diff --git a/.gitignore b/.gitignore index 13bb561270..72ab296f63 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ bin/ build/ */build/ +libs/*.jar out/ */out/ .settings/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 030dcba4ec..683b2b80b9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,30 +1,120 @@ stages: - check + - build - test + - sync check-code: stage: check script: - - "apply_overlay bc-java ./" - - ". cienv.sh; \ gradle check -x test;" - + - "ecr_login" + - "ecr_pull vm_base_intel latest" + - "ci_docker_run \"vm_base_intel:latest\" \"bc-java\" \"/workspace/bc-java/ci/check_java.sh\"" + artifacts: + when: always + paths: + - "core/build/reports" + - "prov/build/reports" + - "pg/build/reports" + - "pkix/build/reports" + - "mail/build/reports" + - "util/build/reports" + - "tls/build/reports" + - "mls/build/reports" + +ant-build: + stage: build + needs: [ "check-code" ] + script: + - "ecr_login" + - "ecr_pull vm_base_intel latest" + - "ci_docker_run \"vm_base_intel:latest\" \"bc-java\" \"/workspace/bc-java/ci/build_1_8.sh\"" + + test-code-8: stage: test + needs: [ "check-code" ] script: - - "apply_overlay bc-java ./" - - "sh gettestdata.sh" - - ". cienv-8.sh; \ gradle -stacktrace clean build;" - + - "ecr_login" + - "ecr_pull vm_base_intel latest" + - "ci_docker_run \"vm_base_intel:latest\" \"bc-java\" \"/workspace/bc-java/ci/test_8.sh\"" + artifacts: + when: always + reports: + junit: + - "core/build/test-results/**/*.xml" + - "prov/build/test-results/**/*.xml" + - "pg/build/test-results/**/*.xml" + - "pkix/build/test-results/**/*.xml" + - "mail/build/test-results/**/*.xml" + - "util/build/test-results/**/*.xml" + - "tls/build/test-results/**/*.xml" + - "mls/build/test-results/**/*.xml" + test-code-11: stage: test + needs: [ "check-code" ] script: - - "apply_overlay bc-java ./" - - "sh gettestdata.sh" - - ". cienv-11.sh; \ gradle -stacktrace clean build;" - + - "ecr_login" + - "ecr_pull vm_base_intel latest" + - "ci_docker_run \"vm_base_intel:latest\" \"bc-java\" \"/workspace/bc-java/ci/test_11.sh\"" + artifacts: + when: always + reports: + junit: + - "core/build/test-results/**/*.xml" + - "prov/build/test-results/**/*.xml" + - "pg/build/test-results/**/*.xml" + - "pkix/build/test-results/**/*.xml" + - "mail/build/test-results/**/*.xml" + - "util/build/test-results/**/*.xml" + - "tls/build/test-results/**/*.xml" + - "mls/build/test-results/**/*.xml" + + test-code-17: stage: test + needs: [ "check-code" ] + script: + - "ecr_login" + - "ecr_pull vm_base_intel latest" + - "ci_docker_run \"vm_base_intel:latest\" \"bc-java\" \"/workspace/bc-java/ci/test_17.sh\"" + artifacts: + when: always + reports: + junit: + - "core/build/test-results/**/*.xml" + - "prov/build/test-results/**/*.xml" + - "pg/build/test-results/**/*.xml" + - "pkix/build/test-results/**/*.xml" + - "mail/build/test-results/**/*.xml" + - "util/build/test-results/**/*.xml" + - "tls/build/test-results/**/*.xml" + - "mls/build/test-results/**/*.xml" + + +test-code-21: + stage: test + needs: [ "check-code" ] + script: + - "ecr_login" + - "ecr_pull vm_base_intel latest" + - "ci_docker_run \"vm_base_intel:latest\" \"bc-java\" \"/workspace/bc-java/ci/test_21.sh\"" + artifacts: + when: always + reports: + junit: + - "core/build/test-results/**/*.xml" + - "prov/build/test-results/**/*.xml" + - "pg/build/test-results/**/*.xml" + - "pkix/build/test-results/**/*.xml" + - "mail/build/test-results/**/*.xml" + - "util/build/test-results/**/*.xml" + - "tls/build/test-results/**/*.xml" + - "mls/build/test-results/**/*.xml" + + +spongycastle: + stage: "sync" script: - - "apply_overlay bc-java ./" - - "sh gettestdata.sh" - - ". cienv-17.sh; \ gradle -stacktrace clean build;" \ No newline at end of file + - "syncpongy.sh" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..771bf2884b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,51 @@ +# Bouncy Castle Contributing Guidelines + +Thank you for contributing to Bouncy Castle! + +In this guide, you get an overview of the contribution workflow from starting a discussion or opening an issue, to creating, reviewing, and merging a pull request. + +For an overview of the project, see [README](README.md). + +### Start a discussion +If you have a question or problem, you can [search in discussions](https://github.com/bcgit/bc-java/discussions), if someone has already found a solution to your problem. + +Or you can [start a new discussion](https://github.com/bcgit/bc-java/discussions/new/choose) and ask your question. + +### Create an issue + +If you find a problem with Bouncy Castle, [search if an issue already exists](https://github.com/bcgit/bc-java/issues). + +> **_NOTE:_** If the issue is a __potential security problem__, please contact us +before posting anything public. See [Security Policy](SECURITY.md). + +If a related discussion or issue doesn't exist, and the issue is not security related, you can [open a new issue](https://github.com/bcgit/bc-java/issues/new). An issue can be converted into a discussion if regarded as one. + +### Contribute to the code + +For substantial, non-trivial contributions, you may be asked to sign a contributor assignment agreement. Optionally, you can also have your name and contact information listed in [Contributors](https://www.bouncycastle.org/contributors.html). + +Please note we are unable to accept contributions which cannot be released under the [Bouncy Castle License](https://www.bouncycastle.org/licence.html). Issuing a pull request on our public github mirror is taken as agreement to issuing under the Bouncy Castle License. + +#### Create a pull request + +> **_NOTE:_** If the issue is a __potential security problem__, please contact us. See [Security Policy](SECURITY.md). + +You are welcome to send patches, under the Bouncy Castle License, as pull requests. For more information, see [Creating a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). For minor updates, you can instead choose to create an issue with short snippets of code. See above. + +* For contributions touching multiple files try and split up the pull request, smaller changes are easier to review and test, as well as being less likely to run into merge issues. +* Create a test cases for your change, it may be a simple addition to an existing test. If you do not know how to do this, ask us and we will help you. +* If you run into any merge issues, check out this [git tutorial](https://github.com/skills/resolve-merge-conflicts) to help you resolve merge conflicts and other issues. + +For more information, refer to the Bouncy Castle documentation on [Getting Started with Bouncy Castle](https://doc.primekey.com/bouncycastle/introduction#Introduction-GettingStartedwithBouncyCastle). + +#### Self-review + +Don't forget to self-review. Please follow these simple guidelines: +* Keep the patch limited, only change the parts related to your patch. +* Do not change other lines, such as whitespace, adding line breaks to Java doc, etc. It will make it very hard for us to review the patch. + + +#### Your pull request is merged + +For acceptance, pull requests need to meet specific quality criteria, including tests for anything substantial. Someone on the Bouncy Castle core team will review the pull request when there is time, and let you know if something is missing or suggest improvements. If it is a useful and generic feature it will be integrated in Bouncy Castle to be available in a later release. + diff --git a/CONTRIBUTORS.html b/CONTRIBUTORS.html index 5c3c90f232..3375f1b545 100644 --- a/CONTRIBUTORS.html +++ b/CONTRIBUTORS.html @@ -10,7 +10,7 @@

The following people and organisations donated financially to help with the release of Bouncy Castle:
 
-EduFer (1.72). Miguel, Rodolfo Hansen, and iterate GmbH (1.69). Encryptomatic.com (1.67). Denis Beurive, Ravi_02, and Manuel Corona (1.66). Christian Kahlo, Alexi Livshitz, and Denis Beurive (1.65). Joshua Hight (1.63). Bihari Babu (1.61). Jens Neuhalfen and perillamint (1.60). Brian Reid (1.59). Joop Kaashoek and Pexus LLC (1.57). DidiSoft, Cotiviti, Atanas Krachev, Encryptomatic LLC, LogicalAnswersIncSupporter (1.56). Digistamp, RAM NAG (1.55). Lobster GmbH (1.54). Sheba, Ishmal Bartley, and Li-Chang Johnny Lo (1.53). lecker@buetterchen.de, Charles Proxy, Gunny Mills, Morgan Le Douget, Ben Whitaker, and Emilio Navarrete Lineros (1.52). Gup & Boz @ Alki Seattle, Bytemine Gmbh, Ted Pennings, Atanas Krachev, PrimeKey Solutions AB, Martin Paljak, CorseraFri19980116, CPU Terminator, Lindsay Bradford, kares, Philius, and Aaron Anderson (1.51). +AXL Software, Larry West (California), A-Sher (1.77). EduFer (1.72). Miguel, Rodolfo Hansen, and iterate GmbH (1.69). Encryptomatic.com (1.67). Denis Beurive, Ravi_02, and Manuel Corona (1.66). Christian Kahlo, Alexi Livshitz, and Denis Beurive (1.65). Joshua Hight (1.63). Bihari Babu (1.61). Jens Neuhalfen and perillamint (1.60). Brian Reid (1.59). Joop Kaashoek and Pexus LLC (1.57). DidiSoft, Cotiviti, Atanas Krachev, Encryptomatic LLC, LogicalAnswersIncSupporter (1.56). Digistamp, RAM NAG (1.55). Lobster GmbH (1.54). Sheba, Ishmal Bartley, and Li-Chang Johnny Lo (1.53). lecker@buetterchen.de, Charles Proxy, Gunny Mills, Morgan Le Douget, Ben Whitaker, and Emilio Navarrete Lineros (1.52). Gup & Boz @ Alki Seattle, Bytemine Gmbh, Ted Pennings, Atanas Krachev, PrimeKey Solutions AB, Martin Paljak, CorseraFri19980116, CPU Terminator, Lindsay Bradford, kares, Philius, and Aaron Anderson (1.51).

We also wish to acknowledge financial and collaborative support from CISCO and additional financial support from PrimeKey towards developing the EST API for RFC 7030 support. @@ -384,7 +384,7 @@

  • Tobias Wich<tobias.wich@ecsec.de> Provided patch for TLS to work around servers sending Supported Elliptic Curves extension unexpectedly.
  • Hauke Mehrtens<hauke@hauke-m.de> TLS patch to add ECDHE_ECDSA CCM ciphersuites from RFC 7251.
  • Daniel Zimmerman<dmz@galois.com> Further key quality improvements to RSAKeyPairGenerator.
  • -
  • Jens Kapitza<j.kapitza@schwarze-allianz.de> Iterable support in OpenPGP API, code cleanup in OpenPGP API.
  • +
  • Jens Kapitza<j.kapitza@schwarze-allianz.de> Iterable support in OpenPGP API, code cleanup in OpenPGP API.
  • Johan Eklund<johan@primekey.se> update to RFC 6960 for OCSPObjectIdentifiers.
  • nikosn<https://github.com/nikosn> Fix to encoding of EC private keys to ensure encoding matches order length.
  • Axel von dem Bruch <axel-vdb@riseup.net> Contributions to BCrypt/OpenBSDBCrypt, original version of Blake2bDigest.
  • @@ -441,18 +441,18 @@
  • David Strawn <https://github.com/isomarcte> fix for off by one error in SCRYPT bounds checking.
  • chris mccown <0xchrismccown@gmail.com> identification of serialisation issue with XMSS/XMSSMT private keys (see also CVE-2018-1000613).
  • ZZMarquis <https://github.com/ZZMarquis> offset patches for SM2 encryption and decryption, improvement to Array constant time comparison.
  • -
  • Andreas Kretschmer <https://github.com/Akretsch> NPE fix for CertTemplate.getVersion()
  • +
  • Andreas Kretschmer, Siemens AG <https://github.com/Akretsch> NPE fix for CertTemplate.getVersion(), ASN.1 KEM Support classes for CMP.
  • Armin Lunkeit, Michael Tautenhahn <> identification of M-R test issue on higher certainty values in RSA key pair generation.
  • Vincent Breitmoser <https://github.com/Valodim> fix to ignore unnecessary checksum calculator on PGP secret key encryption.
  • Adam Vartanian <https://github.com/flooey> use of ShortBuffer exception and buffer size pre-check in Cipher.doFinal().
  • Bernd <https://github.com/ecki> Fix to make PGPUtil.pipeFileContents use buffer and not leak file handle.
  • Shartung <https://github.com/shartung> Additional EC Key Agreement algorithms in support of German BSI TR-03111.
  • -
  • Paul Schaub <https://github.com/vanitasvitae> bringing PGPSecretKey.getUserIds() into line with PGPPublicKey.getUserIds(). Exception message fix in BcPublicKeyDataDecryptorFactory. Additional tests on PGP key ring generation. Improved functionality of PGPSignatureSubpacketGenerator, PGPPublicKeyRing. Tweaks to PGPDataEncryptorBuilder interface, fix for JcaPGP/BcPGP Ed25519 private key conversion. Added configurable CRC detection to ArmoredInputStream, additional control character skipping in ArmoredInputStream. Rewind code for PGPPBEEncryptedData, addition of PGPSignature.getDigestPrefix(). Wrong list traversal fix in PGPSecretKeyRing. Further improvement to use of generics in PGP API. General interop improvements. PGP Public / Secure keyring ignore marker packets when reading. Initial work on PGP session key handling, filtering literal data for canoncialization. Addition of direct key identified key-ring construction. PGPSecretKeyRing.insertOrReplacePublicKey addition. Addition of utility methods for joining/merging signatures and public keys. Addition of PGP regexp packet, PolicyURI packet handling, UTF8 comment testing. Efficiency improvements to TruncatedStream. Initial Argon2 support for OpenPGP. General cleanups. Fast CRC24 implementation, SHA3 addtions to BcImplProvider, improvements to One Pass Signature support, read() consistency in BCPGInputStream. Contributions to AEAD support in PGP API.
  • +
  • Paul Schaub <https://github.com/vanitasvitae> bringing PGPSecretKey.getUserIds() into line with PGPPublicKey.getUserIds(). Exception message fix in BcPublicKeyDataDecryptorFactory. Additional tests on PGP key ring generation. Improved functionality of PGPSignatureSubpacketGenerator, PGPPublicKeyRing. Tweaks to PGPDataEncryptorBuilder interface, fix for JcaPGP/BcPGP Ed25519 private key conversion. Added configurable CRC detection to ArmoredInputStream, additional control character skipping in ArmoredInputStream. Rewind code for PGPPBEEncryptedData, addition of PGPSignature.getDigestPrefix(). Wrong list traversal fix in PGPSecretKeyRing. Further improvement to use of generics in PGP API. General interop improvements. PGP Public / Secure keyring ignore marker packets when reading. Initial work on PGP session key handling, filtering literal data for canoncialization. Addition of direct key identified key-ring construction. PGPSecretKeyRing.insertOrReplacePublicKey addition. Addition of utility methods for joining/merging signatures and public keys. Addition of PGP regexp packet, PolicyURI packet handling, UTF8 comment testing. Efficiency improvements to TruncatedStream. Initial Argon2 support for OpenPGP. General cleanups. Fast CRC24 implementation, SHA3 addtions to BcImplProvider, improvements to One Pass Signature support, signatue validation, read() consistency in BCPGInputStream. Contributions to AEAD support (v6 & v5) in PGP API. Addition of PGP WildCard ID, moving the PGP example code into the 21st century. Security patches for encrypted data generation, initial thread safe certification verification. Support for V6 EC keys, PGP packet criticality, and Preferred AEAD CipherSuites sigsubpacket support.
  • Nick of Nexxar <https://github.com/nros> update to OpenPGP package to handle a broader range of EC curves.
  • catbref <https://github.com/catbref> sample implementation of RFC 7748/Ed25519 (incorporated work from github users Valodim and str4d as well).
  • gerlion <https://github.com/gerlion> detection of concurrency issue with pre-1.60 EC math library.
  • fgrieu <fgrieu@gmail.com> identification and suggested fixes for possible timing vulnerability in OAEPEncoding and RSACoreEngine.
  • -
  • MTG <https://github.com/mtgag> patch for decoding issues in PKIPublicationInfo and CertifiedKeyPair.
  • +
  • MTG <https://github.com/mtgag> patch for decoding issues in PKIPublicationInfo and CertifiedKeyPair, patch for adding jurisdiction{C,ST,L} to X500 name style.
  • Andreas Gadermaier <up.gadermaier@gmail.com> initial version of Argon2 PBKDF algorithm.
  • Tony Washer <tony.washer@yahoo.co.uk> review of qTesla, Java 1.9 module code, additional test code and debugging for GOST, DSTU, and ECNR algorithms. Initial lightweight implementation of the ZUC ciphers and macs. Additions to LMS/HSS API implementations, fix for truncation issue with big HSS keys, contributions to optimization of LMS/HSS. Patch for XDH/EdDSA key handling and mcEliece decryption using kobaraImai. Initial GCM-SIV, Blake3, and Kangaroo implementation.
  • Vincent Bouckaert <https://github.com/veebee> initial version of RFC 4998 ASN.1 classes. Debugging and testing of high level RFC 4998 implementation.
  • @@ -488,7 +488,7 @@
  • vvvlado <https://github.com/vvvlado> Fix to support repeated headers in PGP armored data.
  • a--v--k <https://github.com/a--v--k> Clean up for some invalid mappings in the Java provider.
  • lipnitsk <https://github.com/lipnitsk> Fix for non-CRT RSA Private serialisation.
  • -
  • Niccolò Fontana <https://github.com/NicFontana> Initial fix for high-latency DTLS HelloVerifyRequest handshakes.
  • +
  • Niccolò Fontana <https://github.com/NicFontana> Initial fix for high-latency DTLS HelloVerifyRequest handshakes.
  • sudheernv <https://github.com/sudheernv> Patch for KMAC rightEncode() encoding.
  • Mathias Neuhaus <https://github.com/mneuhaus-cv> Patch for cSHAKE extra padding on block aligned N and S bug.
  • Yuri Schimke <https://github.com/yschimke> Patch for nested exception handling in BcKeyStoreSpi.
  • @@ -529,7 +529,27 @@
  • Amazon AWS Security Team - isolation and identification of performance bottlenecks in the BC PEM parsing support.
  • Phillip Schichtel <https://github.com/pschichtel> - initial code for specifying wrapping algorithm with PGP PBE encryption method, forcing of session key usage.
  • Alexander Dippel <https://github.com/adippel> - corrections to prevent NPEs on chunked encoding of EST responses.
  • -
  • Johann N. Löfflmann <https://github.com/jonelo> - fix to "too small" buffer issue in Blake2sp.
  • +
  • Johann N. Löfflmann <https://github.com/jonelo> - fix to "too small" buffer issue in Blake2sp.
  • +
  • Scott Xu <https://github.com/scott-xu> - message fix in OpenSSHPublicKeyUtil
  • +
  • Scott Arciszewski <https://github/scottarc> - correction to ant scripts to ensure UTF8 support.
  • +
  • GitHub Security team - identification of the X509LDAPCertStoreSpi wildcard bug (see CVE-2023-33201).
  • +
  • James Howe <https://github.com/OrangeDog> - improvement to cross-provider compatibility in JcaPKCS10CertificationRequest.
  • +
  • Steffen Heil <https://github.com/steffen-heil> - correction to error handling in Arrays.getLength().
  • +
  • Thomas D. <https://github.com/thomdev> - expansion of HPKE APIs, addition of user controlled ephemeral key to HPKE API.
  • +
  • Franz Fangmeyer <https://github.com/ff-wl> - exception handling for improper use of '=' in an X.500 RDN.
  • +
  • Jonathan Lennox <https://github.com/JonathanLennox> - fix DTLS retransmission bug with aggregated ChangeCipherSpec.
  • +
  • Thomas Devanneaux <tdevanneaux@apple.com> - extensions to the HPKE API to support encryption/decryption from byte ranges, allow sender selected ephemeral key.
  • +
  • Norman Maurer <norman_maurer@apple.com> - extensions to the HPKE API to support encryption/decryption from byte ranges, allow sender selected ephemeral key.
  • +
  • Bing Shi <roadicing@gmail.com> - addition of F2m bounds checking for imported EC F2m curves.
  • +
  • Phil Brown <https://github.com/brownp2k> - additional ant targets for building util and pkix.
  • +
  • Tamas Cservenak <https://github.com/cstamas> - initial patch for supporting Ed25519 keys in GnuPG S-expressions.
  • +
  • chchen-scholar <https://github.com/chchen-scholar> - encoding fix for EccP256CurvePoint.
  • +
  • Seung Yeon <https://github.com/seungyeonpark> - addition of Memoable method implementations to CertPathValidationContext and CertificatePoliciesValidation.
  • +
  • yuhh0328 <https://github.com/yuhh0328> - initial patch for adding ML-KEM support to TLS.
  • +
  • Jan Oupický <https://github.com/Honzaik> - update to draft 13 of composite PQC signatures.
  • +
  • Karsten Otto <https://github.com/ottoka> - finished the support for jdk.tls.server.defaultDHEParameters.
  • +
  • Markus Sommer <https://github.com/marsom> - BCStyle lookup table fix for jurisdiction values.
  • +
  • TaZbon <https://github.com/TaZbon> - Optional lax parsing patch for PEM parser.
  • diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..277dcd1ebb --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,13 @@ +Copyright (c) 2000-2024 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org). +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sub license, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: The above copyright notice and this +permission notice shall be included in all copies or substantial portions of the Software. + +**THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.** diff --git a/README.md b/README.md index 4b1766478a..2913e3d351 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # The Bouncy Castle Crypto Package For Java -[![Build Status](https://travis-ci.org/bcgit/bc-java.svg?branch=master)](https://travis-ci.org/bcgit/bc-java) - The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms, it was developed by the Legion of the Bouncy Castle, a registered Australian Charity, with a little help! The Legion, and the latest goings on with this package, can be found at [https://www.bouncycastle.org](https://www.bouncycastle.org). The Legion also gratefully acknowledges the contributions made to this package by others (see [here](https://www.bouncycastle.org/contributors.html) for the current list). If you would like to contribute to our efforts please feel free to get in touch with us or visit our [donations page](https://www.bouncycastle.org/donate), sponsor some specific work, or purchase a support contract through [Crypto Workshop](https://www.keyfactor.com/platform/bouncy-castle-support/) (now part of Keyfactor). @@ -12,6 +10,51 @@ Except where otherwise stated, this software is distributed under a license base **Note**: this source tree is not the FIPS version of the APIs - if you are interested in our FIPS version please contact us directly at [office@bouncycastle.org](mailto:office@bouncycastle.org). + +## Environmental Variables + +Before invoking gradlew you need to ensure the following environmental variables are defined and point +to valid JAVA_HOMEs for each JVM version: + +``` +export BC_JDK8=/path/to/java8 +export BC_JDK11=/path/to/java11 +export BC_JDK17=/path/to/java17 +export BC_JDK21=/path/to/java21 +``` + +## Building + +The project now uses ```gradlew``` which can be invoked for example: + +``` +# from the root of the project + +# Ensure JAVA_HOME points to JDK 17 or higher JAVA_HOME + + +./gradlew clean build + +``` + +The gradle script will endeavour to verify their existence but not the correctness of their value. + + +## Multi-release jars and testing +Some subprojects produce multi-release jars and these jars are tested in different jvm versions. +Default testing on these projects is done on java 1.8 and there are specific test tasks for other versions. + +1. test11 test on java 11 JVM +2. test17 test on java 17 JVM +3. test21 test on java 21 JVM + +To run all of them: + +``` +./gradlew clean build test11 test17 test21 +``` + + ## Code Organisation The clean room JCE, for use with JDK 1.1 to JDK 1.3 is in the jce/src/main/java directory. From JDK 1.4 and later the JCE ships with the JVM, the source for later JDKs follows the progress that was made in the later versions of the JCE. If you are using a later version of the JDK which comes with a JCE install please **do not** include the jce directory as a source file as it will clash with the JCE API installed with your JDK. diff --git a/SECURITY.md b/SECURITY.md index c365182c2f..3813599af0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,5 +1,17 @@ -# Reporting a security issue +# Security Policy -If you would like to report something you believe to be a security issue -then please use feedback-crypto@bouncycastle.org. -We can provide a PGP key if required. +## Reporting a Vulnerability + +If you think that you have found a security vulnerability, please report it to this email address: [feedback-crypto@bouncycastle.org](mailto:feedback-crypto@bouncycastle.org) + +Describe the issue including all details, for example: +* Short summary of the problem +* Steps to reproduce +* Affected API versions +* Logs if available + +The Bouncy Castle team will send a response indicating the next steps in handling your report. You may be asked to provide additional information or guidance. + +If the issue is confirmed as a vulnerability, we will open a Security Advisory and acknowledge your contributions as part of it. Optionally, you can have your name and contact information listed in [Contributors](https://www.bouncycastle.org/contributors.html) as well. + +Please note we endeavor to issue patched releases that deal with security issues as soon as they are made known to us, ideally prior to issuing a Security Advisory where otherwise possible. In some cases, particularly if it relates to a FIPS release, delays due to external processes may delay the issuing of a Security Advisory. diff --git a/ant/bc+-build.xml b/ant/bc+-build.xml index 79b90acea9..07e67148c1 100644 --- a/ant/bc+-build.xml +++ b/ant/bc+-build.xml @@ -74,6 +74,7 @@ + @@ -118,7 +119,7 @@ - - - + @@ -311,7 +312,7 @@ - + + + + + - + + + + + + + + + @@ -753,14 +767,27 @@ + + + + + - + + + + + + + + + @@ -815,6 +842,7 @@ + @@ -858,7 +886,10 @@ - + + + + @@ -921,6 +952,7 @@ + @@ -951,6 +983,7 @@ + @@ -989,6 +1022,7 @@ + @@ -1005,6 +1039,8 @@ + + @@ -1036,7 +1072,7 @@ - + + + + + + + + + + + + + + + + + + + + + + diff --git a/ant/build.regexp b/ant/build.regexp index 194e610f26..8e11b2439c 100644 --- a/ant/build.regexp +++ b/ant/build.regexp @@ -1,3 +1,3 @@ -regexp: >|>|]*>>|<[A-Z?][^>@]*[a-zA-Z0-9\\]]>|<[A-Z]>|<[a-z][^>@]*[a-z\\]]>|@SuppressWarnings(.*)|@Override +regexp: >|>|]*>>|<[A-Z?][^>@]*[a-zA-Z0-9\\]]>|<[A-Z]>|<[a-z][^>@]*[a-z\\]]>|@SuppressWarnings(.*)|@Override|@Deprecated|@FunctionalInterface diff --git a/ant/jdk13.xml b/ant/jdk13.xml index fd4017786c..74ad1e18b5 100644 --- a/ant/jdk13.xml +++ b/ant/jdk13.xml @@ -45,7 +45,6 @@ - @@ -80,9 +79,10 @@ + + - @@ -127,6 +127,13 @@ + + + + + + + @@ -254,9 +261,13 @@ + + + + @@ -280,13 +291,17 @@ + + + + + - diff --git a/ant/jdk14.xml b/ant/jdk14.xml index 9a1cebda13..32916cc908 100644 --- a/ant/jdk14.xml +++ b/ant/jdk14.xml @@ -26,7 +26,6 @@ - @@ -54,6 +53,7 @@ + @@ -76,7 +76,7 @@ - + @@ -85,6 +85,7 @@ + @@ -129,17 +130,24 @@ + - + + + - + + + + + @@ -197,6 +205,9 @@ + + + diff --git a/ant/jdk15+.xml b/ant/jdk15+.xml index 11f9cbcb6c..148824d5ba 100644 --- a/ant/jdk15+.xml +++ b/ant/jdk15+.xml @@ -42,17 +42,19 @@ + - + + diff --git a/ant/jdk18+.xml b/ant/jdk18+.xml index 4ad36fb282..66e194ad90 100644 --- a/ant/jdk18+.xml +++ b/ant/jdk18+.xml @@ -9,7 +9,7 @@ - + @@ -46,7 +46,7 @@ - + @@ -107,6 +107,14 @@ + + + + + + + + diff --git a/bc-build.properties b/bc-build.properties index 8b47da7c27..5a9d25595d 100644 --- a/bc-build.properties +++ b/bc-build.properties @@ -3,15 +3,16 @@ # intended to hold user-specific settings that are *not* committed to # the repository. -release.suffix: 173 -release.name: 1.73 -release.version: 1.73 -release.debug: false +release.suffix: 1.79b01 +release.name: 1.78.99 +release.version: 1.78.99 +release.debug: true -mail.jar.home: ./libs/mail.jar -activation.jar.home: ./libs/activation.jar +mail.jar.home: ./libs/javax.mail-1.4.7.jar +activation.jar.home: ./libs/activation-1.1.1.jar jmail.jar.home: ./libs/jakarta.mail-2.0.1.jar jactivation.jar.home: ./libs/jakarta.activation-api-2.0.0.jar -junit.jar.home: ./libs/junit.jar +junit.jar.home: ./libs/junit-4.13.2.jar +ldap.jar.home: ./libs/unboundid-ldapsdk-6.0.8.jar junit.printsummary: off diff --git a/bnd.sh b/bnd.sh new file mode 100755 index 0000000000..13183653a9 --- /dev/null +++ b/bnd.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +JAVA_HOME=/opt/jdk1.5.0 +export JAVA_HOME + +PATH=$JAVA_HOME/bin:$PATH +export PATH + +for jarFile in $* +do + base=`basename $jarFile .jar` + javaVersion=`echo $base | sed -e "s/.*\(jdk..\).*/\\1/"` + name=`echo $base | sed -e "s/\([^-]*\)-jdk.*/\\1/"` + bcVersion=`echo $base | sed -e "s/$name-${javaVersion}.*-\(1.*\)/\\1/" | sed -e "s/b/.0./"` + baseVersion=`echo $bcVersion | sed -e "s/[^.]*.\([0-9]*\).*/\\1/"` + bcMaxVersion="`expr "${baseVersion}" "+" "1"`" + + if [ "`echo $bcVersion | fgrep b`" = "$bcVersion" ] + then + bcVersion=`echo $bcVersion | sed -e "s/50b/49./"` + fi + + if `echo $jarFile | fgrep bcprov > /dev/null` + then + cat > /tmp/bnd.props <<% +Bundle-Version: $bcVersion +Bundle-Name: $name +Bundle-SymbolicName: $name +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Export-Package: org.bouncycastle.*;version=$bcVersion +Import-Package: *;resolution:=optional +% + else + cat > /tmp/bnd.props <<% +Bundle-Version: $bcVersion +Bundle-Name: $name +Bundle-SymbolicName: $name +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Export-Package: org.bouncycastle.*;version=$bcVersion +Import-Package: org.bouncycastle.*;version="[${bcVersion},1.${bcMaxVersion})",*;resolution:=optional +% + fi + + java -jar $BND_HOME/biz.aQute.bnd-2.2.0.jar wrap --properties /tmp/bnd.props $jarFile + mv $base.jar $jarFile +done diff --git a/build.gradle b/build.gradle index 936b089895..ffbff6c8b0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,226 +1,275 @@ buildscript { - repositories { - maven { - url "https://plugins.gradle.org/m2/" + repositories { + maven { + url "https://plugins.gradle.org/m2/" + } } - } + } plugins { - id "io.spring.nohttp" version "0.0.8" - id "checkstyle" - id "jacoco" - id "net.ltgt.errorprone" version "2.0.2" + id "io.spring.nohttp" version "0.0.11" + id "checkstyle" + id "jacoco" + id "net.ltgt.errorprone" version "3.1.0" +} + +println("Environment setup:") +["BC_JDK8", "BC_JDK11", "BC_JDK17", "BC_JDK21"].each({ it -> + println("Looking for JDK ENV '${it}' found ${System.getenv(it)}"); + if (System.getenv(it) == null) { + throw new RuntimeException("Looking for JDK ENV '${it}' but found null, see README 'Environmental variables'"); + } +}) + + +if (JavaVersion.current().isJava8Compatible()) { + allprojects { + tasks.withType(Javadoc) { + options.addStringOption('Xdoclint:none', '-quiet') + } + } } -if (JavaVersion.current().isJava8Compatible()) -{ - allprojects { - tasks.withType(Javadoc) { - options.addStringOption('Xdoclint:none', '-quiet') +def String deriveOSGIVersion(String prjVersion) { + if (prjVersion.contains("-SNAPSHOT")) { + // Snapshots always extend to fourth level and terminate with time in seconds since epoch. + prjVersion = prjVersion.replace("-SNAPSHOT", ""); + while (prjVersion.count(".") < 2) { + prjVersion = prjVersion + ".0"; + } + prjVersion = prjVersion + "." + System.currentTimeMillis().intdiv(1000L).intdiv(60).intdiv(60).intdiv(24); } - } + return prjVersion } +ext { + bundle_version = deriveOSGIVersion(version.toString()); +} + + // this needs to go here, otherwise it can't find config apply plugin: 'io.spring.nohttp' allprojects { - apply plugin: 'java' - apply plugin: 'idea' - apply plugin: 'checkstyle' - apply plugin: 'jacoco' - apply plugin: 'net.ltgt.errorprone' - - repositories { - mavenCentral() - } - - dependencies { - testImplementation group: 'junit', name: 'junit', version: '4.11' - } - - tasks.withType(JavaCompile).configureEach { - options.errorprone { - // Checks that cannot be enabled because implementing their suggestions - // would break backward compatibility. - check('ComparableType', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('JdkObsolete', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - - // ERROR - check('BadShiftAmount', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('BanJNDI', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('BoxedPrimitiveEquality', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('ChainingConstructorIgnoresParameter', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('ConstantOverflow', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('EqualsHashCode', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('EqualsNull', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('HashtableContains', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('ReturnValueIgnored', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('SelfEquals', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - - // WARNING - check('AlmostJavadoc', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('AlreadyChecked', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('AmbiguousMethodReference', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('AssertionFailureIgnored', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('BadImport', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('BadInstanceof', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('BoxedPrimitiveConstructor', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('CanIgnoreReturnValueSuggester', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('CatchAndPrintStackTrace', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('CatchFail', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('ClassNewInstance', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('CompareToZero', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('DefaultCharset', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('DoubleBraceInitialization', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('EmptyBlockTag', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('EmptyCatch', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('EqualsGetClass', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('EqualsIncompatibleType', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('ErroneousBitwiseExpression', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('FallThrough', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('FloatingPointLiteralPrecision', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('HidingField', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('InconsistentCapitalization', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('InconsistentHashCode', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('IncrementInForLoopAndHeader', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('InputStreamSlowMultibyteRead', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('InstanceOfAndCastMatchWrongType', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('IntLongMath', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('InvalidBlockTag', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('InvalidInlineTag', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('InvalidParam', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('InvalidThrows', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('IsInstanceIncompatibleType', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('IsInstanceOfClass', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('JavaLangClash', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('JavaUtilDate', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('MalformedInlineTag', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('MathAbsoluteRandom', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('MissingCasesInEnumSwitch', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('MissingFail', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('MissingImplementsComparable', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('MissingOverride', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('MissingSummary', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('MixedMutabilityReturnType', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('ModifiedButNotUsed', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('MutablePublicArray', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('NarrowCalculation', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('NarrowingCompoundAssignment', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('NestedInstanceOfConditions', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('NonAtomicVolatileUpdate', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('NonOverridingEquals', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('OperatorPrecedence', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('ProtectedMembersInFinalClass', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('ReferenceEquality', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('ReturnFromVoid', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('ShortCircuitBoolean', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('StringSplitter', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('SynchronizeOnNonFinalField', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('ThreadLocalUsage', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('ThreadPriorityCheck', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('TypeParameterUnusedInFormals', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('UndefinedEquals', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('UnescapedEntity', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('UnicodeEscape', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('UnnecessaryParentheses', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('UnrecognisedJavadocTag', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('UnsynchronizedOverridesSynchronized', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('UnusedMethod', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('UnusedNestedClass', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('UnusedVariable', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('UseCorrectAssertInTests', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - check('VariableNameSameAsType', net.ltgt.gradle.errorprone.CheckSeverity.OFF) - } - } + apply plugin: 'java' + apply plugin: 'idea' + apply plugin: 'checkstyle' + apply plugin: 'jacoco' + apply plugin: 'net.ltgt.errorprone' -} + repositories { + mavenCentral() + } + + dependencies { + testImplementation group: 'junit', name: 'junit', version: '4.13.2' + } + tasks.withType(JavaCompile).configureEach { + options.errorprone { + // Checks that cannot be enabled because implementing their suggestions + // would break backward compatibility. + check('ComparableType', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('JdkObsolete', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + + // ERROR + check('BadShiftAmount', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('BanJNDI', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('BoxedPrimitiveEquality', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('ChainingConstructorIgnoresParameter', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('ConstantOverflow', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('EqualsHashCode', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('EqualsNull', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('HashtableContains', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('ReturnValueIgnored', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('SelfEquals', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + + // WARNING + check('AlmostJavadoc', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('AlreadyChecked', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('AmbiguousMethodReference', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('AssertionFailureIgnored', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('BadImport', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('BadInstanceof', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('BoxedPrimitiveConstructor', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('CanIgnoreReturnValueSuggester', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('CatchAndPrintStackTrace', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('CatchFail', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('ClassNewInstance', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('CompareToZero', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('DefaultCharset', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('DoubleBraceInitialization', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('EmptyBlockTag', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('EmptyCatch', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('EqualsGetClass', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('EqualsIncompatibleType', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('ErroneousBitwiseExpression', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('FallThrough', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('FloatingPointLiteralPrecision', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('HidingField', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('InconsistentCapitalization', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('InconsistentHashCode', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('IncrementInForLoopAndHeader', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('InputStreamSlowMultibyteRead', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('InstanceOfAndCastMatchWrongType', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('IntLongMath', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('InvalidBlockTag', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('InvalidInlineTag', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('InvalidParam', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('InvalidThrows', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('IsInstanceIncompatibleType', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('IsInstanceOfClass', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('JavaLangClash', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('JavaUtilDate', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('MalformedInlineTag', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('MathAbsoluteRandom', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('MissingCasesInEnumSwitch', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('MissingFail', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('MissingImplementsComparable', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('MissingOverride', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('MissingSummary', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('MixedMutabilityReturnType', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('ModifiedButNotUsed', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('MutablePublicArray', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('NarrowCalculation', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('NarrowingCompoundAssignment', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('NestedInstanceOfConditions', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('NonAtomicVolatileUpdate', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('NonOverridingEquals', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('OperatorPrecedence', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('ProtectedMembersInFinalClass', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('ReferenceEquality', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('ReturnFromVoid', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('ShortCircuitBoolean', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('StringSplitter', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('SynchronizeOnNonFinalField', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('ThreadLocalUsage', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('ThreadPriorityCheck', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('TypeParameterUnusedInFormals', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('UndefinedEquals', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('UnescapedEntity', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('UnicodeEscape', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('UnnecessaryParentheses', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('UnrecognisedJavadocTag', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('UnsynchronizedOverridesSynchronized', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('UnusedMethod', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('UnusedNestedClass', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('UnusedVariable', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('UseCorrectAssertInTests', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + check('VariableNameSameAsType', net.ltgt.gradle.errorprone.CheckSeverity.OFF) + } + } -ext { - bcTestDataHome = file('core/src/test/data').absolutePath } task printProperties { - doLast { - println bcTestDataHome - } + doLast { + println bcTestDataHome + } +} + +ext { + bcTestDataHome = file('core/src/test/data').absolutePath + + JavaVersion current = JavaVersion.current(); + if (current.compareTo(JavaVersion.VERSION_1_8) <= 0) { + ext.vmrange = 'jdk15to18' + } else { + ext.vmrange = 'jdk18on' + } + + bc_prov = "${rootProject.projectDir}/prov/build/libs/bcprov-${vmrange}-${version}.jar" + bc_util = "${rootProject.projectDir}/util/build/libs/bcutil-${vmrange}-${version}.jar" + bc_pkix = "${rootProject.projectDir}/pkix/build/libs/bcpkix-${vmrange}-${version}.jar" + } + + + subprojects { - apply plugin: 'eclipse' - - JavaVersion current = JavaVersion.current(); - if (current.compareTo(JavaVersion.VERSION_1_8) <= 0) - { - ext.vmrange = 'jdk15to18' - sourceCompatibility = 1.5 - targetCompatibility = 1.5 - } - else - { - ext.vmrange = 'jdk18on' - sourceCompatibility = 1.8 - targetCompatibility = 1.8 - } - - version = '1.73' - - task testFull(type:Test) { - systemProperties = [ - 'bc.test.data.home': bcTestDataHome, - 'test.full':'true' - ] - systemProperty 'bc.test.data.home', bcTestDataHome - maxHeapSize = "1536m" - - finalizedBy jacocoTestReport - - filter { - includeTestsMatching "AllTest*" - } - } - - test { - systemProperty 'bc.test.data.home', bcTestDataHome - maxHeapSize = "1536m" - testLogging.showStandardStreams = true - - finalizedBy jacocoTestReport - - filter { - includeTestsMatching "AllTest*" - if (project.hasProperty('excludeTests')) { - excludeTestsMatching "${excludeTests}" - } - } - } - - - dependencies { - checkstyle files("$rootDir/config/checkstyle/lib/methodchecker.jar") - checkstyle 'com.puppycrawl.tools:checkstyle:9.0' - errorprone "com.google.errorprone:error_prone_core:2.15.0" - } - - checkstyle { - configFile file("$rootDir/config/checkstyle/checkstyle.xml"); - toolVersion '9.0'; // your choice here - sourceSets = [project.sourceSets.main] - } - - nohttp { - source.exclude '**/*.rsp' - } - - jacocoTestReport { - dependsOn test // tests are required to run before generating the report - } - - jacoco { - reportsDirectory = layout.buildDirectory.dir("jacoco") - } + apply plugin: 'eclipse' + + JavaVersion current = JavaVersion.current(); + if (current.compareTo(JavaVersion.VERSION_1_8) <= 0) { + sourceCompatibility = 1.5 + targetCompatibility = 1.5 + } else { + sourceCompatibility = 1.8 + targetCompatibility = 1.8 + } + + + task testFull(type: Test) { + systemProperties = [ + 'bc.test.data.home': bcTestDataHome, + 'test.full' : 'true' + ] + systemProperty 'bc.test.data.home', bcTestDataHome + maxHeapSize = "1536m" + + finalizedBy jacocoTestReport + + filter { + includeTestsMatching "AllTest*" + } + } + + test { + forkEvery = 1; + maxParallelForks = 1; + systemProperty 'bc.test.data.home', bcTestDataHome + maxHeapSize = "1536m" + testLogging.showStandardStreams = true + + javaLauncher = javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(8) + } + + finalizedBy jacocoTestReport + + filter { + includeTestsMatching "AllTest*" + if (project.hasProperty('excludeTests')) { + excludeTestsMatching "${excludeTests}" + } + } + } + + dependencies { + checkstyle files("$rootDir/config/checkstyle/lib/methodchecker-1.0.0.jar") + checkstyle 'com.puppycrawl.tools:checkstyle:9.0' + errorprone "com.google.errorprone:error_prone_core:2.24.1" + } + + checkstyle { + configFile file("$rootDir/config/checkstyle/checkstyle.xml"); + toolVersion '9.0'; // your choice here + sourceSets = [project.sourceSets.main] + } + + nohttp { + source.exclude '**/*.rsp' + } + + jacocoTestReport { + dependsOn test // tests are required to run before generating the report + } + + jacoco { + reportsDirectory = layout.buildDirectory.dir("jacoco") + } + + tasks.withType(JavaCompile).configureEach { + options.debug = true; + } + + tasks.withType(Test).configureEach { + reports { + junitXml.outputLocation = layout.buildDirectory.dir("test-results") + } + } } -test.dependsOn([':core:test', ':prov:test', ':pkix:test', ':mail:test', 'pg:test', ':tls:test']) +test.dependsOn([':core:test', ':prov:test', ':prov:test11', ':prov:test17', ':prov:test21', ':pkix:test', 'pg:test', ':tls:test', 'mls:test', 'mail:test', 'jmail:test']) diff --git a/build1-1 b/build1-1 index 21f875efda..1106236e2e 100644 --- a/build1-1 +++ b/build1-1 @@ -45,6 +45,10 @@ mkdir -p $jdk11src ((cd pkix/src/main/java && tar cf - * ) | (cd $jdk11src && tar xf -)) ((cd pkix/src/main/javadoc && tar cf - * ) | (cd $jdk11src && tar xf -)) ((cd pkix/src/test/java && tar cf - * ) | (cd $jdk11src && tar xf -)) +((cd pg/src/main/jdk1.5 && tar cf - * ) | (cd $jdk11src && tar xf -)) +((cd pg/src/main/jdk1.4 && tar cf - * ) | (cd $jdk11src && tar xf -)) +((cd pg/src/main/jdk1.3 && tar cf - * ) | (cd $jdk11src && tar xf -)) +((cd pg/src/main/jdk1.1 && tar cf - * ) | (cd $jdk11src && tar xf -)) ((cd pkix/src/main/jdk1.4 && tar cf - * ) | (cd $jdk11src && tar xf -)) ((cd pkix/src/test/jdk1.4 && tar cf - * ) | (cd $jdk11src && tar xf -)) ((cd pkix/src/main/jdk1.3 && tar cf - * ) | (cd $jdk11src && tar xf -)) @@ -200,8 +204,10 @@ find $jdk11src -name "*.java" -exec scripts/useseccert.sh \{\} \; rm -r org/bouncycastle/math/raw/test/InterleaveTest.java rm -rf org/bouncycastle/cert/jcajce/JcaAttributeCertificateIssuer.java rm -rf org/bouncycastle/cert/test/ConverterTest* + rm -rf org/bouncycastle/cert/test/ExternalKeyTest* rm -rf org/bouncycastle/cert/test/CertPathLoopTest.java rm -rf org/bouncycastle/cert/test/Bc* + rm -rf org/bouncycastle/cert/test/DeltaCertTest* rm -rf org/bouncycastle/cert/test/GOST3410_2012CMSTest.java rm -rf org/bouncycastle/cert/ocsp/test/PKIXRevocationTest.java rm -rf org/bouncycastle/tsp/GenTimeAccuracyUnit* @@ -232,6 +238,12 @@ find $jdk11src -name "*.java" -exec scripts/useseccert.sh \{\} \; rm -rf org/bouncycastle/pkcs/test rm -rf org/bouncycastle/eac/test rm -rf org/bouncycastle/cms/test + rm -r org/bouncycastle/jcajce/provider/asymmetric/compositesignatures + rm -r org/bouncycastle/jcajce/provider/asymmetric/CompositeSignatures.java + rm org/bouncycastle/pqc/crypto/test/XWingTest.java + rm org/bouncycastle/cert/test/GOSTR3410_2012_256GenerateCertificate.java + rm org/bouncycastle/cert/cmp/test/InvalidMessagesTest.java + rm org/bouncycastle/test/JVMVersionTest.java rm org/bouncycastle/cms/jcajce/JceAADStream.java rm org/bouncycastle/cms/jcajce/JceCMSKEM*.java rm org/bouncycastle/cms/jcajce/JceKEM*.java @@ -259,6 +271,11 @@ find $jdk11src -name "*.java" -exec scripts/useseccert.sh \{\} \; rm -rf org/bouncycastle/pkix/jcajce/X509* rm -rf org/bouncycastle/pkix/jcajce/RFC3280* rm -rf org/bouncycastle/pkix/jcajce/Revocation* + rm org/bouncycastle/pkix/jcajce/CertPath*.java + rm org/bouncycastle/pkix/jcajce/PKIXCert*.java + rm org/bouncycastle/pkix/jcajce/PKIXPolicyN*.java + rm org/bouncycastle/pkix/jcajce/PKIXCRLUtil.java + rm -r org/bouncycastle/pkix/util rm -rf org/bouncycastle/pkix/test/Revocation* rm -rf org/bouncycastle/pkix/test/TestUtil* rm org/bouncycastle/pkix/test/CheckerTest.java @@ -284,7 +301,15 @@ find $jdk11src -name "*.java" -exec scripts/useseccert.sh \{\} \; rm -rf org/bouncycastle/jce/provider/test/SM2SignatureTest.java rm -f org/bouncycastle/jcajce/provider/drbg/EntropyGatherer.java rm -f org/bouncycastle/jcajce/provider/drbg/EntropyDaemon.java + rm -f org/bouncycastle/jcajce/provider/asymmetric/Dilithium.java + rm -f org/bouncycastle/jcajce/provider/asymmetric/NTRU.java + rm -f org/bouncycastle/jcajce/provider/asymmetric/Falcon.java rm -f org/bouncycastle/test/PrintTestResult.java + rm -f org/bouncycastle/openpgp/test/PGPAeadTest.java + rm -f org/bouncycastle/openpgp/test/BytesBooleansTest.java + rm -f org/bouncycastle/openpgp/test/BcImplProviderTest.java + rm -f org/bouncycastle/openpgp/test/BcpgGeneralTest.java + rm -f org/bouncycastle/openpgp/test/OpenPGPTest.java sh ../../scripts/jdk1.2ed.sh > /dev/null 2>&1 sh ../../scripts/jdk1.1ed.sh > /dev/null 2>&1 @@ -629,6 +654,7 @@ then mkdir $artifacts/bcpg-jdk11-$base/src tar cf - index.html LICENSE.html CONTRIBUTORS.html docs | (cd $artifacts/bcpg-jdk11-$base; tar xf -) ((cd pg/src/main/java && tar cf - * ) | (cd $artifacts/bcpg-jdk11-$base/src && tar xf -)) + ((cd pg/src/main/jdk1.5 && tar cf - * ) | (cd $artifacts/bcpg-jdk11-$base/src && tar xf -)) ((cd pg/src/main/jdk1.4 && tar cf - * ) | (cd $artifacts/bcpg-jdk11-$base/src && tar xf -)) ((cd pg/src/main/jdk1.3 && tar cf - * ) | (cd $artifacts/bcpg-jdk11-$base/src && tar xf -)) ((cd pg/src/main/jdk1.1 && tar cf - * ) | (cd $artifacts/bcpg-jdk11-$base/src && tar xf -)) @@ -670,6 +696,14 @@ then rm -f src/org/bouncycastle/openpgp/test/BcPGPEd25519JcaKeyPairConversionTest.java rm src/org/bouncycastle/openpgp/test/ArmoredOutputStreamUTF8Test.java rm -f src/org/bouncycastle/openpgp/examples/DSAElGamalKeyRingGenerator.java + rm -f src/org/bouncycastle/openpgp/examples/EllipticCurveKeyPairGenerator.java + rm src/org/bouncycastle/openpgp/test/PGPAeadTest.java + rm -f src/org/bouncycastle/openpgp/test/BytesBooleansTest.java + rm -f src/org/bouncycastle/openpgp/test/BcImplProviderTest.java + rm -f src/org/bouncycastle/openpgp/test/BcpgGeneralTest.java + rm -f src/org/bouncycastle/openpgp/test/OpenPGPTest.java + rm -f src/org/bouncycastle/openpgp/test/OperatorBcTest.java + rm -f src/org/bouncycastle/openpgp/test/PGPGeneralTest.java find src -name AllTests.java -exec rm {} \; @@ -688,18 +722,26 @@ then echo "compiling" + ( + cd src + sh ../../../../../scripts/jdk1.2ed.sh > /dev/null 2>&1 + sh ../../../../../scripts/jdk1.1ed.sh > /dev/null 2>&1 + ) - for i in src/org/bouncycastle/pqc/jcajce/provider/*/*.java src/org/bouncycastle/pqc/crypto/*/*.java src/org/bouncycastle/bcpg/*.java src/org/bouncycastle/openpgp/*.java src/org/bouncycastle/openpgp/test/*.java - do -ed $i <<%% -g/.Override/d + ed src/org/bouncycastle/gpg/SExpression.java <<% +g/\.\.\. /s//[]/ w q -%% - done +% - ed src/org/bouncycastle/gpg/SExpression.java <<% -g/\.\.\. /s//[]/ + ed src/org/bouncycastle/openpgp/PGPSignature.java <<% +g/private.*final.*;/s/final// +w +q +% + + ed src/org/bouncycastle/openpgp/operator/jcajce/JceAEADUtil.java <<% +g/private.*final.*;/s/final// w q % @@ -714,6 +756,12 @@ q g/private.*final.*;/s/final// w q +% + + ed src/org/bouncycastle/bcpg/sig/PreferredAEADCiphersuites.java <<% +g/private.*final.*;/s/final// +w +q % ed src/org/bouncycastle/bcpg/ArmoredOutputStream.java <<% @@ -770,8 +818,16 @@ w q % - (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:../../../../jce-jdk11-$base/classes:$JDK11PATH/lib/classes.zip bcpg/*.java bcpg/*/*.java openpgp/*.java ) - (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:../../../../jce-jdk11-$base/classes:$JDK11PATH/lib/classes.zip openpgp/*/*.java openpgp/*/*/*.java ) + ed src/org/bouncycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java <<% +g/private.*final.*;/s/final// +w +q +% + + (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:../../../../jce-jdk11-$base/classes:$JDK11PATH/lib/classes.zip bcpg/*.java ) + (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:../../../../jce-jdk11-$base/classes:$JDK11PATH/lib/classes.zip bcpg/*/*.java openpgp/*.java ) + (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:../../../../jce-jdk11-$base/classes:$JDK11PATH/lib/classes.zip openpgp/*/*.java ) + (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:../../../../jce-jdk11-$base/classes:$JDK11PATH/lib/classes.zip openpgp/*/*/*.java ) (cd src/org/bouncycastle; javac -d ../../../classes -classpath ../../../classes:../../../src:../../../../jce-jdk11-$base/classes:$JDK11PATH/lib/classes.zip openpgp/test/RegressionTest.java ) cp ../../../../pg/src/test/resources/org/bouncycastle/openpgp/test/bigpub.asc classes/org/bouncycastle/openpgp/test/bigpub.asc diff --git a/build1-2 b/build1-2 index 2a651ca14e..144b0d0a60 100644 --- a/build1-2 +++ b/build1-2 @@ -47,6 +47,7 @@ mkdir -p $jdk12src ((cd pkix/src/test/jdk1.3 && tar cf - * ) | (cd $jdk12src && tar xf -)) ((cd pkix/src/main/jdk1.2 && tar cf - * ) | (cd $jdk12src && tar xf -)) ((cd pg/src/main/java && tar cf - * ) | (cd $jdk12src && tar xf -)) +((cd pg/src/main/jdk1.5 && tar cf - * ) | (cd $jdk12src && tar xf -)) ((cd pg/src/main/jdk1.4 && tar cf - * ) | (cd $jdk12src && tar xf -)) ((cd pg/src/main/jdk1.3 && tar cf - * ) | (cd $jdk12src && tar xf -)) ((cd pg/src/test/java && tar cf - * ) | (cd $jdk12src && tar xf -)) @@ -67,6 +68,7 @@ find $jdk12src -name "*.java" -exec scripts/usejcecert.sh \{\} \; rm org/bouncycastle/test/PrintTestResult.java rm org/bouncycastle/pqc/legacy/crypto/qtesla/QTeslaKeyEncodingTests.java rm org/bouncycastle/pqc/crypto/util/PQCOtherInfoGenerator.java + rm -rf org/bouncycastle/test/JVMVersionTest.java rm -rf org/bouncycastle/crypto/test/ntru rm -rf org/bouncycastle/pqc/legacy/math/ntru rm -rf org/bouncycastle/pqc/math/test @@ -115,6 +117,14 @@ find $jdk12src -name "*.java" -exec scripts/usejcecert.sh \{\} \; rm org/bouncycastle/pkix/jcajce/Revocation*.java rm org/bouncycastle/pkix/jcajce/X509RevocationChecker.java rm org/bouncycastle/pkix/jcajce/RFC3280*.java + rm org/bouncycastle/pkix/jcajce/CertPath*.java + rm org/bouncycastle/pkix/jcajce/X509CertSel*.java + rm org/bouncycastle/pkix/jcajce/X509CertStoreSel*.java + rm org/bouncycastle/pkix/jcajce/X509CRLStoreSel*.java + rm org/bouncycastle/pkix/jcajce/PKIXCRL*.java + rm org/bouncycastle/pkix/jcajce/PKIXCert*.java + rm org/bouncycastle/pkix/jcajce/PKIXPolicyN*.java + rm -r org/bouncycastle/pkix/util rm org/bouncycastle/cms/jcajce/JceKeyTransAuthEnvelopedRecipient.java rm org/bouncycastle/cms/jcajce/JceAADStream.java rm org/bouncycastle/jcajce/provider/keystore/util/ParameterUtil.java @@ -196,12 +206,16 @@ find $jdk12src -name "*.java" -exec scripts/usejcecert.sh \{\} \; rm org/bouncycastle/pkix/test/TestUtil.java rm org/bouncycastle/cert/cmp/test/PQC*.java rm org/bouncycastle/cert/cmp/test/Elgamal*.java + rm org/bouncycastle/cert/cmp/test/InvalidMessagesTest.java + rm org/bouncycastle/cert/test/GOSTR3410_2012_256GenerateCertificate.java rm org/bouncycastle/cert/ocsp/test/PKIXRevocationTest.java rm -r org/bouncycastle/crypto/test/BigSkippingCipherTest.java rm -rf org/bouncycastle/openssl/test + rm -rf org/bouncycastle/jcajce/provider/asymmetric/compositesignatures rm -rf org/bouncycastle/jcajce/provider/asymmetric/dstu rm -rf org/bouncycastle/jcajce/provider/asymmetric/DSTU*.java rm -rf org/bouncycastle/jcajce/provider/asymmetric/util/EC5*.java + rm -rf org/bouncycastle/jcajce/provider/asymmetric/CompositeSignatures.java rm org/bouncycastle/asn1/test/EnumeratedTest.java rm -rf org/bouncycastle/pqc/crypto/test/QT*.java rm -rf org/bouncycastle/pqc/crypto/test/SphincsPlusTest.java @@ -224,10 +238,16 @@ find $jdk12src -name "*.java" -exec scripts/usejcecert.sh \{\} \; rm -rf org/bouncycastle/cert/test/ConverterTest* rm -rf org/bouncycastle/cert/test/CertPathLoopTest.java rm -rf org/bouncycastle/cert/test/Bc* + rm -rf org/bouncycastle/cert/test/Delta* rm -rf org/bouncycastle/tsp/GenTimeAccuracyUnit* rm -rf org/bouncycastle/tsp/TimeStampTokenInfoUnit* rm org/bouncycastle/openpgp/test/BcPGPEd25519JcaKeyPairConversionTest.java rm org/bouncycastle/openpgp/test/ArmoredOutputStreamUTF8Test.java + rm org/bouncycastle/openpgp/test/PGPAeadTest.java + rm org/bouncycastle/openpgp/test/BytesBooleansTest.java + rm org/bouncycastle/openpgp/test/BcImplProviderTest.java + rm org/bouncycastle/openpgp/test/BcpgGeneralTest.java + rm org/bouncycastle/openpgp/test/OpenPGPTest.java sh ../../scripts/jdk1.2ed.sh diff --git a/build1-5to1-8 b/build1-5to1-8 index c8c074671d..cea656a8a8 100644 --- a/build1-5to1-8 +++ b/build1-5to1-8 @@ -10,6 +10,10 @@ if [ "${JDKPATH}" = "" ] then JDKPATH=/usr/lib/jvm/java-8-openjdk-amd64 fi +if [ "${JDK5PATH}" = "" ] +then + JDK5PATH=/usr/lib/jvm/java-1.5.0-oracle-i586/ +fi JAVA_HOME=$JDKPATH export JAVA_HOME @@ -19,6 +23,15 @@ export PATH if [ "$1" = "test" ] then + # + # Note: always do a full build before running test + # + JAVA_HOME=$JDK5PATH + export JAVA_HOME + + PATH=$JDK5PATH/bin:$PATH + export PATH + ant -f ant/jdk15+.xml test elif [ "$1" = "clean" ] then @@ -29,14 +42,14 @@ else ant -f ant/jdk15+.xml build ant -f ant/jdk15+.xml zip-src fi -fi - -if [ -f build/artifacts/jdk1.5/jars/bcprov-jdk15on*.jar ] -then - tar cf - prov/src/main/resources/META-INF | (cd build/artifacts/jdk1.5/jars/; tar xf -) + if [ -f build/artifacts/jdk1.5/jars/bcprov-jdk15to18*.jar ] + then + tar cf - prov/src/main/resources/META-INF | (cd build/artifacts/jdk1.5/jars/; tar xf -) cd build/artifacts/jdk1.5/jars/ mv prov/src/main/resources/META-INF . - jar uf bcprov-jdk15on*.jar META-INF - jar uf bcprov-ext-jdk15on*.jar META-INF + jar uf bcprov-jdk15to18*.jar META-INF + jar uf bcprov-ext-jdk15to18*.jar META-INF rm -r prov META-INF + fi fi + diff --git a/build1-8+ b/build1-8+ index 9c848ca5ea..f99d5b0ac8 100644 --- a/build1-8+ +++ b/build1-8+ @@ -17,6 +17,12 @@ export JAVA_HOME PATH=$JDKPATH/bin:$PATH export PATH +if [ "${JAVA_VERSION_PREFIX}" = "" ] +then + JAVA_VERSION_PREFIX=1.8 + export JAVA_VERSION_PREFIX +fi + if [ "$1" = "test" ] then ant -f ant/jdk18+.xml test @@ -29,14 +35,14 @@ else ant -f ant/jdk18+.xml build ant -f ant/jdk18+.xml zip-src fi -fi - -if [ -f build/artifacts/jdk1.8/jars/bcprov-jdk15on*.jar ] -then + if [ -f build/artifacts/jdk1.8/jars/bcprov-jdk18on*.jar ] + then tar cf - prov/src/main/resources/META-INF | (cd build/artifacts/jdk1.8/jars/; tar xf -) cd build/artifacts/jdk1.8/jars/ mv prov/src/main/resources/META-INF . jar uf bcprov-jdk18on*.jar META-INF jar uf bcprov-ext-jdk18on*.jar META-INF rm -r prov META-INF + fi fi + diff --git a/ci/build_1_8.sh b/ci/build_1_8.sh new file mode 100644 index 0000000000..d3413d74a8 --- /dev/null +++ b/ci/build_1_8.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -e + +# +# This script is for running inside the docker container +# + +cd /workspace/bc-java +source ci/common.sh + +export JAVA_HOME=`openjdk_8` +export export PATH=$JAVA_HOME/bin:$PATH +export JDKPATH=$JAVA_HOME + +export PATH=$PATH:`ant-bin-1-10` + +sh build1-8+ \ No newline at end of file diff --git a/ci/check_java.sh b/ci/check_java.sh new file mode 100644 index 0000000000..4e26b7a96f --- /dev/null +++ b/ci/check_java.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +set -e + +# +# This script is for running inside the docker container +# + +cd /workspace/bc-java +source ci/common.sh + +export BC_JDK8=`openjdk_8` +export BC_JDK11=`openjdk_11` +export BC_JDK15=`openjdk_15` +export BC_JDK17=`openjdk_17` +export BC_JDK21=`openjdk_21` + +export JAVA_HOME=`openjdk_17` +export PATH=$JAVA_HOME/bin:$PATH + +# Checkstyle +./gradlew check -x test; + + +# OSGI scanner only, no testing +./gradlew clean build -x test +./osgi_scan.sh + diff --git a/ci/common.sh b/ci/common.sh new file mode 100644 index 0000000000..2817e651e7 --- /dev/null +++ b/ci/common.sh @@ -0,0 +1,3 @@ + +export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8 + diff --git a/ci/test_11.sh b/ci/test_11.sh new file mode 100644 index 0000000000..adc317b84d --- /dev/null +++ b/ci/test_11.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -e + +# +# This script is for running inside the docker container +# + +cd /workspace/bc-java +source ci/common.sh + +export BC_JDK8=`openjdk_8` +export BC_JDK11=`openjdk_11` +export BC_JDK17=`openjdk_17` +export BC_JDK21=`openjdk_21` + + +export JAVA_HOME=`openjdk_17` +export PATH=$JAVA_HOME/bin:$PATH + +./gradlew -stacktrace clean build test11 -x test + + + + diff --git a/ci/test_17.sh b/ci/test_17.sh new file mode 100644 index 0000000000..7b411d8b1d --- /dev/null +++ b/ci/test_17.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -e + +# +# This script is for running inside the docker container +# + +cd /workspace/bc-java +source ci/common.sh + +export BC_JDK8=`openjdk_8` +export BC_JDK11=`openjdk_11` +export BC_JDK17=`openjdk_17` +export BC_JDK21=`openjdk_21` + + +export JAVA_HOME=`openjdk_17` +export PATH=$JAVA_HOME/bin:$PATH + +./gradlew -stacktrace clean build test17 -x test + + + + diff --git a/ci/test_21.sh b/ci/test_21.sh new file mode 100644 index 0000000000..afea144f79 --- /dev/null +++ b/ci/test_21.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -e + +# +# This script is for running inside the docker container +# + +cd /workspace/bc-java +source ci/common.sh + +export BC_JDK8=`openjdk_8` +export BC_JDK11=`openjdk_11` +export BC_JDK17=`openjdk_17` +export BC_JDK21=`openjdk_21` + + +export JAVA_HOME=`openjdk_17` +export PATH=$JAVA_HOME/bin:$PATH + +./gradlew -stacktrace clean build test21 -x test + + + + diff --git a/ci/test_8.sh b/ci/test_8.sh new file mode 100644 index 0000000000..ee489af648 --- /dev/null +++ b/ci/test_8.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -e + +# +# This script is for running inside the docker container +# + +cd /workspace/bc-java +source ci/common.sh + +export BC_JDK8=`openjdk_8` +export BC_JDK11=`openjdk_11` +export BC_JDK17=`openjdk_17` +export BC_JDK21=`openjdk_21` + + +export JAVA_HOME=`openjdk_17` +export PATH=$JAVA_HOME/bin:$PATH + +./gradlew -stacktrace clean build -x test11 test17 test21 + + + + diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index c3d61fa62e..1c19a546c1 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -31,6 +31,10 @@ + + + + diff --git a/config/checkstyle/lib/methodchecker-1.0.0-sources.jar b/config/checkstyle/lib/methodchecker-1.0.0-sources.jar new file mode 100644 index 0000000000..783a418586 Binary files /dev/null and b/config/checkstyle/lib/methodchecker-1.0.0-sources.jar differ diff --git a/config/checkstyle/lib/methodchecker.jar b/config/checkstyle/lib/methodchecker-1.0.0.jar similarity index 100% rename from config/checkstyle/lib/methodchecker.jar rename to config/checkstyle/lib/methodchecker-1.0.0.jar diff --git a/config/nohttp/suppressions.xml b/config/nohttp/suppressions.xml index 6110921148..2e7f160b17 100644 --- a/config/nohttp/suppressions.xml +++ b/config/nohttp/suppressions.xml @@ -21,5 +21,5 @@ - + diff --git a/core/build.gradle b/core/build.gradle index f00157a078..d3f9400fdb 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -6,4 +6,10 @@ dependencies { } application { mainClass.set("org.bouncycastle.crypto.fpe.SP80038GMicroBenchmark") -} \ No newline at end of file +} + + +test { + forkEvery = 1; + maxParallelForks = 8; +} diff --git a/core/src/main/j2me/java/math/BigInteger.java b/core/src/main/j2me/java/math/BigInteger.java index 66fd2a7202..7b33e0ce1c 100644 --- a/core/src/main/j2me/java/math/BigInteger.java +++ b/core/src/main/j2me/java/math/BigInteger.java @@ -426,13 +426,13 @@ private int[] makeMagnitude(byte[] bval, int sign) // strip leading -1's for (firstSignificant = 0; firstSignificant < bval.length - 1 - && bval[firstSignificant] == 0xff; firstSignificant++); + && bval[firstSignificant] == (byte)0xff; firstSignificant++); int nBytes = bval.length; boolean leadingByte = false; // check for -2^(n-1) - if (bval[firstSignificant] == 0x80) { + if (bval[firstSignificant] == (byte)0x80) { for (i = firstSignificant + 1; i < bval.length; i++) { if (bval[i] != 0) { break; diff --git a/core/src/main/j2me/org/bouncycastle/asn1/cms/Time.java b/core/src/main/j2me/org/bouncycastle/asn1/cms/Time.java index 2477d6f261..7819d4ca95 100644 --- a/core/src/main/j2me/org/bouncycastle/asn1/cms/Time.java +++ b/core/src/main/j2me/org/bouncycastle/asn1/cms/Time.java @@ -20,7 +20,12 @@ public static Time getInstance( ASN1TaggedObject obj, boolean explicit) { - return getInstance(obj.getObject()); // must be explicitly tagged + if (!explicit) + { + throw new IllegalArgumentException("choice item must be explicitly tagged"); + } + + return getInstance(obj.getExplicitBaseObject()); } public Time( diff --git a/core/src/main/j2me/org/bouncycastle/asn1/x509/Time.java b/core/src/main/j2me/org/bouncycastle/asn1/x509/Time.java index c723e8d2ca..027d0da345 100644 --- a/core/src/main/j2me/org/bouncycastle/asn1/x509/Time.java +++ b/core/src/main/j2me/org/bouncycastle/asn1/x509/Time.java @@ -20,7 +20,12 @@ public static Time getInstance( ASN1TaggedObject obj, boolean explicit) { - return getInstance(obj.getObject()); // must be explicitly tagged + if (!explicit) + { + throw new IllegalArgumentException("choice item must be explicitly tagged"); + } + + return getInstance(obj.getExplicitBaseObject()); } public Time( diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java b/core/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java deleted file mode 100644 index 042d58f237..0000000000 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java +++ /dev/null @@ -1,209 +0,0 @@ -package org.bouncycastle.asn1; - -import java.io.IOException; - -/** - * Base class for an ASN.1 ApplicationSpecific object - * - * @deprecated Will be removed. Change application code to handle as {@link ASN1TaggedObject} only, testing - * for the expected {@link ASN1TaggedObject#getTagClass() tag class} of - * {@link BERTags#APPLICATION} in relevant objects before using. If using a - * {@link ASN1StreamParser stream parser}, handle application-tagged objects using - * {@link ASN1TaggedObjectParser} in the usual way, again testing for a - * {@link ASN1TaggedObjectParser#getTagClass() tag class} of {@link BERTags#APPLICATION}. - */ -public abstract class ASN1ApplicationSpecific - extends ASN1TaggedObject - implements ASN1ApplicationSpecificParser -{ - /** - * Return an ASN1ApplicationSpecific from the passed in object, which may be a byte array, or null. - * - * @param obj the object to be converted. - * @return obj's representation as an ASN1ApplicationSpecific object. - */ - public static ASN1ApplicationSpecific getInstance(Object obj) - { - if (obj == null || obj instanceof ASN1ApplicationSpecific) - { - return (ASN1ApplicationSpecific)obj; - } - else if (obj instanceof byte[]) - { - try - { - return getInstance(ASN1Primitive.fromByteArray((byte[])obj)); - } - catch (IOException e) - { - throw new IllegalArgumentException("Failed to construct object from byte[]: " + e.getMessage()); - } - } - - throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); - } - - final ASN1TaggedObject taggedObject; - - ASN1ApplicationSpecific(ASN1TaggedObject taggedObject) - { - super(taggedObject.explicitness, checkTagClass(taggedObject.tagClass), taggedObject.tagNo, taggedObject.obj); - - this.taggedObject = taggedObject; - } - - /** - * Return the tag number associated with this object, - * - * @return the application tag number. - */ - public int getApplicationTag() - { - return taggedObject.getTagNo(); - } - - /** - * Return the contents of this object as a byte[] - * - * @return the encoded contents of the object. - */ - public byte[] getContents() - { - return taggedObject.getContents(); - } - - /** - * Return the enclosed object assuming explicit tagging. - * - * @return the resulting object - * @throws IOException if reconstruction fails. - */ - public ASN1Primitive getEnclosedObject() throws IOException - { - return taggedObject.getBaseObject().toASN1Primitive(); - } - - /** - * Return the enclosed object assuming implicit tagging. - * - * @param tagNo the type tag that should be applied to the object's contents. - * @return the resulting object - * @throws IOException if reconstruction fails. - */ - public ASN1Primitive getObject(int tagNo) throws IOException - { - return taggedObject.getBaseUniversal(false, tagNo); - } - - public ASN1Encodable getObjectParser(int tag, boolean isExplicit) throws IOException - { - throw new ASN1Exception("this method only valid for CONTEXT_SPECIFIC tags"); - } - - public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException - { - return taggedObject.parseBaseUniversal(declaredExplicit, baseTagNo); - } - - public ASN1Encodable parseExplicitBaseObject() throws IOException - { - return taggedObject.parseExplicitBaseObject(); - } - - public ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException - { - return taggedObject.parseExplicitBaseTagged(); - } - - public ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException - { - return taggedObject.parseImplicitBaseTagged(baseTagClass, baseTagNo); - } - - public boolean hasApplicationTag(int tagNo) - { - return this.tagNo == tagNo; - } - - public boolean hasContextTag(int tagNo) - { - return false; - } - - /** - * ASN1ApplicationSpecific uses an internal ASN1TaggedObject for the - * implementation, and will soon be deprecated in favour of using - * ASN1TaggedObject with a tag class of {@link BERTags#APPLICATION}. This method - * lets you get the internal ASN1TaggedObject so that client code can begin the - * migration. - */ - public ASN1TaggedObject getTaggedObject() - { - return taggedObject; - } - - /** - * Return true if the object is marked as constructed, false otherwise. - * - * @return true if constructed, otherwise false. - */ - public boolean isConstructed() - { - return taggedObject.isConstructed(); - } - - public ASN1Encodable readObject() throws IOException - { - // NOTE: No way to say you're looking for an implicitly-tagged object via ASN1ApplicationSpecificParser - return parseExplicitBaseObject(); - } - - boolean encodeConstructed() - { - return taggedObject.encodeConstructed(); - } - - int encodedLength(boolean withTag) throws IOException - { - return taggedObject.encodedLength(withTag); - } - - void encode(ASN1OutputStream out, boolean withTag) throws IOException - { - taggedObject.encode(out, withTag); - } - - String getASN1Encoding() - { - return taggedObject.getASN1Encoding(); - } - - ASN1Sequence rebuildConstructed(ASN1Primitive primitive) - { - return taggedObject.rebuildConstructed(primitive); - } - - ASN1TaggedObject replaceTag(int tagClass, int tagNo) - { - return taggedObject.replaceTag(tagClass, tagNo); - } - - ASN1Primitive toDERObject() - { - return new DERApplicationSpecific((ASN1TaggedObject)taggedObject.toDERObject()); - } - - ASN1Primitive toDLObject() - { - return new DLApplicationSpecific((ASN1TaggedObject)taggedObject.toDLObject()); - } - - private static int checkTagClass(int tagClass) - { - if (BERTags.APPLICATION != tagClass) - { - throw new IllegalArgumentException(); - } - return tagClass; - } -} diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java b/core/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java deleted file mode 100644 index 4a5bba1891..0000000000 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.bouncycastle.asn1; - -import java.io.IOException; - -/** - * Interface to parse ASN.1 ApplicationSpecific objects. - * - * @deprecated Test for {@link ASN1TaggedObjectParser} with {@link ASN1TaggedObjectParser#getTagClass() tag - * class} of {@link BERTags#APPLICATION} instead. - */ -public interface ASN1ApplicationSpecificParser - extends ASN1TaggedObjectParser -{ - /** - * Read the next object in the parser. - * - * @return an ASN1Encodable - * @throws IOException on a parsing or decoding error. - */ - ASN1Encodable readObject() - throws IOException; -} diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1BMPString.java b/core/src/main/java/org/bouncycastle/asn1/ASN1BMPString.java index 7cef2b05aa..6b1fb1c928 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1BMPString.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1BMPString.java @@ -63,7 +63,7 @@ public static ASN1BMPString getInstance(Object obj) /** * Return a BMP String from a tagged object. * - * @param obj the tagged object holding the object we want + * @param taggedObject the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly tagged false * otherwise. * @exception IllegalArgumentException if the tagged object cannot be converted. diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1External.java b/core/src/main/java/org/bouncycastle/asn1/ASN1External.java index c24616445d..d75ced245b 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1External.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1External.java @@ -258,13 +258,9 @@ private static ASN1Primitive checkExternalContent(int tagNo, ASN1Primitive exter private static ASN1Primitive getExternalContent(ASN1TaggedObject encoding) { - int tagClass = encoding.getTagClass(), tagNo = encoding.getTagNo(); - if (BERTags.CONTEXT_SPECIFIC != tagClass) - { - throw new IllegalArgumentException("invalid tag: " + ASN1Util.getTagText(tagClass, tagNo)); - } + ASN1Util.checkContextTagClass(encoding); - switch (tagNo) + switch (encoding.getTagNo()) { case 0: return encoding.getExplicitBaseObject().toASN1Primitive(); @@ -273,7 +269,7 @@ private static ASN1Primitive getExternalContent(ASN1TaggedObject encoding) case 2: return ASN1BitString.getInstance(encoding, false); default: - throw new IllegalArgumentException("invalid tag: " + ASN1Util.getTagText(tagClass, tagNo)); + throw new IllegalArgumentException("invalid tag: " + ASN1Util.getTagText(encoding)); } } diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java b/core/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java index ff7e3e09d1..9dc4a45826 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java @@ -546,14 +546,21 @@ static ASN1Primitive createPrimitiveDERObject( case OBJECT_DESCRIPTOR: return ASN1ObjectDescriptor.createPrimitive(defIn.toByteArray()); case OBJECT_IDENTIFIER: + { + ASN1ObjectIdentifier.checkContentsLength(defIn.getRemaining()); // TODO Ideally only clone if we used a buffer return ASN1ObjectIdentifier.createPrimitive(getBuffer(defIn, tmpBuffers), true); + } case OCTET_STRING: return ASN1OctetString.createPrimitive(defIn.toByteArray()); case PRINTABLE_STRING: return ASN1PrintableString.createPrimitive(defIn.toByteArray()); case RELATIVE_OID: - return ASN1RelativeOID.createPrimitive(defIn.toByteArray(), false); + { + ASN1RelativeOID.checkContentsLength(defIn.getRemaining()); + // TODO Ideally only clone if we used a buffer + return ASN1RelativeOID.createPrimitive(getBuffer(defIn, tmpBuffers), true); + } case T61_STRING: return ASN1T61String.createPrimitive(defIn.toByteArray()); case UNIVERSAL_STRING: diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java b/core/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java index 97a308ca8d..61acea41af 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java @@ -22,8 +22,24 @@ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString) } }; + /** + * Implementation limit on the length of the contents octets for an Object Identifier. + *

    + * We adopt the same value used by OpenJDK. In theory there is no limit on the length of the contents, or + * the number of subidentifiers, or the length of individual subidentifiers. In practice, supporting + * arbitrary lengths can lead to issues, e.g. denial-of-service attacks when attempting to convert a + * parsed value to its (decimal) string form. + */ + private static final int MAX_CONTENTS_LENGTH = 4096; + private static final int MAX_IDENTIFIER_LENGTH = MAX_CONTENTS_LENGTH * 4 + 1; + public static ASN1ObjectIdentifier fromContents(byte[] contents) { + if (contents == null) + { + throw new NullPointerException("'contents' cannot be null"); + } + return createPrimitive(contents, true); } @@ -80,9 +96,9 @@ public static ASN1ObjectIdentifier getInstance(ASN1TaggedObject taggedObject, bo * * - see https://github.com/bcgit/bc-java/issues/1015 */ - if (!explicit && !taggedObject.isParsed()) + if (!explicit && !taggedObject.isParsed() && taggedObject.hasContextTag()) { - ASN1Primitive base = taggedObject.getObject(); + ASN1Primitive base = taggedObject.getBaseObject().toASN1Primitive(); if (!(base instanceof ASN1ObjectIdentifier)) { return fromContents(ASN1OctetString.getInstance(base).getOctets()); @@ -92,17 +108,244 @@ public static ASN1ObjectIdentifier getInstance(ASN1TaggedObject taggedObject, bo return (ASN1ObjectIdentifier)TYPE.getContextInstance(taggedObject, explicit); } + public static ASN1ObjectIdentifier tryFromID(String identifier) + { + if (identifier == null) + { + throw new NullPointerException("'identifier' cannot be null"); + } + if (identifier.length() <= MAX_IDENTIFIER_LENGTH && isValidIdentifier(identifier)) + { + byte[] contents = parseIdentifier(identifier); + if (contents.length <= MAX_CONTENTS_LENGTH) + { + return new ASN1ObjectIdentifier(contents, identifier); + } + } + + return null; + } + private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7F; private static final ConcurrentMap pool = new ConcurrentHashMap(); - private final String identifier; - private byte[] contents; + private final byte[] contents; + private String identifier; + + /** + * Create an OID based on the passed in String. + * + * @param identifier a string representation of an OID. + */ + public ASN1ObjectIdentifier(String identifier) + { + checkIdentifier(identifier); + + byte[] contents = parseIdentifier(identifier); + checkContentsLength(contents.length); + + this.contents = contents; + this.identifier = identifier; + } + + private ASN1ObjectIdentifier(byte[] contents, String identifier) + { + this.contents = contents; + this.identifier = identifier; + } + + /** + * Return an OID that creates a branch under the current one. + * + * @param branchID node numbers for the new branch. + * @return the OID for the new created branch. + */ + public ASN1ObjectIdentifier branch(String branchID) + { + ASN1RelativeOID.checkIdentifier(branchID); + + byte[] contents; + if (branchID.length() <= 2) + { + checkContentsLength(this.contents.length + 1); + int subID = branchID.charAt(0) - '0'; + if (branchID.length() == 2) + { + subID *= 10; + subID += branchID.charAt(1) - '0'; + } + + contents = Arrays.append(this.contents, (byte)subID); + } + else + { + byte[] branchContents = ASN1RelativeOID.parseIdentifier(branchID); + checkContentsLength(this.contents.length + branchContents.length); + + contents = Arrays.concatenate(this.contents, branchContents); + } + + String rootID = getId(); + String identifier = rootID + "." + branchID; + + return new ASN1ObjectIdentifier(contents, identifier); + } + + /** + * Return the OID as a string. + * + * @return the string representation of the OID carried by this object. + */ + public synchronized String getId() + { + if (identifier == null) + { + identifier = parseContents(contents); + } + + return identifier; + } + + /** + * Return true if this oid is an extension of the passed in branch - stem. + * + * @param stem the arc or branch that is a possible parent. + * @return true if the branch is on the passed in stem, false otherwise. + */ + public boolean on(ASN1ObjectIdentifier stem) + { + byte[] contents = this.contents, stemContents = stem.contents; + int stemLength = stemContents.length; + + return contents.length > stemLength + && Arrays.areEqual(contents, 0, stemLength, stemContents, 0, stemLength); + } + + boolean encodeConstructed() + { + return false; + } + + int encodedLength(boolean withTag) + { + return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length); + } + + void encode(ASN1OutputStream out, boolean withTag) throws IOException + { + out.writeEncodingDL(withTag, BERTags.OBJECT_IDENTIFIER, contents); + } + + public int hashCode() + { + return Arrays.hashCode(contents); + } + + boolean asn1Equals(ASN1Primitive other) + { + if (this == other) + { + return true; + } + if (!(other instanceof ASN1ObjectIdentifier)) + { + return false; + } + + ASN1ObjectIdentifier that = (ASN1ObjectIdentifier)other; + + return Arrays.areEqual(this.contents, that.contents); + } + + public String toString() + { + return getId(); + } + + static void checkContentsLength(int contentsLength) + { + if (contentsLength > MAX_CONTENTS_LENGTH) + { + throw new IllegalArgumentException("exceeded OID contents length limit"); + } + } + + static void checkIdentifier(String identifier) + { + if (identifier == null) + { + throw new NullPointerException("'identifier' cannot be null"); + } + if (identifier.length() > MAX_IDENTIFIER_LENGTH) + { + throw new IllegalArgumentException("exceeded OID contents length limit"); + } + if (!isValidIdentifier(identifier)) + { + throw new IllegalArgumentException("string " + identifier + " not a valid OID"); + } + } + + static ASN1ObjectIdentifier createPrimitive(byte[] contents, boolean clone) + { + checkContentsLength(contents.length); + + final OidHandle hdl = new OidHandle(contents); + ASN1ObjectIdentifier oid = pool.get(hdl); + if (oid != null) + { + return oid; + } + + if (!ASN1RelativeOID.isValidContents(contents)) + { + throw new IllegalArgumentException("invalid OID contents"); + } + + return new ASN1ObjectIdentifier(clone ? Arrays.clone(contents) : contents, null); + } + + private static boolean isValidIdentifier(String identifier) + { + if (identifier.length() < 3 || identifier.charAt(1) != '.') + { + return false; + } + + char first = identifier.charAt(0); + if (first < '0' || first > '2') + { + return false; + } + + if (!ASN1RelativeOID.isValidIdentifier(identifier, 2)) + { + return false; + } + + if (first == '2') + { + return true; + } + + if (identifier.length() == 3 || identifier.charAt(3) == '.') + { + return true; + } + + if (identifier.length() == 4 || identifier.charAt(4) == '.') + { + return identifier.charAt(2) < '4'; + } + + return false; + } - ASN1ObjectIdentifier(byte[] contents, boolean clone) + private static String parseContents(byte[] contents) { - StringBuffer objId = new StringBuffer(); + StringBuilder objId = new StringBuilder(); long value = 0; BigInteger bigValue = null; boolean first = true; @@ -172,92 +415,23 @@ else if (value < 80) } } - this.identifier = objId.toString(); - this.contents = clone ? Arrays.clone(contents) : contents; - } - - /** - * Create an OID based on the passed in String. - * - * @param identifier a string representation of an OID. - */ - public ASN1ObjectIdentifier( - String identifier) - { - if (identifier == null) - { - throw new NullPointerException("'identifier' cannot be null"); - } - if (!isValidIdentifier(identifier)) - { - throw new IllegalArgumentException("string " + identifier + " not an OID"); - } - - this.identifier = identifier; - } - - /** - * Create an OID that creates a branch under the current one. - * - * @param branchID node numbers for the new branch. - * @return the OID for the new created branch. - */ - ASN1ObjectIdentifier(ASN1ObjectIdentifier oid, String branchID) - { - if (!ASN1RelativeOID.isValidIdentifier(branchID, 0)) - { - throw new IllegalArgumentException("string " + branchID + " not a valid OID branch"); - } - - this.identifier = oid.getId() + "." + branchID; - } - - /** - * Return the OID as a string. - * - * @return the string representation of the OID carried by this object. - */ - public String getId() - { - return identifier; - } - - /** - * Return an OID that creates a branch under the current one. - * - * @param branchID node numbers for the new branch. - * @return the OID for the new created branch. - */ - public ASN1ObjectIdentifier branch(String branchID) - { - return new ASN1ObjectIdentifier(this, branchID); - } - - /** - * Return true if this oid is an extension of the passed in branch - stem. - * - * @param stem the arc or branch that is a possible parent. - * @return true if the branch is on the passed in stem, false otherwise. - */ - public boolean on(ASN1ObjectIdentifier stem) - { - String id = getId(), stemId = stem.getId(); - return id.length() > stemId.length() && id.charAt(stemId.length()) == '.' && id.startsWith(stemId); + return objId.toString(); } - private void doOutput(ByteArrayOutputStream aOut) + private static byte[] parseIdentifier(String identifier) { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OIDTokenizer tok = new OIDTokenizer(identifier); int first = Integer.parseInt(tok.nextToken()) * 40; String secondToken = tok.nextToken(); if (secondToken.length() <= 18) { - ASN1RelativeOID.writeField(aOut, first + Long.parseLong(secondToken)); + ASN1RelativeOID.writeField(bOut, first + Long.parseLong(secondToken)); } else { - ASN1RelativeOID.writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first))); + ASN1RelativeOID.writeField(bOut, new BigInteger(secondToken).add(BigInteger.valueOf(first))); } while (tok.hasMoreTokens()) @@ -265,85 +439,15 @@ private void doOutput(ByteArrayOutputStream aOut) String token = tok.nextToken(); if (token.length() <= 18) { - ASN1RelativeOID.writeField(aOut, Long.parseLong(token)); + ASN1RelativeOID.writeField(bOut, Long.parseLong(token)); } else { - ASN1RelativeOID.writeField(aOut, new BigInteger(token)); + ASN1RelativeOID.writeField(bOut, new BigInteger(token)); } } - } - - private synchronized byte[] getContents() - { - if (contents == null) - { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - doOutput(bOut); - - contents = bOut.toByteArray(); - } - - return contents; - } - - boolean encodeConstructed() - { - return false; - } - int encodedLength(boolean withTag) - { - return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContents().length); - } - - void encode(ASN1OutputStream out, boolean withTag) throws IOException - { - out.writeEncodingDL(withTag, BERTags.OBJECT_IDENTIFIER, getContents()); - } - - public int hashCode() - { - return identifier.hashCode(); - } - - boolean asn1Equals( - ASN1Primitive o) - { - if (o == this) - { - return true; - } - - if (!(o instanceof ASN1ObjectIdentifier)) - { - return false; - } - - return identifier.equals(((ASN1ObjectIdentifier)o).identifier); - } - - public String toString() - { - return getId(); - } - - private static boolean isValidIdentifier( - String identifier) - { - if (identifier.length() < 3 || identifier.charAt(1) != '.') - { - return false; - } - - char first = identifier.charAt(0); - if (first < '0' || first > '2') - { - return false; - } - - return ASN1RelativeOID.isValidIdentifier(identifier, 2); + return bOut.toByteArray(); } /** @@ -358,20 +462,27 @@ private static boolean isValidIdentifier( */ public ASN1ObjectIdentifier intern() { - final OidHandle hdl = new OidHandle(getContents()); + final OidHandle hdl = new OidHandle(contents); ASN1ObjectIdentifier oid = pool.get(hdl); if (oid == null) { - oid = pool.putIfAbsent(hdl, this); - if (oid == null) + synchronized (pool) { - oid = this; + if (!pool.containsKey(hdl)) + { + pool.put(hdl, this); + return this; + } + else + { + return pool.get(hdl); + } } } return oid; } - private static class OidHandle + static class OidHandle { private final int key; private final byte[] contents; @@ -397,15 +508,4 @@ public boolean equals(Object o) return false; } } - - static ASN1ObjectIdentifier createPrimitive(byte[] contents, boolean clone) - { - final OidHandle hdl = new OidHandle(contents); - ASN1ObjectIdentifier oid = pool.get(hdl); - if (oid == null) - { - return new ASN1ObjectIdentifier(contents, clone); - } - return oid; - } } diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java b/core/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java index e73a4582c6..896f56f94d 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java @@ -212,6 +212,11 @@ public byte[] getOctets() return string; } + public int getOctetsLength() + { + return getOctets().length; + } + public int hashCode() { return Arrays.hashCode(this.getOctets()); diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1PrintableString.java b/core/src/main/java/org/bouncycastle/asn1/ASN1PrintableString.java index c340015d82..a859b7dc97 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1PrintableString.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1PrintableString.java @@ -82,7 +82,7 @@ public static ASN1PrintableString getInstance(Object obj) /** * Return a Printable String from a tagged object. * - * @param obj the tagged object holding the object we want + * @param taggedObject the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1RelativeOID.java b/core/src/main/java/org/bouncycastle/asn1/ASN1RelativeOID.java index b107cb2e2f..aa75ace012 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1RelativeOID.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1RelativeOID.java @@ -3,6 +3,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import org.bouncycastle.util.Arrays; @@ -17,8 +19,24 @@ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString) } }; + /** + * Implementation limit on the length of the contents octets for a Relative OID. + *

    + * We adopt the same value used by OpenJDK for Object Identifier. In theory there is no limit on the + * length of the contents, or the number of subidentifiers, or the length of individual subidentifiers. In + * practice, supporting arbitrary lengths can lead to issues, e.g. denial-of-service attacks when + * attempting to convert a parsed value to its (decimal) string form. + */ + private static final int MAX_CONTENTS_LENGTH = 4096; + private static final int MAX_IDENTIFIER_LENGTH = MAX_CONTENTS_LENGTH * 4 - 1; + public static ASN1RelativeOID fromContents(byte[] contents) { + if (contents == null) + { + throw new NullPointerException("'contents' cannot be null"); + } + return createPrimitive(contents, true); } @@ -57,114 +75,93 @@ public static ASN1RelativeOID getInstance(ASN1TaggedObject taggedObject, boolean return (ASN1RelativeOID)TYPE.getContextInstance(taggedObject, explicit); } - private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7F; - - private final String identifier; - private byte[] contents; - - public ASN1RelativeOID(String identifier) + public static ASN1RelativeOID tryFromID(String identifier) { if (identifier == null) { throw new NullPointerException("'identifier' cannot be null"); } - if (!isValidIdentifier(identifier, 0)) + if (identifier.length() <= MAX_IDENTIFIER_LENGTH && isValidIdentifier(identifier, 0)) { - throw new IllegalArgumentException("string " + identifier + " not a relative OID"); + byte[] contents = parseIdentifier(identifier); + if (contents.length <= MAX_CONTENTS_LENGTH) + { + return new ASN1RelativeOID(contents, identifier); + } } - this.identifier = identifier; + return null; } - ASN1RelativeOID(ASN1RelativeOID oid, String branchID) + private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7F; + + private static final ConcurrentMap pool = + new ConcurrentHashMap(); + + private final byte[] contents; + private String identifier; + + public ASN1RelativeOID(String identifier) { - if (!isValidIdentifier(branchID, 0)) - { - throw new IllegalArgumentException("string " + branchID + " not a valid OID branch"); - } + checkIdentifier(identifier); - this.identifier = oid.getId() + "." + branchID; + byte[] contents = parseIdentifier(identifier); + checkContentsLength(contents.length); + + this.contents = contents; + this.identifier = identifier; } - private ASN1RelativeOID(byte[] contents, boolean clone) + private ASN1RelativeOID(byte[] contents, String identifier) { - StringBuffer objId = new StringBuffer(); - long value = 0; - BigInteger bigValue = null; - boolean first = true; + this.contents = contents; + this.identifier = identifier; + } - for (int i = 0; i != contents.length; i++) - { - int b = contents[i] & 0xff; + public ASN1RelativeOID branch(String branchID) + { + checkIdentifier(branchID); - if (value <= LONG_LIMIT) + byte[] contents; + if (branchID.length() <= 2) + { + checkContentsLength(this.contents.length + 1); + int subID = branchID.charAt(0) - '0'; + if (branchID.length() == 2) { - value += b & 0x7F; - if ((b & 0x80) == 0) - { - if (first) - { - first = false; - } - else - { - objId.append('.'); - } - - objId.append(value); - value = 0; - } - else - { - value <<= 7; - } + subID *= 10; + subID += branchID.charAt(1) - '0'; } - else - { - if (bigValue == null) - { - bigValue = BigInteger.valueOf(value); - } - bigValue = bigValue.or(BigInteger.valueOf(b & 0x7F)); - if ((b & 0x80) == 0) - { - if (first) - { - first = false; - } - else - { - objId.append('.'); - } - objId.append(bigValue); - bigValue = null; - value = 0; - } - else - { - bigValue = bigValue.shiftLeft(7); - } - } + contents = Arrays.append(this.contents, (byte)subID); } + else + { + byte[] branchContents = parseIdentifier(branchID); + checkContentsLength(this.contents.length + branchContents.length); - this.identifier = objId.toString(); - this.contents = clone ? Arrays.clone(contents) : contents; - } + contents = Arrays.concatenate(this.contents, branchContents); + } - public ASN1RelativeOID branch(String branchID) - { - return new ASN1RelativeOID(this, branchID); + String rootID = getId(); + String identifier = rootID + "." + branchID; + + return new ASN1RelativeOID(contents, identifier); } - public String getId() + public synchronized String getId() { + if (identifier == null) + { + identifier = parseContents(contents); + } + return identifier; } public int hashCode() { - return identifier.hashCode(); + return Arrays.hashCode(contents); } public String toString() @@ -185,17 +182,17 @@ boolean asn1Equals(ASN1Primitive other) ASN1RelativeOID that = (ASN1RelativeOID)other; - return this.identifier.equals(that.identifier); + return Arrays.areEqual(this.contents, that.contents); } int encodedLength(boolean withTag) { - return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContents().length); + return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length); } void encode(ASN1OutputStream out, boolean withTag) throws IOException { - out.writeEncodingDL(withTag, BERTags.RELATIVE_OID, getContents()); + out.writeEncodingDL(withTag, BERTags.RELATIVE_OID, contents); } boolean encodeConstructed() @@ -203,40 +200,66 @@ boolean encodeConstructed() return false; } - private void doOutput(ByteArrayOutputStream aOut) + static void checkContentsLength(int contentsLength) { - OIDTokenizer tok = new OIDTokenizer(identifier); - while (tok.hasMoreTokens()) + if (contentsLength > MAX_CONTENTS_LENGTH) { - String token = tok.nextToken(); - if (token.length() <= 18) - { - writeField(aOut, Long.parseLong(token)); - } - else - { - writeField(aOut, new BigInteger(token)); - } + throw new IllegalArgumentException("exceeded relative OID contents length limit"); } } - private synchronized byte[] getContents() + static void checkIdentifier(String identifier) { - if (contents == null) + if (identifier == null) { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + throw new NullPointerException("'identifier' cannot be null"); + } + if (identifier.length() > MAX_IDENTIFIER_LENGTH) + { + throw new IllegalArgumentException("exceeded relative OID contents length limit"); + } + if (!isValidIdentifier(identifier, 0)) + { + throw new IllegalArgumentException("string " + identifier + " not a valid relative OID"); + } + } + + static ASN1RelativeOID createPrimitive(byte[] contents, boolean clone) + { + checkContentsLength(contents.length); - doOutput(bOut); + final ASN1ObjectIdentifier.OidHandle hdl = new ASN1ObjectIdentifier.OidHandle(contents); + ASN1RelativeOID oid = pool.get(hdl); + if (oid != null) + { + return oid; + } - contents = bOut.toByteArray(); + if (!isValidContents(contents)) + { + throw new IllegalArgumentException("invalid relative OID contents"); } - return contents; + return new ASN1RelativeOID(clone ? Arrays.clone(contents) : contents, null); } - static ASN1RelativeOID createPrimitive(byte[] contents, boolean clone) + static boolean isValidContents(byte[] contents) { - return new ASN1RelativeOID(contents, clone); + if (contents.length < 1) + { + return false; + } + + boolean subIDStart = true; + for (int i = 0; i < contents.length; ++i) + { + if (subIDStart && (contents[i] & 0xff) == 0x80) + return false; + + subIDStart = (contents[i] & 0x80) == 0; + } + + return subIDStart; } static boolean isValidIdentifier(String identifier, int from) @@ -250,8 +273,7 @@ static boolean isValidIdentifier(String identifier, int from) if (ch == '.') { - if (0 == digitCount - || (digitCount > 1 && identifier.charAt(pos + 1) == '0')) + if (0 == digitCount || (digitCount > 1 && identifier.charAt(pos + 1) == '0')) { return false; } @@ -268,8 +290,7 @@ else if ('0' <= ch && ch <= '9') } } - if (0 == digitCount - || (digitCount > 1 && identifier.charAt(pos + 1) == '0')) + if (0 == digitCount || (digitCount > 1 && identifier.charAt(pos + 1) == '0')) { return false; } @@ -277,6 +298,90 @@ else if ('0' <= ch && ch <= '9') return true; } + static String parseContents(byte[] contents) + { + StringBuffer objId = new StringBuffer(); + long value = 0; + BigInteger bigValue = null; + boolean first = true; + + for (int i = 0; i != contents.length; i++) + { + int b = contents[i] & 0xff; + + if (value <= LONG_LIMIT) + { + value += b & 0x7F; + if ((b & 0x80) == 0) + { + if (first) + { + first = false; + } + else + { + objId.append('.'); + } + + objId.append(value); + value = 0; + } + else + { + value <<= 7; + } + } + else + { + if (bigValue == null) + { + bigValue = BigInteger.valueOf(value); + } + bigValue = bigValue.or(BigInteger.valueOf(b & 0x7F)); + if ((b & 0x80) == 0) + { + if (first) + { + first = false; + } + else + { + objId.append('.'); + } + + objId.append(bigValue); + bigValue = null; + value = 0; + } + else + { + bigValue = bigValue.shiftLeft(7); + } + } + } + + return objId.toString(); + } + + static byte[] parseIdentifier(String identifier) + { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + OIDTokenizer tok = new OIDTokenizer(identifier); + while (tok.hasMoreTokens()) + { + String token = tok.nextToken(); + if (token.length() <= 18) + { + writeField(bOut, Long.parseLong(token)); + } + else + { + writeField(bOut, new BigInteger(token)); + } + } + return bOut.toByteArray(); + } + static void writeField(ByteArrayOutputStream out, long fieldValue) { byte[] result = new byte[9]; diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java b/core/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java index 20ffb5258a..bfcebc84df 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java @@ -78,12 +78,6 @@ ASN1Encodable implParseObject(int tagHdr) throws IOException int tagClass = tagHdr & BERTags.PRIVATE; if (0 != tagClass) { - // TODO[asn1] Special handling can be removed once ASN1ApplicationSpecificParser types removed. - if (BERTags.APPLICATION == tagClass) - { - return new BERApplicationSpecificParser(tagNo, sp); - } - return new BERTaggedObjectParser(tagClass, tagNo, sp); } @@ -105,13 +99,6 @@ ASN1Encodable implParseObject(int tagHdr) throws IOException { boolean isConstructed = (tagHdr & BERTags.CONSTRUCTED) != 0; - // TODO[asn1] Special handling can be removed once ASN1ApplicationSpecific types removed. - if (BERTags.APPLICATION == tagClass) - { - // This cast is ensuring the current user-expected return type. - return (DLApplicationSpecific)sp.loadTaggedDL(tagClass, tagNo, isConstructed); - } - return new DLTaggedObjectParser(tagClass, tagNo, isConstructed, sp); } diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java b/core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java index bf215765fb..7a3cbc612a 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java @@ -1,6 +1,5 @@ package org.bouncycastle.asn1; -import java.io.ByteArrayInputStream; import java.io.IOException; import org.bouncycastle.util.Arrays; @@ -52,49 +51,53 @@ else if (obj instanceof byte[]) public static ASN1TaggedObject getInstance(Object obj, int tagClass) { - if (obj == null) - { - throw new NullPointerException("'obj' cannot be null"); - } + return ASN1Util.checkTagClass(checkInstance(obj), tagClass); + } - ASN1TaggedObject taggedObject = getInstance(obj); - if (tagClass != taggedObject.getTagClass()) - { - throw new IllegalArgumentException("unexpected tag in getInstance: " + ASN1Util.getTagText(taggedObject)); - } + public static ASN1TaggedObject getInstance(Object obj, int tagClass, int tagNo) + { + return ASN1Util.checkTag(checkInstance(obj), tagClass, tagNo); + } - return taggedObject; + public static ASN1TaggedObject getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit) + { + return ASN1Util.getExplicitContextBaseTagged(checkInstance(taggedObject, declaredExplicit)); } - public static ASN1TaggedObject getInstance(Object obj, int tagClass, int tagNo) + public static ASN1TaggedObject getInstance(ASN1TaggedObject taggedObject, int tagClass, boolean declaredExplicit) + { + return ASN1Util.getExplicitBaseTagged(checkInstance(taggedObject, declaredExplicit), tagClass); + } + + public static ASN1TaggedObject getInstance(ASN1TaggedObject taggedObject, int tagClass, int tagNo, + boolean declaredExplicit) + { + return ASN1Util.getExplicitBaseTagged(checkInstance(taggedObject, declaredExplicit), tagClass, tagNo); + } + + private static ASN1TaggedObject checkInstance(Object obj) { if (obj == null) { throw new NullPointerException("'obj' cannot be null"); } - ASN1TaggedObject taggedObject = getInstance(obj); - if (!taggedObject.hasTag(tagClass, tagNo)) - { - throw new IllegalArgumentException("unexpected tag in getInstance: " + ASN1Util.getTagText(taggedObject)); - } - - return taggedObject; + return getInstance(obj); } - public static ASN1TaggedObject getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit) + private static ASN1TaggedObject checkInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit) { - if (BERTags.CONTEXT_SPECIFIC != taggedObject.getTagClass()) + if (!declaredExplicit) { - throw new IllegalStateException("this method only valid for CONTEXT_SPECIFIC tags"); + throw new IllegalArgumentException("this method not valid for implicitly tagged tagged objects"); } - if (declaredExplicit) + if (taggedObject == null) { - return taggedObject.getExplicitBaseTagged(); + throw new NullPointerException("'taggedObject' cannot be null"); } - throw new IllegalArgumentException("this method not valid for implicitly tagged tagged objects"); + return taggedObject; } final int explicitness; @@ -212,6 +215,11 @@ public int getTagNo() return tagNo; } + public boolean hasContextTag() + { + return this.tagClass == BERTags.CONTEXT_SPECIFIC; + } + public boolean hasContextTag(int tagNo) { return this.tagClass == BERTags.CONTEXT_SPECIFIC && this.tagNo == tagNo; @@ -222,6 +230,11 @@ public boolean hasTag(int tagClass, int tagNo) return this.tagClass == tagClass && this.tagNo == tagNo; } + public boolean hasTagClass(int tagClass) + { + return this.tagClass == tagClass; + } + /** * return whether or not the object may be explicitly tagged. *

    @@ -256,77 +269,6 @@ boolean isParsed() } } - /** - * Return the contents of this object as a byte[] - * - * @return the encoded contents of the object. - */ - byte[] getContents() - { - try - { - byte[] baseEncoding = obj.toASN1Primitive().getEncoded(getASN1Encoding()); - if (isExplicit()) - { - return baseEncoding; - } - - ByteArrayInputStream input = new ByteArrayInputStream(baseEncoding); - int tag = input.read(); - ASN1InputStream.readTagNumber(input, tag); - int length = ASN1InputStream.readLength(input, input.available(), false); - int remaining = input.available(); - - // For indefinite form, account for end-of-contents octets - int contentsLength = length < 0 ? remaining - 2 : remaining; - if (contentsLength < 0) - { - throw new ASN1ParsingException("failed to get contents"); - } - - byte[] contents = new byte[contentsLength]; - System.arraycopy(baseEncoding, baseEncoding.length - remaining, contents, 0, contentsLength); - return contents; - } - catch (IOException e) - { - throw new ASN1ParsingException("failed to get contents", e); - } - } - - /** - * Return true if the object is marked as constructed, false otherwise. - * - * @return true if constructed, otherwise false. - */ - boolean isConstructed() - { - return encodeConstructed(); - } - - /** - * Return whatever was following the tag. - *

    - * Note: tagged objects are generally context dependent. If you're trying to - * extract a tagged object you should be going via the appropriate getInstance - * method. - * - * @deprecated Tagged objects now include the {@link #getTagClass() tag class}. - * This method will raise an exception if it is not - * {@link BERTags#CONTEXT_SPECIFIC}. Use - * {@link #getBaseUniversal(boolean, int)} only after confirming the - * expected tag class. - */ - public ASN1Primitive getObject() - { - if (BERTags.CONTEXT_SPECIFIC != getTagClass()) - { - throw new IllegalStateException("this method only valid for CONTEXT_SPECIFIC tags"); - } - - return obj.toASN1Primitive(); - } - /** * Needed for open types, until we have better type-guided parsing support. Use sparingly for other * purposes, and prefer {@link #getExplicitBaseTagged()}, {@link #getImplicitBaseTagged(int, int)} or @@ -445,19 +387,6 @@ ASN1Primitive getBaseUniversal(boolean declaredExplicit, ASN1UniversalType unive } } - /** - * @deprecated See {@link ASN1TaggedObjectParser#getObjectParser(int, boolean)}. - */ - public ASN1Encodable getObjectParser(int tag, boolean isExplicit) throws IOException - { - if (BERTags.CONTEXT_SPECIFIC != getTagClass()) - { - throw new ASN1Exception("this method only valid for CONTEXT_SPECIFIC tags"); - } - - return parseBaseUniversal(isExplicit, tag); - } - public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException { ASN1Primitive primitive = getBaseUniversal(declaredExplicit, baseTagNo); @@ -497,8 +426,6 @@ public final ASN1Primitive getLoadedObject() return this; } - abstract String getASN1Encoding(); - abstract ASN1Sequence rebuildConstructed(ASN1Primitive primitive); abstract ASN1TaggedObject replaceTag(int tagClass, int tagNo); @@ -522,49 +449,24 @@ static ASN1Primitive createConstructedDL(int tagClass, int tagNo, ASN1EncodableV { boolean maybeExplicit = (contentsElements.size() == 1); - ASN1TaggedObject taggedObject = maybeExplicit + return maybeExplicit ? new DLTaggedObject(PARSED_EXPLICIT, tagClass, tagNo, contentsElements.get(0)) : new DLTaggedObject(PARSED_IMPLICIT, tagClass, tagNo, DLFactory.createSequence(contentsElements)); - - switch (tagClass) - { - case BERTags.APPLICATION: - return new DLApplicationSpecific(taggedObject); - default: - return taggedObject; - } } static ASN1Primitive createConstructedIL(int tagClass, int tagNo, ASN1EncodableVector contentsElements) { boolean maybeExplicit = (contentsElements.size() == 1); - ASN1TaggedObject taggedObject = maybeExplicit + return maybeExplicit ? new BERTaggedObject(PARSED_EXPLICIT, tagClass, tagNo, contentsElements.get(0)) : new BERTaggedObject(PARSED_IMPLICIT, tagClass, tagNo, BERFactory.createSequence(contentsElements)); - - switch (tagClass) - { - case BERTags.APPLICATION: - return new BERApplicationSpecific(taggedObject); - default: - return taggedObject; - } } static ASN1Primitive createPrimitive(int tagClass, int tagNo, byte[] contentsOctets) { // Note: !CONSTRUCTED => IMPLICIT - ASN1TaggedObject taggedObject = new DLTaggedObject(PARSED_IMPLICIT, tagClass, tagNo, - new DEROctetString(contentsOctets)); - - switch (tagClass) - { - case BERTags.APPLICATION: - return new DLApplicationSpecific(taggedObject); - default: - return taggedObject; - } + return new DLTaggedObject(PARSED_IMPLICIT, tagClass, tagNo, new DEROctetString(contentsOctets)); } private static ASN1TaggedObject checkedCast(ASN1Primitive primitive) diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObjectParser.java b/core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObjectParser.java index fa6ff6bd2a..f92bc1c085 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObjectParser.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObjectParser.java @@ -22,30 +22,13 @@ public interface ASN1TaggedObjectParser */ int getTagNo(); + boolean hasContextTag(); + boolean hasContextTag(int tagNo); boolean hasTag(int tagClass, int tagNo); - /** - * - * Return a parser for the actual object tagged. - * - * @param tag the primitive tag value for the object tagged originally. - * @param isExplicit true if the tagging was done explicitly. - * @return a parser for the tagged object. - * @throws IOException if a parser cannot be constructed. - * - * @deprecated This parser now includes the {@link #getTagClass() tag class}. - * This method will raise an exception if it is not - * {@link BERTags#CONTEXT_SPECIFIC}. Use - * {@link ASN1Util#parseContextBaseUniversal(ASN1TaggedObjectParser, int, int, boolean, int)} - * as a direct replacement, or use - * {@link #parseBaseUniversal(boolean, int)} only after confirming - * the expected tag class (e.g. - * {@link ASN1Util#tryParseContextBaseUniversal(ASN1TaggedObjectParser, int, boolean, int)}. - */ - ASN1Encodable getObjectParser(int tag, boolean isExplicit) - throws IOException; + boolean hasTagClass(int tagClass); ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException; diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1UniversalType.java b/core/src/main/java/org/bouncycastle/asn1/ASN1UniversalType.java index f0bde9d6cd..9e720b0ed1 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1UniversalType.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1UniversalType.java @@ -41,12 +41,7 @@ final ASN1Primitive fromByteArray(byte[] bytes) throws IOException final ASN1Primitive getContextInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit) { - if (BERTags.CONTEXT_SPECIFIC != taggedObject.getTagClass()) - { - throw new IllegalStateException("this method only valid for CONTEXT_SPECIFIC tags"); - } - - return checkedCast(taggedObject.getBaseUniversal(declaredExplicit, this)); + return checkedCast(ASN1Util.checkContextTagClass(taggedObject).getBaseUniversal(declaredExplicit, this)); } final ASN1Tag getTag() diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1Util.java b/core/src/main/java/org/bouncycastle/asn1/ASN1Util.java index eced42d0a0..01c689ea54 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1Util.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1Util.java @@ -4,6 +4,26 @@ public abstract class ASN1Util { + static ASN1TaggedObject checkContextTag(ASN1TaggedObject taggedObject, int tagNo) + { + return checkTag(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo); + } + + static ASN1TaggedObjectParser checkContextTag(ASN1TaggedObjectParser taggedObjectParser, int tagNo) + { + return checkTag(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo); + } + + static ASN1TaggedObject checkContextTagClass(ASN1TaggedObject taggedObject) + { + return checkTagClass(taggedObject, BERTags.CONTEXT_SPECIFIC); + } + + static ASN1TaggedObjectParser checkContextTagClass(ASN1TaggedObjectParser taggedObjectParser) + { + return checkTagClass(taggedObjectParser, BERTags.CONTEXT_SPECIFIC); + } + static ASN1TaggedObject checkTag(ASN1TaggedObject taggedObject, int tagClass, int tagNo) { if (!taggedObject.hasTag(tagClass, tagNo)) @@ -26,11 +46,63 @@ static ASN1TaggedObjectParser checkTag(ASN1TaggedObjectParser taggedObjectParser return taggedObjectParser; } + static ASN1TaggedObject checkTagClass(ASN1TaggedObject taggedObject, int tagClass) + { + if (!taggedObject.hasTagClass(tagClass)) + { + String expected = getTagClassText(tagClass); + String found = getTagClassText(taggedObject); + throw new IllegalStateException("Expected " + expected + " tag but found " + found); + } + return taggedObject; + } + + static ASN1TaggedObjectParser checkTagClass(ASN1TaggedObjectParser taggedObjectParser, int tagClass) + { + if (!taggedObjectParser.hasTagClass(tagClass)) + { + String expected = getTagClassText(tagClass); + String found = getTagClassText(taggedObjectParser); + throw new IllegalStateException("Expected " + expected + " tag but found " + found); + } + return taggedObjectParser; + } + /* * Tag text methods */ + static String getTagClassText(ASN1Tag tag) + { + return getTagClassText(tag.getTagClass()); + } + + public static String getTagClassText(ASN1TaggedObject taggedObject) + { + return getTagClassText(taggedObject.getTagClass()); + } + + public static String getTagClassText(ASN1TaggedObjectParser taggedObjectParser) + { + return getTagClassText(taggedObjectParser.getTagClass()); + } + + public static String getTagClassText(int tagClass) + { + switch (tagClass) + { + case BERTags.APPLICATION: + return "APPLICATION"; + case BERTags.CONTEXT_SPECIFIC: + return "CONTEXT"; + case BERTags.PRIVATE: + return "PRIVATE"; + default: + return "UNIVERSAL"; + } + } + static String getTagText(ASN1Tag tag) { return getTagText(tag.getTagClass(), tag.getTagNumber()); @@ -96,16 +168,36 @@ public static ASN1Object tryGetExplicitContextBaseObject(ASN1TaggedObject tagged * Wrappers for ASN1TaggedObject#getExplicitBaseTagged */ + public static ASN1TaggedObject getExplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass) + { + return checkTagClass(taggedObject, tagClass).getExplicitBaseTagged(); + } + public static ASN1TaggedObject getExplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo) { return checkTag(taggedObject, tagClass, tagNo).getExplicitBaseTagged(); } + public static ASN1TaggedObject getExplicitContextBaseTagged(ASN1TaggedObject taggedObject) + { + return getExplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC); + } + public static ASN1TaggedObject getExplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo) { return getExplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo); } + public static ASN1TaggedObject tryGetExplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass) + { + if (!taggedObject.hasTagClass(tagClass)) + { + return null; + } + + return taggedObject.getExplicitBaseTagged(); + } + public static ASN1TaggedObject tryGetExplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo) { if (!taggedObject.hasTag(tagClass, tagNo)) @@ -116,6 +208,11 @@ public static ASN1TaggedObject tryGetExplicitBaseTagged(ASN1TaggedObject taggedO return taggedObject.getExplicitBaseTagged(); } + public static ASN1TaggedObject tryGetExplicitContextBaseTagged(ASN1TaggedObject taggedObject) + { + return tryGetExplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC); + } + public static ASN1TaggedObject tryGetExplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo) { return tryGetExplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo); @@ -194,18 +291,41 @@ public static ASN1Primitive tryGetContextBaseUniversal(ASN1TaggedObject taggedOb * Wrappers for ASN1TaggedObjectParser#parseExplicitBaseTagged */ + public static ASN1TaggedObjectParser parseExplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser, + int tagClass) throws IOException + { + return checkTagClass(taggedObjectParser, tagClass).parseExplicitBaseTagged(); + } + public static ASN1TaggedObjectParser parseExplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser, int tagClass, int tagNo) throws IOException { return checkTag(taggedObjectParser, tagClass, tagNo).parseExplicitBaseTagged(); } + public static ASN1TaggedObjectParser parseExplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser) + throws IOException + { + return parseExplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC); + } + public static ASN1TaggedObjectParser parseExplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser, int tagNo) throws IOException { return parseExplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo); } + public static ASN1TaggedObjectParser tryParseExplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser, + int tagClass) throws IOException + { + if (!taggedObjectParser.hasTagClass(tagClass)) + { + return null; + } + + return taggedObjectParser.parseExplicitBaseTagged(); + } + public static ASN1TaggedObjectParser tryParseExplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser, int tagClass, int tagNo) throws IOException { @@ -217,6 +337,12 @@ public static ASN1TaggedObjectParser tryParseExplicitBaseTagged(ASN1TaggedObject return taggedObjectParser.parseExplicitBaseTagged(); } + public static ASN1TaggedObjectParser tryParseExplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser) + throws IOException + { + return tryParseExplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC); + } + public static ASN1TaggedObjectParser tryParseExplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser, int tagNo) throws IOException { diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1VisibleString.java b/core/src/main/java/org/bouncycastle/asn1/ASN1VisibleString.java index 5a57783292..6424cfcdaf 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1VisibleString.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1VisibleString.java @@ -63,7 +63,7 @@ public static ASN1VisibleString getInstance( /** * Return a Visible String from a tagged object. * - * @param obj the tagged object holding the object we want + * @param taggedObject the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot diff --git a/core/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java b/core/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java deleted file mode 100644 index 4cfa47c3a0..0000000000 --- a/core/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.bouncycastle.asn1; - -import java.io.IOException; - -/** - * An indefinite-length encoding version of an ASN.1 ApplicationSpecific object. - * - * @deprecated Will be removed. See comments for - * {@link ASN1ApplicationSpecific}. - */ -public class BERApplicationSpecific - extends ASN1ApplicationSpecific -{ - /** - * Create an application specific object with an explicit tag - * - * @param tagNo the tag number for this object. - * @param baseEncodable the object to be contained. - */ - public BERApplicationSpecific(int tagNo, ASN1Encodable baseEncodable) throws IOException - { - this(true, tagNo, baseEncodable); - } - - /** - * Create an application specific object with the tagging style given by the value of explicit. - * - * @param explicit true if the object is explicitly tagged. - * @param tagNo the tag number for this object. - * @param baseEncodable the object to be contained. - */ - public BERApplicationSpecific(boolean explicit, int tagNo, ASN1Encodable baseEncodable) throws IOException - { - super(new BERTaggedObject(explicit, BERTags.APPLICATION, tagNo, baseEncodable)); - } - - /** - * Create an application specific object which is marked as constructed - * - * @param tagNo the tag number for this object. - * @param contentsElements the objects making up the application specific object. - */ - public BERApplicationSpecific(int tagNo, ASN1EncodableVector contentsElements) - { - super(new BERTaggedObject(false, BERTags.APPLICATION, tagNo, BERFactory.createSequence(contentsElements))); - } - - BERApplicationSpecific(ASN1TaggedObject taggedObject) - { - super(taggedObject); - } -} diff --git a/core/src/main/java/org/bouncycastle/asn1/BERApplicationSpecificParser.java b/core/src/main/java/org/bouncycastle/asn1/BERApplicationSpecificParser.java deleted file mode 100644 index 3af7e9da87..0000000000 --- a/core/src/main/java/org/bouncycastle/asn1/BERApplicationSpecificParser.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.bouncycastle.asn1; - -import java.io.IOException; - -/** - * A parser for indefinite-length ASN.1 ApplicationSpecific objects. - * - * @deprecated Test for {@link ASN1TaggedObjectParser} with - * {@link ASN1TaggedObjectParser#getTagClass() tag class} of - * {@link BERTags#APPLICATION} instead. - */ -public class BERApplicationSpecificParser - extends BERTaggedObjectParser - implements ASN1ApplicationSpecificParser -{ - BERApplicationSpecificParser(int tagNo, ASN1StreamParser parser) - { - super(BERTags.APPLICATION, tagNo, parser); - } - - /** - * Return the object contained in this application specific object, - * @return the contained object. - * @throws IOException if the underlying stream cannot be read, or does not contain an ASN.1 encoding. - */ - public ASN1Encodable readObject() - throws IOException - { - // NOTE: No way to say you're looking for an implicitly-tagged object via ASN1ApplicationSpecificParser - return parseExplicitBaseObject(); - } -} diff --git a/core/src/main/java/org/bouncycastle/asn1/BERBitStringParser.java b/core/src/main/java/org/bouncycastle/asn1/BERBitStringParser.java index 6759910988..9b2cfaffc2 100644 --- a/core/src/main/java/org/bouncycastle/asn1/BERBitStringParser.java +++ b/core/src/main/java/org/bouncycastle/asn1/BERBitStringParser.java @@ -7,6 +7,8 @@ /** * A parser for indefinite-length BIT STRINGs. + * + * @deprecated Check for 'ASN1BitStringParser' instead */ public class BERBitStringParser implements ASN1BitStringParser diff --git a/core/src/main/java/org/bouncycastle/asn1/BEROctetString.java b/core/src/main/java/org/bouncycastle/asn1/BEROctetString.java index ef6231611d..dbc8e4b8b9 100644 --- a/core/src/main/java/org/bouncycastle/asn1/BEROctetString.java +++ b/core/src/main/java/org/bouncycastle/asn1/BEROctetString.java @@ -1,8 +1,6 @@ package org.bouncycastle.asn1; import java.io.IOException; -import java.util.Enumeration; -import java.util.NoSuchElementException; /** * ASN.1 OctetStrings, with indefinite length rules, and constructed form support. @@ -87,7 +85,7 @@ public BEROctetString(ASN1OctetString[] elements) */ public BEROctetString(byte[] string, int segmentLimit) { - this(string, new ASN1OctetString[] { new DEROctetString(string) }, segmentLimit); + this(string, null, segmentLimit); } /** @@ -109,74 +107,14 @@ private BEROctetString(byte[] string, ASN1OctetString[] elements, int segmentLim this.segmentLimit = segmentLimit; } - /** - * Return the OCTET STRINGs that make up this string. - * - * @return an Enumeration of the component OCTET STRINGs. - * - * @deprecated Will be removed. - */ - public Enumeration getObjects() - { - if (elements == null) - { - return new Enumeration() - { - int pos = 0; - - public boolean hasMoreElements() - { - return pos < string.length; - } - - public Object nextElement() - { - if (pos < string.length) - { - int length = Math.min(string.length - pos, segmentLimit); - byte[] segment = new byte[length]; - System.arraycopy(string, pos, segment, 0, length); - pos += length; - return new DEROctetString(segment); - } - throw new NoSuchElementException(); - } - }; - } - - return new Enumeration() - { - int counter = 0; - - public boolean hasMoreElements() - { - return counter < elements.length; - } - - public Object nextElement() - { - if (counter < elements.length) - { - return elements[counter++]; - } - throw new NoSuchElementException(); - } - }; - } - boolean encodeConstructed() { - return null != elements || string.length > segmentLimit; + return true; } int encodedLength(boolean withTag) throws IOException { - if (!encodeConstructed()) - { - return DEROctetString.encodedLength(withTag, string.length); - } - int totalLength = withTag ? 4 : 3; if (null != elements) @@ -203,12 +141,6 @@ int encodedLength(boolean withTag) void encode(ASN1OutputStream out, boolean withTag) throws IOException { - if (!encodeConstructed()) - { - DEROctetString.encode(out, withTag, string, 0, string.length); - return; - } - out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.OCTET_STRING); out.write(0x80); diff --git a/core/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java b/core/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java index 568dbe32c0..bce7f0189c 100644 --- a/core/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java +++ b/core/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java @@ -7,6 +7,8 @@ /** * A parser for indefinite-length OCTET STRINGs. + * + * @deprecated Check for 'ASN1OctetStringParser' instead */ public class BEROctetStringParser implements ASN1OctetStringParser diff --git a/core/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java b/core/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java index cf81451352..c53b0014ed 100644 --- a/core/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java +++ b/core/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java @@ -4,6 +4,8 @@ /** * Parser for indefinite-length SEQUENCEs. + * + * @deprecated Check for 'ASN1SequenceParser' instead */ public class BERSequenceParser implements ASN1SequenceParser diff --git a/core/src/main/java/org/bouncycastle/asn1/BERSetParser.java b/core/src/main/java/org/bouncycastle/asn1/BERSetParser.java index dbcdb95829..cc369dfcb9 100644 --- a/core/src/main/java/org/bouncycastle/asn1/BERSetParser.java +++ b/core/src/main/java/org/bouncycastle/asn1/BERSetParser.java @@ -4,6 +4,8 @@ /** * Parser for indefinite-length SETs. + * + * @deprecated Check for 'ASN1SetParser' instead */ public class BERSetParser implements ASN1SetParser diff --git a/core/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java b/core/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java index a276c96c9f..1ef1ccbecc 100644 --- a/core/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java +++ b/core/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java @@ -10,17 +10,6 @@ public class BERTaggedObject extends ASN1TaggedObject { - /** - * create an implicitly tagged object that contains a zero - * length sequence. - * - * @deprecated Will be removed. - */ - public BERTaggedObject(int tagNo) - { - super(false, tagNo, new BERSequence()); - } - /** * @param tagNo the tag number for this object. * @param obj the tagged object. @@ -108,11 +97,6 @@ void encode(ASN1OutputStream out, boolean withTag) throws IOException } } - String getASN1Encoding() - { - return ASN1Encoding.BER; - } - ASN1Sequence rebuildConstructed(ASN1Primitive primitive) { return new BERSequence(primitive); diff --git a/core/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java b/core/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java index 2688ed910a..838e884444 100644 --- a/core/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java +++ b/core/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java @@ -4,10 +4,8 @@ /** * Parser for indefinite-length tagged objects. - * - * @deprecated Will be made non-public. Test for and use only {@link ASN1TaggedObjectParser}. */ -public class BERTaggedObjectParser +class BERTaggedObjectParser implements ASN1TaggedObjectParser { final int _tagClass; @@ -31,6 +29,11 @@ public int getTagNo() return _tagNo; } + public boolean hasContextTag() + { + return this._tagClass == BERTags.CONTEXT_SPECIFIC; + } + public boolean hasContextTag(int tagNo) { return this._tagClass == BERTags.CONTEXT_SPECIFIC && this._tagNo == tagNo; @@ -41,35 +44,9 @@ public boolean hasTag(int tagClass, int tagNo) return this._tagClass == tagClass && this._tagNo == tagNo; } - /** - * Return true if this tagged object is marked as constructed. - * - * @return true if constructed, false otherwise. - */ - public boolean isConstructed() - { - return true; - } - - /** - * Return an object parser for the contents of this tagged object. - * - * @param tag the actual tag number of the object (needed if implicit). - * @param isExplicit true if the contained object was explicitly tagged, false - * if implicit. - * @return an ASN.1 encodable object parser. - * @throws IOException if there is an issue building the object parser from the - * stream. - * @deprecated See {@link ASN1TaggedObjectParser#getObjectParser(int, boolean)}. - */ - public ASN1Encodable getObjectParser(int tag, boolean isExplicit) throws IOException + public boolean hasTagClass(int tagClass) { - if (BERTags.CONTEXT_SPECIFIC != getTagClass()) - { - throw new ASN1Exception("this method only valid for CONTEXT_SPECIFIC tags"); - } - - return parseBaseUniversal(isExplicit, tag); + return this._tagClass == tagClass; } /** @@ -106,12 +83,6 @@ public ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException public ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException { - // TODO[asn1] Special handling can be removed once ASN1ApplicationSpecificParser types removed. - if (BERTags.APPLICATION == baseTagClass) - { - return new BERApplicationSpecificParser(baseTagNo, _parser); - } - return new BERTaggedObjectParser(baseTagClass, baseTagNo, _parser); } diff --git a/core/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java b/core/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java deleted file mode 100644 index e1ecb3404d..0000000000 --- a/core/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.bouncycastle.asn1; - -import java.io.IOException; - -/** - * A DER encoding version of an application specific object. - * - * @deprecated Will be removed. See comments for - * {@link ASN1ApplicationSpecific}. - */ -public class DERApplicationSpecific - extends ASN1ApplicationSpecific -{ - /** - * Create an application specific object from the passed in data. This will assume - * the data does not represent a constructed object. - * - * @param tagNo the tag number for this object. - * @param contentsOctets the encoding of the object's body. - */ - public DERApplicationSpecific(int tagNo, byte[] contentsOctets) - { - super(new DERTaggedObject(false, BERTags.APPLICATION, tagNo, new DEROctetString(contentsOctets))); - } - - /** - * Create an application specific object with a tagging of explicit/constructed. - * - * @param tag the tag number for this object. - * @param baseEncodable the object to be contained. - */ - public DERApplicationSpecific(int tag, ASN1Encodable baseEncodable) throws IOException - { - this(true, tag, baseEncodable); - } - - /** - * Create an application specific object with the tagging style given by the value of explicit. - * - * @param explicit true if the object is explicitly tagged. - * @param tagNo the tag number for this object. - * @param baseEncodable the object to be contained. - */ - public DERApplicationSpecific(boolean explicit, int tagNo, ASN1Encodable baseEncodable) throws IOException - { - super(new DERTaggedObject(explicit, BERTags.APPLICATION, tagNo, baseEncodable)); - } - - /** - * Create an application specific object which is marked as constructed - * - * @param tagNo the tag number for this object. - * @param contentsElements the objects making up the application specific object. - */ - public DERApplicationSpecific(int tagNo, ASN1EncodableVector contentsElements) - { - super(new DERTaggedObject(false, BERTags.APPLICATION, tagNo, DERFactory.createSequence(contentsElements))); - } - - DERApplicationSpecific(ASN1TaggedObject taggedObject) - { - super(taggedObject); - } - - ASN1Primitive toDERObject() - { - return this; - } - - ASN1Primitive toDLObject() - { - return this; - } -} diff --git a/core/src/main/java/org/bouncycastle/asn1/DERBMPString.java b/core/src/main/java/org/bouncycastle/asn1/DERBMPString.java index 5a1f45ca73..31f54acfe7 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERBMPString.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERBMPString.java @@ -11,69 +11,6 @@ public class DERBMPString extends ASN1BMPString { - /** - * Return a BMP String from the given object. - * - * @param obj the object we want converted. - * @exception IllegalArgumentException if the object cannot be converted. - * @return a DERBMPString instance, or null. - * - * @deprecated Use {@link ASN1BMPString#getInstance(Object)} instead. - */ - public static DERBMPString getInstance( - Object obj) - { - if (obj == null || obj instanceof DERBMPString) - { - return (DERBMPString)obj; - } - if (obj instanceof ASN1BMPString) - { - return new DERBMPString(((ASN1BMPString)obj).string); - } - if (obj instanceof byte[]) - { - try - { - return (DERBMPString)fromByteArray((byte[])obj); - } - catch (Exception e) - { - throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); - } - } - - throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); - } - - /** - * Return a BMP String from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly tagged false - * otherwise. - * @exception IllegalArgumentException if the tagged object cannot be converted. - * @return a DERBMPString instance. - * - * @deprecated Use {@link ASN1BMPString#getInstance(ASN1TaggedObject, boolean)} - * instead. - */ - public static DERBMPString getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Primitive o = obj.getObject(); - - if (explicit || o instanceof DERBMPString) - { - return getInstance(o); - } - else - { - return new DERBMPString(ASN1OctetString.getInstance(o).getOctets()); - } - } - /** * Basic constructor * @param string a String to wrap as a BMP STRING. @@ -85,7 +22,7 @@ public DERBMPString(String string) /** * Basic constructor - byte encoded string. - * @param string the encoded BMP STRING to wrap. + * @param contents the encoded BMP STRING to wrap. */ DERBMPString(byte[] contents) { diff --git a/core/src/main/java/org/bouncycastle/asn1/DERBitString.java b/core/src/main/java/org/bouncycastle/asn1/DERBitString.java index 4ea09d3d2f..26953ece02 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERBitString.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERBitString.java @@ -13,70 +13,6 @@ public static DERBitString convert(ASN1BitString bitString) return (DERBitString)bitString.toDERObject(); } - /** - * return a Bit String from the passed in object - * - * @param obj a DERBitString or an object that can be converted into one. - * @exception IllegalArgumentException if the object cannot be converted. - * @return a DERBitString instance, or null. - * - * @deprecated Use {@link ASN1BitString#getInstance(Object)} and - * {@link #convert(ASN1BitString)} instead. - */ - public static DERBitString getInstance( - Object obj) - { - if (obj == null || obj instanceof DERBitString) - { - return (DERBitString)obj; - } - if (obj instanceof ASN1BitString) - { - return convert((ASN1BitString)obj); - } - if (obj instanceof byte[]) - { - try - { - return convert((ASN1BitString)fromByteArray((byte[])obj)); - } - catch (Exception e) - { - throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); - } - } - - throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); - } - - /** - * return a Bit String from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly tagged false - * otherwise. - * @exception IllegalArgumentException if the tagged object cannot be converted. - * @return a DERBitString instance, or null. - * - * @deprecated Use {@link ASN1BitString#getInstance(ASN1TaggedObject, boolean)} - * and {@link #convert(ASN1BitString)} instead. - */ - public static DERBitString getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Primitive o = obj.getObject(); - - if (explicit || o instanceof DERBitString) - { - return getInstance(o); - } - else - { - return fromOctetString(ASN1OctetString.getInstance(o)); - } - } - public DERBitString(byte[] data) { this(data, 0); diff --git a/core/src/main/java/org/bouncycastle/asn1/DERExternal.java b/core/src/main/java/org/bouncycastle/asn1/DERExternal.java index 3e8a079114..fced6d2bac 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERExternal.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERExternal.java @@ -84,7 +84,7 @@ ASN1Sequence buildSequence() } if (dataValueDescriptor != null) { - v.add(dataValueDescriptor); + v.add(dataValueDescriptor.toDERObject()); } v.add(new DERTaggedObject(0 == encoding, encoding, externalContent)); diff --git a/core/src/main/java/org/bouncycastle/asn1/DERExternalParser.java b/core/src/main/java/org/bouncycastle/asn1/DERExternalParser.java index 3621c0b0ef..310acadbbf 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERExternalParser.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERExternalParser.java @@ -63,7 +63,7 @@ static DLExternal parse(ASN1StreamParser sp) throws IOException { try { - return new DLExternal(sp.readVector()); + return new DLExternal(new DLSequence(sp.readVector())); } catch (IllegalArgumentException e) { diff --git a/core/src/main/java/org/bouncycastle/asn1/DERGeneralString.java b/core/src/main/java/org/bouncycastle/asn1/DERGeneralString.java index de3ff6a8c5..c60979e4d8 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERGeneralString.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERGeneralString.java @@ -10,71 +10,6 @@ public class DERGeneralString extends ASN1GeneralString { - /** - * Return a GeneralString from the given object. - * - * @param obj the object we want converted. - * @exception IllegalArgumentException if the object cannot be converted. - * @return a DERBMPString instance, or null. - * - * @deprecated Use {@link ASN1GeneralString#getInstance(Object)} instead. - */ - public static DERGeneralString getInstance( - Object obj) - { - if (obj == null || obj instanceof DERGeneralString) - { - return (DERGeneralString) obj; - } - if (obj instanceof ASN1GeneralString) - { - return new DERGeneralString(((ASN1GeneralString)obj).contents, false); - } - if (obj instanceof byte[]) - { - try - { - return (DERGeneralString)fromByteArray((byte[])obj); - } - catch (Exception e) - { - throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); - } - } - - throw new IllegalArgumentException("illegal object in getInstance: " - + obj.getClass().getName()); - } - - /** - * Return a GeneralString from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly tagged false - * otherwise. - * @exception IllegalArgumentException if the tagged object cannot be converted. - * @return a DERGeneralString instance. - * - * @deprecated Use - * {@link ASN1GeneralString#getInstance(ASN1TaggedObject, boolean)} - * instead. - */ - public static DERGeneralString getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Primitive o = obj.getObject(); - - if (explicit || o instanceof DERGeneralString) - { - return getInstance(o); - } - else - { - return new DERGeneralString(ASN1OctetString.getInstance(o).getOctets(), true); - } - } - /** * Construct a GeneralString from the passed in String. * diff --git a/core/src/main/java/org/bouncycastle/asn1/DERGraphicString.java b/core/src/main/java/org/bouncycastle/asn1/DERGraphicString.java index dbf4478e67..7b6f55f98b 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERGraphicString.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERGraphicString.java @@ -3,70 +3,6 @@ public class DERGraphicString extends ASN1GraphicString { - /** - * return a Graphic String from the passed in object - * - * @param obj a DERGraphicString or an object that can be converted into one. - * @exception IllegalArgumentException if the object cannot be converted. - * @return a DERGraphicString instance, or null. - * - * @deprecated Use {@link ASN1GraphicString#getInstance(Object)} instead. - */ - public static DERGraphicString getInstance( - Object obj) - { - if (obj == null || obj instanceof DERGraphicString) - { - return (DERGraphicString)obj; - } - if (obj instanceof ASN1GraphicString) - { - return new DERGraphicString(((ASN1GraphicString)obj).contents, false); - } - if (obj instanceof byte[]) - { - try - { - return (DERGraphicString)fromByteArray((byte[])obj); - } - catch (Exception e) - { - throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); - } - } - - throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); - } - - /** - * return a Graphic String from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly tagged false - * otherwise. - * @exception IllegalArgumentException if the tagged object cannot be converted. - * @return a DERGraphicString instance, or null. - * - * @deprecated Use - * {@link ASN1GraphicString#getInstance(ASN1TaggedObject, boolean)} - * instead. - */ - public static DERGraphicString getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Primitive o = obj.getObject(); - - if (explicit || o instanceof DERGraphicString) - { - return getInstance(o); - } - else - { - return new DERGraphicString(ASN1OctetString.getInstance(o).getOctets()); - } - } - public DERGraphicString(byte[] octets) { this(octets, true); diff --git a/core/src/main/java/org/bouncycastle/asn1/DERIA5String.java b/core/src/main/java/org/bouncycastle/asn1/DERIA5String.java index 24a7bb5ed8..b2644aac0b 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERIA5String.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERIA5String.java @@ -9,69 +9,6 @@ public class DERIA5String extends ASN1IA5String { - /** - * Return an IA5 string from the passed in object - * - * @param obj a DERIA5String or an object that can be converted into one. - * @exception IllegalArgumentException if the object cannot be converted. - * @return a DERIA5String instance, or null. - * - * @deprecated Use {@link ASN1IA5String#getInstance(Object)} instead. - */ - public static DERIA5String getInstance( - Object obj) - { - if (obj == null || obj instanceof DERIA5String) - { - return (DERIA5String)obj; - } - if (obj instanceof ASN1IA5String) - { - return new DERIA5String(((ASN1IA5String)obj).contents, false); - } - if (obj instanceof byte[]) - { - try - { - return (DERIA5String)fromByteArray((byte[])obj); - } - catch (Exception e) - { - throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); - } - } - - throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); - } - - /** - * Return an IA5 String from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly tagged false - * otherwise. - * @exception IllegalArgumentException if the tagged object cannot be converted. - * @return a DERIA5String instance, or null. - * - * @deprecated Use {@link ASN1IA5String#getInstance(ASN1TaggedObject, boolean)} - * instead. - */ - public static DERIA5String getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Primitive o = obj.getObject(); - - if (explicit || o instanceof DERIA5String) - { - return getInstance(o); - } - else - { - return new DERIA5String(ASN1OctetString.getInstance(o).getOctets(), true); - } - } - /** * Basic constructor - without validation. * @param string the base string to use.. diff --git a/core/src/main/java/org/bouncycastle/asn1/DERNumericString.java b/core/src/main/java/org/bouncycastle/asn1/DERNumericString.java index 0c8dca133a..0ce50746a3 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERNumericString.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERNumericString.java @@ -13,70 +13,6 @@ public class DERNumericString extends ASN1NumericString { - /** - * Return a Numeric string from the passed in object - * - * @param obj a DERNumericString or an object that can be converted into one. - * @exception IllegalArgumentException if the object cannot be converted. - * @return a DERNumericString instance, or null - * - * @deprecated Use {@link ASN1NumericString#getInstance(Object)} instead. - */ - public static DERNumericString getInstance( - Object obj) - { - if (obj == null || obj instanceof DERNumericString) - { - return (DERNumericString)obj; - } - if (obj instanceof ASN1NumericString) - { - return new DERNumericString(((ASN1NumericString)obj).contents, false); - } - if (obj instanceof byte[]) - { - try - { - return (DERNumericString)fromByteArray((byte[])obj); - } - catch (Exception e) - { - throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); - } - } - - throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); - } - - /** - * Return an Numeric String from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly tagged false - * otherwise. - * @exception IllegalArgumentException if the tagged object cannot be converted. - * @return a DERNumericString instance, or null. - * - * @deprecated Use - * {@link ASN1NumericString#getInstance(ASN1TaggedObject, boolean)} - * instead. - */ - public static DERNumericString getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Primitive o = obj.getObject(); - - if (explicit || o instanceof DERNumericString) - { - return getInstance(o); - } - else - { - return new DERNumericString(ASN1OctetString.getInstance(o).getOctets(), true); - } - } - /** * Basic constructor - without validation.. */ diff --git a/core/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java b/core/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java index 1c9c159810..33e1bca3da 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java +++ b/core/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java @@ -5,6 +5,8 @@ /** * Parser for DER encoded OCTET STRINGS + * + * @deprecated Check for 'ASN1OctetStringParser' instead */ public class DEROctetStringParser implements ASN1OctetStringParser diff --git a/core/src/main/java/org/bouncycastle/asn1/DERPrintableString.java b/core/src/main/java/org/bouncycastle/asn1/DERPrintableString.java index 8d4e3fa1f8..a403b87760 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERPrintableString.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERPrintableString.java @@ -29,70 +29,6 @@ public class DERPrintableString extends ASN1PrintableString { - /** - * Return a printable string from the passed in object. - * - * @param obj a DERPrintableString or an object that can be converted into one. - * @exception IllegalArgumentException if the object cannot be converted. - * @return a DERPrintableString instance, or null. - * - * @deprecated Use {@link ASN1PrintableString#getInstance(Object)} instead. - */ - public static DERPrintableString getInstance( - Object obj) - { - if (obj == null || obj instanceof DERPrintableString) - { - return (DERPrintableString)obj; - } - if (obj instanceof ASN1PrintableString) - { - return new DERPrintableString(((ASN1PrintableString)obj).contents, false); - } - if (obj instanceof byte[]) - { - try - { - return (DERPrintableString)fromByteArray((byte[])obj); - } - catch (Exception e) - { - throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); - } - } - - throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); - } - - /** - * Return a Printable String from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly tagged false - * otherwise. - * @exception IllegalArgumentException if the tagged object cannot be converted. - * @return a DERPrintableString instance, or null. - * - * @deprecated Use - * {@link ASN1PrintableString#getInstance(ASN1TaggedObject, boolean)} - * instead. - */ - public static DERPrintableString getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Primitive o = obj.getObject(); - - if (explicit || o instanceof DERPrintableString) - { - return getInstance(o); - } - else - { - return new DERPrintableString(ASN1OctetString.getInstance(o).getOctets(), true); - } - } - /** * Basic constructor - this does not validate the string */ diff --git a/core/src/main/java/org/bouncycastle/asn1/DERT61String.java b/core/src/main/java/org/bouncycastle/asn1/DERT61String.java index 959f3837dc..ade137a546 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERT61String.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERT61String.java @@ -7,69 +7,6 @@ public class DERT61String extends ASN1T61String { - /** - * Return a T61 string from the passed in object. - * - * @param obj a DERT61String or an object that can be converted into one. - * @exception IllegalArgumentException if the object cannot be converted. - * @return a DERT61String instance, or null - * - * @deprecated Use {@link ASN1T61String#getInstance(Object)} instead. - */ - public static DERT61String getInstance( - Object obj) - { - if (obj == null || obj instanceof DERT61String) - { - return (DERT61String)obj; - } - if (obj instanceof ASN1T61String) - { - return new DERT61String(((ASN1T61String)obj).contents, false); - } - if (obj instanceof byte[]) - { - try - { - return (DERT61String)fromByteArray((byte[])obj); - } - catch (Exception e) - { - throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); - } - } - - throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); - } - - /** - * Return an T61 String from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly tagged false - * otherwise. - * @exception IllegalArgumentException if the tagged object cannot be converted. - * @return a DERT61String instance, or null - * - * @deprecated Use {@link ASN1T61String#getInstance(ASN1TaggedObject, boolean)} - * instead. - */ - public static DERT61String getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Primitive o = obj.getObject(); - - if (explicit || o instanceof DERT61String) - { - return getInstance(o); - } - else - { - return new DERT61String(ASN1OctetString.getInstance(o).getOctets(), true); - } - } - /** * Basic constructor - with string 8 bit assumed. * diff --git a/core/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java b/core/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java index fbdbf27fc6..97ffb66e53 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java @@ -88,11 +88,6 @@ void encode(ASN1OutputStream out, boolean withTag) throws IOException primitive.encode(out.getDERSubStream(), explicit); } - String getASN1Encoding() - { - return ASN1Encoding.DER; - } - ASN1Sequence rebuildConstructed(ASN1Primitive primitive) { return new DERSequence(primitive); diff --git a/core/src/main/java/org/bouncycastle/asn1/DERUTF8String.java b/core/src/main/java/org/bouncycastle/asn1/DERUTF8String.java index 6cbc23e912..1b085849f9 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERUTF8String.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERUTF8String.java @@ -6,70 +6,6 @@ public class DERUTF8String extends ASN1UTF8String { - /** - * Return an UTF8 string from the passed in object. - * - * @param obj a DERUTF8String or an object that can be converted into one. - * @exception IllegalArgumentException - * if the object cannot be converted. - * @return a DERUTF8String instance, or null - * - * @deprecated Use {@link ASN1UTF8String#getInstance(Object)} instead. - */ - public static DERUTF8String getInstance(Object obj) - { - if (obj == null || obj instanceof DERUTF8String) - { - return (DERUTF8String)obj; - } - if (obj instanceof ASN1UTF8String) - { - return new DERUTF8String(((ASN1UTF8String)obj).contents, false); - } - if (obj instanceof byte[]) - { - try - { - return (DERUTF8String)fromByteArray((byte[])obj); - } - catch (Exception e) - { - throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); - } - } - - throw new IllegalArgumentException("illegal object in getInstance: " - + obj.getClass().getName()); - } - - /** - * Return an UTF8 String from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly tagged false - * otherwise. - * @exception IllegalArgumentException if the tagged object cannot be converted. - * @return a DERUTF8String instance, or null - * - * @deprecated Use {@link ASN1UTF8String#getInstance(ASN1TaggedObject, boolean)} - * instead. - */ - public static DERUTF8String getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Primitive o = obj.getObject(); - - if (explicit || o instanceof DERUTF8String) - { - return getInstance(o); - } - else - { - return new DERUTF8String(ASN1OctetString.getInstance(o).getOctets(), true); - } - } - /** * Basic constructor * diff --git a/core/src/main/java/org/bouncycastle/asn1/DERUniversalString.java b/core/src/main/java/org/bouncycastle/asn1/DERUniversalString.java index 75994a5984..0c50ef9322 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERUniversalString.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERUniversalString.java @@ -7,70 +7,6 @@ public class DERUniversalString extends ASN1UniversalString { - /** - * Return a Universal String from the passed in object. - * - * @param obj a DERUniversalString or an object that can be converted into one. - * @exception IllegalArgumentException if the object cannot be converted. - * @return a DERUniversalString instance, or null - * - * @deprecated Use {@link ASN1UniversalString#getInstance(Object)} instead. - */ - public static DERUniversalString getInstance( - Object obj) - { - if (obj == null || obj instanceof DERUniversalString) - { - return (DERUniversalString)obj; - } - if (obj instanceof ASN1UniversalString) - { - return new DERUniversalString(((ASN1UniversalString)obj).contents, false); - } - if (obj instanceof byte[]) - { - try - { - return (DERUniversalString)fromByteArray((byte[])obj); - } - catch (Exception e) - { - throw new IllegalArgumentException("encoding error getInstance: " + e.toString()); - } - } - - throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); - } - - /** - * Return a Universal String from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly - * tagged false otherwise. - * @exception IllegalArgumentException if the tagged object cannot - * be converted. - * @return a DERUniversalString instance, or null - * - * @deprecated Use {@link ASN1UniversalString#getInstance(ASN1TaggedObject, boolean)} - * instead. - */ - public static DERUniversalString getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Primitive o = obj.getObject(); - - if (explicit || o instanceof DERUniversalString) - { - return getInstance(o); - } - else - { - return new DERUniversalString(ASN1OctetString.getInstance(o).getOctets(), true); - } - } - /** * Basic constructor - byte encoded string. * diff --git a/core/src/main/java/org/bouncycastle/asn1/DERVideotexString.java b/core/src/main/java/org/bouncycastle/asn1/DERVideotexString.java index c481bac5eb..141bab91f8 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERVideotexString.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERVideotexString.java @@ -3,70 +3,6 @@ public class DERVideotexString extends ASN1VideotexString { - /** - * return a Videotex String from the passed in object - * - * @param obj a DERVideotexString or an object that can be converted into one. - * @exception IllegalArgumentException if the object cannot be converted. - * @return a DERVideotexString instance, or null. - * - * @deprecated Use {@link ASN1VideotexString#getInstance(Object)} instead. - */ - public static DERVideotexString getInstance( - Object obj) - { - if (obj == null || obj instanceof DERVideotexString) - { - return (DERVideotexString)obj; - } - if (obj instanceof ASN1VideotexString) - { - return new DERVideotexString(((ASN1VideotexString)obj).contents, false); - } - if (obj instanceof byte[]) - { - try - { - return (DERVideotexString)fromByteArray((byte[])obj); - } - catch (Exception e) - { - throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); - } - } - - throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); - } - - /** - * return a Videotex String from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly tagged false - * otherwise. - * @exception IllegalArgumentException if the tagged object cannot be converted. - * @return a DERVideotexString instance, or null. - * - * @deprecated Use - * {@link ASN1VideotexString#getInstance(ASN1TaggedObject, boolean)} - * instead. - */ - public static DERVideotexString getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Primitive o = obj.getObject(); - - if (explicit || o instanceof DERVideotexString) - { - return getInstance(o); - } - else - { - return new DERVideotexString(ASN1OctetString.getInstance(o).getOctets()); - } - } - public DERVideotexString(byte[] octets) { this(octets, true); diff --git a/core/src/main/java/org/bouncycastle/asn1/DERVisibleString.java b/core/src/main/java/org/bouncycastle/asn1/DERVisibleString.java index ec60bf4f2a..47dc7874df 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERVisibleString.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERVisibleString.java @@ -9,70 +9,6 @@ public class DERVisibleString extends ASN1VisibleString { - /** - * Return a Visible String from the passed in object. - * - * @param obj a DERVisibleString or an object that can be converted into one. - * @exception IllegalArgumentException if the object cannot be converted. - * @return a DERVisibleString instance, or null - * - * @deprecated Use {@link ASN1VisibleString#getInstance(Object)} instead. - */ - public static DERVisibleString getInstance( - Object obj) - { - if (obj == null || obj instanceof DERVisibleString) - { - return (DERVisibleString)obj; - } - if (obj instanceof ASN1VisibleString) - { - return new DERVisibleString(((ASN1VisibleString)obj).contents, false); - } - if (obj instanceof byte[]) - { - try - { - return (DERVisibleString)fromByteArray((byte[])obj); - } - catch (Exception e) - { - throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); - } - } - - throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); - } - - /** - * Return a Visible String from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly tagged false - * otherwise. - * @exception IllegalArgumentException if the tagged object cannot be converted. - * @return a DERVisibleString instance, or null - * - * @deprecated Use - * {@link ASN1VisibleString#getInstance(ASN1TaggedObject, boolean)} - * instead. - */ - public static DERVisibleString getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Primitive o = obj.getObject(); - - if (explicit || o instanceof DERVisibleString) - { - return getInstance(o); - } - else - { - return new DERVisibleString(ASN1OctetString.getInstance(o).getOctets(), true); - } - } - /** * Basic constructor * diff --git a/core/src/main/java/org/bouncycastle/asn1/DLApplicationSpecific.java b/core/src/main/java/org/bouncycastle/asn1/DLApplicationSpecific.java deleted file mode 100644 index 358c181251..0000000000 --- a/core/src/main/java/org/bouncycastle/asn1/DLApplicationSpecific.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.bouncycastle.asn1; - -import java.io.IOException; - -import org.bouncycastle.util.Arrays; - -/** - * A DER encoding version of an application specific object. - * - * @deprecated Will be removed. See comments for - * {@link ASN1ApplicationSpecific}. - */ -public class DLApplicationSpecific - extends ASN1ApplicationSpecific -{ - /** - * Create an application specific object from the passed in data. This will assume - * the data does not represent a constructed object. - * - * @param tagNo the tag number for this object. - * @param contentsOctets the encoding of the object's body. - */ - public DLApplicationSpecific(int tagNo, byte[] contentsOctets) - { - super(new DLTaggedObject(false, BERTags.APPLICATION, tagNo, new DEROctetString(Arrays.clone(contentsOctets)))); - } - - /** - * Create an application specific object with a tagging of explicit/constructed. - * - * @param tagNo the tag number for this object. - * @param baseEncodable the object to be contained. - */ - public DLApplicationSpecific(int tagNo, ASN1Encodable baseEncodable) throws IOException - { - this(true, tagNo, baseEncodable); - } - - /** - * Create an application specific object with the tagging style given by the value of explicit. - * - * @param explicit true if the object is explicitly tagged. - * @param tagNo the tag number for this object. - * @param baseEncodable the object to be contained. - */ - public DLApplicationSpecific(boolean explicit, int tagNo, ASN1Encodable baseEncodable) throws IOException - { - super(new DLTaggedObject(explicit, BERTags.APPLICATION, tagNo, baseEncodable)); - } - - /** - * Create an application specific object which is marked as constructed - * - * @param tagNo the tag number for this object. - * @param contentsElements the objects making up the application specific object. - */ - public DLApplicationSpecific(int tagNo, ASN1EncodableVector contentsElements) - { - super(new DLTaggedObject(false, BERTags.APPLICATION, tagNo, DLFactory.createSequence(contentsElements))); - } - - DLApplicationSpecific(ASN1TaggedObject taggedObject) - { - super(taggedObject); - } - - ASN1Primitive toDLObject() - { - return this; - } -} diff --git a/core/src/main/java/org/bouncycastle/asn1/DLBitStringParser.java b/core/src/main/java/org/bouncycastle/asn1/DLBitStringParser.java index bc63f63376..ce92398ebc 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DLBitStringParser.java +++ b/core/src/main/java/org/bouncycastle/asn1/DLBitStringParser.java @@ -5,6 +5,8 @@ /** * Parser for a DL encoded BIT STRING. + * + * @deprecated Check for 'ASN1BitStringParser' instead */ public class DLBitStringParser implements ASN1BitStringParser diff --git a/core/src/main/java/org/bouncycastle/asn1/DLExternal.java b/core/src/main/java/org/bouncycastle/asn1/DLExternal.java index c3817a2fb1..8424fc50d0 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DLExternal.java +++ b/core/src/main/java/org/bouncycastle/asn1/DLExternal.java @@ -84,7 +84,7 @@ ASN1Sequence buildSequence() } if (dataValueDescriptor != null) { - v.add(dataValueDescriptor); + v.add(dataValueDescriptor.toDLObject()); } v.add(new DLTaggedObject(0 == encoding, encoding, externalContent)); diff --git a/core/src/main/java/org/bouncycastle/asn1/DLSequenceParser.java b/core/src/main/java/org/bouncycastle/asn1/DLSequenceParser.java index 1f5ed4e74d..83d1a2c047 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DLSequenceParser.java +++ b/core/src/main/java/org/bouncycastle/asn1/DLSequenceParser.java @@ -4,8 +4,8 @@ /** * Parser class for DL SEQUENCEs. - * - * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative + * + * @deprecated Check for 'ASN1SequenceParser' instead */ public class DLSequenceParser implements ASN1SequenceParser diff --git a/core/src/main/java/org/bouncycastle/asn1/DLSetParser.java b/core/src/main/java/org/bouncycastle/asn1/DLSetParser.java index 525b7884c2..4809f70194 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DLSetParser.java +++ b/core/src/main/java/org/bouncycastle/asn1/DLSetParser.java @@ -4,8 +4,8 @@ /** * Parser class for DL SETs. - * - * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative + * + * @deprecated Check for 'ASN1SetParser' instead */ public class DLSetParser implements ASN1SetParser diff --git a/core/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java b/core/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java index 41c936a3ba..c4e1859c2d 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java +++ b/core/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java @@ -88,11 +88,6 @@ void encode(ASN1OutputStream out, boolean withTag) throws IOException primitive.encode(out.getDLSubStream(), explicit); } - String getASN1Encoding() - { - return ASN1Encoding.DL; - } - ASN1Sequence rebuildConstructed(ASN1Primitive primitive) { return new DLSequence(primitive); diff --git a/core/src/main/java/org/bouncycastle/asn1/DLTaggedObjectParser.java b/core/src/main/java/org/bouncycastle/asn1/DLTaggedObjectParser.java index 0dd121f493..d7f5944f98 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DLTaggedObjectParser.java +++ b/core/src/main/java/org/bouncycastle/asn1/DLTaggedObjectParser.java @@ -17,16 +17,6 @@ class DLTaggedObjectParser _constructed = constructed; } - /** - * Return true if this tagged object is marked as constructed. - * - * @return true if constructed, false otherwise. - */ - public boolean isConstructed() - { - return _constructed; - } - /** * Return an in-memory, encodable, representation of the tagged object. * @@ -43,12 +33,7 @@ public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) { if (declaredExplicit) { - if (!_constructed) - { - throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)"); - } - - return _parser.parseObject(baseTagNo); + return checkConstructed().parseObject(baseTagNo); } return _constructed @@ -58,33 +43,26 @@ public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) public ASN1Encodable parseExplicitBaseObject() throws IOException { - if (!_constructed) - { - throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)"); - } - - return _parser.readObject(); + return checkConstructed().readObject(); } public ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException { - if (!_constructed) - { - throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)"); - } - - return _parser.parseTaggedObject(); + return checkConstructed().parseTaggedObject(); } public ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException { - // TODO[asn1] Special handling can be removed once ASN1ApplicationSpecific types removed. - if (BERTags.APPLICATION == baseTagClass) + return new DLTaggedObjectParser(baseTagClass, baseTagNo, _constructed, _parser); + } + + private ASN1StreamParser checkConstructed() throws IOException + { + if (!_constructed) { - // This cast is ensuring the current user-expected return type. - return (DLApplicationSpecific)_parser.loadTaggedDL(baseTagClass, baseTagNo, _constructed); + throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)"); } - return new DLTaggedObjectParser(baseTagClass, baseTagNo, _constructed, _parser); + return _parser; } } diff --git a/core/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java index 2701b3648a..6c5db36169 100644 --- a/core/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java +++ b/core/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java @@ -58,7 +58,7 @@ public interface BCObjectIdentifiers ASN1ObjectIdentifier bc_pbe_sha1_pkcs12 = bc_pbe_sha1.branch("2"); /** - * SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.1 + * SHA-256.PKCS5; 1.3.6.1.4.1.22554.1.2.1.1 */ ASN1ObjectIdentifier bc_pbe_sha256_pkcs5 = bc_pbe_sha256.branch("1"); /** @@ -114,12 +114,14 @@ public interface BCObjectIdentifiers ASN1ObjectIdentifier xmss = bc_sig.branch("2"); ASN1ObjectIdentifier xmss_SHA256ph = xmss.branch("1"); ASN1ObjectIdentifier xmss_SHA512ph = xmss.branch("2"); - ASN1ObjectIdentifier xmss_SHAKE128ph = xmss.branch("3"); - ASN1ObjectIdentifier xmss_SHAKE256ph = xmss.branch("4"); + ASN1ObjectIdentifier xmss_SHAKE128_512ph = xmss.branch("3"); + ASN1ObjectIdentifier xmss_SHAKE256_1024ph = xmss.branch("4"); ASN1ObjectIdentifier xmss_SHA256 = xmss.branch("5"); ASN1ObjectIdentifier xmss_SHA512 = xmss.branch("6"); ASN1ObjectIdentifier xmss_SHAKE128 = xmss.branch("7"); ASN1ObjectIdentifier xmss_SHAKE256 = xmss.branch("8"); + ASN1ObjectIdentifier xmss_SHAKE128ph = xmss.branch("9"); + ASN1ObjectIdentifier xmss_SHAKE256ph = xmss.branch("10"); /** * XMSS^MT @@ -127,47 +129,14 @@ public interface BCObjectIdentifiers ASN1ObjectIdentifier xmss_mt = bc_sig.branch("3"); ASN1ObjectIdentifier xmss_mt_SHA256ph = xmss_mt.branch("1"); ASN1ObjectIdentifier xmss_mt_SHA512ph = xmss_mt.branch("2"); - ASN1ObjectIdentifier xmss_mt_SHAKE128ph = xmss_mt.branch("3"); - ASN1ObjectIdentifier xmss_mt_SHAKE256ph = xmss_mt.branch("4"); + ASN1ObjectIdentifier xmss_mt_SHAKE128_512ph = xmss_mt.branch("3"); + ASN1ObjectIdentifier xmss_mt_SHAKE256_1024ph = xmss_mt.branch("4"); ASN1ObjectIdentifier xmss_mt_SHA256 = xmss_mt.branch("5"); ASN1ObjectIdentifier xmss_mt_SHA512 = xmss_mt.branch("6"); ASN1ObjectIdentifier xmss_mt_SHAKE128 = xmss_mt.branch("7"); ASN1ObjectIdentifier xmss_mt_SHAKE256 = xmss_mt.branch("8"); - - // old OIDs. - /** - * @deprecated use xmss_SHA256ph - */ - ASN1ObjectIdentifier xmss_with_SHA256 = xmss_SHA256ph; - /** - * @deprecated use xmss_SHA512ph - */ - ASN1ObjectIdentifier xmss_with_SHA512 = xmss_SHA512ph; - /** - * @deprecated use xmss_SHAKE128ph - */ - ASN1ObjectIdentifier xmss_with_SHAKE128 = xmss_SHAKE128ph; - /** - * @deprecated use xmss_SHAKE256ph - */ - ASN1ObjectIdentifier xmss_with_SHAKE256 = xmss_SHAKE256ph; - - /** - * @deprecated use xmss_mt_SHA256ph - */ - ASN1ObjectIdentifier xmss_mt_with_SHA256 = xmss_mt_SHA256ph; - /** - * @deprecated use xmss_mt_SHA512ph - */ - ASN1ObjectIdentifier xmss_mt_with_SHA512 = xmss_mt_SHA512ph; - /** - * @deprecated use xmss_mt_SHAKE128ph - */ - ASN1ObjectIdentifier xmss_mt_with_SHAKE128 = xmss_mt_SHAKE128; - /** - * @deprecated use xmss_mt_SHAKE256ph - */ - ASN1ObjectIdentifier xmss_mt_with_SHAKE256 = xmss_mt_SHAKE256; + ASN1ObjectIdentifier xmss_mt_SHAKE128ph = xmss_mt.branch("9"); + ASN1ObjectIdentifier xmss_mt_SHAKE256ph = xmss_mt.branch("10"); /** * qTESLA @@ -209,6 +178,44 @@ public interface BCObjectIdentifiers ASN1ObjectIdentifier sphincsPlus_haraka_256s_r3 = sphincsPlus.branch("17"); ASN1ObjectIdentifier sphincsPlus_haraka_256f_r3 = sphincsPlus.branch("18"); + ASN1ObjectIdentifier sphincsPlus_sha2_128s_r3_simple = sphincsPlus.branch("19"); + ASN1ObjectIdentifier sphincsPlus_sha2_128f_r3_simple = sphincsPlus.branch("20"); + ASN1ObjectIdentifier sphincsPlus_shake_128s_r3_simple = sphincsPlus.branch("21"); + ASN1ObjectIdentifier sphincsPlus_shake_128f_r3_simple = sphincsPlus.branch("22"); + ASN1ObjectIdentifier sphincsPlus_haraka_128s_r3_simple = sphincsPlus.branch("23"); + ASN1ObjectIdentifier sphincsPlus_haraka_128f_r3_simple = sphincsPlus.branch("24"); + + ASN1ObjectIdentifier sphincsPlus_sha2_192s_r3_simple = sphincsPlus.branch("25"); + ASN1ObjectIdentifier sphincsPlus_sha2_192f_r3_simple = sphincsPlus.branch("26"); + ASN1ObjectIdentifier sphincsPlus_shake_192s_r3_simple = sphincsPlus.branch("27"); + ASN1ObjectIdentifier sphincsPlus_shake_192f_r3_simple = sphincsPlus.branch("28"); + ASN1ObjectIdentifier sphincsPlus_haraka_192s_r3_simple = sphincsPlus.branch("29"); + ASN1ObjectIdentifier sphincsPlus_haraka_192f_r3_simple = sphincsPlus.branch("30"); + + ASN1ObjectIdentifier sphincsPlus_sha2_256s_r3_simple = sphincsPlus.branch("31"); + ASN1ObjectIdentifier sphincsPlus_sha2_256f_r3_simple = sphincsPlus.branch("32"); + ASN1ObjectIdentifier sphincsPlus_shake_256s_r3_simple = sphincsPlus.branch("33"); + ASN1ObjectIdentifier sphincsPlus_shake_256f_r3_simple = sphincsPlus.branch("34"); + ASN1ObjectIdentifier sphincsPlus_haraka_256s_r3_simple = sphincsPlus.branch("35"); + ASN1ObjectIdentifier sphincsPlus_haraka_256f_r3_simple = sphincsPlus.branch("36"); + + + ASN1ObjectIdentifier sphincsPlus_interop = new ASN1ObjectIdentifier("1.3.9999.6"); + + ASN1ObjectIdentifier sphincsPlus_sha2_128f = new ASN1ObjectIdentifier("1.3.9999.6.4.13"); + ASN1ObjectIdentifier sphincsPlus_sha2_128s = new ASN1ObjectIdentifier("1.3.9999.6.4.16"); + ASN1ObjectIdentifier sphincsPlus_sha2_192f = new ASN1ObjectIdentifier("1.3.9999.6.5.10"); + ASN1ObjectIdentifier sphincsPlus_sha2_192s = new ASN1ObjectIdentifier("1.3.9999.6.5.12"); + ASN1ObjectIdentifier sphincsPlus_sha2_256f = new ASN1ObjectIdentifier("1.3.9999.6.6.10"); + ASN1ObjectIdentifier sphincsPlus_sha2_256s = new ASN1ObjectIdentifier("1.3.9999.6.6.12"); + + ASN1ObjectIdentifier sphincsPlus_shake_128f = new ASN1ObjectIdentifier("1.3.9999.6.7.13"); + ASN1ObjectIdentifier sphincsPlus_shake_128s = new ASN1ObjectIdentifier("1.3.9999.6.7.16"); + ASN1ObjectIdentifier sphincsPlus_shake_192f = new ASN1ObjectIdentifier("1.3.9999.6.8.10"); + ASN1ObjectIdentifier sphincsPlus_shake_192s = new ASN1ObjectIdentifier("1.3.9999.6.8.12"); + ASN1ObjectIdentifier sphincsPlus_shake_256f = new ASN1ObjectIdentifier("1.3.9999.6.9.10"); + ASN1ObjectIdentifier sphincsPlus_shake_256s = new ASN1ObjectIdentifier("1.3.9999.6.9.12"); + /** * Picnic */ @@ -240,8 +247,8 @@ public interface BCObjectIdentifiers */ ASN1ObjectIdentifier falcon = bc_sig.branch("7"); - ASN1ObjectIdentifier falcon_512 = new ASN1ObjectIdentifier("1.3.9999.3.1"); // falcon.branch("1"); - ASN1ObjectIdentifier falcon_1024 = new ASN1ObjectIdentifier("1.3.9999.3.4"); // falcon.branch("2"); + ASN1ObjectIdentifier falcon_512 = new ASN1ObjectIdentifier("1.3.9999.3.6"); // falcon.branch("1"); + ASN1ObjectIdentifier falcon_1024 = new ASN1ObjectIdentifier("1.3.9999.3.9"); // falcon.branch("2"); /* * Dilithium @@ -249,9 +256,9 @@ public interface BCObjectIdentifiers ASN1ObjectIdentifier dilithium = bc_sig.branch("8"); // OpenSSL OIDs - ASN1ObjectIdentifier dilithium2 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.7.4.4"); // dilithium.branch("1"); - ASN1ObjectIdentifier dilithium3 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.7.6.5"); // dilithium.branch("2"); - ASN1ObjectIdentifier dilithium5 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.7.8.7"); // dilithium.branch("3"); + ASN1ObjectIdentifier dilithium2 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.12.4.4"); // dilithium.branch("1"); + ASN1ObjectIdentifier dilithium3 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.12.6.5"); // dilithium.branch("2"); + ASN1ObjectIdentifier dilithium5 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.12.8.7"); // dilithium.branch("3"); ASN1ObjectIdentifier dilithium2_aes = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.11.4.4"); // dilithium.branch("4"); ASN1ObjectIdentifier dilithium3_aes = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.11.6.5"); // dilithium.branch("5"); ASN1ObjectIdentifier dilithium5_aes = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.11.8.7"); // dilithium.branch("6"); @@ -261,7 +268,6 @@ public interface BCObjectIdentifiers */ ASN1ObjectIdentifier rainbow = bc_sig.branch("9"); - // OpenSSL OIDs ASN1ObjectIdentifier rainbow_III_classic = rainbow.branch("1"); ASN1ObjectIdentifier rainbow_III_circumzenithal = rainbow.branch("2"); ASN1ObjectIdentifier rainbow_III_compressed = rainbow.branch("3"); @@ -370,6 +376,8 @@ public interface BCObjectIdentifiers ASN1ObjectIdentifier ntruhps2048677 = pqc_kem_ntru.branch("2"); ASN1ObjectIdentifier ntruhps4096821 = pqc_kem_ntru.branch("3"); ASN1ObjectIdentifier ntruhrss701 = pqc_kem_ntru.branch("4"); + ASN1ObjectIdentifier ntruhps40961229 = pqc_kem_ntru.branch("5"); + ASN1ObjectIdentifier ntruhrss1373 = pqc_kem_ntru.branch("6"); /** * Kyber @@ -408,6 +416,7 @@ public interface BCObjectIdentifiers * BIKE **/ ASN1ObjectIdentifier pqc_kem_bike = bc_kem.branch("8"); + ASN1ObjectIdentifier bike128 = pqc_kem_bike.branch("1"); ASN1ObjectIdentifier bike192 = pqc_kem_bike.branch("2"); ASN1ObjectIdentifier bike256 = pqc_kem_bike.branch("3"); @@ -416,6 +425,7 @@ public interface BCObjectIdentifiers * HQC **/ ASN1ObjectIdentifier pqc_kem_hqc = bc_kem.branch("9"); + ASN1ObjectIdentifier hqc128 = pqc_kem_hqc.branch("1"); ASN1ObjectIdentifier hqc192 = pqc_kem_hqc.branch("2"); ASN1ObjectIdentifier hqc256 = pqc_kem_hqc.branch("3"); diff --git a/core/src/main/java/org/bouncycastle/asn1/bc/ExternalValue.java b/core/src/main/java/org/bouncycastle/asn1/bc/ExternalValue.java index 326995df72..9c31888bb0 100644 --- a/core/src/main/java/org/bouncycastle/asn1/bc/ExternalValue.java +++ b/core/src/main/java/org/bouncycastle/asn1/bc/ExternalValue.java @@ -3,44 +3,55 @@ import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; +import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralNames; +import org.bouncycastle.util.Arrays; /** * Based on External Keys And Signatures For Use In Internet PKI * draft-ounsworth-pq-external-pubkeys-00 *

      *  ExternalValue ::= SEQUENCE {
    - *      location GeneralName,    # MUST refer to a DER encoded SubjectPublicKeyInfo/Signature  (may be Base64)
    + *      location GeneralNames,    # MUST refer to a DER encoded SubjectPublicKeyInfo/Signature  (may be Base64)
      *      hashAlg AlgorithmIdentifier,
    - *      hashVal BIT STRING } 
    + *      hashVal OCTET STRING }
      * 
    */ public class ExternalValue extends ASN1Object { - private final GeneralName location; + private final GeneralNames location; private final AlgorithmIdentifier hashAlg; - private final ASN1BitString hashVal; + private final byte[] hashValue; public ExternalValue(GeneralName location, AlgorithmIdentifier hashAlg, byte[] hashVal) { - this.location = location; + this.location = new GeneralNames(location); this.hashAlg = hashAlg; - this.hashVal = new DERBitString(hashVal); + this.hashValue = Arrays.clone(hashVal); } private ExternalValue(ASN1Sequence seq) { if (seq.size() == 3) { - location = GeneralName.getInstance(seq.getObjectAt(0)); + location = GeneralNames.getInstance(seq.getObjectAt(0)); hashAlg = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); - hashVal = ASN1BitString.getInstance(seq.getObjectAt(2)); + if (seq.getObjectAt(2) instanceof ASN1BitString) // legacy implementation on 2021 draft + { + hashValue = ASN1BitString.getInstance(seq.getObjectAt(2)).getOctets(); + } + else + { + hashValue = ASN1OctetString.getInstance(seq.getObjectAt(2)).getOctets(); + } } else { @@ -64,7 +75,12 @@ else if (o != null) public GeneralName getLocation() { - return location; + return location.getNames()[0]; + } + + public GeneralName[] getLocations() + { + return location.getNames(); } public AlgorithmIdentifier getHashAlg() @@ -72,9 +88,20 @@ public AlgorithmIdentifier getHashAlg() return hashAlg; } + public byte[] getHashValue() + { + return Arrays.clone(hashValue); + } + + /** + * Get the hash value as a BIT STRING. + * + * @return the hash value as a BIT STRING + * @deprecated use getHash(), the internal encoding is now an OCTET STRING + */ public ASN1BitString getHashVal() { - return hashVal; + return new DERBitString(hashValue); } public ASN1Primitive toASN1Primitive() @@ -83,7 +110,7 @@ public ASN1Primitive toASN1Primitive() v.add(location); v.add(hashAlg); - v.add(hashVal); + v.add(new DEROctetString(hashValue)); return new DERSequence(v); } diff --git a/core/src/main/java/org/bouncycastle/asn1/bc/ObjectStoreIntegrityCheck.java b/core/src/main/java/org/bouncycastle/asn1/bc/ObjectStoreIntegrityCheck.java index 29385cfbdb..c1949829e2 100644 --- a/core/src/main/java/org/bouncycastle/asn1/bc/ObjectStoreIntegrityCheck.java +++ b/core/src/main/java/org/bouncycastle/asn1/bc/ObjectStoreIntegrityCheck.java @@ -48,7 +48,7 @@ private ObjectStoreIntegrityCheck(ASN1Encodable obj) else if (obj instanceof ASN1TaggedObject) { this.type = SIG_CHECK; - this.integrityCheck = SignatureCheck.getInstance(((ASN1TaggedObject)obj).getObject()); + this.integrityCheck = SignatureCheck.getInstance(((ASN1TaggedObject)obj).getExplicitBaseObject()); } else { diff --git a/core/src/main/java/org/bouncycastle/asn1/bc/SignatureCheck.java b/core/src/main/java/org/bouncycastle/asn1/bc/SignatureCheck.java index 9b8a72f2fe..babe612184 100644 --- a/core/src/main/java/org/bouncycastle/asn1/bc/SignatureCheck.java +++ b/core/src/main/java/org/bouncycastle/asn1/bc/SignatureCheck.java @@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; @@ -51,13 +52,13 @@ private SignatureCheck(ASN1Sequence seq) int index = 1; if (seq.getObjectAt(1) instanceof ASN1TaggedObject) { - this.certificates = ASN1Sequence.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(index++)).getObject()); + this.certificates = ASN1Sequence.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(index++)).getBaseUniversal(true, BERTags.SEQUENCE)); } else { this.certificates = null; } - this.signatureValue = DERBitString.getInstance(seq.getObjectAt(index)); + this.signatureValue = ASN1BitString.getInstance(seq.getObjectAt(index)); } public static SignatureCheck getInstance(Object o) diff --git a/core/src/main/java/org/bouncycastle/asn1/cryptopro/CryptoProObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/asn1/cryptopro/CryptoProObjectIdentifiers.java index 129905617a..48580c8f73 100644 --- a/core/src/main/java/org/bouncycastle/asn1/cryptopro/CryptoProObjectIdentifiers.java +++ b/core/src/main/java/org/bouncycastle/asn1/cryptopro/CryptoProObjectIdentifiers.java @@ -99,11 +99,6 @@ public interface CryptoProObjectIdentifiers static final ASN1ObjectIdentifier gostR3410_2001_CryptoPro_XchA = GOST_id.branch("36.0"); /** Gost R3410-2001-CryptoPro-XchA OID: 1.2.643.2.2.36.1 */ static final ASN1ObjectIdentifier gostR3410_2001_CryptoPro_XchB = GOST_id.branch("36.1"); - - /** Gost R3410-ElSqDH3410-default OID: 1.2.643.2.2.36.0 */ - static final ASN1ObjectIdentifier gost_ElSgDH3410_default = GOST_id.branch("36.0"); - /** Gost R3410-ElSqDH3410-1 OID: 1.2.643.2.2.36.1 */ - static final ASN1ObjectIdentifier gost_ElSgDH3410_1 = GOST_id.branch("36.1"); static final ASN1ObjectIdentifier gostR3410_2001_CryptoPro_ESDH = GOST_id.branch("96"); diff --git a/core/src/main/java/org/bouncycastle/asn1/cryptopro/ECGOST3410NamedCurves.java b/core/src/main/java/org/bouncycastle/asn1/cryptopro/ECGOST3410NamedCurves.java index aa60e68d39..27cf2d664b 100644 --- a/core/src/main/java/org/bouncycastle/asn1/cryptopro/ECGOST3410NamedCurves.java +++ b/core/src/main/java/org/bouncycastle/asn1/cryptopro/ECGOST3410NamedCurves.java @@ -5,10 +5,10 @@ import java.util.Hashtable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECParametersHolder; import org.bouncycastle.asn1.x9.X9ECPoint; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; @@ -127,36 +127,6 @@ protected X9ECParameters createParameters() } }; - /* - * GostR3410-2001-CryptoPro-XchB - */ - static X9ECParametersHolder gostR3410_2001_CryptoPro_XchB = new X9ECParametersHolder() - { - protected ECCurve createCurve() - { - BigInteger mod_p = fromHex("9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B"); - BigInteger mod_q = fromHex("9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9"); - - return configureCurve(new ECCurve.Fp( - mod_p, - fromHex("9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598"), - fromHex("805A"), - mod_q, ECConstants.ONE, true)); - } - - protected X9ECParameters createParameters() - { - byte[] S = null; - ECCurve curve = getCurve(); - - X9ECPoint G = configureBasepoint(curve, - ECConstants.ZERO, - fromHex("41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67")); - - return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S); - } - }; - /* * Tc26-Gost-3410-12-256-paramSetA */ @@ -295,8 +265,11 @@ static void defineCurve(String name, ASN1ObjectIdentifier oid, X9ECParametersHol defineCurve("GostR3410-2001-CryptoPro-B", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_B, gostR3410_2001_CryptoPro_B); defineCurve("GostR3410-2001-CryptoPro-C", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_C, gostR3410_2001_CryptoPro_C); defineCurve("GostR3410-2001-CryptoPro-XchA", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchA, gostR3410_2001_CryptoPro_A); - defineCurve("GostR3410-2001-CryptoPro-XchB", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchB, gostR3410_2001_CryptoPro_XchB); + defineCurve("GostR3410-2001-CryptoPro-XchB", CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_XchB, gostR3410_2001_CryptoPro_C); defineCurve("Tc26-Gost-3410-12-256-paramSetA", RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetA, id_tc26_gost_3410_12_256_paramSetA); + defineCurve("Tc26-Gost-3410-12-256-paramSetB", RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetB, gostR3410_2001_CryptoPro_A); + defineCurve("Tc26-Gost-3410-12-256-paramSetC", RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetC, gostR3410_2001_CryptoPro_B); + defineCurve("Tc26-Gost-3410-12-256-paramSetD", RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetD, gostR3410_2001_CryptoPro_C); defineCurve("Tc26-Gost-3410-12-512-paramSetA", RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetA, id_tc26_gost_3410_12_512_paramSetA); defineCurve("Tc26-Gost-3410-12-512-paramSetB", RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetB, id_tc26_gost_3410_12_512_paramSetB); defineCurve("Tc26-Gost-3410-12-512-paramSetC", RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetC, id_tc26_gost_3410_12_512_paramSetC); diff --git a/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410PublicKeyAlgParameters.java b/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410PublicKeyAlgParameters.java index 560cb4adca..f593fb21e1 100644 --- a/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410PublicKeyAlgParameters.java +++ b/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410PublicKeyAlgParameters.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; public class GOST3410PublicKeyAlgParameters extends ASN1Object @@ -60,8 +61,31 @@ public GOST3410PublicKeyAlgParameters( private GOST3410PublicKeyAlgParameters( ASN1Sequence seq) { - this.publicKeyParamSet = (ASN1ObjectIdentifier)seq.getObjectAt(0); - this.digestParamSet = (ASN1ObjectIdentifier)seq.getObjectAt(1); + this.publicKeyParamSet = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); + + if (publicKeyParamSet.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetA)) + { + if (seq.size() > 1) + { + digestParamSet = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(1)); + } + } + else if (publicKeyParamSet.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetB) + || publicKeyParamSet.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetC) + || publicKeyParamSet.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetD)) + { + if (seq.size() > 1) + { + throw new IllegalArgumentException("digestParamSet expected to be absent"); + } + } + else + { + if (seq.size() > 1) + { + digestParamSet = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(1)); + } + } if (seq.size() > 2) { @@ -89,7 +113,11 @@ public ASN1Primitive toASN1Primitive() ASN1EncodableVector v = new ASN1EncodableVector(3); v.add(publicKeyParamSet); - v.add(digestParamSet); + + if (digestParamSet != null) + { + v.add(digestParamSet); + } if (encryptionParamSet != null) { diff --git a/core/src/main/java/org/bouncycastle/asn1/gm/GMNamedCurves.java b/core/src/main/java/org/bouncycastle/asn1/gm/GMNamedCurves.java index b64094646b..c291ee6a7f 100644 --- a/core/src/main/java/org/bouncycastle/asn1/gm/GMNamedCurves.java +++ b/core/src/main/java/org/bouncycastle/asn1/gm/GMNamedCurves.java @@ -103,6 +103,7 @@ static void defineCurve(String name, ASN1ObjectIdentifier oid, X9ECParametersHol static { defineCurve("wapip192v1", GMObjectIdentifiers.wapip192v1, wapip192v1); + defineCurve("wapi192v1", GMObjectIdentifiers.wapi192v1, wapip192v1); defineCurve("sm2p256v1", GMObjectIdentifiers.sm2p256v1, sm2p256v1); } diff --git a/core/src/main/java/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java index ade67827d8..fa3048a5dc 100644 --- a/core/src/main/java/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java +++ b/core/src/main/java/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java @@ -4,6 +4,8 @@ public interface GMObjectIdentifiers { + //1.2.156.10197: Chinese Cryptography Standardization Technology Committee (CCSTC) + //1.2.156.11235: China Broadband Wireless IP Standard Group ASN1ObjectIdentifier sm_scheme = new ASN1ObjectIdentifier("1.2.156.10197.1"); ASN1ObjectIdentifier sm6_ecb = sm_scheme.branch("101.1"); @@ -46,7 +48,20 @@ public interface GMObjectIdentifiers ASN1ObjectIdentifier sm2exchange = sm_scheme.branch("301.2"); ASN1ObjectIdentifier sm2encrypt = sm_scheme.branch("301.3"); - ASN1ObjectIdentifier wapip192v1 = sm_scheme.branch("301.101"); + /** + * <Information security technology — Cryptographic application identifier criterion specification> + * <url>http://c.gb688.cn/bzgk/gb/showGb?type=online&hcno=252CF0F72A7BE339A56DEA7D774E8994</url>, + * Page 21 only cover from 301.1 to 301.3 + * */ + ASN1ObjectIdentifier wapip192v1 = sm_scheme.branch("301.101"); + /** + * <WAPI certificate management—Part 5: Example of certificate format (draft)> + * <url>http://www.chinabwips.org.cn/zqyjgs1.htm</url> and + * <url>http://www.chinabwips.org.cn/doc/101.pdf</url>, + * Page 9 and page 10 states the OID of ECDSA-192 algorithm based on SHA-256 is 1.2.156.11235.1.1.1 + * */ + ASN1ObjectIdentifier wapi192v1 = new ASN1ObjectIdentifier("1.2.156.11235.1.1.1"); + ASN1ObjectIdentifier wapi192v1_parameters = new ASN1ObjectIdentifier("1.2.156.11235.1.1.2.1"); ASN1ObjectIdentifier sm2encrypt_recommendedParameters = sm2encrypt.branch("1"); ASN1ObjectIdentifier sm2encrypt_specifiedParameters = sm2encrypt.branch("2"); diff --git a/core/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java index 572f6f4400..1cc67490fd 100644 --- a/core/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java +++ b/core/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java @@ -226,4 +226,89 @@ public interface NISTObjectIdentifiers static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_384 = sigAlgs.branch("15"); /** 2.16.840.1.101.3.4.3.16 */ static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_512 = sigAlgs.branch("16"); + + // "pure" ML-DSA + /** 2.16.840.1.101.3.4.3.17 */ + static final ASN1ObjectIdentifier id_ml_dsa_44 = sigAlgs.branch("17"); + /** 2.16.840.1.101.3.4.3.18 */ + static final ASN1ObjectIdentifier id_ml_dsa_65 = sigAlgs.branch("18"); + /** 2.16.840.1.101.3.4.3.19 */ + static final ASN1ObjectIdentifier id_ml_dsa_87 = sigAlgs.branch("19"); + // "pre-hash" ML-DSA + /** 2.16.840.1.101.3.4.3.32 */ + static final ASN1ObjectIdentifier id_hash_ml_dsa_44_with_sha512 = sigAlgs.branch("32"); + /** 2.16.840.1.101.3.4.3.33 */ + static final ASN1ObjectIdentifier id_hash_ml_dsa_65_with_sha512 = sigAlgs.branch("33"); + /** 2.16.840.1.101.3.4.3.34 */ + static final ASN1ObjectIdentifier id_hash_ml_dsa_87_with_sha512 = sigAlgs.branch("34"); + + // "pure" SLH-DSA + /** 2.16.840.1.101.3.4.3.20 */ + static final ASN1ObjectIdentifier id_slh_dsa_sha2_128s = sigAlgs.branch("20"); + /** 2.16.840.1.101.3.4.3.21 */ + static final ASN1ObjectIdentifier id_slh_dsa_sha2_128f = sigAlgs.branch("21"); + /** 2.16.840.1.101.3.4.3.22 */ + static final ASN1ObjectIdentifier id_slh_dsa_sha2_192s = sigAlgs.branch("22"); + /** 2.16.840.1.101.3.4.3.23 */ + static final ASN1ObjectIdentifier id_slh_dsa_sha2_192f = sigAlgs.branch("23"); + /** 2.16.840.1.101.3.4.3.24 */ + static final ASN1ObjectIdentifier id_slh_dsa_sha2_256s = sigAlgs.branch("24"); + /** 2.16.840.1.101.3.4.3.25 */ + static final ASN1ObjectIdentifier id_slh_dsa_sha2_256f = sigAlgs.branch("25"); + /** 2.16.840.1.101.3.4.3.26 */ + static final ASN1ObjectIdentifier id_slh_dsa_shake_128s = sigAlgs.branch("26"); + /** 2.16.840.1.101.3.4.3.27 */ + static final ASN1ObjectIdentifier id_slh_dsa_shake_128f = sigAlgs.branch("27"); + /** 2.16.840.1.101.3.4.3.28 */ + static final ASN1ObjectIdentifier id_slh_dsa_shake_192s = sigAlgs.branch("28"); + /** 2.16.840.1.101.3.4.3.29 */ + static final ASN1ObjectIdentifier id_slh_dsa_shake_192f = sigAlgs.branch("29"); + /** 2.16.840.1.101.3.4.3.30 */ + static final ASN1ObjectIdentifier id_slh_dsa_shake_256s = sigAlgs.branch("30"); + /** 2.16.840.1.101.3.4.3.31 */ + static final ASN1ObjectIdentifier id_slh_dsa_shake_256f = sigAlgs.branch("31"); + // "pre-hash" SLH-DSA + + /** 2.16.840.1.101.3.4.3.35 */ + static final ASN1ObjectIdentifier id_hash_slh_dsa_sha2_128s_with_sha256 = sigAlgs.branch("35"); + /** 2.16.840.1.101.3.4.3.36 */ + static final ASN1ObjectIdentifier id_hash_slh_dsa_sha2_128f_with_sha256 = sigAlgs.branch("36"); + /** 2.16.840.1.101.3.4.3.37 */ + static final ASN1ObjectIdentifier id_hash_slh_dsa_sha2_192s_with_sha512 = sigAlgs.branch("37"); + /** 2.16.840.1.101.3.4.3.38 */ + static final ASN1ObjectIdentifier id_hash_slh_dsa_sha2_192f_with_sha512 = sigAlgs.branch("38"); + /** 2.16.840.1.101.3.4.3.39 */ + static final ASN1ObjectIdentifier id_hash_slh_dsa_sha2_256s_with_sha512 = sigAlgs.branch("39"); + /** 2.16.840.1.101.3.4.3.40 */ + static final ASN1ObjectIdentifier id_hash_slh_dsa_sha2_256f_with_sha512 = sigAlgs.branch("40"); + /** 2.16.840.1.101.3.4.3.41 */ + static final ASN1ObjectIdentifier id_hash_slh_dsa_shake_128s_with_shake128 = sigAlgs.branch("41"); + /** 2.16.840.1.101.3.4.3.42 */ + static final ASN1ObjectIdentifier id_hash_slh_dsa_shake_128f_with_shake128 = sigAlgs.branch("42"); + /** 2.16.840.1.101.3.4.3.43 */ + static final ASN1ObjectIdentifier id_hash_slh_dsa_shake_192s_with_shake256 = sigAlgs.branch("43"); + /** 2.16.840.1.101.3.4.3.44 */ + static final ASN1ObjectIdentifier id_hash_slh_dsa_shake_192f_with_shake256 = sigAlgs.branch("44"); + /** 2.16.840.1.101.3.4.3.45 */ + static final ASN1ObjectIdentifier id_hash_slh_dsa_shake_256s_with_shake256 = sigAlgs.branch("45"); + /** 2.16.840.1.101.3.4.3.46 */ + static final ASN1ObjectIdentifier id_hash_slh_dsa_shake_256f_with_shake256 = sigAlgs.branch("46"); + + + // + // KEMs - Key-Establishment Mechanisms + // + /** + * 2.16.840.1.101.3.4.4 + */ + static final ASN1ObjectIdentifier kems = nistAlgorithm.branch("4"); + + // ML-KEM + /** 2.16.840.1.101.3.4.4.1 */ + static final ASN1ObjectIdentifier id_alg_ml_kem_512 = kems.branch("1"); + /** 2.16.840.1.101.3.4.4.2 */ + static final ASN1ObjectIdentifier id_alg_ml_kem_768 = kems.branch("2"); + /** 2.16.840.1.101.3.4.4.3 */ + static final ASN1ObjectIdentifier id_alg_ml_kem_1024 = kems.branch("3"); + } diff --git a/core/src/main/java/org/bouncycastle/asn1/ocsp/CertID.java b/core/src/main/java/org/bouncycastle/asn1/ocsp/CertID.java index 001b6e361c..80d33f85d5 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ocsp/CertID.java +++ b/core/src/main/java/org/bouncycastle/asn1/ocsp/CertID.java @@ -1,5 +1,6 @@ package org.bouncycastle.asn1.ocsp; +import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; @@ -7,6 +8,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; @@ -16,7 +18,7 @@ public class CertID AlgorithmIdentifier hashAlgorithm; ASN1OctetString issuerNameHash; ASN1OctetString issuerKeyHash; - ASN1Integer serialNumber; + ASN1Integer serialNumber; public CertID( AlgorithmIdentifier hashAlgorithm, @@ -81,6 +83,72 @@ public ASN1Integer getSerialNumber() return serialNumber; } + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + + if (o instanceof ASN1Encodable) + { + try + { + CertID other = CertID.getInstance(o); + + if (!this.hashAlgorithm.getAlgorithm().equals(other.hashAlgorithm.getAlgorithm())) + { + return false; + } + if (!isEqual(this.hashAlgorithm.getParameters(), other.hashAlgorithm.getParameters())) + { + return false; + } + + return issuerNameHash.equals(other.issuerNameHash) + && issuerKeyHash.equals(other.issuerKeyHash) + && serialNumber.equals(other.serialNumber); + } + catch (Exception e) + { + return false; + } + } + + return false; + } + + public int hashCode() + { + ASN1Encodable params = hashAlgorithm.getParameters(); + int hashCode = (params == null || DERNull.INSTANCE.equals(params)) ? 0 : params.hashCode(); + + return hashCode + 7 * (hashAlgorithm.getAlgorithm().hashCode() + + 7 * (issuerNameHash.hashCode() + 7 * (issuerKeyHash.hashCode() + 7 * serialNumber.hashCode()))); + } + + private boolean isEqual(ASN1Encodable a, ASN1Encodable b) + { + if (a == b) + { + return true; + } + + if (a == null) + { + return DERNull.INSTANCE.equals(b); + } + else + { + if (DERNull.INSTANCE.equals(a) && b == null) + { + return true; + } + + return a.equals(b); + } + } + /** * Produce an object suitable for an ASN1OutputStream. *
    diff --git a/core/src/main/java/org/bouncycastle/asn1/ocsp/CertStatus.java b/core/src/main/java/org/bouncycastle/asn1/ocsp/CertStatus.java
    index 070d0e8b69..ed1eec6892 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/ocsp/CertStatus.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/ocsp/CertStatus.java
    @@ -84,7 +84,7 @@ public static CertStatus getInstance(
             ASN1TaggedObject obj,
             boolean          explicit)
         {
    -        return getInstance(obj.getObject()); // must be explicitly tagged
    +        return getInstance(obj.getExplicitBaseTagged()); // must be explicitly tagged
         }
         
         public int getTagNo()
    diff --git a/core/src/main/java/org/bouncycastle/asn1/ocsp/ResponderID.java b/core/src/main/java/org/bouncycastle/asn1/ocsp/ResponderID.java
    index 9719047249..c851d79ab0 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/ocsp/ResponderID.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/ocsp/ResponderID.java
    @@ -60,7 +60,12 @@ public static ResponderID getInstance(
             ASN1TaggedObject obj,
             boolean          explicit)
         {
    -        return getInstance(obj.getObject()); // must be explicitly tagged
    +        if (!explicit)
    +        {
    +            throw new IllegalArgumentException("choice item must be explicitly tagged");
    +        }
    +
    +        return getInstance(obj.getExplicitBaseObject());
         }
     
         public byte[] getKeyHash()
    diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java
    index 16a4347ce4..1bb92f5543 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java
    @@ -22,8 +22,8 @@ public class CRLBag
         private CRLBag(
             ASN1Sequence seq)
         {
    -        this.crlId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
    -        this.crlValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getObject();
    +        this.crlId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
    +        this.crlValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getExplicitBaseObject();
         }
     
         public static CRLBag getInstance(Object o)
    diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java
    index f43f472bbf..87f03de71d 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java
    @@ -20,7 +20,7 @@ private CertBag(
             ASN1Sequence    seq)
         {
             this.certId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
    -        this.certValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getObject();
    +        this.certValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getExplicitBaseObject();
         }
     
         public static CertBag getInstance(Object o)
    diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java
    index a7b2bc7478..d28e942dd9 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java
    @@ -46,7 +46,7 @@ private ContentInfo(
     
             if (e.hasMoreElements())
             {
    -            content = ((ASN1TaggedObject)e.nextElement()).getObject();
    +            content = ((ASN1TaggedObject)e.nextElement()).getExplicitBaseObject();
             }
     
             isBer = seq instanceof BERSequence;
    diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptionScheme.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptionScheme.java
    index eeaa48d9a8..9c728cbaa4 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptionScheme.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptionScheme.java
    @@ -7,6 +7,7 @@
     import org.bouncycastle.asn1.ASN1Sequence;
     import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
     
    +// TODO[api] This is not supposed to be a separate type; remove and use AlgorithmIdentifier
     public class EncryptionScheme
         extends ASN1Object
     {
    diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/KeyDerivationFunc.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/KeyDerivationFunc.java
    index 83804f387a..dc6b250a14 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/KeyDerivationFunc.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/KeyDerivationFunc.java
    @@ -7,6 +7,7 @@
     import org.bouncycastle.asn1.ASN1Sequence;
     import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
     
    +// TODO[api] This is not supposed to be a separate type; remove and use AlgorithmIdentifier
     public class KeyDerivationFunc
         extends ASN1Object
     {
    diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
    index 9ac8c5eb48..2a78c1fb50 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
    @@ -164,7 +164,7 @@ private PrivateKeyInfo(ASN1Sequence seq)
                         throw new IllegalArgumentException("'publicKey' requires version v2(1) or later");
                     }
     
    -                this.publicKey = DERBitString.getInstance(tagged, false);
    +                this.publicKey = ASN1BitString.getInstance(tagged, false);
                     break;
                 }
                 default:
    @@ -195,6 +195,11 @@ public ASN1OctetString getPrivateKey()
             return new DEROctetString(privateKey.getOctets());
         }
     
    +    public int getPrivateKeyLength()
    +    {
    +        return privateKey.getOctetsLength();
    +    }
    +
         public ASN1Encodable parsePrivateKey()
             throws IOException
         {
    diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/RC2CBCParameter.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/RC2CBCParameter.java
    index cb25010f51..61bc110f1a 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/RC2CBCParameter.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/RC2CBCParameter.java
    @@ -72,6 +72,11 @@ public BigInteger getRC2ParameterVersion()
             return version.getValue();
         }
     
    +    public ASN1Integer getRC2ParameterVersionData()
    +    {
    +        return version;
    +    }
    +
         public byte[] getIV()
         {
             return iv.getOctets();
    diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
    index 45b93fcbe1..3aecefff09 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
    @@ -9,8 +9,8 @@
     import org.bouncycastle.asn1.DEROctetString;
     import org.bouncycastle.asn1.DERSequence;
     import org.bouncycastle.asn1.DERTaggedObject;
    -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
     import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers;
     
     public class RSAESOAEPparams
         extends ASN1Object
    diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java
    index fb89370c9a..713f83720e 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java
    @@ -11,8 +11,8 @@
     import org.bouncycastle.asn1.DERNull;
     import org.bouncycastle.asn1.DERSequence;
     import org.bouncycastle.asn1.DERTaggedObject;
    -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
     import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers;
     
     public class RSASSAPSSparams
         extends ASN1Object
    diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java
    index 1d39416fce..d6b508eb8d 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java
    @@ -57,7 +57,7 @@ private SafeBag(
             ASN1Sequence    seq)
         {
             this.bagId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
    -        this.bagValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getObject();
    +        this.bagValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getExplicitBaseObject();
             if (seq.size() == 3)
             {
                 this.bagAttributes = (ASN1Set)seq.getObjectAt(2);
    diff --git a/core/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java b/core/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java
    index f372ab8b3c..4ff5e2dcd9 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java
    @@ -1,6 +1,5 @@
     package org.bouncycastle.asn1.util;
     
    -import org.bouncycastle.asn1.ASN1ApplicationSpecific;
     import org.bouncycastle.asn1.ASN1BMPString;
     import org.bouncycastle.asn1.ASN1BitString;
     import org.bouncycastle.asn1.ASN1Boolean;
    @@ -116,10 +115,6 @@ else if (obj instanceof DERSet)
                     _dumpAsString(elementsIndent, verbose, set.getObjectAt(i).toASN1Primitive(), buf);
                 }
             }
    -        else if (obj instanceof ASN1ApplicationSpecific)
    -        {
    -            _dumpAsString(indent, verbose, ((ASN1ApplicationSpecific)obj).getTaggedObject(), buf);
    -        }
             else if (obj instanceof ASN1TaggedObject)
             {
                 buf.append(indent);
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/DirectoryString.java b/core/src/main/java/org/bouncycastle/asn1/x500/DirectoryString.java
    index ebdfdf4900..3d09921c9e 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x500/DirectoryString.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x500/DirectoryString.java
    @@ -64,7 +64,7 @@ public static DirectoryString getInstance(ASN1TaggedObject o, boolean explicit)
                 throw new IllegalArgumentException("choice item must be explicitly tagged");
             }
     
    -        return getInstance(o.getObject());
    +        return getInstance(o.getExplicitBaseObject());
         }
     
         private DirectoryString(
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/RDN.java b/core/src/main/java/org/bouncycastle/asn1/x500/RDN.java
    index 1475b4a4c5..a5f092db3c 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x500/RDN.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x500/RDN.java
    @@ -1,12 +1,11 @@
     package org.bouncycastle.asn1.x500;
     
     import org.bouncycastle.asn1.ASN1Encodable;
    -import org.bouncycastle.asn1.ASN1EncodableVector;
     import org.bouncycastle.asn1.ASN1Object;
     import org.bouncycastle.asn1.ASN1ObjectIdentifier;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1Set;
    -import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
     import org.bouncycastle.asn1.DERSet;
     
     /**
    @@ -19,6 +18,7 @@ public class RDN
     
         private RDN(ASN1Set values)
         {
    +        // TODO Require minimum size of 1?
             this.values = values;
         }
     
    @@ -36,6 +36,11 @@ else if (obj != null)
             return null;
         }
     
    +    public static RDN getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit)
    +    {
    +        return new RDN(ASN1Set.getInstance(taggedObject, declaredExplicit));
    +    }
    +
         /**
          * Create a single valued RDN.
          *
    @@ -44,12 +49,7 @@ else if (obj != null)
          */
         public RDN(ASN1ObjectIdentifier oid, ASN1Encodable value)
         {
    -        ASN1EncodableVector v = new ASN1EncodableVector(2);
    -
    -        v.add(oid);
    -        v.add(value);
    -
    -        this.values = new DERSet(new DERSequence(v));
    +        this(new AttributeTypeAndValue(oid, value));
         }
     
         public RDN(AttributeTypeAndValue attrTAndV)
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/X500Name.java b/core/src/main/java/org/bouncycastle/asn1/x500/X500Name.java
    index 50efe506a7..bf6fdd7cbc 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x500/X500Name.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x500/X500Name.java
    @@ -1,7 +1,5 @@
     package org.bouncycastle.asn1.x500;
     
    -import java.util.Enumeration;
    -
     import org.bouncycastle.asn1.ASN1Choice;
     import org.bouncycastle.asn1.ASN1Encodable;
     import org.bouncycastle.asn1.ASN1Object;
    @@ -111,18 +109,18 @@ private X500Name(
             X500NameStyle style,
             ASN1Sequence  seq)
         {
    +        int count = seq.size();
    +
             this.style = style;
    -        this.rdns = new RDN[seq.size()];
    +        this.rdns = new RDN[count];
     
             boolean inPlace = true;
    -
    -        int index = 0;
    -        for (Enumeration e = seq.getObjects(); e.hasMoreElements();)
    +        for (int index = 0; index < count; ++index)
             {
    -            Object element = e.nextElement();
    +            ASN1Encodable element = seq.getObjectAt(index);
                 RDN rdn = RDN.getInstance(element);
                 inPlace &= (rdn == element);
    -            rdns[index++] = rdn;
    +            rdns[index] = rdn;
             }
     
             if (inPlace)
    @@ -229,6 +227,11 @@ public RDN[] getRDNs(ASN1ObjectIdentifier attributeType)
             return res;
         }
     
    +    public int size()
    +    {
    +        return rdns.length;
    +    }
    +
         public ASN1Primitive toASN1Primitive()
         {
             return rdnSeq;
    @@ -265,14 +268,14 @@ public boolean equals(Object obj)
             
             ASN1Primitive derO = ((ASN1Encodable)obj).toASN1Primitive();
     
    -        if (this.toASN1Primitive().equals(derO))
    +        if (toASN1Primitive().equals(derO))
             {
                 return true;
             }
     
             try
             {
    -            return style.areEqual(this, new X500Name(ASN1Sequence.getInstance(((ASN1Encodable)obj).toASN1Primitive())));
    +            return style.areEqual(this, getInstance(obj));
             }
             catch (Exception e)
             {
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java b/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
    index 8d801b3d6c..6f20e2309d 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
    @@ -131,19 +131,22 @@ protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid, String value
     
         public boolean areEqual(X500Name name1, X500Name name2)
         {
    -        RDN[] rdns1 = name1.getRDNs();
    -        RDN[] rdns2 = name2.getRDNs();
    -
    -        if (rdns1.length != rdns2.length)
    +        if (name1.size() != name2.size())
             {
                 return false;
             }
     
    +        RDN[] rdns1 = name1.getRDNs();
    +        RDN[] rdns2 = name2.getRDNs();
    +
             boolean reverse = false;
     
    -        if (rdns1[0].getFirst() != null && rdns2[0].getFirst() != null)
    +        AttributeTypeAndValue first1 = rdns1[0].getFirst();
    +        AttributeTypeAndValue first2 = rdns2[0].getFirst();
    +
    +        if (first1 != null && first2 != null)
             {
    -            reverse = !rdns1[0].getFirst().getType().equals(rdns2[0].getFirst().getType());  // guess forward
    +            reverse = !first1.getType().equals(first2.getType());  // guess forward
             }
     
             for (int i = 0; i != rdns1.length; i++)
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStrictStyle.java b/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStrictStyle.java
    index eb627c0e1e..dd5f15f621 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStrictStyle.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStrictStyle.java
    @@ -15,14 +15,14 @@ public class BCStrictStyle
     
         public boolean areEqual(X500Name name1, X500Name name2)
         {
    -        RDN[] rdns1 = name1.getRDNs();
    -        RDN[] rdns2 = name2.getRDNs();
    -
    -        if (rdns1.length != rdns2.length)
    +        if (name1.size() != name2.size())
             {
                 return false;
             }
     
    +        RDN[] rdns1 = name1.getRDNs();
    +        RDN[] rdns2 = name2.getRDNs();
    +
             for (int i = 0; i != rdns1.length; i++)
             {
                 if (!rdnAreEqual(rdns1[i], rdns2[i]))
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java b/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java
    index 678207208d..9b3ea955e2 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java
    @@ -187,6 +187,21 @@ public class BCStyle
          */
         public static final ASN1ObjectIdentifier UID = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1");
     
    +    /**
    +     * CA/Browser Forum https://cabforum.org/uploads/CA-Browser-Forum-BR-v2.0.0.pdf, Table 78
    +     */
    +    public static final ASN1ObjectIdentifier JURISDICTION_C = new ASN1ObjectIdentifier("1.3.6.1.4.1.311.60.2.1.3");
    +
    +    /**
    +     * CA/Browser Forum https://cabforum.org/uploads/CA-Browser-Forum-BR-v2.0.0.pdf, Table 78
    +     */
    +    public static final ASN1ObjectIdentifier JURISDICTION_ST = new ASN1ObjectIdentifier("1.3.6.1.4.1.311.60.2.1.2");
    +
    +    /**
    +     * CA/Browser Forum https://cabforum.org/uploads/CA-Browser-Forum-BR-v2.0.0.pdf, Table 78
    +     */
    +    public static final ASN1ObjectIdentifier JURISDICTION_L = new ASN1ObjectIdentifier("1.3.6.1.4.1.311.60.2.1.1");
    +
         /**
          * default look up table translating OID values into their common symbols following
          * the convention in RFC 2253 with a few extras
    @@ -235,6 +250,9 @@ public class BCStyle
             DefaultSymbols.put(TELEPHONE_NUMBER, "TelephoneNumber");
             DefaultSymbols.put(NAME, "Name");
             DefaultSymbols.put(ORGANIZATION_IDENTIFIER, "organizationIdentifier");
    +        DefaultSymbols.put(JURISDICTION_C, "jurisdictionCountry");
    +        DefaultSymbols.put(JURISDICTION_ST, "jurisdictionState");
    +        DefaultSymbols.put(JURISDICTION_L, "jurisdictionLocality");
     
             DefaultLookUp.put("c", C);
             DefaultLookUp.put("o", O);
    @@ -273,6 +291,9 @@ public class BCStyle
             DefaultLookUp.put("telephonenumber", TELEPHONE_NUMBER);
             DefaultLookUp.put("name", NAME);
             DefaultLookUp.put("organizationidentifier", ORGANIZATION_IDENTIFIER);
    +        DefaultLookUp.put("jurisdictioncountry", JURISDICTION_C);
    +        DefaultLookUp.put("jurisdictionstate", JURISDICTION_ST);
    +        DefaultLookUp.put("jurisdictionlocality", JURISDICTION_L);
         }
     
         /**
    @@ -299,12 +320,12 @@ else if (oid.equals(DATE_OF_BIRTH))  // accept time string as well as # (for com
             {
                 return new ASN1GeneralizedTime(value);
             }
    -        else if (oid.equals(C) || oid.equals(SN) || oid.equals(DN_QUALIFIER)
    -            || oid.equals(TELEPHONE_NUMBER))
    +        else if (oid.equals(C) || oid.equals(SERIALNUMBER) || oid.equals(DN_QUALIFIER)
    +            || oid.equals(TELEPHONE_NUMBER) || oid.equals(JURISDICTION_C))
             {
                 return new DERPrintableString(value);
             }
    -        
    +
             return super.encodeStringValue(oid, value);
         }
     
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java b/core/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java
    index 5d79011b94..958de0c2ad 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java
    @@ -22,12 +22,15 @@ public class IETFUtils
     {
         private static String unescape(String elt)
         {
    -        if (elt.length() == 0 || (elt.indexOf('\\') < 0 && elt.indexOf('"') < 0))
    +        if (elt.length() == 0)
    +        {
    +            return elt;
    +        }
    +        if (elt.indexOf('\\') < 0 && elt.indexOf('"') < 0)
             {
                 return elt.trim();
             }
     
    -        char[] elts = elt.toCharArray();
             boolean escaped = false;
             boolean quoted = false;
             StringBuffer buf = new StringBuffer(elt.length());
    @@ -35,9 +38,9 @@ private static String unescape(String elt)
     
             // if it's an escaped hash string and not an actual encoding in string form
             // we need to leave it escaped.
    -        if (elts[0] == '\\')
    +        if (elt.charAt(0) == '\\')
             {
    -            if (elts[1] == '#')
    +            if (elt.charAt(1) == '#')
                 {
                     start = 2;
                     buf.append("\\#");
    @@ -48,9 +51,9 @@ private static String unescape(String elt)
             int     lastEscaped = 0;
             char    hex1 = 0;
     
    -        for (int i = start; i != elts.length; i++)
    +        for (int i = start; i != elt.length(); i++)
             {
    -            char c = elts[i];
    +            char c = elt.charAt(i);
     
                 if (c != ' ')
                 {
    @@ -66,8 +69,8 @@ private static String unescape(String elt)
                     else
                     {
                         buf.append(c);
    +                    escaped = false;
                     }
    -                escaped = false;
                 }
                 else if (c == '\\' && !(escaped || quoted))
                 {
    @@ -128,81 +131,93 @@ private static int convertHex(char c)
     
         public static RDN[] rDNsFromString(String name, X500NameStyle x500Style)
         {
    -        X500NameTokenizer nTok = new X500NameTokenizer(name);
    +        X500NameTokenizer tokenizer = new X500NameTokenizer(name);
             X500NameBuilder builder = new X500NameBuilder(x500Style);
     
    -        while (nTok.hasMoreTokens())
    -        {
    -            String  token = nTok.nextToken();
    +        addRDNs(x500Style, builder, tokenizer);
     
    -            if (token.indexOf('+') > 0)
    -            {
    -                X500NameTokenizer   pTok = new X500NameTokenizer(token, '+');
    -                X500NameTokenizer   vTok = new X500NameTokenizer(pTok.nextToken(), '=');
    -
    -                String              attr = vTok.nextToken();
    +        // TODO There's an unnecessary clone of the RDNs array happening here
    +        return builder.build().getRDNs();
    +    }
     
    -                if (!vTok.hasMoreTokens())
    -                {
    -                    throw new IllegalArgumentException("badly formatted directory string");
    -                }
    +    private static void addRDNs(X500NameStyle style, X500NameBuilder builder, X500NameTokenizer tokenizer)
    +    {
    +        String token;
    +        while ((token = tokenizer.nextToken()) != null)
    +        {
    +            if (token.indexOf('+') >= 0)
    +            {
    +                addMultiValuedRDN(style, builder, new X500NameTokenizer(token, '+'));
    +            }
    +            else
    +            {
    +                addRDN(style, builder, token);
    +            }
    +        }
    +    }
     
    -                String               value = vTok.nextToken();
    -                ASN1ObjectIdentifier oid = x500Style.attrNameToOID(attr.trim());
    +    private static void addMultiValuedRDN(X500NameStyle style, X500NameBuilder builder, X500NameTokenizer tokenizer)
    +    {
    +        String token = tokenizer.nextToken();
    +        if (token == null)
    +        {
    +            throw new IllegalArgumentException("badly formatted directory string");
    +        }
     
    -                if (pTok.hasMoreTokens())
    -                {
    -                    Vector oids = new Vector();
    -                    Vector values = new Vector();
    +        if (!tokenizer.hasMoreTokens())
    +        {
    +            addRDN(style, builder, token);
    +            return;
    +        }
     
    -                    oids.addElement(oid);
    -                    values.addElement(unescape(value));
    +        Vector oids = new Vector();
    +        Vector values = new Vector();
     
    -                    while (pTok.hasMoreTokens())
    -                    {
    -                        vTok = new X500NameTokenizer(pTok.nextToken(), '=');
    +        do
    +        {
    +            collectAttributeTypeAndValue(style, oids, values, token);
    +            token = tokenizer.nextToken();
    +        }
    +        while (token != null);
     
    -                        attr = vTok.nextToken();
    +        builder.addMultiValuedRDN(toOIDArray(oids), toValueArray(values));
    +    }
     
    -                        if (!vTok.hasMoreTokens())
    -                        {
    -                            throw new IllegalArgumentException("badly formatted directory string");
    -                        }
    +    private static void addRDN(X500NameStyle style, X500NameBuilder builder, String token)
    +    {
    +        X500NameTokenizer tokenizer = new X500NameTokenizer(token, '=');
     
    -                        value = vTok.nextToken();
    -                        oid = x500Style.attrNameToOID(attr.trim());
    +        String typeToken = nextToken(tokenizer, true);
    +        String valueToken = nextToken(tokenizer, false);
     
    +        ASN1ObjectIdentifier oid = style.attrNameToOID(typeToken.trim());
    +        String value = unescape(valueToken);
     
    -                        oids.addElement(oid);
    -                        values.addElement(unescape(value));
    -                    }
    +        builder.addRDN(oid, value);
    +    }
     
    -                    builder.addMultiValuedRDN(toOIDArray(oids), toValueArray(values));
    -                }
    -                else
    -                {
    -                    builder.addRDN(oid, unescape(value));
    -                }
    -            }
    -            else
    -            {
    -                X500NameTokenizer   vTok = new X500NameTokenizer(token, '=');
    +    private static void collectAttributeTypeAndValue(X500NameStyle style, Vector oids, Vector values, String token)
    +    {
    +        X500NameTokenizer tokenizer = new X500NameTokenizer(token, '=');
     
    -                String              attr = vTok.nextToken();
    +        String typeToken = nextToken(tokenizer, true);
    +        String valueToken = nextToken(tokenizer, false);
     
    -                if (!vTok.hasMoreTokens())
    -                {
    -                    throw new IllegalArgumentException("badly formatted directory string");
    -                }
    +        ASN1ObjectIdentifier oid = style.attrNameToOID(typeToken.trim());
    +        String value = unescape(valueToken);
     
    -                String               value = vTok.nextToken();
    -                ASN1ObjectIdentifier oid = x500Style.attrNameToOID(attr.trim());
    +        oids.addElement(oid);
    +        values.addElement(value);
    +    }
     
    -                builder.addRDN(oid, unescape(value));
    -            }
    +    private static String nextToken(X500NameTokenizer tokenizer, boolean expectMoreTokens)
    +    {
    +        String token = tokenizer.nextToken();
    +        if (token == null || tokenizer.hasMoreTokens() != expectMoreTokens)
    +        {
    +            throw new IllegalArgumentException("badly formatted directory string");
             }
    -
    -        return builder.build().getRDNs();
    +        return token;
         }
     
         private static String[] toValueArray(Vector values)
    @@ -257,26 +272,26 @@ public static String[] findAttrNamesForOID(
             return aliases;
         }
     
    -    public static ASN1ObjectIdentifier decodeAttrName(
    -        String      name,
    -        Hashtable   lookUp)
    +    public static ASN1ObjectIdentifier decodeAttrName(String name, Hashtable lookUp)
         {
    -        if (Strings.toUpperCase(name).startsWith("OID."))
    +        if (name.regionMatches(true, 0, "OID.", 0, 4))
             {
                 return new ASN1ObjectIdentifier(name.substring(4));
             }
    -        else if (name.charAt(0) >= '0' && name.charAt(0) <= '9')
    +
    +        ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.tryFromID(name);
    +        if (oid != null)
             {
    -            return new ASN1ObjectIdentifier(name);
    +            return oid;
             }
     
    -        ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)lookUp.get(Strings.toLowerCase(name));
    -        if (oid == null)
    +        oid = (ASN1ObjectIdentifier)lookUp.get(Strings.toLowerCase(name));
    +        if (oid != null)
             {
    -            throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name");
    +            return oid;
             }
     
    -        return oid;
    +        throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name");
         }
     
         public static ASN1Encodable valueFromHexString(
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java b/core/src/main/java/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java
    index b7e52f22f4..30dbf7a37b 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java
    @@ -8,83 +8,78 @@
      */
     public class X500NameTokenizer
     {
    -    private String          value;
    -    private int             index;
    -    private char            separator;
    -    private StringBuffer    buf = new StringBuffer();
    +    private final String value;
    +    private final char separator;
     
    -    public X500NameTokenizer(
    -        String  oid)
    +    private int index;
    +
    +    public X500NameTokenizer(String oid)
         {
             this(oid, ',');
         }
    -    
    -    public X500NameTokenizer(
    -        String  oid,
    -        char    separator)
    +
    +    public X500NameTokenizer(String oid, char separator)
         {
    +        if (oid == null)
    +        {
    +            throw new NullPointerException();
    +        }
    +        if (separator == '"' || separator == '\\')
    +        {
    +            throw new IllegalArgumentException("reserved separator character");
    +        }
    +
             this.value = oid;
    -        this.index = -1;
             this.separator = separator;
    +        this.index = oid.length() < 1 ? 0 : -1;
         }
     
         public boolean hasMoreTokens()
         {
    -        return (index != value.length());
    +        return index < value.length();
         }
     
         public String nextToken()
         {
    -        if (index == value.length())
    +        if (index >= value.length())
             {
                 return null;
             }
     
    -        int     end = index + 1;
             boolean quoted = false;
             boolean escaped = false;
     
    -        buf.setLength(0);
    -
    -        while (end != value.length())
    +        int beginIndex = index + 1;
    +        while (++index < value.length())
             {
    -            char    c = value.charAt(end);
    +            char c = value.charAt(index);
     
    -            if (c == '"')
    +            if (escaped)
                 {
    -                if (!escaped)
    -                {
    -                    quoted = !quoted;
    -                }
    -                buf.append(c);
                     escaped = false;
                 }
    -            else
    +            else if (c == '"')
                 {
    -                if (escaped || quoted)
    -                {
    -                    buf.append(c);
    -                    escaped = false;
    -                }
    -                else if (c == '\\')
    -                {
    -                    buf.append(c);
    -                    escaped = true;
    -                }
    -                else if (c == separator)
    -                {
    -                    break;
    -                }
    -                else
    -                {
    -                    buf.append(c);
    -                }
    +                quoted = !quoted;
    +            }
    +            else if (quoted)
    +            {
    +            }
    +            else if (c == '\\')
    +            {
    +                escaped = true;
    +            }
    +            else if (c == separator)
    +            {
    +                return value.substring(beginIndex, index);
                 }
    -            end++;
             }
     
    -        index = end;
    +        if (escaped || quoted)
    +        {
    +            throw new IllegalArgumentException("badly formatted directory string");
    +        }
     
    -        return buf.toString();
    +        return value.substring(beginIndex, index);
         }
     }
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/AttCertIssuer.java b/core/src/main/java/org/bouncycastle/asn1/x509/AttCertIssuer.java
    index 21907c686c..4c53c2ab86 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/AttCertIssuer.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/AttCertIssuer.java
    @@ -46,7 +46,7 @@ public static AttCertIssuer getInstance(
             ASN1TaggedObject obj,
             boolean          explicit)
         {
    -        return getInstance(obj.getObject()); // must be explicitly tagged
    +        return getInstance(obj.getExplicitBaseObject()); // must be explicitly tagged
         }
     
         /**
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificate.java b/core/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificate.java
    index f43e1442c9..7eb26be93a 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificate.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificate.java
    @@ -36,25 +36,23 @@ else if (obj != null)
         public AttributeCertificate(
             AttributeCertificateInfo    acinfo,
             AlgorithmIdentifier         signatureAlgorithm,
    -        DERBitString                signatureValue)
    +        ASN1BitString               signatureValue)
         {
             this.acinfo = acinfo;
             this.signatureAlgorithm = signatureAlgorithm;
             this.signatureValue = signatureValue;
         }
     
    -    private AttributeCertificate(
    -        ASN1Sequence    seq)
    +    private AttributeCertificate(ASN1Sequence seq)
         {
             if (seq.size() != 3)
             {
    -            throw new IllegalArgumentException("Bad sequence size: "
    -                    + seq.size());
    +            throw new IllegalArgumentException("Bad sequence size: " + seq.size());
             }
     
             this.acinfo = AttributeCertificateInfo.getInstance(seq.getObjectAt(0));
             this.signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
    -        this.signatureValue = DERBitString.getInstance(seq.getObjectAt(2));
    +        this.signatureValue = ASN1BitString.getInstance(seq.getObjectAt(2));
         }
         
         public AttributeCertificateInfo getAcinfo()
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java b/core/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java
    index fa4c53d7ca..4773c7f863 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java
    @@ -122,6 +122,11 @@ public BigInteger getPathLenConstraint()
             return null;
         }
     
    +    public ASN1Integer getPathLenConstraintInteger()
    +    {
    +        return pathLenConstraint;
    +    }
    +
         /**
          * Produce an object suitable for an ASN1OutputStream.
          * 
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/DeltaCertificateDescriptor.java b/core/src/main/java/org/bouncycastle/asn1/x509/DeltaCertificateDescriptor.java
    new file mode 100644
    index 0000000000..d562595a6b
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/DeltaCertificateDescriptor.java
    @@ -0,0 +1,274 @@
    +package org.bouncycastle.asn1.x509;
    +
    +import java.util.Enumeration;
    +
    +import org.bouncycastle.asn1.ASN1BitString;
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.x500.X500Name;
    +
    +/**
    + * 
    + *     DeltaCertificateDescriptor ::= SEQUENCE {
    + *      serialNumber          CertificateSerialNumber,
    + *      signature             [0] IMPLICIT AlgorithmIdentifier
    + *           {SIGNATURE_ALGORITHM, {...}} OPTIONAL,
    + *      issuer                [1] IMPLICIT Name OPTIONAL,
    + *      validity              [2] IMPLICIT Validity OPTIONAL,
    + *      subject               [3] IMPLICIT Name OPTIONAL,
    + *      subjectPublicKeyInfo  SubjectPublicKeyInfo,
    + *      extensions            [4] IMPLICIT Extensions{CertExtensions}
    + *           OPTIONAL,
    + *      signatureValue        BIT STRING
    + *    }
    + *    
    + */ +public class DeltaCertificateDescriptor + extends ASN1Object +{ + private final ASN1Integer serialNumber; + + private AlgorithmIdentifier signature; + private X500Name issuer; + private ASN1Sequence validity; + private X500Name subject; + private SubjectPublicKeyInfo subjectPublicKeyInfo; + private Extensions extensions; + + private final ASN1BitString signatureValue; + + public static DeltaCertificateDescriptor getInstance( + Object obj) + { + if (obj instanceof DeltaCertificateDescriptor) + { + return (DeltaCertificateDescriptor)obj; + } + else if (obj != null) + { + return new DeltaCertificateDescriptor(ASN1Sequence.getInstance(obj)); + } + + return null; + } + + /** + * Retrieve a DeltaCertificateDescriptor for a passed in Extensions object, if present. + * + * @param extensions the extensions object to be examined. + * @return the DeltaCertificateDescriptor, null if the extension is not present. + */ + public static DeltaCertificateDescriptor fromExtensions(Extensions extensions) + { + return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.deltaCertificateDescriptor)); + } + + private DeltaCertificateDescriptor(ASN1Sequence seq) + { + this.serialNumber = ASN1Integer.getInstance(seq.getObjectAt(0)); + + int idx = 1; + ASN1Encodable next = seq.getObjectAt(idx); + while (next instanceof ASN1TaggedObject) + { + ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next); + switch (tagged.getTagNo()) + { + case 0: + signature = AlgorithmIdentifier.getInstance(tagged, false); + break; + case 1: + issuer = X500Name.getInstance(tagged, true); // issuer + break; + case 2: + validity = ASN1Sequence.getInstance(tagged, false); + break; + case 3: + subject = X500Name.getInstance(tagged, true); // subject + break; + } + next = seq.getObjectAt(idx++); + } + + subjectPublicKeyInfo = subjectPublicKeyInfo.getInstance(next); + + next = seq.getObjectAt(idx); + while (next instanceof ASN1TaggedObject) + { + ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next); + switch (tagged.getTagNo()) + { + case 4: + extensions = Extensions.getInstance(tagged, false); + break; + } + next = seq.getObjectAt(idx++); + } + + signatureValue = ASN1BitString.getInstance(next); + } + + public ASN1Integer getSerialNumber() + { + return serialNumber; + } + + public AlgorithmIdentifier getSignature() + { + return signature; + } + + public X500Name getIssuer() + { + return issuer; + } + + public ASN1Sequence getValidity() + { + return validity; + } + + public X500Name getSubject() + { + return subject; + } + + public SubjectPublicKeyInfo getSubjectPublicKeyInfo() + { + return subjectPublicKeyInfo; + } + + public Extensions getExtensions() + { + return extensions; + } + + public ASN1BitString getSignatureValue() + { + return signatureValue; + } + + public DeltaCertificateDescriptor trimTo(TBSCertificate baseTbsCertificate, Extensions tbsExtensions) + { + AlgorithmIdentifier signature = baseTbsCertificate.signature; + X500Name issuer = baseTbsCertificate.issuer; + ASN1Sequence validity = new DERSequence(new ASN1Encodable[] + { + baseTbsCertificate.startDate, baseTbsCertificate.endDate + }); + X500Name subject = baseTbsCertificate.subject; + ASN1Sequence s = ASN1Sequence.getInstance(toASN1Primitive()); + ASN1EncodableVector v = new ASN1EncodableVector(); + + Enumeration en = s.getObjects(); + v.add((ASN1Encodable)en.nextElement()); + + ASN1Encodable next = (ASN1Encodable)en.nextElement(); + while (next instanceof ASN1TaggedObject) + { + ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next); + switch (tagged.getTagNo()) + { + case 0: + AlgorithmIdentifier sig = AlgorithmIdentifier.getInstance(tagged, false); + if (!sig.equals(signature)) + { + v.add(next); + } + break; + case 1: + X500Name iss = X500Name.getInstance(tagged, true); // issuer + if (!iss.equals(issuer)) + { + v.add(next); + } + break; + case 2: + ASN1Sequence val = ASN1Sequence.getInstance(tagged, false); + if (!val.equals(validity)) + { + v.add(next); + } + break; + case 3: + X500Name sub = X500Name.getInstance(tagged, true); // subject + if (!sub.equals(subject)) + { + v.add(next); + } + break; + } + next = (ASN1Encodable)en.nextElement(); + } + + v.add(next); + + next = (ASN1Encodable)en.nextElement(); + while (next instanceof ASN1TaggedObject) + { + ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next); + switch (tagged.getTagNo()) + { + case 4: + Extensions deltaExts = Extensions.getInstance(tagged, false); + ExtensionsGenerator deltaExtGen = new ExtensionsGenerator(); + for (Enumeration extEn = deltaExts.oids(); extEn.hasMoreElements(); ) + { + Extension deltaExt = deltaExts.getExtension((ASN1ObjectIdentifier)extEn.nextElement()); + Extension primaryExt = tbsExtensions.getExtension(deltaExt.getExtnId()); + + if (primaryExt != null) + { + if (!deltaExt.equals(primaryExt)) + { + deltaExtGen.addExtension(deltaExt); + } + } + } + + DeltaCertificateDescriptor trimmedDeltaCertDesc; + if (!deltaExtGen.isEmpty()) + { + v.add(new DERTaggedObject(false, 4, deltaExtGen.generate())); + } + } + next = (ASN1Encodable)en.nextElement(); + } + + v.add(next); + + return new DeltaCertificateDescriptor(new DERSequence(v)); + } + + private void addOptional(ASN1EncodableVector v, int tag, boolean explicit, ASN1Object obj) + { + if (obj != null) + { + v.add(new DERTaggedObject(explicit, tag, obj)); + } + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(7); + + v.add(serialNumber); + addOptional(v, 0, false, signature); + addOptional(v, 1, true, issuer); // CHOICE + addOptional(v, 2, false, validity); + addOptional(v, 3, true, subject); // CHOICE + v.add(subjectPublicKeyInfo); + addOptional(v, 4, false, extensions); + v.add(signatureValue); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/DisplayText.java b/core/src/main/java/org/bouncycastle/asn1/x509/DisplayText.java index 7ebc3b379c..e23fb6e132 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/DisplayText.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/DisplayText.java @@ -169,7 +169,12 @@ public static DisplayText getInstance( ASN1TaggedObject obj, boolean explicit) { - return getInstance(obj.getObject()); // must be explicitly tagged + if (!explicit) + { + throw new IllegalArgumentException("choice item must be explicitly tagged"); + } + + return getInstance(obj.getExplicitBaseObject()); } public ASN1Primitive toASN1Primitive() diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java b/core/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java index c7feca5a8d..368b12af1d 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java @@ -1,11 +1,11 @@ package org.bouncycastle.asn1.x509; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.util.Strings; @@ -63,7 +63,7 @@ public DistributionPoint( distributionPoint = DistributionPointName.getInstance(t, true); break; case 1: - reasons = new ReasonFlags(DERBitString.getInstance(t, false)); + reasons = new ReasonFlags(ASN1BitString.getInstance(t, false)); break; case 2: cRLIssuer = GeneralNames.getInstance(t, false); diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/Extension.java b/core/src/main/java/org/bouncycastle/asn1/x509/Extension.java index b323ca7b4e..95cf846d20 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/Extension.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/Extension.java @@ -195,6 +195,11 @@ public class Extension */ public static final ASN1ObjectIdentifier altSignatureValue = new ASN1ObjectIdentifier("2.5.29.74").intern(); + /** + * delta certificate extension - prototype value will change! + */ + public static final ASN1ObjectIdentifier deltaCertificateDescriptor = new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.1"); + private ASN1ObjectIdentifier extnId; private boolean critical; private ASN1OctetString value; diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/Extensions.java b/core/src/main/java/org/bouncycastle/asn1/x509/Extensions.java index 0795a08d45..c552d370b7 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/Extensions.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/Extensions.java @@ -12,6 +12,7 @@ import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.util.Properties; /** *
    @@ -70,6 +71,9 @@ else if (obj != null)
         private Extensions(
             ASN1Sequence seq)
         {
    +        // it's tempting to check there's at least one entry in the sequence. Don't!
    +        // It turns out there's quite a few empty extension blocks out there...
    +
             Enumeration e = seq.getObjects();
     
             while (e.hasMoreElements())
    @@ -78,7 +82,10 @@ private Extensions(
     
                 if (extensions.containsKey(ext.getExtnId()))
                 {
    -                throw new IllegalArgumentException("repeated extension found: " + ext.getExtnId());
    +                if (!Properties.isOverrideSet("org.bouncycastle.x509.ignore_repeated_extensions"))
    +                {
    +                    throw new IllegalArgumentException("repeated extension found: " + ext.getExtnId());
    +                }
                 }
                 
                 extensions.put(ext.getExtnId(), ext);
    @@ -106,6 +113,11 @@ public Extensions(
         public Extensions(
             Extension[] extensions)
         {
    +        if (extensions == null || extensions.length == 0)
    +        {
    +            throw new IllegalArgumentException("extension array cannot be null or empty");
    +        }
    +
             for (int i = 0; i != extensions.length; i++)
             {
                 Extension ext = extensions[i];
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/GeneralName.java b/core/src/main/java/org/bouncycastle/asn1/x509/GeneralName.java
    index 82ee031392..20c19100e4 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/GeneralName.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/GeneralName.java
    @@ -228,6 +228,11 @@ public static GeneralName getInstance(
             ASN1TaggedObject tagObj,
             boolean          explicit)
         {
    +        if (!explicit)
    +        {
    +            throw new IllegalArgumentException("choice item must be explicitly tagged");
    +        }
    +
             return GeneralName.getInstance(ASN1TaggedObject.getInstance(tagObj, true));
         }
     
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java b/core/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java
    index 7b49a245c0..df3af14c37 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java
    @@ -9,7 +9,6 @@
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1Sequence;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.DERBitString;
     import org.bouncycastle.asn1.DERSequence;
     import org.bouncycastle.asn1.x500.X500Name;
     
    @@ -56,7 +55,7 @@ private IssuerSerial(
     
             if (seq.size() == 3)
             {
    -            issuerUID = DERBitString.getInstance(seq.getObjectAt(2));
    +            issuerUID = ASN1BitString.getInstance(seq.getObjectAt(2));
             }
         }
     
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java b/core/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
    index 501b0c6908..6f835419df 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
    @@ -130,7 +130,7 @@ private ObjectDigestInfo(
     
             digestAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1 + offset));
     
    -        objectDigest = DERBitString.getInstance(seq.getObjectAt(2 + offset));
    +        objectDigest = ASN1BitString.getInstance(seq.getObjectAt(2 + offset));
         }
     
         public ASN1Enumerated getDigestedObjectType()
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/OtherName.java b/core/src/main/java/org/bouncycastle/asn1/x509/OtherName.java
    index 93cbafc490..989d0d190d 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/OtherName.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/OtherName.java
    @@ -67,7 +67,7 @@ public OtherName(
         private OtherName(ASN1Sequence seq)
         {
             this.typeID = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
    -        this.value = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getObject(); // explicitly tagged
    +        this.value = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getExplicitBaseObject();
         }
     
         public ASN1ObjectIdentifier getTypeID()
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java b/core/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
    index 6c6b89cb21..9b4a54f0c1 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
    @@ -114,4 +114,9 @@ public ASN1Primitive toASN1Primitive()
     
           return new DERSequence(dev);
        }
    +
    +    public String toString()
    +    {
    +        return "PolicyQualifierInfo[" + policyQualifierId + ", " + qualifier + "]";
    +    }
     }
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java b/core/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
    index 598452134a..9c2241cb2b 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
    @@ -47,6 +47,14 @@ else if (obj != null)
             return null;
         }
     
    +    public SubjectPublicKeyInfo(
    +        AlgorithmIdentifier algId,
    +        ASN1BitString publicKey)
    +    {
    +        this.keyData = publicKey;
    +        this.algId = algId;
    +    }
    +
         public SubjectPublicKeyInfo(
             AlgorithmIdentifier algId,
             ASN1Encodable       publicKey)
    @@ -76,10 +84,10 @@ public SubjectPublicKeyInfo(
                         + seq.size());
             }
     
    -        Enumeration         e = seq.getObjects();
    +        Enumeration e = seq.getObjects();
     
             this.algId = AlgorithmIdentifier.getInstance(e.nextElement());
    -        this.keyData = DERBitString.getInstance(e.nextElement());
    +        this.keyData = ASN1BitString.getInstance(e.nextElement());
         }
     
         public AlgorithmIdentifier getAlgorithm()
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java b/core/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java
    index 0d2aab7f0c..76763291b6 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java
    @@ -7,7 +7,6 @@
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1Sequence;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.DERBitString;
     import org.bouncycastle.asn1.DERSequence;
     import org.bouncycastle.asn1.DERTaggedObject;
     import org.bouncycastle.asn1.x500.X500Name;
    @@ -140,10 +139,10 @@ else if (!version.hasValue(2))
                 switch (extra.getTagNo())
                 {
                 case 1:
    -                issuerUniqueId = DERBitString.getInstance(extra, false);
    +                issuerUniqueId = ASN1BitString.getInstance(extra, false);
                     break;
                 case 2:
    -                subjectUniqueId = DERBitString.getInstance(extra, false);
    +                subjectUniqueId = ASN1BitString.getInstance(extra, false);
                     break;
                 case 3:
                     if (isV2)
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/Time.java b/core/src/main/java/org/bouncycastle/asn1/x509/Time.java
    index d7c9363096..c81470c7d4 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/Time.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/Time.java
    @@ -26,7 +26,12 @@ public static Time getInstance(
             ASN1TaggedObject obj,
             boolean          explicit)
         {
    -        return getInstance(obj.getObject()); // must be explicitly tagged
    +        if (!explicit)
    +        {
    +            throw new IllegalArgumentException("choice item must be explicitly tagged");
    +        }
    +
    +        return getInstance(obj.getExplicitBaseObject());
         }
     
         public Time(
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/X509CertificateStructure.java b/core/src/main/java/org/bouncycastle/asn1/x509/X509CertificateStructure.java
    index 4089c05d66..7c25580b7f 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/X509CertificateStructure.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/X509CertificateStructure.java
    @@ -6,7 +6,6 @@
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1Sequence;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.DERBitString;
     import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
     import org.bouncycastle.asn1.x500.X500Name;
     
    @@ -65,7 +64,7 @@ public X509CertificateStructure(
                 tbsCert = TBSCertificateStructure.getInstance(seq.getObjectAt(0));
                 sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
     
    -            sig = DERBitString.getInstance(seq.getObjectAt(2));
    +            sig = ASN1BitString.getInstance(seq.getObjectAt(2));
             }
             else
             {
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java b/core/src/main/java/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
    index 0ae0f802bf..c888754fe5 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
    @@ -8,6 +8,7 @@
     import org.bouncycastle.asn1.DERIA5String;
     import org.bouncycastle.asn1.DERPrintableString;
     import org.bouncycastle.asn1.DERUTF8String;
    +import org.bouncycastle.asn1.x500.style.BCStyle;
     
     /**
      * The default converter for X509 DN entries when going from their
    @@ -45,16 +46,16 @@ public ASN1Primitive getConvertedValue(
                 {
                     value = value.substring(1);
                 }
    -            if (oid.equals(X509Name.EmailAddress) || oid.equals(X509Name.DC))
    +            if (oid.equals(BCStyle.EmailAddress) || oid.equals(BCStyle.DC))
                 {
                     return new DERIA5String(value);
                 }
    -            else if (oid.equals(X509Name.DATE_OF_BIRTH))  // accept time string as well as # (for compatibility)
    +            else if (oid.equals(BCStyle.DATE_OF_BIRTH))  // accept time string as well as # (for compatibility)
                 {
                     return new DERGeneralizedTime(value);
                 }
    -            else if (oid.equals(X509Name.C) || oid.equals(X509Name.SN) || oid.equals(X509Name.DN_QUALIFIER)
    -                || oid.equals(X509Name.TELEPHONE_NUMBER))
    +            else if (oid.equals(BCStyle.C) || oid.equals(BCStyle.SERIALNUMBER) || oid.equals(BCStyle.DN_QUALIFIER)
    +                || oid.equals(BCStyle.TELEPHONE_NUMBER))
                 {
                      return new DERPrintableString(value);
                 }
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java b/core/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java
    index b19dfdd8aa..b43ecd3103 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java
    @@ -12,6 +12,7 @@
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1Sequence;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERSequence;
     
     /**
    @@ -236,7 +237,9 @@ public static X509Extensions getInstance(
     
             if (obj instanceof ASN1TaggedObject)
             {
    -            return getInstance(((ASN1TaggedObject)obj).getObject());
    +            ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(obj, BERTags.CONTEXT_SPECIFIC);
    +
    +            return getInstance(taggedObject.getBaseObject().toASN1Primitive());
             }
     
             throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/X509Name.java b/core/src/main/java/org/bouncycastle/asn1/x509/X509Name.java
    index d9dadec113..cfa317790f 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x509/X509Name.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x509/X509Name.java
    @@ -660,27 +660,28 @@ public X509Name(
             this(reverse, lookUp, dirName, new X509DefaultEntryConverter());
         }
     
    -    private ASN1ObjectIdentifier decodeOID(
    -        String      name,
    -        Hashtable   lookUp)
    +    private ASN1ObjectIdentifier decodeOID(String name, Hashtable lookUp)
         {
             name = name.trim();
    -        if (Strings.toUpperCase(name).startsWith("OID."))
    +
    +        if (name.regionMatches(true, 0, "OID.", 0, 4))
             {
                 return new ASN1ObjectIdentifier(name.substring(4));
             }
    -        else if (name.charAt(0) >= '0' && name.charAt(0) <= '9')
    +
    +        ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.tryFromID(name);
    +        if (oid != null)
             {
    -            return new ASN1ObjectIdentifier(name);
    +            return oid;
             }
     
    -        ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)lookUp.get(Strings.toLowerCase(name));
    -        if (oid == null)
    +        oid = (ASN1ObjectIdentifier)lookUp.get(Strings.toLowerCase(name));
    +        if (oid != null)
             {
    -            throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name");
    +            return oid;
             }
     
    -        return oid;
    +        throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name");
         }
     
         private String unescape(String elt)
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java b/core/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java
    index 967e2d590b..053dc2c8f1 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java
    @@ -7,7 +7,6 @@
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1Sequence;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.DERBitString;
     import org.bouncycastle.asn1.DERSequence;
     
     /**
    @@ -59,7 +58,7 @@ private DHValidationParms(ASN1Sequence seq)
                 throw new IllegalArgumentException("Bad sequence size: " + seq.size());
             }
     
    -        this.seed = DERBitString.getInstance(seq.getObjectAt(0));
    +        this.seed = ASN1BitString.getInstance(seq.getObjectAt(0));
             this.pgenCounter = ASN1Integer.getInstance(seq.getObjectAt(1));
         }
     
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java b/core/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
    index dd2f7ca674..a74facfcc7 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
    @@ -5,13 +5,13 @@
     
     import org.bouncycastle.asn1.ASN1ObjectIdentifier;
     import org.bouncycastle.asn1.anssi.ANSSINamedCurves;
    -import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers;
     import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
     import org.bouncycastle.asn1.gm.GMNamedCurves;
     import org.bouncycastle.asn1.nist.NISTNamedCurves;
     import org.bouncycastle.asn1.sec.SECNamedCurves;
     import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
     import org.bouncycastle.crypto.ec.CustomNamedCurves;
    +import org.bouncycastle.internal.asn1.cryptlib.CryptlibObjectIdentifiers;
     
     /**
      * A general class that reads all X9.62 style EC curve tables.
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x9/OtherInfo.java b/core/src/main/java/org/bouncycastle/asn1/x9/OtherInfo.java
    index b201ea58b9..0ec5c6faf1 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x9/OtherInfo.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x9/OtherInfo.java
    @@ -70,13 +70,13 @@ private OtherInfo(
             {
                 ASN1TaggedObject o = (ASN1TaggedObject)e.nextElement();
     
    -            if (o.getTagNo() == 0)
    +            if (o.hasContextTag(0))
                 {
    -                partyAInfo = (ASN1OctetString)o.getObject();
    +                partyAInfo = (ASN1OctetString)o.getExplicitBaseObject();
                 }
    -            else if (o.getTagNo() == 2)
    +            else if (o.hasContextTag(2))
                 {
    -                suppPubInfo = (ASN1OctetString)o.getObject();
    +                suppPubInfo = (ASN1OctetString)o.getExplicitBaseObject();
                 }
             }
         }
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java b/core/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java
    index eb067e63cb..b7b29be11e 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java
    @@ -48,7 +48,12 @@ public static X962Parameters getInstance(
             ASN1TaggedObject obj,
             boolean          explicit)
         {
    -        return getInstance(obj.getObject()); // must be explicitly tagged
    +        if (!explicit)
    +        {
    +            throw new IllegalArgumentException("choice item must be explicitly tagged");
    +        }
    +
    +        return getInstance(obj.getExplicitBaseObject());
         }
         
         public X962Parameters(
    diff --git a/core/src/main/java/org/bouncycastle/asn1/x9/X9IntegerConverter.java b/core/src/main/java/org/bouncycastle/asn1/x9/X9IntegerConverter.java
    index 2851bcae18..73984875c7 100644
    --- a/core/src/main/java/org/bouncycastle/asn1/x9/X9IntegerConverter.java
    +++ b/core/src/main/java/org/bouncycastle/asn1/x9/X9IntegerConverter.java
    @@ -17,10 +17,9 @@ public class X9IntegerConverter
          * @param c the curve of interest.
          * @return the field size in bytes (rounded up).
          */
    -    public int getByteLength(
    -        ECCurve c)
    +    public int getByteLength(ECCurve c)
         {
    -        return (c.getFieldSize() + 7) / 8;
    +        return c.getFieldElementEncodingLength();
         }
     
         /**
    @@ -29,10 +28,9 @@ public int getByteLength(
          * @param fe the field element of interest.
          * @return the field size in bytes (rounded up).
          */
    -    public int getByteLength(
    -        ECFieldElement fe)
    +    public int getByteLength(ECFieldElement fe)
         {
    -        return (fe.getFieldSize() + 7) / 8;
    +        return fe.getEncodedLength();
         }
     
         /**
    diff --git a/core/src/main/java/org/bouncycastle/crypto/BlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/BlockCipher.java
    index 3cfa25a09c..370225f65a 100644
    --- a/core/src/main/java/org/bouncycastle/crypto/BlockCipher.java
    +++ b/core/src/main/java/org/bouncycastle/crypto/BlockCipher.java
    @@ -36,16 +36,16 @@ public void init(boolean forEncryption, CipherParameters params)
          * Process one block of input from the array in and write it to
          * the out array.
          *
    -     * @param in the array containing the input data.
    +     * @param input the array containing the input data.
          * @param inOff offset into the in array the data starts at.
    -     * @param out the array the output data will be copied into.
    +     * @param output the array the output data will be copied into.
          * @param outOff the offset into the out array the output will start at.
    -     * @exception DataLengthException if there isn't enough data in in, or
    +     * @exception DataLengthException if there isn't enough data in input , or
          * space in out.
          * @exception IllegalStateException if the cipher isn't initialised.
          * @return the number of bytes processed and produced.
          */
    -    public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
    +    public int processBlock(byte[] input, int inOff, byte[] output, int outOff)
             throws DataLengthException, IllegalStateException;
     
         /**
    diff --git a/core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java
    index 906793d8aa..6a2974147c 100644
    --- a/core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java
    +++ b/core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java
    @@ -24,7 +24,7 @@ public class BufferedBlockCipher
         /**
          * constructor for subclasses
          */
    -    protected BufferedBlockCipher()
    +    BufferedBlockCipher()
         {
         }
     
    @@ -32,6 +32,7 @@ protected BufferedBlockCipher()
          * Create a buffered block cipher without padding.
          *
          * @param cipher the underlying block cipher this buffering object wraps.
    +     * @deprecated use the constructor on DefaultBufferedBlockCipher.
          */
         public BufferedBlockCipher(
             BlockCipher     cipher)
    diff --git a/core/src/main/java/org/bouncycastle/crypto/CryptoServicesRegistrar.java b/core/src/main/java/org/bouncycastle/crypto/CryptoServicesRegistrar.java
    index 486f14c8cf..90d3c85348 100644
    --- a/core/src/main/java/org/bouncycastle/crypto/CryptoServicesRegistrar.java
    +++ b/core/src/main/java/org/bouncycastle/crypto/CryptoServicesRegistrar.java
    @@ -17,6 +17,7 @@
     import org.bouncycastle.crypto.params.DSAParameters;
     import org.bouncycastle.crypto.params.DSAValidationParameters;
     import org.bouncycastle.util.Properties;
    +import org.bouncycastle.util.Strings;
     import org.bouncycastle.util.encoders.Hex;
     
     /**
    @@ -33,19 +34,13 @@ public final class CryptoServicesRegistrar
     
         private static final ThreadLocal> threadProperties = new ThreadLocal>();
         private static final Map globalProperties = Collections.synchronizedMap(new HashMap());
    -    private static final SecureRandomProvider defaultRandomProviderImpl = new SecureRandomProvider()
    -    {
    -        public SecureRandom get()
    -        {
    -            return new SecureRandom();
    -        }
    -    };
    +    private static final SecureRandomProvider defaultRandomProviderImpl = new ThreadLocalSecureRandomProvider();
     
         private static final CryptoServicesConstraints noConstraintsImpl = new CryptoServicesConstraints()
         {
             public void check(CryptoServiceProperties service)
             {
    -             // anything goes.
    +            // anything goes.
             }
         };
     
    @@ -527,4 +522,20 @@ private Property(String name, Class type)
                 this.type = type;
             }
         }
    +
    +    private static class ThreadLocalSecureRandomProvider
    +        implements SecureRandomProvider
    +    {
    +        final ThreadLocal defaultRandoms = new ThreadLocal();
    +
    +        public SecureRandom get()
    +        {
    +            if (defaultRandoms.get() == null)
    +            {
    +                defaultRandoms.set(new SecureRandom());
    +            }
    +
    +            return defaultRandoms.get();
    +        }
    +    }
     }
    diff --git a/core/src/main/java/org/bouncycastle/crypto/DefaultBufferedBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/DefaultBufferedBlockCipher.java
    new file mode 100644
    index 0000000000..662a23a011
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/crypto/DefaultBufferedBlockCipher.java
    @@ -0,0 +1,356 @@
    +package org.bouncycastle.crypto;
    +
    +
    +/**
    + * A wrapper class that allows block ciphers to be used to process data in
    + * a piecemeal fashion. The BufferedBlockCipher outputs a block only when the
    + * buffer is full and more data is being added, or on a doFinal.
    + * 

    + * Note: in the case where the underlying cipher is either a CFB cipher or an + * OFB one the last block may not be a multiple of the block size. Use this class + * for construction rather than BufferedBlockCipher as BufferedBlockCipher will eventually + * turn into an interface. + */ +public class DefaultBufferedBlockCipher + extends BufferedBlockCipher +{ + protected byte[] buf; + protected int bufOff; + + protected boolean forEncryption; + protected BlockCipher cipher; + protected MultiBlockCipher mbCipher; + + protected boolean partialBlockOkay; + protected boolean pgpCFB; + + /** + * constructor for subclasses + */ + protected DefaultBufferedBlockCipher() + { + } + + /** + * Create a buffered block cipher without padding. + * + * @param cipher the underlying block cipher this buffering object wraps. + */ + public DefaultBufferedBlockCipher( + BlockCipher cipher) + { + this.cipher = cipher; + + if (cipher instanceof MultiBlockCipher) + { + this.mbCipher = (MultiBlockCipher)cipher; + buf = new byte[mbCipher.getMultiBlockSize()]; + } + else + { + this.mbCipher = null; + buf = new byte[cipher.getBlockSize()]; + } + + bufOff = 0; + + // + // check if we can handle partial blocks on doFinal. + // + String name = cipher.getAlgorithmName(); + int idx = name.indexOf('/') + 1; + + pgpCFB = (idx > 0 && name.startsWith("PGP", idx)); + + if (pgpCFB || cipher instanceof StreamCipher) + { + partialBlockOkay = true; + } + else + { + partialBlockOkay = (idx > 0 && (name.startsWith("OpenPGP", idx))); + } + } + + /** + * return the cipher this object wraps. + * + * @return the cipher this object wraps. + */ + public BlockCipher getUnderlyingCipher() + { + return cipher; + } + + /** + * initialise the cipher. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param params the key and other data required by the cipher. + * @exception IllegalArgumentException if the params argument is + * inappropriate. + */ + public void init( + boolean forEncryption, + CipherParameters params) + throws IllegalArgumentException + { + this.forEncryption = forEncryption; + + reset(); + + cipher.init(forEncryption, params); + } + + /** + * return the blocksize for the underlying cipher. + * + * @return the blocksize for the underlying cipher. + */ + public int getBlockSize() + { + return cipher.getBlockSize(); + } + + /** + * return the size of the output buffer required for an update + * an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update + * with len bytes of input. + */ + public int getUpdateOutputSize( + int len) + { + int total = len + bufOff; + int leftOver; + + if (pgpCFB) + { + if (forEncryption) + { + leftOver = total % buf.length - (cipher.getBlockSize() + 2); + } + else + { + leftOver = total % buf.length; + } + } + else + { + leftOver = total % buf.length; + } + + return total - leftOver; + } + + /** + * return the size of the output buffer required for an update plus a + * doFinal with an input of 'length' bytes. + * + * @param length the length of the input. + * @return the space required to accommodate a call to update and doFinal + * with 'length' bytes of input. + */ + public int getOutputSize( + int length) + { + if (pgpCFB && forEncryption) + { + return length + bufOff + (cipher.getBlockSize() + 2); + } + + // Note: Can assume partialBlockOkay is true for purposes of this calculation + return length + bufOff; + } + + /** + * process a single byte, producing an output block if necessary. + * + * @param in the input byte. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception IllegalStateException if the cipher isn't initialised. + */ + public int processByte( + byte in, + byte[] out, + int outOff) + throws DataLengthException, IllegalStateException + { + int resultLen = 0; + + buf[bufOff++] = in; + + if (bufOff == buf.length) + { + resultLen = cipher.processBlock(buf, 0, out, outOff); + bufOff = 0; + } + + return resultLen; + } + + /** + * process an array of bytes, producing output if necessary. + * + * @param in the input byte array. + * @param inOff the offset at which the input data starts. + * @param len the number of bytes to be copied out of the input array. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception IllegalStateException if the cipher isn't initialised. + */ + public int processBytes( + byte[] in, + int inOff, + int len, + byte[] out, + int outOff) + throws DataLengthException, IllegalStateException + { + if (len < 0) + { + throw new IllegalArgumentException("Can't have a negative input length!"); + } + + int blockSize = getBlockSize(); + int length = getUpdateOutputSize(len); + + if (length > 0) + { + if ((outOff + length) > out.length) + { + throw new OutputLengthException("output buffer too short"); + } + } + + int resultLen = 0; + int gapLen = buf.length - bufOff; + + if (len > gapLen) + { + System.arraycopy(in, inOff, buf, bufOff, gapLen); + + resultLen += cipher.processBlock(buf, 0, out, outOff); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + if (mbCipher != null) + { + int blockCount = len / mbCipher.getMultiBlockSize(); + + if (blockCount > 0) + { + resultLen += mbCipher.processBlocks(in, inOff, blockCount, out, outOff + resultLen); + + int processed = blockCount * mbCipher.getMultiBlockSize(); + + len -= processed; + inOff += processed; + } + } + else + { + while (len > buf.length) + { + resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen); + + len -= blockSize; + inOff += blockSize; + } + } + } + + System.arraycopy(in, inOff, buf, bufOff, len); + + bufOff += len; + + if (bufOff == buf.length) + { + resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen); + bufOff = 0; + } + + return resultLen; + } + + /** + * Process the last block in the buffer. + * + * @param out the array the block currently being held is copied into. + * @param outOff the offset at which the copying starts. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there is insufficient space in out for + * the output, or the input is not block size aligned and should be. + * @exception IllegalStateException if the underlying cipher is not + * initialised. + * @exception InvalidCipherTextException if padding is expected and not found. + * @exception DataLengthException if the input is not block size + * aligned. + */ + public int doFinal( + byte[] out, + int outOff) + throws DataLengthException, IllegalStateException, InvalidCipherTextException + { + try + { + int resultLen = 0; + + if (outOff + bufOff > out.length) + { + throw new OutputLengthException("output buffer too short for doFinal()"); + } + + if (bufOff != 0) + { + if (!partialBlockOkay) + { + throw new DataLengthException("data not block size aligned"); + } + + cipher.processBlock(buf, 0, buf, 0); + resultLen = bufOff; + bufOff = 0; + System.arraycopy(buf, 0, out, outOff, resultLen); + } + + return resultLen; + } + finally + { + reset(); + } + } + + /** + * Reset the buffer and cipher. After resetting the object is in the same + * state as it was after the last init (if there was one). + */ + public void reset() + { + // + // clean the buffer. + // + for (int i = 0; i < buf.length; i++) + { + buf[i] = 0; + } + + bufOff = 0; + + // + // reset the underlying cipher. + // + cipher.reset(); + } +} diff --git a/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java b/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java index e3446385ae..acec9306c0 100644 --- a/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java +++ b/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java @@ -41,7 +41,7 @@ public void init( public int getFieldSize() { - return (key.getParameters().getCurve().getFieldSize() + 7) / 8; + return key.getParameters().getCurve().getFieldElementEncodingLength(); } public BigInteger calculateAgreement( diff --git a/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHCBasicAgreement.java b/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHCBasicAgreement.java index aa67a7a09a..0c48e5360d 100644 --- a/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHCBasicAgreement.java +++ b/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHCBasicAgreement.java @@ -45,7 +45,7 @@ public void init( public int getFieldSize() { - return (key.getParameters().getCurve().getFieldSize() + 7) / 8; + return key.getParameters().getCurve().getFieldElementEncodingLength(); } public BigInteger calculateAgreement( diff --git a/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHCStagedAgreement.java b/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHCStagedAgreement.java index 222f4f3836..363b7ccec4 100644 --- a/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHCStagedAgreement.java +++ b/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHCStagedAgreement.java @@ -27,7 +27,7 @@ public void init( public int getFieldSize() { - return (key.getParameters().getCurve().getFieldSize() + 7) / 8; + return key.getParameters().getCurve().getFieldElementEncodingLength(); } public AsymmetricKeyParameter calculateStage( diff --git a/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHCUnifiedAgreement.java b/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHCUnifiedAgreement.java index b2df97811e..ccefa18b3a 100644 --- a/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHCUnifiedAgreement.java +++ b/core/src/main/java/org/bouncycastle/crypto/agreement/ECDHCUnifiedAgreement.java @@ -25,7 +25,7 @@ public void init( public int getFieldSize() { - return (privParams.getStaticPrivateKey().getParameters().getCurve().getFieldSize() + 7) / 8; + return privParams.getStaticPrivateKey().getParameters().getCurve().getFieldElementEncodingLength(); } public byte[] calculateAgreement(CipherParameters pubKey) diff --git a/core/src/main/java/org/bouncycastle/crypto/agreement/ECMQVBasicAgreement.java b/core/src/main/java/org/bouncycastle/crypto/agreement/ECMQVBasicAgreement.java index 9038b83f80..34beb8d530 100644 --- a/core/src/main/java/org/bouncycastle/crypto/agreement/ECMQVBasicAgreement.java +++ b/core/src/main/java/org/bouncycastle/crypto/agreement/ECMQVBasicAgreement.java @@ -31,7 +31,7 @@ public void init( public int getFieldSize() { - return (privParams.getStaticPrivateKey().getParameters().getCurve().getFieldSize() + 7) / 8; + return privParams.getStaticPrivateKey().getParameters().getCurve().getFieldElementEncodingLength(); } public BigInteger calculateAgreement(CipherParameters pubKey) diff --git a/core/src/main/java/org/bouncycastle/crypto/agreement/ECVKOAgreement.java b/core/src/main/java/org/bouncycastle/crypto/agreement/ECVKOAgreement.java index eb49a87083..5e64eb7260 100644 --- a/core/src/main/java/org/bouncycastle/crypto/agreement/ECVKOAgreement.java +++ b/core/src/main/java/org/bouncycastle/crypto/agreement/ECVKOAgreement.java @@ -48,7 +48,7 @@ public int getAgreementSize() */ public int getFieldSize() { - return (key.getParameters().getCurve().getFieldSize() + 7) / 8; + return key.getParameters().getCurve().getFieldElementEncodingLength(); } public byte[] calculateAgreement(CipherParameters pubKey) diff --git a/core/src/main/java/org/bouncycastle/crypto/agreement/jpake/JPAKEParticipant.java b/core/src/main/java/org/bouncycastle/crypto/agreement/jpake/JPAKEParticipant.java index cd223bb8cf..25547968e2 100644 --- a/core/src/main/java/org/bouncycastle/crypto/agreement/jpake/JPAKEParticipant.java +++ b/core/src/main/java/org/bouncycastle/crypto/agreement/jpake/JPAKEParticipant.java @@ -194,7 +194,7 @@ public JPAKEParticipant( participantId, password, group, - new SHA256Digest(), + SHA256Digest.newInstance(), CryptoServicesRegistrar.getSecureRandom()); } diff --git a/core/src/main/java/org/bouncycastle/crypto/digests/AsconDigest.java b/core/src/main/java/org/bouncycastle/crypto/digests/AsconDigest.java index 855a592aa3..fd4792745b 100644 --- a/core/src/main/java/org/bouncycastle/crypto/digests/AsconDigest.java +++ b/core/src/main/java/org/bouncycastle/crypto/digests/AsconDigest.java @@ -3,7 +3,7 @@ import java.io.ByteArrayOutputStream; import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.OutputLengthException; /* ASCON v1.2 Digest, https://ascon.iaik.tugraz.at/ . @@ -13,7 +13,7 @@ * ASCON v1.2 Digest with reference to C Reference Impl from: https://github.com/ascon/ascon-c . */ public class AsconDigest - implements Digest + implements ExtendedDigest { public enum AsconParameters { @@ -128,6 +128,12 @@ public int getDigestSize() return CRYPTO_BYTES; } + @Override + public int getByteLength() + { + return 8; + } + @Override public void update(byte in) { diff --git a/core/src/main/java/org/bouncycastle/crypto/digests/CSHAKEDigest.java b/core/src/main/java/org/bouncycastle/crypto/digests/CSHAKEDigest.java index cffe559fcb..387bc8f732 100644 --- a/core/src/main/java/org/bouncycastle/crypto/digests/CSHAKEDigest.java +++ b/core/src/main/java/org/bouncycastle/crypto/digests/CSHAKEDigest.java @@ -47,7 +47,7 @@ public CSHAKEDigest(int bitLength, CryptoServicePurpose purpose, byte[] N, byte[ } } - CSHAKEDigest(CSHAKEDigest source) + public CSHAKEDigest(CSHAKEDigest source) { super(source); diff --git a/core/src/main/java/org/bouncycastle/crypto/digests/GOST3411_2012Digest.java b/core/src/main/java/org/bouncycastle/crypto/digests/GOST3411_2012Digest.java index c7c923fc46..c4e111899f 100644 --- a/core/src/main/java/org/bouncycastle/crypto/digests/GOST3411_2012Digest.java +++ b/core/src/main/java/org/bouncycastle/crypto/digests/GOST3411_2012Digest.java @@ -4,6 +4,7 @@ import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Bytes; import org.bouncycastle.util.Memoable; /** @@ -333,12 +334,9 @@ private void F(byte[] V) V[56] = (byte)(r); } - private void xor512(byte[] A, byte[] B) + private static void xor512(byte[] A, byte[] B) { - for (int i = 0; i < 64; ++i) - { - A[i] ^= B[i]; - } + Bytes.xorTo(64, B, A); } private void E(byte[] K, byte[] m) diff --git a/core/src/main/java/org/bouncycastle/crypto/digests/Haraka256Digest.java b/core/src/main/java/org/bouncycastle/crypto/digests/Haraka256Digest.java index 8b2671b5ff..1e04a23475 100644 --- a/core/src/main/java/org/bouncycastle/crypto/digests/Haraka256Digest.java +++ b/core/src/main/java/org/bouncycastle/crypto/digests/Haraka256Digest.java @@ -3,6 +3,7 @@ import org.bouncycastle.crypto.CryptoServicePurpose; import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Bytes; /** * Haraka-256 v2, https://eprint.iacr.org/2016/098.pdf @@ -64,11 +65,8 @@ private int haraka256256(byte[] msg, byte[] out, int outOff) s1[1] = aesEnc(s1[1], RC[19]); mix256(s1, s2); - s1[0] = xor(s2[0], msg, 0); - s1[1] = xor(s2[1], msg, 16); - - System.arraycopy(s1[0], 0, out, outOff, 16); - System.arraycopy(s1[1], 0, out, outOff + 16, 16); + Bytes.xor(16, s2[0], 0, msg, 0, out, outOff); + Bytes.xor(16, s2[1], 0, msg, 16, out, outOff + 16); return DIGEST_SIZE; } diff --git a/core/src/main/java/org/bouncycastle/crypto/digests/Haraka512Digest.java b/core/src/main/java/org/bouncycastle/crypto/digests/Haraka512Digest.java index 9a804ccd17..d9e9ba6afe 100644 --- a/core/src/main/java/org/bouncycastle/crypto/digests/Haraka512Digest.java +++ b/core/src/main/java/org/bouncycastle/crypto/digests/Haraka512Digest.java @@ -2,6 +2,7 @@ import org.bouncycastle.crypto.CryptoServicePurpose; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Bytes; /** * Haraka-512 v2, https://eprint.iacr.org/2016/098.pdf @@ -122,10 +123,10 @@ private int haraka512256(byte[] msg, byte[] out, int outOff) s1[3] = aesEnc(s1[3], RC[39]); mix512(s1, s2); - s1[0] = xor(s2[0], msg, 0); - s1[1] = xor(s2[1], msg, 16); - s1[2] = xor(s2[2], msg, 32); - s1[3] = xor(s2[3], msg, 48); + Bytes.xor(16, s2[0], 0, msg, 0, s1[0], 0); + Bytes.xor(16, s2[1], 0, msg, 16, s1[1], 0); + Bytes.xor(16, s2[2], 0, msg, 32, s1[2], 0); + Bytes.xor(16, s2[3], 0, msg, 48, s1[3], 0); System.arraycopy(s1[0], 8, out, outOff, 8); System.arraycopy(s1[1], 8, out, outOff + 8, 8); diff --git a/core/src/main/java/org/bouncycastle/crypto/digests/HarakaBase.java b/core/src/main/java/org/bouncycastle/crypto/digests/HarakaBase.java index 37d9a01298..db9f3f20f0 100644 --- a/core/src/main/java/org/bouncycastle/crypto/digests/HarakaBase.java +++ b/core/src/main/java/org/bouncycastle/crypto/digests/HarakaBase.java @@ -1,6 +1,7 @@ package org.bouncycastle.crypto.digests; import org.bouncycastle.crypto.Digest; +import org.bouncycastle.util.Bytes; /** * Base class for Haraka v2, https://eprint.iacr.org/2016/098.pdf @@ -116,7 +117,7 @@ static byte[] aesEnc(byte[] s, byte[] rk) s = subBytes(s); s = shiftRows(s); s = mixColumns(s); - xorWith(rk, s); + Bytes.xorTo(16, rk, s); return s; } @@ -125,24 +126,6 @@ static byte mulX(byte p) return (byte)(((p & 0x7F) << 1) ^ (((p & 0x80) >> 7) * 0x1B)); } - static byte[] xor(byte[] x, byte[] y, int yStart) - { - byte[] out = new byte[16]; - for (int i = 0; i < out.length; i++) - { - out[i] = (byte)(x[i] ^ y[yStart++]); - } - return out; - } - - static void xorWith(byte[] x, byte[] z) - { - for (int i = 0; i < 16; ++i) - { - z[i] ^= x[i]; - } - } - private static byte[] mixColumns(byte[] s) { byte[] out = new byte[s.length]; diff --git a/core/src/main/java/org/bouncycastle/crypto/digests/ParallelHash.java b/core/src/main/java/org/bouncycastle/crypto/digests/ParallelHash.java index d7e336c5c8..5ac7f120d0 100644 --- a/core/src/main/java/org/bouncycastle/crypto/digests/ParallelHash.java +++ b/core/src/main/java/org/bouncycastle/crypto/digests/ParallelHash.java @@ -1,6 +1,10 @@ package org.bouncycastle.crypto.digests; -import org.bouncycastle.crypto.*; +import org.bouncycastle.crypto.CryptoServicePurpose; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.Xof; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; @@ -73,8 +77,11 @@ public ParallelHash(ParallelHash source) this.compressorBuffer = Arrays.clone(source.compressorBuffer); this.purpose = source.purpose; - CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties(this, bitLength, purpose)); + this.firstOutput = source.firstOutput; + this.nCount = source.nCount; + this.bufOff = source.bufOff; + CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties(this, bitLength, purpose)); } public String getAlgorithmName() diff --git a/core/src/main/java/org/bouncycastle/crypto/digests/PhotonBeetleDigest.java b/core/src/main/java/org/bouncycastle/crypto/digests/PhotonBeetleDigest.java index df69619f2a..9e54329faf 100644 --- a/core/src/main/java/org/bouncycastle/crypto/digests/PhotonBeetleDigest.java +++ b/core/src/main/java/org/bouncycastle/crypto/digests/PhotonBeetleDigest.java @@ -6,6 +6,7 @@ import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Bytes; /** * Photon-Beetle, https://www.isical.ac.in/~lightweight/beetle/ @@ -121,11 +122,11 @@ else if (inlen <= INITIAL_RATE_INBYTES) for (i = 0; i < Dlen_inblocks - 1; i++) { PHOTON_Permutation(); - XOR(input, INITIAL_RATE_INBYTES + i * RATE_INBYTES, RATE_INBYTES); + Bytes.xorTo(RATE_INBYTES, input, INITIAL_RATE_INBYTES + i * RATE_INBYTES, state, 0); } PHOTON_Permutation(); LastDBlocklen = inlen - i * RATE_INBYTES; - XOR(input, INITIAL_RATE_INBYTES + i * RATE_INBYTES, LastDBlocklen); + Bytes.xorTo(LastDBlocklen, input, INITIAL_RATE_INBYTES + i * RATE_INBYTES, state, 0); if (LastDBlocklen < RATE_INBYTES) { state[LastDBlocklen] ^= 0x01; // ozs @@ -139,14 +140,6 @@ else if (inlen <= INITIAL_RATE_INBYTES) return TAG_INBYTES; } - void XOR(byte[] in_right, int rOff, int iolen_inbytes) - { - for (int i = 0; i < iolen_inbytes; i++) - { - state[i] ^= in_right[i + rOff]; - } - } - @Override public void reset() { @@ -156,7 +149,7 @@ public void reset() void PHOTON_Permutation() { - int i, j, k, l; + int i, j, k; for (i = 0; i < DSquare; i++) { state_2d[i >>> Dq][i & Dr] = (byte)(((state[i >> 1] & 0xFF) >>> (4 * (i & 1))) & 0xf); @@ -188,29 +181,25 @@ void PHOTON_Permutation() { for (i = 0; i < D; i++) { - byte sum = 0; + int sum = 0; + for (k = 0; k < D; k++) { - int x = MixColMatrix[i][k], ret = 0, b = state_2d[k][j]; - for (l = 0; l < S; l++) - { - if (((b >>> l) & 1) != 0) - { - ret ^= x; - } - if (((x >>> S_1) & 1) != 0) - { - x <<= 1; - x ^= 0x3; - } - else - { - x <<= 1; - } - } - sum ^= ret & 15; + int x = MixColMatrix[i][k], b = state_2d[k][j]; + + sum ^= x * (b & 1); + sum ^= x * (b & 2); + sum ^= x * (b & 4); + sum ^= x * (b & 8); } - state[i] = sum; + + int t0 = sum >>> 4; + sum = (sum & 15) ^ t0 ^ (t0 << 1); + + int t1 = sum >>> 4; + sum = (sum & 15) ^ t1 ^ (t1 << 1); + + state[i] = (byte)sum; } for (i = 0; i < D; i++) { diff --git a/core/src/main/java/org/bouncycastle/crypto/digests/Prehash.java b/core/src/main/java/org/bouncycastle/crypto/digests/Prehash.java new file mode 100644 index 0000000000..4fbd860dc2 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/digests/Prehash.java @@ -0,0 +1,64 @@ +package org.bouncycastle.crypto.digests; + +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.util.io.LimitedBuffer; + +public class Prehash + implements Digest +{ + public static Prehash forDigest(Digest digest) + { + return new Prehash(digest); + } + + private final String algorithmName; + private final LimitedBuffer buf; + + private Prehash(Digest digest) + { + algorithmName = digest.getAlgorithmName(); + buf = new LimitedBuffer(digest.getDigestSize()); + } + + public String getAlgorithmName() + { + return algorithmName; + } + + public int getDigestSize() + { + return buf.limit(); + } + + public void update(byte in) + { + buf.write(in); + } + + public void update(byte[] in, int inOff, int len) + { + buf.write(in, inOff, len); + } + + public int doFinal(byte[] out, int outOff) + { + try + { + if (getDigestSize() != buf.size()) + { + throw new IllegalStateException("Incorrect prehash size"); + } + + return buf.copyTo(out, outOff); + } + finally + { + reset(); + } + } + + public void reset() + { + buf.reset(); + } +} diff --git a/core/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java b/core/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java index 5accd4d4ba..8f3c240ef2 100644 --- a/core/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java +++ b/core/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java @@ -4,6 +4,7 @@ import org.bouncycastle.crypto.CryptoServiceProperties; import org.bouncycastle.crypto.CryptoServicePurpose; import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.SavableDigest; import org.bouncycastle.util.Memoable; import org.bouncycastle.util.Pack; @@ -31,6 +32,31 @@ public class SHA256Digest private int[] X = new int[64]; private int xOff; + public static SavableDigest newInstance() + { + return new SHA256Digest(); + } + + public static SavableDigest newInstance(CryptoServicePurpose purpose) + { + return new SHA256Digest(purpose); + } + + public static SavableDigest newInstance(Digest digest) + { + if (digest instanceof SHA256Digest) + { + return new SHA256Digest((SHA256Digest) digest); + } + + throw new IllegalArgumentException("receiver digest not available for input type " + (digest != null ? digest.getClass().getName() : "null")); + } + + public static SavableDigest newInstance(byte[] encoded) + { + return new SHA256Digest(encoded); + } + /** * Standard constructor */ diff --git a/core/src/main/java/org/bouncycastle/crypto/digests/SparkleDigest.java b/core/src/main/java/org/bouncycastle/crypto/digests/SparkleDigest.java index a04b743f90..90c17f62ea 100644 --- a/core/src/main/java/org/bouncycastle/crypto/digests/SparkleDigest.java +++ b/core/src/main/java/org/bouncycastle/crypto/digests/SparkleDigest.java @@ -1,11 +1,11 @@ package org.bouncycastle.crypto.digests; -import java.io.ByteArrayOutputStream; - import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.OutputLengthException; +import org.bouncycastle.crypto.engines.SparkleEngine; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Integers; import org.bouncycastle.util.Pack; /** @@ -14,117 +14,56 @@ * Specification: https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/sparkle-spec-final.pdf */ public class SparkleDigest - implements Digest + implements ExtendedDigest { + public static class Friend + { + private static final Friend INSTANCE = new Friend(); + private Friend() {} + } + public enum SparkleParameters { ESCH256, ESCH384 } + private static final int RATE_BYTES = 16; + private static final int RATE_WORDS = 4; + private String algorithmName; private final int[] state; - private final ByteArrayOutputStream message = new ByteArrayOutputStream(); + private final byte[] m_buf = new byte[RATE_BYTES]; private final int DIGEST_BYTES; private final int SPARKLE_STEPS_SLIM; private final int SPARKLE_STEPS_BIG; - private final int STATE_BRANS; private final int STATE_WORDS; - private final int RATE_WORDS; - private final int RATE_BYTES; + + private int m_bufPos = 0; public SparkleDigest(SparkleParameters sparkleParameters) { - int ESCH_DIGEST_LEN; - int SPARKLE_STATE; - int SPARKLE_RATE = 128; switch (sparkleParameters) { case ESCH256: - ESCH_DIGEST_LEN = 256; - SPARKLE_STATE = 384; + algorithmName = "ESCH-256"; + DIGEST_BYTES = 32; SPARKLE_STEPS_SLIM = 7; SPARKLE_STEPS_BIG = 11; - algorithmName = "ESCH-256"; + STATE_WORDS = 12; break; case ESCH384: - ESCH_DIGEST_LEN = 384; - SPARKLE_STATE = 512; + algorithmName = "ESCH-384"; + DIGEST_BYTES = 48; SPARKLE_STEPS_SLIM = 8; SPARKLE_STEPS_BIG = 12; - algorithmName = "ESCH-384"; + STATE_WORDS = 16; break; default: throw new IllegalArgumentException("Invalid definition of SCHWAEMM instance"); } - STATE_BRANS = SPARKLE_STATE >>> 6; - STATE_WORDS = SPARKLE_STATE >>> 5; - RATE_WORDS = SPARKLE_RATE >>> 5; - RATE_BYTES = SPARKLE_RATE >>> 3; - DIGEST_BYTES = ESCH_DIGEST_LEN >>> 3; - state = new int[STATE_WORDS]; - } - - private int ROT(int x, int n) - { - return (((x) >>> n) | ((x) << (32 - n))); - } - - private int ELL(int x) - { - return ROT(((x) ^ ((x) << 16)), 16); - } - - private static final int[] RCON = {0xB7E15162, 0xBF715880, 0x38B4DA56, 0x324E7738, 0xBB1185EB, 0x4F7C7B57, - 0xCFBFA1C8, 0xC2B3293D}; - private void sparkle_opt(int[] state, int brans, int steps) - { - int i, j, rc, tmpx, tmpy, x0, y0; - for (i = 0; i < steps; i++) - { - // Add round ant - state[1] ^= RCON[i & 7]; - state[3] ^= i; - // ARXBOX layer - for (j = 0; j < 2 * brans; j += 2) - { - rc = RCON[j >>> 1]; - state[j] += ROT(state[j + 1], 31); - state[j + 1] ^= ROT(state[j], 24); - state[j] ^= rc; - state[j] += ROT(state[j + 1], 17); - state[j + 1] ^= ROT(state[j], 17); - state[j] ^= rc; - state[j] += state[j + 1]; - state[j + 1] ^= ROT(state[j], 31); - state[j] ^= rc; - state[j] += ROT(state[j + 1], 24); - state[j + 1] ^= ROT(state[j], 16); - state[j] ^= rc; - } - // Linear layer - tmpx = x0 = state[0]; - tmpy = y0 = state[1]; - for (j = 2; j < brans; j += 2) - { - tmpx ^= state[j]; - tmpy ^= state[j + 1]; - } - tmpx = ELL(tmpx); - tmpy = ELL(tmpy); - for (j = 2; j < brans; j += 2) - { - state[j - 2] = state[j + brans] ^ state[j] ^ tmpy; - state[j + brans] = state[j]; - state[j - 1] = state[j + brans + 1] ^ state[j + 1] ^ tmpx; - state[j + brans + 1] = state[j + 1]; - } - state[brans - 2] = state[brans] ^ x0 ^ tmpy; - state[brans] = x0; - state[brans - 1] = state[brans + 1] ^ y0 ^ tmpx; - state[brans + 1] = y0; - } + state = new int[STATE_WORDS]; } @Override @@ -139,111 +78,146 @@ public int getDigestSize() return DIGEST_BYTES; } + @Override + public int getByteLength() + { + return RATE_BYTES; + } + @Override public void update(byte input) { - message.write(input); + if (m_bufPos == RATE_BYTES) + { + processBlock(m_buf, 0, SPARKLE_STEPS_SLIM); + m_bufPos = 0; + } + + m_buf[m_bufPos++] = input; } @Override - public void update(byte[] input, int inOff, int len) + public void update(byte[] in, int inOff, int len) { - if (inOff + len > input.length) + if (inOff > in.length - len) { throw new DataLengthException(algorithmName + " input buffer too short"); } - message.write(input, inOff, len); + + if (len < 1) + return; + + int available = RATE_BYTES - m_bufPos; + if (len <= available) + { + System.arraycopy(in, inOff, m_buf, m_bufPos, len); + m_bufPos += len; + return; + } + + int inPos = 0; + if (m_bufPos > 0) + { + System.arraycopy(in, inOff, m_buf, m_bufPos, available); + processBlock(m_buf, 0, SPARKLE_STEPS_SLIM); + inPos += available; + } + + int remaining; + while ((remaining = len - inPos) > RATE_BYTES) + { + processBlock(in, inOff + inPos, SPARKLE_STEPS_SLIM); + inPos += RATE_BYTES; + } + + System.arraycopy(in, inOff + inPos, m_buf, 0, remaining); + m_bufPos = remaining; } @Override public int doFinal(byte[] output, int outOff) { - if (outOff + DIGEST_BYTES > output.length) + if (outOff > output.length - DIGEST_BYTES) { throw new OutputLengthException(algorithmName + " input buffer too short"); } - byte[] input = message.toByteArray(); - int inlen = input.length, i, tmpx, tmpy, inOff = 0; - // Main Hashing Loop - int[] in32 = Pack.littleEndianToInt(input, 0, inlen >> 2); - while (inlen > RATE_BYTES) + + // addition of constant M1 or M2 to the state + if (m_bufPos < RATE_BYTES) { - // addition of a message block to the state - tmpx = 0; - tmpy = 0; - for (i = 0; i < RATE_WORDS; i += 2) - { - tmpx ^= in32[i + (inOff >> 2)]; - tmpy ^= in32[i + 1 + (inOff >> 2)]; - } - tmpx = ELL(tmpx); - tmpy = ELL(tmpy); - for (i = 0; i < RATE_WORDS; i += 2) - { - state[i] ^= (in32[i + (inOff >> 2)] ^ tmpy); - state[i + 1] ^= (in32[i + 1 + (inOff >> 2)] ^ tmpx); - } - for (i = RATE_WORDS; i < (STATE_WORDS / 2); i += 2) + state[(STATE_WORDS >> 1) - 1] ^= 1 << 24; + + // padding + m_buf[m_bufPos] = (byte)0x80; + while(++m_bufPos < RATE_BYTES) { - state[i] ^= tmpy; - state[i + 1] ^= tmpx; + m_buf[m_bufPos] = 0x00; } - // execute SPARKLE with slim number of steps - sparkle_opt(state, STATE_BRANS, SPARKLE_STEPS_SLIM); - inlen -= RATE_BYTES; - inOff += RATE_BYTES; } - // Hashing of Last Block - // addition of constant M1 or M2 to the state - state[STATE_BRANS - 1] ^= ((inlen < RATE_BYTES) ? (1 << 24) : (1 << 25)); - // addition of last msg block (incl. padding) - int[] buffer = new int[RATE_WORDS]; - for (i = 0; i < inlen; ++i) + else { - buffer[i >>> 2] |= (input[inOff++] & 0xff) << ((i & 3) << 3); + state[(STATE_WORDS >> 1) - 1] ^= 1 << 25; } - if (inlen < RATE_BYTES) - { // padding - buffer[i >>> 2] |= 0x80 << ((i & 3) << 3); - } - tmpx = 0; - tmpy = 0; - for (i = 0; i < RATE_WORDS; i += 2) + + processBlock(m_buf, 0, SPARKLE_STEPS_BIG); + + Pack.intToLittleEndian(state, 0, RATE_WORDS, output, outOff); + + if (STATE_WORDS == 16) { - tmpx ^= buffer[i]; - tmpy ^= buffer[i + 1]; + SparkleEngine.sparkle_opt16(Friend.INSTANCE, state, SPARKLE_STEPS_SLIM); + Pack.intToLittleEndian(state, 0, RATE_WORDS, output, outOff + 16); + SparkleEngine.sparkle_opt16(Friend.INSTANCE, state, SPARKLE_STEPS_SLIM); + Pack.intToLittleEndian(state, 0, RATE_WORDS, output, outOff + 32); } - tmpx = ELL(tmpx); - tmpy = ELL(tmpy); - for (i = 0; i < RATE_WORDS; i += 2) + else { - state[i] ^= (buffer[i] ^ tmpy); - state[i + 1] ^= (buffer[i + 1] ^ tmpx); + SparkleEngine.sparkle_opt12(Friend.INSTANCE, state, SPARKLE_STEPS_SLIM); + Pack.intToLittleEndian(state, 0, RATE_WORDS, output, outOff + 16); } - for (i = RATE_WORDS; i < (STATE_WORDS / 2); i += 2) + + reset(); + return DIGEST_BYTES; + } + + @Override + public void reset() + { + Arrays.fill(state, 0); + Arrays.fill(m_buf, (byte)0); + m_bufPos = 0; + } + + private void processBlock(byte[] buf, int off, int steps) + { + int t0 = Pack.littleEndianToInt(buf, off ); + int t1 = Pack.littleEndianToInt(buf, off + 4); + int t2 = Pack.littleEndianToInt(buf, off + 8); + int t3 = Pack.littleEndianToInt(buf, off + 12); + + // addition of a buffer block to the state + int tx = ELL(t0 ^ t2); + int ty = ELL(t1 ^ t3); + state[0] ^= t0 ^ ty; + state[1] ^= t1 ^ tx; + state[2] ^= t2 ^ ty; + state[3] ^= t3 ^ tx; + state[4] ^= ty; + state[5] ^= tx; + if (STATE_WORDS == 16) { - state[i] ^= tmpy; - state[i + 1] ^= tmpx; + state[6] ^= ty; + state[7] ^= tx; + SparkleEngine.sparkle_opt16(Friend.INSTANCE, state, steps); } - // execute SPARKLE with big number of steps - sparkle_opt(state, STATE_BRANS, SPARKLE_STEPS_BIG); - Pack.intToLittleEndian(state, 0, RATE_WORDS, output, outOff); - int outlen = RATE_BYTES; - outOff += RATE_BYTES; - while (outlen < DIGEST_BYTES) + else { - sparkle_opt(state, STATE_BRANS, SPARKLE_STEPS_SLIM); - Pack.intToLittleEndian(state, 0, RATE_WORDS, output, outOff); - outlen += RATE_BYTES; - outOff += RATE_BYTES; + SparkleEngine.sparkle_opt12(Friend.INSTANCE, state, steps); } - return DIGEST_BYTES; } - @Override - public void reset() + private static int ELL(int x) { - Arrays.fill(state, (byte)0); - message.reset(); + return Integers.rotateRight(x, 16) ^ (x & 0xFFFF); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/digests/XoodyakDigest.java b/core/src/main/java/org/bouncycastle/crypto/digests/XoodyakDigest.java index 476dee34ed..33cf5e392e 100644 --- a/core/src/main/java/org/bouncycastle/crypto/digests/XoodyakDigest.java +++ b/core/src/main/java/org/bouncycastle/crypto/digests/XoodyakDigest.java @@ -6,6 +6,7 @@ import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Integers; import org.bouncycastle.util.Pack; /** @@ -26,9 +27,9 @@ public class XoodyakDigest private final int Rhash = 16; private final int PhaseDown = 1; private final int PhaseUp = 2; - private final int NLANES = 12; - private final int NROWS = 3; - private final int NCOLUMS = 4; +// private final int NLANES = 12; +// private final int NROWS = 3; +// private final int NCOLUMS = 4; private final int MAXROUNDS = 12; private final int TAGLEN = 16; private final int[] RC = {0x00000058, 0x00000038, 0x000003C0, 0x000000D0, 0x00000120, 0x00000014, 0x00000060, @@ -123,58 +124,109 @@ private void Up(byte[] Yi, int YiOff, int YiLen, int Cu) { state[f_bPrime - 1] ^= Cu; } - int[] a = new int[NLANES]; - Pack.littleEndianToInt(state, 0, a, 0, a.length); - int x, y; - int[] b = new int[NLANES]; - int[] p = new int[NCOLUMS]; - int[] e = new int[NCOLUMS]; + + int a0 = Pack.littleEndianToInt(state, 0); + int a1 = Pack.littleEndianToInt(state, 4); + int a2 = Pack.littleEndianToInt(state, 8); + int a3 = Pack.littleEndianToInt(state, 12); + int a4 = Pack.littleEndianToInt(state, 16); + int a5 = Pack.littleEndianToInt(state, 20); + int a6 = Pack.littleEndianToInt(state, 24); + int a7 = Pack.littleEndianToInt(state, 28); + int a8 = Pack.littleEndianToInt(state, 32); + int a9 = Pack.littleEndianToInt(state, 36); + int a10 = Pack.littleEndianToInt(state, 40); + int a11 = Pack.littleEndianToInt(state, 44); + for (int i = 0; i < MAXROUNDS; ++i) { /* Theta: Column Parity Mixer */ - for (x = 0; x < NCOLUMS; ++x) - { - p[x] = a[index(x, 0)] ^ a[index(x, 1)] ^ a[index(x, 2)]; - } - for (x = 0; x < NCOLUMS; ++x) - { - y = p[(x + 3) & 3]; - e[x] = ROTL32(y, 5) ^ ROTL32(y, 14); - } - for (x = 0; x < NCOLUMS; ++x) - { - for (y = 0; y < NROWS; ++y) - { - a[index(x, y)] ^= e[x]; - } - } + int p0 = a0 ^ a4 ^ a8; + int p1 = a1 ^ a5 ^ a9; + int p2 = a2 ^ a6 ^ a10; + int p3 = a3 ^ a7 ^ a11; + + int e0 = Integers.rotateLeft(p3, 5) ^ Integers.rotateLeft(p3, 14); + int e1 = Integers.rotateLeft(p0, 5) ^ Integers.rotateLeft(p0, 14); + int e2 = Integers.rotateLeft(p1, 5) ^ Integers.rotateLeft(p1, 14); + int e3 = Integers.rotateLeft(p2, 5) ^ Integers.rotateLeft(p2, 14); + + a0 ^= e0; + a4 ^= e0; + a8 ^= e0; + + a1 ^= e1; + a5 ^= e1; + a9 ^= e1; + + a2 ^= e2; + a6 ^= e2; + a10 ^= e2; + + a3 ^= e3; + a7 ^= e3; + a11 ^= e3; + /* Rho-west: plane shift */ - for (x = 0; x < NCOLUMS; ++x) - { - b[index(x, 0)] = a[index(x, 0)]; - b[index(x, 1)] = a[index(x + 3, 1)]; - b[index(x, 2)] = ROTL32(a[index(x, 2)], 11); - } + int b0 = a0; + int b1 = a1; + int b2 = a2; + int b3 = a3; + + int b4 = a7; + int b5 = a4; + int b6 = a5; + int b7 = a6; + + int b8 = Integers.rotateLeft(a8, 11); + int b9 = Integers.rotateLeft(a9, 11); + int b10 = Integers.rotateLeft(a10, 11); + int b11 = Integers.rotateLeft(a11, 11); + /* Iota: round ant */ - b[0] ^= RC[i]; + b0 ^= RC[i]; + /* Chi: non linear layer */ - for (x = 0; x < NCOLUMS; ++x) - { - for (y = 0; y < NROWS; ++y) - { - a[index(x, y)] = b[index(x, y)] ^ (~b[index(x, y + 1)] & b[index(x, y + 2)]); - } - } + a0 = b0 ^ (~b4 & b8); + a1 = b1 ^ (~b5 & b9); + a2 = b2 ^ (~b6 & b10); + a3 = b3 ^ (~b7 & b11); + + a4 = b4 ^ (~b8 & b0); + a5 = b5 ^ (~b9 & b1); + a6 = b6 ^ (~b10 & b2); + a7 = b7 ^ (~b11 & b3); + + b8 ^= (~b0 & b4); + b9 ^= (~b1 & b5); + b10 ^= (~b2 & b6); + b11 ^= (~b3 & b7); + /* Rho-east: plane shift */ - for (x = 0; x < NCOLUMS; ++x) - { - b[index(x, 0)] = a[index(x, 0)]; - b[index(x, 1)] = ROTL32(a[index(x, 1)], 1); - b[index(x, 2)] = ROTL32(a[index(x + 2, 2)], 8); - } - System.arraycopy(b, 0, a, 0, NLANES); + a4 = Integers.rotateLeft(a4, 1); + a5 = Integers.rotateLeft(a5, 1); + a6 = Integers.rotateLeft(a6, 1); + a7 = Integers.rotateLeft(a7, 1); + + a8 = Integers.rotateLeft(b10, 8); + a9 = Integers.rotateLeft(b11, 8); + a10 = Integers.rotateLeft(b8, 8); + a11 = Integers.rotateLeft(b9, 8); } - Pack.intToLittleEndian(a, 0, a.length, state, 0); + + Pack.intToLittleEndian(a0, state, 0); + Pack.intToLittleEndian(a1, state, 4); + Pack.intToLittleEndian(a2, state, 8); + Pack.intToLittleEndian(a3, state, 12); + Pack.intToLittleEndian(a4, state, 16); + Pack.intToLittleEndian(a5, state, 20); + Pack.intToLittleEndian(a6, state, 24); + Pack.intToLittleEndian(a7, state, 28); + Pack.intToLittleEndian(a8, state, 32); + Pack.intToLittleEndian(a9, state, 36); + Pack.intToLittleEndian(a10, state, 40); + Pack.intToLittleEndian(a11, state, 44); + phase = PhaseUp; if (Yi != null) { @@ -192,15 +244,4 @@ void Down(byte[] Xi, int XiOff, int XiLen, int Cd) state[f_bPrime - 1] ^= (mode == MODE.ModeHash) ? (Cd & 0x01) : Cd; phase = PhaseDown; } - - private int index(int x, int y) - { - return (((y % NROWS) * NCOLUMS) + ((x) % NCOLUMS)); - } - - private int ROTL32(int a, int offset) - { - return (a << (offset & 31)) ^ (a >>> ((32 - (offset)) & 31)); - } - } diff --git a/core/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java b/core/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java index 7d82474590..07de1a6a81 100644 --- a/core/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java +++ b/core/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java @@ -6,12 +6,12 @@ import java.util.Vector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; import org.bouncycastle.asn1.gm.GMObjectIdentifiers; import org.bouncycastle.asn1.sec.SECObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECParametersHolder; import org.bouncycastle.asn1.x9.X9ECPoint; +import org.bouncycastle.internal.asn1.cryptlib.CryptlibObjectIdentifiers; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.WNafUtil; import org.bouncycastle.math.ec.custom.djb.Curve25519; diff --git a/core/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java b/core/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java index 205b30c917..9667f12871 100644 --- a/core/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java +++ b/core/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java @@ -7,10 +7,13 @@ import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.util.DigestFactory; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Bytes; +import org.bouncycastle.util.Memoable; import org.bouncycastle.util.Pack; /** @@ -19,10 +22,21 @@ public class OAEPEncoding implements AsymmetricBlockCipher { - private byte[] defHash; - private Digest mgf1Hash; + private static int getMGF1NoMemoLimit(Digest d) + { + if (d instanceof Memoable && d instanceof ExtendedDigest) + { + return ((ExtendedDigest)d).getByteLength() - 1; + } + + return Integer.MAX_VALUE; + } + + private final AsymmetricBlockCipher engine; + private final Digest mgf1Hash; + private final int mgf1NoMemoLimit; + private final byte[] defHash; - private AsymmetricBlockCipher engine; private SecureRandom random; private boolean forEncryption; @@ -55,6 +69,7 @@ public OAEPEncoding( { this.engine = cipher; this.mgf1Hash = mgf1Hash; + this.mgf1NoMemoLimit = getMGF1NoMemoLimit(mgf1Hash); this.defHash = new byte[hash.getDigestSize()]; hash.reset(); @@ -72,24 +87,19 @@ public AsymmetricBlockCipher getUnderlyingCipher() return engine; } - public void init( - boolean forEncryption, - CipherParameters param) + public void init(boolean forEncryption, CipherParameters param) { + SecureRandom initRandom = null; if (param instanceof ParametersWithRandom) { - ParametersWithRandom rParam = (ParametersWithRandom)param; - - this.random = rParam.getRandom(); - } - else - { - this.random = CryptoServicesRegistrar.getSecureRandom(); + ParametersWithRandom rParam = (ParametersWithRandom)param; + initRandom = rParam.getRandom(); } - engine.init(forEncryption, param); - + this.random = forEncryption ? CryptoServicesRegistrar.getSecureRandom(initRandom) : null; this.forEncryption = forEncryption; + + engine.init(forEncryption, param); } public int getInputBlockSize() @@ -136,18 +146,15 @@ public byte[] processBlock( } } - public byte[] encodeBlock( - byte[] in, - int inOff, - int inLen) - throws InvalidCipherTextException + public byte[] encodeBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException { - if (inLen > getInputBlockSize()) + int inputBlockSize = getInputBlockSize(); + if (inLen > inputBlockSize) { throw new DataLengthException("input data too long"); } - byte[] block = new byte[getInputBlockSize() + 1 + 2 * defHash.length]; + byte[] block = new byte[inputBlockSize + 1 + 2 * defHash.length]; // // copy in the message @@ -171,35 +178,21 @@ public byte[] encodeBlock( // // generate the seed. // - byte[] seed = new byte[defHash.length]; - + byte[] seed = new byte[defHash.length]; random.nextBytes(seed); + System.arraycopy(seed, 0, block, 0, defHash.length); - // - // mask the message block. - // - byte[] mask = maskGeneratorFunction1(seed, 0, seed.length, block.length - defHash.length); - - for (int i = defHash.length; i != block.length; i++) - { - block[i] ^= mask[i - defHash.length]; - } + mgf1Hash.reset(); // - // add in the seed + // mask the message block. // - System.arraycopy(seed, 0, block, 0, defHash.length); + maskGeneratorFunction1(seed, 0, seed.length, block, defHash.length, block.length - defHash.length); // // mask the seed. // - mask = maskGeneratorFunction1( - block, defHash.length, block.length - defHash.length, defHash.length); - - for (int i = 0; i != defHash.length; i++) - { - block[i] ^= mask[i]; - } + maskGeneratorFunction1(block, defHash.length, block.length - defHash.length, block, 0, defHash.length); return engine.processBlock(block, 0, block.length); } @@ -208,54 +201,37 @@ public byte[] encodeBlock( * @exception InvalidCipherTextException if the decrypted block turns out to * be badly formatted. */ - public byte[] decodeBlock( - byte[] in, - int inOff, - int inLen) - throws InvalidCipherTextException + public byte[] decodeBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException { - byte[] data = engine.processBlock(in, inOff, inLen); - byte[] block = new byte[engine.getOutputBlockSize()]; + // i.e. wrong when block.length < (2 * defHash.length) + 1 + int wrongMask = getOutputBlockSize() >> 31; // // as we may have zeros in our leading bytes for the block we produced // on encryption, we need to make sure our decrypted block comes back // the same size. // - - // i.e. wrong when block.length < (2 * defHash.length) + 1 - int wrongMask = (block.length - ((2 * defHash.length) + 1)) >> 31; - - if (data.length <= block.length) - { - System.arraycopy(data, 0, block, block.length - data.length, data.length); - } - else + byte[] block = new byte[engine.getOutputBlockSize()]; { - System.arraycopy(data, 0, block, 0, block.length); - wrongMask |= 1; + byte[] data = engine.processBlock(in, inOff, inLen); + wrongMask |= (block.length - data.length) >> 31; + + int copyLen = Math.min(block.length, data.length); + System.arraycopy(data, 0, block, block.length - copyLen, copyLen); + Arrays.fill(data, (byte)0); } + mgf1Hash.reset(); + // // unmask the seed. // - byte[] mask = maskGeneratorFunction1( - block, defHash.length, block.length - defHash.length, defHash.length); - - for (int i = 0; i != defHash.length; i++) - { - block[i] ^= mask[i]; - } + maskGeneratorFunction1(block, defHash.length, block.length - defHash.length, block, 0, defHash.length); // // unmask the message block. // - mask = maskGeneratorFunction1(block, 0, defHash.length, block.length - defHash.length); - - for (int i = defHash.length; i != block.length; i++) - { - block[i] ^= mask[i - defHash.length]; - } + maskGeneratorFunction1(block, 0, defHash.length, block, defHash.length, block.length - defHash.length); // // check the hash of the encoding params. @@ -296,7 +272,7 @@ public byte[] decodeBlock( // // extract the data block // - byte[] output = new byte[block.length - start]; + byte[] output = new byte[block.length - start]; System.arraycopy(block, start, output, 0, output.length); Arrays.fill(block, (byte)0); @@ -307,43 +283,51 @@ public byte[] decodeBlock( /** * mask generator function, as described in PKCS1v2. */ - private byte[] maskGeneratorFunction1( - byte[] Z, - int zOff, - int zLen, - int length) + private void maskGeneratorFunction1(byte[] z, int zOff, int zLen, byte[] mask, int maskOff, int maskLen) { - byte[] mask = new byte[length]; - byte[] hashBuf = new byte[mgf1Hash.getDigestSize()]; - byte[] C = new byte[4]; - int counter = 0; + int digestSize = mgf1Hash.getDigestSize(); - mgf1Hash.reset(); + byte[] hash = new byte[digestSize]; + byte[] C = new byte[4]; + int counter = 0; - while (counter < (length / hashBuf.length)) - { - Pack.intToBigEndian(counter, C, 0); - - mgf1Hash.update(Z, zOff, zLen); - mgf1Hash.update(C, 0, C.length); - mgf1Hash.doFinal(hashBuf, 0); + int maskEnd = maskOff + maskLen; + int maskLimit = maskEnd - digestSize; + int maskPos = maskOff; - System.arraycopy(hashBuf, 0, mask, counter * hashBuf.length, hashBuf.length); + mgf1Hash.update(z, zOff, zLen); - counter++; + if (zLen > mgf1NoMemoLimit) + { + Memoable memoable = (Memoable)mgf1Hash; + Memoable memo = memoable.copy(); + + while (maskPos < maskLimit) + { + Pack.intToBigEndian(counter++, C, 0); + mgf1Hash.update(C, 0, C.length); + mgf1Hash.doFinal(hash, 0); + memoable.reset(memo); + Bytes.xorTo(digestSize, hash, 0, mask, maskPos); + maskPos += digestSize; + } } - - if ((counter * hashBuf.length) < length) + else { - Pack.intToBigEndian(counter, C, 0); - - mgf1Hash.update(Z, zOff, zLen); - mgf1Hash.update(C, 0, C.length); - mgf1Hash.doFinal(hashBuf, 0); - - System.arraycopy(hashBuf, 0, mask, counter * hashBuf.length, mask.length - (counter * hashBuf.length)); + while (maskPos < maskLimit) + { + Pack.intToBigEndian(counter++, C, 0); + mgf1Hash.update(C, 0, C.length); + mgf1Hash.doFinal(hash, 0); + mgf1Hash.update(z, zOff, zLen); + Bytes.xorTo(digestSize, hash, 0, mask, maskPos); + maskPos += digestSize; + } } - return mask; + Pack.intToBigEndian(counter, C, 0); + mgf1Hash.update(C, 0, C.length); + mgf1Hash.doFinal(hash, 0); + Bytes.xorTo(maskEnd - maskPos, hash, 0, mask, maskPos); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java b/core/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java index 36126aacb6..470f81cade 100644 --- a/core/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java +++ b/core/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java @@ -233,52 +233,86 @@ private byte[] encodeBlock( } /** - * Checks if the argument is a correctly PKCS#1.5 encoded Plaintext - * for encryption. - * - * @param encoded The Plaintext. - * @param pLen Expected length of the plaintext. - * @return Either 0, if the encoding is correct, or -1, if it is incorrect. + * Check the argument is a valid encoding with type 1. Returns the plaintext length if valid, or -1 if invalid. */ - private static int checkPkcs1Encoding(byte[] encoded, int pLen) + private static int checkPkcs1Encoding1(byte[] buf) { - int correct = 0; - /* - * Check if the first two bytes are 0 2 - */ - correct |= (encoded[0] ^ 2); + int foundZeroMask = 0; + int lastPadPos = 0; - /* - * Now the padding check, check for no 0 byte in the padding - */ - int plen = encoded.length - ( - pLen /* Length of the PMS */ - + 1 /* Final 0-byte before PMS */ - ); + // The first byte should be 0x01 + int badPadSign = -((buf[0] & 0xFF) ^ 0x01); - for (int i = 1; i < plen; i++) + // There must be a zero terminator for the padding somewhere + for (int i = 1; i < buf.length; ++i) { - int tmp = encoded[i]; - tmp |= tmp >> 1; - tmp |= tmp >> 2; - tmp |= tmp >> 4; - correct |= (tmp & 1) - 1; + int padByte = buf[i] & 0xFF; + int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31; + int is0xFFMask = ((padByte ^ 0xFF) - 1) >> 31; + lastPadPos ^= i & ~foundZeroMask & is0x00Mask; + foundZeroMask |= is0x00Mask; + badPadSign |= ~(foundZeroMask | is0xFFMask); } - /* - * Make sure the padding ends with a 0 byte. - */ - correct |= encoded[encoded.length - (pLen + 1)]; + // The header should be at least 10 bytes + badPadSign |= lastPadPos - 9; - /* - * Return 0 or 1, depending on the result. - */ - correct |= correct >> 1; - correct |= correct >> 2; - correct |= correct >> 4; - return ~((correct & 1) - 1); + int plaintextLength = buf.length - 1 - lastPadPos; + return plaintextLength | badPadSign >> 31; } + /** + * Check the argument is a valid encoding with type 2. Returns the plaintext length if valid, or -1 if invalid. + */ + private static int checkPkcs1Encoding2(byte[] buf) + { + int foundZeroMask = 0; + int lastPadPos = 0; + + // The first byte should be 0x02 + int badPadSign = -((buf[0] & 0xFF) ^ 0x02); + + // There must be a zero terminator for the padding somewhere + for (int i = 1; i < buf.length; ++i) + { + int padByte = buf[i] & 0xFF; + int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31; + lastPadPos ^= i & ~foundZeroMask & is0x00Mask; + foundZeroMask |= is0x00Mask; + } + + // The header should be at least 10 bytes + badPadSign |= lastPadPos - 9; + + int plaintextLength = buf.length - 1 - lastPadPos; + return plaintextLength | badPadSign >> 31; + } + + /** + * Check the argument is a valid encoding with type 2 of a plaintext with the given length. Returns 0 if + * valid, or -1 if invalid. + */ + private static int checkPkcs1Encoding2(byte[] buf, int plaintextLength) + { + // The first byte should be 0x02 + int badPadSign = -((buf[0] & 0xFF) ^ 0x02); + + int lastPadPos = buf.length - 1 - plaintextLength; + + // The header should be at least 10 bytes + badPadSign |= lastPadPos - 9; + + // All pad bytes before the last one should be non-zero + for (int i = 1; i < lastPadPos; ++i) + { + badPadSign |= (buf[i] & 0xFF) - 1; + } + + // Last pad byte should be zero + badPadSign |= -(buf[lastPadPos] & 0xFF); + + return badPadSign >> 31; + } /** * Decode PKCS#1.5 encoding, and return a random value if the padding is not correct. @@ -298,36 +332,43 @@ private byte[] decodeBlockOrRandom(byte[] in, int inOff, int inLen) throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing"); } - byte[] block = engine.processBlock(in, inOff, inLen); - byte[] random; - if (this.fallback == null) + int plaintextLength = this.pLen; + + byte[] random = fallback; + if (fallback == null) { - random = new byte[this.pLen]; + random = new byte[plaintextLength]; this.random.nextBytes(random); } - else + + int badPadMask = 0; + int strictBlockSize = engine.getOutputBlockSize(); + byte[] block = engine.processBlock(in, inOff, inLen); + + byte[] data = block; + if (block.length != strictBlockSize) { - random = fallback; + if (useStrictLength || block.length < strictBlockSize) + { + data = blockBuffer; + } } - byte[] data = (useStrictLength & (block.length != engine.getOutputBlockSize())) ? blockBuffer : block; + badPadMask |= checkPkcs1Encoding2(data, plaintextLength); - /* - * Check the padding. - */ - int correct = PKCS1Encoding.checkPkcs1Encoding(data, this.pLen); - /* * Now, to a constant time constant memory copy of the decrypted value * or the random value, depending on the validity of the padding. */ - byte[] result = new byte[this.pLen]; - for (int i = 0; i < this.pLen; i++) + int dataOff = data.length - plaintextLength; + byte[] result = new byte[plaintextLength]; + for (int i = 0; i < plaintextLength; ++i) { - result[i] = (byte)((data[i + (data.length - pLen)] & (~correct)) | (random[i] & correct)); + result[i] = (byte)((data[dataOff + i] & ~badPadMask) | (random[i] & badPadMask)); } - Arrays.fill(data, (byte)0); + Arrays.fill(block, (byte)0); + Arrays.fill(blockBuffer, 0, Math.max(0, blockBuffer.length - block.length), (byte)0); return result; } @@ -335,95 +376,50 @@ private byte[] decodeBlockOrRandom(byte[] in, int inOff, int inLen) /** * @throws InvalidCipherTextException if the decrypted block is not in PKCS1 format. */ - private byte[] decodeBlock( - byte[] in, - int inOff, - int inLen) + private byte[] decodeBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException { /* * If the length of the expected plaintext is known, we use a constant-time decryption. * If the decryption fails, we return a random value. */ - if (this.pLen != -1) + if (forPrivateKey && this.pLen != -1) { return this.decodeBlockOrRandom(in, inOff, inLen); } + int strictBlockSize = engine.getOutputBlockSize(); byte[] block = engine.processBlock(in, inOff, inLen); - boolean incorrectLength = (useStrictLength & (block.length != engine.getOutputBlockSize())); - - byte[] data; - if (block.length < getOutputBlockSize()) - { - data = blockBuffer; - } - else - { - data = block; - } - - byte type = data[0]; - - boolean badType; - if (forPrivateKey) - { - badType = (type != 2); - } - else - { - badType = (type != 1); - } - - // - // find and extract the message block. - // - int start = findStart(type, data); - - start++; // data should start at the next byte - if (badType | start < HEADER_LENGTH) - { - Arrays.fill(data, (byte)0); - throw new InvalidCipherTextException("block incorrect"); - } + boolean incorrectLength = useStrictLength & (block.length != strictBlockSize); - // if we get this far, it's likely to be a genuine encoding error - if (incorrectLength) + byte[] data = block; + if (block.length < strictBlockSize) { - Arrays.fill(data, (byte)0); - throw new InvalidCipherTextException("block incorrect size"); + data = blockBuffer; } - byte[] result = new byte[data.length - start]; - - System.arraycopy(data, start, result, 0, result.length); - - return result; - } + int plaintextLength = forPrivateKey ? checkPkcs1Encoding2(data) : checkPkcs1Encoding1(data); - private int findStart(byte type, byte[] block) - throws InvalidCipherTextException - { - int start = -1; - boolean padErr = false; - - for (int i = 1; i != block.length; i++) + try { - byte pad = block[i]; - - if (pad == 0 & start < 0) + if (plaintextLength < 0) { - start = i; + throw new InvalidCipherTextException("block incorrect"); + } + if (incorrectLength) + { + throw new InvalidCipherTextException("block incorrect size"); } - padErr |= (type == 1 & start < 0 & pad != (byte)0xff); - } - if (padErr) + byte[] result = new byte[plaintextLength]; + System.arraycopy(data, data.length - plaintextLength, result, 0, plaintextLength); + return result; + } + finally { - return -1; + Arrays.fill(block, (byte)0); + Arrays.fill(blockBuffer, 0, Math.max(0, blockBuffer.length - block.length), (byte)0); } - - return start; } } diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java index c5cad0a782..ac2eb9aa6a 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java @@ -433,6 +433,7 @@ public static MultiBlockCipher newInstance() /** * default constructor - 128 bit block size. + * @deprecated use AESEngine.newInstance() */ public AESEngine() { diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java index 80309a3ac4..cf70e87b73 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java @@ -14,7 +14,7 @@ public class AESWrapEngine */ public AESWrapEngine() { - super(new AESEngine()); + super(AESEngine.newInstance()); } /** @@ -24,6 +24,6 @@ public AESWrapEngine() */ public AESWrapEngine(boolean useReverseDirection) { - super(new AESEngine(), useReverseDirection); + super(AESEngine.newInstance(), useReverseDirection); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/AESWrapPadEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/AESWrapPadEngine.java index 7776061239..f4c5d43390 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/AESWrapPadEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/AESWrapPadEngine.java @@ -5,6 +5,6 @@ public class AESWrapPadEngine { public AESWrapPadEngine() { - super(new AESEngine()); + super(AESEngine.newInstance()); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/ARIAEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/ARIAEngine.java index 6faeabb10a..c2780428df 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/ARIAEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/ARIAEngine.java @@ -7,6 +7,7 @@ import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.constraints.DefaultServiceProperties; import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.util.Bytes; import org.bouncycastle.util.encoders.Hex; /** @@ -425,10 +426,7 @@ protected static void SL2(byte[] z) protected static void xor(byte[] z, byte[] x) { - for (int i = 0; i < 16; ++i) - { - z[i] ^= x[i]; - } + Bytes.xorTo(16, x, z); } private int bitsOfSecurity() diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/AsconEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/AsconEngine.java index 08c02db321..e4d705ffcc 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/AsconEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/AsconEngine.java @@ -11,9 +11,9 @@ import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Longs; import org.bouncycastle.util.Pack; - /** * ASCON AEAD v1.2, https://ascon.iaik.tugraz.at/ * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/ascon-spec-final.pdf @@ -21,8 +21,6 @@ * ASCON AEAD v1.2 with reference to C Reference Impl from: https://github.com/ascon/ascon-c *

    */ - - public class AsconEngine implements AEADCipher { @@ -104,11 +102,6 @@ public AsconEngine(AsconParameters asconParameters) m_buf = new byte[m_bufferSizeDecrypt]; } - private long ROR(long x, int n) - { - return x >>> n | x << (64 - n); - } - private long PAD(int i) { return 0x80L << (56 - (i << 3)); @@ -121,24 +114,24 @@ private void ROUND(long C) long t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4); long t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4)); long t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1); - x0 = t0 ^ ROR(t0, 19) ^ ROR(t0, 28); - x1 = t1 ^ ROR(t1, 39) ^ ROR(t1, 61); - x2 = ~(t2 ^ ROR(t2, 1) ^ ROR(t2, 6)); - x3 = t3 ^ ROR(t3, 10) ^ ROR(t3, 17); - x4 = t4 ^ ROR(t4, 7) ^ ROR(t4, 41); + x0 = t0 ^ Longs.rotateRight(t0, 19) ^ Longs.rotateRight(t0, 28); + x1 = t1 ^ Longs.rotateRight(t1, 39) ^ Longs.rotateRight(t1, 61); + x2 = ~(t2 ^ Longs.rotateRight(t2, 1) ^ Longs.rotateRight(t2, 6)); + x3 = t3 ^ Longs.rotateRight(t3, 10) ^ Longs.rotateRight(t3, 17); + x4 = t4 ^ Longs.rotateRight(t4, 7) ^ Longs.rotateRight(t4, 41); } private void P(int nr) { - if (nr == 12) - { - ROUND(0xf0L); - ROUND(0xe1L); - ROUND(0xd2L); - ROUND(0xc3L); - } if (nr >= 8) { + if (nr == 12) + { + ROUND(0xf0L); + ROUND(0xe1L); + ROUND(0xd2L); + ROUND(0xc3L); + } ROUND(0xb4L); ROUND(0xa5L); } @@ -171,7 +164,7 @@ private void ascon_aeadinit() x4 ^= K2; } - private void checkAad() + private void checkAAD() { switch (m_state) { @@ -185,36 +178,36 @@ private void checkAad() case EncAad: break; case EncFinal: - throw new IllegalArgumentException(algorithmName + " cannot be reused for encryption"); + throw new IllegalStateException(getAlgorithmName() + " cannot be reused for encryption"); default: - throw new IllegalArgumentException(); + throw new IllegalStateException(getAlgorithmName() + " needs to be initialized"); } } - private boolean CheckData() + private boolean checkData() { switch (m_state) { case DecInit: case DecAad: - FinishAad(State.DecData); + finishAAD(State.DecData); return false; case EncInit: case EncAad: - FinishAad(State.EncData); + finishAAD(State.EncData); return true; case DecData: return false; case EncData: return true; case EncFinal: - throw new IllegalArgumentException(algorithmName + " cannot be reused for encryption"); + throw new IllegalStateException(getAlgorithmName() + " cannot be reused for encryption"); default: - throw new IllegalArgumentException(); + throw new IllegalStateException(getAlgorithmName() + " needs to be initialized"); } } - private void ProcessBufferAad(byte[] buffer, int inOff) + private void processBufferAAD(byte[] buffer, int inOff) { x0 ^= Pack.bigEndianToLong(buffer, inOff); if (ASCON_AEAD_RATE == 16) @@ -224,7 +217,7 @@ private void ProcessBufferAad(byte[] buffer, int inOff) P(nr); } - private void FinishAad(State nextState) + private void finishAAD(State nextState) { // State indicates whether we ever received AAD switch (m_state) @@ -243,6 +236,8 @@ private void FinishAad(State nextState) } P(nr); break; + default: + break; } // domain separation x4 ^= 1L; @@ -250,11 +245,11 @@ private void FinishAad(State nextState) m_state = nextState; } - private void ProcessBufferDecrypt(byte[] buffer, int bufOff, byte[] output, int outOff) + private void processBufferDecrypt(byte[] buffer, int bufOff, byte[] output, int outOff) { if (outOff + ASCON_AEAD_RATE > output.length) { - throw new OutputLengthException(algorithmName + " output buffer too short"); + throw new OutputLengthException("output buffer too short"); } long t0 = Pack.bigEndianToLong(buffer, bufOff); Pack.longToBigEndian(x0 ^ t0, output, outOff); @@ -269,11 +264,11 @@ private void ProcessBufferDecrypt(byte[] buffer, int bufOff, byte[] output, int P(nr); } - private void ProcessBufferEncrypt(byte[] buffer, int bufOff, byte[] output, int outOff) + private void processBufferEncrypt(byte[] buffer, int bufOff, byte[] output, int outOff) { if (outOff + ASCON_AEAD_RATE > output.length) { - throw new OutputLengthException(algorithmName + " output buffer too short"); + throw new OutputLengthException("output buffer too short"); } x0 ^= Pack.bigEndianToLong(buffer, bufOff); Pack.longToBigEndian(x0, output, outOff); @@ -287,7 +282,7 @@ private void ProcessBufferEncrypt(byte[] buffer, int bufOff, byte[] output, int P(nr); } - private void ProcessFinalDecrypt(byte[] input, int inOff, int inLen, byte[] output, int outOff) + private void processFinalDecrypt(byte[] input, int inOff, int inLen, byte[] output, int outOff) { if (inLen >= 8) // ASCON_AEAD_RATE == 16 is implied { @@ -321,10 +316,10 @@ private void ProcessFinalDecrypt(byte[] input, int inOff, int inLen, byte[] outp } } - FinishData(State.DecFinal); + finishData(State.DecFinal); } - private void ProcessFinalEncrypt(byte[] input, int inOff, int inLen, byte[] output, int outOff) + private void processFinalEncrypt(byte[] input, int inOff, int inLen, byte[] output, int outOff) { if (inLen >= 8) // ASCON_AEAD_RATE == 16 is implied { @@ -349,10 +344,10 @@ private void ProcessFinalEncrypt(byte[] input, int inOff, int inLen, byte[] outp Pack.longToLittleEndian_High(x0, output, outOff, inLen); } } - FinishData(State.EncFinal); + finishData(State.EncFinal); } - private void FinishData(State nextState) + private void finishData(State nextState) { switch (asconParameters) { @@ -370,7 +365,7 @@ private void FinishData(State nextState) x3 ^= K2 << 32; break; default: - //throw new InvalidOperationException(); + throw new IllegalStateException(); } P(12); x3 ^= K1; @@ -379,7 +374,6 @@ private void FinishData(State nextState) m_state = nextState; } - @Override public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { @@ -440,12 +434,16 @@ else if (CRYPTO_KEYBYTES == 20) K1 = Pack.bigEndianToLong(k, 4); K2 = Pack.bigEndianToLong(k, 12); } + else + { + throw new IllegalStateException(); + } + m_state = forEncryption ? State.EncInit : State.DecInit; - /*Mask-Gen*/ + reset(true); } - @Override public String getAlgorithmName() { return algorithmName; @@ -456,18 +454,16 @@ public String getAlgorithmVersion() return "v1.2"; } - @Override public void processAADByte(byte in) { - checkAad(); + checkAAD(); m_buf[m_bufPos] = in; if (++m_bufPos == ASCON_AEAD_RATE) { - ProcessBufferAad(m_buf, 0); + processBufferAAD(m_buf, 0); } } - @Override public void processAADBytes(byte[] inBytes, int inOff, int len) { if ((inOff + len) > inBytes.length) @@ -479,7 +475,7 @@ public void processAADBytes(byte[] inBytes, int inOff, int len) { return; } - checkAad(); + checkAAD(); if (m_bufPos > 0) { int available = ASCON_AEAD_RATE - m_bufPos; @@ -492,11 +488,12 @@ public void processAADBytes(byte[] inBytes, int inOff, int len) System.arraycopy(inBytes, inOff, m_buf, m_bufPos, available); inOff += available; len -= available; - ProcessBufferAad(m_buf, 0); + processBufferAAD(m_buf, 0); + //m_bufPos = 0; } while (len >= ASCON_AEAD_RATE) { - ProcessBufferAad(inBytes, inOff); + processBufferAAD(inBytes, inOff); inOff += ASCON_AEAD_RATE; len -= ASCON_AEAD_RATE; } @@ -504,14 +501,12 @@ public void processAADBytes(byte[] inBytes, int inOff, int len) m_bufPos = len; } - @Override public int processByte(byte in, byte[] out, int outOff) throws DataLengthException { return processBytes(new byte[]{in}, 0, 1, out, outOff); } - @Override public int processBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff) throws DataLengthException { @@ -519,7 +514,7 @@ public int processBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int { throw new DataLengthException("input buffer too short"); } - boolean forEncryption = CheckData(); + boolean forEncryption = checkData(); int resultLength = 0; if (forEncryption) @@ -538,14 +533,14 @@ public int processBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int inOff += available; len -= available; - ProcessBufferEncrypt(m_buf, 0, outBytes, outOff); + processBufferEncrypt(m_buf, 0, outBytes, outOff); resultLength = ASCON_AEAD_RATE; //m_bufPos = 0; } while (len >= ASCON_AEAD_RATE) { - ProcessBufferEncrypt(inBytes, inOff, outBytes, outOff + resultLength); + processBufferEncrypt(inBytes, inOff, outBytes, outOff + resultLength); inOff += ASCON_AEAD_RATE; len -= ASCON_AEAD_RATE; resultLength += ASCON_AEAD_RATE; @@ -561,12 +556,13 @@ public int processBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int return 0; } - if (m_bufPos >= ASCON_AEAD_RATE) + // NOTE: Need 'while' here because ASCON_AEAD_RATE < CRYPTO_ABYTES in some parameter sets + while (m_bufPos >= ASCON_AEAD_RATE) { - ProcessBufferDecrypt(m_buf, 0, outBytes, outOff); + processBufferDecrypt(m_buf, 0, outBytes, outOff + resultLength); m_bufPos -= ASCON_AEAD_RATE; System.arraycopy(m_buf, ASCON_AEAD_RATE, m_buf, 0, m_bufPos); - resultLength = ASCON_AEAD_RATE; + resultLength += ASCON_AEAD_RATE; available += ASCON_AEAD_RATE; if (len < available) @@ -581,13 +577,13 @@ public int processBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int System.arraycopy(inBytes, inOff, m_buf, m_bufPos, available); inOff += available; len -= available; - ProcessBufferDecrypt(m_buf, 0, outBytes, outOff + resultLength); + processBufferDecrypt(m_buf, 0, outBytes, outOff + resultLength); resultLength += ASCON_AEAD_RATE; //m_bufPos = 0; while (len >= m_bufferSizeDecrypt) { - ProcessBufferDecrypt(inBytes, inOff, outBytes, outOff + resultLength); + processBufferDecrypt(inBytes, inOff, outBytes, outOff + resultLength); inOff += ASCON_AEAD_RATE; len -= ASCON_AEAD_RATE; resultLength += ASCON_AEAD_RATE; @@ -600,20 +596,19 @@ public int processBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int return resultLength; } - @Override public int doFinal(byte[] outBytes, int outOff) throws IllegalStateException, InvalidCipherTextException, DataLengthException { - boolean forEncryption = CheckData(); + boolean forEncryption = checkData(); int resultLength; if (forEncryption) { resultLength = m_bufPos + CRYPTO_ABYTES; if (outOff + resultLength > outBytes.length) { - throw new OutputLengthException(algorithmName + " output buffer too short"); + throw new OutputLengthException("output buffer too short"); } - ProcessFinalEncrypt(m_buf, 0, m_bufPos, outBytes, outOff); + processFinalEncrypt(m_buf, 0, m_bufPos, outBytes, outOff); mac = new byte[CRYPTO_ABYTES]; Pack.longToBigEndian(x3, mac, 0); Pack.longToBigEndian(x4, mac, 8); @@ -630,27 +625,25 @@ public int doFinal(byte[] outBytes, int outOff) resultLength = m_bufPos; if (outOff + resultLength > outBytes.length) { - throw new OutputLengthException(algorithmName + " output buffer too short"); + throw new OutputLengthException("output buffer too short"); } - ProcessFinalDecrypt(m_buf, 0, m_bufPos, outBytes, outOff); + processFinalDecrypt(m_buf, 0, m_bufPos, outBytes, outOff); x3 ^= Pack.bigEndianToLong(m_buf, m_bufPos); x4 ^= Pack.bigEndianToLong(m_buf, m_bufPos + 8); if ((x3 | x4) != 0L) { - throw new InvalidCipherTextException("mac check in " + algorithmName + " failed"); + throw new InvalidCipherTextException("mac check in " + getAlgorithmName() + " failed"); } reset(true); } return resultLength; } - @Override public byte[] getMac() { return mac; } - @Override public int getUpdateOutputSize(int len) { int total = Math.max(0, len); @@ -674,7 +667,6 @@ public int getUpdateOutputSize(int len) return total - total % ASCON_AEAD_RATE; } - @Override public int getOutputSize(int len) { int total = Math.max(0, len); @@ -695,7 +687,6 @@ public int getOutputSize(int len) } } - @Override public void reset() { reset(true); @@ -726,7 +717,7 @@ private void reset(boolean clearMac) m_state = State.EncFinal; return; default: - throw new IllegalArgumentException(); + throw new IllegalStateException(getAlgorithmName() + " needs to be initialized"); } ascon_aeadinit(); if (initialAssociatedText != null) @@ -745,5 +736,3 @@ public int getIVBytesSize() return CRYPTO_ABYTES; } } - - diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/CAST5Engine.java b/core/src/main/java/org/bouncycastle/crypto/engines/CAST5Engine.java index 0d02c4828b..d00314dd45 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/CAST5Engine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/CAST5Engine.java @@ -742,8 +742,6 @@ protected final void CAST_Encipher(int L0, int R0, int result[]) result[0] = Ri; result[1] = Li; - - return; } protected final void CAST_Decipher(int L16, int R16, int result[]) @@ -792,8 +790,6 @@ protected final void CAST_Decipher(int L16, int R16, int result[]) result[0] = Ri; result[1] = Li; - - return; } protected final void Bits32ToInts(int in, int[] b, int offset) diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java index df1ffc53aa..51ba9bd4e6 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java @@ -43,7 +43,7 @@ public void init( { if (params instanceof KeyParameter) { - if (((KeyParameter)params).getKey().length > 8) + if (((KeyParameter)params).getKeyLength() > 8) { throw new IllegalArgumentException("DES key too long - should be 8 bytes"); } diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/EthereumIESEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/EthereumIESEngine.java index bcbc4e97e2..09a41db9ea 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/EthereumIESEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/EthereumIESEngine.java @@ -251,7 +251,7 @@ private byte[] encryptBlock(byte[] in, int inOff, int inLen) // Ethereum change: // Instead of initializing the mac with the bytes, we initialize with the hash of the bytes. // Old code: mac.init(new KeyParameter(K2)); - Digest hash = new SHA256Digest(); + Digest hash = SHA256Digest.newInstance(); byte[] K2hash = new byte[hash.getDigestSize()]; hash.reset(); hash.update(K2, 0, K2.length); @@ -367,7 +367,7 @@ private byte[] decryptBlock(byte[] in_enc, int inOff, int inLen) // Ethereum change: // Instead of initializing the mac with the bytes, we initialize with the hash of the bytes. // Old code: mac.init(new KeyParameter(K2)); - Digest hash = new SHA256Digest(); + Digest hash = SHA256Digest.newInstance(); byte[] K2hash = new byte[hash.getDigestSize()]; hash.reset(); hash.update(K2, 0, K2.length); diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/Grain128AEADEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/Grain128AEADEngine.java index 3bd368bf88..0d8672c198 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/Grain128AEADEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/Grain128AEADEngine.java @@ -56,7 +56,7 @@ public String getAlgorithmName() public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { - /** + /* * Grain encryption and decryption is completely symmetrical, so the * 'forEncryption' is irrelevant. */ @@ -93,7 +93,7 @@ public void init(boolean forEncryption, CipherParameters params) CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties( this.getAlgorithmName(), 128, params, Utils.getPurpose(forEncryption))); - /** + /* * Initialize variables. */ workingIV = new byte[16]; @@ -270,7 +270,7 @@ private void setKey(byte[] keyBytes, byte[] ivBytes) workingKey = keyBytes; workingIV = ivBytes; - /** + /* * Load NFSR and LFSR */ Pack.littleEndianToInt(workingKey, 0, nfsr); diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/Grain128Engine.java b/core/src/main/java/org/bouncycastle/crypto/engines/Grain128Engine.java index ccb2f7880c..b4eb8b0a69 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/Grain128Engine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/Grain128Engine.java @@ -51,7 +51,7 @@ public String getAlgorithmName() public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { - /** + /* * Grain encryption and decryption is completely symmetrical, so the * 'forEncryption' is irrelevant. */ @@ -88,7 +88,7 @@ public void init(boolean forEncryption, CipherParameters params) CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties( this.getAlgorithmName(), 128, params, Utils.getPurpose(forEncryption))); - /** + /* * Initialize variables. */ workingIV = new byte[keyBytes.length]; @@ -226,7 +226,7 @@ private void setKey(byte[] keyBytes, byte[] ivBytes) workingKey = keyBytes; workingIV = ivBytes; - /** + /* * Load NFSR and LFSR */ int j = 0; diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/Grainv1Engine.java b/core/src/main/java/org/bouncycastle/crypto/engines/Grainv1Engine.java index 236cade826..4681130cd3 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/Grainv1Engine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/Grainv1Engine.java @@ -51,7 +51,7 @@ public String getAlgorithmName() public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { - /** + /* * Grain encryption and decryption is completely symmetrical, so the * 'forEncryption' is irrelevant. */ @@ -85,7 +85,7 @@ public void init(boolean forEncryption, CipherParameters params) "Grain v1 key must be 80 bits long"); } - /** + /* * Initialize variables. */ workingIV = new byte[keyBytes.length]; @@ -219,7 +219,7 @@ private void setKey(byte[] keyBytes, byte[] ivBytes) workingKey = keyBytes; workingIV = ivBytes; - /** + /* * Load NFSR and LFSR */ int j = 0; diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/HC128Engine.java b/core/src/main/java/org/bouncycastle/crypto/engines/HC128Engine.java index aab87a6e87..6da47d64ea 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/HC128Engine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/HC128Engine.java @@ -1,6 +1,10 @@ package org.bouncycastle.crypto.engines; -import org.bouncycastle.crypto.*; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.OutputLengthException; +import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.constraints.DefaultServiceProperties; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; @@ -115,6 +119,11 @@ private void init() throw new java.lang.IllegalArgumentException( "The key must be 128 bits long"); } + if (iv.length != 16) + { + throw new java.lang.IllegalArgumentException( + "The IV must be 128 bits long"); + } idx = 0; cnt = 0; @@ -170,7 +179,7 @@ public String getAlgorithmName() public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException { - CipherParameters keyParam = params; + CipherParameters keyParam; if (params instanceof ParametersWithIV) { @@ -179,7 +188,7 @@ public void init(boolean forEncryption, CipherParameters params) } else { - iv = new byte[0]; + throw new IllegalArgumentException("no IV passed"); } if (keyParam instanceof KeyParameter) diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/ISAPEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/ISAPEngine.java index b7be287f83..7d83c9cfa8 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/ISAPEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/ISAPEngine.java @@ -20,7 +20,6 @@ * ISAP AEAD v2 with reference to C Reference Impl from: https://github.com/isap-lwc/isap-code-package *

    */ - public class ISAPEngine implements AEADCipher { @@ -827,7 +826,7 @@ public void init(boolean forEncryption, CipherParameters params) CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties( this.getAlgorithmName(), 128, params, Utils.getPurpose(forEncryption))); - /** + /* * Initialize variables. */ npub = new byte[iv.length]; diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/PhotonBeetleEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/PhotonBeetleEngine.java index 50bfe99545..64f9219673 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/PhotonBeetleEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/PhotonBeetleEngine.java @@ -306,7 +306,7 @@ private void reset(boolean clearMac) private void PHOTON_Permutation() { - int i, j, k, l; + int i, j, k; for (i = 0; i < DSquare; i++) { state_2d[i >>> Dq][i & Dr] = (byte)(((state[i >> 1] & 0xFF) >>> (4 * (i & 1))) & 0xf); @@ -338,29 +338,25 @@ private void PHOTON_Permutation() { for (i = 0; i < D; i++) { - byte sum = 0; + int sum = 0; + for (k = 0; k < D; k++) { - int x = MixColMatrix[i][k], ret = 0, b = state_2d[k][j]; - for (l = 0; l < S; l++) - { - if (((b >>> l) & 1) != 0) - { - ret ^= x; - } - if (((x >>> S_1) & 1) != 0) - { - x <<= 1; - x ^= 0x3; - } - else - { - x <<= 1; - } - } - sum ^= ret & 15; + int x = MixColMatrix[i][k], b = state_2d[k][j]; + + sum ^= x * (b & 1); + sum ^= x * (b & 2); + sum ^= x * (b & 4); + sum ^= x * (b & 8); } - state[i] = sum; + + int t0 = sum >>> 4; + sum = (sum & 15) ^ t0 ^ (t0 << 1); + + int t1 = sum >>> 4; + sum = (sum & 15) ^ t1 ^ (t1 << 1); + + state[i] = (byte)sum; } for (i = 0; i < D; i++) { diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java index 4fe1fb6b8e..955c4cc3be 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java @@ -20,14 +20,15 @@ public class RFC3394WrapEngine implements Wrapper { - private BlockCipher engine; - private boolean wrapCipherMode; - private KeyParameter param; - private boolean forWrapping; + private static final byte[] DEFAULT_IV = { (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, + (byte)0xa6, (byte)0xa6 }; - private byte[] iv = { - (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, - (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6 }; + private final BlockCipher engine; + private final boolean wrapCipherMode; + private final byte[] iv = new byte[8]; + + private KeyParameter param = null; + private boolean forWrapping = true; /** * Create a RFC 3394 WrapEngine specifying the encrypt for wrapping, decrypt for unwrapping. @@ -65,15 +66,24 @@ public void init( if (param instanceof KeyParameter) { this.param = (KeyParameter)param; + System.arraycopy(DEFAULT_IV, 0, iv, 0, 8); } else if (param instanceof ParametersWithIV) { - this.iv = ((ParametersWithIV)param).getIV(); - this.param = (KeyParameter)((ParametersWithIV) param).getParameters(); - if (this.iv.length != 8) + ParametersWithIV withIV = (ParametersWithIV)param; + + byte[] iv = withIV.getIV(); + if (iv.length != 8) { throw new IllegalArgumentException("IV not equal to 8"); } + + this.param = (KeyParameter)withIV.getParameters(); + System.arraycopy(iv, 0, this.iv, 0, 8); + } + else + { + // TODO Throw an exception for bad parameters? } } @@ -209,9 +219,46 @@ public byte[] unwrap( } } - if (!Arrays.constantTimeAreEqual(a, iv)) + if (n != 1) { - throw new InvalidCipherTextException("checksum failed"); + if (!Arrays.constantTimeAreEqual(a, iv)) + { + throw new InvalidCipherTextException("checksum failed"); + } + } + else + { + // TODO: old (incorrect) backwards compatible unwrap - will be removed. + if (!Arrays.constantTimeAreEqual(a, iv)) + { + System.arraycopy(in, inOff, a, 0, iv.length); + System.arraycopy(in, inOff + iv.length, block, 0, inLen - iv.length); + + for (int j = 5; j >= 0; j--) + { + System.arraycopy(a, 0, buf, 0, iv.length); + System.arraycopy(block, 0, buf, iv.length, 8); + + int t = n * j + 1; + for (int k = 1; t != 0; k++) + { + byte v = (byte)t; + + buf[iv.length - k] ^= v; + + t >>>= 8; + } + + engine.processBlock(buf, 0, buf, 0); + System.arraycopy(buf, 0, a, 0, 8); + System.arraycopy(buf, 8, block, 0, 8); + } + + if (!Arrays.constantTimeAreEqual(a, iv)) + { + throw new InvalidCipherTextException("checksum failed"); + } + } } return block; diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/RFC5649WrapEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/RFC5649WrapEngine.java index 3537b08e57..f1f180e601 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/RFC5649WrapEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/RFC5649WrapEngine.java @@ -21,15 +21,14 @@ public class RFC5649WrapEngine implements Wrapper { - private BlockCipher engine; - private KeyParameter param; - private boolean forWrapping; - // The AIV as defined in the RFC - private byte[] highOrderIV = {(byte)0xa6, (byte)0x59, (byte)0x59, (byte)0xa6}; - private byte[] preIV = highOrderIV; + private static final byte[] DEFAULT_IV = {(byte)0xa6, (byte)0x59, (byte)0x59, (byte)0xa6}; + + private final BlockCipher engine; + private final byte[] preIV = new byte[4]; - private byte[] extractedAIV = null; + private KeyParameter param = null; + private boolean forWrapping = true; public RFC5649WrapEngine(BlockCipher engine) { @@ -48,16 +47,24 @@ public void init(boolean forWrapping, CipherParameters param) if (param instanceof KeyParameter) { this.param = (KeyParameter)param; - this.preIV = highOrderIV; + System.arraycopy(DEFAULT_IV, 0, preIV, 0, 4); } else if (param instanceof ParametersWithIV) { - this.preIV = ((ParametersWithIV)param).getIV(); - this.param = (KeyParameter)((ParametersWithIV)param).getParameters(); - if (this.preIV.length != 4) + ParametersWithIV withIV = (ParametersWithIV)param; + + byte[] iv = withIV.getIV(); + if (iv.length != 4) { throw new IllegalArgumentException("IV length not equal to 4"); } + + this.param = (KeyParameter)withIV.getParameters(); + System.arraycopy(iv, 0, this.preIV, 0, 4); + } + else + { + // TODO Throw an exception for bad parameters? } } @@ -95,14 +102,13 @@ public byte[] wrap(byte[] in, int inOff, int inLen) { throw new IllegalStateException("not set for wrapping"); } + byte[] iv = new byte[8]; - // MLI = size of key to be wrapped - byte[] mli = Pack.intToBigEndian(inLen); // copy in the fixed portion of the AIV - System.arraycopy(preIV, 0, iv, 0, preIV.length); - // copy in the MLI after the AIV - System.arraycopy(mli, 0, iv, preIV.length, mli.length); + System.arraycopy(preIV, 0, iv, 0, 4); + // copy in the MLI (size of key to be wrapped) after the AIV + Pack.intToBigEndian(inLen, iv, 4); // get the relevant plaintext to be wrapped byte[] relevantPlaintext = new byte[inLen]; @@ -120,7 +126,7 @@ public byte[] wrap(byte[] in, int inOff, int inLen) System.arraycopy(paddedPlaintext, 0, paddedPlainTextWithIV, iv.length, paddedPlaintext.length); engine.init(true, param); - for (int i = 0; i < paddedPlainTextWithIV.length; i += engine.getBlockSize()) + for (int i = 0, blockSize = engine.getBlockSize(); i < paddedPlainTextWithIV.length; i += blockSize) { engine.processBlock(paddedPlainTextWithIV, i, paddedPlainTextWithIV, i); } @@ -131,7 +137,7 @@ public byte[] wrap(byte[] in, int inOff, int inLen) { // otherwise, apply the RFC 3394 wrap to // the padded plaintext with the new IV - Wrapper wrapper = new RFC3394WrapEngine(engine); + RFC3394WrapEngine wrapper = new RFC3394WrapEngine(engine); ParametersWithIV paramsWithIV = new ParametersWithIV(param, iv); wrapper.init(true, paramsWithIV); return wrapper.wrap(paddedPlaintext, 0, paddedPlaintext.length); @@ -164,18 +170,19 @@ public byte[] unwrap(byte[] in, int inOff, int inLen) byte[] decrypted = new byte[inLen]; byte[] paddedPlaintext; + byte[] extractedAIV = new byte[8]; + if (n == 2) { // When there are exactly two 64-bit blocks of ciphertext, // they are decrypted as a single block using AES in ECB. engine.init(false, param); - for (int i = 0; i < relevantCiphertext.length; i += engine.getBlockSize()) + for (int i = 0, blockSize = engine.getBlockSize(); i < relevantCiphertext.length; i += blockSize) { engine.processBlock(relevantCiphertext, i, decrypted, i); } // extract the AIV - extractedAIV = new byte[8]; System.arraycopy(decrypted, 0, extractedAIV, 0, extractedAIV.length); paddedPlaintext = new byte[decrypted.length - extractedAIV.length]; System.arraycopy(decrypted, extractedAIV.length, paddedPlaintext, 0, paddedPlaintext.length); @@ -183,25 +190,20 @@ public byte[] unwrap(byte[] in, int inOff, int inLen) else { // Otherwise, unwrap as per RFC 3394 but don't check IV the same way - decrypted = rfc3394UnwrapNoIvCheck(in, inOff, inLen); + decrypted = rfc3394UnwrapNoIvCheck(in, inOff, inLen, extractedAIV); paddedPlaintext = decrypted; } // Decompose the extracted AIV to the fixed portion and the MLI byte[] extractedHighOrderAIV = new byte[4]; - byte[] mliBytes = new byte[4]; - System.arraycopy(extractedAIV, 0, extractedHighOrderAIV, 0, extractedHighOrderAIV.length); - System.arraycopy(extractedAIV, extractedHighOrderAIV.length, mliBytes, 0, mliBytes.length); - int mli = Pack.bigEndianToInt(mliBytes, 0); + System.arraycopy(extractedAIV, 0, extractedHighOrderAIV, 0, 4); + int mli = Pack.bigEndianToInt(extractedAIV, 4); + // Even if a check fails we still continue and check everything // else in order to avoid certain timing based side-channel attacks. - boolean isValid = true; // Check the fixed portion of the AIV - if (!Arrays.constantTimeAreEqual(extractedHighOrderAIV, preIV)) - { - isValid = false; - } + boolean isValid = Arrays.constantTimeAreEqual(extractedHighOrderAIV, preIV); // Check the MLI against the actual length int upperBound = paddedPlaintext.length; @@ -254,15 +256,13 @@ public byte[] unwrap(byte[] in, int inOff, int inLen) * @param inLen * @return Unwrapped data. */ - private byte[] rfc3394UnwrapNoIvCheck(byte[] in, int inOff, int inLen) + private byte[] rfc3394UnwrapNoIvCheck(byte[] in, int inOff, int inLen, byte[] extractedAIV) { - byte[] iv = new byte[8]; - byte[] block = new byte[inLen - iv.length]; - byte[] a = new byte[iv.length]; - byte[] buf = new byte[8 + iv.length]; + byte[] block = new byte[inLen - 8]; + byte[] buf = new byte[16]; - System.arraycopy(in, inOff, a, 0, iv.length); - System.arraycopy(in, inOff + iv.length, block, 0, inLen - iv.length); + System.arraycopy(in, inOff, buf, 0, 8); + System.arraycopy(in, inOff + 8, block, 0, inLen - 8); engine.init(false, param); @@ -273,29 +273,23 @@ private byte[] rfc3394UnwrapNoIvCheck(byte[] in, int inOff, int inLen) { for (int i = n; i >= 1; i--) { - System.arraycopy(a, 0, buf, 0, iv.length); - System.arraycopy(block, 8 * (i - 1), buf, iv.length, 8); + System.arraycopy(block, 8 * (i - 1), buf, 8, 8); int t = n * j + i; for (int k = 1; t != 0; k++) { - byte v = (byte)t; - - buf[iv.length - k] ^= v; - + buf[8 - k] ^= (byte)t; t >>>= 8; } engine.processBlock(buf, 0, buf, 0); - System.arraycopy(buf, 0, a, 0, 8); + System.arraycopy(buf, 8, block, 8 * (i - 1), 8); } } - // set the extracted AIV - extractedAIV = a; + System.arraycopy(buf, 0, extractedAIV, 0, 8); return block; } - } diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java index cc42899021..4ce1fccedd 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java @@ -30,40 +30,20 @@ public class RSABlindedEngine * @param forEncryption true if we are encrypting, false otherwise. * @param param the necessary RSA key parameters. */ - public void init( - boolean forEncryption, - CipherParameters param) + public void init(boolean forEncryption, CipherParameters parameters) { - core.init(forEncryption, param); - - if (param instanceof ParametersWithRandom) + SecureRandom providedRandom = null; + if (parameters instanceof ParametersWithRandom) { - ParametersWithRandom rParam = (ParametersWithRandom)param; - - this.key = (RSAKeyParameters)rParam.getParameters(); - - if (key instanceof RSAPrivateCrtKeyParameters) - { - this.random = rParam.getRandom(); - } - else - { - this.random = null; - } + ParametersWithRandom withRandom = (ParametersWithRandom)parameters; + providedRandom = withRandom.getRandom(); + parameters = withRandom.getParameters(); } - else - { - this.key = (RSAKeyParameters)param; - if (key instanceof RSAPrivateCrtKeyParameters) - { - this.random = CryptoServicesRegistrar.getSecureRandom(); - } - else - { - this.random = null; - } - } + core.init(forEncryption, parameters); + + this.key = (RSAKeyParameters)parameters; + this.random = initSecureRandom(key instanceof RSAPrivateCrtKeyParameters, providedRandom); } /** @@ -99,10 +79,7 @@ public int getOutputBlockSize() * @return the result of the RSA process. * @exception DataLengthException the input block is too large. */ - public byte[] processBlock( - byte[] in, - int inOff, - int inLen) + public byte[] processBlock(byte[] in, int inOff, int inLen) { if (key == null) { @@ -110,39 +87,36 @@ public byte[] processBlock( } BigInteger input = core.convertInput(in, inOff, inLen); + BigInteger result = processInput(input); + return core.convertOutput(result); + } - BigInteger result; + protected SecureRandom initSecureRandom(boolean needed, SecureRandom provided) + { + return needed ? CryptoServicesRegistrar.getSecureRandom(provided) : null; + } + + private BigInteger processInput(BigInteger input) + { if (key instanceof RSAPrivateCrtKeyParameters) { - RSAPrivateCrtKeyParameters k = (RSAPrivateCrtKeyParameters)key; + RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters)key; - BigInteger e = k.getPublicExponent(); + BigInteger e = crtKey.getPublicExponent(); if (e != null) // can't do blinding without a public exponent { - BigInteger m = k.getModulus(); + BigInteger m = crtKey.getModulus(); + BigInteger r = BigIntegers.createRandomInRange(ONE, m.subtract(ONE), random); + BigInteger blind = r.modPow(e, m); + BigInteger unblind = BigIntegers.modOddInverse(m, r); - BigInteger blindedInput = r.modPow(e, m).multiply(input).mod(m); + BigInteger blindedInput = blind.multiply(input).mod(m); BigInteger blindedResult = core.processBlock(blindedInput); - - BigInteger rInv = BigIntegers.modOddInverse(m, r); - result = blindedResult.multiply(rInv).mod(m); - // defence against Arjen Lenstra’s CRT attack - if (!input.equals(result.modPow(e, m))) - { - throw new IllegalStateException("RSA engine faulty decryption/signing detected"); - } - } - else - { - result = core.processBlock(input); + return unblind.multiply(blindedResult).mod(m); } } - else - { - result = core.processBlock(input); - } - return core.convertOutput(result); + return core.processBlock(input); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/RSACoreEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/RSACoreEngine.java index 15e229c52a..cfc0913212 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/RSACoreEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/RSACoreEngine.java @@ -27,24 +27,20 @@ class RSACoreEngine * @param forEncryption true if we are encrypting, false otherwise. * @param param the necessary RSA key parameters. */ - public void init( - boolean forEncryption, - CipherParameters param) + public void init(boolean forEncryption, CipherParameters parameters) { - if (param instanceof ParametersWithRandom) + if (parameters instanceof ParametersWithRandom) { - ParametersWithRandom rParam = (ParametersWithRandom)param; - - key = (RSAKeyParameters)rParam.getParameters(); - } - else - { - key = (RSAKeyParameters)param; + ParametersWithRandom withRandom = (ParametersWithRandom)parameters; + parameters = withRandom.getParameters(); } this.forEncryption = forEncryption; + this.key = (RSAKeyParameters)parameters; - CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("RSA", ConstraintUtils.bitsOfSecurityFor(key.getModulus()), key, getPurpose(key.isPrivate(), forEncryption))); + int bitsOfSecurity = ConstraintUtils.bitsOfSecurityFor(key.getModulus()); + CryptoServicePurpose purpose = getPurpose(key.isPrivate(), forEncryption); + CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("RSA", bitsOfSecurity, key, purpose)); } /** @@ -185,36 +181,43 @@ public BigInteger processBlock(BigInteger input) // RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters)key; - BigInteger p = crtKey.getP(); - BigInteger q = crtKey.getQ(); - BigInteger dP = crtKey.getDP(); - BigInteger dQ = crtKey.getDQ(); - BigInteger qInv = crtKey.getQInv(); + BigInteger e = crtKey.getPublicExponent(); + if (e != null) // can't apply fault-attack countermeasure without public exponent + { + BigInteger p = crtKey.getP(); + BigInteger q = crtKey.getQ(); + BigInteger dP = crtKey.getDP(); + BigInteger dQ = crtKey.getDQ(); + BigInteger qInv = crtKey.getQInv(); - BigInteger mP, mQ, h, m; + BigInteger mP, mQ, h, m; - // mP = ((input mod p) ^ dP)) mod p - mP = (input.remainder(p)).modPow(dP, p); + // mP = ((input mod p) ^ dP)) mod p + mP = (input.remainder(p)).modPow(dP, p); - // mQ = ((input mod q) ^ dQ)) mod q - mQ = (input.remainder(q)).modPow(dQ, q); + // mQ = ((input mod q) ^ dQ)) mod q + mQ = (input.remainder(q)).modPow(dQ, q); - // h = qInv * (mP - mQ) mod p - h = mP.subtract(mQ); - h = h.multiply(qInv); - h = h.mod(p); // mod (in Java) returns the positive residual + // h = qInv * (mP - mQ) mod p + h = mP.subtract(mQ); + h = h.multiply(qInv); + h = h.mod(p); // mod (in Java) returns the positive residual - // m = h * q + mQ - m = h.multiply(q); - m = m.add(mQ); + // m = h * q + mQ + m = h.multiply(q).add(mQ); - return m; - } - else - { - return input.modPow( - key.getExponent(), key.getModulus()); + // defence against Arjen Lenstra’s CRT attack + BigInteger check = m.modPow(e, crtKey.getModulus()); + if (!check.equals(input)) + { + throw new IllegalStateException("RSA engine faulty decryption/signing detected"); + } + + return m; + } } + + return input.modPow(key.getExponent(), key.getModulus()); } private CryptoServicePurpose getPurpose(boolean isPrivate, boolean forEncryption) diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/SM2Engine.java b/core/src/main/java/org/bouncycastle/crypto/engines/SM2Engine.java index e519a04671..8ac88aede1 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/SM2Engine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/SM2Engine.java @@ -22,6 +22,7 @@ import org.bouncycastle.math.ec.FixedPointCombMultiplier; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; +import org.bouncycastle.util.Bytes; import org.bouncycastle.util.Memoable; import org.bouncycastle.util.Pack; @@ -94,7 +95,7 @@ public void init(boolean forEncryption, CipherParameters param) ecParams = ecKey.getParameters(); } - curveLength = (ecParams.getCurve().getFieldSize() + 7) / 8; + curveLength = ecParams.getCurve().getFieldElementEncodingLength(); CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("SM2", ConstraintUtils.bitsOfSecurityFor(ecParams.getCurve()), ecKey, Utils.getPurpose(forEncryption))); } @@ -288,19 +289,11 @@ private void kdf(Digest digest, ECPoint c1, byte[] encData) digest.doFinal(buf, 0); int xorLen = Math.min(digestSize, encData.length - off); - xor(encData, buf, off, xorLen); + Bytes.xorTo(xorLen, buf, 0, encData, off); off += xorLen; } } - private void xor(byte[] data, byte[] kdfOut, int dOff, int dRemaining) - { - for (int i = 0; i != dRemaining; i++) - { - data[dOff + i] ^= kdfOut[i]; - } - } - private BigInteger nextK() { int qBitLength = ecParams.getN().bitLength(); diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/SparkleEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/SparkleEngine.java index 7c0cd29b7d..a1caff26a7 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/SparkleEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/SparkleEngine.java @@ -1,16 +1,18 @@ package org.bouncycastle.crypto.engines; -import java.io.ByteArrayOutputStream; - import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.constraints.DefaultServiceProperties; +import org.bouncycastle.crypto.digests.SparkleDigest; import org.bouncycastle.crypto.modes.AEADCipher; +import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Integers; import org.bouncycastle.util.Pack; /** @@ -29,17 +31,35 @@ public enum SparkleParameters SCHWAEMM256_256 } + private enum State + { + Uninitialized, + EncInit, + EncAad, + EncData, + EncFinal, + DecInit, + DecAad, + DecData, + DecFinal, + } + + private static final int[] RCON = { 0xB7E15162, 0xBF715880, 0x38B4DA56, 0x324E7738, 0xBB1185EB, 0x4F7C7B57, + 0xCFBFA1C8, 0xC2B3293D }; + private String algorithmName; - private boolean forEncryption; private final int[] state; private final int[] k; private final int[] npub; private byte[] tag; - private boolean initialised; private boolean encrypted; - private boolean aadFinished; - private final ByteArrayOutputStream aadData = new ByteArrayOutputStream(); - private final ByteArrayOutputStream message = new ByteArrayOutputStream(); + private State m_state = State.Uninitialized; + private byte[] initialAssociatedText; + + private final int m_bufferSizeDecrypt; + private final byte[] m_buf; + private int m_bufPos = 0; + private final int SCHWAEMM_KEY_LEN; private final int SCHWAEMM_NONCE_LEN; private final int SPARKLE_STEPS_SLIM; @@ -48,11 +68,10 @@ public enum SparkleParameters private final int KEY_BYTES; private final int TAG_WORDS; private final int TAG_BYTES; - private final int STATE_BRANS; private final int STATE_WORDS; private final int RATE_WORDS; private final int RATE_BYTES; - private final int CAP_WORDS; + private final int CAP_MASK; private final int _A0; private final int _A1; private final int _M2; @@ -112,12 +131,12 @@ public SparkleEngine(SparkleParameters sparkleParameters) KEY_BYTES = SCHWAEMM_KEY_LEN >>> 3; TAG_WORDS = SCHWAEMM_TAG_LEN >>> 5; TAG_BYTES = SCHWAEMM_TAG_LEN >>> 3; - STATE_BRANS = SPARKLE_STATE >>> 6; STATE_WORDS = SPARKLE_STATE >>> 5; RATE_WORDS = SCHWAEMM_NONCE_LEN >>> 5; RATE_BYTES = SCHWAEMM_NONCE_LEN >>> 3; int CAP_BRANS = SPARKLE_CAPACITY >>> 6; - CAP_WORDS = SPARKLE_CAPACITY >>> 5; + int CAP_WORDS = SPARKLE_CAPACITY >>> 5; + CAP_MASK = RATE_WORDS > CAP_WORDS ? CAP_WORDS - 1 : -1; _A0 = ((((1 << CAP_BRANS))) << 24); _A1 = (((1 ^ (1 << CAP_BRANS))) << 24); _M2 = (((2 ^ (1 << CAP_BRANS))) << 24); @@ -125,367 +144,318 @@ public SparkleEngine(SparkleParameters sparkleParameters) state = new int[STATE_WORDS]; k = new int[KEY_WORDS]; npub = new int[RATE_WORDS]; - initialised = false; - } - private int ROT(int x, int n) - { - return (((x) >>> n) | ((x) << (32 - n))); + m_bufferSizeDecrypt = RATE_BYTES + TAG_BYTES; + m_buf = new byte[m_bufferSizeDecrypt]; + + // Relied on by processBytes method for decryption +// assert RATE_BYTES >= TAG_BYTES; } - private int ELL(int x) + public int getKeyBytesSize() { - return ROT(((x) ^ ((x) << 16)), 16); + return KEY_BYTES; } - private static final int[] RCON = {0xB7E15162, 0xBF715880, 0x38B4DA56, 0x324E7738, 0xBB1185EB, 0x4F7C7B57, - 0xCFBFA1C8, 0xC2B3293D}; - - void sparkle_opt(int[] state, int brans, int steps) + public int getIVBytesSize() { - int i, j, rc, tmpx, tmpy, x0, y0; - for (i = 0; i < steps; i++) - { - // Add round ant - state[1] ^= RCON[i & 7]; - state[3] ^= i; - // ARXBOX layer - for (j = 0; j < 2 * brans; j += 2) - { - rc = RCON[j >>> 1]; - state[j] += ROT(state[j + 1], 31); - state[j + 1] ^= ROT(state[j], 24); - state[j] ^= rc; - state[j] += ROT(state[j + 1], 17); - state[j + 1] ^= ROT(state[j], 17); - state[j] ^= rc; - state[j] += state[j + 1]; - state[j + 1] ^= ROT(state[j], 31); - state[j] ^= rc; - state[j] += ROT(state[j + 1], 24); - state[j + 1] ^= ROT(state[j], 16); - state[j] ^= rc; - } - // Linear layer - tmpx = x0 = state[0]; - tmpy = y0 = state[1]; - for (j = 2; j < brans; j += 2) - { - tmpx ^= state[j]; - tmpy ^= state[j + 1]; - } - tmpx = ELL(tmpx); - tmpy = ELL(tmpy); - for (j = 2; j < brans; j += 2) - { - state[j - 2] = state[j + brans] ^ state[j] ^ tmpy; - state[j + brans] = state[j]; - state[j - 1] = state[j + brans + 1] ^ state[j + 1] ^ tmpx; - state[j + brans + 1] = state[j + 1]; - } - state[brans - 2] = state[brans] ^ x0 ^ tmpy; - state[brans] = x0; - state[brans - 1] = state[brans + 1] ^ y0 ^ tmpx; - state[brans + 1] = y0; - } + return RATE_BYTES; } - private int CAP_INDEX(int i) + public String getAlgorithmName() { - if (RATE_WORDS > CAP_WORDS) - { - return i & (CAP_WORDS - 1); - } - return i; + return algorithmName; } - // The ProcessAssocData function absorbs the associated data, which becomes - // only authenticated but not encrypted, into the state (in blocks of size - // RATE_BYTES). Note that this function MUST NOT be called when the length of - // the associated data is 0. - void ProcessAssocData(int[] state) + public void init(boolean forEncryption, CipherParameters params) + throws IllegalArgumentException { - int inlen = aadData.size(); - if (aadFinished || inlen == 0) - { - return; - } - aadFinished = true; - byte[] in = aadData.toByteArray(); - // Main Authentication Loop - int inOff = 0, tmp, i, j; - int[] in32 = Pack.littleEndianToInt(in, inOff, in.length >>> 2); - while (inlen > RATE_BYTES) - { - // combined Rho and rate-whitening operation - // Rho and rate-whitening for the authentication of associated data. The third - // parameter indicates whether the uint8_t-pointer 'in' is properly aligned to - // permit casting to a int-pointer. If this is the case then array 'in' is - // processed directly, otherwise it is first copied to an aligned buffer. - for (i = 0, j = RATE_WORDS / 2; i < RATE_WORDS / 2; i++, j++) - { - tmp = state[i]; - state[i] = state[j] ^ in32[i + (inOff >> 2)] ^ state[RATE_WORDS + i]; - state[j] ^= tmp ^ in32[j + (inOff >> 2)] ^ state[RATE_WORDS + CAP_INDEX(j)]; - } - // execute SPARKLE with slim number of steps - sparkle_opt(state, STATE_BRANS, SPARKLE_STEPS_SLIM); - inlen -= RATE_BYTES; - inOff += RATE_BYTES; - } - // Authentication of Last Block - // addition of ant A0 or A1 to the state - state[STATE_WORDS - 1] ^= ((inlen < RATE_BYTES) ? _A0 : _A1); - // combined Rho and rate-whitening (incl. padding) - // Rho and rate-whitening for the authentication of the last associated-data - // block. Since this last block may require padding, it is always copied to a buffer. - int[] buffer = new int[RATE_WORDS]; - for (i = 0; i < inlen; ++i) + KeyParameter key = null; + byte[] iv; + + if (params instanceof AEADParameters) { - buffer[i >>> 2] |= in[inOff++] << ((i & 3) << 3); - } - if (inlen < RATE_BYTES) - { // padding - buffer[i >>> 2] |= 0x80 << ((i & 3) << 3); + AEADParameters aeadParameters = (AEADParameters)params; + key = aeadParameters.getKey(); + iv = aeadParameters.getNonce(); + initialAssociatedText = aeadParameters.getAssociatedText(); + + int macSizeBits = aeadParameters.getMacSize(); + if (macSizeBits != TAG_BYTES * 8) + throw new IllegalArgumentException("Invalid value for MAC size: " + macSizeBits); } - for (i = 0, j = RATE_WORDS / 2; i < RATE_WORDS / 2; i++, j++) + else if (params instanceof ParametersWithIV) { - tmp = state[i]; - state[i] = state[j] ^ buffer[i] ^ state[RATE_WORDS + i]; - state[j] ^= tmp ^ buffer[j] ^ state[RATE_WORDS + CAP_INDEX(j)]; - } - // execute SPARKLE with big number of steps - sparkle_opt(state, STATE_BRANS, SPARKLE_STEPS_BIG); - } - - // The ProcessPlainText function encrypts the plaintext (input blocks of size - // RATE_BYTES) and generates the respective ciphertext. The uint8_t-array 'input' - // contains the plaintext and the ciphertext is written to uint8_t-array 'output' - // ('input' and 'output' can be the same array, i.e. they can have the same start - // address). Note that this function MUST NOT be called when the length of the - // plaintext is 0. - private int ProcessPlainText(int[] state, byte[] output, byte[] input, int inOff, int inlen) - { - // Main Encryption Loop - int outOff = 0, tmp1, tmp2, i, j; - int[] in32 = Pack.littleEndianToInt(input, inOff, input.length >>> 2); - int[] out32 = new int[output.length >>> 2]; - int rv = 0; - while (inlen > RATE_BYTES) - { - // combined Rho and rate-whitening operation - // Rho and rate-whitening for the encryption of plaintext. The third parameter - // indicates whether the uint8_t-pointers 'input' and 'output' are properly aligned - // to permit casting to int-pointers. If this is the case then array 'input' - // and 'output' are processed directly, otherwise 'input' is copied to an aligned buffer. - for (i = 0, j = RATE_WORDS / 2; i < RATE_WORDS / 2; i++, j++) + ParametersWithIV withIV = (ParametersWithIV)params; + CipherParameters ivParameters = withIV.getParameters(); + if (ivParameters instanceof KeyParameter) { - tmp1 = state[i]; - tmp2 = state[j]; - if (forEncryption) - { - state[i] = state[j] ^ in32[i + (inOff >> 2)] ^ state[RATE_WORDS + i]; - state[j] ^= tmp1 ^ in32[j + (inOff >> 2)] ^ state[RATE_WORDS + CAP_INDEX(j)]; - } - else - { - state[i] ^= state[j] ^ in32[i + (inOff >> 2)] ^ state[RATE_WORDS + i]; - state[j] = tmp1 ^ in32[j + (inOff >> 2)] ^ state[RATE_WORDS + CAP_INDEX(j)]; - } - out32[i] = in32[i] ^ tmp1; - out32[j] = in32[j] ^ tmp2; + key = (KeyParameter)ivParameters; } - Pack.intToLittleEndian(out32, 0, RATE_WORDS, output, outOff); - // execute SPARKLE with slim number of steps - sparkle_opt(state, STATE_BRANS, SPARKLE_STEPS_SLIM); - inlen -= RATE_BYTES; - outOff += RATE_BYTES; - inOff += RATE_BYTES; - rv += RATE_BYTES; - encrypted = true; + iv = withIV.getIV(); + initialAssociatedText = null; } - return rv; - } - - @Override - public void init(boolean forEncryption, CipherParameters params) - throws IllegalArgumentException - { - this.forEncryption = forEncryption; - if (!(params instanceof ParametersWithIV)) + else { - throw new IllegalArgumentException(algorithmName + " init parameters must include an IV"); + throw new IllegalArgumentException("invalid parameters passed to Sparkle"); } - ParametersWithIV ivParams = (ParametersWithIV)params; - byte[] iv = ivParams.getIV(); - - if (iv == null || iv.length != RATE_BYTES) + if (key == null) { - throw new IllegalArgumentException(algorithmName + " requires exactly " + RATE_BYTES + " bytes of IV"); + throw new IllegalArgumentException("Sparkle init parameters must include a key"); } - Pack.littleEndianToInt(iv, 0, npub, 0, RATE_WORDS); - if (!(ivParams.getParameters() instanceof KeyParameter)) + int expectedKeyLength = KEY_WORDS * 4; + if (expectedKeyLength != key.getKeyLength()) { - throw new IllegalArgumentException(algorithmName + " init parameters must include a key"); + throw new IllegalArgumentException(algorithmName + " requires exactly " + expectedKeyLength + " bytes of key"); } - KeyParameter key = (KeyParameter)ivParams.getParameters(); - byte[] key8 = key.getKey(); - if (key8.length != KEY_BYTES) + int expectedIVLength = RATE_WORDS * 4; + if (iv == null || expectedIVLength != iv.length) { - throw new IllegalArgumentException(algorithmName + " key must be " + KEY_BYTES + " bits long"); + throw new IllegalArgumentException(algorithmName + " requires exactly " + expectedIVLength + " bytes of IV"); } - Pack.littleEndianToInt(key8, 0, k, 0, KEY_WORDS); + + Pack.littleEndianToInt(key.getKey(), 0, k); + Pack.littleEndianToInt(iv, 0, npub); CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties( this.getAlgorithmName(), 128, params, Utils.getPurpose(forEncryption))); - initialised = true; + + m_state = forEncryption ? State.EncInit : State.DecInit; + reset(); } - @Override - public String getAlgorithmName() + public void processAADByte(byte in) { - return algorithmName; - } + checkAAD(); - @Override - public void processAADByte(byte input) - { - if (encrypted) + if (m_bufPos == RATE_BYTES) { - throw new IllegalArgumentException(algorithmName + ": AAD cannot be added after reading a full block(" + - getBlockSize() + " bytes) of input for " + (forEncryption ? "encryption" : "decryption")); + processBufferAAD(m_buf, 0); + m_bufPos = 0; } - aadData.write(input); + + m_buf[m_bufPos++] = in; } - @Override - public void processAADBytes(byte[] input, int inOff, int len) + public void processAADBytes(byte[] in, int inOff, int len) { - if (encrypted) + if (inOff > in.length - len) + { + throw new DataLengthException("input buffer too short"); + } + + // Don't enter AAD state until we actually get input + if (len <= 0) + return; + + checkAAD(); + + if (m_bufPos > 0) { - throw new IllegalArgumentException(algorithmName + ": AAD cannot be added after reading a full block(" + - getBlockSize() + " bytes) of input for " + (forEncryption ? "encryption" : "decryption")); + int available = RATE_BYTES - m_bufPos; + if (len <= available) + { + System.arraycopy(in, inOff, m_buf, m_bufPos, len); + m_bufPos += len; + return; + } + + System.arraycopy(in, inOff, m_buf, m_bufPos, available); + inOff += available; + len -= available; + + processBufferAAD(m_buf, 0); + //m_bufPos = 0; } - if (inOff + len > input.length) + + while (len > RATE_BYTES) { - throw new DataLengthException(algorithmName + " input buffer too short"); + processBufferAAD(in, inOff); + inOff += RATE_BYTES; + len -= RATE_BYTES; } - aadData.write(input, inOff, len); + + System.arraycopy(in, inOff, m_buf, 0, len); + m_bufPos = len; } - @Override - public int processByte(byte input, byte[] output, int outOff) + public int processByte(byte in, byte[] out, int outOff) throws DataLengthException { - return processBytes(new byte[]{input}, 0, 1, output, outOff); + return processBytes(new byte[]{ in }, 0, 1, out, outOff); } - @Override - public int processBytes(byte[] input, int inOff, int len, byte[] output, int outOff) + public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException { - if (!initialised) + if (inOff > in.length - len) { - throw new IllegalArgumentException(algorithmName + " Need call init function before encryption/decryption"); + throw new DataLengthException("input buffer too short"); } - if (inOff + len > input.length) + + boolean forEncryption = checkData(); + + int resultLength = 0; + + if (forEncryption) { - throw new DataLengthException(algorithmName + " input buffer too short"); + if (m_bufPos > 0) + { + int available = RATE_BYTES - m_bufPos; + if (len <= available) + { + System.arraycopy(in, inOff, m_buf, m_bufPos, len); + m_bufPos += len; + return 0; + } + + System.arraycopy(in, inOff, m_buf, m_bufPos, available); + inOff += available; + len -= available; + + processBufferEncrypt(m_buf, 0, out, outOff); + resultLength = RATE_BYTES; + //m_bufPos = 0; + } + + while (len > RATE_BYTES) + { + processBufferEncrypt(in, inOff, out, outOff + resultLength); + inOff += RATE_BYTES; + len -= RATE_BYTES; + resultLength += RATE_BYTES; + } } - message.write(input, inOff, len); - len = 0; - if ((forEncryption && message.size() > getBlockSize()) || - (!forEncryption && message.size() - TAG_BYTES > getBlockSize())) + else { - len = (message.size() - (forEncryption ? 0 : TAG_BYTES)); - if (len / RATE_BYTES * RATE_BYTES + outOff > output.length) + int available = m_bufferSizeDecrypt - m_bufPos; + if (len <= available) { - throw new OutputLengthException(algorithmName + " output buffer is too short"); + System.arraycopy(in, inOff, m_buf, m_bufPos, len); + m_bufPos += len; + return 0; + } + + if (m_bufPos > RATE_BYTES) + { + processBufferDecrypt(m_buf, 0, out, outOff); + m_bufPos -= RATE_BYTES; + System.arraycopy(m_buf, RATE_BYTES, m_buf, 0, m_bufPos); + resultLength = RATE_BYTES; + + available += RATE_BYTES; + if (len <= available) + { + System.arraycopy(in, inOff, m_buf, m_bufPos, len); + m_bufPos += len; + return resultLength; + } } - byte[] m = message.toByteArray(); - ProcessAssocData(state); - if (len != 0) + + available = RATE_BYTES - m_bufPos; + System.arraycopy(in, inOff, m_buf, m_bufPos, available); + inOff += available; + len -= available; + processBufferDecrypt(m_buf, 0, out, outOff + resultLength); + resultLength += RATE_BYTES; + //m_bufPos = 0; + + while (len > m_bufferSizeDecrypt) { - len = ProcessPlainText(state, output, m, 0, len); + processBufferDecrypt(in, inOff, out, outOff + resultLength); + inOff += RATE_BYTES; + len -= RATE_BYTES; + resultLength += RATE_BYTES; } - message.reset(); - message.write(m, len, m.length - len); } - return len; + + System.arraycopy(in, inOff, m_buf, 0, len); + m_bufPos = len; + + return resultLength; } - @Override - public int doFinal(byte[] output, int outOff) + public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException { - if (!initialised) + boolean forEncryption = checkData(); + + int resultLength; + if (forEncryption) { - throw new IllegalArgumentException(algorithmName + " needs call init function before dofinal"); + resultLength = m_bufPos + TAG_BYTES; } - int inlen = message.size() - (forEncryption ? 0 : TAG_BYTES); - if ((forEncryption && inlen + TAG_BYTES + outOff > output.length) || - (!forEncryption && inlen + outOff > output.length)) + else { - throw new OutputLengthException("output buffer is too short"); + if (m_bufPos < TAG_BYTES) + throw new InvalidCipherTextException("data too short"); + + m_bufPos -= TAG_BYTES; + + resultLength = m_bufPos; } - ProcessAssocData(state); - int i, j, tmp1, tmp2; - byte[] input = message.toByteArray(); - int inOff = 0; - if (encrypted || inlen != 0) + + if (outOff > out.length - resultLength) + { + throw new OutputLengthException("output buffer too short"); + } + + if (encrypted || m_bufPos > 0) { // Encryption of Last Block // addition of ant M2 or M3 to the state - state[STATE_WORDS - 1] ^= ((inlen < RATE_BYTES) ? _M2 : _M3); + state[STATE_WORDS - 1] ^= ((m_bufPos < RATE_BYTES) ? _M2 : _M3); // combined Rho and rate-whitening (incl. padding) // Rho and rate-whitening for the encryption of the last plaintext block. Since // this last block may require padding, it is always copied to a buffer. int[] buffer = new int[RATE_WORDS]; - for (i = 0; i < inlen; ++i) + for (int i = 0; i < m_bufPos; ++i) { - buffer[i >>> 2] |= (input[inOff++] & 0xff) << ((i & 3) << 3); + buffer[i >>> 2] |= (m_buf[i] & 0xFF) << ((i & 3) << 3); } - if (inlen < RATE_BYTES) + if (m_bufPos < RATE_BYTES) { if (!forEncryption) { - int tmp = (i & 3) << 3; - buffer[i >>> 2] |= (state[i >>> 2] >>> tmp) << tmp; - tmp = (i >>> 2) + 1; + int tmp = (m_bufPos & 3) << 3; + buffer[m_bufPos >>> 2] |= (state[m_bufPos >>> 2] >>> tmp) << tmp; + tmp = (m_bufPos >>> 2) + 1; System.arraycopy(state, tmp, buffer, tmp, RATE_WORDS - tmp); } - buffer[i >>> 2] ^= 0x80 << ((i & 3) << 3); + buffer[m_bufPos >>> 2] ^= 0x80 << ((m_bufPos & 3) << 3); } - for (i = 0, j = RATE_WORDS / 2; i < RATE_WORDS / 2; i++, j++) + for (int i = 0; i < RATE_WORDS / 2; ++i) { - tmp1 = state[i]; - tmp2 = state[j]; + int j = i + RATE_WORDS /2; + + int s_i = state[i]; + int s_j = state[j]; if (forEncryption) { - state[i] = state[j] ^ buffer[i] ^ state[RATE_WORDS + i]; - state[j] ^= tmp1 ^ buffer[j] ^ state[RATE_WORDS + CAP_INDEX(j)]; + state[i] = s_j ^ buffer[i] ^ state[RATE_WORDS + i]; + state[j] = s_i ^ s_j ^ buffer[j] ^ state[RATE_WORDS + (j & CAP_MASK)]; } else { - state[i] ^= state[j] ^ buffer[i] ^ state[RATE_WORDS + i]; - state[j] = tmp1 ^ buffer[j] ^ state[RATE_WORDS + CAP_INDEX(j)]; + state[i] = s_i ^ s_j ^ buffer[i] ^ state[RATE_WORDS + i]; + state[j] = s_i ^ buffer[j] ^ state[RATE_WORDS + (j & CAP_MASK)]; } - buffer[i] ^= tmp1; - buffer[j] ^= tmp2; + buffer[i] ^= s_i; + buffer[j] ^= s_j; } - for (i = 0; i < inlen; ++i) + for (int i = 0; i < m_bufPos; ++i) { - output[outOff++] = (byte)(buffer[i >>> 2] >>> ((i & 3) << 3)); + out[outOff++] = (byte)(buffer[i >>> 2] >>> ((i & 3) << 3)); } // execute SPARKLE with big number of steps - sparkle_opt(state, STATE_BRANS, SPARKLE_STEPS_BIG); + sparkle_opt(state, SPARKLE_STEPS_BIG); } // add key to the capacity-part of the state - for (i = 0; i < KEY_WORDS; i++) + for (int i = 0; i < KEY_WORDS; i++) { state[RATE_WORDS + i] ^= k[i]; } @@ -493,49 +463,252 @@ public int doFinal(byte[] output, int outOff) Pack.intToLittleEndian(state, RATE_WORDS, TAG_WORDS, tag, 0); if (forEncryption) { - System.arraycopy(tag, 0, output, outOff, TAG_BYTES); - inlen += TAG_BYTES; + System.arraycopy(tag, 0, out, outOff, TAG_BYTES); } else { - for (i = 0; i < TAG_BYTES; ++i) + if (!Arrays.constantTimeAreEqual(TAG_BYTES, tag, 0, m_buf, m_bufPos)) { - if (tag[i] != input[inlen + i]) - { - throw new IllegalArgumentException(algorithmName + " mac does not match"); - } + throw new InvalidCipherTextException(algorithmName + " mac does not match"); } } - reset(false); - return inlen; + reset(!forEncryption); + return resultLength; } - @Override public byte[] getMac() { return tag; } - @Override public int getUpdateOutputSize(int len) { - return len; + // The -1 is to account for the lazy processing of a full buffer + int total = Math.max(0, len) - 1; + + switch (m_state) + { + case DecInit: + case DecAad: + total = Math.max(0, total - TAG_BYTES); + break; + case DecData: + case DecFinal: + total = Math.max(0, total + m_bufPos - TAG_BYTES); + break; + case EncData: + case EncFinal: + total = Math.max(0, total + m_bufPos); + break; + default: + break; + } + + return total - total % RATE_BYTES; } - @Override public int getOutputSize(int len) { - return len + TAG_BYTES; + int total = Math.max(0, len); + + switch (m_state) + { + case DecInit: + case DecAad: + return Math.max(0, total - TAG_BYTES); + case DecData: + case DecFinal: + return Math.max(0, total + m_bufPos - TAG_BYTES); + case EncData: + case EncFinal: + return total + m_bufPos + TAG_BYTES; + default: + return total + TAG_BYTES; + } } - @Override public void reset() { - if (!initialised) + reset(true); + } + + private void checkAAD() + { + switch (m_state) { - throw new IllegalArgumentException(algorithmName + " needs call init function before reset"); + case DecInit: + m_state = State.DecAad; + break; + case EncInit: + m_state = State.EncAad; + break; + case DecAad: + case EncAad: + break; + case EncFinal: + throw new IllegalStateException(getAlgorithmName() + " cannot be reused for encryption"); + default: + throw new IllegalStateException(getAlgorithmName() + " needs to be initialized"); + } + } + + private boolean checkData() + { + switch (m_state) + { + case DecInit: + case DecAad: + finishAAD(State.DecData); + return false; + case EncInit: + case EncAad: + finishAAD(State.EncData); + return true; + case DecData: + return false; + case EncData: + return true; + case EncFinal: + throw new IllegalStateException(getAlgorithmName() + " cannot be reused for encryption"); + default: + throw new IllegalStateException(getAlgorithmName() + " needs to be initialized"); } - reset(true); + } + + private void finishAAD(State nextState) + { + // State indicates whether we ever received AAD + switch (m_state) + { + case DecAad: + case EncAad: + { + processFinalAAD(); + break; + } + default: + break; + } + + m_bufPos = 0; + m_state = nextState; + } + + private void processBufferAAD(byte[] buffer, int bufOff) + { + for (int i = 0; i < RATE_WORDS / 2; ++i) + { + int j = i + (RATE_WORDS / 2); + + int s_i = state[i]; + int s_j = state[j]; + + int d_i = Pack.littleEndianToInt(buffer, bufOff + (i * 4)); + int d_j = Pack.littleEndianToInt(buffer, bufOff + (j * 4)); + + state[i] = s_j ^ d_i ^ state[RATE_WORDS + i]; + state[j] = s_i ^ s_j ^ d_j ^ state[RATE_WORDS + (j & CAP_MASK)]; + } + + sparkle_opt(state, SPARKLE_STEPS_SLIM); + } + + private void processBufferDecrypt(byte[] buffer, int bufOff, byte[] output, int outOff) + { +// assert bufOff <= buffer.length - RATE_BYTES; + + if (outOff > output.length - RATE_BYTES) + { + throw new OutputLengthException("output buffer too short"); + } + + for (int i = 0; i < RATE_WORDS / 2; ++i) + { + int j = i + (RATE_WORDS / 2); + + int s_i = state[i]; + int s_j = state[j]; + + int d_i = Pack.littleEndianToInt(buffer, bufOff + (i * 4)); + int d_j = Pack.littleEndianToInt(buffer, bufOff + (j * 4)); + + state[i] = s_i ^ s_j ^ d_i ^ state[RATE_WORDS + i]; + state[j] = s_i ^ d_j ^ state[RATE_WORDS + (j & CAP_MASK)]; + + Pack.intToLittleEndian(d_i ^ s_i, output, outOff + (i * 4)); + Pack.intToLittleEndian(d_j ^ s_j, output, outOff + (j * 4)); + } + + sparkle_opt(state, SPARKLE_STEPS_SLIM); + + encrypted = true; + } + + private void processBufferEncrypt(byte[] buffer, int bufOff, byte[] output, int outOff) + { +// assert bufOff <= buffer.length - RATE_BYTES; + + if (outOff > output.length - RATE_BYTES) + { + throw new OutputLengthException("output buffer too short"); + } + + for (int i = 0; i < RATE_WORDS / 2; ++i) + { + int j = i + (RATE_WORDS / 2); + + int s_i = state[i]; + int s_j = state[j]; + + int d_i = Pack.littleEndianToInt(buffer, bufOff + (i * 4)); + int d_j = Pack.littleEndianToInt(buffer, bufOff + (j * 4)); + + state[i] = s_j ^ d_i ^ state[RATE_WORDS + i]; + state[j] = s_i ^ s_j ^ d_j ^ state[RATE_WORDS + (j & CAP_MASK)]; + + Pack.intToLittleEndian(d_i ^ s_i, output, outOff + (i * 4)); + Pack.intToLittleEndian(d_j ^ s_j, output, outOff + (j * 4)); + } + + sparkle_opt(state, SPARKLE_STEPS_SLIM); + + encrypted = true; + } + + private void processFinalAAD() + { + // addition of constant A0 or A1 to the state + if (m_bufPos < RATE_BYTES) + { + state[STATE_WORDS - 1] ^= _A0; + + // padding + m_buf[m_bufPos] = (byte)0x80; + while (++m_bufPos < RATE_BYTES) + { + m_buf[m_bufPos] = 0x00; + } + } + else + { + state[STATE_WORDS - 1] ^= _A1; + } + + for (int i = 0; i < RATE_WORDS / 2; ++i) + { + int j = i + (RATE_WORDS / 2); + + int s_i = state[i]; + int s_j = state[j]; + + int d_i = Pack.littleEndianToInt(m_buf, i * 4); + int d_j = Pack.littleEndianToInt(m_buf, j * 4); + + state[i] = s_j ^ d_i ^ state[RATE_WORDS + i]; + state[j] = s_i ^ s_j ^ d_j ^ state[RATE_WORDS + (j & CAP_MASK)]; + } + + sparkle_opt(state, SPARKLE_STEPS_BIG); } private void reset(boolean clearMac) @@ -544,32 +717,545 @@ private void reset(boolean clearMac) { tag = null; } + + Arrays.clear(m_buf); + m_bufPos = 0; + encrypted = false; + + switch (m_state) + { + case DecInit: + case EncInit: + break; + case DecAad: + case DecData: + case DecFinal: + m_state = State.DecInit; + break; + case EncAad: + case EncData: + case EncFinal: + m_state = State.EncFinal; + return; + default: + throw new IllegalStateException(getAlgorithmName() + " needs to be initialized"); + } + // The Initialize function loads nonce and key into the state and executes the // SPARKLE permutation with the big number of steps. // load nonce into the rate-part of the state System.arraycopy(npub, 0, state, 0, RATE_WORDS); // load key into the capacity-part of the sate System.arraycopy(k, 0, state, RATE_WORDS, KEY_WORDS); - // execute SPARKLE with big number of steps - sparkle_opt(state, STATE_BRANS, SPARKLE_STEPS_BIG); - aadData.reset(); - message.reset(); - encrypted = false; - aadFinished = false; + + sparkle_opt(state, SPARKLE_STEPS_BIG); + + if (initialAssociatedText != null) + { + processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); + } } - public int getBlockSize() + private static int ELL(int x) { - return RATE_BYTES; + return Integers.rotateRight(x, 16) ^ (x & 0xFFFF); } - public int getKeyBytesSize() + private static void sparkle_opt(int[] state, int steps) { - return KEY_BYTES; + switch (state.length) + { + case 8: sparkle_opt8 (state, steps); break; + case 12: sparkle_opt12(state, steps); break; + case 16: sparkle_opt16(state, steps); break; + default: throw new IllegalStateException(); + } } - public int getIVBytesSize() + static void sparkle_opt8(int[] state, int steps) { - return RATE_BYTES; + int s00 = state[0]; + int s01 = state[1]; + int s02 = state[2]; + int s03 = state[3]; + int s04 = state[4]; + int s05 = state[5]; + int s06 = state[6]; + int s07 = state[7]; + + for (int step = 0; step < steps; ++step) + { + // Add round ant + + s01 ^= RCON[step & 7]; + s03 ^= step; + + // ARXBOX layer + { + int rc = RCON[0]; + s00 += Integers.rotateRight(s01, 31); + s01 ^= Integers.rotateRight(s00, 24); + s00 ^= rc; + s00 += Integers.rotateRight(s01, 17); + s01 ^= Integers.rotateRight(s00, 17); + s00 ^= rc; + s00 += s01; + s01 ^= Integers.rotateRight(s00, 31); + s00 ^= rc; + s00 += Integers.rotateRight(s01, 24); + s01 ^= Integers.rotateRight(s00, 16); + s00 ^= rc; + } + { + int rc = RCON[1]; + s02 += Integers.rotateRight(s03, 31); + s03 ^= Integers.rotateRight(s02, 24); + s02 ^= rc; + s02 += Integers.rotateRight(s03, 17); + s03 ^= Integers.rotateRight(s02, 17); + s02 ^= rc; + s02 += s03; + s03 ^= Integers.rotateRight(s02, 31); + s02 ^= rc; + s02 += Integers.rotateRight(s03, 24); + s03 ^= Integers.rotateRight(s02, 16); + s02 ^= rc; + } + { + int rc = RCON[2]; + s04 += Integers.rotateRight(s05, 31); + s05 ^= Integers.rotateRight(s04, 24); + s04 ^= rc; + s04 += Integers.rotateRight(s05, 17); + s05 ^= Integers.rotateRight(s04, 17); + s04 ^= rc; + s04 += s05; + s05 ^= Integers.rotateRight(s04, 31); + s04 ^= rc; + s04 += Integers.rotateRight(s05, 24); + s05 ^= Integers.rotateRight(s04, 16); + s04 ^= rc; + } + { + int rc = RCON[3]; + s06 += Integers.rotateRight(s07, 31); + s07 ^= Integers.rotateRight(s06, 24); + s06 ^= rc; + s06 += Integers.rotateRight(s07, 17); + s07 ^= Integers.rotateRight(s06, 17); + s06 ^= rc; + s06 += s07; + s07 ^= Integers.rotateRight(s06, 31); + s06 ^= rc; + s06 += Integers.rotateRight(s07, 24); + s07 ^= Integers.rotateRight(s06, 16); + s06 ^= rc; + } + + // Linear layer + + int t02 = ELL(s00 ^ s02); + int t13 = ELL(s01 ^ s03); + + int u00 = s00 ^ s04; + int u01 = s01 ^ s05; + int u02 = s02 ^ s06; + int u03 = s03 ^ s07; + + s04 = s00; + s05 = s01; + s06 = s02; + s07 = s03; + + s00 = u02 ^ t13; + s01 = u03 ^ t02; + s02 = u00 ^ t13; + s03 = u01 ^ t02; + } + + state[0] = s00; + state[1] = s01; + state[2] = s02; + state[3] = s03; + state[4] = s04; + state[5] = s05; + state[6] = s06; + state[7] = s07; + } + + static void sparkle_opt12(int[] state, int steps) + { + int s00 = state[0]; + int s01 = state[1]; + int s02 = state[2]; + int s03 = state[3]; + int s04 = state[4]; + int s05 = state[5]; + int s06 = state[6]; + int s07 = state[7]; + int s08 = state[8]; + int s09 = state[9]; + int s10 = state[10]; + int s11 = state[11]; + + for (int step = 0; step < steps; ++step) + { + // Add round ant + + s01 ^= RCON[step & 7]; + s03 ^= step; + + // ARXBOX layer + { + int rc = RCON[0]; + s00 += Integers.rotateRight(s01, 31); + s01 ^= Integers.rotateRight(s00, 24); + s00 ^= rc; + s00 += Integers.rotateRight(s01, 17); + s01 ^= Integers.rotateRight(s00, 17); + s00 ^= rc; + s00 += s01; + s01 ^= Integers.rotateRight(s00, 31); + s00 ^= rc; + s00 += Integers.rotateRight(s01, 24); + s01 ^= Integers.rotateRight(s00, 16); + s00 ^= rc; + } + { + int rc = RCON[1]; + s02 += Integers.rotateRight(s03, 31); + s03 ^= Integers.rotateRight(s02, 24); + s02 ^= rc; + s02 += Integers.rotateRight(s03, 17); + s03 ^= Integers.rotateRight(s02, 17); + s02 ^= rc; + s02 += s03; + s03 ^= Integers.rotateRight(s02, 31); + s02 ^= rc; + s02 += Integers.rotateRight(s03, 24); + s03 ^= Integers.rotateRight(s02, 16); + s02 ^= rc; + } + { + int rc = RCON[2]; + s04 += Integers.rotateRight(s05, 31); + s05 ^= Integers.rotateRight(s04, 24); + s04 ^= rc; + s04 += Integers.rotateRight(s05, 17); + s05 ^= Integers.rotateRight(s04, 17); + s04 ^= rc; + s04 += s05; + s05 ^= Integers.rotateRight(s04, 31); + s04 ^= rc; + s04 += Integers.rotateRight(s05, 24); + s05 ^= Integers.rotateRight(s04, 16); + s04 ^= rc; + } + { + int rc = RCON[3]; + s06 += Integers.rotateRight(s07, 31); + s07 ^= Integers.rotateRight(s06, 24); + s06 ^= rc; + s06 += Integers.rotateRight(s07, 17); + s07 ^= Integers.rotateRight(s06, 17); + s06 ^= rc; + s06 += s07; + s07 ^= Integers.rotateRight(s06, 31); + s06 ^= rc; + s06 += Integers.rotateRight(s07, 24); + s07 ^= Integers.rotateRight(s06, 16); + s06 ^= rc; + } + { + int rc = RCON[4]; + s08 += Integers.rotateRight(s09, 31); + s09 ^= Integers.rotateRight(s08, 24); + s08 ^= rc; + s08 += Integers.rotateRight(s09, 17); + s09 ^= Integers.rotateRight(s08, 17); + s08 ^= rc; + s08 += s09; + s09 ^= Integers.rotateRight(s08, 31); + s08 ^= rc; + s08 += Integers.rotateRight(s09, 24); + s09 ^= Integers.rotateRight(s08, 16); + s08 ^= rc; + } + { + int rc = RCON[5]; + s10 += Integers.rotateRight(s11, 31); + s11 ^= Integers.rotateRight(s10, 24); + s10 ^= rc; + s10 += Integers.rotateRight(s11, 17); + s11 ^= Integers.rotateRight(s10, 17); + s10 ^= rc; + s10 += s11; + s11 ^= Integers.rotateRight(s10, 31); + s10 ^= rc; + s10 += Integers.rotateRight(s11, 24); + s11 ^= Integers.rotateRight(s10, 16); + s10 ^= rc; + } + + // Linear layer + + int t024 = ELL(s00 ^ s02 ^ s04); + int t135 = ELL(s01 ^ s03 ^ s05); + + int u00 = s00 ^ s06; + int u01 = s01 ^ s07; + int u02 = s02 ^ s08; + int u03 = s03 ^ s09; + int u04 = s04 ^ s10; + int u05 = s05 ^ s11; + + s06 = s00; + s07 = s01; + s08 = s02; + s09 = s03; + s10 = s04; + s11 = s05; + + s00 = u02 ^ t135; + s01 = u03 ^ t024; + s02 = u04 ^ t135; + s03 = u05 ^ t024; + s04 = u00 ^ t135; + s05 = u01 ^ t024; + } + + state[0] = s00; + state[1] = s01; + state[2] = s02; + state[3] = s03; + state[4] = s04; + state[5] = s05; + state[6] = s06; + state[7] = s07; + state[8] = s08; + state[9] = s09; + state[10] = s10; + state[11] = s11; + } + + public static void sparkle_opt12(SparkleDigest.Friend friend, int[] state, int steps) + { + if (null == friend) + { + throw new NullPointerException("This method is only for use by SparkleDigest"); + } + + sparkle_opt12(state, steps); + } + + static void sparkle_opt16(int[] state, int steps) + { +// assert (steps & 1) == 0; + + int s00 = state[0]; + int s01 = state[1]; + int s02 = state[2]; + int s03 = state[3]; + int s04 = state[4]; + int s05 = state[5]; + int s06 = state[6]; + int s07 = state[7]; + int s08 = state[8]; + int s09 = state[9]; + int s10 = state[10]; + int s11 = state[11]; + int s12 = state[12]; + int s13 = state[13]; + int s14 = state[14]; + int s15 = state[15]; + + for (int step = 0; step < steps; ++step) + { + // Add round ant + + s01 ^= RCON[step & 7]; + s03 ^= step; + + // ARXBOX layer + { + int rc = RCON[0]; + s00 += Integers.rotateRight(s01, 31); + s01 ^= Integers.rotateRight(s00, 24); + s00 ^= rc; + s00 += Integers.rotateRight(s01, 17); + s01 ^= Integers.rotateRight(s00, 17); + s00 ^= rc; + s00 += s01; + s01 ^= Integers.rotateRight(s00, 31); + s00 ^= rc; + s00 += Integers.rotateRight(s01, 24); + s01 ^= Integers.rotateRight(s00, 16); + s00 ^= rc; + } + { + int rc = RCON[1]; + s02 += Integers.rotateRight(s03, 31); + s03 ^= Integers.rotateRight(s02, 24); + s02 ^= rc; + s02 += Integers.rotateRight(s03, 17); + s03 ^= Integers.rotateRight(s02, 17); + s02 ^= rc; + s02 += s03; + s03 ^= Integers.rotateRight(s02, 31); + s02 ^= rc; + s02 += Integers.rotateRight(s03, 24); + s03 ^= Integers.rotateRight(s02, 16); + s02 ^= rc; + } + { + int rc = RCON[2]; + s04 += Integers.rotateRight(s05, 31); + s05 ^= Integers.rotateRight(s04, 24); + s04 ^= rc; + s04 += Integers.rotateRight(s05, 17); + s05 ^= Integers.rotateRight(s04, 17); + s04 ^= rc; + s04 += s05; + s05 ^= Integers.rotateRight(s04, 31); + s04 ^= rc; + s04 += Integers.rotateRight(s05, 24); + s05 ^= Integers.rotateRight(s04, 16); + s04 ^= rc; + } + { + int rc = RCON[3]; + s06 += Integers.rotateRight(s07, 31); + s07 ^= Integers.rotateRight(s06, 24); + s06 ^= rc; + s06 += Integers.rotateRight(s07, 17); + s07 ^= Integers.rotateRight(s06, 17); + s06 ^= rc; + s06 += s07; + s07 ^= Integers.rotateRight(s06, 31); + s06 ^= rc; + s06 += Integers.rotateRight(s07, 24); + s07 ^= Integers.rotateRight(s06, 16); + s06 ^= rc; + } + { + int rc = RCON[4]; + s08 += Integers.rotateRight(s09, 31); + s09 ^= Integers.rotateRight(s08, 24); + s08 ^= rc; + s08 += Integers.rotateRight(s09, 17); + s09 ^= Integers.rotateRight(s08, 17); + s08 ^= rc; + s08 += s09; + s09 ^= Integers.rotateRight(s08, 31); + s08 ^= rc; + s08 += Integers.rotateRight(s09, 24); + s09 ^= Integers.rotateRight(s08, 16); + s08 ^= rc; + } + { + int rc = RCON[5]; + s10 += Integers.rotateRight(s11, 31); + s11 ^= Integers.rotateRight(s10, 24); + s10 ^= rc; + s10 += Integers.rotateRight(s11, 17); + s11 ^= Integers.rotateRight(s10, 17); + s10 ^= rc; + s10 += s11; + s11 ^= Integers.rotateRight(s10, 31); + s10 ^= rc; + s10 += Integers.rotateRight(s11, 24); + s11 ^= Integers.rotateRight(s10, 16); + s10 ^= rc; + } + { + int rc = RCON[6]; + s12 += Integers.rotateRight(s13, 31); + s13 ^= Integers.rotateRight(s12, 24); + s12 ^= rc; + s12 += Integers.rotateRight(s13, 17); + s13 ^= Integers.rotateRight(s12, 17); + s12 ^= rc; + s12 += s13; + s13 ^= Integers.rotateRight(s12, 31); + s12 ^= rc; + s12 += Integers.rotateRight(s13, 24); + s13 ^= Integers.rotateRight(s12, 16); + s12 ^= rc; + } + { + int rc = RCON[7]; + s14 += Integers.rotateRight(s15, 31); + s15 ^= Integers.rotateRight(s14, 24); + s14 ^= rc; + s14 += Integers.rotateRight(s15, 17); + s15 ^= Integers.rotateRight(s14, 17); + s14 ^= rc; + s14 += s15; + s15 ^= Integers.rotateRight(s14, 31); + s14 ^= rc; + s14 += Integers.rotateRight(s15, 24); + s15 ^= Integers.rotateRight(s14, 16); + s14 ^= rc; + } + + // Linear layer + + int t0246 = ELL(s00 ^ s02 ^ s04 ^ s06); + int t1357 = ELL(s01 ^ s03 ^ s05 ^ s07); + + int u00 = s00 ^ s08; + int u01 = s01 ^ s09; + int u02 = s02 ^ s10; + int u03 = s03 ^ s11; + int u04 = s04 ^ s12; + int u05 = s05 ^ s13; + int u06 = s06 ^ s14; + int u07 = s07 ^ s15; + + s08 = s00; + s09 = s01; + s10 = s02; + s11 = s03; + s12 = s04; + s13 = s05; + s14 = s06; + s15 = s07; + + s00 = u02 ^ t1357; + s01 = u03 ^ t0246; + s02 = u04 ^ t1357; + s03 = u05 ^ t0246; + s04 = u06 ^ t1357; + s05 = u07 ^ t0246; + s06 = u00 ^ t1357; + s07 = u01 ^ t0246; + } + + state[0] = s00; + state[1] = s01; + state[2] = s02; + state[3] = s03; + state[4] = s04; + state[5] = s05; + state[6] = s06; + state[7] = s07; + state[8] = s08; + state[9] = s09; + state[10] = s10; + state[11] = s11; + state[12] = s12; + state[13] = s13; + state[14] = s14; + state[15] = s15; + } + + public static void sparkle_opt16(SparkleDigest.Friend friend, int[] state, int steps) + { + if (null == friend) + { + throw new NullPointerException("This method is only for use by SparkleDigest"); + } + + sparkle_opt16(state, steps); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/XoodyakEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/XoodyakEngine.java index 41cc3bce50..9c473fb6c9 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/XoodyakEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/XoodyakEngine.java @@ -12,6 +12,7 @@ import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Integers; import org.bouncycastle.util.Pack; /** @@ -35,9 +36,9 @@ public class XoodyakEngine private byte[] iv; private final int PhaseDown = 1; private final int PhaseUp = 2; - private final int NLANES = 12; - private final int NROWS = 3; - private final int NCOLUMS = 4; +// private final int NLANES = 12; +// private final int NROWS = 3; +// private final int NCOLUMS = 4; private final int MAXROUNDS = 12; private final int TAGLEN = 16; final int Rkin = 44; @@ -328,58 +329,109 @@ private void Up(byte[] Yi, int YiLen, int Cu) { state[f_bPrime - 1] ^= Cu; } - int[] a = new int[NLANES]; - Pack.littleEndianToInt(state, 0, a, 0, a.length); - int x, y; - int[] b = new int[NLANES]; - int[] p = new int[NCOLUMS]; - int[] e = new int[NCOLUMS]; + + int a0 = Pack.littleEndianToInt(state, 0); + int a1 = Pack.littleEndianToInt(state, 4); + int a2 = Pack.littleEndianToInt(state, 8); + int a3 = Pack.littleEndianToInt(state, 12); + int a4 = Pack.littleEndianToInt(state, 16); + int a5 = Pack.littleEndianToInt(state, 20); + int a6 = Pack.littleEndianToInt(state, 24); + int a7 = Pack.littleEndianToInt(state, 28); + int a8 = Pack.littleEndianToInt(state, 32); + int a9 = Pack.littleEndianToInt(state, 36); + int a10 = Pack.littleEndianToInt(state, 40); + int a11 = Pack.littleEndianToInt(state, 44); + for (int i = 0; i < MAXROUNDS; ++i) { /* Theta: Column Parity Mixer */ - for (x = 0; x < NCOLUMS; ++x) - { - p[x] = a[index(x, 0)] ^ a[index(x, 1)] ^ a[index(x, 2)]; - } - for (x = 0; x < NCOLUMS; ++x) - { - y = p[(x + 3) & 3]; - e[x] = ROTL32(y, 5) ^ ROTL32(y, 14); - } - for (x = 0; x < NCOLUMS; ++x) - { - for (y = 0; y < NROWS; ++y) - { - a[index(x, y)] ^= e[x]; - } - } + int p0 = a0 ^ a4 ^ a8; + int p1 = a1 ^ a5 ^ a9; + int p2 = a2 ^ a6 ^ a10; + int p3 = a3 ^ a7 ^ a11; + + int e0 = Integers.rotateLeft(p3, 5) ^ Integers.rotateLeft(p3, 14); + int e1 = Integers.rotateLeft(p0, 5) ^ Integers.rotateLeft(p0, 14); + int e2 = Integers.rotateLeft(p1, 5) ^ Integers.rotateLeft(p1, 14); + int e3 = Integers.rotateLeft(p2, 5) ^ Integers.rotateLeft(p2, 14); + + a0 ^= e0; + a4 ^= e0; + a8 ^= e0; + + a1 ^= e1; + a5 ^= e1; + a9 ^= e1; + + a2 ^= e2; + a6 ^= e2; + a10 ^= e2; + + a3 ^= e3; + a7 ^= e3; + a11 ^= e3; + /* Rho-west: plane shift */ - for (x = 0; x < NCOLUMS; ++x) - { - b[index(x, 0)] = a[index(x, 0)]; - b[index(x, 1)] = a[index(x + 3, 1)]; - b[index(x, 2)] = ROTL32(a[index(x, 2)], 11); - } + int b0 = a0; + int b1 = a1; + int b2 = a2; + int b3 = a3; + + int b4 = a7; + int b5 = a4; + int b6 = a5; + int b7 = a6; + + int b8 = Integers.rotateLeft(a8, 11); + int b9 = Integers.rotateLeft(a9, 11); + int b10 = Integers.rotateLeft(a10, 11); + int b11 = Integers.rotateLeft(a11, 11); + /* Iota: round ant */ - b[0] ^= RC[i]; + b0 ^= RC[i]; + /* Chi: non linear layer */ - for (x = 0; x < NCOLUMS; ++x) - { - for (y = 0; y < NROWS; ++y) - { - a[index(x, y)] = b[index(x, y)] ^ (~b[index(x, y + 1)] & b[index(x, y + 2)]); - } - } + a0 = b0 ^ (~b4 & b8); + a1 = b1 ^ (~b5 & b9); + a2 = b2 ^ (~b6 & b10); + a3 = b3 ^ (~b7 & b11); + + a4 = b4 ^ (~b8 & b0); + a5 = b5 ^ (~b9 & b1); + a6 = b6 ^ (~b10 & b2); + a7 = b7 ^ (~b11 & b3); + + b8 ^= (~b0 & b4); + b9 ^= (~b1 & b5); + b10 ^= (~b2 & b6); + b11 ^= (~b3 & b7); + /* Rho-east: plane shift */ - for (x = 0; x < NCOLUMS; ++x) - { - b[index(x, 0)] = a[index(x, 0)]; - b[index(x, 1)] = ROTL32(a[index(x, 1)], 1); - b[index(x, 2)] = ROTL32(a[index(x + 2, 2)], 8); - } - System.arraycopy(b, 0, a, 0, NLANES); + a4 = Integers.rotateLeft(a4, 1); + a5 = Integers.rotateLeft(a5, 1); + a6 = Integers.rotateLeft(a6, 1); + a7 = Integers.rotateLeft(a7, 1); + + a8 = Integers.rotateLeft(b10, 8); + a9 = Integers.rotateLeft(b11, 8); + a10 = Integers.rotateLeft(b8, 8); + a11 = Integers.rotateLeft(b9, 8); } - Pack.intToLittleEndian(a, 0, a.length, state, 0); + + Pack.intToLittleEndian(a0, state, 0); + Pack.intToLittleEndian(a1, state, 4); + Pack.intToLittleEndian(a2, state, 8); + Pack.intToLittleEndian(a3, state, 12); + Pack.intToLittleEndian(a4, state, 16); + Pack.intToLittleEndian(a5, state, 20); + Pack.intToLittleEndian(a6, state, 24); + Pack.intToLittleEndian(a7, state, 28); + Pack.intToLittleEndian(a8, state, 32); + Pack.intToLittleEndian(a9, state, 36); + Pack.intToLittleEndian(a10, state, 40); + Pack.intToLittleEndian(a11, state, 44); + phase = PhaseUp; if (Yi != null) { @@ -398,16 +450,6 @@ void Down(byte[] Xi, int XiOff, int XiLen, int Cd) phase = PhaseDown; } - private int index(int x, int y) - { - return (((y % NROWS) * NCOLUMS) + ((x) % NCOLUMS)); - } - - private int ROTL32(int a, int offset) - { - return (a << (offset & 31)) ^ (a >>> ((32 - (offset)) & 31)); - } - public int getBlockSize() { return Rkout; diff --git a/core/src/main/java/org/bouncycastle/crypto/examples/JPAKEExample.java b/core/src/main/java/org/bouncycastle/crypto/examples/JPAKEExample.java index 967624e617..5efd0bc0db 100644 --- a/core/src/main/java/org/bouncycastle/crypto/examples/JPAKEExample.java +++ b/core/src/main/java/org/bouncycastle/crypto/examples/JPAKEExample.java @@ -5,9 +5,10 @@ import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.SavableDigest; +import org.bouncycastle.crypto.agreement.jpake.JPAKEParticipant; import org.bouncycastle.crypto.agreement.jpake.JPAKEPrimeOrderGroup; import org.bouncycastle.crypto.agreement.jpake.JPAKEPrimeOrderGroups; -import org.bouncycastle.crypto.agreement.jpake.JPAKEParticipant; import org.bouncycastle.crypto.agreement.jpake.JPAKERound1Payload; import org.bouncycastle.crypto.agreement.jpake.JPAKERound2Payload; import org.bouncycastle.crypto.agreement.jpake.JPAKERound3Payload; @@ -57,7 +58,7 @@ public static void main(String args[]) throws CryptoException /* * Both participants must use the same hashing algorithm. */ - Digest digest = new SHA256Digest(); + Digest digest = SHA256Digest.newInstance(); SecureRandom random = new SecureRandom(); JPAKEParticipant alice = new JPAKEParticipant("alice", alicePassword.toCharArray(), group, digest, random); @@ -201,7 +202,7 @@ private static BigInteger deriveSessionKey(BigInteger keyingMaterial) * * For the purposes of this example, I'm just going to use a hash of the keying material. */ - SHA256Digest digest = new SHA256Digest(); + SavableDigest digest = SHA256Digest.newInstance(); byte[] keyByteArray = keyingMaterial.toByteArray(); diff --git a/core/src/main/java/org/bouncycastle/crypto/fpe/FPEFF1Engine.java b/core/src/main/java/org/bouncycastle/crypto/fpe/FPEFF1Engine.java index 325b99ca7a..a8118f13d7 100644 --- a/core/src/main/java/org/bouncycastle/crypto/fpe/FPEFF1Engine.java +++ b/core/src/main/java/org/bouncycastle/crypto/fpe/FPEFF1Engine.java @@ -18,7 +18,7 @@ public class FPEFF1Engine */ public FPEFF1Engine() { - this(new AESEngine()); + this(AESEngine.newInstance()); } /** diff --git a/core/src/main/java/org/bouncycastle/crypto/fpe/FPEFF3_1Engine.java b/core/src/main/java/org/bouncycastle/crypto/fpe/FPEFF3_1Engine.java index 384e42858f..9304f59dd3 100644 --- a/core/src/main/java/org/bouncycastle/crypto/fpe/FPEFF3_1Engine.java +++ b/core/src/main/java/org/bouncycastle/crypto/fpe/FPEFF3_1Engine.java @@ -4,8 +4,6 @@ import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.params.FPEParameters; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Properties; /** @@ -20,7 +18,7 @@ public class FPEFF3_1Engine */ public FPEFF3_1Engine() { - this(new AESEngine()); + this(AESEngine.newInstance()); } /** @@ -49,7 +47,7 @@ public void init(boolean forEncryption, CipherParameters parameters) this.fpeParameters = (FPEParameters)parameters; - baseCipher.init(!fpeParameters.isUsingInverseFunction(), new KeyParameter(Arrays.reverse(fpeParameters.getKey().getKey()))); + baseCipher.init(!fpeParameters.isUsingInverseFunction(), fpeParameters.getKey().reverse()); if (fpeParameters.getTweak().length != 7) { diff --git a/core/src/main/java/org/bouncycastle/crypto/fpe/SP80038G.java b/core/src/main/java/org/bouncycastle/crypto/fpe/SP80038G.java index 1f093783c4..06156bb681 100644 --- a/core/src/main/java/org/bouncycastle/crypto/fpe/SP80038G.java +++ b/core/src/main/java/org/bouncycastle/crypto/fpe/SP80038G.java @@ -6,6 +6,7 @@ import org.bouncycastle.crypto.util.RadixConverter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; +import org.bouncycastle.util.Bytes; import org.bouncycastle.util.Integers; import org.bouncycastle.util.Pack; @@ -347,15 +348,17 @@ protected static BigInteger calculateY_FF1(BlockCipher cipher, byte[] T, int b, { int sBlocksLen = (d + BLOCK_SIZE - 1) / BLOCK_SIZE; sBlocks = new byte[sBlocksLen * BLOCK_SIZE]; + + int j0 = Pack.bigEndianToInt(R, BLOCK_SIZE - 4); System.arraycopy(R, 0, sBlocks, 0, BLOCK_SIZE); - byte[] uint32 = new byte[4]; for (int j = 1; j < sBlocksLen; ++j) { int sOff = j * BLOCK_SIZE; - System.arraycopy(R, 0, sBlocks, sOff, BLOCK_SIZE); - Pack.intToBigEndian(j, uint32, 0); - xor(uint32, 0, sBlocks, sOff + BLOCK_SIZE - 4, 4); + + System.arraycopy(R, 0, sBlocks, sOff, BLOCK_SIZE - 4); + Pack.intToBigEndian(j0 ^ j, sBlocks, sOff + BLOCK_SIZE - 4); + cipher.processBlock(sBlocks, sOff, sBlocks, sOff); } } @@ -368,22 +371,15 @@ protected static BigInteger calculateY_FF3(BlockCipher cipher, byte[] T, int wOf { // ii. byte[] P = new byte[BLOCK_SIZE]; - Pack.intToBigEndian(round, P, 0); - xor(T, wOff, P, 0, 4); - BigInteger numAB = radixConverter.fromEncoding(AB); + Pack.intToBigEndian(Pack.bigEndianToInt(T, wOff) ^ round, P, 0); - byte[] bytesAB = BigIntegers.asUnsignedByteArray(numAB); - - if ((P.length - bytesAB.length) < 4) // to be sure... - { - throw new IllegalStateException("input out of range"); - } - System.arraycopy(bytesAB, 0, P, P.length - bytesAB.length, bytesAB.length); + BigInteger numAB = radixConverter.fromEncoding(AB); + BigIntegers.asUnsignedByteArray(numAB, P, 4, BLOCK_SIZE - 4); // iii. - rev(P); + Arrays.reverseInPlace(P); cipher.processBlock(P, 0, P, 0); - rev(P); + Arrays.reverseInPlace(P); byte[] S = P; // iv. @@ -499,8 +495,8 @@ private static short[] decFF3_1(BlockCipher cipher, RadixConverter radixConverte int m = u; // Note we keep A, B in reverse order throughout - rev(A); - rev(B); + Arrays.reverseInPlace(A); + Arrays.reverseInPlace(B); for (int i = 7; i >= 0; --i) { @@ -522,8 +518,8 @@ private static short[] decFF3_1(BlockCipher cipher, RadixConverter radixConverte radixConverter.toEncoding(c, m, C); } - rev(A); - rev(B); + Arrays.reverseInPlace(A); + Arrays.reverseInPlace(B); return Arrays.concatenate(A, B); } @@ -567,8 +563,8 @@ private static short[] encFF3_1(BlockCipher cipher, RadixConverter radixConverte int m = v; // Note we keep A, B in reverse order throughout - rev(a); - rev(b); + Arrays.reverseInPlace(a); + Arrays.reverseInPlace(b); for (int i = 0; i < 8; ++i) { @@ -590,8 +586,8 @@ private static short[] encFF3_1(BlockCipher cipher, RadixConverter radixConverte radixConverter.toEncoding(c, m, C); } - rev(a); - rev(b); + Arrays.reverseInPlace(a); + Arrays.reverseInPlace(b); return Arrays.concatenate(a, b); } @@ -613,51 +609,13 @@ protected static byte[] prf(BlockCipher c, byte[] x) for (int i = 0; i < m; ++i) { - xor(x, i * BLOCK_SIZE, y, 0, BLOCK_SIZE); + Bytes.xorTo(BLOCK_SIZE, x, i * BLOCK_SIZE, y, 0); c.processBlock(y, 0, y, 0); } return y; } -// protected static void rev(byte[] x, int xOff, byte[] y, int yOff, int len) -// { -// for (int i = 1; i <= len; ++i) -// { -// y[yOff + len - i] = x[xOff + i - 1]; -// } -// } - - protected static void rev(byte[] x) - { - int half = x.length / 2, end = x.length - 1; - for (int i = 0; i < half; ++i) - { - byte tmp = x[i]; - x[i] = x[end - i]; - x[end - i] = tmp; - } - } - - protected static void rev(short[] x) - { - int half = x.length / 2, end = x.length - 1; - for (int i = 0; i < half; ++i) - { - short tmp = x[i]; - x[i] = x[end - i]; - x[end - i] = tmp; - } - } - - protected static void xor(byte[] x, int xOff, byte[] y, int yOff, int len) - { - for (int i = 0; i < len; ++i) - { - y[yOff + i] ^= x[xOff + i]; - } - } - private static byte[] toByte(short[] buf) { byte[] s = new byte[buf.length]; diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/Argon2BytesGenerator.java b/core/src/main/java/org/bouncycastle/crypto/generators/Argon2BytesGenerator.java index c4e9eee295..eade40ff68 100755 --- a/core/src/main/java/org/bouncycastle/crypto/generators/Argon2BytesGenerator.java +++ b/core/src/main/java/org/bouncycastle/crypto/generators/Argon2BytesGenerator.java @@ -485,7 +485,7 @@ private static void quarterRound(long[] v, int x, int y, int z, int s) private void initialize(byte[] tmpBlockBytes, byte[] password, int outputLength) { - /** + /* * H0 = H64(p, τ, m, t, v, y, |P|, P, |S|, S, |L|, K, |X|, X) * -> 64 byte (ARGON2_PREHASH_DIGEST_LENGTH) */ diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupParametersGenerator.java b/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupParametersGenerator.java index 1225056d06..0b874a11bd 100644 --- a/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupParametersGenerator.java +++ b/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupParametersGenerator.java @@ -56,7 +56,7 @@ public CramerShoupParameters generateParameters() g2 = ParametersHelper.selectGenerator(q, random); } - return new CramerShoupParameters(q, g1, g2, new SHA256Digest()); + return new CramerShoupParameters(q, g1, g2, SHA256Digest.newInstance()); } public CramerShoupParameters generateParameters(DHParameters dhParams) @@ -71,7 +71,7 @@ public CramerShoupParameters generateParameters(DHParameters dhParams) g2 = ParametersHelper.selectGenerator(p, random); } - return new CramerShoupParameters(p, g1, g2, new SHA256Digest()); + return new CramerShoupParameters(p, g1, g2, SHA256Digest.newInstance()); } private static class ParametersHelper diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/NaccacheSternKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/crypto/generators/NaccacheSternKeyPairGenerator.java index 97d991477b..d6af762404 100644 --- a/core/src/main/java/org/bouncycastle/crypto/generators/NaccacheSternKeyPairGenerator.java +++ b/core/src/main/java/org/bouncycastle/crypto/generators/NaccacheSternKeyPairGenerator.java @@ -24,7 +24,6 @@ public class NaccacheSternKeyPairGenerator implements AsymmetricCipherKeyPairGenerator { - private static int[] smallPrimes = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, @@ -112,6 +111,7 @@ public AsymmetricCipherKeyPair generateKeyPair() BigInteger _2au = a.multiply(u).shiftLeft(1); BigInteger _2bv = b.multiply(v).shiftLeft(1); + BigInteger n; for (;;) { tries++; @@ -142,24 +142,25 @@ public AsymmetricCipherKeyPair generateKeyPair() } } - if (!sigma.gcd(p_.multiply(q_)).equals(ONE)) + if (!BigIntegers.modOddIsCoprime(p_.multiply(q_), sigma)) { // System.out.println("sigma.gcd(p_.mult(q_)) != 1!\n p_: " + p_ // +"\n q_: "+ q_ ); continue; } - if (p.multiply(q).bitLength() < strength) + n = p.multiply(q); + if (n.bitLength() >= strength) { - if (debug) - { - // -DM System.out.println - System.out.println("key size too small. Should be " + strength + " but is actually " - + p.multiply(q).bitLength()); - } - continue; + break; + } + + if (debug) + { + // -DM System.out.println + System.out.println("key size too small. Should be " + strength + " but is actually " + + p.multiply(q).bitLength()); } - break; } if (debug) @@ -168,7 +169,6 @@ public AsymmetricCipherKeyPair generateKeyPair() System.out.println("needed " + tries + " tries to generate p and q."); } - BigInteger n = p.multiply(q); BigInteger phi_n = p.subtract(ONE).multiply(q.subtract(ONE)); BigInteger g; tries = 0; @@ -296,8 +296,9 @@ public AsymmetricCipherKeyPair generateKeyPair() System.out.println(); } - return new AsymmetricCipherKeyPair(new NaccacheSternKeyParameters(false, g, n, sigma.bitLength()), - new NaccacheSternPrivateKeyParameters(g, n, sigma.bitLength(), smallPrimes, phi_n)); + return new AsymmetricCipherKeyPair( + new NaccacheSternKeyParameters(false, g, n, sigma.bitLength()), + new NaccacheSternPrivateKeyParameters(g, n, sigma.bitLength(), smallPrimes, phi_n)); } private static BigInteger generatePrime( @@ -382,5 +383,4 @@ private static Vector findFirstPrimes( return primes; } - } diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/RSABlindingFactorGenerator.java b/core/src/main/java/org/bouncycastle/crypto/generators/RSABlindingFactorGenerator.java index 9e2df35bb8..3c47cc6124 100644 --- a/core/src/main/java/org/bouncycastle/crypto/generators/RSABlindingFactorGenerator.java +++ b/core/src/main/java/org/bouncycastle/crypto/generators/RSABlindingFactorGenerator.java @@ -17,8 +17,7 @@ */ public class RSABlindingFactorGenerator { - private static BigInteger ZERO = BigInteger.valueOf(0); - private static BigInteger ONE = BigInteger.valueOf(1); + private static BigInteger TWO = BigInteger.valueOf(2); private RSAKeyParameters key; private SecureRandom random; @@ -64,15 +63,13 @@ public BigInteger generateBlindingFactor() BigInteger m = key.getModulus(); int length = m.bitLength() - 1; // must be less than m.bitLength() - BigInteger factor; - BigInteger gcd; + BigInteger factor; do { factor = BigIntegers.createRandomBigInteger(length, random); - gcd = factor.gcd(m); } - while (factor.equals(ZERO) || factor.equals(ONE) || !gcd.equals(ONE)); + while (factor.compareTo(TWO) < 0 || !BigIntegers.modOddIsCoprime(m, factor)); return factor; } diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/SCrypt.java b/core/src/main/java/org/bouncycastle/crypto/generators/SCrypt.java index 85e1cb8317..aa9cd857da 100644 --- a/core/src/main/java/org/bouncycastle/crypto/generators/SCrypt.java +++ b/core/src/main/java/org/bouncycastle/crypto/generators/SCrypt.java @@ -115,7 +115,7 @@ private static byte[] MFcrypt(byte[] P, byte[] S, int N, int r, int p, int dkLen private static byte[] SingleIterationPBKDF2(byte[] P, byte[] S, int dkLen) { - PBEParametersGenerator pGen = new PKCS5S2ParametersGenerator(new SHA256Digest()); + PBEParametersGenerator pGen = new PKCS5S2ParametersGenerator(SHA256Digest.newInstance()); pGen.init(P, S, 1); KeyParameter key = (KeyParameter)pGen.generateDerivedMacParameters(dkLen * 8); return key.getKey(); diff --git a/core/src/main/java/org/bouncycastle/crypto/hpke/AEAD.java b/core/src/main/java/org/bouncycastle/crypto/hpke/AEAD.java index f9228f52ee..e4e840bec1 100644 --- a/core/src/main/java/org/bouncycastle/crypto/hpke/AEAD.java +++ b/core/src/main/java/org/bouncycastle/crypto/hpke/AEAD.java @@ -44,60 +44,91 @@ public AEAD(short aeadId, byte[] key, byte[] baseNonce) // used by Sender - public byte[] seal(byte[] aad, byte[] pt) - throws InvalidCipherTextException + public byte[] seal(byte[] aad, byte[] pt, int ptOffset, int ptLength) + throws InvalidCipherTextException { + if (ptOffset < 0 || ptOffset > pt.length) + { + throw new IndexOutOfBoundsException("Invalid offset"); + } + if (ptOffset + ptLength > pt.length) + { + throw new IndexOutOfBoundsException("Invalid length"); + } + CipherParameters params; switch (aeadId) { - case HPKE.aead_AES_GCM128: - case HPKE.aead_AES_GCM256: - case HPKE.aead_CHACHA20_POLY1305: - params = new ParametersWithIV(new KeyParameter(key), ComputeNonce()); - break; - case HPKE.aead_EXPORT_ONLY: - default: - throw new IllegalStateException("Export only mode, cannot be used to seal/open"); + case HPKE.aead_AES_GCM128: + case HPKE.aead_AES_GCM256: + case HPKE.aead_CHACHA20_POLY1305: + params = new ParametersWithIV(new KeyParameter(key), ComputeNonce()); + break; + case HPKE.aead_EXPORT_ONLY: + default: + throw new IllegalStateException("Export only mode, cannot be used to seal/open"); } cipher.init(true, params); cipher.processAADBytes(aad, 0, aad.length); - byte[] ct = new byte[cipher.getOutputSize(pt.length)]; - int len = cipher.processBytes(pt, 0, pt.length, ct, 0); + byte[] ct = new byte[cipher.getOutputSize(ptLength)]; + int len = cipher.processBytes(pt, ptOffset, ptLength, ct, 0); cipher.doFinal(ct, len); seq++; return ct; } + // used by Sender + public byte[] seal(byte[] aad, byte[] pt) + throws InvalidCipherTextException + { + return this.seal(aad, pt, 0, pt.length); + } // used by Receiver - public byte[] open(byte[] aad, byte[] ct) + public byte[] open(byte[] aad, byte[] ct, int ctOffset, int ctLength) throws InvalidCipherTextException { + if (ctOffset < 0 || ctOffset > ct.length) + { + throw new IndexOutOfBoundsException("Invalid offset"); + } + if (ctOffset + ctLength > ct.length) + { + throw new IndexOutOfBoundsException("Invalid length"); + } + CipherParameters params; switch (aeadId) { - case HPKE.aead_AES_GCM128: - case HPKE.aead_AES_GCM256: - case HPKE.aead_CHACHA20_POLY1305: - params = new ParametersWithIV(new KeyParameter(key), ComputeNonce()); - break; - case HPKE.aead_EXPORT_ONLY: - default: - throw new IllegalStateException("Export only mode, cannot be used to seal/open"); + case HPKE.aead_AES_GCM128: + case HPKE.aead_AES_GCM256: + case HPKE.aead_CHACHA20_POLY1305: + params = new ParametersWithIV(new KeyParameter(key), ComputeNonce()); + break; + case HPKE.aead_EXPORT_ONLY: + default: + throw new IllegalStateException("Export only mode, cannot be used to seal/open"); } cipher.init(false, params); cipher.processAADBytes(aad, 0, aad.length); - byte[] pt = new byte[cipher.getOutputSize(ct.length)]; - int len = cipher.processBytes(ct, 0, ct.length, pt, 0); + byte[] pt = new byte[cipher.getOutputSize(ctLength)]; + int len = cipher.processBytes(ct, ctOffset, ctLength, pt, 0); len += cipher.doFinal(pt, len); seq++; return pt; } + // used by Receiver + public byte[] open(byte[] aad, byte[] ct) + throws InvalidCipherTextException + { + return this.open(aad, ct, 0, ct.length); + } + private byte[] ComputeNonce() { byte[] seq_bytes = Pack.longToBigEndian(seq); @@ -106,7 +137,7 @@ private byte[] ComputeNonce() //xor for (int i = 0; i < 8; i++) { - nonce[Nn-8+i] ^= seq_bytes[i]; + nonce[Nn - 8 + i] ^= seq_bytes[i]; } return nonce; } diff --git a/core/src/main/java/org/bouncycastle/crypto/hpke/DHKEM.java b/core/src/main/java/org/bouncycastle/crypto/hpke/DHKEM.java index b2e91744c3..44a46d6a47 100644 --- a/core/src/main/java/org/bouncycastle/crypto/hpke/DHKEM.java +++ b/core/src/main/java/org/bouncycastle/crypto/hpke/DHKEM.java @@ -36,6 +36,7 @@ class DHKEM + extends KEM { private AsymmetricCipherKeyPairGenerator kpGen; @@ -48,6 +49,7 @@ class DHKEM private byte bitmask; private int Nsk; private int Nsecret; + private int Nenc; ECDomainParameters domainParams; @@ -74,7 +76,7 @@ protected DHKEM(short kemid) bitmask = (byte)0xff; Nsk = 32; Nsecret = 32; - + Nenc = 65; this.kpGen = new ECKeyPairGenerator(); this.kpGen.init(new ECKeyGenerationParameters(domainParams, new SecureRandom())); @@ -96,6 +98,7 @@ protected DHKEM(short kemid) bitmask = (byte)0xff; Nsk = 48; Nsecret = 48; + Nenc = 97; this.kpGen = new ECKeyPairGenerator(); this.kpGen.init(new ECKeyGenerationParameters(domainParams, new SecureRandom())); @@ -119,6 +122,7 @@ protected DHKEM(short kemid) bitmask = 0x01; Nsk = 66; Nsecret = 64; + Nenc = 133; this.kpGen = new ECKeyPairGenerator(); this.kpGen.init(new ECKeyGenerationParameters(domainParams, new SecureRandom())); @@ -129,6 +133,7 @@ protected DHKEM(short kemid) this.agreement = new XDHBasicAgreement(); Nsecret = 32; Nsk = 32; + Nenc = 32; this.kpGen = new X25519KeyPairGenerator(); this.kpGen.init(new X25519KeyGenerationParameters(new SecureRandom())); @@ -138,6 +143,7 @@ protected DHKEM(short kemid) this.agreement = new XDHBasicAgreement(); Nsecret = 64; Nsk = 56; + Nenc = 56; this.kpGen = new X448KeyPairGenerator(); this.kpGen.init(new X448KeyGenerationParameters(new SecureRandom())); @@ -242,6 +248,11 @@ public AsymmetricCipherKeyPair DeserializePrivateKey(byte[] skEncoded, byte[] pk } } + int getEncryptionSize() + { + return Nenc; + } + private boolean ValidateSk(BigInteger d) { BigInteger n = domainParams.getN(); @@ -321,11 +332,14 @@ public AsymmetricCipherKeyPair DeriveKeyPair(byte[] ikm) } } - protected byte[][] Encap(AsymmetricKeyParameter pkR) + { + return Encap(pkR, kpGen.generateKeyPair());// todo: can be replaced with deriveKeyPair(random) + } + + protected byte[][] Encap(AsymmetricKeyParameter pkR, AsymmetricCipherKeyPair kpE) { byte[][] output = new byte[2][]; - AsymmetricCipherKeyPair kpE = kpGen.generateKeyPair();// todo: can be replaced with deriveKeyPair(random) //DH agreement.init(kpE.getPrivate()); diff --git a/core/src/main/java/org/bouncycastle/crypto/hpke/HKDF.java b/core/src/main/java/org/bouncycastle/crypto/hpke/HKDF.java index e42730dc1d..a9e0ef8d37 100644 --- a/core/src/main/java/org/bouncycastle/crypto/hpke/HKDF.java +++ b/core/src/main/java/org/bouncycastle/crypto/hpke/HKDF.java @@ -71,4 +71,30 @@ protected byte[] LabeledExpand(byte[] prk, byte[] suiteID, String label, byte[] return rv; } + + protected byte[] Extract(byte[] salt, byte[] ikm) + { + if (salt == null) + { + salt = new byte[hashLength]; + } + + return kdf.extractPRK(salt, ikm); + } + + protected byte[] Expand(byte[] prk, byte[] info, int L) + { + if (L > (1 << 16)) + { + throw new IllegalArgumentException("Expand length cannot be larger than 2^16"); + } + + kdf.init(HKDFParameters.skipExtractParameters(prk, info)); + + byte[] rv = new byte[L]; + + kdf.generateBytes(rv, 0, rv.length); + + return rv; + } } diff --git a/core/src/main/java/org/bouncycastle/crypto/hpke/HPKE.java b/core/src/main/java/org/bouncycastle/crypto/hpke/HPKE.java index b2f781bfe6..64f63c708a 100644 --- a/core/src/main/java/org/bouncycastle/crypto/hpke/HPKE.java +++ b/core/src/main/java/org/bouncycastle/crypto/hpke/HPKE.java @@ -40,7 +40,7 @@ public class HPKE private final short kemId; private final short kdfId; private final short aeadId; - private final DHKEM dhkem; + private final KEM kem; private final HKDF hkdf; short Nk; @@ -58,7 +58,7 @@ public HPKE(byte mode, short kemId, short kdfId, short aeadId) this.kdfId = kdfId; this.aeadId = aeadId; this.hkdf = new HKDF(kdfId); - this.dhkem = new DHKEM(kemId); + this.kem = new DHKEM(kemId); if (aeadId == aead_AES_GCM128) { Nk = 16; @@ -67,25 +67,12 @@ public HPKE(byte mode, short kemId, short kdfId, short aeadId) { Nk = 32; } + } public int getEncSize() { - switch (kemId) - { - case HPKE.kem_P256_SHA256: - return 65; - case HPKE.kem_P384_SHA348: - return 97; - case HPKE.kem_P521_SHA512: - return 133; - case HPKE.kem_X25519_SHA256: - return 32; - case HPKE.kem_X448_SHA512: - return 56; - default: - throw new IllegalArgumentException("invalid kem id"); - } + return kem.getEncryptionSize(); } public short getAeadId() { @@ -139,32 +126,32 @@ private HPKEContext keySchedule(byte mode, byte[] sharedSecret, byte[] info, byt public AsymmetricCipherKeyPair generatePrivateKey() { - return dhkem.GeneratePrivateKey(); + return kem.GeneratePrivateKey(); } public byte[] serializePublicKey(AsymmetricKeyParameter pk) { - return dhkem.SerializePublicKey(pk); + return kem.SerializePublicKey(pk); } public byte[] serializePrivateKey(AsymmetricKeyParameter sk) { - return dhkem.SerializePrivateKey(sk); + return kem.SerializePrivateKey(sk); } public AsymmetricKeyParameter deserializePublicKey(byte[] pkEncoded) { - return dhkem.DeserializePublicKey(pkEncoded); + return kem.DeserializePublicKey(pkEncoded); } public AsymmetricCipherKeyPair deserializePrivateKey(byte[] skEncoded, byte[] pkEncoded) { - return dhkem.DeserializePrivateKey(skEncoded, pkEncoded); + return kem.DeserializePrivateKey(skEncoded, pkEncoded); } public AsymmetricCipherKeyPair deriveKeyPair(byte[] ikm) { - return dhkem.DeriveKeyPair(ikm); + return kem.DeriveKeyPair(ikm); } public byte[][] sendExport(AsymmetricKeyParameter pkR, byte[] info, byte[] exporterContext, int L, @@ -271,10 +258,19 @@ public byte[] open(byte[] enc, AsymmetricCipherKeyPair skR, byte[] info, byte[] return ctx.open(aad, ct); } - public HPKEContextWithEncapsulation setupBaseS(AsymmetricKeyParameter pkR, byte[] info) { - byte[][] output = dhkem.Encap(pkR); // sharedSecret, enc + byte[][] output = kem.Encap(pkR); // sharedSecret, enc + HPKEContext ctx = keySchedule(mode_base, output[0], info, default_psk, default_psk_id); + + return new HPKEContextWithEncapsulation(ctx, output[1]); + } + + // Variant of setupBaseS() where caller can provide their own ephemeral key pair. + // This should only be used to validate test vectors. + public HPKEContextWithEncapsulation setupBaseS(AsymmetricKeyParameter pkR, byte[] info, AsymmetricCipherKeyPair kpE) + { + byte[][] output = kem.Encap(pkR, kpE); // sharedSecret, enc HPKEContext ctx = keySchedule(mode_base, output[0], info, default_psk, default_psk_id); return new HPKEContextWithEncapsulation(ctx, output[1]); @@ -282,13 +278,13 @@ public HPKEContextWithEncapsulation setupBaseS(AsymmetricKeyParameter pkR, byte[ public HPKEContext setupBaseR(byte[] enc, AsymmetricCipherKeyPair skR, byte[] info) { - byte[] sharedSecret = dhkem.Decap(enc, skR); + byte[] sharedSecret = kem.Decap(enc, skR); return keySchedule(mode_base, sharedSecret, info, default_psk, default_psk_id); } public HPKEContextWithEncapsulation SetupPSKS(AsymmetricKeyParameter pkR, byte[] info, byte[] psk, byte[] psk_id) { - byte[][] output = dhkem.Encap(pkR); // sharedSecret, enc + byte[][] output = kem.Encap(pkR); // sharedSecret, enc HPKEContext ctx = keySchedule(mode_psk, output[0], info, psk, psk_id); @@ -297,13 +293,13 @@ public HPKEContextWithEncapsulation SetupPSKS(AsymmetricKeyParameter pkR, byte[] public HPKEContext setupPSKR(byte[] enc, AsymmetricCipherKeyPair skR, byte[] info, byte[] psk, byte[] psk_id) { - byte[] sharedSecret = dhkem.Decap(enc, skR); + byte[] sharedSecret = kem.Decap(enc, skR); return keySchedule(mode_psk, sharedSecret, info, psk, psk_id); } public HPKEContextWithEncapsulation setupAuthS(AsymmetricKeyParameter pkR, byte[] info, AsymmetricCipherKeyPair skS) { - byte[][] output = dhkem.AuthEncap(pkR, skS); + byte[][] output = kem.AuthEncap(pkR, skS); HPKEContext ctx = keySchedule(mode_auth, output[0], info, default_psk, default_psk_id); return new HPKEContextWithEncapsulation(ctx, output[1]); @@ -311,13 +307,13 @@ public HPKEContextWithEncapsulation setupAuthS(AsymmetricKeyParameter pkR, byte[ public HPKEContext setupAuthR(byte[] enc, AsymmetricCipherKeyPair skR, byte[] info, AsymmetricKeyParameter pkS) { - byte[] sharedSecret = dhkem.AuthDecap(enc, skR, pkS); + byte[] sharedSecret = kem.AuthDecap(enc, skR, pkS); return keySchedule(mode_auth, sharedSecret, info, default_psk, default_psk_id); } public HPKEContextWithEncapsulation setupAuthPSKS(AsymmetricKeyParameter pkR, byte[] info, byte[] psk, byte[] psk_id, AsymmetricCipherKeyPair skS) { - byte[][] output = dhkem.AuthEncap(pkR, skS); + byte[][] output = kem.AuthEncap(pkR, skS); HPKEContext ctx = keySchedule(mode_auth_psk, output[0], info, psk, psk_id); return new HPKEContextWithEncapsulation(ctx, output[1]); @@ -325,7 +321,7 @@ public HPKEContextWithEncapsulation setupAuthPSKS(AsymmetricKeyParameter pkR, by public HPKEContext setupAuthPSKR(byte[] enc, AsymmetricCipherKeyPair skR, byte[] info, byte[] psk, byte[] psk_id, AsymmetricKeyParameter pkS) { - byte[] sharedSecret = dhkem.AuthDecap(enc, skR, pkS); + byte[] sharedSecret = kem.AuthDecap(enc, skR, pkS); return keySchedule(mode_auth_psk, sharedSecret, info, psk, psk_id); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/hpke/HPKEContext.java b/core/src/main/java/org/bouncycastle/crypto/hpke/HPKEContext.java index 0ef7961994..ad13208ff8 100644 --- a/core/src/main/java/org/bouncycastle/crypto/hpke/HPKEContext.java +++ b/core/src/main/java/org/bouncycastle/crypto/hpke/HPKEContext.java @@ -28,9 +28,31 @@ public byte[] seal(byte[] aad, byte[] message) return aead.seal(aad, message); } + public byte[] seal(byte[] aad, byte[] pt, int ptOffset, int ptLength) + throws InvalidCipherTextException + { + return aead.seal(aad, pt, ptOffset, ptLength); + } + public byte[] open(byte[] aad, byte[] ct) throws InvalidCipherTextException { return aead.open(aad, ct); } + + public byte[] open(byte[] aad, byte[] ct, int ctOffset, int ctLength) + throws InvalidCipherTextException + { + return aead.open(aad, ct, ctOffset, ctLength); + } + + public byte[] extract(byte[] salt, byte[] ikm) + { + return hkdf.Extract(salt, ikm); + } + + public byte[] expand(byte[] prk, byte[] info, int L) + { + return hkdf.Expand(prk, info, L); + } } diff --git a/core/src/main/java/org/bouncycastle/crypto/hpke/KEM.java b/core/src/main/java/org/bouncycastle/crypto/hpke/KEM.java new file mode 100644 index 0000000000..35bb58348f --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/hpke/KEM.java @@ -0,0 +1,35 @@ +package org.bouncycastle.crypto.hpke; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; + + +/** + * base class for HPKE KEM + */ +public abstract class KEM +{ + // Key Generation + abstract AsymmetricCipherKeyPair GeneratePrivateKey(); + abstract AsymmetricCipherKeyPair DeriveKeyPair(byte[] ikm); + + // Encapsulates a shared secret for a given public key and returns the encapsulated key and shared secret. + abstract byte[][] Encap(AsymmetricKeyParameter recipientPublicKey); + abstract byte[][] Encap(AsymmetricKeyParameter pkR, AsymmetricCipherKeyPair kpE); + abstract byte[][] AuthEncap(AsymmetricKeyParameter pkR, AsymmetricCipherKeyPair kpS); + + // Decapsulates the given encapsulated key using the recipient's key pair and returns the shared secret. + abstract byte[] Decap(byte[] encapsulatedKey, AsymmetricCipherKeyPair recipientKeyPair); + abstract byte[] AuthDecap(byte[] enc, AsymmetricCipherKeyPair kpR, AsymmetricKeyParameter pkS); + + // Serialization + abstract byte[] SerializePublicKey(AsymmetricKeyParameter publicKey); + abstract byte[] SerializePrivateKey(AsymmetricKeyParameter key); + + // Deserialization + abstract AsymmetricKeyParameter DeserializePublicKey(byte[] encodedPublicKey); + abstract AsymmetricCipherKeyPair DeserializePrivateKey(byte[] skEncoded, byte[] pkEncoded); + + abstract int getEncryptionSize(); + +} \ No newline at end of file diff --git a/core/src/main/java/org/bouncycastle/crypto/kems/ECIESKEMExtractor.java b/core/src/main/java/org/bouncycastle/crypto/kems/ECIESKEMExtractor.java index 234cc4355f..578078d6c8 100755 --- a/core/src/main/java/org/bouncycastle/crypto/kems/ECIESKEMExtractor.java +++ b/core/src/main/java/org/bouncycastle/crypto/kems/ECIESKEMExtractor.java @@ -119,6 +119,6 @@ public byte[] extractSecret(byte[] encapsulation) public int getEncapsulationLength() { - return (decKey.getParameters().getCurve().getFieldSize() / 8) * 2 + 1; + return decKey.getParameters().getCurve().getAffinePointEncodingLength(false); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/kems/ECIESKEMGenerator.java b/core/src/main/java/org/bouncycastle/crypto/kems/ECIESKEMGenerator.java index 1b356444ab..5aa57fef07 100755 --- a/core/src/main/java/org/bouncycastle/crypto/kems/ECIESKEMGenerator.java +++ b/core/src/main/java/org/bouncycastle/crypto/kems/ECIESKEMGenerator.java @@ -100,9 +100,9 @@ private ECMultiplier createBasePointMultiplier() public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey) { - if (!(recipientKey instanceof ECKeyParameters)) + if (!(recipientKey instanceof ECPublicKeyParameters)) { - throw new IllegalArgumentException("EC key required"); + throw new IllegalArgumentException("EC public key required"); } ECPublicKeyParameters ecPubKey = (ECPublicKeyParameters)recipientKey; diff --git a/core/src/main/java/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java b/core/src/main/java/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java index 9bf6cb0ef7..9087807357 100644 --- a/core/src/main/java/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java +++ b/core/src/main/java/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java @@ -92,7 +92,7 @@ public CBCBlockCipherMac( throw new IllegalArgumentException("MAC size must be multiple of 8"); } - this.cipher = new CBCBlockCipher(cipher); + this.cipher = CBCBlockCipher.newInstance(cipher); this.padding = padding; this.macSize = macSizeInBits / 8; diff --git a/core/src/main/java/org/bouncycastle/crypto/macs/CMac.java b/core/src/main/java/org/bouncycastle/crypto/macs/CMac.java index def64ded4a..2dccdf5d31 100644 --- a/core/src/main/java/org/bouncycastle/crypto/macs/CMac.java +++ b/core/src/main/java/org/bouncycastle/crypto/macs/CMac.java @@ -80,7 +80,7 @@ public CMac(BlockCipher cipher, int macSizeInBits) + (cipher.getBlockSize() * 8)); } - this.cipher = new CBCBlockCipher(cipher); + this.cipher = CBCBlockCipher.newInstance(cipher); this.macSize = macSizeInBits / 8; this.poly = lookupPoly(cipher.getBlockSize()); diff --git a/core/src/main/java/org/bouncycastle/crypto/macs/GMac.java b/core/src/main/java/org/bouncycastle/crypto/macs/GMac.java index b34f9ea52c..1660c67e78 100644 --- a/core/src/main/java/org/bouncycastle/crypto/macs/GMac.java +++ b/core/src/main/java/org/bouncycastle/crypto/macs/GMac.java @@ -4,11 +4,12 @@ import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Mac; -import org.bouncycastle.crypto.modes.GCMBlockCipher; +import org.bouncycastle.crypto.modes.GCMModeCipher; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; + /** * The GMAC specialisation of Galois/Counter mode (GCM) detailed in NIST Special Publication * 800-38D. @@ -18,7 +19,7 @@ */ public class GMac implements Mac { - private final GCMBlockCipher cipher; + private final GCMModeCipher cipher; private final int macSizeBits; /** @@ -29,7 +30,7 @@ public class GMac implements Mac * @param cipher * the cipher to be used in GCM mode to generate the MAC. */ - public GMac(final GCMBlockCipher cipher) + public GMac(final GCMModeCipher cipher) { // use of this confused flow analyser in some earlier JDKs this.cipher = cipher; @@ -45,7 +46,7 @@ public GMac(final GCMBlockCipher cipher) * @param cipher * the cipher to be used in GCM mode to generate the MAC. */ - public GMac(final GCMBlockCipher cipher, final int macSizeBits) + public GMac(final GCMModeCipher cipher, final int macSizeBits) { this.cipher = cipher; this.macSizeBits = macSizeBits; diff --git a/core/src/main/java/org/bouncycastle/crypto/macs/ISO9797Alg3Mac.java b/core/src/main/java/org/bouncycastle/crypto/macs/ISO9797Alg3Mac.java index 330b39e73d..436401ae3e 100644 --- a/core/src/main/java/org/bouncycastle/crypto/macs/ISO9797Alg3Mac.java +++ b/core/src/main/java/org/bouncycastle/crypto/macs/ISO9797Alg3Mac.java @@ -107,7 +107,7 @@ public ISO9797Alg3Mac( throw new IllegalArgumentException("cipher must be instance of DESEngine"); } - this.cipher = new CBCBlockCipher(cipher); + this.cipher = CBCBlockCipher.newInstance(cipher); this.padding = padding; this.macSize = macSizeInBits / 8; diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/CBCBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/CBCBlockCipher.java index 99feee5dee..130ff78d19 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/CBCBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/CBCBlockCipher.java @@ -36,6 +36,7 @@ public static CBCModeCipher newInstance(BlockCipher cipher) * Basic constructor. * * @param cipher the block cipher to be used as the basis of chaining. + * @deprecated use the CBCBlockCipher.newInstance() static method. */ public CBCBlockCipher( BlockCipher cipher) @@ -89,31 +90,23 @@ public void init( System.arraycopy(iv, 0, IV, 0, iv.length); - reset(); - - // if null it's an IV changed only. - if (ivParam.getParameters() != null) - { - cipher.init(encrypting, ivParam.getParameters()); - } - else if (oldEncrypting != encrypting) - { - throw new IllegalArgumentException("cannot change encrypting state without providing key."); - } + params = ivParam.getParameters(); } else { - reset(); + Arrays.fill(IV, (byte)0); + } - // if it's null, key is to be reused. - if (params != null) - { - cipher.init(encrypting, params); - } - else if (oldEncrypting != encrypting) - { - throw new IllegalArgumentException("cannot change encrypting state without providing key."); - } + reset(); + + // if null it's an IV changed only (key is to be reused). + if (params != null) + { + cipher.init(encrypting, params); + } + else if (oldEncrypting != encrypting) + { + throw new IllegalArgumentException("cannot change encrypting state without providing key."); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/CBCModeCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/CBCModeCipher.java index 8f919d5a13..682b5807c5 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/CBCModeCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/CBCModeCipher.java @@ -1,8 +1,15 @@ package org.bouncycastle.crypto.modes; +import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.MultiBlockCipher; public interface CBCModeCipher extends MultiBlockCipher { + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + BlockCipher getUnderlyingCipher(); } diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java index 0276377f2f..54092e172b 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java @@ -47,6 +47,7 @@ public static CCMModeCipher newInstance(BlockCipher cipher) * Basic constructor. * * @param c the block cipher to be used. + * @deprecated use the CCMBlockCipher.newInstance() static method. */ public CCMBlockCipher(BlockCipher c) { @@ -260,9 +261,19 @@ public int processPacket(byte[] in, int inOff, int inLen, byte[] output, int out if (q < 4) { int limitLen = 1 << (8 * q); - if (inLen >= limitLen) + + // no input length adjustment for encryption + int inputAdjustment = 0; + + if (!forEncryption) + { + // input includes 16 additional bytes: CCM flags and n+q values. + inputAdjustment = 1 /* flags */ + 15 /* n + q */; + } + + if ((inLen-inputAdjustment) >= limitLen) { - throw new IllegalStateException("CCM packet too large for choice of q."); + throw new IllegalStateException("CCM packet too large for choice of q"); } } @@ -270,7 +281,7 @@ public int processPacket(byte[] in, int inOff, int inLen, byte[] output, int out iv[0] = (byte)((q - 1) & 0x7); System.arraycopy(nonce, 0, iv, 1, nonce.length); - BlockCipher ctrCipher = new SICBlockCipher(cipher); + BlockCipher ctrCipher = SICBlockCipher.newInstance(cipher); ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv)); int outputLen; diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java index ae64111119..1bfaef9aac 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java @@ -41,6 +41,7 @@ public static CFBModeCipher newInstance(BlockCipher cipher, int blockSize) * @param cipher the block cipher to be used as the basis of the * feedback mode. * @param bitBlockSize the block size in bits (note: a multiple of 8) + * @deprecated use the equivalent CFBBlockCipher.newInstance() static method. */ public CFBBlockCipher( BlockCipher cipher, diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/CTRModeCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/CTRModeCipher.java new file mode 100644 index 0000000000..13fd97e74e --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/modes/CTRModeCipher.java @@ -0,0 +1,16 @@ +package org.bouncycastle.crypto.modes; + +import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.MultiBlockCipher; +import org.bouncycastle.crypto.SkippingStreamCipher; + +public interface CTRModeCipher + extends MultiBlockCipher, SkippingStreamCipher +{ + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + BlockCipher getUnderlyingCipher(); +} diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/CTSBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/CTSBlockCipher.java index ea80706792..af1fa46ded 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/CTSBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/CTSBlockCipher.java @@ -1,8 +1,8 @@ package org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.DefaultBufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.StreamBlockCipher; @@ -12,7 +12,7 @@ * be used to produce cipher text which is the same length as the plain text. */ public class CTSBlockCipher - extends BufferedBlockCipher + extends DefaultBufferedBlockCipher { private int blockSize; @@ -221,9 +221,9 @@ public int doFinal( buf[i] ^= block[i - blockSize]; } - if (cipher instanceof CBCBlockCipher) + if (cipher instanceof CBCModeCipher) { - BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher(); + BlockCipher c = ((CBCModeCipher)cipher).getUnderlyingCipher(); c.processBlock(buf, blockSize, out, outOff); } @@ -250,9 +250,9 @@ public int doFinal( if (bufOff > blockSize) { - if (cipher instanceof CBCBlockCipher) + if (cipher instanceof CBCModeCipher) { - BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher(); + BlockCipher c = ((CBCModeCipher)cipher).getUnderlyingCipher(); c.processBlock(buf, 0, block, 0); } diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/ChaCha20Poly1305.java b/core/src/main/java/org/bouncycastle/crypto/modes/ChaCha20Poly1305.java index fdcb48bef7..2425dec220 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/ChaCha20Poly1305.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/ChaCha20Poly1305.java @@ -125,7 +125,7 @@ else if (params instanceof ParametersWithIV) } else { - if (KEY_SIZE != initKeyParam.getKey().length) + if (KEY_SIZE != initKeyParam.getKeyLength()) { throw new IllegalArgumentException("Key must be 256 bits"); } @@ -148,7 +148,7 @@ else if (params instanceof ParametersWithIV) if (null != initKeyParam) { - System.arraycopy(initKeyParam.getKey(), 0, key, 0, KEY_SIZE); + initKeyParam.copyTo(key, 0, KEY_SIZE); } System.arraycopy(initNonce, 0, nonce, 0, NONCE_SIZE); diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/EAXBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/EAXBlockCipher.java index 7ec6fdf4fb..6eb5ca4fb1 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/EAXBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/EAXBlockCipher.java @@ -33,7 +33,7 @@ public class EAXBlockCipher private static final byte cTAG = 0x2; - private SICBlockCipher cipher; + private CTRModeCipher cipher; private boolean forEncryption; @@ -64,7 +64,7 @@ public EAXBlockCipher(BlockCipher cipher) macBlock = new byte[blockSize]; associatedTextMac = new byte[mac.getMacSize()]; nonceMac = new byte[mac.getMacSize()]; - this.cipher = new SICBlockCipher(cipher); + this.cipher = SICBlockCipher.newInstance(cipher); } public String getAlgorithmName() diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java index 2946c8d4da..017847ef8d 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java @@ -74,11 +74,24 @@ public static GCMModeCipher newInstance(BlockCipher cipher, GCMMultiplier m) return new GCMBlockCipher(cipher, m); } + /** + * Base constructor - GCM mode over base cipher c. + * + * @param c the base cipher. + * @deprecated use the GCMBlockCipher.newInstance() static method. + */ public GCMBlockCipher(BlockCipher c) { this(c, null); } + /** + * Base constructor - GCM mode over base cipher c over base multiplier m. + * + * @param c the base cipher. + * @param m the GCM multiplier to use. + * @deprecated use the CBCBlockCipher.newInstance() static method. + */ public GCMBlockCipher(BlockCipher c, GCMMultiplier m) { if (c.getBlockSize() != BLOCK_SIZE) diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/GCMSIVBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/GCMSIVBlockCipher.java index bb82e58e12..404629bc4a 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/GCMSIVBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/GCMSIVBlockCipher.java @@ -142,7 +142,7 @@ public class GCMSIVBlockCipher */ public GCMSIVBlockCipher() { - this(new AESEngine()); + this(AESEngine.newInstance()); } /** @@ -217,8 +217,8 @@ else if (cipherParameters instanceof ParametersWithIV) /* Check keysize */ if (myKey == null - || (myKey.getKey().length != BUFLEN - && myKey.getKey().length != (BUFLEN << 1))) + || (myKey.getKeyLength() != BUFLEN + && myKey.getKeyLength() != (BUFLEN << 1))) { throw new IllegalArgumentException("Invalid key"); } @@ -766,7 +766,7 @@ private void deriveKeys(final KeyParameter pKey) final byte[] myIn = new byte[BUFLEN]; final byte[] myOut = new byte[BUFLEN]; final byte[] myResult = new byte[BUFLEN]; - final byte[] myEncKey = new byte[pKey.getKey().length]; + final byte[] myEncKey = new byte[pKey.getKeyLength()]; /* Prepare for encryption */ System.arraycopy(theNonce, 0, myIn, BUFLEN - NONCELEN, NONCELEN); diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/KXTSBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/KXTSBlockCipher.java index 81c9424134..2062fea183 100755 --- a/core/src/main/java/org/bouncycastle/crypto/modes/KXTSBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/KXTSBlockCipher.java @@ -1,9 +1,9 @@ package org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.DefaultBufferedBlockCipher; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Pack; @@ -12,7 +12,7 @@ * Implementation of DSTU7624 XTS mode */ public class KXTSBlockCipher - extends BufferedBlockCipher + extends DefaultBufferedBlockCipher { /* * Constants for GF(2^m) operations @@ -126,13 +126,13 @@ public int processBytes(byte[] input, int inOff, int len, byte[] output, int out for (int pos = 0; pos < len; pos += blockSize) { - processBlock(input, inOff + pos, output, outOff + pos); + processBlocks(input, inOff + pos, output, outOff + pos); } return len; } - private void processBlock(byte[] input, int inOff, byte[] output, int outOff) + private void processBlocks(byte[] input, int inOff, byte[] output, int outOff) { /* * A somewhat arbitrary limit of 2^32 - 1 blocks diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/NISTCTSBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/NISTCTSBlockCipher.java index e15cbd4468..e13c6ea9a5 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/NISTCTSBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/NISTCTSBlockCipher.java @@ -5,8 +5,8 @@ package org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.DefaultBufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.OutputLengthException; @@ -18,7 +18,7 @@ *

    */ public class NISTCTSBlockCipher - extends BufferedBlockCipher + extends DefaultBufferedBlockCipher { public static final int CS1 = 1; public static final int CS2 = 2; @@ -38,7 +38,7 @@ public NISTCTSBlockCipher( BlockCipher cipher) { this.type = type; - this.cipher = new CBCBlockCipher(cipher); + this.cipher = CBCBlockCipher.newInstance(cipher); blockSize = cipher.getBlockSize(); @@ -272,9 +272,9 @@ public int doFinal( { if (this.type == CS3 || (this.type == CS2 && ((buf.length - bufOff) % blockSize) != 0)) { - if (cipher instanceof CBCBlockCipher) + if (cipher instanceof CBCModeCipher) { - BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher(); + BlockCipher c = ((CBCModeCipher)cipher).getUnderlyingCipher(); c.processBlock(buf, 0, block, 0); } @@ -295,7 +295,7 @@ public int doFinal( } else { - BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher(); + BlockCipher c = ((CBCModeCipher)cipher).getUnderlyingCipher(); c.processBlock(buf, bufOff - blockSize, lastBlock, 0); diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/OCBBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/OCBBlockCipher.java index 42667197e1..93854eadc1 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/OCBBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/OCBBlockCipher.java @@ -11,6 +11,8 @@ import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Bytes; +import org.bouncycastle.util.Longs; /** * An implementation of RFC 7253 on The OCB @@ -21,7 +23,7 @@ *

    * Text reproduced below. *
    - * Phillip Rogaway Sat, 27 February 2021 02:46 UTCShow header + * Phillip Rogaway >rogaway@cs.ucdavis.edu< Sat, 27 February 2021 02:46 UTCShow header * * I can confirm that I have abandoned all OCB patents * and placed into the public domain all OCB-related IP of mine. @@ -570,18 +572,7 @@ protected static void OCB_extend(byte[] block, int pos) protected static int OCB_ntz(long x) { - if (x == 0) - { - return 64; - } - - int n = 0; - while ((x & 1L) == 0L) - { - ++n; - x >>>= 1; - } - return n; + return Longs.numberOfTrailingZeros(x); } protected static int shiftLeft(byte[] block, byte[] output) @@ -599,9 +590,6 @@ protected static int shiftLeft(byte[] block, byte[] output) protected static void xor(byte[] block, byte[] val) { - for (int i = 15; i >= 0; --i) - { - block[i] ^= val[i]; - } + Bytes.xorTo(16, val, block); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/OldCTSBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/OldCTSBlockCipher.java index 30aed5b4fe..13ba147753 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/OldCTSBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/OldCTSBlockCipher.java @@ -1,8 +1,8 @@ package org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.DefaultBufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.OutputLengthException; @@ -15,7 +15,7 @@ *

    */ public class OldCTSBlockCipher - extends BufferedBlockCipher + extends DefaultBufferedBlockCipher { private int blockSize; diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/PaddedBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/PaddedBlockCipher.java index 94068087d4..335a147c37 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/PaddedBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/PaddedBlockCipher.java @@ -1,8 +1,8 @@ package org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.DefaultBufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.OutputLengthException; @@ -16,7 +16,7 @@ * @deprecated use org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher instead. */ public class PaddedBlockCipher - extends BufferedBlockCipher + extends DefaultBufferedBlockCipher { /** * Create a buffered block cipher with, or without, padding. diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java index 3d672c0cc9..95f386b9a5 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java @@ -4,7 +4,6 @@ import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.OutputLengthException; -import org.bouncycastle.crypto.SkippingStreamCipher; import org.bouncycastle.crypto.StreamBlockCipher; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; @@ -16,7 +15,7 @@ */ public class SICBlockCipher extends StreamBlockCipher - implements SkippingStreamCipher + implements CTRModeCipher { private final BlockCipher cipher; private final int blockSize; @@ -26,10 +25,21 @@ public class SICBlockCipher private byte[] counterOut; private int byteCount; + /** + * Return a new SIC/CTR mode cipher based on the passed in base cipher + * + * @param cipher the base cipher for the SIC/CTR mode. + */ + public static CTRModeCipher newInstance(BlockCipher cipher) + { + return new SICBlockCipher(cipher); + } + /** * Basic constructor. * * @param c the block cipher to be used. + * @deprecated use newInstance() method. */ public SICBlockCipher(BlockCipher c) { @@ -112,7 +122,7 @@ public int processBlock(byte[] in, int inOff, byte[] out, int outOff) { out[outOff + i] = (byte)(in[inOff + i] ^ counterOut[i]); } - incrementCounterChecked(); + incrementCounter(); return blockSize; } @@ -131,8 +141,11 @@ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) for (int i = 0; i < len; ++i) { byte next; + if (byteCount == 0) { + checkLastIncrement(); + cipher.processBlock(counter, 0, counterOut, 0); next = (byte)(in[inOff + i] ^ counterOut[byteCount++]); } @@ -142,7 +155,7 @@ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) if (byteCount == counter.length) { byteCount = 0; - incrementCounterChecked(); + incrementCounter(); } } out[outOff + i] = next; @@ -156,6 +169,8 @@ protected byte calculateByte(byte in) { if (byteCount == 0) { + checkLastIncrement(); + cipher.processBlock(counter, 0, counterOut, 0); return (byte)(counterOut[byteCount++] ^ in); @@ -166,8 +181,7 @@ protected byte calculateByte(byte in) if (byteCount == counter.length) { byteCount = 0; - - incrementCounterChecked(); + incrementCounter(); } return rv; @@ -178,7 +192,7 @@ private void checkCounter() // if the IV is the same as the blocksize we assume the user knows what they are doing if (IV.length < blockSize) { - for (int i = 0; i != IV.length; i++) + for (int i = IV.length - 1; i >= 0; i--) { if (counter[i] != IV[i]) { @@ -188,23 +202,26 @@ private void checkCounter() } } - private void incrementCounterChecked() + private void checkLastIncrement() { - int i = counter.length; - while (--i >= 0) + // if the IV is the same as the blocksize we assume the user knows what they are doing + if (IV.length < blockSize) { - if (++counter[i] != 0) + if (counter[IV.length - 1] != IV[IV.length - 1]) { - break; + throw new IllegalStateException("Counter in CTR/SIC mode out of range."); } } + } - if (i < IV.length) + private void incrementCounter() + { + int i = counter.length; + while (--i >= 0) { - // if the IV is the same as the blocksize we assume the user knows what they are doing - if (IV.length < blockSize) + if (++counter[i] != 0) { - throw new IllegalStateException("Counter in CTR/SIC mode out of range."); + break; } } } @@ -224,10 +241,8 @@ private void incrementCounterAt(int pos) private void incrementCounter(int offSet) { byte old = counter[counter.length - 1]; - - counter[counter.length - 1] += offSet; - - if (old != 0 && counter[counter.length - 1] < old) + counter[counter.length - 1] += (byte) offSet; + if ((old & 0xff) + offSet > 255) { incrementCounterAt(1); } diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/kgcm/KGCMUtil_128.java b/core/src/main/java/org/bouncycastle/crypto/modes/kgcm/KGCMUtil_128.java index 6a7befd948..2cc5647590 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/kgcm/KGCMUtil_128.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/kgcm/KGCMUtil_128.java @@ -4,9 +4,9 @@ /** * Utilities for the GF(2^m) field with corresponding extension polynomial: - * - * GF (2^128) -> x^128 + x^7 + x^2 + x + 1 - * + *
    + * GF (2^128) -> x^128 + x^7 + x^2 + x + 1
    + * 
    * The representation is little-endian arrays of 64-bit words */ public class KGCMUtil_128 diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/kgcm/KGCMUtil_256.java b/core/src/main/java/org/bouncycastle/crypto/modes/kgcm/KGCMUtil_256.java index fffd204257..4be3e4df4a 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/kgcm/KGCMUtil_256.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/kgcm/KGCMUtil_256.java @@ -4,9 +4,9 @@ /** * Utilities for the GF(2^m) field with corresponding extension polynomial: - * - * GF (2^256) -> x^256 + x^10 + x^5 + x^2 + 1 - * + *
    + * GF (2^256) -> x^256 + x^10 + x^5 + x^2 + 1
    + * 
    * The representation is little-endian arrays of 64-bit words */ public class KGCMUtil_256 diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/kgcm/KGCMUtil_512.java b/core/src/main/java/org/bouncycastle/crypto/modes/kgcm/KGCMUtil_512.java index 1a25908393..4a9ba69086 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/kgcm/KGCMUtil_512.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/kgcm/KGCMUtil_512.java @@ -4,9 +4,9 @@ /** * Utilities for the GF(2^m) field with corresponding extension polynomial: - * - * GF (2^512) -> x^512 + x^8 + x^5 + x^2 + 1 - * + *
    + * GF (2^512) -> x^512 + x^8 + x^5 + x^2 + 1
    + * 
    * The representation is little-endian arrays of 64-bit words */ public class KGCMUtil_512 diff --git a/core/src/main/java/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java index d5928f7094..28ec78bff9 100644 --- a/core/src/main/java/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java @@ -1,9 +1,9 @@ package org.bouncycastle.crypto.paddings; import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.DefaultBufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.ParametersWithRandom; @@ -16,7 +16,7 @@ * The default padding mechanism used is the one outlined in PKCS5/PKCS7. */ public class PaddedBufferedBlockCipher - extends BufferedBlockCipher + extends DefaultBufferedBlockCipher { BlockCipherPadding padding; diff --git a/core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java b/core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java index 1394884846..a36f1d8e13 100644 --- a/core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java +++ b/core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java @@ -3,7 +3,9 @@ import java.math.BigInteger; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X9ECParameters; +import org.bouncycastle.crypto.ec.CustomNamedCurves; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; @@ -11,6 +13,16 @@ public class ECNamedDomainParameters extends ECDomainParameters { + public static ECNamedDomainParameters lookup(ASN1ObjectIdentifier name) + { + X9ECParameters x9 = CustomNamedCurves.getByOID(name); + if (x9 == null) + { + x9 = ECNamedCurveTable.getByOID(name); + } + return new ECNamedDomainParameters(name, x9); + } + private ASN1ObjectIdentifier name; public ECNamedDomainParameters(ASN1ObjectIdentifier name, ECCurve curve, ECPoint G, BigInteger n) diff --git a/core/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java b/core/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java index 5c4fe0e0b1..e16399595a 100644 --- a/core/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java +++ b/core/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java @@ -1,6 +1,7 @@ package org.bouncycastle.crypto.params; import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.util.Arrays; public class KeyParameter implements CipherParameters @@ -18,13 +19,38 @@ public KeyParameter( int keyOff, int keyLen) { - this.key = new byte[keyLen]; + this(keyLen); System.arraycopy(key, keyOff, this.key, 0, keyLen); } + private KeyParameter(int length) + { + this.key = new byte[length]; + } + + public void copyTo(byte[] buf, int off, int len) + { + if (key.length != len) + throw new IllegalArgumentException("len"); + + System.arraycopy(key, 0, buf, off, len); + } + public byte[] getKey() { return key; } + + public int getKeyLength() + { + return key.length; + } + + public KeyParameter reverse() + { + KeyParameter reversed = new KeyParameter(key.length); + Arrays.reverse(this.key, reversed.key); + return reversed; + } } diff --git a/core/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java b/core/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java index 65b0b84ee4..c3f6a60f65 100644 --- a/core/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java +++ b/core/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java @@ -20,8 +20,6 @@ public class RSAKeyParameters + "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f", 16); - private static final BigInteger ONE = BigInteger.valueOf(1); - private BigInteger modulus; private BigInteger exponent; @@ -53,7 +51,19 @@ public RSAKeyParameters( this.exponent = exponent; } - private BigInteger validate(BigInteger modulus, boolean isInternal) + private static boolean hasAnySmallFactors(BigInteger modulus) + { + BigInteger M = modulus, X = SMALL_PRIMES_PRODUCT; + if (modulus.bitLength() < SMALL_PRIMES_PRODUCT.bitLength()) + { + M = SMALL_PRIMES_PRODUCT; + X = modulus; + } + + return !BigIntegers.modOddIsCoprimeVar(M, X); + } + + private static BigInteger validate(BigInteger modulus, boolean isInternal) { if (isInternal) { @@ -74,15 +84,13 @@ private BigInteger validate(BigInteger modulus, boolean isInternal) return modulus; } - int maxBitLength = Properties.asInteger("org.bouncycastle.rsa.max_size", 15360); - - int modBitLength = modulus.bitLength(); - if (maxBitLength < modBitLength) + int maxBitLength = Properties.asInteger("org.bouncycastle.rsa.max_size", 16384); + if (maxBitLength < modulus.bitLength()) { - throw new IllegalArgumentException("modulus value out of range"); + throw new IllegalArgumentException("RSA modulus out of range"); } - if (!modulus.gcd(SMALL_PRIMES_PRODUCT).equals(ONE)) + if (hasAnySmallFactors(modulus)) { throw new IllegalArgumentException("RSA modulus has a small prime factor"); } @@ -92,7 +100,8 @@ private BigInteger validate(BigInteger modulus, boolean isInternal) if (iterations > 0) { - Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, CryptoServicesRegistrar.getSecureRandom(), iterations); + Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, CryptoServicesRegistrar.getSecureRandom(), + iterations); if (!mr.isProvablyComposite()) { throw new IllegalArgumentException("RSA modulus is not composite"); diff --git a/core/src/main/java/org/bouncycastle/crypto/parsers/ECIESPublicKeyParser.java b/core/src/main/java/org/bouncycastle/crypto/parsers/ECIESPublicKeyParser.java index b6b6e857dc..8e58ce6a2f 100644 --- a/core/src/main/java/org/bouncycastle/crypto/parsers/ECIESPublicKeyParser.java +++ b/core/src/main/java/org/bouncycastle/crypto/parsers/ECIESPublicKeyParser.java @@ -1,5 +1,6 @@ package org.bouncycastle.crypto.parsers; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; @@ -7,6 +8,7 @@ import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.io.Streams; public class ECIESPublicKeyParser @@ -22,10 +24,14 @@ public ECIESPublicKeyParser(ECDomainParameters ecParams) public AsymmetricKeyParameter readKey(InputStream stream) throws IOException { - byte[] V; - int first = stream.read(); + int first = stream.read(); + if (first < 0) + { + throw new EOFException(); + } // Decode the public ephemeral key + boolean compressed; switch (first) { case 0x00: // infinity @@ -33,22 +39,30 @@ public AsymmetricKeyParameter readKey(InputStream stream) case 0x02: // compressed case 0x03: // Byte length calculated as in ECPoint.getEncoded(); - V = new byte[1 + (ecParams.getCurve().getFieldSize()+7)/8]; + compressed = true; break; case 0x04: // uncompressed or case 0x06: // hybrid case 0x07: // Byte length calculated as in ECPoint.getEncoded(); - V = new byte[1 + 2*((ecParams.getCurve().getFieldSize()+7)/8)]; + compressed = false; break; default: throw new IOException("Sender's public key has invalid point encoding 0x" + Integer.toString(first, 16)); } + ECCurve curve = ecParams.getCurve(); + int encodingLength = curve.getAffinePointEncodingLength(compressed); + byte[] V = new byte[encodingLength]; V[0] = (byte)first; - Streams.readFully(stream, V, 1, V.length - 1); - return new ECPublicKeyParameters(ecParams.getCurve().decodePoint(V), ecParams); + int readLength = encodingLength - 1; + if (Streams.readFully(stream, V, 1, readLength) != readLength) + { + throw new EOFException(); + } + + return new ECPublicKeyParameters(curve.decodePoint(V), ecParams); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/prng/drbg/CTRSP800DRBG.java b/core/src/main/java/org/bouncycastle/crypto/prng/drbg/CTRSP800DRBG.java index 6e14f67f95..6dbea81bc5 100644 --- a/core/src/main/java/org/bouncycastle/crypto/prng/drbg/CTRSP800DRBG.java +++ b/core/src/main/java/org/bouncycastle/crypto/prng/drbg/CTRSP800DRBG.java @@ -4,6 +4,7 @@ import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.prng.EntropySource; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Bytes; import org.bouncycastle.util.encoders.Hex; /** @@ -109,7 +110,7 @@ private void CTR_DRBG_Update(byte[] seed, byte[] key, byte[] v) ++i; } - XOR(temp, seed, temp, 0); + Bytes.xorTo(seed.length, seed, temp); System.arraycopy(temp, 0, key, 0, key.length); System.arraycopy(temp, key.length, v, 0, v.length); @@ -126,14 +127,6 @@ private void CTR_DRBG_Reseed_algorithm(byte[] additionalInput) _reseedCounter = 1; } - private void XOR(byte[] out, byte[] a, byte[] b, int bOff) - { - for (int i=0; i< out.length; i++) - { - out[i] = (byte)(a[i] ^ b[i+bOff]); - } - } - private void addOneTo(byte[] longer) { int carry = 1; @@ -294,11 +287,11 @@ private byte[] Block_Cipher_df(byte[] inputString, int bitLength) */ private void BCC(byte[] bccOut, byte[] k, byte[] iV, byte[] data) { - int outlen = _engine.getBlockSize(); - byte[] chainingValue = new byte[outlen]; // initial values = 0 - int n = data.length / outlen; + int blockSize = _engine.getBlockSize(); + byte[] chainingValue = new byte[blockSize]; // initial values = 0 + int n = data.length / blockSize; - byte[] inputBlock = new byte[outlen]; + byte[] inputBlock = new byte[blockSize]; _engine.init(true, new KeyParameter(expandKey(k))); @@ -306,7 +299,7 @@ private void BCC(byte[] bccOut, byte[] k, byte[] iV, byte[] data) for (int i = 0; i < n; i++) { - XOR(inputBlock, chainingValue, data, i*outlen); + Bytes.xor(blockSize, chainingValue, 0, data, i * blockSize, inputBlock, 0); _engine.processBlock(inputBlock, 0, chainingValue, 0); } diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java b/core/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java index 7297895586..c962d1cc1b 100644 --- a/core/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java +++ b/core/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java @@ -74,7 +74,7 @@ public void init( this.key = (ECPublicKeyParameters)param; } - CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("DSTU4145", key, forSigning)); + CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("ECDSA", key, forSigning)); this.random = initSecureRandom(forSigning && !kCalculator.isDeterministic(), providedRandom); } diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java b/core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java index 3101431e7c..e064308a1a 100644 --- a/core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java +++ b/core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java @@ -20,7 +20,7 @@ import org.bouncycastle.util.BigIntegers; /** - * GOST R 34.10-2001 Signature Algorithm + * GOST R 34.10-2001 and GOST R 34.10-2012 Signature Algorithm */ public class ECGOST3410Signer implements DSAExt diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/Ed25519Signer.java b/core/src/main/java/org/bouncycastle/crypto/signers/Ed25519Signer.java index 22718758ad..2506a27456 100644 --- a/core/src/main/java/org/bouncycastle/crypto/signers/Ed25519Signer.java +++ b/core/src/main/java/org/bouncycastle/crypto/signers/Ed25519Signer.java @@ -7,6 +7,7 @@ import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; +import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.math.ec.rfc8032.Ed25519; import org.bouncycastle.util.Arrays; @@ -26,7 +27,10 @@ public Ed25519Signer() public void init(boolean forSigning, CipherParameters parameters) { this.forSigning = forSigning; - + if (parameters instanceof ParametersWithRandom) + { + parameters = ((ParametersWithRandom)parameters).getParameters(); + } if (forSigning) { this.privateKey = (Ed25519PrivateKeyParameters)parameters; diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/Ed448Signer.java b/core/src/main/java/org/bouncycastle/crypto/signers/Ed448Signer.java index ccd5af0a63..e60ae6fb28 100644 --- a/core/src/main/java/org/bouncycastle/crypto/signers/Ed448Signer.java +++ b/core/src/main/java/org/bouncycastle/crypto/signers/Ed448Signer.java @@ -7,6 +7,7 @@ import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.Ed448PrivateKeyParameters; import org.bouncycastle.crypto.params.Ed448PublicKeyParameters; +import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.math.ec.rfc8032.Ed448; import org.bouncycastle.util.Arrays; @@ -33,7 +34,10 @@ public Ed448Signer(byte[] context) public void init(boolean forSigning, CipherParameters parameters) { this.forSigning = forSigning; - + if (parameters instanceof ParametersWithRandom) + { + parameters = ((ParametersWithRandom)parameters).getParameters(); + } if (forSigning) { this.privateKey = (Ed448PrivateKeyParameters)parameters; diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java b/core/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java index 1ad57e5f7c..3ab03bf883 100644 --- a/core/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java +++ b/core/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java @@ -15,8 +15,6 @@ public class HMacDSAKCalculator implements DSAKCalculator { - private static final BigInteger ZERO = BigInteger.valueOf(0); - private final HMac hMac; private final byte[] K; private final byte[] V; @@ -31,8 +29,10 @@ public class HMacDSAKCalculator public HMacDSAKCalculator(Digest digest) { this.hMac = new HMac(digest); - this.V = new byte[hMac.getMacSize()]; - this.K = new byte[hMac.getMacSize()]; + + int macSize = hMac.getMacSize(); + this.V = new byte[macSize]; + this.K = new byte[macSize]; } public boolean isDeterministic() @@ -49,27 +49,19 @@ public void init(BigInteger n, BigInteger d, byte[] message) { this.n = n; - Arrays.fill(V, (byte)0x01); - Arrays.fill(K, (byte)0); - - int size = BigIntegers.getUnsignedByteLength(n); - byte[] x = new byte[size]; - byte[] dVal = BigIntegers.asUnsignedByteArray(d); - - System.arraycopy(dVal, 0, x, x.length - dVal.length, dVal.length); - - byte[] m = new byte[size]; - BigInteger mInt = bitsToInt(message); - if (mInt.compareTo(n) >= 0) { mInt = mInt.subtract(n); } - byte[] mVal = BigIntegers.asUnsignedByteArray(mInt); + int size = BigIntegers.getUnsignedByteLength(n); + + byte[] x = BigIntegers.asUnsignedByteArray(size, d); + byte[] m = BigIntegers.asUnsignedByteArray(size, mInt); - System.arraycopy(mVal, 0, m, m.length - mVal.length, mVal.length); + Arrays.fill(K, (byte)0x00); + Arrays.fill(V, (byte)0x01); hMac.init(new KeyParameter(K)); @@ -78,26 +70,21 @@ public void init(BigInteger n, BigInteger d, byte[] message) hMac.update(x, 0, x.length); hMac.update(m, 0, m.length); initAdditionalInput0(hMac); - hMac.doFinal(K, 0); hMac.init(new KeyParameter(K)); - hMac.update(V, 0, V.length); - hMac.doFinal(V, 0); hMac.update(V, 0, V.length); hMac.update((byte)0x01); hMac.update(x, 0, x.length); hMac.update(m, 0, m.length); - + initAdditionalInput1(hMac); hMac.doFinal(K, 0); hMac.init(new KeyParameter(K)); - hMac.update(V, 0, V.length); - hMac.doFinal(V, 0); } @@ -112,7 +99,6 @@ public BigInteger nextK() while (tOff < t.length) { hMac.update(V, 0, V.length); - hMac.doFinal(V, 0); int len = Math.min(t.length - tOff, V.length); @@ -122,25 +108,24 @@ public BigInteger nextK() BigInteger k = bitsToInt(t); - if (k.compareTo(ZERO) > 0 && k.compareTo(n) < 0) + if (k.signum() > 0 && k.compareTo(n) < 0) { return k; } hMac.update(V, 0, V.length); hMac.update((byte)0x00); - hMac.doFinal(K, 0); hMac.init(new KeyParameter(K)); - hMac.update(V, 0, V.length); - hMac.doFinal(V, 0); } } /** + * Supply additional input to HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1)). + *

    * RFC 6979 3.6. Additional data may be added to the input of HMAC [..]. A use case may be a protocol that * requires a non-deterministic signature algorithm on a system that does not have access to a * high-quality random source. It suffices that the additional data [..] is non-repeating (e.g., a @@ -156,15 +141,27 @@ protected void initAdditionalInput0(HMac hmac0) { } + /** + * Supply additional input to HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1)). + *

    + * Refer to comments for {@link #initAdditionalInput0(HMac)}. + * + * @param hmac1 the {@link HMac} to which the additional input should be added. + */ + protected void initAdditionalInput1(HMac hmac1) + { + } + private BigInteger bitsToInt(byte[] t) { - BigInteger v = new BigInteger(1, t); + int blen = t.length * 8; + int qlen = n.bitLength(); - if (t.length * 8 > n.bitLength()) + BigInteger v = BigIntegers.fromUnsignedByteArray(t); + if (blen > qlen) { - v = v.shiftRight(t.length * 8 - n.bitLength()); + v = v.shiftRight(blen - qlen); } - return v; } } diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/PSSSigner.java b/core/src/main/java/org/bouncycastle/crypto/signers/PSSSigner.java index c463150dbe..42193c72e3 100644 --- a/core/src/main/java/org/bouncycastle/crypto/signers/PSSSigner.java +++ b/core/src/main/java/org/bouncycastle/crypto/signers/PSSSigner.java @@ -10,7 +10,7 @@ import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.Xof; -import org.bouncycastle.crypto.digests.NullDigest; +import org.bouncycastle.crypto.digests.Prehash; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSABlindingParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; @@ -27,16 +27,22 @@ public class PSSSigner { public static final byte TRAILER_IMPLICIT = (byte)0xBC; + public static PSSSigner createRawSigner(AsymmetricBlockCipher cipher, Digest digest) + { + return new PSSSigner(cipher, Prehash.forDigest(digest), digest, digest, digest.getDigestSize(), + TRAILER_IMPLICIT); + } + public static PSSSigner createRawSigner(AsymmetricBlockCipher cipher, Digest contentDigest, Digest mgfDigest, int sLen, byte trailer) { - return new PSSSigner(cipher, new NullDigest(), contentDigest, mgfDigest, sLen, trailer); + return new PSSSigner(cipher, Prehash.forDigest(contentDigest), contentDigest, mgfDigest, sLen, trailer); } public static PSSSigner createRawSigner(AsymmetricBlockCipher cipher, Digest contentDigest, Digest mgfDigest, byte[] salt, byte trailer) { - return new PSSSigner(cipher, new NullDigest(), contentDigest, mgfDigest, salt, trailer); + return new PSSSigner(cipher, Prehash.forDigest(contentDigest), contentDigest, mgfDigest, salt, trailer); } private Digest contentDigest1; diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/SM2Signer.java b/core/src/main/java/org/bouncycastle/crypto/signers/SM2Signer.java index b2a7049e3e..eefddc7d79 100644 --- a/core/src/main/java/org/bouncycastle/crypto/signers/SM2Signer.java +++ b/core/src/main/java/org/bouncycastle/crypto/signers/SM2Signer.java @@ -29,10 +29,18 @@ public class SM2Signer implements Signer, ECConstants { + private static final class State + { + static final int UNINITIALIZED = 0; + static final int INIT = 1; + static final int DATA = 2; + } + private final DSAKCalculator kCalculator = new RandomDSAKCalculator(); private final Digest digest; private final DSAEncoding encoding; + private int state = State.UNINITIALIZED; private ECDomainParameters ecParams; private ECPoint pubPoint; private ECKeyParameters ecKey; @@ -117,23 +125,29 @@ public void init(boolean forSigning, CipherParameters param) CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("ECNR", ecKey, forSigning)); + digest.reset(); z = getZ(userID); - - digest.update(z, 0, z.length); + this.state = State.INIT; } public void update(byte b) { + checkData(); + digest.update(b); } public void update(byte[] in, int off, int len) { + checkData(); + digest.update(in, off, len); } public boolean verifySignature(byte[] signature) { + checkData(); + try { BigInteger[] rs = encoding.decode(ecParams.getN(), signature); @@ -143,23 +157,35 @@ public boolean verifySignature(byte[] signature) catch (Exception e) { } + finally + { + reset(); + } return false; } public void reset() { - digest.reset(); - - if (z != null) + switch (state) { - digest.update(z, 0, z.length); + case State.INIT: + return; + case State.DATA: + break; + default: + throw new IllegalStateException("SM2Signer needs to be initialized"); } + + digest.reset(); + this.state = State.INIT; } public byte[] generateSignature() throws CryptoException { + checkData(); + byte[] eHash = digestDoFinal(); BigInteger n = ecParams.getN(); @@ -204,6 +230,10 @@ public byte[] generateSignature() { throw new CryptoException("unable to encode signature: " + ex.getMessage(), ex); } + finally + { + reset(); + } } private boolean verifySignature(BigInteger r, BigInteger s) @@ -250,20 +280,31 @@ private boolean verifySignature(BigInteger r, BigInteger s) return expectedR.equals(r); } + private void checkData() + { + switch (state) + { + case State.INIT: + break; + case State.DATA: + return; + default: + throw new IllegalStateException("SM2Signer needs to be initialized"); + } + + digest.update(z, 0, z.length); + this.state = State.DATA; + } + private byte[] digestDoFinal() { byte[] result = new byte[digest.getDigestSize()]; digest.doFinal(result, 0); - - reset(); - return result; } private byte[] getZ(byte[] userID) { - digest.reset(); - addUserID(digest, userID); addFieldElement(digest, ecParams.getCurve().getA()); @@ -273,18 +314,14 @@ private byte[] getZ(byte[] userID) addFieldElement(digest, pubPoint.getAffineXCoord()); addFieldElement(digest, pubPoint.getAffineYCoord()); - byte[] result = new byte[digest.getDigestSize()]; - - digest.doFinal(result, 0); - - return result; + return digestDoFinal(); } private void addUserID(Digest digest, byte[] userID) { int len = userID.length * 8; - digest.update((byte)(len >> 8 & 0xFF)); - digest.update((byte)(len & 0xFF)); + digest.update((byte)(len >>> 8)); + digest.update((byte)len); digest.update(userID, 0, userID.length); } diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsRsaKeyExchange.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsRsaKeyExchange.java new file mode 100644 index 0000000000..7d57f126c0 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/tls/TlsRsaKeyExchange.java @@ -0,0 +1,268 @@ +package org.bouncycastle.crypto.tls; + +import java.math.BigInteger; +import java.security.SecureRandom; + +import org.bouncycastle.crypto.CryptoServicePurpose; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.constraints.ConstraintUtils; +import org.bouncycastle.crypto.constraints.DefaultServiceProperties; +import org.bouncycastle.crypto.params.RSAKeyParameters; +import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.BigIntegers; +import org.bouncycastle.util.Pack; + +public abstract class TlsRsaKeyExchange +{ + public static final int PRE_MASTER_SECRET_LENGTH = 48; + + private static final BigInteger ONE = BigInteger.valueOf(1); + + private TlsRsaKeyExchange() + { + } + + public static byte[] decryptPreMasterSecret(byte[] in, int inOff, int inLen, RSAKeyParameters privateKey, + int protocolVersion, SecureRandom secureRandom) + { + if (in == null || inLen < 1 || inLen > getInputLimit(privateKey) || inOff < 0 || inOff > in.length - inLen) + { + throw new IllegalArgumentException("input not a valid EncryptedPreMasterSecret"); + } + + if (!privateKey.isPrivate()) + { + throw new IllegalArgumentException("'privateKey' must be an RSA private key"); + } + + BigInteger modulus = privateKey.getModulus(); + int bitLength = modulus.bitLength(); + if (bitLength < 512) + { + throw new IllegalArgumentException("'privateKey' must be at least 512 bits"); + } + + int bitsOfSecurity = ConstraintUtils.bitsOfSecurityFor(modulus); + CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("RSA", bitsOfSecurity, privateKey, + CryptoServicePurpose.DECRYPTION)); + + if ((protocolVersion & 0xFFFF) != protocolVersion) + { + throw new IllegalArgumentException("'protocolVersion' must be a 16 bit value"); + } + + secureRandom = CryptoServicesRegistrar.getSecureRandom(secureRandom); + + /* + * Generate random bytes we can use as a Pre-Master-Secret if the decrypted value is invalid. + */ + byte[] result = new byte[PRE_MASTER_SECRET_LENGTH]; + secureRandom.nextBytes(result); + + try + { + BigInteger input = convertInput(modulus, in, inOff, inLen); + byte[] encoding = rsaBlinded(privateKey, input, secureRandom); + + int pkcs1Length = (bitLength - 1) / 8; + int plainTextOffset = encoding.length - PRE_MASTER_SECRET_LENGTH; + + int badEncodingMask = checkPkcs1Encoding2(encoding, pkcs1Length, PRE_MASTER_SECRET_LENGTH); + int badVersionMask = -((Pack.bigEndianToShort(encoding, plainTextOffset) ^ protocolVersion) & 0xFFFF) >> 31; + int fallbackMask = badEncodingMask | badVersionMask; + + for (int i = 0; i < PRE_MASTER_SECRET_LENGTH; ++i) + { + result[i] = (byte)((result[i] & fallbackMask) | (encoding[plainTextOffset + i] & ~fallbackMask)); + } + + Arrays.fill(encoding, (byte)0); + } + catch (Exception e) + { + /* + * Decryption should never throw an exception; return a random value instead. + * + * In any case, a TLS server MUST NOT generate an alert if processing an RSA-encrypted premaster + * secret message fails, or the version number is not as expected. Instead, it MUST continue the + * handshake with a randomly generated premaster secret. + */ + } + + return result; + } + + public static int getInputLimit(RSAKeyParameters privateKey) + { + return (privateKey.getModulus().bitLength() + 7) / 8; + } + + private static int caddTo(int len, int cond, byte[] x, byte[] z) + { +// assert cond == 0 || cond == -1; + int mask = cond & 0xFF; + + int c = 0; + for (int i = len - 1; i >= 0; --i) + { + c += (z[i] & 0xFF) + (x[i] & mask); + z[i] = (byte)c; + c >>>= 8; + } + return c; + } + + /** + * Check the argument is a valid encoding with type 2 of a plaintext with the given length. Returns 0 if + * valid, or -1 if invalid. + */ + private static int checkPkcs1Encoding2(byte[] buf, int pkcs1Length, int plaintextLength) + { + // The header should be at least 10 bytes + int errorSign = pkcs1Length - plaintextLength - 10; + + int firstPadPos = buf.length - pkcs1Length; + int lastPadPos = buf.length - 1 - plaintextLength; + + // Any leading bytes should be zero + for (int i = 0; i < firstPadPos; ++i) + { + errorSign |= -(buf[i] & 0xFF); + } + + // The first byte should be 0x02 + errorSign |= -((buf[firstPadPos] & 0xFF) ^ 0x02); + + // All pad bytes before the last one should be non-zero + for (int i = firstPadPos + 1; i < lastPadPos; ++i) + { + errorSign |= (buf[i] & 0xFF) - 1; + } + + // Last pad byte should be zero + errorSign |= -(buf[lastPadPos] & 0xFF); + + return errorSign >> 31; + } + + private static BigInteger convertInput(BigInteger modulus, byte[] in, int inOff, int inLen) + { + BigInteger result = BigIntegers.fromUnsignedByteArray(in, inOff, inLen); + if (result.compareTo(modulus) < 0) + { + return result; + } + + throw new DataLengthException("input too large for RSA cipher."); + } + + private static BigInteger rsa(RSAKeyParameters privateKey, BigInteger input) + { + return input.modPow(privateKey.getExponent(), privateKey.getModulus()); + } + + private static byte[] rsaBlinded(RSAKeyParameters privateKey, BigInteger input, SecureRandom secureRandom) + { + BigInteger modulus = privateKey.getModulus(); + int resultSize = modulus.bitLength() / 8 + 1; + + if (privateKey instanceof RSAPrivateCrtKeyParameters) + { + RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters)privateKey; + + BigInteger e = crtKey.getPublicExponent(); + if (e != null) // can't do blinding without a public exponent + { + BigInteger r = BigIntegers.createRandomInRange(ONE, modulus.subtract(ONE), secureRandom); + BigInteger blind = r.modPow(e, modulus); + BigInteger unblind = BigIntegers.modOddInverse(modulus, r); + + BigInteger blindedInput = blind.multiply(input).mod(modulus); + BigInteger blindedResult = rsaCrt(crtKey, blindedInput); + BigInteger offsetResult = unblind.add(ONE).multiply(blindedResult).mod(modulus); + + /* + * BigInteger conversion time is not constant, but is only done for blinded or public values. + */ + byte[] blindedResultBytes = toBytes(blindedResult, resultSize); + byte[] modulusBytes = toBytes(modulus, resultSize); + byte[] resultBytes = toBytes(offsetResult, resultSize); + + /* + * A final modular subtraction is done without timing dependencies on the final result. + */ + int carry = subFrom(resultSize, blindedResultBytes, resultBytes); + caddTo(resultSize, carry, modulusBytes, resultBytes); + + return resultBytes; + } + } + + return toBytes(rsa(privateKey, input), resultSize); + } + + private static BigInteger rsaCrt(RSAPrivateCrtKeyParameters crtKey, BigInteger input) + { + // + // we have the extra factors, use the Chinese Remainder Theorem - the author + // wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for + // advice regarding the expression of this. + // + BigInteger e = crtKey.getPublicExponent(); +// assert e != null; + + BigInteger p = crtKey.getP(); + BigInteger q = crtKey.getQ(); + BigInteger dP = crtKey.getDP(); + BigInteger dQ = crtKey.getDQ(); + BigInteger qInv = crtKey.getQInv(); + + BigInteger mP, mQ, h, m; + + // mP = ((input mod p) ^ dP)) mod p + mP = (input.remainder(p)).modPow(dP, p); + + // mQ = ((input mod q) ^ dQ)) mod q + mQ = (input.remainder(q)).modPow(dQ, q); + + // h = qInv * (mP - mQ) mod p + h = mP.subtract(mQ); + h = h.multiply(qInv); + h = h.mod(p); // mod (in Java) returns the positive residual + + // m = h * q + mQ + m = h.multiply(q).add(mQ); + + // defence against Arjen Lenstra’s CRT attack + BigInteger check = m.modPow(e, crtKey.getModulus()); + if (!check.equals(input)) + { + throw new IllegalStateException("RSA engine faulty decryption/signing detected"); + } + + return m; + } + + private static int subFrom(int len, byte[] x, byte[] z) + { + int c = 0; + for (int i = len - 1; i >= 0; --i) + { + c += (z[i] & 0xFF) - (x[i] & 0xFF); + z[i] = (byte)c; + c >>= 8; + } + return c; + } + + private static byte[] toBytes(BigInteger output, int fixedSize) + { + byte[] bytes = output.toByteArray(); + + byte[] result = new byte[fixedSize]; + System.arraycopy(bytes, 0, result, result.length - bytes.length, bytes.length); + return result; + } +} diff --git a/core/src/main/java/org/bouncycastle/crypto/util/AlgorithmIdentifierFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/AlgorithmIdentifierFactory.java index 9ec8b8420e..ea575f8ab2 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/AlgorithmIdentifierFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/AlgorithmIdentifierFactory.java @@ -5,16 +5,16 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.internal.asn1.cms.CCMParameters; -import org.bouncycastle.internal.asn1.cms.GCMParameters; -import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; -import org.bouncycastle.asn1.misc.CAST5CBCParameters; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RC2CBCParameter; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.internal.asn1.cms.CCMParameters; +import org.bouncycastle.internal.asn1.cms.GCMParameters; +import org.bouncycastle.internal.asn1.kisa.KISAObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.CAST5CBCParameters; +import org.bouncycastle.internal.asn1.ntt.NTTObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; /** * Factory methods for common AlgorithmIdentifiers. diff --git a/core/src/main/java/org/bouncycastle/crypto/util/CipherFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/CipherFactory.java index ee44b90065..a8e9b2f82a 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/CipherFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/CipherFactory.java @@ -2,16 +2,12 @@ import java.io.OutputStream; +import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; -import org.bouncycastle.asn1.misc.CAST5CBCParameters; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RC2CBCParameter; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; @@ -38,6 +34,11 @@ import org.bouncycastle.crypto.params.RC2Parameters; import org.bouncycastle.internal.asn1.cms.CCMParameters; import org.bouncycastle.internal.asn1.cms.GCMParameters; +import org.bouncycastle.internal.asn1.kisa.KISAObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.CAST5CBCParameters; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.ntt.NTTObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; /** * Factory methods for creating Cipher objects and CipherOutputStreams. @@ -65,6 +66,24 @@ public class CipherFactory 0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd }; + private static int getRC2EffectiveKeyBits(RC2CBCParameter rc2CbcParameter) + { + ASN1Integer version = rc2CbcParameter.getRC2ParameterVersionData(); + if (version == null) + { + return 32; + } + + int encoding = version.intPositiveValueExact(); + if (encoding >= 256) + { + return encoding; + } + + // TODO Why an entire table when RFC 8018 B.2.3. says only 160, 120, 58, 256+ are defined? + return rc2Ekb[encoding] & 0xFFFF; + } + /** * Create a content cipher for encrypting bulk data. * @@ -144,9 +163,12 @@ else if (encAlg.equals(AlgorithmIdentifierFactory.CAST5_CBC)) } else if (encAlg.equals(PKCSObjectIdentifiers.RC2_CBC)) { - RC2CBCParameter cbcParams = RC2CBCParameter.getInstance(sParams); + RC2CBCParameter rc2CBCParameter = RC2CBCParameter.getInstance(sParams); + RC2Parameters rc2Parameters = new RC2Parameters( + ((KeyParameter)encKey).getKey(), + getRC2EffectiveKeyBits(rc2CBCParameter)); - cipher.init(forEncryption, new ParametersWithIV(new RC2Parameters(((KeyParameter)encKey).getKey(), rc2Ekb[cbcParams.getRC2ParameterVersion().intValue()]), cbcParams.getIV())); + cipher.init(forEncryption, new ParametersWithIV(rc2Parameters, rc2CBCParameter.getIV())); } else { @@ -177,13 +199,13 @@ private static AEADBlockCipher createAEADCipher(ASN1ObjectIdentifier algorithm) || NISTObjectIdentifiers.id_aes192_GCM.equals(algorithm) || NISTObjectIdentifiers.id_aes256_GCM.equals(algorithm)) { - return new GCMBlockCipher(new AESEngine()); + return GCMBlockCipher.newInstance(AESEngine.newInstance()); } if (NISTObjectIdentifiers.id_aes128_CCM.equals(algorithm) || NISTObjectIdentifiers.id_aes192_CCM.equals(algorithm) || NISTObjectIdentifiers.id_aes256_CCM.equals(algorithm)) { - return new CCMBlockCipher(new AESEngine()); + return CCMBlockCipher.newInstance(AESEngine.newInstance()); } else { @@ -200,23 +222,23 @@ private static BufferedBlockCipher createCipher(ASN1ObjectIdentifier algorithm) || NISTObjectIdentifiers.id_aes192_CBC.equals(algorithm) || NISTObjectIdentifiers.id_aes256_CBC.equals(algorithm)) { - cipher = new CBCBlockCipher(new AESEngine()); + cipher = CBCBlockCipher.newInstance(AESEngine.newInstance()); } else if (PKCSObjectIdentifiers.des_EDE3_CBC.equals(algorithm)) { - cipher = new CBCBlockCipher(new DESedeEngine()); + cipher = CBCBlockCipher.newInstance(new DESedeEngine()); } else if (OIWObjectIdentifiers.desCBC.equals(algorithm)) { - cipher = new CBCBlockCipher(new DESEngine()); + cipher = CBCBlockCipher.newInstance(new DESEngine()); } else if (PKCSObjectIdentifiers.RC2_CBC.equals(algorithm)) { - cipher = new CBCBlockCipher(new RC2Engine()); + cipher = CBCBlockCipher.newInstance(new RC2Engine()); } else if (MiscObjectIdentifiers.cast5CBC.equals(algorithm)) { - cipher = new CBCBlockCipher(new CAST5Engine()); + cipher = CBCBlockCipher.newInstance(new CAST5Engine()); } else { diff --git a/core/src/main/java/org/bouncycastle/crypto/util/CipherKeyGeneratorFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/CipherKeyGeneratorFactory.java index 35284ba3c9..740995444f 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/CipherKeyGeneratorFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/CipherKeyGeneratorFactory.java @@ -3,15 +3,15 @@ import java.security.SecureRandom; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.generators.DESKeyGenerator; import org.bouncycastle.crypto.generators.DESedeKeyGenerator; +import org.bouncycastle.internal.asn1.kisa.KISAObjectIdentifiers; +import org.bouncycastle.internal.asn1.ntt.NTTObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; /** * Factory methods for generating secret key generators for symmetric ciphers. diff --git a/core/src/main/java/org/bouncycastle/crypto/util/DEROtherInfo.java b/core/src/main/java/org/bouncycastle/crypto/util/DEROtherInfo.java index 4e821f7e34..88dfe02748 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/DEROtherInfo.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/DEROtherInfo.java @@ -21,7 +21,7 @@ public class DEROtherInfo public static final class Builder { private final AlgorithmIdentifier algorithmID; - private final ASN1OctetString partyUVInfo; + private final ASN1OctetString partyUInfo; private final ASN1OctetString partyVInfo; private ASN1TaggedObject suppPubInfo; @@ -37,7 +37,7 @@ public static final class Builder public Builder(AlgorithmIdentifier algorithmID, byte[] partyUInfo, byte[] partyVInfo) { this.algorithmID = algorithmID; - this.partyUVInfo = DerUtil.getOctetString(partyUInfo); + this.partyUInfo = DerUtil.getOctetString(partyUInfo); this.partyVInfo = DerUtil.getOctetString(partyVInfo); } @@ -77,7 +77,7 @@ public DEROtherInfo build() ASN1EncodableVector v = new ASN1EncodableVector(); v.add(algorithmID); - v.add(partyUVInfo); + v.add(partyUInfo); v.add(partyVInfo); if (suppPubInfo != null) diff --git a/core/src/main/java/org/bouncycastle/crypto/util/DigestFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/DigestFactory.java index 4f08ee1383..685be1b1c0 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/DigestFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/DigestFactory.java @@ -54,7 +54,7 @@ public Digest createClone(Digest original) { public Digest createClone(Digest original) { - return new SHA256Digest((SHA256Digest)original); + return SHA256Digest.newInstance(original); } }); cloneMap.put(createSHA384().getAlgorithmName(), new Cloner() @@ -149,7 +149,7 @@ public static Digest createSHA224PRF() public static Digest createSHA256() { - return new SHA256Digest(); + return SHA256Digest.newInstance(); } public static Digest createSHA256PRF() diff --git a/core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPrivateKeyUtil.java b/core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPrivateKeyUtil.java index 58d1b7fe2d..b33a1a7036 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPrivateKeyUtil.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPrivateKeyUtil.java @@ -13,12 +13,13 @@ import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPrivateKey; import org.bouncycastle.asn1.sec.ECPrivateKey; -import org.bouncycastle.asn1.x9.ECNamedCurveTable; +import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; +import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECNamedDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; @@ -199,13 +200,24 @@ else if (sequence.size() == 4) && sequence.getObjectAt(2) instanceof ASN1TaggedObject) { ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(sequence); - ASN1ObjectIdentifier curveOID = ASN1ObjectIdentifier.getInstance(ecPrivateKey.getParametersObject()); - X9ECParameters x9Params = ECNamedCurveTable.getByOID(curveOID); - result = new ECPrivateKeyParameters( - ecPrivateKey.getKey(), - new ECNamedDomainParameters( - curveOID, - x9Params)); + + X962Parameters parameters = X962Parameters.getInstance( + ecPrivateKey.getParametersObject().toASN1Primitive()); + ECDomainParameters domainParams; + if (parameters.isNamedCurve()) + { + ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(parameters.getParameters()); + domainParams = ECNamedDomainParameters.lookup(oid); + } + else + { + X9ECParameters x9 = X9ECParameters.getInstance(parameters.getParameters()); + domainParams = new ECDomainParameters(x9); + } + + BigInteger d = ecPrivateKey.getKey(); + + result = new ECPrivateKeyParameters(d, domainParams); } } } diff --git a/core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPublicKeyUtil.java b/core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPublicKeyUtil.java index 07a8ac21a1..7a1ac0f490 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPublicKeyUtil.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPublicKeyUtil.java @@ -30,6 +30,9 @@ private OpenSSHPublicKeyUtil() private static final String ED_25519 = "ssh-ed25519"; private static final String DSS = "ssh-dss"; + private static final String FIDO2_EC_P256 = "sk-ecdsa-sha2-nistp256@openssh.com"; + private static final String FIDO_ED_25519 = "sk-ssh-ed25519@openssh.com"; + /** * Parse a public key. *

    @@ -118,7 +121,7 @@ else if (cipherParameters instanceof Ed25519PublicKeyParameters) return builder.getBytes(); } - throw new IllegalArgumentException("unable to convert " + cipherParameters.getClass().getName() + " to private key"); + throw new IllegalArgumentException("unable to convert " + cipherParameters.getClass().getName() + " to public key"); } /** @@ -167,6 +170,29 @@ else if (magic.startsWith(ECDSA)) curve.decodePoint(pointRaw), new ECNamedDomainParameters(oid, x9ECParameters)); } + else if (magic.equals(FIDO2_EC_P256)) + { + String curveName = buffer.readString(); + + ASN1ObjectIdentifier oid = SSHNamedCurves.getByName(curveName); + X9ECParameters x9ECParameters = SSHNamedCurves.getParameters(oid); + + if (x9ECParameters == null) + { + throw new IllegalStateException("unable to find curve for " + magic + " using curve name " + curveName); + } + + ECCurve curve = x9ECParameters.getCurve(); + + byte[] pointRaw = buffer.readBlock(); + + // TODO: at the moment we have no use for this, but it's there. + String application = buffer.readString(); + + result = new ECPublicKeyParameters( + curve.decodePoint(pointRaw), + new ECNamedDomainParameters(oid, x9ECParameters)); + } else if (ED_25519.equals(magic)) { byte[] pubKeyBytes = buffer.readBlock(); @@ -177,6 +203,19 @@ else if (ED_25519.equals(magic)) result = new Ed25519PublicKeyParameters(pubKeyBytes, 0); } + else if (FIDO2_EC_P256.equals(magic)) + { + byte[] pubKeyBytes = buffer.readBlock(); + if (pubKeyBytes.length != Ed25519PublicKeyParameters.KEY_SIZE) + { + throw new IllegalStateException("public key value of wrong length"); + } + + // TODO: at the moment we have no use for this, but it's there. + String application = buffer.readString(); + + result = new Ed25519PublicKeyParameters(pubKeyBytes, 0); + } if (result == null) { diff --git a/core/src/main/java/org/bouncycastle/crypto/util/PBKDF2Config.java b/core/src/main/java/org/bouncycastle/crypto/util/PBKDF2Config.java index f5639b3dd2..8f672bbb66 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/PBKDF2Config.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/PBKDF2Config.java @@ -9,8 +9,8 @@ import org.bouncycastle.asn1.gm.GMObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.util.Integers; /** diff --git a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java index 26f9abb76a..8e94bc92c4 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java @@ -14,14 +14,10 @@ import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; -import org.bouncycastle.asn1.oiw.ElGamalParameter; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.DHParameter; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPrivateKey; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.sec.ECPrivateKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; @@ -30,7 +26,6 @@ import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; -import org.bouncycastle.crypto.ec.CustomNamedCurves; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; @@ -47,6 +42,10 @@ import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; import org.bouncycastle.crypto.params.X448PrivateKeyParameters; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.ElGamalParameter; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.util.Arrays; /** @@ -155,40 +154,43 @@ else if (algOID.equals(X9ObjectIdentifiers.id_dsa)) } else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey)) { - X962Parameters params = X962Parameters.getInstance(algId.getParameters()); + ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(keyInfo.parsePrivateKey()); - X9ECParameters x9; - ECDomainParameters dParams; - - if (params.isNamedCurve()) + X962Parameters parameters = X962Parameters.getInstance(algId.getParameters().toASN1Primitive()); + ECDomainParameters domainParams; + if (parameters.isNamedCurve()) { - ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); - - x9 = CustomNamedCurves.getByOID(oid); - if (x9 == null) - { - x9 = ECNamedCurveTable.getByOID(oid); - } - dParams = new ECNamedDomainParameters(oid, x9); + ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(parameters.getParameters()); + domainParams = ECNamedDomainParameters.lookup(oid); } else { - x9 = X9ECParameters.getInstance(params.getParameters()); - dParams = new ECDomainParameters( - x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); + X9ECParameters x9 = X9ECParameters.getInstance(parameters.getParameters()); + domainParams = new ECDomainParameters(x9); } - ECPrivateKey ec = ECPrivateKey.getInstance(keyInfo.parsePrivateKey()); - BigInteger d = ec.getKey(); + BigInteger d = ecPrivateKey.getKey(); - return new ECPrivateKeyParameters(d, dParams); + return new ECPrivateKeyParameters(d, domainParams); } else if (algOID.equals(EdECObjectIdentifiers.id_X25519)) { + // Java 11 bug: exact length of X25519/X448 secret used in Java 11 + if (X25519PrivateKeyParameters.KEY_SIZE == keyInfo.getPrivateKeyLength()) + { + return new X25519PrivateKeyParameters(keyInfo.getPrivateKey().getOctets()); + } + return new X25519PrivateKeyParameters(getRawKey(keyInfo)); } else if (algOID.equals(EdECObjectIdentifiers.id_X448)) { + // Java 11 bug: exact length of X25519/X448 secret used in Java 11 + if (X448PrivateKeyParameters.KEY_SIZE == keyInfo.getPrivateKeyLength()) + { + return new X448PrivateKeyParameters(keyInfo.getPrivateKey().getOctets()); + } + return new X448PrivateKeyParameters(getRawKey(keyInfo)); } else if (algOID.equals(EdECObjectIdentifiers.id_Ed25519)) @@ -219,11 +221,12 @@ else if ( gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(), gostParams.getEncryptionParamSet()); - ASN1OctetString privEnc = keyInfo.getPrivateKey(); - if (privEnc.getOctets().length == 32 || privEnc.getOctets().length == 64) + int privateKeyLength = keyInfo.getPrivateKeyLength(); + + if (privateKeyLength == 32 || privateKeyLength == 64) { - d = new BigInteger(1, Arrays.reverse(privEnc.getOctets())); + d = new BigInteger(1, Arrays.reverse(keyInfo.getPrivateKey().getOctets())); } else { diff --git a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java index cd4bf4d36c..1b00473f5e 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java @@ -14,11 +14,9 @@ import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPrivateKey; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.sec.ECPrivateKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; @@ -39,6 +37,8 @@ import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; import org.bouncycastle.crypto.params.X448PrivateKeyParameters; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.math.ec.FixedPointCombMultiplier; diff --git a/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java index 02584fd12c..0a5a1189a4 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java @@ -17,13 +17,9 @@ import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; -import org.bouncycastle.asn1.oiw.ElGamalParameter; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.DHParameter; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.ua.DSTU4145BinaryField; import org.bouncycastle.asn1.ua.DSTU4145ECBinary; import org.bouncycastle.asn1.ua.DSTU4145NamedCurves; @@ -36,14 +32,12 @@ import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.asn1.x9.DHPublicKey; import org.bouncycastle.asn1.x9.DomainParameters; -import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.ValidationParams; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECPoint; import org.bouncycastle.asn1.x9.X9IntegerConverter; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; -import org.bouncycastle.crypto.ec.CustomNamedCurves; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; @@ -61,6 +55,10 @@ import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.X25519PublicKeyParameters; import org.bouncycastle.crypto.params.X448PublicKeyParameters; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.ElGamalParameter; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.Arrays; @@ -291,13 +289,7 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); - - X9ECParameters x9 = CustomNamedCurves.getByOID(oid); - if (x9 == null) - { - x9 = ECNamedCurveTable.getByOID(oid); - } - dParams = new ECNamedDomainParameters(oid, x9); + dParams = ECNamedDomainParameters.lookup(oid); } else if (params.isImplicitlyCA()) { @@ -484,7 +476,7 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } BigInteger b = new BigInteger(1, b_bytes); DSTU4145BinaryField field = binary.getField(); - ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), b); + ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), b, null, null); byte[] g_bytes = binary.getG(); if (algOid.equals(UAObjectIdentifiers.dstu4145le)) { diff --git a/core/src/main/java/org/bouncycastle/crypto/util/ScryptConfig.java b/core/src/main/java/org/bouncycastle/crypto/util/ScryptConfig.java index bb02683b38..2ebbc53397 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/ScryptConfig.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/ScryptConfig.java @@ -1,6 +1,6 @@ package org.bouncycastle.crypto.util; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; /** * Configuration class for a PBKDF based around scrypt. diff --git a/core/src/main/java/org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java index 40e4c39b1d..3ade492281 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java @@ -8,15 +8,12 @@ import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; @@ -36,6 +33,8 @@ import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.X25519PublicKeyParameters; import org.bouncycastle.crypto.params.X448PublicKeyParameters; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; /** * Factory to create ASN.1 subject public key info objects from lightweight public keys. diff --git a/core/src/main/java/org/bouncycastle/i18n/LocalizedMessage.java b/core/src/main/java/org/bouncycastle/i18n/LocalizedMessage.java index 217cc170ba..ac75c6c345 100644 --- a/core/src/main/java/org/bouncycastle/i18n/LocalizedMessage.java +++ b/core/src/main/java/org/bouncycastle/i18n/LocalizedMessage.java @@ -1,10 +1,5 @@ package org.bouncycastle.i18n; -import org.bouncycastle.i18n.filter.Filter; -import org.bouncycastle.i18n.filter.TrustedInput; -import org.bouncycastle.i18n.filter.UntrustedInput; -import org.bouncycastle.i18n.filter.UntrustedUrlInput; - import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.text.DateFormat; @@ -15,6 +10,11 @@ import java.util.ResourceBundle; import java.util.TimeZone; +import org.bouncycastle.i18n.filter.Filter; +import org.bouncycastle.i18n.filter.TrustedInput; +import org.bouncycastle.i18n.filter.UntrustedInput; +import org.bouncycastle.i18n.filter.UntrustedUrlInput; + public class LocalizedMessage { diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/bsi/BSIObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/bsi/BSIObjectIdentifiers.java index 03f9ed9c2e..c306b7b425 100644 --- a/core/src/main/java/org/bouncycastle/internal/asn1/bsi/BSIObjectIdentifiers.java +++ b/core/src/main/java/org/bouncycastle/internal/asn1/bsi/BSIObjectIdentifiers.java @@ -93,24 +93,24 @@ public interface BSIObjectIdentifiers static final ASN1ObjectIdentifier ecka_eg_SessionKDF_AES192 = ecka_eg_SessionKDF.branch("3"); static final ASN1ObjectIdentifier ecka_eg_SessionKDF_AES256 = ecka_eg_SessionKDF.branch("4"); - /** AES encryption (CBC) and authentication (CMAC) - * OID: 0.4.0.127.0.7.1.x */ +// /** AES encryption (CBC) and authentication (CMAC) +// * OID: 0.4.0.127.0.7.1.x */ //TODO: replace "1" with correct OID //static final ASN1ObjectIdentifier aes_cbc_cmac = algorithm.branch("1"); - /** AES encryption (CBC) and authentication (CMAC) with 128 bit - * OID: 0.4.0.127.0.7.1.x.y1 */ +// /** AES encryption (CBC) and authentication (CMAC) with 128 bit +// * OID: 0.4.0.127.0.7.1.x.y1 */ //TODO: replace "1" with correct OID //static final ASN1ObjectIdentifier id_aes128_CBC_CMAC = aes_cbc_cmac.branch("1"); - /** AES encryption (CBC) and authentication (CMAC) with 192 bit - * OID: 0.4.0.127.0.7.1.x.y2 */ +// /** AES encryption (CBC) and authentication (CMAC) with 192 bit +// * OID: 0.4.0.127.0.7.1.x.y2 */ //TODO: replace "1" with correct OID //static final ASN1ObjectIdentifier id_aes192_CBC_CMAC = aes_cbc_cmac.branch("1"); - /** AES encryption (CBC) and authentication (CMAC) with 256 bit - * OID: 0.4.0.127.0.7.1.x.y3 */ +// /** AES encryption (CBC) and authentication (CMAC) with 256 bit +// * OID: 0.4.0.127.0.7.1.x.y3 */ //TODO: replace "1" with correct OID //static final ASN1ObjectIdentifier id_aes256_CBC_CMAC = aes_cbc_cmac.branch("1"); } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/CryptlibObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/cryptlib/CryptlibObjectIdentifiers.java similarity index 70% rename from pg/src/main/java/org/bouncycastle/openpgp/CryptlibObjectIdentifiers.java rename to core/src/main/java/org/bouncycastle/internal/asn1/cryptlib/CryptlibObjectIdentifiers.java index b454af6c25..b6ede69975 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/CryptlibObjectIdentifiers.java +++ b/core/src/main/java/org/bouncycastle/internal/asn1/cryptlib/CryptlibObjectIdentifiers.java @@ -1,9 +1,8 @@ -package org.bouncycastle.openpgp; +package org.bouncycastle.internal.asn1.cryptlib; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -// temporary fix for 172.1 due to module export lacking in provider. -class CryptlibObjectIdentifiers +public class CryptlibObjectIdentifiers { public static final ASN1ObjectIdentifier cryptlib = new ASN1ObjectIdentifier("1.3.6.1.4.1.3029"); diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/edec/EdECObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/edec/EdECObjectIdentifiers.java new file mode 100644 index 0000000000..5ef798e84e --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/edec/EdECObjectIdentifiers.java @@ -0,0 +1,16 @@ +package org.bouncycastle.internal.asn1.edec; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +/** + * Edwards Elliptic Curve Object Identifiers (RFC 8410) + */ +public interface EdECObjectIdentifiers +{ + ASN1ObjectIdentifier id_edwards_curve_algs = new ASN1ObjectIdentifier("1.3.101"); + + ASN1ObjectIdentifier id_X25519 = id_edwards_curve_algs.branch("110").intern(); + ASN1ObjectIdentifier id_X448 = id_edwards_curve_algs.branch("111").intern(); + ASN1ObjectIdentifier id_Ed25519 = id_edwards_curve_algs.branch("112").intern(); + ASN1ObjectIdentifier id_Ed448 = id_edwards_curve_algs.branch("113").intern(); +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/gnu/GNUObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/gnu/GNUObjectIdentifiers.java new file mode 100644 index 0000000000..f038c9eeaa --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/gnu/GNUObjectIdentifiers.java @@ -0,0 +1,111 @@ +package org.bouncycastle.internal.asn1.gnu; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +/** + * GNU project OID collection

    + * { iso(1) identifier-organization(3) dod(6) internet(1) private(4) } == IETF defined things + */ +public interface GNUObjectIdentifiers +{ + /** + * 1.3.6.1.4.1.11591.1 -- used by GNU Radius + */ + ASN1ObjectIdentifier GNU = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.1"); // GNU Radius + /** + * 1.3.6.1.4.1.11591.2 -- used by GNU PG + */ + ASN1ObjectIdentifier GnuPG = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.2"); // GnuPG (Ägypten) + /** + * 1.3.6.1.4.1.11591.2.1 -- notation + */ + ASN1ObjectIdentifier notation = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.2.1"); // notation + /** + * 1.3.6.1.4.1.11591.2.1.1 -- pkaAddress + */ + ASN1ObjectIdentifier pkaAddress = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.2.1.1"); // pkaAddress + /** + * 1.3.6.1.4.1.11591.3 -- GNU Radar + */ + ASN1ObjectIdentifier GnuRadar = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.3"); // GNU Radar + /** + * 1.3.6.1.4.1.11591.12 -- digestAlgorithm + */ + ASN1ObjectIdentifier digestAlgorithm = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.12"); // digestAlgorithm + /** + * 1.3.6.1.4.1.11591.12.2 -- TIGER/192 + */ + ASN1ObjectIdentifier Tiger_192 = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.12.2"); // TIGER/192 + /** + * 1.3.6.1.4.1.11591.13 -- encryptionAlgorithm + */ + ASN1ObjectIdentifier encryptionAlgorithm = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13"); // encryptionAlgorithm + /** + * 1.3.6.1.4.1.11591.13.2 -- Serpent + */ + ASN1ObjectIdentifier Serpent = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2"); // Serpent + /** + * 1.3.6.1.4.1.11591.13.2.1 -- Serpent-128-ECB + */ + ASN1ObjectIdentifier Serpent_128_ECB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.1"); // Serpent-128-ECB + /** + * 1.3.6.1.4.1.11591.13.2.2 -- Serpent-128-CBC + */ + ASN1ObjectIdentifier Serpent_128_CBC = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.2"); // Serpent-128-CBC + /** + * 1.3.6.1.4.1.11591.13.2.3 -- Serpent-128-OFB + */ + ASN1ObjectIdentifier Serpent_128_OFB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.3"); // Serpent-128-OFB + /** + * 1.3.6.1.4.1.11591.13.2.4 -- Serpent-128-CFB + */ + ASN1ObjectIdentifier Serpent_128_CFB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.4"); // Serpent-128-CFB + /** + * 1.3.6.1.4.1.11591.13.2.21 -- Serpent-192-ECB + */ + ASN1ObjectIdentifier Serpent_192_ECB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.21"); // Serpent-192-ECB + /** + * 1.3.6.1.4.1.11591.13.2.22 -- Serpent-192-CCB + */ + ASN1ObjectIdentifier Serpent_192_CBC = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.22"); // Serpent-192-CBC + /** + * 1.3.6.1.4.1.11591.13.2.23 -- Serpent-192-OFB + */ + ASN1ObjectIdentifier Serpent_192_OFB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.23"); // Serpent-192-OFB + /** + * 1.3.6.1.4.1.11591.13.2.24 -- Serpent-192-CFB + */ + ASN1ObjectIdentifier Serpent_192_CFB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.24"); // Serpent-192-CFB + /** + * 1.3.6.1.4.1.11591.13.2.41 -- Serpent-256-ECB + */ + ASN1ObjectIdentifier Serpent_256_ECB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.41"); // Serpent-256-ECB + /** + * 1.3.6.1.4.1.11591.13.2.42 -- Serpent-256-CBC + */ + ASN1ObjectIdentifier Serpent_256_CBC = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.42"); // Serpent-256-CBC + /** + * 1.3.6.1.4.1.11591.13.2.43 -- Serpent-256-OFB + */ + ASN1ObjectIdentifier Serpent_256_OFB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.43"); // Serpent-256-OFB + /** + * 1.3.6.1.4.1.11591.13.2.44 -- Serpent-256-CFB + */ + ASN1ObjectIdentifier Serpent_256_CFB = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.13.2.44"); // Serpent-256-CFB + + /** + * 1.3.6.1.4.1.11591.14 -- CRC algorithms + */ + ASN1ObjectIdentifier CRC = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.14"); // CRC algorithms + /** + * 1.3.6.1.4.1.11591.14,1 -- CRC32 + */ + ASN1ObjectIdentifier CRC32 = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.14.1"); // CRC 32 + + /** + * 1.3.6.1.4.1.11591.15 - ellipticCurve + */ + ASN1ObjectIdentifier ellipticCurve = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.15"); + + ASN1ObjectIdentifier Ed25519 = ellipticCurve.branch("1"); +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/iana/IANAObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/iana/IANAObjectIdentifiers.java new file mode 100644 index 0000000000..97a97d0680 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/iana/IANAObjectIdentifiers.java @@ -0,0 +1,60 @@ +package org.bouncycastle.internal.asn1.iana; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +/** + * IANA: + * { iso(1) identifier-organization(3) dod(6) internet(1) } == IETF defined things + */ +public interface IANAObjectIdentifiers +{ + + /** { iso(1) identifier-organization(3) dod(6) internet(1) } == IETF defined things */ + static final ASN1ObjectIdentifier internet = new ASN1ObjectIdentifier("1.3.6.1"); + /** 1.3.6.1.1: Internet directory: X.500 */ + static final ASN1ObjectIdentifier directory = internet.branch("1"); + /** 1.3.6.1.2: Internet management */ + static final ASN1ObjectIdentifier mgmt = internet.branch("2"); + /** 1.3.6.1.3: */ + static final ASN1ObjectIdentifier experimental = internet.branch("3"); + /** 1.3.6.1.4: */ + static final ASN1ObjectIdentifier _private = internet.branch("4"); + /** 1.3.6.1.5: Security services */ + static final ASN1ObjectIdentifier security = internet.branch("5"); + /** 1.3.6.1.6: SNMPv2 -- never really used */ + static final ASN1ObjectIdentifier SNMPv2 = internet.branch("6"); + /** 1.3.6.1.7: mail -- never really used */ + static final ASN1ObjectIdentifier mail = internet.branch("7"); + + + // id-SHA1 OBJECT IDENTIFIER ::= + // {iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) ipsec(8) isakmpOakley(1)} + // + + + /** IANA security mechanisms; 1.3.6.1.5.5 */ + static final ASN1ObjectIdentifier security_mechanisms = security.branch("5"); + /** IANA security nametypes; 1.3.6.1.5.6 */ + static final ASN1ObjectIdentifier security_nametypes = security.branch("6"); + + /** PKIX base OID: 1.3.6.1.5.6.6 */ + static final ASN1ObjectIdentifier pkix = security_mechanisms.branch("6"); + + + /** IPSEC base OID: 1.3.6.1.5.5.8 */ + static final ASN1ObjectIdentifier ipsec = security_mechanisms.branch("8"); + /** IPSEC ISAKMP-Oakley OID: 1.3.6.1.5.5.8.1 */ + static final ASN1ObjectIdentifier isakmpOakley = ipsec.branch("1"); + + /** IPSEC ISAKMP-Oakley hmacMD5 OID: 1.3.6.1.5.5.8.1.1 */ + static final ASN1ObjectIdentifier hmacMD5 = isakmpOakley.branch("1"); + /** IPSEC ISAKMP-Oakley hmacSHA1 OID: 1.3.6.1.5.5.8.1.2 */ + static final ASN1ObjectIdentifier hmacSHA1 = isakmpOakley.branch("2"); + + /** IPSEC ISAKMP-Oakley hmacTIGER OID: 1.3.6.1.5.5.8.1.3 */ + static final ASN1ObjectIdentifier hmacTIGER = isakmpOakley.branch("3"); + + /** IPSEC ISAKMP-Oakley hmacRIPEMD160 OID: 1.3.6.1.5.5.8.1.4 */ + static final ASN1ObjectIdentifier hmacRIPEMD160 = isakmpOakley.branch("4"); + +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/isara/IsaraObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/isara/IsaraObjectIdentifiers.java new file mode 100644 index 0000000000..47ad51b651 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/isara/IsaraObjectIdentifiers.java @@ -0,0 +1,22 @@ +package org.bouncycastle.internal.asn1.isara; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +public interface IsaraObjectIdentifiers +{ + /* + id-alg-xmss OBJECT IDENTIFIER ::= { itu-t(0) + identified-organization(4) etsi(0) reserved(127) + etsi-identified-organization(0) isara(15) algorithms(1) + asymmetric(1) xmss(13) 0 } + */ + static ASN1ObjectIdentifier id_alg_xmss = new ASN1ObjectIdentifier("0.4.0.127.0.15.1.1.13.0"); + + /* + id-alg-xmssmt OBJECT IDENTIFIER ::= { itu-t(0) + identified-organization(4) etsi(0) reserved(127) + etsi-identified-organization(0) isara(15) algorithms(1) + asymmetric(1) xmssmt(14) 0 } + */ + static ASN1ObjectIdentifier id_alg_xmssmt = new ASN1ObjectIdentifier("0.4.0.127.0.15.1.1.14.0"); +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/isismtt/ISISMTTObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/isismtt/ISISMTTObjectIdentifiers.java index 8153dc2ecb..aa54635416 100644 --- a/core/src/main/java/org/bouncycastle/internal/asn1/isismtt/ISISMTTObjectIdentifiers.java +++ b/core/src/main/java/org/bouncycastle/internal/asn1/isismtt/ISISMTTObjectIdentifiers.java @@ -103,8 +103,6 @@ public interface ISISMTTObjectIdentifiers *

    *

    * OID: 1.3.36.8.3.8 - * - * @see org.bouncycastle.asn1.isismtt.x509.Restriction */ static final ASN1ObjectIdentifier id_isismtt_at_restriction = id_isismtt_at.branch("8"); @@ -129,8 +127,6 @@ public interface ISISMTTObjectIdentifiers * returned in this extension. *

    * OID: 1.3.36.8.3.10 - * - * @see org.bouncycastle.asn1.isismtt.ocsp.RequestedCertificate */ static final ASN1ObjectIdentifier id_isismtt_at_requestedCertificate = id_isismtt_at.branch("10"); @@ -159,8 +155,7 @@ public interface ISISMTTObjectIdentifiers * Hash of a certificate in OCSP. *

    * OID: 1.3.36.8.3.13 - * - * @see org.bouncycastle.asn1.isismtt.ocsp.CertHash + * */ static final ASN1ObjectIdentifier id_isismtt_at_certHash = id_isismtt_at.branch("13"); @@ -186,8 +181,7 @@ public interface ISISMTTObjectIdentifiers *

    *

    * OID: 1.3.36.8.3.15 - * - * @see org.bouncycastle.asn1.isismtt.x509.AdditionalInformationSyntax + * */ static final ASN1ObjectIdentifier id_isismtt_at_additionalInformation = id_isismtt_at.branch("15"); diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/iso/ISOIECObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/iso/ISOIECObjectIdentifiers.java new file mode 100644 index 0000000000..5b9ae28ce9 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/iso/ISOIECObjectIdentifiers.java @@ -0,0 +1,35 @@ +package org.bouncycastle.internal.asn1.iso; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +/** + * OIDS from ISO/IEC 10118-3:2004 + */ +public interface ISOIECObjectIdentifiers +{ + ASN1ObjectIdentifier iso_encryption_algorithms = new ASN1ObjectIdentifier("1.0.10118"); + + ASN1ObjectIdentifier hash_algorithms = iso_encryption_algorithms.branch("3.0"); + + ASN1ObjectIdentifier ripemd160 = hash_algorithms.branch("49"); + ASN1ObjectIdentifier ripemd128 = hash_algorithms.branch("50"); + ASN1ObjectIdentifier whirlpool = hash_algorithms.branch("55"); + + + + /** + * -- ISO/IEC 18033-2 arc + + is18033-2 OID ::= { iso(1) standard(0) is18033(18033) part2(2) } + */ + ASN1ObjectIdentifier is18033_2 = new ASN1ObjectIdentifier("1.0.18033.2"); + + ASN1ObjectIdentifier id_ac_generic_hybrid = is18033_2.branch("1.2"); + + /** + id-kem-rsa OID ::= { + is18033-2 key-encapsulation-mechanism(2) rsa(4) + } + */ + ASN1ObjectIdentifier id_kem_rsa = is18033_2.branch("2.4"); +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/kisa/KISAObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/kisa/KISAObjectIdentifiers.java new file mode 100644 index 0000000000..89ac25559c --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/kisa/KISAObjectIdentifiers.java @@ -0,0 +1,31 @@ +package org.bouncycastle.internal.asn1.kisa; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +/** + * Korea Information Security Agency (KISA) + * ({iso(1) member-body(2) kr(410) kisa(200004)}) + *

    + * See RFC 4010 + * Use of the SEED Encryption Algorithm + * in Cryptographic Message Syntax (CMS), + * and RFC 4269 + * The SEED Encryption Algorithm + */ +public interface KISAObjectIdentifiers +{ + /** RFC 4010, 4269: id-seedCBC; OID 1.2.410.200004.1.4 */ + static final ASN1ObjectIdentifier id_seedCBC = new ASN1ObjectIdentifier("1.2.410.200004.1.4"); + + /** RFC 4269: id-seedMAC; OID 1.2.410.200004.1.7 */ + static final ASN1ObjectIdentifier id_seedMAC = new ASN1ObjectIdentifier("1.2.410.200004.1.7"); + + /** RFC 4269: pbeWithSHA1AndSEED-CBC; OID 1.2.410.200004.1.15 */ + static final ASN1ObjectIdentifier pbeWithSHA1AndSEED_CBC = new ASN1ObjectIdentifier("1.2.410.200004.1.15"); + + /** RFC 4010: id-npki-app-cmsSeed-wrap; OID 1.2.410.200004.7.1.1.1 */ + static final ASN1ObjectIdentifier id_npki_app_cmsSeed_wrap = new ASN1ObjectIdentifier("1.2.410.200004.7.1.1.1"); + + /** RFC 4010: SeedEncryptionAlgorithmInCMS; OID 1.2.840.113549.1.9.16.0.24 */ + static final ASN1ObjectIdentifier id_mod_cms_seed = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.0.24"); +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/microsoft/MicrosoftObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/microsoft/MicrosoftObjectIdentifiers.java new file mode 100644 index 0000000000..9565f1062b --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/microsoft/MicrosoftObjectIdentifiers.java @@ -0,0 +1,30 @@ +package org.bouncycastle.internal.asn1.microsoft; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +/** + * Microsoft + *

    + * Object identifier base: + *

    + *    iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) microsoft(311)
    + * 
    + * 1.3.6.1.4.1.311 + */ +public interface MicrosoftObjectIdentifiers +{ + /** Base OID: 1.3.6.1.4.1.311 */ + static final ASN1ObjectIdentifier microsoft = new ASN1ObjectIdentifier("1.3.6.1.4.1.311"); + /** OID: 1.3.6.1.4.1.311.20.2 */ + static final ASN1ObjectIdentifier microsoftCertTemplateV1 = microsoft.branch("20.2"); + /** OID: 1.3.6.1.4.1.311.21.1 */ + static final ASN1ObjectIdentifier microsoftCaVersion = microsoft.branch("21.1"); + /** OID: 1.3.6.1.4.1.311.21.2 */ + static final ASN1ObjectIdentifier microsoftPrevCaCertHash = microsoft.branch("21.2"); + /** OID: 1.3.6.1.4.1.311.21.4 */ + static final ASN1ObjectIdentifier microsoftCrlNextPublish = microsoft.branch("21.4"); + /** OID: 1.3.6.1.4.1.311.21.7 */ + static final ASN1ObjectIdentifier microsoftCertTemplateV2 = microsoft.branch("21.7"); + /** OID: 1.3.6.1.4.1.311.21.10 */ + static final ASN1ObjectIdentifier microsoftAppPolicies = microsoft.branch("21.10"); +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/misc/CAST5CBCParameters.java b/core/src/main/java/org/bouncycastle/internal/asn1/misc/CAST5CBCParameters.java new file mode 100644 index 0000000000..78c4066245 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/misc/CAST5CBCParameters.java @@ -0,0 +1,79 @@ +package org.bouncycastle.internal.asn1.misc; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.util.Arrays; + +public class CAST5CBCParameters + extends ASN1Object +{ + ASN1Integer keyLength; + ASN1OctetString iv; + + public static CAST5CBCParameters getInstance( + Object o) + { + if (o instanceof CAST5CBCParameters) + { + return (CAST5CBCParameters)o; + } + else if (o != null) + { + return new CAST5CBCParameters(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public CAST5CBCParameters( + byte[] iv, + int keyLength) + { + this.iv = new DEROctetString(Arrays.clone(iv)); + this.keyLength = new ASN1Integer(keyLength); + } + + private CAST5CBCParameters( + ASN1Sequence seq) + { + iv = (ASN1OctetString)seq.getObjectAt(0); + keyLength = (ASN1Integer)seq.getObjectAt(1); + } + + public byte[] getIV() + { + return Arrays.clone(iv.getOctets()); + } + + public int getKeyLength() + { + return keyLength.intValueExact(); + } + + /** + * Produce an object suitable for an ASN1OutputStream. + *
    +     * cast5CBCParameters ::= SEQUENCE {
    +     *                           iv         OCTET STRING DEFAULT 0,
    +     *                                  -- Initialization vector
    +     *                           keyLength  INTEGER
    +     *                                  -- Key length, in bits
    +     *                      }
    +     * 
    + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(2); + + v.add(iv); + v.add(keyLength); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/misc/IDEACBCPar.java b/core/src/main/java/org/bouncycastle/internal/asn1/misc/IDEACBCPar.java new file mode 100644 index 0000000000..ae70d167dc --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/misc/IDEACBCPar.java @@ -0,0 +1,82 @@ +package org.bouncycastle.internal.asn1.misc; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.util.Arrays; + +public class IDEACBCPar + extends ASN1Object +{ + ASN1OctetString iv; + + public static IDEACBCPar getInstance( + Object o) + { + if (o instanceof IDEACBCPar) + { + return (IDEACBCPar)o; + } + else if (o != null) + { + return new IDEACBCPar(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public IDEACBCPar( + byte[] iv) + { + this.iv = new DEROctetString(Arrays.clone(iv)); + } + + private IDEACBCPar( + ASN1Sequence seq) + { + if (seq.size() == 1) + { + iv = (ASN1OctetString)seq.getObjectAt(0); + } + else + { + iv = null; + } + } + + public byte[] getIV() + { + if (iv != null) + { + return Arrays.clone(iv.getOctets()); + } + else + { + return null; + } + } + + /** + * Produce an object suitable for an ASN1OutputStream. + *
    +     * IDEA-CBCPar ::= SEQUENCE {
    +     *                      iv    OCTET STRING OPTIONAL -- exactly 8 octets
    +     *                  }
    +     * 
    + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(1); + + if (iv != null) + { + v.add(iv); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/misc/MiscObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/misc/MiscObjectIdentifiers.java new file mode 100644 index 0000000000..0ff100ec7b --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/misc/MiscObjectIdentifiers.java @@ -0,0 +1,193 @@ +package org.bouncycastle.internal.asn1.misc; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +public interface MiscObjectIdentifiers +{ + // + // Netscape + // iso/itu(2) joint-assign(16) us(840) uscompany(1) netscape(113730) cert-extensions(1) } + // + /** + * Netscape cert extensions OID base: 2.16.840.1.113730.1 + */ + ASN1ObjectIdentifier netscape = new ASN1ObjectIdentifier("2.16.840.1.113730.1"); + /** + * Netscape cert CertType OID: 2.16.840.1.113730.1.1 + */ + ASN1ObjectIdentifier netscapeCertType = netscape.branch("1"); + /** + * Netscape cert BaseURL OID: 2.16.840.1.113730.1.2 + */ + ASN1ObjectIdentifier netscapeBaseURL = netscape.branch("2"); + /** + * Netscape cert RevocationURL OID: 2.16.840.1.113730.1.3 + */ + ASN1ObjectIdentifier netscapeRevocationURL = netscape.branch("3"); + /** + * Netscape cert CARevocationURL OID: 2.16.840.1.113730.1.4 + */ + ASN1ObjectIdentifier netscapeCARevocationURL = netscape.branch("4"); + /** + * Netscape cert RenewalURL OID: 2.16.840.1.113730.1.7 + */ + ASN1ObjectIdentifier netscapeRenewalURL = netscape.branch("7"); + /** + * Netscape cert CApolicyURL OID: 2.16.840.1.113730.1.8 + */ + ASN1ObjectIdentifier netscapeCApolicyURL = netscape.branch("8"); + /** + * Netscape cert SSLServerName OID: 2.16.840.1.113730.1.12 + */ + ASN1ObjectIdentifier netscapeSSLServerName = netscape.branch("12"); + /** + * Netscape cert CertComment OID: 2.16.840.1.113730.1.13 + */ + ASN1ObjectIdentifier netscapeCertComment = netscape.branch("13"); + + // + // Verisign + // iso/itu(2) joint-assign(16) us(840) uscompany(1) verisign(113733) cert-extensions(1) } + // + /** + * Verisign OID base: 2.16.840.1.113733.1 + */ + ASN1ObjectIdentifier verisign = new ASN1ObjectIdentifier("2.16.840.1.113733.1"); + + /** + * Verisign CZAG (Country,Zip,Age,Gender) Extension OID: 2.16.840.1.113733.1.6.3 + */ + ASN1ObjectIdentifier verisignCzagExtension = verisign.branch("6.3"); + + ASN1ObjectIdentifier verisignPrivate_6_9 = verisign.branch("6.9"); + ASN1ObjectIdentifier verisignOnSiteJurisdictionHash = verisign.branch("6.11"); + ASN1ObjectIdentifier verisignBitString_6_13 = verisign.branch("6.13"); + + /** + * Verisign D&B D-U-N-S number Extension OID: 2.16.840.1.113733.1.6.15 + */ + ASN1ObjectIdentifier verisignDnbDunsNumber = verisign.branch("6.15"); + + ASN1ObjectIdentifier verisignIssStrongCrypto = verisign.branch("8.1"); + + // + // Novell + // iso/itu(2) country(16) us(840) organization(1) novell(113719) + // + /** + * Novell OID base: 2.16.840.1.113719 + */ + ASN1ObjectIdentifier novell = new ASN1ObjectIdentifier("2.16.840.1.113719"); + /** + * Novell SecurityAttribs OID: 2.16.840.1.113719.1.9.4.1 + */ + ASN1ObjectIdentifier novellSecurityAttribs = novell.branch("1.9.4.1"); + + // + // Entrust + // iso(1) member-body(16) us(840) nortelnetworks(113533) entrust(7) + // + /** + * NortelNetworks Entrust OID base: 1.2.840.113533.7 + */ + ASN1ObjectIdentifier entrust = new ASN1ObjectIdentifier("1.2.840.113533.7"); + /** + * NortelNetworks Entrust VersionExtension OID: 1.2.840.113533.7.65.0 + */ + ASN1ObjectIdentifier entrustVersionExtension = entrust.branch("65.0"); + + /** + * cast5CBC OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840) nt(113533) nsn(7) algorithms(66) 10} SEE RFC 2984 + */ + ASN1ObjectIdentifier cast5CBC = entrust.branch("66.10"); + + // + // HMAC-SHA1 hMAC-SHA1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) + // dod(6) internet(1) security(5) mechanisms(5) 8 1 2 } + // + ASN1ObjectIdentifier hMAC_SHA1 = new ASN1ObjectIdentifier("1.3.6.1.5.5.8.1.2"); + + // + // Ascom + // + ASN1ObjectIdentifier as_sys_sec_alg_ideaCBC = new ASN1ObjectIdentifier("1.3.6.1.4.1.188.7.1.1.2"); + + // + // Peter Gutmann's Cryptlib + // + ASN1ObjectIdentifier cryptlib = new ASN1ObjectIdentifier("1.3.6.1.4.1.3029"); + + ASN1ObjectIdentifier cryptlib_algorithm = cryptlib.branch("1"); + ASN1ObjectIdentifier cryptlib_algorithm_blowfish_ECB = cryptlib_algorithm.branch("1.1"); + ASN1ObjectIdentifier cryptlib_algorithm_blowfish_CBC = cryptlib_algorithm.branch("1.2"); + ASN1ObjectIdentifier cryptlib_algorithm_blowfish_CFB = cryptlib_algorithm.branch("1.3"); + ASN1ObjectIdentifier cryptlib_algorithm_blowfish_OFB = cryptlib_algorithm.branch("1.4"); + + // + // Blake2b/Blake2s + // + ASN1ObjectIdentifier blake2 = new ASN1ObjectIdentifier("1.3.6.1.4.1.1722.12.2"); + + ASN1ObjectIdentifier id_blake2b160 = blake2.branch("1.5"); + ASN1ObjectIdentifier id_blake2b256 = blake2.branch("1.8"); + ASN1ObjectIdentifier id_blake2b384 = blake2.branch("1.12"); + ASN1ObjectIdentifier id_blake2b512 = blake2.branch("1.16"); + + ASN1ObjectIdentifier id_blake2s128 = blake2.branch("2.4"); + ASN1ObjectIdentifier id_blake2s160 = blake2.branch("2.5"); + ASN1ObjectIdentifier id_blake2s224 = blake2.branch("2.7"); + ASN1ObjectIdentifier id_blake2s256 = blake2.branch("2.8"); + + ASN1ObjectIdentifier blake3 = blake2.branch("3"); + + ASN1ObjectIdentifier blake3_256 = blake3.branch("8"); + + // + // Scrypt + ASN1ObjectIdentifier id_scrypt = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.4.11"); + + // Composite key/signature oid - prototyping + // + // id-alg-composite OBJECT IDENTIFIER ::= { + // iso(1) identified-organization(3) dod(6) internet(1) private(4) + // enterprise(1) OpenCA(18227) Algorithms(2) id-alg-composite(1) } + ASN1ObjectIdentifier id_alg_composite = new ASN1ObjectIdentifier("1.3.6.1.4.1.18227.2.1"); + + // -- To be replaced by IANA + // + //id-composite-key OBJECT IDENTIFIER ::= { + // + // joint-iso-itu-t(2) country(16) us(840) organization(1) entrust(114027) + // + // Algorithm(80) Composite(4) CompositeKey(1) + ASN1ObjectIdentifier id_composite_key = new ASN1ObjectIdentifier("2.16.840.1.114027.80.4.1"); + + ASN1ObjectIdentifier id_oracle_pkcs12_trusted_key_usage = new ASN1ObjectIdentifier("2.16.840.1.113894.746875.1.1"); + + // COMPOSITE SIGNATURES START + // -- To be replaced by IANA + // Composite signature related OIDs. Based https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html + // The current OIDs are EXPERIMENTAL and are going to change. + ASN1ObjectIdentifier id_composite_signatures = new ASN1ObjectIdentifier("2.16.840.1.114027.80.8.1"); + ASN1ObjectIdentifier id_MLDSA44_RSA2048_PSS_SHA256 = id_composite_signatures.branch("1"); + ASN1ObjectIdentifier id_MLDSA44_RSA2048_PKCS15_SHA256 = id_composite_signatures.branch("2"); + ASN1ObjectIdentifier id_MLDSA44_Ed25519_SHA512 = id_composite_signatures.branch("3"); + ASN1ObjectIdentifier id_MLDSA44_ECDSA_P256_SHA256 = id_composite_signatures.branch("4"); + ASN1ObjectIdentifier id_MLDSA44_ECDSA_brainpoolP256r1_SHA256 = id_composite_signatures.branch("5"); + ASN1ObjectIdentifier id_MLDSA65_RSA3072_PSS_SHA512 = id_composite_signatures.branch("6"); + ASN1ObjectIdentifier id_MLDSA65_RSA3072_PKCS15_SHA512 = id_composite_signatures.branch("7"); + ASN1ObjectIdentifier id_MLDSA65_ECDSA_P256_SHA512 = id_composite_signatures.branch("8"); + ASN1ObjectIdentifier id_MLDSA65_ECDSA_brainpoolP256r1_SHA512 = id_composite_signatures.branch("9"); + ASN1ObjectIdentifier id_MLDSA65_Ed25519_SHA512 = id_composite_signatures.branch("10"); + ASN1ObjectIdentifier id_MLDSA87_ECDSA_P384_SHA512 = id_composite_signatures.branch("11"); + ASN1ObjectIdentifier id_MLDSA87_ECDSA_brainpoolP384r1_SHA512 = id_composite_signatures.branch("12"); + ASN1ObjectIdentifier id_MLDSA87_Ed448_SHA512 = id_composite_signatures.branch("13"); + + // Falcon-based composites below were removed from the IETF draft in version 13 and are expected to be included in a later/separate standard. + // Most likely due to the fact that the Falcon (FN-DSA) NIST standard is going to be released after the Dilithium (ML-DSA) standard. + // However, we still leave their implementation for experimental usage. + ASN1ObjectIdentifier id_Falcon512_ECDSA_P256_SHA256 = id_composite_signatures.branch("14"); + ASN1ObjectIdentifier id_Falcon512_ECDSA_brainpoolP256r1_SHA256 = id_composite_signatures.branch("15"); + ASN1ObjectIdentifier id_Falcon512_Ed25519_SHA512 = id_composite_signatures.branch("16"); + // COMPOSITE SIGNATURES END +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/misc/NetscapeCertType.java b/core/src/main/java/org/bouncycastle/internal/asn1/misc/NetscapeCertType.java new file mode 100644 index 0000000000..b8ea5a0193 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/misc/NetscapeCertType.java @@ -0,0 +1,60 @@ +package org.bouncycastle.internal.asn1.misc; + +import org.bouncycastle.asn1.ASN1BitString; +import org.bouncycastle.asn1.DERBitString; + +/** + * The NetscapeCertType object. + *
    + *    NetscapeCertType ::= BIT STRING {
    + *         SSLClient               (0),
    + *         SSLServer               (1),
    + *         S/MIME                  (2),
    + *         Object Signing          (3),
    + *         Reserved                (4),
    + *         SSL CA                  (5),
    + *         S/MIME CA               (6),
    + *         Object Signing CA       (7) }
    + * 
    + */ +public class NetscapeCertType + extends DERBitString +{ + public static final int sslClient = (1 << 7); + public static final int sslServer = (1 << 6); + public static final int smime = (1 << 5); + public static final int objectSigning = (1 << 4); + public static final int reserved = (1 << 3); + public static final int sslCA = (1 << 2); + public static final int smimeCA = (1 << 1); + public static final int objectSigningCA = (1 << 0); + + /** + * Basic constructor. + * + * @param usage - the bitwise OR of the Key Usage flags giving the + * allowed uses for the key. + * e.g. (X509NetscapeCertType.sslCA | X509NetscapeCertType.smimeCA) + */ + public NetscapeCertType( + int usage) + { + super(getBytes(usage), getPadBits(usage)); + } + + public NetscapeCertType( + ASN1BitString usage) + { + super(usage.getBytes(), usage.getPadBits()); + } + + public boolean hasUsages(int usages) + { + return (intValue() & usages) == usages; + } + + public String toString() + { + return "NetscapeCertType: 0x" + Integer.toHexString(intValue()); + } +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/misc/NetscapeRevocationURL.java b/core/src/main/java/org/bouncycastle/internal/asn1/misc/NetscapeRevocationURL.java new file mode 100644 index 0000000000..f8ac5e65e3 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/misc/NetscapeRevocationURL.java @@ -0,0 +1,19 @@ +package org.bouncycastle.internal.asn1.misc; + +import org.bouncycastle.asn1.ASN1IA5String; +import org.bouncycastle.asn1.DERIA5String; + +public class NetscapeRevocationURL + extends DERIA5String +{ + public NetscapeRevocationURL( + ASN1IA5String str) + { + super(str.getString()); + } + + public String toString() + { + return "NetscapeRevocationURL: " + this.getString(); + } +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/misc/ScryptParams.java b/core/src/main/java/org/bouncycastle/internal/asn1/misc/ScryptParams.java new file mode 100644 index 0000000000..38641ab2a9 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/misc/ScryptParams.java @@ -0,0 +1,147 @@ +package org.bouncycastle.internal.asn1.misc; + +import java.math.BigInteger; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.util.Arrays; + +/** + * RFC 7914 scrypt parameters. + * + *
    + * scrypt-params ::= SEQUENCE {
    + *      salt OCTET STRING,
    + *      costParameter INTEGER (1..MAX),
    + *      blockSize INTEGER (1..MAX),
    + *      parallelizationParameter INTEGER (1..MAX),
    + *      keyLength INTEGER (1..MAX) OPTIONAL
    + * }
    + * 
    + */ +public class ScryptParams + extends ASN1Object +{ + private final byte[] salt; + private final BigInteger costParameter; + private final BigInteger blockSize; + private final BigInteger parallelizationParameter; + private final BigInteger keyLength; + + public ScryptParams(byte[] salt, int costParameter, int blockSize, int parallelizationParameter) + { + this(salt, BigInteger.valueOf(costParameter), BigInteger.valueOf(blockSize), BigInteger.valueOf(parallelizationParameter), null); + } + + public ScryptParams(byte[] salt, int costParameter, int blockSize, int parallelizationParameter, int keyLength) + { + this(salt, BigInteger.valueOf(costParameter), BigInteger.valueOf(blockSize), BigInteger.valueOf(parallelizationParameter), BigInteger.valueOf(keyLength)); + } + + /** + * Base constructor. + * + * @param salt salt value + * @param costParameter specifies the CPU/Memory cost parameter N + * @param blockSize block size parameter r + * @param parallelizationParameter parallelization parameter + * @param keyLength length of key to be derived (in octects) + */ + public ScryptParams(byte[] salt, BigInteger costParameter, BigInteger blockSize, BigInteger parallelizationParameter, BigInteger keyLength) + { + this.salt = Arrays.clone(salt); + this.costParameter = costParameter; + this.blockSize = blockSize; + this.parallelizationParameter = parallelizationParameter; + this.keyLength = keyLength; + } + + public static ScryptParams getInstance( + Object o) + { + if (o instanceof ScryptParams) + { + return (ScryptParams)o; + } + else if (o != null) + { + return new ScryptParams(ASN1Sequence.getInstance(o)); + } + + return null; + } + + private ScryptParams(ASN1Sequence seq) + { + if (seq.size() != 4 && seq.size() != 5) + { + throw new IllegalArgumentException("invalid sequence: size = " + seq.size()); + } + + this.salt = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets()); + this.costParameter = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue(); + this.blockSize = ASN1Integer.getInstance(seq.getObjectAt(2)).getValue(); + this.parallelizationParameter = ASN1Integer.getInstance(seq.getObjectAt(3)).getValue(); + + if (seq.size() == 5) + { + this.keyLength = ASN1Integer.getInstance(seq.getObjectAt(4)).getValue(); + } + else + { + this.keyLength = null; + } + } + + public byte[] getSalt() + { + return Arrays.clone(salt); + } + + public BigInteger getCostParameter() + { + return costParameter; + } + + public BigInteger getBlockSize() + { + return blockSize; + } + + public BigInteger getParallelizationParameter() + { + return parallelizationParameter; + } + + /** + * Return the length in octets for the derived key. + * + * @return length for key to be derived (in octets) + */ + public BigInteger getKeyLength() + { + return keyLength; + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(5); + + v.add(new DEROctetString(salt)); + v.add(new ASN1Integer(costParameter)); + v.add(new ASN1Integer(blockSize)); + v.add(new ASN1Integer(parallelizationParameter)); + if (keyLength != null) + { + v.add(new ASN1Integer(keyLength)); + } + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/misc/VerisignCzagExtension.java b/core/src/main/java/org/bouncycastle/internal/asn1/misc/VerisignCzagExtension.java new file mode 100644 index 0000000000..833fb49e1d --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/misc/VerisignCzagExtension.java @@ -0,0 +1,19 @@ +package org.bouncycastle.internal.asn1.misc; + +import org.bouncycastle.asn1.ASN1IA5String; +import org.bouncycastle.asn1.DERIA5String; + +public class VerisignCzagExtension + extends DERIA5String +{ + public VerisignCzagExtension( + ASN1IA5String str) + { + super(str.getString()); + } + + public String toString() + { + return "VerisignCzagExtension: " + this.getString(); + } +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/nsri/NSRIObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/nsri/NSRIObjectIdentifiers.java new file mode 100644 index 0000000000..5ca5d0be62 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/nsri/NSRIObjectIdentifiers.java @@ -0,0 +1,58 @@ +package org.bouncycastle.internal.asn1.nsri; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +public interface NSRIObjectIdentifiers +{ + ASN1ObjectIdentifier nsri = new ASN1ObjectIdentifier("1.2.410.200046"); + + ASN1ObjectIdentifier id_algorithm = nsri.branch("1"); + + ASN1ObjectIdentifier id_sea = id_algorithm.branch("1"); + ASN1ObjectIdentifier id_pad = id_algorithm.branch("2"); + + ASN1ObjectIdentifier id_pad_null = id_algorithm.branch("0"); + ASN1ObjectIdentifier id_pad_1 = id_algorithm.branch("1"); + + ASN1ObjectIdentifier id_aria128_ecb = id_sea.branch("1"); + ASN1ObjectIdentifier id_aria128_cbc = id_sea.branch("2"); + ASN1ObjectIdentifier id_aria128_cfb = id_sea.branch("3"); + ASN1ObjectIdentifier id_aria128_ofb = id_sea.branch("4"); + ASN1ObjectIdentifier id_aria128_ctr = id_sea.branch("5"); + + ASN1ObjectIdentifier id_aria192_ecb = id_sea.branch("6"); + ASN1ObjectIdentifier id_aria192_cbc = id_sea.branch("7"); + ASN1ObjectIdentifier id_aria192_cfb = id_sea.branch("8"); + ASN1ObjectIdentifier id_aria192_ofb = id_sea.branch("9"); + ASN1ObjectIdentifier id_aria192_ctr = id_sea.branch("10"); + + ASN1ObjectIdentifier id_aria256_ecb = id_sea.branch("11"); + ASN1ObjectIdentifier id_aria256_cbc = id_sea.branch("12"); + ASN1ObjectIdentifier id_aria256_cfb = id_sea.branch("13"); + ASN1ObjectIdentifier id_aria256_ofb = id_sea.branch("14"); + ASN1ObjectIdentifier id_aria256_ctr = id_sea.branch("15"); + + ASN1ObjectIdentifier id_aria128_cmac = id_sea.branch("21"); + ASN1ObjectIdentifier id_aria192_cmac = id_sea.branch("22"); + ASN1ObjectIdentifier id_aria256_cmac = id_sea.branch("23"); + + ASN1ObjectIdentifier id_aria128_ocb2 = id_sea.branch("31"); + ASN1ObjectIdentifier id_aria192_ocb2 = id_sea.branch("32"); + ASN1ObjectIdentifier id_aria256_ocb2 = id_sea.branch("33"); + + ASN1ObjectIdentifier id_aria128_gcm = id_sea.branch("34"); + ASN1ObjectIdentifier id_aria192_gcm = id_sea.branch("35"); + ASN1ObjectIdentifier id_aria256_gcm = id_sea.branch("36"); + + ASN1ObjectIdentifier id_aria128_ccm = id_sea.branch("37"); + ASN1ObjectIdentifier id_aria192_ccm = id_sea.branch("38"); + ASN1ObjectIdentifier id_aria256_ccm = id_sea.branch("39"); + + ASN1ObjectIdentifier id_aria128_kw = id_sea.branch("40"); + ASN1ObjectIdentifier id_aria192_kw = id_sea.branch("41"); + ASN1ObjectIdentifier id_aria256_kw = id_sea.branch("42"); + + ASN1ObjectIdentifier id_aria128_kwp = id_sea.branch("43"); + ASN1ObjectIdentifier id_aria192_kwp = id_sea.branch("44"); + ASN1ObjectIdentifier id_aria256_kwp = id_sea.branch("45"); +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/ntt/NTTObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/ntt/NTTObjectIdentifiers.java new file mode 100644 index 0000000000..d84297c24c --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/ntt/NTTObjectIdentifiers.java @@ -0,0 +1,25 @@ +package org.bouncycastle.internal.asn1.ntt; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +/** + * From RFC 3657 + * Use of the Camellia Encryption Algorithm + * in Cryptographic Message Syntax (CMS) + */ +public interface NTTObjectIdentifiers +{ + /** id-camellia128-cbc; OID 1.2.392.200011.61.1.1.1.2 */ + static final ASN1ObjectIdentifier id_camellia128_cbc = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.1.2"); + /** id-camellia192-cbc; OID 1.2.392.200011.61.1.1.1.3 */ + static final ASN1ObjectIdentifier id_camellia192_cbc = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.1.3"); + /** id-camellia256-cbc; OID 1.2.392.200011.61.1.1.1.4 */ + static final ASN1ObjectIdentifier id_camellia256_cbc = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.1.4"); + + /** id-camellia128-wrap; OID 1.2.392.200011.61.1.1.3.2 */ + static final ASN1ObjectIdentifier id_camellia128_wrap = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.3.2"); + /** id-camellia192-wrap; OID 1.2.392.200011.61.1.1.3.3 */ + static final ASN1ObjectIdentifier id_camellia192_wrap = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.3.3"); + /** id-camellia256-wrap; OID 1.2.392.200011.61.1.1.3.4 */ + static final ASN1ObjectIdentifier id_camellia256_wrap = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.3.4"); +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/oiw/ElGamalParameter.java b/core/src/main/java/org/bouncycastle/internal/asn1/oiw/ElGamalParameter.java new file mode 100644 index 0000000000..d281f78269 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/oiw/ElGamalParameter.java @@ -0,0 +1,68 @@ +package org.bouncycastle.internal.asn1.oiw; + +import java.math.BigInteger; +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERSequence; + +public class ElGamalParameter + extends ASN1Object +{ + ASN1Integer p, g; + + public ElGamalParameter( + BigInteger p, + BigInteger g) + { + this.p = new ASN1Integer(p); + this.g = new ASN1Integer(g); + } + + private ElGamalParameter( + ASN1Sequence seq) + { + Enumeration e = seq.getObjects(); + + p = (ASN1Integer)e.nextElement(); + g = (ASN1Integer)e.nextElement(); + } + + public static ElGamalParameter getInstance(Object o) + { + if (o instanceof ElGamalParameter) + { + return (ElGamalParameter)o; + } + else if (o != null) + { + return new ElGamalParameter(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public BigInteger getP() + { + return p.getPositiveValue(); + } + + public BigInteger getG() + { + return g.getPositiveValue(); + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(2); + + v.add(p); + v.add(g); + + return new DERSequence(v); + } +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/oiw/OIWObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/oiw/OIWObjectIdentifiers.java new file mode 100644 index 0000000000..2bd88e78d0 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/oiw/OIWObjectIdentifiers.java @@ -0,0 +1,50 @@ +package org.bouncycastle.internal.asn1.oiw; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +/** + * OIW organization's OIDs: + *

    + * id-SHA1 OBJECT IDENTIFIER ::= + * {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } + */ +public interface OIWObjectIdentifiers +{ + /** OID: 1.3.14.3.2.2 */ + static final ASN1ObjectIdentifier md4WithRSA = new ASN1ObjectIdentifier("1.3.14.3.2.2"); + /** OID: 1.3.14.3.2.3 */ + static final ASN1ObjectIdentifier md5WithRSA = new ASN1ObjectIdentifier("1.3.14.3.2.3"); + /** OID: 1.3.14.3.2.4 */ + static final ASN1ObjectIdentifier md4WithRSAEncryption = new ASN1ObjectIdentifier("1.3.14.3.2.4"); + + /** OID: 1.3.14.3.2.6 */ + static final ASN1ObjectIdentifier desECB = new ASN1ObjectIdentifier("1.3.14.3.2.6"); + /** OID: 1.3.14.3.2.7 */ + static final ASN1ObjectIdentifier desCBC = new ASN1ObjectIdentifier("1.3.14.3.2.7"); + /** OID: 1.3.14.3.2.8 */ + static final ASN1ObjectIdentifier desOFB = new ASN1ObjectIdentifier("1.3.14.3.2.8"); + /** OID: 1.3.14.3.2.9 */ + static final ASN1ObjectIdentifier desCFB = new ASN1ObjectIdentifier("1.3.14.3.2.9"); + + /** OID: 1.3.14.3.2.17 */ + static final ASN1ObjectIdentifier desEDE = new ASN1ObjectIdentifier("1.3.14.3.2.17"); + + /** OID: 1.3.14.3.2.26 */ + static final ASN1ObjectIdentifier idSHA1 = new ASN1ObjectIdentifier("1.3.14.3.2.26"); + + /** OID: 1.3.14.3.2.27 */ + static final ASN1ObjectIdentifier dsaWithSHA1 = new ASN1ObjectIdentifier("1.3.14.3.2.27"); + + /** OID: 1.3.14.3.2.29 */ + static final ASN1ObjectIdentifier sha1WithRSA = new ASN1ObjectIdentifier("1.3.14.3.2.29"); + + /** + *

    +     * ElGamal Algorithm OBJECT IDENTIFIER ::=    
    +     *   {iso(1) identified-organization(3) oiw(14) dirservsig(7) algorithm(2) encryption(1) 1 }
    +     * 
    + * OID: 1.3.14.7.2.1.1 + */ + static final ASN1ObjectIdentifier elGamalAlgorithm = new ASN1ObjectIdentifier("1.3.14.7.2.1.1"); + +} diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/rosstandart/RosstandartObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/internal/asn1/rosstandart/RosstandartObjectIdentifiers.java new file mode 100644 index 0000000000..047ce1e4be --- /dev/null +++ b/core/src/main/java/org/bouncycastle/internal/asn1/rosstandart/RosstandartObjectIdentifiers.java @@ -0,0 +1,52 @@ +package org.bouncycastle.internal.asn1.rosstandart; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +public interface RosstandartObjectIdentifiers +{ + static final ASN1ObjectIdentifier rosstandart = new ASN1ObjectIdentifier("1.2.643.7"); + + static final ASN1ObjectIdentifier id_tc26 = rosstandart.branch("1"); + + static final ASN1ObjectIdentifier id_tc26_gost_3411_12_256 = id_tc26.branch("1.2.2"); + + static final ASN1ObjectIdentifier id_tc26_gost_3411_12_512 = id_tc26.branch("1.2.3"); + + static final ASN1ObjectIdentifier id_tc26_hmac_gost_3411_12_256 = id_tc26.branch("1.4.1"); + + static final ASN1ObjectIdentifier id_tc26_hmac_gost_3411_12_512 = id_tc26.branch("1.4.2"); + + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_256 = id_tc26.branch("1.1.1"); + + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_512 = id_tc26.branch("1.1.2"); + + static final ASN1ObjectIdentifier id_tc26_signwithdigest_gost_3410_12_256 = id_tc26.branch("1.3.2"); + + static final ASN1ObjectIdentifier id_tc26_signwithdigest_gost_3410_12_512 = id_tc26.branch("1.3.3"); + + static final ASN1ObjectIdentifier id_tc26_agreement = id_tc26.branch("1.6"); + + static final ASN1ObjectIdentifier id_tc26_agreement_gost_3410_12_256 = id_tc26_agreement.branch("1"); + + static final ASN1ObjectIdentifier id_tc26_agreement_gost_3410_12_512 = id_tc26_agreement.branch("2"); + + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_256_paramSet = id_tc26.branch("2.1.1"); + + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_256_paramSetA = id_tc26_gost_3410_12_256_paramSet.branch("1"); + + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_256_paramSetB = id_tc26_gost_3410_12_256_paramSet.branch("2"); + + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_256_paramSetC = id_tc26_gost_3410_12_256_paramSet.branch("3"); + + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_256_paramSetD = id_tc26_gost_3410_12_256_paramSet.branch("4"); + + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_512_paramSet = id_tc26.branch("2.1.2"); + + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_512_paramSetA = id_tc26_gost_3410_12_512_paramSet.branch("1"); + + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_512_paramSetB = id_tc26_gost_3410_12_512_paramSet.branch("2"); + + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_512_paramSetC = id_tc26_gost_3410_12_512_paramSet.branch("3"); + + static final ASN1ObjectIdentifier id_tc26_gost_28147_param_Z = id_tc26.branch("2.5.1.1"); +} diff --git a/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java b/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java index 04bde03404..4bef7efac6 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java +++ b/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java @@ -123,6 +123,19 @@ public synchronized Config configure() return new Config(this.coord, this.endomorphism, this.multiplier); } + public int getFieldElementEncodingLength() + { + return (getFieldSize() + 7) / 8; + } + + public int getAffinePointEncodingLength(boolean compressed) + { + int fieldLength = getFieldElementEncodingLength(); + return compressed + ? 1 + fieldLength + : 1 + fieldLength * 2; + } + public ECPoint validatePoint(BigInteger x, BigInteger y) { ECPoint p = createPoint(x, y); @@ -379,7 +392,7 @@ public ECMultiplier getMultiplier() public ECPoint decodePoint(byte[] encoded) { ECPoint p = null; - int expectedLength = (getFieldSize() + 7) / 8; + int expectedLength = getFieldElementEncodingLength(); byte type = encoded[0]; switch (type) @@ -463,25 +476,15 @@ public ECPoint decodePoint(byte[] encoded) */ public ECLookupTable createCacheSafeLookupTable(final ECPoint[] points, int off, final int len) { - final int FE_BYTES = (getFieldSize() + 7) >>> 3; - + final int FE_BYTES = getFieldElementEncodingLength(); final byte[] table = new byte[len * FE_BYTES * 2]; + int pos = 0; + for (int i = 0; i < len; ++i) { - int pos = 0; - for (int i = 0; i < len; ++i) - { - ECPoint p = points[off + i]; - byte[] px = p.getRawXCoord().toBigInteger().toByteArray(); - byte[] py = p.getRawYCoord().toBigInteger().toByteArray(); - - int pxStart = px.length > FE_BYTES ? 1 : 0, pxLen = px.length - pxStart; - int pyStart = py.length > FE_BYTES ? 1 : 0, pyLen = py.length - pyStart; - - System.arraycopy(px, pxStart, table, pos + FE_BYTES - pxLen, pxLen); pos += FE_BYTES; - System.arraycopy(py, pyStart, table, pos + FE_BYTES - pyLen, pyLen); pos += FE_BYTES; - } + ECPoint p = points[off + i]; + p.getRawXCoord().encodeTo(table, pos); pos += FE_BYTES; + p.getRawYCoord().encodeTo(table, pos); pos += FE_BYTES; } - return new AbstractECLookupTable() { public int getSize() @@ -845,6 +848,11 @@ public static BigInteger inverse(int m, int[] ks, BigInteger x) private static FiniteField buildField(int m, int k1, int k2, int k3) { + if (m > Properties.asInteger("org.bouncycastle.ec.max_f2m_field_size", 1142)) // twice 571 + { + throw new IllegalArgumentException("field size out of range: " + m); + } + int[] exponents = (k2 | k3) == 0 ? new int[]{ 0, k1, m } : new int[]{ 0, k1, k2, k3, m }; @@ -855,6 +863,15 @@ private static FiniteField buildField(int m, int k1, int k2, int k3) protected AbstractF2m(int m, int k1, int k2, int k3) { super(buildField(m, k1, k2, k3)); + + if (Properties.isOverrideSet("org.bouncycastle.ec.disable")) + { + throw new UnsupportedOperationException("F2M disabled by \"org.bouncycastle.ec.disable\""); + } + if (Properties.isOverrideSet("org.bouncycastle.ec.disable_f2m")) + { + throw new UnsupportedOperationException("F2M disabled by \"org.bouncycastle.ec.disable_f2m\""); + } } public ECPoint createPoint(BigInteger x, BigInteger y) @@ -997,7 +1014,7 @@ protected ECFieldElement solveQuadraticEquation(ECFieldElement beta) } int m = this.getFieldSize(); - + // For odd m, use the half-trace if (0 != (m & 1)) { diff --git a/core/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java b/core/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java index ef2221265f..c47204ffc0 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java +++ b/core/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java @@ -85,7 +85,17 @@ public String toString() public byte[] getEncoded() { - return BigIntegers.asUnsignedByteArray((getFieldSize() + 7) / 8, toBigInteger()); + return BigIntegers.asUnsignedByteArray(getEncodedLength(), toBigInteger()); + } + + public int getEncodedLength() + { + return (getFieldSize() + 7) / 8; + } + + public void encodeTo(byte[] buf, int off) + { + BigIntegers.asUnsignedByteArray(toBigInteger(), buf, off, getEncodedLength()); } public static abstract class AbstractFp extends ECFieldElement diff --git a/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java b/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java index cc4f63a437..44349f5a4e 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java +++ b/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java @@ -501,11 +501,51 @@ public byte[] getEncoded(boolean compressed) byte[] Y = normed.getYCoord().getEncoded(); - byte[] PO = new byte[X.length + Y.length + 1]; - PO[0] = 0x04; - System.arraycopy(X, 0, PO, 1, X.length); - System.arraycopy(Y, 0, PO, X.length + 1, Y.length); - return PO; + { + byte[] PO = new byte[X.length + Y.length + 1]; + PO[0] = 0x04; + System.arraycopy(X, 0, PO, 1, X.length); + System.arraycopy(Y, 0, PO, X.length + 1, Y.length); + return PO; + } + } + + public int getEncodedLength(boolean compressed) + { + if (isInfinity()) + { + return 1; + } + + if (compressed) + { + return 1 + getXCoord().getEncodedLength(); + } + + return 1 + getXCoord().getEncodedLength() + getYCoord().getEncodedLength(); + } + + public void encodeTo(boolean compressed, byte[] buf, int off) + { + if (isInfinity()) + { + buf[off] = 0x00; + return; + } + + ECPoint normed = normalize(); + ECFieldElement X = normed.getXCoord(), Y = normed.getYCoord(); + + if (compressed) + { + buf[off] = (byte)(normed.getCompressionYTilde() ? 0x03 : 0x02); + X.encodeTo(buf, off + 1); + return; + } + + buf[off] = 0x04; + X.encodeTo(buf, off + 1); + Y.encodeTo(buf, off + 1 + X.getEncodedLength()); } protected abstract boolean getCompressionYTilde(); diff --git a/core/src/main/java/org/bouncycastle/math/ec/rfc7748/X25519.java b/core/src/main/java/org/bouncycastle/math/ec/rfc7748/X25519.java index 2e6a8e95a2..02fdefed0f 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/rfc7748/X25519.java +++ b/core/src/main/java/org/bouncycastle/math/ec/rfc7748/X25519.java @@ -153,6 +153,12 @@ public static void scalarMult(byte[] k, int kOff, byte[] u, int uOff, byte[] r, public static void scalarMultBase(byte[] k, int kOff, byte[] r, int rOff) { + // Equivalent (but much slower) +// byte[] u = new byte[POINT_SIZE]; +// u[0] = 9; +// +// scalarMult(k, kOff, u, 0, r, rOff); + int[] y = F.create(); int[] z = F.create(); diff --git a/core/src/main/java/org/bouncycastle/math/ec/rfc7748/X25519Field.java b/core/src/main/java/org/bouncycastle/math/ec/rfc7748/X25519Field.java index 074ffc87a4..cf2d1913b7 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/rfc7748/X25519Field.java +++ b/core/src/main/java/org/bouncycastle/math/ec/rfc7748/X25519Field.java @@ -12,8 +12,8 @@ public abstract class X25519Field private static final int[] P32 = new int[]{ 0xFFFFFFED, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF }; - private static final int[] ROOT_NEG_ONE = new int[]{ 0x020EA0B0, 0x0386C9D2, 0x00478C4E, 0x0035697F, 0x005E8630, - 0x01FBD7A7, 0x0340264F, 0x01F0B2B4, 0x00027E0E, 0x00570649 }; + private static final int[] ROOT_NEG_ONE = new int[]{ -0x01F15F50, -0x0079362D, 0x00478C4F, 0x0035697F, 0x005E8630, + 0x01FBD7A7, -0x00BFD9B1, -0x000F4D4B, 0x00027E0F, 0x00570649 }; protected X25519Field() {} @@ -519,7 +519,7 @@ public static void negate(int[] x, int[] z) public static void normalize(int[] z) { - int x = ((z[9] >>> 23) & 1); + int x = ((z[9] >>> (24 - 1)) & 1); reduce(z, x); reduce(z, -x); // assert z[9] >>> 24 == 0; diff --git a/core/src/main/java/org/bouncycastle/math/ec/rfc7748/X448.java b/core/src/main/java/org/bouncycastle/math/ec/rfc7748/X448.java index 480b60415b..3954ba110c 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/rfc7748/X448.java +++ b/core/src/main/java/org/bouncycastle/math/ec/rfc7748/X448.java @@ -161,6 +161,12 @@ public static void scalarMult(byte[] k, int kOff, byte[] u, int uOff, byte[] r, public static void scalarMultBase(byte[] k, int kOff, byte[] r, int rOff) { + // Equivalent (but much slower) +// byte[] u = new byte[POINT_SIZE]; +// u[0] = 5; +// +// scalarMult(k, kOff, u, 0, r, rOff); + int[] x = F.create(); int[] y = F.create(); diff --git a/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Ed25519.java b/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Ed25519.java index b12899241d..7aedfb90ef 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Ed25519.java +++ b/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Ed25519.java @@ -157,7 +157,7 @@ private static byte[] calculateS(byte[] r, byte[] k, byte[] s) byte[] result = new byte[SCALAR_BYTES * 2]; Codec.encode32(t, 0, t.length, result, 0); - return Scalar25519.reduce(result); + return Scalar25519.reduce512(result); } private static boolean checkContextVar(byte[] ctx , byte phflag) @@ -175,13 +175,14 @@ private static int checkPoint(PointAffine p) F.sqr(p.x, u); F.sqr(p.y, v); F.mul(u, v, t); - F.sub(v, u, v); + F.sub(u, v, u); F.mul(t, C_d, t); F.addOne(t); - F.sub(t, v, t); + F.add(t, u, t); F.normalize(t); + F.normalize(v); - return F.isZero(t); + return F.isZero(t) & ~F.isZero(v); } private static int checkPoint(PointAccum p) @@ -195,15 +196,17 @@ private static int checkPoint(PointAccum p) F.sqr(p.y, v); F.sqr(p.z, w); F.mul(u, v, t); - F.sub(v, u, v); - F.mul(v, w, v); + F.sub(u, v, u); + F.mul(u, w, u); F.sqr(w, w); F.mul(t, C_d, t); F.add(t, w, t); - F.sub(t, v, t); + F.add(t, u, t); F.normalize(t); + F.normalize(v); + F.normalize(w); - return F.isZero(t); + return F.isZero(t) & ~F.isZero(v) & ~F.isZero(w); } private static boolean checkPointFullVar(byte[] p) @@ -443,7 +446,7 @@ private static void implSign(Digest d, byte[] h, byte[] s, byte[] pk, int pkOff, d.update(m, mOff, mLen); d.doFinal(h, 0); - byte[] r = Scalar25519.reduce(h); + byte[] r = Scalar25519.reduce512(h); byte[] R = new byte[POINT_BYTES]; scalarMultBaseEncoded(r, R, 0); @@ -456,7 +459,7 @@ private static void implSign(Digest d, byte[] h, byte[] s, byte[] pk, int pkOff, d.update(m, mOff, mLen); d.doFinal(h, 0); - byte[] k = Scalar25519.reduce(h); + byte[] k = Scalar25519.reduce512(h); byte[] S = calculateS(r, k, s); System.arraycopy(R, 0, sig, sigOff, POINT_BYTES); @@ -556,14 +559,19 @@ private static boolean implVerify(byte[] sig, int sigOff, byte[] pk, int pkOff, d.update(m, mOff, mLen); d.doFinal(h, 0); - byte[] k = Scalar25519.reduce(h); + byte[] k = Scalar25519.reduce512(h); int[] nA = new int[SCALAR_INTS]; Scalar25519.decode(k, nA); int[] v0 = new int[4]; int[] v1 = new int[4]; - Scalar25519.reduceBasisVar(nA, v0, v1); + + if (!Scalar25519.reduceBasisVar(nA, v0, v1)) + { + throw new IllegalStateException(); + } + Scalar25519.multiply128Var(nS, v1, nS); PointAccum pZ = new PointAccum(); @@ -618,14 +626,19 @@ private static boolean implVerify(byte[] sig, int sigOff, PublicPoint publicPoin d.update(m, mOff, mLen); d.doFinal(h, 0); - byte[] k = Scalar25519.reduce(h); + byte[] k = Scalar25519.reduce512(h); int[] nA = new int[SCALAR_INTS]; Scalar25519.decode(k, nA); int[] v0 = new int[4]; int[] v1 = new int[4]; - Scalar25519.reduceBasisVar(nA, v0, v1); + + if (!Scalar25519.reduceBasisVar(nA, v0, v1)) + { + throw new IllegalStateException(); + } + Scalar25519.multiply128Var(nS, v1, nS); PointAccum pZ = new PointAccum(); @@ -667,16 +680,6 @@ private static void invertDoubleZs(PointExtended[] points) F.copy(u, 0, points[0].z, 0); } -// private static boolean isNeutralElementVar(int[] x, int[] y) -// { -// return F.isZeroVar(x) && F.isOneVar(y); -// } - - private static boolean isNeutralElementVar(int[] x, int[] y, int[] z) - { - return F.isZeroVar(x) && F.areEqualVar(y, z); - } - private static void normalizeToAffine(PointAccum p, PointAffine r) { F.inv(p.z, r.y); @@ -692,7 +695,7 @@ private static boolean normalizeToNeutralElementVar(PointAccum p) F.normalize(p.y); F.normalize(p.z); - return isNeutralElementVar(p.x, p.y, p.z); + return F.isZeroVar(p.x) && !F.isZeroVar(p.y) && F.areEqualVar(p.y, p.z); } private static void pointAdd(PointExtended p, PointExtended q, PointExtended r, PointTemp t) @@ -1190,7 +1193,7 @@ private static void scalarMult(byte[] k, PointAffine p, PointAccum r) { int[] n = new int[SCALAR_INTS]; Scalar25519.decode(k, n); - Scalar25519.toSignedDigits(256, n, n); + Scalar25519.toSignedDigits(256, n); PointPrecompZ q = new PointPrecompZ(); PointTemp t = new PointTemp(); @@ -1228,7 +1231,7 @@ private static void scalarMultBase(byte[] k, PointAccum r) int[] n = new int[SCALAR_INTS]; Scalar25519.decode(k, n); - Scalar25519.toSignedDigits(PRECOMP_RANGE, n, n); + Scalar25519.toSignedDigits(PRECOMP_RANGE, n); groupCombBits(n); PointPrecomp p = new PointPrecomp(); @@ -1364,6 +1367,14 @@ private static void scalarMultStraus128Var(int[] nb, int[] np, PointAffine p, in int bit = 128; while (--bit >= 0) + { + if ((ws_b[bit] | ws_b[128 + bit] | ws_p[bit] | ws_q[bit]) != 0) + { + break; + } + } + + for (; bit >= 0; --bit) { int wb = ws_b[bit]; if (wb != 0) diff --git a/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Ed448.java b/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Ed448.java index 7d1113105b..2d2053e649 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Ed448.java +++ b/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Ed448.java @@ -70,7 +70,7 @@ private static class F extends X448Field {}; 0x03AC222B, 0x0304DB8E, 0x083EE319, 0x05E5DB0B, 0x0ECA503B, 0x0B1C6539, 0x078A8DCE, 0x02D256BC, 0x04A8B05E, 0x0BD9FD57, 0x0A1C3CB8 }; - private static final int C_d = -39081; + private static final int C_d = 39081; // private static final int WNAF_WIDTH = 6; private static final int WNAF_WIDTH_225 = 5; @@ -125,7 +125,7 @@ private static byte[] calculateS(byte[] r, byte[] k, byte[] s) byte[] result = new byte[SCALAR_BYTES * 2]; Codec.encode32(t, 0, t.length, result, 0); - return Scalar448.reduce(result); + return Scalar448.reduce912(result); } private static boolean checkContextVar(byte[] ctx) @@ -143,12 +143,13 @@ private static int checkPoint(PointAffine p) F.sqr(p.y, v); F.mul(u, v, t); F.add(u, v, u); - F.mul(t, -C_d, t); + F.mul(t, C_d, t); F.subOne(t); F.add(t, u, t); F.normalize(t); + F.normalize(v); - return F.isZero(t); + return F.isZero(t) & ~F.isZero(v); } private static int checkPoint(PointProjective p) @@ -165,12 +166,14 @@ private static int checkPoint(PointProjective p) F.add(u, v, u); F.mul(u, w, u); F.sqr(w, w); - F.mul(t, -C_d, t); + F.mul(t, C_d, t); F.sub(t, w, t); F.add(t, u, t); F.normalize(t); + F.normalize(v); + F.normalize(w); - return F.isZero(t); + return F.isZero(t) & ~F.isZero(v) & ~F.isZero(w); } private static boolean checkPointFullVar(byte[] p) @@ -258,7 +261,7 @@ private static boolean decodePointVar(byte[] p, boolean negate, PointAffine r) int[] v = F.create(); F.sqr(r.y, u); - F.mul(u, -C_d, v); + F.mul(u, C_d, v); F.negate(u, u); F.addOne(u); F.addOne(v); @@ -393,7 +396,7 @@ private static void implSign(Xof d, byte[] h, byte[] s, byte[] pk, int pkOff, by d.update(m, mOff, mLen); d.doFinal(h, 0, h.length); - byte[] r = Scalar448.reduce(h); + byte[] r = Scalar448.reduce912(h); byte[] R = new byte[POINT_BYTES]; scalarMultBaseEncoded(r, R, 0); @@ -403,7 +406,7 @@ private static void implSign(Xof d, byte[] h, byte[] s, byte[] pk, int pkOff, by d.update(m, mOff, mLen); d.doFinal(h, 0, h.length); - byte[] k = Scalar448.reduce(h); + byte[] k = Scalar448.reduce912(h); byte[] S = calculateS(r, k, s); System.arraycopy(R, 0, sig, sigOff, POINT_BYTES); @@ -500,14 +503,19 @@ private static boolean implVerify(byte[] sig, int sigOff, byte[] pk, int pkOff, d.update(m, mOff, mLen); d.doFinal(h, 0, h.length); - byte[] k = Scalar448.reduce(h); + byte[] k = Scalar448.reduce912(h); int[] nA = new int[SCALAR_INTS]; Scalar448.decode(k, nA); int[] v0 = new int[8]; int[] v1 = new int[8]; - Scalar448.reduceBasisVar(nA, v0, v1); + + if (!Scalar448.reduceBasisVar(nA, v0, v1)) + { + throw new IllegalStateException(); + } + Scalar448.multiply225Var(nS, v1, nS); PointProjective pZ = new PointProjective(); @@ -559,14 +567,19 @@ private static boolean implVerify(byte[] sig, int sigOff, PublicPoint publicPoin d.update(m, mOff, mLen); d.doFinal(h, 0, h.length); - byte[] k = Scalar448.reduce(h); + byte[] k = Scalar448.reduce912(h); int[] nA = new int[SCALAR_INTS]; Scalar448.decode(k, nA); int[] v0 = new int[8]; int[] v1 = new int[8]; - Scalar448.reduceBasisVar(nA, v0, v1); + + if (!Scalar448.reduceBasisVar(nA, v0, v1)) + { + throw new IllegalStateException(); + } + Scalar448.multiply225Var(nS, v1, nS); PointProjective pZ = new PointProjective(); @@ -607,16 +620,6 @@ private static void invertZs(PointProjective[] points) F.copy(u, 0, points[0].z, 0); } -// private static boolean isNeutralElementVar(int[] x, int[] y) -// { -// return F.isZeroVar(x) && F.isOneVar(y); -// } - - private static boolean isNeutralElementVar(int[] x, int[] y, int[] z) - { - return F.isZeroVar(x) && F.areEqualVar(y, z); - } - private static void normalizeToAffine(PointProjective p, PointAffine r) { F.inv(p.z, r.y); @@ -632,7 +635,7 @@ private static boolean normalizeToNeutralElementVar(PointProjective p) F.normalize(p.y); F.normalize(p.z); - return isNeutralElementVar(p.x, p.y, p.z); + return F.isZeroVar(p.x) && !F.isZeroVar(p.y) && F.areEqualVar(p.y, p.z); } private static void pointAdd(PointAffine p, PointProjective r, PointTemp t) @@ -649,7 +652,7 @@ private static void pointAdd(PointAffine p, PointProjective r, PointTemp t) F.mul(p.x, r.x, c); F.mul(p.y, r.y, d); F.mul(c, d, e); - F.mul(e, -C_d, e); + F.mul(e, C_d, e); // F.apm(b, e, f, g); F.add(b, e, f); F.sub(b, e, g); @@ -684,7 +687,7 @@ private static void pointAdd(PointProjective p, PointProjective r, PointTemp t) F.mul(p.x, r.x, c); F.mul(p.y, r.y, d); F.mul(c, d, e); - F.mul(e, -C_d, e); + F.mul(e, C_d, e); // F.apm(b, e, f, g); F.add(b, e, f); F.sub(b, e, g); @@ -729,7 +732,7 @@ private static void pointAddVar(boolean negate, PointAffine p, PointProjective r F.mul(p.x, r.x, c); F.mul(p.y, r.y, d); F.mul(c, d, e); - F.mul(e, -C_d, e); + F.mul(e, C_d, e); // F.apm(b, e, nf, ng); F.add(b, e, nf); F.sub(b, e, ng); @@ -775,7 +778,7 @@ private static void pointAddVar(boolean negate, PointProjective p, PointProjecti F.mul(p.x, r.x, c); F.mul(p.y, r.y, d); F.mul(c, d, e); - F.mul(e, -C_d, e); + F.mul(e, C_d, e); // F.apm(b, e, nf, ng); F.add(b, e, nf); F.sub(b, e, ng); @@ -888,7 +891,7 @@ private static int[] pointPrecompute(PointProjective p, int count, PointTemp t) pointCopy(p, q); PointProjective d = new PointProjective(); - pointCopy(q, d); + pointCopy(p, d); pointDouble(d, t); int[] table = F.createTable(count * 3); @@ -1258,6 +1261,14 @@ private static void scalarMultStraus225Var(int[] nb, int[] np, PointAffine p, in int bit = 225; while (--bit >= 0) + { + if ((ws_b[bit] | ws_b[225 + bit] | ws_p[bit] | ws_q[bit]) != 0) + { + break; + } + } + + for (; bit >= 0; --bit) { int wb = ws_b[bit]; if (wb != 0) diff --git a/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Scalar25519.java b/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Scalar25519.java index 66dd239c87..175513fba4 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Scalar25519.java +++ b/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Scalar25519.java @@ -7,6 +7,8 @@ abstract class Scalar25519 { static final int SIZE = 8; + private static final int SCALAR_BYTES = SIZE * 4; + private static final long M08L = 0x000000FFL; private static final long M28L = 0x0FFFFFFFL; private static final long M32L = 0xFFFFFFFFL; @@ -52,14 +54,112 @@ static void multiply128Var(int[] x, int[] y128, int[] z) Nat256.subFrom(x, 0, tt, 4, 0); } - byte[] bytes = new byte[64]; + byte[] bytes = new byte[48]; Codec.encode32(tt, 0, 12, bytes, 0); - byte[] r = reduce(bytes); + byte[] r = reduce384(bytes); decode(r, z); } - static byte[] reduce(byte[] n) + static byte[] reduce384(byte[] n) + { + long x00 = Codec.decode32(n, 0) & M32L; // x00:32/-- + long x01 = (Codec.decode24(n, 4) << 4) & M32L; // x01:28/-- + long x02 = Codec.decode32(n, 7) & M32L; // x02:32/-- + long x03 = (Codec.decode24(n, 11) << 4) & M32L; // x03:28/-- + long x04 = Codec.decode32(n, 14) & M32L; // x04:32/-- + long x05 = (Codec.decode24(n, 18) << 4) & M32L; // x05:28/-- + long x06 = Codec.decode32(n, 21) & M32L; // x06:32/-- + long x07 = (Codec.decode24(n, 25) << 4) & M32L; // x07:28/-- + long x08 = Codec.decode32(n, 28) & M32L; // x08:32/-- + long x09 = (Codec.decode24(n, 32) << 4) & M32L; // x09:28/-- + long x10 = Codec.decode32(n, 35) & M32L; // x10:32/-- + long x11 = (Codec.decode24(n, 39) << 4) & M32L; // x11:28/-- + long x12 = Codec.decode32(n, 42) & M32L; // x12:32/-- + long x13 = (Codec.decode16(n, 46) << 4) & M32L; // x13:20/-- + long t; + + // TODO Fix bounds calculations which were copied from Reduce512 + + x13 += (x12 >> 28); x12 &= M28L; // x13:28/22, x12:28/-- + x04 -= x13 * L0; // x04:54/49 + x05 -= x13 * L1; // x05:54/53 + x06 -= x13 * L2; // x06:56/-- + x07 -= x13 * L3; // x07:56/52 + x08 -= x13 * L4; // x08:56/52 + + x12 += (x11 >> 28); x11 &= M28L; // x12:28/24, x11:28/-- + x03 -= x12 * L0; // x03:54/49 + x04 -= x12 * L1; // x04:54/51 + x05 -= x12 * L2; // x05:56/-- + x06 -= x12 * L3; // x06:56/52 + x07 -= x12 * L4; // x07:56/53 + + x11 += (x10 >> 28); x10 &= M28L; // x11:29/--, x10:28/-- + x02 -= x11 * L0; // x02:55/32 + x03 -= x11 * L1; // x03:55/-- + x04 -= x11 * L2; // x04:56/55 + x05 -= x11 * L3; // x05:56/52 + x06 -= x11 * L4; // x06:56/53 + + x10 += (x09 >> 28); x09 &= M28L; // x10:29/--, x09:28/-- + x01 -= x10 * L0; // x01:55/28 + x02 -= x10 * L1; // x02:55/54 + x03 -= x10 * L2; // x03:56/55 + x04 -= x10 * L3; // x04:57/-- + x05 -= x10 * L4; // x05:56/53 + + x08 += (x07 >> 28); x07 &= M28L; // x08:56/53, x07:28/-- + x09 += (x08 >> 28); x08 &= M28L; // x09:29/25, x08:28/-- + + t = x08 >>> 27; + x09 += t; // x09:29/26 + + x00 -= x09 * L0; // x00:55/53 + x01 -= x09 * L1; // x01:55/54 + x02 -= x09 * L2; // x02:57/-- + x03 -= x09 * L3; // x03:57/-- + x04 -= x09 * L4; // x04:57/42 + + x01 += (x00 >> 28); x00 &= M28L; + x02 += (x01 >> 28); x01 &= M28L; + x03 += (x02 >> 28); x02 &= M28L; + x04 += (x03 >> 28); x03 &= M28L; + x05 += (x04 >> 28); x04 &= M28L; + x06 += (x05 >> 28); x05 &= M28L; + x07 += (x06 >> 28); x06 &= M28L; + x08 += (x07 >> 28); x07 &= M28L; + x09 = (x08 >> 28); x08 &= M28L; + + x09 -= t; + +// assert x09 == 0L || x09 == -1L; + + x00 += x09 & L0; + x01 += x09 & L1; + x02 += x09 & L2; + x03 += x09 & L3; + x04 += x09 & L4; + + x01 += (x00 >> 28); x00 &= M28L; + x02 += (x01 >> 28); x01 &= M28L; + x03 += (x02 >> 28); x02 &= M28L; + x04 += (x03 >> 28); x03 &= M28L; + x05 += (x04 >> 28); x04 &= M28L; + x06 += (x05 >> 28); x05 &= M28L; + x07 += (x06 >> 28); x06 &= M28L; + x08 += (x07 >> 28); x07 &= M28L; + + byte[] r = new byte[64]; + Codec.encode56(x00 | (x01 << 28), r, 0); + Codec.encode56(x02 | (x03 << 28), r, 7); + Codec.encode56(x04 | (x05 << 28), r, 14); + Codec.encode56(x06 | (x07 << 28), r, 21); + Codec.encode32((int)x08, r, 28); + return r; + } + + static byte[] reduce512(byte[] n) { long x00 = Codec.decode32(n, 0) & M32L; // x00:32/-- long x01 = (Codec.decode24(n, 4) << 4) & M32L; // x01:28/-- @@ -186,7 +286,7 @@ static byte[] reduce(byte[] n) x07 += (x06 >> 28); x06 &= M28L; x08 += (x07 >> 28); x07 &= M28L; - byte[] r = new byte[64]; + byte[] r = new byte[SCALAR_BYTES]; Codec.encode56(x00 | (x01 << 28), r, 0); Codec.encode56(x02 | (x03 << 28), r, 7); Codec.encode56(x04 | (x05 << 28), r, 14); @@ -195,7 +295,7 @@ static byte[] reduce(byte[] n) return r; } - static void reduceBasisVar(int[] k, int[] z0, int[] z1) + static boolean reduceBasisVar(int[] k, int[] z0, int[] z1) { /* * Split scalar k into two half-size scalars z0 and z1, such that z1 * k == z0 mod L. @@ -206,28 +306,36 @@ static void reduceBasisVar(int[] k, int[] z0, int[] z1) int[] Nu = new int[16]; System.arraycopy(LSq, 0, Nu, 0, 16); int[] Nv = new int[16]; Nat256.square(k, Nv); ++Nv[0]; int[] p = new int[16]; Nat256.mul(L, k, p); + int[] t = new int[16]; // temp array int[] u0 = new int[4]; System.arraycopy(L, 0, u0, 0, 4); int[] u1 = new int[4]; int[] v0 = new int[4]; System.arraycopy(k, 0, v0, 0, 4); int[] v1 = new int[4]; v1[0] = 1; + // Conservative upper bound on the number of loop iterations needed + int iterations = TARGET_LENGTH * 4; int last = 15; int len_Nv = ScalarUtil.getBitLengthPositive(last, Nv); while (len_Nv > TARGET_LENGTH) { + if (--iterations < 0) + { + return false; + } + int len_p = ScalarUtil.getBitLength(last, p); int s = len_p - len_Nv; s &= ~(s >> 31); if (p[last] < 0) { - ScalarUtil.addShifted_NP(last, s, Nu, Nv, p); + ScalarUtil.addShifted_NP(last, s, Nu, Nv, p, t); ScalarUtil.addShifted_UV(3, s, u0, u1, v0, v1); } else { - ScalarUtil.subShifted_NP(last, s, Nu, Nv, p); + ScalarUtil.subShifted_NP(last, s, Nu, Nv, p, t); ScalarUtil.subShifted_UV(3, s, u0, u1, v0, v1); } @@ -245,15 +353,16 @@ static void reduceBasisVar(int[] k, int[] z0, int[] z1) // v1 * k == v0 mod L System.arraycopy(v0, 0, z0, 0, 4); System.arraycopy(v1, 0, z1, 0, 4); + return true; } - static void toSignedDigits(int bits, int[] x, int[] z) + static void toSignedDigits(int bits, int[] z) { // assert bits == 256; // assert z.length >= SIZE; // int c1 = - Nat.cadd(SIZE, ~x[0] & 1, x, L, z); //assert c1 == 0; + Nat.caddTo(SIZE, ~z[0] & 1, L, z); //assert c1 == 0; // int c2 = Nat.shiftDownBit(SIZE, z, 1); //assert c2 == (1 << 31); } diff --git a/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Scalar448.java b/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Scalar448.java index 8b10e16517..f6ba495f97 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Scalar448.java +++ b/core/src/main/java/org/bouncycastle/math/ec/rfc8032/Scalar448.java @@ -76,14 +76,214 @@ static void multiply225Var(int[] x, int[] y225, int[] z) Nat.subFrom(SIZE, x, 0, tt, 8); } - byte[] bytes = new byte[114]; + byte[] bytes = new byte[88]; Codec.encode32(tt, 0, 22, bytes, 0); - byte[] r = reduce(bytes); + byte[] r = reduce704(bytes); decode(r, z); } - static byte[] reduce(byte[] n) + static byte[] reduce704(byte[] n) + { + long x00 = Codec.decode32(n, 0) & M32L; // x00:32/-- + long x01 = (Codec.decode24(n, 4) << 4) & M32L; // x01:28/-- + long x02 = Codec.decode32(n, 7) & M32L; // x02:32/-- + long x03 = (Codec.decode24(n, 11) << 4) & M32L; // x03:28/-- + long x04 = Codec.decode32(n, 14) & M32L; // x04:32/-- + long x05 = (Codec.decode24(n, 18) << 4) & M32L; // x05:28/-- + long x06 = Codec.decode32(n, 21) & M32L; // x06:32/-- + long x07 = (Codec.decode24(n, 25) << 4) & M32L; // x07:28/-- + long x08 = Codec.decode32(n, 28) & M32L; // x08:32/-- + long x09 = (Codec.decode24(n, 32) << 4) & M32L; // x09:28/-- + long x10 = Codec.decode32(n, 35) & M32L; // x10:32/-- + long x11 = (Codec.decode24(n, 39) << 4) & M32L; // x11:28/-- + long x12 = Codec.decode32(n, 42) & M32L; // x12:32/-- + long x13 = (Codec.decode24(n, 46) << 4) & M32L; // x13:28/-- + long x14 = Codec.decode32(n, 49) & M32L; // x14:32/-- + long x15 = (Codec.decode24(n, 53) << 4) & M32L; // x15:28/-- + long x16 = Codec.decode32(n, 56) & M32L; // x16:32/-- + long x17 = (Codec.decode24(n, 60) << 4) & M32L; // x17:28/-- + long x18 = Codec.decode32(n, 63) & M32L; // x18:32/-- + long x19 = (Codec.decode24(n, 67) << 4) & M32L; // x19:28/-- + long x20 = Codec.decode32(n, 70) & M32L; // x20:32/-- + long x21 = (Codec.decode24(n, 74) << 4) & M32L; // x21:28/-- + long x22 = Codec.decode32(n, 77) & M32L; // x22:32/-- + long x23 = (Codec.decode24(n, 81) << 4) & M32L; // x23:28/-- + long x24 = Codec.decode32(n, 84) & M32L; // x24:32/-- + long x25 = 0L & M32L; + + x25 += (x24 >>> 28); x24 &= M28L; // x25:28/--, x24:28/-- + x09 += x25 * L4_0; // x09:54/-- + x10 += x25 * L4_1; // x10:54/53 + x11 += x25 * L4_2; // x11:56/-- + x12 += x25 * L4_3; // x12:57/-- + x13 += x25 * L4_4; // x13:57/55 + x14 += x25 * L4_5; // x14:58/-- + x15 += x25 * L4_6; // x15:58/56 + x16 += x25 * L4_7; // x16:59/-- + + x21 += (x20 >>> 28); x20 &= M28L; // x21:58/--, x20:28/-- + x22 += (x21 >>> 28); x21 &= M28L; // x22:57/54, x21:28/-- + x23 += (x22 >>> 28); x22 &= M28L; // x23:45/42, x22:28/-- + x24 += (x23 >>> 28); x23 &= M28L; // x24:28/18, x23:28/-- + + x08 += x24 * L4_0; // x08:54/-- + x09 += x24 * L4_1; // x09:55/-- + x10 += x24 * L4_2; // x10:56/46 + x11 += x24 * L4_3; // x11:57/46 + x12 += x24 * L4_4; // x12:57/55 + x13 += x24 * L4_5; // x13:58/-- + x14 += x24 * L4_6; // x14:58/56 + x15 += x24 * L4_7; // x15:59/-- + + x07 += x23 * L4_0; // x07:54/-- + x08 += x23 * L4_1; // x08:54/53 + x09 += x23 * L4_2; // x09:56/53 + x10 += x23 * L4_3; // x10:57/46 + x11 += x23 * L4_4; // x11:57/55 + x12 += x23 * L4_5; // x12:58/-- + x13 += x23 * L4_6; // x13:58/56 + x14 += x23 * L4_7; // x14:59/-- + + x06 += x22 * L4_0; // x06:54/-- + x07 += x22 * L4_1; // x07:54/53 + x08 += x22 * L4_2; // x08:56/-- + x09 += x22 * L4_3; // x09:57/53 + x10 += x22 * L4_4; // x10:57/55 + x11 += x22 * L4_5; // x11:58/-- + x12 += x22 * L4_6; // x12:58/56 + x13 += x22 * L4_7; // x13:59/-- + + x18 += (x17 >>> 28); x17 &= M28L; // x18:59/31, x17:28/-- + x19 += (x18 >>> 28); x18 &= M28L; // x19:58/54, x18:28/-- + x20 += (x19 >>> 28); x19 &= M28L; // x20:30/29, x19:28/-- + x21 += (x20 >>> 28); x20 &= M28L; // x21:28/03, x20:28/-- + + x05 += x21 * L4_0; // x05:54/-- + x06 += x21 * L4_1; // x06:55/-- + x07 += x21 * L4_2; // x07:56/31 + x08 += x21 * L4_3; // x08:57/31 + x09 += x21 * L4_4; // x09:57/56 + x10 += x21 * L4_5; // x10:58/-- + x11 += x21 * L4_6; // x11:58/56 + x12 += x21 * L4_7; // x12:59/-- + + x04 += x20 * L4_0; // x04:54/-- + x05 += x20 * L4_1; // x05:54/53 + x06 += x20 * L4_2; // x06:56/53 + x07 += x20 * L4_3; // x07:57/31 + x08 += x20 * L4_4; // x08:57/55 + x09 += x20 * L4_5; // x09:58/-- + x10 += x20 * L4_6; // x10:58/56 + x11 += x20 * L4_7; // x11:59/-- + + x03 += x19 * L4_0; // x03:54/-- + x04 += x19 * L4_1; // x04:54/53 + x05 += x19 * L4_2; // x05:56/-- + x06 += x19 * L4_3; // x06:57/53 + x07 += x19 * L4_4; // x07:57/55 + x08 += x19 * L4_5; // x08:58/-- + x09 += x19 * L4_6; // x09:58/56 + x10 += x19 * L4_7; // x10:59/-- + + x15 += (x14 >>> 28); x14 &= M28L; // x15:59/31, x14:28/-- + x16 += (x15 >>> 28); x15 &= M28L; // x16:59/32, x15:28/-- + x17 += (x16 >>> 28); x16 &= M28L; // x17:31/29, x16:28/-- + x18 += (x17 >>> 28); x17 &= M28L; // x18:28/04, x17:28/-- + + x02 += x18 * L4_0; // x02:54/-- + x03 += x18 * L4_1; // x03:55/-- + x04 += x18 * L4_2; // x04:56/32 + x05 += x18 * L4_3; // x05:57/32 + x06 += x18 * L4_4; // x06:57/56 + x07 += x18 * L4_5; // x07:58/-- + x08 += x18 * L4_6; // x08:58/56 + x09 += x18 * L4_7; // x09:59/-- + + x01 += x17 * L4_0; // x01:54/-- + x02 += x17 * L4_1; // x02:54/53 + x03 += x17 * L4_2; // x03:56/53 + x04 += x17 * L4_3; // x04:57/32 + x05 += x17 * L4_4; // x05:57/55 + x06 += x17 * L4_5; // x06:58/-- + x07 += x17 * L4_6; // x07:58/56 + x08 += x17 * L4_7; // x08:59/-- + + x16 *= 4; + x16 += (x15 >>> 26); x15 &= M26L; + x16 += 1; // x16:30/01 + + x00 += x16 * L_0; + x01 += x16 * L_1; + x02 += x16 * L_2; + x03 += x16 * L_3; + x04 += x16 * L_4; + x05 += x16 * L_5; + x06 += x16 * L_6; + x07 += x16 * L_7; + + x01 += (x00 >>> 28); x00 &= M28L; + x02 += (x01 >>> 28); x01 &= M28L; + x03 += (x02 >>> 28); x02 &= M28L; + x04 += (x03 >>> 28); x03 &= M28L; + x05 += (x04 >>> 28); x04 &= M28L; + x06 += (x05 >>> 28); x05 &= M28L; + x07 += (x06 >>> 28); x06 &= M28L; + x08 += (x07 >>> 28); x07 &= M28L; + x09 += (x08 >>> 28); x08 &= M28L; + x10 += (x09 >>> 28); x09 &= M28L; + x11 += (x10 >>> 28); x10 &= M28L; + x12 += (x11 >>> 28); x11 &= M28L; + x13 += (x12 >>> 28); x12 &= M28L; + x14 += (x13 >>> 28); x13 &= M28L; + x15 += (x14 >>> 28); x14 &= M28L; + x16 = (x15 >>> 26); x15 &= M26L; + + x16 -= 1; + +// assert x16 == 0L || x16 == -1L; + + x00 -= x16 & L_0; + x01 -= x16 & L_1; + x02 -= x16 & L_2; + x03 -= x16 & L_3; + x04 -= x16 & L_4; + x05 -= x16 & L_5; + x06 -= x16 & L_6; + x07 -= x16 & L_7; + + x01 += (x00 >> 28); x00 &= M28L; + x02 += (x01 >> 28); x01 &= M28L; + x03 += (x02 >> 28); x02 &= M28L; + x04 += (x03 >> 28); x03 &= M28L; + x05 += (x04 >> 28); x04 &= M28L; + x06 += (x05 >> 28); x05 &= M28L; + x07 += (x06 >> 28); x06 &= M28L; + x08 += (x07 >> 28); x07 &= M28L; + x09 += (x08 >> 28); x08 &= M28L; + x10 += (x09 >> 28); x09 &= M28L; + x11 += (x10 >> 28); x10 &= M28L; + x12 += (x11 >> 28); x11 &= M28L; + x13 += (x12 >> 28); x12 &= M28L; + x14 += (x13 >> 28); x13 &= M28L; + x15 += (x14 >> 28); x14 &= M28L; + +// assert x15 >>> 26 == 0L; + + byte[] r = new byte[SCALAR_BYTES]; + Codec.encode56(x00 | (x01 << 28), r, 0); + Codec.encode56(x02 | (x03 << 28), r, 7); + Codec.encode56(x04 | (x05 << 28), r, 14); + Codec.encode56(x06 | (x07 << 28), r, 21); + Codec.encode56(x08 | (x09 << 28), r, 28); + Codec.encode56(x10 | (x11 << 28), r, 35); + Codec.encode56(x12 | (x13 << 28), r, 42); + Codec.encode56(x14 | (x15 << 28), r, 49); +// r[SCALAR_BYTES - 1] = 0; + return r; + } + + static byte[] reduce912(byte[] n) { long x00 = Codec.decode32(n, 0) & M32L; // x00:32/-- long x01 = (Codec.decode24(n, 4) << 4) & M32L; // x01:28/-- @@ -360,7 +560,7 @@ static byte[] reduce(byte[] n) return r; } - static void reduceBasisVar(int[] k, int[] z0, int[] z1) + static boolean reduceBasisVar(int[] k, int[] z0, int[] z1) { /* * Split scalar k into two half-size scalars z0 and z1, such that z1 * k == z0 mod L. @@ -371,28 +571,36 @@ static void reduceBasisVar(int[] k, int[] z0, int[] z1) int[] Nu = new int[28]; System.arraycopy(LSq, 0, Nu, 0, 28); int[] Nv = new int[28]; Nat448.square(k, Nv); ++Nv[0]; int[] p = new int[28]; Nat448.mul(L, k, p); + int[] t = new int[28]; // temp array int[] u0 = new int[8]; System.arraycopy(L, 0, u0, 0, 8); int[] u1 = new int[8]; int[] v0 = new int[8]; System.arraycopy(k, 0, v0, 0, 8); int[] v1 = new int[8]; v1[0] = 1; + // Conservative upper bound on the number of loop iterations needed + int iterations = TARGET_LENGTH * 4; int last = 27; int len_Nv = ScalarUtil.getBitLengthPositive(last, Nv); while (len_Nv > TARGET_LENGTH) { + if (--iterations < 0) + { + return false; + } + int len_p = ScalarUtil.getBitLength(last, p); int s = len_p - len_Nv; s &= ~(s >> 31); if (p[last] < 0) { - ScalarUtil.addShifted_NP(last, s, Nu, Nv, p); + ScalarUtil.addShifted_NP(last, s, Nu, Nv, p, t); ScalarUtil.addShifted_UV(7, s, u0, u1, v0, v1); } else { - ScalarUtil.subShifted_NP(last, s, Nu, Nv, p); + ScalarUtil.subShifted_NP(last, s, Nu, Nv, p, t); ScalarUtil.subShifted_UV(7, s, u0, u1, v0, v1); } @@ -413,6 +621,7 @@ static void reduceBasisVar(int[] k, int[] z0, int[] z1) // v1 * k == v0 mod L System.arraycopy(v0, 0, z0, 0, 8); System.arraycopy(v1, 0, z1, 0, 8); + return true; } static void toSignedDigits(int bits, int[] x, int[] z) diff --git a/core/src/main/java/org/bouncycastle/math/ec/rfc8032/ScalarUtil.java b/core/src/main/java/org/bouncycastle/math/ec/rfc8032/ScalarUtil.java index 81d8fd9638..483bf477d9 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/rfc8032/ScalarUtil.java +++ b/core/src/main/java/org/bouncycastle/math/ec/rfc8032/ScalarUtil.java @@ -6,59 +6,113 @@ abstract class ScalarUtil { private static final long M = 0xFFFFFFFFL; - static void addShifted_NP(int last, int s, int[] Nu, int[] Nv, int[] _p) + static void addShifted_NP(int last, int s, int[] Nu, int[] Nv, int[] p, int[] t) { - int sWords = s >>> 5, sBits = s & 31; - - long cc__p = 0L; + long cc_p = 0L; long cc_Nu = 0L; - if (sBits == 0) + if (s == 0) { - for (int i = sWords; i <= last; ++i) + for (int i = 0; i <= last; ++i) { + int p_i = p[i]; + cc_Nu += Nu[i] & M; - cc_Nu += _p[i - sWords] & M; + cc_Nu += p_i & M; - cc__p += _p[i] & M; - cc__p += Nv[i - sWords] & M; - _p[i] = (int)cc__p; cc__p >>>= 32; + cc_p += p_i & M; + cc_p += Nv[i] & M; + p_i = (int)cc_p; cc_p >>>= 32; + p[i] = p_i; - cc_Nu += _p[i - sWords] & M; + cc_Nu += p_i & M; Nu[i] = (int)cc_Nu; cc_Nu >>>= 32; } } - else + else if (s < 32) { int prev_p = 0; int prev_q = 0; int prev_v = 0; - for (int i = sWords; i <= last; ++i) + for (int i = 0; i <= last; ++i) { - int next_p = _p[i - sWords]; - int p_s = (next_p << sBits) | (prev_p >>> -sBits); - prev_p = next_p; + int p_i = p[i]; + int p_s = (p_i << s) | (prev_p >>> -s); + prev_p = p_i; cc_Nu += Nu[i] & M; cc_Nu += p_s & M; - int next_v = Nv[i - sWords]; - int v_s = (next_v << sBits) | (prev_v >>> -sBits); + int next_v = Nv[i]; + int v_s = (next_v << s) | (prev_v >>> -s); prev_v = next_v; - cc__p += _p[i] & M; - cc__p += v_s & M; - _p[i] = (int)cc__p; cc__p >>>= 32; + cc_p += p_i & M; + cc_p += v_s & M; + p_i = (int)cc_p; cc_p >>>= 32; + p[i] = p_i; - int next_q = _p[i - sWords]; - int q_s = (next_q << sBits) | (prev_q >>> -sBits); - prev_q = next_q; + int q_s = (p_i << s) | (prev_q >>> -s); + prev_q = p_i; cc_Nu += q_s & M; Nu[i] = (int)cc_Nu; cc_Nu >>>= 32; } } + else + { + // Copy the low limbs of the original p + System.arraycopy(p, 0, t, 0, last); + + int sWords = s >>> 5; int sBits = s & 31; + if (sBits == 0) + { + for (int i = sWords; i <= last; ++i) + { + cc_Nu += Nu[i] & M; + cc_Nu += t[i - sWords] & M; + + cc_p += p[i] & M; + cc_p += Nv[i - sWords] & M; + p[i] = (int)cc_p; cc_p >>>= 32; + + cc_Nu += p[i - sWords] & M; + Nu[i] = (int)cc_Nu; cc_Nu >>>= 32; + } + } + else + { + int prev_t = 0; + int prev_q = 0; + int prev_v = 0; + + for (int i = sWords; i <= last; ++i) + { + int next_t = t[i - sWords]; + int t_s = (next_t << sBits) | (prev_t >>> -sBits); + prev_t = next_t; + + cc_Nu += Nu[i] & M; + cc_Nu += t_s & M; + + int next_v = Nv[i - sWords]; + int v_s = (next_v << sBits) | (prev_v >>> -sBits); + prev_v = next_v; + + cc_p += p[i] & M; + cc_p += v_s & M; + p[i] = (int)cc_p; cc_p >>>= 32; + + int next_q = p[i - sWords]; + int q_s = (next_q << sBits) | (prev_q >>> -sBits); + prev_q = next_q; + + cc_Nu += q_s & M; + Nu[i] = (int)cc_Nu; cc_Nu >>>= 32; + } + } + } } static void addShifted_UV(int last, int s, int[] u0, int[] u1, int[] v0, int[] v1) @@ -141,59 +195,113 @@ static boolean lessThan(int last, int[] x, int[] y) return false; } - static void subShifted_NP(int last, int s, int[] Nu, int[] Nv, int[] _p) + static void subShifted_NP(int last, int s, int[] Nu, int[] Nv, int[] p, int[] t) { - int sWords = s >>> 5, sBits = s & 31; - - long cc__p = 0L; + long cc_p = 0L; long cc_Nu = 0L; - if (sBits == 0) + if (s == 0) { - for (int i = sWords; i <= last; ++i) + for (int i = 0; i <= last; ++i) { + int p_i = p[i]; + cc_Nu += Nu[i] & M; - cc_Nu -= _p[i - sWords] & M; + cc_Nu -= p_i & M; - cc__p += _p[i] & M; - cc__p -= Nv[i - sWords] & M; - _p[i] = (int)cc__p; cc__p >>= 32; + cc_p += p_i & M; + cc_p -= Nv[i] & M; + p_i = (int)cc_p; cc_p >>= 32; + p[i] = p_i; - cc_Nu -= _p[i - sWords] & M; + cc_Nu -= p_i & M; Nu[i] = (int)cc_Nu; cc_Nu >>= 32; } } - else + else if (s < 32) { int prev_p = 0; int prev_q = 0; int prev_v = 0; - for (int i = sWords; i <= last; ++i) + for (int i = 0; i <= last; ++i) { - int next_p = _p[i - sWords]; - int p_s = (next_p << sBits) | (prev_p >>> -sBits); - prev_p = next_p; + int p_i = p[i]; + int p_s = (p_i << s) | (prev_p >>> -s); + prev_p = p_i; cc_Nu += Nu[i] & M; cc_Nu -= p_s & M; - int next_v = Nv[i - sWords]; - int v_s = (next_v << sBits) | (prev_v >>> -sBits); + int next_v = Nv[i]; + int v_s = (next_v << s) | (prev_v >>> -s); prev_v = next_v; - cc__p += _p[i] & M; - cc__p -= v_s & M; - _p[i] = (int)cc__p; cc__p >>= 32; + cc_p += p_i & M; + cc_p -= v_s & M; + p_i = (int)cc_p; cc_p >>= 32; + p[i] = p_i; - int next_q = _p[i - sWords]; - int q_s = (next_q << sBits) | (prev_q >>> -sBits); - prev_q = next_q; + int q_s = (p_i << s) | (prev_q >>> -s); + prev_q = p_i; cc_Nu -= q_s & M; Nu[i] = (int)cc_Nu; cc_Nu >>= 32; } } + else + { + // Copy the low limbs of the original p + System.arraycopy(p, 0, t, 0, last); + + int sWords = s >>> 5; int sBits = s & 31; + if (sBits == 0) + { + for (int i = sWords; i <= last; ++i) + { + cc_Nu += Nu[i] & M; + cc_Nu -= t[i - sWords] & M; + + cc_p += p[i] & M; + cc_p -= Nv[i - sWords] & M; + p[i] = (int)cc_p; cc_p >>= 32; + + cc_Nu -= p[i - sWords] & M; + Nu[i] = (int)cc_Nu; cc_Nu >>= 32; + } + } + else + { + int prev_t = 0; + int prev_q = 0; + int prev_v = 0; + + for (int i = sWords; i <= last; ++i) + { + int next_t = t[i - sWords]; + int t_s = (next_t << sBits) | (prev_t >>> -sBits); + prev_t = next_t; + + cc_Nu += Nu[i] & M; + cc_Nu -= t_s & M; + + int next_v = Nv[i - sWords]; + int v_s = (next_v << sBits) | (prev_v >>> -sBits); + prev_v = next_v; + + cc_p += p[i] & M; + cc_p -= v_s & M; + p[i] = (int)cc_p; cc_p >>= 32; + + int next_q = p[i - sWords]; + int q_s = (next_q << sBits) | (prev_q >>> -sBits); + prev_q = next_q; + + cc_Nu -= q_s & M; + Nu[i] = (int)cc_Nu; cc_Nu >>= 32; + } + } + } } static void subShifted_UV(int last, int s, int[] u0, int[] u1, int[] v0, int[] v1) diff --git a/core/src/main/java/org/bouncycastle/math/ec/tools/DiscoverEndomorphisms.java b/core/src/main/java/org/bouncycastle/math/ec/tools/DiscoverEndomorphisms.java index c2757976c4..f77a1a37b1 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/tools/DiscoverEndomorphisms.java +++ b/core/src/main/java/org/bouncycastle/math/ec/tools/DiscoverEndomorphisms.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; +import java.util.List; import java.util.SortedSet; import java.util.TreeSet; @@ -314,9 +315,9 @@ private static BigInteger[] calculateRange(BigInteger mid, BigInteger off, BigIn return order(i1, i2); } - private static ArrayList enumToList(Enumeration en) + private static List enumToList(Enumeration en) { - ArrayList rv = new ArrayList(); + List rv = new ArrayList(); while (en.hasMoreElements()) { rv.add(en.nextElement()); diff --git a/core/src/main/java/org/bouncycastle/math/ec/tools/F2mSqrtOptimizer.java b/core/src/main/java/org/bouncycastle/math/ec/tools/F2mSqrtOptimizer.java index 1a94f37786..a76081b50d 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/tools/F2mSqrtOptimizer.java +++ b/core/src/main/java/org/bouncycastle/math/ec/tools/F2mSqrtOptimizer.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; +import java.util.List; import java.util.SortedSet; import java.util.TreeSet; @@ -13,6 +14,7 @@ import org.bouncycastle.math.ec.ECAlgorithms; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECFieldElement; +import org.bouncycastle.util.Strings; public class F2mSqrtOptimizer { @@ -59,7 +61,7 @@ private static void implPrintRootZ(ECCurve curve) ECFieldElement rootZ = z.sqrt(); // -DM System.out.println - System.out.println(rootZ.toBigInteger().toString(16).toUpperCase()); + System.out.println(Strings.toUpperCase(rootZ.toBigInteger().toString(16))); if (!rootZ.square().equals(z)) { @@ -67,9 +69,9 @@ private static void implPrintRootZ(ECCurve curve) } } - private static ArrayList enumToList(Enumeration en) + private static List enumToList(Enumeration en) { - ArrayList rv = new ArrayList(); + List rv = new ArrayList(); while (en.hasMoreElements()) { rv.add(en.nextElement()); diff --git a/core/src/main/java/org/bouncycastle/math/ec/tools/TraceOptimizer.java b/core/src/main/java/org/bouncycastle/math/ec/tools/TraceOptimizer.java index 2e06c25c31..88faf36aee 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/tools/TraceOptimizer.java +++ b/core/src/main/java/org/bouncycastle/math/ec/tools/TraceOptimizer.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; +import java.util.List; import java.util.SortedSet; import java.util.TreeSet; @@ -63,7 +64,7 @@ public static void implPrintNonZeroTraceBits(ECCurve curve) { int m = curve.getFieldSize(); - ArrayList nonZeroTraceBits = new ArrayList(); + List nonZeroTraceBits = new ArrayList(); /* * Determine which of the bits contribute to the trace. @@ -162,9 +163,9 @@ private static int calculateTrace(ECFieldElement fe) throw new IllegalStateException("Internal error in trace calculation"); } - private static ArrayList enumToList(Enumeration en) + private static List enumToList(Enumeration en) { - ArrayList rv = new ArrayList(); + List rv = new ArrayList(); while (en.hasMoreElements()) { rv.add(en.nextElement()); diff --git a/core/src/main/java/org/bouncycastle/math/raw/Mod.java b/core/src/main/java/org/bouncycastle/math/raw/Mod.java index 0f351ad30b..fd182f650f 100644 --- a/core/src/main/java/org/bouncycastle/math/raw/Mod.java +++ b/core/src/main/java/org/bouncycastle/math/raw/Mod.java @@ -4,11 +4,13 @@ import org.bouncycastle.util.Integers; -/* +/** * Modular inversion as implemented in this class is based on the paper "Fast constant-time gcd * computation and modular inversion" by Daniel J. Bernstein and Bo-Yin Yang. + *

    + * In some cases (when it is faster) we use the "half delta" variant of safegcd based on + * hddivsteps. */ - public abstract class Mod { private static final int M30 = 0x3FFFFFFF; @@ -61,17 +63,18 @@ public static int modOddInverse(int[] m, int[] x, int[] z) int[] M = new int[len30]; E[0] = 1; - encode30(bits, x, 0, G, 0); - encode30(bits, m, 0, M, 0); + encode30(bits, x, G); + encode30(bits, m, M); System.arraycopy(M, 0, F, 0, len30); - int delta = 0; + // We use the "half delta" variant here, with theta == delta - 1/2 + int theta = 0; int m0Inv32 = inverse32(M[0]); - int maxDivsteps = getMaximumDivsteps(bits); + int maxDivsteps = getMaximumHDDivsteps(bits); for (int divSteps = 0; divSteps < maxDivsteps; divSteps += 30) { - delta = divsteps30(delta, F[0], G[0], t); + theta = hddivsteps30(theta, F[0], G[0], t); updateDE30(len30, D, E, t, m0Inv32, M); updateFG30(len30, F, G, t); } @@ -86,10 +89,10 @@ public static int modOddInverse(int[] m, int[] x, int[] z) */ cnormalize30(len30, signF, D, M); - decode30(bits, D, 0, z, 0); + decode30(bits, D, z); // assert 0 != Nat.lessThan(len32, z, m); - return Nat.equalTo(len30, F, 1) & Nat.equalToZero(len30, G); + return equalTo(len30, F, 1) & equalTo(len30, G, 0); } public static boolean modOddInverseVar(int[] m, int[] x, int[] z) @@ -102,6 +105,9 @@ public static boolean modOddInverseVar(int[] m, int[] x, int[] z) int bits = (len32 << 5) - Integers.numberOfLeadingZeros(m[len32 - 1]); int len30 = (bits + 29) / 30; + int clz = bits - Nat.getBitLength(len32, x); +// assert clz >= 0; + int[] t = new int[4]; int[] D = new int[len30]; int[] E = new int[len30]; @@ -110,18 +116,19 @@ public static boolean modOddInverseVar(int[] m, int[] x, int[] z) int[] M = new int[len30]; E[0] = 1; - encode30(bits, x, 0, G, 0); - encode30(bits, m, 0, M, 0); + encode30(bits, x, G); + encode30(bits, m, M); System.arraycopy(M, 0, F, 0, len30); - int clzG = Integers.numberOfLeadingZeros(G[len30 - 1] | 1) - (len30 * 30 + 2 - bits); - int eta = -1 - clzG; + // We use the original safegcd here, with eta == 1 - delta + // For shorter x, configure as if low zeros of x had been shifted away by divsteps + int eta = -clz; int lenDE = len30, lenFG = len30; int m0Inv32 = inverse32(M[0]); int maxDivsteps = getMaximumDivsteps(bits); - int divsteps = 0; - while (!Nat.isZero(lenFG, G)) + int divsteps = clz; + while (!equalToVar(lenFG, G, 0)) { if (divsteps >= maxDivsteps) { @@ -133,20 +140,7 @@ public static boolean modOddInverseVar(int[] m, int[] x, int[] z) eta = divsteps30Var(eta, F[0], G[0], t); updateDE30(lenDE, D, E, t, m0Inv32, M); updateFG30(lenFG, F, G, t); - - int fn = F[lenFG - 1]; - int gn = G[lenFG - 1]; - - int cond = (lenFG - 2) >> 31; - cond |= fn ^ (fn >> 31); - cond |= gn ^ (gn >> 31); - - if (cond == 0) - { - F[lenFG - 2] |= fn << 30; - G[lenFG - 2] |= gn << 30; - --lenFG; - } + lenFG = trimFG30(lenFG, F, G); } int signF = F[lenFG - 1] >> 31; @@ -168,7 +162,7 @@ public static boolean modOddInverseVar(int[] m, int[] x, int[] z) } // assert 0 == signF; - if (!Nat.isOne(lenFG, F)) + if (!equalToVar(lenFG, F, 1)) { return false; } @@ -179,12 +173,100 @@ public static boolean modOddInverseVar(int[] m, int[] x, int[] z) } // assert 0 == signD; - decode30(bits, D, 0, z, 0); + decode30(bits, D, z); // assert !Nat.gte(len32, z, m); return true; } + public static int modOddIsCoprime(int[] m, int[] x) + { + int len32 = m.length; +// assert len32 > 0; +// assert (m[0] & 1) != 0; +// assert m[len32 - 1] != 0; + + int bits = (len32 << 5) - Integers.numberOfLeadingZeros(m[len32 - 1]); + int len30 = (bits + 29) / 30; + + int[] t = new int[4]; + int[] F = new int[len30]; + int[] G = new int[len30]; + int[] M = new int[len30]; + + encode30(bits, x, G); + encode30(bits, m, M); + System.arraycopy(M, 0, F, 0, len30); + + // We use the "half delta" variant here, with theta == delta - 1/2 + int theta = 0; + int maxDivsteps = getMaximumHDDivsteps(bits); + + for (int divSteps = 0; divSteps < maxDivsteps; divSteps += 30) + { + theta = hddivsteps30(theta, F[0], G[0], t); + updateFG30(len30, F, G, t); + } + + int signF = F[len30 - 1] >> 31; + cnegate30(len30, signF, F); + + return equalTo(len30, F, 1) & equalTo(len30, G, 0); + } + + public static boolean modOddIsCoprimeVar(int[] m, int[] x) + { + int len32 = m.length; +// assert len32 > 0; +// assert (m[0] & 1) != 0; +// assert m[len32 - 1] != 0; + + int bits = (len32 << 5) - Integers.numberOfLeadingZeros(m[len32 - 1]); + int len30 = (bits + 29) / 30; + + int clz = bits - Nat.getBitLength(len32, x); +// assert clz >= 0; + + int[] t = new int[4]; + int[] F = new int[len30]; + int[] G = new int[len30]; + int[] M = new int[len30]; + + encode30(bits, x, G); + encode30(bits, m, M); + System.arraycopy(M, 0, F, 0, len30); + + // We use the original safegcd here, with eta == 1 - delta + // For shorter x, configure as if low zeros of x had been shifted away by divsteps + int eta = -clz; + int lenFG = len30; + int maxDivsteps = getMaximumDivsteps(bits); + + int divsteps = clz; + while (!equalToVar(lenFG, G, 0)) + { + if (divsteps >= maxDivsteps) + { + return false; + } + + divsteps += 30; + + eta = divsteps30Var(eta, F[0], G[0], t); + updateFG30(lenFG, F, G, t); + lenFG = trimFG30(lenFG, F, G); + } + + int signF = F[lenFG - 1] >> 31; + if (signF < 0) + { + signF = negate30(lenFG, F); + } +// assert 0 == signF; + + return equalToVar(lenFG, F, 1); + } + public static int[] random(int[] p) { int len = p.length; @@ -281,7 +363,7 @@ private static void cnormalize30(int len30, int condNegate, int[] D, int[] M) } } - private static void decode30(int bits, int[] x, int xOff, int[] z, int zOff) + private static void decode30(int bits, int[] x, int[] z) { // assert bits > 0; // assert x != z; @@ -289,6 +371,7 @@ private static void decode30(int bits, int[] x, int xOff, int[] z, int zOff) int avail = 0; long data = 0L; + int xOff = 0, zOff = 0; while (bits > 0) { while (avail < Math.min(32, bits)) @@ -303,48 +386,6 @@ private static void decode30(int bits, int[] x, int xOff, int[] z, int zOff) } } - private static int divsteps30(int delta, int f0, int g0, int[] t) - { - int u = 1 << 30, v = 0, q = 0, r = 1 << 30; - int f = f0, g = g0; - - for (int i = 0; i < 30; ++i) - { -// assert (f & 1) == 1; -// assert ((u >> (30 - i)) * f0 + (v >> (30 - i)) * g0) == f << i; -// assert ((q >> (30 - i)) * f0 + (r >> (30 - i)) * g0) == g << i; - - int c1 = delta >> 31; - int c2 = -(g & 1); - - int x = f ^ c1; - int y = u ^ c1; - int z = v ^ c1; - - g -= x & c2; - q -= y & c2; - r -= z & c2; - - c2 &= ~c1; - delta = (delta ^ c2) - (c2 - 1); - - f += g & c2; - u += q & c2; - v += r & c2; - - g >>= 1; - q >>= 1; - r >>= 1; - } - - t[0] = u; - t[1] = v; - t[2] = q; - t[3] = r; - - return delta; - } - private static int divsteps30Var(int eta, int f0, int g0, int[] t) { int u = 1, v = 0, q = 0, r = 1; @@ -372,15 +413,15 @@ private static int divsteps30Var(int eta, int f0, int g0, int[] t) // assert (u * f0 + v * g0) == f << (30 - i); // assert (q * f0 + r * g0) == g << (30 - i); - if (eta < 0) + if (eta <= 0) { - eta = -eta; + eta = 2 - eta; x = f; f = g; g = -x; y = u; u = q; q = -y; z = v; v = r; r = -z; // Handle up to 6 divsteps at once, subject to eta and i. - limit = (eta + 1) > i ? i : (eta + 1); + limit = eta > i ? i : eta; m = (-1 >>> (32 - limit)) & 63; w = (f * g * (f * f - 2)) & m; @@ -388,11 +429,11 @@ private static int divsteps30Var(int eta, int f0, int g0, int[] t) else { // Handle up to 4 divsteps at once, subject to eta and i. - limit = (eta + 1) > i ? i : (eta + 1); + limit = eta > i ? i : eta; m = (-1 >>> (32 - limit)) & 15; w = f + (((f + 1) & 4) << 1); - w = (-w * g) & m; + w = (w * -g) & m; } g += f * w; @@ -410,7 +451,7 @@ private static int divsteps30Var(int eta, int f0, int g0, int[] t) return eta; } - private static void encode30(int bits, int[] x, int xOff, int[] z, int zOff) + private static void encode30(int bits, int[] x, int[] z) { // assert bits > 0; // assert x != z; @@ -418,6 +459,7 @@ private static void encode30(int bits, int[] x, int xOff, int[] z, int zOff) int avail = 0; long data = 0L; + int xOff = 0, zOff = 0; while (bits > 0) { if (avail < Math.min(30, bits)) @@ -432,9 +474,82 @@ private static void encode30(int bits, int[] x, int xOff, int[] z, int zOff) } } + private static int equalTo(int len, int[] x, int y) + { + int d = x[0] ^ y; + for (int i = 1; i < len; ++i) + { + d |= x[i]; + } + d = (d >>> 1) | (d & 1); + return (d - 1) >> 31; + } + + private static boolean equalToVar(int len, int[] x, int y) + { + int d = x[0] ^ y; + if (d != 0) + return false; + + for (int i = 1; i < len; ++i) + { + d |= x[i]; + } + return d == 0; + } + private static int getMaximumDivsteps(int bits) { - return (49 * bits + (bits < 46 ? 80 : 47)) / 17; + //return (49 * bits + (bits < 46 ? 80 : 47)) / 17; + return (int)((188898L * bits + (bits < 46 ? 308405 : 181188)) >>> 16); + } + + private static int getMaximumHDDivsteps(int bits) + { + //return (int)((45907L * bits + 30179) / 19929); + return (int)((150964L * bits + 99243) >>> 16); + } + + private static int hddivsteps30(int theta, int f0, int g0, int[] t) + { + int u = 1 << 30, v = 0, q = 0, r = 1 << 30; + int f = f0, g = g0; + + for (int i = 0; i < 30; ++i) + { +// assert (f & 1) == 1; +// assert ((u >> (30 - i)) * f0 + (v >> (30 - i)) * g0) == f << i; +// assert ((q >> (30 - i)) * f0 + (r >> (30 - i)) * g0) == g << i; + + int c1 = theta >> 31; + int c2 = -(g & 1); + + int x = f ^ c1; + int y = u ^ c1; + int z = v ^ c1; + + g -= x & c2; + q -= y & c2; + r -= z & c2; + + int c3 = c2 & ~c1; + theta = (theta ^ c3) + 1; + + f += g & c3; + u += q & c3; + v += r & c3; + + g >>= 1; + q >>= 1; + r >>= 1; + } + + t[0] = u; + t[1] = v; + t[2] = q; + t[3] = r; + + return theta; } private static int negate30(int len30, int[] D) @@ -453,6 +568,29 @@ private static int negate30(int len30, int[] D) return c; } + private static int trimFG30(int len30, int[] F, int[] G) + { +// assert len30 > 0; +// assert F.length >= len30; +// assert G.length >= len30; + + int fn = F[len30 - 1]; + int gn = G[len30 - 1]; + + int cond = (len30 - 2) >> 31; + cond |= fn ^ (fn >> 31); + cond |= gn ^ (gn >> 31); + + if (cond == 0) + { + F[len30 - 2] |= fn << 30; + G[len30 - 2] |= gn << 30; + --len30; + } + + return len30; + } + private static void updateDE30(int len30, int[] D, int[] E, int[] t, int m0Inv32, int[] M) { // assert len30 > 0; diff --git a/core/src/main/java/org/bouncycastle/math/raw/Nat.java b/core/src/main/java/org/bouncycastle/math/raw/Nat.java index 297db8f477..3d98cb4ec6 100644 --- a/core/src/main/java/org/bouncycastle/math/raw/Nat.java +++ b/core/src/main/java/org/bouncycastle/math/raw/Nat.java @@ -2,6 +2,7 @@ import java.math.BigInteger; +import org.bouncycastle.util.Integers; import org.bouncycastle.util.Pack; public abstract class Nat @@ -232,6 +233,19 @@ public static int cadd(int len, int mask, int[] x, int[] y, int[] z) return (int)c; } + public static int caddTo(int len, int mask, int[] x, int[] z) + { + long MASK = -(mask & 1) & M; + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (z[i] & M) + (x[i] & MASK); + z[i] = (int)c; + c >>>= 32; + } + return (int)c; + } + public static void cmov(int len, int mask, int[] x, int xOff, int[] z, int zOff) { mask = -(mask & 1); @@ -556,6 +570,28 @@ public static int getBit(int[] x, int bit) return (x[w] >>> b) & 1; } + public static int getBitLength(int len, int[] x) + { + for (int i = len - 1; i >= 0; --i) + { + int x_i = x[i]; + if (x_i != 0) + return i * 32 + 32 - Integers.numberOfLeadingZeros(x_i); + } + return 0; + } + + public static int getBitLength(int len, int[] x, int xOff) + { + for (int i = len - 1; i >= 0; --i) + { + int x_i = x[xOff + i]; + if (x_i != 0) + return i * 32 + 32 - Integers.numberOfLeadingZeros(x_i); + } + return 0; + } + public static boolean gte(int len, int[] x, int[] y) { for (int i = len - 1; i >= 0; --i) diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/CMCEPrivateKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/CMCEPrivateKey.java index 5af7de20e5..4da48dcb90 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/CMCEPrivateKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/CMCEPrivateKey.java @@ -9,7 +9,6 @@ import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.BigIntegers; /** * ASN.1 Encoding for a @@ -60,11 +59,12 @@ public CMCEPrivateKey(int version, byte[] delta, byte[] c, byte[] g, byte[] alph private CMCEPrivateKey(ASN1Sequence seq) { - version = BigIntegers.intValueExact(ASN1Integer.getInstance(seq.getObjectAt(0)).getValue()); + version = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact(); if (version != 0) { throw new IllegalArgumentException("unrecognized version"); } + delta = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets()); C = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(2)).getOctets()); @@ -75,7 +75,6 @@ private CMCEPrivateKey(ASN1Sequence seq) s = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(5)).getOctets()); - // todo optional publickey if(seq.size() == 7) { PublicKey = CMCEPublicKey.getInstance(seq.getObjectAt(6)); diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/CMCEPublicKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/CMCEPublicKey.java index 62053ce290..e09a5d17da 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/CMCEPublicKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/CMCEPublicKey.java @@ -31,6 +31,9 @@ public CMCEPublicKey(byte[] t) this.T = t; } + /** + * @deprecated use getInstance() + */ public CMCEPublicKey(ASN1Sequence seq) { T = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets()); diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/FalconPrivateKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/FalconPrivateKey.java index 6979a853fb..380f547b87 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/FalconPrivateKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/FalconPrivateKey.java @@ -1,9 +1,14 @@ package org.bouncycastle.pqc.asn1; - -import org.bouncycastle.asn1.*; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.BigIntegers; /** * ASN.1 Encoding for a @@ -69,18 +74,18 @@ public byte[] getG() private FalconPrivateKey(ASN1Sequence seq) { - version = BigIntegers.intValueExact(ASN1Integer.getInstance(seq.getObjectAt(0)).getValue()); + version = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact(); if (version != 0) { throw new IllegalArgumentException("unrecognized version"); } + f = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets()); g = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(2)).getOctets()); F = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(3)).getOctets()); - // todo optional publickey if(seq.size() == 5) { publicKey = FalconPublicKey.getInstance(seq.getObjectAt(4)); diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/FalconPublicKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/FalconPublicKey.java index 65f419629b..d5dc89dccb 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/FalconPublicKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/FalconPublicKey.java @@ -29,6 +29,9 @@ public byte[] getH() return h; } + /** + * @deprecated use getInstance() + */ public FalconPublicKey(ASN1Sequence seq) { h = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets()); diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/GMSSPrivateKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/GMSSPrivateKey.java index 470c81c474..71a23c8a71 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/GMSSPrivateKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/GMSSPrivateKey.java @@ -20,6 +20,20 @@ public class GMSSPrivateKey extends ASN1Object { + public static GMSSPrivateKey getInstance(Object o) + { + if (o instanceof GMSSPrivateKey) + { + return (GMSSPrivateKey)o; + } + else if (o != null) + { + return new GMSSPrivateKey(ASN1Sequence.getInstance(o)); + } + + return null; + } + private ASN1Primitive primitive; private GMSSPrivateKey(ASN1Sequence mtsPrivateKey) diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/KyberPrivateKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/KyberPrivateKey.java index f12e5384a2..cbdf006753 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/KyberPrivateKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/KyberPrivateKey.java @@ -9,20 +9,19 @@ import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.BigIntegers; /** * * Crystal Kyber Private Key Format. - * See https://www.ietf.org/archive/id/draft-uni-qsckeys-kyber-00.html for details. + * See https://www.ietf.org/archive/id/draft-uni-qsckeys-kyber-01.html for details. *

      *        KyberPrivateKey ::= SEQUENCE {
    - *        version     INTEGER {v0(0)}   -- version (round 3)
    - *        s           OCTET STRING,     -- EMPTY
    - *        hpk         OCTET STRING      -- EMPTY
    - *        nonce       OCTET STRING,     -- d
    - *        publicKey   [0] IMPLICIT KyberPublicKey OPTIONAL,
    - *                                      -- see next section
    + *            version     INTEGER {v0(0)}   -- version (round 3)
    + *            s           OCTET STRING,     -- sample s
    + *            publicKey   [0] IMPLICIT KyberPublicKey OPTIONAL,
    + *                                          -- see next section
    + *            hpk         OCTET STRING      -- H(pk)
    + *            nonce       OCTET STRING,     -- z
      *        }
      *    
    */ @@ -76,20 +75,18 @@ public byte[] getNonce() private KyberPrivateKey(ASN1Sequence seq) { - int skipPubKey = 1; - if (seq.size() == 5) - skipPubKey = 0; // dont skip - - version = BigIntegers.intValueExact(ASN1Integer.getInstance(seq.getObjectAt(0)).getValue()); + version = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact(); if (version != 0) { throw new IllegalArgumentException("unrecognized version"); } + s = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets()); - // todo optional publickey + int skipPubKey = 1; if (seq.size() == 5) { + skipPubKey = 0; publicKey = KyberPublicKey.getInstance(seq.getObjectAt(2)); } diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/KyberPublicKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/KyberPublicKey.java index 43540606b9..a498e7857b 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/KyberPublicKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/KyberPublicKey.java @@ -12,7 +12,7 @@ /** * * Crystal Kyber Public Key Format. - * See https://www.ietf.org/archive/id/draft-uni-qsckeys-kyber-00.html for details. + * See https://www.ietf.org/archive/id/draft-uni-qsckeys-kyber-01.html for details. *
      *        KyberPublicKey ::= SEQUENCE {
      *         t           OCTET STRING,
    @@ -33,6 +33,9 @@ public KyberPublicKey(byte[] t, byte[] rho)
             this.rho = rho;
         }
     
    +    /**
    +     * @deprecated use getInstance()
    +     */
         public KyberPublicKey(ASN1Sequence seq)
         {
             t = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
    diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/PQCObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/pqc/asn1/PQCObjectIdentifiers.java
    index cc2903e2f8..e88bb0898d 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/asn1/PQCObjectIdentifiers.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/PQCObjectIdentifiers.java
    @@ -111,11 +111,11 @@ public interface PQCObjectIdentifiers
         /**
          * @deprecated use xmss_mt_SHAKE128ph
          */
    -    final ASN1ObjectIdentifier xmss_mt_with_SHAKE128        = xmss_mt_SHAKE128;
    +    final ASN1ObjectIdentifier xmss_mt_with_SHAKE128        = xmss_mt_SHAKE128ph;
         /**
          * @deprecated use xmss_mt_SHAKE256ph
          */
    -    final ASN1ObjectIdentifier xmss_mt_with_SHAKE256        = xmss_mt_SHAKE256;
    +    final ASN1ObjectIdentifier xmss_mt_with_SHAKE256        = xmss_mt_SHAKE256ph;
     
         /**
          * qTESLA
    diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/SABERPrivateKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/SABERPrivateKey.java
    index 0d3685899e..d964d2eb49 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/asn1/SABERPrivateKey.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/SABERPrivateKey.java
    @@ -1,9 +1,14 @@
     package org.bouncycastle.pqc.asn1;
     
    -
    -import org.bouncycastle.asn1.*;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DEROctetString;
    +import org.bouncycastle.asn1.DERSequence;
     import org.bouncycastle.util.Arrays;
    -import org.bouncycastle.util.BigIntegers;
     
     /**
      *    Expires 13 May 2022
    @@ -55,16 +60,16 @@ public SABERPrivateKey(int version, byte[] z, byte[] s, byte[] hpk, SABERPublicK
     
         private SABERPrivateKey(ASN1Sequence seq)
         {
    -        version = BigIntegers.intValueExact(ASN1Integer.getInstance(seq.getObjectAt(0)).getValue());
    +        version = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
             if (version != 0)
             {
                 throw new IllegalArgumentException("unrecognized version");
             }
    +
             z = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
     
             s = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(2)).getOctets());
     
    -        //todo check if public key is supplied
             PublicKey = SABERPublicKey.getInstance(seq.getObjectAt(3));
     
             hpk = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(4)).getOctets());
    diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCSPLUSPrivateKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCSPLUSPrivateKey.java
    index a91fb8bbde..3f86bbe1c3 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCSPLUSPrivateKey.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCSPLUSPrivateKey.java
    @@ -1,8 +1,14 @@
     package org.bouncycastle.pqc.asn1;
     
    -import org.bouncycastle.asn1.*;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DEROctetString;
    +import org.bouncycastle.asn1.DERSequence;
     import org.bouncycastle.util.Arrays;
    -import org.bouncycastle.util.BigIntegers;
     
     /**
      * See https://datatracker.ietf.org/doc/draft-uni-qsckeys-sphincsplus/00/ for details
    @@ -59,18 +65,21 @@ public SPHINCSPLUSPrivateKey(int version, byte[] skseed, byte[] skprf, SPHINCSPL
             this.PublicKey = publicKey;
         }
     
    +    /**
    +     * @deprecated use getInstance()
    +     */
         public SPHINCSPLUSPrivateKey(ASN1Sequence seq)
         {
    -        version = BigIntegers.intValueExact(ASN1Integer.getInstance(seq.getObjectAt(0)).getValue());
    +        version = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
             if (version != 0)
             {
                 throw new IllegalArgumentException("unrecognized version");
             }
    +
             skseed = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
     
             skprf = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(2)).getOctets());
     
    -        // todo optional publickey
             if(seq.size() == 4)
             {
                 PublicKey = SPHINCSPLUSPublicKey.getInstance(seq.getObjectAt(3));
    diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCSPLUSPublicKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCSPLUSPublicKey.java
    index 4bcea5b24c..d0514d6ffc 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCSPLUSPublicKey.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCSPLUSPublicKey.java
    @@ -26,6 +26,9 @@ public SPHINCSPLUSPublicKey(byte[] pkseed, byte[] pkroot)
             this.pkroot = pkroot;
         }
     
    +    /**
    +     * @deprecated use getInstance()
    +     */
         public SPHINCSPLUSPublicKey(ASN1Sequence seq)
         {
             pkseed = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/DigestUtils.java b/core/src/main/java/org/bouncycastle/pqc/crypto/DigestUtils.java
    new file mode 100644
    index 0000000000..247b32512e
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/DigestUtils.java
    @@ -0,0 +1,48 @@
    +package org.bouncycastle.pqc.crypto;
    +
    +import java.util.HashMap;
    +import java.util.Map;
    +
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
    +import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
    +
    +public class DigestUtils
    +{
    +
    +    /**
    +     * Retrieve oid of hash/XOF function used to calculate pre-hash signatures
    +     * for pre-hash versions of slh-dsa and ml-dsa
    +     */
    +    static final Map digestOids = new HashMap();
    +
    +    static
    +    {
    +        digestOids.put("SHA-1", X509ObjectIdentifiers.id_SHA1);
    +        digestOids.put("SHA-224", NISTObjectIdentifiers.id_sha224);
    +        digestOids.put("SHA-256", NISTObjectIdentifiers.id_sha256);
    +        digestOids.put("SHA-384", NISTObjectIdentifiers.id_sha384);
    +        digestOids.put("SHA-512", NISTObjectIdentifiers.id_sha512);
    +        digestOids.put("SHA-512/224", NISTObjectIdentifiers.id_sha512_224);
    +        digestOids.put("SHA-512/256", NISTObjectIdentifiers.id_sha512_256);
    +
    +        digestOids.put("SHA3-224", NISTObjectIdentifiers.id_sha3_224);
    +        digestOids.put("SHA3-256", NISTObjectIdentifiers.id_sha3_256);
    +        digestOids.put("SHA3-384", NISTObjectIdentifiers.id_sha3_384);
    +        digestOids.put("SHA3-512", NISTObjectIdentifiers.id_sha3_512);
    +
    +        digestOids.put("SHAKE128", NISTObjectIdentifiers.id_shake128);
    +        digestOids.put("SHAKE256", NISTObjectIdentifiers.id_shake256);
    +    }
    +
    +
    +    public static ASN1ObjectIdentifier getDigestOid(String digestName)
    +    {
    +        if (digestOids.containsKey(digestName))
    +        {
    +            return (ASN1ObjectIdentifier)digestOids.get(digestName);
    +        }
    +
    +        throw new IllegalArgumentException("unrecognised digest algorithm: " + digestName);
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ExhaustedPrivateKeyException.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ExhaustedPrivateKeyException.java
    index 7fe4cc14b8..cb5362f655 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/ExhaustedPrivateKeyException.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ExhaustedPrivateKeyException.java
    @@ -1,5 +1,8 @@
     package org.bouncycastle.pqc.crypto;
     
    +/**
    + * Exception thrown by a stateful signature algorithm when the private key counter is exhausted.
    + */
     public class ExhaustedPrivateKeyException
         extends IllegalStateException
     {
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/bike/BIKEEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/bike/BIKEEngine.java
    index cafc60fc17..8476a9a3ff 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/bike/BIKEEngine.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/bike/BIKEEngine.java
    @@ -6,6 +6,7 @@
     import org.bouncycastle.crypto.digests.SHA3Digest;
     import org.bouncycastle.crypto.digests.SHAKEDigest;
     import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Bytes;
     
     class BIKEEngine
     {
    @@ -166,7 +167,7 @@ public void encaps(byte[] c0, byte[] c1, byte[] k, byte[] h, SecureRandom random
     
             //calculate c1
             functionL(e0Bytes, e1Bytes, c1);
    -        BIKEUtils.xorTo(m, c1, L_BYTE);
    +        Bytes.xorTo(L_BYTE, m, c1);
     
             // 4. Calculate K
             functionK(m, c0, c1, k);
    @@ -207,7 +208,7 @@ public void decaps(byte[] k, byte[] h0, byte[] h1, byte[] sigma, byte[] c0, byte
             // 2. Compute m'
             byte[] mPrime = new byte[L_BYTE];
             functionL(e0Bytes, e1Bytes, mPrime);
    -        BIKEUtils.xorTo(c1, mPrime, L_BYTE);
    +        Bytes.xorTo(L_BYTE, c1, mPrime);
     
             // 3. Compute K
             byte[] wlist = functionH(mPrime);
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/bike/BIKEPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/bike/BIKEPrivateKeyParameters.java
    index beec7f4d3a..8bbeaddba5 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/bike/BIKEPrivateKeyParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/bike/BIKEPrivateKeyParameters.java
    @@ -46,6 +46,6 @@ byte[] getSigma()
     
         public byte[] getEncoded()
         {
    -        return Arrays.concatenate(Arrays.concatenate(h0, h1), sigma);
    +        return Arrays.concatenate(h0, h1, sigma);
         }
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/bike/BIKEUtils.java b/core/src/main/java/org/bouncycastle/pqc/crypto/bike/BIKEUtils.java
    index 247176d0ea..039bd7638f 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/bike/BIKEUtils.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/bike/BIKEUtils.java
    @@ -5,14 +5,6 @@
     
     class BIKEUtils
     {
    -    static void xorTo(byte[] x, byte[] z, int zLen)
    -    {
    -        for (int i = 0; i < zLen; ++i)
    -        {
    -            z[i] ^= x[i];
    -        }
    -    }
    -
         static int getHammingWeight(byte[] bytes)
         {
             int hammingWeight = 0;
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/BENES.java b/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/BENES.java
    index 12b767d1b0..ed264b2237 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/BENES.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/BENES.java
    @@ -2,6 +2,9 @@
     
     abstract class BENES
     {
    +    private static final long[] TRANSPOSE_MASKS = { 0x5555555555555555L, 0x3333333333333333L,
    +        0x0F0F0F0F0F0F0F0FL, 0x00FF00FF00FF00FFL, 0x0000FFFF0000FFFFL, 0x00000000FFFFFFFFL };
    +
         protected final int SYS_N;
         protected final int SYS_T;
         protected final int GFBITS;
    @@ -17,77 +20,70 @@ public BENES(int n, int t, int m)
         /* output: out, transpose of in */
         static void transpose_64x64(long[] out, long[] in)
         {
    -        int i, j, s, d;
    -
    -        long x, y;
    -        long[][] masks = {
    -                {0x5555555555555555L, 0xAAAAAAAAAAAAAAAAL},
    -                {0x3333333333333333L, 0xCCCCCCCCCCCCCCCCL},
    -                {0x0F0F0F0F0F0F0F0FL, 0xF0F0F0F0F0F0F0F0L},
    -                {0x00FF00FF00FF00FFL, 0xFF00FF00FF00FF00L},
    -                {0x0000FFFF0000FFFFL, 0xFFFF0000FFFF0000L},
    -                {0x00000000FFFFFFFFL, 0xFFFFFFFF00000000L}
    -        };
    +        transpose_64x64(out, in, 0);
    +    }
     
    -        for (i = 0; i < 64; i++)
    -            out[i] = in[i];
    +    static void transpose_64x64(long[] out, long[] in, int offset)
    +    {
    +        System.arraycopy(in, offset, out, offset, 64);
     
    -        for (d = 5; d >= 0; d--)
    +        int d = 5;
    +        do
             {
    -            s = 1 << d;
    -            for (i = 0; i < 64; i += s*2)
    +            long m = TRANSPOSE_MASKS[d];
    +            int s = 1 << d;
    +            for (int i = offset; i < offset + 64; i += s * 2)
                 {
    -                for (j = i; j < i+s; j++)
    +                for (int j = i; j < i + s; j += 4)
                     {
    -                    x = (out[j] & masks[d][0]) | ((out[j+s] & masks[d][0]) << s);
    -                    y = ((out[j] & masks[d][1]) >>> s) | (out[j+s] & masks[d][1]);
    -
    -                    out[j+0] = x;
    -                    out[j+s] = y;
    +//                    Bits.bitPermuteStep2(ref out[j + s + 0], ref out[j + 0], m, s);
    +//                    Bits.bitPermuteStep2(ref out[j + s + 1], ref out[j + 1], m, s);
    +//                    Bits.bitPermuteStep2(ref out[j + s + 2], ref out[j + 2], m, s);
    +//                    Bits.bitPermuteStep2(ref out[j + s + 3], ref out[j + 3], m, s);
    +                    long lo0 = out[j + 0];
    +                    long lo1 = out[j + 1];
    +                    long lo2 = out[j + 2];
    +                    long lo3 = out[j + 3];
    +                    long hi0 = out[j + s + 0];
    +                    long hi1 = out[j + s + 1];
    +                    long hi2 = out[j + s + 2];
    +                    long hi3 = out[j + s + 3];
    +                    long t0 = ((lo0 >>> s) ^ hi0) & m;
    +                    long t1 = ((lo1 >>> s) ^ hi1) & m;
    +                    long t2 = ((lo2 >>> s) ^ hi2) & m;
    +                    long t3 = ((lo3 >>> s) ^ hi3) & m;
    +                    out[j + 0] = lo0 ^ t0 << s;
    +                    out[j + 1] = lo1 ^ t1 << s;
    +                    out[j + 2] = lo2 ^ t2 << s;
    +                    out[j + 3] = lo3 ^ t3 << s;
    +                    out[j + s + 0] = hi0 ^ t0;
    +                    out[j + s + 1] = hi1 ^ t1;
    +                    out[j + s + 2] = hi2 ^ t2;
    +                    out[j + s + 3] = hi3 ^ t3;
                     }
                 }
             }
    +        while (--d >= 2);
     
    -    }
    -
    -    static void transpose_64x64(long[] out, long[] in, int offset)
    -    {
    -        int i, j, s, d;
    -
    -        long x, y;
    -        long[][] masks = {
    -                {0x5555555555555555L, 0xAAAAAAAAAAAAAAAAL},
    -                {0x3333333333333333L, 0xCCCCCCCCCCCCCCCCL},
    -                {0x0F0F0F0F0F0F0F0FL, 0xF0F0F0F0F0F0F0F0L},
    -                {0x00FF00FF00FF00FFL, 0xFF00FF00FF00FF00L},
    -                {0x0000FFFF0000FFFFL, 0xFFFF0000FFFF0000L},
    -                {0x00000000FFFFFFFFL, 0xFFFFFFFF00000000L}
    -        };
    -
    -        for (i = 0; i < 64; i++)
    -            out[i + offset] = in[i + offset];
    -
    -        for (d = 5; d >= 0; d--)
    +        do
             {
    -            s = 1 << d;
    -            for (i = 0; i < 64; i += s*2)
    +            long m = TRANSPOSE_MASKS[d];
    +            int s = 1 << d;
    +            for (int i = offset; i < offset + 64; i += s * 2)
                 {
    -                for (j = i; j < i+s; j++)
    +                for (int j = i; j < i + s; ++j)
                     {
    -                    x = (out[j+offset] & masks[d][0]) | ((out[j+s + offset] & masks[d][0]) << s);
    -                    y = ((out[j+offset] & masks[d][1]) >>> s) | (out[j+s + offset] & masks[d][1]);
    -
    -                    out[j+0 + offset] = x;
    -                    out[j+s + offset] = y;
    +//                    Bits.bitPermuteStep2(ref out[j + s], ref out[j], m, s);
    +                    long lo = out[j + 0];
    +                    long hi = out[j + s];
    +                    long t = ((lo >>> s) ^ hi) & m;
    +                    out[j + 0] = lo ^ t << s;
    +                    out[j + s] = hi ^ t;
                     }
                 }
             }
    -
    +        while (--d >= 0);
         }
     
    -
         abstract protected void support_gen(short[] s, byte[] c);
    -
    -
    -
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/CMCEEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/CMCEEngine.java
    index 9edafef86b..9940495dfc 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/CMCEEngine.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/CMCEEngine.java
    @@ -236,7 +236,7 @@ public void kem_keypair(byte[] pk, byte[] sk, SecureRandom random)
     
                 // SeededKeyGen - 2. Define δ′ as the last l bits of E.
                 // Update seed using the last 32 bytes (l) of E
    -            // If anything fails, this set δ â†Î´â€˛ (the next last 32 bytes of E) and restart the algorithm.
    +            // If anything fails, this set δ = δ′ (the next last 32 bytes of E) and restart the algorithm.
                 seedIndex = E.length - 32;
                 seed_b = Arrays.copyOfRange(E, seedIndex, seedIndex + 32);
     
    @@ -246,7 +246,7 @@ public void kem_keypair(byte[] pk, byte[] sk, SecureRandom random)
     
                 // (step 5 and 4 are swapped)
                 // SeededKeyGen - 5. Compute g from the next Ď1t bits of E by the Irreducible algorithm. If this fails,
    -            // set δ â†Î´â€˛ and restart the algorithm.
    +            // set δ = δ′ and restart the algorithm.
     
                 // Create Field which is an element in gf2^mt
     
    @@ -277,7 +277,7 @@ public void kem_keypair(byte[] pk, byte[] sk, SecureRandom random)
                 }
     
                 // SeededKeyGen - 4. Compute α1,...,αq from the next Ď2q bits of E by the FieldOrdering algorithm.
    -            // If this fails, set δ â†Î´â€˛ and restart the algorithm.
    +            // If this fails, set δ = δ′ and restart the algorithm.
     
                 // Generate permutation
                 int[] perm = new int[(1 << GFBITS)];
    @@ -592,7 +592,7 @@ public int kem_dec(byte[] key, byte[] cipher_text, byte[] sk)
     
             /*
             2.3.3 Decapsulation
    -        4. Compute e â†Decode(C0,Γ′). If e = ⊥, set e â†s and b â†0.
    +        4. Compute e = Decode(C0,Γ′). If e = ⊥, set e = s and b = 0.
              */
     
             // Decrypt
    @@ -600,7 +600,7 @@ public int kem_dec(byte[] key, byte[] cipher_text, byte[] sk)
     
             /*
             2.3.3 Decapsulation
    -        6. If C′1 6= C1, set e â†s and b â†0.
    +        6. If C′1 6= C1, set e = s and b = 0.
              */
     
             short m;
    @@ -611,7 +611,7 @@ public int kem_dec(byte[] key, byte[] cipher_text, byte[] sk)
     
             /*
             2.3.3 Decapsulation
    -        2. Set b â†1.
    +        2. Set b = 1.
              */
             preimage[0] = (byte)(m & 1);
             for (i = 0; i < SYS_N / 8; i++)
    @@ -1502,7 +1502,7 @@ private int pk_gen(byte[] pk, byte[] sk, int[] perm, short[] pi, long[] pivots)
                         mat[row][c] ^= mat[k][c] & mask;
                     }
                 }
    -            // 7. Compute (T,cnâ’kâ’ÎĽ+1,...,cnâ’k,Γ′) ↠MatGen(Γ). If this fails, set δ ↠δ′ and
    +            // 7. Compute (T,cnâ’kâ’ÎĽ+1,...,cnâ’k,Γ′) =  MatGen(Γ). If this fails, set δ =  δ′ and
                 // restart the algorithm.
                 if (((mat[row][i] >> j) & 1) == 0) // return if not systematic
                 {
    @@ -1532,13 +1532,21 @@ private int pk_gen(byte[] pk, byte[] sk, int[] perm, short[] pi, long[] pivots)
                 if (usePadding)
                 {
                     int pk_index = 0, tail = PK_NROWS % 8;
    -                for (i = 0; i < PK_NROWS; i++)
    +                if (tail == 0)
    +                {
    +                    System.arraycopy(mat[i], (PK_NROWS - 1) / 8, pk, pk_index, SYS_N / 8);
    +                    pk_index += SYS_N / 8;
    +                }
    +                else
                     {
    -                    for (j = (PK_NROWS - 1) / 8; j < SYS_N / 8 - 1; j++)
    +                    for (i = 0; i < PK_NROWS; i++)
                         {
    -                        pk[pk_index++] = (byte)(((mat[i][j] & 0xff) >>> tail) | (mat[i][j + 1] << (8 - tail)));
    +                        for (j = (PK_NROWS - 1) / 8; j < SYS_N / 8 - 1; j++)
    +                        {
    +                            pk[pk_index++] = (byte)(((mat[i][j] & 0xff) >>> tail) | (mat[i][j + 1] << (8 - tail)));
    +                        }
    +                        pk[pk_index++] = (byte)((mat[i][j] & 0xff) >>> tail);
                         }
    -                    pk[pk_index++] = (byte)((mat[i][j] & 0xff) >>> tail);
                     }
                 }
                 else
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/GF12.java b/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/GF12.java
    index b814e5928b..c7d3fb72c1 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/GF12.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/GF12.java
    @@ -37,7 +37,8 @@ protected void gf_mul_poly(int length, int[] poly, short[] out, short[] left, sh
                     temp[i - length + poly[j]] ^= temp_i;
                 }
                 {
    -                temp[i - length] ^= gf_mul_ext(gf_reduce(temp_i), (short)2);
    +                // NOTE: Safe because gf_reduce allows up to 24 bits, but gf_mul_ext(_par) only produces 23.
    +                temp[i - length] ^= temp_i << 1;
                 }
             }
     
    @@ -66,7 +67,8 @@ protected void gf_sqr_poly(int length, int[] poly, short[] out, short[] input, i
                     temp[i - length + poly[j]] ^= temp_i;
                 }
                 {
    -                temp[i - length] ^= gf_mul_ext(gf_reduce(temp_i), (short)2);
    +                // NOTE: Safe because gf_reduce allows up to 24 bits, but gf_sq_ext only produces 23.
    +                temp[i - length] ^= temp_i << 1;
                 }
             }
     
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumEngine.java
    index 6bd90c80b7..e81526b0bd 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumEngine.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumEngine.java
    @@ -2,6 +2,7 @@
     
     import java.security.SecureRandom;
     
    +import org.bouncycastle.crypto.Digest;
     import org.bouncycastle.crypto.digests.SHAKEDigest;
     import org.bouncycastle.util.Arrays;
     
    @@ -19,6 +20,8 @@ class DilithiumEngine
         public final static int DilithiumRootOfUnity = 1753;
         public final static int SeedBytes = 32;
         public final static int CrhBytes = 64;
    +    public final static int RndBytes = 32;
    +    public final static int TrBytes = 64;
     
         public final static int DilithiumPolyT1PackedBytes = 320;
         public final static int DilithiumPolyT0PackedBytes = 416;
    @@ -39,6 +42,7 @@ class DilithiumEngine
         private final int DilithiumGamma1;
         private final int DilithiumGamma2;
         private final int DilithiumOmega;
    +    private final int DilithiumCTilde;
     
         private final int CryptoPublicKeyBytes;
         private final int CryptoSecretKeyBytes;
    @@ -53,102 +57,107 @@ protected Symmetric GetSymmetric()
             return symmetric;
         }
     
    -    public int getDilithiumPolyVecHPackedBytes()
    +    int getDilithiumPolyVecHPackedBytes()
         {
             return DilithiumPolyVecHPackedBytes;
         }
     
    -    public int getDilithiumPolyZPackedBytes()
    +    int getDilithiumPolyZPackedBytes()
         {
             return DilithiumPolyZPackedBytes;
         }
     
    -    public int getDilithiumPolyW1PackedBytes()
    +    int getDilithiumPolyW1PackedBytes()
         {
             return DilithiumPolyW1PackedBytes;
         }
     
    -    public int getDilithiumPolyEtaPackedBytes()
    +    int getDilithiumPolyEtaPackedBytes()
         {
             return DilithiumPolyEtaPackedBytes;
         }
     
    -    public int getDilithiumMode()
    +    int getDilithiumMode()
         {
             return DilithiumMode;
         }
     
    -    public int getDilithiumK()
    +    int getDilithiumK()
         {
             return DilithiumK;
         }
     
    -    public int getDilithiumL()
    +    int getDilithiumL()
         {
             return DilithiumL;
         }
     
    -    public int getDilithiumEta()
    +    int getDilithiumEta()
         {
             return DilithiumEta;
         }
     
    -    public int getDilithiumTau()
    +    int getDilithiumTau()
         {
             return DilithiumTau;
         }
     
    -    public int getDilithiumBeta()
    +    int getDilithiumBeta()
         {
             return DilithiumBeta;
         }
     
    -    public int getDilithiumGamma1()
    +    int getDilithiumGamma1()
         {
             return DilithiumGamma1;
         }
     
    -    public int getDilithiumGamma2()
    +    int getDilithiumGamma2()
         {
             return DilithiumGamma2;
         }
     
    -    public int getDilithiumOmega()
    +    int getDilithiumOmega()
         {
             return DilithiumOmega;
         }
    +    
    +    int getDilithiumCTilde()
    +    {
    +        return DilithiumCTilde;
    +    }
     
    -    public int getCryptoPublicKeyBytes()
    +    int getCryptoPublicKeyBytes()
         {
             return CryptoPublicKeyBytes;
         }
     
    -    public int getCryptoSecretKeyBytes()
    +    int getCryptoSecretKeyBytes()
         {
             return CryptoSecretKeyBytes;
         }
     
    -    public int getCryptoBytes()
    +    int getCryptoBytes()
         {
             return CryptoBytes;
         }
     
    -    public int getPolyUniformGamma1NBlocks()
    +    int getPolyUniformGamma1NBlocks()
         {
             return this.PolyUniformGamma1NBlocks;
         }
     
    -    public SHAKEDigest getShake256Digest()
    +    SHAKEDigest getShake256Digest()
         {
             return this.shake256Digest;
         }
     
    -    public SHAKEDigest getShake128Digest()
    +    SHAKEDigest getShake128Digest()
         {
             return this.shake128Digest;
         }
     
    -    public DilithiumEngine(int mode, SecureRandom random, boolean usingAes)
    +    DilithiumEngine(int mode, SecureRandom random, boolean usingAes)
         {
             this.DilithiumMode = mode;
             switch (mode)
    @@ -165,6 +174,7 @@ public DilithiumEngine(int mode, SecureRandom random, boolean usingAes)
                 this.DilithiumPolyZPackedBytes = 576;
                 this.DilithiumPolyW1PackedBytes = 192;
                 this.DilithiumPolyEtaPackedBytes = 96;
    +            this.DilithiumCTilde = 32;
                 break;
             case 3:
                 this.DilithiumK = 6;
    @@ -178,6 +188,7 @@ public DilithiumEngine(int mode, SecureRandom random, boolean usingAes)
                 this.DilithiumPolyZPackedBytes = 640;
                 this.DilithiumPolyW1PackedBytes = 128;
                 this.DilithiumPolyEtaPackedBytes = 128;
    +            this.DilithiumCTilde = 48;
                 break;
             case 5:
                 this.DilithiumK = 8;
    @@ -191,6 +202,7 @@ public DilithiumEngine(int mode, SecureRandom random, boolean usingAes)
                 this.DilithiumPolyZPackedBytes = 640;
                 this.DilithiumPolyW1PackedBytes = 128;
                 this.DilithiumPolyEtaPackedBytes = 96;
    +            this.DilithiumCTilde = 64;
                 break;
             default:
                 throw new IllegalArgumentException("The mode " + mode + "is not supported by Crystals Dilithium!");
    @@ -211,12 +223,13 @@ public DilithiumEngine(int mode, SecureRandom random, boolean usingAes)
             this.CryptoPublicKeyBytes = SeedBytes + this.DilithiumK * DilithiumPolyT1PackedBytes;
             this.CryptoSecretKeyBytes =
                 (
    -                3 * SeedBytes
    +                2 * SeedBytes
    +                    + TrBytes
                         + DilithiumL * this.DilithiumPolyEtaPackedBytes
                         + DilithiumK * this.DilithiumPolyEtaPackedBytes
                         + DilithiumK * DilithiumPolyT0PackedBytes
                 );
    -        this.CryptoBytes = SeedBytes + DilithiumL * this.DilithiumPolyZPackedBytes + this.DilithiumPolyVecHPackedBytes;
    +        this.CryptoBytes = DilithiumCTilde + DilithiumL * this.DilithiumPolyZPackedBytes + this.DilithiumPolyVecHPackedBytes;
     
             if (this.DilithiumGamma1 == (1 << 17))
             {
    @@ -232,24 +245,28 @@ else if (this.DilithiumGamma1 == (1 << 19))
             }
         }
     
    -    public byte[][] generateKeyPair()
    +    //Internal functions are deterministic. No randomness is sampled inside them
    +    public byte[][] generateKeyPairInternal(byte[] seed)
         {
    -        byte[] seedBuf = new byte[SeedBytes];
             byte[] buf = new byte[2 * SeedBytes + CrhBytes];
    -        byte[] tr = new byte[SeedBytes];
    +        byte[] tr = new byte[TrBytes];
     
             byte[] rho = new byte[SeedBytes],
    -            rhoPrime = new byte[CrhBytes],
    -            key = new byte[SeedBytes];
    +                rhoPrime = new byte[CrhBytes],
    +                key = new byte[SeedBytes];
     
             PolyVecMatrix aMatrix = new PolyVecMatrix(this);
     
             PolyVecL s1 = new PolyVecL(this), s1hat;
             PolyVecK s2 = new PolyVecK(this), t1 = new PolyVecK(this), t0 = new PolyVecK(this);
     
    -        random.nextBytes(seedBuf);
     
    -        shake256Digest.update(seedBuf, 0, SeedBytes);
    +
    +        shake256Digest.update(seed, 0, SeedBytes);
    +
    +        //Domain separation
    +        shake256Digest.update((byte)DilithiumK);
    +        shake256Digest.update((byte)DilithiumL);
     
             shake256Digest.doFinal(buf, 0, 2 * SeedBytes + CrhBytes);
             // System.out.print("buf = ");
    @@ -300,14 +317,14 @@ public byte[][] generateKeyPair()
     
             shake256Digest.update(rho, 0, rho.length);
             shake256Digest.update(encT1, 0, encT1.length);
    -        shake256Digest.doFinal(tr, 0, SeedBytes);
    +        shake256Digest.doFinal(tr, 0, TrBytes);
     
             byte[][] sk = Packing.packSecretKey(rho, tr, key, t0, s1, s2, this);
    -        
    +
             return new byte[][]{ sk[0], sk[1], sk[2], sk[3], sk[4], sk[5], encT1};
         }
     
    -    public byte[] signSignature(byte[] msg, int msglen, byte[] rho, byte[] key, byte[] tr, byte[] t0Enc, byte[] s1Enc, byte[] s2Enc)
    +    public byte[] signSignatureInternal(byte[] msg, int msglen, byte[] rho, byte[] key, byte[] tr, byte[] t0Enc, byte[] s1Enc, byte[] s2Enc, byte[] rnd)
         {
             int n;
             byte[] outSig = new byte[CryptoBytes + msglen];
    @@ -320,21 +337,17 @@ public byte[] signSignature(byte[] msg, int msglen, byte[] rho, byte[] key, byte
     
             Packing.unpackSecretKey(t0, s1, s2, t0Enc, s1Enc, s2Enc, this);
     
    -        this.shake256Digest.update(tr, 0, SeedBytes);
    +        this.shake256Digest.update(tr, 0, TrBytes);
             this.shake256Digest.update(msg, 0, msglen);
             this.shake256Digest.doFinal(mu, 0, CrhBytes);
     
    -        if (random != null)
    -        {
    -            random.nextBytes(rhoPrime);
    -        }
    -        else
    -        {
    -            byte[] keyMu = Arrays.copyOf(key, SeedBytes + CrhBytes);
    -            System.arraycopy(mu, 0, keyMu, SeedBytes, CrhBytes);
    -            shake256Digest.update(keyMu, 0, SeedBytes + CrhBytes);
    -            shake256Digest.doFinal(rhoPrime, 0, CrhBytes);
    -        }
    +
    +
    +        byte[] keyMu = Arrays.copyOf(key, SeedBytes + RndBytes + CrhBytes);
    +        System.arraycopy(rnd, 0, keyMu, SeedBytes, RndBytes);
    +        System.arraycopy(mu, 0, keyMu, SeedBytes + RndBytes, CrhBytes);
    +        shake256Digest.update(keyMu, 0, SeedBytes + RndBytes + CrhBytes);
    +        shake256Digest.doFinal(rhoPrime, 0, CrhBytes);
     
             aMatrix.expandMatrix(rho);
     
    @@ -366,9 +379,9 @@ public byte[] signSignature(byte[] msg, int msglen, byte[] rho, byte[] key, byte
     
                 shake256Digest.update(mu, 0, CrhBytes);
                 shake256Digest.update(outSig, 0, DilithiumK * DilithiumPolyW1PackedBytes);
    -            shake256Digest.doFinal(outSig, 0, SeedBytes);
    +            shake256Digest.doFinal(outSig, 0, DilithiumCTilde);
     
    -            cp.challenge(Arrays.copyOfRange(outSig, 0, SeedBytes));
    +            cp.challenge(Arrays.copyOfRange(outSig, 0, DilithiumCTilde));  // uses only the first DilithiumCTilde bytes of sig
                 cp.polyNtt();
     
                 // Compute z, reject if it reveals secret
    @@ -412,17 +425,12 @@ public byte[] signSignature(byte[] msg, int msglen, byte[] rho, byte[] key, byte
             return null;
         }
     
    -    public byte[] sign(byte[] msg, int mlen, byte[] rho, byte[] key, byte[] tr, byte[] t0, byte[] s1, byte[] s2)
    -    {
    -        return signSignature(msg, mlen, rho, key, tr, t0, s1, s2);
    -    }
    -
    -    public boolean signVerify(byte[] sig, int siglen, byte[] msg, int msglen, byte[] rho, byte[] encT1)
    +    public boolean signVerifyInternal(byte[] sig, int siglen, byte[] msg, int msglen, byte[] rho, byte[] encT1)
         {
             byte[] buf,
    -            mu = new byte[CrhBytes],
    -            c,
    -            c2 = new byte[SeedBytes];
    +                mu = new byte[CrhBytes],
    +                c,
    +                c2 = new byte[DilithiumCTilde];
             Poly cp = new Poly(this);
             PolyVecMatrix aMatrix = new PolyVecMatrix(this);
             PolyVecL z = new PolyVecL(this);
    @@ -447,7 +455,7 @@ public boolean signVerify(byte[] sig, int siglen, byte[] msg, int msglen, byte[]
             {
                 return false;
             }
    -        c = Arrays.copyOfRange(sig, 0, SeedBytes);
    +        c = Arrays.copyOfRange(sig, 0, DilithiumCTilde);
     
             // System.out.println(z.toString("z"));
             // System.out.println(h.toString("h"));
    @@ -460,11 +468,11 @@ public boolean signVerify(byte[] sig, int siglen, byte[] msg, int msglen, byte[]
             // Compute crh(crh(rho, t1), msg)
             shake256Digest.update(rho, 0, rho.length);
             shake256Digest.update(encT1, 0, encT1.length);
    -        shake256Digest.doFinal(mu, 0, SeedBytes);
    +        shake256Digest.doFinal(mu, 0, TrBytes);
             // System.out.println("mu before = ");
             // Helper.printByteArray(mu);
     
    -        shake256Digest.update(mu, 0, SeedBytes);
    +        shake256Digest.update(mu, 0, TrBytes);
             shake256Digest.update(msg, 0, msglen);
             shake256Digest.doFinal(mu, 0);
     
    @@ -472,7 +480,7 @@ public boolean signVerify(byte[] sig, int siglen, byte[] msg, int msglen, byte[]
             // Helper.printByteArray(mu);
     
             // Matrix-vector multiplication; compute Az - c2^dt1
    -        cp.challenge(c);
    +        cp.challenge(Arrays.copyOfRange(c, 0, DilithiumCTilde));  // use only first DilithiumCTilde of c.
             // System.out.println("cp = ");
             // System.out.println(cp.toString());
     
    @@ -516,7 +524,7 @@ public boolean signVerify(byte[] sig, int siglen, byte[] msg, int msglen, byte[]
             SHAKEDigest shakeDigest256 = new SHAKEDigest(256);
             shakeDigest256.update(mu, 0, CrhBytes);
             shakeDigest256.update(buf, 0, DilithiumK * DilithiumPolyW1PackedBytes);
    -        shakeDigest256.doFinal(c2, 0, SeedBytes);
    +        shakeDigest256.doFinal(c2, 0, DilithiumCTilde);
     
             // System.out.println("c = ");
             // Helper.printByteArray(c);
    @@ -525,18 +533,53 @@ public boolean signVerify(byte[] sig, int siglen, byte[] msg, int msglen, byte[]
             // Helper.printByteArray(c2);
     
     
    -        for (int i = 0; i < SeedBytes; ++i)
    +        return Arrays.constantTimeAreEqual(c, c2);
    +    }
    +
    +
    +
    +    public byte[][] generateKeyPair()
    +    {
    +        byte[] seedBuf = new byte[SeedBytes];
    +        random.nextBytes(seedBuf);
    +        return generateKeyPairInternal(seedBuf);
    +
    +    }
    +
    +    public byte[] signSignature(byte[] msg, int msglen, byte[] rho, byte[] key, byte[] tr, byte[] t0Enc, byte[] s1Enc, byte[] s2Enc)
    +    {
    +        byte[] rnd = new byte[RndBytes];
    +        if (random != null)
             {
    -            if (c[i] != c2[i])
    -            {
    -                return false;
    -            }
    +            random.nextBytes(rnd);
             }
    -        return true;
    +        return signSignatureInternal(msg, msglen, rho, key, tr, t0Enc, s1Enc, s2Enc, rnd);
    +    }
    +
    +    public byte[] sign(byte[] msg, int mlen, byte[] rho, byte[] key, byte[] tr, byte[] t0, byte[] s1, byte[] s2)
    +    {
    +        return signSignature(msg, mlen, rho, key, tr, t0, s1, s2);
    +    }
    +
    +    public boolean signVerify(byte[] sig, int siglen, byte[] msg, int msglen, byte[] rho, byte[] encT1)
    +    {
    +        //TODO: add domain separation
    +        // M' <- BytesToBits( IntegerToBytes(0, 1) || IntegerToBytes(|ctx|, 1) || ctx ) || M
    +        return signVerifyInternal(sig, siglen, msg, msglen, rho, encT1);
         }
     
         public boolean signOpen(byte[] msg, byte[] signedMsg, int signedMsglen, byte[] rho, byte[] t1)
         {
    +        //TODO: add domain separation
    +        // M' <- BytesToBits( IntegerToBytes(0, 1) || IntegerToBytes(|ctx|, 1) || ctx ) || M
             return signVerify(signedMsg, signedMsglen, msg, msg.length, rho, t1);
         }
    +
    +    // HashML-DSA
    +    //TODO: Generate a "pre-hash" ML-DSA signature
    +//    public byte[] hashSign(byte[] sk, byte[] message, byte[] ctx, Digest ph) {}
    +    //TODO: Verify a pre-hash HashML-DSA signature
    +//    public boolean hashVerify(byte[] pk, byte[] message, byte[] sig) {}
    +
    +
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumKeyPairGenerator.java
    index a32e187e23..25bb5f1219 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumKeyPairGenerator.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumKeyPairGenerator.java
    @@ -44,4 +44,17 @@ public AsymmetricCipherKeyPair generateKeyPair()
         {
             return genKeyPair();
         }
    +    public AsymmetricCipherKeyPair internalGenerateKeyPair(byte[] seed)
    +    {
    +        DilithiumEngine engine = dilithiumParams.getEngine(random);
    +
    +        byte[][] keyPair = engine.generateKeyPairInternal(seed);
    +        // System.out.println("pk gen = ");
    +        // Helper.printByteArray(keyPair[0]);
    +
    +        DilithiumPublicKeyParameters pubKey = new DilithiumPublicKeyParameters(dilithiumParams, keyPair[0], keyPair[6]);
    +        DilithiumPrivateKeyParameters privKey = new DilithiumPrivateKeyParameters(dilithiumParams, keyPair[0], keyPair[1], keyPair[2], keyPair[3], keyPair[4], keyPair[5], keyPair[6]);
    +
    +        return new AsymmetricCipherKeyPair(pubKey, privKey);
    +    }
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumParameters.java
    index c3e0cf9236..b64cc82ab5 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumParameters.java
    @@ -5,17 +5,16 @@
     public class DilithiumParameters
     {
         public static final DilithiumParameters dilithium2 = new DilithiumParameters("dilithium2", 2, false);
    -    public static final DilithiumParameters dilithium2_aes = new DilithiumParameters("dilithium2-aes", 2, true);
    -
         public static final DilithiumParameters dilithium3 = new DilithiumParameters("dilithium3", 3, false);
    -    public static final DilithiumParameters dilithium3_aes = new DilithiumParameters("dilithium3-aes", 3, true);
    -
         public static final DilithiumParameters dilithium5 = new DilithiumParameters("dilithium5", 5, false);
    -    public static final DilithiumParameters dilithium5_aes = new DilithiumParameters("dilithium5-aes", 5, true);
     
         private final int k;
         private final String name;
     
    +    /**
    +     * @deprecated
    +     * obsolete to be removed
    +     */
         private final boolean usingAES;// or shake
     
         private DilithiumParameters(String name, int k, boolean usingAES)
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumPrivateKeyParameters.java
    index f3b8f18009..4193d654b8 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumPrivateKeyParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumPrivateKeyParameters.java
    @@ -14,11 +14,6 @@ public class DilithiumPrivateKeyParameters
     
         private final byte[] t1;
     
    -    public byte[] getPrivateKey()
    -    {
    -        return getEncoded();
    -    }
    -
         public DilithiumPrivateKeyParameters(DilithiumParameters params, byte[] rho, byte[] K, byte[] tr, byte[] s1, byte[] s2, byte[] t0, byte[] t1)
         {
             super(true, params);
    @@ -31,9 +26,35 @@ public DilithiumPrivateKeyParameters(DilithiumParameters params, byte[] rho, byt
             this.t1 = Arrays.clone(t1);
         }
     
    -    public byte[] getRho()
    +    public DilithiumPrivateKeyParameters(DilithiumParameters params, byte[] encoding, DilithiumPublicKeyParameters pubKey)
         {
    -        return Arrays.clone(rho);
    +        super(true, params);
    +
    +        DilithiumEngine eng = params.getEngine(null);
    +        int index = 0;
    +        this.rho = Arrays.copyOfRange(encoding, 0, DilithiumEngine.SeedBytes); index += DilithiumEngine.SeedBytes;
    +        this.k = Arrays.copyOfRange(encoding, index, index + DilithiumEngine.SeedBytes); index += DilithiumEngine.SeedBytes;
    +        this.tr = Arrays.copyOfRange(encoding, index, index + DilithiumEngine.TrBytes); index += DilithiumEngine.TrBytes;
    +        int delta = eng.getDilithiumL() * eng.getDilithiumPolyEtaPackedBytes();
    +        this.s1 = Arrays.copyOfRange(encoding, index, index + delta); index += delta;
    +        delta = eng.getDilithiumK() * eng.getDilithiumPolyEtaPackedBytes();
    +        this.s2 = Arrays.copyOfRange(encoding, index, index + delta); index += delta;
    +        delta = eng.getDilithiumK() * DilithiumEngine.DilithiumPolyT0PackedBytes;
    +        this.t0 = Arrays.copyOfRange(encoding, index, index + delta); index += delta;
    +
    +        if (pubKey != null)
    +        {
    +            this.t1 = pubKey.getT1();
    +        }
    +        else
    +        {
    +            this.t1 = null;
    +        }
    +    }
    +
    +    public byte[] getEncoded()
    +    {
    +        return Arrays.concatenate(new byte[][]{ rho, k, tr, s1, s2, t0 });
         }
     
         public byte[] getK()
    @@ -41,9 +62,25 @@ public byte[] getK()
             return Arrays.clone(k);
         }
     
    -    public byte[] getTr()
    +    /** @deprecated Use {@link #getEncoded()} instead. */
    +    public byte[] getPrivateKey()
         {
    -        return Arrays.clone(tr);
    +        return getEncoded();
    +    }
    +
    +    public byte[] getPublicKey()
    +    {
    +        return DilithiumPublicKeyParameters.getEncoded(rho, t1);
    +    }
    +
    +    public DilithiumPublicKeyParameters getPublicKeyParameters()
    +    {
    +        return new DilithiumPublicKeyParameters(getParameters(), rho, t1);
    +    }
    +
    +    public byte[] getRho()
    +    {
    +        return Arrays.clone(rho);
         }
     
         public byte[] getS1()
    @@ -63,11 +100,11 @@ public byte[] getT0()
     
         public byte[] getT1()
         {
    -        return t1;
    +        return Arrays.clone(t1);
         }
     
    -    public byte[] getEncoded()
    +    public byte[] getTr()
         {
    -        return Arrays.concatenate(new byte[][] { rho, k, tr, s1, s2, t0 });
    +        return Arrays.clone(tr);
         }
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumPublicKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumPublicKeyParameters.java
    index c609be1360..10a60fa61e 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumPublicKeyParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumPublicKeyParameters.java
    @@ -5,35 +5,40 @@
     public class DilithiumPublicKeyParameters
         extends DilithiumKeyParameters
     {
    +    static byte[] getEncoded(byte[] rho, byte[] t1)
    +    {
    +        return Arrays.concatenate(rho, t1);
    +    }
    +
         final byte[] rho;
         final byte[] t1;
     
    -    public byte[] getRho()
    +    public DilithiumPublicKeyParameters(DilithiumParameters params, byte[] encoding)
         {
    -        return Arrays.clone(rho);
    +        super(false, params);
    +        this.rho = Arrays.copyOfRange(encoding, 0, DilithiumEngine.SeedBytes);
    +        this.t1 = Arrays.copyOfRange(encoding, DilithiumEngine.SeedBytes, encoding.length);
         }
     
    -    public byte[] getT1()
    +    public DilithiumPublicKeyParameters(DilithiumParameters params, byte[] rho, byte[] t1)
         {
    -        return Arrays.clone(t1);
    +        super(false, params);
    +        this.rho = Arrays.clone(rho);
    +        this.t1 = Arrays.clone(t1);
         }
     
         public byte[] getEncoded()
         {
    -        return Arrays.concatenate(rho, t1);
    +        return getEncoded(rho, t1);
         }
     
    -    public DilithiumPublicKeyParameters(DilithiumParameters params, byte[] encoding)
    +    public byte[] getRho()
         {
    -        super(false, params);
    -        this.rho = Arrays.copyOfRange(encoding, 0, DilithiumEngine.SeedBytes);
    -        this.t1 = Arrays.copyOfRange(encoding, DilithiumEngine.SeedBytes, encoding.length);
    +        return Arrays.clone(rho);
         }
     
    -    public DilithiumPublicKeyParameters(DilithiumParameters params, byte[] rho, byte[] t1)
    +    public byte[] getT1()
         {
    -        super(false, params);
    -        this.rho = Arrays.clone(rho);
    -        this.t1 = Arrays.clone(t1);
    +        return Arrays.clone(t1);
         }
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumSigner.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumSigner.java
    index 859916207f..a37eaafa75 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumSigner.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumSigner.java
    @@ -45,6 +45,12 @@ public byte[] generateSignature(byte[] message)
     
             return engine.sign(message, message.length, privKey.rho, privKey.k, privKey.tr, privKey.t0, privKey.s1, privKey.s2);
         }
    +    public byte[] internalGenerateSignature(byte[] message, byte[] random)
    +    {
    +        DilithiumEngine engine = privKey.getParameters().getEngine(this.random);
    +
    +        return engine.signSignatureInternal(message, message.length, privKey.rho, privKey.k, privKey.tr, privKey.t0, privKey.s1, privKey.s2, random);
    +    }
     
         public boolean verifySignature(byte[] message, byte[] signature)
         {
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/Packing.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/Packing.java
    index bc0919bd2f..7f63350efb 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/Packing.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/Packing.java
    @@ -86,8 +86,8 @@ static byte[] packSignature(byte[] c, PolyVecL z, PolyVecK h, DilithiumEngine en
             int i, j, k, end = 0;
             byte[] outBytes = new byte[engine.getCryptoBytes()];
     
    -        System.arraycopy(c, 0, outBytes, 0, DilithiumEngine.SeedBytes);
    -        end += DilithiumEngine.SeedBytes;
    +        System.arraycopy(c, 0, outBytes, 0, engine.getDilithiumCTilde());
    +        end += engine.getDilithiumCTilde();
     
             for (i = 0; i < engine.getDilithiumL(); ++i)
             {
    @@ -121,7 +121,7 @@ static boolean unpackSignature(PolyVecL z, PolyVecK h, byte[] sig, DilithiumEngi
         {
             int i, j, k;
     
    -        int end = DilithiumEngine.SeedBytes;
    +        int end = engine.getDilithiumCTilde();
             for (i = 0; i < engine.getDilithiumL(); ++i)
             {
                 z.getVectorIndex(i).zUnpack(Arrays.copyOfRange(sig, end + i * engine.getDilithiumPolyZPackedBytes(), end + (i + 1) * engine.getDilithiumPolyZPackedBytes()));
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/Poly.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/Poly.java
    index 3b1042fb87..62d6a753ce 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/Poly.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/Poly.java
    @@ -580,7 +580,7 @@ public void challenge(byte[] seed)
             byte[] buf = new byte[symmetric.stream256BlockBytes];
     
             SHAKEDigest shake256Digest = new SHAKEDigest(256);
    -        shake256Digest.update(seed, 0, DilithiumEngine.SeedBytes);
    +        shake256Digest.update(seed, 0, engine.getDilithiumCTilde());
             shake256Digest.doOutput(buf, 0, symmetric.stream256BlockBytes);
     
             signs = (long)0;
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/Symmetric.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/Symmetric.java
    index 2349168dce..a255a59087 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/Symmetric.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/Symmetric.java
    @@ -1,5 +1,6 @@
     package org.bouncycastle.pqc.crypto.crystals.dilithium;
     
    +import org.bouncycastle.crypto.StreamCipher;
     import org.bouncycastle.crypto.digests.SHAKEDigest;
     import org.bouncycastle.crypto.engines.AESEngine;
     import org.bouncycastle.crypto.modes.SICBlockCipher;
    @@ -26,16 +27,22 @@ abstract class Symmetric
     
         abstract void stream256squeezeBlocks(byte[] output, int offset, int size);
     
    +
    +    /**
    +     * @deprecated
    +     * obsolete to be removed
    +     */
    +    @Deprecated
         static class AesSymmetric
             extends Symmetric
         {
     
    -        private final SICBlockCipher cipher;
    +        private final StreamCipher cipher;
     
             AesSymmetric()
             {
                 super(64, 64);
    -            cipher = new SICBlockCipher(new AESEngine());
    +            cipher = SICBlockCipher.newInstance(AESEngine.newInstance());
             }
     
             private void aes128(byte[] out, int offset, int size)
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKEMGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKEMGenerator.java
    deleted file mode 100644
    index 9249e67b8c..0000000000
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKEMGenerator.java
    +++ /dev/null
    @@ -1,29 +0,0 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    -
    -import java.security.SecureRandom;
    -
    -import org.bouncycastle.crypto.EncapsulatedSecretGenerator;
    -import org.bouncycastle.crypto.SecretWithEncapsulation;
    -import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
    -import org.bouncycastle.pqc.crypto.util.SecretWithEncapsulationImpl;
    -
    -public class KyberKEMGenerator
    -    implements EncapsulatedSecretGenerator
    -{
    -    // the source of randomness
    -    private final SecureRandom sr;
    -
    -    public KyberKEMGenerator(SecureRandom random)
    -    {
    -        this.sr = random;
    -    }
    -
    -    public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey)
    -    {
    -        KyberPublicKeyParameters key = (KyberPublicKeyParameters)recipientKey;
    -        KyberEngine engine = key.getParameters().getEngine();
    -        engine.init(sr);
    -        byte[][] kemEncrypt = engine.kemEncrypt(key.getPublicKey());
    -        return new SecretWithEncapsulationImpl(kemEncrypt[0], kemEncrypt[1]);
    -    }
    -}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKeyGenerationParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKeyGenerationParameters.java
    deleted file mode 100644
    index 897bb69655..0000000000
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKeyGenerationParameters.java
    +++ /dev/null
    @@ -1,24 +0,0 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    -
    -import java.security.SecureRandom;
    -
    -import org.bouncycastle.crypto.KeyGenerationParameters;
    -
    -public class KyberKeyGenerationParameters
    -    extends KeyGenerationParameters
    -{
    -    private final KyberParameters params;
    -
    -    public KyberKeyGenerationParameters(
    -        SecureRandom random,
    -        KyberParameters kyberParameters)
    -    {
    -        super(random, 256);
    -        this.params = kyberParameters;
    -    }
    -
    -    public KyberParameters getParameters()
    -    {
    -        return params;
    -    }
    -}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKeyPairGenerator.java
    deleted file mode 100644
    index 96ab334d20..0000000000
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKeyPairGenerator.java
    +++ /dev/null
    @@ -1,48 +0,0 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    -
    -import java.security.SecureRandom;
    -
    -import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
    -import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
    -import org.bouncycastle.crypto.KeyGenerationParameters;
    -
    -public class KyberKeyPairGenerator
    -    implements AsymmetricCipherKeyPairGenerator
    -{
    -    private KyberParameters kyberParams;
    -
    -    private SecureRandom random;
    -
    -    private void initialize(
    -        KeyGenerationParameters param)
    -    {
    -        this.kyberParams = ((KyberKeyGenerationParameters)param).getParameters();
    -        this.random = param.getRandom();
    -
    -    }
    -
    -    private AsymmetricCipherKeyPair genKeyPair()
    -    {
    -        KyberEngine engine = kyberParams.getEngine();
    -
    -        engine.init(random);
    -
    -        byte[][] keyPair = engine.generateKemKeyPair();
    -
    -        KyberPublicKeyParameters pubKey = new KyberPublicKeyParameters(kyberParams, keyPair[0], keyPair[1]);
    -        KyberPrivateKeyParameters privKey = new KyberPrivateKeyParameters(kyberParams,  keyPair[2], keyPair[3], keyPair[4], keyPair[0], keyPair[1]);
    -        
    -        return new AsymmetricCipherKeyPair(pubKey, privKey);
    -    }
    -
    -    public void init(KeyGenerationParameters param)
    -    {
    -        this.initialize(param);
    -    }
    -
    -    public AsymmetricCipherKeyPair generateKeyPair()
    -    {
    -        return genKeyPair();
    -    }
    -
    -}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberParameters.java
    deleted file mode 100644
    index 22232be183..0000000000
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberParameters.java
    +++ /dev/null
    @@ -1,42 +0,0 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    -
    -import org.bouncycastle.pqc.crypto.KEMParameters;
    -
    -public class KyberParameters
    -    implements KEMParameters
    -{
    -    public static final KyberParameters kyber512 = new KyberParameters("kyber512", 2, 128, false);
    -    public static final KyberParameters kyber768 = new KyberParameters("kyber768", 3, 192, false);
    -    public static final KyberParameters kyber1024 = new KyberParameters("kyber1024", 4, 256, false);
    -    public static final KyberParameters kyber512_aes = new KyberParameters("kyber512-aes", 2, 128, true);
    -    public static final KyberParameters kyber768_aes = new KyberParameters("kyber768-aes", 3, 192, true);
    -    public static final KyberParameters kyber1024_aes = new KyberParameters("kyber1024-aes", 4, 256, true);
    -
    -    private final String name;
    -    private final int k;
    -    private final int sessionKeySize;
    -    private final boolean usingAes;
    -
    -    private KyberParameters(String name, int k, int sessionKeySize, boolean usingAes)
    -    {
    -        this.name = name;
    -        this.k = k;
    -        this.sessionKeySize = sessionKeySize;
    -        this.usingAes = usingAes;
    -    }
    -
    -    public String getName()
    -    {
    -        return name;
    -    }
    -
    -    KyberEngine getEngine()
    -    {
    -        return new KyberEngine(k, usingAes);
    -    }
    -
    -    public int getSessionKeySize()
    -    {
    -        return sessionKeySize;
    -    }
    -}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberPrivateKeyParameters.java
    deleted file mode 100644
    index f0b7e62ca7..0000000000
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberPrivateKeyParameters.java
    +++ /dev/null
    @@ -1,63 +0,0 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    -
    -import org.bouncycastle.util.Arrays;
    -
    -public class KyberPrivateKeyParameters
    -    extends KyberKeyParameters
    -{
    -    final byte[] s;
    -    final byte[] hpk;
    -    final byte[] nonce;
    -    final byte[] t;
    -    final byte[] rho;
    -
    -    public KyberPrivateKeyParameters(KyberParameters params, byte[] s, byte[] hpk, byte[] nonce, byte[] t, byte[] rho)
    -    {
    -        super(true, params);
    -        this.s = Arrays.clone(s);
    -        this.hpk = Arrays.clone(hpk);
    -        this.nonce = Arrays.clone(nonce);
    -        this.t = Arrays.clone(t);
    -        this.rho = Arrays.clone(rho);
    -    }
    -
    -    public byte[] getT()
    -    {
    -        return Arrays.clone(t);
    -    }
    -
    -    public byte[] getRho()
    -    {
    -        return Arrays.clone(rho);
    -    }
    -
    -    public byte[] getPrivateKey()
    -    {
    -        return Arrays.concatenate(s, getPublicKey(), hpk, nonce);
    -    }
    -
    -    public byte[] getEncoded()
    -    {
    -        return getPrivateKey();
    -    }
    -
    -    public byte[] getPublicKey()
    -    {
    -        return Arrays.concatenate(t, rho);
    -    }
    -
    -    public byte[] getS()
    -    {
    -        return Arrays.clone(s);
    -    }
    -
    -    public byte[] getHPK()
    -    {
    -        return Arrays.clone(hpk);
    -    }
    -
    -    public byte[] getNonce()
    -    {
    -        return Arrays.clone(nonce);
    -    }
    -}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/Symmetric.java b/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/Symmetric.java
    deleted file mode 100644
    index 9639c9cbcb..0000000000
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/Symmetric.java
    +++ /dev/null
    @@ -1,177 +0,0 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    -
    -import org.bouncycastle.crypto.ExtendedDigest;
    -import org.bouncycastle.crypto.digests.SHA256Digest;
    -import org.bouncycastle.crypto.digests.SHA3Digest;
    -import org.bouncycastle.crypto.digests.SHA512Digest;
    -import org.bouncycastle.crypto.digests.SHAKEDigest;
    -import org.bouncycastle.crypto.engines.AESEngine;
    -import org.bouncycastle.crypto.modes.SICBlockCipher;
    -import org.bouncycastle.crypto.params.KeyParameter;
    -import org.bouncycastle.crypto.params.ParametersWithIV;
    -
    -abstract class Symmetric
    -{
    -
    -    final int xofBlockBytes;
    -
    -    abstract void hash_h(byte[] out, byte[] in, int outOffset);
    -
    -    abstract void hash_g(byte[] out, byte[] in);
    -
    -    abstract void xofAbsorb(byte[] seed, byte x, byte y);
    -
    -    abstract void xofSqueezeBlocks(byte[] out, int outOffset, int outLen);
    -
    -    abstract void prf(byte[] out, byte[] key, byte nonce);
    -
    -    abstract void kdf(byte[] out, byte[] in);
    -
    -    Symmetric(int blockBytes)
    -    {
    -        this.xofBlockBytes = blockBytes;
    -    }
    -
    -
    -    static class ShakeSymmetric
    -        extends Symmetric
    -    {
    -        private final SHAKEDigest xof;
    -        private final SHA3Digest sha3Digest512;
    -        private final SHA3Digest sha3Digest256;
    -        private final SHAKEDigest shakeDigest;
    -
    -        ShakeSymmetric()
    -        {
    -            super(168);
    -            this.xof = new SHAKEDigest(128);
    -            this.shakeDigest = new SHAKEDigest(256);
    -            this.sha3Digest256 = new SHA3Digest(256);
    -            this.sha3Digest512 = new SHA3Digest(512);
    -        }
    -
    -        @Override
    -        void hash_h(byte[] out, byte[] in, int outOffset)
    -        {
    -            sha3Digest256.update(in, 0, in.length);
    -            sha3Digest256.doFinal(out, outOffset);
    -        }
    -
    -        @Override
    -        void hash_g(byte[] out, byte[] in)
    -        {
    -            sha3Digest512.update(in, 0, in.length);
    -            sha3Digest512.doFinal(out, 0);
    -        }
    -
    -        @Override
    -        void xofAbsorb(byte[] seed, byte a, byte b)
    -        {
    -            xof.reset();
    -            byte[] buf = new byte[seed.length + 2];
    -            System.arraycopy(seed, 0, buf, 0, seed.length);
    -            buf[seed.length] = a;
    -            buf[seed.length + 1] = b;
    -            xof.update(buf, 0, seed.length + 2);
    -        }
    -
    -        @Override
    -        void xofSqueezeBlocks(byte[] out, int outOffset, int outLen)
    -        {
    -            xof.doOutput(out, outOffset, outLen);
    -        }
    -
    -        @Override
    -        void prf(byte[] out, byte[] seed, byte nonce)
    -        {
    -            byte[] extSeed = new byte[seed.length + 1];
    -            System.arraycopy(seed, 0, extSeed, 0, seed.length);
    -            extSeed[seed.length] = nonce;
    -            shakeDigest.update(extSeed, 0, extSeed.length);
    -            shakeDigest.doFinal(out, 0, out.length);
    -        }
    -
    -        @Override
    -        void kdf(byte[] out, byte[] in)
    -        {
    -            shakeDigest.update(in, 0, in.length);
    -            shakeDigest.doFinal(out, 0, out.length);
    -        }
    -    }
    -
    -    static class AesSymmetric
    -        extends Symmetric
    -    {
    -        private final SHA256Digest sha256Digest;
    -        private final SHA512Digest sha512Digest;
    -        private final SICBlockCipher cipher;
    -
    -        AesSymmetric()
    -        {
    -            super(64);
    -            this.sha256Digest = new SHA256Digest();
    -            this.sha512Digest = new SHA512Digest();
    -            this.cipher = new SICBlockCipher(new AESEngine());
    -        }
    -
    -        private void doDigest(ExtendedDigest digest, byte[] out, byte[] in, int outOffset)
    -        {
    -            digest.update(in, 0, in.length);
    -            digest.doFinal(out, outOffset);
    -        }
    -
    -        private void aes128(byte[] out, int offset, int size)
    -        {
    -            byte[] buf = new byte[size];   // TODO: there might be a more efficient way of doing this...
    -            cipher.processBytes(buf, 0, size, out, offset);
    -        }
    -
    -        @Override
    -        void hash_h(byte[] out, byte[] in, int outOffset)
    -        {
    -            doDigest(sha256Digest, out, in, outOffset);
    -        }
    -
    -        @Override
    -        void hash_g(byte[] out, byte[] in)
    -        {
    -            doDigest(sha512Digest, out, in, 0);
    -        }
    -
    -        @Override
    -        void xofAbsorb(byte[] key, byte x, byte y)
    -        {
    -            byte[] expnonce = new byte[12];
    -            expnonce[0] = x;
    -            expnonce[1] = y;
    -
    -            ParametersWithIV kp = new ParametersWithIV(new KeyParameter(key, 0, 32), expnonce);
    -            cipher.init(true, kp);
    -        }
    -
    -        @Override
    -        void xofSqueezeBlocks(byte[] out, int outOffset, int outLen)
    -        {
    -            aes128(out, outOffset, outLen);
    -        }
    -
    -        @Override
    -        void prf(byte[] out, byte[] key, byte nonce)
    -        {
    -            byte[] expnonce = new byte[12];
    -            expnonce[0] = nonce;
    -
    -            ParametersWithIV kp = new ParametersWithIV(new KeyParameter(key, 0, 32), expnonce);
    -            cipher.init(true, kp);
    -            aes128(out, 0, out.length);
    -        }
    -
    -        @Override
    -        void kdf(byte[] out, byte[] in)
    -        {
    -            byte[] buf = new byte[32];
    -            doDigest(sha256Digest, buf, in, 0);
    -            System.arraycopy(buf, 0, out, 0, out.length);
    -        }
    -    }
    -}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/falcon/FalconVrfy.java b/core/src/main/java/org/bouncycastle/pqc/crypto/falcon/FalconVrfy.java
    index 5478bdc2a5..f1bebf2ad0 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/falcon/FalconVrfy.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/falcon/FalconVrfy.java
    @@ -702,7 +702,7 @@ boolean complete_private(byte[] srcG, int G,
                              byte[] srcf, int f, byte[] srcg, int g, byte[] srcF, int F,
                              int logn, short[] srctmp, int tmp)
         {
    -        boolean success = true;
    +        int success = -1;
             int u, n;
             int t1, t2;
     
    @@ -725,22 +725,20 @@ boolean complete_private(byte[] srcG, int G,
             mq_NTT(srctmp, t2, logn);
             for (u = 0; u < n; u++)
             {
    -            success &= (srctmp[t2 + u] != 0);
    +            int tmp2 = srctmp[t2 + u] & 0xffff;
    +            success &= -tmp2; // check tmp2 != 0
                 srctmp[t1 + u] = (short)mq_div_12289(srctmp[t1 + u], srctmp[t2 + u]);
             }
             mq_iNTT(srctmp, t1, logn);
             for (u = 0; u < n; u++)
             {
    -            int w;
    -            int gi;
    -
    -            w = (srctmp[t1 + u] & 0xffff);
    -            w -= (Q & ~-((w - (Q >> 1)) >>> 31)); // w is unsigned
    -            gi = w; // gi is signed
    -            success &= !(gi < -127 || gi > +127);
    +            int w = srctmp[t1 + u] & 0xffff;
    +            int gi = w - (Q & (((Q >> 1) - w) >> 31));
    +            success &= +gi - 128; // check +gi < 128
    +            success &= -gi - 128; // check -gi < 128
                 srcG[G + u] = (byte)gi;
             }
    -        return success;
    +        return success < 0;
         }
     
         /* see inner.h */
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/frodo/FrodoEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/frodo/FrodoEngine.java
    index d62bc7be8a..66c88c602b 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/frodo/FrodoEngine.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/frodo/FrodoEngine.java
    @@ -322,7 +322,7 @@ private short[] unpack(byte[] in, int n1, int n2)
         private short[] encode(byte[] k)
         {
             int l, byte_index = 0;
    -        byte mask = 1;
    +        int bit = 0;
             short[] K = new short[mbar*nbar];
             int temp;
             // 1. for i = 0; i < mbar; i += 1
    @@ -335,16 +335,13 @@ private short[] encode(byte[] k)
                     temp = 0;
                     for (l = 0; l < B; l++)
                     {
    -                    //mask
    -                    int mult = ((k[byte_index] & mask) == mask) ? 1 : 0;
    -                    temp += (1 << l) * mult;
    -                    mask <<= 1;
    -                    if (mask == 0)
    -                    {
    -                        mask = 1;
    -                        byte_index++;
    -                    }
    +                    temp += ((k[byte_index] >>> bit) & 1) << l;
    +
    +                    ++bit;
    +                    byte_index += bit >>> 3;
    +                    bit &= 7;
                     }
    +
                     // 4. K[i][j] = ec(tmp) = tmp * q/2^B
                     K[i*nbar+j] = (short) (temp * (q / (1 << B)));
                 }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/gemss/GeMSSEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/gemss/GeMSSEngine.java
    index 781ec8af6c..c0dec946d5 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/gemss/GeMSSEngine.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/gemss/GeMSSEngine.java
    @@ -1,9 +1,11 @@
     package org.bouncycastle.pqc.crypto.gemss;
     
    +import java.math.BigInteger;
     import java.security.SecureRandom;
     
     import org.bouncycastle.crypto.digests.SHA3Digest;
     import org.bouncycastle.crypto.digests.SHAKEDigest;
    +import org.bouncycastle.util.Pack;
     
     class GeMSSEngine
     {
    @@ -1895,7 +1897,7 @@ private int chooseRootHFE_gf2nx(Pointer root, SecretKeyHFE.complete_sparse_monic
                 /* Choose a root with a determinist hash */
                 getSHA3Hash(hash, 0, Sha3BitStrength >>> 3, U.toBytes(NB_BYTES_GFqn), 0,
                     NB_BYTES_GFqn, new byte[Sha3BitStrength >>> 3]);
    -            root.copyFrom(0, roots, (int)Long.remainderUnsigned(hash.get(), l) * NB_WORD_GFqn, NB_WORD_GFqn);
    +            root.copyFrom(0, roots, (int)remainderUnsigned(hash.get(), l) * NB_WORD_GFqn, NB_WORD_GFqn);
             }
             return l;
         }
    @@ -3205,4 +3207,16 @@ private void vmpv_xorrange_move(Pointer acc, Pointer V, Pointer F)
             acc.setXorRange(F, NB_WORD_GFqn);
             F.move(MLv_GFqn_SIZE);
         }
    +
    +    private static long remainderUnsigned(long dividend, long divisor)
    +    {
    +        if (dividend > 0L && divisor > 0L)
    +        {
    +            return dividend % divisor;
    +        }
    +        else
    +        {
    +            return new BigInteger(1, Pack.longToBigEndian(dividend)).mod(new BigInteger(1, Pack.longToBigEndian(divisor))).longValue();
    +        }
    +    }
     }
    \ No newline at end of file
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCKEMExtractor.java b/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCKEMExtractor.java
    index d7372aeb38..0de5cc5f85 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCKEMExtractor.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCKEMExtractor.java
    @@ -35,6 +35,7 @@ public byte[] extractSecret(byte[] encapsulation)
     
         public int getEncapsulationLength()
         {
    -        return key.getParameters().getN_BYTES() + key.getParameters().getN1N2_BYTES() + 64;
    +                                                                                        // Hash + salt
    +        return key.getParameters().getN_BYTES() + key.getParameters().getN1N2_BYTES() + 64 + 16;
         }
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/DigestUtil.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/DigestUtil.java
    index 43e3b16223..18948d6e71 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/DigestUtil.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/DigestUtil.java
    @@ -1,14 +1,9 @@
     package org.bouncycastle.pqc.crypto.lms;
     
    -import java.util.HashMap;
    -import java.util.Map;
    -
     import org.bouncycastle.asn1.ASN1ObjectIdentifier;
     import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
     import org.bouncycastle.crypto.Digest;
    -import org.bouncycastle.crypto.Xof;
     import org.bouncycastle.crypto.digests.SHA256Digest;
    -import org.bouncycastle.crypto.digests.SHA512Digest;
     import org.bouncycastle.crypto.digests.SHAKEDigest;
     
     /**
    @@ -16,37 +11,36 @@
      */
     class DigestUtil
     {
    -    private static Map nameToOid = new HashMap();
    -    private static Map oidToName = new HashMap();
    +    static Digest getDigest(LMOtsParameters otsParameters)
    +    {
    +        return createDigest(otsParameters.getDigestOID(), otsParameters.getN());
    +    }
     
    -    static
    +    static Digest getDigest(LMSigParameters sigParameters)
         {
    -        nameToOid.put("SHA-256", NISTObjectIdentifiers.id_sha256);
    -        nameToOid.put("SHA-512", NISTObjectIdentifiers.id_sha512);
    -        nameToOid.put("SHAKE128", NISTObjectIdentifiers.id_shake128);
    -        nameToOid.put("SHAKE256", NISTObjectIdentifiers.id_shake256);
    -
    -        oidToName.put(NISTObjectIdentifiers.id_sha256, "SHA-256");
    -        oidToName.put(NISTObjectIdentifiers.id_sha512, "SHA-512");
    -        oidToName.put(NISTObjectIdentifiers.id_shake128, "SHAKE128");
    -        oidToName.put(NISTObjectIdentifiers.id_shake256, "SHAKE256");
    +        return createDigest(sigParameters.getDigestOID(), sigParameters.getM());
         }
     
    -    static Digest getDigest(ASN1ObjectIdentifier oid)
    +    private static Digest createDigest(ASN1ObjectIdentifier oid, int length)
         {
    -        if (oid.equals(NISTObjectIdentifiers.id_sha256))
    -        {
    -            return new SHA256Digest();
    -        }
    -        if (oid.equals(NISTObjectIdentifiers.id_sha512))
    +        Digest digest = createDigest(oid);
    +
    +        if (NISTObjectIdentifiers.id_shake256_len.equals(oid) ||
    +            digest.getDigestSize() != length)
             {
    -            return new SHA512Digest();
    +            return new WrapperDigest(digest, length);
             }
    -        if (oid.equals(NISTObjectIdentifiers.id_shake128))
    +
    +        return digest;
    +    }
    +
    +    private static Digest createDigest(ASN1ObjectIdentifier oid)
    +    {
    +        if (oid.equals(NISTObjectIdentifiers.id_sha256))
             {
    -            return new SHAKEDigest(128);
    +            return new SHA256Digest();
             }
    -        if (oid.equals(NISTObjectIdentifiers.id_shake256))
    +        if (oid.equals(NISTObjectIdentifiers.id_shake256_len))
             {
                 return new SHAKEDigest(256);
             }
    @@ -54,35 +48,50 @@ static Digest getDigest(ASN1ObjectIdentifier oid)
             throw new IllegalArgumentException("unrecognized digest OID: " + oid);
         }
     
    -    static String getDigestName(ASN1ObjectIdentifier oid)
    +    static class WrapperDigest
    +        implements Digest
         {
    -        String name = oidToName.get(oid);
    -        if (name != null)
    +        private final Digest digest;
    +        private final int length;
    +
    +        WrapperDigest(Digest digest, int length)
             {
    -            return name;
    +            this.digest = digest;
    +            this.length = length;
             }
     
    -        throw new IllegalArgumentException("unrecognized digest oid: " + oid);
    -    }
    +        public String getAlgorithmName()
    +        {
    +            return digest.getAlgorithmName() + "/" + length * 8;
    +        }
     
    -    static ASN1ObjectIdentifier getDigestOID(String name)
    -    {
    -        ASN1ObjectIdentifier oid = nameToOid.get(name);
    -        if (oid != null)
    +        public int getDigestSize()
             {
    -            return oid;
    +            return length;
             }
     
    -        throw new IllegalArgumentException("unrecognized digest name: " + name);
    -    }
    +        public void update(byte in)
    +        {
    +             digest.update(in);
    +        }
     
    -    public static int getDigestSize(Digest digest)
    -    {
    -        if (digest instanceof Xof)
    +        public void update(byte[] in, int inOff, int len)
             {
    -            return digest.getDigestSize() * 2;
    +            digest.update(in, inOff, len);
             }
     
    -        return digest.getDigestSize();
    +        public int doFinal(byte[] out, int outOff)
    +        {
    +            byte[] digOut = new byte[digest.getDigestSize()];
    +            digest.doFinal(digOut, 0);
    +
    +            System.arraycopy(digOut, 0, out, outOff, length);
    +            return length;
    +        }
    +
    +        public void reset()
    +        {
    +            digest.reset();
    +        }
         }
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSS.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSS.java
    index aed2d22d7e..d131993824 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSS.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSS.java
    @@ -15,7 +15,7 @@ public static HSSPrivateKeyParameters generateHSSKeyPair(HSSKeyGenerationParamet
             LMSPrivateKeyParameters[] keys = new LMSPrivateKeyParameters[parameters.getDepth()];
             LMSSignature[] sig = new LMSSignature[parameters.getDepth() - 1];
     
    -        byte[] rootSeed = new byte[32];
    +        byte[] rootSeed = new byte[parameters.getLmsParameters()[0].getLMSigParam().getM()];
             parameters.getRandom().nextBytes(rootSeed);
     
             byte[] I = new byte[16];
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSPrivateKeyParameters.java
    index 99e4f1c3c0..19fe2ebcb1 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSPrivateKeyParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSPrivateKeyParameters.java
    @@ -290,18 +290,19 @@ void resetKeyToIndex()
             {
     
                 LMSPrivateKeyParameters intermediateKey = keys[i - 1];
    +            int n = intermediateKey.getOtsParameters().getN();
     
                 byte[] childI = new byte[16];
    -            byte[] childSeed = new byte[32];
    +            byte[] childSeed = new byte[n];
                 SeedDerive derive = new SeedDerive(
                     intermediateKey.getI(),
                     intermediateKey.getMasterSecret(),
    -                DigestUtil.getDigest(intermediateKey.getOtsParameters().getDigestOID()));
    +                DigestUtil.getDigest(intermediateKey.getOtsParameters()));
                 derive.setQ((int)qTreePath[i - 1]);
                 derive.setJ(~1);
     
                 derive.deriveSeed(childSeed, true);
    -            byte[] postImage = new byte[32];
    +            byte[] postImage = new byte[n];
                 derive.deriveSeed(postImage, false);
                 System.arraycopy(postImage, 0, childI, 0, childI.length);
     
    @@ -370,11 +371,14 @@ public synchronized HSSPublicKeyParameters getPublicKey()
         void replaceConsumedKey(int d)
         {
     
    -        SeedDerive deriver = keys.get(d - 1).getCurrentOTSKey().getDerivationFunction();
    +        LMOtsPrivateKey currentOTSKey = keys.get(d - 1).getCurrentOTSKey();
    +        int n = currentOTSKey.getParameter().getN();
    +
    +        SeedDerive deriver = currentOTSKey.getDerivationFunction();
             deriver.setJ(~1);
    -        byte[] childRootSeed = new byte[32];
    +        byte[] childRootSeed = new byte[n];
             deriver.deriveSeed(childRootSeed, true);
    -        byte[] postImage = new byte[32];
    +        byte[] postImage = new byte[n];
             deriver.deriveSeed(postImage, false);
             byte[] childI = new byte[16];
             System.arraycopy(postImage, 0, childI, 0, childI.length);
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSPublicKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSPublicKeyParameters.java
    index 8f2ece616e..bd3d479681 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSPublicKeyParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSPublicKeyParameters.java
    @@ -18,6 +18,11 @@ public HSSPublicKeyParameters(int l, LMSPublicKeyParameters lmsPublicKey)
         {
             super(false);
     
    +        if (lmsPublicKey == null)
    +        {
    +            throw new NullPointerException("lmsPublicKey");
    +        }
    +
             this.l = l;
             this.lmsPublicKey = lmsPublicKey;
         }
    @@ -114,16 +119,24 @@ public LMSContext generateLMSContext(byte[] sigEnc)
             {
                 throw new IllegalStateException("cannot parse signature: " + e.getMessage());
             }
    -
    +     
             LMSSignedPubKey[] signedPubKeys = signature.getSignedPubKey();
    -        LMSPublicKeyParameters key = signedPubKeys[signedPubKeys.length - 1].getPublicKey();
    +        LMSPublicKeyParameters key;
    +        if (signedPubKeys.length != 0)
    +        {
    +            key = signedPubKeys[signedPubKeys.length - 1].getPublicKey();
    +        }
    +        else
    +        {
    +            key = this.getLMSPublicKey();
    +        }
     
             return key.generateOtsContext(signature.getSignature()).withSignedPublicKeys(signedPubKeys);
         }
     
         public boolean verify(LMSContext context)
         {
    -        boolean failed = false;
    +        boolean passed = true;
     
             LMSSignedPubKey[] sigKeys = context.getSignedPubKeys();
     
    @@ -138,13 +151,10 @@ public boolean verify(LMSContext context)
             {
                 LMSSignature sig = sigKeys[i].getSignature();
                 byte[] msg = sigKeys[i].getPublicKey().toByteArray();
    -            if (!LMS.verifySignature(key, sig, msg))
    -            {
    -                failed = true;
    -            }
    +            passed &= LMS.verifySignature(key, sig, msg);
                 key = sigKeys[i].getPublicKey();
             }
     
    -        return !failed & key.verify(context);
    +        return passed & key.verify(context);
         }
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSSignature.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSSignature.java
    index b9bafd9df8..076be447ff 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSSignature.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSSignature.java
    @@ -4,12 +4,13 @@
     import java.io.DataInputStream;
     import java.io.IOException;
     import java.io.InputStream;
    -import java.util.Arrays;
     
    +import org.bouncycastle.util.Arrays;
     import org.bouncycastle.util.Encodable;
    +import org.bouncycastle.util.Objects;
     import org.bouncycastle.util.io.Streams;
     
    -public class HSSSignature
    +class HSSSignature
         implements Encodable
     {
         private final int lMinus1;
    @@ -106,28 +107,11 @@ public boolean equals(Object o)
                 return false;
             }
     
    -        HSSSignature signature1 = (HSSSignature)o;
    +        HSSSignature that = (HSSSignature)o;
     
    -        if (lMinus1 != signature1.lMinus1)
    -        {
    -            return false;
    -        }
    -        // Probably incorrect - comparing Object[] arrays with Arrays.equals
    -
    -        if (signedPubKey.length != signature1.signedPubKey.length)
    -        {
    -            return false;
    -        }
    -
    -        for (int t = 0; t < signedPubKey.length; t++)
    -        {
    -            if (!signedPubKey[t].equals(signature1.signedPubKey[t]))
    -            {
    -                return false;
    -            }
    -        }
    -
    -        return signature != null ? signature.equals(signature1.signature) : signature1.signature == null;
    +        return this.lMinus1 == that.lMinus1
    +            && Arrays.areEqual(this.signedPubKey, that.signedPubKey)
    +            && Objects.areEqual(this.signature, that.signature);
         }
     
         @Override
    @@ -135,7 +119,7 @@ public int hashCode()
         {
             int result = lMinus1;
             result = 31 * result + Arrays.hashCode(signedPubKey);
    -        result = 31 * result + (signature != null ? signature.hashCode() : 0);
    +        result = 31 * result + Objects.hashCode(signature);
             return result;
         }
     
    @@ -153,7 +137,5 @@ public byte[] getEncoded()
             }
             composer.bytes(signature);
             return composer.build();
    -
         }
    -
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMOtsParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMOtsParameters.java
    index ca2b39f884..9fdb6c13b0 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMOtsParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMOtsParameters.java
    @@ -9,10 +9,25 @@
     public class LMOtsParameters
     {
         public static final int reserved = 0;
    -    public static final LMOtsParameters sha256_n32_w1 = new LMOtsParameters(1, 32, 1, 265, 7, 8516, NISTObjectIdentifiers.id_sha256);
    -    public static final LMOtsParameters sha256_n32_w2 = new LMOtsParameters(2, 32, 2, 133, 6, 4292, NISTObjectIdentifiers.id_sha256);
    -    public static final LMOtsParameters sha256_n32_w4 = new LMOtsParameters(3, 32, 4, 67, 4, 2180, NISTObjectIdentifiers.id_sha256);
    -    public static final LMOtsParameters sha256_n32_w8 = new LMOtsParameters(4, 32, 8, 34, 0, 1124, NISTObjectIdentifiers.id_sha256);
    +    public static final LMOtsParameters sha256_n32_w1 = new LMOtsParameters(0x01, 32, 1, 265, 7, 8516, NISTObjectIdentifiers.id_sha256);
    +    public static final LMOtsParameters sha256_n32_w2 = new LMOtsParameters(0x02, 32, 2, 133, 6, 4292, NISTObjectIdentifiers.id_sha256);
    +    public static final LMOtsParameters sha256_n32_w4 = new LMOtsParameters(0x03, 32, 4, 67, 4, 2180, NISTObjectIdentifiers.id_sha256);
    +    public static final LMOtsParameters sha256_n32_w8 = new LMOtsParameters(0x04, 32, 8, 34, 0, 1124, NISTObjectIdentifiers.id_sha256);
    +
    +    public static final LMOtsParameters sha256_n24_w1 = new LMOtsParameters(0x05, 24, 1, 200, 8, 5436, NISTObjectIdentifiers.id_sha256);
    +    public static final LMOtsParameters sha256_n24_w2 = new LMOtsParameters(0x06, 24, 2, 101, 6, 2940, NISTObjectIdentifiers.id_sha256);
    +    public static final LMOtsParameters sha256_n24_w4 = new LMOtsParameters(0x07, 24, 4, 51, 4, 1500, NISTObjectIdentifiers.id_sha256);
    +    public static final LMOtsParameters sha256_n24_w8 = new LMOtsParameters(0x08, 24, 8, 26, 0, 1020, NISTObjectIdentifiers.id_sha256);
    +
    +    public static final LMOtsParameters shake256_n32_w1 = new LMOtsParameters(0x09, 32, 1, 265, 7, 8516, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMOtsParameters shake256_n32_w2 = new LMOtsParameters(0x0a, 32, 2, 133, 6, 4292, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMOtsParameters shake256_n32_w4 = new LMOtsParameters(0x0b, 32, 4, 67, 4, 2180, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMOtsParameters shake256_n32_w8 = new LMOtsParameters(0x0c, 32, 8, 34, 0, 1124, NISTObjectIdentifiers.id_shake256_len);
    +
    +    public static final LMOtsParameters shake256_n24_w1 = new LMOtsParameters(0x0d, 24, 1, 200, 8, 5436, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMOtsParameters shake256_n24_w2 = new LMOtsParameters(0x0e, 24, 2, 101, 6, 2940, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMOtsParameters shake256_n24_w4 = new LMOtsParameters(0x0f, 24, 4, 51, 4, 1500, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMOtsParameters shake256_n24_w8 = new LMOtsParameters(0x10, 24, 8, 26, 0, 1020, NISTObjectIdentifiers.id_shake256_len);
     
         private static final Map suppliers = new HashMap()
         {
    @@ -21,6 +36,18 @@ public class LMOtsParameters
                 put(sha256_n32_w2.type, sha256_n32_w2);
                 put(sha256_n32_w4.type, sha256_n32_w4);
                 put(sha256_n32_w8.type, sha256_n32_w8);
    +            put(sha256_n24_w1.type, sha256_n24_w1);
    +            put(sha256_n24_w2.type, sha256_n24_w2);
    +            put(sha256_n24_w4.type, sha256_n24_w4);
    +            put(sha256_n24_w8.type, sha256_n24_w8);
    +            put(shake256_n32_w1.type, shake256_n32_w1);
    +            put(shake256_n32_w2.type, shake256_n32_w2);
    +            put(shake256_n32_w4.type, shake256_n32_w4);
    +            put(shake256_n32_w8.type, shake256_n32_w8);
    +            put(shake256_n24_w1.type, shake256_n24_w1);
    +            put(shake256_n24_w2.type, shake256_n24_w2);
    +            put(shake256_n24_w4.type, shake256_n24_w4);
    +            put(shake256_n24_w8.type, shake256_n24_w8);
             }
         };
     
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMOtsPrivateKey.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMOtsPrivateKey.java
    index f324fd4293..d1986d178f 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMOtsPrivateKey.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMOtsPrivateKey.java
    @@ -3,7 +3,6 @@
     import org.bouncycastle.crypto.Digest;
     
     import static org.bouncycastle.pqc.crypto.lms.LM_OTS.D_MESG;
    -import static org.bouncycastle.pqc.crypto.lms.LM_OTS.SEED_LEN;
     import static org.bouncycastle.pqc.crypto.lms.LM_OTS.SEED_RANDOMISER_INDEX;
     
     class LMOtsPrivateKey
    @@ -13,7 +12,7 @@ class LMOtsPrivateKey
         private final int q;
         private final byte[] masterSecret;
     
    -    public LMOtsPrivateKey(LMOtsParameters parameter, byte[] i, int q, byte[] masterSecret)
    +    LMOtsPrivateKey(LMOtsParameters parameter, byte[] i, int q, byte[] masterSecret)
         {
             this.parameter = parameter;
             I = i;
    @@ -23,13 +22,13 @@ public LMOtsPrivateKey(LMOtsParameters parameter, byte[] i, int q, byte[] master
     
         LMSContext getSignatureContext(LMSigParameters sigParams, byte[][] path)
         {
    -        byte[] C = new byte[SEED_LEN];
    +        byte[] C = new byte[parameter.getN()];
     
             SeedDerive derive = getDerivationFunction();
             derive.setJ(SEED_RANDOMISER_INDEX); // This value from reference impl.
             derive.deriveSeed(C, false);
     
    -        Digest ctx = DigestUtil.getDigest(parameter.getDigestOID());
    +        Digest ctx = DigestUtil.getDigest(parameter);
     
             LmsUtils.byteArray(this.getI(), ctx);
             LmsUtils.u32str(this.getQ(), ctx);
    @@ -41,7 +40,7 @@ LMSContext getSignatureContext(LMSigParameters sigParams, byte[][] path)
     
         SeedDerive getDerivationFunction()
         {
    -        SeedDerive derive = new SeedDerive(I, masterSecret, DigestUtil.getDigest(parameter.getDigestOID()));
    +        SeedDerive derive = new SeedDerive(I, masterSecret, DigestUtil.getDigest(parameter));
             derive.setQ(q);
             return derive;
         }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMOtsPublicKey.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMOtsPublicKey.java
    index ecd180bdd7..cf7bad648e 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMOtsPublicKey.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMOtsPublicKey.java
    @@ -21,8 +21,7 @@ class LMOtsPublicKey
         private final int q;
         private final byte[] K;
     
    -
    -    public LMOtsPublicKey(LMOtsParameters parameter, byte[] i, int q, byte[] k)
    +    LMOtsPublicKey(LMOtsParameters parameter, byte[] i, int q, byte[] k)
         {
             this.parameter = parameter;
             this.I = i;
    @@ -112,9 +111,9 @@ public boolean equals(Object o)
     
         public int hashCode()
         {
    -        int result = Objects.hashCode(parameter);
    +        int result = q;
    +        result = 31 * result + Objects.hashCode(parameter);
             result = 31 * result + Arrays.hashCode(I);
    -        result = 31 * result + q;
             result = 31 * result + Arrays.hashCode(K);
             return result;
         }
    @@ -131,7 +130,7 @@ public byte[] getEncoded()
     
         LMSContext createOtsContext(LMOtsSignature signature)
         {
    -        Digest ctx = DigestUtil.getDigest(parameter.getDigestOID());
    +        Digest ctx = DigestUtil.getDigest(parameter);
     
             LmsUtils.byteArray(I, ctx);
             LmsUtils.u32str(q, ctx);
    @@ -143,7 +142,7 @@ LMSContext createOtsContext(LMOtsSignature signature)
     
         LMSContext createOtsContext(LMSSignature signature)
         {
    -        Digest ctx = DigestUtil.getDigest(parameter.getDigestOID());
    +        Digest ctx = DigestUtil.getDigest(parameter);
     
             LmsUtils.byteArray(I, ctx);
             LmsUtils.u32str(q, ctx);
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMS.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMS.java
    index d0845187cc..45e11bd68b 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMS.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMS.java
    @@ -101,7 +101,7 @@ public static boolean verifySignature(LMSPublicKeyParameters publicKey, LMSConte
     
             // tmp = H(I || u32str(node_num) || u16str(D_LEAF) || Kc)
             byte[] I = publicKey.getI();
    -        Digest H = DigestUtil.getDigest(lmsParameter.getDigestOID());
    +        Digest H = DigestUtil.getDigest(lmsParameter);
             byte[] tmp = new byte[H.getDigestSize()];
     
             H.update(I, 0, I.length);
    @@ -135,6 +135,12 @@ public static boolean verifySignature(LMSPublicKeyParameters publicKey, LMSConte
                 }
                 node_num = node_num / 2;
                 i++;
    +            // these two can get out of sync with an invalid signature, we'll
    +            // try and fail gracefully
    +            if (i == path.length && node_num > 1)
    +            {
    +                return false;
    +            }
             }
             byte[] Tc = tmp;
             return publicKey.matchesT1(Tc);
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSContext.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSContext.java
    index 33cc6ba2c0..7fcfffa41e 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSContext.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSContext.java
    @@ -17,7 +17,7 @@ public class LMSContext
         private LMSSignedPubKey[] signedPubKeys;
         private volatile Digest digest;
     
    -    public LMSContext(LMOtsPrivateKey key, LMSigParameters sigParams, Digest digest, byte[] C, byte[][] path)
    +    LMSContext(LMOtsPrivateKey key, LMSigParameters sigParams, Digest digest, byte[] C, byte[][] path)
         {
             this.key = key;
             this.sigParams = sigParams;
    @@ -28,7 +28,7 @@ public LMSContext(LMOtsPrivateKey key, LMSigParameters sigParams, Digest digest,
             this.signature = null;
         }
     
    -    public LMSContext(LMOtsPublicKey publicKey, Object signature, Digest digest)
    +    LMSContext(LMOtsPublicKey publicKey, Object signature, Digest digest)
         {
             this.publicKey = publicKey;
             this.signature = signature;
    @@ -65,7 +65,7 @@ LMOtsPrivateKey getPrivateKey()
             return key;
         }
     
    -    public LMOtsPublicKey getPublicKey()
    +    LMOtsPublicKey getPublicKey()
         {
             return publicKey;
         }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSException.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSException.java
    index 7294e09aad..4a7f17761d 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSException.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSException.java
    @@ -1,6 +1,6 @@
     package org.bouncycastle.pqc.crypto.lms;
     
    -public class LMSException extends Exception
    +class LMSException extends Exception
     {
         public LMSException()
         {
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSKeyPairGenerator.java
    index 793cbf6b5a..e03f781063 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSKeyPairGenerator.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSKeyPairGenerator.java
    @@ -23,10 +23,11 @@ public AsymmetricCipherKeyPair generateKeyPair()
             byte[] I = new byte[16];
             source.nextBytes(I);
     
    -        byte[] rootSecret = new byte[32];
    +        LMSigParameters sigParameter = param.getParameters().getLMSigParam();
    +        byte[] rootSecret = new byte[sigParameter.getM()];
             source.nextBytes(rootSecret);
     
    -        LMSPrivateKeyParameters privKey = LMS.generateKeys(param.getParameters().getLMSigParam(), param.getParameters().getLMOTSParam(), 0, I, rootSecret);
    +        LMSPrivateKeyParameters privKey = LMS.generateKeys(sigParameter, param.getParameters().getLMOTSParam(), 0, I, rootSecret);
     
             return new AsymmetricCipherKeyPair(privKey.getPublicKey(), privKey);
         }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSPrivateKeyParameters.java
    index 1a134cb876..a90a4ed8f8 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSPrivateKeyParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSPrivateKeyParameters.java
    @@ -57,7 +57,7 @@ public LMSPrivateKeyParameters(LMSigParameters lmsParameter, LMOtsParameters ots
             this.masterSecret = Arrays.clone(masterSecret);
             this.maxCacheR = 1 << (parameters.getH() + 1);
             this.tCache = new WeakHashMap();
    -        this.tDigest = DigestUtil.getDigest(lmsParameter.getDigestOID());
    +        this.tDigest = DigestUtil.getDigest(lmsParameter);
         }
     
         private LMSPrivateKeyParameters(LMSPrivateKeyParameters parent, int q, int maxQ)
    @@ -71,7 +71,7 @@ private LMSPrivateKeyParameters(LMSPrivateKeyParameters parent, int q, int maxQ)
             this.masterSecret = parent.masterSecret;
             this.maxCacheR = 1 << parameters.getH();
             this.tCache = parent.tCache;
    -        this.tDigest = DigestUtil.getDigest(parameters.getDigestOID());
    +        this.tDigest = DigestUtil.getDigest(parameters);
             this.publicKey = parent.publicKey;
         }
     
    @@ -286,7 +286,7 @@ public byte[] getMasterSecret()
     
         public long getUsagesRemaining()
         {
    -        return maxQ - q;
    +        return maxQ - getIndex();
         }
     
         public LMSPublicKeyParameters getPublicKey()
    @@ -409,15 +409,6 @@ public boolean equals(Object o)
                 return false;
             }
     
    -        //
    -        // Only compare public keys if they both exist.
    -        // Otherwise we would trigger the creation of one or both of them
    -        //
    -        if (publicKey != null && that.publicKey != null)
    -        {
    -            return publicKey.equals(that.publicKey);
    -        }
    -
             return true;
         }
     
    @@ -430,7 +421,6 @@ public int hashCode()
             result = 31 * result + (otsParameters != null ? otsParameters.hashCode() : 0);
             result = 31 * result + maxQ;
             result = 31 * result + Arrays.hashCode(masterSecret);
    -        result = 31 * result + (publicKey != null ? publicKey.hashCode() : 0);
             return result;
         }
     
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSigParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSigParameters.java
    index 597592c467..9f4311b86a 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSigParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSigParameters.java
    @@ -8,11 +8,29 @@
     
     public class LMSigParameters
     {
    -    public static final LMSigParameters lms_sha256_n32_h5 = new LMSigParameters(5, 32, 5, NISTObjectIdentifiers.id_sha256);
    -    public static final LMSigParameters lms_sha256_n32_h10 = new LMSigParameters(6, 32, 10, NISTObjectIdentifiers.id_sha256);
    -    public static final LMSigParameters lms_sha256_n32_h15 = new LMSigParameters(7, 32, 15, NISTObjectIdentifiers.id_sha256);
    -    public static final LMSigParameters lms_sha256_n32_h20 = new LMSigParameters(8, 32, 20, NISTObjectIdentifiers.id_sha256);
    -    public static final LMSigParameters lms_sha256_n32_h25 = new LMSigParameters(9, 32, 25, NISTObjectIdentifiers.id_sha256);
    +    public static final LMSigParameters lms_sha256_n32_h5 = new LMSigParameters(0x05, 32, 5, NISTObjectIdentifiers.id_sha256);
    +    public static final LMSigParameters lms_sha256_n32_h10 = new LMSigParameters(0x06, 32, 10, NISTObjectIdentifiers.id_sha256);
    +    public static final LMSigParameters lms_sha256_n32_h15 = new LMSigParameters(0x07, 32, 15, NISTObjectIdentifiers.id_sha256);
    +    public static final LMSigParameters lms_sha256_n32_h20 = new LMSigParameters(0x08, 32, 20, NISTObjectIdentifiers.id_sha256);
    +    public static final LMSigParameters lms_sha256_n32_h25 = new LMSigParameters(0x09, 32, 25, NISTObjectIdentifiers.id_sha256);
    +
    +    public static final LMSigParameters lms_sha256_n24_h5 = new LMSigParameters(0x0a, 24, 5, NISTObjectIdentifiers.id_sha256);
    +    public static final LMSigParameters lms_sha256_n24_h10 = new LMSigParameters(0x0b, 24, 10, NISTObjectIdentifiers.id_sha256);
    +    public static final LMSigParameters lms_sha256_n24_h15 = new LMSigParameters(0x0c, 24, 15, NISTObjectIdentifiers.id_sha256);
    +    public static final LMSigParameters lms_sha256_n24_h20 = new LMSigParameters(0x0d, 24, 20, NISTObjectIdentifiers.id_sha256);
    +    public static final LMSigParameters lms_sha256_n24_h25 = new LMSigParameters(0x0e, 24, 25, NISTObjectIdentifiers.id_sha256);
    +
    +    public static final LMSigParameters lms_shake256_n32_h5 = new LMSigParameters(0x0f, 32, 5, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMSigParameters lms_shake256_n32_h10 = new LMSigParameters(0x10, 32, 10, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMSigParameters lms_shake256_n32_h15 = new LMSigParameters(0x11, 32, 15, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMSigParameters lms_shake256_n32_h20 = new LMSigParameters(0x12, 32, 20, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMSigParameters lms_shake256_n32_h25 = new LMSigParameters(0x13, 32, 25, NISTObjectIdentifiers.id_shake256_len);
    +
    +    public static final LMSigParameters lms_shake256_n24_h5 = new LMSigParameters(0x14, 24, 5, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMSigParameters lms_shake256_n24_h10 = new LMSigParameters(0x15, 24, 10, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMSigParameters lms_shake256_n24_h15 = new LMSigParameters(0x16, 24, 15, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMSigParameters lms_shake256_n24_h20 = new LMSigParameters(0x17, 24, 20, NISTObjectIdentifiers.id_shake256_len);
    +    public static final LMSigParameters lms_shake256_n24_h25 = new LMSigParameters(0x18, 24, 25, NISTObjectIdentifiers.id_shake256_len);
     
         private static Map paramBuilders = new HashMap()
         {
    @@ -22,6 +40,24 @@ public class LMSigParameters
                 put(lms_sha256_n32_h15.type, lms_sha256_n32_h15);
                 put(lms_sha256_n32_h20.type, lms_sha256_n32_h20);
                 put(lms_sha256_n32_h25.type, lms_sha256_n32_h25);
    +
    +            put(lms_sha256_n24_h5.type, lms_sha256_n24_h5);
    +            put(lms_sha256_n24_h10.type, lms_sha256_n24_h10);
    +            put(lms_sha256_n24_h15.type, lms_sha256_n24_h15);
    +            put(lms_sha256_n24_h20.type, lms_sha256_n24_h20);
    +            put(lms_sha256_n24_h25.type, lms_sha256_n24_h25);
    +
    +            put(lms_shake256_n32_h5.type, lms_shake256_n32_h5);
    +            put(lms_shake256_n32_h10.type, lms_shake256_n32_h10);
    +            put(lms_shake256_n32_h15.type, lms_shake256_n32_h15);
    +            put(lms_shake256_n32_h20.type, lms_shake256_n32_h20);
    +            put(lms_shake256_n32_h25.type, lms_shake256_n32_h25);
    +
    +            put(lms_shake256_n24_h5.type, lms_shake256_n24_h5);
    +            put(lms_shake256_n24_h10.type, lms_shake256_n24_h10);
    +            put(lms_shake256_n24_h15.type, lms_shake256_n24_h15);
    +            put(lms_shake256_n24_h20.type, lms_shake256_n24_h20);
    +            put(lms_shake256_n24_h25.type, lms_shake256_n24_h25);
             }
         };
     
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LM_OTS.java b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LM_OTS.java
    index 0b0d5168b0..a1d4e5ad55 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LM_OTS.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/lms/LM_OTS.java
    @@ -12,7 +12,6 @@ class LM_OTS
         private static final int ITER_PREV = 23;
         private static final int ITER_J = 22;
         static final int SEED_RANDOMISER_INDEX = ~2;
    -    static final int SEED_LEN = 32;
         static final int MAX_HASH = 32;
     
         static final short D_MESG = (short)0x8181;
    @@ -54,12 +53,10 @@ public static LMOtsPublicKey lms_ots_generatePublicKey(LMOtsPrivateKey privateKe
     
         static byte[] lms_ots_generatePublicKey(LMOtsParameters parameter, byte[] I, int q, byte[] masterSecret)
         {
    -
    -
             //
             // Start hash that computes the final value.
             //
    -        Digest publicContext = DigestUtil.getDigest(parameter.getDigestOID());
    +        Digest publicContext = DigestUtil.getDigest(parameter);
             byte[] prehashPrefix = Composer.compose()
                 .bytes(I)
                 .u32str(q)
    @@ -68,7 +65,7 @@ static byte[] lms_ots_generatePublicKey(LMOtsParameters parameter, byte[] I, int
                 .build();
             publicContext.update(prehashPrefix, 0, prehashPrefix.length);
     
    -        Digest ctx = DigestUtil.getDigest(parameter.getDigestOID());
    +        Digest ctx = DigestUtil.getDigest(parameter);
     
             byte[] buf = Composer.compose()
                 .bytes(I)
    @@ -77,7 +74,7 @@ static byte[] lms_ots_generatePublicKey(LMOtsParameters parameter, byte[] I, int
                 .build();
     
     
    -        SeedDerive derive = new SeedDerive(I, masterSecret, DigestUtil.getDigest(parameter.getDigestOID()));
    +        SeedDerive derive = new SeedDerive(I, masterSecret, DigestUtil.getDigest(parameter));
             derive.setQ(q);
             derive.setJ(0);
     
    @@ -126,8 +123,10 @@ public static LMOtsSignature lm_ots_generate_signature(LMSigParameters sigParams
             }
             else
             {
    -            C = new byte[SEED_LEN];
    -            System.arraycopy(message, 0, Q, 0, privateKey.getParameter().getN());
    +            int n = privateKey.getParameter().getN();
    +            
    +            C = new byte[n];
    +            System.arraycopy(message, 0, Q, 0, n);
             }
     
             return lm_ots_generate_signature(privateKey, Q, C);
    @@ -143,7 +142,7 @@ public static LMOtsSignature lm_ots_generate_signature(LMOtsPrivateKey privateKe
     
             byte[] sigComposer = new byte[p * n];
     
    -        Digest ctx = DigestUtil.getDigest(parameter.getDigestOID());
    +        Digest ctx = DigestUtil.getDigest(parameter);
     
             SeedDerive derive = privateKey.getDerivationFunction();
     
    @@ -217,7 +216,7 @@ public static byte[] lm_ots_validate_signature_calculate(LMSContext context)
             byte[] I = publicKey.getI();
             int    q = publicKey.getQ();
     
    -        Digest finalContext = DigestUtil.getDigest(parameter.getDigestOID());
    +        Digest finalContext = DigestUtil.getDigest(parameter);
             LmsUtils.byteArray(I, finalContext);
             LmsUtils.u32str(q, finalContext);
             LmsUtils.u16str(D_PBLC, finalContext);
    @@ -231,7 +230,7 @@ public static byte[] lm_ots_validate_signature_calculate(LMSContext context)
     
             byte[] y = signature.getY();
     
    -        Digest ctx = DigestUtil.getDigest(parameter.getDigestOID());
    +        Digest ctx = DigestUtil.getDigest(parameter);
             for (int i = 0; i < p; i++)
             {
                 Pack.shortToBigEndian((short)i, tmp, ITER_K);
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/HashMLDSASigner.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/HashMLDSASigner.java
    new file mode 100644
    index 0000000000..2923d26e73
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/HashMLDSASigner.java
    @@ -0,0 +1,165 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +import java.io.IOException;
    +import java.security.SecureRandom;
    +
    +import org.bouncycastle.asn1.ASN1Encoding;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.crypto.CipherParameters;
    +import org.bouncycastle.crypto.CryptoException;
    +import org.bouncycastle.crypto.DataLengthException;
    +import org.bouncycastle.crypto.Digest;
    +import org.bouncycastle.crypto.Signer;
    +import org.bouncycastle.crypto.digests.SHA512Digest;
    +import org.bouncycastle.crypto.params.ParametersWithRandom;
    +import org.bouncycastle.pqc.crypto.DigestUtils;
    +
    +public class HashMLDSASigner
    +    implements Signer
    +{
    +    private MLDSAPrivateKeyParameters privKey;
    +    private MLDSAPublicKeyParameters pubKey;
    +
    +    private SecureRandom random;
    +    private Digest digest;
    +    private byte[] digestOidEncoding;
    +
    +    public HashMLDSASigner()
    +    {
    +        this.digest = new SHA512Digest();
    +    }
    +
    +    public void init(boolean forSigning, CipherParameters param)
    +    {
    +        if (forSigning)
    +        {
    +            if (param instanceof ParametersWithRandom)
    +            {
    +                privKey = (MLDSAPrivateKeyParameters)((ParametersWithRandom)param).getParameters();
    +                random = ((ParametersWithRandom)param).getRandom();
    +            }
    +            else
    +            {
    +                privKey = (MLDSAPrivateKeyParameters)param;
    +                random = null;
    +            }
    +
    +            initDigest(privKey);
    +        }
    +        else
    +        {
    +            pubKey = (MLDSAPublicKeyParameters)param;
    +
    +            initDigest(pubKey);
    +        }
    +
    +        reset();
    +    }
    +
    +    private void initDigest(MLDSAKeyParameters key)
    +    {
    +        if (key.getParameters().isPreHash())
    +        {
    +            digest = key.getParameters().createDigest();
    +        }
    +
    +        ASN1ObjectIdentifier oid = DigestUtils.getDigestOid(digest.getAlgorithmName());
    +        try
    +        {
    +            digestOidEncoding = oid.getEncoded(ASN1Encoding.DER);
    +        }
    +        catch (IOException e)
    +        {
    +            throw new IllegalStateException("oid encoding failed: " + e.getMessage());
    +        }
    +    }
    +
    +    public void update(byte b)
    +    {
    +        digest.update(b);
    +    }
    +
    +    @Override
    +    public void update(byte[] in, int off, int len)
    +    {
    +        digest.update(in, off, len);
    +    }
    +
    +    @Override
    +    public byte[] generateSignature() throws CryptoException, DataLengthException
    +    {
    +        MLDSAEngine engine = privKey.getParameters().getEngine(random);
    +
    +        byte[] ctx = privKey.getContext();
    +        if (ctx.length > 255)
    +        {
    +            throw new RuntimeException("Context too long");
    +        }
    +
    +        byte[] rnd = new byte[MLDSAEngine.RndBytes];
    +        if (random != null)
    +        {
    +            random.nextBytes(rnd);
    +        }
    +
    +        byte[] hash = new byte[digest.getDigestSize()];
    +        digest.doFinal(hash, 0);
    +
    +        byte[] ds_message = new byte[1 + 1 + ctx.length + + digestOidEncoding.length + hash.length];
    +        ds_message[0] = 1;
    +        ds_message[1] = (byte)ctx.length;
    +        System.arraycopy(ctx, 0, ds_message, 2, ctx.length);
    +        System.arraycopy(digestOidEncoding, 0, ds_message, 2 + ctx.length, digestOidEncoding.length);
    +        System.arraycopy(hash, 0, ds_message, 2 + ctx.length + digestOidEncoding.length, hash.length);
    +
    +        return engine.signInternal(ds_message, ds_message.length, privKey.rho, privKey.k, privKey.tr, privKey.t0, privKey.s1, privKey.s2, rnd);
    +    }
    +
    +    @Override
    +    public boolean verifySignature(byte[] signature)
    +    {
    +        MLDSAEngine engine = pubKey.getParameters().getEngine(random);
    +
    +        byte[] ctx = pubKey.getContext();
    +        if (ctx.length > 255)
    +        {
    +            throw new RuntimeException("Context too long");
    +        }
    +
    +        byte[] hash = new byte[digest.getDigestSize()];
    +        digest.doFinal(hash, 0);
    +
    +        byte[] ds_message = new byte[1 + 1 + ctx.length + + digestOidEncoding.length + hash.length];
    +        ds_message[0] = 1;
    +        ds_message[1] = (byte)ctx.length;
    +        System.arraycopy(ctx, 0, ds_message, 2, ctx.length);
    +        System.arraycopy(digestOidEncoding, 0, ds_message, 2 + ctx.length, digestOidEncoding.length);
    +        System.arraycopy(hash, 0, ds_message, 2 + ctx.length + digestOidEncoding.length, hash.length);
    +
    +        return engine.verifyInternal(signature, signature.length, ds_message, ds_message.length, pubKey.rho, pubKey.t1);
    +    }
    +
    +    /**
    +     * reset the internal state
    +     */
    +    @Override
    +    public void reset()
    +    {
    +        digest.reset();
    +    }
    +
    +
    +    public byte[] internalGenerateSignature(byte[] message, byte[] random)
    +    {
    +        MLDSAEngine engine = privKey.getParameters().getEngine(this.random);
    +
    +        return engine.signInternal(message, message.length, privKey.rho, privKey.k, privKey.tr, privKey.t0, privKey.s1, privKey.s2, random);
    +    }
    +
    +    public boolean internalVerifySignature(byte[] message, byte[] signature)
    +    {
    +        MLDSAEngine engine = pubKey.getParameters().getEngine(random);
    +
    +        return engine.verifyInternal(signature, signature.length, message, message.length, pubKey.rho, pubKey.t1);
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAEngine.java
    new file mode 100644
    index 0000000000..1446e2c3f7
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAEngine.java
    @@ -0,0 +1,538 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +import java.security.SecureRandom;
    +
    +import org.bouncycastle.crypto.digests.SHAKEDigest;
    +import org.bouncycastle.util.Arrays;
    +
    +class MLDSAEngine
    +{
    +    private final SecureRandom random;
    +
    +    private final SHAKEDigest shake128Digest = new SHAKEDigest(128);
    +    private final SHAKEDigest shake256Digest = new SHAKEDigest(256);
    +
    +    public final static int DilithiumN = 256;
    +    public final static int DilithiumQ = 8380417;
    +    public final static int DilithiumQinv = 58728449; // q^(-1) mod 2^32
    +    public final static int DilithiumD = 13;
    +    public final static int DilithiumRootOfUnity = 1753;
    +    public final static int SeedBytes = 32;
    +    public final static int CrhBytes = 64;
    +    public final static int RndBytes = 32;
    +    public final static int TrBytes = 64;
    +
    +    public final static int DilithiumPolyT1PackedBytes = 320;
    +    public final static int DilithiumPolyT0PackedBytes = 416;
    +
    +    private final int DilithiumPolyVecHPackedBytes;
    +
    +    private final int DilithiumPolyZPackedBytes;
    +    private final int DilithiumPolyW1PackedBytes;
    +    private final int DilithiumPolyEtaPackedBytes;
    +
    +    private final int DilithiumMode;
    +
    +    private final int DilithiumK;
    +    private final int DilithiumL;
    +    private final int DilithiumEta;
    +    private final int DilithiumTau;
    +    private final int DilithiumBeta;
    +    private final int DilithiumGamma1;
    +    private final int DilithiumGamma2;
    +    private final int DilithiumOmega;
    +    private final int DilithiumCTilde;
    +
    +    private final int CryptoPublicKeyBytes;
    +    private final int CryptoSecretKeyBytes;
    +    private final int CryptoBytes;
    +
    +    private final int PolyUniformGamma1NBlocks;
    +
    +    private final Symmetric symmetric;;
    +
    +    protected Symmetric GetSymmetric()
    +    {
    +        return symmetric;
    +    }
    +
    +    int getDilithiumPolyVecHPackedBytes()
    +    {
    +        return DilithiumPolyVecHPackedBytes;
    +    }
    +
    +    int getDilithiumPolyZPackedBytes()
    +    {
    +        return DilithiumPolyZPackedBytes;
    +    }
    +
    +    int getDilithiumPolyW1PackedBytes()
    +    {
    +        return DilithiumPolyW1PackedBytes;
    +    }
    +
    +    int getDilithiumPolyEtaPackedBytes()
    +    {
    +        return DilithiumPolyEtaPackedBytes;
    +    }
    +
    +    int getDilithiumMode()
    +    {
    +        return DilithiumMode;
    +    }
    +
    +    int getDilithiumK()
    +    {
    +        return DilithiumK;
    +    }
    +
    +    int getDilithiumL()
    +    {
    +        return DilithiumL;
    +    }
    +
    +    int getDilithiumEta()
    +    {
    +        return DilithiumEta;
    +    }
    +
    +    int getDilithiumTau()
    +    {
    +        return DilithiumTau;
    +    }
    +
    +    int getDilithiumBeta()
    +    {
    +        return DilithiumBeta;
    +    }
    +
    +    int getDilithiumGamma1()
    +    {
    +        return DilithiumGamma1;
    +    }
    +
    +    int getDilithiumGamma2()
    +    {
    +        return DilithiumGamma2;
    +    }
    +
    +    int getDilithiumOmega()
    +    {
    +        return DilithiumOmega;
    +    }
    +    
    +    int getDilithiumCTilde()
    +    {
    +        return DilithiumCTilde;
    +    }
    +
    +    int getCryptoPublicKeyBytes()
    +    {
    +        return CryptoPublicKeyBytes;
    +    }
    +
    +    int getCryptoSecretKeyBytes()
    +    {
    +        return CryptoSecretKeyBytes;
    +    }
    +
    +    int getCryptoBytes()
    +    {
    +        return CryptoBytes;
    +    }
    +
    +    int getPolyUniformGamma1NBlocks()
    +    {
    +        return this.PolyUniformGamma1NBlocks;
    +    }
    +
    +    SHAKEDigest getShake256Digest()
    +    {
    +        return this.shake256Digest;
    +    }
    +
    +    SHAKEDigest getShake128Digest()
    +    {
    +        return this.shake128Digest;
    +    }
    +
    +    MLDSAEngine(int mode, SecureRandom random)
    +    {
    +        this.DilithiumMode = mode;
    +        switch (mode)
    +        {
    +        case 2:
    +            this.DilithiumK = 4;
    +            this.DilithiumL = 4;
    +            this.DilithiumEta = 2;
    +            this.DilithiumTau = 39;
    +            this.DilithiumBeta = 78;
    +            this.DilithiumGamma1 = (1 << 17);
    +            this.DilithiumGamma2 = ((DilithiumQ - 1) / 88);
    +            this.DilithiumOmega = 80;
    +            this.DilithiumPolyZPackedBytes = 576;
    +            this.DilithiumPolyW1PackedBytes = 192;
    +            this.DilithiumPolyEtaPackedBytes = 96;
    +            this.DilithiumCTilde = 32;
    +            break;
    +        case 3:
    +            this.DilithiumK = 6;
    +            this.DilithiumL = 5;
    +            this.DilithiumEta = 4;
    +            this.DilithiumTau = 49;
    +            this.DilithiumBeta = 196;
    +            this.DilithiumGamma1 = (1 << 19);
    +            this.DilithiumGamma2 = ((DilithiumQ - 1) / 32);
    +            this.DilithiumOmega = 55;
    +            this.DilithiumPolyZPackedBytes = 640;
    +            this.DilithiumPolyW1PackedBytes = 128;
    +            this.DilithiumPolyEtaPackedBytes = 128;
    +            this.DilithiumCTilde = 48;
    +            break;
    +        case 5:
    +            this.DilithiumK = 8;
    +            this.DilithiumL = 7;
    +            this.DilithiumEta = 2;
    +            this.DilithiumTau = 60;
    +            this.DilithiumBeta = 120;
    +            this.DilithiumGamma1 = (1 << 19);
    +            this.DilithiumGamma2 = ((DilithiumQ - 1) / 32);
    +            this.DilithiumOmega = 75;
    +            this.DilithiumPolyZPackedBytes = 640;
    +            this.DilithiumPolyW1PackedBytes = 128;
    +            this.DilithiumPolyEtaPackedBytes = 96;
    +            this.DilithiumCTilde = 64;
    +            break;
    +        default:
    +            throw new IllegalArgumentException("The mode " + mode + "is not supported by Crystals Dilithium!");
    +        }
    +        
    +        this.symmetric = new Symmetric.ShakeSymmetric();
    +
    +        this.random = random;
    +        this.DilithiumPolyVecHPackedBytes = this.DilithiumOmega + this.DilithiumK;
    +        this.CryptoPublicKeyBytes = SeedBytes + this.DilithiumK * DilithiumPolyT1PackedBytes;
    +        this.CryptoSecretKeyBytes =
    +            (
    +                2 * SeedBytes
    +                    + TrBytes
    +                    + DilithiumL * this.DilithiumPolyEtaPackedBytes
    +                    + DilithiumK * this.DilithiumPolyEtaPackedBytes
    +                    + DilithiumK * DilithiumPolyT0PackedBytes
    +            );
    +        this.CryptoBytes = DilithiumCTilde + DilithiumL * this.DilithiumPolyZPackedBytes + this.DilithiumPolyVecHPackedBytes;
    +
    +        if (this.DilithiumGamma1 == (1 << 17))
    +        {
    +            this.PolyUniformGamma1NBlocks = ((576 + symmetric.stream256BlockBytes - 1) / symmetric.stream256BlockBytes);
    +        }
    +        else if (this.DilithiumGamma1 == (1 << 19))
    +        {
    +            this.PolyUniformGamma1NBlocks = ((640 + symmetric.stream256BlockBytes - 1) / symmetric.stream256BlockBytes);
    +        }
    +        else
    +        {
    +            throw new RuntimeException("Wrong Dilithium Gamma1!");
    +        }
    +    }
    +
    +    //Internal functions are deterministic. No randomness is sampled inside them
    +    public byte[][] generateKeyPairInternal(byte[] seed)
    +    {
    +        byte[] buf = new byte[2 * SeedBytes + CrhBytes];
    +        byte[] tr = new byte[TrBytes];
    +
    +        byte[] rho = new byte[SeedBytes],
    +                rhoPrime = new byte[CrhBytes],
    +                key = new byte[SeedBytes];
    +
    +        PolyVecMatrix aMatrix = new PolyVecMatrix(this);
    +
    +        PolyVecL s1 = new PolyVecL(this), s1hat;
    +        PolyVecK s2 = new PolyVecK(this), t1 = new PolyVecK(this), t0 = new PolyVecK(this);
    +
    +
    +
    +        shake256Digest.update(seed, 0, SeedBytes);
    +
    +        //Domain separation
    +        shake256Digest.update((byte)DilithiumK);
    +        shake256Digest.update((byte)DilithiumL);
    +
    +        shake256Digest.doFinal(buf, 0, 2 * SeedBytes + CrhBytes);
    +        // System.out.print("buf = ");
    +        // Helper.printByteArray(buf);
    +
    +        System.arraycopy(buf, 0, rho, 0, SeedBytes);
    +        System.arraycopy(buf, SeedBytes, rhoPrime, 0, CrhBytes);
    +        System.arraycopy(buf, SeedBytes + CrhBytes, key, 0, SeedBytes);
    +        // System.out.println("key = ");
    +        // Helper.printByteArray(key);
    +
    +        aMatrix.expandMatrix(rho);
    +        // System.out.print(aMatrix.toString("aMatrix"));
    +
    +        // System.out.println("rhoPrime = ");
    +        // Helper.printByteArray(rhoPrime);
    +        s1.uniformEta(rhoPrime, (short)0);
    +        // System.out.println(s1.toString("s1"));
    +
    +        s2.uniformEta(rhoPrime, (short)DilithiumL);
    +
    +        s1hat = new PolyVecL(this);
    +
    +        s1.copyPolyVecL(s1hat);
    +        s1hat.polyVecNtt();
    +
    +        // System.out.println(s1hat.toString("s1hat"));
    +
    +        aMatrix.pointwiseMontgomery(t1, s1hat);
    +        // System.out.println(t1.toString("t1"));
    +
    +        t1.reduce();
    +        t1.invNttToMont();
    +
    +        t1.addPolyVecK(s2);
    +        // System.out.println(s2.toString("s2"));
    +        // System.out.println(t1.toString("t1"));
    +        t1.conditionalAddQ();
    +        t1.power2Round(t0);
    +
    +        // System.out.println(t1.toString("t1"));
    +        // System.out.println(t0.toString("t0"));
    +
    +
    +        byte[] encT1 = Packing.packPublicKey(t1, this);
    +        // System.out.println("pk engine = ");
    +        // Helper.printByteArray(pk);
    +
    +        shake256Digest.update(rho, 0, rho.length);
    +        shake256Digest.update(encT1, 0, encT1.length);
    +        shake256Digest.doFinal(tr, 0, TrBytes);
    +
    +        byte[][] sk = Packing.packSecretKey(rho, tr, key, t0, s1, s2, this);
    +
    +        return new byte[][]{ sk[0], sk[1], sk[2], sk[3], sk[4], sk[5], encT1};
    +    }
    +
    +    public byte[] signInternal(byte[] msg, int msglen, byte[] rho, byte[] key, byte[] tr, byte[] t0Enc, byte[] s1Enc, byte[] s2Enc, byte[] rnd)
    +    {
    +        int n;
    +        byte[] outSig = new byte[CryptoBytes + msglen];
    +        byte[] mu = new byte[CrhBytes], rhoPrime = new byte[CrhBytes];
    +        short nonce = 0;
    +        PolyVecL s1 = new PolyVecL(this), y = new PolyVecL(this), z = new PolyVecL(this);
    +        PolyVecK t0 = new PolyVecK(this), s2 = new PolyVecK(this), w1 = new PolyVecK(this), w0 = new PolyVecK(this), h = new PolyVecK(this);
    +        Poly cp = new Poly(this);
    +        PolyVecMatrix aMatrix = new PolyVecMatrix(this);
    +
    +        Packing.unpackSecretKey(t0, s1, s2, t0Enc, s1Enc, s2Enc, this);
    +
    +        this.shake256Digest.update(tr, 0, TrBytes);
    +        this.shake256Digest.update(msg, 0, msglen);
    +        this.shake256Digest.doFinal(mu, 0, CrhBytes);
    +
    +
    +
    +        byte[] keyMu = Arrays.copyOf(key, SeedBytes + RndBytes + CrhBytes);
    +        System.arraycopy(rnd, 0, keyMu, SeedBytes, RndBytes);
    +        System.arraycopy(mu, 0, keyMu, SeedBytes + RndBytes, CrhBytes);
    +        shake256Digest.update(keyMu, 0, SeedBytes + RndBytes + CrhBytes);
    +        shake256Digest.doFinal(rhoPrime, 0, CrhBytes);
    +
    +        aMatrix.expandMatrix(rho);
    +
    +        s1.polyVecNtt();
    +        s2.polyVecNtt();
    +
    +        t0.polyVecNtt();
    +
    +        int count = 0;
    +        while (count < 1000)
    +        {
    +            count++;
    +            // Sample intermediate vector
    +            y.uniformGamma1(rhoPrime, nonce++);
    +
    +            y.copyPolyVecL(z);
    +            z.polyVecNtt();
    +
    +            // Matrix-vector multiplication
    +            aMatrix.pointwiseMontgomery(w1, z);
    +            w1.reduce();
    +            w1.invNttToMont();
    +
    +            // Decompose w and call the random oracle
    +            w1.conditionalAddQ();
    +            w1.decompose(w0);
    +
    +            System.arraycopy(w1.packW1(), 0, outSig, 0, DilithiumK * DilithiumPolyW1PackedBytes);
    +
    +            shake256Digest.update(mu, 0, CrhBytes);
    +            shake256Digest.update(outSig, 0, DilithiumK * DilithiumPolyW1PackedBytes);
    +            shake256Digest.doFinal(outSig, 0, DilithiumCTilde);
    +
    +            cp.challenge(Arrays.copyOfRange(outSig, 0, DilithiumCTilde));  // uses only the first DilithiumCTilde bytes of sig
    +            cp.polyNtt();
    +
    +            // Compute z, reject if it reveals secret
    +            z.pointwisePolyMontgomery(cp, s1);
    +            z.invNttToMont();
    +            z.addPolyVecL(y);
    +            z.reduce();
    +            if (z.checkNorm(DilithiumGamma1 - DilithiumBeta))
    +            {
    +                continue;
    +            }
    +
    +            h.pointwisePolyMontgomery(cp, s2);
    +            h.invNttToMont();
    +            w0.subtract(h);
    +            w0.reduce();
    +            if (w0.checkNorm(DilithiumGamma2 - DilithiumBeta))
    +            {
    +                continue;
    +            }
    +
    +            h.pointwisePolyMontgomery(cp, t0);
    +            h.invNttToMont();
    +            h.reduce();
    +            if (h.checkNorm(DilithiumGamma2))
    +            {
    +                continue;
    +            }
    +
    +            w0.addPolyVecK(h);
    +            w0.conditionalAddQ();
    +            n = h.makeHint(w0, w1);
    +            if (n > DilithiumOmega)
    +            {
    +                continue;
    +            }
    +
    +            return Packing.packSignature(outSig, z, h, this);
    +        }
    +
    +        return null;
    +    }
    +
    +    public boolean verifyInternal(byte[] sig, int siglen, byte[] msg, int msglen, byte[] rho, byte[] encT1)
    +    {
    +        byte[] buf,
    +                mu = new byte[CrhBytes],
    +                c,
    +                c2 = new byte[DilithiumCTilde];
    +        Poly cp = new Poly(this);
    +        PolyVecMatrix aMatrix = new PolyVecMatrix(this);
    +        PolyVecL z = new PolyVecL(this);
    +        PolyVecK t1 = new PolyVecK(this), w1 = new PolyVecK(this), h = new PolyVecK(this);
    +
    +        if (siglen != CryptoBytes)
    +        {
    +            return false;
    +        }
    +
    +        // System.out.println("publickey = ");
    +        // Helper.printByteArray(publicKey);
    +
    +        t1 = Packing.unpackPublicKey(t1, encT1, this);
    +
    +        // System.out.println(t1.toString("t1"));
    +
    +        // System.out.println("rho = ");
    +        // Helper.printByteArray(rho);
    +
    +        if (!Packing.unpackSignature(z, h, sig, this))
    +        {
    +            return false;
    +        }
    +        c = Arrays.copyOfRange(sig, 0, DilithiumCTilde);
    +
    +        // System.out.println(z.toString("z"));
    +        // System.out.println(h.toString("h"));
    +
    +        if (z.checkNorm(getDilithiumGamma1() - getDilithiumBeta()))
    +        {
    +            return false;
    +        }
    +
    +        // Compute crh(crh(rho, t1), msg)
    +        shake256Digest.update(rho, 0, rho.length);
    +        shake256Digest.update(encT1, 0, encT1.length);
    +        shake256Digest.doFinal(mu, 0, TrBytes);
    +        // System.out.println("mu before = ");
    +        // Helper.printByteArray(mu);
    +
    +        shake256Digest.update(mu, 0, TrBytes);
    +        shake256Digest.update(msg, 0, msglen);
    +        shake256Digest.doFinal(mu, 0);
    +
    +        // System.out.println("mu after = ");
    +        // Helper.printByteArray(mu);
    +
    +        // Matrix-vector multiplication; compute Az - c2^dt1
    +        cp.challenge(Arrays.copyOfRange(c, 0, DilithiumCTilde));  // use only first DilithiumCTilde of c.
    +        // System.out.println("cp = ");
    +        // System.out.println(cp.toString());
    +
    +        aMatrix.expandMatrix(rho);
    +        // System.out.println(aMatrix.toString("aMatrix = "));
    +
    +
    +        z.polyVecNtt();
    +        aMatrix.pointwiseMontgomery(w1, z);
    +
    +        cp.polyNtt();
    +        // System.out.println("cp = ");
    +        // System.out.println(cp.toString());
    +
    +        t1.shiftLeft();
    +        t1.polyVecNtt();
    +        t1.pointwisePolyMontgomery(cp, t1);
    +
    +        // System.out.println(t1.toString("t1"));
    +
    +        w1.subtract(t1);
    +        w1.reduce();
    +        w1.invNttToMont();
    +
    +        // System.out.println(w1.toString("w1 before caddq"));
    +
    +        // Reconstruct w1
    +        w1.conditionalAddQ();
    +        // System.out.println(w1.toString("w1 before hint"));
    +        w1.useHint(w1, h);
    +        // System.out.println(w1.toString("w1"));
    +
    +        buf = w1.packW1();
    +
    +        // System.out.println("buf = ");
    +        // Helper.printByteArray(buf);
    +
    +        // System.out.println("mu = ");
    +        // Helper.printByteArray(mu);
    +
    +        SHAKEDigest shakeDigest256 = new SHAKEDigest(256);
    +        shakeDigest256.update(mu, 0, CrhBytes);
    +        shakeDigest256.update(buf, 0, DilithiumK * DilithiumPolyW1PackedBytes);
    +        shakeDigest256.doFinal(c2, 0, DilithiumCTilde);
    +
    +        // System.out.println("c = ");
    +        // Helper.printByteArray(c);
    +
    +        // System.out.println("c2 = ");
    +        // Helper.printByteArray(c2);
    +
    +
    +        return Arrays.constantTimeAreEqual(c, c2);
    +    }
    +
    +    public byte[][] generateKeyPair()
    +    {
    +        byte[] seedBuf = new byte[SeedBytes];
    +        random.nextBytes(seedBuf);
    +        return generateKeyPairInternal(seedBuf);
    +
    +    }
    +
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAKeyGenerationParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAKeyGenerationParameters.java
    new file mode 100644
    index 0000000000..affee92b3e
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAKeyGenerationParameters.java
    @@ -0,0 +1,24 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +import java.security.SecureRandom;
    +
    +import org.bouncycastle.crypto.KeyGenerationParameters;
    +
    +public class MLDSAKeyGenerationParameters
    +    extends KeyGenerationParameters
    +{
    +    private final MLDSAParameters params;
    +
    +    public MLDSAKeyGenerationParameters(
    +        SecureRandom random,
    +        MLDSAParameters mldsaParameters)
    +    {
    +        super(random, 256);
    +        this.params = mldsaParameters;
    +    }
    +
    +    public MLDSAParameters getParameters()
    +    {
    +        return params;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAKeyPairGenerator.java
    new file mode 100644
    index 0000000000..b55f930333
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAKeyPairGenerator.java
    @@ -0,0 +1,59 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +import java.security.SecureRandom;
    +
    +import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
    +import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
    +import org.bouncycastle.crypto.KeyGenerationParameters;
    +
    +public class MLDSAKeyPairGenerator
    +    implements AsymmetricCipherKeyPairGenerator
    +{
    +    private MLDSAParameters dilithiumParams;
    +
    +    private SecureRandom random;
    +
    +    private void initialize(
    +        KeyGenerationParameters param)
    +    {
    +        this.dilithiumParams = ((MLDSAKeyGenerationParameters)param).getParameters();
    +        this.random = param.getRandom();
    +    }
    +
    +    private AsymmetricCipherKeyPair genKeyPair()
    +    {
    +        MLDSAEngine engine = dilithiumParams.getEngine(random);
    +
    +        byte[][] keyPair = engine.generateKeyPair();
    +        // System.out.println("pk gen = ");
    +        // Helper.printByteArray(keyPair[0]);
    +
    +        MLDSAPublicKeyParameters pubKey = new MLDSAPublicKeyParameters(dilithiumParams, keyPair[0], keyPair[6]);
    +        MLDSAPrivateKeyParameters privKey = new MLDSAPrivateKeyParameters(dilithiumParams, keyPair[0], keyPair[1], keyPair[2], keyPair[3], keyPair[4], keyPair[5], keyPair[6]);
    +
    +        return new AsymmetricCipherKeyPair(pubKey, privKey);
    +    }
    +
    +    public void init(KeyGenerationParameters param)
    +    {
    +        this.initialize(param);
    +    }
    +
    +    public AsymmetricCipherKeyPair generateKeyPair()
    +    {
    +        return genKeyPair();
    +    }
    +    public AsymmetricCipherKeyPair internalGenerateKeyPair(byte[] seed)
    +    {
    +        MLDSAEngine engine = dilithiumParams.getEngine(random);
    +
    +        byte[][] keyPair = engine.generateKeyPairInternal(seed);
    +        // System.out.println("pk gen = ");
    +        // Helper.printByteArray(keyPair[0]);
    +
    +        MLDSAPublicKeyParameters pubKey = new MLDSAPublicKeyParameters(dilithiumParams, keyPair[0], keyPair[6]);
    +        MLDSAPrivateKeyParameters privKey = new MLDSAPrivateKeyParameters(dilithiumParams, keyPair[0], keyPair[1], keyPair[2], keyPair[3], keyPair[4], keyPair[5], keyPair[6]);
    +
    +        return new AsymmetricCipherKeyPair(pubKey, privKey);
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAKeyParameters.java
    new file mode 100644
    index 0000000000..d1825e21cc
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAKeyParameters.java
    @@ -0,0 +1,37 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
    +
    +public class MLDSAKeyParameters
    +    extends AsymmetricKeyParameter
    +{
    +    private final MLDSAParameters params;
    +
    +    private final byte[] context;
    +
    +    public MLDSAKeyParameters(boolean isPrivate, MLDSAParameters params, byte[] context)
    +    {
    +        super(isPrivate);
    +        this.params = params;
    +        this.context = context;
    +    }
    +
    +    public MLDSAKeyParameters(
    +        boolean isPrivate,
    +        MLDSAParameters params)
    +    {
    +        super(isPrivate);
    +        this.params = params;
    +        this.context = new byte[0];
    +    }
    +
    +    public MLDSAParameters getParameters()
    +    {
    +        return params;
    +    }
    +
    +    public byte[] getContext()
    +    {
    +        return context.clone();
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAParameters.java
    new file mode 100644
    index 0000000000..8b4fb1c90c
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAParameters.java
    @@ -0,0 +1,56 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +import java.security.SecureRandom;
    +
    +import org.bouncycastle.crypto.Digest;
    +import org.bouncycastle.crypto.digests.SHA512Digest;
    +
    +public class MLDSAParameters
    +{
    +    public static final int TYPE_PURE = 0;
    +    public static final int TYPE_SHA2_512 = 1;
    +
    +    public static final MLDSAParameters ml_dsa_44 = new MLDSAParameters("ml-dsa-44", 2, TYPE_PURE);
    +    public static final MLDSAParameters ml_dsa_65 = new MLDSAParameters("ml-dsa-65", 3, TYPE_PURE);
    +    public static final MLDSAParameters ml_dsa_87 = new MLDSAParameters("ml-dsa-87", 5, TYPE_PURE);
    +
    +    public static final MLDSAParameters ml_dsa_44_with_sha512 = new MLDSAParameters("ml-dsa-44-with-sha512", 2, TYPE_SHA2_512);
    +    public static final MLDSAParameters ml_dsa_65_with_sha512 = new MLDSAParameters("ml-dsa-65-with-sha512", 3, TYPE_SHA2_512);
    +    public static final MLDSAParameters ml_dsa_87_with_sha512 = new MLDSAParameters("ml-dsa-87-with-sha512", 5, TYPE_SHA2_512);
    +
    +    private final int k;
    +    private final String name;
    +    private final int preHashDigest;
    +
    +    private MLDSAParameters(String name, int k, int preHashDigest)
    +    {
    +        this.name = name;
    +        this.k = k;
    +        this.preHashDigest = preHashDigest;
    +    }
    +
    +    public boolean isPreHash()
    +    {
    +        return preHashDigest != TYPE_PURE;
    +    }
    +
    +    public int getType()
    +    {
    +        return preHashDigest;
    +    }
    +    
    +    Digest createDigest()
    +    {
    +        return preHashDigest == TYPE_PURE ? null : new SHA512Digest();
    +    }
    +
    +    MLDSAEngine getEngine(SecureRandom random)
    +    {
    +        return new MLDSAEngine(k, random);
    +    }
    +
    +    public String getName()
    +    {
    +        return name;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAPrivateKeyParameters.java
    new file mode 100644
    index 0000000000..9814d7321f
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAPrivateKeyParameters.java
    @@ -0,0 +1,110 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +public class MLDSAPrivateKeyParameters
    +    extends MLDSAKeyParameters
    +{
    +    final byte[] rho;
    +    final byte[] k;
    +    final byte[] tr;
    +    final byte[] s1;
    +    final byte[] s2;
    +    final byte[] t0;
    +
    +    private final byte[] t1;
    +
    +    public MLDSAPrivateKeyParameters(MLDSAParameters params, byte[] rho, byte[] K, byte[] tr, byte[] s1, byte[] s2, byte[] t0, byte[] t1)
    +    {
    +        super(true, params);
    +        this.rho = Arrays.clone(rho);
    +        this.k = Arrays.clone(K);
    +        this.tr = Arrays.clone(tr);
    +        this.s1 = Arrays.clone(s1);
    +        this.s2 = Arrays.clone(s2);
    +        this.t0 = Arrays.clone(t0);
    +        this.t1 = Arrays.clone(t1);
    +    }
    +
    +    public MLDSAPrivateKeyParameters(MLDSAParameters params, byte[] encoding, MLDSAPublicKeyParameters pubKey)
    +    {
    +        super(true, params);
    +
    +        MLDSAEngine eng = params.getEngine(null);
    +        int index = 0;
    +        this.rho = Arrays.copyOfRange(encoding, 0, MLDSAEngine.SeedBytes); index += MLDSAEngine.SeedBytes;
    +        this.k = Arrays.copyOfRange(encoding, index, index + MLDSAEngine.SeedBytes); index += MLDSAEngine.SeedBytes;
    +        this.tr = Arrays.copyOfRange(encoding, index, index + MLDSAEngine.TrBytes); index += MLDSAEngine.TrBytes;
    +        int delta = eng.getDilithiumL() * eng.getDilithiumPolyEtaPackedBytes();
    +        this.s1 = Arrays.copyOfRange(encoding, index, index + delta); index += delta;
    +        delta = eng.getDilithiumK() * eng.getDilithiumPolyEtaPackedBytes();
    +        this.s2 = Arrays.copyOfRange(encoding, index, index + delta); index += delta;
    +        delta = eng.getDilithiumK() * MLDSAEngine.DilithiumPolyT0PackedBytes;
    +        this.t0 = Arrays.copyOfRange(encoding, index, index + delta); index += delta;
    +
    +        if (pubKey != null)
    +        {
    +            this.t1 = pubKey.getT1();
    +        }
    +        else
    +        {
    +            this.t1 = null;
    +        }
    +    }
    +
    +    public byte[] getEncoded()
    +    {
    +        return Arrays.concatenate(new byte[][]{ rho, k, tr, s1, s2, t0 });
    +    }
    +
    +    public byte[] getK()
    +    {
    +        return Arrays.clone(k);
    +    }
    +
    +    /** @deprecated Use {@link #getEncoded()} instead. */
    +    public byte[] getPrivateKey()
    +    {
    +        return getEncoded();
    +    }
    +
    +    public byte[] getPublicKey()
    +    {
    +        return MLDSAPublicKeyParameters.getEncoded(rho, t1);
    +    }
    +
    +    public MLDSAPublicKeyParameters getPublicKeyParameters()
    +    {
    +        return new MLDSAPublicKeyParameters(getParameters(), rho, t1);
    +    }
    +
    +    public byte[] getRho()
    +    {
    +        return Arrays.clone(rho);
    +    }
    +
    +    public byte[] getS1()
    +    {
    +        return Arrays.clone(s1);
    +    }
    +
    +    public byte[] getS2()
    +    {
    +        return Arrays.clone(s2);
    +    }
    +
    +    public byte[] getT0()
    +    {
    +        return Arrays.clone(t0);
    +    }
    +
    +    public byte[] getT1()
    +    {
    +        return Arrays.clone(t1);
    +    }
    +
    +    public byte[] getTr()
    +    {
    +        return Arrays.clone(tr);
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAPublicKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAPublicKeyParameters.java
    new file mode 100644
    index 0000000000..d186679184
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAPublicKeyParameters.java
    @@ -0,0 +1,44 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +public class MLDSAPublicKeyParameters
    +    extends MLDSAKeyParameters
    +{
    +    static byte[] getEncoded(byte[] rho, byte[] t1)
    +    {
    +        return Arrays.concatenate(rho, t1);
    +    }
    +
    +    final byte[] rho;
    +    final byte[] t1;
    +
    +    public MLDSAPublicKeyParameters(MLDSAParameters params, byte[] encoding)
    +    {
    +        super(false, params);
    +        this.rho = Arrays.copyOfRange(encoding, 0, MLDSAEngine.SeedBytes);
    +        this.t1 = Arrays.copyOfRange(encoding, MLDSAEngine.SeedBytes, encoding.length);
    +    }
    +
    +    public MLDSAPublicKeyParameters(MLDSAParameters params, byte[] rho, byte[] t1)
    +    {
    +        super(false, params);
    +        this.rho = Arrays.clone(rho);
    +        this.t1 = Arrays.clone(t1);
    +    }
    +
    +    public byte[] getEncoded()
    +    {
    +        return getEncoded(rho, t1);
    +    }
    +
    +    public byte[] getRho()
    +    {
    +        return Arrays.clone(rho);
    +    }
    +
    +    public byte[] getT1()
    +    {
    +        return Arrays.clone(t1);
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSASigner.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSASigner.java
    new file mode 100644
    index 0000000000..7aa56a82fd
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSASigner.java
    @@ -0,0 +1,108 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +import java.security.SecureRandom;
    +
    +import org.bouncycastle.crypto.CipherParameters;
    +import org.bouncycastle.crypto.params.ParametersWithRandom;
    +import org.bouncycastle.pqc.crypto.MessageSigner;
    +
    +public class MLDSASigner
    +    implements MessageSigner
    +{
    +    private MLDSAPrivateKeyParameters privKey;
    +    private MLDSAPublicKeyParameters pubKey;
    +
    +    private SecureRandom random;
    +
    +    public MLDSASigner()
    +    {
    +    }
    +
    +    public void init(boolean forSigning, CipherParameters param)
    +    {
    +        boolean isPreHash;
    +
    +        if (forSigning)
    +        {
    +            if (param instanceof ParametersWithRandom)
    +            {
    +                privKey = (MLDSAPrivateKeyParameters)((ParametersWithRandom)param).getParameters();
    +                random = ((ParametersWithRandom)param).getRandom();
    +            }
    +            else
    +            {
    +                privKey = (MLDSAPrivateKeyParameters)param;
    +                random = null;
    +            }
    +
    +            isPreHash = privKey.getParameters().isPreHash();
    +        }
    +        else
    +        {
    +            pubKey = (MLDSAPublicKeyParameters)param;
    +            isPreHash = pubKey.getParameters().isPreHash();
    +        }
    +
    +        if (isPreHash)
    +        {
    +            throw new IllegalArgumentException("\"pure\" ml-dsa must use non pre-hash parameters");
    +        }
    +    }
    +
    +    public byte[] generateSignature(byte[] message)
    +    {
    +        MLDSAEngine engine = privKey.getParameters().getEngine(random);
    +
    +        byte[] ctx = privKey.getContext();
    +        if (ctx.length > 255)
    +        {
    +            throw new RuntimeException("Context too long");
    +        }
    +
    +        byte[] rnd = new byte[MLDSAEngine.RndBytes];
    +        if (random != null)
    +        {
    +            random.nextBytes(rnd);
    +        }
    +
    +        byte[] ds_message = new byte[1 + 1 + ctx.length + message.length];
    +        ds_message[0] = 0;
    +        ds_message[1] = (byte)ctx.length;
    +        System.arraycopy(ctx, 0, ds_message, 2, ctx.length);
    +        System.arraycopy(message, 0, ds_message, 2 + ctx.length, message.length);
    +
    +        return engine.signInternal(ds_message, ds_message.length, privKey.rho, privKey.k, privKey.tr, privKey.t0, privKey.s1, privKey.s2, rnd);
    +    }
    +    
    +    public byte[] internalGenerateSignature(byte[] message, byte[] random)
    +    {
    +        MLDSAEngine engine = privKey.getParameters().getEngine(this.random);
    +
    +        return engine.signInternal(message, message.length, privKey.rho, privKey.k, privKey.tr, privKey.t0, privKey.s1, privKey.s2, random);
    +    }
    +
    +    public boolean verifySignature(byte[] message, byte[] signature)
    +    {
    +        MLDSAEngine engine = pubKey.getParameters().getEngine(random);
    +
    +        byte[] ctx = pubKey.getContext();
    +        if (ctx.length > 255)
    +        {
    +            throw new RuntimeException("Context too long");
    +        }
    +
    +        byte[] ds_message = new byte[1 + 1 + ctx.length + message.length];
    +        ds_message[0] = 0;
    +        ds_message[1] = (byte)ctx.length;
    +        System.arraycopy(ctx, 0, ds_message, 2, ctx.length);
    +        System.arraycopy(message, 0, ds_message, 2 + ctx.length, message.length);
    +
    +        return engine.verifyInternal(signature, signature.length, ds_message, ds_message.length, pubKey.rho, pubKey.t1);
    +    }
    +    public boolean internalVerifySignature(byte[] message, byte[] signature)
    +    {
    +        MLDSAEngine engine = pubKey.getParameters().getEngine(random);
    +
    +        return engine.verifyInternal(signature, signature.length, message, message.length, pubKey.rho, pubKey.t1);
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Ntt.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Ntt.java
    new file mode 100644
    index 0000000000..6af28663df
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Ntt.java
    @@ -0,0 +1,98 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +class Ntt
    +{
    +    static final int[] nttZetas = {
    +        0, 25847, -2608894, -518909, 237124, -777960, -876248, 466468,
    +        1826347, 2353451, -359251, -2091905, 3119733, -2884855, 3111497, 2680103,
    +        2725464, 1024112, -1079900, 3585928, -549488, -1119584, 2619752, -2108549,
    +        -2118186, -3859737, -1399561, -3277672, 1757237, -19422, 4010497, 280005,
    +        2706023, 95776, 3077325, 3530437, -1661693, -3592148, -2537516, 3915439,
    +        -3861115, -3043716, 3574422, -2867647, 3539968, -300467, 2348700, -539299,
    +        -1699267, -1643818, 3505694, -3821735, 3507263, -2140649, -1600420, 3699596,
    +        811944, 531354, 954230, 3881043, 3900724, -2556880, 2071892, -2797779,
    +        -3930395, -1528703, -3677745, -3041255, -1452451, 3475950, 2176455, -1585221,
    +        -1257611, 1939314, -4083598, -1000202, -3190144, -3157330, -3632928, 126922,
    +        3412210, -983419, 2147896, 2715295, -2967645, -3693493, -411027, -2477047,
    +        -671102, -1228525, -22981, -1308169, -381987, 1349076, 1852771, -1430430,
    +        -3343383, 264944, 508951, 3097992, 44288, -1100098, 904516, 3958618,
    +        -3724342, -8578, 1653064, -3249728, 2389356, -210977, 759969, -1316856,
    +        189548, -3553272, 3159746, -1851402, -2409325, -177440, 1315589, 1341330,
    +        1285669, -1584928, -812732, -1439742, -3019102, -3881060, -3628969, 3839961,
    +        2091667, 3407706, 2316500, 3817976, -3342478, 2244091, -2446433, -3562462,
    +        266997, 2434439, -1235728, 3513181, -3520352, -3759364, -1197226, -3193378,
    +        900702, 1859098, 909542, 819034, 495491, -1613174, -43260, -522500,
    +        -655327, -3122442, 2031748, 3207046, -3556995, -525098, -768622, -3595838,
    +        342297, 286988, -2437823, 4108315, 3437287, -3342277, 1735879, 203044,
    +        2842341, 2691481, -2590150, 1265009, 4055324, 1247620, 2486353, 1595974,
    +        -3767016, 1250494, 2635921, -3548272, -2994039, 1869119, 1903435, -1050970,
    +        -1333058, 1237275, -3318210, -1430225, -451100, 1312455, 3306115, -1962642,
    +        -1279661, 1917081, -2546312, -1374803, 1500165, 777191, 2235880, 3406031,
    +        -542412, -2831860, -1671176, -1846953, -2584293, -3724270, 594136, -3776993,
    +        -2013608, 2432395, 2454455, -164721, 1957272, 3369112, 185531, -1207385,
    +        -3183426, 162844, 1616392, 3014001, 810149, 1652634, -3694233, -1799107,
    +        -3038916, 3523897, 3866901, 269760, 2213111, -975884, 1717735, 472078,
    +        -426683, 1723600, -1803090, 1910376, -1667432, -1104333, -260646, -3833893,
    +        -2939036, -2235985, -420899, -2286327, 183443, -976891, 1612842, -3545687,
    +        -554416, 3919660, -48306, -1362209, 3937738, 1400424, -846154, 1976782
    +    };
    +
    +    static int[] ntt(int[] a)
    +    {
    +        int[] r = Arrays.copyOfRange(a, 0, a.length);
    +
    +        int len, start, j, k;
    +        int zeta, t;
    +
    +        k = 0;
    +        for (len = 128; len > 0; len >>>= 1)
    +        {
    +            for (start = 0; start < MLDSAEngine.DilithiumN; start = j + len)
    +            {
    +                zeta = nttZetas[++k];
    +                for (j = start; j < start + len; ++j)
    +                {
    +                    t = Reduce.montgomeryReduce(((long)zeta * (long)r[j + len]));
    +                    r[j + len] = r[j] - t;
    +                    r[j] = r[j] + t;
    +                }
    +            }
    +        }
    +        return r;
    +    }
    +
    +
    +    static int[] invNttToMont(int[] a)
    +    {
    +        int start, len, j, k;
    +        int t, zeta;
    +        final int f = 41978; // (mont^2)/256
    +
    +        int[] out = Arrays.copyOfRange(a, 0, a.length);
    +
    +        k = 256;
    +        for (len = 1; len < MLDSAEngine.DilithiumN; len <<= 1)
    +        {
    +            for (start = 0; start < MLDSAEngine.DilithiumN; start = j + len)
    +            {
    +                zeta = (-1) * nttZetas[--k];
    +                for (j = start; j < start + len; ++j)
    +                {
    +                    t = out[j];
    +                    out[j] = t + out[j + len];
    +                    out[j + len] = t - out[j + len];
    +                    out[j + len] = Reduce.montgomeryReduce((long)((long)zeta * (long)out[j + len]));
    +                }
    +            }
    +        }
    +
    +        for (j = 0; j < MLDSAEngine.DilithiumN; ++j)
    +        {
    +            out[j] = Reduce.montgomeryReduce((long)((long)f * (long)out[j]));
    +        }
    +        return out;
    +    }
    +}
    +
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Packing.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Packing.java
    new file mode 100644
    index 0000000000..05fd026977
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Packing.java
    @@ -0,0 +1,165 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +class Packing
    +{
    +
    +    static byte[] packPublicKey(PolyVecK t1, MLDSAEngine engine)
    +    {
    +        byte[] out = new byte[engine.getCryptoPublicKeyBytes() - MLDSAEngine.SeedBytes];
    +
    +        for (int i = 0; i < engine.getDilithiumK(); ++i)
    +        {
    +            System.arraycopy(t1.getVectorIndex(i).polyt1Pack(), 0, out, i * MLDSAEngine.DilithiumPolyT1PackedBytes, MLDSAEngine.DilithiumPolyT1PackedBytes);
    +        }
    +        return out;
    +    }
    +
    +    static PolyVecK unpackPublicKey(PolyVecK t1, byte[] publicKey, MLDSAEngine engine)
    +    {
    +        int i;
    +
    +        for (i = 0; i < engine.getDilithiumK(); ++i)
    +        {
    +            t1.getVectorIndex(i).polyt1Unpack(Arrays.copyOfRange(publicKey, i * MLDSAEngine.DilithiumPolyT1PackedBytes, MLDSAEngine.SeedBytes + (i + 1) * MLDSAEngine.DilithiumPolyT1PackedBytes));
    +        }
    +        return t1;
    +    }
    +
    +    static byte[][] packSecretKey(byte[] rho, byte[] tr, byte[] key, PolyVecK t0, PolyVecL s1, PolyVecK s2, MLDSAEngine engine)
    +    {
    +        byte[][] out = new byte[6][];
    +
    +        out[0] = rho;
    +        out[1] = key;
    +        out[2] = tr;
    +
    +        out[3] = new byte[engine.getDilithiumL() * engine.getDilithiumPolyEtaPackedBytes()];
    +        for (int i = 0; i < engine.getDilithiumL(); ++i)
    +        {
    +            s1.getVectorIndex(i).polyEtaPack(out[3], i * engine.getDilithiumPolyEtaPackedBytes());
    +        }
    +
    +        out[4] = new byte[engine.getDilithiumK() * engine.getDilithiumPolyEtaPackedBytes()];
    +        for (int i = 0; i < engine.getDilithiumK(); ++i)
    +        {
    +            s2.getVectorIndex(i).polyEtaPack(out[4], i * engine.getDilithiumPolyEtaPackedBytes());
    +        }
    +
    +        out[5] = new byte[engine.getDilithiumK() * MLDSAEngine.DilithiumPolyT0PackedBytes];
    +        for (int i = 0; i < engine.getDilithiumK(); ++i)
    +        {
    +            t0.getVectorIndex(i).polyt0Pack(out[5], i * MLDSAEngine.DilithiumPolyT0PackedBytes);
    +        }
    +        return out;
    +    }
    +
    +    /**
    +     * @param t0
    +     * @param s1
    +     * @param s2
    +     * @param engine
    +     * @return Byte matrix where byte[0] = rho, byte[1] = tr, byte[2] = key
    +     */
    +
    +    static void unpackSecretKey(PolyVecK t0, PolyVecL s1, PolyVecK s2, byte[] t0Enc, byte[] s1Enc, byte[] s2Enc, MLDSAEngine engine)
    +    {
    +        for (int i = 0; i < engine.getDilithiumL(); ++i)
    +        {
    +            s1.getVectorIndex(i).polyEtaUnpack(s1Enc, i * engine.getDilithiumPolyEtaPackedBytes());
    +        }
    +
    +        for (int i = 0; i < engine.getDilithiumK(); ++i)
    +        {
    +            s2.getVectorIndex(i).polyEtaUnpack(s2Enc, i * engine.getDilithiumPolyEtaPackedBytes());
    +        }
    +
    +        for (int i = 0; i < engine.getDilithiumK(); ++i)
    +        {
    +            t0.getVectorIndex(i).polyt0Unpack(t0Enc, i * MLDSAEngine.DilithiumPolyT0PackedBytes);
    +        }
    +    }
    +
    +    static byte[] packSignature(byte[] c, PolyVecL z, PolyVecK h, MLDSAEngine engine)
    +    {
    +        int i, j, k, end = 0;
    +        byte[] outBytes = new byte[engine.getCryptoBytes()];
    +
    +        System.arraycopy(c, 0, outBytes, 0, engine.getDilithiumCTilde());
    +        end += engine.getDilithiumCTilde();
    +
    +        for (i = 0; i < engine.getDilithiumL(); ++i)
    +        {
    +            System.arraycopy(z.getVectorIndex(i).zPack(), 0, outBytes, end + i * engine.getDilithiumPolyZPackedBytes(), engine.getDilithiumPolyZPackedBytes());
    +        }
    +        end += engine.getDilithiumL() * engine.getDilithiumPolyZPackedBytes();
    +
    +        for (i = 0; i < engine.getDilithiumOmega() + engine.getDilithiumK(); ++i)
    +        {
    +            outBytes[end + i] = 0;
    +        }
    +
    +        k = 0;
    +        for (i = 0; i < engine.getDilithiumK(); ++i)
    +        {
    +            for (j = 0; j < MLDSAEngine.DilithiumN; ++j)
    +            {
    +                if (h.getVectorIndex(i).getCoeffIndex(j) != 0)
    +                {
    +                    outBytes[end + k++] = (byte)j;
    +                }
    +            }
    +            outBytes[end + engine.getDilithiumOmega() + i] = (byte)k;
    +        }
    +
    +        return outBytes;
    +
    +    }
    +
    +    static boolean unpackSignature(PolyVecL z, PolyVecK h, byte[] sig, MLDSAEngine engine)
    +    {
    +        int i, j, k;
    +
    +        int end = engine.getDilithiumCTilde();
    +        for (i = 0; i < engine.getDilithiumL(); ++i)
    +        {
    +            z.getVectorIndex(i).zUnpack(Arrays.copyOfRange(sig, end + i * engine.getDilithiumPolyZPackedBytes(), end + (i + 1) * engine.getDilithiumPolyZPackedBytes()));
    +        }
    +        end += engine.getDilithiumL() * engine.getDilithiumPolyZPackedBytes();
    +
    +        k = 0;
    +        for (i = 0; i < engine.getDilithiumK(); ++i)
    +        {
    +            for (j = 0; j < MLDSAEngine.DilithiumN; ++j)
    +            {
    +                h.getVectorIndex(i).setCoeffIndex(j, 0);
    +            }
    +
    +            if ((sig[end + engine.getDilithiumOmega() + i] & 0xFF) < k || (sig[end + engine.getDilithiumOmega() + i] & 0xFF) > engine.getDilithiumOmega())
    +            {
    +                return false;
    +            }
    +
    +            for (j = k; j < (sig[end + engine.getDilithiumOmega() + i] & 0xFF); ++j)
    +            {
    +                if (j > k && (sig[end + j] & 0xFF) <= (sig[end + j - 1] & 0xFF))
    +                {
    +                    return false;
    +                }
    +                h.getVectorIndex(i).setCoeffIndex((sig[end + j] & 0xFF), 1);
    +            }
    +
    +            k = (int)(sig[end + engine.getDilithiumOmega() + i]);
    +        }
    +        for (j = k; j < engine.getDilithiumOmega(); ++j)
    +        {
    +            if ((sig[end + j] & 0xFF) != 0)
    +            {                    
    +                return false;
    +            }
    +        }
    +        return true;
    +    }
    +
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Poly.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Poly.java
    new file mode 100644
    index 0000000000..2066d8607e
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Poly.java
    @@ -0,0 +1,802 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +import org.bouncycastle.crypto.digests.SHAKEDigest;
    +
    +class Poly
    +{
    +    private final int polyUniformNBlocks;
    +    private int[] coeffs;
    +    private final MLDSAEngine engine;
    +    private final int dilithiumN;
    +
    +    private final Symmetric symmetric;
    +
    +
    +    public Poly(MLDSAEngine engine)
    +    {
    +        this.dilithiumN = MLDSAEngine.DilithiumN;
    +        this.coeffs = new int[dilithiumN];
    +        this.engine = engine;
    +        this.symmetric = engine.GetSymmetric();
    +        this.polyUniformNBlocks = (768 + symmetric.stream128BlockBytes - 1) / symmetric.stream128BlockBytes;
    +    }
    +
    +    public int getCoeffIndex(int i)
    +    {
    +        return this.coeffs[i];
    +    }
    +
    +    public int[] getCoeffs()
    +    {
    +        return this.coeffs;
    +    }
    +
    +    public void setCoeffIndex(int i, int val)
    +    {
    +        this.coeffs[i] = val;
    +    }
    +
    +    public void setCoeffs(int[] coeffs)
    +    {
    +        this.coeffs = coeffs;
    +    }
    +
    +    public void uniformBlocks(byte[] seed, short nonce)
    +    {
    +        int i, ctr, off,
    +            buflen = polyUniformNBlocks * symmetric.stream128BlockBytes;
    +        byte[] buf = new byte[buflen + 2];
    +
    +        symmetric.stream128init(seed, nonce);
    +
    +        symmetric.stream128squeezeBlocks(buf, 0, buflen);
    +
    +        ctr = rejectUniform(this, 0, dilithiumN, buf, buflen);
    +
    +        // ctr can be less than N
    +
    +        while (ctr < dilithiumN)
    +        {
    +            off = buflen % 3;
    +            for (i = 0; i < off; ++i)
    +            {
    +                buf[i] = buf[buflen - off + i];
    +            }
    +            symmetric.stream128squeezeBlocks(buf, off, symmetric.stream128BlockBytes);
    +            buflen = symmetric.stream128BlockBytes + off;
    +            ctr += rejectUniform(this, ctr, dilithiumN - ctr, buf, buflen);
    +        }
    +
    +    }
    +
    +    private static int rejectUniform(Poly outputPoly, int coeffOff, int len, byte[] inpBuf, int buflen)
    +    {
    +        int ctr, pos;
    +        int t;
    +
    +        ctr = pos = 0;
    +        while (ctr < len && pos + 3 <= buflen)
    +        {
    +            t = (inpBuf[pos++] & 0xFF);
    +            t |= (inpBuf[pos++] & 0xFF) << 8;
    +            t |= (inpBuf[pos++] & 0xFF) << 16;
    +            t &= 0x7FFFFF;
    +
    +            if (t < MLDSAEngine.DilithiumQ)
    +            {
    +                outputPoly.setCoeffIndex(coeffOff + ctr, t);
    +                ctr++;
    +            }
    +        }
    +
    +        return ctr;
    +
    +    }
    +
    +    public void uniformEta(byte[] seed, short nonce)
    +    {
    +        int ctr, polyUniformEtaNBlocks, eta = engine.getDilithiumEta();
    +
    +        if (engine.getDilithiumEta() == 2)
    +        {
    +            polyUniformEtaNBlocks = ((136 + symmetric.stream256BlockBytes - 1) / symmetric.stream256BlockBytes); // TODO: change with class
    +        }
    +        else if (engine.getDilithiumEta() == 4)
    +        {
    +            polyUniformEtaNBlocks = ((227 + symmetric.stream256BlockBytes - 1) / symmetric.stream256BlockBytes); // TODO: change with class
    +        }
    +        else
    +        {
    +            throw new RuntimeException("Wrong Dilithium Eta!");
    +        }
    +
    +        int buflen = polyUniformEtaNBlocks * symmetric.stream256BlockBytes;
    +
    +        byte[] buf = new byte[buflen];
    +
    +        symmetric.stream256init(seed, nonce);
    +        symmetric.stream256squeezeBlocks(buf, 0, buflen);
    +
    +        ctr = rejectEta(this, 0, dilithiumN, buf, buflen, eta);
    +
    +        while (ctr < MLDSAEngine.DilithiumN)
    +        {
    +            symmetric.stream256squeezeBlocks(buf, 0, symmetric.stream256BlockBytes);
    +            ctr += rejectEta(this, ctr, dilithiumN - ctr, buf, symmetric.stream256BlockBytes, eta);
    +        }
    +
    +    }
    +
    +    private static int rejectEta(Poly outputPoly, int coeffOff, int len, byte[] buf, int buflen, int eta)
    +    {
    +        int ctr, pos;
    +        int t0, t1;
    +
    +        ctr = pos = 0;
    +
    +        while (ctr < len && pos < buflen)
    +        {
    +            t0 = (buf[pos] & 0xFF) & 0x0F;
    +            t1 = (buf[pos++] & 0xFF) >> 4;
    +            if (eta == 2)
    +            {
    +                if (t0 < 15)
    +                {
    +                    t0 = t0 - (205 * t0 >> 10) * 5;
    +                    outputPoly.setCoeffIndex(coeffOff + ctr, 2 - t0);
    +                    ctr++;
    +                }
    +                if (t1 < 15 && ctr < len)
    +                {
    +                    t1 = t1 - (205 * t1 >> 10) * 5;
    +                    outputPoly.setCoeffIndex(coeffOff + ctr, 2 - t1);
    +                    ctr++;
    +                }
    +            }
    +            else if (eta == 4)
    +            {
    +                if (t0 < 9)
    +                {
    +                    outputPoly.setCoeffIndex(coeffOff + ctr, 4 - t0);
    +                    ctr++;
    +                }
    +                if (t1 < 9 && ctr < len)
    +                {
    +                    outputPoly.setCoeffIndex(coeffOff + ctr, 4 - t1);
    +                    ctr++;
    +                }
    +                // System.out.printf("ctr %d coeff %d\n", ctr, outputPoly.getCoeffIndex(ctr - 1));
    +            }
    +        }
    +        return ctr;
    +    }
    +
    +    public void polyNtt()
    +    {
    +        this.setCoeffs(Ntt.ntt(this.coeffs));
    +    }
    +
    +    public void pointwiseMontgomery(Poly v, Poly w)
    +    {
    +        int i;
    +        for (i = 0; i < dilithiumN; ++i)
    +        {
    +            this.setCoeffIndex(i, Reduce.montgomeryReduce((long)((long)v.getCoeffIndex(i) * (long)w.getCoeffIndex(i))));
    +        }
    +    }
    +
    +    public void pointwiseAccountMontgomery(PolyVecL u, PolyVecL v)
    +    {
    +        int i;
    +        Poly t = new Poly(engine);
    +
    +        this.pointwiseMontgomery(u.getVectorIndex(0), v.getVectorIndex(0));
    +
    +        for (i = 1; i < engine.getDilithiumL(); ++i)
    +        {
    +            t.pointwiseMontgomery(u.getVectorIndex(i), v.getVectorIndex(i));
    +            this.addPoly(t);
    +        }
    +
    +
    +    }
    +
    +    public void addPoly(Poly a)
    +    {
    +        int i;
    +        for (i = 0; i < dilithiumN; i++)
    +        {
    +            this.setCoeffIndex(i, this.getCoeffIndex(i) + a.getCoeffIndex(i));
    +        }
    +    }
    +
    +
    +    public void reduce()
    +    {
    +        for (int i = 0; i < dilithiumN; ++i)
    +        {
    +            this.setCoeffIndex(i, Reduce.reduce32(this.getCoeffIndex(i)));
    +        }
    +    }
    +
    +    public void invNttToMont()
    +    {
    +        this.setCoeffs(Ntt.invNttToMont(this.getCoeffs()));
    +    }
    +
    +    public void conditionalAddQ()
    +    {
    +        for (int i = 0; i < dilithiumN; ++i)
    +        {
    +            this.setCoeffIndex(i, Reduce.conditionalAddQ(this.getCoeffIndex(i)));
    +        }
    +    }
    +
    +    public void power2Round(Poly a)
    +    {
    +        for (int i = 0; i < dilithiumN; ++i)
    +        {
    +            int[] p2r = Rounding.power2Round(this.getCoeffIndex(i));
    +            this.setCoeffIndex(i, p2r[0]);
    +            a.setCoeffIndex(i, p2r[1]);
    +        }
    +    }
    +
    +    public byte[] polyt1Pack()
    +    {
    +        byte[] out = new byte[MLDSAEngine.DilithiumPolyT1PackedBytes];
    +
    +        for (int i = 0; i < dilithiumN / 4; ++i)
    +        {
    +            out[5 * i + 0] = (byte)(this.coeffs[4 * i + 0] >> 0);
    +            out[5 * i + 1] = (byte)((this.coeffs[4 * i + 0] >> 8) | (this.coeffs[4 * i + 1] << 2));
    +            out[5 * i + 2] = (byte)((this.coeffs[4 * i + 1] >> 6) | (this.coeffs[4 * i + 2] << 4));
    +            out[5 * i + 3] = (byte)((this.coeffs[4 * i + 2] >> 4) | (this.coeffs[4 * i + 3] << 6));
    +            out[5 * i + 4] = (byte)(this.coeffs[4 * i + 3] >> 2);
    +        }
    +        return out;
    +    }
    +
    +    public void polyt1Unpack(byte[] a)
    +    {
    +        int i;
    +
    +        for (i = 0; i < dilithiumN / 4; ++i)
    +        {
    +            this.setCoeffIndex(4 * i + 0, (((a[5 * i + 0] & 0xFF) >> 0) | ((int)(a[5 * i + 1] & 0xFF) << 8)) & 0x3FF);
    +            this.setCoeffIndex(4 * i + 1, (((a[5 * i + 1] & 0xFF) >> 2) | ((int)(a[5 * i + 2] & 0xFF) << 6)) & 0x3FF);
    +            this.setCoeffIndex(4 * i + 2, (((a[5 * i + 2] & 0xFF) >> 4) | ((int)(a[5 * i + 3] & 0xFF) << 4)) & 0x3FF);
    +            this.setCoeffIndex(4 * i + 3, (((a[5 * i + 3] & 0xFF) >> 6) | ((int)(a[5 * i + 4] & 0xFF) << 2)) & 0x3FF);
    +        }
    +    }
    +
    +    public byte[] polyEtaPack(byte[] out, int outOff)
    +    {
    +        int i;
    +        byte[] t = new byte[8];
    +
    +        if (engine.getDilithiumEta() == 2)
    +        {
    +            for (i = 0; i < dilithiumN / 8; ++i)
    +            {
    +                t[0] = (byte)(engine.getDilithiumEta() - this.getCoeffIndex(8 * i + 0));
    +                t[1] = (byte)(engine.getDilithiumEta() - this.getCoeffIndex(8 * i + 1));
    +                t[2] = (byte)(engine.getDilithiumEta() - this.getCoeffIndex(8 * i + 2));
    +                t[3] = (byte)(engine.getDilithiumEta() - this.getCoeffIndex(8 * i + 3));
    +                t[4] = (byte)(engine.getDilithiumEta() - this.getCoeffIndex(8 * i + 4));
    +                t[5] = (byte)(engine.getDilithiumEta() - this.getCoeffIndex(8 * i + 5));
    +                t[6] = (byte)(engine.getDilithiumEta() - this.getCoeffIndex(8 * i + 6));
    +                t[7] = (byte)(engine.getDilithiumEta() - this.getCoeffIndex(8 * i + 7));
    +
    +                out[outOff + 3 * i + 0] = (byte)((t[0] >> 0) | (t[1] << 3) | (t[2] << 6));
    +                out[outOff + 3 * i + 1] = (byte)((t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7));
    +                out[outOff + 3 * i + 2] = (byte)((t[5] >> 1) | (t[6] << 2) | (t[7] << 5));
    +            }
    +        }
    +        else if (engine.getDilithiumEta() == 4)
    +        {
    +            for (i = 0; i < dilithiumN / 2; ++i)
    +            {
    +                t[0] = (byte)(engine.getDilithiumEta() - this.getCoeffIndex(2 * i + 0));
    +                t[1] = (byte)(engine.getDilithiumEta() - this.getCoeffIndex(2 * i + 1));
    +                out[outOff + i] = (byte)(t[0] | t[1] << 4);
    +            }
    +        }
    +        else
    +        {
    +            throw new RuntimeException("Eta needs to be 2 or 4!");
    +        }
    +        return out;
    +    }
    +
    +    public void polyEtaUnpack(byte[] a, int aOff)
    +    {
    +        int i, eta = engine.getDilithiumEta();
    +
    +        if (engine.getDilithiumEta() == 2)
    +        {
    +            for (i = 0; i < dilithiumN / 8; ++i)
    +            {
    +                int base = aOff + 3 * i;
    +                this.setCoeffIndex(8 * i + 0, (((a[base + 0] & 0xFF) >> 0)) & 7);
    +                this.setCoeffIndex(8 * i + 1, (((a[base + 0] & 0xFF) >> 3)) & 7);
    +                this.setCoeffIndex(8 * i + 2, ((a[base + 0] & 0xFF) >> 6) | ((a[base + 1] & 0xFF) << 2) & 7);
    +                this.setCoeffIndex(8 * i + 3, (((a[base + 1] & 0xFF) >> 1)) & 7);
    +                this.setCoeffIndex(8 * i + 4, (((a[base + 1] & 0xFF) >> 4)) & 7);
    +                this.setCoeffIndex(8 * i + 5, ((a[base + 1] & 0xFF) >> 7) | ((a[base + 2] & 0xFF) << 1) & 7);
    +                this.setCoeffIndex(8 * i + 6, (((a[base + 2] & 0xFF) >> 2)) & 7);
    +                this.setCoeffIndex(8 * i + 7, (((a[base + 2] & 0xFF) >> 5)) & 7);
    +
    +                this.setCoeffIndex(8 * i + 0, eta - this.getCoeffIndex(8 * i + 0));
    +                this.setCoeffIndex(8 * i + 1, eta - this.getCoeffIndex(8 * i + 1));
    +                this.setCoeffIndex(8 * i + 2, eta - this.getCoeffIndex(8 * i + 2));
    +                this.setCoeffIndex(8 * i + 3, eta - this.getCoeffIndex(8 * i + 3));
    +                this.setCoeffIndex(8 * i + 4, eta - this.getCoeffIndex(8 * i + 4));
    +                this.setCoeffIndex(8 * i + 5, eta - this.getCoeffIndex(8 * i + 5));
    +                this.setCoeffIndex(8 * i + 6, eta - this.getCoeffIndex(8 * i + 6));
    +                this.setCoeffIndex(8 * i + 7, eta - this.getCoeffIndex(8 * i + 7));
    +            }
    +        }
    +        else if (engine.getDilithiumEta() == 4)
    +        {
    +            for (i = 0; i < dilithiumN / 2; ++i)
    +            {
    +                this.setCoeffIndex(2 * i + 0, a[aOff + i] & 0x0F);
    +                this.setCoeffIndex(2 * i + 1, (a[aOff + i] & 0xFF) >> 4);
    +                this.setCoeffIndex(2 * i + 0, eta - this.getCoeffIndex(2 * i + 0));
    +                this.setCoeffIndex(2 * i + 1, eta - this.getCoeffIndex(2 * i + 1));
    +            }
    +        }
    +    }
    +
    +    public byte[] polyt0Pack(byte[] out, int outOff)
    +    {
    +        int i;
    +        int[] t = new int[8];
    +
    +        for (i = 0; i < dilithiumN / 8; ++i)
    +        {
    +            t[0] = (1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 0);
    +            t[1] = (1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 1);
    +            t[2] = (1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 2);
    +            t[3] = (1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 3);
    +            t[4] = (1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 4);
    +            t[5] = (1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 5);
    +            t[6] = (1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 6);
    +            t[7] = (1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 7);
    +
    +            int base = outOff + 13 * i;
    +            out[base + 0] = (byte)(t[0]);
    +            out[base + 1] = (byte)(t[0] >> 8);
    +            out[base + 1] = (byte)(out[base + 1] | (byte)(t[1] << 5));
    +            out[base + 2] = (byte)(t[1] >> 3);
    +            out[base + 3] = (byte)(t[1] >> 11);
    +            out[base + 3] = (byte)(out[base + 3] | (byte)(t[2] << 2));
    +            out[base + 4] = (byte)(t[2] >> 6);
    +            out[base + 4] = (byte)(out[base + 4] | (byte)(t[3] << 7));
    +            out[base + 5] = (byte)(t[3] >> 1);
    +            out[base + 6] = (byte)(t[3] >> 9);
    +            out[base + 6] = (byte)(out[base + 6] | (byte)(t[4] << 4));
    +            out[base + 7] = (byte)(t[4] >> 4);
    +            out[base + 8] = (byte)(t[4] >> 12);
    +            out[base + 8] = (byte)(out[base + 8] | (byte)(t[5] << 1));
    +            out[base + 9] = (byte)(t[5] >> 7);
    +            out[base + 9] = (byte)(out[base + 9] | (byte)(t[6] << 6));
    +            out[base + 10] = (byte)(t[6] >> 2);
    +            out[base + 11] = (byte)(t[6] >> 10);
    +            out[base + 11] = (byte)(out[base + 11] | (byte)(t[7] << 3));
    +            out[base + 12] = (byte)(t[7] >> 5);
    +        }
    +        return out;
    +    }
    +
    +    public void polyt0Unpack(byte[] a, int aOff)
    +    {
    +        int i;
    +        for (i = 0; i < dilithiumN / 8; ++i)
    +        {
    +            int base = aOff + 13 * i;
    +            this.setCoeffIndex(8 * i + 0,
    +                (
    +                    (a[base + 0] & 0xFF) |
    +                        ((a[base + 1] & 0xFF) << 8)
    +                ) & 0x1FFF);
    +            this.setCoeffIndex(8 * i + 1,
    +                (
    +                    (((a[base + 1] & 0xFF) >> 5) |
    +                        ((a[base + 2] & 0xFF) << 3)) |
    +                        ((a[base + 3] & 0xFF) << 11)
    +                ) & 0x1FFF);
    +
    +            this.setCoeffIndex(8 * i + 2,
    +                (
    +                    (((a[base + 3] & 0xFF) >> 2) |
    +                        ((a[base + 4] & 0xFF) << 6))
    +                ) & 0x1FFF);
    +
    +            this.setCoeffIndex(8 * i + 3,
    +                (
    +                    (((a[base + 4] & 0xFF) >> 7) |
    +                        ((a[base + 5] & 0xFF) << 1)) |
    +                        ((a[base + 6] & 0xFF) << 9)
    +                ) & 0x1FFF);
    +
    +            this.setCoeffIndex(8 * i + 4,
    +                (
    +                    (((a[base + 6] & 0xFF) >> 4) |
    +                        ((a[base + 7] & 0xFF) << 4)) |
    +                        ((a[base + 8] & 0xFF) << 12)
    +                ) & 0x1FFF);
    +
    +            this.setCoeffIndex(8 * i + 5,
    +                (
    +                    (((a[base + 8] & 0xFF) >> 1) |
    +                        ((a[base + 9] & 0xFF) << 7))
    +                ) & 0x1FFF);
    +
    +            this.setCoeffIndex(8 * i + 6,
    +                (
    +                    (((a[base + 9] & 0xFF) >> 6) |
    +                        ((a[base + 10] & 0xFF) << 2)) |
    +                        ((a[base + 11] & 0xFF) << 10)
    +                ) & 0x1FFF);
    +
    +            this.setCoeffIndex(8 * i + 7,
    +                (
    +                    ((a[base + 11] & 0xFF) >> 3 |
    +                        ((a[base + 12] & 0xFF) << 5))
    +                ) & 0x1FFF);
    +
    +
    +            this.setCoeffIndex(8 * i + 0, ((1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 0)));
    +            this.setCoeffIndex(8 * i + 1, ((1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 1)));
    +            this.setCoeffIndex(8 * i + 2, ((1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 2)));
    +            this.setCoeffIndex(8 * i + 3, ((1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 3)));
    +            this.setCoeffIndex(8 * i + 4, ((1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 4)));
    +            this.setCoeffIndex(8 * i + 5, ((1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 5)));
    +            this.setCoeffIndex(8 * i + 6, ((1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 6)));
    +            this.setCoeffIndex(8 * i + 7, ((1 << (MLDSAEngine.DilithiumD - 1)) - this.getCoeffIndex(8 * i + 7)));
    +        }
    +    }
    +
    +
    +    public void uniformGamma1(byte[] seed, short nonce)
    +    {
    +        byte[] buf = new byte[engine.getPolyUniformGamma1NBlocks() * symmetric.stream256BlockBytes];
    +
    +        symmetric.stream256init(seed, nonce);
    +        symmetric.stream256squeezeBlocks(buf, 0, engine.getPolyUniformGamma1NBlocks() * symmetric.stream256BlockBytes);// todo this is final
    +
    +        this.unpackZ(buf);
    +    }
    +
    +    private void unpackZ(byte[] a)
    +    {
    +        int i;
    +        if (engine.getDilithiumGamma1() == (1 << 17))
    +        {
    +            for (i = 0; i < dilithiumN / 4; ++i)
    +            {
    +                this.setCoeffIndex(4 * i + 0,
    +                    (
    +                        (((a[9 * i + 0] & 0xFF)) |
    +                            ((a[9 * i + 1] & 0xFF) << 8)) |
    +                            ((a[9 * i + 2] & 0xFF) << 16)
    +                    ) & 0x3FFFF);
    +                this.setCoeffIndex(4 * i + 1,
    +                    (
    +                        (((a[9 * i + 2] & 0xFF) >> 2) |
    +                            ((a[9 * i + 3] & 0xFF) << 6)) |
    +                            ((a[9 * i + 4] & 0xFF) << 14)
    +                    ) & 0x3FFFF);
    +                this.setCoeffIndex(4 * i + 2,
    +                    (
    +                        (((a[9 * i + 4] & 0xFF) >> 4) |
    +                            ((a[9 * i + 5] & 0xFF) << 4)) |
    +                            ((a[9 * i + 6] & 0xFF) << 12)
    +                    ) & 0x3FFFF);
    +                this.setCoeffIndex(4 * i + 3,
    +                    (
    +                        (((a[9 * i + 6] & 0xFF) >> 6) |
    +                            ((a[9 * i + 7] & 0xFF) << 2)) |
    +                            ((a[9 * i + 8] & 0xFF) << 10)
    +                    ) & 0x3FFFF);
    +
    +
    +                this.setCoeffIndex(4 * i + 0, engine.getDilithiumGamma1() - this.getCoeffIndex(4 * i + 0));
    +                this.setCoeffIndex(4 * i + 1, engine.getDilithiumGamma1() - this.getCoeffIndex(4 * i + 1));
    +                this.setCoeffIndex(4 * i + 2, engine.getDilithiumGamma1() - this.getCoeffIndex(4 * i + 2));
    +                this.setCoeffIndex(4 * i + 3, engine.getDilithiumGamma1() - this.getCoeffIndex(4 * i + 3));
    +            }
    +        }
    +        else if (engine.getDilithiumGamma1() == (1 << 19))
    +        {
    +            for (i = 0; i < dilithiumN / 2; ++i)
    +            {
    +                this.setCoeffIndex(2 * i + 0,
    +                    (
    +                        (((a[5 * i + 0] & 0xFF)) |
    +                            ((a[5 * i + 1] & 0xFF) << 8)) |
    +                            ((a[5 * i + 2] & 0xFF) << 16)
    +                    ) & 0xFFFFF);
    +                this.setCoeffIndex(2 * i + 1,
    +                    (
    +                        (((a[5 * i + 2] & 0xFF) >> 4) |
    +                            ((a[5 * i + 3] & 0xFF) << 4)) |
    +                            ((a[5 * i + 4] & 0xFF) << 12)
    +                    ) & 0xFFFFF);
    +
    +                this.setCoeffIndex(2 * i + 0, engine.getDilithiumGamma1() - this.getCoeffIndex(2 * i + 0));
    +                this.setCoeffIndex(2 * i + 1, engine.getDilithiumGamma1() - this.getCoeffIndex(2 * i + 1));
    +            }
    +        }
    +        else
    +        {
    +            throw new RuntimeException("Wrong Dilithiumn Gamma1!");
    +        }
    +    }
    +
    +    public void decompose(Poly a)
    +    {
    +        int i;
    +        for (i = 0; i < dilithiumN; ++i)
    +        {
    +            int[] decomp = Rounding.decompose(this.getCoeffIndex(i), engine.getDilithiumGamma2());
    +            this.setCoeffIndex(i, decomp[1]);
    +            a.setCoeffIndex(i, decomp[0]);
    +        }
    +    }
    +
    +    public byte[] w1Pack()
    +    {
    +        int i;
    +
    +        byte[] out = new byte[engine.getDilithiumPolyW1PackedBytes()];
    +
    +        if (engine.getDilithiumGamma2() == (MLDSAEngine.DilithiumQ - 1) / 88)
    +        {
    +            for (i = 0; i < dilithiumN / 4; ++i)
    +            {
    +                out[3 * i + 0] = (byte)(((byte)this.getCoeffIndex(4 * i + 0)) | (this.getCoeffIndex(4 * i + 1) << 6));
    +                out[3 * i + 1] = (byte)((byte)(this.getCoeffIndex(4 * i + 1) >> 2) | (this.getCoeffIndex(4 * i + 2) << 4));
    +                out[3 * i + 2] = (byte)((byte)(this.getCoeffIndex(4 * i + 2) >> 4) | (this.getCoeffIndex(4 * i + 3) << 2));
    +            }
    +        }
    +        else if (engine.getDilithiumGamma2() == (MLDSAEngine.DilithiumQ - 1) / 32)
    +        {
    +            for (i = 0; i < dilithiumN / 2; ++i)
    +            {
    +                out[i] = (byte)(this.getCoeffIndex(2 * i + 0) | (this.getCoeffIndex(2 * i + 1) << 4));
    +            }
    +        }
    +
    +        return out;
    +    }
    +
    +    public void challenge(byte[] seed)
    +    {
    +        int i, b = 0, pos;
    +        long signs;
    +        byte[] buf = new byte[symmetric.stream256BlockBytes];
    +
    +        SHAKEDigest shake256Digest = new SHAKEDigest(256);
    +        shake256Digest.update(seed, 0, engine.getDilithiumCTilde());
    +        shake256Digest.doOutput(buf, 0, symmetric.stream256BlockBytes);
    +
    +        signs = (long)0;
    +        for (i = 0; i < 8; ++i)
    +        {
    +            signs |= (long)(buf[i] & 0xFF) << 8 * i;
    +        }
    +
    +        pos = 8;
    +
    +        for (i = 0; i < dilithiumN; ++i)
    +        {
    +            this.setCoeffIndex(i, 0);
    +        }
    +        for (i = dilithiumN - engine.getDilithiumTau(); i < dilithiumN; ++i)
    +        {
    +            do
    +            {
    +                if (pos >= symmetric.stream256BlockBytes)
    +                {
    +                    shake256Digest.doOutput(buf, 0, symmetric.stream256BlockBytes);
    +                    pos = 0;
    +                }
    +                b = (buf[pos++] & 0xFF);
    +            }
    +            while (b > i);
    +
    +            this.setCoeffIndex(i, this.getCoeffIndex(b));
    +            this.setCoeffIndex(b, (int)(1 - 2 * (signs & 1)));
    +            signs = (long)(signs >> 1);
    +        }
    +    }
    +
    +    public boolean checkNorm(int B)
    +    {
    +        int i, t;
    +
    +        if (B > (MLDSAEngine.DilithiumQ - 1) / 8)
    +        {
    +            return true;
    +        }
    +
    +        for (i = 0; i < dilithiumN; ++i)
    +        {
    +            t = this.getCoeffIndex(i) >> 31;
    +            t = this.getCoeffIndex(i) - (t & 2 * this.getCoeffIndex(i));
    +
    +            if (t >= B)
    +            {
    +                return true;
    +            }
    +        }
    +        return false;
    +    }
    +
    +    public void subtract(Poly inpPoly)
    +    {
    +        for (int i = 0; i < dilithiumN; ++i)
    +        {
    +            this.setCoeffIndex(i, this.getCoeffIndex(i) - inpPoly.getCoeffIndex(i));
    +        }
    +    }
    +
    +    public int polyMakeHint(Poly a0, Poly a1)
    +    {
    +        int i, s = 0;
    +
    +        for (i = 0; i < dilithiumN; ++i)
    +        {
    +            this.setCoeffIndex(i, Rounding.makeHint(a0.getCoeffIndex(i), a1.getCoeffIndex(i), engine));
    +            s += this.getCoeffIndex(i);
    +        }
    +        return s;
    +    }
    +
    +    public void polyUseHint(Poly a, Poly h)
    +    {
    +        for (int i = 0; i < dilithiumN; ++i)
    +        {
    +            this.setCoeffIndex(i, Rounding.useHint(a.getCoeffIndex(i), h.getCoeffIndex(i), engine.getDilithiumGamma2()));
    +        }
    +    }
    +
    +    public byte[] zPack()
    +    {
    +        byte[] outBytes = new byte[engine.getDilithiumPolyZPackedBytes()];
    +        int i;
    +        int[] t = new int[4];
    +        if (engine.getDilithiumGamma1() == (1 << 17))
    +        {
    +            for (i = 0; i < dilithiumN / 4; ++i)
    +            {
    +                t[0] = engine.getDilithiumGamma1() - this.getCoeffIndex(4 * i + 0);
    +                t[1] = engine.getDilithiumGamma1() - this.getCoeffIndex(4 * i + 1);
    +                t[2] = engine.getDilithiumGamma1() - this.getCoeffIndex(4 * i + 2);
    +                t[3] = engine.getDilithiumGamma1() - this.getCoeffIndex(4 * i + 3);
    +
    +                outBytes[9 * i + 0] = (byte)t[0];
    +                outBytes[9 * i + 1] = (byte)(t[0] >> 8);
    +                outBytes[9 * i + 2] = (byte)((byte)(t[0] >> 16) | (t[1] << 2));
    +                outBytes[9 * i + 3] = (byte)(t[1] >> 6);
    +                outBytes[9 * i + 4] = (byte)((byte)(t[1] >> 14) | (t[2] << 4));
    +                outBytes[9 * i + 5] = (byte)(t[2] >> 4);
    +                outBytes[9 * i + 6] = (byte)((byte)(t[2] >> 12) | (t[3] << 6));
    +                outBytes[9 * i + 7] = (byte)(t[3] >> 2);
    +                outBytes[9 * i + 8] = (byte)(t[3] >> 10);
    +            }
    +        }
    +        else if (engine.getDilithiumGamma1() == (1 << 19))
    +        {
    +            for (i = 0; i < dilithiumN / 2; ++i)
    +            {
    +                t[0] = engine.getDilithiumGamma1() - this.getCoeffIndex(2 * i + 0);
    +                t[1] = engine.getDilithiumGamma1() - this.getCoeffIndex(2 * i + 1);
    +
    +                outBytes[5 * i + 0] = (byte)t[0];
    +                outBytes[5 * i + 1] = (byte)(t[0] >> 8);
    +                outBytes[5 * i + 2] = (byte)((byte)(t[0] >> 16) | (t[1] << 4));
    +                outBytes[5 * i + 3] = (byte)(t[1] >> 4);
    +                outBytes[5 * i + 4] = (byte)(t[1] >> 12);
    +
    +            }
    +        }
    +        else
    +        {
    +            throw new RuntimeException("Wrong Dilithium Gamma1!");
    +        }
    +        return outBytes;
    +    }
    +
    +    void zUnpack(byte[] a)
    +    {
    +        int i;
    +        if (engine.getDilithiumGamma1() == (1 << 17))
    +        {
    +            for (i = 0; i < dilithiumN / 4; ++i)
    +            {
    +                this.setCoeffIndex(4 * i + 0,
    +                    (((int)(a[9 * i + 0] & 0xFF)
    +                        | (int)((a[9 * i + 1] & 0xFF) << 8))
    +                        | (int)((a[9 * i + 2] & 0xFF) << 16))
    +                        & 0x3FFFF);
    +
    +                this.setCoeffIndex(4 * i + 1,
    +                    (((int)((a[9 * i + 2] & 0xFF) >>> 2)
    +                        | (int)((a[9 * i + 3] & 0xFF) << 6))
    +                        | (int)((a[9 * i + 4] & 0xFF) << 14))
    +                        & 0x3FFFF);
    +
    +                this.setCoeffIndex(4 * i + 2,
    +                    (((int)((a[9 * i + 4] & 0xFF) >>> 4)
    +                        | (int)((a[9 * i + 5] & 0xFF) << 4))
    +                        | (int)((a[9 * i + 6] & 0xFF) << 12))
    +                        & 0x3FFFF);
    +
    +                this.setCoeffIndex(4 * i + 3,
    +                    (((int)((a[9 * i + 6] & 0xFF) >>> 6)
    +                        | (int)((a[9 * i + 7] & 0xFF) << 2))
    +                        | (int)((a[9 * i + 8] & 0xFF) << 10))
    +                        & 0x3FFFF);
    +
    +                this.setCoeffIndex(4 * i + 0, engine.getDilithiumGamma1() - this.getCoeffIndex(4 * i + 0));
    +                this.setCoeffIndex(4 * i + 1, engine.getDilithiumGamma1() - this.getCoeffIndex(4 * i + 1));
    +                this.setCoeffIndex(4 * i + 2, engine.getDilithiumGamma1() - this.getCoeffIndex(4 * i + 2));
    +                this.setCoeffIndex(4 * i + 3, engine.getDilithiumGamma1() - this.getCoeffIndex(4 * i + 3));
    +            }
    +        }
    +        else if (engine.getDilithiumGamma1() == (1 << 19))
    +        {
    +            for (i = 0; i < dilithiumN / 2; ++i)
    +            {
    +                this.setCoeffIndex(2 * i + 0,
    +                    (int)(((((int)(a[5 * i + 0] & 0xFF))
    +                        | (int)((a[5 * i + 1] & 0xFF) << 8))
    +                        | (int)((a[5 * i + 2] & 0xFF) << 16))
    +                        & 0xFFFFF)
    +                );
    +
    +                this.setCoeffIndex(2 * i + 1,
    +                    (int)(((((int)((a[5 * i + 2] & 0xFF) >>> 4))
    +                        | (int)((a[5 * i + 3] & 0xFF) << 4))
    +                        | (int)((a[5 * i + 4] & 0xFF) << 12))
    +                        & 0xFFFFF)
    +                );
    +
    +                this.setCoeffIndex(2 * i + 0, engine.getDilithiumGamma1() - this.getCoeffIndex(2 * i + 0));
    +                this.setCoeffIndex(2 * i + 1, engine.getDilithiumGamma1() - this.getCoeffIndex(2 * i + 1));
    +            }
    +        }
    +        else
    +        {
    +            throw new RuntimeException("Wrong Dilithium Gamma1!");
    +        }
    +    }
    +
    +    public void shiftLeft()
    +    {
    +        for (int i = 0; i < dilithiumN; ++i)
    +        {
    +            this.setCoeffIndex(i, this.getCoeffIndex(i) << MLDSAEngine.DilithiumD);
    +        }
    +    }
    +
    +    public String toString()
    +    {
    +        StringBuffer out = new StringBuffer();
    +        out.append("[");
    +        for (int i = 0; i < coeffs.length; i++)
    +        {
    +            out.append(coeffs[i]);
    +            if (i != coeffs.length - 1)
    +            {
    +                out.append(", ");
    +            }
    +        }
    +        out.append("]");
    +        return out.toString();
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/PolyVecK.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/PolyVecK.java
    new file mode 100644
    index 0000000000..ec8890056e
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/PolyVecK.java
    @@ -0,0 +1,198 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +class PolyVecK
    +{
    +    Poly[] vec;
    +    private MLDSAEngine engine;
    +    private int mode;
    +    private int polyVecBytes;
    +    private int dilithiumK;
    +    private int dilithiumL;
    +
    +    public PolyVecK(MLDSAEngine engine)
    +    {
    +        this.engine = engine;
    +        this.mode = engine.getDilithiumMode();
    +        this.dilithiumK = engine.getDilithiumK();
    +        this.dilithiumL = engine.getDilithiumL();
    +
    +        this.vec = new Poly[dilithiumK];
    +        for (int i = 0; i < dilithiumK; i++)
    +        {
    +            vec[i] = new Poly(engine);
    +        }
    +    }
    +
    +    public PolyVecK()
    +        throws Exception
    +    {
    +        throw new Exception("Requires Parameter");
    +    }
    +
    +    public Poly getVectorIndex(int i)
    +    {
    +        return vec[i];
    +    }
    +
    +    public void setVectorIndex(int i, Poly p)
    +    {
    +        this.vec[i] = p;
    +    }
    +
    +    public void uniformEta(byte[] seed, short nonce)
    +    {
    +        int i;
    +        short n = nonce;
    +        for (i = 0; i < dilithiumK; ++i)
    +        {
    +            getVectorIndex(i).uniformEta(seed, n++);
    +        }
    +
    +    }
    +
    +    public void reduce()
    +    {
    +        for (int i = 0; i < dilithiumK; ++i)
    +        {
    +            this.getVectorIndex(i).reduce();
    +        }
    +    }
    +
    +    public void invNttToMont()
    +    {
    +        for (int i = 0; i < dilithiumK; ++i)
    +        {
    +            this.getVectorIndex(i).invNttToMont();
    +        }
    +    }
    +
    +    public void addPolyVecK(PolyVecK b)
    +    {
    +        for (int i = 0; i < dilithiumK; ++i)
    +        {
    +            this.getVectorIndex(i).addPoly(b.getVectorIndex(i));
    +        }
    +    }
    +
    +    public void conditionalAddQ()
    +    {
    +        for (int i = 0; i < dilithiumK; ++i)
    +        {
    +            this.getVectorIndex(i).conditionalAddQ();
    +        }
    +    }
    +
    +    public void power2Round(PolyVecK pvk)
    +    {
    +        for (int i = 0; i < dilithiumK; ++i)
    +        {
    +            this.getVectorIndex(i).power2Round(pvk.getVectorIndex(i));
    +        }
    +    }
    +
    +    public void polyVecNtt()
    +    {
    +        int i;
    +        for (i = 0; i < dilithiumK; ++i)
    +        {
    +            this.vec[i].polyNtt();
    +        }
    +    }
    +
    +    public void decompose(PolyVecK v)
    +    {
    +        for (int i = 0; i < dilithiumK; ++i)
    +        {
    +            this.getVectorIndex(i).decompose(v.getVectorIndex(i));
    +        }
    +    }
    +
    +    public byte[] packW1()
    +    {
    +        byte[] out = new byte[dilithiumK * engine.getDilithiumPolyW1PackedBytes()];
    +        int i;
    +        for (i = 0; i < dilithiumK; ++i)
    +        {
    +            System.arraycopy(this.getVectorIndex(i).w1Pack(), 0, out, i * engine.getDilithiumPolyW1PackedBytes(), engine.getDilithiumPolyW1PackedBytes());
    +        }
    +        return out;
    +    }
    +
    +    public void pointwisePolyMontgomery(Poly a, PolyVecK v)
    +    {
    +        for (int i = 0; i < dilithiumK; ++i)
    +        {
    +            this.getVectorIndex(i).pointwiseMontgomery(a, v.getVectorIndex(i));
    +        }
    +    }
    +
    +    public void subtract(PolyVecK inpVec)
    +    {
    +        for (int i = 0; i < dilithiumK; ++i)
    +        {
    +            this.getVectorIndex(i).subtract(inpVec.getVectorIndex(i));
    +        }
    +    }
    +
    +    public boolean checkNorm(int bound)
    +    {
    +        for (int i = 0; i < dilithiumK; ++i)
    +        {
    +            if (this.getVectorIndex(i).checkNorm(bound))
    +            {
    +                return true;
    +            }
    +        }
    +
    +        return false;
    +    }
    +
    +    public int makeHint(PolyVecK v0, PolyVecK v1)
    +    {
    +        int i, s = 0;
    +        for (i = 0; i < dilithiumK; ++i)
    +        {
    +            s += this.getVectorIndex(i).polyMakeHint(v0.getVectorIndex(i), v1.getVectorIndex(i));
    +        }
    +
    +        return s;
    +    }
    +
    +    public void useHint(PolyVecK u, PolyVecK h)
    +    {
    +        for (int i = 0; i < dilithiumK; ++i)
    +        {
    +            this.getVectorIndex(i).polyUseHint(u.getVectorIndex(i), h.getVectorIndex(i));
    +        }
    +    }
    +
    +    public void shiftLeft()
    +    {
    +        for (int i = 0; i < dilithiumK; ++i)
    +        {
    +            this.getVectorIndex(i).shiftLeft();
    +        }
    +    }
    +
    +    @Override
    +    public String toString()
    +    {
    +        String out = "[";
    +        for (int i = 0; i < dilithiumK; i++)
    +        {
    +            out += i + " " + this.getVectorIndex(i).toString();
    +            if (i == dilithiumK - 1)
    +            {
    +                continue;
    +            }
    +            out += ",\n";
    +        }
    +        out += "]";
    +        return out;
    +    }
    +
    +    public String toString(String name)
    +    {
    +        return name + ": " + this.toString();
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/PolyVecL.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/PolyVecL.java
    new file mode 100644
    index 0000000000..1bff4cfd37
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/PolyVecL.java
    @@ -0,0 +1,152 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +class PolyVecL
    +{
    +    Poly[] vec;
    +    private MLDSAEngine engine;
    +    private int mode;
    +    private int polyVecBytes;
    +    private int dilithiumL;
    +    private int dilithiumK;
    +
    +    public PolyVecL(MLDSAEngine engine)
    +    {
    +        this.engine = engine;
    +        this.mode = engine.getDilithiumMode();
    +        this.dilithiumL = engine.getDilithiumL();
    +        this.dilithiumK = engine.getDilithiumK();
    +
    +        this.vec = new Poly[dilithiumL];
    +        for (int i = 0; i < dilithiumL; i++)
    +        {
    +            vec[i] = new Poly(engine);
    +        }
    +    }
    +
    +    public PolyVecL()
    +        throws Exception
    +    {
    +        throw new Exception("Requires Parameter");
    +    }
    +
    +    public Poly getVectorIndex(int i)
    +    {
    +        return vec[i];
    +    }
    +
    +    public void expandMatrix(byte[] rho, int i)
    +    {
    +        int j;
    +        for (j = 0; j < dilithiumL; j++)
    +        {
    +            vec[j].uniformBlocks(rho, (short)((i << 8) + j));
    +        }
    +    }
    +
    +    public void uniformEta(byte[] seed, short nonce)
    +    {
    +        int i;
    +        short n = nonce;
    +        for (i = 0; i < dilithiumL; ++i)
    +        {
    +            getVectorIndex(i).uniformEta(seed, n++);
    +        }
    +
    +    }
    +
    +    public void copyPolyVecL(PolyVecL outPoly)
    +    {
    +        for (int i = 0; i < dilithiumL; i++)
    +        {
    +            for (int j = 0; j < MLDSAEngine.DilithiumN; j++)
    +            {
    +                outPoly.getVectorIndex(i).setCoeffIndex(j, this.getVectorIndex(i).getCoeffIndex(j));
    +            }
    +        }
    +    }
    +
    +    public void polyVecNtt()
    +    {
    +        int i;
    +        for (i = 0; i < dilithiumL; ++i)
    +        {
    +            this.vec[i].polyNtt();
    +        }
    +    }
    +
    +    public void uniformGamma1(byte[] seed, short nonce)
    +    {
    +        int i;
    +        for (i = 0; i < dilithiumL; ++i)
    +        {
    +            this.getVectorIndex(i).uniformGamma1(seed, (short)(dilithiumL * nonce + i));
    +        }
    +
    +    }
    +
    +    public void pointwisePolyMontgomery(Poly a, PolyVecL v)
    +    {
    +        for (int i = 0; i < dilithiumL; ++i)
    +        {
    +            this.getVectorIndex(i).pointwiseMontgomery(a, v.getVectorIndex(i));
    +        }
    +    }
    +
    +    public void invNttToMont()
    +    {
    +        for (int i = 0; i < dilithiumL; ++i)
    +        {
    +            this.getVectorIndex(i).invNttToMont();
    +        }
    +    }
    +
    +    public void addPolyVecL(PolyVecL v)
    +    {
    +        for (int i = 0; i < dilithiumL; ++i)
    +        {
    +            this.getVectorIndex(i).addPoly(v.getVectorIndex(i));
    +        }
    +    }
    +
    +    public void reduce()
    +    {
    +        for (int i = 0; i < dilithiumL; ++i)
    +        {
    +            this.getVectorIndex(i).reduce();
    +        }
    +    }
    +
    +    public boolean checkNorm(int bound)
    +    {
    +        for (int i = 0; i < dilithiumL; ++i)
    +        {
    +            if (this.getVectorIndex(i).checkNorm(bound))
    +            {
    +                return true;
    +            }
    +        }
    +        return false;
    +    }
    +
    +    @Override
    +    public String toString()
    +    {
    +        String out = "\n[";
    +        for (int i = 0; i < dilithiumL; i++)
    +        {
    +            out += "Inner Matrix " + i + " " + this.getVectorIndex(i).toString();
    +            if (i == dilithiumL - 1)
    +            {
    +                continue;
    +            }
    +            out += ",\n";
    +        }
    +        out += "]";
    +        return out;
    +    }
    +
    +    public String toString(String name)
    +    {
    +        return name + ": " + this.toString();
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/PolyVecMatrix.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/PolyVecMatrix.java
    new file mode 100644
    index 0000000000..d1d36a58de
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/PolyVecMatrix.java
    @@ -0,0 +1,71 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +class PolyVecMatrix
    +{
    +    private final int dilithiumK;
    +    private final int dilithiumL;
    +
    +    private final PolyVecL[] mat;
    +
    +    /**
    +     * PolyVecL Matrix of size K
    +     *
    +     * @param engine source engine for the matrix to be used by.
    +     */
    +    public PolyVecMatrix(MLDSAEngine engine)
    +    {
    +        this.dilithiumK = engine.getDilithiumK();
    +        this.dilithiumL = engine.getDilithiumL();
    +        this.mat = new PolyVecL[dilithiumK];
    +
    +        for (int i = 0; i < dilithiumK; i++)
    +        {
    +            mat[i] = new PolyVecL(engine);
    +        }
    +    }
    +
    +    public void pointwiseMontgomery(PolyVecK t, PolyVecL v)
    +    {
    +        int i;
    +        for (i = 0; i < dilithiumK; ++i)
    +        {
    +            t.getVectorIndex(i).pointwiseAccountMontgomery(mat[i], v);
    +        }
    +    }
    +
    +    public void expandMatrix(byte[] rho)
    +    {
    +        int i, j;
    +        for (i = 0; i < dilithiumK; ++i)
    +        {
    +            for (j = 0; j < dilithiumL; ++j)
    +            {
    +                this.mat[i].getVectorIndex(j).uniformBlocks(rho, (short)((i << 8) + j));
    +            }
    +        }
    +    }
    +
    +    private String addString()
    +    {
    +        String out = "[";
    +        int i;
    +        for (i = 0; i < dilithiumK; i++)
    +        {
    +            out += "Outer Matrix " + i + " [";
    +            out += this.mat[i].toString();
    +            if (i == dilithiumK - 1)
    +            {
    +                out += "]\n";
    +                continue;
    +            }
    +            out += "],\n";
    +        }
    +        out += "]\n";
    +        return out;
    +    }
    +
    +    public String toString(String name)
    +    {
    +        return name.concat(": \n" + this.addString());
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Reduce.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Reduce.java
    new file mode 100644
    index 0000000000..9ea32ce546
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Reduce.java
    @@ -0,0 +1,28 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +class Reduce
    +{
    +    static int montgomeryReduce(long a)
    +    {
    +        int t;
    +        t = (int)(a * MLDSAEngine.DilithiumQinv);
    +        t = (int)((a - ((long)t) * MLDSAEngine.DilithiumQ) >>> 32);
    +        // System.out.printf("%d, ", t);
    +        return t;
    +
    +    }
    +
    +    static int reduce32(int a)
    +    {
    +        int t;
    +        t = (a + (1 << 22)) >> 23;
    +        t = a - t * MLDSAEngine.DilithiumQ;
    +        return t;
    +    }
    +
    +    static int conditionalAddQ(int a)
    +    {
    +        a += (a >> 31) & MLDSAEngine.DilithiumQ;
    +        return a;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Rounding.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Rounding.java
    new file mode 100644
    index 0000000000..a7428b9c7c
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Rounding.java
    @@ -0,0 +1,90 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +class Rounding
    +{
    +    public static int[] power2Round(int a)
    +    {
    +        int[] out = new int[2];
    +
    +        out[0] = (a + (1 << (MLDSAEngine.DilithiumD - 1)) - 1) >> MLDSAEngine.DilithiumD;
    +        out[1] = a - (out[0] << MLDSAEngine.DilithiumD);
    +        return out;
    +    }
    +
    +    public static int[] decompose(int a, int gamma2)
    +    {
    +        int a1, a0;
    +
    +        a1 = (a + 127) >> 7;
    +        if (gamma2 == (MLDSAEngine.DilithiumQ - 1) / 32)
    +        {
    +            a1 = (a1 * 1025 + (1 << 21)) >> 22;
    +            a1 &= 15;
    +        }
    +        else if (gamma2 == (MLDSAEngine.DilithiumQ - 1) / 88)
    +        {
    +            a1 = (a1 * 11275 + (1 << 23)) >> 24;
    +            a1 ^= ((43 - a1) >> 31) & a1;
    +        }
    +        else
    +        {
    +            throw new RuntimeException("Wrong Gamma2!");
    +        }
    +
    +        a0 = a - a1 * 2 * gamma2;
    +        a0 -= (((MLDSAEngine.DilithiumQ - 1) / 2 - a0) >> 31) & MLDSAEngine.DilithiumQ;
    +        return new int[]{a0, a1};
    +    }
    +
    +    public static int makeHint(int a0, int a1, MLDSAEngine engine)
    +    {
    +        int g2 = engine.getDilithiumGamma2(), q = MLDSAEngine.DilithiumQ;
    +        if (a0 <= g2 || a0 > q - g2 || (a0 == q - g2 && a1 == 0))
    +        {
    +            return 0;
    +        }
    +        return 1;
    +    }
    +
    +    public static int useHint(int a, int hint, int gamma2)
    +    {
    +        int a0, a1;
    +
    +        int[] intArray = decompose(a, gamma2);
    +        a0 = intArray[0];
    +        a1 = intArray[1];
    +        // System.out.printf("a0: %d, a1: %d\n", a0, a1);
    +
    +        if (hint == 0)
    +        {
    +            return a1;
    +        }
    +
    +        if (gamma2 == (MLDSAEngine.DilithiumQ - 1) / 32)
    +        {
    +            if (a0 > 0)
    +            {
    +                return (a1 + 1) & 15;
    +            }
    +            else
    +            {
    +                return (a1 - 1) & 15;
    +            }
    +        }
    +        else if (gamma2 == (MLDSAEngine.DilithiumQ - 1) / 88)
    +        {
    +            if (a0 > 0)
    +            {
    +                return (a1 == 43) ? 0 : a1 + 1;
    +            }
    +            else
    +            {
    +                return (a1 == 0) ? 43 : a1 - 1;
    +            }
    +        }
    +        else
    +        {
    +            throw new RuntimeException("Wrong Gamma2!");
    +        }
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Symmetric.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Symmetric.java
    new file mode 100644
    index 0000000000..1fc4d278b1
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/Symmetric.java
    @@ -0,0 +1,80 @@
    +package org.bouncycastle.pqc.crypto.mldsa;
    +
    +import org.bouncycastle.crypto.digests.SHAKEDigest;
    +
    +abstract class Symmetric
    +{
    +
    +    final int stream128BlockBytes;
    +    final int stream256BlockBytes;
    +
    +    Symmetric(int stream128, int stream256)
    +    {
    +        this.stream128BlockBytes = stream128;
    +        this.stream256BlockBytes = stream256;
    +    }
    +
    +    abstract void stream128init(byte[] seed, short nonce);
    +
    +    abstract void stream256init(byte[] seed, short nonce);
    +
    +    abstract void stream128squeezeBlocks(byte[] output, int offset, int size);
    +
    +    abstract void stream256squeezeBlocks(byte[] output, int offset, int size);
    +
    +    static class ShakeSymmetric
    +        extends Symmetric
    +    {
    +        private final SHAKEDigest digest128;
    +        private final SHAKEDigest digest256;
    +
    +        ShakeSymmetric()
    +        {
    +            super(168, 136);
    +            digest128 = new SHAKEDigest(128);
    +            digest256 = new SHAKEDigest(256);
    +        }
    +
    +        private void streamInit(SHAKEDigest digest, byte[] seed, short nonce)
    +        {
    +            digest.reset();
    +            // byte[] temp = new byte[seed.length + 2];
    +            // System.arraycopy(seed, 0, temp, 0, seed.length);
    +
    +            // temp[seed.length] = (byte) nonce;
    +            // temp[seed.length] = (byte) (nonce >> 8);
    +            byte[] temp = new byte[2];
    +            // System.arraycopy(seed, 0, temp, 0, seed.length);
    +            temp[0] = (byte)nonce;
    +            temp[1] = (byte)(nonce >> 8);
    +
    +            digest.update(seed, 0, seed.length);
    +            digest.update(temp, 0, temp.length);
    +        }
    +
    +
    +        @Override
    +        void stream128init(byte[] seed, short nonce)
    +        {
    +            streamInit(digest128, seed, nonce);
    +        }
    +
    +        @Override
    +        void stream256init(byte[] seed, short nonce)
    +        {
    +            streamInit(digest256, seed, nonce);
    +        }
    +
    +        @Override
    +        void stream128squeezeBlocks(byte[] output, int offset, int size)
    +        {
    +            digest128.doOutput(output, offset, size);
    +        }
    +
    +        @Override
    +        void stream256squeezeBlocks(byte[] output, int offset, int size)
    +        {
    +            digest256.doOutput(output, offset, size);
    +        }
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/CBD.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/CBD.java
    similarity index 91%
    rename from core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/CBD.java
    rename to core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/CBD.java
    index 946cef3f23..a7df3c7fc8 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/CBD.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/CBD.java
    @@ -1,9 +1,9 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    +package org.bouncycastle.pqc.crypto.mlkem;
     
     final class CBD
     {
     
    -    public static void kyberCBD(Poly r, byte[] bytes, int eta)
    +    public static void mlkemCBD(Poly r, byte[] bytes, int eta)
         {
             long t, d;
             int a, b;
    @@ -11,7 +11,7 @@ public static void kyberCBD(Poly r, byte[] bytes, int eta)
             switch (eta)
             {
             case 3:
    -            for (int i = 0; i < KyberEngine.KyberN / 4; i++)
    +            for (int i = 0; i < MLKEMEngine.KyberN / 4; i++)
                 {
                     t = convertByteTo24BitUnsignedInt(bytes, 3 * i);
                     d = t & 0x00249249;
    @@ -28,7 +28,7 @@ public static void kyberCBD(Poly r, byte[] bytes, int eta)
                 break;
             default:
                 // Only for Kyber512 where eta = 2
    -            for (int i = 0; i < KyberEngine.KyberN / 8; i++)
    +            for (int i = 0; i < MLKEMEngine.KyberN / 8; i++)
                 {
                     t = convertByteTo32BitUnsignedInt(bytes, 4 * i); // ? Problem
                     d = t & 0x55555555;
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMEngine.java
    similarity index 71%
    rename from core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberEngine.java
    rename to core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMEngine.java
    index b17bd4f256..356915916e 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberEngine.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMEngine.java
    @@ -1,13 +1,13 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    +package org.bouncycastle.pqc.crypto.mlkem;
     
     import java.security.SecureRandom;
     
     import org.bouncycastle.util.Arrays;
     
    -class KyberEngine
    +class MLKEMEngine
     {
         private SecureRandom random;
    -    private KyberIndCpa indCpa;
    +    private MLKEMIndCpa indCpa;
     
         // constant parameters
         public final static int KyberN = 256;
    @@ -136,7 +136,7 @@ public int getKyberEta1()
             return KyberEta1;
         }
     
    -    public KyberEngine(int k, boolean usingAes)
    +    public MLKEMEngine(int k)
         {
             this.KyberK = k;
             switch (k)
    @@ -145,13 +145,13 @@ public KyberEngine(int k, boolean usingAes)
                 KyberEta1 = 3;
                 KyberPolyCompressedBytes = 128;
                 KyberPolyVecCompressedBytes = k * 320;
    -            sessionKeyLength = 16;
    +            sessionKeyLength = 32;
                 break;
             case 3:
                 KyberEta1 = 2;
                 KyberPolyCompressedBytes = 128;
                 KyberPolyVecCompressedBytes = k * 320;
    -            sessionKeyLength = 24;
    +            sessionKeyLength = 32;
                 break;
             case 4:
                 KyberEta1 = 2;
    @@ -177,16 +177,9 @@ public KyberEngine(int k, boolean usingAes)
             this.CryptoPublicKeyBytes = KyberPublicKeyBytes;
             this.CryptoCipherTextBytes = KyberCipherTextBytes;
     
    -        if(usingAes)
    -        {
    -            symmetric = new Symmetric.AesSymmetric();
    -        }
    -        else
    -        {
    -            symmetric = new Symmetric.ShakeSymmetric();
    -        }
    +        this.symmetric = new Symmetric.ShakeSymmetric();
     
    -        this.indCpa = new KyberIndCpa(this);
    +        this.indCpa = new MLKEMIndCpa(this);
         }
     
         public void init(SecureRandom random)
    @@ -194,9 +187,10 @@ public void init(SecureRandom random)
             this.random = random;
         }
     
    -    public byte[][] generateKemKeyPair()
    +    //Internal functions are deterministic. No randomness is sampled inside them
    +    public byte[][] generateKemKeyPairInternal(byte[] d, byte[] z)
         {
    -        byte[][] indCpaKeyPair = indCpa.generateKeyPair();
    +        byte[][] indCpaKeyPair = indCpa.generateKeyPair(d);
     
             byte[] s = new byte[KyberIndCpaSecretKeyBytes];
     
    @@ -206,78 +200,103 @@ public byte[][] generateKemKeyPair()
     
             symmetric.hash_h(hashedPublicKey, indCpaKeyPair[0], 0);
     
    -        byte[] z = new byte[KyberSymBytes];
    -        random.nextBytes(z);
    -
             byte[] outputPublicKey = new byte[KyberIndCpaPublicKeyBytes];
             System.arraycopy(indCpaKeyPair[0], 0, outputPublicKey, 0, KyberIndCpaPublicKeyBytes);
             return new byte[][]{ Arrays.copyOfRange(outputPublicKey, 0, outputPublicKey.length - 32), Arrays.copyOfRange(outputPublicKey, outputPublicKey.length - 32, outputPublicKey.length), s, hashedPublicKey, z };
         }
     
    -    public byte[][] kemEncrypt(byte[] publicKeyInput)
    +    public byte[][] kemEncryptInternal(byte[] publicKeyInput, byte[] randBytes)
         {
             byte[] outputCipherText;
     
             byte[] buf = new byte[2 * KyberSymBytes];
             byte[] kr = new byte[2 * KyberSymBytes];
     
    -        byte[] randBytes = new byte[KyberSymBytes];
    -
    -        random.nextBytes(randBytes);
    -
    -        // SHA3-256 Random Bytes
    -        symmetric.hash_h(randBytes, randBytes, 0);
             System.arraycopy(randBytes, 0, buf, 0, KyberSymBytes);
     
             // SHA3-256 Public Key
             symmetric.hash_h(buf, publicKeyInput, KyberSymBytes);
     
             // SHA3-512( SHA3-256(RandBytes) || SHA3-256(PublicKey) )
    -
             symmetric.hash_g(kr, buf);
     
             // IndCpa Encryption
    -        outputCipherText = indCpa.encrypt(Arrays.copyOfRange(buf, 0, KyberSymBytes), publicKeyInput, Arrays.copyOfRange(kr, 32, kr.length));
    -
    -        symmetric.hash_h(kr, outputCipherText, KyberSymBytes);
    +        outputCipherText = indCpa.encrypt(publicKeyInput, Arrays.copyOfRange(buf, 0, KyberSymBytes), Arrays.copyOfRange(kr, 32, kr.length));
     
             byte[] outputSharedSecret = new byte[sessionKeyLength];
     
    -        symmetric.kdf(outputSharedSecret, kr);
    +        System.arraycopy(kr, 0, outputSharedSecret, 0, outputSharedSecret.length);
     
             byte[][] outBuf = new byte[2][];
             outBuf[0] = outputSharedSecret;
             outBuf[1] = outputCipherText;
    -
             return outBuf;
         }
     
    -    public byte[] kemDecrypt(byte[] cipherText, byte[] secretKey)
    +    public byte[] kemDecryptInternal(byte[] secretKey, byte[] cipherText)
         {
             byte[] buf = new byte[2 * KyberSymBytes],
    -            kr = new byte[2 * KyberSymBytes];
    +                kr = new byte[2 * KyberSymBytes];
     
             byte[] publicKey = Arrays.copyOfRange(secretKey, KyberIndCpaSecretKeyBytes, secretKey.length);
     
    -        System.arraycopy(indCpa.decrypt(cipherText, secretKey), 0, buf, 0, KyberSymBytes);
    +        System.arraycopy(indCpa.decrypt(secretKey, cipherText), 0, buf, 0, KyberSymBytes);
     
             System.arraycopy(secretKey, KyberSecretKeyBytes - 2 * KyberSymBytes, buf, KyberSymBytes, KyberSymBytes);
     
             symmetric.hash_g(kr, buf);
     
    -        byte[] cmp = indCpa.encrypt(Arrays.copyOfRange(buf, 0, KyberSymBytes), publicKey, Arrays.copyOfRange(kr, KyberSymBytes, kr.length));
    +        byte[] implicit_rejection = new byte[KyberSymBytes + KyberCipherTextBytes];
    +
    +        System.arraycopy(secretKey, KyberSecretKeyBytes - KyberSymBytes, implicit_rejection, 0, KyberSymBytes);
    +
    +        System.arraycopy(cipherText, 0, implicit_rejection, KyberSymBytes, KyberCipherTextBytes);
    +
    +        symmetric.kdf(implicit_rejection, implicit_rejection ); // J(z||c)
    +
    +        byte[] cmp = indCpa.encrypt(publicKey, Arrays.copyOfRange(buf, 0, KyberSymBytes), Arrays.copyOfRange(kr, KyberSymBytes, kr.length));
     
             boolean fail = !(Arrays.constantTimeAreEqual(cipherText, cmp));
     
    -        symmetric.hash_h(kr, cipherText, KyberSymBytes);
    +        cmov(kr, implicit_rejection, KyberSymBytes, fail);
     
    -        cmov(kr, Arrays.copyOfRange(secretKey, KyberSecretKeyBytes - KyberSymBytes, KyberSecretKeyBytes), KyberSymBytes, fail);
    +        return Arrays.copyOfRange(kr, 0, sessionKeyLength);
    +    }
     
    -        byte[] outputSharedSecret = new byte[sessionKeyLength];
    +    public byte[][] generateKemKeyPair()
    +    {
    +        byte[] d = new byte[KyberSymBytes];
    +        byte[] z = new byte[KyberSymBytes];
    +        random.nextBytes(d);
    +        random.nextBytes(z);
     
    -        symmetric.kdf(outputSharedSecret, kr);
    +        return generateKemKeyPairInternal(d, z);
    +    }
     
    -        return outputSharedSecret;
    +    public byte[][] kemEncrypt(byte[] publicKeyInput, byte[] randBytes)
    +    {
    +        //TODO: do input validation elsewhere?
    +        // Input validation (6.2 ML-KEM Encaps)
    +        // Type Check
    +        if (publicKeyInput.length != KyberIndCpaPublicKeyBytes)
    +        {
    +            throw new IllegalArgumentException("Input validation Error: Type check failed for ml-kem encapsulation");
    +        }
    +        // Modulus Check
    +        PolyVec polyVec = new PolyVec(this);
    +        byte[] seed = indCpa.unpackPublicKey(polyVec, publicKeyInput);
    +        byte[] ek = indCpa.packPublicKey(polyVec, seed);
    +        if (!Arrays.areEqual(ek, publicKeyInput))
    +        {
    +            throw new IllegalArgumentException("Input validation: Modulus check failed for ml-kem encapsulation");
    +        }
    +
    +        return kemEncryptInternal(publicKeyInput, randBytes);
    +    }
    +    public byte[] kemDecrypt(byte[] secretKey, byte[] cipherText)
    +    {
    +        //TODO: do input validation
    +        return kemDecryptInternal(secretKey, cipherText);
         }
     
         private void cmov(byte[] r, byte[] x, int xlen, boolean b)
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKEMExtractor.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMExtractor.java
    similarity index 62%
    rename from core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKEMExtractor.java
    rename to core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMExtractor.java
    index bfda4e56a7..90189fee90 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKEMExtractor.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMExtractor.java
    @@ -1,16 +1,16 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    +package org.bouncycastle.pqc.crypto.mlkem;
     
     import org.bouncycastle.crypto.EncapsulatedSecretExtractor;
     import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
     
    -public class KyberKEMExtractor
    +public class MLKEMExtractor
         implements EncapsulatedSecretExtractor
     {
    -    private KyberEngine engine;
    +    private MLKEMEngine engine;
     
    -    private KyberPrivateKeyParameters key;
    +    private MLKEMPrivateKeyParameters key;
     
    -    public KyberKEMExtractor(KyberPrivateKeyParameters privParams)
    +    public MLKEMExtractor(MLKEMPrivateKeyParameters privParams)
         {
             this.key = privParams;
             initCipher(privParams);
    @@ -18,7 +18,7 @@ public KyberKEMExtractor(KyberPrivateKeyParameters privParams)
     
         private void initCipher(AsymmetricKeyParameter recipientKey)
         {
    -        KyberPrivateKeyParameters key = (KyberPrivateKeyParameters)recipientKey;
    +        MLKEMPrivateKeyParameters key = (MLKEMPrivateKeyParameters)recipientKey;
             engine = key.getParameters().getEngine();
         }
     
    @@ -26,7 +26,7 @@ private void initCipher(AsymmetricKeyParameter recipientKey)
         public byte[] extractSecret(byte[] encapsulation)
         {
             // Decryption
    -        byte[] sharedSecret = engine.kemDecrypt(encapsulation, key.getPrivateKey());
    +        byte[] sharedSecret = engine.kemDecrypt(key.getEncoded(), encapsulation);
             return sharedSecret;
         }
     
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMGenerator.java
    new file mode 100644
    index 0000000000..61c693724d
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMGenerator.java
    @@ -0,0 +1,42 @@
    +package org.bouncycastle.pqc.crypto.mlkem;
    +
    +import java.security.SecureRandom;
    +
    +import org.bouncycastle.crypto.EncapsulatedSecretGenerator;
    +import org.bouncycastle.crypto.SecretWithEncapsulation;
    +import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
    +import org.bouncycastle.pqc.crypto.util.SecretWithEncapsulationImpl;
    +
    +public class MLKEMGenerator
    +    implements EncapsulatedSecretGenerator
    +{
    +    // the source of randomness
    +    private final SecureRandom sr;
    +
    +    public MLKEMGenerator(SecureRandom random)
    +    {
    +        this.sr = random;
    +    }
    +
    +    public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey)
    +    {
    +        MLKEMPublicKeyParameters key = (MLKEMPublicKeyParameters)recipientKey;
    +        MLKEMEngine engine = key.getParameters().getEngine();
    +        engine.init(sr);
    +
    +        byte[] randBytes = new byte[32];
    +        engine.getRandomBytes(randBytes);
    +
    +        byte[][] kemEncrypt = engine.kemEncrypt(key.getEncoded(), randBytes);
    +        return new SecretWithEncapsulationImpl(kemEncrypt[0], kemEncrypt[1]);
    +    }
    +    public SecretWithEncapsulation internalGenerateEncapsulated(AsymmetricKeyParameter recipientKey, byte[] randBytes)
    +    {
    +        MLKEMPublicKeyParameters key = (MLKEMPublicKeyParameters)recipientKey;
    +        MLKEMEngine engine = key.getParameters().getEngine();
    +        engine.init(sr);
    +
    +        byte[][] kemEncrypt = engine.kemEncryptInternal(key.getEncoded(), randBytes);
    +        return new SecretWithEncapsulationImpl(kemEncrypt[0], kemEncrypt[1]);
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberIndCpa.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMIndCpa.java
    similarity index 92%
    rename from core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberIndCpa.java
    rename to core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMIndCpa.java
    index 6d826dba6c..33c2cdb1e3 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberIndCpa.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMIndCpa.java
    @@ -1,11 +1,11 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    +package org.bouncycastle.pqc.crypto.mlkem;
     
     import org.bouncycastle.crypto.digests.SHAKEDigest;
     import org.bouncycastle.util.Arrays;
     
    -class KyberIndCpa
    +class MLKEMIndCpa
     {
    -    private KyberEngine engine;
    +    private MLKEMEngine engine;
         private int kyberK;
         private int eta1;
         private int indCpaPublicKeyBytes;
    @@ -16,7 +16,7 @@ class KyberIndCpa
     
         private Symmetric symmetric;
     
    -    public KyberIndCpa(KyberEngine engine)
    +    public MLKEMIndCpa(MLKEMEngine engine)
         {
             this.engine = engine;
             this.kyberK = engine.getKyberK();
    @@ -31,9 +31,9 @@ public KyberIndCpa(KyberEngine engine)
             KyberGenerateMatrixNBlocks =
                 (
                     (
    -                    12 * KyberEngine.KyberN
    +                    12 * MLKEMEngine.KyberN
                             / 8 * (1 << 12)
    -                        / KyberEngine.KyberQ + symmetric.xofBlockBytes
    +                        / MLKEMEngine.KyberQ + symmetric.xofBlockBytes
                     )
                         / symmetric.xofBlockBytes
                 );
    @@ -45,20 +45,18 @@ public KyberIndCpa(KyberEngine engine)
          *
          * @return KeyPair where each key is represented as bytes
          */
    -    public byte[][] generateKeyPair()
    +    byte[][] generateKeyPair(byte[] d)
         {
             PolyVec secretKey = new PolyVec(engine),
                 publicKey = new PolyVec(engine),
                 e = new PolyVec(engine);
     
    -        byte[] d = new byte[32];
    -
    -        // (p, sigma) <- G(d)
    -
    -        engine.getRandomBytes(d);
    +        // (p, sigma) <- G(d || k)
     
             byte[] buf = new byte[64];
    -        symmetric.hash_g(buf, d);
    +        byte[] k = new byte[1];
    +        k[0] = (byte)kyberK;
    +        symmetric.hash_g(buf, Arrays.concatenate(d, k));
     
             byte[] publicSeed = new byte[32]; // p in docs
             byte[] noiseSeed = new byte[32]; // sigma in docs
    @@ -141,7 +139,7 @@ public byte[][] generateKeyPair()
             return new byte[][]{packPublicKey(publicKey, publicSeed), packSecretKey(secretKey)};
         }
     
    -    public byte[] encrypt(byte[] msg, byte[] publicKeyInput, byte[] coins)
    +    public byte[] encrypt(byte[] publicKeyInput, byte[] msg, byte[] coins)
         {
             int i;
             byte[] seed;
    @@ -295,15 +293,15 @@ public byte[] packPublicKey(PolyVec publicKeyPolyVec, byte[] seed)
         {
             byte[] buf = new byte[indCpaPublicKeyBytes];
             System.arraycopy(publicKeyPolyVec.toBytes(), 0, buf, 0, polyVecBytes);
    -        System.arraycopy(seed, 0, buf, polyVecBytes, KyberEngine.KyberSymBytes);
    +        System.arraycopy(seed, 0, buf, polyVecBytes, MLKEMEngine.KyberSymBytes);
             return buf;
         }
     
         public byte[] unpackPublicKey(PolyVec publicKeyPolyVec, byte[] publicKey)
         {
    -        byte[] outputSeed = new byte[KyberEngine.KyberSymBytes];
    +        byte[] outputSeed = new byte[MLKEMEngine.KyberSymBytes];
             publicKeyPolyVec.fromBytes(publicKey);
    -        System.arraycopy(publicKey, polyVecBytes, outputSeed, 0, KyberEngine.KyberSymBytes);
    +        System.arraycopy(publicKey, polyVecBytes, outputSeed, 0, MLKEMEngine.KyberSymBytes);
             return outputSeed;
         }
     
    @@ -339,9 +337,9 @@ public void generateMatrix(PolyVec[] aMatrix, byte[] seed, boolean transposed)
                     symmetric.xofSqueezeBlocks(buf, 0, symmetric.xofBlockBytes * KyberGenerateMatrixNBlocks);
     
                     int buflen = KyberGenerateMatrixNBlocks * symmetric.xofBlockBytes;
    -                ctr = rejectionSampling(aMatrix[i].getVectorIndex(j), 0, KyberEngine.KyberN, buf, buflen);
    +                ctr = rejectionSampling(aMatrix[i].getVectorIndex(j), 0, MLKEMEngine.KyberN, buf, buflen);
     
    -                while (ctr < KyberEngine.KyberN)
    +                while (ctr < MLKEMEngine.KyberN)
                     {
                         off = buflen % 3;
                         for (k = 0; k < off; k++)
    @@ -351,7 +349,7 @@ public void generateMatrix(PolyVec[] aMatrix, byte[] seed, boolean transposed)
                         symmetric.xofSqueezeBlocks(buf, off, symmetric.xofBlockBytes * 2);
                         buflen = off + symmetric.xofBlockBytes;
                         // Error in code Section Unsure
    -                    ctr += rejectionSampling(aMatrix[i].getVectorIndex(j), ctr, KyberEngine.KyberN - ctr, buf, buflen);
    +                    ctr += rejectionSampling(aMatrix[i].getVectorIndex(j), ctr, MLKEMEngine.KyberN - ctr, buf, buflen);
                     }
                 }
             }
    @@ -368,12 +366,12 @@ private static int rejectionSampling(Poly outputBuffer, int coeffOff, int len, b
                 val0 = (short)(((((short)(inpBuf[pos] & 0xFF)) >> 0) | (((short)(inpBuf[pos + 1] & 0xFF)) << 8)) & 0xFFF);
                 val1 = (short)(((((short)(inpBuf[pos + 1] & 0xFF)) >> 4) | (((short)(inpBuf[pos + 2] & 0xFF)) << 4)) & 0xFFF);
                 pos = pos + 3;
    -            if (val0 < (short)KyberEngine.KyberQ)
    +            if (val0 < (short)MLKEMEngine.KyberQ)
                 {
                     outputBuffer.setCoeffIndex(coeffOff + ctr, (short)val0);
                     ctr++;
                 }
    -            if (ctr < len && val1 < (short)KyberEngine.KyberQ)
    +            if (ctr < len && val1 < (short)MLKEMEngine.KyberQ)
                 {
                     outputBuffer.setCoeffIndex(coeffOff + ctr, (short)val1);
                     ctr++;
    @@ -383,10 +381,10 @@ private static int rejectionSampling(Poly outputBuffer, int coeffOff, int len, b
     
         }
     
    -    public byte[] decrypt(byte[] cipherText, byte[] secretKey)
    +    public byte[] decrypt(byte[] secretKey, byte[] cipherText)
         {
             int i;
    -        byte[] outputMessage = new byte[KyberEngine.getKyberIndCpaMsgBytes()];
    +        byte[] outputMessage = new byte[MLKEMEngine.getKyberIndCpaMsgBytes()];
     
             PolyVec bp = new PolyVec(engine), secretKeyPolyVec = new PolyVec(engine);
             Poly v = new Poly(engine), mp = new Poly(engine);
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMKeyGenerationParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMKeyGenerationParameters.java
    new file mode 100644
    index 0000000000..7d92602345
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMKeyGenerationParameters.java
    @@ -0,0 +1,24 @@
    +package org.bouncycastle.pqc.crypto.mlkem;
    +
    +import java.security.SecureRandom;
    +
    +import org.bouncycastle.crypto.KeyGenerationParameters;
    +
    +public class MLKEMKeyGenerationParameters
    +    extends KeyGenerationParameters
    +{
    +    private final MLKEMParameters params;
    +
    +    public MLKEMKeyGenerationParameters(
    +        SecureRandom random,
    +        MLKEMParameters mlkemParameters)
    +    {
    +        super(random, 256);
    +        this.params = mlkemParameters;
    +    }
    +
    +    public MLKEMParameters getParameters()
    +    {
    +        return params;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMKeyPairGenerator.java
    new file mode 100644
    index 0000000000..7c41860151
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMKeyPairGenerator.java
    @@ -0,0 +1,58 @@
    +package org.bouncycastle.pqc.crypto.mlkem;
    +
    +import java.security.SecureRandom;
    +
    +import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
    +import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
    +import org.bouncycastle.crypto.KeyGenerationParameters;
    +
    +public class MLKEMKeyPairGenerator
    +    implements AsymmetricCipherKeyPairGenerator
    +{
    +    private MLKEMParameters mlkemParams;
    +
    +    private SecureRandom random;
    +
    +    private void initialize(
    +        KeyGenerationParameters param)
    +    {
    +        this.mlkemParams = ((MLKEMKeyGenerationParameters)param).getParameters();
    +        this.random = param.getRandom();
    +
    +    }
    +
    +    private AsymmetricCipherKeyPair genKeyPair()
    +    {
    +        MLKEMEngine engine = mlkemParams.getEngine();
    +
    +        engine.init(random);
    +
    +        byte[][] keyPair = engine.generateKemKeyPair();
    +
    +        MLKEMPublicKeyParameters pubKey = new MLKEMPublicKeyParameters(mlkemParams, keyPair[0], keyPair[1]);
    +        MLKEMPrivateKeyParameters privKey = new MLKEMPrivateKeyParameters(mlkemParams,  keyPair[2], keyPair[3], keyPair[4], keyPair[0], keyPair[1]);
    +        
    +        return new AsymmetricCipherKeyPair(pubKey, privKey);
    +    }
    +
    +    public void init(KeyGenerationParameters param)
    +    {
    +        this.initialize(param);
    +    }
    +
    +    public AsymmetricCipherKeyPair generateKeyPair()
    +    {
    +        return genKeyPair();
    +    }
    +
    +    public AsymmetricCipherKeyPair internalGenerateKeyPair(byte[] d, byte[] z)
    +    {
    +        byte[][] keyPair = mlkemParams.getEngine().generateKemKeyPairInternal(d, z);
    +
    +        MLKEMPublicKeyParameters pubKey = new MLKEMPublicKeyParameters(mlkemParams, keyPair[0], keyPair[1]);
    +        MLKEMPrivateKeyParameters privKey = new MLKEMPrivateKeyParameters(mlkemParams,  keyPair[2], keyPair[3], keyPair[4], keyPair[0], keyPair[1]);
    +
    +        return new AsymmetricCipherKeyPair(pubKey, privKey);
    +    }
    +
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMKeyParameters.java
    similarity index 51%
    rename from core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKeyParameters.java
    rename to core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMKeyParameters.java
    index 9fa5567283..227a46c65a 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKeyParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMKeyParameters.java
    @@ -1,21 +1,21 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    +package org.bouncycastle.pqc.crypto.mlkem;
     
     import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
     
    -public class KyberKeyParameters
    +public class MLKEMKeyParameters
         extends AsymmetricKeyParameter
     {
    -    private KyberParameters params;
    +    private MLKEMParameters params;
     
    -    public KyberKeyParameters(
    +    public MLKEMKeyParameters(
             boolean isPrivate,
    -        KyberParameters params)
    +        MLKEMParameters params)
         {
             super(isPrivate);
             this.params = params;
         }
     
    -    public KyberParameters getParameters()
    +    public MLKEMParameters getParameters()
         {
             return params;
         }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMParameters.java
    new file mode 100644
    index 0000000000..0dbc69bece
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMParameters.java
    @@ -0,0 +1,37 @@
    +package org.bouncycastle.pqc.crypto.mlkem;
    +
    +import org.bouncycastle.pqc.crypto.KEMParameters;
    +
    +public class MLKEMParameters
    +    implements KEMParameters
    +{
    +    public static final MLKEMParameters ml_kem_512 = new MLKEMParameters("ML-KEM-512", 2, 256);
    +    public static final MLKEMParameters ml_kem_768 = new MLKEMParameters("ML-KEM-768", 3, 256);
    +    public static final MLKEMParameters ml_kem_1024 = new MLKEMParameters("ML-KEM-1024", 4, 256);
    +
    +    private final String name;
    +    private final int k;
    +    private final int sessionKeySize;
    +
    +    private MLKEMParameters(String name, int k, int sessionKeySize)
    +    {
    +        this.name = name;
    +        this.k = k;
    +        this.sessionKeySize = sessionKeySize;
    +    }
    +
    +    public String getName()
    +    {
    +        return name;
    +    }
    +
    +    public MLKEMEngine getEngine()
    +    {
    +        return new MLKEMEngine(k);
    +    }
    +
    +    public int getSessionKeySize()
    +    {
    +        return sessionKeySize;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPrivateKeyParameters.java
    new file mode 100644
    index 0000000000..75a2e56c04
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPrivateKeyParameters.java
    @@ -0,0 +1,77 @@
    +package org.bouncycastle.pqc.crypto.mlkem;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +public class MLKEMPrivateKeyParameters
    +    extends MLKEMKeyParameters
    +{
    +    final byte[] s;
    +    final byte[] hpk;
    +    final byte[] nonce;
    +    final byte[] t;
    +    final byte[] rho;
    +
    +    public MLKEMPrivateKeyParameters(MLKEMParameters params, byte[] s, byte[] hpk, byte[] nonce, byte[] t, byte[] rho)
    +    {
    +        super(true, params);
    +
    +        this.s = Arrays.clone(s);
    +        this.hpk = Arrays.clone(hpk);
    +        this.nonce = Arrays.clone(nonce);
    +        this.t = Arrays.clone(t);
    +        this.rho = Arrays.clone(rho);
    +    }
    +
    +    public MLKEMPrivateKeyParameters(MLKEMParameters params, byte[] encoding)
    +    {
    +        super(true, params);
    +
    +        MLKEMEngine eng = params.getEngine();
    +        int index = 0;
    +        this.s = Arrays.copyOfRange(encoding, 0, eng.getKyberIndCpaSecretKeyBytes()); index += eng.getKyberIndCpaSecretKeyBytes();
    +        this.t = Arrays.copyOfRange(encoding, index, index + eng.getKyberIndCpaPublicKeyBytes() - MLKEMEngine.KyberSymBytes); index += eng.getKyberIndCpaPublicKeyBytes() - MLKEMEngine.KyberSymBytes;
    +        this.rho = Arrays.copyOfRange(encoding, index, index + 32); index += 32;
    +        this.hpk = Arrays.copyOfRange(encoding, index, index + 32); index += 32;
    +        this.nonce = Arrays.copyOfRange(encoding, index, index + MLKEMEngine.KyberSymBytes);
    +    }
    +
    +    public byte[] getEncoded()
    +    {
    +        return Arrays.concatenate(new byte[][]{ s, t, rho, hpk, nonce });
    +    }
    +
    +    public byte[] getHPK()
    +    {
    +        return Arrays.clone(hpk);
    +    }
    +
    +    public byte[] getNonce()
    +    {
    +        return Arrays.clone(nonce);
    +    }
    +
    +    public byte[] getPublicKey()
    +    {
    +        return MLKEMPublicKeyParameters.getEncoded(t, rho);
    +    }
    +
    +    public MLKEMPublicKeyParameters getPublicKeyParameters()
    +    {
    +        return new MLKEMPublicKeyParameters(getParameters(), t, rho);
    +    }
    +
    +    public byte[] getRho()
    +    {
    +        return Arrays.clone(rho);
    +    }
    +
    +    public byte[] getS()
    +    {
    +        return Arrays.clone(s);
    +    }
    +
    +    public byte[] getT()
    +    {
    +        return Arrays.clone(t);
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberPublicKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPublicKeyParameters.java
    similarity index 61%
    rename from core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberPublicKeyParameters.java
    rename to core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPublicKeyParameters.java
    index 0e4f596693..5f2676d730 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberPublicKeyParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPublicKeyParameters.java
    @@ -1,44 +1,44 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    +package org.bouncycastle.pqc.crypto.mlkem;
     
     import org.bouncycastle.util.Arrays;
     
    -public class KyberPublicKeyParameters
    -    extends KyberKeyParameters
    +public class MLKEMPublicKeyParameters
    +    extends MLKEMKeyParameters
     {
    -    final byte[] t;
    -    final byte[] rho;
    -
    -    public byte[] getPublicKey()
    +    static byte[] getEncoded(byte[] t, byte[] rho)
         {
             return Arrays.concatenate(t, rho);
         }
     
    -    public byte[] getEncoded()
    -    {
    -        return getPublicKey();
    -    }
    +    final byte[] t;
    +    final byte[] rho;
     
    -    public KyberPublicKeyParameters(KyberParameters params, byte[] t, byte[] rho)
    +    public MLKEMPublicKeyParameters(MLKEMParameters params, byte[] t, byte[] rho)
         {
             super(false, params);
             this.t = Arrays.clone(t);
             this.rho = Arrays.clone(rho);
         }
     
    -    public KyberPublicKeyParameters(KyberParameters params, byte[] encoding)
    +    public MLKEMPublicKeyParameters(MLKEMParameters params, byte[] encoding)
         {
             super(false, params);
    -        this.t = Arrays.copyOfRange(encoding, 0, encoding.length - KyberEngine.KyberSymBytes);
    -        this.rho = Arrays.copyOfRange(encoding, encoding.length - KyberEngine.KyberSymBytes, encoding.length);
    +        this.t = Arrays.copyOfRange(encoding, 0, encoding.length - MLKEMEngine.KyberSymBytes);
    +        this.rho = Arrays.copyOfRange(encoding, encoding.length - MLKEMEngine.KyberSymBytes, encoding.length);
         }
     
    -    public byte[] getT()
    +    public byte[] getEncoded()
         {
    -        return Arrays.clone(t);
    +        return getEncoded(t, rho);
         }
     
         public byte[] getRho()
         {
             return Arrays.clone(rho);
         }
    +
    +    public byte[] getT()
    +    {
    +        return Arrays.clone(t);
    +    }
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/Ntt.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Ntt.java
    similarity index 94%
    rename from core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/Ntt.java
    rename to core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Ntt.java
    index c16cf71637..100647de08 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/Ntt.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Ntt.java
    @@ -1,4 +1,4 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    +package org.bouncycastle.pqc.crypto.mlkem;
     
     class Ntt
     {
    @@ -29,7 +29,7 @@ class Ntt
     
         public static short[] ntt(short[] inp)
         {
    -        short[] r = new short[KyberEngine.KyberN];
    +        short[] r = new short[MLKEMEngine.KyberN];
             System.arraycopy(inp, 0, r, 0, r.length);
             int len, start, j, k;
             short t, zeta;
    @@ -53,8 +53,8 @@ public static short[] ntt(short[] inp)
     
         public static short[] invNtt(short[] inp)
         {
    -        short[] r = new short[KyberEngine.KyberN];
    -        System.arraycopy(inp, 0, r, 0, KyberEngine.KyberN);
    +        short[] r = new short[MLKEMEngine.KyberN];
    +        System.arraycopy(inp, 0, r, 0, MLKEMEngine.KyberN);
             int len, start, j, k;
             short t, zeta;
             k = 0;
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/Poly.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Poly.java
    similarity index 73%
    rename from core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/Poly.java
    rename to core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Poly.java
    index e976f8f00d..d7402a5ea7 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/Poly.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Poly.java
    @@ -1,22 +1,22 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    +package org.bouncycastle.pqc.crypto.mlkem;
     
     class Poly
     {
         private short[] coeffs;
    -    private KyberEngine engine;
    +    private MLKEMEngine engine;
         private int polyCompressedBytes;
         private int eta1;
         private int eta2;
     
         private Symmetric symmetric;
     
    -    public Poly(KyberEngine engine)
    +    public Poly(MLKEMEngine engine)
         {
    -        this.coeffs = new short[KyberEngine.KyberN];
    +        this.coeffs = new short[MLKEMEngine.KyberN];
             this.engine = engine;
             polyCompressedBytes = engine.getKyberPolyCompressedBytes();
             this.eta1 = engine.getKyberEta1();
    -        this.eta2 = KyberEngine.getKyberEta2();
    +        this.eta2 = MLKEMEngine.getKyberEta2();
             this.symmetric = engine.getSymmetric();
         }
     
    @@ -54,7 +54,7 @@ public void polyInverseNttToMont()
         public void reduce()
         {
             int i;
    -        for (i = 0; i < KyberEngine.KyberN; i++)
    +        for (i = 0; i < MLKEMEngine.KyberN; i++)
             {
                 this.setCoeffIndex(i, Reduce.barretReduce(this.getCoeffIndex(i)));
             }
    @@ -63,7 +63,7 @@ public void reduce()
         public static void baseMultMontgomery(Poly r, Poly a, Poly b)
         {
             int i;
    -        for (i = 0; i < KyberEngine.KyberN / 4; i++)
    +        for (i = 0; i < MLKEMEngine.KyberN / 4; i++)
             {
                 Ntt.baseMult(r, 4 * i,
                     a.getCoeffIndex(4 * i), a.getCoeffIndex(4 * i + 1),
    @@ -79,7 +79,7 @@ public static void baseMultMontgomery(Poly r, Poly a, Poly b)
         public void addCoeffs(Poly b)
         {
             int i;
    -        for (i = 0; i < KyberEngine.KyberN; i++)
    +        for (i = 0; i < MLKEMEngine.KyberN; i++)
             {
                 this.setCoeffIndex(i, (short)(this.getCoeffIndex(i) + b.getCoeffIndex(i)));
             }
    @@ -88,8 +88,8 @@ public void addCoeffs(Poly b)
         public void convertToMont()
         {
             int i;
    -        final short f = (short)(((long)1 << 32) % KyberEngine.KyberQ);
    -        for (i = 0; i < KyberEngine.KyberN; i++)
    +        final short f = (short)(((long)1 << 32) % MLKEMEngine.KyberQ);
    +        for (i = 0; i < MLKEMEngine.KyberN; i++)
             {
                 this.setCoeffIndex(i, Reduce.montgomeryReduce(this.getCoeffIndex(i) * f));
             }
    @@ -109,16 +109,25 @@ public byte[] compressPoly()
     
             if (polyCompressedBytes == 128)
             {
    -            for (i = 0; i < KyberEngine.KyberN / 8; i++)
    +            for (i = 0; i < MLKEMEngine.KyberN / 8; i++)
                 {
                     for (j = 0; j < 8; j++)
                     {
    -                    t[j] =
    +                    /*t[j] =
                             (byte)((((((short)this.getCoeffIndex(8 * i + j)) << 4)
                                 +
                                 (KyberEngine.KyberQ / 2)
                             ) / KyberEngine.KyberQ)
    -                            & 15);
    +                            & 15);*/
    +                    // Fix for KyberSlash2: division by KyberQ above is not
    +                    // constant time.
    +                    int t_j = this.getCoeffIndex(8 * i + j);
    +                    t_j <<= 4;
    +                    t_j += 1665;
    +                    t_j *= 80635;
    +                    t_j >>= 28;
    +                    t_j &= 15;
    +                    t[j] = (byte)t_j;
                     }
     
                     r[count + 0] = (byte)(t[0] | (t[1] << 4));
    @@ -130,17 +139,26 @@ public byte[] compressPoly()
             }
             else if (polyCompressedBytes == 160)
             {
    -            for (i = 0; i < KyberEngine.KyberN / 8; i++)
    +            for (i = 0; i < MLKEMEngine.KyberN / 8; i++)
                 {
                     for (j = 0; j < 8; j++)
                     {
    -                    t[j] =
    +                    /*t[j] =
                             (byte)(((((this.getCoeffIndex(8 * i + j) << 5))
                                 +
                                 (KyberEngine.KyberQ / 2)
                             ) / KyberEngine.KyberQ
                             ) & 31
    -                        );
    +                        );*/
    +                    // Fix for KyberSlash2: division by KyberQ above is not
    +                    // constant time.
    +                    int t_j = this.getCoeffIndex(8 * i + j);
    +                    t_j <<= 5;
    +                    t_j += 1664;
    +                    t_j *= 40318;
    +                    t_j >>= 27;
    +                    t_j &= 31;
    +                    t[j] = (byte)t_j;
                     }
                     r[count + 0] = (byte)((t[0] >> 0) | (t[1] << 5));
                     r[count + 1] = (byte)((t[1] >> 3) | (t[2] << 2) | (t[3] << 7));
    @@ -168,10 +186,10 @@ public void decompressPoly(byte[] compressedPolyCipherText)
     
             if (engine.getKyberPolyCompressedBytes() == 128)
             {
    -            for (i = 0; i < KyberEngine.KyberN / 2; i++)
    +            for (i = 0; i < MLKEMEngine.KyberN / 2; i++)
                 {
    -                this.setCoeffIndex(2 * i + 0, (short)((((short)((compressedPolyCipherText[count] & 0xFF) & 15) * KyberEngine.KyberQ) + 8) >> 4));
    -                this.setCoeffIndex(2 * i + 1, (short)((((short)((compressedPolyCipherText[count] & 0xFF) >> 4) * KyberEngine.KyberQ) + 8) >> 4));
    +                this.setCoeffIndex(2 * i + 0, (short)((((short)((compressedPolyCipherText[count] & 0xFF) & 15) * MLKEMEngine.KyberQ) + 8) >> 4));
    +                this.setCoeffIndex(2 * i + 1, (short)((((short)((compressedPolyCipherText[count] & 0xFF) >> 4) * MLKEMEngine.KyberQ) + 8) >> 4));
                     count += 1;
                 }
             }
    @@ -179,7 +197,7 @@ else if (engine.getKyberPolyCompressedBytes() == 160)
             {
                 int j;
                 byte[] t = new byte[8];
    -            for (i = 0; i < KyberEngine.KyberN / 8; i++)
    +            for (i = 0; i < MLKEMEngine.KyberN / 8; i++)
                 {
                     t[0] = (byte)((compressedPolyCipherText[count + 0] & 0xFF) >> 0);
                     t[1] = (byte)(((compressedPolyCipherText[count + 0] & 0xFF) >> 5) | ((compressedPolyCipherText[count + 1] & 0xFF) << 3));
    @@ -192,7 +210,7 @@ else if (engine.getKyberPolyCompressedBytes() == 160)
                     count += 5;
                     for (j = 0; j < 8; j++)
                     {
    -                    this.setCoeffIndex(8 * i + j, (short)(((t[j] & 31) * KyberEngine.KyberQ + 16) >> 5));
    +                    this.setCoeffIndex(8 * i + j, (short)(((t[j] & 31) * MLKEMEngine.KyberQ + 16) >> 5));
                     }
                 }
             }
    @@ -205,10 +223,10 @@ else if (engine.getKyberPolyCompressedBytes() == 160)
     
         public byte[] toBytes()
         {
    -        byte[] r = new byte[KyberEngine.KyberPolyBytes];
    +        byte[] r = new byte[MLKEMEngine.KyberPolyBytes];
             short t0, t1;
             this.conditionalSubQ();
    -        for (int i = 0; i < KyberEngine.KyberN / 2; i++)
    +        for (int i = 0; i < MLKEMEngine.KyberN / 2; i++)
             {
                 t0 = this.getCoeffIndex(2 * i);
                 t1 = this.getCoeffIndex(2 * i + 1);
    @@ -224,7 +242,7 @@ public byte[] toBytes()
         public void fromBytes(byte[] inpBytes)
         {
             int i;
    -        for (i = 0; i < KyberEngine.KyberN / 2; i++)
    +        for (i = 0; i < MLKEMEngine.KyberN / 2; i++)
             {
                 this.setCoeffIndex(2 * i, (short)(
                     (
    @@ -243,18 +261,24 @@ public void fromBytes(byte[] inpBytes)
     
         public byte[] toMsg()
         {
    -        byte[] outMsg = new byte[KyberEngine.getKyberIndCpaMsgBytes()];
    -        int i, j;
    -        short t;
    +        int LOWER = MLKEMEngine.KyberQ >>> 2;
    +        int UPPER = MLKEMEngine.KyberQ - LOWER;
    +
    +        byte[] outMsg = new byte[MLKEMEngine.getKyberIndCpaMsgBytes()];
     
             this.conditionalSubQ();
     
    -        for (i = 0; i < KyberEngine.KyberN / 8; i++)
    +        for (int i = 0; i < MLKEMEngine.KyberN / 8; i++)
             {
                 outMsg[i] = 0;
    -            for (j = 0; j < 8; j++)
    +            for (int j = 0; j < 8; j++)
                 {
    -                t = (short)(((((short)(this.getCoeffIndex(8 * i + j) << 1) + KyberEngine.KyberQ / 2) / KyberEngine.KyberQ) & 1));
    +                int c_j = this.getCoeffIndex(8 * i + j);
    +
    +                // KyberSlash: division by Q is not constant time.
    +//                int t = (((c_j << 1) + (KyberEngine.KyberQ / 2)) / KyberEngine.KyberQ) & 1;
    +                int t = ((LOWER - c_j) & (c_j - UPPER)) >>> 31;
    +
                     outMsg[i] |= (byte)(t << j);
                 }
             }
    @@ -265,16 +289,16 @@ public void fromMsg(byte[] msg)
         {
             int i, j;
             short mask;
    -        if (msg.length != KyberEngine.KyberN / 8)
    +        if (msg.length != MLKEMEngine.KyberN / 8)
             {
                 throw new RuntimeException("KYBER_INDCPA_MSGBYTES must be equal to KYBER_N/8 bytes!");
             }
    -        for (i = 0; i < KyberEngine.KyberN / 8; i++)
    +        for (i = 0; i < MLKEMEngine.KyberN / 8; i++)
             {
                 for (j = 0; j < 8; j++)
                 {
                     mask = (short)((-1) * (short)(((msg[i] & 0xFF) >> j) & 1));
    -                this.setCoeffIndex(8 * i + j, (short)(mask & (short)((KyberEngine.KyberQ + 1) / 2)));
    +                this.setCoeffIndex(8 * i + j, (short)(mask & (short)((MLKEMEngine.KyberQ + 1) / 2)));
                 }
             }
         }
    @@ -282,7 +306,7 @@ public void fromMsg(byte[] msg)
         public void conditionalSubQ()
         {
             int i;
    -        for (i = 0; i < KyberEngine.KyberN; i++)
    +        for (i = 0; i < MLKEMEngine.KyberN; i++)
             {
                 this.setCoeffIndex(i, Reduce.conditionalSubQ(this.getCoeffIndex(i)));
             }
    @@ -290,22 +314,22 @@ public void conditionalSubQ()
     
         public void getEta1Noise(byte[] seed, byte nonce)
         {
    -        byte[] buf = new byte[KyberEngine.KyberN * eta1 / 4];
    +        byte[] buf = new byte[MLKEMEngine.KyberN * eta1 / 4];
             symmetric.prf(buf, seed, nonce);
    -        CBD.kyberCBD(this, buf, eta1);
    +        CBD.mlkemCBD(this, buf, eta1);
         }
     
         public void getEta2Noise(byte[] seed, byte nonce)
         {
    -        byte[] buf = new byte[KyberEngine.KyberN * eta2 / 4];
    +        byte[] buf = new byte[MLKEMEngine.KyberN * eta2 / 4];
             symmetric.prf(buf, seed, nonce);
    -        CBD.kyberCBD(this, buf, eta2);
    +        CBD.mlkemCBD(this, buf, eta2);
         }
     
         public void polySubtract(Poly b)
         {
             int i;
    -        for (i = 0; i < KyberEngine.KyberN; i++)
    +        for (i = 0; i < MLKEMEngine.KyberN; i++)
             {
                 this.setCoeffIndex(i, (short)(b.getCoeffIndex(i) - this.getCoeffIndex(i)));
             }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/PolyVec.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/PolyVec.java
    similarity index 82%
    rename from core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/PolyVec.java
    rename to core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/PolyVec.java
    index eb93c4fd4a..d6613e904f 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/PolyVec.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/PolyVec.java
    @@ -1,15 +1,15 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    +package org.bouncycastle.pqc.crypto.mlkem;
     
     import org.bouncycastle.util.Arrays;
     
     class PolyVec
     {
         Poly[] vec;
    -    private KyberEngine engine;
    +    private MLKEMEngine engine;
         private int kyberK;
         private int polyVecBytes;
     
    -    public PolyVec(KyberEngine engine)
    +    public PolyVec(MLKEMEngine engine)
         {
             this.engine = engine;
             this.kyberK = engine.getKyberK();
    @@ -63,17 +63,26 @@ public byte[] compressPolyVec()
                 t = new short[4];
                 for (i = 0; i < kyberK; i++)
                 {
    -                for (j = 0; j < KyberEngine.KyberN / 4; j++)
    +                for (j = 0; j < MLKEMEngine.KyberN / 4; j++)
                     {
                         for (k = 0; k < 4; k++)
                         {
    -                        t[k] = (short)
    +                        /*t[k] = (short)
                                 (
                                     (
                                         ((this.getVectorIndex(i).getCoeffIndex(4 * j + k) << 10)
                                             + (KyberEngine.KyberQ / 2))
                                             / KyberEngine.KyberQ)
    -                                    & 0x3ff);
    +                                    & 0x3ff);*/
    +                        // Fix for KyberSlash2: division by KyberQ above is not
    +                        // constant time.
    +                        long t_k = this.getVectorIndex(i).getCoeffIndex(4 * j + k);
    +                        t_k <<= 10;
    +                        t_k += 1665;
    +                        t_k *= 1290167;
    +                        t_k >>= 32;
    +                        t_k &= 0x3ff;
    +                        t[k] = (short)t_k;
                         }
                         r[count + 0] = (byte)(t[0] >> 0);
                         r[count + 1] = (byte)((t[0] >> 8) | (t[1] << 2));
    @@ -89,17 +98,26 @@ else if (engine.getKyberPolyVecCompressedBytes() == kyberK * 352)
                 t = new short[8];
                 for (i = 0; i < kyberK; i++)
                 {
    -                for (j = 0; j < KyberEngine.KyberN / 8; j++)
    +                for (j = 0; j < MLKEMEngine.KyberN / 8; j++)
                     {
                         for (k = 0; k < 8; k++)
                         {
    -                        t[k] = (short)
    +                        /*t[k] = (short)
                                 (
                                     (
                                         ((this.getVectorIndex(i).getCoeffIndex(8 * j + k) << 11)
                                             + (KyberEngine.KyberQ / 2))
                                             / KyberEngine.KyberQ)
    -                                    & 0x7ff);
    +                                    & 0x7ff);*/
    +                        // Fix for KyberSlash2: division by KyberQ above is not
    +                        // constant time.
    +                        long t_k = this.getVectorIndex(i).getCoeffIndex(8 * j + k);
    +                        t_k <<= 11;
    +                        t_k += 1664;
    +                        t_k *= 645084;
    +                        t_k >>= 31;
    +                        t_k &= 0x7ff;
    +                        t[k] = (short)t_k;
                         }
                         r[count + 0] = (byte)((t[0] >> 0));
                         r[count + 1] = (byte)((t[0] >> 8) | (t[1] << 3));
    @@ -132,7 +150,7 @@ public void decompressPolyVec(byte[] compressedPolyVecCipherText)
                 short[] t = new short[4];
                 for (i = 0; i < kyberK; i++)
                 {
    -                for (j = 0; j < KyberEngine.KyberN / 4; j++)
    +                for (j = 0; j < MLKEMEngine.KyberN / 4; j++)
                     {
                         t[0] = (short)(((compressedPolyVecCipherText[count] & 0xFF) >> 0) | (short)((compressedPolyVecCipherText[count + 1] & 0xFF) << 8));
                         t[1] = (short)(((compressedPolyVecCipherText[count + 1] & 0xFF) >> 2) | (short)((compressedPolyVecCipherText[count + 2] & 0xFF) << 6));
    @@ -141,7 +159,7 @@ public void decompressPolyVec(byte[] compressedPolyVecCipherText)
                         count += 5;
                         for (k = 0; k < 4; k++)
                         {
    -                        this.vec[i].setCoeffIndex(4 * j + k, (short)(((t[k] & 0x3FF) * KyberEngine.KyberQ + 512) >> 10));
    +                        this.vec[i].setCoeffIndex(4 * j + k, (short)(((t[k] & 0x3FF) * MLKEMEngine.KyberQ + 512) >> 10));
                         }
                     }
     
    @@ -153,7 +171,7 @@ else if (engine.getKyberPolyVecCompressedBytes() == (kyberK * 352))
                 short[] t = new short[8];
                 for (i = 0; i < kyberK; i++)
                 {
    -                for (j = 0; j < KyberEngine.KyberN / 8; j++)
    +                for (j = 0; j < MLKEMEngine.KyberN / 8; j++)
                     {
                         t[0] = (short)(((compressedPolyVecCipherText[count] & 0xFF) >> 0) | ((short)(compressedPolyVecCipherText[count + 1] & 0xFF) << 8));
                         t[1] = (short)(((compressedPolyVecCipherText[count + 1] & 0xFF) >> 3) | ((short)(compressedPolyVecCipherText[count + 2] & 0xFF) << 5));
    @@ -166,7 +184,7 @@ else if (engine.getKyberPolyVecCompressedBytes() == (kyberK * 352))
                         count += 11;
                         for (k = 0; k < 8; k++)
                         {
    -                        this.vec[i].setCoeffIndex(8 * j + k, (short)(((t[k] & 0x7FF) * KyberEngine.KyberQ + 1024) >> 11));
    +                        this.vec[i].setCoeffIndex(8 * j + k, (short)(((t[k] & 0x7FF) * MLKEMEngine.KyberQ + 1024) >> 11));
                         }
                     }
                 }
    @@ -177,7 +195,7 @@ else if (engine.getKyberPolyVecCompressedBytes() == (kyberK * 352))
             }
         }
     
    -    public static void pointwiseAccountMontgomery(Poly out, PolyVec inp1, PolyVec inp2, KyberEngine engine)
    +    public static void pointwiseAccountMontgomery(Poly out, PolyVec inp1, PolyVec inp2, MLKEMEngine engine)
         {
             int i;
             Poly t = new Poly(engine);
    @@ -214,7 +232,7 @@ public byte[] toBytes()
             byte[] r = new byte[polyVecBytes];
             for (int i = 0; i < kyberK; i++)
             {
    -            System.arraycopy(this.vec[i].toBytes(), 0, r, i * KyberEngine.KyberPolyBytes, KyberEngine.KyberPolyBytes);
    +            System.arraycopy(this.vec[i].toBytes(), 0, r, i * MLKEMEngine.KyberPolyBytes, MLKEMEngine.KyberPolyBytes);
             }
     
             return r;
    @@ -224,7 +242,7 @@ public void fromBytes(byte[] inputBytes)
         {
             for (int i = 0; i < kyberK; i++)
             {
    -            this.getVectorIndex(i).fromBytes(Arrays.copyOfRange(inputBytes, i * KyberEngine.KyberPolyBytes, (i + 1) * KyberEngine.KyberPolyBytes));
    +            this.getVectorIndex(i).fromBytes(Arrays.copyOfRange(inputBytes, i * MLKEMEngine.KyberPolyBytes, (i + 1) * MLKEMEngine.KyberPolyBytes));
             }
         }
     
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/Reduce.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Reduce.java
    similarity index 55%
    rename from core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/Reduce.java
    rename to core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Reduce.java
    index c852a13e1d..c0b51d2c07 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/Reduce.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Reduce.java
    @@ -1,4 +1,4 @@
    -package org.bouncycastle.pqc.crypto.crystals.kyber;
    +package org.bouncycastle.pqc.crypto.mlkem;
     
     class Reduce
     {
    @@ -8,8 +8,8 @@ public static short montgomeryReduce(int a)
             int t;
             short u;
     
    -        u = (short)(a * KyberEngine.KyberQinv);
    -        t = (int)(u * KyberEngine.KyberQ);
    +        u = (short)(a * MLKEMEngine.KyberQinv);
    +        t = (int)(u * MLKEMEngine.KyberQ);
             t = a - t;
             t >>= 16;
             return (short)t;
    @@ -19,16 +19,16 @@ public static short barretReduce(short a)
         {
             short t;
             long shift = (((long)1) << 26);
    -        short v = (short)((shift + (KyberEngine.KyberQ / 2)) / KyberEngine.KyberQ);
    +        short v = (short)((shift + (MLKEMEngine.KyberQ / 2)) / MLKEMEngine.KyberQ);
             t = (short)((v * a) >> 26);
    -        t = (short)(t * KyberEngine.KyberQ);
    +        t = (short)(t * MLKEMEngine.KyberQ);
             return (short)(a - t);
         }
     
         public static short conditionalSubQ(short a)
         {
    -        a -= KyberEngine.KyberQ;
    -        a += (a >> 15) & KyberEngine.KyberQ;
    +        a -= MLKEMEngine.KyberQ;
    +        a += (a >> 15) & MLKEMEngine.KyberQ;
             return a;
         }
     
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Symmetric.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Symmetric.java
    new file mode 100644
    index 0000000000..40c309dedf
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Symmetric.java
    @@ -0,0 +1,94 @@
    +package org.bouncycastle.pqc.crypto.mlkem;
    +
    +import org.bouncycastle.crypto.digests.SHA3Digest;
    +import org.bouncycastle.crypto.digests.SHAKEDigest;
    +
    +abstract class Symmetric
    +{
    +
    +    final int xofBlockBytes;
    +
    +    abstract void hash_h(byte[] out, byte[] in, int outOffset);
    +
    +    abstract void hash_g(byte[] out, byte[] in);
    +
    +    abstract void xofAbsorb(byte[] seed, byte x, byte y);
    +
    +    abstract void xofSqueezeBlocks(byte[] out, int outOffset, int outLen);
    +
    +    abstract void prf(byte[] out, byte[] key, byte nonce);
    +
    +    abstract void kdf(byte[] out, byte[] in);
    +
    +    Symmetric(int blockBytes)
    +    {
    +        this.xofBlockBytes = blockBytes;
    +    }
    +
    +
    +    static class ShakeSymmetric
    +        extends Symmetric
    +    {
    +        private final SHAKEDigest xof;
    +        private final SHA3Digest sha3Digest512;
    +        private final SHA3Digest sha3Digest256;
    +        private final SHAKEDigest shakeDigest;
    +
    +        ShakeSymmetric()
    +        {
    +            super(168);
    +            this.xof = new SHAKEDigest(128);
    +            this.shakeDigest = new SHAKEDigest(256);
    +            this.sha3Digest256 = new SHA3Digest(256);
    +            this.sha3Digest512 = new SHA3Digest(512);
    +        }
    +
    +        @Override
    +        void hash_h(byte[] out, byte[] in, int outOffset)
    +        {
    +            sha3Digest256.update(in, 0, in.length);
    +            sha3Digest256.doFinal(out, outOffset);
    +        }
    +
    +        @Override
    +        void hash_g(byte[] out, byte[] in)
    +        {
    +            sha3Digest512.update(in, 0, in.length);
    +            sha3Digest512.doFinal(out, 0);
    +        }
    +
    +        @Override
    +        void xofAbsorb(byte[] seed, byte a, byte b)
    +        {
    +            xof.reset();
    +            byte[] buf = new byte[seed.length + 2];
    +            System.arraycopy(seed, 0, buf, 0, seed.length);
    +            buf[seed.length] = a;
    +            buf[seed.length + 1] = b;
    +            xof.update(buf, 0, seed.length + 2);
    +        }
    +
    +        @Override
    +        void xofSqueezeBlocks(byte[] out, int outOffset, int outLen)
    +        {
    +            xof.doOutput(out, outOffset, outLen);
    +        }
    +
    +        @Override
    +        void prf(byte[] out, byte[] seed, byte nonce)
    +        {
    +            byte[] extSeed = new byte[seed.length + 1];
    +            System.arraycopy(seed, 0, extSeed, 0, seed.length);
    +            extSeed[seed.length] = nonce;
    +            shakeDigest.update(extSeed, 0, extSeed.length);
    +            shakeDigest.doFinal(out, 0, out.length);
    +        }
    +
    +        @Override
    +        void kdf(byte[] out, byte[] in)
    +        {
    +            shakeDigest.update(in, 0, in.length);
    +            shakeDigest.doFinal(out, 0, out.length);
    +        }
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java
    index b2d05d040a..2d8582496a 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java
    @@ -4,7 +4,9 @@
     import org.bouncycastle.pqc.crypto.KEMParameters;
     import org.bouncycastle.pqc.math.ntru.parameters.NTRUHPS2048509;
     import org.bouncycastle.pqc.math.ntru.parameters.NTRUHPS2048677;
    +import org.bouncycastle.pqc.math.ntru.parameters.NTRUHPS40961229;
     import org.bouncycastle.pqc.math.ntru.parameters.NTRUHPS4096821;
    +import org.bouncycastle.pqc.math.ntru.parameters.NTRUHRSS1373;
     import org.bouncycastle.pqc.math.ntru.parameters.NTRUHRSS701;
     import org.bouncycastle.pqc.math.ntru.parameters.NTRUParameterSet;
     
    @@ -27,11 +29,21 @@ public class NTRUParameters
          */
         public static final NTRUParameters ntruhps4096821 = new NTRUParameters("ntruhps4096821", new NTRUHPS4096821());
     
    +    /**
    +     * NTRU-HPS parameter set with n = 1229 and q = 4096.
    +     */
    +    public static final NTRUParameters ntruhps40961229 = new NTRUParameters("ntruhps40961229", new NTRUHPS40961229());
    +
         /**
          * NTRU-HRSS parameter set with n = 701.
          */
         public static final NTRUParameters ntruhrss701 = new NTRUParameters("ntruhrss701", new NTRUHRSS701());
     
    +    /**
    +     * NTRU-HRSS parameter set with n = 1373.
    +     */
    +    public static final NTRUParameters ntruhrss1373 = new NTRUParameters("ntruhrss1373", new NTRUHRSS1373());
    +
         private final String name;
         /**
          * Currently selected parameter set
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/NTRULPRimeParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/NTRULPRimeParameters.java
    index 3c02bf9b51..6912708dd7 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/NTRULPRimeParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/NTRULPRimeParameters.java
    @@ -1,6 +1,5 @@
     package org.bouncycastle.pqc.crypto.ntruprime;
     
    -import org.bouncycastle.crypto.CipherParameters;
     import org.bouncycastle.pqc.crypto.KEMParameters;
     
     /**
    @@ -11,19 +10,19 @@ public class NTRULPRimeParameters
     {
         public static final NTRULPRimeParameters ntrulpr653 = new NTRULPRimeParameters("ntrulpr653", 653, 4621, 252, 289,
             2175, 113, 2031, 290,
    -        865, 897, 1125, 16);
    +        865, 897, 1125, 32);
         public static final NTRULPRimeParameters ntrulpr761 = new NTRULPRimeParameters("ntrulpr761", 761, 4591, 250, 292,
             2156, 114, 2007, 287,
    -        1007, 1039, 1294, 16);
    +        1007, 1039, 1294, 32);
         public static final NTRULPRimeParameters ntrulpr857 = new NTRULPRimeParameters("ntrulpr857", 857, 5167, 281, 329,
             2433, 101, 2265, 324,
    -        1152, 1184, 1463, 16);
    +        1152, 1184, 1463, 32);
         public static final NTRULPRimeParameters ntrulpr953 = new NTRULPRimeParameters("ntrulpr953", 953, 6343, 345, 404,
             2997, 82, 2798, 400,
    -        1317, 1349, 1652, 24);
    +        1317, 1349, 1652, 32);
         public static final NTRULPRimeParameters ntrulpr1013 = new NTRULPRimeParameters("ntrulpr1013", 1013, 7177, 392, 450,
             3367, 73, 3143, 449,
    -        1423, 1455, 1773, 24);
    +        1423, 1455, 1773, 32);
         public static final NTRULPRimeParameters ntrulpr1277 = new NTRULPRimeParameters("ntrulpr1277", 1277, 7879, 429, 502,
             3724, 66, 3469, 496,
             1815, 1847, 2231, 32);
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/SNTRUPrimeParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/SNTRUPrimeParameters.java
    index 27df57c979..8cf04473b9 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/SNTRUPrimeParameters.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/SNTRUPrimeParameters.java
    @@ -9,15 +9,15 @@ public class SNTRUPrimeParameters
         implements KEMParameters
     {
         public static final SNTRUPrimeParameters sntrup653 = new SNTRUPrimeParameters("sntrup653", 653, 4621, 288,
    -                                                                    994, 865, 994, 1518, 16);
    +                                                                    994, 865, 994, 1518, 32);
         public static final SNTRUPrimeParameters sntrup761 = new SNTRUPrimeParameters("sntrup761", 761, 4591, 286,
    -                                                                    1158, 1007, 1158, 1763, 16);
    +                                                                    1158, 1007, 1158, 1763, 32);
         public static final SNTRUPrimeParameters sntrup857 = new SNTRUPrimeParameters("sntrup857", 857, 5167, 322,
    -                                                                    1322, 1152, 1322, 1999, 16);
    +                                                                    1322, 1152, 1322, 1999, 32);
         public static final SNTRUPrimeParameters sntrup953 = new SNTRUPrimeParameters("sntrup953", 953, 6343, 396,
    -                                                                    1505, 1317, 1505, 2254, 24);
    +                                                                    1505, 1317, 1505, 2254, 32);
         public static final SNTRUPrimeParameters sntrup1013 = new SNTRUPrimeParameters("sntrup1013", 1013, 7177, 448,
    -                                                                    1623, 1423, 1623, 2417, 24);
    +                                                                    1623, 1423, 1623, 2417, 32);
         public static final SNTRUPrimeParameters sntrup1277 = new SNTRUPrimeParameters("sntrup1277", 1277, 7879, 492,
                                                                         2067, 1815, 2067, 3059, 32);
     
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/Utils.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/Utils.java
    index 93c1cfae9e..fafe21ff3c 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/Utils.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/Utils.java
    @@ -313,7 +313,7 @@ protected static void getEncodedSmallPolynomial(byte[] encSP, byte[] sp, int p)
     
         private static void generateAES256CTRStream(byte[] in, byte[] out, byte[] nonce, byte[] key)
         {
    -        StreamCipher cipher = new SICBlockCipher(new AESEngine());
    +        StreamCipher cipher = SICBlockCipher.newInstance(AESEngine.newInstance());
             cipher.init(true, new ParametersWithIV(new KeyParameter(key), nonce));
             cipher.processBytes(in, 0, out.length, out, 0);
         }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstants.java b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstants.java
    index 8f65400e0e..97d0b2ac26 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstants.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstants.java
    @@ -1,6 +1,8 @@
     package org.bouncycastle.pqc.crypto.picnic;
     
     import java.io.ByteArrayOutputStream;
    +import java.io.DataInputStream;
    +import java.io.IOException;
     import java.util.Properties;
     
     import org.bouncycastle.util.Pack;
    @@ -28,6 +30,17 @@ abstract class LowmcConstants
         protected KMatrices KMatrix_inv;
         protected KMatrices RConstants_full;
     
    +    static int[] readArray(DataInputStream dIn)
    +        throws IOException
    +    {
    +        int[] rv = new int[dIn.readInt()];
    +        for (int i = 0; i != rv.length; i++)
    +        {
    +            rv[i] = dIn.readInt();
    +        }
    +        return rv;
    +    }
    +
         static int[] ReadFromProperty(Properties props, String key, int intSize)
         {
             String s = props.getProperty(key);
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstantsL1.java b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstantsL1.java
    index d824090038..1b7c4fa92f 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstantsL1.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstantsL1.java
    @@ -1,23 +1,30 @@
     package org.bouncycastle.pqc.crypto.picnic;
     
    -import org.bouncycastle.util.Exceptions;
    -
    +import java.io.DataInputStream;
     import java.io.IOException;
    -import java.io.InputStream;
    -import java.util.Properties;
    +import java.util.zip.GZIPInputStream;
    +
    +import org.bouncycastle.util.Exceptions;
     
     public class LowmcConstantsL1
         extends LowmcConstants
     {
         LowmcConstantsL1()
         {
    -        InputStream input = LowmcConstants.class.getResourceAsStream("lowmcL1.properties");
    -        Properties props = new Properties();
    -
             // load a properties file
             try
             {
    -            props.load(input);
    +            DataInputStream input = new DataInputStream(new GZIPInputStream(LowmcConstants.class.getResourceAsStream("lowmcL1.bin.properties")));
    +
    +            linearMatrices = readArray(input);
    +            roundConstants = readArray(input);
    +            keyMatrices = readArray(input);
    +
    +            linearMatrices_full = readArray(input);
    +            keyMatrices_full = readArray(input);
    +            keyMatrices_inv = readArray(input);
    +            linearMatrices_inv = readArray(input);
    +            roundConstants_full = readArray(input);
             }
             catch (IOException e)
             {
    @@ -27,9 +34,9 @@ public class LowmcConstantsL1
             // Parameters for security level L1
             // Block/key size: 128
             // Rounds: 20
    -        linearMatrices = ReadFromProperty(props, "linearMatrices", 40960);
    -        roundConstants = ReadFromProperty(props, "roundConstants", 320);
    -        keyMatrices = ReadFromProperty(props, "keyMatrices", 43008);
    +//        linearMatrices = ReadFromProperty(props, "linearMatrices", 40960);
    +//        roundConstants = ReadFromProperty(props, "roundConstants", 320);
    +//        keyMatrices = ReadFromProperty(props, "keyMatrices", 43008);
     
             LMatrix = new KMatrices(20, 128, 4, linearMatrices);
             KMatrix = new KMatrices(21, 128, 4, keyMatrices);
    @@ -39,11 +46,11 @@ public class LowmcConstantsL1
             // Block/key size: 129
             // Rounds: 4
             // Note that each 129-bit row of the matrix is zero padded to 160 bits (the next multiple of 32)
    -        linearMatrices_full = ReadFromProperty(props, "linearMatrices_full", 12800);
    -        keyMatrices_full = ReadFromProperty(props, "keyMatrices_full", 12900);
    -        keyMatrices_inv = ReadFromProperty(props, "keyMatrices_inv", 2850);
    -        linearMatrices_inv = ReadFromProperty(props, "linearMatrices_inv", 12800);
    -        roundConstants_full = ReadFromProperty(props, "roundConstants_full", 80);
    +//        linearMatrices_full = ReadFromProperty(props, "linearMatrices_full", 12800);
    +//        keyMatrices_full = ReadFromProperty(props, "keyMatrices_full", 12900);
    +//        keyMatrices_inv = ReadFromProperty(props, "keyMatrices_inv", 2850);
    +//        linearMatrices_inv = ReadFromProperty(props, "linearMatrices_inv", 12800);
    +//        roundConstants_full = ReadFromProperty(props, "roundConstants_full", 80);
     
             LMatrix_full = new KMatrices(4, 129, 5, linearMatrices_full);
             LMatrix_inv = new KMatrices(4, 129, 5, linearMatrices_inv);
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstantsL3.java b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstantsL3.java
    index 7697a86add..f392c2eb5d 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstantsL3.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstantsL3.java
    @@ -1,23 +1,30 @@
     package org.bouncycastle.pqc.crypto.picnic;
     
    -import org.bouncycastle.util.Exceptions;
    -
    +import java.io.DataInputStream;
     import java.io.IOException;
    -import java.io.InputStream;
    -import java.util.Properties;
    +import java.util.zip.GZIPInputStream;
    +
    +import org.bouncycastle.util.Exceptions;
     
     public class LowmcConstantsL3
         extends LowmcConstants
     {
         LowmcConstantsL3()
         {
    -        InputStream input = LowmcConstants.class.getResourceAsStream("lowmcL3.properties");
    -        Properties props = new Properties();
    -
             // load a properties file
             try
             {
    -            props.load(input);
    +            DataInputStream input = new DataInputStream(new GZIPInputStream(LowmcConstants.class.getResourceAsStream("lowmcL3.bin.properties")));
    +
    +            linearMatrices = readArray(input);
    +            roundConstants = readArray(input);
    +            keyMatrices = readArray(input);
    +
    +            linearMatrices_full = readArray(input);
    +            keyMatrices_full = readArray(input);
    +            keyMatrices_inv = readArray(input);
    +            linearMatrices_inv = readArray(input);
    +            roundConstants_full = readArray(input);
             }
             catch (IOException e)
             {
    @@ -27,9 +34,9 @@ public class LowmcConstantsL3
             // Parameters for security level L3
             // Block/key size: 192
             // Rounds: 30
    -        linearMatrices = ReadFromProperty(props, "linearMatrices", 138240);
    -        roundConstants = ReadFromProperty(props, "roundConstants", 720);
    -        keyMatrices = ReadFromProperty(props, "keyMatrices", 142848);
    +//        linearMatrices = ReadFromProperty(props, "linearMatrices", 138240);
    +//        roundConstants = ReadFromProperty(props, "roundConstants", 720);
    +//        keyMatrices = ReadFromProperty(props, "keyMatrices", 142848);
     
             LMatrix = new KMatrices(30, 192, 6, linearMatrices);
             KMatrix = new KMatrices(31, 192, 6, keyMatrices);
    @@ -39,11 +46,11 @@ public class LowmcConstantsL3
             // Block/key size: 192
             // S-boxes: 64
             // Rounds: 4
    -        linearMatrices_full = ReadFromProperty(props, "linearMatrices_full", 18432);
    -        linearMatrices_inv = ReadFromProperty(props, "linearMatrices_inv", 18432);
    -        roundConstants_full = ReadFromProperty(props, "roundConstants_full", 96);
    -        keyMatrices_full = ReadFromProperty(props, "keyMatrices_full", 23040);
    -        keyMatrices_inv = ReadFromProperty(props, "keyMatrices_inv", 4608);
    +//        linearMatrices_full = ReadFromProperty(props, "linearMatrices_full", 18432);
    +//        linearMatrices_inv = ReadFromProperty(props, "linearMatrices_inv", 18432);
    +//        roundConstants_full = ReadFromProperty(props, "roundConstants_full", 96);
    +//        keyMatrices_full = ReadFromProperty(props, "keyMatrices_full", 23040);
    +//        keyMatrices_inv = ReadFromProperty(props, "keyMatrices_inv", 4608);
     
             LMatrix_full = new KMatrices(4, 192, 6, linearMatrices_full);
             LMatrix_inv = new KMatrices(4, 192, 6, linearMatrices_inv);
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstantsL5.java b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstantsL5.java
    index 111a0ba624..09de4353ea 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstantsL5.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/LowmcConstantsL5.java
    @@ -1,23 +1,30 @@
     package org.bouncycastle.pqc.crypto.picnic;
     
    -import org.bouncycastle.util.Exceptions;
    -
    +import java.io.DataInputStream;
     import java.io.IOException;
    -import java.io.InputStream;
    -import java.util.Properties;
    +import java.util.zip.GZIPInputStream;
    +
    +import org.bouncycastle.util.Exceptions;
     
     public class LowmcConstantsL5
         extends LowmcConstants
     {
         LowmcConstantsL5()
         {
    -        InputStream input = LowmcConstants.class.getResourceAsStream("lowmcL5.properties");
    -        Properties props = new Properties();
    -
             // load a properties file
             try
             {
    -            props.load(input);
    +            DataInputStream input = new DataInputStream(new GZIPInputStream(LowmcConstants.class.getResourceAsStream("lowmcL5.bin.properties")));
    +
    +            linearMatrices = readArray(input);
    +            roundConstants = readArray(input);
    +            keyMatrices = readArray(input);
    +
    +            linearMatrices_full = readArray(input);
    +            keyMatrices_full = readArray(input);
    +            keyMatrices_inv = readArray(input);
    +            linearMatrices_inv = readArray(input);
    +            roundConstants_full = readArray(input);
             }
             catch (IOException e)
             {
    @@ -26,9 +33,9 @@ public class LowmcConstantsL5
             // Parameters for security level L5
             // Block/key size: 256
             // Rounds: 38
    -        linearMatrices = ReadFromProperty(props, "linearMatrices", 311296);
    -        roundConstants = ReadFromProperty(props, "roundConstants", 1216);
    -        keyMatrices = ReadFromProperty(props, "keyMatrices", 319488);
    +//        linearMatrices = ReadFromProperty(props, "linearMatrices", 311296);
    +//        roundConstants = ReadFromProperty(props, "roundConstants", 1216);
    +//        keyMatrices = ReadFromProperty(props, "keyMatrices", 319488);
     
             LMatrix = new KMatrices(38, 256, 8, linearMatrices);
             KMatrix = new KMatrices(39, 256, 8, keyMatrices);
    @@ -38,11 +45,11 @@ public class LowmcConstantsL5
             // Block/key size: 255
             // S-boxes: 85
             // Rounds: 4
    -        linearMatrices_full = ReadFromProperty(props, "linearMatrices_full", 32768);
    -        linearMatrices_inv = ReadFromProperty(props, "linearMatrices_inv", 32768);
    -        roundConstants_full = ReadFromProperty(props, "roundConstants_full", 128);
    -        keyMatrices_full = ReadFromProperty(props, "keyMatrices_full", 40960);
    -        keyMatrices_inv = ReadFromProperty(props, "keyMatrices_inv", 8160);
    +//        linearMatrices_full = ReadFromProperty(props, "linearMatrices_full", 32768);
    +//        linearMatrices_inv = ReadFromProperty(props, "linearMatrices_inv", 32768);
    +//        roundConstants_full = ReadFromProperty(props, "roundConstants_full", 128);
    +//        keyMatrices_full = ReadFromProperty(props, "keyMatrices_full", 40960);
    +//        keyMatrices_inv = ReadFromProperty(props, "keyMatrices_inv", 8160);
     
             LMatrix_full = new KMatrices(4, 255, 8, linearMatrices_full);
             LMatrix_inv = new KMatrices(4, 255, 8, linearMatrices_inv);
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/PicnicEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/PicnicEngine.java
    index 89861b6f45..8530b39714 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/PicnicEngine.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/PicnicEngine.java
    @@ -7,6 +7,7 @@
     import org.bouncycastle.crypto.digests.SHAKEDigest;
     import org.bouncycastle.math.raw.Bits;
     import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Integers;
     import org.bouncycastle.util.Pack;
     
     class PicnicEngine
    @@ -340,19 +341,19 @@ public boolean crypto_sign_open(byte[] m, byte[] sm, byte[] pk)
     
         private int picnic_verify(byte[] pk, byte[] message, byte[] signature, int sigLen)
         {
    -        byte[] plaintext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
    -        byte[] ciphertext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
    -        picnic_read_public_key(ciphertext_bytes, plaintext_bytes, pk);
             int[] ciphertext = new int[stateSizeWords];
             int[] plaintext = new int[stateSizeWords];
    -
    -        Pack.littleEndianToInt(plaintext_bytes, 0, plaintext);
    -        Pack.littleEndianToInt(ciphertext_bytes, 0, ciphertext);
    +        picnic_read_public_key(ciphertext, plaintext, pk);
     
             if(is_picnic3(parameters))
             {
                 Signature2 sig = new Signature2(this);
    -            deserializeSignature2(sig, signature, sigLen,  message.length + 4);
    +            int ret = deserializeSignature2(sig, signature, sigLen,  message.length + 4);
    +            if (ret != 0)
    +            {
    +                LOG.fine("Error couldn't deserialize signature (2)!");
    +                return -1;
    +            }
     
                 return verify_picnic3(sig, ciphertext, plaintext, message);
             }
    @@ -395,9 +396,13 @@ private int verify(Signature sig, int[] pubKey, int[] plaintext, byte[] message)
                 view1s[i] = new View(this);
                 view2s[i] = new View(this);
     
    -            verifyProof(proofs[i], view1s[i], view2s[i],
    -                    getChallenge(received_challengebits, i), sig.salt, i,
    -                    tmp, plaintext, tape);
    +            if (!verifyProof(proofs[i], view1s[i], view2s[i],
    +                getChallenge(received_challengebits, i), sig.salt, i,
    +                tmp, plaintext, tape))
    +            {
    +                LOG.fine(("Invalid signature. Did not verify"));
    +                return -1;
    +            }
     
                 // create ordered array of commitments with order computed based on the challenge
                 // check commitments of the two opened views
    @@ -416,7 +421,7 @@ private int verify(Signature sig, int[] pubKey, int[] plaintext, byte[] message)
                 viewOutputs[i][challenge] = view1s[i].outputShare;
                 viewOutputs[i][(challenge + 1) % 3] = view2s[i].outputShare;
                 int[] view3Output = new int[stateSizeWords];     /* pointer into the slab to the current 3rd view */
    -            xor_three(view3Output, view1s[i].outputShare,  view2s[i].outputShare, pubKey, stateSizeBytes);
    +            xor_three(view3Output, view1s[i].outputShare,  view2s[i].outputShare, pubKey);
                 viewOutputs[i][(challenge + 2) % 3] = view3Output;
             }
     
    @@ -436,7 +441,7 @@ private int verify(Signature sig, int[] pubKey, int[] plaintext, byte[] message)
         }
     
         boolean verifyProof(Signature.Proof proof, View view1, View view2, int challenge, byte[] salt,
    -                     int roundNumber, byte[] tmp, int[] plaintext, Tape tape)
    +        int roundNumber, byte[] tmp, int[] plaintext, Tape tape)
         {
             System.arraycopy(proof.communicatedBits, 0, view2.communicatedBits, 0, andSizeBytes);
             tape.pos = 0;
    @@ -461,6 +466,7 @@ boolean verifyProof(Signature.Proof proof, View view1, View view2, int challenge
                     {
                         break;
                     }
    +
                     Pack.littleEndianToInt(tmp, 0, view2.inputShare);//todo check
                     System.arraycopy(tmp, stateSizeBytes, tape.tapes[1], 0, andSizeBytes);
     
    @@ -477,12 +483,13 @@ boolean verifyProof(Signature.Proof proof, View view1, View view2, int challenge
                     System.arraycopy(tmp, stateSizeBytes, tape.tapes[0], 0, andSizeBytes);
                     status = status && createRandomTape(proof.seed2, 0, salt, roundNumber,
                             2, tape.tapes[1], andSizeBytes);
    +
                     if (!status)
                     {
                         break;
                     }
     
    -                System.arraycopy(proof.inputShare, 0, view2.inputShare, 0, stateSizeBytes);
    +                System.arraycopy(proof.inputShare, 0, view2.inputShare, 0, stateSizeWords);
                     break;
     
                 case 2:
    @@ -490,12 +497,14 @@ boolean verifyProof(Signature.Proof proof, View view1, View view2, int challenge
                     // it is not computable from the seed. We just need to compute view2's input from
                     // its seed
                     status = createRandomTape(proof.seed1, 0, salt, roundNumber, 2, tape.tapes[0], andSizeBytes);
    -                System.arraycopy(proof.inputShare, 0, view1.inputShare, 0, stateSizeBytes);
    +                System.arraycopy(proof.inputShare, 0, view1.inputShare, 0, stateSizeWords);
                     status = status && createRandomTape(proof.seed2, 0, salt, roundNumber, 0, tmp, stateSizeBytes + andSizeBytes);
    +
                     if (!status)
                     {
                         break;
                     }
    +
                     Pack.littleEndianToInt(tmp, 0, view2.inputShare);//todo check
                     System.arraycopy(tmp, stateSizeBytes, tape.tapes[1], 0, andSizeBytes);
                     break;
    @@ -510,18 +519,9 @@ boolean verifyProof(Signature.Proof proof, View view1, View view2, int challenge
                 LOG.fine("Failed to generate random tapes, signature verification will fail (but signature may actually be valid)");
                 return false;
             }
    -        /* When input shares are read from the tapes, and the length is not a whole number of bytes, the trailing bits must be zero */
    -        byte[] view_bytes = new byte[stateSizeBytes * 4];
    -        Pack.intToLittleEndian(view1.inputShare, view_bytes, 0);
    -        Arrays.fill(view_bytes, stateSizeBytes, view_bytes.length, (byte) 0); //todo have correct size: reduce view.inputshare by /4
    -        zeroTrailingBits(view_bytes, stateSizeBits);
    -        Pack.littleEndianToInt(view_bytes, 0, view1.inputShare);
     
    -        Pack.intToLittleEndian(view2.inputShare, view_bytes, 0);
    -        Arrays.fill(view_bytes, stateSizeBytes, view_bytes.length, (byte) 0);
    -        zeroTrailingBits(view_bytes, stateSizeBits);
    -
    -        Pack.littleEndianToInt(view_bytes, 0, view2.inputShare);
    +        Utils.zeroTrailingBits(view1.inputShare, stateSizeBits);
    +        Utils.zeroTrailingBits(view2.inputShare, stateSizeBits);
     
             int[] tmp_ints = Pack.littleEndianToInt(tmp, 0, tmp.length/4);
             mpc_LowMC_verify(view1, view2, tape, tmp_ints, plaintext, challenge);
    @@ -542,7 +542,7 @@ void mpc_LowMC_verify(View view1, View view2, Tape tapes, int[] tmp, int[] plain
                     view2.inputShare, 0,
                     current.getData(), current.getMatrixPointer());
     
    -        mpc_xor(tmp, tmp, stateSizeWords, 2);
    +        mpc_xor(tmp, tmp, 2);
     
             for (int r = 1; r <= numRounds; ++r)
             {
    @@ -563,7 +563,7 @@ void mpc_LowMC_verify(View view1, View view2, Tape tapes, int[] tmp, int[] plain
     
                 current = lowmcConstants.RConstant(this, r - 1);
                 mpc_xor_constant_verify(tmp, current.getData(), current.getMatrixPointer(), stateSizeWords, challenge);
    -            mpc_xor(tmp, tmp, stateSizeWords, 2);
    +            mpc_xor(tmp, tmp, 2);
             }
     
             System.arraycopy(tmp, 2*stateSizeWords, view1.outputShare, 0, stateSizeWords);
    @@ -609,10 +609,14 @@ void mpc_substitution_verify(int[] state, Tape rand, View view1, View view2)
     
         void mpc_AND_verify(int[] in1, int[] in2, int[] out, Tape rand, View view1, View view2)
         {
    -        int[] r = { Utils.getBit(rand.tapes[0], rand.pos), Utils.getBit(rand.tapes[1], rand.pos) };
    +        int r0 = Utils.getBit(rand.tapes[0], rand.pos);
    +        int r1 = Utils.getBit(rand.tapes[1], rand.pos);
    +
    +        int a0 = in1[0], a1 = in1[1];
    +        int b0 = in2[0], b1 = in2[1];
     
    -        out[0] = (in1[0] & in2[1]) ^ (in1[1] & in2[0]) ^ (in1[0] & in2[0]) ^ r[0] ^ r[1];
    -        Utils.setBit(view1.communicatedBits, rand.pos, (byte) (out[0] & 0xff));
    +        out[0] = (a0 & b1) ^ (a1 & b0) ^ (a0 & b0) ^ r0 ^ r1;
    +        Utils.setBit(view1.communicatedBits, rand.pos, (byte)out[0]);
             out[1] = Utils.getBit(view2.communicatedBits, rand.pos);
     
             rand.pos++;
    @@ -636,49 +640,52 @@ else if (challenge == 2)
             }
             for (int i = 0; i < length; i++)
             {
    -            state[i + offset] = state[i + offset] ^ in[i + inOffset];
    +            state[i + offset] ^= in[i + inOffset];
             }
     
         }
     
    -
         private int deserializeSignature(Signature sig, byte[] sigBytes, int sigBytesLen, int sigBytesOffset)
         {
             Signature.Proof[] proofs = sig.proofs;
             byte[] challengeBits = sig.challengeBits;
    +        int challengesLength = Utils.numBytes(2 * numMPCRounds);
     
             /* Validate input buffer is large enough */
    -        if (sigBytesLen < Utils.numBytes(2 * numMPCRounds))
    +        if (sigBytesLen < challengesLength)
             {     /* ensure the input has at least the challenge */
                 return -1;
             }
     
    -        int inputShareSize = computeInputShareSize(sigBytes, stateSizeBytes);
    -        int bytesExpected = Utils.numBytes(2 * numMPCRounds) + saltSizeBytes +
    -                numMPCRounds * (2 * seedSizeBytes + andSizeBytes + digestSizeBytes) + inputShareSize;
    +        // NOTE: This also validates that there are no challenges > 2
    +        int numNonZeroChallenges = countNonZeroChallenges(sigBytes, sigBytesOffset);
    +        if (numNonZeroChallenges < 0)
    +            return -1;
    +
    +        int inputShareSize = numNonZeroChallenges * stateSizeBytes;
    +        int bytesRequired = challengesLength + saltSizeBytes +
    +            numMPCRounds * (2 * seedSizeBytes + andSizeBytes + digestSizeBytes) + inputShareSize;
     
             if (transform == TRANSFORM_UR)
             {
    -            bytesExpected += UnruhGWithoutInputBytes * numMPCRounds;
    +            bytesRequired += UnruhGWithInputBytes * (numMPCRounds - numNonZeroChallenges);
    +            bytesRequired += UnruhGWithoutInputBytes * numNonZeroChallenges;
             }
    -        if (sigBytesLen < bytesExpected)
    +
    +        if (sigBytesLen != bytesRequired)
             {
    +            LOG.fine("sigBytesLen = " + sigBytesLen + ", expected bytesRequired = " + bytesRequired);
                 return -1;
             }
     
    -        System.arraycopy(sigBytes, sigBytesOffset, challengeBits, 0,  Utils.numBytes(2 * numMPCRounds));
    -        sigBytesOffset += Utils.numBytes(2 * numMPCRounds);
    +        System.arraycopy(sigBytes, sigBytesOffset, challengeBits, 0, challengesLength);
    +        sigBytesOffset += challengesLength;
     
    -        if (!isChallengeValid(challengeBits))
    -        {
    -            return -1;
    -        }
             System.arraycopy(sigBytes, sigBytesOffset, sig.salt, 0, saltSizeBytes);
             sigBytesOffset += saltSizeBytes;
     
             for (int i = 0; i < numMPCRounds; i++)
             {
    -
                 int challenge = getChallenge(challengeBits, i);
     
                 System.arraycopy(sigBytes, sigBytesOffset, proofs[i].view3Commitment, 0, digestSizeBytes);
    @@ -710,7 +717,8 @@ private int deserializeSignature(Signature sig, byte[] sigBytes, int sigBytesLen
                     }
     
                     sigBytesOffset += stateSizeBytes;
    -                if(!arePaddingBitsZero(Pack.intToLittleEndian(proofs[i].inputShare), stateSizeBits))
    +
    +                if (!arePaddingBitsZero(proofs[i].inputShare, stateSizeBits))
                     {
                         return -1;
                     }
    @@ -721,43 +729,50 @@ private int deserializeSignature(Signature sig, byte[] sigBytes, int sigBytesLen
             return 0;
         }
     
    -    private boolean isChallengeValid(byte[] challengeBits)
    -    {
    -        for (int i = 0; i < numMPCRounds; i++)
    -        {
    -            int challenge = getChallenge(challengeBits, i);
    -            if (challenge > 2)
    -            {
    -                return false;
    -            }
    -        }
    -        return true;
    -    }
    -
    -    private int computeInputShareSize(byte[] challengeBits, int stateSizeBytes)
    +    private int countNonZeroChallenges(byte[] challengeBits, int challengeBitsOffset)
         {
             /* When the FS transform is used, the input share is included in the proof
    -         * only when the challenge is 1 or 2.  When dersializing, to compute the
    +         * only when the challenge is 1 or 2.  When deserializing, to compute the
              * number of bytes expected, we must check how many challenge values are 1
    -         * or 2. The parameter stateSizeBytes is the size of an input share. */
    -        int inputShareSize = 0;
    +         * or 2. We also check that no challenges have the invalid value 3. */
    +        int count = 0;
    +        int challenges3 = 0;
     
    -        for (int i = 0; i < numMPCRounds; i++)
    +        int i = 0;
    +        while (i + 16 <= numMPCRounds)
             {
    -            int challenge = getChallenge(challengeBits, i);
    -            if (challenge == 1 || challenge == 2)
    -            {
    -                inputShareSize += stateSizeBytes;
    -            }
    +            int challenges = Pack.littleEndianToInt(challengeBits, challengeBitsOffset + (i >>> 2));
    +            challenges3 |= challenges & (challenges >>> 1);
    +            count += Integers.bitCount((challenges ^ (challenges >>> 1)) & 0x55555555);
    +            i += 16;
             }
    -        return inputShareSize;
    +
    +        int remainingBits = (numMPCRounds - i) * 2;
    +        if (remainingBits > 0)
    +        {
    +            int remainingBytes = (remainingBits + 7) / 8;
    +            int challenges = Pack.littleEndianToInt_Low(challengeBits, challengeBitsOffset + (i >>> 2), remainingBytes);
    +            challenges &= Utils.getTrailingBitsMask(remainingBits);
    +            challenges3 |= challenges & (challenges >>> 1);
    +            count += Integers.bitCount((challenges ^ (challenges >>> 1)) & 0x55555555);
    +        }
    +
    +        return (challenges3 & 0x55555555) == 0 ? count : -1;
         }
     
    -    private int picnic_read_public_key(byte[] ciphertext, byte[] plaintext, byte[] pk)
    +    private void picnic_read_public_key(int[] ciphertext, int[] plaintext, byte[] pk)
         {
    -        System.arraycopy(pk, 1, ciphertext, 0, stateSizeBytes);
    -        System.arraycopy(pk, 1 + stateSizeBytes, plaintext, 0, stateSizeBytes);
    -        return 0;
    +        int ciphertextPos = 1, plaintextPos = 1 + stateSizeBytes;
    +        int fullWords = stateSizeBytes / 4;
    +        Pack.littleEndianToInt(pk, ciphertextPos, ciphertext, 0, fullWords);
    +        Pack.littleEndianToInt(pk, plaintextPos, plaintext, 0, fullWords);
    +
    +        if (fullWords < stateSizeWords)
    +        {
    +            int fullWordBytes = fullWords * 4, partialWordBytes = stateSizeBytes - fullWordBytes;
    +            ciphertext[fullWords] = Pack.littleEndianToInt_Low(pk, ciphertextPos + fullWordBytes, partialWordBytes);
    +            plaintext[fullWords] = Pack.littleEndianToInt_Low(pk, plaintextPos + fullWordBytes, partialWordBytes);
    +        }
         }
     
         private int verify_picnic3(Signature2 sig, int[] pubKey, int[] plaintext, byte[] message)
    @@ -984,7 +999,7 @@ private int deserializeSignature2(Signature2 sig, byte[] sigBytes, int sigLen,
             /* Fail if the signature does not have the exact number of bytes we expect */
             if (sigLen != bytesRequired)
             {
    -            LOG.fine("sigBytesLen = " + sigBytes.length + ", expected bytesRequired = " + bytesRequired);
    +            LOG.fine("sigLen = " + sigLen + ", expected bytesRequired = " + bytesRequired);
                 return -1;
             }
     
    @@ -1054,6 +1069,16 @@ private boolean arePaddingBitsZero(byte[] data, int bitLength)
             return true;
         }
     
    +    private boolean arePaddingBitsZero(int[] data, int bitLength)
    +    {
    +        int partialWord = bitLength & 31;
    +        if (partialWord == 0)
    +            return true;
    +
    +        int mask = Utils.getTrailingBitsMask(bitLength);
    +        return (data[bitLength >>> 5] & ~mask) == 0;
    +    }
    +
         public void crypto_sign(byte[] sm, byte[] m, byte[] sk)
         {
             boolean ret = picnic_sign(sk, m, sm);
    @@ -1062,27 +1087,27 @@ public void crypto_sign(byte[] sm, byte[] m, byte[] sk)
                 return; // throw error?
             }
             System.arraycopy(m, 0, sm, 4, m.length);
    -//        sm = Arrays.copyOfRange(sm, 0, signatureLength);
         }
     
         private boolean picnic_sign(byte[] sk, byte[] message, byte[] signature)
         {
    -        //todo unify conversion
    -
    -        byte[] data_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
    -        System.arraycopy(sk, 1, data_bytes, 0, stateSizeBytes);
    -        byte[] ciphertext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
    -        System.arraycopy(sk, 1 + stateSizeBytes, ciphertext_bytes, 0,  stateSizeBytes);
    -        byte[] plaintext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
    -        System.arraycopy(sk, 1 + 2 * stateSizeBytes, plaintext_bytes, 0, stateSizeBytes);
             int[] data = new int[stateSizeWords];
             int[] ciphertext = new int[stateSizeWords];
             int[] plaintext = new int[stateSizeWords];
     
    -        Pack.littleEndianToInt(data_bytes, 0, data);
    -        Pack.littleEndianToInt(plaintext_bytes, 0, plaintext);
    -        Pack.littleEndianToInt(ciphertext_bytes, 0, ciphertext);
    +        int dataPos = 1, ciphertextPos = 1 + stateSizeBytes, plaintextPos = 1 + 2 * stateSizeBytes;
    +        int fullWords = stateSizeBytes / 4;
    +        Pack.littleEndianToInt(sk, dataPos, data, 0, fullWords);
    +        Pack.littleEndianToInt(sk, ciphertextPos, ciphertext, 0, fullWords);
    +        Pack.littleEndianToInt(sk, plaintextPos, plaintext, 0, fullWords);
     
    +        if (fullWords < stateSizeWords)
    +        {
    +            int fullWordBytes = fullWords * 4, partialWordBytes = stateSizeBytes - fullWordBytes;
    +            data[fullWords] = Pack.littleEndianToInt_Low(sk, dataPos + fullWordBytes, partialWordBytes);
    +            ciphertext[fullWords] = Pack.littleEndianToInt_Low(sk, ciphertextPos + fullWordBytes, partialWordBytes);
    +            plaintext[fullWords] = Pack.littleEndianToInt_Low(sk, plaintextPos + fullWordBytes, partialWordBytes);
    +        }
     
             if(!is_picnic3(parameters))
             {
    @@ -1096,11 +1121,12 @@ private boolean picnic_sign(byte[] sk, byte[] message, byte[] signature)
                 }
     
                 int len = serializeSignature(sig, signature, message.length + 4);
    -            if (len == -1)
    +            if (len < 0)
                 {
                     LOG.fine("Failed to serialize signature");
                     return false;
                 }
    +
                 signatureLength = len;
                 Pack.intToLittleEndian(len, signature, 0);
                 return true;
    @@ -1116,7 +1142,7 @@ private boolean picnic_sign(byte[] sk, byte[] message, byte[] signature)
                 }
     
                 int len = serializeSignature2(sig, signature, message.length + 4);
    -            if (len == -1)
    +            if (len < 0)
                 {
                     LOG.fine("Failed to serialize signature");
                     return false;
    @@ -1155,7 +1181,6 @@ int serializeSignature(Signature sig, byte[] sigBytes, int sigOffset)
             sigByteIndex += Utils.numBytes(2 * numMPCRounds);
     
             System.arraycopy(sig.salt, 0, sigBytes, sigByteIndex,saltSizeBytes);
    -
             sigByteIndex += saltSizeBytes;
     
             for (int i = 0; i < numMPCRounds; i++)
    @@ -1194,12 +1219,11 @@ int serializeSignature(Signature sig, byte[] sigBytes, int sigOffset)
     
         int getChallenge(byte[] challenge, int round)
         {
    -        return (Utils.getBit(challenge, 2 * round + 1) << 1) | Utils.getBit(challenge, 2 * round);
    +        return Utils.getCrumbAligned(challenge, round);
         }
     
         private int serializeSignature2(Signature2 sig, byte[] sigBytes, int sigOffset)
         {
    -
             /* Compute the number of bytes required for the signature */
             int bytesRequired = digestSizeBytes + saltSizeBytes;     /* challenge and salt */
     
    @@ -1289,7 +1313,6 @@ private int sign_picnic1(int[] privateKey, int[] pubKey, int[] plaintext, byte[]
             Tape tape = new Tape(this);
     
             byte[] tmp = new byte[Math.max(9 * stateSizeBytes, stateSizeBytes + andSizeBytes)];
    -        byte[] view_byte = new byte[stateSizeBytes*4];
     
             for (int k = 0; k < numMPCRounds; k++)
             {
    @@ -1306,9 +1329,11 @@ private int sign_picnic1(int[] privateKey, int[] pubKey, int[] plaintext, byte[]
                         LOG.fine("createRandomTape failed");
                         return -1;
                     }
    -                System.arraycopy(tmp, 0, view_byte, 0, stateSizeBytes);
    -                zeroTrailingBits(view_byte, stateSizeBits);
    -                Pack.littleEndianToInt(view_byte, 0, views[k][j].inputShare);
    +
    +                int[] inputShare = views[k][j].inputShare;
    +                Pack.littleEndianToInt(tmp, 0, inputShare);
    +                Utils.zeroTrailingBits(inputShare, stateSizeBits);
    +                
                     System.arraycopy(tmp, stateSizeBytes, tape.tapes[j], 0, andSizeBytes);
                 }
     
    @@ -1322,7 +1347,7 @@ private int sign_picnic1(int[] privateKey, int[] pubKey, int[] plaintext, byte[]
                     return -1;
                 }
     
    -            xor_three(views[k][2].inputShare, privateKey, views[k][0].inputShare, views[k][1].inputShare, stateSizeBytes);
    +            xor_three(views[k][2].inputShare, privateKey, views[k][0].inputShare, views[k][1].inputShare);
                 tape.pos = 0;
     
                 int[] tmp_int = Pack.littleEndianToInt(tmp, 0, tmp.length/4);
    @@ -1331,8 +1356,7 @@ private int sign_picnic1(int[] privateKey, int[] pubKey, int[] plaintext, byte[]
                 Pack.intToLittleEndian(tmp_int, tmp, 0);
     
                 int[] temp = new int[LOWMC_MAX_WORDS];
    -            xor_three(temp, views[k][0].outputShare, views[k][1].outputShare, views[k][2].outputShare, stateSizeBytes);
    -
    +            xor_three(temp, views[k][0].outputShare, views[k][1].outputShare, views[k][2].outputShare);
     
                 if(!subarrayEquals(temp, pubKey, stateSizeWords))
                 {
    @@ -1354,16 +1378,8 @@ private int sign_picnic1(int[] privateKey, int[] pubKey, int[] plaintext, byte[]
             }
     
             //Generating challenges
    -        int[][][] viewOutputs = new int[numMPCRounds][3][stateSizeBytes];
    -        for (int i = 0; i < numMPCRounds; i++)
    -        {
    -            for (int j = 0; j < 3; j++)
    -            {
    -                viewOutputs[i][j] = views[i][j].outputShare;
    -            }
    -        }
     
    -        H3(pubKey, plaintext, viewOutputs, as, sig.challengeBits, sig.salt, message, gs);
    +        H3(pubKey, plaintext, views, as, sig.challengeBits, sig.salt, message, gs);
     
             //Packing Z
             for (int i = 0; i < numMPCRounds; i++)
    @@ -1373,7 +1389,6 @@ private int sign_picnic1(int[] privateKey, int[] pubKey, int[] plaintext, byte[]
                         views[i], as[i], (transform != TRANSFORM_UR) ? null : gs[i]); //todo check if
             }
     
    -
             return 0;
         }
     
    @@ -1399,12 +1414,14 @@ else if (challenge == 2)
             else 
             {
                 LOG.fine("Invalid challenge");
    +            throw new IllegalArgumentException("challenge");
             }
     
             if (challenge == 1 || challenge == 2)
             {
    -            System.arraycopy(views[2].inputShare, 0, proof.inputShare, 0, stateSizeBytes);
    +            System.arraycopy(views[2].inputShare, 0, proof.inputShare, 0, stateSizeWords);
             }
    +
             System.arraycopy(views[(challenge + 1) % 3].communicatedBits, 0, proof.communicatedBits, 0, andSizeBytes);
     
             System.arraycopy(commitments[(challenge + 2) % 3], 0, proof.view3Commitment, 0, digestSizeBytes);
    @@ -1414,28 +1431,56 @@ else if (challenge == 2)
                 System.arraycopy(gs[(challenge + 2) % 3], 0, proof.view3UnruhG, 0, view3UnruhLength);
             }
         }
    -    
    -    void H3(int[] circuitOutput, int[] plaintext, int[][][] viewOutputs,
    -            byte[][][] as, byte[] challengeBits, byte[] salt,
    -            byte[] message, byte[][][] gs)
    +
    +    private void H3(int[] circuitOutput, int[] plaintext, View[][] views, byte[][][] as, byte[] challengeBits,
    +        byte[] salt, byte[] message, byte[][][] gs)
         {
    -        byte[] hash = new byte[digestSizeBytes];
    +        digest.update((byte) 1);
     
    -        /* Depending on the number of rounds, we might not set part of the last
    -         * byte, make sure it's always zero. */
    -        challengeBits[Utils.numBytes(numMPCRounds * 2) - 1] = 0;
    +        byte[] tmp = new byte[stateSizeWords * 4];
    +        
    +        /* Hash the output share from each view */
    +        for (int i = 0; i < numMPCRounds; i++) 
    +        {
    +            for (int j = 0; j < 3; j++) 
    +            {
    +                Pack.intToLittleEndian(views[i][j].outputShare, tmp, 0);
    +                digest.update(tmp, 0, stateSizeBytes);
    +            }
    +        }
     
    +        implH3(circuitOutput, plaintext, as, challengeBits, salt, message, gs);
    +    }
    +
    +    private void H3(int[] circuitOutput, int[] plaintext, int[][][] viewOutputs, byte[][][] as, byte[] challengeBits,
    +        byte[] salt, byte[] message, byte[][][] gs)
    +    {
             digest.update((byte) 1);
     
    +        byte[] tmp = new byte[stateSizeWords * 4];
    +        
             /* Hash the output share from each view */
             for (int i = 0; i < numMPCRounds; i++) 
             {
                 for (int j = 0; j < 3; j++) 
                 {
    -                digest.update( Pack.intToLittleEndian(viewOutputs[i][j]), 0, stateSizeBytes);
    +                Pack.intToLittleEndian(viewOutputs[i][j], tmp, 0);
    +                digest.update(tmp, 0, stateSizeBytes);
                 }
             }
     
    +        implH3(circuitOutput, plaintext, as, challengeBits, salt, message, gs);
    +    }
    +
    +    private void implH3(int[] circuitOutput, int[] plaintext, byte[][][] as, byte[] challengeBits, byte[] salt,
    +        byte[] message, byte[][][] gs)
    +    {
    +        byte[] hash = new byte[digestSizeBytes];
    +
    +        /* Depending on the number of rounds, we might not set part of the last
    +         * byte, make sure it's always zero. */
    +        challengeBits[Utils.numBytes(numMPCRounds * 2) - 1] = 0;
    +
             /* Hash all the commitments C */
             for (int i = 0; i < numMPCRounds; i++) 
             {
    @@ -1551,7 +1596,7 @@ private void mpc_LowMC(Tape tapes, View[] views, int[] plaintext, int[] slab)
                         current.getData(), current.getMatrixPointer());
             }
     
    -        mpc_xor(slab, slab, stateSizeWords, 3);
    +        mpc_xor(slab, slab, 3);
     
             for (int r = 1; r <= numRounds; r++)
             {
    @@ -1574,7 +1619,7 @@ private void mpc_LowMC(Tape tapes, View[] views, int[] plaintext, int[] slab)
                 mpc_xor_constant(slab, 3*stateSizeWords,
                                  current.getData(), current.getMatrixPointer(), stateSizeWords);
     
    -            mpc_xor(slab, slab, stateSizeWords, 3);
    +            mpc_xor(slab, slab, 3);
             }
     
             for (int i = 0; i < 3; i++)
    @@ -1638,37 +1683,31 @@ private void mpc_substitution(int[] state, Tape rand, View[] views)
         /*** Functions implementing Sign ***/
         private void mpc_AND(int[] in1, int[] in2, int[] out, Tape rand, View[] views)
         {
    -        int[] r = new int[]{
    -                Utils.getBit(rand.tapes[0], rand.pos),
    -                Utils.getBit(rand.tapes[1], rand.pos),
    -                Utils.getBit(rand.tapes[2], rand.pos)
    -        };
    +        int r0 = Utils.getBit(rand.tapes[0], rand.pos);
    +        int r1 = Utils.getBit(rand.tapes[1], rand.pos);
    +        int r2 = Utils.getBit(rand.tapes[2], rand.pos);
     
    -        for (int i = 0; i < 3; i++)
    -        {
    -            out[i] = (in1[i] & in2[(i + 1) % 3]) ^ (in1[(i + 1) % 3] & in2[i])
    -                    ^ (in1[i] & in2[i]) ^ r[i] ^ r[(i + 1) % 3];
    +        out[0] = (in1[0] & in2[1]) ^ (in1[1] & in2[0]) ^ (in1[0] & in2[0]) ^ r0 ^ r1;
    +        out[1] = (in1[1] & in2[2]) ^ (in1[2] & in2[1]) ^ (in1[1] & in2[1]) ^ r1 ^ r2;
    +        out[2] = (in1[2] & in2[0]) ^ (in1[0] & in2[2]) ^ (in1[2] & in2[2]) ^ r2 ^ r0;
    +
    +        Utils.setBit(views[0].communicatedBits, rand.pos, (byte)out[0]);
    +        Utils.setBit(views[1].communicatedBits, rand.pos, (byte)out[1]);
    +        Utils.setBit(views[2].communicatedBits, rand.pos, (byte)out[2]);
     
    -            Utils.setBit(views[i].communicatedBits, rand.pos, (byte) (out[i] & 0xff));
    -        }
             rand.pos++;
         }
     
    -
    -    private void mpc_xor(int[] state, int[] in, int len, int players)
    +    private void mpc_xor(int[] state, int[] in, int players)
         {
    -        for (int player = 0; player < players; player++)
    +        for (int i = 0, count = stateSizeWords * players; i < count; ++i)
             {
    -            for (int i = 0; i < len; i++)
    -            {
    -                state[i + (players+player)*stateSizeWords] = state[i + (players+player)*stateSizeWords]  ^ in[i + player*stateSizeWords];
    -            }
    +            state[players * stateSizeWords + i] ^= in[i];           
             }
         }
     
    -
         private void mpc_matrix_mul(int[] output, int outputOffset, int[] state, int stateOffset,
    -                        int[] matrix, int matrixOffset,  int players)
    +        int[] matrix, int matrixOffset,  int players)
         {
             for (int player = 0; player < players; player++)
             {
    @@ -1683,7 +1722,7 @@ private void mpc_xor_constant(int[] state, int stateOffset, int[] in, int inOffs
         {
             for (int i = 0; i < len; i++)
             {
    -            state[i + stateOffset] = state[i + stateOffset] ^ in[i + inOffset];
    +            state[i + stateOffset] ^= in[i + inOffset];
             }
         }
     
    @@ -1716,11 +1755,12 @@ private boolean createRandomTape(byte[] seed, int seedOffset, byte[] salt, int r
         private byte[] computeSeeds(int[] privateKey, int[] publicKey, int[] plaintext, byte[] message)
         {
             byte[] allSeeds = new byte[seedSizeBytes * (numMPCParties * numMPCRounds) + saltSizeBytes];
    +        byte[] temp = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
     
    -        digest.update(Pack.intToLittleEndian(privateKey), 0, stateSizeBytes);
    +        updateDigest(privateKey, temp);
             digest.update(message, 0, message.length);
    -        digest.update(Pack.intToLittleEndian(publicKey), 0, stateSizeBytes);
    -        digest.update(Pack.intToLittleEndian(plaintext), 0, stateSizeBytes);
    +        updateDigest(publicKey, temp);
    +        updateDigest(plaintext, temp);
             digest.update(Pack.intToLittleEndian(stateSizeBits), 0, 2);
     
             // Derive the N*T seeds + 1 salt
    @@ -1781,7 +1821,7 @@ private boolean sign_picnic3(int[] privateKey, int[] pubKey, int[] plaintext, by
             {
                 msgs[t] = new Msg(this);
                 int[] maskedKey = Pack.littleEndianToInt(inputs[t], 0, stateSizeWords);
    -            xor_array(maskedKey, maskedKey, privateKey, 0,  stateSizeWords);
    +            xor_array(maskedKey, maskedKey, privateKey, 0);
                 int rv = simulateOnline(maskedKey, tapes[t], tmp_shares, msgs[t], plaintext, pubKey);
                 if (rv != 0)
                 {
    @@ -1864,8 +1904,6 @@ static int indexOf(int[] list, int len, int value)
             return -1;
         }
     
    -
    -
         private int[] getMissingLeavesList(int[] challengeC)
         {
             int missingLeavesSize = numMPCRounds - numOpenedRounds;
    @@ -1884,7 +1922,6 @@ private int[] getMissingLeavesList(int[] challengeC)
             return missingLeaves;
         }
     
    -
         private void HCP(byte[] challengeHash, int[] challengeC, int[] challengeP, byte[][] Ch,
                         byte[] hCv, byte[] salt, int[] pubKey, int[] plaintext, byte[] message)
         {
    @@ -1895,10 +1932,12 @@ private void HCP(byte[] challengeHash, int[] challengeC, int[] challengeP, byte[
                 digest.update(Ch[t], 0, digestSizeBytes);
             }
     
    +        byte[] temp = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
    +        
             digest.update(hCv, 0,  digestSizeBytes);
             digest.update(salt, 0, saltSizeBytes);
    -        digest.update(Pack.intToLittleEndian(pubKey), 0, stateSizeBytes);
    -        digest.update(Pack.intToLittleEndian(plaintext), 0, stateSizeBytes);
    +        updateDigest(pubKey, temp);
    +        updateDigest(plaintext, temp);
             digest.update(message, 0, message.length);
             digest.doFinal(challengeHash, 0, digestSizeBytes);
     
    @@ -1914,7 +1953,8 @@ static int bitsToChunks(int chunkLenBits, byte[] input, int inputLen, int[] chun
             {
                 return 0;
             }
    -        int chunkCount = ((inputLen * 8) / chunkLenBits);
    +
    +        int chunkCount = (inputLen * 8) / chunkLenBits;
     
             for (int i = 0; i < chunkCount; i++)
             {
    @@ -1948,8 +1988,6 @@ static int appendUnique(int[] list, int value, int position)
             return position + 1;
         }
     
    -
    -
         private void expandChallengeHash(byte[] challengeHash, int[] challengeC, int[] challengeP)
         {
             // Populate C
    @@ -2026,8 +2064,6 @@ private void commit_v(byte[] digest_arr, byte[] input, Msg msg)
             digest.doFinal(digest_arr, 0, digestSizeBytes);
         }
     
    -
    -
         private int simulateOnline(int[] maskedKey, Tape tape, int[] tmp_shares,
                                   Msg msg, int[] plaintext, int[] pubKey)
         {
    @@ -2037,7 +2073,7 @@ private int simulateOnline(int[] maskedKey, Tape tape, int[] tmp_shares,
     
             KMatricesWithPointer current = lowmcConstants.KMatrix(this,0);
             matrix_mul(roundKey, maskedKey, current.getData(), current.getMatrixPointer()); // roundKey = maskedKey * KMatrix[0]
    -        xor_array(state, roundKey, plaintext,0, stateSizeWords);      // state = plaintext + roundKey
    +        xor_array(state, roundKey, plaintext, 0);      // state = plaintext + roundKey
     
             for (int r = 1; r <= numRounds; r++)
             {
    @@ -2048,11 +2084,11 @@ private int simulateOnline(int[] maskedKey, Tape tape, int[] tmp_shares,
                 matrix_mul(state, state, current.getData(), current.getMatrixPointer()); // state = state * LMatrix (r-1)
     
                 current = lowmcConstants.RConstant(this,r - 1);
    -            xor_array(state, state, current.getData(), current.getMatrixPointer(), stateSizeWords);  // state += RConstant
    +            xor_array(state, state, current.getData(), current.getMatrixPointer());  // state += RConstant
     
                 current = lowmcConstants.KMatrix(this, r);
                 matrix_mul(roundKey, maskedKey, current.getData(), current.getMatrixPointer());
    -            xor_array(state, roundKey, state, 0, stateSizeWords);      // state += roundKey
    +            xor_array(state, roundKey, state, 0);      // state += roundKey
             }
     
             if(!(subarrayEquals(state, pubKey, stateSizeWords)))
    @@ -2078,26 +2114,34 @@ private void createRandomTapes(Tape tape, byte[][] seeds, int seedsOffset, byte[
     
         private static boolean subarrayEquals(byte[] a, byte[] b, int length)
         {
    -        if(a.length < length || b.length < length)
    +        if (a.length < length || b.length < length)
    +        {
                 return false;
    +        }
     
             for (int i = 0; i < length; i++)
             {
    -            if(a[i] != b[i])
    +            if (a[i] != b[i])
    +            {
                     return false;
    +            }
             }
             return true;
         }
     
         private static boolean subarrayEquals(int[] a, int[] b, int length)
         {
    -        if(a.length < length || b.length < length)
    +        if (a.length < length || b.length < length)
    +        {
                 return false;
    +        }
     
             for (int i = 0; i < length; i++)
             {
                 if(a[i] != b[i])
    +            {
                     return false;
    +            }
             }
             return true;
         }
    @@ -2191,7 +2235,6 @@ private void aux_mpc_AND(int mask_a, int mask_b, int fresh_output_mask, Tape tap
             Utils.setBit(tape.tapes[lastParty], tape.pos - 1, (byte) (aux_bit & 0xff));
         }
     
    -
         private boolean contains(int[] list, int len, int value)
         {
             for (int i = 0; i < len; i++)
    @@ -2214,15 +2257,16 @@ private void tapesToWords(int[] shares, Tape tape)
     
         private void getAuxBits(byte[] output, Tape tape)
         {
    -        int last = numMPCParties - 1;
    -        int pos = 0;
    -        int n = stateSizeBits;
    +        byte[] lastTape = tape.tapes[numMPCParties - 1];
    +        int n = stateSizeBits, pos = 0, tapePos = 0;
     
             for(int j = 0; j < numRounds; j++)
             {
    +            tapePos += n;
    +
                 for(int i = 0; i < n; i++)
                 {
    -                Utils.setBit(output, pos++, Utils.getBit(tape.tapes[last], n + n*2*j  + i));
    +                Utils.setBit(output, pos++, Utils.getBit(lastTape, tapePos++));
                 }
             }
         }
    @@ -2243,46 +2287,38 @@ private void commit(byte[] digest_arr, byte[] seed, byte[] aux, byte[] salt, int
     
         private void computeSaltAndRootSeed(byte[] saltAndRoot, int[] privateKey, int[] pubKey, int[] plaintext, byte[] message)
         {
    -        //todo unify conversion
    -        //copy back to byte array
    -        byte[] privatekey_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
    -        byte[] pubkey_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
    -        byte[] plaintext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
    -        Pack.intToLittleEndian(privateKey, privatekey_bytes, 0);
    -        Pack.intToLittleEndian(pubKey, pubkey_bytes, 0);
    -        Pack.intToLittleEndian(plaintext, plaintext_bytes, 0);
    -        privatekey_bytes = Arrays.copyOfRange(privatekey_bytes, 0, stateSizeBytes);
    -        pubkey_bytes = Arrays.copyOfRange(pubkey_bytes, 0, stateSizeBytes);
    -        plaintext_bytes = Arrays.copyOfRange(plaintext_bytes, 0, stateSizeBytes);
    -        //
    +        byte[] temp = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
     
             // init done in constructor
    -        digest.update(privatekey_bytes, 0, stateSizeBytes);
    +        updateDigest(privateKey, temp);
             digest.update(message, 0, message.length);
    -        digest.update(pubkey_bytes, 0, stateSizeBytes);
    -        digest.update(plaintext_bytes, 0, stateSizeBytes);
    -        digest.update(Pack.shortToLittleEndian((short)(stateSizeBits & 0xffff)), 0, 2);
    +        updateDigest(pubKey, temp);
    +        updateDigest(plaintext, temp);
    +        Pack.shortToLittleEndian((short)stateSizeBits, temp, 0);
    +        digest.update(temp, 0, 2);
             digest.doFinal(saltAndRoot, 0, saltAndRoot.length);
         }
     
    +    private void updateDigest(int[] block, byte[] temp)
    +    {
    +        Pack.intToLittleEndian(block, temp, 0);
    +        digest.update(temp, 0, stateSizeBytes);
    +    }
    +
         static boolean is_picnic3(int params)
         {
    -        if (params == 7/*Picnic3_L1*/ ||
    -            params == 8/*Picnic3_L3*/ ||
    -            params == 9/*Picnic3_L5*/ )
    -        {
    -            return true;
    -        }
    -        return false;
    +        return params == 7/*Picnic3_L1*/
    +            || params == 8/*Picnic3_L3*/
    +            || params == 9/*Picnic3_L5*/;
         }
     
         //todo return int;
         public void crypto_sign_keypair(byte[] pk, byte[] sk, SecureRandom random)
         {
             // set array sizes
    -        byte[] plaintext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
    -        byte[] ciphertext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
    -        byte[] data_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
    +        byte[] plaintext_bytes = new byte[stateSizeWords * 4];
    +        byte[] ciphertext_bytes = new byte[stateSizeWords * 4];
    +        byte[] data_bytes = new byte[stateSizeWords * 4];
     
             picnic_keygen(plaintext_bytes, ciphertext_bytes, data_bytes, random);
             picnic_write_public_key(ciphertext_bytes, plaintext_bytes, pk);
    @@ -2325,28 +2361,16 @@ private void picnic_keygen(byte[] plaintext_bytes, byte[] ciphertext_bytes, byte
             int[] data = new int[data_bytes.length/4];
             int[] plaintext = new int[plaintext_bytes.length/4];
             int[] ciphertext = new int[ciphertext_bytes.length/4];
    -        byte[] temp = new byte[stateSizeBytes];
     
             // generate a private key
    -        random.nextBytes(temp);
    -        zeroTrailingBits(temp, stateSizeBits);
    -        System.arraycopy(temp, 0, data_bytes, 0, temp.length);
    -
    -        for (int i = 0; i < data.length; i++)
    -        {
    -            data[i] = Pack.littleEndianToInt(data_bytes, i * 4);
    -        }
    -
    +        random.nextBytes(data_bytes);
    +        Pack.littleEndianToInt(data_bytes, 0, data);
    +        Utils.zeroTrailingBits(data, stateSizeBits);
     
             // generate a plaintext block
    -        random.nextBytes(temp);
    -        zeroTrailingBits(temp, stateSizeBits);
    -        System.arraycopy(temp, 0, plaintext_bytes, 0, temp.length);
    -
    -        for (int i = 0; i < plaintext.length; i++)
    -        {
    -            plaintext[i] = Pack.littleEndianToInt(plaintext_bytes, i * 4);
    -        }
    +        random.nextBytes(plaintext_bytes);
    +        Pack.littleEndianToInt(plaintext_bytes, 0, plaintext);
    +        Utils.zeroTrailingBits(plaintext, stateSizeBits);
     
             // computer ciphertext
             LowMCEnc(plaintext, ciphertext, data);
    @@ -2371,7 +2395,7 @@ private void LowMCEnc(int[] plaintext, int[] output, int[] key)
             KMatricesWithPointer current = lowmcConstants.KMatrix(this,0);
             matrix_mul(roundKey, key, current.getData(), current.getMatrixPointer());
     
    -        xor_array(output, output, roundKey, 0,  stateSizeWords);
    +        xor_array(output, output, roundKey, 0);
     
             for (int r = 1; r <= numRounds; r++)
             {
    @@ -2384,8 +2408,8 @@ private void LowMCEnc(int[] plaintext, int[] output, int[] key)
                 matrix_mul(output, output, current.getData(), current.getMatrixPointer());
     
                 current = lowmcConstants.RConstant(this,r-1);
    -            xor_array(output, output, current.getData(), current.getMatrixPointer(), stateSizeWords);
    -            xor_array(output, output, roundKey, 0, stateSizeWords);
    +            xor_array(output, output, current.getData(), current.getMatrixPointer());
    +            xor_array(output, output, roundKey, 0);
             }
         }
     
    @@ -2404,18 +2428,17 @@ private void substitution(int[] state)
             }
         }
     
    -    private void xor_three(int[] output, int[] in1, int[] in2, int[] in3, int lenBytes)
    +    private void xor_three(int[] output, int[] in1, int[] in2, int[] in3)
         {
    -        int wholeWords = stateSizeWords;
    -        for(int i = 0; i < wholeWords; i++)
    +        for(int i = 0; i < stateSizeWords; i++)
             {
                 output[i] = in1[i] ^ in2[i] ^ in3[i];
             }
         }
     
    -    protected void xor_array(int[] out, int[] in1, int[] in2, int in2_offset, int length)
    +    protected void xor_array(int[] out, int[] in1, int[] in2, int in2_offset)
         {
    -        for (int i = 0; i < length; i++)
    +        for (int i = 0; i < stateSizeWords; i++)
             {
                 out[i] = in1[i] ^ in2[i + in2_offset];
             }
    @@ -2464,13 +2487,4 @@ protected void matrix_mul_offset(int[] output, int outputOffset,
     
             System.arraycopy(temp, 0, output, outputOffset, stateSizeWords);
         }
    -
    -    private void zeroTrailingBits(byte[] data, int bitLength)
    -    {
    -        int byteLength = Utils.numBytes(bitLength);
    -        for (int i = bitLength; i < byteLength * 8; i++)
    -        {
    -            Utils.setBit(data, i, (byte) 0);
    -        }
    -    }
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/Signature.java b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/Signature.java
    index d04d4e8f75..b99f1b55f5 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/Signature.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/Signature.java
    @@ -2,9 +2,9 @@
     
     class Signature
     {
    -    byte[] challengeBits;
    -    byte[] salt;
    -    Proof[] proofs;
    +    final byte[] challengeBits;
    +    final byte[] salt;
    +    final Proof[] proofs;
         Signature(PicnicEngine engine)
         {
             salt = new byte[PicnicEngine.saltSizeBytes];
    @@ -18,18 +18,18 @@ class Signature
     
         public static class Proof
         {
    -        byte[] seed1;
    -        byte[] seed2;
    -        int[] inputShare;     // Input share of the party which does not derive it from the seed (not included if challenge is 0)
    -        byte[] communicatedBits;
    -        byte[] view3Commitment;
    -        byte[] view3UnruhG;     // we include the max length, but we will only serialize the bytes we use
    +        final byte[] seed1;
    +        final byte[] seed2;
    +        final int[] inputShare;     // Input share of the party which does not derive it from the seed (not included if challenge is 0)
    +        final byte[] communicatedBits;
    +        final byte[] view3Commitment;
    +        final byte[] view3UnruhG;     // we include the max length, but we will only serialize the bytes we use
     
             Proof(PicnicEngine engine)
             {
                 seed1 = new byte[engine.seedSizeBytes];
                 seed2 = new byte[engine.seedSizeBytes];
    -            inputShare = new int[engine.stateSizeBytes];
    +            inputShare = new int[engine.stateSizeWords];
                 communicatedBits = new byte[engine.andSizeBytes];
                 view3Commitment = new byte[engine.digestSizeBytes];
                 if (engine.UnruhGWithInputBytes > 0)
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/Tape.java b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/Tape.java
    index 1b67dae274..3badebdd25 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/Tape.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/Tape.java
    @@ -1,6 +1,5 @@
     package org.bouncycastle.pqc.crypto.picnic;
     
    -import org.bouncycastle.util.Arrays;
     import org.bouncycastle.util.Pack;
     
     class Tape
    @@ -61,19 +60,17 @@ protected void computeAuxTape(byte[] inputs)
     //        for (int i = 0; i < key0.length; i++)
     //        {System.out.printf("%08x ", key[i]);}System.out.println();
     
    -
    -        if(inputs != null)
    +        if (inputs != null)
             {
    -            Pack.intToLittleEndian(Arrays.copyOf(key, engine.stateSizeWords), inputs, 0);
    +            Pack.intToLittleEndian(key, 0, engine.stateSizeWords, inputs, 0);
             }
     
    -
             for (int r = engine.numRounds; r > 0; r--)
             {
                 current = engine.lowmcConstants.KMatrix(engine, r);
                 engine.matrix_mul(roundKey, key, current.getData(), current.getMatrixPointer());    // roundKey = key * KMatrix(r)
     
    -            engine.xor_array(x, x, roundKey, 0, engine.stateSizeWords);
    +            engine.xor_array(x, x, roundKey, 0);
     
                 current = engine.lowmcConstants.LMatrixInv(engine, r-1);
                 engine.matrix_mul(y, x, current.getData(), current.getMatrixPointer());
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/Utils.java b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/Utils.java
    index 3a7b0541e3..cb0014ec18 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/Utils.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/Utils.java
    @@ -93,6 +93,14 @@ protected static byte getBit(byte[] array, int bitNumber)
             return (byte)((array[arrayPos] >>> bitPos) & 1);
         }
     
    +    /* Get a crumb (i.e. two bits) from a byte array. */
    +    protected static byte getCrumbAligned(byte[] array, int crumbNumber)
    +    {
    +        int arrayPos = crumbNumber >>> 2, bitPos = ((crumbNumber << 1) & 6) ^ 6;
    +        int b = (int)array[arrayPos] >>> bitPos;
    +        return (byte)((b & 1) << 1 | (b & 2) >> 1);
    +    }
    +
         protected static int getBit(int word, int bitNumber)
         {
             int bitPos = bitNumber ^ 7;
    @@ -132,4 +140,27 @@ protected static void setBit(int[] array, int bitNumber, int val)
             t |= val << bitPos;
             array[arrayPos] = t;
         }
    +
    +    protected static void zeroTrailingBits(int[] data, int bitLength)
    +    {
    +        int partialWord = bitLength & 31;
    +        if (partialWord != 0)
    +        {
    +            data[bitLength >>> 5] &= getTrailingBitsMask(bitLength);
    +        }
    +    }
    +
    +    protected static int getTrailingBitsMask(int bitLength)
    +    {
    +        int partialShift = bitLength & ~7;
    +        int mask = ~(0xFFFFFFFF << partialShift);
    +
    +        int partialByte = bitLength & 7;
    +        if (partialByte != 0)
    +        {
    +            mask ^= ((0xFF00 >>> partialByte) & 0xFF) << partialShift;
    +        }
    +
    +        return mask;
    +    }    
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/View.java b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/View.java
    index d0537ade32..538bfa6b13 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/View.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/picnic/View.java
    @@ -2,13 +2,13 @@
     
     class View
     {
    -    int[] inputShare;
    -    byte[] communicatedBits;
    -    int[] outputShare;
    +    final int[] inputShare;
    +    final byte[] communicatedBits;
    +    final int[] outputShare;
         public View(PicnicEngine engine)
         {
    -        inputShare = new int[engine.stateSizeBytes] ;
    +        inputShare = new int[engine.stateSizeWords] ;
             communicatedBits = new byte[engine.andSizeBytes];
    -        outputShare = new int[engine.stateSizeBytes] ;
    +        outputShare = new int[engine.stateSizeWords] ;
         }
     }
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/saber/Symmetric.java b/core/src/main/java/org/bouncycastle/pqc/crypto/saber/Symmetric.java
    index ca65c9555c..8fb1e83c5c 100644
    --- a/core/src/main/java/org/bouncycastle/pqc/crypto/saber/Symmetric.java
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/saber/Symmetric.java
    @@ -1,5 +1,6 @@
     package org.bouncycastle.pqc.crypto.saber;
     
    +import org.bouncycastle.crypto.StreamCipher;
     import org.bouncycastle.crypto.Xof;
     import org.bouncycastle.crypto.digests.SHA256Digest;
     import org.bouncycastle.crypto.digests.SHA3Digest;
    @@ -53,24 +54,20 @@ void prf(byte[] out, byte[] in, int inLen, int outLen)
                 shakeDigest.update(in, 0, inLen);
                 shakeDigest.doFinal(out, 0, outLen);
             }
    -
    -
         }
    +    
         static class AesSymmetric
             extends Symmetric
         {
    -
             private final SHA256Digest sha256Digest;
             private final SHA512Digest sha512Digest;
    -
    -        private final SICBlockCipher cipher;
    -
    +        private final StreamCipher cipher;
     
             AesSymmetric()
             {
                 sha256Digest = new SHA256Digest();
                 sha512Digest = new SHA512Digest();
    -            this.cipher = new SICBlockCipher(new AESEngine());
    +            this.cipher = SICBlockCipher.newInstance(AESEngine.newInstance());
             }
             @Override
             void hash_h(byte[] out, byte[] in, int outOffset)
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/ADRS.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/ADRS.java
    new file mode 100644
    index 0000000000..f71f74a4a5
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/ADRS.java
    @@ -0,0 +1,114 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Pack;
    +
    +class ADRS
    +{
    +    public static final int WOTS_HASH = 0;
    +    public static final int WOTS_PK = 1;
    +    public static final int TREE = 2;
    +    public static final int FORS_TREE = 3;
    +    public static final int FORS_PK = 4;
    +    public static final int WOTS_PRF = 5;
    +    public static final int FORS_PRF = 6;
    +    
    +    static final int OFFSET_LAYER = 0;
    +    static final int OFFSET_TREE = 4;
    +    static final int OFFSET_TREE_HGT = 24;
    +    static final int OFFSET_TREE_INDEX = 28;
    +    static final int OFFSET_TYPE = 16;
    +    static final int OFFSET_KP_ADDR = 20;
    +    static final int OFFSET_CHAIN_ADDR = 24;
    +    static final int OFFSET_HASH_ADDR = 28;
    +    
    +    final byte[] value = new byte[32];
    +
    +    ADRS()
    +    {
    +    }
    +
    +    ADRS(ADRS adrs)
    +    {
    +        System.arraycopy(adrs.value, 0, this.value, 0, adrs.value.length);
    +    }
    +
    +    public void setLayerAddress(int layer)
    +    {
    +        Pack.intToBigEndian(layer, value, OFFSET_LAYER);
    +    }
    +
    +    public int getLayerAddress()
    +    {
    +        return Pack.bigEndianToInt(value, OFFSET_LAYER);
    +    }
    +
    +    public void setTreeAddress(long tree)
    +    {
    +        // tree address is 12 bytes
    +        Pack.longToBigEndian(tree, value, OFFSET_TREE + 4);
    +    }
    +
    +    public long getTreeAddress()
    +    {
    +        return Pack.bigEndianToLong(value, OFFSET_TREE + 4);
    +    }
    +
    +    public void setTreeHeight(int height)
    +    {
    +        Pack.intToBigEndian(height, value, OFFSET_TREE_HGT);
    +    }
    +
    +    public int getTreeHeight()
    +    {
    +        return Pack.bigEndianToInt(value, OFFSET_TREE_HGT);
    +    }
    +
    +    public void setTreeIndex(int index)
    +    {
    +        Pack.intToBigEndian(index, value, OFFSET_TREE_INDEX);
    +    }
    +
    +    public int getTreeIndex()
    +    {
    +        return Pack.bigEndianToInt(value, OFFSET_TREE_INDEX);
    +    }
    +
    +    // resets part of value to zero in line with 2.7.3
    +    public void setType(int type)
    +    {
    +        Pack.intToBigEndian(type, value, OFFSET_TYPE);
    +
    +        Arrays.fill(value, 20, value.length, (byte)0);
    +    }
    +
    +    public void changeType(int type)
    +    {
    +        Pack.intToBigEndian(type, value, OFFSET_TYPE);
    +    }
    +
    +    public int getType()
    +    {
    +        return Pack.bigEndianToInt(value, OFFSET_TYPE);
    +    }
    +
    +    public void setKeyPairAddress(int keyPairAddr)
    +    {
    +        Pack.intToBigEndian(keyPairAddr, value, OFFSET_KP_ADDR);
    +    }
    +
    +    public int getKeyPairAddress()
    +    {
    +        return Pack.bigEndianToInt(value, OFFSET_KP_ADDR);
    +    }
    +
    +    public void setHashAddress(int hashAddr)
    +    {
    +        Pack.intToBigEndian(hashAddr, value, OFFSET_HASH_ADDR);
    +    }          
    +
    +    public void setChainAddress(int chainAddr)
    +    {
    +        Pack.intToBigEndian(chainAddr, value, OFFSET_CHAIN_ADDR);
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/Fors.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/Fors.java
    new file mode 100644
    index 0000000000..cb134e2f34
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/Fors.java
    @@ -0,0 +1,164 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +import java.math.BigInteger;
    +import java.util.LinkedList;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +class Fors
    +{
    +    SLHDSAEngine engine;
    +
    +    public Fors(SLHDSAEngine engine)
    +    {
    +        this.engine = engine;
    +    }
    +
    +    // Input: Secret seed SK.seed, start index s, target node height z, public seed PK.seed, address ADRS
    +    // Output: n-byte root node - top node on Stack
    +    byte[] treehash(byte[] skSeed, int s, int z, byte[] pkSeed, ADRS adrsParam)
    +    {
    +        LinkedList stack = new LinkedList();
    +
    +        if (s % (1 << z) != 0)
    +        {
    +            return null;
    +        }
    +
    +        ADRS adrs = new ADRS(adrsParam);
    +
    +        for (int idx = 0; idx < (1 << z); idx++)
    +        {
    +            adrs.setType(ADRS.FORS_PRF);
    +            adrs.setKeyPairAddress(adrsParam.getKeyPairAddress());
    +            adrs.setTreeHeight(0);
    +            adrs.setTreeIndex(s + idx);
    +
    +            byte[] sk = engine.PRF(pkSeed, skSeed, adrs);
    +
    +            adrs.changeType(ADRS.FORS_TREE);
    +
    +            byte[] node = engine.F(pkSeed, adrs, sk);
    +
    +            adrs.setTreeHeight(1);
    +
    +            // while ( Top node on Stack has same height as node )
    +            while (!stack.isEmpty()
    +                && ((NodeEntry)stack.get(0)).nodeHeight == adrs.getTreeHeight())
    +            {
    +                adrs.setTreeIndex((adrs.getTreeIndex() - 1) / 2);
    +                NodeEntry current = ((NodeEntry)stack.remove(0));
    +
    +                node = engine.H(pkSeed, adrs, current.nodeValue, node);
    +                //topmost node is now one layer higher
    +                adrs.setTreeHeight(adrs.getTreeHeight() + 1);
    +            }
    +
    +            stack.add(0, new NodeEntry(node, adrs.getTreeHeight()));
    +        }
    +
    +        return ((NodeEntry)stack.get(0)).nodeValue;
    +    }
    +
    +    public SIG_FORS[] sign(byte[] md, byte[] skSeed, byte[] pkSeed, ADRS paramAdrs)
    +    {
    +        ADRS adrs = new ADRS(paramAdrs);
    +
    +//        int[] idxs = message_to_idxs(md, engine.K, engine.A);
    +        int[] idxs = base2B(md, engine.A, engine.K);
    +        SIG_FORS[] sig_fors = new SIG_FORS[engine.K];
    +// compute signature elements
    +        int t = engine.T;
    +        for (int i = 0; i < engine.K; i++)
    +        {
    +// get next index
    +            int idx = idxs[i];
    +// pick private key element
    +            adrs.setType(ADRS.FORS_PRF);
    +            adrs.setKeyPairAddress(paramAdrs.getKeyPairAddress());
    +            adrs.setTreeHeight(0);
    +            adrs.setTreeIndex(i * t + idx);
    +
    +            byte[] sk = engine.PRF(pkSeed, skSeed, adrs);
    +
    +            adrs.changeType(ADRS.FORS_TREE);
    +
    +            byte[][] authPath = new byte[engine.A][];
    +// compute auth path
    +            for (int j = 0; j < engine.A; j++)
    +            {
    +                int s = (idx / (1 << j)) ^ 1;
    +                authPath[j] = treehash(skSeed, i * t + s * (1 << j), j, pkSeed, adrs);
    +            }
    +            sig_fors[i] = new SIG_FORS(sk, authPath);
    +        }
    +        return sig_fors;
    +    }
    +
    +    public byte[] pkFromSig(SIG_FORS[] sig_fors, byte[] message, byte[] pkSeed, ADRS adrs)
    +    {
    +        byte[][] node = new byte[2][];
    +        byte[][] root = new byte[engine.K][];
    +        int t = engine.T;
    +
    +//        int[] idxs = message_to_idxs(message, engine.K, engine.A);
    +        int[] idxs = base2B(message, engine.A, engine.K);
    +        // compute roots
    +        for (int i = 0; i < engine.K; i++)
    +        {
    +            // get next index
    +            int idx = idxs[i];
    +            // compute leaf
    +            byte[] sk = sig_fors[i].getSK();
    +            adrs.setTreeHeight(0);
    +            adrs.setTreeIndex(i * t + idx);
    +            node[0] = engine.F(pkSeed, adrs, sk);
    +            // compute root from leaf and AUTH
    +            byte[][] authPath = sig_fors[i].getAuthPath();
    +
    +            adrs.setTreeIndex(i * t + idx);
    +            for (int j = 0; j < engine.A; j++)
    +            {
    +                adrs.setTreeHeight(j + 1);
    +                if (((idx / (1 << j)) % 2) == 0)
    +                {
    +                    adrs.setTreeIndex(adrs.getTreeIndex() / 2);
    +                    node[1] = engine.H(pkSeed, adrs, node[0], authPath[j]);
    +                }
    +                else
    +                {
    +                    adrs.setTreeIndex((adrs.getTreeIndex() - 1) / 2);
    +                    node[1] = engine.H(pkSeed, adrs, authPath[j], node[0]);
    +                }
    +                node[0] = node[1];
    +            }
    +            root[i] = node[0];
    +        }
    +        ADRS forspkADRS = new ADRS(adrs); // copy address to create FTS public key address
    +        forspkADRS.setType(ADRS.FORS_PK);
    +        forspkADRS.setKeyPairAddress(adrs.getKeyPairAddress());
    +        return engine.T_l(pkSeed, forspkADRS, Arrays.concatenate(root));
    +    }
    +
    +    static int[] base2B(byte[] msg, int b, int outLen)
    +    {
    +        int[] baseB = new int[outLen];
    +        int i = 0;
    +        int bits = 0;
    +        BigInteger total = BigInteger.ZERO;
    +
    +        for (int o = 0; o < outLen; o++)
    +        {
    +            while (bits < b)
    +            {
    +                total = total.shiftLeft(8).add(BigInteger.valueOf(msg[i] & 0xff));
    +                i+= 1;
    +                bits += 8;
    +            }
    +            bits -= b;
    +            baseB[o] = (total.shiftRight(bits).mod(BigInteger.valueOf(2).pow(b))).intValue();
    +        }
    +
    +        return baseB;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/HT.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/HT.java
    new file mode 100644
    index 0000000000..d1d465f552
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/HT.java
    @@ -0,0 +1,213 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +import java.util.LinkedList;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +class HT
    +{
    +    private final byte[] skSeed;
    +    private final byte[] pkSeed;
    +    SLHDSAEngine engine;
    +    WotsPlus wots;
    +
    +    final byte[] htPubKey;
    +
    +    public HT(SLHDSAEngine engine, byte[] skSeed, byte[] pkSeed)
    +    {
    +        this.skSeed = skSeed;
    +        this.pkSeed = pkSeed;
    +
    +        this.engine = engine;
    +        this.wots = new WotsPlus(engine);
    +
    +        ADRS adrs = new ADRS();
    +        adrs.setLayerAddress(engine.D - 1);
    +        adrs.setTreeAddress(0);
    +
    +        if (skSeed != null)
    +        {
    +            htPubKey = xmss_PKgen(skSeed, pkSeed, adrs);
    +        }
    +        else
    +        {
    +            htPubKey = null;
    +        }
    +    }
    +
    +    byte[] sign(byte[] M, long idx_tree, int idx_leaf)
    +    {
    +        // init
    +        ADRS adrs = new ADRS();
    +        // sign
    +       // adrs.setType(ADRS.TREE);
    +        adrs.setLayerAddress(0);
    +        adrs.setTreeAddress(idx_tree);
    +        SIG_XMSS SIG_tmp = xmss_sign(M, skSeed, idx_leaf, pkSeed, adrs);
    +        SIG_XMSS[] SIG_HT = new SIG_XMSS[engine.D];
    +        SIG_HT[0] = SIG_tmp;
    +
    +        adrs.setLayerAddress(0);
    +        adrs.setTreeAddress(idx_tree);
    +
    +        byte[] root = xmss_pkFromSig(idx_leaf, SIG_tmp, M, pkSeed, adrs);
    +
    +        for (int j = 1; j < engine.D; j++)
    +        {
    +            idx_leaf = (int)(idx_tree & ((1 << engine.H_PRIME) - 1));  // least significant bits of idx_tree;
    +            idx_tree >>>= engine.H_PRIME; // most significant bits of idx_tree;
    +            adrs.setLayerAddress(j);
    +            adrs.setTreeAddress(idx_tree);
    +            SIG_tmp = xmss_sign(root, skSeed, idx_leaf, pkSeed, adrs);
    +            SIG_HT[j] = SIG_tmp;
    +            if (j < engine.D - 1)
    +            {
    +                root = xmss_pkFromSig(idx_leaf, SIG_tmp, root, pkSeed, adrs);
    +            }
    +        }
    +
    +        byte[][] totSigs = new byte[SIG_HT.length][];
    +        for (int i = 0; i != totSigs.length; i++)
    +        {
    +            totSigs[i] = Arrays.concatenate(SIG_HT[i].sig, Arrays.concatenate(SIG_HT[i].auth));
    +        }
    +
    +        return Arrays.concatenate(totSigs);
    +    }
    +
    +    byte[] xmss_PKgen(byte[] skSeed, byte[] pkSeed, ADRS adrs)
    +    {
    +        return treehash(skSeed, 0, engine.H_PRIME, pkSeed, adrs);
    +    }
    +
    +    // Input: index idx, XMSS signature SIG_XMSS = (sig || AUTH), n-byte message M, public seed PK.seed, address ADRS
    +    // Output: n-byte root value node[0]
    +    byte[] xmss_pkFromSig(int idx, SIG_XMSS sig_xmss, byte[] M, byte[] pkSeed, ADRS paramAdrs)
    +    {
    +        ADRS adrs = new ADRS(paramAdrs);
    +
    +        // compute WOTS+ pk from WOTS+ sig
    +        adrs.setType(ADRS.WOTS_HASH);
    +        adrs.setKeyPairAddress(idx);
    +        byte[] sig = sig_xmss.getWOTSSig();
    +        byte[][] AUTH = sig_xmss.getXMSSAUTH();
    +
    +        byte[] node0 = wots.pkFromSig(sig, M, pkSeed, adrs);
    +        byte[] node1 = null;
    +
    +        // compute root from WOTS+ pk and AUTH
    +        adrs.setType(ADRS.TREE);
    +        adrs.setTreeIndex(idx);
    +        for (int k = 0; k < engine.H_PRIME; k++)
    +        {
    +            adrs.setTreeHeight(k + 1);
    +            if (((idx / (1 << k)) % 2) == 0)
    +            {
    +                adrs.setTreeIndex(adrs.getTreeIndex() / 2);
    +                node1 = engine.H(pkSeed, adrs, node0, AUTH[k]);
    +            }
    +            else
    +            {
    +                adrs.setTreeIndex((adrs.getTreeIndex() - 1) / 2);
    +                node1 = engine.H(pkSeed, adrs, AUTH[k], node0);
    +            }
    +            node0 = node1;
    +        }
    +        return node0;
    +    }
    +
    +    //    # Input: n-byte message M, secret seed SK.seed, index idx, public seed PK.seed,
    +    //    address ADRS
    +    //    # Output: XMSS signature SIG_XMSS = (sig || AUTH)
    +    SIG_XMSS xmss_sign(byte[] M, byte[] skSeed, int idx, byte[] pkSeed, ADRS paramAdrs)
    +    {
    +        byte[][] AUTH = new byte[engine.H_PRIME][];
    +
    +        ADRS adrs = new ADRS(paramAdrs);
    +
    +        adrs.setType(ADRS.TREE);
    +        adrs.setLayerAddress(paramAdrs.getLayerAddress());
    +        adrs.setTreeAddress(paramAdrs.getTreeAddress());
    +
    +        // build authentication path
    +        for (int j = 0; j < engine.H_PRIME; j++)
    +        {
    +            int k = (idx / (1 << j)) ^ 1;
    +            AUTH[j] = treehash(skSeed, k * (1 << j), j, pkSeed, adrs);
    +        }
    +        adrs = new ADRS(paramAdrs);
    +        adrs.setType(ADRS.WOTS_PK);
    +        adrs.setKeyPairAddress(idx);
    +
    +        byte[] sig = wots.sign(M, skSeed, pkSeed, adrs);
    +
    +        return new SIG_XMSS(sig, AUTH);
    +    }
    +
    +    //
    +    // Input: Secret seed SK.seed, start index s, target node height z, public seed
    +    //PK.seed, address ADRS
    +    // Output: n-byte root node - top node on Stack
    +    byte[] treehash(byte[] skSeed, int s, int z, byte[] pkSeed, ADRS adrsParam)
    +    {
    +        ADRS adrs = new ADRS(adrsParam);
    +
    +        LinkedList stack = new LinkedList();
    +
    +        if (s % (1 << z) != 0)
    +        {
    +            return null;
    +        }
    +
    +        for (int idx = 0; idx < (1 << z); idx++)
    +        {
    +            adrs.setType(ADRS.WOTS_HASH);
    +            adrs.setKeyPairAddress(s + idx);
    +            byte[] node = wots.pkGen(skSeed, pkSeed, adrs);
    +
    +            adrs.setType(ADRS.TREE);
    +            adrs.setTreeHeight(1);
    +            adrs.setTreeIndex(s + idx);
    +
    +            // while ( Top node on Stack has same height as node )
    +            while (!stack.isEmpty()
    +                && ((NodeEntry)stack.get(0)).nodeHeight == adrs.getTreeHeight())
    +            {
    +                adrs.setTreeIndex((adrs.getTreeIndex() - 1) / 2);
    +                NodeEntry current = ((NodeEntry)stack.remove(0));
    +
    +                node = engine.H(pkSeed, adrs, current.nodeValue, node);
    +                //topmost node is now one layer higher
    +                adrs.setTreeHeight(adrs.getTreeHeight() + 1);
    +            }
    +
    +            stack.add(0, new NodeEntry(node, adrs.getTreeHeight()));
    +        }
    +
    +        return ((NodeEntry)stack.get(0)).nodeValue;
    +    }
    +
    +    //    # Input: Message M, signature SIG_HT, public seed PK.seed, tree index idx_tree,
    +//    leaf index idx_leaf, HT public key PK_HT.
    +//    # Output: Boolean
    +    public boolean verify(byte[] M, SIG_XMSS[] sig_ht, byte[] pkSeed, long idx_tree, int idx_leaf, byte[] PK_HT)
    +    {
    +        // init
    +        ADRS adrs = new ADRS();
    +        // verify
    +        SIG_XMSS SIG_tmp = sig_ht[0];
    +        adrs.setLayerAddress(0);
    +        adrs.setTreeAddress(idx_tree);
    +        byte[] node = xmss_pkFromSig(idx_leaf, SIG_tmp, M, pkSeed, adrs);
    +        for (int j = 1; j < engine.D; j++)
    +        {
    +            idx_leaf = (int)(idx_tree & ((1 << engine.H_PRIME) - 1));  // least significant bits of idx_tree;
    +            idx_tree >>>= engine.H_PRIME; // most significant bits of idx_tree;
    +            SIG_tmp = sig_ht[j];
    +            adrs.setLayerAddress(j);
    +            adrs.setTreeAddress(idx_tree);
    +            node = xmss_pkFromSig(idx_leaf, SIG_tmp, node, pkSeed, adrs);
    +        }
    +        return Arrays.areEqual(PK_HT, node);
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/HashSLHDSASigner.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/HashSLHDSASigner.java
    new file mode 100644
    index 0000000000..41afbf09e3
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/HashSLHDSASigner.java
    @@ -0,0 +1,286 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +import java.io.IOException;
    +import java.security.SecureRandom;
    +
    +import org.bouncycastle.asn1.ASN1Encoding;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.crypto.CipherParameters;
    +import org.bouncycastle.crypto.CryptoException;
    +import org.bouncycastle.crypto.DataLengthException;
    +import org.bouncycastle.crypto.Digest;
    +import org.bouncycastle.crypto.Signer;
    +import org.bouncycastle.crypto.digests.SHA256Digest;
    +import org.bouncycastle.crypto.digests.SHA512Digest;
    +import org.bouncycastle.crypto.digests.SHAKEDigest;
    +import org.bouncycastle.crypto.params.ParametersWithRandom;
    +import org.bouncycastle.pqc.crypto.DigestUtils;
    +import org.bouncycastle.util.Arrays;
    +
    +/**
    + * SLH-DA signer.
    + */
    +public class HashSLHDSASigner
    +    implements Signer
    +{
    +    private SLHDSAPrivateKeyParameters privKey;
    +    private SLHDSAPublicKeyParameters pubKey;
    +
    +    private SecureRandom random;
    +    private Digest digest;
    +    private byte[] digestOidEncoding;
    +
    +    public HashSLHDSASigner()
    +    {
    +    }
    +
    +    public void init(boolean forSigning, CipherParameters param)
    +    {
    +        if (forSigning)
    +        {
    +            if (param instanceof ParametersWithRandom)
    +            {
    +                privKey = ((SLHDSAPrivateKeyParameters)((ParametersWithRandom)param).getParameters());
    +                this.random = ((ParametersWithRandom)param).getRandom();
    +            }
    +            else
    +            {
    +                privKey = (SLHDSAPrivateKeyParameters)param;
    +            }
    +
    +            initDigest(privKey);
    +        }
    +        else
    +        {
    +            pubKey = (SLHDSAPublicKeyParameters)param;
    +
    +            initDigest(pubKey);
    +        }
    +
    +        reset();
    +    }
    +
    +    private void initDigest(SLHDSAKeyParameters key)
    +    {
    +        digest = createDigest(key);
    +
    +        ASN1ObjectIdentifier oid = DigestUtils.getDigestOid(digest.getAlgorithmName());
    +        try
    +        {
    +            digestOidEncoding = oid.getEncoded(ASN1Encoding.DER);
    +        }
    +        catch (IOException e)
    +        {
    +            throw new IllegalStateException("oid encoding failed: " + e.getMessage());
    +        }
    +    }
    +
    +    @Override
    +    public void update(byte b)
    +    {
    +        digest.update(b);
    +    }
    +
    +    @Override
    +    public void update(byte[] in, int off, int len)
    +    {
    +        digest.update(in, off, len);
    +    }
    +
    +    @Override
    +    public byte[] generateSignature() throws CryptoException, DataLengthException
    +    {
    +        SLHDSAEngine engine = privKey.getParameters().getEngine();
    +
    +        engine.init(privKey.pk.seed);
    +        byte[] ctx = privKey.getContext();
    +
    +        if (ctx.length > 255)
    +        {
    +            throw new RuntimeException("Context too long");
    +        }
    +
    +        byte[] hash = new byte[digest.getDigestSize()];
    +        digest.doFinal(hash, 0);
    +
    +        byte[] ds_message = new byte[1 + 1 + ctx.length + digestOidEncoding.length + hash.length];
    +        ds_message[0] = 1;
    +        ds_message[1] = (byte)ctx.length;
    +        System.arraycopy(ctx, 0, ds_message, 2, ctx.length);
    +        System.arraycopy(digestOidEncoding, 0, ds_message, 2 + ctx.length, digestOidEncoding.length);
    +        System.arraycopy(hash, 0, ds_message, 2 + ctx.length + digestOidEncoding.length, hash.length);
    +
    +        // generate randomizer
    +        byte[] optRand = new byte[engine.N];
    +        return internalGenerateSignature(ds_message, optRand);
    +    }
    +
    +    @Override
    +    public boolean verifySignature(byte[] signature)
    +    {
    +        byte[] ctx = pubKey.getContext();
    +
    +        if (ctx.length > 255)
    +        {
    +            throw new RuntimeException("Context too long");
    +        }
    +
    +        byte[] hash = new byte[digest.getDigestSize()];
    +        digest.doFinal(hash, 0);
    +
    +        byte[] ds_message = new byte[1 + 1 + ctx.length + digestOidEncoding.length + hash.length];
    +        ds_message[0] = 1;
    +        ds_message[1] = (byte)ctx.length;
    +        System.arraycopy(ctx, 0, ds_message, 2, ctx.length);
    +        System.arraycopy(digestOidEncoding, 0, ds_message, 2 + ctx.length, digestOidEncoding.length);
    +        System.arraycopy(hash, 0, ds_message, 2 + ctx.length + digestOidEncoding.length, hash.length);
    +
    +        return internalVerifySignature(ds_message, signature);
    +    }
    +
    +    @Override
    +    public void reset()
    +    {
    +        digest.reset();
    +    }
    +
    +    public byte[] internalGenerateSignature(byte[] message, byte[] optRand)
    +    {
    +        SLHDSAEngine engine = privKey.getParameters().getEngine();
    +        engine.init(privKey.pk.seed);
    +
    +        if (optRand == null)
    +        {
    +            optRand = new byte[engine.N];
    +            System.arraycopy(privKey.pk.seed, 0, optRand, 0, optRand.length);
    +        }
    +
    +        Fors fors = new Fors(engine);
    +        byte[] R = engine.PRF_msg(privKey.sk.prf, optRand, message);
    +
    +        IndexedDigest idxDigest = engine.H_msg(R, privKey.pk.seed, privKey.pk.root, message);
    +        byte[] mHash = idxDigest.digest;
    +        long idx_tree = idxDigest.idx_tree;
    +        int idx_leaf = idxDigest.idx_leaf;
    +        // FORS sign
    +        ADRS adrs = new ADRS();
    +        adrs.setType(ADRS.FORS_TREE);
    +        adrs.setTreeAddress(idx_tree);
    +        adrs.setKeyPairAddress(idx_leaf);
    +        SIG_FORS[] sig_fors = fors.sign(mHash, privKey.sk.seed, privKey.pk.seed, adrs);
    +        // get FORS public key - spec shows M?
    +        adrs = new ADRS();
    +        adrs.setType(ADRS.FORS_TREE);
    +        adrs.setTreeAddress(idx_tree);
    +        adrs.setKeyPairAddress(idx_leaf);
    +        byte[] PK_FORS = fors.pkFromSig(sig_fors, mHash, privKey.pk.seed, adrs);
    +
    +        // sign FORS public key with HT
    +        ADRS treeAdrs = new ADRS();
    +        treeAdrs.setType(ADRS.TREE);
    +
    +        HT ht = new HT(engine, privKey.getSeed(), privKey.getPublicSeed());
    +        byte[] SIG_HT = ht.sign(PK_FORS, idx_tree, idx_leaf);
    +
    +        byte[][] sigComponents = new byte[sig_fors.length + 2][];
    +        sigComponents[0] = R;
    +
    +        for (int i = 0; i != sig_fors.length; i++)
    +        {
    +            sigComponents[1 + i] = Arrays.concatenate(sig_fors[i].sk, Arrays.concatenate(sig_fors[i].authPath));
    +        }
    +        sigComponents[sigComponents.length - 1] = SIG_HT;
    +
    +        return Arrays.concatenate(sigComponents);
    +    }
    +
    +    public boolean internalVerifySignature(byte[] message, byte[] signature)
    +    {
    +        //# Input: Message M, signature SIG, public key PK
    +        //# Output: Boolean
    +
    +        // init
    +        SLHDSAEngine engine = pubKey.getParameters().getEngine();
    +
    +        engine.init(pubKey.getSeed());
    +
    +        ADRS adrs = new ADRS();
    +
    +        if (((1 + engine.K * (1 + engine.A) + engine.H + engine.D *engine.WOTS_LEN)* engine.N) != signature.length)
    +        {
    +            return false;
    +        }
    +
    +        SIG sig = new SIG(engine.N, engine.K, engine.A, engine.D, engine.H_PRIME, engine.WOTS_LEN, signature);
    +
    +        byte[] R = sig.getR();
    +        SIG_FORS[] sig_fors = sig.getSIG_FORS();
    +        SIG_XMSS[] SIG_HT = sig.getSIG_HT();
    +
    +        // compute message digest and index
    +        IndexedDigest idxDigest = engine.H_msg(R, pubKey.getSeed(), pubKey.getRoot(), message);
    +        byte[] mHash = idxDigest.digest;
    +        long idx_tree = idxDigest.idx_tree;
    +        int idx_leaf = idxDigest.idx_leaf;
    +
    +        // compute FORS public key
    +        adrs.setType(ADRS.FORS_TREE);
    +        adrs.setLayerAddress(0);
    +        adrs.setTreeAddress(idx_tree);
    +        adrs.setKeyPairAddress(idx_leaf);
    +        byte[] PK_FORS = new Fors(engine).pkFromSig(sig_fors, mHash, pubKey.getSeed(), adrs);
    +        // verify HT signature
    +        adrs.setType(ADRS.TREE);
    +        adrs.setLayerAddress(0);
    +        adrs.setTreeAddress(idx_tree);
    +        adrs.setKeyPairAddress(idx_leaf);
    +        HT ht = new HT(engine, null, pubKey.getSeed());
    +        return ht.verify(PK_FORS, SIG_HT, pubKey.getSeed(), idx_tree, idx_leaf, pubKey.getRoot());
    +    }
    +
    +    private static Digest createDigest(SLHDSAKeyParameters key)
    +    {
    +        int type = key.getParameters().getType();
    +
    +        switch (type)
    +        {
    +        case SLHDSAParameters.TYPE_PURE:
    +            String name = key.getParameters().getName();
    +            if (name.startsWith("sha2"))
    +            {
    +                if (SLHDSAParameters.sha2_128f == key.parameters
    +                    || SLHDSAParameters.sha2_128s == key.parameters)
    +                {
    +                    return SHA256Digest.newInstance();
    +                }
    +                else
    +                {
    +                    return new SHA512Digest();
    +                }
    +            }
    +            else
    +            {
    +                if (SLHDSAParameters.shake_128f == key.parameters
    +                    || SLHDSAParameters.shake_128s == key.parameters)
    +                {
    +                    return new SHAKEDigest(128);
    +                }
    +                else
    +                {
    +                    return new SHAKEDigest(256);
    +                }
    +            }
    +        case SLHDSAParameters.TYPE_SHA2_256:
    +            return SHA256Digest.newInstance();
    +        case SLHDSAParameters.TYPE_SHA2_512:
    +            return new SHA512Digest();
    +        case SLHDSAParameters.TYPE_SHAKE128:
    +            return new SHAKEDigest(128);
    +        case SLHDSAParameters.TYPE_SHAKE256:
    +            return new SHAKEDigest(256);
    +        default:
    +            throw new IllegalArgumentException("unknown parameters type");
    +        }
    +    }
    +}
    +
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/IndexedDigest.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/IndexedDigest.java
    new file mode 100644
    index 0000000000..e43f1c5a20
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/IndexedDigest.java
    @@ -0,0 +1,15 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +class IndexedDigest
    +{
    +    final long idx_tree;
    +    final int idx_leaf;
    +    final byte[] digest;
    +
    +    IndexedDigest(long idx_tree, int idx_leaf, byte[] digest)
    +    {
    +        this.idx_tree = idx_tree;
    +        this.idx_leaf = idx_leaf;
    +        this.digest = digest;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/NodeEntry.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/NodeEntry.java
    new file mode 100644
    index 0000000000..e9d57b9bc3
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/NodeEntry.java
    @@ -0,0 +1,13 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +class NodeEntry
    +{
    +    final byte[] nodeValue;
    +    final int nodeHeight;
    +
    +    NodeEntry(byte[] nodeValue, int nodeHeight)
    +    {
    +        this.nodeValue = nodeValue;
    +        this.nodeHeight = nodeHeight;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/PK.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/PK.java
    new file mode 100644
    index 0000000000..36794f4067
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/PK.java
    @@ -0,0 +1,13 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +class PK
    +{
    +    final byte[] seed;
    +    final byte[] root;
    +
    +    PK(byte[] seed, byte[] root)
    +    {
    +        this.seed = seed;
    +        this.root = root;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SIG.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SIG.java
    new file mode 100644
    index 0000000000..918b7a0924
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SIG.java
    @@ -0,0 +1,66 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +class SIG
    +{
    +    private final byte[] r;
    +    private final SIG_FORS[] sig_fors;
    +    private final SIG_XMSS[] sig_ht;
    +
    +    public SIG(int n, int k, int a, int d, int hPrime, int wots_len, byte[] signature)
    +    {
    +        this.r = new byte[n];
    +        System.arraycopy(signature, 0, r, 0, n);
    +
    +        this.sig_fors = new SIG_FORS[k];
    +        int offset = n;
    +        for (int i = 0; i != k; i++)
    +        {
    +            byte[] sk = new byte[n];
    +            System.arraycopy(signature, offset, sk, 0, n);
    +            offset += n;
    +            byte[][] authPath = new byte[a][];
    +            for (int j = 0; j != a; j++)
    +            {
    +                authPath[j] = new byte[n];
    +                System.arraycopy(signature, offset, authPath[j], 0, n);
    +                offset += n;
    +            }
    +            sig_fors[i] = new SIG_FORS(sk, authPath);
    +        }
    +
    +        sig_ht = new SIG_XMSS[d];
    +        for (int i = 0; i != d; i++)
    +        {
    +            byte[] sig = new byte[wots_len * n];
    +            System.arraycopy(signature, offset, sig, 0, sig.length);
    +            offset += sig.length;
    +            byte[][] authPath = new byte[hPrime][];
    +            for (int j = 0; j != hPrime; j++)
    +            {
    +                authPath[j] = new byte[n];
    +                System.arraycopy(signature, offset, authPath[j], 0, n);
    +                offset += n;
    +            }
    +            sig_ht[i] = new SIG_XMSS(sig, authPath);
    +        }
    +        if (offset != signature.length)
    +        {
    +            throw new IllegalArgumentException("signature wrong length");
    +        }
    +    }
    +
    +    public byte[] getR()
    +    {
    +        return r;
    +    }
    +
    +    public SIG_FORS[] getSIG_FORS()
    +    {
    +        return sig_fors;
    +    }
    +
    +    public SIG_XMSS[] getSIG_HT()
    +    {
    +        return sig_ht;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SIG_FORS.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SIG_FORS.java
    new file mode 100644
    index 0000000000..76977003c3
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SIG_FORS.java
    @@ -0,0 +1,23 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +class SIG_FORS
    +{
    +    final byte[][] authPath;
    +    final byte[] sk;
    +
    +    SIG_FORS(byte[] sk, byte[][] authPath)
    +    {
    +        this.authPath = authPath;
    +        this.sk = sk;
    +    }
    +
    +    byte[] getSK()
    +    {
    +        return sk;
    +    }
    +
    +    public byte[][] getAuthPath()
    +    {
    +        return authPath;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SIG_XMSS.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SIG_XMSS.java
    new file mode 100644
    index 0000000000..1d6011f7cd
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SIG_XMSS.java
    @@ -0,0 +1,23 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +class SIG_XMSS
    +{
    +    final byte[] sig;
    +    final byte[][] auth;
    +
    +    public SIG_XMSS(byte[] sig, byte[][] auth)
    +    {
    +        this.sig = sig;
    +        this.auth = auth;
    +    }
    +
    +    public byte[] getWOTSSig()
    +    {
    +        return sig;
    +    }
    +
    +    public byte[][] getXMSSAUTH()
    +    {
    +        return auth;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SK.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SK.java
    new file mode 100644
    index 0000000000..1a698b1d39
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SK.java
    @@ -0,0 +1,13 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +class SK
    +{
    +    final byte[] seed;
    +    final byte[] prf;
    +
    +    SK(byte[] seed, byte[] prf)
    +    {
    +        this.seed = seed;
    +        this.prf = prf;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAEngine.java
    new file mode 100644
    index 0000000000..69c8427672
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAEngine.java
    @@ -0,0 +1,441 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +import org.bouncycastle.crypto.Digest;
    +import org.bouncycastle.crypto.Xof;
    +import org.bouncycastle.crypto.digests.SHA256Digest;
    +import org.bouncycastle.crypto.digests.SHA512Digest;
    +import org.bouncycastle.crypto.digests.SHAKEDigest;
    +import org.bouncycastle.crypto.generators.MGF1BytesGenerator;
    +import org.bouncycastle.crypto.macs.HMac;
    +import org.bouncycastle.crypto.params.KeyParameter;
    +import org.bouncycastle.crypto.params.MGFParameters;
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Bytes;
    +import org.bouncycastle.util.Memoable;
    +import org.bouncycastle.util.Pack;
    +
    +abstract class SLHDSAEngine
    +{
    +    final int N;
    +
    +    final int WOTS_W;
    +    final int WOTS_LOGW;
    +    final int WOTS_LEN;
    +    final int WOTS_LEN1;
    +    final int WOTS_LEN2;
    +
    +    final int D;
    +    final int A; // FORS_HEIGHT
    +    final int K; // FORS_TREES
    +    final int H; // FULL_HEIGHT
    +    final int H_PRIME;  // H / D
    +
    +    final int T; // T = 1 << A
    +
    +    public SLHDSAEngine(int n, int w, int d, int a, int k, int h)
    +    {
    +        this.N = n;
    +
    +        /* SPX_WOTS_LEN2 is floor(log(len_1 * (w - 1)) / log(w)) + 1; we precompute */
    +        if (w == 16)
    +        {
    +            WOTS_LOGW = 4;
    +            WOTS_LEN1 = (8 * N / WOTS_LOGW);
    +            if (N <= 8)
    +            {
    +                WOTS_LEN2 = 2;
    +            }
    +            else if (N <= 136)
    +            {
    +                WOTS_LEN2 = 3;
    +            }
    +            else if (N <= 256)
    +            {
    +                WOTS_LEN2 = 4;
    +            }
    +            else
    +            {
    +                throw new IllegalArgumentException("cannot precompute SPX_WOTS_LEN2 for n outside {2, .., 256}");
    +            }
    +        }
    +        else if (w == 256)
    +        {
    +            WOTS_LOGW = 8;
    +            WOTS_LEN1 = (8 * N / WOTS_LOGW);
    +            if (N <= 1)
    +            {
    +                WOTS_LEN2 = 1;
    +            }
    +            else if (N <= 256)
    +            {
    +                WOTS_LEN2 = 2;
    +            }
    +            else
    +            {
    +                throw new IllegalArgumentException("cannot precompute SPX_WOTS_LEN2 for n outside {2, .., 256}");
    +            }
    +        }
    +        else
    +        {
    +            throw new IllegalArgumentException("wots_w assumed 16 or 256");
    +        }
    +        this.WOTS_W = w;
    +        this.WOTS_LEN = WOTS_LEN1 + WOTS_LEN2;
    +
    +        this.D = d;
    +        this.A = a;
    +        this.K = k;
    +        this.H = h;
    +        this.H_PRIME = h / d;
    +        this.T = 1 << a;
    +    }
    +
    +    abstract void init(byte[] pkSeed);
    +
    +    abstract byte[] F(byte[] pkSeed, ADRS adrs, byte[] m1);
    +
    +    abstract byte[] H(byte[] pkSeed, ADRS adrs, byte[] m1, byte[] m2);
    +
    +    abstract IndexedDigest H_msg(byte[] prf, byte[] pkSeed, byte[] pkRoot, byte[] message);
    +
    +    abstract byte[] T_l(byte[] pkSeed, ADRS adrs, byte[] m);
    +
    +    abstract byte[] PRF(byte[] pkSeed, byte[] skSeed, ADRS adrs);
    +
    +    abstract byte[] PRF_msg(byte[] prf, byte[] randomiser, byte[] message);
    +
    +    static class Sha2Engine
    +        extends SLHDSAEngine
    +    {
    +        private final HMac treeHMac;
    +        private final MGF1BytesGenerator mgf1;
    +        private final byte[] hmacBuf;
    +        private final Digest msgDigest;
    +        private final byte[] msgDigestBuf;
    +        private final int bl;
    +        private final Digest sha256 = new SHA256Digest();
    +        private final byte[] sha256Buf = new byte[sha256.getDigestSize()];
    +
    +        private Memoable msgMemo;
    +        private Memoable sha256Memo;
    +
    +        public Sha2Engine(int n, int w, int d, int a, int k, int h)
    +        {
    +            super(n, w, d, a, k, h);
    +            if (n == 16)
    +            {
    +                this.msgDigest = new SHA256Digest();
    +                this.treeHMac = new HMac(new SHA256Digest());
    +                this.mgf1 = new MGF1BytesGenerator(new SHA256Digest());
    +                this.bl = 64;
    +            }
    +            else
    +            {
    +                this.msgDigest = new SHA512Digest();
    +                this.treeHMac = new HMac(new SHA512Digest());
    +                this.mgf1 = new MGF1BytesGenerator(new SHA512Digest());
    +                this.bl = 128;
    +            }
    +
    +            this.hmacBuf = new byte[treeHMac.getMacSize()];
    +            this.msgDigestBuf = new byte[msgDigest.getDigestSize()];
    +        }
    +
    +        void init(byte[] pkSeed)
    +        {
    +            final byte[] padding = new byte[bl];
    +
    +            msgDigest.update(pkSeed, 0, pkSeed.length);
    +            msgDigest.update(padding, 0, bl - N); // toByte(0, 64 - n)
    +            msgMemo = ((Memoable)msgDigest).copy();
    +            
    +            msgDigest.reset();
    +
    +            sha256.update(pkSeed, 0, pkSeed.length);
    +            sha256.update(padding, 0, 64 - pkSeed.length); // toByte(0, 64 - n)
    +            sha256Memo = ((Memoable)sha256).copy();
    +
    +            sha256.reset();
    +        }
    +
    +        public byte[] F(byte[] pkSeed, ADRS adrs, byte[] m1)
    +        {
    +            byte[] compressedADRS = compressedADRS(adrs);
    +
    +            ((Memoable)sha256).reset(sha256Memo);
    +
    +            sha256.update(compressedADRS, 0, compressedADRS.length);
    +            sha256.update(m1, 0, m1.length);
    +            sha256.doFinal(sha256Buf, 0);
    +
    +            return Arrays.copyOfRange(sha256Buf, 0, N);
    +        }
    +
    +        public byte[] H(byte[] pkSeed, ADRS adrs, byte[] m1, byte[] m2)
    +        {
    +            byte[] compressedADRS = compressedADRS(adrs);
    +
    +            ((Memoable)msgDigest).reset(msgMemo);
    +
    +            msgDigest.update(compressedADRS, 0, compressedADRS.length);
    +
    +            msgDigest.update(m1, 0, m1.length);
    +            msgDigest.update(m2, 0, m2.length);
    +
    +            msgDigest.doFinal(msgDigestBuf, 0);
    +
    +            return Arrays.copyOfRange(msgDigestBuf, 0, N);
    +        }
    +
    +        IndexedDigest H_msg(byte[] prf, byte[] pkSeed, byte[] pkRoot, byte[] message)
    +        {
    +            int forsMsgBytes = ((A * K) + 7) / 8;
    +            int leafBits = H / D;
    +            int treeBits = H - leafBits;
    +            int leafBytes = (leafBits + 7) / 8;
    +            int treeBytes = (treeBits + 7) / 8;
    +            int m = forsMsgBytes + leafBytes + treeBytes;
    +            byte[] out = new byte[m];
    +            byte[] dig = new byte[msgDigest.getDigestSize()];
    +
    +            msgDigest.update(prf, 0, prf.length);
    +            msgDigest.update(pkSeed, 0, pkSeed.length);
    +            msgDigest.update(pkRoot, 0, pkRoot.length);
    +            msgDigest.update(message, 0, message.length);
    +            msgDigest.doFinal(dig, 0);
    +
    +            out = bitmask(Arrays.concatenate(prf, pkSeed, dig), out);
    +
    +            // tree index
    +            // currently, only indexes up to 64 bits are supported
    +            byte[] treeIndexBuf = new byte[8];
    +            System.arraycopy(out, forsMsgBytes, treeIndexBuf, 8 - treeBytes, treeBytes);
    +            long treeIndex = Pack.bigEndianToLong(treeIndexBuf, 0);
    +            treeIndex &= (~0L) >>> (64 - treeBits);
    +
    +            byte[] leafIndexBuf = new byte[4];
    +            System.arraycopy(out, forsMsgBytes + treeBytes, leafIndexBuf, 4 - leafBytes, leafBytes);
    +
    +            int leafIndex = Pack.bigEndianToInt(leafIndexBuf, 0);
    +            leafIndex &= (~0) >>> (32 - leafBits);
    +
    +            return new IndexedDigest(treeIndex, leafIndex, Arrays.copyOfRange(out, 0, forsMsgBytes));
    +        }
    +
    +        public byte[] T_l(byte[] pkSeed, ADRS adrs, byte[] m)
    +        {
    +            byte[] compressedADRS = compressedADRS(adrs);
    +
    +            ((Memoable)msgDigest).reset(msgMemo);
    +
    +            msgDigest.update(compressedADRS, 0, compressedADRS.length);
    +            msgDigest.update(m, 0, m.length);
    +            msgDigest.doFinal(msgDigestBuf, 0);
    +
    +            return Arrays.copyOfRange(msgDigestBuf, 0, N);
    +        }
    +
    +        byte[] PRF(byte[] pkSeed, byte[] skSeed, ADRS adrs)
    +        {
    +            int n = skSeed.length;
    +
    +            ((Memoable)sha256).reset(sha256Memo);
    +
    +            byte[] compressedADRS = compressedADRS(adrs);
    +
    +            sha256.update(compressedADRS, 0, compressedADRS.length);
    +            sha256.update(skSeed, 0, skSeed.length);
    +            sha256.doFinal(sha256Buf, 0);
    +
    +            return Arrays.copyOfRange(sha256Buf, 0, n);
    +        }
    +
    +        public byte[] PRF_msg(byte[] prf, byte[] randomiser, byte[] message)
    +        {
    +            treeHMac.init(new KeyParameter(prf));
    +            treeHMac.update(randomiser, 0, randomiser.length);
    +            treeHMac.update(message, 0, message.length);
    +            treeHMac.doFinal(hmacBuf, 0);
    +
    +            return Arrays.copyOfRange(hmacBuf, 0, N);
    +        }
    +
    +        private byte[] compressedADRS(ADRS adrs)
    +        {
    +            byte[] rv = new byte[22];
    +            System.arraycopy(adrs.value, ADRS.OFFSET_LAYER + 3, rv, 0, 1); // LSB layer address
    +            System.arraycopy(adrs.value, ADRS.OFFSET_TREE + 4, rv, 1, 8); // LS 8 bytes Tree address
    +            System.arraycopy(adrs.value, ADRS.OFFSET_TYPE + 3, rv, 9, 1); // LSB type
    +            System.arraycopy(adrs.value, 20, rv, 10, 12);
    +
    +            return rv;
    +        }
    +
    +        protected byte[] bitmask(byte[] key, byte[] m)
    +        {
    +            byte[] mask = new byte[m.length];
    +            mgf1.init(new MGFParameters(key));
    +            mgf1.generateBytes(mask, 0, mask.length);
    +            Bytes.xorTo(m.length, m, mask);
    +            return mask;
    +        }
    +
    +        protected byte[] bitmask(byte[] key, byte[] m1, byte[] m2)
    +        {
    +            byte[] mask = new byte[m1.length + m2.length];
    +            mgf1.init(new MGFParameters(key));
    +            mgf1.generateBytes(mask, 0, mask.length);
    +            Bytes.xorTo(m1.length, m1, mask);
    +            Bytes.xorTo(m2.length, m2, 0, mask, m1.length);
    +            return mask;
    +        }
    +
    +        protected byte[] bitmask256(byte[] key, byte[] m)
    +        {
    +            byte[] mask = new byte[m.length];
    +            MGF1BytesGenerator mgf1 = new MGF1BytesGenerator(new SHA256Digest());
    +            mgf1.init(new MGFParameters(key));
    +            mgf1.generateBytes(mask, 0, mask.length);
    +            Bytes.xorTo(m.length, m, mask);
    +            return mask;
    +        }
    +    }
    +
    +    static class Shake256Engine
    +        extends SLHDSAEngine
    +    {
    +        private final Xof treeDigest;
    +        private final Xof maskDigest;
    +
    +        public Shake256Engine(int n, int w, int d, int a, int k, int h)
    +        {
    +            super(n, w, d, a, k, h);
    +
    +            this.treeDigest = new SHAKEDigest(256);
    +            this.maskDigest = new SHAKEDigest(256);
    +        }
    +
    +        void init(byte[] pkSeed)
    +        {
    +
    +        }
    +
    +        byte[] F(byte[] pkSeed, ADRS adrs, byte[] m1)
    +        {
    +            byte[] mTheta = m1;
    +
    +            byte[] rv = new byte[N];
    +
    +            treeDigest.update(pkSeed, 0, pkSeed.length);
    +            treeDigest.update(adrs.value, 0, adrs.value.length);
    +            treeDigest.update(mTheta, 0, mTheta.length);
    +            treeDigest.doFinal(rv, 0, rv.length);
    +
    +            return rv;
    +        }
    +
    +        byte[] H(byte[] pkSeed, ADRS adrs, byte[] m1, byte[] m2)
    +        {
    +            byte[] rv = new byte[N];
    +
    +            treeDigest.update(pkSeed, 0, pkSeed.length);
    +            treeDigest.update(adrs.value, 0, adrs.value.length);
    +
    +            treeDigest.update(m1, 0, m1.length);
    +            treeDigest.update(m2, 0, m2.length);
    +
    +            treeDigest.doFinal(rv, 0, rv.length);
    +
    +            return rv;
    +        }
    +
    +        IndexedDigest H_msg(byte[] R, byte[] pkSeed, byte[] pkRoot, byte[] message)
    +        {
    +            int forsMsgBytes = ((A * K) + 7) / 8;
    +            int leafBits = H / D;
    +            int treeBits = H - leafBits;
    +            int leafBytes = (leafBits + 7) / 8;
    +            int treeBytes = (treeBits + 7) / 8;
    +            int m = forsMsgBytes + leafBytes + treeBytes;
    +            byte[] out = new byte[m];
    +
    +            treeDigest.update(R, 0, R.length);
    +            treeDigest.update(pkSeed, 0, pkSeed.length);
    +            treeDigest.update(pkRoot, 0, pkRoot.length);
    +            treeDigest.update(message, 0, message.length);
    +
    +            treeDigest.doFinal(out, 0, out.length);
    +
    +            // tree index
    +            // currently, only indexes up to 64 bits are supported
    +            byte[] treeIndexBuf = new byte[8];
    +            System.arraycopy(out, forsMsgBytes, treeIndexBuf, 8 - treeBytes, treeBytes);
    +            long treeIndex = Pack.bigEndianToLong(treeIndexBuf, 0);
    +            treeIndex &= (~0L) >>> (64 - treeBits);
    +
    +            byte[] leafIndexBuf = new byte[4];
    +            System.arraycopy(out, forsMsgBytes + treeBytes, leafIndexBuf, 4 - leafBytes, leafBytes);
    +
    +            int leafIndex = Pack.bigEndianToInt(leafIndexBuf, 0);
    +            leafIndex &= (~0) >>> (32 - leafBits);
    +
    +            return new IndexedDigest(treeIndex, leafIndex, Arrays.copyOfRange(out, 0, forsMsgBytes));
    +        }
    +
    +        byte[] T_l(byte[] pkSeed, ADRS adrs, byte[] m)
    +        {
    +            byte[] mTheta = m;
    +
    +            byte[] rv = new byte[N];
    +
    +            treeDigest.update(pkSeed, 0, pkSeed.length);
    +            treeDigest.update(adrs.value, 0, adrs.value.length);
    +            treeDigest.update(mTheta, 0, mTheta.length);
    +            treeDigest.doFinal(rv, 0, rv.length);
    +
    +            return rv;
    +        }
    +
    +        byte[] PRF(byte[] pkSeed, byte[] skSeed, ADRS adrs)
    +        {
    +            treeDigest.update(pkSeed, 0, pkSeed.length);
    +            treeDigest.update(adrs.value, 0, adrs.value.length);
    +            treeDigest.update(skSeed, 0, skSeed.length);
    +
    +            byte[] prf = new byte[N];
    +            treeDigest.doFinal(prf, 0, N);
    +            return prf;
    +        }
    +
    +        public byte[] PRF_msg(byte[] prf, byte[] randomiser, byte[] message)
    +        {
    +            treeDigest.update(prf, 0, prf.length);
    +            treeDigest.update(randomiser, 0, randomiser.length);
    +            treeDigest.update(message, 0, message.length);
    +            byte[] out = new byte[N];
    +            treeDigest.doFinal(out, 0, out.length);
    +            return out;
    +        }
    +
    +        protected byte[] bitmask(byte[] pkSeed, ADRS adrs, byte[] m)
    +        {
    +            byte[] mask = new byte[m.length];
    +            maskDigest.update(pkSeed, 0, pkSeed.length);
    +            maskDigest.update(adrs.value, 0, adrs.value.length);
    +            maskDigest.doFinal(mask, 0, mask.length);
    +            Bytes.xorTo(m.length, m, mask);
    +            return mask;
    +        }
    +
    +        protected byte[] bitmask(byte[] pkSeed, ADRS adrs, byte[] m1, byte[] m2)
    +        {
    +            byte[] mask = new byte[m1.length + m2.length];
    +            maskDigest.update(pkSeed, 0, pkSeed.length);
    +            maskDigest.update(adrs.value, 0, adrs.value.length);
    +            maskDigest.doFinal(mask, 0, mask.length);
    +            Bytes.xorTo(m1.length, m1, mask);
    +            Bytes.xorTo(m2.length, m2, 0, mask, m1.length);
    +            return mask;
    +        }
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAEngineProvider.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAEngineProvider.java
    new file mode 100644
    index 0000000000..14a6aae5c6
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAEngineProvider.java
    @@ -0,0 +1,8 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +interface SLHDSAEngineProvider
    +{
    +    int getN();
    +
    +    SLHDSAEngine get();
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAKeyGenerationParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAKeyGenerationParameters.java
    new file mode 100644
    index 0000000000..ce4f67967d
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAKeyGenerationParameters.java
    @@ -0,0 +1,22 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +import java.security.SecureRandom;
    +
    +import org.bouncycastle.crypto.KeyGenerationParameters;
    +
    +public class SLHDSAKeyGenerationParameters
    +    extends KeyGenerationParameters
    +{
    +    private final SLHDSAParameters parameters;
    +
    +    public SLHDSAKeyGenerationParameters(SecureRandom random, SLHDSAParameters parameters)
    +    {
    +        super(random, -1);
    +        this.parameters = parameters;
    +    }
    +
    +    SLHDSAParameters getParameters()
    +    {
    +        return parameters;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAKeyPairGenerator.java
    new file mode 100644
    index 0000000000..cfceb2d584
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAKeyPairGenerator.java
    @@ -0,0 +1,57 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +import java.security.SecureRandom;
    +
    +import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
    +import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
    +import org.bouncycastle.crypto.KeyGenerationParameters;
    +
    +public class SLHDSAKeyPairGenerator
    +    implements AsymmetricCipherKeyPairGenerator
    +{
    +    private SecureRandom random;
    +    private SLHDSAParameters parameters;
    +
    +    public void init(KeyGenerationParameters param)
    +    {
    +        random = param.getRandom();
    +        parameters = ((SLHDSAKeyGenerationParameters)param).getParameters();
    +    }
    +
    +    public AsymmetricCipherKeyPair internalGenerateKeyPair(byte[] skSeed, byte[] skPrf, byte[] pkSeed)
    +    {
    +        SLHDSAEngine engine = parameters.getEngine();
    +        SK sk = new SK(skSeed, skPrf);
    +
    +        engine.init(pkSeed);
    +
    +        // TODO
    +        PK pk = new PK(pkSeed, new HT(engine, sk.seed, pkSeed).htPubKey);
    +
    +        return new AsymmetricCipherKeyPair(new SLHDSAPublicKeyParameters(parameters, pk),
    +                new SLHDSAPrivateKeyParameters(parameters, sk, pk));
    +    }
    +
    +    public AsymmetricCipherKeyPair generateKeyPair()
    +    {
    +        SLHDSAEngine engine = parameters.getEngine();
    +        byte[] pkSeed;
    +        byte[] skSeed;
    +        byte[] skPrf;
    +
    +
    +        skSeed = sec_rand(engine.N);
    +        skPrf = sec_rand(engine.N);
    +        pkSeed = sec_rand(engine.N);
    +        return internalGenerateKeyPair(skSeed, skPrf, pkSeed);
    +    }
    +
    +    private byte[] sec_rand(int n)
    +    {
    +        byte[] rv = new byte[n];
    +
    +        random.nextBytes(rv);
    +
    +        return rv;
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAKeyParameters.java
    new file mode 100644
    index 0000000000..a66df488ee
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAKeyParameters.java
    @@ -0,0 +1,34 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
    +
    +public class SLHDSAKeyParameters
    +    extends AsymmetricKeyParameter
    +{
    +    final SLHDSAParameters parameters;
    +    final byte[] context;
    +
    +    protected SLHDSAKeyParameters(boolean isPrivate, SLHDSAParameters parameters, byte[] context)
    +    {
    +        super(isPrivate);
    +        this.parameters = parameters;
    +        this.context = context;
    +    }
    +
    +    protected SLHDSAKeyParameters(boolean isPrivate, SLHDSAParameters parameters)
    +    {
    +        super(isPrivate);
    +        this.parameters = parameters;
    +        this.context = new byte[0];
    +    }
    +
    +    public SLHDSAParameters getParameters()
    +    {
    +        return parameters;
    +    }
    +
    +    public byte[] getContext()
    +    {
    +        return context.clone();
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAParameters.java
    new file mode 100644
    index 0000000000..9a36776c82
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAParameters.java
    @@ -0,0 +1,184 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +import java.util.HashMap;
    +import java.util.Map;
    +
    +import org.bouncycastle.util.Integers;
    +import org.bouncycastle.util.Pack;
    +
    +public class SLHDSAParameters
    +{
    +    public static final int TYPE_PURE = 0;
    +    public static final int TYPE_SHA2_256 = 1;
    +    public static final int TYPE_SHA2_512 = 2;
    +    public static final int TYPE_SHAKE128 = 3;
    +    public static final int TYPE_SHAKE256 = 4;
    +
    +    // "Pure" SLH-DSA Parameters
    +    // SHA-2
    +    public static final SLHDSAParameters sha2_128f = new SLHDSAParameters(
    +        "sha2-128f", new Sha2EngineProvider(16, 16, 22, 6, 33, 66), TYPE_PURE);
    +    public static final SLHDSAParameters sha2_128s = new SLHDSAParameters(
    +        "sha2-128s", new Sha2EngineProvider(16, 16, 7, 12, 14, 63), TYPE_PURE);
    +
    +    public static final SLHDSAParameters sha2_192f = new SLHDSAParameters(
    +        "sha2-192f", new Sha2EngineProvider(24, 16, 22, 8, 33, 66), TYPE_PURE);
    +    public static final SLHDSAParameters sha2_192s = new SLHDSAParameters(
    +        "sha2-192s", new Sha2EngineProvider(24, 16, 7, 14, 17, 63), TYPE_PURE);
    +
    +    public static final SLHDSAParameters sha2_256f = new SLHDSAParameters(
    +        "sha2-256f", new Sha2EngineProvider(32, 16, 17, 9, 35, 68), TYPE_PURE);
    +    public static final SLHDSAParameters sha2_256s = new SLHDSAParameters(
    +        "sha2-256s", new Sha2EngineProvider(32, 16, 8, 14, 22, 64), TYPE_PURE);
    +
    +    // SHAKE-256.
    +    public static final SLHDSAParameters shake_128f = new SLHDSAParameters(
    +        "shake-128f", new Shake256EngineProvider(16, 16, 22, 6, 33, 66), TYPE_PURE);
    +    public static final SLHDSAParameters shake_128s = new SLHDSAParameters(
    +        "shake-128s", new Shake256EngineProvider(16, 16, 7, 12, 14, 63), TYPE_PURE);
    +
    +    public static final SLHDSAParameters shake_192f = new SLHDSAParameters(
    +        "shake-192f", new Shake256EngineProvider(24, 16, 22, 8, 33, 66), TYPE_PURE);
    +    public static final SLHDSAParameters shake_192s = new SLHDSAParameters(
    +        "shake-192s", new Shake256EngineProvider(24, 16, 7, 14, 17, 63), TYPE_PURE);
    +
    +    public static final SLHDSAParameters shake_256f = new SLHDSAParameters(
    +        "shake-256f", new Shake256EngineProvider(32, 16, 17, 9, 35, 68), TYPE_PURE);
    +    public static final SLHDSAParameters shake_256s = new SLHDSAParameters(
    +        "shake-256s", new Shake256EngineProvider(32, 16, 8, 14, 22, 64), TYPE_PURE);
    +
    +
    +    // "Pre-hash" SLH-DSA Parameters
    +    // SHA-2
    +    public static final SLHDSAParameters sha2_128f_with_sha256 = new SLHDSAParameters(
    +        "sha2-128f-with-sha256", new Sha2EngineProvider(16, 16, 22, 6, 33, 66), TYPE_SHA2_256);
    +    public static final SLHDSAParameters sha2_128s_with_sha256 = new SLHDSAParameters(
    +        "sha2-128s-with-sha256", new Sha2EngineProvider(16, 16, 7, 12, 14, 63), TYPE_SHA2_256);
    +
    +    public static final SLHDSAParameters sha2_192f_with_sha512 = new SLHDSAParameters(
    +        "sha2-192f-with-sha512", new Sha2EngineProvider(24, 16, 22, 8, 33, 66), TYPE_SHA2_512);
    +    public static final SLHDSAParameters sha2_192s_with_sha512 = new SLHDSAParameters(
    +        "sha2-192s-with-sha512", new Sha2EngineProvider(24, 16, 7, 14, 17, 63), TYPE_SHA2_512);
    +
    +    public static final SLHDSAParameters sha2_256f_with_sha512 = new SLHDSAParameters(
    +        "sha2-256f-with-sha512", new Sha2EngineProvider(32, 16, 17, 9, 35, 68), TYPE_SHA2_512);
    +    public static final SLHDSAParameters sha2_256s_with_sha512 = new SLHDSAParameters(
    +        "sha2-256s-with-sha512", new Sha2EngineProvider(32, 16, 8, 14, 22, 64), TYPE_SHA2_512);
    +
    +    // SHAKE-256.
    +    public static final SLHDSAParameters shake_128f_with_shake128 = new SLHDSAParameters(
    +        "shake-128f-with-shake128", new Shake256EngineProvider(16, 16, 22, 6, 33, 66), TYPE_SHAKE128);
    +    public static final SLHDSAParameters shake_128s_with_shake128 = new SLHDSAParameters(
    +        "shake-128s-with-shake128", new Shake256EngineProvider(16, 16, 7, 12, 14, 63), TYPE_SHAKE128);
    +
    +    public static final SLHDSAParameters shake_192f_with_shake256 = new SLHDSAParameters(
    +        "shake-192f-with-shake256", new Shake256EngineProvider(24, 16, 22, 8, 33, 66), TYPE_SHAKE256);
    +    public static final SLHDSAParameters shake_192s_with_shake256 = new SLHDSAParameters(
    +        "shake-192s-with-shake256", new Shake256EngineProvider(24, 16, 7, 14, 17, 63), TYPE_SHAKE256);
    +
    +    public static final SLHDSAParameters shake_256f_with_shake256 = new SLHDSAParameters(
    +        "shake-256f-with-shake256", new Shake256EngineProvider(32, 16, 17, 9, 35, 68), TYPE_SHAKE256);
    +    public static final SLHDSAParameters shake_256s_with_shake256 = new SLHDSAParameters(
    +        "shake-256s-with-shake256", new Shake256EngineProvider(32, 16, 8, 14, 22, 64), TYPE_SHAKE256);
    +
    +
    +    private static final Map ID_TO_PARAMS = new HashMap();
    +
    +    private final String name;
    +    private final SLHDSAEngineProvider engineProvider;
    +    private final int preHashDigest;
    +
    +    private SLHDSAParameters(String name, SLHDSAEngineProvider engineProvider, int preHashDigest)
    +    {
    +        this.name = name;
    +        this.engineProvider = engineProvider;
    +        this.preHashDigest = preHashDigest;
    +    }
    +
    +    public String getName()
    +    {
    +        return name;
    +    }
    +
    +    public int getType()
    +    {
    +        return preHashDigest;
    +    }
    +
    +    int getN()
    +    {
    +        return engineProvider.getN();
    +    }
    +
    +    SLHDSAEngine getEngine()
    +    {
    +        return engineProvider.get();
    +    }
    +
    +    public boolean isPreHash()
    +    {
    +        return preHashDigest != TYPE_PURE;
    +    }
    +
    +    private static class Sha2EngineProvider
    +        implements SLHDSAEngineProvider
    +    {
    +        private final int n;
    +        private final int w;
    +        private final int d;
    +        private final int a;
    +        private final int k;
    +        private final int h;
    +
    +        public Sha2EngineProvider(int n, int w, int d, int a, int k, int h)
    +        {
    +            this.n = n;
    +            this.w = w;
    +            this.d = d;
    +            this.a = a;
    +            this.k = k;
    +            this.h = h;
    +        }
    +
    +        public int getN()
    +        {
    +            return n;
    +        }
    +
    +        public SLHDSAEngine get()
    +        {
    +            return new SLHDSAEngine.Sha2Engine(n, w, d, a, k, h);
    +        }
    +    }
    +
    +    private static class Shake256EngineProvider
    +        implements SLHDSAEngineProvider
    +    {
    +        private final int n;
    +        private final int w;
    +        private final int d;
    +        private final int a;
    +        private final int k;
    +        private final int h;
    +
    +        public Shake256EngineProvider(int n, int w, int d, int a, int k, int h)
    +        {
    +            this.n = n;
    +            this.w = w;
    +            this.d = d;
    +            this.a = a;
    +            this.k = k;
    +            this.h = h;
    +        }
    +
    +        public int getN()
    +        {
    +            return n;
    +        }
    +
    +        public SLHDSAEngine get()
    +        {
    +            return new SLHDSAEngine.Shake256Engine(n, w, d, a, k, h);
    +        }
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAPrivateKeyParameters.java
    new file mode 100644
    index 0000000000..764a51dcb9
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAPrivateKeyParameters.java
    @@ -0,0 +1,69 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +public class SLHDSAPrivateKeyParameters
    +    extends SLHDSAKeyParameters
    +{
    +    final SK sk;
    +    final PK pk;
    +
    +    public SLHDSAPrivateKeyParameters(SLHDSAParameters parameters, byte[] skpkEncoded)
    +    {
    +        super(true, parameters);
    +        int n = parameters.getN();
    +        if (skpkEncoded.length != 4 * n)
    +        {
    +            throw new IllegalArgumentException("private key encoding does not match parameters");
    +        }
    +        this.sk = new SK(Arrays.copyOfRange(skpkEncoded, 0, n), Arrays.copyOfRange(skpkEncoded, n, 2 * n));
    +        this.pk = new PK(Arrays.copyOfRange(skpkEncoded, 2 * n, 3 * n), Arrays.copyOfRange(skpkEncoded, 3 * n, 4 * n));
    +    }
    +
    +    public SLHDSAPrivateKeyParameters(SLHDSAParameters parameters, byte[] skSeed, byte[] prf, byte[] pkSeed, byte[] pkRoot)
    +    {
    +        super(true, parameters);
    +        this.sk = new SK(skSeed, prf);
    +        this.pk = new PK(pkSeed, pkRoot);
    +    }
    +    SLHDSAPrivateKeyParameters(SLHDSAParameters parameters, SK sk, PK pk)
    +    {
    +        super(true, parameters);
    +        this.sk = sk;
    +        this.pk = pk;
    +    }
    +
    +    public byte[] getSeed()
    +    {
    +        return Arrays.clone(sk.seed);
    +    }
    +
    +    public byte[] getPrf()
    +    {
    +        return Arrays.clone(sk.prf);
    +    }
    +
    +    public byte[] getPublicSeed()
    +    {
    +        return Arrays.clone(pk.seed);
    +    }
    +    public byte[] getRoot()
    +    {
    +        return Arrays.clone(pk.root);
    +    }
    +
    +    public byte[] getPublicKey()
    +    {
    +        return Arrays.concatenate(pk.seed, pk.root);
    +    }
    +
    +    public byte[] getEncoded()
    +    {
    +        return Arrays.concatenate(new byte[][]{ sk.seed, sk.prf, pk.seed, pk.root });
    +    }
    +
    +    public byte[] getEncodedPublicKey()
    +    {
    +        return Arrays.concatenate(pk.seed, pk.root);
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAPublicKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAPublicKeyParameters.java
    new file mode 100644
    index 0000000000..5789fa335a
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSAPublicKeyParameters.java
    @@ -0,0 +1,41 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +public class SLHDSAPublicKeyParameters
    +    extends SLHDSAKeyParameters
    +{
    +    private final PK pk;
    +
    +    public SLHDSAPublicKeyParameters(SLHDSAParameters parameters, byte[] pkValues)
    +    {
    +        super(false, parameters);
    +        int n = parameters.getN();
    +        if (pkValues.length != 2 * n)
    +        {
    +            throw new IllegalArgumentException("public key encoding does not match parameters");
    +        }
    +        this.pk = new PK(Arrays.copyOfRange(pkValues, 0, n), Arrays.copyOfRange(pkValues, n, 2 * n));
    +    }
    +    
    +    SLHDSAPublicKeyParameters(SLHDSAParameters parameters, PK pk)
    +    {
    +        super(false, parameters);
    +        this.pk = pk;
    +    }
    +
    +    public byte[] getSeed()
    +    {
    +        return Arrays.clone(pk.seed);
    +    }
    +
    +    public byte[] getRoot()
    +    {
    +        return Arrays.clone(pk.root);
    +    }
    +
    +    public byte[] getEncoded()
    +    {
    +        return Arrays.concatenate(pk.seed, pk.root);
    +    }
    +}
    diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSASigner.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSASigner.java
    new file mode 100644
    index 0000000000..686924f5c0
    --- /dev/null
    +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/SLHDSASigner.java
    @@ -0,0 +1,199 @@
    +package org.bouncycastle.pqc.crypto.slhdsa;
    +
    +import java.security.SecureRandom;
    +
    +import org.bouncycastle.crypto.CipherParameters;
    +import org.bouncycastle.crypto.params.ParametersWithRandom;
    +import org.bouncycastle.pqc.crypto.MessageSigner;
    +import org.bouncycastle.util.Arrays;
    +
    +/**
    + * SLH-DA signer.
    + * 

    + * This version is based on the 3rd submission with deference to the updated reference + * implementation on github as at November 9th 2021. This version includes the changes + * for the countermeasure for the long-message second preimage attack - see + * "https://github.com/sphincs/sphincsplus/commit/61cd2695c6f984b4f4d6ed675378ed9a486cbede" + * for further details. + *

    + */ +public class SLHDSASigner + implements MessageSigner +{ + private SLHDSAPrivateKeyParameters privKey; + private SLHDSAPublicKeyParameters pubKey; + + private SecureRandom random; + + /** + * Base constructor. + */ + public SLHDSASigner() + { + } + + public void init(boolean forSigning, CipherParameters param) + { + boolean isPreHash; + + if (forSigning) + { + if (param instanceof ParametersWithRandom) + { + privKey = ((SLHDSAPrivateKeyParameters)((ParametersWithRandom)param).getParameters()); + this.random = ((ParametersWithRandom)param).getRandom(); + } + else + { + privKey = (SLHDSAPrivateKeyParameters)param; + } + + isPreHash = privKey.parameters.isPreHash(); + } + else + { + pubKey = (SLHDSAPublicKeyParameters)param; + isPreHash = pubKey.parameters.isPreHash(); + } + + if (isPreHash) + { + throw new IllegalArgumentException("\"pure\" slh-dsa must use non pre-hash parameters"); + } + } + + public byte[] generateSignature(byte[] message) + { + SLHDSAEngine engine = privKey.getParameters().getEngine(); + + engine.init(privKey.pk.seed); + byte[] ctx = privKey.getContext(); + + if (ctx.length > 255) + { + throw new RuntimeException("Context too long"); + } + + byte[] ds_message = new byte[1 + 1 + ctx.length + message.length]; + ds_message[0] = 0; + ds_message[1] = (byte)ctx.length; + System.arraycopy(ctx, 0, ds_message, 2, ctx.length); + System.arraycopy(message, 0, ds_message, 2 + ctx.length, message.length); + + // generate randomizer + byte[] optRand = new byte[engine.N]; + return internalGenerateSignature(ds_message, optRand); + } + + // Equivalent to slh_verify_internal from specs + public boolean verifySignature(byte[] message, byte[] signature) + { + byte[] ctx = pubKey.getContext(); + if (ctx.length > 255) + { + throw new RuntimeException("Context too long"); + } + + byte[] ds_message = new byte[1 + 1 + ctx.length + message.length]; + ds_message[0] = 0; + ds_message[1] = (byte)ctx.length; + System.arraycopy(ctx, 0, ds_message, 2, ctx.length); + System.arraycopy(message, 0, ds_message, 2 + ctx.length, message.length); + + return internalVerifySignature(ds_message, signature); + } + public boolean internalVerifySignature(byte[] message, byte[] signature) + { + //# Input: Message M, signature SIG, public key PK + //# Output: Boolean + + // init + SLHDSAEngine engine = pubKey.getParameters().getEngine(); + + engine.init(pubKey.getSeed()); + + ADRS adrs = new ADRS(); + + if (((1 + engine.K * (1 + engine.A) + engine.H + engine.D *engine.WOTS_LEN)* engine.N) != signature.length) + { + return false; + } + + SIG sig = new SIG(engine.N, engine.K, engine.A, engine.D, engine.H_PRIME, engine.WOTS_LEN, signature); + + byte[] R = sig.getR(); + SIG_FORS[] sig_fors = sig.getSIG_FORS(); + SIG_XMSS[] SIG_HT = sig.getSIG_HT(); + + // compute message digest and index + IndexedDigest idxDigest = engine.H_msg(R, pubKey.getSeed(), pubKey.getRoot(), message); + byte[] mHash = idxDigest.digest; + long idx_tree = idxDigest.idx_tree; + int idx_leaf = idxDigest.idx_leaf; + + // compute FORS public key + adrs.setType(ADRS.FORS_TREE); + adrs.setLayerAddress(0); + adrs.setTreeAddress(idx_tree); + adrs.setKeyPairAddress(idx_leaf); + byte[] PK_FORS = new Fors(engine).pkFromSig(sig_fors, mHash, pubKey.getSeed(), adrs); + // verify HT signature + adrs.setType(ADRS.TREE); + adrs.setLayerAddress(0); + adrs.setTreeAddress(idx_tree); + adrs.setKeyPairAddress(idx_leaf); + HT ht = new HT(engine, null, pubKey.getSeed()); + return ht.verify(PK_FORS, SIG_HT, pubKey.getSeed(), idx_tree, idx_leaf, pubKey.getRoot()); + } + + public byte[] internalGenerateSignature(byte[] message, byte[] optRand) + { + SLHDSAEngine engine = privKey.getParameters().getEngine(); + engine.init(privKey.pk.seed); + + if (optRand == null) + { + optRand = new byte[engine.N]; + System.arraycopy(privKey.pk.seed, 0, optRand, 0, optRand.length); + } + + Fors fors = new Fors(engine); + byte[] R = engine.PRF_msg(privKey.sk.prf, optRand, message); + + IndexedDigest idxDigest = engine.H_msg(R, privKey.pk.seed, privKey.pk.root, message); + byte[] mHash = idxDigest.digest; + long idx_tree = idxDigest.idx_tree; + int idx_leaf = idxDigest.idx_leaf; + // FORS sign + ADRS adrs = new ADRS(); + adrs.setType(ADRS.FORS_TREE); + adrs.setTreeAddress(idx_tree); + adrs.setKeyPairAddress(idx_leaf); + SIG_FORS[] sig_fors = fors.sign(mHash, privKey.sk.seed, privKey.pk.seed, adrs); + // get FORS public key - spec shows M? + adrs = new ADRS(); + adrs.setType(ADRS.FORS_TREE); + adrs.setTreeAddress(idx_tree); + adrs.setKeyPairAddress(idx_leaf); + byte[] PK_FORS = fors.pkFromSig(sig_fors, mHash, privKey.pk.seed, adrs); + + // sign FORS public key with HT + ADRS treeAdrs = new ADRS(); + treeAdrs.setType(ADRS.TREE); + + HT ht = new HT(engine, privKey.getSeed(), privKey.getPublicSeed()); + byte[] SIG_HT = ht.sign(PK_FORS, idx_tree, idx_leaf); + + byte[][] sigComponents = new byte[sig_fors.length + 2][]; + sigComponents[0] = R; + + for (int i = 0; i != sig_fors.length; i++) + { + sigComponents[1 + i] = Arrays.concatenate(sig_fors[i].sk, Arrays.concatenate(sig_fors[i].authPath)); + } + sigComponents[sigComponents.length - 1] = SIG_HT; + + return Arrays.concatenate(sigComponents); + } +} + diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/WotsPlus.java b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/WotsPlus.java new file mode 100644 index 0000000000..e6c2d57f83 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/slhdsa/WotsPlus.java @@ -0,0 +1,166 @@ +package org.bouncycastle.pqc.crypto.slhdsa; + +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Pack; + +class WotsPlus +{ + private final SLHDSAEngine engine; + private final int w; + + WotsPlus(SLHDSAEngine engine) + { + this.engine = engine; + this.w = this.engine.WOTS_W; + } + + byte[] pkGen(byte[] skSeed, byte[] pkSeed, ADRS paramAdrs) + { + ADRS wotspkADRS = new ADRS(paramAdrs); // copy address to create OTS public key address + + byte[][] tmp = new byte[engine.WOTS_LEN][]; + for (int i = 0; i < engine.WOTS_LEN; i++) + { + ADRS adrs = new ADRS(paramAdrs); + adrs.setType(ADRS.WOTS_PRF); + adrs.setKeyPairAddress(paramAdrs.getKeyPairAddress()); + adrs.setChainAddress(i); + adrs.setHashAddress(0); + + byte[] sk = engine.PRF(pkSeed, skSeed, adrs); + + adrs.setType(ADRS.WOTS_HASH); + adrs.setKeyPairAddress(paramAdrs.getKeyPairAddress()); + adrs.setChainAddress(i); + adrs.setHashAddress(0); + tmp[i] = chain(sk, 0, w - 1, pkSeed, adrs); + } + + wotspkADRS.setType(ADRS.WOTS_PK); + wotspkADRS.setKeyPairAddress(paramAdrs.getKeyPairAddress()); + + return engine.T_l(pkSeed, wotspkADRS, Arrays.concatenate(tmp)); + } + + // #Input: Input string X, start index i, number of steps s, public seed PK.seed, address ADRS + // #Output: value of F iterated s times on X + byte[] chain(byte[] X, int i, int s, byte[] pkSeed, ADRS adrs) + { + if (s == 0) + { + return Arrays.clone(X); + } + if ((i + s) > (this.w - 1)) + { + return null; + } + byte[] result = X; + for (int j = 0; j < s; ++j) + { + adrs.setHashAddress(i + j); + result = engine.F(pkSeed, adrs, result); + } + return result; + } + + // #Input: Message M, secret seed SK.seed, public seed PK.seed, address ADRS + // #Output: WOTS+ signature sig + public byte[] sign(byte[] M, byte[] skSeed, byte[] pkSeed, ADRS paramAdrs) + { + ADRS adrs = new ADRS(paramAdrs); + + int[] msg = new int[engine.WOTS_LEN]; + + // convert message to base w + base_w(M, 0, w, msg, 0, engine.WOTS_LEN1); + + // compute checksum + int csum = 0; + for (int i = 0; i < engine.WOTS_LEN1; i++) + { + csum += w - 1 - msg[i]; + } + + // convert csum to base w + if ((engine.WOTS_LOGW % 8) != 0) + { + csum = csum << (8 - ((engine.WOTS_LEN2 * engine.WOTS_LOGW) % 8)); + } + int len_2_bytes = (engine.WOTS_LEN2 * engine.WOTS_LOGW + 7) / 8; + byte[] csum_bytes = Pack.intToBigEndian(csum); + base_w(csum_bytes, 4 - len_2_bytes, w, msg, engine.WOTS_LEN1, engine.WOTS_LEN2); + + byte[][] sig = new byte[engine.WOTS_LEN][]; + for (int i = 0; i < engine.WOTS_LEN; i++) + { + adrs.setType(ADRS.WOTS_PRF); + adrs.setKeyPairAddress(paramAdrs.getKeyPairAddress()); + adrs.setChainAddress(i); + adrs.setHashAddress(0); + byte[] sk = engine.PRF(pkSeed, skSeed, adrs); + adrs.setType(ADRS.WOTS_HASH); + adrs.setKeyPairAddress(paramAdrs.getKeyPairAddress()); + adrs.setChainAddress(i); + adrs.setHashAddress(0); + sig[i] = chain(sk, 0, msg[i], pkSeed, adrs); + } + return Arrays.concatenate(sig); + } + + // + // Input: len_X-byte string X, int w, output length out_len + // Output: out_len int array basew + void base_w(byte[] X, int XOff, int w, int[] output, int outOff, int outLen) + { + int total = 0; + int bits = 0; + + for (int consumed = 0; consumed < outLen; consumed++) + { + if (bits == 0) + { + total = X[XOff++]; + bits += 8; + } + bits -= engine.WOTS_LOGW; + output[outOff++] = ((total >>> bits) & (w - 1)); + } + } + + public byte[] pkFromSig(byte[] sig, byte[] M, byte[] pkSeed, ADRS adrs) + { + ADRS wotspkADRS = new ADRS(adrs); + + int[] msg = new int[engine.WOTS_LEN]; + + // convert message to base w + base_w(M, 0, w, msg, 0, engine.WOTS_LEN1); + + // compute checksum + int csum = 0; + for (int i = 0; i < engine.WOTS_LEN1; i++ ) + { + csum += w - 1 - msg[i]; + } + + // convert csum to base w + csum = csum << (8 - ((engine.WOTS_LEN2 * engine.WOTS_LOGW) % 8)); + int len_2_bytes = (engine.WOTS_LEN2 * engine.WOTS_LOGW + 7) / 8; + byte[] csum_bytes = Pack.intToBigEndian(csum); + base_w(csum_bytes, 4 - len_2_bytes, w, msg, engine.WOTS_LEN1, engine.WOTS_LEN2); + + byte[] sigI = new byte[engine.N]; + byte[][] tmp = new byte[engine.WOTS_LEN][]; + for (int i = 0; i < engine.WOTS_LEN; i++ ) + { + adrs.setChainAddress(i); + System.arraycopy(sig, i * engine.N, sigI, 0, engine.N); + tmp[i] = chain(sigI, msg[i], w - 1 - msg[i], pkSeed, adrs); + } + + wotspkADRS.setType(ADRS.WOTS_PK); + wotspkADRS.setKeyPairAddress(adrs.getKeyPairAddress()); + + return engine.T_l(pkSeed, wotspkADRS, Arrays.concatenate(tmp)); + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/sphincs/SPHINCS256Signer.java b/core/src/main/java/org/bouncycastle/pqc/crypto/sphincs/SPHINCS256Signer.java index 7f61a1fe6d..0c8a3205b7 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/sphincs/SPHINCS256Signer.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/sphincs/SPHINCS256Signer.java @@ -406,13 +406,12 @@ boolean verify(HashFunctions hs, byte[] m, byte[] sm, byte[] pk) smlen -= SPHINCS256Config.SUBTREE_HEIGHT * SPHINCS256Config.HASH_BYTES; } + // Because we use custom offsets on tpk, rather than incurring an + // expensive copy, we use a manual constant time comparison. boolean verified = true; for (i = 0; i < SPHINCS256Config.HASH_BYTES; i++) { - if (root[i] != tpk[i + Horst.N_MASKS * SPHINCS256Config.HASH_BYTES]) - { - verified = false; - } + verified &= root[i] == tpk[i + Horst.N_MASKS * SPHINCS256Config.HASH_BYTES]; } return verified; diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusEngine.java index 1bae4b6254..18cae24b72 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusEngine.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusEngine.java @@ -10,11 +10,17 @@ import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.MGFParameters; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Bytes; import org.bouncycastle.util.Memoable; import org.bouncycastle.util.Pack; abstract class SPHINCSPlusEngine { + /** + * @deprecated + * obsolete to be removed + */ + @Deprecated final boolean robust; final int N; @@ -291,53 +297,29 @@ private byte[] compressedADRS(ADRS adrs) protected byte[] bitmask(byte[] key, byte[] m) { byte[] mask = new byte[m.length]; - mgf1.init(new MGFParameters(key)); - mgf1.generateBytes(mask, 0, mask.length); - - for (int i = 0; i < m.length; ++i) - { - mask[i] ^= m[i]; - } - + Bytes.xorTo(m.length, m, mask); return mask; } protected byte[] bitmask(byte[] key, byte[] m1, byte[] m2) { byte[] mask = new byte[m1.length + m2.length]; - mgf1.init(new MGFParameters(key)); - mgf1.generateBytes(mask, 0, mask.length); - - for (int i = 0; i < m1.length; ++i) - { - mask[i] ^= m1[i]; - } - for (int i = 0; i < m2.length; ++i) - { - mask[i + m1.length] ^= m2[i]; - } + Bytes.xorTo(m1.length, m1, mask); + Bytes.xorTo(m2.length, m2, 0, mask, m1.length); return mask; } protected byte[] bitmask256(byte[] key, byte[] m) { byte[] mask = new byte[m.length]; - MGF1BytesGenerator mgf1 = new MGF1BytesGenerator(new SHA256Digest()); - mgf1.init(new MGFParameters(key)); - mgf1.generateBytes(mask, 0, mask.length); - - for (int i = 0; i < m.length; ++i) - { - mask[i] ^= m[i]; - } - + Bytes.xorTo(m.length, m, mask); return mask; } } @@ -477,38 +459,21 @@ public byte[] PRF_msg(byte[] prf, byte[] randomiser, byte[] message) protected byte[] bitmask(byte[] pkSeed, ADRS adrs, byte[] m) { byte[] mask = new byte[m.length]; - maskDigest.update(pkSeed, 0, pkSeed.length); maskDigest.update(adrs.value, 0, adrs.value.length); - maskDigest.doFinal(mask, 0, mask.length); - - for (int i = 0; i < m.length; ++i) - { - mask[i] ^= m[i]; - } - + Bytes.xorTo(m.length, m, mask); return mask; } protected byte[] bitmask(byte[] pkSeed, ADRS adrs, byte[] m1, byte[] m2) { byte[] mask = new byte[m1.length + m2.length]; - maskDigest.update(pkSeed, 0, pkSeed.length); maskDigest.update(adrs.value, 0, adrs.value.length); - maskDigest.doFinal(mask, 0, mask.length); - - for (int i = 0; i < m1.length; ++i) - { - mask[i] ^= m1[i]; - } - for (int i = 0; i < m2.length; ++i) - { - mask[i + m1.length] ^= m2[i]; - } - + Bytes.xorTo(m1.length, m1, mask); + Bytes.xorTo(m2.length, m2, 0, mask, m1.length); return mask; } } @@ -540,10 +505,7 @@ public byte[] F(byte[] pkSeed, ADRS adrs, byte[] m1) { harakaS256Digest.update(adrs.value, 0, adrs.value.length); harakaS256Digest.doFinal(hash, 0); - for (int i = 0; i < m1.length; ++i) - { - hash[i] ^= m1[i]; - } + Bytes.xorTo(m1.length, m1, hash); harakaS512Digest.update(hash, 0, m1.length); } else @@ -629,11 +591,7 @@ protected byte[] bitmask(ADRS adrs, byte[] m) byte[] mask = new byte[m.length]; harakaSXof.update(adrs.value, 0, adrs.value.length); harakaSXof.doFinal(mask, 0, mask.length); - for (int i = 0; i < m.length; ++i) - { - m[i] ^= mask[i]; - } - return m; + Bytes.xorTo(m.length, mask, m); } return m; } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusParameters.java index e056f4a50c..35204ee8f1 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusParameters.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusParameters.java @@ -8,205 +8,158 @@ public class SPHINCSPlusParameters { - public static final SPHINCSPlusParameters sha2_128f = new SPHINCSPlusParameters("sha2-128f-robust", new Sha2EngineProvider(true, 16, 16, 22, 6, 33, 66)); - public static final SPHINCSPlusParameters sha2_128s = new SPHINCSPlusParameters("sha2-128s-robust", new Sha2EngineProvider(true, 16, 16, 7, 12, 14, 63)); - - public static final SPHINCSPlusParameters sha2_192f = new SPHINCSPlusParameters("sha2-192f-robust", new Sha2EngineProvider(true, 24, 16, 22, 8, 33, 66)); - public static final SPHINCSPlusParameters sha2_192s = new SPHINCSPlusParameters("sha2-192s-robust", new Sha2EngineProvider(true, 24, 16, 7, 14, 17, 63)); - - public static final SPHINCSPlusParameters sha2_256f = new SPHINCSPlusParameters("sha2-256f-robust", new Sha2EngineProvider(true, 32, 16, 17, 9, 35, 68)); - public static final SPHINCSPlusParameters sha2_256s = new SPHINCSPlusParameters("sha2-256s-robust", new Sha2EngineProvider(true, 32, 16, 8, 14, 22, 64)); - - public static final SPHINCSPlusParameters sha2_128f_simple = new SPHINCSPlusParameters("sha2-128f-simple", new Sha2EngineProvider(false, 16, 16, 22, 6, 33, 66)); - public static final SPHINCSPlusParameters sha2_128s_simple = new SPHINCSPlusParameters("sha2-128s-simple", new Sha2EngineProvider(false, 16, 16, 7, 12, 14, 63)); - - public static final SPHINCSPlusParameters sha2_192f_simple = new SPHINCSPlusParameters("sha2-192f-simple", new Sha2EngineProvider(false, 24, 16, 22, 8, 33, 66)); - public static final SPHINCSPlusParameters sha2_192s_simple = new SPHINCSPlusParameters("sha2-192s-simple", new Sha2EngineProvider(false, 24, 16, 7, 14, 17, 63)); - - public static final SPHINCSPlusParameters sha2_256f_simple = new SPHINCSPlusParameters("sha2-256f-simple", new Sha2EngineProvider(false, 32, 16, 17, 9, 35, 68)); - public static final SPHINCSPlusParameters sha2_256s_simple = new SPHINCSPlusParameters("sha2-256s-simple", new Sha2EngineProvider(false, 32, 16, 8, 14, 22, 64)); + // SHA-2 + + public static final SPHINCSPlusParameters sha2_128f_robust = new SPHINCSPlusParameters( + Integers.valueOf(0x010101), "sha2-128f-robust", new Sha2EngineProvider(true, 16, 16, 22, 6, 33, 66)); + public static final SPHINCSPlusParameters sha2_128s_robust = new SPHINCSPlusParameters( + Integers.valueOf(0x010102), "sha2-128s-robust", new Sha2EngineProvider(true, 16, 16, 7, 12, 14, 63)); + + public static final SPHINCSPlusParameters sha2_192f_robust = new SPHINCSPlusParameters( + Integers.valueOf(0x010103), "sha2-192f-robust", new Sha2EngineProvider(true, 24, 16, 22, 8, 33, 66)); + public static final SPHINCSPlusParameters sha2_192s_robust = new SPHINCSPlusParameters( + Integers.valueOf(0x010104), "sha2-192s-robust", new Sha2EngineProvider(true, 24, 16, 7, 14, 17, 63)); + + public static final SPHINCSPlusParameters sha2_256f_robust = new SPHINCSPlusParameters( + Integers.valueOf(0x010105), "sha2-256f-robust", new Sha2EngineProvider(true, 32, 16, 17, 9, 35, 68)); + public static final SPHINCSPlusParameters sha2_256s_robust = new SPHINCSPlusParameters( + Integers.valueOf(0x010106), "sha2-256s-robust", new Sha2EngineProvider(true, 32, 16, 8, 14, 22, 64)); + + public static final SPHINCSPlusParameters sha2_128f = new SPHINCSPlusParameters( + Integers.valueOf(0x010201), "sha2-128f", new Sha2EngineProvider(false, 16, 16, 22, 6, 33, 66)); + public static final SPHINCSPlusParameters sha2_128s = new SPHINCSPlusParameters( + Integers.valueOf(0x010202), "sha2-128s", new Sha2EngineProvider(false, 16, 16, 7, 12, 14, 63)); + + public static final SPHINCSPlusParameters sha2_192f = new SPHINCSPlusParameters( + Integers.valueOf(0x010203), "sha2-192f", new Sha2EngineProvider(false, 24, 16, 22, 8, 33, 66)); + public static final SPHINCSPlusParameters sha2_192s = new SPHINCSPlusParameters( + Integers.valueOf(0x010204), "sha2-192s", new Sha2EngineProvider(false, 24, 16, 7, 14, 17, 63)); + + public static final SPHINCSPlusParameters sha2_256f = new SPHINCSPlusParameters( + Integers.valueOf(0x010205), "sha2-256f", new Sha2EngineProvider(false, 32, 16, 17, 9, 35, 68)); + public static final SPHINCSPlusParameters sha2_256s = new SPHINCSPlusParameters( + Integers.valueOf(0x010206), "sha2-256s", new Sha2EngineProvider(false, 32, 16, 8, 14, 22, 64)); // SHAKE-256. - public static final SPHINCSPlusParameters shake_128f = new SPHINCSPlusParameters("shake-128f-robust", new Shake256EngineProvider(true, 16, 16, 22, 6, 33, 66)); - public static final SPHINCSPlusParameters shake_128s = new SPHINCSPlusParameters("shake-128s-robust", new Shake256EngineProvider(true, 16, 16, 7, 12, 14, 63)); + public static final SPHINCSPlusParameters shake_128f_robust = new SPHINCSPlusParameters( + Integers.valueOf(0x020101), "shake-128f-robust", new Shake256EngineProvider(true, 16, 16, 22, 6, 33, 66)); + public static final SPHINCSPlusParameters shake_128s_robust = new SPHINCSPlusParameters( + Integers.valueOf(0x020102), "shake-128s-robust", new Shake256EngineProvider(true, 16, 16, 7, 12, 14, 63)); - public static final SPHINCSPlusParameters shake_192f = new SPHINCSPlusParameters("shake-192f-robust", new Shake256EngineProvider(true, 24, 16, 22, 8, 33, 66)); - public static final SPHINCSPlusParameters shake_192s = new SPHINCSPlusParameters("shake-192s-robust", new Shake256EngineProvider(true, 24, 16, 7, 14, 17, 63)); + public static final SPHINCSPlusParameters shake_192f_robust = new SPHINCSPlusParameters( + Integers.valueOf(0x020103), "shake-192f-robust", new Shake256EngineProvider(true, 24, 16, 22, 8, 33, 66)); + public static final SPHINCSPlusParameters shake_192s_robust = new SPHINCSPlusParameters( + Integers.valueOf(0x020104), "shake-192s-robust", new Shake256EngineProvider(true, 24, 16, 7, 14, 17, 63)); - public static final SPHINCSPlusParameters shake_256f = new SPHINCSPlusParameters("shake-256f-robust", new Shake256EngineProvider(true, 32, 16, 17, 9, 35, 68)); - public static final SPHINCSPlusParameters shake_256s = new SPHINCSPlusParameters("shake-256s-robust", new Shake256EngineProvider(true, 32, 16, 8, 14, 22, 64)); + public static final SPHINCSPlusParameters shake_256f_robust = new SPHINCSPlusParameters( + Integers.valueOf(0x020105), "shake-256f-robust", new Shake256EngineProvider(true, 32, 16, 17, 9, 35, 68)); + public static final SPHINCSPlusParameters shake_256s_robust = new SPHINCSPlusParameters( + Integers.valueOf(0x020106), "shake-256s-robust", new Shake256EngineProvider(true, 32, 16, 8, 14, 22, 64)); - public static final SPHINCSPlusParameters shake_128f_simple = new SPHINCSPlusParameters("shake-128f-simple", new Shake256EngineProvider(false, 16, 16, 22, 6, 33, 66)); - public static final SPHINCSPlusParameters shake_128s_simple = new SPHINCSPlusParameters("shake-128s-simple", new Shake256EngineProvider(false, 16, 16, 7, 12, 14, 63)); + public static final SPHINCSPlusParameters shake_128f = new SPHINCSPlusParameters( + Integers.valueOf(0x020201), "shake-128f", new Shake256EngineProvider(false, 16, 16, 22, 6, 33, 66)); + public static final SPHINCSPlusParameters shake_128s = new SPHINCSPlusParameters( + Integers.valueOf(0x020202), "shake-128s", new Shake256EngineProvider(false, 16, 16, 7, 12, 14, 63)); - public static final SPHINCSPlusParameters shake_192f_simple = new SPHINCSPlusParameters("shake-192f-simple", new Shake256EngineProvider(false, 24, 16, 22, 8, 33, 66)); - public static final SPHINCSPlusParameters shake_192s_simple = new SPHINCSPlusParameters("shake-192s-simple", new Shake256EngineProvider(false, 24, 16, 7, 14, 17, 63)); + public static final SPHINCSPlusParameters shake_192f = new SPHINCSPlusParameters( + Integers.valueOf(0x020203), "shake-192f", new Shake256EngineProvider(false, 24, 16, 22, 8, 33, 66)); + public static final SPHINCSPlusParameters shake_192s = new SPHINCSPlusParameters( + Integers.valueOf(0x020204), "shake-192s", new Shake256EngineProvider(false, 24, 16, 7, 14, 17, 63)); - public static final SPHINCSPlusParameters shake_256f_simple = new SPHINCSPlusParameters("shake-256f-simple", new Shake256EngineProvider(false, 32, 16, 17, 9, 35, 68)); - public static final SPHINCSPlusParameters shake_256s_simple = new SPHINCSPlusParameters("shake-256s-simple", new Shake256EngineProvider(false, 32, 16, 8, 14, 22, 64)); + public static final SPHINCSPlusParameters shake_256f = new SPHINCSPlusParameters( + Integers.valueOf(0x020205), "shake-256f", new Shake256EngineProvider(false, 32, 16, 17, 9, 35, 68)); + public static final SPHINCSPlusParameters shake_256s = new SPHINCSPlusParameters( + Integers.valueOf(0x020206), "shake-256s", new Shake256EngineProvider(false, 32, 16, 8, 14, 22, 64)); // Haraka. - public static final SPHINCSPlusParameters haraka_128f = new SPHINCSPlusParameters("haraka-128f-robust", new HarakaSEngineProvider(true, 16, 16, 22, 6, 33, 66)); - public static final SPHINCSPlusParameters haraka_128s = new SPHINCSPlusParameters("haraka-128s-robust", new HarakaSEngineProvider(true, 16, 16, 7, 12, 14, 63)); - - public static final SPHINCSPlusParameters haraka_256f = new SPHINCSPlusParameters("haraka-256f-robust", new HarakaSEngineProvider(true, 32, 16, 17, 9, 35, 68)); - public static final SPHINCSPlusParameters haraka_256s = new SPHINCSPlusParameters("haraka-256s-robust", new HarakaSEngineProvider(true, 32, 16, 8, 14, 22, 64)); - - public static final SPHINCSPlusParameters haraka_192f = new SPHINCSPlusParameters("haraka-192f-robust", new HarakaSEngineProvider(true, 24, 16, 22, 8, 33, 66)); - public static final SPHINCSPlusParameters haraka_192s = new SPHINCSPlusParameters("haraka-192s-robust", new HarakaSEngineProvider(true, 24, 16, 7, 14, 17, 63)); - - public static final SPHINCSPlusParameters haraka_128f_simple = new SPHINCSPlusParameters("haraka-128f-simple", new HarakaSEngineProvider(false, 16, 16, 22, 6, 33, 66)); - public static final SPHINCSPlusParameters haraka_128s_simple = new SPHINCSPlusParameters("haraka-128s-simple", new HarakaSEngineProvider(false, 16, 16, 7, 12, 14, 63)); - - public static final SPHINCSPlusParameters haraka_192f_simple = new SPHINCSPlusParameters("haraka-192f-simple", new HarakaSEngineProvider(false, 24, 16, 22, 8, 33, 66)); - public static final SPHINCSPlusParameters haraka_192s_simple = new SPHINCSPlusParameters("haraka-192s-simple", new HarakaSEngineProvider(false, 24, 16, 7, 14, 17, 63)); - - public static final SPHINCSPlusParameters haraka_256f_simple = new SPHINCSPlusParameters("haraka-256f-simple", new HarakaSEngineProvider(false, 32, 16, 17, 9, 35, 68)); - public static final SPHINCSPlusParameters haraka_256s_simple = new SPHINCSPlusParameters("haraka-256s-simple", new HarakaSEngineProvider(false, 32, 16, 8, 14, 22, 64)); - - private static final Integer sphincsPlus_sha2_128f_robust = Integers.valueOf(0x010101); - private static final Integer sphincsPlus_sha2_128s_robust = Integers.valueOf(0x010102); - private static final Integer sphincsPlus_sha2_192f_robust = Integers.valueOf(0x010103); - private static final Integer sphincsPlus_sha2_192s_robust = Integers.valueOf(0x010104); - private static final Integer sphincsPlus_sha2_256f_robust = Integers.valueOf(0x010105); - private static final Integer sphincsPlus_sha2_256s_robust = Integers.valueOf(0x010106); - - private static final Integer sphincsPlus_sha2_128f_simple = Integers.valueOf(0x010201); - private static final Integer sphincsPlus_sha2_128s_simple = Integers.valueOf(0x010202); - private static final Integer sphincsPlus_sha2_192f_simple = Integers.valueOf(0x010203); - private static final Integer sphincsPlus_sha2_192s_simple = Integers.valueOf(0x010204); - private static final Integer sphincsPlus_sha2_256f_simple = Integers.valueOf(0x010205); - private static final Integer sphincsPlus_sha2_256s_simple = Integers.valueOf(0x010206); - - private static final Integer sphincsPlus_shake_128f_robust = Integers.valueOf(0x020101); - private static final Integer sphincsPlus_shake_128s_robust = Integers.valueOf(0x020102); - private static final Integer sphincsPlus_shake_192f_robust = Integers.valueOf(0x020103); - private static final Integer sphincsPlus_shake_192s_robust = Integers.valueOf(0x020104); - private static final Integer sphincsPlus_shake_256f_robust = Integers.valueOf(0x020105); - private static final Integer sphincsPlus_shake_256s_robust = Integers.valueOf(0x020106); - - private static final Integer sphincsPlus_shake_128f_simple = Integers.valueOf(0x020201); - private static final Integer sphincsPlus_shake_128s_simple = Integers.valueOf(0x020202); - private static final Integer sphincsPlus_shake_192f_simple = Integers.valueOf(0x020203); - private static final Integer sphincsPlus_shake_192s_simple = Integers.valueOf(0x020204); - private static final Integer sphincsPlus_shake_256f_simple = Integers.valueOf(0x020205); - private static final Integer sphincsPlus_shake_256s_simple = Integers.valueOf(0x020206); - - private static final Integer sphincsPlus_haraka_128f_robust = Integers.valueOf(0x030101); - private static final Integer sphincsPlus_haraka_128s_robust = Integers.valueOf(0x030102); - private static final Integer sphincsPlus_haraka_192f_robust = Integers.valueOf(0x030103); - private static final Integer sphincsPlus_haraka_192s_robust = Integers.valueOf(0x030104); - private static final Integer sphincsPlus_haraka_256f_robust = Integers.valueOf(0x030105); - private static final Integer sphincsPlus_haraka_256s_robust = Integers.valueOf(0x030106); - - private static final Integer sphincsPlus_haraka_128f_simple = Integers.valueOf(0x030201); - private static final Integer sphincsPlus_haraka_128s_simple = Integers.valueOf(0x030202); - private static final Integer sphincsPlus_haraka_192f_simple = Integers.valueOf(0x030203); - private static final Integer sphincsPlus_haraka_192s_simple = Integers.valueOf(0x030204); - private static final Integer sphincsPlus_haraka_256f_simple = Integers.valueOf(0x030205); - private static final Integer sphincsPlus_haraka_256s_simple = Integers.valueOf(0x030206); - - private static final Map oidToParams = new HashMap(); - private static final Map paramsToOid = new HashMap(); + /** + * @deprecated + * obsolete to be removed + */ + @Deprecated + public static final SPHINCSPlusParameters haraka_128f = new SPHINCSPlusParameters( + Integers.valueOf(0x030101), "haraka-128f-robust", new HarakaSEngineProvider(true, 16, 16, 22, 6, 33, 66)); + @Deprecated + public static final SPHINCSPlusParameters haraka_128s = new SPHINCSPlusParameters( + Integers.valueOf(0x030102), "haraka-128s-robust", new HarakaSEngineProvider(true, 16, 16, 7, 12, 14, 63)); + @Deprecated + public static final SPHINCSPlusParameters haraka_192f = new SPHINCSPlusParameters( + Integers.valueOf(0x030103), "haraka-192f-robust", new HarakaSEngineProvider(true, 24, 16, 22, 8, 33, 66)); + @Deprecated + public static final SPHINCSPlusParameters haraka_192s = new SPHINCSPlusParameters( + Integers.valueOf(0x030104), "haraka-192s-robust", new HarakaSEngineProvider(true, 24, 16, 7, 14, 17, 63)); + @Deprecated + public static final SPHINCSPlusParameters haraka_256f = new SPHINCSPlusParameters( + Integers.valueOf(0x030105), "haraka-256f-robust", new HarakaSEngineProvider(true, 32, 16, 17, 9, 35, 68)); + @Deprecated + public static final SPHINCSPlusParameters haraka_256s = new SPHINCSPlusParameters( + Integers.valueOf(0x030106), "haraka-256s-robust", new HarakaSEngineProvider(true, 32, 16, 8, 14, 22, 64)); + + public static final SPHINCSPlusParameters haraka_128f_simple = new SPHINCSPlusParameters( + Integers.valueOf(0x030201), "haraka-128f-simple", new HarakaSEngineProvider(false, 16, 16, 22, 6, 33, 66)); + public static final SPHINCSPlusParameters haraka_128s_simple = new SPHINCSPlusParameters( + Integers.valueOf(0x030202), "haraka-128s-simple", new HarakaSEngineProvider(false, 16, 16, 7, 12, 14, 63)); + + public static final SPHINCSPlusParameters haraka_192f_simple = new SPHINCSPlusParameters( + Integers.valueOf(0x030203), "haraka-192f-simple", new HarakaSEngineProvider(false, 24, 16, 22, 8, 33, 66)); + public static final SPHINCSPlusParameters haraka_192s_simple = new SPHINCSPlusParameters( + Integers.valueOf(0x030204), "haraka-192s-simple", new HarakaSEngineProvider(false, 24, 16, 7, 14, 17, 63)); + + public static final SPHINCSPlusParameters haraka_256f_simple = new SPHINCSPlusParameters( + Integers.valueOf(0x030205), "haraka-256f-simple", new HarakaSEngineProvider(false, 32, 16, 17, 9, 35, 68)); + public static final SPHINCSPlusParameters haraka_256s_simple = new SPHINCSPlusParameters( + Integers.valueOf(0x030206), "haraka-256s-simple", new HarakaSEngineProvider(false, 32, 16, 8, 14, 22, 64)); + + private static final Map ID_TO_PARAMS = new HashMap(); static { - oidToParams.put(sphincsPlus_sha2_128f_robust, SPHINCSPlusParameters.sha2_128f); - oidToParams.put(sphincsPlus_sha2_128s_robust, SPHINCSPlusParameters.sha2_128s); - oidToParams.put(sphincsPlus_sha2_192f_robust, SPHINCSPlusParameters.sha2_192f); - oidToParams.put(sphincsPlus_sha2_192s_robust, SPHINCSPlusParameters.sha2_192s); - oidToParams.put(sphincsPlus_sha2_256f_robust, SPHINCSPlusParameters.sha2_256f); - oidToParams.put(sphincsPlus_sha2_256s_robust, SPHINCSPlusParameters.sha2_256s); - - oidToParams.put(sphincsPlus_sha2_128f_simple, SPHINCSPlusParameters.sha2_128f_simple); - oidToParams.put(sphincsPlus_sha2_128s_simple, SPHINCSPlusParameters.sha2_128s_simple); - oidToParams.put(sphincsPlus_sha2_192f_simple, SPHINCSPlusParameters.sha2_192f_simple); - oidToParams.put(sphincsPlus_sha2_192s_simple, SPHINCSPlusParameters.sha2_192s_simple); - oidToParams.put(sphincsPlus_sha2_256f_simple, SPHINCSPlusParameters.sha2_256f_simple); - oidToParams.put(sphincsPlus_sha2_256s_simple, SPHINCSPlusParameters.sha2_256s_simple); - - oidToParams.put(sphincsPlus_shake_128f_robust, SPHINCSPlusParameters.shake_128f); - oidToParams.put(sphincsPlus_shake_128s_robust, SPHINCSPlusParameters.shake_128s); - oidToParams.put(sphincsPlus_shake_192f_robust, SPHINCSPlusParameters.shake_192f); - oidToParams.put(sphincsPlus_shake_192s_robust, SPHINCSPlusParameters.shake_192s); - oidToParams.put(sphincsPlus_shake_256f_robust, SPHINCSPlusParameters.shake_256f); - oidToParams.put(sphincsPlus_shake_256s_robust, SPHINCSPlusParameters.shake_256s); - - oidToParams.put(sphincsPlus_shake_128f_simple, SPHINCSPlusParameters.shake_128f_simple); - oidToParams.put(sphincsPlus_shake_128s_simple, SPHINCSPlusParameters.shake_128s_simple); - oidToParams.put(sphincsPlus_shake_192f_simple, SPHINCSPlusParameters.shake_192f_simple); - oidToParams.put(sphincsPlus_shake_192s_simple, SPHINCSPlusParameters.shake_192s_simple); - oidToParams.put(sphincsPlus_shake_256f_simple, SPHINCSPlusParameters.shake_256f_simple); - oidToParams.put(sphincsPlus_shake_256s_simple, SPHINCSPlusParameters.shake_256s_simple); - - oidToParams.put(sphincsPlus_haraka_128f_simple, SPHINCSPlusParameters.haraka_128f_simple); - oidToParams.put(sphincsPlus_haraka_128f_robust, SPHINCSPlusParameters.haraka_128f); - oidToParams.put(sphincsPlus_haraka_192f_simple, SPHINCSPlusParameters.haraka_192f_simple); - oidToParams.put(sphincsPlus_haraka_192f_robust, SPHINCSPlusParameters.haraka_192f); - oidToParams.put(sphincsPlus_haraka_256f_simple, SPHINCSPlusParameters.haraka_256f_simple); - oidToParams.put(sphincsPlus_haraka_256f_robust, SPHINCSPlusParameters.haraka_256f); - - oidToParams.put(sphincsPlus_haraka_128s_simple, SPHINCSPlusParameters.haraka_128s_simple); - oidToParams.put(sphincsPlus_haraka_128s_robust, SPHINCSPlusParameters.haraka_128s); - oidToParams.put(sphincsPlus_haraka_192s_simple, SPHINCSPlusParameters.haraka_192s_simple); - oidToParams.put(sphincsPlus_haraka_192s_robust, SPHINCSPlusParameters.haraka_192s); - oidToParams.put(sphincsPlus_haraka_256s_simple, SPHINCSPlusParameters.haraka_256s_simple); - oidToParams.put(sphincsPlus_haraka_256s_robust, SPHINCSPlusParameters.haraka_256s); - - paramsToOid.put(SPHINCSPlusParameters.sha2_128f, sphincsPlus_sha2_128f_robust); - paramsToOid.put(SPHINCSPlusParameters.sha2_128s, sphincsPlus_sha2_128s_robust); - paramsToOid.put(SPHINCSPlusParameters.sha2_192f, sphincsPlus_sha2_192f_robust); - paramsToOid.put(SPHINCSPlusParameters.sha2_192s, sphincsPlus_sha2_192s_robust); - paramsToOid.put(SPHINCSPlusParameters.sha2_256f, sphincsPlus_sha2_256f_robust); - paramsToOid.put(SPHINCSPlusParameters.sha2_256s, sphincsPlus_sha2_256s_robust); - - paramsToOid.put(SPHINCSPlusParameters.sha2_128f_simple, sphincsPlus_sha2_128f_simple); - paramsToOid.put(SPHINCSPlusParameters.sha2_128s_simple, sphincsPlus_sha2_128s_simple); - paramsToOid.put(SPHINCSPlusParameters.sha2_192f_simple, sphincsPlus_sha2_192f_simple); - paramsToOid.put(SPHINCSPlusParameters.sha2_192s_simple, sphincsPlus_sha2_192s_simple); - paramsToOid.put(SPHINCSPlusParameters.sha2_256f_simple, sphincsPlus_sha2_256f_simple); - paramsToOid.put(SPHINCSPlusParameters.sha2_256s_simple, sphincsPlus_sha2_256s_simple); - - paramsToOid.put(SPHINCSPlusParameters.shake_128f, sphincsPlus_shake_128f_robust); - paramsToOid.put(SPHINCSPlusParameters.shake_128s, sphincsPlus_shake_128s_robust); - paramsToOid.put(SPHINCSPlusParameters.shake_192f, sphincsPlus_shake_192f_robust); - paramsToOid.put(SPHINCSPlusParameters.shake_192s, sphincsPlus_shake_192s_robust); - paramsToOid.put(SPHINCSPlusParameters.shake_256f, sphincsPlus_shake_256f_robust); - paramsToOid.put(SPHINCSPlusParameters.shake_256s, sphincsPlus_shake_256s_robust); - - paramsToOid.put(SPHINCSPlusParameters.shake_128f_simple, sphincsPlus_shake_128f_simple); - paramsToOid.put(SPHINCSPlusParameters.shake_128s_simple, sphincsPlus_shake_128s_simple); - paramsToOid.put(SPHINCSPlusParameters.shake_192f_simple, sphincsPlus_shake_192f_simple); - paramsToOid.put(SPHINCSPlusParameters.shake_192s_simple, sphincsPlus_shake_192s_simple); - paramsToOid.put(SPHINCSPlusParameters.shake_256f_simple, sphincsPlus_shake_256f_simple); - paramsToOid.put(SPHINCSPlusParameters.shake_256s_simple, sphincsPlus_shake_256s_simple); - - paramsToOid.put(SPHINCSPlusParameters.haraka_128f, sphincsPlus_haraka_128f_robust); - paramsToOid.put(SPHINCSPlusParameters.haraka_192f, sphincsPlus_haraka_192f_robust); - paramsToOid.put(SPHINCSPlusParameters.haraka_256f, sphincsPlus_haraka_256f_robust); - paramsToOid.put(SPHINCSPlusParameters.haraka_128s, sphincsPlus_haraka_128s_robust); - paramsToOid.put(SPHINCSPlusParameters.haraka_192s, sphincsPlus_haraka_192s_robust); - paramsToOid.put(SPHINCSPlusParameters.haraka_256s, sphincsPlus_haraka_256s_robust); - - paramsToOid.put(SPHINCSPlusParameters.haraka_128f_simple, sphincsPlus_haraka_128f_simple); - paramsToOid.put(SPHINCSPlusParameters.haraka_192f_simple, sphincsPlus_haraka_192f_simple); - paramsToOid.put(SPHINCSPlusParameters.haraka_256f_simple, sphincsPlus_haraka_256f_simple); - paramsToOid.put(SPHINCSPlusParameters.haraka_128s_simple, sphincsPlus_haraka_128s_simple); - paramsToOid.put(SPHINCSPlusParameters.haraka_192s_simple, sphincsPlus_haraka_192s_simple); - paramsToOid.put(SPHINCSPlusParameters.haraka_256s_simple, sphincsPlus_haraka_256s_simple); + SPHINCSPlusParameters[] all = new SPHINCSPlusParameters[]{ + SPHINCSPlusParameters.sha2_128f_robust, SPHINCSPlusParameters.sha2_128s_robust, + SPHINCSPlusParameters.sha2_192f_robust, SPHINCSPlusParameters.sha2_192s_robust, + SPHINCSPlusParameters.sha2_256f_robust, SPHINCSPlusParameters.sha2_256s_robust, + SPHINCSPlusParameters.sha2_128f, SPHINCSPlusParameters.sha2_128s, + SPHINCSPlusParameters.sha2_192f, SPHINCSPlusParameters.sha2_192s, + SPHINCSPlusParameters.sha2_256f, SPHINCSPlusParameters.sha2_256s, + SPHINCSPlusParameters.shake_128f_robust, SPHINCSPlusParameters.shake_128s_robust, + SPHINCSPlusParameters.shake_192f_robust, SPHINCSPlusParameters.shake_192s_robust, + SPHINCSPlusParameters.shake_256f_robust, SPHINCSPlusParameters.shake_256s_robust, + SPHINCSPlusParameters.shake_128f, SPHINCSPlusParameters.shake_128s, + SPHINCSPlusParameters.shake_192f, SPHINCSPlusParameters.shake_192s, + SPHINCSPlusParameters.shake_256f, SPHINCSPlusParameters.shake_256s, + SPHINCSPlusParameters.haraka_128f, SPHINCSPlusParameters.haraka_128s, + SPHINCSPlusParameters.haraka_192f, SPHINCSPlusParameters.haraka_192s, + SPHINCSPlusParameters.haraka_256f, SPHINCSPlusParameters.haraka_256s, + SPHINCSPlusParameters.haraka_128f_simple, SPHINCSPlusParameters.haraka_128s_simple, + SPHINCSPlusParameters.haraka_192f_simple, SPHINCSPlusParameters.haraka_192s_simple, + SPHINCSPlusParameters.haraka_256f_simple, SPHINCSPlusParameters.haraka_256s_simple, + }; + + for (int i = 0; i < all.length; ++i) + { + SPHINCSPlusParameters parameters = all[i]; + ID_TO_PARAMS.put(parameters.getID(), parameters); + } } + private final Integer id; private final String name; private final SPHINCSPlusEngineProvider engineProvider; - private SPHINCSPlusParameters(String name, SPHINCSPlusEngineProvider engineProvider) + private SPHINCSPlusParameters(Integer id, String name, SPHINCSPlusEngineProvider engineProvider) { + this.id = id; this.name = name; this.engineProvider = engineProvider; } + public Integer getID() + { + return id; + } + public String getName() { return name; @@ -230,7 +183,7 @@ SPHINCSPlusEngine getEngine() */ public static SPHINCSPlusParameters getParams(Integer id) { - return (SPHINCSPlusParameters)oidToParams.get(id); + return (SPHINCSPlusParameters)ID_TO_PARAMS.get(id); } /** @@ -238,15 +191,16 @@ public static SPHINCSPlusParameters getParams(Integer id) * * @param params the parameters of interest. * @return the OID for the parameter set. + * @deprecated Use {@link #getID()} instead */ public static Integer getID(SPHINCSPlusParameters params) { - return (Integer)paramsToOid.get(params); + return params.getID(); } public byte[] getEncoded() { - return Pack.intToBigEndian(getID(this).intValue()); + return Pack.intToBigEndian(getID().intValue()); } private static class Sha2EngineProvider @@ -262,7 +216,6 @@ private static class Sha2EngineProvider public Sha2EngineProvider(boolean robust, int n, int w, int d, int a, int k, int h) { - this.robust = robust; this.n = n; this.w = w; @@ -296,7 +249,6 @@ private static class Shake256EngineProvider public Shake256EngineProvider(boolean robust, int n, int w, int d, int a, int k, int h) { - this.robust = robust; this.n = n; this.w = w; diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusPrivateKeyParameters.java index 5c2838dd86..c599f2f7f4 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusPrivateKeyParameters.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusPrivateKeyParameters.java @@ -1,7 +1,6 @@ package org.bouncycastle.pqc.crypto.sphincsplus; import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.Pack; public class SPHINCSPlusPrivateKeyParameters extends SPHINCSPlusKeyParameters @@ -60,11 +59,11 @@ public byte[] getPublicKey() public byte[] getEncoded() { - return Arrays.concatenate(Pack.intToBigEndian(SPHINCSPlusParameters.getID(getParameters()).intValue()), Arrays.concatenate(sk.seed, sk.prf, pk.seed, pk.root)); + return Arrays.concatenate(new byte[][]{ sk.seed, sk.prf, pk.seed, pk.root }); } public byte[] getEncodedPublicKey() { - return Arrays.concatenate(Pack.intToBigEndian(SPHINCSPlusParameters.getID(getParameters()).intValue()), pk.seed, pk.root); + return Arrays.concatenate(pk.seed, pk.root); } } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusPublicKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusPublicKeyParameters.java index 1b59641323..0ea6db8d2e 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusPublicKeyParameters.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/sphincsplus/SPHINCSPlusPublicKeyParameters.java @@ -1,7 +1,6 @@ package org.bouncycastle.pqc.crypto.sphincsplus; import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.Pack; public class SPHINCSPlusPublicKeyParameters extends SPHINCSPlusKeyParameters @@ -37,6 +36,6 @@ public byte[] getRoot() public byte[] getEncoded() { - return Arrays.concatenate(Pack.intToBigEndian(SPHINCSPlusParameters.getID(getParameters()).intValue()), pk.seed, pk.root); + return Arrays.concatenate(pk.seed, pk.root); } } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PQCOtherInfoGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PQCOtherInfoGenerator.java index 7e8a0bfea8..cb7d03ccd7 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PQCOtherInfoGenerator.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PQCOtherInfoGenerator.java @@ -4,27 +4,19 @@ import java.security.SecureRandom; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.EncapsulatedSecretExtractor; import org.bouncycastle.crypto.EncapsulatedSecretGenerator; -import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.DEROtherInfo; -import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; -import org.bouncycastle.pqc.crypto.ExchangePair; import org.bouncycastle.pqc.crypto.KEMParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKEMExtractor; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKEMGenerator; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKeyGenerationParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKeyPairGenerator; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberPrivateKeyParameters; -import org.bouncycastle.pqc.crypto.newhope.NHAgreement; -import org.bouncycastle.pqc.crypto.newhope.NHExchangePairGenerator; -import org.bouncycastle.pqc.crypto.newhope.NHKeyPairGenerator; -import org.bouncycastle.pqc.crypto.newhope.NHPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyPairGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUKEMExtractor; import org.bouncycastle.pqc.crypto.ntru.NTRUKEMGenerator; import org.bouncycastle.pqc.crypto.ntru.NTRUKeyGenerationParameters; @@ -66,8 +58,6 @@ public static class PartyU private AsymmetricCipherKeyPair aKp; private EncapsulatedSecretExtractor encSE; - private NHAgreement agreement = new NHAgreement(); - /** * Create a basic builder with just the compulsory fields for the initiator. * @@ -81,15 +71,15 @@ public PartyU(KEMParameters kemParams, AlgorithmIdentifier algorithmID, byte[] p { super(algorithmID, partyUInfo, partyVInfo, random); - if (kemParams instanceof KyberParameters) + if (kemParams instanceof MLKEMParameters) { - KyberKeyPairGenerator kPg = new KyberKeyPairGenerator(); + MLKEMKeyPairGenerator kPg = new MLKEMKeyPairGenerator(); - kPg.init(new KyberKeyGenerationParameters(random, (KyberParameters)kemParams)); + kPg.init(new MLKEMKeyGenerationParameters(random, (MLKEMParameters)kemParams)); aKp = kPg.generateKeyPair(); - encSE = new KyberKEMExtractor((KyberPrivateKeyParameters)aKp.getPrivate()); + encSE = new MLKEMExtractor((MLKEMPrivateKeyParameters)aKp.getPrivate()); } else if (kemParams instanceof NTRUParameters) { @@ -154,9 +144,9 @@ public PartyV(KEMParameters kemParams, AlgorithmIdentifier algorithmID, byte[] p { super(algorithmID, partyUInfo, partyVInfo, random); - if (kemParams instanceof KyberParameters) + if (kemParams instanceof MLKEMParameters) { - encSG = new KyberKEMGenerator(random); + encSG = new MLKEMGenerator(random); } else if (kemParams instanceof NTRUParameters) { diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java index 21864da3f6..a8d1c3186c 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java @@ -11,19 +11,20 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.pqc.asn1.CMCEPrivateKey; import org.bouncycastle.pqc.asn1.FalconPrivateKey; -import org.bouncycastle.pqc.asn1.KyberPrivateKey; -import org.bouncycastle.pqc.asn1.KyberPublicKey; import org.bouncycastle.pqc.asn1.McElieceCCA2PrivateKey; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; import org.bouncycastle.pqc.asn1.SPHINCSPLUSPrivateKey; +import org.bouncycastle.pqc.asn1.SPHINCSPLUSPublicKey; import org.bouncycastle.pqc.asn1.XMSSKeyParams; import org.bouncycastle.pqc.asn1.XMSSMTKeyParams; import org.bouncycastle.pqc.asn1.XMSSMTPrivateKey; @@ -34,8 +35,7 @@ import org.bouncycastle.pqc.crypto.cmce.CMCEPrivateKeyParameters; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumParameters; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPrivateKeyParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; import org.bouncycastle.pqc.crypto.falcon.FalconParameters; import org.bouncycastle.pqc.crypto.falcon.FalconPrivateKeyParameters; import org.bouncycastle.pqc.crypto.frodo.FrodoParameters; @@ -44,6 +44,11 @@ import org.bouncycastle.pqc.crypto.hqc.HQCPrivateKeyParameters; import org.bouncycastle.pqc.crypto.lms.HSSPrivateKeyParameters; import org.bouncycastle.pqc.crypto.lms.LMSPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAParameters; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; import org.bouncycastle.pqc.crypto.newhope.NHPrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUPrivateKeyParameters; @@ -57,6 +62,8 @@ import org.bouncycastle.pqc.crypto.rainbow.RainbowPrivateKeyParameters; import org.bouncycastle.pqc.crypto.saber.SABERParameters; import org.bouncycastle.pqc.crypto.saber.SABERPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAPrivateKeyParameters; import org.bouncycastle.pqc.crypto.sphincs.SPHINCSPrivateKeyParameters; import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusParameters; import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusPrivateKeyParameters; @@ -69,8 +76,6 @@ import org.bouncycastle.pqc.crypto.xmss.XMSSUtil; import org.bouncycastle.pqc.legacy.crypto.mceliece.McElieceCCA2PrivateKeyParameters; import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLAPrivateKeyParameters; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEParameters; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEPrivateKeyParameters; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Pack; @@ -132,18 +137,18 @@ public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo) AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm(); ASN1ObjectIdentifier algOID = algId.getAlgorithm(); - if (algOID.on(BCObjectIdentifiers.qTESLA)) + if (algOID.on(PQCObjectIdentifiers.qTESLA)) { ASN1OctetString qTESLAPriv = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()); - return new QTESLAPrivateKeyParameters(Utils.qTeslaLookupSecurityCategory(keyInfo.getPrivateKeyAlgorithm()), qTESLAPriv.getOctets()); + return new QTESLAPrivateKeyParameters(Utils.qTeslaLookupSecurityCategory(algId), qTESLAPriv.getOctets()); } - else if (algOID.equals(BCObjectIdentifiers.sphincs256)) + else if (algOID.equals(PQCObjectIdentifiers.sphincs256)) { return new SPHINCSPrivateKeyParameters(ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(), - Utils.sphincs256LookupTreeAlgName(SPHINCS256KeyParams.getInstance(keyInfo.getPrivateKeyAlgorithm().getParameters()))); + Utils.sphincs256LookupTreeAlgName(SPHINCS256KeyParams.getInstance(algId.getParameters()))); } - else if (algOID.equals(BCObjectIdentifiers.newHope)) + else if (algOID.equals(PQCObjectIdentifiers.newHope)) { return new NHPrivateKeyParameters(convert(ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets())); } @@ -173,74 +178,89 @@ else if (algOID.equals(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig)) return HSSPrivateKeyParameters.getInstance(Arrays.copyOfRange(keyEnc, 4, keyEnc.length)); } } - else if (algOID.on(BCObjectIdentifiers.sphincsPlus)) + else if (algOID.on(BCObjectIdentifiers.sphincsPlus) || algOID.on(BCObjectIdentifiers.sphincsPlus_interop)) { - SPHINCSPLUSPrivateKey spKey = SPHINCSPLUSPrivateKey.getInstance(keyInfo.parsePrivateKey()); - SPHINCSPlusParameters spParams = Utils.sphincsPlusParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + SPHINCSPlusParameters spParams = Utils.sphincsPlusParamsLookup(algOID); - return new SPHINCSPlusPrivateKeyParameters(spParams, spKey.getSkseed(), spKey.getSkprf(), spKey.getPublicKey().getPkseed(), spKey.getPublicKey().getPkroot()); + ASN1Encodable obj = keyInfo.parsePrivateKey(); + if (obj instanceof ASN1Sequence) + { + SPHINCSPLUSPrivateKey spKey = SPHINCSPLUSPrivateKey.getInstance(obj); + SPHINCSPLUSPublicKey publicKey = spKey.getPublicKey(); + return new SPHINCSPlusPrivateKeyParameters(spParams, spKey.getSkseed(), spKey.getSkprf(), + publicKey.getPkseed(), publicKey.getPkroot()); + } + else + { + return new SPHINCSPlusPrivateKeyParameters(spParams, ASN1OctetString.getInstance(obj).getOctets()); + } + } + else if (Utils.shldsaParams.containsKey(algOID)) + { + SLHDSAParameters spParams = Utils.slhdsaParamsLookup(algOID); + + ASN1Encodable obj = keyInfo.parsePrivateKey(); + if (obj instanceof ASN1Sequence) + { + SPHINCSPLUSPrivateKey spKey = SPHINCSPLUSPrivateKey.getInstance(obj); + SPHINCSPLUSPublicKey publicKey = spKey.getPublicKey(); + return new SLHDSAPrivateKeyParameters(spParams, spKey.getSkseed(), spKey.getSkprf(), + publicKey.getPkseed(), publicKey.getPkroot()); + } + else + { + return new SLHDSAPrivateKeyParameters(spParams, ASN1OctetString.getInstance(obj).getOctets()); + } } else if (algOID.on(BCObjectIdentifiers.picnic)) { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); - PicnicParameters pParams = Utils.picnicParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + PicnicParameters pParams = Utils.picnicParamsLookup(algOID); return new PicnicPrivateKeyParameters(pParams, keyEnc); } else if (algOID.on(BCObjectIdentifiers.pqc_kem_mceliece)) { CMCEPrivateKey cmceKey = CMCEPrivateKey.getInstance(keyInfo.parsePrivateKey()); - CMCEParameters spParams = Utils.mcElieceParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + CMCEParameters spParams = Utils.mcElieceParamsLookup(algOID); return new CMCEPrivateKeyParameters(spParams, cmceKey.getDelta(), cmceKey.getC(), cmceKey.getG(), cmceKey.getAlpha(), cmceKey.getS()); } else if (algOID.on(BCObjectIdentifiers.pqc_kem_frodo)) { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); - FrodoParameters spParams = Utils.frodoParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + FrodoParameters spParams = Utils.frodoParamsLookup(algOID); return new FrodoPrivateKeyParameters(spParams, keyEnc); } else if (algOID.on(BCObjectIdentifiers.pqc_kem_saber)) { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); - SABERParameters spParams = Utils.saberParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + SABERParameters spParams = Utils.saberParamsLookup(algOID); return new SABERPrivateKeyParameters(spParams, keyEnc); } - else if (algOID.on(BCObjectIdentifiers.pqc_kem_sike)) - { - byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); - SIKEParameters spParams = Utils.sikeParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); - - return new SIKEPrivateKeyParameters(spParams, keyEnc); - } else if (algOID.on(BCObjectIdentifiers.pqc_kem_ntru)) { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); - NTRUParameters spParams = Utils.ntruParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + NTRUParameters spParams = Utils.ntruParamsLookup(algOID); return new NTRUPrivateKeyParameters(spParams, keyEnc); } - else if (algOID.on(BCObjectIdentifiers.pqc_kem_kyber)) + else if (algOID.equals(NISTObjectIdentifiers.id_alg_ml_kem_512) || + algOID.equals(NISTObjectIdentifiers.id_alg_ml_kem_768) || + algOID.equals(NISTObjectIdentifiers.id_alg_ml_kem_1024)) { - KyberPrivateKey kyberKey = KyberPrivateKey.getInstance(keyInfo.parsePrivateKey()); - KyberParameters kyberParams = Utils.kyberParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + ASN1OctetString kyberKey = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()); + MLKEMParameters kyberParams = Utils.mlkemParamsLookup(algOID); - KyberPublicKey pubKey = kyberKey.getPublicKey(); - if(pubKey != null) - { - return new KyberPrivateKeyParameters(kyberParams, kyberKey.getS(), kyberKey.getHpk(), kyberKey.getNonce(), - kyberKey.getPublicKey().getT(), kyberKey.getPublicKey().getRho()); - } - return new KyberPrivateKeyParameters(kyberParams, kyberKey.getS(), kyberKey.getHpk(), kyberKey.getNonce(), - null, null); + return new MLKEMPrivateKeyParameters(kyberParams, kyberKey.getOctets()); } else if (algOID.on(BCObjectIdentifiers.pqc_kem_ntrulprime)) { ASN1Sequence keyEnc = ASN1Sequence.getInstance(keyInfo.parsePrivateKey()); - NTRULPRimeParameters spParams = Utils.ntrulprimeParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + NTRULPRimeParameters spParams = Utils.ntrulprimeParamsLookup(algOID); return new NTRULPRimePrivateKeyParameters(spParams, ASN1OctetString.getInstance(keyEnc.getObjectAt(0)).getOctets(), @@ -252,7 +272,7 @@ else if (algOID.on(BCObjectIdentifiers.pqc_kem_sntruprime)) { ASN1Sequence keyEnc = ASN1Sequence.getInstance(keyInfo.parsePrivateKey()); - SNTRUPrimeParameters spParams = Utils.sntruprimeParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + SNTRUPrimeParameters spParams = Utils.sntruprimeParamsLookup(algOID); return new SNTRUPrimePrivateKeyParameters(spParams, ASN1OctetString.getInstance(keyEnc.getObjectAt(0)).getOctets(), @@ -261,13 +281,66 @@ else if (algOID.on(BCObjectIdentifiers.pqc_kem_sntruprime)) ASN1OctetString.getInstance(keyEnc.getObjectAt(3)).getOctets(), ASN1OctetString.getInstance(keyEnc.getObjectAt(4)).getOctets()); } + else if (Utils.mldsaParams.containsKey(algOID)) + { + ASN1Encodable keyObj = keyInfo.parsePrivateKey(); + MLDSAParameters spParams = Utils.mldsaParamsLookup(algOID); + + if (keyObj instanceof ASN1Sequence) + { + ASN1Sequence keyEnc = ASN1Sequence.getInstance(keyObj); + + int version = ASN1Integer.getInstance(keyEnc.getObjectAt(0)).intValueExact(); + if (version != 0) + { + throw new IOException("unknown private key version: " + version); + } + + if (keyInfo.getPublicKeyData() != null) + { + MLDSAPublicKeyParameters pubParams = PublicKeyFactory.MLDSAConverter.getPublicKeyParams(spParams, keyInfo.getPublicKeyData()); + + return new MLDSAPrivateKeyParameters(spParams, + ASN1BitString.getInstance(keyEnc.getObjectAt(1)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(2)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(3)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(4)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(5)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(6)).getOctets(), + pubParams.getT1()); // encT1 + } + else + { + return new MLDSAPrivateKeyParameters(spParams, + ASN1BitString.getInstance(keyEnc.getObjectAt(1)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(2)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(3)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(4)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(5)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(6)).getOctets(), + null); + } + } + else if (keyObj instanceof DEROctetString) + { + byte[] data = ASN1OctetString.getInstance(keyObj).getOctets(); + if (keyInfo.getPublicKeyData() != null) + { + MLDSAPublicKeyParameters pubParams = PublicKeyFactory.MLDSAConverter.getPublicKeyParams(spParams, keyInfo.getPublicKeyData()); + return new MLDSAPrivateKeyParameters(spParams, data, pubParams); + } + return new MLDSAPrivateKeyParameters(spParams, data, null); + } + else + { + throw new IOException("not supported"); + } + } else if (algOID.equals(BCObjectIdentifiers.dilithium2) - || algOID.equals(BCObjectIdentifiers.dilithium3) || algOID.equals(BCObjectIdentifiers.dilithium5) - || algOID.equals(BCObjectIdentifiers.dilithium2_aes) - || algOID.equals(BCObjectIdentifiers.dilithium3_aes) || algOID.equals(BCObjectIdentifiers.dilithium5_aes)) + || algOID.equals(BCObjectIdentifiers.dilithium3) || algOID.equals(BCObjectIdentifiers.dilithium5)) { ASN1Encodable keyObj = keyInfo.parsePrivateKey(); - DilithiumParameters spParams = Utils.dilithiumParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + DilithiumParameters dilParams = Utils.dilithiumParamsLookup(algOID); if (keyObj instanceof ASN1Sequence) { @@ -281,19 +354,20 @@ else if (algOID.equals(BCObjectIdentifiers.dilithium2) if (keyInfo.getPublicKeyData() != null) { - ASN1Sequence pubKey = ASN1Sequence.getInstance(keyInfo.getPublicKeyData().getOctets()); - return new DilithiumPrivateKeyParameters(spParams, + DilithiumPublicKeyParameters pubParams = PublicKeyFactory.DilithiumConverter.getPublicKeyParams(dilParams, keyInfo.getPublicKeyData()); + + return new DilithiumPrivateKeyParameters(dilParams, ASN1BitString.getInstance(keyEnc.getObjectAt(1)).getOctets(), ASN1BitString.getInstance(keyEnc.getObjectAt(2)).getOctets(), ASN1BitString.getInstance(keyEnc.getObjectAt(3)).getOctets(), ASN1BitString.getInstance(keyEnc.getObjectAt(4)).getOctets(), ASN1BitString.getInstance(keyEnc.getObjectAt(5)).getOctets(), ASN1BitString.getInstance(keyEnc.getObjectAt(6)).getOctets(), - ASN1OctetString.getInstance(pubKey.getObjectAt(1)).getOctets()); // encT1 + pubParams.getT1()); // encT1 } else { - return new DilithiumPrivateKeyParameters(spParams, + return new DilithiumPrivateKeyParameters(dilParams, ASN1BitString.getInstance(keyEnc.getObjectAt(1)).getOctets(), ASN1BitString.getInstance(keyEnc.getObjectAt(2)).getOctets(), ASN1BitString.getInstance(keyEnc.getObjectAt(3)).getOctets(), @@ -303,31 +377,32 @@ else if (algOID.equals(BCObjectIdentifiers.dilithium2) null); } } + else if (keyObj instanceof DEROctetString) + { + byte[] data = ASN1OctetString.getInstance(keyObj).getOctets(); + if (keyInfo.getPublicKeyData() != null) + { + DilithiumPublicKeyParameters pubParams = PublicKeyFactory.DilithiumConverter.getPublicKeyParams(dilParams, keyInfo.getPublicKeyData()); + return new DilithiumPrivateKeyParameters(dilParams, data, pubParams); + } + return new DilithiumPrivateKeyParameters(dilParams, data, null); + } else { - // TODO throw new IOException("not supported"); -// return new DilithiumPrivateKeyParameters(spParams, -// new byte[1], -// new byte[1], -// new byte[1], -// new byte[1], -// new byte[1], -// new byte[1], -// null); } } else if (algOID.equals(BCObjectIdentifiers.falcon_512) || algOID.equals(BCObjectIdentifiers.falcon_1024)) { FalconPrivateKey falconKey = FalconPrivateKey.getInstance(keyInfo.parsePrivateKey()); - FalconParameters falconParams = Utils.falconParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + FalconParameters falconParams = Utils.falconParamsLookup(algOID); return new FalconPrivateKeyParameters(falconParams, falconKey.getf(), falconKey.getG(), falconKey.getF(), falconKey.getPublicKey().getH()); } else if (algOID.on(BCObjectIdentifiers.pqc_kem_bike)) { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); - BIKEParameters bikeParams = Utils.bikeParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + BIKEParameters bikeParams = Utils.bikeParamsLookup(algOID); byte[] h0 = Arrays.copyOfRange(keyEnc, 0, bikeParams.getRByte()); byte[] h1 = Arrays.copyOfRange(keyEnc, bikeParams.getRByte(), 2 * bikeParams.getRByte()); @@ -337,20 +412,20 @@ else if (algOID.on(BCObjectIdentifiers.pqc_kem_bike)) else if (algOID.on(BCObjectIdentifiers.pqc_kem_hqc)) { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); - HQCParameters hqcParams = Utils.hqcParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + HQCParameters hqcParams = Utils.hqcParamsLookup(algOID); return new HQCPrivateKeyParameters(hqcParams, keyEnc); } else if (algOID.on(BCObjectIdentifiers.rainbow)) { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); - RainbowParameters rainbowParams = Utils.rainbowParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm()); + RainbowParameters rainbowParams = Utils.rainbowParamsLookup(algOID); return new RainbowPrivateKeyParameters(rainbowParams, keyEnc); } - else if (algOID.equals(BCObjectIdentifiers.xmss)) + else if (algOID.equals(PQCObjectIdentifiers.xmss)) { - XMSSKeyParams keyParams = XMSSKeyParams.getInstance(keyInfo.getPrivateKeyAlgorithm().getParameters()); + XMSSKeyParams keyParams = XMSSKeyParams.getInstance(algId.getParameters()); ASN1ObjectIdentifier treeDigest = keyParams.getTreeDigest().getAlgorithm(); XMSSPrivateKey xmssPrivateKey = XMSSPrivateKey.getInstance(keyInfo.parsePrivateKey()); @@ -385,7 +460,7 @@ else if (algOID.equals(BCObjectIdentifiers.xmss)) } else if (algOID.equals(PQCObjectIdentifiers.xmss_mt)) { - XMSSMTKeyParams keyParams = XMSSMTKeyParams.getInstance(keyInfo.getPrivateKeyAlgorithm().getParameters()); + XMSSMTKeyParams keyParams = XMSSMTKeyParams.getInstance(algId.getParameters()); ASN1ObjectIdentifier treeDigest = keyParams.getTreeDigest().getAlgorithm(); try diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java index 424724b0cb..e2cec72e51 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java @@ -3,9 +3,7 @@ import java.io.IOException; import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Set; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; @@ -16,13 +14,9 @@ import org.bouncycastle.pqc.asn1.CMCEPublicKey; import org.bouncycastle.pqc.asn1.FalconPrivateKey; import org.bouncycastle.pqc.asn1.FalconPublicKey; -import org.bouncycastle.pqc.asn1.KyberPrivateKey; -import org.bouncycastle.pqc.asn1.KyberPublicKey; import org.bouncycastle.pqc.asn1.McElieceCCA2PrivateKey; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; -import org.bouncycastle.pqc.asn1.SPHINCSPLUSPrivateKey; -import org.bouncycastle.pqc.asn1.SPHINCSPLUSPublicKey; import org.bouncycastle.pqc.asn1.XMSSKeyParams; import org.bouncycastle.pqc.asn1.XMSSMTKeyParams; import org.bouncycastle.pqc.asn1.XMSSMTPrivateKey; @@ -30,13 +24,16 @@ import org.bouncycastle.pqc.crypto.bike.BIKEPrivateKeyParameters; import org.bouncycastle.pqc.crypto.cmce.CMCEPrivateKeyParameters; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPrivateKeyParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; import org.bouncycastle.pqc.crypto.falcon.FalconPrivateKeyParameters; import org.bouncycastle.pqc.crypto.frodo.FrodoPrivateKeyParameters; import org.bouncycastle.pqc.crypto.hqc.HQCPrivateKeyParameters; import org.bouncycastle.pqc.crypto.lms.Composer; import org.bouncycastle.pqc.crypto.lms.HSSPrivateKeyParameters; import org.bouncycastle.pqc.crypto.lms.LMSPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; import org.bouncycastle.pqc.crypto.newhope.NHPrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUPrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePrivateKeyParameters; @@ -44,6 +41,7 @@ import org.bouncycastle.pqc.crypto.picnic.PicnicPrivateKeyParameters; import org.bouncycastle.pqc.crypto.rainbow.RainbowPrivateKeyParameters; import org.bouncycastle.pqc.crypto.saber.SABERPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAPrivateKeyParameters; import org.bouncycastle.pqc.crypto.sphincs.SPHINCSPrivateKeyParameters; import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusPrivateKeyParameters; import org.bouncycastle.pqc.crypto.xmss.BDS; @@ -53,7 +51,6 @@ import org.bouncycastle.pqc.crypto.xmss.XMSSUtil; import org.bouncycastle.pqc.legacy.crypto.mceliece.McElieceCCA2PrivateKeyParameters; import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLAPrivateKeyParameters; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEPrivateKeyParameters; import org.bouncycastle.util.Pack; /** @@ -63,7 +60,6 @@ public class PrivateKeyInfoFactory { private PrivateKeyInfoFactory() { - } /** @@ -100,7 +96,7 @@ else if (privateKey instanceof SPHINCSPrivateKeyParameters) { SPHINCSPrivateKeyParameters params = (SPHINCSPrivateKeyParameters)privateKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.sphincs256, - new SPHINCS256KeyParams(Utils.sphincs256LookupTreeAlgID(params.getTreeDigest()))); + new SPHINCS256KeyParams(Utils.sphincs256LookupTreeAlgID(params.getTreeDigest()))); return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getKeyData())); } @@ -143,16 +139,21 @@ else if (privateKey instanceof HSSPrivateKeyParameters) else if (privateKey instanceof SPHINCSPlusPrivateKeyParameters) { SPHINCSPlusPrivateKeyParameters params = (SPHINCSPlusPrivateKeyParameters)privateKey; - + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.sphincsPlusOidLookup(params.getParameters())); - SPHINCSPLUSPublicKey spPub = new SPHINCSPLUSPublicKey(params.getPublicSeed(), params.getRoot()); - SPHINCSPLUSPrivateKey spPriv = new SPHINCSPLUSPrivateKey(0, params.getSeed(), params.getPrf(), spPub); - return new PrivateKeyInfo(algorithmIdentifier, spPriv, attributes); + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getEncoded()), attributes, params.getPublicKey()); } - else if (privateKey instanceof PicnicPrivateKeyParameters) + else if (privateKey instanceof SLHDSAPrivateKeyParameters) { + SLHDSAPrivateKeyParameters params = (SLHDSAPrivateKeyParameters)privateKey; + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.slhdsaOidLookup(params.getParameters())); + + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getEncoded()), attributes, params.getPublicKey()); + } + else if (privateKey instanceof PicnicPrivateKeyParameters) + { PicnicPrivateKeyParameters params = (PicnicPrivateKeyParameters)privateKey; byte[] encoding = params.getEncoded(); @@ -164,7 +165,6 @@ else if (privateKey instanceof CMCEPrivateKeyParameters) { CMCEPrivateKeyParameters params = (CMCEPrivateKeyParameters)privateKey; - byte[] encoding = params.getEncoded(); //todo either make CMCEPrivateKey split the parameters from the private key or // (current) Make CMCEPrivateKey take parts of the private key splitted in the params @@ -220,16 +220,6 @@ else if (privateKey instanceof SABERPrivateKeyParameters) return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); } - else if (privateKey instanceof SIKEPrivateKeyParameters) - { - SIKEPrivateKeyParameters params = (SIKEPrivateKeyParameters)privateKey; - - byte[] encoding = params.getEncoded(); - - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.sikeOidLookup(params.getParameters())); - - return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); - } else if (privateKey instanceof NTRUPrivateKeyParameters) { NTRUPrivateKeyParameters params = (NTRUPrivateKeyParameters)privateKey; @@ -251,16 +241,13 @@ else if (privateKey instanceof FalconPrivateKeyParameters) return new PrivateKeyInfo(algorithmIdentifier, falconPriv, attributes); } - else if (privateKey instanceof KyberPrivateKeyParameters) + else if (privateKey instanceof MLKEMPrivateKeyParameters) { - KyberPrivateKeyParameters params = (KyberPrivateKeyParameters)privateKey; + MLKEMPrivateKeyParameters params = (MLKEMPrivateKeyParameters)privateKey; - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.kyberOidLookup(params.getParameters())); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.mlkemOidLookup(params.getParameters())); - KyberPublicKey kyberPub = new KyberPublicKey(params.getT(), params.getRho()); - KyberPrivateKey kyberPriv = new KyberPrivateKey(0, params.getS(), params.getHPK(), params.getNonce(), kyberPub); - - return new PrivateKeyInfo(algorithmIdentifier, kyberPriv, attributes); + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getEncoded()), attributes); } else if (privateKey instanceof NTRULPRimePrivateKeyParameters) { @@ -293,27 +280,25 @@ else if (privateKey instanceof SNTRUPrimePrivateKeyParameters) return new PrivateKeyInfo(algorithmIdentifier, new DERSequence(v), attributes); } - else if (privateKey instanceof DilithiumPrivateKeyParameters) + else if (privateKey instanceof MLDSAPrivateKeyParameters) { - DilithiumPrivateKeyParameters params = (DilithiumPrivateKeyParameters)privateKey; + MLDSAPrivateKeyParameters params = (MLDSAPrivateKeyParameters)privateKey; - ASN1EncodableVector v = new ASN1EncodableVector(); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.mldsaOidLookup(params.getParameters())); + + MLDSAPublicKeyParameters pubParams = params.getPublicKeyParameters(); - v.add(new ASN1Integer(0)); - v.add(new DERBitString(params.getRho())); - v.add(new DERBitString(params.getK())); - v.add(new DERBitString(params.getTr())); - v.add(new DERBitString(params.getS1())); - v.add(new DERBitString(params.getS2())); - v.add(new DERBitString(params.getT0())); + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getEncoded()), attributes, pubParams.getEncoded()); + } + else if (privateKey instanceof DilithiumPrivateKeyParameters) + { + DilithiumPrivateKeyParameters params = (DilithiumPrivateKeyParameters)privateKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.dilithiumOidLookup(params.getParameters())); - ASN1EncodableVector vPub = new ASN1EncodableVector(); - vPub.add(new DEROctetString(params.getRho())); - vPub.add(new DEROctetString(params.getT1())); + DilithiumPublicKeyParameters pubParams = params.getPublicKeyParameters(); - return new PrivateKeyInfo(algorithmIdentifier, new DERSequence(v), attributes, new DERSequence(vPub).getEncoded()); + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getEncoded()), attributes, pubParams.getEncoded()); } else if (privateKey instanceof BIKEPrivateKeyParameters) { diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java index 357118c915..12f034acdb 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java @@ -5,17 +5,19 @@ import java.util.HashMap; import java.util.Map; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; -import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.internal.asn1.isara.IsaraObjectIdentifiers; import org.bouncycastle.pqc.asn1.CMCEPublicKey; import org.bouncycastle.pqc.asn1.KyberPublicKey; import org.bouncycastle.pqc.asn1.McElieceCCA2PublicKey; @@ -30,8 +32,6 @@ import org.bouncycastle.pqc.crypto.cmce.CMCEPublicKeyParameters; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumParameters; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberPublicKeyParameters; import org.bouncycastle.pqc.crypto.falcon.FalconParameters; import org.bouncycastle.pqc.crypto.falcon.FalconPublicKeyParameters; import org.bouncycastle.pqc.crypto.frodo.FrodoParameters; @@ -40,6 +40,10 @@ import org.bouncycastle.pqc.crypto.hqc.HQCPublicKeyParameters; import org.bouncycastle.pqc.crypto.lms.HSSPublicKeyParameters; import org.bouncycastle.pqc.crypto.lms.LMSPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAParameters; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; import org.bouncycastle.pqc.crypto.newhope.NHPublicKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUPublicKeyParameters; @@ -53,6 +57,8 @@ import org.bouncycastle.pqc.crypto.rainbow.RainbowPublicKeyParameters; import org.bouncycastle.pqc.crypto.saber.SABERParameters; import org.bouncycastle.pqc.crypto.saber.SABERPublicKeyParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAPublicKeyParameters; import org.bouncycastle.pqc.crypto.sphincs.SPHINCSPublicKeyParameters; import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusParameters; import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusPublicKeyParameters; @@ -62,8 +68,6 @@ import org.bouncycastle.pqc.crypto.xmss.XMSSPublicKeyParameters; import org.bouncycastle.pqc.legacy.crypto.mceliece.McElieceCCA2PublicKeyParameters; import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLAPublicKeyParameters; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEParameters; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEPublicKeyParameters; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Pack; @@ -88,6 +92,7 @@ public class PublicKeyFactory converters.put(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, new LMSConverter()); converters.put(PQCObjectIdentifiers.mcElieceCca2, new McElieceCCA2Converter()); converters.put(BCObjectIdentifiers.sphincsPlus, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, new SPHINCSPlusConverter()); converters.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, new SPHINCSPlusConverter()); converters.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, new SPHINCSPlusConverter()); @@ -106,6 +111,27 @@ public class PublicKeyFactory converters.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, new SPHINCSPlusConverter()); converters.put(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, new SPHINCSPlusConverter()); converters.put(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple, new SPHINCSPlusConverter()); + + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_128s, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_128f, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_128s, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_128f, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_192s, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_192f, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_192s, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_192f, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_256s, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_256f, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_256s, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_256f, new SPHINCSPlusConverter()); + converters.put(new ASN1ObjectIdentifier("1.3.9999.6.4.10"), new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.mceliece348864_r3, new CMCEConverter()); converters.put(BCObjectIdentifiers.mceliece348864f_r3, new CMCEConverter()); converters.put(BCObjectIdentifiers.mceliece460896_r3, new CMCEConverter()); @@ -152,23 +178,17 @@ public class PublicKeyFactory converters.put(BCObjectIdentifiers.picnicl1full, new PicnicConverter()); converters.put(BCObjectIdentifiers.picnicl3full, new PicnicConverter()); converters.put(BCObjectIdentifiers.picnicl5full, new PicnicConverter()); - converters.put(BCObjectIdentifiers.sikep434, new SIKEConverter()); - converters.put(BCObjectIdentifiers.sikep503, new SIKEConverter()); - converters.put(BCObjectIdentifiers.sikep610, new SIKEConverter()); - converters.put(BCObjectIdentifiers.sikep751, new SIKEConverter()); - converters.put(BCObjectIdentifiers.sikep434_compressed, new SIKEConverter()); - converters.put(BCObjectIdentifiers.sikep503_compressed, new SIKEConverter()); - converters.put(BCObjectIdentifiers.sikep610_compressed, new SIKEConverter()); - converters.put(BCObjectIdentifiers.sikep751_compressed, new SIKEConverter()); converters.put(BCObjectIdentifiers.ntruhps2048509, new NtruConverter()); converters.put(BCObjectIdentifiers.ntruhps2048677, new NtruConverter()); converters.put(BCObjectIdentifiers.ntruhps4096821, new NtruConverter()); + converters.put(BCObjectIdentifiers.ntruhps40961229, new NtruConverter()); converters.put(BCObjectIdentifiers.ntruhrss701, new NtruConverter()); + converters.put(BCObjectIdentifiers.ntruhrss1373, new NtruConverter()); converters.put(BCObjectIdentifiers.falcon_512, new FalconConverter()); converters.put(BCObjectIdentifiers.falcon_1024, new FalconConverter()); - converters.put(BCObjectIdentifiers.kyber512, new KyberConverter()); - converters.put(BCObjectIdentifiers.kyber768, new KyberConverter()); - converters.put(BCObjectIdentifiers.kyber1024, new KyberConverter()); + converters.put(NISTObjectIdentifiers.id_alg_ml_kem_512, new KyberConverter()); + converters.put(NISTObjectIdentifiers.id_alg_ml_kem_768, new KyberConverter()); + converters.put(NISTObjectIdentifiers.id_alg_ml_kem_1024, new KyberConverter()); converters.put(BCObjectIdentifiers.kyber512_aes, new KyberConverter()); converters.put(BCObjectIdentifiers.kyber768_aes, new KyberConverter()); converters.put(BCObjectIdentifiers.kyber1024_aes, new KyberConverter()); @@ -184,6 +204,12 @@ public class PublicKeyFactory converters.put(BCObjectIdentifiers.sntrup953, new SNTRUPrimeConverter()); converters.put(BCObjectIdentifiers.sntrup1013, new SNTRUPrimeConverter()); converters.put(BCObjectIdentifiers.sntrup1277, new SNTRUPrimeConverter()); + converters.put(NISTObjectIdentifiers.id_ml_dsa_44, new MLDSAConverter()); + converters.put(NISTObjectIdentifiers.id_ml_dsa_65, new MLDSAConverter()); + converters.put(NISTObjectIdentifiers.id_ml_dsa_87, new MLDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512, new MLDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512, new MLDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512, new MLDSAConverter()); converters.put(BCObjectIdentifiers.dilithium2, new DilithiumConverter()); converters.put(BCObjectIdentifiers.dilithium3, new DilithiumConverter()); converters.put(BCObjectIdentifiers.dilithium5, new DilithiumConverter()); @@ -202,6 +228,31 @@ public class PublicKeyFactory converters.put(BCObjectIdentifiers.rainbow_V_classic, new RainbowConverter()); converters.put(BCObjectIdentifiers.rainbow_V_circumzenithal, new RainbowConverter()); converters.put(BCObjectIdentifiers.rainbow_V_compressed, new RainbowConverter()); + + converters.put(NISTObjectIdentifiers.id_slh_dsa_sha2_128s, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_slh_dsa_sha2_128f, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_slh_dsa_sha2_192s, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_slh_dsa_sha2_192f, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_slh_dsa_sha2_256s, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_slh_dsa_sha2_256f, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_slh_dsa_shake_128s, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_slh_dsa_shake_128f, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_slh_dsa_shake_192s, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_slh_dsa_shake_192f, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_slh_dsa_shake_256s, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_slh_dsa_shake_256f, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256, new SLHDSAConverter()); + converters.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256, new SLHDSAConverter()); } /** @@ -410,11 +461,22 @@ private static class SPHINCSPlusConverter AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) throws IOException { - byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + try + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); - SPHINCSPlusParameters spParams = Utils.sphincsPlusParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + SPHINCSPlusParameters spParams = Utils.sphincsPlusParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); - return new SPHINCSPlusPublicKeyParameters(spParams, Arrays.copyOfRange(keyEnc, 4, keyEnc.length)); + return new SPHINCSPlusPublicKeyParameters(spParams, Arrays.copyOfRange(keyEnc, 4, keyEnc.length)); + } + catch (Exception e) + { + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); + + SPHINCSPlusParameters spParams = Utils.sphincsPlusParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new SPHINCSPlusPublicKeyParameters(spParams, keyEnc); + } } } @@ -424,11 +486,22 @@ private static class CMCEConverter AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) throws IOException { - byte[] keyEnc = CMCEPublicKey.getInstance(keyInfo.parsePublicKey()).getT(); + try + { + byte[] keyEnc = CMCEPublicKey.getInstance(keyInfo.parsePublicKey()).getT(); - CMCEParameters spParams = Utils.mcElieceParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + CMCEParameters spParams = Utils.mcElieceParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); - return new CMCEPublicKeyParameters(spParams, keyEnc); + return new CMCEPublicKeyParameters(spParams, keyEnc); + } + catch (Exception e) + { + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); + + CMCEParameters spParams = Utils.mcElieceParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new CMCEPublicKeyParameters(spParams, keyEnc); + } } } @@ -473,20 +546,6 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } } - private static class SIKEConverter - extends SubjectPublicKeyInfoConverter - { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException - { - byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); - - SIKEParameters sParams = Utils.sikeParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); - - return new SIKEPublicKeyParameters(sParams, keyEnc); - } - } - private static class PicnicConverter extends SubjectPublicKeyInfoConverter { @@ -537,19 +596,19 @@ private static class KyberConverter AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) throws IOException { - KyberParameters kyberParameters = Utils.kyberParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + MLKEMParameters kyberParameters = Utils.mlkemParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); try { ASN1Primitive obj = keyInfo.parsePublicKey(); KyberPublicKey kyberKey = KyberPublicKey.getInstance(obj); - return new KyberPublicKeyParameters(kyberParameters, kyberKey.getT(), kyberKey.getRho()); + return new MLKEMPublicKeyParameters(kyberParameters, kyberKey.getT(), kyberKey.getRho()); } - catch (IOException e) + catch (Exception e) { // we're a raw encoding - return new KyberPublicKeyParameters(kyberParameters, keyInfo.getPublicKeyData().getOctets()); + return new MLKEMPublicKeyParameters(kyberParameters, keyInfo.getPublicKeyData().getOctets()); } } } @@ -582,7 +641,7 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } } - private static class DilithiumConverter + static class DilithiumConverter extends SubjectPublicKeyInfoConverter { AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) @@ -590,9 +649,14 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje { DilithiumParameters dilithiumParams = Utils.dilithiumParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + return getPublicKeyParams(dilithiumParams, keyInfo.getPublicKeyData()); + } + + static DilithiumPublicKeyParameters getPublicKeyParams(DilithiumParameters dilithiumParams, ASN1BitString publicKeyData) + { try { - ASN1Primitive obj = keyInfo.parsePublicKey(); + ASN1Primitive obj = ASN1Primitive.fromByteArray(publicKeyData.getOctets()); if (obj instanceof ASN1Sequence) { ASN1Sequence keySeq = ASN1Sequence.getInstance(obj); @@ -608,10 +672,49 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje return new DilithiumPublicKeyParameters(dilithiumParams, encKey); } } - catch (IOException e) + catch (Exception e) + { + // we're a raw encoding + return new DilithiumPublicKeyParameters(dilithiumParams, publicKeyData.getOctets()); + } + } + } + + static class MLDSAConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + MLDSAParameters dilithiumParams = Utils.mldsaParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return getPublicKeyParams(dilithiumParams, keyInfo.getPublicKeyData()); + } + + static MLDSAPublicKeyParameters getPublicKeyParams(MLDSAParameters dilithiumParams, ASN1BitString publicKeyData) + { + try + { + ASN1Primitive obj = ASN1Primitive.fromByteArray(publicKeyData.getOctets()); + if (obj instanceof ASN1Sequence) + { + ASN1Sequence keySeq = ASN1Sequence.getInstance(obj); + + return new MLDSAPublicKeyParameters(dilithiumParams, + ASN1OctetString.getInstance(keySeq.getObjectAt(0)).getOctets(), + ASN1OctetString.getInstance(keySeq.getObjectAt(1)).getOctets()); + } + else + { + byte[] encKey = ASN1OctetString.getInstance(obj).getOctets(); + + return new MLDSAPublicKeyParameters(dilithiumParams, encKey); + } + } + catch (Exception e) { // we're a raw encoding - return new DilithiumPublicKeyParameters(dilithiumParams, keyInfo.getPublicKeyData().getOctets()); + return new MLDSAPublicKeyParameters(dilithiumParams, publicKeyData.getOctets()); } } } @@ -622,11 +725,22 @@ private static class BIKEConverter AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) throws IOException { - byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + try + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + BIKEParameters bikeParams = Utils.bikeParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new BIKEPublicKeyParameters(bikeParams, keyEnc); + } + catch (Exception e) + { + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); - BIKEParameters bikeParams = Utils.bikeParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + BIKEParameters bikeParams = Utils.bikeParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); - return new BIKEPublicKeyParameters(bikeParams, keyEnc); + return new BIKEPublicKeyParameters(bikeParams, keyEnc); + } } } @@ -636,11 +750,48 @@ private static class HQCConverter AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) throws IOException { - byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + try + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + HQCParameters hqcParams = Utils.hqcParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new HQCPublicKeyParameters(hqcParams, keyEnc); + } + catch (Exception e) + { + // raw encoding + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); + + HQCParameters hqcParams = Utils.hqcParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new HQCPublicKeyParameters(hqcParams, keyEnc); + } + } + } + + private static class SLHDSAConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + try + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + SLHDSAParameters spParams = Utils.slhdsaParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new SLHDSAPublicKeyParameters(spParams, Arrays.copyOfRange(keyEnc, 4, keyEnc.length)); + } + catch (Exception e) + { + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); - HQCParameters hqcParams = Utils.hqcParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + SLHDSAParameters spParams = Utils.slhdsaParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); - return new HQCPublicKeyParameters(hqcParams, keyEnc); + return new SLHDSAPublicKeyParameters(spParams, keyEnc); + } } } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java index 4a322e0ef4..2d525d4c1a 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java @@ -4,12 +4,11 @@ import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.pqc.asn1.CMCEPublicKey; +import org.bouncycastle.internal.asn1.isara.IsaraObjectIdentifiers; import org.bouncycastle.pqc.asn1.McElieceCCA2PublicKey; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; @@ -20,13 +19,14 @@ import org.bouncycastle.pqc.crypto.bike.BIKEPublicKeyParameters; import org.bouncycastle.pqc.crypto.cmce.CMCEPublicKeyParameters; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberPublicKeyParameters; import org.bouncycastle.pqc.crypto.falcon.FalconPublicKeyParameters; import org.bouncycastle.pqc.crypto.frodo.FrodoPublicKeyParameters; import org.bouncycastle.pqc.crypto.hqc.HQCPublicKeyParameters; import org.bouncycastle.pqc.crypto.lms.Composer; import org.bouncycastle.pqc.crypto.lms.HSSPublicKeyParameters; import org.bouncycastle.pqc.crypto.lms.LMSPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; import org.bouncycastle.pqc.crypto.newhope.NHPublicKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUPublicKeyParameters; import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePublicKeyParameters; @@ -34,14 +34,13 @@ import org.bouncycastle.pqc.crypto.picnic.PicnicPublicKeyParameters; import org.bouncycastle.pqc.crypto.rainbow.RainbowPublicKeyParameters; import org.bouncycastle.pqc.crypto.saber.SABERPublicKeyParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAPublicKeyParameters; import org.bouncycastle.pqc.crypto.sphincs.SPHINCSPublicKeyParameters; import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusPublicKeyParameters; import org.bouncycastle.pqc.crypto.xmss.XMSSMTPublicKeyParameters; import org.bouncycastle.pqc.crypto.xmss.XMSSPublicKeyParameters; import org.bouncycastle.pqc.legacy.crypto.mceliece.McElieceCCA2PublicKeyParameters; import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLAPublicKeyParameters; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEPublicKeyParameters; -import org.bouncycastle.util.Arrays; /** * Factory to create ASN.1 subject public key info objects from lightweight public keys. @@ -103,6 +102,15 @@ else if (publicKey instanceof HSSPublicKeyParameters) AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig); return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); } + else if (publicKey instanceof SLHDSAPublicKeyParameters) + { + SLHDSAPublicKeyParameters params = (SLHDSAPublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.slhdsaOidLookup(params.getParameters())); + return new SubjectPublicKeyInfo(algorithmIdentifier, encoding); + } else if (publicKey instanceof SPHINCSPlusPublicKeyParameters) { SPHINCSPlusPublicKeyParameters params = (SPHINCSPlusPublicKeyParameters)publicKey; @@ -110,7 +118,7 @@ else if (publicKey instanceof SPHINCSPlusPublicKeyParameters) byte[] encoding = params.getEncoded(); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.sphincsPlusOidLookup(params.getParameters())); - return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); + return new SubjectPublicKeyInfo(algorithmIdentifier, encoding); } else if (publicKey instanceof CMCEPublicKeyParameters) { @@ -120,8 +128,7 @@ else if (publicKey instanceof CMCEPublicKeyParameters) AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.mcElieceOidLookup(params.getParameters())); - // https://datatracker.ietf.org/doc/draft-uni-qsckeys/ - return new SubjectPublicKeyInfo(algorithmIdentifier, new CMCEPublicKey(encoding)); + return new SubjectPublicKeyInfo(algorithmIdentifier, encoding); } else if (publicKey instanceof XMSSPublicKeyParameters) { @@ -180,7 +187,7 @@ else if (publicKey instanceof FrodoPublicKeyParameters) AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.frodoOidLookup(params.getParameters())); - return new SubjectPublicKeyInfo(algorithmIdentifier, (new DEROctetString(encoding))); + return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); } else if (publicKey instanceof SABERPublicKeyParameters) { @@ -201,14 +208,6 @@ else if (publicKey instanceof PicnicPublicKeyParameters) AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.picnicOidLookup(params.getParameters())); return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); } - else if (publicKey instanceof SIKEPublicKeyParameters) - { - SIKEPublicKeyParameters params = (SIKEPublicKeyParameters)publicKey; - - byte[] encoding = params.getEncoded(); - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.sikeOidLookup(params.getParameters())); - return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); - } else if (publicKey instanceof NTRUPublicKeyParameters) { NTRUPublicKeyParameters params = (NTRUPublicKeyParameters)publicKey; @@ -231,16 +230,13 @@ else if (publicKey instanceof FalconPublicKeyParameters) return new SubjectPublicKeyInfo(algorithmIdentifier, keyEnc); } - else if (publicKey instanceof KyberPublicKeyParameters) + else if (publicKey instanceof MLKEMPublicKeyParameters) { - KyberPublicKeyParameters params = (KyberPublicKeyParameters)publicKey; - - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.kyberOidLookup(params.getParameters())); -// ASN1EncodableVector v = new ASN1EncodableVector(); -// v.add(new DEROctetString(params.getT())); -// v.add(new DEROctetString(params.getRho())); -// return new SubjectPublicKeyInfo(algorithmIdentifier, new DERSequence(v)); - return new SubjectPublicKeyInfo(algorithmIdentifier, Arrays.concatenate(params.getT(), params.getRho())); + MLKEMPublicKeyParameters params = (MLKEMPublicKeyParameters)publicKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.mlkemOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, params.getEncoded()); } else if (publicKey instanceof NTRULPRimePublicKeyParameters) { @@ -266,7 +262,15 @@ else if (publicKey instanceof DilithiumPublicKeyParameters) AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.dilithiumOidLookup(params.getParameters())); - return new SubjectPublicKeyInfo(algorithmIdentifier, Arrays.concatenate(params.getRho(), params.getT1())); + return new SubjectPublicKeyInfo(algorithmIdentifier, params.getEncoded()); + } + else if (publicKey instanceof MLDSAPublicKeyParameters) + { + MLDSAPublicKeyParameters params = (MLDSAPublicKeyParameters)publicKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.mldsaOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, params.getEncoded()); } else if (publicKey instanceof BIKEPublicKeyParameters) { @@ -276,7 +280,7 @@ else if (publicKey instanceof BIKEPublicKeyParameters) AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.bikeOidLookup(params.getParameters())); - return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); + return new SubjectPublicKeyInfo(algorithmIdentifier, encoding); } else if (publicKey instanceof HQCPublicKeyParameters) { @@ -286,7 +290,7 @@ else if (publicKey instanceof HQCPublicKeyParameters) AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.hqcOidLookup(params.getParameters())); - return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); + return new SubjectPublicKeyInfo(algorithmIdentifier, encoding); } else if (publicKey instanceof RainbowPublicKeyParameters) { diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/Utils.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/Utils.java index 693c96c84e..6e53dbf7d9 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/Utils.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/Utils.java @@ -7,32 +7,33 @@ import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.digests.SHAKEDigest; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; import org.bouncycastle.pqc.crypto.bike.BIKEParameters; import org.bouncycastle.pqc.crypto.cmce.CMCEParameters; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters; import org.bouncycastle.pqc.crypto.falcon.FalconParameters; import org.bouncycastle.pqc.crypto.frodo.FrodoParameters; import org.bouncycastle.pqc.crypto.hqc.HQCParameters; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUParameters; import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeParameters; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeParameters; import org.bouncycastle.pqc.crypto.picnic.PicnicParameters; import org.bouncycastle.pqc.crypto.rainbow.RainbowParameters; import org.bouncycastle.pqc.crypto.saber.SABERParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAParameters; import org.bouncycastle.pqc.crypto.sphincs.SPHINCSKeyParameters; import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusParameters; import org.bouncycastle.pqc.crypto.xmss.XMSSKeyParameters; import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLASecurityCategory; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEParameters; import org.bouncycastle.util.Integers; class Utils @@ -74,9 +75,6 @@ class Utils static final Map falconOids = new HashMap(); static final Map falconParams = new HashMap(); - static final Map kyberOids = new HashMap(); - static final Map kyberParams = new HashMap(); - static final Map ntruprimeOids = new HashMap(); static final Map ntruprimeParams = new HashMap(); @@ -95,6 +93,15 @@ class Utils static final Map rainbowOids = new HashMap(); static final Map rainbowParams = new HashMap(); + static final Map mlkemOids = new HashMap(); + static final Map mlkemParams = new HashMap(); + + static final Map mldsaOids = new HashMap(); + static final Map mldsaParams = new HashMap(); + + static final Map shldsaOids = new HashMap(); + static final Map shldsaParams = new HashMap(); + static { categories.put(PQCObjectIdentifiers.qTESLA_p_I, Integers.valueOf(QTESLASecurityCategory.PROVABLY_SECURE_I)); @@ -201,33 +208,19 @@ class Utils picnicParams.put(BCObjectIdentifiers.picnicl3full, PicnicParameters.picnicl3full); picnicParams.put(BCObjectIdentifiers.picnicl5full, PicnicParameters.picnicl5full); - sikeOids.put(SIKEParameters.sikep434, BCObjectIdentifiers.sikep434); - sikeOids.put(SIKEParameters.sikep503, BCObjectIdentifiers.sikep503); - sikeOids.put(SIKEParameters.sikep610, BCObjectIdentifiers.sikep610); - sikeOids.put(SIKEParameters.sikep751, BCObjectIdentifiers.sikep751); - sikeOids.put(SIKEParameters.sikep434_compressed, BCObjectIdentifiers.sikep434_compressed); - sikeOids.put(SIKEParameters.sikep503_compressed, BCObjectIdentifiers.sikep503_compressed); - sikeOids.put(SIKEParameters.sikep610_compressed, BCObjectIdentifiers.sikep610_compressed); - sikeOids.put(SIKEParameters.sikep751_compressed, BCObjectIdentifiers.sikep751_compressed); - - sikeParams.put(BCObjectIdentifiers.sikep434, SIKEParameters.sikep434); - sikeParams.put(BCObjectIdentifiers.sikep503, SIKEParameters.sikep503); - sikeParams.put(BCObjectIdentifiers.sikep610, SIKEParameters.sikep610); - sikeParams.put(BCObjectIdentifiers.sikep751, SIKEParameters.sikep751); - sikeParams.put(BCObjectIdentifiers.sikep434_compressed, SIKEParameters.sikep434_compressed); - sikeParams.put(BCObjectIdentifiers.sikep503_compressed, SIKEParameters.sikep503_compressed); - sikeParams.put(BCObjectIdentifiers.sikep610_compressed, SIKEParameters.sikep610_compressed); - sikeParams.put(BCObjectIdentifiers.sikep751_compressed, SIKEParameters.sikep751_compressed); - ntruOids.put(NTRUParameters.ntruhps2048509, BCObjectIdentifiers.ntruhps2048509); ntruOids.put(NTRUParameters.ntruhps2048677, BCObjectIdentifiers.ntruhps2048677); ntruOids.put(NTRUParameters.ntruhps4096821, BCObjectIdentifiers.ntruhps4096821); + ntruOids.put(NTRUParameters.ntruhps40961229, BCObjectIdentifiers.ntruhps40961229); ntruOids.put(NTRUParameters.ntruhrss701, BCObjectIdentifiers.ntruhrss701); + ntruOids.put(NTRUParameters.ntruhrss1373, BCObjectIdentifiers.ntruhrss1373); ntruParams.put(BCObjectIdentifiers.ntruhps2048509, NTRUParameters.ntruhps2048509); ntruParams.put(BCObjectIdentifiers.ntruhps2048677, NTRUParameters.ntruhps2048677); ntruParams.put(BCObjectIdentifiers.ntruhps4096821, NTRUParameters.ntruhps4096821); + ntruParams.put(BCObjectIdentifiers.ntruhps40961229, NTRUParameters.ntruhps40961229); ntruParams.put(BCObjectIdentifiers.ntruhrss701, NTRUParameters.ntruhrss701); + ntruParams.put(BCObjectIdentifiers.ntruhrss1373, NTRUParameters.ntruhrss1373); falconOids.put(FalconParameters.falcon_512, BCObjectIdentifiers.falcon_512); falconOids.put(FalconParameters.falcon_1024, BCObjectIdentifiers.falcon_1024); @@ -235,19 +228,13 @@ class Utils falconParams.put(BCObjectIdentifiers.falcon_512, FalconParameters.falcon_512); falconParams.put(BCObjectIdentifiers.falcon_1024, FalconParameters.falcon_1024); - kyberOids.put(KyberParameters.kyber512, BCObjectIdentifiers.kyber512); - kyberOids.put(KyberParameters.kyber768, BCObjectIdentifiers.kyber768); - kyberOids.put(KyberParameters.kyber1024, BCObjectIdentifiers.kyber1024); - kyberOids.put(KyberParameters.kyber512_aes, BCObjectIdentifiers.kyber512_aes); - kyberOids.put(KyberParameters.kyber768_aes, BCObjectIdentifiers.kyber768_aes); - kyberOids.put(KyberParameters.kyber1024_aes, BCObjectIdentifiers.kyber1024_aes); + mlkemOids.put(MLKEMParameters.ml_kem_512, NISTObjectIdentifiers.id_alg_ml_kem_512); + mlkemOids.put(MLKEMParameters.ml_kem_768, NISTObjectIdentifiers.id_alg_ml_kem_768); + mlkemOids.put(MLKEMParameters.ml_kem_1024,NISTObjectIdentifiers.id_alg_ml_kem_1024); - kyberParams.put(BCObjectIdentifiers.kyber512, KyberParameters.kyber512); - kyberParams.put(BCObjectIdentifiers.kyber768, KyberParameters.kyber768); - kyberParams.put(BCObjectIdentifiers.kyber1024, KyberParameters.kyber1024); - kyberParams.put(BCObjectIdentifiers.kyber512_aes, KyberParameters.kyber512_aes); - kyberParams.put(BCObjectIdentifiers.kyber768_aes, KyberParameters.kyber768_aes); - kyberParams.put(BCObjectIdentifiers.kyber1024_aes, KyberParameters.kyber1024_aes); + mlkemParams.put(NISTObjectIdentifiers.id_alg_ml_kem_512, MLKEMParameters.ml_kem_512); + mlkemParams.put(NISTObjectIdentifiers.id_alg_ml_kem_768, MLKEMParameters.ml_kem_768); + mlkemParams.put(NISTObjectIdentifiers.id_alg_ml_kem_1024, MLKEMParameters.ml_kem_1024); ntruprimeOids.put(NTRULPRimeParameters.ntrulpr653, BCObjectIdentifiers.ntrulpr653); ntruprimeOids.put(NTRULPRimeParameters.ntrulpr761, BCObjectIdentifiers.ntrulpr761); @@ -277,19 +264,27 @@ class Utils sntruprimeParams.put(BCObjectIdentifiers.sntrup1013, SNTRUPrimeParameters.sntrup1013); sntruprimeParams.put(BCObjectIdentifiers.sntrup1277, SNTRUPrimeParameters.sntrup1277); + mldsaOids.put(MLDSAParameters.ml_dsa_44, NISTObjectIdentifiers.id_ml_dsa_44); + mldsaOids.put(MLDSAParameters.ml_dsa_65, NISTObjectIdentifiers.id_ml_dsa_65); + mldsaOids.put(MLDSAParameters.ml_dsa_87, NISTObjectIdentifiers.id_ml_dsa_87); + mldsaOids.put(MLDSAParameters.ml_dsa_44_with_sha512, NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512); + mldsaOids.put(MLDSAParameters.ml_dsa_65_with_sha512, NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512); + mldsaOids.put(MLDSAParameters.ml_dsa_87_with_sha512, NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512); + + mldsaParams.put(NISTObjectIdentifiers.id_ml_dsa_44, MLDSAParameters.ml_dsa_44); + mldsaParams.put(NISTObjectIdentifiers.id_ml_dsa_65, MLDSAParameters.ml_dsa_65); + mldsaParams.put(NISTObjectIdentifiers.id_ml_dsa_87, MLDSAParameters.ml_dsa_87); + mldsaParams.put(NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512, MLDSAParameters.ml_dsa_44_with_sha512); + mldsaParams.put(NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512, MLDSAParameters.ml_dsa_65_with_sha512); + mldsaParams.put(NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512, MLDSAParameters.ml_dsa_87_with_sha512); + dilithiumOids.put(DilithiumParameters.dilithium2, BCObjectIdentifiers.dilithium2); dilithiumOids.put(DilithiumParameters.dilithium3, BCObjectIdentifiers.dilithium3); dilithiumOids.put(DilithiumParameters.dilithium5, BCObjectIdentifiers.dilithium5); - dilithiumOids.put(DilithiumParameters.dilithium2_aes, BCObjectIdentifiers.dilithium2_aes); - dilithiumOids.put(DilithiumParameters.dilithium3_aes, BCObjectIdentifiers.dilithium3_aes); - dilithiumOids.put(DilithiumParameters.dilithium5_aes, BCObjectIdentifiers.dilithium5_aes); dilithiumParams.put(BCObjectIdentifiers.dilithium2, DilithiumParameters.dilithium2); dilithiumParams.put(BCObjectIdentifiers.dilithium3, DilithiumParameters.dilithium3); dilithiumParams.put(BCObjectIdentifiers.dilithium5, DilithiumParameters.dilithium5); - dilithiumParams.put(BCObjectIdentifiers.dilithium2_aes, DilithiumParameters.dilithium2_aes); - dilithiumParams.put(BCObjectIdentifiers.dilithium3_aes, DilithiumParameters.dilithium3_aes); - dilithiumParams.put(BCObjectIdentifiers.dilithium5_aes, DilithiumParameters.dilithium5_aes); bikeParams.put(BCObjectIdentifiers.bike128, BIKEParameters.bike128); bikeParams.put(BCObjectIdentifiers.bike192, BIKEParameters.bike192); @@ -321,46 +316,169 @@ class Utils rainbowOids.put(RainbowParameters.rainbowVcircumzenithal, BCObjectIdentifiers.rainbow_V_circumzenithal); rainbowOids.put(RainbowParameters.rainbowVcompressed, BCObjectIdentifiers.rainbow_V_compressed); - sphincsPlusOids.put(SPHINCSPlusParameters.sha2_128s, BCObjectIdentifiers.sphincsPlus_sha2_128s_r3); - sphincsPlusOids.put(SPHINCSPlusParameters.sha2_128f, BCObjectIdentifiers.sphincsPlus_sha2_128f_r3); - sphincsPlusOids.put(SPHINCSPlusParameters.shake_128s, BCObjectIdentifiers.sphincsPlus_shake_128s_r3); - sphincsPlusOids.put(SPHINCSPlusParameters.shake_128f, BCObjectIdentifiers.sphincsPlus_shake_128f_r3); + shldsaOids.put(SLHDSAParameters.sha2_128s, NISTObjectIdentifiers.id_slh_dsa_sha2_128s); + shldsaOids.put(SLHDSAParameters.sha2_128f, NISTObjectIdentifiers.id_slh_dsa_sha2_128f); + shldsaOids.put(SLHDSAParameters.sha2_192s, NISTObjectIdentifiers.id_slh_dsa_sha2_192s); + shldsaOids.put(SLHDSAParameters.sha2_192f, NISTObjectIdentifiers.id_slh_dsa_sha2_192f); + shldsaOids.put(SLHDSAParameters.sha2_256s, NISTObjectIdentifiers.id_slh_dsa_sha2_256s); + shldsaOids.put(SLHDSAParameters.sha2_256f, NISTObjectIdentifiers.id_slh_dsa_sha2_256f); + shldsaOids.put(SLHDSAParameters.shake_128s, NISTObjectIdentifiers.id_slh_dsa_shake_128s); + shldsaOids.put(SLHDSAParameters.shake_128f, NISTObjectIdentifiers.id_slh_dsa_shake_128f); + shldsaOids.put(SLHDSAParameters.shake_192s, NISTObjectIdentifiers.id_slh_dsa_shake_192s); + shldsaOids.put(SLHDSAParameters.shake_192f, NISTObjectIdentifiers.id_slh_dsa_shake_192f); + shldsaOids.put(SLHDSAParameters.shake_256s, NISTObjectIdentifiers.id_slh_dsa_shake_256s); + shldsaOids.put(SLHDSAParameters.shake_256f, NISTObjectIdentifiers.id_slh_dsa_shake_256f); + + shldsaOids.put(SLHDSAParameters.sha2_128s_with_sha256, NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256); + shldsaOids.put(SLHDSAParameters.sha2_128f_with_sha256, NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256); + shldsaOids.put(SLHDSAParameters.sha2_192s_with_sha512, NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512); + shldsaOids.put(SLHDSAParameters.sha2_192f_with_sha512, NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512); + shldsaOids.put(SLHDSAParameters.sha2_256s_with_sha512, NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512); + shldsaOids.put(SLHDSAParameters.sha2_256f_with_sha512, NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512); + shldsaOids.put(SLHDSAParameters.shake_128s_with_shake128, NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128); + shldsaOids.put(SLHDSAParameters.shake_128f_with_shake128, NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128); + shldsaOids.put(SLHDSAParameters.shake_192s_with_shake256, NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256); + shldsaOids.put(SLHDSAParameters.shake_192f_with_shake256, NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256); + shldsaOids.put(SLHDSAParameters.shake_256s_with_shake256, NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256); + shldsaOids.put(SLHDSAParameters.shake_256f_with_shake256, NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256); + + shldsaParams.put(NISTObjectIdentifiers.id_slh_dsa_sha2_128s, SLHDSAParameters.sha2_128s); + shldsaParams.put(NISTObjectIdentifiers.id_slh_dsa_sha2_128f, SLHDSAParameters.sha2_128f); + shldsaParams.put(NISTObjectIdentifiers.id_slh_dsa_sha2_192s, SLHDSAParameters.sha2_192s); + shldsaParams.put(NISTObjectIdentifiers.id_slh_dsa_sha2_192f, SLHDSAParameters.sha2_192f); + shldsaParams.put(NISTObjectIdentifiers.id_slh_dsa_sha2_256s, SLHDSAParameters.sha2_256s); + shldsaParams.put(NISTObjectIdentifiers.id_slh_dsa_sha2_256f, SLHDSAParameters.sha2_256f); + shldsaParams.put(NISTObjectIdentifiers.id_slh_dsa_shake_128s, SLHDSAParameters.shake_128s); + shldsaParams.put(NISTObjectIdentifiers.id_slh_dsa_shake_128f, SLHDSAParameters.shake_128f); + shldsaParams.put(NISTObjectIdentifiers.id_slh_dsa_shake_192s, SLHDSAParameters.shake_192s); + shldsaParams.put(NISTObjectIdentifiers.id_slh_dsa_shake_192f, SLHDSAParameters.shake_192f); + shldsaParams.put(NISTObjectIdentifiers.id_slh_dsa_shake_256s, SLHDSAParameters.shake_256s); + shldsaParams.put(NISTObjectIdentifiers.id_slh_dsa_shake_256f, SLHDSAParameters.shake_256f); + + shldsaParams.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256, SLHDSAParameters.sha2_128s_with_sha256); + shldsaParams.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256, SLHDSAParameters.sha2_128f_with_sha256); + shldsaParams.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512, SLHDSAParameters.sha2_192s_with_sha512); + shldsaParams.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512, SLHDSAParameters.sha2_192f_with_sha512); + shldsaParams.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512, SLHDSAParameters.sha2_256s_with_sha512); + shldsaParams.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512, SLHDSAParameters.sha2_256f_with_sha512); + shldsaParams.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128, SLHDSAParameters.shake_128s_with_shake128); + shldsaParams.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128, SLHDSAParameters.shake_128f_with_shake128); + shldsaParams.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256, SLHDSAParameters.shake_192s_with_shake256); + shldsaParams.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256, SLHDSAParameters.shake_192f_with_shake256); + shldsaParams.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256, SLHDSAParameters.shake_256s_with_shake256); + shldsaParams.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256, SLHDSAParameters.shake_256f_with_shake256); + + sphincsPlusOids.put(SLHDSAParameters.sha2_128s, BCObjectIdentifiers.sphincsPlus_sha2_128s); + sphincsPlusOids.put(SLHDSAParameters.sha2_128f, BCObjectIdentifiers.sphincsPlus_sha2_128f); + sphincsPlusOids.put(SLHDSAParameters.sha2_192s, BCObjectIdentifiers.sphincsPlus_sha2_192s); + sphincsPlusOids.put(SLHDSAParameters.sha2_192f, BCObjectIdentifiers.sphincsPlus_sha2_192f); + sphincsPlusOids.put(SLHDSAParameters.sha2_256s, BCObjectIdentifiers.sphincsPlus_sha2_256s); + sphincsPlusOids.put(SLHDSAParameters.sha2_256f, BCObjectIdentifiers.sphincsPlus_sha2_256f); + sphincsPlusOids.put(SLHDSAParameters.shake_128s, BCObjectIdentifiers.sphincsPlus_shake_128s); + sphincsPlusOids.put(SLHDSAParameters.shake_128f, BCObjectIdentifiers.sphincsPlus_shake_128f); + sphincsPlusOids.put(SLHDSAParameters.shake_192s, BCObjectIdentifiers.sphincsPlus_shake_192s); + sphincsPlusOids.put(SLHDSAParameters.shake_192f, BCObjectIdentifiers.sphincsPlus_shake_192f); + sphincsPlusOids.put(SLHDSAParameters.shake_256s, BCObjectIdentifiers.sphincsPlus_shake_256s); + sphincsPlusOids.put(SLHDSAParameters.shake_256f, BCObjectIdentifiers.sphincsPlus_shake_256f); + + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_128s_robust, BCObjectIdentifiers.sphincsPlus_sha2_128s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_128f_robust, BCObjectIdentifiers.sphincsPlus_sha2_128f_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_128s_robust, BCObjectIdentifiers.sphincsPlus_shake_128s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_128f_robust, BCObjectIdentifiers.sphincsPlus_shake_128f_r3); sphincsPlusOids.put(SPHINCSPlusParameters.haraka_128s, BCObjectIdentifiers.sphincsPlus_haraka_128s_r3); sphincsPlusOids.put(SPHINCSPlusParameters.haraka_128f, BCObjectIdentifiers.sphincsPlus_haraka_128f_r3); - sphincsPlusOids.put(SPHINCSPlusParameters.sha2_192s, BCObjectIdentifiers.sphincsPlus_sha2_192s_r3); - sphincsPlusOids.put(SPHINCSPlusParameters.sha2_192f, BCObjectIdentifiers.sphincsPlus_sha2_192f_r3); - sphincsPlusOids.put(SPHINCSPlusParameters.shake_192s, BCObjectIdentifiers.sphincsPlus_shake_192s_r3); - sphincsPlusOids.put(SPHINCSPlusParameters.shake_192f, BCObjectIdentifiers.sphincsPlus_shake_192f_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_192s_robust, BCObjectIdentifiers.sphincsPlus_sha2_192s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_192f_robust, BCObjectIdentifiers.sphincsPlus_sha2_192f_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_192s_robust, BCObjectIdentifiers.sphincsPlus_shake_192s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_192f_robust, BCObjectIdentifiers.sphincsPlus_shake_192f_r3); sphincsPlusOids.put(SPHINCSPlusParameters.haraka_192s, BCObjectIdentifiers.sphincsPlus_haraka_192s_r3); sphincsPlusOids.put(SPHINCSPlusParameters.haraka_192f, BCObjectIdentifiers.sphincsPlus_haraka_192f_r3); - sphincsPlusOids.put(SPHINCSPlusParameters.sha2_256s, BCObjectIdentifiers.sphincsPlus_sha2_256s_r3); - sphincsPlusOids.put(SPHINCSPlusParameters.sha2_256f, BCObjectIdentifiers.sphincsPlus_sha2_256f_r3); - sphincsPlusOids.put(SPHINCSPlusParameters.shake_256s, BCObjectIdentifiers.sphincsPlus_shake_256s_r3); - sphincsPlusOids.put(SPHINCSPlusParameters.shake_256f, BCObjectIdentifiers.sphincsPlus_shake_256f_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_256s_robust, BCObjectIdentifiers.sphincsPlus_sha2_256s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_256f_robust, BCObjectIdentifiers.sphincsPlus_sha2_256f_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_256s_robust, BCObjectIdentifiers.sphincsPlus_shake_256s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_256f_robust, BCObjectIdentifiers.sphincsPlus_shake_256f_r3); sphincsPlusOids.put(SPHINCSPlusParameters.haraka_256s, BCObjectIdentifiers.sphincsPlus_haraka_256s_r3); sphincsPlusOids.put(SPHINCSPlusParameters.haraka_256f, BCObjectIdentifiers.sphincsPlus_haraka_256f_r3); - - sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, SPHINCSPlusParameters.sha2_128s); - sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, SPHINCSPlusParameters.sha2_128f); - sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, SPHINCSPlusParameters.shake_128s); - sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3, SPHINCSPlusParameters.shake_128f); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_128s_simple, BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_128f_simple, BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_192s_simple, BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_192f_simple, BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_256s_simple, BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_256f_simple, BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple); + + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_128s, BCObjectIdentifiers.sphincsPlus_sha2_128s); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_128f, BCObjectIdentifiers.sphincsPlus_sha2_128f); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_192s, BCObjectIdentifiers.sphincsPlus_sha2_192s); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_192f, BCObjectIdentifiers.sphincsPlus_sha2_192f); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_256s, BCObjectIdentifiers.sphincsPlus_sha2_256s); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_256f, BCObjectIdentifiers.sphincsPlus_sha2_256f); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_128s, BCObjectIdentifiers.sphincsPlus_shake_128s); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_128f, BCObjectIdentifiers.sphincsPlus_shake_128f); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_192s, BCObjectIdentifiers.sphincsPlus_shake_192s); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_192f, BCObjectIdentifiers.sphincsPlus_shake_192f); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_256s, BCObjectIdentifiers.sphincsPlus_shake_256s); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_256f, BCObjectIdentifiers.sphincsPlus_shake_256f); + + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128s, SPHINCSPlusParameters.sha2_128s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128f, SPHINCSPlusParameters.sha2_128f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128s, SPHINCSPlusParameters.shake_128s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128f, SPHINCSPlusParameters.shake_128f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192s, SPHINCSPlusParameters.sha2_192s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192f, SPHINCSPlusParameters.sha2_192f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192s, SPHINCSPlusParameters.shake_192s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192f, SPHINCSPlusParameters.shake_192f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256s, SPHINCSPlusParameters.sha2_256s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256f, SPHINCSPlusParameters.sha2_256f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256s, SPHINCSPlusParameters.shake_256s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256f, SPHINCSPlusParameters.shake_256f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, SPHINCSPlusParameters.sha2_128s_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, SPHINCSPlusParameters.sha2_128f_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, SPHINCSPlusParameters.shake_128s_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3, SPHINCSPlusParameters.shake_128f_robust); sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3, SPHINCSPlusParameters.haraka_128s); sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3, SPHINCSPlusParameters.haraka_128f); - sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, SPHINCSPlusParameters.sha2_192s); - sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, SPHINCSPlusParameters.sha2_192f); - sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3, SPHINCSPlusParameters.shake_192s); - sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3, SPHINCSPlusParameters.shake_192f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, SPHINCSPlusParameters.sha2_192s_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, SPHINCSPlusParameters.sha2_192f_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3, SPHINCSPlusParameters.shake_192s_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3, SPHINCSPlusParameters.shake_192f_robust); sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3, SPHINCSPlusParameters.haraka_192s); sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3, SPHINCSPlusParameters.haraka_192f); - sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, SPHINCSPlusParameters.sha2_256s); - sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, SPHINCSPlusParameters.sha2_256f); - sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3, SPHINCSPlusParameters.shake_256s); - sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, SPHINCSPlusParameters.shake_256f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, SPHINCSPlusParameters.sha2_256s_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, SPHINCSPlusParameters.sha2_256f_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3, SPHINCSPlusParameters.shake_256s_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, SPHINCSPlusParameters.shake_256f_robust); sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, SPHINCSPlusParameters.haraka_256s); sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, SPHINCSPlusParameters.haraka_256f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, SPHINCSPlusParameters.sha2_128s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, SPHINCSPlusParameters.sha2_128f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, SPHINCSPlusParameters.shake_128s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, SPHINCSPlusParameters.shake_128f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple, SPHINCSPlusParameters.haraka_128s_simple); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple, SPHINCSPlusParameters.haraka_128f_simple); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, SPHINCSPlusParameters.sha2_192s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, SPHINCSPlusParameters.sha2_192f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, SPHINCSPlusParameters.shake_192s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, SPHINCSPlusParameters.shake_192f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple, SPHINCSPlusParameters.haraka_192s_simple); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple, SPHINCSPlusParameters.haraka_192f_simple); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, SPHINCSPlusParameters.sha2_256s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, SPHINCSPlusParameters.sha2_256f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, SPHINCSPlusParameters.shake_256s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, SPHINCSPlusParameters.shake_256f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple, SPHINCSPlusParameters.haraka_256s_simple); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple, SPHINCSPlusParameters.haraka_256f_simple); + } + static ASN1ObjectIdentifier slhdsaOidLookup(SLHDSAParameters params) + { + return (ASN1ObjectIdentifier)shldsaOids.get(params); } + static SLHDSAParameters slhdsaParamsLookup(ASN1ObjectIdentifier oid) + { + return (SLHDSAParameters)shldsaParams.get(oid); + } + static int qTeslaLookupSecurityCategory(AlgorithmIdentifier algorithm) { return ((Integer)categories.get(algorithm.getAlgorithm())).intValue(); @@ -515,6 +633,7 @@ static ASN1ObjectIdentifier sphincsPlusOidLookup(SPHINCSPlusParameters params) { return (ASN1ObjectIdentifier)sphincsPlusOids.get(params); } + static SPHINCSPlusParameters sphincsPlusParamsLookup(ASN1ObjectIdentifier oid) { return (SPHINCSPlusParameters)sphincsPlusParams.get(oid); @@ -560,16 +679,6 @@ static PicnicParameters picnicParamsLookup(ASN1ObjectIdentifier oid) return (PicnicParameters)picnicParams.get(oid); } - static ASN1ObjectIdentifier sikeOidLookup(SIKEParameters params) - { - return (ASN1ObjectIdentifier)sikeOids.get(params); - } - - static SIKEParameters sikeParamsLookup(ASN1ObjectIdentifier oid) - { - return (SIKEParameters)sikeParams.get(oid); - } - static ASN1ObjectIdentifier falconOidLookup(FalconParameters params) { return (ASN1ObjectIdentifier)falconOids.get(params); @@ -590,14 +699,14 @@ static NTRUParameters ntruParamsLookup(ASN1ObjectIdentifier oid) return (NTRUParameters)ntruParams.get(oid); } - static ASN1ObjectIdentifier kyberOidLookup(KyberParameters params) + static ASN1ObjectIdentifier mlkemOidLookup(MLKEMParameters params) { - return (ASN1ObjectIdentifier)kyberOids.get(params); + return (ASN1ObjectIdentifier)mlkemOids.get(params); } - static KyberParameters kyberParamsLookup(ASN1ObjectIdentifier oid) + static MLKEMParameters mlkemParamsLookup(ASN1ObjectIdentifier oid) { - return (KyberParameters)kyberParams.get(oid); + return (MLKEMParameters)mlkemParams.get(oid); } static ASN1ObjectIdentifier ntrulprimeOidLookup(NTRULPRimeParameters params) @@ -620,6 +729,16 @@ static SNTRUPrimeParameters sntruprimeParamsLookup(ASN1ObjectIdentifier oid) return (SNTRUPrimeParameters)sntruprimeParams.get(oid); } + static ASN1ObjectIdentifier mldsaOidLookup(MLDSAParameters params) + { + return (ASN1ObjectIdentifier)mldsaOids.get(params); + } + + static MLDSAParameters mldsaParamsLookup(ASN1ObjectIdentifier oid) + { + return (MLDSAParameters)mldsaParams.get(oid); + } + static ASN1ObjectIdentifier dilithiumOidLookup(DilithiumParameters params) { return (ASN1ObjectIdentifier)dilithiumOids.get(params); @@ -639,7 +758,7 @@ static BIKEParameters bikeParamsLookup(ASN1ObjectIdentifier oid) { return (BIKEParameters)bikeParams.get(oid); } - + static ASN1ObjectIdentifier hqcOidLookup(HQCParameters params) { return (ASN1ObjectIdentifier)hqcOids.get(params); diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/xmss/DigestUtil.java b/core/src/main/java/org/bouncycastle/pqc/crypto/xmss/DigestUtil.java index c15acdcbae..8ea5c17655 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/xmss/DigestUtil.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/xmss/DigestUtil.java @@ -6,7 +6,6 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Xof; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.digests.SHAKEDigest; @@ -72,14 +71,4 @@ static ASN1ObjectIdentifier getDigestOID(String name) throw new IllegalArgumentException("unrecognized digest name: " + name); } - - public static int getDigestSize(Digest digest) - { - if (digest instanceof Xof) - { - return digest.getDigestSize() * 2; - } - - return digest.getDigestSize(); - } } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKEMExtractor.java b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKEMExtractor.java new file mode 100644 index 0000000000..cbc815f22d --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKEMExtractor.java @@ -0,0 +1,62 @@ +package org.bouncycastle.pqc.crypto.xwing; + +import org.bouncycastle.crypto.EncapsulatedSecretExtractor; +import org.bouncycastle.crypto.agreement.X25519Agreement; +import org.bouncycastle.crypto.digests.SHA3Digest; +import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; +import org.bouncycastle.crypto.params.X25519PublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; + +public class XWingKEMExtractor + implements EncapsulatedSecretExtractor +{ + private final XWingPrivateKeyParameters key; + private final MLKEMExtractor kemExtractor; + + public XWingKEMExtractor(XWingPrivateKeyParameters privParams) + { + this.key = privParams; + this.kemExtractor = new MLKEMExtractor((MLKEMPrivateKeyParameters)key.getKyberPrivateKey()); + } + + @Override + public byte[] extractSecret(byte[] encapsulation) + { + // Decryption + byte[] kybSecret = kemExtractor.extractSecret(Arrays.copyOfRange(encapsulation, 0, encapsulation.length - X25519PublicKeyParameters.KEY_SIZE)); + X25519Agreement xdhAgree = new X25519Agreement(); + + byte[] k = new byte[kybSecret.length + xdhAgree.getAgreementSize()]; + + System.arraycopy(kybSecret, 0, k, 0, kybSecret.length); + + Arrays.clear(kybSecret); + + xdhAgree.init(key.getXDHPrivateKey()); + + X25519PublicKeyParameters ephXdhPub = new X25519PublicKeyParameters(Arrays.copyOfRange(encapsulation, encapsulation.length - X25519PublicKeyParameters.KEY_SIZE, encapsulation.length)); + + xdhAgree.calculateAgreement(ephXdhPub, k, kybSecret.length); + + SHA3Digest sha3 = new SHA3Digest(256); + + sha3.update(Strings.toByteArray("\\.//^\\"), 0, 6); + sha3.update(k, 0, k.length); + sha3.update(ephXdhPub.getEncoded(), 0, X25519PublicKeyParameters.KEY_SIZE); + sha3.update(((X25519PrivateKeyParameters)key.getXDHPrivateKey()).generatePublicKey().getEncoded(), 0, X25519PublicKeyParameters.KEY_SIZE); + + byte[] kemSecret = new byte[32]; + + sha3.doFinal(kemSecret, 0); + + return kemSecret; + } + + public int getEncapsulationLength() + { + return kemExtractor.getEncapsulationLength() + X25519PublicKeyParameters.KEY_SIZE; + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKEMGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKEMGenerator.java new file mode 100644 index 0000000000..fe32917fb7 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKEMGenerator.java @@ -0,0 +1,70 @@ +package org.bouncycastle.pqc.crypto.xwing; + +import java.security.SecureRandom; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.EncapsulatedSecretGenerator; +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.crypto.agreement.X25519Agreement; +import org.bouncycastle.crypto.digests.SHA3Digest; +import org.bouncycastle.crypto.generators.X25519KeyPairGenerator; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.params.X25519KeyGenerationParameters; +import org.bouncycastle.crypto.params.X25519PublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator; +import org.bouncycastle.pqc.crypto.util.SecretWithEncapsulationImpl; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; + +public class XWingKEMGenerator + implements EncapsulatedSecretGenerator +{ + // the source of randomness + private final SecureRandom sr; + + public XWingKEMGenerator(SecureRandom random) + { + this.sr = random; + } + + public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey) + { + XWingPublicKeyParameters key = (XWingPublicKeyParameters)recipientKey; + + MLKEMGenerator kybKem = new MLKEMGenerator(sr); + + SecretWithEncapsulation kybSecWithEnc = kybKem.generateEncapsulated(key.getKyberPublicKey()); + X25519Agreement xdhAgree = new X25519Agreement(); + byte[] kybSecret = kybSecWithEnc.getSecret(); + byte[] k = new byte[kybSecret.length + xdhAgree.getAgreementSize()]; + + System.arraycopy(kybSecret, 0, k, 0, kybSecret.length); + + Arrays.clear(kybSecret); + + X25519KeyPairGenerator xdhGen = new X25519KeyPairGenerator(); + + xdhGen.init(new X25519KeyGenerationParameters(sr)); + + AsymmetricCipherKeyPair ephXdh = xdhGen.generateKeyPair(); + + xdhAgree.init(ephXdh.getPrivate()); + + xdhAgree.calculateAgreement(key.getXDHPublicKey(), k, kybSecret.length); + + X25519PublicKeyParameters ephXdhPub = (X25519PublicKeyParameters)ephXdh.getPublic(); + + SHA3Digest sha3 = new SHA3Digest(256); + + sha3.update(Strings.toByteArray("\\.//^\\"), 0, 6); + sha3.update(k, 0, k.length); + sha3.update(ephXdhPub.getEncoded(), 0, X25519PublicKeyParameters.KEY_SIZE); + sha3.update(((X25519PublicKeyParameters)key.getXDHPublicKey()).getEncoded(), 0, X25519PublicKeyParameters.KEY_SIZE); + + byte[] kemSecret = new byte[32]; + + sha3.doFinal(kemSecret, 0); + + return new SecretWithEncapsulationImpl(kemSecret, Arrays.concatenate(kybSecWithEnc.getEncapsulation(), ephXdhPub.getEncoded())); + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKeyGenerationParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKeyGenerationParameters.java new file mode 100644 index 0000000000..1b93d6f280 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKeyGenerationParameters.java @@ -0,0 +1,14 @@ +package org.bouncycastle.pqc.crypto.xwing; + +import java.security.SecureRandom; + +import org.bouncycastle.crypto.KeyGenerationParameters; + +public class XWingKeyGenerationParameters + extends KeyGenerationParameters +{ + public XWingKeyGenerationParameters(SecureRandom random) + { + super(random, 128); + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKeyPairGenerator.java new file mode 100644 index 0000000000..f7691d0125 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKeyPairGenerator.java @@ -0,0 +1,53 @@ +package org.bouncycastle.pqc.crypto.xwing; + +import java.security.SecureRandom; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; +import org.bouncycastle.crypto.KeyGenerationParameters; +import org.bouncycastle.crypto.generators.X25519KeyPairGenerator; +import org.bouncycastle.crypto.params.X25519KeyGenerationParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyPairGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; + +public class XWingKeyPairGenerator + implements AsymmetricCipherKeyPairGenerator +{ + private SecureRandom random; + + private void initialize( + KeyGenerationParameters param) + { + this.random = param.getRandom(); + } + + private AsymmetricCipherKeyPair genKeyPair() + { + MLKEMKeyPairGenerator kyberKeyGen = new MLKEMKeyPairGenerator(); + + kyberKeyGen.init(new MLKEMKeyGenerationParameters(random, MLKEMParameters.ml_kem_768)); + + X25519KeyPairGenerator x25519KeyGen = new X25519KeyPairGenerator(); + + x25519KeyGen.init(new X25519KeyGenerationParameters(random)); + + AsymmetricCipherKeyPair kybKp = kyberKeyGen.generateKeyPair(); + AsymmetricCipherKeyPair xdhKp = x25519KeyGen.generateKeyPair(); + + return new AsymmetricCipherKeyPair( + new XWingPublicKeyParameters(kybKp.getPublic(), xdhKp.getPublic()), + new XWingPrivateKeyParameters(kybKp.getPrivate(), xdhKp.getPrivate())); + } + + public void init(KeyGenerationParameters param) + { + this.initialize(param); + } + + public AsymmetricCipherKeyPair generateKeyPair() + { + return genKeyPair(); + } + +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKeyParameters.java new file mode 100644 index 0000000000..7aca1c0fd4 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingKeyParameters.java @@ -0,0 +1,13 @@ +package org.bouncycastle.pqc.crypto.xwing; + +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; + +public class XWingKeyParameters + extends AsymmetricKeyParameter +{ + XWingKeyParameters( + boolean isPrivate) + { + super(isPrivate); + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingPrivateKeyParameters.java new file mode 100644 index 0000000000..5558f76120 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingPrivateKeyParameters.java @@ -0,0 +1,45 @@ +package org.bouncycastle.pqc.crypto.xwing; + +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; +import org.bouncycastle.util.Arrays; + +public class XWingPrivateKeyParameters + extends XWingKeyParameters +{ + private final MLKEMPrivateKeyParameters kybPriv; + private final X25519PrivateKeyParameters xdhPriv; + + XWingPrivateKeyParameters(AsymmetricKeyParameter kybPriv, AsymmetricKeyParameter xdhPriv) + { + super(true); + + this.kybPriv = (MLKEMPrivateKeyParameters)kybPriv; + this.xdhPriv = (X25519PrivateKeyParameters)xdhPriv; + } + + public XWingPrivateKeyParameters(byte[] encoding) + { + super(false); + + this.kybPriv = new MLKEMPrivateKeyParameters(MLKEMParameters.ml_kem_768, Arrays.copyOfRange(encoding, 0, encoding.length - X25519PrivateKeyParameters.KEY_SIZE)); + this.xdhPriv = new X25519PrivateKeyParameters(encoding, encoding.length - X25519PrivateKeyParameters.KEY_SIZE); + } + + MLKEMPrivateKeyParameters getKyberPrivateKey() + { + return kybPriv; + } + + X25519PrivateKeyParameters getXDHPrivateKey() + { + return xdhPriv; + } + + public byte[] getEncoded() + { + return Arrays.concatenate(kybPriv.getEncoded(), xdhPriv.getEncoded()); + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingPublicKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingPublicKeyParameters.java new file mode 100644 index 0000000000..d1894564a6 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/xwing/XWingPublicKeyParameters.java @@ -0,0 +1,45 @@ +package org.bouncycastle.pqc.crypto.xwing; + +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.params.X25519PublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; +import org.bouncycastle.util.Arrays; + +public class XWingPublicKeyParameters + extends XWingKeyParameters +{ + private final MLKEMPublicKeyParameters kybPub; + private final X25519PublicKeyParameters xdhPub; + + XWingPublicKeyParameters(AsymmetricKeyParameter kybPub, AsymmetricKeyParameter xdhPub) + { + super(false); + + this.kybPub = (MLKEMPublicKeyParameters)kybPub; + this.xdhPub = (X25519PublicKeyParameters)xdhPub; + } + + public XWingPublicKeyParameters(byte[] encoding) + { + super(false); + + this.kybPub = new MLKEMPublicKeyParameters(MLKEMParameters.ml_kem_768, Arrays.copyOfRange(encoding, 0, encoding.length - X25519PublicKeyParameters.KEY_SIZE)); + this.xdhPub = new X25519PublicKeyParameters(encoding, encoding.length - X25519PublicKeyParameters.KEY_SIZE); + } + + MLKEMPublicKeyParameters getKyberPublicKey() + { + return kybPub; + } + + X25519PublicKeyParameters getXDHPublicKey() + { + return xdhPub; + } + + public byte[] getEncoded() + { + return Arrays.concatenate(kybPub.getEncoded(), xdhPub.getEncoded()); + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/ntru/NTRUEngine.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/ntru/NTRUEngine.java index 794281c911..79f6769c93 100644 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/ntru/NTRUEngine.java +++ b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/ntru/NTRUEngine.java @@ -41,27 +41,28 @@ public NTRUEngine() public void init(boolean forEncryption, CipherParameters parameters) { this.forEncryption = forEncryption; - if (forEncryption) - { - if (parameters instanceof ParametersWithRandom) - { - ParametersWithRandom p = (ParametersWithRandom)parameters; - this.random = p.getRandom(); - this.pubKey = (NTRUEncryptionPublicKeyParameters)p.getParameters(); - } - else - { - this.random = CryptoServicesRegistrar.getSecureRandom(); - this.pubKey = (NTRUEncryptionPublicKeyParameters)parameters; - } + SecureRandom providedRandom = null; + if (parameters instanceof ParametersWithRandom) + { + ParametersWithRandom withRandom = (ParametersWithRandom)parameters; + providedRandom = withRandom.getRandom(); + parameters = withRandom.getParameters(); + } + if (forEncryption) + { + this.pubKey = (NTRUEncryptionPublicKeyParameters)parameters; + this.privKey = null; this.params = pubKey.getParameters(); + this.random = CryptoServicesRegistrar.getSecureRandom(providedRandom); } else { + this.pubKey = null; this.privKey = (NTRUEncryptionPrivateKeyParameters)parameters; this.params = privKey.getParameters(); + this.random = null; } } diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/rainbow/util/ComputeInField.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/rainbow/util/ComputeInField.java index b4210d6172..181a6c4967 100644 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/rainbow/util/ComputeInField.java +++ b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/rainbow/util/ComputeInField.java @@ -46,7 +46,7 @@ public short[] solveEquation(short[][] B, short[] b) { - /** initialize **/ + // initialize // this matrix stores B and b from the equation B*x = b // b is stored as the last column. // B contains one column more than rows. @@ -55,7 +55,7 @@ public short[] solveEquation(short[][] B, short[] b) // stores the solution of the LES x = new short[B.length]; - /** copy B into the global matrix A **/ + // copy B into the global matrix A for (int i = 0; i < B.length; i++) { // rows for (int j = 0; j < B[0].length; j++) @@ -64,7 +64,7 @@ public short[] solveEquation(short[][] B, short[] b) } } - /** copy the vector b into the global A **/ + // copy the vector b into the global A //the free coefficient, stored in the last column of A( A[i][b.length] // is to be subtracted from b for (int i = 0; i < b.length; i++) @@ -72,7 +72,7 @@ public short[] solveEquation(short[][] B, short[] b) A[i][b.length] = GF2Field.addElem(b[i], A[i][b.length]); } - /** call the methods for gauss elimination and backward substitution **/ + // call the methods for gauss elimination and backward substitution computeZerosUnder(false); // obtain zeros under the diagonal substitute(); @@ -100,7 +100,7 @@ public short[][] inverse(short[][] coef) { try { - /** Initialization: **/ + // Initialization: short factor; short[][] inverse; A = new short[coef.length][2 * coef.length]; @@ -110,7 +110,7 @@ public short[][] inverse(short[][] coef) "The matrix is not invertible. Please choose another one!"); } - /** prepare: Copy coef and the identity matrix into the global A. **/ + // prepare: Copy coef and the identity matrix into the global A. for (int i = 0; i < coef.length; i++) { for (int j = 0; j < coef.length; j++) @@ -126,7 +126,7 @@ public short[][] inverse(short[][] coef) A[i][i + A.length] = 1; } - /** Elimination operations to get the identity matrix from the left side of A. **/ + // Elimination operations to get the identity matrix from the left side of A. // modify A to get 0s under the diagonal. computeZerosUnder(true); @@ -290,7 +290,7 @@ private void substitute() throw new IllegalStateException("The equation system is not solvable"); } - /** backward substitution **/ + // backward substitution x[A.length - 1] = GF2Field.multElem(A[A.length - 1][A.length], temp); for (int i = A.length - 2; i >= 0; i--) { diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/Fpx.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/Fpx.java deleted file mode 100644 index 992db0f99f..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/Fpx.java +++ /dev/null @@ -1,2197 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import org.bouncycastle.util.Pack; - -class Fpx -{ - private SIKEEngine engine; - Fpx(SIKEEngine engine) - { - this.engine = engine; - } - - // Multiprecision left shift by one. - private void mp_shiftl1(long[] x, int nwords) - { - int i; - for (i = nwords-1; i > 0; i--) - { - //SHIFTL - x[i] = (x[i] << 1) ^ (x[i-1] >>> (Internal.RADIX - 1)); - } - x[0] <<= 1; - } - - // Cyclotomic squaring on elements of norm 1, using a^(p+1) = 1. - protected void sqr_Fp2_cycl(long[][] a, long[] one) - { - long[] t0 = new long[engine.params.NWORDS_FIELD]; - - fpaddPRIME(a[0], a[1], t0); // t0 = a0 + a1 - fpsqr_mont(t0, t0); // t0 = t0^2 - fpsubPRIME(t0, one, a[1]); // a1 = t0 - 1 - fpsqr_mont(a[0], t0); // t0 = a0^2 - fpaddPRIME(t0, t0, t0); // t0 = t0 + t0 - fpsubPRIME(t0, one, a[0]); // a0 = t0 - 1 - } - - // n-way simultaneous inversion using Montgomery's trick. - // SECURITY NOTE: This function does not run in constant time. - // Also, vec and out CANNOT be the same variable! - protected void mont_n_way_inv(long[][][] vec, int n, long[][][] out) - { - long[][] t1 = new long[2][engine.params.NWORDS_FIELD]; - int i; - - fp2copy(vec[0], out[0]); // out[0] = vec[0] - for (i = 1; i < n; i++) - { - fp2mul_mont(out[i-1], vec[i], out[i]); // out[i] = out[i-1]*vec[i] - } - - fp2copy(out[n-1], t1); // t1 = 1/out[n-1] - fp2inv_mont_bingcd(t1); - - for (i = n-1; i >= 1; i--) - { - fp2mul_mont(out[i-1], t1, out[i]); // out[i] = t1*out[i-1] - fp2mul_mont(t1, vec[i], t1); // t1 = t1*vec[i] - } - fp2copy(t1, out[0]); // out[0] = t1 - } - - - // Copy a field element, c = a. - protected void fpcopy(long[] a, int aOffset, long[] c) - { - int i; - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - c[i] = a[i + aOffset]; - } - } - - // GF(p^2) addition without correction, c = a+b in GF(p^2). - protected void mp2_add(long[][] a, long[][] b, long[][] c) - { - mp_add(a[0], b[0], c[0], engine.params.NWORDS_FIELD); - mp_add(a[1], b[1], c[1], engine.params.NWORDS_FIELD); - } - - // Modular correction, a = a in GF(p^2). - protected void fp2correction(long[][] a) - { - fpcorrectionPRIME(a[0]); - fpcorrectionPRIME(a[1]); - } - - // Multiprecision addition, c = a+b, where lng(a) = lng(b) = nwords. Returns the carry bit. - protected int mp_add(long[] a, long[] b, long[] c, int nwords) - { - int i, carry = 0; - - for (i = 0; i < nwords; i++) - { - //ADDC - long tempReg = a[i] + carry; - c[i] = b[i] + tempReg; - carry = (is_digit_lessthan_ct(tempReg, carry) | is_digit_lessthan_ct(c[i], tempReg)); - } - return carry; - } - - // Multiprecision addition, c = a+b, where lng(a) = lng(b) = nwords. Returns the carry bit. - private int mp_add(long[] a, int aOffset, long[] b, long[] c, int cOffset, int nwords) - { - int i, carry = 0; - - for (i = 0; i < nwords; i++) - { - //ADDC - long tempReg = a[i + aOffset] + carry; - c[i + cOffset] = b[i] + tempReg; - carry = (is_digit_lessthan_ct(tempReg, carry) | is_digit_lessthan_ct(c[i + cOffset], tempReg)); - } - return carry; - } - - // Multiprecision addition, c = a+b, where lng(a) = lng(b) = nwords. Returns the carry bit. - private int mp_add(long[] a, int aOffset, long[] b, int bOffset, long[] c, int cOffset, int nwords) - { - int i, carry = 0; - - for (i = 0; i < nwords; i++) - { - //ADDC - long tempReg = a[i + aOffset] + carry; - c[i + cOffset] = b[i + bOffset] + tempReg; - carry = (is_digit_lessthan_ct(tempReg, carry) | is_digit_lessthan_ct(c[i + cOffset], tempReg)); - } - return carry; - } - - // Is x < y? - private int is_digit_lessthan_ct(long x, long y) - { - return (int) ((x ^ ((x ^ y) | ((x - y) ^ y))) >>> (Internal.RADIX -1)); - } - - // Is x != 0? - private int is_digit_nonzero_ct(long x) - { - return (int)((x | (0-x)) >>> (Internal.RADIX -1)); - } - // Is x = 0? - private int is_digit_zero_ct(long x) - { - return (1 ^ is_digit_nonzero_ct(x)); - } - - void fp2neg(long[][] a) - { // GF(p^2) negation, a = -a in GF(p^2). - fpnegPRIME(a[0]); - fpnegPRIME(a[1]); - } - - // Is x = 0? return 1 (TRUE) if condition is true, 0 (FALSE) otherwise. - // SECURITY NOTE: This function does not run in constant-time. - protected boolean is_felm_zero(long[] x) - { - int i; - - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - if (x[i] != 0) - return false; - } - return true; - } - - // Is x < y? return 1 (TRUE) if condition is true, 0 (FALSE) otherwise. - // SECURITY NOTE: This function does not run in constant-time. - private boolean is_felm_lt(long[] x, long[] y) - { - for (int i = engine.params.NWORDS_FIELD-1; i >= 0; i--) - { - if (x[i] + Long.MIN_VALUE < y[i] + Long.MIN_VALUE) - { - return true; - } - else if (x[i] + Long.MIN_VALUE > y[i] + Long.MIN_VALUE ) - { - return false; - } - } - return false; - } - - // Is x even? return 1 (TRUE) if condition is true, 0 (FALSE) otherwise. - private static boolean is_felm_even(long[] x) - { - return (x[0] & 1L) == 0L; - } - - // Test if a is a square in GF(p^2) and return 1 if true, 0 otherwise - // If a is a quadratic residue, s will be assigned with a partially computed square root of a - protected boolean is_sqr_fp2(long[][] a, long[] s) - { - int i; - long[] a0 = new long[engine.params.NWORDS_FIELD], - a1 = new long[engine.params.NWORDS_FIELD], - z = new long[engine.params.NWORDS_FIELD], - temp = new long[engine.params.NWORDS_FIELD]; - - fpsqr_mont(a[0],a0); - fpsqr_mont(a[1],a1); - fpaddPRIME(a0,a1,z); - - fpcopy(z, 0,s); - for (i = 0; i < engine.params.OALICE_BITS - 2; i++) - { - fpsqr_mont(s, s); - } - for (i = 0; i < engine.params.OBOB_EXPON; i++) - { - fpsqr_mont(s, temp); - fpmul_mont(s, temp, s); - } - fpsqr_mont(s,temp); // s = z^((p+1)/4) - fpcorrectionPRIME(temp); - fpcorrectionPRIME(z); - if (!subarrayEquals(temp, z, engine.params.NWORDS_FIELD)) // s^2 !=? z - { - return false; - } - - return true; - } - - // Partial Montgomery inversion via the binary GCD algorithm. - private void fpinv_mont_bingcd_partial(long[] a, long[] x1, int[] k) - { - long[] u = new long[engine.params.NWORDS_FIELD], - v = new long[engine.params.NWORDS_FIELD], - x2 = new long[engine.params.NWORDS_FIELD]; - - int cwords; // Number of words necessary for x1, x2 - - fpcopy(a, 0, u); - fpcopy(engine.params.PRIME, 0, v); - fpzero(x1); x1[0] = 1; - fpzero(x2); - k[0] = 0; - - while (!is_felm_zero(v)) - { - cwords = ((k[0] + 1) / Internal.RADIX) + 1; - if ((cwords < engine.params.NWORDS_FIELD)) - { - if (is_felm_even(v)) - { - mp_shiftr1(v); - mp_shiftl1(x1, cwords); - } - else if (is_felm_even(u)) - { - mp_shiftr1(u); - mp_shiftl1(x2, cwords); - } - else if (!is_felm_lt(v, u)) - { - mp_sub(v, u, v, engine.params.NWORDS_FIELD); - mp_shiftr1(v); - mp_add(x1, x2, x2, cwords); - mp_shiftl1(x1, cwords); - } - else - { - mp_sub(u, v, u, engine.params.NWORDS_FIELD); - mp_shiftr1(u); - mp_add(x1, x2, x1, cwords); - mp_shiftl1(x2, cwords); - } - } - else - { - if (is_felm_even(v)) - { - mp_shiftr1(v); - mp_shiftl1(x1, engine.params.NWORDS_FIELD); - } - else if (is_felm_even(u)) - { - mp_shiftr1(u); - mp_shiftl1(x2, engine.params.NWORDS_FIELD); - } - else if (!is_felm_lt(v, u)) - { - mp_sub(v, u, v, engine.params.NWORDS_FIELD); - mp_shiftr1(v); - mp_add(x1, x2, x2, engine.params.NWORDS_FIELD); - mp_shiftl1(x1, engine.params.NWORDS_FIELD); - } - else - { - mp_sub(u, v, u, engine.params.NWORDS_FIELD); - mp_shiftr1(u); - mp_add(x1, x2, x1, engine.params.NWORDS_FIELD); - mp_shiftl1(x2, engine.params.NWORDS_FIELD); - } - } - k[0] += 1; - } - - if (is_felm_lt(engine.params.PRIME, x1)) - { - mp_sub(x1, engine.params.PRIME, x1, engine.params.NWORDS_FIELD); - } - } - - // Set up the value 2^mark. - private void power2_setup(long[] x, int mark, int nwords) - { - int i; - - for (i = 0; i < nwords; i++) x[i] = 0; - - i = 0; - while (mark >= 0) - { - if (mark < Internal.RADIX) - { - x[i] = (long)1 << mark; - } - mark -= Internal.RADIX; - i += 1; - } - } - - - // Field inversion via the binary GCD using Montgomery arithmetic, a = a^-1*r' mod p. - // SECURITY NOTE: This function does not run in constant-time and is therefore only suitable for - // operations not involving any secret data. - private void fpinv_mont_bingcd(long[] a) - { - long[] x = new long[engine.params.NWORDS_FIELD], - t = new long[engine.params.NWORDS_FIELD]; - int[] k = new int[1]; - - if (is_felm_zero(a)) - return; - - fpinv_mont_bingcd_partial(a, x, k); - if (k[0] <= engine.params.MAXBITS_FIELD) - { - fpmul_mont(x, engine.params.Montgomery_R2, x); - k[0] += engine.params.MAXBITS_FIELD; - } - fpmul_mont(x, engine.params.Montgomery_R2, x); - power2_setup(t, 2*engine.params.MAXBITS_FIELD - k[0], engine.params.NWORDS_FIELD); - fpmul_mont(x, t, a); - } - - // GF(p^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2) - // This uses the binary GCD for inversion in fp and is NOT constant time!!! - protected void fp2inv_mont_bingcd(long[][] a) - { - long[][] t1 = new long[2][engine.params.NWORDS_FIELD]; - - fpsqr_mont(a[0], t1[0]); // t10 = a0^2 - fpsqr_mont(a[1], t1[1]); // t11 = a1^2 - fpaddPRIME(t1[0], t1[1], t1[0]); // t10 = a0^2+a1^2 - - - fpinv_mont_bingcd(t1[0]); // t10 = (a0^2+a1^2)^-1 - fpnegPRIME(a[1]); // a = a0-i*a1 - fpmul_mont(a[0], t1[0], a[0]); - fpmul_mont(a[1], t1[0], a[1]); // a = (a0-i*a1)*(a0^2+a1^2)^-1 - } - - // GF(p^2) division by two, c = a/2 in GF(p^2). - protected void fp2div2(long[][] a, long[][] c) - { - fpdiv2_PRIME(a[0], c[0]); - fpdiv2_PRIME(a[1], c[1]); - } - - // Modular division by two, c = a/2 mod PRIME. - // Input : a in [0, 2*PRIME-1] - // Output: c in [0, 2*PRIME-1] - private void fpdiv2_PRIME(long[] a, long[] c) - { - int i, carry = 0; - long mask; - - mask = 0 - (a[0] & 1); // If a is odd compute a+PRIME - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //ADDC - long tempReg = a[i] + carry; - c[i] = (engine.params.PRIME[i] & mask) + tempReg; - carry = (is_digit_lessthan_ct(tempReg, carry) | is_digit_lessthan_ct(c[i], tempReg)); - } - - mp_shiftr1(c); - } - - // Multiprecision subtraction with correction with 2*p, c = a-b+2p. - private void mp_subPRIME_p2(long [] a, long[] b, long[] c) - { - int i, borrow = 0; - - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //SUBC - long tempReg = a[i] - b[i]; - int borrowReg = (is_digit_lessthan_ct(a[i], b[i]) | (borrow & is_digit_zero_ct(tempReg))); - c[i] = tempReg - (long)(borrow); - borrow = borrowReg; - } - - borrow = 0; - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //ADDC - long tempReg = c[i] + borrow; - c[i] = engine.params.PRIMEx2[i] + tempReg; - borrow = (is_digit_lessthan_ct(tempReg, borrow) | is_digit_lessthan_ct(c[i], tempReg)); - } - } - - // Multiprecision subtraction with correction with 4*p, c = a-b+4p. - private void mp_subPRIME_p4(long[] a, long[] b, long[] c) - { - int i, borrow = 0; - - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //SUBC - long tempReg = a[i] - b[i]; - int borrowReg = (is_digit_lessthan_ct(a[i], b[i]) | (borrow & is_digit_zero_ct(tempReg))); - c[i] = tempReg - (long)(borrow); - borrow = borrowReg; - - } - - borrow = 0; - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //ADDC - long tempReg = c[i] + borrow; - c[i] = engine.params.PRIMEx4[i] + tempReg; - borrow = (is_digit_lessthan_ct(tempReg, borrow) | is_digit_lessthan_ct(c[i], tempReg)); - - } - } - - // Digit multiplication, digit * digit -> 2-digit result - private void digit_x_digit(long a, long b, long[] c) - { - long al, ah, bl, bh, temp; - long albl, albh, ahbl, ahbh, res1, res2, res3, carry; - long mask_low = ((long)(-1)) >>> (8*4), mask_high = ((-1L)) << (8*4); - - al = a & mask_low; // Low part - ah = a >>> (8 * 4); // High part - bl = b & mask_low; - bh = b >>> (8 * 4); - - albl = al*bl; - albh = al*bh; - ahbl = ah*bl; - ahbh = ah*bh; - c[0] = albl & mask_low; // C00 - - res1 = albl >>> (8 * 4); - res2 = ahbl & mask_low; - res3 = albh & mask_low; - temp = res1 + res2 + res3; - carry = temp >>> (8 * 4); - c[0] ^= temp << (8 * 4); // C01 - - res1 = ahbl >>> (8 * 4); - res2 = albh >>> (8 * 4); - res3 = ahbh & mask_low; - temp = res1 + res2 + res3 + carry; - c[1] = temp & mask_low; // C10 - carry = temp & mask_high; - c[1] ^= (ahbh & mask_high) + carry; // C11 - } - - // Efficient Montgomery reduction using comba and exploiting the special form of the prime PRIME. - // mc = ma*R^-1 mod PRIMEx2, where R = 2^448. - // If ma < 2^448*PRIME, the output mc is in the range [0, 2*PRIME-1]. - // ma is assumed to be in Montgomery representation. - private void rdc_mont(long[] ma, long[] mc) - { - int i, j, carry, count = engine.params.PRIME_ZERO_WORDS; - long t = 0, u = 0, v = 0, temp; - long[] UV = new long[2]; - - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - mc[i] = 0; - } - - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - for (j = 0; j < i; j++) - { - if (j < (i-engine.params.PRIME_ZERO_WORDS+1)) - { - //MUL - digit_x_digit(mc[j], engine.params.PRIMEp1[i - j], UV); - - //ADDC - temp = UV[0]; - v += temp; - temp = UV[1] + is_digit_lessthan_ct(v, temp); // No overflow possible; high part of product < Long.MAX_VALUE - - //ADDC - u += temp; - t += is_digit_lessthan_ct(u, temp); - } - } - - //ADDC - long tempReg = ma[i]; - v += tempReg; - carry = is_digit_lessthan_ct(v, tempReg); - - //ADDC - u += carry; - carry &= is_digit_zero_ct(u); - - t += carry; - mc[i] = v; - v = u; - u = t; - t = 0; - } - - for (i = engine.params.NWORDS_FIELD; i < 2*engine.params.NWORDS_FIELD-1; i++) - { - if (count > 0) - { - count -= 1; - } - for (j = i-engine.params.NWORDS_FIELD+1; j < engine.params.NWORDS_FIELD; j++) - { - if (j < (engine.params.NWORDS_FIELD-count)) - { - //MUL - digit_x_digit(mc[j], engine.params.PRIMEp1[i - j], UV); - - //ADDC - temp = UV[0]; - v += temp; - temp = UV[1] + is_digit_lessthan_ct(v, temp); // No overflow possible; high part of product < Long.MAX_VALUE - - //ADDC - u += temp; - t += is_digit_lessthan_ct(u, temp); - } - } - - //ADDC - long tempReg = ma[i]; - v += tempReg; - carry = is_digit_lessthan_ct(v, tempReg); - - //ADDC - u += carry; - carry &= is_digit_zero_ct(u); - - t += carry; - mc[i - engine.params.NWORDS_FIELD] = v; - v = u; - u = t; - t = 0; - } - - //ADDC - long tempReg = ma[2*engine.params.NWORDS_FIELD-1]; - v += tempReg; - carry = is_digit_lessthan_ct(v, tempReg); -// assert carry == 0; - - mc[engine.params.NWORDS_FIELD-1] = v; -// assert u == 0; -// assert t == 0; - } - - protected static boolean subarrayEquals(long[] a, long[] b, int length) - { - for (int i = 0; i < length; i++) - { - if(a[i] != b[i]) - return false; - } - return true; - } - - protected static boolean subarrayEquals(long[][] a, long[][] b, int length) - { - int nwords_feild = b[0].length; - for (int i = 0; i < length; i++) - { - if(a[i/nwords_feild][i%nwords_feild] != b[i/nwords_feild][i%nwords_feild]) - return false; - } - return true; - } - - protected static boolean subarrayEquals(long[][] a, long[][] b, int bOffset, int length) - { - int nwords_feild = b[0].length; - for (int i = 0; i < length; i++) - { - if(a[i/nwords_feild][i%nwords_feild] != b[(i + bOffset)/nwords_feild][(i+bOffset)%nwords_feild]) - return false; - } - return true; - } - - protected static boolean subarrayEquals(long[][] a, long[] b, int bOffset, int length) - { - int nwords_field = a[0].length; - for (int i = 0; i < length; i++) - { - if(a[i/nwords_field][i%nwords_field] != b[(i + bOffset)]) - return false; //8316 -> 425529A64ABCAC1F - } - return true; - } - - // Computes square roots of elements in (Fp2)^2 using Hamburg's trick. - void sqrt_Fp2(long[][] u, long[][] y) - { - - long[] t0 = new long[engine.params.NWORDS_FIELD], - t1 = new long[engine.params.NWORDS_FIELD], - t2 = new long[engine.params.NWORDS_FIELD], - t3 = new long[engine.params.NWORDS_FIELD]; - - int i; - - fpsqr_mont(u[0], t0); // t0 = a^2 - fpsqr_mont(u[1], t1); // t1 = b^2 - fpaddPRIME(t0, t1, t0); // t0 = t0+t1 - fpcopy(t0, 0, t1); - for (i = 0; i < engine.params.OALICE_BITS - 2; i++) - { // t = t3^((p+1)/4) - fpsqr_mont(t1, t1); - } - for (i = 0; i < engine.params.OBOB_EXPON; i++) - { - fpsqr_mont(t1, t0); - fpmul_mont(t1, t0, t1); - } - fpaddPRIME(u[0], t1, t0); // t0 = a+t1 - fpdiv2_PRIME(t0, t0); // t0 = t0/2 - fpcopy(t0, 0, t2); - fpinv_chain_mont(t2); // t2 = t0^((p-3)/4) - fpmul_mont(t0, t2, t1); // t1 = t2*t0 - fpmul_mont(t2, u[1], t2); // t2 = t2*b - fpdiv2_PRIME(t2, t2); // t2 = t2/2 - fpsqr_mont(t1, t3); // t3 = t1^2 - fpcorrectionPRIME(t0); - fpcorrectionPRIME(t3); - - if (subarrayEquals(t0, t3, engine.params.NWORDS_FIELD)) - { - fpcopy(t1, 0, y[0]); - fpcopy(t2, 0, y[1]); - } - else - { - fpnegPRIME(t1); - fpcopy(t2, 0, y[0]); - fpcopy(t1, 0, y[1]); - } - } - - // GF(p^2) squaring using Montgomery arithmetic, c = a^2 in GF(p^2). - // Inputs: a = a0+a1*i, where a0, a1 are in [0, 2*p-1] - // Output: c = c0+c1*i, where c0, c1 are in [0, 2*p-1] - protected void fp2sqr_mont(long[][] a, long[][] c) - { - long[] t1 = new long[engine.params.NWORDS_FIELD], - t2 = new long[engine.params.NWORDS_FIELD], - t3 = new long[engine.params.NWORDS_FIELD]; - - mp_add(a[0], a[1], t1, engine.params.NWORDS_FIELD); // t1 = a0+a1 - mp_subPRIME_p4(a[0], a[1], t2); // t2 = a0-a1 - mp_add(a[0], a[0], t3, engine.params.NWORDS_FIELD); // t3 = 2a0 - fpmul_mont(t1, t2, c[0]); // c0 = (a0+a1)(a0-a1) - fpmul_mont(t3, a[1], c[1]); // c1 = 2a0*a1 - } - - // Modular addition, c = a+b mod PRIME. - // Inputs: a, b in [0, 2*PRIME-1] - // Output: c in [0, 2*PRIME-1] - protected void fpaddPRIME(long[] a, long[] b, long[] c) - { - int i, carry = 0; - long mask; - - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //ADDC - long tempReg = a[i] + carry; - c[i] = b[i] + tempReg; - carry = (is_digit_lessthan_ct(tempReg, carry) | is_digit_lessthan_ct(c[i], tempReg)); - - } - - carry = 0; - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //SUBC - long tempReg = c[i] - engine.params.PRIMEx2[i]; - int borrowReg = (is_digit_lessthan_ct(c[i], engine.params.PRIMEx2[i]) | (carry & is_digit_zero_ct(tempReg))); - c[i] = tempReg - (long)(carry); - carry = borrowReg; - - } - mask = 0 - carry; - - carry = 0; - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //ADDC - long tempReg = c[i] + carry; - c[i] = (engine.params.PRIMEx2[i] & mask) + tempReg; - carry = (is_digit_lessthan_ct(tempReg, carry) | is_digit_lessthan_ct(c[i], tempReg)); - - } - } - - // Cyclotomic cubing on elements of norm 1, using a^(p+1) = 1. - protected void cube_Fp2_cycl(long[][] a, long[] one) - { - long[] t0 = new long[engine.params.NWORDS_FIELD]; - - fpaddPRIME(a[0], a[0], t0); // t0 = a0 + a0 - fpsqr_mont(t0, t0); // t0 = t0^2 - fpsubPRIME(t0, one, t0); // t0 = t0 - 1 - fpmul_mont(a[1], t0, a[1]); // a1 = t0*a1 - fpsubPRIME(t0, one, t0); - fpsubPRIME(t0, one, t0); // t0 = t0 - 2 - fpmul_mont(a[0], t0, a[0]); // a0 = t0*a0 - } - - // Modular subtraction, c = a-b mod PRIME. - // Inputs: a, b in [0, 2*PRIME-1] - // Output: c in [0, 2*PRIME-1] - protected void fpsubPRIME(long[] a, long[] b, int bOffset, long[] c) - { - int i, borrow = 0; - long mask; - - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //SUBC - long tempReg = a[i] - b[i + bOffset]; - int borrowReg = (is_digit_lessthan_ct(a[i], b[i + bOffset]) | (borrow & is_digit_zero_ct(tempReg))); - c[i] = tempReg - (long)(borrow); - borrow = borrowReg; - } - mask = 0 - borrow; - - borrow = 0; - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //ADDC - long tempReg = c[i] + borrow; - c[i] = (engine.params.PRIMEx2[i] & mask) + tempReg; - borrow = (is_digit_lessthan_ct(tempReg, borrow) | is_digit_lessthan_ct(c[i], tempReg)); - } - } - - protected void fpsubPRIME(long[] a, int aOffset, long[] b, long[] c) - { - int i, borrow = 0; - long mask; - - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //SUBC - long tempReg = a[i + aOffset] - b[i]; - int borrowReg = (is_digit_lessthan_ct(a[i + aOffset], b[i]) | (borrow & is_digit_zero_ct(tempReg))); - c[i] = tempReg - (long)(borrow); - borrow = borrowReg; - } - mask = 0 - borrow; - - borrow = 0; - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //ADDC - long tempReg = c[i] + borrow; - c[i] = (engine.params.PRIMEx2[i] & mask) + tempReg; - borrow = (is_digit_lessthan_ct(tempReg, borrow) | is_digit_lessthan_ct(c[i], tempReg)); - } - } - - protected void fpsubPRIME(long[] a, long[] b, long[] c) - { - int i, borrow = 0; - long mask; - - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //SUBC - long tempReg = a[i] - b[i]; - int borrowReg = (is_digit_lessthan_ct(a[i], b[i]) | (borrow & is_digit_zero_ct(tempReg))); - c[i] = tempReg - (long)(borrow); - borrow = borrowReg; - } - mask = 0 - borrow; - - borrow = 0; - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //ADDC - long tempReg = c[i] + borrow; - c[i] = (engine.params.PRIMEx2[i] & mask) + tempReg; - borrow = (is_digit_lessthan_ct(tempReg, borrow) | is_digit_lessthan_ct(c[i], tempReg)); - } - } - - // Modular negation, a = -a mod PRIME. - // Input/output: a in [0, 2*PRIME-1] - protected void fpnegPRIME(long[] a) - { - int i, borrow = 0; - - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //SUBC - long tempReg = engine.params.PRIMEx2[i] - a[i]; - int borrowReg = (is_digit_lessthan_ct(engine.params.PRIMEx2[i], a[i]) | (borrow & is_digit_zero_ct(tempReg))); - a[i] = tempReg - (long)(borrow); - borrow = borrowReg; - } - } - - // Conversion of a GF(p^2) element from Montgomery representation to standard representation, - // c_i = ma_i*R^(-1) = a_i in GF(p^2). - protected void from_fp2mont(long[][] ma, long[][] c) - { - from_mont(ma[0], c[0]); - from_mont(ma[1], c[1]); - } - - // Conversion of GF(p^2) element from Montgomery to standard representation, and encoding by removing leading 0 bytes - protected void fp2_encode(long[][] x, byte[] enc, int encOffset) - { - long[][] t = new long[2][engine.params.NWORDS_FIELD]; - - from_fp2mont(x, t); - encode_to_bytes(t[0], enc, encOffset,engine.params.FP2_ENCODED_BYTES / 2); - encode_to_bytes(t[1], enc, encOffset + engine.params.FP2_ENCODED_BYTES / 2, engine.params.FP2_ENCODED_BYTES / 2); - } - - // Parse byte sequence back into GF(p^2) element, and conversion to Montgomery representation - protected void fp2_decode(byte[] x, long[][] dec, int xOffset) - { - decode_to_digits(x, xOffset, dec[0], engine.params.FP2_ENCODED_BYTES / 2, engine.params.NWORDS_FIELD); - decode_to_digits(x,xOffset + (engine.params.FP2_ENCODED_BYTES/2), dec[1], engine.params.FP2_ENCODED_BYTES / 2, engine.params.NWORDS_FIELD); - to_fp2mont(dec, dec); - } - - // Conversion of elements in Z_r to Montgomery representation, where the order r is up to NBITS_ORDER bits. - protected void to_Montgomery_mod_order(long[] a, long[] mc, long[] order, long[] Montgomery_rprime, long[] Montgomery_Rprime) - { - Montgomery_multiply_mod_order(a, Montgomery_Rprime, mc, order, Montgomery_rprime); - } - - // Montgomery multiplication modulo the group order, mc = ma*mb*r' mod order, where ma,mb,mc in [0, order-1]. - // ma, mb and mc are assumed to be in Montgomery representation. - // The Montgomery constant r' = -r^(-1) mod 2^(log_2(r)) is the value "Montgomery_rprime", where r is the order. - // Assume log_2(r) is a multiple of RADIX bits - protected void Montgomery_multiply_mod_order(long[] ma, long[] mb, long[] mc, long[] order, long[] Montgomery_rprime) - { - int i, cout = 0, bout = 0; - long mask; - long[] P = new long[2*engine.params.NWORDS_ORDER], - Q = new long[2*engine.params.NWORDS_ORDER], - temp = new long[2*engine.params.NWORDS_ORDER]; - - multiply(ma, mb, P, engine.params.NWORDS_ORDER); // P = ma * mb - multiply(P, Montgomery_rprime, Q, engine.params.NWORDS_ORDER); // Q = P * r' mod 2^(log_2(r)) - multiply(Q, order, temp, engine.params.NWORDS_ORDER); // temp = Q * r - cout = mp_add(P, temp, temp, 2*engine.params.NWORDS_ORDER); // (cout, temp) = P + Q * r - - for (i = 0; i < engine.params.NWORDS_ORDER; i++) // (cout, mc) = (P + Q * r)/2^(log_2(r)) - { - mc[i] = temp[engine.params.NWORDS_ORDER+i]; - } - - // Final, constant-time subtraction - bout = mp_sub(mc, order, mc, engine.params.NWORDS_ORDER); // (cout, mc) = (cout, mc) - r - mask = cout - bout; // if (cout, mc) >= 0 then mask = 0x00..0, else if (cout, mc) < 0 then mask = 0xFF..F - - for (i = 0; i < engine.params.NWORDS_ORDER; i++) - { // temp = mask & r - temp[i] = (order[i] & mask); - } - - mp_add(mc, temp, mc, engine.params.NWORDS_ORDER); // mc = mc + (mask & r) - } - - // Inversion of an odd integer modulo an even integer of the form 2^m. - // Algorithm 3: Explicit Quadratic Modular inverse modulo 2^m from Dumas'12: https://arxiv.org/pdf/1209.6626.pdf - // If the input is invalid (even), the function outputs c = a. - protected void inv_mod_orderA(long[] a, long[] c) - { - int i, f, s = 0; - long[] am1 = new long[engine.params.NWORDS_ORDER], - tmp1 = new long[engine.params.NWORDS_ORDER], - tmp2 = new long[2*engine.params.NWORDS_ORDER], - one = new long[engine.params.NWORDS_ORDER], - order = new long[engine.params.NWORDS_ORDER]; - long mask = ((-1L) >>> (engine.params.NBITS_ORDER - engine.params.OALICE_BITS)); - - order[engine.params.NWORDS_ORDER-1] = (1L << (64 - (engine.params.NBITS_ORDER - engine.params.OALICE_BITS))); // Load most significant digit of Alice's order - one[0] = 1; - - mp_sub(a, one, am1, engine.params.NWORDS_ORDER); // am1 = a-1 - - if (((a[0] & 1) == 0) || (is_zero(am1, engine.params.NWORDS_ORDER))) - { // Check if the input is even or one - copy_words(a, c, engine.params.NWORDS_ORDER); - c[engine.params.NWORDS_ORDER-1] &= mask; // mod 2^m - } - else - { - mp_sub(order, am1, c, engine.params.NWORDS_ORDER); - mp_add(c, one, c, engine.params.NWORDS_ORDER); // c = 2^m - a + 2 - - copy_words(am1, tmp1, engine.params.NWORDS_ORDER); - while ((tmp1[0] & 1L) == 0) - { - s += 1; - mp_shiftr1(tmp1, engine.params.NWORDS_ORDER); - } - - f = engine.params.OALICE_BITS / s; - for (i = 1; i < f; i <<= 1) - { - multiply(am1, am1, tmp2, engine.params.NWORDS_ORDER); // tmp2 = am1^2 - copy_words(tmp2, am1, engine.params.NWORDS_ORDER); - am1[engine.params.NWORDS_ORDER-1] &= mask; // am1 = tmp2 mod 2^m - mp_add(am1, one, tmp1, engine.params.NWORDS_ORDER); // tmp1 = am1 + 1 - tmp1[engine.params.NWORDS_ORDER-1] &= mask; // mod 2^m - multiply(c, tmp1, tmp2, engine.params.NWORDS_ORDER); // c = c*tmp1 - copy_words(tmp2, c, engine.params.NWORDS_ORDER); - c[engine.params.NWORDS_ORDER-1] &= mask; // mod 2^m - } - } - } - - // Multiprecision comba multiply, c = a*b, where lng(a) = lng(b) = nwords. - // NOTE: a and c CANNOT be the same variable! - protected void multiply(long[] a, long[] b, long[] c, int nwords) - { - int i, j; - long t = 0, u = 0, v = 0, temp; - long[] UV = new long[2]; - - for (i = 0; i < nwords; i++) - { - for (j = 0; j <= i; j++) - { - //MUL - digit_x_digit(a[j], b[i - j], UV); - - //ADDC - temp = UV[0]; - v += temp; - temp = UV[1] + is_digit_lessthan_ct(v, temp); // No overflow possible; high part of product < Long.MAX_VALUE - - //ADDC - u += temp; - t += is_digit_lessthan_ct(u, temp); - } - c[i] = v; - v = u; - u = t; - t = 0; - } - for (i = nwords; i < 2*nwords-1; i++) - { - for (j = i-nwords+1; j < nwords; j++) - { - //MUL - digit_x_digit(a[j], b[i - j], UV); - - //ADDC - temp = UV[0]; - v += temp; - temp = UV[1] + is_digit_lessthan_ct(v, temp); // No overflow possible; high part of product < Long.MAX_VALUE - - //ADDC - u += temp; - t += is_digit_lessthan_ct(u, temp); - } - c[i] = v; - v = u; - u = t; - t = 0; - } - c[2 * nwords - 1] = v; -// assert u == 0; -// assert t == 0; - } - - // Is x = 0? return 1 (TRUE) if condition is true, 0 (FALSE) otherwise - // SECURITY NOTE: This function does not run in constant time. - private boolean is_zero_mod_order(long[] x) - { - int i; - for (i = 0; i < engine.params.NWORDS_ORDER; i++) - { - if (x[i] != 0) - { - return false; - } - } - return true; - } - - // Is x even? return 1 (TRUE) if condition is true, 0 (FALSE) otherwise. - private boolean is_even_mod_order(long[] x) - { - return ((x[0] & 1) ^ 1) == 1; - } - - // Is x < y? return 1 (TRUE) if condition is true, 0 (FALSE) otherwise. - // SECURITY NOTE: This function does not run in constant time. - private boolean is_lt_mod_order(long[] x, long[] y) - { - int i; - - for (i = engine.params.NWORDS_ORDER-1; i >= 0; i--) - { - if (x[i] + Long.MIN_VALUE < y[i] + Long.MIN_VALUE ) - { - return true; - } - else if (x[i] + Long.MIN_VALUE > y[i] + Long.MIN_VALUE ) - { - return false; - } - } - return false; - } - - // Check if multiprecision element is zero. - // SECURITY NOTE: This function does not run in constant time. - private boolean is_zero(long[] a, int nwords) - { - for (int i = 0; i < nwords; i++) - { - if (a[i] != 0) - { - return false; - } - } - return true; - } - - - // Partial Montgomery inversion modulo order. - private void Montgomery_inversion_mod_order_bingcd_partial(long[] a, long[] x1, int[] k, long[] order) - { - long[] u = new long[engine.params.NWORDS_ORDER], - v = new long[engine.params.NWORDS_ORDER], - x2 = new long[engine.params.NWORDS_ORDER]; - int cwords; // number of words necessary for x1, x2 - - copy_words(a, u, engine.params.NWORDS_ORDER); - copy_words(order, v, engine.params.NWORDS_ORDER); - copy_words(x2, x1, engine.params.NWORDS_ORDER); - x1[0] = 1; - k[0] = 0; - - while (!is_zero_mod_order(v)) - { - cwords = ((k[0] + 1) / Internal.RADIX) + 1; - if ((cwords < engine.params.NWORDS_ORDER)) - { - if (is_even_mod_order(v)) - { - mp_shiftr1(v, engine.params.NWORDS_ORDER); - mp_shiftl1(x1, cwords); - } - else if (is_even_mod_order(u)) - { - mp_shiftr1(u, engine.params.NWORDS_ORDER); - mp_shiftl1(x2, cwords); - } - else if (!is_lt_mod_order(v, u)) - { - mp_sub(v, u, v, engine.params.NWORDS_ORDER); - mp_shiftr1(v, engine.params.NWORDS_ORDER); - mp_add(x1, x2, x2, cwords); - mp_shiftl1(x1, cwords); - } - else - { - mp_sub(u, v, u, engine.params.NWORDS_ORDER); - mp_shiftr1(u, engine.params.NWORDS_ORDER); - mp_add(x1, x2, x1, cwords); - mp_shiftl1(x2, cwords); - } - } - else - { - if (is_even_mod_order(v)) - { - mp_shiftr1(v, engine.params.NWORDS_ORDER); - mp_shiftl1(x1, engine.params.NWORDS_ORDER); - } - else if (is_even_mod_order(u)) - { - mp_shiftr1(u, engine.params.NWORDS_ORDER); - mp_shiftl1(x2, engine.params.NWORDS_ORDER); - } - else if (!is_lt_mod_order(v, u)) - { - mp_sub(v, u, v, engine.params.NWORDS_ORDER); - mp_shiftr1(v, engine.params.NWORDS_ORDER); - mp_add(x1, x2, x2, engine.params.NWORDS_ORDER); - mp_shiftl1(x1, engine.params.NWORDS_ORDER); - } - else - { - mp_sub(u, v, u, engine.params.NWORDS_ORDER); - mp_shiftr1(u, engine.params.NWORDS_ORDER); - mp_add(x1, x2, x1, engine.params.NWORDS_ORDER); - mp_shiftl1(x2, engine.params.NWORDS_ORDER); - } - } - k[0] += 1; - } - - if (is_lt_mod_order(order, x1)) - { - mp_sub(x1, order, x1, engine.params.NWORDS_ORDER); - } - } - - // Montgomery inversion modulo order, c = a^(-1)*R mod order. - protected void Montgomery_inversion_mod_order_bingcd(long[] a, long[] c, long[] order, long[] Montgomery_rprime, long[] Montgomery_Rprime) - { - long[] x = new long[engine.params.NWORDS_ORDER], - t = new long[engine.params.NWORDS_ORDER]; - int[] k = new int[1]; - - if (is_zero(a, engine.params.NWORDS_ORDER)) - { - copy_words(t, c, engine.params.NWORDS_ORDER); - return; - } - - Montgomery_inversion_mod_order_bingcd_partial(a, x, k, order); - if (k[0] <= engine.params.NBITS_ORDER) - { - Montgomery_multiply_mod_order(x, Montgomery_Rprime, x, order, Montgomery_rprime); - k[0] += engine.params.NBITS_ORDER; - } - - Montgomery_multiply_mod_order(x, Montgomery_Rprime, x, order, Montgomery_rprime); - power2_setup(t, 2*engine.params.NBITS_ORDER - k[0], engine.params.NWORDS_ORDER); - Montgomery_multiply_mod_order(x, t, c, order, Montgomery_rprime); - } - - // Conversion of elements in Z_r from Montgomery to standard representation, where the order is up to NBITS_ORDER bits. - protected void from_Montgomery_mod_order(long[] ma, long[] c, long[] order, long[] Montgomery_rprime) - { - long[] one = new long[engine.params.NWORDS_ORDER]; - one[0] = 1; - - Montgomery_multiply_mod_order(ma, one, c, order, Montgomery_rprime); - } - - // Computes the input modulo 3 - // The input is assumed to be NWORDS_ORDER long - protected int mod3(long[] a) - { - long temp; - int r = 0; - int[] val = Pack.littleEndianToInt(Pack.longToLittleEndian(a), 0, a.length*2); - - for (int i = (2*engine.params.NWORDS_ORDER-1); i >= 0; i--) - { - temp = ((long)r << (4*8)) | ((long)val[i]) & 0x00000000ffffffffL; - r = (int)(temp % 3); - } - - return r; -} - - // Conversion of a GF(p^2) element to Montgomery representation, - // mc_i = a_i*R^2*R^(-1) = a_i*R in GF(p^2). - protected void to_fp2mont(long[][] a, long[][] mc) - { - to_mont(a[0], mc[0]); - to_mont(a[1], mc[1]); - } - - // Conversion to Montgomery representation, - // mc = a*R^2*R^(-1) mod p = a*R mod p, where a in [0, p-1]. - // The Montgomery constant R^2 mod p is the global value "Montgomery_R2". - private void to_mont(long[] a, long[] mc) - { - fpmul_mont(a, engine.params.Montgomery_R2, mc); - } - - - // Modular correction to reduce field element a in [0, 2*PRIME-1] to [0, PRIME-1]. - protected void fpcorrectionPRIME(long[] a) - { - int i, borrow = 0; - long mask; - - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //SUBC - long tempReg = a[i] - engine.params.PRIME[i]; - int borrowReg = (is_digit_lessthan_ct(a[i], engine.params.PRIME[i]) | (borrow & is_digit_zero_ct(tempReg))); - a[i] = tempReg - (long)(borrow); - borrow = borrowReg; - } - mask = 0 - borrow; - - borrow = 0; - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - //ADDC - long tempReg = a[i] + borrow; - a[i] = (engine.params.PRIME[i] & mask) + tempReg; - borrow = (is_digit_lessthan_ct(tempReg, borrow) | is_digit_lessthan_ct(a[i], tempReg)); - } - } - - protected byte cmp_f2elm(long[][] x, long[][] y) - { // Comparison of two GF(p^2) elements in constant time. - // Is x != y? return -1 if condition is true, 0 otherwise. - long[][] a = new long[2][engine.params.NWORDS_FIELD], - b = new long[2][engine.params.NWORDS_FIELD]; - byte r = 0; - - fp2copy(x, a); - fp2copy(y, b); - fp2correction(a); - fp2correction(b); - - for (int i = engine.params.NWORDS_FIELD-1; i >= 0; i--) - { - r |= (a[0][i] ^ b[0][i]) | (a[1][i] ^ b[1][i]); - } - - return (byte) ((-(byte)r) >>> (8-1)); - } - - - // Encoding digits to bytes according to endianness - protected void encode_to_bytes(long[] x, byte[] enc, int encOffset, int nbytes) - { - byte[] test = new byte[((nbytes*4+7)&~7)]; - Pack.longToLittleEndian(x, test, 0); - System.arraycopy(test, 0, enc, encOffset, nbytes); - } - - // Decoding bytes to digits according to endianness - protected void decode_to_digits(byte[] x, int xOffset, long[] dec, int nbytes, int ndigits) - { - // x -> dec - dec[ndigits - 1] = 0; - byte[] temp = new byte[(nbytes+7)&~7]; - System.arraycopy(x, xOffset, temp, 0, nbytes); - Pack.littleEndianToLong(temp, 0, dec); - - } - - // r = a - b*i where v = a + b*i - protected void fp2_conj(long[][] v, long[][] r) - { - fpcopy(v[0], 0, r[0]); - fpcopy(v[1], 0, r[1]); - - if(!is_felm_zero(r[1])) - { - fpnegPRIME(r[1]); - } - } - - - - - // Conversion from Montgomery representation to standard representation, - // c = ma*R^(-1) mod p = a mod p, where ma in [0, p-1]. - private void from_mont(long[] ma, long[] c) - { - long[] one = new long[engine.params.NWORDS_FIELD]; - - one[0] = 1; - fpmul_mont(ma, one, c); - fpcorrectionPRIME(c); - } - - // Multiprecision right shift by one. - private void mp_shiftr1(long[] x) - { - int i; - - for (i = 0; i < engine.params.NWORDS_FIELD-1; i++) - { - //SHIFTR - x[i] = (x[i] >>> 1) ^ (x[i+1] << (Internal.RADIX - 1)); - } - x[engine.params.NWORDS_FIELD-1] >>>= 1; - } - - private void mp_shiftr1(long[] x, int nwords) - { - int i; - - for (i = 0; i < nwords-1; i++) - { - //SHIFTR - x[i] = (x[i] >>> 1) ^ (x[i+1] << (Internal.RADIX - 1)); - } - x[nwords-1] >>>= 1; - } - - // Copy a GF(p^2) element, c = a. - protected void fp2copy(long[][] a, long[][] c) - { - fpcopy(a[0], 0, c[0]); - fpcopy(a[1], 0, c[1]); - } - - // Copy a GF(p^2) element, c = a. - protected void fp2copy(long[][] a, int aOffset, long[][] c) - { - fpcopy(a[0 + aOffset], 0, c[0]); - fpcopy(a[1 + aOffset], 0, c[1]); - } - - // Copy a GF(p^2) element, c = a. - protected void fp2copy(long[] a, int aOffset, long[][] c) - { - fpcopy(a, aOffset, c[0]); - fpcopy(a, aOffset + engine.params.NWORDS_FIELD, c[1]); - } - - // Zero a field element, a = 0. - protected void fpzero(long[] a) - { - int i; - - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - a[i] = 0; - } - } - - // GF(p^2) subtraction with correction with 2*p, c = a-b+2p in GF(p^2). - protected void mp2_sub_p2(long[][] a, long[][] b, long[][] c) - { - //todo/org : make fp class and change this to generic mp_sub_p2 - mp_subPRIME_p2(a[0], b[0], c[0]); - mp_subPRIME_p2(a[1], b[1], c[1]); - } - - // Multiprecision comba multiply, c = a*b, where lng(a) = lng(b) = nwords. - protected void mp_mul(long[] a, long[] b, long[] c, int nwords) - { - int i, j; - long t = 0, u = 0, v = 0, temp; - long[] UV = new long[2]; - - for (i = 0; i < nwords; i++) - { - for (j = 0; j <= i; j++) - { - //MUL - digit_x_digit(a[j], b[i - j], UV); - - //ADDC - temp = UV[0]; - v += temp; - temp = UV[1] + is_digit_lessthan_ct(v, temp); // No overflow possible; high part of product < Long.MAX_VALUE - - //ADDC - u += temp; - t += is_digit_lessthan_ct(u, temp); - } - c[i] = v; - v = u; - u = t; - t = 0; - } - - for (i = nwords; i < 2*nwords-1; i++) - { - for (j = i-nwords+1; j < nwords; j++) - { - //MUL - digit_x_digit(a[j], b[i - j], UV); - - //ADDC - temp = UV[0]; - v += temp; - temp = UV[1] + is_digit_lessthan_ct(v, temp); // No overflow possible; high part of product < Long.MAX_VALUE - - //ADDC - u += temp; - t += is_digit_lessthan_ct(u, temp); - } - c[i] = v; - v = u; - u = t; - t = 0; - } - c[2 * nwords - 1] = v; -// assert u == 0; -// assert t == 0; - } - - // Multiprecision comba multiply, c = a*b, where lng(a) = lng(b) = nwords. - protected void mp_mul(long[] a, int aOffset, long[] b, long[] c, int nwords) - { - int i, j; - long t = 0, u = 0, v = 0, temp; - long[] UV = new long[2]; - - for (i = 0; i < nwords; i++) - { - for (j = 0; j <= i; j++) - { - //MUL - digit_x_digit(a[j + aOffset], b[i - j], UV); - - //ADDC - temp = UV[0]; - v += temp; - temp = UV[1] + is_digit_lessthan_ct(v, temp); // No overflow possible; high part of product < Long.MAX_VALUE - - //ADDC - u += temp; - t += is_digit_lessthan_ct(u, temp); - } - c[i] = v; - v = u; - u = t; - t = 0; - } - - for (i = nwords; i < 2*nwords-1; i++) - { - for (j = i-nwords+1; j < nwords; j++) - { - //MUL - digit_x_digit(a[j + aOffset], b[i - j], UV); - - //ADDC - temp = UV[0]; - v += temp; - temp = UV[1] + is_digit_lessthan_ct(v, temp); // No overflow possible; high part of product < Long.MAX_VALUE - - //ADDC - u += temp; - t += is_digit_lessthan_ct(u, temp); - } - c[i] = v; - v = u; - u = t; - t = 0; - } - c[2 * nwords - 1] = v; -// assert u == 0; -// assert t == 0; - } - - // GF(p^2) multiplication using Montgomery arithmetic, c = a*b in GF(p^2). - // Inputs: a = a0+a1*i and b = b0+b1*i, where a0, a1, b0, b1 are in [0, 2*p-1] - // Output: c = c0+c1*i, where c0, c1 are in [0, 2*p-1] - protected void fp2mul_mont(long[][] a, long[][] b, long[][] c) - { - long[] t1 = new long[engine.params.NWORDS_FIELD], - t2 = new long[engine.params.NWORDS_FIELD]; - long[] tt1 = new long[2*engine.params.NWORDS_FIELD], - tt2 = new long[2*engine.params.NWORDS_FIELD], - tt3 = new long[2*engine.params.NWORDS_FIELD]; - - mp_add(a[0], a[1], t1, engine.params.NWORDS_FIELD); // t1 = a0+a1 - mp_add(b[0], b[1], t2, engine.params.NWORDS_FIELD); // t2 = b0+b1 - mp_mul(a[0], b[0], tt1, engine.params.NWORDS_FIELD); // tt1 = a0*b0 - mp_mul(a[1], b[1], tt2, engine.params.NWORDS_FIELD); // tt2 = a1*b1 - mp_mul(t1, t2, tt3, engine.params.NWORDS_FIELD); // tt3 = (a0+a1)*(b0+b1) - mp_dblsubfast(tt1, tt2, tt3); // tt3 = (a0+a1)*(b0+b1) - a0*b0 - a1*b1 - mp_subaddfast(tt1, tt2, tt1); // tt1 = a0*b0 - a1*b1 + p*2^MAXBITS_FIELD if a0*b0 - a1*b1 < 0, else tt1 = a0*b0 - a1*b1 - rdc_mont(tt3, c[1]); // c[1] = (a0+a1)*(b0+b1) - a0*b0 - a1*b1 - rdc_mont(tt1, c[0]); // c[0] = a0*b0 - a1*b1 - } - - protected void fp2mul_mont(long[][] a, long[][] b, int bOffset, long[][] c) - { - -// System.out.print("b: "); -// for (int di = 0; di < 2; di++){for (int dj = 0; dj < engine.params.NWORDS_FIELD; dj++) -// {System.out.printf("%016x ", b[di + bOffset][dj] );}System.out.println();} - - long[] t1 = new long[engine.params.NWORDS_FIELD], - t2 = new long[engine.params.NWORDS_FIELD]; - long[] tt1 = new long[2*engine.params.NWORDS_FIELD], - tt2 = new long[2*engine.params.NWORDS_FIELD], - tt3 = new long[2*engine.params.NWORDS_FIELD]; - - mp_add(a[0], a[1], t1, engine.params.NWORDS_FIELD); // t1 = a0+a1 - mp_add(b[0 + bOffset], b[bOffset + 1], t2, engine.params.NWORDS_FIELD); // t2 = b0+b1 - mp_mul(a[0], b[bOffset + 0], tt1, engine.params.NWORDS_FIELD); // tt1 = a0*b0 - mp_mul(a[1], b[bOffset + 1], tt2, engine.params.NWORDS_FIELD); // tt2 = a1*b1 - mp_mul(t1, t2, tt3, engine.params.NWORDS_FIELD); // tt3 = (a0+a1)*(b0+b1) - mp_dblsubfast(tt1, tt2, tt3); // tt3 = (a0+a1)*(b0+b1) - a0*b0 - a1*b1 - mp_subaddfast(tt1, tt2, tt1); // tt1 = a0*b0 - a1*b1 + p*2^MAXBITS_FIELD if a0*b0 - a1*b1 < 0, else tt1 = a0*b0 - a1*b1 - rdc_mont(tt3, c[1]); // c[1] = (a0+a1)*(b0+b1) - a0*b0 - a1*b1 - rdc_mont(tt1, c[0]); // c[0] = a0*b0 - a1*b1 - } - - protected void fp2mul_mont(long[][] a, long[] b, int bOffset, long[][] c) - { - long[] t1 = new long[engine.params.NWORDS_FIELD], - t2 = new long[engine.params.NWORDS_FIELD]; - long[] tt1 = new long[2*engine.params.NWORDS_FIELD], - tt2 = new long[2*engine.params.NWORDS_FIELD], - tt3 = new long[2*engine.params.NWORDS_FIELD]; - - mp_add(a[0], a[1], t1, engine.params.NWORDS_FIELD); // t1 = a0+a1 - mp_add(b, bOffset, b, bOffset + engine.params.NWORDS_FIELD, t2, 0,engine.params.NWORDS_FIELD); // t2 = b0+b1 - mp_mul(b, bOffset, a[0], tt1, engine.params.NWORDS_FIELD); // tt1 = a0*b0 - mp_mul(b,bOffset + engine.params.NWORDS_FIELD, a[1], tt2, engine.params.NWORDS_FIELD); // tt2 = a1*b1 - mp_mul(t1, t2, tt3, engine.params.NWORDS_FIELD); // tt3 = (a0+a1)*(b0+b1) - mp_dblsubfast(tt1, tt2, tt3); // tt3 = (a0+a1)*(b0+b1) - a0*b0 - a1*b1 - mp_subaddfast(tt1, tt2, tt1); // tt1 = a0*b0 - a1*b1 + p*2^MAXBITS_FIELD if a0*b0 - a1*b1 < 0, else tt1 = a0*b0 - a1*b1 - rdc_mont(tt3, c[1]); // c[1] = (a0+a1)*(b0+b1) - a0*b0 - a1*b1 - rdc_mont(tt1, c[0]); // c[0] = a0*b0 - a1*b1 - } - - // Multiprecision subtraction, c = c-a-b, where lng(a) = lng(b) = 2*engine.params.NWORDS_FIELD. - private void mp_dblsubfast(long[] a, long[] b, long[] c) - { - mp_sub(c, a, c, 2*engine.params.NWORDS_FIELD); - mp_sub(c, b, c, 2*engine.params.NWORDS_FIELD); - } - - // Multiprecision subtraction, c = a-b, where lng(a) = lng(b) = nwords. Returns the borrow bit. - protected int mp_sub(long[] a, long[] b, long[] c, int nwords) - { - int i, borrow = 0; - - for (i = 0; i < nwords; i++) - { - //SUBC - long tempReg = a[i] - b[i]; -// System.out.printf("%016x ", tempReg); - int borrowReg = (is_digit_lessthan_ct(a[i], b[i]) | (borrow & is_digit_zero_ct(tempReg))); - c[i] = tempReg - (long)(borrow); - borrow = borrowReg; - } -// System.out.println(); - return borrow; - } - - // Is x < y? return 1 (TRUE) if condition is true, 0 (FALSE) otherwise. - // SECURITY NOTE: This function does not run in constant-time. - protected boolean is_orderelm_lt(long[] x, long[] y) - { - - for (int i = engine.params.NWORDS_ORDER-1; i >= 0; i--) - { - - if (x[i] + Long.MIN_VALUE < y[i] + Long.MIN_VALUE) - { - return true; - } - else if (x[i] + Long.MIN_VALUE > y[i] + Long.MIN_VALUE ) - { - return false; - } - } - return false; - } - - - // Multiprecision subtraction followed by addition with p*2^MAXBITS_FIELD, c = a-b+(p*2^MAXBITS_FIELD) if a-b < 0, otherwise c=a-b. - private void mp_subaddfast(long[] a, long[] b, long[] c) - { - long[] t1 = new long[engine.params.NWORDS_FIELD]; - - long mask = 0 - (long) mp_sub(a, b, c, 2*engine.params.NWORDS_FIELD); - for (int i = 0; i < engine.params.NWORDS_FIELD; i++) - { - t1[i] = engine.params.PRIME[i] & mask; - } - mp_add(c, engine.params.NWORDS_FIELD, t1, c, engine.params.NWORDS_FIELD, engine.params.NWORDS_FIELD); - } - - // Multiprecision squaring, c = a^2 mod p. - protected void fpsqr_mont(long[] ma, long[] mc) - { - long[] temp = new long[2*engine.params.NWORDS_FIELD]; - - mp_mul(ma, ma, temp, engine.params.NWORDS_FIELD); - rdc_mont(temp, mc); - } - - // Field inversion using Montgomery arithmetic, a = a^(-1)*R mod p. - private void fpinv_mont(long[] a) - { - long[] tt = new long[engine.params.NWORDS_FIELD]; - - fpcopy(a, 0, tt); - fpinv_chain_mont(tt); - fpsqr_mont(tt, tt); - fpsqr_mont(tt, tt); - fpmul_mont(a, tt, a); - } - - // GF(p^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2). - protected void fp2inv_mont(long[][] a) - { - long[][] t1 = new long[2][engine.params.NWORDS_FIELD]; - - fpsqr_mont(a[0], t1[0]); // t10 = a0^2 - fpsqr_mont(a[1], t1[1]); // t11 = a1^2 - fpaddPRIME(t1[0], t1[1], t1[0]); // t10 = a0^2+a1^2 - fpinv_mont(t1[0]); // t10 = (a0^2+a1^2)^-1 - fpnegPRIME(a[1]); // a = a0-i*a1 - fpmul_mont(a[0], t1[0], a[0]); - fpmul_mont(a[1], t1[0], a[1]); // a = (a0-i*a1)*(a0^2+a1^2)^-1 - } - - // Computes a = 3*a - // The input is assumed to be OBOB_BITS-2 bits long and stored in SECRETKEY_B_BYTES - protected void mul3(byte[] a) - { - long[] temp1 = new long[engine.params.NWORDS_ORDER], - temp2 = new long[engine.params.NWORDS_ORDER]; - - decode_to_digits(a, 0, temp1, engine.params.SECRETKEY_B_BYTES, engine.params.NWORDS_ORDER); - mp_add(temp1, temp1, temp2, engine.params.NWORDS_ORDER); // temp2 = 2*a - mp_add(temp1, temp2, temp1, engine.params.NWORDS_ORDER); // temp1 = 3*a - encode_to_bytes(temp1, a, 0, engine.params.SECRETKEY_B_BYTES); - } - - // Compare two byte arrays in constant time. - // Returns 0 if the byte arrays are equal, -1 otherwise. - protected byte ct_compare(byte[] a, byte[] b, int len) - { - byte r = 0; - - for (int i = 0; i < len; i++) - { - r |= a[i] ^ b[i]; - } - return (byte)((-(byte)r) >>> 7); - } - - // Conditional move in constant time. - // If selector = -1 then load r with a, else if selector = 0 then keep r. - protected void ct_cmov(byte[] r, byte[] a, int len, byte selector) - { - for (int i = 0; i < len; i++) - { - r[i] ^= selector & (a[i] ^ r[i]); - } - } - - // Copy wordsize digits, c = a, where lng(a) = nwords. - protected void copy_words(long[] a, long[] c, int nwords) - { - int i; - for (i = 0; i < nwords; i++) - { - c[i] = a[i]; - } - } - - // c = (2^k)*a - protected void fp2shl(long[][] a, int k, long[][] c) - { - fp2copy(a, c); - for (int j = 0; j < k; j++) - { - fp2add(c, c, c); - } - } - - // Copy wordsize digits, c = a, where lng(a) = nwords. - protected void copy_words(PointProj a, PointProj c) - { - int i; - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - c.X[0][i] = a.X[0][i]; - c.X[1][i] = a.X[1][i]; - c.Z[0][i] = a.Z[0][i]; - c.Z[1][i] = a.Z[1][i]; - } - } - - // Modular negation, a = -a mod p. - // Input/output: a in [0, 2*p-1] - void Montgomery_neg(long[] a, long[] order) - { - int i, borrow = 0; - - for (i = 0; i < engine.params.NWORDS_ORDER; i++) - { - //SUBC - long tempReg = order[i] - a[i]; - int borrowReg = (is_digit_lessthan_ct(order[i], a[i]) | (borrow & is_digit_zero_ct(tempReg))); - a[i] = tempReg - (long)(borrow); - borrow = borrowReg; - - } - } - - - // GF(p^2) addition, c = a+b in GF(p^2). - protected void fp2add(long[][] a, long[][] b, long[][] c) - { - fpaddPRIME(a[0], b[0], c[0]); - fpaddPRIME(a[1], b[1], c[1]); - } - - // GF(p^2) subtraction, c = a-b in GF(p^2). - protected void fp2sub(long[][] a, long[][] b, long[][] c) - { - fpsubPRIME(a[0], b[0], c[0]); - fpsubPRIME(a[1], b[1], c[1]); - } - - // GF(p^2) subtraction with correction with 4*p, c = a-b+4p in GF(p^2). -// private void mp2_sub_p4(long[][] a, long[][] b, long[][] c) -// { -// mp_subPRIME_p4(a[0], b[0], c[0]); -// mp_subPRIME_p4(a[1], b[1], c[1]); -// } - - // Multiprecision multiplication, c = a*b mod p. - protected void fpmul_mont(long[] ma, long[] mb, long[] mc) - { - long[] temp = new long[2*engine.params.NWORDS_FIELD]; - - mp_mul(ma, mb, temp, engine.params.NWORDS_FIELD); - rdc_mont(temp, mc); - } - - // Multiprecision multiplication, c = a*b mod p. - protected void fpmul_mont(long[] ma, int maOffset, long[] mb, long[] mc) - { - long[] temp = new long[2*engine.params.NWORDS_FIELD]; - - mp_mul(ma, maOffset, mb, temp, engine.params.NWORDS_FIELD); - rdc_mont(temp, mc); - } - - // Chain to compute a^(p-3)/4 using Montgomery arithmetic. - private void fpinv_chain_mont(long[] a) - { - int i, j; - if (engine.params.NBITS_FIELD == 434) - { - long[] tt = new long[engine.params.NWORDS_FIELD]; - long[][] t = new long[31][engine.params.NWORDS_FIELD]; - - // Precomputed table - fpsqr_mont(a, tt); - fpmul_mont(a, tt, t[0]); - for (i = 0; i <= 29; i++) fpmul_mont(t[i], tt, t[i + 1]); - - fpcopy(a, 0, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[5], tt, tt); - for (i = 0; i < 10; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[14], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[3], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[23], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[13], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[24], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[7], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[12], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[30], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[1], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[30], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[21], tt, tt); - for (i = 0; i < 9; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[2], tt, tt); - for (i = 0; i < 9; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[19], tt, tt); - for (i = 0; i < 9; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[1], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[24], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[26], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[16], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[10], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[6], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[0], tt, tt); - for (i = 0; i < 9; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[20], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[9], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[25], tt, tt); - for (i = 0; i < 9; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[30], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[26], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(a, tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[28], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[6], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[10], tt, tt); - for (i = 0; i < 9; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[22], tt, tt); - for (j = 0; j < 35; j++) - { - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[30], tt, tt); - } - fpcopy(tt, 0, a); - } - - if (engine.params.NBITS_FIELD == 503) - { - long[][] t = new long[15][engine.params.NWORDS_FIELD]; - long[] tt = new long[engine.params.NWORDS_FIELD]; - - // Precomputed table - fpsqr_mont(a, tt); - fpmul_mont(a, tt, t[0]); - for (i = 0; i <= 13; i++) fpmul_mont(t[i], tt, t[i + 1]); - - fpcopy(a,0, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(a, tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[8], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[6], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[9], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[0], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(a, tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[6], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[2], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[8], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(a, tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[10], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[0], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[10], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[10], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[5], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[2], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[6], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[3], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[5], tt, tt); - for (i = 0; i < 12; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[12], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[8], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[6], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[12], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[11], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[6], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[5], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[14], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[14], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[5], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[6], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[8], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(a, tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[4], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[6], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[5], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[7], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(a, tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[0], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[11], tt, tt); - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[13], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[1], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[10], tt, tt); - for (j = 0; j < 49; j++) - { - for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[14], tt, tt); - } - fpcopy(tt, 0, a); - } - - if (engine.params.NBITS_FIELD == 610) - { - long[][] t = new long[31][engine.params.NWORDS_FIELD]; - long[] tt = new long[engine.params.NWORDS_FIELD]; - - // Precomputed table - fpsqr_mont(a, tt); - fpmul_mont(a, tt, t[0]); - for (i = 0; i <= 29; i++) fpmul_mont(t[i], tt, t[i + 1]); - - fpcopy(a, 0, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[6], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[30], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[25], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[28], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[7], tt, tt); - for (i = 0; i < 11; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[11], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(a, tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[0], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[3], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[16], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[24], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[28], tt, tt); - for (i = 0; i < 9; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[16], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[4], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[3], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[20], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[11], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[14], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[15], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[0], tt, tt); - for (i = 0; i < 9; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[15], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[19], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[9], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[5], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[27], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[28], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[29], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[1], tt, tt); - for (i = 0; i < 9; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[3], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[2], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[30], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[25], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[28], tt, tt); - for (i = 0; i < 9; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[22], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[3], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[22], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[7], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[9], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[4], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[20], tt, tt); - for (i = 0; i < 11; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[10], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[26], tt, tt); - for (i = 0; i < 11; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[2], tt, tt); - for (j = 0; j < 50; j++) - { - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[30], tt, tt); - } - fpcopy(tt, 0, a); - } - - if (engine.params.NBITS_FIELD == 751) - { - long[][] t = new long[27][engine.params.NWORDS_FIELD]; - long[] tt = new long[engine.params.NWORDS_FIELD]; - - // Precomputed table - fpsqr_mont(a, tt); - fpmul_mont(a, tt, t[0]); - fpmul_mont(t[0], tt, t[1]); - fpmul_mont(t[1], tt, t[2]); - fpmul_mont(t[2], tt, t[3]); - fpmul_mont(t[3], tt, t[3]); - for (i = 3; i <= 8; i++) fpmul_mont(t[i], tt, t[i + 1]); - fpmul_mont(t[9], tt, t[9]); - for (i = 9; i <= 20; i++) fpmul_mont(t[i], tt, t[i + 1]); - fpmul_mont(t[21], tt, t[21]); - for (i = 21; i <= 24; i++) fpmul_mont(t[i], tt, t[i + 1]); - fpmul_mont(t[25], tt, t[25]); - fpmul_mont(t[25], tt, t[26]); - - fpcopy(a, 0, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[20], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[24], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[11], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[8], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[2], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[23], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[2], tt, tt); - for (i = 0; i < 9; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[2], tt, tt); - for (i = 0; i < 10; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[15], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[13], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[26], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[20], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[11], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[10], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[14], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[4], tt, tt); - for (i = 0; i < 10; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[18], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[1], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[22], tt, tt); - for (i = 0; i < 10; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[6], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[24], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[9], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[18], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[17], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(a, tt, tt); - for (i = 0; i < 10; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[16], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[7], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[0], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[12], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[19], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[22], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[25], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[2], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[10], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[22], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[18], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[4], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[14], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[13], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[5], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[23], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[21], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[2], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[23], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[12], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[9], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[3], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[13], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[17], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[26], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[5], tt, tt); - for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[8], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[2], tt, tt); - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[11], tt, tt); - for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[20], tt, tt); - for (j = 0; j < 61; j++) - { - for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); - fpmul_mont(t[26], tt, tt); - } - fpcopy(tt,0, a); - } - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/Internal.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/Internal.java deleted file mode 100644 index d4865c2a62..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/Internal.java +++ /dev/null @@ -1,197 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import java.util.Properties; - -import org.bouncycastle.util.Pack; -import org.bouncycastle.util.encoders.Hex; - -abstract class Internal -{ - protected static final int RADIX = 64; - protected static final int LOG2RADIX = 6; - - protected int CRYPTO_PUBLICKEYBYTES; - protected int CRYPTO_CIPHERTEXTBYTES; - protected int CRYPTO_BYTES; - protected int CRYPTO_SECRETKEYBYTES; - - - protected int NWORDS_FIELD; // Number of words of a n-bit field element - protected int PRIME_ZERO_WORDS; // Number of "0" digits in the least significant part of PRIME + 1 - protected int NBITS_FIELD; - protected int MAXBITS_FIELD; - protected int MAXWORDS_FIELD; // Max. number of words to represent field elements - protected int NWORDS64_FIELD; // Number of 64-bit words of a 434-bit field element - protected int NBITS_ORDER; - protected int NWORDS_ORDER; // Number of words of oA and oB, where oA and oB are the subgroup orders of Alice and Bob, resp. - protected int NWORDS64_ORDER; // Number of 64-bit words of a x-bit element - protected int MAXBITS_ORDER; - protected int ALICE; - protected int BOB; - protected int OALICE_BITS; - protected int OBOB_BITS; - protected int OBOB_EXPON; - protected int MASK_ALICE; - protected int MASK_BOB; - protected int PARAM_A; - protected int PARAM_C; - - // Fixed parameters for isogeny tree computation - protected int MAX_INT_POINTS_ALICE; - protected int MAX_INT_POINTS_BOB; - protected int MAX_Alice; - protected int MAX_Bob; - protected int MSG_BYTES; - protected int SECRETKEY_A_BYTES; - protected int SECRETKEY_B_BYTES; - protected int FP2_ENCODED_BYTES; - - protected boolean COMPRESS; - - // Compressed Parameters - protected int MASK2_BOB; - protected int MASK3_BOB; - protected int ORDER_A_ENCODED_BYTES; - protected int ORDER_B_ENCODED_BYTES; - protected int PARTIALLY_COMPRESSED_CHUNK_CT; - protected int COMPRESSED_CHUNK_CT; - protected int UNCOMPRESSEDPK_BYTES; - // Table sizes used by the Entangled basis generation - protected int TABLE_R_LEN; - protected int TABLE_V_LEN; - protected int TABLE_V3_LEN; - // Parameters for discrete log computations - // Binary Pohlig-Hellman reduced to smaller logs of order ell^W - protected int W_2; - protected int W_3; - // ell^w - protected int ELL2_W; - protected int ELL3_W; - // ell^(e mod w) - protected int ELL2_EMODW; - protected int ELL3_EMODW; - // # of digits in the discrete log - protected int DLEN_2; // ceil(eA/W_2) - protected int DLEN_3; // ceil(eB/W_3) - // Use compressed tables: FULL_SIGNED - - - // Encoding of field elements - protected int PLEN_2; - protected int PLEN_3; - - protected long[] PRIME; - protected long[] PRIMEx2; - protected long[] PRIMEx4; - protected long[] PRIMEp1; - protected long[] PRIMEx16p; - protected long[] PRIMEp1x64; - protected long[] Alice_order; // Order of Alice's subgroup - protected long[] Bob_order; // Order of Bob's subgroup - protected long[] A_gen; // Alice's generator values {XPA0 + XPA1*iL, XQA0 + xQA1*iL, XRA0 + XRA1*i} in GF(p^2)L, expressed in Montgomery representation - protected long[] B_gen; // Bob's generator values {XPB0L, XQB0L, XRB0 + XRB1*i} in GF(p^2)L, expressed in Montgomery representation - protected long[] Montgomery_R2; // Montgomery constant Montgomery_R2 = (2^448)^2 mod p434 - protected long[] Montgomery_one; // Value one in Montgomery representation - - // Fixed parameters for isogeny tree computation - protected int[] strat_Alice; - protected int[] strat_Bob; - - //Compressed Encodings - //todo: abstract this more? - protected long[] XQB3; - protected long[] A_basis_zero; - protected long[] B_basis_zero; - protected long[] B_gen_3_tors; - protected long[] g_R_S_im; - protected long[] g_phiR_phiS_re; - protected long[] g_phiR_phiS_im; - protected long[] Montgomery_R; - protected long[] Montgomery_RB1; - protected long[] Montgomery_RB2; - protected long[] threeinv; - protected int[] ph2_path; - protected int[] ph3_path; - protected long[] u_entang; - protected long[] u0_entang; - protected long[][] table_r_qr; - protected long[][] table_r_qnr; - protected long[][] table_v_qr; - protected long[][] table_v_qnr; - protected long[][][] v_3_torsion; - - protected long[] T_tate3; - protected long[] T_tate2_firststep_P; - protected long[] T_tate2_P; - protected long[] T_tate2_firststep_Q; - protected long[] T_tate2_Q; - - ///Compressed Dlogs - protected long[] ph2_T; - protected long[] ph2_T1; - protected long[] ph2_T2; - protected long[] ph3_T; - protected long[] ph3_T1; - protected long[] ph3_T2; - - - static protected int[] ReadIntsFromProperty(Properties props, String key, int intSize) - { - int[] ints = new int[intSize]; - String s = props.getProperty(key); - String[] vals = s.split(","); - for (int i = 0; i != vals.length; i++) - { - ints[i] = Integer.parseInt(vals[i]); - } - return ints; - } - - static protected long[] ReadFromProperty(Properties props, String key, int longSize) - { - String s = props.getProperty(key); - s = s.replaceAll(",", ""); - byte[] bytes = Hex.decode(s); - long[] longs = new long[longSize]; - for (int i = 0; i < bytes.length / 8; i++) - { - longs[i] = Pack.bigEndianToLong(bytes, i * 8); - } - return longs; - } - - static protected long[][] ReadFromProperty(Properties props, String key, int d1Size, int d2Size) - { - String s = props.getProperty(key); - s = s.replaceAll(",", ""); - byte[] bytes = Hex.decode(s); - long[][] longs = new long[d1Size][d2Size]; - int i, j; - for (int x = 0; x < bytes.length / 8; x++) - { - i = x / d2Size; - j = x % d2Size; - longs[i][j] = Pack.bigEndianToLong(bytes, x * 8); - } - return longs; - } - - static protected long[][][] ReadFromProperty(Properties props, String key, int d1Size, int d2Size, int d3Size) - { - String s = props.getProperty(key); - s = s.replaceAll(",", ""); - byte[] bytes = Hex.decode(s); - long[][][] longs = new long[d1Size][d2Size][d3Size]; - int i, j, k; - for (int x = 0; x < bytes.length / 8; x++) - { - i = x / (d2Size * d3Size); - j = x % (d2Size * d3Size) / d3Size; - k = x % d3Size; - longs[i][j][k] = Pack.bigEndianToLong(bytes, x * 8); - } - return longs; - } - - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/Isogeny.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/Isogeny.java deleted file mode 100644 index 0de9a37b2f..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/Isogeny.java +++ /dev/null @@ -1,654 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -class Isogeny -{ - SIKEEngine engine; - Isogeny(SIKEEngine engine) - { - this.engine = engine; - } - - // Doubling of a Montgomery point in projective coordinates (X:Z) over affine curve coefficient A. - // Input: projective Montgomery x-coordinates P = (X1:Z1), where x1=X1/Z1 and Montgomery curve constants (A+2)/4. - // Output: projective Montgomery x-coordinates Q = 2*P = (X2:Z2). - protected void Double(PointProj P, PointProj Q, long[][] A24, int k) - { - long[][] temp = new long[2][engine.params.NWORDS_FIELD], - a = new long[2][engine.params.NWORDS_FIELD], - b = new long[2][engine.params.NWORDS_FIELD], - c = new long[2][engine.params.NWORDS_FIELD], - aa = new long[2][engine.params.NWORDS_FIELD], - bb = new long[2][engine.params.NWORDS_FIELD]; - engine.fpx.fp2copy(P.X, Q.X); - engine.fpx.fp2copy(P.Z, Q.Z); - - for (int j = 0; j < k; j++) - { - engine.fpx.fp2add(Q.X, Q.Z, a); - engine.fpx.fp2sub(Q.X, Q.Z, b); - engine.fpx.fp2sqr_mont(a, aa); - engine.fpx.fp2sqr_mont(b, bb); - engine.fpx.fp2sub(aa, bb, c); - engine.fpx.fp2mul_mont(aa, bb, Q.X); - engine.fpx.fp2mul_mont(A24, c, temp); - engine.fpx.fp2add(temp, bb, temp); - engine.fpx.fp2mul_mont(c, temp, Q.Z); - } - } - - protected void CompleteMPoint(long[][] A, PointProj P, PointProjFull R) - { // Given an xz-only representation on a montgomery curve, compute its affine representation - long[][] zero = new long[2][engine.params.NWORDS_FIELD], - one = new long[2][engine.params.NWORDS_FIELD], - xz = new long[2][engine.params.NWORDS_FIELD], - yz = new long[2][engine.params.NWORDS_FIELD], - s2 = new long[2][engine.params.NWORDS_FIELD], - r2 = new long[2][engine.params.NWORDS_FIELD], - invz = new long[2][engine.params.NWORDS_FIELD], - temp0 = new long[2][engine.params.NWORDS_FIELD], - temp1 = new long[2][engine.params.NWORDS_FIELD]; - - - engine.fpx.fpcopy(engine.params.Montgomery_one,0, one[0]); - - if (!Fpx.subarrayEquals(P.Z[0], zero[0], engine.params.NWORDS_FIELD) || !Fpx.subarrayEquals(P.Z[1], zero[1], engine.params.NWORDS_FIELD)) - { - engine.fpx.fp2mul_mont(P.X, P.Z, xz); // xz = x*z; - engine.fpx.fpsubPRIME(P.X[0], P.Z[1], temp0[0]); - engine.fpx.fpaddPRIME(P.X[1], P.Z[0], temp0[1]); - engine.fpx.fpaddPRIME(P.X[0], P.Z[1], temp1[0]); - engine.fpx.fpsubPRIME(P.X[1], P.Z[0], temp1[1]); - engine.fpx.fp2mul_mont(temp0, temp1, s2); // s2 = (x + i*z)*(x - i*z); - engine.fpx.fp2mul_mont(A, xz, temp0); - engine.fpx.fp2add(temp0, s2, temp1); - engine.fpx.fp2mul_mont(xz, temp1, r2); // r2 = xz*(A*xz + s2); - engine.fpx.sqrt_Fp2(r2, yz); - engine.fpx.fp2copy(P.Z, invz); - engine.fpx.fp2inv_mont_bingcd(invz); - engine.fpx.fp2mul_mont(P.X, invz, R.X); - engine.fpx.fp2sqr_mont(invz, temp0); - engine.fpx.fp2mul_mont(yz, temp0, R.Y); // R = EM![x*invz, yz*invz^2]; - engine.fpx.fp2copy(one, R.Z); - } - else - { - engine.fpx.fp2copy(zero, R.X); - engine.fpx.fp2copy(one, R.Y); - engine.fpx.fp2copy(zero, R.Z); // R = EM!0; - } - } - - void Ladder(PointProj P, long[] m, long[][] A, int order_bits, PointProj R) - { - PointProj R0 = new PointProj(engine.params.NWORDS_FIELD), - R1 = new PointProj(engine.params.NWORDS_FIELD); - long[][] A24 = new long[2][engine.params.NWORDS_FIELD]; - int bit = 0; - long mask; - int j, swap, prevbit = 0; - - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, A24[0]); - engine.fpx.fpaddPRIME(A24[0], A24[0], A24[0]); - engine.fpx.fp2add(A, A24, A24); - engine.fpx.fp2div2(A24, A24); - engine.fpx.fp2div2(A24, A24); // A24 = (A+2)/4 - - j = order_bits - 1; - bit = (int) ((m[j >> Internal.LOG2RADIX] >>> (j & (Internal.RADIX-1))) & 1); - while (bit == 0) - { - j--; - bit = (int) ((m[j >> Internal.LOG2RADIX] >>> (j & (Internal.RADIX-1))) & 1); - } - - // R0 <- P, R1 <- 2P - engine.fpx.fp2copy(P.X, R0.X); - engine.fpx.fp2copy(P.Z, R0.Z); - xDBL_e(P, R1, A24, 1); - - // Main loop - for (int i = j - 1; i >= 0; i--) - { - bit = (int) ((m[i >> Internal.LOG2RADIX] >>> (i & (Internal.RADIX-1))) & 1); - swap = bit ^ prevbit; - prevbit = bit; - mask = 0 - swap; - - swap_points(R0, R1, mask); - xDBLADD_proj(R0, R1, P.X, P.Z, A24); - } - swap = 0 ^ prevbit; - mask = 0 - swap; - swap_points(R0, R1, mask); - - engine.fpx.fp2copy(R0.X, R.X); - engine.fpx.fp2copy(R0.Z, R.Z); - } - - // Simultaneous doubling and differential addition. - // Input: projective Montgomery points P=(XP:ZP) and Q=(XQ:ZQ) such that xP=XP/ZP and xQ=XQ/ZQ, affine difference xPQ=x(P-Q) and Montgomery curve constant A24=(A+2)/4. - // Output: projective Montgomery points P <- 2*P = (X2P:Z2P) such that x(2P)=X2P/Z2P, and Q <- P+Q = (XQP:ZQP) such that = x(Q+P)=XQP/ZQP. - private void xDBLADD_proj(PointProj P, PointProj Q, long[][] XPQ, long[][] ZPQ, long[][] A24) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - t2 = new long[2][engine.params.NWORDS_FIELD]; - - - engine.fpx.fp2add(P.X, P.Z, t0); // t0 = XP+ZP - engine.fpx.fp2sub(P.X, P.Z, t1); // t1 = XP-ZP - engine.fpx.fp2sqr_mont(t0, P.X); // XP = (XP+ZP)^2 - engine.fpx.fp2sub(Q.X, Q.Z, t2); // t2 = XQ-ZQ - engine.fpx.fp2correction(t2); - engine.fpx.fp2add(Q.X, Q.Z, Q.X); // XQ = XQ+ZQ - engine.fpx.fp2mul_mont(t0, t2, t0); // t0 = (XP+ZP)*(XQ-ZQ) - engine.fpx.fp2sqr_mont(t1, P.Z); // ZP = (XP-ZP)^2 - engine.fpx.fp2mul_mont(t1, Q.X, t1); // t1 = (XP-ZP)*(XQ+ZQ) - engine.fpx.fp2sub(P.X, P.Z, t2); // t2 = (XP+ZP)^2-(XP-ZP)^2 - engine.fpx.fp2mul_mont(P.X, P.Z, P.X); // XP = (XP+ZP)^2*(XP-ZP)^2 - engine.fpx.fp2mul_mont(t2, A24, Q.X); // XQ = A24*[(XP+ZP)^2-(XP-ZP)^2] - engine.fpx.fp2sub(t0, t1, Q.Z); // ZQ = (XP+ZP)*(XQ-ZQ)-(XP-ZP)*(XQ+ZQ) - engine.fpx.fp2add(Q.X, P.Z, P.Z); // ZP = A24*[(XP+ZP)^2-(XP-ZP)^2]+(XP-ZP)^2 - engine.fpx.fp2add(t0, t1, Q.X); // XQ = (XP+ZP)*(XQ-ZQ)+(XP-ZP)*(XQ+ZQ) - engine.fpx.fp2mul_mont(P.Z, t2, P.Z); // ZP = [A24*[(XP+ZP)^2-(XP-ZP)^2]+(XP-ZP)^2]*[(XP+ZP)^2-(XP-ZP)^2] - engine.fpx.fp2sqr_mont(Q.Z, Q.Z); // ZQ = [(XP+ZP)*(XQ-ZQ)-(XP-ZP)*(XQ+ZQ)]^2 - engine.fpx.fp2sqr_mont(Q.X, Q.X); // XQ = [(XP+ZP)*(XQ-ZQ)+(XP-ZP)*(XQ+ZQ)]^2 - engine.fpx.fp2mul_mont(Q.X, ZPQ, Q.X); // XQ = ZPQ*[(XP+ZP)*(XQ-ZQ)+(XP-ZP)*(XQ+ZQ)]^2 - engine.fpx.fp2mul_mont(Q.Z, XPQ, Q.Z); // ZQ = XPQ*[(XP+ZP)*(XQ-ZQ)-(XP-ZP)*(XQ+ZQ)]^2 - } - - // Doubling of a Montgomery point in projective coordinates (X:Z) over affine curve coefficient A. - // Input: projective Montgomery x-coordinates P = (X1:Z1), where x1=X1/Z1 and Montgomery curve constants (A+2)/4. - // Output: projective Montgomery x-coordinates Q = 2*P = (X2:Z2). - private void xDBL_e(PointProj P, PointProj Q, long[][] A24, int e) - { - long[][] temp = new long[2][engine.params.NWORDS_FIELD], - a = new long[2][engine.params.NWORDS_FIELD], - b = new long[2][engine.params.NWORDS_FIELD], - c = new long[2][engine.params.NWORDS_FIELD], - aa = new long[2][engine.params.NWORDS_FIELD], - bb = new long[2][engine.params.NWORDS_FIELD]; - - - engine.fpx.fp2copy(P.X,Q.X); - engine.fpx.fp2copy(P.Z,Q.Z); - - for (int j = 0; j < e; j++) - { - engine.fpx.fp2add(Q.X, Q.Z, a); // a = xQ + zQ - engine.fpx.fp2sub(Q.X, Q.Z, b); // b = xQ - zQ - engine.fpx.fp2sqr_mont(a, aa); //aa = (xQ + zQ)^2 - engine.fpx.fp2sqr_mont(b, bb); //bb = (xQ - zQ)^2 - engine.fpx.fp2sub(aa, bb, c); // c = (xQ + zQ)^2 - (xQ - zQ)^2 - engine.fpx.fp2mul_mont(aa, bb, Q.X); // xQ = (xQ + zQ)^2 * (xQ - zQ)^2 - engine.fpx.fp2mul_mont(A24, c, temp); // temp = A24 * ((xQ + zQ)^2 - (xQ - zQ)^2) - engine.fpx.fp2add(temp, bb, temp); // temp = A24 * ((xQ + zQ)^2 - (xQ - zQ)^2) + (xQ - zQ)^2 - engine.fpx.fp2mul_mont(c, temp, Q.Z); // temp = (A24 * ((xQ + zQ)^2 - (xQ - zQ)^2) + (xQ - zQ)^2) * ((xQ + zQ)^2 - (xQ - zQ)^2) - } - } - - // Computes [3^e](X:Z) on Montgomery curve with projective constant via e repeated triplings. e triplings in E costs k*(5M + 6S + 9A) - // Input: projective Montgomery x-coordinates P = (X:Z), where x=X/Z, Montgomery curve constant A2 = A/2 and the number of triplings e. - // Output: projective Montgomery x-coordinates Q <- [3^e]P. - void xTPLe_fast(PointProj P, PointProj Q, long[][] A2, int e) - { - PointProj T = new PointProj(engine.params.NWORDS_FIELD); - - engine.fpx.copy_words(P, T); - for (int j = 0; j < e; j++) - { - xTPL_fast(T, T, A2); - } - engine.fpx.copy_words(T, Q); - } - - // Montgomery curve (E: y^2 = x^3 + A*x^2 + x) x-only tripling at a cost 5M + 6S + 9A = 27p + 61a. - // Input : projective Montgomery x-coordinates P = (X:Z), where x=X/Z and Montgomery curve constant A/2. - // Output: projective Montgomery x-coordinates Q = 3*P = (X3:Z3). - private void xTPL_fast(PointProj P, PointProj Q, long[][] A2) - { - long[][] t1 = new long[2][engine.params.NWORDS_FIELD], - t2 = new long[2][engine.params.NWORDS_FIELD], - t3 = new long[2][engine.params.NWORDS_FIELD], - t4 = new long[2][engine.params.NWORDS_FIELD]; - - - engine.fpx.fp2sqr_mont(P.X, t1); // t1 = x^2 - engine.fpx.fp2sqr_mont(P.Z, t2); // t2 = z^2 - engine.fpx.fp2add(t1, t2, t3); // t3 = t1 + t2 - engine.fpx.fp2add(P.X, P.Z, t4); // t4 = x + z - engine.fpx.fp2sqr_mont(t4, t4); // t4 = t4^2 - engine.fpx.fp2sub(t4, t3, t4); // t4 = t4 - t3 - engine.fpx.fp2mul_mont(A2, t4, t4); // t4 = t4*A2 - engine.fpx.fp2add(t3, t4, t4); // t4 = t4 + t3 - engine.fpx.fp2sub(t1, t2, t3); // t3 = t1 - t2 - engine.fpx.fp2sqr_mont(t3, t3); // t3 = t3^2 - engine.fpx.fp2mul_mont(t1, t4, t1); // t1 = t1*t4 - engine.fpx.fp2shl(t1, 2, t1); // t1 = 4*t1 - engine.fpx.fp2sub(t1, t3, t1); // t1 = t1 - t3 - engine.fpx.fp2sqr_mont(t1, t1); // t1 = t1^2 - engine.fpx.fp2mul_mont(t2, t4, t2); // t2 = t2*t4 - engine.fpx.fp2shl(t2, 2, t2); // t2 = 4*t2 - engine.fpx.fp2sub(t2, t3, t2); // t2 = t2 - t3 - engine.fpx.fp2sqr_mont(t2, t2); // t2 = t2^2 - engine.fpx.fp2mul_mont(P.X, t2, Q.X); // x = x*t2 - engine.fpx.fp2mul_mont(P.Z, t1, Q.Z); // z = z*t1 - } - - - protected void LADDER3PT(long[][] xP, long[][] xQ, long[][] xPQ, long[] m, int AliceOrBob, PointProj R, long[][] A) - { - PointProj R0 = new PointProj(engine.params.NWORDS_FIELD), - R2 = new PointProj(engine.params.NWORDS_FIELD); - long[][] A24 = new long[2][engine.params.NWORDS_FIELD]; - long mask; - int i, nbits, bit, swap, prevbit = 0; - - if (AliceOrBob == engine.params.ALICE) - { - nbits = engine.params.OALICE_BITS; - } else - { - nbits = engine.params.OBOB_BITS - 1; - } - - // Initializing constant - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, A24[0]); - engine.fpx.mp2_add(A24, A24, A24); - engine.fpx.mp2_add(A, A24, A24); - engine.fpx.fp2div2(A24, A24); - engine.fpx.fp2div2(A24, A24); // A24 = (A+2)/4 - - // Initializing points - engine.fpx.fp2copy(xQ, R0.X); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, R0.Z[0]); - engine.fpx.fp2copy(xPQ, R2.X); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, R2.Z[0]); - engine.fpx.fp2copy(xP, R.X); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, R.Z[0]); - engine.fpx.fpzero((R.Z)[1]); - - // Main loop - for (i = 0; i < nbits; i++) - { - bit = (int) ((m[i >>> Internal.LOG2RADIX] >>> (i & (Internal.RADIX-1))) & 1); - swap = bit ^ prevbit; - prevbit = bit; - mask = 0 - (long) swap; - swap_points(R, R2, mask); - xDBLADD(R0, R2, R.X, A24); - engine.fpx.fp2mul_mont(R2.X, R.Z, R2.X); - } - swap = 0 ^ prevbit; - mask = 0 - (long)swap; - swap_points(R, R2, mask); - } - - // Complete point on A = 0 curve - protected void CompletePoint(PointProj P, PointProjFull R) - { - long[][] xz = new long[2][engine.params.NWORDS_FIELD], - s2 = new long[2][engine.params.NWORDS_FIELD], - r2 = new long[2][engine.params.NWORDS_FIELD], - yz = new long[2][engine.params.NWORDS_FIELD], - invz = new long[2][engine.params.NWORDS_FIELD], - t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - one = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, one[0]); - engine.fpx.fp2mul_mont(P.X, P.Z, xz); - engine.fpx.fpsubPRIME(P.X[0], P.Z[1], t0[0]); - engine.fpx.fpaddPRIME(P.X[1], P.Z[0], t0[1]); - engine.fpx.fpaddPRIME(P.X[0], P.Z[1], t1[0]); - engine.fpx.fpsubPRIME(P.X[1], P.Z[0], t1[1]); - engine.fpx.fp2mul_mont(t0, t1, s2); - engine.fpx.fp2mul_mont(xz, s2, r2); - engine.fpx.sqrt_Fp2(r2, yz); - engine.fpx.fp2copy(P.Z,invz); - engine.fpx.fp2inv_mont_bingcd(invz); - engine.fpx.fp2mul_mont(P.X, invz, R.X); - engine.fpx.fp2sqr_mont(invz, t0); - engine.fpx.fp2mul_mont(yz, t0, R.Y); - engine.fpx.fp2copy(one, R.Z); - } - - - // Swap points. - // If option = 0 then P <- P and Q <- Q, else if option = 0xFF...FF then P <- Q and Q <- P - protected void swap_points(PointProj P, PointProj Q, long option) - { - long temp; - int i; - - for (i = 0; i < engine.params.NWORDS_FIELD; i++) - { - temp = option & (P.X[0][i] ^ Q.X[0][i]); - P.X[0][i] = temp ^ P.X[0][i]; - Q.X[0][i] = temp ^ Q.X[0][i]; - temp = option & (P.X[1][i] ^ Q.X[1][i]); - P.X[1][i] = temp ^ P.X[1][i]; - Q.X[1][i] = temp ^ Q.X[1][i]; - temp = option & (P.Z[0][i] ^ Q.Z[0][i]); - P.Z[0][i] = temp ^ P.Z[0][i]; - Q.Z[0][i] = temp ^ Q.Z[0][i]; - temp = option & (P.Z[1][i] ^ Q.Z[1][i]); - P.Z[1][i] = temp ^ P.Z[1][i]; - Q.Z[1][i] = temp ^ Q.Z[1][i]; - } - } - - // Simultaneous doubling and differential addition. - // Input: projective Montgomery points P=(XP:ZP) and Q=(XQ:ZQ) such that xP=XP/ZP and xQ=XQ/ZQ, affine difference xPQ=x(P-Q) and Montgomery curve constant A24=(A+2)/4. - // Output: projective Montgomery points P <- 2*P = (X2P:Z2P) such that x(2P)=X2P/Z2P, and Q <- P+Q = (XQP:ZQP) such that = x(Q+P)=XQP/ZQP. - protected void xDBLADD(PointProj P, PointProj Q, long[][] xPQ, long[][] A24) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - t2 = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.mp2_add(P.X, P.Z, t0); // t0 = XP+ZP - engine.fpx.mp2_sub_p2(P.X, P.Z, t1); // t1 = XP-ZP - engine.fpx.fp2sqr_mont(t0, P.X); // XP = (XP+ZP)^2 - engine.fpx.mp2_sub_p2(Q.X, Q.Z, t2); // t2 = XQ-ZQ - engine.fpx.mp2_add(Q.X, Q.Z, Q.X); // XQ = XQ+ZQ - engine.fpx.fp2mul_mont(t0, t2, t0); // t0 = (XP+ZP)*(XQ-ZQ) - engine.fpx.fp2sqr_mont(t1, P.Z); // ZP = (XP-ZP)^2 - engine.fpx.fp2mul_mont(t1, Q.X, t1); // t1 = (XP-ZP)*(XQ+ZQ) - engine.fpx.mp2_sub_p2(P.X, P.Z, t2); // t2 = (XP+ZP)^2-(XP-ZP)^2 - engine.fpx.fp2mul_mont(P.X, P.Z, P.X); // XP = (XP+ZP)^2*(XP-ZP)^2 - engine.fpx.fp2mul_mont(A24, t2, Q.X); // XQ = A24*[(XP+ZP)^2-(XP-ZP)^2] - engine.fpx.mp2_sub_p2(t0, t1, Q.Z); // ZQ = (XP+ZP)*(XQ-ZQ)-(XP-ZP)*(XQ+ZQ) - engine.fpx.mp2_add(Q.X, P.Z, P.Z); // ZP = A24*[(XP+ZP)^2-(XP-ZP)^2]+(XP-ZP)^2 - engine.fpx.mp2_add(t0, t1, Q.X); // XQ = (XP+ZP)*(XQ-ZQ)+(XP-ZP)*(XQ+ZQ) - engine.fpx.fp2mul_mont(P.Z, t2, P.Z); // ZP = [A24*[(XP+ZP)^2-(XP-ZP)^2]+(XP-ZP)^2]*[(XP+ZP)^2-(XP-ZP)^2] - engine.fpx.fp2sqr_mont(Q.Z, Q.Z); // ZQ = [(XP+ZP)*(XQ-ZQ)-(XP-ZP)*(XQ+ZQ)]^2 - engine.fpx.fp2sqr_mont(Q.X, Q.X); // XQ = [(XP+ZP)*(XQ-ZQ)+(XP-ZP)*(XQ+ZQ)]^2 - engine.fpx.fp2mul_mont(Q.Z, xPQ, Q.Z); // ZQ = xPQ*[(XP+ZP)*(XQ-ZQ)-(XP-ZP)*(XQ+ZQ)]^2 - } - - // Computes [2^e](X:Z) on Montgomery curve with projective constant via e repeated doublings. - // Input: projective Montgomery x-coordinates P = (XP:ZP), such that xP=XP/ZP and Montgomery curve constants A+2C and 4C. - // Output: projective Montgomery x-coordinates Q <- (2^e)*P. - protected void xDBLe(PointProj P, PointProj Q, long[][] A24plus, long[][] C24, int e) - { - int i; - engine.fpx.copy_words(P, Q); - - for (i = 0; i < e; i++) - { - xDBL(Q, Q, A24plus, C24); - } - } - - // Doubling of a Montgomery point in projective coordinates (X:Z). - // Input: projective Montgomery x-coordinates P = (X1:Z1), where x1=X1/Z1 and Montgomery curve constants A+2C and 4C. - // Output: projective Montgomery x-coordinates Q = 2*P = (X2:Z2). - protected void xDBL(PointProj P, PointProj Q, long[][] A24plus, long[][] C24) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.mp2_sub_p2(P.X, P.Z, t0); // t0 = X1-Z1 - engine.fpx.mp2_add(P.X, P.Z, t1); // t1 = X1+Z1 - engine.fpx.fp2sqr_mont(t0, t0); // t0 = (X1-Z1)^2 - engine.fpx.fp2sqr_mont(t1, t1); // t1 = (X1+Z1)^2 - engine.fpx.fp2mul_mont(C24, t0, Q.Z); // Z2 = C24*(X1-Z1)^2 - engine.fpx.fp2mul_mont(t1, Q.Z, Q.X); // X2 = C24*(X1-Z1)^2*(X1+Z1)^2 - engine.fpx.mp2_sub_p2(t1, t0, t1); // t1 = (X1+Z1)^2-(X1-Z1)^2 - engine.fpx.fp2mul_mont(A24plus, t1, t0); // t0 = A24plus*[(X1+Z1)^2-(X1-Z1)^2] - engine.fpx.mp2_add(Q.Z, t0, Q.Z); // Z2 = A24plus*[(X1+Z1)^2-(X1-Z1)^2] + C24*(X1-Z1)^2 - engine.fpx.fp2mul_mont(Q.Z, t1, Q.Z); // Z2 = [A24plus*[(X1+Z1)^2-(X1-Z1)^2] + C24*(X1-Z1)^2]*[(X1+Z1)^2-(X1-Z1)^2] - } - - // Tripling of a Montgomery point in projective coordinates (X:Z). - // Input: projective Montgomery x-coordinates P = (X:Z), where x=X/Z and Montgomery curve constants A24plus = A+2C and A24minus = A-2C. - // Output: projective Montgomery x-coordinates Q = 3*P = (X3:Z3). - private void xTPL(PointProj P, PointProj Q, long[][] A24minus, long[][] A24plus) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - t2 = new long[2][engine.params.NWORDS_FIELD], - t3 = new long[2][engine.params.NWORDS_FIELD], - t4 = new long[2][engine.params.NWORDS_FIELD], - t5 = new long[2][engine.params.NWORDS_FIELD], - t6 = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.mp2_sub_p2(P.X, P.Z, t0); // t0 = X-Z - engine.fpx.fp2sqr_mont(t0, t2); // t2 = (X-Z)^2 - engine.fpx.mp2_add(P.X, P.Z, t1); // t1 = X+Z - engine.fpx.fp2sqr_mont(t1, t3); // t3 = (X+Z)^2 - engine.fpx.mp2_add(P.X, P.X, t4); // t4 = 2*X - engine.fpx.mp2_add(P.Z, P.Z, t0); // t0 = 2*Z - engine.fpx.fp2sqr_mont(t4, t1); // t1 = 4*X^2 - engine.fpx.mp2_sub_p2(t1, t3, t1); // t1 = 4*X^2 - (X+Z)^2 - engine.fpx.mp2_sub_p2(t1, t2, t1); // t1 = 4*X^2 - (X+Z)^2 - (X-Z)^2 - engine.fpx.fp2mul_mont(A24plus, t3, t5); // t5 = A24plus*(X+Z)^2 - engine.fpx.fp2mul_mont(t3, t5, t3); // t3 = A24plus*(X+Z)^4 - engine.fpx.fp2mul_mont(A24minus, t2, t6); // t6 = A24minus*(X-Z)^2 - engine.fpx.fp2mul_mont(t2, t6, t2); // t2 = A24minus*(X-Z)^4 - engine.fpx.mp2_sub_p2(t2, t3, t3); // t3 = A24minus*(X-Z)^4 - A24plus*(X+Z)^4 - engine.fpx.mp2_sub_p2(t5, t6, t2); // t2 = A24plus*(X+Z)^2 - A24minus*(X-Z)^2 - engine.fpx.fp2mul_mont(t1, t2, t1); // t1 = [4*X^2 - (X+Z)^2 - (X-Z)^2]*[A24plus*(X+Z)^2 - A24minus*(X-Z)^2] - engine.fpx.fp2add(t3, t1, t2); // t2 = [4*X^2 - (X+Z)^2 - (X-Z)^2]*[A24plus*(X+Z)^2 - A24minus*(X-Z)^2] + A24minus*(X-Z)^4 - A24plus*(X+Z)^4 - engine.fpx.fp2sqr_mont(t2, t2); // t2 = t2^2 - engine.fpx.fp2mul_mont(t4, t2, Q.X); // X3 = 2*X*t2 - engine.fpx.fp2sub(t3, t1, t1); // t1 = A24minus*(X-Z)^4 - A24plus*(X+Z)^4 - [4*X^2 - (X+Z)^2 - (X-Z)^2]*[A24plus*(X+Z)^2 - A24minus*(X-Z)^2] - engine.fpx.fp2sqr_mont(t1, t1); // t1 = t1^2 - engine.fpx.fp2mul_mont(t0, t1, Q.Z); // Z3 = 2*Z*t1 - } - - // Computes [3^e](X:Z) on Montgomery curve with projective constant via e repeated triplings. - // Input: projective Montgomery x-coordinates P = (XP:ZP), such that xP=XP/ZP and Montgomery curve constants A24plus = A+2C and A24minus = A-2C. - // Output: projective Montgomery x-coordinates Q <- (3^e)*P. - protected void xTPLe(PointProj P, PointProj Q, long[][] A24minus, long[][] A24plus, int e) - { - int i; - engine.fpx.copy_words(P, Q); - for (i = 0; i < e; i++) - { - xTPL(Q, Q, A24minus, A24plus); - } - } - - // Given the x-coordinates of P, Q, and R, returns the value A corresponding to the Montgomery curve E_A: y^2=x^3+A*x^2+x such that R=Q-P on E_A. - // Input: the x-coordinates xP, xQ, and xR of the points P, Q and R. - // Output: the coefficient A corresponding to the curve E_A: y^2=x^3+A*x^2+x. - protected void get_A(long[][] xP, long[][] xQ, long[][] xR, long[][] A) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - one = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, one[0]); - engine.fpx.fp2add(xP, xQ, t1); // t1 = xP+xQ - engine.fpx.fp2mul_mont(xP, xQ, t0); // t0 = xP*xQ - engine.fpx.fp2mul_mont(xR, t1, A); // A = xR*t1 - engine.fpx.fp2add(t0, A, A); // A = A+t0 - engine.fpx.fp2mul_mont(t0, xR, t0); // t0 = t0*xR - engine.fpx.fp2sub(A, one, A); // A = A-1 - engine.fpx.fp2add(t0, t0, t0); // t0 = t0+t0 - engine.fpx.fp2add(t1, xR, t1); // t1 = t1+xR - engine.fpx.fp2add(t0, t0, t0); // t0 = t0+t0 - engine.fpx.fp2sqr_mont(A, A); // A = A^2 - engine.fpx.fp2inv_mont(t0); // t0 = 1/t0 - engine.fpx.fp2mul_mont(A, t0, A); // A = A*t0 - engine.fpx.fp2sub(A, t1, A); // Afinal = A-t1 - } - - // Computes the j-invariant of a Montgomery curve with projective constant. - // Input: A,C in GF(p^2). - // Output: j=256*(A^2-3*C^2)^3/(C^4*(A^2-4*C^2)), which is the j-invariant of the Montgomery curve B*y^2=x^3+(A/C)*x^2+x or (equivalently) j-invariant of B'*y^2=C*x^3+A*x^2+C*x. - protected void j_inv(long[][] A, long[][] C, long[][] jinv) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.fp2sqr_mont(A, jinv); // jinv = A^2 - engine.fpx.fp2sqr_mont(C, t1); // t1 = C^2 - engine.fpx.fp2add(t1, t1, t0); // t0 = t1+t1 - engine.fpx.fp2sub(jinv, t0, t0); // t0 = jinv-t0 - engine.fpx.fp2sub(t0, t1, t0); // t0 = t0-t1 - engine.fpx.fp2sub(t0, t1, jinv); // jinv = t0-t1 - engine.fpx.fp2sqr_mont(t1, t1); // t1 = t1^2 - engine.fpx.fp2mul_mont(jinv, t1, jinv); // jinv = jinv*t1 - engine.fpx.fp2add(t0, t0, t0); // t0 = t0+t0 - engine.fpx.fp2add(t0, t0, t0); // t0 = t0+t0 - engine.fpx.fp2sqr_mont(t0, t1); // t1 = t0^2 - engine.fpx.fp2mul_mont(t0, t1, t0); // t0 = t0*t1 - engine.fpx.fp2add(t0, t0, t0); // t0 = t0+t0 - engine.fpx.fp2add(t0, t0, t0); // t0 = t0+t0 - engine.fpx.fp2inv_mont(jinv); // jinv = 1/jinv - engine.fpx.fp2mul_mont(jinv, t0, jinv); // jinv = t0*jinv - } - - - - // Computes the corresponding 3-isogeny of a projective Montgomery point (X3:Z3) of order 3. - // Input: projective point of order three P = (X3:Z3). - // Output: the 3-isogenous Montgomery curve with projective coefficient A/C. - protected void get_3_isog(PointProj P, long[][] A24minus, long[][] A24plus, long[][][] coeff) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - t2 = new long[2][engine.params.NWORDS_FIELD], - t3 = new long[2][engine.params.NWORDS_FIELD], - t4 = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.mp2_sub_p2(P.X, P.Z, coeff[0]); // coeff0 = X-Z - engine.fpx.fp2sqr_mont(coeff[0], t0); // t0 = (X-Z)^2 - engine.fpx.mp2_add(P.X, P.Z, coeff[1]); // coeff1 = X+Z - engine.fpx.fp2sqr_mont(coeff[1], t1); // t1 = (X+Z)^2 - engine.fpx.mp2_add(P.X, P.X, t3); // t3 = 2*X - engine.fpx.fp2sqr_mont(t3, t3); // t3 = 4*X^2 - engine.fpx.fp2sub(t3, t0, t2); // t2 = 4*X^2 - (X-Z)^2 - engine.fpx.fp2sub(t3, t1, t3); // t3 = 4*X^2 - (X+Z)^2 - engine.fpx.mp2_add(t0, t3, t4); // t4 = 4*X^2 - (X+Z)^2 + (X-Z)^2 - engine.fpx.mp2_add(t4, t4, t4); // t4 = 2(4*X^2 - (X+Z)^2 + (X-Z)^2) - engine.fpx.mp2_add(t1, t4, t4); // t4 = 8*X^2 - (X+Z)^2 + 2*(X-Z)^2 - engine.fpx.fp2mul_mont(t2, t4, A24minus); // A24minus = [4*X^2 - (X-Z)^2]*[8*X^2 - (X+Z)^2 + 2*(X-Z)^2] - engine.fpx.mp2_add(t1, t2, t4); // t4 = 4*X^2 + (X+Z)^2 - (X-Z)^2 - engine.fpx.mp2_add(t4, t4, t4); // t4 = 2(4*X^2 + (X+Z)^2 - (X-Z)^2) - engine.fpx.mp2_add(t0, t4, t4); // t4 = 8*X^2 + 2*(X+Z)^2 - (X-Z)^2 - engine.fpx.fp2mul_mont(t3, t4, A24plus); // A24plus = [4*X^2 - (X+Z)^2]*[8*X^2 + 2*(X+Z)^2 - (X-Z)^2] - } - - // Computes the 3-isogeny R=phi(X:Z), given projective point (X3:Z3) of order 3 on a Montgomery curve and - // a point P with 2 coefficients in coeff (computed in the function get_3_isog()). - // Inputs: projective points P = (X3:Z3) and Q = (X:Z). - // Output: the projective point Q <- phi(Q) = (X3:Z3). - protected void eval_3_isog(PointProj Q, long[][][] coeff) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - t2 = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.mp2_add(Q.X, Q.Z, t0); // t0 = X+Z - engine.fpx.mp2_sub_p2(Q.X, Q.Z, t1); // t1 = X-Z - engine.fpx.fp2mul_mont(coeff[0], t0, t0); // t0 = coeff0*(X+Z) - engine.fpx.fp2mul_mont(coeff[1], t1, t1); // t1 = coeff1*(X-Z) - engine.fpx.mp2_add(t0, t1, t2); // t2 = coeff0*(X+Z) + coeff1*(X-Z) - engine.fpx.mp2_sub_p2(t1, t0, t0); // t0 = coeff1*(X-Z) - coeff0*(X+Z) - engine.fpx.fp2sqr_mont(t2, t2); // t2 = [coeff0*(X+Z) + coeff1*(X-Z)]^2 - engine.fpx.fp2sqr_mont(t0, t0); // t0 = [coeff1*(X-Z) - coeff0*(X+Z)]^2 - engine.fpx.fp2mul_mont(Q.X, t2, Q.X); // X3final = X*[coeff0*(X+Z) + coeff1*(X-Z)]^2 - engine.fpx.fp2mul_mont(Q.Z, t0, Q.Z); // Z3final = Z*[coeff1*(X-Z) - coeff0*(X+Z)]^2 - } - - // 3-way simultaneous inversion - // Input: z1,z2,z3 - // Output: 1/z1,1/z2,1/z3 (override inputs). - protected void inv_3_way(long[][] z1, long[][] z2, long[][] z3) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - t2 = new long[2][engine.params.NWORDS_FIELD], - t3 = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.fp2mul_mont(z1, z2, t0); // t0 = z1*z2 - engine.fpx.fp2mul_mont(z3, t0, t1); // t1 = z1*z2*z3 - engine.fpx.fp2inv_mont(t1); // t1 = 1/(z1*z2*z3) - engine.fpx.fp2mul_mont(z3, t1, t2); // t2 = 1/(z1*z2) - engine.fpx.fp2mul_mont(t2, z2, t3); // t3 = 1/z1 - engine.fpx.fp2mul_mont(t2, z1, z2); // z2 = 1/z2 - engine.fpx.fp2mul_mont(t0, t1, z3); // z3 = 1/z3 - engine.fpx.fp2copy(t3, z1); // z1 = 1/z1 - } - - // Computes the corresponding 2-isogeny of a projective Montgomery point (X2:Z2) of order 2. - // Input: projective point of order two P = (X2:Z2). - // Output: the 2-isogenous Montgomery curve with projective coefficients A/C. - protected void get_2_isog(PointProj P, long[][] A, long[][] C) - { - engine.fpx.fp2sqr_mont(P.X, A); // A = X2^2 - engine.fpx.fp2sqr_mont(P.Z, C); // C = Z2^2 - engine.fpx.mp2_sub_p2(C, A, A); // A = Z2^2 - X2^2 - } - - // Evaluates the isogeny at the point (X:Z) in the domain of the isogeny, given a 2-isogeny phi. - // Inputs: the projective point P = (X:Z) and the 2-isogeny kernel projetive point Q = (X2:Z2). - // Output: the projective point P = phi(P) = (X:Z) in the codomain. - protected void eval_2_isog(PointProj P, PointProj Q) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - t2 = new long[2][engine.params.NWORDS_FIELD], - t3 = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.mp2_add(Q.X, Q.Z, t0); // t0 = X2+Z2 - engine.fpx.mp2_sub_p2(Q.X, Q.Z, t1); // t1 = X2-Z2 - engine.fpx.mp2_add(P.X, P.Z, t2); // t2 = X+Z - engine.fpx.mp2_sub_p2(P.X, P.Z, t3); // t3 = X-Z - engine.fpx.fp2mul_mont(t0, t3, t0); // t0 = (X2+Z2)*(X-Z) - engine.fpx.fp2mul_mont(t1, t2, t1); // t1 = (X2-Z2)*(X+Z) - engine.fpx.mp2_add(t0, t1, t2); // t2 = (X2+Z2)*(X-Z) + (X2-Z2)*(X+Z) - engine.fpx.mp2_sub_p2(t0, t1, t3); // t3 = (X2+Z2)*(X-Z) - (X2-Z2)*(X+Z) - engine.fpx.fp2mul_mont(P.X, t2, P.X); // Xfinal - engine.fpx.fp2mul_mont(P.Z, t3, P.Z); // Zfinal - } - - // Computes the corresponding 4-isogeny of a projective Montgomery point (X4:Z4) of order 4. - // Input: projective point of order four P = (X4:Z4). - // Output: the 4-isogenous Montgomery curve with projective coefficients A+2C/4C and the 3 coefficients - // that are used to evaluate the isogeny at a point in eval_4_isog(). - protected void get_4_isog(PointProj P, long[][] A24plus, long[][] C24, long[][][] coeff) - { - engine.fpx.mp2_sub_p2(P.X, P.Z, coeff[1]); // coeff[1] = X4-Z4 - engine.fpx.mp2_add(P.X, P.Z, coeff[2]); // coeff[2] = X4+Z4 - engine.fpx.fp2sqr_mont(P.Z, coeff[0]); // coeff[0] = Z4^2 - engine.fpx.mp2_add(coeff[0], coeff[0], coeff[0]); // coeff[0] = 2*Z4^2 - engine.fpx.fp2sqr_mont(coeff[0], C24); // C24 = 4*Z4^4 - engine.fpx.mp2_add(coeff[0], coeff[0], coeff[0]); // coeff[0] = 4*Z4^2 - engine.fpx.fp2sqr_mont(P.X, A24plus); // A24plus = X4^2 - engine.fpx.mp2_add(A24plus, A24plus, A24plus); // A24plus = 2*X4^2 - engine.fpx.fp2sqr_mont(A24plus, A24plus); // A24plus = 4*X4^4 - } - - // Evaluates the isogeny at the point (X:Z) in the domain of the isogeny, given a 4-isogeny phi defined - // by the 3 coefficients in coeff (computed in the function get_4_isog()). - // Inputs: the coefficients defining the isogeny, and the projective point P = (X:Z). - // Output: the projective point P = phi(P) = (X:Z) in the codomain. - protected void eval_4_isog(PointProj P, long[][][] coeff) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.mp2_add(P.X, P.Z, t0); // t0 = X+Z - engine.fpx.mp2_sub_p2(P.X, P.Z, t1); // t1 = X-Z - engine.fpx.fp2mul_mont(t0, coeff[1], P.X); // X = (X+Z)*coeff[1] - engine.fpx.fp2mul_mont(t1, coeff[2], P.Z); // Z = (X-Z)*coeff[2] - engine.fpx.fp2mul_mont(t0, t1, t0); // t0 = (X+Z)*(X-Z) - engine.fpx.fp2mul_mont(coeff[0], t0, t0); // t0 = coeff[0]*(X+Z)*(X-Z) - engine.fpx.mp2_add(P.X, P.Z, t1); // t1 = (X-Z)*coeff[2] + (X+Z)*coeff[1] - engine.fpx.mp2_sub_p2(P.X, P.Z, P.Z); // Z = (X-Z)*coeff[2] - (X+Z)*coeff[1] - engine.fpx.fp2sqr_mont(t1, t1); // t1 = [(X-Z)*coeff[2] + (X+Z)*coeff[1]]^2 - engine.fpx.fp2sqr_mont(P.Z, P.Z); // Z = [(X-Z)*coeff[2] - (X+Z)*coeff[1]]^2 - engine.fpx.mp2_add(t1, t0, P.X); // X = coeff[0]*(X+Z)*(X-Z) + [(X-Z)*coeff[2] + (X+Z)*coeff[1]]^2 - engine.fpx.mp2_sub_p2(P.Z, t0, t0); // t0 = [(X-Z)*coeff[2] - (X+Z)*coeff[1]]^2 - coeff[0]*(X+Z)*(X-Z) - engine.fpx.fp2mul_mont(P.X, t1, P.X); // Xfinal - engine.fpx.fp2mul_mont(P.Z, t0, P.Z); // Zfinal - } - - - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/P434.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/P434.java deleted file mode 100644 index 1ce2cd6572..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/P434.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -class P434 - extends Internal -{ - // Encoding of field elementsL, elements over Z_orderL, elements over GF(p^2) and elliptic curve points: - // -------------------------------------------------------------------------------------------------- - // Elements over GF(p) and Z_order are encoded with the least significant octet (and digit) located at the leftmost position (i.e.L, little endian format). - // Elements (a+b*i) over GF(p^2)L, where a and b are defined over GF(p)L, are encoded as {aL, b}L, with a in the least significant position. - // Elliptic curve points P = (x,y) are encoded as {xL, y}L, with x in the least significant position. - // InternallyL, the number of digits used to represent all these elements is obtained by approximating the number of bits to the immediately greater multiple of 32. - // For exampleL, a 434-bit field element is represented with Ceil(434 / 64) = 7 64-bit digits or Ceil(434 / 32) = 14 32-bit digits. - - // - // Curve isogeny system "SIDHp434". Base curve: Montgomery curve By^2 = Cx^3 + Ax^2 + Cx defined over GF(p434^2)L, where A=6L, B=1L, C=1 and p434 = 2^216*3^137-1 - // - P434(boolean isCompressed) - { - super(); - this.COMPRESS = isCompressed; - CRYPTO_SECRETKEYBYTES = 374; - CRYPTO_PUBLICKEYBYTES = 330; - CRYPTO_BYTES = 16; - CRYPTO_CIPHERTEXTBYTES = 346; - if (isCompressed) - { - CRYPTO_SECRETKEYBYTES = 350; - CRYPTO_PUBLICKEYBYTES = 197; - CRYPTO_CIPHERTEXTBYTES = 236; - } - - - this.NWORDS_FIELD = 7; // Number of words of a 434-bit field element - this.PRIME_ZERO_WORDS = 3; // Number of "0" digits in the least significant part of p434 + 1 - - // Basic constants - - this.NBITS_FIELD = 434; - this.MAXBITS_FIELD = 448; - this.MAXWORDS_FIELD = ((MAXBITS_FIELD + RADIX - 1) / RADIX); // Max. number of words to represent field elements - this.NWORDS64_FIELD = ((NBITS_FIELD + 63) / 64); // Number of 64-bit words of a 434-bit field element; - this.NBITS_ORDER = 256; - this.NWORDS_ORDER = ((NBITS_ORDER + RADIX - 1) / RADIX); // Number of words of oA and oB, where oA and oB are the subgroup orders of Alice and Bob, resp.; - this.NWORDS64_ORDER = ((NBITS_ORDER + 63) / 64); // Number of 64-bit words of a 224-bit element; - this.MAXBITS_ORDER = NBITS_ORDER; - this.ALICE = 0; - this.BOB = 1; - this.OALICE_BITS = 216; - this.OBOB_BITS = 218; - this.OBOB_EXPON = 137; - this.MASK_ALICE = 0xFF; - this.MASK_BOB = 0x01; - this.PARAM_A = 6; - this.PARAM_C = 1; - // Fixed parameters for isogeny tree computation - this.MAX_INT_POINTS_ALICE = 7; - this.MAX_INT_POINTS_BOB = 8; - this.MAX_Alice = 108; - this.MAX_Bob = 137; - this.MSG_BYTES = 16; - this.SECRETKEY_A_BYTES = ((OALICE_BITS + 7) / 8); - this.SECRETKEY_B_BYTES = ((OBOB_BITS - 1 + 7) / 8); - this.FP2_ENCODED_BYTES = 2 * ((NBITS_FIELD + 7) / 8); - - PRIME = new long[]{0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFDC1767AE2FFFFFFL, 0x7BC65C783158AEA3L, 0x6CFC5FD681C52056L, 0x0002341F27177344L}; - PRIMEx2 = new long[]{0xFFFFFFFFFFFFFFFEL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFB82ECF5C5FFFFFFL, 0xF78CB8F062B15D47L, 0xD9F8BFAD038A40ACL, 0x0004683E4E2EE688L}; - PRIMEx4 = new long[]{0xFFFFFFFFFFFFFFFCL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xF705D9EB8BFFFFFFL, 0xEF1971E0C562BA8FL, 0xB3F17F5A07148159L, 0x0008D07C9C5DCD11L}; - PRIMEp1 = new long[]{0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0xFDC1767AE3000000L, 0x7BC65C783158AEA3L, 0x6CFC5FD681C52056L, 0x0002341F27177344L}; - PRIMEx16p = new long[]{0x0000000000000010L, 0x0000000000000000L, 0x0000000000000000L, 0x47D130A3A0000000L, 0x873470F9D4EA2B80L, 0x6074052FC75BF530L, 0x54497C1B1D119772L, 0xC55F373D2CDCA412L, 0x732CA2221C664B96L, 0x6445AB96AF6359A5L, 0x221708AB42ABE1B4L, 0xAE3D3D0063244F01L, 0x18B920F2ECF68816L, 0x0000004DB194809DL}; - Alice_order = new long[]{0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000001000000}; - Bob_order = new long[]{0x58AEA3FDC1767AE3L, 0xC520567BC65C7831L, 0x1773446CFC5FD681L, 0x0000000002341F27}; - A_gen = new long[]{0x05ADF455C5C345BFL, 0x91935C5CC767AC2BL, 0xAFE4E879951F0257L, 0x70E792DC89FA27B1L, 0xF797F526BB48C8CDL, 0x2181DB6131AF621FL, 0x00000A1C08B1ECC4L, 0x74840EB87CDA7788L, 0x2971AA0ECF9F9D0BL, 0xCB5732BDF41715D5L, 0x8CD8E51F7AACFFAAL, 0xA7F424730D7E419FL, 0xD671EB919A179E8CL, 0x0000FFA26C5A924AL, 0xFEC6E64588B7273BL, 0xD2A626D74CBBF1C6L, 0xF8F58F07A78098C7L, 0xE23941F470841B03L, 0x1B63EDA2045538DDL, 0x735CFEB0FFD49215L, 0x0001C4CB77542876L, 0xADB0F733C17FFDD6L, 0x6AFFBD037DA0A050L, 0x680EC43DB144E02FL, 0x1E2E5D5FF524E374L, 0xE2DDA115260E2995L, 0xA6E4B552E2EDE508L, 0x00018ECCDDF4B53EL, 0x01BA4DB518CD6C7DL, 0x2CB0251FE3CC0611L, 0x259B0C6949A9121BL, 0x60E17AC16D2F82ADL, 0x3AA41F1CE175D92DL, 0x413FBE6A9B9BC4F3L, 0x00022A81D8D55643L, 0xB8ADBC70FC82E54AL, 0xEF9CDDB0D5FADDEDL, 0x5820C734C80096A0L, 0x7799994BAA96E0E4L, 0x044961599E379AF8L, 0xDB2B94FBF09F27E2L, 0x0000B87FC716C0C6L}; - - - B_gen = new long[]{0x6E5497556EDD48A3L, 0x2A61B501546F1C05L, 0xEB919446D049887DL, 0x5864A4A69D450C4FL, 0xB883F276A6490D2BL, 0x22CC287022D5F5B9L, 0x0001BED4772E551FL, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0xFAE2A3F93D8B6B8EL, 0x494871F51700FE1CL, 0xEF1A94228413C27CL, 0x498FF4A4AF60BD62L, 0xB00AD2A708267E8AL, 0xF4328294E017837FL, 0x000034080181D8AEL, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x283B34FAFEFDC8E4L, 0x9208F44977C3E647L, 0x7DEAE962816F4E9AL, 0x68A2BA8AA262EC9DL, 0x8176F112EA43F45BL, 0x02106D022634F504L, 0x00007E8A50F02E37L, 0xB378B7C1DA22CCB1L, 0x6D089C99AD1D9230L, 0xEBE15711813E2369L, 0x2B35A68239D48A53L, 0x445F6FD138407C93L, 0xBEF93B29A3F6B54BL, 0x000173FA910377D3L}; // XRB1 - Montgomery_R2 = new long[]{0x28E55B65DCD69B30L, 0xACEC7367768798C2L, 0xAB27973F8311688DL, 0x175CC6AF8D6C7C0BL, 0xABCD92BF2DDE347EL, 0x69E16A61C7686D9AL, 0x000025A89BCDD12AL}; - Montgomery_one = new long[]{0x000000000000742CL, 0x0000000000000000L, 0x0000000000000000L, 0xB90FF404FC000000L, 0xD801A4FB559FACD4L, 0xE93254545F77410CL, 0x0000ECEEA7BD2EDAL}; - strat_Alice = new int[]{48, 28, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 13, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 4, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1}; - strat_Bob = new int[]{66, 33, 17, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 32, 16, 8, 4, 3, 1, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1}; - - if (isCompressed) - { - this.MASK2_BOB = 0x00; - this.MASK3_BOB = 0x7F; - this.ORDER_A_ENCODED_BYTES = SECRETKEY_A_BYTES; - this.ORDER_B_ENCODED_BYTES = SECRETKEY_B_BYTES; - this.PARTIALLY_COMPRESSED_CHUNK_CT = (4 * ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES + 2); - this.COMPRESSED_CHUNK_CT = (3 * ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES + 2); - this.UNCOMPRESSEDPK_BYTES = 330; - // Table sizes used by the Entangled basis generation - this.TABLE_R_LEN = 17; - this.TABLE_V_LEN = 34; - this.TABLE_V3_LEN = 20; - // Parameters for discrete log computations - // Binary Pohlig-Hellman reduced to smaller logs of order ell^W - this.W_2 = 4; - this.W_3 = 3; - // ell^w - this.ELL2_W = (1 << W_2); - this.ELL3_W = 27; - // ell^(e mod w) - this.ELL2_EMODW = (1 << (OALICE_BITS % W_2)); - this.ELL3_EMODW = 9; - // # of digits in the discrete log - this.DLEN_2 = ((OALICE_BITS + W_2 - 1) / W_2); // ceil(eA/W_2) - this.DLEN_3 = ((OBOB_EXPON + W_3 - 1) / W_3); // ceil(eB/W_3) - this.PLEN_2 = 55; - this.PLEN_3 = 47; - - // Import compression tables from properties - InputStream input = P434.class.getResourceAsStream("p434.properties"); - Properties props = new Properties(); - // load a properties file - try - { - props.load(input); - } - catch (IOException e) - { - throw new IllegalStateException("unable to load Picnic properties: " + e.getMessage(), e); - } - ph2_path = Internal.ReadIntsFromProperty(props,"ph2_path", PLEN_2); - ph3_path = Internal.ReadIntsFromProperty(props,"ph3_path", PLEN_3); - A_gen = Internal.ReadFromProperty(props,"A_gen", 6 * NWORDS64_FIELD); - B_gen = Internal.ReadFromProperty(props,"B_gen", 6 * NWORDS64_FIELD); - XQB3 = Internal.ReadFromProperty(props,"XQB3", 2 * NWORDS64_FIELD); - A_basis_zero = Internal.ReadFromProperty(props,"A_basis_zero", 8 * NWORDS64_FIELD); - B_basis_zero = Internal.ReadFromProperty(props,"B_basis_zero", 8 * NWORDS64_FIELD); - B_gen_3_tors = Internal.ReadFromProperty(props,"B_gen_3_tors", 16 * NWORDS64_FIELD); - g_R_S_im = Internal.ReadFromProperty(props,"g_R_S_im", NWORDS64_FIELD ); - g_phiR_phiS_re = Internal.ReadFromProperty(props,"g_phiR_phiS_re", NWORDS64_FIELD); - g_phiR_phiS_im = Internal.ReadFromProperty(props,"g_phiR_phiS_im", NWORDS64_FIELD); - Montgomery_RB1 = Internal.ReadFromProperty(props,"Montgomery_RB1", NWORDS64_FIELD); - Montgomery_RB2 = Internal.ReadFromProperty(props,"Montgomery_RB2", NWORDS64_FIELD); - threeinv = Internal.ReadFromProperty(props,"threeinv", NWORDS64_FIELD); - u_entang = Internal.ReadFromProperty(props,"u_entang", 2 * NWORDS64_FIELD); - u0_entang = Internal.ReadFromProperty(props,"u0_entang", 2 * NWORDS64_FIELD); - table_r_qr = Internal.ReadFromProperty(props,"table_r_qr", TABLE_R_LEN, NWORDS64_FIELD); - table_r_qnr = Internal.ReadFromProperty(props,"table_r_qnr", TABLE_R_LEN, NWORDS64_FIELD); - table_v_qr = Internal.ReadFromProperty(props,"table_v_qr", TABLE_V_LEN, NWORDS64_FIELD); - table_v_qnr = Internal.ReadFromProperty(props,"table_v_qnr", TABLE_V_LEN, NWORDS64_FIELD); - v_3_torsion = Internal.ReadFromProperty(props,"v_3_torsion", TABLE_V3_LEN, 2, NWORDS64_FIELD); - T_tate3 = Internal.ReadFromProperty(props,"T_tate3", (6 * (OBOB_EXPON - 1) + 4) * NWORDS64_FIELD); - T_tate2_firststep_P = Internal.ReadFromProperty(props,"T_tate2_firststep_P", 4 * NWORDS64_FIELD); - T_tate2_P = Internal.ReadFromProperty(props,"T_tate2_P", 3 * (OALICE_BITS - 2) * NWORDS64_FIELD); - T_tate2_firststep_Q = Internal.ReadFromProperty(props,"T_tate2_firststep_Q", 4 * NWORDS64_FIELD); - T_tate2_Q = Internal.ReadFromProperty(props,"T_tate2_Q", 3 * (OALICE_BITS - 2) * NWORDS64_FIELD); - ph2_T = Internal.ReadFromProperty(props,"ph2_T",DLEN_2*(ELL2_W >>> 1)*2*NWORDS64_FIELD); - ph3_T1 = Internal.ReadFromProperty(props,"ph3_T1",DLEN_3*(ELL3_W >>> 1)*2*NWORDS64_FIELD); - ph3_T2 = Internal.ReadFromProperty(props,"ph3_T2",DLEN_3*(ELL3_W >>> 1)*2*NWORDS64_FIELD); - - ph2_T1 = new long[2*((DLEN_2 - 1)*(ELL2_W/2) + (ph2_path[PLEN_2 - 1]-1))]; - ph2_T2 = new long[2*((DLEN_2 - 1)*(ELL2_W/2) + (ph2_path[PLEN_2 - 1]-1))]; - ph3_T= new long[2*((DLEN_3 - 1)*(ELL3_W/2) + (ph3_path[PLEN_3 - 1]-1))]; - } - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/P503.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/P503.java deleted file mode 100644 index 55401657d6..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/P503.java +++ /dev/null @@ -1,202 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -class P503 - extends Internal -{ - // Encoding of field elements, elements over Z_order, elements over GF(p^2) and elliptic curve points: - // -------------------------------------------------------------------------------------------------- - // Elements over GF(p) and Z_order are encoded with the least significant octet (and digit) located at the leftmost position (i.e., little endian format). - // Elements (a+b*i) over GF(p^2), where a and b are defined over GF(p), are encoded as {a, b}, with a in the least significant position. - // Elliptic curve points P = (x,y) are encoded as {x, y}, with x in the least significant position. - // Internally, the number of digits used to represent all these elements is obtained by approximating the number of bits to the immediately greater multiple of 32. - // For example, a 503-bit field element is represented with Ceil(503 / 64) = 8 64-bit digits or Ceil(503 / 32) = 16 32-bit digits. - - // - // Curve isogeny system "SIDHp503". Base curve: Montgomery curve By^2 = Cx^3 + Ax^2 + Cx defined over GF(p503^2), where A=6, B=1, C=1 and p503 = 2^250*3^159-1 - // - P503(boolean isCompressed) - { - this.COMPRESS = isCompressed; - CRYPTO_SECRETKEYBYTES = 434; - CRYPTO_PUBLICKEYBYTES = 378; - CRYPTO_BYTES = 24; - CRYPTO_CIPHERTEXTBYTES = 402; - if(isCompressed) - { - CRYPTO_SECRETKEYBYTES = 407; - CRYPTO_PUBLICKEYBYTES = 225; - CRYPTO_CIPHERTEXTBYTES = 280; - } - - this.NWORDS_FIELD = 8; // Number of words of a 503-bit field element - this.PRIME_ZERO_WORDS = 3; // Number of "0" digits in the least significant part of p503 + 1 - - - // Basic constants - this.NBITS_FIELD = 503; - this.MAXBITS_FIELD = 512; - this.MAXWORDS_FIELD = ((MAXBITS_FIELD+RADIX-1)/RADIX); // Max. number of words to represent field elements; - this.NWORDS64_FIELD = ((NBITS_FIELD+63)/64); // Number of 64-bit words of a 503-bit field element; - this.NBITS_ORDER = 256; - this.NWORDS_ORDER = ((NBITS_ORDER+RADIX-1)/RADIX); // Number of words of oA and oB, where oA and oB are the subgroup orders of Alice and Bob, resp.; - this.NWORDS64_ORDER = ((NBITS_ORDER+63)/64); // Number of 64-bit words of a 256-bit element; - this.MAXBITS_ORDER = NBITS_ORDER; - this.ALICE = 0; - this.BOB = 1; - this.OALICE_BITS = 250; - this.OBOB_BITS = 253; - this.OBOB_EXPON = 159; - this.MASK_ALICE = 0x03; - this.MASK_BOB = 0x0F; - this.PARAM_A = 6; - this.PARAM_C = 1; - // Fixed parameters for isogeny tree computation - this.MAX_INT_POINTS_ALICE = 7; - this.MAX_INT_POINTS_BOB = 8; - this.MAX_Alice = 125; - this.MAX_Bob = 159; - this.MSG_BYTES = 24; - this.SECRETKEY_A_BYTES = ((OALICE_BITS + 7) / 8); - this.SECRETKEY_B_BYTES = ((OBOB_BITS - 1 + 7) / 8); - this.FP2_ENCODED_BYTES = 2*((NBITS_FIELD + 7) / 8); - - - PRIME = new long[] { 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xABFFFFFFFFFFFFFFL,0x13085BDA2211E7A0L, 0x1B9BF6C87B7E7DAFL, 0x6045C6BDDA77A4D0L, 0x004066F541811E1EL }; - PRIMEx2 = new long[] { 0xFFFFFFFFFFFFFFFEL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0x57FFFFFFFFFFFFFFL,0x2610B7B44423CF41L, 0x3737ED90F6FCFB5EL, 0xC08B8D7BB4EF49A0L, 0x0080CDEA83023C3CL }; - PRIMEx4 = new long[] { 0xFFFFFFFFFFFFFFFCL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xAFFFFFFFFFFFFFFFL,0x4C216F6888479E82L, 0x6E6FDB21EDF9F6BCL, 0x81171AF769DE9340L, 0x01019BD506047879L }; - PRIMEp1 = new long[] { 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0xAC00000000000000L,0x13085BDA2211E7A0L, 0x1B9BF6C87B7E7DAFL, 0x6045C6BDDA77A4D0L, 0x004066F541811E1EL }; - PRIMEp1x64 = new long[] { 0xC216F6888479E82BL, 0xE6FDB21EDF9F6BC4L, 0x1171AF769DE93406L, 0x1019BD5060478798L }; - PRIMEx16p = new long[] { 0x0000000000000010L, 0x0000000000000000L, 0x0000000000000000L, 0x8000000000000000L,0x9EF484BBBDC30BEAL, 0x8C8126F090304A1DL, 0xF7472844B10B65FCL, 0x30F32157CFDC3C33L, - 0x1463AB4329A333F7L, 0xDFC933977C47D3A4L, 0x338A3767F6F2520BL, 0x4F8CB7565CCC13FAL,0xDE43B73AACD2189BL, 0xBCF845CAC5405FBDL, 0x516D02A09E684B7AL, 0x0001033A4091BB86L }; - Alice_order = new long[] { 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0400000000000000L }; - Bob_order = new long[] { 0xC216F6888479E82BL, 0xE6FDB21EDF9F6BC4L, 0x1171AF769DE93406L, 0x1019BD5060478798L }; - A_gen = new long[] { 0x5D083011589AD893L, 0xADFD8D2CB67D0637L, 0x330C9AC34FFB6361L, 0xF0D47489A2E805A2L, - 0x27E2789259C6B8DCL, 0x63866A2C121931B9L, 0x8D4C65A7137DCF44L, 0x003A183AE5967B3FL, // XPA0 - 0x7E3541B8C96D1519L, 0xD3ADAEEC0D61A26CL, 0xC0A2219CE7703DD9L, 0xFF3E46658FCDBC52L, - 0xD5B38DEAE6E196FFL, 0x1AAC826364956D58L, 0xEC9F4875B9A5F27AL, 0x001B0B475AB99843L, // XPA1 - 0x4D83695107D03BADL, 0x221F3299005E2FCFL, 0x78E6AE22F30DECF2L, 0x6D982DB5111253E4L, - 0x504C80A8AB4526A8L, 0xEFD0C3AA210BB024L, 0xCB77483501DC6FCFL, 0x001052544A96BDF3L, // XQA0 - 0x0D74FE3402BCAE47L, 0xDF5B8CDA832D8AEDL, 0xB86BCF06E4BD837EL, 0x892A2933A0FA1F63L, - 0x9F88FC67B6CCB461L, 0x822926EA9DDA3AC8L, 0xEAC8DDE5855425EDL, 0x000618FE6DA37A80L, // XQA1 - 0x1D9D32D2DC877C17L, 0x5517CD8F71D5B02BL, 0x395AFB8F6B60C117L, 0x3AE31AC85F9098C8L, - 0x5F5341C198450848L, 0xF8C609DBEA435C6AL, 0xD832BC7EDC7BA5E4L, 0x002AD98AA6968BF5L, // XRA0 - 0xC466CAB0F73C2E5BL, 0x7B1817148FB2CF9CL, 0x873E87C099E470A0L, 0xBB17AC6D17A7BAC1L, - 0xA146FDCD0F2E2A58L, 0x88B311E9CEAB6201L, 0x37604CF5C7951757L, 0x0006804071C74BF9L }; // XRA1 - B_gen = new long[] { 0xDF630FC5FB2468DBL, 0xC30C5541C102040EL, 0x3CDC9987B76511FCL, 0xF54B5A09353D0CDDL, - 0x3ADBA8E00703C42FL, 0x8253F9303DDC95D0L, 0x62D30778763ABFD7L, 0x001CD00FB581CD55L, // XPB0 - 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, - 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, // XPB1 - 0x2E3457A12B429261L, 0x311F94E89627DCF8L, 0x5B71C98FD1DB73F6L, 0x3671DB7DCFC21541L, - 0xB6D1484C9FE0CF4FL, 0x19CD110717356E35L, 0xF4F9FB00AC9919DFL, 0x0035BC124D38A70BL, // XQB0 - 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, - 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, // XQB1 - 0x2E08BB99413D2952L, 0xD3021467CD088D72L, 0x21017AF859752245L, 0x26314ED8FFD9DE5CL, - 0x4AF43C73344B6686L, 0xCFA1F91149DF0993L, 0xF327A95365587A89L, 0x000DBF54E03D3906L, // XRB0 - 0x03E03FF342F5F304L, 0x993D604D7B4B6E56L, 0x80412F4D9280E71FL, 0x0FFDC9EF990B3982L, - 0xE584E64C51604931L, 0x1374F42AC8B0BBD7L, 0x07D5BC37DFA41A5FL, 0x00396CCFD61FD34CL }; // XRB1 - Montgomery_R2 = new long[] { 0x5289A0CF641D011FL, 0x9B88257189FED2B9L, 0xA3B365D58DC8F17AL, 0x5BC57AB6EFF168ECL, - 0x9E51998BD84D4423L, 0xBF8999CBAC3B5695L, 0x46E9127BCE14CDB6L, 0x003F6CFCE8B81771L }; - Montgomery_one = new long[] { 0x00000000000003F9L, 0x0000000000000000L, 0x0000000000000000L, 0xB400000000000000L, - 0x63CB1A6EA6DED2B4L, 0x51689D8D667EB37DL, 0x8ACD77C71AB24142L, 0x0026FBAEC60F5953L }; - strat_Alice = new int[] { - 61, 32, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, - 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, - 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 29, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, - 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 13, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, - 1, 1, 2, 1, 1, 5, 4, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1 }; - strat_Bob = new int[] { - 71, 38, 21, 13, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 5, 4, 2, 1, 1, 2, 1, - 1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 17, 9, - 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, - 1, 4, 2, 1, 1, 2, 1, 1, 33, 17, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, - 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 1, 2, - 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1 }; - - if(COMPRESS) - { - this.MASK2_BOB = 0x03; - this.MASK3_BOB = 0xFF; - this.ORDER_A_ENCODED_BYTES = SECRETKEY_A_BYTES; - this.ORDER_B_ENCODED_BYTES = SECRETKEY_B_BYTES; - this.PARTIALLY_COMPRESSED_CHUNK_CT = (4 * ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES + 2); - this.COMPRESSED_CHUNK_CT = (3 * ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES + 2); - this.UNCOMPRESSEDPK_BYTES = 378; - // Table sizes used by the Entangled basis generation - this.TABLE_R_LEN = 17; - this.TABLE_V_LEN = 34; - this.TABLE_V3_LEN = 20; - // Parameters for discrete log computations - // Binary Pohlig-Hellman reduced to smaller logs of order ell^W - this.W_2 = 5; - this.W_3 = 3; - // ell^w - this.ELL2_W = (1 << W_2); - this.ELL3_W = 27; - // ell^(e mod w) - this.ELL2_EMODW = (1 << (OALICE_BITS % W_2)); - this.ELL3_EMODW = 1; - // # of digits in the discrete log - this.DLEN_2 = ((OALICE_BITS + W_2 - 1) / W_2); // ceil(eA/W_2); - this.DLEN_3 = ((OBOB_EXPON + W_3 - 1) / W_3); // ceil(eB/W_3); - this.PLEN_2 = 51; - this.PLEN_3 = 54; - - // Import compression tables from properties - InputStream input = P503.class.getResourceAsStream("p503.properties"); - Properties props = new Properties(); - // load a properties file - try - { - props.load(input); - } - catch (IOException e) - { - throw new IllegalStateException("unable to load Picnic properties: " + e.getMessage(), e); - } - ph2_path = Internal.ReadIntsFromProperty(props,"ph2_path", PLEN_2); - ph3_path = Internal.ReadIntsFromProperty(props,"ph3_path", PLEN_3); - A_gen = Internal.ReadFromProperty(props,"A_gen", 6 * NWORDS64_FIELD); - B_gen = Internal.ReadFromProperty(props,"B_gen", 6 * NWORDS64_FIELD); - XQB3 = Internal.ReadFromProperty(props,"XQB3", 2 * NWORDS64_FIELD); - A_basis_zero = Internal.ReadFromProperty(props,"A_basis_zero", 8 * NWORDS64_FIELD); - B_basis_zero = Internal.ReadFromProperty(props,"B_basis_zero", 8 * NWORDS64_FIELD); - B_gen_3_tors = Internal.ReadFromProperty(props,"B_gen_3_tors", 16 * NWORDS64_FIELD); - g_R_S_im = Internal.ReadFromProperty(props,"g_R_S_im", NWORDS64_FIELD ); - Montgomery_R2 = Internal.ReadFromProperty(props,"Montgomery_R2", NWORDS64_FIELD); - Montgomery_RB1 = Internal.ReadFromProperty(props,"Montgomery_RB1", NWORDS64_FIELD); - Montgomery_RB2 = Internal.ReadFromProperty(props,"Montgomery_RB2", NWORDS64_FIELD); - Montgomery_one = Internal.ReadFromProperty(props, "Montgomery_one", NWORDS64_FIELD); - threeinv = Internal.ReadFromProperty(props,"threeinv", NWORDS64_FIELD); - u_entang = Internal.ReadFromProperty(props,"u_entang", 2 * NWORDS64_FIELD); - u0_entang = Internal.ReadFromProperty(props,"u0_entang", 2 * NWORDS64_FIELD); - table_r_qr = Internal.ReadFromProperty(props,"table_r_qr", TABLE_R_LEN, NWORDS64_FIELD); - table_r_qnr = Internal.ReadFromProperty(props,"table_r_qnr", TABLE_R_LEN, NWORDS64_FIELD); - table_v_qr = Internal.ReadFromProperty(props,"table_v_qr", TABLE_V_LEN, NWORDS64_FIELD); - table_v_qnr = Internal.ReadFromProperty(props,"table_v_qnr", TABLE_V_LEN, NWORDS64_FIELD); - v_3_torsion = Internal.ReadFromProperty(props,"v_3_torsion", TABLE_V3_LEN, 2, NWORDS64_FIELD); - T_tate3 = Internal.ReadFromProperty(props,"T_tate3", (6 * (OBOB_EXPON - 1) + 4) * NWORDS64_FIELD); - T_tate2_firststep_P = Internal.ReadFromProperty(props,"T_tate2_firststep_P", 4 * NWORDS64_FIELD); - T_tate2_P = Internal.ReadFromProperty(props,"T_tate2_P", 3 * (OALICE_BITS - 2) * NWORDS64_FIELD); - T_tate2_firststep_Q = Internal.ReadFromProperty(props,"T_tate2_firststep_Q", 4 * NWORDS64_FIELD); - T_tate2_Q = Internal.ReadFromProperty(props,"T_tate2_Q", 3 * (OALICE_BITS - 2) * NWORDS64_FIELD); - ph2_T = Internal.ReadFromProperty(props,"ph2_T",DLEN_2*(ELL2_W >>> 1)*2*NWORDS64_FIELD); - ph3_T = Internal.ReadFromProperty(props, "ph3_T", DLEN_3*(ELL3_W>>1)*2*NWORDS64_FIELD); - - Montgomery_R = new long[NWORDS64_FIELD]; - ph3_T1 = new long[DLEN_3*(ELL3_W >>> 1)*2*NWORDS64_FIELD]; - ph3_T2 = new long[DLEN_3*(ELL3_W >>> 1)*2*NWORDS64_FIELD]; - ph2_T1 = new long[2*((DLEN_2 - 1)*(ELL2_W/2) + (ph2_path[PLEN_2 - 1]-1))]; - ph2_T2 = new long[2*((DLEN_2 - 1)*(ELL2_W/2) + (ph2_path[PLEN_2 - 1]-1))]; - - - } - - - - - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/P610.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/P610.java deleted file mode 100644 index d9a9f665db..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/P610.java +++ /dev/null @@ -1,199 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -class P610 - extends Internal -{ - P610(boolean isCompressed) - { - this.COMPRESS = isCompressed; - CRYPTO_SECRETKEYBYTES = 524; - CRYPTO_PUBLICKEYBYTES = 462; - CRYPTO_BYTES = 24; - CRYPTO_CIPHERTEXTBYTES = 486; - if(isCompressed) - { - CRYPTO_SECRETKEYBYTES = 491; - CRYPTO_PUBLICKEYBYTES = 274; - CRYPTO_CIPHERTEXTBYTES = 336; - } - - - NWORDS_FIELD = 10; // Number of words of a 610-bit field element - PRIME_ZERO_WORDS = 4; // Number of "0" digits in the least significant part of p610 + 1 - - - - // Basic constants - - NBITS_FIELD = 610; - MAXBITS_FIELD = 640; - MAXWORDS_FIELD = ((MAXBITS_FIELD+RADIX-1)/RADIX); // Max. number of words to represent field elements - NWORDS64_FIELD = ((NBITS_FIELD+63)/64); // Number of 64-bit words of a 610-bit field element - NBITS_ORDER = 320; - NWORDS_ORDER = ((NBITS_ORDER+RADIX-1)/RADIX); // Number of words of oA and oB, where oA and oB are the subgroup orders of Alice and Bob, resp - NWORDS64_ORDER = ((NBITS_ORDER+63)/64); // Number of 64-bit words of a 320-bit element - MAXBITS_ORDER = NBITS_ORDER; - ALICE = 0; - BOB = 1; - OALICE_BITS = 305; - OBOB_BITS = 305; - OBOB_EXPON = 192; - MASK_ALICE = 0x01; - MASK_BOB = 0xFF; - PARAM_A = 6; - PARAM_C = 1; - // Fixed parameters for isogeny tree computation - MAX_INT_POINTS_ALICE = 8; - MAX_INT_POINTS_BOB = 10; - MAX_Alice = 152; - MAX_Bob = 192; - MSG_BYTES = 24; - SECRETKEY_A_BYTES = ((OALICE_BITS + 7) / 8); - SECRETKEY_B_BYTES = ((OBOB_BITS - 1 + 7) / 8); - FP2_ENCODED_BYTES = 2*((NBITS_FIELD + 7) / 8); - - PRIME = new long[] { 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0x6E01FFFFFFFFFFFFL, - 0xB1784DE8AA5AB02EL, 0x9AE7BF45048FF9ABL, 0xB255B2FA10C4252AL, 0x819010C251E7D88CL, 0x000000027BF6A768L }; - PRIMEx2 = new long[] { 0xFFFFFFFFFFFFFFFEL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xDC03FFFFFFFFFFFFL, - 0x62F09BD154B5605CL, 0x35CF7E8A091FF357L, 0x64AB65F421884A55L, 0x03202184A3CFB119L, 0x00000004F7ED4ED1L }; - PRIMEx4 = new long[] { 0xFFFFFFFFFFFFFFFCL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xB807FFFFFFFFFFFFL, - 0xC5E137A2A96AC0B9L, 0x6B9EFD14123FE6AEL, 0xC956CBE8431094AAL, 0x06404309479F6232L, 0x00000009EFDA9DA2L }; - PRIMEp1 = new long[] { 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x6E02000000000000L, - 0xB1784DE8AA5AB02EL, 0x9AE7BF45048FF9ABL, 0xB255B2FA10C4252AL, 0x819010C251E7D88CL, 0x000000027BF6A768L }; - PRIMEx16p = new long[] { 0x0000000000000010L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x3FC0000000000000L, - 0xD0F642EAB4A9FA32L, 0xA308175F6E00CA89L, 0xB549A0BDE77B5AACL, 0xCDFDE7B5C304EE69L, 0x7FDB7FF0812B12EFL, - 0xE09BA529B9FE1167L, 0xD249C196DAB8CD7FL, 0xD4E22754A3F20928L, 0x97825638B19A7CCEL, 0x05E04550FC4CCE0DL, - 0x8FB5DA1152CDE50CL, 0xF9649BA3EA408644L, 0x4473C93E6441063DL, 0xBE190269D1337B7BL, 0x0000000000000062L }; - Alice_order = new long[] { 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0002000000000000L }; - Bob_order = new long[] { 0x26F4552D58173701L, 0xDFA28247FCD5D8BCL, 0xD97D086212954D73L, 0x086128F3EC46592AL, 0x00013DFB53B440C8L }; - A_gen = new long[] { 0x5019EC96A75AC57AL, 0x8AEA0E717712C6F1L, 0x03C067C819D29E5EL, 0x59F454425FE307D9L, 0x6D29215D9AD5E6D4L, - 0xD8C5A27CDC9DD34AL, 0x972DC274DAB435B3L, 0x82A597C70A80E10FL, 0x48175986EFED547FL, 0x00000000671A3592L, // XPA0 - 0xE4BA9CC3EEEC53F4L, 0xBD34E4FEDB0132D3L, 0x1B7125C87BEE960CL, 0x25D615BF3CFAA355L, 0xFC8EC20DC367D66AL, - 0xB44F3FD1CC73289CL, 0xD84BF51195C2E012L, 0x38D7C756EB370F48L, 0xBBC236249F94F72AL, 0x000000013020CC63L, // XPA1 - 0x1D7C945D3DBCC38CL, 0x9A5F7C12CA8BA5B9L, 0x1E8F87985B01CBE3L, 0xD2CABF82F5BC5235L, 0x3BDE474ECCA9FAA2L, - 0xB98CD975DF9FB0A8L, 0x444E4464B9C67790L, 0xCB2E888565CE6AD9L, 0xDB64FFE2A1C350E2L, 0x00000001D7532756L, // XQA0 - 0x1E8B3AA2382C9079L, 0x28CB31E08A943C00L, 0xE04D02266E8A63E1L, 0x84A2D260214EF65FL, 0xD5933DA25018E226L, - 0xBC8BF038928C4BA9L, 0x91E9D0CB7EAF58A9L, 0x04A4627B75E008E1L, 0x58CEF27583E50C2EL, 0x00000002170DDF44L, // XQA1 - 0x261DD0782CEC958DL, 0xC25B3AE64BBC0311L, 0x9F21B8A8981B15FEL, 0xA3C0B52CD5FFC45BL, 0x5D2E65A016702C6AL, - 0x8C5586CA98722EDEL, 0x61490A967A6B4B1AL, 0xFA64E30231F719AFL, 0x9CEAB8B6301BB2DFL, 0x00000000CF5AEA7DL, // XRA0 - 0xB980435A77B912C0L, 0x2B4A97F70E0FC873L, 0x415C7FA4DE96F43CL, 0xE5EED95643E443FDL, 0xCBE18DB57C51B354L, - 0x51C96C3FFABD2D46L, 0x5C14637B9A5765D6L, 0x45D2369C4D0199A5L, 0x25A1F9C5BBF1E683L, 0x000000025AD7A11BL }; // XRA1 - B_gen = new long[] { 0xC6C8E180E41884BAL, 0x2161D2F4FBC32B95L, 0xCBF83091BDB34092L, 0xD742CC0AD4CC7E38L, 0x61A1FA7E1B14FBD7L, - 0xF0E5FC70137597C4L, 0x1F0C8F2585E20B1FL, 0xC68E44A1C032A4C2L, 0xE3C65FB8AF155A0DL, 0x00000001409EE8D5L, // XPB0 - 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, - 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, // XPB1 - 0xF586DB4A16BE1880L, 0x712F10D95E6C65A9L, 0x9D5AAC3B83584B87L, 0x4ECDAA98182C8261L, 0xAD7D4C15588FD230L, - 0x4197C54E96B7D926L, 0xED15BB13E8C588EDL, 0x3E299AEAD5AAD7C7L, 0xF36B25F1BD579F79L, 0x000000021CE65B5BL, // XQB0 - 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, - 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, // XQB1 - 0x7A87897A0C4C3FD7L, 0x3C1879ECD4D33D76L, 0x595C28A36FFBA1A0L, 0xF53FF66A2A7FD0FBL, 0xB39F5A91230E56FAL, - 0x81F21610DA3EA8B5L, 0xEBB3B9A627428A90L, 0x8661123B35748010L, 0xE196173B9C48781DL, 0x00000002198166ACL, // XRB0 - 0x5E3CC79B37006D6AL, 0xE0358A9AB2EA7923L, 0x3B725CB595180951L, 0x0724637F1DD0C191L, 0x7BB031B67DAB9D19L, - 0x53CCB8BECEDD3435L, 0xEE5DF7FFEBFA7A0AL, 0x899EDB7D8B9694C4L, 0x0CA38EB4AE5506B6L, 0x00000001489DE1CDL }; // XRB1 - Montgomery_R2 = new long[] { 0xE75F5D201A197727L, 0xE0B85963B627392EL, 0x6BC1707818DE493DL, 0xDC7F419940D1A0C5L, 0x7358030979EDE54AL, - 0x84F4BEBDEED75A5CL, 0x7ECCA66E13427B47L, 0xC5BB4E65280080B3L, 0x7019950F516DA19AL, 0x000000008E290FF3L }; - Montgomery_one = new long[] { 0x00000000670CC8E6L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x9A34000000000000L, - 0x4D99C2BD28717A3FL, 0x0A4A1839A323D41CL, 0xD2B62215D06AD1E2L, 0x1369026E862CAF3DL, 0x000000010894E964L }; - - strat_Alice = new int[] { - 67, 37, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1, - 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 16, 9, - 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, - 1, 4, 2, 1, 1, 2, 1, 1, 33, 16, 8, 5, 2, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 2, 1, - 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 1, 2, 1, 1, - 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1 }; - - strat_Bob = new int[] { - 86, 48, 27, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1, - 1, 3, 2, 1, 1, 1, 1, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, - 1, 1, 2, 1, 1, 1, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, - 1, 1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 38, - 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, - 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 17, 9, 5, 3, 2, 1, 1, - 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, - 1, 1 }; - - if(COMPRESS) - { - MASK2_BOB = 0x07; - MASK3_BOB = 0xFF; - ORDER_A_ENCODED_BYTES = SECRETKEY_A_BYTES; - ORDER_B_ENCODED_BYTES = (SECRETKEY_B_BYTES + 1); - PARTIALLY_COMPRESSED_CHUNK_CT = (4 * ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES + 2); - COMPRESSED_CHUNK_CT = (3 * ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES + 2); - UNCOMPRESSEDPK_BYTES = 480; - // Table sizes used by the Entangled basis generation - TABLE_R_LEN = 17; - TABLE_V_LEN = 34; - TABLE_V3_LEN = 20; - // Parameters for discrete log computations - // Binary Pohlig-Hellman reduced to smaller logs of order ell^W - W_2 = 5; - W_3 = 3; - // ell^w - ELL2_W = (1 << W_2); - ELL3_W = 27; - // ell^(e mod w) - ELL2_EMODW = (1 << (OALICE_BITS % W_2)); - ELL3_EMODW = 1; - // # of digits in the discrete log - DLEN_2 = ((OALICE_BITS + W_2 - 1) / W_2); // ceil(eA/W_2) - DLEN_3 = ((OBOB_EXPON + W_3 - 1) / W_3); // ceil(eB/W_3) - this.PLEN_2 = 62; - this.PLEN_3 = 65; - - // Import compression tables from properties - InputStream input = P610.class.getResourceAsStream("p610.properties"); - Properties props = new Properties(); - // load a properties file - try - { - props.load(input); - } - catch (IOException e) - { - throw new IllegalStateException("unable to load Picnic properties: " + e.getMessage(), e); - } - ph2_path = Internal.ReadIntsFromProperty(props,"ph2_path", PLEN_2); - ph3_path = Internal.ReadIntsFromProperty(props,"ph3_path", PLEN_3); - A_gen = Internal.ReadFromProperty(props,"A_gen", 6 * NWORDS64_FIELD); - B_gen = Internal.ReadFromProperty(props,"B_gen", 6 * NWORDS64_FIELD); - XQB3 = Internal.ReadFromProperty(props,"XQB3", 2 * NWORDS64_FIELD); - A_basis_zero = Internal.ReadFromProperty(props,"A_basis_zero", 8 * NWORDS64_FIELD); - B_basis_zero = Internal.ReadFromProperty(props,"B_basis_zero", 8 * NWORDS64_FIELD); - B_gen_3_tors = Internal.ReadFromProperty(props,"B_gen_3_tors", 16 * NWORDS64_FIELD); - g_R_S_im = Internal.ReadFromProperty(props,"g_R_S_im", NWORDS64_FIELD ); - Montgomery_R2 = Internal.ReadFromProperty(props,"Montgomery_R2", NWORDS64_FIELD); - Montgomery_RB1 = Internal.ReadFromProperty(props,"Montgomery_RB1", NWORDS64_FIELD); - Montgomery_RB2 = Internal.ReadFromProperty(props,"Montgomery_RB2", NWORDS64_FIELD); - Montgomery_one = Internal.ReadFromProperty(props, "Montgomery_one", NWORDS64_FIELD); - threeinv = Internal.ReadFromProperty(props,"threeinv", NWORDS64_FIELD); - u_entang = Internal.ReadFromProperty(props,"u_entang", 2 * NWORDS64_FIELD); - u0_entang = Internal.ReadFromProperty(props,"u0_entang", 2 * NWORDS64_FIELD); - table_r_qr = Internal.ReadFromProperty(props,"table_r_qr", TABLE_R_LEN, NWORDS64_FIELD); - table_r_qnr = Internal.ReadFromProperty(props,"table_r_qnr", TABLE_R_LEN, NWORDS64_FIELD); - table_v_qr = Internal.ReadFromProperty(props,"table_v_qr", TABLE_V_LEN, NWORDS64_FIELD); - table_v_qnr = Internal.ReadFromProperty(props,"table_v_qnr", TABLE_V_LEN, NWORDS64_FIELD); - v_3_torsion = Internal.ReadFromProperty(props,"v_3_torsion", TABLE_V3_LEN, 2, NWORDS64_FIELD); - T_tate3 = Internal.ReadFromProperty(props,"T_tate3", (6 * (OBOB_EXPON - 1) + 4) * NWORDS64_FIELD); - T_tate2_firststep_P = Internal.ReadFromProperty(props,"T_tate2_firststep_P", 4 * NWORDS64_FIELD); - T_tate2_P = Internal.ReadFromProperty(props,"T_tate2_P", 3 * (OALICE_BITS - 2) * NWORDS64_FIELD); - T_tate2_firststep_Q = Internal.ReadFromProperty(props,"T_tate2_firststep_Q", 4 * NWORDS64_FIELD); - T_tate2_Q = Internal.ReadFromProperty(props,"T_tate2_Q", 3 * (OALICE_BITS - 2) * NWORDS64_FIELD); - ph2_T = Internal.ReadFromProperty(props,"ph2_T",DLEN_2*(ELL2_W >>> 1)*2*NWORDS64_FIELD); - ph3_T = Internal.ReadFromProperty(props, "ph3_T", DLEN_3*(ELL3_W >>> 1)*2*NWORDS64_FIELD); - - Montgomery_R = new long[NWORDS64_FIELD]; - ph3_T1 = new long[DLEN_3*(ELL3_W >>> 1)*2*NWORDS64_FIELD]; - ph3_T2 = new long[DLEN_3*(ELL3_W >>> 1)*2*NWORDS64_FIELD]; - ph2_T1 = new long[2*((DLEN_2 - 1)*(ELL2_W/2) + (ph2_path[PLEN_2 - 1]-1))]; - ph2_T2 = new long[2*((DLEN_2 - 1)*(ELL2_W/2) + (ph2_path[PLEN_2 - 1]-1))]; - - } - } - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/P751.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/P751.java deleted file mode 100644 index 5a1e2f8ba6..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/P751.java +++ /dev/null @@ -1,212 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -class P751 - extends Internal -{ - // Encoding of field elements, elements over Z_order, elements over GF(p^2) and elliptic curve points: - // -------------------------------------------------------------------------------------------------- - // Elements over GF(p) and Z_order are encoded with the least significant octet (and digit) located at the leftmost position (i.e., little endian format). - // Elements (a+b*i) over GF(p^2), where a and b are defined over GF(p), are encoded as {a, b}, with a in the least significant position. - // Elliptic curve points P = (x,y) are encoded as {x, y}, with x in the least significant position. - // Internally, the number of digits used to represent all these elements is obtained by approximating the number of bits to the immediately greater multiple of 32. - // For example, a 751-bit field element is represented with Ceil(751 / 64) = 12 64-bit digits or Ceil(751 / 32) = 24 32-bit digits. - - // - // Curve isogeny system "SIDHp751". Base curve: Montgomery curve By^2 = Cx^3 + Ax^2 + Cx defined over GF(p751^2), where A=6, B=1, C=1 and p751 = 2^372*3^239-1 - // - P751(boolean isCompressed) - { - this.COMPRESS = isCompressed; - CRYPTO_SECRETKEYBYTES = 644; - CRYPTO_PUBLICKEYBYTES = 564; - CRYPTO_BYTES = 32; - CRYPTO_CIPHERTEXTBYTES = 596; - if(isCompressed) - { - CRYPTO_SECRETKEYBYTES = 602; - CRYPTO_PUBLICKEYBYTES = 335; - CRYPTO_CIPHERTEXTBYTES = 410; - } - - - NWORDS_FIELD = 12; // Number of words of a 751-bit field element - PRIME_ZERO_WORDS = 5; // Number of "0" digits in the least significant part of p751 + 1 - - - // Basic constants - NBITS_FIELD = 751; - MAXBITS_FIELD = 768; - MAXWORDS_FIELD = ((MAXBITS_FIELD+RADIX-1)/RADIX); // Max. number of words to represent field elements - NWORDS64_FIELD = ((NBITS_FIELD+63)/64); // Number of 64-bit words of a 751-bit field element - NBITS_ORDER = 384; - NWORDS_ORDER = ((NBITS_ORDER+RADIX-1)/RADIX); // Number of words of oA and oB, where oA and oB are the subgroup orders of Alice and Bob, resp. - NWORDS64_ORDER = ((NBITS_ORDER+63)/64); // Number of 64-bit words of a 384-bit element - MAXBITS_ORDER = NBITS_ORDER; - ALICE = 0; - BOB = 1; - OALICE_BITS = 372; - OBOB_BITS = 379; - OBOB_EXPON = 239; - MASK_ALICE = 0x0F; - MASK_BOB = 0x03; - PARAM_A = 6; - PARAM_C = 1; - // Fixed parameters for isogeny tree computation - MAX_INT_POINTS_ALICE = 8; - MAX_INT_POINTS_BOB = 10; - MAX_Alice = 186; - MAX_Bob = 239; - MSG_BYTES = 32; - SECRETKEY_A_BYTES = ((OALICE_BITS + 7) / 8); - SECRETKEY_B_BYTES = ((OBOB_BITS - 1 + 7) / 8); - FP2_ENCODED_BYTES = 2*((NBITS_FIELD + 7) / 8); - - - PRIME = new long[] { 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xEEAFFFFFFFFFFFFFL, - 0xE3EC968549F878A8L, 0xDA959B1A13F7CC76L, 0x084E9867D6EBE876L, 0x8562B5045CB25748L, 0x0E12909F97BADC66L, 0x00006FE5D541F71CL }; - PRIMEx2 = new long[] { 0xFFFFFFFFFFFFFFFEL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xDD5FFFFFFFFFFFFFL, - 0xC7D92D0A93F0F151L, 0xB52B363427EF98EDL, 0x109D30CFADD7D0EDL, 0x0AC56A08B964AE90L, 0x1C25213F2F75B8CDL, 0x0000DFCBAA83EE38L }; - PRIMEx4 = new long[] { 0xFFFFFFFFFFFFFFFCL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xBABFFFFFFFFFFFFFL, - 0x8FB25A1527E1E2A3L, 0x6A566C684FDF31DBL, 0x213A619F5BAFA1DBL, 0x158AD41172C95D20L, 0x384A427E5EEB719AL, 0x0001BF975507DC70L }; - PRIMEp1 = new long[] { 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0xEEB0000000000000L, - 0xE3EC968549F878A8L, 0xDA959B1A13F7CC76L, 0x084E9867D6EBE876L, 0x8562B5045CB25748L, 0x0E12909F97BADC66L, 0x00006FE5D541F71CL }; - PRIMEx16p = new long[] { 0x0000000000000010L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x2A00000000000000L, - 0x826D2F56C0F0EAE2L, 0xAD4C9CBD81067123L, 0xF62CF3052282F124L, 0x53A95F7469B516FEL, 0x3DADEC0D08A4732FL, 0x58AD934557C11C7EL, - 0x7F731B89B2DA43F2L, 0x51AE9F5F5F6AFF3BL, 0xD74319A6C9BCA375L, 0x5BAB790796CF84D4L, 0xA421554FE2E49CA8L, 0x20AD617C8DF437CFL, - 0x3AB06E7A12F5FF7BL, 0x70A25E037E40347EL, 0x51F1D323FB4C1151L, 0xAE0D99AA4835FED9L, 0xDF5429960D2536B6L, 0x000000030E91D466L }; - Alice_order = new long[] { 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0010000000000000L }; - Bob_order = new long[] { 0xC968549F878A8EEBL, 0x59B1A13F7CC76E3EL, 0xE9867D6EBE876DA9L, 0x2B5045CB25748084L, 0x2909F97BADC66856L, 0x06FE5D541F71C0E1L }; - A_gen = new long[] { 0x884F46B74000BAA8L, 0xBA52630F939DEC20L, 0xC16FB97BA714A04DL, 0x082536745B1AB3DBL, 0x1117157F446F9E82L, 0xD2F27D621A018490L, - 0x6B24AB523D544BCDL, 0x9307D6AA2EA85C94L, 0xE1A096729528F20FL, 0x896446F868F3255CL, 0x2401D996B1BFF8A5L, 0x00000EF8786A5C0AL, // XPA0 - 0xAEB78B3B96F59394L, 0xAB26681E29C90B74L, 0xE520AC30FDC4ACF1L, 0x870AAAE3A4B8111BL, 0xF875BDB738D64EFFL, 0x50109A7ECD7ED6BCL, - 0x4CC64848FF0C56FBL, 0xE617CB6C519102C9L, 0x9C74B3835921E609L, 0xC91DDAE4A35A7146L, 0x7FC82A155C1B9129L, 0x0000214FA6B980B3L, // XPA1 - 0x0F93CC38680A8CA9L, 0x762E733822E7FED7L, 0xE549F005AC0ADB67L, 0x94A71FDD2C43A4EDL, 0xD48645C2B04721C5L, 0x432DA1FE4D4CA4DCL, - 0xBC99655FAA7A80E8L, 0xB2C6D502BCFD4823L, 0xEE92F40CA2EC8BDBL, 0x7B074132EFB6D16CL, 0x3340B46FA38A7633L, 0x0000215749657F6CL, // XQA0 - 0xECFF375BF3079F4CL, 0xFBFE74B043E80EF3L, 0x17376CBE3C5C7AD1L, 0xC06327A7E29CDBF2L, 0x2111649C438BF3D4L, 0xC1F9298261BA2E97L, - 0x1F9FECE869CFD1C2L, 0x01A39B4FC9346D62L, 0x147CD1D3E82A3C9FL, 0xDE84E9D249E533EEL, 0x1C48A5ADFB7C578DL, 0x000061ACA0B82E1DL, // XQA1 - 0x1600C525D41059F1L, 0xA596899A0A1D83F7L, 0x6BFDEED6D2B23F35L, 0x5C7E707270C23910L, 0x276CA1A4E8369411L, 0xB193651A602925A0L, - 0x243D239F1CA1F04AL, 0x543DC6DA457860ADL, 0xCDA590F325181DE9L, 0xD3AB7ACFDA80B395L, 0x6C97468580FDDF7BL, 0x0000352A3E5C4C77L, // XRA0 - 0x9B794F9FD1CC3EE8L, 0xDB32E40A9B2FD23EL, 0x26192A2542E42B67L, 0xA18E94FCA045BCE7L, 0x96DC1BC38E7CDA2DL, 0x9A1D91B752487DE2L, - 0xCC63763987436DA3L, 0x1316717AACCC551DL, 0xC4C368A4632AFE72L, 0x4B6EA85C9CCD5710L, 0x7A12CAD582C7BC9AL, 0x00001C7E240149BFL }; // XRA1 - B_gen = new long[] { 0x85691AAF4015F88CL, 0x7478C5B8C36E9631L, 0x7EF2A185DE4DD6E2L, 0x943BBEE46BEB9DC7L, 0x1A3EC62798792D22L, 0x791BC4B084B31D69L, - 0x03DBE6522CEA17C4L, 0x04749AA65D665D83L, 0x3D52B5C45EF450F3L, 0x0B4219848E36947DL, 0xA4CF7070466BDE27L, 0x0000334B1FA6D193L, // XPB0 - 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, - 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, // XPB1 - 0x8E7CB3FA53211340L, 0xD67CE54F7A05EEE0L, 0xFDDC2C8BCE46FC38L, 0x08587FAE3110DF1EL, 0xD6B8246FA22B058BL, 0x4DAC3ACC905A5DBDL, - 0x51D0BF2FADCED3E8L, 0xE5A2406DF6484425L, 0x907F177584F671B8L, 0x4738A2FFCCED051CL, 0x2B0067B4177E4853L, 0x00002806AC948D3DL, // XQB0 - 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, - 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, // XQB1 - 0xB56457016D1D6D1CL, 0x03DECCB38F39C491L, 0xDFB910AC8A559452L, 0xA9D0F17D1FF24883L, 0x8562BBAF515C248CL, 0x249B2A6DDB1CB67DL, - 0x3131AF96FB46835CL, 0xE10258398480C3E1L, 0xEAB5E2B872D4FAB1L, 0xB71E63875FAEB1DFL, 0xF8384D4F13757CF6L, 0x0000361EC9B09912L, // XRB0 - 0x58C967899ED16EF4L, 0x81998376DC622A4BL, 0x3D1C1DCFE0B12681L, 0x9347DEBB953E1730L, 0x9ABB344D3A82C2D7L, 0xE4881BD2820552B2L, - 0x0037247923D90266L, 0x2E3156EDB157E5A5L, 0xF86A46A7506823F7L, 0x8FE5523A7B7F1CFCL, 0xFA3CFFA38372F67BL, 0x0000692DCE85FFBDL }; // XRB1 - Montgomery_R2 = new long[] { 0x233046449DAD4058L, 0xDB010161A696452AL, 0x5E36941472E3FD8EL, 0xF40BFE2082A2E706L, 0x4932CCA8904F8751L, 0x1F735F1F1EE7FC81L, - 0xA24F4D80C1048E18L, 0xB56C383CCDB607C5L, 0x441DD47B735F9C90L, 0x5673ED2C6A6AC82AL, 0x06C905261132294BL, 0x000041AD830F1F35L }; - Montgomery_one = new long[] { 0x00000000000249adL, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x8310000000000000L, - 0x5527b1e4375c6c66L, 0x697797bf3f4f24d0L, 0xc89db7b2ac5c4e2eL, 0x4ca4b439d2076956L, 0x10f7926c7512c7e9L, 0x00002d5b24bce5e2L }; - - strat_Alice = new int[] { - 80, 48, 27, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1, - 1, 3, 2, 1, 1, 1, 1, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, - 1, 1, 2, 1, 1, 1, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, - 1, 1, 1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, - 33, 20, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1, 2, 1, - 1, 1, 8, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, - 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1 }; - - strat_Bob = new int[] { - 112, 63, 32, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, - 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, - 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 31, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, - 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4, - 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 49, 31, 16, 8, 4, 2, - 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, - 15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, - 1, 1, 1, 21, 12, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 5, 3, 2, 1, 1, 1, 1, - 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1 }; - - - if(COMPRESS) - { - MASK2_BOB = 0x00; - MASK3_BOB = 0xFF; - ORDER_A_ENCODED_BYTES = SECRETKEY_A_BYTES; - ORDER_B_ENCODED_BYTES = SECRETKEY_B_BYTES; - PARTIALLY_COMPRESSED_CHUNK_CT = (4 * ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES + 2); - COMPRESSED_CHUNK_CT = (3 * ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES + 2); - UNCOMPRESSEDPK_BYTES = 564; - // Table sizes used by the Entangled basis generation - TABLE_R_LEN = 17; - TABLE_V_LEN = 34; - TABLE_V3_LEN = 20; - // Parameters for discrete log computations - // Binary Pohlig-Hellman reduced to smaller logs of order ell^W - W_2 = 4; - W_3 = 3; - // ell^w - ELL2_W = (1 << W_2); - ELL3_W = 27; - // ell^(e mod w) - ELL2_EMODW = (1 << (OALICE_BITS % W_2)); - ELL3_EMODW = 9; - // # of digits in the discrete log - DLEN_2 = ((OALICE_BITS + W_2 - 1) / W_2); - DLEN_3 = ((OBOB_EXPON + W_3 - 1) / W_3); - PLEN_2 = 94; - PLEN_3 = 81; - - // Import compression tables from properties - InputStream input = P751.class.getResourceAsStream("p751.properties"); - Properties props = new Properties(); - // load a properties file - try - { - props.load(input); - } - catch (IOException e) - { - throw new IllegalStateException("unable to load Picnic properties: " + e.getMessage(), e); - } - ph2_path = Internal.ReadIntsFromProperty(props,"ph2_path", PLEN_2); - ph3_path = Internal.ReadIntsFromProperty(props,"ph3_path", PLEN_3); - A_gen = Internal.ReadFromProperty(props,"A_gen", 6 * NWORDS64_FIELD); - B_gen = Internal.ReadFromProperty(props,"B_gen", 6 * NWORDS64_FIELD); - XQB3 = Internal.ReadFromProperty(props,"XQB3", 2 * NWORDS64_FIELD); - A_basis_zero = Internal.ReadFromProperty(props,"A_basis_zero", 8 * NWORDS64_FIELD); - B_basis_zero = Internal.ReadFromProperty(props,"B_basis_zero", 8 * NWORDS64_FIELD); - B_gen_3_tors = Internal.ReadFromProperty(props,"B_gen_3_tors", 16 * NWORDS64_FIELD); - g_R_S_im = Internal.ReadFromProperty(props,"g_R_S_im", NWORDS64_FIELD ); - Montgomery_R2 = Internal.ReadFromProperty(props,"Montgomery_R2", NWORDS64_FIELD); - Montgomery_RB1 = Internal.ReadFromProperty(props,"Montgomery_RB1", NWORDS64_FIELD); - Montgomery_RB2 = Internal.ReadFromProperty(props,"Montgomery_RB2", NWORDS64_FIELD); - Montgomery_one = Internal.ReadFromProperty(props, "Montgomery_one", NWORDS64_FIELD); - threeinv = Internal.ReadFromProperty(props,"threeinv", NWORDS64_FIELD); - u_entang = Internal.ReadFromProperty(props,"u_entang", 2 * NWORDS64_FIELD); - u0_entang = Internal.ReadFromProperty(props,"u0_entang", 2 * NWORDS64_FIELD); - table_r_qr = Internal.ReadFromProperty(props,"table_r_qr", TABLE_R_LEN, NWORDS64_FIELD); - table_r_qnr = Internal.ReadFromProperty(props,"table_r_qnr", TABLE_R_LEN, NWORDS64_FIELD); - table_v_qr = Internal.ReadFromProperty(props,"table_v_qr", TABLE_V_LEN, NWORDS64_FIELD); - table_v_qnr = Internal.ReadFromProperty(props,"table_v_qnr", TABLE_V_LEN, NWORDS64_FIELD); - v_3_torsion = Internal.ReadFromProperty(props,"v_3_torsion", TABLE_V3_LEN, 2, NWORDS64_FIELD); - T_tate3 = Internal.ReadFromProperty(props,"T_tate3", (6 * (OBOB_EXPON - 1) + 4) * NWORDS64_FIELD); - T_tate2_firststep_P = Internal.ReadFromProperty(props,"T_tate2_firststep_P", 4 * NWORDS64_FIELD); - T_tate2_P = Internal.ReadFromProperty(props,"T_tate2_P", 3 * (OALICE_BITS - 2) * NWORDS64_FIELD); - T_tate2_firststep_Q = Internal.ReadFromProperty(props,"T_tate2_firststep_Q", 4 * NWORDS64_FIELD); - T_tate2_Q = Internal.ReadFromProperty(props,"T_tate2_Q", 3 * (OALICE_BITS - 2) * NWORDS64_FIELD); - ph2_T = Internal.ReadFromProperty(props,"ph2_T",DLEN_2*(ELL2_W >>> 1)*2*NWORDS64_FIELD); - ph3_T1 = Internal.ReadFromProperty(props, "ph3_T1", DLEN_3*(ELL3_W>>1)*2*NWORDS64_FIELD); - ph3_T2 = Internal.ReadFromProperty(props, "ph3_T2", DLEN_3*(ELL3_W>>1)*2*NWORDS64_FIELD); - - Montgomery_R = new long[NWORDS64_FIELD]; - ph2_T1 = new long[2*((DLEN_2 - 1)*(ELL2_W/2) + (ph2_path[PLEN_2 - 1]-1))]; - ph2_T2 = new long[2*((DLEN_2 - 1)*(ELL2_W/2) + (ph2_path[PLEN_2 - 1]-1))]; - ph3_T = new long[DLEN_3*(ELL3_W>>1)*2*NWORDS64_FIELD]; - } - - - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/PointProj.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/PointProj.java deleted file mode 100644 index 7056d2f804..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/PointProj.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -class PointProj -{ - PointProj(int nwords_field) - { - X = new long[2][nwords_field]; - Z = new long[2][nwords_field]; - } - long[][] X; - long[][] Z; -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/PointProjFull.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/PointProjFull.java deleted file mode 100644 index a641dab608..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/PointProjFull.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -class PointProjFull -{ - PointProjFull(int nwords_field) - { - X = new long[2][nwords_field]; - Y = new long[2][nwords_field]; - Z = new long[2][nwords_field]; - } - long[][] X; - long[][] Y; - long[][] Z; -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIDH.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIDH.java deleted file mode 100644 index 0322e095b1..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIDH.java +++ /dev/null @@ -1,358 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - - -class SIDH -{ - - private SIKEEngine engine; - - public SIDH(SIKEEngine engine) - { - this.engine = engine; - } - - // Initialization of basis points - protected void init_basis(long[] gen, long[][] XP, long[][] XQ, long[][] XR) - { - engine.fpx.fpcopy(gen, 0, XP[0]); - engine.fpx.fpcopy(gen, engine.params.NWORDS_FIELD, XP[1]); - engine.fpx.fpcopy(gen, 2 * engine.params.NWORDS_FIELD, XQ[0]); - engine.fpx.fpcopy(gen, 3 * engine.params.NWORDS_FIELD, XQ[1]); - engine.fpx.fpcopy(gen, 4 * engine.params.NWORDS_FIELD, XR[0]); - engine.fpx.fpcopy(gen, 5 * engine.params.NWORDS_FIELD, XR[1]); - } - - // Bob's ephemeral public key generation - // Input: a private key PrivateKeyB in the range [0, 2^Floor(Log(2,oB)) - 1]. - // Output: the public key PublicKeyB consisting of 3 elements in GF(p^2) which are encoded by removing leading 0 bytes. - protected void EphemeralKeyGeneration_B(byte[] sk, byte[] pk) - { - PointProj R = new PointProj(engine.params.NWORDS_FIELD), - phiP = new PointProj(engine.params.NWORDS_FIELD), - phiQ = new PointProj(engine.params.NWORDS_FIELD), - phiR = new PointProj(engine.params.NWORDS_FIELD); - - PointProj[] pts = new PointProj[engine.params.MAX_INT_POINTS_BOB]; - - long[][] XPB = new long[2][engine.params.NWORDS_FIELD], - XQB = new long[2][engine.params.NWORDS_FIELD], - XRB = new long[2][engine.params.NWORDS_FIELD], - A24plus = new long[2][engine.params.NWORDS_FIELD], - A24minus = new long[2][engine.params.NWORDS_FIELD], - A = new long[2][engine.params.NWORDS_FIELD]; - - long[][][] coeff = new long[3][2][engine.params.NWORDS_FIELD]; - int i, row, m, index = 0, npts = 0, ii = 0; - int[] pts_index = new int[engine.params.MAX_INT_POINTS_BOB]; - long[] SecretKeyB = new long[engine.params.NWORDS_ORDER]; - - // Initialize basis points - init_basis(engine.params.B_gen, XPB, XQB, XRB); - init_basis(engine.params.A_gen, phiP.X, phiQ.X, phiR.X); - engine.fpx.fpcopy(engine.params.Montgomery_one,0,phiP.Z[0]); - engine.fpx.fpcopy(engine.params.Montgomery_one,0,phiQ.Z[0]); - engine.fpx.fpcopy(engine.params.Montgomery_one,0,phiR.Z[0]); - - // Initialize constants: A24minus = A-2C, A24plus = A+2C, where A=6, C=1 - engine.fpx.fpcopy(engine.params.Montgomery_one, 0,A24plus[0]); - engine.fpx.mp2_add(A24plus, A24plus, A24plus); - engine.fpx.mp2_add(A24plus, A24plus, A24minus); - engine.fpx.mp2_add(A24plus, A24minus, A); - engine.fpx.mp2_add(A24minus, A24minus, A24plus); - engine.fpx.decode_to_digits(sk, engine.params.MSG_BYTES, SecretKeyB, engine.params.SECRETKEY_B_BYTES, engine.params.NWORDS_ORDER); - engine.isogeny.LADDER3PT(XPB, XQB, XRB, SecretKeyB, engine.params.BOB, R, A); - - // Traverse tree - index =0; - for(row = 1; row < engine.params.MAX_Bob; row++) - { - while (index < engine.params.MAX_Bob - row) - { - pts[npts] = new PointProj(engine.params.NWORDS_FIELD); - engine.fpx.fp2copy(R.X, pts[npts].X); - engine.fpx.fp2copy(R.Z, pts[npts].Z); - pts_index[npts++] = index; - m = engine.params.strat_Bob[ii++]; - engine.isogeny.xTPLe(R, R, A24minus, A24plus, m); - index += m; - } - engine.isogeny.get_3_isog(R, A24minus, A24plus, coeff); - - for (i = 0; i < npts; i++) - { - engine.isogeny.eval_3_isog(pts[i], coeff); - } - engine.isogeny.eval_3_isog(phiP, coeff); - engine.isogeny.eval_3_isog(phiQ, coeff); - engine.isogeny.eval_3_isog(phiR, coeff); - - engine.fpx.fp2copy(pts[npts - 1].X, R.X); - engine.fpx.fp2copy(pts[npts - 1].Z, R.Z); - index = pts_index[npts - 1]; - npts -= 1; - } - engine.isogeny.get_3_isog(R, A24minus, A24plus, coeff); - engine.isogeny.eval_3_isog(phiP, coeff); - engine.isogeny.eval_3_isog(phiQ, coeff); - engine.isogeny.eval_3_isog(phiR, coeff); - engine.isogeny.inv_3_way(phiP.Z, phiQ.Z, phiR.Z); - - engine.fpx.fp2mul_mont(phiP.X, phiP.Z, phiP.X); - engine.fpx.fp2mul_mont(phiQ.X, phiQ.Z, phiQ.X); - engine.fpx.fp2mul_mont(phiR.X, phiR.Z, phiR.X); - - // Format public key - engine.fpx.fp2_encode(phiP.X, pk, 0); - engine.fpx.fp2_encode(phiQ.X, pk, engine.params.FP2_ENCODED_BYTES); - engine.fpx.fp2_encode(phiR.X, pk, 2*engine.params.FP2_ENCODED_BYTES); - } - - // Alice's ephemeral public key generation - // Input: a private key PrivateKeyA in the range [0, 2^eA - 1]. - // Output: the public key PublicKeyA consisting of 3 elements in GF(p^2) which are encoded by removing leading 0 bytes. - protected void EphemeralKeyGeneration_A(byte[] ephemeralsk, byte[] ct) - { - PointProj R = new PointProj(engine.params.NWORDS_FIELD), - phiP = new PointProj(engine.params.NWORDS_FIELD), - phiQ = new PointProj(engine.params.NWORDS_FIELD), - phiR = new PointProj(engine.params.NWORDS_FIELD); - - PointProj[] pts = new PointProj[engine.params.MAX_INT_POINTS_ALICE]; - - long[][] XPA = new long[2][engine.params.NWORDS_FIELD], - XQA = new long[2][engine.params.NWORDS_FIELD], - XRA = new long[2][engine.params.NWORDS_FIELD], - A24plus = new long[2][engine.params.NWORDS_FIELD], - C24 = new long[2][engine.params.NWORDS_FIELD], - A = new long[2][engine.params.NWORDS_FIELD]; - - long[][][] coeff = new long[3][2][engine.params.NWORDS_FIELD]; - int i, row, m, index = 0, npts = 0, ii = 0; - int[] pts_index = new int[engine.params.MAX_INT_POINTS_ALICE]; - long[] SecretKeyA = new long[engine.params.NWORDS_ORDER]; - - // Initialize basis points - init_basis(engine.params.A_gen, XPA, XQA, XRA); - init_basis(engine.params.B_gen, phiP.X, phiQ.X, phiR.X); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, phiP.Z[0]); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, phiQ.Z[0]); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, phiR.Z[0]); - - // Initialize constants: A24plus = A+2C, C24 = 4C, where A=6, C=1 - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, A24plus[0]); - engine.fpx.mp2_add(A24plus, A24plus, A24plus); - engine.fpx.mp2_add(A24plus, A24plus, C24); - engine.fpx.mp2_add(A24plus, C24, A); - engine.fpx.mp2_add(C24, C24, A24plus); - - // Retrieve kernel point - engine.fpx.decode_to_digits(ephemeralsk, 0, SecretKeyA, engine.params.SECRETKEY_A_BYTES, engine.params.NWORDS_ORDER); - engine.isogeny.LADDER3PT(XPA, XQA, XRA, SecretKeyA, engine.params.ALICE, R, A); - - if (engine.params.OALICE_BITS % 2 == 1) - { - PointProj S = new PointProj(engine.params.NWORDS_FIELD); - engine.isogeny.xDBLe(R, S, A24plus, C24, (int) (engine.params.OALICE_BITS - 1)); - engine.isogeny.get_2_isog(S, A24plus, C24); - engine.isogeny.eval_2_isog(phiP, S); - engine.isogeny.eval_2_isog(phiQ, S); - engine.isogeny.eval_2_isog(phiR, S); - engine.isogeny.eval_2_isog(R, S); - } - - // Traverse tree - index = 0; - for (row = 1; row < engine.params.MAX_Alice; row++) - { - while (index < engine.params.MAX_Alice-row) - { - pts[npts] = new PointProj(engine.params.NWORDS_FIELD); - engine.fpx.fp2copy(R.X, pts[npts].X); - engine.fpx.fp2copy(R.Z, pts[npts].Z); - pts_index[npts++] = index; - m = engine.params.strat_Alice[ii++]; - engine.isogeny.xDBLe(R, R, A24plus, C24, (int)(2*m)); - index += m; - } - engine.isogeny.get_4_isog(R, A24plus, C24, coeff); - - for (i = 0; i < npts; i++) - { - engine.isogeny.eval_4_isog(pts[i], coeff); - } - engine.isogeny.eval_4_isog(phiP, coeff); - engine.isogeny.eval_4_isog(phiQ, coeff); - engine.isogeny.eval_4_isog(phiR, coeff); - - engine.fpx.fp2copy(pts[npts-1].X, R.X); - engine.fpx.fp2copy(pts[npts-1].Z, R.Z); - index = pts_index[npts-1]; - npts -= 1; - } - - engine.isogeny.get_4_isog(R, A24plus, C24, coeff); - engine.isogeny.eval_4_isog(phiP, coeff); - engine.isogeny.eval_4_isog(phiQ, coeff); - engine.isogeny.eval_4_isog(phiR, coeff); - - engine.isogeny.inv_3_way(phiP.Z, phiQ.Z, phiR.Z); - engine.fpx.fp2mul_mont(phiP.X, phiP.Z, phiP.X); - engine.fpx.fp2mul_mont(phiQ.X, phiQ.Z, phiQ.X); - engine.fpx.fp2mul_mont(phiR.X, phiR.Z, phiR.X); - - // Format public key - engine.fpx.fp2_encode(phiP.X, ct,0); - engine.fpx.fp2_encode(phiQ.X, ct, engine.params.FP2_ENCODED_BYTES); - engine.fpx.fp2_encode(phiR.X, ct,2*engine.params.FP2_ENCODED_BYTES); - - } - - // Alice's ephemeral shared secret computation - // It produces a shared secret key SharedSecretA using her secret key PrivateKeyA and Bob's public key PublicKeyB - // Inputs: Alice's PrivateKeyA is an integer in the range [0, oA-1]. - // Bob's PublicKeyB consists of 3 elements in GF(p^2) encoded by removing leading 0 bytes. - // Output: a shared secret SharedSecretA that consists of one element in GF(p^2) encoded by removing leading 0 bytes. - protected void EphemeralSecretAgreement_A(byte[] ephemeralsk, byte[] pk, byte[] jinvariant) - { - PointProj R = new PointProj(engine.params.NWORDS_FIELD); - PointProj[] pts = new PointProj[engine.params.MAX_INT_POINTS_ALICE]; - long[][][] PKB = new long[3][2][engine.params.NWORDS_FIELD], - coeff = new long[3][2][engine.params.NWORDS_FIELD]; - long[][] jinv = new long[2][engine.params.NWORDS_FIELD], - A24plus = new long[2][engine.params.NWORDS_FIELD], - C24 = new long[2][engine.params.NWORDS_FIELD], - A = new long[2][engine.params.NWORDS_FIELD]; - - int i = 0, row = 0, m = 0, index = 0, npts = 0, ii = 0; - int[] pts_index = new int[engine.params.MAX_INT_POINTS_ALICE]; - long[] SecretKeyA = new long[engine.params.NWORDS_ORDER]; - - // Initialize images of Bob's basis - engine.fpx.fp2_decode(pk, PKB[0], 0); - engine.fpx.fp2_decode(pk, PKB[1], engine.params.FP2_ENCODED_BYTES); - engine.fpx.fp2_decode(pk, PKB[2], 2*engine.params.FP2_ENCODED_BYTES); - - // Initialize constants: A24plus = A+2C, C24 = 4C, where C=1 - engine.isogeny.get_A(PKB[0], PKB[1], PKB[2], A); - engine.fpx.mp_add(engine.params.Montgomery_one, engine.params.Montgomery_one, C24[0], engine.params.NWORDS_FIELD); - engine.fpx.mp2_add(A, C24, A24plus); - engine.fpx.mp_add(C24[0], C24[0], C24[0], engine.params.NWORDS_FIELD); - - // Retrieve kernel point - engine.fpx.decode_to_digits(ephemeralsk, 0, SecretKeyA, engine.params.SECRETKEY_A_BYTES, engine.params.NWORDS_ORDER); - engine.isogeny.LADDER3PT(PKB[0], PKB[1], PKB[2], SecretKeyA, engine.params.ALICE, R, A); - - if (engine.params.OALICE_BITS % 2 == 1) - { - PointProj S = new PointProj(engine.params.NWORDS_FIELD); - - engine.isogeny.xDBLe(R, S, A24plus, C24, (int) (engine.params.OALICE_BITS - 1)); - engine.isogeny.get_2_isog(S, A24plus, C24); - engine.isogeny.eval_2_isog(R, S); - } - - // Traverse tree - index = 0; - for (row = 1; row < engine.params.MAX_Alice; row++) - { - while (index < engine.params.MAX_Alice-row) - { - pts[npts] = new PointProj(engine.params.NWORDS_FIELD); - engine.fpx.fp2copy(R.X, pts[npts].X); - engine.fpx.fp2copy(R.Z, pts[npts].Z); - pts_index[npts++] = index; - m = engine.params.strat_Alice[ii++]; - engine.isogeny.xDBLe(R, R, A24plus, C24, (int)(2*m)); - index += m; - } - engine.isogeny.get_4_isog(R, A24plus, C24, coeff); - - for (i = 0; i < npts; i++) - { - engine.isogeny.eval_4_isog(pts[i], coeff); - } - - engine.fpx.fp2copy(pts[npts-1].X, R.X); - engine.fpx.fp2copy(pts[npts-1].Z, R.Z); - index = pts_index[npts-1]; - npts -= 1; - } - - engine.isogeny.get_4_isog(R, A24plus, C24, coeff); - engine.fpx.mp2_add(A24plus, A24plus, A24plus); - engine.fpx.fp2sub(A24plus, C24, A24plus); - engine.fpx.fp2add(A24plus, A24plus, A24plus); - engine.isogeny.j_inv(A24plus, C24, jinv); - engine.fpx.fp2_encode(jinv, jinvariant, 0); // Format shared secret - } - - // Bob's ephemeral shared secret computation - // It produces a shared secret key SharedSecretB using his secret key PrivateKeyB and Alice's public key PublicKeyA - // Inputs: Bob's PrivateKeyB is an integer in the range [0, 2^Floor(Log(2,oB)) - 1]. - // Alice's PublicKeyA consists of 3 elements in GF(p^2) encoded by removing leading 0 bytes. - // Output: a shared secret SharedSecretB that consists of one element in GF(p^2) encoded by removing leading 0 bytes. - protected void EphemeralSecretAgreement_B(byte[] sk, byte[] ct, byte[] jinvariant_) - { - PointProj R = new PointProj(engine.params.NWORDS_FIELD); - PointProj[] pts = new PointProj[engine.params.MAX_INT_POINTS_BOB]; - long[][][] coeff = new long[3][2][engine.params.NWORDS_FIELD], - PKB = new long[3][2][engine.params.NWORDS_FIELD]; - long[][] jinv = new long[2][engine.params.NWORDS_FIELD], - A24plus = new long[2][engine.params.NWORDS_FIELD], - A24minus = new long[2][engine.params.NWORDS_FIELD], - A = new long[2][engine.params.NWORDS_FIELD]; - int i, row, m, index = 0, npts = 0, ii = 0; - int[] pts_index = new int[engine.params.MAX_INT_POINTS_BOB]; - long[] SecretKeyB = new long[engine.params.NWORDS_ORDER]; - - // Initialize images of Alice's basis - engine.fpx.fp2_decode(ct, PKB[0], 0); - engine.fpx.fp2_decode(ct, PKB[1], engine.params.FP2_ENCODED_BYTES); - engine.fpx.fp2_decode(ct, PKB[2], 2*engine.params.FP2_ENCODED_BYTES); - - // Initialize constants: A24plus = A+2C, A24minus = A-2C, where C=1 - engine.isogeny.get_A(PKB[0], PKB[1], PKB[2], A); - engine.fpx.mp_add(engine.params.Montgomery_one, engine.params.Montgomery_one, A24minus[0], engine.params.NWORDS_FIELD); - engine.fpx.mp2_add(A, A24minus, A24plus); - engine.fpx.mp2_sub_p2(A, A24minus, A24minus); - - // Retrieve kernel point - engine.fpx.decode_to_digits(sk, engine.params.MSG_BYTES, SecretKeyB, engine.params.SECRETKEY_B_BYTES, engine.params.NWORDS_ORDER); - engine.isogeny.LADDER3PT(PKB[0], PKB[1], PKB[2], SecretKeyB, engine.params.BOB, R, A); - - // Traverse tree - index = 0; - for (row = 1; row < engine.params.MAX_Bob; row++) - { - while (index < engine.params.MAX_Bob-row) - { - pts[npts] = new PointProj(engine.params.NWORDS_FIELD); - engine.fpx.fp2copy(R.X, pts[npts].X); - engine.fpx.fp2copy(R.Z, pts[npts].Z); - pts_index[npts++] = index; - m = engine.params.strat_Bob[ii++]; - engine.isogeny.xTPLe(R, R, A24minus, A24plus, (int)m); - index += m; - } - engine.isogeny.get_3_isog(R, A24minus, A24plus, coeff); - - for (i = 0; i < npts; i++) - { - engine.isogeny.eval_3_isog(pts[i], coeff); - } - - engine.fpx.fp2copy(pts[npts-1].X, R.X); - engine.fpx.fp2copy(pts[npts-1].Z, R.Z); - index = pts_index[npts-1]; - npts -= 1; - } - - engine.isogeny.get_3_isog(R, A24minus, A24plus, coeff); - engine.fpx.fp2add(A24plus, A24minus, A); - engine.fpx.fp2add(A, A, A); - engine.fpx.fp2sub(A24plus, A24minus, A24plus); - engine.isogeny.j_inv(A, A24plus, jinv); - engine.fpx.fp2_encode(jinv, jinvariant_, 0); // Format shared secret - } - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIDH_Compressed.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIDH_Compressed.java deleted file mode 100644 index c33b09f585..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIDH_Compressed.java +++ /dev/null @@ -1,2421 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import java.security.SecureRandom; - -import org.bouncycastle.util.Arrays; - -class SIDH_Compressed -{ - private SIKEEngine engine; - - public SIDH_Compressed(SIKEEngine engine) - { - this.engine = engine; - } - protected void init_basis(long[] gen, long[][] XP, long[][] XQ, long[][] XR) - { // Initialization of basis points - - engine.fpx.fpcopy(gen, 0, XP[0]); - engine.fpx.fpcopy(gen, engine.params.NWORDS_FIELD, XP[1]); - engine.fpx.fpcopy(gen, 2*engine.params.NWORDS_FIELD, XQ[0]); - engine.fpx.fpcopy(gen, 3*engine.params.NWORDS_FIELD, XQ[1]); - engine.fpx.fpcopy(gen, 4*engine.params.NWORDS_FIELD, XR[0]); - engine.fpx.fpcopy(gen, 5*engine.params.NWORDS_FIELD, XR[1]); - } - - - protected void FormatPrivKey_B(byte[] skB) - { - skB[engine.params.SECRETKEY_B_BYTES-2] &= engine.params.MASK3_BOB; - skB[engine.params.SECRETKEY_B_BYTES-1] &= engine.params.MASK2_BOB; // Clear necessary bits so that 3*ephemeralsk is still less than Bob_order - engine.fpx.mul3(skB); // Multiply ephemeralsk by 3 - } - - // Generation of Alice's secret key - // Outputs random value in [0, 2^eA - 1] - protected void random_mod_order_A(byte[] random_digits, SecureRandom random) - { - byte[] temp = new byte[engine.params.SECRETKEY_A_BYTES]; - random.nextBytes(temp); - System.arraycopy(temp, 0, random_digits, 0, engine.params.SECRETKEY_A_BYTES); - random_digits[0] &= 0xFE; // Make private scalar even - random_digits[engine.params.SECRETKEY_A_BYTES-1] &= engine.params.MASK_ALICE; // Masking last byte - } - - // Generation of Bob's secret key - // Outputs random value in [0, 2^Floor(Log(2, oB)) - 1] - protected void random_mod_order_B(byte[] random_digits, SecureRandom random) - { - byte[] temp = new byte[engine.params.SECRETKEY_B_BYTES]; - random.nextBytes(temp); - System.arraycopy(temp, 0, random_digits, 0, engine.params.SECRETKEY_A_BYTES); - FormatPrivKey_B(random_digits); - } - - // Project 3-point ladder - protected void Ladder3pt_dual(PointProj[] Rs, long[] m, int AliceOrBob, PointProj R, long[][] A24) - { - PointProj R0 = new PointProj(engine.params.NWORDS_FIELD), - R2 = new PointProj(engine.params.NWORDS_FIELD); - long mask; - int i, nbits, bit, swap, prevbit = 0; - - if (AliceOrBob == engine.params.ALICE) - { - nbits = engine.params.OALICE_BITS; - } else - { - nbits = engine.params.OBOB_BITS; - } - - engine.fpx.fp2copy(Rs[1].X, R0.X); - engine.fpx.fp2copy(Rs[1].Z, R0.Z); - engine.fpx.fp2copy(Rs[2].X, R2.X); - engine.fpx.fp2copy(Rs[2].Z, R2.Z); - engine.fpx.fp2copy(Rs[0].X, R.X); - engine.fpx.fp2copy(Rs[0].Z, R.Z); - - // Main loop - for (i = 0; i < nbits; i++) - { - bit = (int) ((m[i >>> Internal.LOG2RADIX] >>> (i & (Internal.RADIX-1))) & 1); - swap = bit ^ prevbit; - prevbit = bit; - mask = 0 - (long)swap; - - engine.isogeny.swap_points(R, R2, mask); - engine.isogeny.xDBLADD(R0, R2, R.X, A24); - engine.fpx.fp2mul_mont(R2.X, R.Z, R2.X); - } - swap = 0 ^ prevbit; - mask = 0 - (long)swap; - engine.isogeny.swap_points(R, R2, mask); - } - - - - protected void Elligator2(long[][] a24, int[] r, int rIndex, long[][] x, byte[] bit, int bitOffset, int COMPorDEC) - { // Generate an x-coordinate of a point on curve with (affine) coefficient a24 - // Use the counter r - int i; - long[] one_fp = new long[engine.params.NWORDS_FIELD], - a2 = new long[engine.params.NWORDS_FIELD], - b2 = new long[engine.params.NWORDS_FIELD], - N = new long[engine.params.NWORDS_FIELD], - temp0 = new long[engine.params.NWORDS_FIELD], - temp1 = new long[engine.params.NWORDS_FIELD]; - long[][] A = new long[2][engine.params.NWORDS_FIELD], - y2 = new long[2][engine.params.NWORDS_FIELD]; - - int t_ptr = 0; - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, one_fp); - engine.fpx.fp2add(a24, a24, A); - engine.fpx.fpsubPRIME(A[0], one_fp, A[0]); - engine.fpx.fp2add(A, A, A); // A = 4*a24-2 - - // Elligator computation - t_ptr = r[rIndex]; //(long[][] *)&v_3_torsion[r]; - engine.fpx.fp2mul_mont(A, engine.params.v_3_torsion[t_ptr], x); // x = A*v; v := 1/(1 + U*r^2) table lookup - engine.fpx.fp2neg(x); // x = -A*v; - - if (COMPorDEC == 0) //COMPRESSION - { - engine.fpx.fp2add(A, x, y2); // y2 = x + A - engine.fpx.fp2mul_mont(y2, x, y2); // y2 = x*(x + A) - engine.fpx.fpaddPRIME(y2[0], one_fp, y2[0]); // y2 = x(x + A) + 1 - engine.fpx.fp2mul_mont(x, y2, y2); // y2 = x*(x^2 + Ax + 1); - engine.fpx.fpsqr_mont(y2[0], a2); - engine.fpx.fpsqr_mont(y2[1], b2); - engine.fpx.fpaddPRIME(a2, b2, N); // N := norm(y2); - engine.fpx.fpcopy(N,0, temp0); - for (i = 0; i < engine.params.OALICE_BITS - 2; i++) - { - engine.fpx.fpsqr_mont(temp0, temp0); - } - for (i = 0; i < engine.params.OBOB_EXPON; i++) - { - engine.fpx.fpsqr_mont(temp0, temp1); - engine.fpx.fpmul_mont(temp0, temp1, temp0); - } - engine.fpx.fpsqr_mont(temp0, temp1); // z = N^((p + 1) div 4); - engine.fpx.fpcorrectionPRIME(temp1); - engine.fpx.fpcorrectionPRIME(N); - if(!Fpx.subarrayEquals(temp1, N, engine.params.NWORDS_FIELD)) - { - engine.fpx.fp2neg(x); - engine.fpx.fp2sub(x, A, x); // x = -x - A; - if (COMPorDEC == 0) - { - bit[bitOffset] = 1; - } - } - } - else - { - if (bit[bitOffset] == 1) - { - engine.fpx.fp2neg(x); - engine.fpx.fp2sub(x,A,x); // x = -x - A; - } - } - } - - - protected void make_positive(long[][] x) - { - int nbytes = engine.params.NWORDS_FIELD; - long[] zero = new long[engine.params.NWORDS_FIELD]; - - engine.fpx.from_fp2mont(x, x); - if (!Fpx.subarrayEquals(x[0], zero, nbytes)) - { - if ((x[0][0] & 1) == 1) - { - engine.fpx.fp2neg(x); - } - } - else - { - if ((x[1][0] & 1) == 1) - { - engine.fpx.fp2neg(x); - } - } - engine.fpx.to_fp2mont(x, x); - } - - - protected void BiQuad_affine(long[][] a24, long[][] x0, long[][] x1, PointProj R) - { - long[][] Ap2 = new long[2][engine.params.NWORDS_FIELD], - aa = new long[2][engine.params.NWORDS_FIELD], - bb = new long[2][engine.params.NWORDS_FIELD], - cc = new long[2][engine.params.NWORDS_FIELD], - t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.fp2add(a24, a24, Ap2); - engine.fpx.fp2add(Ap2, Ap2, Ap2); // Ap2 = a+2 = 4*a24 - - engine.fpx.fp2sub(x0, x1, aa); - engine.fpx.fp2sqr_mont(aa, aa); - - engine.fpx.fp2mul_mont(x0, x1, cc); - engine.fpx.fpsubPRIME(cc[0], engine.params.Montgomery_one, cc[0]); - engine.fpx.fp2sqr_mont(cc, cc); - - engine.fpx.fpsubPRIME(x0[0], engine.params.Montgomery_one, bb[0]); - engine.fpx.fpcopy(x0[1], 0, bb[1]); - engine.fpx.fp2sqr_mont(bb, bb); - engine.fpx.fp2mul_mont(Ap2, x0, t0); - engine.fpx.fp2add(bb, t0, bb); - engine.fpx.fp2mul_mont(x1, bb, bb); - engine.fpx.fpsubPRIME(x1[0], engine.params.Montgomery_one, t0[0]); - engine.fpx.fpcopy(x1[1], 0, t0[1]); - engine.fpx.fp2sqr_mont(t0, t0); - engine.fpx.fp2mul_mont(Ap2, x1, t1); - engine.fpx.fp2add(t0, t1, t0); - engine.fpx.fp2mul_mont(x0, t0, t0); - engine.fpx.fp2add(bb, t0, bb); - engine.fpx.fp2add(bb, bb, bb); - - engine.fpx.fp2sqr_mont(bb, t0); - engine.fpx.fp2mul_mont(aa, cc, t1); - engine.fpx.fp2add(t1, t1, t1); - engine.fpx.fp2add(t1, t1, t1); - engine.fpx.fp2sub(t0, t1, t0); - engine.fpx.sqrt_Fp2(t0, t0); - make_positive(t0); // Make the sqrt "positive" - engine.fpx.fp2add(bb, t0, R.X); - engine.fpx.fp2add(aa, aa, R.Z); - } - - - protected void get_4_isog_dual(PointProj P, long[][] A24, long[][] C24, long[][][] coeff) - { - engine.fpx.fp2sub(P.X, P.Z, coeff[1]); - engine.fpx.fp2add(P.X, P.Z, coeff[2]); - engine.fpx.fp2sqr_mont(P.Z, coeff[4]); - engine.fpx.fp2add(coeff[4], coeff[4], coeff[0]); - engine.fpx.fp2sqr_mont(coeff[0], C24); - engine.fpx.fp2add(coeff[0], coeff[0], coeff[0]); - engine.fpx.fp2sqr_mont(P.X, coeff[3]); - engine.fpx.fp2add(coeff[3], coeff[3], A24); - engine.fpx.fp2sqr_mont(A24, A24); - } - - protected void eval_dual_2_isog(long[][] X2, long[][] Z2, PointProj P) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.fp2add(P.X, P.Z, t0); - engine.fpx.fp2sub(P.X, P.Z, P.Z); - engine.fpx.fp2sqr_mont(t0, t0); - engine.fpx.fp2sqr_mont(P.Z, P.Z); - engine.fpx.fp2sub(t0, P.Z, P.Z); - engine.fpx.fp2mul_mont(X2, P.Z, P.Z); - engine.fpx.fp2mul_mont(Z2, t0, P.X); - } - - protected void eval_final_dual_2_isog(PointProj P) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD]; - long[] t2 = new long[engine.params.NWORDS_FIELD]; - - engine.fpx.fp2add(P.X, P.Z, t0); - engine.fpx.fp2mul_mont(P.X, P.Z, t1); - engine.fpx.fp2sqr_mont(t0, P.X); - engine.fpx.fpcopy(P.X[0], 0, t2); - engine.fpx.fpcopy(P.X[1], 0, (P.X)[0]); - engine.fpx.fpcopy(t2, 0, P.X[1]); - engine.fpx.fpnegPRIME((P.X)[1]); - engine.fpx.fp2add(t1, t1, P.Z); - engine.fpx.fp2add(P.Z, P.Z, P.Z); - } - - - protected void eval_dual_4_isog_shared(long[][] X4pZ4, long[][] X42, long[][] Z42, long[][][] coeff, int coeffOffset) - { - engine.fpx.fp2sub(X42, Z42, coeff[0 + coeffOffset]); - engine.fpx.fp2add(X42, Z42, coeff[1 + coeffOffset]); - engine.fpx.fp2sqr_mont(X4pZ4, coeff[2 + coeffOffset]); - engine.fpx.fp2sub(coeff[2 + coeffOffset], coeff[1 + coeffOffset], coeff[2 + coeffOffset]); - } - - - protected void eval_dual_4_isog(long[][] A24, long[][] C24, long[][][] coeff, int coeffOffset, PointProj P) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - t2 = new long[2][engine.params.NWORDS_FIELD], - t3 = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.fp2add(P.X, P.Z, t0); - engine.fpx.fp2sub(P.X, P.Z, t1); - engine.fpx.fp2sqr_mont(t0, t0); - engine.fpx.fp2sqr_mont(t1, t1); - engine.fpx.fp2sub(t0, t1, t2); - engine.fpx.fp2sub(C24, A24, t3); - engine.fpx.fp2mul_mont(t2, t3, t3); - engine.fpx.fp2mul_mont(C24, t0, t2); - engine.fpx.fp2sub(t2, t3, t2); - engine.fpx.fp2mul_mont(t2, t0, P.X); - engine.fpx.fp2mul_mont(t3, t1, P.Z); - engine.fpx.fp2mul_mont(coeff[0 + coeffOffset], P.X, P.X); - engine.fpx.fp2mul_mont(coeff[1 + coeffOffset], P.Z, t0); - engine.fpx.fp2add(P.X, t0, P.X); - engine.fpx.fp2mul_mont(coeff[2 + coeffOffset], P.Z, P.Z); - } - - - protected void eval_full_dual_4_isog(long[][][][] As, PointProj P) - { - for(int i = 0; i < engine.params.MAX_Alice; i++) - { - eval_dual_4_isog(As[engine.params.MAX_Alice-i][0], - As[engine.params.MAX_Alice-i][1], - As[engine.params.MAX_Alice-i-1], 2, - P); - } - if (engine.params.OALICE_BITS % 2 == 1) - { - eval_dual_2_isog(As[engine.params.MAX_Alice][2], As[engine.params.MAX_Alice][3], P); - } - eval_final_dual_2_isog(P); // to A = 0 - } - - - protected void TripleAndParabola_proj(PointProjFull R, long[][] l1x, long[][] l1z) - { - engine.fpx.fp2sqr_mont(R.X, l1z); - engine.fpx.fp2add(l1z, l1z, l1x); - engine.fpx.fp2add(l1x, l1z, l1x); - engine.fpx.fpaddPRIME(l1x[0], engine.params.Montgomery_one, l1x[0]); - engine.fpx.fp2add(R.Y, R.Y, l1z); - } - - - protected void Tate3_proj(PointProjFull P, PointProjFull Q, long[][] gX, long[][] gZ) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - l1x = new long[2][engine.params.NWORDS_FIELD]; - - TripleAndParabola_proj(P, l1x, gZ); - engine.fpx.fp2sub(Q.X, P.X, gX); - engine.fpx.fp2mul_mont(l1x, gX, gX); - engine.fpx.fp2sub(P.Y, Q.Y, t0); - engine.fpx.fp2mul_mont(gZ, t0, t0); - engine.fpx.fp2add(gX, t0, gX); - } - - - protected void FinalExpo3(long[][] gX, long[][] gZ) - { - int i; - long[][] f_ = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.fp2copy(gZ, f_); - engine.fpx.fpnegPRIME(f_[1]); - engine.fpx.fp2mul_mont(gX, f_, f_); - engine.fpx.fp2inv_mont_bingcd(f_); - engine.fpx.fpnegPRIME(gX[1]); - engine.fpx.fp2mul_mont(gX,gZ, gX); - engine.fpx.fp2mul_mont(gX,f_, gX); - for(i = 0; i < engine.params.OALICE_BITS; i++) - { - engine.fpx.fp2sqr_mont(gX, gX); - } - for(i = 0; i < engine.params.OBOB_EXPON-1; i++) - { - engine.fpx.cube_Fp2_cycl(gX, engine.params.Montgomery_one); - } - } - - - protected void FinalExpo3_2way(long[][][] gX, long[][][] gZ) - { - int i, j; - long[][][] f_ = new long[2][2][engine.params.NWORDS_FIELD], - finv = new long[2][2][engine.params.NWORDS_FIELD]; - - for(i = 0; i < 2; i++) - { - engine.fpx.fp2copy(gZ[i], f_[i]); - engine.fpx.fpnegPRIME(f_[i][1]); // Conjugate - engine.fpx.fp2mul_mont(gX[i], f_[i], f_[i]); - } - engine.fpx.mont_n_way_inv(f_, 2, finv); - for(i = 0; i < 2; i++) - { - engine.fpx.fpnegPRIME(gX[i][1]); - engine.fpx.fp2mul_mont(gX[i], gZ[i], gX[i]); - engine.fpx.fp2mul_mont(gX[i], finv[i], gX[i]); - for(j = 0; j < engine.params.OALICE_BITS; j++) - { - engine.fpx.fp2sqr_mont(gX[i], gX[i]); - } - for(j = 0; j < engine.params.OBOB_EXPON-1; j++) - { - engine.fpx.cube_Fp2_cycl(gX[i], engine.params.Montgomery_one); - } - } - } - - - private boolean FirstPoint_dual(PointProj P, PointProjFull R, byte[] ind) - { - PointProjFull R3 = new PointProjFull(engine.params.NWORDS_FIELD), - S3 = new PointProjFull(engine.params.NWORDS_FIELD); - long[][][] gX = new long[2][2][engine.params.NWORDS_FIELD], - gZ = new long[2][2][engine.params.NWORDS_FIELD]; - long[] zero = new long[engine.params.NWORDS_FIELD]; - int nbytes = engine.params.NWORDS_FIELD; - int alpha,beta; - - engine.fpx.fpcopy(engine.params.B_gen_3_tors, 0*engine.params.NWORDS_FIELD, (R3.X)[0]); - engine.fpx.fpcopy(engine.params.B_gen_3_tors, 1*engine.params.NWORDS_FIELD, (R3.X)[1]); - engine.fpx.fpcopy(engine.params.B_gen_3_tors, 2*engine.params.NWORDS_FIELD, (R3.Y)[0]); - engine.fpx.fpcopy(engine.params.B_gen_3_tors, 3*engine.params.NWORDS_FIELD, (R3.Y)[1]); - engine.fpx.fpcopy(engine.params.B_gen_3_tors, 4*engine.params.NWORDS_FIELD, (S3.X)[0]); - engine.fpx.fpcopy(engine.params.B_gen_3_tors, 5*engine.params.NWORDS_FIELD, (S3.X)[1]); - engine.fpx.fpcopy(engine.params.B_gen_3_tors, 6*engine.params.NWORDS_FIELD, (S3.Y)[0]); - engine.fpx.fpcopy(engine.params.B_gen_3_tors, 7*engine.params.NWORDS_FIELD, (S3.Y)[1]); - - engine.isogeny.CompletePoint(P,R); - - Tate3_proj(R3,R,gX[0],gZ[0]); - Tate3_proj(S3,R,gX[1],gZ[1]); - FinalExpo3_2way(gX,gZ); - - // Do small DLog with respect to g_R3_S3 - engine.fpx.fp2correction(gX[0]); - engine.fpx.fp2correction(gX[1]); - - if (Fpx.subarrayEquals(gX[0][1], zero, nbytes)) // = 1 - { - alpha = 0; - } - else if (Fpx.subarrayEquals(gX[0][1], engine.params.g_R_S_im, nbytes)) // = g_R3_S3 - { - alpha = 1; - } - else // = g_R3_S3^2 - { - alpha = 2; - } - - if (Fpx.subarrayEquals(gX[1][1], zero, nbytes)) // = 1 - { - beta = 0; - } - else if (Fpx.subarrayEquals(gX[1][1], engine.params.g_R_S_im, nbytes))// = g_R3_S3 - { - beta = 1; - } - else // = g_R3_S3^2 - { - beta = 2; - } - - if (alpha == 0 && beta == 0) // Not full order - { - return false; - } - - // Return the 3-torsion point that R lies above - if (alpha == 0) // Lies above R3 - { - ind[0] = 0; - } - else if (beta == 0) // Lies above S3 - { - ind[0] = 1; - } - else if (alpha + beta == 3) // Lies above R3+S3 - { - ind[0] = 3; - } - else // Lies above R3-S3 - { - ind[0] = 2; - } - - return true; - } - - - private boolean SecondPoint_dual(PointProj P, PointProjFull R, byte[] ind) - { - PointProjFull RS3 = new PointProjFull(engine.params.NWORDS_FIELD); - long[][] gX = new long[2][engine.params.NWORDS_FIELD], - gZ = new long[2][engine.params.NWORDS_FIELD]; - - long[] zero = new long[engine.params.NWORDS_FIELD]; - int nbytes = engine.params.NWORDS_FIELD; - - // Pair with 3-torsion point determined by first point - engine.fpx.fpcopy(engine.params.B_gen_3_tors, (4*ind[0] + 0)*engine.params.NWORDS_FIELD, (RS3.X)[0]); - engine.fpx.fpcopy(engine.params.B_gen_3_tors, (4*ind[0] + 1)*engine.params.NWORDS_FIELD, (RS3.X)[1]); - engine.fpx.fpcopy(engine.params.B_gen_3_tors, (4*ind[0] + 2)*engine.params.NWORDS_FIELD, (RS3.Y)[0]); - engine.fpx.fpcopy(engine.params.B_gen_3_tors, (4*ind[0] + 3)*engine.params.NWORDS_FIELD, (RS3.Y)[1]); - - engine.isogeny.CompletePoint(P, R); - Tate3_proj(RS3, R, gX, gZ); - FinalExpo3(gX, gZ); - - engine.fpx.fp2correction(gX); - if (!Fpx.subarrayEquals(gX[1], zero, nbytes)) // Not equal to 1 - { - return true; - } - else - { - return false; - } - } - - - protected void FirstPoint3n(long[][] a24, long[][][][] As, long[][] x, PointProjFull R, int[] r, byte[] ind, byte[] bitEll) - { - boolean b = false; - PointProj P = new PointProj(engine.params.NWORDS_FIELD); - long[] zero = new long[engine.params.NWORDS_FIELD]; - r[0] = 0; - - while (!b) - { - bitEll[0] = 0; - Elligator2(a24, r, 0, x, bitEll,0, 0); // Get x-coordinate on curve a24 - engine.fpx.fp2copy(x, P.X); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, P.Z[0]); - engine.fpx.fpcopy(zero, 0, P.Z[1]); - eval_full_dual_4_isog(As, P); // Move x over to A = 0 - b = FirstPoint_dual(P, R, ind); // Compute DLog with 3-torsion points - r[0] = r[0] + 1; - } - } - - - protected void SecondPoint3n(long[][] a24, long[][][][] As, long[][] x, PointProjFull R, int[] r, byte[] ind, byte[] bitEll) - { - boolean b = false; - PointProj P = new PointProj(engine.params.NWORDS_FIELD); - long[] zero = new long[engine.params.NWORDS_FIELD]; - - while (!b) - { - bitEll[0] = 0; - Elligator2(a24, r, 1, x, bitEll, 0, 0); - engine.fpx.fp2copy(x, P.X); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, P.Z[0]); - engine.fpx.fpcopy(zero, 0, P.Z[1]); - eval_full_dual_4_isog(As, P); // Move x over to A = 0 - b = SecondPoint_dual(P, R, ind); - r[1] = r[1] + 1; - } - } - - - protected void makeDiff(PointProjFull R, PointProjFull S, PointProj D) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - t2 = new long[2][engine.params.NWORDS_FIELD]; - int nbytes = engine.params.NWORDS_FIELD; - - engine.fpx.fp2sub(R.X, S.X, t0); - engine.fpx.fp2sub(R.Y, S.Y, t1); - engine.fpx.fp2sqr_mont(t0, t0); - engine.fpx.fp2sqr_mont(t1, t1); - engine.fpx.fp2add(R.X, S.X, t2); - engine.fpx.fp2mul_mont(t0, t2, t2); - engine.fpx.fp2sub(t1, t2, t1); - engine.fpx.fp2mul_mont(D.Z, t1, t1); - engine.fpx.fp2mul_mont(D.X, t0, t0); - engine.fpx.fp2correction(t0); - engine.fpx.fp2correction(t1); - if (Fpx.subarrayEquals(t0[0], t1[0], nbytes) & Fpx.subarrayEquals(t0[1], t1[1], nbytes)) - { - engine.fpx.fp2neg(S.Y); - } - } - - - protected void BuildOrdinary3nBasis_dual(long[][] a24, long[][][][] As, PointProjFull[] R, int[] r, int[] bitsEll, int bitsEllOffset) - { - PointProj D = new PointProj(engine.params.NWORDS_FIELD); - long[][][] xs = new long[2][2][engine.params.NWORDS_FIELD]; - byte[] ind = new byte[1], - bit = new byte[1]; - - FirstPoint3n(a24, As, xs[0], R[0], r, ind, bit); - bitsEll[bitsEllOffset] = bit[0]; - r[1] = r[0]; - SecondPoint3n(a24, As, xs[1], R[1], r, ind, bit); - bitsEll[bitsEllOffset] |= ((int)bit[0] << 1); - - // Get x-coordinate of difference - BiQuad_affine(a24, xs[0], xs[1], D); - eval_full_dual_4_isog(As, D); // Move x over to A = 0 - makeDiff(R[0], R[1], D); - } - - - protected void FullIsogeny_A_dual(byte[] PrivateKeyA, long[][][][] As, long[][] a24, int sike) - { - // Input: a private key PrivateKeyA in the range [0, 2^eA - 1]. - // Output: the public key PublicKeyA consisting of 3 elements in GF(p^2) which are encoded by removing leading 0 bytes. - PointProj R = new PointProj(engine.params.NWORDS_FIELD); - PointProj[] pts = new PointProj[engine.params.MAX_INT_POINTS_ALICE]; - long[][] XPA = new long[2][engine.params.NWORDS_FIELD], - XQA = new long[2][engine.params.NWORDS_FIELD], - XRA = new long[2][engine.params.NWORDS_FIELD], - A24 = new long[2][engine.params.NWORDS_FIELD], - C24 = new long[2][engine.params.NWORDS_FIELD], - A = new long[2][engine.params.NWORDS_FIELD]; - long[][][] coeff = new long[5][2][engine.params.NWORDS_FIELD]; - - int i, row, m, index = 0, npts = 0, ii = 0; - int[] pts_index = new int[engine.params.MAX_INT_POINTS_ALICE]; - long[] SecretKeyA = new long[engine.params.NWORDS_ORDER]; - - // Initialize basis points - init_basis(engine.params.A_gen, XPA, XQA, XRA); - - // Initialize constants: A24 = A+2C, C24 = 4C, where A=6, C=1 - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, A24[0]); - engine.fpx.fp2add(A24, A24, A24); - engine.fpx.fp2add(A24, A24, C24); - engine.fpx.fp2add(A24, C24, A); - engine.fpx.fp2add(C24, C24, A24); - - // Retrieve kernel point - engine.fpx.decode_to_digits(PrivateKeyA, engine.params.MSG_BYTES, SecretKeyA, engine.params.SECRETKEY_A_BYTES, engine.params.NWORDS_ORDER); - engine.isogeny.LADDER3PT(XPA, XQA, XRA, SecretKeyA, engine.params.ALICE, R, A); - engine.fpx.fp2inv_mont(R.Z); - engine.fpx.fp2mul_mont(R.X,R.Z,R.X); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, R.Z[0]); - engine.fpx.fpzero(R.Z[1]); - if (sike == 1) - { - engine.fpx.fp2_encode(R.X, PrivateKeyA, engine.params.MSG_BYTES + engine.params.SECRETKEY_A_BYTES + engine.params.CRYPTO_PUBLICKEYBYTES); // privA ||= x(KA) = x(PA + sk_A*QA) - } - if (engine.params.OALICE_BITS % 2 == 1) - { - PointProj S = new PointProj(engine.params.NWORDS_FIELD); - - engine.isogeny.xDBLe(R, S, A24, C24, (int) (engine.params.OALICE_BITS - 1)); - engine.isogeny.get_2_isog(S, A24, C24); - engine.isogeny.eval_2_isog(R, S); - engine.fpx.fp2copy(S.X, As[engine.params.MAX_Alice][2]); - engine.fpx.fp2copy(S.Z, As[engine.params.MAX_Alice][3]); - } - - // Traverse tree - index = 0; - for (row = 1; row < engine.params.MAX_Alice; row++) - { - while (index < engine.params.MAX_Alice-row) - { - pts[npts] = new PointProj(engine.params.NWORDS_FIELD); - engine.fpx.fp2copy(R.X, pts[npts].X); - engine.fpx.fp2copy(R.Z, pts[npts].Z); - pts_index[npts++] = index; - m = engine.params.strat_Alice[ii++]; - engine.isogeny.xDBLe(R, R, A24, C24, (int)(2*m)); - index += m; - } - - engine.fpx.fp2copy(A24, As[row-1][0]); - engine.fpx.fp2copy(C24, As[row-1][1]); - get_4_isog_dual(R, A24, C24, coeff); - for (i = 0; i < npts; i++) - { - engine.isogeny.eval_4_isog(pts[i], coeff); - } - eval_dual_4_isog_shared(coeff[2], coeff[3], coeff[4], As[row-1], 2); - engine.fpx.fp2copy(pts[npts-1].X, R.X); - engine.fpx.fp2copy(pts[npts-1].Z, R.Z); - index = pts_index[npts-1]; - npts -= 1; - } - engine.fpx.fp2copy(A24, As[engine.params.MAX_Alice-1][0]); - engine.fpx.fp2copy(C24, As[engine.params.MAX_Alice-1][1]); - - get_4_isog_dual(R, A24, C24, coeff); - eval_dual_4_isog_shared(coeff[2], coeff[3], coeff[4], As[engine.params.MAX_Alice-1], 2); - engine.fpx.fp2copy(A24, As[engine.params.MAX_Alice][0]); - engine.fpx.fp2copy(C24, As[engine.params.MAX_Alice][1]); - engine.fpx.fp2inv_mont_bingcd(C24); - engine.fpx.fp2mul_mont(A24, C24, a24); - } - - - protected void Dlogs3_dual(long[][][] f, int[] D, long[] d0, long[] c0, long[] d1, long[] c1) - { - solve_dlog(f[0], D, d0, 3); - solve_dlog(f[2], D, c0, 3); - solve_dlog(f[1], D, d1, 3); - solve_dlog(f[3], D, c1, 3); - engine.fpx.mp_sub(engine.params.Bob_order, c0, c0, engine.params.NWORDS_ORDER); - engine.fpx.mp_sub(engine.params.Bob_order, c1, c1, engine.params.NWORDS_ORDER); - } - - - protected void BuildOrdinary3nBasis_Decomp_dual(long[][] A24, PointProj[] Rs, int[] r, int[] bitsEll, int bitsEllIndex) - { - byte[] bitEll = new byte[2]; - - bitEll[0] = (byte) (bitsEll[bitsEllIndex] & 0x1); - bitEll[1] = (byte) ((bitsEll[bitsEllIndex] >>> 1) & 0x1); - - // Elligator2 both x-coordinates - r[0] -= 1; - Elligator2(A24, r, 0, Rs[0].X, bitEll, 0, 1); - r[1] -= 1; - Elligator2(A24, r, 1, Rs[1].X, bitEll, 1, 1); - // Get x-coordinate of difference - BiQuad_affine(A24, Rs[0].X, Rs[1].X, Rs[2]); - } - - - protected void PKADecompression_dual(byte[] SecretKeyB, byte[] CompressedPKA, PointProj R, long[][] A) - { - byte bit; - int[] rs = new int[3]; - long[][] A24 = new long[2][engine.params.NWORDS_FIELD]; - PointProj[] Rs = new PointProj[3]; - Rs[0] = new PointProj(engine.params.NWORDS_FIELD); - Rs[1] = new PointProj(engine.params.NWORDS_FIELD); - Rs[2] = new PointProj(engine.params.NWORDS_FIELD); - - - long[] t1 = new long[engine.params.NWORDS_ORDER], - t2 = new long[engine.params.NWORDS_ORDER], - t3 = new long[engine.params.NWORDS_ORDER], - t4 = new long[engine.params.NWORDS_ORDER], - vone = new long[engine.params.NWORDS_ORDER], - temp = new long[engine.params.NWORDS_ORDER], - SKin = new long[engine.params.NWORDS_ORDER]; - - - engine.fpx.fp2_decode(CompressedPKA, A, 3*engine.params.ORDER_B_ENCODED_BYTES); - vone[0] = 1; - engine.fpx.to_Montgomery_mod_order(vone, vone, engine.params.Bob_order, engine.params.Montgomery_RB2, engine.params.Montgomery_RB1); // Converting to Montgomery representation - bit = (byte) ((CompressedPKA[3*engine.params.ORDER_B_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES] & 0xff) >> 7); - - byte[] rs_temp = new byte[3]; - System.arraycopy(CompressedPKA, 3*engine.params.ORDER_B_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES, rs_temp, 0, 3); - rs[0] = rs_temp[0] & 0xffff; - rs[1] = rs_temp[1] & 0xffff; - rs[2] = rs_temp[2] & 0xffff; - - rs[0] &= 0x7F; - - engine.fpx.fpaddPRIME(A[0], engine.params.Montgomery_one, A24[0]); - engine.fpx.fpcopy(A[1], 0, A24[1]); - engine.fpx.fpaddPRIME(A24[0], engine.params.Montgomery_one, A24[0]); - engine.fpx.fp2div2(A24, A24); - engine.fpx.fp2div2(A24, A24); - - BuildOrdinary3nBasis_Decomp_dual(A24, Rs, rs, rs, 2); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, Rs[0].Z[0]); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, Rs[1].Z[0]); - - engine.isogeny.swap_points(Rs[0], Rs[1], -(long) bit); - engine.fpx.decode_to_digits(SecretKeyB, 0, SKin, engine.params.SECRETKEY_B_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.to_Montgomery_mod_order(SKin, t1, engine.params.Bob_order, engine.params.Montgomery_RB2, engine.params.Montgomery_RB1); // Converting to Montgomery representation - engine.fpx.decode_to_digits(CompressedPKA, 0, temp, engine.params.ORDER_B_ENCODED_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.to_Montgomery_mod_order(temp, t2, engine.params.Bob_order, engine.params.Montgomery_RB2, engine.params.Montgomery_RB1); - engine.fpx.decode_to_digits(CompressedPKA, engine.params.ORDER_B_ENCODED_BYTES, temp, engine.params.ORDER_B_ENCODED_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.to_Montgomery_mod_order(temp, t3, engine.params.Bob_order, engine.params.Montgomery_RB2, engine.params.Montgomery_RB1); - engine.fpx.decode_to_digits(CompressedPKA, 2*engine.params.ORDER_B_ENCODED_BYTES, temp, engine.params.ORDER_B_ENCODED_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.to_Montgomery_mod_order(temp, t4, engine.params.Bob_order, engine.params.Montgomery_RB2, engine.params.Montgomery_RB1); - - if (bit == 0) - { - engine.fpx.Montgomery_multiply_mod_order(t1, t3, t3, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.mp_add(t3, vone, t3, engine.params.NWORDS_ORDER); - engine.fpx.Montgomery_inversion_mod_order_bingcd(t3, t3, engine.params.Bob_order, engine.params.Montgomery_RB2, engine.params.Montgomery_RB1); - engine.fpx.Montgomery_multiply_mod_order(t1, t4, t4, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.mp_add(t2, t4, t4, engine.params.NWORDS_ORDER); - engine.fpx.Montgomery_multiply_mod_order(t3, t4, t3, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.from_Montgomery_mod_order(t3, t3, engine.params.Bob_order, engine.params.Montgomery_RB2); // Converting back from Montgomery representation - Ladder3pt_dual(Rs, t3, engine.params.BOB, R, A24); - } - else - { - engine.fpx.Montgomery_multiply_mod_order(t1, t4, t4, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.mp_add(t4, vone, t4, engine.params.NWORDS_ORDER); - engine.fpx.Montgomery_inversion_mod_order_bingcd(t4, t4, engine.params.Bob_order, engine.params.Montgomery_RB2, engine.params.Montgomery_RB1); - engine.fpx.Montgomery_multiply_mod_order(t1, t3, t3, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.mp_add(t2, t3, t3, engine.params.NWORDS_ORDER); - engine.fpx.Montgomery_multiply_mod_order(t3, t4, t3, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.from_Montgomery_mod_order(t3, t3, engine.params.Bob_order, engine.params.Montgomery_RB2); // Converting back from Montgomery representation - Ladder3pt_dual(Rs,t3,engine.params.BOB, R, A24); - } - engine.isogeny.Double(R, R, A24, engine.params.OALICE_BITS); // x, z := Double(A24, x, 1, eA); - } - - - protected void Compress_PKA_dual(long[] d0, long[] c0, long[] d1, long[] c1, long[][] a24, int[] rs, byte[] CompressedPKA) - { - int bit; - long[] temp = new long[engine.params.NWORDS_ORDER], - inv = new long[engine.params.NWORDS_ORDER]; - long[][] A = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.fp2add(a24,a24,A); - engine.fpx.fp2add(A,A,A); - engine.fpx.fpsubPRIME(A[0],engine.params.Montgomery_one,A[0]); - engine.fpx.fpsubPRIME(A[0],engine.params.Montgomery_one,A[0]); // 4*a24-2 - - bit = engine.fpx.mod3(d1); - engine.fpx.to_Montgomery_mod_order(c0, c0, engine.params.Bob_order, engine.params.Montgomery_RB2, engine.params.Montgomery_RB1); // Converting to Montgomery representation - engine.fpx.to_Montgomery_mod_order(c1, c1, engine.params.Bob_order, engine.params.Montgomery_RB2, engine.params.Montgomery_RB1); - engine.fpx.to_Montgomery_mod_order(d0, d0, engine.params.Bob_order, engine.params.Montgomery_RB2, engine.params.Montgomery_RB1); - engine.fpx.to_Montgomery_mod_order(d1, d1, engine.params.Bob_order, engine.params.Montgomery_RB2, engine.params.Montgomery_RB1); - - if (bit != 0) - { // Storing [d1*c0inv, c1*c0inv, d0*c0inv] and setting bit "NBITS_ORDER" to 0 - engine.fpx.Montgomery_inversion_mod_order_bingcd(d1, inv, engine.params.Bob_order, engine.params.Montgomery_RB2, engine.params.Montgomery_RB1); - engine.fpx.Montgomery_neg(d0, engine.params.Bob_order); - engine.fpx.Montgomery_multiply_mod_order(d0, inv, temp, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.from_Montgomery_mod_order(temp, temp, engine.params.Bob_order, engine.params.Montgomery_RB2); // Converting back from Montgomery representation - engine.fpx.encode_to_bytes(temp, CompressedPKA, 0, engine.params.ORDER_B_ENCODED_BYTES); - engine.fpx.Montgomery_neg(c1, engine.params.Bob_order); - engine.fpx.Montgomery_multiply_mod_order(c1, inv, temp, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.from_Montgomery_mod_order(temp, temp, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.encode_to_bytes(temp, CompressedPKA, engine.params.ORDER_B_ENCODED_BYTES, engine.params.ORDER_B_ENCODED_BYTES); - engine.fpx.Montgomery_multiply_mod_order(c0, inv, temp, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.from_Montgomery_mod_order(temp, temp, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.encode_to_bytes(temp, CompressedPKA, 2*engine.params.ORDER_B_ENCODED_BYTES, engine.params.ORDER_B_ENCODED_BYTES); - CompressedPKA[3*engine.params.ORDER_B_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES] = 0x00; - } - else - { // Storing [d1*d0inv, c1*d0inv, c0*d0inv] and setting bit "NBITS_ORDER" to 1 - engine.fpx.Montgomery_inversion_mod_order_bingcd(d0, inv, engine.params.Bob_order, engine.params.Montgomery_RB2, engine.params.Montgomery_RB1); - engine.fpx.Montgomery_neg(d1, engine.params.Bob_order); - engine.fpx.Montgomery_multiply_mod_order(d1, inv, temp, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.from_Montgomery_mod_order(temp, temp, engine.params.Bob_order, engine.params.Montgomery_RB2); // Converting back from Montgomery representation - engine.fpx.encode_to_bytes(temp, CompressedPKA, 0, engine.params.ORDER_B_ENCODED_BYTES); - engine.fpx.Montgomery_multiply_mod_order(c1, inv, temp, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.from_Montgomery_mod_order(temp, temp, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.encode_to_bytes(temp, CompressedPKA, engine.params.ORDER_B_ENCODED_BYTES, engine.params.ORDER_B_ENCODED_BYTES); - engine.fpx.Montgomery_neg(c0, engine.params.Bob_order); - engine.fpx.Montgomery_multiply_mod_order(c0, inv, temp, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.from_Montgomery_mod_order(temp, temp, engine.params.Bob_order, engine.params.Montgomery_RB2); - engine.fpx.encode_to_bytes(temp, CompressedPKA, 2*engine.params.ORDER_B_ENCODED_BYTES, engine.params.ORDER_B_ENCODED_BYTES); - CompressedPKA[3*engine.params.ORDER_B_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES] = (byte) 0x80; - } - - engine.fpx.fp2_encode(A, CompressedPKA, 3*engine.params.ORDER_B_ENCODED_BYTES); - CompressedPKA[3*engine.params.ORDER_B_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES] |= (byte)rs[0]; - CompressedPKA[3*engine.params.ORDER_B_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES + 1] = (byte) rs[1]; - CompressedPKA[3*engine.params.ORDER_B_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES + 2] = (byte) rs[2]; - } - - // Alice's ephemeral public key generation using compression -- SIKE protocol - // Output: PrivateKeyA[MSG_BYTES + engine.params.SECRETKEY_A_BYTES] <- x(K_A) where K_A = PA + sk_A*Q_A - protected int EphemeralKeyGeneration_A_extended(byte[] PrivateKeyA, byte[] CompressedPKA) - { - int[] rs = new int[3], - D = new int[engine.params.DLEN_3]; - long[][] a24 = new long[2][engine.params.NWORDS_FIELD]; - long[][][][] As = new long[engine.params.MAX_Alice+1][5][2][engine.params.NWORDS_FIELD]; - long[][][] f = new long[4][2][engine.params.NWORDS_FIELD]; - long[] c0 = new long[engine.params.NWORDS_ORDER], - d0 = new long[engine.params.NWORDS_ORDER], - c1 = new long[engine.params.NWORDS_ORDER], - d1 = new long[engine.params.NWORDS_ORDER]; - PointProjFull[] Rs = new PointProjFull[2]; - Rs[0] = new PointProjFull(engine.params.NWORDS_FIELD); - Rs[1] = new PointProjFull(engine.params.NWORDS_FIELD); - - FullIsogeny_A_dual(PrivateKeyA, As, a24, 1); - BuildOrdinary3nBasis_dual(a24, As, Rs, rs, rs, 2); - Tate3_pairings(Rs, f); - Dlogs3_dual(f, D, d0, c0, d1, c1); - Compress_PKA_dual(d0, c0, d1, c1, a24, rs, CompressedPKA); - return 0; - } - - // Alice's ephemeral public key generation using compression -- SIDH protocol - // Output: PrivateKeyA[MSG_BYTES + engine.params.SECRETKEY_A_BYTES] <- x(K_A) where K_A = PA + sk_A*Q_A -// private int EphemeralKeyGeneration_A(byte[] PrivateKeyA, byte[] CompressedPKA) -// { -// int[] rs = new int[3], -// D = new int[engine.params.DLEN_3]; -// long[] c0 = new long[engine.params.NWORDS_ORDER], -// d0 = new long[engine.params.NWORDS_ORDER], -// c1 = new long[engine.params.NWORDS_ORDER], -// d1 = new long[engine.params.NWORDS_ORDER]; -// long[][] a24 = new long[2][engine.params.NWORDS_FIELD]; -// long[][][] f = new long[4][2][engine.params.NWORDS_FIELD]; -// long[][][][] As = new long[engine.params.MAX_Alice+1][5][2][engine.params.NWORDS_FIELD]; -// PointProjFull[] Rs = new PointProjFull[2]; -// -// FullIsogeny_A_dual(PrivateKeyA, As, a24, 0); -// BuildOrdinary3nBasis_dual(a24, As, Rs, rs, rs, 2); -// Tate3_pairings(Rs, f); -// Dlogs3_dual(f, D, d0, c0, d1, c1); -// Compress_PKA_dual(d0, c0, d1, c1, a24, rs, CompressedPKA); -// return 0; -// } - - // Bob's ephemeral shared secret computation using compression - // It produces a shared secret key SharedSecretB using his secret key PrivateKeyB and Alice's decompressed data point_R and param_A - // Inputs: Bob's PrivateKeyB is an integer in the range [1, oB-1], where oB = 3^OBOB_EXP. - // Alice's decompressed data consists of point_R in (X:Z) coordinates and the curve parameter param_A in GF(p^2). - // Output: a shared secret SharedSecretB that consists of one element in GF(p^2). - int EphemeralSecretAgreement_B(byte[] PrivateKeyB, byte[] PKA, byte[] SharedSecretB) - { - int i, ii = 0, row, m, index = 0, npts = 0; - int[] pts_index = new int[engine.params.MAX_INT_POINTS_BOB]; - long[][] A24plus = new long[2][engine.params.NWORDS_FIELD], - A24minus = new long[2][engine.params.NWORDS_FIELD]; - PointProj R = new PointProj(engine.params.NWORDS_FIELD); - PointProj[] pts = new PointProj[engine.params.MAX_INT_POINTS_BOB]; - long[][] jinv = new long[2][engine.params.NWORDS_FIELD], A = new long[2][engine.params.NWORDS_FIELD]; - long[][][] coeff = new long[3][2][engine.params.NWORDS_FIELD]; - long[][] param_A = new long[2][engine.params.NWORDS_FIELD]; - - PKADecompression_dual(PrivateKeyB, PKA, R, param_A); - engine.fpx.fp2copy(param_A, A); - engine.fpx.fpaddPRIME(engine.params.Montgomery_one, engine.params.Montgomery_one, A24minus[0]); - engine.fpx.fp2add(A, A24minus, A24plus); - engine.fpx.fp2sub(A, A24minus, A24minus); - - // Traverse tree - index = 0; - for (row = 1; row < engine.params.MAX_Bob; row++) - { - while (index < engine.params.MAX_Bob-row) - { - pts[npts] = new PointProj(engine.params.NWORDS_FIELD); - engine.fpx.fp2copy(R.X, pts[npts].X); - engine.fpx.fp2copy(R.Z, pts[npts].Z); - pts_index[npts++] = index; - m = engine.params.strat_Bob[ii++]; - engine.isogeny.xTPLe(R, R, A24minus, A24plus, (int)m); - index += m; - } - engine.isogeny.get_3_isog(R, A24minus, A24plus, coeff); - - for (i = 0; i < npts; i++) - { - engine.isogeny.eval_3_isog(pts[i], coeff); - } - - engine.fpx.fp2copy(pts[npts-1].X, R.X); - engine.fpx.fp2copy(pts[npts-1].Z, R.Z); - index = pts_index[npts-1]; - npts -= 1; - } - - engine.isogeny.get_3_isog(R, A24minus, A24plus, coeff); - engine.fpx.fp2add(A24plus, A24minus, A); - engine.fpx.fp2add(A, A, A); - engine.fpx.fp2sub(A24plus, A24minus, A24plus); - engine.isogeny.j_inv(A, A24plus, jinv); - engine.fpx.fp2_encode(jinv, SharedSecretB, 0); // Format shared secret - - return 0; - } - - - protected void BuildEntangledXonly(long[][] A, PointProj[] R, byte[] qnr, byte[] ind) - { - long[] s = new long[engine.params.NWORDS_FIELD]; - long[][] t_ptr, r = new long[2][engine.params.NWORDS_FIELD], - t = new long[2][engine.params.NWORDS_FIELD]; - int t_ptrOffset = 0; - - // Select the correct table - if (engine.fpx.is_sqr_fp2(A, s)) - { - t_ptr = engine.params.table_v_qnr; - qnr[0] = 1; - } - else - { - t_ptr = engine.params.table_v_qr; - qnr[0] = 0; - } - - // Get x0 - ind[0] = 0; - do - { - engine.fpx.fp2mul_mont(A, t_ptr, t_ptrOffset, R[0].X); // R[0].X = A*v - t_ptrOffset += 2; - engine.fpx.fp2neg(R[0].X); // R[0].X = -A*v - engine.fpx.fp2add(R[0].X, A, t); - engine.fpx.fp2mul_mont(R[0].X, t, t); - engine.fpx.fpaddPRIME(t[0], engine.params.Montgomery_one, t[0]); - engine.fpx.fp2mul_mont(R[0].X, t, t); // t = R[0].X^3 + A*R[0].X^2 + R[0].X - ind[0] += 1; - } while (!engine.fpx.is_sqr_fp2(t, s)); - ind[0] -= 1; - - if (qnr[0] == 1) - { - engine.fpx.fpcopy(engine.params.table_r_qnr[ind[0]], 0, r[0]); - } - else - { - engine.fpx.fpcopy(engine.params.table_r_qr[ind[0]], 0, r[0]); - } - - // Get x1 - engine.fpx.fp2add(R[0].X, A, R[1].X); - engine.fpx.fp2neg(R[1].X); // R[1].X = -R[0].X-A - - // Get difference x2, z2 - engine.fpx.fp2sub(R[0].X, R[1].X, R[2].Z); - engine.fpx.fp2sqr_mont(R[2].Z, R[2].Z); - - engine.fpx.fpcopy(r[0], 0, r[1]); // (1+i)*ind - engine.fpx.fpaddPRIME(engine.params.Montgomery_one, r[0], r[0]); - engine.fpx.fp2sqr_mont(r, r); - engine.fpx.fp2mul_mont(t, r, R[2].X); - } - - - protected void RecoverY(long[][] A, PointProj[] xs, PointProjFull[] Rs) - { - long[][] t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - t2 = new long[2][engine.params.NWORDS_FIELD], - t3 = new long[2][engine.params.NWORDS_FIELD], - t4 = new long[2][engine.params.NWORDS_FIELD]; - - engine.fpx.fp2mul_mont(xs[2].X, xs[1].Z, t0); - engine.fpx.fp2mul_mont(xs[1].X, xs[2].Z, t1); - engine.fpx.fp2mul_mont(xs[1].X, xs[2].X, t2); - engine.fpx.fp2mul_mont(xs[1].Z, xs[2].Z, t3); - engine.fpx.fp2sqr_mont(xs[1].X, t4); - engine.fpx.fp2sqr_mont(xs[1].Z, Rs[1].X); - engine.fpx.fp2sub(t2, t3, Rs[1].Y); - engine.fpx.fp2mul_mont(xs[1].X, Rs[1].Y, Rs[1].Y); - engine.fpx.fp2add(t4, Rs[1].X, t4); - engine.fpx.fp2mul_mont(xs[2].Z, t4, t4); - engine.fpx.fp2mul_mont(A, t1, Rs[1].X); - engine.fpx.fp2sub(t0, t1, Rs[1].Z); - - engine.fpx.fp2mul_mont(Rs[0].X, Rs[1].Z, t0); - engine.fpx.fp2add(t2, Rs[1].X, t1); - engine.fpx.fp2add(t1, t1, t1); - engine.fpx.fp2sub(t0, t1, t0); - engine.fpx.fp2mul_mont(xs[1].Z, t0, t0); - engine.fpx.fp2sub(t0, t4, t0); - engine.fpx.fp2mul_mont(Rs[0].X, t0, t0); - engine.fpx.fp2add(t0, Rs[1].Y, Rs[1].Y); - engine.fpx.fp2mul_mont(Rs[0].Y, t3, t0); - engine.fpx.fp2mul_mont(xs[1].X, t0, Rs[1].X); - engine.fpx.fp2add(Rs[1].X, Rs[1].X, Rs[1].X); - engine.fpx.fp2mul_mont(xs[1].Z, t0, Rs[1].Z); - engine.fpx.fp2add(Rs[1].Z, Rs[1].Z, Rs[1].Z); - - engine.fpx.fp2inv_mont_bingcd(Rs[1].Z); - engine.fpx.fp2mul_mont(Rs[1].X, Rs[1].Z, Rs[1].X); - engine.fpx.fp2mul_mont(Rs[1].Y, Rs[1].Z, Rs[1].Y); - } - - - protected void BuildOrdinary2nBasis_dual(long[][] A, long[][][][] Ds, PointProjFull[] Rs, byte[] qnr, byte[] ind) - { - int i; - long[] t0 = new long[engine.params.NWORDS_FIELD]; - long[][] A6 = new long[2][engine.params.NWORDS_FIELD]; - PointProj[] xs = new PointProj[3]; - xs[0] = new PointProj(engine.params.NWORDS_FIELD); - xs[1] = new PointProj(engine.params.NWORDS_FIELD); - xs[2] = new PointProj(engine.params.NWORDS_FIELD); - - // Generate x-only entangled basis - BuildEntangledXonly(A, xs, qnr, ind); - engine.fpx.fpcopy(engine.params.Montgomery_one,0, (xs[0].Z)[0]); - engine.fpx.fpcopy(engine.params.Montgomery_one,0, (xs[1].Z)[0]); - - // Move them back to A = 6 - for(i = 0; i < engine.params.MAX_Bob; i++) - { - engine.isogeny.eval_3_isog(xs[0], Ds[engine.params.MAX_Bob-1-i]); - engine.isogeny.eval_3_isog(xs[1], Ds[engine.params.MAX_Bob-1-i]); - engine.isogeny.eval_3_isog(xs[2], Ds[engine.params.MAX_Bob-1-i]); - } - - // Recover y-coordinates with a single sqrt on A = 6 - engine.fpx.fpcopy(engine.params.Montgomery_one,0, A6[0]); - engine.fpx.fpaddPRIME(A6[0], A6[0], t0); - engine.fpx.fpaddPRIME(t0, t0, A6[0]); - engine.fpx.fpaddPRIME(A6[0], t0, A6[0]); // A6 = 6 - - engine.isogeny.CompleteMPoint(A6, xs[0], Rs[0]); - RecoverY(A6, xs, Rs); - } - - // Bob's ephemeral public key generation - // Input: a private key PrivateKeyB in the range [0, 2^Floor(Log(2,oB)) - 1]. - // Output: the public key PublicKeyB consisting of 3 elements in GF(p^2) which are encoded by removing leading 0 bytes. - protected void FullIsogeny_B_dual(byte[] PrivateKeyB, long[][][][] Ds, long[][] A) - { - PointProj R = new PointProj(engine.params.NWORDS_FIELD), - Q3 = new PointProj(engine.params.NWORDS_FIELD); - PointProj[] pts = new PointProj[engine.params.MAX_INT_POINTS_BOB]; - - long[][] XPB = new long[2][engine.params.NWORDS_FIELD], - XQB = new long[2][engine.params.NWORDS_FIELD], - XRB = new long[2][engine.params.NWORDS_FIELD], - A24plus = new long[2][engine.params.NWORDS_FIELD], - A24minus = new long[2][engine.params.NWORDS_FIELD]; - long[][][] coeff = new long[3][2][engine.params.NWORDS_FIELD]; - int i, row, m, index = 0, npts = 0, ii = 0; - int[] pts_index = new int[engine.params.MAX_INT_POINTS_BOB]; - long[] SecretKeyB = new long[engine.params.NWORDS_ORDER]; - - // Initialize basis points - init_basis(engine.params.B_gen, XPB, XQB, XRB); - engine.fpx.fpcopy(engine.params.XQB3, 0, Q3.X[0]); - engine.fpx.fpcopy(engine.params.XQB3, engine.params.NWORDS_FIELD, (Q3.X)[1]); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, Q3.Z[0]); - - // Initialize constants: A24minus = A-2C, A24plus = A+2C, where A=6, C=1 - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, A24plus[0]); - engine.fpx.fp2add(A24plus, A24plus, A24plus); - engine.fpx.fp2add(A24plus, A24plus, A24minus); - engine.fpx.fp2add(A24plus, A24minus, A); - engine.fpx.fp2add(A24minus, A24minus, A24plus); - - // Retrieve kernel point - engine.fpx.decode_to_digits(PrivateKeyB, 0, SecretKeyB, engine.params.SECRETKEY_B_BYTES, engine.params.NWORDS_ORDER); - engine.isogeny.LADDER3PT(XPB, XQB, XRB, SecretKeyB, engine.params.BOB, R, A); - - // Traverse tree - index = 0; - for (row = 1; row < engine.params.MAX_Bob; row++) - { - while (index < engine.params.MAX_Bob-row) - { - pts[npts] = new PointProj(engine.params.NWORDS_FIELD); - engine.fpx.fp2copy(R.X, pts[npts].X); - engine.fpx.fp2copy(R.Z, pts[npts].Z); - pts_index[npts++] = index; - m = engine.params.strat_Bob[ii++]; - engine.isogeny.xTPLe(R, R, A24minus, A24plus, (int)m); - index += m; - } - engine.isogeny.get_3_isog(R, A24minus, A24plus, coeff); - for (i = 0; i < npts; i++) - { - engine.isogeny.eval_3_isog(pts[i], coeff); - } - engine.isogeny.eval_3_isog(Q3, coeff); // Kernel of dual - engine.fpx.fp2sub(Q3.X,Q3.Z,Ds[row-1][0]); - engine.fpx.fp2add(Q3.X,Q3.Z,Ds[row-1][1]); - - engine.fpx.fp2copy(pts[npts-1].X, R.X); - engine.fpx.fp2copy(pts[npts-1].Z, R.Z); - index = pts_index[npts-1]; - npts -= 1; - } - engine.isogeny.get_3_isog(R, A24minus, A24plus, coeff); - engine.isogeny.eval_3_isog(Q3, coeff); // Kernel of dual - engine.fpx.fp2sub(Q3.X, Q3.Z, Ds[engine.params.MAX_Bob-1][0]); - engine.fpx.fp2add(Q3.X, Q3.Z, Ds[engine.params.MAX_Bob-1][1]); - - engine.fpx.fp2add(A24plus, A24minus, A); - engine.fpx.fp2sub(A24plus, A24minus, A24plus); - engine.fpx.fp2inv_mont_bingcd(A24plus); - engine.fpx.fp2mul_mont(A24plus, A, A); - engine.fpx.fp2add(A, A, A); // A = 2*(A24plus+A24mins)/(A24plus-A24minus) - } - - - protected void Dlogs2_dual(long[][][] f, int[] D, long[] d0, long[] c0, long[] d1, long[] c1) - { - solve_dlog(f[0], D, d0, 2); - solve_dlog(f[2], D, c0, 2); - solve_dlog(f[1], D, d1, 2); - solve_dlog(f[3], D, c1, 2); - engine.fpx.mp_sub(engine.params.Alice_order, c0, c0, engine.params.NWORDS_ORDER); - engine.fpx.mp_sub(engine.params.Alice_order, c1, c1, engine.params.NWORDS_ORDER); - } - - - protected void BuildEntangledXonly_Decomp(long[][] A, PointProj[] R, int qnr, int ind) - { - long[][] t_ptr, r = new long[2][engine.params.NWORDS_FIELD], t = new long[2][engine.params.NWORDS_FIELD]; - - // Select the correct table - if ( qnr == 1 ) - { - t_ptr = engine.params.table_v_qnr; - } - else - { - t_ptr = engine.params.table_v_qr; - } - - if (ind >= engine.params.TABLE_V_LEN/2) - { - ind = 0; - } - // Get x0 - engine.fpx.fp2mul_mont(A, t_ptr, ind * 2, R[0].X); // x1 = A*v - engine.fpx.fp2neg(R[0].X); // R[0].X = -A*v - engine.fpx.fp2add(R[0].X, A, t); - engine.fpx.fp2mul_mont(R[0].X, t, t); - engine.fpx.fpaddPRIME(t[0], engine.params.Montgomery_one, t[0]); - engine.fpx.fp2mul_mont(R[0].X, t, t); // t = R[0].X^3 + A*R[0].X^2 + R[0].X - - if (qnr == 1) - { - engine.fpx.fpcopy(engine.params.table_r_qnr[ind], 0, r[0]); - } - else - { - engine.fpx.fpcopy(engine.params.table_r_qr[ind], 0, r[0]); - } - - // Get x1 - engine.fpx.fp2add(R[0].X, A, R[1].X); - engine.fpx.fp2neg(R[1].X); // R[1].X = -R[0].X-A - - // Get difference x2,z2 - engine.fpx.fp2sub(R[0].X, R[1].X, R[2].Z); - engine.fpx.fp2sqr_mont(R[2].Z, R[2].Z); - - engine.fpx.fpcopy(r[0], 0, r[1]); // (1+i)*ind - engine.fpx.fpaddPRIME(engine.params.Montgomery_one, r[0], r[0]); - engine.fpx.fp2sqr_mont(r, r); - engine.fpx.fp2mul_mont(t, r, R[2].X); - } - - // Bob's PK decompression -- SIKE protocol - protected void PKBDecompression_extended(byte[] SecretKeyA, int SecretKeyAOffset, byte[] CompressedPKB, PointProj R, long[][] A, byte[] tphiBKA_t, int tphiBKA_tOffset) - { - long mask = -1L; - int qnr, ind; - long[][] A24 = new long[2][engine.params.NWORDS_FIELD], - Adiv2 = new long[2][engine.params.NWORDS_FIELD]; - long[] tmp1 = new long[2*engine.params.NWORDS_ORDER], - tmp2 = new long[2*engine.params.NWORDS_ORDER], - inv = new long[engine.params.NWORDS_ORDER], - scal = new long[2*engine.params.NWORDS_ORDER], - SKin = new long[engine.params.NWORDS_ORDER], - a0 = new long[engine.params.NWORDS_ORDER], - a1 = new long[engine.params.NWORDS_ORDER], - b0 = new long[engine.params.NWORDS_ORDER], - b1 = new long[engine.params.NWORDS_ORDER]; - PointProj[] Rs = new PointProj[3]; - Rs[0] = new PointProj(engine.params.NWORDS_FIELD); - Rs[1] = new PointProj(engine.params.NWORDS_FIELD); - Rs[2] = new PointProj(engine.params.NWORDS_FIELD); - - mask >>>= (engine.params.MAXBITS_ORDER - engine.params.OALICE_BITS); - - engine.fpx.fp2_decode(CompressedPKB, A, 4*engine.params.ORDER_A_ENCODED_BYTES); - qnr = CompressedPKB[4*engine.params.ORDER_A_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES] & 0x01; - ind = CompressedPKB[4*engine.params.ORDER_A_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES + 1]; - BuildEntangledXonly_Decomp(A, Rs, qnr, ind); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, Rs[0].Z[0]); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, Rs[1].Z[0]); - - engine.fpx.fpaddPRIME(A[0], engine.params.Montgomery_one, A24[0]); - engine.fpx.fpcopy(A[1], 0, A24[1]); - engine.fpx.fpaddPRIME(A24[0], engine.params.Montgomery_one, A24[0]); - engine.fpx.fp2div2(A24, A24); - engine.fpx.fp2div2(A24, A24); - - engine.fpx.decode_to_digits(SecretKeyA, SecretKeyAOffset, SKin, engine.params.SECRETKEY_A_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.decode_to_digits(CompressedPKB, 0, a0, engine.params.ORDER_A_ENCODED_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.decode_to_digits(CompressedPKB, engine.params.ORDER_A_ENCODED_BYTES, b0, engine.params.ORDER_A_ENCODED_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.decode_to_digits(CompressedPKB, 2*engine.params.ORDER_A_ENCODED_BYTES, a1, engine.params.ORDER_A_ENCODED_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.decode_to_digits(CompressedPKB, 3*engine.params.ORDER_A_ENCODED_BYTES, b1, engine.params.ORDER_A_ENCODED_BYTES, engine.params.NWORDS_ORDER); - - if ( (a0[0] & 1) == 1) - { - engine.fpx.multiply(SKin, b1, tmp1, engine.params.NWORDS_ORDER); - engine.fpx.mp_add(tmp1, b0, tmp1, engine.params.NWORDS_ORDER); - tmp1[engine.params.NWORDS_ORDER-1] &= mask; - engine.fpx.multiply(SKin, a1, tmp2, engine.params.NWORDS_ORDER); - engine.fpx.mp_add(tmp2, a0, tmp2, engine.params.NWORDS_ORDER); - tmp2[engine.params.NWORDS_ORDER-1] &= mask; - engine.fpx.inv_mod_orderA(tmp2, inv); - engine.fpx.multiply(tmp1, inv, scal, engine.params.NWORDS_ORDER); - scal[engine.params.NWORDS_ORDER-1] &= mask; - Ladder3pt_dual(Rs, scal, engine.params.ALICE, R, A24); - } - else - { - engine.fpx.multiply(SKin, a1, tmp1, engine.params.NWORDS_ORDER); - engine.fpx.mp_add(tmp1, a0, tmp1, engine.params.NWORDS_ORDER); - tmp1[engine.params.NWORDS_ORDER-1] &= (long)mask; - engine.fpx.multiply(SKin, b1, tmp2, engine.params.NWORDS_ORDER); - engine.fpx.mp_add(tmp2, b0, tmp2, engine.params.NWORDS_ORDER); - tmp2[engine.params.NWORDS_ORDER-1] &= (long)mask; - engine.fpx.inv_mod_orderA(tmp2, inv); - engine.fpx.multiply(inv, tmp1, scal, engine.params.NWORDS_ORDER); - scal[engine.params.NWORDS_ORDER-1] &= (long)mask; - engine.isogeny.swap_points(Rs[0], Rs[1], -1L); - Ladder3pt_dual(Rs, scal, engine.params.ALICE, R, A24); - } - - engine.fpx.fp2div2(A,Adiv2); - engine.isogeny.xTPLe_fast(R, R, Adiv2, engine.params.OBOB_EXPON); - - engine.fpx.fp2_encode(R.X, tphiBKA_t, tphiBKA_tOffset); - engine.fpx.fp2_encode(R.Z, tphiBKA_t, tphiBKA_tOffset + engine.params.FP2_ENCODED_BYTES); - engine.fpx.encode_to_bytes(inv, tphiBKA_t, tphiBKA_tOffset + 2*engine.params.FP2_ENCODED_BYTES, engine.params.ORDER_A_ENCODED_BYTES); - } - - // Bob's PK compression -- SIKE protocol - protected void Compress_PKB_dual_extended(long[] d0, long[] c0, long[] d1, long[] c1, long[][] A, byte[] qnr, byte[] ind, byte[] CompressedPKB) - { - long mask = -1L; - long[] tmp = new long[2*engine.params.NWORDS_ORDER], - D = new long[2*engine.params.NWORDS_ORDER], Dinv = new long[2*engine.params.NWORDS_ORDER]; - - mask >>>= (engine.params.MAXBITS_ORDER - engine.params.OALICE_BITS); - - engine.fpx.multiply(c0, d1, tmp, engine.params.NWORDS_ORDER); - engine.fpx.multiply(c1, d0, D, engine.params.NWORDS_ORDER); - engine.fpx.Montgomery_neg(D, engine.params.Alice_order); - engine.fpx.mp_add(tmp, D, D, engine.params.NWORDS_ORDER); - D[engine.params.NWORDS_ORDER-1] &= (long)mask; - engine.fpx.inv_mod_orderA(D, Dinv); - engine.fpx.multiply(d1, Dinv, tmp, engine.params.NWORDS_ORDER); // a0' = 3^n * d1 / D - tmp[engine.params.NWORDS_ORDER-1] &= mask; - engine.fpx.encode_to_bytes(tmp, CompressedPKB, 0, engine.params.ORDER_A_ENCODED_BYTES); - - engine.fpx.Montgomery_neg(d0, engine.params.Alice_order); - engine.fpx.multiply(d0, Dinv, tmp, engine.params.NWORDS_ORDER); // b0' = 3^n * (- d0 / D) - tmp[engine.params.NWORDS_ORDER-1] &= (long)mask; - engine.fpx.encode_to_bytes(tmp,CompressedPKB, engine.params.ORDER_A_ENCODED_BYTES, engine.params.ORDER_A_ENCODED_BYTES); - - engine.fpx.Montgomery_neg(c1, engine.params.Alice_order); - engine.fpx.multiply(c1, Dinv, tmp, engine.params.NWORDS_ORDER); // a1' = 3^n * (- c1 / D) - tmp[engine.params.NWORDS_ORDER-1] &= (long)mask; - engine.fpx.encode_to_bytes(tmp, CompressedPKB, 2*engine.params.ORDER_A_ENCODED_BYTES, engine.params.ORDER_A_ENCODED_BYTES); - - engine.fpx.multiply(c0, Dinv, tmp, engine.params.NWORDS_ORDER); // b1' = 3^n * (c0 / D) - tmp[engine.params.NWORDS_ORDER-1] &= (long)mask; - engine.fpx.encode_to_bytes(tmp, CompressedPKB, 3*engine.params.ORDER_A_ENCODED_BYTES, engine.params.ORDER_A_ENCODED_BYTES); - - engine.fpx.fp2_encode(A, CompressedPKB, 4*engine.params.ORDER_A_ENCODED_BYTES); - CompressedPKB[4*engine.params.ORDER_A_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES] = qnr[0]; - CompressedPKB[4*engine.params.ORDER_A_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES + 1] = ind[0]; - } - - // Bob's PK decompression -- SIDH protocol - protected void PKBDecompression(byte[] SecretKeyA, int SecretKeyAOffset, byte[] CompressedPKB, PointProj R, long[][] A) - { - long mask = -1L; - int bit,qnr,ind; - long[][] A24 = new long[2][engine.params.NWORDS_FIELD]; - long[] tmp1 = new long[2*engine.params.NWORDS_ORDER], - tmp2 = new long[2*engine.params.NWORDS_ORDER], - vone = new long[2*engine.params.NWORDS_ORDER], - SKin = new long[engine.params.NWORDS_ORDER], - comp_temp = new long[engine.params.NWORDS_ORDER]; - PointProj[] Rs = new PointProj[3]; - - mask >>>= (engine.params.MAXBITS_ORDER - engine.params.OALICE_BITS); - vone[0] = 1; - - engine.fpx.fp2_decode(CompressedPKB, A, 3*engine.params.ORDER_A_ENCODED_BYTES); - bit = CompressedPKB[3*engine.params.ORDER_A_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES] >>> 7; - qnr = CompressedPKB[3*engine.params.ORDER_A_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES] & 0x1; - ind = CompressedPKB[3*engine.params.ORDER_A_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES + 1]; - - // Rebuild the basis - BuildEntangledXonly_Decomp(A,Rs,qnr,ind); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, Rs[0].Z[0]); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, Rs[1].Z[0]); - - engine.fpx.fpaddPRIME(A[0], engine.params.Montgomery_one, A24[0]); - engine.fpx.fpcopy(A[1], 0, A24[1]); - engine.fpx.fpaddPRIME(A24[0], engine.params.Montgomery_one, A24[0]); - engine.fpx.fp2div2(A24, A24); - engine.fpx.fp2div2(A24, A24); - - engine.fpx.decode_to_digits(SecretKeyA, SecretKeyAOffset, SKin, engine.params.SECRETKEY_A_BYTES, engine.params.NWORDS_ORDER); - engine.isogeny.swap_points(Rs[0], Rs[1], 0-(long)bit); - if (bit == 0) - { - engine.fpx.decode_to_digits(CompressedPKB, engine.params.ORDER_A_ENCODED_BYTES, comp_temp, engine.params.ORDER_A_ENCODED_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.multiply(SKin, comp_temp, tmp1, engine.params.NWORDS_ORDER); - engine.fpx.mp_add(tmp1, vone, tmp1, engine.params.NWORDS_ORDER); - tmp1[engine.params.NWORDS_ORDER-1] &= (long)mask; - engine.fpx.inv_mod_orderA(tmp1, tmp2); - engine.fpx.decode_to_digits(CompressedPKB, 2*engine.params.ORDER_A_ENCODED_BYTES, comp_temp, engine.params.ORDER_A_ENCODED_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.multiply(SKin, comp_temp, tmp1, engine.params.NWORDS_ORDER); - engine.fpx.decode_to_digits(CompressedPKB, 0, comp_temp, engine.params.ORDER_A_ENCODED_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.mp_add(comp_temp, tmp1, tmp1, engine.params.NWORDS_ORDER); - engine.fpx.multiply(tmp1, tmp2, vone, engine.params.NWORDS_ORDER); - vone[engine.params.NWORDS_ORDER-1] &= mask; - Ladder3pt_dual(Rs, vone, engine.params.ALICE, R, A24); - } - else - { - engine.fpx.decode_to_digits(CompressedPKB, 2*engine.params.ORDER_A_ENCODED_BYTES, comp_temp, engine.params.ORDER_A_ENCODED_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.multiply(SKin, comp_temp, tmp1, engine.params.NWORDS_ORDER); - engine.fpx.mp_add(tmp1, vone, tmp1, engine.params.NWORDS_ORDER); - tmp1[engine.params.NWORDS_ORDER-1] &= mask; - engine.fpx.inv_mod_orderA(tmp1, tmp2); - engine.fpx.decode_to_digits(CompressedPKB, engine.params.ORDER_A_ENCODED_BYTES, comp_temp, engine.params.ORDER_A_ENCODED_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.multiply(SKin, comp_temp, tmp1, engine.params.NWORDS_ORDER); - engine.fpx.decode_to_digits(CompressedPKB, 0, comp_temp, engine.params.ORDER_A_ENCODED_BYTES, engine.params.NWORDS_ORDER); - engine.fpx.mp_add(comp_temp, tmp1, tmp1, engine.params.NWORDS_ORDER); - engine.fpx.multiply(tmp1, tmp2, vone, engine.params.NWORDS_ORDER); - vone[engine.params.NWORDS_ORDER-1] &= mask; - Ladder3pt_dual(Rs, vone, engine.params.ALICE, R, A24); - } - engine.fpx.fp2div2(A, A24); - engine.isogeny.xTPLe_fast(R, R, A24, engine.params.OBOB_EXPON); - } - - // Bob's PK compression -- SIDH protocol - protected void Compress_PKB_dual(long[] d0, long[] c0, long[] d1, long[] c1, long[][] A, byte qnr[], byte ind[], byte[] CompressedPKB) - { - long[] tmp = new long[2*engine.params.NWORDS_ORDER], - inv = new long[engine.params.NWORDS_ORDER]; - if ((d1[0] & 1) == 1) - { // Storing [-d0*d1^-1 = b1*a0^-1, -c1*d1^-1 = a1*a0^-1, c0*d1^-1 = b0*a0^-1] and setting bit384 to 0 - engine.fpx.inv_mod_orderA(d1, inv); - engine.fpx.Montgomery_neg(d0, engine.params.Alice_order); - engine.fpx.multiply(d0, inv, tmp, engine.params.NWORDS_ORDER); - engine.fpx.encode_to_bytes(tmp, CompressedPKB, 0, engine.params.ORDER_A_ENCODED_BYTES); - CompressedPKB[engine.params.ORDER_A_ENCODED_BYTES-1] &= engine.params.MASK_ALICE; - engine.fpx.Montgomery_neg(c1, engine.params.Alice_order); - engine.fpx.multiply(c1, inv, tmp, engine.params.NWORDS_ORDER); - engine.fpx.encode_to_bytes(tmp, CompressedPKB,engine.params.ORDER_A_ENCODED_BYTES, engine.params.ORDER_A_ENCODED_BYTES); - CompressedPKB[2*engine.params.ORDER_A_ENCODED_BYTES-1] &= engine.params.MASK_ALICE; - engine.fpx.multiply(c0, inv, tmp, engine.params.NWORDS_ORDER); - engine.fpx.encode_to_bytes(tmp, CompressedPKB, 2*engine.params.ORDER_A_ENCODED_BYTES, engine.params.ORDER_A_ENCODED_BYTES); - CompressedPKB[3*engine.params.ORDER_A_ENCODED_BYTES-1] &= engine.params.MASK_ALICE; - CompressedPKB[3*engine.params.ORDER_A_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES] = 0x00; - } - else - { // Storing [ -d1*d0^-1 = b1*b0inv, c1*d0^-1 = a1*b0inv, -c0*d0^-1 = a0*b0inv] and setting bit384 to 1 - engine.fpx.inv_mod_orderA(d0, inv); - engine.fpx.Montgomery_neg(d1, engine.params.Alice_order); - engine.fpx.multiply(d1, inv, tmp, engine.params.NWORDS_ORDER); - engine.fpx.encode_to_bytes(tmp, CompressedPKB,0, engine.params.ORDER_A_ENCODED_BYTES); - CompressedPKB[engine.params.ORDER_A_ENCODED_BYTES - 1] &= engine.params.MASK_ALICE; - engine.fpx.multiply(c1, inv, tmp, engine.params.NWORDS_ORDER); - engine.fpx.encode_to_bytes(tmp, CompressedPKB, engine.params.ORDER_A_ENCODED_BYTES, engine.params.ORDER_A_ENCODED_BYTES); - CompressedPKB[2*engine.params.ORDER_A_ENCODED_BYTES-1] &= engine.params.MASK_ALICE; - engine.fpx.Montgomery_neg(c0, engine.params.Alice_order); - engine.fpx.multiply(c0, inv, tmp, engine.params.NWORDS_ORDER); - engine.fpx.encode_to_bytes(tmp, CompressedPKB,2*engine.params.ORDER_A_ENCODED_BYTES, engine.params.ORDER_A_ENCODED_BYTES); - CompressedPKB[3*engine.params.ORDER_A_ENCODED_BYTES-1] &= engine.params.MASK_ALICE; - CompressedPKB[3*engine.params.ORDER_A_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES] = (byte) 0x80; - } - - engine.fpx.fp2_encode(A, CompressedPKB,3*engine.params.ORDER_A_ENCODED_BYTES); - CompressedPKB[3*engine.params.ORDER_A_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES] |= qnr[0]; - CompressedPKB[3*engine.params.ORDER_A_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES + 1] = ind[0]; - CompressedPKB[3*engine.params.ORDER_A_ENCODED_BYTES + engine.params.FP2_ENCODED_BYTES + 2] = 0; - } - - // Bob's ephemeral public key generation using compression -- SIKE protocol - protected int EphemeralKeyGeneration_B_extended(byte[] PrivateKeyB, byte[] CompressedPKB, int sike) - { - byte[] qnr = new byte[1], ind = new byte[1]; - int[] D = new int[engine.params.DLEN_2]; - long[] c0 = new long[engine.params.NWORDS_ORDER], - d0 = new long[engine.params.NWORDS_ORDER], - c1 = new long[engine.params.NWORDS_ORDER], - d1 = new long[engine.params.NWORDS_ORDER]; - long[][][][] Ds = new long[engine.params.MAX_Bob][2][2][engine.params.NWORDS_FIELD]; - long[][][] f = new long[4][2][engine.params.NWORDS_FIELD]; - long[][] A = new long[2][engine.params.NWORDS_FIELD]; - - PointProjFull[] Rs = new PointProjFull[2]; - Rs[0] = new PointProjFull(engine.params.NWORDS_FIELD); - Rs[1] = new PointProjFull(engine.params.NWORDS_FIELD); - - PointProj Pw = new PointProj(engine.params.NWORDS_FIELD), - Qw = new PointProj(engine.params.NWORDS_FIELD); - - FullIsogeny_B_dual(PrivateKeyB, Ds, A); - BuildOrdinary2nBasis_dual(A, Ds, Rs, qnr, ind); // Generate a basis in E_A and pulls it back to E_A6. Rs[0] and Rs[1] affinized. - - // Maps from y^2 = x^3 + 6x^2 + x into y^2 = x^3 -11x + 14 - engine.fpx.fpaddPRIME(engine.params.Montgomery_one, Rs[0].X[0], Rs[0].X[0]); - engine.fpx.fpaddPRIME(engine.params.Montgomery_one, Rs[0].X[0], Rs[0].X[0]); // Weierstrass form - engine.fpx.fpaddPRIME(engine.params.Montgomery_one, Rs[1].X[0], Rs[1].X[0]); - engine.fpx.fpaddPRIME(engine.params.Montgomery_one, Rs[1].X[0], Rs[1].X[0]); // Weierstrass form - - engine.fpx.fpcopy(engine.params.A_basis_zero, 0*engine.params.NWORDS_FIELD, Pw.X[0]); - engine.fpx.fpcopy(engine.params.A_basis_zero, 1*engine.params.NWORDS_FIELD, Pw.X[1]); - engine.fpx.fpcopy(engine.params.A_basis_zero, 2*engine.params.NWORDS_FIELD, Pw.Z[0]);//y - engine.fpx.fpcopy(engine.params.A_basis_zero, 3*engine.params.NWORDS_FIELD, Pw.Z[1]);//y - engine.fpx.fpcopy(engine.params.A_basis_zero, 4*engine.params.NWORDS_FIELD, Qw.X[0]); - engine.fpx.fpcopy(engine.params.A_basis_zero, 5*engine.params.NWORDS_FIELD, Qw.X[1]); - engine.fpx.fpcopy(engine.params.A_basis_zero, 6*engine.params.NWORDS_FIELD, Qw.Z[0]);//y - engine.fpx.fpcopy(engine.params.A_basis_zero, 7*engine.params.NWORDS_FIELD, Qw.Z[1]);//y - - Tate2_pairings(Pw, Qw, Rs, f); - engine.fpx.fp2correction(f[0]); - engine.fpx.fp2correction(f[1]); - engine.fpx.fp2correction(f[2]); - engine.fpx.fp2correction(f[3]); - Dlogs2_dual(f, D, d0, c0, d1, c1); - - if (sike == 1) - { - Compress_PKB_dual_extended(d0, c0, d1, c1, A, qnr, ind, CompressedPKB); - } - else - { - Compress_PKB_dual(d0, c0, d1, c1, A, qnr, ind, CompressedPKB); - } - - return 0; - } - - // Bob's ephemeral public key generation using compression -- SIDH protocol - protected int EphemeralKeyGeneration_B(byte[] PrivateKeyB, byte[] CompressedPKB) - { - return EphemeralKeyGeneration_B_extended(PrivateKeyB, CompressedPKB, 0); - } - - // Alice's ephemeral shared secret computation using compression -- SIKE protocol - protected int EphemeralSecretAgreement_A_extended(byte[] PrivateKeyA, int PrivateKeyAOffset, byte[] PKB, byte[] SharedSecretA, int sike) - { - int i, ii = 0, row, m, index = 0, npts = 0; - int[] pts_index = new int[engine.params.MAX_INT_POINTS_ALICE]; - long[][] A24plus = new long[2][engine.params.NWORDS_FIELD], - C24 = new long[2][engine.params.NWORDS_FIELD]; - - PointProj R = new PointProj(engine.params.NWORDS_FIELD); - PointProj[] pts = new PointProj[engine.params.MAX_INT_POINTS_ALICE]; - long[][] jinv = new long[2][engine.params.NWORDS_FIELD], - A = new long[2][engine.params.NWORDS_FIELD], - param_A = new long[2][engine.params.NWORDS_FIELD]; - long[][][] coeff = new long[5][2][engine.params.NWORDS_FIELD]; - - - if (sike == 1) - { - PKBDecompression_extended(PrivateKeyA, PrivateKeyAOffset, PKB, R, param_A, SharedSecretA, engine.params.FP2_ENCODED_BYTES); - } - else - { - PKBDecompression(PrivateKeyA, PrivateKeyAOffset, PKB, R, param_A); - } - - engine.fpx.fp2copy(param_A, A); - engine.fpx.fpaddPRIME(engine.params.Montgomery_one, engine.params.Montgomery_one, C24[0]); - engine.fpx.fp2add(A, C24, A24plus); - engine.fpx.fpaddPRIME(C24[0], C24[0], C24[0]); - - if (engine.params.OALICE_BITS % 2 == 1) - { - PointProj S = new PointProj(engine.params.NWORDS_FIELD); - - engine.isogeny.xDBLe(R, S, A24plus, C24, (engine.params.OALICE_BITS - 1)); - engine.isogeny.get_2_isog(S, A24plus, C24); - engine.isogeny.eval_2_isog(R, S); - } - - // Traverse tree - index = 0; - for (row = 1; row < engine.params.MAX_Alice; row++) - { - while (index < engine.params.MAX_Alice-row) - { - pts[npts] = new PointProj(engine.params.NWORDS_FIELD); - engine.fpx.fp2copy(R.X, pts[npts].X); - engine.fpx.fp2copy(R.Z, pts[npts].Z); - pts_index[npts++] = index; - m = engine.params.strat_Alice[ii++]; - engine.isogeny.xDBLe(R, R, A24plus, C24, (int)(2*m)); - index += m; - } - engine.isogeny.get_4_isog(R, A24plus, C24, coeff); - - for (i = 0; i < npts; i++) - { - engine.isogeny.eval_4_isog(pts[i], coeff); - } - - engine.fpx.fp2copy(pts[npts-1].X, R.X); - engine.fpx.fp2copy(pts[npts-1].Z, R.Z); - index = pts_index[npts-1]; - npts -= 1; - } - - engine.isogeny.get_4_isog(R, A24plus, C24, coeff); - engine.fpx.fp2add(A24plus, A24plus, A24plus); - engine.fpx.fp2sub(A24plus, C24, A24plus); - engine.fpx.fp2add(A24plus, A24plus, A24plus); - engine.isogeny.j_inv(A24plus, C24, jinv); - engine.fpx.fp2_encode(jinv, SharedSecretA, 0); // Format shared secret - - return 0; - } - - // Alice's ephemeral shared secret computation using compression -- SIDH protocol - // It produces a shared secret key SharedSecretA using her secret key PrivateKeyA and Bob's decompressed data point_R and param_A - // Inputs: Alice's PrivateKeyA is an even integer in the range [2, oA-2], where oA = 2^engine.params.OALICE_BITS. - // Bob's decompressed data consists of point_R in (X:Z) coordinates and the curve parameter param_A in GF(p^2). - // Output: a shared secret SharedSecretA that consists of one element in GF(p^2). - int EphemeralSecretAgreement_A(byte[] PrivateKeyA, int PrivateKeyAOffset, byte[] PKB, byte[] SharedSecretA) - { - return EphemeralSecretAgreement_A_extended(PrivateKeyA, PrivateKeyAOffset, PKB, SharedSecretA, 0); - } - - - protected byte validate_ciphertext(byte[] ephemeralsk_, byte[] CompressedPKB, byte[] xKA, int xKAOffset, byte[] tphiBKA_t, int tphiBKA_tOffset) - { // If ct validation passes returns 0, otherwise returns -1. - PointProj[] phis = new PointProj[3], - pts = new PointProj[engine.params.MAX_INT_POINTS_BOB]; - - phis[0] = new PointProj(engine.params.NWORDS_FIELD); - phis[1] = new PointProj(engine.params.NWORDS_FIELD); - phis[2] = new PointProj(engine.params.NWORDS_FIELD); - - PointProj R = new PointProj(engine.params.NWORDS_FIELD), - S = new PointProj(engine.params.NWORDS_FIELD); - - long[][] XPB = new long[2][engine.params.NWORDS_FIELD], - XQB = new long[2][engine.params.NWORDS_FIELD], - XRB = new long[2][engine.params.NWORDS_FIELD], - A24plus = new long[2][engine.params.NWORDS_FIELD], - A24minus = new long[2][engine.params.NWORDS_FIELD], - A = new long[2][engine.params.NWORDS_FIELD], - comp1 = new long[2][engine.params.NWORDS_FIELD], - comp2 = new long[2][engine.params.NWORDS_FIELD], - one = new long[2][engine.params.NWORDS_FIELD]; - long[][][] coeff = new long[3][2][engine.params.NWORDS_FIELD]; - - int i, row, m, index = 0, npts = 0, ii = 0; - int[] pts_index = new int[engine.params.MAX_INT_POINTS_BOB]; - long[] temp = new long[engine.params.NWORDS_ORDER], - sk = new long[engine.params.NWORDS_ORDER]; - - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, one[0]); - - // Initialize basis points - init_basis(engine.params.B_gen, XPB, XQB, XRB); - - engine.fpx.fp2_decode(xKA, phis[0].X, xKAOffset); - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, phis[0].Z[0]); // phi[0] <- PA + skA*QA - - // Initialize constants: A24minus = A-2C, A24plus = A+2C, where A=6, C=1 - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, A24plus[0]); - engine.fpx.fp2add(A24plus, A24plus, A24plus); - engine.fpx.fp2add(A24plus, A24plus, A24minus); // A24minus = 4 - engine.fpx.fp2add(A24plus, A24minus, A); // A = 6 - engine.fpx.fp2add(A24minus, A24minus, A24plus); // A24plus = 8 - - // Retrieve kernel point - engine.fpx.decode_to_digits(ephemeralsk_, 0, sk, engine.params.SECRETKEY_B_BYTES, engine.params.NWORDS_ORDER); - engine.isogeny.LADDER3PT(XPB, XQB, XRB, sk, engine.params.BOB, R, A); - - // Traverse tree - index = 0; - for (row = 1; row < engine.params.MAX_Bob; row++) - { - while (index < engine.params.MAX_Bob-row) - { - pts[npts] = new PointProj(engine.params.NWORDS_FIELD); - engine.fpx.fp2copy(R.X, pts[npts].X); - engine.fpx.fp2copy(R.Z, pts[npts].Z); - pts_index[npts++] = index; - m = engine.params.strat_Bob[ii++]; - engine.isogeny.xTPLe(R, R, A24minus, A24plus, (int)m); - index += m; - } - engine.isogeny.get_3_isog(R, A24minus, A24plus, coeff); - for (i = 0; i < npts; i++) - { - engine.isogeny.eval_3_isog(pts[i], coeff); - } - engine.isogeny.eval_3_isog(phis[0], coeff); - - engine.fpx.fp2copy(pts[npts-1].X, R.X); - engine.fpx.fp2copy(pts[npts-1].Z, R.Z); - index = pts_index[npts-1]; - npts -= 1; - } - engine.isogeny.get_3_isog(R, A24minus, A24plus, coeff); - engine.isogeny.eval_3_isog(phis[0], coeff); // phis[0] <- phiB(PA + skA*QA) - - engine.fpx.fp2_decode(CompressedPKB, A, 4*engine.params.ORDER_A_ENCODED_BYTES); - - // Single equation check: t*(phiP + skA*phiQ) =? t*3^n*((a0+skA*a1)*S1 + (b0+skA*b1)*S2) for t in {(a0+skA*a1)^-1, (b0+skA*b1)^-1} - - engine.fpx.fp2_decode(tphiBKA_t, S.X, tphiBKA_tOffset); - engine.fpx.fp2_decode(tphiBKA_t, S.Z, tphiBKA_tOffset + engine.params.FP2_ENCODED_BYTES); // Recover t*3^n*((a0+skA*a1)*S1 + (b0+skA*b1)*S2) - engine.fpx.decode_to_digits(tphiBKA_t, tphiBKA_tOffset + 2*engine.params.FP2_ENCODED_BYTES, temp, engine.params.ORDER_A_ENCODED_BYTES, engine.params.NWORDS_ORDER); - engine.isogeny.Ladder(phis[0], temp, A, engine.params.OALICE_BITS, R); // t*(phiP + skA*phiQ) - - engine.fpx.fp2mul_mont(R.X, S.Z, comp1); - engine.fpx.fp2mul_mont(R.Z, S.X, comp2); - return (engine.fpx.cmp_f2elm(comp1, comp2)); - } - - - - /// DLOG - - // Computes the discrete log of input r = g^d where g = e(P,Q)^ell^e, and P,Q are torsion generators in the initial curve - // Return the integer d - void solve_dlog(long[][] r, int[] D, long[] d, int ell) - { - if (ell == 2) - { - if (engine.params.OALICE_BITS % engine.params.W_2 == 0) - { - Traverse_w_div_e_fullsigned(r, 0, 0, engine.params.PLEN_2 - 1, engine.params.ph2_path, - engine.params.ph2_T, D, engine.params.DLEN_2, engine.params.ELL2_W, engine.params.W_2); - } - else - { - Traverse_w_notdiv_e_fullsigned(r, 0, 0, engine.params.PLEN_2 - 1, engine.params.ph2_path, - engine.params.ph2_T1, engine.params.ph2_T2, D, engine.params.DLEN_2, ell, engine.params.ELL2_W, - engine.params.ELL2_EMODW, engine.params.W_2, engine.params.OALICE_BITS); - } - from_base(D, d, engine.params.DLEN_2, engine.params.ELL2_W); - } - else if (ell == 3) - { - if (engine.params.OBOB_EXPON % engine.params.W_3 == 0) - { - Traverse_w_div_e_fullsigned(r, 0, 0, engine.params.PLEN_3 - 1, engine.params.ph3_path, - engine.params.ph3_T, D, engine.params.DLEN_3, engine.params.ELL3_W, engine.params.W_3); - } - else - { - Traverse_w_notdiv_e_fullsigned(r, 0, 0, engine.params.PLEN_3 - 1, engine.params.ph3_path, - engine.params.ph3_T1, engine.params.ph3_T2, D, engine.params.DLEN_3, ell, engine.params.ELL3_W, - engine.params.ELL3_EMODW, engine.params.W_3, engine.params.OBOB_EXPON); - } - from_base(D, d, engine.params.DLEN_3, engine.params.ELL3_W); - } - } - - // Convert a number in base "base" with signed digits: (D[k-1]D[k-2]...D[1]D[0])_base < 2^(NWORDS_ORDER*RADIX) into decimal - // Output: r = D[k-1]*base^(k-1) + ... + D[1]*base + D[0] - private void from_base(int[] D, long[] r, int Dlen, int base) - { - long[] ell = new long[engine.params.NWORDS_ORDER], - digit = new long[engine.params.NWORDS_ORDER], - temp = new long[engine.params.NWORDS_ORDER]; - int ellw; - - ell[0] = base; - if (D[Dlen-1] < 0) - { - digit[0] = (((int)-D[Dlen-1])*ell[0]); - if ((base & 1) == 0) - { - engine.fpx.Montgomery_neg(digit, engine.params.Alice_order); - engine.fpx.copy_words(digit, r, engine.params.NWORDS_ORDER); - } - else - { - engine.fpx.mp_sub(engine.params.Bob_order, digit, r, engine.params.NWORDS_ORDER); - } - } - else - { - r[0] = (D[Dlen-1]*ell[0]); - } - - for (int i = Dlen-2; i >= 1; i--) - { - ellw = base; - Arrays.fill(digit, 0); - if (D[i] < 0) - { - digit[0] = (-D[i]); - if ((base & 1) == 0) - { - engine.fpx.Montgomery_neg(digit, engine.params.Alice_order); - } - else - { - engine.fpx.mp_sub(engine.params.Bob_order, digit, digit, engine.params.NWORDS_ORDER); - } - } - else - { - digit[0] = D[i]; - } - engine.fpx.mp_add(r, digit, r, engine.params.NWORDS_ORDER); - if ((base & 1) != 0) - { - if (!engine.fpx.is_orderelm_lt(r, engine.params.Bob_order)) - { - engine.fpx.mp_sub(r, engine.params.Bob_order, r, engine.params.NWORDS_ORDER); - } - } - - if ((base & 1) == 0) - { - while (ellw > 1) - { - engine.fpx.mp_add(r, r, r, engine.params.NWORDS_ORDER); - ellw /= 2; - } - } - else - { - while (ellw > 1) - { - Arrays.fill(temp, 0); - engine.fpx.mp_add(r, r, temp, engine.params.NWORDS_ORDER); - if (!engine.fpx.is_orderelm_lt(temp, engine.params.Bob_order)) - { - engine.fpx.mp_sub(temp, engine.params.Bob_order, temp, engine.params.NWORDS_ORDER); - } - - engine.fpx.mp_add(r, temp, r, engine.params.NWORDS_ORDER); - - if (!engine.fpx.is_orderelm_lt(r, engine.params.Bob_order)) - { - engine.fpx.mp_sub(r, engine.params.Bob_order, r, engine.params.NWORDS_ORDER); - } - ellw /= 3; - } - } - } - Arrays.fill(digit, 0); - if (D[0] < 0) - { - digit[0] = (-D[0]); - if ((base & 1) == 0) - { - engine.fpx.Montgomery_neg(digit, engine.params.Alice_order); - } - else - { - engine.fpx.mp_sub(engine.params.Bob_order, digit, digit, engine.params.NWORDS_ORDER); - } - } - else - { - digit[0] = D[0]; - } - engine.fpx.mp_add(r, digit, r, engine.params.NWORDS_ORDER); - if ((base & 1) != 0) - { - if (!engine.fpx.is_orderelm_lt(r, engine.params.Bob_order)) - { - engine.fpx.mp_sub(r, engine.params.Bob_order, r, engine.params.NWORDS_ORDER); - } - } - } - - - - // Traverse a Pohlig-Hellman optimal strategy to solve a discrete log in a group of order ell^e - // Leaves are used to recover the digits which are numbers from 0 to ell^w-1 except by the last leaf that gives a digit between 0 and ell^(e mod w) - // Assume w does not divide the exponent e - void Traverse_w_notdiv_e_fullsigned(long[][] r, int j, int k, int z, int[] P, long[] CT1, long[] CT2, - int[] D, int Dlen, int ell, int ellw, int ell_emodw, int w, int e) - { - long[][] rp = new long[2][engine.params.NWORDS_FIELD], - alpha = new long[2][engine.params.NWORDS_FIELD]; - - - if (z > 1) - { - int t = P[z], goleft; - engine.fpx.fp2copy(r, rp); - goleft = (j > 0) ? w*(z-t) : (e % w) + w*(z-t-1); - for (int i = 0; i < goleft; i++) - { - if ((ell & 1) == 0) - { - engine.fpx.sqr_Fp2_cycl(rp, engine.params.Montgomery_one); - } - else - { - engine.fpx.cube_Fp2_cycl(rp, engine.params.Montgomery_one); - } - - } - - Traverse_w_notdiv_e_fullsigned(rp, j + (z - t), k, t, P, CT1, CT2, D, Dlen, ell, ellw, ell_emodw, w, e); - - engine.fpx.fp2copy(r, rp); - for (int h = k; h < k + t; h++) - { - if (D[h] != 0) - { - if (j > 0) - { - if (D[h] < 0) - { - engine.fpx.fp2copy(CT2, engine.params.NWORDS_FIELD * (2*(j + h)*(ellw/2)+2*(-D[h]-1)), alpha); - engine.fpx.fpnegPRIME(alpha[1]); - engine.fpx.fp2mul_mont(rp, alpha, rp); - } - else - { - engine.fpx.fp2mul_mont(rp, CT2, engine.params.NWORDS_FIELD * (2*((j + h)*(ellw/2) + (D[h]-1))), rp); - } - } - else - { - if (D[h] < 0) - { - engine.fpx.fp2copy(CT1, engine.params.NWORDS_FIELD * (2*((j + h)*(ellw/2) + (-D[h]-1))), alpha); - engine.fpx.fpnegPRIME(alpha[1]); - engine.fpx.fp2mul_mont(rp, alpha, rp); - } - else - { - engine.fpx.fp2mul_mont(rp, CT1, engine.params.NWORDS_FIELD * (2*((j + h)*(ellw/2) + (D[h]-1))), rp); - } - } - } - } - - Traverse_w_notdiv_e_fullsigned(rp, j, k + t, z - t, P, CT1, CT2, D, Dlen, ell, ellw, ell_emodw, w, e); - } - else - { - engine.fpx.fp2copy(r, rp); - engine.fpx.fp2correction(rp); - - - if (engine.fpx.is_felm_zero(rp[1]) && Fpx.subarrayEquals(rp[0],engine.params.Montgomery_one, engine.params.NWORDS_FIELD)) - { - D[k] = 0; - } - else - { - - if (!(j == 0 && k == Dlen - 1)) - { - - for (int t = 1; t <= (ellw/2); t++) - { - if (Fpx.subarrayEquals(rp, CT2, engine.params.NWORDS_FIELD * (2 *(ellw/2)*(Dlen-1) + 2*(t-1)), 2*engine.params.NWORDS_FIELD)) - { - D[k] = -t; - break; - } - else - { - engine.fpx.fp2copy(CT2, engine.params.NWORDS_FIELD *(2*((ellw/2)*(Dlen-1) + (t-1))), alpha); - engine.fpx.fpnegPRIME(alpha[1]); - engine.fpx.fpcorrectionPRIME(alpha[1]); - if (Fpx.subarrayEquals(rp, alpha, 2*engine.params.NWORDS_FIELD)) - { - D[k] = t; - break; - } - } - } - } - else - { - for (int t = 1; t <= ell_emodw/2; t++) - { - if (Fpx.subarrayEquals(rp, CT1,engine.params.NWORDS_FIELD * (2*(ellw/2)*(Dlen - 1) + 2*(t-1)), 2*engine.params.NWORDS_FIELD)) - { - D[k] = -t; - break; - } - else - { - engine.fpx.fp2copy(CT1, engine.params.NWORDS_FIELD * (2*((ellw/2)*(Dlen-1) + (t-1))), alpha); - engine.fpx.fpnegPRIME(alpha[1]); - engine.fpx.fpcorrectionPRIME(alpha[1]); - if (Fpx.subarrayEquals(rp, alpha, 2*engine.params.NWORDS_FIELD)) - { - D[k] = t; - break; - } - } - } - } - } - } - } - - - - // Traverse a Pohlig-Hellman optimal strategy to solve a discrete log in a group of order ell^e - // The leaves of the tree will be used to recover the signed digits which are numbers from +/-{0,1... Ceil((ell^w-1)/2)} - // Assume the integer w divides the exponent e - void Traverse_w_div_e_fullsigned(long[][] r, int j, int k, int z, int[] P, long[] CT, int[] D, int Dlen, int ellw, int w) - { - long[][] rp = new long[2][engine.params.NWORDS_FIELD], alpha = new long[2][engine.params.NWORDS_FIELD]; - - if (z > 1) - { - int t = P[z]; - engine.fpx.fp2copy(r, rp); - for (int i = 0; i < z-t; i++) - { - if ((ellw & 1) == 0) - { - for (int ii = 0; ii < w; ii++) - { - engine.fpx.sqr_Fp2_cycl(rp, engine.params.Montgomery_one); - } - } - else - { - for (int ii = 0; ii < w; ii++) - { - engine.fpx.cube_Fp2_cycl(rp, engine.params.Montgomery_one); - } - } - } - - Traverse_w_div_e_fullsigned(rp, j + (z - t), k, t, P, CT, D, Dlen, ellw, w); - - engine.fpx.fp2copy(r, rp); - for (int h = k; h < k + t; h++) - { - if (D[h] != 0) - { - if(D[h] < 0) - { - engine.fpx.fp2copy(CT, engine.params.NWORDS_FIELD * (2*((j + h)*(ellw/2) + (-D[h]-1))), alpha); - engine.fpx.fpnegPRIME(alpha[1]); - engine.fpx.fp2mul_mont(rp, alpha, rp); - } - else - { - engine.fpx.fp2mul_mont(rp, CT, engine.params.NWORDS_FIELD * (2*((j + h)*(ellw/2) + (D[h]-1))), rp); - } - } - } - Traverse_w_div_e_fullsigned(rp, j, k + t, z - t, P, CT, D, Dlen, ellw, w); - } - else - { - engine.fpx.fp2copy(r, rp); - engine.fpx.fp2correction(rp); - - if (engine.fpx.is_felm_zero(rp[1]) && Fpx.subarrayEquals(rp[0], engine.params.Montgomery_one, engine.params.NWORDS_FIELD)) - { - D[k] = 0; - } - else - { - for (int t = 1; t <= ellw/2; t++) - { - if (Fpx.subarrayEquals(rp, CT, engine.params.NWORDS_FIELD * (2*((Dlen - 1)*(ellw/2) + (t-1))), 2*engine.params.NWORDS_FIELD)) - { - D[k] = -t; - break; - } - else - { - engine.fpx.fp2copy(CT, engine.params.NWORDS_FIELD * (2*((Dlen - 1)*(ellw/2) + (t-1))), alpha); - engine.fpx.fpnegPRIME(alpha[1]); - engine.fpx.fpcorrectionPRIME(alpha[1]); - if (Fpx.subarrayEquals(rp, alpha, 2*engine.params.NWORDS_FIELD )) - { - D[k] = t; - break; - } - } - } - } - } - } - /// - - //Pairing - private static final int t_points = 2; - private void Tate3_pairings(PointProjFull[] Qj, long[][][] f) - { - long[] x = new long[engine.params.NWORDS_FIELD], - y = new long[engine.params.NWORDS_FIELD], - l1 = new long[engine.params.NWORDS_FIELD], - l2 = new long[engine.params.NWORDS_FIELD], - n1 = new long[engine.params.NWORDS_FIELD], - n2 = new long[engine.params.NWORDS_FIELD], - x2 = new long[engine.params.NWORDS_FIELD], - x23 = new long[engine.params.NWORDS_FIELD], - x2p3 = new long[engine.params.NWORDS_FIELD]; - - long[][][] xQ2s = new long[t_points][2][engine.params.NWORDS_FIELD], - finv = new long[2*t_points][2][engine.params.NWORDS_FIELD]; - long[][] one = new long[2][engine.params.NWORDS_FIELD], - t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - t2 = new long[2][engine.params.NWORDS_FIELD], - t3 = new long[2][engine.params.NWORDS_FIELD], - t4 = new long[2][engine.params.NWORDS_FIELD], - t5 = new long[2][engine.params.NWORDS_FIELD], - g = new long[2][engine.params.NWORDS_FIELD], - h = new long[2][engine.params.NWORDS_FIELD], - tf = new long[2][engine.params.NWORDS_FIELD]; - - - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, one[0]); - - for (int j = 0; j < t_points; j++) - { - engine.fpx.fp2copy(one, f[j]); - engine.fpx.fp2copy(one, f[j+t_points]); - engine.fpx.fp2sqr_mont(Qj[j].X, xQ2s[j]); - } - for (int k = 0; k < engine.params.OBOB_EXPON - 1; k++) - { - System.arraycopy(engine.params.T_tate3, engine.params.NWORDS_FIELD * (6*k + 0), l1, 0, engine.params.NWORDS_FIELD); - System.arraycopy(engine.params.T_tate3, engine.params.NWORDS_FIELD * (6*k + 1), l2, 0, engine.params.NWORDS_FIELD); - System.arraycopy(engine.params.T_tate3, engine.params.NWORDS_FIELD * (6*k + 2), n1, 0, engine.params.NWORDS_FIELD); - System.arraycopy(engine.params.T_tate3, engine.params.NWORDS_FIELD * (6*k + 3), n2, 0, engine.params.NWORDS_FIELD); - System.arraycopy(engine.params.T_tate3, engine.params.NWORDS_FIELD * (6*k + 4), x23, 0, engine.params.NWORDS_FIELD); - System.arraycopy(engine.params.T_tate3, engine.params.NWORDS_FIELD * (6*k + 5), x2p3, 0, engine.params.NWORDS_FIELD); - for (int j = 0; j < t_points; j++) - { - engine.fpx.fpmul_mont(Qj[j].X[0], l1, t0[0]); - engine.fpx.fpmul_mont(Qj[j].X[1], l1, t0[1]); - engine.fpx.fpmul_mont(Qj[j].X[0], l2, t2[0]); - engine.fpx.fpmul_mont(Qj[j].X[1], l2, t2[1]); - engine.fpx.fpaddPRIME(xQ2s[j][0], x23, t4[0]); - engine.fpx.fpcopy(xQ2s[j][1], 0, t4[1]); - engine.fpx.fpmul_mont(Qj[j].X[0], x2p3, t5[0]); - engine.fpx.fpmul_mont(Qj[j].X[1], x2p3, t5[1]); - engine.fpx.fp2sub(t0, Qj[j].Y, t1); - engine.fpx.fpaddPRIME(t1[0], n1, t1[0]); - engine.fpx.fp2sub(t2, Qj[j].Y, t3); - engine.fpx.fpaddPRIME(t3[0], n2, t3[0]); - engine.fpx.fp2mul_mont(t1, t3, g); - engine.fpx.fp2sub(t4, t5, h); - engine.fpx.fp2_conj(h, h); - engine.fpx.fp2mul_mont(g, h, g); - - engine.fpx.fp2sqr_mont(f[j], tf); - engine.fpx.fp2mul_mont(f[j], tf, f[j]); - engine.fpx.fp2mul_mont(f[j], g, f[j]); - - engine.fpx.fpsubPRIME(t0[1], Qj[j].Y[0], t1[0]); - engine.fpx.fpaddPRIME(t0[0], Qj[j].Y[1], t1[1]); - engine.fpx.fpnegPRIME(t1[1]); - engine.fpx.fpaddPRIME(t1[1], n1, t1[1]); - engine.fpx.fpsubPRIME(t2[1], Qj[j].Y[0], t3[0]); - engine.fpx.fpaddPRIME(t2[0], Qj[j].Y[1], t3[1]); - engine.fpx.fpnegPRIME(t3[1]); - engine.fpx.fpaddPRIME(t3[1], n2, t3[1]); - - engine.fpx.fp2mul_mont(t1, t3, g); - engine.fpx.fp2add(t4, t5, h); - engine.fpx.fp2_conj(h, h); - engine.fpx.fp2mul_mont(g, h, g); - - engine.fpx.fp2sqr_mont(f[j+t_points], tf); - engine.fpx.fp2mul_mont(f[j+t_points], tf, f[j+t_points]); - engine.fpx.fp2mul_mont(f[j+t_points], g, f[j+t_points]); - } - } - for (int j = 0; j < t_points; j++) - { - System.arraycopy(engine.params.T_tate3, engine.params.NWORDS_FIELD * (6*(engine.params.OBOB_EXPON-1) + 0), x, 0, engine.params.NWORDS_FIELD); - System.arraycopy(engine.params.T_tate3, engine.params.NWORDS_FIELD * (6*(engine.params.OBOB_EXPON-1) + 1), y, 0, engine.params.NWORDS_FIELD); - System.arraycopy(engine.params.T_tate3, engine.params.NWORDS_FIELD * (6*(engine.params.OBOB_EXPON-1) + 2), l1, 0, engine.params.NWORDS_FIELD); - System.arraycopy(engine.params.T_tate3, engine.params.NWORDS_FIELD * (6*(engine.params.OBOB_EXPON-1) + 3), x2, 0, engine.params.NWORDS_FIELD); - - engine.fpx.fpsubPRIME(Qj[j].X[0], x, t0[0]); - engine.fpx.fpcopy(Qj[j].X[1], 0, t0[1]); - engine.fpx.fpmul_mont(l1, t0[0], t1[0]); - engine.fpx.fpmul_mont(l1, t0[1], t1[1]); - engine.fpx.fp2sub(t1, Qj[j].Y, t2); - engine.fpx.fpaddPRIME(t2[0], y, t2[0]); - engine.fpx.fp2mul_mont(t0, t2, g); - engine.fpx.fpsubPRIME(Qj[j].X[0], x2, h[0]); - engine.fpx.fpcopy(Qj[j].X[1],0, h[1]); - engine.fpx.fpnegPRIME(h[1]); - engine.fpx.fp2mul_mont(g, h, g); - - engine.fpx.fp2sqr_mont(f[j], tf); - engine.fpx.fp2mul_mont(f[j], tf, f[j]); - engine.fpx.fp2mul_mont(f[j], g, f[j]); - - engine.fpx.fpaddPRIME(Qj[j].X[0], x, t0[0]); - engine.fpx.fpmul_mont(l1, t0[0], t1[0]); - engine.fpx.fpsubPRIME(Qj[j].Y[0], t1[1], t2[0]); - engine.fpx.fpaddPRIME(Qj[j].Y[1], t1[0], t2[1]); - engine.fpx.fpsubPRIME(t2[1], y, t2[1]); - engine.fpx.fp2mul_mont(t0, t2, g); - engine.fpx.fpaddPRIME(Qj[j].X[0], x2, h[0]); - engine.fpx.fp2mul_mont(g, h, g); - - engine.fpx.fp2sqr_mont(f[j+t_points], tf); - engine.fpx.fp2mul_mont(f[j+t_points], tf, f[j+t_points]); - engine.fpx.fp2mul_mont(f[j+t_points], g, f[j+t_points]); - } - - // Final exponentiation: - engine.fpx.mont_n_way_inv(f, 2*t_points, finv); - for (int j = 0; j < 2*t_points; j++) - { - final_exponentiation_3_torsion(f[j], finv[j], f[j]); - } - } - - // The final exponentiation for pairings in the 3-torsion group. Raising the value f to the power (p^2-1)/3^eB. - private void final_exponentiation_3_torsion(long[][] f, long[][] finv, long[][] fout) - { - long[] one = new long[engine.params.NWORDS_FIELD]; - long[][] temp = new long[2][engine.params.NWORDS_FIELD]; - int i; - - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, one); - - // f = f^p - engine.fpx.fp2_conj(f, temp); - engine.fpx.fp2mul_mont(temp, finv, temp); // temp = f^(p-1) - - for (i = 0; i < engine.params.OALICE_BITS; i++) - { - engine.fpx.sqr_Fp2_cycl(temp, one); - } - engine.fpx.fp2copy(temp, fout); - } - - private void Tate2_pairings(PointProj P, PointProj Q, PointProjFull[] Qj, long[][][] f) - { - long[] x, y, x_, y_, l1; - long[][][] finv = new long[2*t_points][2][engine.params.NWORDS_FIELD]; - - long[][] x_first, y_first, - one = new long[2][engine.params.NWORDS_FIELD], - l1_first = new long[2][engine.params.NWORDS_FIELD], - t0 = new long[2][engine.params.NWORDS_FIELD], - t1 = new long[2][engine.params.NWORDS_FIELD], - g = new long[2][engine.params.NWORDS_FIELD], - h = new long[2][engine.params.NWORDS_FIELD]; - - int x_Offset, y_Offset, l1Offset, xOffset, yOffset; - - - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, one[0]); - - for (int j = 0; j < t_points; j++) - { - engine.fpx.fp2copy(one, f[j]); - engine.fpx.fp2copy(one, f[j+t_points]); - } - - // Pairings with P - x_first = P.X; - y_first = P.Z; - - x_Offset = 0; - y_Offset = 1; - x_ = engine.params.T_tate2_firststep_P; - y_ = engine.params.T_tate2_firststep_P; - - engine.fpx.fpcopy(engine.params.T_tate2_firststep_P, 2*engine.params.NWORDS_FIELD, l1_first[0]); - engine.fpx.fpcopy(engine.params.T_tate2_firststep_P, 3*engine.params.NWORDS_FIELD, l1_first[1]); - - - for (int j = 0; j < t_points; j++) - { - engine.fpx.fp2sub(Qj[j].X, x_first, t0); - engine.fpx.fp2sub(Qj[j].Y, y_first, t1); - engine.fpx.fp2mul_mont(l1_first, t0, t0); - engine.fpx.fp2sub(t0, t1, g); - - engine.fpx.fpsubPRIME(Qj[j].X[0], engine.params.T_tate2_firststep_P, x_Offset, h[0]); - engine.fpx.fpcopy(Qj[j].X[1], 0, h[1]); - engine.fpx.fpnegPRIME(h[1]); - engine.fpx.fp2mul_mont(g, h, g); - - engine.fpx.fp2sqr_mont(f[j], f[j]); - engine.fpx.fp2mul_mont(f[j], g, f[j]); - } - xOffset = 0; - yOffset = 1 * engine.params.NWORDS_FIELD; - x = x_; - y = y_; - - for (int k = 0; k < engine.params.OALICE_BITS - 2; k++) - { - - x_ = engine.params.T_tate2_P; - y_ = engine.params.T_tate2_P; - l1 = engine.params.T_tate2_P; - x_Offset = engine.params.NWORDS_FIELD * (3 * k + 0); - y_Offset = engine.params.NWORDS_FIELD * (3 * k + 1); - l1Offset = engine.params.NWORDS_FIELD * (3 * k + 2); - for (int j = 0; j < t_points; j++) - { - engine.fpx.fpsubPRIME(x, xOffset, Qj[j].X[0], t0[1]); - engine.fpx.fpmul_mont(l1, l1Offset, t0[1], t0[1]); - engine.fpx.fpmul_mont(l1, l1Offset, Qj[j].X[1], t0[0]); - engine.fpx.fpsubPRIME(Qj[j].Y[1], y, yOffset, t1[1]); - engine.fpx.fpsubPRIME(t0[1], t1[1], g[1]); - engine.fpx.fpsubPRIME(t0[0], Qj[j].Y[0], g[0]); - - engine.fpx.fpsubPRIME(Qj[j].X[0], x_, x_Offset, h[0]); - engine.fpx.fpcopy(Qj[j].X[1], 0, h[1]); - engine.fpx.fpnegPRIME(h[1]); - engine.fpx.fp2mul_mont(g, h, g); - - engine.fpx.fp2sqr_mont(f[j], f[j]); - engine.fpx.fp2mul_mont(f[j], g, f[j]); - } - x = x_; - y = y_; - yOffset = y_Offset; - xOffset = x_Offset; - } - for (int j = 0; j < t_points; j++) - { - engine.fpx.fpsubPRIME(Qj[j].X[0], x, xOffset, g[0]); - engine.fpx.fpcopy(Qj[j].X[1], 0, g[1]); - engine.fpx.fp2sqr_mont(f[j], f[j]); - engine.fpx.fp2mul_mont(f[j], g, f[j]); - } - - // Pairings with Q - x_first = Q.X; - y_first = Q.Z; - x_ = engine.params.T_tate2_firststep_Q; - y_ = engine.params.T_tate2_firststep_Q; - x_Offset = 0; - y_Offset = 1 * engine.params.NWORDS_FIELD; - - engine.fpx.fpcopy(engine.params.T_tate2_firststep_Q, 2 * engine.params.NWORDS_FIELD, l1_first[0]); - engine.fpx.fpcopy(engine.params.T_tate2_firststep_Q, 3 * engine.params.NWORDS_FIELD, l1_first[1]); - - for (int j = 0; j < t_points; j++) - { - engine.fpx.fp2sub(Qj[j].X, x_first, t0); - engine.fpx.fp2sub(Qj[j].Y, y_first, t1); - engine.fpx.fp2mul_mont(l1_first, t0, t0); - engine.fpx.fp2sub(t0, t1, g); - - engine.fpx.fpsubPRIME(Qj[j].X[0], x_, x_Offset, h[0]); - engine.fpx.fpcopy(Qj[j].X[1], 0, h[1]); - engine.fpx.fpnegPRIME(h[1]); - engine.fpx.fp2mul_mont(g, h, g); - - engine.fpx.fp2sqr_mont(f[j+t_points], f[j+t_points]); - engine.fpx.fp2mul_mont(f[j+t_points], g, f[j+t_points]); - } - x = x_; - y = y_; - yOffset = y_Offset; - xOffset = x_Offset; - - for (int k = 0; k < engine.params.OALICE_BITS - 2; k++) - { - x_ = engine.params.T_tate2_Q; - y_ = engine.params.T_tate2_Q; - l1 = engine.params.T_tate2_Q; - - x_Offset = engine.params.NWORDS_FIELD * (3*k + 0); - y_Offset = engine.params.NWORDS_FIELD * (3*k + 1); - l1Offset = engine.params.NWORDS_FIELD * (3*k + 2); - for (int j = 0; j < t_points; j++) - { - engine.fpx.fpsubPRIME(Qj[j].X[0], x, xOffset, t0[0]); - engine.fpx.fpmul_mont(l1, l1Offset, t0[0], t0[0]); - engine.fpx.fpmul_mont(l1, l1Offset, Qj[j].X[1], t0[1]); - engine.fpx.fpsubPRIME(Qj[j].Y[0], y, yOffset, t1[0]); - engine.fpx.fpsubPRIME(t0[0], t1[0], g[0]); - engine.fpx.fpsubPRIME(t0[1], Qj[j].Y[1], g[1]); - - engine.fpx.fpsubPRIME(Qj[j].X[0], x_, x_Offset, h[0]); - engine.fpx.fpcopy(Qj[j].X[1], 0, h[1]); - engine.fpx.fpnegPRIME(h[1]); - engine.fpx.fp2mul_mont(g, h, g); - - engine.fpx.fp2sqr_mont(f[j+t_points], f[j+t_points]); - engine.fpx.fp2mul_mont(f[j+t_points], g, f[j+t_points]); - } - x = x_; - y = y_; - yOffset = y_Offset; - xOffset = x_Offset; - } - // Last iteration - for (int j = 0; j < t_points; j++) - { - engine.fpx.fpsubPRIME(Qj[j].X[0], x, xOffset, g[0]); - engine.fpx.fpcopy(Qj[j].X[1], 0, g[1]); - - engine.fpx.fp2sqr_mont(f[j+t_points], f[j+t_points]); - engine.fpx.fp2mul_mont(f[j+t_points], g, f[j+t_points]); - } - - // Final exponentiation: - engine.fpx.mont_n_way_inv(f, 2*t_points, finv); - for (int j = 0; j < 2*t_points; j++) - { - final_exponentiation_2_torsion(f[j], finv[j], f[j]); - } - } - - // The final exponentiation for pairings in the 2^eA-torsion group. Raising the value f to the power (p^2-1)/2^eA. - private void final_exponentiation_2_torsion(long[][] f, long[][] finv, long[][] fout) - { - long[] one = new long[engine.params.NWORDS_FIELD]; - long[][] temp = new long[2][engine.params.NWORDS_FIELD]; - int i; - - engine.fpx.fpcopy(engine.params.Montgomery_one, 0, one); - - // f = f^p - engine.fpx.fp2_conj(f, temp); - engine.fpx.fp2mul_mont(temp, finv, temp); // temp = f^(p-1) - - for (i = 0; i < engine.params.OBOB_EXPON; i++) - { - engine.fpx.cube_Fp2_cycl(temp, one); - } - engine.fpx.fp2copy(temp, fout); - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEEngine.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEEngine.java deleted file mode 100644 index e1b5cdb0eb..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEEngine.java +++ /dev/null @@ -1,287 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.Xof; -import org.bouncycastle.crypto.digests.SHAKEDigest; - -class SIKEEngine -{ - protected Internal params; - protected Isogeny isogeny; - protected Fpx fpx; - private SIDH sidh; - private SIDH_Compressed sidhCompressed; - private boolean isCompressed; - - public int getDefaultSessionKeySize() - { - return params.MSG_BYTES * 8; - } - - public int getCipherTextSize() - { - return params.CRYPTO_CIPHERTEXTBYTES; - } - - public int getPrivateKeySize() - { - return params.CRYPTO_SECRETKEYBYTES; - } - - public int getPublicKeySize() - { - return params.CRYPTO_PUBLICKEYBYTES; - } - - public SIKEEngine(int ver, boolean isCompressed) - { - this.isCompressed = isCompressed; - switch(ver) - { - case 434: - params = new P434(isCompressed); - break; - case 503: - params = new P503(isCompressed); - break; - case 610: - params = new P610(isCompressed); - break; - case 751: - params = new P751(isCompressed); - break; - default: - break; - - } - fpx = new Fpx(this); - isogeny = new Isogeny(this); - if(isCompressed) - { - sidhCompressed = new SIDH_Compressed(this); - } - sidh = new SIDH(this); - } - - // SIKE's key generation - // Outputs: secret key sk (CRYPTO_SECRETKEYBYTES = MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes) - // public key pk (CRYPTO_PUBLICKEYBYTES bytes) - public int crypto_kem_keypair(byte[] pk, byte[] sk, SecureRandom random) - { - byte[] s = new byte[params.MSG_BYTES]; - random.nextBytes(s); - - - - if (isCompressed) - { - // Generation of Alice's secret key - // Outputs random value in [0, 2^eA - 1] - - byte[] random_digits = new byte[params.SECRETKEY_A_BYTES]; - random.nextBytes(random_digits); - random_digits[0] &= 0xFE; // Make private scalar even - random_digits[params.SECRETKEY_A_BYTES-1] &= params.MASK_ALICE; // Masking last byte - - System.arraycopy(s, 0, sk, 0, params.MSG_BYTES); - System.arraycopy(random_digits, 0, sk, params.MSG_BYTES, params.SECRETKEY_A_BYTES); - // - - sidhCompressed.EphemeralKeyGeneration_A_extended(sk, pk); - System.arraycopy(pk, 0, sk, params.MSG_BYTES + params.SECRETKEY_A_BYTES, params.CRYPTO_PUBLICKEYBYTES); - - } - else - { - // Generation of Bob's secret key - // Outputs random value in [0, 2^Floor(Log(2, oB)) - 1] - byte[] random_digits = new byte[params.SECRETKEY_B_BYTES]; - random.nextBytes(random_digits); - random_digits[params.SECRETKEY_B_BYTES-1] &= params.MASK_BOB; - - System.arraycopy(s, 0, sk, 0, params.MSG_BYTES); - System.arraycopy(random_digits, 0, sk, params.MSG_BYTES, params.SECRETKEY_B_BYTES); - /// - - sidh.EphemeralKeyGeneration_B(sk, pk); - System.arraycopy(pk, 0, sk, params.MSG_BYTES + params.SECRETKEY_B_BYTES, params.CRYPTO_PUBLICKEYBYTES); - - } - // Append public key pk to secret key sk - - return 0; - } - - // SIKE's encapsulation - // Input: public key pk (CRYPTO_PUBLICKEYBYTES bytes) - // Outputs: shared secret ss (CRYPTO_BYTES bytes) - // ciphertext message ct (CRYPTO_CIPHERTEXTBYTES = CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes) - public int crypto_kem_enc(byte[] ct, byte[] ss, byte[] pk, SecureRandom random) - { - if(isCompressed) - { - byte[] ephemeralsk = new byte[params.SECRETKEY_B_BYTES]; - byte[] jinvariant = new byte[params.FP2_ENCODED_BYTES]; - byte[] h = new byte[params.MSG_BYTES]; - byte[] temp = new byte[params.CRYPTO_CIPHERTEXTBYTES + params.MSG_BYTES]; - - // Generate ephemeralsk <- G(m||pk) mod oB - byte[] tmp = new byte[params.MSG_BYTES]; - random.nextBytes(tmp); - System.arraycopy(tmp, 0, temp, 0, params.MSG_BYTES); - System.arraycopy(pk, 0, temp, params.MSG_BYTES, params.CRYPTO_PUBLICKEYBYTES); - - Xof digest = new SHAKEDigest(256); - digest.update(temp, 0, params.CRYPTO_PUBLICKEYBYTES + params.MSG_BYTES); - digest.doFinal(ephemeralsk, 0, params.SECRETKEY_B_BYTES); - - sidhCompressed.FormatPrivKey_B(ephemeralsk); - - // Encrypt - sidhCompressed.EphemeralKeyGeneration_B_extended(ephemeralsk, ct, 1); - sidhCompressed.EphemeralSecretAgreement_B(ephemeralsk, pk, jinvariant); - - digest.update(jinvariant, 0, params.FP2_ENCODED_BYTES); - digest.doFinal(h, 0, params.MSG_BYTES); - - for (int i = 0; i < params.MSG_BYTES; i++) - { - ct[i + params.PARTIALLY_COMPRESSED_CHUNK_CT] = (byte) (temp[i] ^ h[i]); - } - - // Generate shared secret ss <- H(m||ct) - System.arraycopy(ct, 0, temp, params.MSG_BYTES, params.CRYPTO_CIPHERTEXTBYTES); - - digest.update(temp, 0, params.CRYPTO_CIPHERTEXTBYTES + params.MSG_BYTES); - digest.doFinal(ss, 0, params.CRYPTO_BYTES); - return 0; - } - else - { - byte[] ephemeralsk = new byte[params.SECRETKEY_A_BYTES]; - byte[] jinvariant = new byte[params.FP2_ENCODED_BYTES]; - byte[] h = new byte[params.MSG_BYTES]; - byte[] temp = new byte[params.CRYPTO_CIPHERTEXTBYTES + params.MSG_BYTES]; - - // Generate ephemeralsk <- G(m||pk) mod oA - byte[] tmp = new byte[params.MSG_BYTES]; - random.nextBytes(tmp); - System.arraycopy(tmp, 0, temp, 0, params.MSG_BYTES); - System.arraycopy(pk, 0, temp, params.MSG_BYTES, params.CRYPTO_PUBLICKEYBYTES); - - Xof digest = new SHAKEDigest(256); - digest.update(temp, 0, params.CRYPTO_PUBLICKEYBYTES + params.MSG_BYTES); - digest.doFinal(ephemeralsk, 0, params.SECRETKEY_A_BYTES); - ephemeralsk[params.SECRETKEY_A_BYTES - 1] &= params.MASK_ALICE; - - // Encrypt - sidh.EphemeralKeyGeneration_A(ephemeralsk, ct); - sidh.EphemeralSecretAgreement_A(ephemeralsk, pk, jinvariant); - - digest.update(jinvariant, 0, params.FP2_ENCODED_BYTES); - digest.doFinal(h, 0, params.MSG_BYTES); - - for (int i = 0; i < params.MSG_BYTES; i++) - { - ct[i + params.CRYPTO_PUBLICKEYBYTES] = (byte) (temp[i] ^ h[i]); - } - - // Generate shared secret ss <- H(m||ct) - System.arraycopy(ct, 0, temp, params.MSG_BYTES, params.CRYPTO_CIPHERTEXTBYTES); - - digest.update(temp, 0, params.CRYPTO_CIPHERTEXTBYTES + params.MSG_BYTES); - digest.doFinal(ss, 0, params.CRYPTO_BYTES); - - return 0; - } - } - - // SIKE's decapsulation - // Input: secret key sk (CRYPTO_SECRETKEYBYTES = MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes) - // ciphertext message ct (CRYPTO_CIPHERTEXTBYTES = CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes) - // Outputs: shared secret ss (CRYPTO_BYTES bytes) - public int crypto_kem_dec(byte[] ss, byte[] ct, byte[] sk) - { - if (isCompressed) - { - byte[] ephemeralsk_ = new byte[params.SECRETKEY_B_BYTES]; - byte[] jinvariant_ = new byte[params.FP2_ENCODED_BYTES + 2*params.FP2_ENCODED_BYTES + params.SECRETKEY_A_BYTES], - h_ = new byte[params.MSG_BYTES]; - byte[] temp = new byte[params.CRYPTO_CIPHERTEXTBYTES + params.MSG_BYTES]; - byte[] tphiBKA_t = jinvariant_;//jinvariant_[params.FP2_ENCODED_BYTES]; - - // Decrypt - sidhCompressed.EphemeralSecretAgreement_A_extended(sk, params.MSG_BYTES, ct, jinvariant_, 1); - - Xof digest = new SHAKEDigest(256); - digest.update(jinvariant_, 0, params.FP2_ENCODED_BYTES); - digest.doFinal(h_, 0, params.MSG_BYTES); - - for (int i = 0; i < params.MSG_BYTES; i++) - { - temp[i] = (byte) (ct[i + params.PARTIALLY_COMPRESSED_CHUNK_CT] ^ h_[i]); - } - - // Generate ephemeralsk_ <- G(m||pk) mod oB - System.arraycopy(sk, params.MSG_BYTES + params.SECRETKEY_A_BYTES, temp, params.MSG_BYTES, params.CRYPTO_PUBLICKEYBYTES); - - digest.update(temp, 0, params.CRYPTO_PUBLICKEYBYTES + params.MSG_BYTES); - digest.doFinal(ephemeralsk_, 0, params.SECRETKEY_B_BYTES); - sidhCompressed.FormatPrivKey_B(ephemeralsk_); - - // Generate shared secret ss <- H(m||ct), or output ss <- H(s||ct) in case of ct verification failure - // No need to recompress, just check if x(phi(P) + t*phi(Q)) == x((a0 + t*a1)*R1 + (b0 + t*b1)*R2) - byte selector = sidhCompressed.validate_ciphertext(ephemeralsk_, ct, sk, params.MSG_BYTES + params.SECRETKEY_A_BYTES + params.CRYPTO_PUBLICKEYBYTES, tphiBKA_t, params.FP2_ENCODED_BYTES); - // If ct validation passes (selector = 0) then do ss = H(m||ct), otherwise (selector = -1) load s to do ss = H(s||ct) - fpx.ct_cmov(temp, sk, params.MSG_BYTES, selector); - - System.arraycopy(ct, 0, temp, params.MSG_BYTES, params.CRYPTO_CIPHERTEXTBYTES); - digest.update(temp, 0, params.CRYPTO_CIPHERTEXTBYTES + params.MSG_BYTES); - digest.doFinal(ss, 0, params.CRYPTO_BYTES); - - return 0; - } - else - { - byte[] ephemeralsk_ = new byte[params.SECRETKEY_A_BYTES]; - byte[] jinvariant_ = new byte[params.FP2_ENCODED_BYTES]; - byte[] h_ = new byte[params.MSG_BYTES]; - byte[] c0_ = new byte[params.CRYPTO_PUBLICKEYBYTES]; - byte[] temp = new byte[params.CRYPTO_CIPHERTEXTBYTES + params.MSG_BYTES]; - - // Decrypt - // int EphemeralSecretAgreement_B(PrivateKeyB, PublicKeyA, SharedSecretB) - sidh.EphemeralSecretAgreement_B(sk, ct, jinvariant_); - - Xof digest = new SHAKEDigest(256); - digest.update(jinvariant_, 0, params.FP2_ENCODED_BYTES); - digest.doFinal(h_, 0, params.MSG_BYTES); - for (int i = 0; i < params.MSG_BYTES; i++) - { - temp[i] = (byte) (ct[i + params.CRYPTO_PUBLICKEYBYTES] ^ h_[i]); - } - - // Generate ephemeralsk_ <- G(m||pk) mod oA - System.arraycopy(sk, params.MSG_BYTES + params.SECRETKEY_B_BYTES, temp, params.MSG_BYTES, params.CRYPTO_PUBLICKEYBYTES); - - digest.update(temp, 0, params.CRYPTO_PUBLICKEYBYTES + params.MSG_BYTES); - digest.doFinal(ephemeralsk_, 0, params.SECRETKEY_A_BYTES); - ephemeralsk_[params.SECRETKEY_A_BYTES - 1] &= params.MASK_ALICE; - - - // Generate shared secret ss <- H(m||ct), or output ss <- H(s||ct) in case of ct verification failure - sidh.EphemeralKeyGeneration_A(ephemeralsk_, c0_); - - // If selector = 0 then do ss = H(m||ct), else if selector = -1 load s to do ss = H(s||ct) - byte selector = fpx.ct_compare(c0_, ct, params.CRYPTO_PUBLICKEYBYTES); - fpx.ct_cmov(temp, sk, params.MSG_BYTES, selector); - - System.arraycopy(ct, 0, temp, params.MSG_BYTES, params.CRYPTO_CIPHERTEXTBYTES); - digest.update(temp, 0, params.CRYPTO_CIPHERTEXTBYTES + params.MSG_BYTES); - digest.doFinal(ss, 0, params.CRYPTO_BYTES); - - return 0; - } - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKEMExtractor.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKEMExtractor.java deleted file mode 100644 index 26d0bd4877..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKEMExtractor.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import org.bouncycastle.crypto.CryptoServicePurpose; -import org.bouncycastle.crypto.CryptoServicesRegistrar; -import org.bouncycastle.crypto.EncapsulatedSecretExtractor; -import org.bouncycastle.crypto.constraints.DefaultServiceProperties; - -public class SIKEKEMExtractor - implements EncapsulatedSecretExtractor -{ - private SIKEEngine engine; - - private SIKEKeyParameters key; - - public SIKEKEMExtractor(SIKEPrivateKeyParameters privParams) - { - // -DM System.err.println - System.err.println("WARNING: the SIKE algorithm is only for research purposes, insecure"); - CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("SIKEKEM", 0, privParams, CryptoServicePurpose.DECRYPTION)); - - this.key = privParams; - initCipher(key.getParameters()); - } - - private void initCipher(SIKEParameters param) - { - engine = param.getEngine(); - } - - public byte[] extractSecret(byte[] encapsulation) - { - return extractSecret(encapsulation, engine.getDefaultSessionKeySize()); - } - - public byte[] extractSecret(byte[] encapsulation, int sessionKeySizeInBits) - { - // -DM System.err.println - System.err.println("WARNING: the SIKE algorithm is only for research purposes, insecure"); - byte[] session_key = new byte[sessionKeySizeInBits / 8]; - engine.crypto_kem_dec(session_key, encapsulation, ((SIKEPrivateKeyParameters)key).getPrivateKey()); - return session_key; - } - - public int getEncapsulationLength() - { - return engine.getCipherTextSize(); - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKEMGenerator.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKEMGenerator.java deleted file mode 100644 index ff7cdb9b60..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKEMGenerator.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.CryptoServicePurpose; -import org.bouncycastle.crypto.CryptoServicesRegistrar; -import org.bouncycastle.crypto.EncapsulatedSecretGenerator; -import org.bouncycastle.crypto.SecretWithEncapsulation; -import org.bouncycastle.crypto.constraints.DefaultServiceProperties; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.pqc.crypto.util.SecretWithEncapsulationImpl; - -public class SIKEKEMGenerator - implements EncapsulatedSecretGenerator -{ - // the source of randomness - private final SecureRandom sr; - - - public SIKEKEMGenerator(SecureRandom random) - { - this.sr = random; - } - - public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey) - { - CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("SIKEKEM", 0, recipientKey, CryptoServicePurpose.ENCRYPTION)); - - SIKEPublicKeyParameters key = (SIKEPublicKeyParameters)recipientKey; - SIKEEngine engine = key.getParameters().getEngine(); - - return generateEncapsulated(recipientKey, engine.getDefaultSessionKeySize()); - } - - public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey, int sessionKeySizeInBits) - { - // -DM System.err.println - System.err.println("WARNING: the SIKE algorithm is only for research purposes, insecure"); - SIKEPublicKeyParameters key = (SIKEPublicKeyParameters)recipientKey; - SIKEEngine engine = key.getParameters().getEngine(); - byte[] cipher_text = new byte[engine.getCipherTextSize()]; - byte[] sessionKey = new byte[sessionKeySizeInBits / 8]; - engine.crypto_kem_enc(cipher_text, sessionKey, key.getPublicKey(), sr); - return new SecretWithEncapsulationImpl(sessionKey, cipher_text); - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKeyGenerationParameters.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKeyGenerationParameters.java deleted file mode 100644 index 642f19e70b..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKeyGenerationParameters.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.KeyGenerationParameters; - -public class SIKEKeyGenerationParameters - extends KeyGenerationParameters -{ - private SIKEParameters params; - - public SIKEKeyGenerationParameters( - SecureRandom random, - SIKEParameters sikeParameters - ) - { - super(random, 256); - this.params = sikeParameters; - } - public SIKEParameters getParameters() - { - return params; - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKeyPairGenerator.java deleted file mode 100644 index e783aa5a17..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKeyPairGenerator.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; -import org.bouncycastle.crypto.CryptoServicePurpose; -import org.bouncycastle.crypto.CryptoServicesRegistrar; -import org.bouncycastle.crypto.KeyGenerationParameters; -import org.bouncycastle.crypto.constraints.DefaultServiceProperties; - -public class SIKEKeyPairGenerator - implements AsymmetricCipherKeyPairGenerator -{ - private SIKEKeyGenerationParameters sikeParams; - - private SecureRandom random; - - private void initialize(KeyGenerationParameters param) - { - this.sikeParams = (SIKEKeyGenerationParameters) param; - this.random = param.getRandom(); - } - - private AsymmetricCipherKeyPair genKeyPair() - { - // -DM System.err.println - System.err.println("WARNING: the SIKE algorithm is only for research purposes, insecure"); - CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("SIKEKeyGen", 0, sikeParams.getParameters(), CryptoServicePurpose.KEYGEN)); - - SIKEEngine engine = sikeParams.getParameters().getEngine(); - byte[] sk = new byte[engine.getPrivateKeySize()]; - byte[] pk = new byte[engine.getPublicKeySize()]; - - engine.crypto_kem_keypair(pk, sk, random); - - - SIKEPublicKeyParameters pubKey = new SIKEPublicKeyParameters(sikeParams.getParameters(), pk); - SIKEPrivateKeyParameters privKey = new SIKEPrivateKeyParameters(sikeParams.getParameters(), sk); - return new AsymmetricCipherKeyPair(pubKey, privKey); - } - - public void init(KeyGenerationParameters param) - { - this.initialize(param); - } - - public AsymmetricCipherKeyPair generateKeyPair() - { - return genKeyPair(); - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKeyParameters.java deleted file mode 100644 index b316944ab4..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEKeyParameters.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; - -public class SIKEKeyParameters - extends AsymmetricKeyParameter -{ - private SIKEParameters params; - - public SIKEKeyParameters( - boolean isPrivate, - SIKEParameters params - ) - { - super(isPrivate); - this.params = params; - } - - public SIKEParameters getParameters() - { - return params; - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEParameters.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEParameters.java deleted file mode 100644 index 8d385b74f3..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEParameters.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -public class SIKEParameters -{ - private static class SikeP434Engine - { - static final SIKEEngine INSTANCE = new SIKEEngine(434, false); - } - - private static class SikeP503Engine - { - static final SIKEEngine INSTANCE = new SIKEEngine(503, false); - } - - private static class SikeP610Engine - { - static final SIKEEngine INSTANCE = new SIKEEngine(610, false); - } - - private static class SikeP751Engine - { - static final SIKEEngine INSTANCE = new SIKEEngine(751, false); - } - - private static class SikeP434CompressedEngine - { - static final SIKEEngine INSTANCE = new SIKEEngine(434, true); - } - - private static class SikeP503CompressedEngine - { - static final SIKEEngine INSTANCE = new SIKEEngine(503, true); - } - - private static class SikeP610CompressedEngine - { - static final SIKEEngine INSTANCE = new SIKEEngine(610, true); - } - - private static class SikeP751CompressedEngine - { - static final SIKEEngine INSTANCE = new SIKEEngine(751, true); - } - - public static final SIKEParameters sikep434 = new SIKEParameters(434, false,"sikep434"); - public static final SIKEParameters sikep503 = new SIKEParameters(503, false,"sikep503"); - public static final SIKEParameters sikep610 = new SIKEParameters(610, false,"sikep610"); - public static final SIKEParameters sikep751 = new SIKEParameters(751, false,"sikep751"); - - public static final SIKEParameters sikep434_compressed = new SIKEParameters(434, true,"sikep434_compressed"); - public static final SIKEParameters sikep503_compressed = new SIKEParameters(503, true,"sikep503_compressed"); - public static final SIKEParameters sikep610_compressed = new SIKEParameters(610, true,"sikep610_compressed"); - public static final SIKEParameters sikep751_compressed = new SIKEParameters(751, true,"sikep751_compressed"); - - private final String name; - private final int ver; - private final boolean isCompressed; - private SIKEParameters(int ver, boolean isCompressed, String name) - { - this.name = name; - this.ver = ver; - this.isCompressed = isCompressed; - } - - SIKEEngine getEngine() - { - if (isCompressed) - { - switch (ver) - { - case 434: return SikeP434CompressedEngine.INSTANCE; - case 503: return SikeP503CompressedEngine.INSTANCE; - case 610: return SikeP610CompressedEngine.INSTANCE; - case 751: return SikeP751CompressedEngine.INSTANCE; - default: return null; - } - } - else - { - switch (ver) - { - case 434: return SikeP434Engine.INSTANCE; - case 503: return SikeP503Engine.INSTANCE; - case 610: return SikeP610Engine.INSTANCE; - case 751: return SikeP751Engine.INSTANCE; - default: return null; - } - } - } - - public String getName() - { - return name; - } - - public int getSessionKeySize() - { - return getEngine().getDefaultSessionKeySize(); - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEPrivateKeyParameters.java deleted file mode 100644 index fdeaf7f039..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEPrivateKeyParameters.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import org.bouncycastle.util.Arrays; - -public class SIKEPrivateKeyParameters - extends SIKEKeyParameters -{ - private byte[] privateKey; - - public byte[] getPrivateKey() - { - return Arrays.clone(privateKey); - } - - public SIKEPrivateKeyParameters(SIKEParameters params, byte[] privateKey) - { - super(true, params); - this.privateKey = Arrays.clone(privateKey); - } - - public byte[] getEncoded() - { - return Arrays.clone(privateKey); - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEPublicKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEPublicKeyParameters.java deleted file mode 100644 index 62eeb1ba88..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/crypto/sike/SIKEPublicKeyParameters.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.bouncycastle.pqc.legacy.crypto.sike; - -import org.bouncycastle.util.Arrays; - -public class SIKEPublicKeyParameters - extends SIKEKeyParameters -{ - private final byte[] publicKey; - - public byte[] getPublicKey() - { - return Arrays.clone(publicKey); - } - - public byte[] getEncoded() - { - return getPublicKey(); - } - - public SIKEPublicKeyParameters(SIKEParameters params, byte[] publicKey) - { - super(false, params); - this.publicKey = Arrays.clone(publicKey); - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/ByteUtils.java b/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/ByteUtils.java index f221121567..26eeaa69fd 100644 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/ByteUtils.java +++ b/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/ByteUtils.java @@ -1,5 +1,7 @@ package org.bouncycastle.pqc.legacy.math.linearalgebra; +import org.bouncycastle.util.Strings; + /** * This class is a utility class for manipulating byte arrays. * @@ -180,7 +182,7 @@ public static byte[] clone(byte[] array) */ public static byte[] fromHexString(String s) { - char[] rawChars = s.toUpperCase().toCharArray(); + char[] rawChars = Strings.toUpperCase(s).toCharArray(); int hexChars = 0; for (int i = 0; i < rawChars.length; i++) diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/GF2Polynomial.java b/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/GF2Polynomial.java index 7fea75f326..5f5ed824fa 100644 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/GF2Polynomial.java +++ b/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/GF2Polynomial.java @@ -1736,7 +1736,6 @@ public void setBit(int i) throw new RuntimeException(); } value[i >>> 5] |= bitMask[i & 0x1f]; - return; } /** @@ -1838,7 +1837,7 @@ public GF2Polynomial shiftLeft() */ public void shiftLeftThis() { - /** @todo This is untested. */ + // @todo This is untested. int i; if ((len & 0x1f) == 0) { // check if blocks increases diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/GF2nONBElement.java b/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/GF2nONBElement.java index 6fd601cff5..49cc38fda2 100644 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/GF2nONBElement.java +++ b/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/GF2nONBElement.java @@ -1122,7 +1122,7 @@ else if (radix == 16) */ public BigInteger toFlexiBigInt() { - /** @todo this method does not reverse the bit-order as it should!!! */ + /* @todo this method does not reverse the bit-order as it should!!! */ return new BigInteger(1, toByteArray()); } @@ -1135,7 +1135,7 @@ public BigInteger toFlexiBigInt() */ public byte[] toByteArray() { - /** @todo this method does not reverse the bit-order as it should!!! */ + /* @todo this method does not reverse the bit-order as it should!!! */ int k = ((mDegree - 1) >> 3) + 1; byte[] result = new byte[k]; diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/GF2nPolynomial.java b/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/GF2nPolynomial.java index 09f53f3c2a..1e579b0bf5 100644 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/GF2nPolynomial.java +++ b/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/GF2nPolynomial.java @@ -537,7 +537,7 @@ public final GF2nPolynomial quotient(GF2nPolynomial b) * * @param g - * a GF2nPolynomial - * @return gcd(< i > this < / i >, < i > g < / i >) + * @return gcd(this, g) */ public final GF2nPolynomial gcd(GF2nPolynomial g) { diff --git a/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/IntegerFunctions.java b/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/IntegerFunctions.java index 2b9d7d2160..8e44d10523 100644 --- a/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/IntegerFunctions.java +++ b/core/src/main/java/org/bouncycastle/pqc/legacy/math/linearalgebra/IntegerFunctions.java @@ -483,7 +483,7 @@ public static long pow(long a, int e) */ public static int modPow(int a, int e, int n) { - if (n <= 0 || (n * n) > Integer.MAX_VALUE || e < 0) + if (n <= 0 || ((long)n * n) > Integer.MAX_VALUE || e < 0) { return 0; } diff --git a/core/src/main/java/org/bouncycastle/pqc/math/ntru/HPSPolynomial.java b/core/src/main/java/org/bouncycastle/pqc/math/ntru/HPSPolynomial.java index 855c2236ff..107cc597e1 100644 --- a/core/src/main/java/org/bouncycastle/pqc/math/ntru/HPSPolynomial.java +++ b/core/src/main/java/org/bouncycastle/pqc/math/ntru/HPSPolynomial.java @@ -112,36 +112,4 @@ public void lift(Polynomial a) System.arraycopy(a.coeffs, 0, this.coeffs, 0, n); this.z3ToZq(); } - - @Override - public void r2Inv(Polynomial a) - { - HPSPolynomial f = new HPSPolynomial((NTRUHPSParameterSet)this.params); - HPSPolynomial g = new HPSPolynomial((NTRUHPSParameterSet)this.params); - HPSPolynomial v = new HPSPolynomial((NTRUHPSParameterSet)this.params); - HPSPolynomial w = new HPSPolynomial((NTRUHPSParameterSet)this.params); - this.r2Inv(a, f, g, v, w); - } - - @Override - public void rqInv(Polynomial a) - { - HPSPolynomial ai2 = new HPSPolynomial((NTRUHPSParameterSet)this.params); - HPSPolynomial b = new HPSPolynomial((NTRUHPSParameterSet)this.params); - HPSPolynomial c = new HPSPolynomial((NTRUHPSParameterSet)this.params); - HPSPolynomial s = new HPSPolynomial((NTRUHPSParameterSet)this.params); - this.rqInv(a, ai2, b, c, s); - } - - @Override - public void s3Inv(Polynomial a) - { - HPSPolynomial f = new HPSPolynomial((NTRUHPSParameterSet)this.params); - HPSPolynomial g = new HPSPolynomial((NTRUHPSParameterSet)this.params); - HPSPolynomial v = new HPSPolynomial((NTRUHPSParameterSet)this.params); - HPSPolynomial w = new HPSPolynomial((NTRUHPSParameterSet)this.params); - this.s3Inv(a, f, g, v, w); - } - - } diff --git a/core/src/main/java/org/bouncycastle/pqc/math/ntru/HRSS1373Polynomial.java b/core/src/main/java/org/bouncycastle/pqc/math/ntru/HRSS1373Polynomial.java new file mode 100644 index 0000000000..b69f73ea55 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/math/ntru/HRSS1373Polynomial.java @@ -0,0 +1,84 @@ +package org.bouncycastle.pqc.math.ntru; + +import org.bouncycastle.pqc.math.ntru.parameters.NTRUHRSSParameterSet; + +public class HRSS1373Polynomial + extends HRSSPolynomial +{ + private static final int L = ((1373 + 31) / 32) * 32; + private static final int M = L / 4; + private static final int K = L / 16; + + public HRSS1373Polynomial(NTRUHRSSParameterSet params) + { + super(params); + } + + @Override + public byte[] sqToBytes(int len) + { + byte[] r = new byte[len]; + int i, j; + short[] t = new short[4]; + + for (i = 0; i < params.packDegree() / 4; i++) + { + for (j = 0; j < 4; j++) + { + t[j] = (short)modQ(this.coeffs[4 * i + j] & 0xffff, params.q()); + } + + // t0 t1 t2 t3 + // r0 8 + // r1 6 | 2 + // r2 8 + // r3 4 | 4 + // r4 8 + // r5 2 | 6 + // r6 8 + + r[7 * i + 0] = (byte)(t[0] & 0xff); + r[7 * i + 1] = (byte)((t[0] >>> 8) | ((t[1] & 0x03) << 6)); + r[7 * i + 2] = (byte)((t[1] >>> 2) & 0xff); + r[7 * i + 3] = (byte)((t[1] >>> 10) | ((t[2] & 0x0f) << 4)); + r[7 * i + 4] = (byte)((t[2] >>> 4) & 0xff); + r[7 * i + 5] = (byte)((t[2] >>> 12) | ((t[3] & 0x3f) << 2)); + r[7 * i + 6] = (byte)(t[3] >>> 6); + } + + // i=NTRU_PACK_DEG/4; + if (params.packDegree() % 4 == 2) + { + t[0] = (short)modQ(this.coeffs[params.packDegree() - 2] & 0xffff, params.q()); + t[1] = (short)modQ(this.coeffs[params.packDegree() - 1] & 0xffff, params.q()); + r[7 * i + 0] = (byte)(t[0] & 0xff); + r[7 * i + 1] = (byte)((t[0] >>> 8) | ((t[1] & 0x03) << 6)); + r[7 * i + 2] = (byte)((t[1] >>> 2) & 0xff); + r[7 * i + 3] = (byte)(t[1] >>> 10); + } + + return r; + } + + @Override + public void sqFromBytes(byte[] a) + { + int i; + for (i = 0; i < params.packDegree() / 4; i++) + { + this.coeffs[4 * i + 0] = (short)((a[7 * i + 0] & 0xff) | (((short)(a[7 * i + 1] & 0xff) & 0x3f) << 8)); + this.coeffs[4 * i + 1] = (short)(((a[7 * i + 1] & 0xff) >>> 6) | (((short)(a[7 * i + 2] & 0xff)) << 2) | ((short)(a[7 * i + 3] & 0x0f) << 10)); + this.coeffs[4 * i + 2] = (short)(((a[7 * i + 3] & 0xff) >>> 4) | (((short)(a[7 * i + 4] & 0xff) & 0xff) << 4) | ((short)(a[7 * i + 5] & 0x03) << 12)); + this.coeffs[4 * i + 3] = (short)(((a[7 * i + 5] & 0xff) >>> 2) | (((short)(a[7 * i + 6] & 0xff)) << 6)); + } + + // i=NTRU_PACK_DEG/4; + if (params.packDegree() % 4 == 2) + { + this.coeffs[4 * i + 0] = (short)(a[7 * i + 0] | ((a[7 * i + 1] & 0x3f) << 8)); + this.coeffs[4 * i + 1] = (short)((a[7 * i + 1] >>> 6) | (((short)a[7 * i + 2]) << 2) | (((short)a[7 * i + 3] & 0x0f) << 10)); + } + + this.coeffs[params.n() - 1] = 0; + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/math/ntru/HRSSPolynomial.java b/core/src/main/java/org/bouncycastle/pqc/math/ntru/HRSSPolynomial.java index 091f81420a..e71fb09d2e 100644 --- a/core/src/main/java/org/bouncycastle/pqc/math/ntru/HRSSPolynomial.java +++ b/core/src/main/java/org/bouncycastle/pqc/math/ntru/HRSSPolynomial.java @@ -117,7 +117,7 @@ public void lift(Polynomial a) /* NOTE: Assumes input is in {0,1,2}^N */ /* Produces output in [0,Q-1]^N */ int i; - HRSSPolynomial b = new HRSSPolynomial((NTRUHRSSParameterSet)this.params); + Polynomial b = this.params.createPolynomial(); short t, zj; /* Define z by = delta_{i,0} mod 3: */ @@ -162,34 +162,4 @@ public void lift(Polynomial a) this.coeffs[i + 1] = (short)(b.coeffs[i] - b.coeffs[i + 1]); } } - - @Override - public void r2Inv(Polynomial a) - { - HRSSPolynomial f = new HRSSPolynomial((NTRUHRSSParameterSet)this.params); - HRSSPolynomial g = new HRSSPolynomial((NTRUHRSSParameterSet)this.params); - HRSSPolynomial v = new HRSSPolynomial((NTRUHRSSParameterSet)this.params); - HRSSPolynomial w = new HRSSPolynomial((NTRUHRSSParameterSet)this.params); - this.r2Inv(a, f, g, v, w); - } - - @Override - public void rqInv(Polynomial a) - { - HRSSPolynomial ai2 = new HRSSPolynomial((NTRUHRSSParameterSet)this.params); - HRSSPolynomial b = new HRSSPolynomial((NTRUHRSSParameterSet)this.params); - HRSSPolynomial c = new HRSSPolynomial((NTRUHRSSParameterSet)this.params); - HRSSPolynomial s = new HRSSPolynomial((NTRUHRSSParameterSet)this.params); - this.rqInv(a, ai2, b, c, s); - } - - @Override - public void s3Inv(Polynomial a) - { - HRSSPolynomial f = new HRSSPolynomial((NTRUHRSSParameterSet)this.params); - HRSSPolynomial g = new HRSSPolynomial((NTRUHRSSParameterSet)this.params); - HRSSPolynomial v = new HRSSPolynomial((NTRUHRSSParameterSet)this.params); - HRSSPolynomial w = new HRSSPolynomial((NTRUHRSSParameterSet)this.params); - this.s3Inv(a, f, g, v, w); - } } diff --git a/core/src/main/java/org/bouncycastle/pqc/math/ntru/Polynomial.java b/core/src/main/java/org/bouncycastle/pqc/math/ntru/Polynomial.java index 1dcc5b43b7..f207f25cc4 100644 --- a/core/src/main/java/org/bouncycastle/pqc/math/ntru/Polynomial.java +++ b/core/src/main/java/org/bouncycastle/pqc/math/ntru/Polynomial.java @@ -257,9 +257,35 @@ public void rqToS3(Polynomial a) this.mod3PhiN(); } - // defined in poly_r2_inv.c - public abstract void r2Inv(Polynomial a); + public void r2Inv(Polynomial a) + { + Polynomial f = this.params.createPolynomial(); + Polynomial g = this.params.createPolynomial(); + Polynomial v = this.params.createPolynomial(); + Polynomial w = this.params.createPolynomial(); + this.r2Inv(a, f, g, v, w); + } + + // defined in poly.c + public void rqInv(Polynomial a) + { + Polynomial ai2 = this.params.createPolynomial(); + Polynomial b = this.params.createPolynomial(); + Polynomial c = this.params.createPolynomial(); + Polynomial s = this.params.createPolynomial(); + this.rqInv(a, ai2, b, c, s); + } + + // defined in poly_s3_inv.c + public void s3Inv(Polynomial a) + { + Polynomial f = this.params.createPolynomial(); + Polynomial g = this.params.createPolynomial(); + Polynomial v = this.params.createPolynomial(); + Polynomial w = this.params.createPolynomial(); + this.s3Inv(a, f, g, v, w); + } void r2Inv(Polynomial a, Polynomial f, Polynomial g, Polynomial v, Polynomial w) { @@ -326,9 +352,6 @@ void r2Inv(Polynomial a, Polynomial f, Polynomial g, Polynomial v, Polynomial w) this.coeffs[n - 1] = 0; } - // defined in poly.c - public abstract void rqInv(Polynomial a); - void rqInv(Polynomial a, Polynomial ai2, Polynomial b, Polynomial c, Polynomial s) { ai2.r2Inv(a); @@ -365,10 +388,7 @@ private void r2InvToRqInv(Polynomial ai, Polynomial a, Polynomial b, Polynomial c.coeffs[0] += 2; this.rqMul(c, s); } - - // defined in poly_s3_inv.c - public abstract void s3Inv(Polynomial a); - + void s3Inv(Polynomial a, Polynomial f, Polynomial g, Polynomial v, Polynomial w) { int n = this.coeffs.length; diff --git a/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHPS2048509.java b/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHPS2048509.java index 242dbccf91..8d1fa3721d 100644 --- a/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHPS2048509.java +++ b/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHPS2048509.java @@ -15,7 +15,7 @@ public NTRUHPS2048509() 11, 32, 32, - 16 // category 1 (local model), 16. + 32 // category 1 (local model) ); } } diff --git a/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHPS2048677.java b/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHPS2048677.java index 86a42d73e1..7b1a77ea73 100644 --- a/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHPS2048677.java +++ b/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHPS2048677.java @@ -16,7 +16,7 @@ public NTRUHPS2048677() 11, 32, 32, - 24 // Category 3 (local model) - KATs based on 256 bit + 32 // Category 3 (local model) - KATs based on 256 bit ); } } diff --git a/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHPS40961229.java b/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHPS40961229.java new file mode 100644 index 0000000000..1e55a9fcd8 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHPS40961229.java @@ -0,0 +1,30 @@ +package org.bouncycastle.pqc.math.ntru.parameters; + +import org.bouncycastle.pqc.math.ntru.HPS4096Polynomial; +import org.bouncycastle.pqc.math.ntru.Polynomial; + +/** + * NTRU-HPS parameter set with n = 1229 and q = 4096. + * + * @see NTRUHPSParameterSet + */ +public class NTRUHPS40961229 + extends NTRUHPSParameterSet +{ + public NTRUHPS40961229() + { + super( + 1229, + 12, + 32, + 32, + 32 // Category 5 (local model) + ); + } + + @Override + public Polynomial createPolynomial() + { + return new HPS4096Polynomial(this); + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHRSS1373.java b/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHRSS1373.java new file mode 100644 index 0000000000..2bdfafc77d --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHRSS1373.java @@ -0,0 +1,22 @@ +package org.bouncycastle.pqc.math.ntru.parameters; + + +/** + * NTRU-HRSS parameter set with n = 701. + * + * @see NTRUHRSSParameterSet + */ +public class NTRUHRSS1373 + extends NTRUHRSSParameterSet +{ + public NTRUHRSS1373() + { + super( + 1373, + 14, + 32, + 32, + 32 // Category 5 (local model) - KATs based on 256 bit + ); + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHRSS701.java b/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHRSS701.java index 7017e53772..2fea3bd0a2 100644 --- a/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHRSS701.java +++ b/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHRSS701.java @@ -16,7 +16,7 @@ public NTRUHRSS701() 13, 32, 32, - 24 // Category 3 (local model) - KATs based on 256 bit + 32 // Category 3 (local model) - KATs based on 256 bit ); } } diff --git a/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHRSSParameterSet.java b/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHRSSParameterSet.java index 2e6f7f50ff..89986f2f97 100644 --- a/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHRSSParameterSet.java +++ b/core/src/main/java/org/bouncycastle/pqc/math/ntru/parameters/NTRUHRSSParameterSet.java @@ -1,5 +1,6 @@ package org.bouncycastle.pqc.math.ntru.parameters; +import org.bouncycastle.pqc.math.ntru.HRSS1373Polynomial; import org.bouncycastle.pqc.math.ntru.HRSSPolynomial; import org.bouncycastle.pqc.math.ntru.Polynomial; @@ -22,7 +23,7 @@ public abstract class NTRUHRSSParameterSet @Override public Polynomial createPolynomial() { - return new HRSSPolynomial(this); + return this.n() == 1373 ? new HRSS1373Polynomial(this) : new HRSSPolynomial(this); } @Override diff --git a/core/src/main/java/org/bouncycastle/util/Arrays.java b/core/src/main/java/org/bouncycastle/util/Arrays.java index 999011aca6..27371dd423 100644 --- a/core/src/main/java/org/bouncycastle/util/Arrays.java +++ b/core/src/main/java/org/bouncycastle/util/Arrays.java @@ -803,9 +803,7 @@ private static int getLength(int from, int to) int newLength = to - from; if (newLength < 0) { - StringBuffer sb = new StringBuffer(from); - sb.append(" > ").append(to); - throw new IllegalArgumentException(sb.toString()); + throw new IllegalArgumentException(from + " > " + to); } return newLength; } @@ -1072,6 +1070,15 @@ public static int[] reverse(int[] a) return result; } + public static void reverse(byte[] input, byte[] output) + { + int last = input.length - 1; + for (int i = 0; i <= last; ++i) + { + output[i] = input[last - i]; + } + } + public static byte[] reverseInPlace(byte[] a) { if (null == a) @@ -1101,6 +1108,24 @@ public static void reverseInPlace(byte[] a, int aOff, int aLen) } } + public static short[] reverseInPlace(short[] a) + { + if (null == a) + { + return null; + } + + int p1 = 0, p2 = a.length - 1; + while (p1 < p2) + { + short t1 = a[p1], t2 = a[p2]; + a[p1++] = t2; + a[p2--] = t1; + } + + return a; + } + public static int[] reverseInPlace(int[] a) { if (null == a) diff --git a/core/src/main/java/org/bouncycastle/util/BigIntegers.java b/core/src/main/java/org/bouncycastle/util/BigIntegers.java index 5d908eb493..7e70366cdc 100644 --- a/core/src/main/java/org/bouncycastle/util/BigIntegers.java +++ b/core/src/main/java/org/bouncycastle/util/BigIntegers.java @@ -218,7 +218,7 @@ public static BigInteger modOddInverse(BigInteger M, BigInteger X) { throw new ArithmeticException("BigInteger: modulus not positive"); } - if (X.signum() < 0 || X.compareTo(M) >= 0) + if (X.signum() < 0 || X.bitLength() > M.bitLength()) { X = X.mod(M); } @@ -249,7 +249,7 @@ public static BigInteger modOddInverseVar(BigInteger M, BigInteger X) { return ZERO; } - if (X.signum() < 0 || X.compareTo(M) >= 0) + if (X.signum() < 0 || X.bitLength() > M.bitLength()) { X = X.mod(M); } @@ -270,6 +270,52 @@ public static BigInteger modOddInverseVar(BigInteger M, BigInteger X) return Nat.toBigInteger(len, z); } + public static boolean modOddIsCoprime(BigInteger M, BigInteger X) + { + if (!M.testBit(0)) + { + throw new IllegalArgumentException("'M' must be odd"); + } + if (M.signum() != 1) + { + throw new ArithmeticException("BigInteger: modulus not positive"); + } + if (X.signum() < 0 || X.bitLength() > M.bitLength()) + { + X = X.mod(M); + } + + int bits = M.bitLength(); + int[] m = Nat.fromBigInteger(bits, M); + int[] x = Nat.fromBigInteger(bits, X); + return 0 != Mod.modOddIsCoprime(m, x); + } + + public static boolean modOddIsCoprimeVar(BigInteger M, BigInteger X) + { + if (!M.testBit(0)) + { + throw new IllegalArgumentException("'M' must be odd"); + } + if (M.signum() != 1) + { + throw new ArithmeticException("BigInteger: modulus not positive"); + } + if (X.signum() < 0 || X.bitLength() > M.bitLength()) + { + X = X.mod(M); + } + if (X.equals(ONE)) + { + return true; + } + + int bits = M.bitLength(); + int[] m = Nat.fromBigInteger(bits, M); + int[] x = Nat.fromBigInteger(bits, X); + return Mod.modOddIsCoprimeVar(m, x); + } + public static int getUnsignedByteLength(BigInteger n) { if (n.equals(ZERO)) diff --git a/core/src/main/java/org/bouncycastle/util/Bytes.java b/core/src/main/java/org/bouncycastle/util/Bytes.java index 572e225701..4db85758a0 100644 --- a/core/src/main/java/org/bouncycastle/util/Bytes.java +++ b/core/src/main/java/org/bouncycastle/util/Bytes.java @@ -7,4 +7,36 @@ public class Bytes { public static final int BYTES = 1; public static final int SIZE = Byte.SIZE; + + public static void xor(int len, byte[] x, byte[] y, byte[] z) + { + for (int i = 0; i < len; ++i) + { + z[i] = (byte)(x[i] ^ y[i]); + } + } + + public static void xor(int len, byte[] x, int xOff, byte[] y, int yOff, byte[] z, int zOff) + { + for (int i = 0; i < len; ++i) + { + z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); + } + } + + public static void xorTo(int len, byte[] x, byte[] z) + { + for (int i = 0; i < len; ++i) + { + z[i] ^= x[i]; + } + } + + public static void xorTo(int len, byte[] x, int xOff, byte[] z, int zOff) + { + for (int i = 0; i < len; ++i) + { + z[zOff + i] ^= x[xOff + i]; + } + } } diff --git a/core/src/main/java/org/bouncycastle/util/Exceptions.java b/core/src/main/java/org/bouncycastle/util/Exceptions.java index 6c5f66608a..74ef192532 100644 --- a/core/src/main/java/org/bouncycastle/util/Exceptions.java +++ b/core/src/main/java/org/bouncycastle/util/Exceptions.java @@ -1,7 +1,6 @@ package org.bouncycastle.util; import java.io.IOException; -import java.io.InvalidObjectException; public class Exceptions { diff --git a/core/src/main/java/org/bouncycastle/util/Pack.java b/core/src/main/java/org/bouncycastle/util/Pack.java index 54237f143d..a2ce48f90e 100644 --- a/core/src/main/java/org/bouncycastle/util/Pack.java +++ b/core/src/main/java/org/bouncycastle/util/Pack.java @@ -174,6 +174,25 @@ public static int littleEndianToInt(byte[] bs, int off) return n; } + public static int littleEndianToInt_High(byte[] bs, int off, int len) + { + return littleEndianToInt_Low(bs, off, len) << ((4 - len) << 3); + } + + public static int littleEndianToInt_Low(byte[] bs, int off, int len) + { +// assert 1 <= len && len <= 4; + + int result = bs[off] & 0xff; + int pos = 0; + for (int i = 1; i < len; ++i) + { + pos += 8; + result |= (bs[off + i] & 0xff) << pos; + } + return result; + } + public static void littleEndianToInt(byte[] bs, int off, int[] ns) { for (int i = 0; i < ns.length; ++i) diff --git a/core/src/main/java/org/bouncycastle/util/Properties.java b/core/src/main/java/org/bouncycastle/util/Properties.java index 645054d041..62c7c724f8 100644 --- a/core/src/main/java/org/bouncycastle/util/Properties.java +++ b/core/src/main/java/org/bouncycastle/util/Properties.java @@ -48,6 +48,32 @@ public static boolean isOverrideSet(String propertyName) } } + /** + * Return whether a particular override has been set to true. + * + * @param propertyName the property name for the override. + * @return true if the property is set to "true", false otherwise. + */ + public static boolean isOverrideSet(String propertyName, boolean defIsTrue) + { + try + { + String value = getPropertyValue(propertyName); + if (value == null) + { + return defIsTrue; + } + else + { + return isSetTrue(value); + } + } + catch (AccessControlException e) + { + return false; + } + } + /** * Return whether a particular override has been set to false. * @@ -217,6 +243,18 @@ public Object run() }); } + public static String getPropertyValue(final String propertyName, String defValue) + { + String rv = getPropertyValue(propertyName); + + if (rv == null) + { + return defValue; + } + + return rv; + } + private static boolean isSetFalse(String p) { if (p == null || p.length() != 5) diff --git a/core/src/main/java/org/bouncycastle/util/io/LimitedBuffer.java b/core/src/main/java/org/bouncycastle/util/io/LimitedBuffer.java new file mode 100644 index 0000000000..4b8421111f --- /dev/null +++ b/core/src/main/java/org/bouncycastle/util/io/LimitedBuffer.java @@ -0,0 +1,53 @@ +package org.bouncycastle.util.io; + +import java.io.OutputStream; + +public class LimitedBuffer extends OutputStream +{ + private final byte[] buf; + private int count; + + public LimitedBuffer(int limit) + { + buf = new byte[limit]; + count = 0; + } + + public int copyTo(byte[] b, int off) + { + System.arraycopy(buf, 0, b, off, count); + return count; + } + + public int limit() + { + return buf.length; + } + + public void reset() + { + count = 0; + } + + public int size() + { + return count; + } + + public void write(int b) + { + buf[count++] = (byte)b; + } + + public void write(byte[] b) + { + System.arraycopy(b, 0, buf, count, b.length); + count += b.length; + } + + public void write(byte b[], int off, int len) + { + System.arraycopy(b, off, buf, count, len); + count += len; + } +} diff --git a/core/src/main/java/org/bouncycastle/util/io/pem/PemReader.java b/core/src/main/java/org/bouncycastle/util/io/pem/PemReader.java index 7156818784..53008fcca2 100644 --- a/core/src/main/java/org/bouncycastle/util/io/pem/PemReader.java +++ b/core/src/main/java/org/bouncycastle/util/io/pem/PemReader.java @@ -5,6 +5,8 @@ import java.io.Reader; import java.util.ArrayList; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import org.bouncycastle.util.encoders.Base64; @@ -14,8 +16,11 @@ public class PemReader extends BufferedReader { + public static final String LAX_PEM_PARSING_SYSTEM_PROPERTY_NAME = "org.bouncycastle.pemreader.lax"; + private static final String BEGIN = "-----BEGIN "; private static final String END = "-----END "; + private static final Logger LOG = Logger.getLogger(PemReader.class.getName()); public PemReader(Reader reader) { @@ -40,7 +45,7 @@ public PemObject readPemObject() if (line != null) { - line = line.substring(BEGIN.length()); + line = line.substring(BEGIN.length()).trim(); int index = line.indexOf('-'); if (index > 0 && line.endsWith("-----") && (line.length() - index) == 5) @@ -58,7 +63,7 @@ private PemObject loadObject(String type) throws IOException { String line; - String endMarker = END + type; + String endMarker = END + type + "-----"; StringBuffer buf = new StringBuffer(); List headers = new ArrayList(); @@ -75,7 +80,17 @@ private PemObject loadObject(String type) continue; } - if (line.indexOf(endMarker) != -1) + if (System.getProperty(LAX_PEM_PARSING_SYSTEM_PROPERTY_NAME, "false").equalsIgnoreCase("true")) + { + String trimmedLine = line.trim(); + if (!trimmedLine.equals(line) && LOG.isLoggable(Level.WARNING)) + { + LOG.log(Level.WARNING, "PEM object contains whitespaces on -----END line", new Exception("trace")); + } + line = trimmedLine; + } + + if (line.indexOf(endMarker) == 0) { break; } diff --git a/core/src/main/java/org/bouncycastle/util/test/SimpleTest.java b/core/src/main/java/org/bouncycastle/util/test/SimpleTest.java index 3278b48e96..742c1a7470 100644 --- a/core/src/main/java/org/bouncycastle/util/test/SimpleTest.java +++ b/core/src/main/java/org/bouncycastle/util/test/SimpleTest.java @@ -233,7 +233,6 @@ public static void runTests(Test[] tests, PrintStream out) { TestResult result = tests[i].perform(); - if (!result.isSuccessful()) { failures.addElement(result); @@ -266,8 +265,30 @@ public static void runTests(Test[] tests, PrintStream out) System.out.println("=> " + (TestResult)e.nextElement()); } } + } + protected interface TestExceptionOperation + { + void operation() + throws Exception; + } - + protected Exception testException(String failMessage, String exceptionClass, TestExceptionOperation operation) + { + try + { + operation.operation(); + fail(failMessage); + } + catch (Exception e) + { + if (failMessage != null) + { + isTrue(e.getMessage(), e.getMessage().indexOf(failMessage) >= 0); + } + isTrue(e.getClass().getName().indexOf(exceptionClass) >= 0); + return e; + } + return null; } } diff --git a/core/src/main/jdk1.1/java/security/cert/CertUtil.java b/core/src/main/jdk1.1/java/security/cert/CertUtil.java index cf1aae2029..323790723d 100644 --- a/core/src/main/jdk1.1/java/security/cert/CertUtil.java +++ b/core/src/main/jdk1.1/java/security/cert/CertUtil.java @@ -1,17 +1,15 @@ package java.security.cert; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; +import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.DERIA5String; -import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.OIDTokenizer; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.util.Strings; @@ -336,12 +334,7 @@ static byte[] parseOID(String oid) throws IOException { throw new IOException("token: " + token + ": " + ex.toString()); } - ASN1Object derData = new ASN1ObjectIdentifier(oid); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - derOutStream.writeObject(derData); - derOutStream.close(); - return outStream.toByteArray(); + return new ASN1ObjectIdentifier(oid).getEncoded(ASN1Encoding.DER); } /** @@ -452,12 +445,7 @@ private static byte[] parseIPv6(String data) private static byte[] parseURI(String data) throws IOException { // TODO do parsing test - ASN1Object derData = new DERIA5String(data); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - derOutStream.writeObject(derData); - derOutStream.close(); - return outStream.toByteArray(); + return new DERIA5String(data).getEncoded(ASN1Encoding.DER); } /** @@ -479,13 +467,8 @@ private static byte[] parseRfc822(String data) throws IOException { throw new IOException("wrong format of rfc822Name:" + data); } - // TODO more test for illegal charateers - ASN1Object derData = new DERIA5String(data); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - derOutStream.writeObject(derData); - derOutStream.close(); - return outStream.toByteArray(); + // TODO more test for illegal characters + return new DERIA5String(data).getEncoded(ASN1Encoding.DER); } /** @@ -502,13 +485,8 @@ private static byte[] parseRfc822(String data) throws IOException */ private static byte[] parseDNSName(String data) throws IOException { - // TODO more test for illegal charateers - ASN1Object derData = new DERIA5String(data); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - derOutStream.writeObject(derData); - derOutStream.close(); - return outStream.toByteArray(); + // TODO more test for illegal characters + return new DERIA5String(data).getEncoded(ASN1Encoding.DER); } /** @@ -524,12 +502,8 @@ private static byte[] parseDNSName(String data) throws IOException */ private static byte[] parseX509Name(String data) throws IOException { - // TODO more test for illegal charateers - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - derOutStream.writeObject(new X509Name(trimX509Name(data))); - derOutStream.close(); - return outStream.toByteArray(); + // TODO more test for illegal characters + return new X509Name(trimX509Name(data)).getEncoded(ASN1Encoding.DER); } /** diff --git a/core/src/main/jdk1.1/java/security/cert/X509CertSelector.java b/core/src/main/jdk1.1/java/security/cert/X509CertSelector.java index d242e02d4d..69da5faddb 100644 --- a/core/src/main/jdk1.1/java/security/cert/X509CertSelector.java +++ b/core/src/main/jdk1.1/java/security/cert/X509CertSelector.java @@ -1,7 +1,5 @@ package java.security.cert; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.PublicKey; @@ -20,16 +18,15 @@ import java.util.List; import java.util.Set; -import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; -import org.bouncycastle.asn1.ASN1OutputStream; +import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.ASN1GeneralizedTime; -import org.bouncycastle.asn1.DERGeneralizedTime; -import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; @@ -77,10 +74,8 @@ * TODO: implement name constraints * TODO: implement match check for path to names
    *
    - * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, + * Uses {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, - * {@link org.bouncycastle.asn1.ASN1OutputStream DEROutputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.OIDTokenizer OIDTokenizer}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name}, @@ -284,8 +279,7 @@ public void setIssuer(String issuerDN) throws IOException * Note that the byte array specified here is cloned to protect against * subsequent modifications.
    *
    - * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, + * Uses {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} * @@ -305,9 +299,7 @@ public void setIssuer(byte[] issuerDN) throws IOException } else { - ByteArrayInputStream inStream = new ByteArrayInputStream(issuerDN); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object obj = derInStream.readObject(); + ASN1Object obj = ASN1Primitive.fromByteArray(issuerDN); if (obj instanceof ASN1Sequence) { this.issuerDNX509 = new X509Name((ASN1Sequence)obj); @@ -371,8 +363,7 @@ public void setSubject(String subjectDN) throws IOException * the ASN.1 notation for this structure, see * {@link #setIssuer(byte []) setIssuer(byte [] issuerDN)}.
    *
    - * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, + * Uses {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} * @@ -392,10 +383,7 @@ public void setSubject(byte[] subjectDN) throws IOException } else { - ByteArrayInputStream inStream = new ByteArrayInputStream(subjectDN); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object obj = derInStream.readObject(); - + ASN1Object obj = ASN1Primitive.fromByteArray(subjectDN); if (obj instanceof ASN1Sequence) { this.subjectDNX509 = new X509Name((ASN1Sequence)obj); @@ -587,8 +575,15 @@ public void setPrivateKeyValid(Date privateKeyValid) */ public void setSubjectPublicKeyAlgID(String oid) throws IOException { - CertUtil.parseOID(oid); - subjectKeyAlgID = new ASN1ObjectIdentifier(oid); + if (oid != null) + { + CertUtil.parseOID(oid); + subjectKeyAlgID = new ASN1ObjectIdentifier(oid); + } + else + { + subjectKeyAlgID = null; + } } /** @@ -728,11 +723,11 @@ public void setExtendedKeyUsage(Set keyPurposeSet) throws IOException { if (keyPurposeSet == null || keyPurposeSet.isEmpty()) { - this.keyPurposeSet = keyPurposeSet; + this.keyPurposeSet = null; } else { - this.keyPurposeSet = new HashSet(); + HashSet checkKeyPurposeSet = new HashSet(); Iterator iter = keyPurposeSet.iterator(); Object obj; KeyPurposeId purposeID; @@ -741,15 +736,16 @@ public void setExtendedKeyUsage(Set keyPurposeSet) throws IOException obj = iter.next(); if (obj instanceof String) { - purposeID = (KeyPurposeId)keyPurposeIdMap.get((String)obj); + String str = (String)obj; + purposeID = (KeyPurposeId)keyPurposeIdMap.get(str); if (purposeID == null) { - throw new IOException("unknown purposeID " - + (String)obj); + throw new IOException("unknown purposeID " + str); } - this.keyPurposeSet.add(purposeID); + checkKeyPurposeSet.add(purposeID); } } + this.keyPurposeSet = Collections.unmodifiableSet(checkKeyPurposeSet); } } @@ -849,8 +845,7 @@ else if (data instanceof byte[]) } else { - throw new IOException( - "parsing error: unknown data type"); + throw new IOException("parsing error: unknown data type"); } } } @@ -901,6 +896,7 @@ public void addSubjectAlternativeName(int type, String name) tmpList.add(Integers.valueOf(type)); tmpList.add(name); subjectAltNames.add(tmpList); + // FIXME Surely this affects the entry we just added to subjectAltNames?? tmpList.set(1, encoded); subjectAltNamesByte.add(tmpList); } @@ -1087,7 +1083,7 @@ public void setPolicy(Set certPolicySet) throws IOException } else { - policyOID = new HashSet(); + HashSet checkPolicyOID = new HashSet(); Iterator iter = certPolicySet.iterator(); Object item; while (iter.hasNext()) @@ -1096,15 +1092,15 @@ public void setPolicy(Set certPolicySet) throws IOException if (item instanceof String) { CertUtil.parseOID((String)item); - policyOID.add(new ASN1ObjectIdentifier((String)item)); + checkPolicyOID.add(new ASN1ObjectIdentifier((String)item)); } else { - throw new IOException( - "certPolicySet contains null values or non String objects"); + throw new IOException("certPolicySet contains null values or non String objects"); } } - policy = new HashSet(certPolicySet); + this.policy = Collections.unmodifiableSet(new HashSet(certPolicySet)); + this.policyOID = Collections.unmodifiableSet(checkPolicyOID); } } @@ -1190,8 +1186,7 @@ else if (data instanceof byte[]) } else { - throw new IOException( - "parsing error: unknown data type"); + throw new IOException("parsing error: unknown data type"); } } } @@ -1241,6 +1236,7 @@ public void addPathToName(int type, String name) throws IOException tmpList.add(Integers.valueOf(type)); tmpList.add(name); pathToNames.add(tmpList); + // FIXME Surely this affects the entry we just added to pathToNames?? tmpList.set(1, encoded); pathToNamesByte.add(tmpList); throw new UnsupportedOperationException(); @@ -1333,7 +1329,7 @@ public String getIssuerAsString() { if (issuerDN instanceof String) { - return new String((String)issuerDN); + return (String)issuerDN; } else if (issuerDNX509 != null) { @@ -1357,8 +1353,7 @@ else if (issuerDNX509 != null) * Note that the byte array returned is cloned to protect against subsequent * modifications.
    *
    - * Uses {@link org.bouncycastle.asn1.ASN1OutputStream DEROutputStream}, - * {@link org.bouncycastle.asn1.x509.X509Name X509Name} to gnerate byte[] + * Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} to generate byte[] * output for String issuerDN. * * @return a byte array containing the required issuer distinguished name in @@ -1375,13 +1370,7 @@ public byte[] getIssuerAsBytes() throws IOException } else if (issuerDNX509 != null) { - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - - derOutStream.writeObject(issuerDNX509.toASN1Primitive()); - derOutStream.close(); - - return outStream.toByteArray(); + return issuerDNX509.getEncoded(ASN1Encoding.DER); } return null; @@ -1406,7 +1395,7 @@ public String getSubjectAsString() { if (subjectDN instanceof String) { - return new String((String)subjectDN); + return (String)subjectDN; } else if (subjectDNX509 != null) { @@ -1430,8 +1419,7 @@ else if (subjectDNX509 != null) * Note that the byte array returned is cloned to protect against subsequent * modifications.
    *
    - * Uses {@link org.bouncycastle.asn1.ASN1OutputStream DEROutputStream}, - * {@link org.bouncycastle.asn1.x509.X509Name X509Name} to gnerate byte[] + * Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} to generate byte[] * output for String subjectDN. * * @return a byte array containing the required subject distinguished name @@ -1448,13 +1436,7 @@ public byte[] getSubjectAsBytes() throws IOException } else if (subjectDNX509 != null) { - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - - derOutStream.writeObject(subjectDNX509.toASN1Primitive()); - derOutStream.close(); - - return outStream.toByteArray(); + return subjectDNX509.getEncoded(ASN1Encoding.DER); } return null; @@ -1627,19 +1609,7 @@ public boolean[] getKeyUsage() */ public Set getExtendedKeyUsage() { - if (keyPurposeSet == null || keyPurposeSet.isEmpty()) - { - return keyPurposeSet; - } - - Set returnSet = new HashSet(); - Iterator iter = keyPurposeSet.iterator(); - while (iter.hasNext()) - { - returnSet.add(iter.next().toString()); - } - - return Collections.unmodifiableSet(returnSet); + return keyPurposeSet; } /** @@ -1697,7 +1667,7 @@ public boolean getMatchAllSubjectAltNames() */ public Collection getSubjectAlternativeNames() { - if (subjectAltNames != null) + if (subjectAltNames == null) { return null; } @@ -1706,19 +1676,18 @@ public Collection getSubjectAlternativeNames() List returnList; Iterator iter = subjectAltNames.iterator(); List obj; + Object data; while (iter.hasNext()) { obj = (List)iter.next(); returnList = new ArrayList(); returnList.add(obj.get(0)); - if (obj.get(1) instanceof byte[]) - { - returnList.add(((byte[])obj.get(1)).clone()); - } - else + data = obj.get(1); + if (data instanceof byte[]) { - returnList.add(obj.get(1)); + data = data.clone(); } + returnList.add(data); returnAltNames.add(returnList); } @@ -1788,12 +1757,7 @@ public int getBasicConstraints() */ public Set getPolicy() { - if (policy == null) - { - return null; - } - - return Collections.unmodifiableSet(policy); + return policy; } /** @@ -1836,20 +1800,18 @@ public Collection getPathToNames() List returnList; Iterator iter = pathToNames.iterator(); List obj; - + Object data; while (iter.hasNext()) { obj = (List)iter.next(); returnList = new ArrayList(); returnList.add(obj.get(0)); - if (obj.get(1) instanceof byte[]) - { - returnList.add(((byte[])obj.get(1)).clone()); - } - else + data = obj.get(1); + if (data instanceof byte[]) { - returnList.add(obj.get(1)); + data = data.clone(); } + returnList.add(data); returnPathToNames.add(returnList); } @@ -1862,8 +1824,7 @@ public Collection getPathToNames() * TODO: implement output for currently unsupported options(name * constraints)
    *
    - * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, + * Uses {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.x509.KeyPurposeId KeyPurposeId} * * @return a String describing the contents of the @@ -1893,19 +1854,13 @@ public String toString() { if (subjectKeyID != null) { - ByteArrayInputStream inStream = new ByteArrayInputStream( - subjectKeyID); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object derObject = derInStream.readObject(); + ASN1Object derObject = ASN1Primitive.fromByteArray(subjectKeyID); sb.append(" Subject Key Identifier: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } if (authorityKeyID != null) { - ByteArrayInputStream inStream = new ByteArrayInputStream( - authorityKeyID); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object derObject = derInStream.readObject(); + ASN1Object derObject = ASN1Primitive.fromByteArray(authorityKeyID); sb.append(" Authority Key Identifier: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } @@ -1958,10 +1913,7 @@ public String toString() while (iter.hasNext()) { obj = (List)iter.next(); - ByteArrayInputStream inStream = new ByteArrayInputStream( - (byte[])obj.get(1)); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object derObject = derInStream.readObject(); + ASN1Object derObject = ASN1Primitive.fromByteArray((byte[])obj.get(1)); sb.append(" Type: ").append(obj.get(0)).append(" Data: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } @@ -1982,10 +1934,7 @@ public String toString() while (iter.hasNext()) { obj = (List)iter.next(); - ByteArrayInputStream inStream = new ByteArrayInputStream( - (byte[])obj.get(1)); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object derObject = derInStream.readObject(); + ASN1Object derObject = ASN1Primitive.fromByteArray((byte[])obj.get(1)); sb.append(" Type: ").append(obj.get(0)).append(" Data: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } @@ -2005,11 +1954,10 @@ public String toString() *
    * TODO: implement missing tests (name constraints and path to names)
    *
    - * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, + * Uses {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, - * {@link org.bouncycastle.asn1.DERGeneralizedTime DERGeneralizedTime}, + * {@link org.bouncycastle.asn1.ASN1GeneralizedTime ASN1GeneralizedTime}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name}, * {@link org.bouncycastle.asn1.x509.X509Extensions X509Extensions}, * {@link org.bouncycastle.asn1.x509.ExtendedKeyUsage ExtendedKeyUsage}, @@ -2040,8 +1988,7 @@ public boolean match(Certificate cert) { return false; } - if (serialNumber != null - && !serialNumber.equals(certX509.getSerialNumber())) + if (serialNumber != null && !serialNumber.equals(certX509.getSerialNumber())) { return false; } @@ -2049,16 +1996,14 @@ public boolean match(Certificate cert) { if (issuerDNX509 != null) { - if (!issuerDNX509.equals(PrincipalUtil - .getIssuerX509Principal(certX509), true)) + if (!issuerDNX509.equals(PrincipalUtil.getIssuerX509Principal(certX509), true)) { return false; } } if (subjectDNX509 != null) { - if (!subjectDNX509.equals(PrincipalUtil - .getSubjectX509Principal(certX509), true)) + if (!subjectDNX509.equals(PrincipalUtil.getSubjectX509Principal(certX509), true)) { return false; } @@ -2070,19 +2015,14 @@ public boolean match(Certificate cert) } if (subjectKeyID != null) { - byte[] data = certX509 - .getExtensionValue(X509Extensions.SubjectKeyIdentifier - .getId()); + byte[] data = certX509.getExtensionValue(X509Extensions.SubjectKeyIdentifier.getId()); if (data == null) { return false; } try { - ByteArrayInputStream inStream = new ByteArrayInputStream(data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - byte[] testData = ((ASN1OctetString)derInputStream.readObject()) - .getOctets(); + byte[] testData = ASN1OctetString.getInstance(data).getOctets(); if (!Arrays.equals(subjectKeyID, testData)) { return false; @@ -2095,19 +2035,14 @@ public boolean match(Certificate cert) } if (authorityKeyID != null) { - byte[] data = certX509 - .getExtensionValue(X509Extensions.AuthorityKeyIdentifier - .getId()); + byte[] data = certX509.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (data == null) { return false; } try { - ByteArrayInputStream inStream = new ByteArrayInputStream(data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - byte[] testData = ((ASN1OctetString)derInputStream.readObject()) - .getOctets(); + byte[] testData = ASN1OctetString.getInstance(data).getOctets(); if (!Arrays.equals(authorityKeyID, testData)) { return false; @@ -2135,31 +2070,19 @@ public boolean match(Certificate cert) { try { - byte[] data = certX509 - .getExtensionValue(X509Extensions.PrivateKeyUsagePeriod - .getId()); + byte[] data = certX509.getExtensionValue(X509Extensions.PrivateKeyUsagePeriod.getId()); if (data != null) { - ByteArrayInputStream inStream = new ByteArrayInputStream( - data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - inStream = new ByteArrayInputStream( - ((ASN1OctetString)derInputStream.readObject()) - .getOctets()); - derInputStream = new ASN1InputStream(inStream); // TODO fix this, Sequence contains tagged objects - ASN1Sequence derObject = (ASN1Sequence)derInputStream - .readObject(); - ASN1GeneralizedTime derDate = DERGeneralizedTime - .getInstance(derObject.getObjectAt(0)); - SimpleDateFormat dateF = new SimpleDateFormat( - "yyyyMMddHHmmssZ"); + ASN1Sequence derObject = ASN1Sequence.getInstance( + ASN1OctetString.getInstance(data).getOctets()); + ASN1GeneralizedTime derDate = ASN1GeneralizedTime.getInstance(derObject.getObjectAt(0)); + SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssZ"); if (privateKeyValid.before(dateF.parse(derDate.getTime()))) { return false; } - derDate = DERGeneralizedTime.getInstance(derObject - .getObjectAt(1)); + derDate = ASN1GeneralizedTime.getInstance(derObject.getObjectAt(1)); if (privateKeyValid.after(dateF.parse(derDate.getTime()))) { return false; @@ -2175,7 +2098,8 @@ public boolean match(Certificate cert) { try { - SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(certX509.getPublicKey().getEncoded()); + SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance( + certX509.getPublicKey().getEncoded()); AlgorithmIdentifier algInfo = publicKeyInfo.getAlgorithmId(); if (!algInfo.getAlgorithm().equals(subjectKeyAlgID)) { @@ -2189,8 +2113,7 @@ public boolean match(Certificate cert) } if (subjectPublicKeyByte != null) { - if (!Arrays.equals(subjectPublicKeyByte, certX509.getPublicKey() - .getEncoded())) + if (!Arrays.equals(subjectPublicKeyByte, certX509.getPublicKey().getEncoded())) { return false; } @@ -2221,21 +2144,14 @@ public boolean match(Certificate cert) { try { - byte[] data = certX509 - .getExtensionValue(X509Extensions.ExtendedKeyUsage - .getId()); + byte[] data = certX509.getExtensionValue(X509Extensions.ExtendedKeyUsage.getId()); if (data != null) { - ByteArrayInputStream inStream = new ByteArrayInputStream( - data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - ExtendedKeyUsage extendedKeyUsage = ExtendedKeyUsage.getInstance( - (ASN1Sequence)derInputStream.readObject()); + ExtendedKeyUsage extendedKeyUsage = ExtendedKeyUsage.getInstance(data); tempIter = keyPurposeSet.iterator(); while (tempIter.hasNext()) { - if (!extendedKeyUsage - .hasKeyPurposeId((KeyPurposeId)tempIter.next())) + if (!extendedKeyUsage.hasKeyPurposeId((KeyPurposeId)tempIter.next())) { return false; } @@ -2263,30 +2179,21 @@ public boolean match(Certificate cert) { try { - byte[] data = certX509 - .getExtensionValue(X509Extensions.CertificatePolicies - .getId()); + byte[] data = certX509.getExtensionValue(X509Extensions.CertificatePolicies.getId()); if (data == null) { return false; } if (!policyOID.isEmpty()) { - ByteArrayInputStream inStream = new ByteArrayInputStream( - data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - inStream = new ByteArrayInputStream( - ((ASN1OctetString)derInputStream.readObject()) - .getOctets()); - derInputStream = new ASN1InputStream(inStream); - Enumeration policySequence = ((ASN1Sequence)derInputStream - .readObject()).getObjects(); + ASN1Sequence seq = ASN1Sequence.getInstance( + ASN1OctetString.getInstance(data).getOctets()); + Enumeration policySequence = seq.getObjects(); ASN1Sequence policyObject; boolean test = false; while (policySequence.hasMoreElements() && !test) { - policyObject = (ASN1Sequence)policySequence - .nextElement(); + policyObject = (ASN1Sequence)policySequence.nextElement(); if (policyOID.contains(policyObject.getObjectAt(0))) { test = true; @@ -2307,40 +2214,24 @@ public boolean match(Certificate cert) { try { - byte[] data = certX509 - .getExtensionValue(X509Extensions.SubjectAlternativeName - .getId()); + byte[] data = certX509.getExtensionValue(X509Extensions.SubjectAlternativeName.getId()); if (data == null) { return false; } - ByteArrayInputStream inStream = new ByteArrayInputStream(data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - inStream = new ByteArrayInputStream( - ((ASN1OctetString)derInputStream.readObject()) - .getOctets()); - derInputStream = new ASN1InputStream(inStream); - Enumeration altNamesSequence = ((ASN1Sequence)derInputStream - .readObject()).getObjects(); - ASN1TaggedObject altNameObject; + ASN1Sequence seq = ASN1Sequence.getInstance( + ASN1OctetString.getInstance(data).getOctets()); + Enumeration altNamesSequence = seq.getObjects(); boolean test = false; Set testSet = new HashSet(subjectAltNamesByte); - List testList; - ASN1Object derData; - ByteArrayOutputStream outStream; - ASN1OutputStream derOutStream; while (altNamesSequence.hasMoreElements() && !test) { - altNameObject = (ASN1TaggedObject)altNamesSequence - .nextElement(); - testList = new ArrayList(2); + // TODO Should this be requiring explicit tagging? + ASN1TaggedObject altNameObject = ASN1TaggedObject.getInstance(altNamesSequence.nextElement(), + BERTags.CONTEXT_SPECIFIC); + List testList = new ArrayList(2); testList.add(Integers.valueOf(altNameObject.getTagNo())); - derData = altNameObject.getObject(); - outStream = new ByteArrayOutputStream(); - derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - derOutStream.writeObject(derData); - derOutStream.close(); - testList.add(outStream.toByteArray()); + testList.add(altNameObject.getBaseObject().getEncoded(ASN1Encoding.DER)); if (testSet.remove(testList)) { @@ -2394,8 +2285,7 @@ public Object clone() } if (subjectPublicKeyByte != null) { - copy.subjectPublicKeyByte = (byte[])subjectPublicKeyByte - .clone(); + copy.subjectPublicKeyByte = (byte[])subjectPublicKeyByte.clone(); } if (keyUsage != null) { @@ -2403,22 +2293,16 @@ public Object clone() } if (keyPurposeSet != null) { - copy.keyPurposeSet = new HashSet(keyPurposeSet); + copy.keyPurposeSet = keyPurposeSet; } if (policy != null) { - copy.policy = new HashSet(policy); - copy.policyOID = new HashSet(); - Iterator iter = policyOID.iterator(); - while (iter.hasNext()) - { - copy.policyOID.add(new ASN1ObjectIdentifier( - ((ASN1ObjectIdentifier)iter.next()).getId())); - } + copy.policy = policy; + copy.policyOID = policyOID; } if (subjectAltNames != null) { - copy.subjectAltNames = new HashSet(getSubjectAlternativeNames()); + copy.subjectAltNames = getSubjectAlternativeNames(); Iterator iter = subjectAltNamesByte.iterator(); List obj; List cloneObj; @@ -2433,7 +2317,7 @@ public Object clone() } if (pathToNames != null) { - copy.pathToNames = new HashSet(getPathToNames()); + copy.pathToNames = getPathToNames(); Iterator iter = pathToNamesByte.iterator(); List obj; List cloneObj; diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/modes/EAXBlockCipher.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/modes/EAXBlockCipher.java new file mode 100644 index 0000000000..29c254d90b --- /dev/null +++ b/core/src/main/jdk1.1/org/bouncycastle/crypto/modes/EAXBlockCipher.java @@ -0,0 +1,387 @@ +package org.bouncycastle.crypto.modes; + +import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.Mac; +import org.bouncycastle.crypto.OutputLengthException; +import org.bouncycastle.crypto.macs.CMac; +import org.bouncycastle.crypto.params.AEADParameters; +import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.util.Arrays; + +/** + * A Two-Pass Authenticated-Encryption Scheme Optimized for Simplicity and + * Efficiency - by M. Bellare, P. Rogaway, D. Wagner. + * + * https://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf + * + * EAX is an AEAD scheme based on CTR and OMAC1/CMAC, that uses a single block + * cipher to encrypt and authenticate data. It's on-line (the length of a + * message isn't needed to begin processing it), has good performances, it's + * simple and provably secure (provided the underlying block cipher is secure). + * + * Of course, this implementations is NOT thread-safe. + */ +public class EAXBlockCipher + implements AEADBlockCipher +{ + private static final byte nTAG = 0x0; + + private static final byte hTAG = 0x1; + + private static final byte cTAG = 0x2; + + private CTRModeCipher cipher; + + private boolean forEncryption; + + private int blockSize; + + private Mac mac; + + private byte[] nonceMac; + private byte[] associatedTextMac; + private byte[] macBlock; + + private int macSize; + private byte[] bufBlock; + private int bufOff; + + private boolean cipherInitialized; + private byte[] initialAssociatedText; + + /** + * Constructor that accepts an instance of a block cipher engine. + * + * @param cipher the engine to use + */ + public EAXBlockCipher(BlockCipher cipher) + { + blockSize = cipher.getBlockSize(); + mac = new CMac(cipher); + macBlock = new byte[blockSize]; + associatedTextMac = new byte[mac.getMacSize()]; + nonceMac = new byte[mac.getMacSize()]; + this.cipher = SICBlockCipher.newInstance(cipher); + } + + public String getAlgorithmName() + { + return cipher.getUnderlyingCipher().getAlgorithmName() + "/EAX"; + } + + public BlockCipher getUnderlyingCipher() + { + return cipher.getUnderlyingCipher(); + } + + public int getBlockSize() + { + return cipher.getBlockSize(); + } + + public void init(boolean forEncryption, CipherParameters params) + throws IllegalArgumentException + { + this.forEncryption = forEncryption; + + byte[] nonce; + CipherParameters keyParam; + + if (params instanceof AEADParameters) + { + AEADParameters param = (AEADParameters)params; + + nonce = param.getNonce(); + initialAssociatedText = param.getAssociatedText(); + macSize = param.getMacSize() / 8; + keyParam = param.getKey(); + } + else if (params instanceof ParametersWithIV) + { + ParametersWithIV param = (ParametersWithIV)params; + + nonce = param.getIV(); + initialAssociatedText = null; + macSize = mac.getMacSize() / 2; + keyParam = param.getParameters(); + } + else + { + throw new IllegalArgumentException("invalid parameters passed to EAX"); + } + + bufBlock = new byte[forEncryption ? blockSize : (blockSize + macSize)]; + + byte[] tag = new byte[blockSize]; + + // Key reuse implemented in CBC mode of underlying CMac + mac.init(keyParam); + + tag[blockSize - 1] = nTAG; + mac.update(tag, 0, blockSize); + mac.update(nonce, 0, nonce.length); + mac.doFinal(nonceMac, 0); + + // Same BlockCipher underlies this and the mac, so reuse last key on cipher + ((BlockCipher)cipher).init(true, new ParametersWithIV(keyParam, nonceMac)); + + reset(); + } + + private void initCipher() + { + if (cipherInitialized) + { + return; + } + + cipherInitialized = true; + + mac.doFinal(associatedTextMac, 0); + + byte[] tag = new byte[blockSize]; + tag[blockSize - 1] = cTAG; + mac.update(tag, 0, blockSize); + } + + private void calculateMac() + { + byte[] outC = new byte[blockSize]; + mac.doFinal(outC, 0); + + for (int i = 0; i < macBlock.length; i++) + { + macBlock[i] = (byte)(nonceMac[i] ^ associatedTextMac[i] ^ outC[i]); + } + } + + public void reset() + { + reset(true); + } + + private void reset( + boolean clearMac) + { + ((BlockCipher)cipher).reset(); // TODO Redundant since the mac will reset it? + mac.reset(); + + bufOff = 0; + Arrays.fill(bufBlock, (byte)0); + + if (clearMac) + { + Arrays.fill(macBlock, (byte)0); + } + + byte[] tag = new byte[blockSize]; + tag[blockSize - 1] = hTAG; + mac.update(tag, 0, blockSize); + + cipherInitialized = false; + + if (initialAssociatedText != null) + { + processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); + } + } + + public void processAADByte(byte in) + { + if (cipherInitialized) + { + throw new IllegalStateException("AAD data cannot be added after encryption/decryption processing has begun."); + } + mac.update(in); + } + + public void processAADBytes(byte[] in, int inOff, int len) + { + if (cipherInitialized) + { + throw new IllegalStateException("AAD data cannot be added after encryption/decryption processing has begun."); + } + mac.update(in, inOff, len); + } + + public int processByte(byte in, byte[] out, int outOff) + throws DataLengthException + { + initCipher(); + + return process(in, out, outOff); + } + + public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) + throws DataLengthException + { + initCipher(); + + if (in.length < (inOff + len)) + { + throw new DataLengthException("Input buffer too short"); + } + + int resultLen = 0; + + for (int i = 0; i != len; i++) + { + resultLen += process(in[inOff + i], out, outOff + resultLen); + } + + return resultLen; + } + + public int doFinal(byte[] out, int outOff) + throws IllegalStateException, InvalidCipherTextException + { + initCipher(); + + int extra = bufOff; + byte[] tmp = new byte[bufBlock.length]; + + bufOff = 0; + + if (forEncryption) + { + if (out.length < (outOff + extra + macSize)) + { + throw new OutputLengthException("Output buffer too short"); + } + cipher.processBlock(bufBlock, 0, tmp, 0); + + System.arraycopy(tmp, 0, out, outOff, extra); + + mac.update(tmp, 0, extra); + + calculateMac(); + + System.arraycopy(macBlock, 0, out, outOff + extra, macSize); + + reset(false); + + return extra + macSize; + } + else + { + if (extra < macSize) + { + throw new InvalidCipherTextException("data too short"); + } + if (out.length < (outOff + extra - macSize)) + { + throw new OutputLengthException("Output buffer too short"); + } + if (extra > macSize) + { + mac.update(bufBlock, 0, extra - macSize); + + cipher.processBlock(bufBlock, 0, tmp, 0); + + System.arraycopy(tmp, 0, out, outOff, extra - macSize); + } + + calculateMac(); + + if (!verifyMac(bufBlock, extra - macSize)) + { + throw new InvalidCipherTextException("mac check in EAX failed"); + } + + reset(false); + + return extra - macSize; + } + } + + public byte[] getMac() + { + byte[] mac = new byte[macSize]; + + System.arraycopy(macBlock, 0, mac, 0, macSize); + + return mac; + } + + public int getUpdateOutputSize(int len) + { + int totalData = len + bufOff; + if (!forEncryption) + { + if (totalData < macSize) + { + return 0; + } + totalData -= macSize; + } + return totalData - totalData % blockSize; + } + + public int getOutputSize(int len) + { + int totalData = len + bufOff; + + if (forEncryption) + { + return totalData + macSize; + } + + return totalData < macSize ? 0 : totalData - macSize; + } + + private int process(byte b, byte[] out, int outOff) + { + bufBlock[bufOff++] = b; + + if (bufOff == bufBlock.length) + { + if (out.length < (outOff + blockSize)) + { + throw new OutputLengthException("Output buffer is too short"); + } + // TODO Could move the processByte(s) calls to here +// initCipher(); + + int size; + + if (forEncryption) + { + size = cipher.processBlock(bufBlock, 0, out, outOff); + + mac.update(out, outOff, blockSize); + } + else + { + mac.update(bufBlock, 0, blockSize); + + size = cipher.processBlock(bufBlock, 0, out, outOff); + } + + bufOff = 0; + if (!forEncryption) + { + System.arraycopy(bufBlock, blockSize, bufBlock, 0, macSize); + bufOff = macSize; + } + + return size; + } + + return 0; + } + + private boolean verifyMac(byte[] mac, int off) + { + int nonEqual = 0; + + for (int i = 0; i < macSize; i++) + { + nonEqual |= (macBlock[i] ^ mac[off + i]); + } + + return nonEqual == 0; + } +} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/params/RSAKeyParameters.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/params/RSAKeyParameters.java index 2df80a1bb9..e0bb18c827 100644 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/params/RSAKeyParameters.java +++ b/core/src/main/jdk1.1/org/bouncycastle/crypto/params/RSAKeyParameters.java @@ -18,8 +18,6 @@ public class RSAKeyParameters + "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f", 16); - private static final BigInteger ONE = BigInteger.valueOf(1); - private BigInteger modulus; private BigInteger exponent; @@ -52,7 +50,19 @@ public RSAKeyParameters( this.exponent = exponent; } - private BigInteger validate(BigInteger modulus, boolean isInternal) + private static boolean hasAnySmallFactors(BigInteger modulus) + { + BigInteger M = modulus, X = SMALL_PRIMES_PRODUCT; + if (modulus.compareTo(SMALL_PRIMES_PRODUCT) < 0) + { + M = SMALL_PRIMES_PRODUCT; + X = modulus; + } + + return !BigIntegers.modOddIsCoprimeVar(M, X); + } + + private static BigInteger validate(BigInteger modulus, boolean isInternal) { if (isInternal) { @@ -71,15 +81,13 @@ private BigInteger validate(BigInteger modulus, boolean isInternal) return modulus; } - int maxBitLength = Properties.asInteger("org.bouncycastle.rsa.max_size", 15360); - - int modBitLength = modulus.bitLength(); - if (maxBitLength < modBitLength) + int maxBitLength = Properties.asInteger("org.bouncycastle.rsa.max_size", 16384); + if (maxBitLength < modulus.bitLength()) { - throw new IllegalArgumentException("modulus value out of range"); + throw new IllegalArgumentException("RSA modulus out of range"); } - if (!modulus.gcd(SMALL_PRIMES_PRODUCT).equals(ONE)) + if (hasAnySmallFactors(modulus)) { throw new IllegalArgumentException("RSA modulus has a small prime factor"); } @@ -90,7 +98,8 @@ private BigInteger validate(BigInteger modulus, boolean isInternal) : bits >= 512 ? 7 : 50; - Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, CryptoServicesRegistrar.getSecureRandom(), iterations); + Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, CryptoServicesRegistrar.getSecureRandom(), + iterations); if (!mr.isProvablyComposite()) { throw new IllegalArgumentException("RSA modulus is not composite"); diff --git a/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java new file mode 100644 index 0000000000..2048a892fe --- /dev/null +++ b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java @@ -0,0 +1,242 @@ +package org.bouncycastle.pqc.crypto.util; + +import java.io.IOException; +import java.io.InputStream; + +import org.bouncycastle.asn1.ASN1BitString; +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.pqc.asn1.CMCEPrivateKey; +import org.bouncycastle.pqc.asn1.FalconPrivateKey; +import org.bouncycastle.pqc.asn1.McElieceCCA2PrivateKey; +import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; +import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; +import org.bouncycastle.pqc.crypto.bike.BIKEParameters; +import org.bouncycastle.pqc.crypto.bike.BIKEPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.newhope.NHPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.saber.SABERParameters; +import org.bouncycastle.pqc.crypto.saber.SABERPrivateKeyParameters; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Pack; + +/** + * Factory for creating private key objects from PKCS8 PrivateKeyInfo objects. + */ +public class PrivateKeyFactory +{ + /** + * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding. + * + * @param privateKeyInfoData the PrivateKeyInfo encoding + * @return a suitable private key parameter + * @throws IOException on an error decoding the key + */ + public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData) + throws IOException + { + if (privateKeyInfoData == null) + { + throw new IllegalArgumentException("privateKeyInfoData array null"); + } + if (privateKeyInfoData.length == 0) + { + throw new IllegalArgumentException("privateKeyInfoData array empty"); + } + return createKey(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(privateKeyInfoData))); + } + + /** + * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding read from a + * stream. + * + * @param inStr the stream to read the PrivateKeyInfo encoding from + * @return a suitable private key parameter + * @throws IOException on an error decoding the key + */ + public static AsymmetricKeyParameter createKey(InputStream inStr) + throws IOException + { + return createKey(PrivateKeyInfo.getInstance(new ASN1InputStream(inStr).readObject())); + } + + /** + * Create a private key parameter from the passed in PKCS8 PrivateKeyInfo object. + * + * @param keyInfo the PrivateKeyInfo object containing the key material + * @return a suitable private key parameter + * @throws IOException on an error decoding the key + */ + public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo) + throws IOException + { + if (keyInfo == null) + { + throw new IllegalArgumentException("keyInfo array null"); + } + + AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm(); + ASN1ObjectIdentifier algOID = algId.getAlgorithm(); + + if (algOID.equals(PQCObjectIdentifiers.newHope)) + { + return new NHPrivateKeyParameters(convert(ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets())); + } + else if (algOID.on(BCObjectIdentifiers.picnic)) + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); + PicnicParameters pParams = Utils.picnicParamsLookup(algOID); + + return new PicnicPrivateKeyParameters(pParams, keyEnc); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_mceliece)) + { + CMCEPrivateKey cmceKey = CMCEPrivateKey.getInstance(keyInfo.parsePrivateKey()); + CMCEParameters spParams = Utils.mcElieceParamsLookup(algOID); + + return new CMCEPrivateKeyParameters(spParams, cmceKey.getDelta(), cmceKey.getC(), cmceKey.getG(), cmceKey.getAlpha(), cmceKey.getS()); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_frodo)) + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); + FrodoParameters spParams = Utils.frodoParamsLookup(algOID); + + return new FrodoPrivateKeyParameters(spParams, keyEnc); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_saber)) + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); + SABERParameters spParams = Utils.saberParamsLookup(algOID); + + return new SABERPrivateKeyParameters(spParams, keyEnc); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_kyber)) + { + ASN1OctetString kyberKey = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()); + KyberParameters kyberParams = Utils.kyberParamsLookup(algOID); + + return new KyberPrivateKeyParameters(kyberParams, kyberKey.getOctets()); + } + else if (algOID.equals(BCObjectIdentifiers.dilithium2) + || algOID.equals(BCObjectIdentifiers.dilithium3) || algOID.equals(BCObjectIdentifiers.dilithium5)) + { + ASN1Encodable keyObj = keyInfo.parsePrivateKey(); + DilithiumParameters spParams = Utils.dilithiumParamsLookup(algOID); + + if (keyObj instanceof ASN1Sequence) + { + ASN1Sequence keyEnc = ASN1Sequence.getInstance(keyObj); + + int version = ASN1Integer.getInstance(keyEnc.getObjectAt(0)).intValueExact(); + if (version != 0) + { + throw new IOException("unknown private key version: " + version); + } + + if (keyInfo.getPublicKeyData() != null) + { + DilithiumPublicKeyParameters pubParams = PublicKeyFactory.DilithiumConverter.getPublicKeyParams(spParams, keyInfo.getPublicKeyData()); + + return new DilithiumPrivateKeyParameters(spParams, + ASN1BitString.getInstance(keyEnc.getObjectAt(1)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(2)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(3)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(4)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(5)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(6)).getOctets(), + pubParams.getT1()); // encT1 + } + else + { + return new DilithiumPrivateKeyParameters(spParams, + ASN1BitString.getInstance(keyEnc.getObjectAt(1)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(2)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(3)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(4)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(5)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(6)).getOctets(), + null); + } + } + else if (keyObj instanceof DEROctetString) + { + byte[] data = ASN1OctetString.getInstance(keyObj).getOctets(); + if (keyInfo.getPublicKeyData() != null) + { + DilithiumPublicKeyParameters pubParams = PublicKeyFactory.DilithiumConverter.getPublicKeyParams(spParams, keyInfo.getPublicKeyData()); + return new DilithiumPrivateKeyParameters(spParams, data, pubParams); + } + return new DilithiumPrivateKeyParameters(spParams, data, null); + } + else + { + throw new IOException("not supported"); + } + } + else if (algOID.equals(BCObjectIdentifiers.falcon_512) || algOID.equals(BCObjectIdentifiers.falcon_1024)) + { + FalconPrivateKey falconKey = FalconPrivateKey.getInstance(keyInfo.parsePrivateKey()); + FalconParameters falconParams = Utils.falconParamsLookup(algOID); + + return new FalconPrivateKeyParameters(falconParams, falconKey.getf(), falconKey.getG(), falconKey.getF(), falconKey.getPublicKey().getH()); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_bike)) + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); + BIKEParameters bikeParams = Utils.bikeParamsLookup(algOID); + + byte[] h0 = Arrays.copyOfRange(keyEnc, 0, bikeParams.getRByte()); + byte[] h1 = Arrays.copyOfRange(keyEnc, bikeParams.getRByte(), 2 * bikeParams.getRByte()); + byte[] sigma = Arrays.copyOfRange(keyEnc, 2 * bikeParams.getRByte(), keyEnc.length); + return new BIKEPrivateKeyParameters(bikeParams, h0, h1, sigma); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_hqc)) + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); + HQCParameters hqcParams = Utils.hqcParamsLookup(algOID); + + return new HQCPrivateKeyParameters(hqcParams, keyEnc); + } + else + { + throw new RuntimeException("algorithm identifier in private key not recognised"); + } + } + + private static short[] convert(byte[] octets) + { + short[] rv = new short[octets.length / 2]; + + for (int i = 0; i != rv.length; i++) + { + rv[i] = Pack.littleEndianToShort(octets, i * 2); + } + + return rv; + } +} diff --git a/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java new file mode 100644 index 0000000000..b566feed92 --- /dev/null +++ b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java @@ -0,0 +1,170 @@ +package org.bouncycastle.pqc.crypto.util; + +import java.io.IOException; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.pqc.asn1.CMCEPrivateKey; +import org.bouncycastle.pqc.asn1.CMCEPublicKey; +import org.bouncycastle.pqc.asn1.FalconPrivateKey; +import org.bouncycastle.pqc.asn1.FalconPublicKey; +import org.bouncycastle.pqc.asn1.McElieceCCA2PrivateKey; +import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; +import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; +import org.bouncycastle.pqc.crypto.bike.BIKEPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.newhope.NHPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.saber.SABERPrivateKeyParameters; +import org.bouncycastle.util.Pack; + +/** + * Factory to create ASN.1 private key info objects from lightweight private keys. + */ +public class PrivateKeyInfoFactory +{ + private PrivateKeyInfoFactory() + { + } + + /** + * Create a PrivateKeyInfo representation of a private key. + * + * @param privateKey the key to be encoded into the info object. + * @return the appropriate PrivateKeyInfo + * @throws java.io.IOException on an error encoding the key + */ + public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter privateKey) throws IOException + { + return createPrivateKeyInfo(privateKey, null); + } + + /** + * Create a PrivateKeyInfo representation of a private key with attributes. + * + * @param privateKey the key to be encoded into the info object. + * @param attributes the set of attributes to be included. + * @return the appropriate PrivateKeyInfo + * @throws java.io.IOException on an error encoding the key + */ + public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter privateKey, ASN1Set attributes) throws IOException + { + if (privateKey instanceof NHPrivateKeyParameters) + { + NHPrivateKeyParameters params = (NHPrivateKeyParameters)privateKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.newHope); + + short[] privateKeyData = params.getSecData(); + + byte[] octets = new byte[privateKeyData.length * 2]; + for (int i = 0; i != privateKeyData.length; i++) + { + Pack.shortToLittleEndian(privateKeyData[i], octets, i * 2); + } + + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(octets)); + } + else if (privateKey instanceof PicnicPrivateKeyParameters) + { + PicnicPrivateKeyParameters params = (PicnicPrivateKeyParameters)privateKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.picnicOidLookup(params.getParameters())); + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); + } + else if (privateKey instanceof CMCEPrivateKeyParameters) + { + CMCEPrivateKeyParameters params = (CMCEPrivateKeyParameters)privateKey; + + //todo either make CMCEPrivateKey split the parameters from the private key or + // (current) Make CMCEPrivateKey take parts of the private key splitted in the params + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.mcElieceOidLookup(params.getParameters())); + + CMCEPublicKey cmcePub = new CMCEPublicKey(params.reconstructPublicKey()); + CMCEPrivateKey cmcePriv = new CMCEPrivateKey(0, params.getDelta(), params.getC(), params.getG(), params.getAlpha(), params.getS(), cmcePub); + return new PrivateKeyInfo(algorithmIdentifier, cmcePriv, attributes); + } + else if (privateKey instanceof FrodoPrivateKeyParameters) + { + FrodoPrivateKeyParameters params = (FrodoPrivateKeyParameters)privateKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.frodoOidLookup(params.getParameters())); + + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); + } + else if (privateKey instanceof SABERPrivateKeyParameters) + { + SABERPrivateKeyParameters params = (SABERPrivateKeyParameters)privateKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.saberOidLookup(params.getParameters())); + + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); + } + else if (privateKey instanceof FalconPrivateKeyParameters) + { + FalconPrivateKeyParameters params = (FalconPrivateKeyParameters)privateKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.falconOidLookup(params.getParameters())); + + FalconPublicKey falconPub = new FalconPublicKey(params.getPublicKey()); + FalconPrivateKey falconPriv = new FalconPrivateKey(0, params.getSpolyf(), params.getG(), params.getSpolyF(), falconPub); + + return new PrivateKeyInfo(algorithmIdentifier, falconPriv, attributes); + } + else if (privateKey instanceof KyberPrivateKeyParameters) + { + KyberPrivateKeyParameters params = (KyberPrivateKeyParameters)privateKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.kyberOidLookup(params.getParameters())); + + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getEncoded()), attributes); + } + else if (privateKey instanceof DilithiumPrivateKeyParameters) + { + DilithiumPrivateKeyParameters params = (DilithiumPrivateKeyParameters)privateKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.dilithiumOidLookup(params.getParameters())); + + DilithiumPublicKeyParameters pubParams = params.getPublicKeyParameters(); + + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getEncoded()), attributes, pubParams.getEncoded()); + } + else if (privateKey instanceof BIKEPrivateKeyParameters) + { + BIKEPrivateKeyParameters params = (BIKEPrivateKeyParameters)privateKey; + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.bikeOidLookup(params.getParameters())); + byte[] encoding = params.getEncoded(); + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); + } + else if (privateKey instanceof HQCPrivateKeyParameters) + { + HQCPrivateKeyParameters params = (HQCPrivateKeyParameters)privateKey; + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.hqcOidLookup(params.getParameters())); + byte[] encoding = params.getEncoded(); + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); + } + else + { + throw new IOException("key parameters not recognized"); + } + } +} diff --git a/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java new file mode 100644 index 0000000000..9038e7d748 --- /dev/null +++ b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java @@ -0,0 +1,420 @@ +package org.bouncycastle.pqc.crypto.util; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import org.bouncycastle.asn1.ASN1BitString; +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.internal.asn1.isara.IsaraObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.pqc.asn1.CMCEPublicKey; +import org.bouncycastle.pqc.asn1.KyberPublicKey; +import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; +import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; +import org.bouncycastle.pqc.crypto.bike.BIKEParameters; +import org.bouncycastle.pqc.crypto.bike.BIKEPublicKeyParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEPublicKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberPublicKeyParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconPublicKeyParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoPublicKeyParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCPublicKeyParameters; +import org.bouncycastle.pqc.crypto.newhope.NHPublicKeyParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicPublicKeyParameters; +import org.bouncycastle.pqc.crypto.saber.SABERParameters; +import org.bouncycastle.pqc.crypto.saber.SABERPublicKeyParameters; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Pack; + +/** + * Factory to create asymmetric public key parameters for asymmetric ciphers from range of + * ASN.1 encoded SubjectPublicKeyInfo objects. + */ +public class PublicKeyFactory +{ + private static Map converters = new HashMap(); + + static + { + converters.put(PQCObjectIdentifiers.newHope, new NHConverter()); + + + + converters.put(BCObjectIdentifiers.mceliece348864_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece348864f_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece460896_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece460896f_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece6688128_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece6688128f_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece6960119_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece6960119f_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece8192128_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece8192128f_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.frodokem640aes, new FrodoConverter()); + converters.put(BCObjectIdentifiers.frodokem640shake, new FrodoConverter()); + converters.put(BCObjectIdentifiers.frodokem976aes, new FrodoConverter()); + converters.put(BCObjectIdentifiers.frodokem976shake, new FrodoConverter()); + converters.put(BCObjectIdentifiers.frodokem1344aes, new FrodoConverter()); + converters.put(BCObjectIdentifiers.frodokem1344shake, new FrodoConverter()); + converters.put(BCObjectIdentifiers.lightsaberkem128r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.saberkem128r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.firesaberkem128r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.lightsaberkem192r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.saberkem192r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.firesaberkem192r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.lightsaberkem256r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.saberkem256r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.firesaberkem256r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.ulightsaberkemr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.usaberkemr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.ufiresaberkemr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.lightsaberkem90sr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.saberkem90sr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.firesaberkem90sr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.ulightsaberkem90sr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.usaberkem90sr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.ufiresaberkem90sr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.picnicl1fs, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl1ur, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl3fs, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl3ur, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl5fs, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl5ur, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnic3l1, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnic3l3, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnic3l5, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl1full, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl3full, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl5full, new PicnicConverter()); + converters.put(BCObjectIdentifiers.falcon_512, new FalconConverter()); + converters.put(BCObjectIdentifiers.falcon_1024, new FalconConverter()); + converters.put(BCObjectIdentifiers.kyber512, new KyberConverter()); + converters.put(BCObjectIdentifiers.kyber768, new KyberConverter()); + converters.put(BCObjectIdentifiers.kyber1024, new KyberConverter()); + converters.put(BCObjectIdentifiers.kyber512_aes, new KyberConverter()); + converters.put(BCObjectIdentifiers.kyber768_aes, new KyberConverter()); + converters.put(BCObjectIdentifiers.kyber1024_aes, new KyberConverter()); + converters.put(BCObjectIdentifiers.dilithium2, new DilithiumConverter()); + converters.put(BCObjectIdentifiers.dilithium3, new DilithiumConverter()); + converters.put(BCObjectIdentifiers.dilithium5, new DilithiumConverter()); + converters.put(BCObjectIdentifiers.dilithium2_aes, new DilithiumConverter()); + converters.put(BCObjectIdentifiers.dilithium3_aes, new DilithiumConverter()); + converters.put(BCObjectIdentifiers.dilithium5_aes, new DilithiumConverter()); + converters.put(BCObjectIdentifiers.bike128, new BIKEConverter()); + converters.put(BCObjectIdentifiers.bike192, new BIKEConverter()); + converters.put(BCObjectIdentifiers.bike256, new BIKEConverter()); + converters.put(BCObjectIdentifiers.hqc128, new HQCConverter()); + converters.put(BCObjectIdentifiers.hqc192, new HQCConverter()); + converters.put(BCObjectIdentifiers.hqc256, new HQCConverter()); + } + + /** + * Create a public key from a SubjectPublicKeyInfo encoding + * + * @param keyInfoData the SubjectPublicKeyInfo encoding + * @return the appropriate key parameter + * @throws IOException on an error decoding the key + */ + public static AsymmetricKeyParameter createKey(byte[] keyInfoData) + throws IOException + { + if (keyInfoData == null) + { + throw new IllegalArgumentException("keyInfoData array null"); + } + if (keyInfoData.length == 0) + { + throw new IllegalArgumentException("keyInfoData array empty"); + } + return createKey(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(keyInfoData))); + } + + /** + * Create a public key from a SubjectPublicKeyInfo encoding read from a stream + * + * @param inStr the stream to read the SubjectPublicKeyInfo encoding from + * @return the appropriate key parameter + * @throws IOException on an error decoding the key + */ + public static AsymmetricKeyParameter createKey(InputStream inStr) + throws IOException + { + return createKey(SubjectPublicKeyInfo.getInstance(new ASN1InputStream(inStr).readObject())); + } + + /** + * Create a public key from the passed in SubjectPublicKeyInfo + * + * @param keyInfo the SubjectPublicKeyInfo containing the key data + * @return the appropriate key parameter + * @throws IOException on an error decoding the key + */ + public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo) + throws IOException + { + if (keyInfo == null) + { + throw new IllegalArgumentException("keyInfo argument null"); + } + return createKey(keyInfo, null); + } + + /** + * Create a public key from the passed in SubjectPublicKeyInfo + * + * @param keyInfo the SubjectPublicKeyInfo containing the key data + * @param defaultParams default parameters that might be needed. + * @return the appropriate key parameter + * @throws IOException on an error decoding the key + */ + public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + if (keyInfo == null) + { + throw new IllegalArgumentException("keyInfo argument null"); + } + + AlgorithmIdentifier algId = keyInfo.getAlgorithm(); + SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)converters.get(algId.getAlgorithm()); + + if (converter != null) + { + return converter.getPublicKeyParameters(keyInfo, defaultParams); + } + else + { + throw new IOException("algorithm identifier in public key not recognised: " + algId.getAlgorithm()); + } + } + + private static abstract class SubjectPublicKeyInfoConverter + { + abstract AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException; + } + + private static class NHConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + return new NHPublicKeyParameters(keyInfo.getPublicKeyData().getBytes()); + } + } + + private static class CMCEConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + try + { + byte[] keyEnc = CMCEPublicKey.getInstance(keyInfo.parsePublicKey()).getT(); + + CMCEParameters spParams = Utils.mcElieceParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new CMCEPublicKeyParameters(spParams, keyEnc); + } + catch (Exception e) + { + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); + + CMCEParameters spParams = Utils.mcElieceParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new CMCEPublicKeyParameters(spParams, keyEnc); + } + } + } + + private static class SABERConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + byte[] keyEnc = ASN1OctetString.getInstance( + ASN1Sequence.getInstance(keyInfo.parsePublicKey()).getObjectAt(0)).getOctets(); + + SABERParameters saberParams = Utils.saberParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new SABERPublicKeyParameters(saberParams, keyEnc); + } + } + + private static class FrodoConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + FrodoParameters fParams = Utils.frodoParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new FrodoPublicKeyParameters(fParams, keyEnc); + } + } + + private static class PicnicConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + PicnicParameters picnicParams = Utils.picnicParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new PicnicPublicKeyParameters(picnicParams, keyEnc); + } + } + + private static class FalconConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); +// FalconPublicKey falconPublicKey = FalconPublicKey.getInstance(keyInfo.parsePublicKey()); + + FalconParameters falconParams = Utils.falconParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new FalconPublicKeyParameters(falconParams, Arrays.copyOfRange(keyEnc, 1, keyEnc.length)); + + } + } + + private static class KyberConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + KyberParameters kyberParameters = Utils.kyberParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + try + { + ASN1Primitive obj = keyInfo.parsePublicKey(); + KyberPublicKey kyberKey = KyberPublicKey.getInstance(obj); + + return new KyberPublicKeyParameters(kyberParameters, kyberKey.getT(), kyberKey.getRho()); + } + catch (Exception e) + { + // we're a raw encoding + return new KyberPublicKeyParameters(kyberParameters, keyInfo.getPublicKeyData().getOctets()); + } + } + } + + static class DilithiumConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + DilithiumParameters dilithiumParams = Utils.dilithiumParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return getPublicKeyParams(dilithiumParams, keyInfo.getPublicKeyData()); + } + + static DilithiumPublicKeyParameters getPublicKeyParams(DilithiumParameters dilithiumParams, ASN1BitString publicKeyData) + { + try + { + ASN1Primitive obj = ASN1Primitive.fromByteArray(publicKeyData.getOctets()); + if (obj instanceof ASN1Sequence) + { + ASN1Sequence keySeq = ASN1Sequence.getInstance(obj); + + return new DilithiumPublicKeyParameters(dilithiumParams, + ASN1OctetString.getInstance(keySeq.getObjectAt(0)).getOctets(), + ASN1OctetString.getInstance(keySeq.getObjectAt(1)).getOctets()); + } + else + { + byte[] encKey = ASN1OctetString.getInstance(obj).getOctets(); + + return new DilithiumPublicKeyParameters(dilithiumParams, encKey); + } + } + catch (Exception e) + { + // we're a raw encoding + return new DilithiumPublicKeyParameters(dilithiumParams, publicKeyData.getOctets()); + } + } + } + + private static class BIKEConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + try + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + BIKEParameters bikeParams = Utils.bikeParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new BIKEPublicKeyParameters(bikeParams, keyEnc); + } + catch (Exception e) + { + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); + + BIKEParameters bikeParams = Utils.bikeParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new BIKEPublicKeyParameters(bikeParams, keyEnc); + } + } + } + + private static class HQCConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + try + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + HQCParameters hqcParams = Utils.hqcParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new HQCPublicKeyParameters(hqcParams, keyEnc); + } + catch (Exception e) + { + // raw encoding + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); + + HQCParameters hqcParams = Utils.hqcParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new HQCPublicKeyParameters(hqcParams, keyEnc); + } + } + } +} diff --git a/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java new file mode 100644 index 0000000000..bd3dc8a39e --- /dev/null +++ b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java @@ -0,0 +1,145 @@ +package org.bouncycastle.pqc.crypto.util; + +import java.io.IOException; + +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.internal.asn1.isara.IsaraObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; +import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; +import org.bouncycastle.pqc.crypto.bike.BIKEPublicKeyParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEPublicKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberPublicKeyParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconPublicKeyParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoPublicKeyParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCPublicKeyParameters; +import org.bouncycastle.pqc.crypto.newhope.NHPublicKeyParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicPublicKeyParameters; +import org.bouncycastle.pqc.crypto.saber.SABERPublicKeyParameters; + +/** + * Factory to create ASN.1 subject public key info objects from lightweight public keys. + */ +public class SubjectPublicKeyInfoFactory +{ + private SubjectPublicKeyInfoFactory() + { + + } + + /** + * Create a SubjectPublicKeyInfo public key. + * + * @param publicKey the key to be encoded into the info object. + * @return a SubjectPublicKeyInfo representing the key. + * @throws java.io.IOException on an error encoding the key + */ + public static SubjectPublicKeyInfo createSubjectPublicKeyInfo(AsymmetricKeyParameter publicKey) + throws IOException + { + if (publicKey instanceof NHPublicKeyParameters) + { + NHPublicKeyParameters params = (NHPublicKeyParameters)publicKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.newHope); + return new SubjectPublicKeyInfo(algorithmIdentifier, params.getPubData()); + } + else if (publicKey instanceof CMCEPublicKeyParameters) + { + CMCEPublicKeyParameters params = (CMCEPublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.mcElieceOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, encoding); + } + else if (publicKey instanceof FrodoPublicKeyParameters) + { + FrodoPublicKeyParameters params = (FrodoPublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.frodoOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); + } + else if (publicKey instanceof SABERPublicKeyParameters) + { + SABERPublicKeyParameters params = (SABERPublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.saberOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, new DERSequence(new DEROctetString(encoding))); + } + else if (publicKey instanceof PicnicPublicKeyParameters) + { + PicnicPublicKeyParameters params = (PicnicPublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.picnicOidLookup(params.getParameters())); + return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); + } + else if (publicKey instanceof FalconPublicKeyParameters) + { + FalconPublicKeyParameters params = (FalconPublicKeyParameters)publicKey; + + byte[] encoding = params.getH(); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.falconOidLookup(params.getParameters())); + + byte[] keyEnc = new byte[encoding.length + 1]; + keyEnc[0] = (byte)(0x00 + params.getParameters().getLogN()); + System.arraycopy(encoding, 0, keyEnc, 1, encoding.length); + + return new SubjectPublicKeyInfo(algorithmIdentifier, keyEnc); + } + else if (publicKey instanceof KyberPublicKeyParameters) + { + KyberPublicKeyParameters params = (KyberPublicKeyParameters)publicKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.kyberOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, params.getEncoded()); + } + else if (publicKey instanceof DilithiumPublicKeyParameters) + { + DilithiumPublicKeyParameters params = (DilithiumPublicKeyParameters)publicKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.dilithiumOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, params.getEncoded()); + } + else if (publicKey instanceof BIKEPublicKeyParameters) + { + BIKEPublicKeyParameters params = (BIKEPublicKeyParameters) publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.bikeOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, encoding); + } + else if (publicKey instanceof HQCPublicKeyParameters) + { + HQCPublicKeyParameters params = (HQCPublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.hqcOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, encoding); + } + else + { + throw new IOException("key parameters not recognized"); + } + } +} diff --git a/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/Utils.java b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/Utils.java new file mode 100644 index 0000000000..e390edf385 --- /dev/null +++ b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/Utils.java @@ -0,0 +1,397 @@ +package org.bouncycastle.pqc.crypto.util; + +import java.util.HashMap; +import java.util.Map; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.digests.SHA512Digest; +import org.bouncycastle.crypto.digests.SHAKEDigest; +import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; +import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; +import org.bouncycastle.pqc.crypto.bike.BIKEParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicParameters; +import org.bouncycastle.pqc.crypto.saber.SABERParameters; +import org.bouncycastle.util.Integers; + +class Utils +{ + static final AlgorithmIdentifier SPHINCS_SHA3_256 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_256); + static final AlgorithmIdentifier SPHINCS_SHA512_256 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512_256); + + static final Map categories = new HashMap(); + + static final Map picnicOids = new HashMap(); + static final Map picnicParams = new HashMap(); + + static final Map frodoOids = new HashMap(); + static final Map frodoParams = new HashMap(); + + static final Map saberOids = new HashMap(); + static final Map saberParams = new HashMap(); + + static final Map mcElieceOids = new HashMap(); + static final Map mcElieceParams = new HashMap(); + + static final Map sphincsPlusOids = new HashMap(); + static final Map sphincsPlusParams = new HashMap(); + + static final Map sikeOids = new HashMap(); + static final Map sikeParams = new HashMap(); + + static final Map ntruOids = new HashMap(); + static final Map ntruParams = new HashMap(); + + static final Map falconOids = new HashMap(); + static final Map falconParams = new HashMap(); + + static final Map kyberOids = new HashMap(); + static final Map kyberParams = new HashMap(); + + static final Map ntruprimeOids = new HashMap(); + static final Map ntruprimeParams = new HashMap(); + + static final Map sntruprimeOids = new HashMap(); + static final Map sntruprimeParams = new HashMap(); + + static final Map dilithiumOids = new HashMap(); + static final Map dilithiumParams = new HashMap(); + + static final Map bikeOids = new HashMap(); + static final Map bikeParams = new HashMap(); + + static final Map hqcOids = new HashMap(); + static final Map hqcParams = new HashMap(); + + static final Map rainbowOids = new HashMap(); + static final Map rainbowParams = new HashMap(); + + static + { + mcElieceOids.put(CMCEParameters.mceliece348864r3, BCObjectIdentifiers.mceliece348864_r3); + mcElieceOids.put(CMCEParameters.mceliece348864fr3, BCObjectIdentifiers.mceliece348864f_r3); + mcElieceOids.put(CMCEParameters.mceliece460896r3, BCObjectIdentifiers.mceliece460896_r3); + mcElieceOids.put(CMCEParameters.mceliece460896fr3, BCObjectIdentifiers.mceliece460896f_r3); + mcElieceOids.put(CMCEParameters.mceliece6688128r3, BCObjectIdentifiers.mceliece6688128_r3); + mcElieceOids.put(CMCEParameters.mceliece6688128fr3, BCObjectIdentifiers.mceliece6688128f_r3); + mcElieceOids.put(CMCEParameters.mceliece6960119r3, BCObjectIdentifiers.mceliece6960119_r3); + mcElieceOids.put(CMCEParameters.mceliece6960119fr3, BCObjectIdentifiers.mceliece6960119f_r3); + mcElieceOids.put(CMCEParameters.mceliece8192128r3, BCObjectIdentifiers.mceliece8192128_r3); + mcElieceOids.put(CMCEParameters.mceliece8192128fr3, BCObjectIdentifiers.mceliece8192128f_r3); + + mcElieceParams.put(BCObjectIdentifiers.mceliece348864_r3, CMCEParameters.mceliece348864r3); + mcElieceParams.put(BCObjectIdentifiers.mceliece348864f_r3, CMCEParameters.mceliece348864fr3); + mcElieceParams.put(BCObjectIdentifiers.mceliece460896_r3, CMCEParameters.mceliece460896r3); + mcElieceParams.put(BCObjectIdentifiers.mceliece460896f_r3, CMCEParameters.mceliece460896fr3); + mcElieceParams.put(BCObjectIdentifiers.mceliece6688128_r3, CMCEParameters.mceliece6688128r3); + mcElieceParams.put(BCObjectIdentifiers.mceliece6688128f_r3, CMCEParameters.mceliece6688128fr3); + mcElieceParams.put(BCObjectIdentifiers.mceliece6960119_r3, CMCEParameters.mceliece6960119r3); + mcElieceParams.put(BCObjectIdentifiers.mceliece6960119f_r3, CMCEParameters.mceliece6960119fr3); + mcElieceParams.put(BCObjectIdentifiers.mceliece8192128_r3, CMCEParameters.mceliece8192128r3); + mcElieceParams.put(BCObjectIdentifiers.mceliece8192128f_r3, CMCEParameters.mceliece8192128fr3); + + frodoOids.put(FrodoParameters.frodokem640aes, BCObjectIdentifiers.frodokem640aes); + frodoOids.put(FrodoParameters.frodokem640shake, BCObjectIdentifiers.frodokem640shake); + frodoOids.put(FrodoParameters.frodokem976aes, BCObjectIdentifiers.frodokem976aes); + frodoOids.put(FrodoParameters.frodokem976shake, BCObjectIdentifiers.frodokem976shake); + frodoOids.put(FrodoParameters.frodokem1344aes, BCObjectIdentifiers.frodokem1344aes); + frodoOids.put(FrodoParameters.frodokem1344shake, BCObjectIdentifiers.frodokem1344shake); + + frodoParams.put(BCObjectIdentifiers.frodokem640aes, FrodoParameters.frodokem640aes); + frodoParams.put(BCObjectIdentifiers.frodokem640shake, FrodoParameters.frodokem640shake); + frodoParams.put(BCObjectIdentifiers.frodokem976aes, FrodoParameters.frodokem976aes); + frodoParams.put(BCObjectIdentifiers.frodokem976shake, FrodoParameters.frodokem976shake); + frodoParams.put(BCObjectIdentifiers.frodokem1344aes, FrodoParameters.frodokem1344aes); + frodoParams.put(BCObjectIdentifiers.frodokem1344shake, FrodoParameters.frodokem1344shake); + + saberOids.put(SABERParameters.lightsaberkem128r3, BCObjectIdentifiers.lightsaberkem128r3); + saberOids.put(SABERParameters.saberkem128r3, BCObjectIdentifiers.saberkem128r3); + saberOids.put(SABERParameters.firesaberkem128r3, BCObjectIdentifiers.firesaberkem128r3); + saberOids.put(SABERParameters.lightsaberkem192r3, BCObjectIdentifiers.lightsaberkem192r3); + saberOids.put(SABERParameters.saberkem192r3, BCObjectIdentifiers.saberkem192r3); + saberOids.put(SABERParameters.firesaberkem192r3, BCObjectIdentifiers.firesaberkem192r3); + saberOids.put(SABERParameters.lightsaberkem256r3, BCObjectIdentifiers.lightsaberkem256r3); + saberOids.put(SABERParameters.saberkem256r3, BCObjectIdentifiers.saberkem256r3); + saberOids.put(SABERParameters.firesaberkem256r3, BCObjectIdentifiers.firesaberkem256r3); + saberOids.put(SABERParameters.ulightsaberkemr3, BCObjectIdentifiers.ulightsaberkemr3); + saberOids.put(SABERParameters.usaberkemr3, BCObjectIdentifiers.usaberkemr3); + saberOids.put(SABERParameters.ufiresaberkemr3, BCObjectIdentifiers.ufiresaberkemr3); + saberOids.put(SABERParameters.lightsaberkem90sr3, BCObjectIdentifiers.lightsaberkem90sr3); + saberOids.put(SABERParameters.saberkem90sr3, BCObjectIdentifiers.saberkem90sr3); + saberOids.put(SABERParameters.firesaberkem90sr3, BCObjectIdentifiers.firesaberkem90sr3); + saberOids.put(SABERParameters.ulightsaberkem90sr3, BCObjectIdentifiers.ulightsaberkem90sr3); + saberOids.put(SABERParameters.usaberkem90sr3, BCObjectIdentifiers.usaberkem90sr3); + saberOids.put(SABERParameters.ufiresaberkem90sr3, BCObjectIdentifiers.ufiresaberkem90sr3); + + saberParams.put(BCObjectIdentifiers.lightsaberkem128r3, SABERParameters.lightsaberkem128r3); + saberParams.put(BCObjectIdentifiers.saberkem128r3, SABERParameters.saberkem128r3); + saberParams.put(BCObjectIdentifiers.firesaberkem128r3, SABERParameters.firesaberkem128r3); + saberParams.put(BCObjectIdentifiers.lightsaberkem192r3, SABERParameters.lightsaberkem192r3); + saberParams.put(BCObjectIdentifiers.saberkem192r3, SABERParameters.saberkem192r3); + saberParams.put(BCObjectIdentifiers.firesaberkem192r3, SABERParameters.firesaberkem192r3); + saberParams.put(BCObjectIdentifiers.lightsaberkem256r3, SABERParameters.lightsaberkem256r3); + saberParams.put(BCObjectIdentifiers.saberkem256r3, SABERParameters.saberkem256r3); + saberParams.put(BCObjectIdentifiers.firesaberkem256r3, SABERParameters.firesaberkem256r3); + saberParams.put(BCObjectIdentifiers.ulightsaberkemr3, SABERParameters.ulightsaberkemr3); + saberParams.put(BCObjectIdentifiers.usaberkemr3, SABERParameters.usaberkemr3); + saberParams.put(BCObjectIdentifiers.ufiresaberkemr3, SABERParameters.ufiresaberkemr3); + saberParams.put(BCObjectIdentifiers.lightsaberkem90sr3, SABERParameters.lightsaberkem90sr3); + saberParams.put(BCObjectIdentifiers.saberkem90sr3, SABERParameters.saberkem90sr3); + saberParams.put(BCObjectIdentifiers.firesaberkem90sr3, SABERParameters.firesaberkem90sr3); + saberParams.put(BCObjectIdentifiers.ulightsaberkem90sr3, SABERParameters.ulightsaberkem90sr3); + saberParams.put(BCObjectIdentifiers.usaberkem90sr3, SABERParameters.usaberkem90sr3); + saberParams.put(BCObjectIdentifiers.ufiresaberkem90sr3, SABERParameters.ufiresaberkem90sr3); + + picnicOids.put(PicnicParameters.picnicl1fs, BCObjectIdentifiers.picnicl1fs); + picnicOids.put(PicnicParameters.picnicl1ur, BCObjectIdentifiers.picnicl1ur); + picnicOids.put(PicnicParameters.picnicl3fs, BCObjectIdentifiers.picnicl3fs); + picnicOids.put(PicnicParameters.picnicl3ur, BCObjectIdentifiers.picnicl3ur); + picnicOids.put(PicnicParameters.picnicl5fs, BCObjectIdentifiers.picnicl5fs); + picnicOids.put(PicnicParameters.picnicl5ur, BCObjectIdentifiers.picnicl5ur); + picnicOids.put(PicnicParameters.picnic3l1, BCObjectIdentifiers.picnic3l1); + picnicOids.put(PicnicParameters.picnic3l3, BCObjectIdentifiers.picnic3l3); + picnicOids.put(PicnicParameters.picnic3l5, BCObjectIdentifiers.picnic3l5); + picnicOids.put(PicnicParameters.picnicl1full, BCObjectIdentifiers.picnicl1full); + picnicOids.put(PicnicParameters.picnicl3full, BCObjectIdentifiers.picnicl3full); + picnicOids.put(PicnicParameters.picnicl5full, BCObjectIdentifiers.picnicl5full); + + picnicParams.put(BCObjectIdentifiers.picnicl1fs, PicnicParameters.picnicl1fs); + picnicParams.put(BCObjectIdentifiers.picnicl1ur, PicnicParameters.picnicl1ur); + picnicParams.put(BCObjectIdentifiers.picnicl3fs, PicnicParameters.picnicl3fs); + picnicParams.put(BCObjectIdentifiers.picnicl3ur, PicnicParameters.picnicl3ur); + picnicParams.put(BCObjectIdentifiers.picnicl5fs, PicnicParameters.picnicl5fs); + picnicParams.put(BCObjectIdentifiers.picnicl5ur, PicnicParameters.picnicl5ur); + picnicParams.put(BCObjectIdentifiers.picnic3l1, PicnicParameters.picnic3l1); + picnicParams.put(BCObjectIdentifiers.picnic3l3, PicnicParameters.picnic3l3); + picnicParams.put(BCObjectIdentifiers.picnic3l5, PicnicParameters.picnic3l5); + picnicParams.put(BCObjectIdentifiers.picnicl1full, PicnicParameters.picnicl1full); + picnicParams.put(BCObjectIdentifiers.picnicl3full, PicnicParameters.picnicl3full); + picnicParams.put(BCObjectIdentifiers.picnicl5full, PicnicParameters.picnicl5full); + + + + falconOids.put(FalconParameters.falcon_512, BCObjectIdentifiers.falcon_512); + falconOids.put(FalconParameters.falcon_1024, BCObjectIdentifiers.falcon_1024); + + falconParams.put(BCObjectIdentifiers.falcon_512, FalconParameters.falcon_512); + falconParams.put(BCObjectIdentifiers.falcon_1024, FalconParameters.falcon_1024); + + kyberOids.put(KyberParameters.kyber512, BCObjectIdentifiers.kyber512); + kyberOids.put(KyberParameters.kyber768, BCObjectIdentifiers.kyber768); + kyberOids.put(KyberParameters.kyber1024, BCObjectIdentifiers.kyber1024); + + kyberParams.put(BCObjectIdentifiers.kyber512, KyberParameters.kyber512); + kyberParams.put(BCObjectIdentifiers.kyber768, KyberParameters.kyber768); + kyberParams.put(BCObjectIdentifiers.kyber1024, KyberParameters.kyber1024); + + + + + + dilithiumOids.put(DilithiumParameters.dilithium2, BCObjectIdentifiers.dilithium2); + dilithiumOids.put(DilithiumParameters.dilithium3, BCObjectIdentifiers.dilithium3); + dilithiumOids.put(DilithiumParameters.dilithium5, BCObjectIdentifiers.dilithium5); + + dilithiumParams.put(BCObjectIdentifiers.dilithium2, DilithiumParameters.dilithium2); + dilithiumParams.put(BCObjectIdentifiers.dilithium3, DilithiumParameters.dilithium3); + dilithiumParams.put(BCObjectIdentifiers.dilithium5, DilithiumParameters.dilithium5); + + bikeParams.put(BCObjectIdentifiers.bike128, BIKEParameters.bike128); + bikeParams.put(BCObjectIdentifiers.bike192, BIKEParameters.bike192); + bikeParams.put(BCObjectIdentifiers.bike256, BIKEParameters.bike256); + + bikeOids.put(BIKEParameters.bike128, BCObjectIdentifiers.bike128); + bikeOids.put(BIKEParameters.bike192, BCObjectIdentifiers.bike192); + bikeOids.put(BIKEParameters.bike256, BCObjectIdentifiers.bike256); + + hqcParams.put(BCObjectIdentifiers.hqc128, HQCParameters.hqc128); + hqcParams.put(BCObjectIdentifiers.hqc192, HQCParameters.hqc192); + hqcParams.put(BCObjectIdentifiers.hqc256, HQCParameters.hqc256); + + hqcOids.put(HQCParameters.hqc128, BCObjectIdentifiers.hqc128); + hqcOids.put(HQCParameters.hqc192, BCObjectIdentifiers.hqc192); + hqcOids.put(HQCParameters.hqc256, BCObjectIdentifiers.hqc256); + + + + + + + } + + static Digest getDigest(ASN1ObjectIdentifier oid) + { + if (oid.equals(NISTObjectIdentifiers.id_sha256)) + { + return new SHA256Digest(); + } + if (oid.equals(NISTObjectIdentifiers.id_sha512)) + { + return new SHA512Digest(); + } + if (oid.equals(NISTObjectIdentifiers.id_shake128)) + { + return new SHAKEDigest(128); + } + if (oid.equals(NISTObjectIdentifiers.id_shake256)) + { + return new SHAKEDigest(256); + } + + throw new IllegalArgumentException("unrecognized digest OID: " + oid); + } + + public static AlgorithmIdentifier getAlgorithmIdentifier(String digestName) + { + if (digestName.equals("SHA-1")) + { + return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); + } + if (digestName.equals("SHA-224")) + { + return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224); + } + if (digestName.equals("SHA-256")) + { + return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256); + } + if (digestName.equals("SHA-384")) + { + return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384); + } + if (digestName.equals("SHA-512")) + { + return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512); + } + + throw new IllegalArgumentException("unrecognised digest algorithm: " + digestName); + } + + public static String getDigestName(ASN1ObjectIdentifier digestOid) + { + if (digestOid.equals(OIWObjectIdentifiers.idSHA1)) + { + return "SHA-1"; + } + if (digestOid.equals(NISTObjectIdentifiers.id_sha224)) + { + return "SHA-224"; + } + if (digestOid.equals(NISTObjectIdentifiers.id_sha256)) + { + return "SHA-256"; + } + if (digestOid.equals(NISTObjectIdentifiers.id_sha384)) + { + return "SHA-384"; + } + if (digestOid.equals(NISTObjectIdentifiers.id_sha512)) + { + return "SHA-512"; + } + + throw new IllegalArgumentException("unrecognised digest algorithm: " + digestOid); + } + + static ASN1ObjectIdentifier mcElieceOidLookup(CMCEParameters params) + { + return (ASN1ObjectIdentifier)mcElieceOids.get(params); + } + + static CMCEParameters mcElieceParamsLookup(ASN1ObjectIdentifier oid) + { + return (CMCEParameters)mcElieceParams.get(oid); + } + + static ASN1ObjectIdentifier frodoOidLookup(FrodoParameters params) + { + return (ASN1ObjectIdentifier)frodoOids.get(params); + } + + static FrodoParameters frodoParamsLookup(ASN1ObjectIdentifier oid) + { + return (FrodoParameters)frodoParams.get(oid); + } + + static ASN1ObjectIdentifier saberOidLookup(SABERParameters params) + { + return (ASN1ObjectIdentifier)saberOids.get(params); + } + + static SABERParameters saberParamsLookup(ASN1ObjectIdentifier oid) + { + return (SABERParameters)saberParams.get(oid); + } + + static ASN1ObjectIdentifier picnicOidLookup(PicnicParameters params) + { + return (ASN1ObjectIdentifier)picnicOids.get(params); + } + + static PicnicParameters picnicParamsLookup(ASN1ObjectIdentifier oid) + { + return (PicnicParameters)picnicParams.get(oid); + } + + static ASN1ObjectIdentifier falconOidLookup(FalconParameters params) + { + return (ASN1ObjectIdentifier)falconOids.get(params); + } + + static FalconParameters falconParamsLookup(ASN1ObjectIdentifier oid) + { + return (FalconParameters)falconParams.get(oid); + } + + static ASN1ObjectIdentifier kyberOidLookup(KyberParameters params) + { + return (ASN1ObjectIdentifier)kyberOids.get(params); + } + + static KyberParameters kyberParamsLookup(ASN1ObjectIdentifier oid) + { + return (KyberParameters)kyberParams.get(oid); + } + + static ASN1ObjectIdentifier dilithiumOidLookup(DilithiumParameters params) + { + return (ASN1ObjectIdentifier)dilithiumOids.get(params); + } + + static DilithiumParameters dilithiumParamsLookup(ASN1ObjectIdentifier oid) + { + return (DilithiumParameters)dilithiumParams.get(oid); + } + + static ASN1ObjectIdentifier bikeOidLookup(BIKEParameters params) + { + return (ASN1ObjectIdentifier)bikeOids.get(params); + } + + static BIKEParameters bikeParamsLookup(ASN1ObjectIdentifier oid) + { + return (BIKEParameters)bikeParams.get(oid); + } + + static ASN1ObjectIdentifier hqcOidLookup(HQCParameters params) + { + return (ASN1ObjectIdentifier)hqcOids.get(params); + } + + static HQCParameters hqcParamsLookup(ASN1ObjectIdentifier oid) + { + return (HQCParameters)hqcParams.get(oid); + } +} diff --git a/core/src/main/jdk1.1/org/bouncycastle/util/BigIntegers.java b/core/src/main/jdk1.1/org/bouncycastle/util/BigIntegers.java index 2b72fd725e..3d7a724da0 100644 --- a/core/src/main/jdk1.1/org/bouncycastle/util/BigIntegers.java +++ b/core/src/main/jdk1.1/org/bouncycastle/util/BigIntegers.java @@ -368,6 +368,51 @@ private static byte[] createRandom(int bitLength, SecureRandom random) return rv; } + public static boolean modOddIsCoprime(BigInteger M, BigInteger X) + { + if (!M.testBit(0)) + { + throw new IllegalArgumentException("'M' must be odd"); + } + if (M.signum() != 1) + { + throw new ArithmeticException("BigInteger: modulus not positive"); + } + if (X.signum() < 0 || X.bitLength() > M.bitLength()) + { + X = X.mod(M); + } + + int bits = M.bitLength(); + int[] m = Nat.fromBigInteger(bits, M); + int[] x = Nat.fromBigInteger(bits, X); + return 0 != Mod.modOddIsCoprime(m, x); + } + + public static boolean modOddIsCoprimeVar(BigInteger M, BigInteger X) + { + if (!M.testBit(0)) + { + throw new IllegalArgumentException("'M' must be odd"); + } + if (M.signum() != 1) + { + throw new ArithmeticException("BigInteger: modulus not positive"); + } + if (X.signum() < 0 || X.bitLength() > M.bitLength()) + { + X = X.mod(M); + } + if (X.equals(ONE)) + { + return true; + } + + int bits = M.bitLength(); + int[] m = Nat.fromBigInteger(bits, M); + int[] x = Nat.fromBigInteger(bits, X); + return Mod.modOddIsCoprimeVar(m, x); + } public static class Cache { private final Map values = new HashMap(); diff --git a/core/src/main/jdk1.3/org/bouncycastle/pqc/crypto/picnic/PicnicEngine.java b/core/src/main/jdk1.3/org/bouncycastle/pqc/crypto/picnic/PicnicEngine.java index f39d29624e..0620e11a05 100644 --- a/core/src/main/jdk1.3/org/bouncycastle/pqc/crypto/picnic/PicnicEngine.java +++ b/core/src/main/jdk1.3/org/bouncycastle/pqc/crypto/picnic/PicnicEngine.java @@ -6,6 +6,7 @@ import org.bouncycastle.crypto.digests.SHAKEDigest; import org.bouncycastle.math.raw.Bits; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Integers; import org.bouncycastle.util.Pack; class PicnicEngine @@ -338,19 +339,18 @@ public boolean crypto_sign_open(byte[] m, byte[] sm, byte[] pk) private int picnic_verify(byte[] pk, byte[] message, byte[] signature, int sigLen) { - byte[] plaintext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; - byte[] ciphertext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; - picnic_read_public_key(ciphertext_bytes, plaintext_bytes, pk); int[] ciphertext = new int[stateSizeWords]; int[] plaintext = new int[stateSizeWords]; - - Pack.littleEndianToInt(plaintext_bytes, 0, plaintext); - Pack.littleEndianToInt(ciphertext_bytes, 0, ciphertext); + picnic_read_public_key(ciphertext, plaintext, pk); if(is_picnic3(parameters)) { Signature2 sig = new Signature2(this); - deserializeSignature2(sig, signature, sigLen, message.length + 4); + int ret = deserializeSignature2(sig, signature, sigLen, message.length + 4); + if (ret != 0) + { + return -1; + } return verify_picnic3(sig, ciphertext, plaintext, message); } @@ -392,9 +392,12 @@ private int verify(Signature sig, int[] pubKey, int[] plaintext, byte[] message) view1s[i] = new View(this); view2s[i] = new View(this); - verifyProof(proofs[i], view1s[i], view2s[i], - getChallenge(received_challengebits, i), sig.salt, i, - tmp, plaintext, tape); + if (!verifyProof(proofs[i], view1s[i], view2s[i], + getChallenge(received_challengebits, i), sig.salt, i, + tmp, plaintext, tape)) + { + return -1; + } // create ordered array of commitments with order computed based on the challenge // check commitments of the two opened views @@ -413,7 +416,7 @@ private int verify(Signature sig, int[] pubKey, int[] plaintext, byte[] message) viewOutputs[i][challenge] = view1s[i].outputShare; viewOutputs[i][(challenge + 1) % 3] = view2s[i].outputShare; int[] view3Output = new int[stateSizeWords]; /* pointer into the slab to the current 3rd view */ - xor_three(view3Output, view1s[i].outputShare, view2s[i].outputShare, pubKey, stateSizeBytes); + xor_three(view3Output, view1s[i].outputShare, view2s[i].outputShare, pubKey); viewOutputs[i][(challenge + 2) % 3] = view3Output; } @@ -432,7 +435,7 @@ private int verify(Signature sig, int[] pubKey, int[] plaintext, byte[] message) } boolean verifyProof(Signature.Proof proof, View view1, View view2, int challenge, byte[] salt, - int roundNumber, byte[] tmp, int[] plaintext, Tape tape) + int roundNumber, byte[] tmp, int[] plaintext, Tape tape) { System.arraycopy(proof.communicatedBits, 0, view2.communicatedBits, 0, andSizeBytes); tape.pos = 0; @@ -457,6 +460,7 @@ boolean verifyProof(Signature.Proof proof, View view1, View view2, int challenge { break; } + Pack.littleEndianToInt(tmp, 0, view2.inputShare);//todo check System.arraycopy(tmp, stateSizeBytes, tape.tapes[1], 0, andSizeBytes); @@ -473,12 +477,13 @@ boolean verifyProof(Signature.Proof proof, View view1, View view2, int challenge System.arraycopy(tmp, stateSizeBytes, tape.tapes[0], 0, andSizeBytes); status = status && createRandomTape(proof.seed2, 0, salt, roundNumber, 2, tape.tapes[1], andSizeBytes); + if (!status) { break; } - System.arraycopy(proof.inputShare, 0, view2.inputShare, 0, stateSizeBytes); + System.arraycopy(proof.inputShare, 0, view2.inputShare, 0, stateSizeWords); break; case 2: @@ -486,12 +491,14 @@ boolean verifyProof(Signature.Proof proof, View view1, View view2, int challenge // it is not computable from the seed. We just need to compute view2's input from // its seed status = createRandomTape(proof.seed1, 0, salt, roundNumber, 2, tape.tapes[0], andSizeBytes); - System.arraycopy(proof.inputShare, 0, view1.inputShare, 0, stateSizeBytes); + System.arraycopy(proof.inputShare, 0, view1.inputShare, 0, stateSizeWords); status = status && createRandomTape(proof.seed2, 0, salt, roundNumber, 0, tmp, stateSizeBytes + andSizeBytes); + if (!status) { break; } + Pack.littleEndianToInt(tmp, 0, view2.inputShare);//todo check System.arraycopy(tmp, stateSizeBytes, tape.tapes[1], 0, andSizeBytes); break; @@ -504,18 +511,9 @@ boolean verifyProof(Signature.Proof proof, View view1, View view2, int challenge { return false; } - /* When input shares are read from the tapes, and the length is not a whole number of bytes, the trailing bits must be zero */ - byte[] view_bytes = new byte[stateSizeBytes * 4]; - Pack.intToLittleEndian(view1.inputShare, view_bytes, 0); - Arrays.fill(view_bytes, stateSizeBytes, view_bytes.length, (byte) 0); //todo have correct size: reduce view.inputshare by /4 - zeroTrailingBits(view_bytes, stateSizeBits); - Pack.littleEndianToInt(view_bytes, 0, view1.inputShare); - Pack.intToLittleEndian(view2.inputShare, view_bytes, 0); - Arrays.fill(view_bytes, stateSizeBytes, view_bytes.length, (byte) 0); - zeroTrailingBits(view_bytes, stateSizeBits); - - Pack.littleEndianToInt(view_bytes, 0, view2.inputShare); + Utils.zeroTrailingBits(view1.inputShare, stateSizeBits); + Utils.zeroTrailingBits(view2.inputShare, stateSizeBits); int[] tmp_ints = Pack.littleEndianToInt(tmp, 0, tmp.length/4); mpc_LowMC_verify(view1, view2, tape, tmp_ints, plaintext, challenge); @@ -536,7 +534,7 @@ void mpc_LowMC_verify(View view1, View view2, Tape tapes, int[] tmp, int[] plain view2.inputShare, 0, current.getData(), current.getMatrixPointer()); - mpc_xor(tmp, tmp, stateSizeWords, 2); + mpc_xor(tmp, tmp, 2); for (int r = 1; r <= numRounds; ++r) { @@ -557,7 +555,7 @@ void mpc_LowMC_verify(View view1, View view2, Tape tapes, int[] tmp, int[] plain current = lowmcConstants.RConstant(this, r - 1); mpc_xor_constant_verify(tmp, current.getData(), current.getMatrixPointer(), stateSizeWords, challenge); - mpc_xor(tmp, tmp, stateSizeWords, 2); + mpc_xor(tmp, tmp, 2); } System.arraycopy(tmp, 2*stateSizeWords, view1.outputShare, 0, stateSizeWords); @@ -603,10 +601,14 @@ void mpc_substitution_verify(int[] state, Tape rand, View view1, View view2) void mpc_AND_verify(int[] in1, int[] in2, int[] out, Tape rand, View view1, View view2) { - int[] r = { Utils.getBit(rand.tapes[0], rand.pos), Utils.getBit(rand.tapes[1], rand.pos) }; + int r0 = Utils.getBit(rand.tapes[0], rand.pos); + int r1 = Utils.getBit(rand.tapes[1], rand.pos); + + int a0 = in1[0], a1 = in1[1]; + int b0 = in2[0], b1 = in2[1]; - out[0] = (in1[0] & in2[1]) ^ (in1[1] & in2[0]) ^ (in1[0] & in2[0]) ^ r[0] ^ r[1]; - Utils.setBit(view1.communicatedBits, rand.pos, (byte) (out[0] & 0xff)); + out[0] = (a0 & b1) ^ (a1 & b0) ^ (a0 & b0) ^ r0 ^ r1; + Utils.setBit(view1.communicatedBits, rand.pos, (byte)out[0]); out[1] = Utils.getBit(view2.communicatedBits, rand.pos); rand.pos++; @@ -630,49 +632,51 @@ else if (challenge == 2) } for (int i = 0; i < length; i++) { - state[i + offset] = state[i + offset] ^ in[i + inOffset]; + state[i + offset] ^= in[i + inOffset]; } } - private int deserializeSignature(Signature sig, byte[] sigBytes, int sigBytesLen, int sigBytesOffset) { Signature.Proof[] proofs = sig.proofs; byte[] challengeBits = sig.challengeBits; + int challengesLength = Utils.numBytes(2 * numMPCRounds); /* Validate input buffer is large enough */ - if (sigBytesLen < Utils.numBytes(2 * numMPCRounds)) + if (sigBytesLen < challengesLength) { /* ensure the input has at least the challenge */ return -1; } - int inputShareSize = computeInputShareSize(sigBytes, stateSizeBytes); - int bytesExpected = Utils.numBytes(2 * numMPCRounds) + saltSizeBytes + - numMPCRounds * (2 * seedSizeBytes + andSizeBytes + digestSizeBytes) + inputShareSize; + // NOTE: This also validates that there are no challenges > 2 + int numNonZeroChallenges = countNonZeroChallenges(sigBytes, sigBytesOffset); + if (numNonZeroChallenges < 0) + return -1; + + int inputShareSize = numNonZeroChallenges * stateSizeBytes; + int bytesRequired = challengesLength + saltSizeBytes + + numMPCRounds * (2 * seedSizeBytes + andSizeBytes + digestSizeBytes) + inputShareSize; if (transform == TRANSFORM_UR) { - bytesExpected += UnruhGWithoutInputBytes * numMPCRounds; + bytesRequired += UnruhGWithInputBytes * (numMPCRounds - numNonZeroChallenges); + bytesRequired += UnruhGWithoutInputBytes * numNonZeroChallenges; } - if (sigBytesLen < bytesExpected) + + if (sigBytesLen != bytesRequired) { return -1; } - System.arraycopy(sigBytes, sigBytesOffset, challengeBits, 0, Utils.numBytes(2 * numMPCRounds)); - sigBytesOffset += Utils.numBytes(2 * numMPCRounds); + System.arraycopy(sigBytes, sigBytesOffset, challengeBits, 0, challengesLength); + sigBytesOffset += challengesLength; - if (!isChallengeValid(challengeBits)) - { - return -1; - } System.arraycopy(sigBytes, sigBytesOffset, sig.salt, 0, saltSizeBytes); sigBytesOffset += saltSizeBytes; for (int i = 0; i < numMPCRounds; i++) { - int challenge = getChallenge(challengeBits, i); System.arraycopy(sigBytes, sigBytesOffset, proofs[i].view3Commitment, 0, digestSizeBytes); @@ -704,7 +708,8 @@ private int deserializeSignature(Signature sig, byte[] sigBytes, int sigBytesLen } sigBytesOffset += stateSizeBytes; - if(!arePaddingBitsZero(Pack.intToLittleEndian(proofs[i].inputShare), stateSizeBits)) + + if (!arePaddingBitsZero(proofs[i].inputShare, stateSizeBits)) { return -1; } @@ -715,43 +720,50 @@ private int deserializeSignature(Signature sig, byte[] sigBytes, int sigBytesLen return 0; } - private boolean isChallengeValid(byte[] challengeBits) - { - for (int i = 0; i < numMPCRounds; i++) - { - int challenge = getChallenge(challengeBits, i); - if (challenge > 2) - { - return false; - } - } - return true; - } - - private int computeInputShareSize(byte[] challengeBits, int stateSizeBytes) + private int countNonZeroChallenges(byte[] challengeBits, int challengeBitsOffset) { /* When the FS transform is used, the input share is included in the proof - * only when the challenge is 1 or 2. When dersializing, to compute the + * only when the challenge is 1 or 2. When deserializing, to compute the * number of bytes expected, we must check how many challenge values are 1 - * or 2. The parameter stateSizeBytes is the size of an input share. */ - int inputShareSize = 0; + * or 2. We also check that no challenges have the invalid value 3. */ + int count = 0; + int challenges3 = 0; - for (int i = 0; i < numMPCRounds; i++) + int i = 0; + while (i + 16 <= numMPCRounds) { - int challenge = getChallenge(challengeBits, i); - if (challenge == 1 || challenge == 2) - { - inputShareSize += stateSizeBytes; - } + int challenges = Pack.littleEndianToInt(challengeBits, challengeBitsOffset + (i >>> 2)); + challenges3 |= challenges & (challenges >>> 1); + count += Integers.bitCount((challenges ^ (challenges >>> 1)) & 0x55555555); + i += 16; } - return inputShareSize; + + int remainingBits = (numMPCRounds - i) * 2; + if (remainingBits > 0) + { + int remainingBytes = (remainingBits + 7) / 8; + int challenges = Pack.littleEndianToInt_Low(challengeBits, challengeBitsOffset + (i >>> 2), remainingBytes); + challenges &= Utils.getTrailingBitsMask(remainingBits); + challenges3 |= challenges & (challenges >>> 1); + count += Integers.bitCount((challenges ^ (challenges >>> 1)) & 0x55555555); + } + + return (challenges3 & 0x55555555) == 0 ? count : -1; } - private int picnic_read_public_key(byte[] ciphertext, byte[] plaintext, byte[] pk) + private void picnic_read_public_key(int[] ciphertext, int[] plaintext, byte[] pk) { - System.arraycopy(pk, 1, ciphertext, 0, stateSizeBytes); - System.arraycopy(pk, 1 + stateSizeBytes, plaintext, 0, stateSizeBytes); - return 0; + int ciphertextPos = 1, plaintextPos = 1 + stateSizeBytes; + int fullWords = stateSizeBytes / 4; + Pack.littleEndianToInt(pk, ciphertextPos, ciphertext, 0, fullWords); + Pack.littleEndianToInt(pk, plaintextPos, plaintext, 0, fullWords); + + if (fullWords < stateSizeWords) + { + int fullWordBytes = fullWords * 4, partialWordBytes = stateSizeBytes - fullWordBytes; + ciphertext[fullWords] = Pack.littleEndianToInt_Low(pk, ciphertextPos + fullWordBytes, partialWordBytes); + plaintext[fullWords] = Pack.littleEndianToInt_Low(pk, plaintextPos + fullWordBytes, partialWordBytes); + } } private int verify_picnic3(Signature2 sig, int[] pubKey, int[] plaintext, byte[] message) @@ -1042,6 +1054,16 @@ private boolean arePaddingBitsZero(byte[] data, int bitLength) return true; } + private boolean arePaddingBitsZero(int[] data, int bitLength) + { + int partialWord = bitLength & 31; + if (partialWord == 0) + return true; + + int mask = Utils.getTrailingBitsMask(bitLength); + return (data[bitLength >>> 5] & ~mask) == 0; + } + public void crypto_sign(byte[] sm, byte[] m, byte[] sk) { boolean ret = picnic_sign(sk, m, sm); @@ -1050,27 +1072,27 @@ public void crypto_sign(byte[] sm, byte[] m, byte[] sk) return; // throw error? } System.arraycopy(m, 0, sm, 4, m.length); -// sm = Arrays.copyOfRange(sm, 0, signatureLength); } private boolean picnic_sign(byte[] sk, byte[] message, byte[] signature) { - //todo unify conversion - - byte[] data_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; - System.arraycopy(sk, 1, data_bytes, 0, stateSizeBytes); - byte[] ciphertext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; - System.arraycopy(sk, 1 + stateSizeBytes, ciphertext_bytes, 0, stateSizeBytes); - byte[] plaintext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; - System.arraycopy(sk, 1 + 2 * stateSizeBytes, plaintext_bytes, 0, stateSizeBytes); int[] data = new int[stateSizeWords]; int[] ciphertext = new int[stateSizeWords]; int[] plaintext = new int[stateSizeWords]; - Pack.littleEndianToInt(data_bytes, 0, data); - Pack.littleEndianToInt(plaintext_bytes, 0, plaintext); - Pack.littleEndianToInt(ciphertext_bytes, 0, ciphertext); + int dataPos = 1, ciphertextPos = 1 + stateSizeBytes, plaintextPos = 1 + 2 * stateSizeBytes; + int fullWords = stateSizeBytes / 4; + Pack.littleEndianToInt(sk, dataPos, data, 0, fullWords); + Pack.littleEndianToInt(sk, ciphertextPos, ciphertext, 0, fullWords); + Pack.littleEndianToInt(sk, plaintextPos, plaintext, 0, fullWords); + if (fullWords < stateSizeWords) + { + int fullWordBytes = fullWords * 4, partialWordBytes = stateSizeBytes - fullWordBytes; + data[fullWords] = Pack.littleEndianToInt_Low(sk, dataPos + fullWordBytes, partialWordBytes); + ciphertext[fullWords] = Pack.littleEndianToInt_Low(sk, ciphertextPos + fullWordBytes, partialWordBytes); + plaintext[fullWords] = Pack.littleEndianToInt_Low(sk, plaintextPos + fullWordBytes, partialWordBytes); + } if(!is_picnic3(parameters)) { @@ -1083,10 +1105,11 @@ private boolean picnic_sign(byte[] sk, byte[] message, byte[] signature) } int len = serializeSignature(sig, signature, message.length + 4); - if (len == -1) + if (len < 0) { return false; } + signatureLength = len; Pack.intToLittleEndian(len, signature, 0); return true; @@ -1101,7 +1124,7 @@ private boolean picnic_sign(byte[] sk, byte[] message, byte[] signature) } int len = serializeSignature2(sig, signature, message.length + 4); - if (len == -1) + if (len < 0) { return false; } @@ -1139,7 +1162,6 @@ int serializeSignature(Signature sig, byte[] sigBytes, int sigOffset) sigByteIndex += Utils.numBytes(2 * numMPCRounds); System.arraycopy(sig.salt, 0, sigBytes, sigByteIndex,saltSizeBytes); - sigByteIndex += saltSizeBytes; for (int i = 0; i < numMPCRounds; i++) @@ -1178,12 +1200,11 @@ int serializeSignature(Signature sig, byte[] sigBytes, int sigOffset) int getChallenge(byte[] challenge, int round) { - return (Utils.getBit(challenge, 2 * round + 1) << 1) | Utils.getBit(challenge, 2 * round); + return Utils.getCrumbAligned(challenge, round); } private int serializeSignature2(Signature2 sig, byte[] sigBytes, int sigOffset) { - /* Compute the number of bytes required for the signature */ int bytesRequired = digestSizeBytes + saltSizeBytes; /* challenge and salt */ @@ -1273,7 +1294,6 @@ private int sign_picnic1(int[] privateKey, int[] pubKey, int[] plaintext, byte[] Tape tape = new Tape(this); byte[] tmp = new byte[Math.max(9 * stateSizeBytes, stateSizeBytes + andSizeBytes)]; - byte[] view_byte = new byte[stateSizeBytes*4]; for (int k = 0; k < numMPCRounds; k++) { @@ -1289,9 +1309,11 @@ private int sign_picnic1(int[] privateKey, int[] pubKey, int[] plaintext, byte[] { return -1; } - System.arraycopy(tmp, 0, view_byte, 0, stateSizeBytes); - zeroTrailingBits(view_byte, stateSizeBits); - Pack.littleEndianToInt(view_byte, 0, views[k][j].inputShare); + + int[] inputShare = views[k][j].inputShare; + Pack.littleEndianToInt(tmp, 0, inputShare); + Utils.zeroTrailingBits(inputShare, stateSizeBits); + System.arraycopy(tmp, stateSizeBytes, tape.tapes[j], 0, andSizeBytes); } @@ -1304,7 +1326,7 @@ private int sign_picnic1(int[] privateKey, int[] pubKey, int[] plaintext, byte[] return -1; } - xor_three(views[k][2].inputShare, privateKey, views[k][0].inputShare, views[k][1].inputShare, stateSizeBytes); + xor_three(views[k][2].inputShare, privateKey, views[k][0].inputShare, views[k][1].inputShare); tape.pos = 0; int[] tmp_int = Pack.littleEndianToInt(tmp, 0, tmp.length/4); @@ -1313,8 +1335,7 @@ private int sign_picnic1(int[] privateKey, int[] pubKey, int[] plaintext, byte[] Pack.intToLittleEndian(tmp_int, tmp, 0); int[] temp = new int[LOWMC_MAX_WORDS]; - xor_three(temp, views[k][0].outputShare, views[k][1].outputShare, views[k][2].outputShare, stateSizeBytes); - + xor_three(temp, views[k][0].outputShare, views[k][1].outputShare, views[k][2].outputShare); if(!subarrayEquals(temp, pubKey, stateSizeWords)) { @@ -1335,16 +1356,8 @@ private int sign_picnic1(int[] privateKey, int[] pubKey, int[] plaintext, byte[] } //Generating challenges - int[][][] viewOutputs = new int[numMPCRounds][3][stateSizeBytes]; - for (int i = 0; i < numMPCRounds; i++) - { - for (int j = 0; j < 3; j++) - { - viewOutputs[i][j] = views[i][j].outputShare; - } - } - H3(pubKey, plaintext, viewOutputs, as, sig.challengeBits, sig.salt, message, gs); + H3(pubKey, plaintext, views, as, sig.challengeBits, sig.salt, message, gs); //Packing Z for (int i = 0; i < numMPCRounds; i++) @@ -1354,7 +1367,6 @@ private int sign_picnic1(int[] privateKey, int[] pubKey, int[] plaintext, byte[] views[i], as[i], (transform != TRANSFORM_UR) ? null : gs[i]); //todo check if } - return 0; } @@ -1379,13 +1391,14 @@ else if (challenge == 2) } else { -// ignore + throw new IllegalArgumentException("challenge"); } if (challenge == 1 || challenge == 2) { - System.arraycopy(views[2].inputShare, 0, proof.inputShare, 0, stateSizeBytes); + System.arraycopy(views[2].inputShare, 0, proof.inputShare, 0, stateSizeWords); } + System.arraycopy(views[(challenge + 1) % 3].communicatedBits, 0, proof.communicatedBits, 0, andSizeBytes); System.arraycopy(commitments[(challenge + 2) % 3], 0, proof.view3Commitment, 0, digestSizeBytes); @@ -1395,28 +1408,56 @@ else if (challenge == 2) System.arraycopy(gs[(challenge + 2) % 3], 0, proof.view3UnruhG, 0, view3UnruhLength); } } - - void H3(int[] circuitOutput, int[] plaintext, int[][][] viewOutputs, - byte[][][] as, byte[] challengeBits, byte[] salt, - byte[] message, byte[][][] gs) + + private void H3(int[] circuitOutput, int[] plaintext, View[][] views, byte[][][] as, byte[] challengeBits, + byte[] salt, byte[] message, byte[][][] gs) { - byte[] hash = new byte[digestSizeBytes]; + digest.update((byte) 1); - /* Depending on the number of rounds, we might not set part of the last - * byte, make sure it's always zero. */ - challengeBits[Utils.numBytes(numMPCRounds * 2) - 1] = 0; + byte[] tmp = new byte[stateSizeWords * 4]; + + /* Hash the output share from each view */ + for (int i = 0; i < numMPCRounds; i++) + { + for (int j = 0; j < 3; j++) + { + Pack.intToLittleEndian(views[i][j].outputShare, tmp, 0); + digest.update(tmp, 0, stateSizeBytes); + } + } + implH3(circuitOutput, plaintext, as, challengeBits, salt, message, gs); + } + + private void H3(int[] circuitOutput, int[] plaintext, int[][][] viewOutputs, byte[][][] as, byte[] challengeBits, + byte[] salt, byte[] message, byte[][][] gs) + { digest.update((byte) 1); + byte[] tmp = new byte[stateSizeWords * 4]; + /* Hash the output share from each view */ for (int i = 0; i < numMPCRounds; i++) { for (int j = 0; j < 3; j++) { - digest.update( Pack.intToLittleEndian(viewOutputs[i][j]), 0, stateSizeBytes); + Pack.intToLittleEndian(viewOutputs[i][j], tmp, 0); + digest.update(tmp, 0, stateSizeBytes); } } + implH3(circuitOutput, plaintext, as, challengeBits, salt, message, gs); + } + + private void implH3(int[] circuitOutput, int[] plaintext, byte[][][] as, byte[] challengeBits, byte[] salt, + byte[] message, byte[][][] gs) + { + byte[] hash = new byte[digestSizeBytes]; + + /* Depending on the number of rounds, we might not set part of the last + * byte, make sure it's always zero. */ + challengeBits[Utils.numBytes(numMPCRounds * 2) - 1] = 0; + /* Hash all the commitments C */ for (int i = 0; i < numMPCRounds; i++) { @@ -1532,7 +1573,7 @@ private void mpc_LowMC(Tape tapes, View[] views, int[] plaintext, int[] slab) current.getData(), current.getMatrixPointer()); } - mpc_xor(slab, slab, stateSizeWords, 3); + mpc_xor(slab, slab, 3); for (int r = 1; r <= numRounds; r++) { @@ -1555,7 +1596,7 @@ private void mpc_LowMC(Tape tapes, View[] views, int[] plaintext, int[] slab) mpc_xor_constant(slab, 3*stateSizeWords, current.getData(), current.getMatrixPointer(), stateSizeWords); - mpc_xor(slab, slab, stateSizeWords, 3); + mpc_xor(slab, slab, 3); } for (int i = 0; i < 3; i++) @@ -1619,37 +1660,31 @@ private void mpc_substitution(int[] state, Tape rand, View[] views) /*** Functions implementing Sign ***/ private void mpc_AND(int[] in1, int[] in2, int[] out, Tape rand, View[] views) { - int[] r = new int[]{ - Utils.getBit(rand.tapes[0], rand.pos), - Utils.getBit(rand.tapes[1], rand.pos), - Utils.getBit(rand.tapes[2], rand.pos) - }; + int r0 = Utils.getBit(rand.tapes[0], rand.pos); + int r1 = Utils.getBit(rand.tapes[1], rand.pos); + int r2 = Utils.getBit(rand.tapes[2], rand.pos); - for (int i = 0; i < 3; i++) - { - out[i] = (in1[i] & in2[(i + 1) % 3]) ^ (in1[(i + 1) % 3] & in2[i]) - ^ (in1[i] & in2[i]) ^ r[i] ^ r[(i + 1) % 3]; + out[0] = (in1[0] & in2[1]) ^ (in1[1] & in2[0]) ^ (in1[0] & in2[0]) ^ r0 ^ r1; + out[1] = (in1[1] & in2[2]) ^ (in1[2] & in2[1]) ^ (in1[1] & in2[1]) ^ r1 ^ r2; + out[2] = (in1[2] & in2[0]) ^ (in1[0] & in2[2]) ^ (in1[2] & in2[2]) ^ r2 ^ r0; + + Utils.setBit(views[0].communicatedBits, rand.pos, (byte)out[0]); + Utils.setBit(views[1].communicatedBits, rand.pos, (byte)out[1]); + Utils.setBit(views[2].communicatedBits, rand.pos, (byte)out[2]); - Utils.setBit(views[i].communicatedBits, rand.pos, (byte) (out[i] & 0xff)); - } rand.pos++; } - - private void mpc_xor(int[] state, int[] in, int len, int players) + private void mpc_xor(int[] state, int[] in, int players) { - for (int player = 0; player < players; player++) + for (int i = 0, count = stateSizeWords * players; i < count; ++i) { - for (int i = 0; i < len; i++) - { - state[i + (players+player)*stateSizeWords] = state[i + (players+player)*stateSizeWords] ^ in[i + player*stateSizeWords]; - } + state[players * stateSizeWords + i] ^= in[i]; } } - private void mpc_matrix_mul(int[] output, int outputOffset, int[] state, int stateOffset, - int[] matrix, int matrixOffset, int players) + int[] matrix, int matrixOffset, int players) { for (int player = 0; player < players; player++) { @@ -1664,7 +1699,7 @@ private void mpc_xor_constant(int[] state, int stateOffset, int[] in, int inOffs { for (int i = 0; i < len; i++) { - state[i + stateOffset] = state[i + stateOffset] ^ in[i + inOffset]; + state[i + stateOffset] ^= in[i + inOffset]; } } @@ -1697,11 +1732,12 @@ private boolean createRandomTape(byte[] seed, int seedOffset, byte[] salt, int r private byte[] computeSeeds(int[] privateKey, int[] publicKey, int[] plaintext, byte[] message) { byte[] allSeeds = new byte[seedSizeBytes * (numMPCParties * numMPCRounds) + saltSizeBytes]; + byte[] temp = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; - digest.update(Pack.intToLittleEndian(privateKey), 0, stateSizeBytes); + updateDigest(privateKey, temp); digest.update(message, 0, message.length); - digest.update(Pack.intToLittleEndian(publicKey), 0, stateSizeBytes); - digest.update(Pack.intToLittleEndian(plaintext), 0, stateSizeBytes); + updateDigest(publicKey, temp); + updateDigest(plaintext, temp); digest.update(Pack.intToLittleEndian(stateSizeBits), 0, 2); // Derive the N*T seeds + 1 salt @@ -1762,7 +1798,7 @@ private boolean sign_picnic3(int[] privateKey, int[] pubKey, int[] plaintext, by { msgs[t] = new Msg(this); int[] maskedKey = Pack.littleEndianToInt(inputs[t], 0, stateSizeWords); - xor_array(maskedKey, maskedKey, privateKey, 0, stateSizeWords); + xor_array(maskedKey, maskedKey, privateKey, 0); int rv = simulateOnline(maskedKey, tapes[t], tmp_shares, msgs[t], plaintext, pubKey); if (rv != 0) { @@ -1844,8 +1880,6 @@ static int indexOf(int[] list, int len, int value) return -1; } - - private int[] getMissingLeavesList(int[] challengeC) { int missingLeavesSize = numMPCRounds - numOpenedRounds; @@ -1864,7 +1898,6 @@ private int[] getMissingLeavesList(int[] challengeC) return missingLeaves; } - private void HCP(byte[] challengeHash, int[] challengeC, int[] challengeP, byte[][] Ch, byte[] hCv, byte[] salt, int[] pubKey, int[] plaintext, byte[] message) { @@ -1875,10 +1908,12 @@ private void HCP(byte[] challengeHash, int[] challengeC, int[] challengeP, byte[ digest.update(Ch[t], 0, digestSizeBytes); } + byte[] temp = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; + digest.update(hCv, 0, digestSizeBytes); digest.update(salt, 0, saltSizeBytes); - digest.update(Pack.intToLittleEndian(pubKey), 0, stateSizeBytes); - digest.update(Pack.intToLittleEndian(plaintext), 0, stateSizeBytes); + updateDigest(pubKey, temp); + updateDigest(plaintext, temp); digest.update(message, 0, message.length); digest.doFinal(challengeHash, 0, digestSizeBytes); @@ -1894,7 +1929,8 @@ static int bitsToChunks(int chunkLenBits, byte[] input, int inputLen, int[] chun { return 0; } - int chunkCount = ((inputLen * 8) / chunkLenBits); + + int chunkCount = (inputLen * 8) / chunkLenBits; for (int i = 0; i < chunkCount; i++) { @@ -1928,8 +1964,6 @@ static int appendUnique(int[] list, int value, int position) return position + 1; } - - private void expandChallengeHash(byte[] challengeHash, int[] challengeC, int[] challengeP) { // Populate C @@ -2006,8 +2040,6 @@ private void commit_v(byte[] digest_arr, byte[] input, Msg msg) digest.doFinal(digest_arr, 0, digestSizeBytes); } - - private int simulateOnline(int[] maskedKey, Tape tape, int[] tmp_shares, Msg msg, int[] plaintext, int[] pubKey) { @@ -2017,7 +2049,7 @@ private int simulateOnline(int[] maskedKey, Tape tape, int[] tmp_shares, KMatricesWithPointer current = lowmcConstants.KMatrix(this,0); matrix_mul(roundKey, maskedKey, current.getData(), current.getMatrixPointer()); // roundKey = maskedKey * KMatrix[0] - xor_array(state, roundKey, plaintext,0, stateSizeWords); // state = plaintext + roundKey + xor_array(state, roundKey, plaintext, 0); // state = plaintext + roundKey for (int r = 1; r <= numRounds; r++) { @@ -2028,11 +2060,11 @@ private int simulateOnline(int[] maskedKey, Tape tape, int[] tmp_shares, matrix_mul(state, state, current.getData(), current.getMatrixPointer()); // state = state * LMatrix (r-1) current = lowmcConstants.RConstant(this,r - 1); - xor_array(state, state, current.getData(), current.getMatrixPointer(), stateSizeWords); // state += RConstant + xor_array(state, state, current.getData(), current.getMatrixPointer()); // state += RConstant current = lowmcConstants.KMatrix(this, r); matrix_mul(roundKey, maskedKey, current.getData(), current.getMatrixPointer()); - xor_array(state, roundKey, state, 0, stateSizeWords); // state += roundKey + xor_array(state, roundKey, state, 0); // state += roundKey } if(!(subarrayEquals(state, pubKey, stateSizeWords))) @@ -2058,26 +2090,34 @@ private void createRandomTapes(Tape tape, byte[][] seeds, int seedsOffset, byte[ private static boolean subarrayEquals(byte[] a, byte[] b, int length) { - if(a.length < length || b.length < length) + if (a.length < length || b.length < length) + { return false; + } for (int i = 0; i < length; i++) { - if(a[i] != b[i]) + if (a[i] != b[i]) + { return false; + } } return true; } private static boolean subarrayEquals(int[] a, int[] b, int length) { - if(a.length < length || b.length < length) + if (a.length < length || b.length < length) + { return false; + } for (int i = 0; i < length; i++) { if(a[i] != b[i]) + { return false; + } } return true; } @@ -2171,7 +2211,6 @@ private void aux_mpc_AND(int mask_a, int mask_b, int fresh_output_mask, Tape tap Utils.setBit(tape.tapes[lastParty], tape.pos - 1, (byte) (aux_bit & 0xff)); } - private boolean contains(int[] list, int len, int value) { for (int i = 0; i < len; i++) @@ -2194,15 +2233,16 @@ private void tapesToWords(int[] shares, Tape tape) private void getAuxBits(byte[] output, Tape tape) { - int last = numMPCParties - 1; - int pos = 0; - int n = stateSizeBits; + byte[] lastTape = tape.tapes[numMPCParties - 1]; + int n = stateSizeBits, pos = 0, tapePos = 0; for(int j = 0; j < numRounds; j++) { + tapePos += n; + for(int i = 0; i < n; i++) { - Utils.setBit(output, pos++, Utils.getBit(tape.tapes[last], n + n*2*j + i)); + Utils.setBit(output, pos++, Utils.getBit(lastTape, tapePos++)); } } } @@ -2223,46 +2263,38 @@ private void commit(byte[] digest_arr, byte[] seed, byte[] aux, byte[] salt, int private void computeSaltAndRootSeed(byte[] saltAndRoot, int[] privateKey, int[] pubKey, int[] plaintext, byte[] message) { - //todo unify conversion - //copy back to byte array - byte[] privatekey_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; - byte[] pubkey_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; - byte[] plaintext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; - Pack.intToLittleEndian(privateKey, privatekey_bytes, 0); - Pack.intToLittleEndian(pubKey, pubkey_bytes, 0); - Pack.intToLittleEndian(plaintext, plaintext_bytes, 0); - privatekey_bytes = Arrays.copyOfRange(privatekey_bytes, 0, stateSizeBytes); - pubkey_bytes = Arrays.copyOfRange(pubkey_bytes, 0, stateSizeBytes); - plaintext_bytes = Arrays.copyOfRange(plaintext_bytes, 0, stateSizeBytes); - // + byte[] temp = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; // init done in constructor - digest.update(privatekey_bytes, 0, stateSizeBytes); + updateDigest(privateKey, temp); digest.update(message, 0, message.length); - digest.update(pubkey_bytes, 0, stateSizeBytes); - digest.update(plaintext_bytes, 0, stateSizeBytes); - digest.update(Pack.shortToLittleEndian((short)(stateSizeBits & 0xffff)), 0, 2); + updateDigest(pubKey, temp); + updateDigest(plaintext, temp); + Pack.shortToLittleEndian((short)stateSizeBits, temp, 0); + digest.update(temp, 0, 2); digest.doFinal(saltAndRoot, 0, saltAndRoot.length); } + private void updateDigest(int[] block, byte[] temp) + { + Pack.intToLittleEndian(block, temp, 0); + digest.update(temp, 0, stateSizeBytes); + } + static boolean is_picnic3(int params) { - if (params == 7/*Picnic3_L1*/ || - params == 8/*Picnic3_L3*/ || - params == 9/*Picnic3_L5*/ ) - { - return true; - } - return false; + return params == 7/*Picnic3_L1*/ + || params == 8/*Picnic3_L3*/ + || params == 9/*Picnic3_L5*/; } //todo return int; public void crypto_sign_keypair(byte[] pk, byte[] sk, SecureRandom random) { // set array sizes - byte[] plaintext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; - byte[] ciphertext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; - byte[] data_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE]; + byte[] plaintext_bytes = new byte[stateSizeWords * 4]; + byte[] ciphertext_bytes = new byte[stateSizeWords * 4]; + byte[] data_bytes = new byte[stateSizeWords * 4]; picnic_keygen(plaintext_bytes, ciphertext_bytes, data_bytes, random); picnic_write_public_key(ciphertext_bytes, plaintext_bytes, pk); @@ -2303,28 +2335,16 @@ private void picnic_keygen(byte[] plaintext_bytes, byte[] ciphertext_bytes, byte int[] data = new int[data_bytes.length/4]; int[] plaintext = new int[plaintext_bytes.length/4]; int[] ciphertext = new int[ciphertext_bytes.length/4]; - byte[] temp = new byte[stateSizeBytes]; // generate a private key - random.nextBytes(temp); - zeroTrailingBits(temp, stateSizeBits); - System.arraycopy(temp, 0, data_bytes, 0, temp.length); - - for (int i = 0; i < data.length; i++) - { - data[i] = Pack.littleEndianToInt(data_bytes, i * 4); - } - + random.nextBytes(data_bytes); + Pack.littleEndianToInt(data_bytes, 0, data); + Utils.zeroTrailingBits(data, stateSizeBits); // generate a plaintext block - random.nextBytes(temp); - zeroTrailingBits(temp, stateSizeBits); - System.arraycopy(temp, 0, plaintext_bytes, 0, temp.length); - - for (int i = 0; i < plaintext.length; i++) - { - plaintext[i] = Pack.littleEndianToInt(plaintext_bytes, i * 4); - } + random.nextBytes(plaintext_bytes); + Pack.littleEndianToInt(plaintext_bytes, 0, plaintext); + Utils.zeroTrailingBits(plaintext, stateSizeBits); // computer ciphertext LowMCEnc(plaintext, ciphertext, data); @@ -2349,7 +2369,7 @@ private void LowMCEnc(int[] plaintext, int[] output, int[] key) KMatricesWithPointer current = lowmcConstants.KMatrix(this,0); matrix_mul(roundKey, key, current.getData(), current.getMatrixPointer()); - xor_array(output, output, roundKey, 0, stateSizeWords); + xor_array(output, output, roundKey, 0); for (int r = 1; r <= numRounds; r++) { @@ -2362,8 +2382,8 @@ private void LowMCEnc(int[] plaintext, int[] output, int[] key) matrix_mul(output, output, current.getData(), current.getMatrixPointer()); current = lowmcConstants.RConstant(this,r-1); - xor_array(output, output, current.getData(), current.getMatrixPointer(), stateSizeWords); - xor_array(output, output, roundKey, 0, stateSizeWords); + xor_array(output, output, current.getData(), current.getMatrixPointer()); + xor_array(output, output, roundKey, 0); } } @@ -2382,18 +2402,17 @@ private void substitution(int[] state) } } - private void xor_three(int[] output, int[] in1, int[] in2, int[] in3, int lenBytes) + private void xor_three(int[] output, int[] in1, int[] in2, int[] in3) { - int wholeWords = stateSizeWords; - for(int i = 0; i < wholeWords; i++) + for(int i = 0; i < stateSizeWords; i++) { output[i] = in1[i] ^ in2[i] ^ in3[i]; } } - protected void xor_array(int[] out, int[] in1, int[] in2, int in2_offset, int length) + protected void xor_array(int[] out, int[] in1, int[] in2, int in2_offset) { - for (int i = 0; i < length; i++) + for (int i = 0; i < stateSizeWords; i++) { out[i] = in1[i] ^ in2[i + in2_offset]; } @@ -2442,13 +2461,4 @@ protected void matrix_mul_offset(int[] output, int outputOffset, System.arraycopy(temp, 0, output, outputOffset, stateSizeWords); } - - private void zeroTrailingBits(byte[] data, int bitLength) - { - int byteLength = Utils.numBytes(bitLength); - for (int i = bitLength; i < byteLength * 8; i++) - { - Utils.setBit(data, i, (byte) 0); - } - } } diff --git a/core/src/main/jdk1.3/org/bouncycastle/pqc/crypto/picnic/Tree.java b/core/src/main/jdk1.3/org/bouncycastle/pqc/crypto/picnic/Tree.java index 9bffa4a497..9e33ebdd64 100644 --- a/core/src/main/jdk1.3/org/bouncycastle/pqc/crypto/picnic/Tree.java +++ b/core/src/main/jdk1.3/org/bouncycastle/pqc/crypto/picnic/Tree.java @@ -1,5 +1,6 @@ package org.bouncycastle.pqc.crypto.picnic; + import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Pack; @@ -8,7 +9,7 @@ class Tree { private static final int MAX_SEED_SIZE_BYTES = 32; - private final int MAX_AUX_BYTES; +// private final int MAX_AUX_BYTES; private int depth; /* The depth of the tree */ @@ -33,7 +34,7 @@ protected int getLeavesOffset() public Tree(PicnicEngine engine, int numLeaves, int dataSize) { this.engine = engine; - MAX_AUX_BYTES = ((engine.LOWMC_MAX_AND_GATES + engine.LOWMC_MAX_KEY_BITS) / 8 + 1); +// MAX_AUX_BYTES = ((PicnicEngine.LOWMC_MAX_AND_GATES + PicnicEngine.LOWMC_MAX_KEY_BITS) / 8 + 1); this.depth = Utils.ceil_log2(numLeaves) + 1; this.numNodes = ((1 << (this.depth)) - 1) - ((1 << (this.depth - 1)) - numLeaves); /* Num nodes in complete - number of missing leaves */ @@ -283,7 +284,8 @@ protected int revealSeedsSize(int[] hideList, int hideListSize) { int[] numNodesRevealed = new int[1]; numNodesRevealed[0] = 0; - int[] revealed = getRevealedNodes(hideList, hideListSize, numNodesRevealed); +// int[] revealed = + getRevealedNodes(hideList, hideListSize, numNodesRevealed); return numNodesRevealed[0] * engine.seedSizeBytes; } @@ -316,7 +318,8 @@ protected int revealSeeds(int[] hideList, int hideListSize, byte[] output, int o protected int openMerkleTreeSize(int[] missingLeaves, int missingLeavesSize) { int[] revealedSize = new int[1]; - int[] revealed = this.getRevealedMerkleNodes(missingLeaves, missingLeavesSize, revealedSize); +// int[] revealed = + getRevealedMerkleNodes(missingLeaves, missingLeavesSize, revealedSize); return revealedSize[0] * engine.digestSizeBytes; } @@ -427,7 +430,7 @@ private void computeParentHash(int child, byte[] salt) /* One node may not have a right child when there's an odd number of leaves */ engine.digest.update(this.nodes[2 * parent + 2],0, engine.digestSizeBytes); } - engine.digest.update(salt,0, engine.saltSizeBytes); + engine.digest.update(salt,0, PicnicEngine.saltSizeBytes); engine.digest.update(Pack.intToLittleEndian(parent), 0, 2); engine.digest.doFinal(this.nodes[parent], 0, engine.digestSizeBytes); this.haveNode[parent] = true; @@ -521,10 +524,9 @@ private void expandSeeds(byte[] salt, int repIndex) private void hashSeed(byte[] digest_arr, byte[] inputSeed, byte[] salt, byte hashPrefix, int repIndex, int nodeIndex) { - engine.digest.update(hashPrefix); engine.digest.update(inputSeed, 0, engine.seedSizeBytes); - engine.digest.update(salt, 0, engine.saltSizeBytes); + engine.digest.update(salt, 0, PicnicEngine.saltSizeBytes); engine.digest.update(Pack.shortToLittleEndian((short)(repIndex & 0xffff)), 0, 2); //todo check endianness engine.digest.update(Pack.shortToLittleEndian((short)(nodeIndex & 0xffff)), 0, 2); //todo check endianness engine.digest.doFinal(digest_arr, 0, 2 * engine.seedSizeBytes); diff --git a/core/src/main/jdk1.4/org/bouncycastle/asn1/ASN1ApplicationSpecific.java b/core/src/main/jdk1.4/org/bouncycastle/asn1/ASN1ApplicationSpecific.java deleted file mode 100644 index ddb7fdf5eb..0000000000 --- a/core/src/main/jdk1.4/org/bouncycastle/asn1/ASN1ApplicationSpecific.java +++ /dev/null @@ -1,209 +0,0 @@ -package org.bouncycastle.asn1; - -import java.io.IOException; - -/** - * Base class for an ASN.1 ApplicationSpecific object - * - * @deprecated Will be removed. Change application code to handle as {@link ASN1TaggedObject} only, testing - * for the expected {@link ASN1TaggedObject#getTagClass() tag class} of - * {@link BERTags#APPLICATION} in relevant objects before using. If using a - * {@link ASN1StreamParser stream parser}, handle application-tagged objects using - * {@link ASN1TaggedObjectParser} in the usual way, again testing for a - * {@link ASN1TaggedObjectParser#getTagClass() tag class} of {@link BERTags#APPLICATION}. - */ -public abstract class ASN1ApplicationSpecific - extends ASN1TaggedObject - implements ASN1ApplicationSpecificParser -{ - /** - * Return an ASN1ApplicationSpecific from the passed in object, which may be a byte array, or null. - * - * @param obj the object to be converted. - * @return obj's representation as an ASN1ApplicationSpecific object. - */ - public static ASN1TaggedObject getInstance(Object obj) - { - if (obj == null || obj instanceof ASN1ApplicationSpecific) - { - return (ASN1ApplicationSpecific)obj; - } - else if (obj instanceof byte[]) - { - try - { - return getInstance(ASN1Primitive.fromByteArray((byte[])obj)); - } - catch (IOException e) - { - throw new IllegalArgumentException("Failed to construct object from byte[]: " + e.getMessage()); - } - } - - throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); - } - - final ASN1TaggedObject taggedObject; - - ASN1ApplicationSpecific(ASN1TaggedObject taggedObject) - { - super(taggedObject.explicitness, checkTagClass(taggedObject.tagClass), taggedObject.tagNo, taggedObject.obj); - - this.taggedObject = taggedObject; - } - - /** - * Return the tag number associated with this object, - * - * @return the application tag number. - */ - public int getApplicationTag() - { - return taggedObject.getTagNo(); - } - - /** - * Return the contents of this object as a byte[] - * - * @return the encoded contents of the object. - */ - public byte[] getContents() - { - return taggedObject.getContents(); - } - - /** - * Return the enclosed object assuming explicit tagging. - * - * @return the resulting object - * @throws IOException if reconstruction fails. - */ - public ASN1Primitive getEnclosedObject() throws IOException - { - return taggedObject.getBaseObject().toASN1Primitive(); - } - - /** - * Return the enclosed object assuming implicit tagging. - * - * @param tagNo the type tag that should be applied to the object's contents. - * @return the resulting object - * @throws IOException if reconstruction fails. - */ - public ASN1Primitive getObject(int tagNo) throws IOException - { - return taggedObject.getBaseUniversal(false, tagNo); - } - - public ASN1Encodable getObjectParser(int tag, boolean isExplicit) throws IOException - { - throw new ASN1Exception("this method only valid for CONTEXT_SPECIFIC tags"); - } - - public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException - { - return taggedObject.parseBaseUniversal(declaredExplicit, baseTagNo); - } - - public ASN1Encodable parseExplicitBaseObject() throws IOException - { - return taggedObject.parseExplicitBaseObject(); - } - - public ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException - { - return taggedObject.parseExplicitBaseTagged(); - } - - public ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException - { - return taggedObject.parseImplicitBaseTagged(baseTagClass, baseTagNo); - } - - public boolean hasApplicationTag(int tagNo) - { - return this.tagNo == tagNo; - } - - public boolean hasContextTag(int tagNo) - { - return false; - } - - /** - * ASN1ApplicationSpecific uses an internal ASN1TaggedObject for the - * implementation, and will soon be deprecated in favour of using - * ASN1TaggedObject with a tag class of {@link BERTags#APPLICATION}. This method - * lets you get the internal ASN1TaggedObject so that client code can begin the - * migration. - */ - public ASN1TaggedObject getTaggedObject() - { - return taggedObject; - } - - /** - * Return true if the object is marked as constructed, false otherwise. - * - * @return true if constructed, otherwise false. - */ - public boolean isConstructed() - { - return taggedObject.isConstructed(); - } - - public ASN1Encodable readObject() throws IOException - { - // NOTE: No way to say you're looking for an implicitly-tagged object via ASN1ApplicationSpecificParser - return parseExplicitBaseObject(); - } - - boolean encodeConstructed() - { - return taggedObject.encodeConstructed(); - } - - int encodedLength(boolean withTag) throws IOException - { - return taggedObject.encodedLength(withTag); - } - - void encode(ASN1OutputStream out, boolean withTag) throws IOException - { - taggedObject.encode(out, withTag); - } - - String getASN1Encoding() - { - return taggedObject.getASN1Encoding(); - } - - ASN1Sequence rebuildConstructed(ASN1Primitive primitive) - { - return taggedObject.rebuildConstructed(primitive); - } - - ASN1TaggedObject replaceTag(int tagClass, int tagNo) - { - return taggedObject.replaceTag(tagClass, tagNo); - } - - ASN1Primitive toDERObject() - { - return new DERApplicationSpecific((ASN1TaggedObject)taggedObject.toDERObject()); - } - - ASN1Primitive toDLObject() - { - return new DLApplicationSpecific((ASN1TaggedObject)taggedObject.toDLObject()); - } - - private static int checkTagClass(int tagClass) - { - if (BERTags.APPLICATION != tagClass) - { - throw new IllegalArgumentException(); - } - return tagClass; - } -} diff --git a/core/src/main/jdk1.4/org/bouncycastle/asn1/ASN1ObjectIdentifier.java b/core/src/main/jdk1.4/org/bouncycastle/asn1/ASN1ObjectIdentifier.java index d10c020970..addc076e51 100644 --- a/core/src/main/jdk1.4/org/bouncycastle/asn1/ASN1ObjectIdentifier.java +++ b/core/src/main/jdk1.4/org/bouncycastle/asn1/ASN1ObjectIdentifier.java @@ -22,8 +22,24 @@ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString) } }; + /** + * Implementation limit on the length of the contents octets for an Object Identifier. + *

    + * We adopt the same value used by OpenJDK. In theory there is no limit on the length of the contents, or + * the number of subidentifiers, or the length of individual subidentifiers. In practice, supporting + * arbitrary lengths can lead to issues, e.g. denial-of-service attacks when attempting to convert a + * parsed value to its (decimal) string form. + */ + private static final int MAX_CONTENTS_LENGTH = 4096; + private static final int MAX_IDENTIFIER_LENGTH = MAX_CONTENTS_LENGTH * 4 + 1; + public static ASN1ObjectIdentifier fromContents(byte[] contents) { + if (contents == null) + { + throw new NullPointerException("'contents' cannot be null"); + } + return createPrimitive(contents, true); } @@ -80,9 +96,9 @@ public static ASN1ObjectIdentifier getInstance(ASN1TaggedObject taggedObject, bo * * - see https://github.com/bcgit/bc-java/issues/1015 */ - if (!explicit && !taggedObject.isParsed()) + if (!explicit && !taggedObject.isParsed() && taggedObject.hasContextTag()) { - ASN1Primitive base = taggedObject.getObject(); + ASN1Primitive base = taggedObject.getBaseObject().toASN1Primitive(); if (!(base instanceof ASN1ObjectIdentifier)) { return fromContents(ASN1OctetString.getInstance(base).getOctets()); @@ -92,14 +108,227 @@ public static ASN1ObjectIdentifier getInstance(ASN1TaggedObject taggedObject, bo return (ASN1ObjectIdentifier)TYPE.getContextInstance(taggedObject, explicit); } + public static ASN1ObjectIdentifier tryFromID(String identifier) + { + if (identifier == null) + { + throw new NullPointerException("'identifier' cannot be null"); + } + if (identifier.length() <= MAX_IDENTIFIER_LENGTH && isValidIdentifier(identifier)) + { + byte[] contents = parseIdentifier(identifier); + if (contents.length <= MAX_CONTENTS_LENGTH) + { + return new ASN1ObjectIdentifier(contents, identifier); + } + } + + return null; + } + private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7F; private static final Map pool = new HashMap(); - private final String identifier; - private byte[] contents; + private final byte[] contents; + private String identifier; + + /** + * Create an OID based on the passed in String. + * + * @param identifier a string representation of an OID. + */ + public ASN1ObjectIdentifier(String identifier) + { + checkIdentifier(identifier); + + byte[] contents = parseIdentifier(identifier); + checkContentsLength(contents.length); + + this.contents = contents; + this.identifier = identifier; + } + + private ASN1ObjectIdentifier(byte[] contents, String identifier) + { + this.contents = contents; + this.identifier = identifier; + } + + /** + * Return an OID that creates a branch under the current one. + * + * @param branchID node numbers for the new branch. + * @return the OID for the new created branch. + */ + public ASN1ObjectIdentifier branch(String branchID) + { + ASN1RelativeOID.checkIdentifier(branchID); + + byte[] branchContents = ASN1RelativeOID.parseIdentifier(branchID); + checkContentsLength(this.contents.length + branchContents.length); + + byte[] contents = Arrays.concatenate(this.contents, branchContents); + String identifier = getId() + "." + branchID; + + return new ASN1ObjectIdentifier(contents, identifier); + } + + /** + * Return the OID as a string. + * + * @return the string representation of the OID carried by this object. + */ + public synchronized String getId() + { + if (identifier == null) + { + identifier = parseContents(contents); + } + + return identifier; + } + + /** + * Return true if this oid is an extension of the passed in branch - stem. + * + * @param stem the arc or branch that is a possible parent. + * @return true if the branch is on the passed in stem, false otherwise. + */ + public boolean on(ASN1ObjectIdentifier stem) + { + byte[] contents = this.contents, stemContents = stem.contents; + int stemLength = stemContents.length; + + return contents.length > stemLength + && Arrays.areEqual(contents, 0, stemLength, stemContents, 0, stemLength); + } + + boolean encodeConstructed() + { + return false; + } + + int encodedLength(boolean withTag) + { + return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length); + } + + void encode(ASN1OutputStream out, boolean withTag) throws IOException + { + out.writeEncodingDL(withTag, BERTags.OBJECT_IDENTIFIER, contents); + } + + public int hashCode() + { + return Arrays.hashCode(contents); + } + + boolean asn1Equals(ASN1Primitive other) + { + if (this == other) + { + return true; + } + if (!(other instanceof ASN1ObjectIdentifier)) + { + return false; + } + + ASN1ObjectIdentifier that = (ASN1ObjectIdentifier)other; + + return Arrays.areEqual(this.contents, that.contents); + } + + public String toString() + { + return getId(); + } + + static void checkContentsLength(int contentsLength) + { + if (contentsLength > MAX_CONTENTS_LENGTH) + { + throw new IllegalArgumentException("exceeded OID contents length limit"); + } + } + + static void checkIdentifier(String identifier) + { + if (identifier == null) + { + throw new NullPointerException("'identifier' cannot be null"); + } + if (identifier.length() > MAX_IDENTIFIER_LENGTH) + { + throw new IllegalArgumentException("exceeded OID contents length limit"); + } + if (!isValidIdentifier(identifier)) + { + throw new IllegalArgumentException("string " + identifier + " not a valid OID"); + } + } + + static ASN1ObjectIdentifier createPrimitive(byte[] contents, boolean clone) + { + checkContentsLength(contents.length); + + final OidHandle hdl = new OidHandle(contents); + + synchronized (pool) + { + ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)pool.get(hdl); + if (oid != null) + { + return oid; + } + } + + if (!ASN1RelativeOID.isValidContents(contents)) + { + throw new IllegalArgumentException("invalid OID contents"); + } + + return new ASN1ObjectIdentifier(clone ? Arrays.clone(contents) : contents, null); + } + + private static boolean isValidIdentifier(String identifier) + { + if (identifier.length() < 3 || identifier.charAt(1) != '.') + { + return false; + } + + char first = identifier.charAt(0); + if (first < '0' || first > '2') + { + return false; + } + + if (!ASN1RelativeOID.isValidIdentifier(identifier, 2)) + { + return false; + } + + if (first == '2') + { + return true; + } - ASN1ObjectIdentifier(byte[] contents, boolean clone) + if (identifier.length() == 3 || identifier.charAt(3) == '.') + { + return true; + } + + if (identifier.length() == 4 || identifier.charAt(4) == '.') + { + return identifier.charAt(2) < '4'; + } + + return false; + } + + private static String parseContents(byte[] contents) { StringBuffer objId = new StringBuffer(); long value = 0; @@ -171,92 +400,23 @@ else if (value < 80) } } - this.identifier = objId.toString(); - this.contents = clone ? Arrays.clone(contents) : contents; - } - - /** - * Create an OID based on the passed in String. - * - * @param identifier a string representation of an OID. - */ - public ASN1ObjectIdentifier( - String identifier) - { - if (identifier == null) - { - throw new NullPointerException("'identifier' cannot be null"); - } - if (!isValidIdentifier(identifier)) - { - throw new IllegalArgumentException("string " + identifier + " not an OID"); - } - - this.identifier = identifier; - } - - /** - * Create an OID that creates a branch under the current one. - * - * @param branchID node numbers for the new branch. - * @return the OID for the new created branch. - */ - ASN1ObjectIdentifier(ASN1ObjectIdentifier oid, String branchID) - { - if (!ASN1RelativeOID.isValidIdentifier(branchID, 0)) - { - throw new IllegalArgumentException("string " + branchID + " not a valid OID branch"); - } - - this.identifier = oid.getId() + "." + branchID; - } - - /** - * Return the OID as a string. - * - * @return the string representation of the OID carried by this object. - */ - public String getId() - { - return identifier; - } - - /** - * Return an OID that creates a branch under the current one. - * - * @param branchID node numbers for the new branch. - * @return the OID for the new created branch. - */ - public ASN1ObjectIdentifier branch(String branchID) - { - return new ASN1ObjectIdentifier(this, branchID); - } - - /** - * Return true if this oid is an extension of the passed in branch - stem. - * - * @param stem the arc or branch that is a possible parent. - * @return true if the branch is on the passed in stem, false otherwise. - */ - public boolean on(ASN1ObjectIdentifier stem) - { - String id = getId(), stemId = stem.getId(); - return id.length() > stemId.length() && id.charAt(stemId.length()) == '.' && id.startsWith(stemId); + return objId.toString(); } - private void doOutput(ByteArrayOutputStream aOut) + private static byte[] parseIdentifier(String identifier) { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OIDTokenizer tok = new OIDTokenizer(identifier); int first = Integer.parseInt(tok.nextToken()) * 40; String secondToken = tok.nextToken(); if (secondToken.length() <= 18) { - ASN1RelativeOID.writeField(aOut, first + Long.parseLong(secondToken)); + ASN1RelativeOID.writeField(bOut, first + Long.parseLong(secondToken)); } else { - ASN1RelativeOID.writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first))); + ASN1RelativeOID.writeField(bOut, new BigInteger(secondToken).add(BigInteger.valueOf(first))); } while (tok.hasMoreTokens()) @@ -264,85 +424,15 @@ private void doOutput(ByteArrayOutputStream aOut) String token = tok.nextToken(); if (token.length() <= 18) { - ASN1RelativeOID.writeField(aOut, Long.parseLong(token)); + ASN1RelativeOID.writeField(bOut, Long.parseLong(token)); } else { - ASN1RelativeOID.writeField(aOut, new BigInteger(token)); + ASN1RelativeOID.writeField(bOut, new BigInteger(token)); } } - } - - private synchronized byte[] getContents() - { - if (contents == null) - { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - doOutput(bOut); - contents = bOut.toByteArray(); - } - - return contents; - } - - boolean encodeConstructed() - { - return false; - } - - int encodedLength(boolean withTag) - { - return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContents().length); - } - - void encode(ASN1OutputStream out, boolean withTag) throws IOException - { - out.writeEncodingDL(withTag, BERTags.OBJECT_IDENTIFIER, getContents()); - } - - public int hashCode() - { - return identifier.hashCode(); - } - - boolean asn1Equals( - ASN1Primitive o) - { - if (o == this) - { - return true; - } - - if (!(o instanceof ASN1ObjectIdentifier)) - { - return false; - } - - return identifier.equals(((ASN1ObjectIdentifier)o).identifier); - } - - public String toString() - { - return getId(); - } - - private static boolean isValidIdentifier( - String identifier) - { - if (identifier.length() < 3 || identifier.charAt(1) != '.') - { - return false; - } - - char first = identifier.charAt(0); - if (first < '0' || first > '2') - { - return false; - } - - return ASN1RelativeOID.isValidIdentifier(identifier, 2); + return bOut.toByteArray(); } /** @@ -357,7 +447,7 @@ private static boolean isValidIdentifier( */ public ASN1ObjectIdentifier intern() { - final OidHandle hdl = new OidHandle(getContents()); + final OidHandle hdl = new OidHandle(contents); synchronized (pool) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)pool.get(hdl); @@ -373,7 +463,7 @@ public ASN1ObjectIdentifier intern() } } - private static class OidHandle + static class OidHandle { private final int key; private final byte[] contents; @@ -399,18 +489,4 @@ public boolean equals(Object o) return false; } } - - static ASN1ObjectIdentifier createPrimitive(byte[] contents, boolean clone) - { - final OidHandle hdl = new OidHandle(contents); - synchronized (pool) - { - ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)pool.get(hdl); - if (oid == null) - { - return new ASN1ObjectIdentifier(contents, clone); - } - return oid; - } - } } diff --git a/core/src/main/jdk1.4/org/bouncycastle/asn1/ASN1RelativeOID.java b/core/src/main/jdk1.4/org/bouncycastle/asn1/ASN1RelativeOID.java new file mode 100644 index 0000000000..c46900018b --- /dev/null +++ b/core/src/main/jdk1.4/org/bouncycastle/asn1/ASN1RelativeOID.java @@ -0,0 +1,402 @@ +package org.bouncycastle.asn1; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.util.HashMap; +import java.util.Map; + +import org.bouncycastle.util.Arrays; + +public class ASN1RelativeOID + extends ASN1Primitive +{ + static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1RelativeOID.class, BERTags.RELATIVE_OID) + { + ASN1Primitive fromImplicitPrimitive(DEROctetString octetString) + { + return createPrimitive(octetString.getOctets(), false); + } + }; + + /** + * Implementation limit on the length of the contents octets for a Relative OID. + *

    + * We adopt the same value used by OpenJDK for Object Identifier. In theory there is no limit on the + * length of the contents, or the number of subidentifiers, or the length of individual subidentifiers. In + * practice, supporting arbitrary lengths can lead to issues, e.g. denial-of-service attacks when + * attempting to convert a parsed value to its (decimal) string form. + */ + private static final int MAX_CONTENTS_LENGTH = 4096; + private static final int MAX_IDENTIFIER_LENGTH = MAX_CONTENTS_LENGTH * 4 - 1; + + public static ASN1RelativeOID fromContents(byte[] contents) + { + if (contents == null) + { + throw new NullPointerException("'contents' cannot be null"); + } + + return createPrimitive(contents, true); + } + + public static ASN1RelativeOID getInstance(Object obj) + { + if (obj == null || obj instanceof ASN1RelativeOID) + { + return (ASN1RelativeOID)obj; + } + if (obj instanceof ASN1Encodable) + { + ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive(); + if (primitive instanceof ASN1RelativeOID) + { + return (ASN1RelativeOID)primitive; + } + } + else if (obj instanceof byte[]) + { + byte[] enc = (byte[])obj; + try + { + return (ASN1RelativeOID)TYPE.fromByteArray(enc); + } + catch (IOException e) + { + throw new IllegalArgumentException("failed to construct relative OID from byte[]: " + e.getMessage()); + } + } + + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); + } + + public static ASN1RelativeOID getInstance(ASN1TaggedObject taggedObject, boolean explicit) + { + return (ASN1RelativeOID)TYPE.getContextInstance(taggedObject, explicit); + } + + public static ASN1RelativeOID tryFromID(String identifier) + { + if (identifier == null) + { + throw new NullPointerException("'identifier' cannot be null"); + } + if (identifier.length() <= MAX_IDENTIFIER_LENGTH && isValidIdentifier(identifier, 0)) + { + byte[] contents = parseIdentifier(identifier); + if (contents.length <= MAX_CONTENTS_LENGTH) + { + return new ASN1RelativeOID(contents, identifier); + } + } + + return null; + } + + private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7F; + + private static final Map pool = new HashMap(); + + private final byte[] contents; + private String identifier; + + public ASN1RelativeOID(String identifier) + { + checkIdentifier(identifier); + + byte[] contents = parseIdentifier(identifier); + checkContentsLength(contents.length); + + this.contents = contents; + this.identifier = identifier; + } + + private ASN1RelativeOID(byte[] contents, String identifier) + { + this.contents = contents; + this.identifier = identifier; + } + + public ASN1RelativeOID branch(String branchID) + { + checkIdentifier(branchID); + + byte[] branchContents = parseIdentifier(branchID); + checkContentsLength(this.contents.length + branchContents.length); + + byte[] contents = Arrays.concatenate(this.contents, branchContents); + String identifier = getId() + "." + branchID; + + return new ASN1RelativeOID(contents, identifier); + } + + public synchronized String getId() + { + if (identifier == null) + { + identifier = parseContents(contents); + } + + return identifier; + } + + public int hashCode() + { + return Arrays.hashCode(contents); + } + + public String toString() + { + return getId(); + } + + boolean asn1Equals(ASN1Primitive other) + { + if (this == other) + { + return true; + } + if (!(other instanceof ASN1RelativeOID)) + { + return false; + } + + ASN1RelativeOID that = (ASN1RelativeOID)other; + + return Arrays.areEqual(this.contents, that.contents); + } + + int encodedLength(boolean withTag) + { + return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length); + } + + void encode(ASN1OutputStream out, boolean withTag) throws IOException + { + out.writeEncodingDL(withTag, BERTags.RELATIVE_OID, contents); + } + + boolean encodeConstructed() + { + return false; + } + + static void checkContentsLength(int contentsLength) + { + if (contentsLength > MAX_CONTENTS_LENGTH) + { + throw new IllegalArgumentException("exceeded relative OID contents length limit"); + } + } + + static void checkIdentifier(String identifier) + { + if (identifier == null) + { + throw new NullPointerException("'identifier' cannot be null"); + } + if (identifier.length() > MAX_IDENTIFIER_LENGTH) + { + throw new IllegalArgumentException("exceeded relative OID contents length limit"); + } + if (!isValidIdentifier(identifier, 0)) + { + throw new IllegalArgumentException("string " + identifier + " not a valid relative OID"); + } + } + + static ASN1RelativeOID createPrimitive(byte[] contents, boolean clone) + { + checkContentsLength(contents.length); + + final ASN1ObjectIdentifier.OidHandle hdl = new ASN1ObjectIdentifier.OidHandle(contents); + synchronized (pool) + { + ASN1RelativeOID oid = (ASN1RelativeOID)pool.get(hdl); + if (oid != null) + { + return oid; + } + } + + if (!isValidContents(contents)) + { + throw new IllegalArgumentException("invalid relative OID contents"); + } + + return new ASN1RelativeOID(clone ? Arrays.clone(contents) : contents, null); + } + + static boolean isValidContents(byte[] contents) + { + if (contents.length < 1) + { + return false; + } + + boolean subIDStart = true; + for (int i = 0; i < contents.length; ++i) + { + if (subIDStart && (contents[i] & 0xff) == 0x80) + return false; + + subIDStart = (contents[i] & 0x80) == 0; + } + + return subIDStart; + } + + static boolean isValidIdentifier(String identifier, int from) + { + int digitCount = 0; + + int pos = identifier.length(); + while (--pos >= from) + { + char ch = identifier.charAt(pos); + + if (ch == '.') + { + if (0 == digitCount || (digitCount > 1 && identifier.charAt(pos + 1) == '0')) + { + return false; + } + + digitCount = 0; + } + else if ('0' <= ch && ch <= '9') + { + ++digitCount; + } + else + { + return false; + } + } + + if (0 == digitCount || (digitCount > 1 && identifier.charAt(pos + 1) == '0')) + { + return false; + } + + return true; + } + + static String parseContents(byte[] contents) + { + StringBuffer objId = new StringBuffer(); + long value = 0; + BigInteger bigValue = null; + boolean first = true; + + for (int i = 0; i != contents.length; i++) + { + int b = contents[i] & 0xff; + + if (value <= LONG_LIMIT) + { + value += b & 0x7F; + if ((b & 0x80) == 0) + { + if (first) + { + first = false; + } + else + { + objId.append('.'); + } + + objId.append(value); + value = 0; + } + else + { + value <<= 7; + } + } + else + { + if (bigValue == null) + { + bigValue = BigInteger.valueOf(value); + } + bigValue = bigValue.or(BigInteger.valueOf(b & 0x7F)); + if ((b & 0x80) == 0) + { + if (first) + { + first = false; + } + else + { + objId.append('.'); + } + + objId.append(bigValue); + bigValue = null; + value = 0; + } + else + { + bigValue = bigValue.shiftLeft(7); + } + } + } + + return objId.toString(); + } + + static byte[] parseIdentifier(String identifier) + { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + OIDTokenizer tok = new OIDTokenizer(identifier); + while (tok.hasMoreTokens()) + { + String token = tok.nextToken(); + if (token.length() <= 18) + { + writeField(bOut, Long.parseLong(token)); + } + else + { + writeField(bOut, new BigInteger(token)); + } + } + return bOut.toByteArray(); + } + + static void writeField(ByteArrayOutputStream out, long fieldValue) + { + byte[] result = new byte[9]; + int pos = 8; + result[pos] = (byte)((int)fieldValue & 0x7F); + while (fieldValue >= (1L << 7)) + { + fieldValue >>= 7; + result[--pos] = (byte)((int)fieldValue | 0x80); + } + out.write(result, pos, 9 - pos); + } + + static void writeField(ByteArrayOutputStream out, BigInteger fieldValue) + { + int byteCount = (fieldValue.bitLength() + 6) / 7; + if (byteCount == 0) + { + out.write(0); + } + else + { + BigInteger tmpValue = fieldValue; + byte[] tmp = new byte[byteCount]; + for (int i = byteCount - 1; i >= 0; i--) + { + tmp[i] = (byte)(tmpValue.intValue() | 0x80); + tmpValue = tmpValue.shiftRight(7); + } + tmp[byteCount - 1] &= 0x7F; + out.write(tmp, 0, tmp.length); + } + } +} diff --git a/core/src/main/jdk1.4/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java b/core/src/main/jdk1.4/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java index cbbbd2ab14..51e908fa09 100644 --- a/core/src/main/jdk1.4/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java +++ b/core/src/main/jdk1.4/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java @@ -9,9 +9,9 @@ import java.util.Map; import java.util.Set; +import org.bouncycastle.asn1.ASN1IA5String; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.IETFUtils; @@ -71,14 +71,14 @@ public void checkPermitted(GeneralName name) extractNameAsString(name)); break; case GeneralName.dNSName: - checkPermittedDNS(permittedSubtreesDNS, DERIA5String.getInstance( + checkPermittedDNS(permittedSubtreesDNS, ASN1IA5String.getInstance( name.getName()).getString()); break; case GeneralName.directoryName: checkPermittedDN(X500Name.getInstance(name.getName())); break; case GeneralName.uniformResourceIdentifier: - checkPermittedURI(permittedSubtreesURI, DERIA5String.getInstance( + checkPermittedURI(permittedSubtreesURI, ASN1IA5String.getInstance( name.getName()).getString()); break; case GeneralName.iPAddress: @@ -110,14 +110,14 @@ public void checkExcluded(GeneralName name) checkExcludedEmail(excludedSubtreesEmail, extractNameAsString(name)); break; case GeneralName.dNSName: - checkExcludedDNS(excludedSubtreesDNS, DERIA5String.getInstance( + checkExcludedDNS(excludedSubtreesDNS, ASN1IA5String.getInstance( name.getName()).getString()); break; case GeneralName.directoryName: checkExcludedDN(X500Name.getInstance(name.getName())); break; case GeneralName.uniformResourceIdentifier: - checkExcludedURI(excludedSubtreesURI, DERIA5String.getInstance( + checkExcludedURI(excludedSubtreesURI, ASN1IA5String.getInstance( name.getName()).getString()); break; case GeneralName.iPAddress: @@ -1830,7 +1830,7 @@ private static String extractHostFromURL(String url) private String extractNameAsString(GeneralName name) { - return DERIA5String.getInstance(name.getName()).getString(); + return ASN1IA5String.getInstance(name.getName()).getString(); } /** diff --git a/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java b/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java index 13ae25c3c5..1d3d697c5d 100644 --- a/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java +++ b/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java @@ -3,20 +3,57 @@ import java.io.IOException; import java.io.InputStream; +import org.bouncycastle.asn1.ASN1BitString; +import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.pqc.asn1.CMCEPrivateKey; +import org.bouncycastle.pqc.asn1.FalconPrivateKey; +import org.bouncycastle.pqc.asn1.McElieceCCA2PrivateKey; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; +import org.bouncycastle.pqc.asn1.SPHINCSPLUSPrivateKey; +import org.bouncycastle.pqc.asn1.SPHINCSPLUSPublicKey; +import org.bouncycastle.pqc.crypto.bike.BIKEParameters; +import org.bouncycastle.pqc.crypto.bike.BIKEPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCPrivateKeyParameters; import org.bouncycastle.pqc.crypto.newhope.NHPrivateKeyParameters; -import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLAPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.ntru.NTRUParameters; +import org.bouncycastle.pqc.crypto.ntru.NTRUPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeParameters; +import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePrivateKeyParameters; +import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeParameters; +import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimePrivateKeyParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.saber.SABERParameters; +import org.bouncycastle.pqc.crypto.saber.SABERPrivateKeyParameters; import org.bouncycastle.pqc.crypto.sphincs.SPHINCSPrivateKeyParameters; - +import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusParameters; +import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusPrivateKeyParameters; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Pack; /** @@ -26,55 +63,229 @@ public class PrivateKeyFactory { /** * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding. - * + * * @param privateKeyInfoData the PrivateKeyInfo encoding * @return a suitable private key parameter * @throws IOException on an error decoding the key */ - public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData) throws IOException + public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData) + throws IOException { + if (privateKeyInfoData == null) + { + throw new IllegalArgumentException("privateKeyInfoData array null"); + } + if (privateKeyInfoData.length == 0) + { + throw new IllegalArgumentException("privateKeyInfoData array empty"); + } return createKey(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(privateKeyInfoData))); } /** * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding read from a * stream. - * + * * @param inStr the stream to read the PrivateKeyInfo encoding from * @return a suitable private key parameter * @throws IOException on an error decoding the key */ - public static AsymmetricKeyParameter createKey(InputStream inStr) throws IOException + public static AsymmetricKeyParameter createKey(InputStream inStr) + throws IOException { return createKey(PrivateKeyInfo.getInstance(new ASN1InputStream(inStr).readObject())); } /** * Create a private key parameter from the passed in PKCS8 PrivateKeyInfo object. - * + * * @param keyInfo the PrivateKeyInfo object containing the key material * @return a suitable private key parameter * @throws IOException on an error decoding the key */ - public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo) throws IOException + public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo) + throws IOException { + if (keyInfo == null) + { + throw new IllegalArgumentException("keyInfo array null"); + } + AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm(); ASN1ObjectIdentifier algOID = algId.getAlgorithm(); - if (algOID.on(BCObjectIdentifiers.qTESLA)) + if (algOID.equals(PQCObjectIdentifiers.sphincs256)) + { + return new SPHINCSPrivateKeyParameters(ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(), + Utils.sphincs256LookupTreeAlgName(SPHINCS256KeyParams.getInstance(algId.getParameters()))); + } + else if (algOID.equals(PQCObjectIdentifiers.newHope)) + { + return new NHPrivateKeyParameters(convert(ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets())); + } + else if (algOID.on(BCObjectIdentifiers.sphincsPlus) || algOID.on(BCObjectIdentifiers.sphincsPlus_interop)) { - ASN1OctetString qTESLAPriv = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()); + SPHINCSPlusParameters spParams = Utils.sphincsPlusParamsLookup(algOID); - return new QTESLAPrivateKeyParameters(Utils.qTeslaLookupSecurityCategory(keyInfo.getPrivateKeyAlgorithm()), qTESLAPriv.getOctets()); + ASN1Encodable obj = keyInfo.parsePrivateKey(); + if (obj instanceof ASN1Sequence) + { + SPHINCSPLUSPrivateKey spKey = SPHINCSPLUSPrivateKey.getInstance(obj); + SPHINCSPLUSPublicKey publicKey = spKey.getPublicKey(); + return new SPHINCSPlusPrivateKeyParameters(spParams, spKey.getSkseed(), spKey.getSkprf(), + publicKey.getPkseed(), publicKey.getPkroot()); + } + else + { + return new SPHINCSPlusPrivateKeyParameters(spParams, ASN1OctetString.getInstance(obj).getOctets()); + } } - else if (algOID.equals(BCObjectIdentifiers.sphincs256)) + else if (algOID.on(BCObjectIdentifiers.picnic)) { - return new SPHINCSPrivateKeyParameters(ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(), - Utils.sphincs256LookupTreeAlgName(SPHINCS256KeyParams.getInstance(keyInfo.getPrivateKeyAlgorithm().getParameters()))); + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); + PicnicParameters pParams = Utils.picnicParamsLookup(algOID); + + return new PicnicPrivateKeyParameters(pParams, keyEnc); } - else if (algOID.equals(BCObjectIdentifiers.newHope)) + else if (algOID.on(BCObjectIdentifiers.pqc_kem_mceliece)) { - return new NHPrivateKeyParameters(convert(ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets())); + CMCEPrivateKey cmceKey = CMCEPrivateKey.getInstance(keyInfo.parsePrivateKey()); + CMCEParameters spParams = Utils.mcElieceParamsLookup(algOID); + + return new CMCEPrivateKeyParameters(spParams, cmceKey.getDelta(), cmceKey.getC(), cmceKey.getG(), cmceKey.getAlpha(), cmceKey.getS()); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_frodo)) + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); + FrodoParameters spParams = Utils.frodoParamsLookup(algOID); + + return new FrodoPrivateKeyParameters(spParams, keyEnc); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_saber)) + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); + SABERParameters spParams = Utils.saberParamsLookup(algOID); + + return new SABERPrivateKeyParameters(spParams, keyEnc); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_ntru)) + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); + NTRUParameters spParams = Utils.ntruParamsLookup(algOID); + + return new NTRUPrivateKeyParameters(spParams, keyEnc); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_kyber)) + { + ASN1OctetString kyberKey = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()); + KyberParameters kyberParams = Utils.kyberParamsLookup(algOID); + + return new KyberPrivateKeyParameters(kyberParams, kyberKey.getOctets()); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_ntrulprime)) + { + ASN1Sequence keyEnc = ASN1Sequence.getInstance(keyInfo.parsePrivateKey()); + + NTRULPRimeParameters spParams = Utils.ntrulprimeParamsLookup(algOID); + + return new NTRULPRimePrivateKeyParameters(spParams, + ASN1OctetString.getInstance(keyEnc.getObjectAt(0)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(1)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(2)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(3)).getOctets()); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_sntruprime)) + { + ASN1Sequence keyEnc = ASN1Sequence.getInstance(keyInfo.parsePrivateKey()); + + SNTRUPrimeParameters spParams = Utils.sntruprimeParamsLookup(algOID); + + return new SNTRUPrimePrivateKeyParameters(spParams, + ASN1OctetString.getInstance(keyEnc.getObjectAt(0)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(1)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(2)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(3)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(4)).getOctets()); + } + else if (algOID.equals(BCObjectIdentifiers.dilithium2) + || algOID.equals(BCObjectIdentifiers.dilithium3) || algOID.equals(BCObjectIdentifiers.dilithium5)) + { + ASN1Encodable keyObj = keyInfo.parsePrivateKey(); + DilithiumParameters spParams = Utils.dilithiumParamsLookup(algOID); + + if (keyObj instanceof ASN1Sequence) + { + ASN1Sequence keyEnc = ASN1Sequence.getInstance(keyObj); + + int version = ASN1Integer.getInstance(keyEnc.getObjectAt(0)).intValueExact(); + if (version != 0) + { + throw new IOException("unknown private key version: " + version); + } + + if (keyInfo.getPublicKeyData() != null) + { + DilithiumPublicKeyParameters pubParams = PublicKeyFactory.DilithiumConverter.getPublicKeyParams(spParams, keyInfo.getPublicKeyData()); + + return new DilithiumPrivateKeyParameters(spParams, + ASN1BitString.getInstance(keyEnc.getObjectAt(1)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(2)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(3)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(4)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(5)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(6)).getOctets(), + pubParams.getT1()); // encT1 + } + else + { + return new DilithiumPrivateKeyParameters(spParams, + ASN1BitString.getInstance(keyEnc.getObjectAt(1)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(2)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(3)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(4)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(5)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(6)).getOctets(), + null); + } + } + else if (keyObj instanceof DEROctetString) + { + byte[] data = ASN1OctetString.getInstance(keyObj).getOctets(); + if (keyInfo.getPublicKeyData() != null) + { + DilithiumPublicKeyParameters pubParams = PublicKeyFactory.DilithiumConverter.getPublicKeyParams(spParams, keyInfo.getPublicKeyData()); + return new DilithiumPrivateKeyParameters(spParams, data, pubParams); + } + return new DilithiumPrivateKeyParameters(spParams, data, null); + } + else + { + throw new IOException("not supported"); + } + } + else if (algOID.equals(BCObjectIdentifiers.falcon_512) || algOID.equals(BCObjectIdentifiers.falcon_1024)) + { + FalconPrivateKey falconKey = FalconPrivateKey.getInstance(keyInfo.parsePrivateKey()); + FalconParameters falconParams = Utils.falconParamsLookup(algOID); + + return new FalconPrivateKeyParameters(falconParams, falconKey.getf(), falconKey.getG(), falconKey.getF(), falconKey.getPublicKey().getH()); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_bike)) + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); + BIKEParameters bikeParams = Utils.bikeParamsLookup(algOID); + + byte[] h0 = Arrays.copyOfRange(keyEnc, 0, bikeParams.getRByte()); + byte[] h1 = Arrays.copyOfRange(keyEnc, bikeParams.getRByte(), 2 * bikeParams.getRByte()); + byte[] sigma = Arrays.copyOfRange(keyEnc, 2 * bikeParams.getRByte(), keyEnc.length); + return new BIKEPrivateKeyParameters(bikeParams, h0, h1, sigma); + } + else if (algOID.on(BCObjectIdentifiers.pqc_kem_hqc)) + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); + HQCParameters hqcParams = Utils.hqcParamsLookup(algOID); + + return new HQCPrivateKeyParameters(hqcParams, keyEnc); } else { diff --git a/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java b/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java index 89a86053ce..008be2b28b 100644 --- a/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java +++ b/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java @@ -2,16 +2,37 @@ import java.io.IOException; +import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.pqc.asn1.CMCEPrivateKey; +import org.bouncycastle.pqc.asn1.CMCEPublicKey; +import org.bouncycastle.pqc.asn1.FalconPrivateKey; +import org.bouncycastle.pqc.asn1.FalconPublicKey; +import org.bouncycastle.pqc.asn1.McElieceCCA2PrivateKey; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; +import org.bouncycastle.pqc.crypto.bike.BIKEPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCPrivateKeyParameters; import org.bouncycastle.pqc.crypto.newhope.NHPrivateKeyParameters; -import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLAPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.ntru.NTRUPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePrivateKeyParameters; +import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimePrivateKeyParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.saber.SABERPrivateKeyParameters; import org.bouncycastle.pqc.crypto.sphincs.SPHINCSPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusPrivateKeyParameters; import org.bouncycastle.util.Pack; /** @@ -21,7 +42,6 @@ public class PrivateKeyInfoFactory { private PrivateKeyInfoFactory() { - } /** @@ -46,19 +66,11 @@ public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter private */ public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter privateKey, ASN1Set attributes) throws IOException { - if (privateKey instanceof QTESLAPrivateKeyParameters) - { - QTESLAPrivateKeyParameters keyParams = (QTESLAPrivateKeyParameters)privateKey; - - AlgorithmIdentifier algorithmIdentifier = Utils.qTeslaLookupAlgID(keyParams.getSecurityCategory()); - - return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(keyParams.getSecret()), attributes); - } - else if (privateKey instanceof SPHINCSPrivateKeyParameters) + if (privateKey instanceof SPHINCSPrivateKeyParameters) { SPHINCSPrivateKeyParameters params = (SPHINCSPrivateKeyParameters)privateKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.sphincs256, - new SPHINCS256KeyParams(Utils.sphincs256LookupTreeAlgID(params.getTreeDigest()))); + new SPHINCS256KeyParams(Utils.sphincs256LookupTreeAlgID(params.getTreeDigest()))); return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getKeyData())); } @@ -78,6 +90,140 @@ else if (privateKey instanceof NHPrivateKeyParameters) return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(octets)); } + else if (privateKey instanceof SPHINCSPlusPrivateKeyParameters) + { + SPHINCSPlusPrivateKeyParameters params = (SPHINCSPlusPrivateKeyParameters)privateKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.sphincsPlusOidLookup(params.getParameters())); + + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getEncoded()), attributes, params.getPublicKey()); + } + else if (privateKey instanceof PicnicPrivateKeyParameters) + { + PicnicPrivateKeyParameters params = (PicnicPrivateKeyParameters)privateKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.picnicOidLookup(params.getParameters())); + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); + } + else if (privateKey instanceof CMCEPrivateKeyParameters) + { + CMCEPrivateKeyParameters params = (CMCEPrivateKeyParameters)privateKey; + + //todo either make CMCEPrivateKey split the parameters from the private key or + // (current) Make CMCEPrivateKey take parts of the private key splitted in the params + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.mcElieceOidLookup(params.getParameters())); + + CMCEPublicKey cmcePub = new CMCEPublicKey(params.reconstructPublicKey()); + CMCEPrivateKey cmcePriv = new CMCEPrivateKey(0, params.getDelta(), params.getC(), params.getG(), params.getAlpha(), params.getS(), cmcePub); + return new PrivateKeyInfo(algorithmIdentifier, cmcePriv, attributes); + } + else if (privateKey instanceof FrodoPrivateKeyParameters) + { + FrodoPrivateKeyParameters params = (FrodoPrivateKeyParameters)privateKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.frodoOidLookup(params.getParameters())); + + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); + } + else if (privateKey instanceof SABERPrivateKeyParameters) + { + SABERPrivateKeyParameters params = (SABERPrivateKeyParameters)privateKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.saberOidLookup(params.getParameters())); + + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); + } + else if (privateKey instanceof NTRUPrivateKeyParameters) + { + NTRUPrivateKeyParameters params = (NTRUPrivateKeyParameters)privateKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.ntruOidLookup(params.getParameters())); + + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); + } + else if (privateKey instanceof FalconPrivateKeyParameters) + { + FalconPrivateKeyParameters params = (FalconPrivateKeyParameters)privateKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.falconOidLookup(params.getParameters())); + + FalconPublicKey falconPub = new FalconPublicKey(params.getPublicKey()); + FalconPrivateKey falconPriv = new FalconPrivateKey(0, params.getSpolyf(), params.getG(), params.getSpolyF(), falconPub); + + return new PrivateKeyInfo(algorithmIdentifier, falconPriv, attributes); + } + else if (privateKey instanceof KyberPrivateKeyParameters) + { + KyberPrivateKeyParameters params = (KyberPrivateKeyParameters)privateKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.kyberOidLookup(params.getParameters())); + + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getEncoded()), attributes); + } + else if (privateKey instanceof NTRULPRimePrivateKeyParameters) + { + NTRULPRimePrivateKeyParameters params = (NTRULPRimePrivateKeyParameters)privateKey; + + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(new DEROctetString(params.getEnca())); + v.add(new DEROctetString(params.getPk())); + v.add(new DEROctetString(params.getRho())); + v.add(new DEROctetString(params.getHash())); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.ntrulprimeOidLookup(params.getParameters())); + + return new PrivateKeyInfo(algorithmIdentifier, new DERSequence(v), attributes); + } + else if (privateKey instanceof SNTRUPrimePrivateKeyParameters) + { + SNTRUPrimePrivateKeyParameters params = (SNTRUPrimePrivateKeyParameters)privateKey; + + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(new DEROctetString(params.getF())); + v.add(new DEROctetString(params.getGinv())); + v.add(new DEROctetString(params.getPk())); + v.add(new DEROctetString(params.getRho())); + v.add(new DEROctetString(params.getHash())); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.sntruprimeOidLookup(params.getParameters())); + + return new PrivateKeyInfo(algorithmIdentifier, new DERSequence(v), attributes); + } + else if (privateKey instanceof DilithiumPrivateKeyParameters) + { + DilithiumPrivateKeyParameters params = (DilithiumPrivateKeyParameters)privateKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.dilithiumOidLookup(params.getParameters())); + + DilithiumPublicKeyParameters pubParams = params.getPublicKeyParameters(); + + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getEncoded()), attributes, pubParams.getEncoded()); + } + else if (privateKey instanceof BIKEPrivateKeyParameters) + { + BIKEPrivateKeyParameters params = (BIKEPrivateKeyParameters)privateKey; + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.bikeOidLookup(params.getParameters())); + byte[] encoding = params.getEncoded(); + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); + } + else if (privateKey instanceof HQCPrivateKeyParameters) + { + HQCPrivateKeyParameters params = (HQCPrivateKeyParameters)privateKey; + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.hqcOidLookup(params.getParameters())); + byte[] encoding = params.getEncoded(); + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); + } else { throw new IOException("key parameters not recognized"); diff --git a/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java b/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java index 52eeaa2cf6..02af5585da 100644 --- a/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java +++ b/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java @@ -5,18 +5,52 @@ import java.util.HashMap; import java.util.Map; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.internal.asn1.isara.IsaraObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.pqc.asn1.CMCEPublicKey; +import org.bouncycastle.pqc.asn1.KyberPublicKey; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; +import org.bouncycastle.pqc.crypto.bike.BIKEParameters; +import org.bouncycastle.pqc.crypto.bike.BIKEPublicKeyParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEPublicKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberPublicKeyParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconPublicKeyParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoPublicKeyParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCPublicKeyParameters; import org.bouncycastle.pqc.crypto.newhope.NHPublicKeyParameters; -import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLAPublicKeyParameters; +import org.bouncycastle.pqc.crypto.ntru.NTRUParameters; +import org.bouncycastle.pqc.crypto.ntru.NTRUPublicKeyParameters; +import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeParameters; +import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePublicKeyParameters; +import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeParameters; +import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimePublicKeyParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicPublicKeyParameters; +import org.bouncycastle.pqc.crypto.saber.SABERParameters; +import org.bouncycastle.pqc.crypto.saber.SABERPublicKeyParameters; import org.bouncycastle.pqc.crypto.sphincs.SPHINCSPublicKeyParameters; +import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusParameters; +import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusPublicKeyParameters; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Pack; /** * Factory to create asymmetric public key parameters for asymmetric ciphers from range of @@ -28,16 +62,143 @@ public class PublicKeyFactory static { - converters.put(BCObjectIdentifiers.qTESLA_Rnd1_I, new QTeslaConverter()); - converters.put(BCObjectIdentifiers.qTESLA_Rnd1_III_size, new QTeslaConverter()); - converters.put(BCObjectIdentifiers.qTESLA_Rnd1_III_speed, new QTeslaConverter()); - converters.put(BCObjectIdentifiers.qTESLA_Rnd1_p_I, new QTeslaConverter()); - converters.put(BCObjectIdentifiers.qTESLA_Rnd1_p_III, new QTeslaConverter()); - - converters.put(PQCObjectIdentifiers.qTESLA_p_I, new QTeslaConverter()); - converters.put(PQCObjectIdentifiers.qTESLA_p_III, new QTeslaConverter()); converters.put(PQCObjectIdentifiers.sphincs256, new SPHINCSConverter()); converters.put(PQCObjectIdentifiers.newHope, new NHConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, new SPHINCSPlusConverter()); + + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple, new SPHINCSPlusConverter()); + + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_128s, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_128f, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_128s, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_128f, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_192s, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_192f, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_192s, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_192f, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_256s, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_sha2_256f, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_256s, new SPHINCSPlusConverter()); + converters.put(BCObjectIdentifiers.sphincsPlus_shake_256f, new SPHINCSPlusConverter()); + converters.put(new ASN1ObjectIdentifier("1.3.9999.6.4.10"), new SPHINCSPlusConverter()); + + converters.put(BCObjectIdentifiers.mceliece348864_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece348864f_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece460896_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece460896f_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece6688128_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece6688128f_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece6960119_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece6960119f_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece8192128_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.mceliece8192128f_r3, new CMCEConverter()); + converters.put(BCObjectIdentifiers.frodokem640aes, new FrodoConverter()); + converters.put(BCObjectIdentifiers.frodokem640shake, new FrodoConverter()); + converters.put(BCObjectIdentifiers.frodokem976aes, new FrodoConverter()); + converters.put(BCObjectIdentifiers.frodokem976shake, new FrodoConverter()); + converters.put(BCObjectIdentifiers.frodokem1344aes, new FrodoConverter()); + converters.put(BCObjectIdentifiers.frodokem1344shake, new FrodoConverter()); + converters.put(BCObjectIdentifiers.lightsaberkem128r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.saberkem128r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.firesaberkem128r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.lightsaberkem192r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.saberkem192r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.firesaberkem192r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.lightsaberkem256r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.saberkem256r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.firesaberkem256r3, new SABERConverter()); + converters.put(BCObjectIdentifiers.ulightsaberkemr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.usaberkemr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.ufiresaberkemr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.lightsaberkem90sr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.saberkem90sr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.firesaberkem90sr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.ulightsaberkem90sr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.usaberkem90sr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.ufiresaberkem90sr3, new SABERConverter()); + converters.put(BCObjectIdentifiers.picnicl1fs, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl1ur, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl3fs, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl3ur, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl5fs, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl5ur, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnic3l1, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnic3l3, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnic3l5, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl1full, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl3full, new PicnicConverter()); + converters.put(BCObjectIdentifiers.picnicl5full, new PicnicConverter()); + converters.put(BCObjectIdentifiers.ntruhps2048509, new NtruConverter()); + converters.put(BCObjectIdentifiers.ntruhps2048677, new NtruConverter()); + converters.put(BCObjectIdentifiers.ntruhps4096821, new NtruConverter()); + converters.put(BCObjectIdentifiers.ntruhrss701, new NtruConverter()); + converters.put(BCObjectIdentifiers.falcon_512, new FalconConverter()); + converters.put(BCObjectIdentifiers.falcon_1024, new FalconConverter()); + converters.put(BCObjectIdentifiers.kyber512, new KyberConverter()); + converters.put(BCObjectIdentifiers.kyber768, new KyberConverter()); + converters.put(BCObjectIdentifiers.kyber1024, new KyberConverter()); + converters.put(BCObjectIdentifiers.kyber512_aes, new KyberConverter()); + converters.put(BCObjectIdentifiers.kyber768_aes, new KyberConverter()); + converters.put(BCObjectIdentifiers.kyber1024_aes, new KyberConverter()); + converters.put(BCObjectIdentifiers.ntrulpr653, new NTRULPrimeConverter()); + converters.put(BCObjectIdentifiers.ntrulpr761, new NTRULPrimeConverter()); + converters.put(BCObjectIdentifiers.ntrulpr857, new NTRULPrimeConverter()); + converters.put(BCObjectIdentifiers.ntrulpr953, new NTRULPrimeConverter()); + converters.put(BCObjectIdentifiers.ntrulpr1013, new NTRULPrimeConverter()); + converters.put(BCObjectIdentifiers.ntrulpr1277, new NTRULPrimeConverter()); + converters.put(BCObjectIdentifiers.sntrup653, new SNTRUPrimeConverter()); + converters.put(BCObjectIdentifiers.sntrup761, new SNTRUPrimeConverter()); + converters.put(BCObjectIdentifiers.sntrup857, new SNTRUPrimeConverter()); + converters.put(BCObjectIdentifiers.sntrup953, new SNTRUPrimeConverter()); + converters.put(BCObjectIdentifiers.sntrup1013, new SNTRUPrimeConverter()); + converters.put(BCObjectIdentifiers.sntrup1277, new SNTRUPrimeConverter()); + converters.put(BCObjectIdentifiers.dilithium2, new DilithiumConverter()); + converters.put(BCObjectIdentifiers.dilithium3, new DilithiumConverter()); + converters.put(BCObjectIdentifiers.dilithium5, new DilithiumConverter()); + converters.put(BCObjectIdentifiers.dilithium2_aes, new DilithiumConverter()); + converters.put(BCObjectIdentifiers.dilithium3_aes, new DilithiumConverter()); + converters.put(BCObjectIdentifiers.dilithium5_aes, new DilithiumConverter()); + converters.put(BCObjectIdentifiers.bike128, new BIKEConverter()); + converters.put(BCObjectIdentifiers.bike192, new BIKEConverter()); + converters.put(BCObjectIdentifiers.bike256, new BIKEConverter()); + converters.put(BCObjectIdentifiers.hqc128, new HQCConverter()); + converters.put(BCObjectIdentifiers.hqc192, new HQCConverter()); + converters.put(BCObjectIdentifiers.hqc256, new HQCConverter()); } /** @@ -50,6 +211,14 @@ public class PublicKeyFactory public static AsymmetricKeyParameter createKey(byte[] keyInfoData) throws IOException { + if (keyInfoData == null) + { + throw new IllegalArgumentException("keyInfoData array null"); + } + if (keyInfoData.length == 0) + { + throw new IllegalArgumentException("keyInfoData array empty"); + } return createKey(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(keyInfoData))); } @@ -76,13 +245,17 @@ public static AsymmetricKeyParameter createKey(InputStream inStr) public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo) throws IOException { + if (keyInfo == null) + { + throw new IllegalArgumentException("keyInfo argument null"); + } return createKey(keyInfo, null); } /** * Create a public key from the passed in SubjectPublicKeyInfo * - * @param keyInfo the SubjectPublicKeyInfo containing the key data + * @param keyInfo the SubjectPublicKeyInfo containing the key data * @param defaultParams default parameters that might be needed. * @return the appropriate key parameter * @throws IOException on an error decoding the key @@ -90,6 +263,11 @@ public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo) public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Object defaultParams) throws IOException { + if (keyInfo == null) + { + throw new IllegalArgumentException("keyInfo argument null"); + } + AlgorithmIdentifier algId = keyInfo.getAlgorithm(); SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)converters.get(algId.getAlgorithm()); @@ -109,34 +287,288 @@ abstract AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyI throws IOException; } - private static class QTeslaConverter + private static class SPHINCSConverter extends SubjectPublicKeyInfoConverter { AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) throws IOException { - return new QTESLAPublicKeyParameters(Utils.qTeslaLookupSecurityCategory(keyInfo.getAlgorithm()), keyInfo.getPublicKeyData().getOctets()); + return new SPHINCSPublicKeyParameters(keyInfo.getPublicKeyData().getBytes(), + Utils.sphincs256LookupTreeAlgName(SPHINCS256KeyParams.getInstance(keyInfo.getAlgorithm().getParameters()))); } } - private static class SPHINCSConverter + private static class NHConverter extends SubjectPublicKeyInfoConverter { AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) throws IOException { - return new SPHINCSPublicKeyParameters(keyInfo.getPublicKeyData().getBytes(), - Utils.sphincs256LookupTreeAlgName(SPHINCS256KeyParams.getInstance(keyInfo.getAlgorithm().getParameters()))); + return new NHPublicKeyParameters(keyInfo.getPublicKeyData().getBytes()); } } - private static class NHConverter + private static class SPHINCSPlusConverter extends SubjectPublicKeyInfoConverter { AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) throws IOException { - return new NHPublicKeyParameters(keyInfo.getPublicKeyData().getBytes()); + try + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + SPHINCSPlusParameters spParams = Utils.sphincsPlusParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new SPHINCSPlusPublicKeyParameters(spParams, Arrays.copyOfRange(keyEnc, 4, keyEnc.length)); + } + catch (Exception e) + { + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); + + SPHINCSPlusParameters spParams = Utils.sphincsPlusParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new SPHINCSPlusPublicKeyParameters(spParams, keyEnc); + } + } + } + + private static class CMCEConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + try + { + byte[] keyEnc = CMCEPublicKey.getInstance(keyInfo.parsePublicKey()).getT(); + + CMCEParameters spParams = Utils.mcElieceParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new CMCEPublicKeyParameters(spParams, keyEnc); + } + catch (Exception e) + { + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); + + CMCEParameters spParams = Utils.mcElieceParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new CMCEPublicKeyParameters(spParams, keyEnc); + } + } + } + + private static class SABERConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + byte[] keyEnc = ASN1OctetString.getInstance( + ASN1Sequence.getInstance(keyInfo.parsePublicKey()).getObjectAt(0)).getOctets(); + + SABERParameters saberParams = Utils.saberParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new SABERPublicKeyParameters(saberParams, keyEnc); + } + } + + private static class FrodoConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + FrodoParameters fParams = Utils.frodoParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new FrodoPublicKeyParameters(fParams, keyEnc); + } + } + + private static class PicnicConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + PicnicParameters picnicParams = Utils.picnicParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new PicnicPublicKeyParameters(picnicParams, keyEnc); + } + } + + private static class NtruConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + NTRUParameters ntruParams = Utils.ntruParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new NTRUPublicKeyParameters(ntruParams, keyEnc); + } + } + + private static class FalconConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); +// FalconPublicKey falconPublicKey = FalconPublicKey.getInstance(keyInfo.parsePublicKey()); + + FalconParameters falconParams = Utils.falconParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new FalconPublicKeyParameters(falconParams, Arrays.copyOfRange(keyEnc, 1, keyEnc.length)); + + } + } + + private static class KyberConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + KyberParameters kyberParameters = Utils.kyberParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + try + { + ASN1Primitive obj = keyInfo.parsePublicKey(); + KyberPublicKey kyberKey = KyberPublicKey.getInstance(obj); + + return new KyberPublicKeyParameters(kyberParameters, kyberKey.getT(), kyberKey.getRho()); + } + catch (Exception e) + { + // we're a raw encoding + return new KyberPublicKeyParameters(kyberParameters, keyInfo.getPublicKeyData().getOctets()); + } + } + } + + private static class NTRULPrimeConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + NTRULPRimeParameters ntruLPRimeParams = Utils.ntrulprimeParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new NTRULPRimePublicKeyParameters(ntruLPRimeParams, keyEnc); + } + } + + private static class SNTRUPrimeConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + SNTRUPrimeParameters ntruLPRimeParams = Utils.sntruprimeParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new SNTRUPrimePublicKeyParameters(ntruLPRimeParams, keyEnc); + } + } + + static class DilithiumConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + DilithiumParameters dilithiumParams = Utils.dilithiumParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return getPublicKeyParams(dilithiumParams, keyInfo.getPublicKeyData()); + } + + static DilithiumPublicKeyParameters getPublicKeyParams(DilithiumParameters dilithiumParams, ASN1BitString publicKeyData) + { + try + { + ASN1Primitive obj = ASN1Primitive.fromByteArray(publicKeyData.getOctets()); + if (obj instanceof ASN1Sequence) + { + ASN1Sequence keySeq = ASN1Sequence.getInstance(obj); + + return new DilithiumPublicKeyParameters(dilithiumParams, + ASN1OctetString.getInstance(keySeq.getObjectAt(0)).getOctets(), + ASN1OctetString.getInstance(keySeq.getObjectAt(1)).getOctets()); + } + else + { + byte[] encKey = ASN1OctetString.getInstance(obj).getOctets(); + + return new DilithiumPublicKeyParameters(dilithiumParams, encKey); + } + } + catch (Exception e) + { + // we're a raw encoding + return new DilithiumPublicKeyParameters(dilithiumParams, publicKeyData.getOctets()); + } + } + } + + private static class BIKEConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + try + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + BIKEParameters bikeParams = Utils.bikeParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new BIKEPublicKeyParameters(bikeParams, keyEnc); + } + catch (Exception e) + { + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); + + BIKEParameters bikeParams = Utils.bikeParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new BIKEPublicKeyParameters(bikeParams, keyEnc); + } + } + } + + private static class HQCConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + try + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + HQCParameters hqcParams = Utils.hqcParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new HQCPublicKeyParameters(hqcParams, keyEnc); + } + catch (Exception e) + { + // raw encoding + byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); + + HQCParameters hqcParams = Utils.hqcParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new HQCPublicKeyParameters(hqcParams, keyEnc); + } } } } diff --git a/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java b/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java index c8f36e074d..7f51da104c 100644 --- a/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java +++ b/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java @@ -2,14 +2,30 @@ import java.io.IOException; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.internal.asn1.isara.IsaraObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; +import org.bouncycastle.pqc.crypto.bike.BIKEPublicKeyParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEPublicKeyParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberPublicKeyParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconPublicKeyParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoPublicKeyParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCPublicKeyParameters; import org.bouncycastle.pqc.crypto.newhope.NHPublicKeyParameters; -import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLAPublicKeyParameters; +import org.bouncycastle.pqc.crypto.ntru.NTRUPublicKeyParameters; +import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePublicKeyParameters; +import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimePublicKeyParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicPublicKeyParameters; +import org.bouncycastle.pqc.crypto.saber.SABERPublicKeyParameters; import org.bouncycastle.pqc.crypto.sphincs.SPHINCSPublicKeyParameters; +import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusPublicKeyParameters; /** * Factory to create ASN.1 subject public key info objects from lightweight public keys. @@ -31,14 +47,7 @@ private SubjectPublicKeyInfoFactory() public static SubjectPublicKeyInfo createSubjectPublicKeyInfo(AsymmetricKeyParameter publicKey) throws IOException { - if (publicKey instanceof QTESLAPublicKeyParameters) - { - QTESLAPublicKeyParameters keyParams = (QTESLAPublicKeyParameters)publicKey; - AlgorithmIdentifier algorithmIdentifier = Utils.qTeslaLookupAlgID(keyParams.getSecurityCategory()); - - return new SubjectPublicKeyInfo(algorithmIdentifier, keyParams.getPublicData()); - } - else if (publicKey instanceof SPHINCSPublicKeyParameters) + if (publicKey instanceof SPHINCSPublicKeyParameters) { SPHINCSPublicKeyParameters params = (SPHINCSPublicKeyParameters)publicKey; @@ -53,6 +62,130 @@ else if (publicKey instanceof NHPublicKeyParameters) AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.newHope); return new SubjectPublicKeyInfo(algorithmIdentifier, params.getPubData()); } + else if (publicKey instanceof SPHINCSPlusPublicKeyParameters) + { + SPHINCSPlusPublicKeyParameters params = (SPHINCSPlusPublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.sphincsPlusOidLookup(params.getParameters())); + return new SubjectPublicKeyInfo(algorithmIdentifier, encoding); + } + else if (publicKey instanceof CMCEPublicKeyParameters) + { + CMCEPublicKeyParameters params = (CMCEPublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.mcElieceOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, encoding); + } + else if (publicKey instanceof FrodoPublicKeyParameters) + { + FrodoPublicKeyParameters params = (FrodoPublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.frodoOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); + } + else if (publicKey instanceof SABERPublicKeyParameters) + { + SABERPublicKeyParameters params = (SABERPublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.saberOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, new DERSequence(new DEROctetString(encoding))); + } + else if (publicKey instanceof PicnicPublicKeyParameters) + { + PicnicPublicKeyParameters params = (PicnicPublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.picnicOidLookup(params.getParameters())); + return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); + } + else if (publicKey instanceof NTRUPublicKeyParameters) + { + NTRUPublicKeyParameters params = (NTRUPublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.ntruOidLookup(params.getParameters())); + return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); + } + else if (publicKey instanceof FalconPublicKeyParameters) + { + FalconPublicKeyParameters params = (FalconPublicKeyParameters)publicKey; + + byte[] encoding = params.getH(); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.falconOidLookup(params.getParameters())); + + byte[] keyEnc = new byte[encoding.length + 1]; + keyEnc[0] = (byte)(0x00 + params.getParameters().getLogN()); + System.arraycopy(encoding, 0, keyEnc, 1, encoding.length); + + return new SubjectPublicKeyInfo(algorithmIdentifier, keyEnc); + } + else if (publicKey instanceof KyberPublicKeyParameters) + { + KyberPublicKeyParameters params = (KyberPublicKeyParameters)publicKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.kyberOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, params.getEncoded()); + } + else if (publicKey instanceof NTRULPRimePublicKeyParameters) + { + NTRULPRimePublicKeyParameters params = (NTRULPRimePublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.ntrulprimeOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); + } + else if (publicKey instanceof SNTRUPrimePublicKeyParameters) + { + SNTRUPrimePublicKeyParameters params = (SNTRUPrimePublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.sntruprimeOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); + } + else if (publicKey instanceof DilithiumPublicKeyParameters) + { + DilithiumPublicKeyParameters params = (DilithiumPublicKeyParameters)publicKey; + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.dilithiumOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, params.getEncoded()); + } + else if (publicKey instanceof BIKEPublicKeyParameters) + { + BIKEPublicKeyParameters params = (BIKEPublicKeyParameters) publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.bikeOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, encoding); + } + else if (publicKey instanceof HQCPublicKeyParameters) + { + HQCPublicKeyParameters params = (HQCPublicKeyParameters)publicKey; + + byte[] encoding = params.getEncoded(); + + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.hqcOidLookup(params.getParameters())); + + return new SubjectPublicKeyInfo(algorithmIdentifier, encoding); + } else { throw new IOException("key parameters not recognized"); diff --git a/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/Utils.java b/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/Utils.java index 5508800d37..8cf674f296 100644 --- a/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/Utils.java +++ b/core/src/main/jdk1.4/org/bouncycastle/pqc/crypto/util/Utils.java @@ -4,7 +4,10 @@ import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; @@ -12,49 +15,343 @@ import org.bouncycastle.crypto.digests.SHAKEDigest; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; -import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLASecurityCategory; +import org.bouncycastle.pqc.crypto.bike.BIKEParameters; +import org.bouncycastle.pqc.crypto.cmce.CMCEParameters; +import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumParameters; +import org.bouncycastle.pqc.crypto.mlkem.KyberParameters; +import org.bouncycastle.pqc.crypto.falcon.FalconParameters; +import org.bouncycastle.pqc.crypto.frodo.FrodoParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCParameters; +import org.bouncycastle.pqc.crypto.ntru.NTRUParameters; +import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeParameters; +import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeParameters; +import org.bouncycastle.pqc.crypto.picnic.PicnicParameters; +import org.bouncycastle.pqc.crypto.saber.SABERParameters; import org.bouncycastle.pqc.crypto.sphincs.SPHINCSKeyParameters; +import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusParameters; import org.bouncycastle.util.Integers; class Utils { - static final AlgorithmIdentifier AlgID_qTESLA_p_I = new AlgorithmIdentifier(PQCObjectIdentifiers.qTESLA_p_I); - static final AlgorithmIdentifier AlgID_qTESLA_p_III = new AlgorithmIdentifier(PQCObjectIdentifiers.qTESLA_p_III); - static final AlgorithmIdentifier SPHINCS_SHA3_256 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_256); static final AlgorithmIdentifier SPHINCS_SHA512_256 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512_256); - static final AlgorithmIdentifier XMSS_SHA256 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256); - static final AlgorithmIdentifier XMSS_SHA512 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512); - static final AlgorithmIdentifier XMSS_SHAKE128 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake128); - static final AlgorithmIdentifier XMSS_SHAKE256 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256); - static final Map categories = new HashMap(); + static final Map picnicOids = new HashMap(); + static final Map picnicParams = new HashMap(); + + static final Map frodoOids = new HashMap(); + static final Map frodoParams = new HashMap(); + + static final Map saberOids = new HashMap(); + static final Map saberParams = new HashMap(); + + static final Map mcElieceOids = new HashMap(); + static final Map mcElieceParams = new HashMap(); + + static final Map sphincsPlusOids = new HashMap(); + static final Map sphincsPlusParams = new HashMap(); + + static final Map sikeOids = new HashMap(); + static final Map sikeParams = new HashMap(); + + static final Map ntruOids = new HashMap(); + static final Map ntruParams = new HashMap(); + + static final Map falconOids = new HashMap(); + static final Map falconParams = new HashMap(); + + static final Map kyberOids = new HashMap(); + static final Map kyberParams = new HashMap(); + + static final Map ntruprimeOids = new HashMap(); + static final Map ntruprimeParams = new HashMap(); + + static final Map sntruprimeOids = new HashMap(); + static final Map sntruprimeParams = new HashMap(); + + static final Map dilithiumOids = new HashMap(); + static final Map dilithiumParams = new HashMap(); + + static final Map bikeOids = new HashMap(); + static final Map bikeParams = new HashMap(); + + static final Map hqcOids = new HashMap(); + static final Map hqcParams = new HashMap(); + + static final Map rainbowOids = new HashMap(); + static final Map rainbowParams = new HashMap(); + static { - categories.put(PQCObjectIdentifiers.qTESLA_p_I, Integers.valueOf(QTESLASecurityCategory.PROVABLY_SECURE_I)); - categories.put(PQCObjectIdentifiers.qTESLA_p_III, Integers.valueOf(QTESLASecurityCategory.PROVABLY_SECURE_III)); - } + mcElieceOids.put(CMCEParameters.mceliece348864r3, BCObjectIdentifiers.mceliece348864_r3); + mcElieceOids.put(CMCEParameters.mceliece348864fr3, BCObjectIdentifiers.mceliece348864f_r3); + mcElieceOids.put(CMCEParameters.mceliece460896r3, BCObjectIdentifiers.mceliece460896_r3); + mcElieceOids.put(CMCEParameters.mceliece460896fr3, BCObjectIdentifiers.mceliece460896f_r3); + mcElieceOids.put(CMCEParameters.mceliece6688128r3, BCObjectIdentifiers.mceliece6688128_r3); + mcElieceOids.put(CMCEParameters.mceliece6688128fr3, BCObjectIdentifiers.mceliece6688128f_r3); + mcElieceOids.put(CMCEParameters.mceliece6960119r3, BCObjectIdentifiers.mceliece6960119_r3); + mcElieceOids.put(CMCEParameters.mceliece6960119fr3, BCObjectIdentifiers.mceliece6960119f_r3); + mcElieceOids.put(CMCEParameters.mceliece8192128r3, BCObjectIdentifiers.mceliece8192128_r3); + mcElieceOids.put(CMCEParameters.mceliece8192128fr3, BCObjectIdentifiers.mceliece8192128f_r3); - static int qTeslaLookupSecurityCategory(AlgorithmIdentifier algorithm) - { - return ((Integer)categories.get(algorithm.getAlgorithm())).intValue(); - } + mcElieceParams.put(BCObjectIdentifiers.mceliece348864_r3, CMCEParameters.mceliece348864r3); + mcElieceParams.put(BCObjectIdentifiers.mceliece348864f_r3, CMCEParameters.mceliece348864fr3); + mcElieceParams.put(BCObjectIdentifiers.mceliece460896_r3, CMCEParameters.mceliece460896r3); + mcElieceParams.put(BCObjectIdentifiers.mceliece460896f_r3, CMCEParameters.mceliece460896fr3); + mcElieceParams.put(BCObjectIdentifiers.mceliece6688128_r3, CMCEParameters.mceliece6688128r3); + mcElieceParams.put(BCObjectIdentifiers.mceliece6688128f_r3, CMCEParameters.mceliece6688128fr3); + mcElieceParams.put(BCObjectIdentifiers.mceliece6960119_r3, CMCEParameters.mceliece6960119r3); + mcElieceParams.put(BCObjectIdentifiers.mceliece6960119f_r3, CMCEParameters.mceliece6960119fr3); + mcElieceParams.put(BCObjectIdentifiers.mceliece8192128_r3, CMCEParameters.mceliece8192128r3); + mcElieceParams.put(BCObjectIdentifiers.mceliece8192128f_r3, CMCEParameters.mceliece8192128fr3); - static AlgorithmIdentifier qTeslaLookupAlgID(int securityCategory) - { - switch (securityCategory) - { - case QTESLASecurityCategory.PROVABLY_SECURE_I: - return AlgID_qTESLA_p_I; - case QTESLASecurityCategory.PROVABLY_SECURE_III: - return AlgID_qTESLA_p_III; - default: - throw new IllegalArgumentException("unknown security category: " + securityCategory); - } - } + frodoOids.put(FrodoParameters.frodokem640aes, BCObjectIdentifiers.frodokem640aes); + frodoOids.put(FrodoParameters.frodokem640shake, BCObjectIdentifiers.frodokem640shake); + frodoOids.put(FrodoParameters.frodokem976aes, BCObjectIdentifiers.frodokem976aes); + frodoOids.put(FrodoParameters.frodokem976shake, BCObjectIdentifiers.frodokem976shake); + frodoOids.put(FrodoParameters.frodokem1344aes, BCObjectIdentifiers.frodokem1344aes); + frodoOids.put(FrodoParameters.frodokem1344shake, BCObjectIdentifiers.frodokem1344shake); + + frodoParams.put(BCObjectIdentifiers.frodokem640aes, FrodoParameters.frodokem640aes); + frodoParams.put(BCObjectIdentifiers.frodokem640shake, FrodoParameters.frodokem640shake); + frodoParams.put(BCObjectIdentifiers.frodokem976aes, FrodoParameters.frodokem976aes); + frodoParams.put(BCObjectIdentifiers.frodokem976shake, FrodoParameters.frodokem976shake); + frodoParams.put(BCObjectIdentifiers.frodokem1344aes, FrodoParameters.frodokem1344aes); + frodoParams.put(BCObjectIdentifiers.frodokem1344shake, FrodoParameters.frodokem1344shake); + + saberOids.put(SABERParameters.lightsaberkem128r3, BCObjectIdentifiers.lightsaberkem128r3); + saberOids.put(SABERParameters.saberkem128r3, BCObjectIdentifiers.saberkem128r3); + saberOids.put(SABERParameters.firesaberkem128r3, BCObjectIdentifiers.firesaberkem128r3); + saberOids.put(SABERParameters.lightsaberkem192r3, BCObjectIdentifiers.lightsaberkem192r3); + saberOids.put(SABERParameters.saberkem192r3, BCObjectIdentifiers.saberkem192r3); + saberOids.put(SABERParameters.firesaberkem192r3, BCObjectIdentifiers.firesaberkem192r3); + saberOids.put(SABERParameters.lightsaberkem256r3, BCObjectIdentifiers.lightsaberkem256r3); + saberOids.put(SABERParameters.saberkem256r3, BCObjectIdentifiers.saberkem256r3); + saberOids.put(SABERParameters.firesaberkem256r3, BCObjectIdentifiers.firesaberkem256r3); + saberOids.put(SABERParameters.ulightsaberkemr3, BCObjectIdentifiers.ulightsaberkemr3); + saberOids.put(SABERParameters.usaberkemr3, BCObjectIdentifiers.usaberkemr3); + saberOids.put(SABERParameters.ufiresaberkemr3, BCObjectIdentifiers.ufiresaberkemr3); + saberOids.put(SABERParameters.lightsaberkem90sr3, BCObjectIdentifiers.lightsaberkem90sr3); + saberOids.put(SABERParameters.saberkem90sr3, BCObjectIdentifiers.saberkem90sr3); + saberOids.put(SABERParameters.firesaberkem90sr3, BCObjectIdentifiers.firesaberkem90sr3); + saberOids.put(SABERParameters.ulightsaberkem90sr3, BCObjectIdentifiers.ulightsaberkem90sr3); + saberOids.put(SABERParameters.usaberkem90sr3, BCObjectIdentifiers.usaberkem90sr3); + saberOids.put(SABERParameters.ufiresaberkem90sr3, BCObjectIdentifiers.ufiresaberkem90sr3); + + saberParams.put(BCObjectIdentifiers.lightsaberkem128r3, SABERParameters.lightsaberkem128r3); + saberParams.put(BCObjectIdentifiers.saberkem128r3, SABERParameters.saberkem128r3); + saberParams.put(BCObjectIdentifiers.firesaberkem128r3, SABERParameters.firesaberkem128r3); + saberParams.put(BCObjectIdentifiers.lightsaberkem192r3, SABERParameters.lightsaberkem192r3); + saberParams.put(BCObjectIdentifiers.saberkem192r3, SABERParameters.saberkem192r3); + saberParams.put(BCObjectIdentifiers.firesaberkem192r3, SABERParameters.firesaberkem192r3); + saberParams.put(BCObjectIdentifiers.lightsaberkem256r3, SABERParameters.lightsaberkem256r3); + saberParams.put(BCObjectIdentifiers.saberkem256r3, SABERParameters.saberkem256r3); + saberParams.put(BCObjectIdentifiers.firesaberkem256r3, SABERParameters.firesaberkem256r3); + saberParams.put(BCObjectIdentifiers.ulightsaberkemr3, SABERParameters.ulightsaberkemr3); + saberParams.put(BCObjectIdentifiers.usaberkemr3, SABERParameters.usaberkemr3); + saberParams.put(BCObjectIdentifiers.ufiresaberkemr3, SABERParameters.ufiresaberkemr3); + saberParams.put(BCObjectIdentifiers.lightsaberkem90sr3, SABERParameters.lightsaberkem90sr3); + saberParams.put(BCObjectIdentifiers.saberkem90sr3, SABERParameters.saberkem90sr3); + saberParams.put(BCObjectIdentifiers.firesaberkem90sr3, SABERParameters.firesaberkem90sr3); + saberParams.put(BCObjectIdentifiers.ulightsaberkem90sr3, SABERParameters.ulightsaberkem90sr3); + saberParams.put(BCObjectIdentifiers.usaberkem90sr3, SABERParameters.usaberkem90sr3); + saberParams.put(BCObjectIdentifiers.ufiresaberkem90sr3, SABERParameters.ufiresaberkem90sr3); + + picnicOids.put(PicnicParameters.picnicl1fs, BCObjectIdentifiers.picnicl1fs); + picnicOids.put(PicnicParameters.picnicl1ur, BCObjectIdentifiers.picnicl1ur); + picnicOids.put(PicnicParameters.picnicl3fs, BCObjectIdentifiers.picnicl3fs); + picnicOids.put(PicnicParameters.picnicl3ur, BCObjectIdentifiers.picnicl3ur); + picnicOids.put(PicnicParameters.picnicl5fs, BCObjectIdentifiers.picnicl5fs); + picnicOids.put(PicnicParameters.picnicl5ur, BCObjectIdentifiers.picnicl5ur); + picnicOids.put(PicnicParameters.picnic3l1, BCObjectIdentifiers.picnic3l1); + picnicOids.put(PicnicParameters.picnic3l3, BCObjectIdentifiers.picnic3l3); + picnicOids.put(PicnicParameters.picnic3l5, BCObjectIdentifiers.picnic3l5); + picnicOids.put(PicnicParameters.picnicl1full, BCObjectIdentifiers.picnicl1full); + picnicOids.put(PicnicParameters.picnicl3full, BCObjectIdentifiers.picnicl3full); + picnicOids.put(PicnicParameters.picnicl5full, BCObjectIdentifiers.picnicl5full); + + picnicParams.put(BCObjectIdentifiers.picnicl1fs, PicnicParameters.picnicl1fs); + picnicParams.put(BCObjectIdentifiers.picnicl1ur, PicnicParameters.picnicl1ur); + picnicParams.put(BCObjectIdentifiers.picnicl3fs, PicnicParameters.picnicl3fs); + picnicParams.put(BCObjectIdentifiers.picnicl3ur, PicnicParameters.picnicl3ur); + picnicParams.put(BCObjectIdentifiers.picnicl5fs, PicnicParameters.picnicl5fs); + picnicParams.put(BCObjectIdentifiers.picnicl5ur, PicnicParameters.picnicl5ur); + picnicParams.put(BCObjectIdentifiers.picnic3l1, PicnicParameters.picnic3l1); + picnicParams.put(BCObjectIdentifiers.picnic3l3, PicnicParameters.picnic3l3); + picnicParams.put(BCObjectIdentifiers.picnic3l5, PicnicParameters.picnic3l5); + picnicParams.put(BCObjectIdentifiers.picnicl1full, PicnicParameters.picnicl1full); + picnicParams.put(BCObjectIdentifiers.picnicl3full, PicnicParameters.picnicl3full); + picnicParams.put(BCObjectIdentifiers.picnicl5full, PicnicParameters.picnicl5full); + + ntruOids.put(NTRUParameters.ntruhps2048509, BCObjectIdentifiers.ntruhps2048509); + ntruOids.put(NTRUParameters.ntruhps2048677, BCObjectIdentifiers.ntruhps2048677); + ntruOids.put(NTRUParameters.ntruhps4096821, BCObjectIdentifiers.ntruhps4096821); + ntruOids.put(NTRUParameters.ntruhrss701, BCObjectIdentifiers.ntruhrss701); + + ntruParams.put(BCObjectIdentifiers.ntruhps2048509, NTRUParameters.ntruhps2048509); + ntruParams.put(BCObjectIdentifiers.ntruhps2048677, NTRUParameters.ntruhps2048677); + ntruParams.put(BCObjectIdentifiers.ntruhps4096821, NTRUParameters.ntruhps4096821); + ntruParams.put(BCObjectIdentifiers.ntruhrss701, NTRUParameters.ntruhrss701); + + falconOids.put(FalconParameters.falcon_512, BCObjectIdentifiers.falcon_512); + falconOids.put(FalconParameters.falcon_1024, BCObjectIdentifiers.falcon_1024); + + falconParams.put(BCObjectIdentifiers.falcon_512, FalconParameters.falcon_512); + falconParams.put(BCObjectIdentifiers.falcon_1024, FalconParameters.falcon_1024); + + kyberOids.put(KyberParameters.kyber512, BCObjectIdentifiers.kyber512); + kyberOids.put(KyberParameters.kyber768, BCObjectIdentifiers.kyber768); + kyberOids.put(KyberParameters.kyber1024, BCObjectIdentifiers.kyber1024); + + kyberParams.put(BCObjectIdentifiers.kyber512, KyberParameters.kyber512); + kyberParams.put(BCObjectIdentifiers.kyber768, KyberParameters.kyber768); + kyberParams.put(BCObjectIdentifiers.kyber1024, KyberParameters.kyber1024); + + ntruprimeOids.put(NTRULPRimeParameters.ntrulpr653, BCObjectIdentifiers.ntrulpr653); + ntruprimeOids.put(NTRULPRimeParameters.ntrulpr761, BCObjectIdentifiers.ntrulpr761); + ntruprimeOids.put(NTRULPRimeParameters.ntrulpr857, BCObjectIdentifiers.ntrulpr857); + ntruprimeOids.put(NTRULPRimeParameters.ntrulpr953, BCObjectIdentifiers.ntrulpr953); + ntruprimeOids.put(NTRULPRimeParameters.ntrulpr1013, BCObjectIdentifiers.ntrulpr1013); + ntruprimeOids.put(NTRULPRimeParameters.ntrulpr1277, BCObjectIdentifiers.ntrulpr1277); + + ntruprimeParams.put(BCObjectIdentifiers.ntrulpr653, NTRULPRimeParameters.ntrulpr653); + ntruprimeParams.put(BCObjectIdentifiers.ntrulpr761, NTRULPRimeParameters.ntrulpr761); + ntruprimeParams.put(BCObjectIdentifiers.ntrulpr857, NTRULPRimeParameters.ntrulpr857); + ntruprimeParams.put(BCObjectIdentifiers.ntrulpr953, NTRULPRimeParameters.ntrulpr953); + ntruprimeParams.put(BCObjectIdentifiers.ntrulpr1013, NTRULPRimeParameters.ntrulpr1013); + ntruprimeParams.put(BCObjectIdentifiers.ntrulpr1277, NTRULPRimeParameters.ntrulpr1277); + + sntruprimeOids.put(SNTRUPrimeParameters.sntrup653, BCObjectIdentifiers.sntrup653); + sntruprimeOids.put(SNTRUPrimeParameters.sntrup761, BCObjectIdentifiers.sntrup761); + sntruprimeOids.put(SNTRUPrimeParameters.sntrup857, BCObjectIdentifiers.sntrup857); + sntruprimeOids.put(SNTRUPrimeParameters.sntrup953, BCObjectIdentifiers.sntrup953); + sntruprimeOids.put(SNTRUPrimeParameters.sntrup1013, BCObjectIdentifiers.sntrup1013); + sntruprimeOids.put(SNTRUPrimeParameters.sntrup1277, BCObjectIdentifiers.sntrup1277); + + sntruprimeParams.put(BCObjectIdentifiers.sntrup653, SNTRUPrimeParameters.sntrup653); + sntruprimeParams.put(BCObjectIdentifiers.sntrup761, SNTRUPrimeParameters.sntrup761); + sntruprimeParams.put(BCObjectIdentifiers.sntrup857, SNTRUPrimeParameters.sntrup857); + sntruprimeParams.put(BCObjectIdentifiers.sntrup953, SNTRUPrimeParameters.sntrup953); + sntruprimeParams.put(BCObjectIdentifiers.sntrup1013, SNTRUPrimeParameters.sntrup1013); + sntruprimeParams.put(BCObjectIdentifiers.sntrup1277, SNTRUPrimeParameters.sntrup1277); + + dilithiumOids.put(DilithiumParameters.dilithium2, BCObjectIdentifiers.dilithium2); + dilithiumOids.put(DilithiumParameters.dilithium3, BCObjectIdentifiers.dilithium3); + dilithiumOids.put(DilithiumParameters.dilithium5, BCObjectIdentifiers.dilithium5); + dilithiumParams.put(BCObjectIdentifiers.dilithium2, DilithiumParameters.dilithium2); + dilithiumParams.put(BCObjectIdentifiers.dilithium3, DilithiumParameters.dilithium3); + dilithiumParams.put(BCObjectIdentifiers.dilithium5, DilithiumParameters.dilithium5); + + bikeParams.put(BCObjectIdentifiers.bike128, BIKEParameters.bike128); + bikeParams.put(BCObjectIdentifiers.bike192, BIKEParameters.bike192); + bikeParams.put(BCObjectIdentifiers.bike256, BIKEParameters.bike256); + + bikeOids.put(BIKEParameters.bike128, BCObjectIdentifiers.bike128); + bikeOids.put(BIKEParameters.bike192, BCObjectIdentifiers.bike192); + bikeOids.put(BIKEParameters.bike256, BCObjectIdentifiers.bike256); + + hqcParams.put(BCObjectIdentifiers.hqc128, HQCParameters.hqc128); + hqcParams.put(BCObjectIdentifiers.hqc192, HQCParameters.hqc192); + hqcParams.put(BCObjectIdentifiers.hqc256, HQCParameters.hqc256); + + hqcOids.put(HQCParameters.hqc128, BCObjectIdentifiers.hqc128); + hqcOids.put(HQCParameters.hqc192, BCObjectIdentifiers.hqc192); + hqcOids.put(HQCParameters.hqc256, BCObjectIdentifiers.hqc256); + + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_128s_robust, BCObjectIdentifiers.sphincsPlus_sha2_128s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_128f_robust, BCObjectIdentifiers.sphincsPlus_sha2_128f_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_128s_robust, BCObjectIdentifiers.sphincsPlus_shake_128s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_128f_robust, BCObjectIdentifiers.sphincsPlus_shake_128f_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_128s, BCObjectIdentifiers.sphincsPlus_haraka_128s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_128f, BCObjectIdentifiers.sphincsPlus_haraka_128f_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_192s_robust, BCObjectIdentifiers.sphincsPlus_sha2_192s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_192f_robust, BCObjectIdentifiers.sphincsPlus_sha2_192f_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_192s_robust, BCObjectIdentifiers.sphincsPlus_shake_192s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_192f_robust, BCObjectIdentifiers.sphincsPlus_shake_192f_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_192s, BCObjectIdentifiers.sphincsPlus_haraka_192s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_192f, BCObjectIdentifiers.sphincsPlus_haraka_192f_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_256s_robust, BCObjectIdentifiers.sphincsPlus_sha2_256s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_256f_robust, BCObjectIdentifiers.sphincsPlus_sha2_256f_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_256s_robust, BCObjectIdentifiers.sphincsPlus_shake_256s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_256f_robust, BCObjectIdentifiers.sphincsPlus_shake_256f_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_256s, BCObjectIdentifiers.sphincsPlus_haraka_256s_r3); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_256f, BCObjectIdentifiers.sphincsPlus_haraka_256f_r3); + + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_128s_simple, BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_128f_simple, BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_192s_simple, BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_192f_simple, BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_256s_simple, BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple); + sphincsPlusOids.put(SPHINCSPlusParameters.haraka_256f_simple, BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple); + + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_128s, BCObjectIdentifiers.sphincsPlus_sha2_128s); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_128f, BCObjectIdentifiers.sphincsPlus_sha2_128f); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_128s, BCObjectIdentifiers.sphincsPlus_shake_128s); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_128f, BCObjectIdentifiers.sphincsPlus_shake_128f); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_192s, BCObjectIdentifiers.sphincsPlus_sha2_192s); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_192f, BCObjectIdentifiers.sphincsPlus_sha2_192f); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_192s, BCObjectIdentifiers.sphincsPlus_shake_192s); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_192f, BCObjectIdentifiers.sphincsPlus_shake_192f); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_256s, BCObjectIdentifiers.sphincsPlus_sha2_256s); + sphincsPlusOids.put(SPHINCSPlusParameters.sha2_256f, BCObjectIdentifiers.sphincsPlus_sha2_256f); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_256s, BCObjectIdentifiers.sphincsPlus_shake_256s); + sphincsPlusOids.put(SPHINCSPlusParameters.shake_256f, BCObjectIdentifiers.sphincsPlus_shake_256f); + + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128s, SPHINCSPlusParameters.sha2_128s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128f, SPHINCSPlusParameters.sha2_128f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128s, SPHINCSPlusParameters.shake_128s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128f, SPHINCSPlusParameters.shake_128f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192s, SPHINCSPlusParameters.sha2_192s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192f, SPHINCSPlusParameters.sha2_192f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192s, SPHINCSPlusParameters.shake_192s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192f, SPHINCSPlusParameters.shake_192f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256s, SPHINCSPlusParameters.sha2_256s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256f, SPHINCSPlusParameters.sha2_256f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256s, SPHINCSPlusParameters.shake_256s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256f, SPHINCSPlusParameters.shake_256f); + + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, SPHINCSPlusParameters.sha2_128s_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, SPHINCSPlusParameters.sha2_128f_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, SPHINCSPlusParameters.shake_128s_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3, SPHINCSPlusParameters.shake_128f_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3, SPHINCSPlusParameters.haraka_128s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3, SPHINCSPlusParameters.haraka_128f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, SPHINCSPlusParameters.sha2_192s_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, SPHINCSPlusParameters.sha2_192f_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3, SPHINCSPlusParameters.shake_192s_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3, SPHINCSPlusParameters.shake_192f_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3, SPHINCSPlusParameters.haraka_192s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3, SPHINCSPlusParameters.haraka_192f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, SPHINCSPlusParameters.sha2_256s_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, SPHINCSPlusParameters.sha2_256f_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3, SPHINCSPlusParameters.shake_256s_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, SPHINCSPlusParameters.shake_256f_robust); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, SPHINCSPlusParameters.haraka_256s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, SPHINCSPlusParameters.haraka_256f); + + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, SPHINCSPlusParameters.sha2_128s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, SPHINCSPlusParameters.sha2_128f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, SPHINCSPlusParameters.shake_128s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, SPHINCSPlusParameters.shake_128f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple, SPHINCSPlusParameters.haraka_128s_simple); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple, SPHINCSPlusParameters.haraka_128f_simple); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, SPHINCSPlusParameters.sha2_192s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, SPHINCSPlusParameters.sha2_192f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, SPHINCSPlusParameters.shake_192s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, SPHINCSPlusParameters.shake_192f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple, SPHINCSPlusParameters.haraka_192s_simple); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple, SPHINCSPlusParameters.haraka_192f_simple); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, SPHINCSPlusParameters.sha2_256s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, SPHINCSPlusParameters.sha2_256f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, SPHINCSPlusParameters.shake_256s); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, SPHINCSPlusParameters.shake_256f); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple, SPHINCSPlusParameters.haraka_256s_simple); + sphincsPlusParams.put(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple, SPHINCSPlusParameters.haraka_256f_simple); + } + static AlgorithmIdentifier sphincs256LookupTreeAlgID(String treeDigest) { if (treeDigest.equals(SPHINCSKeyParameters.SHA3_256)) @@ -110,4 +407,186 @@ static Digest getDigest(ASN1ObjectIdentifier oid) throw new IllegalArgumentException("unrecognized digest OID: " + oid); } + + public static AlgorithmIdentifier getAlgorithmIdentifier(String digestName) + { + if (digestName.equals("SHA-1")) + { + return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); + } + if (digestName.equals("SHA-224")) + { + return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224); + } + if (digestName.equals("SHA-256")) + { + return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256); + } + if (digestName.equals("SHA-384")) + { + return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384); + } + if (digestName.equals("SHA-512")) + { + return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512); + } + + throw new IllegalArgumentException("unrecognised digest algorithm: " + digestName); + } + + public static String getDigestName(ASN1ObjectIdentifier digestOid) + { + if (digestOid.equals(OIWObjectIdentifiers.idSHA1)) + { + return "SHA-1"; + } + if (digestOid.equals(NISTObjectIdentifiers.id_sha224)) + { + return "SHA-224"; + } + if (digestOid.equals(NISTObjectIdentifiers.id_sha256)) + { + return "SHA-256"; + } + if (digestOid.equals(NISTObjectIdentifiers.id_sha384)) + { + return "SHA-384"; + } + if (digestOid.equals(NISTObjectIdentifiers.id_sha512)) + { + return "SHA-512"; + } + + throw new IllegalArgumentException("unrecognised digest algorithm: " + digestOid); + } + + static ASN1ObjectIdentifier sphincsPlusOidLookup(SPHINCSPlusParameters params) + { + return (ASN1ObjectIdentifier)sphincsPlusOids.get(params); + } + + static SPHINCSPlusParameters sphincsPlusParamsLookup(ASN1ObjectIdentifier oid) + { + return (SPHINCSPlusParameters)sphincsPlusParams.get(oid); + } + + static ASN1ObjectIdentifier mcElieceOidLookup(CMCEParameters params) + { + return (ASN1ObjectIdentifier)mcElieceOids.get(params); + } + + static CMCEParameters mcElieceParamsLookup(ASN1ObjectIdentifier oid) + { + return (CMCEParameters)mcElieceParams.get(oid); + } + + static ASN1ObjectIdentifier frodoOidLookup(FrodoParameters params) + { + return (ASN1ObjectIdentifier)frodoOids.get(params); + } + + static FrodoParameters frodoParamsLookup(ASN1ObjectIdentifier oid) + { + return (FrodoParameters)frodoParams.get(oid); + } + + static ASN1ObjectIdentifier saberOidLookup(SABERParameters params) + { + return (ASN1ObjectIdentifier)saberOids.get(params); + } + + static SABERParameters saberParamsLookup(ASN1ObjectIdentifier oid) + { + return (SABERParameters)saberParams.get(oid); + } + + static ASN1ObjectIdentifier picnicOidLookup(PicnicParameters params) + { + return (ASN1ObjectIdentifier)picnicOids.get(params); + } + + static PicnicParameters picnicParamsLookup(ASN1ObjectIdentifier oid) + { + return (PicnicParameters)picnicParams.get(oid); + } + + static ASN1ObjectIdentifier falconOidLookup(FalconParameters params) + { + return (ASN1ObjectIdentifier)falconOids.get(params); + } + + static FalconParameters falconParamsLookup(ASN1ObjectIdentifier oid) + { + return (FalconParameters)falconParams.get(oid); + } + + static ASN1ObjectIdentifier ntruOidLookup(NTRUParameters params) + { + return (ASN1ObjectIdentifier)ntruOids.get(params); + } + + static NTRUParameters ntruParamsLookup(ASN1ObjectIdentifier oid) + { + return (NTRUParameters)ntruParams.get(oid); + } + + static ASN1ObjectIdentifier kyberOidLookup(KyberParameters params) + { + return (ASN1ObjectIdentifier)kyberOids.get(params); + } + + static KyberParameters kyberParamsLookup(ASN1ObjectIdentifier oid) + { + return (KyberParameters)kyberParams.get(oid); + } + + static ASN1ObjectIdentifier ntrulprimeOidLookup(NTRULPRimeParameters params) + { + return (ASN1ObjectIdentifier)ntruprimeOids.get(params); + } + + static NTRULPRimeParameters ntrulprimeParamsLookup(ASN1ObjectIdentifier oid) + { + return (NTRULPRimeParameters)ntruprimeParams.get(oid); + } + + static ASN1ObjectIdentifier sntruprimeOidLookup(SNTRUPrimeParameters params) + { + return (ASN1ObjectIdentifier)sntruprimeOids.get(params); + } + + static SNTRUPrimeParameters sntruprimeParamsLookup(ASN1ObjectIdentifier oid) + { + return (SNTRUPrimeParameters)sntruprimeParams.get(oid); + } + + static ASN1ObjectIdentifier dilithiumOidLookup(DilithiumParameters params) + { + return (ASN1ObjectIdentifier)dilithiumOids.get(params); + } + + static DilithiumParameters dilithiumParamsLookup(ASN1ObjectIdentifier oid) + { + return (DilithiumParameters)dilithiumParams.get(oid); + } + + static ASN1ObjectIdentifier bikeOidLookup(BIKEParameters params) + { + return (ASN1ObjectIdentifier)bikeOids.get(params); + } + + static BIKEParameters bikeParamsLookup(ASN1ObjectIdentifier oid) + { + return (BIKEParameters)bikeParams.get(oid); + } + + static ASN1ObjectIdentifier hqcOidLookup(HQCParameters params) + { + return (ASN1ObjectIdentifier)hqcOids.get(params); + } + + static HQCParameters hqcParamsLookup(ASN1ObjectIdentifier oid) + { + return (HQCParameters)hqcParams.get(oid); + } } diff --git a/core/src/main/jdk1.4/org/bouncycastle/util/Arrays.java b/core/src/main/jdk1.4/org/bouncycastle/util/Arrays.java index 57148e2c47..ef5d23662f 100644 --- a/core/src/main/jdk1.4/org/bouncycastle/util/Arrays.java +++ b/core/src/main/jdk1.4/org/bouncycastle/util/Arrays.java @@ -613,9 +613,7 @@ private static int getLength(int from, int to) int newLength = to - from; if (newLength < 0) { - StringBuffer sb = new StringBuffer(from); - sb.append(" > ").append(to); - throw new IllegalArgumentException(sb.toString()); + throw new IllegalArgumentException(from + " > " + to); } return newLength; } @@ -869,6 +867,15 @@ public static int[] reverse(int[] a) return result; } + public static void reverse(byte[] input, byte[] output) + { + int last = input.length - 1; + for (int i = 0; i <= last; ++i) + { + output[i] = input[last - i]; + } + } + public static byte[] reverseInPlace(byte[] a) { if (null == a) @@ -887,7 +894,18 @@ public static byte[] reverseInPlace(byte[] a) return a; } - public static int[] reverseInPlace(int[] a) + public static void reverseInPlace(byte[] a, int aOff, int aLen) + { + int p1 = aOff, p2 = aOff + aLen - 1; + while (p1 < p2) + { + byte t1 = a[p1], t2 = a[p2]; + a[p1++] = t2; + a[p2--] = t1; + } + } + + public static short[] reverseInPlace(short[] a) { if (null == a) { @@ -897,7 +915,7 @@ public static int[] reverseInPlace(int[] a) int p1 = 0, p2 = a.length - 1; while (p1 < p2) { - int t1 = a[p1], t2 = a[p2]; + short t1 = a[p1], t2 = a[p2]; a[p1++] = t2; a[p2--] = t1; } @@ -905,15 +923,22 @@ public static int[] reverseInPlace(int[] a) return a; } - public static void reverseInPlace(byte[] a, int aOff, int aLen) + public static int[] reverseInPlace(int[] a) { - int p1 = aOff, p2 = aOff + aLen - 1; + if (null == a) + { + return null; + } + + int p1 = 0, p2 = a.length - 1; while (p1 < p2) { - byte t1 = a[p1], t2 = a[p2]; + int t1 = a[p1], t2 = a[p2]; a[p1++] = t2; a[p2--] = t1; } + + return a; } /** diff --git a/core/src/main/jdk1.4/org/bouncycastle/util/Bytes.java b/core/src/main/jdk1.4/org/bouncycastle/util/Bytes.java index c9f4a99398..526a27659e 100644 --- a/core/src/main/jdk1.4/org/bouncycastle/util/Bytes.java +++ b/core/src/main/jdk1.4/org/bouncycastle/util/Bytes.java @@ -7,4 +7,36 @@ public class Bytes { public static final int BYTES = 1; public static final int SIZE = 8; + + public static void xor(int len, byte[] x, byte[] y, byte[] z) + { + for (int i = 0; i < len; ++i) + { + z[i] = (byte)(x[i] ^ y[i]); + } + } + + public static void xor(int len, byte[] x, int xOff, byte[] y, int yOff, byte[] z, int zOff) + { + for (int i = 0; i < len; ++i) + { + z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); + } + } + + public static void xorTo(int len, byte[] x, byte[] z) + { + for (int i = 0; i < len; ++i) + { + z[i] ^= x[i]; + } + } + + public static void xorTo(int len, byte[] x, int xOff, byte[] z, int zOff) + { + for (int i = 0; i < len; ++i) + { + z[zOff + i] ^= x[xOff + i]; + } + } } diff --git a/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL1.bin.properties b/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL1.bin.properties new file mode 100644 index 0000000000..eeeccd0ab4 Binary files /dev/null and b/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL1.bin.properties differ diff --git a/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL1.properties b/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL1.properties deleted file mode 100644 index 01c2187362..0000000000 --- a/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL1.properties +++ /dev/null @@ -1,10 +0,0 @@ - -linearMatrices = 57,19,80,2C,F5,C3,05,3E,78,2A,D3,2F,DD,3A,EF,3C,B0,36,E3,4F,9F,1D,C4,2E,67,7C,3E,22,B9,1D,96,E7,DB,AA,0B,3E,7B,49,C3,D0,C8,08,3C,23,F4,C3,B1,9F,D9,88,DE,06,B2,C8,93,15,87,22,27,D8,75,84,52,0B,C9,E7,51,A6,CA,26,F3,87,65,24,A0,42,3D,E0,0F,DB,C3,EF,A0,4C,BA,7D,D1,40,C1,E7,FA,FB,DC,1E,8B,8E,36,9B,C3,31,CE,BD,A5,CC,16,A4,58,68,49,7D,E1,13,27,2D,A4,08,DB,6F,95,4A,F9,4A,DE,5E,E4,17,93,E9,E4,09,E1,A6,F8,35,92,EF,E0,A0,E9,BD,E7,A4,24,A4,AF,02,FE,1B,BF,D6,5E,17,84,95,AE,F1,AC,DF,2C,AB,12,52,53,55,52,45,04,4B,DA,38,33,6B,47,8B,21,35,A0,07,18,5B,C4,52,CC,A2,27,DB,B2,15,F4,BC,22,BA,97,5E,5A,3B,18,4A,E8,B6,C2,43,DF,5F,87,32,09,C5,40,06,0C,1B,4A,98,13,41,D7,43,DD,17,69,84,07,99,D4,3B,05,5F,15,2B,EB,22,80,EA,1B,CA,15,90,26,8F,50,11,E9,48,50,B9,59,37,AD,B7,13,E7,4E,48,4E,B0,84,2B,2F,82,E9,BF,FA,AE,19,A5,F1,FE,50,B0,4F,17,84,79,01,EF,1B,05,4D,E6,55,3E,ED,6A,7C,79,4F,69,5C,A1,94,3C,D2,87,A8,17,4D,38,AC,FC,4B,E8,C3,16,5D,29,29,DD,DE,EE,CF,48,E8,13,06,AA,DE,C6,5D,52,CB,AD,DB,72,AB,C9,34,66,E8,19,5D,F8,E2,BE,5D,46,15,02,EF,58,10,A2,1D,3F,29,F5,0C,B1,9A,87,13,65,C3,D0,83,9A,42,3B,EB,A0,C8,68,AE,24,45,A0,00,64,E5,6F,68,F2,2B,4B,3D,77,55,07,2F,3C,76,34,E8,41,EF,27,3E,4F,F9,AF,CC,F1,3C,5D,33,C7,B8,70,E7,C1,C5,56,78,C0,77,04,19,D7,08,5A,4D,B4,7C,2E,82,82,83,70,01,99,47,A8,1D,26,7C,F8,DC,D8,DB,E4,04,98,28,CC,BC,18,18,02,FC,D6,A0,4B,EE,0B,F1,1D,10,92,34,DB,80,57,AB,9C,F8,2B,D4,20,1F,4D,77,DF,C7,88,19,37,DF,A5,4E,4C,99,40,92,1F,3C,54,21,79,66,92,77,24,BC,4E,A7,89,D7,E5,E5,BA,F8,87,2B,3A,A8,6B,2E,80,92,C4,FE,65,B2,84,6F,B3,B5,14,C6,D6,62,8C,1B,FD,4D,1C,D1,48,FC,9C,99,4B,15,14,B7,F9,44,58,B4,7C,36,0C,F7,8F,35,D4,61,51,77,E0,75,BC,AE,D5,E8,9A,FE,CA,BB,B3,4D,4E,57,7B,E3,2D,BB,10,CD,2C,47,4E,AC,14,C6,B6,40,BA,5F,03,27,E0,3B,4F,21,E1,72,25,69,EE,81,18,5C,87,BA,F6,AC,D0,72,7C,AB,EB,D7,D1,49,24,C8,87,5D,B5,48,66,05,81,32,59,4D,F1,BA,B2,63,B7,B8,5F,6D,C6,11,D2,E4,42,60,BB,B0,D9,B7,0F,D8,B2,EF,9D,27,96,02,A1,D0,9B,C2,AB,4A,03,B3,95,58,DC,87,14,B2,4B,A0,7B,79,6E,8C,85,F7,7C,D7,BC,88,79,85,2F,74,50,28,84,A4,29,94,BC,FE,A0,E5,8C,C9,24,94,E8,D0,7F,22,C7,AF,50,7B,54,AA,6D,3F,24,CC,10,AE,5D,AE,45,45,AF,A9,A5,80,88,D8,EF,22,9E,02,E5,4F,7C,EF,8F,21,93,CA,5A,6C,3F,DC,A8,50,A5,73,15,3E,BF,76,AE,57,6F,15,E6,48,51,0E,FA,EF,A9,5F,2F,DD,5B,B4,FE,F0,0C,BF,AE,97,59,00,D7,38,DE,4A,EC,2A,19,A5,09,12,BC,B9,D2,A2,E4,0F,E8,8F,E1,03,86,98,05,51,83,0F,99,99,43,44,C3,F2,86,32,D6,CF,22,72,A1,CC,53,AA,07,B5,AA,D4,E7,1A,63,75,71,4A,8A,FE,14,EF,16,66,17,E1,DB,FB,2C,74,65,9A,49,16,96,75,FB,F9,4B,BC,2F,69,E0,3B,78,16,97,1B,63,A0,E2,3A,A9,25,C8,EE,28,D0,CE,DE,07,CE,D1,FF,C5,F2,0A,38,44,FF,97,CB,FB,3A,DB,93,5B,B4,94,95,83,B4,EE,AD,8D,48,80,D8,84,D7,41,09,3A,6E,5A,74,4E,EE,53,1A,16,C0,78,DB,82,FF,6A,AA,EA,93,CC,99,D8,B2,B9,82,FC,47,18,DB,2F,E5,93,4F,BC,91,74,B1,93,CD,98,7A,16,E4,38,5E,2A,96,5E,8C,45,91,ED,05,3B,73,76,2E,B1,77,50,FB,D1,45,3A,13,16,57,C7,AB,35,DC,DA,F2,DA,67,37,24,42,E8,00,FB,3F,5E,AA,E2,62,59,64,F1,6E,CB,B7,D0,B9,16,B0,50,A1,D4,0B,3B,5A,B9,86,96,BE,20,D5,09,B5,F7,F3,9F,37,CA,59,99,85,CC,D9,AF,30,B1,66,FB,CA,D4,85,97,C4,19,32,5F,53,E4,5D,31,43,86,75,EE,CF,73,6A,FF,C8,4E,49,B3,A7,E4,DF,E2,23,9A,B6,92,6B,C0,B4,14,74,A4,5F,E6,EB,95,DF,50,33,6D,2D,D7,B9,11,79,E8,C0,44,95,FA,35,7B,39,BB,B7,D4,B1,ED,99,24,8D,BF,EF,1A,4E,E4,38,1C,A4,2F,BD,29,6F,3A,86,F8,E6,CF,76,CE,7D,0A,88,8A,E9,54,55,E2,AA,D5,AA,B9,5F,A2,EE,0D,D9,CA,2C,51,28,37,34,FD,D5,01,63,6C,86,31,4F,10,8D,4B,F1,1F,49,6D,63,A5,5D,6B,33,12,64,54,76,F5,25,31,6F,D4,13,10,E7,C7,E5,C0,9A,DE,69,D7,DC,2E,FE,04,8F,7E,A6,FE,2A,0A,AE,F1,36,DA,04,71,54,E2,82,4A,A0,32,D8,00,5D,49,CE,98,89,2C,73,D9,D2,1B,98,E1,A7,44,ED,DF,F1,2A,7E,C3,80,75,22,38,42,61,4F,E1,E5,58,CB,6D,74,CF,02,36,67,8A,78,A2,12,F9,43,8A,A2,D7,B5,76,B2,B0,B4,E0,B9,6A,FB,A3,44,E9,36,72,46,28,A0,23,92,0F,9B,FA,A2,DD,D9,ED,2F,A5,57,FB,87,6C,C4,25,E4,75,2A,66,90,B1,65,BF,EF,20,76,6C,CE,80,49,51,02,06,5F,F3,85,37,C1,0B,AA,C2,FB,74,A9,B9,00,D2,0A,01,67,51,AE,2E,C2,66,99,5E,B0,DE,9D,2E,C2,BC,2C,FA,82,21,45,60,47,B8,62,43,51,70,8C,7C,18,5A,17,99,4D,3F,08,77,BB,41,9B,42,B6,26,28,78,2C,8A,A9,3D,86,D0,E7,C3,53,42,EE,0A,AC,33,28,06,FC,B5,77,F0,94,2B,17,DE,CE,1C,AE,15,DC,1B,44,D1,5F,0C,DC,18,AC,41,E8,89,09,34,94,6B,97,E9,83,EF,05,C5,5A,4F,68,70,B8,BA,D0,E3,AC,20,A9,4D,53,7A,97,F4,AA,15,51,5E,67,D9,71,1F,2F,7F,DB,69,88,CB,83,CC,87,73,EC,2B,AC,30,B6,F1,46,8A,DF,E5,84,5C,AE,9B,8B,EB,20,2A,56,DD,9C,F8,7A,3C,AD,48,C5,45,FD,D9,07,A6,02,A9,9B,B9,C7,7B,12,65,F0,C2,08,C0,77,76,D2,3E,AE,08,76,6D,61,A8,41,37,CB,68,75,35,53,0A,7B,B7,2B,5B,16,D0,A4,18,FC,46,1C,2E,06,B7,0F,1E,19,A9,C6,EC,AB,05,65,70,55,5C,72,AD,1C,1F,2F,30,76,C4,3F,D4,BC,38,FD,22,FD,84,13,FB,1C,AB,45,B9,6F,A8,DE,96,6E,24,BE,C4,E7,33,DF,FC,B5,24,67,1F,4A,1B,A2,31,3D,46,06,5D,6C,96,36,B7,3E,2F,6C,9A,65,2E,BA,0F,03,17,DB,85,58,91,E3,93,4E,FB,77,D6,66,C3,11,2E,BA,3E,A9,AA,17,F1,FC,CD,51,AE,39,5E,83,3F,07,40,F9,34,BC,D1,06,42,A7,68,18,53,CE,04,C2,A8,79,F0,2D,03,83,AF,C6,43,37,2A,4F,D4,0A,CE,60,DB,39,0F,FC,57,E5,98,34,44,AD,DD,8F,EF,9E,19,B2,69,E1,A2,8D,0E,10,13,CE,13,90,D9,FA,A3,3C,5C,33,6C,83,CA,44,65,B2,44,51,4E,E5,DD,B8,AB,24,7F,44,71,D6,9A,E1,D4,E3,46,8C,DB,94,CD,DF,CF,49,E2,90,57,AC,2D,2A,3D,26,38,1A,47,43,35,91,F3,41,56,94,4A,5B,D1,0E,67,08,1C,FD,17,17,57,EE,EC,19,72,F1,40,6E,E6,13,46,84,53,D0,D9,A7,7A,61,DB,E3,CD,0D,88,DD,66,4D,C3,08,01,78,DC,1C,1B,B3,0D,5F,66,58,E9,F4,21,D6,60,E2,52,A9,CF,31,A7,80,98,54,D1,64,0F,28,59,BD,A1,27,15,50,E4,13,96,A5,62,C9,CD,C2,A8,30,4B,DE,D5,5C,BA,DA,03,C3,E8,31,6B,EA,EC,B3,4A,44,BE,0B,BE,71,D9,38,83,CC,9C,C4,65,C0,46,19,84,88,84,82,FE,3F,0C,45,AE,D9,C5,A0,A3,CE,B5,FC,E9,C1,65,CE,A6,4A,3E,25,F6,2F,C7,1A,5C,F7,06,43,25,8C,B1,2D,72,72,1D,C2,92,10,81,FE,C4,27,38,F2,83,83,40,C5,0A,DC,BF,8A,7F,02,FB,ED,D7,67,36,21,DB,DF,35,E0,74,37,43,7B,97,2E,4C,30,50,14,59,AE,E9,DD,4F,58,D5,14,F8,44,1A,13,F7,62,6A,BC,BC,1F,A1,37,4C,F4,C2,0D,88,65,8B,9F,61,A9,AB,EB,8F,6B,1C,98,8F,95,D9,17,CB,67,C2,8C,CD,49,A4,FA,B4,A4,23,39,F4,51,D8,A6,F6,E5,63,B5,54,48,99,33,CC,EA,DE,BC,5C,90,D3,9A,75,4C,3A,E3,A9,37,74,7D,17,40,D6,3E,21,CD,47,06,96,55,13,A3,E5,2F,9B,98,E0,A0,99,72,5D,9C,84,22,A0,5B,6D,C8,08,DD,95,49,1A,7F,99,55,B7,92,37,54,40,A3,B3,12,51,2E,B2,D4,94,4D,D8,50,AC,81,7C,1A,F5,DC,39,CB,A3,40,51,A3,A9,06,8B,36,4E,3A,35,E0,DD,30,78,41,52,D4,7A,6A,DB,CD,91,5C,B1,8C,EF,09,CD,FA,B3,72,38,7A,AF,09,D6,3F,FB,8B,80,27,F1,9E,5F,15,A3,CC,2D,62,19,65,CD,B2,FB,55,04,17,E6,87,5D,A6,0C,E8,EA,5F,83,FC,2E,B7,D2,96,9C,CC,C2,D2,00,A0,FF,4A,0A,A1,08,B9,E9,81,EA,A3,C2,17,88,41,B6,5F,FC,76,46,C5,38,1F,44,5B,89,67,3C,C1,AB,AA,4D,F7,84,98,35,A2,99,66,93,BF,5D,F6,BB,D0,0D,78,9B,DC,56,EE,CC,C8,40,FD,D0,07,D7,71,B6,1E,C7,33,93,0C,81,7D,90,B3,48,CD,D1,94,EE,13,08,A6,88,13,AF,58,EA,D3,87,96,1A,1C,50,00,1F,C5,07,19,AE,2E,61,19,1B,4D,21,32,F5,02,5F,B0,C1,7E,5F,FD,F6,B6,18,B5,C4,0A,53,C2,9F,96,98,1D,D1,13,B1,FC,99,CB,C7,79,E3,98,4A,09,FE,4A,FC,B4,A2,26,6C,0A,AD,2A,CF,DF,2C,5E,3B,54,A1,FE,2A,0E,0E,69,1F,51,1B,7A,CA,E3,A0,EC,12,F9,B3,07,21,7B,42,F3,CB,E2,22,0F,D2,D3,22,9D,AC,E2,24,DA,FE,58,CD,B4,FA,15,CF,24,8D,F7,BF,6F,F4,03,5D,0F,8F,65,BE,5B,A7,42,0C,7A,07,EF,D9,C6,75,27,FF,9E,15,BA,40,D1,BB,DD,98,C8,8F,B1,35,02,19,7C,B4,E9,E6,FA,2D,2F,47,EF,10,1D,8A,08,7D,6A,38,8D,9E,9A,66,73,1E,24,CE,AF,B2,EA,6D,38,D9,D3,E2,F8,74,FC,0B,62,91,43,6E,35,20,06,C3,3E,9F,0E,93,12,DD,81,CB,64,C8,50,AA,FA,43,DE,69,A1,EC,5D,A2,1D,AD,88,AE,D5,1B,44,A2,24,7F,D6,4E,D6,01,07,A2,4C,AD,58,52,E5,FB,37,AE,5A,D6,6F,90,01,8F,8A,C8,9D,BE,75,C6,98,D2,B3,E8,AA,73,E3,83,0B,32,64,84,DC,B0,CF,98,2B,91,48,81,2D,73,FF,43,37,71,15,84,50,01,95,F5,B7,21,8F,4D,3A,67,7A,3B,AE,2E,F1,C9,26,0C,C8,48,19,64,73,79,7F,6D,06,28,4C,2E,4B,A6,3D,99,DE,DA,A5,40,AA,BC,4C,2B,87,43,DF,FE,B1,F1,61,86,6D,C5,52,23,43,1F,D1,DE,A6,F8,D6,DB,24,1B,90,A0,7D,68,AD,18,35,4D,2A,E5,38,99,6F,91,BE,23,DF,74,26,07,14,76,4A,C2,8B,7C,BB,AA,0E,87,13,47,F6,3C,2C,A1,2C,FB,AA,C9,FF,BF,0A,5E,26,F5,52,13,6E,58,A7,4A,B6,DB,AB,45,C0,DE,D2,53,A1,B9,FC,76,1B,39,88,F7,0A,AD,17,5D,93,45,F4,C6,E3,AC,9F,19,D2,E8,C3,A2,D7,6D,01,61,4E,72,F4,BA,4F,C9,7B,3C,AF,F0,5D,8E,9E,99,9B,5E,06,C4,7F,2D,1D,BD,33,AE,35,4F,B2,1F,0E,FB,4E,D6,A3,63,74,C2,C8,36,E4,7A,63,B3,A2,1D,27,A0,30,0A,53,A5,BD,7C,52,C9,4F,E1,DC,F4,3D,30,3E,20,E9,73,41,36,AA,A5,95,78,37,B2,4A,A3,65,C6,C0,EE,B0,67,DF,A6,C4,2D,ED,06,5E,D6,87,14,B0,B4,7A,58,63,61,D7,DA,0D,12,A2,CA,8A,1A,3B,5C,94,3A,2B,D6,59,5B,10,B5,2A,24,BA,1C,25,03,1A,D3,EE,19,D4,FA,10,7B,52,EF,9A,21,F6,B1,AC,44,60,F5,9F,7C,C0,CB,7E,64,53,C4,C2,D2,00,D0,CB,A5,52,D0,56,36,8A,19,19,92,7F,19,6C,3E,32,2B,CE,3B,6A,F0,5C,E1,67,3C,A0,F6,CA,14,E3,C4,1A,7C,0B,B5,00,FA,EE,78,29,FB,A1,47,AC,80,D5,80,59,7C,93,4C,31,0F,FD,E8,36,E8,05,B0,92,B9,37,29,6F,AB,00,87,EA,E5,A3,BA,1D,49,32,6C,2F,64,77,79,4E,E5,29,9F,86,C9,09,4F,0F,F3,5A,60,F1,6D,DB,4D,94,14,69,35,14,C1,1B,C6,BC,C9,E6,13,4C,DD,80,1B,BD,84,1F,B5,86,3B,15,AC,F8,F9,85,67,26,C4,C3,15,3F,FB,95,68,87,9C,36,DB,79,6B,85,E1,59,D8,D4,20,76,2B,29,1A,8D,A5,7F,27,A7,F5,CA,82,33,94,A8,5A,3B,F1,90,58,69,F4,A8,47,A9,DF,80,82,83,E7,3D,3A,F0,C6,B5,3B,99,A1,0B,D8,C5,3A,C4,D2,37,F3,2C,FB,2F,78,4C,E2,D7,A4,8C,5B,67,74,61,15,91,10,09,AF,F7,06,CB,C7,D6,43,DB,04,DD,F1,B3,2D,61,8B,F0,AB,6C,21,69,D6,85,0B,97,9B,0E,D4,92,37,35,67,89,21,ED,1C,00,9A,F8,9A,E1,AD,95,AF,45,0A,CB,82,84,95,3D,E5,B6,AA,F5,9E,FD,51,BA,FD,29,E0,04,FD,55,90,29,D0,03,D6,EF,40,E7,55,F9,1E,F2,07,C3,56,10,7B,1B,C0,CD,40,F7,06,99,83,A6,45,3F,62,0E,5E,17,21,6A,2E,A3,63,6F,F7,F1,DD,4B,C9,C2,62,0C,5E,84,0A,57,10,90,93,46,4E,60,1F,0A,2C,6C,3D,7D,24,66,23,64,98,66,5B,38,A8,74,A9,0D,50,E2,DC,06,86,0A,98,83,0F,6B,05,CF,68,C6,D6,D2,51,46,2A,E5,D0,EA,88,58,5E,4E,DF,2E,59,AF,2C,A9,B1,DA,B8,01,75,16,3C,0A,5E,06,88,73,66,B9,AB,E1,6F,91,28,BC,0A,77,77,41,40,E8,6E,B5,4C,D0,FE,8B,2E,9C,EE,9B,BD,21,BF,49,CC,E2,E4,E1,63,39,08,74,74,64,B8,A6,12,0F,08,79,3A,0D,8A,61,61,B7,5C,6C,32,C1,17,89,07,33,3C,40,97,F1,13,F9,04,9D,21,A5,EE,75,3A,CF,31,FF,1D,B8,62,88,25,2E,86,3E,CD,F3,19,5D,15,43,6D,4A,FD,57,83,53,B7,BB,B4,7A,8D,03,F6,6D,89,42,F8,59,55,4C,96,AB,46,F2,8D,80,2B,28,FB,DE,6C,9C,B9,72,E5,B2,35,3A,E8,C6,53,96,73,8E,D6,0E,CA,2B,C8,FE,D8,E8,79,CC,33,76,4F,63,E7,FC,07,C8,7B,1B,B6,8E,1F,21,B6,3F,BE,44,55,56,78,16,DA,21,B8,73,9C,1D,1C,2F,F0,33,C8,AA,E6,66,C9,32,F8,F1,2E,31,D0,C4,B0,88,E8,7D,69,3E,DE,1C,10,77,56,B5,FE,C0,20,2F,3A,25,C0,52,EE,E3,82,F9,BD,24,8D,7B,AD,DC,8B,0A,35,D3,8E,3B,58,A1,6E,EA,0E,AB,93,75,C1,DA,B5,EB,82,6D,C6,EC,52,E3,13,C5,24,0D,33,A9,5A,98,25,50,5F,67,D7,AC,D4,BC,DB,2D,D9,E9,E7,EE,08,98,85,D2,51,51,04,E0,D4,B6,73,56,68,E2,68,AA,A1,31,DE,EE,57,58,B4,34,15,2C,37,27,28,D7,88,B4,40,0D,6D,0F,C1,B8,AB,0F,D8,3D,F4,9D,06,53,37,FC,14,4F,FD,2A,91,A9,C1,57,04,13,80,7A,2E,98,65,62,1C,32,60,CF,53,1C,20,3D,E3,D5,F4,65,CE,22,97,91,10,6F,1D,2D,45,DB,06,EA,33,23,77,93,E3,8C,A0,7D,86,74,4E,16,78,E6,F9,1E,B2,7A,7E,18,B8,E6,0A,DD,0C,EF,3A,2A,28,99,97,A0,0F,B0,14,11,A3,16,E3,CF,06,92,CF,AD,E6,E4,19,F1,36,2C,94,09,37,C9,4E,8A,15,9D,09,C1,8D,D0,82,2C,7A,8B,76,FD,4D,C4,50,DE,54,B2,98,31,4D,32,99,26,DE,21,C9,AE,66,9C,7B,71,67,C8,A2,45,2B,9D,96,0C,5E,0C,27,AD,1B,C8,64,78,66,18,53,B7,63,FA,37,69,8C,CA,09,17,7C,92,4B,D1,00,6B,4B,71,42,E4,C0,61,18,AD,A8,08,29,B5,0E,92,BA,C3,F2,9F,BF,8F,E3,B4,43,CD,CB,00,E0,B9,1E,93,61,10,21,2E,EE,AF,E4,B7,23,9C,AB,A6,4C,02,93,53,59,6C,71,23,13,0F,1A,E5,15,0E,0D,DF,EC,A7,4B,5F,97,9D,30,7C,56,35,21,E7,AF,42,D4,BC,71,71,53,57,69,94,B4,52,F3,EB,61,3A,11,F7,CF,00,85,E0,E6,16,D5,0B,1D,8D,70,A1,13,9A,F6,FC,91,88,F0,89,88,57,56,4F,DB,03,D3,E6,D5,39,C9,EE,88,2B,04,BF,09,CC,E0,39,E1,D9,7D,EC,F2,F0,5C,73,79,24,44,26,F1,DD,6E,7C,59,AD,C5,F7,46,96,26,96,DE,97,D9,A6,09,23,1F,E6,A8,27,27,2F,C4,69,4A,78,4A,1D,40,0B,A3,0C,3A,DF,83,A1,BD,A9,BD,78,22,B5,E2,77,2A,C1,12,27,3D,E1,FD,80,B3,09,52,84,4C,D5,B2,B9,05,C0,53,A4,B2,AD,4D,4F,94,5C,91,12,83,7A,1A,16,B1,6D,B5,8B,41,85,13,56,7E,56,F9,2B,68,E8,AA,E4,E0,D1,AB,88,E4,25,6B,5C,A0,19,01,7E,46,25,72,16,33,CD,E2,41,9F,F3,4F,45,45,B8,A3,FF,87,79,07,14,35,CC,47,2C,66,53,75,05,25,6B,BF,92,80,34,6C,CD,9C,E8,F5,44,65,A9,28,CC,C8,00,FE,BA,F5,C5,A0,8E,71,90,E3,CC,3C,42,F8,F0,83,9A,F3,7E,C4,46,C2,23,75,1B,97,18,04,97,78,66,CC,FD,B2,D5,9A,EF,91,E9,D0,BC,36,18,A2,60,2E,6D,14,DD,87,23,4B,E4,62,31,A8,0E,5D,F9,42,CD,FE,1B,C3,3A,94,88,3C,F8,0F,5B,DD,E8,69,DB,68,1F,95,10,31,8F,E8,AC,E1,EF,09,59,FE,4F,A1,17,E5,F7,70,73,8D,56,0B,01,92,99,28,C8,BF,5D,D1,66,62,D9,0E,0E,C9,B2,28,66,BD,9A,B4,31,28,0A,02,C4,EB,EA,15,AB,F3,35,D8,01,8D,25,F2,A9,80,85,F1,92,A4,10,09,9E,6F,12,46,F8,00,34,F5,0E,F8,78,32,F2,5C,C6,FC,F1,DF,F0,AE,A0,CF,AF,B2,6B,A7,89,D1,E0,82,36,1C,BD,4D,08,52,DA,8F,9A,36,51,72,19,DC,9B,39,45,27,53,97,3F,3F,C5,19,55,B9,87,85,25,4C,84,35,5B,9C,E8,17,C4,F0,93,E5,2C,CA,D2,14,62,3C,6E,2D,68,2C,78,F2,F1,CD,40,B6,FD,48,6A,C7,1A,88,D1,DA,62,B7,C9,AC,DE,B2,4D,0D,73,19,86,7B,25,66,6A,F4,15,93,B6,81,9F,B6,99,E3,A6,9A,12,D3,F8,61,6D,11,51,66,F3,A0,38,A0,97,DB,54,C7,02,C4,69,61,2C,E5,ED,01,9E,78,0F,02,F6,11,C5,18,7B,B9,D2,FA,9B,80,9E,0E,B1,D9,0B,B0,27,CD,59,E7,66,48,48,8D,89,75,01,D8,A2,81,DD,55,F2,65,9B,90,55,E6,FB,27,BE,A4,1A,99,5B,A7,57,64,C4,75,64,1A,96,D0,62,6D,8F,E3,0D,92,8C,9A,C2,B0,0D,EE,2C,08,2D,C9,1E,B9,78,16,5E,82,73,7C,8E,53,40,01,51,2D,F6,EC,D5,47,18,21,A8,B3,8C,28,89,41,B7,0F,69,AE,92,B8,99,02,F0,DE,E2,2A,2D,D5,EB,DE,E1,34,E0,C5,E0,76,B5,2F,6C,26,5A,15,DE,2F,A3,D6,21,B1,9E,CE,20,49,72,10,A6,66,A4,C2,B6,EE,F7,03,1B,30,5E,B0,E7,AA,61,25,1E,63,A4,A0,0C,93,AE,9F,5D,6A,E1,6A,7F,51,1C,58,B6,CB,4F,F8,68,3A,E4,C5,74,CC,5C,2D,01,A8,CA,90,F6,99,EA,0F,29,56,67,09,C6,9B,56,2D,04,E7,2C,3F,E3,23,8E,72,C5,3D,58,10,96,D1,78,CC,4C,BE,96,0F,49,1E,C3,79,2F,42,AB,93,39,59,EF,42,D8,F9,78,DE,24,DC,38,08,DA,CB,EF,C0,7B,DC,20,14,35,2C,38,F6,BC,96,E6,27,61,54,59,C0,30,B8,5A,CE,62,D0,A8,6C,6B,8E,B7,6B,93,5C,94,31,1E,29,6B,69,EE,E8,76,17,4A,3E,41,43,1C,0E,79,1F,30,D9,26,5E,FB,41,0C,26,1C,5A,36,99,19,68,65,91,97,5E,83,7E,89,D3,E0,CC,D6,FE,48,CB,EE,A8,13,D5,CA,71,20,A6,F7,0D,E2,99,82,3B,02,BC,73,65,1F,86,08,1E,8D,32,7A,73,55,54,78,65,74,8E,2E,EF,F3,C5,B0,4A,13,D4,F5,30,DA,B8,9A,80,EC,F3,E3,D5,B7,63,16,B5,55,8D,65,10,D8,D8,9A,8B,AA,C9,4B,61,2C,09,19,03,82,DE,6F,07,BF,B0,08,22,E0,E2,A4,7C,6D,E9,D1,0C,45,5E,3A,E4,44,9F,CC,AF,90,E8,B5,AF,78,52,48,13,76,6A,96,B0,1F,E9,BF,8B,29,24,81,53,AB,D1,2D,F3,FC,99,B3,9C,69,30,2C,39,88,C2,F9,64,AD,92,9E,E9,8F,8F,10,83,B2,2C,67,71,43,C6,62,63,A4,73,49,DC,F4,79,D2,A4,F8,36,C8,19,F0,75,9C,33,E2,ED,81,04,A3,36,AD,D1,A9,B9,8F,DF,2D,18,FB,EA,07,BB,EF,59,1E,37,72,C4,3E,72,4E,42,B9,D7,2B,A4,FA,05,C7,7D,93,C9,79,D3,21,7E,86,8E,7D,CD,09,69,51,A3,7D,66,DB,6F,21,42,09,E5,5D,46,E8,66,F5,77,5D,A4,D3,5D,51,36,50,40,8B,B7,29,47,3D,23,BC,16,56,87,1B,A1,BB,9F,B4,24,24,6E,61,0E,9C,3C,71,14,6B,73,99,76,0C,B4,3A,73,46,47,EE,52,F5,40,C7,70,71,5E,76,07,6E,79,60,33,D4,A4,AF,62,24,8C,2A,AA,A3,3C,C3,DB,CB,8B,46,C9,B4,AC,78,E1,D9,03,F3,96,66,55,E6,EB,6D,8F,25,90,E6,CD,73,9D,D5,17,44,36,0D,58,DD,41,21,7E,9B,24,05,A6,DF,D4,B1,EA,84,11,07,1D,DB,65,07,3B,6F,F7,87,2E,0A,EB,6F,4A,D7,CA,5C,C5,41,3B,BE,9C,D2,9A,B9,18,A8,73,E7,54,F8,48,3B,81,36,D0,2D,5C,2F,AA,3C,00,A5,F6,D8,B7,D8,47,DD,BF,00,CF,CD,A0,66,55,63,6C,51,50,13,64,73,72,E6,A8,E8,7F,6F,FF,93,43,B5,5E,25,3B,F9,CD,C2,32,EA,0C,E4,92,8E,F1,B8,27,74,0F,37,59,5B,CE,08,97,0E,D5,40,74,9A,87,B9,FC,CF,4B,80,BB,EE,D6,EE,1C,67,48,03,C1,7F,39,2D,0F,09,2E,BE,99,95,56,F0,89,73,A3,B8,B6,BF,58,F4,87,4E,E1,CF,AF,F1,47,5C,63,EF,D6,FC,94,57,02,F1,5A,69,50,44,12,C4,F7,B1,0D,6B,E4,E8,BF,DD,84,11,28,3B,9D,9F,8D,C3,63,8C,3A,43,2A,F9,A5,AB,13,F1,75,DF,BE,3B,82,AC,AD,15,75,BC,E4,B0,62,8A,29,60,1D,28,C3,3D,31,96,DF,75,3B,2C,44,9B,5B,9A,79,3D,A1,2E,95,92,EB,D9,F5,78,D1,58,BC,18,C4,D1,62,14,C3,36,50,78,11,BB,FD,AE,84,77,1F,59,B8,52,27,38,A2,63,3D,4A,C4,86,BC,FB,14,E2,72,A6,9B,02,5F,80,D0,15,84,DE,CA,29,39,A6,EE,F2,4D,37,2D,A1,01,F3,03,7B,83,98,93,D1,A3,B0,C3,4F,55,75,CB,2A,CA,D8,4D,32,1B,A9,D5,CE,98,B1,DE,72,2E,EC,49,3A,63,B1,A5,19,89,EC,E5,58,E0,32,E4,CC,18,D7,19,EC,75,55,EC,DB,FF,2E,E8,EC,8C,50,2D,FA,27,98,EE,EF,1E,72,28,A0,5A,6C,78,F4,E4,88,37,A1,B2,B5,4E,23,54,DD,73,EA,97,B7,B0,F9,0E,9F,65,E9,55,36,FB,A8,BD,21,F9,E6,4B,15,50,15,F8,70,7F,6F,6F,CF,C1,94,9A,A0,9E,89,87,0B,41,5A,8B,64,89,C4,53,17,6A,F3,69,E8,D0,B5,6D,F1,18,D4,F5,37,8A,CF,63,4B,01,D0,D9,B3,F7,4E,89,A4,0C,FF,1B,DE,20,A6,F3,E4,64,F0,A1,07,C4,FA,3D,0C,5D,B6,2C,34,7A,DC,E2,73,15,7A,62,71,EB,27,A0,87,B3,70,25,23,00,AE,A2,4C,6D,F7,0B,35,11,D3,51,2B,9A,79,1A,FF,EC,45,C2,28,FB,BD,44,9E,4E,C2,E0,F9,E8,97,92,96,F4,A5,08,52,2B,EA,CD,8F,6B,49,A7,8C,F7,5B,58,21,1B,1B,E7,91,A9,69,D0,2F,2B,EA,6F,9E,03,FD,41,4B,C9,51,9B,5D,F8,E0,48,C9,DA,81,ED,59,58,B9,27,94,95,6B,38,32,55,20,61,4E,2A,B1,C6,F9,43,A2,8D,CF,A2,CA,C2,C3,3E,55,FF,B2,DF,88,9B,57,10,7E,FA,94,A6,C2,29,F7,92,77,1B,84,C3,B3,AD,BA,FA,B8,4E,0C,A0,10,F8,1D,DD,4F,C5,47,B6,D5,B7,8E,F6,F8,71,A5,7B,C3,FB,9F,01,03,14,BB,4F,86,47,42,12,61,0D,7E,E3,1F,55,7C,CA,88,3F,D9,84,13,2B,75,6D,75,3D,F6,43,31,62,37,98,9A,62,35,B7,90,6B,28,9E,CA,DF,F8,7D,73,39,DE,E9,8F,56,BA,C7,DB,9E,57,6F,DE,47,0A,CE,24,9F,FA,4F,97,02,04,B7,BB,51,78,F7,3E,5A,57,65,BF,F9,50,00,60,C6,D1,A4,2E,9E,CC,35,D7,5A,3F,9B,C9,D6,85,41,49,93,10,FF,3C,14,A1,17,C1,83,E0,4D,4B,06,A1,16,B0,1E,B5,D7,12,3D,A4,CD,19,47,B1,09,51,8F,58,98,C6,47,3A,D5,33,06,C2,1E,25,9D,69,5B,AD,B8,BF,3D,2A,C8,9F,07,89,06,A6,85,A7,36,88,61,FE,88,06,46,CD,26,E0,D0,32,B0,16,F1,5A,B4,1F,81,1F,0A,26,0E,51,A7,1A,33,60,76,CA,4A,6E,61,CF,CA,35,FB,30,0E,8F,84,79,45,5E,AF,8A,12,CE,9E,36,94,2F,63,E2,C0,82,44,99,D2,52,7F,25,D5,9F,80,F2,D4,C5,A1,43,D7,4A,8E,F0,BD,1E,AE,07,3C,01,1C,1D,53,64,6D,30,9D,9B,6A,29,49,32,9D,44,A1,91,4D,75,16,FF,1C,C1,34,55,2E,9C,FC,09,1F,6B,EC,10,DC,0E,D5,64,F5,B4,A4,A6,62,42,D4,63,53,34,31,B0,54,40,12,64,F2,BD,45,41,A5,8E,95,82,97,00,F3,09,C7,8B,75,AC,1C,DA,07,95,FA,5B,18,29,74,57,43,F1,C2,7F,A7,23,65,16,C2,34,06,26,D4,0D,5E,51,B9,78,C1,67,92,EB,52,2A,FD,A4,69,D5,F7,65,98,6D,EC,2A,39,C3,5E,A0,43,5A,B7,13,E0,86,6C,60,FA,B6,3A,85,54,9A,BD,0C,E5,08,A5,41,68,A4,D3,D3,FA,3C,F0,38,1B,DB,2B,E1,5A,F0,C4,5D,FD,0C,24,8E,2C,F0,E1,D9,30,83,4F,B5,4F,66,33,29,97,71,A1,71,66,12,58,79,B5,FA,2C,79,59,43,F8,E7,F4,91,8C,3F,0B,49,EC,88,1A,FC,CB,73,3F,14,26,7F,A6,D6,D9,69,32,B7,19,79,E2,5A,EF,2B,33,E7,FD,57,FD,3D,73,BA,46,F4,3F,D4,D3,44,66,92,2A,62,71,4E,7F,2D,34,7D,07,7B,2E,84,24,1D,01,DE,39,A5,63,E9,03,B4,F2,84,ED,9F,D7,D7,6A,31,C4,AF,B4,36,94,BB,C8,94,83,55,71,C7,3D,98,BF,8D,BD,BB,65,AA,92,07,8B,88,E7,F3,A7,30,EF,48,7F,42,73,7B,E5,D9,9B,79,4A,C2,68,8E,70,FE,88,DC,25,24,16,7D,58,CE,06,E6,15,EE,7E,7D,AB,12,CE,B0,EA,94,8A,9A,2B,4A,D4,B2,E7,80,B8,8A,D3,6C,C8,0A,7A,99,77,FE,D0,1B,CF,72,D2,9F,A3,28,5E,0A,96,4F,76,5D,BA,22,80,CA,26,15,A3,0C,CB,7B,0E,F2,5E,56,E2,D5,61,F8,E7,78,1F,C6,F9,77,5F,13,FF,0B,BD,F9,09,FD,BB,31,E4,24,E2,71,D2,DD,9A,73,C0,E9,E2,60,7B,BE,5C,64,48,1C,50,20,FE,C1,68,39,F5,E8,E2,C0,1B,92,91,70,25,89,18,26,CD,3D,06,8C,41,9D,50,69,DC,36,30,78,31,A0,2F,25,1C,95,63,E5,84,F3,B0,78,2C,AC,16,6C,90,00,F7,23,95,B5,1E,C7,49,03,08,ED,7F,8F,60,99,72,F5,B8,6B,CC,D4,6E,67,49,C7,C0,43,47,E3,DC,FC,05,D0,5C,83,3D,E8,47,ED,18,1D,66,E8,26,D4,79,32,C4,F2,45,9F,FF,15,BE,04,1F,3A,93,CF,2A,A0,D6,3C,45,06,3F,D1,59,9A,F6,3E,5A,7B,B1,EB,29,92,88,28,D4,9B,9B,09,DD,1A,F9,D2,BF,0C,7A,DD,AC,4F,E5,F8,AE,55,0A,13,80,F3,E1,BD,A9,B3,87,89,8D,2A,FC,7C,8C,BC,41,27,D6,41,30,13,34,54,F1,CA,04,67,76,41,71,E5,85,1B,C4,B6,2D,66,40,FB,14,50,55,EE,AE,EC,BA,99,99,DF,2E,44,41,1C,CC,1F,57,7D,84,4A,F3,E7,F0,F0,5D,A2,0F,9B,F9,2E,B6,69,4A,92,3C,29,34,D1,3F,91,EB,BD,C5,79,4D,A5,EB,5D,3B,48,9F,24,97,5D,54,4D,DA,17,8B,BD,B9,68,4E,5C,A8,2F,6B,49,88,E1,4D,3B,B8,E8,21,9E,87,0E,35,FA,13,D0,E9,53,42,69,0B,6A,48,9D,CB,8F,7E,72,21,04,5B,80,C5,9E,22,77,36,D4,20,C6,80,D8,BA,C0,6E,D2,6A,13,25,20,0F,8F,29,AF,9C,7D,48,91,B3,62,75,A8,6C,F0,21,FE,1D,7F,EF,CD,3F,A7,40,CF,6F,C9,12,31,28,99,2E,50,B0,44,5A,8F,03,2C,19,18,6B,16,C4,B8,40,21,10,6F,F1,C2,3A,64,E3,39,91,9E,DF,6B,40,C1,77,FE,EB,E8,03,DA,1E,70,F3,7B,C4,A1,FC,E1,53,9D,18,D6,80,FE,50,2B,8B,EC,71,2B,D1,31,17,D3,6B,6A,0E,77,F1,5E,FB,C3,32,0C,3C,C9,84,1B,D0,BD,52,99,B9,B6,F0,35,03,5A,29,0F,BD,58,F3,EF,11,C4,68,B6,A7,62,CE,13,15,60,FB,7E,BA,93,F9,0F,62,E3,F4,28,FF,F9,FC,27,9D,2B,A7,CE,C4,E4,FC,F4,39,1E,4E,E4,E0,24,19,F9,90,A3,B0,87,7E,4C,5B,40,A6,0C,61,27,EE,6A,E9,9E,B6,9B,3A,E7,9E,42,C2,56,8F,57,91,17,5D,B2,98,6C,96,0B,E7,56,3D,97,57,CB,9D,3D,02,39,8F,62,58,79,BF,91,9B,13,F2,93,3A,4F,85,60,1A,86,E0,D1,4D,6B,16,4A,2A,6A,47,26,DA,FA,7E,6B,54,34,A9,4E,F9,94,21,A1,AA,99,8F,E8,36,48,00,E9,EF,C5,D8,A7,D3,AB,5C,C9,96,AF,4A,D6,BD,14,6B,43,BE,C3,A9,60,B2,32,84,F2,E0,C5,49,C9,1A,1C,A5,8F,DD,E2,96,C1,1A,AC,4A,BF,D2,64,4F,B6,47,61,1C,A7,D9,04,31,99,56,68,5F,8A,77,30,3F,85,97,20,41,8B,BF,0A,30,61,44,0E,44,EF,AF,D8,4C,6C,CB,CE,4D,15,86,4E,03,02,46,57,71,F8,9A,DA,3C,28,10,41,85,D4,3E,87,46,A9,00,CB,7B,6E,61,F9,DD,40,27,B9,FB,48,6F,39,D4,CA,2B,35,AD,41,0A,AC,96,1B,31,1B,96,8C,1A,DC,A3,78,67,95,84,1E,73,BC,A1,5D,D8,BD,08,BA,2E,1E,06,3B,47,C5,B1,8B,7B,CB,77,55,C7,5E,B3,F8,FD,3B,C4,64,AA,BF,D8,69,C4,38,87,0C,79,71,0C,C5,35,CF,0F,E8,0F,93,B6,1E,E4,59,5F,C6,1A,8F,C8,44,89,8E,AD,5E,45,4A,96,19,C3,4E,A0,40,B1,3C,00,E5,A8,E7,A1,16,64,7B,87,14,35,08,F9,10,DA,3B,E7,20,AF,C4,9D,DA,5C,7F,FA,4B,B2,9C,22,E3,15,BE,83,4E,E4,14,51,34,FA,8D,A6,E6,B4,48,C7,54,67,F4,0A,68,07,0C,B4,13,CC,74,D4,76,35,B3,E7,9F,42,46,9C,AF,7A,36,97,4C,94,5C,64,F5,D5,7B,39,57,0E,E0,B3,78,0B,ED,8A,B5,A9,0A,9B,BC,FD,27,A5,2A,96,40,CC,CC,81,62,38,2D,61,5C,2B,0C,DC,1C,AE,11,4B,AC,87,1A,CE,9A,EF,83,6D,84,3D,90,B7,C0,24,C0,1F,6C,CE,2A,EC,44,1A,72,FF,E3,05,D8,49,5C,C7,0E,3D,25,E8,8A,5D,DA,89,6E,47,92,E2,C6,C3,3A,AD,74,68,E0,1E,8C,5E,57,6A,7D,8B,B9,E6,07,55,B9,46,01,10,71,24,A7,4A,C4,19,13,2E,D4,41,DE,59,C9,A4,A5,27,5E,0C,DE,83,27,32,2C,BC,92,06,39,5C,42,9D,B6,2A,5D,CC,D3,B6,C5,C6,21,46,BA,9D,AB,83,D5,A4,15,AE,C4,0F,53,B0,B0,A5,0F,8F,6A,58,4A,99,58,2C,E7,AF,4C,76,40,C4,2D,8A,C3,F8,6E,8D,EB,D0,AC,E7,A1,52,48,06,D0,9E,D5,04,B7,57,70,B0,2F,DC,FC,0D,B0,14,80,94,9F,D4,50,38,3C,9A,99,88,CB,69,F3,3D,5A,16,AF,92,19,27,37,14,4E,BA,9A,F3,D3,C4,2E,59,2E,CA,52,87,E1,20,F1,3B,CA,F5,67,6A,C7,D4,A4,9B,4B,BF,15,57,D0,96,76,A0,BB,A8,BD,13,41,0B,3D,58,3C,3F,DB,DE,CA,95,60,5F,D2,C2,13,45,E1,E2,21,B6,29,14,F6,7C,45,F8,65,CA,FB,A4,CA,5A,A6,27,60,9E,33,21,5F,54,5D,97,0D,5E,C0,87,10,27,EC,D5,2C,71,8C,BC,5D,A2,0A,F2,E0,C0,BF,11,74,0C,7D,43,2F,81,CD,3E,85,D3,B1,7D,DA,40,5B,C4,02,AB,3C,5E,A9,20,A1,60,B7,65,68,83,E4,02,B2,D8,66,7B,F7,1F,EE,2E,F4,C1,BE,9F,F9,57,1D,78,4B,5A,B1,DF,E3,2B,13,4A,0A,ED,9B,0B,B8,DD,5D,52,1F,37,BA,39,7A,60,7F,52,DB,02,DF,95,43,A5,36,3D,F2,B5,BA,DA,72,E7,24,3D,4A,34,4B,E9,A5,3C,5C,5B,35,4D,24,80,0A,45,0D,BC,6F,D5,EB,2E,67,6B,2D,3E,67,5D,0E,00,26,A4,51,1A,C4,93,C1,B8,BC,14,B3,DB,CB,25,45,37,EA,4B,D8,B8,E2,AF,4B,00,A2,95,F7,55,B7,00,C3,6F,D8,40,AA,9A,39,22,59,58,5E,5C,61,DC,5B,7F,D4,BA,18,94,88,AB,B9,A6,A7,62,09,57,48,6D,74,2B,87,0D,15,D6,11,EB,72,3B,D0,C8,5E,12,02,60,A4,E9,27,83,0A,C9,1D,E3,36,D4,E3,74,57,D6,91,FA,EE,79,4A,EC,0A,43,87,37,2D,8F,41,FD,94,E8,86,2C,E5,42,77,22,BA,45,08,25,A5,DA,8A,BE,BD,E3,BA,76,2E,76,BE,A6,33,93,2B,50,7F,A2,30,42,5D,93,41,87,1F,4B,CD,CA,06,C4,9F,27,86,FC,16,A8,6B,E2,EE,99,6D,2D,8B,0B,71,61,95,9B,FA,02,DA,91,1C,0D,40,9A,94,6E,75,FD,70,3C,F5,A4,A9,0E,53,53,ED,57,92,A8,21,BF,13,01,B0,3C,8F,BA,5A,E7,A2,B6,29,D5,5C,97,F2,15,FF,4F,11,09,4F,AB,CF,56,4D,C7,60,3F,E2,05,F1,6D,0E,90,0A,9F,4D,39,0D,BF,FA,7D,30,31,E5,51,0E,56,36,55,7B,97,E5,52,B9,03,B2,FC,4B,7E,08,B1,48,A6,AF,B7,E6,51,EE,26,79,55,70,86,93,EE,22,50,25,99,7A,EE,F7,3E,A2,C3,A8,CA,9F,FC,D6,87,67,60,A1,0C,7F,D3,5A,6A,38,EE,BC,11,61,46,07,DF,BE,F5,60,4C,CE,78,04,66,24,96,33,87,09,B3,A0,D3,25,BD,25,E3,AF,EA,AA,0C,C5,AF,EE,DE,0B,7E,45,27,06,66,50,C3,92,D4,A4,67,57,72,05,4B,E4,5E,61,52,89,55,39,19,B6,E9,54,2E,A2,C2,C9,3D,5A,D3,F5,F6,20,24,07,C4,A8,A2,58,F0,76,7F,35,53,16,17,ED,90,D9,C0,E8,B3,D2,28,A0,73,75,2E,33,1E,EC,31,55,3D,4F,3B,6C,DD,E2,EE,7A,BC,9B,E6,29,FD,00,5A,A8,C3,7C,9F,F5,57,63,28,92,75,C5,8E,E2,DA,E9,04,B5,04,68,22,7D,BE,F0,7B,78,60,6D,70,59,A2,17,F6,42,28,4C,0B,77,00,52,10,63,FB,C4,1A,6B,62,C8,AD,81,C9,E5,F5,79,0A,5E,73,4A,F7,66,66,43,FF,9C,D6,A0,35,F7,E7,E2,F8,6A,F0,65,1D,9E,95,FA,3F,1B,8B,24,FF,60,78,03,1D,E0,CC,58,27,25,BE,A8,AC,DD,E0,5F,AD,1B,12,65,CC,14,9C,C7,1D,81,E1,BD,A9,88,50,B3,5C,64,FE,26,15,AE,46,FE,55,89,C4,0B,FE,9C,A9,B8,A8,19,BF,7F,A3,F2,1D,F3,66,12,5E,15,E9,89,91,56,6A,12,60,8E,61,BB,46,A5,7D,47,71,B9,61,45,53,88,9B,D7,92,F8,D6,24,BB,B0,9B,A5,CE,6B,E9,3E,C5,16,E5,3F,42,45,A7,FC,37,83,63,7F,CF,CF,DB,88,1C,90,13,E6,CB,0D,4D,B5,91,71,B8,9F,AD,6E,68,45,CE,9E,5E,4B,35,9D,E8,D6,32,8F,1F,39,70,AC,47,78,C7,1B,E0,3B,7A,F7,2A,F7,AB,B2,3B,57,4B,14,A7,DF,A2,3B,B9,1E,53,42,B5,BA,83,4A,37,16,5D,C7,F9,E0,37,F1,E5,60,02,B2,AF,D2,82,10,82,1C,01,89,74,35,84,92,F3,E3,05,26,D6,B3,F1,86,44,07,04,B8,5B,FD,A5,C0,ED,CB,1E,47,9C,E5,70,A2,05,68,6E,54,C5,85,2C,A5,EF,14,A2,F9,5C,19,CA,F5,97,B6,C2,F1,81,0C,DC,9B,2A,2B,43,2F,44,A4,44,39,E6,F5,1B,B9,12,C0,01,07,59,A0,93,C5,04,C1,99,DD,CE,5C,2B,1F,72,4B,10,C1,16,8B,F6,A0,8C,A9,A6,22,6D,B0,22,98,05,DD,40,94,B0,71,44,1C,EE,F4,BA,C3,4C,73,3B,D7,C2,1F,9A,73,3B,58,60,20,47,06,18,07,95,E2,FB,9A,42,62,ED,33,B5,14,9E,40,86,C5,76,77,85,00,C5,6D,52,79,39,58,FC,FB,E2,5D,63,F6,F1,02,47,3C,FB,C0,96,DD,54,CD,82,F3,10,CF,E9,F0,F2,40,74,93,6F,7A,49,A8,2B,08,77,87,26,25,50,73,67,C5,02,F3,03,28,10,6F,22,EB,B3,72,F8,9A,97,66,9F,04,AB,CD,F9,99,D6,1E,C2,40,2A,7B,EB,F1,F7,B9,6A,AA,73,DF,97,A8,CF,13,7A,4F,F6,4D,25,81,59,EF,AD,D2,EA,EA,E2,EE,F6,E2,E7,F6,B3,08,30,49,87,C6,47,86,34,A8,67,95,AA,2D,FC,FB,4D,89,9F,32,85,CE,CA,27,DA,BB,1D,76,B2,67,82,84,AE,F8,3A,70,DF,59,BC,81,02,CC,D1,FD,84,20,84,42,EF,05,7C,84,99,AB,98,4C,8F,9A,32,FD,AC,4B,2D,DB,F3,88,8E,8E,83,56,BD,7E,14,5C,46,95,B3,C8,0F,88,70,DB,88,53,F5,36,5D,E6,C2,5A,63,B3,7A,06,9A,86,41,E1,EE,F5,E5,A8,CB,4A,C4,24,A0,95,CC,90,7E,7D,E3,0F,03,53,C3,3D,A5,47,1D,59,CA,0F,D2,33,13,4F,B0,1D,7F,66,D8,C5,48,B8,AE,BF,5C,B8,92,33,0C,35,9A,96,C5,04,BE,22,B3,7E,65,E5,12,F9,FA,C9,95,F2,B8,B8,11,3D,42,9B,B2,29,12,38,40,B8,0D,5A,B2,11,03,F0,96,D1,B9,2D,0A,38,FE,51,72,4D,53,AE,C9,30,C0,AA,23,8E,FB,75,CB,AF,A3,93,F2,E5,14,4B,8B,F0,4F,17,1E,9B,05,48,A5,F8,DF,AD,3D,C4,8D,8A,46,52,47,31,D8,F0,E6,5B,4B,2A,B6,C1,35,36,5F,BD,93,0C,9A,CD,B4,F7,E5,B5,8C,32,99,83,B8,EE,D0,FA,6A,AE,0F,AD,AB,75,79,84,ED,D2,C4,B7,3D,2E,14,E4,F2,31,02,8F,46,7E,BC,DD,80,01,AF,10,D4,6E,CD,D4,1E,40,CA,A8,F4,5E,82,41,CD,79,58,68,BD,48,91,05,E6,52,1B,18,DA,DA,E3,25,8E,65,5C,AA,89,50,F3,78,55,B8,F8,C6,18,0D,C2,BA,C9,B3,FD,B5,C9,D1,F3,DB,D6,D1,D3,DE,CB,A2,AB,75,3D,89,5E,6A,99,63,FD,BB,89,E7,ED,A1,E9,6F,CA,87,1A,2E,0D,9F,B5,11,76,32,D3,03,91,AC,EC,1A,A4,1E,2A,E5,CD,91,E0,A4,2D,C5,F8,6A,CC,A7,8D,59,1A,47,A9,7C,31,A4,D8,CC,0F,C0,02,75,11,9E,B0,27,58,E7,7F,00,27,64,B2,41,30,7E,7E,CE,DA,99,8A,33,99,5A,6D,E8,04,7B,7D,71,4B,50,3D,40,8B,EF,3F,8A,C1,20,88,6E,55,B5,EA,3C,D5,B2,14,B7,DC,18,46,24,56,41,99,BA,C2,70,2A,EC,1D,F8,FA,16,6E,33,D6,5B,4E,96,F4,DA,39,92,51,A6,21,09,96,C9,DB,88,1F,82,9A,52,3D,A7,FE,BB,0F,72,7B,46,1F,52,28,B2,0F,56,0E,42,63,1E,3E,A3,1E,21,FC,93,CE,46,A9,F1,B9,A7,52,4D,D7,52,68,EE,6A,67,2E,4F,24,64,0B,5A,8F,F2,58,8B,CC,75,43,AA,0A,0B,5E,8C,CE,29,EA,A0,B6,BA,C7,B8,D9,22,1A,C8,56,C2,31,A6,D4,F2,6C,39,18,07,74,04,4A,53,25,F1,FE,EA,5A,7D,CA,FE,09,B4,73,94,50,5E,BA,8C,20,A4,27,44,BA,48,36,F2,00,7D,B7,06,65,53,64,30,DD,CB,5D,1B,53,20,17,BF,13,F2,E0,B3,47,85,2F,41,E5,4E,FE,8B,7A,A0,D6,FC,DE,9B,94,E2,B0,50,CC,71,7B,DD,D0,1A,BB,C6,05,A1,63,16,D9,C4,CE,57,2A,7D,26,7B,AA,6A,D1,FA,54,C3,15,DB,F5,B9,6C,E7,85,AE,D7,13,94,77,80,25,62,A0,B2,2A,30,9A,1F,DE,F0,84,47,D6,9C,C0,67,8B,A1,FA,D1,57,D8,F5,9A,3D,ED,1B,96,43,C8,C3,3A,34,D1,2F,75,24,98,FA,58,87,08,39,14,34,45,FD,CC,7E,88,3C,EA,CF,69,82,7C,D4,CA,D0,16,71,A9,D5,98,55,34,2E,17,E7,80,64,0B,2B,6C,B3,12,8C,A3,98,3D,DE,7E,09,15,27,F2,67,3A,26,B5,5E,C3,7A,94,B1,C9,03,8B,E8,87,84,E6,18,8D,B3,98,76,97,7E,7E,BB,9D,BC,A8,D2,B0,79,C7,8F,82,E6,71,68,7E,1A,03,69,F0,71,9D,69,C5,77,B1,31,7F,D6,89,68,08,73,BC,53,39,77,A4,4F,38,FD,CB,3A,A4,FC,7A,2D,75,A0,FD,41,22,80,6C,59,89,7E,F4,F7,8A,7A,87,7B,84,60,B2,5D,9C,82,17,7A,CB,54,BA,7D,10,68,F3,1A,98,AC,40,3D,7A,3B,27,47,04,00,6E,C1,CC,54,06,66,58,01,C1,EC,C0,41,60,4B,FC,C2,04,54,F3,66,E3,3D,2C,11,68,C3,DC,57,0E,65,5F,DF,1A,AE,C5,00,20,B5,3A,38,DC,21,6E,D1,5F,C2,E0,7C,1B,2C,04,5A,6F,A8,26,98,4C,E1,3F,73,C6,03,B1,D9,4B,98,EF,DC,D2,4C,5D,69,64,AA,30,20,9C,AE,E8,EE,64,2A,8B,F6,2C,AE,56,09,B2,E8,4E,07,29,88,3A,02,07,8A,2F,5E,AF,F2,E5,39,E8,D6,43,E4,80,39,02,E4,31,00,84,56,DB,AD,3F,D9,26,C2,25,04,D4,ED,02,0C,07,F7,76,43,B7,FB,96,58,B1,34,49,3A,8F,3A,B6,9D,CC,EC,73,D2,B8,CA,D5,3C,BF,09,04,CE,08,1E,2A,F4,44,80,08,C8,88,A3,85,4B,4A,62,62,B6,9E,1C,2E,6F,19,07,3D,45,62,58,6D,2D,30,3B,3D,E5,5C,9C,FE,23,91,BB,AB,4C,3A,AE,6A,98,F2,CE,DE,24,FC,BF,60,44,A7,DC,06,9B,3C,DB,26,C0,B4,F8,FB,EE,3A,E2,B6,9C,3B,F1,A3,C7,F9,32,E7,00,5F,D0,9F,FF,C3,D7,6A,53,C0,59,DD,46,BD,F6,C1,9C,26,B8,ED,AD,E2,DF,AB,FF,D9,DC,EA,A1,E6,80,F1,43,AB,C6,A8,B7,E0,F2,52,04,97,BA,1E,95,8C,82,3E,93,DB,00,F8,45,64,85,52,22,3C,7F,A8,DF,E2,91,A5,9F,82,F6,39,8E,D3,36,0D,E8,A4,A8,02,D3,01,62,41,36,08,E4,2E,38,0F,D9,B2,8E,A3,F4,83,CC,E1,A5,AA,D4,BF,04,13,BD,19,69,30,85,6A,D7,3E,6E,4F,D1,A4,3D,3C,ED,05,6C,AA,B0,1B,95,F2,B0,BC,41,09,EF,86,B1,25,AC,49,CF,40,46,EF,3F,A1,D9,DC,11,08,3A,8F,C7,4B,90,93,8C,3C,04,E1,98,68,A0,B7,28,FB,7C,17,87,9E,A1,E2,28,C6,64,39,2A,E9,77,41,9C,26,CB,E9,C1,AF,62,09,26,34,1F,AC,07,F4,C6,61,80,97,47,19,44,45,C0,2B,1E,0B,D6,73,8D,28,3C,C4,56,3D,0F,1D,23,FF,2C,4A,BB,2A,52,5D,10,45,EC,AA,07,6F,47,D4,84,2D,EF,E6,31,BD,BD,8F,02,C3,51,61,31,8E,1D,92,94,24,A4,D4,0D,06,FA,93,0D,CC,E2,C2,3E,D5,63,55,2C,65,E7,C6,87,9D,1B,B0,D0,B9,C4,9B,FA,32,20,0E,29,9C,08,95,F8,04,77,85,59,07,E6,00,18,EE,2B,23,A1,C6,6C,D0,84,B1,5A,40,B4,B0,C2,B9,11,F1,C1,C9,D3,D8,22,A4,26,85,37,17,51,7B,BC,E7,14,C3,8F,0A,90,2A,AC,CD,8E,58,7C,0F,8F,89,92,8F,1A,42,73,3D,BA,DA,40,59,6E,A7,ED,85,13,44,33,59,47,65,D0,89,A5,D7,95,38,32,81,59,68,7E,9D,BA,D5,88,2C,1F,AB,90,21,CF,55,52,43,1E,58,D7,B6,91,89,BF,EA,69,A0,B0,C0,EA,C0,B5,1F,3C,2F,5D,96,F6,59,60,05,C1,ED,DA,96,4A,34,DA,07,C9,63,F3,0A,06,38,F3,F7,C0,86,2E,5B,A0,50,2E,AE,CA,B6,F7,78,BC,DF,E8,5B,2A,DD,8A,3E,32,56,78,72,FA,25,64,EB,B2,73,2E,6E,6E,12,A7,8E,40,E8,F2,1B,7D,8E,AB,A7,BA,EA,25,6A,65,7B,D4,A9,F9,A3,B2,A5,17,11,94,32,BD,D6,87,7C,8B,75,85,5C,9E,F8,89,E0,01,86,B9,C6,41,3D,3C,3F,3D,4C,FD,23,9C,C6,61,1C,DF,DA,C7,47,1D,2B,60,A2,8D,3C,46,9F,69,85,A9,5D,80,8F,4A,65,2C,3C,38,F8,61,93,6D,5B,E5,B3,EF,44,C0,51,08,8C,F3,DD,28,3C,85,B1,1B,BD,9F,47,FA,F5,06,A5,43,BF,6A,A4,6C,15,92,20,AA,86,19,AF,E8,30,C0,4C,6E,4B,EE,22,79,BE,65,EB,0A,16,A6,E2,94,5D,D8,E5,A1,84,96,24,65,D0,BF,C3,33,86,51,26,89,E2,67,E5,EC,D7,F1,E3,5B,69,39,54,00,EB,43,70,51,5F,E3,C5,01,33,D0,5B,EA,8B,9A,39,6F,70,5A,AB,1B,58,21,43,6C,AA,BE,D9,D4,58,7D,05,78,2B,4C,13,CA,57,AE,6B,FF,56,0A,27,52,00,FC,E6,D2,3B,72,0F,C0,B2,39,31,6D,84,D7,6F,3A,D0,1D,6C,5B,C7,8C,A3,05,26,4A,38,E6,94,8B,3E,50,97,F5,49,38,2C,26,33,CC,2B,B2,05,C9,3F,F0,43,32,B6,E6,E3,69,27,AC,59,E2,E9,34,F0,F0,56,F2,28,9F,3B,20,CE,50,0C,D1,19,B9,17,6B,26,96,A0,DE,FE,93,E5,DC,B0,45,F3,4F,93,23,EE,D8,23,F5,E3,E0,E7,3D,9A,E7,90,2E,54,53,06,64,FC,22,EF,E6,20,E3,D5,37,92,65,1C,02,5B,31,0B,25,3A,ED,16,65,C3,FF,81,C0,48,BE,0C,05,3D,77,30,53,C1,39,5B,C7,F3,D6,B9,F9,41,36,AA,DB,62,2D,C4,4F,79,F9,73,BA,EA,4D,56,75,ED,47,3E,52,39,8B,85,06,A8,D2,ED,BE,EC,C1,5D,00,C5,F8,29,E8,B6,EF,E0,8F,FE,83,21,1D,A1,5D,F5,AD,7B,EE,95,52,4E,EC,32,4F,5C,C0,46,4A,E8,37,06,CE,8F,1B,A3,22,80,F1,D5,5A,B4,C2,77,12,E6,8A,17,B8,38,DA,92,C4,99,1D,18,AB,F5,89,77,B1,33,D2,7F,45,8D,36,83,CA,7A,B0,41,BC,BC,6A,8A,11,A5,FC,D9,0E,68,84,5D,36,50,0F,9D,E4,90,53,44,6D,38,94,01,1C,C6,42,04,7F,E6,F1,F1,FD,7B,6B,36,AF,01,1C,52,33,45,74,52,19,F8,3A,BB,AD,6A,C0,74,E0,F8,6A,26,E7,1F,DE,50,38,CE,B2,A0,0F,E3,53,8B,4A,F4,D3,68,0E,3C,7C,5E,D6,07,CA,30,19,A8,46,14,A4,55,27,EA,99,E1,BB,81,2E,95,4F,71,74,EE,9C,1F,CA,4E,66,33,08,50,35,E6,BD,A5,31,9F,DA,E6,0D,44,A0,87,3B,DF,EC,26,11,F0,4F,09,31,89,4B,D3,79,26,4B,2D,9B,D0,0F,8A,DF,2B,01,2A,7B,D6,8F,36,2E,A5,51,36,AD,FB,F7,E7,9C,BC,B1,AC,F8,9F,0D,01,A0,E3,93,D2,57,78,FD,9F,F5,5D,44,D3,7B,2B,DB,60,5C,8C,01,86,94,B2,B6,F5,D3,0E,6E,9C,3F,4F,F5,59,C7,AD,A0,42,7B,D4,91,45,DF,F5,1D,6E,A2,7F,1B,A3,0A,EB,EC,07,AD,C0,D1,FC,AA,8D,79,74,D6,D4,12,7C,7D,7B,7A,94,86,6F,5C,9F,B7,16,7B,D6,3B,7E,83,5D,B2,7C,B4,F1,DD,DA,94,F9,41,61,EA,04,00,FC,74,E3,26,A5,E9,70,37,D4,A5,9F,67,A3,6F,4B,88,42,DD,ED,30,9B,66,10,C9,B2,08,5C,6F,35,E5,5E,77,A5,8B,04,17,D4,EE,99,45,91,AB,D8,7F,F5,6D,C9,C7,8A,D7,18,B8,31,DC,80,BA,50,6A,00,ED,1A,0A,45,81,94,F4,BE,4F,33,F9,2C,78,89,32,FC,10,09,34,E2,4B,C0,B3,74,39,07,11,5B,74,97,E8,5E,81,4E,08,4D,99,A8,E2,DE,C3,19,29,3E,6C,6F,3C,F9,54,65,B2,C5,4E,71,93,18,46,5F,3A,4B,52,C2,7D,7A,74,CC,C5,A7,85,FB,8A,67,44,3F,F5,5E,02,C8,5F,EC,EA,63,0E,D5,9B,E0,1C,44,1C,90,B2,08,15,FB,D2,5F,F1,C0,58,12,B0,82,15,4F,FB,DC,F7,EA,C9,F2,F2,FE,85,71,74,9A,B4,5E,F7,D9,BF,35,56,66,AB,F7,F7,A6,12,22,6E,E6,0A,5B,1C,90,81,E7,53,32,33,F8,A3,4F,A1,BA,23,43,0E,12,AE,83,D6,4A,73,CC,7E,F4,8D,27,A1,B2,35,7D,B7,D9,2A,9A,01,B8,E4,53,62,21,87,4A,CD,29,62,F6,32,DE,62,C5,FD,1E,42,AD,6E,D7,DC,06,EB,97,A6,D5,A9,13,08,73,12,F9,A2,FE,5A,41,22,82,AF,0F,D3,DF,70,9D,65,A4,3D,FA,CF,60,0A,20,A2,14,2A,67,49,DC,73,47,31,9E,C3,F8,69,27,79,2C,21,67,7D,74,D3,80,C7,C2,3B,26,53,95,55,09,87,2F,62,82,BA,3C,42,A7,FC,C4,8D,A6,48,4C,98,45,C8,29,E2,52,99,85,81,F1,02,69,0E,B5,DB,03,B9,3E,2B,9B,75,AD,81,CF,D2,11,C5,61,AB,C1,DD,B1,14,D7,4B,EA,56,19,9C,C8,F1,94,A3,99,E1,84,37,84,B2,9E,FD,AD,77,3E,D2,9A,FA,4F,F4,B2,00,01,2B,B8,99,F6,50,6D,F1,B3,9E,BC,D3,F1,F4,D9,5F,C5,95,57,7C,AA,05,AE,26,87,DC,2E,98,43,5C,F4,CB,99,14,7F,55,23,EA,7B,46,6D,BC,D3,E4,ED,13,41,0A,B5,04,1C,E6,BC,65,A2,49,67,2D,28,8E,AC,47,3B,35,DF,8D,55,D8,9E,DE,08,06,C7,5A,48,FB,4E,5D,AF,68,0E,41,4F,97,5C,50,17,DA,D2,27,A0,63,E9,D2,84,83,B6,23,45,92,2D,EB,D9,3C,A0,98,90,87,A4,7C,60,2D,25,87,9D,EA,B1,C8,2B,99,6D,A5,06,E5,31,03,D9,84,65,02,16,6B,E3,57,6A,73,0B,DF,46,69,98,DF,8A,76,A6,0A,A4,E9,C3,40,FB,C4,8F,72,B1,48,80,30,ED,44,47,5D,6A,8B,C7,45,F2,E6,F2,EA,85,80,0A,F1,FF,AC,1F,EF,C7,F3,91,9C,A2,83,A8,DD,09,FB,19,61,7A,67,DD,DD,27,94,18,CA,8C,75,28,E8,DE,84,1A,BF,6E,03,E2,99,84,9A,09,D2,A3,8D,58,1A,3F,9B,5A,A1,D2,92,4E,4B,B4,16,99,31,46,F3,31,5B,D9,8E,CF,32,77,6F,CE,4B,E3,C0,F7,51,AB,A6,9B,37,A3,F4,08,1D,E2,F2,6B,DB,FE,02,9B,4D,B6,D2,FB,55,2F,BB,DF,E5,A2,B0,91,DD,3F,AE,B2,66,C1,82,BB,CB,99,9D,7D,89,6C,30,67,A6,ED,4E,53,95,38,92,56,EE,3C,7F,5F,BB,3F,9B,F2,7B,FE,53,FF,B9,5F,79,45,2C,77,77,03,9E,07,42,8D,05,50,B9,61,C6,63,B6,6E,56,32,16,9A,1D,E5,38,29,1B,56,BA,E4,89,17,54,4F,A6,83,B3,EE,8C,0B,93,A9,82,BC,0E,66,D2,38,22,16,27,D1,36,C9,0F,FB,A1,6F,13,7C,79,89,3E,BF,EC,06,FE,FF,EC,3D,99,BE,CE,44,0F,7E,3B,06,5A,04,77,79,4D,2C,8A,1F,18,47,DD,C0,EE,E1,D0,BB,D0,1D,86,39,D7,8E,A0,02,DB,D6,33,06,EA,63,3A,74,3F,F4,B6,B5,F9,46,D8,A4,0D,F9,84,65,E9,66,D5,25,78,00,F0,1A,F4,49,86,D4,02,09,86,39,7F,2D,95,E1,7C,14,ED,01,13,C5,76,B8,6E,F7,AC,BF,1E,6A,2E,C7,71,8C,99,02,03,68,93,0C,56,AA,21,F4,9B,D6,68,A8,7E,B5,27,70,5E,3B,93,6F,B0,F2,B7,C0,40,76,A3,01,98,44,8C,4C,D6,A5,D1,8C,82,EF,20,3D,2C,0C,79,9F,C9,2F,3E,D8,31,73,5F,B6,47,86,93,2A,52,89,C7,B4,B2,D1,34,F4,9A,D4,BB,D2,EC,00,19,D6,8A,E5,FE,03,7D,0E,AE,F3,77,9C,D8,27,E4,C0,0A,1E,9B,51,B9,E4,2D,E2,AC,C1,6A,2B,06,9F,15,BC,37,12,15,2D,EE,95,58,B7,95,5A,B0,58,2D,B8,02,9D,3B,39,87,BE,F3,0A,1F,4B,D9,6D,C2,1B,6D,FD,9F,6A,FB,7F,F2,64,E5,69,C5,0B,71,71,0D,B1,F5,2F,43,F7,57,81,6E,E5,79,5B,82,13,87,CA,0F,CA,D1,92,C5,79,5C,BE,B6,5B,98,D4,5B,18,47,B6,4B,63,1F,40,38,94,18,3D,8D,B1,F0,0B,47,3B,D6,7F,71,7F,86,65,41,E0,2C,06,8D,5B,CC,39,C9,43,07,E9,51,31,AB,1F,22,92,DE,C3,73,66,00,D2,63,CF,76,D1,C2,BB,22,4E,4B,70,0F,90,AC,B4,55,87,2E,AB,5F,2F,AC,9A,1B,83,03,E1,9B,CD,6D,7E,65,9D,01,0B,AE,DD,52,B1,0D,44,EA,AD,C5,BA,7C,12,13,E7,A3,58,39,1C,5F,72,43,CB,BB,FF,3C,DF,11,B0,6D,78,81,7D,B2,7C,62,06,56,C1,BD,E4,45,02,19,4E,94,15,73,91,35,53,D9,34,88,4B,E7,1E,0F,E9,6B,65,19,78,5D,EF,3B,F4,AF,63,CD,43,B7,58,00,ED,A8,E6,04,CA,DF,69,9D,35,6E,11,EC,4E,72,AC,E1,28,80,94,7A,E1,27,ED,74,03,AD,F3,E5,14,59,0E,6C,70,22,D4,C0,66,EF,0A,59,63,E0,1E,D7,A2,5D,F7,EE,53,9B,C4,EB,3C,AB,8B,A7,1F,1C,D4,88,3B,27,FA,B7,6F,7B,C2,3D,7F,FB,8A,2F,FB,4B,33,08,47,78,54,51,07,20,BF,94,18,49,DF,FA,2B,F0,29,C5,4C,33,DB,78,EA,C5,A1,01,F6,EF,98,CF,B6,A5,4A,7D,1B,2F,5C,1D,0C,CF,55,87,2C,24,C6,02,0C,35,07,7D,97,72,2F,FB,5E,22,54,75,35,6E,FF,49,FA,E5,F4,A8,1E,07,4B,96,D7,A8,76,02,67,9F,F1,62,ED,F9,3C,43,EA,96,BE,77,DD,0B,62,1C,A0,C5,F1,28,2B,BA,91,AB,18,C1,85,AE,B8,3D,FE,78,C4,F1,E3,DE,F5,BB,DE,29,DA,E0,7A,AA,C7,83,C5,B5,A6,44,05,66,F2,43,5E,41,F5,2B,B9,A5,27,8A,4F,C5,48,70,90,6C,66,DE,02,9E,20,CC,41,B0,E9,5A,F6,36,48,E3,24,E6,70,59,6B,87,93,50,82,62,4B,F8,76,BF,61,D4,DF,39,6C,16,BC,24,48,95,C8,A7,1B,0B,9E,FE,63,05,1A,83,DA,01,B1,68,A4,7C,0A,38,A1,52,2A,A6,94,94,CC,BA,73,42,5D,DF,A9,9F,3E,25,19,2B,A6,62,93,58,DB,E1,87,AC,E4,98,2A,74,B1,FF,10,EF,9B,C1,58,C2,D7,EC,A8,64,CA,53,F8,2D,B6,D9,74,16,34,62,3F,91,5F,71,1C,53,01,5C,24,E3,7F,0F,15,0E,7D,C7,71,B0,99,1A,83,36,BF,31,D1,9B,2C,68,1E,40,E7,E3,F3,8F,B2,AD,04,CE,FB,B5,F2,81,43,36,A3,F9,92,2D,7C,4B,8B,B7,64,BF,58,8C,B1,DE,CB,D7,61,E3,0C,D7,96,E8,47,BC,06,2D,DF,87,E4,54,6A,7C,F9,1D,E2,CC,8D,8B,89,C6,6B,64,43,CD,1B,C1,B8,38,DB,F7,7F,7E,F9,2B,4C,CB,E8,44,0B,84,E4,A9,61,42,F0,81,6A,35,BC,06,04,CE,EC,CC,59,29,51,99,7C,E8,26,A2,58,D4,9C,00,B4,42,A4,2C,30,59,C6,54,2B,9D,7D,94,78,B1,E1,CC,17,BD,F9,5F,D8,3B,8A,A9,B2,8E,18,68,C4,93,67,EF,F0,DF,D2,65,28,11,9B,57,99,65,A4,FB,26,68,15,90,A8,2E,06,2B,56,3F,73,4A,F8,DB,19,C2,CF,11,AB,E3,76,C0,26,74,CC,21,BD,C0,98,13,7D,C9,03,40,A0,74,DD,06,9D,15,DD,4B,38,19,64,A8,83,C7,4C,16,5A,84,2A,BD,1B,42,08,BB,A8,B4,97,0B,FD,EA,73,B2,41,D1,E6,97,9E,5D,6D,15,D8,44,34,B3,53,8E,B3,2C,D2,68,2B,5E,F2,9B,E6,C1,0D,9E,EF,26,BC,9A,04,D8,97,AF,33,49,FD,EC,42,03,E2,38,F9,D4,5A,E4,58,A5,A4,F1,D8,83,2C,AF,D8,A1,66,FA,01,FE,B7,B7,30,3D,F6,27,5F,0C,63,3C,64,D4,25,06,2E,26,35,26,3D,56,75,60,CC,FC,82,C2,77,D2,5F,2E,6E,EF,3E,E9,A6,E9,C0,9D,B6,66,20,9E,89,D9,A3,E8,CB,31,14,D6,FD,65,02,83,99,C4,E2,35,14,95,5C,2B,BF,C7,FD,11,A5,C1,AF,E6,71,4A,54,6B,66,18,01,F8,7F,E8,AE,69,F3,19,4D,36,BE,BC,16,C1,D6,C9,2E,39,B6,E4,0F,F9,1C,AE,2B,C6,C5,C7,53,9D,56,C6,99,57,AB,77,38,7C,13,D1,CB,E8,85,57,AE,C4,58,0D,5D,C2,C2,42,F4,1B,BC,F0,67,96,24,F3,29,2A,45,C1,C6,BF,B5,A9,07,2E,67,99,AD,79,BA,50,B5,72,C3,67,8B,F4,68,0F,6E,57,82,ED,11,ED,24,5B,70,25,02,10,25,95,7E,96,D1,17,98,2E,26,63,E4,2B,BE,23,A4,1F,09,ED,5E,7C,F2,13,62,F3,B3,A9,E2,01,B2,D9,78,5A,28,0E,2C,E7,3E,16,2C,BD,52,E2,3E,27,15,4C,EA,65,77,C0,F0,82,58,5F,5C,5A,C3,56,5F,94,D0,16,20,17,69,E6,DB,44,91,BB,02,53,8A,06,90,2E,C8,1F,1B,2E,E2,DA,04,BC,39,95,A8,A5,0A,BA,89,20,65,92,E1,48,4C,10,15,41,CC,C8,E4,F3,07,CA,97,FC,40,90,3E,97,7E,59,60,60,2E,07,F3,0C,3B,82,E3,0C,BC,A1,5A,8D,8C,6A,2F,93,A9,84,4C,70,FE,33,A0,0F,B7,2D,7E,83,C7,F5,69,47,FE,68,F2,3D,B4,D2,83,AC,21,09,C0,D4,5D,E5,30,51,A9,17,C7,B9,AE,41,9E,E3,E3,DD,7A,50,85,EC,5A,82,D3,63,D0,C9,47,66,A4,7E,43,12,BD,6E,11,88,53,49,8A,CE,C6,29,62,7A,B8,A7,B0,F2,D6,34,4E,94,D3,5C,45,96,F9,68,99,08,2D,7C,A9,7C,AA,D1,1B,47,CB,FA,ED,D9,F8,A2,27,1D,95,87,02,81,64,AD,5F,79,5F,FF,F2,C4,E7,68,AF,B4,27,5E,53,FE,7F,76,F9,EA,66,5D,AC,6B,51,66,67,B0,F9,14,26,F4,E4,1F,7D,62,89,CD,F7,68,F4,9F,6B,B9,9B,AD,FC,34,57,0F,E4,81,FC,C9,CA,CB,54,6E,C8,7E,B3,28,53,25,01,E5,00,DB,FF,B3,B4,02,3C,A0,5F,8F,8D,E8,56,2F,D6,E7,4A,2D,8D,B2,A0,C6,73,76,43,7B,A3,05,06,49,FD,0D,52,68,86,65,96,D6,EC,20,BC,4F,32,6B,9A,AE,35,80,E5,09,B0,B5,F5,7B,BF,59,DD,91,6D,E6,CB,44,CC,10,E1,C0,BF,6E,E6,AC,3A,68,CA,02,8A,26,34,A9,54,FB,CA,14,05,33,E8,88,08,B7,0B,8B,77,23,FA,89,63,1F,B7,54,63,D1,AD,DF,E3,D6,AA,D2,DB,C5,5C,A6,2C,B0,0F,E0,2E,57,B7,20,72,45,2B,44,A1,A4,20,30,C1,87,27,BF,0A,69,04,81,6D,E2,7B,81,BF,49,57,00,BD,CE,EE,9F,36,87,3B,2E,4C,A5,48,19,6E,C7,EE,7E,25,D5,45,C5,5F,33,A6,04,B4,8F,3F,C4,50,4B,C6,F8,8C,5A,83,AC,A3,40,A0,B0,8F,EB,FE,F8,9D,D8,1A,6D,01,3D,C9,E9,9C,5F,F2,B2,21,84,4C,DD,EA,DE,72,E5,8E,FF,F7,F0,E6,68,43,0F,F9,0F,D9,9A,BB,D8,A0,32,D1,82,BC,6A,DC,EB,A4,CD,E7,C3,0B,B6,92,E0,FC,D3,58,19,5C,04,1E,35,93,03,4C,79,53,52,D4,24,9F,4F,BD,DE,4B,70,4E,72,63,68,FA,52,3F,E0,0D,D2,EB,BB,FA,BB,DD,1E,74,74,75,FE,B8,AA,34,2A,4E,18,34,BA,08,D1,23,20,6D,8B,97,FA,D2,F4,82,AF,06,0D,63,EE,1B,05,19,0A,45,84,9C,9A,8C,9F,44,70,A6,1E,BB,61,01,D0,99,95,83,8A,05,71,F5,AF,16,28,B7,B5,00,35,3B,AA,97,72,46,B8,16,C2,E7,5B,DC,21,50,E4,01,EA,12,17,58,3C,DD,A0,67,21,37,9F,55,24,7F,F0,7B,28,4E,6E,FF,3F,BC,94,3F,6E,90,C2,05,B7,12,30,B3,69,73,71,D8,E6,CE,C6,95,4F,1D,91,0C,97,1A,F5,FE,A2,31,37,86,73,38,B4,46,19,25,79,1A,8B,09,C7,90,AB,AE,B3,E8,E5,4F,E7,07,5A,8D,42,3B,1A,B4,95,BB,E9,6B,CA,39,DA,5F,8B,52,4F,54,69,95,B7,FA,ED,29,4C,B6,AB,0B,2A,14,BE,C0,1B,F8,52,CB,EA,3D,89,0B,81,94,97,17,DB,84,12,B2,B0,A9,02,7F,D9,6B,E7,2F,B5,0C,AA,04,98,8A,67,61,91,94,3F,4F,29,E6,AA,3D,D7,44,EE,C4,71,BA,47,88,9F,57,F4,83,C3,43,54,C7,E0,FD,65,48,2F,4E,10,71,F1,09,86,94,B6,92,B4,CF,36,58,BD,C9,F8,26,F1,1D,10,8E,FB,7C,A1,E3,93,9B,EE,69,4A,85,37,D2,2F,9B,9D,F2,5C,91,26,BA,17,C4,67,48,14,7D,C4,FD,85,BF,78,76,31,B5,E0,E6,EF,FF,40,74,DD,32,CF,3B,D2,91,D3,F4,63,46,B1,BE,52,C0,58,F6,83,03,B3,B3,20,B9,A3,C4,1E,A4,D2,62,50,64,93,6D,14,9F,1C,7C,FB,13,E0,63,96,67,FE,5E,96,DF,E3,05,31,2B,E6,87,03,78,24,7A,18,D5,10,AF,33,85,5D,D6,9B,3F,25,B3,6F,AF,34,A5,15,0C,DE,2E,1A,96,31,CD,33,64,65,66,67,24,52,6E,7D,09,F6,F1,B9,1B,ED,95,5B,5A,52,52,97,EF,FD,50,0A,3B,2A,47,86,FB,08,ED,CF,56,6E,E6,F2,53,03,B2,C1,20,CC,E2,82,96,65,13,14,6E,D7,AC,EC,BB,39,6D,93,54,9A,03,49,EC,05,27,BB,F7,AE,50,9B,2B,55,FE,57,BF,66,BB,50,4A,8C,34,E4,15,5F,59,C2,C4,41,05,78,0B,21,4C,54,BF,FC,F5,12,2E,D8,52,D2,35,31,D6,52,52,33,59,9E,3C,DD,F2,87,69,4B,C5,2D,BE,C1,0E,5F,01,10,74,91,66,13,BF,89,53,61,6C,0E,D8,A1,D5,5B,BE,C9,E8,4B,75,FA,1F,73,8E,CF,F4,AF,BC,9F,A9,E9,64,44,93,6E,9A,EA,19,0D,8E,07,16,63,FD,BD,66,85,F6,20,7B,D1,DA,D0,F0,54,E8,72,C0,B8,92,92,52,26,2E,C1,F6,82,25,49,15,12,35,DB,0A,CC,03,55,D7,7B,9E,0C,52,FB,79,64,B0,C8,79,ED,00,3B,AD,E8,00,6E,7E,A7,17,DD,E8,BF,EB,FB,29,B3,50,BA,9E,75,E5,78,B5,18,DC,03,59,FF,46,3F,0B,4B,DE,79,01,CA,C9,66,F5,F0,3B,A8,3A,49,92,A8,F8,65,CA,06,88,46,CC,45,DF,6C,93,A6,12,CF,90,71,8E,03,C0,C1,92,A2,C3,04,A1,EB,05,69,59,B3,1E,2B,DA,33,4A,8C,C5,6C,F5,F2,3D,5A,58,C1,94,50,23,8B,7B,27,EE,27,2A,88,D4,A1,0B,B5,EA,D4,1C,8D,12,AF,47,E8,7C,08,79,7C,48,B7,E2,F9,3A,8F,6D,C0,64,A2,03,54,56,A4,29,DF,24,86,A4,27,5F,99,5E,6F,31,00,3F,D9,3E,94,5D,90,BA,73,74,19,F3,BB,D8,6F,DE,4A,92,AA,1A,65,AA,81,7E,AB,1B,00,35,B3,1C,A1,59,4B,9B,6F,FE,3F,6C,7F,F5,5F,4E,F1,57,C5,81,94,1B,3E,52,B6,6C,03,0D,9F,00,36,F2,29,9E,A3,9B,C3,34,84,7D,0E,F4,30,90,87,47,47,FF,1F,15,5A,43,4C,85,1A,75,C8,E0,F0,AF,10,B6,1A,24,B0,DC,CD,C6,31,B9,CC,C1,6E,8E,21,19,A7,43,1F,D4,38,08,06,06,24,F3,7F,59,E4,83,D0,36,98,C5,8C,DF,7E,16,1A,8B,F3,BD,23,69,F2,B4,99,EB,C6,FC,64,7E,40,E7,2F,DC,D0,85,6D,A7,05,58,00,88,B4,70,20,92,24,48,5D,C5,89,EB,53,27,A2,7E,1B,A9,79,79,82,4C,95,E3,64,AC,71,F7,61,0C,84,5F,12,85,B4,FA,75,A8,A2,10,4B,4C,CF,EE,53,4C,D3,5A,6A,5C,2F,16,2C,EF,B7,84,50,10,61,C5,17,DA,9E,42,1A,87,30,19,93,6B,DF,4E,66,CD,1C,6A,FA,98,28,86,6F,0F,F8,C4,E4,0E,18,2A,8C,1E,81,E1,2B,67,5B,45,AD,75,64,F2,91,B7,41,65,4B,F0,83,34,57,94,18,C5,8C,3B,15,DB,45,2A,8E,49,0E,D5,30,83,1A,DE,17,7D,4D,93,53,E9,22,B8,88,EF,8B,09,B2,37,8D,86,1E,B3,6F,1C,1F,25,E2,D2,70,E2,16,10,90,75,A7,BF,91,DC,8E,99,B4,9A,97,FC,21,1F,EB,C2,D4,56,65,C6,87,6A,BE,F3,CA,9A,C0,FE,C7,35,54,FA,0F,68,06,01,A2,6C,20,F9,52,51,F6,8C,BC,FC,D1,BC,D2,08,75,5A,A0,04,15,7F,BA,57,D9,6E,E6,4E,25,99,2C,11,93,32,F9,03,59,4C,77,79,B4,27,0B,DA,2B,CA,2B,DD,C2,4F,7C,01,20,FE,8C,6D,9F,99,18,92,F2,39,07,78,01,D7,E0,7E,77,60,B0,5A,87,DB,C8,D9,BB,19,F2,43,E5,B4,2D,B6,83,1A,76,5C,49,84,68,11,FD,53,DA,83,CC,33,8E,C6,81,33,F0,DE,58,EC,3C,F0,4B,EF,AA,B2,67,B3,A8,8A,41,00,C7,B2,3E,95,CC,0B,89,68,40,04,0D,B7,D0,2F,3A,7E,8E,65,EA,F6,AB,5D,FA,FF,96,6B,49,B5,B8,1B,5A,4D,BF,36,F0,DC,86,17,C0,30,E0,D3,95,7C,24,82,D3,A0,C2,9F,30,D9,19,45,6E,BD,46,3E,E4,84,9C,84,10,7B,AF,3B,D8,D0,9B,C8,C4,B6,C6,FA,30,F0,1D,38,CE,4B,56,C1,5D,87,D9,3F,64,4B,DE,EA,5A,4E,B9,68,35,42,6C,C0,A7,8E,16,E2,BC,FE,5D,48,50,D2,9C,8D,D0,09,0B,E2,37,53,D1,8F,D7,68,A4,02,A0,7D,85,24,93,FC,55,90,2E,2D,7A,3E,C2,FC,FB,E2,F3,0E,00,D6,2E,10,AD,19,21,D6,7C,80,21,F4,DE,1C,BC,A9,1D,3E,32,D0,D3,2D,AC,8E,CB,09,44,88,3C,3B,EF,86,1E,18,CB,7C,69,6F,CC,10,85,9C,AA,56,6D,B8,E6,62,50,7B,25,B8,27,94,A0,26,1B,42,16,77,20,58,E6,AC,1D,D4,F0,7C,90,EC,70,EB,0B,DA,FC,65,CE,75,AC,13,E1,5F,39,F3,19,F4,58,8A,8A,06,E2,43,35,17,CB,61,D3,A7,6B,78,B3,0C,4C,8C,B1,C2,F8,8A,69,19,6D,09,9E,00,C6,13,4C,61,D1,73,30,77,84,FA,96,AD,15,4F,63,07,65,7C,E2,FE,68,3C,4F,1C,EB,6E,E9,9B,8A,7C,A9,7A,39,DC,5F,8E,AF,0C,8F,81,C6,97,69,7C,94,11,99,57,86,41,49,98,1B,33,0D,5D,57,83,97,4D,AF,27,5C,A2,48,87,BA,7A,2A,C2,CC,2D,77,F3,33,50,D0,36,5B,38,10,00,ED,4E,F6,55,73,C8,36,F1,92,BC,04,1F,F3,78,B8,A2,63,53,0B,23,32,5E,BB,5E,77,EF,63,C2,BE,DD,E5,D9,BF,61,4F,DB,E8,4B,2A,9F,4E,74,A4,CB,24,C5,20,34,CA,D2,1A,FD,5A,EC,33,35,85,1F,09,00,04,10,95,F9,21,4B,61,44,BD,BA,71,71,B4,61,98,4A,A7,CC,88,2C,03,1A,DE,8E,89,F0,EB,24,C5,2A,C8,AF,7A,E7,F6,9D,BC,C3,92,E3,1E,08,C1,05,C8,ED,E3,C0,D1,73,66,3D,D2,31,1B,5E,E7,79,93,E3,A4,1A,83,23,01,AA,BB,B4,54,E8,7F,B3,AC,F8,A4,6A,54,32,00,76,4A,33,03,A5,E5,6D,5B,92,64,34,62,4E,2C,BE,36,34,43,19,D6,34,46,90,0E,B6,03,9E,82,36,4B,13,14,94,A4,1F,0B,CD,39,4E,36,67,CB,F5,E9,E3,00,7D,88,FF,54,06,82,9F,38,68,36,4F,38,08,9F,48,90,77,89,C4,3A,BA,31,DE,37,B8,48,8E,FC,B6,A7,87,6C,86,12,D8,DA,D6,65,C7,1A,C9,CE,65,21,18,E7,F8,A1,40,45,8E,27,FF,FE,C7,A4,A7,73,D7,0B,4F,C9,52,AB,DA,AD,CB,B9,A0,13,6F,B8,7D,57,86,E9,D5,51,01,25,36,1C,49,40,D7,82,8C,9A,0C,A3,52,1F,2B,B5,21,EF,DB,D3,00,D7,70,C8,A1,74,4D,97,92,C8,F9,CC,3A,82,1C,E3,74,2C,E8,0C,B9,F1,89,9E,D4,7E,A0,CE,6A,BC,D5,7E,80,E2,B6,0D,11,91,12,DA,5A,EF,C1,26,F9,11,82,80,A2,09,3B,3F,FD,A5,5A,82,ED,49,5A,94,5C,84,E2,2B,91,6B,23,7D,86,1B,CC,07,CA,76,EA,D0,42,A8,4E,CB,C7,DB,66,3B,D0,AF,22,AE,63,9E,56,D2,FF,53,99,B0,32,14,CA,99,54,57,89,F9,8D,4B,69,CC,95,FE,C6,52,58,B0,9D,FD,44,72,8F,4E,24,C1,43,3E,CE,3F,10,8B,A0,AB,32,B0,D2,8A,DB,9B,38,A8,6B,72,DC,DA,75,9C,F5,25,1D,CD,62,62,C6,40,12,4B,AD,A7,A7,4A,D0,9A,0C,6B,6E,7B,E5,CC,F3,18,C0,34,42,C1,57,7C,9B,A7,79,D1,61,88,E7,C9,6F,D7,2D,0F,F0,C4,FF,0D,BC,5D,31,35,43,64,56,76,90,98,44,52,98,C0,01,23,59,C6,41,60,3A,2F,B1,6B,0E,B6,1C,38,D8,69,FD,04,95,D0,6E,E5,48,69,17,76,BB,C1,14,E6,62,5E,08,7F,A6,73,33,08,05,43,26,BE,3B,AA,3B,82,DF,53,F4,8E,11,21,FD,18,C0,54,1E,64,65,63,4A,9C,01,83,CC,10,56,BC,A3,43,B7,02,D6,33,20,D4,3D,79,63,B1,43,BB,AF,76,C2,9C,D4,71,20,C4,4D,07,5F,A2,D3,7E,FF,CC,E9,90,EB,EF,12,9F,C3,13,95,10,BD,23,F3,C6,28,DD,FE,08,8D,96,EC,68,9B,A1,C4,3A,AA,56,57,ED,C9,4C,D0,24,7F,32,79,5C,BC,F8,23,89,A1,22,C1,16,0B,B9,1A,8D,B4,3F,67,8A,D6,CC,B3,F6,94,DC,BC,74,FD,EC,C3,EB,B7,D8,E3,B5,55,D1,44,CA,5B,9A,31,E3,E4,07,3B,40,21,00,5D,B7,65,4F,5B,13,6B,A2,A3,57,B6,7D,6A,2F,80,65,DD,A6,28,C8,52,B8,AD,8C,1C,56,7F,C2,C9,95,A6,44,3B,5C,06,F1,B4,45,2F,1E,30,5F,14,A2,3B,9E,AD,73,6C,A7,86,F0,BE,13,42,49,82,D7,AE,8F,C3,8A,AD,B0,39,C4,CF,52,C6,8B,3D,1E,59,17,76,F3,ED,63,96,A0,2B,59,7E,73,F5,4C,84,7B,86,4B,37,77,07,E9,CF,C0,4B,B3,98,FF,17,D3,4B,7F,BA,22,4F,F3,B0,8A,09,4C,1B,99,E0,D1,51,0B,3B,E3,E1,E7,40,54,58,3B,56,07,C0,80,A4,61,2B,C5,89,F7,1A,A0,54,78,CD,DF,16,84,93,93,7D,F6,84,FB,B8,A4,54,10,82,BA,93,88,0E,2B,EA,DA,43,23,E8,1C,BF,D6,90,D3,34,19,70,C8,8B,93,F1,D5,25,B4,F9,9B,DC,FC,2C,90,94,65,C3,92,F3,0A,83,5F,58,01,36,66,23,20,F9,50,BF,EC,9C,C3,22,50,5E,15,87,ED,25,2F,E8,7F,E4,A0,FE,25,08,41,BD,5C,F9,DE,EB,7A,F3,24,08,06,D6,38,75,F7,04,05,13,FF,F1,A0,3E,D9,34,29,FB,43,38,8D,96,2E,AB,4C,8F,C1,A8,AE,64,BE,86,A7,3C,28,4E,65,01,42,13,B5,63,3D,07,8B,29,24,48,76,AB,70,2D,69,E7,19,18,4D,1C,9A,23,A2,E1,16,FF,56,81,4C,E5,E6,12,0F,8A,93,48,1D,3E,77,AD,CE,96,6F,EB,46,C3,35,BD,47,21,17,AB,09,E0,9B,B5,6F,25,07,BA,4A,31,75,0E,52,F0,C7,4F,30,D3,9E,61,52,0A,12,4A,DF,9D,08,E7,37,57,A7,A5,89,84,4C,ED,91,FA,6B,45,88,52,7E,B9,DD,E9,A6,C6,B0,42,2D,20,C4,96,23,4B,12,43,41,82,14,4D,42,6C,91,F2,5C,40,19,6A,D8,4C,3C,D9,1C,FD,59,45,6C,D9,80,C6,1E,66,A0,6E,A5,59,0C,CE,6E,3D,5E,A1,6A,B2,37,C6,16,B3,B7,67,D0,66,85,D4,D8,25,E0,BD,A4,49,99,3F,E4,0B,28,BD,85,2A,12,B3,CA,22,97,A8,99,F0,37,47,39,26,15,68,77,33,BE,1F,54,25,29,37,63,97,AF,DE,AB,D8,1C,82,BC,0C,E0,AB,2F,B6,6B,1B,E3,88,8D,DA,5D,99,5B,01,DC,72,3D,B1,4D,6A,68,0D,A3,70,DD,4A,75,64,A3,D3,88,8C,4F,73,12,0B,16,0D,77,EE,17,8C,67,91,C1,EC,4B,B7,BB,09,87,48,77,1D,90,BB,AF,C5,91,4F,6C,AF,F4,4B,8C,43,FD,48,8E,76,7F,51,5B,DF,6A,43,1B,4F,E7,7B,05,79,71,9C,3D,DD,5D,6F,B7,C9,6E,7B,20,68,53,C9,06,83,86,43,07,64,0C,6E,AF,50,31,D5,42,25,D2,C8,E1,74,FC,FE,3F,C3,75,CF,10,07,59,1A,7E,CD,E0,43,C5,57,DD,AF,EB,E3,7D,25,BF,39,F3,7A,D7,DC,77,66,5D,8D,42,4C,AA,B3,7E,3E,F1,D5,BB,A1,62,D6,17,CE,E6,9A,BC,5C,E5,2D,0E,B4,2D,7D,36,05,45,80,D3,95,35,17,EC,6E,BE,8A,F5,5A,64,F1,27,B4,D9,77,3F,40,C3,2E,5E,4D,49,A3,86,5D,6A,C6,20,B0,4A,9E,62,63,B3,53,1E,A2,7E,0C,67,19,1C,B1,1A,3B,92,AC,EB,03,1E,7D,1D,C1,ED,22,DA,22,6A,A7,C0,04,98,90,02,15,59,F1,F3,99,D4,8A,9A,D9,DC,22,39,4D,4A,15,E6,E2,FC,D0,07,18,F3,0A,C6,4F,8E,10,ED,CB,55,0D,93,62,D8,7E,A3,EC,26,2A,D0,E6,EF,D4,2B,72,85,34,C5,21,10,81,E3,8E,B4,59,C7,D9,F0,75,0E,13,CF,07,5D,2F,74,2B,EE,58,A4,54,CF,2B,54,DF,AF,C8,5B,F2,F0,B3,E1,9F,62,FF,68,11,3B,56,9A,CA,B1,9D,07,9C,F7,81,E3,13,DF,87,62,A7,7D,9A,80,D9,41,72,13,03,5F,E7,7E,63,AD,8B,54,9C,B2,A3,73,90,70,3B,AF,51,85,A3,50,92,88,C1,5F,62,FC,A6,BF,E7,A3,56,69,C0,B6,9A,8C,48,B0,BB,A2,40,35,75,13,7B,36,57,31,DC,8F,A7,9C,F2,C9,D3,62,85,CE,14,64,B4,C4,DC,EC,C8,63,5D,3F,5A,87,21,6C,02,A7,C2,E0,07,D3,FE,80,E4,69,08,00,25,FC,A4,75,8A,82,B6,96,64,49,7F,51,D3,CC,27,EA,50,7F,03,1C,9D,C6,66,ED,6A,D9,D8,B3,3E,1E,77,E3,A8,39,C1,49,34,69,6B,59,23,28,BC,A8,C9,E8,CF,FC,DC,90,B2,BB,5B,A4,F4,01,9D,EE,D1,A5,C5,F8,EB,4B,CC,C9,47,56,74,E3,A6,2F,58,C2,07,A3,3C,81,7C,80,25,A3,B6,74,5C,76,18,DE,F7,38,77,98,82,3B,A3,07,97,FE,5C,1B,FB,3E,9C,FE,1C,93,F0,67,61,58,68,8A,51,42,3B,C0,24,AD,52,E0,58,41,D4,BB,AD,DE,1F,23,E2,C5,27,56,9E,B4,91,E4,1D,72,DC,8E,C0,FF,53,8F,81,74,BB,7B,84,27,7F,D9,64,ED,65,9A,74,DE,10,83,44,04,A6,E0,59,A3,37,29,E1,CD,3B,F0,FD,33,68,4F,0E,BF,48,16,14,62,25,BC,7C,8E,19,54,31,A3,47,4E,10,2E,04,88,DC,6A,4B,59,DA,E9,1A,86,5F,38,80,8F,E3,48,02,0C,B0,A5,B8,36,4A,8D,D8,68,EE,BD,34,FC,C4,46,2B,0F,22,1D,1C,3D,49,FF,3E,0E,B0,2F,FB,30,6C,10,D7,2E,74,F7,B3,DC,51,23,83,69,E7,87,60,7B,F1,CA,B7,62,47,D0,6A,9F,F1,BA,7D,A5,8C,E2,CB,BB,9C,CC,99,10,21,4F,5C,C3,58,84,81,4C,12,F3,B2,76,8A,73,84,88,2B,2F,B8,A2,AF,5D,59,B7,38,AA,88,B0,8D,C5,D8,91,1A,A8,B0,DC,98,0D,22,34,AB,37,20,34,4C,64,1A,15,2B,E9,9B,F3,5B,C1,FC,32,C5,52,C2,BE,62,4E,96,EA,01,7B,B6,A5,36,CA,F2,43,BA,18,36,13,C2,7C,94,FB,CB,1D,06,D5,E5,96,9F,36,04,4F,F4,04,AA,EA,EA,ED,C2,EF,FC,24,01,30,81,D6,28,9F,D2,DD,D1,51,8E,45,8C,DC,D8,E3,4B,A1,2C,FE,8F,4A,AE,B0,A2,17,26,7F,F9,E9,3F,4B,99,CC,18,28,AA,40,5A,5A,09,2C,DC,C0,2F,D5,30,48,DC,9F,3B,17,19,2E,02,6B,23,34,D6,A3,EE,0D,BD,0F,D8,A3,42,69,0E,E8,28,F2,16,0A,4A,29,64,F9,16,78,08,1B,96,CE,12,3C,70,50,86,7F,96,F7,46,EB,32,E3,7B,00,4D,5F,1E,09,C3,49,FF,A7,C9,8D,4C,64,D0,99,2E,EF,05,CA,61,64,EE,BB,BC,F9,D1,7D,9F,C7,3C,AC,F1,1C,86,84,01,92,4A,92,EE,47,2C,D2,3A,20,F8,B2,96,B5,94,BD,12,71,43,EA,8C,D9,F7,AB,96,59,F6,EB,B9,14,F3,4B,A5,0A,EF,4E,32,A1,AB,1F,D9,36,6D,73,1C,90,00,DC,70,2B,8C,02,6C,45,23,23,33,A3,45,CE,A7,6B,0D,C7,F2,6F,A6,02,98,7B,24,FB,EB,EF,22,54,24,2C,FB,23,1B,71,96,91,71,B7,08,AD,4F,ED,9C,C9,14,33,E0,F4,5E,B3,16,F4,3F,47,5D,52,53,03,11,93,0D,D4,65,27,23,6F,29,8C,F6,F4,91,96,8F,DD,92,E5,A7,DA,B0,13,36,EE,AA,D8,F0,18,B7,72,7D,E1,C4,5F,BD,63,40,34,FE,F4,39,32,68,8B,9D,28,18,41,3A,4C,7B,81,65,33,50,9D,33,BE,1C,C2,89,70,DF,83,0B,86,C2,CA,2D,54,9F,41,27,41,1A,C9,AD,DC,42,E5,E6,C5,43,BE,04,DD,59,93,59,84,0C,59,3B,14,1D,6E,7F,14,8B,6A,91,1B,C5,9E,AE,61,FF,43,32,F8,D5,84,C1,6F,CC,22,B1,9C,37,CE,EA,9E,52,72,3F,B9,2E,C3,BE,CD,E6,97,6F,62,AF,B9,0E,72,28,CA,4A,63,70,94,3B,BD,10,2A,8C,81,73,C7,3A,6F,41,35,7C,14,58,80,D9,6A,BF,FC,65,A9,A9,20,34,99,AA,F3,E3,1F,5B,AC,0F,DC,4C,A7,5C,C6,70,D9,06,1D,D3,17,B8,36,6E,07,97,7F,24,0F,37,33,D5,D7,84,05,DA,B5,00,B2,90,8A,07,50,47,5C,A8,1C,3B,FC,CF,00,EE,2B,B2,DA,CF,01,4E,56,87,C1,0B,14,69,E1,AA,9D,95,17,17,1D,13,87,CE,60,B0,81,A7,9A,92,8C,EF,3C,98,78,60,92,BF,A5,5A,0C,3B,7C,2A,C6,95,26,AF,81,03,DD,42,9E,01,EF,83,E3,8C,C1,17,00,31,AE,5B,DA,E3,18,4B,24,AF,96,AC,6C,1F,C5,8E,86,F2,25,AF,84,36,3A,9E,C0,45,D2,0D,DD,04,E7,58,4A,69,A2,9A,12,B5,93,F5,65,BB,7F,98,4F,0C,D1,21,FE,06,4A,4C,F8,EC,31,3B,5D,C5,A6,2C,CF,F2,3E,11,73,12,71,DA,7C,05,23,4D,A5,DE,63,03,1F,E9,A4,F3,DF,76,49,29,74,B0,FC,F4,C7,2A,82,3D,95,A3,97,7B,4E,20,AB,7F,9A,40,2D,44,1C,E6,4A,94,B5,6B,22,69,88,12,02,81,19,60,84,7C,90,E0,EF,D0,78,A5,1B,92,59,D1,46,7E,64,B2,52,66,13,DE,FF,ED,D1,85,D0,7B,7A,8B,07,C2,CE,27,00,07,81,C5,6C,66,9A,75,4A,8D,42,26,10,A5,7D,4A,BD,29,D9,83,43,7E,55,F6,80,5E,72,C4,A3,E2,29,C7,E5,AA,F0,27,6E,3C,4D,F2,5D,01,AF,45,77,20,16,1B,DB,E5,E8,62,15,BC,DD,DA,EC,C3,81,74,F6,F8,E1,88,C7,E5,D3,DE,DD,94,9A,C8,1D,E8,23,90,E1,7C,D0,40,F5,5E,FB,D3,2C,E3,6B,D4,DF,5F,18,7E,D2,65,5D,B1,12,7F,27,8F,6F,6B,2E,79,CA,E6,C4,10,B1,5A,DC,80,57,A7,BA,84,D1,57,6E,B4,71,AB,81,F5,BF,46,3F,A3,A6,FF,85,22,1A,D8,5B,F8,2E,28,C2,63,5F,81,2E,A3,2C,89,7F,D9,7F,19,24,B4,82,CF,D8,B8,0D,12,3D,31,D8,1B,90,2D,C5,88,D3,F4,FE,7B,BE,89,06,C6,1C,23,C8,EF,96,B5,CA,F3,DB,F9,1D,43,A0,88,6B,B1,C1,93,31,CE,DA,40,4C,92,D0,46,99,37,CF,74,ED,CE,72,93,7F,E0,F7,D8,6C,46,E6,21,20,7D,39,65,D7,82,E4,15,98,07,B7,D6,6E,D5,A9,A8,7A,04,2B,C9,23,D4,65,0C,5F,70,9D,86,05,0F,16,E3,18,46,A5,E6,7E,38,81,40,07,A8,A5,46,79,2C,49,BE,AB,35,C0,A2,11,07,99,6B,02,4E,B3,40,F2,5D,96,F5,67,ED,10,E5,20,3A,D2,CA,04,20,44,CD,FB,AA,07,37,B0,88,61,86,F3,AA,32,C1,4B,6B,E2,C8,68,1E,79,60,51,BB,4B,09,93,35,3F,27,3D,9E,3F,E1,4C,31,40,DE,FA,5E,83,E6,25,AD,B4,32,06,41,90,BF,1C,7B,8C,7E,B4,E3,38,99,E5,21,E1,02,3A,BB,CF,78,02,17,62,B3,6E,65,B8,73,DC,7C,D3,34,98,51,61,34,98,BE,A0,8B,C9,55,99,EA,04,A5,61,CB,9E,D7,88,A3,6F,A8,4A,77,62,60,55,6E,F6,2E,17,6C,75,28,24,03,83,17,07,CC,74,79,47,40,B0,39,64,6C,C0,2F,87,99,D9,CC,A7,6A,4F,23,F3,5B,EF,A6,11,B6,73,D9,AC,15,8D,3C,09,63,EE,15,95,13,65,E2,64,E0,62,B0,CC,85,65,2C,4E,37,00,D1,1B,05,4C,5C,39,B3,1B,92,7C,D4,4F,6F,5A,35,D6,AA,71,9C,2E,90,26,1B,C8,31,D7,A9,70,98,A0,9C,C5,93,66,84,1C,51,CB,C3,D9,1F,18,13,3B,7D,EF,07,B5,B0,6E,B5,A8,E5,63,13,F2,1B,D3,08,BF,BE,32,AC,4C,0A,4D,15,21,63,5B,66,9D,97,B0,99,BA,FD,BA,41,53,23,E7,E8,4E,F7,D5,87,A7,EA,C0,F5,DB,F4,46,BF,0E,28,5D,B2,09,44,1D,13,E4,1B,07,90,4B,D9,AE,45,F7,1D,76,2A,A5,08,67,D8,68,AB,4A,38,FA,B6,7E,ED,BD,B4,87,30,38,AF,CA,CA,CC,F3,63,4B,B9,26,61,30,68,4C,BE,B6,99,E9,4B,5D,44,9F,D4,15,95,74,5F,88,F6,DD,6A,8C,74,2C,CE,29,93,96,F9,B5,D2,BA,DB,56,EE,D6,CF,2F,D2,63,1E,1B,90,63,73,D6,EB,1A,7C,D3,B8,DB,99,8C,39,80,38,B5,A8,4E,0B,CD,CE,FD,88,3E,BB,EB,AC,F7,01,D8,D8,0D,21,2B,97,D5,33,EF,BF,5C,E6,F8,C1,42,71,F8,D3,3C,C4,6E,CA,4B,AB,43,CB,7A,EA,84,4F,81,57,2E,AF,D2,C0,82,F7,D5,66,0D,A0,67,5B,EB,AD,62,2D,F0,FF,32,75,C9,60,64,2A,BB,2D,DD,24,61,1D,52,93,0C,39,41,E5,16,86,D6,14,7E,39,3F,B3,03,69,42,F5,0D,87,28,DE,2C,C3,31,75,7C,01,84,24,2F,3B,D7,1C,E8,0E,DF,64,33,45,36,ED,BE,E5,5B,E7,F6,AE,E3,75,7A,16,D4,48,2B,1F,DF,27,61,79,B4,10,7C,D0,7A,E2,F4,72,B9,64,C0,F7,6F,C5,99,15,5E,C8,6F,74,C7,46,D4,96,77,E9,91,8F,6A,85,DD,BC,73,5E,58,B6,73,80,A5,F1,82,F4,52,D2,B3,CB,B3,1B,63,91,B3,01,10,45,71,4B,44,12,6A,70,CA,46,65,CC,C8,31,36,42,0D,9C,8E,3D,63,A4,9C,A3,D3,14,F1,9B,AA,CF,C7,76,89,0A,BC,FD,BC,3C,31,28,DB,08,72,6D,A8,19,D2,84,DF,B4,05,67,88,6D,36,9B,D5,2C,C9,CC,2B,9D,AC,F0,70,D0,E7,25,C3,08,81,20,1C,7D,66,DB,BE,3B,5B,41,03,90,7F,04,B4,87,A4,7D,B7,F1,8B,9E,42,56,53,EE,08,B4,4B,9E,C3,85,74,19,B7,0A,AE,B4,3E,F5,E4,F1,BF,A0,19,67,55,89,B4,FC,52,DF,CD,6E,5C,1D,57,E7,BF,D7,F6,3E,C2,60,AE,FF,B5,E8,53,3C,F1,49,C7,E8,CC,9C,85,94,47,2A,82,B9,81,2F,A8,9B,88,81,01,79,45,B4,B4,4D,4E,12,05,54,BA,DE,8B,10,84,AD,7A,13,1F,90,72,34,83,B3,9D,B1,4F,49,8E,A1,42,4C,5F,C4,12,03,47,52,60,0B,A7,50,FE,AA,D7,C5,80,DC,03,E7,A1,D2,D9,A0,E4,7B,C6,4F,7E,9D,C7,9F,B6,75,59,70,A5,96,17,2E,CA,17,0B,34,03,F0,48,59,AC,62,C1,87,2A,A3,A0,DC,B6,B4,81,BF,9D,83,79,34,F3,62,F1,91,32,DC,80,D4,D3,98,64,5F,A5,9F,AD,6A,BB,2D,17,95,82,3F,47,E5,EB,31,69,42,4C,32,31,8D,58,C6,DC,41,38,0C,06,FD,68,8E,02,B7,ED,5F,CA,7E,7D,56,3D,41,57,9F,9F,24,C0,9A,CD,A9,6F,94,89,59,C6,E0,85,0B,18,DE,DF,A9,31,78,41,2E,4F,12,91,53,EF,4D,E2,97,E6,BE,91,9F,B3,45,DE,48,29,C3,76,E8,99,B3,2C,36,8F,11,EB,DF,D2,72,7A,5F,3F,DD,9F,F4,D3,81,A8,12,F6,6F,3D,3B,C9,CF,43,E5,1D,61,81,1C,FE,FA,10,CF,B3,DB,A2,EE,A6,10,99,50,08,65,A2,40,A9,18,9D,A9,45,7A,B4,C4,3A,1F,95,75,8F,4C,F7,4D,D8,18,FE,CC,63,8B,BF,22,4B,27,B0,D2,31,19,F1,E5,71,5B,64,93,58,E1,D7,F4,88,84,81,A4,15,88,A7,E1,C8,76,BF,7C,3F,50,53,E1,B8,B7,E3,84,99,89,11,C8,2E,55,B3,E5,76,FF,9A,C5,7E,0C,B4,88,73,79,EB,C2,26,DF,5C,7D,6C,0F,9A,EB,BB,5C,AF,AB,34,1C,67,AC,9C,88,41,94,85,B5,78,FD,F6,5B,5C,AC,1C,62,C0,A7,C9,5F,9C,80,83,9E,18,36,AB,85,65,4A,0E,2F,4F,AF,E0,DB,EA,66,33,7E,EB,26,7E,AC,3A,85,37,2C,92,03,2D,22,19,DD,96,21,66,DC,E6,09,10,18,1F,60,41,B1,32,9B,79,E7,7F,F1,73,06,CB,D6,D2,0B,8A,F4,BE,DA,F2,DE,B8,46,41,3C,E3,AF,9B,D2,BA,5D,96,1C,DA,9D,86,7F,7D,19,C5,A8,4D,CD,C9,68,4F,41,6B,DC,9C,01,81,20,85,E2,52,D4,2C,7C,7A,54,01,EB,6C,87,F5,F9,57,F8,AD,7C,09,34,2C,23,10,3A,6E,E9,53,0E,FF,C0,00,64,92,24,2D,5D,29,BB,9B,D6,AA,E3,3F,92,59,CD,A7,BE,BB,DF,A7,D1,BC,E1,2B,D9,86,5B,58,40,4B,58,7C,3E,F9,05,64,42,EB,17,FB,DF,0B,9A,CD,D7,A6,35,89,77,FB,0D,CF,99,D8,B9,D2,BB,08,61,98,7F,B9,1F,4D,EA,B2,AC,FF,64,58,5F,05,86,54,98,B1,2C,9E,F2,14,BC,38,56,0A,95,89,EB,8A,38,6F,75,30,BB,28,0A,58,08,8B,E8,FF,AF,F9,0D,A6,D8,4B,3E,A1,98,02,13,89,6B,CD,09,1C,BA,E7,53,B3,5E,13,7F,A2,B1,6A,4A,93,BC,F0,DA,0D,51,03,C4,0D,1C,CF,9B,3E,5E,69,8B,24,FF,A4,4C,12,1E,E0,CC,08,F1,FA,F8,72,2D,D3,37,AE,C0,A2,E1,78,A6,BE,77,CA,D9,F6,4A,60,35,2D,D1,01,05,AC,62,54,8D,57,36,74,62,BC,D3,4B,C5,F4,85,B0,90,12,64,6C,0B,3D,91,93,BF,85,56,E1,0C,5A,29,A1,83,5E,8B,A0,AC,E9,2A,37,09,AC,C7,0E,DB,90,7D,4B,1F,46,6A,DA,92,A8,93,C4,27,5F,ED,10,4C,DB,53,78,EB,26,AC,D9,16,C9,AD,DD,52,38,F6,D8,1B,15,51,65,7C,EF,51,49,5D,60,5F,28,E6,0F,97,B3,DD,A5,0D,89,2F,1F,94,7C,3A,33,82,55,B8,92,F8,25,1C,19,26,86,43,F3,B5,5C,93,A4,C4,93,E6,82,82,E7,AD,DA,F0,5F,78,82,31,27,00,5C,69,CF,C3,6D,39,74,2E,26,2C,CB,76,E7,13,BD,D3,D9,3F,E0,5E,62,DD,E1,93,76,05,C5,89,DE,3D,BE,B5,E0,BA,E1,59,A6,F1,B6,A0,9A,13,F5,34,90,09,98,35,5B,1F,04,56,28,D0,7E,77,1C,10,73,CC,C7,82,93,B3,CA,D6,9F,4D,D4,67,5F,43,74,F5,D5,E2,41,EE,90,51,85,C9,46,27,9D,7B,E3,3C,83,3E,3B,FA,F3,D5,B1,9F,F6,4D,5A,2F,BD,82,25,8D,9B,0D,8C,21,56,85,79,59,14,53,6F,75,D5,19,91,AB,9C,6F,E6,78,C9,81,47,15,51,C3,A7,7F,F5,79,8C,78,98,AB,03,88,D8,18,7F,11,42,85,F9,E2,42,99,47,1B,19,28,31,4A,0C,74,E5,10,6A,EC,C8,0F,50,62,75,A5,BA,15,BE,83,3C,C4,C5,C6,2C,1B,41,66,AF,9E,32,F5,BD,E8,E4,1F,DA,5D,61,48,DA,3E,7A,0F,0E,A8,24,D4,55,5B,7B,3A,45,90,0B,39,7B,FA,12,FE,89,89,07,2B,B8,91,FA,62,F6,7D,E8,92,EB,05,15,DD,30,73,B3,DE,23,F0,25,73,4A,AA,D0,90,68,A9,9C,9B,50,C7,6C,7C,A4,C3,D4,58,97,BF,5D,40,B9,FB,51,2B,DE,2C,B0,D6,D1,FB,4D,DF,73,0E,3A,4F,66,5D,82,D4,75,FC,A4,26,35,13,13,AD,63,03,CA,E3,88,00,6E,3A,39,77,6E,96,30,0E,6E,98,C7,2F,1D,94,33,A1,35,0A,6E,30,76,3C,66,17,0F,E1,19,E8,CB,8F,33,6F,E1,E5,0F,AC,5B,E3,86,D4,4D,D0,3B,97,80,83,AC,1E,F3,03,33,DA,FF,3C,93,AE,08,F4,34,F7,44,E2,34,DF,0F,DE,7A,4B,E3,D2,5F,B9,2E,31,96,E3,B1,61,7E,A0,B2,42,3A,4C,7F,49,68,3F,C9,DB,D8,FB,44,1F,76,06,6E,0A,C6,D0,66,13,EE,E9,7B,76,A9,C3,AF,A2,03,A9,36,08,B6,89,E0,53,D5,00,8B,45,75,3F,51,08,4C,C2,BA,52,AC,F7,FB,50,55,56,4B,CC,D4,C9,C0,2A,FC,69,9D,06,E8,28,6A,90,FE,4D,F2,4D,84,E3,4A,71,21,E5,5A,C9,B7,26,7F,2E,F8,99,06,67,1D,CE,BE,AE,EB,62,FC,48,16,D1,B6,44,18,2D,18,BF,D8,18,BF,90,56,F6,FF,CB,DA,D7,26,52,CD,06,B5,9E,FF,34,5D,94,2E,DF,D1,78,5C,AE,9D,AA,EE,59,3C,DD,FE,DA,25,40,36,F5,83,A0,F1,A1,E1,DE,71,78,12,9A,BC,80,F6,64,34,7F,1A,06,BC,91,65,8D,E6,FA,6E,B7,61,A8,3E,A2,64,C8,8D,1F,98,83,8C,C6,71,40,89,3B,0F,9D,5F,DD,3A,BF,42,47,78,23,73,86,BB,50,99,28,31,56,CD,BC,36,3E,3E,DB,4C,DF,35,84,A9,92,36,E5,1E,D1,8C,39,11,FA,10,3B,6A,51,01,16,36,85,F1,89,40,96,24,79,A5,0A,40,0A,E5,1A,DA,59,44,6F,D4,95,96,7A,47,66,5B,16,0B,45,6D,88,C6,4D,72,A9,31,D0,78,ED,23,05,26,C0,34,D5,02,1B,3E,D0,82,6F,0A,2D,D4,13,09,B0,0E,2D,74,C6,FE,63,D7,F9,36,59,ED,B5,AC,3C,E0,20,A4,4B,25,92,88,99,80,8F,69,FC,F8,D3,A1,4D,B7,A9,63,FD,8D,21,91,68,60,7D,EF,62,65,31,E4,79,90,12,FD,DB,12,7B,92,03,FC,5E,22,B8,25,C9,E1,2A,DC,64,CD,56,85,FD,80,44,82,8D,14,47,E4,E2,E7,00,D2,48,2B,F2,3B,56,A4,3A,A6,54,81,B8,7B,5F,5D,24,8C,89,FF,47,BF,E6,80,24,03,9C,14,D1,9E,59,50,DA,C8,C9,F3,44,00,1F,98,BD,C6,5E,92,7B,03,2D,02,69,25,B2,09,D8,A6,38,AD,0A,1A,A0,96,97,EE,89,22,3E,3E,48,37,65,6E,6E,07,24,F0,4C,31,5E,AF,1A,3E,05,44,83,ED,BF,FC,CE,0A,45,B0,74,B0,58,E8,0F,8D,6D,41,EF,43,EC,5A,A9,BC,08,48,DC,1D,6B,66,B3,EA,61,1D,46,28,15,39,5E,14,F2,B4,9C,57,2E,FE,47,82,36,49,31,98,9E,53,4A,21,9B,B8,ED,FF,A9,44,EF,C0,B1,AB,9D,A4,C5,D1,0E,FB,7B,98,DD,DE,17,94,1A,3F,57,02,2A,DF,40,E8,24,AE,EC,FA,B5,39,CB,D8,FF,C5,71,0C,39,C9,7A,EA,E7,20,C8,3D,58,D4,3A,A1,11,69,FB,B7,A9,DF,59,29,07,C2,B6,8C,86,DE,FD,99,44,EC,49,6C,12,0C,46,73,6D,73,6D,61,F3,76,7C,2F,C9,40,84,65,4E,15,1B,2E,FD,34,59,BA,5C,68,31,59,72,74,11,1A,57,0E,F7,4F,23,52,FB,F2,AE,6A,B0,EC,0B,03,58,4D,C0,3A,68,79,D2,B3,AB,D5,32,A0,A9,9B,E5,C8,F6,79,ED,0A,07,7A,12,D5,A2,22,00,81,6C,DA,C1,8C,0F,BF,AA,EB,B4,92,7E,65,29,7B,7D,FD,8A,BA,BB,5F,37,78,AA,83,49,37,86,40,BD,67,33,42,F8,A9,5A,02,71,5C,D7,85,03,93,80,76,EE,36,CF,99,57,5F,F2,3C,82,28,A6,49,CF,77,CA,46,DE,3C,BF,DC,09,23,8E,2F,1D,7C,5D,3B,77,9C,0B,3D,19,12,CC,26,53,32,BE,33,86,7E,D9,0F,4E,0D,41,C8,CD,37,33,73,30,37,2D,D2,9B,75,8B,47,2D,30,C4,F8,9C,5D,9C,40,F6,0D,12,9B,46,4F,4F,48,E9,AF,01,F7,34,8D,80,91,7C,0A,46,F0,84,FA,06,D4,F1,3C,60,B7,C3,3C,02,C2,E1,11,31,C3,39,81,07,24,F1,8F,8E,4C,9F,D9,C7,C7,D9,D6,61,9B,E1,6D,D6,A4,38,50,58,F8,17,E2,81,9C,C5,33,66,20,B1,F2,65,06,3A,80,B3,72,7E,93,D9,C4,34,7D,5E,7F,C3,0E,C0,CC,ED,7C,9B,7D,70,F4,76,63,07,CC,DB,00,72,72,9D,0C,9E,9E,48,51,20,DE,79,25,5C,01,CC,F1,2E,BF,24,80,0F,7C,02,DD,74,19,72,39,FC,BD,CD,78,CC,F2,B1,36,46,4A,FD,65,82,A4,E2,B0,2A,44,5A,ED,DA,5F,A5,20,A4,03,AE,A7,7C,F0,2A,26,F4,72,86,0D,11,4F,61,B5,FB,A3,33,D9,45,80,D0,9F,A5,CE,E0,44,28,6A,9A,A0,9E,7C,BC,56,7C,AA,6D,37,2A,5C,C4,E6,85,F8,69,0D,E8,1E,FE,D5,BC,6D,10,A3,E3,76,EB,BD,AD,DF,A4,99,75,1B,F5,98,FA,3F,8C,0E,CE,FB,C5,89,58,81,F1,CF,E9,A6,67,70,A8,D1,B4,24,09,A8,D1,0F,4C,CD,71,E2,B6,C8,26,10,4E,0B,49,E9,50,04,D2,95,5F,03,3D,8E,B6,9A,08,11,4B,56,BD,0A,20,23,79,0A,96,20,85,81,54,AA,A0,67,3B,03,20,17,6D,22,B3,61,B3,E6,6D,AD,12,61,2C,A5,0E,67,8E,4B,84,ED,0F,A4,F4,B7,B4,91,CC,3E,88,6C,99,49,15,ED,C1,36,AC,5D,91,71,3F,F3,8C,40,73,5E,A8,7A,71,EC,4B,35,7B,A6,10,7F,26,E2,24,E8,64,06,42,EA,A9,63,B3,4E,B5,AD,0F,CF,39,D7,5D,56,EF,B4,F0,0C,0D,95,34,81,8D,D7,95,98,20,47,C4,E7,62,2E,C7,82,8C,64,21,1E,AF,9B,F5,F9,C1,9A,F0,0D,1C,3B,BD,07,60,98,6C,A5,68,E6,64,84,37,98,FF,5B,59,54,F8,0C,39,0B,0E,54,A2,E0,4C,FD,2C,BE,B3,C2,9E,D1,AB,00,28,D6,1B,25,B6,1E,C1,E6,71,8D,34,E6,D4,00,76,BA,E3,A7,DD,D0,24,F8,FE,52,01,3F,88,F9,BF,60,22,FB,62,47,7E,B6,E0,62,6B,A6,C3,EB,E5,E1,BB,2B,01,D8,93,75,22,B4,57,A6,BB,B1,9F,A2,FE,69,CA,79,D3,C8,4E,EA,86,F6,24,BE,E2,EF,2E,B3,1B,8C,97,DD,92,69,DB,FB,92,D2,AD,C9,B1,10,68,D3,4B,EA,9E,33,D0,8A,2D,7C,04,08,0A,C9,5B,71,89,EE,B3,E4,3A,F3,F3,1E,99,32,09,FB,07,1E,34,57,40,C5,E3,C0,5A,B8,F1,B8,09,5D,FA,C9,38,F8,BF,A9,D6,71,3F,11,CA,07,B9,95,B2,CC,45,5A,0B,CA,09,58,9B,E7,E0,C6,0F,73,55,12,55,F1,04,81,4E,20,95,9B,94,75,D3,F7,76,42,3D,7D,6F,CA,87,90,68,5F,11,5E,78,C1,FE,CC,F8,94,E0,6A,FF,F7,95,93,F3,EF,B8,FB,EB,57,3A,18,88,E0,1B,E5,07,79,1C,7D,1D,72,E0,76,2D,C9,6A,35,DB,25,CC,AD,14,05,37,A6,D5,C1,4C,20,71,A4,B0,39,7C,9C,36,8D,9F,ED,53,32,E3,4B,95,9B,D1,C1,E9,8D,A8,57,6F,AA,3C,A0,8C,A3,00,1D,1A,E2,22,CC,A2,AB,87,8A,50,69,91,6C,E5,82,C6,EA,78,3E,71,C4,B4,0B,65,04,8C,82,6B,B1,DC,EF,19,66,03,92,7F,D8,04,13,15,DB,D4,78,31,0E,13,D0,CA,C9,23,B4,AE,C9,37,E8,F3,A9,48,DF,64,9D,A7,A7,49,F1,33,9D,E6,B3,2C,D9,18,80,8F,E5,17,A5,09,DE,8D,E6,AA,7E,00,0D,3F,9B,1E,E2,E4,E2,32,7B,99,94,13,4B,9E,56,7F,3E,1C,96,D0,0B,4C,64,5E,08,30,B9,BE,D4,F8,02,B2,66,19,C6,C7,84,2B,D3,54,44,DD,C6,2B,2F,70,B2,F0,35,3B,D0,43,FA,92,BC,71,2E,F2,8A,EC,23,C2,0A,4E,0B,F4,D1,12,9B,4C,62,3C,1A,01,4F,9B,14,BC,54,2D,4C,55,DA,71,05,5A,16,B2,04,AA,5C,A3,4F,94,C1,4E,94,F0,04,D5,CB,33,67,83,59,CB,52,D3,82,4E,2D,AF,04,4B,21,35,65,0E,DF,89,A9,3F,AF,CD,5C,86,12,9F,D7,0F,33,C3,E1,92,59,74,E1,FD,E5,07,2B,B0,59,8B,DC,8E,4C,D6,23,9C,21,1A,53,10,0A,08,60,F5,CB,C5,5D,5A,F2,5D,7B,4B,C4,40,EF,48,F2,57,A8,3C,E2,52,83,83,02,D9,50,0C,E9,A4,C8,4C,BC,B1,49,95,F9,3F,79,84,74,C3,EE,DC,3F,83,10,5B,3B,89,96,DC,33,F5,D3,1F,81,85,AC,13,B1,33,1D,54,A8,EF,DA,50,F1,FF,75,93,1B,EF,1A,B2,22,C0,31,4F,CE,B2,31,C8,DF,10,2F,33,44,FD,B8,07,3D,4C,A0,CC,AD,79,C4,3C,22,7D,29,4C,84,E2,66,BB,15,D8,B7,C5,88,28,72,AB,91,94,12,EF,4F,E6,9C,EE,83,AA,BD,75,CA,32,6C,83,9E,E2,A9,F5,11,08,3A,BE,2B,4C,65,AE,60,61,E9,4D,BC,27,0B,56,2D,09,B0,AC,1B,8F,A7,64,19,73,5A,57,2A,A0,E7,DC,3E,1B,8C,52,42,90,59,60,0B,1C,5F,45,C0,C9,0D,68,51,D3,00,A1,D6,13,06,A5,E2,C9,DD,A6,4D,A1,73,93,A4,DF,D5,3F,CE,D2,08,87,9F,D0,33,5A,72,A8,C8,F6,6D,4D,6C,D1,4E,DF,AA,B9,1D,BB,E7,FF,21,E2,9F,99,53,9F,0B,EF,8F,0B,A2,13,AA,79,C0,B7,F4,66,E9,C7,D9,E4,C1,B6,C8,11,E3,8A,F6,97,CD,88,D8,B3,45,52,98,70,DA,F6,9F,28,55,73,E4,15,56,0E,78,B4,BA,75,F7,7A,F3,0D,AA,89,F3,14,21,CC,7E,A7,22,1A,F2,84,2E,3C,48,6C,B9,79,04,A5,C5,E7,50,0C,68,11,D8,B4,67,52,55,D3,14,9A,F8,3C,49,DD,B5,93,D0,22,A1,D5,A0,AD,89,8E,5D,6E,C2,69,33,CF,9F,63,E5,FE,1B,4C,59,C1,C6,C3,A0,A8,8F,48,43,A1,F0,FF,10,F7,D5,CE,5C,0D,18,D5,C5,44,D7,4A,64,ED,DC,3B,A1,D6,4C,D0,85,4E,00,22,A1,42,0E,CC,CA,2E,CA,42,DE,C1,CD,41,75,10,73,01,B0,E3,9C,21,A7,5A,C3,F6,5B,9D,93,40,5B,31,A4,3F,51,75,76,59,BA,4C,4D,74,7A,F7,7B,97,20,DE,7B,2F,AB,FE,5E,2E,DB,07,92,70,C6,AE,F1,78,61,AB,20,8D,68,57,05,9B,A1,16,B1,F8,8F,A5,44,1A,84,28,E5,43,EC,C4,1C,1D,B2,E6,40,72,E7,C5,F3,55,12,58,F7,4B,F8,D4,2A,AB,4A,BE,B8,AF,19,49,15,A0,FE,79,57,DE,6F,A9,90,D9,B8,B3,EE,63,D9,88,E1,7D,82,40,3C,5D,E1,B2,58,59,32,73,E3,C6,AE,6C,82,25,02,E1,25,85,15,32,A1,75,94,AC,C9,2B,0D,09,47,99,82,27,B8,38,F3,08,D6,6E,39,0D,EE,82,2A,DA,0C,AC,28,1B,8E,0A,37,5F,E4,74,B1,0B,2F,91,BE,61,89,64,7C,B8,DF,CA,43,4C,A2,B6,B6,AF,A6,61,31,75,98,59,D5,6C,A1,E9,1A,7B,CA,79,DC,DD,FF,4D,7E,D8,16,52,63,2D,C9,59,B3,A2,9D,B4,A8,37,D0,2B,06,CA,9F,A5,B8,0D,5F,71,63,36,29,1F,B9,30,B5,C3,4E,44,AB,E8,82,40,BE,D0,CE,F6,36,41,7E,02,70,95,D0,63,D9,A5,B1,36,AA,6B,B6,6E,08,A3,24,56,E8,E1,FD,41,7D,C1,CB,6F,EC,7F,E0,E9,8E,81,D2,15,90,86,BC,F4,E9,50,12,35,C6,C8,AC,EB,21,62,A3,56,FB,4A,62,FE,14,46,AC,E1,C5,95,BB,61,10,AA,79,BC,81,7F,18,FD,E8,8B,8B,AB,8E,71,7E,41,AB,CC,22,7F,59,5F,A7,F3,C3,19,7B,05,2C,A2,0E,6D,61,54,E3,83,4D,FB,40,E3,0B,59,1C,FC,8F,76,A8,E9,A8,2F,12,12,83,05,49,6E,60,0C,15,68,1E,94,69,3D,22,BA,56,74,23,47,C0,70,3C,35,4C,80,D1,1E,53,1C,06,98,84,A0,9E,5E,AE,D0,23,EF,14,D6,D0,52,97,CD,4D,66,0B,EF,FE,AA,A8,94,F4,1C,55,DD,E5,61,41,F4,1F,AA,9D,37,4D,61,0C,6C,3B,0F,8B,42,C2,1A,C9,8E,E8,2E,EF,94,C6,0C,30,DA,8D,6A,0E,98,78,10,94,4F,B5,E0,5E,F6,45,E5,16,1F,5A,A7,CE,1A,8D,7D,05,36,07,9B,07,41,D6,09,7A,B1,F3,1F,90,A3,BB,62,07,3B,2D,8E,7C,5D,6D,53,D6,77,9E,A7,10,73,94,31,AB,01,DC,69,9B,C5,7A,04,64,D6,29,90,64,F9,41,A0,71,02,6E,49,2B,37,1A,83,85,89,B1,B7,3A,01,8A,19,43,9D,66,79,22,15,51,8C,D1,0F,E3,AD,FB,90,AD,72,66,13,59,9B,FA,70,26,54,11,0E,19,62,17,FA,F2,30,A3,7B,EB,02,A6,AD,00,04,4F,D7,02,67,BA,61,13,1D,EE,3E,0A,B2,0F,BD,B0,AD,F3,B8,2E,34,F8,C1,57,9C,18,50,38,E8,B0,7D,94,44,BE,52,4C,F4,20,DE,03,F7,F5,EA,90,B8,AC,C2,D7,22,42,1F,3F,69,CA,5B,FE,A4,3E,26,72,D0,4D,64,D6,4D,BE,23,EC,06,33,AE,4E,27,57,73,F2,2E,77,24,14,86,8B,24,BE,FD,C8,60,03,81,71,0F,6C,80,56,CB,A4,F3,1B,6F,A8,91,67,22,C6,C6,78,02,24,36,AA,12,5D,08,7E,0A,4D,29,50,0C,E7,53,1E,7B,0D,08,5A,62,E1,10,FE,11,7A,2B,F8,F0,35,92,83,E3,7D,27,3B,DA,7B,E2,54,21,EA,D9,AE,1C,C6,C8,67,48,10,78,68,A2,6E,99,75,C3,FA,60,A2,FA,4A,BC,41,AC,EA,79,F7,DB,99,63,13,3B,DA,FA,2F,CE,F5,41,F7,77,F2,3E,D5,76,A3,E0,CF,15,88,DA,6C,6E,BB,8B,A5,9D,A9,E6,37,A8,08,88,8A,C8,99,C9,2C,BC,D7,53,28,B3,21,0B,69,77,23,AD,08,1B,AF,DC,28,7E,AC,BB,B4,F5,61,04,11,31,33,7E,36,2D,CE,27,94,8C,01,DB,9D,7C,AE,58,59,0D,81,96,79,2F,03,BA,21,37,B0,5F,17,4E,92,8F,FA,DF,9D,D2,AA,FD,96,94,4A,9F,53,D2,11,81,C0,31,DF,95,23,4E,25,4F,3B,2F,26,83,B8,1E,FC,0F,29,70,12,1D,4B,9B,6A,C5,6C,94,B2,A3,56,65,32,60,DE,DF,2E,7D,7B,D6,C3,D4,19,34,7A,4E,7D,D8,29,80,4A,41,D9,B2,7B,96,A8,48,B8,22,11,50,4C,2C,48,85,31,D9,C4,00,BF,6F,66,CD,8B,C3,9C,DD,AB,85,78,59,5E,AD,D1,6C,3F,41,49,49,3A,6A,C1,5C,92,D7,ED,0F,B3,CE,5D,19,5B,07,49,97,E5,51,51,BF,57,2D,C9,27,55,3B,DB,73,24,05,D4,B7,21,C8,55,D8,77,32,F1,81,01,57,B6,D6,E1,E0,7F,6F,6D,48,0E,D5,70,59,C7,29,E8,7F,E3,36,7B,71,B1,DA,0F,7A,78,6E,FC,FC,5A,6A,67,16,BC,19,36,78,53,66,DE,A4,3A,B3,C0,D1,88,A0,4D,40,B9,4D,74,10,78,4F,AD,69,B9,96,72,32,CC,05,50,78,32,46,8A,85,08,8F,A2,90,EA,CE,43,CF,8D,01,6D,A8,78,C1,54,42,9E,3A,06,A3,3E,36,D2,E0,B6,E1,71,9B,D0,8B,D1,70,45,A3,63,E0,71,B5,4F,D8,13,B1,61,D8,36,47,89,DA,97,EF,A7,8F,F4,B3,43,9C,54,03,F8,3D,C4,EB,DC,CE,21,27,F5,B8,79,EC,F7,2E,83,54,41,AE,15,E1,14,23,7B,B9,99,FA,EA,60,C6,59,0F,C3,25,31,2B,43,E2,E6,94,A2,BF,B1,9F,97,93,BB,21,D7,E1,C8,F7,A3,26,CF,F3,8B,9D,26,60,B0,24,60,02,1C,5C,86,B2,2F,B6,A6,AA,F2,92,8F,D5,BD,CA,C4,2A,63,BE,78,65,56,91,F0,F6,E9,6B,53,22,9D,C2,F1,BF,CA,69,A8,AC,4E,C7,29,B0,D4,D5,52,33,5B,FE,A4,F1,BC,0B,13,CB,F4,8A,76,5B,21,88,15,80,37,0E,BF,6E,EB,E0,72,22,70,D6,BD,47,EA,55,8F,1F,F0,BD,DE,7B,5F,6C,FA,37,7E,1D,16,44,2F,6F,BA,A3,BB,39,CF,CD,F3,21,7F,CF,E6,73,BC,BC,24,D2,38,D0,60,4A,4C,B1,6F,FB,2F,0D,58,0A,04,3B,47,ED,F4,64,39,BE,91,F4,BF,DA,FB,50,CF,82,95,F4,59,D1,22,68,F9,49,54,07,AC,ED,76,D9,D4,1B,65,C5,F0,33,17,8C,E7,95,18,B4,FF,ED,C2,5C,4B,F3,29,0C,BC,A2,89,A1,5F,45,B0,4D,B6,83,A4,DA,C7,DF,CD,E6,80,5A,5D,05,41,22,E8,B2,CC,10,13,5A,BD,92,3D,C6,48,78,76,CF,17,95,8B,09,C4,E8,25,31,BF,63,EF,B6,E9,EB,40,1C,1E,3D,D6,54,D2,07,B7,BC,45,CE,AA,F5,6B,F1,51,B9,E8,18,7D,43,D1,B9,52,DB,9E,4E,9B,C6,26,DF,67,E5,61,F6,F5,BD,3F,52,5D,37,83,E1,67,89,24,85,22,70,BE,B8,A0,CF,9D,2A,14,16,70,E8,68,2F,73,20,57,47,07,A3,E7,66,BE,87,23,43,78,35,FE,44,61,33,4F,06,00,11,E6,5A,6B,2D,DF,56,6F,C3,CA,4E,4C,70,6B,90,40,4E,11,B9,A0,AE,AF,E5,EE,21,9E,DD,A3,47,EC,85,99,C2,17,25,AD,5E,8B,D5,9B,F6,69,E6,85,BF,ED,B1,2F,BD,62,82,D8,5A,04,6E,C9,B1,9C,A6,39,B9,4E,E7,E3,E7,CD,00,15,AC,EB,63,10,05,62,F4,44,AF,D9,BA,AE,1F,18,F2,0C,59,DC,E9,98,80,F5,C7,BB,55,9C,C5,F6,2E,96,34,39,9B,C2,BF,77,27,68,99,35,A6,1A,57,FA,7E,AA,1F,8F,DD,B1,74,B9,6F,2A,DF,46,4A,34,89,F9,72,8F,0D,CA,F9,78,9C,C8,44,92,CC,F6,B9,0E,51,A0,2F,1E,86,4A,AB,6E,0E,42,37,1A,43,B8,88,7C,47,44,15,9A,F0,82,50,8E,56,59,0E,9A,AE,7A,71,E2,C9,FB,B7,3F,51,FB,65,C8,B5,71,BF,32,8B,2C,9A,67,6C,BA,3A,EA,40,37,92,B4,39,4A,AA,06,6D,52,21,C4,A5,06,BE,0F,B4,60,5B,22,61,D9,1A,3F,5E,EB,5B,44,F2,2B,88,DB,77,4B,EE,FE,FE,4D,63,9E,77,A8,AD,62,B7,07,61,A5,97,00,69,FE,1B,A1,A8,87,DF,5F,8D,80,D8,D5,67,9D,28,4E,FC,4A,0B,A3,C8,04,BA,CA,DA,AF,C5,3A,96,67,10,16,A5,EA,D2,80,81,97,E9,20,B5,0C,F1,ED,1C,FF,75,51,FC,AD,EE,5F,CB,90,25,70,3C,EE,96,BF,14,2B,2C,52,01,D2,44,29,80,ED,57,19,72,D1,42,F2,0E,0D,3C,EF,B8,7A,A7,92,3F,92,FB,61,07,78,23,D4,A7,3F,BF,16,EA,30,DA,5C,D3,10,4B,4D,1F,5E,A1,FC,B6,E4,7D,E0,48,AD,15,63,60,5F,89,FA,AE,CA,DB,E6,B4,18,63,A3,E9,75,A4,E7,3D,10,0A,28,3D,4D,2A,E3,77,6D,3C,36,22,C3,87,E5,2B,1A,93,31,93,61,CD,98,3A,EE,BE,E0,2A,4F,79,C1,7F,E6,81,19,7F,B0,34,99,8D,E6,33,B4,04,F9,D2,B4,41,01,CF,80,99,BA,76,E5,55,F8,67,5A,F9,40,76,2B,5E,5C,A0,21,B7,C2,CA,EC,2C,43,25,93,3F,E1,FE,B7,66,CC,E5,02,2F,40,B2,57,C5,7A,D7,86,45,52,E9,75,5F,00,3E,DD,36,8F,B2,CD,DC,09,27,7D,91,20,F9,46,E5,45,08,B3,44,C1,BD,B9,D5,EC,AC,DB,89,64,C4,42,E6,82,0F,54,5D,2D,0C,F8,F0,B9,CD,FC,23,12,91,3D,70,D5,86,FB,7B,15,13,4C,20,CA,F7,B5,42,2A,20,32,D3,B7,B6,7D,1C,11,DC,15,56,29,D3,A8,D6,6D,A2,46,02,11,04,FE,3B,97,FF,66,CF,68,EE,4C,85,C8,BD,61,78,32,0E,9E,67,00,43,68,B8,DA,68,C1,EB,91,72,62,AD,33,57,0E,20,60,F5,23,D3,26,67,94,23,66,52,D3,DD,AE,BB,20,2B,51,D1,DF,DA,58,84,BF,B5,32,51,FC,EB,20,6D,2E,C8,72,8B,78,E5,35,93,69,B6,AD,F5,09,4E,09,15,CB,A6,D1,4E,D0,4A,6F,92,15,34,1D,E7,61,32,09,F6,BD,72,94,C2,DD,DA,A4,A5,1A,2B,16,A4,25,C3,EA,B4,5C,04,CC,8A,0B,B2,28,5B,17,B6,9B,79,2E,AC,20,5F,BD,BA,D5,4E,23,B0,7D,26,A0,E5,97,F3,7F,50,6A,A2,77,13,D2,2E,2D,5B,BD,3A,C8,6C,A0,3D,D7,C4,55,55,22,72,58,FF,99,29,69,1B,7B,21,EC,BD,58,EB,0A,5C,B4,41,98,F0,7C,AD,6E,3C,FD,CE,7E,8F,F2,84,4E,FC,A4,32,DC,BB,D0,A6,97,65,9F,36,2D,29,AC,DB,1D,1A,70,2D,C3,A1,92,72,28,4F,7C,40,48,39,C4,59,3B,3F,A6,4E,6E,05,60,2F,55,F9,F8,98,39,2E,28,C0,BC,84,4C,96,18,B6,A9,C4,E6,65,A8,72,90,82,79,6D,DE,BC,1D,93,D8,13,69,46,FE,E9,BF,DB,81,AB,66,D7,FE,13,4A,21,F7,A8,5E,F4,0E,AA,3D,EE,B2,8A,33,72,C5,CD,3D,07,4C,13,6A,DC,22,28,B6,DD,F6,BB,F4,12,F9,F1,E1,27,1E,DA,81,CF,D1,79,6E,08,26,6E,7B,8E,8B,CB,59,FF,A4,34,1D,52,18,BF,52,4F,AF,71,1B,9C,3C,21,9E,F1,F5,48,CA,42,6D,52,36,64,B9,DD,E4,1A,73,55,71,9C,B7,AB,8F,CD,10,27,DD,96,B7,50,16,92,EA,5F,4F,4A,19,05,C7,7D,CB,93,B1,6B,25,EE,A7,7A,E7,EC,7E,89,E4,EA,F6,C8,A7,7F,CE,7E,E7,96,EB,50,0C,9C,E7,65,99,7A,A9,CE,EB,73,72,30,3F,10,CE,2E,45,98,87,7C,52,20,23,54,6D,64,7C,A0,F3,CB,58,C3,CF,5D,51,47,2F,4B,C9,E0,46,45,C7,43,85,2C,57,20,57,D1,C3,82,19,E5,F5,B5,62,B9,02,22,57,E4,D4,12,B8,7D,B7,E7,6A,12,AF,9D,F3,E1,73,81,3C,A9,E1,A0,A8,32,07,91,C4,85,84,EF,DE,EC,38,B1,1E,A4,54,36,FD,4F,4E,0C,B7,C1,EE,27,0B,88,17,D7,62,3C,E4,51,3C,E5,72,E9,4D,42,1D,31,11,99,DF,FF,34,C4,D4,54,5F,99,94,26,07,3C,95,E3,11,F9,78,F3,11,80,D4,C6,5F,05,41,A9,C4,88,F6,30,4A,E0,69,D4,32,CF,E6,97,FE,72,56,24,C9,88,85,88,21,A6,21,EB,FD,2C,59,29,B0,DC,1B,02,F4,E9,35,8F,A4,0A,E2,BD,C7,CA,FE,10,1B,C2,01,87,12,E3,DE,B7,2D,61,06,B9,53,01,A3,4F,4E,6E,FA,8E,7E,D0,B8,5F,36,54,28,85,C8,B8,EA,64,87,84,AF,25,58,E8,63,D2,88,A3,7A,76,EB,FD,00,C3,BB,EB,F6,33,2A,09,77,21,1E,5E,A6,1A,12,62,D0,D0,30,35,DF,3D,55,A8,0E,3E,BA,C6,56,DC,D8,C7,56,D2,FA,66,E2,6E,1D,A8,0A,5F,C9,48,5D,05,E6,06,23,4C,CC,43,ED,2A,C3,26,C8,87,0E,E7,15,82,3F,68,F7,C9,9A,97,47,17,F2,B5,89,88,0F,D3,47,17,0E,B0,03,AC,50,56,15,A1,45,2C,50,CA,0F,4E,4C,D0,7A,3D,7C,49,46,F7,8A,2B,F4,92,79,71,CE,16,AE,C6,ED,40,74,07,5B,3E,45,B6,B8,5E,1E,5D,BC,14,53,43,24,EA,04,D2,10,86,21,22,97,E7,66,74,75,6D,D5,26,85,2D,F9,96,D0,0A,6D,A7,12,38,3F,FB,B9,DF,CF,04,D0,8D,52,B5,1C,56,60,3F,0C,51,CB,67,A6,1C,6E,33,58,A1,09,94,3E,34,05,6A,CE,72,98,8D,40,F1,9F,6C,1E,A4,EE,AA,CD,91,C0,65,76,37,83,AA,E8,C3,C9,A5,B5,66,E0,69,55,7C,53,3C,89,E6,47,2D,85,8A,66,64,FD,A2,03,DD,F5,40,F6,14,99,12,82,8B,60,95,74,C5,FA,94,28,71,FF,4A,28,64,1A,2C,09,D4,59,69,CC,50,0C,03,B1,D1,08,A8,CF,4A,E0,88,84,77,8A,E5,B6,EF,FC,EA,15,30,F3,5E,F9,73,98,3F,3F,E5,89,46,2C,1D,C4,FF,A9,5B,CA,1E,78,81,F0,69,8C,65,18,0C,88,CB,00,A7,91,CC,6D,45,6D,05,8F,D9,C9,23,5E,2B,0F,BE,BC,DA,5C,99,3A,59,7C,2C,09,37,C2,1D,E0,40,77,FB,29,A1,42,ED,0A,B0,E6,21,1C,82,38,81,EF,B4,79,FB,65,65,59,6A,9E,3A,8D,EE,B0,2C,D8,2E,08,F5,49,91,B7,2A,F9,20,AA,FE,33,19,AB,72,42,5D,2B,C0,9B,1D,53,A0,CC,FB,12,30,46,77,B1,11,C9,6E,6E,50,F9,AE,D5,09,3E,61,A7,E4,CD,1C,00,C1,24,AB,CA,39,83,A0,1B,57,89,EB,84,BB,3B,54,F4,F5,94,D0,0E,7B,88,B1,F2,CD,F8,A7,23,9E,37,9C,7F,8A,C1,7B,BF,C7,66,61,00,81,F0,C4,C4,8C,91,90,FC,4A,C7,27,AC,54,5E,C5,68,11,B7,84,76,F3,94,3F,A6,A8,63,DC,F7,E8,28,24,01,A1,0D,52,4B,D7,36,D3,86,B2,ED,2A,E3,6B,D8,43,99,79,2C,E0,06,FF,02,50,AE,5D,F2,DB,79,E6,8F,C5,2C,F9,FF,09,A7,D7,2C,71,CF,C8,2B,98,79,6E,A5,EC,F1,01,CF,88,99,3C,8A,AA,62,55,BF,D8,5F,9B,E9,CA,B8,59,06,79,2B,30,B1,31,46,F6,1E,99,EE,EF,CA,D7,0E,D0,C5,DF,6F,0E,98,7E,A4,C5,2D,D7,38,AE,0F,13,3B,CA,43,BD,A4,D8,DD,E6,3C,6A,E8,68,16,C2,25,18,62,7B,CC,14,59,01,BC,EF,2A,88,10,F1,9D,33,7F,64,9E,BA,E7,52,2F,A9,BB,8F,BD,E4,FC,B8,42,42,CE,F5,02,1B,07,1F,E1,74,E6,E0,9E,0B,B2,11,78,16,F8,5E,FE,61,9C,3D,82,10,2C,B0,CE,4F,AA,BB,7E,18,61,27,2C,08,6F,A4,4E,03,A3,B5,3E,20,6B,7E,C4,5D,52,24,3F,63,02,A1,CB,1B,42,94,96,EF,0C,27,22,AF,82,43,B7,1B,41,18,FF,EB,F6,A5,73,74,66,83,60,90,D8,F6,67,CB,80,85,B8,28,A6,1C,53,D9,E5,6F,2E,AC,14,99,F5,11,4A,47,E7,E3,B7,69,DC,25,5C,49,E6,AC,D3,07,2D,E5,82,7E,5F,7C,4E,C3,DA,F6,75,0D,9D,BA,69,0C,CD,D6,94,8B,30,C9,82,AB,79,72,4B,D1,C0,98,C9,6E,F6,0F,FC,77,6A,FB,A5,13,E0,F5,CE,0C,A6,4F,19,09,2E,BA,B3,B6,78,F7,A1,E4,B2,A2,33,78,55,50,AE,B0,98,7C,BF,20,5F,31,C9,7C,CA,68,1D,65,9B,4B,3B,C0,53,87,5C,B4,5C,C7,07,94,73,5D,D5,50,1C,16,55,4C,24,15,A5,D2,1A,70,C4,49,7E,52,A2,0A,3E,9A,56,4C,7C,F9,71,FD,07,35,E7,4F,5B,0C,06,65,AA,5A,67,11,AC,5A,3E,81,8A,39,A2,F4,98,F4,4B,8F,05,13,CE,50,53,18,7A,80,7C,53,D5,95,B5,B3,19,12,BE,8F,3F,43,C6,02,B5,EE,2C,89,20,43,B7,71,75,F5,D9,F1,AE,76,2A,6C,8D,73,11,50,AC,85,D4,42,7C,F4,22,04,13,EC,3C,64,87,6E,5A,F6,A2,3E,08,9E,CA,23,44,21,91,0A,C2,68,AD,E3,29,AF,10,C3,B6,A6,3E,56,8A,4E,D8,76,C7,32,9E,C7,78,3E,93,74,FB,AB,94,B1,17,BD,6B,DA,C0,EB,13,99,21,05,D4,30,A0,54,B9,41,02,BA,0D,29,13,F4,0D,CF,BF,FD,15,32,87,8A,83,71,00,7C,22,20,4B,34,74,8E,4E,09,60,C2,95,EB,AC,AC,CD,87,A7,1A,98,58,4C,73,D9,2E,77,5D,DF,A6,4D,63,A8,4B,36,EB,BD,AC,0D,30,66,AB,5D,0F,E0,BF,6E,58,87,FC,92,C0,43,CA,43,69,6B,3F,70,37,16,DC,8D,CD,FA,4E,C2,33,4D,1A,51,FF,2B,9E,1C,9B,0F,54,45,3F,5E,94,04,93,56,BC,8A,E5,09,2B,75,6B,62,26,84,1A,32,F9,A2,E7,0F,E9,B8,96,8B,D2,B8,4B,51,6F,EB,D9,3D,AC,41,71,05,CB,1D,19,7E,44,9F,D0,04,15,87,E5,98,89,64,1B,82,14,CA,D0,71,21,6C,F7,92,AA,1D,D4,62,27,44,16,00,BE,D9,49,05,7C,85,E3,DC,76,76,EF,DC,9B,8D,11,55,88,55,CB,AF,1E,9D,79,37,C6,B2,D1,3C,23,8B,0C,F9,06,D8,51,F2,8A,B9,09,E5,19,94,A2,99,A6,FF,9D,54,4D,37,3E,7D,33,94,83,7C,2B,92,D0,35,2B,4D,C2,2F,67,D0,E8,4A,C0,2F,8B,61,6F,95,A3,86,9F,B2,44,F2,4D,F1,DC,EA,A3,64,45,01,9E,76,91,05,B7,3D,7E,E7,F5,8B,FC,0F,A0,C9,78,7E,9E,A4,1E,33,65,13,C8,76,78,28,48,66,CD,04,DA,5F,5D,FE,FC,8C,8F,FE,7B,EC,A5,A1,5A,68,8E,FF,1C,A5,AD,27,4F,42,69,5D,3F,58,12,3C,30,12,D7,43,C5,B9,8E,03,37,79,AD,BF,35,45,D2,61,11,28,72,44,9D,7B,CA,A7,B5,73,A7,D3,DF,B6,B0,ED,89,95,11,70,50,D1,1B,A1,01,AF,C3,88,DF,EC,3F,DC,0D,4B,EC,D8,C9,89,13,C0,58,18,41,CF,49,D0,CF,B0,BD,9D,0E,3F,10,0C,20,60,66,0D,65,57,91,34,C3,06,CA,B1,B6,47,E0,60,87,D5,F0,FE,A5,77,9F,73,E7,F7,2C,AD,94,D9,2C,18,5F,AD,E2,E3,5E,0D,59,A0,C5,E0,F8,4E,F2,69,E9,46,40,E8,C9,60,24,60,13,6B,97,1A,CF,EB,94,55,2A,6B,CB,BB,85,12,45,3B,2E,24,C2,72,E0,1B,23,52,C9,EA,CA,4F,C6,EE,22,BE,83,AE,8A,40,ED,49,BE,FD,95,4B,B1,B9,52,4B,99,B6,39,DF,19,97,00,14,67,23,C1,AE,B9,9D,8B,0D,6F,F1,0E,00,2B,84,91,EA,7E,1E,D6,5C,58,0E,31,D6,FA,B7,36,F5,69,3F,AC,22,3F,1D,0E,FB,66,7D,87,42,9A,DD,18,9C,0B,EA,CF,05,4D,AC,68,F1,9F,97,BA,2C,4C,92,41,9A,96,0D,71,D5,A5,AF,C2,82,21,1F,28,70,72,8E,01,21,25,7D,B3,1C,35,EA,F4,DA,26,63,7C,4D,4E,5F,26,B2,34,89,72,59,3E,DF,07,85,F5,31,AA,D5,7D,BA,39,73,D4,B7,FC,47,0A,FA,C6,34,96,BA,9B,A2,23,E3,C8,E6,74,A8,E4,5F,0E,90,42,EF,F5,87,02,FC,12,C8,5F,47,81,FD,BD,D9,0C,86,89,72,19,A7,40,D3,85,5A,54,FB,83,FD,86,7E,5A,C7,41,55,26,D7,23,E0,32,2B,11,38,87,12,60,99,C1,4D,A3,50,82,2F,E4,06,E3,07,4C,2A,21,78,42,92,5C,90,BF,19,E8,B8,DC,32,73,98,D3,DE,BD,D1,BC,BC,D1,90,6E,5C,60,75,97,44,5E,26,29,8F,CD,FB,B9,27,2F,DE,D3,7A,9D,8D,4C,1A,CB,27,74,B6,31,07,AE,B2,EE,54,B5,F4,1F,E1,7F,73,DB,92,E6,D3,E8,20,BA,23,5D,70,47,67,06,A2,A8,0C,EB,CE,06,A2,7D,90,8B,48,6A,DD,A2,23,01,8F,6C,C2,BC,C9,E4,84,9E,26,1C,96,CA,18,95,FC,08,69,81,AC,DB,75,E7,3E,93,F0,73,81,27,49,8A,32,F9,FD,F6,EA,DA,F4,2B,49,08,C3,CD,6A,38,1D,35,1D,0F,F0,6B,67,4C,8D,BF,69,C1,F9,3D,3D,7B,80,DE,AE,8A,F2,28,E8,42,48,F8,96,36,51,9C,48,75,20,46,B7,2F,4B,7E,68,24,61,0E,48,35,84,43,F6,F9,2B,F8,8E,28,70,1E,E1,08,5D,E4,AE,F3,A1,EA,F1,54,BB,71,3B,A7,9F,34,B5,E4,67,63,A1,D9,CC,61,98,B2,3E,A5,83,11,4C,EB,7D,36,0B,C1,DD,E6,BF,A9,C1,F1,B1,26,5A,69,98,48,F7,FB,75,AD,AC,39,84,D3,33,16,CD,D0,40,DB,EF,66,16,05,68,DD,FD,6F,C6,06,92,A7,60,FA,2B,EF,23,04,BB,BD,9C,27,A4,92,E5,EC,3B,1E,3B,0F,B6,B7,D6,6D,87,FA,AB,6D,82,40,85,7C,12,91,E9,9D,31,C1,96,6A,73,B4,D6,26,0D,4E,73,F4,2E,C2,03,2A,0A,C6,80,0F,A5,59,3D,AB,06,80,1A,E1,27,94,90,64,42,12,5D,49,F0,29,4A,81,D4,E9,79,24,EE,08,3B,CE,5F,79,EC,07,FB,31,B3,73,32,C2,2B,07,92,CC,BF,0A,6E,C6,09,9B,3F,87,35,34,E8,03,9E,A8,3D,A8,FE,48,1D,97,E6,6C,FE,5E,E5,6B,38,A2,59,75,83,02,0D,F6,65,59,20,29,41,B5,9D,A4,C6,13,A4,43,CD,72,E1,18,04,D6,A9,38,FA,F9,21,E6,6C,9E,0F,58,1D,B6,81,A1,06,27,72,E8,C8,CA,9D,B7,03,5D,EB,10,CC,FF,3C,B8,F0,60,BE,3E,72,20,FD,41,B5,05,ED,A9,8E,7F,2B,69,77,7E,90,C1,C2,58,77,1F,58,34,74,AE,B9,0C,43,14,6F,B2,9A,11,DD,68,B7,6C,46,57,0A,83,59,CD,88,D5,4F,99,99,73,6C,27,F7,B2,20,26,2C,A5,B2,95,E4,E4,35,3F,79,C0,18,60,30,CA,45,5F,2F,0D,C1,E4,09,69,26,56,9E,23,F5,D2,02,F4,C6,82,40,58,E2,35,87,21,0B,A9,78,93,E6,D3,4E,4B,81,FA,3C,46,C1,32,5D,39,FB,BE,4B,0A,CD,94,18,F8,28,78,68,0E,A4,42,56,C6,80,22,07,F4,4F,55,45,3F,A7,F6,AE,28,24,23,8E,75,E4,28,B1,45,27,DB,F6,93,D6,A8,7F,0D,71,2D,17,27,B0,C9,7F,3B,BF,C2,48,CD,32,DF,46,1A,65,62,06,A9,EF,D7,1E,78,5E,3D,17,C7,D6,0F,6F,59,CB,38,2D,30,4A,2E,27,31,EF,B4,86,1F,EE,8F,96,0E,A2,C1,3B,25,47,18,8D,7B,16,C9,01,A6,37,6F,7B,55,F4,5D,F6,A3,80,9F,EB,55,2A,06,33,70,7C,B1,8F,A3,58,DD,56,B5,19,A7,AF,56,DD,4B,4A,FD,1B,9F,40,90,91,40,A4,14,AC,44,C9,DE,E9,14,6A,BA,F6,90,58,BA,B9,E7,07,7B,99,25,E1,A1,54,E1,C1,1C,DA,BA,AC,E5,63,A5,98,DB,1C,D1,7F,DE,D7,41,86,9D,D3,B1,00,EB,58,A8,58,11,77,5E,77,8F,01,63,14,20,80,BF,7E,E4,96,A9,1B,22,84,23,05,1F,6A,FE,71,03,90,3E,A6,A5,F0,02,FC,40,66,D3,BF,A2,FE,DD,40,D8,91,81,3E,25,38,45,54,82,54,E9,E4,89,2A,7B,DE,32,27,91,80,5F,FD,95,53,41,85,91,58,A9,9C,86,0C,E5,A0,16,F3,D8,97,1A,69,6F,B6,8E,5C,78,6E,07,77,05,AF,86,3E,B9,0B,D2,87,DA,CC,EA,A9,A5,CA,47,AD,AD,1E,1B,55,A0,8F,C4,83,31,56,3D,54,A9,CE,36,A4,D1,73,41,1E,C1,AC,7B,29,C8,A7,37,2C,52,B9,E2,A6,59,19,C0,B9,60,75,27,57,C8,37,72,5D,B4,98,3E,3B,49,7D,E2,75,B6,C3,C2,25,50,B9,AC,D9,4C,D5,23,06,B7,BC,B3,31,90,7C,F3,5F,EF,D7,9C,DC,56,65,76,49,10,17,22,8C,DB,56,05,3C,02,25,3C,77,C5,51,F4,F6,63,CA,E6,81,F6,EE,AC,7D,4A,02,76,31,42,F8,E5,B2,5C,05,A9,72,12,31,25,3D,0A,67,F0,F4,F9,6D,20,24,54,02,EA,8B,70,2C,2A,D1,5C,74,FF,28,6F,5A,D3,EB,9C,6F,42,AF,16,A6,26,50,05,8D,00,6D,0F,31,C8,0E,AE,39,4E,3E,86,38,A3,43,AE,A1,B0,C6,6A,D4,AF,B9,7A,26,D6,FB,27,8F,B6,56,B3,EE,60,27,3D,80,39,9B,09,E4,B3,DF,4F,37,A2,B2,E2,7B,C3,A3,C8,07,13,31,BE,F8,94,86,B3,60,B2,3F,0C,B6,FC,6D,85,12,9E,00,2A,D4,53,B9,7C,55,01,3A,F8,5B,89,24,B3,66,FC,26,4B,2E,15,42,32,4F,90,A0,99,2D,65,36,F1,5A,C1,49,25,BB,BF,81,AA,C0,95,8F,51,FE,14,60,F8,18,87,08,98,75,DC,6E,90,E1,57,B4,29,93,62,47,A6,8E,BB,5D,66,35,AE,2C,0E,84,5D,D6,C6,7B,C4,5C,3A,A7,01,55,F5,AA,44,B3,C8,97,B7,49,4A,0E,60,73,4D,4A,44,F1,90,78,C0,9F,21,F7,6D,31,B2,4C,54,A7,04,3E,E5,FE,F8,6D,18,B6,4D,0D,00,92,01,79,BA,13,51,0F,2B,24,A4,62,B9,4A,B1,4B,21,CD,EE,12,80,39,6B,EE,EF,40,31,14,96,5F,FE,73,90,CE,ED,73,7C,73,8B,51,AF,D6,C7,7F,BA,60,9E,D4,63,80,24,D9,B0,A2,50,F4,AB,F7,5B,AB,77,CD,B0,13,0D,89,5A,B9,72,1C,B3,C1,B9,C4,70,AA,A7,D5,27,E1,7F,AF,A9,A8,67,48,48,D8,44,59,A1,92,A8,DB,19,14,E2,69,BC,99,B0,D0,A8,A1,7E,9E,34,17,6C,81,C7,C6,1F,0A,B4,A9,D1,6C,A8,B6,18,B7,F3,0A,C4,2D,1E,42,A6,EF,18,24,62,AB,F7,0B,A1,47,25,4E,1A,CD,EC,DD,3E,BE,A7,0D,8A,AB,41,26,7E,E7,08,30,E1,0F,94,5F,66,4D,36,7C,68,EF,91,AD,1B,F6,B7,13,1A,C7,95,DA,AA,7C,4A,02,A6,A6,C8,F5,C7,E4,F3,A8,1B,D4,D7,81,C3,96,E3,62,5A,78,58,58,24,37,3C,CB,16,B7,8F,8E,82,47,A5,44,8B,CA,E0,0E,4D,10,5A,90,89,CD,1C,C0,C1,DD,35,A3,DF,D8,8F,CC,0B,D6,E1,F5,A1,99,1A,80,87,18,52,CF,76,5F,77,1D,0C,A5,4D,ED,80,0F,50,D0,47,26,82,43,E8,85,53,67,EA,03,54,A4,9E,4E,1C,EE,74,1F,93,53,41,AA,99,28,C7,DC,4B,3D,8A,C8,EC,C9,73,42,C0,02,DD,19,A4,A6,75,4F,29,E6,83,E4,EE,95,EC,A3,B6,BA,FD,68,2D,7E,6D,91,16,E2,CE,EB,8C,30,4F,13,31,57,D0,56,9A,D3,6F,E2,F9,C9,E3,8D,BB,FE,3C,53,DF,3C,DE,1F,B7,A4,CE,5F,AA,59,EE,EB,EA,58,C3,45,F1,1D,35,D4,DA,87,8D,5B,01,28,1F,10,17,41,4A,5D,24,FB,0C,13,53,DF,11,3D,83,C8,7F,73,62,FA,28,A0,3E,3E,E2,72,32,40,0E,B9,88,FB,47,DF,17,D0,8D,7B,A7,B2,0D,51,46,41,61,49,23,AE,1A,46,CD,A7,63,FF,B5,F6,7E,38,EC,9D,C9,1F,7A,DE,83,F9,90,B2,B5,8C,9F,CB,11,53,22,BB,77,64,67,2A,96,73,2C,1D,0D,01,AF,7B,EF,AC,43,9D,1E,80,BA,E3,0F,05,89,46,2E,6B,5B,91,87,B6,C1,12,74,94,DC,4D,83,6D,2F,74,1F,24,0B,34,E2,3A,B4,B5,C1,6D,A7,B1,89,C1,77,9E,41,0E,B5,37,EE,52,52,65,39,C4,D3,8C,64,13,FD,31,AF,40,9D,0C,11,83,00,41,6D,27,E0,F9,D2,15,2D,B2,8A,6D,C8,E9,27,B5,68,0F,BB,1E,7C,D9,6E,CE,13,A4,CD,6B,AE,CC,EF,64,47,2C,D1,DC,45,05,83,5E,A2,74,15,AA,85,40,56,3B,70,7A,56,38,DC,D8,A7,D3,EC,EF,03,A9,11,D2,5A,E6,D4,F0,F2,DA,0C,04,4D,13,2B,C2,3A,9A,DD,BC,E8,28,85,27,D7,6E,FA,F9,B3,37,AA,03,CD,62,74,7D,9C,0C,59,93,04,D9,F6,A0,0C,45,92,19,9F,4A,DE,BD,F4,BA,55,50,93,74,67,9A,C0,8C,81,84,A7,B5,EA,CB,17,6A,55,BC,3D,A0,CB,F7,86,25,9F,89,F4,80,74,42,C5,4C,D5,BF,AB,80,FD,54,21,C7,E0,0E,F3,4F,A1,FF,AF,1C,39,1B,E5,0B,87,F7,E3,8F,D0,BD,05,59,5D,6F,BC,65,D4,48,AB,7A,24,2E,DF,54,B8,EE,95,4C,9C,DC,7F,77,8E,12,D7,5E,61,38,86,15,72,24,1E,BF,65,D2,19,A0,E3,9B,32,67,68,D9,E7,76,55,18,97,78,B6,BE,42,32,F3,25,3C,CD,B5,73,C5,66,D6,CA,50,3F,6F,57,A0,93,D2,30,E9,B3,57,4A,A5,BF,2A,0B,C8,B1,1F,69,C5,6E,0E,04,2E,E0,AE,A7,7A,35,90,64,4A,30,78,99,FA,E6,F2,B6,52,67,EE,79,6C,6D,85,86,F3,D0,16,88,B7,70,C5,FD,4B,6F,71,80,10,73,4D,0D,08,95,69,11,A5,CF,47,53,E1,15,0C,0B,E2,A6,16,41,A7,B5,02,F2,77,38,A7,22,95,6C,66,94,40,7B,22,ED,DB,08,5D,8A,E3,E5,59,80,52,92,89,0F,09,A7,AE,8E,CF,55,9D,2F,25,9F,F1,31,AF,9E,D2,F1,FD,F7,C1,62,FE,58,E4,0D,0E,3D,08,44,03,EF,54,AE,E2,05,DA,62,E5,15,3E,93,53,21,23,71,1A,4A,56,DB,19,25,EC,67,7D,84,2F,EF,CE,CB,0E,EA,F5,AD,34,44,BA,AA,45,35,DA,30,0D,CA,DE,CA,26,8A,A0,06,00,60,B1,59,C7,F3,7D,8B,E9,EA,EC,0C,14,F3,8B,7A,62,EB,45,AC,87,9B,8B,FB,1D,49,F7,2C,36,36,FF,A0,43,8E,70,36,05,A8,94,FD,45,28,DE,45,2E,D8,5B,7A,90,7C,29,E0,14,47,7B,51,EF,5C,71,83,CE,05,54,01,5C,6B,9B,CE,D1,3F,EA,34,17,55,77,BD,3A,7C,6C,FB,C5,4F,CB,60,40,31,6F,51,05,88,81,FC,0E,5A,75,46,CA,4E,6D,AA,45,3B,73,64,0B,7B,BF,77,91,A0,69,F2,D6,37,4A,4D,18,72,E2,56,EF,D8,3A,9D,C7,97,15,75,04,91,42,67,5A,E5,F8,8F,93,35,40,63,81,96,64,33,C0,94,95,2E,2F,B4,37,55,D0,6C,0B,8E,0A,43,6C,1B,97,4B,BB,B3,BA,2A,B0,69,1D,0B,36,F6,C1,2E,F8,64,C2,6D,41,55,08,3D,18,AD,D1,02,8F,34,DB,CE,E3,DC,0B,AB,F0,7A,68,8E,3E,5E,05,06,4D,F3,DA,73,97,65,BC,1E,01,B2,8D,08,A8,9B,91,4E,52,02,B3,FC,FC,76,EB,3E,DB,43,3B,A8,A9,CB,EF,34,F0,5D,A8,BD,F3,E2,E8,95,FB,F3,88,B4,A8,21,8A,F0,E6,E0,BE,34,4F,7C,3A,50,97,32,E0,68,27,90,00,23,A6,64,D5,FD,0F,65,67,04,7D,CA,F0,94,D5,46,D0,E7,11,92,7E,CB,28,0C,F3,DE,D1,7C,A9,58,D8,F8,B5,FD,F1,B0,E9,B4,A2,BF,81,99,CF,F3,A7,16,57,4B,2E,AD,05,EC,06,DB,94,B4,0F,55,24,6F,B0,37,FE,8B,12,8E,CE,B0,FD,A5,C5,CB,35,3D,F3,FA,E9,D9,E2,21,E5,FA,5B,16,26,01,0A,38,5B,6E,AC,4B,5B,68,01,4C,E0,0C,68,E8,A4,68,D8,B4,7B,4D,E1,91,0A,2B,E2,0E,BE,BC,79,62,E2,7E,15,FD,6C,00,0E,30,73,B9,9B,85,34,FF,4D,5E,C2,AF,EE,51,0B,4D,A7,F0,41,26,2F,08,F1,99,12,7E,93,FE,A5,0A,A2,C0,49,13,1E,9D,A3,1A,41,90,20,9C,57,5E,AC,54,A0,88,ED,77,D9,EF,31,39,EF,12,37,AF,DA,CD,0F,B6,B9,51,EF,76,31,C6,D4,2F,ED,F7,95,23,26,6A,DE,DB,D5,0C,4C,8B,C7,5F,C7,A4,18,13,99,4A,1A,1B,51,75,44,F1,7E,5F,B9,77,1D,FE,7D,52,E1,1A,C0,BC,EA,97,90,42,B7,E1,74,FB,7F,A3,94,2C,AA,3D,7F,C3,F9,A9,3F,F5,D2,5D,B7,63,C7,1C,25,D1,61,46,23,FF,A6,76,3E,8C,2B,57,30,B2,05,CA,90,87,BC,B0,CE,2D,7B,FF,AB,76,D2,DE,5B,FA,19,47,BE,DE,1A,71,84,0A,2C,99,66,DB,4A,49,BA,75,65,E6,68,29,0C,70,76,D6,5E,69,63,DC,87,1E,46,12,DF,99,63,4D,A4,0D,7C,6E,01,8C,47,AA,0F,AB,57,ED,C9,C2,C3,CE,D5,CD,6A,14,DD,BF,43,A6,66,1F,C7,89,F0,CA,37,EC,4F,79,CA,C3,A5,EE,45,D5,87,6D,EA,90,40,F3,CC,4F,D5,BB,6E,BD,79,4F,18,66,27,FA,6A,9B,7F,64,91,69,B9,17,28,65,B4,11,F6,DD,BA,6C,DB,5F,ED,1E,86,49,0C,A0,F6,38,4F,4B,7D,77,71,9A,32,F9,CB,42,BB,FE,EE,62,7C,9A,02,BD,52,4B,2E,13,CA,3F,FE,78,E5,E9,9A,6A,CF,20,CE,EF,02,7B,B8,CA,10,B6,EF,61,4D,C7,BA,96,1D,F3,92,9A,CE,1D,5F,B9,54,9B,C9,25,A1,96,CE,F4,29,0E,CB,4A,7F,EE,AF,5C,33,6D,23,5C,A6,4A,AE,17,6E,FA,A3,88,7E,26,DC,1A,DB,B3,FD,CD,7F,F4,FF,76,72,B9,DF,DF,C3,02,FB,CA,96,87,58,68,C7,0E,C7,0B,7E,38,01,82,7A,E1,E1,E2,9F,59,0F,EF,3A,E5,1B,4D,40,52,40,EF,76,C2,5E,93,D8,8F,54,8C,4D,9D,CF,0E,5E,30,03,D1,1A,C7,70,71,1F,92,B1,BD,55,98,E9,39,31,13,23,75,6C,24,A4,AE,86,6E,06,E8,B0,E5,5D,B1,30,CD,B5,FB,C6,91,9B,90,EC,7B,27,1C,8D,41,DE,4F,83,9A,EF,D8,B1,53,7B,F7,E7,B2,A5,FD,C1,CB,DA,3C,04,F0,48,BF,CD,60,2D,1A,F3,6C,EE,42,F5,B8,60,3B,C6,1D,E5,6B,B8,3A,C3,C7,84,8C,38,DA,08,91,0B,77,DD,07,16,88,65,17,1B,3B,E6,24,18,03,C9,53,7F,85,01,05,63,CB,7A,2F,04,93,EC,E4,24,9B,9A,12,09,9A,A5,68,85,4D,6A,17,4B,CC,0F,E8,B0,F8,A7,6A,D1,6A,85,1D,9C,C0,A0,AC,4E,5B,89,E6,56,7A,FC,91,2A,8F,6F,15,8D,09,B8,B9,D6,61,19,E6,9B,1A,06,3D,7C,34,8D,F4,10,14,B1,BA,18,36,6E,EF,C0,CF,2D,6B,FD,F8,90,C0,D0,BA,2F,32,A8,CE,CC,64,5D,BC,0E,7B,AE,0C,43,AC,B0,53,00,FD,D3,37,87,B8,9A,B1,B4,A6,29,D1,35,58,9F,93,C2,E4,2E,71,D9,07,86,0A,0F,A8,D4,23,CA,00,9C,8D,1F,A9,95,B6,D1,73,DC,1C,10,45,82,ED,53,E6,97,E1,25,B4,26,73,1D,4E,F1,95,2F,C3,46,70,4A,BB,7F,06,C0,46,CB,A2,71,18,19,9F,94,96,4B,E2,92,37,B9,B1,04,C5,5F,4F,D5,A6,3B,8B,44,C6,FF,48,9E,55,28,CC,BA,C3,42,21,C9,F0,0C,4B,C3,26,88,8C,E2,51,31,0A,A8,F5,E6,3E,33,FD,6F,A6,8B,90,55,E6,08,04,D7,77,3E,EE,18,48,CA,1B,63,C0,77,9B,5E,3F,86,99,77,81,E4,AA,2D,D7,ED,BD,1A,6D,ED,F5,06,C9,7D,D2,2D,A8,3B,11,71,62,10,56,41,53,F5,CF,8A,D1,15,AD,74,D7,5E,2E,1C,70,C9,31,82,80,CC,63,03,45,8A,AC,F6,74,8F,F8,9E,68,32,3F,BD,AF,01,AC,61,EE,18,6C,9B,C0,D9,E4,EE,D5,6E,18,CB,AE,42,96,49,D1,FC,19,45,C0,08,DE,CA,0A,FE,AF,D8,01,EB,C4,F7,6B,00,CC,BA,80,5D,16,2E,9D,17,04,DD,A6,89,ED,A5,CD,CD,34,BF,03,BF,25,51,D3,2A,2A,EE,B2,2A,2F,E4,C2,D1,02,0A,3E,A4,1B,60,13,2D,82,07,07,34,25,F8,79,69,B5,66,56,5D,DB,F9,33,0A,4B,67,49,26,39,9C,A4,48,16,EA,D0,C6,09,7F,2D,6C,42,AC,0E,B7,8F,9E,71,7B,F0,B9,8D,35,04,FA,05,6A,04,3F,1D,77,0A,EE,C1,84,57,6D,58,79,8F,02,18,FF,C3,6B,93,23,2A,07,D2,7D,4A,7A,2B,62,05,BB,0E,D9,0B,CF,2E,20,76,3C,FE,C2,6E,3A,F4,EA,C7,D5,AF,E2,0A,9A,22,EE,26,DC,A1,A4,56,A0,1D,A8,EA,FD,7D,00,E0,EC,59,2B,97,30,BA,A1,62,38,7C,BA,E6,06,76,7C,CA,98,00,61,23,7F,84,74,1D,BA,8A,E4,F2,09,17,E9,2B,E6,AC,6E,BA,92,6C,EE,4E,F5,91,BA,59,F8,7D,22,09,38,28,B5,93,74,CD,DC,7E,BE,A2,E0,52,8F,24,DC,99,EB,30,EB,01,4D,90,64,D0,AA,D3,D4,4A,92,34,00,46,C7,C3,9C,46,12,BD,53,27,75,85,54,5C,63,3E,BE,82,05,C8,C5,C5,E0,A6,02,1A,F3,70,B0,A6,EE,92,93,00,8E,18,54,F8,C8,70,80,07,9E,7B,55,33,AE,28,34,D7,32,CA,48,5E,2A,85,F9,4B,4B,A2,C8,D8,44,F1,A1,C1,52,F4,73,F5,9F,F7,45,7E,AD,0C,2F,08,EB,E5,35,68,6F,A3,FA,F9,F0,C3,87,70,DF,0E,3B,99,4A,A7,E1,87,43,A3,5B,C6,8A,A2,85,5C,72,21,50,85,71,DC,67,56,8F,7A,FB,A4,74,D4,DF,2C,7A,5F,63,03,E5,4D,FE,AC,C3,F1,C1,AE,E0,AA,B0,EC,34,24,4D,95,7A,FD,8F,57,00,1B,F2,06,94,42,91,62,01,5D,75,55,72,83,B1,D9,9B,D7,A9,EC,E6,A2,B2,01,CC,F9,41,FC,3B,CE,D3,3E,A4,C9,97,A6,2D,74,CF,0E,D2,D3,CF,AD,26,70,35,32,6E,C8,A5,C7,F4,66,EE,63,B1,4E,12,C9,A5,4C,BA,B7,B0,AC,F2,A8,DE,A5,18,67,33,60,B9,16,1D,17,67,19,9D,9B,3C,4C,53,06,A0,F0,B2,14,8F,C3,9F,28,A1,53,E5,15,B6,77,EA,1B,3E,40,32,22,42,FF,24,96,0B,C7,39,24,A0,11,DD,FA,A2,85,B1,90,04,43,47,83,6C,2B,AF,B8,0E,23,77,B7,7F,E4,55,AF,E1,D6,74,C0,4F,B0,02,58,C9,82,E5,C4,56,1B,CA,17,6C,C2,A6,75,FA,19,7C,3B,C5,1E,0E,77,25,31,46,D5,7D,42,AA,27,8E,6A,72,E3,7A,0D,97,10,27,C9,6A,D6,9E,C1,04,FA,0C,8D,AF,9B,74,65,E7,63,A4,4E,A4,27,0E,56,5D,68,29,10,C2,AD,48,C9,4D,7D,F2,62,B0,D5,88,82,64,26,6B,06,81,29,7A,AF,74,12,52,47,2A,0F,ED,4E,CE,67,28,47,74,F2,AC,67,75,BB,66,F0,50,EB,1E,DA,75,7C,85,4E,18,E4,D7,14,CF,8B,D2,6C,16,7A,D2,9A,29,E8,00,AD,A8,03,71,60,34,21,EC,67,77,35,86,75,64,78,E0,34,D2,66,CE,3F,19,0B,00,F9,52,16,BC,0A,7F,2A,18,64,FC,1C,C0,3D,19,45,7C,6D,44,B8,7D,6A,95,4A,49,C5,AC,21,49,1F,12,D3,17,05,1C,43,1F,C6,B3,30,64,3B,C8,29,ED,68,E3,F3,5A,D2,4F,C0,0E,52,7F,C4,F5,FB,1C,50,FF,F0,D4,CB,7A,E1,08,64,75,ED,1D,BE,C6,C5,64,BC,1A,A2,EF,09,33,D8,20,D5,81,E9,59,CB,47,CD,90,D5,95,93,71,C5,89,B7,3A,AB,4F,48,73,4F,2D,E3,99,29,C1,7D,A9,23,71,54,22,F7,44,8C,13,EA,28,CB,8B,09,9E,BC,FA,3D,F2,66,51,65,2F,D2,56,97,1B,4B,F0,5A,73,AA,7C,86,6F,14,19,F8,CD,CF,7C,AC,57,D6,2D,8A,B8,08,4C,90,0B,7F,34,FB,2D,4F,2D,36,12,60,28,FB,7C,DB,B3,6F,C6,F3,8B,64,22,A3,C4,FF,52,0A,AC,7D,A9,21,D4,8E,61,FC,63,80,B1,83,92,A2,6D,DE,E3,8B,FA,E2,9F,58,76,55,12,4A,59,70,1E,A7,BE,05,7B,F2,7C,C5,E8,AA,10,28,A7,33,48,FC,9C,DC,64,43,75,F8,02,29,97,92,60,13,47,34,DC,B3,3F,16,C6,5C,2A,C5,F4,9B,94,6C,2F,4D,BF,1C,83,15,54,EF,8E,36,E0,BF,E8,5E,57,92,17,EA,19,BF,61,31,6A,ED,53,1E,72,D6,E1,54,F4,6A,B3,87,73,69,C3,E0,DF,14,A0,16,22,A0,99,70,85,A1,F9,22,95,62,C1,1A,80,72,E9,9D,80,8A,D2,EE,B1,F4,12,89,4B,42,02,79,B8,4A,95,B4,DC,95,54,CF,D9,CC,68,56,BB,09,72,10,60,53,D8,B9,56,DD,15,EE,72,E1,F3,87,F1,3C,68,68,17,CE,DF,28,CE,F3,57,DD,1A,75,94,FD,FF,C5,06,FA,75,84,F7,B7,11,0A,5C,90,36,95,6D,7B,0A,2E,42,C0,04,72,7C,76,C0,B7,2B,38,FC,8B,2F,64,FE,EC,C7,8F,EC,21,A0,0B,FF,8F,05,19,85,52,D4,00,DF,77,8A,E5,D2,6B,94,15,21,AF,F2,BD,51,0E,C9,AE,0F,F7,73,F3,E4,B6,12,BD,2D,76,B0,88,13,75,1B,79,A1,13,86,1A,FE,C9,A7,73,AA,7E,4C,51,52,AC,E3,D2,0E,16,9B,57,9E,F9,20,7A,77,AD,5F,B2,20,C4,66,9D,E1,8A,C6,7F,E7,F5,4F,22,9C,97,37,BE,DF,F3,23,32,41,47,80,D6,A7,B4,05,DF,42,D0,9D,30,AB,04,9C,BF,54,5B,24,01,32,AE,5A,E2,81,55,F1,CD,68,37,14,C1,76,AE,D7,02,7E,DB,24,C0,A6,09,36,1A,D7,BE,B1,88,D6,83,38,BB,C8,C6,A9,60,FD,B7,08,D2,8E,9E,E8,DF,CC,AE,9A,9A,CD,4A,A7,A3,34,75,0C,27,E0,A1,80,14,99,AB,9C,68,AF,6C,5F,6F,4E,17,69,FD,5D,14,99,FC,A9,41,C0,E2,45,AB,76,22,BA,61,6E,CB,39,C1,D6,70,23,01,26,59,C1,9A,0B,FD,E4,CF,5B,FC,9B,A4,76,08,C4,73,80,AD,66,EC,E2,C7,47,69,02,36,40,4F,45,FE,A7,F6,24,A2,F2,E8,F9,75,81,37,15,B0,18,92,03,33,52,B6,8B,62,64,81,B5,AB,80,BD,84,D7,CA,5F,ED,1B,94,37,B5,7D,D9,51,B7,54,A9,00,7F,B7,3F,F4,99,25,EC,65,5F,5A,B8,61,D2,54,A8,AF,78,9C,7F,76,EF,AF,FC,B3,9F,F8,30,7A,76,86,3E,05,DF,76,43,97,72,A1,92,22,19,57,04,61,E0,D8,C1,A6,B2,AE,BC,95,17,78,85,72,E3,57,B3,C4,5F,D0,B8,60,ED,00,58,0F,85,EB,BA,50,C3,8B,7B,3C,C6,7A,97,E6,6B,2C,48,F1,F9,7B,AF,9F,87,D7,5E,2B,28,73,F0,EF,69,23,25,FB,49,73,86,EE,67,54,78,E8,B7,3C,A5,F8,F6,14,8B,F1,81,72,94,E8,F8,76,4D,28,22,B3,F7,48,80,2D,47,6D,07,DD,D9,90,A5,C1,32,C3,9E,F5,38,5C,2E,E4,BA,34,93,13,14,F7,F1,A4,5C,63,47,25,32,3A,8C,37,88,02,54,A1,54,49,CA,EC,13,95,BD,3C,F0,A0,4E,01,28,08,9D,57,07,DF,00,A3,F9,2A,74,31,7B,FD,5C,2C,4C,81,D8,CE,36,63,A8,B7,E8,F9,D3,7A,DD,75,86,A3,A7,14,33,34,F4,C5,8A,75,2D,E2,33,6B,BF,B7,FB,2C,11,CD,A3,65,D6,00,36,37,02,A0,6E,B6,8E,54,15,70,12,50,51,D2,1E,1E,31,DF,18,2F,76,14,1E,42,66,6B,52,F8,60,9E,03,DE,30,38,95,38,45,B6,0E,0E,BA,F3,36,22,66,34,D7,F3,75,9A,2E,5F,55,A5,1F,CF,6B,B0,5C,C1,22,13,7C,D3,A6,3D,45,53,4F,8A,83,33,2B,0B,F3,D4,6B,D5,DA,3C,31,93,82,BE,22,D7,34,86,22,5F,1B,03,CB,53,C5,16,CF,AF,3B,6F,3D,9A,FA,27,CC,F6,02,12,A4,F6,48,C6,48,21,00,36,B8,89,C6,3D,0B,66,8D,F5,0A,AE,91,42,BC,17,48,3A,6F,88,A5,80,AD,10,80,09,AD,8A,56,9A,A5,AD,79,94,CB,78,E2,A8,C2,B2,66,E1,BD,F6,C9,82,63,4F,84,EA,A3,4A,B3,A2,CB,E0,CD,8C,D5,9D,3E,67,81,98,D9,1E,36,F3,E3,DE,9C,DB,F5,94,F4,5C,1D,2D,FA,3F,BF,F7,21,FA,1C,B9,C0,9F,36,8A,E7,D6,21,F3,3F,49,B8,20,7D,99,65,3F,A3,24,0A,7F,92,5A,FF,8C,38,4B,9E,D1,6A,15,51,50,06,47,B3,C3,76,90,B4,BF,86,3F,35,20,AD,19,E6,C3,DC,B2,D9,18,66,38,9F,FB,F2,78,34,B7,7F,CF,ED,AB,66,16,FF,CC,D0,D9,03,46,2B,C9,3C,E2,28,95,17,CE,DC,E9,9D,8E,E4,AE,4E,D6,0D,15,38,ED,B5,8F,97,D9,83,F1,2F,A5,F8,4C,33,F5,F1,0D,01,41,E2,D7,CD,55,6C,EF,DD,C3,80,ED,49,49,5D,BF,12,AD,91,6A,E1,6C,BB,4F,65,34,38,30,85,CB,56,04,83,BC,FF,F0,81,F7,37,7C,07,76,C3,97,B7,71,1A,4A,26,55,0B,CE,68,DA,68,63,74,10,F1,00,55,E8,23,B6,8B,9B,43,3F,CE,7A,BB,FD,03,17,C2,29,91,0A,C8,46,79,9D,09,80,EE,04,39,F4,B5,7A,61,18,45,8D,33,A0,50,1B,4C,4B,40,64,DA,E8,B9,0D,E8,A4,BC,75,44,9F,41,FF,9E,D2,05,62,E8,E0,75,CF,8A,AC,CE,CA,B2,F1,41,5E,8C,ED,A8,F0,63,87,31,2C,1F,D2,39,69,C0,44,E6,3D,42,08,E2,AE,53,86,B2,88,F8,E5,C0,30,37,21,5F,4D,8D,D8,29,FD,B3,A4,04,03,40,C5,AE,41,5F,07,D8,E4,6E,B7,D2,0D,AF,1C,8C,33,0D,26,DF,7F,3C,1A,ED,79,39,69,7B,D6,62,9A,6B,4D,55,89,E3,9B,D5,EF,08,FD,3B,D0,8D,44,22,5D,5B,EA,66,B9,B4,2F,8B,FC,8A,CE,51,B7,E7,E3,91,D1,45,37,42,D0,9F,D8,8B,56,7C,AF,B1,E7,5F,DD,D2,F1,15,77,4C,12,B9,3F,DD,00,F2,F9,0D,2C,D3,96,7F,13,A7,FA,94,3F,0F,F4,79,17,11,6A,97,28,7E,63,5C,3F,0B,2C,8C,72,64,26,E0,B9,4A,0E,6C,3F,6A,34,6D,EF,7B,CB,22,7F,B9,25,E2,4A,AB,01,75,AE,41,3A,9E,D2,3F,7A,5F,4D,FB,5D,BA,83,15,CB,E9,11,A2,4F,A7,D3,9F,78,49,45,23,FE,AA,E2,09,34,88,B8,B3,42,31,E5,74,5E,97,55,70,B6,8A,B7,F3,D1,5B,61,82,AD,FF,8A,A7,A3,A5,F8,50,29,B5,01,1E,73,FC,53,65,65,DF,12,DF,CD,51,40,18,2A,8B,40,49,41,BE,2B,F2,3C,B8,CF,33,95,2C,C3,04,7B,54,76,51,45,7C,D5,2F,A7,8C,3E,F9,D2,F6,82,49,09,44,84,2E,7C,22,0C,D6,4C,C1,11,AC,EC,7B,5B,98,6A,9E,0D,F8,05,18,1D,20,A8,76,69,D3,36,64,54,B4,BE,47,A8,93,3B,66,4A,6E,C0,98,C8,11,B7,F7,EB,EA,5F,05,F9,3B,B5,7A,7E,28,FF,9A,2D,50,98,A8,D6,D7,BC,57,A6,8D,F2,D1,E2,3A,F4,E4,3D,AD,E9,7C,CA,65,5C,D8,A8,A3,CB,6B,C5,16,D9,D8,60,4F,EC,2A,5E,BE,49,72,1D,F7,E8,1B,CF,75,21,53,A1,64,28,5B,8D,69,42,1A,5E,03,04,B8,F4,83,BE,84,CA,CF,79,D9,0C,00,B8,92,90,5C,D3,BA,DD,E2,56,7D,01,62,69,77,80,8B,0C,B6,3F,F0,85,35,42,59,8A,CB,2C,1A,BD,3C,57,A9,DB,EE,00,B5,0E,DB,B1,0A,80,6C,10,55,4D,AE,43,E3,13,65,0F,30,0E,7A,5B,6E,4C,4B,F6,FC,2A,66,2F,16,71,3C,56,FB,53,87,84,83,EF,CF,2E,36,FC,B4,CA,9F,74,46,06,CD,FA,44,E8,39,B8,DA,A1,53,5C,51,60,0C,5D,21,3B,F4,FF,B9,DB,5E,18,A4,27,B4,F0,21,59,17,53,1B,4B,D1,F7,64,61,33,6D,01,B3,EF,2A,0B,28,FE,59,37,78,77,C8,7E,F0,68,6B,F3,34,FB,C1,D1,A3,F7,46,A7,7F,98,07,82,41,78,34,B8,50,0E,EE,28,D6,2E,D8,36,7F,E2,24,8D,7A,A9,D6,A2,1B,A1,80,48,E9,68,37,39,DD,70,2F,33,E7,0C,7D,C1,F9,DA,46,A7,8C,55,03,DE,58,A3,FD,AA,D9,A0,C7,5E,6E,23,90,9D,0D,88,24,85,11,88,B0,EF,E4,43,FA,14,EC,1F,F8,BF,66,FA,9C,A2,75,AB,D7,31,CF,F4,58,2A,55,01,70,B8,21,BB,08,34,95,45,FB,B9,86,0E,2B,26,F2,84,DB,17,0D,CD,59,8B,19,93,4A,40,93,AC,1E,16,B1,1C,F3,4B,D9,62,7B,95,58,4D,CB,62,52,7B,EA,7F,72,F8,CF,AD,C5,31,6B,28,2B,C7,E1,F0,50,72,CD,F2,69,81,54,E3,BD,36,E1,CA,FC,77,DE,54,7C,E1,F9,D9,B0,AE,FF,85,2F,6D,17,C9,84,E9,4A,AD,EB,A7,94,D1,59,9B,FB,E6,0C,3F,FD,BB,51,33,D2,65,59,9F,35,F2,8E,5B,20,86,17,99,A2,31,6A,50,BD,EC,DD,14,9F,12,B4,25,22,9F,B1,C2,93,89,40,8A,43,11,61,95,8F,C0,32,69,74,CE,87,7C,87,38,DF,DD,77,2F,76,C4,12,4B,38,C8,8B,CE,E8,BB,E1,7E,66,82,63,80,D4,B8,B2,72,3D,F9,CB,0D,03,45,0A,80,46,9B,24,08,CE,A7,AB,1E,1C,46,86,FA,21,C7,93,B5,5F,C2,34,C8,67,B8,9E,60,09,56,93,9C,0C,6C,29,70,94,2C,05,C1,CF,C0,F5,3F,C8,0B,3A,5B,10,12,56,E5,80,16,07,46,50,F3,7F,33,72,9B,A1,86,12,C9,9D,41,09,61,B5,D2,20,A6,83,CB,41,52,E5,9D,4D,EB,1D,D9,69,6C,2D,30,BA,46,FD,B4,B4,FB,BD,C2,61,DD,18,0D,5B,B2,E6,A6,03,39,8D,12,1F,F8,8B,22,1F,7B,CC,9C,12,64,42,18,43,CA,79,05,1C,94,5F,03,74,EC,9B,55,7E,D6,C5,47,19,FF,B5,F2,2F,CD,1F,DF,2F,57,69,64,E3,57,D6,75,CA,43,27,B8,CC,F5,1F,AE,63,20,30,7B,F1,8D,07,58,64,0C,37,EE,86,4A,1A,9E,B2,AC,90,86,B3,55,5C,2A,33,53,01,12,1C,E0,65,9D,45,7A,82,C0,00,A5,FB,1E,0B,C6,DB,71,5A,BC,5A,21,C5,F0,26,F7,DB,37,4B,A2,57,3E,55,99,C8,B6,3D,5B,C5,26,E5,34,57,76,85,B2,04,94,F7,1C,59,59,DE,FE,22,94,C5,AE,9C,67,95,C6,01,EA,5D,58,5D,14,7F,A9,11,11,AD,26,86,C5,A1,B9,8C,84,E1,E5,66,15,DE,0D,67,5D,CE,C0,9A,8E,8A,D3,D7,B0,61,41,B4,B1,52,5B,D5,C1,EA,BF,65,9B,F2,21,68,C7,62,A0,88,35,D2,77,99,14,BF,59,F7,24,41,8F,C1,AA,B7,33,2E,C8,AE,2A,3D,EF,3C,9E,84,1F,14,4E,9C,8B,31,DB,9A,44,86,C8,2E,17,71,5E,90,B7,E0,FD,3B,E5,43,9B,0E,3D,46,FE,F1,B1,3D,06,47,C6,DC,A9,02,42,EF,4B,15,16,99,FD,CE,91,D7,D7,5E,A8,A2,FD,A9,52,B1,E2,7F,78,11,3A,AB,AB,A4,53,93,A6,7A,A1,EB,8E,83,35,76,90,FE,45,33,F6,C4,E9,D6,E0,C6,80,C1,0A,12,BF,08,E8,D6,FD,C4,3C,DD,3E,A8,02,A6,DD,6F,C5,8E,B4,53,19,25,72,CF,09,4C,53,44,5E,7C,C7,C6,8D,D4,24,D4,89,D4,73,50,53,91,C1,F4,78,3B,E2,86,00,A1,49,58,93,1D,7E,EF,A4,6D,CE,D5,31,BB,31,E8,A5,14,5E,22,E9,BD,EF,ED,68,A5,E0,B6,DD,EC,7F,EE,BC,75,54,AE,33,0B,F7,76,77,FE,81,39,03,29,4E,02,BB,C0,57,24,47,B1,FE,5D,C2,66,C4,18,78,50,CF,87,2C,F9,6E,3B,2B,B9,7B,C6,F2,AD,86,53,FF,A6,DC,D5,92,B4,54,91,B6,6E,FB,A3,B4,60,83,DF,56,2C,E6,17,1F,57,58,E6,96,9F,94,8A,27,62,4F,F5,EA,69,E0,69,7E,2D,12,D7,95,CE,E0,62,8E,12,A7,DF,A3,CB,7E,93,7D,4A,93,70,CF,E0,E2,4A,10,7A,72,9F,F9,64,3D,D9,68,3D,1D,DB,2D,AF,28,E4,DF,C8,70,89,B4,F1,94,4E,A5,64,ED,7F,02,DB,09,10,D2,04,AF,BD,71,3B,BC,E3,48,C4,24,5A,37,BF,B9,B3,AE,43,2C,C3,B7,52,51,AE,ED,89,E3,51,13,EE,ED,C8,A9,1F,FA,D8,48,9F,90,1C,BE,51,9B,B8,DE,31,19,24,DD,73,09,3B,AC,C4,D7,2D,30,89,B5,A2,6F,0B,60,FA,16,DE,8D,99,1D,62,A9,93,03,2A,56,A5,5F,EC,9B,B1,45,90,EB,48,F7,17,E8,97,7F,13,16,01,EB,77,B6,FF,E1,A2,1B,F3,F9,DF,E6,E5,A2,99,B0,B3,C0,49,16,BA,32,C2,AD,C3,18,3E,4A,AC,84,CF,DD,CE,58,02,10,2E,69,BE,4A,11,13,63,1B,A6,67,5D,F8,E3,7D,04,B3,7F,3A,1F,CB,31,9B,E5,34,EC,AC,7F,2F,65,CF,FF,10,CC,68,35,35,72,DB,72,AA,CF,6C,51,F0,13,32,61,4E,C8,4D,9B,92,B3,25,CE,30,A9,C1,EC,57,84,6B,42,DA,1F,63,98,06,03,30,E4,3A,1F,0A,D1,D7,2C,FC,5F,51,E3,0D,5B,1A,A1,39,B5,55,9E,CA,F9,FC,11,5B,F0,06,08,48,A4,71,8A,91,98,4A,4A,B2,CC,BD,1A,A6,C4,60,6E,D2,DB,99,0D,5F,BE,05,EE,64,9F,E7,5D,3A,51,CF,4C,D1,6D,6F,A7,F7,8B,5B,66,33,EB,F8,57,76,1F,A2,D8,86,E0,53,11,12,55,CC,41,18,04,B3,CC,92,97,20,E4,79,46,D1,EC,6E,79,B9,93,C0,BC,E6,FC,2B,22,1D,A3,FF,5C,78,EF,31,01,E9,F8,82,83,98,4D,81,4E,43,CA,DD,9E,A6,B4,BB,55,5F,99,CB,88,B8,72,C2,C1,C8,A0,D4,20,DC,20,3C,89,4D,FB,65,2C,89,F3,83,92,E2,D8,4D,A6,21,3F,03,61,33,2D,3E,8B,6F,7A,DC,BD,D9,17,C1,E9,8C,BE,35,FF,9F,B6,4F,2D,26,A3,F6,5F,B6,DA,30,69,15,FC,85,C5,3F,D2,E7,69,78,56,F1,8C,D0,A0,4D,28,69,0E,A9,F8,04,DF,C8,66,32,3B,C1,D8,03,22,C2,1B,91,48,D3,64,50,E0,73,EA,C5,7F,65,CD,B7,1A,48,22,CA,01,B0,73,0C,8F,4C,62,A8,75,39,EC,21,B5,87,6D,BD,C1,B7,BE,3D,09,B5,9A,9D,29,45,81,76,DD,D2,10,FE,B7,89,E2,AA,0B,00,BD,25,02,B3,21,24,22,0D,C1,CC,54,2D,09,E0,CC,72,5A,D7,FB,5E,B4,A7,20,4C,E2,34,23,81,1A,E4,CA,05,A0,C4,BA,14,9B,33,63,0A,EE,BC,C3,8B,2C,E0,CD,B8,E5,43,0B,21,1F,63,7E,22,34,8B,9D,42,2A,23,69,10,B0,C3,10,FC,27,40,7D,B3,4A,79,FA,54,AF,4E,44,57,5F,FF,6E,5D,18,98,83,26,FF,2C,16,E3,52,F8,3F,C0,F2,D4,61,37,41,67,EC,77,50,E8,52,61,EF,CB,5B,70,BE,8F,D6,1C,B5,AC,C7,18,C6,00,9C,58,38,40,03,27,08,BF,1C,2F,4F,1F,1B,0D,F7,D4,AC,73,39,89,00,85,B1,CB,91,F5,70,46,35,49,E9,C1,BB,40,60,A5,B5,A0,B9,15,6B,DA,09,2A,8D,D6,43,8D,F7,08,9E,11,44,08,84,FD,40,5F,97,8F,7D,E5,56,4A,FF,93,EC,98,8B,EC,65,3F,F4,03,E7,5D,03,74,D1,89,D7,77,85,41,A7,69,30,ED,5A,B8,E9,97,EE,27,4B,0E,0C,03,63,AD,59,9E,ED,17,EC,AD,3B,16,25,53,2D,AD,D7,D5,14,39,B8,22,EC,BE,BF,31,A9,B2,61,E0,0A,3E,8F,68,A1,D1,A9,CA,AF,E5,B7,EE,65,78,5B,9C,D9,55,F4,43,95,C4,85,BB,21,8D,1D,5A,4D,CF,75,37,DD,72,22,04,A5,92,0B,B7,61,D6,36,3D,8D,4F,1A,88,F4,BB,15,34,E8,FC,0C,C9,BE,27,2E,9C,1E,BC,F4,D4,71,21,71,27,0C,D2,6B,BC,7D,33,19,A3,B2,D2,AF,74,31,4F,07,DA,2D,49,7F,CD,82,CE,D6,5A,CA,0B,9D,2E,B8,BE,3A,41,30,F1,4B,B9,F7,FD,E8,83,C5,D0,27,CC,D0,81,E0,49,F2,3A,14,67,9B,36,62,24,5A,BA,40,AE,AD,6E,6C,DE,F5,76,03,59,7D,0A,E4,77,24,69,5C,D4,64,0A,33,36,16,CE,DE,4B,F3,3F,74,B4,B7,E9,88,A8,C5,7D,06,AE,23,30,19,C8,29,D8,F5,FB,F2,B2,D0,F3,85,4F,70,AA,1D,7D,99,78,D9,52,F0,60,B1,BD,D7,39,93,85,F0,A2,0D,5E,5E,96,7B,9A,38,8D,C1,3A,2B,E6,9A,96,77,F3,7F,23,E5,69,E9,CC,00,63,08,FE,49,0C,59,AC,4B,79,51,BD,A4,A5,5A,27,E4,71,FF,4D,D5,26,71,AE,F5,26,81,44,9F,95,0D,87,29,F7,B2,1C,06,38,07,ED,CA,E0,55,8E,DE,68,FF,37,75,8F,63,AB,60,D6,6F,F6,59,19,C9,67,3F,2C,DE,CD,BE,C4,84,63,5B,21,E5,D2,08,5B,08,DF,8A,8F,59,0E,87,61,59,B4,5A,79,54,66,C7,24,25,01,C9,29,50,C4,DC,64,DE,EB,EA,0E,BF,47,76,05,10,63,18,F5,33,D8,30,9B,9A,AC,BE,B6,2D,29,BC,EC,90,66,92,BF,EC,E9,3E,F6,00,54,E6,45,14,C0,C7,99,5B,75,86,E3,49,3E,92,71,85,13,F7,C4,9B,A5,15,CB,ED,06,86,45,F0,6C,91,F5,18,19,C7,27,AC,AC,42,1C,AE,8D,ED,30,0A,3B,3D,7B,DD,D8,80,BA,36,C9,C6,3B,D6,63,39,B5,92,57,B8,C6,D6,7F,F9,4B,EA,00,39,9D,D8,A2,E9,18,61,45,FD,93,93,2A,9C,8A,0E,88,60,BE,A5,50,CE,C3,AF,95,C6,18,FE,B3,F7,7A,9D,00,FF,1E,0B,D1,DF,00,B1,BF,FB,49,A8,D8,5E,AC,0F,20,42,8C,94,46,08,40,35,AC,82,C1,EA,1A,64,68,D0,70,36,F1,F2,08,F0,E7,69,F8,61,42,0C,F3,CE,C1,78,19,8C,78,08,6A,8E,B5,AA,5A,FB,0F,F6,F1,0C,70,A5,4E,D2,C5,D3,C3,71,56,A4,90,EE,33,2B,79,53,C8,6F,13,C4,00,7A,40,2D,45,7B,16,9B,00,88,24,44,B3,A5,D0,1B,61,8E,AF,07,B7,2D,31,06,EE,D2,37,B3,F3,0B,E7,D8,CE,94,9D,DC,67,84,7E,8D,E3,B9,9D,EB,33,0E,08,C8,A8,19,E4,BD,A0,B0,09,4C,68,D3,B7,92,02,86,66,DA,FF,2F,BF,D5,DA,59,0B,CE,36,6C,58,28,A2,46,FA,06,55,C8,BA,BB,FD,9E,9A,5E,6A,2F,6F,9A,F0,B9,52,65,12,75,3C,B8,A8,1D,56,F4,CB,B8,D2,80,BF,61,02,B5,5A,97,B7,B3,74,ED,92,A0,8A,29,F5,E5,F7,FD,FE,11,55,27,32,21,C8,37,C3,4F,EE,E1,C2,38,F2,29,20,A8,F0,9E,34,35,31,A2,B6,F2,16,58,1E,AE,D4,9F,C5,93,00,D2,B4,E9,AD,27,32,FB,1A,44,98,B2,61,03,72,D6,00,03,FA,00,02,20,65,85,3F,C2,77,8E,A1,FC,D7,81,6B,60,F4,ED,5B,7F,05,43,AB,F0,42,DD,15,EB,20,C6,9B,0A,F8,FF,CD,3E,AB,E6,CE,F3,90,57,F4,F3,C6,ED,57,C8,1D,6B,E3,31,74,5B,47,CB,5F,72,B6,62,F9,FB,6F,4A,AA,C7,A7,00,A0,77,A1,5E,9E,70,DD,A5,20,70,41,86,5B,CD,BC,E9,67,EF,D6,74,D0,C8,C3,BB,E2,AE,F8,01,11,71,C3,B2,98,22,8A,3E,11,4F,A6,51,11,62,E2,7D,81,0E,14,6B,B6,D7,2C,48,D0,E3,A3,B7,8F,0D,88,1D,02,3D,85,90,C6,6B,9D,31,6D,E1,5F,79,B6,0F,10,17,99,A0,9D,0D,6F,85,A4,00,97,78,60,78,2A,DA,6E,DD,EF,E3,D2,54,34,31,0B,89,41,AC,E2,8F,BE,4B,D2,75,77,6E,33,41,CC,A6,9F,85,9A,D8,09,BD,18,34,02,FE,86,77,F1,96,AF,4A,D3,30,0B,1E,05,52,B0,F3,9C,AC,05,26,2A,B0,09,B6,9B,29,22,D5,C2,F1,87,40,CE,EB,77,6E,9F,5F,8F,2C,C6,6A,D1,B8,71,0D,0F,BE,2B,35,AF,C4,B7,2E,F3,87,BF,91,A6,F6,FF,B9,C6,B0,AD,1B,1F,73,CC,E7,4E,91,78,49,51,1D,E1,37,4D,92,A9,3E,C0,9B,6B,19,56,F1,73,2A,92,84,BE,0A,DA,B8,CC,10,54,2C,6E,48,80,B2,2D,1E,22,0C,F4,08,43,0B,9C,4F,28,D8,FF,9B,AE,3A,3C,9E,F2,88,38,84,10,31,A6,EC,CB,0B,25,F5,36,BF,7D,09,3E,D0,66,3F,61,91,58,F7,62,92,0E,40,EE,4E,21,17,E1,18,45,23,94,EB,12,AA,40,DF,E2,B7,61,78,17,72,7C,23,65,8A,7C,DD,36,6E,B7,F4,E7,B3,BC,B1,85,49,F1,3A,78,41,6B,A8,CE,84,5C,1E,47,F3,02,DF,BB,01,1E,34,FA,5F,B2,C4,51,2E,08,45,FA,DC,A9,A1,36,53,4E,35,DD,22,C6,A4,49,FD,C4,EA,DE,D7,E3,37,F0,75,45,5E,3E,DF,AD,0E,DA,BD,FC,91,60,01,17,B8,C4,A2,91,AB,B5,C6,18,B0,8F,BA,05,DC,A0,B4,86,54,81,51,60,93,4F,90,6D,10,00,21,86,42,2F,78,65,59,A7,0D,0C,A4,35,D4,F6,F1,14,85,DC,9B,98,38,F3,F1,E5,D8,EC,0C,E2,F5,7D,0C,53,E1,78,F3,94,35,A3,36,83,D5,F0,6C,9B,8C,D7,43,A7,BE,CF,8F,AF,5C,EF,E4,4D,22,20,3B,69,46,4C,D4,E5,99,E9,2E,8F,AD,E8,82,8C,89,AF,CB,5D,54,17,D9,1C,79,74,A7,87,AE,36,9A,58,74,C2,A8,84,81,53,BA,86,48,AA,60,E9,C2,7F,80,20,0B,35,94,BB,B4,11,96,D2,41,65,C9,AD,01,05,E4,92,CD,BB,D1,8B,84,7C,F5,FF,90,04,D5,5A,17,D5,8E,ED,FE,F4,76,E2,C2,96,62,20,B0,09,B6,6A,8E,78,7B,63,AF,60,C7,56,01,9E,42,DB,19,A0,A3,77,48,EE,C6,27,26,43,A5,46,9F,C9,EA,08,B3,09,93,A2,75,25,34,2A,2B,FC,7B,04,9E,B7,80,C0,AC,43,4B,4A,6C,DB,C3,C4,0F,29,5E,65,69,FA,EE,D1,57,4F,5F,59,A4,3A,A6,A9,78,4C,84,E2,6F,E5,1D,55,C9,C9,67,38,F2,54,FB,E8,D1,93,6E,F4,52,DC,2F,B3,8A,74,31,4D,1C,F6,83,F5,55,E3,A6,BE,74,51,01,E0,9B,AD,A9,A0,F4,1A,E7,9B,A3,96,07,34,58,85,C9,D5,BD,BD,F6,B5,F6,08,C9,10,B2,44,F9,60,00,E4,0E,1F,BC,A8,E7,51,17,56,A9,01,B3,3F,31,C1,BC,52,B1,88,EB,4F,51,AD,0E,30,B6,FE,23,85,05,86,11,68,D8,6C,9A,09,AF,9E,B7,D4,7B,07,F0,35,12,51,A9,65,B1,F3,7C,37,D9,D4,C8,C1,3D,E7,34,DE,2B,22,53,0F,45,C2,2E,B6,3E,D4,F6,C7,05,A1,26,66,38,59,55,C0,3C,65,31,7A,34,AF,30,57,64,DC,22,61,EE,12,9D,0D,4A,AD,72,86,DC,B8,FD,D7,43,AA,95,16,C8,52,7B,70,D7,7C,DC,01,EC,0C,09,B4,A5,7E,BD,2A,D2,A1,98,B5,D1,56,A2,8E,CD,AF,83,0A,4B,FA,95,6D,D6,57,08,CC,60,F5,45,3B,D2,5B,D3,32,C3,1A,1A,3D,A3,EB,D2,19,DE,7C,F1,41,D9,62,40,AB,54,2E,8F,20,3B,45,DD,5E,D4,24,60,A4,3A,2A,EB,6E,06,FE,67,00,C2,D7,EB,29,06,80,CA,25,DD,64,D7,4B,E9,68,0F,9B,02,66,42,5C,2C,5E,CA,D2,84,CA,94,CB,B2,90,D5,A9,02,FC,31,A8,75,79,4F,F7,0B,04,D4,01,50,55,86,22,1D,7B,B1,5A,A1,9B,D7,7C,B6,B2,B5,DE,19,1C,72,B3,62,52,37,B2,BC,42,0C,21,35,7D,F8,E3,DE,D9,A3,4C,66,A8,A0,30,E3,14,2F,D4,9C,52,CC,69,ED,B6,83,B9,56,27,50,46,35,FA,F6,14,73,48,74,9B,84,F0,B9,56,5B,F9,93,13,C5,D7,AC,B0,DF,66,4D,EF,D0,76,8B,8C,1D,A1,36,0B,C4,B6,C0,8F,BC,74,AE,1E,82,CF,E0,22,10,0E,AF,B9,05,80,4F,0C,92,09,4E,FC,7D,80,22,9E,C3,67,08,A3,7B,50,A5,0E,BA,CA,E9,FC,C3,92,B7,B1,80,B4,0E,E4,A3,00,E1,92,A5,25,FC,04,91,79,F9,2E,A8,0A,B7,08,ED,C7,5B,51,3B,7B,0D,A6,2A,44,50,F1,5D,1C,EE,82,EF,7E,F9,C8,07,4C,F5,65,EA,6B,7E,31,6A,71,14,D7,A4,17,51,86,1F,7E,3E,56,C1,C8,E0,A1,A5,85,28,58,FC,31,07,F6,4F,F0,60,76,BE,12,02,89,5A,28,F8,2E,FB,BF,EC,D3,A2,95,32,44,B8,96,D9,B1,A1,E0,38,7F,EC,23,92,CC,AC,54,35,82,C0,B2,8C,56,2A,35,81,AE,3A,D2,3C,6F,43,A8,C3,54,8A,D4,41,FC,47,15,02,0E,83,A6,39,BE,5C,66,28,F6,60,57,49,B7,62,62,8B,A7,F3,F5,0D,33,D5,E9,DD,43,33,C2,5C,11,89,F3,19,AF,62,1A,97,49,0D,66,82,27,9E,C5,B0,8B,D2,11,51,1D,E1,8F,65,8D,E9,48,A4,D2,2E,E9,A2,9A,76,C8,48,3F,F3,C7,23,06,4D,AA,5E,5C,50,A3,A8,25,65,17,3F,42,F4,F7,4E,DA,1D,A8,DE,6E,98,80,8E,9A,C7,8B,F5,CB,54,B1,2E,F2,51,8A,62,F8,A9,5C,BD,11,73,4E,60,B3,65,4B,B7,A9,84,D1,1B,0B,71,E3,FD,D7,1B,4B,25,51,B2,5B,D5,7F,EE,B6,5F,BE,CA,E7,EA,A8,62,8F,D3,A7,55,CE,17,DA,24,03,2E,72,C6,0E,5A,69,BF,25,C7,9E,DD,19,94,9E,76,C1,FB,1D,FA,1F,E6,36,FD,56,4B,B6,29,98,DA,EF,F1,BC,E3,8F,AF,9E,EA,E0,88,3C,8F,AC,3A,A9,67,53,08,DF,69,E1,02,7F,DA,31,6E,AA,E8,5B,1A,1F,78,2D,E2,51,4A,82,09,16,5E,55,12,5F,CF,EC,6A,3D,AC,71,E9,BD,0D,7B,FE,CB,AC,EA,C4,3C,FB,A5,F5,C5,D7,E8,27,E3,01,7A,4E,A7,FA,8C,92,58,9A,7F,6B,44,C3,E6,45,3A,F2,48,7B,B7,03,3A,7A,0C,C1,AA,A4,16,13,28,71,4A,64,D5,39,CA,E6,6D,69,04,81,ED,C2,EB,1A,F1,7C,64,7F,BC,E1,40,B7,0B,AA,16,9F,DE,47,68,7E,BA,C4,11,25,30,D0,58,54,DC,73,0D,66,0E,3D,BC,F5,92,D2,1B,4E,D8,49,2C,F8,2F,C3,07,C8,ED,06,85,F7,7F,B1,F4,04,05,26,37,92,3F,8B,F4,8D,81,95,4B,39,04,34,D2,7F,3F,E1,EB,3D,74,DB,E6,31,35,92,70,07,10,42,C9,81,8C,F7,F5,F6,9A,A2,B8,DF,70,69,6E,F0,D2,E4,EF,B4,B5,BF,FF,5D,79,CE,7E,81,70,86,AF,8C,15,79,02,3C,92,97,59,7B,D1,57,54,DB,BA,43,5E,3B,9E,16,DF,FC,94,F4,49,B7,15,6E,AE,54,C2,AA,D8,22,5F,5B,F4,3A,E0,EE,54,CF,93,E4,75,9B,36,A6,D5,DD,20,B3,B7,99,51,1C,EA,19,98,BA,DC,28,FA,F2,A5,90,1B,50,D3,6F,D4,B8,A0,C8,59,D5,84,A3,EE,63,F1,D5,62,35,97,AD,33,4E,02,A5,C9,7E,4C,E8,C4,41,81,78,9F,D6,78,87,37,B3,FF,8E,F2,56,C6,E9,C4,DA,16,8C,FD,E8,F5,8F,05,E3,2C,A6,C4,D4,04,88,33,49,28,6E,24,9F,DA,D3,37,94,5A,A1,3F,A9,F6,F9,FE,EA,3C,25,17,61,6E,EF,DF,C8,EF,8F,D2,3B,85,21,78,87,8A,EE,75,81,9C,FF,41,CC,AF,EC,56,04,43,81,77,7E,13,65,DC,20,2F,F1,52,C3,D1,49,B1,28,67,21,94,CA,61,26,02,16,73,05,D8,1A,B9,0A,11,25,39,67,59,72,B1,8A,BE,38,9C,0C,0F,E6,49,EB,5E,CD,FE,81,35,44,E6,DB,55,F0,A8,4C,8C,C9,9D,CF,CC,BA,33,97,69,5D,01,DF,D2,3E,B6,A0,9D,73,69,84,9A,05,5A,31,2B,FF,95,0C,B8,5A,2F,F2,63,F8,0D,22,8E,58,E6,46,7F,0B,B0,68,B8,EA,DE,0F,01,C8,A2,BB,32,6F,47,58,C6,70,74,07,98,83,92,FC,96,31,F8,D9,1D,32,4B,AE,5A,69,1F,BD,E8,E1,99,9F,67,CE,C2,5E,27,A2,64,64,B8,46,EB,B3,1E,73,A3,09,CC,C5,23,0B,C5,E7,3D,7B,58,B4,05,F1,42,87,2C,D4,26,BD,ED,A7,E1,AA,5A,20,9D,83,1F,70,9D,01,43,60,E4,A0,72,68,77,B6,44,70,8C,22,41,64,AC,89,D9,A2,3B,CD,3A,35,06,FF,25,36,8E,99,E9,DC,CB,41,35,CE,95,BB,5D,5A,42,EF,95,57,57,0A,93,56,D4,1C,4F,D2,BA,35,6D,70,2F,80,DE,A0,D1,E0,CB,B1,76,E3,BD,A3,9F,7D,25,48,A5,FB,83,4E,26,37,90,11,7E,B3,FB,F5,F2,10,13,87,7E,37,A8,D8,26,CC,4A,32,ED,59,1A,B8,86,74,C3,36,54,AB,A3,98,88,0D,0A,A7,FA,FB,D7,9D,0A,D2,40,17,CB,AD,4E,BB,35,16,6B,89,D3,03,A4,B8,EA,EC,A5,82,2A,03,60,FF,F8,FD,25,7A,39,7E,66,03,2B,47,63,E6,4A,D9,A6,C1,D5,11,91,8C,A8,96,81,7C,AC,A7,D0,25,04,33,98,BD,F0,89,A6,41,F8,F2,47,5A,40,25,5E,4D,E7,BA,27,3D,FA,85,D8,90,8E,74,2E,10,8F,54,98,9F,FD,B6,7B,36,8F,2A,85,91,99,02,AA,D1,73,42,96,E8,52,12,87,38,F2,BD,F0,D6,8D,4B,E1,2D,4B,F8,FC,09,91,C4,43,CC,56,F3,69,4B,F0,F4,E4,C5,0E,B2,62,84,2E,2A,2D,CC,46,02,C2,E0,26,96,2D,B8,E5,3B,C0,E3,6E,5C,2E,53,A2,3A,0C,6F,33,A2,37,C9,32,72,80,CB,8A,FB,42,F3,E4,FA,1C,76,86,AA,EB,55,43,57,01,45,53,F0,8C,6E,66,5A,BF,1D,68,83,A2,32,50,2E,C1,47,FD,83,DF,31,B5,7B,F7,96,AA,93,A7,5A,1B,9A,44,70,9C,04,B9,91,F6,D8,0B,BB,C4,A2,BB,90,6F,13,1C,38,68,E9,7E,13,7C,87,44,D3,8D,5C,95,E4,77,BE,08,43,6A,36,6C,CE,C2,07,CF,CC,7D,F1,03,2D,71,A6,11,56,9F,33,79,5D,D9,12,89,4C,56,D9,B2,E2,D3,0E,89,32,BE,BF,B8,20,3C,FB,BE,AD,D2,6C,BE,1F,7A,30,82,92,2E,A3,6F,B3,3C,C4,C9,30,EB,96,14,2F,91,8D,8C,61,8B,6F,2E,2A,62,2E,08,BE,97,07,86,A7,82,CC,B8,D1,7C,1E,AE,2D,FF,18,C6,EF,C3,F6,6B,E3,3C,92,37,78,DD,F0,22,FE,0A,FC,0A,74,99,25,0A,AC,E3,23,B9,91,2F,E2,60,51,EA,BF,44,D4,FC,6C,C0,23,42,F9,5E,E9,21,B7,C1,DD,81,24,00,71,10,C6,94,1C,05,0A,DF,43,67,E0,EB,4B,F2,33,64,26,E2,E2,7C,F6,7C,2B,3D,9C,CB,C7,FE,42,34,4E,01,6D,D5,86,C5,7D,B7,45,82,31,56,F0,1A,D4,6D,E9,F3,6F,C0,22,04,77,16,69,76,98,3B,7D,E5,CD,66,BE,C1,B6,85,49,36,F2,63,2E,37,62,E2,60,2D,87,92,EA,F3,6E,F2,BF,94,26,FD,67,51,84,69,EA,21,C9,FD,65,5A,12,CD,8B,69,35,C0,7C,57,FC,56,FC,87,EA,E5,39,91,AE,6B,B1,69,C7,DF,F6,04,FE,5D,05,FC,88,E4,67,0E,EE,58,37,AF,79,40,28,F4,E3,6B,72,4C,72,02,D0,C3,42,9B,19,9B,68,7C,15,5F,D8,C8,61,ED,00,6E,34,25,B8,BE,BF,60,02,41,1A,25,EB,04,A1,35,E4,63,AA,AF,7B,9D,7E,D2,AC,10,17,B0,75,1A,83,FD,76,F8,22,17,77,0D,FF,FB,AA,A9,EA,6E,0B,ED,F5,75,72,DE,F7,1C,2B,A0,D9,63,64,A8,C0,17,AD,BB,7E,6B,62,16,ED,8F,8D,75,A6,DD,F2,05,71,5F,CD,E0,48,B4,F5,91,78,4C,E8,DA,11,2E,B1,9D,7D,A3,90,11,2E,C5,2E,9C,D6,62,56,4D,ED,F1,61,28,A0,18,CC,CD,E3,9B,97,CD,6D,90,0D,4D,EB,BC,C6,EF,45,28,CE,4C,87,E1,FF,B7,E9,EC,0C,DB,2D,48,21,79,11,81,1D,E9,E7,2A,C2,5F,36,17,92,7E,F0,21,9B,D7,4B,35,3D,00,F9,6C,8F,E0,29,14,99,10,7E,D1,C7,E6,7E,61,24,48,19,0A,65,91,EB,E4,A0,2F,64,EA,3F,4A,35,88,B6,B7,83,6E,7F,5D,66,70,B5,1A,16,64,85,68,5B,D5,1C,1B,AC,89,A2,35,2D,E0,37,D2,5A,3C,12,14,94,00,24,73,6A,B8,78,E6,9F,22,F9,EB,FD,20,15,F5,A9,3B,EF,60,95,FF,1F,D2,7F,78,FF,D8,B4,AB,9D,A2,B7,0E,CA,E4,B4,CC,AF,DF,E6,62,16,71,EA,BC,22,65,E5,63,38,37,C8,AD,20,61,B0,7B,F2,B0,CD,E7,CD,16,9A,AF,86,9B,50,95,06,80,08,3C,2C,75,A3,54,A9,2A,29,08,9D,71,94,60,6A,F5,5D,AF,23,95,B4,BD,E7,B5,B1,F8,F7,94,7E,D1,41,50,B6,0B,34,80,D3,DA,7D,A0,2C,58,75,68,3B,A6,74,6B,EB,6B,0F,B2,92,2C,F6,8E,13,97,73,CE,31,EB,69,F1,D6,02,69,D1,DA,A3,AC,84,36,F8,CC,82,36,58,BC,EB,52,1D,D5,EB,E3,BB,2D,69,14,9A,D2,E4,47,26,D3,77,56,6A,D4,A2,8C,A4,3E,79,5E,2F,C7,13,C4,20,BE,02,E1,90,82,37,C4,58,A6,92,AE,37,AB,F5,E2,5C,0B,E8,85,A5,B9,5F,28,13,BD,BB,B8,30,0D,99,5C,2B,5D,95,7A,58,B1,34,EE,B4,58,38,8B,67,70,BA,CF,4C,F2,8A,87,8A,0E,35,83,55,4D,A4,34,BE,5D,08,5C,E2,3E,C0,A0,D8,CC,AF,6F,D5,98,29,2C,FA,F9,2B,0A,B0,E2,30,8F,6D,F7,D3,95,81,78,24,E1,1E,29,0F,BD,42,11,C7,79,9C,B6,D6,AB,86,E4,1D,8E,5E,17,1F,2E,38,16,84,29,0D,42,6D,DA,2F,AB,73,04,70,8F,C5,17,4B,05,26,8C,77,00,55,7C,1C,BC,9F,56,EC,2C,69,7C,B2,7B,A0,46,8E,F7,3D,1F,A7,FE,FB,2D,A9,94,72,28,4D,39,D9,86,B4,76,5B,0F,CB,D8,09,B4,2B,F4,13,2D,F6,B3,A3,87,2B,90,D6,C0,A2,09,14,DB,61,82,F1,22,0D,DC,F4,FC,FE,FE,9A,36,08,05,A6,EE,C6,0B,70,34,B9,92,22,BB,6E,9B,72,98,DB,03,E7,E5,22,C1,96,05,59,DD,1D,2E,B4,24,3D,3B,93,B1,6B,F4,5D,B4,00,A1,4C,AF,45,D9,12,07,22,01,68,9E,84,98,8F,64,33,A8,31,8F,96,74,03,B8,BA,C1,E9,B8,CA,B9,2A,8C,57,73,14,12,35,DE,56,E7,F1,27,98,49,3C,95,91,0F,52,8B,F7,BC,65,11,1C,B0,C9,88,D0,A6,72,7B,E1,E1,7F,85,F5,03,4A,86,77,66,FC,D8,EB,B3,01,2B,37,97,4F,16,A6,34,B9,DD,A5,47,7B,DE,D0,37,B9,0A,52,4C,E9,2F,30,F2,FE,78,E7,E6,27,5E,57,FB,F3,1A,90,47,20,B1,FD,E7,B2,19,34,0B,B6,87,F3,E3,45,2C,6B,3F,26,E6,59,97,14,50,0F,D0,2F,A2,E0,0A,85,48,D6,E5,27,3B,C3,35,A7,18,A0,07,65,22,C0,D7,4C,15,14,F3,B2,EE,C1,B1,7D,2D,DE,05,45,32,94,05,88,6C,FA,D1,F9,60,D4,07,3B,64,5C,FA,62,AC,5E,A7,E0,4A,FB,C1,D6,05,F8,3F,2F,D9,C4,F2,E9,09,53,18,BC,AB,19,53,A7,85,24,91,93,91,08,69,CE,FF,9C,E3,55,CF,9B,CD,B8,4D,00,30,B1,DD,3C,8C,5A,9B,96,82,D4,9F,A4,86,E5,6A,FF,9F,C0,F0,5B,1F,0D,63,8B,AC,E2,48,65,1E,FD,43,78,19,6D,3B,0E,AB,A7,5A,78,FF,63,01,9F,5F,12,6B,D5,54,0F,A3,92,87,24,98,59,1F,48,82,20,C7,A3,5C,79,5F,B4,E6,AA,35,71,68,5B,E3,9D,DF,FC,E4,8D,CD,0F,B3,90,F2,69,DA,40,F1,13,DD,75,DA,5E,30,A9,56,BF,0F,76,93,B6,5D,88,4B,47,9E,E8,09,AF,B6,41,D5,38,87,3D,72,CB,0B,B1,13,A1,4F,22,E3,2C,3A,C2,96,4C,51,88,49,01,77,F7,5C,5B,5D,4E,18,AF,5F,3E,37,B9,1A,88,F3,FA,36,FE,77,11,80,A6,33,4C,E6,D7,D0,16,A5,90,59,5F,BC,21,38,F1,E6,C5,54,2F,18,88,E2,26,9A,1B,C3,62,C0,B5,B7,46,79,5F,4C,2D,4A,C7,20,42,13,4D,79,F3,85,C2,B8,18,D3,69,63,ED,B2,1E,AF,43,6D,CD,8D,CA,30,DD,13,D1,C6,C8,D0,25,0A,BE,F5,01,45,5B,97,5C,60,48,F9,FC,C0,59,A0,BA,88,D3,A1,B4,26,C3,00,24,CF,7D,1E,8B,BE,D4,25,7D,E0,B9,53,3E,85,4B,8B,29,F3,28,9C,CD,66,79,16,30,7E,6E,91,1C,55,77,11,EE,09,7F,3C,84,5E,1D,1D,05,C9,78,A9,67,5A,B0,7A,A5,4B,75,DD,A3,BF,8E,BE,F5,BF,87,CE,41,FC,48,EB,7C,8C,70,46,D0,39,E7,0F,7C,80,76,59,02,94,E1,A2,5E,99,9B,90,93,B3,C1,83,B0,7B,C6,68,DD,AE,FB,45,D9,E3,29,E4,19,50,32,F4,5A,19,E2,74,51,E2,8C,91,5A,A9,01,2F,68,C9,2E,F3,1F,26,46,75,F9,A6,F2,CE,58,36,3B,2E,A0,8F,15,40,14,85,67,43,B2,26,01,60,53,39,DC,BB,90,E0,CB,1E,86,F9,13,E3,AE,EA,30,F7,45,87,DE,63,85,1C,B6,EA,FE,0B,E0,EC,10,69,25,6D,C1,42,92,7C,EC,D5,62,9E,D0,7F,53,12,EA,AD,AE,39,50,E9,E6,FE,7E,C0,B8,62,74,76,EC,BF,26,D6,15,39,01,B0,61,AC,88,EA,55,93,E2,FC,77,96,DF,61,90,29,E6,2F,EF,AD,F4,35,1F,94,8B,B7,59,89,C7,8B,1D,7C,DF,47,6F,5F,27,44,6E,1A,CC,0E,0E,09,D9,6E,95,8C,94,86,52,58,BF,E4,E2,65,61,74,3F,82,E6,CA,79,F4,A7,EF,67,B0,8F,C8,EE,08,71,C7,D3,0A,96,D7,A9,05,1A,68,8C,0C,E0,CF,D9,9B,3F,31,70,31,FD,63,D7,6A,AC,9F,1B,CF,1B,8C,2D,15,A1,CF,44,C4,5F,DB,EC,85,09,FD,3B,D6,BF,8C,77,1E,3A,3C,8E,32,8B,BD,FE,02,15,7C,FA,93,9F,6A,A8,69,A4,A7,C6,58,D0,00,1B,E5,86,5C,95,FF,FE,5A,AB,5C,C4,27,D2,4D,FC,CA,73,87,A8,31,0F,F9,F3,D9,E8,3D,21,A2,6C,E9,03,31,84,3D,E9,AB,7C,74,31,CD,9E,E5,3D,27,95,D5,93,AA,2D,E2,6B,69,02,E0,18,7F,E6,64,53,51,09,11,FD,6C,16,08,3D,00,EA,5A,65,F3,17,A6,94,E6,CC,FE,B3,F2,F1,B5,B6,A8,72,76,15,EC,F0,16,B8,11,83,09,C9,37,B5,B5,F2,D9,0E,EA,42,E7,99,24,C4,B2,37,D4,98,6E,54,7E,AF,D7,6F,14,CB,6D,E2,23,B5,D9,03,3F,40,6C,1B,B5,45,40,BC,56,3A,C3,DD,F1,C1,72,2F,3E,7D,47,CE,98,27,D0,BA,00,95,2B,49,95,48,7D,78,B9,8C,A9,96,A3,1B,C8,81,C8,C6,C3,15,A7,E1,DF,D7,9C,57,7E,5C,42,6C,5E,F2,CF,96,20,9D,59,31,29,1F,60,AE,72,D7,C3,5F,3C,66,86,D0,F8,22,98,E9,60,7E,8C,C8,A6,BF,4B,44,7F,DD,0B,B6,04,1C,17,13,2F,B4,BD,F2,2B,38,6A,53,4B,E1,DF,43,57,8B,93,8D,B0,E9,BA,E9,FF,C0,37,2C,9D,7E,CD,E7,A5,41,63,83,09,FF,E1,AF,E3,2E,50,F8,9C,0F,91,39,43,5B,60,A7,F1,CD,8D,71,38,F5,E3,5D,C4,0D,5A,40,6D,56,63,82,25,B1,51,C9,EE,C0,FC,32,AE,E6,D1,6E,62,D5,E0,45,55,46,D5,A4,D2,39,89,BC,F4,A0,17,06,E9,41,5D,96,51,7E,16,BC,D8,45,81,C5,E6,C2,AD,FB,0E,63,B8,0F,61,2A,93,B9,C6,46,56,DD,5B,D6,C2,21,A4,3D,6C,3F,D3,EC,32,16,F1,7F,C8,DA,14,80,7E,A6,89,ED,5B,D9,80,FA,DE,B2,0A,07,E1,D3,DD,E8,68,D1,4F,D7,A6,51,70,AC,A6,E2,E1,B5,39,80,C1,62,E8,73,CC,15,23,A3,D2,F9,18,71,AA,97,3F,11,58,64,70,7B,34,CD,4D,82,E9,BE,81,D7,0E,8C,36,62,2A,01,69,34,A8,EC,F9,80,B7,17,D9,10,F1,4A,D5,9E,21,26,A4,C6,36,D7,CD,AC,9B,54,2D,5B,A9,7A,2A,02,F3,59,17,F0,80,39,02,F0,7B,31,80,F3,77,D6,18,82,04,EA,68,FF,51,68,2E,C1,ED,E9,38,D4,DF,CD,F6,7D,43,76,AA,DC,D5,EC,E1,7D,2B,8F,F5,7B,03,55,6E,31,02,96,49,E4,FB,9A,55,93,F2,96,5C,01,1D,B3,35,A0,00,FF,2F,3E,77,95,73,46,A2,0F,93,81,BD,94,68,C7,6C,63,2F,A2,23,5C,3C,84,CE,68,5E,E3,02,62,2D,40,48,87,B8,7E,C4,19,2A,18,89,9E,FA,22,C4,99,70,AA,41,AA,A6,A4,B8,40,03,2A,AA,4F,47,45,E8,21,D7,63,CF,86,D3,80,3A,17,65,50,15,37,F0,EE,1C,F2,14,41,58,77,38,83,5B,86,7E,98,F6,D3,D9,10,59,57,83,33,EC,70,89,64,49,EC,42,BE,9E,1F,01,26,B1,79,A3,5F,23,14,09,0B,0B,23,64,D9,8B,2F,CC,7C,A9,B0,68,6C,D1,1C,C1,B9,5B,F6,B6,C5,F2,C9,8E,D6,0B,E7,C5,EE,BF,F9,6D,F1,AB,CF,0C,74,6F,CC,56,A3,75,27,B6,CB,93,B6,F8,60,A4,A7,4E,31,01,48,0F,15,F2,6F,EC,B1,28,79,A7,D0,0B,97,0F,D5,53,AD,5B,1E,90,6C,59,C7,4B,20,BD,D5,06,41,49,B7,34,B2,AD,2B,65,80,D7,A0,7A,3B,9F,A7,AB,A1,B1,A0,69,E9,61,26,3D,E9,83,F7,1A,B4,6C,EE,00,15,0F,9C,43,28,FA,24,AB,27,EE,E3,BF,A2,FE,F7,FE,0D,88,AC,B7,49,F7,BE,7C,F3,8C,CA,F5,68,58,D0,E2,2E,82,6A,8D,9D,C5,8D,D2,9A,5D,C3,D8,1A,FD,CC,5D,0E,B2,36,BB,4F,EC,49,EC,DE,66,88,73,47,65,7D,1C,0F,31,4D,8F,34,DA,A5,75,BD,37,6E,97,AF,2D,74,FB,8D,34,6E,81,09,88,F8,0D,67,D2,C5,17,B8,62,F3,CB,28,CF,FA,FC,AF,96,51,63,D5,5A,F7,E8,28,C8,EC,96,3D,09,A6,39,C4,9F,4A,FA,4A,BE,17,15,5C,5C,14,5F,5F,04,10,99,B4,46,4B,49,2C,5A,DB,D7,CB,C2,4B,98,26,84,20,AA,B8,65,EE,03,55,6F,49,D2,4C,B1,7A,72,10,F0,60,E6,1C,BF,D1,AF,C5,6F,03,B8,DE,D4,F4,5F,51,0C,15,CF,C9,D1,ED,D8,69,6B,C7,EB,BE,F4,6B,8D,4D,F7,03,82,43,B4,BF,01,83,5D,90,2E,E1,B5,59,1D,50,38,23,26,6F,FE,7E,1B,A7,C9,BF,E7,AF,E6,49,DE,86,DE,CB,F8,22,AE,43,62,C0,BD,1F,26,64,0A,C4,49,E8,48,6A,60,7B,A4,3A,E6,23,4B,DB,9F,E0,54,38,F4,76,70,13,9B,AC,93,09,5F,F0,45,D3,18,61,B2,04,84,A8,2E,71,7C,E8,7E,3F,26,C3,C5,A6,EF,42,21,20,C3,AE,2A,41,4E,D3,46,A7,EE,AF,BD,53,D9,EB,DB,C8,11,2D,17,26,0C,B5,5D,F1,EF,2D,E5,81,29,3D,6C,C5,C8,26,0D,ED,1E,84,E9,B8,9A,0F,71,EA,9A,DF,25,9F,63,3E,F7,DC,36,26,4C,F8,8E,68,FA,3A,B8,DA,0A,71,60,EF,7A,E2,E5,6C,99,0A,86,5F,74,1E,6C,38,59,EC,EB,08,1F,0F,20,A0,38,82,C4,F8,97,DA,DE,57,6F,DE,2D,93,75,3F,36,72,9A,79,51,2B,AE,1A,B0,D1,7F,AD,79,53,08,A7,C2,6D,C5,FE,56,9E,FA,17,F6,44,71,0D,6D,A8,FE,BF,34,1C,0B,C3,DD,6C,8B,9D,C3,FD,45,3E,D4,2B,B6,F3,4A,D5,6E,E2,13,1F,EE,49,8A,92,E2,ED,EE,43,ED,C5,71,60,75,06,B7,8E,5A,51,67,FE,9A,E8,58,9A,94,B6,3B,53,2D,4A,7A,B7,F1,B8,F8,C5,32,05,99,C9,C4,88,7E,79,1B,E3,2D,23,79,2C,FD,94,36,F4,6E,F2,E0,58,16,F5,11,D2,8F,9F,5E,2E,18,C7,FC,DF,BE,87,67,9A,02,BE,3E,F9,70,F0,A4,40,97,4E,FE,CD,AC,76,B0,8A,27,32,B4,A8,29,99,84,8D,DF,36,11,3A,AF,22,99,72,53,2A,B6,D0,F1,E0,94,A7,37,9E,A8,54,3D,85,BD,27,8D,29,85,74,65,E3,5A,BC,24,B0,7C,B5,AE,0D,B0,A1,D2,F3,73,BF,74,61,28,7E,76,7A,12,60,96,75,5A,5F,2C,F1,F3,42,7B,29,28,BB,28,0A,1F,85,8C,D5,E9,9D,20,32,E0,82,CC,A4,F1,90,16,49,8F,7D,9A,8B,47,37,C2,36,1F,F0,4B,FB,47,8B,4F,DA,EF,78,82,1F,B6,9D,84,92,ED,B7,6D,D5,DB,86,A5,5F,08,F9,BD,0B,7E,AF,2E,F6,1C,37,3C,5A,AE,7C,25,A2,1D,DB,B5,39,46,07,78,66,24,33,C2,98,6E,EE,DD,CC,E4,A5,4A,44,8D,34,51,FE,B6,41,87,CA,BD,B1,D4,64,C0,A7,40,AD,03,26,A7,26,62,95,21,07,6D,E0,8F,07,E9,F6,32,32,9F,5B,AC,77,3F,C5,A6,D9,D3,2F,9D,59,AE,9F,B4,FB,53,84,DC,BE,4C,24,65,64,85,00,F8,1D,76,83,D0,3A,1B,E6,E0,3D,22,F8,64,FD,31,BE,79,C7,55,76,BF,CE,44,1B,FB,EC,59,AA,13,62,63,B3,DE,E3,D0,32,3F,22,2A,B8,FB,15,A5,F1,EE,B5,9A,D7,79,97,C2,4D,F9,83,AE,6C,59,7A,A0,D1,19,FB,90,7D,80,4F,F3,92,FB,92,1F,26,99,25,2C,B8,A1,5B,2D,EB,F5,BD,D9,65,9C,80,C9,10,B3,0F,9C,A6,60,77,1E,1F,B3,10,2D,2E,66,EC,70,45,27,AE,A9,92,1D,98,A6,78,72,93,8C,B4,F9,71,39,76,AF,C0,57,40,77,A3,5C,88,95,BB,71,23,A0,F9,24,CE,B1,C8,6C,8E,58,30,75,64,9F,8F,BF,15,31,EC,C5,6C,2D,19,F0,B4,DE,92,50,3E,E5,5A,F0,32,CE,F5,57,F4,1A,3B,DC,0B,E2,4A,FA,71,37,F3,2F,E1,D0,7C,CE,FA,77,A9,22,2E,23,0B,08,E6,2D,4A,DC,BD,B5,DD,8A,2C,14,49,F2,7B,5B,44,B6,EF,F1,AD,D0,3D,D4,20,68,17,3C,12,91,AF,D3,9A,35,FC,29,D5,62,8B,31,E2,EE,79,B5,5A,6D,CD,C0,08,3F,FF,97,C0,F1,DB,06,00,DB,2B,D1,42,0D,4A,DD,75,06,38,68,4A,FC,0B,13,24,44,5C,31,70,51,DB,14,A0,DF,04,FE,DA,CD,E5,52,63,11,B1,6F,52,67,EB,17,D7,D0,24,AF,3C,B3,68,58,59,BA,2A,6F,14,9F,18,A9,AE,2F,E4,6D,07,34,BC,7C,6C,3E,00,07,3B,B6,4C,4A,17,14,97,5B,B1,2D,15,74,BD,64,6D,DE,D4,75,01,C6,4F,ED,E9,66,05,63,AB,FC,FD,0D,51,90,0F,AB,90,41,99,97,05,FF,BC,ED,65,DF,12,41,9E,6E,21,BB,0B,C9,4B,FB,1C,C4,6C,41,CF,DF,A9,AA,13,F0,FD,75,56,19,FF,9B,AF,35,02,02,EF,E3,B8,0B,22,59,10,E5,60,B9,61,B3,63,C6,3F,FF,9C,C7,43,CC,B0,8B,AF,C4,38,AB,7E,41,C4,ED,31,BF,52,FD,20,F3,FA,CE,77,FF,4A,3C,4D,8A,51,B4,5F,DA,54,E2,A4,D2,02,D1,D5,85,88,AE,CB,E0,00,82,96,31,73,2F,E6,E8,1C,1F,40,99,DB,BC,D0,53,E5,AB,52,EA,FB,60,0F,B1,CD,6F,56,03,AB,01,FB,A2,6E,BA,72,6E,F9,7B,81,12,35,CC,89,EA,2E,7D,4B,E9,25,06,4D,7D,30,33,6A,AF,E0,29,61,4D,82,65,81,DB,8C,6B,67,AE,3C,4B,8F,1C,24,ED,E0,8D,A8,81,1E,96,96,F8,82,14,65,CA,CD,5D,29,E9,0C,3F,C3,8F,42,97,C5,06,77,D6,95,3D,04,BF,39,78,A7,10,8A,44,B8,2A,EC,92,57,31,3D,7C,CB,55,F2,26,B6,24,F7,2A,B9,B0,94,BF,37,38,90,73,A1,DC,74,74,B4,D2,3A,34,3E,E1,A3,ED,E3,66,BC,96,C8,DF,00,28,86,07,76,D6,E6,2E,F5,1C,BF,17,09,05,3D,E1,75,3E,71,2E,73,6C,C0,99,C5,17,25,4D,43,CB,87,10,47,6E,D4,75,89,09,AF,A5,D9,BE,1B,49,89,53,81,6C,75,15,8D,4A,89,A9,5E,09,0C,CE,0F,81,DE,DB,A9,81,37,5A,90,36,D8,A0,F3,84,01,29,94,EA,A1,0F,8A,90,0B,23,98,E2,91,05,55,EC,9E,6F,58,A5,23,D3,58,2D,07,D7,21,12,99,08,DE,3E,44,ED,FB,DD,B0,F4,92,9C,7A,AC,B5,C6,D5,1B,D5,DC,F2,26,7D,95,33,4D,E5,E6,AD,32,6C,B7,7C,E5,32,8C,EC,76,25,FD,BA,F3,5D,0A,20,04,38,51,DA,9A,1F,36,8A,51,47,D9,40,0F,CE,0E,A8,63,DC,76,EC,A0,EC,94,DB,88,FB,10,70,F7,68,47,39,6A,2C,19,30,C2,A7,B4,8A,F3,8B,CE,C2,57,FB,7F,DD,90,BF,65,26,64,D3,06,60,FD,D4,99,92,23,1D,01,5D,C8,71,42,62,A4,22,7E,4E,8D,80,9F,A1,43,19,38,4E,8D,AF,10,52,CA,22,A1,A3,E4,AD,3C,D0,73,3D,2E,6F,F5,38,CB,E5,AD,20,78,CE,89,F4,05,15,63,6D,57,CC,72,97,7A,A2,F3,8F,DC,55,B1,31,A9,AA,2B,48,2C,34,83,62,41,FC,EA,B5,27,A1,81,A9,1A,C4,DA,5C,61,50,98,E4,B1,88,C5,A6,B2,96,31,07,5A,5B,48,5A,54,2A,7B,02,4D,E5,89,7F,95,96,05,DA,7B,EE,81,41,CB,E5,32,69,CD,3F,38,F6,97,1E,E7,47,15,81,2D,95,91,FC,C2,32,EC,1D,AB,D1,B1,58,65,7A,9D,A8,B0,2F,19,38,25,4D,E6,F4,B3,5A,EE,5E,F0,51,46,53,27,50,E0,AC,A2,FE,DC,33,B0,9F,F3,49,14,08,4E,9F,41,5E,29,60,D6,2F,06,B0,3C,46,F9,E4,96,71,0D,D3,5F,AD,28,84,EA,B1,44,EE,E3,6F,17,D5,85,14,7A,DE,B3,DC,0C,56,F0,34,3C,5D,5E,41,30,59,26,AD,3B,51,9D,5A,9E,AC,EF,03,67,C2,06,33,0F,42,77,85,68,6E,A2,13,54,48,90,9E,CB,AD,CB,1D,EC,62,DC,18,1B,B4,D1,7F,4A,06,C4,F9,C3,A9,68,EC,1F,9E,6A,D6,17,51,B0,0F,3C,11,B1,E9,AF,7D,AF,4F,69,5E,0F,F2,F7,C1,93,C3,53,C7,49,69,B7,67,DA,A0,C5,7E,C8,AE,01,0A,0E,AD,3E,22,43,F5,EF,37,DF,05,98,FC,88,53,49,A6,25,A0,39,48,B6,2E,3E,46,78,82,9F,47,A9,33,34,B7,08,9B,FA,E5,D5,86,82,BB,69,8A,CE,B8,51,36,06,67,FE,3A,58,5F,F7,69,0E,3A,09,7D,9F,99,26,70,F6,34,65,E0,B9,12,58,76,07,59,86,AD,D6,14,94,0D,D9,2F,BA,E4,30,10,02,9E,77,5F,89,59,36,28,D0,63,F1,01,D6,10,21,98,E8,E5,47,AA,F3,47,20,21,74,35,92,E9,5D,DA,58,BB,46,16,6C,E6,18,10,AB,61,0F,48,AA,15,BF,36,18,29,F6,7D,87,9B,F7,A5,78,BC,2A,13,DC,40,E9,48,6E,1A,9A,A9,2E,74,98 -roundConstants = 59,04,0F,95,A8,62,EF,07,40,70,87,3B,AB,23,73,3B,2D,01,E3,5B,A7,79,8B,0B,FC,9E,64,EE,D6,D0,B8,60,9E,1D,7D,81,66,21,71,C1,46,9A,DE,26,65,ED,09,C9,E5,2B,29,0C,D4,77,7F,D1,D5,73,67,D7,7F,65,77,6E,E7,36,39,8E,9D,BC,19,AA,43,E6,90,E7,DB,07,94,B3,EB,D4,29,5A,40,95,8C,00,57,90,E6,8E,21,A6,34,43,BC,92,6F,F2,97,FF,38,B7,D6,A4,3E,8B,12,A5,F9,70,8A,EA,F2,12,72,17,28,15,FD,72,83,1D,77,18,91,59,52,46,97,7E,3D,29,C3,4C,C2,E2,B5,73,9B,72,81,3E,00,8C,85,2E,93,63,1B,C6,88,CB,EB,26,62,B4,E0,88,11,4C,84,D8,8B,BD,88,C9,90,38,64,BF,C5,B4,A4,97,B7,7E,18,61,F8,82,7D,6D,C8,2D,C0,B3,4C,A7,2C,00,02,D5,B9,75,BD,34,28,B3,A1,5F,67,FF,46,8F,9E,9C,4E,7A,73,74,CC,63,FE,6C,99,F1,3E,1F,34,6D,03,04,B4,1F,0D,EC,E5,23,90,A5,49,0E,E1,6C,78,52,D0,4C,2A,DA,2F,0A,77,8F,D8,74,F6,EE,3E,AA,57,26,5A,D8,0C,DD,DF,90,97,48,47,62,A3,71,F5,D8,94,A2,10,04,26,D2,12,24,6C,D0,0A,C8,AA,15,B4,79,62,C2,77,A9,1C,29,33,D5,5E,23,00,BF,E8,13,78,7D,61,A1,C3,0A,7C,77,87,76,BA,B5,89,D1,26,78,A6,3B,F4,F4,38,B2 -keyMatrices = 6B,A7,89,FD,FD,B5,E5,24,B0,B7,68,98,15,6F,09,0E,21,8C,99,73,16,B9,C3,C5,E6,DA,4F,F0,F2,13,20,D9,A3,56,30,23,F7,86,84,63,ED,42,A4,FE,AF,6C,E7,5F,50,1B,B4,43,AE,45,FE,B6,72,F3,DC,4D,68,CE,AA,D5,AD,77,13,74,A7,5D,78,34,4C,CD,81,2B,16,01,E0,A6,91,0F,B2,B3,CD,D0,FF,07,46,A0,1E,1A,C6,30,AE,49,BC,51,CE,30,CA,B9,AB,8E,BB,FB,A7,40,54,6E,FA,FF,3C,2B,16,83,31,1A,80,41,28,C2,22,73,D9,BA,3A,82,65,87,15,C5,18,FD,0C,D5,44,D1,21,E1,C4,F1,F3,8D,A8,C1,56,EA,08,1F,EE,C0,35,D3,65,0F,BF,45,4A,18,4D,95,B9,40,14,E1,12,7A,4C,01,1F,E4,06,38,24,46,49,31,FB,6A,84,B2,5F,8A,FB,56,D1,51,5E,30,02,B6,50,3E,CB,C9,04,05,F1,3A,84,C3,46,20,C4,08,1A,D8,73,63,BB,C6,D2,9A,E3,EB,58,CE,76,D3,F1,F1,81,3A,C3,47,AE,20,58,34,1F,E8,4F,76,B1,17,AA,42,DC,8E,24,4E,28,34,C2,9C,1C,87,ED,01,25,30,B3,02,F7,AF,8C,5B,E1,F2,8D,86,EB,F7,0C,44,E6,2E,11,B6,45,A9,FD,0E,10,37,F8,8C,05,99,A7,4F,7E,98,6B,BE,21,D8,A6,EE,F9,3F,CE,A9,AB,FF,42,4F,AB,A6,F7,3D,25,82,F1,B5,23,0E,CA,C6,98,6A,02,18,3F,93,12,02,B4,70,D9,3A,BB,98,C1,A0,5E,B0,27,54,9B,69,06,FE,F1,67,68,99,84,2C,62,75,56,34,08,0B,C8,7B,DD,49,8A,14,75,A7,75,42,D2,36,A0,A9,98,7A,18,07,34,61,0A,A4,72,6F,05,2C,76,06,84,FC,5F,86,85,EC,DB,C9,CD,99,5B,02,22,39,19,10,54,A5,F9,BF,0D,D0,EA,49,20,15,01,4D,0E,AE,53,B7,DE,B4,29,87,D5,54,FF,9D,CC,96,3A,18,D0,7F,25,83,D8,0E,C0,A7,D9,50,5F,05,9A,AC,EA,4B,BB,24,66,46,39,C8,F6,9C,2A,D8,2C,29,42,D4,A9,22,C1,B6,AB,FD,E6,33,D8,B4,97,23,64,63,2E,7C,4E,24,16,27,30,96,58,63,D3,83,E7,51,48,9C,35,8B,EC,F6,47,6D,87,A5,6B,9D,6F,6C,49,35,B9,36,00,3A,9D,A9,E1,56,AB,8D,11,CF,3B,65,48,12,3F,12,84,B9,21,81,04,CE,BC,4A,DB,90,EC,D7,B9,F3,BD,4C,61,B3,EE,F3,54,AA,03,AE,10,8F,9F,21,48,CF,F3,2D,C3,6A,53,A3,94,FA,82,EC,2B,78,97,8D,41,04,2E,8B,76,C3,D4,46,26,74,E3,04,B5,B8,2A,60,B2,F7,AD,45,62,DE,3D,EA,38,81,EA,07,C8,A9,99,72,C3,D4,DA,CD,94,DF,E5,9C,10,B2,0A,94,BE,51,E2,D0,3C,18,93,40,DD,74,64,8E,92,4F,2C,35,40,41,84,76,EC,15,40,E7,76,BE,FD,AB,15,B1,53,49,8D,23,5C,C1,D0,50,DF,A5,0A,26,E7,62,D6,C8,EA,19,D2,D9,9B,9B,A0,BF,49,CA,90,2C,BD,9B,F0,77,FA,FB,C9,2E,EA,78,11,80,5D,E3,7C,93,E0,CE,44,5A,BE,A9,D1,0A,7B,8E,BD,0C,C0,28,31,AF,B6,E9,68,3C,21,2A,CE,8C,28,E4,10,A4,CB,E9,7D,1C,89,E7,69,BE,75,AE,67,BB,B5,C6,20,71,1A,4E,98,43,4B,DD,95,F8,BD,AB,91,9E,6E,19,0A,26,5E,22,46,D6,6A,E3,19,DB,31,5B,9C,C2,19,E0,48,59,27,F7,B1,0F,5A,91,91,84,A3,36,18,DF,90,8B,AC,34,0A,C8,87,C8,EC,D4,AD,50,9B,CD,65,B5,4D,E7,4F,4C,82,39,C9,BC,93,60,83,3A,98,EF,4D,DF,70,10,71,10,FE,33,79,08,72,68,AD,27,FE,C8,57,63,C3,0A,B8,6D,4E,BC,B4,50,57,AE,6D,8D,F8,1E,DB,A4,F9,9B,9A,1B,35,E0,3F,B8,9A,90,A8,D6,A4,35,0F,6D,03,7C,32,5D,48,1F,51,4C,21,8B,47,26,D2,88,09,BA,54,4D,73,48,0E,DA,6C,A0,37,F7,71,92,48,8E,1B,52,D7,13,B4,B9,04,F2,7E,60,E4,35,29,C7,B1,C1,5F,6A,74,6F,D8,8C,EB,C7,0B,E3,0A,91,5F,23,30,FA,6D,E8,86,19,02,EF,9A,FA,CB,65,91,3E,E6,75,51,07,6B,B8,0E,73,52,CC,F1,55,2D,35,F1,F0,56,A0,D3,B3,0F,F1,F9,8B,6E,1A,9B,AD,A3,6D,01,D7,22,47,10,84,91,AC,09,0E,46,43,0C,2D,24,AC,C5,4D,7C,CF,FB,B7,14,02,0A,68,01,C7,69,A9,D0,8C,1F,8F,D7,ED,3E,A3,1C,AC,E8,20,11,F4,C9,D2,9E,04,85,CD,8B,E2,B8,FB,3F,4A,A1,51,BC,1F,D0,97,7F,C1,A1,85,05,56,13,59,D4,DA,EC,51,B4,24,E2,58,07,28,8A,C7,FC,CA,7F,E2,EB,0D,A7,8D,2E,DA,F7,81,AD,E1,E5,60,95,8C,06,8E,58,DA,B3,39,03,CC,49,01,4E,69,C6,A4,79,01,62,2A,3F,24,F7,0B,BD,3C,40,1F,63,C1,EB,8E,5E,C1,A8,A6,A8,60,4C,FD,EC,05,AE,45,1E,E1,8F,FC,2E,85,4F,AF,39,94,60,50,F2,D0,02,FB,9E,37,37,7C,DD,04,8B,D2,44,FD,C9,0B,D6,76,39,71,DC,B7,AA,49,3B,B0,F9,E0,7B,B9,26,B3,A1,E8,07,82,24,26,6D,5A,32,6C,60,D6,C4,5C,B2,4D,3D,9E,09,3B,D4,0E,14,5D,8E,71,C7,07,35,11,A2,1C,7A,EF,66,17,51,FA,07,1D,54,75,6D,81,3D,B9,C3,AA,87,9E,4D,8A,6B,CD,3D,F0,F1,69,47,0B,2F,8F,68,FA,2E,4C,85,A3,66,DF,DB,17,E0,FB,9E,8B,05,CC,BA,CC,51,45,47,65,3C,8E,7C,BE,32,5D,B5,7D,99,72,6F,8A,9E,DA,72,35,9B,C1,B3,FF,6B,33,DE,7F,C5,B5,E9,4B,4B,19,F8,55,86,D9,7A,0D,EE,92,25,17,2D,F2,C2,07,BD,94,82,36,54,8D,95,46,EC,0E,A6,FA,55,44,88,BD,49,62,0F,A9,81,1C,BD,77,01,C8,EC,5A,9B,E0,89,6A,1F,2A,6B,1D,90,68,DF,58,76,A9,39,CC,A3,F8,E0,40,92,F1,D7,C1,CE,59,CE,CF,89,6B,B2,6A,A8,D8,EE,3F,4A,C2,23,6A,72,34,EA,8C,18,52,09,C9,D5,51,E7,86,22,32,64,5D,AA,4F,B1,3A,65,AB,AD,0F,3A,73,43,6C,93,AE,76,C2,03,38,61,60,8C,6E,DF,BF,98,3E,61,5F,C7,DD,D9,DD,8B,B3,8D,50,37,23,C3,1D,6F,E2,CE,4B,C3,B9,69,35,50,43,27,F8,A8,CB,FE,F0,8E,2D,84,26,45,D1,D5,C2,63,08,68,2E,9B,1F,50,9E,F7,7D,2B,58,D8,A2,EE,77,52,38,E0,7E,C5,D3,15,33,55,74,B8,7C,66,04,33,26,FD,EE,8E,81,CE,97,C2,82,EA,B3,D5,6C,BF,E6,CB,48,9F,C7,17,24,41,5E,AE,27,B6,BA,06,38,01,CE,9B,3B,12,99,9E,66,7B,10,74,7E,85,63,2F,01,3E,11,4F,C1,7C,96,7F,92,F9,6E,9D,F9,54,8B,79,33,FD,4B,E5,CB,48,4C,E2,0F,44,6B,1A,EF,A9,5E,BE,06,A2,8A,14,8A,73,A5,7C,FF,56,4C,A9,B1,98,FF,60,94,24,2E,8C,54,82,75,11,7A,C8,0E,44,CA,DD,2E,5F,CE,CB,B7,37,78,47,51,54,EA,00,EC,DE,15,67,04,ED,84,03,97,CB,F9,4B,FA,98,8F,B6,AF,A3,9F,8A,F8,15,75,B0,34,F8,20,80,05,BB,9A,C5,44,B4,33,2F,1E,10,2B,96,10,76,2C,F9,A7,0C,C0,0F,52,22,08,F8,9C,8A,4E,E5,10,88,57,41,DE,15,1A,B0,65,99,5D,0C,4C,68,FF,E3,43,01,A9,6F,0E,F4,58,AF,99,A0,88,56,08,95,21,C7,EC,A4,B9,6F,94,50,37,EA,AA,A8,D4,F4,01,71,9E,60,30,FD,40,D7,91,DE,29,EE,76,A4,E9,34,A8,53,2B,E1,7F,C9,02,47,B9,B1,0E,C0,23,1C,E8,DF,10,5F,38,45,84,F1,04,FC,E2,B8,B0,8C,D9,4B,96,55,69,CC,30,05,2B,26,71,0C,8D,E4,CD,1F,24,10,81,98,57,7D,44,C5,DB,26,5C,76,E1,C0,08,1E,A4,FF,4E,54,ED,5A,17,C1,C5,11,F7,67,54,DB,F1,12,7D,20,7C,FA,C3,1A,E3,A9,00,D1,68,E9,82,31,ED,29,58,6D,01,61,35,78,79,AD,AD,79,C0,E2,7E,7F,43,22,85,39,EE,8D,0D,BB,67,D4,5D,94,BB,27,69,C5,16,88,D1,5D,08,5F,6F,B8,23,08,21,DE,5D,EB,74,69,61,F4,D5,3B,E3,DB,5C,27,3C,E0,50,E3,68,E1,E5,86,24,05,C0,D9,0F,FB,18,9C,60,8F,C2,04,71,1B,88,53,78,79,FA,13,1E,2C,2B,7C,BE,19,39,3D,61,09,DA,9A,45,CF,E4,07,93,25,99,12,13,E7,7A,3B,13,FA,29,22,66,B4,65,71,6F,DC,9D,85,67,2B,A9,43,2E,36,96,94,72,61,FB,60,44,AD,48,64,B3,91,30,84,21,46,61,04,0B,90,14,39,F0,A9,A3,99,6E,D9,30,17,7A,CA,7D,9F,36,CD,22,25,55,D8,93,64,78,C2,B5,F3,1A,C2,7A,6F,8D,9E,19,55,4C,8D,F2,FE,2F,89,3E,FF,E0,25,11,82,AB,8B,97,4A,E8,9E,D8,CF,6E,19,8A,F7,32,2C,27,52,FE,72,EE,06,09,01,D5,8E,64,41,6E,84,43,70,62,13,05,17,1A,02,5B,80,FE,39,97,36,6B,5F,EE,7B,17,88,1A,09,A4,B8,6D,FD,3A,69,12,0A,93,63,34,1B,9E,BC,A6,6D,F4,4C,7C,38,7D,55,83,B2,59,C4,3A,DA,47,F9,4D,93,D3,22,B2,AF,6E,16,7F,B4,00,EB,8F,53,65,21,86,F9,EC,9A,FB,E3,93,7A,37,23,6A,17,E2,8D,74,B0,4D,24,DC,DB,80,61,EA,2C,C1,B3,A8,75,AF,3F,94,04,9E,90,D3,30,FE,7E,1F,B6,F1,A4,53,52,48,03,7A,32,A4,20,3D,D4,9F,3B,D7,9F,96,FC,5F,38,82,71,9C,86,D2,EA,47,89,CA,A6,F6,31,13,32,16,B6,C8,61,6F,CF,B9,76,00,86,DB,68,CD,3C,D3,DC,6C,EB,DC,C8,CE,C5,87,CA,3D,E4,D2,73,73,39,F2,20,CF,ED,23,8C,80,FA,70,72,0F,B9,FD,DC,F1,2C,1D,E9,FA,0D,B9,E1,0C,22,1D,7F,2C,E4,1D,C6,D1,80,50,67,BE,5B,7F,6A,68,81,BA,DF,E5,73,68,6B,46,13,10,24,12,9E,C8,9F,BF,3D,55,13,72,1B,AC,AF,25,A1,A0,AC,8B,1E,58,6D,86,8A,67,C0,4A,B1,E1,6B,AC,81,78,71,29,3D,6B,17,DC,3F,92,CB,51,52,C5,EF,D1,4C,95,C7,32,A8,D9,8D,5B,32,C4,2E,77,B4,DA,18,86,9C,A6,69,10,53,B5,76,3C,42,9A,8A,11,B4,16,AE,E1,A2,B5,01,21,B7,C4,BA,5F,1B,1D,4D,4A,BF,7A,58,3F,19,08,C0,AB,1E,59,C7,C5,2B,18,AC,3D,6A,61,C1,13,B0,21,1A,AA,8A,59,56,D0,F7,2A,9A,53,88,47,48,7D,0B,26,0F,6D,E9,E8,BD,82,27,D9,B3,0E,D7,50,22,75,58,DC,BD,C0,03,0C,37,0F,6B,56,39,2E,B7,73,2E,28,FD,BB,78,15,C2,AC,A9,47,50,CE,F9,0A,3D,FB,C8,4F,E5,1B,36,32,F9,A5,02,01,55,33,10,39,88,1B,E0,22,A2,E3,A2,95,66,00,17,62,F1,62,78,FB,DC,29,42,8F,2E,9A,24,DE,7C,E8,92,9B,47,EC,24,C0,F7,B9,E5,45,D6,92,9A,58,27,26,55,7F,93,E7,43,44,1B,FE,2D,1D,5F,AF,D8,06,E6,1C,46,CF,4A,1C,C5,66,0B,BA,4A,C1,CF,17,8A,5C,39,E7,6F,72,BA,7B,F4,45,05,9B,45,A8,2F,13,78,EA,C2,7A,C7,01,49,9F,2A,D7,01,C7,33,0F,93,F4,C0,9D,44,A0,1A,BB,33,C1,B5,AD,EE,A8,70,A8,93,97,08,96,B6,E5,6B,F6,8F,99,F6,21,87,9E,FA,C4,AF,46,46,D2,89,EA,26,0D,7B,FD,A7,EB,CC,FD,A0,4E,AA,DD,D3,BD,91,DE,05,6D,BE,8B,BA,9D,C9,6D,A3,9E,EE,C0,AA,06,28,70,06,24,E3,E8,6A,07,EB,B3,05,06,DE,C6,C4,F0,5C,3F,E0,35,86,00,EA,9A,01,D2,70,57,40,FB,7F,25,15,62,1F,97,E0,F3,56,F6,0C,6C,D7,55,AE,25,A3,4E,3E,38,5E,5F,E4,2F,F8,36,64,C8,E7,80,C0,F0,9F,1C,63,EE,F6,4D,E0,47,94,29,6A,6E,F5,67,E5,47,5F,E8,EB,64,28,B9,58,18,00,DD,DB,61,A6,28,A2,B3,89,2A,9E,CF,C1,40,5B,32,AC,3A,43,0D,3E,96,67,71,01,69,48,06,E5,05,3C,C9,4E,7E,56,83,AE,80,CC,27,13,96,45,A5,F7,ED,A7,05,0D,30,DA,A3,19,EF,2A,BB,BF,EF,87,FB,F9,F9,C7,C4,4B,E9,53,B1,F2,FD,37,CD,63,93,19,5F,E4,D2,E0,AC,99,87,2F,29,76,1A,4F,99,99,3D,E9,CE,04,4C,43,57,27,FD,A9,0C,8D,B2,7A,92,7F,40,8E,AA,EA,41,0B,8C,D8,A1,0F,2A,5D,1C,1F,0B,C1,F9,09,55,0C,8A,2C,84,28,FF,04,95,01,E2,32,07,D9,34,8D,A1,C9,B7,56,6B,54,F9,A1,AB,90,F9,00,2B,13,43,C9,C3,FA,A4,A0,7A,C8,95,D2,8E,1E,C9,6B,D1,D2,69,78,EC,5F,B1,53,92,FD,95,26,0C,FA,0C,2F,FB,A1,31,89,1E,6A,6B,ED,D7,D4,02,A0,E0,7A,6E,2D,F5,9A,1B,0D,04,FB,9B,95,06,3B,55,4D,72,7F,62,AC,BB,0B,76,54,03,CE,F5,FC,4B,9A,4E,EC,B9,22,5B,A3,F0,90,A9,80,EB,A4,44,9F,99,AB,09,84,DD,4F,6A,F4,E9,61,43,74,D5,45,A6,DB,76,0D,D8,22,8A,3F,DF,78,8F,5A,70,43,65,71,0E,04,B4,FB,FA,CE,08,D3,92,C7,EC,FC,A4,07,EC,62,2C,E5,E6,8D,0B,EA,64,BB,9A,11,1A,D4,A4,B7,DF,82,65,7A,FB,91,77,E0,CB,1A,2A,87,6A,8C,30,5E,3D,CA,E0,DC,1F,F7,69,7B,BF,9D,8D,4F,3B,F8,FF,27,39,93,13,3E,29,7D,58,EF,B7,30,9C,E1,76,17,0D,52,61,A8,20,48,D9,7F,6C,4E,9F,F6,1F,2E,E1,34,A7,9D,B2,41,D0,F1,55,C3,04,4D,A8,EB,D2,62,85,B9,67,58,7F,A6,53,12,18,93,3B,BD,A3,3E,7A,7A,27,CF,61,54,E4,A2,6B,42,95,1F,59,32,CB,38,38,96,1A,2F,8A,40,8B,DB,C3,41,08,FB,4E,61,A6,7F,1A,AA,E2,6C,4E,E8,76,9B,09,08,DD,06,53,77,B4,A9,95,6C,49,E8,23,B7,D7,A4,93,7B,14,05,84,05,8C,E2,E2,A8,21,70,5F,E9,B1,11,05,7A,E0,4E,F9,4F,20,80,C1,B7,71,AC,26,76,06,CC,1F,5C,F4,15,7C,F6,3A,E8,0B,EC,DF,B5,E4,37,32,11,27,52,C5,7E,E1,FC,94,E3,52,53,E2,DA,B6,4D,AD,CD,1A,B5,03,53,B9,FA,67,DE,62,DD,88,67,79,E0,09,1F,7B,CF,4C,E3,10,4F,DC,8C,01,1A,C3,7C,D5,53,76,DC,5B,C4,20,75,60,BB,0E,63,56,81,55,A1,D3,22,EB,6C,D4,D7,5A,68,EB,30,3E,66,FC,00,54,DE,1B,C2,ED,84,F9,6E,23,F7,E4,5A,10,08,18,7E,F8,08,74,1D,9A,E2,F1,95,78,52,DC,BB,E4,76,D7,C9,2E,2C,30,27,E0,FA,2D,C1,B4,99,D4,A2,7B,9D,6F,57,C8,A7,61,FE,EC,8C,53,B1,61,2C,99,FD,D4,21,9C,74,DA,62,0B,C2,8E,BD,06,98,79,DF,03,C9,48,C6,27,70,5B,7B,D6,AC,3A,A4,D6,39,51,0D,08,AC,63,A6,3C,3C,DA,CA,1A,8E,D5,B5,95,AE,2B,A7,D6,96,BC,D6,03,22,C2,43,36,E0,B0,EC,DC,66,FA,38,21,35,A9,43,9F,95,EC,58,36,9A,01,93,DB,95,A2,7F,29,CF,B4,AF,C0,F6,CE,B1,17,39,94,1F,45,35,E7,11,B2,EE,2D,3F,F1,7D,1A,62,BA,40,D4,1C,77,11,78,95,52,3F,D7,18,D0,31,F9,A9,B7,9B,7B,8D,33,22,C6,D7,31,1D,F6,87,03,4D,DF,3D,40,6E,79,9B,8B,71,58,06,FF,90,B4,8A,2E,0E,E2,89,E1,2E,24,5A,F1,A0,C3,6D,25,85,81,23,42,7B,CC,1B,5B,B9,89,41,A6,D8,34,A9,BD,77,ED,AB,25,67,71,F7,ED,CC,66,18,F3,F2,A4,C9,86,C8,89,10,25,16,9A,FE,F4,8F,1F,8B,B1,5A,E1,D0,FB,26,63,65,9C,EB,F3,9D,B1,D9,00,47,64,6D,39,47,93,C0,08,25,E9,07,FB,4C,40,2B,2F,D9,97,2E,55,B5,E3,61,19,49,1E,91,D7,35,FD,CE,C7,82,C0,F0,40,5C,FE,C3,C2,8F,B1,8E,3B,0C,1C,D6,DF,37,A0,FA,FF,42,E7,42,66,44,EB,D8,1B,A8,D7,80,E9,14,A4,17,36,FB,A5,53,ED,EF,52,B0,7B,E4,F0,A6,D6,76,20,16,D3,36,41,21,CA,DB,6F,5F,83,41,7B,44,CA,35,12,CE,32,C8,29,8A,BA,64,A7,FF,49,BC,A0,34,16,9A,86,6E,27,D0,FE,0A,9E,64,6D,4C,EB,D3,BC,3F,84,9B,93,3F,83,38,B5,44,F2,4D,C6,BE,14,F5,FE,13,DD,51,45,3A,8B,02,43,59,B6,8A,65,F1,AF,31,F0,10,D3,12,41,D6,6D,B5,DC,EE,F6,B4,DE,7B,0B,AA,B3,EF,75,50,18,9C,AD,FB,21,7F,A9,FF,9C,AE,77,04,80,EF,5B,39,42,77,02,CD,24,DB,E0,54,E0,70,B8,3C,72,31,20,A9,D4,D9,D5,07,45,84,58,C6,71,92,36,5B,10,45,BD,84,30,7A,60,83,54,C0,DD,E0,C3,4C,B4,23,AD,CE,74,29,C6,D4,EC,7E,FF,A5,53,EE,B6,C1,CB,DC,79,9D,4B,74,F6,7E,73,3B,FF,13,AA,01,35,89,A4,0D,A4,C2,09,67,D8,36,A2,64,50,5F,75,3E,C9,29,81,87,F5,2D,12,51,CB,A1,ED,0F,1E,B7,66,9D,22,BB,F4,1D,7D,F4,8B,77,5C,72,95,68,DF,93,50,4D,9D,E3,F7,86,6B,88,11,74,78,6E,61,67,3B,8A,23,83,28,91,BC,94,15,F2,0C,8E,81,A8,AC,45,05,13,2D,44,E6,DB,5F,34,DC,1A,14,7E,BB,3E,64,B2,1E,7A,42,17,A4,A2,03,48,43,53,4E,71,2B,8B,32,ED,C1,5C,35,D8,EA,17,7B,12,FC,90,2F,26,2F,7A,85,E6,AC,CD,45,05,E9,F3,42,CB,D8,20,5E,BB,8A,2C,64,DB,83,9F,04,6B,D3,EC,7C,2E,DB,A3,C9,9A,AD,6C,C6,C6,43,EC,90,E6,BE,BD,F5,68,BA,C6,BB,11,F1,91,B7,42,F9,78,A4,C1,62,FB,B3,5D,7D,E3,ED,9A,6E,8C,93,B0,49,07,D8,B5,78,61,25,16,19,93,A2,FF,99,56,2F,3B,52,19,4A,5D,1B,2C,67,56,1C,2A,8E,D9,63,46,4A,8E,4B,DF,33,55,CC,85,2A,00,3D,E3,90,29,38,16,95,28,AB,E4,6C,46,B5,A4,BF,FB,CF,F3,39,B2,30,38,57,9A,1F,79,C1,04,85,47,A2,20,47,F0,74,84,45,9D,00,CC,35,A5,08,9B,AD,1C,6B,AF,43,9E,BA,91,3D,6B,19,B1,42,45,2D,7C,B6,8C,E1,1A,C1,56,62,31,E8,6A,85,A4,88,04,25,2D,C2,16,0F,82,D8,F7,4A,BA,46,22,D5,62,5E,C9,40,8F,6A,48,24,BD,D9,B1,BC,35,DC,7E,2D,06,D8,41,F1,13,0D,93,34,3C,45,EA,6D,7E,52,2C,28,7E,DC,93,33,70,BF,68,37,F7,FF,C4,C3,55,6C,2A,C5,60,6E,A6,5D,BD,42,F8,25,03,AC,3F,1C,99,42,FC,FA,DC,87,51,CA,35,C4,FF,50,50,2F,77,A1,76,23,81,7F,59,D4,CB,D6,18,43,07,85,50,EA,7C,4B,A0,C7,9B,90,2D,2D,69,9A,C6,05,0A,80,0C,EF,EF,ED,15,EE,1A,8E,39,60,77,D5,0A,C6,26,EE,50,2A,7E,9C,6B,83,EB,64,C0,FA,63,F9,DB,94,0F,76,15,62,97,0E,23,09,4D,36,88,7E,D9,26,20,C0,4E,7D,91,27,0A,40,33,CC,4C,02,7D,A0,71,DB,7A,19,BD,F5,5A,73,64,2B,CE,38,0F,50,CE,3E,40,3D,04,6C,08,1B,EE,EA,EE,87,A0,58,C2,F6,0A,66,8B,1C,20,64,48,60,B3,B7,CA,9A,F1,80,7B,0B,78,C7,F6,67,97,6F,11,C2,CD,53,E4,83,CC,60,35,CB,6C,70,E5,25,8B,E2,74,72,F0,A4,C6,3A,4B,A4,EF,EE,9B,B0,AD,D3,1A,C9,27,65,C4,3B,48,D8,47,71,79,3A,6B,1B,48,E6,34,C6,67,5D,D0,F6,42,06,9E,97,C6,BD,F5,C7,30,67,A7,DE,37,7A,78,44,98,54,CD,A1,1F,46,90,FA,B7,4D,5A,72,EA,E0,9A,A3,18,F4,61,A4,B6,94,67,A9,BB,3B,A9,DA,04,33,40,8B,26,E3,4A,C9,4D,86,74,04,8B,3C,77,91,6B,B6,64,86,D0,C1,3E,A4,F1,8B,2A,5E,17,F6,B6,6D,08,53,4D,85,B8,96,5A,07,9E,DF,4F,E5,BB,D5,10,AB,B3,6D,3D,0F,2E,F0,66,EA,75,11,C5,5F,8E,9E,74,5E,66,43,26,34,E4,77,F7,88,2C,D0,1D,B7,13,EF,3C,6E,83,E1,A4,C3,74,20,1C,4B,46,52,31,27,BD,18,FF,95,F8,2A,A6,C6,0D,F1,D3,3E,D1,6A,C2,75,B7,74,C5,31,2F,90,BE,DF,B8,D6,61,A8,A7,9E,98,43,37,97,F2,69,8A,7E,9B,56,1A,9B,73,1D,08,B4,71,42,5F,C4,89,18,C0,1D,92,23,C6,8D,E3,4D,98,44,4D,3F,22,B4,E4,FF,6A,29,37,38,9D,59,13,61,47,74,E4,BE,1C,E3,B9,CC,39,FA,1C,47,0E,C2,47,F2,9A,31,95,FA,CE,DC,2E,15,27,29,F0,69,EA,F4,BC,71,68,71,FF,6A,C7,5B,58,CB,86,F2,B7,60,30,8B,FA,29,69,6F,47,1E,3A,CC,AB,5A,5D,55,81,66,0C,33,E3,24,09,34,B1,E4,9D,91,A0,21,C1,B6,F3,82,A5,85,EB,70,3E,5E,76,21,97,48,D6,B7,14,76,E6,6D,7C,9B,B8,4E,03,5B,AA,78,51,06,EF,DA,89,F4,BD,3A,4B,58,3C,B2,D7,E0,69,F6,24,8A,BC,96,30,3D,D6,04,11,5B,D7,55,97,C7,97,6E,52,0D,2A,8E,31,27,12,9B,20,E9,46,27,32,32,7C,57,D1,F4,3A,8B,42,48,72,12,01,CD,7A,9B,1A,BD,7A,9C,44,59,B2,58,9D,42,3F,4C,E3,2B,86,21,B2,DB,E0,5A,0F,41,87,DB,78,44,CB,D0,EF,06,73,0B,DC,E3,1F,6B,0C,E1,35,E4,BA,3A,D8,36,3D,F1,93,1E,BF,76,BC,06,F5,55,07,57,E9,C2,8B,55,B5,06,B7,D3,5C,B8,D9,2C,0D,B1,12,0E,A3,EC,82,12,A3,73,E5,AF,20,3A,59,67,4E,0E,90,3A,3F,A9,39,1D,71,E4,8B,AC,6A,E2,94,2D,DC,8F,9C,74,20,24,0C,63,A1,25,59,9D,7C,07,60,C0,A7,DF,74,40,CD,74,96,F8,5B,A4,17,78,D7,7C,1A,17,D5,B0,9D,C8,73,0D,92,43,19,B4,18,18,C8,84,3F,4F,C3,0B,A7,4A,35,C8,58,A3,E2,B0,BF,D2,8F,2D,B6,AE,BB,F8,17,99,F9,40,FB,E0,2D,26,75,96,19,8F,38,4F,9C,86,97,52,86,E4,21,94,2E,B4,CD,CD,AB,65,D6,83,03,17,C1,9C,D7,9A,5D,6A,F1,FA,AD,F3,8E,26,E6,8C,1A,15,91,AA,0B,F1,BA,B1,4E,EE,47,07,19,67,D5,2F,AD,DA,44,C7,4D,42,EB,F3,24,70,45,4A,EF,7A,E0,E2,9F,5F,A2,26,83,E1,4C,53,3C,48,A9,C0,A7,7B,C0,16,0A,B6,D2,F2,49,10,A3,FE,6C,54,1D,E3,89,D7,60,15,2D,0C,03,3F,4D,CD,A6,5E,70,ED,3F,B7,2A,E7,21,C7,01,42,DE,A7,72,BC,F9,2A,1C,78,FE,78,9E,20,80,9F,83,EA,D9,1A,FA,D1,78,99,32,B5,F7,FB,DC,75,83,BC,34,0A,82,85,5C,9E,2E,03,8D,4A,C5,82,86,8E,AA,1A,B9,F0,AB,B7,B5,59,58,07,26,8D,DD,5E,8F,52,1C,8D,D0,63,B0,8D,CA,C8,63,6C,FB,6A,8E,02,D3,54,32,F1,D5,F8,A5,AB,EE,4F,6A,3E,D2,2C,F0,08,2B,DC,F6,AF,8D,C3,A5,60,3C,D5,2E,87,44,18,48,B1,99,7A,26,45,06,1A,88,2B,05,73,CF,EF,B4,35,DF,AF,43,0F,8A,53,9F,FA,11,D6,0D,A8,82,B1,1C,2A,FD,FF,2C,BD,88,A3,C5,31,3D,68,73,C8,ED,F6,82,A0,28,F6,52,B7,5C,82,64,92,9C,89,19,A6,13,5B,F7,E4,1D,E7,DB,3B,3E,45,13,49,0C,FE,43,BE,5D,7D,E4,E0,99,91,18,8E,F8,62,36,DB,F3,BF,36,81,6E,5F,5F,76,D9,80,D9,91,DE,21,32,CC,B3,9B,73,BD,F6,C2,B4,9C,40,F0,EC,25,A3,78,4D,AD,C1,20,42,D3,BA,AD,10,43,B0,3A,F9,6C,4A,6B,13,32,71,AD,C1,40,31,C9,B0,75,04,A0,A6,53,E6,2B,59,D9,D7,7D,42,36,B2,68,6A,DD,C6,95,38,E0,C0,14,19,5C,82,3E,3C,62,CE,D8,77,F7,FF,61,73,E7,62,BB,C9,0E,7E,67,14,85,8B,7F,55,DF,B8,5E,4E,31,CC,21,2D,C0,5A,8A,24,60,E5,E3,E5,05,5D,4C,3F,39,71,40,1B,C7,AC,0E,2E,91,DF,12,EB,BA,30,4D,B2,5B,5A,6E,63,B3,5C,01,2C,F4,5F,D5,1A,4A,8E,8E,9E,D7,C7,1C,B8,46,B4,31,0F,A8,4A,38,E6,6E,5D,DB,5E,3F,CE,83,A4,A4,78,77,71,28,06,37,ED,B0,89,39,7D,6A,19,40,F3,BC,A2,98,60,FA,75,F8,E0,A1,B5,C6,95,8D,67,91,67,15,DB,68,8F,72,E6,0D,BB,8B,A7,6B,CB,D9,71,0B,9C,5C,F9,DC,CA,7B,45,9F,14,35,CE,58,CD,73,47,9F,83,07,EF,DD,EA,24,CE,E6,FA,D6,00,EE,56,51,45,76,B9,D4,71,88,A5,22,4F,BA,02,75,B9,1D,8D,CC,2F,58,F4,42,75,8B,13,6D,3E,BE,7F,19,7F,30,6A,57,D2,E7,EB,04,6F,C1,5A,ED,5F,E8,48,0A,A0,B1,4E,49,5B,51,33,0F,2D,6C,9B,A4,24,6B,E3,C0,38,E1,44,A5,80,69,CD,74,08,EB,E3,73,4A,90,1F,AC,DE,44,BF,B1,03,5F,AD,16,38,4F,13,3A,DA,4C,17,BA,AE,48,D0,40,D6,3F,64,E1,85,67,DC,31,3D,C7,25,BB,B3,EE,52,8C,9F,7B,A5,7A,DA,F2,EC,4B,23,31,D0,1E,22,0B,C5,B1,04,B1,A9,41,0A,86,1E,9B,98,C0,46,2F,ED,5A,0F,03,47,F8,AB,76,70,7B,71,20,6D,C3,7D,78,E4,96,24,C6,AD,68,81,79,A9,6E,76,8A,EC,C1,9B,21,00,22,69,F7,DB,13,8F,51,DA,E8,30,C0,6D,4A,70,78,4A,B6,A6,3A,F5,36,DF,64,AA,B0,79,F7,CE,02,20,E9,CA,C5,12,BA,43,5C,5E,7D,E6,C7,63,CD,18,A8,D4,A2,1D,B0,8E,54,F9,D5,F6,23,CB,8A,77,97,CB,06,18,C6,53,08,0D,CA,65,F2,3B,DD,07,A3,7E,44,E0,90,37,55,8E,48,77,6D,D3,0A,8D,C6,E9,27,44,F0,19,18,BC,29,F3,16,96,29,B0,D0,C5,14,79,AC,22,94,AA,27,81,5F,BB,06,FD,8A,18,23,A4,11,38,11,FC,11,24,6B,42,29,E3,48,2F,F3,BC,20,07,1E,13,A4,24,05,54,8B,3E,92,25,64,77,FC,01,26,1B,85,54,3A,D7,C6,2A,2E,BB,86,49,36,AE,43,DB,D6,50,F8,FA,A7,50,DB,B4,FD,CC,36,C1,1D,94,45,F5,BF,BA,8B,CE,86,B7,F6,CE,7D,3A,EE,88,F1,9A,F0,61,A7,6A,95,DA,A7,11,22,7A,F0,E7,A2,9D,68,4D,50,24,10,EC,11,BD,09,11,2D,CE,CA,CA,86,65,62,D3,31,0C,51,8F,7F,63,FE,4A,64,2C,78,41,1A,F6,11,C0,63,46,52,02,9F,9C,64,93,43,E4,77,BA,81,B2,7C,F5,F2,C9,DB,B5,76,91,63,02,92,A2,11,19,A7,8D,C3,29,44,CC,7B,21,65,BD,F9,46,0F,6A,35,4F,10,26,7E,43,87,9E,BE,7E,1A,CA,8D,E2,2F,CA,55,E6,17,2F,36,10,AE,F4,3E,5D,03,4A,7B,CC,5A,8B,A7,00,D1,3A,49,C0,46,3F,36,5D,87,18,8C,85,6E,F4,FF,D6,BD,7C,85,1A,B7,26,F3,86,39,FF,59,9D,ED,27,F8,3F,63,E7,4C,E2,2F,3C,8B,FF,4F,95,27,5D,D3,AD,63,8B,29,78,2C,39,7F,4A,91,FF,91,82,59,EC,25,21,01,43,00,30,7D,1E,42,31,0E,B3,A6,50,42,FB,71,27,BB,24,41,65,5B,8A,2C,B1,28,E2,DE,5C,3E,EB,1A,33,BD,87,7B,25,45,4A,69,4E,5F,94,85,E2,C5,2F,7F,E2,BA,E7,4E,FE,58,69,68,FE,43,FA,D5,43,A5,38,09,96,31,BA,17,35,6D,94,94,26,6C,94,96,2D,BA,03,3E,C9,C8,83,00,30,6C,AC,2A,66,77,DD,10,B9,8C,39,F1,40,82,34,D1,88,3B,6D,E1,77,E0,6F,75,BB,29,B3,99,08,D0,E1,C3,95,51,BB,46,9E,FE,EC,68,F5,53,4A,3A,CA,BE,B1,9E,3B,A4,BE,7E,39,A6,F2,49,56,BB,A8,D6,35,0C,DC,AF,E7,0F,44,5B,08,3D,DF,02,C6,C8,38,AE,1E,03,8E,C1,B7,57,BA,9C,95,0A,DB,86,3F,99,C0,3E,BF,DC,92,6E,11,21,01,C7,9D,2F,5D,AB,96,09,4E,E6,26,F4,2E,B7,BD,FD,A2,60,F0,60,21,D7,A6,97,59,96,59,6B,FD,AB,E4,1F,87,F3,C7,3F,1C,18,30,41,DF,E9,E5,22,BB,97,EC,C9,7E,6D,F1,CF,46,23,D1,73,B6,12,9D,37,E4,F5,0D,F2,59,A5,3F,90,A9,B1,D6,8A,2B,24,B3,6A,BA,51,D5,B6,79,E7,F8,B7,E7,17,A0,A0,33,F0,66,A0,F1,7D,20,88,3C,EE,78,E8,62,CB,F7,64,57,3A,87,B6,86,92,3D,62,76,D9,E2,B1,2A,F1,F3,33,4B,E3,D7,F9,1F,42,35,0B,C0,3E,A7,AE,FB,B7,EA,79,43,36,2A,CB,E7,D4,DB,09,9F,0A,8A,3A,E4,F2,98,78,D6,60,11,B3,C0,86,F3,4F,BF,42,68,4B,7D,5F,B7,1E,21,1F,8B,DB,A2,83,11,FE,7F,6F,9E,DE,C3,31,81,20,95,BD,B4,B2,E4,C9,72,3F,20,54,4C,81,1D,38,C7,8F,29,D3,95,72,93,B8,A3,52,6D,68,AD,F4,34,C1,6A,8A,C3,6D,B0,14,BF,8E,F4,0D,E6,BE,B4,24,92,B1,D9,15,5D,80,63,07,01,CD,12,8A,7E,08,CD,CD,0B,A2,15,E7,D7,07,C8,D0,91,A1,72,3B,CB,D4,45,7A,3B,55,38,8A,7F,F6,3E,52,50,7A,D9,03,F0,AB,C5,86,0E,24,6C,0F,E8,E5,43,55,99,6B,CF,35,3E,D7,6D,FB,65,92,7A,13,12,05,9D,62,39,BB,4D,A6,92,42,EF,20,10,25,26,A4,61,E5,12,F3,93,47,FF,02,E1,94,8A,CD,EB,6C,4A,68,1B,D8,1F,B2,C8,2F,44,CD,57,F1,CE,15,FD,5E,42,1B,9C,7B,BE,12,59,90,70,29,FE,13,3C,8D,AA,D2,63,94,6E,3C,04,45,57,61,EE,0E,D3,B3,FC,70,22,DA,29,65,4E,0B,AC,A5,C1,F4,79,46,D7,89,7B,D1,60,E0,80,2F,7A,A2,98,93,4E,F7,71,B9,EC,AF,7F,03,14,67,87,E0,F4,F9,67,23,C9,1D,0F,29,19,40,7B,94,88,21,79,B4,0B,57,93,A9,D8,E6,8F,47,E2,78,7D,0B,FF,D3,CE,07,1D,B7,16,F8,0D,9A,1D,71,2D,EC,5F,AC,FE,AE,60,16,55,45,C5,F6,06,1D,07,5C,CE,06,06,77,15,D3,79,10,7C,F6,63,B6,A3,ED,63,81,B3,2A,75,69,35,37,7C,B8,0F,E4,E1,79,C9,34,4E,12,23,88,60,18,DE,F5,E0,4C,27,9B,7B,83,87,DE,28,72,BD,FB,F1,84,57,E5,AD,53,61,DD,32,C4,40,DB,8E,FD,D6,29,08,6B,0F,DB,F8,3F,F7,F4,68,28,69,B8,FA,82,DC,7E,7B,A6,BF,A9,60,1D,8F,16,3A,C5,CB,E4,A4,46,49,30,C0,3A,40,67,D9,48,09,B0,AF,BA,61,11,88,43,19,0E,5B,61,5E,48,3D,F5,50,DD,3E,91,D1,BA,A3,2B,3E,DD,7C,76,05,55,22,77,22,F6,3B,B5,BF,72,99,A1,96,6E,ED,C1,EC,7A,9B,4C,ED,B0,AB,63,DE,71,36,18,2D,EC,35,A4,69,69,59,BE,16,14,48,E6,97,0C,48,A6,F8,39,C3,AC,40,B7,D6,8E,A2,51,74,08,0A,4C,83,8A,17,A1,73,81,42,BD,8C,12,2B,20,6E,81,3E,39,CA,52,0C,E5,CA,F1,D2,9F,ED,B4,0B,29,40,98,6E,41,D4,E1,31,BC,FF,FA,BA,1C,0D,C4,EC,59,6C,1F,70,7A,BC,45,2C,CF,D7,11,F0,41,64,C8,C5,8A,98,00,52,75,67,2C,9A,A6,35,43,C2,DF,BB,0E,01,DA,57,51,B6,C8,76,2D,E9,23,EE,2E,45,5C,40,C2,1F,30,BC,F8,E6,1F,9D,82,05,11,89,87,C8,15,5E,93,DF,DC,26,69,8E,1C,47,C4,F4,53,C2,5A,62,F6,FA,00,73,81,EE,8B,83,9A,D6,BE,84,B2,79,96,2B,11,A0,2D,68,B0,65,4F,02,DF,6B,9A,C1,46,3D,32,C0,58,ED,62,B9,86,FC,79,65,BB,AE,A8,BF,D6,A6,B0,1D,7F,6F,4A,51,8B,F4,B1,81,C2,5D,B7,05,FB,AF,D7,E0,A6,AC,05,19,A5,47,F6,A7,B0,75,37,82,81,83,3F,08,A4,BB,7C,27,89,C6,EC,78,BF,10,4B,D2,B5,87,9F,69,51,83,30,30,AB,B9,FD,24,A6,3D,31,C7,27,9D,47,76,A0,DC,F9,95,3C,A3,6D,08,79,E8,77,6F,40,24,99,28,42,91,A9,02,6D,EC,F3,E3,B9,C1,0F,C8,7B,79,71,31,FB,49,ED,52,18,7D,3F,83,47,C3,DF,E6,A4,AE,61,B1,5A,68,F4,C7,F7,68,24,FC,6C,6F,54,34,D2,48,08,2A,53,C4,B8,6B,D7,2E,78,FA,5A,B8,B5,01,7D,04,AE,11,10,C0,3A,40,8B,7C,83,F8,AC,60,41,AE,F1,BB,7B,B2,16,79,69,6F,7B,6E,5D,D1,3E,62,E1,D1,D8,1A,0A,E4,50,B5,11,DF,A6,77,AF,6B,CB,AA,CB,7E,A7,F4,AC,AE,CE,FC,EB,4E,BE,A7,88,5E,CE,1F,E6,3C,44,A7,15,33,81,1F,B0,18,C9,49,84,A5,4C,2D,E2,BF,39,EA,86,E0,D0,4C,3F,DF,90,CD,B0,07,48,5C,91,E9,83,E2,FE,BF,4E,29,D6,C0,F8,AF,75,91,49,45,B0,5D,F1,17,12,03,DD,BD,E0,46,29,39,D1,89,E0,1A,6C,9B,C6,84,F3,68,22,00,11,6A,2C,45,88,EA,FD,60,0F,9A,93,8B,C9,7A,6E,79,FD,01,C8,E6,47,B1,B0,8C,22,B0,07,E3,F9,D3,17,C7,E2,D6,AA,6A,B5,47,C5,64,84,49,F4,56,8B,BC,CF,23,82,E1,AF,17,A8,A1,FA,27,A0,BC,96,05,D1,A8,A5,13,0F,07,53,76,D3,F5,E7,70,9F,46,D5,8C,34,6E,11,37,6D,F7,60,63,74,C5,FD,87,EB,93,CC,A8,1A,64,AC,33,89,09,7D,0E,94,B6,C9,C4,7F,2A,8E,55,68,D5,15,BB,B7,FC,B9,D5,AE,8F,DA,DD,96,8D,D5,2F,E7,9C,4C,41,0F,FB,2A,06,76,CD,4C,3A,B6,F8,92,0F,66,8C,3A,E7,DE,62,BC,D1,19,2B,6E,66,22,53,EF,12,81,23,52,4E,E9,93,8D,20,28,50,E1,02,14,CB,13,80,72,F4,17,66,6A,F7,77,E4,05,8A,15,FF,93,20,80,67,36,9E,6F,B2,FE,92,FD,36,55,CA,80,4E,6C,33,AF,4C,B9,A4,3E,A4,1E,9C,6B,59,54,64,E7,72,6B,8A,36,C6,44,75,1A,EA,5A,EC,A9,61,C7,F9,81,FC,9C,89,F5,09,35,D3,92,9B,14,28,A0,B0,B3,50,7C,22,DF,29,E9,63,AE,53,BD,9E,D6,4A,5D,70,DC,18,10,4D,AE,10,6F,A9,96,13,CE,2C,DA,21,CB,1D,9A,F0,3E,58,FC,47,5A,3F,3F,16,B8,0B,38,E0,88,2F,EF,03,6B,B7,01,0A,C5,26,9D,02,09,BC,3B,10,52,E0,43,0D,D0,A4,B7,65,8E,5B,1B,0D,CF,40,CB,2B,0D,AE,94,AE,59,EE,A4,C7,8E,00,20,32,0B,F5,AC,CD,B8,09,B5,54,A1,55,B0,3C,D1,49,E2,47,C3,6F,EF,98,AB,54,EF,C0,AB,AC,16,5C,D8,FD,AE,66,30,28,02,B1,9F,C4,27,5D,BA,E4,48,8E,3E,D4,44,6E,86,1C,61,0E,50,DD,4C,DF,59,8F,A0,10,3B,F9,9F,6A,C8,D8,DE,02,8C,73,18,72,E6,DD,3A,C6,91,3E,0B,B5,7E,6B,94,01,3F,35,35,7E,F1,18,14,8B,49,0D,EC,12,3A,AA,EC,40,94,4E,2E,3E,BF,33,D3,26,42,F4,94,C9,6C,9F,BB,9E,A3,C4,AA,97,F3,10,21,1B,AF,FB,3C,6A,91,F4,0D,D8,55,09,48,16,48,79,30,B2,47,73,59,CA,9B,5D,CE,6D,4A,A5,5C,64,80,B8,26,4D,7D,77,65,20,8B,12,96,6E,58,C2,78,7A,50,FE,D0,0A,0B,62,C7,6C,64,73,C9,32,30,A1,57,F5,7D,05,F4,E0,D3,FF,67,E7,BC,36,E6,4C,29,17,CB,E7,BB,2D,C2,D0,3E,D0,5D,C1,5B,89,CB,25,4C,50,E7,89,5B,6A,6D,29,6E,D3,30,E0,34,3B,4F,22,47,B7,FE,EE,91,A2,45,11,A9,8B,E6,73,44,87,1A,AC,1F,DF,3F,D4,68,46,32,FB,F7,74,EE,32,C3,69,5C,7E,43,58,CC,CD,24,51,B1,8C,5F,6D,52,30,8C,28,FC,06,63,EE,34,68,E8,75,71,B4,44,71,25,38,97,02,80,1E,97,16,90,1E,E2,62,65,29,A8,F0,DE,7F,88,66,6A,56,BC,76,97,70,A5,B6,91,1E,D1,47,AE,BF,8E,FC,F2,49,9B,35,A8,36,D9,B4,62,3B,D6,20,D3,FF,1F,4D,AD,07,0A,37,84,BF,86,FB,DF,2B,74,BA,8C,19,4D,5D,34,EF,99,20,33,E0,82,32,39,99,65,3D,EC,38,83,62,5B,49,0F,5D,BE,5A,90,57,2B,F4,9F,BE,C4,0D,CA,0C,49,2C,AF,60,4C,64,04,00,48,C4,C6,A2,3C,44,2B,B8,9B,B8,47,4B,91,EB,32,38,37,A6,CC,64,95,83,D1,B3,1E,7B,20,BD,55,39,D8,4B,54,6C,B5,67,C4,04,D5,2D,ED,E8,C6,F9,FD,7D,81,40,3C,3C,6B,58,A9,7C,8D,68,A9,20,81,80,35,31,50,F3,DF,B0,FE,92,A1,2A,B6,D1,6F,7B,25,83,21,36,E2,D0,9F,49,F7,4E,3C,51,37,52,A1,20,B8,EC,E2,24,AB,01,85,96,41,09,CF,42,8F,D8,BA,3E,42,52,CB,81,A4,D6,7E,C1,1E,3C,F7,86,FA,E4,99,D9,52,96,38,9F,9A,A1,83,35,9E,86,9C,36,06,C9,46,59,14,69,21,4F,EA,61,A6,2A,3F,90,BE,9F,BA,ED,CF,AD,65,63,11,8C,44,4C,A5,89,6D,E7,D5,1D,4C,A7,BC,F8,74,E5,3B,6B,79,D2,06,C9,06,65,8D,22,95,74,16,29,B2,37,98,87,99,FC,24,D1,F7,55,7C,E9,0C,D9,63,97,02,F9,18,61,A4,E3,22,1C,26,19,CE,D5,8C,EE,A9,FB,44,4E,D5,3A,F7,E7,8B,C6,3B,3D,E6,30,D6,90,54,CC,3A,C2,49,56,76,BC,77,2D,B7,C6,73,67,96,29,9F,FE,A3,05,67,4A,1B,53,2A,F6,73,8C,8C,ED,D8,DA,93,8F,06,AA,36,23,B9,73,BE,02,39,D2,53,FE,EB,08,CA,9D,19,96,14,70,AF,EF,0A,CD,CD,4F,F8,11,D1,68,2D,CE,27,9A,6B,2B,89,EB,64,7B,EA,BE,AD,48,1A,6A,91,F2,20,22,AC,A0,C0,6A,E6,D8,64,7F,19,5E,5E,17,9B,DB,67,74,01,FF,0D,9F,E9,E6,A2,A4,23,C5,EC,98,95,3B,22,BD,68,20,63,B9,52,AF,68,6B,8D,BC,38,6C,63,DE,8B,4F,DD,91,57,DB,08,12,21,7B,E1,91,D3,B7,04,EF,53,FC,E5,D3,CA,E7,B6,CE,C8,94,29,10,5B,A3,9F,84,9F,0D,35,DE,6A,E2,B1,D8,C5,FE,0E,FD,5F,B2,07,D6,5A,84,E7,5E,74,7E,3D,9A,3C,24,AB,43,40,2A,FE,FD,05,D1,0F,7E,87,A1,7E,70,55,C8,E5,59,E5,CC,DC,D1,BE,B7,07,E7,56,98,C2,71,09,46,65,59,0F,BA,D8,17,A4,0B,94,CD,43,44,F0,52,0C,C3,2A,D5,D1,E2,B9,5B,03,B9,68,3B,6C,AD,0A,D4,FA,05,F4,01,B5,0C,79,CF,0C,78,B3,78,A9,BA,B5,CB,B4,E6,9F,DC,44,1F,E1,CD,E0,C6,26,1F,C0,A0,83,1E,8F,45,29,8C,64,B0,AD,AC,FA,94,1A,3F,84,3E,EA,33,61,F4,73,1A,CB,7F,7B,B7,AC,DC,94,D5,EC,FA,CC,92,C3,ED,EB,50,25,08,0F,7A,A9,EF,89,D4,94,5B,AB,84,D4,8C,98,64,E9,42,A5,C1,10,2A,48,5F,D1,C5,5B,21,A4,7C,2C,1D,3E,0B,B7,54,EE,54,54,3E,89,30,9C,C8,7B,30,22,5A,EC,C6,EC,FE,6F,B0,93,1E,FD,31,DA,4B,AC,22,B6,C0,73,72,93,C2,6D,40,D5,9E,9B,0E,5B,8E,38,0E,A1,AC,39,B6,E7,30,74,09,3E,D0,B1,FA,70,04,AF,8E,C0,81,92,C4,C1,92,EE,49,F2,94,BB,7C,DC,7B,A5,85,31,8E,F3,94,E6,79,46,AB,57,B2,59,43,C9,BC,0D,79,C9,59,86,BB,05,B8,F1,E5,9F,7F,CA,BC,DA,C8,CF,11,2B,EA,EF,5E,35,54,37,18,4B,96,8C,BD,0E,C4,9B,5B,12,30,B2,A3,32,AC,2E,C5,5A,42,87,1C,1A,A2,27,66,F9,7E,2D,02,1A,30,44,22,50,51,84,D0,08,E3,4F,7F,99,0A,CE,78,52,0C,BA,5F,9F,5F,96,8F,71,46,13,CA,7F,4F,06,C9,94,A4,58,0F,37,EA,46,4E,48,41,D2,6E,9B,BB,C2,71,10,51,5F,1C,76,07,F0,FF,FA,41,9D,6F,DE,ED,29,82,A4,69,54,1E,A0,95,1E,E1,9D,DA,8F,11,15,20,6E,0E,C3,BE,17,7E,F2,3F,65,90,A5,E1,E5,C1,4E,72,AB,25,A4,50,14,2A,70,0D,5F,5D,FA,E6,23,21,91,42,10,7E,33,EB,8C,66,01,62,C0,59,E4,2D,19,9C,5C,9E,2B,B1,6B,1A,FC,69,92,0B,D3,B3,1F,61,38,12,19,32,C3,2A,14,D1,75,63,8A,49,E0,19,78,D8,84,DC,71,44,D7,34,D9,D5,69,32,FD,23,F1,2E,10,1E,BC,76,0A,AB,33,4E,22,23,A3,55,46,43,79,96,B4,F0,05,3D,E7,73,0B,14,9A,3A,00,01,5C,7E,78,C2,19,17,C6,E2,28,9F,57,1E,73,39,4F,63,BE,02,E0,E2,AD,2C,60,44,78,D7,6B,CD,03,C6,AB,0D,7B,9C,16,AA,D0,69,44,9F,0C,F8,6B,DD,B2,AF,6B,E1,D8,D2,5E,EC,ED,D6,6F,FC,AA,9F,8F,AA,64,4D,32,94,39,7A,6A,A7,4C,CF,E9,B9,C1,09,90,61,7F,39,7E,1E,6A,65,9B,32,A1,A1,FD,4B,23,87,2D,AE,70,45,C7,0D,54,E8,D9,DF,E4,66,1C,ED,2E,CA,7A,91,3A,9F,62,AF,F4,A3,E1,FD,65,52,99,5D,1A,AA,04,55,01,4A,EF,F6,28,2B,47,8A,D9,13,7D,25,75,9C,D0,C8,FA,54,62,47,86,96,ED,8F,3B,38,BB,DD,32,C0,50,4C,E8,E9,F7,2F,28,47,B0,97,96,0C,74,22,4B,3A,96,D4,80,93,AB,30,AB,5B,3D,A9,E9,EC,BB,AA,9B,B5,50,17,37,50,AC,A9,0F,B0,EC,06,23,F3,1B,89,35,11,86,4C,17,5E,10,A1,B9,03,1B,98,52,D9,D0,A6,E7,58,25,41,CA,D3,84,A2,A8,3C,15,5A,D3,EF,3B,2F,EF,66,30,1D,9C,C5,DD,AF,92,1B,70,C9,96,24,25,4C,2B,10,35,91,AD,97,39,05,06,CB,D6,E5,88,0A,37,B2,91,D0,67,35,7F,B5,9C,48,86,DE,D8,D5,8B,D5,AD,2D,66,3E,3E,6B,30,26,02,7A,7F,EC,AF,1B,33,32,41,82,BE,03,19,42,CD,59,98,02,19,41,07,A3,48,E4,9A,34,61,AE,E2,21,6E,19,42,F2,AA,3B,42,1B,75,B6,C5,82,E5,E3,83,47,21,B0,5C,9C,79,35,20,24,C5,9A,EB,B8,23,84,CF,CC,2F,58,02,9E,97,20,FB,04,76,DA,6F,57,15,8A,34,1F,5F,39,12,D2,E7,89,70,CA,8A,90,9D,DC,47,5A,C6,80,8F,8D,97,4E,FD,C0,E4,64,FA,EA,70,56,8C,2F,81,41,1D,BD,7A,41,68,58,56,85,4A,C3,83,3E,AF,EC,8B,CE,28,7B,CE,47,0B,B7,DD,4B,3D,12,07,89,89,76,95,BC,75,C8,E8,13,C9,DA,4C,FB,FC,30,16,EF,D7,CE,0A,9B,64,56,18,D4,B0,CD,34,D1,F3,82,F0,33,95,65,B0,73,93,23,C2,89,DC,10,1A,14,87,7A,72,08,B3,2D,BE,29,4A,E1,59,3D,85,1B,57,87,E0,50,8B,D2,0B,8D,C7,0B,84,FF,9C,BA,35,3C,ED,11,B4,C6,38,D8,39,70,1F,BE,0D,E9,0C,FB,92,40,39,48,56,AB,0C,DC,02,3C,6B,D2,A4,C6,16,5A,08,2F,48,E2,83,29,4C,A0,63,AB,3D,D7,FD,09,68,63,5C,93,39,2B,84,23,C3,D0,D7,32,27,0D,B1,A4,05,73,8D,11,E4,E8,8E,BF,40,E2,06,B5,3A,7D,0B,B8,B3,3C,7F,CE,DB,A9,74,41,89,A3,AA,8A,3E,43,4D,98,1F,16,AF,4C,21,80,5D,8B,CB,FD,46,B7,51,5D,A2,94,25,24,8E,31,D5,02,05,9D,FE,09,FC,F2,F3,61,AE,33,DD,BD,D2,CA,0C,83,E7,2E,47,E7,FB,CF,23,5B,7A,6E,4A,81,9B,92,37,BB,B8,06,19,9D,CD,C5,5B,58,F1,B4,2F,D4,24,B0,4D,05,38,17,7A,00,EF,73,4F,D0,AA,38,01,5C,9C,9B,D8,62,D6,1E,EC,93,AC,00,67,6F,51,2D,04,A4,CA,EC,FF,79,07,82,61,E6,40,F7,15,76,40,07,89,DF,6F,C4,4F,0C,7D,50,A9,37,B6,3F,91,51,FD,AA,1C,07,BE,C8,DC,0D,C4,3F,69,2A,87,5E,EB,9D,90,5A,03,F8,85,11,37,89,DB,AE,2D,6B,1E,CC,A9,B2,71,26,2B,0E,9B,0E,E8,4F,EB,61,AA,AD,5D,54,F4,B0,41,DF,53,47,26,7C,9A,FE,FA,80,8D,96,6E,D4,36,7C,CF,62,31,B6,97,A8,FE,FB,3A,E5,CC,7A,B7,F6,FC,64,E7,A5,07,41,E3,57,DC,DE,56,7B,05,2B,7C,02,CA,E8,2A,2C,5A,45,64,3C,9D,B6,FA,BC,23,DE,1D,4E,9F,CC,AD,08,04,05,62,86,30,A4,C8,63,38,66,A1,CB,65,48,E7,FC,A2,FB,99,DD,50,EE,7E,30,55,0C,5C,BA,E2,5A,62,56,CE,11,72,6F,8E,F5,AD,E3,FC,DF,69,A4,FF,57,0F,A4,BA,64,51,AE,BA,3C,16,AC,75,54,66,B1,46,12,74,9B,1D,B9,3C,86,7F,82,5F,3A,46,7E,16,7B,B1,01,4B,C0,C1,3F,8A,79,89,BF,A2,7D,F9,EC,F5,B3,43,04,2D,A5,2F,B1,E3,9F,F6,9A,DB,98,15,E5,AC,82,54,50,D0,A8,F2,76,ED,BC,4C,67,8B,8A,6C,13,BA,D6,C8,42,70,4F,A3,49,A5,57,A9,97,E0,92,2D,A8,D1,49,16,0A,1B,9B,52,1C,2D,B5,F7,95,18,09,89,60,6F,7B,79,4F,18,00,92,23,C9,79,B8,BA,71,33,89,E3,90,22,BC,59,41,AE,BC,C9,DC,CE,D0,CC,55,BB,90,AB,D5,BD,73,4A,EB,36,9B,6F,E8,DD,F1,BD,A3,A7,3A,54,84,B2,A4,5C,A9,FB,C2,C9,71,DE,35,5C,F8,FD,BE,60,DD,4E,29,12,0A,E5,D3,CF,5B,D9,F5,F6,3B,E4,B1,88,16,49,8D,FD,73,80,F2,2D,54,AB,A8,F7,F5,E1,99,0F,EA,60,37,F2,4A,0F,07,D6,DC,5D,63,7D,56,FC,CA,61,D1,14,88,4C,0A,D8,30,79,C0,4C,87,D3,42,57,EF,A5,34,B1,79,02,FD,15,B4,FA,52,A3,1A,FC,F9,55,0F,F1,07,60,B3,E5,98,CD,22,72,7D,50,FA,C4,30,B9,16,45,3F,33,9A,1E,4B,ED,F6,0D,8D,7A,1C,57,2A,FA,22,91,D4,F4,10,37,36,CC,27,EB,79,92,77,FF,F2,C8,0F,4A,AA,3E,EB,E0,62,88,38,56,F3,48,5E,0F,2A,98,39,9B,F8,CE,15,63,2C,2F,32,18,F0,C5,EA,52,53,25,DA,37,B3,35,EA,25,AF,C7,0B,8D,43,8B,CF,56,A0,CF,82,24,C4,09,4F,E4,01,B7,DF,26,2D,AA,D3,E7,23,BE,5C,C2,48,7F,0F,95,CB,E0,F9,86,AC,E7,8E,DF,02,AD,78,3C,EA,61,E7,F9,57,C4,7C,62,8B,13,0D,E1,63,12,8F,B5,C9,27,7D,D7,9C,47,C1,AF,AB,1E,6B,13,2D,30,C6,1D,F2,86,DD,02,90,B6,18,27,E7,D2,EC,B3,39,A3,8B,DF,9F,55,8D,50,9E,57,C5,BE,3F,82,D6,B7,9B,EC,5E,21,66,56,7D,C5,6C,89,B5,8C,A4,ED,89,E0,C4,D2,6B,77,29,F1,0C,FA,58,D3,9B,E8,7D,CA,77,BB,82,F3,A7,4F,96,B8,05,45,7D,D4,A0,14,9E,39,98,85,47,E3,13,E8,A1,19,00,96,2B,AF,5E,3F,25,02,2D,F7,FD,F2,36,70,EF,E4,1E,44,91,58,48,A9,3A,97,A6,23,63,4A,AB,46,A0,71,9A,C1,4A,40,67,B0,55,85,90,55,E5,A0,B6,CB,FA,8A,1A,71,C0,56,1F,4D,14,48,1D,E8,E2,0A,3A,30,86,77,6E,74,B9,24,13,87,14,1E,44,40,9D,49,8E,3B,43,E0,55,F4,D3,74,FD,9F,00,E0,77,28,31,6F,98,7A,B8,1E,B6,DC,70,A0,A1,A3,C0,B5,E4,38,F9,56,54,AD,61,94,FE,A0,27,A1,5C,EE,92,D7,7C,A1,70,AA,3C,92,9B,C5,0B,44,A0,B4,A2,2D,7D,9D,EE,11,1B,6C,E3,9F,34,96,FD,92,9E,33,63,D0,13,8A,6A,6D,0C,5D,E4,7A,4A,D6,0B,84,20,B5,73,82,EA,EA,4E,24,64,B3,17,3D,0E,ED,1D,FD,9C,41,4A,54,56,75,D9,AD,2C,CF,2B,67,D9,87,6C,D3,C1,EE,CB,05,A3,35,3C,F9,63,E6,4E,10,55,62,6B,00,EA,2A,1D,FE,C8,AF,DA,EF,F6,D3,A9,9C,BE,36,C6,C1,12,0E,11,EE,38,92,7B,3B,EA,09,1E,96,0A,F4,FB,F8,99,84,0A,2B,EB,CD,1E,7F,CB,49,A9,95,C6,B8,57,2F,78,FB,3B,83,99,F0,9D,8E,67,21,26,60,33,44,EB,58,9E,2F,38,F0,2F,E1,F1,CA,15,96,BB,18,85,43,6C,93,AE,39,EB,D1,E6,98,1C,AA,8A,7D,EB,54,C8,01,E9,62,31,68,90,D5,68,7F,A9,C1,77,B6,1B,10,B0,9B,03,E5,FE,81,3F,DE,CC,38,45,6E,6F,AF,39,1C,D1,95,47,E6,7C,1A,DB,F2,EC,B8,9D,98,BB,7A,AD,FC,0A,2D,32,82,DC,72,DF,DB,9E,76,D4,0E,9E,23,88,F9,A5,AD,13,D8,8D,4B,E0,22,D6,D8,AC,42,9C,AB,2D,D5,9B,50,B8,F8,E9,85,27,91,07,20,ED,4E,CF,76,72,4D,7C,6B,06,58,30,E3,B9,1D,A9,DE,97,B7,0C,43,46,A3,C0,49,69,74,D9,EA,EA,9D,E7,D8,6E,3A,BE,A5,CD,45,1D,29,FE,34,25,8C,5E,07,49,1C,AA,1E,0D,29,1C,0A,84,75,2A,1E,5B,9D,91,3A,99,C4,63,10,FA,7F,4D,85,2A,63,1A,C7,FE,D3,63,72,C9,17,60,B2,D8,FC,AE,4D,80,17,85,91,FC,14,57,2D,EC,F0,4C,F8,6E,E2,94,33,A5,CB,16,45,9D,40,8A,05,BC,C8,E7,6D,9E,50,89,E8,5A,14,05,65,18,1A,1E,AD,69,01,2A,F6,0C,EE,C8,AA,2D,BF,A6,0F,A8,D3,DA,12,3A,76,5D,4A,18,C6,3C,E2,36,9F,62,3C,21,4F,48,12,91,B2,8A,E7,02,9A,F5,56,01,75,C1,5B,2B,6F,A7,A7,FB,B2,58,BC,D1,5F,9D,62,9B,4A,B9,70,69,76,F6,4D,03,C3,9E,DA,02,A3,91,C9,61,59,0B,4A,54,98,0E,89,8D,01,77,BB,F7,B1,9F,A8,37,24,A1,DF,DB,F6,F7,F2,9B,B3,97,CD,5F,65,57,91,5E,99,91,73,0B,B3,A1,B7,45,55,F5,48,DC,86,62,F3,40,1C,54,55,6B,4A,C6,C0,A4,BA,07,6C,2C,B4,D4,5F,01,65,E8,7B,1B,EE,05,8F,40,09,BB,81,86,C8,38,ED,C1,EB,09,43,13,51,CB,AC,90,0B,E2,24,F2,D3,0C,37,14,48,CB,29,37,7F,C5,52,9B,0C,54,1D,DB,F4,91,18,43,1E,51,4F,F7,13,0A,91,FC,35,01,0B,1D,8C,D6,A7,6D,B0,D1,C0,1D,A0,97,95,97,E4,4A,53,46,D7,6F,FF,37,49,76,31,5A,CE,AF,8C,04,91,A6,69,CF,61,77,76,31,7A,7C,76,FF,D6,EB,4B,CF,26,4E,52,EF,1A,B4,C8,39,24,D1,8F,04,A5,AF,28,DB,05,30,A3,C4,A3,23,66,0F,0C,27,2A,42,A1,AA,EF,9A,D2,D5,C0,F2,4C,E8,CD,C9,5A,C0,46,1C,B3,A4,AE,0F,A9,54,19,90,30,76,7A,5B,98,D9,8C,E3,F7,18,5F,18,58,17,71,17,B9,A0,56,C7,ED,74,DB,F9,EF,A3,C1,15,AD,75,47,53,0B,0C,F8,CE,7F,D6,1B,ED,55,38,34,A3,E9,65,1B,BA,B9,85,76,F4,53,C1,7C,18,38,6B,8E,02,39,8F,F2,F4,2B,37,22,5C,E3,58,11,01,EB,CF,CC,81,8B,8E,46,EC,DA,FF,1E,E3,A7,AF,EF,D8,86,46,D2,11,C6,83,8D,F0,F7,A4,E8,BD,85,A3,F3,E1,51,97,0E,BB,08,6F,7F,49,B1,3A,E4,E0,E7,29,06,DA,7C,73,D6,AF,DE,17,DF,D8,AB,D6,0D,97,9F,AB,53,65,54,A1,DE,F0,BD,9D,02,EA,38,2F,FD,7B,56,6F,FC,53,4E,9E,39,37,B7,00,86,61,8B,43,77,3B,7B,6B,CB,79,4D,0A,DF,1D,5F,22,00,35,B6,2E,8C,8A,86,77,14,DB,38,4C,46,83,A5,7B,0D,CB,94,9B,56,3B,DE,9F,BE,B8,9E,F7,63,8C,0F,E9,C4,D9,2C,3B,9E,A3,5C,3F,82,C0,F3,9F,1F,21,A4,21,60,C5,26,FD,B5,70,EE,A8,9E,00,1D,C8,0D,61,D1,15,1B,F2,3E,4B,19,3A,AF,6A,17,93,DC,6D,16,FC,DA,66,CF,BC,72,7E,BD,98,75,E4,3E,FD,42,55,03,72,FC,FE,C1,52,DA,61,87,82,D9,AF,CE,BF,64,EB,08,BD,7A,E8,AC,84,67,98,EE,DF,6F,FC,F1,00,DD,5F,2C,77,90,DE,85,A6,37,FA,09,AD,A5,68,CA,A9,6B,99,F6,9D,A5,B2,2D,32,49,3B,F5,48,96,E5,3A,FB,2D,F7,7E,48,B6,C1,1C,5D,65,CD,73,5E,C8,F8,43,E7,12,50,E4,4C,43,E7,75,04,36,5D,12,95,8E,6B,E5,79,83,3A,60,02,85,08,3E,27,9B,07,92,26,DB,3F,C1,5C,9C,AF,5F,5C,E8,BA,8A,C9,12,87,4F,1C,2A,ED,B0,7C,97,EB,B1,E4,F7,72,FF,A9,FD,53,D0,FB,5A,74,5C,AD,6C,5A,A4,4F,D5,8D,71,DC,04,A9,33,1B,55,5D,2B,28,33,D5,69,56,37,0D,1A,27,27,B9,EE,88,60,22,96,C7,DF,D5,11,1C,64,7D,97,1B,FA,01,74,61,33,3D,25,64,EF,C7,05,42,CD,DC,7E,B2,61,83,1C,64,3B,83,BE,F1,93,E2,02,4B,19,61,6D,E4,3F,63,9D,1E,4D,A4,13,E0,10,40,7B,79,1F,0E,F5,9B,72,25,FD,14,81,43,DC,0A,14,2E,0D,CE,AD,2E,90,D4,AF,D3,97,7E,D5,72,C4,27,2A,91,3C,E6,F8,EC,6A,BF,55,89,0F,6A,2D,C4,E9,32,A1,FB,74,E1,E8,24,14,16,EC,3D,16,E1,7A,2D,FB,2E,87,F6,0C,B6,E6,E3,76,9A,90,40,9A,BB,E4,CB,5D,6A,CF,D6,6A,8B,78,27,50,1D,FA,77,D6,8B,C6,57,32,9B,F7,14,8F,13,E8,B0,A3,75,1E,01,86,00,77,97,3C,D3,23,D8,AB,51,A3,2C,49,11,46,43,49,71,48,9B,B8,E8,E5,89,24,89,F7,1F,7B,77,21,7B,21,D7,62,D6,8B,54,D9,C8,F3,5F,C4,39,28,3B,18,96,80,AB,A5,3C,74,40,60,00,1B,A2,8F,61,01,7D,B7,CE,B5,54,5E,BE,B0,64,CF,CF,B3,E3,66,5C,D4,E7,E5,24,5E,B0,08,C2,0C,82,D3,EF,D7,B0,9A,92,44,2C,A4,D9,8C,CB,67,93,8B,B0,7D,0D,5C,4B,A0,EB,80,FB,55,7E,81,E9,6F,A7,83,D4,F8,E7,CF,6F,8E,DE,02,1D,E8,6A,FE,43,92,C1,DB,1E,1A,43,49,FB,65,3E,A2,3F,76,93,CE,C3,FD,96,F9,17,F8,EA,00,1A,EE,CE,1E,E8,2D,15,45,B3,58,04,60,09,30,72,C8,C2,AC,21,7A,25,25,CF,09,5B,FB,6E,C7,2E,89,FB,C4,F2,CE,F6,E4,8F,AA,BC,A4,09,B8,CF,20,9E,F3,0B,53,8A,0B,07,F9,CB,3E,7D,00,12,B6,A9,3E,93,1F,83,88,87,02,67,D0,C4,64,C9,F9,7F,74,EA,EC,06,E1,47,C5,85,8D,2C,D2,28,A8,FC,75,43,A1,E8,CD,6C,5E,52,21,1B,E5,C2,53,B1,C9,C3,98,7C,F1,03,74,DB,14,83,04,0B,27,F5,F9,37,8B,58,51,86,2B,69,1B,9D,FB,49,59,B6,C8,A4,DD,2C,8C,01,25,71,9C,DD,64,11,95,05,69,2B,95,62,CC,F9,80,0B,C1,C4,9B,46,4E,AA,41,90,70,93,31,B3,7B,6C,ED,47,09,D8,F9,43,7C,FF,39,ED,5B,7D,52,A9,23,9E,C5,DE,3B,0E,A1,0F,3B,53,1A,E1,F7,50,E0,FF,FB,FE,3F,DB,3A,9F,5D,F5,50,92,7D,92,75,32,99,8A,84,B3,D3,45,7B,9F,5B,AF,77,67,12,B5,3E,0E,B1,25,46,CA,15,35,63,99,8C,44,61,1A,64,0E,F2,24,34,12,D7,C4,3C,50,D8,08,1B,F8,75,30,A1,74,E7,5A,36,A1,00,0E,B2,1B,2F,BE,E6,78,3C,F5,05,40,79,D7,DC,4C,1E,5D,E5,92,ED,0C,D6,5C,7E,28,E1,35,EB,EF,8D,ED,E9,17,E3,4E,B1,D5,36,90,01,13,67,37,19,33,FE,EF,3E,6B,AE,06,81,9D,B2,D5,19,39,31,EA,AB,5B,30,E9,C1,C4,A8,0B,A8,A6,F2,EC,54,0D,D6,0F,31,C8,26,6F,EE,93,F5,A2,0C,80,CA,9A,77,F4,C7,C6,86,C7,DB,5C,F2,E0,A0,9C,2C,84,C7,13,BF,16,9E,03,6B,D8,40,8D,85,05,0E,3E,4D,87,FC,67,9B,F3,5F,60,A1,19,AA,DC,9C,04,B0,E5,89,80,AF,B2,5E,C2,16,BB,0D,0E,F5,1D,17,59,DF,01,14,B6,54,8B,F2,13,66,9C,27,49,51,53,CB,6C,A5,9B,3C,B0,4B,43,88,E0,86,12,6C,64,DE,07,4C,20,3F,D1,50,E9,73,3A,A2,2F,87,B5,D7,AE,87,24,D0,80,4C,A8,3A,2B,66,30,68,36,25,CE,4C,BA,94,7C,41,7E,A9,D8,82,C5,90,07,1F,28,2D,BE,87,72,A3,FE,03,68,B1,A7,AB,33,BA,3E,75,7B,41,EA,4F,B9,A6,C3,9B,1F,CC,E8,CF,52,BE,F8,98,FC,97,51,72,4A,37,C3,D4,8F,BE,C7,56,46,AB,B4,5A,DF,32,75,65,9B,C2,6E,F4,A2,85,DB,EA,11,C4,CE,CF,98,D9,63,74,F7,AC,93,0C,F0,E7,CE,6F,F0,94,68,7E,E3,7D,7B,C4,2D,15,C2,AD,E1,40,05,3A,E1,18,E9,23,72,80,62,3A,6B,EB,30,8A,F9,AE,11,DA,42,AC,DE,12,2C,61,9F,2E,36,58,F9,CC,63,D0,2F,1E,73,F9,B9,5A,E9,BF,DF,ED,22,5B,EE,E4,02,25,A9,2D,94,DD,BD,31,15,09,1D,33,D9,32,61,70,F8,C9,CD,8F,B0,F8,F7,AA,A2,79,00,F7,88,AF,D5,41,9C,60,7E,3E,BE,60,72,B8,11,3D,E2,0E,DD,22,57,05,30,C6,2E,E7,3E,D4,2D,75,C6,43,7A,58,FE,56,4E,0C,1D,F2,8E,A4,B5,B3,4F,BF,D2,61,0B,98,CA,B7,4B,87,6D,DB,C7,15,9F,BB,00,F4,B2,86,8A,56,05,90,A6,6F,B4,3B,99,02,90,9B,81,0F,A2,37,B0,1B,08,CF,89,0F,46,95,63,2D,C5,A2,DF,E3,37,21,D2,01,23,B4,90,D6,E7,8F,C6,55,57,E1,AC,A3,E2,5F,F5,22,64,24,D7,AE,87,B1,DE,9B,E9,AB,23,1D,A7,09,00,E3,6E,7A,87,32,C2,BA,90,48,65,21,79,8A,D8,A6,D1,C5,F8,57,1A,F9,23,1A,1A,D3,9D,72,37,B0,5F,79,20,97,E1,9C,5D,E6,24,6C,16,1B,41,5C,55,58,D6,30,55,E1,D5,19,4B,C6,16,5A,31,13,8B,DA,AE,3E,7D,FA,B8,2B,F2,08,56,7D,75,7A,5A,F9,2A,FA,3D,8D,40,9E,62,04,50,51,0C,74,1A,DE,46,FA,A4,05,01,A3,86,14,32,37,1B,E8,86,F4,A5,D2,92,5B,91,3A,36,E8,6E,89,44,C5,D5,99,D6,80,6D,ED,DC,F6,DA,77,80,25,13,2B,E5,FD,59,9E,6D,83,72,F5,9E,ED,F3,62,0F,83,03,5C,FD,6E,D9,80,C6,D0,5E,93,E7,0D,4D,A8,17,D0,99,27,5E,54,DD,0D,5F,6E,BD,4E,9F,A6,FC,37,B4,B8,A6,C3,5A,8A,42,35,6B,DB,63,F7,16,2E,34,5D,F4,44,DC,40,C4,CE,7B,FA,F5,9F,4F,CC,6F,AC,F6,10,A0,8B,0C,E6,70,95,CE,37,FD,34,50,04,DC,B2,FC,2C,3F,AB,56,C2,C3,05,40,B3,04,D9,AA,24,F0,29,9A,C5,EB,08,EE,E4,FE,FC,47,95,B5,C1,28,9A,11,07,ED,F6,AE,A4,7B,32,9B,7A,C3,40,4B,05,D0,84,07,62,60,25,08,CE,98,DA,0A,CF,47,F7,AD,79,07,27,62,40,C3,0E,16,37,50,ED,4E,BD,7F,F7,01,74,9E,9D,02,1A,20,50,01,EE,08,E5,AA,07,A1,23,3D,CE,66,9D,BB,AA,F4,3B,7F,87,89,BD,3D,11,E5,FC,43,CD,CD,8C,0C,05,9C,66,BF,EE,21,0C,A7,A6,A4,6F,D2,43,BD,FC,BD,C2,83,86,C4,15,6E,9D,77,50,C0,CF,97,15,84,10,B7,9B,86,F1,80,84,7B,9F,F1,7C,DB,21,E2,A9,00,EF,11,1C,DF,BF,C7,CC,B4,C8,03,FA,8C,2B,82,81,04,61,EC,D5,7A,CB,59,E5,8F,2C,F3,08,3E,55,B8,64,03,9A,02,C5,16,28,E1,90,05,DE,F2,5A,FF,18,F9,53,FD,71,D4,B5,A8,D8,C7,AD,A6,61,5A,F0,A9,3F,F5,7A,7E,33,BC,24,78,E6,A5,5E,8A,28,27,E4,87,60,B7,35,6E,5F,DE,DB,BD,DF,31,9D,B0,B9,E3,32,E8,8B,CC,8B,60,73,1C,ED,77,A9,51,00,30,42,5F,BD,4A,AF,04,C2,C8,BF,E4,4D,91,AB,9B,CE,63,E5,AB,98,38,4C,F0,75,4E,BB,AC,61,F3,D0,79,FC,6D,9E,9E,6E,31,D4,85,6B,1C,2B,E2,60,08,E3,81,58,5B,4D,85,EE,B0,76,03,6B,44,A9,72,E6,D2,63,BA,68,5D,B4,2F,3B,B6,EA,10,B3,C9,1B,7C,49,AD,42,8E,56,B4,5B,02,8C,AF,CE,A3,CF,DA,BF,FE,61,F2,1E,4F,A2,E0,D7,9E,F3,E2,C5,58,EE,AC,6C,66,DF,7B,BC,10,B7,B9,49,98,A1,3E,B6,AC,48,DE,ED,84,CD,4A,7C,19,4D,4E,FF,2C,C2,04,BA,8C,7D,22,92,CD,D0,93,DA,A8,A0,08,2D,1C,B4,81,7C,C9,C9,C6,6C,39,6E,A3,2B,69,07,EA,2D,DD,E9,68,12,B0,41,64,9E,76,BD,05,DA,48,31,74,E4,7F,A9,61,39,6B,D8,ED,B2,A0,8A,86,86,D3,BD,D4,17,7B,78,E2,8F,B3,F9,6D,9F,6C,E2,D9,A7,E4,DB,96,0C,36,95,EC,1B,BC,38,7B,07,C1,2E,4C,21,DF,10,E5,A6,89,AE,ED,06,3E,80,A1,8E,F1,F8,29,8C,E4,08,51,D6,A1,E7,7A,2D,3D,C4,BE,00,BC,1D,5E,96,55,79,C9,E5,DB,0C,66,B5,60,7C,08,EC,A4,42,40,CA,FD,AF,B9,74,01,E5,4A,30,85,6D,95,21,78,0C,85,82,3F,D6,04,CC,1C,8D,C7,60,E5,E8,FA,2E,B4,F4,B1,FF,97,C5,30,77,7C,C8,CA,53,CC,E1,5C,FB,7E,FF,6B,C6,C7,4F,EB,26,18,A6,1B,7F,E9,67,97,22,F0,5F,44,65,10,60,55,A0,9F,14,D4,8A,2A,35,B1,29,79,62,AB,1B,BB,BF,FC,3B,C7,C6,8D,DD,21,EC,24,63,04,A6,71,C6,10,5B,91,C5,CF,6D,30,A3,E3,71,17,5D,DB,0D,6C,33,1E,A6,86,AD,D5,2C,5F,E4,56,C4,97,B7,F1,CD,4D,62,28,4A,8F,F0,57,F0,3D,99,82,37,FD,7F,25,91,FF,D5,AA,A3,A2,B4,92,09,07,15,D6,90,B2,E4,9E,A7,A2,18,A8,B7,0E,41,75,B3,1C,9B,7B,6A,0C,49,FA,1F,35,FE,E4,E9,0B,9F,43,35,47,B4,D1,7E,88,45,65,39,D2,A3,69,73,58,99,EE,51,CB,2F,05,E5,55,9B,BA,92,EC,75,47,BD,EE,2A,25,9D,0D,27,C0,13,52,78,40,CA,15,18,1E,D8,1A,63,C3,9B,63,4D,35,E8,9A,4F,1B,79,95,4F,A5,4F,0C,A4,5B,15,F0,E6,54,E3,95,43,83,8D,64,AF,EC,0A,6E,98,B7,26,E7,E6,F3,88,87,99,3B,FF,89,2E,9C,89,7D,22,83,C8,0B,81,AF,77,7F,10,BC,08,D9,8B,92,32,5A,AF,3B,0A,FC,3E,87,A6,FE,4D,31,1E,77,27,2C,F2,2D,CE,48,A7,64,01,B8,6C,8F,07,0A,B3,3D,0B,37,05,A8,33,20,73,A9,92,35,B5,EC,04,72,11,0B,0F,E9,78,20,E3,60,66,C2,AB,62,59,C5,AB,AC,B9,1D,23,86,FC,AD,26,DC,09,E1,89,93,BC,18,CF,AD,71,0E,53,39,FA,47,BF,39,83,F3,73,25,1C,C0,18,D1,73,AF,9B,30,A1,68,9C,78,C6,F9,E2,E7,82,76,78,83,3E,31,A2,77,DE,4D,F9,5A,B1,FC,4A,75,E3,C7,EE,4E,E0,2F,7D,EF,1E,22,66,EC,1A,80,98,09,10,6F,BA,49,91,2D,C6,46,E7,0C,16,7D,83,A7,0E,54,DB,8A,D7,08,32,AB,BD,08,6E,25,D9,78,EA,75,F3,0F,BE,98,02,29,CC,10,7B,74,1C,5B,56,E2,5F,D7,03,18,FE,57,26,FB,E6,08,DA,47,F6,E4,48,1A,E9,B3,00,0C,60,45,B6,FF,13,6D,4B,DB,6E,0D,8E,60,8A,46,03,6E,25,3B,BF,3C,DE,C9,7D,6F,64,0C,15,A7,C6,72,3B,C9,81,F4,70,D5,9F,0E,10,AC,BA,D3,54,30,32,23,74,73,DF,9E,24,E0,24,6E,EA,D9,15,1A,C7,46,51,EE,B7,1F,1F,FC,33,1B,1B,26,A6,23,0F,33,17,4E,12,CF,97,0F,A4,3A,0F,E9,2E,21,43,7D,31,E5,C9,AB,5D,E6,AF,03,A9,E1,DB,B7,36,5B,3D,0F,8C,D3,E6,D0,44,24,8E,6A,4F,FB,09,EE,25,8F,DE,F5,A8,D6,51,93,00,4C,1C,65,7A,DE,92,82,56,0C,FE,BA,DF,65,5D,1A,BB,6B,2B,DE,44,6D,51,31,F9,50,C0,D3,CD,9A,C1,F1,43,B1,B9,42,CD,4A,BB,C3,06,24,43,3E,81,3F,8F,16,22,D1,A7,B7,70,0C,77,F6,47,14,F6,41,5E,C8,28,57,8E,05,89,49,52,58,CB,51,F9,CB,F1,1E,43,22,9B,98,5C,6A,2F,33,30,4F,C5,A8,79,CD,3B,C3,0C,F5,0A,B2,02,6A,9E,5F,BA,C4,DF,32,36,65,89,94,51,4A,5E,BC,BF,99,3E,05,1F,F3,03,DD,F2,90,5A,1A,7E,71,9D,0A,A1,59,56,95,C5,99,C6,D2,66,84,1D,50,EC,E2,E8,97,A2,1C,25,76,65,77,11,B4,78,F4,48,AA,CC,6D,14,E5,A8,CD,9E,47,C1,EB,76,21,F5,2D,EE,FD,A4,E3,BC,B2,BE,7B,3F,A5,C7,7F,61,50,B1,E0,1A,47,88,71,19,AA,88,83,2A,AA,0E,4B,4A,19,03,50,05,78,D3,C9,98,47,98,5D,84,C8,B2,78,AB,F6,39,F6,EB,ED,9E,0B,21,9C,38,4D,0A,63,9B,7D,FB,27,9E,0D,20,47,C3,FC,03,FE,35,23,65,90,1A,E8,75,46,3B,33,C6,25,35,A8,2F,38,AD,A2,7F,15,00,55,34,5C,54,C5,14,A5,C4,A5,76,A1,97,6A,E5,48,E1,EC,8E,5A,55,07,8C,F1,BD,13,EC,2F,6D,5C,13,E7,DD,59,2B,00,2A,E2,F2,81,65,54,BF,58,22,90,C7,4B,EC,25,52,5E,51,33,A6,F9,D7,E1,8D,F0,19,CF,D2,B3,9E,D9,BA,CF,BB,3B,5A,6B,B5,66,AE,D2,B8,96,EE,B9,B0,44,50,4E,E4,77,5E,E5,E1,F4,BB,58,74,5F,69,A0,B5,16,ED,71,EF,45,1D,31,31,6D,E6,FC,6F,1F,D5,83,6F,65,FE,14,1A,D3,9F,7F,9C,1C,38,0B,D9,0F,20,8A,BD,9D,2A,BD,45,B4,8A,ED,7D,63,2D,54,86,28,5B,27,E1,8F,EF,CF,ED,DE,85,79,B5,FF,50,C9,F5,F4,95,F7,30,E0,68,5B,6F,C6,FF,D6,FA,76,90,B1,BC,22,36,CB,20,82,40,91,BD,63,BB,D3,FE,18,7C,0C,C5,62,00,16,2A,68,E1,F6,8A,C5,24,B7,B0,6E,7D,FE,3A,C3,44,39,BC,33,31,23,41,29,A9,A9,12,34,21,34,43,4A,5F,FF,16,77,25,C3,FA,20,92,D5,5C,80,DD,01,BB,94,C7,E7,25,4B,1B,3D,A8,23,38,CF,89,1A,35,0C,74,CF,9A,5D,79,3F,D8,EF,55,97,CE,F2,0A,1B,D3,C8,59,0A,EC,22,CF,55,BF,51,9B,66,19,F6,FE,85,AE,7B,48,91,58,E9,02,7A,08,D2,41,23,F7,37,B9,AC,12,F2,3E,71,2E,B8,FA,6F,B4,A5,F3,27,77,4F,3D,88,9A,FD,C4,EC,3D,AC,D3,9E,4E,AB,03,27,44,3F,84,A7,74,F5,3A,E1,90,82,85,8F,BA,F4,E3,F3,B1,D8,0D,35,50,7B,68,26,CA,BF,48,73,54,64,CB,8D,B8,62,B8,DD,75,1F,63,FD,80,6A,CA,C5,DA,D3,F3,6D,E7,B6,CF,62,A4,D8,37,C9,10,69,E5,13,D0,92,3A,1F,A4,13,7A,4E,19,34,67,79,27,74,AE,41,08,2E,87,16,DC,08,BA,BC,1A,F4,4C,44,73,E7,75,8F,CB,7A,9E,C5,29,42,CA,EA,9A,1A,91,30,83,E1,99,AC,19,D5,43,41,52,94,C6,07,88,A2,CF,4D,14,AD,79,E2,FA,43,1D,A9,7B,74,50,25,D5,F3,AD,3E,1F,D3,94,8B,88,EB,52,2D,A3,ED,7E,AB,CD,75,61,B9,19,B4,55,07,00,5A,FC,E8,18,60,AD,C9,53,79,2B,62,E0,46,8E,84,96,70,22,DD,EC,95,D6,FD,DF,A1,74,61,60,AB,35,95,0B,DE,D5,B5,C2,81,08,06,A1,94,2E,C0,D1,BA,A9,90,86,29,78,70,A0,4C,07,26,83,82,11,18,74,D6,01,EB,E3,A9,EB,B0,2A,FA,FA,07,BD,37,1C,CD,10,F9,05,AC,7A,D4,70,0C,53,A6,3C,B1,B0,98,B3,89,6D,08,44,30,93,A6,D9,93,2D,CE,3C,D4,E3,34,2B,45,F1,63,BA,F4,89,00,BB,B2,62,87,1C,FA,12,08,4D,BC,79,DD,34,90,C5,81,BE,69,B5,53,34,77,FC,84,C3,C8,AB,D6,CE,22,5C,AE,B7,B9,58,2E,E3,54,A8,D9,66,03,5C,BE,59,56,DF,5E,7D,E2,29,CE,EF,8C,E6,D0,0B,F7,AF,0D,63,0D,26,2B,ED,FC,C9,85,36,09,C1,B7,5F,4F,E0,A5,8C,4D,BD,A8,48,D6,3A,AB,71,08,1B,D2,D5,2E,AE,CE,4F,F7,6D,B3,DF,D2,C3,21,B1,F0,73,76,4B,5D,06,5E,76,A4,EB,9F,6B,59,0D,12,F3,B6,CD,85,C0,0C,3C,B0,56,9E,81,72,76,21,A1,AD,2F,15,A6,9A,88,00,82,19,4A,9E,BC,77,DB,BF,7F,5F,A4,43,23,E9,CF,E7,A6,75,23,EA,F7,52,F3,1E,12,BF,92,A2,AF,01,BA,AC,93,B3,2F,5D,5F,8F,10,B7,A5,0A,5F,92,F4,90,C1,64,35,32,21,5B,9A,81,07,02,03,D0,09,97,35,95,B8,87,B8,DC,C8,46,21,CE,66,08,C9,A7,8B,82,5D,38,2B,68,EE,DF,C3,0B,40,20,2A,AF,87,08,F0,8F,E7,84,13,B6,A7,14,94,3A,0A,BD,80,59,A7,E5,6D,CF,DF,2D,29,0C,28,7B,C8,08,71,2D,A8,88,A4,AF,DA,78,7A,0B,65,1E,A4,DE,52,D6,51,0C,5A,AD,84,7E,E7,F9,FF,55,14,D1,A8,A3,13,68,19,25,11,3F,A6,B8,02,B5,FF,1E,A4,87,68,67,F8,A4,AE,67,D0,17,6A,21,F4,D2,2C,ED,22,35,C8,C6,F9,99,60,31,66,A5,B5,6D,AB,97,E4,98,5A,41,A3,E2,AE,A0,91,BD,8D,90,EC,2B,BE,0C,15,39,45,89,9D,0B,0A,78,43,0D,07,19,AC,A5,F2,89,EE,41,52,FB,D3,9B,68,B0,E0,FF,B3,78,64,28,30,92,28,26,16,51,67,38,0F,24,BA,2B,5E,3E,E2,22,B6,30,31,D6,84,A3,9D,32,8C,1D,B7,C1,23,36,C0,C9,BF,8F,36,CC,24,8E,B2,29,DA,F6,E7,00,9B,71,F4,B4,63,0F,11,11,85,BD,AE,DD,EE,93,D4,3F,4E,53,09,15,BE,75,E7,C3,84,8E,18,EB,3F,F5,F3,82,B8,DC,4B,D7,28,D0,B3,80,58,A2,D9,04,03,C1,47,61,D0,73,E3,87,1F,1E,E4,C8,1A,BC,F4,50,2C,E7,82,04,D6,67,25,9F,D8,A4,68,65,9B,AF,52,82,51,87,C4,BE,C6,9B,98,A6,D9,05,EE,34,9D,D0,65,68,AF,D8,18,1C,D6,66,EF,B3,31,11,B7,35,C2,7E,41,78,E7,F1,D6,3F,C1,36,29,28,22,B6,5A,E9,60,74,39,77,4D,EC,9C,D3,62,D5,8D,90,94,A4,EF,3A,CF,8F,61,76,24,1C,5B,0F,A7,5C,9D,D5,B5,FA,64,E0,DF,C3,F5,D5,9E,CF,14,FE,8D,9D,FB,C9,E0,37,D6,2B,3E,C9,C7,B1,4D,90,65,5A,62,83,78,23,CC,20,C2,A2,FC,64,F2,CD,B5,87,6C,3E,B2,55,E0,CB,DB,06,59,A2,4B,C1,96,46,96,71,6A,4B,88,6F,70,7B,40,75,F9,54,82,CE,3C,F2,63,EA,57,46,8F,60,C3,FC,73,0C,9B,69,25,70,74,BE,B7,06,04,C5,B3,5D,10,E6,3C,C1,03,6D,90,D0,4D,AB,6F,5B,99,1E,70,69,EC,0A,B0,C6,63,73,96,04,C6,8F,5F,2F,1B,E7,8F,44,86,09,A8,16,2F,6A,E7,F9,27,0D,90,F6,F1,13,83,F8,D2,89,FE,E8,1D,16,55,E1,B6,02,19,19,6E,97,B8,CB,0B,4A,0F,61,FE,F4,29,B3,A0,F4,B2,B9,D4,AB,18,19,EF,F4,C2,33,50,38,E9,11,5E,F9,36,36,9E,55,CB,E2,43,FE,5D,D6,D2,2D,3A,77,D5,1E,65,48,F6,AA,05,9A,DB,18,28,1D,C8,20,CC,42,05,14,5F,64,24,B3,5D,BE,4C,7D,0B,B1,85,DA,C9,87,66,D8,AB,82,DB,19,21,4E,B2,1C,91,1C,CE,D6,25,2D,26,5D,8F,64,BF,EB,D6,C8,36,85,52,DF,52,34,22,AA,55,E7,34,12,B0,F9,9D,F4,A9,B4,31,FB,7C,91,98,2E,D3,36,8D,55,81,CD,7D,E8,8D,55,19,58,F0,1B,1E,85,0A,9E,91,4C,06,F0,1F,F9,1E,22,0E,98,94,B4,76,D0,16,57,FF,1A,C6,0C,0A,9A,18,A5,F4,85,C0,33,4E,D7,93,3F,41,9E,18,69,7E,41,0A,AC,27,5A,FF,54,BE,3F,C5,78,A9,60,90,08,CE,9D,DD,6D,7E,5E,58,4E,3E,B4,79,4B,75,4B,E0,09,1C,4E,52,B9,BA,0A,25,4C,47,8C,00,0F,47,7D,99,A8,F5,1F,0D,E8,C9,2E,42,D1,8B,BF,79,E1,E4,0C,A7,3A,95,EB,09,EE,58,A3,50,89,56,71,64,30,C0,9E,54,59,B0,19,03,67,8A,41,EC,70,F8,DB,55,A7,B4,13,37,A7,18,70,6B,21,C9,35,4A,8F,E2,7F,EF,47,3F,F6,77,B2,A2,75,36,9A,57,25,B1,A1,67,54,73,D4,3A,68,72,E3,69,D6,1E,15,01,84,79,7E,54,9D,74,D7,15,11,D2,C8,D4,7C,A4,86,BD,90,9C,11,6C,F6,53,CB,4F,EC,EA,79,FF,10,8D,E5,F4,FC,6A,FB,2F,AA,2D,20,20,FD,1A,CE,3F,7B,F3,97,E4,C8,ED,C8,3C,46,B7,04,AB,0A,DD,C3,42,A9,02,1F,75,1A,AF,C2,2A,FB,BF,D2,7C,A0,50,B4,CF,C1,9D,3E,61,51,8E,C3,6F,38,F1,81,05,21,D5,5E,83,3A,0C,A3,11,72,B1,71,0B,C2,74,51,B0,25,49,30,FB,67,F3,E7,22,2A,EC,94,7A,4E,B3,D9,DC,4F,0E,7E,26,FD,AD,3A,F6,AE,D1,F6,01,36,BF,7B,2F,31,00,06,97,97,49,62,B7,34,3C,6B,A0,19,2D,A5,93,D0,8B,A9,65,2E,61,19,9C,E4,C1,CD,E9,98,CC,60,D1,DD,84,89,20,58,31,72,DB,3C,CC,26,87,68,39,DA,31,FD,52,4C,A5,DB,B0,4D,51,4F,EC,E3,42,DF,21,E2,9E,73,C5,FD,4E,3D,CC,2A,D2,77,B5,18,2C,43,14,20,B2,E9,FE,1D,0D,6E,09,90,6C,7B,6D,7C,F3,58,BB,FD,FF,1B,22,4F,B9,CB,B3,12,38,69,1E,C6,9D,16,C2,28,A0,36,B9,15,51,FF,6B,F6,D3,F6,83,D0,0F,6C,1D,1C,DF,46,1B,D8,F6,C1,C9,C9,60,FD,EE,FE,D3,57,B1,9D,06,95,2B,A5,56,FF,94,59,44,4F,BB,D3,A0,6C,68,96,A4,F5,39,43,8A,10,EA,9B,09,5C,7C,B8,4D,DA,F8,FD,67,3E,14,10,60,14,A3,10,1E,DD,D9,69,5B,33,9D,F1,91,DF,36,BB,9E,43,C8,38,20,50,DE,88,86,D6,BA,6D,AD,43,2D,3B,0A,A9,88,FD,4B,35,3B,BB,83,36,7C,78,15,C6,25,D3,59,05,DA,58,06,6F,A7,D7,91,65,DF,EB,26,3F,DA,97,C6,36,87,FE,89,D5,42,A5,77,D3,71,C3,2E,91,FA,FC,CB,C8,5D,6C,0E,26,EF,38,16,5F,60,33,AA,C4,44,C4,74,FF,7C,BC,7C,C8,13,4A,35,4B,BB,59,10,61,A8,22,A8,12,5D,6D,9C,EB,BC,83,5A,BE,FA,B3,87,82,97,F1,B9,2D,A9,AE,CB,59,BD,38,B8,9E,A9,FC,BD,3C,FF,59,5F,12,67,C3,59,44,54,E3,D2,FE,4D,D8,13,83,C4,09,69,13,34,2B,0E,BB,20,75,8B,FA,DC,0A,94,DA,1A,20,A7,F8,A2,85,C7,03,E8,8E,E9,A5,3D,3D,C6,8C,29,A4,E2,6A,7A,3B,78,12,F3,44,6B,D5,7E,A8,06,59,92,AE,E3,30,2D,A6,1C,55,A2,95,96,48,1D,C7,E7,A3,10,86,0F,C7,75,15,4D,1E,FE,35,37,F5,98,C5,8D,D4,94,C6,5B,1F,5F,68,48,A7,BB,23,92,E3,BB,F2,4E,73,EF,7D,73,2E,8F,B2,E3,3E,CA,4B,3A,1F,30,6B,99,93,F0,03,20,1B,2B,DC,7F,72,B5,7C,8A,36,74,2B,F6,B2,56,FD,1F,FD,7F,95,0A,61,50,E2,D3,FA,8E,50,3E,2F,61,C5,C7,DA,F1,F9,12,54,94,A2,A3,61,D3,8B,4F,B8,4E,9E,73,78,D7,2A,2D,7F,40,44,60,A1,9E,90,1B,85,A9,56,7F,51,62,4B,33,F6,BF,55,D7,EA,BC,FB,2B,AB,DE,8F,B6,20,0E,4C,1A,F4,45,50,DA,4A,F4,7E,5D,0A,D9,F8,82,ED,D5,6D,1C,C4,12,ED,17,FE,EE,FC,EF,C2,82,BC,CF,80,CC,AC,72,20,AA,81,E9,3C,9F,BA,C3,91,B3,41,C2,55,08,FC,2E,C5,AB,28,35,15,F8,63,D9,28,54,A5,7C,9B,E9,84,B3,3A,A1,9E,2E,B7,38,57,4D,68,C9,4B,FE,86,E0,96,10,BE,56,33,3B,A6,E3,50,B5,30,5F,A3,FD,C1,FB,D4,48,F5,E7,3F,A9,FA,51,31,AD,58,D6,29,19,B7,AF,B5,F6,16,8F,16,86,E5,4B,6A,61,47,99,55,FE,E8,C2,5E,BB,C2,48,78,2D,EE,CA,7B,FE,B9,24,EA,76,BB,6C,67,5D,A6,1C,59,5E,66,7C,12,11,57,89,FC,7F,AE,20,16,9E,79,EC,08,E8,E4,6D,23,B1,9F,E7,88,A7,5A,91,1F,30,75,9B,77,78,29,32,87,66,3B,91,3C,F3,1D,D1,8E,7F,DB,AA,7D,A9,43,82,1F,1E,12,4B,70,F8,13,9E,F7,9C,2B,CC,E2,83,6E,60,BB,C9,31,9B,AB,55,5D,EA,A9,90,20,24,5D,5F,18,EC,2E,60,2C,E9,28,E9,4E,9B,E3,75,63,8F,AA,52,3F,14,E2,26,FD,82,71,E6,2B,6E,65,37,9C,8D,54,E4,66,D6,D9,31,A6,26,2B,4B,5E,3B,E5,27,D2,1A,AE,C6,2C,AF,EA,70,B4,86,0B,79,CA,CB,FE,D9,26,CC,C2,5C,07,F0,F7,F8,35,E8,03,1D,D3,9C,5B,47,4A,A1,47,C6,0B,CB,AC,45,EB,E2,B7,49,58,2E,7E,02,C5,BA,CD,88,8B,5C,CB,73,14,79,4D,58,10,59,3C,10,4A,72,C4,50,51,FF,F6,4E,5D,D4,7F,99,BF,27,BB,33,E7,A1,F9,F5,CC,9B,B0,7F,8E,40,90,E2,AA,F7,54,05,95,2C,A9,42,2F,68,19,BC,9A,0F,BD,30,8A,FD,F1,AB,65,84,79,0F,6A,3E,78,6F,8F,18,0B,1F,AC,4F,11,C1,19,25,84,8A,AB,75,E2,B4,6E,D1,69,63,B0,59,1E,E4,28,A5,68,1C,49,67,9C,AC,74,F7,09,64,53,2D,49,80,09,BE,58,46,CA,78,A5,8A,EF,E3,69,FB,5B,CF,CE,0A,22,CC,07,BA,5F,E5,90,C9,E4,24,0B,DD,56,07,CA,12,8E,26,0F,F2,EF,44,34,57,3A,75,0C,1C,F8,D9,17,7E,C7,10,BC,93,D7,3E,B6,73,7F,6D,53,43,65,67,3D,0D,9F,D2,79,CD,95,5A,6A,B1,12,6A,05,51,B0,DF,63,CD,F2,F6,48,F3,15,61,59,0D,B8,E6,70,F2,3B,FD,92,3C,BB,B0,26,93,6F,68,9E,C8,F5,C1,F0,79,ED,A5,E4,0A,4E,9A,F0,6A,0A,49,BF,EF,58,09,1A,A6,1A,A5,B6,9A,86,39,99,DA,E4,E9,CB,26,F8,DB,D4,DF,23,86,C2,E5,07,14,FC,10,2F,EB,3F,DD,95,11,C2,57,03,1F,A7,BC,28,01,D3,A8,60,54,7E,86,53,94,0E,0E,4C,17,4C,0F,E3,5B,11,F1,CC,47,6A,27,68,C4,29,EE,15,AD,8A,0B,08,EE,8E,07,47,B8,33,59,10,E0,B5,0D,E0,18,B6,85,0D,E7,1C,B5,7D,A0,C3,47,52,AE,B8,73,A6,0B,50,C7,DC,DD,EA,9D,51,9C,46,1D,FF,36,23,DB,D8,87,0F,98,F1,AE,0C,F2,E0,3E,54,66,E1,84,A5,20,8C,E4,14,CC,0E,79,B7,F1,43,45,41,54,E3,5C,1F,B8,8E,E3,0A,7C,C4,42,CD,BE,AD,3C,48,AF,0F,63,96,A6,1E,6E,AD,2F,21,56,88,A0,FA,C9,A1,3B,E4,38,D7,A0,12,8A,F8,9E,DF,9C,5A,B7,0C,AF,95,F1,EB,D4,F1,CB,27,6B,3F,0C,7D,1A,9C,98,47,4A,3A,65,2A,B8,70,50,C5,3F,61,5C,81,3B,D1,1C,1C,8B,10,24,F0,2A,80,6E,99,5E,3B,09,CB,44,E4,75,76,B0,1F,E1,52,47,04,15,BD,B0,E6,4C,8E,8C,BD,97,59,8E,13,1C,BC,5F,5A,29,FD,89,87,13,0F,AB,BD,76,B7,0C,6F,9D,40,56,7C,1B,0A,3D,B5,38,A1,60,04,3D,4F,D5,91,B4,1E,A3,FF,B5,45,AF,1D,1F,11,87,21,9E,B9,8F,69,F7,43,C5,EA,D6,69,09,E8,7A,0A,45,B6,A3,F0,86,8C,0E,D2,44,F6,AA,6B,59,48,3C,A9,21,94,4C,23,71,4E,B6,3A,8D,CC,66,8E,37,E5,E7,51,8C,1C,AB,78,1A,8A,CA,E1,35,35,49,0C,73,DD,56,8C,97,CF,97,9B,BC,A0,E8,F5,26,5A,D4,A2,1F,62,33,0A,99,FD,C9,DC,2D,A1,0A,AB,85,1B,55,6B,05,7A,50,0E,1C,82,AF,AA,58,FA,23,80,C1,51,AA,95,C3,54,A8,B4,A0,52,14,4D,35,2D,CE,7E,CE,78,E4,B9,B3,E1,28,9B,3E,05,4D,4C,C0,94,54,92,B3,12,49,5A,DD,40,59,14,C6,B4,4E,7C,B5,FB,C0,E7,E0,5D,31,1F,EF,4E,04,8B,95,17,2E,5A,3F,38,EB,6D,72,84,75,DB,E9,A0,FE,B5,58,7F,1B,4F,DD,05,70,B7,92,04,7F,B2,F1,22,E0,FA,C5,3D,E0,36,15,D6,A8,63,87,6B,BC,C1,1E,E6,AC,57,9C,F0,55,76,A0,06,09,B0,94,C6,1E,F5,2C,ED,69,14,C5,E3,55,57,8F,05,54,8A,B8,35,0C,11,2D,CC,AE,37,8B,8F,56,84,1A,02,5F,78,E2,D3,1E,23,2F,B9,26,3C,1A,DC,24,AB,58,5E,41,41,1E,05,4D,38,97,61,07,A4,A9,51,19,9C,3E,03,30,54,D6,AC,65,E2,85,0E,B0,05,04,F6,30,9E,D4,AC,28,5D,09,D2,1D,8D,05,95,05,9A,0D,02,0D,9D,C4,4D,C4,91,B5,3E,01,4E,9F,53,E0,F9,40,C2,81,90,63,F0,65,FF,7F,B7,25,9C,83,FB,0A,6C,2A,DE,F4,E8,5F,82,1E,1C,D6,B4,05,BB,E1,58,C7,5F,47,C9,93,C9,CD,4E,9F,35,4D,6C,D1,0A,F2,FB,C1,41,15,43,7A,BF,BD,E4,A0,8B,3B,C7,25,7A,3E,DC,0D,1E,E7,8F,AB,EB,88,3C,84,FE,9D,B1,CA,FB,25,45,AF,BD,79,EA,6C,58,66,1E,03,CF,A6,63,1E,6B,3B,E8,EC,BD,73,D9,40,93,1D,4D,A0,D3,38,EC,2B,68,23,F9,46,9F,2A,13,0A,5D,22,10,38,34,DC,3E,74,EF,57,50,22,13,81,B2,B3,0A,2D,C6,21,CF,E8,6A,80,C9,AE,54,2E,B5,ED,6D,AF,2E,73,E9,0E,5C,D6,BF,10,E6,2F,9C,A3,00,E6,F9,AC,A9,AE,FE,45,17,02,47,FD,95,8D,D0,B6,07,8B,4D,25,29,8B,65,6D,0B,DE,97,38,4A,37,A4,D0,A6,5D,12,72,4D,B6,1C,29,AC,7D,12,EC,79,A0,37,04,DF,52,35,58,D7,B5,82,A0,39,F8,E5,55,0F,39,93,83,30,A9,0F,28,F0,12,EF,40,8A,59,E0,90,AA,67,BB,C2,C5,5C,8F,95,FD,03,00,8D,54,0E,ED,0A,27,96,F4,D0,B5,98,C2,EB,86,04,31,66,05,59,84,D4,B8,33,A5,F5,EC,65,D4,B9,D3,F1,8E,B5,FD,7C,6A,59,42,DD,92,32,CB,1C,8B,CB,DE,DB,54,C8,52,E5,C8,47,0A,7F,D4,5C,38,69,FD,10,6F,00,88,93,90,4E,55,55,67,A7,E5,D1,95,16,65,B9,2D,E0,93,06,E9,DA,4C,DB,E6,ED,28,66,2B,C2,79,0A,A8,90,7F,13,E2,35,B8,BD,43,F3,EC,A4,55,7A,B5,FF,0B,7E,7C,EB,9A,EE,CF,AE,4C,C5,9C,F6,42,D2,B3,23,B0,4B,95,65,D4,BF,D4,70,12,5E,13,8A,40,0A,12,DC,BE,01,F5,D0,1F,B5,3B,D3,02,89,79,62,1D,E0,63,6A,A7,7C,20,F1,84,69,C0,F4,A6,60,B6,C5,BE,4D,81,6F,F6,C3,D1,65,13,2C,9B,41,92,4B,65,44,28,92,A6,EA,15,DA,51,AC,CD,39,C0,2E,AE,D0,7F,B9,2B,1F,70,F0,D6,B7,BB,C4,65,A6,1A,25,80,2A,E4,C2,BC,6E,64,A1,F9,3C,F3,F2,EB,70,69,2C,01,1B,F2,EC,24,3B,81,9C,D0,2E,2B,A3,0E,BF,03,33,28,47,2A,FE,1D,A8,C7,A0,8A,F4,AB,16,F3,EB,45,F8,04,36,CB,3C,84,CC,53,DD,81,E8,28,6F,E6,D7,B6,CF,C2,5E,16,A3,6B,3A,02,B4,7D,D8,5D,77,B1,51,44,7C,11,F9,AA,E3,F1,98,88,44,16,BE,C4,3E,BE,08,B8,BF,75,8D,5D,C9,D0,A9,D9,29,DC,8B,4B,3C,EA,39,EE,97,67,BE,4B,F7,CA,CC,F9,A7,57,EF,17,C0,1F,D6,71,C2,EB,7C,25,6A,9A,21,F5,ED,EE,DB,EE,E8,C5,BB,D4,B2,D8,95,4F,79,D8,A1,74,47,FE,45,38,B4,BA,94,FF,2A,C6,12,1A,E5,38,CD,35,1E,1C,8F,63,46,8D,33,18,02,39,7E,F4,38,85,8D,39,05,D4,87,2E,76,B2,80,27,29,D0,89,50,C2,E4,A4,82,C7,BD,31,E3,14,EA,34,D3,81,27,8E,F0,A1,82,C1,AA,94,B0,25,8D,9F,15,94,87,E2,0A,BB,FB,47,A2,5E,D7,16,37,90,8E,11,D5,8D,3D,A5,7C,50,EB,C7,2A,6A,30,34,63,91,03,AB,C0,62,F2,B5,5A,EF,AD,F1,EA,AF,A7,37,46,AF,25,4D,6A,0C,E5,DB,EF,9F,62,0B,3D,CC,2A,E5,93,00,E1,5E,8E,B8,F9,86,2F,32,82,6A,57,8A,63,E9,41,C3,19,B1,83,F3,71,E3,44,33,D2,F8,F9,E3,7F,09,01,3B,F2,86,15,23,80,93,54,A2,8F,BE,33,55,AC,6A,97,52,FA,7C,E9,F4,52,BC,B4,B4,68,9F,E5,B2,83,C5,F3,FD,56,24,88,60,28,4F,C8,02,7B,F2,C3,5D,21,9E,CF,7D,88,52,21,32,E4,18,E0,CE,52,44,DB,C1,C9,D7,A6,07,C0,85,7C,50,A5,3C,E7,AC,42,BD,BA,BE,55,0F,B5,7B,97,A1,37,C5,53,6D,EB,41,AF,5C,27,A2,10,D2,39,25,65,A9,01,18,48,5E,C5,7F,53,95,3D,AC,B7,03,08,72,A1,F5,9E,92,47,95,CD,4C,0D,CC,AA,B0,5C,9D,36,58,99,D6,16,73,2C,80,D1,32,23,66,D7,15,FD,83,9A,CC,8C,78,A2,C3,81,F4,1D,D6,B8,EB,3F,0C,F6,0F,75,0E,7C,3F,29,58,0B,C9,78,D4,0A,9C,E0,AD,42,E9,E2,2D,EA,A0,71,48,AA,D5,5F,74,28,B9,26,1D,CF,6D,5D,6C,EE,03,2E,4C,2B,33,D7,C7,82,04,35,FB,79,DA,EE,E1,AB,F6,0D,07,62,B6,D5,11,5E,7E,39,84,00,B6,10,8D,38,50,D7,8F,62,9C,23,26,00,2B,30,28,28,19,E5,10,62,7F,1B,4B,2F,8A,8C,B8,23,DF,8A,84,82,51,67,9C,37,CE,95,C5,C3,76,47,01,ED,ED,4F,D8,66,95,72,BD,03,7D,53,FB,6D,07,FA,F3,D9,49,5D,8D,0C,DE,28,83,FB,02,44,5C,DB,35,04,0D,3F,E6,41,B4,09,B0,09,44,5E,87,C5,19,ED,84,93,BB,39,62,05,2B,3C,A2,80,63,13,43,61,17,D0,00,41,02,A8,F1,92,65,2E,90,CB,83,15,99,4A,42,A5,79,2B,FF,B2,9F,3B,2B,82,60,C7,CB,F9,86,C5,0A,F5,84,FB,39,4B,9E,C0,85,A1,45,EA,41,1B,5A,8B,F9,93,B4,51,5D,27,B7,A3,ED,66,DA,A1,B5,35,FA,BB,61,ED,A3,55,EA,75,A3,0F,7F,FA,3D,52,74,55,5A,F1,4C,77,57,18,52,CE,6B,87,1C,7B,FF,78,3A,6F,B9,27,C3,3E,A8,D6,2F,C2,FD,5C,15,05,CA,F1,8E,19,5A,7B,A1,A3,97,58,93,FC,1B,5F,94,F5,38,F6,F2,D0,47,25,0D,13,84,59,1C,04,41,03,34,D8,3F,12,CE,55,78,7F,EA,BA,C1,6C,18,27,7B,AC,48,E6,E4,56,54,10,20,82,F1,96,C9,F6,D4,A7,FC,D2,81,81,3D,2C,A5,7E,44,BF,32,1D,CA,3B,00,73,7C,61,46,D2,37,07,DE,67,03,F0,C7,DC,D3,06,BB,16,4A,35,59,ED,73,47,88,CB,08,3E,C5,41,BE,AC,72,86,F6,8A,26,D2,59,E5,2D,75,79,C2,E8,76,8D,42,7B,9E,EE,3D,C4,D2,10,D3,3B,17,A0,C0,70,2D,DE,43,F8,51,12,3A,EE,28,F1,74,F6,4A,E7,B5,06,A4,62,50,D3,C0,67,C9,50,85,35,40,69,96,6E,63,59,90,86,8A,37,D0,F7,1B,65,91,84,D1,84,59,E9,19,45,DD,9F,92,79,AA,8D,1E,3C,0B,9A,86,B2,45,F2,74,48,7A,9B,F1,BD,6B,5F,53,AE,60,F0,08,8D,B4,85,5A,97,00,49,AA,E4,67,4B,5F,B7,B8,B5,87,22,65,6B,17,1E,6C,A4,F6,43,1B,F1,80,6F,A6,77,87,64,13,59,07,8E,6F,DE,EF,E5,2B,6A,00,0B,80,95,89,5C,17,FE,96,45,82,6C,DB,6D,70,03,20,36,BC,06,6F,6E,3F,91,53,7A,E5,5F,2D,C4,E5,36,38,24,86,F6,AA,34,B2,50,22,EC,CC,64,2C,89,67,ED,B3,BF,53,9E,7D,5A,01,82,54,F6,8E,36,39,AC,9E,71,A5,0E,73,43,0C,AE,28,90,E8,AA,40,4F,42,42,59,4C,F6,B9,FB,D5,DA,83,1B,E7,9F,B5,C5,A2,BB,52,36,1A,62,50,B4,02,80,03,2D,F4,E7,0F,0D,A0,83,B5,E3,E4,32,4B,6F,F1,58,E0,A5,3C,C3,82,A8,92,5D,B3,63,CB,65,81,B6,54,B0,9B,FB,82,5D,D9,B2,92,FD,AE,56,28,5B,29,71,7E,DA,CC,59,F2,9A,93,92,1B,71,F4,F0,77,39,3A,D6,CC,D3,2C,3F,1A,DD,6E,D9,CD,A7,DF,77,EF,93,34,78,15,C6,B9,38,30,CC,FD,93,47,FC,23,7A,D8,71,B3,55,EB,B9,D9,25,88,03,87,DA,CF,75,6B,57,EB,27,B0,F3,DF,5C,91,F3,8D,5A,FC,8E,EC,7C,B4,90,63,03,3A,48,B7,9F,A5,55,34,66,B6,22,6E,EC,56,01,88,87,F4,C8,6F,72,C4,6A,D6,E3,7D,35,B6,F8,82,AF,D4,2B,BA,0C,BD,A2,3A,9F,F6,A6,C5,0C,D3,EF,81,6D,44,4E,09,05,47,F3,3B,31,A5,F5,7C,23,5A,CE,3F,F2,F5,CB,E7,6A,0A,DD,DA,3A,5E,CB,82,6F,32,A3,CF,47,A1,24,68,4C,D5,D0,11,92,CE,29,A4,F5,84,59,ED,E3,31,5F,17,87,41,EC,B7,2F,0E,2A,F9,22,45,3D,D7,B9,E0,E9,E2,D8,C3,83,F1,E4,D5,CD,EF,E1,FB,38,BD,83,C6,C7,D1,41,C4,16,4B,2B,4B,0F,EE,3C,65,76,97,51,F4,0E,A9,DB,6A,06,91,92,E9,36,3B,99,41,0D,27,17,4A,0A,CB,78,D7,65,B3,EC,E8,E0,B7,46,64,A6,E0,4C,6A,EF,00,70,E9,D0,58,01,7A,16,B1,3B,3B,30,47,EF,F0,FC,A8,06,DF,C6,FC,46,62,37,9F,99,E8,E4,89,F1,EE,54,AA,CB,7B,BB,05,8A,07,F4,20,27,9B,EB,BC,1C,E7,3A,5F,8E,C8,2A,DB,C6,30,B5,44,6C,77,36,33,EB,DA,83,C2,9C,C2,29,5F,C0,1A,05,41,3A,5B,30,43,7C,88,15,97,C1,51,04,6E,58,24,44,1F,B1,46,32,AE,85,0D,BD,B0,41,84,BB,B5,AA,DB,BF,B9,B3,CE,A2,8F,15,A8,AA,AC,AC,3A,40,73,21,4D,6C,3D,06,0E,8F,2A,07,58,17,AA,55,76,E1,31,50,1A,70,03,AF,69,80,C3,75,CC,D0,77,11,46,CC,D0,71,E0,B3,B9,40,41,ED,2D,5A,45,2C,8C,D9,0D,03,32,52,64,18,67,FD,08,F2,62,3B,48,F4,E1,B1,84,2B,4A,F7,A7,FC,EB,B6,CC,6E,D7,37,2F,25,E5,E7,B6,49,16,3D,12,A0,57,0B,90,98,1E,48,06,1C,63,1B,B2,C5,7C,98,3C,78,7F,2B,A1,56,79,C6,CD,A7,F8,A9,42,E1,B6,9F,7B,39,41,45,1A,54,9E,65,27,0C,03,2A,07,9B,A1,C4,9D,7A,6E,13,51,1D,17,5E,2F,F2,78,61,CB,B6,82,9D,C9,CC,E9,A8,C3,86,42,DF,68,C7,6B,4E,2F,65,2D,41,57,EA,EF,17,53,D9,FC,17,57,62,B7,3B,7C,CE,3C,F9,8F,C5,66,B6,32,CB,4F,7D,0A,C8,71,36,DE,0F,7A,A9,47,24,A3,62,01,1D,38,07,C3,12,1F,71,52,28,70,75,9D,BE,77,F1,AF,57,66,B5,92,5E,06,87,5F,AB,78,7C,0A,20,ED,34,0F,56,3A,E9,5E,3C,AD,88,0C,35,0D,49,72,DC,6D,D6,F9,F3,B6,F7,24,3C,9C,27,49,68,98,06,D5,9B,55,02,0B,B7,27,33,59,72,F3,3B,B5,87,4F,46,28,90,02,40,BA,01,10,57,28,3D,97,DF,0B,7D,95,4D,4F,AB,74,26,5D,C5,7D,92,52,7F,2D,88,2C,76,99,8D,9D,04,82,CB,BB,34,66,C2,7F,0B,57,C2,A1,38,50,1A,B8,16,24,0B,D7,3D,D7,75,54,15,AA,EE,76,EE,D3,01,3A,98,B5,7D,5C,1D,A4,1F,9B,AD,41,DB,56,42,04,C8,AA,73,A4,CE,95,29,41,71,4D,1B,B7,0C,8A,44,33,5A,7A,7B,E5,0C,14,01,37,20,B3,1A,10,F1,25,8A,E7,53,85,F9,F6,8C,97,D6,A9,89,CC,F0,9C,40,51,DA,70,D3,11,7A,5D,EA,AE,F8,7A,B6,79,F8,43,19,A9,37,92,B0,37,F7,25,C2,3E,05,FE,E3,BB,79,60,29,DA,2E,B8,73,3A,E6,A2,3C,C2,2B,DE,10,56,42,42,C6,28,92,8F,81,D3,1C,41,14,E9,2A,5F,F8,48,99,17,30,C6,A8,0F,7A,95,59,E5,F8,67,AF,EC,14,01,52,6B,33,8C,FA,58,A2,9C,BF,C2,F9,F6,BE,03,BC,B8,68,03,A4,3A,32,CC,BD,28,7E,B6,F6,2C,CD,D9,84,F0,2C,F0,00,50,75,ED,39,C7,AB,D3,8B,07,41,47,2A,A5,26,15,5B,26,EF,32,17,59,86,35,67,1E,98,08,86,AD,B6,C3,B9,E2,F4,06,29,4B,81,49,0E,78,7E,42,B8,34,B0,E6,D2,60,2C,F9,BF,80,8F,76,F0,D5,0D,22,66,85,02,12,FC,A4,B3,BE,03,CC,88,E8,E7,BE,06,52,C0,E6,B9,D6,DD,CC,06,1A,1E,8D,26,56,99,E3,46,7A,CB,2B,97,60,EE,2E,10,86,AE,19,E9,37,5D,E2,79,B7,23,59,22,AF,98,BF,A1,75,26,70,97,FF,50,74,6D,17,E0,30,4E,1B,BB,49,EA,91,2C,51,DE,97,E4,80,3E,0A,69,A4,E5,20,ED,41,49,D1,59,A8,1D,97,9B,CB,22,05,2F,90,45,2D,4C,A8,43,B8,9B,DA,50,31,25,5E,43,F0,18,85,3D,D4,CA,BB,94,AC,81,2C,E5,45,77,42,B3,F5,4B,C6,CC,3E,3A,91,F5,9D,16,86,42,51,27,CD,F5,14,C6,F2,12,C9,11,D7,B1,F0,A1,6F,5E,B9,13,DE,BE,44,92,A4,38,B5,78,73,8F,11,63,6A,F5,1A,8B,44,ED,2F,0E,FA,16,49,67,82,5C,B9,74,BD,75,8E,A4,5C,A3,AB,BC,7A,08,24,AF,E6,DF,70,95,61,4C,A1,FE,47,36,99,05,1E,72,6B,E9,20,AC,5E,21,88,87,13,9A,D4,90,87,2D,75,E3,68,15,A4,EF,C3,3F,DD,D5,6A,E4,83,63,F6,88,86,2A,53,DF,A6,D9,07,5B,FE,41,15,5F,3F,84,B5,36,80,0B,4A,CD,C2,8A,4A,6D,11,B9,8F,63,F5,EB,CD,E5,6A,77,D3,7C,A0,0E,9D,DA,A1,53,42,7C,BC,DC,BA,F3,AF,0B,E6,BA,3D,BC,06,FC,1E,1A,48,6D,81,83,D1,9E,CA,D8,5F,18,72,23,00,9E,CE,A1,10,D9,A9,A2,B0,39,60,F7,FC,3B,EA,39,E3,86,42,BC,DC,B3,63,A8,F5,69,B5,00,1A,C8,9A,DA,1E,E4,3A,01,6E,50,60,49,5C,8A,51,B6,72,7C,36,66,5F,72,58,9B,C7,1A,B4,E3,CD,30,70,CF,8A,F9,8C,47,C7,79,59,CE,41,4B,04,0F,A7,6C,5B,01,F5,25,3B,BD,E2,C6,0C,5B,32,94,0A,3F,B5,B2,C8,E2,8A,1C,09,D9,64,7B,A1,65,2D,D9,FC,23,64,06,86,26,7C,FB,91,89,EE,0C,06,28,60,D2,E2,E9,D9,F5,C3,18,A1,8B,31,4B,5D,ED,FD,67,47,54,5F,3F,AE,E2,E3,29,F5,2F,80,65,7B,CE,20,EA,53,1C,16,D9,03,62,AA,3E,C7,7F,B3,26,61,83,3B,A9,1B,C3,4A,40,EC,BB,64,2A,01,E8,73,ED,91,01,B8,7D,18,D3,1C,12,13,6A,B0,E8,09,7E,E4,3B,53,F5,3A,2A,17,DF,B4,9C,B7,A7,9D,DF,75,70,61,FA,A4,07,C5,37,6C,87,A0,1E,70,37,7D,16,BE,D9,0C,03,F3,1F,66,9F,EA,31,8A,11,9A,26,01,22,DE,27,31,F4,75,95,0E,88,F4,2B,04,07,D8,B3,5D,D5,07,5D,09,8C,B1,71,74,9B,0E,A9,A9,DD,41,8B,CF,48,43,4C,83,6D,13,3A,CB,89,C6,2B,79,D5,AC,3B,B3,C3,EF,86,21,D7,0E,F5,8D,33,BA,09,24,1E,9D,75,57,F4,CA,9C,31,BD,BF,5D,69,86,EE,31,0C,00,A3,67,40,41,93,C7,E7,7E,AD,13,87,35,C4,73,2B,9F,00,32,3F,3E,23,A6,B9,36,45,A3,C5,52,F6,69,C5,03,39,71,F5,25,13,CD,59,A6,08,CE,F9,D2,53,45,F4,70,6D,4C,D5,DE,6A,74,EF,87,87,0B,EF,08,BE,52,C7,0F,94,BD,5F,05,79,E8,5A,3B,96,1E,D4,EB,BE,4E,72,AB,EA,B4,2C,00,9E,24,8C,80,B2,C8,22,BB,63,17,81,A8,9D,3A,6C,DF,01,9E,5C,EB,D4,92,8A,00,A8,F6,02,FB,A4,B1,5E,EB,1A,64,E6,57,7D,34,CA,24,6D,8C,62,E0,D5,13,AA,70,03,66,17,02,DD,AB,AD,E6,12,B9,05,58,2D,43,1A,1B,8D,6F,C5,36,BB,35,B7,D4,24,FF,F3,6B,28,B9,8E,96,09,FB,9E,7B,6C,8A,F9,8F,25,0A,E2,AF,EC,17,5A,38,9F,CF,49,B2,FD,FB,61,AE,0F,97,7A,79,3B,7E,90,8E,65,E9,14,7A,08,0C,ED,96,F5,48,10,A0,4D,C9,D5,CA,F3,27,25,1E,17,55,90,E9,B0,53,85,6D,76,89,24,BB,4E,FB,17,AC,B1,F4,C6,F9,EC,5E,BC,8B,FD,30,A2,3A,5D,82,BC,21,E7,44,6D,5F,C7,13,5B,43,B0,F2,65,30,7F,43,31,4B,87,DB,C5,3A,4D,35,CE,90,3C,9B,69,3A,86,B0,FC,47,36,41,CB,13,A7,79,F2,21,11,AB,40,B9,B7,31,88,6B,FE,83,68,4F,09,A4,0E,B7,F0,E1,84,64,D0,5A,D2,6F,1A,79,AE,68,CD,76,52,8D,74,AA,36,7D,4A,19,66,76,7E,DD,BC,A9,F9,B2,EC,E0,DE,84,4C,C2,41,43,21,68,D7,DA,22,5F,68,55,6D,2D,BF,B9,97,3C,D4,D0,B9,53,CD,48,DC,61,96,07,B1,03,2F,CA,05,25,9B,ED,7A,7A,E5,54,95,BF,74,12,18,FB,1B,25,09,09,9E,19,28,D1,01,41,ED,25,19,7E,80,88,D0,14,53,BB,C5,CE,80,E8,5D,30,27,89,E2,72,6E,83,74,E4,A4,72,2E,AE,93,7A,84,7D,45,1B,2E,7A,B3,21,65,49,34,E6,1C,B5,1F,0B,41,54,CE,D9,42,D4,2B,00,1D,9B,6E,7E,91,E4,1E,94,BD,C4,DB,5B,67,F7,72,C1,56,8B,AB,FB,25,CD,66,7B,8D,79,3D,13,3E,99,8A,02,26,6A,6F,B3,1E,85,43,EA,36,2B,56,E7,E1,03,5A,64,61,11,41,00,48,E5,F8,10,58,1D,08,01,D1,DE,1B,CC,F8,E5,99,15,1E,5C,FB,B8,5C,9C,AE,AF,AC,D5,AB,9B,B6,B4,DB,03,FC,20,BD,7A,AA,6F,D7,A6,64,E0,BE,D3,F1,C3,10,51,EB,59,EC,0F,E9,D9,D3,5A,EF,0F,F7,E2,1F,95,C3,48,BD,3D,ED,3D,27,2F,CB,A5,96,D3,92,9E,62,1C,80,49,70,9E,BE,1D,EA,E2,32,30,93,68,D7,B8,8D,1C,9D,18,66,11,0D,63,70,14,B8,C4,98,F0,7D,9E,BF,5E,F0,CA,E7,76,98,6C,A7,E4,8C,23,AA,86,F9,36,DE,32,AE,06,E2,DE,BF,10,C8,0A,B0,F8,59,A5,8A,28,D8,37,38,71,B8,60,FD,DB,33,56,27,6F,A5,A0,CA,A9,83,60,96,F9,6D,EB,05,4A,75,CD,BE,EC,E1,37,A3,9B,E2,CD,9E,D9,8E,1E,60,02,E9,31,53,90,79,69,B0,0F,BD,4B,91,22,5C,57,E2,5A,14,D5,E7,A8,ED,43,AB,BC,56,CD,C5,A4,42,37,99,49,02,4B,C4,17,DA,7A,D6,ED,79,FA,DE,DA,F1,56,FA,34,74,D2,A2,E6,70,A9,BA,2B,8C,D2,CE,0C,7A,7B,D6,D5,56,A3,64,23,40,33,9C,B7,D9,81,9E,78,3F,53,37,1C,39,23,3A,F2,37,A9,C6,E3,F2,1F,4B,06,BE,EC,7E,44,4E,4E,4D,22,08,EB,2E,D0,18,5E,7A,62,8F,BD,11,44,0E,EF,CC,A7,EF,7D,EE,E2,30,64,C2,CE,76,57,68,A2,93,20,45,4D,23,21,34,8C,49,C7,15,FB,81,51,32,D0,CA,9B,9D,35,AC,87,4B,BB,06,6C,DB,60,B2,32,15,1A,CC,46,92,C6,16,2D,56,50,A5,00,FC,2F,51,05,DC,88,42,E8,FD,F7,8D,BF,98,CA,A1,A3,C3,F3,86,C7,3B,42,1C,D5,18,AB,2A,B6,F8,19,CC,B4,1B,C3,10,80,E9,36,94,FE,22,05,B8,5F,3E,46,9B,20,90,31,B3,F5,64,6A,BE,5E,36,CB,E0,87,A7,90,C1,CB,8F,6C,87,F1,0D,AD,9A,A1,C6,32,05,61,31,89,3E,FE,FB,1F,33,14,A5,90,19,D3,CD,6F,F5,C0,79,4F,5F,56,F1,02,A0,7D,F3,65,B5,E4,9B,0B,0F,04,4F,BB,C7,5D,13,C6,EB,A8,C4,F5,FA,61,D3,FA,2A,A6,2C,65,84,86,42,2C,F6,4D,C4,36,42,C7,57,66,C0,EC,03,2F,57,99,9F,00,3E,43,37,8B,06,AC,02,35,D1,A7,84,FA,53,4A,8D,18,57,22,22,D6,0B,2A,7E,BB,19,20,68,F2,5F,4B,84,7B,F9,0C,84,43,0E,13,4B,38,6C,12,1A,62,26,A4,FA,61,53,76,E9,E3,A0,69,F7,C3,B0,16,58,1E,8A,4B,4D,D9,D2,EE,86,B7,DB,73,6A,15,80,09,06,CA,45,2F,2E,DD,67,67,F5,C4,AB,7E,84,63,F4,6D,6B,F5,3F,99,4C,43,89,01,20,A1,EB,F5,26,EE,2D,B0,20,88,54,B1,D9,07,4C,B4,A6,66,62,69,A0,85,44,84,89,5C,02,A7,66,20,0A,8B,A8,E5,8D,82,EA,C4,34,BD,6F,65,6E,B3,63,BD,63,34,FC,CD,6B,13,28,05,B4,0B,0C,37,1F,E6,1F,5F,8B,45,B5,DF,54,1B,AD,47,B2,95,1C,53,C6,C5,86,E3,E7,50,21,C0,C0,74,4D,81,06,76,61,C8,73,40,F4,2D,99,13,0F,94,B3,61,59,77,46,81,C1,75,0F,94,55,65,28,AC,E8,B3,21,D5,BB,52,84,A4,FA,16,2E,09,4D,A9,7B,98,50,1A,D7,9D,DD,69,D7,34,9D,23,DE,58,40,BB,E1,D9,1E,3A,DA,D5,7F,5B,E9,C3,8E,F9,BF,64,05,B7,45,DC,38,02,CB,A3,7D,88,1A,61,26,EA,C6,6B,8F,DD,9A,6A,6A,E1,86,58,BA,8A,55,43,26,F0,FC,3B,1E,62,68,DA,B5,E7,6D,5B,A4,68,88,C2,32,09,E4,5C,AF,ED,01,E7,8D,B7,82,A3,34,FA,C7,CE,D9,B5,C2,DB,1C,7B,0F,B2,2D,11,A4,B5,76,C9,71,1C,29,E9,EB,11,8D,A8,94,BD,2C,F6,54,D4,A5,A8,80,9E,9E,30,B8,60,DE,AC,07,63,EB,32,51,3C,04,39,75,5B,3B,4F,98,47,11,4D,70,00,91,89,02,80,93,75,06,E8,17,C9,7B,82,2A,ED,65,71,92,C7,54,9F,91,75,B5,0E,97,E9,9B,17,6A,FB,E0,7D,57,23,09,F4,BF,1B,F7,FA,27,9A,DD,DF,4A,38,DA,1A,6A,ED,0B,BC,91,B0,F0,21,76,0D,EA,25,A5,6D,E7,4A,39,90,CC,7B,0D,5C,D6,A3,A1,CE,5D,E0,53,51,2B,4B,AC,C9,18,02,D9,B3,23,00,30,07,22,B1,8C,E2,44,4C,DF,F6,A4,DB,CE,8A,F6,35,60,17,5C,EE,5C,4B,10,56,48,C6,72,5F,12,D8,6F,B4,4E,89,76,8E,AE,70,A8,67,F2,EC,CD,77,B0,41,5D,38,53,3F,D0,27,BE,DE,F0,FC,C3,75,50,0C,8E,FF,6C,83,8E,1B,BC,A8,69,71,EA,90,F4,6A,10,C6,F5,79,0D,6B,A9,FC,36,F1,D9,09,E0,3F,C8,D3,E6,21,A0,30,6E,8D,A9,5B,32,E5,F4,21,F8,31,23,35,1D,05,AB,BD,C8,28,78,65,26,CF,BB,36,CB,D2,13,46,F4,FC,E8,B2,02,CB,9A,1C,0B,9C,F1,4F,6A,67,32,2B,C7,8A,01,90,B2,2B,F4,C7,8E,E6,4C,05,E5,36,D3,F8,36,44,B9,1D,1D,E9,CB,2A,7C,F9,90,3F,4F,84,45,B5,09,6D,3C,BE,F4,A1,76,6D,A7,0E,A3,10,20,AC,59,9C,3C,CD,E6,7E,1A,04,2E,D7,A8,90,C6,B4,3C,8B,B1,59,99,4A,21,0E,9C,FA,52,9F,1E,FB,5C,CA,96,1F,14,42,9A,7E,ED,47,FC,21,99,D1,5C,B3,55,2F,CF,37,5E,F0,03,52,BD,55,6B,76,C6,9A,E4,49,76,C1,19,85,F9,C7,69,86,0E,82,07,0C,7C,3C,16,29,42,8B,CF,A7,0B,EC,51,8B,96,A8,C9,5D,B2,BB,6F,16,86,38,D0,AB,B0,BE,2F,B8,44,33,91,DA,70,8F,DF,93,41,D9,D8,8D,75,56,56,96,E3,F2,B8,C1,F1,39,8B,30,E7,8B,B5,29,D9,0A,C8,F6,23,5E,F0,33,94,69,8B,70,BE,D4,D0,69,FF,76,0D,95,38,F3,5B,66,FC,F1,F5,EF,C8,F1,79,35,4B,7A,E8,6D,05,6D,EA,54,71,5E,F2,22,48,95,62,4E,34,5E,9E,9D,5F,E3,D6,CB,DC,AB,FD,BD,82,DB,70,EB,88,43,84,A3,D7,53,C4,6E,5C,59,65,2E,B8,0B,6B,E6,70,82,98,E5,32,C7,43,35,61,57,45,13,08,FB,57,2A,5F,1B,25,60,0A,1F,04,DE,8A,E1,71,5E,AD,FD,F5,21,55,B9,22,A0,12,B6,83,EC,FA,D2,B0,7A,60,20,E2,7E,D1,FE,F8,88,B7,EB,BF,D4,23,99,9E,80,BC,7C,2D,13,D0,1C,07,8C,1A,10,13,8D,75,6D,69,AC,E1,89,AF,48,AC,D1,39,2B,CC,7B,B3,15,EB,32,8A,4B,DD,1D,78,40,5E,3C,C4,FC,A0,FF,07,98,23,BD,19,A1,6C,B6,52,E8,BB,87,3A,7C,FA,D9,55,63,37,F4,28,8B,57,EC,6B,5B,05,30,1B,74,46,55,9F,E0,4F,40,CD,61,35,F7,4D,8E,56,6E,3C,D5,A4,B2,9F,3E,1A,F8,D0,6C,DE,A7,AE,C3,00,72,03,7F,E4,CF,52,DA,EC,A2,43,BC,A1,A8,23,2E,1D,8F,ED,6A,1C,B4,BF,B6,E1,B9,06,80,FC,3B,DE,59,63,FD,B0,A0,16,83,B9,CC,4E,0A,8B,94,70,B8,03,31,D3,89,74,41,18,92,99,AC,32,9F,3E,E4,4A,A2,A9,0E,94,DC,CE,AB,27,37,95,FC,28,B0,18,37,FA,23,E1,7D,7C,C9,B2,0D,4A,9E,FD,8F,75,C9,AE,64,7E,AE,AE,DE,BC,C1,09,8D,8D,FA,75,15,56,25,17,97,FF,05,2D,A1,06,3D,03,37,6D,B7,D6,CF,5C,9B,B1,FF,E4,3F,8C,9C,26,CF,8D,40,E9,23,26,E7,00,02,A0,C7,51,D6,3E,0E,CB,8F,19,DC,48,0E,20,40,4D,61,DD,B3,18,D8,37,FA,49,0D,1A,4F,C0,4A,72,A4,B4,38,DD,81,7E,84,16,94,ED,CA,B2,D2,25,EB,79,60,25,B3,92,EA,D1,02,86,7F,65,3B,9F,28,79,6B,43,CD,B2,8B,44,84,DB,F4,BA,4F,68,E2,6F,F2,C9,05,02,E2,30,BD,36,E8,84,20,1A,34,D0,83,3D,5F,1D,EB,31,60,47,F3,1D,5C,D0,F8,A4,AE,DC,96,25,AA,2D,4D,C3,32,21,93,CB,75,9B,25,C0,58,4B,61,C7,49,4B,C2,A2,88,7C,3A,16,89,7B,21,24,D6,87,7D,53,F3,5B,35,6F,F2,D1,B0,E6,C8,17,2C,C9,73,D2,12,74,8F,48,E3,40,35,3F,E4,BD,57,5A,64,75,24,6E,40,B3,8D,BC,1F,C5,F8,6D,4E,CB,64,5D,58,2F,C0,EF,5E,31,86,8B,C5,A0,BE,F0,CF,D7,D2,4E,76,34,A7,C5,05,28,CA,63,83,B8,A5,F3,42,14,DD,1B,E0,67,F2,FC,BE,9B,01,08,66,46,4C,B2,B2,D8,76,36,60,94,EC,6F,6B,B0,8B,BE,D0,E3,CD,C3,A1,4D,E6,66,0D,76,C7,79,79,4A,7E,B9,90,90,E6,C4,1B,83,E0,B9,14,36,1B,23,4E,45,73,D0,90,7A,2F,F1,21,1A,24,66,0E,60,C2,04,B3,F2,6A,30,DF,92,9A,CF,0A,3F,8D,BB,CD,1B,85,CA,6C,BB,73,DA,B3,67,A9,B2,2E,C7,23,63,15,BE,98,08,8D,2A,24,76,72,6E,2E,3E,73,26,69,FB,B5,ED,B3,35,D9,B8,73,41,AA,C9,57,F7,09,30,38,AD,C5,C1,56,05,E6,82,DC,0B,E5,06,BA,DA,09,69,0B,17,A6,49,86,E4,21,AF,A3,08,10,C1,04,BB,D4,B6,46,6B,10,64,7A,45,20,62,93,E8,5D,60,25,5F,0E,6E,9B,48,FF,A7,DE,42,FF,09,1B,A6,45,4C,61,77,9C,22,C7,B6,BE,42,69,BA,EB,46,55,2C,E0,30,EE,04,50,C8,53,F6,46,24,30,24,23,1A,25,56,81,3E,73,09,6C,67,73,CB,D5,43,35,9E,9C,22,F4,15,0D,A0,A2,8E,3D,E1,68,6C,D4,41,D3,85,82,FF,42,0E,46,4C,53,E8,77,1F,D3,AC,6C,03,7A,E7,7E,F9,8F,BB,9F,1C,6E,04,E3,A9,AB,0B,5B,23,A6,B6,0B,BA,1C,63,79,AD,A1,B2,78,3A,77,E4,00,F7,2D,80,D4,27,E0,12,7C,62,72,8B,FF,33,91,CE,FA,C3,06,2B,75,2D,59,06,14,BD,1C,96,47,A3,71,84,0B,1B,91,88,AD,41,BD,ED,FC,D3,5A,D3,EF,94,DA,D0,C5,FA,42,F3,90,D8,C3,03,26,D1,F9,8B,75,2F,B7,7A,F1,88,FE,E1,A1,00,BE,25,4B,CA,13,8D,15,CE,98,59,18,B0,22,5A,10,7B,A9,F4,CB,AA,98,27,3D,1D,A0,CF,F3,5B,70,F2,C3,C4,A3,37,E1,88,BA,93,03,EB,94,92,52,F7,50,D0,99,51,68,12,D4,7A,35,CB,9A,41,9D,08,1B,43,C3,9E,BC,CB,83,D0,7D,59,DD,21,0B,5D,77,B2,EA,88,7F,0E,62,FF,21,7F,A4,1A,5F,12,65,22,12,4C,0E,8C,C0,84,FB,91,05,9D,EF,E0,05,15,EF,30,B2,A5,B6,1A,C8,A2,EC,94,57,ED,AD,FA,A8,6D,9B,97,B9,E4,5B,5B,CE,B3,97,B0,11,0F,BD,1E,AD,4E,98,69,80,03,27,7E,79,7C,54,81,F9,E0,86,1C,3C,36,CB,F2,16,EC,0A,4C,02,0A,23,F8,4B,6C,BC,80,79,FC,D7,B8,10,A8,76,58,46,65,4E,AF,32,1C,6E,FF,62,FC,30,1D,EF,28,AA,18,0F,B0,85,AD,99,1A,26,6B,09,D1,50,83,F0,11,F0,C4,0E,9E,E5,E2,DB,5B,A7,BF,DF,8D,6C,B8,BE,6F,F3,47,90,FB,E5,8F,C0,B7,DB,74,C7,E0,00,05,2D,D2,BE,01,21,34,50,A7,E7,41,BE,4A,B1,B4,39,74,A1,5F,91,88,ED,31,B4,19,46,B4,34,E0,DC,68,51,C2,D2,9A,F7,6E,F6,F0,6A,39,44,BC,92,28,DC,7E,04,13,69,C3,B9,3A,70,2B,CF,6D,F0,41,8C,6A,66,B9,BD,2D,F9,DB,05,D6,5B,74,ED,B1,CA,95,65,05,92,74,1C,0A,04,46,E1,06,77,99,7B,8F,8A,26,A4,B1,B1,AF,64,82,49,0D,65,61,67,3E,5E,49,F8,49,1A,43,3F,E7,98,E0,17,F7,6D,9C,16,49,4E,F6,45,17,46,3A,8C,91,7D,8C,43,86,90,1C,09,7F,35,05,AD,A8,97,16,B6,F7,B7,AF,9A,2C,9D,3C,90,A6,64,C9,DF,3A,EC,18,EC,7F,CD,C7,3F,2F,78,ED,A6,40,94,D2,64,F8,ED,03,9E,79,A8,B7,D3,CB,38,A8,EB,2C,4F,8F,6D,51,96,9C,8D,4F,D1,98,7F,F4,5D,F7,79,E8,1F,07,D5,37,20,90,CC,06,4E,68,F4,91,8A,48,4A,4E,36,A0,23,3B,9C,E7,BD,A2,CB,B6,51,4B,A5,42,58,92,42,76,81,59,9C,AA,D8,FE,B9,D6,0C,C2,FA,96,CE,00,FA,7B,CE,B4,C1,DA,05,EC,3D,09,20,D1,B3,E6,1C,59,90,BD,E0,6F,9F,A8,2A,9D,59,69,C3,F4,70,61,8F,70,95,C2,4E,35,E4,6A,E7,1C,03,43,A9,A1,D8,BE,0D,75,95,5A,55,36,9D,43,C3,4B,32,9D,B8,4A,93,3B,5E,75,50,CA,F1,58,E7,9E,D6,CD,83,CB,56,48,47,EF,70,44,AF,92,29,28,E8,DD,05,16,7B,17,C3,0E,4A,D5,69,BF,93,AB,FA,67,AA,F9,50,D9,C0,9D,01,5F,00,24,25,14,63,2D,EF,93,7E,56,1A,31,FC,62,AE,23,4A,CA,F6,A5,1F,F4,E0,83,E6,70,2B,42,86,E2,81,24,4F,9A,1D,E0,09,E7,C2,11,2C,28,B1,EB,1D,B4,78,BE,F4,E4,29,5A,DE,E1,C0,35,3B,DC,6F,42,68,68,99,9F,1A,A9,E9,C3,41,FE,0F,6C,DE,A3,45,FE,BB,6A,E4,89,D8,2A,0F,04,92,55,BF,80,F7,6F,7E,4B,08,12,36,EB,85,D7,7B,A8,32,52,4A,B9,63,9A,CA,FD,F3,65,B5,26,4F,9E,23,D8,0B,C3,DA,A1,48,04,9A,77,79,9F,0A,24,36,C1,A2,77,96,43,A7,86,BD,68,40,B6,20,9A,C3,24,C3,1A,7E,24,03,23,26,77,07,08,B2,42,39,90,AD,2D,F4,21,36,FB,B3,91,20,B6,5D,4C,C9,32,E4,D3,AC,08,49,1C,C1,95,DC,BD,D3,FD,14,1E,6D,15,BC,A1,28,06,DD,24,BE,28,1D,28,4B,27,69,9E,77,75,A9,0A,34,75,C7,2F,95,A8,93,6C,5F,5B,70,AE,81,0C,5F,81,B3,AE,95,89,96,16,57,38,3F,21,29,C0,64,BC,26,CC,68,EB,90,B9,7C,E1,14,3D,90,06,B5,0A,FE,95,C8,FA,C8,E4,20,A9,E9,89,41,2C,C2,8F,04,05,AB,36,4F,8E,FF,0F,D7,5F,23,6B,50,35,79,36,C3,7D,A3,CF,E8,6B,4A,00,35,85,39,8F,5B,B3,5E,4F,E5,9E,99,AF,6B,D4,E9,AA,CD,3C,0C,30,CC,6D,72,64,D7,72,88,E0,38,FF,CC,4A,1C,45,59,EE,92,08,02,1C,EA,FF,9E,B0,8B,D3,B0,18,55,83,71,3F,77,D1,11,65,E4,EF,6E,E5,FA,23,70,9A,07,AF,8D,5D,4D,B1,87,ED,AE,C2,50,3E,17,82,51,BB,73,2C,17,9F,D5,D2,5E,E6,34,27,9A,C2,04,B5,E6,43,79,26,0F,3E,D4,16,D7,5D,1B,EE,D1,EA,06,05,4F,74,69,CA,EE,6D,E1,3E,39,37,DF,4A,C1,B9,D0,5F,56,E9,41,7A,13,9A,09,BA,A9,A6,1B,F9,2D,E9,67,7B,E0,B9,5F,56,7A,81,1D,B1,A3,1A,9E,8F,A0,FD,2F,96,ED,5F,5F,E4,79,92,89,BC,03,EA,C4,74,AC,3D,68,4C,49,BF,7D,25,6A,5F,BA,23,DF,F7,C3,FF,E0,EA,56,E7,54,85,C9,80,58,D2,67,8E,B5,0C,7A,5A,DB,29,45,05,18,AA,B3,26,88,47,B2,F3,B1,1A,26,54,F5,27,04,45,6C,9D,09,7C,F0,73,23,AB,D8,77,A2,05,32,06,D5,1B,59,20,24,0E,14,3D,92,52,02,0C,3D,14,3B,7C,C6,C9,16,8A,F4,84,4F,F2,EE,26,6F,DE,8E,58,6D,55,23,D9,6B,29,11,7E,A3,31,8F,0F,04,6F,14,50,C7,0B,7C,13,59,32,71,5B,72,7C,21,DD,B9,71,6E,5A,9D,E2,62,1A,2F,CA,0B,8D,0E,6F,37,82,7E,76,8B,92,FC,EA,95,63,AD,04,BC,68,25,39,D1,83,D5,46,2C,57,D0,DF,A1,6E,05,1D,3C,3E,4A,67,08,B7,E4,F7,52,D3,4F,16,57,3C,77,9E,3D,FF,BE,6B,FE,ED,1E,FB,76,C2,58,84,0D,62,B3,8D,5C,91,34,17,B7,BD,39,C3,A3,2E,C6,96,92,D3,89,31,69,D1,4B,ED,D3,D2,68,BD,EA,52,7E,17,1F,B8,30,9D,3F,CE,56,19,CB,EE,EA,D5,53,D0,6C,0E,95,23,06,77,79,52,C8,02,07,6B,CC,83,84,32,A9,7B,2D,45,08,FE,D6,DB,A5,70,0A,EA,DF,36,2C,75,12,85,49,C1,82,6A,A1,4D,4A,6C,0A,04,4E,6B,C7,D7,16,2E,CA,64,F7,EA,D8,60,71,6C,AD,7A,31,F2,07,60,68,6F,77,29,84,A5,91,8D,EA,DA,28,C3,B7,C2,96,16,EA,40,15,EB,3F,63,B5,E6,8F,8E,5F,A9,C4,A9,6A,0A,62,A6,7A,0D,6A,F7,24,7A,68,77,32,64,9A,38,56,DD,EC,58,CD,D4,5F,08,32,9B,7E,7A,BB,48,57,E7,21,70,DC,06,6A,41,58,A3,69,05,E5,CF,62,14,A0,4E,F0,20,05,3F,BC,FD,A8,0B,5E,EE,1C,43,B6,4E,70,7C,98,80,FA,08,64,4A,86,EE,42,0F,4F,EF,12,63,72,AF,9A,7E,96,F8,60,7B,54,85,71,96,4D,25,B2,47,88,15,C9,DB,64,8C,E1,30,45,87,91,5A,EB,79,01,68,F6,4E,03,49,67,18,E3,F9,AA,32,CD,17,13,1E,60,1B,B7,80,85,AA,5C,EC,5D,08,A8,52,D3,A7,A9,B6,CE,07,8D,83,76,44,BD,32,A6,56,83,07,23,94,39,45,AD,C3,61,3C,A1,97,96,C9,1A,CF,FF,B1,A1,29,3E,63,BC,F4,73,E9,7C,70,42,C0,77,22,C2,1B,C3,A1,77,08,12,F8,74,2C,81,49,08,27,EE,9C,69,0B,E3,AE,36,69,82,14,2C,6D,99,7E,DD,27,6F,9D,31,17,9B,80,75,51,B2,A3,48,D7,88,1B,57,CC,19,E5,C8,82,53,EF,29,F5,FD,E5,53,3C,1C,7D,87,A4,AC,C3,BC,94,72,66,81,6E,72,4B,E8,9E,5F,4C,B8,D3,54,2D,2D,5F,A3,EA,DE,4D,E2,3F,58,FA,85,41,86,46,C3,EE,7C,8A,F2,C5,40,D5,59,E6,F9,EC,6F,02,D4,8F,EB,15,97,DD,F1,EC,4A,14,50,90,0C,1C,C6,B1,DF,5B,D1,1E,8E,E8,54,FC,F2,F5,98,3D,30,37,DA,F6,84,F0,E3,93,FD,C6,0C,BD,B2,01,91,C8,61,88,51,96,29,BD,80,8B,16,15,7E,57,46,37,52,BB,A7,52,89,CF,CD,BE,90,CC,BA,2C,31,5D,B2,AE,5D,C3,21,65,BE,5D,6A,95,02,2B,6E,DE,12,DA,95,BB,87,40,52,74,FA,F2,D6,3C,40,EC,29,BA,8D,2D,56,80,BD,A3,D0,20,12,25,81,98,E9,EC,F9,AD,4D,93,52,57,B8,34,EA,31,95,D2,97,B8,6B,8F,5E,1A,1C,2F,F4,58,52,E5,6C,A1,2C,69,91,F6,22,D5,DC,D0,0A,D5,C2,3F,95,D3,DC,E2,65,07,CA,69,A2,03,95,5F,89,83,6C,6E,71,56,9F,03,7D,7A,B0,43,65,3F,B7,DA,F6,29,EC,F6,A5,22,86,E3,6A,9C,76,03,72,F8,0D,B5,FC,91,2A,0F,35,AD,98,CF,BD,3E,5F,1D,6D,3C,F8,FE,B4,82,BC,61,99,94,07,1C,47,7D,47,3A,AF,5C,7E,DC,D6,E6,5C,F4,46,BC,FB,39,ED,57,79,4E,27,DA,95,EE,58,0A,9D,CF,CB,74,BD,D5,7E,85,B0,8D,20,6C,9F,02,AE,DF,F5,32,57,FC,FF,41,76,27,DD,71,F1,8A,85,35,09,E5,7A,2A,F0,44,A3,BC,7E,5C,09,D4,9E,04,D0,89,30,33,AF,D8,7B,6C,82,9A,06,3E,75,6D,FB,38,BB,B1,A8,00,B6,84,35,98,5A,A6,88,49,30,F2,E5,23,19,24,0B,51,39,3F,FD,65,DD,E6,7A,4C,E2,91,AE,87,81,A9,8E,77,4E,21,37,B9,61,64,71,B2,EB,9B,51,43,98,8B,94,C5,7B,C5,B1,BE,2C,6D,F6,03,57,A7,31,5B,B9,BD,3A,F6,C0,D5,47,55,05,D4,B3,D2,40,56,C7,7A,6F,88,59,8F,93,9D,CD,B5,4E,D5,26,9B,CE,A9,B1,E4,A4,CC,36,19,52,04,92,56,F7,CC,58,62,2D,E7,0A,89,2E,40,64,B6,C9,23,04,09,43,53,38,D2,E5,16,53,88,FB,6B,C9,6C,F8,8E,0A,DC,16,B2,A7,50,F0,3A,16,BA,6D,EE,DA,E5,D6,CB,85,7F,40,6E,6E,21,55,1C,90,E5,74,76,46,8F,5A,38,F2,A3,A5,2B,E1,FB,9C,E0,40,91,1B,1D,B4,EF,54,E0,6D,DA,8D,D4,54,DE,CB,AA,12,CF,22,16,60,85,15,B6,2E,E5,F9,B9,B9,30,A7,D2,16,7A,4B,11,69,8D,51,21,AC,5A,54,17,8E,EC,C0,CE,13,8E,D2,93,8E,8D,1B,78,03,BE,16,23,3A,54,56,02,19,33,B4,88,43,0D,AF,3F,2B,25,20,EC,B7,CC,4B,B9,01,8A,B4,C6,10,AD,75,92,64,A3,EA,69,C0,84,19,25,14,CA,71,5E,B4,C1,1A,4F,BB,71,BC,AF,EB,BD,FF,8D,C9,58,54,23,B7,AA,34,57,57,AE,46,BE,F9,B5,F6,C7,B0,37,D4,5C,17,CD,44,E4,A9,C3,22,67,B3,AA,59,C4,3E,89,EE,04,60,EA,1C,66,5D,DC,03,93,64,C7,1F,9D,F3,00,39,46,E4,41,2B,7D,7D,26,FA,87,12,96,20,82,C3,DC,C7,4E,23,59,01,DA,CE,9F,65,97,A2,7D,9C,6B,37,F2,0F,2A,B3,67,A8,04,6D,B9,D6,31,CC,2B,F3,F6,BB,C6,36,5C,40,AA,07,B9,22,14,31,34,95,7A,AB,24,44,47,C1,B7,05,22,77,6E,DE,F1,07,A5,BD,BD,7E,2A,94,46,3D,60,DE,65,B3,8B,81,EE,46,5A,C8,C0,FC,30,0C,AF,FF,9F,75,24,78,2A,53,89,79,C7,00,B1,52,0C,7D,6C,FB,40,ED,4C,5E,9D,BC,0D,87,BF,93,6B,4A,0A,AA,27,A2,14,82,4B,33,3E,C0,BE,BD,2E,D3,0E,92,26,5E,47,27,0C,4C,67,C5,0E,A9,39,AA,2A,6C,D8,65,78,3F,8F,66,68,54,7A,1B,29,23,19,22,18,C1,CE,82,E0,95,78,0C,06,B2,68,9D,5A,66,9C,A1,5B,80,96,D1,95,A1,1B,4F,FF,90,2C,DD,31,BE,CC,8C,77,15,71,4D,7D,AC,12,F2,4B,69,42,5B,42,35,85,EF,A6,BA,F5,3A,2F,48,34,6B,A0,6A,0C,13,F1,8D,38,02,96,C7,27,B6,98,1F,46,AA,CC,A2,3E,B2,D8,09,94,C8,3F,A0,C5,21,41,FB,D1,B0,CC,B4,6D,29,2C,BB,AE,BF,F3,C0,AD,3E,E8,A5,7E,25,7B,63,AC,1A,6F,0A,46,97,72,47,57,9F,6B,B0,DA,F2,7B,A4,3F,ED,2F,E7,36,FB,DD,AC,58,E2,F8,AB,5F,6E,48,E4,0B,50,BF,F2,13,E6,09,A6,2B,62,07,7F,E9,53,BA,59,2B,AC,B4,71,52,92,62,4F,B1,57,6E,CB,74,F2,DA,BB,10,29,62,49,FA,E6,03,F9,6A,33,58,42,18,2C,99,72,56,ED,B4,C5,E4,67,A0,51,C7,E7,A5,CA,18,54,9E,B0,64,FF,A8,76,04,C6,CE,05,31,DE,39,51,54,B9,94,B5,A5,2E,12,5A,FA,73,20,99,ED,23,30,27,18,9B,35,FD,67,8B,55,61,33,73,EB,DB,9E,73,CD,F9,DB,21,37,18,D6,68,BE,E1,82,3E,D0,D8,62,28,75,66,14,5A,88,4A,9E,5C,FC,18,5B,74,4F,B8,F6,4B,E6,B2,2E,29,5D,76,15,91,A8,CB,DF,DB,27,26,10,98,30,8D,32,47,B8,E5,64,FC,63,78,42,C9,D1,CC,80,6D,D3,D4,26,9A,38,81,10,8B,89,34,90,4A,99,12,3F,82,1B,F3,66,B4,64,C9,83,20,3F,C4,FF,35,EA,D3,10,78,B2,0D,E3,79,97,C0,C9,94,20,14,53,27,B2,80,69,B3,68,64,D7,F5,44,E6,3B,F2,9E,07,79,2F,F9,12,18,F7,D5,2F,84,53,DA,D5,B0,86,C2,19,DE,14,21,27,94,75,D0,2E,29,4B,0C,9B,28,31,B4,F7,60,85,5B,EE,69,F8,6D,13,2A,65,80,6B,2C,B6,C8,7E,0B,F2,70,F1,E1,31,50,BA,14,B9,7D,C0,94,6A,59,81,5E,12,D1,20,CD,E1,11,22,BE,07,B4,A4,A0,CE,6F,41,C0,40,3D,F2,F2,C6,B7,81,8C,21,48,D2,05,5B,C6,ED,09,58,F4,77,7D,A2,B3,D7,A0,66,A0,71,FE,1E,A2,F0,14,7D,F2,01,F7,3E,50,24,C0,15,66,7E,A7,E4,9B,5F,35,CB,04,B5,50,69,2B,DA,F7,34,0B,99,F2,71,3C,C0,87,6A,8F,25,36,54,D8,6E,B8,52,3B,D1,BD,4C,D4,18,16,9A,A6,6C,D7,6D,9F,F8,72,4D,29,85,57,5A,0C,0A,56,75,AF,96,DB,E5,D9,53,CE,69,5D,95,06,43,3D,DF,75,D9,85,EC,22,11,04,2C,5B,99,B3,14,7B,A9,12,E8,19,41,AC,A9,D0,2F,9A,CA,8C,3B,1A,87,8A,91,4E,3E,AE,20,5E,22,20,9C,2C,A9,F8,48,64,1C,26,06,48,39,A0,17,37,4F,6F,43,8A,23,0B,07,56,C6,FD,94,9A,FC,1B,73,92,94,24,4C,4A,BD,38,AB,8A,00,31,B5,6F,D5,95,39,0C,83,10,31,F6,A0,9A,1C,5A,E8,A6,6E,13,9C,6F,F6,4A,D6,49,EA,A2,06,E7,ED,C1,7E,4E,DE,4C,F4,05,67,B0,65,C4,BA,BE,AA,C0,5A,37,F0,F3,55,B7,2D,AA,3A,FF,A5,73,4F,A3,7B,C8,93,22,12,FF,0A,A0,0A,9B,E0,6C,C4,86,A1,4A,76,2D,9A,4A,F3,7E,42,95,B3,BF,7A,49,98,B5,93,13,B1,0D,20,EF,75,96,49,34,C8,D6,6D,25,C6,00,8B,13,C9,79,52,0F,16,7D,04,A0,93,C3,7C,62,5F,7A,C5,A7,76,D0,C6,6C,E5,38,5D,16,BE,87,E4,32,20,0A,18,1F,63,54,EA,51,6E,B5,0B,A1,66,84,62,C9,C8,D3,F2,85,AE,5C,30,70,D1,7F,96,72,BF,90,A5,94,E2,68,7A,D9,E7,CE,D0,78,95,66,DD,37,96,A0,21,31,35,49,1B,4D,76,DD,F8,D3,67,8D,3A,B1,21,60,25,0D,1A,E6,0C,93,9F,6C,A4,78,49,23,FD,F7,76,7E,2B,BD,19,78,D6,D4,D4,7B,9D,73,6F,E6,EF,6B,10,11,D5,EB,53,39,3B,EE,7A,89,28,F1,4F,11,41,2B,BE,4C,C8,65,51,9D,81,2A,BC,B5,F7,5B,A8,0F,EE,EB,C0,41,24,70,F7,17,18,2F,C3,D7,6B,39,12,3E,75,C3,2F,E7,8C,10,EF,E9,46,32,AD,89,17,AC,90,A3,4F,3E,02,0A,CE,DE,A5,E4,3E,BB,71,4F,F0,04,3E,81,70,F2,A5,4A,10,41,BF,C1,02,CD,A2,42,0D,57,65,DD,5F,BD,CD,A0,88,D1,E4,23,A3,16,32,BF,17,D7,16,1E,8D,C7,44,E3,76,FD,66,4F,9E,D6,44,48,DE,F7,AE,A6,9D,82,F6,6E,21,E5,B5,E2,9C,96,EE,9D,D2,11,FC,07,6B,BF,10,EC,15,59,9A,A6,F4,0F,DD,0F,27,E3,EF,A7,D0,5D,15,E8,86,CB,EC,DF,33,22,1B,45,98,71,AE,BF,AE,11,E3,4A,E4,F9,E1,B7,8D,02,C5,B6,17,B2,B8,FF,DA,3D,AC,93,7B,89,EF,51,B8,DD,14,72,C5,53,F6,E3,59,E9,DD,3C,9E,AB,2E,AD,FF,05,15,4D,DA,F3,A4,05,CD,78,69,F2,28,66,7B,83,7E,8F,55,85,86,4D,A7,C1,47,B9,FA,12,6A,29,09,ED,FE,6F,3D,06,C0,13,6E,91,07,63,D7,C3,1A,AB,64,8B,56,C0,BD,68,4C,84,1D,E5,FE,D2,EA,96,E2,FA,2B,AD,9B,EF,C1,B8,49,B0,9C,BD,BC,11,11,73,C9,40,D4,B5,B1,87,5B,BE,B2,16,EA,48,8A,F4,AE,51,76,A3,C6,0F,7E,BC,FD,8D,69,EF,2C,1B,24,FF,72,E8,E6,A7,D3,A8,82,CD,71,C5,9F,24,35,82,38,BE,DB,E2,12,A6,05,B4,F1,88,8B,19,23,12,70,0B,8F,39,92,59,86,1A,80,43,F4,BE,64,2A,11,12,14,00,D7,4D,02,B4,AC,49,B0,8D,ED,6A,67,06,DA,C1,B7,30,C0,38,EF,67,63,2D,9A,CC,8F,7E,89,B2,69,4F,D5,7F,13,8F,5B,CE,E8,2A,C0,E6,1E,D8,0B,17,96,AB,C6,65,F9,F4,53,CF,FD,D2,DA,5A,44,0F,E2,57,F1,FB,5C,60,B9,8D,60,4B,4E,6E,AA,13,9C,A2,3D,57,D6,8D,10,D9,AE,13,B3,A3,49,13,4B,41,C1,62,51,6A,28,DF,A3,01,96,EF,1E,77,DE,1E,C5,32,05,46,EB,91,DB,73,44,E0,F3,96,D5,77,C4,93,52,A0,E8,E6,00,D0,FC,2B,72,9D,56,6F,E2,14,EA,C1,EB,B2,C0,92,4E,BC,C2,93,54,AE,06,CF,4A,C5,6B,E7,BF,1B,CD,D4,DD,FB,E2,07,82,84,7A,6E,27,32,0C,14,F7,DA,A6,70,D3,AD,61,A7,46,49,A4,E3,44,D7,79,0A,78,7C,A8,2B,91,48,0A,4F,01,46,73,C6,E0,1D,8F,0A,03,BF,AC,23,8F,C4,89,53,17,4B,7B,3F,70,87,1B,F3,E3,5E,0D,FC,E5,3F,E4,21,9A,F8,D8,38,C2,B0,31,3F,3D,89,9A,70,CB,21,C2,8D,9B,43,03,57,9D,55,98,A8,E6,E6,D4,44,D0,EA,D3,98,F6,E5,B8,4D,94,FD,74,BE,06,F8,7F,1E,4A,1B,72,DF,0A,3F,96,E0,A0,10,8D,CF,68,4D,9E,B7,C5,44,1F,80,CD,75,AF,CA,0B,9A,88,31,60,CC,25,F5,A6,D3,F3,B6,FB,BC,6E,B2,C3,19,A5,94,B2,82,81,0F,F9,74,FB,9D,72,0A,93,1F,58,9F,23,5E,F3,97,0E,50,E8,3D,A6,23,E9,55,98,D3,48,68,E6,E3,47,7F,5B,D9,79,C4,FF,46,B4,84,97,37,AF,3F,DE,98,E1,4F,CC,08,BC,83,03,F9,6F,5C,4B,B0,28,A5,EA,CB,EA,09,41,7C,71,64,81,4A,A6,63,25,F6,90,99,9F,03,5D,54,AB,F2,52,F5,08,E1,50,26,0C,56,7A,0C,B8,2B,A1,63,70,01,C9,EA,43,60,CB,4B,C0,6D,95,80,D4,1D,BF,F5,E0,2E,19,EF,C2,32,00,96,D6,B6,C3,6E,44,D0,41,91,FD,E2,69,10,8F,F4,31,91,B9,D0,2D,7F,B6,0D,92,BE,57,CD,0C,B5,B8,10,9F,BC,7C,F0,B8,9C,8F,92,EF,78,EB,97,6F,8E,8B,F9,18,DC,8B,23,EA,21,EF,3B,93,CD,4F,26,EB,C2,CC,49,A3,8A,E3,3C,28,20,24,29,6E,3E,70,76,ED,81,1D,AD,A5,E2,72,F6,19,9D,A2,1E,DF,A2,3A,57,92,DD,F7,EA,B1,71,85,29,7D,E4,7A,19,99,D0,21,20,0D,D7,13,EC,9F,C3,8D,4E,1C,68,99,9E,0A,5B,D5,FD,4D,71,98,53,2D,7A,DE,B8,79,AF,8F,F2,17,57,D1,55,62,A3,9C,4D,D6,00,F0,5C,7C,61,B4,33,F2,14,1E,CF,38,F5,1F,A3,59,91,5E,18,08,F5,A7,09,D8,94,D3,01,74,43,7E,59,EF,DC,B1,F8,7C,2B,19,6D,73,B4,10,50,4E,CC,9A,53,7F,C1,9A,A0,F9,6E,FD,55,9C,4E,C7,4E,A4,C0,17,44,1B,DF,88,3C,5C,01,14,6B,05,F5,B2,22,E0,42,83,F1,AB,DF,3B,08,C6,66,54,24,4D,A5,B2,C5,C8,77,AA,96,1E,D4,94,D3,77,D0,9C,E4,E9,5B,68,F6,D6,27,6C,46,6A,DB,4E,67,C7,E6,7A,86,40,5B,B5,6B,B2,DF,97,C9,A4,62,95,25,DF,DB,74,3E,88,B8,54,58,84,21,8C,A9,4B,58,18,CB,AF,71,DC,DD,CA,D3,7B,CD,8E,E4,0D,E0,39,4F,8E,0B,9F,BE,76,94,9D,C4,7A,40,3A,B6,6F,77,03,AF,BF,CF,CA,63,79,D8,EF,8B,8E,6E,2E,56,DE,90,66,4A,36,0F,1B,16,A3,1C,8E,7E,BB,5E,69,EE,22,4A,AE,18,1F,CC,89,5E,D7,DD,39,CF,F0,0B,50,82,42,56,F1,54,4B,A2,8D,B4,91,0E,22,04,2F,EC,79,A6,30,E9,F9,48,D2,26,2D,E1,F5,5A,0A,C5,34,30,93,AB,6C,31,0B,62,61,F4,F9,73,2B,1D,DA,53,24,54,D9,B6,06,E8,83,43,4F,06,BA,B7,8B,C5,68,40,88,B4,D5,BB,85,03,36,45,2C,DA,7F,C8,C8,B2,43,86,12,AE,E6,BA,E1,94,4B,71,25,80,00,58,71,D0,16,02,5E,0C,69,D6,4B,BA,F1,CF,4B,B8,B5,13,6A,4B,DE,62,07,ED,50,19,14,61,13,01,1E,28,19,F1,2D,1B,D3,7E,8A,7C,A2,95,F6,01,5C,02,D2,4E,25,CD,CD,37,24,20,B0,E0,5D,75,7C,6C,7F,51,EF,FB,A2,81,AF,11,84,C0,6E,B8,63,2A,A7,25,F0,9E,38,93,D6,7B,3F,FA,56,00,AF,B1,87,F8,5E,D0,3F,3D,B7,40,6F,55,C0,C1,B2,07,B3,5C,91,BE,BA,D6,1F,59,D0,0C,1C,DE,E8,20,B9,91,FB,CD,DF,AE,0D,71,ED,F9,CC,64,23,C9,73,51,C2,1C,3F,31,30,AF,44,9F,8C,FE,5D,FE,E5,91,AA,74,D3,75,24,59,C5,0B,05,1E,FB,A9,0F,3A,DA,EB,E8,A5,FE,6C,15,22,E7,5D,A1,60,F9,F4,FD,F0,39,10,ED,8E,6E,82,58,DE,AA,04,66,75,C8,E2,B2,E1,A1,71,D5,8E,53,B6,85,12,FA,E7,C9,C6,44,81,BD,21,33,91,F5,87,1F,69,9D,F2,46,DC,B4,01,B0,AC,C9,78,57,3C,6B,D3,52,81,28,0A,F7,B9,82,F9,89,6C,73,2D,70,B3,2B,F3,78,1A,D5,E4,C8,F8,72,8C,59,97,F8,38,3E,D7,62,8F,30,9E,0F,C8,EC,30,EE,11,0C,70,34,93,3B,DF,52,B9,34,22,80,5D,00,4C,5E,6C,87,5B,64,DA,04,87,30,F6,C3,5D,E8,B3,34,7C,F2,9E,7A,67,99,77,95,22,9A,B9,42,D5,05,F3,8B,24,DF,6F,B4,9C,22,C7,BB,94,CE,EA,55,0C,27,86,76,79,FB,D1,88,32,B2,26,E8,AB,AB,87,E6,65,44,C2,0E,92,7C,95,6C,25,B1,DA,8E,A6,41,7B,89,DC,4B,C4,9F,A8,25,4E,68,5F,4C,E8,F5,B5,C9,FE,C9,64,12,09,3A,DC,E3,7A,09,8A,C5,01,44,EE,37,B6,58,98,3E,24,18,F7,D4,E9,8A,49,64,5D,86,E8,76,F6,17,41,6D,5F,29,0A,8E,32,20,63,8F,26,E3,3B,F5,F7,30,93,1F,2E,BB,72,66,72,16,98,9E,28,45,D4,31,7E,F6,ED,9E,C8,D0,87,72,97,29,9F,1D,3F,70,E0,78,C2,52,9B,ED,49,6D,5C,69,60,81,05,72,72,B9,D7,05,46,85,77,46,C3,9E,0D,AB,CB,7C,FA,D3,32,1D,1D,0F,AF,5E,ED,1D,B4,D4,C2,53,86,60,CB,55,51,32,98,EF,85,02,BA,D4,A4,06,95,BD,AB,53,6F,6B,62,96,DD,D3,EB,B3,75,DC,58,00,12,09,47,0A,60,03,53,29,7D,4D,D7,FC,41,59,CE,22,54,96,AD,22,D7,1A,26,A1,14,F3,4A,05,A5,67,D8,C5,CB,A2,EC,2F,7F,4E,17,59,2B,48,98,59,D2,67,9C,FE,48,A2,3E,C0,04,6B,20,D8,D7,C9,EC,96,57,C4,BB,CE,F2,AE,B0,81,9B,36,0B,D0,C7,67,E6,EE,48,CE,45,C4,B7,1C,3F,AB,FF,73,C4,14,7E,90,5F,25,7B,B7,AD,19,37,E9,67,CA,EB,FA,28,DE,4C,E2,CB,0E,CC,C5,36,98,7A,3F,BC,58,F6,B6,C6,84,79,DF,7C,96,93,48,0F,BF,F1,9A,08,76,51,6F,F4,F8,4B,CB,2E,B9,01,92,4A,BC,77,6D,F2,4C,D1,00,7D,B9,FB,74,75,84,1A,CA,32,53,3A,B1,9B,14,98,3D,29,FC,BC,80,18,F9,65,84,80,C5,B9,29,2A,48,08,16,BF,0F,06,E1,07,63,DD,90,53,5D,F6,2F,50,C7,8D,26,B3,E7,1B,2F,B4,C3,58,F5,70,32,83,49,77,04,2F,19,B2,BF,23,2E,69,F8,ED,22,D2,7A,9F,45,D6,8F,24,05,B7,CA,CF,E0,3B,78,27,13,79,B2,F5,10,DD,7E,0D,84,F2,85,3E,1D,E9,24,05,69,86,8E,C9,87,FE,99,EE,B4,FB,21,F5,FE,31,B5,3C,84,F1,7E,6D,EF,09,6C,AA,E3,E4,17,F2,3B,D9,01,51,49,F3,EA,6C,5E,13,92,44,3E,60,AA,26,8E,C2,A3,54,EB,62,E1,22,C0,27,25,F4,34,20,28,23,AB,A1,86,5B,C8,16,77,4D,80,1E,D4,23,D3,16,A1,9B,17,25,C8,44,82,04,C4,75,AA,8D,BE,6F,49,86,CE,30,C9,51,67,A4,2C,A9,8F,C8,BA,5F,DA,18,89,FF,E9,D8,D9,D6,02,D1,D1,50,E4,EE,9E,8E,E6,53,32,86,3B,EE,3F,BD,72,16,1B,45,5F,98,DF,EF,B2,50,FE,BA,01,B3,05,99,1F,E3,DC,34,2B,51,9D,46,44,76,5A,58,BF,DB,23,DD,C5,58,C0,34,DE,25,9C,94,C8,19,81,CA,B4,48,05,EB,D8,69,84,D7,2D,C1,39,D8,7F,99,13,BF,49,2D,3D,36,31,0B,C9,F5,C7,D1,E5,2C,58,27,BC,0A,98,61,FB,01,E3,8C,24,54,F7,0A,27,22,A3,FB,B7,9A,23,FE,F5,A9,FB,5C,CD,23,D6,70,4C,45,6B,72,43,5D,E9,73,3C,3E,C0,24,6C,F0,11,26,94,EA,46,3D,69,D6,A0,AF,4C,95,8E,8B,77,4B,55,0F,16,DB,EA,3D,A9,CB,72,6E,F3,B6,21,69,5A,1F,2A,AE,85,5F,41,43,E3,54,C3,6C,F5,BC,2D,72,49,F4,3C,4C,73,CB,85,1F,48,15,F9,E4,64,DB,21,7B,CD,46,A7,2E,4C,2A,44,48,CC,F3,70,EB,85,53,46,8C,8D,DA,6B,3B,0E,D0,75,5D,86,01,45,C9,4D,E4,57,5E,0F,B5,9F,09,B2,EB,64,A9,57,9F,70,34,E0,22,9E,48,63,46,71,06,42,AE,81,59,FD,0A,0D,D5,41,0F,B4,8D,EA,63,CB,15,1A,34,F6,20,22,E7,3B,F7,BB,C4,D8,A9,B1,A7,96,6E,D6,F7,FC,15,F7,E4,5A,8B,E1,E9,11,19,A0,CA,86,CE,BD,A0,75,91,C3,6C,2D,E3,29,46,76,9F,67,DE,17,C7,A8,A1,74,CC,5C,52,6A,00,F5,52,5E,19,18,CA,2B,93,90,19,7B,47,50,B4,80,BE,D9,B0,9E,3D,B3,36,B6,59,C9,2A,81,3D,48,4A,CA,1E,81,0F,22,70,55,88,F4,67,A2,E6,93,F4,F2,F6,84,FF,A4,B9,15,8B,93,0C,6C,91,60,1F,CE,B1,34,CB,F4,A1,BA,D4,38,31,57,7E,D6,4D,85,F0,0C,25,73,58,BF,E2,94,D9,5B,D9,44,AA,E4,C6,3F,3B,85,50,DB,A5,4A,1D,BC,8B,F0,7E,38,FB,F0,8D,76,19,ED,EA,C6,5F,BA,28,38,F3,AC,84,22,B1,9A,5D,F6,56,87,C0,18,7E,A4,74,7C,3B,B3,80,3B,F0,38,53,E8,9B,5D,8A,BC,16,EE,76,9E,6B,24,15,BE,52,31,95,97,04,83,EF,19,95,C5,49,31,C7,28,C9,99,DA,7E,E1,18,8D,4A,CB,B2,76,42,7D,26,EA,94,A1,E8,D1,2A,5D,37,FA,6F,FD,62,7A,15,89,7C,EC,56,0B,F6,C2,11,30,88,28,73,07,9B,FA,0D,81,F1,22,C2,52,46,E2,41,B2,5D,66,10,40,BB,40,3F,15,C3,30,15,1C,67,B9,A7,10,6C,4C,83,1D,C7,09,1F,68,50,B9,36,DC,04,44,A9,E0,B3,52,B6,E1,6F,BA,33,44,7B,78,10,BA,11,3C,DC,24,BF,17,C8,EF,2A,41,E9,B1,EC,6C,9A,C3,B3,03,CF,DF,99,1C,C5,C4,97,C3,3D,6B,60,EE,B7,50,81,F2,95,60,C8,15,C1,49,AD,43,02,0A,69,E3,23,C3,EC,C8,BF,86,55,D4,CC,4A,E7,CF,80,63,90,E8,F6,3F,1A,A7,EE,39,48,5A,49,81,E3,A9,37,07,4E,A6,8D,60,50,89,EA,F6,0A,CD,7B,A6,D8,11,1C,0C,2E,CC,F6,2E,68,27,57,1D,E1,36,17,E0,06,99,E1,DD,8A,0E,EC,8D,E1,F0,30,16,1A,29,AD,AC,80,C6,4B,19,CB,85,9E,35,1B,14,25,C4,DB,74,DD,93,4A,84,3A,C9,6A,44,A6,75,08,6F,71,13,E2,D0,BC,F2,2C,F2,3B,B0,C6,22,FC,66,96,4F,29,73,9F,90,77,D6,54,26,BC,26,6F,1F,18,5E,FF,E0,B1,C9,12,AB,DF,BA,5B,EC,85,56,24,E4,EF,7E,F6,A1,15,0E,B2,8E,73,65,77,36,E1,FE,E0,56,3F,56,F2,6F,C0,2F,99,02,CB,1C,C3,38,75,4C,60,58,73,9E,8F,57,9C,0D,BB,FA,D0,1C,AA,B1,18,44,36,F6,31,4B,25,6D,9A,E6,04,D2,50,AE,56,6C,0B,7D,61,83,F7,F9,5F,FF,9F,F8,D3,C7,92,C3,54,7A,D6,9A,B8,B4,CC,52,20,CB,B2,3C,71,25,35,EE,24,AF,79,79,1A,5A,56,AB,C3,E9,BD,7A,6E,EE,C0,DE,C0,8D,42,5E,0B,8E,CB,26,B2,4D,7D,19,C5,09,AD,DC,5C,12,39,CC,16,54,27,B3,96,7D,17,7D,B9,0C,26,D4,AA,1E,59,70,FE,8A,A6,D4,07,68,2E,F5,AA,22,22,93,00,DA,B2,F1,75,73,14,F2,5E,11,60,BC,B2,81,0E,88,46,65,18,39,F5,02,06,23,23,64,0B,55,D1,4B,F0,86,0A,4C,19,FE,8B,B8,A5,F5,47,51,E2,71,8A,2C,22,B5,AD,D8,52,29,F9,26,60,A6,1A,0C,EF,CD,48,8F,B3,26,BB,71,31,3B,D3,95,83,2E,B9,66,2D,10,A0,B2,B9,DC,CA,FC,D7,87,39,F9,A2,F8,F2,64,E0,4C,51,08,87,61,B4,CE,84,7B,4B,5B,37,2E,70,77,2C,CC,14,75,CE,9D,58,3C,DA,93,DC,DC,41,0E,AF,72,4F,92,27,1E,D8,B7,E2,8A,29,30,C0,D7,D4,0C,58,72,09,22,75,D1,9C,CA,31,31,D2,8C,B7,06,77,15,F5,B6,A1,FA,66,47,40,57,2D,7B,0E,FD,0C,54,D0,24,8E,9A,A0,1B,4F,B7,BB,D6,98,70,AB,4C,BF,75,31,09,33,60,84,3F,1F,31,AE,DD,11,76,B7,57,97,A0,40,FE,74,DC,06,78,1E,89,6C,98,30,DF,5E,3D,8F,33,02,46,F9,FD,90,45,E9,3F,75,F9,69,35,41,DB,A1,C3,39,0C,B7,6C,B2,5C,9C,DF,1E,85,60,AC,CC,DF,AE,57,FE,03,D4,50,30,8E,25,E3,EA,68,E4,24,D9,74,84,9A,ED,67,F3,05,D2,C0,4C,E7,75,A9,27,9C,3F,4D,09,7D,01,3F,73,5D,CC,8A,3B,F9,83,FE,BB,10,15,F6,6C,E5,3F,BA,C9,A2,61,C4,B1,24,FF,A7,99,C2,A6,3D,62,58,AB,63,A3,23,76,C2,C2,B7,EB,3A,F5,DB,6F,67,8B,5B,81,22,6C,83,21,25,E7,A0,C9,E8,D5,C1,CA,46,2F,99,FD,A3,3A,A2,DE,CD,1F,DB,DD,5E,97,6B,08,64,B9,BC,B8,C3,A4,18,20,E9,1D,81,42,0E,C2,96,38,BF,A6,8F,32,8C,45,C5,06,BD,64,19,F0,03,E2,2C,1B,A8,E6,55,9C,86,1A,FC,30,54,BD,FA,7D,72,8D,2F,2A,13,36,5B,0C,58,0E,11,F5,99,E4,0F,A3,48,23,FD,43,28,F6,CC,B3,51,CB,58,AE,4B,CF,85,03,84,9C,B8,05,CE,9D,1B,0C,75,A1,43,D0,CE,94,5F,AA,FF,DF,12,F5,48,F6,33,BF,6E,66,22,9B,84,A2,42,68,47,73,39,FD,C8,A4,26,1C,20,6A,34,B3,F4,58,F6,3F,26,9A,13,F4,22,6A,AD,80,9B,B9,10,B8,26,46,C3,17,41,34,90,5F,61,12,E2,19,7C,8E,72,06,B0,87,08,1C,7C,97,8C,02,FC,92,1C,DC,6A,66,2F,A0,FA,7A,E3,8F,13,82,E3,14,06,0C,BC,5E,42,C7,1F,F0,0F,4D,5A,6E,41,CB,ED,6A,D5,75,E3,2E,8C,33,92,DA,88,9E,06,EE,83,4D,60,51,DF,24,80,17,A8,39,9C,95,6D,CA,11,CF,6B,D4,A3,0D,E6,62,91,17,A1,2F,9D,62,EA,92,4E,6B,5A,7E,03,11,A4,EC,26,FB,8C,79,E8,B0,62,25,68,8C,B8,38,5D,4A,6C,7E,98,F3,91,27,84,D1,D8,6B,1E,0E,70,82,FC,45,A2,E4,74,6A,FE,9D,04,F9,BA,8D,16,2D,AA,42,E3,82,2B,EC,1B,65,1F,F1,0D,2A,19,8C,0A,B8,06,B2,04,DD,A8,4B,28,F7,35,34,7D,7A,B2,62,2C,9F,02,FA,30,3A,FF,B3,67,F9,B0,CF,98,77,F1,A5,D1,EB,14,C1,26,CE,0C,94,E4,A9,56,5B,B0,77,5C,C1,B7,55,DB,85,A8,AC,37,20,99,3E,6F,00,FA,DB,55,75,10,A3,5B,0E,63,B8,BB,CE,D5,6F,8D,48,30,BA,BE,D5,CB,92,20,5A,41,C0,F3,A9,F3,88,AC,34,64,75,3F,69,56,41,87,73,60,78,3C,D9,C8,BC,07,E7,8C,B6,D5,71,D2,46,74,23,AF,D4,9D,0F,13,A8,B2,38,94,60,A6,07,3C,ED,9E,74,C3,B4,6D,33,78,8C,53,33,A1,71,C3,D5,A6,C8,A0,E3,33,44,BB,89,09,C7,6C,17,04,51,08,B8,46,A5,9C,A5,84,00,96,6B,62,7E,0A,5A,51,50,C8,02,2B,5F,E6,FC,65,B2,11,D0,BB,2E,98,64,5C,07,05,42,A9,F8,BA,49,28,E5,78,B9,61,50,2E,EC,1F,8C,EE,AC,6F,6C,72,96,6E,8B,2C,CE,D7,09,EB,20,07,75,39,23,C0,3E,A6,7B,CC,AF,6B,E8,7D,F4,1C,41,F4,AB,78,4C,4D,B0,BF,1D,18,44,45,C1,DB,B2,4A,90,15,04,D4,63,3B,09,F9,B1,BE,CE,E4,83,4A,0C,62,90,4F,29,3D,D4,61,F6,3F,6D,16,B5,9F,75,90,20,56,08,36,E5,E5,CA,C3,B9,91,A5,FE,8A,C3,91,87,50,DD,79,DA,83,51,90,DD,03,B0,E1,4B,A0,87,C9,7A,70,47,CC,00,F8,B9,6F,91,17,83,21,9E,E1,94,8B,73,6D,BD,E2,CF,23,C2,6A,CF,FE,EB,4C,E7,7A,BF,21,C3,F7,4F,0B,80,E9,E6,21,D0,F9,62,3E,0B,01,20,38,87,44,7C,B5,6F,4A,E3,F8,BC,BE,9E,AF,B1,86,8D,B4,AC,16,0B,4E,0D,6A,BB,33,83,B9,29,E8,31,3D,35,15,08,08,20,49,BB,5D,F1,13,1A,91,F7,D9,55,04,0B,1D,4F,FE,08,9C,D4,60,B0,B2,E4,3F,74,F0,D4,4D,14,6C,4D,1F,86,E5,08,C5,B2,17,8F,6E,16,E4,F1,7B,2D,79,F5,B7,A1,DD,1F,9D,07,41,D0,22,D0,C5,33,FE,7E,84,3F,3F,F8,21,BC,42,D2,E5,39,2C,B3,26,94,B1,6E,9B,37,C9,F7,E1,FF,29,3E,6E,98,F8,9B,CA,98,DD,DA,76,8E,00,79,CC,EA,C3,9B,18,90,D3,95,8A,CB,5C,49,DA,20,0B,B6,A7,92,D8,FB,3E,CD,09,AD,EB,52,26,8A,AC,DD,AD,13,C9,99,F3,19,F9,28,C6,0F,1A,E6,CB,7C,66,85,E5,BB,EE,B9,78,7D,C7,B1,92,CA,DC,73,3C,13,82,FC,6E,A3,54,5A,29,2C,30,80,BF,AC,1F,88,C3,D2,D7,DE,0D,D2,8D,1C,55,5A,84,CC,82,B7,33,43,8A,DE,A9,1A,BE,F4,FB,1A,04,67,E4,7C,B5,5F,23,9A,E4,7D,50,0C,79,CC,28,D0,D2,69,37,50,BC,DA,BB,5C,DD,1E,21,3C,0C,33,B9,BB,F7,5B,82,5F,51,C8,8D,98,B4,75,B8,89,04,CA,3D,71,F2,5D,A4,E3,61,39,4B,BC,9A,6E,4F,97,EB,EA,BD,62,52,EC,5A,A8,0F,88,BF,FF,D6,2F,E8,17,88,5F,BF,6E,0C,EA,A3,B8,87,75,09,2F,FC,C5,08,C1,FF,44,33,F3,C0,E0,F6,94,34,C7,6B,BD,59,1E,B6,78,9A,82,0C,73,76,03,D0,01,D7,C0,F1,29,74,2A,30,B0,9C,39,20,C8,52,F0,F9,DE,36,3E,A4,15,85,37,EC,3F,C3,2E,4E,0D,A0,2D,EE,73,08,28,4C,33,80,26,3A,07,10,C4,27,56,0F,F8,50,76,62,1F,22,30,F1,B0,D1,BB,CA,65,7F,F7,1D,18,C5,C6,AA,16,C5,A5,48,8F,CA,26,C4,AF,28,59,9E,79,EE,7F,D9,82,D2,06,77,0D,17,89,B5,9D,C8,E9,0A,92,BE,65,2D,20,A2,6F,12,B9,1C,73,14,FF,87,97,01,12,73,39,C7,96,92,52,69,85,A5,FF,6F,E7,44,0E,D3,16,44,C3,AB,D0,CA,2D,B0,9E,CF,E3,EF,6C,88,45,9F,89,CB,3A,35,25,AD,36,FC,43,43,16,1D,D4,55,2C,C9,E7,5C,B0,2F,F6,9B,66,F2,2E,15,77,72,00,5F,35,E1,EC,05,07,7F,30,F6,66,2E,9B,05,58,1E,6A,69,C6,B0,B6,EF,6E,5C,E6,E8,6C,57,6F,C9,77,C5,4D,A1,B0,52,42,C2,E4,20,97,94,AC,06,3E,B3,0E,A8,E0,3B,B9,C4,78,5D,C0,A8,09,AC,CF,76,11,A5,87,E4,0D,EE,61,27,05,1F,44,A8,E0,28,75,81,DC,BA,F7,CE,58,1F,2F,35,81,F2,E4,C8,EE,CB,25,D3,A9,87,75,4D,E3,74,A4,55,E4,3B,0D,82,57,FD,36,E0,B3,DB,80,FC,CC,B7,C7,10,24,DF,91,1D,46,09,79,9C,31,4F,60,3C,32,6C,BA,D2,BA,24,4E,4F,F3,0D,F5,4A,1B,68,0D,AD,C8,A2,6D,89,60,0E,AF,68,C2,2D,12,D7,D2,1F,25,3A,FA,73,F7,60,B2,CF,9E,EA,68,0D,03,6C,93,12,B6,3F,7A,5C,C1,38,02,DE,90,65,E9,29,99,3C,4A,33,42,01,EF,5B,40,DF,19,9E,51,50,85,8C,FD,31,AE,87,24,E1,43,67,4E,BB,4C,DF,6B,17,C9,69,F0,F3,20,7D,16,C9,FC,D0,A0,F7,E7,56,35,63,21,AE,B0,9E,D4,AD,69,E5,F8,85,76,1B,B5,28,BF,C5,D1,9D,38,43,23,AD,83,38,16,73,72,0B,D5,E0,0F,C8,02,33,59,7D,E1,18,D6,24,0A,F5,EE,AD,DD,58,3D,0C,05,1D,F8,A9,B4,1C,E8,69,FD,1C,A0,3F,D5,ED,8F,FC,D0,77,D6,01,7B,13,73,CB,9D,26,8D,38,06,7D,0C,A3,CC,B2,9D,02,CF,D2,D4,E3,5B,59,D6,E4,7D,0D,FB,AE,77,54,DD,1C,F3,26,34,C5,7F,4F,20,CF,13,D5,BD,DD,33,90,A0,FB,B0,8C,CE,EF,CE,F6,83,31,CA,23,56,CD,6A,23,3B,DA,A1,A1,6C,B9,B7,4E,7B,72,8C,CE,0F,C5,66,D9,0C,D9,8A,20,88,D4,EB,38,19,E0,93,7E,12,1F,34,C4,8E,88,63,1B,2E,41,CD,B1,2A,76,81,99,D3,E6,47,79,D3,F3,3C,56,9A,4E,A8,87,F8,EA,BE,56,41,AE,CF,65,5D,DE,D9,B8,B3,86,03,8B,6F,A1,A4,B8,18,56,6C,B1,72,49,1C,7C,8A,C7,5D,C1,40,47,74,E9,57,E7,02,87,31,FA,56,D1,FF,78,69,3F,B9,DD,B3,4B,96,E6,88,CA,A5,38,D6,D7,4A,7C,CB,15,A0,35,1D,14,EB,83,DC,46,A8,0C,99,7D,6E,37,81,88,03,7D,49,C9,F6,CD,8B,A8,49,67,E0,EC,61,E2,FB,A0,91,C9,5A,24,F9,4F,35,F0,CC,74,5F,47,A8,FD,5C,D8,85,A3,3F,D9,8D,4C,5A,1B,58,85,0E,5D,24,4B,47,C0,78,DD,EB,82,F9,D7,2D,88,F6,3C,83,77,8A,3C,E3,82,6E,93,E6,FD,39,BC,36,FB,8A,E4,B7,AC,D8,51,8A,63,87,58,71,C6,0E,52,1A,16,C2,8A,61,94,60,BF,88,B6,70,DA,6C,0B,E5,10,63,E2,22,10,C6,C8,BE,18,08,F8,52,47,18,8A,DF,F7,0D,3C,56,70,24,79,41,0C,14,9E,9D,CA,2E,F3,84,F1,EE,98,9B,D3,8E,42,8A,33,B2,AF,A7,B6,2B,A5,5F,4C,F8,86,1B,1C,96,8C,05,A7,01,CD,17,F9,37,8A,F8,9B,7F,EE,D6,3D,0F,49,84,0C,8F,37,64,90,9A,1A,79,F3,AD,D6,CD,24,37,1D,B6,4D,C8,A5,FB,8B,0E,27,C9,8B,59,D5,B2,7A,63,D1,DE,B7,08,91,16,87,3E,E6,91,57,25,0B,8E,FA,AE,3A,7D,46,2F,51,DE,55,F0,B3,56,37,8C,DE,34,EB,BD,4F,30,D9,1E,2D,63,46,64,4C,9A,73,DB,1C,6A,E9,FA,13,7E,C4,48,41,49,16,D2,7E,EE,57,02,24,94,64,5C,8B,FD,9D,29,76,04,52,EB,FC,DC,42,28,B1,ED,01,07,4C,C2,24,09,0C,96,ED,D0,81,A9,19,2E,65,3F,AF,9F,D9,83,DB,80,29,0D,6D,E1,92,DC,68,32,B0,B7,4B,C8,7D,4C,2B,69,92,EF,80,B7,6F,D8,B8,87,55,55,59,4D,AA,AE,D9,84,7C,67,A9,4D,A2,0F,DB,CB,6A,DE,1B,07,31,6C,3B,30,F0,C9,D9,25,C0,5F,88,14,EE,72,CA,01,83,F6,BA,C9,66,2F,0C,EE,3D,9C,B6,C1,61,5C,EF,DC,D5,04,B9,A0,13,BB,73,1F,99,21,E9,45,13,57,CE,A1,7B,AD,0D,F8,35,05,19,A9,42,7E,F8,F7,45,1B,12,66,0C,D4,A7,A4,46,78,F4,C6,C1,72,25,ED,E8,CC,4B,43,F7,34,19,B3,6D,3B,4E,4C,77,55,72,36,F8,C2,72,C9,4D,5F,9D,00,94,D1,0D,65,E9,68,AA,80,6C,42,42,1F,5A,85,D3,61,DC,73,14,5C,30,07,3C,92,DD,B9,5F,DC,10,31,FB,5F,C5,52,F7,94,22,FB,93,2B,EC,23,F6,DD,AD,4B,8A,70,44,BC,43,13,E0,20,67,3C,74,24,45,F0,E8,FF,1C,34,86,AA,F1,6E,78,DB,9D,6B,E3,9C,13,F7,0A,96,DA,38,CE,9E,7D,96,EB,26,6E,AC,41,01,55,ED,3B,D7,3A,EB,23,44,F4,76,3F,60,F4,84,D5,6C,F0,4F,BB,87,42,42,01,C7,78,B9,5C,72,4D,4A,9A,1C,02,C5,80,22,8C,23,A7,23,DD,01,93,D0,5B,2F,D7,35,83,36,6C,6B,E6,74,C6,88,BE,FB,FD,A5,8D,34,03,AD,AE,00,64,4C,C2,5B,B3,24,D3,50,23,42,18,11,47,7C,DB,10,C5,14,A2,F5,F6,B7,46,32,E0,AA,8F,54,7C,93,7C,F7,95,C6,75,34,D8,8A,2F,9B,B2,EB,BC,C0,0F,41,29,61,1B,29,5C,F1,44,2B,43,FF,5A,36,30,ED,F7,69,1D,30,A3,E0,8A,6F,D2,5C,AC,18,6A,1B,EB,BC,B7,93,50,C4,7F,C2,C7,E2,6A,26,73,C5,5D,5D,4B,9B,71,D7,68,15,16,15,C5,1A,2F,A8,52,77,58,E1,EB,F9,3D,7A,B1,84,05,5A,21,38,30,11,72,26,2C,BB,84,A5,E7,7A,95,2C,BA,91,D1,49,CD,7E,66,6F,D4,30,9F,E2,C7,7C,3B,AB,E6,D1,BF,69,75,A4,77,9C,DE,3C,96,D6,90,42,3D,A2,C5,3B,20,3E,E1,B3,B6,75,3E,BF,DD,B9,2A,13,87,A2,20,EA,4A,56,C0,34,9C,C4,16,D7,5B,C8,09,48,13,33,42,A2,A9,E6,58,D3,DA,6E,F0,DF,7C,14,CD,A8,33,8D,95,7D,F2,05,FE,E3,1B,AC,DB,5F,54,59,19,D6,76,05,2B,9E,33,4D,D1,60,02,36,87,C5,97,6D,5E,76,FF,CD,8D,66,2F,B8,C1,64,7B,05,B7,79,BB,89,D0,6C,EC,67,68,67,FB,11,EF,53,EA,26,F8,85,B3,20,65,D8,09,68,58,8E,F3,28,C9,8C,D9,3A,AC,4E,C2,46,7A,1B,AF,48,77,67,46,10,11,95,8C,16,80,31,47,70,55,05,3E,07,EF,C2,19,A9,1B,C3,5E,D5,C6,40,F1,F6,1A,97,38,2C,57,15,C5,96,52,FF,17,2B,92,CC,65,F3,6C,3A,5C,29,12,04,AB,8D,96,87,0E,71,FD,40,AE,AD,E6,63,46,66,14,09,8C,B8,69,56,82,C7,24,44,04,9F,3D,A1,9B,5B,83,D5,BF,C4,06,E7,C6,2C,CB,EA,3D,11,C1,88,37,AE,69,F0,5F,10,11,C4,E9,8A,DE,AD,BC,F8,6C,A0,4C,3D,72,51,26,6F,95,53,73,29,73,F6,B7,73,45,93,7E,3B,22,87,A1,F1,73,58,C0,B0,BB,2C,E4,6C,E9,F4,37,6E,40,43,C7,5C,16,6B,0F,95,A1,E0,FF,FA,82,E5,14,5D,E8,CF,2C,C8,FA,C5,4A,42,A6,A1,7C,C4,80,BA,DC,86,28,6A,A8,14,C8,1F,AC,79,65,B6,FC,9F,FE,94,7A,78,33,86,6B,08,27,45,FA,60,6C,37,25,7B,C5,9A,8A,47,35,11,D7,FC,21,E9,6E,89,CE,E3,AC,58,01,AF,93,89,18,AF,45,A7,1B,13,7E,4F,2C,90,9B,70,91,94,23,61,52,04,A6,A6,F9,29,AE,AC,27,DF,54,AB,F1,3F,7B,49,7F,0C,C0,52,CB,44,84,49,AE,23,2F,03,31,32,33,7C,3E,16,F6,BF,23,39,0D,6F,B0,B8,88,24,25,0A,F0,67,9A,05,E7,AC,B6,6F,6B,93,7A,50,8F,98,5F,24,44,BC,6F,35,C7,7D,C9,1B,48,CD,9D,69,5D,29,A5,20,E6,1C,DC,3C,2F,40,E6,1D,67,25,F0,0F,C6,67,20,3D,FB,46,08,6F,23,86,0A,AD,A2,99,7F,54,23,C1,8F,CB,96,E7,DD,14,31,2F,70,0B,FE,3A,FD,B2,5D,5F,97,62,F2,6C,6F,05,90,FA,2F,61,B4,F9,E1,23,99,78,70,4A,59,61,ED,A4,88,AB,65,61,5D,3E,A1,4B,67,11,1E,76,86,08,CB,29,34,A6,69,FA,85,36,19,A1,93,80,FD,CE,BF,47,36,29,D1,28,77,AD,B9,87,B5,11,1F,71,8C,89,EB,E1,ED,25,3D,6D,C1,92,1E,65,FF,FB,FC,BB,8B,D8,95,1A,53,FE,0C,35,D0,09,6F,C6,B6,B0,48,5A,1E,C4,89,5D,10,08,BA,FA,93,53,60,3D,17,42,5E,01,D7,28,AC,60,AC,B6,44,31,16,59,0F,26,08,6E,18,BE,71,06,0B,32,9D,F3,05,1F,42,B0,41,9A,D9,E4,B6,8C,86,75,21,F4,35,EF,72,56,03,B1,7E,41,24,2D,36,1B,E5,BF,FA,9E,BF,5C,E7,6B,1A,85,EA,E7,04,1C,B3,B7,11,37,47,0F,17,3A,FE,01,3D,D1,DE,92,C2,7B,C5,2B,0E,F2,00,81,15,07,6D,1A,67,8A,C1,71,26,E4,CF,7A,16,6F,66,8C,5B,24,56,BD,26,BD,AB,20,F8,09,F5,43,EB,89,5F,05,E2,49,6E,B7,53,C2,25,9A,C8,8C,27,1B,61,AF,19,7E,DA,5D,FB,57,20,C1,60,58,24,9E,D2,20,87,FB,4E,E9,B4,14,5A,44,DD,17,E3,9D,25,40,B3,37,12,A1,B2,D8,0F,BE,27,CE,24,E1,BE,81,95,9E,84,2A,8E,98,64,2B,77,52,F1,F1,B1,DE,54,3D,5F,B6,0A,10,54,29,E4,8E,4F,98,4B,DE,2A,FD,91,43,B3,A1,74,B3,12,3B,4F,1E,E0,6C,E5,0C,B9,D8,2D,3D,28,7D,CB,E3,8C,84,EA,E8,83,CC,A9,0A,0A,E4,99,45,F2,71,D5,2E,59,ED,7C,97,FA,FC,CD,DE,68,26,EE,EA,64,71,74,63,DD,93,FB,44,26,22,7D,B9,B7,95,27,06,DF,A8,8A,D0,28,D9,6C,75,C5,3D,35,63,2F,62,3A,0B,E2,C1,A9,DB,BC,65,D2,0A,01,DD,8D,75,DB,C8,2C,50,91,0C,46,94,7D,87,BE,C8,61,9F,5F,8D,20,2A,AC,F9,45,AC,ED,85,E3,17,4B,0B,16,8D,1A,75,71,43,C6,29,CD,07,CB,07,74,59,40,C0,80,B5,50,9A,6D,B4,CE,1D,9F,C9,D9,69,6E,AC,7B,F6,E3,49,AC,81,9D,4A,0B,8B,BF,18,92,1E,7C,2B,EA,80,A2,C7,C1,4C,C2,97,6F,2B,33,E4,24,E4,2F,EC,5C,A7,D8,DA,6B,85,1D,D2,F5,4B,6C,CC,0E,C2,3D,1F,A5,B6,DB,13,51,A6,C6,40,C8,39,CE,9F,4B,A3,6D,AC,38,A3,99,58,F8,B3,FD,2D,45,23,0E,38,25,B1,EC,08,D8,AA,8E,7D,F2,EC,0D,76,3E,E7,21,95,09,74,34,F2,DA,BA,C4,8E,06,96,76,1E,9A,7E,5E,6D,70,B9,34,72,D8,A9,8D,99,9B,8C,C5,30,E6,A7,D4,5F,05,91,81,FA,41,78,CE,8E,94,AD,3F,9A,C2,20,1D,67,3D,D3,6D,98,55,EA,CA,BE,F4,A5,5C,D1,0E,E5,F1,85,CE,3F,02,42,69,93,76,D3,C0,AB,B7,B5,14,9E,70,B5,1B,8A,AD,1E,FB,14,25,DE,F4,CB,11,0D,F8,C8,AF,8C,FD,C6,7E,88,70,8B,63,5D,16,A5,42,71,C8,93,2F,AC,01,9A,EB,ED,A7,DE,BA,64,60,EA,2A,CD,C7,85,62,80,15,91,F4,E9,DE,99,7F,59,50,C3,C2,69,00,76,A9,0B,16,B8,4B,26,12,3B,47,30,3F,B0,34,FA,11,36,F5,EE,3C,03,AB,32,17,D8,29,06,64,01,F2,00,2B,21,B6,6B,E8,90,43,00,A6,27,4A,0D,03,D4,CF,9E,9F,B5,BB,33,13,8D,9D,AC,56,8F,3C,DD,EA,21,8C,85,45,7F,F2,7F,83,36,41,38,BA,15,7C,33,2D,B9,B4,7C,26,BB,33,80,DE,C1,09,B7,53,75,64,5E,4B,F2,56,52,92,F7,3D,90,6F,F6,4B,15,93,35,49,6B,0F,6C,1D,26,F2,2A,42,62,5A,CA,07,6D,8B,49,D0,58,8E,85,BB,D1,58,89,22,0C,D8,D6,72,FF,66,CD,D0,87,EE,A5,48,93,BC,97,72,3B,5C,9E,57,25,C0,B2,CD,C8,86,79,2C,EC,AD,C7,DE,1B,A4,A7,9C,4E,04,ED,C1,60,3B,2E,21,86,9D,22,50,22,52,43,8B,1B,F0,3C,1C,0A,1B,F7,6A,EB,D9,F3,D0,54,86,02,8D,89,EC,9D,0A,F0,DD,25,38,07,22,31,AA,17,04,84,C3,17,AD,F8,EB,AE,86,0B,33,2F,8C,E9,D1,BC,68,85,BA,CA,99,35,70,3C,A0,6F,EE,88,CD,58,FD,73,1E,26,31,A3,31,65,78,BB,07,57,4E,CB,76,19,FC,16,5B,FA,58,3C,CC,F5,3C,B8,92,A3,60,06,19,0A,9A,19,A3,02,6F,9B,CD,4A,70,3E,EC,34,E1,EE,CA,37,6D,4B,B0,76,5C,E8,AF,00,B2,AB,8D,23,F2,70,F4,D6,58,86,CE,E8,14,61,0A,0E,EE,06,DC,9E,A4,F0,6E,CA,BB,49,DE,84,09,54,93,04,68,13,5C,73,5C,8F,80,86,A7,89,1E,4E,63,DB,DE,27,3F,E8,A4,B4,8D,D0,CF,93,E9,86,5F,70,91,41,A4,45,46,42,E6,99,13,B0,F4,3B,96,21,66,5E,F0,E8,2D,74,76,56,6F,8E,71,49,B2,80,00,66,89,62,24,10,7D,0F,73,8D,C8,43,33,79,83,AB,2A,00,C0,A9,E5,24,2B,E8,9A,EB,39,91,20,5F,95,51,F2,FE,19,72,27,19,DB,DA,62,A6,FC,BF,58,D7,E5,D0,CD,6A,CF,44,D7,11,E8,E0,07,E2,4C,B7,00,C5,81,00,80,03,6A,F1,AC,84,3D,94,CB,CD,BC,A9,A0,21,4A,75,4C,76,E2,4B,9F,FC,4A,E3,B1,66,52,BF,7F,C8,37,84,9D,44,D0,DC,39,A6,BB,B7,BC,6D,27,B4,4B,C3,47,A5,07,66,B6,F2,54,AD,BA,39,F7,10,FB,B6,AF,9A,F9,F7,F4,77,CB,12,E0,27,5B,E9,24,D1,AF,92,78,E2,65,32,19,19,4C,6B,70,FC,90,68,4C,44,F4,02,A0,5A,ED,8A,ED,4F,44,B2,C3,06,71,27,F7,76,AD,ED,65,50,7E,0B,33,55,26,88,CF,9A,58,24,AC,00,B3,12,D2,8F,B5,ED,60,23,9B,77,53,EC,9E,86,2A,E2,DF,35,A2,5A,E8,AA,DD,2F,AE,F4,64,88,77,9D,A6,AC,DA,80,55,D0,7D,27,41,91,8A,64,BF,D5,76,61,3C,38,7D,46,B1,EA,E9,5F,65,61,3C,1D,84,20,B5,C5,F3,E0,0D,94,97,E2,DA,29,09,06,27,30,97,87,56,46,42,43,54,6F,1C,07,E8,BE,E2,70,0B,5C,BF,56,33,39,9E,34,9D,EE,BE,0D,78,AF,24,98,6B,2E,0D,15,73,37,90,C4,5A,1E,B7,52,35,21,BF,5F,04,D3,2A,BB,41,36,00,9D,8A,00,AF,4E,9D,99,EC,7F,B0,DF,D0,67,1B,C9,1D,A1,F8,46,E1,01,FD,B8,6C,D9,93,00,67,89,13,25,F8,BB,F2,51,09,19,02,43,66,79,03,A5,59,E7,69,EE,96,23,9D,9D,3C,53,AB,1C,A4,EF,12,46,F7,7F,77,BB,6A,A3,E9,E3,F7,90,26,63,DC,51,01,92,C1,98,C6,B0,77,DC,62,02,D8,A0,AA,3E,B6,32,0A,1D,08,77,2E,77,45,2C,97,4B,85,B3,EA,2A,8E,F5,2E,62,0C,49,00,6A,7B,99,71,2D,7B,0C,83,96,4F,A2,9D,1F,09,A3,33,6D,46,8C,5C,2A,00,FA,C1,3D,35,31,E7,83,37,1F,5D,5C,CE,69,72,56,08,F7,30,B2,FA,F2,73,41,F7,3A,6D,DF,7B,DF,70,49,8F,77,67,AB,3B,7C,D4,3C,05,1C,36,29,E7,53,D0,02,FF,0F,A9,50,01,E9,EC,C8,BE,D1,CC,DB,FB,1D,5F,18,B9,01,61,DE,F9,92,00,C1,00,80,37,0B,69,B0,72,62,30,90,6A,17,1D,CE,37,3B,29,29,61,E4,AC,CE,DF,0F,41,E8,9C,65,67,DB,99,40,47,43,FC,B2,7A,B0,C7,84,85,DB,53,42,D9,13,2A,08,E6,97,E2,97,64,86,18,AF,A8,F4,FB,8A,9D,37,E9,20,62,0B,6C,24,A1,E5,ED,D0,AF,11,1A,A3,67,BE,D3,14,23,9E,B0,4B,80,FE,D6,00,B4,A3,35,B1,D7,20,31,02,3F,E8,44,59,50,16,14,9A,DB,07,2A,27,11,25,7F,54,82,6A,A3,BB,C0,94,2F,71,6A,95,07,D2,11,EB,C0,11,E2,2A,21,58,6E,12,84,81,4A,25,B9,DB,30,D7,C8,EA,10,6A,F9,E6,5E,D3,E4,07,8E,73,31,52,E7,C9,B1,CC,F7,4D,A3,64,BE,D6,0C,1B,F9,77,23,36,ED,8C,E4,29,70,2E,A7,FD,03,D8,0C,DB,B2,51,18,94,D5,07,5A,BE,E7,B2,DF,3C,74,99,50,84,B0,27,B3,91,7C,91,5D,73,B9,A8,30,45,8D,0B,89,D8,E7,22,22,A3,05,52,2B,F8,4D,2D,BC,48,DA,1E,4D,CD,B3,AA,5E,59,D8,0D,1E,71,74,FF,71,BA,85,AC,DD,40,7A,D8,02,FA,4F,7F,83,B1,FF,82,3D,86,22,A9,15,FA,94,B5,A0,76,4D,CE,5A,2C,5D,C7,FC,8E,24,4D,D6,49,21,CE,45,A2,F3,39,89,69,0F,CF,DC,B7,F3,FE,D1,29,B7,DB,B5,21,33,C2,4A,26,BF,61,44,18,88,DB,2F,F9,E6,E4,6A,F5,18,6A,0F,63,94,5F,38,FC,E7,E2,F4,11,34,C0,3F,96,C7,0E,B1,E5,C6,CD,B5,9F,5C,4F,4D,EB,9D,B4,7C,34,D1,DB,8F,7C,0E,30,45,C4,97,58,74,E8,E5,DE,29,58,C8,02,BB,24,D5,6E,57,77,9A,2E,5F,44,7F,31,DB,F5,9E,25,2D,04,3C,A0,A2,E3,57,3B,7A,D1,D4,41,A8,54,8D,C1,39,C1,63,AC,1F,56,08,BE,E5,8B,C7,32,A6,B1,4F,92,46,A6,DA,E3,0A,86,7B,8A,03,63,B6,B8,DB,1D,5F,99,4E,24,87,49,9A,ED,6A,40,FB,A4,32,48,A1,4C,4D,4B,41,E2,BF,66,08,B8,F9,89,41,AA,AB,B5,41,31,BD,D2,39,57,50,89,3C,43,54,1F,9A,34,F8,B9,21,E1,20,D1,F8,A7,1D,DA,DF,AE,18,D5,16,34,EE,74,3D,7F,8D,13,AF,DF,BA,EA,E9,C2,CA,62,03,F1,34,B2,0E,A3,7A,C1,2D,32,31,01,AC,E8,6E,6B,5A,DD,13,99,A9,1E,50,0A,40,A7,EB,A8,27,53,15,6D,54,74,A8,3C,C2,5A,D2,4D,AC,79,37,18,7D,48,5E,61,BF,3F,CC,E6,22,5A,5C,02,FB,E6,03,2B,33,0E,1E,F6,CB,69,77,9C,50,D2,F1,10,FB,96,6A,89,E1,1B,DE,D4,1C,51,94,31,86,63,6B,E6,B8,5D,FF,79,6F,90,AB,13,4C,59,3A,74,D3,1D,2A,D4,9B,D7,2C,66,B8,4B,83,33,B8,96,2F,1D,DA,15,76,0D,39,4D,EB,D9,6E,EF,48,B4,B0,0B,5E,E1,68,8F,FC,A7,C8,82,B2,93,B0,8C,16,E5,24,B8,9A,64,09,79,14,57,29,71,5D,04,03,BE,E5,23,D0,2B,E0,41,9F,3B,6A,7A,30,BE,B4,4C,66,29,58,90,55,60,53,DE,06,FD,94,55,6E,76,24,9A,EE,9D,EC,FC,72,4F,16,72,DE,94,50,59,7B,1B,D2,F4,6D,3E,D8,ED,5B,8C,C5,0A,39,7B,2E,EF,4D,46,B6,09,94,25,FB,32,E9,90,8F,30,5E,76,A8,90,8E,6E,77,32,A9,D1,60,A2,E5,33,7E,59,74,55,F1,DD,5F,A4,81,78,95,46,EE,3C,5E,B4,4B,66,6F,29,25,88,6A,5F,C7,7C,AE,B0,58,7D,26,06,E6,D0,23,EA,E8,3B,45,19,5E,2E,40,87,9D,20,9C,AA,4E,C7,19,9F,85,88,9B,CA,51,8E,F9,09,84,18,DE,C7,93,42,BF,02,C1,A9,7D,33,B6,D3,60,46,84,5E,B6,62,5E,6F,DB,50,D1,85,91,83,C9,5C,CF,9E,11,40,DD,22,61,84,A2,56,E6,D5,1C,DA,89,F1,CE,DC,E3,25,80,47,EA,FD,C3,F5,81,48,E3,52,E7,95,47,9C,11,35,C9,50,EF,28,4F,4F,F0,47,FC,A6,F2,EB,91,4C,6C,5E,92,AB,19,65,59,5A,72,85,30,C1,44,D7,01,0A,C4,D5,1A,77,6F,24,14,E1,43,F2,32,07,A6,E2,34,7C,E6,2F,F2,C2,6E,B9,E2,49,82,7F,78,92,BA,9F,51,DF,5C,55,60,E7,C0,06,9F,10,CF,3D,9F,E1,91,4D,1A,90,89,9C,93,CE,10,9D,55,A4,19,CD,45,E7,C4,11,CB,40,7D,0A,A0,A5,CD,0E,C4,3C,F2,76,D2,54,DE,28,43,8A,F2,A9,B3,1E,1E,3C,78,7E,20,94,25,4C,7D,D3,70,07,41,AC,7D,9C,E8,FB,40,F8,E0,4B,14,EB,92,D6,8B,FA,86,7C,80,94,31,B3,1B,59,4F,35,B1,BE,13,7B,6F,33,77,49,CA,E4,3C,AD,73,1B,D4,C6,86,41,37,25,DD,11,ED,61,60,09,64,A9,AE,6D,A7,99,EF,8E,C3,1A,2C,DF,BF,7D,5D,6A,D5,D5,2E,4A,04,F1,2E,13,51,C7,EC,B1,FC,4D,7E,FC,B4,C8,B9,B8,E0,2C,F2,8E,5F,C6,A7,6E,55,4C,1E,51,B3,9A,6F,EB,92,77,68,57,E2,E4,BE,DE,2F,58,91,B0,CE,1C,A9,0E,1A,E0,38,4B,FE,8B,0D,65,B6,B2,34,4E,58,02,A1,FB,3A,63,73,E3,28,DC,74,BA,75,A5,83,91,97,20,94,DB,44,A0,8F,9B,2A,E0,63,21,37,83,C7,33,7C,9A,56,69,5E,4B,13,8D,C5,C3,5E,E4,DE,C9,5F,85,47,3E,6B,49,13,64,F2,90,FD,33,A3,20,BE,9E,EA,71,7C,D7,E5,15,1A,95,F6,5C,77,F4,5B,F5,EF,43,46,D4,5B,26,23,26,CF,52,A7,19,E6,A4,FE,13,8C,0C,E2,D6,A1,C2,7A,04,27,47,63,86,63,26,69,37,4F,A0,18,30,E5,14,F4,71,A0,40,1C,66,6F,33,1F,8B,0F,CC,B9,77,9C,ED,53,41,B1,BC,65,E9,11,13,A3,95,29,3C,AE,5A,AC,C4,72,28,C9,91,53,54,7B,D5,07,44,F0,D8,65,14,F8,59,97,FC,CF,3A,54,F1,81,DE,26,B4,2C,54,72,A9,FE,DC,41,24,1D,2C,72,77,EC,EC,85,F6,2C,C5,EB,B5,98,3A,8C,17,5E,3A,3B,EF,59,AB,F8,F0,0E,CC,B7,EC,20,4C,2B,59,59,91,85,5A,A0,A3,C4,E4,7F,30,FC,07,CD,CC,CB,10,CE,46,A9,69,08,BD,2D,7A,FA,AD,7C,5D,1F,D1,39,A3,DD,E1,BA,02,09,5B,9E,26,3B,68,91,6D,F1,66,45,E8,F2,24,29,E4,6F,DD,8C,86,6A,D1,0C,02,33,05,33,34,1F,CC,EF,41,7D,74,AE,F2,55,F5,C7,C4,BE,8B,33,E7,AE,D7,17,7E,62,DB,D7,E0,9E,68,3B,E9,78,1F,34,BA,3C,F9,A2,1F,63,34,43,01,EE,2A,2C,C3,D4,AB,05,A5,3F,AA,2E,32,70,6B,3B,F6,A6,6A,71,E6,40,95,0D,14,2A,F3,4C,70,EA,78,A8,43,8B,EC,E8,D5,9B,99,2E,EE,30,51,B4,6B,6E,0A,F6,A2,24,D4,C6,FC,41,02,28,15,B0,00,5D,35,8B,8C,E6,9E,77,2B,F9,54,36,0D,94,74,D9,68,BD,30,24,91,45,71,CA,19,11,0F,68,F1,99,9A,22,D1,34,78,B7,CA,2D,2B,B5,80,87,EA,C8,1E,C6,0D,E9,CD,78,B2,C3,D3,36,C2,DC,D5,2B,D9,E5,FF,7F,CD,B7,B2,C7,C9,6E,9A,1C,E4,95,19,94,07,A9,D0,D6,39,C4,9B,3F,7E,F1,5E,AE,4A,55,6A,0D,E7,2C,A2,4C,E9,B7,C0,DB,E7,D1,BA,94,A4,D7,E5,A3,54,DE,4B,6E,3E,67,20,4A,C0,37,79,13,D5,5A,4C,D1,20,D8,68,53,60,BA,37,9F,12,C3,21,31,94,83,73,EF,EA,46,B7,03,11,48,3C,81,CE,AB,BA,38,17,D1,2F,31,EF,7B,25,0B,A9,58,9B,0D,1D,82,86,13,DB,7E,B0,27,7B,BA,B0,FB,39,B9,6E,45,DE,16,EA,F5,F2,4E,C6,2F,74,23,BE,DA,5A,63,88,4A,B5,B9,2C,10,4D,12,CA,58,AC,B6,C7,74,2D,7A,87,38,AD,89,F0,5C,2E,3A,A7,65,17,04,2F,8B,4B,90,44,AA,29,FB,5B,FE,2F,37,CF,29,82,C3,85,9E,8B,6D,D2,8B,03,56,48,3B,8A,3E,0F,73,15,B3,E8,E4,81,EF,20,0A,AC,83,54,8B,17,75,C1,BE,AC,8D,E2,6C,2A,A5,11,9C,FC,91,66,38,01,6E,67,5E,7D,CB,F5,C6,1D,1B,0A,5C,F2,7E,84,68,84,F7,77,63,9B,81,5A,F7,FB,BC,C5,79,4C,D4,0B,8F,B1,24,23,45,D9,0E,B4,37,17,92,02,89,71,8F,D2,C9,3C,CD,2B,E6,56,56,A4,76,94,E0,6A,2B,B0,B3,2A,4A,06,65,82,DA,4B,82,3E,6C,06,A2,42,1A,58,2A,49,6B,56,EA,C9,E8,D1,84,46,19,9D,2A,CA,EE,14,45,62,C3,07,0E,D4,EB,DF,E0,12,27,1E,C4,15,D0,A6,F2,B2,BA,88,52,5F,6F,9C,92,0A,DE,3E,FD,F8,FB,28,9B,E7,37,A0,27,95,C6,0E,F4,D2,CE,54,B2,44,52,7D,1E,7B,77,E2,2D,0E,0A,01,26,C5,D5,F3,C1,60,2A,BB,66,8F,E7,F8,92,1F,90,74,2D,7D,21,14,20,7D,CF,9F,32,C3,27,45,94,BE,D0,34,3B,B0,F5,90,EC,36,98,06,06,29,0E,98,E3,D9,29,CC,F1,DB,36,46,58,AB,05,CC,AC,1A,FA,DF,95,40,1C,02,F3,EB,EA,56,54,3F,21,B3,25,09,4C,3C,DA,39,81,9E,8D,95,CC,E8,54,9F,DA,15,C7,35,90,1A,96,A0,FF,AC,3E,96,37,35,0B,EE,24,23,DB,D5,97,BC,D0,1C,DA,9B,39,D3,9E,C4,31,CE,C0,64,E8,ED,06,9A,52,F2,B8,FD,93,91,53,49,0D,17,0F,78,AB,E7,C2,34,8E,4D,62,CB,FD,A5,B3,8D,64,25,59,5E,14,B1,38,49,C1,E5,F8,52,72,0A,A9,6A,8A,3F,03,A5,49,47,C8,19,2B,62,8A,0C,1B,5D,A6,07,34,ED,61,8A,B1,93,56,CF,76,28,71,4F,05,1B,10,99,D9,9E,37,38,DB,EC,83,07,C8,0B,A7,D3,89,AC,1D,93,5F,0D,2E,FF,7C,13,03,32,54,4F,D0,0C,9F,28,7A,63,5A,48,C8,EA,ED,D7,B3,FA,E6,62,78,F7,91,67,B9,4F,4A,3A,F1,ED,79,87,34,7B,FC,3A,D1,70,F9,CE,83,BF,C1,AE,85,81,FC,86,E4,1B,D3,21,08,AF,B3,37,D1,79,D7,33,4B,56,3C,E8,DC,70,C9,3D,E5,72,BC,41,BA,2C,BE,C9,D2,65,24,22,74,52,45,F9,FF,0F,25,B7,12,9C,26,7C,E7,C8,52,02,AD,2D,63,7A,47,E3,37,05,4F,35,95,73,0D,6B,A4,B7,40,B4,B5,67,BE,75,CE,65,6A,99,A1,D0,9A,FA,81,AD,6B,41,95,E9,01,40,82,1D,03,3C,D0,46,DD,1D,E3,F5,71,2C,D1,91,EC,78,C0,FE,FD,46,B2,BE,C9,0E,69,9C,C4,65,08,C8,6A,BE,F6,F0,89,F7,AA,C4,12,BD,17,17,C1,F7,E6,D1,C9,AD,E2,38,04,B5,25,FE,E7,21,B3,78,16,21,4A,A4,48,31,BC,7D,F3,21,A6,22,A5,99,47,EE,2A,84,CA,CA,55,00,37,24,45,31,6A,54,81,66,A1,5B,B3,44,68,0C,E2,D1,61,89,A3,E0,9E,8E,CB,65,0D,9D,AF,6D,8D,29,0C,14,9F,E7,43,AA,AE,8B,C3,32,F2,C9,16,82,03,10,CE,43,C9,00,59,26,54,30,64,97,D1,61,17,37,A7,6A,14,37,8D,01,DE,C9,79,A9,33,4D,A2,98,C5,F7,E8,E3,B5,6F,B0,52,CD,A5,B5,8A,7F,E0,12,D6,7F,14,EE,8C,94,43,A9,80,29,70,C2,FB,0E,BB,9A,0F,7C,CE,14,B1,60,21,CE,E8,0A,91,0C,94,41,90,F9,8E,0B,CE,8C,73,FA,85,60,A9,FA,0E,8D,C5,AE,D7,D2,93,67,19,41,7B,27,61,64,A9,D3,FB,BE,F6,02,40,69,01,BD,E2,E5,9B,5D,47,F0,9A,B0,04,40,0A,27,6B,E5,8D,AA,D5,81,CE,D6,ED,95,16,91,00,A4,06,72,9B,EE,3C,0B,39,30,4F,DD,C8,81,0E,8C,A3,59,F5,62,BA,14,F9,37,6D,41,BE,F1,00,AB,12,F8,F4,51,E3,EB,A8,3D,0C,03,9C,A8,94,7C,7A,E7,57,0E,73,3B,4E,10,37,28,CF,37,E5,E3,2E,5E,90,FF,FF,4A,C2,90,19,C9,85,93,0F,51,2A,AB,36,43,2C,CD,93,6C,D9,DC,E7,1D,31,6F,A9,51,2F,6B,FA,3B,BF,81,9A,7C,56,8F,8E,2F,31,9F,ED,AE,C6,FC,00,43,3B,FC,73,F8,D4,29,11,92,E8,E3,0A,68,DA,E1,70,FB,50,30,A5,9E,9D,29,A9,DD,52,AD,76,63,B5,11,30,0A,15,B8,94,32,EF,D3,F5,4E,4E,5C,98,79,22,8F,20,70,AD,76,AC,5A,74,E5,FE,BB,16,0B,C2,8A,3D,AD,C6,22,A7,29,06,71,19,D9,6B,34,49,74,86,9B,1C,24,2A,FE,02,0E,B0,2D,98,40,BE,00,44,78,85,FF,0D,76,38,C2,63,D0,1D,D3,65,AF,5C,30,E0,23,9B,E8,EB,B9,A1,96,24,73,9D,B0,A4,C7,22,E3,BE,C4,AC,11,06,CE,BD,72,71,C0,AF,84,17,9D,BB,30,32,32,9D,BC,82,7D,8B,F5,EB,A0,F1,E3,60,90,F7,A4,17,83,19,AC,53,96,86,BC,45,CC,E5,96,D9,64,D5,AD,8D,62,0D,94,07,E2,21,E2,78,88,13,E3,AB,C5,E9,BC,8B,21,4D,33,2A,BE,47,66,13,D7,66,44,FC,6E,49,40,10,CB,6B,47,2E,69,3F,66,18,21,0F,6C,FF,A0,22,00,EA,87,35,10,42,4C,F0,58,F3,63,CC,C6,D2,A9,6B,52,97,15,E6,FE,09,A9,86,4B,6C,DB,9D,C8,96,98,2F,B5,32,DE,57,DC,AB,73,4F,E4,09,6D,A0,F7,68,43,98,FC,DE,9D,11,85,E5,50,D2,1B,9B,C6,A0,75,BE,FF,29,9D,D1,A8,96,E9,94,7C,92,70,9A,8F,C8,A5,73,9A,70,81,35,C0,23,B4,7F,CA,A1,3E,62,00,2C,FA,72,2F,C8,4C,44,54,18,9F,C0,9F,37,46,24,79,AC,0C,54,F2,D3,35,24,22,31,8D,72,9F,72,F9,CA,2F,10,25,C7,98,8C,81,5A,EE,21,5F,8B,D1,36,D0,5E,69,2E,38,4F,D3,6B,03,BC,96,B3,B1,AB,52,5E,90,9D,DB,D4,45,08,B7,DE,39,E0,29,F9,86,6B,DC,9A,7F,8F,FE,05,48,59,32,6B,FC,51,C0,85,D7,A0,F1,0E,49,F0,4D,16,7A,4A,D4,C1,DC,7A,7E,A9,45,1C,59,E5,21,0A,C8,5B,A3,A9,7E,3C,16,8A,80,C4,D6,24,F2,B1,3E,DC,25,55,3A,32,52,FA,D5,8F,2C,FA,ED,21,30,04,6A,04,D1,91,12,FC,09,9D,68,F6,A6,F0,53,51,BB,36,6A,1E,30,C1,83,6D,81,76,AF,39,41,44,2D,D4,43,EC,37,40,85,4C,F5,1C,DE,16,21,CF,53,88,EB,70,18,A0,C6,4A,AD,DD,6C,48,1E,C2,77,7E,1A,B1,EC,F1,0B,F8,C8,95,03,1E,00,0B,D6,75,07,4C,43,BA,44,2A,09,27,29,F9,BF,49,4F,8D,55,59,5F,6C,B2,01,95,E4,B5,17,E0,C3,E7,78,08,46,86,0B,77,85,EB,7B,A2,69,0B,4C,68,30,16,D2,E8,28,52,35,73,ED,F8,53,8D,DD,3C,AB,39,62,8F,27,13,DE,98,A4,27,75,78,50,E6,FA,EF,14,6E,24,03,C9,CD,83,34,EF,02,2E,01,39,D1,20,D3,45,40,37,B0,5E,B2,F1,CD,46,2A,38,38,4C,33,5B,41,28,88,56,94,6E,1F,41,D3,EA,22,86,E0,A2,CB,51,A7,51,AC,2C,70,30,18,F2,6B,C7,30,91,2B,2E,6C,2E,EB,BB,8D,1B,2F,CB,CF,93,24,8E,99,70,C7,2C,14,DB,81,EA,2E,8D,4A,38,5E,56,12,D9,A7,04,13,E0,1F,61,96,2E,51,91,01,8B,53,F1,94,21,B9,33,5D,56,99,05,75,2C,B6,E3,E7,F5,67,E8,26,D0,B2,5D,2E,65,72,FD,BB,BA,D2,1B,98,82,E2,1F,DB,8B,EA,D0,A8,2E,36,6F,5D,8B,9D,3D,09,52,3F,55,24,FA,3D,47,40,E8,A5,30,BE,E7,92,48,DE,6A,3A,B8,CF,E2,9A,9E,3D,B4,DC,44,65,4A,17,26,B5,0A,94,0C,B1,B5,81,40,7E,52,C9,F6,9A,B7,60,72,51,34,A3,20,93,E9,AC,29,11,7E,02,DB,2E,58,C7,B2,8F,61,EE,FB,FB,4E,89,F4,2A,2D,0F,2E,DF,7A,8A,2D,DE,3C,2F,3B,90,F4,B0,6A,17,17,2A,CD,62,53,F5,3E,69,05,F5,3F,46,E5,BC,19,F0,81,BD,8F,8E,6F,6B,F6,DA,B7,5B,05,99,C0,60,57,25,D8,D8,5C,BD,5C,48,54,58,20,A3,7A,65,E9,0D,F0,6F,40,FC,E9,C6,48,FD,B1,F2,E3,20,AB,C6,9A,CE,4F,A9,FC,99,24,C1,E4,D6,D0,4C,5F,0D,B3,CA,89,EC,6D,5C,DB,D0,34,E3,E5,B6,46,1E,6C,95,AF,10,30,94,96,23,86,5F,24,3B,6D,E3,7B,51,3F,67,75,0D,AB,BB,B5,F2,0D,A2,03,BD,18,45,57,35,6D,1E,4C,FF,06,66,F4,C5,2D,CC,8B,83,78,6E,85,4D,3A,8E,39,9B,21,AF,5C,D1,43,BD,9C,7F,9F,2F,F8,93,25,4C,F9,EA,A2,EF,10,15,16,CC,96,69,FA,01,16,15,E1,58,51,0E,33,09,2C,6C,6F,AF,BB,E9,9F,E9,30,55,8B,89,5F,0E,7B,E9,71,CF,E9,FB,74,BD,1C,6B,70,D9,DA,FB,29,3D,58,1B,08,97,33,6B,F2,75,18,F9,F3,51,F6,C3,FF,8F,9F,FE,85,F2,A7,A7,EC,62,5A,52,CD,E1,5E,BA,58,4C,4D,B5,D8,16,E6,0C,B9,0E,2D,6C,56,EE,09,87,BF,3D,EA,40,8C,D9,84,C3,A3,67,2A,40,72,54,C2,7C,82,A8,E1,C3,2D,98,8B,E9,C0,CF,59,2C,0B,D1,9E,87,49,06,4B,0C,B6,E7,88,3C,49,19,73,C1,E9,22,7E,6D,0B,50,66,06,9E,4E,17,C6,17,C2,99,19,A6,9A,50,63,CA,F6,23,53,F2,6D,9D,C6,35,AB,74,E0,64,83,14,90,53,E3,CD,E7,CC,C6,80,07,70,B8,F1,43,B3,A5,CB,50,3C,03,BF,D4,5D,8A,F1,10,40,74,3A,E5,53,DA,8A,B8,D4,9B,DD,28,E8,6B,2D,6D,1B,13,F0,89,2A,DE,8B,34,D8,3D,C9,7E,D1,1B,96,56,C1,5B,40,04,B8,10,88,76,03,3C,65,0A,18,97,8F,A6,85,D7,58,DF,DC,F4,23,10,F3,79,CC,1D,9F,D5,01,11,A2,2D,82,B8,53,A2,D0,2C,19,40,80,A7,34,4D,17,B5,9B,B3,5B,6E,7B,6D,B4,3E,36,27,24,EA,F6,15,E3,0B,A3,75,6D,6C,29,60,20,9E,8A,A2,C6,D5,A2,8C,10,04,CD,6E,78,13,EC,96,EB,73,D0,F3,46,CA,B7,C6,8F,10,0C,F7,61,F0,9B,36,93,90,40,C0,A6,CE,61,30,69,CD,C4,74,67,25,4F,BB,ED,63,24,41,9C,7A,24,7C,01,33,B8,A8,47,D1,24,A2,07,7D,42,E6,7F,5B,CD,7C,01,9A,15,76,02,CD,2E,58,51,D8,60,F7,85,D9,88,11,B4,97,66,56,58,E7,1D,C8,FB,9F,06,E6,06,A1,89,62,BF,3F,DA,A2,60,A7,E7,C9,1F,73,49,BE,22,FA,49,81,34,96,07,C8,75,90,0B,B7,5A,2E,4D,9F,50,86,24,F7,EC,16,4A,E3,21,39,F7,1F,92,EB,B7,6B,5E,CC,C9,26,B9,12,E6,9E,FA,88,86,FF,AA,6F,82,93,42,F8,D8,7E,F0,20,2C,E5,2A,76,0B,9C,1F,AD,BB,81,FF,03,2C,2A,52,58,1A,7B,DA,AD,3C,29,32,8B,9C,C2,66,1B,63,1B,7B,21,B5,9F,B7,B9,4F,6F,47,C7,70,3C,12,47,F9,EB,4B,35,EB,B3,16,07,AF,63,94,B1,7B,F5,06,08,F3,BE,8D,3F,AC,7A,E8,81,EE,AC,4D,4C,FB,FA,37,C1,AB,AC,08,4C,1D,9E,F6,DA,5A,3E,62,65,43,0E,BE,19,CB,53,33,B2,02,98,17,00,32,12,76,39,D5,99,02,ED,A7,75,FE,5B,51,8B,D4,07,57,FE,CB,F0,DE,A0,16,0C,15,C5,B1,D9,7D,E6,D3,02,7B,7B,F6,B6,C7,1C,16,53,B1,E2,A8,B7,A3,38,D2,AD,3D,EA,48,96,31,51,90,44,D6,BD,5A,67,6A,9B,76,CF,E4,40,8F,CE,B6,68,88,06,D4,CB,69,BD,8A,0E,BA,52,85,78,ED,4D,A6,F2,5A,50,53,C4,71,4A,6B,5A,16,9C,D6,41,F6,17,AE,16,FF,25,AB,04,1A,FD,6D,AF,2A,55,23,0D,F4,F2,16,C0,F4,D4,41,86,75,06,01,8C,26,4B,5B,3D,72,87,10,E0,BA,13,89,9A,86,2D,FC,9D,A3,0A,44,9E,B4,34,EF,FB,E0,10,6F,08,EA,1F,77,99,68,8B,73,A7,08,42,61,42,48,46,45,C3,D2,C5,2E,72,69,44,B5,23,A5,50,4A,71,A7,1C,8D,A2,93,EF,13,4D,B1,C2,66,2C,47,57,31,DD,F8,31,3D,26,0F,E5,63,99,A5,D1,9F,00,53,B2,3E,A6,4A,C0,7C,78,81,90,ED,A8,8F,AC,A4,13,CE,53,F5,4A,46,60,A3,C6,0F,57,6E,98,A4,23,14,67,D8,C3,1D,FC,18,38,95,C8,EF,27,3D,35,E3,44,FC,79,67,36,8A,5F,B0,9B,13,A2,D2,AE,38,A2,4E,86,5E,B6,5D,2D,0F,D9,3B,B2,0A,A8,9A,4B,E9,46,79,C3,96,8B,12,87,AD,32,94,EF,31,7D,68,FB,2F,F0,8C,54,F0,64,62,FC,C6,1B,3F,53,47,4C,1D,C9,61,55,C7,97,FB,F1,04,1E,F7,70,01,E3,D7,50,CB,F2,05,03,1F,0B,2C,4E,B5,B4,14,D4,31,65,F3,BB,24,28,EF,A6,2A,80,02,36,57,0A,7F,84,53,7F,1E,1B,B8,04,5B,01,B0,82,D1,9B,25,48,6E,BB,18,C7,65,94,B5,19,30,D6,BB,26,A5,44,C9,4D,24,55,16,38,D5,16,1D,32,AB,AC,94,85,21,7D,CE,34,11,63,9B,6F,D6,56,BC,97,2B,1C,BF,BB,B2,B9,C5,C7,89,11,F7,C9,A6,39,D9,BA,CD,05,49,31,36,93,A2,44,31,CC,3B,49,90,5D,17,1F,42,81,4A,6F,6C,39,C0,5D,CE,CC,4C,A6,47,70,09,F1,80,B9,DC,90,26,60,DC,7E,F9,CD,F0,85,8D,76,AA,4E,E6,07,43,9C,E2,A0,6A,62,D7,BD,1E,73,46,0D,64,89,E1,E4,E0,D8,B4,BF,85,C5,80,7C,B5,8C,0C,2E,25,00,D0,D9,6A,1B,15,9A,C1,C7,3F,26,E6,D8,AD,82,0B,89,61,CB,42,7E,06,94,88,70,DE,49,2C,6B,87,93,E0,CE,EF,7B,8D,7E,C9,DC,9D,52,B5,DA,34,B2,B0,D5,E6,03,C2,08,1C,CC,BD,1D,50,92,AD,A9,52,79,8A,56,23,C3,26,C7,44,8A,74,D9,C8,16,09,B5,CE,A4,FA,3A,CB,29,D1,D8,38,F1,CC,60,03,35,16,2C,C6,7B,8A,90,06,DB,25,F1,D3,1E,F7,0B,77,71,8E,A1,06,48,92,8E,14,96,CD,17,61,CD,8D,6E,2E,7C,81,42,95,2B,75,26,C3,24,B0,3F,31,42,22,E4,D0,54,7B,0A,BA,3B,50,EB,6E,8C,EC,90,F4,8A,46,02,6C,AB,16,03,E2,57,FD,48,12,51,D3,A8,C6,1A,F1,45,09,65,6E,90,1A,AE,D9,E4,F6,82,22,99,45,C5,D5,F7,89,BA,3E,E5,CC,C9,63,B1,94,0D,C1,BD,AA,B9,92,F1,17,D4,A8,DF,D4,50,C7,57,53,16,23,BE,B9,74,59,BA,99,A3,11,B2,EF,66,B7,B8,3E,85,3A,B9,0E,E1,C9,42,63,36,5A,43,45,2B,AF,F9,E8,44,76,74,D9,EE,20,25,61,C4,BA,BE,95,75,F9,6C,80,B1,5E,20,76,2B,0E,D8,3A,3E,21,35,74,51,F2,19,55,5C,83,C6,14,0A,59,E1,C2,37,8E,D3,26,01,9C,D0,DE,95,BA,65,5C,D9,B7,0D,45,E8,38,CC,B9,3D,B8,0B,C3,F0,B1,3E,7C,35,30,12,39,87,58,7D,CA,2A,80,CA,A6,1B,3F,3A,A0,E2,22,D8,14,7F,52,66,92,F1,61,E9,53,68,1B,5F,0E,2D,3D,D1,BE,A8,93,40,AF,5C,55,80,F4,3D,95,FE,75,DE,95,CD,42,B9,8E,52,BC,08,45,93,5B,0A,68,B6,1B,B9,1A,66,37,11,C5,6A,A7,5B,B4,AE,D2,08,80,75,99,20,73,5F,E6,DE,4A,4F,C2,8E,A2,4C,F9,FA,A1,D8,66,57,5A,C7,A2,42,C8,B7,DE,0F,43,2C,8E,63,B0,1E,30,6C,38,25,4D,4D,C2,34,9F,B4,61,8D,FD,94,85,A7,C1,A5,F5,EA,02,C6,D5,0E,D8,D5,62,52,7D,F7,EA,50,28,2E,BB,C6,B0,A6,6F,BC,A9,C2,2D,EF,0B,37,3B,6C,8F,B1,E5,49,48,8C,04,12,99,69,2C,D6,A2,98,D1,0C,24,9E,8E,AD,2C,EF,79,8A,09,11,31,27,83,F9,F3,A1,81,E3,46,08,3E,70,87,EE,70,9B,33,20,50,17,18,F8,32,3C,29,51,A2,D1,03,FC,D0,AF,2D,59,3E,BB,EB,03,E2,DC,9D,9D,8E,9B,B7,A5,E5,DE,56,0F,EE,70,53,A9,F3,64,89,69,E8,E5,2E,8E,F8,F0,D5,B1,67,7C,BE,70,56,49,F1,FD,0A,DE,26,4E,D5,4B,9B,02,61,BD,97,E6,17,93,52,64,55,31,FC,6E,7A,DD,CA,59,16,3C,9D,C5,0F,89,0F,ED,31,68,42,80,9C,DB,0D,12,C0,90,4F,BD,D6,23,1F,E2,D7,B8,57,A4,CD,0C,E0,42,2A,23,8E,74,90,AB,4A,80,1F,04,9C,D4,E8,84,32,BC,FE,4F,44,81,6F,C9,02,46,C2,E6,D4,D9,41,07,89,17,C4,0A,97,8E,CF,2C,DF,4D,B7,24,27,10,04,91,B8,44,07,AB,03,CD,A8,86,E6,BB,D9,F5,AC,3F,7E,78,FC,5C,BC,FE,3B,FE,7D,09,40,A9,8E,16,0F,16,B7,18,24,00,6D,BF,B8,DC,F3,CE,D4,0C,09,3E,73,03,92,58,3E,B7,15,7D,5C,B1,CE,6C,DE,EB,A5,30,35,2D,B4,77,16,68,47,88,B1,65,E0,8C,32,59,0D,A2,88,5F,F0,46,D8,9C,2F,5F,0D,55,15,44,AF,95,B9,68,77,45,4E,F9,B0,23,13,03,2F,CE,01,1C,09,2B,16,22,4A,0A,3F,B4,FC,AB,A7,1C,84,70,7D,C7,72,53,37,3E,B3,6B,D1,24,F6,19,48,6B,71,50,DB,30,66,E1,21,A9,D8,FF,7F,55,01,8D,2C,02,A4,02,0A,CC,2D,32,88,8C,40,5F,94,64,B7,7F,9B,E3,CB,55,51,E7,D0,A2,6D,4F,0C,44,5B,CB,FD,D3,4D,CC,41,B0,2C,5B,A2,BC,07,76,A0,70,B5,13,EC,25,F2,1F,30,59,92,5E,B3,22,94,FD,6C,04,29,E6,CD,11,33,92,2E,95,72,9C,34,21,19,3A,97,B9,05,C8,E1,F1,54,2C,5F,0A,7C,CD,ED,6F,A6,73,3C,7A,3F,66,1B,92,A5,30,EC,40,27,70,86,63,86,42,66,64,49,BC,35,D4,12,B8,B1,A2,4B,B0,31,EC,28,F4,D3,DB,41,7F,3F,6B,62,6E,4F,60,D8,31,17,3A,2D,33,74,BC,FC,FB,C8,7D,35,99,82,14,C7,E9,0D,4F,E3,E7,00,68,13,9B,41,69,38,44,2E,47,68,8D,F7,09,DC,0F,9F,71,8C,77,04,15,2E,C0,48,69,30,F0,AC,91,00,3B,BC,70,F2,BF,57,F7,73,D9,4E,A5,51,EF,F8,8C,9E,20,AC,C3,FC,5B,10,34,B2,F8,84,A9,97,4C,FA,47,A9,41,A6,59,88,B2,9E,71,1F,74,54,E4,72,DB,05,67,1C,AA,41,FB,DB,12,70,45,7C,77,88,43,B1,6F,31,F1,46,99,8D,C1,D7,C2,95,3E,FB,27,74,8F,3A,38,4B,63,0F,40,6E,37,8C,83,BA,11,AD,0D,DE,50,8C,55,3D,D7,ED,C5,35,02,EE,D7,54,98,79,4F,0A,58,08,79,C7,99,7A,2E,8C,96,FF,54,B7,60,66,7F,65,87,74,F8,61,2A,5F,C4,73,F6,6F,24,25,F9,C1,A3,75,70,2C,3B,AC,1A,ED,10,78,85,D3,03,3E,CE,C1,DF,6B,AF,78,D0,14,2B,1D,B7,95,EA,6E,77,AA,4D,5A,58,BD,5C,BF,F4,BB,28,F9,81,8E,5F,0E,C6,49,EF,9C,7B,BE,4C,6F,7B,EE,2A,23,61,9E,34,5D,B6,FD,59,E6,AD,3D,CC,FA,4A,E8,A9,7D,CD,38,F8,8B,56,3B,50,0B,85,E7,F7,77,1F,AC,DA,14,AB,ED,D3,9E,74,A6,AF,74,E5,68,B0,25,1C,CF,4F,4D,65,F7,CE,A5,82,72,FC,25,BB,18,D7,1A,2E,6A,BD,48,42,13,6F,DE,B5,9D,16,0F,84,CF,23,E8,3B,E6,3E,2A,91,A2,A2,D9,70,D2,72,7D,93,06,C6,0E,F8,5B,4A,AA,59,FE,63,F3,0B,98,FC,5A,27,2E,08,38,6E,A0,82,A2,6E,39,D6,58,A3,C3,02,DE,5E,A6,03,F7,E6,F0,9D,24,7C,D8,ED,EC,B3,69,1A,2F,79,92,9D,5D,C5,64,46,79,A0,34,7C,64,21,8F,85,A4,D6,A5,27,B9,2E,1A,47,F4,FE,F6,4E,8D,7B,F6,E6,53,57,33,D5,ED,97,86,7C,34,06,1E,98,81,6C,94,A9,62,79,0B,9B,3D,F5,2B,54,F8,30,6B,A1,7D,A5,15,D5,BD,7E,E7,EA,F6,4D,F9,67,48,EC,96,A9,07,17,FD,C3,9E,F7,A6,13,4A,7C,E9,E4,0E,EB,22,B4,11,77,75,63,20,42,18,0B,A4,0C,26,F0,44,E4,63,D2,83,CB,76,1B,CA,91,B4,42,19,81,95,18,86,F5,0B,30,BD,93,05,CF,4C,7F,CF,CE,33,3F,BB,73,9B,6F,4D,00,36,D2,36,EB,9C,E2,5F,3B,9D,89,8E,D4,D6,02,76,7F,F0,1D,F8,68,56,B0,EB,BE,13,7A,55,B9,AA,52,77,49,29,99,C5,09,68,58,CE,8E,E2,BE,FC,BC,39,FE,A0,F9,0B,04,3F,30,36,01,C9,4B,BA,D4,FE,63,CD,7E,93,92,EC,8B,9E,45,87,02,96,04,01,72,BA,B9,49,5D,64,57,68,57,35,73,93,2D,E3,4C,CF,A3,A8,C7,FE,B9,8A,A0,C9,B5,45,84,71,A2,4B,CA,85,26,07,8E,2A,42,0E,C8,1E,A5,1E,9E,DE,D8,F2,4B,76,E1,42,7B,2D,15,98,65,39,5E,8A,95,D2,01,1F,BA,71,69,40,CB,73,08,E0,1C,EE,3E,81,06,01,1D,EC,80,AF,CE,DF,59,7E,CA,02,37,12,98,D3,76,43,F8,0E,76,2A,5B,EB,5C,4E,FF,FD,AA,68,D3,B1,24,0F,B7,07,D9,7A,C0,AD,D5,21,5B,60,1A,58,ED,6B,6B,9A,EB,33,E2,8D,71,F1,3A,78,CC,6C,CE,35,D3,E2,DD,70,46,58,2D,A7,22,6E,A4,0F,C8,92,2E,63,A2,77,14,D7,12,C3,3E,C6,83,1E,8C,8E,AB,1B,D6,6D,E8,D7,8A,7F,D1,9C,EC,68,C0,7C,EB,16,18,E8,5F,8A,1F,0D,9E,AC,4B,2B,61,92,40,55,49,08,A4,A2,84,B7,81,B3,03,17,36,9A,E9,9C,33,8B,B0,95,E5,E1,DE,D8,79,AF,23,26,CF,38,B6,26,A9,44,8B,1F,05,E4,E8,6E,57,DA,D5,A3,76,B7,78,62,46,4E,1A,7A,BF,9C,3F,37,3D,76,7B,D4,43,4C,6F,CE,BC,5D,7C,E7,B9,BC,26,ED,73,F9,79,66,B0,9B,28,35,4A,FD,54,97,2E,64,15,4C,70,E4,D7,EA,EF,E9,73,F9,88,8D,DC,91,FB,AE,1B,24,A4,15,FE,78,30,6F,F5,96,52,32,9F,50,29,C2,96,FE,D8,69,CA,5D,5E,90,57,52,B6,0F,2F,2A,8D,C3,9B,41,B9,9C,F2,4C,38,CC,F1,FC,7E,03,D2,5A,A6,E2,4A,92,8C,15,B4,30,C1,3D,B1,68,EE,F2,30,85,A7,36,48,47,67,7B,49,7A,B6,44,F1,7C,FF,47,70,6E,A1,00,55,1C,80,A8,6C,C3,CD,32,66,07,BD,6C,B9,AC,03,F0,2F,CA,A2,23,D8,82,74,52,39,D3,3A,8E,C8,9B,95,E7,BE,2E,AA,04,60,0C,C9,F0,CA,C3,AF,DB,B0,CB,54,F9,40,F1,61,27,D3,42,FC,90,B7,B5,7A,20,46,3C,95,13,5B,50,08,47,5F,13,15,20,F7,F6,EF,29,D8,6C,95,7A,F2,42,24,3C,1D,01,80,D6,BB,04,42,1E,3D,CD,19,18,A0,7A,59,24,AA,28,62,47,78,89,BD,F6,57,C6,3F,FE,C5,97,EA,03,B7,B8,5E,30,43,37,40,7B,1B,DE,D1,AC,80,B4,1F,21,2E,DB,25,6B,82,0B,38,63,63,52,61,8B,FE,FE,D8,08,0C,34,12,4B,98,24,47,4A,F9,B7,C9,43,7E,D8,09,38,4D,E7,3F,6F,57,F9,DC,77,33,8B,D5,64,9D,BF,61,66,44,CE,57,B9,08,82,04,14,DA,98,DB,8C,4E,5A,CD,59,71,41,58,E0,D3,72,9C,E6,B4,E9,7C,DE,07,4C,02,FC,B1,1F,09,67,58,AA,3F,DF,3A,0C,E1,2E,E9,A8,3D,71,90,EB,35,B2,45,28,CE,B8,CA,60,E6,D6,0E,C3,F6,FA,8A,E1,30,91,7B,C4,08,43,C3,90,3D,80,65,D8,32,09,CE,66,E8,FE,2D,53,61,5C,22,9C,F6,C9,49,FD,A3,A9,10,DB,19,36,19,55,A1,A7,54,5C,BC,1E,89,F2,AB,37,FC,EE,2A,46,E1,5B,25,9F,0F,43,7B,29,DB,BD,A0,01,EE,13,29,84,4C,92,0B,01,FB,D5,56,5A,A0,4D,52,34,7F,80,74,00,7F,F1,4A,51,FC,62,87,24,FF,DF,D2,E9,62,50,89,48,FD,C2,E3,99,9B,D1,CE,0D,23,2E,1A,34,A6,F5,D7,A2,C9,DE,12,B8,F1,3C,2A,21,41,D8,94,AB,A5,99,8C,09,AF,26,70,FA,26,6C,79,0F,41,C0,EA,4C,01,50,3F,14,0B,3A,5C,44,6B,1A,09,6F,ED,49,D7,0B,B5,19,66,C9,D3,3D,4D,D1,E7,D9,F5,4B,86,FF,01,7D,03,56,04,A8,7C,C3,B9,47,2D,4F,0C,5A,94,80,4F,19,2C,EE,8A,72,DA,FF,82,CC,57,22,CC,B4,37,3F,4C,60,3D,34,52,DE,C8,F7,AF,BF,B9,F1,43,2A,57,47,1A,F7,22,64,C4,10,DF,F1,68,43,EF,6F,41,23,61,3A,C7,A7,46,02,E8,E8,DE,97,16,01,AD,3D,B2,7A,BC,2D,59,70,84,77,9E,CE,7B,B0,55,CD,FA,28,DE,5C,B6,14,B1,BC,D5,CB,18,E4,4D,F0,07,5D,4B,6F,91,D6,4F,F7,84,AD,D3,E2,B0,D0,7B,58,21,40,C2,0C,BA,9F,18,94,D1,A3,05,6F,9D,45,65,31,34,B5,38,71,95,38,C0,D7,FD,60,59,C4,A7,AE,21,33,AB,62,15,24,38,EF,A0,36,1A,4D,99,9A,5D,40,C1,25,B2,74,22,4E,88,05,E0,21,5C,53,3D,95,07,0B,28,13,D8,5A,33,5D,18,73,82,A3,B4,5A,D6,B7,92,B2,A0,AE,20,28,8F,F7,C4,B8,B9,ED,13,CC,43,75,FA,CB,A4,0F,17,85,05,29,EF,02,5E,C1,93,27,9F,8A,13,1F,C2,49,65,58,14,F9,D4,AF,8D,0D,BF,AD,5C,A9,56,00,3A,E6,12,88,95,5B,DA,33,AB,F8,F6,30,1C,D1,9C,17,A4,0C,B4,BB,06,53,81,79,55,1F,F7,A8,44,42,58,C8,1A,10,C3,B7,A7,94,13,37,08,53,98,A1,00,E7,27,AA,F2,22,19,67,AF,26,11,EE,24,60,89,E1,D4,98,C8,AB,E9,56,0B,1C,9E,C1,B1,AE,85,50,BD,20,09,71,91,C3,AC,EA,37,E8,4D,64,D6,AF,06,A1,BC,E1,CF,7B,36,FF,FA,E6,A0,E0,9D,00,08,10,12,94,96,2A,F5,48,75,64,67,B3,77,10,F0,E7,0E,DF,FE,9E,FC,70,1F,AC,47,41,EB,BC,EF,14,12,61,B1,00,71,F4,2E,16,C3,9F,00,04,5A,65,33,35,B3,36,11,1D,34,3D,81,05,5D,91,9E,6B,E2,90,AA,39,F3,5C,9E,C7,C6,CB,5C,4E,08,63,E4,6E,FF,67,74,83,67,79,0C,B2,37,3F,3D,76,2E,07,D4,94,B8,EA,5C,FC,DA,53,38,D1,52,35,75,AF,79,56,EC,AE,39,E2,7C,14,D8,C4,CE,48,8C,1C,DF,BA,46,2B,8C,6E,8B,92,B8,B4,BA,57,9F,4C,4D,AE,90,B2,5B,99,82,A0,F1,27,74,65,8C,E9,77,11,95,9E,71,EB,16,48,87,73,BD,3E,95,93,92,BF,10,66,AA,88,9E,83,76,25,A9,72,26,3D,2A,68,A6,67,74,DF,89,A6,70,1A,3F,61,C6,19,D0,2E,51,75,13,DE,E1,BB,79,49,4E,5F,48,B2,78,F6,1D,0D,F2,BB,74,F7,AE,C3,6E,A2,44,B4,C9,D3,31,A8,AE,C6,0A,77,5C,97,01,1C,72,E5,82,87,11,18,E5,36,C8,4C,79,7F,24,5D,DD,22,41,43,F6,99,B0,05,03,64,27,45,21,62,DA,16,9D,5E,C0,2D,A7,D4,39,EB,18,33,FD,27,5C,9A,BE,81,BB,E6,5E,A2,ED,05,E5,6A,29,55,EB,D7,09,40,F9,E5,44,2B,2A,4A,55,21,2C,86,63,E4,81,78,05,BC,97,AC,81,D2,D7,B3,C1,01,11,19,F3,06,79,31,CF,CE,FA,2B,E5,C6,00,71,11,B9,4F,99,20,5A,57,1B,7F,B2,67,4A,8D,9D,85,EA,59,11,32,14,B0,CE,38,D9,98,D3,F3,4C,B0,22,28,70,6C,5A,01,21,F2,5F,2D,66,8D,B4,2B,22,84,9C,C2,86,18,CC,A2,5B,87,C7,BD,30,64,80,BC,AD,33,1D,F5,78,A0,95,AD,A3,89,1A,BF,CD,3C,E2,89,F0,52,A5,C0,89,69,23,14,0D,21,D2,C7,5E,F7,AC,F5,04,20,77,6F,03,1F,E1,AB,68,F5,74,29,7F,2A,91,99,1D,B0,81,59,C4,84,3A,2E,04,DC,73,2E,B4,AB,CB,63,86,4D,BD,FD,34,BD,3A,35,05,2B,0C,35,7C,4A,A8,05,58,F2,56,A9,8D,F1,D8,91,FC,4F,2F,DA,A8,68,B1,1D,F4,38,E7,32,25,E1,39,8B,66,61,1A,B8,7C,4A,20,0C,F3,E3,2D,80,DA,72,9E,5C,F4,8F,D0,5E,CA,8D,88,28,38,B5,3E,59,AD,31,88,CB,5D,83,40,21,D2,DF,FD,A2,3F,86,26,BF,34,C8,90,54,77,B1,78,E5,42,28,6E,7A,DE,D2,F8,F0,AE,B7,2B,D8,E2,6E,48,EC,65,B4,0E,9D,7E,2E,69,65,B7,71,0C,C4,D2,9D,DB,60,A1,D6,1A,07,D5,52,25,C3,88,32,5C,D6,71,10,BD,E9,45,A5,F4,1D,F3,45,36,28,27,F6,DC,74,74,C0,F5,D1,E0,84,6E,D2,D6,EA,36,20,CF,B3,EE,80,F3,6F,14,94,63,0E,F4,78,E4,5A,AB,B2,3E,34,C3,54,4B,D4,DE,D3,E5,52,7B,99,0A,27,BC,AC,7B,EE,64,B7,6D,C0,30,22,AD,77,35,21,E2,02,AD,C3,90,6A,5E,0F,06,D5,9C,61,A6,FB,44,F8,EF,55,9A,94,C8,5E,F8,48,75,F5,48,AE,5A,B9,3B,07,AC,4E,1B,91,34,7B,C5,E3,7B,17,C9,12,DA,65,27,C6,55,0C,4B,CF,6C,04,F0,67,B6,72,1C,D1,2C,D6,72,5E,E2,CA,FC,05,34,14,A0,7E,ED,23,CA,71,4A,CC,C9,E4,A6,0A,17,B7,E8,96,1C,CF,47,F7,F5,67,B6,1A,71,32,BA,59,A0,50,E6,57,82,81,2A,33,27,B9,2B,BD - -linearMatrices_full = 31,C1,12,36,B1,D3,AE,D8,FA,91,7D,27,02,E6,03,2B,80,00,00,00,84,0D,C7,FE,0F,9B,B7,8E,C5,BC,C1,19,71,98,76,AB,00,00,00,00,67,2E,91,5E,C7,C6,8E,9D,93,11,4B,5C,97,AC,43,C3,80,00,00,00,D2,13,55,19,17,35,A6,D2,8F,CE,DD,15,DA,02,6F,8E,00,00,00,00,1E,34,A3,50,44,48,4C,84,5E,22,38,AC,98,14,73,FD,80,00,00,00,8E,17,6F,BE,1C,94,ED,15,1D,4F,9D,9D,8F,E4,75,A9,80,00,00,00,85,80,AB,E0,7D,41,2E,BF,4C,B2,D6,71,39,94,A4,40,80,00,00,00,57,B3,D6,0C,4B,FF,88,61,2A,80,C9,9E,B6,49,87,4A,00,00,00,00,05,DD,E1,E2,5D,EA,D2,A5,07,33,6C,F8,7C,54,5F,3C,80,00,00,00,66,EB,52,DF,1A,1D,F6,0B,6B,0C,1F,BD,D6,EB,6A,ED,80,00,00,00,45,C2,1D,7C,A2,7C,B7,0C,CE,4E,D6,49,D4,57,94,44,00,00,00,00,C7,53,DE,B1,DA,1E,C6,42,A8,95,BB,34,EC,C9,3A,8C,00,00,00,00,B6,89,FB,4E,7F,88,27,00,9B,AA,61,7F,4B,7A,E5,C9,00,00,00,00,B4,55,04,F8,33,96,2F,23,2A,30,D7,66,EB,34,25,B5,00,00,00,00,FF,24,03,83,EE,53,95,FE,65,8D,3B,E6,A7,6D,B3,D3,00,00,00,00,0A,E7,70,0E,D6,7A,E4,F3,37,F3,5E,FD,49,8C,4A,2A,00,00,00,00,B6,44,8D,E3,41,38,79,24,CC,30,36,7D,EE,55,2B,08,80,00,00,00,67,A7,EA,BD,69,AD,F8,36,92,15,4F,E5,A4,B9,03,AD,80,00,00,00,8B,85,24,ED,CD,31,44,B6,0D,AC,C2,07,19,FF,A1,3E,80,00,00,00,6B,3A,DE,80,41,F8,34,B4,08,2B,84,CD,44,13,0C,99,00,00,00,00,F1,AF,40,D2,F9,DC,42,B4,66,8C,22,B4,9B,5F,33,90,80,00,00,00,3C,50,56,34,48,D9,BB,DC,2A,FB,F3,8A,8A,20,99,DC,00,00,00,00,B3,20,AA,59,EF,13,CE,06,BF,E3,6E,AE,0F,62,56,D4,00,00,00,00,0C,30,70,46,8E,86,67,5B,70,68,34,6B,A9,D7,DA,DC,00,00,00,00,6E,DE,4A,74,F2,B4,AA,30,22,53,0B,55,C7,A3,17,F4,00,00,00,00,35,2D,73,63,E1,14,82,72,5D,7A,24,24,14,A7,C1,64,80,00,00,00,2D,6F,8A,8B,29,50,B7,87,1A,A3,53,80,CA,9E,F0,2D,80,00,00,00,AC,81,0C,99,1B,BC,D3,BA,B4,99,F0,EA,1D,84,94,32,80,00,00,00,78,4F,54,A5,21,67,9E,C0,C1,76,40,FF,0C,DA,50,B5,80,00,00,00,A5,00,56,FD,54,12,41,ED,A2,AE,76,AD,A1,2C,46,11,80,00,00,00,7C,D9,63,86,55,F5,03,FB,9C,7B,62,61,7E,F8,29,38,80,00,00,00,BB,EC,0D,8A,B1,35,9E,CB,82,D4,25,D2,4C,5F,69,9A,80,00,00,00,08,71,BD,68,D4,21,EB,46,49,DE,A6,89,52,FF,BB,BF,00,00,00,00,F6,29,29,72,67,02,F2,B3,E0,76,AC,71,C9,7C,16,FC,80,00,00,00,62,8B,B1,66,D9,52,0D,C3,7D,6E,51,1D,6F,23,76,1E,00,00,00,00,DE,84,E5,E3,4D,B5,54,36,3C,EA,5A,B7,03,63,2E,DF,80,00,00,00,23,96,7A,6F,82,68,85,43,B2,6E,71,CE,3A,C5,64,4F,80,00,00,00,7D,20,FA,CD,19,1E,FF,EE,02,DE,E5,1C,25,D3,28,03,80,00,00,00,82,B2,93,55,28,08,38,80,F5,9A,6B,4C,6D,D8,A8,3D,80,00,00,00,87,9F,3F,2B,EC,A2,8D,D8,E1,B5,3E,D8,3B,EB,11,D9,00,00,00,00,64,21,D4,54,39,D5,19,A2,24,B1,6B,25,92,1E,50,F8,80,00,00,00,D0,35,36,CF,2C,D3,78,BF,C1,4C,22,C1,4F,E6,28,D2,80,00,00,00,3C,6A,7B,FD,08,2F,0F,9C,B5,95,EF,62,AE,83,F4,B5,00,00,00,00,99,B5,2F,5C,50,AE,95,71,1B,F3,30,2D,A5,26,AF,3F,00,00,00,00,42,5E,BE,EF,E1,FA,C4,28,F2,02,F7,71,25,98,F0,6D,00,00,00,00,CB,7C,E3,42,2E,CD,5E,45,8B,C0,AF,27,7F,21,F5,30,80,00,00,00,BF,03,04,B4,13,16,9C,6A,D8,95,F4,3D,86,EE,50,7F,00,00,00,00,9F,2E,54,AE,3C,13,59,42,30,AC,49,FD,B5,B3,0A,F9,00,00,00,00,8D,57,F0,EF,7A,B7,38,FE,7C,FF,E8,FA,9A,A3,91,31,00,00,00,00,29,C7,3C,30,8F,A3,F1,83,CB,E5,FD,2F,59,0B,EC,FE,80,00,00,00,D6,DB,C2,81,1C,25,3D,04,9E,A6,5A,A1,1F,5C,C6,FF,00,00,00,00,1F,AB,26,2A,96,39,78,FB,0A,B3,04,89,F9,8D,70,CF,00,00,00,00,29,C1,D7,61,40,D6,E9,52,F3,0F,E0,B7,04,8A,F4,D5,80,00,00,00,BD,BE,97,8A,B5,BC,BD,D1,DE,68,27,BA,4B,85,1B,4C,00,00,00,00,B5,E5,A3,AB,2A,F7,67,1D,17,C6,F6,6C,22,7B,2A,A8,00,00,00,00,6F,C9,82,A7,BA,DB,91,D6,27,16,72,46,80,67,9B,EE,80,00,00,00,C8,5B,2D,C0,F7,CA,9E,49,56,85,AD,0A,E2,99,C1,26,00,00,00,00,13,70,1E,BB,8C,0C,56,7D,68,16,E9,C6,9E,AD,6B,6B,80,00,00,00,44,4A,37,72,42,02,02,5F,8F,F3,77,C3,A3,A8,B4,07,80,00,00,00,D1,0B,25,25,18,E0,9E,8D,07,F2,6C,35,C5,2D,47,86,00,00,00,00,63,D9,92,F2,57,65,9B,7A,44,D1,25,18,93,BE,0C,56,00,00,00,00,D0,D8,A2,FB,44,5C,3E,AF,2C,93,5E,8C,EB,84,2C,7A,80,00,00,00,B3,4B,B6,C8,18,BC,16,1D,39,9C,4B,E0,CF,56,FB,30,00,00,00,00,65,86,F2,51,B1,03,B0,8D,2C,05,4B,EC,A5,4C,B8,47,00,00,00,00,22,9D,B7,07,C7,DB,5A,CE,9C,5A,33,5C,DA,10,85,A7,00,00,00,00,9D,DE,EB,E6,D1,E9,CD,15,E3,1C,8C,94,B4,CD,8E,81,00,00,00,00,2A,24,A8,35,DB,7D,21,87,FC,CC,E8,9F,7C,8C,3B,18,80,00,00,00,A9,63,39,53,CF,D9,D2,6F,03,5F,91,74,FC,53,7B,EE,80,00,00,00,4E,7C,C7,46,DC,07,3F,61,C6,33,16,78,5E,C2,6E,A4,80,00,00,00,3E,21,5A,39,12,38,CD,97,3E,B2,0B,73,D7,67,42,1E,80,00,00,00,C6,8A,64,64,B2,98,F7,49,CC,1A,84,86,49,53,CD,04,00,00,00,00,C4,D6,4D,44,A9,6D,7D,03,59,FD,68,D5,F4,E7,9B,D4,00,00,00,00,59,C1,54,FB,42,88,44,42,64,20,E7,E6,EA,73,E0,32,80,00,00,00,13,1E,31,CF,D7,25,F7,23,0D,E3,35,F4,7F,6A,03,FB,80,00,00,00,8C,5D,DA,D3,13,7A,09,85,19,23,5F,8A,26,EF,5D,37,80,00,00,00,8E,3F,B9,CB,10,7E,39,5D,38,89,23,0F,DC,B5,E7,79,00,00,00,00,E7,10,14,19,AA,BE,8F,3B,57,C5,01,E7,A7,0F,E6,7B,80,00,00,00,52,3A,33,9D,12,E1,37,0E,0C,57,55,90,0A,D6,ED,10,00,00,00,00,AE,4B,91,64,0A,5C,44,14,BF,E6,46,15,04,B5,43,98,00,00,00,00,EF,00,F3,AF,D3,A3,12,F4,78,6C,11,8D,28,86,44,6E,00,00,00,00,90,2B,8B,CE,C6,BA,C2,7E,6F,D8,E3,98,14,C4,2A,85,00,00,00,00,46,B8,CC,91,50,7E,E2,C0,C1,91,95,76,C6,98,19,7A,80,00,00,00,F4,5D,37,3C,46,9E,34,A9,77,74,5D,D6,A3,A4,5A,79,00,00,00,00,7A,3D,11,85,91,7B,33,54,5B,FC,85,BD,0E,96,A1,2E,00,00,00,00,E7,FF,AD,39,35,15,B0,F3,37,E8,74,B1,AF,38,95,F7,80,00,00,00,DF,D8,BB,BC,0C,3B,02,31,D3,DD,EC,AB,86,77,4A,FE,80,00,00,00,0F,DD,30,8E,D1,43,6E,CC,B8,F8,8B,63,14,F2,AF,4C,80,00,00,00,18,58,A4,F9,50,FB,B3,23,23,2F,B9,3A,95,3F,35,2F,00,00,00,00,8B,F2,B8,A1,D2,D5,8A,D9,E5,34,65,27,66,C2,AC,F5,00,00,00,00,3D,B0,96,DA,A8,D1,8C,3D,37,B6,A4,55,E5,66,AF,5A,80,00,00,00,01,ED,5F,D9,E2,D0,74,F0,15,D8,D5,5E,C2,E0,33,AC,80,00,00,00,77,AE,6D,BC,9F,BB,9A,C9,29,3F,76,9A,A9,FF,4B,DA,80,00,00,00,F9,AE,A3,ED,A5,1F,6F,EB,11,5D,F0,D0,D6,98,D4,F2,80,00,00,00,3E,A1,07,FC,4F,1E,F4,E1,0A,6D,AD,C7,CC,BD,D1,45,80,00,00,00,E6,79,BC,6D,59,2B,66,10,87,20,23,A4,3E,46,82,7A,00,00,00,00,B8,23,E3,2F,6A,8F,02,5F,B6,A7,B1,61,68,1E,A2,AC,80,00,00,00,CB,B6,7E,E1,FB,76,51,5C,1C,56,FF,3D,81,66,41,7C,80,00,00,00,14,BD,76,A4,76,AA,9D,D6,8B,64,80,01,65,A7,D7,F8,00,00,00,00,B5,FF,35,83,36,93,6A,3E,93,9B,16,6A,EF,0E,76,EE,80,00,00,00,00,12,11,D5,5A,34,26,61,89,2F,EB,56,54,FF,EC,DE,00,00,00,00,C8,1F,EF,55,1B,D0,50,1A,0B,D1,01,4D,7E,B2,E6,E8,80,00,00,00,BE,F3,8B,26,F8,3C,E5,DF,0D,9C,C6,64,FE,0A,0F,1A,00,00,00,00,16,2C,D3,48,68,F9,9A,E5,52,B8,6F,5B,28,F7,75,6D,80,00,00,00,05,9D,E0,FC,78,CB,2A,F2,73,9E,6F,04,56,67,57,98,80,00,00,00,38,1A,5A,E6,D8,03,B2,DE,01,52,DF,23,4C,87,49,72,80,00,00,00,91,69,32,6A,08,44,C7,19,EE,2F,C4,F1,0A,D5,7C,08,00,00,00,00,D2,6C,4B,0D,D2,3B,10,23,1E,73,8A,8B,2B,F6,C0,02,80,00,00,00,40,D1,73,C0,5C,27,F5,29,AA,47,20,62,80,17,C6,7F,80,00,00,00,E5,B0,21,3F,E8,79,1A,24,84,98,D1,A5,BE,3C,27,4F,00,00,00,00,5E,04,82,FF,F8,FC,27,AD,4B,AB,C9,69,9B,09,64,B8,00,00,00,00,5F,BD,D6,76,D4,9D,EF,5F,FE,66,D5,F7,78,74,CC,02,00,00,00,00,14,A2,35,E4,1D,F2,1B,4C,A2,34,FA,A4,64,88,D1,C8,80,00,00,00,33,DF,9B,D5,29,D1,BC,84,62,20,86,59,E5,F4,7A,A8,80,00,00,00,6F,84,E9,3B,17,DB,20,AA,5D,AC,8B,00,C2,CE,5E,7A,00,00,00,00,12,4F,E2,EC,5A,B1,E5,DD,0E,98,F6,A7,1F,70,5F,77,80,00,00,00,E8,DC,E7,C0,AC,60,F5,C8,8A,E2,07,DE,A7,70,C7,7C,80,00,00,00,76,D4,A3,2E,29,73,1B,2F,4A,B4,B3,5E,8A,40,CE,A4,00,00,00,00,0D,2A,61,DA,99,FE,B6,A3,41,F1,D4,41,DE,E3,17,4E,80,00,00,00,67,97,F6,8D,C9,66,65,59,B6,6E,B0,1B,8E,A0,DE,B2,00,00,00,00,A8,DD,8B,5D,DE,AC,4C,94,44,40,51,4B,A3,E2,87,40,80,00,00,00,8F,27,B7,6D,08,AD,48,36,19,F3,7D,89,17,23,34,44,80,00,00,00,76,95,CE,A3,34,C2,5C,89,0C,65,2C,D7,36,D3,BC,42,80,00,00,00,C1,08,29,44,EC,9A,12,84,E4,10,B8,C4,AF,B4,F1,D7,80,00,00,00,9D,E7,24,50,6D,59,72,1E,FD,9F,E7,E7,94,5A,F5,1A,80,00,00,00,20,87,3A,18,47,30,83,06,7F,44,6D,6F,9B,FF,E1,04,80,00,00,00,C1,05,C3,A4,84,1C,0A,C2,EA,96,3A,C7,90,17,18,A5,80,00,00,00,6A,9B,7B,FE,C6,3A,E6,3E,1A,6A,C1,23,32,3B,F1,E3,80,00,00,00,08,40,D7,30,FB,0A,32,B4,0A,68,EF,83,4F,AA,68,D7,80,00,00,00,55,2B,56,BD,72,32,48,0F,9E,81,86,1F,56,56,73,6A,00,00,00,00,55,49,28,57,D5,D6,EB,FC,26,38,A6,6E,D2,74,AA,9A,80,00,00,00,DC,F4,A3,0C,7C,FE,77,A4,5C,38,ED,40,7B,B1,43,F8,00,00,00,00,E0,66,DB,F3,09,E2,91,F8,5A,F2,F1,43,C8,F5,95,F4,80,00,00,00,A2,58,65,0B,F0,41,2A,0A,E0,71,F5,BC,29,0D,88,44,80,00,00,00,C9,AE,DF,73,4C,6A,80,A1,56,4F,13,0A,05,08,8D,32,00,00,00,00,4A,C7,AB,6B,BE,54,E6,39,86,B8,0B,02,62,ED,F2,2B,00,00,00,00,0D,D1,09,50,10,B2,CD,6D,79,FB,D3,5F,03,2E,66,30,80,00,00,00,65,27,5C,CA,E5,25,38,AF,38,5F,A3,AC,EF,62,25,04,80,00,00,00,57,09,F3,25,ED,80,6B,2B,D0,85,11,B4,23,20,FC,C1,00,00,00,00,A6,0E,FF,AF,9E,29,21,02,5F,AD,33,1C,4C,47,81,9F,80,00,00,00,94,FE,8F,1B,D1,0D,B2,03,8C,97,FA,A5,13,F8,07,0C,00,00,00,00,EE,B5,76,E5,B1,0A,C3,BA,DF,08,9C,72,04,F0,20,49,80,00,00,00,32,28,C8,B8,E5,7E,20,A0,9A,31,32,C9,FD,9E,E0,25,00,00,00,00,07,C3,14,C0,33,A7,E8,CC,F1,E9,A9,00,ED,C3,DC,BB,80,00,00,00,48,05,7A,55,BE,22,E9,00,8C,1B,17,72,AF,79,3D,EC,80,00,00,00,1D,6D,22,29,7A,8F,21,D3,30,7C,40,12,A6,F8,5D,73,00,00,00,00,31,86,0E,C7,F8,01,1F,F4,A1,B9,52,1D,6B,56,75,EF,80,00,00,00,60,A4,B6,05,24,1B,0B,F1,E4,37,2B,91,BD,0B,33,0E,00,00,00,00,41,4D,FC,94,A5,7D,4D,5F,F0,BB,B5,FA,77,4A,03,B3,00,00,00,00,DE,DB,81,69,C5,A3,34,7D,71,C8,C8,89,3D,9F,DA,AE,00,00,00,00,55,E9,73,17,3A,47,D1,29,E1,21,13,7A,13,F2,99,0A,00,00,00,00,B9,A6,9B,EE,FD,1B,DF,99,4E,0A,AA,33,84,FF,62,76,00,00,00,00,48,BD,01,13,F1,35,F5,3C,D3,B6,AA,AB,16,43,49,5E,80,00,00,00,C8,78,12,3B,78,5E,91,0D,16,41,CB,9C,32,A6,1A,D7,80,00,00,00,42,E4,2F,E1,BC,75,EC,C0,FC,51,5D,4A,33,F6,9A,1A,00,00,00,00,83,1D,AC,1B,A4,A6,E4,ED,1B,AE,31,DE,A2,1F,89,FC,00,00,00,00,82,5F,3D,E2,6E,7A,0C,8E,E3,F1,C7,83,C0,3C,1C,8D,00,00,00,00,CD,0C,A4,06,3C,3C,B8,2C,79,FB,F8,3A,6C,9F,35,9D,80,00,00,00,13,26,B8,3E,D3,6A,B4,6A,1C,61,FF,E0,28,C8,D4,8C,80,00,00,00,DB,87,FF,09,39,28,E2,09,87,EA,0F,F9,EE,50,7C,A2,00,00,00,00,19,B4,73,FE,7C,6C,CA,D2,67,B5,01,E4,FE,E9,D7,9B,80,00,00,00,4F,F2,94,E1,37,ED,F9,AA,61,99,F9,81,D0,1A,B7,E1,00,00,00,00,FC,32,92,CE,1E,8B,C0,F4,1B,BC,91,58,75,2F,B8,C4,00,00,00,00,ED,DA,EB,D4,E0,54,D7,4F,7D,33,89,E9,BE,74,30,D2,00,00,00,00,8C,0F,3D,B4,75,AC,F7,67,C3,30,2A,2E,C3,B0,4C,17,00,00,00,00,DA,52,EF,C6,D5,57,5D,CD,3D,21,91,FF,FC,C3,6C,EA,00,00,00,00,F8,8B,66,39,02,DF,1A,A3,A8,50,AC,10,61,36,D3,B0,00,00,00,00,2E,B8,5B,79,95,0A,70,C6,B6,DE,8E,38,CF,7D,15,A0,80,00,00,00,E7,D3,CD,6F,9F,3A,B5,16,E5,18,DA,C7,97,F0,B8,47,00,00,00,00,50,A8,BE,CF,58,AD,76,8B,0D,70,AD,2D,93,F8,DD,86,00,00,00,00,D4,71,8D,32,BB,6E,E1,0C,73,92,6A,57,1C,8D,42,86,00,00,00,00,68,D1,32,F9,CF,97,CB,02,79,C9,9B,6C,5F,5F,19,0A,80,00,00,00,B3,6B,8B,1F,25,9E,3A,09,31,AA,57,6A,08,7B,D1,04,80,00,00,00,69,28,8F,D8,F1,F3,28,50,CB,1C,26,1D,02,AC,82,11,80,00,00,00,D3,5F,7F,D8,82,55,70,30,90,6A,31,53,73,56,D3,C8,80,00,00,00,B6,BF,0D,F3,9F,A2,08,EA,52,BE,0D,58,07,AB,88,99,80,00,00,00,2C,8A,D8,60,20,35,43,D0,ED,20,72,40,72,AC,92,6C,80,00,00,00,49,D7,D0,9A,A5,9C,00,B1,86,BB,2F,A6,EE,07,74,2A,80,00,00,00,CC,CF,30,E4,8A,9F,3D,8D,94,7B,84,7C,4C,82,CE,B7,80,00,00,00,4E,AF,D9,AD,C0,AC,AC,A4,0C,64,B8,73,89,2F,D8,BA,80,00,00,00,C2,2A,65,1D,1E,59,02,AB,8C,46,E3,8D,A7,D2,69,06,00,00,00,00,91,E7,82,CC,26,B0,41,C9,82,49,B1,C0,0A,36,07,59,80,00,00,00,3E,41,0A,A3,FF,72,D2,E4,C6,F5,DA,E1,89,82,09,92,80,00,00,00,F5,1F,DE,39,F0,E5,D9,C0,4F,06,F7,D0,C4,4F,06,B2,80,00,00,00,EB,12,D3,C9,15,03,8A,6C,F9,E4,B0,C0,D8,72,73,59,80,00,00,00,4C,F7,91,F5,88,73,4A,D7,EF,77,E9,A1,9B,C6,7C,DA,80,00,00,00,62,C0,08,61,34,04,2A,5B,22,88,54,57,68,C9,B7,21,00,00,00,00,46,6E,A0,07,DC,3E,B3,85,3E,9A,93,ED,70,86,F2,D9,00,00,00,00,9E,07,36,42,F0,09,38,B1,8F,FC,56,8C,73,7A,7E,E9,80,00,00,00,74,0A,E7,99,56,81,CA,A7,EE,9A,FD,F9,CF,96,ED,A7,80,00,00,00,49,E6,95,C5,2C,72,AB,A3,F0,9C,EC,E7,EB,43,96,C9,80,00,00,00,89,66,04,F6,21,35,41,D6,81,2D,17,39,AF,46,0C,B5,80,00,00,00,B6,BA,DE,74,E3,C0,A4,22,28,92,B3,A3,0C,0A,DB,7D,80,00,00,00,5C,83,49,3A,B9,DD,F1,86,F2,07,B7,32,F8,93,D7,91,80,00,00,00,32,EE,79,DC,7E,12,E7,55,2E,08,81,95,20,85,98,38,80,00,00,00,99,1B,74,72,7F,D5,6E,85,4F,2D,CC,34,05,A4,13,6E,00,00,00,00,23,59,BF,8D,99,33,25,0F,1B,E8,6D,AE,CE,23,FE,2E,00,00,00,00,92,0C,6C,1A,1A,3C,1D,BC,0E,1C,A1,3D,C3,0C,A7,A3,00,00,00,00,E6,57,A9,44,C1,AC,5A,55,13,AB,A0,EC,54,13,30,F7,80,00,00,00,C7,4F,6D,CC,6F,03,0D,B1,55,8E,46,99,B6,F5,F7,94,80,00,00,00,AF,8B,4B,0A,6E,8B,96,7F,11,F5,31,5C,B4,A0,00,8B,80,00,00,00,C0,2A,96,19,D5,BF,31,16,29,BD,12,38,14,A3,68,96,80,00,00,00,17,03,75,64,35,00,1A,7B,A1,54,51,34,47,00,6C,56,80,00,00,00,C2,65,61,6F,DA,90,89,01,34,4B,D3,FD,44,93,15,A3,00,00,00,00,CC,3C,37,64,70,DA,75,7D,2A,42,FB,39,57,63,E1,C1,80,00,00,00,9E,84,C4,A8,A1,24,E5,FC,6E,0D,03,18,EE,87,A7,97,80,00,00,00,EA,A6,96,9B,2E,AF,60,FB,7C,7B,18,08,4F,48,72,DD,80,00,00,00,D5,30,1F,88,EE,2C,44,7D,53,DB,DD,38,18,03,29,D5,80,00,00,00,37,A7,C4,6F,4F,EF,AF,4C,5B,93,AB,96,E5,1E,14,B2,80,00,00,00,0D,C0,AD,2C,E6,4C,69,DD,3A,53,70,E6,EB,07,30,C7,80,00,00,00,8F,0F,4A,21,6E,89,BF,97,3F,56,3C,C8,D2,F9,B4,EB,00,00,00,00,59,2D,2F,E1,AE,72,65,4D,15,64,8F,AA,86,DA,94,01,80,00,00,00,5D,5B,66,30,96,16,3A,00,13,D1,18,EB,CE,77,02,3C,00,00,00,00,BC,68,74,50,24,8D,7D,DA,20,2E,8D,87,D9,51,FC,69,00,00,00,00,70,96,92,FB,AA,12,10,4C,04,4F,D7,6E,EF,CE,34,E3,80,00,00,00,7E,0E,8E,4E,D8,5D,15,38,C9,52,14,A9,24,4A,9B,46,80,00,00,00,45,E8,A3,F3,89,8C,35,3B,17,84,77,A4,F1,89,5F,4D,80,00,00,00,BE,9E,27,AB,1D,E8,74,75,07,DF,0A,A7,64,91,65,CC,80,00,00,00,79,12,11,BC,57,6F,26,F8,C5,64,97,7E,BC,87,7A,FC,80,00,00,00,EC,EF,40,BE,24,00,80,FE,D2,36,5D,35,3A,74,2E,1B,80,00,00,00,23,9F,C4,F6,6E,CA,6D,D7,4C,EE,A2,F4,41,C9,A6,A2,00,00,00,00,B8,D6,D1,7B,76,CC,E4,02,6A,F5,B7,86,B2,F5,19,13,80,00,00,00,EB,25,04,A5,F1,1B,ED,EC,D2,E5,32,5F,FD,89,59,FB,80,00,00,00,E3,5B,C0,73,D8,9B,B3,66,FC,CF,FC,75,C2,F7,51,F3,00,00,00,00,AF,22,A2,74,4C,AB,E1,81,34,F6,6C,A9,2B,F3,09,87,80,00,00,00,AA,38,C9,BA,75,62,BD,13,56,E2,E6,4B,09,DC,5B,40,00,00,00,00,78,73,43,8D,78,E0,80,D0,87,B1,F1,68,7E,54,3F,3A,80,00,00,00,B3,5B,AF,36,CD,1E,45,6C,75,CB,E9,9D,C4,30,95,68,00,00,00,00,7C,58,F2,22,B5,50,15,D8,EE,22,C2,07,12,2F,48,6A,80,00,00,00,45,6E,CD,69,AC,40,94,5C,E4,52,AD,0C,E2,9A,E6,A0,00,00,00,00,AC,6C,24,86,B5,F3,9F,28,5D,B9,E8,7D,6F,43,23,2B,00,00,00,00,18,80,63,66,6A,EF,EE,0D,D5,46,7A,AD,70,2F,C5,2B,80,00,00,00,C5,FA,8E,E2,2A,6B,44,72,C7,B5,08,BF,56,E1,27,EA,00,00,00,00,F1,70,4D,7E,CA,6F,EC,BA,21,3F,DD,BD,59,13,A2,7F,00,00,00,00,C5,F2,95,64,83,B5,0B,12,B3,9A,98,18,3E,C6,DD,48,80,00,00,00,11,26,7C,28,0A,41,75,87,3C,29,43,E9,8A,36,3F,A7,00,00,00,00,C2,B1,7F,7D,8E,D0,CB,1D,12,48,60,62,AC,7F,4B,A5,00,00,00,00,A6,B5,B8,80,94,43,B0,3B,5F,18,81,B5,76,9B,70,8A,80,00,00,00,BA,11,33,34,C5,06,EA,37,9D,AD,9B,A3,A9,4E,15,79,80,00,00,00,EA,FA,0A,F2,11,BA,51,C2,48,AB,0A,E6,F7,53,F6,FA,00,00,00,00,D6,06,C4,F3,CA,37,F6,85,F8,52,BB,7C,31,48,79,C4,00,00,00,00,89,90,55,6D,2E,C3,C4,7F,0A,09,02,C9,2E,DE,33,5E,00,00,00,00,A3,25,68,DF,B8,3A,78,38,82,73,48,95,76,FC,50,8A,80,00,00,00,29,16,10,A6,D6,2E,2D,9D,54,1C,0A,CE,68,93,3B,A1,00,00,00,00,1D,E1,C0,DB,7E,48,6C,CD,7D,75,6C,74,A5,4F,46,8F,80,00,00,00,C0,6D,A7,DB,ED,CC,E0,EE,2E,FA,A7,E6,A9,11,57,9C,80,00,00,00,E6,3E,0E,02,EE,21,F7,72,A3,62,70,97,AD,52,4A,55,80,00,00,00,5E,8C,8E,C0,9C,1E,53,4C,C5,2A,10,76,86,A4,6D,45,00,00,00,00,7C,CE,15,ED,0C,E9,F6,3A,71,99,0E,13,4F,4D,7B,4A,00,00,00,00,C7,FC,6F,94,CF,BB,A9,83,F7,E2,9A,04,DB,26,4B,5A,80,00,00,00,5E,71,10,99,81,6A,86,4E,D3,91,C7,DB,19,63,2C,1F,80,00,00,00,B4,B0,56,98,0C,D7,07,AC,E5,01,27,60,29,D7,32,0D,00,00,00,00,15,C8,A4,10,74,8A,DB,27,BF,A7,AA,08,9B,D8,72,94,00,00,00,00,FB,51,10,81,B5,21,7F,C5,14,23,23,23,C7,BB,53,C9,80,00,00,00,38,B3,3F,15,B6,22,2A,0D,9C,62,0A,DD,34,B0,2B,43,00,00,00,00,69,E0,52,32,3F,43,80,E3,E9,2A,65,D0,35,9D,95,DF,00,00,00,00,E7,91,77,5D,C9,4E,9B,17,88,2A,47,7E,6A,7D,4A,BB,00,00,00,00,44,34,D2,A6,85,44,7D,93,FD,4D,95,DE,1C,0E,12,07,80,00,00,00,BC,EF,DF,31,7A,C9,4D,2D,6B,CE,C2,C5,81,17,6F,26,00,00,00,00,10,CE,70,3E,AC,37,20,A2,3D,F1,12,9B,8E,84,38,3D,00,00,00,00,58,F3,87,CD,3B,41,5C,91,11,6F,16,CA,A3,2E,E2,1E,80,00,00,00,2D,CD,5C,C9,86,93,A9,E6,D9,BA,14,D4,A5,9A,EE,05,80,00,00,00,FF,12,97,F6,7A,CA,55,4A,95,9C,59,B6,E2,2A,5A,70,80,00,00,00,C6,9E,C2,70,20,A9,CC,BC,6B,B7,36,AA,73,DE,89,B9,80,00,00,00,FE,B3,5D,25,01,35,90,4F,03,6D,16,0E,14,D8,32,02,80,00,00,00,86,33,81,CE,B2,8F,74,F0,95,A0,07,19,C0,8B,D8,6C,80,00,00,00,37,19,A0,2E,FF,B0,5A,95,AA,CF,8D,CC,2B,EC,FB,71,80,00,00,00,4D,D4,CD,1A,97,0D,B5,C4,95,0A,37,97,70,2E,22,0F,00,00,00,00,CB,D8,56,7D,22,85,3E,DE,F1,44,C7,51,3D,BA,E0,38,00,00,00,00,E4,A7,5A,4C,51,76,CB,69,AA,6F,19,15,E9,26,BD,04,00,00,00,00,99,80,84,26,2C,AD,8E,6C,96,8E,B1,0C,AC,22,8F,B0,80,00,00,00,E7,62,F1,89,67,71,92,6C,E0,DC,01,18,C9,7F,CD,97,00,00,00,00,DA,4E,CC,85,EF,D1,4F,E7,50,76,2B,2D,1C,07,51,9C,00,00,00,00,E1,F1,46,A4,6E,CB,12,80,CC,18,1E,E8,38,C3,4C,12,00,00,00,00,37,A8,16,AF,C6,29,00,35,A7,98,42,7A,BE,F1,78,79,00,00,00,00,D8,6E,F8,B4,43,85,5D,63,0F,AB,75,EE,77,B7,E1,0D,00,00,00,00,35,50,FA,25,C0,86,27,74,6F,C5,38,C3,21,EE,22,96,00,00,00,00,54,60,4D,24,2C,01,B7,A3,1E,CF,CD,37,1D,89,AE,E9,80,00,00,00,BB,8E,20,3D,34,AE,D9,3D,E7,58,DD,88,E1,9D,58,14,80,00,00,00,C2,15,8E,15,6F,7F,63,B0,ED,49,33,52,A3,DF,6C,35,00,00,00,00,E0,B5,69,E7,BB,18,85,AB,71,01,49,1D,97,6D,8E,29,80,00,00,00,85,52,D0,DE,08,DF,EC,0F,95,CB,6F,82,CE,03,0B,3C,80,00,00,00,B6,F5,1D,61,BF,1F,B1,23,25,1C,E3,01,40,A9,17,F8,00,00,00,00,B7,32,0F,DA,9B,7C,12,E5,10,36,73,A6,CD,37,8E,DD,00,00,00,00,4F,96,D2,26,35,C2,AF,DC,90,4D,B1,09,02,D4,F4,B5,00,00,00,00,34,FF,1D,6D,F5,CA,4C,B3,C4,37,5A,98,D6,07,B9,A0,80,00,00,00,3C,BC,E6,31,31,07,AB,1B,B8,A6,16,36,55,DF,87,2D,80,00,00,00,49,F2,D4,BE,43,6A,10,1D,74,84,33,CE,5C,5F,DF,8E,80,00,00,00,78,F8,64,EA,EB,B2,03,B5,8A,1A,9E,A7,CA,FE,25,6D,00,00,00,00,11,4D,17,0D,8C,9C,4F,43,8B,C2,77,BA,56,78,66,59,00,00,00,00,0B,2C,51,56,CA,1B,AB,08,55,14,DB,A3,64,39,F2,6E,80,00,00,00,BF,41,6E,41,58,39,87,DC,6F,ED,F2,80,2E,E3,B7,82,00,00,00,00,0E,35,42,04,04,B8,8C,E3,DA,80,53,1E,21,40,A3,3B,80,00,00,00,8A,EC,B5,3A,87,DC,45,A4,71,B8,F7,E1,5B,C0,8E,10,80,00,00,00,C8,42,7D,00,00,5D,C0,C9,D5,AD,F2,B7,2C,0F,C7,47,00,00,00,00,DA,48,23,DB,37,69,D5,7F,50,D2,E2,CC,B8,D0,0D,36,00,00,00,00,00,18,7A,35,75,A8,89,86,71,30,E8,F1,ED,42,27,E4,00,00,00,00,45,0A,C7,50,F4,8D,45,99,FF,5E,79,7E,A1,0A,37,FC,80,00,00,00,95,87,C3,FA,80,8E,AD,39,34,E5,61,46,8B,A9,FD,BA,80,00,00,00,EA,8C,E9,76,EA,4F,3A,B6,5B,3F,A2,74,E7,9D,08,CA,00,00,00,00,9C,3E,F8,40,B9,C0,50,32,D0,94,04,9B,21,A7,26,AC,00,00,00,00,D7,3D,62,07,21,78,22,9B,3C,32,FC,F0,26,D0,4E,21,80,00,00,00,A6,3A,A4,01,DC,DB,F6,43,BA,41,55,44,C9,4C,1F,BA,00,00,00,00,28,E5,9C,BD,31,0A,0E,74,D7,A1,57,5D,31,E5,68,83,00,00,00,00,36,FB,A4,8A,0E,3C,8C,24,92,C4,29,33,91,53,7A,FD,00,00,00,00,21,9D,51,78,C6,0C,1C,B0,18,21,B7,16,8C,B8,7D,E4,80,00,00,00,D2,5C,6F,77,A1,DC,8C,4F,1D,24,53,12,A1,7B,12,75,00,00,00,00,54,5E,D1,78,A5,F1,9A,F2,46,29,3F,83,78,28,ED,D1,00,00,00,00,AC,42,D0,80,6C,EA,74,C2,9B,D1,F9,7E,9C,E8,62,3E,80,00,00,00,01,61,39,CD,4B,BE,C6,00,C9,23,06,56,72,A4,91,EA,00,00,00,00,E8,3D,F9,0E,C2,0F,16,69,06,1C,F0,3A,C3,30,77,D3,80,00,00,00,E3,57,7E,40,F6,45,13,83,26,91,1C,E4,5B,68,06,C6,80,00,00,00,32,9B,2D,4E,2D,CD,A3,16,5F,3E,48,92,14,52,56,80,80,00,00,00,04,20,80,D0,7A,AD,30,BA,ED,1A,70,BE,59,F8,8D,FA,80,00,00,00,26,C5,49,B8,E5,D7,38,94,D5,49,0D,28,3D,CF,C7,07,80,00,00,00,47,CB,B3,06,41,BD,B9,D8,8B,EA,22,47,4B,23,88,C2,80,00,00,00,04,DD,D1,47,03,9E,31,5A,A0,1B,A6,AA,8D,AA,40,9A,00,00,00,00,51,0F,4F,9E,1F,2D,5D,2E,5C,DF,15,43,C3,DB,C5,8D,80,00,00,00,87,9F,A9,A8,50,36,75,48,14,1E,A6,DF,24,66,57,D0,80,00,00,00,6D,7C,E4,D1,63,E5,22,1E,4E,F6,E6,60,BB,7A,6D,DC,80,00,00,00,73,8E,9E,F1,20,71,F6,1B,C7,56,9D,E4,71,B1,7B,E5,80,00,00,00,AB,12,62,88,01,4D,28,3F,E2,45,50,BD,42,7A,3F,0B,00,00,00,00,E5,22,DF,42,C4,C2,4B,30,E9,ED,EE,73,EA,E7,B2,E1,00,00,00,00,1A,DA,EE,ED,52,76,18,40,28,35,E8,67,1C,28,05,93,80,00,00,00,A2,F0,3C,52,30,E6,89,E5,55,25,84,D9,EB,17,E4,BA,80,00,00,00,EA,0D,16,3C,50,5A,32,93,CB,35,46,25,20,6D,53,C3,80,00,00,00,A2,4A,C1,B6,D3,25,A7,F7,C6,A5,FD,0F,CE,5A,1F,FD,00,00,00,00,17,29,CC,32,69,11,BC,47,78,CB,DE,C3,20,BA,B4,78,00,00,00,00,50,B3,81,35,4B,57,EC,F4,AD,AA,72,66,19,0B,57,E7,80,00,00,00,35,1E,E8,D7,C7,C4,11,64,4E,E1,E7,8F,F3,BB,04,88,80,00,00,00,F0,93,28,25,54,23,E1,D3,40,40,E8,FB,AD,0D,E1,2C,00,00,00,00,7D,FE,61,D9,AA,A1,47,29,53,1E,8D,C2,B0,3B,69,13,00,00,00,00,D9,05,7C,F8,5A,56,F1,C9,7A,21,DE,94,BD,AA,23,4E,80,00,00,00,B5,00,1A,A9,C1,95,77,AF,0E,35,A1,72,0D,90,73,2D,00,00,00,00,3B,60,0B,7B,DC,30,77,11,50,13,E7,16,24,FB,0A,C4,80,00,00,00,E6,FE,B1,DC,56,91,2C,86,0C,DB,51,B7,8B,C6,F5,20,00,00,00,00,C3,94,1C,80,AC,7A,C7,68,8C,A9,97,7E,57,0E,F5,3B,80,00,00,00,DF,A9,70,A5,C4,AF,9D,B4,0D,E8,E7,65,7B,F4,27,89,80,00,00,00,5F,FD,41,19,A6,52,87,73,0F,CC,5B,B1,E2,DD,6D,89,80,00,00,00,77,C0,AA,96,9C,7E,4A,6C,17,22,FF,C7,F9,ED,A1,42,80,00,00,00,2F,04,A5,AE,1E,71,A5,84,82,D1,63,32,46,FA,4D,02,80,00,00,00,99,60,74,0F,22,C1,17,97,51,DA,22,A1,0D,B0,06,E0,00,00,00,00,FC,A6,7E,F7,89,71,7C,7A,37,77,21,E4,E4,45,E6,97,00,00,00,00,20,1E,6D,1F,05,30,23,F3,FA,D2,3B,11,F8,03,08,DD,00,00,00,00,40,B4,73,E3,C9,5A,81,07,C9,BE,9C,CF,4F,55,55,E3,00,00,00,00,05,2C,0B,45,59,7F,8A,0B,9E,F2,E1,A7,95,5B,4B,1A,80,00,00,00,EF,A0,C2,1E,AB,90,3B,8A,26,11,7A,6F,A2,46,3D,70,80,00,00,00,9B,94,52,EC,E7,E1,8A,0E,77,60,F1,DB,B4,13,E7,D5,00,00,00,00,1E,80,63,C9,31,5E,83,5A,11,18,ED,4C,F6,28,3F,AF,00,00,00,00,D0,C1,A9,C5,86,05,02,A3,B4,7C,7F,C4,32,28,9E,8D,80,00,00,00,A3,40,D9,35,20,8D,1D,27,25,CF,F6,7F,60,CA,5A,76,80,00,00,00,6D,F9,AD,63,9A,FE,B0,F3,DD,B2,7E,21,39,41,BF,C5,80,00,00,00,80,D4,DF,F9,C2,3E,0E,52,8C,0D,69,44,D4,6D,9E,A2,80,00,00,00,8B,F9,16,91,9B,C4,3C,5B,C7,36,C6,7B,89,0F,FD,E2,80,00,00,00,0E,1E,37,F5,75,A3,80,A6,B0,FB,3D,8C,9B,99,26,9D,00,00,00,00,DF,67,99,01,AA,CE,B2,A4,BB,73,9F,02,96,17,A8,D5,80,00,00,00,45,A9,29,BC,7E,40,ED,81,8F,F3,BB,7D,30,0C,EC,2F,00,00,00,00,E0,33,28,36,55,16,DD,58,FB,42,29,16,F5,EC,B2,9E,80,00,00,00,54,61,EF,DD,D7,3E,6B,31,68,7B,CC,CA,C5,7D,E8,6D,80,00,00,00,5A,A1,77,66,AE,2F,BD,97,5F,A0,A8,4D,AA,25,05,82,80,00,00,00,7A,EC,1D,71,F0,9B,55,C4,9F,67,DC,5A,D9,D0,E1,93,80,00,00,00,36,46,BC,BF,38,5A,2F,13,5C,16,7E,D2,25,58,61,AF,80,00,00,00,45,1C,EB,1A,2A,B1,88,0E,76,BD,88,9E,79,55,F6,AE,00,00,00,00,DF,13,E7,94,AA,DF,41,0C,8B,67,43,12,58,86,B0,A6,80,00,00,00,98,F1,66,9A,4E,B5,B0,2E,FE,4C,63,45,A0,BF,08,24,80,00,00,00,56,4F,51,7C,F9,ED,E0,1D,D0,DB,3A,13,C1,1E,EC,81,00,00,00,00,99,AB,8F,DA,3B,2F,38,21,43,99,BA,9F,C2,EE,C1,68,00,00,00,00,90,70,C8,02,9F,4B,18,A6,13,5F,D5,F6,D6,75,47,07,80,00,00,00,6A,66,1B,90,A5,57,82,DE,1C,0C,E1,6B,D7,4B,78,DC,80,00,00,00,F8,39,EA,77,42,7D,FF,A6,BE,CE,D6,01,FA,8C,EA,74,80,00,00,00,4E,B6,1E,7F,F4,9E,83,2E,6D,D1,B5,CD,B9,79,48,85,00,00,00,00,8F,D8,0D,5B,9D,12,44,A8,6D,5A,76,0C,05,A2,F2,76,00,00,00,00,D3,AB,61,6C,E0,76,0F,A8,21,13,41,4F,1A,E7,DF,0B,00,00,00,00,9F,DA,15,03,05,AC,7A,CF,6E,A4,89,18,35,4D,97,1E,00,00,00,00,37,A5,EB,B5,81,BA,2C,BD,D9,41,7A,77,FE,A7,E7,99,00,00,00,00,63,47,59,53,A2,48,81,62,8D,4F,7A,20,AE,CD,24,C3,00,00,00,00,B7,3B,88,86,0A,B8,54,41,F3,43,4F,1B,60,84,41,18,80,00,00,00,DD,FB,7F,D0,39,DC,68,70,3F,BE,F3,E7,EA,E5,0C,85,00,00,00,00,E2,96,A3,D3,56,DE,6C,8A,E5,8C,67,78,4E,6F,D5,9B,80,00,00,00,23,87,AA,F0,9D,63,FF,B8,B8,02,7F,19,E5,F1,5A,3C,80,00,00,00,85,AC,43,2C,B9,B6,5F,6A,A0,82,FC,D0,EB,B4,C1,9D,00,00,00,00,3A,97,E0,FF,0B,AD,F4,A5,A7,33,30,B4,80,28,3F,D2,80,00,00,00,05,50,84,5C,F4,C0,F5,51,E1,0B,C4,20,DB,2F,FE,3B,00,00,00,00,46,C5,38,1F,44,5B,89,67,3C,C1,AB,AA,4D,F7,84,98,00,00,00,00,6B,45,32,CD,27,7E,BB,ED,77,A0,1A,F1,37,B8,AD,DD,80,00,00,00,33,21,03,F7,40,1F,5D,C6,D8,7B,1C,CE,4C,32,05,F6,00,00,00,00,85,9A,46,6E,8C,A7,70,98,45,34,40,9D,7A,C7,56,9C,00,00,00,00,79,61,A1,C5,00,01,FC,50,71,9A,E2,E6,11,91,B4,D2,00,00,00,00,26,5E,A0,4B,F6,18,2F,CB,FF,BE,D6,C3,16,B8,81,4A,00,00,00,00,F0,A7,E5,A6,07,74,44,EC,7F,26,72,F1,DE,78,E6,12,80,00,00,00,04,FF,25,7E,5A,51,13,36,05,56,95,67,EF,96,2F,1D,80,00,00,00,54,A1,FE,2A,0E,0E,69,1F,51,1B,7A,CA,E3,A0,EC,12,80,00,00,00,F3,66,0E,42,F6,85,E7,97,C4,44,1F,A5,A6,45,3B,59,80,00,00,00,88,93,6B,F9,63,36,D3,E8,57,3C,92,37,DE,FD,BF,D0,00,00,00,00,1A,E8,7C,7B,2D,F2,DD,3A,10,63,D0,3F,7E,CE,33,A9,00,00,00,00,7F,F9,E1,5B,A4,0D,1B,BD,D9,8C,88,FB,13,50,21,97,80,00,00,00,96,9D,3C,DF,45,A5,E8,FD,E2,03,B1,41,0F,AD,47,11,80,00,00,00,67,A6,99,9C,C7,89,33,AB,EC,BA,9B,4E,36,74,F8,BE,00,00,00,00,3A,7E,05,B1,48,A1,B7,1A,90,03,61,9F,4F,87,49,89,00,00,00,00,DD,81,CB,64,C8,50,AA,FA,43,DE,69,A1,EC,5D,A2,1D,80,00,00,00,5B,11,5D,AA,36,89,44,48,FF,AC,9D,AC,02,0F,44,99,00,00,00,00,B5,61,4B,97,EC,DE,B9,6B,59,BE,40,06,3E,2B,22,76,80,00,00,00,F3,AE,34,C6,95,9F,45,53,9F,1C,18,59,93,24,26,E5,80,00,00,00,0C,F9,82,B9,14,88,12,D7,3F,F4,33,77,11,58,45,00,00,00,00,00,32,BE,B6,E4,31,E9,A7,4C,EF,47,75,C5,DE,39,24,C1,80,00,00,00,32,12,06,59,1C,DE,5F,DB,41,8A,13,0B,92,E9,8F,66,00,00,00,00,EF,6D,52,A0,55,5E,26,15,C3,A1,EF,FF,58,F8,B0,C3,00,00,00,00,6D,C5,52,23,43,1F,D1,DE,A6,F8,D6,DB,24,1B,90,A0,00,00,00,00,FA,D1,5A,30,6A,9A,55,CA,71,32,DF,23,7C,47,BE,E8,00,00,00,00,98,1C,51,D9,2B,0A,2D,F2,EE,A8,3A,1C,4D,1F,D8,F0,80,00,00,00,65,09,67,DD,56,4F,FD,F8,52,F1,37,AA,90,9B,72,C5,00,00,00,00,74,AB,6D,BA,B4,5C,0D,ED,25,3A,1B,9F,C7,61,B3,98,80,00,00,00,1E,E1,55,A2,EB,B2,68,BE,98,DC,75,93,E3,3A,5D,18,00,00,00,00,E8,B5,DB,40,58,53,9C,BD,2E,93,F2,5E,CF,2B,FC,17,00,00,00,00,C7,4F,4C,CD,AF,03,62,3F,96,8E,DE,99,D7,1A,A7,D9,00,00,00,00,1F,0E,FB,4E,D6,A3,63,74,C2,C8,36,E4,7A,63,B3,A2,00,00,00,00,3A,4F,40,60,14,A7,4B,7A,F8,A5,92,9F,C3,B9,E8,7A,00,00,00,00,C0,F8,83,A5,CD,04,DA,AA,96,55,E0,DE,C9,2A,8D,97,00,00,00,00,36,07,75,83,3E,FD,36,21,6F,68,32,F6,B4,38,A5,85,80,00,00,00,47,A5,86,36,1D,7D,A0,D1,2A,2C,A8,A1,A3,B5,C9,43,80,00,00,00,45,7A,CB,2B,62,16,A5,44,97,43,84,A0,63,5A,7D,C3,00,00,00,00,75,3E,84,1E,D4,BB,E6,88,7D,AC,6B,11,18,3D,67,DF,00,00,00,00,60,65,BF,32,29,E2,61,69,00,68,65,D2,A9,68,2B,1B,00,00,00,00,8A,19,19,92,7F,19,6C,3E,32,2B,CE,3B,6A,F0,5C,E1,00,00,00,00,CE,79,41,ED,94,29,C7,88,34,F8,17,6A,01,F5,DC,F0,00,00,00,00,A7,EE,85,1E,B2,03,56,01,65,F2,4D,30,C4,3F,F7,A0,80,00,00,00,B7,40,2D,84,95,C9,B9,4B,7D,58,04,3F,57,2D,1D,D0,80,00,00,00,D4,93,26,C2,F6,47,77,94,EE,52,99,F8,6C,90,94,F0,80,00,00,00,FE,6B,4C,1E,2D,BB,69,B2,82,8D,26,A2,98,23,78,D7,80,00,00,00,32,79,84,D3,37,60,06,EF,61,07,ED,61,8E,C5,6B,3E,00,00,00,00,7C,C2,B3,93,62,61,8A,9F,FD,CA,B4,43,CE,1B,6D,BC,80,00,00,00,6B,85,E1,59,D8,D4,20,76,2B,29,1A,8D,A5,7F,27,A7,80,00,00,00,EB,95,04,67,29,50,B4,77,E3,20,B0,D3,E9,50,8F,53,80,00,00,00,7E,02,0A,0F,9C,F4,EB,C3,1A,D4,EE,66,84,2F,63,14,80,00,00,00,D6,26,91,BF,99,67,D9,7B,C2,67,16,BD,24,62,DB,3B,80,00,00,00,46,11,59,11,00,9A,FF,70,6C,BC,7D,64,3D,B0,4D,DF,00,00,00,00,36,65,AC,31,7E,15,6D,84,2D,3A,D0,A1,72,F3,61,DA,80,00,00,00,24,8D,CD,59,E2,48,7B,47,00,26,BE,26,B8,6B,65,6B,80,00,00,00,A2,85,65,C1,42,4A,9E,F2,DB,55,7A,CF,7E,A8,DD,7E,80,00,00,00,29,E0,04,FD,55,90,29,D0,03,D6,EF,40,E7,55,F9,1E,80,00,00,00,E4,0F,86,AC,20,F6,37,81,9A,81,EE,0D,33,07,4C,8A,00,00,00,00,FD,88,39,78,5C,85,A8,BA,8D,8D,BF,DF,C7,75,2F,27,00,00,00,00,13,10,62,F4,20,52,B8,84,84,9A,32,73,00,F8,51,63,00,00,00,00,C3,D7,D2,46,62,36,49,86,65,B3,8A,87,4A,90,D5,0E,00,00,00,00,5B,80,D0,C1,53,10,61,ED,60,B9,ED,18,DA,DA,4A,28,80,00,00,00,8A,B9,74,3A,A2,16,17,93,B7,CB,96,6B,CB,2A,6C,76,80,00,00,00,5C,00,BA,8B,1E,05,2F,03,44,39,B3,5C,D5,F0,B7,C8,80,00,00,00,28,BC,0A,77,77,41,40,E8,6E,B5,4C,D0,FE,8B,2E,9C,80,00,00,00,DD,37,7A,43,7E,93,99,C5,C9,C2,C6,72,10,E8,E8,C9,00,00,00,00,E2,98,48,3C,21,E4,E8,36,29,85,86,DD,71,B0,CB,04,00,00,00,00,BC,48,39,99,E2,04,BF,88,9F,C8,24,E9,0D,2F,73,A9,80,00,00,00,AC,F3,1F,F1,DB,86,28,82,52,E8,63,EC,DF,31,95,D1,00,00,00,00,A8,6D,A9,5F,AA,F0,6A,76,F7,76,8F,51,A0,7E,CD,B1,00,00,00,00,50,BE,16,55,53,25,AA,D1,BC,A3,60,0A,CA,3E,F7,9B,00,00,00,00,4E,5C,B9,72,D9,1A,9D,74,63,29,CB,39,C7,6B,07,65,00,00,00,00,2B,C8,FE,D8,E8,79,CC,33,76,4F,63,E7,FC,07,C8,7B,00,00,00,00,37,6D,1C,3E,43,6C,7F,7C,88,AA,AC,F0,2D,B4,43,70,80,00,00,00,CE,70,74,70,BF,C0,CF,22,AB,99,9B,24,CB,E3,C4,B8,80,00,00,00,8E,86,25,84,47,43,EB,49,F6,F0,E0,83,BA,B5,AF,F6,00,00,00,00,02,02,F3,A2,5C,05,2E,EE,38,2F,9B,D2,48,D7,BA,DD,80,00,00,00,91,61,46,BA,71,C7,6B,14,2D,DD,41,D5,72,6E,B8,3B,00,00,00,00,AD,7A,E0,9B,71,BB,14,B8,C4,F1,49,03,4C,EA,56,A6,00,00,00,00,12,A8,2F,B3,EB,D6,6A,5E,6D,96,EC,F4,F3,F7,04,4C,00,00,00,00,85,D2,51,51,04,E0,D4,B6,73,56,68,E2,68,AA,A1,31,80,00,00,00,BD,DC,AE,B1,68,68,2A,58,6E,4E,51,AF,11,68,80,1A,80,00,00,00,B4,3F,06,E2,AC,3F,60,F7,D2,74,19,4C,DF,F0,51,3F,80,00,00,00,E9,54,8D,4E,0A,B8,20,9C,03,D1,74,C3,2B,10,E1,93,00,00,00,00,0C,F5,31,C2,03,DE,3D,5F,46,5C,E2,29,79,11,06,F1,80,00,00,00,A5,A8,BB,60,DD,46,64,6E,F2,7C,71,94,0F,B0,CE,89,80,00,00,00,85,9E,39,BE,47,AC,9E,9F,86,2E,39,82,B7,43,3B,CE,80,00,00,00,15,14,4C,CB,D0,07,D8,0A,08,D1,8B,71,E7,83,49,67,80,00,00,00,AD,E6,E4,19,F1,36,2C,94,09,37,C9,4E,8A,15,9D,09,80,00,00,00,83,1B,A1,04,58,F5,16,ED,FA,9B,88,A1,BC,A9,65,30,00,00,00,00,C5,34,CA,64,9B,78,87,26,B9,9A,71,ED,C5,9F,22,89,00,00,00,00,29,5C,EC,B0,62,F0,61,3D,68,DE,43,23,C3,30,C2,9D,80,00,00,00,76,3F,A3,76,98,CC,A0,91,77,C9,24,BD,10,06,B4,B7,00,00,00,00,28,5C,98,0C,23,15,B5,01,05,36,A1,D2,57,58,7E,53,80,00,00,00,EF,E3,F8,ED,10,F3,72,C0,38,2E,47,A4,D8,44,08,4B,80,00,00,00,77,57,F2,5B,91,CE,55,D3,26,01,49,A9,AC,B6,38,91,80,00,00,00,13,0F,1A,E5,15,0E,0D,DF,EC,A7,4B,5F,97,9D,30,7C,00,00,00,00,AC,6A,43,CF,5E,85,A9,78,E2,E2,A6,AE,D3,29,68,A5,80,00,00,00,CF,AD,84,E8,47,DF,3C,02,17,83,98,5B,54,2C,76,35,80,00,00,00,85,08,9C,D7,B7,E4,8C,47,84,4C,42,BA,B2,7E,D8,1E,80,00,00,00,3E,6D,53,9C,9E,E8,82,B0,4B,F0,9C,CE,03,9E,1D,97,80,00,00,00,BD,9E,5E,0B,8E,6F,24,88,84,DE,3B,AD,CF,8B,35,B8,80,00,00,00,7D,D1,A5,89,A5,B7,A5,F6,69,82,48,C7,F9,AA,09,C9,80,00,00,00,97,E2,34,A5,3C,25,0E,A0,05,D1,86,1D,6F,C1,D0,DE,80,00,00,00,A9,BD,78,22,B5,E2,77,2A,C1,12,27,3D,E1,FD,80,B3,00,00,00,00,12,A5,08,99,AB,65,72,0B,80,A7,49,65,5A,9A,9F,28,80,00,00,00,72,44,4A,0D,E8,68,5A,C5,B6,D6,2D,06,14,4D,59,F9,00,00,00,00,B7,C9,5B,47,45,57,27,06,8D,5C,47,21,2B,5A,E5,00,80,00,00,00,90,17,E4,62,57,21,63,3C,DE,24,19,FF,34,F4,54,5B,80,00,00,00,14,7F,F0,EF,20,E2,86,B9,88,E5,8C,CA,6E,A0,A4,AD,00,00,00,00,EF,E4,A0,0D,1B,33,67,3A,3D,51,19,6A,4A,33,32,00,00,00,00,00,7F,5D,7A,E2,D0,47,38,C8,71,E6,1E,21,7C,78,41,CD,00,00,00,00,F3,7E,C4,46,C2,23,75,1B,97,18,04,97,78,66,CC,FD,80,00,00,00,65,AB,35,DF,23,D3,A1,78,6C,31,44,C0,5C,DA,29,BB,00,00,00,00,1C,8D,2F,91,88,C6,A0,39,77,E5,0B,37,F8,6F,0C,EA,00,00,00,00,A4,41,E7,C0,7A,DE,EF,43,4E,DB,40,FC,A8,81,8C,7F,00,00,00,00,8A,CE,1E,F0,95,9F,E4,FA,11,7E,5F,77,07,38,D5,60,80,00,00,00,60,32,53,25,19,17,EB,BA,2C,CC,5B,21,C1,D9,36,45,00,00,00,00,19,AF,66,AD,0C,4A,02,80,B1,3A,FA,85,6A,FC,CD,76,00,00,00,00,00,C6,92,F9,54,C0,42,F8,C9,52,08,04,CF,37,89,23,00,00,00,00,F8,00,34,F5,0E,F8,78,32,F2,5C,C6,FC,F1,DF,F0,AE,80,00,00,00,41,9F,5F,64,D7,4F,13,A3,C1,04,6C,39,7A,9A,10,A5,80,00,00,00,6A,3E,68,D9,45,C8,67,72,6C,E5,14,9D,4E,5C,FC,FF,00,00,00,00,28,CA,AD,CC,3C,29,2A,64,21,AA,DC,E7,40,BE,27,84,80,00,00,00,3E,52,CC,AD,21,46,23,C6,E2,D6,82,C7,8F,2F,1C,D4,00,00,00,00,16,DF,A9,0D,58,E3,51,1A,3B,4C,56,F9,35,9B,D6,49,80,00,00,00,43,5C,C6,61,9E,C9,59,9A,BD,05,64,ED,A0,67,ED,A6,00,00,00,00,F1,D3,4D,09,69,FC,30,B6,88,A8,B3,79,D0,1C,50,4B,80,00,00,00,DB,54,C7,02,C4,69,61,2C,E5,ED,01,9E,78,0F,02,F6,00,00,00,00,23,8A,30,F7,73,A5,F5,37,01,3C,1D,63,B2,17,60,4F,80,00,00,00,35,67,9D,99,21,22,36,25,D4,07,62,8A,07,75,57,C9,80,00,00,00,2C,DC,82,AF,37,D9,3D,F5,20,D4,CA,DD,3A,BB,26,23,80,00,00,00,56,41,A9,6D,06,26,D8,FE,30,D9,28,C9,AC,2B,00,DE,80,00,00,00,C5,81,05,B9,23,D7,2F,02,CB,D0,4E,6F,91,CA,68,00,00,00,00,00 -keyMatrices_full = 3A,06,7B,7E,48,91,89,44,C9,72,85,82,22,D4,78,19,00,00,00,00,C1,91,86,B1,6C,4B,84,02,11,06,FF,1C,23,A6,4E,33,80,00,00,00,32,33,DB,ED,68,18,2E,FF,DD,7D,00,7B,43,CE,1E,6F,00,00,00,00,F1,28,7F,38,54,E7,46,35,A0,3F,94,0A,E2,FB,1C,4A,80,00,00,00,E8,98,8B,E9,B5,B5,07,3B,F8,AF,7D,E1,99,06,1E,64,80,00,00,00,84,1B,D0,BD,52,99,B9,B6,F0,35,03,5A,29,0F,BD,58,80,00,00,00,E7,DE,23,88,D1,6D,4E,C5,9C,26,2A,C1,F6,FD,75,27,80,00,00,00,E4,3D,8B,8F,D0,A3,FF,E7,F0,9E,74,AE,9F,3B,13,93,80,00,00,00,E7,A1,C8,F2,77,27,01,20,CF,CC,85,1D,84,3B,F2,62,80,00,00,00,B4,0A,60,C6,12,7E,E6,AE,99,EB,69,B3,AE,79,E4,2C,00,00,00,00,4A,D1,EA,F2,22,EB,B6,53,0D,92,C1,7C,EA,C7,B2,EA,80,00,00,00,F2,E7,4F,40,8E,63,D8,96,1E,6F,E4,66,C4,FC,A4,CE,80,00,00,00,27,C2,B0,0D,43,70,68,A6,B5,8B,25,15,35,23,93,6D,00,00,00,00,FA,7E,6B,54,34,A9,4E,F9,94,21,A1,AA,99,8F,E8,36,00,00,00,00,90,01,D3,DF,8B,B1,4F,A7,56,B9,93,2D,5E,95,AD,7A,00,00,00,00,51,AD,0E,FB,0E,A5,82,C8,CA,13,CB,83,15,27,24,68,00,00,00,00,E5,2C,7E,EF,14,B6,08,D5,62,55,FE,93,22,7D,B2,3B,00,00,00,00,11,CA,7D,90,43,19,95,66,85,F8,A7,73,03,F8,59,72,00,00,00,00,08,31,77,E1,46,0C,28,81,C8,9D,F5,FB,09,8D,99,79,80,00,00,00,93,45,61,93,80,C0,91,95,DC,7E,26,B6,8F,0A,04,10,00,00,00,00,C2,EA,1F,43,A3,54,80,65,BD,B7,30,FC,EE,A0,13,DC,80,00,00,00,FB,48,6F,39,D4,CA,2B,35,AD,41,0A,AC,96,1B,31,1B,80,00,00,00,2D,18,35,B9,46,F0,CF,2B,08,3C,E7,79,42,BB,B1,7A,00,00,00,00,22,E8,B8,78,18,ED,1F,16,C6,2D,EF,2D,DD,57,1D,7A,80,00,00,00,9F,C7,E9,DE,23,25,55,FE,C3,4E,21,C4,38,63,CB,88,00,00,00,00,CC,53,5C,F0,FE,80,F9,3B,61,EE,45,95,FC,61,A8,FC,80,00,00,00,08,91,31,D5,AB,C8,A9,52,C3,38,69,D4,08,16,27,80,00,00,00,00,39,6A,39,E8,45,99,1E,E1,C5,0D,42,3E,44,36,8E,F9,80,00,00,00,90,57,E2,4E,ED,2E,3F,FD,25,D9,4E,11,71,8A,DF,41,80,00,00,00,4E,E4,14,51,34,FA,8D,A6,E6,B4,48,C7,54,67,F4,0A,00,00,00,00,D0,0E,19,68,27,98,E9,A8,EC,6B,67,CF,3E,84,8D,39,00,00,00,00,BD,E8,DA,5D,32,51,71,93,D7,55,EC,E5,5C,3B,82,CD,80,00,00,00,C0,5F,6C,55,AD,48,54,DD,E7,E9,3D,29,54,B2,06,66,00,00,00,00,C8,16,23,82,D6,15,C2,B0,CD,C1,CA,E1,14,BA,C8,71,80,00,00,00,59,D3,5D,F0,6D,B0,87,B2,16,F8,04,98,03,ED,99,C5,00,00,00,00,BB,11,06,9C,BF,F8,C1,76,12,57,31,C3,8F,49,7A,22,80,00,00,00,2E,ED,44,B7,23,C9,71,63,61,9D,56,BA,34,70,0F,46,00,00,00,00,5E,57,6A,7D,8B,B9,E6,07,55,B9,46,01,10,71,24,A7,00,00,00,00,95,88,32,26,5D,A8,83,BC,B3,93,49,4A,4E,BC,19,BD,00,00,00,00,0C,9C,C8,B2,F2,48,18,E5,71,0A,76,D8,A9,77,33,4E,80,00,00,00,B6,2E,31,0A,35,D4,ED,5C,1E,AD,20,AD,76,20,7A,9D,80,00,00,00,0B,0A,50,F8,F6,A5,84,A9,95,82,CE,7A,F4,C7,64,0C,00,00,00,00,85,B1,58,7F,0D,D1,BD,7A,15,9C,F4,2A,49,00,DA,13,80,00,00,00,B5,41,2D,D5,DC,2C,0B,F7,3F,03,6C,05,20,25,27,F5,00,00,00,00,28,1C,1E,4D,4C,C4,65,B4,F9,9E,AD,0B,57,C9,0C,93,80,00,00,00,37,14,4E,BA,9A,F3,D3,C4,2E,59,2E,CA,52,87,E1,20,80,00,00,00,E2,77,95,EA,CE,D5,8F,A9,49,36,97,7E,2A,AF,A1,2C,80,00,00,00,DA,82,EE,A2,F4,4D,04,2C,F5,60,F0,FF,6F,7B,2A,55,80,00,00,00,02,FE,96,10,9A,2F,0F,11,0D,B1,48,A7,B3,E2,2F,C3,00,00,00,00,5C,AF,BA,4C,A5,AA,62,76,09,E3,32,15,F5,45,D9,70,80,00,00,00,AB,D8,10,E2,04,FD,9A,A5,8E,31,97,8B,B4,41,5E,5C,00,00,00,00,30,2F,C4,5D,03,1F,50,CB,E0,73,4F,A1,74,EC,5F,76,80,00,00,00,20,2D,E2,01,55,9E,2F,54,90,50,B0,5B,B2,B4,41,F2,00,00,00,00,02,B2,D8,66,7B,F7,1F,EE,2E,F4,C1,BE,9F,F9,57,1D,00,00,00,00,F0,96,B5,63,BF,C6,56,26,94,15,DB,36,17,71,BA,BA,80,00,00,00,48,7C,DE,E8,E5,E9,81,FD,4B,6C,0B,7E,55,0E,94,D8,80,00,00,00,EF,95,AD,D6,D3,97,39,21,EA,51,A2,5F,4D,29,E2,E2,80,00,00,00,B3,54,D2,48,00,A4,50,DB,C6,FD,5E,B2,E6,76,B2,D3,80,00,00,00,CC,EB,A1,C0,04,D4,8A,23,58,92,78,37,17,82,96,7B,00,00,00,00,F2,C9,51,4D,FA,92,F6,2E,38,AB,D2,C0,28,A5,7D,D5,00,00,00,00,DB,80,61,B7,EC,20,55,4D,1C,91,2C,AC,2F,2E,30,EE,00,00,00,00,5B,7F,D4,BA,18,94,88,AB,B9,A6,A7,62,09,57,48,6D,00,00,00,00,E8,57,0E,1A,2B,AC,23,D6,E4,77,A1,90,BC,24,04,C1,00,00,00,00,93,A4,9E,0C,2B,24,77,8C,DB,53,8D,D1,5F,5A,47,EB,80,00,00,00,73,CA,57,60,52,1C,39,B9,6C,7A,0F,EC,A7,44,31,67,00,00,00,00,54,27,72,2B,A4,50,82,5A,5D,A8,AB,EB,DE,3B,A7,62,80,00,00,00,CE,D7,D4,C6,72,65,6A,0F,F4,46,08,4B,B2,68,30,E3,80,00,00,00,D2,F3,72,81,B1,27,C9,E1,BF,05,AA,1A,F8,BB,A6,5B,00,00,00,00,96,C5,85,B8,B0,CA,CD,FD,01,6D,48,8E,06,A0,4D,4A,00,00,00,00,6E,75,FD,70,3C,F5,A4,A9,0E,53,53,ED,57,92,A8,21,80,00,00,00,7E,26,03,60,79,1F,74,B5,CF,45,6C,53,AA,B9,2F,E4,00,00,00,00,57,FD,3C,44,25,3E,AF,3D,59,37,1D,80,FF,88,17,C5,80,00,00,00,68,74,80,54,FA,69,C8,6D,FF,D3,E9,81,8F,2A,88,72,80,00,00,00,63,65,57,B9,7E,55,2B,90,3B,2F,C4,B7,E0,8B,14,8A,00,00,00,00,D5,F6,FC,CA,3D,C4,CF,2A,AE,10,D2,7D,C4,4A,04,B3,00,00,00,00,5E,BB,BD,CF,A8,B0,EA,32,A7,FF,35,A1,D9,D8,28,43,00,00,00,00,3F,E9,AD,35,1C,77,5E,08,B0,A3,03,EF,DF,7A,B0,26,00,00,00,00,CE,78,04,66,24,96,33,87,09,B3,A0,D3,25,BD,25,E3,80,00,00,00,5F,D5,54,19,8B,5F,DD,BC,16,FC,8A,4E,0C,CC,A1,87,00,00,00,00,4B,52,91,9D,5D,C8,15,2F,91,79,85,4A,25,54,E4,66,80,00,00,00,B7,4A,A1,75,16,16,49,EA,D6,9F,AF,B1,01,20,3E,25,00,00,00,00,8A,25,8F,07,67,F3,55,31,61,7E,D9,0D,9C,0E,8B,3D,00,00,00,00,45,14,0E,6E,A5,C6,63,DD,86,2A,A7,A9,E7,6D,9B,BC,00,00,00,00,BB,9E,AF,26,F9,8A,7F,40,16,AA,30,DF,27,FD,55,D8,80,00,00,00,94,49,3A,E2,C7,71,6D,74,82,5A,82,34,11,3E,DF,78,00,00,00,00,7B,78,60,6D,70,59,A2,17,F6,42,28,4C,0B,77,00,52,00,00,00,00,20,C7,F7,88,34,D6,C5,91,5B,03,93,CB,EA,F2,14,BC,80,00,00,00,CD,2B,DD,99,99,0F,FE,73,5A,80,D7,DF,9F,8B,E1,AB,80,00,00,00,83,28,EC,F4,AF,D1,F8,DC,59,27,FB,03,C0,18,EF,06,00,00,00,00,C5,82,72,5B,EA,8A,CD,DE,05,FA,D1,B1,26,5C,C1,49,80,00,00,00,98,E3,B0,3C,37,B5,31,0A,16,6B,8C,9F,C4,C2,B5,C8,80,00,00,00,BF,95,62,71,02,FF,A7,2A,6E,2A,06,6F,DF,E8,FC,87,00,00,00,00,F9,B3,09,2F,0A,F4,C4,C8,AB,35,09,30,47,30,DD,A3,00,00,00,00,A5,7D,47,71,B9,61,45,53,88,9B,D7,92,F8,D6,24,BB,80,00,00,00,61,37,4B,9C,D7,D2,7D,8A,2D,CA,7E,84,8B,4F,F8,6F,00,00,00,00,0D,8D,FF,3F,3F,6E,20,72,40,4F,9B,2C,35,36,D6,45,80,00,00,00,8D,C4,FD,6B,73,42,2E,74,F2,F2,59,AC,EF,46,B1,94,00,00,00,00,F1,F3,97,0A,C4,77,8C,71,BE,03,B7,AF,72,AF,7A,BB,00,00,00,00,47,6A,E9,62,94,FB,F4,47,77,23,CA,68,56,B7,50,69,00,00,00,00,8D,C5,97,71,FE,78,0D,FC,79,58,00,AC,AB,F4,A0,84,00,00,00,00,41,0E,00,C4,BA,1A,C2,49,79,F1,82,93,6B,59,F8,C3,00,00,00,00,44,07,04,B8,5B,FD,A5,C0,ED,CB,1E,47,9C,E5,70,A2,00,00,00,00,0A,D0,DC,A9,8B,0A,59,4B,DE,29,45,F2,B8,33,95,EB,00,00,00,00,5E,DB,0B,C6,04,33,72,6C,A8,AD,0C,BD,12,91,10,E7,80,00,00,00,37,A8,DD,C8,96,00,08,3A,CD,04,9E,28,26,0C,CE,EE,00,00,00,00,E5,C2,B1,F7,24,B1,0C,11,68,BF,6A,08,CA,9A,62,26,80,00,00,00,B6,04,53,00,BB,A8,12,96,0E,28,83,9D,DE,97,58,69,80,00,00,00,1C,CE,F5,F0,87,E6,9C,CE,D6,18,08,11,C1,86,01,E5,00,00,00,00,F1,7D,CD,21,31,76,99,DA,8A,4F,20,43,62,BB,3B,C2,80,00,00,00,00,C5,6D,52,79,39,58,FC,FB,E2,5D,63,F6,F1,02,47,00,00,00,00,79,F7,81,2D,BA,A9,9B,05,E6,21,9F,D3,E1,E4,80,E9,00,00,00,00,4D,BD,E9,26,A0,AC,21,DE,1C,98,95,41,CD,9F,14,0B,80,00,00,00,98,19,40,83,79,17,5D,9B,97,C4,D4,BB,34,F8,25,5E,00,00,00,00,DF,99,9D,61,EC,24,02,A7,BE,BF,1F,7B,96,AA,A7,3D,80,00,00,00,F2,F5,19,E2,6F,49,FE,C9,A4,B0,2B,3D,F5,BA,5D,5D,00,00,00,00,B8,BB,BD,B8,B9,FD,AC,C2,0C,12,61,F1,91,E1,8D,2A,00,00,00,00,33,CA,D5,16,FE,7D,A6,C4,CF,99,42,E7,65,13,ED,5D,80,00,00,00,1D,76,B2,67,82,84,AE,F8,3A,70,DF,59,BC,81,02,CC,80,00,00,00,A3,FB,08,41,08,85,DE,0A,F9,09,33,57,30,99,1F,34,00,00,00,00,CB,F6,B1,2C,B7,6F,CE,22,3A,3A,0D,5A,F5,F8,51,71,00,00,00,00,34,AD,9E,40,7C,43,86,DC,42,9F,A9,B2,EF,36,12,D3,00,00,00,00,3B,37,A0,69,A8,64,1E,1E,EF,5E,5A,8C,B4,AC,42,4A,00,00,00,00,12,B9,92,0F,CF,BC,61,E0,6A,78,67,B4,A8,E3,AB,39,00,00,00,00,83,F4,8C,C4,D3,EC,07,5F,D9,B6,31,52,2E,2B,AF,D7,00,00,00,00,5C,49,19,86,1A,CD,4B,62,82,5F,11,59,BF,32,F2,89,00,00,00,00,F9,FA,C9,95,F2,B8,B8,11,3D,42,9B,B2,29,12,38,40,80,00,00,00,70,1A,B5,64,22,07,E1,2D,A3,72,5A,14,71,FC,A2,E4,80,00,00,00,35,4E,BB,24,C3,02,A8,8E,3B,ED,D7,2E,BE,8E,4F,CB,80,00,00,00,28,A2,5C,5F,82,78,B8,F4,D8,2A,45,2F,C6,FD,69,EE,00,00,00,00,38,C9,8C,23,2F,9D,25,A9,61,3E,BD,3A,66,62,D3,C2,80,00,00,00,FB,8A,67,44,3F,F5,5E,02,C8,5F,EC,EA,63,0E,D5,9B,80,00,00,00,C0,38,88,39,21,64,10,2B,F7,A4,BF,E3,80,B0,25,61,00,00,00,00,08,55,3F,EF,73,DF,AB,27,CB,CB,FA,15,C5,D2,6A,D1,00,00,00,00,F7,BE,CD,F9,AA,B3,35,5F,BF,BD,30,91,13,77,30,52,80,00,00,00,B1,C9,08,1E,75,33,23,3F,8A,34,FA,1B,A2,34,30,E1,00,00,00,00,55,D0,7A,C9,4E,79,8F,DE,91,A4,F4,36,46,AF,B6,FB,00,00,00,00,4A,A6,80,6E,39,14,D8,88,61,D2,B3,4A,58,BD,8C,B7,80,00,00,00,31,62,FE,8F,21,56,B7,6B,EE,03,75,CB,D3,6A,D4,89,80,00,00,00,08,73,12,F9,A2,FE,5A,41,22,82,AF,0F,D3,DF,70,9D,00,00,00,00,CB,48,7B,F5,9E,C0,14,41,44,28,54,CE,93,B8,E6,8E,00,00,00,00,C6,7B,0F,E1,A4,9D,E4,B0,85,9D,F5,D3,4E,03,1F,08,80,00,00,00,D9,32,9C,AA,A8,4C,39,7B,14,15,D1,E2,15,3F,E6,24,00,00,00,00,DA,64,84,C9,84,5C,82,9E,25,29,98,58,1F,10,26,90,80,00,00,00,D6,BB,60,77,27,C5,73,6E,B5,B0,39,FA,42,38,AC,35,00,00,00,00,F0,77,6C,45,35,D2,FA,95,86,67,32,3C,65,28,E6,78,00,00,00,00,C2,1B,C2,59,4F,7E,D6,BB,9F,69,4D,7D,27,FA,59,00,00,00,00,00,01,2B,B8,99,F6,50,6D,F1,B3,9E,BC,D3,F1,F4,D9,5F,80,00,00,00,8B,2A,AE,F9,54,0B,5C,4D,0F,B8,5D,30,86,B9,E9,97,00,00,00,00,64,51,FD,54,8F,A9,ED,19,B6,F3,4F,93,B4,4D,04,2A,80,00,00,00,A8,20,E7,35,E3,2D,12,4B,39,69,44,75,62,39,D9,AE,80,00,00,00,F8,D5,5D,89,ED,E0,80,6C,75,A4,8F,B4,E5,DA,F6,80,80,00,00,00,C8,29,F2,EB,8A,02,FB,5A,44,F4,0C,7D,3A,50,90,76,80,00,00,00,88,D1,64,8B,7A,F6,4F,28,26,24,21,E9,1F,18,0B,49,00,00,00,00,C3,CE,F5,58,E4,15,CC,B6,D2,83,72,98,81,EC,C2,32,80,00,00,00,02,16,6B,E3,57,6A,73,0B,DF,46,69,98,DF,8A,76,A6,00,00,00,00,15,49,D3,86,81,F7,89,1E,E5,62,91,00,61,DA,88,8E,80,00,00,00,75,AA,2F,1D,17,CB,9B,CB,AA,16,00,2B,C7,FE,B0,7F,80,00,00,00,7E,3F,9C,8C,E5,14,1D,46,E8,4F,D8,CB,0B,D3,3E,EE,80,00,00,00,D2,79,41,8C,A8,C7,52,8E,8D,E8,41,AB,F6,E0,3E,29,80,00,00,00,30,93,41,3A,54,71,AB,03,47,F3,6B,54,3A,52,49,C9,00,00,00,00,ED,05,A6,4C,51,BC,CC,56,F6,63,B3,CC,9D,DB,F3,92,80,00,00,00,F1,E0,7B,A8,D5,D3,4D,9B,D1,FA,04,0E,F1,79,35,ED,80,00,00,00,FE,02,9B,4D,B6,D2,FB,55,2F,BB,DF,E5,A2,B0,91,DD,00,00,00,00,7F,5D,64,CD,83,05,77,97,33,3A,FB,12,D8,60,CF,4D,80,00,00,00,B5,39,4E,54,E2,49,5B,B8,F1,FD,7E,EC,FE,6F,C9,EF,80,00,00,00,F2,9F,FD,CA,FB,CA,29,63,BB,B8,1C,F0,3A,14,68,2A,80,00,00,00,0B,96,1C,66,3B,66,E5,63,21,69,A1,DE,53,82,91,B5,00,00,00,00,D7,5C,91,22,EA,89,F4,D0,76,7D,D1,81,72,75,30,57,80,00,00,00,03,99,B4,8E,08,85,89,F4,4D,B2,43,FE,E8,5B,C4,DF,00,00,00,00,3C,C4,9F,5F,F6,03,7F,7F,F6,1E,CC,DF,67,22,07,BF,00,00,00,00,3B,06,5A,04,77,79,4D,2C,8A,1F,18,47,DD,C0,EE,E1,80,00,00,00,A1,77,A0,3B,0C,73,AF,1D,40,05,B7,AC,66,0D,D4,C6,00,00,00,00,E9,D0,FF,D2,DA,D7,E5,1B,62,90,37,E6,11,97,A5,9B,00,00,00,00,A9,2B,C0,07,80,D7,A2,4C,36,A0,10,4C,31,CB,F9,6C,80,00,00,00,5E,17,C1,4E,D0,11,3C,57,6B,86,EF,7A,CB,F1,E6,A2,80,00,00,00,D8,EE,31,93,20,40,6D,12,61,8A,D5,44,3E,93,7A,CD,00,00,00,00,2A,1F,AD,49,DC,17,8E,E4,DB,EC,3C,AD,F0,10,1D,A8,80,00,00,00,80,CC,22,46,26,6B,52,E8,C6,41,77,90,1E,96,06,3C,80,00,00,00,9F,C9,2F,3E,D8,31,73,5F,B6,47,86,93,2A,52,89,C7,80,00,00,00,69,65,A2,69,E9,35,A9,77,A5,D8,00,33,AD,15,CB,FC,00,00,00,00,0D,F4,3A,BB,CD,DE,73,60,9F,93,00,28,7A,6D,46,E7,80,00,00,00,21,6F,15,66,0B,51,58,34,F8,AD,E1,B8,90,A9,6F,74,80,00,00,00,55,8B,79,55,AB,05,82,DB,80,29,D3,B3,98,7B,EF,30,80,00,00,00,43,E9,7B,2D,B8,43,6D,BF,B3,ED,5F,6F,FE,4C,9C,AD,00,00,00,00,71,42,DC,5C,43,6C,7D,4B,D0,FD,D5,E0,5B,B9,5E,56,80,00,00,00,C1,09,C3,E5,07,E5,68,C9,62,BC,AE,5F,5B,2D,CC,6A,00,00,00,00,5B,18,47,B6,4B,63,1F,40,38,94,18,3D,8D,B1,F0,0B,00,00,00,00,8E,77,AC,FE,E2,FF,0C,CA,83,C0,58,0D,1A,B7,98,73,80,00,00,00,25,0C,1F,A5,44,C6,AC,7C,8A,4B,7B,0D,CD,98,03,49,80,00,00,00,1E,7B,B6,8E,15,D9,12,72,5B,80,7C,85,65,A2,AC,39,00,00,00,00,EA,B5,F2,FA,C9,A1,B8,30,3E,19,BC,D6,D7,E6,59,D0,00,00,00,00,21,75,DB,AA,56,21,A8,9D,55,B8,B7,4F,82,42,7C,F4,00,00,00,00,D6,0E,47,17,DC,90,F2,EE,FF,CF,37,C4,6C,1B,5E,20,00,00,00,00,BE,D9,3E,31,03,2B,60,DE,F2,22,81,0C,A7,4A,0A,B9,80,00,00,00,91,35,53,D9,34,88,4B,E7,1E,0F,E9,6B,65,19,78,5D,80,00,00,00,DE,77,E9,5E,C7,9A,87,6E,B0,01,DB,51,CC,09,95,BE,80,00,00,00,A6,74,D5,B8,47,B1,39,CA,B3,84,A2,02,51,EB,84,9F,80,00,00,00,6B,A0,1D,6F,9F,28,A2,C8,73,63,81,16,A6,03,37,78,00,00,00,00,A5,96,3E,01,ED,7A,25,DF,7E,E5,39,BC,4E,B3,CA,B8,80,00,00,00,74,E3,E3,9A,91,07,64,FF,56,ED,EF,78,47,AF,FF,71,00,00,00,00,8B,FE,D2,CC,C2,11,DE,15,14,41,C8,2F,E5,06,12,77,80,00,00,00,FD,15,F8,14,E2,A6,19,ED,BC,75,62,D0,80,FB,77,CC,00,00,00,00,CF,B6,A5,4A,7D,1B,2F,5C,1D,0C,CF,55,87,2C,24,C6,00,00,00,00,04,18,6A,0E,FB,2E,E4,5F,F6,BC,44,A8,EA,6A,DD,FE,80,00,00,00,27,EB,97,D2,A0,78,1D,2E,5B,5E,A1,D8,09,9E,7F,C5,80,00,00,00,17,6F,C9,E2,1F,54,B5,F3,BE,E8,5B,10,E5,06,2F,89,00,00,00,00,82,BB,A9,1A,B1,8C,18,5A,EB,83,DF,E7,8C,4F,1E,3D,80,00,00,00,DE,B7,7B,C5,3B,5C,0F,55,58,F0,78,B6,B4,C8,80,AC,80,00,00,00,BC,90,D7,90,7D,4A,EE,69,49,E2,93,F1,52,1C,24,1B,00,00,00,00,33,6F,01,4F,10,66,20,D8,74,AD,7B,1B,24,71,92,73,00,00,00,00,70,59,6B,87,93,50,82,62,4B,F8,76,BF,61,D4,DF,39,00,00,00,00,D8,2D,78,48,91,2B,91,4E,36,17,3D,FC,C6,0A,35,07,80,00,00,00,68,06,C5,A2,91,F0,28,E2,85,48,AA,9A,52,53,32,E9,80,00,00,00,9A,12,EE,FD,4C,F9,F1,28,C9,5D,33,14,9A,C6,DF,0C,00,00,00,00,7A,CE,49,82,A7,4B,1F,F1,0E,F9,BC,15,8C,2D,7E,CA,80,00,00,00,0C,99,4A,7F,05,B6,DB,2E,82,C6,8C,47,F2,2B,EE,23,80,00,00,00,14,C0,57,09,38,DF,C3,C5,43,9F,71,DC,6C,26,46,A0,80,00,00,00,9B,5F,98,E8,CD,96,34,0F,20,73,F1,F9,C7,D9,56,82,00,00,00,00,CE,FB,B5,F2,81,43,36,A3,F9,92,2D,7C,4B,8B,B7,64,80,00,00,00,7E,B1,19,63,BD,97,AE,C3,C6,19,AF,2D,D0,8F,78,0C,00,00,00,00,B7,7E,1F,91,51,A9,F3,E4,77,8B,32,36,2E,27,19,AD,80,00,00,00,22,1E,68,DE,0D,C1,C6,DF,BB,FB,F7,C9,5A,66,5F,42,00,00,00,00,40,B8,4E,4A,96,14,2F,08,16,A3,5B,C0,60,4C,EE,CC,80,00,00,00,8B,25,2A,33,2F,9D,04,D4,4B,1A,93,80,16,88,54,85,80,00,00,00,0C,16,71,95,0A,E7,5F,65,1E,2C,78,73,05,EF,7E,57,80,00,00,00,EC,1D,C5,54,D9,47,0C,34,62,49,B3,F7,F8,6F,E9,32,80,00,00,00,28,11,9B,57,99,65,A4,FB,26,68,15,90,A8,2E,06,2B,00,00,00,00,AC,7E,E6,95,F1,B6,33,85,9E,23,57,C6,ED,80,4C,E9,80,00,00,00,30,86,F7,02,60,4D,F7,24,0D,02,81,D3,74,1A,74,57,00,00,00,00,EA,59,C0,CB,25,44,1E,3A,60,B2,D4,21,55,E8,DA,10,00,00,00,00,8B,B6,DD,CB,8F,37,6D,13,A5,B5,96,69,FA,1D,37,20,00,00,00,00,25,06,F9,78,30,29,96,E0,A5,3E,45,1B,9B,11,66,84,80,00,00,00,C1,B9,56,20,2C,EE,36,B2,C4,8B,7B,26,93,49,90,BD,00,00,00,00,76,A3,AC,A8,46,F2,A0,E0,84,8B,CE,90,9F,99,EA,2C,00,00,00,00,C1,26,84,AD,10,8D,26,9C,BB,78,0B,69,8F,61,DF,3A,00,00,00,00,7E,75,D3,23,2F,5B,11,00,A1,CE,10,17,A7,45,DF,1A,00,00,00,00,55,AB,29,90,38,95,73,52,DF,29,FB,DB,67,A3,0D,DC,80,00,00,00,A2,7D,BF,C5,68,76,6C,0F,2A,08,9C,A8,7B,B9,73,02,80,00,00,00,10,C3,96,DB,4A,3F,C2,52,A1,5E,10,E0,C0,FE,31,12,00,00,00,00,8D,CE,48,8C,08,A5,E4,B0,88,60,A5,4F,AA,3F,A0,62,00,00,00,00,7D,4F,82,2D,DF,04,6D,70,72,43,51,2E,1E,25,67,10,80,00,00,00,ED,D8,FC,A5,E8,6E,9D,D8,AC,D3,CE,81,B6,68,5C,11,80,00,00,00,06,30,70,91,24,46,8D,34,65,73,51,E0,21,BE,CA,C1,00,00,00,00,BF,7E,7A,4A,59,22,3F,40,3E,39,79,F6,93,5D,61,52,80,00,00,00,BE,CB,16,F8,77,EE,F4,54,EF,9E,F4,9B,7E,97,B3,4F,80,00,00,00,C7,BA,08,A5,D9,F3,B8,28,D0,17,56,EE,E6,CC,8F,AB,00,00,00,00,EB,BD,D6,F8,E4,E1,C8,BB,F1,37,8E,C8,0D,D8,7D,29,80,00,00,00,B8,C5,DD,D7,54,AB,CC,7F,47,E0,33,46,1C,70,DD,F1,00,00,00,00,7B,E9,84,13,D2,A5,C7,8D,F2,06,0A,D5,2F,75,8A,B2,00,00,00,00,DC,45,7F,F0,44,21,16,A3,4C,51,64,D8,AF,03,C7,D5,80,00,00,00,E6,5D,E0,EB,DD,6F,CE,91,2A,6D,57,5F,27,FE,09,C0,80,00,00,00,61,86,A1,E2,1C,8B,57,B2,F3,01,AF,B4,7B,B8,7C,10,80,00,00,00,B1,A5,99,5F,44,99,C1,74,F4,53,60,8B,F9,AC,68,DF,00,00,00,00,BE,F1,BB,86,8E,8F,E2,EB,CC,C2,A7,FA,B9,55,70,1E,80,00,00,00,20,77,9F,84,5F,31,6D,E2,54,88,8D,61,2F,A4,6B,7B,00,00,00,00,51,86,D9,50,46,6B,7D,54,5B,15,ED,A1,8E,26,F1,C9,00,00,00,00,B9,94,67,9F,98,8D,EA,4D,36,78,FF,15,84,EF,87,77,80,00,00,00,A7,42,09,87,ED,D0,BC,70,D6,E1,C2,1F,34,8F,2C,B6,80,00,00,00,C0,F6,11,E5,F6,D0,E6,A9,A0,32,3B,E3,DC,A9,CE,E8,00,00,00,00,94,DB,81,C3,7F,CB,B3,A0,AC,96,DF,58,99,2B,6A,BB,00,00,00,00,66,BF,2A,41,69,0E,10,F8,71,1C,C8,88,33,D8,04,60,00,00,00,00,E7,B3,56,84,FC,7A,B0,71,21,91,48,2A,3F,D6,53,EA,80,00,00,00,D3,FA,AD,42,E5,08,C3,D0,EE,CD,FF,4F,DF,51,40,F4,00,00,00,00,8F,10,BB,B9,23,7B,B7,7D,E2,FB,75,B4,23,BF,8B,B0,80,00,00,00,30,D7,09,01,6A,C0,F6,1E,19,3C,E4,86,4B,3E,F7,E6,80,00,00,00,E9,E6,B3,67,63,AA,B8,8D,A9,AB,C9,92,E3,0A,17,42,80,00,00,00,00,05,57,01,EE,B7,3B,B9,0D,41,E3,7E,70,D9,7F,28,80,00,00,00,C0,6A,F4,49,59,48,FA,DB,2F,D8,1E,88,F2,72,9A,A0,00,00,00,00,71,30,20,7D,18,30,F2,0E,D6,78,23,DD,82,9D,0F,65,80,00,00,00,F3,0E,8A,7A,C2,9F,4C,3A,8A,0C,05,87,92,01,92,D5,80,00,00,00,C8,77,7D,7D,63,21,1E,AD,B6,42,83,42,C8,33,CB,C3,00,00,00,00,48,A6,69,C5,09,B5,DA,7C,FE,B0,23,E4,E1,33,4D,CC,00,00,00,00,D3,67,1D,72,C3,D6,6D,EE,65,DF,96,C4,CA,4F,D6,2B,80,00,00,00,CA,04,4B,A2,BE,AD,F4,FB,09,AA,D5,82,0F,06,DC,F6,00,00,00,00,42,E6,40,8A,EE,52,0C,64,4A,14,F9,D4,A0,23,52,CD,80,00,00,00,BE,52,BF,4D,88,51,AC,51,BD,6A,D4,3F,C7,91,FC,8A,00,00,00,00,CB,D2,AF,B0,A7,72,B4,60,68,BF,61,AD,48,7C,D4,1C,00,00,00,00,3E,2F,EE,10,E5,27,C9,59,32,38,06,40,8B,1F,F5,09,80,00,00,00,FC,B0,F4,C9,F4,C8,2F,A5,81,F6,63,9A,A4,E6,E4,A7,00,00,00,00,0C,55,BE,11,31,73,9F,F3,5C,2F,22,F7,58,9A,DC,26,00,00,00,00,94,35,1E,B2,7F,E0,D8,F8,F6,F2,E4,E8,32,27,A6,50,00,00,00,00,1C,90,8B,78,E6,3F,73,17,10,3E,97,D3,B3,19,80,E6,80,00,00,00,6D,A4,9B,8F,5A,7B,94,40,90,94,EE,A2,DA,46,27,47,00,00,00,00,6F,B1,93,DE,CB,1C,EE,DB,B4,B1,58,63,E3,F2,4E,13,80,00,00,00,D7,D3,60,47,A7,9E,9F,95,9D,A1,08,49,7D,69,C5,26,80,00,00,00,0E,08,51,18,5D,7D,B0,06,6E,61,A5,6B,E0,EF,DA,16,00,00,00,00,BF,13,73,4C,A5,C2,BC,8C,06,74,32,62,3E,DF,AA,BE,80,00,00,00,BC,5B,F8,60,2F,98,97,16,DB,09,A3,5C,F6,2D,A5,9D,00,00,00,00,74,F6,74,85,BC,E4,8A,F9,B7,5C,2A,56,5B,70,D7,10,80,00,00,00,E3,7C,3E,46,37,74,C9,A7,C1,17,4E,CB,FE,54,69,0E,00,00,00,00,2C,D6,D8,59,95,13,DF,D6,10,51,0A,74,6D,02,90,33,00,00,00,00,18,EB,D4,B7,80,E1,A8,82,05,4B,4F,A3,6A,CA,31,20,80,00,00,00,6A,A3,3B,F4,BA,6F,ED,EB,3D,BD,F2,0F,AB,EB,28,99,80,00,00,00,0D,48,7C,CB,9F,B1,7B,4D,1B,FC,1E,02,5C,90,A1,AD,80,00,00,00,76,67,58,2F,B9,AF,2E,9E,13,28,4E,F8,E1,AD,C4,70,80,00,00,00,7E,05,49,21,E3,3F,B2,E9,AB,9B,11,C6,01,A6,99,9B,80,00,00,00,2F,22,C7,76,BC,62,79,81,AC,35,E0,FA,83,8F,47,7B,00,00,00,00,E9,B1,7E,54,15,2C,11,F9,57,17,04,A4,BA,B1,EE,D0,00,00,00,00,C3,AD,E7,B5,39,05,4D,48,6B,0A,20,89,68,36,87,16,80,00,00,00,D0,F9,B1,3B,61,06,83,15,68,3D,0C,F5,90,AA,36,6A,80,00,00,00,DB,6B,E5,A4,64,5A,29,5C,A9,FD,A0,79,5A,63,E2,E9,00,00,00,00,C6,16,6F,39,D4,6F,39,CB,AC,88,F7,7C,0E,9E,CD,8B,00,00,00,00,34,FF,C7,4A,0A,9C,7D,E0,34,FF,A9,CB,8B,60,95,35,00,00,00,00,55,A0,D0,0C,D3,76,AF,DA,7E,ED,79,81,CE,CD,2F,21,00,00,00,00,75,F0,EF,A6,13,A0,16,B9,81,7C,AC,63,6C,32,8C,0F,80,00,00,00,4B,58,0A,62,DD,8F,E7,A8,29,D0,1C,29,FC,FC,74,93,80,00,00,00,6C,98,97,6A,E4,AD,F8,BB,7D,03,C9,64,D5,D6,3A,A8,00,00,00,00,03,A0,A5,19,52,C0,57,93,33,FD,F4,F2,2C,ED,40,62,00,00,00,00,BF,A8,39,3C,43,B0,7D,BB,20,69,DE,1D,72,F5,F9,87,00,00,00,00,7E,14,0E,1D,59,C5,A6,61,6B,E8,2A,E3,30,94,6E,C4,80,00,00,00,66,7D,42,E6,5F,9E,CA,CF,27,7F,59,E2,30,16,6E,38,80,00,00,00,68,5C,9A,09,C1,59,CD,89,B1,A6,DE,6E,19,25,92,A7,80,00,00,00,81,C0,3C,47,56,9E,91,B8,0B,5B,6F,8A,C5,3A,73,69,00,00,00,00,B1,98,7A,EA,DC,ED,94,0C,9E,AB,E9,EA,6F,12,00,0D,00,00,00,00,41,C3,83,A3,06,8E,1A,31,9B,C4,55,17,D1,33,1D,45,80,00,00,00,B7,08,79,24,10,A9,68,2B,81,39,91,1E,06,9A,C8,60,00,00,00,00,6D,45,61,13,70,41,4E,2F,A1,7D,FC,B3,E6,D2,BB,5C,00,00,00,00,AF,AE,C1,4A,88,EA,5E,71,5F,FE,EB,FD,B2,57,FD,A9,00,00,00,00,A3,D6,5E,8A,04,2B,13,F0,C9,17,83,D5,04,45,67,3E,00,00,00,00,59,03,47,1E,06,02,82,CB,A8,BA,B0,AB,A6,DD,8D,1B,00,00,00,00,98,F0,BB,7B,B6,BE,A3,21,DC,04,40,4C,75,FC,CB,C1,00,00,00,00,34,46,3D,85,AA,D3,4F,31,19,1F,01,4E,48,45,03,0F,80,00,00,00,B2,9B,6E,46,B7,2E,14,49,54,AF,14,7A,FB,E4,34,15,00,00,00,00,FC,5F,BC,2E,29,D7,1F,2D,79,0F,A1,78,25,E8,CA,AD,80,00,00,00,68,70,61,39,84,E4,79,74,00,96,92,FC,1E,0A,DA,29,80,00,00,00,88,8D,11,ED,F9,A7,A8,9F,7C,80,C5,A3,F3,9C,AD,41,80,00,00,00,1C,50,4C,3D,76,60,D5,AE,ED,5F,25,61,70,05,D7,88,80,00,00,00,33,CB,13,86,13,19,D0,6A,A4,5B,C4,F0,F1,5D,2E,38,80,00,00,00,B1,42,A2,E0,6E,BE,F8,75,F5,C5,A4,BD,1D,AE,68,C4,80,00,00,00,74,DB,25,54,ED,68,40,EF,5F,6C,2A,8B,F6,B1,3D,FA,80,00,00,00,98,BC,05,22,5D,E6,BC,44,52,B4,6F,A2,A6,D3,2B,CD,00,00,00,00,04,BC,1A,57,FB,CD,5E,65,90,AB,03,9C,F8,C3,D9,4C,00,00,00,00,CD,7C,34,31,F3,13,ED,22,7E,8E,F5,00,A3,7D,AB,D1,80,00,00,00,48,C9,51,57,CA,85,73,67,D2,42,97,15,F4,B7,4F,B4,00,00,00,00,CC,3C,FC,04,13,F3,A9,22,E5,D1,11,70,C3,CC,68,AE,00,00,00,00,5B,52,32,CE,F3,EF,E9,DC,E9,4E,92,E2,80,97,7A,47,00,00,00,00,88,5A,42,DA,20,F3,45,45,98,A6,34,D7,22,3C,B0,55,00,00,00,00,74,B1,5C,50,C6,C0,BB,51,39,75,D0,86,B9,FC,0D,8A,80,00,00,00,0C,2F,EB,D3,C0,E2,C2,F4,EC,B9,DB,0C,31,29,9A,91,00,00,00,00,38,6A,45,DD,3D,8D,49,20,CD,5D,4A,22,B0,FD,D5,1F,80,00,00,00,9D,43,72,44,9B,06,3C,82,0A,8B,BD,7E,28,B5,4B,04,00,00,00,00,98,A5,27,CF,59,55,73,12,52,E7,36,6E,B2,38,20,F1,80,00,00,00,8A,59,AC,2F,9D,9B,BE,12,33,41,C6,B9,B6,45,E4,9C,80,00,00,00,E3,30,27,AC,EF,43,EC,35,2C,C4,9B,27,0E,D1,43,02,00,00,00,00,2E,7D,18,52,5D,7E,1C,29,E6,E0,AB,17,C2,1E,75,87,00,00,00,00,59,DC,B7,3D,D6,E6,EB,81,7E,83,C0,41,DA,5C,AF,D3,80,00,00,00,98,1F,CF,0D,AB,FF,3A,D1,BE,E0,D7,57,DD,AB,AD,63,00,00,00,00,70,44,D5,23,CF,7F,E5,DE,D0,F3,2E,7C,BE,8D,3B,DA,00,00,00,00,95,66,BE,C1,38,BD,54,86,6E,FB,8F,9C,04,FA,8B,8B,80,00,00,00,4E,E0,15,14,EB,7B,3A,29,97,DC,46,69,17,F7,0D,CD,80,00,00,00,5A,7D,AF,B4,39,82,7A,8F,A2,49,8A,6E,47,02,A2,6C,80,00,00,00,18,84,23,B6,1C,C5,49,F6,4C,31,38,3A,24,BF,04,00,00,00,00,00,85,15,8B,74,8B,11,FA,F0,54,FD,1B,A4,E6,D7,AC,C2,00,00,00,00,1A,EC,57,63,1A,A8,29,A4,E9,A6,F1,F1,61,D7,23,D5,00,00,00,00,A3,D3,D6,FD,CC,D0,5F,4A,BE,09,C0,BC,0F,50,94,92,80,00,00,00,93,9C,B6,54,81,51,51,71,83,A5,7E,A4,08,9B,3E,BC,00,00,00,00,13,83,62,DE,E1,E3,CA,DF,DD,C2,E5,15,CF,46,9F,1A,00,00,00,00,2E,07,4F,3C,AD,84,F6,26,89,F2,BD,FE,91,63,67,2F,00,00,00,00,1B,0D,97,31,3F,D4,5B,28,94,E4,C0,A8,EA,A9,CC,03,80,00,00,00,C6,68,B9,9C,8E,C3,A5,9D,98,96,C5,23,E9,20,79,67,80,00,00,00,AB,42,C9,E8,56,72,FE,6C,7E,7E,0C,42,57,E6,84,19,00,00,00,00,3F,B1,E7,99,C4,77,8D,57,BF,2C,AE,80,63,9E,11,C1,00,00,00,00,70,34,09,81,F8,49,6B,35,7C,26,C4,69,0D,CB,8A,7B,00,00,00,00,6F,FB,DD,D1,04,05,3A,D7,A0,06,21,7B,02,A3,22,12,00,00,00,00,53,9D,9A,DC,89,80,9A,A7,6D,A0,16,FC,69,1D,21,2F,80,00,00,00,44,5B,E4,A7,49,97,CF,F2,62,C9,3B,ED,8B,A6,8C,79,80,00,00,00,FF,18,AD,81,05,B9,E8,9F,E7,59,CB,7B,35,BD,61,E8,80,00,00,00,9D,99,D0,A9,9D,10,C6,1F,BE,CB,86,E5,1B,51,C3,33,80,00,00,00,AB,EB,0D,9F,0F,F0,07,C3,7B,88,23,BE,A3,1A,58,9C,00,00,00,00,72,7A,E4,24,E2,99,DE,EE,E2,3C,EA,69,EB,5B,6B,6D,00,00,00,00,16,F2,20,38,F2,D5,F8,FB,B2,FE,54,39,4A,9A,DC,1F,00,00,00,00,6E,40,F4,99,74,CC,D0,AB,74,45,E8,5D,59,BA,46,8E,00,00,00,00,42,F3,BA,23,70,67,BD,0C,8F,D2,4F,82,62,8F,F5,73,80,00,00,00,4B,4D,94,48,D0,29,22,FF,8D,BA,2A,09,92,60,6B,F3,00,00,00,00,2D,34,DB,EC,CF,B1,50,A6,31,6E,B7,84,FE,7B,93,C2,80,00,00,00,64,CC,C3,3D,DA,7C,CC,33,04,DA,D4,51,E8,1A,76,A9,80,00,00,00,78,13,A5,5E,84,8F,D5,8F,49,3B,B3,BC,83,60,74,0F,80,00,00,00,A8,90,56,53,26,B3,A7,43,2A,A2,70,A6,A1,A0,42,22,80,00,00,00,EC,D9,D7,B2,20,01,2C,59,21,BA,10,79,6B,BF,34,B7,80,00,00,00,42,BF,CF,E3,27,BE,44,F7,49,60,2D,BA,16,97,0C,5A,80,00,00,00,7E,68,53,71,89,74,DE,99,70,6A,DF,17,A0,9D,91,1D,00,00,00,00,82,99,DE,0A,92,04,51,85,D9,3A,CA,46,3C,CA,03,F6,00,00,00,00,BD,8D,F6,03,DC,E7,F1,C4,78,1C,F8,1C,F5,C1,54,4C,80,00,00,00,B3,84,13,17,83,21,38,AB,0B,48,F7,D5,BB,A1,A1,51,00,00,00,00,4A,82,41,0F,4C,08,08,71,18,0E,72,5D,9E,A5,DD,C1,80,00,00,00,A8,DA,03,78,BB,67,DA,B3,2D,10,F5,8F,FD,21,F1,23,00,00,00,00,E0,E9,2A,CC,F6,98,0C,C7,62,91,1C,DF,AF,C3,4D,EB,00,00,00,00,A2,49,50,02,79,71,69,5B,F1,40,7F,3F,A2,E3,B3,37,80,00,00,00,49,D4,9D,59,15,21,84,CA,5C,9B,E7,83,2C,E1,AB,93,00,00,00,00,A0,B7,8C,75,E1,AD,6C,03,CB,79,2A,94,20,4D,99,42,00,00,00,00,EE,AD,05,BC,77,B1,3F,AD,27,96,B9,B3,4A,A0,A7,8D,80,00,00,00,59,7A,31,4B,C4,96,74,46,FB,8A,62,10,C6,68,24,2D,80,00,00,00,72,20,05,6F,39,53,30,BA,45,2E,3E,F5,EF,51,75,36,00,00,00,00,0C,EF,8D,CA,B5,51,FA,C0,1F,80,A9,89,CE,08,95,95,80,00,00,00,82,A5,64,04,7A,A7,25,4E,7B,9D,EB,9C,D3,07,1F,D2,00,00,00,00,7E,26,33,3D,3C,8E,11,1D,97,F2,14,99,2B,2E,04,19,80,00,00,00,D6,97,25,03,2D,66,B5,33,1A,BC,26,CB,F4,D0,08,93,00,00,00,00,22,CC,FD,69,57,4D,46,9F,C5,82,07,02,35,20,6A,86,00,00,00,00,D6,DA,B2,6F,75,20,61,A0,91,31,07,BE,7C,B5,10,5B,80,00,00,00,07,54,C6,A5,4F,2B,DB,D9,CB,0C,23,1D,92,28,DC,F9,80,00,00,00,71,08,1F,6A,CA,0D,87,5A,40,C7,23,21,A7,DB,2E,67,80,00,00,00,6C,C3,71,58,02,FB,14,0A,B6,45,8E,92,F4,F6,36,C7,80,00,00,00,EB,6A,A6,40,81,82,15,11,C7,A0,AD,98,D6,6A,93,A6,80,00,00,00,83,D9,91,D0,C9,45,78,2E,5A,84,0E,16,96,C3,3C,FA,80,00,00,00,71,68,66,D9,49,91,AB,78,B8,6E,62,69,9D,21,98,FD,00,00,00,00,BA,2B,2F,BF,EF,E0,6D,76,DD,B9,5A,D3,D5,28,96,3E,80,00,00,00,99,8F,B9,BA,CB,83,91,8B,4C,CB,BD,8C,1F,A7,A7,C3,80,00,00,00,18,34,B9,6B,CA,75,5C,E7,FF,E9,11,1B,34,12,4C,D4,80,00,00,00,5C,1D,68,6B,AE,B8,4C,F6,A2,E7,C7,74,99,1A,10,3B,00,00,00,00,6F,A4,CA,16,06,AA,D7,C8,75,F8,25,96,B1,EB,F8,AD,80,00,00,00,45,D8,60,58,4B,68,9D,40,DA,75,7B,E8,CA,E4,48,FB,80,00,00,00,31,54,74,F7,21,31,69,86,91,7F,C9,20,70,CD,67,3F,00,00,00,00,F4,92,C8,94,6A,BB,CA,A6,00,A6,17,94,FC,16,EE,72,80,00,00,00,9C,2E,57,82,C2,9D,BD,5A,3E,99,6F,AA,0F,98,9E,EB,80,00,00,00,E2,BF,8D,E3,AF,FF,FE,BC,C8,BA,DC,B9,54,6C,BE,06,00,00,00,00,59,8A,00,0A,F7,32,4B,39,4A,8A,EB,89,02,F8,F8,45,00,00,00,00,86,DA,D7,CC,F6,6E,36,1B,29,1C,5F,69,DA,0C,E5,46,80,00,00,00,93,B5,27,7E,A1,A9,C7,1A,0E,03,83,4D,98,A3,DD,A5,80,00,00,00,F6,BD,A1,4C,6B,3E,D4,9D,14,D0,56,6B,CE,50,0C,18,00,00,00,00,7D,36,64,DA,DF,8C,6C,99,FA,E4,94,03,22,98,96,0C,80,00,00,00,AB,D3,61,D3,BA,E7,58,CA,C6,79,70,42,3A,08,B7,DB,00,00,00,00,66,51,35,9B,0B,5C,6B,79,CB,E1,1C,40,AD,47,4E,7D,80,00,00,00,11,A2,6F,C9,6C,82,8E,4A,DE,7F,D0,15,E0,2D,44,9C,80,00,00,00,1F,EB,A2,C8,AF,91,B0,8C,52,DF,B8,86,7D,CA,B4,A8,80,00,00,00,DE,47,81,82,40,A6,DA,53,D9,DE,04,70,D8,76,BE,5F,80,00,00,00,58,79,FB,7E,6C,C8,D9,C9,B5,F6,E4,1A,B0,32,10,79,00,00,00,00,2C,2A,12,6A,B9,64,55,E7,02,E6,39,E3,CD,60,8E,78,80,00,00,00,75,57,66,15,75,15,F9,5D,CC,93,21,00,51,07,2C,63,80,00,00,00,DC,2E,ED,01,ED,7B,46,70,06,C5,DF,3D,F9,9A,84,FB,80,00,00,00,8C,32,C5,D9,27,B7,96,E5,D5,E9,09,A5,68,81,12,32,80,00,00,00,35,59,08,5D,BC,C2,CE,D8,0D,DC,F4,BD,D7,BD,12,11,00,00,00,00,B5,11,A9,B2,50,EA,A6,1F,31,8D,E0,E1,54,88,A1,90,80,00,00,00,67,05,AB,52,09,C3,63,2F,69,FB,6D,EF,16,93,4D,0E,80,00,00,00,79,A3,9A,68,1C,41,8D,04,B3,E0,C2,9B,32,05,D1,D4,80,00,00,00,3D,E7,41,0B,6F,FA,2B,F6,31,D5,04,F1,62,76,E0,0D,00,00,00,00,23,5C,20,33,1E,02,69,0C,88,FB,13,20,2C,FA,F5,13,00,00,00,00,F7,01,CB,E2,16,45,5E,AA,D2,57,06,1A,8C,47,CD,0A,80,00,00,00,C3,41,DB,E7,A5,B7,D9,40,92,51,F6,78,F3,BA,92,E1,80,00,00,00,FA,7A,CD,78,51,32,BC,E5,C2,D5,0D,C2,AA,5B,6A,86,80,00,00,00,3F,46,42,29,7F,F5,53,46,44,B4,BA,C2,F7,B5,C4,69,00,00,00,00,8E,D0,28,AD,61,DB,F9,78,62,2C,B1,1A,21,68,F5,9A,00,00,00,00,2C,16,F4,E5,B3,5D,A4,FD,19,1C,B6,0B,05,21,EB,F5,80,00,00,00,34,C0,16,95,07,86,1F,E0,D8,CE,BE,66,A2,78,0B,61,00,00,00,00,FD,3F,25,9F,AC,9C,B5,95,A7,68,98,33,EA,41,95,E3,00,00,00,00,CA,E4,45,F6,39,90,AD,64,ED,8C,EF,E0,45,64,A6,80,00,00,00,00,D1,E8,46,BB,FA,B5,67,A5,FC,AF,06,0D,4A,70,03,A9,80,00,00,00,E4,27,53,60,F2,4C,E0,D7,9C,A5,3A,D7,99,BF,19,90,00,00,00,00,E4,2F,0E,F4,1C,7E,E6,00,EE,16,7E,DD,1F,F9,B6,CC,80,00,00,00,D4,B5,BB,60,EA,A9,D2,7A,54,B2,F5,A4,02,33,F5,19,00,00,00,00,78,D1,E8,1B,B8,1A,B2,A3,C1,C8,0A,E0,16,93,32,58,00,00,00,00,32,FD,40,B8,7B,50,BD,9D,BA,91,B5,8A,BB,17,E9,CC,80,00,00,00,3F,42,45,ED,0E,FB,C6,6D,26,B1,06,69,5A,3B,92,E7,00,00,00,00,91,8D,7F,3D,63,27,C6,77,FE,9B,82,7A,BA,31,E2,C9,80,00,00,00,8D,CC,A8,4A,15,A2,B3,BD,30,B5,61,AC,BB,B0,BA,CB,00,00,00,00,78,65,CD,74,7D,D8,3C,13,0B,B3,4F,84,79,67,A5,FC,00,00,00,00,49,30,CB,88,22,E7,E5,5C,23,B8,EC,DB,26,B0,8D,00,00,00,00,00,76,FD,EB,D0,F4,7C,FA,12,3C,16,62,E3,E3,7B,BA,5B,80,00,00,00,7E,2E,AF,8C,95,E5,45,9D,AA,41,2C,D8,53,0F,D4,56,00,00,00,00,65,0F,13,F0,F3,87,66,02,5A,A9,93,B2,35,E0,2A,86,00,00,00,00,33,32,07,67,9A,5D,A4,11,18,5F,A0,5F,9F,FA,2A,E7,80,00,00,00,20,CE,74,B1,C3,FF,B1,DA,DC,CC,3B,74,EC,44,6A,AF,80,00,00,00,4F,1B,5B,66,82,6A,C1,A8,28,67,9B,4C,2E,E2,46,9E,80,00,00,00,8D,40,A1,6D,88,2B,AE,57,D7,5B,59,9C,26,35,89,B5,00,00,00,00,3D,BF,56,06,EE,18,3E,DE,F9,3D,EA,89,0A,90,45,F9,80,00,00,00,6B,14,41,AF,21,8B,1F,C9,5E,61,D1,83,C1,8A,82,E1,80,00,00,00,38,4A,7E,BE,8F,E7,1E,A6,C1,E9,B2,7A,E5,65,FB,13,00,00,00,00,A3,C3,99,4D,9A,8B,18,C8,CE,17,8E,EC,80,84,B6,B3,00,00,00,00,EC,F1,9E,81,56,F6,DF,92,0A,86,D2,DB,C2,4E,02,04,00,00,00,00,E4,E9,40,EF,ED,DB,6E,B9,21,38,9C,79,90,54,27,29,80,00,00,00,3E,3D,F7,6C,7E,F4,D5,D8,2E,88,65,9A,F8,D7,C1,80,80,00,00,00,DF,8D,A0,85,8B,6D,E7,24,89,D4,70,31,88,7B,E3,57,80,00,00,00,AE,87,70,58,96,EE,3D,5B,EF,77,63,DF,73,B8,B6,1C,00,00,00,00,21,EB,29,5F,72,30,56,8F,C8,21,01,7E,1B,F1,AE,F9,80,00,00,00,E0,F5,EA,2A,00,54,01,55,DE,4A,39,36,39,A9,9E,98,80,00,00,00,EA,7F,29,5F,ED,7F,B2,9D,54,5B,7C,FB,61,2B,A5,9A,00,00,00,00,7F,AD,34,FA,F7,E6,93,75,38,3D,4F,FF,BC,CD,3D,88,80,00,00,00,BB,B0,2C,81,D6,29,C5,ED,C9,F1,38,35,65,EA,9C,D0,80,00,00,00,24,82,E9,E9,36,C8,CA,EB,68,4B,8A,2E,34,39,0B,F1,80,00,00,00,71,CF,54,5A,4B,85,FE,F5,39,D9,20,E8,F3,4B,CF,2E,80,00,00,00,6D,15,D8,44,34,B3,53,8E,B3,2C,D2,68,2B,5E,F2,9B,80,00,00,00,CD,82,1B,3D,DE,4D,79,34,09,B1,2F,5E,66,93,FB,D8,80,00,00,00,08,0F,88,E3,E7,51,6B,91,62,96,93,C7,62,0C,B2,BF,00,00,00,00,C5,0B,37,D0,0F,F5,BD,B9,81,EF,B1,3A,F8,63,19,E3,00,00,00,00,4D,42,50,62,E2,63,52,63,D5,67,56,0C,CF,C8,2C,27,00,00,00,00,FA,4B,E5,CD,DD,E7,DD,34,DD,38,13,B6,CC,C4,13,D1,00,00,00,00,76,68,FA,32,CC,45,35,BF,59,40,A0,E6,71,38,8D,45,00,00,00,00,4A,AE,15,DF,E3,FE,88,D2,E0,D7,F3,38,A5,2A,35,B3,00,00,00,00,18,01,F8,7F,E8,AE,69,F3,19,4D,36,BE,BC,16,C1,D6,80,00,00,00,92,5C,73,6D,C8,1F,F2,39,5C,57,8D,8B,8E,A7,3A,AD,80,00,00,00,1A,65,5E,AD,DC,E1,F0,4F,47,2F,A2,15,5E,BB,11,60,00,00,00,00,6A,EE,16,12,17,A0,DD,E7,83,3C,B1,27,99,49,52,2E,00,00,00,00,1C,6B,FB,5A,90,72,E6,79,9A,D7,9B,A5,0B,57,2C,36,00,00,00,00,F1,7E,8D,01,ED,CA,F0,5D,A2,3D,A4,8B,6E,04,A0,42,00,00,00,00,09,65,5F,A5,B4,45,E6,0B,89,98,F9,0A,EF,88,E9,07,80,00,00,00,84,F6,AF,3E,79,09,B1,79,D9,D4,F1,00,D9,6C,BC,2D,00,00,00,00,28,0E,2C,E7,3E,16,2C,BD,52,E2,3E,27,15,4C,EA,65,00,00,00,00,EF,81,E1,04,B0,BE,B8,B5,86,AC,BF,29,A0,2C,40,2E,80,00,00,00,A7,9B,6D,12,46,EC,09,4E,28,1A,40,BB,20,7C,6C,BB,80,00,00,00,16,D0,25,E1,CC,AD,45,28,55,D4,49,03,2C,97,0A,42,00,00,00,00,C1,01,54,1C,CC,8E,4F,30,7C,A9,7F,C4,09,03,E9,77,80,00,00,00,CB,2C,0C,05,C0,FE,61,87,70,5C,61,97,94,2B,51,B1,80,00,00,00,1A,8B,E4,EA,61,13,1C,3F,8C,E8,03,ED,CB,5F,A0,F1,80,00,00,00,FA,B4,A3,FF,34,79,1E,DA,69,41,D6,10,84,E0,6A,2E,80,00,00,00,E5,30,51,A9,17,C7,B9,AE,41,9E,E3,E3,DD,7A,50,85,80,00,00,00,D8,B5,05,A6,C7,A1,92,8E,CD,48,FC,86,25,7A,DC,23,00,00,00,00,21,4D,26,2B,3B,18,A5,89,EA,E2,9E,C3,CB,58,D1,3A,00,00,00,00,A6,9A,E2,2C,B7,CB,44,C8,41,6B,E5,4B,E5,56,88,DA,00,00,00,00,7C,BF,AE,DD,9F,8A,22,71,D9,58,70,28,16,4A,D5,F7,80,00,00,00,2B,FF,FE,58,9C,ED,15,F6,84,EB,CA,7F,CF,EE,DF,3D,00,00,00,00,99,97,6B,1A,D4,59,99,EC,3E,45,09,BD,39,07,DF,58,80,00,00,00,44,E6,FB,B4,7A,4F,B5,DC,CD,D6,FE,1A,2B,87,F2,40,80,00,00,00,FC,C9,CA,CB,54,6E,C8,7E,B3,28,53,25,01,E5,00,DB,80,00,00,00,FF,67,68,04,79,40,BF,1F,1B,D0,AC,5F,AD,CE,94,5B,00,00,00,00,36,CA,83,19,CD,D9,0D,EE,8C,14,19,27,F4,35,49,A2,00,00,00,00,33,2C,B6,B7,61,05,E2,79,93,5C,D5,71,AC,07,28,4D,80,00,00,00,0B,5F,57,BB,F5,9D,D9,16,DE,6C,B4,4C,C1,0E,1C,0B,80,00,00,00,DF,61,86,F3,01,F2,9D,BA,B4,10,AA,13,B2,F1,F6,D9,80,00,00,00,1D,E8,57,91,57,31,CF,2B,69,7F,A9,CC,D8,19,0A,65,00,00,00,00,99,54,57,89,F9,8D,4B,69,CC,95,FE,C6,52,58,B0,9D,80,00,00,00,FA,88,E5,1E,9C,49,82,86,7D,9C,7E,21,17,41,56,65,00,00,00,00,C3,4A,2B,6E,6C,E2,A1,AD,CB,73,69,D6,73,D4,94,77,00,00,00,00,6B,13,16,32,00,92,5D,6D,3D,3A,56,84,D0,63,5B,73,80,00,00,00,BE,5C,CF,31,8C,03,44,2C,15,77,C9,BA,77,9D,16,18,80,00,00,00,1C,F9,2D,FA,E5,A1,FE,18,9F,E1,B7,8B,A6,26,A8,6C,80,00,00,00,15,9D,A4,26,11,14,A6,30,00,48,D6,71,90,58,0E,8B,80,00,00,00,D8,B5,87,5B,0E,1C,6C,34,FE,82,4A,E8,37,72,A4,34,80,00,00,00,17,76,BB,C1,14,E6,62,5E,08,7F,A6,73,33,08,05,43,00,00,00,00,4D,7C,77,54,77,05,BE,A7,E9,1C,22,43,FA,31,80,A8,00,00,00,00,79,91,95,8D,2A,70,06,0F,30,41,5A,F2,8D,0E,DC,0B,00,00,00,00,B1,99,06,A1,EB,CB,1D,8A,1D,DD,7B,B6,14,E6,A3,89,00,00,00,00,0C,44,D0,75,FA,2D,37,EF,FC,CE,99,0E,BE,F1,29,FC,00,00,00,00,62,72,A2,17,A4,7E,78,C5,1B,BF,C1,11,B2,DD,8D,13,00,00,00,00,E8,71,0E,AA,95,95,FB,72,53,34,09,1F,CC,9E,57,2F,00,00,00,00,7C,11,C4,D0,91,60,8B,05,DC,8D,46,DA,1F,B3,C5,6B,00,00,00,00,CC,B3,F6,94,DC,BC,74,FD,EC,C3,EB,B7,D8,E3,B5,55,80,00,00,00,A2,89,94,B7,34,63,C7,C8,0E,76,80,42,00,BB,6E,CA,80,00,00,00,3D,6C,4D,AE,8A,8D,5E,D9,F5,A8,BE,01,97,76,98,A3,00,00,00,00,42,95,C5,6C,60,E2,B3,FE,16,4C,AD,32,21,DA,E0,37,80,00,00,00,1B,44,52,F1,E3,05,F1,4A,23,B9,EA,D7,36,CA,78,6F,00,00,00,00,17,C2,68,49,30,5A,F5,D1,F8,71,55,B6,07,38,99,EA,00,00,00,00,B1,A2,CF,47,96,45,DD,BC,FB,58,E5,A8,0A,D6,5F,9C,80,00,00,00,FA,A6,42,3D,C3,25,9B,BB,83,F4,E7,E0,25,D9,CC,7F,80,00,00,00,17,D3,4B,7F,BA,22,4F,F3,B0,8A,09,4C,1B,99,E0,D1,00,00,00,00,A2,16,77,C7,C3,CE,80,A8,B0,76,AC,0F,81,01,48,C2,00,00,00,00,AF,16,27,DC,6A,81,51,E3,37,7C,5A,12,4E,4D,F7,DA,00,00,00,00,27,DD,C5,22,A0,84,15,D4,9C,40,71,5F,56,D2,19,1F,00,00,00,00,81,CB,FD,69,0D,33,41,97,0C,88,B9,3F,1D,52,5B,4F,80,00,00,00,33,7B,9F,85,92,12,8C,B8,72,5E,61,50,6B,EB,00,26,80,00,00,00,99,88,C8,3E,54,2F,FB,27,30,C8,94,17,85,61,FB,49,00,00,00,00,97,F4,3F,F2,50,7F,12,84,20,DE,AE,7C,EF,75,BD,79,80,00,00,00,24,08,06,D6,38,75,F7,04,05,13,FF,F1,A0,3E,D9,34,00,00,00,00,53,F6,86,71,1B,2C,5D,56,99,1F,83,51,5C,C9,7D,0D,00,00,00,00,9C,F0,A1,39,94,05,08,4E,D5,8C,F4,1E,2C,A4,91,21,80,00,00,00,B5,5B,81,6B,4F,38,C8,C2,68,E4,D1,1D,17,08,B7,FA,80,00,00,00,68,14,CE,5E,61,20,F8,A9,34,81,D3,E7,7A,DC,E9,66,80,00,00,00,FD,68,D8,66,B7,A8,E4,22,F5,61,3C,13,76,AD,E4,A0,80,00,00,00,EE,92,8C,5D,43,94,BC,31,D3,CC,34,E7,98,54,82,84,80,00,00,00,25,6F,CE,84,73,9B,AB,D3,D2,C4,C2,26,76,C8,FD,35,80,00,00,00,45,88,52,7E,B9,DD,E9,A6,C6,B0,42,2D,20,C4,96,23,00,00,00,00,96,24,86,83,04,28,9A,84,D9,23,E4,B8,80,32,D5,B0,80,00,00,00,30,F3,64,73,F5,65,15,B3,66,03,18,79,9A,81,BA,95,00,00,00,00,C8,66,73,71,EA,F5,0B,55,91,BE,30,B5,9D,BB,3E,83,00,00,00,00,68,5D,4D,82,5E,0B,DA,44,99,93,FE,40,B2,8B,D8,52,80,00,00,00,42,56,79,44,52,F5,13,3E,06,E8,E7,24,C2,AD,0E,E6,00,00,00,00,EF,87,D5,09,4A,4D,D8,E5,EB,F7,AA,F6,07,20,AF,03,00,00,00,00,70,55,97,DB,35,8D,F1,C4,46,ED,2E,CC,AD,80,EE,39,00,00,00,00,3D,B1,4D,6A,68,0D,A3,70,DD,4A,75,64,A3,D3,88,8C,00,00,00,00,9E,E6,24,16,2C,1A,EF,DC,2F,18,CF,23,83,D8,97,6F,00,00,00,00,EC,26,1D,21,DC,76,42,EE,BF,16,45,3D,B2,BF,D1,2E,00,00,00,00,62,1F,EA,44,73,B3,FA,8A,DE,FB,52,18,DA,7F,3B,D8,00,00,00,00,57,97,19,C3,DD,D5,D6,FB,7C,96,E7,B2,06,85,3C,90,00,00,00,00,D0,70,C8,60,EC,81,8D,D5,EA,06,3A,A8,44,BA,59,1C,00,00,00,00,5D,3F,3F,8F,F0,DD,73,C4,01,D6,46,9F,B3,78,10,F1,00,00,00,00,AB,EE,D7,F5,F1,BE,92,DF,9C,F9,BD,6B,EE,3B,B3,2E,80,00,00,00,8D,42,4C,AA,B3,7E,3E,F1,D5,BB,A1,62,D6,17,CE,E6,80,00,00,00,35,78,B9,CA,5A,1D,68,5A,FA,6C,0A,8B,01,A7,2A,6A,00,00,00,00,5F,B1,BA,FA,2B,D5,69,93,C4,9E,D3,65,DC,FD,03,0C,80,00,00,00,72,F2,6A,4D,1C,32,EB,56,31,05,82,54,F3,13,1D,9A,80,00,00,00,31,EA,27,E0,C6,71,91,CB,11,A3,B9,2A,CE,B0,31,E7,80,00,00,00,A3,B8,3D,A4,5B,44,4D,54,F8,00,93,12,00,42,AB,3E,00,00,00,00,7C,E6,75,22,A6,B6,77,08,8E,53,52,85,79,B8,BF,34,00,00,00,00,03,8C,79,85,63,27,C7,08,76,E5,AA,86,C9,B1,6C,3F,00,00,00,00,A3,EC,26,2A,D0,E6,EF,D4,2B,72,85,34,C5,21,10,81,80,00,00,00,C7,1D,68,B3,8F,B3,E0,EA,1C,27,9E,0E,BA,5E,E8,57,80,00,00,00,B9,62,91,53,3C,AD,53,7E,BF,21,6F,CB,C2,CF,86,7D,80,00,00,00,17,FB,40,89,DA,B4,D6,55,8C,E8,3C,E7,BC,0F,18,9E,80,00,00,00,F8,76,2A,77,D9,A8,0D,94,17,21,30,35,FE,77,E6,3A,80,00,00,00,B1,6A,93,96,54,6E,72,0E,07,75,EA,30,B4,6A,12,51,00,00,00,00,30,57,D8,BF,29,AF,F9,E8,D5,9A,70,2D,A6,A3,12,2C,00,00,00,00,5D,D1,20,1A,BA,89,BD,9B,2B,98,EE,47,D3,CE,79,64,80,00,00,00,D3,62,85,CE,14,64,B4,C4,DC,EC,C8,63,5D,3F,5A,87,00,00,00,00,42,D8,05,4F,85,C0,0F,A7,FD,01,C8,D2,10,00,4B,F9,00,00,00,00,91,D6,2A,0A,DA,59,91,25,FD,47,4F,30,9F,A9,41,FC,00,00,00,00,18,E4,EE,33,37,6B,56,CE,C5,99,F0,F3,BF,1D,41,CE,00,00,00,00,14,93,46,96,B5,92,32,8B,CA,8C,9E,8C,FF,CD,C9,0B,00,00,00,00,57,6B,74,9E,80,33,BD,DA,34,B8,BF,1D,69,79,99,28,80,00,00,00,D5,9D,38,E9,8B,D6,30,81,E8,CF,20,5F,20,09,68,ED,80,00,00,00,3A,2E,3B,0C,6F,7B,9C,3B,CC,41,1D,D1,83,CB,FF,2E,00,00,00,00,1B,FB,3E,9C,FE,1C,93,F0,67,61,58,68,8A,51,42,3B,80,00,00,00,80,49,5A,A5,C0,B0,83,A9,77,5B,BC,3E,47,C5,8A,4E,80,00,00,00,5A,7A,D2,47,90,75,CB,72,3B,03,FD,4E,3E,05,D2,ED,80,00,00,00,DC,21,3B,FE,CB,27,6B,2C,D3,A6,F0,84,1A,20,25,37,00,00,00,00,05,9A,33,72,9E,1C,D3,BF,0F,D3,36,84,F0,EB,F4,81,00,00,00,00,C2,8C,53,4A,40,FC,8F,25,4D,91,51,8D,9F,07,11,09,00,00,00,00,E7,55,60,A3,16,11,39,CA,73,71,7E,FB,40,DF,28,0A,80,00,00,00,A6,BB,C2,0F,8E,4B,2B,14,78,0F,39,BC,62,EA,7F,AF,80,00,00,00,B2,A0,FF,3C,8E,85,35,33,48,93,CC,03,E7,B6,CB,AF,80,00,00,00,7C,F0,F6,51,49,1B,C3,C3,04,C7,E7,09,F3,27,7D,F6,00,00,00,00,4C,95,D2,06,8D,E9,D6,E7,F2,E2,DB,C5,88,BF,10,79,80,00,00,00,BA,A9,DC,46,00,3B,D6,0E,3F,1E,48,F8,15,58,B0,AD,00,00,00,00,CA,95,4B,BA,71,6B,DE,A1,1B,45,4B,E0,3A,48,81,CE,00,00,00,00,C7,2E,53,08,E5,B9,42,99,15,2B,47,04,8E,66,8D,BC,00,00,00,00,42,57,58,43,FA,AE,5E,B1,54,21,61,B7,DC,11,56,E1,00,00,00,00,29,C2,E3,CD,68,43,0C,6D,CD,65,D0,FA,D4,E6,EF,2C,00,00,00,00,B5,33,D0,EC,F6,E8,D8,E0,4C,D9,B2,89,10,FC,C8,3B,80,00,00,00,59,CC,60,B2,AE,DD,C5,2A,DC,6E,45,2C,E7,1D,41,C8,00,00,00,00,B9,15,99,18,13,F2,23,A8,1C,E6,BF,44,3F,FA,39,99,00,00,00,00,95,34,B9,A5,97,DF,C7,E1,2A,A9,32,A6,4D,C0,1F,7D,80,00,00,00,4E,7A,E0,09,85,9D,AA,9A,6F,F5,1B,F3,6D,A8,B3,0C,80,00,00,00,EE,ED,A8,69,C6,FC,17,69,F1,E3,56,AF,61,45,0A,DF,80,00,00,00,D0,A3,48,C1,64,83,B8,04,F3,38,61,0E,12,76,4E,04,80,00,00,00,15,A7,DD,AF,AB,03,A5,58,DC,DB,88,32,DA,BF,79,D7,80,00,00,00,0A,41,CC,16,99,51,AB,A8,9B,E7,4F,B9,4B,C7,52,4C,80,00,00,00,85,3F,18,8F,01,B0,98,FA,2D,FF,5B,6F,E7,E8,7C,B5,80,00,00,00,5C,98,59,6C,9A,BA,9C,6C,5E,75,DD,22,CA,4F,95,DC,00,00,00,00,94,32,2F,9C,14,10,FC,1D,10,3C,58,90,4B,17,BE,24,80,00,00,00,91,47,F2,1E,08,BF,0B,DF,BB,69,E6,60,0B,66,C9,48,80,00,00,00,13,E3,5B,1A,FB,39,B7,FA,6C,F4,69,6D,68,DF,36,71,00,00,00,00,12,3A,F7,F4,86,4A,A6,19,23,E6,F6,C3,E2,AD,F6,55,00,00,00,00,11,4F,E7,F3,C7,6F,A3,F5,B2,BF,8D,7A,1E,B8,00,53,00,00,00,00,D5,3E,D7,47,BB,23,C4,53,4F,8B,19,FC,D6,B5,2E,47,80,00,00,00,17,00,96,68,C1,12,70,B7,B3,D7,2C,4C,54,2D,FC,1A,00,00,00,00,26,28,E0,49,A5,13,CA,E2,64,1D,9F,5F,EF,89,34,25,00,00,00,00,BC,C6,3D,22,9D,77,3C,CE,5B,6C,C9,41,99,25,0F,29,00,00,00,00,7A,BA,7C,BB,64,3E,B4,E6,D8,05,6F,A4,EF,CB,BD,F0,80,00,00,00,44,37,AF,9F,C6,CA,7D,4A,48,8C,A9,56,4D,D7,99,F8,00,00,00,00,2F,27,BF,61,ED,D3,7F,B2,7E,7D,EC,ED,DB,99,50,25,00,00,00,00,1E,D9,23,5D,29,A1,E0,18,5F,DB,8B,4B,7E,28,44,2C,00,00,00,00,7B,FE,6A,F9,A6,BA,39,28,EB,73,F6,2D,9A,F8,F1,FB,00,00,00,00,CA,61,C5,97,93,05,F2,A0,C3,42,D4,7D,DB,77,B6,79,00,00,00,00,49,17,5A,2D,A9,E8,36,39,AF,9D,2C,9A,3D,77,B8,67,80,00,00,00,96,86,CF,A1,47,92,51,C3,C2,FA,FC,BB,73,2E,CA,4C,80,00,00,00,D4,96,01,07,D4,D0,F5,B4,54,9F,E0,A6,48,0C,2B,C8,80,00,00,00,62,0F,B0,2E,C4,A9,64,0A,13,A1,50,02,B3,72,22,97,00,00,00,00,CF,B6,0D,1F,C9,0F,DF,78,7B,66,C2,49,A3,80,58,C5,00,00,00,00 -keyMatrices_inv = F2,8E,2D,ED,52,8B,1C,52,91,CB,69,FC,63,E2,C0,EE,80,00,00,00,63,8C,94,AD,8F,93,BB,D7,03,03,78,5D,11,B4,31,9F,00,00,00,00,5B,08,0C,B3,4D,4E,08,EE,60,B0,C6,95,24,E7,7C,45,80,00,00,00,67,AB,EA,E6,B9,39,E5,54,1A,AB,0B,60,5E,0A,6F,7A,00,00,00,00,AF,76,69,2A,DD,A0,F9,AE,98,30,02,D2,B7,62,8C,5E,00,00,00,00,7F,6B,38,5E,16,1E,5B,8F,F7,44,D9,E7,51,3B,52,7B,80,00,00,00,A0,50,10,22,D9,25,1B,9A,35,B5,07,09,37,BF,B8,C1,00,00,00,00,66,82,DB,B4,0B,2A,3D,03,59,86,9B,A6,0C,A5,B3,D1,00,00,00,00,FF,8D,08,B7,35,88,A1,2E,E9,65,A7,51,C0,11,61,AE,80,00,00,00,C7,8F,7C,B9,A4,F0,87,48,EF,C0,99,17,54,B5,54,1A,00,00,00,00,23,74,06,81,AB,BC,2A,16,E1,0D,A9,14,40,4E,99,48,80,00,00,00,E1,B4,B5,16,39,E9,CD,4F,D2,51,12,1D,00,85,9A,5A,80,00,00,00,86,F0,E0,6A,55,04,39,FA,EC,B5,D0,01,B6,B3,17,92,80,00,00,00,9B,D6,80,7C,FE,87,4D,D7,53,74,17,92,69,0D,52,2B,00,00,00,00,F9,DA,79,2E,1F,09,F9,3C,91,EE,59,5A,C6,EF,F5,D1,00,00,00,00,6B,6C,42,50,59,DB,86,1C,7C,87,56,50,68,42,95,AD,00,00,00,00,05,4F,39,0A,80,25,CF,3B,27,CE,B6,DC,72,2D,B1,EC,00,00,00,00,08,DC,F9,4F,1E,08,87,CB,44,E7,A2,22,03,04,A6,79,00,00,00,00,06,63,5D,A4,D6,9C,9D,0C,31,CA,94,E9,47,9E,09,F4,00,00,00,00,91,B2,13,9C,5D,A5,80,41,9F,B9,EF,B9,DC,C8,DD,45,00,00,00,00,32,35,80,81,98,5B,BE,BB,C8,E8,AC,9D,88,CC,75,3A,00,00,00,00,1D,1B,B3,54,AE,D0,38,EE,74,3D,7B,82,D7,1F,32,6D,00,00,00,00,45,DE,D0,8E,93,63,82,AD,9B,6A,B5,94,81,7F,47,02,00,00,00,00,8B,70,13,E9,67,7E,A8,1B,93,2A,F3,EE,65,6E,16,53,00,00,00,00,21,F6,9D,28,F8,0A,DF,9D,69,9A,55,6A,B9,85,2A,62,00,00,00,00,40,CF,E4,1F,E7,53,AC,A1,2D,00,D9,96,33,46,92,CF,00,00,00,00,0F,27,13,91,36,DC,3D,55,22,2A,12,09,40,77,EC,8D,00,00,00,00,D2,B0,5D,3F,BA,86,3B,18,AC,86,4F,ED,66,47,17,A0,00,00,00,00,F7,7C,9A,4F,73,9D,11,F3,A6,3A,52,E7,8C,4A,06,FB,00,00,00,00,D5,5B,51,9A,2D,0F,4B,97,B9,B7,10,2E,63,FA,9A,E9,80,00,00,00,FF,81,04,40,58,28,F7,E7,97,7F,12,E6,B4,97,33,DB,80,00,00,00,E0,25,27,16,A4,9A,91,A3,08,7C,A4,09,BB,8A,74,52,00,00,00,00,E1,E7,CE,F8,7B,0A,03,7D,42,9E,89,08,C6,B9,1A,93,00,00,00,00,2F,BD,88,0F,DE,91,F5,4E,1C,AB,6A,8B,CB,25,7E,A7,00,00,00,00,4B,30,E4,54,83,66,4E,D5,91,C9,BF,1D,44,65,93,76,80,00,00,00,B5,10,06,33,18,46,72,D3,8B,8C,D6,F1,9F,5C,AD,14,00,00,00,00,EC,4F,17,00,8A,C3,B8,0A,D2,4A,0D,21,1D,CD,06,C0,80,00,00,00,57,B8,E8,38,97,AE,52,18,64,22,3E,06,35,D5,7D,F6,80,00,00,00,74,A9,92,CC,07,6F,97,73,12,F0,FE,E7,18,33,DE,8D,80,00,00,00,2B,AF,69,44,12,87,57,31,93,86,07,C8,6A,23,1F,41,80,00,00,00,59,55,1D,80,72,7A,A6,F5,7A,9C,97,A1,23,38,60,18,80,00,00,00,5B,BA,17,24,01,56,44,75,4C,F1,DE,96,7B,C0,70,E5,00,00,00,00,F3,E5,0A,31,44,51,B2,D0,01,D1,6D,21,95,B8,0B,79,00,00,00,00,E9,2B,46,F6,42,BE,65,B0,8C,A4,0C,3B,DB,FB,AC,66,00,00,00,00,1C,31,04,C6,C9,B8,E2,A2,4B,9C,64,3D,3C,C9,6F,B6,00,00,00,00,E0,A7,D9,8B,31,76,54,97,26,9A,FF,E3,61,21,0A,D1,80,00,00,00,49,38,0C,7E,6C,E6,75,31,63,9F,27,2B,B5,67,CB,57,80,00,00,00,F4,10,B7,3C,11,9F,F2,49,20,66,0F,43,F0,ED,5B,C9,00,00,00,00,A3,90,06,5B,64,C9,FE,44,39,23,22,06,E2,9F,11,9B,00,00,00,00,0D,0A,1E,86,24,CE,75,BE,92,DD,5E,1A,2A,2B,CF,68,80,00,00,00,1F,F3,52,ED,ED,84,D3,EB,8E,FB,CE,E1,03,A2,A0,64,00,00,00,00,24,B0,80,CC,B2,31,E6,43,04,DA,0F,42,5E,CE,2D,D8,00,00,00,00,EC,79,6B,14,75,91,9E,D8,F9,A8,97,8F,0D,17,C0,D6,80,00,00,00,06,8F,BD,D2,04,9E,A0,1D,B1,62,D9,40,88,8B,01,D1,80,00,00,00,20,E9,4A,9F,1E,45,0F,5A,B5,A7,18,1E,8F,D2,5F,D7,00,00,00,00,8F,2D,B9,8E,A5,E0,45,D4,C5,3A,3B,F8,59,D1,E8,BC,00,00,00,00,6E,B8,64,B6,48,B3,B7,AF,31,2D,7E,C8,14,92,89,2D,80,00,00,00,0E,B2,4A,59,4D,F6,50,3B,E2,93,7E,BB,F4,5A,99,8A,00,00,00,00,6F,3A,9E,4C,8C,FC,2D,A4,B2,DE,17,CD,46,88,70,3E,00,00,00,00,F4,62,16,37,86,53,26,F7,0D,B7,63,95,77,4A,4D,48,80,00,00,00,ED,2C,2E,AF,21,10,A1,85,04,19,05,E0,DE,0E,DD,DA,80,00,00,00,58,C8,29,B5,77,38,AF,D5,8C,A9,95,BF,11,7A,06,23,80,00,00,00,D2,14,09,35,31,2F,3D,D4,37,0C,FA,D4,69,8E,7D,D5,80,00,00,00,F5,43,19,4F,46,41,38,D6,5E,AB,70,95,4B,D6,E6,74,80,00,00,00,DC,BE,16,E1,C4,06,72,B7,4B,EB,F2,6F,B5,FC,4C,7C,80,00,00,00,85,64,61,99,01,84,DC,75,5B,EA,CE,9E,64,BA,1E,58,80,00,00,00,9E,D4,E0,95,1B,B4,09,33,3F,7B,7E,E7,F7,0A,23,80,00,00,00,00,78,8E,EB,EE,17,18,C6,2C,42,5A,92,33,79,79,6B,E6,00,00,00,00,12,8B,B4,EA,83,7E,D0,D7,1A,F9,DF,39,E0,A1,FD,02,00,00,00,00,0C,D1,68,CF,6C,B3,42,8E,D5,15,36,0F,FB,A4,68,03,80,00,00,00,F7,95,A3,A9,B3,15,96,45,C3,6A,66,3C,E1,4C,E9,F7,80,00,00,00,34,F7,1B,36,58,E1,44,58,DB,70,3B,40,B6,B1,12,17,00,00,00,00,90,DA,57,F2,EF,01,6C,5C,A1,E0,C5,1D,8E,7A,4D,E8,00,00,00,00,7C,95,36,C8,09,9E,1E,01,00,D7,5C,CC,7E,78,DD,00,80,00,00,00,EB,CB,81,AD,87,D3,8B,33,F7,23,2C,13,FA,BE,D0,90,80,00,00,00,75,5E,29,17,E6,C1,E1,86,FA,72,FE,3E,EC,29,62,15,00,00,00,00,5E,24,87,5B,AE,F9,2B,94,E8,E2,9A,E2,F1,05,05,F2,00,00,00,00,6F,4B,70,64,B9,EC,CF,52,E9,F0,E1,C2,6F,9A,ED,70,00,00,00,00,2C,3A,7F,78,1A,11,BD,6D,2F,44,CB,FE,12,C6,6A,1F,80,00,00,00,C4,25,AF,60,EB,95,4D,2F,62,54,06,6D,AA,6B,5D,D4,80,00,00,00,5E,22,F3,07,C1,75,21,FD,0E,B0,BF,7A,CB,96,0B,FF,80,00,00,00,2F,6D,17,C2,6E,D8,9F,5B,88,96,2A,4C,8C,92,04,1D,80,00,00,00,29,4D,38,A2,4D,1A,29,FE,38,4C,37,B8,56,48,F9,E4,00,00,00,00,AF,15,B1,50,36,B7,8E,08,27,CB,73,5E,C6,62,2D,63,80,00,00,00,83,36,83,66,09,DC,5A,6C,15,88,58,CB,4B,7E,B3,43,00,00,00,00,76,67,6D,26,0F,5F,DC,F0,5C,34,58,45,CD,0B,D2,97,80,00,00,00,34,A5,1C,96,70,40,FF,81,A6,49,E9,A3,28,C8,88,7B,00,00,00,00,B7,58,41,07,D6,46,22,79,62,5A,F3,A6,36,80,50,10,80,00,00,00,52,42,85,9A,74,B4,DE,E0,8E,F1,A4,CF,14,8B,BB,7B,00,00,00,00,4F,8C,DB,F7,24,42,9F,1C,41,9E,E0,9A,1A,14,89,F0,80,00,00,00,2D,FB,B3,1E,CC,FD,07,A3,BA,86,28,49,50,97,43,09,00,00,00,00,8B,14,73,C3,AB,78,40,97,99,2C,3F,FB,4B,FF,68,5C,80,00,00,00,C0,BD,09,8C,B8,D5,B0,B6,8F,01,D9,C2,B8,9B,77,91,00,00,00,00,BD,46,70,20,17,4B,59,2E,14,F3,93,B5,B9,BB,35,C7,00,00,00,00,9B,56,B3,C9,05,7B,96,A6,35,4A,FD,0D,42,07,06,84,00,00,00,00,19,CD,DA,47,F3,77,EA,72,5F,4D,08,D2,96,8E,09,32,80,00,00,00,04,68,BA,46,D8,BC,EB,CD,14,39,C0,F9,DA,F6,65,1D,00,00,00,00,F7,18,AF,04,B4,8E,A8,5B,79,C4,6A,51,93,59,26,86,00,00,00,00,F9,F0,25,11,E8,68,DF,4E,7B,7F,55,F0,D9,3C,70,34,80,00,00,00,E0,20,F9,CA,28,F2,35,E1,5E,BB,72,17,C4,14,1C,0C,80,00,00,00,E5,65,B3,E9,51,D3,3A,3D,B1,9E,17,43,A3,03,69,BA,00,00,00,00,B5,0D,3C,86,C4,66,10,0A,3E,47,DF,E9,3F,9B,B5,82,00,00,00,00,30,C5,7A,CD,28,2F,EC,8F,8D,D6,54,9F,7A,BC,CB,FD,80,00,00,00,AC,58,B9,02,F3,4E,E4,33,87,7C,2F,2E,FA,18,F7,F3,00,00,00,00,49,C5,68,C5,72,FA,1F,B0,CD,14,C9,E7,74,15,5E,22,00,00,00,00,CE,79,B8,1F,04,BD,FA,ED,01,B6,CB,80,AB,B8,42,FA,80,00,00,00,33,98,33,10,7D,7B,2B,C5,33,6B,7B,1B,7C,71,6C,5C,80,00,00,00,F9,A9,35,93,8C,A0,F3,64,33,C8,03,66,8F,22,0E,23,00,00,00,00,93,C5,D4,5E,B0,63,01,A8,31,4E,10,60,7D,2F,7A,8B,80,00,00,00,DE,EF,61,46,77,E7,60,04,80,06,6F,78,A3,00,8C,1A,80,00,00,00,88,87,43,58,C6,1D,E3,02,DC,3F,E3,3F,90,B0,36,98,00,00,00,00,BF,D4,FE,E4,21,00,A4,96,42,8D,A5,43,A2,13,E5,BF,80,00,00,00,A2,BD,75,D6,B6,93,2B,90,48,19,87,53,EF,5D,76,E6,80,00,00,00,11,41,97,E1,10,9F,78,31,9F,24,2E,57,EA,6A,86,AD,80,00,00,00,24,08,C7,0B,A8,49,6E,4F,1B,3E,2F,6F,CB,F7,11,29,00,00,00,00,70,3C,BF,3D,80,EB,67,53,94,84,BC,93,95,CA,83,84,00,00,00,00,1C,8D,4D,2C,38,87,41,79,A5,F5,AE,D5,74,74,88,85,00,00,00,00,68,2A,0A,B4,4E,B0,E6,C4,12,FC,F9,41,0A,C1,37,1C,00,00,00,00,87,AD,F9,61,41,7A,A7,6F,A0,21,12,4F,2C,A3,58,FD,80,00,00,00,5F,9D,6E,3B,CB,F4,C0,B8,6B,71,24,80,EA,AE,CD,AD,00,00,00,00,2D,AB,2C,97,C7,8C,B2,E4,61,18,59,7E,21,51,61,04,80,00,00,00,87,08,A7,A0,10,CB,08,B2,0E,30,25,89,D8,9B,73,56,00,00,00,00,E9,F0,5F,DA,96,A8,9E,DB,E5,FF,C2,07,33,D4,84,E8,00,00,00,00,13,27,BD,1B,6A,1F,5F,27,67,A3,3A,F3,D1,5A,B1,B4,80,00,00,00,08,C4,55,51,48,93,D5,DF,38,53,09,33,51,7F,A4,0D,00,00,00,00,93,63,4A,3C,98,FD,98,39,12,18,3A,59,22,CC,D8,3C,00,00,00,00,26,7F,16,86,64,6D,B5,52,F9,21,CF,B3,BC,B6,0F,66,80,00,00,00,2F,82,72,6B,14,95,8F,99,7C,23,68,4C,E9,54,79,62,80,00,00,00,F1,AC,A1,56,F0,29,A6,7E,7E,72,D1,53,AA,12,69,CB,80,00,00,00 -linearMatrices_inv = 0F,F1,DD,2A,69,B4,E7,04,34,05,EC,A7,F5,A7,2B,C1,00,00,00,00,D9,96,B9,7E,33,6F,81,18,23,0B,92,80,4F,D2,66,8A,00,00,00,00,CD,2B,10,1C,CF,CE,A6,E4,77,A2,03,37,76,00,65,5B,80,00,00,00,CE,80,18,30,B9,09,66,36,B4,A0,F8,7E,85,15,92,8C,80,00,00,00,E1,30,81,F1,85,B1,F7,9A,45,4E,9F,BC,8C,41,31,67,80,00,00,00,AF,A4,9F,4D,E5,11,ED,74,19,69,0E,0F,B1,EC,C6,C5,00,00,00,00,B0,F5,56,72,F5,11,3D,57,23,FD,61,B8,93,F8,2B,51,00,00,00,00,16,FA,3A,F5,65,12,21,B4,29,C6,0A,EA,D9,CA,8A,0A,80,00,00,00,3F,D5,7E,D4,85,41,D0,2E,AA,84,F5,83,27,71,AE,12,00,00,00,00,AE,44,76,57,07,B9,0C,DC,A3,A9,1E,14,B8,46,33,50,00,00,00,00,BA,01,7A,32,3F,59,0F,30,61,FD,B7,AF,7E,3B,BA,AA,00,00,00,00,25,32,FF,AB,A3,A1,DD,48,90,B6,9D,E4,72,A6,A7,4B,00,00,00,00,0C,C0,F4,BB,53,0C,A9,B8,CF,0E,76,44,42,A9,CC,A4,80,00,00,00,55,3B,62,7E,1F,57,1E,DD,CE,CB,7F,D6,9B,4F,D8,6E,80,00,00,00,B3,A0,6D,7C,55,CF,F8,08,F9,9B,BB,31,CA,99,DC,91,00,00,00,00,BC,95,D6,09,7C,54,FF,0E,4F,FB,44,02,AF,D6,E0,3C,80,00,00,00,68,3C,45,98,3F,AA,37,00,72,23,49,6C,42,F5,8C,E9,00,00,00,00,3C,BF,CB,50,A2,42,D5,05,2B,6D,C1,8D,1F,D3,37,A8,00,00,00,00,64,32,F2,AB,7F,A1,C4,B2,79,A5,A2,02,DD,8A,B4,76,80,00,00,00,30,44,C8,A8,A7,E2,2A,2E,57,37,2E,35,AF,CA,6F,29,80,00,00,00,B4,B5,3A,A0,9F,5A,E8,05,E1,81,8E,B5,B5,17,E3,CF,80,00,00,00,2C,53,78,46,49,C9,4E,02,9A,1B,8E,EA,72,08,A9,C5,00,00,00,00,4C,6E,F2,5B,B4,4F,FF,4C,E6,A2,86,3E,57,56,CD,DE,80,00,00,00,49,B8,0E,BF,69,80,A0,6C,F2,86,DF,16,FF,65,22,21,80,00,00,00,F9,8F,8D,27,54,8A,D9,A8,5C,5B,62,9A,68,FA,EB,16,80,00,00,00,E8,28,79,03,8F,A7,69,8B,66,43,08,F8,12,0E,1E,16,80,00,00,00,90,E0,E9,A8,55,89,05,F7,00,C8,71,9F,94,DC,01,02,80,00,00,00,14,B1,0F,DD,F8,53,DB,14,2B,EF,8D,DF,72,58,BF,D0,80,00,00,00,A8,99,58,19,61,6B,F5,B1,39,74,14,B0,E7,A8,0D,60,00,00,00,00,DB,1A,03,09,FF,3E,ED,86,76,40,08,CB,3F,D4,72,BC,80,00,00,00,3E,51,C7,29,4B,43,7A,A6,D5,EA,66,B4,CC,7D,94,56,80,00,00,00,5C,02,64,E1,23,E9,B3,18,EB,8E,97,0E,8C,72,94,35,00,00,00,00,22,58,FF,2D,97,25,65,2C,3A,A2,14,29,9F,46,F1,FC,00,00,00,00,AC,E4,86,28,33,AE,D4,14,CF,D5,FB,1F,5B,4B,16,5F,00,00,00,00,71,88,CE,23,F7,90,4C,27,C6,2F,92,CD,77,F4,7B,22,80,00,00,00,49,39,FE,43,BE,3A,2D,8B,73,DA,5A,D9,61,EE,29,66,00,00,00,00,52,22,16,0D,7D,EE,D6,7D,B1,06,7D,7A,EF,C2,9A,8D,80,00,00,00,73,2A,CA,4C,1A,55,6B,72,24,74,0C,5A,3A,FA,80,A3,00,00,00,00,36,44,AA,01,FC,48,5E,5A,4C,C7,3B,97,C5,0B,26,D7,00,00,00,00,DF,39,A2,94,DD,96,64,B9,85,DB,BD,B9,26,1C,99,72,00,00,00,00,E6,C1,3D,87,F4,DC,51,76,C5,A6,E0,79,38,01,D8,24,80,00,00,00,36,36,73,5E,7A,F2,7D,6A,EB,ED,27,C8,C2,E2,73,CF,80,00,00,00,4A,7E,2D,6C,7E,77,19,30,38,0C,DE,A9,BD,B0,FB,46,00,00,00,00,61,3E,23,23,EB,BB,6D,F0,10,4E,C4,F1,4D,1D,CE,6D,00,00,00,00,29,32,8D,44,77,AE,D3,10,7B,6E,98,25,7B,94,75,5F,00,00,00,00,72,9C,15,B0,CC,82,99,50,5C,4C,16,E1,97,03,5D,C2,00,00,00,00,35,B3,B1,B4,25,1D,10,80,73,24,3C,56,63,B4,72,21,80,00,00,00,67,FA,E4,F1,99,0B,69,B7,63,41,9A,BF,EE,1B,50,B9,80,00,00,00,33,36,B4,7B,4A,49,DC,C4,40,CD,C4,31,17,AE,F7,6E,00,00,00,00,62,C0,7A,EA,CF,2F,AF,27,1D,68,A5,6C,CC,E3,DE,EC,00,00,00,00,6D,C8,01,49,FA,57,E4,02,E1,B8,1E,4A,06,F4,17,D3,80,00,00,00,7F,38,4B,D1,E6,E9,B9,45,93,1D,92,78,CE,93,E3,44,00,00,00,00,08,E8,8C,5B,A3,37,A6,5D,C7,A3,DE,E2,29,94,02,AA,80,00,00,00,46,0C,2A,08,C2,E6,E4,D8,30,06,36,E3,E2,FB,AD,21,00,00,00,00,51,DB,79,DF,48,A6,7A,8F,28,05,41,3B,59,98,22,17,00,00,00,00,1E,72,5E,55,B3,61,22,A7,D7,34,1B,9E,1B,27,33,D3,00,00,00,00,C7,E0,00,77,F8,45,3B,2F,5E,83,A5,6E,FD,4E,FC,CE,00,00,00,00,8B,40,FB,1E,E4,5D,A6,29,99,93,71,51,44,07,5B,CE,00,00,00,00,20,F2,4A,E9,C7,72,BB,A7,56,61,BC,4E,82,E9,5A,1B,00,00,00,00,B2,41,A8,54,E2,E5,3B,5B,94,D8,85,A6,5E,3A,10,7A,80,00,00,00,73,71,1F,D6,C2,43,45,A6,F2,00,DD,F8,A0,A7,77,A8,80,00,00,00,5D,56,3C,7C,64,7C,58,C0,00,45,C3,E0,2A,05,98,DE,80,00,00,00,22,E1,5B,8A,2D,62,29,38,A3,7D,2E,50,83,97,AD,DF,00,00,00,00,89,95,8D,3F,88,A9,03,A0,93,43,09,0E,D4,4D,06,2C,00,00,00,00,ED,9C,4E,2C,33,B7,85,EE,52,B2,07,B0,39,6C,30,CE,80,00,00,00,6A,D3,15,7C,16,F5,4C,D4,B5,CA,2C,2C,1B,2D,EC,C8,00,00,00,00,4A,0B,CE,99,65,B3,FF,16,9D,8A,1C,06,2E,6B,03,B9,80,00,00,00,2B,CE,94,0A,E3,81,3C,F7,E9,40,DD,1F,AF,D1,3D,F7,00,00,00,00,D3,99,2A,EB,E0,8D,E6,7F,27,38,2E,2A,59,DA,8D,D5,80,00,00,00,17,27,68,28,7C,97,1A,BD,73,0C,E7,81,C5,05,22,75,00,00,00,00,E5,4E,13,F8,30,0A,81,EE,EF,1A,86,74,FE,B7,DD,73,80,00,00,00,1C,F3,49,94,F5,1B,29,02,C2,4E,0D,F1,33,7F,ED,70,00,00,00,00,F8,F2,4B,1F,41,27,03,5B,50,C3,3C,86,55,93,8E,4E,00,00,00,00,2F,61,F3,BC,4C,25,21,B2,1E,90,7B,42,C3,FB,EB,12,80,00,00,00,7D,47,60,56,B1,82,85,D5,BD,C6,AD,4E,B6,56,20,F2,80,00,00,00,BF,1F,0D,4E,4B,B8,FB,AE,4D,C7,A8,1E,CC,7A,35,01,00,00,00,00,75,66,F4,45,39,67,2A,E0,82,6F,91,B5,EF,20,F6,FE,80,00,00,00,7A,E0,C7,50,2E,51,80,71,EA,B1,8E,E6,BA,3F,54,7B,00,00,00,00,BA,82,A9,31,D6,C8,5F,45,ED,12,51,76,70,84,8F,3B,00,00,00,00,E4,F9,FA,F8,A9,8B,B3,D2,81,D7,8A,35,14,DA,B9,1C,00,00,00,00,CB,C3,59,BF,A6,0C,CC,C4,DD,B9,2D,39,29,1D,9B,65,80,00,00,00,4A,FF,8C,71,7E,31,F3,1B,2D,98,18,5C,BC,E7,4F,31,80,00,00,00,42,02,EF,7A,E3,C1,AB,3E,F4,16,81,2C,79,14,67,B5,00,00,00,00,D0,16,40,34,3B,AA,80,73,FE,CF,36,8C,0D,6A,29,54,00,00,00,00,5A,84,B8,7B,D9,A4,1B,2B,7C,66,10,47,9E,12,31,3A,00,00,00,00,E4,14,20,63,51,AF,96,20,AA,64,23,98,7F,17,37,C0,00,00,00,00,9F,7D,A2,60,02,27,B3,26,ED,5C,88,20,BE,97,74,23,00,00,00,00,52,30,E0,F1,BD,A2,A7,51,02,E7,F4,B6,56,6D,62,47,80,00,00,00,B7,FC,62,B0,1C,16,0F,57,B7,DA,C6,AA,DD,DE,8D,9D,80,00,00,00,4B,08,97,DB,18,81,7F,FD,41,CF,44,07,32,D4,EC,FB,00,00,00,00,5C,2C,76,2A,F5,15,E4,5E,2B,FF,10,CD,24,55,32,29,80,00,00,00,3D,92,3F,DD,9F,47,AA,90,41,FE,00,C4,2F,45,DF,F1,00,00,00,00,D8,1B,16,91,44,FF,85,C7,7E,D3,A2,86,7C,2B,54,A6,00,00,00,00,2E,F3,C1,2B,8D,BF,23,25,CB,6F,18,59,E1,E8,2C,9D,00,00,00,00,A3,20,97,80,5C,E8,29,B3,3D,00,1F,F8,A2,21,51,EC,80,00,00,00,C7,8C,16,25,0D,C7,61,EB,FB,90,06,2F,4D,1A,1F,65,80,00,00,00,F6,9D,B6,53,D5,0D,8C,C6,BB,FC,6F,39,D8,53,AD,EF,80,00,00,00,09,0B,B8,4C,67,0D,54,69,AA,67,A8,B5,7E,05,49,22,00,00,00,00,31,EB,53,8F,F0,FE,E1,F1,9D,61,05,E1,5E,98,3F,A9,80,00,00,00,E3,2A,38,A9,E4,BB,B8,AE,76,B2,54,C3,1B,7C,0E,8F,80,00,00,00,F8,FA,6D,B2,D1,B3,46,26,DA,E4,36,DE,C4,BC,E8,28,80,00,00,00,D7,44,FF,DC,06,CA,22,99,50,38,16,44,7B,4A,45,5B,00,00,00,00,C5,44,21,FD,F2,E9,5F,DF,23,76,86,4A,E4,94,FC,80,00,00,00,00,6A,DF,74,39,0C,C7,BE,2B,13,F5,D7,9E,CF,2E,AB,28,80,00,00,00,E4,71,FD,31,CB,0A,8B,4E,72,9B,A0,80,6D,9B,B0,CB,00,00,00,00,11,CD,6A,B1,59,66,77,58,9F,94,6D,7D,A4,35,2A,DF,00,00,00,00,21,19,DD,3A,7B,F5,1B,26,6C,90,70,85,9E,F4,55,8C,00,00,00,00,74,6B,92,33,28,C6,D3,DD,08,80,F5,80,1F,A0,48,49,00,00,00,00,51,B0,88,19,9F,4C,AB,6D,0B,7D,79,A6,3F,11,7F,20,80,00,00,00,E4,55,40,ED,CD,6E,5F,9E,39,40,49,F6,A6,56,25,12,80,00,00,00,3A,8C,F3,EB,84,80,9C,24,B9,1A,7B,C5,CD,94,5D,1A,00,00,00,00,A4,3C,E8,EF,89,98,FF,11,86,33,2B,58,DF,D6,7F,85,00,00,00,00,F6,EE,02,DE,F2,50,FA,54,D6,05,7F,21,EC,C9,D0,12,80,00,00,00,C6,B4,8A,84,AD,1B,4A,8A,FD,DD,73,87,39,64,E7,21,80,00,00,00,E5,5A,E1,F2,F3,B6,80,B5,4B,55,5E,D2,26,F4,A7,4C,80,00,00,00,4C,AC,4B,8D,AB,F6,3B,66,CF,94,09,40,5C,16,08,80,00,00,00,00,EF,44,CB,EA,0D,E3,45,75,6C,3E,31,05,08,D1,2B,A1,00,00,00,00,0D,20,8C,5C,E1,FF,4E,5B,B1,D5,25,ED,AC,8B,D9,EA,00,00,00,00,4B,36,49,08,C7,E1,F7,A6,90,77,0B,4B,FB,B5,16,EA,80,00,00,00,ED,A8,A5,8B,B5,09,E3,8D,A3,D2,B6,CB,5F,39,6A,B1,00,00,00,00,1A,1D,35,61,6E,A6,67,EE,06,E4,B4,C7,30,99,78,98,00,00,00,00,E6,5A,79,1B,A6,44,33,E4,07,9A,05,BA,CE,A3,E9,0F,00,00,00,00,72,A3,CE,D6,E6,20,4F,C2,0B,15,6D,40,D4,38,B9,15,80,00,00,00,EF,B6,74,CF,B1,E3,3B,9B,B2,91,55,CD,97,7B,98,6B,80,00,00,00,0D,3B,82,69,FA,0C,95,07,8A,10,DD,6B,23,13,09,28,80,00,00,00,5E,B4,A2,FF,DB,11,F9,A6,27,56,A0,76,28,F8,72,41,80,00,00,00,8D,29,28,48,BE,36,FA,FE,14,EB,22,66,63,89,3D,C9,80,00,00,00,8E,54,8E,37,37,22,2A,B6,6F,65,EC,9E,79,F7,8F,BA,80,00,00,00,0B,56,B0,CF,47,E5,DB,5F,97,81,B0,FD,EB,E0,9A,A3,00,00,00,00,6F,F1,D1,BA,37,81,3C,2E,08,0F,A8,AD,B9,1A,93,7F,80,00,00,00,AC,B5,27,15,CD,A1,52,5D,77,F9,0A,ED,D2,1B,EB,F1,00,00,00,00,80,83,54,D6,7D,A9,BA,C5,46,B2,27,3A,DA,27,65,09,00,00,00,00,33,4F,74,DA,BF,F4,B4,6A,88,E5,52,10,6D,0D,51,54,80,00,00,00,F7,5C,86,91,99,F2,12,E0,2B,DC,81,36,58,B8,FC,D3,80,00,00,00,B7,D1,7C,46,51,15,D6,8C,70,04,10,9B,C9,54,E4,6F,00,00,00,00,6A,9C,7C,94,AA,5D,DD,7C,21,0D,00,B2,47,1B,12,58,00,00,00,00,A3,CD,56,77,69,0A,35,0B,33,41,87,AC,6E,EF,DD,B3,80,00,00,00,2F,04,BC,32,D3,29,50,8D,9C,A6,A5,B5,4B,0B,5C,0F,00,00,00,00,D7,46,E1,B2,7E,DA,CE,5B,C3,D5,59,42,A0,DA,4F,B0,00,00,00,00,5A,39,DD,97,D4,2E,1F,E4,68,DA,3D,1F,2F,54,86,68,00,00,00,00,24,3F,7A,55,59,47,2E,64,A0,52,F5,9F,01,FD,E0,0C,00,00,00,00,6D,C6,E6,81,1E,DE,1D,A5,A9,E1,CB,31,C0,E2,BE,9B,00,00,00,00,8F,C6,A6,5B,47,94,48,4A,E3,51,EA,41,68,C4,8F,59,80,00,00,00,55,0E,5B,C8,76,F4,E4,19,C2,7A,83,A6,09,90,2F,8E,00,00,00,00,10,3D,AA,11,EB,E0,2E,DA,30,C3,07,55,BD,0D,14,23,80,00,00,00,13,7B,C9,DF,F2,84,B0,33,AE,8F,9C,EA,3B,C0,D3,40,00,00,00,00,6E,08,0E,70,D1,73,CB,A8,E0,90,8A,8F,30,30,A7,18,00,00,00,00,F7,6C,5C,69,07,87,E4,7B,18,4F,FC,2C,44,72,C6,D4,80,00,00,00,0E,E8,E5,84,6F,25,5F,A9,AD,82,DC,E7,25,59,BB,BC,00,00,00,00,A5,A0,33,F7,89,AD,3A,27,A7,FE,A3,A2,58,C0,ED,FD,80,00,00,00,01,A6,38,48,08,85,00,3A,DF,95,85,FC,57,D6,83,C9,00,00,00,00,F5,DB,8B,5C,28,B3,23,EF,12,BF,A0,B4,7D,84,A0,13,80,00,00,00,F8,36,48,6F,48,48,FF,08,F9,D8,7A,BE,81,15,3D,09,00,00,00,00,C1,3D,F6,A4,58,ED,0E,4B,49,F7,34,EC,DA,61,A7,03,00,00,00,00,7F,7A,AA,ED,16,C2,D4,D0,AB,15,02,CA,9F,E7,4F,3A,00,00,00,00,02,90,91,41,CD,F1,A8,B4,E3,85,20,2E,70,68,75,0D,80,00,00,00,76,BB,4C,DA,C0,83,39,FD,AE,04,84,8C,8A,25,C8,36,80,00,00,00,AF,A9,81,FA,5A,4D,B1,FA,94,07,4A,78,F2,D1,7F,63,00,00,00,00,72,5B,88,72,CD,93,DD,69,DE,3C,81,27,D2,17,BC,6E,80,00,00,00,1F,34,C6,84,F7,4A,CF,57,BA,34,D7,D1,18,F4,4D,19,80,00,00,00,63,8E,D8,A1,A3,7C,45,71,A9,0B,D3,DE,6E,17,F5,2E,00,00,00,00,68,8F,77,09,16,81,5A,5D,01,38,71,82,41,AA,E2,CF,00,00,00,00,1D,AC,AA,5E,E4,DA,59,0D,20,55,F9,98,7A,CA,AC,56,00,00,00,00,12,D5,E1,B6,CE,8F,68,1B,D3,2C,35,55,5B,6A,F4,F4,00,00,00,00,87,1C,9A,62,05,1B,41,7D,0C,4F,DB,9D,7F,07,3A,C3,00,00,00,00,5B,89,54,1E,2D,47,DC,94,97,B7,26,31,B2,A7,AD,9C,80,00,00,00,48,0A,D2,64,4D,14,03,26,21,87,05,C1,00,C6,4A,35,80,00,00,00,C8,50,21,CD,93,7C,67,8D,FA,4D,92,21,03,6E,7B,CA,00,00,00,00,4D,4C,E9,81,9B,B9,27,66,EC,BA,0D,E3,D9,C6,65,CC,80,00,00,00,C2,21,CD,0C,56,87,3A,EA,82,30,59,9E,A6,B1,0E,A7,80,00,00,00,5F,E2,17,44,83,83,87,B2,3A,A1,04,A3,B0,F9,6A,9B,00,00,00,00,31,D3,7A,38,DB,0D,B9,CB,8B,95,4A,0B,2E,8A,53,59,80,00,00,00,26,5B,84,88,49,8B,20,AA,F9,DF,AA,AF,6F,98,7E,97,80,00,00,00,5B,DA,BE,0D,EE,42,F7,48,1A,5C,3D,4F,D2,D6,D3,9E,80,00,00,00,CC,B2,68,C5,A9,A3,0E,22,49,36,A7,70,89,A9,56,04,00,00,00,00,51,EF,8B,8F,93,1A,71,1C,18,02,96,A2,B7,9C,12,37,80,00,00,00,A3,DE,2D,00,77,7D,AF,A3,D3,97,8E,71,AE,D5,47,4B,80,00,00,00,ED,7D,B5,46,4B,04,8D,64,43,CC,A5,CC,54,A7,AB,C5,00,00,00,00,2D,35,32,66,69,5C,20,A2,C1,67,6F,24,6E,4A,9F,7D,00,00,00,00,6F,2E,85,E6,ED,30,80,61,CB,15,92,5C,44,2A,6B,A3,80,00,00,00,0C,2D,4B,94,D2,B6,6F,E6,DC,7D,92,C5,B4,CA,7A,EA,80,00,00,00,FF,20,2E,2C,9E,A2,15,4D,2F,A7,06,72,09,A8,19,D3,80,00,00,00,1D,14,4D,47,E2,CE,8F,95,55,0D,3E,18,40,37,97,87,80,00,00,00,5D,38,89,65,73,AF,28,3A,7B,6E,60,DD,F5,68,ED,69,00,00,00,00,09,A4,F4,51,81,62,11,BA,A4,64,93,E3,81,44,4E,BE,00,00,00,00,C5,95,43,61,41,6F,79,4A,01,D0,D3,53,72,D0,E8,12,00,00,00,00,B1,A4,94,E3,35,C1,DC,02,DD,A5,9D,3E,10,31,E1,A5,80,00,00,00,2F,AD,A9,32,C5,4F,C2,44,CE,7F,D5,03,38,A9,75,D8,00,00,00,00,70,69,EF,8C,EA,42,28,01,0F,EF,D9,48,C8,B1,19,6C,80,00,00,00,C7,1B,BB,E1,06,06,DB,C2,C6,6F,5C,6A,32,F8,FD,76,80,00,00,00,53,61,E7,A2,01,0E,A9,91,C9,DD,99,B2,5E,66,E8,CC,00,00,00,00,20,36,DF,B4,34,26,8E,0A,CB,D5,3A,5C,9D,66,43,89,80,00,00,00,39,E6,83,45,3F,82,A1,EB,F7,B0,B9,3A,3B,E3,E0,72,80,00,00,00,E1,74,6A,48,A5,77,B0,B9,21,B8,D0,05,88,44,B4,07,80,00,00,00,C1,0B,5A,F1,85,30,00,A7,9A,2D,59,5D,74,DE,28,8B,80,00,00,00,DF,42,C6,1C,8F,73,08,D4,0F,AB,42,E3,2A,B2,D4,BE,80,00,00,00,AA,F6,83,15,42,55,57,E0,53,4B,8E,0E,0A,64,5E,FF,00,00,00,00,45,19,ED,C8,62,B2,05,4E,66,E2,24,41,92,58,E7,02,00,00,00,00,57,AA,79,97,8E,5D,90,51,EC,D5,7D,24,66,49,45,37,00,00,00,00,CB,EE,E3,E5,24,FF,86,B2,0D,25,0A,90,C5,8A,B4,C3,80,00,00,00,95,25,ED,6F,BF,88,19,B4,35,80,D3,90,B6,9D,4F,39,80,00,00,00,1F,43,EE,91,25,21,4D,6F,67,19,2E,50,D3,CE,78,14,80,00,00,00,27,D2,98,78,A3,BE,8F,74,AC,8C,DB,12,8B,45,D4,B5,00,00,00,00,DE,8E,2F,94,12,6D,4B,66,25,1B,C3,06,C6,E9,BC,22,00,00,00,00,B2,DA,B9,ED,39,0B,03,A3,2F,DB,B0,4D,33,33,F0,9A,80,00,00,00,0C,A2,D5,22,57,05,F0,24,57,D4,34,00,9F,15,34,2E,00,00,00,00,FF,3A,D4,93,AE,A7,09,12,AA,22,02,7F,6D,88,5B,B2,00,00,00,00,0D,D9,5A,24,B2,C1,B5,62,CB,15,C2,AE,5B,DF,42,5A,00,00,00,00,11,AC,DC,F1,64,98,0E,F2,FD,4C,4C,52,AD,E0,05,2B,00,00,00,00,CA,FD,E8,58,48,E0,2F,8C,39,EC,4F,84,13,6B,11,0B,80,00,00,00,B8,D9,53,66,E7,71,73,63,B1,AA,F3,EC,60,4E,31,FD,00,00,00,00,CF,0C,5F,17,FD,DC,EF,59,77,94,F2,88,B3,70,04,69,00,00,00,00,FE,D4,FC,F2,A4,C4,66,4C,11,02,D3,C2,9E,B6,62,E0,00,00,00,00,6D,ED,15,4B,AF,46,76,12,E5,35,7C,51,03,32,C5,F0,00,00,00,00,E3,EF,B6,B1,87,B4,E7,3D,AD,FB,FF,31,84,D4,03,7C,80,00,00,00,B9,CB,BE,19,F2,E4,3C,D1,0D,A3,91,8A,83,7D,95,05,80,00,00,00,A7,40,8D,31,68,78,F1,F0,E3,2D,E6,8A,42,2E,A0,96,80,00,00,00,4C,8D,06,10,C3,74,25,A7,42,CA,98,7C,EE,22,47,4F,00,00,00,00,09,A2,85,3C,84,4F,27,D1,6B,D8,43,32,A1,2C,34,54,00,00,00,00,04,92,1A,75,40,0F,71,43,2A,DB,7D,8F,03,8D,47,4C,80,00,00,00,D9,C6,0A,78,1D,B9,23,7F,98,D3,92,F3,72,ED,8C,5F,80,00,00,00,77,A8,A2,D5,CD,0B,16,C5,14,47,69,5D,FA,2E,E1,8B,80,00,00,00,96,B3,1B,E4,A8,16,4B,78,4B,56,38,A5,35,7A,A7,8F,00,00,00,00,F9,5A,CC,31,C6,59,E6,27,D1,9D,97,2B,33,8D,67,1E,80,00,00,00,A2,3E,F9,67,80,34,9A,1A,51,64,75,E4,D4,1C,4F,25,80,00,00,00,3B,0D,46,8F,A2,3F,58,1F,8D,BB,5F,ED,BE,4A,AA,DF,80,00,00,00,06,EC,C8,F9,94,5F,67,F4,45,0E,BC,4F,0A,04,B3,00,00,00,00,00,F8,DB,BC,68,8C,09,FF,2A,50,C2,4D,26,C1,D6,7D,38,00,00,00,00,DA,7E,36,2C,31,63,01,7D,93,55,6B,F2,56,6E,AA,28,80,00,00,00,2C,03,71,D1,0F,07,F3,86,52,D8,43,97,FD,5C,75,88,00,00,00,00,F4,F8,47,13,85,74,5A,D9,E2,75,11,40,C5,59,E4,69,00,00,00,00,15,70,26,01,5C,0E,0C,A2,09,7A,CA,22,0E,CC,2A,33,80,00,00,00,03,84,56,22,F9,B4,F6,17,EE,77,88,08,E1,03,88,1D,80,00,00,00,08,64,49,C0,C0,74,8D,E4,21,92,E9,9B,D0,67,CA,78,00,00,00,00,57,C7,35,3F,7F,78,3B,72,E9,DB,FC,D3,C4,F6,16,06,80,00,00,00,D5,7E,38,A0,32,71,E9,BD,A5,32,1C,AF,DA,0C,B9,5F,00,00,00,00,95,C4,C3,80,B0,04,63,34,D9,E3,77,20,17,09,5D,CC,80,00,00,00,72,45,92,52,B7,BC,7B,30,E3,19,18,C2,42,3E,61,70,80,00,00,00,1E,32,E5,48,53,6B,30,41,A9,0B,0C,3C,95,9B,B8,10,00,00,00,00,2F,C2,99,31,74,7C,25,83,11,86,20,B7,B2,52,AF,4A,80,00,00,00,C0,31,BE,18,5B,CD,12,F6,F0,0D,3D,11,8C,3F,96,5B,00,00,00,00,CC,3E,48,2D,BC,5F,F3,A4,79,84,81,85,6B,DC,CC,16,80,00,00,00,7F,6F,94,BC,30,3B,75,FA,90,14,D9,8F,E2,9B,E9,78,00,00,00,00,78,42,0F,67,62,3B,4F,79,AA,F3,CF,78,65,7C,60,73,80,00,00,00,9A,76,44,39,6B,54,99,FB,57,54,B6,7B,77,77,BE,84,80,00,00,00,F7,47,91,B7,C1,02,C9,06,E6,D5,83,F3,CB,10,1D,80,00,00,00,00,C3,96,78,7B,02,77,C2,E6,03,B2,9B,81,DA,C7,BA,FF,80,00,00,00,E2,34,CF,16,6A,45,21,15,C0,B3,0D,8E,91,86,49,38,80,00,00,00,BC,8A,43,E3,1E,7F,D4,4E,D4,F3,C6,98,0A,85,2E,0C,00,00,00,00,79,67,7F,C8,12,54,99,A7,81,25,3E,C9,62,22,BF,C8,00,00,00,00,E1,DC,21,13,3A,5C,DC,B0,42,87,7A,59,48,2F,F8,24,00,00,00,00,F3,CB,05,FA,78,10,45,19,D4,0F,2A,01,C1,7F,E2,30,00,00,00,00,D3,A2,7E,E1,08,1D,03,74,D5,F3,3A,6A,C4,B9,F5,50,80,00,00,00,2F,E3,A7,6F,B0,A9,FD,BD,A4,96,B5,81,7C,9C,1B,52,00,00,00,00,C1,2A,A7,DD,AE,C1,F7,8A,32,44,33,78,EA,55,AE,D8,80,00,00,00,14,EB,90,4E,9F,B3,79,03,13,2F,78,D0,97,83,7B,EF,00,00,00,00,06,7B,FC,E3,2E,1E,20,8A,D5,3D,26,18,E9,2C,B0,C6,00,00,00,00,3C,68,46,AD,33,D6,8D,F5,20,29,38,4A,3C,F8,D3,EC,00,00,00,00,04,52,AE,D4,DC,3F,EC,FF,40,5B,52,15,4B,BB,39,E9,80,00,00,00,45,6A,23,F1,39,E5,B0,3A,7C,55,7A,F5,28,D4,2D,76,00,00,00,00,F4,5C,29,09,B7,9A,05,23,FB,AB,AB,72,DC,22,A3,E5,80,00,00,00,68,2D,28,10,F9,C1,46,F0,FD,92,CE,0E,11,50,DF,A1,80,00,00,00,F5,DD,B2,A5,95,AF,6D,57,00,32,4D,12,A2,3F,88,B0,80,00,00,00,3C,8D,97,21,D3,F2,6F,5E,59,2B,14,9E,2E,DB,6B,1A,80,00,00,00,A0,17,26,CE,AE,D5,AE,3F,5E,0F,25,E2,FB,CF,52,35,00,00,00,00,5D,12,0D,AB,CE,CE,F1,18,85,9F,C8,CE,D6,D8,4F,A0,00,00,00,00,B6,91,08,A1,12,A2,77,EF,9D,23,D2,BC,05,36,C4,D6,80,00,00,00,92,84,CB,1A,7B,17,A7,71,7C,14,08,D6,5D,0D,FD,CC,00,00,00,00,71,B4,BE,3A,E5,F4,28,4A,10,EE,98,6D,10,EA,3D,34,00,00,00,00,94,28,F2,83,BE,CF,26,4B,A0,24,3D,3A,86,94,C7,61,80,00,00,00,DD,E5,7D,47,69,3F,65,47,F4,99,A1,66,A4,AC,78,6B,80,00,00,00,C2,60,3B,2A,18,DE,CE,8A,EC,41,3E,02,E4,8D,9F,76,00,00,00,00,0E,59,5D,04,68,F8,79,10,D5,6A,9B,FC,DC,E0,15,41,00,00,00,00,F4,63,7C,CF,9E,8E,A7,78,95,AC,6A,7A,5E,FD,B1,5F,80,00,00,00,96,00,89,20,FA,64,60,16,E1,38,E2,58,DA,29,D8,82,00,00,00,00,CC,04,DA,CF,3B,E4,5C,41,E0,C3,C1,67,35,94,88,97,80,00,00,00,26,15,DC,65,8E,0B,6E,42,3F,46,29,79,C0,6A,8C,A6,00,00,00,00,00,2B,E6,56,ED,5E,D4,EA,C9,AE,93,6B,67,E1,0C,F0,00,00,00,00,88,F4,04,BE,23,B2,B3,B8,42,86,6A,AE,37,F0,07,C6,00,00,00,00,29,BE,9F,F0,FF,90,02,E8,D6,E8,F9,03,ED,CC,8B,F4,00,00,00,00,81,5D,0C,F7,E3,72,4F,78,B4,49,83,05,6D,80,F3,25,80,00,00,00,6A,D7,D8,51,C9,4D,CB,07,75,59,5D,52,0A,DF,AE,78,00,00,00,00,DF,35,A5,0B,18,FE,57,A1,D7,89,B0,E4,91,C1,D9,E5,80,00,00,00,D4,97,CE,89,4C,E8,84,6E,5F,FB,31,F4,A6,F2,FA,9D,00,00,00,00,2F,8E,0F,0C,4F,52,E2,2C,79,42,30,5D,ED,AF,38,B1,00,00,00,00,0A,AA,8C,E8,50,1C,41,D7,46,A1,90,D9,D2,32,3B,E7,80,00,00,00,9E,1E,0A,F9,97,23,49,B3,B5,D0,E1,76,C1,21,40,D8,00,00,00,00,C4,17,AB,20,42,29,60,F3,33,D1,E9,FC,47,17,D6,A2,00,00,00,00,AD,31,D4,C4,A8,3F,AB,A1,4E,BE,E6,12,09,60,26,E5,80,00,00,00,60,96,96,D5,BE,89,E7,85,D0,44,7B,63,A3,1A,7E,88,00,00,00,00,46,18,DC,3A,2A,3C,74,B4,E7,B5,19,8A,E0,A4,50,CD,00,00,00,00,B9,43,FC,98,07,E8,9E,C5,5A,47,B8,8B,75,98,84,72,80,00,00,00,B0,3F,3C,CB,E5,D4,C6,87,C5,21,D2,72,A3,3B,22,99,80,00,00,00,DD,36,9F,1C,52,01,8B,AD,25,B1,F6,3B,46,69,26,DF,80,00,00,00,C2,D0,DE,19,A6,7F,53,B0,69,67,53,CF,3D,30,DA,08,00,00,00,00,7B,9A,02,69,3F,C1,9E,64,66,9F,03,EA,56,BE,CD,D6,80,00,00,00,F7,2F,F8,2D,DD,D3,26,4A,A8,69,82,09,35,BE,8D,A5,00,00,00,00,6D,40,8D,48,72,39,FD,94,C1,C2,2B,22,A3,05,6F,17,00,00,00,00,34,18,99,74,7F,E6,E6,55,41,9E,0B,42,FD,62,0E,83,00,00,00,00,A7,8E,C5,1B,44,DE,29,13,D5,C6,F7,8B,9A,CC,ED,54,80,00,00,00,25,8B,02,89,79,DF,6D,F2,AD,23,04,E5,E2,4E,04,18,80,00,00,00,71,24,5A,C9,5B,E9,C5,F5,F2,15,D4,F2,B5,5A,04,68,00,00,00,00,A4,EF,16,53,BF,9A,47,51,18,BA,BF,50,59,12,E9,37,00,00,00,00,1C,BB,E8,FE,9E,41,B1,9B,BD,93,B0,5C,CC,36,1E,9C,00,00,00,00,24,E2,87,D7,D0,58,4D,56,88,1E,77,79,E2,ED,00,6F,80,00,00,00,20,73,01,67,A4,35,33,E2,22,2F,AB,A3,A2,AF,13,0D,80,00,00,00,AC,A9,3D,06,99,56,72,AD,F1,9B,C2,EC,E0,41,FE,20,80,00,00,00,06,E1,23,E8,3E,AC,54,A5,BD,4F,EA,77,E0,13,B4,14,80,00,00,00,52,1E,5D,BD,CB,09,60,DB,AC,80,2C,57,BC,73,3F,6C,00,00,00,00,A7,BF,44,EB,E9,C8,EA,52,3D,9E,1A,77,CF,DA,24,80,80,00,00,00,53,13,90,51,5B,3E,49,6D,9B,07,34,49,B3,0C,08,A5,00,00,00,00,63,42,8B,0E,9F,9F,9B,C2,69,92,BE,9A,52,4E,03,52,00,00,00,00,4D,7A,AC,9F,39,13,D1,E6,EB,B7,86,7B,A8,E9,F5,B7,00,00,00,00,E7,31,2D,6A,78,90,95,8A,75,32,75,F2,76,FB,F9,FA,80,00,00,00,85,ED,00,F2,93,16,46,65,61,F4,D9,DD,01,BA,16,29,80,00,00,00,56,BC,3E,AD,1B,D7,6C,E3,84,D0,C6,13,32,32,3A,89,80,00,00,00,02,83,E5,5F,C9,D3,0D,92,B9,1C,FF,57,8D,D4,25,F4,80,00,00,00,1E,56,E9,36,2B,35,3C,67,76,EF,B5,44,66,21,18,69,00,00,00,00,F2,F2,B1,BA,52,A1,99,25,1A,9B,CA,53,FA,BE,43,15,00,00,00,00,B2,E1,1E,C4,73,2B,31,78,95,34,BF,C4,7A,96,EE,90,00,00,00,00,B9,C3,E8,C3,D5,CD,B4,87,0F,30,06,CB,64,62,06,FE,80,00,00,00,A0,79,2E,AD,41,3C,B8,35,72,A4,2D,63,3B,6A,0B,92,00,00,00,00,8D,98,03,FA,3C,39,E4,05,30,E9,E7,1C,46,D5,3E,14,00,00,00,00,18,F1,AF,82,A5,BE,C8,91,C5,62,D6,B6,FF,3C,E0,A3,80,00,00,00,59,A1,24,5B,A1,B0,58,D4,B7,C7,4C,13,5E,1B,BE,35,80,00,00,00,FA,A7,C4,72,BE,B0,97,E0,AE,DE,12,52,34,79,40,81,80,00,00,00,6C,E0,D8,B8,63,AA,FF,99,55,BE,60,07,A4,F5,61,E8,00,00,00,00,5B,B7,F1,8C,E9,4E,4F,52,F9,93,17,B3,D2,94,53,37,80,00,00,00,AC,E5,54,0E,F6,39,39,DB,6A,CD,17,96,89,D8,44,63,00,00,00,00,F7,8F,D5,11,1B,19,F2,01,C8,A7,64,03,0E,8F,CD,15,80,00,00,00,C9,57,72,B1,82,5D,02,E6,D0,F7,94,BE,54,7B,66,DE,80,00,00,00,1A,D3,92,2E,00,8C,33,14,08,78,81,1C,DF,DB,91,00,00,00,00,00,C2,2D,66,D9,CE,5D,21,88,8E,9E,A1,78,34,2B,92,79,00,00,00,00,54,2C,ED,6C,A9,EB,A5,8A,5F,CE,D1,D8,35,33,D3,16,00,00,00,00,2E,7B,28,A1,6C,9A,C7,EE,EB,A4,CB,EC,60,EF,40,5C,80,00,00,00,0E,10,14,19,8D,8F,3F,B7,91,B7,A0,78,B5,CB,93,66,00,00,00,00,F7,66,EF,49,B8,83,B3,5F,E1,99,D8,0F,FC,C7,D6,7B,80,00,00,00,45,A1,94,70,86,53,37,6B,E8,EB,08,94,1B,50,4C,B9,80,00,00,00,95,A4,22,6B,BF,8A,7E,50,D3,B2,F5,4E,4C,12,F8,7F,00,00,00,00,68,AF,DC,54,9A,FF,89,D1,C1,AA,17,8D,6C,00,5E,09,00,00,00,00,04,5F,AD,A4,97,2F,B1,24,FC,09,83,0D,C9,29,77,CD,00,00,00,00,B4,86,26,E8,64,62,DB,F1,75,9E,00,F2,2D,60,BE,A8,00,00,00,00,65,C8,81,54,87,ED,7A,52,BA,00,B0,5A,95,D9,AD,76,80,00,00,00,6D,56,01,9E,C3,31,77,6B,C4,E8,3B,5D,D9,03,97,B2,80,00,00,00,AA,6D,CB,8E,36,33,C7,F9,CE,06,AA,60,DD,AE,CC,17,00,00,00,00,B6,09,27,1C,DE,B1,3E,CC,FA,1C,51,DC,CA,8D,EB,55,80,00,00,00,F8,5B,04,93,10,32,98,4C,46,E5,ED,28,20,1C,0B,62,80,00,00,00,89,F8,5E,6A,6C,80,5C,25,E8,26,25,14,33,CA,31,43,80,00,00,00,BF,84,1C,B9,4B,F8,06,9C,49,CB,9E,60,9A,51,2E,0F,80,00,00,00,EE,75,2A,89,FA,55,B5,17,B1,78,33,BD,E2,C5,D7,A1,00,00,00,00,C1,C9,74,A2,B2,CF,EA,17,AC,1D,93,7F,D2,5A,71,99,80,00,00,00,90,F3,1E,12,5C,B5,C3,44,AE,F2,A1,E5,E8,A7,3D,BE,80,00,00,00,53,D6,64,C5,9F,E3,C8,85,8F,AE,F8,BC,BE,F5,60,8D,80,00,00,00,A9,8B,A6,F9,A4,9D,11,21,64,CD,C5,17,D0,AD,E7,E5,80,00,00,00,0B,72,75,9D,29,1A,97,86,91,20,50,0D,B9,96,83,C8,80,00,00,00,3A,7F,AD,26,35,6F,F7,C7,97,49,BE,F1,76,8F,23,EC,80,00,00,00,6E,FB,95,1B,19,5E,66,D5,1D,46,6D,08,1F,40,26,87,00,00,00,00,45,17,B6,08,60,EA,C1,C1,C1,0A,D5,FF,27,20,66,6B,80,00,00,00,A4,E0,8D,EB,99,64,CC,EA,4D,30,1F,03,94,D5,D7,43,80,00,00,00,14,E1,80,4C,E5,B1,CC,F5,35,41,71,6A,2B,89,47,53,80,00,00,00,6D,8E,4E,A7,37,3F,86,C5,06,CC,2F,C2,AC,CF,0A,DD,80,00,00,00,15,31,BC,D4,2E,86,CC,DC,FF,03,C4,61,58,2F,20,DB,80,00,00,00,7E,29,0A,A0,D0,34,38,19,77,F8,39,8A,36,34,9C,CA,80,00,00,00,4D,4D,20,A2,95,4E,41,8F,F2,8D,37,A7,33,58,3F,D0,80,00,00,00,BC,EF,E3,B0,50,B8,01,20,F5,D4,08,29,E0,F3,A9,B4,80,00,00,00,9C,04,60,AC,38,F5,A3,C7,7F,48,C5,CB,2F,D7,34,7A,00,00,00,00,09,68,9D,9D,72,7E,15,39,B3,C4,E9,53,66,81,C9,C9,00,00,00,00,29,B9,27,05,66,CC,03,54,6B,20,2A,AC,AB,7C,14,DE,00,00,00,00,5D,28,E1,FF,66,53,50,45,4E,E7,3F,8B,50,CA,DB,42,00,00,00,00,E9,49,93,90,FF,39,C8,5B,6D,7F,C1,53,16,74,9E,B5,80,00,00,00,48,BE,B6,A6,1B,59,BE,CE,3A,C1,DE,B7,B6,A7,CB,89,80,00,00,00,0C,60,15,36,17,1F,6E,49,6F,7C,19,04,D2,0D,88,7C,00,00,00,00,9C,9C,27,A3,F5,71,80,DE,10,33,F1,5B,B1,82,DC,CE,80,00,00,00,31,58,2C,84,E9,7C,14,6B,50,7D,03,A5,1F,6A,80,3D,80,00,00,00,85,86,BE,91,84,35,20,C1,4A,DC,D2,85,FD,E6,E9,2A,80,00,00,00,58,67,80,47,8B,4B,44,0A,77,DD,28,1F,79,0E,68,12,00,00,00,00,24,7C,41,89,E9,0F,FE,D7,AA,88,E1,4B,CF,38,D7,6D,80,00,00,00,C2,2F,93,76,E9,74,02,2B,F4,11,4C,D4,93,38,D2,B8,00,00,00,00,59,4C,D0,9C,66,61,95,12,9F,DD,2F,3D,DD,79,B7,DF,80,00,00,00,73,07,ED,7D,07,19,6A,A9,B1,65,32,B2,47,DA,E4,89,00,00,00,00,7F,A1,5E,5D,03,AF,F1,8D,9C,DB,74,86,C9,93,CE,2B,00,00,00,00,68,B4,97,DF,5C,9B,4F,D9,55,88,05,E7,0C,2E,6E,3C,80,00,00,00,A4,10,F3,7D,A4,A0,10,C0,B2,92,0B,35,2E,F8,18,60,80,00,00,00,98,8E,D0,B1,41,D6,AA,80,6D,FF,0A,D5,E6,B0,EC,71,00,00,00,00,E6,C2,87,C4,2A,7E,25,DD,63,27,E7,9C,2F,59,EB,A2,00,00,00,00,58,96,6E,EF,43,D6,93,D0,56,F5,A6,06,34,B7,1E,91,00,00,00,00,9B,2B,A6,AB,C9,10,15,3B,C9,33,30,C2,1A,5A,94,DF,80,00,00,00,92,35,85,00,F8,7F,59,ED,B9,5D,57,A4,C8,27,1A,E4,00,00,00,00,E0,CF,69,A4,50,77,2C,74,8C,0C,12,8E,FE,8B,C6,D3,00,00,00,00,78,D0,70,8A,8A,C2,A6,85,86,92,45,7A,0F,A9,04,87,80,00,00,00,B5,ED,B7,C1,F7,80,F3,72,15,C5,57,74,9E,A3,52,A8,80,00,00,00,A8,7E,88,BA,C2,41,C9,D0,D9,D5,56,37,8D,5B,EC,69,80,00,00,00,C5,39,E1,44,A1,FC,81,18,F0,89,9C,AE,39,02,E8,49,80,00,00,00,EB,19,96,90,B3,9C,FB,4F,AE,68,C1,35,F1,DE,99,21,00,00,00,00,3B,65,DD,B1,D1,01,5E,9E,C1,F3,23,2F,F1,56,B0,7F,00,00,00,00,5C,F5,70,68,D4,8B,D7,11,CB,50,F9,AD,1D,79,3C,22,00,00,00,00,4B,84,AB,87,6F,DF,5B,4B,81,5B,60,A7,A7,71,B3,F6,00,00,00,00,4D,E2,7F,C4,A9,BC,8C,EE,27,B8,A0,C9,FB,6B,8E,8F,00,00,00,00,23,0D,ED,15,00,39,3B,83,D8,B7,83,BA,1A,6C,46,D9,80,00,00,00,64,6D,1B,B5,62,41,C2,79,F1,7D,7D,B3,21,F7,2F,4E,00,00,00,00,A2,D6,38,4F,E1,B0,8D,60,E6,D7,54,A5,0A,5E,A1,4E,00,00,00,00,42,85,9D,2E,DA,23,6F,FA,56,55,04,93,69,62,04,55,00,00,00,00,E8,C4,A9,5B,87,7B,60,4B,E4,0E,D0,8A,9B,2E,A8,A0,80,00,00,00,AE,D7,79,F8,B1,6F,25,A7,20,03,B8,F8,E2,DA,F5,4C,80,00,00,00,65,BE,4F,78,14,0D,83,28,A5,0B,78,2C,BC,4A,EE,A4,00,00,00,00,65,96,82,B6,D5,CB,55,F6,D5,A0,07,6F,A3,6D,12,DF,80,00,00,00,FC,BB,82,FE,A0,E5,56,F9,15,FB,B2,1D,59,BC,F2,EC,80,00,00,00,AF,47,75,D6,D2,3E,D9,7F,A2,E3,45,8D,6E,C0,0B,93,00,00,00,00,F6,2B,76,AE,C1,03,94,BC,AB,7E,5A,E3,C9,F3,8B,C8,00,00,00,00,47,22,52,BA,18,36,79,7B,31,21,97,82,A9,75,3E,29,00,00,00,00,4E,A0,2F,DE,87,E7,8D,B5,58,A5,0C,81,F6,83,45,6A,00,00,00,00,B3,37,34,8D,C5,5F,A2,D2,04,6E,B8,08,D1,9C,F8,6F,00,00,00,00,57,C6,9F,C5,CD,7D,A9,33,32,70,55,86,6E,DD,0B,B7,80,00,00,00,C1,94,23,25,08,E7,75,02,15,AD,1F,EA,9F,66,09,F5,00,00,00,00,4D,D7,5F,70,12,6B,18,AF,E5,2F,44,67,C4,62,B4,FD,00,00,00,00,49,58,99,E3,D9,29,4A,23,05,6F,44,B2,0A,AF,F7,4C,80,00,00,00,A0,9C,FB,B2,61,1C,13,3F,CA,C4,91,4F,EA,84,0A,C0,80,00,00,00,6A,DE,8A,A0,97,8A,E0,A8,D2,4E,E6,60,25,52,DB,85,80,00,00,00,9C,29,C3,BF,30,58,47,0D,12,F7,A1,AA,14,F5,5C,45,80,00,00,00,44,A7,73,C7,20,8F,91,17,95,C7,05,AC,59,69,95,D8,00,00,00,00,DC,EA,E6,D1,10,8A,0F,26,16,BB,F5,1A,A8,00,22,C0,80,00,00,00,05,DD,71,45,6B,A3,B6,33,D9,23,8E,0E,3B,97,F0,2B,80,00,00,00,D9,9D,27,95,BF,F7,AA,23,B3,FA,2F,5B,F8,73,DE,97,00,00,00,00,25,48,22,D9,D8,53,7A,7C,8A,D9,25,9B,D4,0B,E7,BA,00,00,00,00,55,E1,20,3E,F2,0B,40,3C,14,BC,AD,F0,74,87,D2,6C,80,00,00,00,6D,DF,F8,17,70,60,37,74,DB,03,87,59,F1,8F,11,1B,80,00,00,00,64,36,ED,25,D9,6C,09,F7,DD,D0,35,E1,F8,40,F9,40,80,00,00,00,BC,6C,6C,D8,C0,34,14,07,F4,8E,59,B4,5E,5E,26,17,80,00,00,00,65,0F,E7,92,59,4D,DB,18,C7,AE,D5,64,97,BD,73,41,80,00,00,00,DA,AC,16,76,92,6F,70,D8,3F,14,43,4C,AC,B4,EA,EA,80,00,00,00,EC,D0,8A,DA,93,EE,A7,9C,29,78,FC,88,0C,65,CE,22,00,00,00,00,D0,12,DA,54,FA,62,DE,BA,16,F2,E5,3C,77,8E,9E,D7,00,00,00,00,74,85,57,E7,29,74,C8,3F,2D,A7,33,A0,57,E1,E5,37,80,00,00,00,AF,F6,9E,D3,D5,02,11,77,A4,64,E2,4B,FB,7F,07,1A,80,00,00,00,2D,96,D3,11,1C,C5,F1,A5,59,4F,CA,89,99,94,82,E1,80,00,00,00,59,66,87,B9,85,E2,43,D0,E0,21,3D,9E,5B,D5,E4,82,80,00,00,00,40,28,D5,95,D6,E9,16,2F,41,C1,36,E1,F5,F7,19,49,80,00,00,00,68,86,45,D2,30,30,82,1C,25,57,A8,34,F2,C6,33,62,00,00,00,00,78,90,1B,5A,5C,38,4E,7B,69,58,D1,99,52,A2,77,75,80,00,00,00,06,27,75,6A,C6,5D,6F,C0,AB,60,BF,34,23,D5,09,FA,80,00,00,00,F0,F4,B3,20,5E,E8,14,67,2F,94,27,97,77,A0,89,04,80,00,00,00,22,84,AA,40,51,80,6B,C3,41,5A,D3,3D,51,0D,05,A4,80,00,00,00,4E,1E,34,BD,E1,63,AC,CA,87,BB,0A,34,4E,39,FF,D6,00,00,00,00,CE,02,43,ED,70,74,32,B8,A9,B4,51,9E,D9,12,B6,D7,00,00,00,00,A5,BE,8E,59,CB,54,AB,D7,C0,1F,1C,3B,0A,E4,67,3F,00,00,00,00,DB,3B,FD,0C,8A,BD,CF,F0,BB,B1,5E,79,5D,8F,25,BF,00,00,00,00,D1,8B,19,45,90,C5,04,E1,3E,A9,F0,F6,9A,C3,90,38,00,00,00,00,54,A1,28,07,A4,A9,7C,D2,09,A3,67,CF,68,97,F2,52,00,00,00,00,A7,73,D0,98,76,CF,45,67,D8,ED,BF,70,25,E7,0D,90,80,00,00,00,39,4D,78,DD,8A,5D,9D,77,1E,91,58,C9,58,EA,74,07,80,00,00,00,CA,86,48,B5,A6,53,7C,7B,A0,08,A4,95,9F,83,97,C8,00,00,00,00,EC,95,B3,F5,C2,B1,26,80,33,E6,F6,77,33,58,EE,5E,80,00,00,00,1C,A4,9E,CA,A1,59,63,C2,E7,F7,54,18,BB,40,FA,1B,80,00,00,00,9C,BD,19,CF,F9,2A,BA,54,F8,F8,09,E7,BA,7B,1E,12,00,00,00,00,11,2A,42,52,15,FB,B2,2A,AA,AB,7E,16,94,57,CE,A3,80,00,00,00,85,EC,86,1C,53,69,BE,77,BB,22,38,7B,92,4B,EF,3B,00,00,00,00,87,D9,7C,C2,A4,A1,01,67,6B,E4,7E,22,3B,E4,EF,5C,80,00,00,00,0B,BF,58,0F,59,0A,29,77,5A,06,9A,A1,EA,EB,C8,41,80,00,00,00,34,A4,31,16,9D,49,4A,30,7D,86,81,99,1A,91,58,AA,80,00,00,00,72,5A,24,81,DA,3E,73,5A,6C,39,74,C8,6F,B4,BA,DF,80,00,00,00,A9,B3,F0,05,27,F5,51,44,6B,98,0B,29,EE,68,40,2F,00,00,00,00,02,5B,F7,87,FA,14,30,23,CC,E4,D2,32,B4,48,DF,EF,00,00,00,00,F6,55,6A,CE,A2,E9,1F,6B,76,DB,82,98,83,78,DC,D2,00,00,00,00,0E,71,43,A9,4C,66,C2,1A,D9,5E,D9,6F,1E,E6,4F,2B,00,00,00,00,5D,A0,26,73,E2,40,28,FB,C3,9B,5E,00,F4,60,BE,74,00,00,00,00,A2,00,A8,DD,55,71,E6,8A,5B,81,D0,82,2C,CB,FA,DB,80,00,00,00,89,7F,1E,FD,D1,2E,F6,0B,30,26,21,5B,EB,40,3B,0F,80,00,00,00,EE,6F,45,5F,EC,E1,98,2A,29,F6,05,3D,D0,F8,6D,92,80,00,00,00,2E,C9,20,7A,7B,D6,0D,96,2D,A5,48,1B,51,AB,72,D9,00,00,00,00,35,8C,C5,6F,1A,09,BA,58,55,74,FB,2D,44,F4,1D,A0,80,00,00,00,52,66,5F,AB,BE,A4,3B,ED,A0,71,78,61,47,BA,C0,9E,00,00,00,00,46,03,71,CF,CB,87,19,7F,7E,CF,51,EB,F9,81,FB,F1,00,00,00,00,83,04,0A,DF,C6,98,F4,51,22,04,E6,D7,4A,DF,25,92,00,00,00,00,68,97,7C,AD,65,4F,43,19,CB,6D,AE,AC,85,54,78,83,80,00,00,00,4D,7D,A4,3A,3C,34,F0,DE,11,CD,FD,4D,E3,E1,4F,91,80,00,00,00,81,93,5A,FF,E5,4B,FE,A5,6A,2F,34,1F,F5,43,B8,80,80,00,00,00,CF,A5,C4,0C,E3,7E,54,40,36,53,1E,07,D1,82,EB,0F,80,00,00,00,51,2B,73,75,6C,77,C3,93,DF,26,9F,8F,8E,74,DF,ED,00,00,00,00,3B,C6,7F,1B,CB,02,EA,A7,54,50,FF,7E,53,6E,EF,17,00,00,00,00,D5,33,0B,44,CF,A7,9C,80,D1,DA,6B,89,F1,04,75,2B,00,00,00,00,95,C8,57,80,96,E6,4A,1E,0F,0A,F1,E0,00,65,52,AA,00,00,00,00,4A,78,E6,B0,2D,95,7B,0F,93,E2,5D,7B,AB,D9,EE,79,00,00,00,00,3A,43,2B,91,96,19,84,EA,52,60,DC,57,A6,3C,7D,F0,80,00,00,00,C6,F2,78,79,86,45,7D,BB,FA,95,C5,AA,A9,77,F7,9A,80,00,00,00,C4,5E,DD,4B,2A,19,D8,66,2E,E0,2F,25,46,4E,F7,CC,00,00,00,00,32,77,CF,18,9F,53,D3,8D,B8,3D,53,75,C0,8B,ED,42,00,00,00,00,B1,B7,90,C4,E2,E0,47,28,A4,76,12,E9,9E,F9,00,49,00,00,00,00,EC,8D,19,81,36,61,52,69,A6,6B,EC,A2,EE,F9,F2,09,00,00,00,00,A8,47,9C,57,04,B8,C7,61,F5,71,C7,B2,87,93,A7,23,80,00,00,00,5F,AF,9E,04,A3,7E,10,52,85,AB,FD,8B,27,0D,15,18,80,00,00,00,F8,46,9E,61,3C,A8,0A,04,8E,72,AB,6C,A6,D3,CB,A0,00,00,00,00,2D,C1,59,AB,71,6C,C4,E5,4B,D2,09,D0,EA,A1,89,9B,00,00,00,00,42,36,59,A0,1A,A2,85,C8,37,83,DB,01,37,D2,06,0B,00,00,00,00,F2,83,A2,C2,C0,43,22,73,C9,20,6C,33,00,E5,6D,6E,00,00,00,00,3C,38,53,E5,8B,41,B8,32,6C,2C,22,B0,1A,03,89,0C,80,00,00,00,48,3D,98,88,0D,24,C0,6D,9F,87,69,DD,23,66,1B,1B,00,00,00,00,32,75,C5,1B,74,BB,7F,EC,64,33,85,19,A1,EF,2D,43,80,00,00,00,8B,77,F0,24,FD,5F,8D,FD,9B,45,B7,01,B5,87,D6,2E,80,00,00,00,A3,15,03,BC,22,A1,20,34,70,26,90,B7,E6,4D,3A,BD,00,00,00,00,3A,F9,2F,46,3F,8C,FB,6C,32,EF,85,AC,13,C1,8D,B0,00,00,00,00,AA,F2,18,98,08,7C,22,46,68,73,9C,C0,92,44,53,29,80,00,00,00,B5,D4,4F,E3,E9,24,0D,AA,3A,5F,36,19,75,4E,F5,F6,00,00,00,00,CC,D3,55,BA,B8,D6,1C,F8,E9,79,65,F5,17,E1,AC,1E,00,00,00,00,18,0C,6C,C7,B6,B1,06,CE,D8,EE,08,40,E1,3F,2F,03,00,00,00,00,F9,4A,14,D1,04,8B,8D,33,2D,B0,73,93,D3,A8,4C,28,80,00,00,00,BE,A4,36,B4,8A,8D,32,DF,BB,C0,2F,7A,EB,53,BC,4F,00,00,00,00,23,27,B8,81,42,78,67,08,0B,C4,75,30,A1,35,3F,A8,00,00,00,00,81,91,FC,0E,0E,C9,8B,08,96,80,8C,6C,1E,94,42,70,80,00,00,00,23,DF,D6,DA,BA,41,50,3F,6E,C6,89,64,D2,AC,14,B9,80,00,00,00,FF,C9,90,06,4C,91,81,E7,05,07,35,96,39,26,F7,C8,80,00,00,00,20,66,5D,0C,5A,4A,5A,6C,26,86,EA,25,55,84,1B,31,00,00,00,00,59,8B,40,BD,FE,C6,6E,09,E5,B1,E9,5B,61,30,C3,CB,00,00,00,00,68,FA,A6,F3,1B,D5,47,F9,0B,89,CB,E2,AA,4D,67,9A,80,00,00,00,99,46,E5,07,E4,27,3F,DA,43,7C,D9,C3,88,60,10,A6,00,00,00,00,BC,71,A9,24,96,10,7A,50,6C,E4,10,70,B1,C6,9F,88,00,00,00,00,19,B0,B8,1C,8B,D8,D7,E0,8F,1B,10,10,AE,B1,40,52,80,00,00,00 -roundConstants_full = 54,4B,7D,BB,35,51,C6,08,6A,2C,E3,0A,22,50,6D,C3,80,00,00,00,B4,D7,49,5C,4C,81,78,6F,71,15,16,EA,F5,EF,70,9A,00,00,00,00,E0,C5,E0,76,B5,2F,6C,26,5A,15,DE,2F,A3,D6,21,B1,80,00,00,00,3D,9C,40,92,E4,21,4C,CD,49,85,6D,DD,EE,06,36,60,80,00,00,00 diff --git a/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL3.bin.properties b/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL3.bin.properties new file mode 100644 index 0000000000..935d2fa7bb Binary files /dev/null and b/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL3.bin.properties differ diff --git a/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL3.properties b/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL3.properties deleted file mode 100644 index 8045892a71..0000000000 --- a/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL3.properties +++ /dev/null @@ -1,10 +0,0 @@ - -linearMatrices = 46,CD,26,E0,D0,32,B0,16,F1,5A,B4,1F,81,1F,0A,26,0E,51,A7,1A,33,60,76,CA,4A,6E,61,CF,CA,35,FB,30,0E,8F,84,79,45,5E,AF,8A,12,CE,9E,36,94,2F,63,E2,C0,82,44,99,D2,52,7F,25,D5,9F,80,F2,D4,C5,A1,43,D7,4A,8E,F0,BD,1E,AE,07,3C,01,1C,1D,53,64,6D,30,9D,9B,6A,29,49,32,9D,44,A1,91,4D,75,16,FF,1C,C1,34,55,2E,9C,FC,09,1F,6B,EC,10,DC,0E,D5,64,F5,B4,A4,A6,62,42,D4,63,53,34,31,B0,54,40,12,64,F2,BD,45,41,A5,8E,95,82,97,00,F3,09,C7,8B,75,AC,1C,DA,07,95,FA,5B,18,29,74,57,43,F1,C2,7F,A7,23,65,16,C2,34,06,26,D4,0D,5E,51,B9,78,C1,67,92,EB,52,2A,FD,A4,69,D5,F7,65,98,6D,EC,2A,39,C3,5E,A0,43,5A,B7,13,E0,86,6C,60,FA,B6,3A,85,54,9A,BD,0C,E5,08,A5,41,68,A4,D3,D3,FA,3C,F0,38,1B,DB,2B,E1,5A,F0,C4,5D,FD,0C,24,8E,2C,F0,E1,D9,30,83,4F,B5,4F,66,33,29,97,71,A1,71,66,12,58,79,B5,FA,2C,79,59,43,F8,E7,F4,91,8C,3F,0B,49,EC,88,1A,FC,CB,73,3F,14,26,7F,A6,D6,D9,69,32,B7,19,79,E2,5A,EF,2B,33,E7,FD,57,FD,3D,73,BA,46,F4,3F,D4,D3,44,66,92,2A,62,71,4E,7F,2D,34,7D,07,7B,2E,84,24,1D,01,DE,39,A5,63,E9,03,B4,F2,84,ED,9F,D7,D7,6A,31,C4,AF,B4,36,94,BB,C8,94,83,55,71,C7,3D,98,BF,8D,BD,BB,65,AA,92,07,8B,88,E7,F3,A7,30,EF,48,7F,42,73,7B,E5,D9,9B,79,4A,C2,68,8E,70,FE,88,DC,25,24,16,7D,58,CE,06,E6,15,EE,7E,7D,AB,12,CE,B0,EA,94,8A,9A,2B,4A,D4,B2,E7,80,B8,8A,D3,6C,C8,0A,7A,99,77,FE,D0,1B,CF,72,D2,9F,A3,28,5E,0A,96,4F,76,5D,BA,22,80,CA,26,15,A3,0C,CB,7B,0E,F2,5E,56,E2,D5,61,F8,E7,78,1F,C6,F9,77,5F,13,FF,0B,BD,F9,09,FD,BB,31,E4,24,E2,71,D2,DD,9A,73,C0,E9,E2,60,7B,BE,5C,64,48,1C,50,20,FE,C1,68,39,F5,E8,E2,C0,1B,92,91,70,25,89,18,26,CD,3D,06,8C,41,9D,50,69,DC,36,30,78,31,A0,2F,25,1C,95,63,E5,84,F3,B0,78,2C,AC,16,6C,90,00,F7,23,95,B5,1E,C7,49,03,08,ED,7F,8F,60,99,72,F5,B8,6B,CC,D4,6E,67,49,C7,C0,43,47,E3,DC,FC,05,D0,5C,83,3D,E8,47,ED,18,1D,66,E8,26,D4,79,32,C4,F2,45,9F,FF,15,BE,04,1F,3A,93,CF,2A,A0,D6,3C,45,06,3F,D1,59,9A,F6,3E,5A,7B,B1,EB,29,92,88,28,D4,9B,9B,09,DD,1A,F9,D2,BF,0C,7A,DD,AC,4F,E5,F8,AE,55,0A,13,80,F3,E1,BD,A9,B3,87,89,8D,2A,FC,7C,8C,BC,41,27,D6,41,30,13,34,54,F1,CA,04,67,76,41,71,E5,85,1B,C4,B6,2D,66,40,FB,14,50,55,EE,AE,EC,BA,99,99,DF,2E,44,41,1C,CC,1F,57,7D,84,4A,F3,E7,F0,F0,5D,A2,0F,9B,F9,2E,B6,69,4A,92,3C,29,34,D1,3F,91,EB,BD,C5,79,4D,A5,EB,5D,3B,48,9F,24,97,5D,54,4D,DA,17,8B,BD,B9,68,4E,5C,A8,2F,6B,49,88,E1,4D,3B,B8,E8,21,9E,87,0E,35,FA,13,D0,E9,53,42,69,0B,6A,48,9D,CB,8F,7E,72,21,04,5B,80,C5,9E,22,77,36,D4,20,C6,80,D8,BA,C0,6E,D2,6A,13,25,20,0F,8F,29,AF,9C,7D,48,91,B3,62,75,A8,6C,F0,21,FE,1D,7F,EF,CD,3F,A7,40,CF,6F,C9,12,31,28,99,2E,50,B0,44,5A,8F,03,2C,19,18,6B,16,C4,B8,40,21,10,6F,F1,C2,3A,64,E3,39,91,9E,DF,6B,40,C1,77,FE,EB,E8,03,DA,1E,70,F3,7B,C4,A1,FC,E1,53,9D,18,D6,80,FE,50,2B,8B,EC,71,2B,D1,31,17,D3,6B,6A,0E,77,F1,5E,FB,C3,32,0C,3C,C9,84,1B,D0,BD,52,99,B9,B6,F0,35,03,5A,29,0F,BD,58,F3,EF,11,C4,68,B6,A7,62,CE,13,15,60,FB,7E,BA,93,F9,0F,62,E3,F4,28,FF,F9,FC,27,9D,2B,A7,CE,C4,E4,FC,F4,39,1E,4E,E4,E0,24,19,F9,90,A3,B0,87,7E,4C,5B,40,A6,0C,61,27,EE,6A,E9,9E,B6,9B,3A,E7,9E,42,C2,56,8F,57,91,17,5D,B2,98,6C,96,0B,E7,56,3D,97,57,CB,9D,3D,02,39,8F,62,58,79,BF,91,9B,13,F2,93,3A,4F,85,60,1A,86,E0,D1,4D,6B,16,4A,2A,6A,47,26,DA,FA,7E,6B,54,34,A9,4E,F9,94,21,A1,AA,99,8F,E8,36,48,00,E9,EF,C5,D8,A7,D3,AB,5C,C9,96,AF,4A,D6,BD,14,6B,43,BE,C3,A9,60,B2,32,84,F2,E0,C5,49,C9,1A,1C,A5,8F,DD,E2,96,C1,1A,AC,4A,BF,D2,64,4F,B6,47,61,1C,A7,D9,04,31,99,56,68,5F,8A,77,30,3F,85,97,20,41,8B,BF,0A,30,61,44,0E,44,EF,AF,D8,4C,6C,CB,CE,4D,15,86,4E,03,02,46,57,71,F8,9A,DA,3C,28,10,41,85,D4,3E,87,46,A9,00,CB,7B,6E,61,F9,DD,40,27,B9,FB,48,6F,39,D4,CA,2B,35,AD,41,0A,AC,96,1B,31,1B,96,8C,1A,DC,A3,78,67,95,84,1E,73,BC,A1,5D,D8,BD,08,BA,2E,1E,06,3B,47,C5,B1,8B,7B,CB,77,55,C7,5E,B3,F8,FD,3B,C4,64,AA,BF,D8,69,C4,38,87,0C,79,71,0C,C5,35,CF,0F,E8,0F,93,B6,1E,E4,59,5F,C6,1A,8F,C8,44,89,8E,AD,5E,45,4A,96,19,C3,4E,A0,40,B1,3C,00,E5,A8,E7,A1,16,64,7B,87,14,35,08,F9,10,DA,3B,E7,20,AF,C4,9D,DA,5C,7F,FA,4B,B2,9C,22,E3,15,BE,83,4E,E4,14,51,34,FA,8D,A6,E6,B4,48,C7,54,67,F4,0A,68,07,0C,B4,13,CC,74,D4,76,35,B3,E7,9F,42,46,9C,AF,7A,36,97,4C,94,5C,64,F5,D5,7B,39,57,0E,E0,B3,78,0B,ED,8A,B5,A9,0A,9B,BC,FD,27,A5,2A,96,40,CC,CC,81,62,38,2D,61,5C,2B,0C,DC,1C,AE,11,4B,AC,87,1A,CE,9A,EF,83,6D,84,3D,90,B7,C0,24,C0,1F,6C,CE,2A,EC,44,1A,72,FF,E3,05,D8,49,5C,C7,0E,3D,25,E8,8A,5D,DA,89,6E,47,92,E2,C6,C3,3A,AD,74,68,E0,1E,8C,5E,57,6A,7D,8B,B9,E6,07,55,B9,46,01,10,71,24,A7,4A,C4,19,13,2E,D4,41,DE,59,C9,A4,A5,27,5E,0C,DE,83,27,32,2C,BC,92,06,39,5C,42,9D,B6,2A,5D,CC,D3,B6,C5,C6,21,46,BA,9D,AB,83,D5,A4,15,AE,C4,0F,53,B0,B0,A5,0F,8F,6A,58,4A,99,58,2C,E7,AF,4C,76,40,C4,2D,8A,C3,F8,6E,8D,EB,D0,AC,E7,A1,52,48,06,D0,9E,D5,04,B7,57,70,B0,2F,DC,FC,0D,B0,14,80,94,9F,D4,50,38,3C,9A,99,88,CB,69,F3,3D,5A,16,AF,92,19,27,37,14,4E,BA,9A,F3,D3,C4,2E,59,2E,CA,52,87,E1,20,F1,3B,CA,F5,67,6A,C7,D4,A4,9B,4B,BF,15,57,D0,96,76,A0,BB,A8,BD,13,41,0B,3D,58,3C,3F,DB,DE,CA,95,60,5F,D2,C2,13,45,E1,E2,21,B6,29,14,F6,7C,45,F8,65,CA,FB,A4,CA,5A,A6,27,60,9E,33,21,5F,54,5D,97,0D,5E,C0,87,10,27,EC,D5,2C,71,8C,BC,5D,A2,0A,F2,E0,C0,BF,11,74,0C,7D,43,2F,81,CD,3E,85,D3,B1,7D,DA,40,5B,C4,02,AB,3C,5E,A9,20,A1,60,B7,65,68,83,E4,02,B2,D8,66,7B,F7,1F,EE,2E,F4,C1,BE,9F,F9,57,1D,78,4B,5A,B1,DF,E3,2B,13,4A,0A,ED,9B,0B,B8,DD,5D,52,1F,37,BA,39,7A,60,7F,52,DB,02,DF,95,43,A5,36,3D,F2,B5,BA,DA,72,E7,24,3D,4A,34,4B,E9,A5,3C,5C,5B,35,4D,24,80,0A,45,0D,BC,6F,D5,EB,2E,67,6B,2D,3E,67,5D,0E,00,26,A4,51,1A,C4,93,C1,B8,BC,14,B3,DB,CB,25,45,37,EA,4B,D8,B8,E2,AF,4B,00,A2,95,F7,55,B7,00,C3,6F,D8,40,AA,9A,39,22,59,58,5E,5C,61,DC,5B,7F,D4,BA,18,94,88,AB,B9,A6,A7,62,09,57,48,6D,74,2B,87,0D,15,D6,11,EB,72,3B,D0,C8,5E,12,02,60,A4,E9,27,83,0A,C9,1D,E3,36,D4,E3,74,57,D6,91,FA,EE,79,4A,EC,0A,43,87,37,2D,8F,41,FD,94,E8,86,2C,E5,42,77,22,BA,45,08,25,A5,DA,8A,BE,BD,E3,BA,76,2E,76,BE,A6,33,93,2B,50,7F,A2,30,42,5D,93,41,87,1F,4B,CD,CA,06,C4,9F,27,86,FC,16,A8,6B,E2,EE,99,6D,2D,8B,0B,71,61,95,9B,FA,02,DA,91,1C,0D,40,9A,94,6E,75,FD,70,3C,F5,A4,A9,0E,53,53,ED,57,92,A8,21,BF,13,01,B0,3C,8F,BA,5A,E7,A2,B6,29,D5,5C,97,F2,15,FF,4F,11,09,4F,AB,CF,56,4D,C7,60,3F,E2,05,F1,6D,0E,90,0A,9F,4D,39,0D,BF,FA,7D,30,31,E5,51,0E,56,36,55,7B,97,E5,52,B9,03,B2,FC,4B,7E,08,B1,48,A6,AF,B7,E6,51,EE,26,79,55,70,86,93,EE,22,50,25,99,7A,EE,F7,3E,A2,C3,A8,CA,9F,FC,D6,87,67,60,A1,0C,7F,D3,5A,6A,38,EE,BC,11,61,46,07,DF,BE,F5,60,4C,CE,78,04,66,24,96,33,87,09,B3,A0,D3,25,BD,25,E3,AF,EA,AA,0C,C5,AF,EE,DE,0B,7E,45,27,06,66,50,C3,92,D4,A4,67,57,72,05,4B,E4,5E,61,52,89,55,39,19,B6,E9,54,2E,A2,C2,C9,3D,5A,D3,F5,F6,20,24,07,C4,A8,A2,58,F0,76,7F,35,53,16,17,ED,90,D9,C0,E8,B3,D2,28,A0,73,75,2E,33,1E,EC,31,55,3D,4F,3B,6C,DD,E2,EE,7A,BC,9B,E6,29,FD,00,5A,A8,C3,7C,9F,F5,57,63,28,92,75,C5,8E,E2,DA,E9,04,B5,04,68,22,7D,BE,F0,7B,78,60,6D,70,59,A2,17,F6,42,28,4C,0B,77,00,52,10,63,FB,C4,1A,6B,62,C8,AD,81,C9,E5,F5,79,0A,5E,73,4A,F7,66,66,43,FF,9C,D6,A0,35,F7,E7,E2,F8,6A,F0,65,1D,9E,95,FA,3F,1B,8B,24,FF,60,78,03,1D,E0,CC,58,27,25,BE,A8,AC,DD,E0,5F,AD,1B,12,65,CC,14,9C,C7,1D,81,E1,BD,A9,88,50,B3,5C,64,FE,26,15,AE,46,FE,55,89,C4,0B,FE,9C,A9,B8,A8,19,BF,7F,A3,F2,1D,F3,66,12,5E,15,E9,89,91,56,6A,12,60,8E,61,BB,46,A5,7D,47,71,B9,61,45,53,88,9B,D7,92,F8,D6,24,BB,B0,9B,A5,CE,6B,E9,3E,C5,16,E5,3F,42,45,A7,FC,37,83,63,7F,CF,CF,DB,88,1C,90,13,E6,CB,0D,4D,B5,91,71,B8,9F,AD,6E,68,45,CE,9E,5E,4B,35,9D,E8,D6,32,8F,1F,39,70,AC,47,78,C7,1B,E0,3B,7A,F7,2A,F7,AB,B2,3B,57,4B,14,A7,DF,A2,3B,B9,1E,53,42,B5,BA,83,4A,37,16,5D,C7,F9,E0,37,F1,E5,60,02,B2,AF,D2,82,10,82,1C,01,89,74,35,84,92,F3,E3,05,26,D6,B3,F1,86,44,07,04,B8,5B,FD,A5,C0,ED,CB,1E,47,9C,E5,70,A2,05,68,6E,54,C5,85,2C,A5,EF,14,A2,F9,5C,19,CA,F5,97,B6,C2,F1,81,0C,DC,9B,2A,2B,43,2F,44,A4,44,39,E6,F5,1B,B9,12,C0,01,07,59,A0,93,C5,04,C1,99,DD,CE,5C,2B,1F,72,4B,10,C1,16,8B,F6,A0,8C,A9,A6,22,6D,B0,22,98,05,DD,40,94,B0,71,44,1C,EE,F4,BA,C3,4C,73,3B,D7,C2,1F,9A,73,3B,58,60,20,47,06,18,07,95,E2,FB,9A,42,62,ED,33,B5,14,9E,40,86,C5,76,77,85,00,C5,6D,52,79,39,58,FC,FB,E2,5D,63,F6,F1,02,47,3C,FB,C0,96,DD,54,CD,82,F3,10,CF,E9,F0,F2,40,74,93,6F,7A,49,A8,2B,08,77,87,26,25,50,73,67,C5,02,F3,03,28,10,6F,22,EB,B3,72,F8,9A,97,66,9F,04,AB,CD,F9,99,D6,1E,C2,40,2A,7B,EB,F1,F7,B9,6A,AA,73,DF,97,A8,CF,13,7A,4F,F6,4D,25,81,59,EF,AD,D2,EA,EA,E2,EE,F6,E2,E7,F6,B3,08,30,49,87,C6,47,86,34,A8,67,95,AA,2D,FC,FB,4D,89,9F,32,85,CE,CA,27,DA,BB,1D,76,B2,67,82,84,AE,F8,3A,70,DF,59,BC,81,02,CC,D1,FD,84,20,84,42,EF,05,7C,84,99,AB,98,4C,8F,9A,32,FD,AC,4B,2D,DB,F3,88,8E,8E,83,56,BD,7E,14,5C,46,95,B3,C8,0F,88,70,DB,88,53,F5,36,5D,E6,C2,5A,63,B3,7A,06,9A,86,41,E1,EE,F5,E5,A8,CB,4A,C4,24,A0,95,CC,90,7E,7D,E3,0F,03,53,C3,3D,A5,47,1D,59,CA,0F,D2,33,13,4F,B0,1D,7F,66,D8,C5,48,B8,AE,BF,5C,B8,92,33,0C,35,9A,96,C5,04,BE,22,B3,7E,65,E5,12,F9,FA,C9,95,F2,B8,B8,11,3D,42,9B,B2,29,12,38,40,B8,0D,5A,B2,11,03,F0,96,D1,B9,2D,0A,38,FE,51,72,4D,53,AE,C9,30,C0,AA,23,8E,FB,75,CB,AF,A3,93,F2,E5,14,4B,8B,F0,4F,17,1E,9B,05,48,A5,F8,DF,AD,3D,C4,8D,8A,46,52,47,31,D8,F0,E6,5B,4B,2A,B6,C1,35,36,5F,BD,93,0C,9A,CD,B4,F7,E5,B5,8C,32,99,83,B8,EE,D0,FA,6A,AE,0F,AD,AB,75,79,84,ED,D2,C4,B7,3D,2E,14,E4,F2,31,02,8F,46,7E,BC,DD,80,01,AF,10,D4,6E,CD,D4,1E,40,CA,A8,F4,5E,82,41,CD,79,58,68,BD,48,91,05,E6,52,1B,18,DA,DA,E3,25,8E,65,5C,AA,89,50,F3,78,55,B8,F8,C6,18,0D,C2,BA,C9,B3,FD,B5,C9,D1,F3,DB,D6,D1,D3,DE,CB,A2,AB,75,3D,89,5E,6A,99,63,FD,BB,89,E7,ED,A1,E9,6F,CA,87,1A,2E,0D,9F,B5,11,76,32,D3,03,91,AC,EC,1A,A4,1E,2A,E5,CD,91,E0,A4,2D,C5,F8,6A,CC,A7,8D,59,1A,47,A9,7C,31,A4,D8,CC,0F,C0,02,75,11,9E,B0,27,58,E7,7F,00,27,64,B2,41,30,7E,7E,CE,DA,99,8A,33,99,5A,6D,E8,04,7B,7D,71,4B,50,3D,40,8B,EF,3F,8A,C1,20,88,6E,55,B5,EA,3C,D5,B2,14,B7,DC,18,46,24,56,41,99,BA,C2,70,2A,EC,1D,F8,FA,16,6E,33,D6,5B,4E,96,F4,DA,39,92,51,A6,21,09,96,C9,DB,88,1F,82,9A,52,3D,A7,FE,BB,0F,72,7B,46,1F,52,28,B2,0F,56,0E,42,63,1E,3E,A3,1E,21,FC,93,CE,46,A9,F1,B9,A7,52,4D,D7,52,68,EE,6A,67,2E,4F,24,64,0B,5A,8F,F2,58,8B,CC,75,43,AA,0A,0B,5E,8C,CE,29,EA,A0,B6,BA,C7,B8,D9,22,1A,C8,56,C2,31,A6,D4,F2,6C,39,18,07,74,04,4A,53,25,F1,FE,EA,5A,7D,CA,FE,09,B4,73,94,50,5E,BA,8C,20,A4,27,44,BA,48,36,F2,00,7D,B7,06,65,53,64,30,DD,CB,5D,1B,53,20,17,BF,13,F2,E0,B3,47,85,2F,41,E5,4E,FE,8B,7A,A0,D6,FC,DE,9B,94,E2,B0,50,CC,71,7B,DD,D0,1A,BB,C6,05,A1,63,16,D9,C4,CE,57,2A,7D,26,7B,AA,6A,D1,FA,54,C3,15,DB,F5,B9,6C,E7,85,AE,D7,13,94,77,80,25,62,A0,B2,2A,30,9A,1F,DE,F0,84,47,D6,9C,C0,67,8B,A1,FA,D1,57,D8,F5,9A,3D,ED,1B,96,43,C8,C3,3A,34,D1,2F,75,24,98,FA,58,87,08,39,14,34,45,FD,CC,7E,88,3C,EA,CF,69,82,7C,D4,CA,D0,16,71,A9,D5,98,55,34,2E,17,E7,80,64,0B,2B,6C,B3,12,8C,A3,98,3D,DE,7E,09,15,27,F2,67,3A,26,B5,5E,C3,7A,94,B1,C9,03,8B,E8,87,84,E6,18,8D,B3,98,76,97,7E,7E,BB,9D,BC,A8,D2,B0,79,C7,8F,82,E6,71,68,7E,1A,03,69,F0,71,9D,69,C5,77,B1,31,7F,D6,89,68,08,73,BC,53,39,77,A4,4F,38,FD,CB,3A,A4,FC,7A,2D,75,A0,FD,41,22,80,6C,59,89,7E,F4,F7,8A,7A,87,7B,84,60,B2,5D,9C,82,17,7A,CB,54,BA,7D,10,68,F3,1A,98,AC,40,3D,7A,3B,27,47,04,00,6E,C1,CC,54,06,66,58,01,C1,EC,C0,41,60,4B,FC,C2,04,54,F3,66,E3,3D,2C,11,68,C3,DC,57,0E,65,5F,DF,1A,AE,C5,00,20,B5,3A,38,DC,21,6E,D1,5F,C2,E0,7C,1B,2C,04,5A,6F,A8,26,98,4C,E1,3F,73,C6,03,B1,D9,4B,98,EF,DC,D2,4C,5D,69,64,AA,30,20,9C,AE,E8,EE,64,2A,8B,F6,2C,AE,56,09,B2,E8,4E,07,29,88,3A,02,07,8A,2F,5E,AF,F2,E5,39,E8,D6,43,E4,80,39,02,E4,31,00,84,56,DB,AD,3F,D9,26,C2,25,04,D4,ED,02,0C,07,F7,76,43,B7,FB,96,58,B1,34,49,3A,8F,3A,B6,9D,CC,EC,73,D2,B8,CA,D5,3C,BF,09,04,CE,08,1E,2A,F4,44,80,08,C8,88,A3,85,4B,4A,62,62,B6,9E,1C,2E,6F,19,07,3D,45,62,58,6D,2D,30,3B,3D,E5,5C,9C,FE,23,91,BB,AB,4C,3A,AE,6A,98,F2,CE,DE,24,FC,BF,60,44,A7,DC,06,9B,3C,DB,26,C0,B4,F8,FB,EE,3A,E2,B6,9C,3B,F1,A3,C7,F9,32,E7,00,5F,D0,9F,FF,C3,D7,6A,53,C0,59,DD,46,BD,F6,C1,9C,26,B8,ED,AD,E2,DF,AB,FF,D9,DC,EA,A1,E6,80,F1,43,AB,C6,A8,B7,E0,F2,52,04,97,BA,1E,95,8C,82,3E,93,DB,00,F8,45,64,85,52,22,3C,7F,A8,DF,E2,91,A5,9F,82,F6,39,8E,D3,36,0D,E8,A4,A8,02,D3,01,62,41,36,08,E4,2E,38,0F,D9,B2,8E,A3,F4,83,CC,E1,A5,AA,D4,BF,04,13,BD,19,69,30,85,6A,D7,3E,6E,4F,D1,A4,3D,3C,ED,05,6C,AA,B0,1B,95,F2,B0,BC,41,09,EF,86,B1,25,AC,49,CF,40,46,EF,3F,A1,D9,DC,11,08,3A,8F,C7,4B,90,93,8C,3C,04,E1,98,68,A0,B7,28,FB,7C,17,87,9E,A1,E2,28,C6,64,39,2A,E9,77,41,9C,26,CB,E9,C1,AF,62,09,26,34,1F,AC,07,F4,C6,61,80,97,47,19,44,45,C0,2B,1E,0B,D6,73,8D,28,3C,C4,56,3D,0F,1D,23,FF,2C,4A,BB,2A,52,5D,10,45,EC,AA,07,6F,47,D4,84,2D,EF,E6,31,BD,BD,8F,02,C3,51,61,31,8E,1D,92,94,24,A4,D4,0D,06,FA,93,0D,CC,E2,C2,3E,D5,63,55,2C,65,E7,C6,87,9D,1B,B0,D0,B9,C4,9B,FA,32,20,0E,29,9C,08,95,F8,04,77,85,59,07,E6,00,18,EE,2B,23,A1,C6,6C,D0,84,B1,5A,40,B4,B0,C2,B9,11,F1,C1,C9,D3,D8,22,A4,26,85,37,17,51,7B,BC,E7,14,C3,8F,0A,90,2A,AC,CD,8E,58,7C,0F,8F,89,92,8F,1A,42,73,3D,BA,DA,40,59,6E,A7,ED,85,13,44,33,59,47,65,D0,89,A5,D7,95,38,32,81,59,68,7E,9D,BA,D5,88,2C,1F,AB,90,21,CF,55,52,43,1E,58,D7,B6,91,89,BF,EA,69,A0,B0,C0,EA,C0,B5,1F,3C,2F,5D,96,F6,59,60,05,C1,ED,DA,96,4A,34,DA,07,C9,63,F3,0A,06,38,F3,F7,C0,86,2E,5B,A0,50,2E,AE,CA,B6,F7,78,BC,DF,E8,5B,2A,DD,8A,3E,32,56,78,72,FA,25,64,EB,B2,73,2E,6E,6E,12,A7,8E,40,E8,F2,1B,7D,8E,AB,A7,BA,EA,25,6A,65,7B,D4,A9,F9,A3,B2,A5,17,11,94,32,BD,D6,87,7C,8B,75,85,5C,9E,F8,89,E0,01,86,B9,C6,41,3D,3C,3F,3D,4C,FD,23,9C,C6,61,1C,DF,DA,C7,47,1D,2B,60,A2,8D,3C,46,9F,69,85,A9,5D,80,8F,4A,65,2C,3C,38,F8,61,93,6D,5B,E5,B3,EF,44,C0,51,08,8C,F3,DD,28,3C,85,B1,1B,BD,9F,47,FA,F5,06,A5,43,BF,6A,A4,6C,15,92,20,AA,86,19,AF,E8,30,C0,4C,6E,4B,EE,22,79,BE,65,EB,0A,16,A6,E2,94,5D,D8,E5,A1,84,96,24,65,D0,BF,C3,33,86,51,26,89,E2,67,E5,EC,D7,F1,E3,5B,69,39,54,00,EB,43,70,51,5F,E3,C5,01,33,D0,5B,EA,8B,9A,39,6F,70,5A,AB,1B,58,21,43,6C,AA,BE,D9,D4,58,7D,05,78,2B,4C,13,CA,57,AE,6B,FF,56,0A,27,52,00,FC,E6,D2,3B,72,0F,C0,B2,39,31,6D,84,D7,6F,3A,D0,1D,6C,5B,C7,8C,A3,05,26,4A,38,E6,94,8B,3E,50,97,F5,49,38,2C,26,33,CC,2B,B2,05,C9,3F,F0,43,32,B6,E6,E3,69,27,AC,59,E2,E9,34,F0,F0,56,F2,28,9F,3B,20,CE,50,0C,D1,19,B9,17,6B,26,96,A0,DE,FE,93,E5,DC,B0,45,F3,4F,93,23,EE,D8,23,F5,E3,E0,E7,3D,9A,E7,90,2E,54,53,06,64,FC,22,EF,E6,20,E3,D5,37,92,65,1C,02,5B,31,0B,25,3A,ED,16,65,C3,FF,81,C0,48,BE,0C,05,3D,77,30,53,C1,39,5B,C7,F3,D6,B9,F9,41,36,AA,DB,62,2D,C4,4F,79,F9,73,BA,EA,4D,56,75,ED,47,3E,52,39,8B,85,06,A8,D2,ED,BE,EC,C1,5D,00,C5,F8,29,E8,B6,EF,E0,8F,FE,83,21,1D,A1,5D,F5,AD,7B,EE,95,52,CA,86,C6,E6,A3,EF,FF,29,B4,5F,2A,05,C0,C8,54,18,E0,D7,77,D4,B7,1C,47,23,14,4E,DF,31,87,BD,50,30,66,D5,25,3B,67,18,31,92,8F,EF,94,DC,5A,1B,A0,A8,EB,5E,72,7F,31,25,43,E5,80,99,AA,A6,AD,26,22,52,A1,50,35,98,E1,6E,7D,1A,91,B1,1F,C8,61,18,8B,11,9C,6B,13,86,91,68,FE,DF,F5,DD,B2,8D,00,C0,21,72,76,D8,27,DC,1B,E5,CD,71,98,AD,50,E3,C4,85,FE,3F,25,67,FF,A8,20,C8,7B,BD,8A,BC,A8,B3,E4,6E,40,5E,DC,B1,38,48,31,DE,76,8A,63,5B,57,52,C9,09,A8,69,F7,32,D3,86,95,CF,FC,15,8F,9D,27,31,04,A4,A9,6B,BA,FF,96,0A,83,8C,15,75,B7,CC,3B,63,58,75,B0,EE,22,39,B2,89,2F,D1,09,67,C4,FC,F1,FD,82,BE,1B,22,E6,8D,4F,A9,29,83,3C,BA,69,24,3F,66,AD,A2,78,AE,75,31,02,C1,28,E3,1B,6B,E0,3B,AA,A6,39,82,AD,D7,B1,EF,21,23,9A,96,3F,0E,4A,B6,74,8E,37,15,3C,D3,F9,0C,21,70,89,B6,51,9B,8E,14,A8,7E,55,77,F6,C1,70,F2,D6,54,C5,23,23,34,96,64,8F,DA,09,B8,67,D1,D8,0A,5D,53,4E,82,6B,13,71,25,0E,AA,60,FC,AE,D7,52,79,29,C9,15,7D,A3,48,59,01,13,BA,B6,FE,49,D1,B9,F2,CC,60,99,BB,3F,B4,12,26,50,6A,4F,AD,0C,E7,6A,32,CF,56,43,93,ED,5B,24,D7,E7,DF,CB,0F,77,07,6D,28,59,C7,47,2D,FF,E3,05,C7,12,CD,EF,9C,07,87,44,CD,8F,AD,8B,BA,D5,8E,D9,1A,3D,D1,5B,A0,15,7E,C3,55,98,6C,66,97,73,46,8F,9B,DA,C2,4F,E3,92,75,70,83,24,35,D3,15,27,5F,CF,68,75,C7,46,30,F5,74,4D,16,58,33,E9,58,F7,2B,CA,39,E4,1D,D6,7A,D3,84,B9,55,BD,D1,61,8B,A2,27,36,5E,4B,F7,27,0C,76,2E,F2,D5,15,04,6D,B0,A1,F4,01,35,1C,99,2C,9C,B1,53,D1,B6,59,6F,23,3D,8C,65,F1,2F,78,E6,0A,18,EB,4F,A6,3C,C7,B0,14,5A,F0,CF,BB,06,A3,07,54,F9,8B,C7,4F,2D,70,F2,FF,1B,89,6F,AD,D0,1E,71,E8,B7,AA,20,A7,E6,B5,BF,B8,17,3F,B5,CC,CC,44,09,02,8C,7F,7F,C2,EB,68,5E,22,AD,FB,EC,02,B2,C8,5F,0C,5D,D5,5A,88,EF,6D,C8,91,E1,23,6F,25,44,38,94,23,F7,9A,C3,22,E7,5E,7F,B7,97,1A,D5,1A,BC,E1,C5,BD,AC,A6,A7,19,05,D8,D5,5A,B1,45,A9,B1,6C,36,E9,79,6B,99,B8,8F,1F,22,5D,C7,24,CD,A9,B0,D1,81,F0,C6,A5,90,83,49,B5,6F,95,D8,4C,DB,BA,5C,2A,B3,33,46,A5,5E,31,1E,40,C9,16,06,A1,D6,72,78,01,4D,00,73,CC,4E,1F,47,65,6C,18,B2,B4,4A,E7,E7,25,8B,62,69,26,57,A4,22,C1,A2,5C,C3,8E,9E,49,00,FE,2C,19,BB,C2,A7,C2,A7,0F,7E,91,7F,2E,B5,A8,1A,27,3F,FD,CF,5F,C7,2A,E0,0C,96,48,5D,A3,E5,42,19,45,B5,E0,AB,FE,BE,CB,20,50,EC,05,E1,F0,B5,E0,9C,66,FE,20,AD,A5,9D,52,FE,72,58,22,99,C3,27,19,3E,AA,CC,4C,D4,10,0A,39,4F,F2,80,46,1E,64,F9,69,CE,73,EE,27,1E,D6,1A,A4,9D,0F,63,11,E7,24,84,33,E4,FF,A6,2F,66,95,C4,33,C2,73,F8,37,A3,17,C7,F8,D8,14,10,CB,64,B4,E5,18,83,C1,84,6F,10,E0,03,D8,AE,1D,15,0E,97,53,0F,26,EB,80,E0,CA,AD,75,4B,94,C6,67,37,60,7D,9C,16,E4,11,5F,B1,78,28,CB,FE,90,87,04,2B,96,97,13,24,4C,6A,57,9D,26,36,BA,C0,5F,64,AF,44,D6,0D,EB,FE,F8,9A,87,68,BB,BE,99,C6,8E,82,7B,E6,9D,18,C9,1D,6C,19,89,53,97,0E,D7,C2,86,56,B0,50,5E,FB,B6,E6,7D,DA,87,05,C1,53,F8,8D,A7,93,88,3D,E6,D8,8C,61,37,F1,11,37,3E,2D,F1,25,86,6E,06,55,AA,CA,EE,39,12,E9,D7,18,A6,DE,4D,92,E5,47,1B,7F,CC,D8,E4,2C,B7,3F,FC,F4,72,92,7A,3F,34,4D,62,8F,23,01,2F,73,FC,3E,D5,B6,2E,35,CF,82,6B,A6,4C,30,06,F2,1B,A0,C6,BC,9E,63,23,5E,50,17,02,9D,1B,43,6D,C8,F7,F1,D5,9C,2A,A7,59,D0,14,E0,CA,15,40,A8,26,47,21,41,0A,A3,42,A9,31,64,B6,08,4A,50,5D,DB,5F,1F,88,35,59,F7,FC,F3,EA,8F,B9,11,44,76,40,31,31,5D,B2,A2,3E,7B,77,76,00,BD,50,19,06,41,1E,C5,E9,C4,5B,6E,E3,87,0C,55,9E,AE,99,93,89,29,46,07,06,98,F6,60,00,0E,6F,0A,04,EA,5E,52,76,60,5E,85,01,A0,CE,6F,EE,D8,14,62,D5,2A,01,03,A4,99,CC,8F,09,5E,0B,6F,03,FB,F0,ED,40,11,A3,6F,87,9A,22,92,09,47,22,9D,9F,FB,84,A9,E7,00,5F,30,1F,AC,CB,D1,5A,79,0D,E9,73,DD,73,35,73,1F,A1,5D,3F,A5,D6,9D,CA,5E,04,CB,DB,03,5D,66,CE,8E,00,A6,6E,3F,E7,D4,6D,93,E5,2A,D9,91,89,58,67,BE,A7,F4,F2,60,60,CA,1B,8B,9A,A6,E2,48,8B,2F,6E,7B,96,2B,C7,B9,A9,90,95,EC,E5,BD,44,71,52,5F,AC,97,6A,9F,BA,25,33,61,C6,F6,AE,E1,79,37,9E,CB,17,47,ED,12,4A,03,41,35,34,F8,5C,1B,44,F6,72,D1,01,2D,42,F6,BF,D4,FE,2F,12,06,A6,D6,ED,5A,6F,1B,C9,DB,9C,86,3F,8F,D1,20,DF,F8,71,65,BF,77,B8,D0,B2,08,56,36,A2,53,03,AF,EA,15,6C,C1,6F,0A,8D,9D,AF,31,D2,4D,33,34,97,08,44,80,D4,38,9D,90,27,57,64,1B,86,D4,73,EB,B7,E7,8A,15,35,62,6F,E4,B2,D4,77,A4,37,DB,96,2C,F7,44,53,61,B0,12,14,90,74,34,6C,2D,72,1B,E8,97,76,68,CF,E5,B0,48,E6,D8,A0,C7,C8,8A,3F,22,EC,B9,45,53,1E,B8,DE,ED,BE,65,1A,1D,62,10,FF,0F,FD,B3,AD,A5,01,36,46,A0,71,3A,CB,16,C8,EC,5E,B4,92,CE,DF,91,9A,8E,5F,AB,EC,EF,C8,8F,EB,72,2A,C4,BD,46,52,07,30,02,F2,2B,2E,5A,E5,FB,94,B1,62,E5,05,3C,BD,AB,A2,E9,7E,CB,31,8B,81,E4,70,E0,A5,0C,03,FF,AC,E7,43,30,2C,C6,3C,E7,EC,EE,02,48,5D,24,87,8C,A8,B4,FE,D9,12,D1,32,E8,B6,6B,F8,0F,2B,1D,C7,57,A6,BA,B9,61,7C,7C,AC,6F,EE,67,98,45,0E,7E,6D,46,97,6C,09,37,E7,93,37,C2,41,23,88,49,A7,8A,AB,F3,11,58,8A,69,80,9A,B2,DF,65,58,9D,58,6C,38,60,74,C8,D4,39,D0,9B,96,18,B0,62,74,74,A5,9D,3D,EC,DD,9C,D4,82,EE,55,07,FB,92,A2,D4,60,27,3F,5B,D2,E5,E6,B6,C3,5B,70,8F,F1,FD,06,93,6D,A6,1A,F7,52,98,E1,19,BB,CF,3E,51,13,F7,A4,A7,88,E2,B9,58,00,3C,AD,AB,25,E3,03,23,B9,3E,11,61,48,20,A2,90,52,C4,50,7D,7E,95,27,12,FA,D9,B4,27,44,7B,CD,4C,9F,B8,16,F6,3F,C6,66,25,EF,1C,58,0B,43,2A,FA,4B,60,B5,2B,C7,C1,11,8C,11,45,F3,E4,1C,AF,13,A1,1E,9E,DE,F0,FB,2D,0E,66,84,99,A3,E9,39,84,E5,5D,96,CD,34,BD,AC,4A,46,6C,F9,14,47,A3,A0,98,CA,AC,7F,06,77,83,02,43,8B,82,63,CA,9B,B7,61,83,F6,CC,8F,F3,A5,B1,63,B5,98,11,40,AF,7A,7A,5A,B2,C5,70,58,DC,BE,B0,C9,4C,87,B8,7B,12,F2,23,13,57,D2,A5,90,21,3C,19,ED,A7,1D,F0,AA,95,24,05,5D,4D,AB,22,35,CA,B5,07,AA,A1,62,B0,57,68,A3,55,7C,F9,6C,3F,0E,F3,97,9F,01,F5,F0,56,87,14,3E,DD,BA,61,A2,FB,C5,4E,1C,CD,43,C6,7A,A7,38,75,1A,09,32,C2,9F,21,01,FC,5A,0A,A1,3C,C8,36,25,75,61,A4,B5,DA,A4,4F,5D,EA,52,0C,9D,CA,2C,53,CD,DC,18,B2,0A,38,05,14,01,01,9A,A8,4C,6C,46,8A,BF,3A,F0,C5,94,1A,29,9B,7A,F4,29,87,3C,09,93,C8,98,5B,64,5E,F0,3A,EC,7C,45,10,AB,37,B5,D7,DC,F6,DE,D1,82,C5,EE,05,E4,71,E2,5F,0E,49,11,D3,BB,33,2D,63,4E,DF,A4,F3,F8,F1,A8,8A,6E,4E,9E,3F,B8,1C,9D,C1,D6,A8,07,04,A1,A1,00,CE,A8,82,50,A9,5A,5C,BD,8B,7A,50,C2,2D,BA,5A,92,67,AF,21,05,7E,22,37,9C,C7,E5,1C,16,A8,1C,43,B9,36,0C,EA,12,D1,9A,E7,18,D0,6A,2A,4A,F7,6D,E1,8B,63,94,77,3A,29,34,30,FB,48,0B,D9,E7,40,E0,96,04,ED,CC,1D,32,E4,CF,15,66,34,78,7C,79,E1,2B,4E,CC,27,50,68,B3,5F,F7,4C,5E,2D,70,91,0C,9B,99,AB,A5,93,6C,CE,10,D1,9F,27,0B,E8,F7,2B,09,0D,AF,E1,14,76,B8,FB,CE,3B,FF,F4,7A,19,32,FC,FC,22,F4,9B,41,06,D7,F4,D6,70,29,84,23,C3,54,C4,D6,EA,1D,D6,AC,5C,7B,DE,A8,77,BB,53,23,C9,08,65,C5,31,0E,05,C9,46,C9,EA,6D,5D,49,32,4C,13,38,D2,F6,F8,19,70,54,42,7F,91,6F,8D,37,E8,41,CB,95,60,75,A7,2D,A2,0B,D2,83,C3,0D,59,8A,6B,FF,4D,9C,9E,FF,55,04,26,3C,3D,86,EA,FE,CF,C5,20,E1,0D,64,CB,9F,35,50,B9,24,94,35,CF,6D,D8,6A,3A,88,16,90,58,90,20,EA,6F,26,7E,1C,A5,7E,DD,F0,5D,BB,A5,62,E8,93,B2,95,8A,CF,2C,9A,D9,BF,FD,16,D0,0B,8C,C8,0F,38,18,7B,AE,0D,55,AF,C9,75,3D,E2,10,49,7E,12,08,CB,39,1C,6D,54,93,AE,05,38,67,3D,08,D6,C9,50,47,6E,26,DA,5B,AE,74,C7,92,8B,F4,56,AF,65,F3,E9,86,3C,CF,0D,85,FF,3E,AE,EF,71,13,58,FC,AE,2E,8C,85,CF,C4,10,E4,E0,E2,1E,8D,D9,C8,F9,96,6B,19,EE,78,AC,58,05,29,65,EF,B6,D5,2F,EB,15,32,21,98,15,01,57,A2,61,6E,6E,10,36,D9,A7,A8,9C,14,6B,9A,5A,05,F1,05,89,4E,34,03,E4,55,89,50,E6,82,3F,06,2A,57,50,B2,83,8F,EE,71,3D,97,17,98,B5,4B,BE,B1,26,79,E4,AF,53,05,DD,9F,9C,D8,A8,C8,4F,62,39,37,60,6F,2A,FE,62,FC,58,98,6A,B7,2D,38,FF,D1,1B,A4,98,B5,3C,4A,4C,7C,DF,56,6E,D2,81,8D,4A,46,9D,C3,50,9B,A3,BB,BA,42,37,7B,4A,12,6F,9F,14,54,63,B8,A8,A2,8D,13,19,2E,BF,04,6C,09,0B,C9,76,CA,F3,89,00,54,50,EB,E0,39,1D,AE,DE,8F,9E,8F,F4,92,57,11,B7,2F,20,29,F8,12,1B,CC,D9,DB,46,3A,9D,57,2C,FF,E7,01,3C,16,C3,74,DD,3D,77,EB,FA,8B,83,E5,91,21,43,37,9F,7C,B2,18,00,A6,B5,6F,D4,24,1F,14,B5,4D,3C,55,6D,FF,17,AA,D1,FB,4E,18,E6,7F,DF,0F,B8,32,9E,4E,5B,AF,B3,26,D7,9A,CB,DB,9A,1C,82,BC,A7,36,08,17,6D,84,B0,33,85,65,C3,89,EF,5F,9B,85,68,CC,5B,AE,27,61,0C,26,C5,65,4B,10,F2,DA,1E,9B,44,27,DA,D1,E0,64,09,9F,48,61,07,F6,BE,66,97,56,53,0E,EE,48,B6,50,DC,FB,32,02,70,53,E7,68,C0,8C,D6,DE,03,B6,2C,5B,7B,B1,5C,74,6A,DA,66,87,17,C2,0A,21,C8,87,A5,61,E3,0C,80,17,05,34,32,F4,AE,65,50,27,1E,03,C6,92,6D,99,2B,1B,1A,6B,8F,18,AF,6A,AD,CA,3F,E8,BB,CD,B2,BF,43,68,6B,2F,DD,C4,1A,CC,8B,11,CD,57,74,A8,7F,72,F6,BB,9C,EE,F5,E2,76,54,1D,35,A5,1C,B8,74,A6,11,6C,AE,4B,7F,BE,5C,59,91,09,F3,5D,21,DF,6B,C5,B1,CC,6B,0B,32,C3,22,17,15,4F,BE,93,CF,E8,C7,CC,59,C6,B9,5B,FB,C4,FA,11,84,95,55,A0,45,33,48,9B,79,E2,00,29,36,79,1F,60,43,63,92,13,F0,73,6C,E2,BF,49,3B,CD,C3,97,34,44,19,FB,74,08,09,FF,56,CE,AC,1B,A3,8F,F8,9A,4D,48,19,83,37,60,80,75,4D,B6,8F,30,1B,8C,25,F1,63,5D,79,0C,51,8E,73,1F,F5,49,C0,3A,54,D3,77,D0,B2,9A,7B,AA,A7,F9,4F,3C,78,D6,AF,12,92,49,E2,C4,42,6E,01,F3,5C,1F,38,E6,29,E6,FF,3D,61,7B,7D,13,F2,F7,E1,24,A4,91,8D,E3,7D,0E,7D,E5,2F,4D,40,25,FB,F8,36,10,10,EF,C6,3A,9F,AC,DC,76,D3,4A,2D,61,01,D2,E7,0F,4B,38,98,DC,CC,37,D2,51,73,B8,0E,9E,37,82,F3,AC,58,A6,E9,6B,A8,F0,FE,28,E5,31,9B,6C,99,EC,47,78,B0,F6,7F,CA,48,93,DD,2E,F8,64,DB,DD,6C,88,C3,21,AB,C0,37,29,F5,5A,7C,3B,41,1F,55,2C,BD,46,21,7E,85,CE,0B,4D,A9,36,81,0D,4C,B9,54,94,8D,4E,B6,3E,59,7F,AA,74,57,B7,4B,1A,0D,DE,A3,66,0F,EA,FD,FF,B4,D1,86,0B,76,3F,A0,2E,54,E9,68,2A,3B,A8,EF,5F,5F,98,FE,B1,55,FC,76,08,1C,F3,C7,DF,4B,24,F2,F5,F4,8A,63,5D,B4,37,4E,81,17,77,B1,D8,B5,8F,FB,E6,18,F3,40,3A,DC,F3,1E,0A,89,21,54,6D,35,2F,3B,B6,55,8B,29,0D,55,B8,BB,B4,76,79,1B,FD,DC,51,CD,56,F6,F4,3A,50,EE,40,8C,5D,21,67,23,49,D2,19,CE,FF,8C,1B,50,1B,81,87,E7,EB,0A,D7,AF,15,10,CF,65,5C,B1,C9,B3,00,64,A4,13,68,82,12,2A,57,57,9B,42,DA,AA,13,11,86,9E,C8,DF,37,3A,16,E4,5E,DA,4D,E8,3F,F9,5E,02,CA,FE,2A,24,31,BF,38,12,7B,A6,3F,40,03,A1,C1,E4,92,D8,60,3B,84,00,AA,F6,97,07,A7,A1,91,17,22,8E,04,4C,88,72,E2,25,83,ED,06,36,90,CF,17,24,82,13,07,93,D6,0F,82,0B,6B,91,8A,6C,1D,9E,2A,1B,54,53,5F,55,53,5E,09,92,8D,E4,2B,99,02,29,98,7E,94,37,3A,C0,EF,1A,55,4D,4B,08,FF,09,D2,6E,0B,BB,6F,D9,92,30,75,F4,7D,2B,67,D2,9B,9F,F6,FE,93,A4,63,F7,19,5E,11,02,50,A2,53,B2,7D,08,19,7D,68,86,18,51,A1,F2,AA,83,37,5A,66,FF,72,FA,5E,C3,67,56,2C,AE,EF,C4,9C,C0,D8,48,EE,31,AD,11,2C,AE,99,85,AC,65,23,D1,A3,67,49,34,6E,29,1E,2C,1A,98,12,45,0B,C8,35,DE,59,6F,8E,AB,20,5A,1E,76,43,F1,C0,1B,05,07,10,98,0D,41,E5,B3,8F,00,1E,C2,29,2F,71,32,5E,D3,3B,60,03,E5,F5,E2,98,48,79,E0,E8,73,14,28,47,7B,04,EC,F6,78,B4,1D,73,F1,E7,34,6E,89,63,8A,7B,C2,C2,6A,40,DC,62,B6,92,F5,70,57,A3,A9,A3,1A,15,BE,BB,10,57,BB,5D,F3,78,67,41,2B,0D,E1,B2,5E,3A,B4,74,F8,BD,84,62,25,35,99,44,B3,85,33,D5,EF,E8,BD,E9,D4,24,78,19,5D,D4,7A,5D,D4,5C,FF,F2,5D,5D,CC,45,83,DB,1F,6E,31,58,07,EC,AC,66,98,00,26,A1,A6,12,CF,90,B6,FE,DB,77,DA,ED,32,8A,2B,0B,AD,D5,A4,90,DB,4A,55,8A,01,ED,8A,0E,8A,5A,AE,28,71,FC,96,EB,02,56,35,57,81,2C,25,C4,BE,20,B3,48,78,7E,0E,A9,DA,2A,FF,A9,C0,22,2C,BC,2D,29,76,10,5D,A6,DA,4C,70,0E,5F,9C,EB,9A,94,A9,6D,3C,40,5A,AD,B1,E6,04,9F,F7,AC,C6,56,74,94,98,38,0E,7A,AB,6F,42,3E,E2,8C,14,8B,36,0B,8D,F5,1A,09,64,3C,99,1E,81,D1,99,38,35,BC,8B,8C,17,78,8A,93,A1,E6,B4,7B,DC,4E,4B,C7,AA,AB,D3,6C,9A,9B,40,4E,A7,A6,6C,68,36,5E,A6,85,D9,5A,FD,56,8C,5D,3E,49,56,98,0B,80,76,2C,41,BB,65,95,F3,56,61,0A,DC,9E,04,8F,D0,E8,AC,87,AF,D8,15,20,7A,E2,DA,2A,F5,94,DE,0D,8B,5C,B6,91,F9,CA,6B,F1,58,E8,34,3F,07,2C,57,1E,B6,D6,13,59,A2,E3,DC,C6,7E,CC,C2,E7,66,F6,DE,40,4E,32,E5,CA,9B,1F,EB,EC,2F,A5,74,54,62,0C,FF,99,41,89,C9,57,44,50,6C,73,41,B1,D2,65,74,B1,1C,AC,A2,CB,A4,D1,D2,CA,46,B3,64,E5,04,66,D5,C0,2C,A5,01,83,C1,D7,13,E7,BF,37,14,3D,C6,9E,96,9F,07,62,AE,F1,B6,56,0C,31,FC,62,6D,04,A4,6A,A0,24,64,11,D7,7D,86,48,84,82,D1,DE,31,BD,BA,5D,11,38,D2,DB,10,56,19,C6,45,7E,A2,5C,37,20,67,8E,03,FD,32,58,E4,55,89,ED,A4,67,C0,98,19,0B,90,D3,0B,49,C3,7E,A4,ED,02,A8,24,17,02,A2,03,3A,B9,0F,70,CA,38,B9,E8,3C,D1,72,1C,08,9B,73,70,50,7F,4B,4F,77,55,D1,10,50,EC,04,A5,D8,7E,1E,30,BE,88,26,A7,88,61,05,34,27,F9,72,A3,B8,3D,13,B8,09,6B,AD,59,C9,FC,5B,4D,F6,EF,67,F8,55,94,A1,2A,B6,8F,E5,FF,E0,AD,58,60,0D,53,59,F6,6F,F8,5C,7B,2A,20,17,4F,41,75,22,A9,65,78,45,61,5A,BE,DE,15,A3,EC,47,7A,45,A3,A5,9F,A0,56,E3,C6,61,CE,7B,8B,91,13,D3,22,EF,9A,3D,74,4B,24,B8,1A,9F,F6,19,3A,6D,B5,A0,5C,0C,C5,AE,20,19,68,7D,2F,BD,4F,69,2F,54,57,1B,15,4B,B8,42,30,90,81,32,6E,21,AC,A3,66,71,84,A0,65,47,2A,1B,0C,D9,7C,72,62,EA,0A,BD,6D,89,71,28,A4,93,77,6A,A8,73,CA,B6,7D,C3,5D,3E,F0,E7,69,1F,F0,8C,D2,75,4B,6A,41,84,AF,FF,CA,E8,F0,BC,0F,F2,99,4E,B2,E3,3A,1A,0F,88,A5,B8,E2,16,E6,7A,F8,96,82,37,68,7E,C4,87,50,65,31,74,4B,14,B5,6F,49,40,31,A8,45,C5,C6,67,C1,70,80,C2,E5,5F,58,E3,E5,66,E6,CC,77,B1,EF,9A,45,F1,73,94,37,39,E4,D1,20,96,25,7E,4A,5F,DD,6C,95,41,6C,52,02,8D,EE,D7,EB,F4,D8,38,5F,71,7A,A4,D5,E6,8C,15,CC,37,DD,B6,CE,67,74,B7,E5,66,9B,F0,42,FE,AE,25,A3,AF,71,A9,ED,DA,57,5B,3C,7D,B9,46,22,96,52,A0,40,FC,3E,BA,66,29,AE,37,CF,BF,F1,D8,A4,D7,2A,AD,CA,A8,11,9B,2D,AC,22,5D,EA,E8,84,33,51,A7,26,19,A2,A3,77,B5,92,BE,89,87,6B,02,67,F8,D8,B7,D2,BA,15,6E,15,B1,7D,EA,B4,78,73,F2,AD,38,CD,DE,FA,C8,FB,9C,FF,34,88,11,0F,3D,43,2D,80,58,E1,ED,6F,11,25,3F,25,83,32,53,3A,9F,17,D7,03,2E,FA,28,37,AF,3E,CC,84,7C,2B,FD,47,B1,1E,CA,CF,95,35,58,E3,C8,A1,1E,F4,D2,18,93,86,3D,04,DC,E0,8F,02,18,E4,6A,F6,43,E4,3D,58,62,E7,B2,7D,7D,0E,81,1B,E4,9D,61,DA,CB,67,16,3C,9E,59,72,D9,37,07,D3,85,E7,78,2E,CA,A4,5A,F7,D9,74,C1,37,E1,AC,92,F8,0E,DD,6E,1A,13,29,2B,21,17,05,72,DC,C8,68,C8,F7,30,BA,6B,DC,FA,F4,E5,20,C6,95,ED,2D,D6,EA,B5,D0,D1,0C,E2,80,7D,7B,2B,A9,C8,2D,71,D1,6B,16,CA,13,71,8B,3F,9D,10,DD,4C,DB,B6,A1,D2,59,5B,1F,E7,BD,1D,C4,E7,0B,2F,42,87,80,81,F7,28,3B,80,A0,DE,3D,A7,CC,69,14,F0,66,74,A8,9E,1D,4B,7C,F0,8B,6E,4D,ED,5A,0C,86,EA,DA,F6,D3,33,AA,EB,BA,F4,F7,39,20,CA,FD,9B,86,4D,50,CD,E3,29,09,74,11,B4,0C,F9,7C,85,FE,C4,98,09,37,37,02,64,F7,84,37,20,D6,CE,EC,60,72,4A,73,D9,98,A9,D7,0A,B7,01,E2,3D,62,91,4A,7F,C2,C0,50,DE,9E,A8,F9,50,59,94,70,F2,EA,CC,E6,0E,3E,EA,BA,08,98,AA,6B,A8,B8,E9,C5,6B,54,EE,BD,BA,BE,A5,45,CC,03,A2,82,43,14,6D,F5,2E,5E,8C,D7,35,5C,78,0B,F6,DE,58,09,E3,E9,A9,BD,09,4E,48,B0,7E,77,9B,B3,10,56,35,7B,A3,E4,11,A1,19,CE,D3,35,8A,EF,D2,E4,37,31,F7,C6,D1,34,93,06,1B,9A,FB,4D,9C,2C,AE,6C,EE,A8,AB,16,AE,75,98,D8,84,95,65,56,20,E9,FC,70,D1,10,A2,D7,FC,37,AD,26,E8,44,C3,42,CC,18,C3,59,C9,3E,77,0D,FB,8B,27,D1,A4,97,41,B9,D7,58,4D,C6,CA,51,53,8C,37,AA,7B,E2,BA,42,9B,3D,EC,81,8F,BB,06,46,10,39,76,F7,73,A0,D0,7C,35,7F,64,28,C0,AF,A9,80,B8,B7,6E,25,50,CE,DD,0B,E0,18,EA,29,D7,27,CD,B0,9D,44,DF,53,40,F7,D6,98,63,60,57,73,03,30,A5,F7,37,5F,14,88,9C,60,9D,EA,00,E1,DE,DE,3B,1D,05,15,03,63,CA,33,6C,08,69,5E,6F,90,CD,50,79,53,A5,66,76,DD,55,12,49,B7,9E,18,49,D9,D5,7E,FE,1B,7E,B7,DF,61,46,63,5C,C9,91,F9,86,AF,D3,34,F7,9D,6B,2E,59,51,90,20,D9,6C,3D,3F,2F,8E,76,3E,33,F5,27,B6,25,FE,AE,AA,84,49,69,BC,02,A4,58,47,34,F5,E5,50,A8,CB,93,26,5A,A2,07,16,4C,C4,C7,46,9F,38,D6,77,E0,8A,0D,58,AB,BF,E6,F3,AD,27,DC,27,4E,A2,AD,3F,BB,0D,87,B1,97,E3,21,09,32,10,2E,3C,82,99,11,81,0F,45,D4,E0,35,3F,76,EB,55,7D,54,F1,4C,36,BA,DC,4E,E5,02,7E,87,B6,7C,11,6B,0C,9D,12,B3,F0,1A,9C,26,75,2D,3F,94,06,E3,DA,30,B4,72,2C,9B,4A,E4,31,D8,47,3E,CC,18,CF,62,9C,4D,E5,31,B6,D5,FE,E6,9A,96,70,C9,D4,5E,AC,1D,69,3D,79,00,CB,24,3E,FA,14,43,03,A2,62,FF,31,BA,30,7C,3A,45,DD,0E,89,66,8F,EA,52,DB,12,3A,33,1D,E8,98,BC,FA,C4,61,0B,50,63,E9,E3,CD,D3,18,B8,77,7B,59,47,46,63,37,6D,3A,7A,89,E8,71,FF,11,28,8F,70,B7,90,EC,C4,78,9B,92,54,86,B4,4E,14,48,CF,E5,30,45,61,07,03,3E,8F,B2,4E,C4,BA,0E,18,D2,66,82,25,6F,61,DA,5F,5E,59,8D,E4,7A,5C,AE,8C,DE,07,02,DC,57,1A,C7,23,BB,AF,92,83,6D,98,57,F1,98,AC,06,79,14,95,4F,E6,EA,78,9D,AE,D4,3E,43,8F,E8,0E,E9,7D,6D,EC,E4,E5,46,8E,02,1F,00,A0,C8,7D,AA,DC,6F,45,2A,67,08,C4,50,26,E6,C4,7C,98,CD,B3,D2,20,ED,3D,15,3B,6A,31,3D,76,39,EE,24,30,80,5B,82,4A,8D,CB,21,FF,D7,66,FA,94,32,A0,CB,9F,36,1B,83,48,BA,D0,F3,24,8D,E3,22,29,B1,16,0A,F1,E9,AD,DA,10,1E,B9,61,33,A0,F1,A6,03,7E,BD,FB,A6,A9,A9,A7,7A,33,38,02,3A,FD,47,0F,C3,9B,0B,4D,1B,FA,84,60,31,0A,DD,35,F9,30,91,E8,E3,4F,69,E1,03,95,AA,E9,E4,CA,D9,C0,EF,6E,6E,AA,91,A4,94,EF,9F,90,E9,17,A0,34,33,88,92,A1,67,B5,BE,65,CE,02,4A,63,31,49,77,A1,91,DA,5E,93,9D,0A,0E,D9,6F,FD,B6,B0,BD,3F,F6,ED,FF,64,D3,E2,EE,2A,55,AF,41,60,96,CF,EB,7C,41,6B,79,29,50,22,CC,1A,D0,F3,73,E8,1E,49,76,F3,BC,BA,67,73,31,AF,9F,7F,E8,35,48,57,EA,F5,12,F5,F6,48,70,FC,F7,48,5B,C4,8F,C3,5C,54,42,91,66,72,54,5E,22,EF,94,DF,68,0C,9E,B8,ED,04,74,82,28,92,D5,D9,12,91,9D,4A,8A,0E,33,D7,74,D9,7B,C8,9C,29,6A,FE,11,83,5C,69,D1,67,4A,CA,85,A0,4A,F6,EC,60,59,B3,2F,56,2F,7A,BC,C4,AD,A9,D8,CB,2A,52,1B,B4,01,73,76,E1,C9,65,D0,E5,60,B8,5F,70,11,19,15,DD,25,94,7B,D3,E1,7F,BC,F6,D6,92,B3,FD,E4,1E,D6,23,CA,04,E0,E8,20,58,1E,39,61,13,13,9C,19,4A,E5,5A,3A,C9,71,DD,F4,C8,B4,F4,DB,4F,0C,FA,85,E3,12,4D,A4,6C,73,F6,C3,E0,60,C0,D1,B3,0E,46,48,6E,64,31,C3,EF,3F,E0,1D,FC,E4,F0,CA,10,6F,4A,7C,FB,94,5F,E2,BF,B6,4C,56,CE,59,5E,98,74,1A,5E,6A,43,92,C7,00,AA,E1,3F,B2,82,30,48,AB,9D,81,91,6D,DB,C8,67,90,B2,88,75,26,31,8C,40,34,7D,08,EB,27,B8,90,E8,8A,8E,90,E7,76,78,AB,92,26,E2,35,1F,56,7A,B2,0A,2F,16,F3,02,24,A3,AB,33,88,A4,81,0E,8D,EB,AA,96,4A,FF,85,1B,ED,4C,5A,C7,95,B1,75,93,F7,89,F6,13,9A,DF,1B,5E,45,81,10,52,00,53,45,4E,18,BC,3E,CD,32,9F,E6,8F,E8,26,2E,2A,D8,8B,45,E0,52,41,39,9D,F6,31,6B,98,93,35,5E,01,14,EC,20,51,F6,2B,D3,9A,FA,09,10,FA,51,D3,1E,85,40,E7,2B,2C,89,9F,21,A5,D2,9A,4F,27,89,55,1B,75,08,9A,DC,41,94,CF,6C,47,D1,41,0C,A9,D1,30,B9,74,34,5B,78,D0,27,06,0A,58,39,A3,81,6F,F4,90,73,BC,C3,74,44,9D,FF,66,8A,06,C4,D7,03,B0,85,13,C7,F8,2B,12,AD,2D,66,94,61,24,AD,80,1E,7F,8F,3B,BB,6B,18,32,54,59,FE,7E,7F,03,94,80,02,B1,88,73,5F,D2,5D,44,A6,12,3A,41,B4,DA,14,7A,7E,57,28,A6,40,DC,83,13,63,95,B3,FA,0E,D8,11,F2,45,9D,C3,2E,36,42,C9,0F,4A,C1,0A,87,08,E4,C2,68,63,AF,C0,AD,B0,2E,2E,72,9D,F8,7E,AE,15,3C,76,76,CC,72,F2,59,DC,08,D1,46,4F,20,A7,70,CF,7C,9D,58,F7,F1,20,B0,14,59,2F,12,AC,21,8D,36,00,DA,03,8E,69,AF,B6,F0,A4,4A,7C,56,58,17,51,17,1A,EF,BD,68,A7,5B,32,BB,F2,5B,73,54,59,A4,DB,71,79,78,61,E0,04,55,1E,63,3E,3F,EC,AB,46,32,D4,15,DA,5C,EA,24,E6,53,74,9C,27,DC,A4,03,FC,AA,01,8A,63,AC,F4,C7,26,EF,8D,9F,BA,AA,A2,F6,06,DF,1A,30,26,B0,88,80,FC,8E,47,05,6A,6C,5A,39,F5,62,5B,BB,73,4C,66,77,C6,AD,56,09,19,C1,F5,5B,AA,A5,3B,00,43,E7,25,AF,DF,89,B5,08,75,E7,65,8B,C7,65,0E,45,5B,F9,00,39,BE,C7,1F,77,FF,7D,3B,08,64,32,CF,C5,67,EF,8C,5D,F8,52,8C,03,21,8B,4A,25,CD,30,96,F1,E0,0D,8B,57,AF,A6,75,F9,A8,F5,F3,98,16,73,D9,05,07,5C,CE,3B,AE,8A,88,CA,2A,E7,A3,4C,14,B4,59,15,49,32,64,4A,4B,8F,F5,DB,D4,30,D5,94,FF,E3,9D,56,73,76,4E,F8,E3,8B,0C,57,3D,5C,03,4C,78,D4,61,C7,75,84,9A,9C,B2,8E,AB,96,E5,A7,2A,B6,FE,7A,9E,7D,94,FB,2C,CC,FB,4D,7B,7A,D9,37,1D,0B,81,8B,3B,A3,3F,48,AB,BB,2A,CC,21,46,D6,C5,1C,E9,45,2C,16,61,46,37,39,71,ED,94,F8,87,EE,81,67,21,19,DA,D4,8E,53,44,4E,9F,F8,56,E9,58,E2,38,63,1D,B8,35,CA,A3,1F,B4,06,2F,A2,C4,0D,12,84,6F,B1,3A,9B,4F,CA,A8,E3,B1,33,D0,47,82,A9,08,4D,FE,03,4D,65,5F,97,3A,98,84,A6,CA,E3,65,6F,9D,EB,E8,7B,15,49,FF,C4,43,54,3C,27,E0,85,A3,EB,71,4E,AC,7D,1C,48,71,FB,26,28,14,7D,EC,F0,8A,E4,39,78,A3,D0,25,4A,1E,05,07,A4,C6,0A,48,94,1D,AD,64,BC,2C,A5,EF,76,B4,B2,C5,C6,0D,FB,06,13,9F,D3,7A,7D,4A,42,5D,07,60,74,14,A3,18,93,38,66,C0,E1,3A,97,D1,7F,ED,A7,99,AD,DF,87,80,3C,13,FB,39,68,F9,94,10,2E,70,3F,9B,F7,4F,41,C1,F0,DE,A6,DE,62,1F,31,72,80,5C,6A,A2,AA,16,0B,41,53,A0,E3,05,E3,F7,53,1D,C5,64,A5,0F,E6,F7,70,63,C4,47,73,56,DC,AD,70,13,4A,9A,F8,22,FD,66,BF,FA,A5,DD,C7,D2,15,9D,A6,7B,CB,BE,9F,C8,F2,A7,AD,47,7B,85,EB,33,ED,AB,3D,8E,B1,1A,C2,9F,F5,21,43,EE,9B,99,D7,64,2E,8A,A8,F1,F0,DF,7C,F2,56,8A,A3,B3,18,EA,93,39,09,9D,7C,DF,E6,EB,6A,A3,A6,59,E1,84,45,B4,28,AB,C5,0B,F8,CD,1B,F0,07,54,6F,AE,58,58,4C,22,52,62,D1,9B,4B,E8,EB,5F,B8,49,6D,B9,E0,7F,DA,9B,33,D8,7B,43,96,42,7A,69,A5,DB,73,3F,83,AC,E6,9D,38,12,DC,EC,9C,DB,7F,B6,23,E8,AE,D4,99,C5,74,74,B4,1F,E6,29,BF,8B,9C,66,7B,4F,38,87,EF,A8,D8,CD,06,41,1B,79,35,46,3E,3B,1F,9C,24,E3,36,C4,93,29,8B,72,A5,7B,9E,11,D2,EF,5C,1C,8B,1F,70,3A,05,64,58,D3,AD,0D,47,BA,D0,04,75,EB,27,DD,C6,6A,DE,25,07,44,C1,6C,37,E0,81,E6,1F,B7,62,77,26,E0,E1,42,36,E7,B4,D2,57,DB,A7,D3,79,22,7C,93,06,09,52,74,35,04,CB,F2,FF,65,24,27,2A,D9,0E,28,2B,9F,66,65,45,4E,F3,96,B5,91,F2,24,69,EE,0A,99,2D,72,1C,B6,5D,02,61,6F,91,37,5A,8F,F0,24,9E,0B,B4,BB,07,37,A0,8C,FE,FC,5E,F6,AA,0A,AF,C9,3A,49,B7,87,79,49,69,C8,18,55,E3,A0,C6,70,78,55,83,19,5E,3E,7A,DB,4C,B4,C8,F6,3E,6E,4A,BE,11,DC,6D,7E,5F,61,22,A1,84,2A,2A,A5,93,B6,55,3D,22,40,DC,EA,4B,4E,7E,BA,C3,CF,8D,38,0E,41,86,C9,20,E8,4E,A2,44,EE,25,A3,01,87,59,58,35,E3,9D,7B,EE,5E,3C,EE,03,95,E8,B6,71,EE,A4,01,0D,B9,E7,28,21,E7,73,AE,96,63,82,00,6C,2E,A8,1E,92,C1,F7,64,6B,77,91,69,E5,C9,DB,83,94,05,DF,A3,64,D0,D1,6E,6C,2D,5B,0A,92,F5,BC,31,EE,5C,7D,02,A9,9A,9C,38,F8,03,1D,C2,EE,99,B2,5D,62,D9,87,AA,C0,E8,E3,93,44,1B,78,CB,C2,02,FB,2A,9D,F9,EE,D2,44,20,0C,72,9A,0A,79,6D,47,CD,D4,BF,EC,A7,6F,E1,03,41,E0,77,03,6E,8B,21,69,8B,EA,41,59,54,7E,29,BA,CA,6F,5F,C3,82,E2,78,28,62,35,04,0E,E2,84,CF,34,58,F2,2B,7A,5D,5C,32,43,01,12,39,5B,7E,6F,58,D1,6D,BA,A3,3B,C4,50,EC,44,EC,51,41,26,EE,FE,20,95,2F,31,E1,B2,F2,F6,4F,F7,EC,56,E8,6D,08,21,6D,05,4E,69,3E,5D,A8,58,6A,E4,00,C7,65,23,3F,FF,92,D9,F2,3A,92,A4,9F,9B,87,7D,09,9F,70,43,F3,58,E2,5E,00,80,33,C3,00,7C,FC,6C,96,A6,DD,27,80,5F,02,6C,56,67,1C,6D,7B,73,D8,98,D9,2A,5C,B3,15,1F,3B,43,B9,39,36,65,16,6D,96,8B,B1,06,1A,CA,03,0D,33,2B,95,06,71,61,B9,83,63,91,4C,6D,6F,C8,9C,F0,14,E9,5A,C3,E2,37,5E,22,FF,38,19,BB,CC,79,26,EA,28,9F,E9,61,DE,E3,05,04,29,A3,78,2C,03,1C,44,3A,5D,0A,06,9F,AE,51,27,A1,5E,58,B7,61,F8,34,19,FA,10,11,A1,9F,78,96,85,08,4F,7F,14,59,42,6C,33,8F,BE,44,F5,F9,B8,18,79,D5,C3,33,57,1E,79,88,B5,10,D4,E1,02,B6,04,95,A2,8D,16,51,59,98,DF,28,40,28,38,AA,76,9E,34,B2,AA,11,38,1F,03,70,48,13,1C,C3,B4,98,3D,DF,65,AC,12,92,56,BB,A0,11,8A,7E,8D,CD,14,F7,2A,5C,66,C8,1E,7B,07,FA,92,C8,F4,51,A9,2E,99,AE,B2,96,05,CA,8B,08,46,07,A4,28,C0,8C,E6,57,23,17,D2,BA,AA,CD,08,6A,72,D7,7C,B1,F8,1F,32,78,93,72,6B,12,3C,F0,9D,AD,B1,C0,7B,2B,29,56,B1,38,40,AA,4C,CD,7F,F4,85,82,90,1B,30,53,A3,56,EE,13,B5,C5,14,93,01,1F,FA,69,16,40,E2,0E,A1,8D,CF,02,A7,97,DC,31,D0,65,7D,E1,FA,D0,E9,BE,D3,DB,7A,E0,2A,99,40,C7,9F,FE,32,A6,AA,4C,6D,60,A9,FA,8D,B8,94,42,FD,E0,A1,D4,26,14,A5,5A,D2,A6,DD,23,62,C2,F6,DB,10,8E,A5,36,63,36,2B,42,FA,ED,50,17,6C,0E,C9,25,63,75,29,73,6B,1F,52,06,07,ED,73,86,0F,9D,E5,78,68,A8,1C,A4,5D,60,D9,AB,F1,42,DF,E0,1B,2E,10,45,97,58,C1,1A,E4,84,9D,61,9B,ED,E0,75,36,2F,B7,99,A3,51,BE,30,F8,19,F7,86,00,33,95,F8,C6,E5,D7,DF,AF,3A,88,0C,BD,E6,CD,DF,33,1C,6E,0F,7D,09,CE,CB,60,CB,45,6F,E7,7D,03,23,FF,E9,B0,5B,67,F4,EB,A5,5F,55,EA,11,E1,52,A7,87,0D,34,AB,AB,31,9A,83,08,92,29,FA,37,C8,57,3D,9B,A7,80,56,4F,E5,AF,59,AC,DC,0F,C5,74,E9,67,20,F8,08,E7,81,05,7F,FA,6F,1B,C7,44,7E,C7,B1,85,62,F1,D7,E6,24,AC,CF,BA,D6,EE,D5,D9,0F,24,7E,C1,A7,EF,7C,0D,70,4C,B6,D0,47,F2,36,71,5C,5D,BE,72,A5,AB,61,29,F7,9C,CC,FA,EE,4E,A6,97,5A,9E,AA,31,8E,2F,AE,51,33,06,CA,91,3B,B4,93,36,C2,FB,2C,6E,6D,ED,C3,00,83,E5,2C,00,A2,85,3C,66,4E,31,53,30,7E,89,9D,A0,3C,1B,8A,E4,5A,DB,10,66,93,82,8C,33,13,4F,67,11,32,F6,57,9F,8B,D1,92,D4,9A,9F,DE,7A,76,B2,7C,1C,F2,2E,7E,6C,05,5A,2C,F1,00,33,60,FC,E7,7A,60,F6,09,2B,09,BA,20,F4,CB,B5,8E,BB,A9,80,22,C3,E3,DC,47,99,39,97,B7,B7,1D,F1,07,A9,C2,93,7A,7B,E1,D0,30,47,BF,0B,83,76,A9,52,FA,46,AF,FF,0E,EB,60,01,70,35,5C,F9,03,CE,F8,90,85,B4,EF,71,1B,A3,6D,EA,06,30,28,5B,E1,60,54,45,20,53,D0,5D,3B,A2,0B,18,1F,47,C5,19,92,B6,1D,16,07,CC,D2,8D,5A,75,25,98,A0,D1,5B,F6,E2,2A,FB,56,03,16,D4,00,0F,C5,07,44,C5,47,31,D8,2D,85,59,21,96,16,FE,4B,F5,67,04,8E,7A,D0,4B,11,39,02,81,B5,39,21,D1,75,D5,19,CE,91,00,3E,60,37,83,F9,FF,D7,A0,AF,3F,A7,8E,00,76,9B,65,DA,DE,57,03,5F,42,91,32,AA,6D,8D,DD,8F,22,EE,CA,22,8A,3D,28,88,F8,50,F9,13,15,D8,3F,B7,62,B5,C6,31,49,15,18,15,33,3B,6B,34,1A,06,31,D5,3F,A1,19,66,F8,42,8E,3A,1B,85,B0,51,14,C7,DF,E4,C7,E6,BA,08,46,E6,7C,56,A8,3F,E9,43,C9,7A,7D,6D,09,22,03,81,23,01,B6,70,DD,86,A0,41,4B,E4,FA,2C,57,CD,2B,A8,85,89,E8,33,36,0E,2C,5C,62,7E,7C,E5,09,B9,62,78,2B,A7,C8,2F,DE,D0,E5,CE,A9,80,52,BA,63,AF,AC,3F,78,70,8F,27,8E,34,E2,A3,92,90,6C,51,FC,68,04,55,82,AC,32,AA,73,B5,60,7C,58,18,0B,EA,37,ED,2B,16,DE,F0,4C,74,9A,85,1E,D8,A7,94,D8,74,2E,DF,BE,B6,B7,5F,3B,C6,59,04,D5,4F,18,E8,46,C7,6D,32,CA,0C,3F,9A,42,61,F8,D8,34,F3,01,04,51,B4,D4,70,90,27,02,ED,FB,81,07,6A,6C,99,D8,7C,A1,45,D9,D4,3F,3F,99,E2,11,FF,4F,98,C5,A6,38,81,0D,95,FB,4D,3F,A7,9A,59,D2,4D,FE,82,8F,15,46,7F,CB,C4,40,DE,AB,63,8E,5C,50,4A,98,0C,F0,C7,A9,1D,7D,F6,51,31,01,68,4D,83,76,73,79,FE,AB,FF,65,1E,95,26,E8,DC,04,DA,8C,AD,A6,5B,CF,3D,97,28,2E,AF,19,22,8A,00,7F,D2,3A,41,62,84,6C,F3,4C,BF,67,7A,74,BF,12,88,CA,D6,7D,99,FD,B3,B9,84,A8,1F,B9,7B,A9,43,AF,45,A2,7E,52,FD,39,6A,2F,62,46,B3,66,2D,48,6E,D0,C5,DE,0B,8E,7A,71,16,4B,D2,36,D0,A6,63,85,95,CC,41,F9,99,67,B9,28,4F,EF,48,81,E6,5D,8A,86,58,C0,4C,DD,78,F1,29,B6,83,56,D4,F6,B2,63,5B,76,6D,BB,99,EF,5F,B7,24,BD,B8,0D,31,89,CE,77,9F,CF,3D,75,88,00,9C,48,AE,9C,7F,F8,C5,A5,5B,19,5E,EB,F5,1D,16,2D,5F,A6,82,E4,19,F3,F2,CD,4D,45,44,57,D1,77,80,7D,6E,AE,88,BA,6D,62,59,59,C5,D7,1E,24,B8,44,0A,26,00,3C,0A,C2,55,B3,C6,3D,F7,E7,B2,41,92,58,26,97,F3,F9,22,42,59,35,BD,7F,ED,74,7F,32,AA,4B,7A,DA,83,5D,9B,21,20,96,02,B9,B7,62,DA,A5,5D,BD,4F,21,52,08,6F,56,7A,F9,34,B2,13,39,84,EF,C1,37,3C,B7,9A,46,BF,F5,A9,53,E3,5A,DC,CA,46,16,0D,42,B1,7B,3C,2A,2B,9A,6D,E3,E6,AE,1E,46,9F,0D,7C,93,AF,CF,B8,E1,66,AA,1F,59,AE,E5,DA,BC,FD,5D,C9,C6,27,D4,2C,04,86,9E,D0,27,82,31,D9,A0,0A,BE,CC,ED,E1,76,14,36,89,3C,58,21,4E,FF,AD,6D,8B,6B,70,B1,73,83,5E,0E,53,69,25,E4,36,AE,A6,9F,A5,8F,C8,36,AE,A8,35,6A,4C,90,39,D8,88,3C,1C,72,06,ED,97,9B,2B,9A,5B,B7,D8,19,58,6F,03,8C,23,DD,9E,A7,4F,0B,06,CC,EA,2D,23,3A,53,48,F1,19,64,C8,3E,64,75,27,77,F4,39,08,90,A0,DA,E4,54,7E,E3,17,53,43,DA,46,46,6D,54,4A,22,BD,63,7E,3A,66,2D,EC,36,CB,65,3C,DA,3B,5E,EA,8D,DE,62,DB,71,9A,B4,B6,D8,A9,C2,9F,47,57,86,05,04,D8,56,DC,0D,2D,ED,FD,69,8D,D2,74,E9,BD,95,51,7E,59,26,10,52,CC,3D,F2,94,6B,9F,74,9F,AD,9D,A9,66,83,0E,C0,F2,D7,8E,4F,F9,9A,A1,17,16,BE,4C,5B,83,45,99,3F,3B,50,71,45,78,A1,E6,8B,44,DF,3A,F2,C1,91,46,69,8E,C7,FB,7F,6D,37,C0,B4,12,54,49,89,28,0D,D0,51,78,AA,6A,4D,89,23,59,B5,5E,F1,51,FD,83,1B,5E,F4,B2,10,1D,25,32,C0,DA,12,3B,43,1C,1F,EF,97,E2,3E,FE,BC,05,65,B8,A8,69,B3,7E,D9,73,F6,B7,87,71,7C,B0,B1,5B,0B,3D,27,9F,8D,00,0D,5C,CA,C3,10,06,FD,A7,08,61,74,52,8D,CE,56,99,60,45,3A,37,55,A1,EC,EF,29,4D,B6,E9,04,02,18,5E,AF,DA,BC,46,62,EC,67,E0,A4,17,D4,63,85,1A,3E,8B,E6,A4,96,33,5F,80,BD,8F,D6,2C,53,25,34,9E,35,8B,BE,92,A4,D4,BF,8A,5A,21,FA,63,B6,4F,3C,9B,66,25,66,49,27,1F,58,E6,D8,7C,FD,13,6D,FC,85,4A,35,89,5E,02,87,30,41,37,B4,67,B6,CE,5F,44,B6,39,16,38,60,66,97,06,40,8C,8C,BB,1D,51,7E,C9,20,FD,A0,E3,06,1F,6F,D9,18,CC,CA,75,D7,1F,CE,3B,4E,00,5C,E7,D0,C6,84,16,6C,89,DC,D1,85,72,40,AA,7E,10,22,F0,60,1E,A3,6F,39,47,92,C2,CE,F1,93,F9,2B,0C,59,64,E9,41,47,B4,1D,6E,A9,A5,69,2B,CD,2B,DA,6C,F1,EB,E8,61,77,63,65,C9,5B,6B,24,9C,0B,9C,8C,FB,BE,F3,37,09,FE,42,4A,C2,83,27,09,06,27,E3,E5,89,B0,DA,EE,16,95,FA,13,6C,68,A1,49,BA,7B,C7,E9,D9,40,70,2A,0A,91,35,04,E5,33,9B,EE,95,B4,F7,1D,6B,04,71,6A,27,21,F5,FE,F3,1F,56,8A,C1,F8,94,46,E5,A2,E2,D8,24,7C,85,45,38,45,76,F7,C8,28,77,42,E4,59,C1,FB,97,64,2F,E7,BE,C3,31,48,A6,3B,45,19,4B,71,9A,15,89,7C,13,D6,5D,B5,63,9C,B7,8E,F9,87,F6,4E,3E,01,4E,87,65,C3,C5,C7,46,48,90,FC,F7,1C,AC,55,87,ED,59,07,D4,86,DE,8F,F6,AF,62,6E,A1,2D,92,ED,E5,04,DF,1C,35,F5,04,67,49,97,3B,1E,2D,1B,4C,3F,4C,15,DE,E4,18,9A,A2,39,13,C0,B5,DE,3E,9D,80,6F,DB,A1,6A,63,71,92,10,70,F7,40,46,1C,FC,D6,E8,0B,16,3B,A1,FE,DB,A0,A4,57,C8,9F,D5,F5,E5,32,49,EC,CC,ED,34,38,DB,55,45,E0,89,DF,36,66,81,26,E6,8E,ED,99,AD,4B,34,7E,57,26,F4,B8,A1,B1,3E,D8,5B,4F,6F,17,F8,5C,72,86,28,D1,73,B8,A9,C4,5B,DE,5B,82,9C,29,BA,CB,5E,17,07,78,6B,37,2A,9E,26,15,E3,E1,98,DB,BB,08,FB,8E,04,99,AE,A9,12,6E,5F,4C,A1,80,3F,C4,D6,7F,FE,70,55,A6,92,FB,31,1C,0D,D1,96,37,47,5F,2F,84,8A,10,8A,62,6E,20,5E,95,3E,D0,FF,B4,5A,E8,E5,5E,A4,E2,D6,F0,80,07,D8,47,00,B4,2E,82,CE,80,0F,E1,B4,72,65,94,31,67,C3,6A,9F,53,DE,42,D5,9F,F5,EF,1B,D2,1D,E4,68,7C,AD,17,32,EB,6F,F6,E1,3E,42,0A,12,85,36,86,D2,29,2D,37,AE,45,C9,0E,5B,77,F4,DF,E4,A2,6B,8C,B7,28,C3,1A,3F,10,7D,2B,7B,E5,D4,6C,6B,ED,20,84,6C,A0,70,6D,DB,42,24,15,90,CC,C7,F8,1B,87,73,94,A6,0F,89,7D,7E,6F,A4,96,55,0F,AE,F2,51,6F,20,FE,69,17,D9,ED,A1,90,91,6B,29,FF,D5,AC,89,09,F4,B7,66,F3,83,B7,66,A2,20,6C,74,7B,C2,E3,6E,FD,96,3A,4E,6D,E8,93,6C,FA,08,11,64,02,86,46,22,07,F2,E0,E7,24,77,56,A0,53,9C,BC,CB,6A,7E,D4,D5,17,FB,5F,D9,EA,98,95,23,47,0D,32,DA,0A,53,CD,23,FF,49,99,8C,5D,8D,76,EB,00,0F,1A,11,B3,30,6C,0B,39,A0,FF,C6,74,B1,04,6D,A0,CC,58,82,12,02,5C,4C,77,7F,D2,25,3F,75,45,5C,E1,0F,EE,1E,F5,BD,9A,FA,7E,2D,1D,2A,82,65,86,3D,8A,87,C2,31,5C,92,ED,EC,F5,A9,9D,29,D7,8D,2A,39,A1,15,22,D5,4D,9A,D5,7B,F8,1A,43,96,A9,04,6D,5C,00,92,FD,29,EB,EC,A7,35,0E,D9,7B,B8,F8,72,03,C4,F6,7F,82,5A,20,38,29,B5,05,B9,C8,BE,48,F9,74,AA,79,CA,EB,A3,38,58,6C,09,C7,D1,A2,B6,6E,DD,49,F0,16,C7,0C,D7,93,3D,CA,BF,4D,8E,8F,53,70,3C,51,B5,34,AD,E5,56,63,46,42,D6,F1,31,85,1A,FA,AE,15,EF,39,3F,B5,4B,0A,D6,F3,E5,30,AA,8C,42,6F,11,86,3A,07,96,6D,E0,CD,58,68,57,19,0B,E5,A2,5F,E1,EC,82,D3,BB,1D,8E,FC,AB,99,F0,4B,60,5E,B6,0E,C0,E9,A1,B5,32,EE,BA,8C,C9,7B,97,EC,92,36,21,BF,E6,43,CD,75,C5,21,19,ED,60,EB,51,B0,D0,D2,86,B4,D0,AA,17,00,1D,E6,9C,A7,EF,9B,57,DD,47,CA,F3,DE,59,3A,C0,17,16,36,22,C6,F2,49,76,4B,A4,1F,AA,D0,01,2E,37,20,75,E7,45,16,86,B1,DE,89,E4,E8,EC,6C,1A,6F,7B,1F,5F,E1,C1,5F,E0,22,02,40,BD,14,3B,29,75,4A,46,23,BF,E6,7C,A2,13,3E,2B,D0,3A,7B,18,42,86,53,59,73,0A,73,88,4C,CC,A5,63,5C,05,3C,26,A8,CB,EB,E5,4E,F9,33,D8,7D,D3,13,02,D7,6D,2E,46,BF,DC,B7,FC,6F,1C,55,0F,27,E3,79,52,17,38,EA,98,5A,06,1D,E2,47,7B,18,06,DB,35,CF,B5,E2,5F,2D,1B,4F,60,1E,05,C9,54,38,4A,5F,B3,31,50,17,59,8D,FD,D8,3E,73,55,F8,83,51,15,44,D9,8D,7D,75,6D,69,2E,8E,83,86,E3,58,A3,63,12,59,D8,0A,BF,87,3A,E0,DA,C3,B6,0B,65,45,7C,4A,D6,D5,3B,E5,C2,06,0A,03,B7,8E,19,C5,1C,13,47,E5,0B,6C,E5,90,01,37,71,A7,61,5A,85,D3,B7,90,AB,2C,53,3C,B4,C1,7E,E7,72,3A,30,04,1F,72,80,57,D2,CD,04,60,EF,C0,52,73,46,46,D8,BE,B4,7D,B2,23,16,9A,B2,2A,80,DA,93,88,BC,5C,EC,1E,8F,00,AB,EF,B3,8E,8F,4E,80,0F,2E,1D,F3,6C,4E,1B,D6,39,96,46,15,CC,FC,33,1B,F3,CE,2C,62,8B,05,40,4B,F6,9F,B1,BA,3E,19,5D,55,6A,A9,E3,4E,C1,F7,AB,DF,75,47,BC,83,37,4D,AA,C5,00,A9,82,54,25,B1,FF,E4,E4,4A,44,E9,FB,D6,92,6B,8F,40,A0,FE,59,95,C7,08,3A,F8,69,45,E9,C4,62,16,C7,27,17,3B,08,06,14,1A,BD,39,E9,E0,B7,78,B5,1D,03,57,A1,E0,EC,FF,C4,64,8D,06,9D,3B,10,4C,37,99,D4,FD,C3,3C,A8,5C,88,06,F7,75,92,2E,B4,FE,58,FC,A0,03,3F,EB,DF,4E,32,E0,17,B4,30,54,AF,E5,FA,19,FD,2C,2A,F3,E1,37,E1,94,C3,8C,37,E9,81,29,67,73,7F,66,70,E8,8E,A2,76,CE,FF,EB,10,A9,6C,6E,D4,20,14,1B,81,F2,B0,E6,CE,FA,6A,06,C0,3C,5E,F7,33,08,09,1B,D5,1F,0A,38,10,06,01,72,3B,10,16,02,AA,96,A7,DB,54,EC,C2,6D,9A,73,C4,01,FB,BD,75,5D,48,0F,46,B3,F2,45,EC,7E,FC,55,05,2C,DC,B0,1F,BC,A6,6B,C0,D6,DF,85,A9,E2,CA,70,D1,01,2C,ED,C9,CB,1D,D2,49,5E,74,D8,0B,BB,B3,50,C3,35,72,F0,16,89,12,AE,67,93,3D,7B,30,A9,8E,BA,F2,7C,16,8B,47,F2,FC,69,C4,DA,2E,4D,34,FE,0F,8A,03,F9,82,D6,30,44,94,63,D7,E2,CE,7B,32,CF,9A,C8,6E,4D,AE,95,CF,C7,72,72,81,B5,67,EE,1C,4D,38,44,71,E6,85,37,B7,50,B7,2D,CA,7D,22,E7,27,5B,78,50,3B,3F,C1,36,F4,5D,C8,C4,58,E6,9B,A5,8D,81,C1,9D,1C,C5,36,96,82,59,D9,E4,D2,E2,EE,99,89,37,B8,D2,F4,5C,B1,4C,12,65,B2,5F,0A,06,27,44,7E,C6,A9,36,D5,BF,73,47,F3,29,84,77,D9,12,9A,24,24,59,6E,B7,16,B4,4E,B8,6E,12,BC,79,0B,F4,C4,96,0E,87,30,B7,98,57,37,B4,0E,49,5C,F6,9E,54,40,9D,2C,EA,15,3F,8D,6A,92,98,73,6E,A2,33,9B,13,A3,74,19,C7,C9,AB,76,07,51,EF,67,F7,3D,B6,AE,1A,A3,98,D6,E0,D6,FD,24,09,10,E4,F3,57,D9,2A,EB,4B,23,75,D5,E6,78,D6,82,66,29,96,2B,1C,2B,33,61,64,C6,95,A3,1F,02,20,23,4D,7A,2F,D4,BB,83,76,89,A1,C9,04,94,DB,39,9E,53,62,AE,3A,D1,3E,D5,FA,DA,9A,BE,84,7D,ED,42,8E,C2,63,4C,7D,60,8F,36,3E,3B,4B,ED,4A,E5,B5,12,65,0F,88,25,C3,80,06,A0,53,00,68,BD,27,39,E4,42,44,6D,E0,BC,B9,A2,C2,BC,3D,E8,66,F8,D5,F0,BC,1B,03,1B,D1,BF,D3,C7,29,77,9A,D6,09,8B,45,ED,C4,C3,41,DD,92,FC,74,EC,6E,76,63,77,52,B7,2A,40,04,27,07,30,9C,38,92,E2,5F,C2,B8,08,0D,50,0F,A6,19,40,08,2A,EF,36,3E,D0,AD,03,D7,65,1F,BC,2A,53,17,85,6B,33,F5,66,2A,55,E7,88,92,D1,B3,A6,88,08,0A,4E,A1,59,67,1C,39,A2,11,DA,0D,58,74,60,B6,B2,62,3A,85,6B,83,FA,AA,BF,2B,48,D6,0D,F8,75,BB,AC,4B,86,E3,59,0B,62,47,AE,EC,EA,08,85,6C,C7,A2,63,37,72,49,1D,51,48,37,76,38,68,11,85,60,CE,3E,9B,00,8B,1F,90,6A,92,EC,28,05,67,BC,70,7C,24,92,04,C3,14,4A,A2,F6,21,7B,F8,46,A9,45,26,8A,67,BF,58,73,F1,C8,2F,35,EB,E2,8A,3E,35,0D,27,BA,60,F9,D4,2C,76,C4,BB,9A,10,CB,6C,0A,89,52,6F,EA,23,5F,4B,BF,64,B2,F5,FE,AA,4F,3C,4B,03,E9,DB,7B,E5,B2,13,04,68,80,50,AE,6C,C4,53,4C,D6,C5,39,04,2B,5B,95,96,13,C8,D9,80,F7,DD,60,8B,06,DF,43,3D,AB,58,8E,8B,90,A8,B8,7B,BA,14,B3,94,7F,97,9F,98,21,6F,15,51,AF,D3,83,DF,B7,86,46,FE,7A,07,D2,FE,CF,C6,90,26,12,5A,66,60,28,7C,33,2A,ED,49,5A,DF,2C,0E,0C,62,BC,40,93,49,F9,23,27,31,16,C6,CE,85,35,23,82,44,DF,65,E6,B7,87,51,57,6F,9E,1B,FD,41,9F,76,EA,66,CB,62,E2,CB,4C,07,22,84,74,DE,30,58,18,B5,62,9A,BC,E0,F5,4A,16,4A,BD,51,FE,BE,3E,A6,59,91,85,60,6B,EB,F0,8E,8A,EC,3F,52,6A,19,84,7D,BF,74,EF,7D,96,9C,AD,B7,DA,06,8B,C5,3E,78,1B,FA,A2,8A,37,83,34,E7,53,BC,64,67,11,49,BE,5E,B1,55,8F,10,9F,B5,02,27,17,F6,95,31,4A,33,12,B3,F2,EE,5A,48,52,90,D3,CA,2D,B0,F6,8C,BD,0C,75,47,C6,71,08,32,37,6F,3D,08,BF,3B,DC,48,02,C5,66,1B,A8,F6,66,DA,69,46,40,00,5A,A7,D6,4C,5A,F6,0C,71,67,5D,FD,18,4D,6A,23,F5,74,0A,A8,02,B7,69,29,D4,A2,45,56,39,A6,DF,53,6A,B6,D3,AD,FD,AA,8F,13,1D,4A,B0,B5,2F,9A,25,7D,75,93,9E,99,2D,C9,9F,AE,FE,04,C2,C5,D4,87,A8,70,5A,A9,A7,D7,5C,DD,BC,A5,86,72,10,3C,CC,AA,3B,E5,F6,39,57,EA,17,63,4E,1B,E3,19,B4,C3,9A,28,9D,27,6A,26,C4,DD,55,C0,17,03,91,54,70,B1,0A,A9,75,B5,CE,35,E2,B7,DA,8F,D8,5F,31,29,05,DE,E9,47,32,5F,43,79,59,D5,4C,B0,11,A4,67,77,0C,5C,BA,0F,B8,DA,AA,B3,8C,56,A0,7A,91,83,74,43,3F,9F,43,D7,A5,21,62,1E,76,24,37,4F,86,B2,3C,43,2A,AF,8E,40,92,09,A3,48,B3,93,C0,D5,C7,7C,FC,55,B8,EF,E9,D0,7A,9C,88,B9,1D,38,B7,A6,BF,71,9E,78,0D,C0,9C,2C,3E,85,BB,57,EB,4A,EB,63,38,C8,3C,EF,DF,33,FC,AD,15,92,B7,69,C9,F7,C0,A8,77,3C,66,03,C7,5E,C5,8C,A5,B7,CA,EB,17,66,93,AF,AF,98,36,34,AA,76,6F,FA,40,42,58,33,47,1C,F4,A5,49,8B,99,B2,E7,AA,25,AA,F5,99,F4,C7,BC,68,96,12,FE,7B,14,8E,F9,D8,C4,E4,5B,9C,D2,B2,3A,34,8B,EF,92,08,24,F7,02,F7,F1,4E,F3,D2,CD,EA,F2,6B,CA,A5,A0,BE,57,4A,45,DB,54,9F,DA,5E,57,6F,21,70,83,F7,49,C9,86,49,2B,72,BF,E7,B2,CE,60,8A,74,8B,5D,65,19,82,8F,6A,1B,B3,07,61,A1,1C,36,10,17,25,45,BA,E7,D1,41,2D,91,C0,77,8C,57,19,C7,FB,DF,71,04,C1,8E,09,3C,22,B7,68,7D,73,15,AB,F6,28,69,06,0B,AA,82,F0,69,8F,50,9B,F4,9E,D0,7B,66,F8,8F,CE,81,33,F6,B8,DB,AF,72,29,39,A6,24,48,63,87,EA,C7,ED,FF,10,11,E2,5B,08,2B,19,FB,08,3C,57,F1,24,B7,8C,9D,E7,73,DE,24,26,15,63,7C,21,86,13,5C,7E,11,9A,DD,00,50,52,56,5C,1A,B4,D2,21,82,83,2C,91,56,56,F2,16,F4,7E,01,65,EB,3C,6F,FE,74,73,3B,EF,BF,12,18,E0,77,96,44,8F,40,8F,6C,17,57,AB,9E,E5,8C,0C,20,39,98,AB,03,2B,D2,C5,AE,B0,3F,52,7B,83,EB,AC,0F,1C,0A,F7,EB,10,B1,5E,61,74,87,FC,9B,B3,D9,A1,B8,35,EB,5C,E1,53,0B,D4,B9,15,F7,2D,9F,2D,49,C8,4C,E3,2C,A3,16,70,EB,CE,74,81,D1,19,27,3A,4A,B4,7E,6F,23,DD,1B,94,42,05,4A,25,D4,84,00,81,9C,15,13,A5,BD,28,2E,A3,D6,8F,B8,52,FA,83,4D,EA,48,41,42,B9,6D,26,87,8A,5C,B2,DC,A2,DA,78,73,4B,70,68,08,6C,7D,94,FB,85,D9,BE,42,7C,E4,D1,7D,E8,70,C4,DA,60,CC,C2,47,00,62,69,4F,87,CF,A2,B8,78,8C,4B,3D,66,BD,E6,24,9C,2B,82,92,21,63,B2,6C,53,BE,3F,EF,69,2F,BF,00,92,51,54,10,1D,11,53,19,9D,A2,78,DE,3F,49,BE,0D,33,AC,CB,E4,E2,B5,3D,E0,68,F9,1E,89,37,6B,6A,F2,65,28,CC,79,A6,DF,09,90,B3,B3,7D,A9,1C,61,18,6B,F9,02,D8,E9,80,E9,72,AD,FB,C3,6C,52,24,C2,7D,38,83,14,D7,4A,B8,5F,C9,CF,00,68,8E,67,C9,4F,E1,94,C5,3F,83,AB,54,01,27,73,F5,CB,14,53,4D,EC,D2,F9,64,02,64,88,A6,DD,EC,A2,F3,12,F7,9E,3C,C5,AB,73,23,34,A9,1D,13,C1,11,14,56,FB,E8,BD,C6,01,EB,60,CF,39,E6,A9,23,6A,1F,F5,A5,44,15,CA,89,58,11,A3,8E,D2,9F,0C,50,3E,DC,86,06,09,EA,82,65,6E,38,F9,0C,5C,18,9B,40,61,E6,19,FF,69,86,E1,75,C4,3F,C7,95,2D,0B,6F,12,34,39,40,46,6E,4C,7E,65,31,B0,31,84,51,37,0B,ED,80,AC,F1,1F,F9,63,BD,7E,90,CE,AA,16,A4,80,73,8C,D5,80,18,A4,84,05,98,54,F1,4A,9E,BE,73,3B,BD,65,CF,A7,39,17,2C,B3,9B,DD,FD,D2,CE,4E,E1,45,90,25,33,3D,94,63,06,85,60,A6,CA,AF,48,60,93,AD,1F,83,DE,AE,FC,A2,B3,67,7B,B5,FD,FD,61,AC,93,94,93,BB,2F,05,2A,23,38,07,70,DF,0F,CC,69,BE,66,F8,DA,6D,DD,1C,65,83,65,97,A8,88,4D,FF,BF,AD,A2,8C,F0,69,2E,21,BD,17,BD,21,DA,73,25,BA,E0,BA,E7,1D,10,CB,ED,EA,C9,87,7A,28,83,47,BA,3A,5A,4E,BB,D7,F8,C1,94,F1,FE,7A,F0,99,37,11,4E,79,44,D9,A6,F2,68,B4,6F,CB,24,C9,EF,2D,9C,23,E4,F2,C1,B4,C9,4E,71,BF,C0,E5,AB,A3,FA,E2,70,51,67,0F,A0,50,DB,2D,59,24,5C,BF,57,39,83,1A,C9,BA,44,83,8F,EB,92,C6,09,63,21,48,C1,66,F1,EC,0B,6C,1C,1C,C5,97,E1,F7,3A,95,90,B2,F3,4C,2C,6B,9A,B1,CB,17,B5,76,FA,DD,41,B8,CD,22,5F,AB,7B,59,3B,BD,BD,63,60,06,B2,7C,AF,BC,CD,9B,C9,A2,5E,4A,19,48,1F,BD,82,82,4F,B4,2A,AB,D7,A5,77,9F,82,C6,93,6E,D3,5A,77,3B,AE,8D,72,D2,09,F8,3A,EF,59,81,CF,BD,C6,5A,5F,DE,EE,97,0E,58,12,3E,43,FA,86,77,BA,4B,F4,48,E7,C3,57,35,74,60,5C,1E,5E,4E,EF,35,7A,6C,71,EF,AF,7E,DC,4B,26,95,56,6A,36,15,72,FA,D2,3F,5E,B2,62,6C,F1,F1,79,24,0D,5D,0C,A5,4A,A6,96,61,C5,A9,3A,8C,4C,DD,0A,81,D4,D0,82,97,E8,AE,D5,C5,27,88,3C,3C,D8,12,9E,77,2D,4F,D8,A4,00,43,E4,72,81,12,F5,33,0E,18,13,4F,AC,9F,93,D6,BB,A7,E8,FA,24,6F,CA,4F,DA,AA,EC,D1,8D,9E,B1,BC,38,F1,A4,99,C5,D0,36,D9,D6,C0,C8,44,91,96,1A,1B,9E,F8,1E,25,43,3C,18,EC,4D,9F,A5,E0,5D,72,5E,87,BF,9A,AF,81,8B,8E,72,7A,4C,99,1E,EB,41,1D,48,B2,D8,08,56,A1,EF,14,22,80,8E,4B,6E,90,5F,E1,B1,A7,59,7B,4F,0E,87,0B,C7,AA,3D,04,F4,6D,E1,A9,05,D0,5D,67,2F,D4,EC,D3,65,AE,3B,CE,8F,9E,3D,75,4F,CB,D4,DE,69,11,10,0F,26,4B,E5,22,C7,CE,EE,19,43,B3,6F,1C,AE,A2,41,CC,36,A6,6E,4D,DD,19,CD,78,A3,56,81,CF,BD,C2,90,DE,10,C7,68,AA,44,AE,46,BB,ED,6C,3E,6E,69,50,9A,6A,29,02,DC,4E,77,31,E9,0E,1E,5A,27,01,80,69,80,04,C8,4F,87,47,7A,61,D8,26,54,6D,4A,A9,40,F6,E9,13,00,3F,EF,40,5D,CA,AA,70,43,B1,AF,29,EB,25,B8,8E,B9,7B,4E,42,41,8F,75,14,BC,98,3E,36,FE,6C,02,55,C4,E8,2A,CF,F8,39,62,11,00,88,B1,6D,0F,40,1D,F0,F6,D0,99,13,8F,4C,DB,4E,8C,FA,CC,E1,80,F8,F9,50,78,04,C0,36,A0,FD,52,F8,FF,C8,62,24,29,7D,27,37,F9,5F,8D,6E,A2,F6,DD,28,C5,BA,6C,E4,E9,9A,89,42,FF,CC,20,F8,6F,17,5E,C7,70,06,47,A1,F7,9D,97,AA,31,0B,A6,72,35,55,ED,71,0F,A3,28,41,02,DE,6D,88,E4,43,B0,E8,78,D0,03,56,88,26,4A,BD,A2,EB,73,28,E0,92,14,D6,FA,D7,CD,60,03,C0,6D,F8,05,1B,50,E9,B9,02,BA,9D,F4,78,28,B1,32,2B,31,4C,36,56,7B,9F,03,63,9F,7B,66,06,5B,AC,8B,13,F5,4F,C2,54,D0,99,D7,10,86,94,7C,50,E5,05,60,AD,B4,54,FA,2E,8E,12,9F,EA,D2,8C,64,81,91,DC,D3,30,66,D1,0A,EA,F3,A6,F2,EF,16,DC,A0,E0,3C,74,CB,2F,B1,55,EC,EA,5F,EB,D6,A0,5A,02,23,A1,5D,88,62,4B,D3,7C,83,BD,6D,D5,70,75,7D,0D,D6,39,0F,1C,15,72,4A,02,C0,4B,10,B6,AC,2E,03,06,1A,49,D0,58,D8,AD,98,BE,B6,05,61,40,07,CA,A6,B5,49,B1,0A,C9,59,48,0B,3B,E6,A7,23,0D,37,4E,80,F7,AC,66,92,E7,7D,86,56,88,32,40,A8,16,18,EE,BB,52,94,FB,06,7A,62,79,DF,04,26,DC,DB,B5,60,49,58,D4,00,F5,B5,E6,6C,70,E7,91,94,2D,60,40,9F,F9,B9,4F,F8,B8,CA,72,FF,12,7C,DE,4D,2D,E7,95,1F,78,FC,E2,9C,66,45,24,D9,6B,7D,12,65,7A,B5,21,72,EC,5A,44,0C,CB,C2,09,2A,95,74,30,CD,CD,46,16,71,00,C7,02,FF,88,76,E0,BC,97,96,7A,22,DF,8D,C9,7A,25,3A,61,54,CF,9F,CF,38,16,FF,1A,76,59,05,B7,A0,19,4F,84,DB,C8,09,E6,D9,EE,BB,AC,F3,D9,49,84,C3,9D,2F,7C,21,66,F5,F7,97,BA,63,05,1C,34,54,AA,AF,67,D7,CB,30,F3,7C,83,7C,35,4C,61,F4,73,7A,9C,98,3E,52,70,9A,EC,EE,2A,65,E6,2A,0F,16,AF,BF,AF,E1,CA,6A,A3,53,AE,9A,8F,91,96,94,C0,00,A0,7A,5B,03,AA,89,35,BC,ED,64,5B,FF,1A,F3,E5,1F,B3,92,2B,00,19,17,16,26,3B,79,0A,41,28,B4,46,17,29,9F,6D,6F,06,25,B1,98,92,DC,AA,B1,54,06,05,B3,9A,91,98,73,68,B4,71,15,C7,FF,63,70,07,F1,19,40,C3,5B,41,E5,86,11,D9,47,66,D6,99,30,2A,96,08,83,A4,0C,ED,1B,DF,8C,7E,E2,F4,A0,09,66,07,17,29,FB,2F,FA,98,70,D4,EF,74,89,37,18,A8,46,30,BA,BB,F9,99,E7,09,52,C7,50,78,32,46,8A,85,08,8F,A2,90,EA,CE,43,CF,8D,01,6D,A8,78,C1,54,42,9E,3A,06,A3,3E,36,D2,E0,B6,E1,71,9B,D0,8B,D1,70,45,A3,63,E0,71,B5,4F,D8,13,B1,61,D8,36,47,89,DA,97,EF,A7,8F,F4,B3,43,9C,54,03,F8,3D,C4,EB,DC,CE,21,27,F5,B8,79,EC,F7,2E,83,54,41,AE,15,E1,14,23,7B,B9,99,FA,EA,60,C6,59,0F,C3,25,31,2B,43,E2,E6,94,A2,BF,B1,9F,97,93,BB,21,D7,E1,C8,F7,A3,26,CF,F3,8B,9D,26,60,B0,24,60,02,1C,5C,86,B2,2F,B6,A6,AA,F2,92,8F,D5,BD,CA,C4,2A,63,BE,78,65,56,91,F0,F6,E9,6B,53,22,9D,C2,F1,BF,CA,69,A8,AC,4E,C7,29,B0,D4,D5,52,33,5B,FE,A4,F1,BC,0B,13,CB,F4,8A,76,5B,21,88,15,80,37,0E,BF,6E,EB,E0,72,22,70,D6,BD,47,EA,55,8F,1F,F0,BD,DE,7B,5F,6C,FA,37,7E,1D,16,44,2F,6F,BA,A3,BB,39,CF,CD,F3,21,7F,CF,E6,73,BC,BC,24,D2,38,D0,60,4A,4C,B1,6F,FB,2F,0D,58,0A,04,3B,47,ED,F4,64,39,BE,91,F4,BF,DA,FB,50,CF,82,95,F4,59,D1,22,68,F9,49,54,07,AC,ED,76,D9,D4,1B,65,C5,F0,33,17,8C,E7,95,18,B4,FF,ED,C2,5C,4B,F3,29,0C,BC,A2,89,A1,5F,45,B0,4D,B6,83,A4,DA,C7,DF,CD,E6,80,5A,5D,05,41,22,E8,B2,CC,10,13,5A,BD,92,3D,C6,48,78,76,CF,17,95,8B,09,C4,E8,25,31,BF,63,EF,B6,E9,EB,40,1C,1E,3D,D6,54,D2,07,B7,BC,45,CE,AA,F5,6B,F1,51,B9,E8,18,7D,43,D1,B9,52,DB,9E,4E,9B,C6,26,DF,67,E5,61,F6,F5,BD,3F,52,5D,37,83,E1,67,89,24,85,22,70,BE,B8,A0,CF,9D,2A,14,16,70,E8,68,2F,73,20,57,47,07,A3,E7,66,BE,87,23,43,78,35,FE,44,61,33,4F,06,00,11,E6,5A,6B,2D,DF,56,6F,C3,CA,4E,4C,70,6B,90,40,4E,11,B9,A0,AE,AF,E5,EE,21,9E,DD,A3,47,EC,85,99,C2,17,25,AD,5E,8B,D5,9B,F6,69,E6,85,BF,ED,B1,2F,BD,62,82,D8,5A,04,6E,C9,B1,9C,A6,39,B9,4E,E7,E3,E7,CD,00,15,AC,EB,63,10,05,62,F4,44,AF,D9,BA,AE,1F,18,F2,0C,59,DC,E9,98,80,F5,C7,BB,55,9C,C5,F6,2E,96,34,39,9B,C2,BF,77,27,68,99,35,A6,1A,57,FA,7E,AA,1F,8F,DD,B1,74,B9,6F,2A,DF,46,4A,34,89,F9,72,8F,0D,CA,F9,78,9C,C8,44,92,CC,F6,B9,0E,51,A0,2F,1E,86,4A,AB,6E,0E,42,37,1A,43,B8,88,7C,47,44,15,9A,F0,82,50,8E,56,59,0E,9A,AE,7A,71,E2,C9,FB,B7,3F,51,FB,65,C8,B5,71,BF,32,8B,2C,9A,67,6C,BA,3A,EA,40,37,92,B4,39,4A,AA,06,6D,52,21,C4,A5,06,BE,0F,B4,60,5B,22,61,D9,1A,3F,5E,EB,5B,44,F2,2B,88,DB,77,4B,EE,FE,FE,4D,63,9E,77,A8,AD,62,B7,07,61,A5,97,00,69,FE,1B,A1,A8,87,DF,5F,8D,80,D8,D5,67,9D,28,4E,FC,4A,0B,A3,C8,04,BA,CA,DA,AF,C5,3A,96,67,10,16,A5,EA,D2,80,81,97,E9,20,B5,0C,F1,ED,1C,FF,75,51,FC,AD,EE,5F,CB,90,25,70,3C,EE,96,BF,14,2B,2C,52,01,D2,44,29,80,ED,57,19,72,D1,42,F2,0E,0D,3C,EF,B8,7A,A7,92,3F,92,FB,61,07,78,23,D4,A7,3F,BF,16,EA,30,DA,5C,D3,10,4B,4D,1F,5E,A1,FC,B6,E4,7D,E0,48,AD,15,63,60,5F,89,FA,AE,CA,DB,E6,B4,18,63,A3,E9,75,A4,E7,3D,10,0A,28,3D,4D,2A,E3,77,6D,3C,36,22,C3,87,E5,2B,1A,93,31,93,61,CD,98,3A,EE,BE,E0,2A,4F,79,C1,7F,E6,81,19,7F,B0,34,99,8D,E6,33,B4,04,F9,D2,B4,41,01,CF,80,99,BA,76,E5,55,F8,67,5A,F9,40,76,2B,5E,5C,A0,21,B7,C2,CA,EC,2C,43,25,93,3F,E1,FE,B7,66,CC,E5,02,2F,40,B2,57,C5,7A,D7,86,45,52,E9,75,5F,00,3E,DD,36,8F,B2,CD,DC,09,27,7D,91,20,F9,46,E5,45,08,B3,44,C1,BD,B9,D5,EC,AC,DB,89,64,C4,42,E6,82,0F,54,5D,2D,0C,F8,F0,B9,CD,FC,23,12,91,3D,70,D5,86,FB,7B,15,13,4C,20,CA,F7,B5,42,2A,20,32,D3,B7,B6,7D,1C,11,DC,15,56,29,D3,A8,D6,6D,A2,46,02,11,04,FE,3B,97,FF,66,CF,68,EE,4C,85,C8,BD,61,78,32,0E,9E,67,00,43,68,B8,DA,68,C1,EB,91,72,62,AD,33,57,0E,20,60,F5,23,D3,26,67,94,A6,D1,60,48,87,C7,A9,68,DB,BB,20,47,77,64,8F,F9,77,D1,C9,EE,60,F2,95,5D,D5,B1,06,39,4D,F3,40,52,A0,E6,F6,12,F9,36,F1,F1,30,14,49,08,04,8C,B5,54,DA,AD,CC,51,27,2A,1F,F8,FE,44,70,81,7F,96,20,46,01,BB,EA,F3,21,54,C0,5F,84,F8,82,57,24,B4,D8,BF,F9,B8,76,BB,CA,78,94,7D,E9,EC,2F,FF,1F,67,1A,42,27,1B,32,29,85,0A,AD,16,36,4A,6F,C6,02,03,88,94,86,0D,A5,55,60,9F,F0,E4,F6,05,72,A6,43,A8,68,6D,AB,54,26,2F,EE,25,0D,DD,67,41,57,51,08,F5,6D,39,4B,D5,96,96,E8,84,2D,15,B2,1D,21,2A,BE,8B,1F,B1,3B,38,24,14,E1,B5,22,7E,E7,BA,0A,72,3E,62,7F,B4,12,42,78,8F,17,C7,64,AA,FC,8E,94,79,CC,E3,29,49,D9,A7,84,D3,C9,BF,D7,13,B8,7B,1A,B2,72,B6,EE,C9,D6,F2,79,85,E2,7F,08,D9,7A,C5,C4,32,16,6F,C1,7D,D9,2F,22,99,60,EF,DF,DE,09,0A,4B,93,74,80,B3,4B,CA,43,1F,68,FB,3D,6A,9F,15,31,B3,9F,EB,E1,1D,36,E4,C1,68,AD,C4,56,D2,83,BC,DD,D8,7E,5B,25,F6,E7,06,79,5E,BF,94,D9,CF,7A,1F,2D,1B,51,3E,55,90,90,67,B6,E6,B0,E4,3C,8C,2B,A2,57,5C,6F,B9,37,50,07,B7,C5,C4,8E,AF,5E,89,36,B7,49,10,0E,E8,EF,5C,95,D9,0F,3F,48,1F,E8,80,68,EA,26,E9,7E,0D,38,4F,82,09,61,97,12,5A,55,E7,38,8B,0B,21,C1,CF,A4,E8,81,BE,60,71,13,84,C4,1A,96,FE,84,A0,3F,0A,29,77,9F,6C,E6,26,61,78,EA,8D,3C,C7,94,28,BC,9A,FE,5A,35,AB,1A,13,53,D3,E7,91,6F,52,25,07,5D,E2,BF,97,C7,C9,EA,FF,A4,63,00,42,85,38,13,EF,FB,4F,62,66,D9,D1,6D,8F,0C,87,EF,8E,8B,A9,11,40,3F,38,9C,EC,18,06,6A,6E,44,51,F9,7C,53,6E,8E,C3,9C,A6,90,CD,73,F5,E0,3C,9B,58,60,45,40,FE,9B,EB,52,91,AD,E2,CC,F6,95,84,52,90,06,9F,25,DD,31,B8,B2,69,57,83,98,C0,40,8C,F7,AF,F2,0D,0A,03,7E,DC,BF,66,4B,D1,7E,AB,D2,41,95,7F,04,89,61,7D,98,69,43,EA,28,53,B7,BD,72,B4,25,92,0F,52,AC,04,48,28,45,E4,8D,69,C3,C5,69,88,AE,D3,07,05,72,BB,94,53,5F,30,36,C5,A4,85,AF,C5,05,30,1A,00,22,8F,FA,B7,F3,91,6C,5E,ED,9A,34,03,80,66,16,A7,C5,0F,72,3B,05,87,E3,66,83,3F,C6,2F,F6,E5,A3,C0,0B,EC,BB,1A,F7,FB,4D,A4,FC,91,CF,EA,2C,67,FE,4A,E9,E8,A0,4F,0D,33,2C,0D,08,07,F1,08,54,53,CB,F2,75,90,C8,4B,0A,C6,2D,82,79,83,5A,2C,CD,48,77,A9,8E,24,8F,37,28,D6,2F,42,16,7A,96,A6,B2,55,85,DE,36,15,DC,FB,F0,E1,72,9A,44,40,44,BF,42,93,91,07,F9,15,E0,65,BB,82,56,74,D8,7A,5D,D3,87,22,82,00,A1,CA,9C,25,2E,A7,44,7E,32,B2,55,7D,D3,15,88,36,1A,CA,C3,69,1D,E4,E6,78,BF,9C,62,5A,2F,4F,CA,84,C8,6A,2E,2A,AA,09,3E,8A,71,32,9C,FF,78,A5,C9,73,A4,2A,7A,DE,84,D9,A5,07,C4,72,9D,BC,62,D6,21,09,43,95,55,D6,6C,AB,FF,DA,6C,5A,DE,AC,8F,33,91,8A,2E,7B,D9,1E,BB,BE,3A,19,18,E7,E5,A9,0C,34,BB,26,CB,FA,58,32,00,9E,48,E6,D2,96,CA,CE,D7,6A,7C,E1,0B,2D,16,2E,AD,D5,40,27,52,94,A1,E5,B5,8E,27,B0,0D,D9,57,2B,48,2C,9E,96,14,F7,D7,FA,6A,3B,43,25,26,1B,A0,BB,3B,54,DD,51,E7,3D,57,52,E4,C4,22,40,20,5E,4B,F1,CE,E1,9B,3B,04,C2,C6,94,46,54,51,D9,FC,74,C4,5F,76,14,CA,56,0F,0C,B8,6E,EF,E7,14,B7,A5,7A,BB,3B,F1,6A,EB,70,E8,7A,C4,32,53,23,FD,B5,B4,D6,30,EB,F2,A2,57,A9,71,39,E1,87,B4,60,E7,08,BF,47,6F,72,24,5A,37,22,A2,23,33,80,FE,E1,E0,11,7D,56,68,73,E8,DE,3A,46,03,2F,5A,84,C5,98,8C,5E,D8,20,7B,20,31,60,B9,F5,FB,01,A0,E5,9E,16,F1,1F,15,6A,0C,06,1C,1D,55,02,A3,61,4D,04,07,DF,14,0A,F5,5D,BB,A4,56,B1,86,C4,0B,8C,CF,4B,90,C2,AD,03,95,4A,14,1B,B6,7E,B2,5E,E3,E5,01,9A,12,98,AB,AC,7A,4F,52,42,D8,AE,B8,C1,48,6A,BF,ED,F4,98,7E,A0,FF,60,62,C0,26,B8,15,B0,CA,3F,5F,85,EA,6E,86,D0,E3,AA,5F,95,71,0B,4C,9A,05,DC,AF,E1,04,64,33,E2,36,5A,7B,13,2B,9E,A3,01,06,40,DA,D6,06,5C,A4,BD,FD,76,50,68,E2,E7,50,AF,BC,92,2F,75,B9,8D,F1,6A,51,AA,B8,69,FD,AD,2F,57,2A,06,AE,90,B6,E7,85,E6,7C,E2,89,9B,C5,D1,1C,B9,54,F5,2E,C1,FC,46,1C,EF,87,79,45,E5,82,33,BD,78,F1,8B,DC,20,E5,7F,4C,2F,8B,7D,F8,4F,37,C3,06,CD,59,51,2F,DF,AC,B1,AB,B0,1A,92,16,54,4C,8E,97,36,AF,B1,45,67,16,C7,6B,6A,D2,E5,93,20,C1,B0,99,37,26,40,A6,DD,57,8D,98,E4,CA,4A,F8,3E,BC,75,BD,EA,6F,FD,BD,F9,A8,86,DB,86,1E,69,76,AD,A7,AE,D1,D4,94,12,5E,26,28,40,7C,25,54,D6,F9,63,84,7F,C9,4F,E3,37,CF,E9,FD,7D,9A,47,65,C2,C2,F4,F4,44,66,F4,29,75,E4,87,64,6E,03,72,74,98,42,E9,10,C2,4D,64,A1,58,ED,10,D2,B3,83,AE,4D,DE,99,89,BF,1E,90,EC,9B,03,DA,F3,40,04,DD,42,52,C8,1B,0D,A2,E1,6A,1D,09,F8,CE,C6,29,8E,3D,86,E4,BD,5E,5F,CD,6C,9E,D2,0C,44,81,EA,4C,BA,A3,F9,88,FA,96,BD,32,CA,F8,C5,85,03,4C,42,20,B6,C1,7B,CA,6A,6D,39,EA,F7,3F,9C,7A,9D,96,FD,86,7C,E5,C1,34,7C,B1,20,20,5C,12,35,25,CE,05,97,51,6E,F9,B0,39,13,33,E1,E6,BF,62,85,E7,C1,59,09,81,53,43,8C,A6,35,E4,95,3F,9E,C7,A2,0B,07,A5,3C,E8,0E,21,BA,61,DE,47,8A,87,F6,CC,88,8B,14,05,0F,16,C2,72,36,13,71,FA,81,3E,48,41,B7,95,9A,32,06,7E,F2,F8,AC,1E,69,BD,97,EF,E8,B8,69,97,36,EE,F5,F3,A7,75,26,73,3C,38,C2,46,BC,47,43,D7,A7,55,BB,A0,25,4D,09,46,E2,AC,D3,E9,52,DE,58,C1,69,D6,B5,3C,4B,12,D3,76,E5,4F,BB,20,6A,FD,D4,B3,F7,FC,61,6B,BC,02,42,FA,52,BA,D3,32,90,4C,57,D7,22,C0,24,03,91,6F,A4,55,21,54,7E,6E,CF,54,CF,9B,DB,7A,06,76,EB,D9,61,EA,85,D8,F6,2B,53,2A,4B,43,DF,FA,DC,3A,A0,F4,41,6B,CD,EE,09,B3,BA,7D,19,CC,65,78,51,F2,65,30,46,82,2B,55,0D,C4,6F,50,9A,59,53,5F,4F,69,C3,57,00,AD,F9,C3,04,58,63,1D,81,DD,DA,10,22,F8,F2,1D,C2,C2,69,E1,66,06,C0,7E,C8,1D,B7,46,F1,9B,56,84,05,B4,19,8D,0E,92,8F,C8,4A,AB,77,97,5A,4E,62,AE,05,74,67,D4,99,F2,4C,9A,2E,BC,BB,40,13,1E,F9,B8,1E,6A,3D,D3,0B,24,65,02,D8,06,27,1B,32,8D,AE,2F,54,F9,5B,91,77,87,10,E4,23,4C,DD,48,07,9D,75,8A,B1,66,B8,12,44,26,85,42,0D,8A,67,07,1C,7A,20,99,02,78,21,07,65,DE,EF,66,3A,BB,38,FD,F4,34,B0,97,71,F6,FD,32,D9,90,AF,13,BA,DA,54,70,3A,B3,A3,D2,14,F9,B7,73,4E,75,3F,A6,0B,C8,53,E5,95,6D,E1,D3,08,20,8C,91,86,5C,83,69,4B,A4,F5,DA,7C,A6,F5,12,73,60,7E,80,8C,50,70,78,F5,FC,3A,31,60,85,F8,84,17,28,E3,05,51,E1,89,20,08,68,59,24,F8,3D,C4,18,D1,58,00,55,CA,11,FD,73,A1,58,20,A5,41,22,34,C3,68,39,DF,9C,0E,C3,87,04,AF,81,08,3A,FC,7D,00,B7,8F,13,D5,BA,80,FE,78,7B,EB,D4,4A,D0,93,D1,8C,6D,D4,40,33,7A,FA,02,EC,E2,95,6A,D9,C3,D4,D4,F1,F8,DE,C5,8A,36,42,70,75,7A,D6,5B,C0,E7,04,EB,1D,2E,D6,75,FB,94,D4,3F,39,B1,D4,20,9A,A8,F8,A5,29,59,9A,90,E0,79,6C,A6,A1,3A,0F,48,05,90,14,45,AC,DE,51,E3,10,69,19,41,D5,1C,22,E8,C7,CF,8D,F5,09,CF,BA,1C,D3,AB,39,35,CF,7F,E1,BA,F4,1F,55,03,D4,D1,8B,A0,AB,CC,57,7F,5F,E7,45,A9,39,D2,A3,FE,08,6D,D0,7C,16,91,E0,B5,6D,99,4E,5F,DD,D6,84,90,E4,05,A5,97,0A,28,0D,C9,A0,2C,0C,25,1B,0F,C7,5E,16,B9,FF,AE,AB,61,58,6E,19,3C,1F,AF,F5,30,2F,89,3E,68,5A,AC,37,83,B9,66,FC,55,FD,44,59,EE,11,D5,47,6F,13,5C,2D,B1,2B,5A,5B,BD,7E,72,D7,30,5A,B3,71,C1,8A,42,F6,CD,BB,E5,8D,8B,E7,63,7E,39,C4,B9,27,48,A4,BE,F0,D6,9B,BB,14,A9,FA,83,2B,20,D6,A6,61,24,3C,00,34,D6,9F,F7,45,29,1A,4A,B0,EC,BE,E2,5B,24,54,BA,B3,64,54,00,44,63,48,2C,45,91,6D,82,33,F1,FA,09,FC,2F,21,91,17,D1,67,82,9C,29,61,68,C8,96,6E,EB,BB,CE,FF,D4,56,A9,92,B6,4F,7D,08,A6,40,7F,C6,E5,0E,61,A8,54,6D,EB,E2,70,9E,79,DC,2F,83,0B,94,3B,9F,F3,1B,61,75,9B,A3,55,D5,0D,BF,BF,00,08,2D,23,11,75,9C,BA,D8,C1,7A,95,5E,EF,2B,FD,90,BF,10,5A,24,E8,7D,DC,6B,BD,9E,40,0D,C6,26,10,BE,4A,0A,46,67,47,88,DE,90,1F,28,EF,99,BB,BE,4D,17,7B,12,5C,6C,E4,2C,A1,62,5D,18,97,94,A7,D1,49,1F,7F,F0,60,68,9C,9C,3A,BB,A2,24,42,B9,2C,63,12,CB,75,A0,BD,AF,1F,25,C3,B5,1B,47,A0,D6,1D,94,72,B8,F5,20,BA,AF,4E,7C,6E,9E,D1,D8,2C,38,53,26,7A,AD,1E,C7,4D,98,74,4A,3F,04,F5,FB,CF,C7,E0,43,77,3B,5E,CD,5B,75,4D,A7,2E,F3,F7,4C,9F,B0,8D,26,CF,DC,3A,FA,CC,48,F0,E2,BD,73,64,F7,B5,61,F0,17,0E,C7,60,69,DD,9A,4F,69,A7,1C,4C,BB,86,86,04,AA,F9,96,C9,26,C5,2A,9D,10,29,33,42,BD,28,49,EE,8B,31,57,43,E9,0D,36,14,A8,3C,8F,28,C1,73,11,72,7B,81,A2,C1,B9,17,16,94,8B,36,C6,40,27,F8,14,C4,24,58,9E,9B,CB,75,11,73,AA,2D,96,FD,24,DF,8B,FE,7D,F0,79,AC,33,7F,3C,9A,B7,88,78,3F,69,73,2C,64,FE,77,89,E6,4E,E2,31,D2,98,9E,59,18,AE,03,01,D7,E9,95,1D,C8,9A,E6,5E,D8,E4,59,E3,B9,34,0D,64,A2,D8,AB,91,EF,1C,9B,1F,84,9E,03,F0,6C,35,57,AE,55,D0,59,38,B3,52,B0,E8,7A,09,5B,E0,5F,B4,8C,5D,75,68,94,BA,3C,A0,1D,78,81,0E,22,1F,D0,88,74,03,A7,6D,99,8D,E9,B8,F7,75,58,E0,FD,FD,80,E3,BA,E9,3E,30,0A,3D,A4,A0,4A,7B,06,F9,05,C9,E0,01,94,66,48,D0,57,5A,96,2E,B8,59,61,BC,D5,92,E7,51,79,48,C7,13,C2,7E,45,FF,3F,AD,20,FD,8C,26,6F,8E,F7,A0,1B,B4,A9,BC,D8,8E,FC,89,AE,6D,76,18,42,82,3C,25,D7,61,64,5E,8E,6F,5D,26,AE,B6,81,2E,2E,7D,24,42,17,94,5C,67,AA,4F,FF,89,90,00,ED,D8,70,B1,F6,1B,BA,64,EA,03,88,63,98,09,4C,0D,B6,75,04,63,71,8D,29,65,35,76,5F,B6,F5,7F,10,DB,89,67,92,54,E5,EE,3C,20,DB,91,5F,C6,D2,CF,A7,CE,18,C2,DB,59,94,20,09,20,FD,86,07,1D,5C,97,2F,6B,28,D3,91,3D,2C,13,F8,51,D9,BE,AB,4E,B2,A7,1F,B7,27,74,D7,EE,32,C3,E4,E0,A2,AA,1A,F9,C6,E6,3B,CE,83,31,69,09,1E,B1,8F,7E,FE,03,29,C9,AC,97,AE,FF,8B,F2,7C,AA,5E,AA,DD,5E,86,7D,C2,8E,81,A6,B9,3D,CA,20,78,87,39,A8,F4,BC,7B,19,46,6A,1E,34,39,F8,0C,3E,BA,21,DD,89,25,26,A8,99,34,B5,EB,16,F1,82,27,51,7A,B1,84,29,E2,A5,88,BF,0D,26,1B,46,E7,51,63,F6,C8,E0,2D,D6,E3,1B,20,88,3E,38,A4,E2,6C,88,8D,85,6D,8D,1B,1C,85,44,DB,58,46,44,5C,40,30,8B,D3,24,0B,D8,96,DD,DF,FD,63,04,73,56,09,E5,34,A7,16,88,17,AE,D2,73,4D,70,9F,98,01,59,B0,10,7C,94,FD,80,CC,4F,76,1C,05,C8,CA,43,14,80,CD,B1,15,67,59,8E,3C,49,9E,A5,9E,B2,94,BC,7C,CE,12,2A,88,F1,C0,21,25,09,EE,58,BE,EA,CA,29,30,17,C0,D3,C3,D9,2F,8D,60,85,5E,C8,2F,83,E2,3F,1C,CB,10,BB,35,0F,0D,31,49,21,E9,F4,92,05,CD,52,4B,EA,30,C1,32,05,C7,F3,EC,19,02,0D,3B,04,0F,7E,FD,24,FA,82,DA,EC,9F,24,5E,9D,2E,70,A0,D1,07,06,70,A6,E0,40,1A,B2,EA,64,A9,AD,F7,5C,B6,59,B1,A3,77,45,63,53,06,14,35,5E,F8,65,02,B3,A8,6F,B1,3B,57,19,F9,D8,4B,7D,D4,ED,3C,DE,B6,CB,CA,85,E3,BC,6B,2C,38,00,83,CD,76,E9,55,F6,62,4D,F2,B7,8C,04,53,0A,1B,87,AC,09,A0,39,71,ED,18,5C,30,21,AF,1C,26,0F,48,E7,8F,D7,D7,E7,9B,F7,89,06,CB,55,F4,C9,54,21,C1,11,7A,ED,87,9A,A6,81,5B,13,AE,83,4B,86,31,E6,C8,71,0D,81,CE,A7,5C,B2,64,49,19,4E,08,27,38,82,3C,68,1F,89,39,83,78,93,E0,E9,1B,BA,F8,24,09,7F,3F,74,9F,9C,03,B9,2E,47,49,37,F3,2B,66,20,25,AE,36,82,E6,46,60,98,8D,AE,CD,6A,74,36,CD,AD,AE,22,64,F1,30,9C,B8,2E,9A,E2,7C,EF,FB,7B,68,52,BF,AB,D7,67,C8,34,AF,2E,05,82,6C,B6,7C,8C,54,C4,9D,17,C4,CF,83,84,A4,9D,F0,83,5C,E5,A6,C7,0B,78,6E,3A,E0,F7,4F,B8,A1,AB,74,0E,ED,BE,53,77,2B,82,76,DC,32,98,C7,05,6A,0F,DD,85,F0,85,18,EC,B0,74,43,4E,79,DC,48,03,C5,2B,14,5C,20,4F,16,45,D0,C8,B1,F5,0D,24,80,4B,D2,56,0B,F9,E2,41,C0,18,F3,81,66,DC,BF,2F,8C,D2,B0,47,B3,79,C3,49,68,DA,FC,38,D1,E4,C7,F0,45,4A,4F,93,B7,7D,B3,4F,61,1F,D6,5F,4E,7C,6D,5E,3A,51,10,CF,19,29,FF,04,55,D7,B8,8D,C5,09,C2,50,02,70,CF,24,94,5D,C5,2A,01,46,36,CD,10,46,5E,66,C2,BF,D4,F8,AD,EE,59,FE,E9,09,D7,CB,E8,52,AE,46,65,9D,69,E6,16,94,09,90,61,CD,85,A3,E5,94,49,24,F9,E6,E9,1D,B3,B7,04,8A,F4,5C,FF,78,20,D6,2A,9E,8B,31,37,19,9C,76,5C,9A,A2,14,D7,FF,3D,A2,EF,37,BF,92,95,EF,87,0B,DE,7C,FB,9C,B3,DB,C1,63,1F,CF,12,7E,31,F5,3D,90,39,77,EC,D0,CF,64,73,03,F5,D4,1D,0D,43,AD,ED,E7,07,2C,86,5A,67,70,46,BE,01,C5,A8,F5,95,83,71,9D,00,08,A8,8E,64,03,2D,C6,15,0C,B8,B1,65,31,D3,9E,37,71,E1,D6,50,01,25,64,0F,AE,39,5B,8C,D6,9B,32,E4,DB,18,C7,61,BB,93,8F,56,71,79,4C,32,FF,E8,59,08,3A,F0,3D,F6,4E,BD,CE,25,C9,3D,56,35,C7,4A,04,1C,88,38,74,C8,26,CF,F4,22,AB,C4,4F,CA,EE,F2,17,04,86,DA,EC,C4,DA,B6,EE,DD,F0,DD,10,4A,33,29,62,25,3F,0A,1B,51,2E,D0,A4,24,6F,AE,F3,21,DB,C1,4C,B9,9B,CB,92,B7,00,BB,C3,66,57,94,43,CF,A3,78,9D,EE,FA,20,5C,05,4D,9A,BF,7D,82,FF,BE,CA,38,3A,47,A4,EF,27,4C,63,28,58,C2,EE,CA,60,11,79,63,41,BC,ED,6B,4A,F5,57,23,3F,01,12,82,13,98,F1,07,81,FE,C3,E1,A8,FF,94,06,09,0F,67,BB,BB,61,18,55,50,D1,1E,0F,90,9B,07,6E,52,49,73,D6,13,40,21,8A,AF,BF,C7,BD,C8,A4,5B,22,5C,C0,88,22,0A,B7,62,88,6B,02,DC,E2,9E,CB,8E,9D,83,62,1B,8B,AE,26,88,82,61,5B,50,FD,66,49,F4,8A,2D,E8,70,FB,31,4E,16,E6,AD,28,AB,E2,FF,1D,0A,32,3E,B5,52,45,1E,71,8E,5D,12,53,9D,4A,37,6B,6E,85,C1,80,9A,C6,E7,A0,A1,A0,66,75,1E,C9,7F,D7,29,15,6C,71,D6,63,65,DE,74,A3,58,E4,FC,E5,C8,2A,3F,1E,02,F3,AE,10,97,4C,23,8A,35,28,E0,3C,F9,15,09,CC,09,C0,9E,26,5F,2C,1B,4B,2B,F8,63,A8,8B,31,AB,22,02,F8,8D,53,48,A2,63,2C,1C,93,71,14,51,C4,21,1E,3B,14,48,86,E7,26,8D,41,78,11,76,51,C8,7E,31,98,EE,D2,45,14,E5,3D,23,29,94,C0,78,17,B3,F5,9A,65,5F,1D,00,27,FB,89,1C,2D,1C,AC,12,67,1F,BE,95,D6,9D,77,38,09,03,EC,4E,AF,0A,38,A6,D1,A5,BC,3C,B2,D5,0D,EC,12,C6,0F,F7,7E,13,0C,A2,3F,EF,84,E8,45,E1,F8,24,66,F3,5B,A1,40,AA,2C,57,34,3C,E0,B4,3F,85,0E,D5,C0,BB,15,1E,74,CE,58,E2,39,94,B1,A0,8C,1F,73,CD,A8,44,76,01,50,88,63,60,5A,54,4E,45,F5,B2,3B,B0,8D,83,D8,FE,FC,77,15,1D,C7,94,E7,E5,72,C1,2F,65,CC,C7,2A,F1,3B,39,80,AD,E6,5E,CD,59,DC,BE,43,E8,63,FC,31,0E,D0,8F,15,E8,9D,DC,1C,39,85,13,A7,0E,D0,9A,1F,BA,EF,04,E4,7A,64,94,D9,EE,96,FE,6E,CE,0F,9A,66,B6,1B,FD,EC,68,1C,C2,D2,54,9E,9C,92,AD,44,5D,D7,CB,92,42,54,87,24,B1,A9,7D,8E,68,7D,0B,CC,BA,2B,50,C7,6F,C6,5D,0B,EA,A8,94,14,D3,49,7A,0E,7A,1B,9F,20,E2,33,FD,48,A2,30,C7,4E,D5,C7,DE,0C,B4,22,A8,A7,3F,5A,5A,55,AE,E3,C9,AC,1E,B7,48,4B,8A,83,2A,2D,E6,03,4B,FC,CD,F6,23,2A,2D,CC,E6,7B,4D,8F,15,45,A7,B9,2F,8A,A4,DC,42,F4,53,FE,00,E2,28,79,5A,0F,3C,91,A9,58,92,15,DE,76,5B,44,54,39,ED,85,14,2D,34,63,03,1E,57,2C,71,75,7A,90,07,6A,EE,BA,2D,F1,1A,C4,77,DD,B1,46,09,E3,B9,1D,FB,87,3C,43,9B,CE,59,C9,A4,38,49,06,A4,AB,74,BB,49,51,85,02,AA,E8,AC,33,38,1D,01,71,01,DE,FF,34,C0,0D,42,32,75,0B,60,E4,59,45,91,91,7F,1D,1B,AA,85,91,0A,C8,9D,70,02,DB,AF,5D,7D,76,F4,F7,9F,F0,9C,5F,F6,4C,4A,63,6A,41,21,9D,1F,3E,0A,45,4D,94,2C,7D,F5,2D,D7,90,F7,E2,63,88,87,7C,A5,B0,BD,8C,33,CE,A7,2B,7B,8D,54,A2,21,CF,77,63,82,D6,3C,1E,25,C1,49,18,91,7B,7E,E6,CB,8F,92,4E,32,04,86,D7,1D,FC,E5,1D,DA,24,EF,8D,64,3E,D0,D2,25,D5,3E,63,01,84,CF,CD,2E,C7,D4,BB,38,BA,3B,56,EB,98,F9,33,A6,32,D5,23,15,0B,ED,3D,00,B8,5A,AE,FA,05,3D,A3,E5,C8,F4,41,50,8F,C4,3E,1E,7F,7D,E8,11,98,0B,B2,87,62,8B,30,88,79,E0,CD,CD,34,7C,1C,FF,EF,CD,DD,C4,2C,84,4A,79,4E,69,EA,DD,9D,39,FF,D6,DA,1A,0C,98,FD,DD,AC,CC,E8,59,57,64,9A,32,7B,41,D8,14,5F,F5,31,76,AA,B7,6D,D5,77,E4,2D,B4,1C,62,79,54,AB,1C,64,7B,A0,4D,70,34,72,D9,06,55,B0,9E,65,8C,DD,E3,9F,6E,1A,A3,E6,69,09,C3,3B,DD,D4,74,7E,1F,63,63,5B,E8,E8,3B,1D,EB,A9,F6,D9,E8,86,C4,02,C3,54,15,F3,C3,EF,1A,1E,10,78,F7,43,FB,87,94,FF,DE,1F,DF,42,90,F1,9B,11,C8,DF,73,3D,D4,4E,42,AD,27,88,15,C5,E0,F4,A9,E8,7D,AB,9D,7B,92,0B,E8,ED,27,D1,07,E9,FD,D6,74,FA,91,53,E8,26,D2,D0,F1,0F,EF,7F,BB,F2,74,0C,89,93,45,F1,8A,C1,E0,66,39,62,E5,4A,26,35,9B,62,7B,47,FE,D5,F0,67,DC,68,E2,CC,2A,E5,59,99,48,D3,9E,46,B1,A6,6B,43,F2,B0,3F,0F,76,D6,35,34,89,0B,72,AE,86,3C,09,DA,45,98,9D,5F,61,05,6C,A1,A3,37,98,84,F4,5A,47,C2,2E,13,E8,18,E7,B3,3D,D1,B4,4E,03,F0,23,DD,5E,0C,CA,DF,51,72,F6,73,9F,5F,1F,79,D0,97,B4,10,90,F9,84,FD,A7,BD,D1,AF,20,6A,60,C7,34,55,37,05,4A,C5,62,8B,57,19,D9,F7,D1,1B,47,DC,3B,30,84,DB,7B,72,A5,1C,3C,5B,3A,23,4B,2F,52,1A,CD,2F,02,FB,65,A2,39,6E,95,16,9E,44,5C,B5,8A,9C,8D,72,1C,E8,72,CD,16,3E,63,CA,5D,41,78,D8,51,56,BF,B8,59,46,22,CF,30,2B,28,ED,6D,FE,EC,41,35,59,D8,C3,99,53,A8,4F,FB,3B,C0,DE,02,D2,5B,18,0E,DC,51,27,A0,42,AF,F9,C1,F5,89,5F,E5,75,82,B4,00,07,1F,5B,E3,A9,9F,00,87,0D,63,00,18,CA,85,66,DE,FC,51,C3,1F,F6,AA,2D,AA,BE,78,71,13,6B,64,45,76,03,BE,F2,0C,47,DA,87,98,CA,4C,93,09,43,10,72,E9,D5,9C,3B,27,6F,50,75,09,8F,AC,D6,60,BB,F3,A9,50,40,91,B5,63,CD,6A,76,86,11,12,FC,F5,FD,CA,B8,43,E4,A2,36,91,D0,D8,64,91,E0,B4,9D,CC,09,9F,B3,4D,80,0D,51,6D,69,83,C5,86,8F,F7,92,61,4F,2F,36,5F,1F,A9,F0,AD,A8,EC,B8,BA,77,07,DC,05,BD,15,70,11,82,90,28,07,AC,01,FA,96,C6,40,61,C7,E4,E3,11,E0,F1,51,4C,DA,84,FD,58,0D,C5,91,7E,D9,F7,A7,06,8E,98,26,19,0A,01,BE,FE,6A,8D,11,CB,DE,45,5B,53,CD,A8,74,9B,4B,1F,3E,F9,F2,5A,55,97,F7,F8,7E,4C,4E,59,C5,C1,C4,5F,45,E1,F9,58,24,C7,2C,8B,A3,6C,00,79,E5,E0,86,40,4D,41,32,E0,72,E2,6D,A6,3A,1E,5C,31,0C,C9,B9,9B,EB,18,C5,FD,CA,64,CC,45,67,52,BF,F3,C8,D6,76,4C,AD,3D,33,41,32,2B,42,B6,2B,A4,A7,10,49,BC,7D,95,C5,27,C0,6F,5D,1E,EE,79,99,B1,F5,CF,8E,F0,6E,49,B4,19,46,A3,10,D0,B1,86,BB,01,B2,3C,C0,72,C9,96,CB,8B,71,0D,DD,10,5B,D4,CD,C8,50,E1,CE,13,90,32,05,EB,CC,25,2B,54,1D,13,83,15,1D,B8,F6,05,BF,6B,36,E9,06,BC,12,97,E7,85,37,A9,41,C9,8F,FB,18,F3,3F,56,95,91,44,5B,A4,51,A6,0E,D4,26,28,6F,00,8C,23,2A,06,D4,9B,51,14,E8,A0,43,EC,18,20,67,86,AE,56,17,C6,EE,EF,60,17,2E,D6,A3,BC,49,93,DA,AC,1D,C7,5B,BB,32,55,BA,82,78,C8,6B,D5,60,1F,A4,E6,0C,63,36,0A,A2,13,3B,F5,0B,B3,BB,3E,A6,0F,E3,99,37,4F,9C,12,0B,E9,0B,2F,F7,F9,BB,23,FB,CD,29,6F,00,63,77,B5,C4,2B,DF,A6,21,4A,1C,06,C3,60,43,26,A7,4C,C2,0C,EA,0F,CE,EB,E9,62,79,A7,F1,69,A6,DA,3F,5A,D6,4D,D9,D6,1C,E6,05,F9,6E,B3,1E,B5,3C,EB,DA,88,07,3F,44,67,DF,6C,C3,26,03,5D,B7,87,FF,2E,97,28,08,4A,DD,3C,D4,F1,FC,4B,DD,61,B5,CE,45,0F,6C,A6,3E,88,39,02,9C,99,70,19,0F,41,D8,EC,73,51,76,55,80,3D,C6,75,45,6C,A6,FC,C6,B8,F5,BB,29,01,82,5A,C6,97,AE,56,FF,12,A2,67,3D,4C,24,6B,0D,B6,94,A4,FD,CB,C4,2E,09,03,46,0C,E5,1C,30,97,C5,4F,D5,F5,47,78,5F,AE,53,10,E9,AD,A1,1F,38,7C,0D,D2,A0,FB,FC,3F,D2,DC,79,F9,FD,A5,7B,BA,B4,6E,99,1C,C5,9C,78,14,7F,C0,6D,31,E2,72,AF,EC,C9,C2,69,1A,3E,37,E3,0B,48,95,61,8E,A6,AA,42,A7,B4,54,C5,11,4C,BE,3B,DB,A4,F6,54,18,CD,DE,C7,59,94,97,04,AA,59,A4,07,25,E6,66,53,CF,6F,82,B6,1E,38,09,C5,CA,7C,2B,00,CC,8A,37,DC,CF,A4,BC,88,4B,2A,23,D1,57,2A,84,19,17,5F,9A,63,F7,A8,F1,76,90,FF,51,B4,97,E9,DE,ED,2C,B5,CA,32,B9,4E,F2,D7,9B,5F,0C,CC,67,B2,4A,82,16,23,89,96,8C,78,36,91,5B,35,4C,61,62,3F,4D,09,DF,F6,D7,D8,56,4C,46,32,A0,06,FD,D1,4C,56,58,0F,87,9D,47,49,0D,7F,DF,41,E7,B1,38,9D,30,4B,97,4A,C4,58,2A,0C,02,54,BB,81,0D,9F,AC,9D,04,8F,F4,9A,E7,54,DE,35,69,5B,82,E6,A5,96,95,5D,29,B5,43,23,F3,49,17,29,B3,19,96,C1,C6,2E,98,AC,A2,B8,96,06,C8,99,5D,56,73,C5,98,8E,B3,B4,23,D8,CE,3B,43,0A,F9,F2,A6,AE,E6,B6,F9,58,FB,F1,BB,89,83,79,72,AC,97,E4,12,3A,97,FF,4D,E8,FD,21,A5,DB,68,04,33,08,B3,8E,87,54,DE,71,8D,3F,C3,AB,2B,68,86,54,55,5F,AF,F6,A9,4E,3B,EF,67,15,2B,CC,6B,FC,F3,37,5E,9F,DE,EB,4B,42,33,08,84,C8,6F,DE,25,DA,6A,19,38,83,1D,44,4D,A6,F3,9F,36,58,FD,D4,EC,14,9C,29,F2,69,A2,C4,A2,1E,3D,D5,66,0B,B7,89,3E,57,EB,38,D8,B8,07,1E,86,5C,93,5D,59,59,A3,AA,C1,4A,41,0A,4F,7F,6C,2C,C1,5D,AF,EF,97,FE,BE,10,2D,64,19,4B,2B,9B,2D,BE,DE,94,A5,22,59,72,C0,D8,B5,84,37,A3,C5,09,BF,CE,DB,D2,1F,FF,7E,3C,0F,CC,BA,8D,76,37,34,69,52,00,76,A2,73,F6,B0,5C,59,22,AD,E3,9E,8B,2C,6C,8B,78,F7,61,85,7B,F3,FC,BC,6C,C6,AD,8A,85,A8,30,7A,72,70,88,E7,40,88,71,50,32,C7,1D,4E,51,1C,45,F7,E6,E1,C8,20,46,3A,9C,5D,63,32,59,31,36,80,6B,A4,C5,2D,37,EC,B0,8A,2E,B8,FB,C7,29,AD,59,87,A4,16,89,09,AD,CE,35,7F,34,A1,04,F1,97,E4,E5,14,2C,A7,7C,C2,EA,8B,6A,15,27,7C,0E,A5,0D,D1,68,99,B4,D9,04,B4,E3,3E,24,80,4B,3B,E3,79,59,8A,3B,23,82,EB,E9,2C,27,71,1B,8F,C3,28,02,BA,89,AD,2D,9B,56,90,7E,9E,E9,56,09,FA,7D,91,72,00,DA,FA,96,64,89,3B,9C,52,F8,0C,D0,20,A1,FE,FA,B4,5A,08,D6,AC,09,AB,C9,EE,7E,CF,B4,5A,D4,27,D8,57,7B,41,76,FA,21,D0,D8,65,51,FF,2A,13,59,41,33,69,AF,4F,24,F4,B0,58,A8,69,F5,40,B0,83,27,96,CB,1C,39,48,04,0E,E3,89,94,62,20,7F,B8,A4,E9,61,6F,27,81,B4,D8,A7,88,EE,CF,A4,B4,04,0D,30,BA,7F,D2,D0,F8,AB,9A,9A,87,EF,9F,B1,BC,33,9A,73,11,7E,14,FB,97,F6,85,26,FA,0A,C5,1E,ED,02,77,14,75,14,3B,D4,51,10,66,5E,43,9B,5F,F2,C5,E8,F7,F3,A0,62,D9,BC,E8,D2,8D,A6,5E,54,7C,33,57,FE,05,E4,4B,40,DF,50,A3,7A,92,F3,50,B9,61,81,5D,34,4D,28,B7,97,A6,2E,8E,F5,6C,3A,FD,3F,BD,07,AE,8A,B9,73,5E,0B,51,8B,8A,3F,21,71,50,C6,C5,82,D8,14,0C,04,E7,F8,75,62,49,6F,00,EC,E0,47,5E,33,50,FE,07,5D,71,23,C2,0C,2C,F9,E8,CC,07,87,3D,53,53,23,BD,A7,D4,48,EB,5B,C0,61,D4,F9,53,AB,57,BD,D3,EE,6A,90,19,CB,98,25,29,7E,82,DA,BF,9F,C8,C3,08,1D,FB,8F,D1,87,F0,E4,55,B4,68,6E,9F,2E,01,8B,40,C1,2D,15,89,EC,DF,33,D7,45,91,4E,EF,1D,9A,B3,E3,D8,D9,70,6D,0D,3E,B7,51,75,34,09,4A,63,D7,53,68,50,21,E0,B5,A0,C4,AE,A2,A9,68,03,D9,15,87,AA,EB,59,00,E2,B4,54,B0,40,46,99,FC,F8,06,E9,26,97,E4,F6,64,AB,7E,36,19,70,75,D4,19,85,9C,50,C4,FB,9E,32,66,7F,43,0D,16,30,B2,25,47,82,BD,70,6F,7A,64,7E,BD,DD,78,5D,A7,05,09,AD,3B,81,29,91,DD,AD,D2,71,DC,CD,01,26,3F,7D,3F,A3,3D,69,92,88,3F,E5,5E,F2,EC,F1,A9,D8,9B,71,C3,33,44,8F,2B,5F,F7,DB,4B,BF,DA,FB,07,9B,D6,63,E4,6B,BA,CE,ED,2D,87,1D,91,84,04,EA,FE,1F,A4,76,DB,DB,35,1F,57,EC,07,73,B0,2D,02,3F,BB,5F,4C,62,BD,17,08,63,8B,3C,05,0D,EF,AB,2D,0A,11,9F,5D,49,78,B8,89,88,1A,46,40,13,89,7C,54,7E,E3,53,10,C5,22,96,33,BC,C9,58,C1,F2,16,1F,CC,A6,42,A6,67,24,8A,C7,73,8D,95,34,0C,AD,89,B4,F5,DA,46,33,69,E8,CA,06,BF,76,85,19,C4,10,41,0B,ED,E3,70,36,5B,BA,03,D8,10,38,6A,DA,29,4B,15,88,20,CF,36,BF,21,16,06,1E,4D,F4,7E,5D,63,72,1C,F4,5D,F1,B4,83,A3,8A,4A,3B,B9,DC,16,94,A9,AA,EA,A4,DE,F6,BA,10,BF,2D,C5,B8,65,4D,3F,40,D5,F5,3E,F2,47,0A,C1,D0,70,7F,06,53,0A,5C,E0,7E,B8,F7,4F,27,8C,65,70,AA,17,35,B9,79,9E,6D,E2,26,71,A0,2A,14,EF,9F,51,81,02,8E,97,AC,48,65,36,39,FB,A0,EA,4C,04,A7,58,AF,2D,78,B8,74,82,43,66,D4,98,D5,66,2E,D7,D6,97,C5,FB,B2,D5,8F,24,5C,77,CD,E0,EE,DD,AC,BB,7F,9B,2C,AE,85,8D,B7,CA,85,58,F4,0B,4C,02,A2,AC,51,57,8E,2D,82,69,DF,10,AA,FC,F6,39,B9,D4,04,45,62,4A,EE,46,2D,7C,B2,80,03,6C,C7,54,B5,55,B8,19,1C,E4,F7,D1,22,DD,70,6E,17,82,27,8B,6E,41,30,4F,42,2A,07,F6,C1,E9,C5,C3,F9,CD,72,DA,05,BB,00,9C,50,AA,B7,72,20,18,97,38,97,29,5A,70,B1,38,70,A8,09,09,4E,D2,54,B6,01,69,CC,61,1A,9C,C2,6E,85,28,24,58,C7,8D,84,24,CB,34,5D,C2,05,D6,C5,D0,D6,D9,40,6D,3C,50,E3,16,81,7B,51,47,B8,65,81,E7,6B,82,C8,FF,13,BA,2C,91,7C,BF,26,8E,D4,13,79,C4,2F,51,0D,43,E6,4A,1F,0B,F7,6D,64,66,5E,B1,7D,F4,4A,90,88,89,34,07,6C,67,CC,2C,65,7A,85,89,5E,FA,EA,61,3F,84,4A,F3,67,B9,0C,4F,E2,04,C2,26,68,38,08,45,03,A2,BF,4C,32,93,79,8B,2F,FF,FA,CB,09,04,4D,6A,06,55,1C,CF,80,42,EC,27,36,53,48,5E,84,4C,6C,9B,6D,17,95,5F,17,E0,BA,98,DB,33,9E,1E,30,5E,64,48,C7,E3,AC,D2,D1,99,A0,C3,67,B7,48,1F,FB,31,76,91,89,C1,38,83,85,1E,D6,5D,EF,E5,49,7F,A2,61,CE,49,06,60,97,4E,EF,84,85,40,45,DE,3F,3D,73,F5,49,D4,A2,01,92,85,09,8E,78,01,C6,E4,F9,A7,34,7F,90,81,6E,29,D0,7F,6C,ED,05,77,FC,16,F1,36,3A,FD,C6,B1,1C,7F,E5,BA,FA,A7,A8,45,F2,41,F3,2C,0B,6C,45,9C,C5,A5,1D,62,FF,B7,AD,A4,2C,E4,42,D1,E6,82,DC,D6,7C,19,78,7C,1F,78,4A,5D,E6,C6,E5,FC,67,CF,3A,99,F3,DA,0D,73,10,E1,66,4E,33,53,E4,00,3A,83,B6,11,3C,0F,F9,14,68,E5,2A,5D,42,E1,8E,EE,A4,78,8C,BA,26,53,24,C8,CF,03,31,92,D4,DF,26,CF,C3,77,45,DB,D8,A9,C0,A7,7E,C5,4B,59,C0,B0,83,CD,01,AE,47,39,65,67,B4,B9,23,0E,09,F5,B9,EB,19,5A,30,CA,D6,5C,1C,F0,4A,4F,0B,6D,6A,2C,DB,65,8D,FD,F8,FE,3B,E7,7D,87,EA,14,CB,53,6A,FA,DD,AD,CD,A6,5F,59,CF,B2,32,1D,83,72,46,6C,B9,1E,B5,05,BF,C6,27,98,F2,A9,B4,59,EC,38,43,FF,5B,0F,9E,85,0F,60,74,26,0A,90,E1,45,8E,4D,56,50,26,8A,6C,E3,F7,6E,71,C0,3A,D1,C0,96,6E,E1,1C,7E,D9,9B,1C,FE,A7,95,C2,7A,5E,77,37,7F,7F,FC,D0,37,0E,A4,43,27,0B,61,9E,4A,06,88,37,A4,69,F9,6D,17,A1,3E,07,AA,06,B7,F5,B5,FC,9A,3F,A1,48,AE,E8,B2,3C,FC,59,74,3E,8D,EA,F2,BF,DD,5B,D8,C9,F9,91,70,DF,8D,AB,EE,FD,E4,38,F1,49,2E,C0,64,57,91,32,AB,76,4C,C3,F6,23,1D,91,30,52,F7,DD,D9,BD,25,40,EB,EE,A5,C5,80,3E,9B,7A,B5,DE,BB,78,75,3C,95,50,7A,1D,9E,67,BA,F6,F3,B6,49,58,13,D4,02,DB,8F,CF,DE,7B,05,BF,00,2A,03,7A,9B,A8,99,16,B0,EA,D4,DE,EA,E1,D4,B0,E0,79,B3,4B,23,B7,22,34,95,EA,8C,26,AE,D5,C2,B4,87,61,61,63,96,A7,3B,7D,81,96,C7,AA,BD,65,C7,7C,2D,31,A4,60,18,3F,A9,B1,D2,D0,A7,5E,75,F8,91,30,6D,CC,10,01,AD,46,8A,54,5E,37,18,A5,5B,09,E2,96,E0,29,E2,33,1E,C5,5F,4A,0F,E9,BE,7E,D6,5D,39,0B,7F,E9,90,D6,03,B2,25,59,43,26,73,07,B0,3B,5D,A2,72,55,E9,37,4A,9E,D5,F6,C3,82,C7,1F,65,87,CB,81,E3,88,54,98,D3,9F,40,00,03,A8,03,0C,27,85,2D,E9,04,1C,93,15,44,7A,35,6F,D6,2B,20,49,B4,C1,A7,FF,74,BE,15,16,5F,F3,28,F3,02,3E,26,BA,BD,59,0A,44,0B,4B,AE,35,6C,A7,A4,3A,02,F4,73,ED,6E,7A,C5,EE,C3,95,25,8E,5C,38,33,C8,85,55,54,00,5C,15,15,EE,2E,9E,F7,80,D6,D2,F6,B3,B9,28,C0,14,7C,43,F4,AA,EF,66,1E,C0,B5,EE,4E,B6,90,FE,D9,0B,6E,87,F0,3B,7A,B2,49,C2,CF,BC,6C,4B,B6,22,81,E6,50,CF,4F,FB,94,B7,1A,C2,62,30,CA,88,4B,0C,DD,28,0F,CC,F0,B9,F4,DC,FC,F0,18,B8,41,AD,42,EE,D2,F4,87,8D,5B,2C,A5,7C,EF,59,C6,7D,30,7A,44,48,E0,E3,BC,BB,65,20,FD,87,B3,FB,B2,E9,3F,88,EF,28,60,29,60,3F,9A,BF,A0,71,F6,44,9B,C1,FD,51,D5,BD,87,FC,5B,3A,CF,ED,99,CD,E6,C1,53,1A,0A,9D,09,04,DA,96,ED,11,14,62,AC,35,5A,BB,D7,13,5B,1E,2F,D2,82,71,C3,C4,A1,3D,86,89,4C,BE,96,3A,87,4F,50,6A,A1,CB,52,92,E7,2D,6D,10,91,A7,BB,ED,05,1E,83,5C,94,7C,A5,3B,95,0D,96,A4,23,7C,4B,ED,2C,E5,BD,14,C0,F3,E6,43,78,86,82,1C,16,27,38,28,26,D9,43,AD,92,50,DC,DE,74,F4,5D,91,B3,0D,B7,5A,96,74,67,2B,2A,1B,6C,FC,B8,CA,6A,26,57,2F,4D,01,2A,AA,98,5D,28,1B,54,55,64,81,A5,01,EB,37,EA,5E,5E,32,46,08,D6,83,6D,F4,77,36,41,30,3A,A8,17,06,DD,D3,13,15,F7,9A,13,58,AB,8B,1F,BE,AC,EA,F8,50,9F,32,E5,CF,7E,C0,23,84,EA,67,FE,2B,00,25,A3,C8,07,F4,00,5B,00,69,9D,80,75,11,E6,C1,52,07,83,F8,52,76,18,0B,21,74,E8,97,5D,62,7D,A5,FC,74,D0,B0,05,1A,99,2A,4E,94,2E,33,98,4C,CF,88,0C,3D,FB,7E,BA,C5,F2,82,10,4A,3D,25,36,30,B8,29,09,DC,64,9F,20,8A,12,C4,43,1E,17,98,EF,36,44,56,8B,10,33,73,1C,0A,DD,7C,F7,A0,A8,0B,54,E6,D2,70,8B,B9,C6,77,79,E6,59,6A,FA,65,DB,02,4D,25,BC,E4,63,E0,0D,FC,FC,D2,15,FE,FE,31,BE,B2,AF,E6,91,BE,71,F0,4F,82,C6,76,C1,F6,1C,0B,3A,B0,71,A6,C4,95,77,0C,34,56,44,B1,12,99,B8,87,D9,76,90,AC,57,13,0C,36,F3,6B,A3,9D,A4,B2,8D,55,63,AA,57,F3,25,28,10,B2,89,A4,B7,AB,09,6E,9E,11,48,53,00,94,3C,E9,2D,9D,56,7F,2D,2E,4B,4A,46,23,53,35,70,57,1E,0A,8E,41,9E,22,94,6F,91,27,C2,4C,3F,CD,D2,67,28,5D,4F,7D,ED,7C,CC,7C,44,AB,A1,F2,8F,A2,8F,58,8C,F2,15,C6,68,AD,3B,D5,2F,EC,DF,A5,13,60,73,2E,28,58,D1,DB,E8,0D,22,5C,95,A5,DD,0C,71,EB,BD,69,E4,0A,58,C9,6A,0F,79,96,6D,5A,95,BE,E3,BD,7E,BE,5A,8E,38,03,31,86,CB,DA,BA,FA,E6,65,F7,BB,2C,80,C4,FB,BC,3E,62,EA,DF,E0,96,7E,6A,52,67,70,9E,B4,DB,3E,F8,07,AD,1B,DA,D9,91,90,A4,C2,70,73,A9,AB,41,9A,08,FB,8C,1F,78,91,89,D4,02,27,72,BB,89,69,0C,EA,57,0B,AF,00,8D,41,1F,2D,5C,F9,55,18,25,C4,7E,E5,6E,88,C4,05,B7,C5,64,B6,25,DD,6D,00,AE,15,0D,E0,57,CF,8F,9B,AE,9A,6E,ED,76,A1,9A,E0,59,17,6E,70,B9,91,57,E8,14,CF,F1,FE,29,15,2A,7E,B0,2B,06,58,9C,4D,89,41,AC,E8,B9,3E,E6,72,E8,0C,32,87,03,77,FE,2A,D5,B9,91,39,79,72,25,F0,D8,7A,A4,BA,AC,6B,DA,54,1C,88,92,A5,6B,42,84,66,58,A9,C2,74,50,B2,91,50,3C,69,69,8E,39,D0,00,90,05,10,54,AC,69,71,9A,58,7D,93,9F,A5,C2,CE,F3,16,45,01,56,A4,1C,AB,2F,9D,D0,A7,17,43,A6,F5,8A,C7,F4,B6,3F,66,5E,13,CF,81,7D,8B,BB,94,78,52,28,6E,D7,0A,AA,08,DE,06,40,02,35,65,99,6E,FE,73,81,22,D7,08,BF,97,25,A3,AA,5B,2B,0D,72,70,F5,0A,BC,83,34,C0,CE,B1,BE,72,E7,E4,7C,7F,C9,46,EA,17,63,6E,DA,F0,89,A9,AA,2D,F1,27,4E,DF,CD,0E,88,22,3E,8A,B8,07,F8,A4,3A,88,46,4D,26,86,FD,8A,C7,D7,0D,3F,43,D1,D6,C2,F3,19,11,62,73,1D,5D,38,33,97,B1,01,73,8F,98,37,31,DF,B1,F2,19,70,52,A9,1F,FF,09,AE,9F,61,5D,90,C3,E5,C2,13,5B,B5,EA,77,8E,33,AB,45,C0,AD,3A,D2,5F,2B,38,06,62,D5,86,25,2D,C8,50,DD,C2,CB,80,FB,89,88,54,D0,38,DF,07,D4,27,AC,DC,30,92,72,BE,36,03,E2,2E,4A,79,CD,53,2D,2E,DA,41,95,8B,D0,9E,A3,73,99,74,7D,68,54,F1,88,2E,B9,60,9D,A4,2A,FC,1D,25,4B,39,69,6D,58,D2,48,BF,06,A8,99,5D,6E,19,5B,EE,C8,48,98,23,04,59,05,F4,D6,2A,FB,79,24,AB,23,DD,AE,95,FC,71,D3,4B,CD,EB,C0,03,42,65,18,F4,C0,EB,71,24,04,69,90,0C,7E,15,5A,53,8C,BF,F7,35,66,2F,86,AB,CF,59,63,F3,79,53,13,57,43,89,21,B2,5B,AB,01,9E,85,A7,A8,69,9E,AF,F9,2A,9D,F0,14,22,0E,57,F4,05,17,5E,16,F1,A6,A5,00,1F,CF,D8,78,92,D7,88,68,ED,7A,40,CB,E0,74,5C,6C,53,4D,F1,8A,05,38,84,88,91,8F,20,7F,5B,A1,10,B3,92,43,40,54,A3,54,5C,CC,D4,A7,C3,A5,C4,F4,AD,AD,96,6A,79,AB,E1,20,F1,B8,51,4C,DA,97,87,F7,AC,5E,1B,45,E9,7A,25,0D,46,54,18,54,75,25,D9,45,DF,70,E3,82,D7,BE,DB,1F,8E,08,3A,80,88,B0,B9,5D,32,6F,DF,07,92,89,58,37,65,35,9A,3B,24,8B,C8,6C,34,11,37,E1,9E,5D,4C,B4,D2,12,BD,2C,7B,81,90,CC,F9,35,0E,A9,A2,4B,40,73,3A,D9,AF,3B,EE,4F,CB,17,84,70,98,53,34,D6,E8,DD,0F,C4,85,88,BF,A7,4E,BA,EC,EE,39,8F,10,58,5C,25,BE,0A,49,7C,72,FF,20,C8,3B,55,CE,E3,3C,7E,77,51,9F,41,C1,1E,71,16,C2,88,E2,17,E9,13,5D,C9,CD,D3,82,6C,17,21,9C,BE,6C,1F,4A,53,46,C9,E1,E5,A9,31,EE,49,60,4D,E4,51,9A,AF,55,BC,10,69,B9,E8,1D,2B,61,5A,B8,BB,FD,67,69,DA,11,D0,AD,84,37,E2,44,45,21,C7,0B,D4,7A,18,2F,E0,E8,AD,67,6F,19,8B,C7,5B,33,09,65,11,32,73,A3,C8,4D,C0,91,1C,70,97,60,E2,99,91,2F,3F,50,A2,9F,39,BF,AE,40,31,95,42,FB,94,2C,93,3D,90,88,48,28,E1,97,50,91,BD,BB,37,6E,FB,D3,1D,A6,A9,30,B8,5E,58,8C,53,AC,64,ED,E5,C0,EB,41,0F,70,55,29,DA,D5,18,15,9D,77,AA,BF,D7,D0,A3,B9,06,02,41,66,9B,4B,60,BE,B8,79,85,E0,79,44,98,F9,6B,47,94,0C,66,6A,E1,AC,59,3E,11,5B,F3,C1,F5,3B,53,DD,D8,86,65,C9,6B,B0,C1,96,31,00,31,E9,64,C0,E7,C2,F3,A4,91,45,16,63,C9,C2,B8,4D,AF,1B,76,6E,64,52,D5,35,FB,9E,0B,00,E3,D4,CF,07,35,ED,85,47,CA,6F,1E,3D,84,B0,96,BF,8A,3D,9D,F3,74,02,76,3C,39,B3,65,9B,6D,E0,B9,66,DD,DA,A5,0C,0D,AD,E6,01,0C,38,C4,A3,F2,20,E2,F9,24,6A,23,89,78,0F,FC,B6,DD,56,A5,45,F4,0C,03,56,70,E2,18,3E,E6,6E,97,1A,6D,E0,F1,6D,00,0B,E6,88,04,B0,2E,B8,22,09,8B,D9,86,5E,36,F6,B7,19,A8,B2,DD,07,E5,5A,B5,38,9E,3E,B2,68,00,84,1E,F6,7D,3F,0E,13,06,4A,AA,B4,FD,80,23,3C,22,65,31,74,70,1F,FA,04,88,F6,ED,B5,70,99,E1,F2,07,66,C4,17,24,66,92,D7,62,4C,DD,6F,5A,8F,95,ED,78,32,5C,B5,98,07,0D,D7,A7,25,5E,17,63,1D,43,57,C1,BF,0D,14,EB,9E,D6,BE,F6,BC,1B,29,F8,64,72,E4,CF,F8,5C,FA,80,18,3C,9E,14,A0,75,7C,AF,1A,46,F0,BF,F9,CD,D7,97,86,E4,C6,6E,BD,04,D0,2D,10,31,F5,42,0E,7A,56,E9,3D,11,06,B5,6E,2D,74,23,59,04,0F,95,A8,62,EF,07,40,70,87,3B,AB,23,73,3B,2D,01,E3,5B,A7,79,8B,0B,FC,9E,64,EE,D6,D0,B8,60,9E,1D,7D,81,66,21,71,C1,46,9A,DE,26,65,ED,09,C9,E5,2B,29,0C,D4,77,7F,D1,D5,73,67,D7,7F,65,77,6E,E7,36,39,8E,9D,BC,19,AA,43,E6,90,E7,DB,07,94,B3,EB,D4,29,5A,40,95,8C,00,57,90,E6,8E,21,A6,34,43,BC,92,6F,F2,97,FF,38,B7,D6,A4,3E,8B,12,A5,F9,70,8A,EA,F2,12,72,17,28,15,FD,72,83,1D,77,18,91,59,52,46,97,7E,3D,29,C3,4C,C2,E2,B5,73,9B,72,81,3E,00,8C,85,2E,93,63,1B,C6,88,CB,EB,26,62,B4,E0,88,11,4C,84,D8,8B,BD,88,C9,90,38,64,BF,C5,B4,A4,97,B7,7E,18,61,F8,82,7D,6D,C8,2D,C0,B3,4C,A7,2C,00,02,D5,B9,75,BD,34,28,B3,A1,5F,67,FF,46,8F,9E,9C,4E,7A,73,74,CC,63,FE,6C,99,F1,3E,1F,34,6D,03,04,B4,1F,0D,EC,E5,23,90,A5,49,0E,E1,6C,78,52,D0,4C,2A,DA,2F,0A,77,8F,D8,74,F6,EE,3E,AA,57,26,5A,D8,0C,DD,DF,90,97,48,47,62,A3,71,F5,D8,94,A2,10,04,26,D2,12,24,6C,D0,0A,C8,AA,15,B4,79,62,C2,77,A9,1C,29,33,D5,5E,23,00,BF,E8,13,78,7D,61,A1,C3,0A,7C,77,87,76,BA,B5,89,D1,26,78,A6,3B,F4,F4,38,B2,FB,9D,17,38,E4,57,78,51,47,09,5D,84,25,00,94,E8,78,86,78,E9,1D,38,3A,42,B1,92,B7,B6,51,01,BA,FE,4A,3F,C9,9E,37,AF,85,5D,11,F3,93,50,4C,C6,7C,2F,B7,C8,9C,B5,BD,C5,5C,6A,E5,D3,A9,1F,79,5D,8E,65,F0,67,49,CA,44,6B,90,4B,D1,56,3F,21,1B,E0,FA,80,75,01,8E,F3,B4,17,0E,85,EE,27,EC,7F,94,C1,3D,8A,2E,CE,49,39,24,65,1A,25,CC,7E,91,C3,64,BE,A0,7A,B5,B7,3E,4D,B3,41,53,EA,8C,DF,0A,E4,96,61,82,5D,12,83,67,72,6E,F3,20,F1,E2,94,20,62,26,5C,60,7D,D9,3C,2F,6C,A2,42,C2,BA,07,22,94,5D,A2,9C,05,93,0C,AD,94,0E,77,B4,BC,8F,CC,3D,09,84,F9,81,C4,11,F9,A5,F6,41,26,21,0B,10,54,B6,69,76,2B,DC,CC,01,11,43,C7,D5,9F,F7,61,67,1B,B0,65,E0,9F,11,F5,5C,4A,BC,D4,C7,7F,8F,DF,F5,3A,D8,58,AF,7B,D0,B3,32,7F,BC,0E,B2,7C,CB,47,AE,47,5F,D6,61,1D,20,5C,27,6D,DE,1B,56,4D,82,02,05,1A,93,87,F4,BB,81,B3,99,9A,31,8B,EF,B1,82,28,57,5B,5B,42,12,83,D9,6A,99,C4,21,2C,64,E8,D3,28,7A,5C,97,9D,BE,D8,62,E2,02,D5,ED,64,29,B0,AB,D8,8E,94,10,28,B5,B3,C6,EF,7C,54,CF,72,54,4A,70,B4,70,3E,92,9A,FB,49,59,62,19,4C,B4,A9,2A,79,F5,62,40,5C,B6,B6,A1,2F,66,15,50,21,D0,2F,9B,22,94,84,40,30,8F,25,66,8A,2E,30,56,6D,C8,DA,8F,3A,BC,90,90,49,BA,B9,A5,D8,C7,8A,72,46,A6,54,5F,D0,1E,DB,B4,13,72,12,3D,48,18,A2,4D,C8,CE,52,D5,6A,87,9C,B6,62,13,46,31,B5,7D,37,09,0F,B1,3A,41,7C,EC,36,19,5F,51,0D,23,52,6C,54,B9,83,59,84,E1,67,B8,91,39,2C,A2,D9,3D,E9,F8,26,69,9C,02,77,E8,59,53,E0,D6,2D,2B,D4,59,43,23,DA,8C,89,A5,1F,D0,AE,44,A7,01,A8,94,4B,CC,E3,17,A4,B1,26,4F,5E,B3,35,FC,31,3B,67,DD,52,4C,42,D7,05,05,5A,97,3C,90,83,AD,2C,E1,AD,23,9B,59,76,F8,A2,1D,FF,C6,4A,ED,01,62,E5,5D,9E,10,14,69,E2,30,0B,34,5A,20,89,7C,C3,AF,32,F7,D0,B1,7A,D9,65,4C,FF,72,C7,E9,01,82,EA,A2,2F,69,AF,AD,93,C4,D7,AA,69,CE,43,AE,4E,3D,62,25,76,E2,69,43,A7,7E,7B,6D,29,00,9C,0A,7E,1B,02,09,42,7D,DA,E9,B2,E3,FD,EA,19,86,DE,32,1B,32,C4,E6,34,FC,DA,98,29,16,C2,31,9D,21,EA,96,0F,1B,AB,A3,6F,84,25,FB,AD,AF,C4,B0,1C,5A,99,A6,06,52,58,B9,A6,08,0B,FA,05,1F,41,79,73,40,B1,C8,00,24,C1,BA,43,E6,94,6F,7C,14,96,85,51,75,ED,D9,FB,A5,66,48,0B,87,05,86,AE,41,2A,38,62,54,83,78,B2,2C,84,F1,F4,47,08,8F,9D,E2,38,3E,C7,2B,84,2F,62,10,0B,F4,B1,52,21,C2,5E,57,8E,14,B2,49,BF,30,C0,57,9A,51,E0,A9,E7,81,46,04,C5,39,E3,7F,45,56,D8,E6,B5,A0,12,D6,9B,7E,00,10,FB,47,C1,CE,DC,53,AF,97,1C,44,EC,F2,69,64,47,EB,EC,BF,53,4D,AD,34,2A,50,98,1D,C1,56,24,BB,74,73,33,90,D9,AA,CE,09,1B,A4,F1,75,BA,00,A3,CB,9E,29,52,E5,53,57,B1,30,CA,0B,8B,1C,78,9E,AA,D4,E6,9E,7F,54,91,87,35,CC,68,BF,B0,21,9B,52,77,84,98,9D,B6,D4,49,73,C6,44,4E,BC,49,91,7E,85,F5,A4,4B,31,05,79,AD,65,E8,D2,3B,F6,0D,94,61,83,E0,B0,C7,22,BC,69,DA,2A,56,D9,B8,19,5B,CF,FE,C7,6F,9B,49,8D,CD,27,A3,41,36,92,34,4B,81,1C,CC,FA,33,B4,C1,EB,41,41,E9,03,A4,7A,27,CE,B7,A7,87,EA,AD,F8,E9,05,3A,6D,F6,C1,F6,82,A9,0B,39,14,F1,7D,90,32,CA,AA,64,2C,A5,5A,6F,BB,1A,F5,16,47,6B,96,DD,FA,2F,B3,BE,D3,0F,F4,66,CC,49,CC,58,04,7F,59,20,71,1C,56,83,E1,34,07,4B,04,FB,CB,1B,70,0D,4A,6B,29,F2,AE,C4,C5,19,85,33,72,1B,06,AE,C9,DA,99,D8,6B,25,CE,E9,65,BA,00,85,84,7C,3E,CC,E2,FB,A2,4E,C4,27,9F,86,4F,04,46,07,2E,54,57,F3,D6,D7,49,02,48,F2,7F,28,16,F1,54,1C,37,A8,70,76,63,18,FD,C8,EE,12,04,16,43,7B,D9,8B,3C,11,26,BF,C2,8E,AB,29,7F,A5,D9,33,D6,B0,EB,F3,AA,5E,99,B0,9C,B7,52,E5,1D,D8,A2,AE,23,ED,EA,1E,18,1A,55,5D,F0,EE,36,05,D4,67,FD,17,20,28,1E,FF,87,D0,49,B8,2F,E5,51,5F,4F,52,F8,D3,F9,66,B3,0B,8D,6D,B7,49,3E,C4,D0,B2,3C,1B,6C,EE,20,D1,6A,A1,7D,9A,F0,34,AC,9C,EF,18,95,4B,79,8E,58,78,06,A8,44,39,64,65,31,9E,5E,34,71,2F,23,D3,C3,E0,63,63,EE,FD,AD,CE,4F,0C,80,DD,D4,AF,F1,BD,81,D7,0B,6C,2D,85,F7,10,A8,EB,14,1D,3B,71,2C,97,65,EF,27,22,CB,AC,14,5F,E1,71,E9,0B,3C,BB,00,48,5B,51,D9,75,83,7D,5C,CA,5C,D0,C3,41,A6,CB,C3,1F,8C,51,F2,20,99,13,81,92,41,17,4B,F1,07,68,4D,7A,B1,00,7E,51,50,16,3A,32,E7,DE,B0,60,CB,06,7E,CE,2D,B2,70,0F,81,78,E5,7B,C7,48,59,24,B2,59,44,85,29,A0,B4,2B,E2,A6,C0,BC,70,4A,3B,DB,C6,D4,FC,D9,90,11,F9,F1,6B,E4,0F,82,F6,E3,A9,6D,64,34,81,6B,12,36,57,6A,50,50,3E,19,14,9A,DD,07,A0,44,2C,6F,1B,F8,23,82,F5,23,73,C5,8C,6F,E4,E6,4E,E2,E3,32,37,C4,9A,78,3C,8F,F8,DF,4E,55,DC,E8,BC,98,9F,8A,93,51,D4,F0,7A,5A,70,2A,FE,48,06,06,BB,88,C2,BA,D5,8D,4D,B9,51,EB,17,04,47,A8,3B,E9,1F,55,C0,EB,5C,89,8F,77,DA,E2,17,A5,65,A7,6E,A2,80,AF,9C,D1,16,05,79,58,19,C6,E3,8C,DE,7E,B9,14,2F,3E,E0,13,F7,8A,69,13,D2,F0,09,DD,0C,3B,51,6D,0E,65,2F,58,F0,EC,7E,B0,4D,5C,62,4B,DA,5C,F6,D1,3C,41,56,69,E2,8D,2E,D7,20,AA,C6,D5,00,AE,85,D7,87,25,1D,0C,84,E7,49,60,0D,F8,3F,C8,CC,23,98,26,32,49,BD,24,52,65,98,E5,5D,4E,C0,27,97,26,D3,51,37,D0,CB,B4,2C,5A,03,FE,B5,6F,B4,FE,C4,43,B7,10,A4,A6,94,1B,D9,18,11,24,0F,FA,68,92,F9,D6,58,02,97,CD,09,27,28,17,7A,59,D4,52,95,A4,03,C0,B4,EB,5A,35,12,0D,60,4A,5B,CE,31,D3,85,78,F3,F0,0B,12,B6,97,E4,B7,16,ED,ED,EA,11,DE,09,E4,87,ED,50,BD,48,7F,0D,07,6E,21,22,76,12,47,02,00,A4,10,D1,0F,5D,0C,1E,7F,18,B9,0B,50,16,EF,C3,11,09,0F,D7,20,AF,58,51,F0,88,49,47,92,AB,0E,06,F2,84,9A,B3,17,79,A8,60,EF,AF,D6,79,80,DB,EE,42,CE,6C,58,74,E4,08,BD,74,4D,3C,B7,F7,5B,4F,CF,B9,B3,49,09,2D,61,17,96,50,D2,E9,E3,EA,F8,3B,2C,52,AE,C7,56,46,E4,CF,09,F4,D8,C1,46,4E,3D,B2,CB,7C,92,8C,A5,01,D3,91,9D,09,F0,32,B7,6C,57,C1,F8,25,B9,BA,49,86,C2,39,FD,60,CB,F4,2A,C9,CD,08,54,15,22,94,03,8A,7B,5E,26,17,70,8E,D0,27,54,3C,CB,F6,D5,43,00,98,83,62,CA,EB,53,52,F0,B4,81,29,B7,4B,EF,74,11,23,7A,FB,9F,DD,0E,E6,64,F1,80,1E,42,5C,9A,11,A9,CC,D3,3E,5D,0A,34,50,E7,F7,80,D1,E8,C9,AC,A3,6A,70,D0,7E,53,A9,BF,28,CA,FF,9E,AD,55,83,FC,C0,C5,CB,97,0D,4C,13,89,01,A3,EF,3A,73,87,7E,2E,44,D7,18,5C,AE,9C,FF,AF,82,D1,74,13,4C,81,4D,1F,91,F6,14,73,80,7D,B3,11,DC,00,D1,6E,97,41,51,0E,43,06,DE,4F,E4,E9,E6,1C,D5,58,8F,9C,53,7F,FA,84,1A,6E,E8,45,0E,EA,09,A7,AB,F3,E5,1C,86,9E,18,CC,DE,C0,92,B3,A9,C6,2A,90,9C,E6,87,41,70,B8,1D,B8,AF,9D,8E,07,89,B1,81,45,42,63,47,9B,B3,C0,99,A8,C2,3D,B5,04,14,43,07,6D,63,6C,10,06,8E,DE,ED,33,0F,C6,D8,46,55,1F,43,F9,F7,88,C7,16,0F,1A,22,E3,12,92,01,32,3E,9A,26,F8,54,DA,59,70,52,E2,F2,B2,21,54,1B,CB,F5,26,61,69,D7,CF,93,46,7E,63,5A,CC,BD,29,97,FD,6A,49,27,72,74,A4,D1,AF,D3,1B,E0,B5,0F,25,43,89,71,D4,0D,46,D7,25,F8,11,C2,5C,92,32,08,00,37,18,AC,62,30,01,91,A3,20,E1,42,9C,8F,BD,46,39,DE,51,42,AE,B5,D4,4B,74,40,62,88,BD,5A,29,B9,DB,98,78,FD,3C,E7,9F,20,AE,7F,45,C3,7B,2D,E5,D7,D4,A0,BC,4F,D4,65,FC,0B,80,8F,86,9B,FC,21,E5,3E,79,57,A2,D6,E0,98,46,84,48,F8,36,B9,D8,43,DB,29,DE,15,53,EB,41,77,BB,F8,A0,A9,6B,A7,89,FD,FD,B5,E5,24,B0,B7,68,98,15,6F,09,0E,21,8C,99,73,16,B9,C3,C5,E6,DA,4F,F0,F2,13,20,D9,A3,56,30,23,F7,86,84,63,ED,42,A4,FE,AF,6C,E7,5F,50,1B,B4,43,AE,45,FE,B6,72,F3,DC,4D,68,CE,AA,D5,AD,77,13,74,A7,5D,78,34,4C,CD,81,2B,16,01,E0,A6,91,0F,B2,B3,CD,D0,FF,07,46,A0,1E,1A,C6,30,AE,49,BC,51,CE,30,CA,B9,AB,8E,BB,FB,A7,40,54,6E,FA,FF,3C,2B,16,83,31,1A,80,41,28,C2,22,73,D9,BA,3A,82,65,87,15,C5,18,FD,0C,D5,44,D1,21,E1,C4,F1,F3,8D,A8,C1,56,EA,08,1F,EE,C0,35,D3,65,0F,BF,45,4A,18,4D,95,B9,40,14,E1,12,7A,4C,01,1F,E4,06,38,24,46,49,31,FB,6A,84,B2,5F,8A,FB,56,D1,51,5E,30,02,B6,50,3E,CB,C9,04,05,F1,3A,84,C3,46,20,C4,08,1A,D8,73,63,BB,C6,D2,9A,E3,EB,58,CE,76,D3,F1,F1,81,3A,C3,47,AE,20,58,34,1F,E8,4F,76,B1,17,AA,42,DC,8E,24,4E,28,34,C2,9C,1C,87,ED,01,25,30,B3,02,F7,AF,8C,5B,E1,F2,8D,86,EB,F7,0C,44,E6,2E,11,B6,45,A9,FD,0E,10,37,F8,8C,05,99,A7,4F,7E,98,6B,BE,21,D8,A6,EE,F9,3F,CE,A9,AB,FF,42,4F,AB,A6,F7,3D,25,82,F1,B5,23,0E,CA,C6,98,6A,02,18,3F,93,12,02,B4,70,D9,3A,BB,98,C1,A0,5E,B0,27,54,9B,69,06,FE,F1,67,68,99,84,2C,62,75,56,34,08,0B,C8,7B,DD,49,8A,14,75,A7,75,42,D2,36,A0,A9,98,7A,18,07,34,61,0A,A4,72,6F,05,2C,76,06,84,FC,5F,86,85,EC,DB,C9,CD,99,5B,02,22,39,19,10,54,A5,F9,BF,0D,D0,EA,49,20,15,01,4D,0E,AE,53,B7,DE,B4,29,87,D5,54,FF,9D,CC,96,3A,18,D0,7F,25,83,D8,0E,C0,A7,D9,50,5F,05,9A,AC,EA,4B,BB,24,66,46,39,C8,F6,9C,2A,D8,2C,29,42,D4,A9,22,C1,B6,AB,FD,E6,33,D8,B4,97,23,64,63,2E,7C,4E,24,16,27,30,96,58,63,D3,83,E7,51,48,9C,35,8B,EC,F6,47,6D,87,A5,6B,9D,6F,6C,49,35,B9,36,00,3A,9D,A9,E1,56,AB,8D,11,CF,3B,65,48,12,3F,12,84,B9,21,81,04,CE,BC,4A,DB,90,EC,D7,B9,F3,BD,4C,61,B3,EE,F3,54,AA,03,AE,10,8F,9F,21,48,CF,F3,2D,C3,6A,53,A3,94,FA,82,EC,2B,78,97,8D,41,04,2E,8B,76,C3,D4,46,26,74,E3,04,B5,B8,2A,60,B2,F7,AD,45,62,DE,3D,EA,38,81,EA,07,C8,A9,99,72,C3,D4,DA,CD,94,DF,E5,9C,10,B2,0A,94,BE,51,E2,D0,3C,18,93,40,DD,74,64,8E,92,4F,2C,35,40,41,84,76,EC,15,40,E7,76,BE,FD,AB,15,B1,53,49,8D,23,5C,C1,D0,50,DF,A5,0A,26,E7,62,D6,C8,EA,19,D2,D9,9B,9B,A0,BF,49,CA,90,2C,BD,9B,F0,77,FA,FB,C9,2E,EA,78,11,80,5D,E3,7C,93,E0,CE,44,5A,BE,A9,D1,0A,7B,8E,BD,0C,C0,28,31,AF,B6,E9,68,3C,21,2A,CE,8C,28,E4,10,A4,CB,E9,7D,1C,89,E7,69,BE,75,AE,67,BB,B5,C6,20,71,1A,4E,98,43,4B,DD,95,F8,BD,AB,91,9E,6E,19,0A,26,5E,22,46,D6,6A,E3,19,DB,31,5B,9C,C2,19,E0,48,59,27,F7,B1,0F,5A,91,91,84,A3,36,18,DF,90,8B,AC,34,0A,C8,87,C8,EC,D4,AD,50,9B,CD,65,B5,4D,E7,4F,4C,82,39,C9,BC,93,60,83,3A,98,EF,4D,DF,70,10,71,10,FE,33,79,08,72,68,AD,27,FE,C8,57,63,C3,0A,B8,6D,4E,BC,B4,50,57,AE,6D,8D,F8,1E,DB,A4,F9,9B,9A,1B,35,E0,3F,B8,9A,90,A8,D6,A4,35,0F,6D,03,7C,32,5D,48,1F,51,4C,21,8B,47,26,D2,88,09,BA,54,4D,73,48,0E,DA,6C,A0,37,F7,71,92,48,8E,1B,52,D7,13,B4,B9,04,F2,7E,60,E4,35,29,C7,B1,C1,5F,6A,74,6F,D8,8C,EB,C7,0B,E3,0A,91,5F,23,30,FA,6D,E8,86,19,02,EF,9A,FA,CB,65,91,3E,E6,75,51,07,6B,B8,0E,73,52,CC,F1,55,2D,35,F1,F0,56,A0,D3,B3,0F,F1,F9,8B,6E,1A,9B,AD,A3,6D,01,D7,22,47,10,84,91,AC,09,0E,46,43,0C,2D,24,AC,C5,4D,7C,CF,FB,B7,14,02,0A,68,01,C7,69,A9,D0,8C,1F,8F,D7,ED,3E,A3,1C,AC,E8,20,11,F4,C9,D2,9E,04,85,CD,8B,E2,B8,FB,3F,4A,A1,51,BC,1F,D0,97,7F,C1,A1,85,05,56,13,59,D4,DA,EC,51,B4,24,E2,58,07,28,8A,C7,FC,CA,7F,E2,EB,0D,A7,8D,2E,DA,F7,81,AD,E1,E5,60,95,8C,06,8E,58,DA,B3,39,03,CC,49,01,4E,69,C6,A4,79,01,62,2A,3F,24,F7,0B,BD,3C,40,1F,63,C1,EB,8E,5E,C1,A8,A6,A8,60,4C,FD,EC,05,AE,45,1E,E1,8F,FC,2E,85,4F,AF,39,94,60,50,F2,D0,02,FB,9E,37,37,7C,DD,04,8B,D2,44,FD,C9,0B,D6,76,39,71,DC,B7,AA,49,3B,B0,F9,E0,7B,B9,26,B3,A1,E8,07,82,24,26,6D,5A,32,6C,60,D6,C4,5C,B2,4D,3D,9E,09,3B,D4,0E,14,5D,8E,71,C7,07,35,11,A2,1C,7A,EF,66,17,51,FA,07,1D,54,75,6D,81,3D,B9,C3,AA,87,9E,4D,8A,6B,CD,3D,F0,F1,69,47,0B,2F,8F,68,FA,2E,4C,85,A3,66,DF,DB,17,E0,FB,9E,8B,05,CC,BA,CC,51,45,47,65,3C,8E,7C,BE,32,5D,B5,7D,99,72,6F,8A,9E,DA,72,35,9B,C1,B3,FF,6B,33,DE,7F,C5,B5,E9,4B,4B,19,F8,55,86,D9,7A,0D,EE,92,25,17,2D,F2,C2,07,BD,94,82,36,54,8D,95,46,EC,0E,A6,FA,55,44,88,BD,49,62,0F,A9,81,1C,BD,77,01,C8,EC,5A,9B,E0,89,6A,1F,2A,6B,1D,90,68,DF,58,76,A9,39,CC,A3,F8,E0,40,92,F1,D7,C1,CE,59,CE,CF,89,6B,B2,6A,A8,D8,EE,3F,4A,C2,23,6A,72,34,EA,8C,18,52,09,C9,D5,51,E7,86,22,32,64,5D,AA,4F,B1,3A,65,AB,AD,0F,3A,73,43,6C,93,AE,76,C2,03,38,61,60,8C,6E,DF,BF,98,3E,61,5F,C7,DD,D9,DD,8B,B3,8D,50,37,23,C3,1D,6F,E2,CE,4B,C3,B9,69,35,50,43,27,F8,A8,CB,FE,F0,8E,2D,84,26,45,D1,D5,C2,63,08,68,2E,9B,1F,50,9E,F7,7D,2B,58,D8,A2,EE,77,52,38,E0,7E,C5,D3,15,33,55,74,B8,7C,66,04,33,26,FD,EE,8E,81,CE,97,C2,82,EA,B3,D5,6C,BF,E6,CB,48,9F,C7,17,24,41,5E,AE,27,B6,BA,06,38,01,CE,9B,3B,12,99,9E,66,7B,10,74,7E,85,63,2F,01,3E,11,4F,C1,7C,96,7F,92,F9,6E,9D,F9,54,8B,79,33,FD,4B,E5,CB,48,4C,E2,0F,44,6B,1A,EF,A9,5E,BE,06,A2,8A,14,8A,73,A5,7C,FF,56,4C,A9,B1,98,FF,60,94,24,2E,8C,54,82,75,11,7A,C8,0E,44,CA,DD,2E,5F,CE,CB,B7,37,78,47,51,54,EA,00,EC,DE,15,67,04,ED,84,03,97,CB,F9,4B,FA,98,8F,B6,AF,A3,9F,8A,F8,15,75,B0,34,F8,20,80,05,BB,9A,C5,44,B4,33,2F,1E,10,2B,96,10,76,2C,F9,A7,0C,C0,0F,52,22,08,F8,9C,8A,4E,E5,10,88,57,41,DE,15,1A,B0,65,99,5D,0C,4C,68,FF,E3,43,01,A9,6F,0E,F4,58,AF,99,A0,88,56,08,95,21,C7,EC,A4,B9,6F,94,50,37,EA,AA,A8,D4,F4,01,71,9E,60,30,FD,40,D7,91,DE,29,EE,76,A4,E9,34,A8,53,2B,E1,7F,C9,02,47,B9,B1,0E,C0,23,1C,E8,DF,10,5F,38,45,84,F1,04,FC,E2,B8,B0,8C,D9,4B,96,55,69,CC,30,05,2B,26,71,0C,8D,E4,CD,1F,24,10,81,98,57,7D,44,C5,DB,26,5C,76,E1,C0,08,1E,A4,FF,4E,54,ED,5A,17,C1,C5,11,F7,67,54,DB,F1,12,7D,20,7C,FA,C3,1A,E3,A9,00,D1,68,E9,82,31,ED,29,58,6D,01,61,35,78,79,AD,AD,79,C0,E2,7E,7F,43,22,85,39,EE,8D,0D,BB,67,D4,5D,94,BB,27,69,C5,16,88,D1,5D,08,5F,6F,B8,23,08,21,DE,5D,EB,74,69,61,F4,D5,3B,E3,DB,5C,27,3C,E0,50,E3,68,E1,E5,86,24,05,C0,D9,0F,FB,18,9C,60,8F,C2,04,71,1B,88,53,78,79,FA,13,1E,2C,2B,7C,BE,19,39,3D,61,09,DA,9A,45,CF,E4,07,93,25,99,12,13,E7,7A,3B,13,FA,29,22,66,B4,65,71,6F,DC,9D,85,67,2B,A9,43,2E,36,96,94,72,61,FB,60,44,AD,48,64,B3,91,30,84,21,46,61,04,0B,90,14,39,F0,A9,A3,99,6E,D9,30,17,7A,CA,7D,9F,36,CD,22,25,55,D8,93,64,78,C2,B5,F3,1A,C2,7A,6F,8D,9E,19,55,4C,8D,F2,FE,2F,89,3E,FF,E0,25,11,82,AB,8B,97,4A,E8,9E,D8,CF,6E,19,8A,F7,32,2C,27,52,FE,72,EE,06,09,01,D5,8E,64,41,6E,84,43,70,62,13,05,17,1A,02,5B,80,FE,39,97,36,6B,5F,EE,7B,17,88,1A,09,A4,B8,6D,FD,3A,69,12,0A,93,63,34,1B,9E,BC,A6,6D,F4,4C,7C,38,7D,55,83,B2,59,C4,3A,DA,47,F9,4D,93,D3,22,B2,AF,6E,16,7F,B4,00,EB,8F,53,65,B5,BA,44,BF,8C,8D,0C,51,0E,9B,DB,8B,7A,9D,5A,3F,9D,9D,2A,DB,46,DC,AF,AB,65,96,6D,F9,53,A1,AB,CB,0F,AF,CE,AE,5B,18,EB,3C,96,D7,CD,D1,EC,CE,8E,D8,7C,F6,81,E1,39,96,69,7D,6B,15,98,9E,7E,8C,6A,0E,71,DA,B2,45,7C,0B,46,9B,4F,DB,DE,AC,33,83,05,47,F3,03,CC,74,43,04,36,10,D5,B7,E3,3D,AE,87,79,3E,10,30,AD,46,43,24,27,AD,BB,A5,CD,58,A9,30,D7,74,2F,59,11,C7,4A,2A,A0,5C,5D,D1,01,7B,D7,63,CA,1C,4B,E2,15,B1,27,07,57,73,AD,80,6A,E5,7F,C1,C4,26,56,24,8B,FF,53,2C,3A,CB,19,C7,41,9C,40,11,19,23,5E,2D,89,EF,72,F8,69,80,BD,31,74,DF,BC,57,5E,EA,9A,3C,73,96,74,88,9C,6F,48,DB,4D,05,2F,60,A4,87,30,E2,E8,95,A5,D5,12,EF,F6,D8,67,41,7D,75,DA,A6,52,14,79,2E,1B,08,F7,BB,81,EF,6C,B7,29,49,60,68,F1,8F,71,69,36,BA,9B,20,7B,C8,EC,B8,96,F7,92,C5,39,F5,FC,F5,EB,7C,F4,1B,C9,64,28,45,29,F9,FB,51,46,16,32,51,1D,47,47,60,2E,9C,64,00,E7,37,5A,E2,BB,4A,AB,CA,51,CE,F3,1E,1C,41,0A,F6,32,41,E9,CB,54,9C,6C,DA,27,EA,4F,20,84,E6,44,38,41,A5,6A,49,87,04,F3,38,87,7E,02,DF,A1,64,A2,9A,E8,47,9F,1E,C9,AF,0D,C4,F3,79,3D,02,E1,4C,44,7C,AF,04,EF,C2,F4,13,D5,B7,7F,4C,86,BD,08,9C,CE,B4,24,74,6F,81,7E,5B,B1,15,EF,68,90,7F,28,61,59,AD,C5,ED,5E,94,FC,D0,4C,0B,D1,F5,B4,21,B1,0B,42,5C,BE,12,29,AE,C5,D7,B0,C5,85,44,9F,24,F1,D3,1F,0C,3E,DF,94,E1,47,0F,AC,D3,24,67,A5,A3,7B,AB,05,BC,43,29,B4,C4,3D,55,CB,B0,F2,C3,41,F6,25,96,12,76,90,4A,C7,77,40,14,C9,DA,24,FE,D4,21,C7,15,AD,C7,33,AC,52,E8,2E,BB,08,44,08,DB,F3,2B,B2,4D,42,0E,25,06,64,86,32,6D,D6,AA,13,81,34,39,E2,AC,53,32,B4,37,66,BA,25,03,C5,C8,9F,51,D1,F1,64,CA,4C,48,0B,25,17,C8,E2,02,C9,6D,BF,F3,8A,18,87,6F,E5,93,C6,A6,70,6B,D1,F7,55,7C,E9,0C,D9,63,97,02,F9,18,61,A4,E3,22,1C,26,19,CE,D5,8C,EE,A9,FB,44,4E,D5,3A,F7,E7,8B,C6,3B,3D,E6,30,D6,90,54,CC,3A,C2,49,56,76,BC,77,2D,B7,C6,73,67,96,29,9F,FE,A3,05,67,4A,1B,53,2A,F6,73,8C,8C,ED,D8,DA,93,8F,06,AA,36,23,B9,73,BE,02,39,D2,53,FE,EB,08,CA,9D,19,96,14,70,AF,EF,0A,CD,CD,4F,F8,11,D1,68,2D,CE,27,9A,6B,2B,89,EB,64,7B,EA,BE,AD,48,1A,6A,91,F2,20,22,AC,A0,C0,6A,E6,D8,64,7F,19,5E,5E,17,9B,DB,67,74,01,FF,0D,9F,E9,E6,A2,A4,23,C5,EC,98,95,3B,22,BD,68,20,63,B9,52,AF,68,6B,8D,BC,38,6C,63,DE,8B,4F,DD,91,57,DB,08,12,21,7B,E1,91,D3,B7,04,EF,53,FC,E5,D3,CA,E7,B6,CE,C8,94,29,10,5B,A3,9F,84,9F,0D,35,DE,6A,E2,B1,D8,C5,FE,0E,FD,5F,B2,07,D6,5A,84,E7,5E,74,7E,3D,9A,3C,24,AB,43,40,2A,FE,FD,05,D1,0F,7E,87,A1,7E,70,55,C8,E5,59,E5,CC,DC,D1,BE,B7,07,E7,56,98,C2,71,09,46,65,59,0F,BA,D8,17,A4,0B,94,CD,43,44,F0,52,0C,C3,2A,D5,D1,E2,B9,5B,03,B9,68,3B,6C,AD,0A,D4,FA,05,F4,01,B5,0C,79,CF,0C,78,B3,78,A9,BA,B5,CB,B4,E6,9F,DC,44,1F,E1,CD,E0,C6,26,1F,C0,A0,83,1E,8F,45,29,8C,64,B0,AD,AC,FA,94,1A,3F,84,3E,EA,33,61,F4,73,1A,CB,7F,7B,B7,AC,DC,94,D5,EC,FA,CC,92,C3,ED,EB,50,25,08,0F,7A,A9,EF,89,D4,94,5B,AB,84,D4,8C,98,64,E9,42,A5,C1,10,2A,48,5F,D1,C5,5B,21,A4,7C,2C,1D,3E,0B,B7,54,EE,54,54,3E,89,30,9C,C8,7B,30,22,5A,EC,C6,EC,FE,6F,B0,93,1E,FD,31,DA,4B,AC,22,B6,C0,73,72,93,C2,6D,40,D5,9E,9B,0E,5B,8E,38,0E,A1,AC,39,B6,E7,30,74,09,3E,D0,B1,FA,70,04,AF,8E,C0,81,92,C4,C1,92,EE,49,F2,94,BB,7C,DC,7B,A5,85,31,8E,F3,94,E6,79,46,AB,57,B2,59,43,C9,BC,0D,79,C9,59,86,BB,05,B8,F1,E5,9F,7F,CA,BC,DA,C8,CF,11,2B,EA,EF,5E,35,54,37,18,4B,96,8C,BD,0E,C4,9B,5B,12,30,B2,A3,32,AC,2E,C5,5A,42,87,1C,1A,A2,27,66,F9,7E,2D,02,1A,30,44,22,50,51,84,D0,08,E3,4F,7F,99,0A,CE,78,52,0C,BA,5F,9F,5F,96,8F,71,46,13,CA,7F,4F,06,C9,94,A4,58,0F,37,EA,46,4E,48,41,D2,6E,9B,BB,C2,71,10,51,5F,1C,76,07,F0,FF,FA,41,9D,6F,DE,ED,29,82,A4,69,54,1E,A0,95,1E,E1,9D,DA,8F,11,15,20,6E,0E,C3,BE,17,7E,F2,3F,65,90,A5,E1,E5,C1,4E,72,AB,25,A4,50,14,2A,70,0D,5F,5D,FA,E6,23,21,91,42,10,7E,33,EB,8C,66,01,62,C0,59,E4,2D,19,9C,5C,9E,2B,B1,6B,1A,FC,69,92,0B,D3,B3,1F,61,38,12,19,32,C3,2A,14,D1,75,63,8A,49,E0,19,78,D8,84,DC,71,44,D7,34,D9,D5,69,32,FD,23,F1,2E,10,1E,BC,76,0A,AB,33,4E,22,23,A3,55,46,43,79,96,B4,F0,05,3D,E7,73,0B,14,9A,3A,00,01,5C,7E,78,C2,19,17,C6,E2,28,9F,57,1E,73,39,4F,63,BE,02,E0,E2,AD,2C,60,44,78,D7,6B,CD,03,C6,AB,0D,7B,9C,16,AA,D0,69,44,9F,0C,F8,6B,DD,B2,AF,6B,E1,D8,D2,5E,EC,ED,D6,6F,FC,AA,9F,8F,AA,64,4D,32,94,39,7A,6A,A7,4C,CF,E9,B9,C1,09,90,61,7F,39,7E,1E,6A,65,9B,32,A1,A1,FD,4B,23,87,2D,AE,70,45,C7,0D,54,E8,D9,DF,E4,66,1C,ED,2E,CA,7A,91,3A,9F,62,AF,F4,A3,E1,FD,65,52,99,5D,1A,AA,04,55,01,4A,EF,F6,28,2B,47,8A,D9,13,7D,25,75,9C,D0,C8,FA,54,62,47,86,96,ED,8F,3B,38,BB,DD,32,C0,50,4C,E8,E9,F7,2F,28,47,B0,97,96,0C,74,22,4B,3A,96,D4,80,93,AB,30,AB,5B,3D,A9,E9,EC,BB,AA,9B,B5,50,17,37,50,AC,A9,0F,B0,EC,06,23,F3,1B,89,35,11,86,4C,17,5E,10,A1,B9,03,1B,98,52,D9,D0,A6,E7,58,25,41,CA,D3,84,A2,A8,3C,15,5A,D3,EF,3B,2F,EF,66,30,1D,9C,C5,DD,AF,92,1B,70,C9,96,24,25,4C,2B,10,35,91,AD,97,39,05,06,CB,D6,E5,88,0A,37,B2,91,D0,67,35,7F,B5,9C,48,86,DE,D8,D5,8B,D5,AD,2D,66,3E,3E,6B,30,26,02,7A,7F,EC,AF,1B,33,32,41,82,BE,03,19,42,CD,59,98,02,19,41,07,A3,48,E4,9A,34,61,AE,E2,21,6E,19,42,F2,AA,3B,42,1B,75,B6,C5,82,E5,E3,83,47,21,B0,5C,9C,79,35,20,24,C5,9A,EB,B8,23,84,CF,CC,2F,58,02,9E,97,20,FB,04,76,DA,6F,57,15,8A,34,1F,5F,39,12,D2,E7,89,70,CA,8A,90,9D,DC,47,5A,C6,80,8F,8D,97,4E,FD,C0,E4,64,FA,EA,70,56,8C,2F,81,41,1D,BD,7A,41,68,58,56,85,4A,C3,83,3E,AF,EC,8B,CE,28,7B,CE,47,0B,B7,DD,4B,3D,12,07,89,89,76,95,BC,75,C8,E8,13,C9,DA,4C,FB,FC,30,16,EF,D7,CE,0A,9B,64,56,18,D4,B0,CD,34,D1,F3,82,F0,33,95,65,B0,73,93,23,C2,89,DC,10,1A,14,87,7A,72,08,B3,2D,BE,29,4A,E1,59,3D,85,1B,57,87,E0,50,8B,D2,0B,8D,C7,0B,84,FF,9C,BA,35,3C,ED,11,B4,C6,38,D8,39,70,1F,BE,0D,E9,0C,FB,92,40,39,48,56,AB,0C,DC,02,3C,6B,D2,A4,C6,16,5A,08,2F,48,E2,83,29,4C,A0,63,AB,3D,D7,FD,09,68,63,5C,93,39,2B,84,23,C3,D0,D7,32,27,0D,B1,A4,05,73,8D,11,E4,E8,8E,BF,40,E2,06,B5,3A,7D,0B,B8,B3,3C,7F,CE,DB,A9,74,41,89,A3,AA,8A,3E,43,4D,98,1F,16,AF,4C,21,80,5D,8B,CB,FD,46,B7,51,5D,A2,94,25,24,8E,31,D5,02,05,9D,FE,09,FC,F2,F3,61,AE,33,DD,BD,D2,CA,0C,83,E7,2E,47,E7,FB,CF,23,5B,7A,6E,4A,81,9B,92,37,BB,B8,06,19,9D,CD,C5,5B,58,F1,B4,2F,D4,24,B0,4D,05,38,17,7A,00,EF,73,4F,D0,AA,38,01,5C,9C,9B,D8,62,D6,1E,EC,93,AC,00,67,6F,51,2D,04,A4,CA,EC,FF,79,07,82,61,E6,40,F7,15,76,40,07,89,DF,6F,C4,4F,0C,7D,50,A9,37,B6,3F,91,51,FD,AA,1C,07,BE,C8,DC,0D,C4,3F,69,2A,87,5E,EB,9D,90,5A,03,F8,85,11,37,89,DB,AE,2D,6B,1E,CC,A9,B2,71,26,2B,0E,9B,0E,E8,4F,EB,61,AA,AD,5D,54,F4,B0,41,DF,53,47,26,7C,9A,FE,FA,80,8D,96,6E,D4,36,7C,CF,62,31,B6,97,A8,FE,FB,3A,E5,CC,7A,B7,F6,FC,64,E7,A5,07,41,E3,57,DC,DE,56,7B,05,2B,7C,02,CA,E8,2A,2C,5A,45,64,3C,9D,B6,FA,BC,23,DE,1D,4E,9F,CC,AD,08,04,05,62,86,30,A4,C8,63,38,66,A1,CB,65,48,E7,FC,A2,FB,99,DD,50,EE,7E,30,55,0C,5C,BA,E2,5A,62,56,CE,11,72,6F,8E,F5,AD,E3,FC,DF,69,A4,FF,57,0F,A4,BA,64,51,AE,BA,3C,16,AC,75,54,66,B1,46,12,74,9B,1D,B9,3C,86,7F,82,5F,3A,46,7E,16,7B,B1,01,4B,C0,C1,3F,8A,79,89,BF,A2,7D,F9,EC,F5,B3,43,04,2D,A5,2F,B1,E3,9F,F6,9A,DB,98,15,E5,AC,82,54,50,D0,A8,F2,76,ED,BC,4C,67,8B,8A,6C,13,BA,D6,C8,42,70,4F,A3,49,A5,57,A9,97,E0,92,2D,A8,D1,49,16,0A,1B,9B,52,1C,2D,B5,F7,95,18,09,89,60,6F,7B,79,4F,18,00,92,23,C9,79,B8,BA,71,33,89,E3,90,22,BC,59,41,AE,BC,C9,DC,CE,D0,CC,55,BB,90,AB,D5,BD,73,4A,EB,36,9B,6F,E8,DD,F1,BD,A3,A7,3A,54,84,B2,A4,5C,A9,FB,C2,C9,71,DE,35,5C,F8,FD,BE,60,DD,4E,29,12,0A,E5,D3,CF,5B,D9,F5,F6,3B,E4,B1,88,16,49,8D,FD,73,80,F2,2D,54,AB,A8,F7,F5,E1,99,0F,EA,60,37,F2,4A,0F,07,D6,DC,5D,63,7D,56,FC,CA,61,D1,14,88,4C,0A,D8,30,79,C0,4C,87,D3,42,57,EF,A5,34,B1,79,02,FD,15,B4,FA,52,A3,1A,FC,F9,55,0F,F1,07,60,B3,E5,98,CD,22,72,7D,50,FA,C4,30,B9,16,45,3F,33,9A,1E,4B,ED,F6,0D,8D,7A,1C,57,2A,FA,22,91,D4,F4,10,37,36,CC,27,EB,79,92,77,FF,F2,C8,0F,4A,AA,3E,EB,E0,62,88,38,56,F3,48,5E,0F,2A,98,39,9B,F8,CE,15,63,2C,2F,32,18,F0,C5,EA,52,53,25,DA,37,B3,35,EA,25,AF,C7,0B,8D,43,8B,CF,56,A0,CF,82,24,C4,09,4F,E4,01,B7,DF,26,2D,AA,D3,E7,23,BE,5C,C2,48,7F,0F,95,CB,E0,F9,86,AC,E7,8E,DF,02,AD,78,3C,EA,61,E7,F9,57,C4,7C,62,8B,13,0D,E1,63,12,8F,B5,C9,27,7D,D7,9C,47,C1,AF,AB,1E,6B,13,2D,30,C6,1D,F2,86,DD,02,90,B6,18,27,E7,D2,EC,B3,39,A3,8B,DF,9F,55,8D,50,9E,57,C5,BE,3F,82,D6,B7,9B,EC,5E,21,66,56,7D,C5,6C,89,B5,8C,A4,ED,89,E0,C4,D2,6B,77,29,F1,0C,FA,58,D3,9B,E8,7D,CA,77,BB,82,F3,A7,4F,96,B8,05,45,7D,D4,A0,14,9E,39,98,85,47,E3,13,E8,A1,19,00,96,2B,AF,5E,3F,25,02,2D,F7,FD,F2,36,70,EF,E4,1E,44,91,58,48,A9,3A,97,A6,23,63,4A,AB,46,A0,71,9A,C1,4A,40,67,B0,55,85,90,55,E5,A0,B6,CB,FA,8A,1A,71,C0,56,1F,4D,14,48,1D,E8,E2,0A,3A,30,86,77,6E,74,B9,24,13,87,14,1E,44,40,9D,49,8E,3B,43,E0,55,F4,D3,74,FD,9F,00,E0,77,28,31,6F,98,7A,B8,1E,B6,DC,70,A0,A1,A3,C0,B5,E4,38,F9,56,54,AD,61,94,FE,A0,27,A1,5C,EE,92,D7,7C,A1,70,AA,3C,92,9B,C5,0B,44,A0,B4,A2,2D,7D,9D,EE,11,1B,6C,E3,9F,34,96,FD,92,9E,33,63,D0,13,8A,6A,6D,0C,5D,E4,7A,4A,D6,0B,84,20,B5,73,82,EA,EA,4E,24,64,B3,17,3D,0E,ED,1D,FD,9C,41,4A,54,56,75,D9,AD,2C,CF,2B,67,D9,87,6C,D3,C1,EE,CB,05,A3,35,3C,F9,63,E6,4E,10,55,62,6B,00,EA,2A,1D,FE,C8,AF,DA,EF,F6,D3,A9,9C,BE,36,C6,C1,12,0E,11,EE,38,92,7B,3B,EA,09,1E,96,0A,F4,FB,F8,99,84,0A,2B,EB,CD,1E,7F,CB,49,A9,95,C6,B8,57,2F,78,FB,3B,83,99,F0,9D,8E,67,21,26,60,33,44,EB,58,9E,2F,38,F0,2F,E1,F1,CA,15,96,BB,18,85,43,6C,93,AE,39,EB,D1,E6,98,1C,AA,8A,7D,EB,54,C8,01,E9,62,31,68,90,D5,68,7F,A9,C1,77,B6,1B,10,B0,9B,03,E5,FE,81,3F,DE,CC,38,45,6E,6F,AF,39,1C,D1,95,47,E6,7C,1A,DB,F2,EC,B8,9D,98,BB,7A,AD,FC,0A,2D,32,82,DC,72,DF,DB,9E,76,D4,0E,9E,23,88,F9,A5,AD,13,D8,8D,4B,E0,22,D6,D8,AC,42,9C,AB,2D,D5,9B,50,B8,F8,E9,85,27,91,07,20,ED,4E,CF,76,72,4D,7C,6B,06,58,30,E3,B9,1D,A9,DE,97,B7,0C,43,46,A3,C0,49,69,74,D9,EA,EA,9D,E7,D8,6E,3A,BE,A5,CD,45,1D,29,FE,34,25,8C,5E,07,49,1C,AA,1E,0D,29,1C,0A,84,75,2A,1E,5B,9D,91,3A,99,C4,63,10,FA,7F,4D,85,2A,63,1A,C7,FE,D3,63,72,C9,17,60,B2,D8,FC,AE,4D,80,17,85,91,FC,14,57,2D,EC,F0,4C,F8,6E,E2,94,33,A5,CB,16,45,9D,40,8A,05,BC,C8,E7,6D,9E,50,89,E8,5A,14,05,65,18,1A,1E,AD,69,01,2A,F6,0C,EE,C8,AA,2D,BF,A6,0F,A8,D3,DA,12,3A,76,5D,4A,18,C6,3C,E2,36,9F,62,3C,21,4F,48,12,91,B2,8A,E7,02,9A,F5,56,01,75,C1,5B,2B,6F,A7,A7,FB,B2,58,BC,D1,5F,9D,62,9B,4A,B9,70,69,76,F6,4D,03,C3,9E,DA,02,A3,91,C9,61,59,0B,4A,54,98,0E,89,8D,01,77,BB,F7,B1,9F,A8,37,24,A1,DF,DB,F6,F7,F2,9B,B3,97,CD,5F,65,57,91,5E,99,91,73,0B,B3,A1,B7,45,55,F5,48,DC,86,62,F3,40,1C,54,55,6B,4A,C6,C0,A4,BA,07,6C,2C,B4,D4,5F,01,65,E8,7B,1B,EE,05,8F,40,09,BB,81,86,C8,38,ED,C1,EB,09,43,13,51,CB,AC,90,0B,E2,24,F2,D3,0C,37,14,48,CB,29,37,7F,C5,52,9B,0C,54,1D,DB,F4,91,18,43,1E,51,4F,F7,13,0A,91,FC,35,01,0B,1D,8C,D6,A7,6D,B0,D1,C0,1D,A0,97,95,97,E4,4A,53,46,D7,6F,FF,37,49,76,31,5A,CE,AF,8C,04,91,A6,69,CF,61,77,76,31,7A,7C,76,FF,D6,EB,4B,CF,26,4E,52,EF,1A,B4,C8,39,24,D1,8F,04,A5,AF,28,DB,05,30,A3,C4,A3,23,66,0F,0C,27,2A,42,A1,AA,EF,9A,D2,D5,C0,F2,4C,E8,CD,C9,5A,C0,46,1C,B3,A4,AE,0F,A9,54,19,90,30,76,7A,5B,98,D9,8C,E3,F7,18,5F,18,58,17,71,17,B9,A0,56,C7,ED,74,DB,F9,EF,A3,C1,15,AD,75,47,53,0B,0C,F8,CE,7F,D6,1B,ED,55,38,34,A3,E9,65,1B,BA,B9,85,76,F4,53,C1,7C,18,38,6B,8E,02,39,8F,F2,F4,2B,37,22,5C,E3,58,11,01,EB,CF,CC,81,8B,8E,46,EC,DA,FF,1E,E3,A7,AF,EF,D8,86,46,D2,11,C6,83,8D,F0,F7,A4,E8,BD,85,A3,F3,E1,51,97,0E,BB,08,6F,7F,49,B1,3A,E4,E0,E7,29,06,DA,7C,73,D6,AF,DE,17,DF,D8,AB,D6,0D,97,9F,AB,53,65,54,A1,DE,F0,BD,9D,02,EA,38,2F,FD,7B,56,6F,FC,53,4E,9E,39,37,B7,00,86,61,8B,43,77,3B,7B,6B,CB,79,4D,0A,DF,1D,5F,22,00,35,B6,2E,8C,8A,86,77,14,DB,38,4C,46,83,A5,7B,0D,CB,94,9B,56,3B,DE,9F,BE,B8,9E,F7,63,8C,0F,E9,C4,D9,2C,3B,9E,A3,5C,3F,82,C0,F3,9F,1F,21,A4,21,60,C5,26,FD,B5,70,EE,A8,9E,00,1D,C8,0D,61,D1,15,1B,F2,3E,4B,19,3A,AF,6A,17,93,DC,6D,16,FC,DA,66,CF,BC,72,7E,BD,98,75,E4,3E,FD,42,55,03,72,FC,FE,C1,52,DA,61,87,82,D9,AF,CE,BF,64,EB,08,BD,7A,E8,AC,84,67,98,EE,DF,6F,FC,F1,00,DD,5F,2C,77,90,DE,85,A6,37,FA,09,AD,A5,68,CA,A9,6B,99,F6,9D,A5,B2,2D,32,49,3B,F5,48,96,E5,3A,FB,2D,F7,7E,48,B6,C1,1C,5D,65,CD,73,5E,C8,F8,43,E7,12,50,E4,4C,43,E7,75,04,36,5D,12,95,8E,6B,E5,79,83,3A,60,02,85,08,3E,27,9B,07,92,26,DB,3F,C1,5C,9C,AF,5F,5C,E8,BA,8A,C9,12,87,4F,1C,2A,ED,B0,7C,97,EB,B1,E4,F7,72,FF,A9,FD,53,D0,FB,5A,74,5C,AD,6C,5A,A4,4F,D5,8D,71,DC,04,A9,33,1B,55,5D,2B,28,33,D5,69,56,37,0D,1A,27,27,B9,EE,88,60,22,96,C7,DF,D5,11,1C,64,7D,97,1B,FA,01,74,61,33,3D,25,64,EF,C7,05,42,CD,DC,7E,B2,61,83,1C,64,3B,83,BE,F1,93,E2,02,4B,19,61,6D,E4,3F,63,9D,1E,4D,A4,13,E0,10,40,7B,79,1F,0E,F5,9B,72,25,FD,14,81,43,DC,0A,14,2E,0D,CE,AD,2E,90,D4,AF,D3,97,7E,D5,72,C4,27,2A,91,3C,E6,F8,EC,6A,BF,55,89,0F,6A,2D,C4,E9,32,A1,FB,74,E1,E8,24,14,16,EC,3D,16,E1,7A,2D,FB,2E,87,F6,0C,B6,E6,E3,76,9A,90,40,9A,BB,E4,CB,5D,6A,CF,D6,6A,8B,78,27,50,1D,FA,77,D6,8B,C6,57,32,9B,F7,14,8F,13,E8,B0,A3,75,1E,01,86,00,77,97,3C,D3,23,D8,AB,51,A3,2C,49,11,46,43,49,71,48,9B,B8,E8,E5,89,24,89,F7,1F,7B,77,21,7B,21,D7,62,D6,8B,54,D9,C8,F3,5F,C4,39,28,3B,18,96,80,AB,A5,3C,74,40,60,00,1B,A2,8F,61,01,7D,B7,CE,B5,54,5E,BE,B0,64,CF,CF,B3,E3,66,5C,D4,E7,E5,24,5E,B0,08,C2,0C,82,D3,EF,D7,B0,9A,92,44,2C,A4,D9,8C,CB,67,93,8B,B0,7D,0D,5C,4B,A0,EB,80,FB,55,7E,81,E9,6F,A7,83,D4,F8,E7,CF,6F,8E,DE,02,1D,E8,6A,FE,43,92,C1,DB,1E,1A,43,49,FB,65,3E,A2,3F,76,93,CE,C3,FD,96,F9,17,F8,EA,00,1A,EE,CE,1E,E8,2D,15,45,B3,58,04,60,09,30,72,C8,C2,AC,21,7A,25,25,CF,09,5B,FB,6E,C7,2E,89,FB,C4,F2,CE,F6,E4,8F,AA,BC,A4,09,B8,CF,20,9E,F3,0B,53,8A,0B,07,F9,CB,3E,7D,00,12,B6,A9,3E,93,1F,83,88,87,02,67,D0,C4,64,C9,F9,7F,74,EA,EC,06,E1,47,C5,85,8D,2C,D2,28,A8,FC,75,43,A1,E8,CD,6C,5E,52,21,1B,E5,C2,53,B1,C9,C3,98,7C,F1,03,74,DB,14,83,04,0B,27,F5,F9,37,8B,58,51,86,2B,69,1B,9D,FB,49,59,B6,C8,A4,DD,2C,8C,01,25,71,9C,DD,64,11,95,05,69,2B,95,62,CC,F9,80,0B,C1,C4,9B,46,4E,AA,41,90,70,93,31,B3,7B,6C,ED,47,09,D8,F9,43,7C,FF,39,ED,5B,7D,52,A9,23,9E,C5,DE,3B,0E,A1,0F,3B,53,1A,E1,F7,50,E0,FF,FB,FE,3F,DB,3A,9F,5D,F5,50,92,7D,92,75,32,99,8A,84,B3,D3,45,7B,9F,5B,AF,77,67,12,B5,3E,0E,B1,25,46,CA,15,35,63,99,8C,44,61,1A,64,0E,F2,24,34,12,D7,C4,3C,50,D8,08,1B,F8,75,30,A1,74,E7,5A,36,A1,00,0E,B2,1B,2F,BE,E6,78,3C,F5,05,40,79,D7,DC,4C,1E,5D,E5,92,ED,0C,D6,5C,7E,28,E1,35,EB,EF,8D,ED,E9,17,E3,4E,B1,D5,36,90,01,13,67,37,19,33,FE,EF,3E,6B,AE,06,81,9D,B2,D5,19,39,31,EA,AB,5B,30,E9,C1,C4,A8,0B,A8,A6,F2,EC,54,0D,D6,0F,31,C8,26,6F,EE,93,F5,A2,0C,80,CA,9A,77,F4,C7,C6,86,C7,DB,5C,F2,E0,A0,9C,2C,84,C7,13,BF,16,9E,03,6B,D8,40,8D,85,05,0E,3E,4D,87,FC,67,9B,F3,5F,60,A1,19,AA,DC,9C,04,B0,E5,89,80,AF,B2,5E,C2,16,BB,0D,0E,F5,1D,17,59,DF,01,14,B6,54,8B,F2,13,66,9C,27,49,51,53,CB,6C,A5,9B,3C,B0,4B,43,88,E0,86,12,6C,64,DE,07,4C,20,3B,C7,06,10,90,2A,69,04,CA,9A,CB,09,94,A4,D2,1F,22,A6,5A,1E,28,FB,4F,8D,FE,A1,90,B1,0B,39,29,0D,95,49,F3,5F,CE,BB,08,6D,72,19,56,71,0E,06,29,BE,CB,7C,BE,E9,A1,EB,B0,F4,35,21,40,E7,0B,0B,2B,CE,B8,47,AD,71,D3,27,DD,C5,D5,A1,6E,C3,4A,38,A2,D1,FB,DE,19,9E,B6,C3,A2,33,D7,BC,C1,B7,2C,43,1A,94,04,72,62,AF,75,C9,5A,50,2F,7B,B6,EC,00,03,A0,F2,51,49,56,DF,77,4F,51,C5,D5,CC,3F,57,0C,02,C2,0F,A6,8C,E5,A5,8E,5D,F1,66,9B,B7,F8,55,2B,6A,55,C4,F3,9A,2E,BC,00,7F,A3,EA,1E,83,D4,65,C7,9D,3D,09,91,A6,BF,D1,94,2E,D1,2B,1D,EF,D4,C3,A9,73,F8,E1,4C,AF,6D,5E,E8,22,05,E0,62,B1,10,7F,78,EA,DF,68,08,F7,89,C0,DA,A6,A8,E8,F1,95,5C,DD,38,08,E4,43,75,89,C3,DA,E4,6C,00,16,E8,BB,15,7E,E5,F9,12,85,48,60,6D,B6,60,A6,D5,30,2C,37,5D,73,72,8F,DD,D4,03,5D,78,AA,2D,8F,C2,C0,92,E0,CE,B7,31,61,5D,52,D9,0F,0F,C3,EA,77,0A,FF,B5,84,97,2E,A5,BA,38,19,31,A5,22,7C,0D,E7,A6,27,9F,F4,BC,D3,EF,96,61,6F,E1,68,61,BD,D4,7F,05,1C,5A,7A,82,B3,76,9C,92,F6,21,08,09,F0,FA,57,56,43,01,04,8E,37,B8,36,2E,FA,FA,57,56,EF,04,47,93,20,C1,DD,B1,6C,AA,45,8E,D4,3D,13,5F,91,57,C2,E4,28,3B,6C,ED,4E,C1,C2,D7,48,6D,3C,7D,8F,2B,A8,9E,D0,9C,9F,67,F1,F1,F5,4C,FC,E0,05,7D,2A,BD,EA,D9,F4,6A,52,2F,6B,00,99,DD,65,3E,F4,A2,6C,94,96,A7,8E,F1,00,6E,69,27,FB,A4,2D,DB,77,99,64,FE,1F,AB,52,8A,B7,9A,19,91,C3,5A,33,6C,76,1F,41,C0,A4,25,9F,39,D5,5E,ED,78,5D,2E,36,71,EF,97,B5,2C,BA,8D,86,FC,51,47,D8,68,56,B9,F6,DE,5D,66,5B,04,FD,E7,4C,18,4C,88,5B,F6,67,D9,FE,F3,2F,64,AD,03,6A,C8,66,D0,6E,AD,4A,02,FA,67,67,A3,CC,9B,43,40,4C,AA,64,13,28,E5,89,0C,94,7E,60,FA,ED,5E,B3,DC,C8,83,44,F4,F6,FD,C9,40,E4,9E,88,5A,5F,A6,E4,93,86,94,ED,3F,5D,97,69,B3,DC,F1,6E,78,49,03,75,28,5C,8F,EB,5A,54,72,E2,E4,58,A3,56,62,ED,04,FB,8D,B7,A3,2A,40,A0,32,C7,12,1A,64,B9,11,26,ED,3A,E3,FE,3F,D0,78,B6,FC,DB,1D,A9,C0,98,72,AF,97,AC,F6,D9,34,CA,3B,23,7B,69,CC,2F,65,5C,12,32,56,0B,75,76,75,54,96,0B,FA,0C,23,8E,79,81,5C,AF,3C,A8,61,46,77,D5,8C,A0,1C,27,CB,14,2F,C7,C9,65,40,60,42,E2,3C,0D,B7,8E,00,C5,48,00,27,4B,37,8C,79,4D,95,12,B6,92,6A,86,B6,09,B0,5E,E2,CE,A8,6E,E8,AE,1B,C8,33,3C,19,27,16,15,BC,E7,F7,2E,33,9F,8E,5D,C0,DE,AF,00,F9,1A,4D,41,15,61,E2,24,96,CA,E1,B8,F6,04,45,B1,4D,EC,FE,19,06,63,04,37,CD,B9,F1,62,63,0C,EF,23,D3,0E,1B,DB,97,1D,5E,D5,60,F6,0A,9E,7C,F1,C3,22,5F,71,7B,90,4B,76,54,CB,16,AC,03,D1,7B,DE,02,C0,C4,C5,74,1F,F2,38,01,1F,98,C9,A5,7A,40,AA,83,51,C8,0E,9C,1E,73,9A,22,F4,8C,4C,28,9F,B2,C7,84,9A,4A,EF,5A,71,AA,5C,85,17,FF,5C,E2,B1,6D,E0,0F,5C,13,0D,A4,7F,27,43,44,9A,B6,10,CA,BB,BC,10,72,CE,62,C9,D0,54,43,CD,52,52,CD,2B,43,5A,A5,03,62,9E,20,A0,5C,51,E7,6D,7E,0B,64,0A,94,A4,30,DB,BD,B9,BC,F1,97,7A,EE,B1,0C,40,CD,C1,F0,D9,D5,37,B5,DA,6B,B7,97,74,D2,2F,66,F8,95,46,68,51,64,EC,FE,82,7F,2F,D2,78,1D,67,D2,CA,DC,73,55,EC,DA,3C,73,06,74,9F,89,65,BE,B7,53,21,DF,55,B4,D3,0C,63,86,B8,DC,D7,50,88,BA,EE,2B,B9,5A,0A,0A,7C,A8,E0,06,31,F2,DD,DC,9F,49,46,49,7D,6F,3F,36,66,3B,04,56,D6,8D,F4,C5,7E,F0,3E,A0,6D,8B,02,A3,F6,C9,B9,2D,D9,80,58,AC,64,95,B0,40,0C,E8,9A,2F,E9,47,35,2B,B2,FE,E1,E6,B9,36,8D,19,B1,42,D2,C8,48,B2,6C,C6,44,21,F4,CF,71,E9,64,49,50,14,AC,00,22,79,F2,15,4F,AB,1F,70,11,E3,4A,F0,77,10,BF,6E,7E,3F,69,85,E0,3B,8E,60,33,30,BF,F8,32,2B,E4,39,B5,07,9E,E6,1F,CE,83,1D,3D,41,5C,6E,0D,77,EE,78,84,85,4C,9A,47,5F,17,5B,26,0B,A8,D1,B1,3E,68,74,D0,33,A3,6C,F0,24,9E,81,B1,F0,B1,F4,81,13,40,CD,D5,5B,55,94,C6,0B,69,FA,23,B7,19,21,3B,88,B0,52,CD,E5,6C,09,E5,65,01,38,3F,3A,11,36,19,65,81,A0,A1,F6,D8,07,40,84,C5,B5,AB,3B,4C,85,04,5F,9E,5B,09,5D,31,6C,44,97,DD,17,34,79,65,F0,54,95,7D,7D,85,7F,05,46,61,E2,C2,61,DA,ED,46,4B,0E,A3,34,B1,5D,FD,20,2E,9E,7A,63,E4,2B,8A,45,93,79,C7,C1,2F,7F,99,7D,BD,AA,16,23,76,EE,4B,64,AB,2C,CC,AE,33,8A,EB,EE,0E,04,AB,CD,8B,C5,AB,62,1F,82,02,B8,DC,DB,F8,AF,B1,F8,B3,81,58,3A,57,81,FE,03,CD,98,22,69,36,08,FA,6C,B2,B6,B7,AD,DB,D5,00,41,6B,B6,59,8F,3B,8A,69,7B,24,24,14,C5,E8,C8,6C,30,7D,7D,DB,04,E5,88,71,09,58,2C,90,8E,AA,8C,65,BC,1B,66,AE,F7,79,F2,58,D9,E4,F7,67,B6,F5,55,29,3F,88,3C,9B,F9,E5,E5,12,4B,13,5A,0D,DF,CF,A2,6A,5A,0A,14,3E,BC,46,64,52,6D,AF,16,FF,05,10,0E,A8,6B,ED,AF,BC,82,53,71,D7,08,8E,10,65,5D,E7,42,EE,5E,13,DC,89,3F,71,45,AA,09,FE,8C,4A,88,7B,F0,C3,2A,96,D6,95,1A,CC,39,B7,70,DC,F7,18,BE,07,D7,73,62,47,84,D5,E4,82,40,F9,E0,C3,3B,AF,9B,D0,31,B9,AF,71,27,AB,FE,C0,AC,9C,1C,13,18,B1,1B,71,9D,05,8C,B7,45,55,A6,66,F7,0A,33,94,83,55,86,50,06,66,B6,AE,34,29,02,C9,85,45,86,22,C6,E5,10,F0,97,F3,DC,F1,B5,B2,DF,83,04,2D,DA,78,5A,CA,3C,BF,5F,C2,46,AE,98,BA,2F,D5,87,6A,DB,AE,D5,D9,2E,6D,0D,C7,47,4C,B0,15,2E,63,BA,BA,20,C2,34,D8,13,70,C2,3D,A9,C0,2E,51,1B,62,1A,77,02,24,B2,CB,AA,D9,EB,2E,B7,A4,7B,73,9F,DC,FA,98,3A,22,B8,C7,08,44,B0,67,02,F2,29,7B,C4,A6,66,61,71,AB,F2,6B,6B,7A,3D,71,0C,01,B7,08,99,33,E9,AE,C1,24,06,7D,BD,7A,75,01,44,CD,4D,04,C6,79,86,45,B9,51,32,64,0B,1E,A7,55,91,B0,1C,97,0E,B9,A3,9D,8E,9D,B7,3E,08,B5,16,00,EC,2D,FA,CB,9E,8D,62,E8,41,A0,21,FC,91,45,80,12,BD,1C,C1,4C,B0,AB,69,5B,A4,1A,76,CF,85,EB,30,20,10,8E,10,EC,03,5A,79,CC,F7,EF,33,15,D3,98,37,75,27,14,EC,51,91,CE,C5,26,FF,AC,6F,D9,63,17,C7,24,FA,AB,E8,7E,E0,76,CD,F7,39,AE,03,FD,C1,E5,EE,77,15,66,34,FA,62,CA,E1,D7,B0,DC,11,89,33,DF,92,1D,88,5B,C4,B9,BE,F4,DB,EF,3A,FF,79,01,4E,F6,CC,27,D9,1F,0B,6B,62,E5,8C,44,A0,F7,D2,9B,26,B9,0D,68,07,64,58,3D,B4,D4,95,7C,F6,AD,21,AB,0B,B4,04,B7,67,07,D4,3A,F9,2C,89,9F,CD,00,E1,C5,1A,5F,75,C8,AF,75,68,05,C9,D0,9D,B3,3D,86,5F,E5,F9,C6,AF,79,44,DF,5C,EE,A3,F1,D9,55,BC,F5,2F,F8,0A,0E,E2,2D,C3,7A,2A,D4,44,D8,4E,66,9E,CA,B6,95,08,6F,8E,C1,D9,72,71,FA,8D,B3,03,63,B7,25,5F,D0,BC,C8,6A,2F,27,02,19,B6,1E,1D,8E,B5,BB,0C,DE,B2,A4,82,B1,2C,A9,20,33,79,37,50,E4,68,11,C2,6E,95,37,6A,BB,D2,BE,6A,D2,1C,0A,F2,28,A9,31,89,0B,42,15,E3,86,F7,03,04,FC,7F,F0,ED,4F,60,76,02,F7,DD,BC,EF,44,55,D8,EE,62,01,86,CC,18,01,48,EA,35,A3,54,9B,3C,A5,55,F8,B6,AC,4A,69,4F,82,03,8B,1B,F8,7A,87,03,9B,23,F4,56,1B,1F,AA,7A,1F,FD,F0,EB,25,43,DC,F8,85,66,C1,A5,D3,2F,1A,EC,AF,E2,88,5D,A6,8B,87,D7,C0,52,F6,11,71,E4,19,ED,1C,44,AE,10,51,FD,47,D5,6B,5C,C1,F9,DF,71,86,32,9F,2A,C4,58,0C,49,BC,67,2E,14,F0,5B,19,BF,7E,B3,9A,44,B2,B7,F8,2D,9E,1C,D1,94,0D,D7,F9,90,78,50,4F,7C,66,B4,49,4F,78,50,48,DE,AA,C4,A7,80,C3,99,E7,5E,12,F1,81,57,EE,7B,F7,91,6C,96,65,CA,69,C5,EF,8D,FA,46,81,B0,F9,CB,BD,E8,86,0C,D7,33,43,0E,F6,18,40,06,97,D8,84,47,75,DD,01,3B,42,02,D3,BA,5E,4B,47,D9,8E,10,7B,FC,DD,22,87,5C,9F,67,81,17,18,03,4D,CD,AD,2E,F1,A2,6D,B8,83,1F,27,C0,B6,DE,E3,6E,42,E9,18,B1,56,F0,4D,79,83,43,58,0A,DC,10,0C,2F,18,78,55,E4,F7,8F,6B,5F,5B,60,85,FE,CD,7D,01,00,12,2E,BD,7C,23,1D,B2,53,00,65,6C,FD,58,67,E3,5E,5B,9B,9E,87,E3,F8,83,03,33,92,F4,7A,57,66,A2,78,F8,F2,35,F7,F1,32,70,8E,2C,1B,54,AA,97,5D,11,E9,11,39,6C,8A,3B,7D,61,22,9F,07,6A,4E,DB,DC,1F,51,13,33,A5,E4,5E,5D,89,7E,43,4F,56,5C,52,6E,BB,2D,9E,E7,9D,71,6E,99,51,BC,05,AF,5A,7B,94,EB,22,5F,24,23,55,FF,97,A9,43,49,49,3A,D0,72,77,AD,A4,B2,29,07,A4,D5,4D,B3,D0,A5,58,36,15,2F,72,9F,AA,85,CC,81,B1,E8,6D,83,26,81,44,46,02,94,90,9E,9A,8B,EA,D8,53,A1,15,00,9D,CD,B5,4D,B7,B3,04,29,06,BB,7D,B0,8C,19,AA,FB,CB,49,27,4B,AD,85,74,C7,2A,9C,3A,B0,5E,80,1B,A0,6D,20,AB,ED,F1,13,0F,D2,02,DE,B8,D8,5F,A0,DD,FA,E9,42,3A,58,B6,E9,AC,E1,44,25,07,9E,4D,55,A0,BB,95,E1,46,A6,FB,5F,A6,E1,21,12,4E,45,62,22,71,4B,75,10,54,91,AC,63,C0,5C,DC,86,CE,23,9C,4E,E6,AB,C0,95,A9,BF,C8,1B,11,FF,BB,65,0F,6D,8F,A1,65,4F,E9,6E,9D,78,2C,B6,46,98,2E,C0,A8,BE,60,77,F3,5D,63,74,D7,1B,9C,B4,E7,E0,43,AC,39,DC,9A,AE,89,EF,8D,D4,62,7F,B7,29,D4,FF,24,F7,C2,BA,68,3A,D2,83,4B,4C,6A,AE,06,9F,C3,D3,3D,75,AA,4D,9C,87,EF,56,93,31,61,45,82,B7,F3,C2,A3,A9,DE,F7,11,AC,08,A9,1F,E3,EF,BD,1C,2C,6B,D3,BB,F2,CC,FA,58,BC,48,87,C2,9F,B9,01,63,B0,4B,05,6C,F3,5B,3A,CA,A3,9E,49,C3,FB,DD,F3,0E,26,97,2B,52,31,79,17,F3,79,AC,D0,26,B4,BF,9E,EB,DA,3C,DE,BD,C8,B4,2A,8B,9E,51,83,69,90,B6,81,D0,D7,51,B5,58,72,CF,2B,23,88,9C,33,5A,23,3B,FE,DC,E9,4C,8A,EF,22,63,69,4C,E1,64,7B,53,5C,4A,7D,F4,D0,7F,7C,67,FF,F7,14,9C,5C,A5,25,2B,C6,51,72,36,49,D5,AD,03,8B,25,20,A2,3C,AA,4B,7A,B9,8F,10,5D,26,A0,8A,DE,36,71,9D,47,87,91,45,B8,70,2D,F1,04,AB,57,AF,DA,A0,5B,28,2F,DF,43,9C,EF,43,30,9B,4D,D9,A5,6C,1A,C4,96,F9,E4,22,73,FC,74,DD,D9,15,FA,49,12,40,F7,35,33,0A,E1,95,66,6A,B2,E0,EE,00,29,2A,6D,5E,03,02,F2,B4,45,85,A5,EB,B1,9C,EE,CE,F3,91,AB,C9,93,A5,EE,FE,66,51,3C,CC,A5,E5,FC,6C,FC,EC,1E,2B,98,E7,0A,59,84,89,F3,7E,41,77,A3,30,CB,5B,28,FE,23,99,52,B5,67,78,31,48,4B,3A,63,73,39,A5,B4,C1,4D,2C,5B,7C,46,BC,03,46,ED,74,DA,B7,23,DC,0D,B4,A7,31,60,15,19,69,DA,9C,1D,07,50,E3,36,FF,91,41,8C,B0,1B,B4,D6,92,1F,DD,75,E2,0E,BD,7D,59,13,C2,BD,A1,52,66,4C,2C,FA,CA,2D,5E,50,F7,C2,AE,4E,6D,5B,93,06,63,ED,D1,97,4A,84,35,ED,82,2E,67,A3,F8,5F,41,C4,CA,43,3E,09,39,34,01,A4,D8,6E,99,AB,D9,38,D7,AF,D2,27,95,E9,55,40,EE,D7,A8,F7,0C,C3,18,BC,0F,AB,B1,D6,1C,6A,DC,13,8C,CE,9F,2C,66,D4,03,80,8F,78,B8,4B,07,F7,E7,7F,3C,F6,C4,4A,D9,4B,53,0E,D9,F6,08,65,F7,5B,96,58,EE,59,7C,24,04,81,CF,66,15,B8,D6,1B,30,16,CB,46,08,84,59,5C,57,4C,5E,AE,4D,D9,B8,B1,40,55,85,CD,92,02,12,10,35,FD,CB,F1,4B,02,1A,67,13,F4,E9,A0,7B,24,F3,D6,4C,02,5C,AD,EC,F9,DE,C3,0E,6E,48,1D,16,0B,17,91,DD,51,3D,D9,1E,CD,4B,DC,99,35,34,20,97,8C,E2,00,A4,14,75,69,0B,2D,E3,61,6E,69,57,72,00,E9,4C,6C,DB,30,E3,88,92,C7,12,5C,CC,FE,0B,31,BE,23,BA,AC,C9,F0,74,50,22,03,96,CA,24,BD,D4,6D,56,60,8F,93,41,DF,50,DA,43,9A,78,99,A0,E1,06,FD,48,28,0C,1B,1C,88,33,DD,AE,D3,8D,8D,E2,0B,70,C9,47,72,22,DA,BB,0D,79,D0,96,8A,D9,D0,2F,98,95,00,ED,DF,02,6B,14,21,EF,6B,B7,17,38,F1,6F,38,2D,FD,7E,AA,82,95,52,52,64,F7,E1,46,F6,98,DF,9F,42,6B,5C,14,2B,B1,65,35,9D,3E,B6,1C,24,4A,92,84,45,5E,28,84,76,3D,15,FE,DE,0F,FF,28,07,6B,BC,E2,FE,00,CC,0D,E4,AA,9A,F9,2A,12,5F,96,E9,82,22,65,73,B4,17,9D,34,E5,C2,2B,D7,96,2D,4F,2A,F0,05,1F,91,ED,B4,C0,B6,94,EF,45,35,D4,CE,0A,94,43,96,63,23,A3,65,F6,7C,99,98,E1,6E,A2,74,21,6E,B4,8F,81,D1,E1,F5,57,5E,4D,80,E6,8F,83,AF,C9,14,A9,A5,1C,E0,4C,A3,3B,DC,17,9D,7D,EB,4A,8C,29,84,24,FB,4F,7E,C8,3D,71,86,2D,41,C1,AF,CF,A6,13,34,17,5A,EB,C5,9B,F3,1E,F5,D7,E2,EA,60,42,56,46,A9,05,5B,3B,4B,26,52,94,4D,70,40,FB,B4,CC,FE,BA,54,10,45,51,89,3A,C2,FE,2F,B6,EF,31,67,B3,5E,93,74,D7,79,50,02,DD,69,11,89,A4,3D,5C,1F,BC,AF,AB,E6,88,38,3A,32,13,60,B3,EA,3F,22,DA,FA,15,97,51,88,E4,75,5D,99,55,52,C4,B8,60,7E,D6,2E,31,43,0F,72,68,57,C7,A5,9E,3E,97,59,1C,26,03,D6,08,41,0F,F7,6F,62,0A,29,5D,9E,A0,DD,AD,93,F5,56,4C,79,54,94,40,1B,BE,AF,E6,99,11,BB,67,C4,DB,D1,C9,2F,8C,36,68,22,64,1E,5B,23,31,F4,9D,A0,86,B7,D2,FF,1F,72,9D,9C,17,35,ED,20,FC,75,54,45,16,FD,5B,86,70,9D,1A,4D,18,83,0E,4C,C5,02,E8,D9,14,67,22,B3,49,63,DB,99,7D,06,75,79,C7,10,D7,C4,8A,69,62,F8,30,05,D7,F4,7E,E8,6A,CE,3F,B4,90,99,C5,53,C0,7C,B7,7A,07,4D,A7,7E,E9,5C,5A,19,E5,30,87,3C,FF,59,D2,BA,C5,B4,79,15,C2,E5,21,83,63,3C,E2,7B,19,CB,53,AA,62,8D,F5,2D,B2,C4,8C,66,66,2E,E2,76,18,CA,36,0C,D5,EF,E0,FA,DF,38,93,1F,2D,02,2B,AC,B4,33,29,46,3B,43,54,05,C3,9D,2E,40,CF,54,31,13,7C,6B,C3,F3,6C,8D,A6,B4,F1,6D,FF,4A,EA,5A,5F,82,73,32,FA,B1,81,F8,A0,75,A8,DC,D8,1F,F5,6E,B9,0E,EC,E8,78,DB,0D,FC,72,59,61,84,15,9A,6E,3D,A0,D7,82,A8,44,C9,27,17,AA,76,2C,02,65,12,E1,0A,36,BB,4A,2F,D0,78,BF,2E,9C,E9,22,4E,B4,D9,CF,56,54,B5,23,1B,FC,3D,28,91,9C,21,36,5E,4A,79,54,A9,88,64,5E,CB,92,8E,4A,56,02,CC,B1,E5,1C,17,3D,D0,88,AD,B2,FE,6F,C3,D8,22,ED,6B,53,9A,9B,0F,9A,05,03,31,87,83,1D,07,2D,8C,D2,3A,C1,D1,29,94,56,8F,68,82,04,71,09,D6,CF,67,04,CC,80,25,BA,F4,27,3A,E7,F6,1B,BF,F7,6E,22,A0,DD,F4,22,3D,CE,1B,20,70,B4,33,91,42,EB,A3,AA,92,47,90,36,57,2A,A0,BE,FF,72,A1,9B,47,56,28,07,1A,31,D5,5A,08,0D,E7,AB,38,EA,81,7F,19,4E,5F,5E,6B,79,CB,A1,0A,2E,53,CA,0F,79,EA,2E,C4,7B,90,49,92,0E,6E,3A,1D,3C,B7,27,C2,7A,77,69,4E,B6,0B,89,EB,80,16,D2,77,9F,73,47,C8,F6,C8,85,7E,68,07,9C,51,94,2E,F6,DC,DF,22,19,43,E3,5A,67,8E,F7,7C,88,93,22,20,03,67,57,C4,F9,E7,24,9B,11,02,5E,C9,50,39,5B,86,92,81,4A,40,1A,0F,C4,C5,1E,3D,0B,13,45,39,00,78,89,C7,DF,8D,07,F6,5A,AF,8C,69,53,DB,6B,E2,A2,0F,D2,57,1B,6D,6F,50,21,EA,F6,50,CC,F6,13,07,28,5E,5C,79,D0,B5,24,B1,9B,66,83,8A,55,0D,65,24,A6,BA,1F,21,4B,D6,09,5E,C9,E5,2C,AF,A0,A6,BE,22,A8,CC,44,BC,E3,36,E9,84,43,D7,93,17,FB,50,06,FB,01,55,27,A4,1D,4E,45,8D,05,A1,E0,25,96,2D,A2,AC,DF,07,AB,46,F1,C3,E8,99,49,05,C1,D9,34,C6,74,B9,B5,B1,EF,23,B7,85,AD,BA,4B,29,14,E5,DC,87,B0,4B,60,0D,77,78,54,BC,5B,F7,90,86,27,38,81,02,A5,4F,70,47,8F,79,EE,F8,8C,4E,36,C0,E4,5E,44,41,2B,03,C3,97,7D,85,DF,50,5C,BB,74,78,C3,6E,6D,81,B1,6A,B0,65,D7,52,17,69,E5,E2,14,17,F4,8B,63,40,95,E7,3A,98,56,71,DA,F2,82,C7,C8,19,C2,F6,48,E4,B7,00,1D,06,72,14,DA,B9,87,4B,B1,41,0B,93,19,7C,F0,32,1D,29,1D,69,81,C9,99,1A,43,5C,B9,5C,9D,AA,B6,4E,35,89,52,7E,CD,E3,9C,BC,D7,93,0D,03,0C,DA,17,B8,93,08,6A,92,FC,75,30,B8,72,22,81,21,7D,24,32,0C,50,45,21,E7,25,62,DD,C2,09,49,F8,43,EA,CA,FA,8A,D6,87,EC,BE,C9,77,B4,CE,E7,B6,09,DD,5E,BD,80,D7,22,E2,55,A6,75,AB,99,0B,C2,E2,55,C9,E1,70,C7,4F,66,6A,4B,FC,13,76,50,74,FA,1C,EA,61,B6,9C,9B,40,85,7E,0E,AF,3B,2A,3E,E9,EA,70,F3,18,B8,31,43,26,7F,3C,F3,AB,C6,3D,BC,70,8C,4F,BC,7D,D0,3D,B2,4C,AD,C6,52,0B,B5,C5,1D,55,0F,A4,95,F9,90,1E,95,8B,3A,58,1B,1E,B7,66,3F,34,8B,B7,0E,9D,9F,26,83,78,2B,08,5D,0C,7B,4E,AD,3B,80,F8,B4,E4,38,EB,93,18,B4,E0,D6,5E,BF,F8,61,B2,0D,E0,F7,C4,64,99,A8,94,47,C4,0E,01,04,92,A8,34,B2,01,07,71,81,8B,3B,15,36,15,18,59,83,D8,0C,67,64,A2,7B,CD,2F,31,39,69,04,4E,59,1C,6D,60,89,16,B1,0E,41,4B,9B,C6,64,0C,80,BA,8F,28,44,94,54,22,08,97,C9,7B,DF,3D,49,70,9C,C0,E1,2B,C2,BF,E8,08,C4,07,6E,78,00,B0,05,D3,C9,DA,67,DE,FC,5E,56,66,B4,76,1A,B5,DC,A8,01,25,41,14,03,19,FE,79,96,A1,12,4E,93,96,1E,13,77,D0,2C,F9,AC,2E,8E,B7,5A,1B,38,F9,59,73,72,3C,42,29,E8,DF,40,C8,03,9D,A9,48,F9,FF,32,D2,A2,7A,8B,6E,72,F4,8D,C0,62,60,F2,57,87,F0,C2,F8,08,3B,32,E3,11,22,28,C9,AE,22,42,CB,FB,3F,98,45,4F,05,1F,CD,91,B5,31,42,0F,5A,C8,A2,84,B1,C6,53,62,1B,8F,AF,33,9F,92,8A,92,AC,14,D6,F4,70,9C,E5,D9,5E,99,58,B9,EE,0C,22,4B,08,4A,98,0A,CA,C5,ED,81,CC,1A,83,34,7C,07,7B,E2,14,BA,FE,0A,3A,95,B0,72,4D,72,BF,9F,3C,D5,1C,E9,8B,69,34,B2,81,6D,8C,97,D4,38,2F,B0,5B,03,6C,CC,F4,FE,0F,D0,FB,1C,A0,5B,34,CD,D2,7E,D9,72,18,C3,34,3E,59,7A,0D,F1,60,53,E4,94,3A,25,C8,52,35,AF,3D,42,0F,1B,89,7D,7A,FD,3E,A3,86,BA,D0,A0,65,EB,F7,86,0F,4D,46,7C,14,70,C5,9A,2C,FC,EF,25,53,71,23,4E,3A,47,DC,CE,39,1C,24,50,A4,60,12,97,96,45,35,83,51,39,E2,87,39,F7,EC,86,B8,F5,31,AB,2E,45,F3,44,CF,57,EE,1A,C0,EA,BD,7B,D9,CA,6B,BA,3A,B5,7B,E3,11,5B,98,DC,A5,28,BE,51,AB,7C,C1,6F,45,B7,A9,7A,96,59,E6,B2,13,6E,19,F5,50,11,76,C7,E2,2B,75,18,4B,15,BB,28,F4,31,CF,DA,68,7D,70,BE,31,77,51,C2,62,48,2B,9B,2D,C0,9A,E8,FD,85,8D,5C,A2,91,C9,47,0C,D4,E3,D6,B4,45,B8,13,E1,C1,30,5C,AE,8D,CD,F0,90,53,DD,60,B1,02,2A,B2,79,B2,DD,0A,6E,71,57,63,D7,3E,41,4D,14,16,2F,D7,91,A8,BF,6F,0F,7E,6F,3B,13,15,E1,44,CF,7E,D9,20,DB,95,EB,04,82,76,55,93,5C,7E,9F,E1,74,78,09,C9,4E,52,03,2D,CE,FA,F5,CB,C3,5A,D5,74,47,92,CF,43,69,2C,E9,CA,F7,2C,9D,E0,FD,82,B2,EF,CA,D1,BD,E7,4B,3A,A6,FC,0A,60,D2,E2,E9,D9,F5,C3,18,A1,8B,31,4B,5D,ED,FD,67,47,54,5F,3F,AE,E2,E3,29,F5,2F,80,65,7B,CE,20,EA,53,1C,16,D9,03,62,AA,3E,C7,7F,B3,26,61,83,3B,A9,1B,C3,4A,40,EC,BB,64,2A,01,E8,73,ED,91,01,B8,7D,18,D3,1C,12,13,6A,B0,E8,09,7E,E4,3B,53,F5,3A,2A,17,DF,B4,9C,B7,A7,9D,DF,75,70,61,FA,A4,07,C5,37,6C,87,A0,1E,70,37,7D,16,BE,D9,0C,03,F3,1F,66,9F,EA,31,8A,11,9A,26,01,22,DE,27,31,F4,75,95,0E,88,F4,2B,04,07,D8,B3,5D,D5,07,5D,09,8C,B1,71,74,9B,0E,A9,A9,DD,41,8B,CF,48,43,4C,83,6D,13,3A,CB,89,C6,2B,79,D5,AC,3B,B3,C3,EF,86,21,D7,0E,F5,8D,33,BA,09,24,1E,9D,75,57,F4,CA,9C,31,BD,BF,5D,69,86,EE,31,0C,00,A3,67,40,41,93,C7,E7,7E,AD,13,87,35,C4,73,2B,9F,00,32,3F,3E,23,A6,B9,36,45,A3,C5,52,F6,69,C5,03,39,71,F5,25,13,CD,59,A6,08,CE,F9,D2,53,45,F4,70,6D,4C,D5,DE,6A,74,EF,87,87,0B,EF,08,BE,52,C7,0F,94,BD,5F,05,79,E8,5A,3B,96,1E,D4,EB,BE,4E,72,AB,EA,B4,2C,00,9E,24,8C,80,B2,C8,22,BB,63,17,81,A8,9D,3A,6C,DF,01,9E,5C,EB,D4,92,8A,00,A8,F6,02,FB,A4,B1,5E,EB,1A,64,E6,57,7D,34,CA,24,6D,8C,62,E0,D5,13,AA,70,03,66,17,02,DD,AB,AD,E6,12,B9,05,58,2D,43,1A,1B,8D,6F,C5,36,BB,35,B7,D4,24,FF,F3,6B,28,B9,8E,96,09,FB,9E,7B,6C,8A,F9,8F,25,0A,E2,AF,EC,17,5A,38,9F,CF,49,B2,FD,FB,61,AE,0F,97,7A,79,3B,7E,90,8E,65,E9,14,7A,08,0C,ED,96,F5,48,10,A0,4D,C9,D5,CA,F3,27,25,1E,17,55,90,E9,B0,53,85,6D,76,89,24,BB,4E,FB,17,AC,B1,F4,C6,F9,EC,5E,BC,8B,FD,30,A2,3A,5D,82,BC,21,E7,44,6D,5F,C7,13,5B,43,B0,F2,65,30,7F,43,31,4B,87,DB,C5,3A,4D,35,CE,90,3C,9B,69,3A,86,B0,FC,47,36,41,CB,13,A7,79,F2,21,11,AB,40,B9,B7,31,88,6B,FE,83,68,4F,09,A4,0E,B7,F0,E1,84,64,D0,5A,D2,6F,1A,79,AE,68,CD,76,52,8D,74,AA,36,7D,4A,19,66,76,7E,DD,BC,A9,F9,B2,EC,E0,DE,84,4C,C2,41,43,21,68,D7,DA,22,5F,68,55,6D,2D,BF,B9,97,3C,D4,D0,B9,53,CD,48,DC,61,96,07,B1,03,2F,CA,05,25,9B,ED,7A,7A,E5,54,95,BF,74,12,18,FB,1B,25,09,09,9E,19,28,D1,01,41,ED,25,19,7E,80,88,D0,14,53,BB,C5,CE,80,E8,5D,30,27,89,E2,72,6E,83,74,E4,A4,72,2E,AE,93,7A,84,7D,45,1B,2E,7A,B3,21,65,49,34,E6,1C,B5,1F,0B,41,54,CE,D9,42,D4,2B,00,1D,9B,6E,7E,91,E4,1E,94,BD,C4,DB,5B,67,F7,72,C1,56,8B,AB,FB,25,CD,66,7B,8D,79,3D,13,3E,99,8A,02,26,6A,6F,B3,1E,85,43,EA,36,2B,56,E7,E1,03,5A,64,61,11,41,00,48,E5,F8,10,58,1D,08,01,D1,DE,1B,CC,F8,E5,99,15,1E,5C,FB,B8,5C,9C,AE,AF,AC,D5,AB,9B,B6,B4,DB,03,FC,20,BD,7A,AA,6F,D7,A6,64,E0,BE,D3,F1,C3,10,51,EB,59,EC,0F,E9,D9,D3,5A,EF,0F,F7,E2,1F,95,C3,48,BD,3D,ED,3D,27,2F,CB,A5,96,D3,92,9E,62,1C,80,49,70,9E,BE,1D,EA,E2,32,30,93,68,D7,B8,8D,1C,9D,18,66,11,0D,63,70,14,B8,C4,98,F0,7D,9E,BF,5E,F0,CA,E7,76,98,6C,A7,E4,8C,23,AA,86,F9,36,DE,32,AE,06,E2,DE,BF,10,C8,0A,B0,F8,59,A5,8A,28,D8,37,38,71,B8,60,FD,DB,33,56,27,6F,A5,A0,CA,A9,83,60,96,F9,6D,EB,05,4A,75,CD,BE,EC,E1,37,A3,9B,E2,CD,9E,D9,8E,1E,60,02,E9,31,53,90,79,69,B0,0F,BD,4B,91,22,5C,57,E2,5A,14,D5,E7,A8,ED,43,AB,BC,56,CD,C5,A4,42,37,99,49,02,4B,C4,17,DA,7A,D6,ED,79,FA,DE,DA,F1,56,FA,34,74,D2,A2,E6,70,A9,BA,2B,8C,D2,CE,0C,7A,7B,D6,D5,56,A3,64,23,40,33,9C,B7,D9,81,9E,78,3F,53,37,1C,39,23,3A,F2,37,A9,C6,E3,F2,1F,4B,06,BE,EC,7E,44,4E,4E,4D,22,08,EB,2E,D0,18,5E,7A,62,8F,BD,11,44,0E,EF,CC,A7,EF,7D,EE,E2,30,64,C2,CE,76,57,68,A2,93,20,45,4D,23,21,34,8C,49,C7,15,FB,81,51,32,D0,CA,9B,9D,35,AC,87,4B,BB,06,6C,DB,60,B2,32,15,1A,CC,46,92,C6,16,2D,56,50,A5,00,FC,2F,51,05,DC,88,42,E8,FD,F7,8D,BF,98,CA,A1,A3,C3,F3,86,C7,3B,42,1C,D5,18,AB,2A,B6,F8,19,CC,B4,1B,C3,10,80,E9,36,94,FE,22,05,B8,5F,3E,46,9B,20,90,31,B3,F5,64,6A,BE,5E,36,CB,E0,87,A7,90,C1,CB,8F,6C,87,F1,0D,AD,9A,A1,C6,32,05,61,31,89,3E,FE,FB,1F,33,14,A5,90,19,D3,CD,6F,F5,C0,79,4F,5F,56,F1,02,A0,7D,F3,65,B5,E4,9B,0B,0F,04,4F,BB,C7,5D,13,C6,EB,A8,C4,F5,FA,61,D3,FA,2A,A6,2C,65,84,86,42,2C,F6,4D,C4,36,42,C7,57,66,C0,EC,03,2F,57,99,9F,00,3E,43,37,8B,06,AC,02,35,D1,A7,84,FA,53,4A,8D,18,57,22,22,D6,0B,2A,7E,BB,19,20,68,F2,5F,4B,84,7B,F9,0C,84,43,0E,13,4B,38,6C,12,1A,62,26,A4,FA,61,53,76,E9,E3,A0,69,F7,C3,B0,16,58,1E,8A,4B,4D,D9,D2,EE,86,B7,DB,73,6A,15,80,09,06,CA,45,2F,2E,DD,67,67,F5,C4,AB,7E,84,63,F4,6D,6B,F5,3F,99,4C,43,89,01,20,A1,EB,F5,26,EE,2D,B0,20,88,54,B1,D9,07,4C,B4,A6,66,62,69,A0,85,44,84,89,5C,02,A7,66,20,0A,8B,A8,E5,8D,82,EA,C4,34,BD,6F,65,6E,B3,63,BD,63,34,FC,CD,6B,13,28,05,B4,0B,0C,37,1F,E6,1F,5F,8B,45,B5,DF,54,1B,AD,47,B2,95,1C,53,C6,C5,86,E3,E7,50,21,C0,C0,74,4D,81,06,76,61,C8,73,40,F4,2D,99,13,0F,94,B3,61,59,77,46,81,C1,75,0F,94,55,65,28,AC,E8,B3,21,D5,BB,52,84,A4,FA,16,2E,09,4D,A9,7B,98,50,1A,D7,9D,DD,69,D7,34,9D,23,DE,58,40,BB,E1,D9,1E,3A,DA,D5,7F,5B,E9,C3,8E,F9,BF,64,05,B7,45,DC,38,02,CB,A3,7D,88,1A,61,26,EA,C6,6B,8F,DD,9A,6A,6A,E1,86,58,BA,8A,55,43,26,F0,FC,3B,1E,62,68,DA,B5,E7,6D,5B,A4,68,88,C2,32,09,E4,5C,AF,ED,01,E7,8D,B7,82,A3,34,FA,C7,CE,D9,B5,C2,DB,1C,7B,0F,B2,2D,11,A4,B5,76,C9,71,1C,29,E9,EB,11,8D,A8,94,BD,2C,F6,54,D4,A5,A8,80,9E,9E,30,B8,60,DE,AC,07,63,EB,32,51,3C,04,39,75,5B,3B,4F,98,47,11,4D,70,00,91,89,02,80,93,75,06,E8,17,C9,7B,82,2A,ED,65,71,92,C7,54,9F,91,75,B5,0E,97,E9,9B,17,6A,FB,E0,7D,57,23,09,F4,BF,1B,F7,FA,27,9A,DD,DF,4A,38,DA,1A,6A,ED,0B,BC,91,B0,F0,21,76,0D,EA,25,A5,6D,E7,4A,39,90,CC,7B,0D,5C,D6,A3,A1,CE,5D,E0,53,51,2B,4B,AC,C9,18,02,D9,B3,23,00,30,07,22,B1,8C,E2,44,4C,DF,F6,A4,DB,CE,8A,F6,35,60,17,5C,EE,5C,4B,10,56,48,C6,72,5F,12,D8,6F,B4,4E,89,76,8E,AE,70,A8,67,F2,EC,CD,77,B0,41,5D,38,53,3F,D0,27,BE,DE,F0,FC,C3,75,50,0C,8E,FF,6C,83,8E,1B,BC,A8,69,71,EA,90,F4,6A,10,C6,F5,79,0D,6B,A9,FC,36,F1,D9,09,E0,3F,C8,D3,E6,21,A0,30,6E,8D,A9,5B,32,E5,F4,21,F8,31,23,35,1D,05,AB,BD,C8,28,78,65,26,CF,BB,36,CB,D2,13,46,F4,FC,E8,B2,02,CB,9A,1C,0B,9C,F1,4F,6A,67,32,2B,C7,8A,01,90,B2,2B,F4,C7,8E,E6,4C,05,E5,36,D3,F8,36,44,B9,1D,1D,E9,CB,2A,7C,F9,90,3F,4F,84,45,B5,09,6D,3C,BE,F4,A1,76,6D,A7,0E,A3,10,20,AC,59,9C,3C,CD,E6,7E,1A,04,2E,D7,A8,90,C6,B4,3C,8B,B1,59,99,4A,21,0E,92,EA,67,BA,15,99,09,69,1D,C9,51,E7,FF,AD,C5,39,E6,B0,A5,3D,C7,F1,9F,92,08,A7,CE,01,51,90,F5,12,AB,5B,CD,79,8F,62,EF,A4,2B,4E,C1,15,0C,22,76,6C,99,D2,8B,44,9C,D6,8C,E6,A4,01,C4,0F,28,61,39,19,52,75,D6,9B,EB,7D,BF,1D,29,2E,96,AA,00,DD,30,AD,C9,EC,38,29,66,67,E6,5D,9E,AA,01,57,2F,E5,B8,6A,99,E3,92,57,B9,E3,46,39,AD,97,82,74,CA,4E,64,B1,B7,E0,F8,C2,D3,A2,9A,7C,7E,AC,CA,EA,A3,60,06,84,7C,0C,15,06,F0,0A,B1,90,57,64,2B,20,89,D5,7C,ED,26,6F,27,45,9F,96,99,3C,71,58,7F,92,E0,DB,AC,27,42,BF,14,5D,6A,E9,8D,A1,E2,97,07,C3,F1,26,47,52,8D,ED,41,CC,E8,61,98,BF,D6,99,FF,A2,C0,9A,BF,43,DC,0A,A9,30,8B,6C,E0,D4,A3,B2,57,56,F1,4E,81,23,A7,8D,52,41,E7,01,A4,53,87,AE,AA,D3,70,43,DE,94,F1,D6,E1,25,7C,7C,D1,BB,E1,0D,3F,25,CC,1D,E1,71,98,7F,84,8E,37,3F,78,95,11,53,9E,3D,38,A2,73,90,B4,59,4F,13,60,A4,E5,D6,15,33,1E,95,31,BC,CA,29,32,11,C4,C1,7E,14,96,8C,19,AC,86,B1,79,99,D5,12,FF,43,02,57,BF,45,AA,29,91,AE,81,E5,89,96,1F,41,23,09,BD,59,5A,62,B0,52,5C,19,8F,EF,EB,71,E3,DE,56,0D,30,37,B8,42,B3,F1,BA,27,41,62,86,EA,9B,FB,15,71,99,23,AD,02,04,4C,C0,4C,E3,2A,48,8F,BD,A6,32,8D,D7,4F,CB,99,FC,72,0E,CC,AA,A6,E0,7A,3E,2F,1E,F8,2E,57,08,BE,DC,A4,7B,4C,A2,55,42,F7,A5,E8,95,06,DD,0E,9B,BA,46,65,A2,BA,53,AA,82,60,02,02,1D,B9,8F,55,37,2A,0D,5C,AC,BF,0C,EC,80,16,0D,FD,4F,84,84,1A,D5,14,DB,C7,EF,59,64,3F,F5,E7,D4,D2,5E,54,6F,80,66,60,A8,60,EA,AC,B5,52,E2,B6,53,8C,5A,0E,D5,04,50,5C,C3,28,E7,07,5C,F4,90,49,58,B7,02,28,94,BD,48,68,24,F8,21,B3,60,BB,35,64,8B,46,E4,6E,77,FD,97,98,4F,73,EB,71,DE,45,69,CD,8B,87,80,FA,8D,78,C8,E7,E5,7A,1B,DE,EC,35,E5,EA,8F,7D,2E,BF,02,64,D7,FD,3E,A1,3B,9B,44,2E,1C,17,25,32,B7,D6,E5,2E,18,48,22,F5,DF,D1,56,2D,42,41,DE,E3,AF,4A,69,07,AE,C3,92,A0,7C,6A,37,76,B1,FD,31,32,C6,E3,43,BF,49,36,4B,6B,C6,72,36,EA,28,32,25,0E,8F,3F,AC,5E,FE,83,29,88,4E,63,24,38,30,28,F8,9B,F8,ED,8A,D6,99,BB,CE,E6,BA,09,6A,FB,3A,62,1E,8A,18,D2,39,80,FC,A9,D1,B7,F5,CB,A1,AE,BC,56,E1,48,85,5F,60,4A,CE,4F,AA,4F,F0,7C,2F,51,E4,B7,52,AD,58,B0,A6,44,BC,E2,40,CA,E9,71,45,FD,22,84,70,CE,28,61,F6,DD,90,B5,72,93,50,A6,9D,1D,F0,CB,C6,9D,94,1C,67,D2,D2,9F,FA,0C,48,F3,18,49,A6,5B,99,0F,2B,CB,0A,16,82,32,67,A8,CD,47,FE,21,6D,04,CC,5D,30,B2,1C,37,73,D8,53,EF,FC,B1,13,F5,13,89,11,7C,B8,A7,C2,B1,D7,A9,A2,7A,D2,D3,94,E9,72,6C,46,18,3B,CA,D5,C9,BC,5E,4F,BA,DD,72,9E,6B,35,FD,B7,62,6F,2D,05,C5,89,FD,EE,C1,59,D6,B9,E8,A4,1F,C7,1B,4B,29,A3,64,89,A9,CF,FE,E7,A5,80,0D,FE,5C,1F,BD,9A,33,62,EE,FF,42,8F,28,71,F8,77,2F,8C,91,2A,08,ED,35,44,E2,F8,5E,C3,77,32,65,09,60,CD,09,AD,BF,3D,A1,FB,14,07,C2,10,B9,8B,4B,6E,48,DF,36,90,FF,F7,42,19,8F,10,D6,55,B7,08,59,87,4B,44,EE,ED,13,F9,30,E3,E6,5F,87,7B,FB,B2,31,F8,DE,EB,15,43,E2,E0,78,72,1C,83,EF,AA,FC,66,06,0F,B4,4A,5E,AA,67,11,86,CB,CA,26,C6,01,42,7E,63,BA,78,52,00,5B,79,D3,4B,FB,50,73,27,1D,1E,15,22,9F,EB,FA,E2,FF,A6,58,FE,72,5C,44,4B,E0,71,31,32,FC,F6,F7,23,29,EF,82,BD,45,57,13,D9,29,1A,FC,FF,1F,2D,04,33,53,09,68,25,E1,42,90,5B,16,32,9A,FB,57,57,71,B9,70,B1,3E,FE,0E,75,DB,9C,6F,C7,12,C0,81,12,AA,CC,CA,6D,71,63,6A,8C,56,69,0A,49,CD,82,B0,89,C0,3A,AD,CB,97,B1,E7,67,CC,7C,EF,9B,C7,8E,C3,71,D5,2C,D0,9F,63,4A,12,CA,D4,BA,4A,6D,66,C2,26,1D,21,14,BA,A0,27,B9,2E,63,FB,61,ED,32,5E,19,FA,CB,52,8C,11,2F,E8,CA,D4,79,1D,0A,98,C7,40,83,B4,63,5A,A7,A9,B4,2E,7D,F8,F2,08,17,39,60,52,99,BC,50,FA,30,5F,14,B5,7C,BD,A5,3E,5A,44,FD,BC,56,46,2E,D6,0C,94,25,56,CC,BA,B5,9D,52,82,22,07,8C,BB,FE,10,32,96,D5,0A,52,EC,F2,F7,0B,37,77,C2,A5,2F,97,7C,A1,95,FF,7C,C4,27,8D,9D,3E,E2,03,27,9B,F2,8F,62,45,2C,CE,AC,76,9B,57,77,1E,84,F1,D9,50,56,DA,4B,0D,43,7A,42,1F,67,C1,ED,EC,91,E9,F1,AE,A7,51,B7,E8,8C,68,0B,CC,4B,8A,72,4F,BB,C0,36,D4,23,C3,3C,10,74,BB,95,69,AA,E7,7D,59,6F,4B,D4,E8,4D,86,4C,DF,94,B0,A6,70,09,36,9D,C6,94,8A,F2,71,92,AA,64,59,07,E5,7E,C6,68,8C,F5,71,5F,D2,EB,1D,DA,62,22,41,65,2C,28,19,9B,B8,5A,05,84,A6,13,70,B1,3E,05,EF,3D,88,C3,74,2C,DD,10,44,86,06,49,C1,10,07,9C,A7,CB,5E,13,11,C8,20,E3,CA,48,10,41,9F,90,96,5C,1B,14,57,26,60,D3,DA,97,7C,39,62,F3,2F,12,07,82,F8,67,1F,2A,89,64,BE,30,07,60,5E,D1,57,CA,1D,C0,81,D5,ED,D8,25,11,89,32,B1,93,C8,76,BB,BA,B5,0C,AF,01,1F,DC,C6,60,F1,D5,57,43,28,2F,C8,2F,BE,B3,A0,CE,C5,3E,57,39,89,2A,D1,F0,C7,EE,19,40,49,70,81,2E,2B,AA,84,47,85,18,F4,1F,B4,74,D8,FE,A5,AB,18,DD,30,9D,D3,E4,54,CE,0F,DC,01,20,37,FB,B8,53,41,82,88,3A,12,52,53,1A,53,7F,71,07,92,16,F4,3C,3C,B1,F6,15,73,31,F7,E5,4F,D5,62,DE,6E,9E,94,CA,BC,3C,96,D2,D4,43,B5,DB,E1,13,DB,E7,18,2F,19,B3,DD,BF,F8,B3,1F,E7,29,24,42,83,74,B0,74,81,21,E3,0C,09,01,8F,54,78,DA,B3,4A,10,6E,F1,B4,B3,05,DC,2F,CE,06,41,E2,7E,A6,D2,0E,4F,01,C4,34,1B,5D,F8,B4,30,FA,1F,91,3A,E9,3F,BD,E5,B2,F9,E2,18,AA,63,81,81,7B,A8,5F,C6,54,4F,33,42,72,82,C0,19,42,45,D5,8E,61,86,30,82,E5,14,14,68,3F,14,BC,13,29,1B,80,A6,9B,63,16,2A,1A,36,7C,1F,20,6B,20,49,FA,42,39,8A,5D,A6,E6,A3,64,5E,2D,96,8D,05,B7,05,5A,5C,6D,17,56,79,58,D2,D1,04,40,4B,C7,4F,6F,5D,B0,30,1C,94,8E,87,26,0A,3B,76,79,89,65,B6,34,AA,70,E9,00,A6,0B,30,0C,75,5D,C3,7B,F8,EB,C2,56,D2,89,A6,4D,A2,8D,7A,09,1D,5B,67,15,A9,95,27,FE,95,95,5B,85,E4,CE,84,42,06,18,9E,84,10,77,5F,B9,ED,0E,C9,40,BF,2A,24,A9,FE,FE,DF,F5,A2,BF,F3,F6,99,EA,C3,93,B0,DB,A2,1F,FC,E4,51,9F,BB,DA,B8,A2,FD,9B,D5,77,41,D8,C6,7F,A4,F6,F0,EF,1A,AE,E0,80,D7,54,A4,22,6D,A9,C0,4F,18,8B,25,99,77,FD,D2,17,9C,86,07,C3,53,25,DE,C2,14,4B,62,3F,66,21,46,02,76,44,4B,FE,EA,AC,3E,FC,3F,AA,3C,CB,97,15,35,51,A7,53,3A,7D,93,EA,69,1F,08,45,60,D1,03,FC,88,D1,A0,D0,ED,CF,5D,73,9E,61,27,17,C3,CC,BE,1C,DD,D3,E6,3A,95,21,40,07,E3,BF,05,73,BD,DE,4D,39,74,E4,35,23,57,C3,19,34,82,5F,04,9C,33,49,E3,FB,61,75,1B,88,B9,F6,FD,E7,4D,9D,96,A2,75,D8,2A,8D,54,3B,A3,06,09,5A,A2,ED,FC,71,CC,C4,B2,79,6B,6C,2F,F7,9E,A0,A9,2B,FC,26,EA,29,30,A1,67,7B,6A,06,58,BB,A8,D2,7E,52,8B,6F,E7,02,34,DA,5F,9F,B3,5B,64,65,31,11,9C,FD,4C,C6,E1,D1,EE,E8,67,B3,75,74,74,F4,73,41,AD,9D,F4,B1,7C,29,C2,9D,97,AF,A4,95,D7,3B,2B,4F,44,DB,F5,9A,FD,42,4C,2E,31,3A,22,CA,02,F2,D6,37,67,B6,E6,6C,D5,D8,8E,CC,EE,1F,09,06,8A,F5,F3,57,40,E5,C0,58,64,30,86,59,BE,69,19,8D,0A,34,53,1C,51,DA,D9,97,69,50,CD,C2,83,D2,56,A5,A9,78,CA,C6,BD,43,36,22,31,91,35,48,EF,C8,C3,64,71,20,C3,8B,FE,CA,F0,D7,74,CB,20,D2,72,5D,B7,3E,57,CC,FE,D7,C3,8F,C0,09,AB,FB,7E,D4,50,CD,01,CF,CD,DE,74,F5,29,B6,18,6F,28,F8,15,7C,AC,B3,40,21,00,B8,3D,DA,3D,05,1A,98,6A,D1,78,18,2E,E1,27,0B,34,9C,7F,3A,46,80,1F,F4,9C,FA,52,9F,1E,FB,5C,CA,96,1F,14,42,9A,7E,ED,47,FC,21,99,D1,5C,B3,55,2F,CF,37,5E,F0,03,52,BD,55,6B,76,C6,9A,E4,49,76,C1,19,85,F9,C7,69,86,0E,82,07,0C,7C,3C,16,29,42,8B,CF,A7,0B,EC,51,8B,96,A8,C9,5D,B2,BB,6F,16,86,38,D0,AB,B0,BE,2F,B8,44,33,91,DA,70,8F,DF,93,41,D9,D8,8D,75,56,56,96,E3,F2,B8,C1,F1,39,8B,30,E7,8B,B5,29,D9,0A,C8,F6,23,5E,F0,33,94,69,8B,70,BE,D4,D0,69,FF,76,0D,95,38,F3,5B,66,FC,F1,F5,EF,C8,F1,79,35,4B,7A,E8,6D,05,6D,EA,54,71,5E,F2,22,48,95,62,4E,34,5E,9E,9D,5F,E3,D6,CB,DC,AB,FD,BD,82,DB,70,EB,88,43,84,A3,D7,53,C4,6E,5C,59,65,2E,B8,0B,6B,E6,70,82,98,E5,32,C7,43,35,61,57,45,13,08,FB,57,2A,5F,1B,25,60,0A,1F,04,DE,8A,E1,71,5E,AD,FD,F5,21,55,B9,22,A0,12,B6,83,EC,FA,D2,B0,7A,60,20,E2,7E,D1,FE,F8,88,B7,EB,BF,D4,23,99,9E,80,BC,7C,2D,13,D0,1C,07,8C,1A,10,13,8D,75,6D,69,AC,E1,89,AF,48,AC,D1,39,2B,CC,7B,B3,15,EB,32,8A,4B,DD,1D,78,40,5E,3C,C4,FC,A0,FF,07,98,23,BD,19,A1,6C,B6,52,E8,BB,87,3A,7C,FA,D9,55,63,37,F4,28,8B,57,EC,6B,5B,05,30,1B,74,46,55,9F,E0,4F,40,CD,61,35,F7,4D,8E,56,6E,3C,D5,A4,B2,9F,3E,1A,F8,D0,6C,DE,A7,AE,C3,00,72,03,7F,E4,CF,52,DA,EC,A2,43,BC,A1,A8,23,2E,1D,8F,ED,6A,1C,B4,BF,B6,E1,B9,06,80,FC,3B,DE,59,63,FD,B0,A0,16,83,B9,CC,4E,0A,8B,94,70,B8,03,31,D3,89,74,41,18,92,99,AC,32,9F,3E,E4,4A,A2,A9,0E,94,DC,CE,AB,27,37,95,FC,28,B0,18,37,FA,23,E1,7D,7C,C9,B2,0D,4A,9E,FD,8F,75,C9,AE,64,7E,AE,AE,DE,BC,C1,09,8D,8D,FA,75,15,56,25,17,97,FF,05,2D,A1,06,3D,03,37,6D,B7,D6,CF,5C,9B,B1,FF,E4,3F,8C,9C,26,CF,8D,40,E9,23,26,E7,00,02,A0,C7,51,D6,3E,0E,CB,8F,19,DC,48,0E,20,40,4D,61,DD,B3,18,D8,37,FA,49,0D,1A,4F,C0,4A,72,A4,B4,38,DD,81,7E,84,16,94,ED,CA,B2,D2,25,EB,79,60,25,B3,92,EA,D1,02,86,7F,65,3B,9F,28,79,6B,43,CD,B2,8B,44,84,DB,F4,BA,4F,68,E2,6F,F2,C9,05,02,E2,30,BD,36,E8,84,20,1A,34,D0,83,3D,5F,1D,EB,31,60,47,F3,1D,5C,D0,F8,A4,AE,DC,96,25,AA,2D,4D,C3,32,21,93,CB,75,9B,25,C0,58,4B,61,C7,49,4B,C2,A2,88,7C,3A,16,89,7B,21,24,D6,87,7D,53,F3,5B,35,6F,F2,D1,B0,E6,C8,17,2C,C9,73,D2,12,74,8F,48,E3,40,35,3F,E4,BD,57,5A,64,75,24,6E,40,B3,8D,BC,1F,C5,F8,6D,4E,CB,64,5D,58,2F,C0,EF,5E,31,86,8B,C5,A0,BE,F0,CF,D7,D2,4E,76,34,A7,C5,05,28,CA,63,83,B8,A5,F3,42,14,DD,1B,E0,67,F2,FC,BE,9B,01,08,66,FC,09,35,6D,B8,CA,62,81,74,52,16,84,82,86,86,93,A3,11,A7,CA,60,E2,21,89,4E,2B,2E,80,FF,1F,9A,D5,0D,B2,69,6B,59,6A,5D,9E,A0,66,4E,B6,7B,8F,15,79,D2,D3,46,48,2F,BE,A4,47,3A,79,82,DF,5A,EC,7B,72,75,C6,5E,F4,6B,60,B8,85,7B,B5,35,13,09,9E,0E,4D,FA,EE,44,B7,A6,7A,1A,C6,03,E9,47,63,2C,F7,AA,46,BC,75,C1,8A,80,DB,E1,B9,37,D2,19,88,6B,0E,14,00,BE,92,CA,77,E5,02,1B,B4,81,AF,63,29,A0,14,12,DB,49,25,26,C5,2B,43,84,C7,31,B7,AC,1A,6B,72,D2,86,6F,8C,CB,5D,76,B6,E4,2F,55,34,9A,13,CB,8C,F0,49,C8,00,0B,0A,00,36,79,1A,F2,C7,A9,0A,FC,85,F3,E4,B1,15,9B,BF,7C,B6,D7,F4,FD,3A,EA,C4,A6,1A,2C,E1,00,08,33,E6,A3,46,01,EC,44,39,EC,98,51,15,25,18,93,DA,D1,5C,DE,48,CC,6A,70,7D,CB,B6,46,99,02,09,6F,85,E8,51,84,48,41,84,CD,88,72,B2,A6,0A,F1,51,53,02,E6,7E,E8,A7,CE,B9,58,1E,56,44,A5,D3,B1,B5,CE,C1,B0,79,4A,5C,FB,37,F0,61,DE,5C,16,EF,D3,D3,0D,2B,6A,3D,84,55,63,AA,0E,F5,06,57,A7,DF,C4,8C,0E,E0,B1,BB,16,95,F1,59,C5,A1,8A,BC,3C,A1,29,E5,CC,2F,C9,E1,66,55,90,53,14,0A,38,D6,C7,58,1B,8E,90,B6,CB,36,89,A9,EC,27,5C,06,FD,7A,1E,B0,61,03,49,D4,07,CF,13,D3,DC,22,A1,E9,DA,7F,AA,79,7D,17,16,63,1E,E0,6C,37,BC,8F,37,E8,2B,06,FF,59,05,4B,11,47,7F,D6,2C,D1,02,30,B0,41,12,11,D8,C6,88,14,1A,F3,9F,41,FB,D2,80,73,95,1F,9E,C2,A4,17,BC,2D,B3,81,4B,3E,BB,E6,89,A7,6D,97,B1,E2,18,80,08,21,23,35,C4,78,D1,9B,8B,78,9E,3D,65,52,33,C8,EA,02,A0,6F,44,F3,B4,68,2F,62,D4,9E,5E,C5,DB,14,D0,9B,99,BD,93,8A,0F,03,C0,1B,96,E9,7C,1F,97,F1,3A,48,6B,1F,BB,AC,3F,D4,DF,E4,7B,7B,2C,D6,E0,BC,B3,54,9A,76,F6,F1,D8,B9,9D,FA,FF,53,14,81,9A,6D,0C,90,45,E7,73,C7,F8,A6,14,EC,CD,D7,0A,6D,6D,1D,91,86,0D,E3,BC,4D,AF,51,00,05,5E,1F,67,41,49,F9,44,31,1F,DF,69,E3,2C,96,A5,3A,2B,45,FC,44,46,18,5D,41,8E,C6,1F,D8,22,AC,61,9F,31,C0,22,CE,9D,6A,13,13,B4,67,36,51,60,21,10,ED,27,8D,23,57,CB,60,45,D2,8E,0C,7E,00,FF,8E,2D,73,0E,DA,E6,07,B1,0B,41,AB,D1,58,30,2F,55,65,E7,47,DB,26,2E,A9,06,FE,61,42,94,59,19,53,52,60,F4,FA,14,A9,2E,48,49,14,AC,D6,57,37,F3,0C,7C,DD,B0,73,DB,95,F8,A7,B3,12,7E,00,B8,89,20,2D,38,9D,1B,B8,7A,07,88,DC,2F,13,05,3E,3E,11,AC,46,E4,59,6A,60,C6,DC,D5,F3,10,F3,3C,F0,72,DE,F2,19,00,8D,A1,8F,08,4E,0B,65,85,B2,FE,13,74,DA,3C,BA,E1,3A,9A,70,CA,21,81,21,45,39,FB,6A,00,CF,07,6B,21,35,F5,60,EB,07,B6,1B,18,7C,1B,FE,D5,D0,F4,8F,3E,84,77,E4,0F,73,B7,89,09,73,C3,23,8B,6B,89,48,1B,B4,13,70,70,80,25,3B,15,36,E1,D2,C9,F0,30,5E,D2,2D,34,5D,BF,49,2A,E3,3F,E2,82,10,A9,7D,10,5C,18,FE,1A,01,50,C4,13,DB,4B,57,53,42,56,BF,FE,43,0C,49,5B,37,DB,19,77,1A,A0,5B,2A,5C,2E,AC,41,0B,AB,CF,DA,5A,E5,A5,20,C5,6C,9F,84,7E,D5,90,25,D0,E2,88,04,64,F3,24,02,BB,62,30,23,11,F4,FE,D3,50,1A,A0,1A,D6,CB,51,9D,35,65,A5,53,23,35,72,C4,72,FB,84,8B,05,7F,3D,D9,97,76,84,1E,FC,20,80,7A,5E,96,16,33,82,6C,7F,60,B6,7F,C2,C9,E1,FE,E8,D5,57,2D,A9,F0,02,99,5E,99,C2,4B,BD,14,84,F4,E5,F9,96,1E,40,49,47,17,8D,82,E0,B9,25,68,6B,36,09,0E,B4,6B,BD,B4,43,30,1B,A7,B4,0A,C0,92,D0,6F,F1,4D,42,F2,EB,4E,C9,8E,44,A7,75,F4,96,EE,D7,8F,CD,35,EE,E0,CA,C3,6B,00,CA,4B,27,65,03,59,A9,E2,4F,17,3B,55,01,61,EC,C4,4C,14,B4,ED,83,25,64,23,54,32,8A,8A,81,6F,34,D7,0B,C2,C8,7B,AF,26,98,7A,8A,65,91,E5,D5,A5,87,7A,05,00,4B,88,14,2A,B0,DD,88,D4,02,0D,D3,27,0C,DE,80,01,51,04,EE,69,33,D8,6F,95,DB,A1,6F,03,7A,C3,FF,9D,48,4C,1C,47,0C,1D,2F,FC,FC,C0,45,C2,97,1B,FC,52,C5,8C,DC,19,7E,F0,BF,C6,43,A7,AD,69,DF,FF,DC,B0,74,C5,83,C6,4F,64,F8,80,BF,52,23,EC,84,45,74,20,8A,B2,11,37,3B,F5,E9,FC,FB,FA,EF,E3,EC,06,99,79,69,B4,08,3C,8B,8A,CB,36,02,55,21,52,94,AE,AD,85,2D,1F,11,01,29,0F,73,5E,DD,7F,F4,CB,DC,B3,94,CA,C7,C2,82,DA,4C,44,40,F5,D2,24,29,97,E8,D4,0F,2C,FD,B1,18,BC,53,0A,5F,8A,D9,14,C0,19,39,2F,09,AD,3F,97,C1,A2,3A,D8,C9,B4,D8,AF,A2,9B,D9,C0,A9,E7,E0,91,34,B1,ED,D9,10,DB,CA,D6,D4,E4,5F,24,52,5A,E9,0C,C6,4D,E0,E6,E9,B4,0F,B7,60,5C,33,E8,71,D0,86,4C,BD,9E,3F,67,4F,F9,88,EA,EB,BF,BD,CC,37,96,6D,58,AF,DE,AE,FA,42,0A,9F,83,9D,F3,47,4C,16,17,6F,E2,A5,E1,BF,79,FF,65,21,DD,37,A4,2B,CA,54,9F,4D,38,5B,B2,A3,BD,7F,10,FA,3B,70,35,19,A7,9C,37,72,88,55,4D,E1,FA,19,5D,18,A2,9C,0F,51,5E,2E,00,FF,A0,86,F9,BE,55,9C,AA,25,CD,50,3C,96,87,87,3B,41,74,56,85,68,5A,A8,60,E7,C2,10,0E,42,DF,BA,3A,74,B5,51,ED,BD,5B,74,1B,DE,20,8D,03,B8,09,B9,D0,29,54,5D,6F,C3,B0,7F,07,21,16,B2,54,FE,FD,47,8B,8E,9C,D9,8D,23,85,5F,EE,84,6E,FA,98,CC,D0,B3,91,F5,F8,49,46,9E,5F,82,48,65,74,6B,CD,96,AB,3C,0C,F5,94,34,88,E4,2D,C6,96,93,D2,61,73,B2,8C,D2,1E,7A,47,10,C4,BE,B8,49,38,41,D7,6F,C4,66,81,50,BF,44,B3,A8,72,EA,9C,82,13,52,DF,CF,7F,BC,7B,09,A6,7F,63,60,D4,DA,F6,55,CB,0C,FA,95,7C,3B,3D,C7,92,46,DF,97,DA,BD,9F,D5,6C,04,90,41,87,5E,06,34,F8,6B,16,3B,B1,E3,DE,91,6F,68,C0,F8,F4,9D,C5,92,18,68,2F,09,D2,5D,D8,EB,0F,1A,1A,1F,E0,04,59,09,16,84,71,23,21,5D,9E,A5,5C,C0,A5,2C,49,B9,7E,48,75,D6,1E,F5,EC,66,89,0D,F9,C0,EE,16,65,F4,EC,A6,C3,8A,2A,52,B9,C5,23,BF,A4,F1,C3,C0,AB,ED,77,A5,16,0B,28,6C,3D,DC,E1,E2,55,AC,30,7E,C9,34,DF,98,07,9D,2B,8F,DF,A2,08,4C,E1,C1,F5,13,01,55,49,19,3E,55,BA,67,FC,94,AB,BB,BC,CA,8C,F5,3C,F1,06,35,61,F6,DE,2A,8D,6A,07,F5,E3,A2,DD,75,69,96,EB,49,B8,1E,64,35,A1,E2,DE,FC,3A,AB,1C,42,21,3C,61,20,7F,C1,84,96,78,D8,23,1D,27,48,7D,44,E5,4F,72,B8,5C,48,7D,27,42,95,32,AF,6F,D0,2C,89,13,EB,45,CF,BE,6A,81,47,A5,5A,98,C5,61,36,EA,EB,60,8E,75,DA,E4,89,4B,5F,23,D8,73,69,AF,33,00,B1,C8,31,A7,7E,9C,49,86,CF,26,66,70,63,C6,3E,AD,D7,4F,88,75,6E,2C,3E,D1,80,8D,F8,E0,1A,AA,E7,15,7B,A0,FA,F5,26,0F,3E,BD,14,BB,BF,A2,52,DF,4E,95,18,8A,15,C2,73,BE,7D,4C,C6,A2,22,12,AF,D6,0A,0A,DC,93,43,12,B1,55,D3,83,E0,DF,39,62,90,A4,78,9C,CD,9B,E1,44,87,A0,61,BA,CC,2D,92,EB,7F,39,40,65,F4,05,FF,6B,F9,73,E6,FF,65,92,A4,38,E9,9E,ED,DB,37,E4,47,34,45,2C,17,98,5B,C6,04,A1,05,7A,7E,0A,13,BA,39,4A,ED,36,DB,BC,F2,04,08,29,A2,EF,60,9C,D6,45,AF,DC,4F,C2,97,B3,3E,62,E3,E6,D4,6E,BA,44,7E,8E,AE,47,1D,D7,0A,04,68,4A,B4,98,23,04,96,0C,9D,21,AB,80,F1,0B,F3,52,1E,DF,FD,99,3B,88,31,06,D1,B6,49,6E,8C,2C,A0,B5,EB,2C,BD,12,F4,91,7F,B1,21,B9,AB,5B,28,86,A3,72,FA,E3,37,9A,0A,1D,D5,C6,3C,E8,A9,7F,00,F2,62,BE,F5,66,50,DE,25,17,59,DD,AB,9A,32,FB,3E,E7,21,4F,1E,65,5F,D4,2C,7B,75,B1,79,B4,22,13,8D,50,68,54,B2,B2,C3,98,D3,ED,36,95,B2,A7,49,CB,0C,42,B9,39,F5,D2,27,9F,7F,00,A9,DB,88,0C,23,4A,C7,27,3F,70,50,19,C2,DC,95,5C,0C,79,F4,03,0E,E1,5D,CE,51,C9,D5,A7,48,D4,27,B6,EE,6C,CB,21,D0,CF,79,55,39,66,AE,82,39,CB,C1,FD,1D,62,C4,AB,0C,5B,95,D1,0D,14,55,40,89,F4,C3,2D,06,04,21,B6,C9,5F,69,09,1C,86,7F,B3,AE,B2,6D,AD,E8,03,F4,DF,57,BF,30,F6,3D,0B,40,19,A3,5C,73,1C,3E,B9,28,6A,44,77,F3,6C,46,8D,65,58,B0,E7,BF,7F,48,AA,93,D9,97,CF,02,D3,05,49,6E,A5,03,79,B4,68,39,0A,75,B3,59,49,20,B5,83,9C,00,37,CD,56,74,B1,1E,2E,F3,3E,47,BB,78,4E,73,B5,0C,94,38,44,CD,1E,26,C1,64,01,51,51,02,79,B5,C6,A3,4D,D7,CC,A7,A2,D2,41,76,39,E6,4B,A6,4A,FC,C1,1B,BC,D5,E6,DF,85,AC,93,3C,D0,8C,D5,4E,81,80,B4,84,8B,4C,33,48,6F,82,D7,5D,C3,BB,56,5B,C5,CC,A2,E2,55,7B,48,8B,61,9B,46,A2,F5,4A,75,79,20,95,07,BA,0B,06,03,62,DD,5E,BC,49,40,83,FE,66,63,BA,A8,C4,D3,B0,0D,65,24,BD,93,A0,CD,11,D4,EE,BF,DB,BF,90,10,30,F0,01,B4,A8,AB,2A,B6,AF,6E,74,B0,1F,3B,0F,4F,F6,42,B1,B5,66,33,0B,13,04,3C,D2,C3,01,A3,0C,EF,06,F2,A8,1C,BD,1A,EB,4E,F5,64,74,9A,5D,BC,99,88,0B,53,CA,CE,91,C0,CB,88,CB,E7,6A,E8,B0,16,56,F8,6E,EC,42,56,45,41,85,D2,D2,BB,EC,48,9B,0E,27,D5,62,7D,53,F4,61,A4,98,E7,69,EC,BA,E7,E0,DF,D3,E1,33,64,50,08,58,94,C5,CA,1F,A1,FE,B4,68,E3,29,BB,46,44,EF,F4,77,B0,14,31,25,9D,2D,C9,20,47,05,50,FC,22,E7,D7,58,BF,56,5E,1C,BC,2B,39,37,48,B2,B9,E9,78,16,C6,D8,78,EC,81,A5,9E,56,59,15,5B,02,CE,87,CD,06,17,36,EB,90,D8,12,D7,1A,B5,E3,FA,B1,2A,57,91,5A,9A,BD,64,93,5A,6B,7F,64,53,52,96,90,F9,F6,61,B6,DE,AB,75,E7,B1,35,50,33,C7,F3,68,E8,A5,51,59,D2,20,99,18,E2,8E,8D,76,A5,7A,45,0F,31,4F,74,9D,29,52,E1,EB,B4,83,3F,0B,F2,A2,3C,4A,E6,E2,27,75,21,9E,56,08,0A,CA,1A,B2,CF,CC,D8,8E,F9,23,12,D5,BF,DA,A9,B1,C0,F3,7F,0F,B0,C7,5F,23,97,63,E0,91,A6,8E,6F,17,AB,3A,33,C1,E1,D0,90,87,E7,46,83,DB,61,B4,C5,83,E7,43,4E,BF,7B,A7,E4,45,02,B9,61,3E,FA,61,BD,CF,CE,0F,6D,83,17,76,B3,B1,5B,61,CA,61,67,04,6D,EA,A8,7D,6F,32,90,2C,83,68,06,4A,5C,87,EB,4F,0F,64,99,3E,3C,08,1C,60,65,64,0E,6A,AB,61,03,02,A1,A4,65,11,BD,AF,B1,C1,F0,A5,EF,C5,87,E2,CC,9C,96,A5,8B,CB,9C,13,46,05,AE,EF,B1,1B,73,B3,FA,08,CF,34,2C,44,13,B8,8A,01,0E,06,47,2D,D7,EA,ED,38,5C,D7,53,B0,73,3E,15,7D,19,72,ED,3D,32,06,AE,D5,BD,24,26,95,02,3B,A6,DD,A4,FD,AB,28,36,C9,E4,CB,9F,0A,0F,BD,20,CB,45,79,E5,AF,D6,7D,74,21,93,6D,E7,E7,EE,3C,F0,90,00,0E,0B,87,2D,BD,4A,2C,28,E6,38,6F,8E,83,D6,1D,CC,11,C9,BE,23,A5,40,6E,B6,8F,C1,F2,8B,54,8E,F0,20,0D,14,A1,C7,9A,0E,51,37,4C,B5,72,24,BD,F0,F4,D7,4D,D6,04,E1,BE,E2,2E,2F,31,89,F0,C7,ED,37,3B,34,8E,49,86,62,10,28,3C,C4,18,F2,11,6A,E4,AF,3E,76,D2,6E,2E,AE,8D,F6,5A,80,9C,C9,1E,20,C7,0A,61,1C,E0,3B,60,4A,04,0A,EE,78,A6,81,D6,3C,01,8E,68,56,3C,9F,57,03,F0,0E,AC,83,04,D1,42,26,8B,8A,E0,32,1D,62,27,28,F3,24,04,5A,C6,29,39,F7,6F,6D,21,04,FF,CE,98,42,E2,FF,89,BF,05,41,AF,05,EC,ED,EC,30,8E,78,1C,A9,D8,B7,56,EB,44,67,CC,68,A5,90,C7,FE,B2,54,4C,A0,15,EE,B3,69,E2,25,EA,A9,5A,A5,F6,B4,A8,66,B4,8A,86,25,81,A2,98,00,70,C3,8C,EC,E0,4F,DB,E4,B1,68,42,AD,1A,8B,5E,42,E5,51,0B,F6,CC,20,F8,93,F3,A2,A2,86,FF,F8,90,94,D9,DA,56,D3,AD,A1,45,CD,A6,DB,D2,B2,FE,53,A4,98,FD,4C,80,72,98,8B,02,7F,6C,3F,2E,8D,E8,1C,0D,EE,EC,6F,4E,B4,D3,E5,96,84,99,41,64,9C,26,10,E6,B6,61,B1,58,B1,2A,10,34,CD,7C,04,93,BB,D6,93,13,DA,8A,1B,9D,05,3D,DE,AC,B8,9B,0F,D7,2B,75,F7,87,9A,FA,D5,55,15,72,AC,B7,F6,EB,FE,C2,E5,6A,4D,1F,85,7F,2D,4A,F7,CE,C3,29,1A,67,78,48,F5,66,13,03,78,40,E4,57,A1,EB,92,03,45,70,98,00,C6,8C,AA,67,29,21,41,24,01,A4,07,C4,D7,5C,F6,40,AB,BA,E1,BC,C4,FE,80,00,7E,3C,FF,5F,77,77,9E,98,CF,C0,16,8F,19,8C,BF,64,3D,D4,A1,BA,D4,99,2F,F1,6F,67,97,D4,6E,8E,BD,86,8E,CE,8A,45,AC,6B,4D,2C,1E,2D,C0,7E,4D,89,4C,05,96,41,BD,64,AE,F5,C7,B0,B4,7C,96,CA,17,1B,4C,DC,B8,B1,32,AE,47,8C,F4,E9,E7,A3,7C,0B,82,14,B3,68,AB,59,01,B3,F6,23,7D,55,40,07,52,DE,48,6A,AA,72,D0,F9,AA,FD,CF,D5,B3,08,62,BC,1F,3B,D9,F9,59,FC,14,42,44,94,92,C1,25,F6,CF,A1,C1,93,1B,FF,28,03,49,89,A5,8C,B8,E9,5E,8F,9C,7E,9D,B4,05,4A,D0,C3,BF,C0,A3,46,76,A4,90,F0,AF,36,AE,1C,EF,94,94,B6,9B,54,AA,FB,6D,66,60,F7,09,AE,96,BD,07,CA,A4,67,7C,72,6F,6F,EC,8F,0B,D0,82,BA,91,59,71,88,27,1E,8C,91,28,E3,DE,DB,2D,4B,FC,4A,BF,A7,24,20,E9,0B,1C,CE,1C,B0,E9,04,BC,66,20,78,A2,BA,8E,DF,5C,9C,3E,94,CA,A5,9D,BE,6F,E4,7D,EF,56,19,82,56,0B,23,65,73,33,16,75,69,85,A8,91,47,F8,1A,E0,C2,98,19,F8,4E,E5,6A,64,E1,56,13,FC,D4,73,14,32,A0,D0,1D,64,48,37,DA,34,8F,3A,30,F6,DB,20,DB,60,E9,D6,1C,E4,13,F9,DB,B2,6E,D6,D3,D4,E1,E1,10,2A,4A,3C,11,C9,9D,F9,16,91,A1,7F,0D,92,FB,FC,5F,2D,1F,71,59,EF,FC,7D,1F,CD,E8,64,2B,A3,43,68,8F,6B,E6,99,4C,84,D9,AD,C0,EB,4A,EB,FA,26,EC,50,35,80,1B,AA,3F,2F,3B,66,5C,3A,97,AF,12,FD,74,9B,4B,77,04,3D,54,00,43,F2,79,69,FF,B7,81,05,6A,E1,20,7C,FA,9D,57,7F,F7,7C,CA,F9,99,F7,A9,3D,2D,AE,02,67,7B,C3,71,5A,65,6E,EC,B4,DD,C3,07,CF,54,F7,20,FE,42,10,C2,4B,E5,AC,F4,F2,90,2B,CD,74,5C,8F,C8,86,07,5A,9D,D5,CD,E0,85,A3,E6,5D,20,28,96,E0,04,A3,52,D4,F5,02,8A,CE,87,42,D5,9E,D7,D1,A9,75,EB,D9,D6,59,DB,AA,8F,1B,0B,C6,4D,7E,6E,CC,DA,3E,EC,EF,97,79,C2,B9,A2,BF,66,6D,C4,A5,FA,71,86,8C,D3,D1,F7,59,53,13,63,C4,14,FC,7F,6B,4A,45,32,DA,49,64,42,DC,10,EF,BD,3F,8D,3C,C3,1A,0B,66,46,5A,70,8E,3C,38,98,31,8F,40,57,0A,A8,E3,BE,C3,FD,71,9C,5B,D1,B1,AF,B1,66,D3,93,DC,C1,DE,B5,84,BA,70,F7,68,01,9B,1C,79,31,22,2B,F2,B6,88,1E,02,02,D3,BD,E3,0E,AE,95,EA,E6,DD,C0,FA,4C,B0,06,C8,3C,3F,DD,A2,09,B9,F3,7B,7B,0E,D1,ED,69,15,10,37,ED,5A,BA,0E,7F,BF,D8,23,92,B7,CF,57,03,2E,E8,9F,2E,88,66,FD,F6,06,C5,CF,95,E7,CA,71,BE,CF,23,8C,25,CF,AA,AE,D2,4B,9C,7A,59,4B,49,D9,23,D2,FB,54,C4,5F,57,64,48,1B,E9,3E,AD,94,9A,90,00,91,4C,67,92,C4,26,AF,B6,97,7F,79,A4,11,5B,0C,BF,15,47,54,51,1D,05,BA,77,EB,69,E6,84,EF,73,E6,2A,DA,D4,80,45,A6,ED,0A,DB,6A,06,0C,6D,A7,00,04,69,98,F6,60,EB,D9,52,E9,5A,FE,69,EF,93,A7,19,94,43,C1,89,B4,F0,ED,4A,F9,40,61,D4,10,2F,63,82,86,60,B5,22,F4,AC,30,75,93,BF,60,9D,B8,B9,2E,8C,1C,17,FF,81,B3,85,61,87,BE,13,65,1B,5C,5D,13,A1,8B,5B,09,5C,FF,D6,06,C0,81,8E,59,62,53,D2,65,DA,A0,BC,0E,B4,83,99,D9,3F,3A,F1,DE,EB,BD,49,D9,63,12,37,95,DE,BE,C3,1B,1E,41,5D,93,3F,E8,41,F6,3D,9A,2C,96,66,B9,FC,D5,5A,8B,EF,FE,C5,71,CF,57,1B,05,DC,AD,D6,EC,87,AE,E7,C7,78,80,5E,D6,35,B6,54,99,C2,93,87,D8,A5,50,67,E2,20,D9,E2,3A,BA,76,77,0A,A5,9A,A5,60,E9,EE,23,06,CE,13,98,D4,B0,A1,F5,AE,77,D9,1B,F0,BB,08,B5,8C,91,79,11,D9,3A,17,F2,CF,20,D9,00,FD,38,0D,EF,12,95,D4,56,B6,7F,09,F7,93,4C,20,CC,CD,12,05,CB,35,9E,B1,4E,95,15,5B,A3,3E,07,79,FE,6A,5C,16,E2,28,39,66,10,79,9F,E7,72,D8,BF,6D,74,B6,F6,C9,EA,46,35,E5,1B,3C,87,F4,0D,49,2F,FF,21,DE,2B,A1,0D,74,2B,37,C7,27,22,F4,4D,1C,BE,1A,1A,A4,0D,6E,80,0E,AD,C1,D0,61,1F,79,92,6E,55,4B,8D,00,B7,8D,4E,FE,DA,19,05,18,02,CF,E5,80,A9,47,7D,BE,55,49,5E,97,12,C6,01,E3,1F,41,CE,FF,9C,CF,B4,40,D6,76,45,F4,00,3C,3F,75,A1,F5,46,79,A8,E9,43,A6,52,0D,1F,7D,45,A5,B5,C5,27,DD,27,01,E7,D5,4B,B5,21,B6,81,CE,9F,BA,5B,8B,DA,F6,95,25,84,E0,C8,18,AB,19,C5,A5,EC,E3,98,4D,31,60,F2,CF,FD,F5,99,B2,91,DE,17,DE,5F,D0,B1,6F,5F,D1,00,C1,31,35,FE,45,7D,D3,C4,F3,28,31,4D,45,1D,33,94,43,E9,12,76,2E,E9,0A,15,21,42,68,EE,30,D6,6D,28,18,3D,D1,0F,79,A7,57,83,C4,D8,61,23,DB,B1,E6,B4,25,FB,8C,A5,C9,40,25,2D,90,7E,F4,B6,71,06,FF,9F,50,44,A0,82,E0,79,6B,11,73,0A,B4,8A,BA,28,E5,8B,7A,A2,73,4C,62,CC,B2,C0,BF,C0,CD,D1,E0,F5,82,41,14,5D,B5,E8,AA,06,F1,4C,9C,13,C3,74,84,DC,5F,BE,4D,65,64,22,06,EF,9B,53,84,67,66,FE,EA,B1,75,17,D4,DF,C9,C3,88,53,AB,97,F3,EE,9B,9E,7F,37,99,8D,96,59,D3,06,A0,B3,E8,5F,1F,48,B3,1C,C1,B0,BA,7B,1A,89,F7,40,32,C7,AE,A7,82,AA,36,37,64,DC,D8,F2,85,EA,49,C9,F0,49,B0,56,38,1C,CA,37,CC,9D,38,7D,84,20,65,F1,C5,5B,97,97,E4,09,00,E3,40,29,B3,8F,F5,AE,3F,5A,30,F4,DE,9F,31,4C,0C,3A,68,6C,2A,D1,52,3C,E4,70,16,8F,4F,EF,4F,E6,C3,FA,09,C3,7F,5E,3A,7B,46,0A,3B,98,19,A1,4D,6D,72,C9,7D,71,46,AC,5C,93,56,93,A5,EB,FC,CC,4E,DE,DE,68,15,5B,4F,66,9C,21,58,56,E7,8D,68,0F,FD,48,46,56,ED,99,F5,BD,91,F8,A4,56,DB,AC,0A,B3,15,DF,26,FB,B7,F0,5E,5B,9E,3A,0B,6A,2D,B5,94,EE,31,78,C9,33,6E,89,B0,BC,C4,72,57,5E,0D,72,B7,5C,2C,7F,9D,29,5C,FA,33,C8,2E,BF,E6,0B,50,40,E3,8C,D3,7E,59,4C,73,E3,9C,6C,7E,07,2F,3B,EB,3B,ED,28,3A,CF,91,56,20,82,F6,A4,B8,65,8A,77,AE,0B,AC,5A,34,54,95,A8,98,AD,DE,11,AA,F7,32,AF,95,7D,41,75,9B,56,47,6B,22,71,CC,69,11,03,92,38,96,A1,42,13,B1,BA,AB,A5,2F,39,2F,12,FC,D8,77,3B,A9,E6,1E,D8,0B,17,96,AB,C6,65,F9,F4,53,CF,FD,D2,DA,5A,44,0F,E2,57,F1,FB,5C,60,B9,8D,60,4B,4E,6E,AA,13,9C,A2,3D,57,D6,8D,10,D9,AE,13,B3,A3,49,13,4B,41,C1,62,51,6A,28,DF,A3,01,96,EF,1E,77,DE,1E,C5,32,05,46,EB,91,DB,73,44,E0,F3,96,D5,77,C4,93,52,A0,E8,E6,00,D0,FC,2B,72,9D,56,6F,E2,14,EA,C1,EB,B2,C0,92,4E,BC,C2,93,54,AE,06,CF,4A,C5,6B,E7,BF,1B,CD,D4,DD,FB,E2,07,82,84,7A,6E,27,32,0C,14,F7,DA,A6,70,D3,AD,61,A7,46,49,A4,E3,44,D7,79,0A,78,7C,A8,2B,91,48,0A,4F,01,46,73,C6,E0,1D,8F,0A,03,BF,AC,23,8F,C4,89,53,17,4B,7B,3F,70,87,1B,F3,E3,5E,0D,FC,E5,3F,E4,21,9A,F8,D8,38,C2,B0,31,3F,3D,89,9A,70,CB,21,C2,8D,9B,43,03,57,9D,55,98,A8,E6,E6,D4,44,D0,EA,D3,98,F6,E5,B8,4D,94,FD,74,BE,06,F8,7F,1E,4A,1B,72,DF,0A,3F,96,E0,A0,10,8D,CF,68,4D,9E,B7,C5,44,1F,80,CD,75,AF,CA,0B,9A,88,31,60,CC,25,F5,A6,D3,F3,B6,FB,BC,6E,B2,C3,19,A5,94,B2,82,81,0F,F9,74,FB,9D,72,0A,93,1F,58,9F,23,5E,F3,97,0E,50,E8,3D,A6,23,E9,55,98,D3,48,68,E6,E3,47,7F,5B,D9,79,C4,FF,46,B4,84,97,37,AF,3F,DE,98,E1,4F,CC,08,BC,83,03,F9,6F,5C,4B,B0,28,A5,EA,CB,EA,09,41,7C,71,64,81,4A,A6,63,25,F6,90,99,9F,03,5D,54,AB,F2,52,F5,08,E1,50,26,0C,56,7A,0C,B8,2B,A1,63,70,01,C9,EA,43,60,CB,4B,C0,6D,95,80,D4,1D,BF,F5,E0,2E,19,EF,C2,32,00,96,D6,B6,C3,6E,44,D0,41,91,FD,E2,69,10,8F,F4,31,91,B9,D0,2D,7F,B6,0D,92,BE,57,CD,0C,B5,B8,10,9F,BC,7C,F0,B8,9C,8F,92,EF,78,EB,97,6F,8E,8B,F9,18,DC,8B,23,EA,21,EF,3B,93,CD,4F,26,EB,C2,CC,49,A3,8A,E3,3C,28,20,24,29,6E,3E,70,76,ED,81,1D,AD,A5,E2,72,F6,19,9D,A2,1E,DF,A2,3A,57,92,DD,F7,EA,B1,71,85,29,7D,E4,7A,19,99,D0,21,20,0D,D7,13,EC,9F,C3,8D,4E,1C,68,99,9E,0A,5B,D5,FD,4D,71,98,53,2D,7A,DE,B8,79,AF,8F,F2,17,57,D1,55,62,A3,9C,4D,D6,00,F0,5C,7C,61,B4,33,F2,14,1E,CF,38,F5,1F,A3,59,91,5E,18,08,F5,A7,09,D8,94,D3,01,74,43,7E,59,EF,DC,B1,F8,7C,2B,19,6D,73,B4,10,50,4E,CC,9A,53,7F,C1,9A,A0,F9,6E,FD,55,9C,4E,C7,4E,A4,C0,17,44,1B,DF,88,3C,5C,01,14,6B,05,F5,B2,22,E0,42,83,F1,AB,DF,3B,08,C6,66,54,24,4D,A5,B2,C5,C8,77,AA,96,1E,D4,94,D3,77,D0,9C,E4,E9,5B,68,F6,D6,27,6C,46,6A,DB,4E,67,C7,E6,7A,86,40,5B,B5,6B,B2,DF,97,C9,A4,62,95,25,DF,DB,74,3E,88,B8,54,58,84,21,8C,A9,4B,58,18,CB,AF,71,DC,DD,CA,D3,7B,CD,8E,E4,0D,E0,39,4F,8E,0B,9F,BE,76,94,9D,C4,7A,40,3A,B6,6F,77,03,AF,BF,CF,CA,63,79,D8,EF,8B,8E,6E,2E,56,DE,90,66,4A,36,0F,1B,16,A3,1C,8E,7E,BB,5E,69,EE,22,4A,AE,18,1F,CC,89,5E,D7,DD,39,CF,F0,0B,50,82,42,56,F1,54,4B,A2,8D,B4,91,0E,22,04,2F,EC,79,A6,30,E9,F9,48,D2,26,2D,E1,F5,5A,0A,C5,34,30,93,AB,6C,31,0B,62,61,F4,F9,73,2B,1D,DA,53,24,54,D9,B6,06,E8,83,43,4F,06,BA,B7,8B,C5,68,40,88,B4,D5,BB,85,03,36,45,2C,DA,7F,C8,C8,B2,43,86,12,AE,E6,BA,E1,94,4B,71,25,80,00,58,71,D0,16,02,5E,0C,69,D6,4B,BA,F1,CF,4B,B8,B5,13,6A,4B,DE,62,07,ED,50,19,14,61,13,01,1E,28,19,F1,2D,1B,D3,7E,8A,7C,A2,95,F6,01,5C,02,D2,4E,25,CD,CD,37,24,20,B0,E0,5D,75,7C,6C,7F,51,EF,FB,A2,81,AF,11,84,C0,6E,B8,63,2A,A7,25,F0,9E,38,93,D6,7B,3F,FA,56,00,AF,B1,87,F8,5E,D0,3F,3D,B7,40,6F,55,C0,C1,B2,07,B3,5C,91,BE,BA,D6,1F,59,D0,0C,1C,DE,E8,20,B9,91,FB,CD,DF,AE,0D,71,ED,F9,CC,64,23,C9,73,51,C2,1C,3F,31,30,AF,44,9F,8C,FE,5D,FE,E5,91,AA,74,D3,75,24,59,C5,0B,05,1E,FB,A9,0F,3A,DA,EB,E8,A5,FE,6C,15,22,E7,5D,A1,60,F9,F4,FD,F0,39,10,ED,8E,6E,82,58,DE,AA,04,66,75,C8,E2,B2,E1,A1,71,D5,8E,53,B6,85,12,FA,E7,C9,C6,44,81,BD,21,33,91,F5,87,1F,69,9D,F2,46,DC,B4,01,B0,AC,C9,78,57,3C,6B,D3,52,81,28,0A,F7,B9,82,F9,89,6C,73,2D,70,B3,2B,F3,78,1A,D5,E4,C8,F8,72,8C,59,97,F8,38,3E,D7,62,8F,30,9E,0F,C8,EC,30,EE,11,0C,70,34,93,3B,DF,52,B9,34,22,80,5D,00,4C,5E,6C,87,5B,64,DA,04,87,30,F6,C3,5D,E8,B3,34,7C,F2,9E,7A,67,99,77,95,22,9A,B9,42,D5,05,F3,8B,24,DF,6F,B4,9C,22,C7,BB,94,CE,EA,55,0C,27,86,76,79,FB,D1,88,32,B2,26,E8,AB,AB,87,E6,65,44,C2,0E,92,7C,95,6C,25,B1,DA,8E,A6,41,7B,89,DC,4B,C4,9F,A8,25,4E,68,5F,4C,E8,F5,B5,C9,FE,C9,64,12,09,3A,DC,E3,7A,09,8A,C5,01,44,EE,37,B6,58,98,3E,24,18,F7,D4,E9,8A,49,64,5D,86,E8,76,F6,17,41,6D,5F,29,0A,8E,32,20,63,8F,26,E3,3B,F5,F7,30,93,1F,2E,BB,72,66,72,16,98,9E,28,45,D4,31,7E,F6,ED,9E,C8,D0,87,72,97,29,9F,1D,3F,70,E0,78,C2,52,9B,ED,49,6D,5C,69,60,81,05,72,72,B9,D7,05,46,85,77,46,C3,9E,0D,AB,CB,7C,FA,D3,32,1D,1D,0F,AF,5E,ED,1D,B4,D4,C2,53,86,60,CB,55,51,32,98,EF,85,02,BA,D4,A4,06,95,BD,AB,53,6F,6B,62,96,DD,D3,EB,B3,75,DC,58,00,12,09,47,0A,60,03,53,29,7D,4D,D7,FC,41,59,CE,22,54,96,AD,22,D7,1A,26,A1,14,F3,4A,05,A5,67,D8,C5,CB,A2,EC,2F,7F,4E,17,59,2B,48,98,59,D2,67,9C,FE,48,A2,3E,C0,04,6B,20,D8,D7,C9,EC,96,57,C4,BB,CE,F2,AE,B0,81,9B,36,0B,D0,C7,67,E6,EE,48,CE,45,C4,B7,1C,3F,AB,FF,73,C4,14,7E,90,5F,25,7B,B7,AD,19,37,E9,67,CA,EB,FA,28,DE,4C,E2,CB,0E,CC,C5,36,98,7A,3F,BC,58,F6,B6,C6,84,79,DF,7C,96,93,48,0F,BF,F1,9A,08,76,51,6F,F4,F8,4B,CB,2E,B9,01,92,4A,BC,77,6D,F2,4C,D1,00,7D,B9,FB,74,75,84,1A,CA,32,53,3A,B1,9B,14,98,3D,29,FC,BC,80,18,F9,65,84,80,C5,B9,29,2A,48,08,16,BF,0F,06,E1,07,63,DD,90,53,5D,F6,2F,50,C7,8D,26,B3,E7,1B,2F,B4,C3,58,F5,70,32,83,49,77,04,2F,19,B2,BF,23,2E,69,F8,ED,22,D2,7A,9F,45,D6,8F,24,05,B7,CA,CF,E0,3B,78,27,13,79,B2,F5,10,DD,7E,0D,84,F2,85,3E,1D,E9,24,05,69,86,8E,C9,87,FE,99,EE,B4,FB,21,F5,FE,31,B5,3C,84,F1,7E,6D,EF,09,6C,AA,E3,E4,17,F2,3B,D9,01,51,49,F3,EA,6C,5E,13,92,44,3E,60,AA,26,8E,C2,A3,54,EB,62,E1,22,C0,27,25,F4,34,20,28,23,AB,A1,86,5B,C8,16,77,4D,80,1E,D4,23,D3,16,A1,9B,17,25,C8,44,82,04,C4,75,AA,8D,BE,6F,49,86,CE,30,C9,51,67,A4,2C,A9,8F,C8,BA,5F,DA,18,89,FF,E9,D8,D9,D6,02,D1,D1,50,E4,EE,9E,8E,E6,53,32,86,3B,EE,3F,BD,72,16,1B,45,5F,98,DF,EF,B2,50,FE,BA,01,B3,05,99,1F,E3,DC,34,2B,51,9D,46,44,76,5A,58,BF,DB,23,DD,C5,58,C0,34,DE,25,9C,94,C8,19,81,CA,B4,48,05,EB,D8,69,84,D7,2D,C1,39,D8,7F,99,13,BF,49,2D,3D,36,31,0B,C9,F5,C7,D1,E5,2C,58,27,BC,0A,98,61,FB,01,E3,8C,24,54,F7,0A,27,22,A3,FB,B7,9A,23,FE,F5,A9,FB,5C,CD,23,D6,70,4C,45,6B,72,43,5D,E9,73,3C,3E,C0,24,6C,F0,11,26,94,EA,46,3D,69,D6,A0,AF,4C,95,8E,8B,77,4B,55,0F,16,DB,EA,3D,A9,CB,72,6E,F3,B6,21,69,5A,1F,2A,AE,85,5F,41,43,E3,54,C3,6C,F5,BC,2D,72,49,F4,3C,4C,73,CB,85,1F,48,15,F9,E4,64,DB,21,7B,CD,46,A7,2E,4C,2A,44,48,CC,F3,70,EB,85,53,46,8C,8D,DA,6B,3B,0E,D0,75,5D,86,01,45,C9,4D,E4,57,5E,0F,B5,9F,09,B2,EB,64,A9,57,9F,70,34,E0,22,9E,48,63,46,71,06,42,AE,81,59,FD,0A,0D,D5,41,0F,B4,8D,EA,63,CB,15,1A,34,F6,20,22,E7,3B,F7,BB,C4,D8,A9,B1,A7,96,6E,D6,F7,FC,15,F7,E4,5A,8B,E1,E9,11,19,A0,CA,86,CE,BD,A0,75,91,C3,6C,2D,E3,29,46,76,9F,67,DE,17,C7,A8,A1,74,CC,5C,52,6A,00,F5,52,5E,19,18,CA,2B,93,90,19,7B,47,50,B4,80,BE,D9,B0,9E,3D,B3,36,B6,59,C9,2A,81,3D,48,4A,CA,1E,81,0F,22,70,55,88,F4,67,A2,E6,93,F4,F2,F6,84,FF,A4,B9,15,8B,93,0C,6C,91,60,1F,CE,B1,34,CB,F4,A1,BA,D4,38,31,57,7E,D6,4D,85,F0,0C,25,73,58,BF,E2,94,D9,5B,D9,44,AA,E4,C6,3F,3B,85,50,DB,A5,4A,1D,BC,8B,F0,7E,38,FB,F0,8D,76,19,ED,EA,C6,5F,BA,28,38,F3,AC,84,22,B1,9A,5D,F6,56,87,C0,18,7E,A4,74,7C,3B,B3,80,3B,F0,38,53,E8,9B,5D,8A,BC,16,EE,76,9E,6B,24,15,BE,52,31,95,97,04,83,EF,19,95,C5,49,31,C7,28,C9,99,DA,7E,E1,18,8D,4A,CB,B2,76,42,7D,26,EA,94,A1,E8,D1,2A,5D,37,FA,6F,FD,62,7A,15,89,7C,EC,56,0B,F6,C2,11,30,88,28,73,07,9B,FA,0D,81,F1,22,C2,52,46,E2,41,B2,5D,66,10,40,BB,40,3F,15,C3,30,15,1C,67,B9,A7,10,6C,4C,83,1D,C7,09,1F,68,50,B9,36,DC,04,44,A9,E0,B3,52,B6,E1,6F,BA,33,44,7B,78,10,BA,11,3C,DC,24,BF,17,C8,EF,2A,41,E9,B1,EC,6C,9A,C3,B3,03,CF,DF,99,1C,C5,C4,97,C3,3D,6B,60,EE,B7,50,81,F2,95,60,C8,15,C1,49,AD,43,02,0A,69,E3,23,C3,EC,C8,BF,86,55,D4,CC,4A,E7,CF,80,63,90,E8,F6,3F,1A,A7,EE,39,48,5A,49,81,E3,A9,37,07,4E,A6,8D,60,50,89,EA,F6,0A,CD,7B,A6,D8,11,1C,0C,2E,CC,F6,2E,68,27,57,1D,E1,36,17,E0,06,99,E1,DD,8A,0E,EC,8D,E1,F0,30,16,1A,29,AD,AC,80,C6,4B,19,CB,85,9E,35,1B,14,25,C4,DB,74,DD,93,4A,84,3A,C9,6A,44,A6,75,08,6F,71,13,E2,D0,BC,F2,2C,F2,3B,B0,C6,22,FC,66,96,4F,29,73,9F,90,77,D6,54,26,BC,26,6F,1F,18,5E,FF,E0,B1,C9,12,AB,DF,BA,5B,EC,85,56,24,E4,EF,7E,F6,A1,15,0E,B2,8E,73,65,77,36,E1,FE,E0,56,3F,56,F2,6F,C0,2F,99,02,CB,1C,C3,38,75,4C,60,58,73,9E,8F,57,9C,0D,BB,FA,D0,1C,AA,B1,18,44,36,F6,31,4B,25,6D,9A,E6,04,D2,50,AE,56,6C,0B,7D,61,83,F7,F9,5F,FF,9F,F8,D3,C7,92,C3,54,7A,D6,9A,B8,B4,CC,52,20,CB,B2,3C,71,25,35,EE,24,AF,79,79,1A,5A,56,AB,C3,E9,BD,7A,6E,EE,C0,DE,C0,8D,42,5E,0B,8E,CB,26,B2,4D,7D,19,C5,09,AD,DC,5C,12,39,CC,16,54,27,B3,96,7D,17,7D,B9,0C,26,D4,AA,1E,59,70,FE,8A,A6,D4,07,68,2E,F5,AA,22,22,93,00,DA,B2,F1,75,73,14,F2,5E,11,60,BC,B2,81,0E,88,46,65,18,39,F5,02,06,23,23,64,0B,55,D1,4B,F0,86,0A,4C,19,FE,8B,B8,A5,F5,47,51,E2,71,8A,2C,22,B5,AD,D8,52,29,F9,26,60,A6,1A,0C,EF,CD,48,8F,B3,26,BB,71,31,3B,D3,95,83,2E,B9,66,2D,10,A0,B2,B9,DC,CA,FC,D7,87,39,F9,A2,F8,F2,64,E0,4C,51,08,87,61,B4,CE,84,7B,4B,5B,37,2E,70,77,2C,CC,14,75,CE,9D,58,3C,DA,93,DC,DC,41,0E,AF,72,4F,92,27,1E,D8,B7,E2,8A,29,30,C0,D7,D4,0C,58,72,09,22,75,D1,9C,CA,31,31,D2,8C,B7,06,77,15,F5,B6,A1,FA,66,47,40,57,2D,7B,0E,FD,0C,54,D0,24,8E,9A,A0,1B,4F,B7,BB,D6,98,70,AB,4C,BF,75,31,09,33,60,84,3F,1F,31,AE,DD,11,76,B7,57,97,A0,40,FE,74,DC,06,78,1E,89,6C,98,30,DF,5E,3D,8F,33,02,46,F9,FD,90,45,E9,3F,75,F9,69,35,41,DB,A1,C3,39,0C,B7,6C,B2,5C,9C,DF,1E,85,60,AC,CC,DF,AE,57,FE,03,D4,50,30,8E,25,E3,EA,68,E4,24,D9,74,84,9A,ED,67,F3,05,D2,C0,4C,E7,75,A9,27,9C,3F,4D,09,7D,01,3F,73,5D,CC,8A,3B,F9,83,FE,BB,10,15,F6,6C,E5,3F,BA,C9,A2,61,C4,B1,24,FF,A7,99,C2,A6,3D,62,58,AB,63,A3,23,76,C2,C2,B7,EB,3A,F5,DB,6F,67,8B,5B,81,22,6C,83,21,25,E7,A0,C9,E8,D5,C1,CA,46,2F,99,FD,A3,3A,A2,DE,CD,1F,DB,DD,5E,97,6B,08,64,B9,BC,B8,C3,A4,18,20,E9,1D,81,42,0E,C2,96,38,BF,A6,8F,32,8C,45,C5,06,BD,64,19,F0,03,E2,2C,1B,A8,E6,55,9C,86,1A,FC,30,54,BD,FA,7D,72,8D,2F,2A,13,36,5B,0C,58,0E,11,F5,99,E4,0F,A3,48,23,FD,43,28,F6,CC,B3,51,CB,58,AE,4B,CF,85,03,84,9C,B8,05,CE,9D,1B,0C,75,A1,43,D0,CE,94,5F,AA,FF,DF,12,F5,48,F6,33,BF,6E,66,22,9B,84,A2,42,68,47,73,39,FD,C8,A4,26,1C,20,6A,34,B3,F4,58,F6,3F,26,9A,13,F4,22,6A,AD,80,9B,B9,10,B8,26,46,C3,17,41,34,90,5F,61,12,E2,19,7C,8E,72,06,B0,87,08,1C,7C,97,8C,02,FC,92,1C,DC,6A,66,2F,A0,FA,7A,E3,8F,13,82,E3,14,06,0C,BC,5E,42,C7,1F,F0,0F,4D,5A,6E,41,CB,ED,6A,D5,75,E3,2E,8C,33,92,DA,88,9E,06,EE,83,4D,60,51,DF,24,80,17,A8,39,9C,95,6D,CA,11,CF,6B,D4,A3,0D,E6,62,91,17,A1,2F,9D,62,EA,92,4E,6B,5A,7E,03,11,A4,EC,26,FB,8C,79,E8,B0,62,25,68,8C,B8,38,5D,4A,6C,7E,98,F3,91,27,84,D1,D8,6B,1E,0E,70,82,FC,45,A2,E4,74,6A,FE,9D,04,F9,BA,8D,16,2D,AA,42,E3,82,2B,EC,1B,65,1F,F1,0D,2A,19,8C,0A,B8,06,B2,04,DD,A8,4B,28,F7,35,34,7D,7A,B2,62,2C,9F,02,FA,30,3A,FF,B3,67,F9,B0,CF,98,77,F1,A5,D1,EB,14,C1,26,CE,0C,94,E4,A9,56,5B,B0,77,5C,C1,B7,55,DB,85,A8,AC,37,20,99,3E,6F,00,FA,DB,55,75,10,A3,5B,0E,63,B8,BB,CE,D5,6F,8D,48,30,BA,BE,D5,CB,92,20,5A,41,C0,F3,A9,F3,88,AC,34,64,75,3F,69,56,41,87,73,60,78,3C,D9,C8,BC,07,E7,8C,B6,D5,71,D2,46,74,23,AF,D4,9D,0F,13,A8,B2,38,94,60,A6,07,3C,ED,9E,74,C3,B4,6D,33,78,8C,53,33,A1,71,C3,D5,A6,C8,A0,E3,33,44,BB,89,09,C7,6C,17,04,51,08,B8,46,A5,9C,A5,84,00,96,6B,62,7E,0A,5A,51,50,C8,02,2B,5F,E6,FC,65,B2,11,D0,BB,2E,98,64,5C,07,05,42,A9,F8,BA,49,28,E5,78,B9,61,50,2E,EC,1F,8C,EE,AC,6F,6C,72,96,6E,8B,2C,CE,D7,09,EB,20,07,75,39,23,C0,3E,A6,7B,CC,AF,6B,E8,7D,F4,1C,41,F4,AB,78,4C,4D,B0,BF,1D,18,44,45,C1,DB,B2,4A,90,15,04,D4,63,3B,09,F9,B1,BE,CE,E4,83,4A,0C,62,90,4F,29,3D,D4,61,F6,3F,6D,16,B5,9F,75,90,20,56,08,36,E5,E5,CA,C3,B9,91,A5,FE,8A,C3,91,87,50,DD,79,DA,83,51,90,DD,03,B0,E1,4B,A0,87,C9,7A,70,47,CC,00,F8,B9,6F,91,17,83,21,9E,E1,94,8B,73,6D,BD,E2,CF,23,C2,6A,CF,FE,EB,4C,E7,7A,BF,21,C3,F7,4F,0B,80,E9,E6,21,D0,F9,62,3E,0B,01,20,38,87,44,7C,B5,6F,4A,E3,F8,BC,BE,9E,AF,B1,86,8D,B4,AC,16,0B,4E,0D,6A,BB,33,83,B9,29,E8,31,3D,35,15,08,08,20,49,BB,5D,F1,13,1A,91,F7,D9,55,04,0B,1D,4F,FE,08,9C,D4,60,B0,B2,E4,3F,74,F0,D4,4D,14,6C,4D,1F,86,E5,08,C5,B2,17,8F,6E,16,E4,F1,7B,2D,79,F5,B7,A1,DD,1F,9D,07,41,D0,22,D0,C5,33,FE,7E,84,3F,3F,F8,21,BC,42,D2,E5,39,2C,B3,26,94,B1,6E,9B,37,C9,F7,E1,FF,29,3E,6E,98,F8,9B,CA,98,DD,DA,76,8E,00,79,CC,EA,C3,9B,18,90,D3,95,8A,CB,5C,49,DA,20,0B,B6,A7,92,D8,FB,3E,CD,09,AD,EB,52,26,8A,AC,DD,AD,13,C9,99,F3,19,F9,28,C6,0F,1A,E6,CB,7C,66,85,E5,BB,EE,B9,78,7D,C7,B1,92,CA,DC,73,3C,13,82,FC,6E,A3,54,5A,29,2C,30,80,BF,AC,1F,88,C3,D2,D7,DE,0D,D2,8D,1C,55,5A,84,CC,82,B7,33,43,8A,DE,A9,1A,BE,F4,FB,1A,04,67,E4,7C,B5,5F,23,9A,E4,7D,50,0C,79,CC,28,D0,D2,69,37,50,BC,DA,BB,5C,DD,1E,21,3C,0C,33,B9,BB,F7,5B,82,5F,51,C8,8D,98,B4,75,B8,89,04,CA,3D,71,F2,5D,A4,E3,61,39,4B,BC,9A,6E,4F,97,EB,EA,BD,62,52,EC,5A,A8,0F,88,BF,FF,D6,2F,E8,17,88,5F,BF,6E,0C,EA,A3,B8,87,75,09,2F,FC,C5,08,C1,FF,44,33,F3,C0,E0,F6,94,34,C7,6B,BD,59,1E,B6,78,9A,82,0C,73,76,03,D0,01,D7,C0,F1,29,74,2A,30,B0,9C,39,20,C8,52,F0,F9,DE,36,3E,A4,15,85,37,EC,3F,C3,2E,4E,0D,A0,2D,EE,73,08,28,4C,33,80,26,3A,07,10,C4,27,56,0F,F8,50,76,62,1F,22,30,F1,B0,D1,BB,CA,65,7F,F7,1D,18,C5,C6,AA,16,C5,A5,48,8F,CA,26,C4,AF,28,59,9E,79,EE,7F,D9,82,D2,06,77,0D,17,89,B5,9D,C8,E9,0A,92,BE,65,2D,20,A2,6F,12,B9,1C,73,14,FF,87,97,01,12,73,39,C7,96,92,52,69,85,A5,FF,6F,E7,44,0E,D3,16,44,C3,AB,D0,CA,2D,B0,9E,CF,E3,EF,6C,88,45,9F,89,CB,3A,35,25,AD,36,FC,43,43,16,1D,D4,55,2C,C9,E7,5C,B0,2F,F6,9B,66,F2,2E,15,77,72,00,5F,35,E1,EC,05,07,7F,30,F6,66,2E,9B,05,58,1E,6A,69,C6,B0,B6,EF,6E,5C,E6,E8,6C,57,6F,C9,77,C5,4D,A1,B0,52,42,C2,E4,20,97,94,AC,06,3E,B3,0E,A8,E0,3B,B9,C4,78,5D,C0,A8,09,AC,CF,76,11,A5,87,E4,0D,EE,61,27,05,1F,44,A8,E0,28,75,81,DC,BA,F7,CE,58,1F,2F,35,81,F2,E4,C8,EE,CB,25,D3,A9,87,75,4D,E3,74,A4,55,E4,3B,0D,82,57,FD,36,E0,B3,DB,80,FC,CC,B7,C7,10,24,DF,91,1D,46,09,79,9C,31,4F,60,3C,32,6C,BA,D2,BA,24,4E,4F,F3,0D,F5,4A,1B,68,0D,AD,C8,A2,6D,89,60,0E,AF,68,C2,2D,12,D7,D2,1F,25,3A,FA,73,F7,60,B2,CF,9E,EA,68,0D,03,6C,93,12,B6,3F,7A,5C,C1,38,02,DE,90,65,E9,29,99,3C,4A,33,42,01,EF,5B,40,DF,19,9E,51,50,85,8C,FD,31,AE,87,24,E1,43,67,4E,BB,4C,DF,6B,17,C9,69,F0,F3,20,7D,16,C9,FC,D0,A0,F7,E7,56,35,63,21,AE,B0,9E,D4,AD,69,E5,F8,85,76,1B,B5,28,BF,C5,D1,9D,38,43,23,AD,83,38,16,73,72,0B,D5,E0,0F,C8,02,33,59,7D,E1,18,D6,24,0A,F5,EE,AD,DD,58,3D,0C,05,1D,F8,A9,B4,1C,E8,69,FD,1C,A0,3F,D5,ED,8F,FC,D0,77,D6,01,7B,13,73,CB,9D,26,8D,38,06,7D,0C,A3,CC,B2,9D,02,CF,D2,D4,E3,5B,59,D6,E4,7D,0D,FB,AE,77,54,DD,1C,F3,26,34,C5,7F,4F,20,CF,13,D5,BD,DD,33,90,A0,FB,B0,8C,CE,EF,CE,F6,83,31,CA,23,56,CD,6A,23,3B,DA,A1,A1,6C,B9,B7,4E,7B,72,8C,CE,0F,C5,66,D9,0C,D9,8A,20,88,D4,EB,38,19,E0,93,7E,12,1F,34,C4,8E,88,63,1B,2E,41,CD,B1,2A,76,81,99,D3,E6,47,79,D3,F3,3C,56,9A,4E,A8,87,F8,EA,BE,56,41,AE,CF,65,5D,DE,D9,B8,B3,86,DC,BA,03,1E,67,E1,28,9B,6B,8B,50,48,64,6D,51,F6,9F,5F,83,84,99,62,0C,EC,6F,9B,89,39,67,1F,18,EE,43,DA,AC,E6,EE,63,5B,67,F3,25,EF,BB,3E,C8,DE,81,17,35,E7,BE,F0,9E,45,35,F0,A5,55,42,57,3E,48,19,D9,A2,F6,7D,D3,F0,F9,F9,C4,10,AE,71,FD,30,DD,BA,4B,9E,2C,BA,2D,6A,17,D3,CF,A5,E2,86,F8,7D,13,BB,D7,65,F4,24,CA,98,47,1D,5E,0A,01,2D,F2,97,07,CA,A2,8B,C6,55,A3,76,2E,C4,EF,0E,19,7F,28,50,74,DD,C1,E4,B3,9B,D8,36,80,59,76,82,55,9A,86,64,AA,EB,D3,34,7B,12,67,76,77,EA,5C,11,A6,E3,6B,52,C4,33,F3,51,11,0D,2E,4E,C0,9A,07,86,ED,F0,A3,AE,43,94,09,FE,B4,33,38,E6,5F,11,35,D9,7C,56,F8,CE,71,9C,32,B6,8E,68,E4,61,A4,BC,E7,74,1A,25,F2,F4,78,1B,12,9C,F4,2A,78,67,21,EB,7B,F4,5B,F6,E0,88,A3,44,EE,C6,B6,EF,53,8D,C4,32,30,95,1A,72,86,F8,5F,0C,AF,D5,52,B1,81,C5,03,D3,D8,E0,F7,F4,1F,9A,71,DF,D1,F9,C1,E5,FA,5D,B8,9C,DA,2A,31,EB,6B,1A,D6,A2,07,25,F9,D9,7B,07,8B,3D,52,40,B7,AA,B4,A5,BB,17,B1,DA,FA,2C,A2,93,C6,86,9D,2D,7A,56,31,65,BA,5A,77,4D,CC,89,22,91,DB,39,6B,C2,11,E7,6E,59,C3,CA,50,9F,A9,D9,D5,32,50,4F,0F,3E,62,26,7C,38,92,13,69,79,DA,5D,53,D2,AF,7D,EA,82,98,04,D2,84,D0,61,6C,95,A9,0F,D5,EA,3C,FD,9A,9F,A2,AE,9A,AF,2F,0E,66,47,FF,2D,ED,41,29,85,DD,A4,AC,15,F0,90,0B,8E,6E,DD,F0,8A,E9,33,9B,C6,18,16,E6,A4,50,19,2C,B5,96,A7,67,08,79,26,7A,91,25,97,0A,7C,35,30,A9,EA,87,A0,76,E4,CC,44,0A,28,7C,FE,95,26,D9,7E,20,01,D3,54,48,B5,E8,1D,85,B4,24,CA,A8,1B,86,5F,97,98,6C,84,ED,D0,74,27,13,98,5F,A0,FE,68,0A,94,3F,92,E0,55,DF,8F,93,FF,66,32,15,65,C2,41,C4,FD,A8,F9,C8,2E,E0,D5,85,AA,64,51,D4,0D,E7,0B,56,D4,F7,8B,8E,53,85,E3,04,17,5B,32,1C,39,C5,D7,53,2B,E3,47,F7,35,F6,81,2C,68,79,05,CB,E8,E8,F6,D6,E0,B1,5D,84,81,84,34,C1,85,F1,39,14,97,1D,9D,64,A7,02,EA,74,F6,5B,F4,E2,20,CE,7D,66,FF,83,9B,E4,FF,7F,E7,20,F6,12,0F,33,83,C6,A2,29,B2,4D,E3,FC,50,94,5A,3E,6B,EB,47,78,78,39,2B,F7,20,AD,F0,25,F1,33,00,AC,CC,3B,21,F7,9D,57,11,3A,91,2D,87,4A,87,B5,73,00,9A,A0,08,5B,36,99,AF,D5,E7,32,C9,16,3D,92,8F,B8,A5,07,78,D9,20,1D,31,BE,8E,F8,3C,C1,0D,CA,26,80,DB,96,12,1E,6C,02,FE,67,AE,09,68,8E,D7,14,22,A9,53,06,DB,08,69,4B,DB,50,D9,F0,1A,BA,C9,18,18,8B,63,A8,1E,E0,E3,79,72,7E,96,34,45,A1,3E,B5,26,51,1D,08,AF,E2,41,BB,77,77,ED,B6,BB,03,75,00,8C,80,68,43,0F,CE,39,BC,0E,4C,98,4B,D8,27,0C,82,3C,3E,43,9A,C9,73,9D,E1,60,88,55,12,A7,55,EC,20,6E,23,10,3E,F9,92,A5,08,6D,D2,1A,53,DB,10,59,81,9D,54,14,B9,8F,37,9B,F0,6A,E5,78,94,20,79,CC,D7,B2,9D,68,24,B5,C1,BF,D4,D7,BC,3E,A6,6F,D5,20,FE,2E,EB,13,BF,E8,B4,68,05,30,FF,6A,56,0E,80,58,D3,01,A9,F4,98,6C,49,7B,55,31,69,DB,CC,A9,87,D4,65,03,52,C1,37,0F,5C,CD,A7,FA,03,2A,77,D5,A7,52,73,E3,9D,71,F3,71,BC,2F,53,2F,34,CF,4D,0E,2F,40,7B,C0,F3,D3,DA,87,BA,C1,4B,ED,99,F8,8B,DF,F5,8D,0F,A5,5E,75,40,A0,AC,07,F5,23,16,3E,86,E9,3C,C5,8E,D4,F9,68,FF,27,F7,8F,A8,0E,7D,AB,49,AD,5B,CD,33,BD,F2,76,28,FE,87,30,3F,B9,5E,9B,A7,AD,8E,7D,ED,A7,87,1F,D7,85,08,31,3F,63,51,D0,94,BE,5C,11,28,01,D3,4F,C2,9D,A6,01,38,D7,83,EC,CB,F5,9E,C4,C3,8A,F8,21,18,C9,C2,EC,0B,01,FE,BB,F9,A7,67,7A,32,85,7E,7A,0E,4D,09,FD,6A,DC,27,39,9E,5E,A7,BA,1E,5C,29,D2,7D,9A,05,4A,89,84,0E,B2,D1,77,07,0F,F9,49,79,4C,DB,09,FF,23,67,0C,F4,B2,47,31,87,C8,2E,5D,EA,AE,4D,7A,E0,CA,C8,68,1D,64,B7,F7,C2,DD,D3,40,B0,13,6A,68,99,36,65,87,26,30,9D,AC,C1,C0,83,F6,2C,80,A9,89,6A,99,18,20,6D,5F,C1,7B,20,5C,57,56,19,82,3C,4B,B4,69,02,D9,C0,3D,47,07,26,CE,9E,F0,48,B9,BE,0B,E0,D9,C3,24,3C,42,8F,68,00,AB,BC,BB,FF,8F,83,0B,60,AD,BE,EB,9D,29,F7,1A,D5,D3,88,AB,CA,93,F7,19,61,39,14,48,24,49,AC,17,EA,F9,D1,D1,8D,A8,71,7D,4E,99,A8,89,80,DC,DA,BD,0A,DB,05,C7,89,F0,E9,E9,18,EC,5F,CD,78,F5,F8,22,7D,8C,72,75,09,AA,0E,42,7C,9A,40,BE,02,F7,92,A9,7D,CF,05,30,1D,72,B0,69,30,DA,0E,0B,99,D1,E9,27,18,61,54,DD,6D,83,EB,29,84,CA,55,C0,C6,86,6D,FC,D8,D3,4E,9F,E3,DB,F4,7D,62,3A,CB,13,F9,46,1B,B3,E4,F3,02,0F,34,F3,70,F2,E5,0E,AC,70,F2,D2,3F,63,62,AC,7A,C7,CC,F3,AE,6D,8D,32,BB,48,5C,3B,76,5A,C0,7F,57,69,E3,C6,D5,1D,A3,4A,DA,53,80,AC,03,F8,D6,8E,AF,CC,7E,30,03,9A,1B,7E,04,74,F7,63,A6,65,F7,4F,98,09,D5,45,F0,99,3F,28,63,FF,DD,40,83,11,70,68,0A,7A,81,12,16,1F,35,EE,D4,59,44,02,4E,CC,57,6D,1A,BE,BC,CD,EF,7B,43,3D,AD,20,7E,C7,39,3B,A2,79,33,9D,56,A6,64,F7,5B,96,F6,90,24,D7,80,A0,5C,FE,EB,8B,4F,82,93,AE,AA,BD,05,8A,4D,BA,FE,32,4B,69,BB,33,B4,B9,01,DB,92,00,CB,FE,47,9D,2B,A1,52,7D,94,BD,2E,34,03,29,06,4F,81,B8,91,13,76,E9,6F,CB,21,EA,43,D0,72,4B,09,BD,49,33,E6,95,42,38,88,BD,73,3E,39,97,18,69,23,E8,E3,F6,9D,CD,28,C5,D6,A7,AA,6E,75,48,84,26,77,2F,0A,0B,1A,C2,11,58,E1,D4,4A,BB,E3,82,96,7C,46,B6,36,C6,99,E9,9D,02,BB,3A,03,33,F7,17,B3,03,AD,52,1B,1C,4E,EA,70,BA,64,F1,B1,97,2A,06,FD,8B,A3,0C,E8,46,5D,26,F9,80,49,1A,E0,BF,F2,7A,D3,7C,69,CC,EF,A2,2F,AF,FE,8C,D1,FB,C2,44,73,B8,F7,35,D7,DB,F1,DE,8A,1C,BA,B1,86,E7,8A,C2,B5,9B,71,72,5D,AC,19,0E,67,D8,1D,8E,AB,00,76,53,E5,76,19,B5,B9,62,BC,89,35,82,70,F7,10,42,FA,13,21,F2,34,82,7A,63,71,C3,30,FB,8D,57,9D,92,7F,B9,30,A9,5D,C8,57,4D,D3,82,81,9C,F8,85,03,96,33,21,4B,49,34,7E,A3,9D,CE,FE,15,AE,6B,F0,1B,A8,54,AA,51,CA,53,AF,67,92,02,3C,01,E2,69,2A,CA,AC,F7,B9,98,3E,71,B8,26,F1,BD,C7,F6,C9,92,AA,EB,0C,F1,B4,D0,64,8D,FF,26,75,3E,1C,07,F4,6A,4D,A1,4A,0D,BA,84,B4,94,14,75,2A,70,5C,3F,8C,6B,43,0B,08,68,CE,4D,BF,67,70,93,36,B8,ED,DD,8C,CF,2C,58,EB,9F,F0,8A,39,CF,7E,6D,DD,34,1A,4B,11,C7,4F,69,B0,D4,57,9C,1C,E3,13,D7,70,87,37,C1,3F,2B,01,2D,39,F9,5B,7D,18,44,C2,1E,D4,EF,76,5A,82,50,D2,15,EA,05,24,CB,44,3D,8F,3A,66,01,A5,D0,7B,2C,CF,C4,6D,A5,56,E7,7E,87,2E,89,42,F4,FE,DA,72,F4,02,5B,88,28,5A,40,0C,FA,DD,90,A9,B1,32,97,55,5C,9E,9D,F3,66,BA,CB,CA,58,44,AF,EB,A2,82,77,07,82,E3,29,A7,49,86,DD,B5,D7,54,A0,EA,7E,5F,4D,D2,21,68,66,A7,79,DF,AE,CD,E8,5F,F2,B7,FF,63,9E,0B,8A,AB,FE,02,B6,23,54,71,90,CC,D5,23,C4,20,AA,F5,5D,DA,FD,E4,A6,A3,09,D1,6F,F0,D7,90,AF,E0,87,05,DC,A1,4D,F2,CA,7D,10,81,0D,A1,D2,F8,96,82,62,96,8B,40,3C,18,A3,80,7F,55,FA,36,D2,47,15,E5,99,F5,20,F3,D2,E2,D5,38,46,C8,06,8E,64,B2,41,EE,BF,78,D0,A7,DA,5B,FF,EC,C2,77,5E,7A,8F,09,67,76,6B,99,E3,A2,F6,B7,16,32,49,5C,0A,9F,0B,A7,B3,6C,7F,E1,F6,CC,56,13,89,83,E1,B1,86,9F,C2,AF,F5,BD,88,DE,0D,5A,1C,3B,9D,B7,66,0F,F1,CE,6A,52,23,62,CC,9B,3C,2C,18,06,AA,81,B8,11,2D,AC,E8,1B,73,77,79,67,56,2F,0B,3B,CB,40,33,3E,95,06,AC,F9,37,D4,22,E6,FA,13,51,81,1D,D6,C1,F3,16,A9,98,B5,88,00,3D,9B,41,55,45,A6,C1,80,EF,DB,94,06,A2,E8,21,6A,3B,15,14,55,E1,FA,43,B1,F9,2E,B0,B4,B1,21,5C,E5,A8,58,63,FB,7C,74,8F,0C,5F,AA,95,8C,1B,D7,83,28,16,02,9E,FD,57,11,36,5F,AB,57,99,94,E8,11,2B,C4,C6,B5,0D,51,4F,79,58,C7,22,90,D3,F6,C6,9D,7B,C0,89,1D,07,E9,C9,F3,E1,79,54,A0,72,A3,C7,59,A2,FF,DF,CE,C6,33,D3,A0,37,94,29,02,84,5C,EB,75,45,7B,49,D4,C5,0F,8A,68,0A,27,04,FB,C1,10,2D,AE,26,BE,84,F5,91,98,FC,CA,57,C4,26,19,31,78,B9,BA,F2,98,C0,B9,50,A7,10,43,A6,4B,E1,B3,E0,95,1D,EF,8D,D8,C2,F3,BD,B9,AF,F3,02,A7,7E,D2,1A,BE,5A,13,D5,43,81,6B,58,4C,3A,5C,55,CD,20,F4,67,DC,AA,2C,C2,CF,15,7D,0C,0A,70,4D,61,3E,3B,4E,FF,4D,FD,4D,4D,0E,64,42,06,A2,8F,88,EC,99,1C,28,7C,45,2D,16,93,5F,0D,96,17,F4,87,40,D5,54,81,00,FB,9B,C8,75,AE,78,E2,B6,4C,14,F4,7E,6A,B5,6D,43,2A,70,A7,89,34,7B,48,59,57,17,BE,A0,D1,96,BD,DB,E2,1C,FC,1A,68,27,1E,12,C5,A1,9D,D3,09,0D,91,8F,42,24,A3,BE,9B,88,B1,AC,A1,0D,BE,5A,E2,5A,67,25,AE,F5,00,CA,3F,41,3C,00,7B,87,88,62,4E,46,79,7B,B2,10,90,02,5C,B3,80,A6,2E,26,A0,1C,53,DE,33,7C,2E,58,04,C0,19,41,CE,DB,08,B5,0A,C1,28,45,78,11,A7,37,8F,8B,1F,AE,90,77,2A,E7,58,54,94,72,99,AD,DE,D5,50,41,50,3C,96,10,20,42,C4,9D,1F,7F,CC,7B,E2,6E,5A,98,34,F2,58,D4,F2,E0,C4,F9,B4,FA,5B,FE,19,9B,68,1F,2E,0D,62,40,F4,95,1C,30,F1,E9,45,32,FD,0D,FB,41,2A,F8,EA,81,46,AA,E2,04,8C,21,22,69,87,4C,1F,14,19,92,7B,1C,57,BD,E2,85,3E,E5,6E,1A,5C,95,C4,13,04,7E,C5,5A,A2,05,42,35,DB,EC,B1,CA,12,6B,74,90,D8,47,9D,64,59,6C,63,07,AE,3E,2F,8B,A4,67,F8,1F,33,66,DA,B2,83,42,18,A4,48,9E,B2,1A,19,F1,1D,58,1A,E7,E5,53,16,16,CB,BE,05,3C,01,92,CD,60,26,C2,B2,6F,7C,24,81,FE,47,49,85,E0,DE,19,1A,87,64,8E,99,C1,34,A1,55,75,1E,2D,9A,F5,8B,19,4F,4B,91,F3,C6,BF,1B,C4,89,B4,6A,CD,0C,05,62,D4,72,99,D3,BA,FF,9C,51,5C,24,BB,75,AA,2F,EB,9B,E0,EC,9D,BC,3A,10,DE,61,12,9A,99,A7,17,CE,5D,25,67,F2,DD,3B,BC,EB,62,E5,CB,1D,34,B5,15,87,92,63,31,69,34,E3,0F,1E,BD,93,7C,0E,1C,8F,75,86,35,B6,28,07,3B,8E,6A,52,6B,D8,06,5F,FA,B4,A3,7E,26,6B,DC,00,96,A7,4B,86,92,1B,B7,BA,3A,F3,2A,14,2F,79,CF,84,D7,AE,EF,E9,B1,76,52,2B,CF,29,0E,5A,0A,ED,60,C8,89,0E,8F,F8,33,5C,16,DD,8C,A3,29,A1,92,57,83,7E,7F,D3,EE,9A,5D,E5,DF,95,CD,5D,56,9B,44,25,1E,0D,11,DE,F6,77,C5,52,AD,AA,EA,0A,47,45,C4,6A,E3,CF,26,F4,5B,25,E3,75,9F,3C,6A,8C,72,01,8F,DA,31,7E,5A,DA,38,39,2B,1D,E8,3B,94,10,9D,AB,5D,E3,4F,DF,9A,49,38,35,1C,FD,09,35,C4,B0,0A,97,B3,4D,D1,7D,E5,50,13,26,D2,75,CE,EF,E5,31,21,E1,6E,8B,8E,46,4D,29,AE,9F,C1,57,AD,D3,07,C3,14,20,5C,5A,BF,D7,7F,91,82,66,0C,60,94,38,57,01,5A,9D,3E,69,1F,C9,BE,89,B2,A1,B4,35,D7,70,B0,B7,FD,C1,C9,EB,A3,A3,A6,7E,23,7C,35,C7,5B,49,2F,47,9E,DA,D9,E3,27,C5,92,B1,DB,94,11,64,A1,D1,9B,D0,11,7C,8B,62,8B,85,F4,D2,09,35,2C,4A,42,FA,CA,5A,45,3A,75,E3,99,6A,7F,0E,3C,9F,7F,99,AC,A9,B6,CB,D2,65,9E,B3,35,62,4C,B1,1F,90,4F,E8,06,F8,8C,13,A2,E2,65,21,5A,38,07,B1,08,1A,F7,4E,06,F4,95,03,01,C9,3A,FF,E9,24,0B,F4,F8,F3,A1,27,F4,D1,57,76,F1,89,7C,2C,FF,22,C2,92,8C,5B,7B,CC,70,90,22,E0,45,B1,D1,02,79,C2,B8,72,7C,1C,63,C4,37,8B,A2,4A,B2,CA,B1,55,50,00,DF,B6,DA,3A,F1,EE,C3,25,D7,05,5F,16,B4,19,BD,96,69,83,8B,0E,54,22,52,F4,36,B9,02,F1,B2,6E,34,2C,AD,7E,EE,68,D9,FA,C2,12,09,A3,24,6F,F8,B3,33,BD,7E,2A,74,6C,2C,CB,81,FE,B1,3B,8E,3A,C3,F1,2B,05,E1,25,54,E8,FE,2B,B9,B9,A7,2B,3B,5A,F5,F0,DF,6E,2A,0F,2F,B0,88,54,2B,50,6E,5A,69,DF,D3,D1,4E,AC,B3,29,A5,DA,20,64,4C,43,1E,38,78,4F,28,BA,62,79,BD,87,C1,3E,A6,30,39,B5,42,62,B9,C7,7F,0D,67,9D,71,38,8C,EA,A4,41,9A,8D,5E,E6,25,47,05,85,04,46,ED,48,91,AF,2C,22,D5,0B,9A,ED,61,D8,15,83,16,84,07,41,5D,E7,1E,7E,33,DF,0B,DC,AD,24,73,EB,EB,B5,23,C3,F9,A1,89,A1,45,93,15,41,F2,14,05,70,43,1B,27,DA,9D,ED,DC,4C,34,5E,CB,6A,4C,1A,ED,12,44,20,71,E1,A6,6C,BC,CD,F2,D0,AF,71,0F,6A,F7,24,99,9C,27,23,DF,74,73,E3,97,86,A0,33,C8,44,B4,26,F7,D1,E4,5F,18,C4,6E,7C,61,31,C2,3F,15,B3,E4,7C,9E,45,49,E5,4C,B5,8F,3E,41,FE,88,A8,F2,86,07,9B,FE,EA,C6,7A,A3,2D,2F,9A,E9,4A,64,6E,4E,39,9C,7F,5B,36,F8,C9,46,D2,E8,FF,38,D9,A5,C0,52,27,74,8E,75,51,91,41,14,38,6A,EB,81,97,BE,61,DC,F3,AA,A1,C3,DF,3E,FC,16,F8,71,23,28,76,CE,27,FD,4B,22,4C,BE,4E,8D,90,C3,C3,87,79,1B,54,A3,E0,6D,20,7A,C6,2E,FB,8D,81,B9,24,BE,CF,6F,80,4F,69,4C,8D,42,65,47,C2,F4,0C,AD,51,61,A3,B6,06,56,DF,D5,C2,8B,09,73,3A,41,51,C3,7A,FA,20,52,0A,96,06,97,53,AB,C4,5A,28,E7,A5,87,7E,1E,A7,51,B9,55,1B,70,EE,B3,D6,5D,B2,A6,B7,7F,AA,3E,88,D0,4D,01,3F,DC,F2,9E,29,25,EB,3C,DC,FF,4F,FA,4A,1D,B5,B6,59,41,F1,93,71,44,BD,16,12,83,B8,51,F2,F1,39,72,5E,D8,AB,A4,6C,15,58,AA,28,67,86,A3,D3,25,3E,1A,52,97,5B,5D,BC,4D,55,02,EF,0F,26,13,FF,1E,C0,5D,18,85,2F,76,91,5A,BA,D9,07,00,28,1B,13,61,43,31,A7,3D,A5,A8,A4,EC,11,C6,5C,EA,36,BA,D7,E7,99,DE,49,8E,28,44,CD,4B,14,C7,CB,F0,B2,21,26,60,F1,89,19,CA,BF,E4,DA,DB,C4,11,48,56,F3,A5,68,93,DA,95,FA,EB,82,F1,DE,35,E7,E4,9F,D2,81,BC,B1,E2,CE,BC,B8,3A,0D,67,1A,D3,88,54,28,79,82,33,18,0C,3E,60,2B,50,F6,32,46,AB,E9,2D,A8,C5,B6,91,94,BF,42,DB,52,EB,BF,51,7F,75,B8,92,45,5C,C8,E4,D7,68,3A,E6,33,E7,D7,7B,3F,9C,1C,D9,C3,26,EA,3F,44,FD,60,50,C6,76,1A,55,CD,E6,EB,D6,BF,E7,FF,FE,2B,7A,80,F2,6C,53,75,58,FC,67,7F,06,DC,A4,1D,7B,1E,A2,25,01,AF,5D,06,0B,78,57,4C,3F,76,E5,6D,76,B6,5D,D7,FA,3A,11,59,89,7E,5E,4E,B5,60,72,AD,B9,FB,2F,77,A6,7E,EC,C3,56,E4,1C,23,20,23,7C,09,E3,1D,E4,F0,FE,CB,C0,12,D9,34,63,7B,BD,2C,84,15,70,9A,EE,35,98,30,38,46,A0,5A,F7,68,86,8C,7D,41,3C,97,FE,D7,BC,08,19,E4,05,8B,67,7A,05,4C,1D,A9,B8,1A,BE,A3,BC,68,59,57,53,F5,84,12,96,3C,AB,D9,DB,A1,94,93,5C,1F,29,ED,CA,8B,DA,A6,D8,44,BE,A7,A9,76,8C,2A,01,8B,8A,69,9D,66,6C,53,7F,9C,B2,EC,F3,CD,2B,1B,4E,AB,FD,8B,16,B1,C2,8B,DA,14,DC,95,32,5B,DE,3E,26,46,8C,BD,BD,72,2A,44,7E,6A,4C,DE,51,02,39,FB,72,62,2F,CB,93,4B,4A,7B,55,6B,6A,AE,C8,FC,FC,D4,44,03,76,5E,B9,0A,89,55,52,F1,5E,B1,7A,19,BA,5E,58,34,30,6F,FC,56,6F,6A,AA,04,FB,5E,AF,64,79,FC,AF,1A,2A,06,B9,47,1E,36,EA,0A,A4,D4,76,EA,D5,36,2F,5E,82,84,C4,50,08,73,F6,AD,61,C7,0D,64,0C,7B,84,B2,38,C2,EF,05,6D,64,83,18,F8,65,04,A6,81,D9,FE,79,46,82,C1,F0,C8,60,6F,56,39,7D,77,86,6F,2D,55,E5,BB,35,5B,EE,4B,18,B9,AA,33,C9,D4,C3,22,E6,02,B7,A6,ED,78,31,64,11,45,C2,91,65,A0,91,F0,99,B3,33,F8,5C,FC,6D,2F,EB,C4,D2,52,D0,B7,F3,D0,A8,1C,D7,4A,1F,A3,74,4B,ED,80,24,33,CE,47,91,5E,CF,19,66,1C,D4,DC,32,16,70,B0,58,76,C6,E6,2F,99,A6,4A,16,BF,FD,E4,95,58,46,9F,C9,DF,9D,C0,D0,A5,52,31,C1,71,83,00,83,9F,EF,04,43,DB,B5,98,1A,0F,2B,35,95,19,46,00,FE,C5,E0,E8,5D,12,0E,D0,5F,23,C3,3C,2D,99,F5,2A,7E,F6,A1,17,03,5E,C0,BD,0B,27,99,9A,17,AC,D0,24,A5,DB,05,77,F7,E6,67,3F,80,AA,05,DA,76,5F,33,CE,C1,39,F7,2F,93,CA,83,AF,D0,67,BA,E7,28,FB,C4,57,B5,29,14,4A,D6,C0,53,E0,E5,FB,69,7C,6B,E0,31,EE,B2,1B,06,62,CD,C7,45,51,3E,EF,A8,18,F8,FF,FF,75,5F,B6,92,D5,EB,7A,88,F6,D9,26,C7,40,4B,B3,74,37,12,24,B6,C8,E6,65,E0,F9,6A,40,1E,3F,FE,48,C7,56,0C,41,91,85,63,CA,D6,FD,24,D0,5A,F3,CB,C3,6C,5C,F6,08,06,4C,21,5F,6A,3E,4B,1E,E9,23,7B,51,7B,14,4E,8C,38,18,7E,61,6D,EF,B6,6B,53,24,AD,CC,BE,8F,83,B3,13,3D,A6,8B,BD,E5,44,36,25,B2,AB,0D,96,37,FB,B1,4E,9F,FF,E0,D0,58,56,D7,0E,BC,D4,C5,56,48,8A,72,BF,5E,B1,38,98,DC,4C,0C,21,B5,76,26,9C,91,E5,58,C0,66,B3,28,BF,C5,FD,42,FC,95,7F,1D,EA,CD,27,12,68,EC,FF,9E,6F,FE,2A,48,D9,2B,30,CA,C8,46,A2,B6,2F,C8,61,D3,A4,0A,D1,F8,DF,91,E2,06,02,60,03,00,92,8B,E2,20,3A,7C,3C,B3,9A,1E,6F,17,68,C5,BF,B0,B2,7A,8A,39,55,34,7E,96,78,26,D9,A6,9D,2B,EB,60,97,FC,0B,ED,FC,BD,F6,6C,25,6F,86,62,50,18,B8,82,7B,28,F7,D2,02,7E,A5,BE,68,47,CC,BB,89,B9,1E,DF,DD,F3,01,D8,19,DF,11,F9,36,35,40,84,1E,96,D8,D0,B9,7C,9A,2E,8D,57,E5,47,3C,4D,2C,78,84,5E,62,72,E6,DA,95,07,68,8F,C8,15,E5,0C,E9,43,88,FC,46,51,3B,7B,BD,C7,B1,2C,E0,C6,13,33,21,C8,B6,08,C9,DC,B1,78,CF,08,21,C7,ED,9E,DE,6A,C5,C0,B6,97,41,8C,8E,BE,34,51,BD,0D,2C,FC,55,EE,F6,94,C6,77,9D,83,CA,46,3B,49,48,F7,B0,4A,67,46,C2,74,55,7F,54,7E,39,1C,D6,B8,86,84,3F,5D,AF,E9,6B,CB,BF,30,B9,3F,99,0E,CB,18,86,68,37,26,E9,C9,A4,71,F1,82,1D,EC,4A,43,47,79,95,A5,98,78,EC,CD,F1,02,75,68,D0,E4,54,B2,1C,58,CE,62,C5,D1,9D,EC,AB,DB,BE,9B,A1,10,22,B2,91,13,2F,DE,40,3F,61,F5,A4,25,20,7E,2A,F4,4B,42,DC,61,F5,A4,C8,FE,4F,EC,60,E8,A7,57,3F,38,04,22,51,0F,4A,11,FE,A7,5C,C7,1F,7F,80,86,8F,28,C1,AA,95,D7,CA,F6,3C,D6,96,1B,85,B7,2B,8E,95,2C,0E,EB,FC,24,28,07,16,05,51,33,0A,FE,0F,83,18,B4,A0,C8,F9,38,9C,45,0A,12,09,B3,B3,BC,48,16,EC,B0,6B,3B,E3,50,BF,94,50,B1,09,ED,05,90,B9,59,CC,C9,4B,E5,1F,1B,AC,83,9A,15,E1,C3,84,CC,CB,BA,DE,CD,3F,F0,65,AE,FE,6B,A1,D8,8E,6E,A9,5C,14,8D,F1,BF,59,7F,4B,F7,D1,B7,35,17,C6,56,07,0B,EF,BC,BD,44,42,94,70,3A,63,32,CB,BF,C5,C0,F6,CB,06,46,3C,6A,76,66,D6,73,AE,4D,E7,14,F9,AE,F4,53,44,DF,77,AF,05,A1,EE,EB,30,C7,42,DB,6E,77,F4,82,3C,AC,15,1E,5F,38,D5,58,ED,C9,65,B9,87,07,13,EF,68,9E,AB,24,E2,D7,AE,95,98,25,A1,F9,80,EB,AD,83,D4,70,29,08,E8,6C,62,B3,65,58,E2,2D,B1,31,22,5F,87,64,59,BE,7F,89,59,0E,DA,60,CD,93,39,74,2E,DC,A1,F1,04,F1,5C,85,18,D6,B3,5E,A8,5D,22,80,04,40,86,CF,6E,26,0A,FC,73,AC,5E,61,28,C2,3F,EA,0A,B9,EB,BF,38,7E,3C,CE,EB,19,40,C9,30,52,8D,2D,C2,CD,5E,2E,7F,7D,0E,7D,77,64,A9,89,6C,9E,BC,2D,C0,F4,45,B5,A1,01,79,D0,4A,2C,BB,D1,47,8B,5C,68,3C,22,72,D9,86,F9,55,4D,34,41,8C,89,6A,32,92,C3,D0,F8,09,F5,5D,2E,08,DF,EF,17,F3,BB,A2,BE,D3,CA,11,5C,FA,9A,E6,3E,A7,77,38,5E,DC,E9,9B,4F,1A,C0,A1,9C,BA,86,29,34,6D,23,41,57,27,1C,D9,9C,91,19,F9,A3,2C,23,51,13,86,F9,06,54,09,F8,83,97,06,1A,F4,12,D7,D0,07,4A,B4,81,68,4D,3A,5E,41,9B,4D,59,04,D2,44,49,10,51,BE,6C,57,6D,91,2C,0B,06,32,83,A9,51,CF,BD,66,E0,89,9D,0D,3D,44,30,A4,0D,CB,40,AF,16,0F,93,CA,33,9E,55,BC,F3,4F,19,16,51,A0,C4,95,44,A5,69,4E,E0,51,BB,0F,CF,0F,FE,8C,B9,98,28,07,6A,AB,C4,1D,94,37,95,C8,53,52,60,1C,61,58,97,D8,E9,D4,3F,3D,82,05,78,BB,C7,66,98,3F,1A,FA,A3,7F,48,E8,8B,BB,82,C5,2C,E8,05,AF,3C,E6,23,E3,CC,44,26,0B,F6,B3,D1,1F,AE,27,10,6D,F9,04,B4,CC,FA,B5,2E,68,09,E4,CF,B6,80,B7,02,E0,DE,11,F3,B7,2B,54,10,15,A9,AA,18,30,9D,BE,3E,81,E0,32,06,98,83,B4,DA,B3,EC,F2,69,4B,E5,1E,B5,17,D2,7E,D0,4D,C7,65,14,B9,8A,AF,C3,0B,55,A3,15,28,44,E6,53,F8,CF,E5,3C,F3,D9,8A,73,F9,8D,8D,74,FD,ED,04,31,8D,3B,F7,85,38,C7,3F,B7,F2,EB,27,8E,E2,08,A4,43,48,50,27,F5,F1,88,86,84,99,9F,E4,50,AB,2F,92,BF,BB,BF,E1,57,85,D1,12,55,48,AC,4C,9E,5B,31,BF,36,2B,06,DB,57,C1,74,A2,8B,FD,09,11,BC,C7,DB,ED,DC,97,77,55,7D,B7,0E,FA,34,F8,E9,65,7B,4C,3B,A0,24,32,C9,2C,92,34,4A,1F,8C,17,F9,F8,C8,4F,83,6F,F6,6C,64,0E,E6,F9,26,D8,9A,49,3A,1A,E3,9A,6B,F5,A7,28,E3,35,9E,8F,B8,F0,A9,5A,21,AF,44,AD,FC,DD,A8,AF,DC,60,E7,94,E7,52,02,45,0C,1A,5C,FF,F8,23,A9,35,84,77,E8,77,9F,EE,80,0D,EF,7A,54,C8,94,53,E0,C6,F1,33,31,FB,8A,49,61,19,E0,79,E8,0B,BD,01,60,EC,B4,5F,57,0E,29,BD,ED,B3,79,7A,BB,EA,B1,4F,E1,BB,CA,E0,C9,AD,AD,24,90,04,19,97,91,A9,80,48,A3,0E,49,47,4B,0E,49,91,E6,16,6C,4A,B7,DF,88,8A,FE,FB,C4,0B,59,38,D5,11,67,D0,69,24,54,40,72,B0,22,B1,D1,BC,CD,1E,3C,0C,77,69,02,5E,47,F9,CB,83,01,97,50,23,7F,27,92,B5,FE,A6,42,52,E9,5F,55,37,42,8C,E1,18,8A,CA,8C,4F,46,A3,72,02,FB,D8,79,C6,B5,C6,67,9D,CC,AB,26,3E,50,3E,97,E7,FD,56,57,DE,B3,2B,A5,69,B2,19,99,50,6E,2E,2A,C2,76,07,06,DF,87,BF,F7,4B,D2,76,8F,62,3A,2D,0B,AD,4B,59,A5,96,A5,17,5D,E2,F3,3F,42,B2,9E,CC,1A,E9,69,D4,8B,25,4B,99,48,DA,3E,8F,25,43,6D,45,BF,F2,BD,36,68,22,CC,08,42,CC,41,63,9E,EB,2F,AC,99,66,48,C7,58,7F,7E,B3,E0,35,6C,86,A1,C7,33,74,B7,A4,8B,5C,0C,9F,56,3C,BF,65,90,4A,AA,A9,2C,9B,A6,07,79,B5,96,F9,AB,7C,62,9C,12,1A,A2,58,C3,65,60,32,42,36,74,E9,2E,06,DE,0F,97,4E,69,F6,7A,5C,20,69,7E,47,C2,2A,F9,39,87,5C,77,15,56,36,2B,F1,DB,B5,07,83,EC,3A,65,68,2A,C7,25,E5,8D,27,92,19,4D,56,01,9E,E9,A5,13,76,73,36,C1,D1,A4,4C,C1,DC,2B,A1,5C,A5,03,81,D8,A6,9D,1D,57,7D,92,61,21,16,D8,B5,DA,CF,40,B2,2C,EB,90,2F,4A,00,9F,6D,1F,25,C1,F6,86,D9,2A,22,48,65,06,F9,E9,FF,F2,DC,33,B6,C9,E3,D1,19,D6,C8,17,CC,44,85,C5,58,FC,F5,10,EE,6C,DF,50,BC,C1,53,1E,E0,3E,18,62,EE,71,32,16,56,F2,C3,37,71,94,3E,A8,33,0D,37,24,D1,1B,01,14,FB,B9,20,12,F4,9A,20,47,90,46,7C,D3,DD,5F,F3,A4,82,C2,86,77,66,4F,E1,5A,CE,DD,0F,08,B5,FF,32,2A,34,3F,ED,09,8C,95,D8,E6,A4,8F,33,B7,7F,9F,6A,F1,5C,B4,38,E9,68,AC,CB,14,27,59,F0,CB,23,72,79,1A,72,2F,74,75,91,B8,F8,32,99,B3,7B,BA,DD,4C,60,8A,0E,9C,31,94,1C,96,9D,DE,C2,65,F7,9C,D6,87,A5,12,C6,98,2B,6D,B5,E2,8B,24,09,EC,B6,3C,04,61,ED,0B,AF,FF,95,D9,F9,A4,6C,85,10,FF,4D,4B,BC,7D,53,35,70,8C,93,DE,50,60,87,30,43,84,8D,DB,61,F2,61,6D,97,7D,11,B6,80,A9,DB,1C,6B,98,85,AE,76,3F,4A,59,B3,41,01,22,DE,EF,C2,96,26,67,1F,37,0D,CE,A5,FD,8B,F5,1D,D9,0F,5E,01,D3,97,4E,29,AA,7E,C2,45,5A,C4,11,02,5C,20,6B,6A,82,34,E2,3C,D2,3C,77,BE,97,34,ED,43,0B,FA,2E,02,FB,1D,FA,8D,7D,D0,18,3C,7D,15,A5,32,3C,A3,76,0E,85,EA,01,5F,D2,E5,49,4E,A1,43,F3,29,84,E4,E1,4B,B6,90,E0,E8,4A,24,E6,2C,3F,E8,A5,E0,73,7C,91,7B,B1,9C,A1,11,CF,66,06,C3,C4,09,F7,9F,A7,FA,A3,4D,A8,40,D2,90,E0,C2,CA,94,FE,A7,69,AC,ED,A6,B3,DC,B8,A1,09,15,13,2B,9A,A7,2C,28,B7,74,57,33,53,C8,45,FF,B2,C3,2B,C8,C8,43,51,BE,F1,B1,D4,5E,99,04,F9,F1,32,7F,13,7E,B8,0C,6A,80,67,E6,41,94,95,3D,E4,04,B8,9D,A8,59,9D,22,14,54,AA,E8,0F,33,AE,7F,25,41,BE,0B,00,E6,44,1B,96,20,CE,38,94,68,92,B5,60,83,60,4A,A0,2A,E4,A1,1C,92,D5,05,03,3A,07,A8,2E,D7,DC,5E,E3,DE,58,34,B3,4E,84,17,7D,35,8C,6C,FC,90,57,42,D6,51,E3,9F,17,B4,A8,C1,6A,49,42,9C,44,EC,C6,65,37,36,09,49,A5,4C,49,13,D0,82,45,14,63,4C,CB,AF,8C,07,DA,CF,A6,76,FF,1B,BA,B6,CF,D6,E0,0D,A3,42,54,66,A8,49,82,14,8C,2E,C7,2A,05,C9,4F,6A,3C,79,EE,30,0B,FE,45,07,AE,CD,46,13,77,85,63,78,70,C1,44,4F,DF,CB,C1,CF,8C,2F,3F,96,E4,17,CD,78,2D,68,6B,FF,AC,EA,FD,D7,8D,8B,9B,45,9F,3F,8E,FF,06,B7,26,0D,13,C2,E1,38,68,C3,BB,CA,C7,25,80,A8,4E,D1,5E,47,A0,D9,05,4C,E9,3C,4D,3B,A4,6F,64,4E,FF,4F,D8,F6,EB,2F,50,D3,6B,28,A5,A9,BC,B7,76,46,C0,A7,B0,1B,11,90,46,0D,4E,50,DE,C3,6F,C8,27,EE,2D,EB,66,FF,27,FA,75,6D,4A,88,E0,B2,B3,7D,82,DE,B2,6F,54,1D,5D,A1,29,46,65,1A,66,39,B2,F4,3E,66,CE,AC,8F,8B,D4,25,6E,F7,7E,B4,1C,54,9D,2B,C0,DB,E9,89,3F,E4,51,39,90,A0,E3,44,79,7A,0D,15,32,75,65,0D,63,8E,7A,4B,4B,1F,BB,A0,C0,8E,F0,2F,EF,89,71,4A,FD,57,9F,72,84,6B,46,C9,1B,91,F0,E0,23,73,18,EF,BF,C4,5B,22,0E,4B,01,4A,01,8A,75,55,95,74,45,DF,5C,FD,FA,DA,AD,43,14,B3,D5,48,0E,68,7B,CE,54,41,74,A3,91,CA,CE,75,8F,DF,67,80,19,19,19,22,2E,D2,F8,1C,B1,D9,B1,A6,45,A1,0D,0F,2B,A6,04,AA,55,23,65,0C,2C,F0,2C,FC,B4,7F,BD,E1,84,57,5E,F2,64,D8,97,FD,69,F2,AB,4C,B9,6C,DD,E4,26,78,45,10,F5,CF,7E,52,37,76,DE,50,8B,B2,CE,F9,F1,84,5C,21,6D,82,2C,7C,4A,DC,00,71,63,46,33,18,5D,07,6F,0D,21,06,9E,12,74,0D,F2,EE,2C,67,0F,32,13,38,D2,CE,CC,49,DA,A9,19,92,15,51,64,23,48,7A,28,B9,20,C7,11,D1,71,1A,30,79,4D,B6,8B,FC,8B,1C,A8,D7,18,70,2F,D6,67,96,53,54,72,57,5E,DA,F2,65,A3,3F,B6,AA,3B,DA,AC,F4,C5,2F,B9,57,22,ED,02,DA,2D,DB,3D,26,C2,BD,F1,2B,E7,88,64,81,CA,54,0D,76,9A,51,9E,8D,5C,C0,33,30,87,FE,DA,78,E4,B2,E2,39,09,E0,7A,C3,F0,24,93,03,25,4C,46,5E,68,8D,38,D4,E8,55,39,6C,86,61,ED,36,89,15,E0,01,A1,C1,A6,B5,12,A3,85,4C,87,8C,A1,8D,41,BD,B9,B4,F9,4F,AD,DD,E0,DE,9E,E0,B0,A6,26,1A,07,4F,62,A4,BC,66,CF,79,C4,AB,F0,3A,B3,51,4C,97,BC,3F,5A,FD,92,45,C2,96,29,BE,AB,9C,56,A1,E8,83,02,31,13,5A,42,D9,08,35,96,F7,8A,B5,07,8B,D5,BF,63,45,87,6B,7E,6A,82,BD,48,73,E8,E8,10,25,ED,C3,D3,33,A1,56,84,30,3D,70,A7,B5,8A,E4,46,B3,5A,16,08,31,EE,D5,34,29,B0,C7,EE,2A,6F,AC,F4,CD,99,5F,12,08,40,C2,61,D7,0A,CC,7D,99,99,29,49,43,F4,E9,9C,E4,3B,3D,6E,3B,1A,D7,A3,C5,B3,E5,B4,EF,0B,2F,26,0D,F0,1D,2E,A4,DD,18,30,10,FD,DF,53,56,95,DD,75,01,64,D3,9D,C5,47,35,BB,C6,A5,76,BB,9B,3E,F3,70,55,49,D5,92,82,E5,46,94,87,69,5C,86,4D,FE,17,A4,0A,23,CC,30,45,B7,2E,13,50,58,1E,BE,EC,DE,5C,3D,31,C4,FB,B7,26,BE,CA,EC,9C,01,31,DE,FC,DD,C5,9F,DB,71,9E,5E,DF,E8,65,1C,A1,0E,34,E0,90,F1,F3,61,40,E3,4A,28,3E,2B,75,A2,2C,55,B8,70,25,CF,C5,7D,B4,0F,78,DB,66,61,F9,30,C7,2F,1E,9F,1F,A8,4F,D8,59,B5,64,C3,2C,E3,C6,4A,33,7C,3F,16,DE,10,67,34,9A,C7,93,08,13,D6,56,04,9B,68,63,78,9D,B1,F2,C9,7F,6E,94,11,A6,11,4E,01,07,ED,68,C4,1B,A9,F5,75,DC,BD,65,09,46,E2,24,FD,82,F6,23,78,DA,46,F8,70,A6,2E,4C,34,C4,61,56,E3,EC,73,C6,7D,63,25,32,06,B6,03,F7,46,AB,35,DA,A5,B0,12,91,05,E7,22,97,D5,0C,5B,6D,12,EF,C7,E4,A3,DA,46,1B,49,94,CA,FE,47,2F,84,48,4D,28,60,62,BD,89,EF,B8,0A,BC,1C,40,29,21,E6,DB,CA,C7,AC,5C,E1,E8,A1,71,D6,92,42,1C,1F,92,3A,A4,F2,1C,EF,7F,B3,03,72,99,0B,36,37,31,B8,84,D3,58,A3,25,94,18,E9,48,23,83,76,40,61,82,78,D6,31,86,52,D0,74,F3,82,59,FE,26,B1,9A,D6,69,FA,91,EE,9C,C9,3E,EA,BC,90,79,55,BB,27,24,F4,12,BD,59,70,47,BF,05,A0,46,D2,6E,2D,63,62,DB,77,F8,2D,2E,B6,F2,EC,14,E3,47,65,A0,E4,80,53,1E,A0,74,2E,17,A7,49,0C,FF,7A,82,7A,43,24,F2,75,0F,A9,97,5D,57,BF,B8,B0,0A,67,8E,B8,C0,61,01,AD,1E,A3,E9,67,02,EF,3F,E1,6A,5F,61,0F,92,61,93,28,FF,65,B0,5C,9D,8C,CA,73,BE,00,DB,CC,FF,73,7F,F6,F1,40,59,39,DD,F0,90,E4,D8,54,9B,F3,3C,D0,0D,81,3A,61,2B,FB,0D,89,F1,FA,67,18,AF,9E,73,A0,A5,AF,FF,F5,0B,3F,53,99,CD,0B,0E,12,11,2C,F8,E8,41,C7,A1,76,D6,0E,3A,D1,55,26,00,06,80,04,BC,07,4F,B3,EE,0C,3C,D4,B2,91,EE,D4,D2,AC,42,74,99,18,CF,1C,09,AE,CA,F5,89,FB,1E,A1,0C,45,B2,E7,C3,36,EB,D4,EF,D3,0E,D4,82,AE,2B,41,2B,1E,17,36,BF,2B,76,63,DC,27,74,AF,61,F3,75,AA,09,9E,F1,15,AB,25,2C,77,AB,62,3C,8B,F7,1B,F7,EF,BC,B9,6E,1A,0F,DD,48,76,C2,A2,D1,7E,97,AF,7F,2F,BC,80,44,79,8B,7C,01,F4,67,B4,CA,C0,3D,15,20,04,A3,76,D1,25,2C,FF,41,E2,E8,01,F3,C5,37,20,3D,0D,4A,07,B7,EB,33,92,84,1A,58,C3,C4,B9,28,3A,A6,3F,5A,7E,64,93,4F,F0,55,9C,4F,D2,60,87,10,01,A1,F4,46,8A,6D,7C,B9,3E,5F,5D,CA,2E,FA,99,80,C0,A3,EE,39,14,46,EA,F1,53,54,BB,56,D1,39,2B,9B,4A,2C,89,E5,FE,46,0E,C7,67,94,92,38,08,19,57,CA,12,CF,14,C1,2C,C8,D3,02,57,EA,CD,BC,B8,2C,E3,25,FB,BE,A6,3D,A9,2E,3D,CC,D4,02,EF,7E,BE,A6,CB,C6,04,D9,59,38,A5,96,9C,A6,E3,13,29,17,CA,5E,40,4A,85,3A,D4,12,F4,5B,2C,64,78,F6,D5,70,50,DA,34,9C,13,A8,5D,30,EA,A2,52,DE,D4,F1,6F,95,FA,69,3B,67,2C,41,EA,9C,6B,F5,B2,D2,B1,2A,19,3B,0E,52,C9,81,0D,23,19,6B,08,FA,94,67,EF,A1,1F,C4,71,AA,7A,1C,C2,85,1C,F8,41,0B,A5,92,D9,0D,C4,7D,25,65,A9,5A,2C,10,76,5D,2A,1C,FF,7E,0F,AF,1C,8E,33,13,9F,DD,06,56,A5,04,FC,6B,4D,B1,88,AF,A8,88,75,BC,1F,EB,BD,97,8F,5B,D8,EC,BD,57,C7,67,00,1C,2B,CD,A7,A1,E1,08,5F,F9,14,17,27,33,8A,55,E9,B1,4D,D9,8F,AA,24,2D,21,F5,E6,AD,66,0D,E6,84,AC,33,AF,13,07,42,91,93,12,29,6B,AC,38,78,EE,DD,2E,2A,1B,D8,1E,84,DC,70,7D,7B,1A,04,34,68,68,BC,A5,A1,CB,3B,8F,EE,AF,A0,F9,46,1E,1A,E8,AE,3D,C4,0F,1B,7A,D0,7F,12,13,8A,E0,1B,AF,0E,47,D5,6B,57,A3,9A,F7,84,1F,B7,3F,9C,98,F7,C4,1E,88,D6,EA,A6,86,99,E3,51,3F,46,89,F6,FD,28,76,19,44,3E,E2,AB,CE,CA,DF,AF,45,1D,52,6B,2D,77,60,6E,F5,B8,5B,68,69,CB,18,3F,8A,07,E2,7F,53,22,E0,D3,5B,A6,C7,43,B0,A2,38,D5,97,00,C6,2F,50,7C,84,B7,99,DC,78,0E,0E,29,F7,AE,1E,53,0B,C2,D3,CB,BE,3D,2A,8A,61,43,CE,4F,79,98,3F,AF,0C,73,5C,E8,51,5B,01,BF,60,98,58,E0,12,05,F7,A6,1C,36,C3,0D,8F,09,74,03,4D,4A,5C,15,18,3A,33,37,EF,91,C3,EB,12,39,C1,80,82,63,89,DC,B7,56,48,CB,72,9B,32,68,1C,BB,1A,DA,A3,56,F7,BF,CF,38,1E,C1,DB,95,D3,78,7D,2B,2A,FA,D3,CE,0F,D6,74,4E,23,53,C5,F2,D7,15,4A,4F,F2,B9,10,88,AE,BE,5D,7C,00,93,3F,DA,5C,D3,3F,FF,49,B8,AB,2E,A0,20,5D,3D,3C,67,12,10,A1,CE,17,6F,7C,CB,D2,4A,C4,49,C0,29,BA,D5,FD,4E,A2,F7,29,9B,AE,AD,6F,15,EC,1C,D0,CC,1A,B9,A7,21,91,43,B0,11,24,3D,1C,2D,4B,BD,E7,FE,58,42,09,4C,1A,17,A1,4C,8D,96,02,10,F8,89,92,76,9B,61,7D,6D,64,37,68,0F,44,E5,CF,6D,34,50,53,61,D7,51,1D,68,5F,9A,43,FA,C5,DA,68,16,42,3E,22,E9,27,51,95,8C,27,77,FF,2D,FB,C3,E7,76,58,8F,56,92,0C,37,B9,33,18,07,A5,1F,56,09,73,16,E8,56,F5,AC,27,E7,C7,ED,87,09,73,81,9B,8C,C8,7C,D1,02,C9,33,9A,7E,72,69,18,AC,D5,99,C6,60,A9,24,F1,CF,52,B0,8B,7B,31,CA,BC,4B,5F,AB,9B,DA,FC,8F,E1,7C,A9,08,0C,72,85,EB,61,98,95,9B,94,06,D7,5F,04,88,FE,96,BE,16,4C,E1,63,80,F6,57,F7,D4,84,12,19,F8,97,B9,8E,71,C5,DA,56,90,33,CB,1C,15,80,D9,01,91,48,C2,AB,F7,2F,3C,AE,AA,00,96,F1,97,71,C2,35,3D,D8,F7,EB,0B,6A,09,B2,CC,C9,9A,7A,7A,BE,13,19,19,6D,67,47,5B,96,69,10,AB,80,25,53,E9,95,D2,7D,E6,77,D7,E6,D7,AD,A7,EE,77,AC,E0,EB,05,15,66,E1,6D,F7,31,53,C4,E3,DC,E0,74,D3,30,29,5F,4E,97,9D,16,4F,2E,CF,CE,63,9F,E3,57,C4,AE,6C,CF,54,4D,6D,23,EE,EE,4D,EA,B0,A2,E4,4C,2A,D6,27,ED,53,6E,19,C8,64,2E,0E,2A,1A,ED,B2,1F,07,99,A0,3C,02,37,ED,C3,C0,6F,B8,52,3C,1A,36,F6,D9,DA,00,FF,7E,D5,07,71,B2,37,A9,7E,B3,E1,B2,1B,BA,99,23,1A,EF,92,74,7E,27,83,BB,4A,9F,DB,97,7E,8F,33,4A,56,7B,2A,2F,CF,0A,4C,6C,A5,19,F5,C2,96,16,27,87,33,2E,EA,C9,8B,05,BD,DE,C3,C9,84,83,B2,D6,B5,29,5F,07,07,51,ED,77,6F,E7,24,22,23,4F,ED,50,14,62,2B,6D,65,A2,F7,4E,8F,DB,52,34,7F,18,BC,5E,5C,0B,C9,5D,FA,BE,08,BF,D5,AD,33,B6,A6,59,6F,C7,EF,44,ED,F1,23,1E,8C,A4,5D,9D,18,5D,64,36,2C,39,F3,88,8F,92,50,12,1F,92,29,74,E3,F0,69,57,EB,5A,E5,0A,94,FC,F2,00,54,E2,B7,80,06,E2,8F,AD,1E,3E,25,B5,7E,2B,33,7B,C0,54,20,33,0D,86,E9,58,BC,40,5C,E7,08,B1,4E,55,E8,1A,60,E5,13,B2,1E,18,82,B0,EE,0E,A4,51,9F,E1,C0,17,5E,D4,25,ED,87,2C,50,E0,EE,BE,7C,88,C3,07,2D,51,AF,F9,EB,2B,F3,D4,88,D7,B2,23,09,17,07,6C,F1,7B,08,BA,C6,17,81,DE,F6,7A,C3,19,15,DD,A6,93,9A,D1,CA,55,77,5C,98,C5,45,BC,10,A7,64,3E,FB,D4,F5,9B,D3,FF,E1,93,62,35,82,CF,5C,72,C4,F4,BE,7C,5F,28,64,29,8B,4C,F1,8E,27,3D,DC,06,FD,6A,B2,A0,9D,BA,FC,20,83,0A,90,AC,14,01,A1,68,AE,C5,E2,43,75,B8,41,5E,43,3D,90,B3,47,E2,3E,DF,DA,D6,33,DD,DE,32,08,18,86,EF,85,19,C6,EC,F9,1F,49,03,AB,FD,C7,B7,44,88,42,86,00,FB,65,37,6A,1E,75,A2,83,C2,1C,E7,86,E9,93,57,9F,84,8B,85,94,F6,0F,DA,7D,9B,0B,AC,00,5F,33,56,C6,B8,21,E1,5E,EB,0B,54,1D,4C,DE,C1,6D,0A,7D,B6,CF,BF,27,47,9B,E5,B9,27,6F,06,F0,A6,F7,25,65,A9,48,9A,98,20,1C,3D,0B,8B,2D,B6,06,4A,76,AD,51,D8,04,5F,6C,2A,DF,54,78,BF,38,AD,EF,5E,6C,A1,D1,1A,C4,FC,0A,4A,17,1F,AE,15,1A,C7,F2,AD,3C,30,64,65,9C,FF,F7,C8,DC,BD,FF,0B,AA,EA,41,39,C3,F6,BD,7F,54,54,FC,0C,F6,6F,8C,F1,C0,71,7A,22,A9,6E,7E,40,25,60,DC,85,55,94,45,19,B8,04,29,1C,07,69,37,4F,65,91,23,44,ED,F0,66,53,34,14,C5,73,A0,08,CA,03,74,BB,3D,F2,1D,82,22,DF,0A,1F,65,14,3F,A3,1C,98,BD,7C,05,68,44,CA,AF,65,19,A2,7D,1E,D7,1F,2C,FE,1B,7F,D5,E1,79,29,3A,BF,22,A6,8C,90,4D,52,0A,79,A3,FB,2A,71,90,7E,33,2D,6A,98,E6,37,35,BC,8E,4B,C7,ED,6B,D4,91,8C,DB,5E,46,D3,01,C7,0A,B9,F6,60,AA,08,3B,6D,C3,8B,D1,5E,FF,D1,3B,A6,4E,78,66,EA,D2,AC,8C,9E,7F,22,9E,6A,86,E0,B4,9C,6F,4A,8C,0D,CC,C6,1F,88,47,62,93,A8,EE,E8,FB,EE,3A,A9,02,24,3D,04,73,72,73,1F,9A,A0,DF,82,72,B8,1E,0F,2D,54,2A,5D,6D,E0,A9,91,FE,BA,E2,1A,98,7C,A7,68,E0,36,6C,9B,59,37,36,53,1E,A2,DE,F7,1B,44,E2,79,4F,27,84,02,64,57,67,21,86,68,2C,4F,10,FF,A6,D4,25,99,3E,5E,EB,3C,1F,DE,40,90,F6,26,10,31,15,20,C9,AD,8B,7E,80,AA,A6,34,47,2A,8E,AE,0A,86,F4,B5,56,70,F6,EE,74,DB,46,FA,47,BE,78,9D,B2,02,2A,C9,49,EB,93,0B,C1,03,0A,E4,0A,29,22,34,F5,C3,02,E0,55,73,8B,E8,8D,D0,D5,B8,A9,22,A3,1E,65,70,4D,81,D9,30,A4,6C,1D,0E,4C,EB,C8,07,48,45,E4,27,60,98,CE,05,EA,95,E2,74,03,D0,0F,B9,48,DB,CE,33,2D,7D,78,BB,51,C7,AC,E2,C9,4E,33,7A,D7,EC,E4,DD,D5,BF,03,15,62,51,3F,9C,D4,E6,FB,AE,5B,C1,4D,4B,B0,5D,CB,68,94,82,8E,59,F5,F2,A5,A8,15,1A,F6,C5,DD,DE,4E,55,96,90,E4,7C,53,9D,31,C7,6B,6A,96,DA,56,B1,9D,17,1A,D0,35,EC,2D,AE,14,B7,D7,E1,C2,34,10,0A,E9,47,46,42,E6,B6,D5,74,DC,EC,C1,4A,BB,A1,9F,67,50,9B,AE,85,B9,1D,C4,01,CC,10,47,B7,5F,BA,26,F6,35,45,49,37,BF,9B,08,13,9E,9D,01,4D,95,E5,BD,15,14,77,73,6E,53,01,8A,5C,31,52,11,9D,9F,00,65,39,F0,93,DC,7C,B6,3A,89,00,6A,22,47,BE,E3,21,F3,B7,B5,B3,80,4A,3F,C7,CC,ED,F8,69,D3,0A,AB,E8,04,5E,80,20,B6,09,88,E7,F7,7B,53,2A,B3,FB,C8,E8,A1,BC,FE,D5,1A,EC,F9,33,0E,7A,E0,DF,FF,25,C2,0B,1B,ED,E1,5B,41,A3,E7,EE,3F,96,F5,36,14,0C,E5,66,49,7D,CD,91,01,8B,E6,DA,D2,16,1A,67,C7,FA,C5,A2,CE,47,CF,3C,71,4B,98,E9,8E,A7,DE,64,A1,F6,0F,C9,91,A1,D4,AF,F7,73,8A,4D,00,4F,98,8E,FA,CB,B9,36,BC,B3,F5,25,8C,03,C2,16,C3,DB,14,90,96,64,26,3F,A4,03,6D,0D,2B,9C,98,FA,56,60,ED,59,48,04,E6,07,CB,6D,60,AB,3F,22,8D,61,B5,2C,DB,FE,4F,10,C6,CB,24,92,EA,EB,12,47,97,F7,90,4E,C5,C2,D2,E2,D5,E2,9F,CD,B0,CD,CD,61,AD,5B,B4,4B,67,6A,F9,2E,69,3C,42,CF,52,84,84,12,50,56,48,BA,D2,4F,77,94,36,46,5A,19,67,CE,19,B1,E8,82,CF,AF,D5,B3,55,A6,46,11,25,41,A3,DD,4E,B0,21,D7,63,37,45,4F,C5,EC,45,80,0E,E6,A8,9A,46,FA,9A,57,11,FE,6C,C1,14,35,48,4D,EF,0A,3A,A0,13,A8,2C,3F,FA,55,C6,94,AE,D0,CD,54,19,E2,D4,A9,8A,5D,22,DD,4C,17,A4,02,EB,8A,C1,C1,87,3C,7F,5D,B6,B7,B7,46,A0,6D,6C,1C,50,44,00,CC,01,27,95,5B,A3,18,24,6C,27,48,41,48,A1,1B,AA,58,BB,A1,5F,CC,15,AB,2F,71,A5,F0,0A,B3,6B,77,95,D1,5A,CA,4C,D9,BA,09,00,F1,EF,60,64,07,FA,39,69,FA,A4,54,20,E8,D6,F6,55,6C,E5,03,1C,BB,A7,C7,D6,D2,E8,D4,F7,E7,38,FB,B6,9B,00,EA,D9,EC,33,DA,45,82,BB,B1,2C,88,ED,E9,5A,88,F0,15,F8,B9,A3,33,5B,5E,8A,F0,7D,9C,F6,C5,E7,ED,9F,40,7B,B6,1D,AF,C4,7C,4A,FA,0F,86,47,F4,EA,C6,BC,3C,92,6A,9A,45,26,AD,95,23,B7,1D,70,C5,D6,7C,66,ED,43,DB,A2,74,B3,DB,48,61,A9,67,89,58,27,37,C8,79,D1,14,54,EB,1E,B2,31,A8,31,36,42,16,DE,0E,49,06,F2,0C,F6,9B,CD,14,A5,78,62,10,68,EB,57,E0,CF,58,81,B0,72,B8,03,D1,AC,DA,BB,14,58,55,8A,13,1B,03,60,0E,8E,85,BD,0C,6E,34,76,5E,E3,05,DF,BF,E2,12,C4,57,A0,54,D3,63,EE,8A,B3,6B,DC,54,65,0F,B0,A2,38,2B,3F,69,30,87,BC,39,F8,3D,B7,16,49,86,53,DD,AE,20,E3,BF,9A,F6,12,E2,C2,19,25,87,49,FB,C0,14,D0,4F,13,54,F8,98,54,2E,63,14,0D,60,E1,BC,01,F0,6C,0F,EF,19,36,18,A2,2F,90,FE,D0,F7,1B,C7,00,D6,0E,90,8F,E2,70,1E,A9,A7,AE,F7,13,3C,AD,95,04,10,E9,A6,8B,6B,C2,8F,92,E4,F3,F2,CA,27,4B,16,A5,55,1A,78,CE,10,B4,0C,70,2D,07,27,88,7A,30,D0,37,9E,9C,E1,3A,73,EA,68,EB,2E,96,5F,66,76,85,7E,C5,DB,E9,E7,72,EC,E7,21,E2,13,7B,22,0F,AA,09,3A,72,DD,60,57,B0,14,6C,43,B8,37,AE,E6,F3,C7,16,76,1A,8B,1D,1E,2E,27,3F,E6,F6,C1,A4,C6,12,B9,9C,1D,69,36,0C,56,99,70,CE,15,D8,02,69,3D,96,13,4D,E5,50,67,B8,E1,87,19,E0,5B,76,CC,33,57,C4,7E,D6,3F,E8,BE,78,39,0B,A9,8E,5B,E1,51,34,E3,FE,00,65,19,C2,F7,C3,FF,29,C9,0A,08,64,A7,03,3A,05,81,E6,E7,CE,EE,24,D1,1B,AF,51,17,AC,E7,DE,7B,57,32,BB,A3,D1,68,5D,3A,9F,45,CA,71,DD,F8,05,F1,D2,82,7B,76,68,84,54,18,7E,9F,DA,73,F0,98,BC,74,88,D2,25,6B,58,BE,59,86,96,0A,C4,50,5F,47,E5,32,12,43,35,F3,9B,41,C5,B9,D0,F1,2A,40,93,12,BC,72,50,2F,11,F1,89,0B,E6,E4,F8,3F,68,C3,F9,6D,98,B4,C3,92,FC,84,28,14,6C,21,15,B2,23,A8,03,5F,54,02,2D,DF,AD,E0,3E,D2,05,08,52,96,94,82,3C,A1,A1,18,EA,99,D9,D4,4E,88,0F,F1,E8,BC,AE,CE,6E,42,7E,A9,0F,2A,B9,91,4C,A8,D3,8A,A0,63,71,28,19,02,82,4E,D3,C0,CB,CB,A8,79,45,D5,94,1C,C3,FD,B6,04,2F,D6,23,73,FC,B8,FA,83,F8,19,03,CE,F7,3F,F9,CD,52,81,0F,1A,35,C9,EF,75,06,E7,46,68,03,01,42,8F,B4,52,4A,FF,F8,79,75,9C,E6,05,7A,C7,96,AB,72,82,72,B8,53,2E,D1,6B,D8,FA,BA,65,4A,1C,4F,5C,47,B9,F0,FE,63,C9,AC,35,21,5B,42,E0,4C,EA,21,77,3B,7B,24,2E,76,20,21,82,C3,59,69,6B,5A,D8,17,48,2D,74,A9,51,1A,F6,96,05,88,D2,A3,BB,1F,CB,41,6A,3F,50,A1,B8,06,0C,14,FD,9C,4D,BA,27,22,04,CE,8A,DD,0D,29,A7,54,E7,8D,AC,F6,4E,0C,8A,81,FC,18,A8,08,CE,41,EB,65,49,32,CD,74,1C,1C,11,35,E4,E0,21,CD,EB,FC,84,52,E2,A9,B4,78,EE,D6,C3,C0,35,A1,53,2F,E1,0E,36,7E,33,17,38,3D,29,CF,01,1E,F0,FF,E5,48,69,B8,17,C8,A8,10,FE,DF,31,E0,6A,66,38,3B,8C,54,65,5E,14,E3,34,55,34,69,90,6C,61,22,95,69,83,5E,5B,BA,55,BD,ED,09,CE,D7,7A,12,17,87,2B,4C,1D,89,82,1A,C5,55,6B,47,44,5A,31,22,31,6A,F5,FA,1E,DD,95,00,A1,8C,66,64,0A,0D,62,2D,08,B9,B2,6E,59,2D,F9,14,59,11,16,82,A5,3C,31,C0,89,AC,DB,F0,D6,FB,17,5C,2C,A4,2F,68,81,5F,F0,EC,DF,9B,83,F5,1C,C5,63,44,51,E5,37,85,A4,5B,6D,2A,32,D0,27,89,EB,CC,96,BF,40,83,DF,D6,09,1C,25,7B,90,E3,CD,C1,4B,4F,D7,D6,C0,28,E4,E4,F8,A7,2F,BD,5C,E5,B3,C4,3B,E5,E7,F8,56,FB,FC,AC,56,48,EE,39,8E,E6,DE,D5,69,57,99,BD,E4,62,B3,16,1B,32,B2,65,00,3C,F2,1A,21,E2,3D,60,19,8D,9A,5D,38,67,96,4E,FE,20,8A,09,92,B3,A0,94,88,42,89,56,21,DE,12,AD,C3,20,92,16,55,E8,18,47,B5,5A,64,19,6F,8B,DA,05,9F,74,E7,F5,1E,46,6C,BF,41,2F,9B,22,19,9E,57,5A,2F,AC,99,DA,07,B9,D2,F0,FA,6B,FE,68,D9,2F,D9,D9,A6,D4,71,A4,EA,E5,66,2E,90,3F,11,CE,4E,2A,80,8F,46,98,D0,B8,24,99,3D,C0,A0,61,C7,0D,6A,1E,6D,D6,2A,D1,33,0B,34,84,EB,76,0D,91,F1,63,E6,9E,86,89,05,E9,4D,E0,6A,F8,76,14,BD,49,F7,44,4A,64,D6,C9,8A,3E,00,2C,16,93,31,2D,26,33,4D,03,A6,1A,01,D2,59,56,B9,AD,CE,E6,C4,C0,E8,AC,BE,95,AF,42,DB,5B,D8,48,8F,86,8E,21,7B,E2,29,F6,83,70,E7,0A,30,06,A1,75,00,02,68,16,C2,37,4C,3D,2B,2E,23,D2,49,E5,E7,6C,07,41,04,99,14,85,B8,DB,23,D3,67,F0,B9,C9,44,F9,92,8E,C4,0C,CD,1D,2E,49,56,16,B1,81,07,65,2F,1B,69,55,EC,70,E6,CF,BB,92,25,C5,F2,E0,4D,09,5D,E8,47,5D,12,76,66,ED,50,85,DC,32,5E,6A,53,EA,BC,23,70,7C,F2,44,9A,F8,AC,00,80,D2,F3,FB,A5,0D,63,5C,11,94,6D,FF,48,B9,C7,5A,7C,E6,B8,74,69,5E,49,34,C0,4A,D7,D0,82,76,6D,62,A2,2B,35,4B,20,DA,B5,2D,00,AC,65,10,6A,FF,59,C8,14,90,5A,ED,C4,DA,32,B5,92,98,D6,5A,4F,51,6D,51,32,E9,B0,85,39,93,9C,50,F5,BD,C3,0D,48,50,D5,03,B4,E3,38,9A,93,C3,CA,1C,9C,33,3F,8E,DD,05,04,92,E6,D2,C6,F1,BA,C9,59,14,85,C9,5E,CA,FE,57,81,04,DB,F5,3C,48,4D,B0,60,5A,3C,A0,ED,84,5D,9F,5B,7D,E4,B3,AA,CA,26,99,D4,B7,05,6C,29,D4,2C,C0,D2,4F,F6,B8,F8,7E,89,A7,3A,82,54,A3,52,4B,4B,B2,4D,F5,4D,E4,7D,CD,3E,F4,03,18,B9,9C,ED,01,AD,93,07,C7,3F,EC,51,75,10,B3,63,FC,06,B1,F1,50,44,7C,B8,4E,D7,E2,33,54,7D,8D,23,9A,73,8A,CF,AA,36,43,60,D1,FE,1C,DD,D6,F3,35,C1,16,AD,46,29,E3,1E,14,BC,58,8F,F8,B7,35,AA,C8,FB,83,43,A4,A8,EB,E5,CB,FF,2B,A7,06,82,9E,6B,9E,FA,34,BF,F3,11,EB,0D,A3,09,AB,FE,11,ED,7C,3D,B5,C5,53,CF,DB,27,C7,13,D3,01,14,90,F3,E2,CD,37,A6,64,7A,C4,4B,43,CB,FC,6C,C9,C3,D0,0B,EC,03,8D,49,3A,DB,58,04,8B,FC,70,96,FE,8C,F9,58,A6,3A,4C,DB,75,DA,07,AD,75,A9,F7,B3,39,8D,A1,12,D2,8D,79,80,B1,25,BF,04,1B,9B,5A,07,1E,2F,69,A9,48,95,E5,AE,E0,11,A7,E2,C5,AD,B6,E8,13,D8,CA,66,A9,CA,F7,D0,66,73,D7,63,3E,33,78,55,DF,2B,21,06,59,FB,29,23,17,6D,89,2E,9B,81,83,0C,2B,9C,C2,E2,15,CF,F3,06,14,C0,14,CF,A8,DF,D8,76,B9,BE,73,7F,D5,BD,F8,20,65,72,CC,3A,F7,EF,E6,F5,A7,ED,AB,7A,E3,40,8C,E4,82,E6,14,A9,BE,18,A2,48,B6,9C,65,82,44,48,5E,9B,69,F0,F7,FD,A3,59,57,EB,77,C3,FB,97,F5,EE,09,66,08,41,BB,23,85,43,CE,D9,54,32,0F,04,D5,8B,0A,DB,5E,8A,FB,63,CA,CC,46,E5,A6,51,C6,43,52,FA,62,DA,AA,27,AA,97,5B,80,4F,BB,32,36,6D,51,C7,85,46,FA,7E,2B,A9,CD,2F,15,3A,D2,3F,68,91,53,D7,11,50,0F,67,1A,F5,C2,10,A1,B9,E3,8E,7D,E6,7B,5D,00,92,CB,2B,9A,1A,0E,95,3C,80,3B,C4,F1,7F,07,BD,C9,90,F5,42,CC,D6,35,E2,AA,5F,A9,C9,BE,D0,CE,CE,AF,55,3A,27,80,78,7A,33,1E,E0,76,B1,7B,2D,55,61,C1,39,DB,CB,6A,97,05,EB,E7,8A,2B,EC,20,FD,04,1B,E7,0F,DA,4F,13,03,60,E7,43,C5,DA,CB,8F,3F,D8,E0,3A,6D,0F,4A,59,52,31,29,25,CE,9C,7A,39,C5,2D,C2,98,61,1F,DF,80,AF,57,26,2D,F3,FB,01,4A,7E,9C,6E,9C,DB,5E,B1,A0,0F,41,F8,59,F5,DC,76,3A,CD,19,95,60,4F,5F,12,A6,DC,76,D6,8E,24,B8,06,79,87,D4,95,46,BB,E0,AD,2E,E4,99,25,66,F1,FC,1F,48,51,4E,B3,A2,4F,BF,21,93,E7,C2,FA,E9,42,B1,72,82,A6,74,70,62,D8,1F,A3,44,77,96,23,42,61,DC,7C,F4,EF,3F,62,68,52,F8,E3,4A,BC,4B,C5,61,68,05,44,C0,09,E8,F6,38,81,F3,EA,58,B8,24,78,E0,28,95,9E,59,0E,29,26,84,FC,8E,23,20,30,75,36,95,52,1B,80,3E,5A,9A,74,5E,62,A0,1A,EF,47,BB,FC,43,54,3B,76,94,6C,7F,5B,1F,2D,6D,54,81,89,99,34,04,94,A3,8C,DD,F6,8A,D2,7C,17,89,9F,E8,BD,DC,F5,B5,41,53,90,CF,2A,7C,AF,C8,18,7C,38,E6,0E,5D,F4,86,4B,B5,A1,4E,E3,DE,DF,43,08,4E,74,49,D4,AB,42,EF,5F,C0,E8,E2,85,77,5B,F7,12,6B,21,13,81,00,3E,4F,4E,4D,90,50,E5,49,D5,F4,7E,AC,CF,9D,05,7C,32,8E,7F,30,B7,B6,A9,21,E4,51,79,17,57,87,82,B3,B1,60,03,09,5F,DF,63,7C,0F,C3,66,0E,4B,20,DC,C0,62,7C,28,D0,EA,75,5B,2F,AB,C8,72,CF,07,B3,A9,40,50,27,6D,8B,E8,C7,0D,D5,31,53,48,F6,CE,24,DA,4A,6E,1B,C3,AC,70,62,97,95,02,AE,55,50,CC,73,3D,CB,DF,1B,1E,B3,C2,9B,D0,26,52,62,28,31,03,49,33,B8,44,B1,A7,9E,23,12,29,9A,34,02,46,A7,31,68,2D,99,23,AC,46,94,80,88,99,CF,B1,D7,51,3E,9A,83,B1,04,C3,16,B7,A0,10,0E,C2,F7,2C,6B,92,3F,A7,0F,8D,24,C1,3D,87,32,BC,FA,27,37,2D,BA,94,20,CB,C3,0F,A3,B5,F6,07,C7,49,6C,2F,72,E9,16,E9,D8,CD,21,54,A6,2B,CB,E8,85,C4,95,12,29,B9,EE,CF,49,97,1B,0E,A6,75,CC,50,B1,53,1D,8D,E8,82,5B,0C,3F,33,A1,17,1F,5E,CA,A9,90,C9,28,E6,7C,86,28,E1,56,37,E0,F5,77,63,A1,66,FE,59,33,1E,1C,54,F8,08,3C,D2,8B,51,27,C0,9A,F1,96,5E,7E,1F,A8,FA,AB,FD,96,5B,1C,99,32,25,86,6D,B0,4B,B0,0C,B3,B0,D2,AA,C4,AB,07,8B,B9,E2,0D,7F,DE,9A,A6,8A,A2,B4,A6,DA,A3,88,F4,79,75,0B,2C,24,BD,52,F4,12,33,DA,42,BE,4F,8C,69,A5,AA,E1,F2,A2,CA,0F,C9,1C,19,09,30,50,C6,F4,82,88,22,73,AC,75,69,4E,E8,EF,64,96,E0,43,10,82,13,35,A4,94,AD,2A,DB,40,4D,82,82,A7,5B,0C,E3,8D,96,DC,EC,BF,A3,B9,8E,79,2F,04,8D,F5,B5,9F,32,9E,CE,21,55,65,6D,0B,26,10,C8,DA,6C,78,EB,55,DD,80,63,99,D0,89,4C,99,E9,51,74,0B,67,56,2D,08,12,C9,E8,81,F0,40,36,13,73,F1,58,03,C5,DC,05,7F,0C,BA,D4,51,24,C6,4B,EF,7C,35,EA,6E,36,B0,7B,AF,86,7A,5D,9E,D4,8A,EB,A7,64,4E,8D,6C,8E,31,3D,AF,4F,7C,4B,81,72,F2,05,41,2B,DE,3C,1D,18,24,92,71,57,4A,0D,30,FA,5E,20,75,8B,36,0F,59,B9,6C,76,D1,69,7D,23,97,0F,71,40,AB,56,2C,54,C4,C0,53,0F,E9,64,B3,89,1C,8F,10,10,BF,49,8C,7A,90,E0,80,98,99,BE,81,53,3B,A8,E6,25,AD,0E,40,E6,45,D2,B1,1A,B4,CC,4A,FD,1F,7A,61,A6,78,CE,FA,E6,DF,31,52,EB,BD,A5,06,E8,75,C8,4C,B4,46,3F,EE,03,2C,91,3E,7F,9D,87,5E,A0,FA,4B,65,BD,89,EC,67,C0,25,69,DA,FB,68,8E,F5,90,30,F5,C7,C9,2F,47,31,47,56,FF,9B,D8,53,67,1A,96,09,8B,84,8E,A3,CF,DC,BA,E3,10,3C,0A,19,E5,71,F3,CE,13,F0,CE,04,72,82,25,BC,BD,7A,AA,65,41,DB,0B,FD,28,25,3D,76,1C,8B,42,C2,6D,5D,92,8C,86,EA,40,D5,B5,5D,83,07,03,8D,AE,26,28,E1,4F,9F,7C,A2,A8,72,0D,9D,F7,84,8D,B6,EE,AE,5A,D5,73,D8,45,01,D4,50,40,D9,4A,82,7D,21,59,56,03,7E,D9,B3,FA,3C,D0,6A,05,A5,FC,63,DD,2A,1D,E3,CA,0A,65,7B,37,60,F0,C9,F7,05,CB,8D,B1,59,03,42,EC,6B,6C,97,31,B5,DF,21,F3,34,31,7F,50,83,01,79,50,34,48,37,D8,44,C0,47,50,04,5A,97,37,9F,10,7A,C2,78,15,D1,F4,87,94,D5,45,65,17,B1,7E,5B,07,81,DE,90,A5,6D,F9,69,5E,CF,4A,E5,B2,84,1E,4D,43,A5,68,E8,A2,59,F3,B0,DE,85,DD,0C,4E,B3,95,B8,28,E9,BB,9E,C1,D8,59,85,E1,3D,2B,75,04,DE,BE,05,0F,96,14,95,18,EC,77,5B,2C,D1,93,D2,6A,64,6B,36,37,F5,86,26,21,2E,CD,DB,B3,06,31,8F,6E,85,6C,A2,E2,82,B0,61,4B,15,9C,79,9C,8F,52,54,0A,2E,09,EE,A9,BE,5B,01,AB,75,C4,76,77,EB,20,26,BF,06,00,0D,9A,C7,DE,3B,87,A7,86,32,BE,67,1D,10,3D,FC,65,A0,42,F2,A9,0F,45,F4,7D,AB,8B,7C,5E,C8,0D,C5,5C,0A,C2,90,AB,C9,43,03,54,68,75,13,F2,21,97,1F,7D,CF,00,86,62,54,40,B1,32,4F,1B,98,C4,D0,37,18,9C,5A,7C,27,C1,CE,B5,C3,63,1D,9F,D5,13,64,C2,6F,65,97,6A,3C,34,DE,4B,DA,2F,FA,9E,7E,5E,97,7F,64,9F,FF,2D,AA,2B,BE,8A,DB,1C,78,41,C0,6D,0A,3C,77,D4,A3,C4,1F,6E,B5,D8,2D,27,C1,1A,F3,14,BD,1A,4A,C8,95,D1,9F,DA,8E,0C,78,89,A3,44,79,0D,7A,D4,3F,74,B7,A8,29,7A,D1,09,76,FE,3C,F8,12,22,06,6A,F0,A9,11,E1,0C,3C,5F,48,8E,7F,E8,17,88,C9,C7,D9,24,8E,EC,3E,5F,3D,30,9C,24,DE,0C,4F,EA,1C,87,7A,27,F4,8F,23,16,57,3E,85,63,7F,D6,E7,5D,B9,31,A7,36,B6,95,49,9A,63,2A,D7,DE,D8,86,FF,AA,C3,87,96,34,54,F9,F7,A2,75,03,02,07,28,F0,3D,ED,E9,0B,A6,84,F2,35,33,81,6F,0B,B0,F9,0B,7C,55,F3,9C,A9,6D,E0,7B,9E,64,EB,70,C0,CF,96,83,06,8C,90,EF,59,C3,C0,7B,F7,BA,CD,BA,DB,A7,F0,2E,6A,77,58,BA,8F,18,71,3C,A9,A9,C8,A6,BF,AB,E4,8D,C7,6F,10,12,96,69,0B,08,02,BE,32,D5,71,78,29,9A,51,8A,A2,EF,7D,71,6A,C0,C7,E0,07,2B,B9,AC,DD,49,12,3B,8D,39,21,73,AC,8F,D0,96,5F,95,5F,37,18,C0,9B,F3,79,7E,21,07,A5,AF,4C,F3,B0,2C,32,11,F0,5E,D4,CB,A8,04,F6,69,48,65,88,61,AA,A7,ED,6F,04,5F,C5,94,0C,A3,5F,E9,59,43,D0,6F,44,D5,38,E4,6C,31,96,51,5B,F8,23,DA,F4,DB,22,C4,37,11,78,68,7E,BE,4E,1F,8F,D3,4C,26,11,0A,B9,BC,18,F9,21,C2,30,62,3F,9F,63,E6,80,9B,41,E9,A3,5A,11,AA,5F,48,E0,24,B5,20,47,DE,07,9B,66,D4,1F,BF,BF,1F,74,78,06,ED,A4,1F,19,E1,C6,29,D2,AE,8F,04,E3,5C,FA,9A,8D,3A,18,56,B3,72,76,60,7A,7E,69,0A,B9,A3,59,FF,EC,0D,0D,29,E3,6C,48,6E,65,CF,2D,87,F7,24,EB,29,02,2C,16,AC,E7,6B,66,11,0D,1B,FF,39,CF,48,5D,FA,0E,F0,9F,72,46,27,87,A7,44,65,C5,6B,21,3F,18,79,5B,42,8E,45,AE,FD,77,35,DF,F0,E4,10,23,6E,6B,09,F8,E4,EE,8E,C1,85,4C,7E,43,EC,E3,DA,86,3D,4C,90,D7,3B,61,71,42,3E,1E,69,8D,98,88,D8,52,F0,D9,50,18,AB,78,8D,C2,AA,5F,BA,D6,DD,34,A7,7C,9B,5E,8A,62,63,90,42,D0,97,FF,C7,8D,FB,30,81,74,F0,3A,4D,3A,52,BA,43,40,CC,F3,9F,A4,B2,06,C9,E2,0E,BD,8F,2C,0D,84,40,E6,41,2D,71,90,69,4F,CA,43,CB,84,E8,38,27,8B,C0,AF,8D,F0,8C,49,17,EA,BB,BA,1B,EF,46,A3,A8,7E,B9,72,61,68,22,91,15,FF,6A,55,70,95,6A,E9,11,E0,88,99,D1,C6,7F,03,4E,80,4D,EA,D7,32,DB,63,8B,EB,EA,85,DC,EE,35,E9,6C,15,70,2E,26,89,24,87,3B,4B,86,47,CD,C4,E7,CF,46,5A,7A,7C,36,15,FC,5A,CB,E3,04,1C,F4,41,97,5E,D0,4C,63,E2,DF,AD,09,D5,C7,B1,27,46,50,7B,25,2D,7A,F1,55,2D,07,EA,A3,D5,16,74,77,67,F1,AD,98,F6,79,3C,12,BE,DE,AE,E3,B0,B0,04,3B,3A,35,12,19,8D,7B,B0,E2,ED,60,1F,BF,F6,BC,06,CA,E1,A9,A5,4B,34,FA,EB,63,CA,4F,DF,06,62,5F,38,40,0F,58,18,60,08,27,99,F3,D3,DA,37,0B,42,5B,81,B0,30,D1,12,3F,DE,F6,1B,AD,5D,E9,50,5D,F6,CE,8F,3A,5C,3D,A6,EB,C6,50,EB,08,F4,03,22,7E,F4,9B,9E,33,9B,A4,B2,E1,B1,BB,F7,92,F3,52,24,05,95,48,A9,5C,63,90,FE,04,8A,68,49,42,B3,62,77,5F,C9,AF,95,BE,14,D1,AB,E5,1B,31,E0,B1,10,6B,A9,49,55,80,7C,4A,28,56,D0,C5,E5,43,ED,95,FB,68,CC,BD,5D,A5,42,A8,A1,F2,FC,A0,E4,1C,34,67,07,EC,9C,3D,22,DE,7B,61,57,9C,57,3A,C3,9C,F3,52,42,92,81,B2,2F,80,E3,1B,08,8B,B0,06,77,EB,4B,AA,F6,13,92,28,67,79,BD,57,9F,71,05,D6,F2,9A,B6,C8,53,1B,97,D0,A4,FC,BF,DF,61,3B,50,72,6D,C0,3F,66,55,07,F9,BD,5C,E4,B1,07,85,53,EC,37,AF,06,0C,3A,93,12,09,1A,BD,94,BA,AD,63,C2,12,4C,A0,BC,83,2C,2E,44,86,37,1B,6A,F4,36,14,2D,21,B3,4B,15,17,14,7D,05,CA,14,79,21,3E,49,14,3F,67,3E,FA,C5,BA,92,17,7B,05,A1,6C,EE,26,A1,75,57,F5,36,DD,58,F7,9D,73,F8,A2,64,A4,93,35,69,55,D2,04,5B,DB,6A,75,10,09,46,3B,B4,68,E2,6B,47,CD,5B,8A,B1,C2,E5,10,32,C6,AA,8C,70,D4,47,CE,7C,CE,E4,2D,1D,B4,39,27,FE,2D,01,0F,F2,96,CE,80,46,FD,EA,5F,CE,89,D5,00,01,DE,F8,CF,EF,12,D8,AA,71,B8,AC,9E,6A,49,6E,CC,46,09,0B,81,7F,DA,2F,C6,44,74,11,B1,6B,7F,07,96,11,86,97,C5,36,C0,6F,67,60,9B,5D,51,C4,B5,F0,4B,F9,C4,89,A9,2C,18,AA,19,D9,D6,6A,44,F8,56,E2,A9,1E,F6,20,3B,5B,3E,10,D9,8F,1F,FA,0D,25,D6,84,2E,7C,B6,09,AE,E6,38,18,E6,FA,73,DF,DF,09,21,9B,A3,C3,04,12,6C,B8,AF,56,40,8B,E5,1C,FC,B5,AB,42,2E,44,40,CB,D9,9A,8B,E0,AA,D5,E3,28,8B,3F,68,CE,D6,00,4A,CC,A8,54,09,FE,57,10,67,0E,7A,F3,26,3B,0C,7A,58,6B,9E,EC,7D,6A,FC,77,76,88,AB,F4,95,E1,B0,E4,AD,35,5C,F3,C3,96,92,AF,6D,A4,EB,D9,42,A3,D1,EB,5C,2D,7C,50,3A,AE,A3,31,D3,FD,58,A6,EE,7F,8F,A6,FB,FD,97,9B,C6,E6,4E,8D,E5,59,27,AB,AE,D3,41,76,38,29,C5,59,63,4C,40,D2,6A,72,6C,78,1B,2E,4B,F7,D3,DE,84,CF,91,BC,F0,C8,9B,24,81,48,3C,33,51,C2,CA,16,FE,50,10,CD,A6,62,66,AA,80,9A,83,FB,7E,43,8E,7A,D4,63,FF,69,46,D1,8D,47,9D,1A,5E,53,B6,4F,54,78,8C,68,58,9D,20,C5,89,53,FE,C6,31,A5,F5,09,2A,AD,42,ED,0E,70,40,50,9C,DB,EA,BB,EF,ED,84,86,B4,BA,5E,D4,D3,56,6B,DA,A6,52,53,AA,41,D5,6C,DB,20,38,76,41,8D,BC,72,43,9A,A8,33,8D,C3,50,04,46,43,F0,C9,7A,30,4F,DE,9F,CC,96,7C,63,24,1B,92,7C,D7,9F,C7,B9,99,85,6E,3C,CB,0F,4E,1A,61,53,21,BB,B4,09,77,C7,05,94,07,08,4B,47,EE,36,2B,41,40,93,AC,30,AF,00,A8,1C,F8,9F,E0,20,6C,E4,30,3E,B2,40,7B,66,F3,72,55,4C,95,C0,80,2E,F8,7D,BA,4E,F5,33,F0,85,36,41,3D,BB,A2,31,5A,61,F0,9D,5B,69,C8,DF,BE,6B,93,62,F6,B6,65,51,C4,F4,CA,EE,38,51,92,94,17,C6,D2,DE,AF,F9,FB,69,91,08,7D,03,2A,D5,02,75,8E,0F,3E,85,22,4C,94,F7,8C,75,72,C8,95,B9,7F,93,0B,08,B7,FE,BA,AA,EB,96,31,89,31,70,12,18,93,91,25,56,0E,D2,2D,20,74,7B,7D,D3,75,C4,1E,08,F9,53,48,BC,5B,8A,15,98,B8,9B,99,CB,80,16,44,F0,E2,72,DF,BA,AD,33,36,9D,C6,06,0F,DA,F4,83,C5,13,E2,38,7B,4F,EE,BF,D1,62,EC,7D,87,6F,28,C6,80,F2,42,B8,0A,9D,C6,B4,23,2B,0D,B2,9D,A4,48,F9,A2,47,39,EE,F6,4A,92,6A,9F,42,C9,6A,1F,25,BF,30,81,0C,DA,2F,A8,E9,2D,1A,23,55,B6,40,7C,DF,37,81,02,7C,77,1B,DD,43,96,FC,DC,42,3E,A5,41,4B,F1,F7,77,40,F7,5C,F2,C2,6C,11,72,F3,D7,10,71,A8,4E,6E,51,06,CF,A5,AD,DF,98,4C,90,1E,3F,2F,DD,DA,EB,1B,3C,9C,13,4B,E6,2A,C6,BD,82,5A,A3,18,73,7F,D5,25,FC,99,3E,F8,07,BB,8F,0F,4B,BB,A2,2F,B5,9D,44,98,10,F3,07,8E,DF,CC,83,D9,15,BC,68,B2,80,E0,C8,C2,80,00,4E,1C,B5,6C,39,AD,09,5B,0C,70,0E,12,BF,28,69,EB,1C,67,6D,41,91,14,DA,42,17,B1,F6,3D,AA,3C,69,02,47,48,C8,62,CC,96,90,27,37,1E,98,00,7F,4D,66,DD,8E,FE,41,42,D7,0E,E1,E8,53,F5,9D,3C,59,53,0F,E4,95,9A,F5,DF,C0,4B,BD,A1,11,DB,6E,2F,96,84,3A,DB,37,E2,60,14,D6,5C,7A,F2,08,1A,74,47,4C,98,35,FC,4E,8D,22,6C,28,24,53,5F,1B,37,4C,A6,D0,17,68,CF,2E,39,EF,2E,55,57,CA,EE,C3,EA,06,A9,10,5D,0E,0D,44,F0,87,27,92,56,26,3B,4A,F2,CA,56,22,08,C2,40,79,8E,C4,44,C1,DB,28,46,9D,2B,E2,D2,ED,E2,0D,4D,F7,61,F5,E0,02,7B,0D,F3,0B,BF,4E,64,99,52,A6,EE,15,C7,E3,F0,AE,1D,9F,29,33,97,1F,77,2C,27,00,28,F9,CA,55,98,93,34,35,D6,D7,54,AE,32,AF,20,F2,C2,31,D1,4E,68,90,C0,B2,8C,29,78,67,9F,96,65,6A,EE,4F,79,B4,5D,EF,E6,18,0F,65,59,9F,24,08,DC,ED,0D,FC,D5,E0,75,BD,28,46,A7,47,EC,6E,11,94,73,56,A6,89,70,39,4F,CF,40,8A,F5,ED,52,B0,28,4F,06,93,7E,D3,8B,A3,47,E7,5A,A0,45,EC,4C,86,7C,14,B8,10,E2,92,EE,6E,89,52,71,8E,C2,46,FC,68,2F,8E,9C,8A,70,12,EF,1C,E4,79,2E,52,79,3A,D1,BD,4B,6E,33,2D,07,BA,E8,DE,3B,69,D7,5A,1C,1A,86,6D,CC,4B,CA,50,9F,5B,45,D0,5B,20,22,0D,22,D9,EF,4E,B4,AA,03,14,B8,9F,7B,5A,0D,2C,5A,BA,E4,77,12,D2,EA,46,A1,49,B8,F0,69,05,0E,50,73,36,F7,93,3A,BE,09,F8,5D,73,27,48,35,5D,9F,99,74,67,8B,76,66,75,F1,6D,D6,EB,1B,BC,98,2E,24,4F,57,54,4F,8B,0E,E5,7D,19,F0,78,5A,46,DB,02,57,CC,CE,1D,9A,BD,0B,74,70,BC,E0,95,EA,BC,9C,79,50,22,47,3A,45,1F,B9,38,F9,32,41,BC,8E,7E,21,81,06,B6,44,0A,56,D7,2B,E3,6F,57,4E,6D,4F,3D,F1,DF,50,17,D1,F5,C8,45,C4,F5,1C,1A,F1,77,0E,1B,84,42,FB,56,9A,D9,65,84,3F,12,01,07,A8,3E,AF,5E,BA,13,FF,59,63,8F,58,76,B4,42,2F,A5,FE,C9,03,AD,80,29,73,99,AD,58,E9,B0,E5,9A,B4,CA,3C,2E,6D,D4,7B,AD,FE,15,EB,2D,B6,1C,67,8D,C8,CE,7B,38,05,55,89,06,D3,6B,64,F5,FB,37,02,9A,37,09,F6,6A,9C,8A,23,09,D2,B8,3C,92,FB,DE,73,52,82,68,47,B2,33,FD,12,9B,E1,10,BF,99,32,2C,A6,61,36,96,59,38,22,49,2B,72,83,F6,E1,B9,13,90,A2,8F,D6,A7,10,E4,6F,BA,2F,EC,0B,18,65,B4,29,AC,A5,9A,3A,93,FF,CC,CF,77,15,48,BA,77,96,9A,FE,69,F4,DA,11,6B,25,7B,57,F2,50,12,A2,05,2A,A0,39,71,F1,30,23,F1,FD,84,C8,D5,FB,BD,BB,16,8D,B1,DB,8E,E6,57,BF,CC,51,FE,8E,CE,27,ED,59,13,79,9D,1B,DA,96,86,1D,65,75,1D,12,F8,FA,1F,A5,C8,18,26,74,F4,5A,8E,18,80,FF,81,24,75,80,4A,64,78,81,0D,26,DD,0F,2F,C6,00,2B,83,FE,17,9C,86,BC,A2,D3,BC,C1,89,4C,F4,C6,79,36,D3,B7,BA,F0,A7,12,46,41,A1,78,2F,37,89,1F,16,02,88,24,2B,E9,68,7D,2D,61,4E,EA,2A,8A,4A,06,85,2F,B5,AA,56,70,6E,6A,9E,A0,9E,C0,75,75,25,7B,A9,D6,E6,5B,F3,C0,5C,B4,87,8F,C4,BD,6C,3B,0C,24,3F,88,82,E0,1B,B9,3A,BB,5B,74,1C,63,27,B8,19,12,81,88,CB,00,05,C9,7F,B0,28,8F,73,A2,2F,2E,62,C4,8B,C7,1A,F1,B8,F7,73,DB,F4,34,53,7F,40,02,35,9F,35,BB,54,6B,F9,11,1F,BA,DC,C4,5B,44,D0,A5,10,AF,80,4E,AA,96,29,FE,ED,EB,89,EC,A1,6A,13,EC,81,36,C0,BE,22,32,98,A5,EC,00,8A,5E,DF,54,3A,A2,B4,C1,52,1F,75,08,D0,F1,DF,41,2F,EA,07,86,C8,C3,28,26,CE,3D,44,09,9E,0F,B4,2B,FC,F5,56,6A,F9,BA,57,87,59,4E,09,55,B0,FE,76,E7,5B,C3,5A,93,FB,44,BA,9D,55,14,34,28,89,3F,BB,2D,B9,32,19,20,D9,72,44,C3,A5,6B,20,0C,42,C7,FD,F5,E3,96,F6,FE,29,17,D8,66,82,67,D4,78,44,2E,56,25,99,1B,F4,BE,44,11,AC,B9,66,45,74,F8,66,71,DC,D5,B5,15,EF,92,91,59,54,D2,6C,1B,FB,31,43,3C,26,84,86,64,8C,30,22,82,88,5D,66,DC,45,43,EC,12,52,67,14,8D,61,6D,22,68,94,4A,BF,6A,31,22,C5,AD,BD,EC,5C,F0,F5,2E,86,36,7B,DA,37,98,5E,58,E8,28,D3,44,DC,75,2A,AC,14,C1,28,AA,D5,46,B1,94,FD,72,48,FB,2A,1E,34,88,AD,90,9E,86,16,FC,73,3A,4F,D7,0A,11,9D,A4,C4,71,64,56,C6,13,DD,B0,99,E5,41,61,91,5E,A5,E2,08,3F,89,82,A0,44,70,BC,7E,87,05,B1,07,FD,A4,E2,AE,29,96,2D,E3,1B,95,90,26,0B,3F,6C,E2,0D,50,08,13,9C,C3,B1,80,84,6A,AC,B3,35,D7,4D,C3,D4,BD,B0,F8,57,1F,51,8A,AB,7C,EB,5A,E5,C5,3A,9F,EE,4A,CB,8D,AA,C3,62,F0,8C,E8,17,07,9F,B4,9A,49,E4,68,2C,1A,93,A3,C9,28,C0,66,C9,25,A3,41,4A,4D,6E,B8,85,D3,4B,A9,66,8B,B7,A5,88,C4,CB,38,89,63,80,88,DC,83,74,0B,AF,90,03,BD,85,82,3D,7E,E4,3B,D0,B3,45,90,FD,5A,7B,48,04,87,E4,C6,2E,EF,A5,0A,D5,AF,E3,E3,C0,6C,89,22,00,FF,E7,FE,69,4A,2D,B3,BC,2E,74,0A,98,BC,1B,B2,6D,90,3D,9C,D7,9E,1A,4C,55,39,B5,7C,09,B3,AA,87,2C,C0,21,C8,20,98,18,46,18,5A,47,3A,0B,74,C7,0F,2B,CE,9B,EE,E1,6E,E5,02,F4,0D,BB,F4,A6,39,9A,05,2F,50,79,A3,E1,79,43,7C,3C,38,89,D0,7F,DE,5B,96,59,EB,29,6B,38,76,7E,31,9B,4F,57,45,90,79,B8,F7,A4,6B,A5,AF,F3,B6,9E,40,7A,DC,7D,03,09,71,37,EC,17,20,46,CB,B4,C8,06,B3,43,CD,E9,DB,76,DE,C8,07,10,F3,E7,B3,12,91,FD,45,5B,A4,9A,48,E9,DD,74,F9,7F,1B,35,EF,E8,4C,0E,3D,5E,6A,81,29,8F,92,24,52,F4,FE,59,4B,0A,65,9F,76,DA,8D,36,38,21,49,7E,05,49,86,88,7B,80,74,5D,49,6E,69,D1,80,55,BC,99,84,0C,8E,D3,44,B5,89,6B,F8,47,EA,AF,D4,09,84,99,74,B9,73,86,D5,67,9C,27,7F,62,60,C3,73,D1,4F,65,91,D5,11,77,6C,F7,47,72,0B,2C,F5,C9,70,D7,DD,3E,49,CB,45,51,65,E4,62,9A,39,8D,9C,CC,B1,E0,2F,61,8D,43,B7,4D,8E,65,CA,D4,73,AC,34,3B,7A,16,40,EA,B2,2A,6B,A1,0B,48,EC,79,E7,8F,2A,00,D3,78,56,9E,7A,E3,A9,0D,88,9D,16,52,63,4B,4C,59,85,10,DD,64,34,81,F6,DD,97,1D,E9,0F,EA,CE,73,0B,9D,01,67,E5,62,B9,5A,6F,50,C1,D5,EE,31,26,DA,C7,10,9A,E7,D3,00,A2,97,96,C2,DB,3D,33,99,95,8C,E3,DC,9D,CE,CD,FA,A6,9A,0E,FF,B3,0B,AD,A6,1A,4C,D7,1F,AB,3F,22,4A,AA,3C,C1,9B,8C,71,C2,AF,A5,BC,63,E9,BD,80,EA,3E,DA,E9,E3,55,52,9B,97,03,09,4A,0B,AF,D4,B1,73,12,08,DD,F2,2A,10,64,BC,D1,01,4B,01,84,71,46,FE,D2,8A,71,E4,B8,0A,EB,8C,55,C2,F4,D7,E7,B5,3E,35,30,54,04,0F,51,4D,B6,06,07,B1,50,73,B7,54,20,86,92,ED,93,C5,57,EF,8B,1D,7B,76,CA,13,E3,E5,81,26,A0,A9,0F,3D,D9,E1,69,52,9C,9A,91,B8,21,93,11,CD,6F,D3,F7,C8,ED,4B,68,D6,48,8A,AC,1B,2D,86,17,09,91,38,6B,15,A8,A2,E4,FF,89,DA,F3,26,14,50,85,73,19,B0,C9,AB,9A,0C,28,5D,5A,78,92,91,54,1D,3B,5B,AB,5B,91,37,3C,27,D8,29,64,1E,9E,99,BA,BC,5D,2A,5B,7E,7D,B1,12,5B,72,FF,6F,F8,82,F5,19,20,92,07,B3,F3,DA,2A,6C,A0,DB,73,0A,39,61,6F,03,20,A6,82,60,E8,02,F4,38,FA,C3,F5,A6,8E,44,5D,81,FF,4A,2F,9C,AD,B9,8D,16,E3,86,DD,81,F0,20,7F,AA,4F,7D,86,7E,94,08,3B,7D,99,74,B3,19,3B,B3,54,78,80,62,9C,12,0D,89,29,9F,5B,54,9B,1F,24,20,FB,42,6C,27,3B,24,37,7F,51,69,70,AB,0B,22,9B,01,18,DE,F6,A7,06,C9,F0,C9,60,53,B0,3E,96,BD,05,DA,43,99,D2,84,14,77,98,32,22,79,39,46,B4,EB,E1,38,0D,C5,19,3A,50,D0,22,24,B8,FA,46,65,C5,16,D0,39,C2,71,DB,88,78,E0,2B,7D,3B,DB,AE,44,38,67,61,A8,33,B0,06,AE,43,17,2B,61,8B,90,B2,C5,E2,9C,8B,34,5D,23,E9,E8,8E,9A,9C,11,25,2E,5D,33,AC,EC,D7,E7,77,13,12,0D,46,A5,A5,9F,8C,70,A7,B4,49,AD,C5,CA,4F,89,B5,FF,D2,F7,30,A8,DF,8D,DE,2E,7E,25,6E,7C,74,B9,C5,F5,30,03,F1,97,F9,55,57,3F,68,09,04,D0,58,7F,27,CD,74,2A,9E,6F,B9,BF,AD,4C,0D,65,79,0B,C7,1A,AE,5A,CC,5C,70,98,8B,CE,64,AD,4D,25,85,53,1C,6B,4F,9E,B0,FF,D4,F6,A0,1A,5F,95,74,62,F8,80,3F,59,D4,8D,41,FA,96,13,C4,5F,24,01,83,54,C4,47,1D,92,91,62,83,82,BD,DC,5E,15,98,F7,4D,76,EB,6E,F4,C1,E9,39,CD,0F,83,5C,2F,97,C5,26,35,85,01,B4,94,38,5E,60,ED,8D,08,A0,40,92,71,95,85,2B,C7,AE,EE,35,95,3A,90,11,FE,6E,90,1C,AF,02,F3,DE,6E,3A,C9,AB,68,CD,08,AC,A6,2B,6E,D3,F7,91,6D,2A,2F,0E,84,6A,BE,48,FF,77,97,68,E0,FB,FF,42,F5,37,7C,BE,F9,95,17,F3,7F,42,F5,CC,EE,27,07,6F,4A,E0,BF,8E,15,32,00,47,39,C6,A6,81,56,2E,BA,F9,A8,3E,40,0C,88,6D,87,71,94,33,11,2B,E0,F0,C0,FB,AF,36,16,F6,04,0D,F7,2B,99,75,18,E5,73,C3,7E,73,64,12,A6,30,9C,92,5A,17,BF,85,99,44,46,6B,4B,66,3B,10,D1,B9,B1,D7,1D,EE,A2,04,E4,C2,EF,B1,EE,B8,91,4E,61,BB,D3,3B,53,27,84,87,66,6B,5B,CE,B7,D5,8E,0F,E0,01,5A,11,C6,94,E9,6A,48,1A,5A,5B,F2,F4,A1,44,21,C0,3D,7D,17,51,DA,08,45,BF,82,E7,3F,2C,46,37,89,F0,C6,5E,E9,D3,09,40,87,A3,13,1E,FC,E7,72,E6,AD,AA,0D,51,E6,AA,3D,F5,F4,81,32,BB,88,DF,DB,01,B8,CA,6A,F6,E8,42,D5,30,0D,6F,AB,E2,5D,DE,F8,00,B5,F0,29,BE,E7,76,26,61,1D,37,67,38,E1,77,C9,EF,C0,8D,16,64,1E,6E,43,3D,3C,4E,65,CD,DC,36,11,E9,33,09,AB,23,CE,6D,1D,83,0D,A2,6E,D0,BF,D3,58,46,29,C3,A0,B6,C1,E2,9E,66,21,C5,5F,A7,91,E6,8B,CA,A8,F2,16,3A,2F,28,AC,35,64,C8,0C,CE,B4,A7,F5,10,44,A5,19,55,93,D1,FE,2D,8F,36,2A,82,41,44,FB,25,06,5D,B1,5A,DE,1B,26,7F,92,81,C3,0C,C9,30,DA,F6,86,0A,5B,3C,A5,AF,FE,5E,74,E8,43,3B,D6,BA,E8,C6,AD,E4,28,51,8A,F3,26,4A,6B,8D,FB,D1,55,AB,BA,4A,B5,1D,51,C6,79,30,C0,CD,82,9A,D2,8D,CC,30,3E,EF,84,8B,3A,B1,93,FD,F3,7B,7D,A5,A0,90,1C,F3,37,33,98,0C,01,8D,CE,9E,E8,BB,F8,9D,E8,12,C4,E4,95,3E,42,66,10,AA,E6,F8,1B,22,C2,B5,7F,74,8B,78,C3,BA,D3,D8,E4,5B,F5,2E,2A,83,E8,1D,82,8B,CB,7E,C8,83,77,C0,3A,9D,C8,D0,8F,04,77,E4,E4,2D,26,01,65,C7,5D,90,82,81,B4,E5,53,31,A5,FF,9D,1C,DB,16,6F,C1,BC,0D,BE,52,08,C8,56,9B,73,CF,5C,E7,B9,49,93,90,3E,3B,8D,32,70,79,62,03,4B,2C,D8,A3,B5,57,09,D6,21,EE,11,83,8B,EA,50,BA,D9,A8,D4,FE,CB,31,48,46,B2,26,BA,FA,DC,3F,F3,BD,4B,4D,19,EA,00,78,2E,5E,99,FE,DB,56,EA,26,92,5E,9F,BE,38,39,B7,E0,08,C8,F4,04,68,AA,6D,F3,95,4D,7B,65,2E,0F,16,D3,61,75,80,FB,D5,AB,57,DA,9B,E9,93,BB,6B,C0,F9,31,50,D0,26,88,DB,40,4F,18,FD,88,4F,79,FF,9D,42,A3,8F,0B,99,8E,69,1D,01,10,E5,94,E7,FB,40,5B,64,C7,30,02,47,60,96,EE,7E,78,DD,9D,69,B5,94,DD,8B,EA,41,8B,A4,D4,B5,F3,51,D8,6F,A6,D0,5D,C2,86,F2,96,98,40,2B,8C,15,61,51,C0,B2,36,79,D4,4A,99,33,BC,AB,5C,27,AA,E9,B4,2A,2C,07,3E,99,4B,54,C0,20,4C,C9,A2,0A,F1,0B,B3,36,F3,5F,CC,D9,99,F7,1C,C0,D3,7C,93,38,2C,50,74,F9,F8,9A,92,9A,58,C2,1A,51,C0,AD,61,A2,80,7A,56,05,7B,68,91,8D,3C,0E,B8,4D,9A,DB,CF,22,D5,95,00,55,AA,9C,6B,E0,D6,38,51,40,2D,F1,F3,B8,FB,42,09,66,DD,E4,BC,EC,58,40,74,23,52,83,E8,08,E4,7A,70,67,64,B3,23,30,96,BF,34,29,80,E4,CB,B3,41,2D,03,42,7A,DE,60,91,00,3F,15,BF,4A,1C,4E,45,0F,DB,B2,20,A2,7B,D2,26,66,39,AE,25,A0,F4,DB,50,7E,92,41,C5,E0,D3,C3,88,BC,A2,9C,DE,B3,A1,C7,3A,A2,38,35,30,41,6D,87,A7,B1,B1,AF,D8,7B,91,DF,4A,66,12,89,A6,5D,55,B9,64,27,40,5F,85,E2,17,9F,46,D6,F2,C3,BB,CA,E6,79,CE,40,19,78,69,2A,A1,B8,67,DE,88,D3,29,90,A3,D2,E0,E2,5F,4C,71,83,93,24,87,B9,67,26,92,47,F8,32,11,09,38,49,88,11,F8,69,F1,32,8F,A9,AD,99,81,C7,6A,9B,A6,9F,53,84,C3,36,20,77,5C,DF,E5,FC,56,43,E6,A7,CB,20,72,53,74,9F,FE,71,C4,14,39,EC,C5,D7,03,8F,05,C7,0E,98,E5,B0,E9,34,8C,57,7B,17,11,2A,E7,5F,93,27,9C,34,F1,BF,49,06,67,48,DC,4B,9D,85,BC,DC,00,C5,C9,0B,F9,47,FF,B4,93,BF,72,54,28,33,6F,79,43,4E,74,C3,8B,8F,54,BA,DA,5D,30,02,06,2F,D8,A2,CC,5F,23,3B,1C,9C,94,F3,2D,93,80,35,BB,DB,3E,AB,31,C0,77,50,FA,6E,FF,CB,B2,52,22,BE,B6,6A,40,03,47,B1,0A,B1,A6,31,14,58,8A,91,8C,00,BC,DA,C9,91,C8,56,8C,2D,14,F3,8B,93,D5,D3,DD,21,AF,6B,C6,90,F1,71,FC,99,A2,4A,F4,DE,31,86,4E,1B,A5,3B,16,F3,CA,1E,1C,E9,2C,F8,6C,09,71,DE,E8,F5,FF,74,35,6E,9D,3E,F6,DC,06,D8,6C,91,AE,70,D5,F2,6B,D5,25,DF,C6,C7,0F,FF,0F,2A,87,AA,71,FC,D4,35,4A,78,5C,F8,84,D3,6D,55,5A,94,E9,57,71,C7,C0,C1,73,E9,5B,A1,AA,7C,EB,A1,AC,5C,2F,43,AC,2A,5D,A6,26,23,64,7B,67,E1,D8,64,ED,B7,13,83,93,B6,25,4D,C1,CE,8A,D4,9C,5B,E0,92,6D,0A,31,7C,1E,41,D9,9C,C6,98,69,F2,48,F4,4C,27,61,22,71,85,9C,36,EC,1E,45,13,8C,1C,A1,B3,C4,91,6D,C9,88,02,77,A4,9F,3D,5F,FD,72,7B,88,EF,53,B3,6F,B1,EC,9A,4B,54,05,D6,F7,B9,45,3F,93,33,24,A0,00,77,CF,61,60,51,11,87,40,30,12,CA,37,F7,34,DA,32,4F,BF,58,26,D2,4E,84,5F,2E,4F,CF,C4,C2,04,7F,76,11,6D,5C,86,84,22,88,59,3C,BE,26,76,78,F5,02,E2,60,4C,62,66,BF,FF,3C,AC,32,7B,F3,0B,46,34,EF,E3,E9,57,5D,3D,21,C1,F7,11,70,19,A2,18,A9,39,FF,8E,B4,42,55,9A,43,2B,D2,9D,78,DD,7A,25,96,D0,57,5E,D6,1E,5E,E1,02,51,51,7F,DB,61,BC,D3,7A,AF,08,B9,91,30,3F,FF,41,D6,FF,00,37,9C,8B,D1,25,09,85,C3,49,DA,FC,0F,B6,B2,94,2F,3E,AA,0D,8E,9D,5A,7C,F5,9C,33,4A,BB,1D,D4,F3,53,68,5F,54,83,C1,D0,8B,56,D8,3E,DE,83,1C,3C,2B,77,17,8B,43,95,FF,A6,77,7C,5B,50,43,A6,83,50,81,92,BA,38,22,BC,4E,78,07,45,A0,D7,3F,ED,1B,97,91,4A,1A,F0,68,C8,98,F4,0A,2C,76,31,FD,33,BE,B4,9D,BB,C4,F4,89,4B,AF,1A,ED,49,E0,21,D3,99,1F,E5,B8,92,2A,10,BC,BA,90,A6,7C,4C,9F,47,7C,4D,48,A3,C3,4F,FD,45,4B,10,91,77,9B,87,31,14,3F,20,2E,F7,01,46,87,DB,C9,C4,F1,E4,F3,7C,29,17,86,D4,46,F9,B9,8D,CB,F8,27,E0,03,E3,08,22,5E,3A,77,F0,EC,DC,F7,48,08,D6,E9,9D,69,38,57,30,06,61,64,E5,45,3F,D0,7C,E5,99,3D,C3,91,F8,8D,31,10,61,33,5E,3D,24,7C,F3,F9,4F,C0,52,6E,0E,AE,7E,D1,AF,27,C8,26,5C,DE,5E,D7,AC,3B,10,38,FB,7C,C6,6F,17,1E,D7,A8,7F,FA,89,E5,A5,B1,CD,EB,3E,A5,39,1E,E3,07,52,3A,86,8A,93,EB,BE,D2,6E,D3,D4,9C,30,2C,94,98,89,1C,85,DA,E0,A5,59,79,38,AC,71,4A,5E,87,DE,30,DD,B6,95,7C,41,DF,B5,C1,1D,CA,6A,69,93,53,14,9A,80,87,61,28,7B,43,47,87,00,AA,20,4E,3E,1D,66,19,86,0D,5E,04,7F,7E,00,A5,61,61,D9,8E,8A,4B,87,EF,FC,FA,68,21,C9,88,1D,40,17,86,ED,EC,F1,2C,27,D7,2D,7B,3C,C8,47,42,37,BE,33,29,DC,27,11,28,51,8D,0A,20,28,56,A3,57,33,A1,A1,9F,7D,C3,C7,67,D0,75,CB,5F,52,28,C0,BB,FA,D4,3B,02,14,AD,7D,08,F4,D1,7C,EA,61,A9,AC,0E,9E,89,E3,49,7A,6C,F9,21,FC,1A,E1,91,30,C7,0E,59,8C,A3,25,9C,10,00,4B,AE,89,4F,FB,14,07,72,2A,15,27,09,94,F0,A8,37,D9,0E,8A,EE,CC,E1,53,46,32,75,EF,8C,77,7D,40,2C,2F,8C,30,75,9B,7B,0C,6C,A5,30,33,04,80,47,BF,48,52,B5,C3,0C,75,4E,85,DE,C3,58,FC,36,7E,75,06,FC,AA,FE,BF,48,BA,6C,A6,3B,56,90,51,2C,E4,38,FD,A9,69,0D,25,1D,E7,A1,02,6B,A6,F8,38,AC,82,E7,2C,7F,11,73,F2,19,46,11,C0,CC,C0,D0,6D,7F,00,04,1E,AB,3B,90,14,53,EB,63,45,E1,DD,46,E2,50,02,BB,29,3F,4A,C0,19,ED,C3,4D,64,00,E6,8E,3E,3D,EB,ED,B9,66,6C,CA,0B,0B,CE,94,FF,3B,F4,67,F1,31,67,70,DC,0D,1F,0A,B6,B0,99,DC,0E,D4,E6,B5,5D,21,F0,EE,BE,0B,85,BE,F8,A9,63,1D,D2,E0,A1,20,4F,EE,B5,99,D1,C9,B7,18,E2,48,7C,A0,A3,76,A3,AB,B8,F8,31,6B,42,32,C5,C7,5F,81,43,07,7B,CF,0A,0B,D3,FC,9C,64,4F,BF,F8,77,81,39,CE,46,29,90,D5,36,17,1F,03,D4,68,4F,9A,78,93,5C,4B,AD,BE,30,6A,44,97,88,73,E3,07,C8,C5,EC,24,B4,FB,46,80,3E,B1,70,88,4C,2B,E5,F6,BD,13,AE,42,BC,AE,0E,3D,8F,95,03,2C,E1,90,D5,74,75,4C,7A,15,71,08,1A,75,D9,3A,D3,90,CA,8B,6A,0C,29,FB,31,DD,58,24,9E,06,26,32,E8,0D,75,F8,E2,8E,4B,8C,FC,03,DD,38,16,D2,D2,56,55,62,83,53,2A,61,96,49,C5,1F,4D,B1,AF,B7,70,98,96,35,47,3D,C2,81,A9,A5,00,A1,85,A2,34,43,82,FB,91,FA,42,6A,ED,07,6B,F8,D6,74,F6,5C,19,5B,BC,6B,45,C3,4C,3D,34,17,BB,EE,6D,CE,6E,32,24,7F,F0,DE,4D,96,E5,0F,FD,28,88,98,32,4F,2E,A5,CA,70,CD,A7,3D,53,9B,3E,9A,2E,04,77,D3,68,73,D1,31,85,0A,D9,F7,C8,72,18,29,52,E7,32,49,1C,5B,C4,EF,1C,6F,CB,0E,63,2C,55,2F,26,6F,06,1A,88,23,F8,16,FE,74,9D,B4,48,A1,86,FF,5C,66,03,C3,6C,66,86,C4,8D,1E,2E,CA,31,98,F2,B9,53,1D,97,6F,63,55,CC,BF,C6,86,FD,F8,DC,6D,D1,B3,BB,1B,6C,2F,32,E6,8D,87,1E,CB,F8,A3,69,7C,D0,01,7C,38,E4,B6,BB,2B,03,C9,D4,5F,26,21,81,1A,95,E7,22,9C,8A,3E,47,8C,9C,E3,53,FD,BA,F4,15,64,57,C2,45,56,B8,8E,0C,DD,A6,34,EA,0B,9A,E3,9E,2E,35,D6,AB,FC,65,3B,8C,AD,E2,C8,9D,F1,51,62,CA,7D,08,07,87,33,01,60,84,59,FF,5D,D7,C2,99,17,0D,AD,8D,E8,12,3B,27,BC,42,36,60,0B,8E,A9,14,FA,1B,AB,72,41,D2,74,45,C3,0D,FD,9F,63,B4,0E,CA,FE,79,C0,C5,A6,74,C5,66,26,D5,96,65,2F,C2,F5,7B,2E,6E,A8,11,F5,2C,DE,22,6F,01,1C,A9,69,41,B0,36,32,9C,DF,7D,75,32,E8,9A,95,D1,67,13,76,2A,82,A8,6F,57,18,B9,13,9B,C6,5A,AF,7E,E5,03,A5,45,87,9B,87,74,FA,F1,37,80,E8,E0,BE,F5,1D,0A,03,F8,C1,64,54,4C,44,AA,BA,B8,7C,15,2B,15,0A,4D,F8,E9,80,A0,69,CC,B3,EA,DD,65,AF,2B,73,65,D7,C7,72,04,FB,76,5C,42,56,A0,5D,A9,5B,5F,6D,13,64,18,C0,29,82,10,3C,4B,28,BE,08,9B,E4,DA,D3,AF,36,BE,A2,B1,2F,0D,3A,DD,C3,BF,E9,46,C7,55,4A,48,9B,62,DE,44,D7,B3,D9,4B,48,15,E2,13,BD,8A,0F,36,53,8D,6B,8A,0C,FF,0D,91,DA,BB,D8,13,C3,85,B7,C6,61,5A,08,8E,55,A4,4D,F4,21,AD,FD,CD,B1,F7,8D,69,23,CA,6B,1D,52,36,7C,FD,7E,CF,AA,5B,16,29,C2,6A,AD,14,59,C4,BF,46,E9,40,D7,E6,4D,DE,40,53,32,36,7A,F4,0A,2C,DD,05,93,4B,C3,DF,7A,D1,07,75,1D,DD,DB,96,42,C4,E2,8A,DE,6E,50,B3,F4,AB,53,F4,46,49,F1,56,B5,C0,FD,6E,93,06,90,88,FE,9F,42,5D,39,BB,C9,A4,42,03,A6,F6,66,D6,B3,13,7A,D0,B5,55,5A,59,4B,5C,DC,EA,91,54,41,80,DC,20,E1,3F,39,8A,5A,99,AF,9B,38,04,88,46,7C,4B,9A,A5,DB,06,CD,8B,66,EC,CC,99,E9,84,64,24,BC,7E,8C,D5,0E,F9,62,D6,FE,C8,AD,3D,04,6B,9F,92,43,77,9D,A8,96,E2,F5,CD,96,18,4F,93,04,12,4E,1E,5C,8A,53,FF,08,CE,D6,A7,83,1D,C8,C6,84,1F,A7,B1,2D,EC,30,F2,A0,AE,A5,CB,DF,DA,49,4F,13,A2,59,06,A5,7D,B4,3E,3F,08,49,30,E2,2E,29,35,98,49,4A,89,D0,54,67,8D,3C,AB,D6,80,13,8A,FA,7F,80,89,C8,42,20,7A,55,1E,01,56,7E,4C,C9,42,7D,22,F1,D7,10,CE,9C,C1,5D,DB,79,DC,B3,C3,52,E3,2C,6D,1C,85,0C,A2,01,8C,E6,DB,FA,4F,FF,7C,3C,BC,E2,AB,93,F6,FF,0F,2C,FA,94,5F,0F,53,52,56,7F,56,47,C3,EF,00,CF,D6,FC,B2,A2,56,6B,46,EC,56,C5,3E,2B,FE,70,E3,35,2A,ED,DB,07,92,0E,22,78,41,E1,55,7C,ED,56,4E,90,92,4A,79,8B,C0,F5,33,48,BE,12,77,F8,7D,F0,9A,41,C2,41,FB,43,C6,FD,E7,51,BC,B4,47,64,5E,02,BD,19,5D,3F,09,2B,D7,1B,5D,56,34,10,A0,10,59,7C,ED,9E,E8,94,BC,01,2F,37,78,7F,C6,8B,15,F5,18,16,35,28,10,2B,9C,9E,90,C2,3C,16,3B,F6,00,7B,C5,B7,7C,2B,5E,D2,68,87,C0,3B,04,19,ED,82,9E,54,57,80,6C,6A,1B,A4,B3,1A,8D,B0,01,2B,4B,77,52,80,31,01,0F,8C,92,1D,3B,D8,71,95,5C,B5,89,18,12,63,31,C5,F2,2C,37,AF,8D,80,5D,92,4D,80,9C,BC,A1,21,9D,DD,D8,90,F4,AD,31,94,AA,E2,8B,A0,24,38,37,48,23,F2,41,0E,C5,85,49,03,5A,C3,16,99,50,E4,A0,88,36,AD,4D,68,BB,B9,B6,64,C6,70,AA,41,32,5D,66,F5,30,54,EE,81,3A,75,8E,4F,BB,3A,EA,CC,81,80,9C,42,0C,F9,E8,98,7B,66,91,43,58,CB,71,A4,0A,5B,8B,83,1C,AF,A9,B7,50,F0,24,E7,F5,38,AF,34,E3,52,CF,1E,0C,16,70,91,78,68,E4,25,1B,84,78,5A,46,4A,BC,84,D3,3C,9F,CC,EA,D2,22,85,2F,AC,54,AF,6C,3E,72,37,E8,BA,01,A0,E6,CD,74,B8,21,7F,6D,A4,48,89,60,8E,C3,03,1E,C0,1F,31,60,6A,67,F8,84,03,54,BA,16,24,AD,AD,8A,5B,32,63,71,7C,1A,09,01,AE,97,DD,2B,F3,9B,56,D8,5D,2B,DD,93,51,0D,E1,91,C0,3D,19,8F,D5,16,64,6D,DE,2D,31,72,DF,12,11,61,B0,67,EE,09,D6,1C,D4,3E,02,91,49,E7,85,BE,09,7F,FC,92,8A,76,37,66,55,2B,F2,EE,3E,4A,3C,35,FA,DD,B0,AA,B7,C8,9E,74,0D,D1,69,8B,54,8F,C9,82,23,55,E2,34,44,D8,F9,C3,ED,D4,B6,51,EE,B8,D9,4E,17,FD,6C,E2,C5,E4,7A,8E,64,DC,0A,06,39,BC,87,9E,BA,EB,5B,0A,C4,E5,17,24,F1,0E,BF,A9,9D,C9,42,01,9C,6C,7A,05,C2,95,99,21,61,36,C9,83,7F,E7,66,F3,D8,32,76,0A,52,E3,19,B9,DF,57,1B,06,A6,86,A4,71,69,02,4F,6D,AB,E7,F3,9C,C1,24,7F,08,5B,FF,09,FB,4F,40,03,A7,B2,06,46,BB,A8,4D,39,74,F1,04,2F,0E,53,30,76,9F,C0,35,10,CC,5D,75,58,32,DB,43,D3,9C,4E,8F,D7,44,0B,09,A9,89,D8,1F,DD,6E,3B,BF,1F,D9,FF,27,05,98,7E,07,42,51,7D,99,04,0C,76,EF,D6,C8,03,14,19,C7,F6,B2,92,07,CF,58,69,7F,F1,7B,1C,6F,BD,D3,BC,EF,D7,D7,BC,64,88,5A,A9,68,02,FD,F3,85,06,1F,45,6D,77,5B,CF,2D,82,FE,48,F6,F9,71,70,89,08,27,55,29,03,C2,21,CD,96,71,E9,4A,0F,7B,A8,A3,32,FE,B5,2B,2C,83,6E,AF,60,9A,58,6B,C3,11,4D,90,39,13,BF,47,40,D4,BA,D6,C2,79,00,34,D1,EA,72,54,16,65,7B,43,EB,94,C6,1C,8F,07,4C,8A,09,96,F9,E5,F6,D6,4B,AD,97,76,61,01,D1,58,A9,49,8D,A8,AD,B0,DD,CC,52,98,CF,97,2C,5F,32,6F,B2,3D,25,E3,C3,BC,A3,77,F5,52,F9,3E,72,E7,61,1E,A2,5F,B4,03,D7,4A,E6,55,A4,49,87,5F,C2,55,30,82,C6,D1,2B,67,F1,65,1C,F5,35,E4,6D,17,C3,2E,93,C0,D1,8E,BC,92,84,34,AE,6F,18,01,0B,82,DE,E1,F6,4E,1B,B3,41,C8,A9,37,0B,E2,1A,57,C0,0C,06,62,F6,CF,8C,69,2A,B0,8A,44,8B,4C,36,C0,4B,56,C8,76,F2,45,05,21,E6,EC,2A,02,7D,46,F8,03,F2,2A,9B,21,63,97,D9,17,0A,CF,CB,AF,42,32,86,F6,57,C5,59,A7,1A,76,48,F7,81,52,4A,6F,9B,9F,64,B0,CA,8D,8B,F1,C3,20,9E,66,79,CF,7D,4E,C2,38,2A,D6,73,E9,EC,9A,B4,02,17,52,A1,27,A6,1E,B3,CD,2D,3B,FF,42,60,44,06,E8,1F,18,6B,0B,55,7C,7E,F5,D5,C4,69,CA,EA,DD,86,51,DE,07,6C,87,83,09,2F,75,8A,9A,39,59,48,33,DD,0C,50,62,03,C6,58,32,38,5B,2D,07,FE,92,E3,83,B1,B9,7C,E9,C6,A7,A3,AD,28,E4,F5,18,E3,5D,AF,9A,D1,71,9F,A3,D5,BA,30,F5,7B,0F,E3,E8,FF,B4,78,FE,54,61,F3,3B,25,A4,17,E7,A2,36,BD,44,42,5A,16,42,D9,C5,9E,7C,34,F9,8C,51,85,97,B3,F4,8B,E9,AF,65,AE,D4,B9,FF,E4,7E,09,C2,18,5F,81,EF,AF,6C,AC,14,17,10,02,B3,EA,84,D6,C3,92,9C,AF,4B,A7,AD,FE,8C,A8,15,42,3C,F0,58,0A,80,2B,82,54,A7,99,78,F1,22,A2,38,DD,79,08,ED,78,12,4C,55,B7,E9,E4,DC,46,1F,1C,5A,8B,E0,01,13,B3,88,14,EE,C1,9C,49,F0,60,9E,37,6D,88,F9,44,AA,5F,72,5F,71,6F,62,F2,30,94,49,13,14,2C,83,E7,88,36,53,44,E5,68,77,9E,E8,41,15,7F,CC,51,09,CC,06,5D,87,C1,EF,2D,85,51,11,A9,E5,A0,ED,35,8F,77,91,8F,B0,0C,05,32,31,40,40,4E,D6,3E,18,DA,DD,4D,E3,C2,E2,5F,97,A9,A3,2A,21,6E,EB,FA,65,DC,94,45,AE,CD,96,84,D4,88,88,B1,AB,BE,E3,1F,A2,B0,87,6D,2E,36,69,3A,7C,32,C8,56,82,24,60,B5,F6,FE,9D,D8,98,C1,C2,57,B9,55,1E,79,74,36,92,36,2A,4C,3A,C5,C7,5C,4D,A4,48,E0,44,CB,E1,7C,01,FD,90,38,4B,16,9A,20,91,2E,C0,70,82,16,81,4F,FD,F0,E9,AA,E6,F1,36,9E,47,40,9A,C4,FD,16,93,72,D0,25,8F,71,08,42,E2,EA,6A,EA,F8,F2,7B,32,77,88,8B,01,66,4B,19,C8,11,DF,B9,DA,C0,0C,9E,0F,68,D2,4F,A1,A9,64,47,E8,C0,9E,83,C7,DA,81,67,76,A1,09,E4,E5,07,7A,70,D1,5A,EA,4E,4C,57,B8,E9,46,D3,0A,0A,FD,5E,D7,07,09,6B,E1,17,C9,B2,74,12,77,2D,18,38,7D,A4,55,47,2E,05,D5,72,B9,E3,00,DF,0A,08,45,40,5D,4C,42,23,99,7A,7D,3A,08,AC,25,B4,B4,30,A2,FA,DE,8C,AF,9B,96,F2,65,50,F7,41,21,ED,1A,7A,7B,E4,38,18,B7,FF,2B,CE,B0,FF,78,E6,FB,BD,F0,67,A9,00,72,82,0E,29,38,29,72,D5,97,84,6F,51,1E,D1,79,77,07,76,01,A5,3A,E8,64,B7,4D,7E,8A,E8,E7,A0,83,84,07,05,85,D3,09,80,D2,AD,CF,09,E5,16,9E,DF,08,F5,1B,9E,1E,48,38,46,DA,EC,EC,EA,62,55,A0,77,39,21,21,B4,C1,98,9D,31,A8,A4,BA,5B,EE,71,B3,13,A3,EF,17,F2,E7,02,38,D3,28,D1,0A,77,D3,D9,77,49,92,60,F8,8F,69,D0,3A,EC,11,7A,22,41,92,60,69,5A,F3,46,81,96,2A,C8,52,77,49,1E,71,8A,4E,E0,68,C0,04,0C,F3,7B,D3,DE,62,77,E1,CF,0A,78,11,91,29,B0,5C,D1,3C,2A,E6,27,21,8D,04,2B,88,36,C4,D2,78,B3,94,F5,F2,4B,3F,94,F9,38,C9,6A,19,C7,F3,45,0A,E3,6B,84,17,0B,A0,9B,7D,F5,EF,CD,80,85,2A,BD,F3,1E,CA,A7,50,D9,04,6D,D4,77,C2,DC,5F,B1,43,BF,50,3D,3F,76,4F,3B,B1,B7,A8,91,3C,85,56,88,1A,EB,0B,4D,D0,7E,D1,2E,70,11,CE,90,42,EF,45,2F,14,FB,98,0A,84,EF,DB,F6,B4,6C,50,A1,37,96,F1,E8,17,2D,1E,64,F0,44,50,AB,C6,E3,6F,BC,9C,AA,76,F9,D3,CD,28,F3,CF,96,1B,16,2F,4D,B3,CB,F5,5D,93,5A,76,C0,1D,81,CF,91,3B,CB,4A,95,0B,10,DE,C7,CB,9E,BE,D6,DE,01,A2,03,69,EC,7F,2A,F9,77,75,56,C4,88,2B,2A,2C,2C,22,BF,D7,39,12,CE,6A,28,3C,63,13,13,CA,88,1A,AA,E1,EC,AB,FD,F7,BA,DD,85,1C,DB,E1,69,5B,C3,F8,84,16,36,FA,7B,8D,65,DB,76,C4,A0,73,62,83,6E,6F,E1,34,25,A5,62,8B,93,04,F5,77,5E,D8,F4,B6,69,42,CE,13,03,4D,96,F2,92,08,4B,B6,45,10,2A,C5,6C,00,80,60,8F,74,05,57,9C,14,DB,12,33,41,B9,ED,22,C4,BB,F6,EF,C4,E0,79,DD,4A,3F,48,25,E3,AC,F5,FB,48,4D,7F,FB,BD,E7,E1,94,78,49,4F,3E,E8,83,86,2C,82,64,AB,1D,8A,5D,4F,A9,29,27,63,CB,41,06,A8,A7,0E,3A,2E,9D,32,F2,19,38,A6,08,74,5E,EC,3A,01,7A,99,8F,95,79,C7,44,B2,1E,DF,56,34,60,60,D7,67,A1,F7,D7,87,89,47,2A,29,12,D5,59,C1,5A,CF,04,E6,A4,69,05,3F,29,69,80,66,6D,34,D3,06,7C,21,0D,A3,7F,24,9C,BF,1D,14,FC,87,1A,65,AB,4A,86,9F,F6,B5,76,6B,04,65,10,CC,D3,2C,38,96,FB,0E,40,50,9C,DB,9A,6D,87,68,54,66,99,A7,75,F0,BA,69,98,6C,82,5C,92,B7,3B,50,BC,CC,B3,7F,06,1E,36,87,7D,1B,BC,18,C6,E9,E8,5A,33,D1,0F,B3,BC,E7,B2,3D,49,BD,08,3E,AC,D5,0E,16,E2,74,44,94,C9,DB,4D,E1,85,60,46,B9,2D,8A,8C,29,7D,25,84,8D,FE,AD,50,4F,BE,AC,4F,82,4F,CC,CE,CA,F0,3A,45,9C,05,79,CC,9C,C3,83,40,E5,E2,18,E6,20,03,73,B9,0B,B5,66,29,03,84,71,2C,6B,99,8D,75,85,3A,78,B8,C5,44,E6,8A,B1,F3,D4,2E,84,0F,19,9A,11,52,66,13,D6,20,6F,9E,22,19,D2,DD,DD,BA,74,B5,17,2C,60,90,67,39,62,D4,2E,E2,A6,8F,36,4B,A2,96,08,30,9A,18,10,CA,E6,5C,94,A4,5E,95,DD,27,E3,7E,4A,4C,1E,49,B9,E3,C1,52,53,1F,DD,DA,5D,7E,6D,B1,BD,D9,33,F3,42,D2,80,8A,E5,55,EC,44,A1,55,E1,F1,0A,79,44,91,7E,A3,F2,65,90,D3,61,A3,99,E4,5C,66,89,E3,CE,FF,62,70,1C,6E,8E,C0,DC,D6,24,A8,19,10,C0,E8,6A,91,66,B1,67,EB,34,D1,05,CC,2C,AF,89,81,74,5A,BC,0E,CC,87,34,20,17,CD,3E,C6,3D,06,E8,0D,6A,EB,EE,A6,73,31,0C,05,EE,26,0F,90,B8,9E,05,5A,AE,BC,3F,2D,07,33,D7,B2,D7,FE,11,1F,74,78,D3,39,CF,52,A2,A5,E4,A8,74,89,75,43,48,62,E0,59,D1,98,13,ED,F6,87,BD,ED,1C,6B,67,86,0D,E3,AA,2C,11,FA,52,69,20,03,06,92,60,C6,F6,89,7C,6B,F1,72,F4,8F,EA,38,82,25,69,9F,3D,B2,1C,4E,A0,30,22,98,92,1E,0A,FA,91,F3,12,40,8E,B5,28,29,3C,E2,02,D2,EF,B6,DB,3D,02,A6,94,C9,9A,6F,37,7E,44,4E,45,88,EE,01,51,D4,7D,69,8C,2B,56,4E,2C,38,36,93,6A,23,AE,18,AF,81,FD,7F,35,43,6E,E0,16,4F,E7,35,F3,98,0B,F3,9A,D9,6B,4B,79,1A,4A,83,75,D4,04,57,4C,61,47,B3,F8,50,B7,8A,AF,08,7B,57,55,CC,F7,53,20,F4,54,86,C2,D6,6D,EA,E3,D3,B4,29,15,26,D9,B4,2D,FB,49,71,8C,65,DA,04,3E,AC,2E,9F,C1,60,B9,1D,AC,1A,CC,F5,3E,4D,48,2C,56,D0,CF,D1,16,D3,EE,B6,3E,F7,56,B5,F5,31,CD,F1,BF,47,21,17,D2,58,04,1F,7A,75,2A,33,42,52,2A,B4,29,4E,24,9E,1D,39,18,31,ED,A3,FF,96,0F,01,6C,B9,23,AA,60,65,8A,17,B9,FA,DC,DD,B6,B5,59,A3,69,CB,C0,55,C1,74,CF,D3,6F,D3,3E,42,6C,8F,98,1D,F5,81,C6,6E,83,39,ED,C2,52,6D,0A,53,76,10,38,3A,3E,9D,F4,08,36,48,52,33,94,E6,AC,E9,2C,39,CE,E5,0B,76,A3,04,86,74,CC,46,33,0C,04,D9,3D,D6,C5,70,53,B5,13,69,CB,BC,ED,58,0A,E4,E8,41,30,E7,3B,2E,4F,8F,C7,3D,0F,32,51,42,33,44,67,17,1B,58,6A,47,69,2E,A8,82,0C,0E,34,65,37,0C,79,12,57,07,92,42,8E,70,A5,19,A9,A6,5C,F5,C7,20,13,85,5C,FE,44,80,9F,EC,AF,5B,C5,61,1F,BD,C0,90,0B,F2,59,E1,D2,B6,BD,F0,80,08,AB,2E,7E,B2,BE,5E,68,18,48,71,A7,62,D9,DA,40,69,32,4D,CA,B2,2C,41,21,41,EE,8E,FD,BB,86,2E,79,51,A4,30,F7,D4,85,6D,40,3E,9D,3A,33,5E,8E,69,A1,B7,5B,DA,6D,74,B8,0C,BA,16,DB,3A,E7,8C,79,6F,57,31,C6,49,D8,BC,4B,30,DB,B4,AE,F9,DC,CD,BD,95,A1,94,12,60,B6,67,E3,86,63,1C,A0,F3,33,A6,31,C1,28,DA,8A,90,5E,75,A3,51,EA,0D,8F,16,85,54,12,3D,21,28,0C,ED,F4,7D,84,BC,9E,49,D1,7F,38,0F,EB,1D,26,94,E4,76,32,05,21,1F,6B,7D,27,F9,DC,01,53,20,1D,84,EA,52,2F,84,C6,28,EC,A8,B7,E5,F4,50,6E,BE,8E,4B,24,50,23,2A,53,B1,8F,50,2E,89,3F,F6,69,F1,9E,DD,40,63,D3,CD,17,F1,0E,E4,EF,41,0F,61,04,F7,58,78,55,AB,76,7D,0A,50,4A,79,03,D7,51,E0,0D,E8,11,E5,32,65,2A,DC,B3,26,98,5E,3C,55,19,82,93,67,CB,9A,E6,FB,7E,6F,21,A8,42,00,6A,DE,24,D5,D3,33,D4,4A,D2,81,79,15,90,5A,00,5B,76,1A,18,4F,70,8B,8E,7C,B9,9A,A4,44,04,95,D9,1E,4C,AC,C2,E1,5A,0D,54,46,85,26,04,6B,07,67,12,7D,78,1C,15,C9,36,44,43,6E,E3,EA,49,D4,B0,21,49,F9,3F,90,CA,DD,B8,F4,49,A7,2C,85,06,43,1A,37,5D,E5,3D,71,61,51,0D,02,7B,E8,E2,AE,E2,04,C4,BF,B2,96,C7,DF,BE,DC,D1,E1,E6,79,CB,04,99,2B,5B,1B,C5,CE,71,F3,18,EA,65,57,06,BF,50,2F,3D,F5,9E,AC,59,AD,B3,B6,B6,DA,F4,2B,23,72,50,02,EB,C2,DC,BF,04,D3,4D,70,57,18,04,3E,36,AD,7E,2A,EC,72,3A,E0,D8,3B,A2,28,4D,4C,7B,7E,AC,71,B4,A8,56,BA,0C,87,48,9F,8F,66,DD,A1,97,01,73,1E,F1,93,F0,9A,57,31,60,2C,6E,81,0E,C8,94,EE,00,27,89,2F,53,DB,CD,60,9D,1A,11,BA,6B,42,0C,41,B4,54,11,E8,70,A8,F2,48,F6,26,2B,82,47,EE,7F,80,F5,88,42,FD,48,30,6A,31,B9,6C,90,82,D9,A5,2B,CA,DD,4E,73,1B,57,CC,8D,2E,88,19,2C,2F,97,26,2E,68,21,B5,93,60,61,82,6B,C8,3D,23,75,E8,34,C0,FF,48,DC,1C,50,AD,D9,5D,83,A2,A9,22,B7,65,1D,4D,71,2F,2C,D4,D5,21,E5,92,14,FB,CA,A9,32,C0,9D,BD,4C,32,A7,FB,B2,04,46,8C,98,52,BC,C6,12,0C,3F,0C,60,A1,34,93,E2,6B,EE,C4,06,15,55,B1,B7,9B,69,12,52,CC,3E,13,A5,2F,B0,E2,3A,97,98,F9,E4,F2,9B,3E,4F,AB,B7,0C,82,C8,C4,36,B3,D6,BF,BC,29,32,F7,C3,A4,A2,9F,5D,91,54,7B,98,AA,A0,CB,28,17,70,D2,BC,15,2F,DE,08,27,A6,98,A8,A2,DA,2B,3F,6A,84,06,3E,41,7A,8D,A5,1E,A9,28,B5,7C,CB,BC,F4,D3,96,9A,F0,FC,6C,58,5E,B8,B0,58,6D,25,6C,65,F5,2F,D8,AD,BC,65,AB,A4,C7,AD,3D,DE,7C,46,44,0B,4C,6E,B0,0E,E0,C9,41,63,69,BF,FB,B7,5C,4E,8B,D2,06,A9,D8,2D,78,C1,58,71,70,7C,C9,85,8B,37,3F,A7,9B,07,03,D5,8D,03,97,33,77,20,DB,21,25,CA,F6,0F,8B,B1,B2,75,AA,02,FF,EA,57,EF,8B,00,1C,51,D2,E5,F9,85,14,C0,79,0A,5D,31,BE,7E,FB,4D,DB,A3,FA,03,A9,59,FE,4E,8A,A8,07,EF,A4,CA,B7,2C,65,86,3F,D9,9F,2E,15,E0,63,09,62,6E,E8,6C,A2,22,56,A9,33,6E,1C,58,87,88,CD,D7,17,FA,1E,76,A1,56,7A,A3,A2,2C,51,66,9C,50,C4,AB,86,69,E7,4B,57,A3,F1,87,C5,7E,62,9C,35,39,A6,F4,88,F7,6B,EA,9F,EF,15,E2,77,3E,DC,05,66,A8,EF,A7,3C,B5,20,CA,20,1F,98,0A,11,72,2C,7C,2A,9A,7C,3B,36,58,06,79,FF,9A,F2,EC,C7,56,C6,FA,77,A7,42,6E,15,EF,A1,6D,1B,3D,28,0E,F0,7A,03,62,89,C9,27,7B,FE,96,0E,E3,40,C5,83,BB,A2,30,74,AF,72,B1,47,71,37,83,9A,68,0F,E1,E9,C8,1E,53,48,3A,2F,34,2E,E8,31,76,3C,A3,DA,EE,DC,87,C9,4C,CC,D3,AD,87,79,4E,E5,94,5C,14,ED,49,F0,EF,32,0D,D4,77,3C,8B,6B,65,4A,05,F5,3C,9D,12,9E,D0,A5,56,74,D8,E1,93,AE,B5,52,C9,CB,33,32,73,59,0F,4F,31,2E,EA,51,A4,3E,06,EC,E8,B8,06,5D,C7,3F,63,06,5E,AA,6B,4D,AF,F7,A0,AF,20,83,DC,59,26,46,0F,64,7E,42,21,97,12,A8,B9,78,68,8A,4F,E7,1A,AC,64,41,93,6D,91,5D,FD,2D,0E,1E,D1,AD,0E,B2,A9,54,CA,A9,2C,0E,33,FB,25,7A,6B,5C,DA,89,B8,64,33,2C,E8,8E,E8,6E,DB,27,7B,5C,B8,FC,D6,54,BD,68,E4,1E,DF,30,7A,85,F4,98,33,FA,78,CF,E2,31,B8,D8,A8,2A,C7,8A,A9,A4,C0,56,EA,84,4B,FA,7B,E8,26,10,6D,09,90,61,B5,4B,97,99,A2,91,D0,32,01,33,4C,59,9F,C2,EC,9E,13,20,04,6D,BD,E8,1C,50,27,6C,0F,08,39,0C,20,DB,F4,85,AA,46,29,1A,42,B1,F2,42,D4,89,2F,85,D5,4D,E8,30,81,AA,3A,4F,F7,F9,4C,31,18,A4,29,54,1A,8C,FA,12,2E,5C,84,BE,25,EE,44,A2,22,7C,16,DE,D8,88,36,11,11,33,4E,DD,2D,4A,CF,1B,7D,3D,83,96,EA,56,96,79,D0,78,A4,06,CA,78,E3,19,FC,12,4F,1B,B4,3D,FF,34,CC,F7,A2,AE,3D,30,4C,F1,20,68,23,34,F5,1F,F8,F1,BD,79,42,89,76,C6,E3,44,FA,EE,27,8C,E0,C5,73,4A,FA,14,D6,36,FF,71,96,EF,41,4B,A9,01,43,95,80,0D,1B,2B,65,44,F6,AB,31,7C,E5,FE,B4,C5,D2,86,36,60,53,72,EC,C0,1D,61,6C,50,94,F6,06,CE,6D,15,E5,B7,D4,9D,99,32,E7,3F,23,96,74,C7,03,03,8F,A3,78,60,49,B7,BB,DB,00,42,62,2D,AE,CD,B2,EF,C2,47,E2,2B,FD,AD,D8,12,74,75,76,18,4D,7F,B2,B9,5C,A4,DE,91,3A,2B,8C,71,32,37,54,4D,41,81,01,2A,9B,EE,89,2E,A6,40,75,6D,7B,74,40,9A,ED,1C,AB,18,31,1C,49,B9,A5,10,2A,10,79,AB,A7,30,7B,15,84,C6,EE,7D,CE,49,CA,A2,0A,72,CE,50,D4,63,15,D8,D5,51,CC,BB,66,A4,70,2A,AC,AE,2D,CC,37,98,4D,23,8E,4B,BB,70,A8,E0,33,93,8B,18,99,22,D1,7B,43,A6,2B,A6,46,AC,45,6F,21,95,34,A1,85,28,BD,03,B6,28,06,BB,F3,5F,7F,56,23,1B,67,EE,25,65,9A,E2,56,7D,CF,CF,B5,C3,49,86,02,31,0A,6E,FA,49,C7,15,32,04,5C,08,FE,8D,CC,6A,48,C4,2B,E8,F6,EB,D9,C6,E3,8C,4B,DF,10,1A,62,67,C3,E4,76,5B,A1,95,3D,E5,76,EC,80,05,A8,F9,B3,00,82,32,83,2B,60,67,91,34,94,A4,48,A9,6F,3C,26,04,D0,BA,3D,1B,4E,84,8C,F4,33,FE,8C,43,B7,9E,61,22,70,35,87,99,56,77,D4,33,9A,DA,5A,03,A0,0E,FA,84,D2,FC,31,26,64,E1,15,8A,54,33,A0,D6,E5,CE,D2,BD,FE,E8,4F,E6,34,84,15,88,80,4E,AF,43,2C,E4,9E,D7,D0,B6,35,B3,DE,BC,9D,C3,4B,8B,C4,DB,D9,E9,D3,81,61,FD,B2,BE,29,C9,DA,F2,0B,4B,83,D7,76,A8,6D,31,7E,47,78,F2,9E,31,FB,48,15,B9,76,FA,3E,AD,2C,65,4E,24,6F,EF,56,48,B9,08,FB,9F,2F,C7,9C,7C,20,4E,CB,E4,3E,26,3B,48,68,CE,A6,64,2C,64,3E,A4,85,59,46,A5,44,96,6C,78,F8,C0,72,60,92,F5,3C,24,BC,DC,46,B4,12,99,AE,71,44,AB,DC,26,FE,AD,A9,CB,E6,A6,E0,45,CB,65,87,AF,8D,1E,44,FD,A3,F3,60,A6,C0,80,3A,99,61,AA,0B,B9,F1,75,8F,FC,20,35,3F,C5,0A,90,81,14,B5,B1,C4,D7,9B,67,24,32,27,5A,16,4F,AC,D5,5B,C1,33,18,DC,F1,CD,78,BD,58,10,0B,DA,92,69,9E,A0,85,37,06,4B,0F,3C,60,D7,3E,6A,05,1A,18,F4,BB,30,42,32,5C,C6,89,39,E8,BD,21,6C,56,44,9E,C6,75,48,31,D1,46,05,D2,D8,2E,40,1D,D7,DA,FC,8F,E4,D4,8F,82,97,03,A0,6D,E2,5B,B0,78,A7,56,96,D7,EE,4C,75,6B,39,C9,3E,25,57,B8,56,4B,FA,81,3E,F7,22,63,71,FB,60,8D,6A,A1,C9,CD,FF,13,41,D0,18,A8,EE,02,7F,1F,71,8B,C9,D8,5F,96,B0,5D,35,DD,8B,65,98,D1,C0,DF,70,AA,32,06,8D,65,78,A4,FE,D9,39,15,31,46,FD,B6,DE,64,B5,6F,D2,9F,99,E8,79,4B,26,97,D7,BF,95,B8,85,4E,34,A8,3E,22,99,FD,8D,29,81,26,3C,8C,6F,30,EB,EB,06,BA,FF,6E,7D,6C,A3,CD,5E,5C,97,D0,5A,E4,EA,ED,BD,30,DD,28,35,34,3C,C2,F4,CB,0E,50,F9,C7,F5,69,D4,94,14,FE,5B,C5,02,E8,5D,E6,BA,EA,4E,83,AA,94,AD,45,E3,FD,86,BD,B1,53,0B,30,D4,79,66,06,A0,86,7F,2E,63,82,A1,39,EC,B1,F3,86,EB,F7,1D,42,EE,AA,AB,F3,94,FF,86,69,A8,C8,4E,2F,FF,D7,32,32,A5,BC,DE,1C,75,D8,1A,03,FC,8F,94,A7,85,37,96,42,2F,F0,F7,41,DA,76,08,5C,5D,7A,BF,FD,A2,25,C0,42,39,A6,D0,E8,4D,6A,05,71,61,E7,63,20,84,60,AD,46,CE,01,F9,CC,B0,B0,BE,8C,02,E0,24,9E,C8,61,9E,5F,03,AB,12,55,B0,5B,23,16,D7,91,A6,C9,DD,84,6C,6F,44,F6,81,F6,DC,FA,46,EC,64,FE,C9,8C,8E,82,DD,15,75,D7,F9,B5,39,0B,59,AC,10,19,8C,BB,1F,8F,D3,1A,F5,C1,55,1C,6D,13,2A,AF,4A,22,CE,96,97,3C,14,F5,CE,C9,47,84,35,65,1D,D5,4C,AA,D0,6D,15,00,3B,45,85,74,A5,25,46,D0,13,91,81,E1,28,98,9C,43,47,0E,39,43,3E,96,68,72,8C,6C,21,D9,8B,D7,78,85,57,74,DE,E1,5E,7B,33,E2,CB,7B,D1,21,7F,E8,49,F2,A6,62,26,D1,E4,37,1B,F1,A9,3D,AE,53,CB,83,73,D1,A2,66,59,84,90,D4,5E,C7,A4,0E,F1,A2,A4,3D,83,D7,CF,31,14,EF,19,72,ED,F6,21,D2,FC,E4,37,3B,B8,06,17,1A,BB,68,D4,C4,C6,2F,DD,60,7F,2D,5A,4A,5E,E7,33,C5,EE,27,1F,02,87,18,BD,CD,D6,9A,69,37,2B,5D,6B,73,53,8D,2D,4B,7A,90,6E,EA,3A,FE,5C,57,0B,8A,A1,6C,ED,C7,04,3D,ED,C6,9C,A3,35,2A,F9,56,72,1A,02,F3,C3,52,A5,BA,24,E4,21,07,A0,7E,4A,26,16,79,BF,27,AA,A4,4E,63,E7,5E,9E,BE,1A,6D,FC,55,D0,23,F5,FB,BB,47,B3,A1,D4,0A,92,A9,48,08,77,8F,3E,29,8A,16,B1,54,8E,A7,74,C6,0D,82,5C,B5,FD,B1,51,FE,32,69,37,5B,05,DE,D9,B5,77,24,A3,27,61,1E,6F,99,F1,0F,4A,DA,60,8B,7B,94,49,15,AA,0E,16,43,A7,14,87,FD,9D,03,C2,7D,51,6F,4F,34,C1,B8,79,7E,40,1B,96,49,91,B5,95,54,37,6A,BD,12,73,68,BF,43,53,C7,E3,92,82,BF,30,5E,DE,3D,89,B1,F7,0B,C3,DB,90,BF,A0,E8,34,49,F8,6C,73,70,D8,A0,96,B5,6D,3C,94,1B,92,32,6D,AA,F5,63,00,FD,56,5A,C6,6A,8D,DE,F3,DF,46,DE,29,E7,20,73,26,4B,B0,4E,F5,1B,EC,BA,AC,41,81,AE,4D,B2,6A,89,B6,F8,6F,9A,8E,86,2C,DE,C1,0D,67,0D,94,83,40,5A,66,ED,66,10,07,4A,20,FC,B8,B0,04,D4,9C,23,80,2C,4C,91,AC,E9,78,C3,B4,C3,14,0B,98,5D,35,4B,CB,10,DC,41,E4,C5,90,F6,D7,2C,87,94,8F,49,41,D0,70,94,5D,F5,DD,62,A9,97,CA,48,33,4B,9A,48,57,9B,3B,0E,86,80,15,14,11,6E,8E,EF,7F,D8,50,7E,03,89,90,51,74,B0,FC,9F,86,61,D5,C8,1D,AA,C0,1D,AB,4C,FA,78,3D,B4,9C,54,5A,BF,61,18,4D,6F,D7,A2,11,93,67,03,38,68,57,24,23,28,20,E7,12,B8,FF,32,26,3B,77,AD,BF,B4,DB,22,7F,59,63,8F,2B,B6,87,60,C8,C0,50,9F,70,7F,B0,22,59,95,75,07,6D,43,96,1F,A9,F6,3A,92,28,88,85,65,6C,95,13,F1,0D,50,8D,62,83,68,42,5D,D2,21,C5,05,FF,BC,EE,55,AC,7C,E5,44,B9,76,27,02,C8,3C,B4,F1,66,C8,0D,48,DD,A5,90,31,F8,9F,6F,60,E2,CF,95,B8,EF,17,4D,5E,CD,D0,38,E9,DE,37,9C,56,47,D3,C4,0B,57,B0,52,A7,8F,96,AF,6A,EF,EF,A3,5C,C4,B7,C8,9A,A1,47,49,6A,72,26,2E,74,3A,A6,BB,DC,25,1A,60,0A,C6,75,EC,D9,7B,51,AE,BB,D8,B7,0F,C7,64,2F,D7,7C,41,75,8B,4E,80,9B,D8,29,62,13,40,35,69,14,2C,E8,26,DB,E7,27,9B,C0,33,31,68,AE,8F,E3,66,C7,E0,37,BC,DB,7E,18,9E,BA,B0,43,F0,22,EB,90,6D,F0,07,E7,5F,16,D5,BE,07,F9,46,79,9E,45,0F,ED,65,10,4A,66,6F,28,EA,47,79,4F,2E,65,6C,4D,CD,FE,45,CF,A6,6D,A5,A9,73,CA,59,42,E6,96,EA,91,9C,2D,AA,54,6D,D6,18,D2,D7,A6,ED,6C,88,3C,DC,0D,07,04,D7,D1,75,17,28,D7,FF,4D,4C,A2,BF,AB,93,CD,BC,BA,54,46,2A,4F,10,2C,65,6A,7E,04,A4,A1,D6,CE,C2,21,6F,0E,0C,95,8E,68,EE,BD,6F,AA,AA,B1,40,3C,F6,42,20,49,CC,BF,E6,5D,85,E5,E4,C4,14,05,B2,F3,66,9B,A8,88,88,57,A0,28,04,3A,C3,A5,FD,20,3E,E8,A0,E8,3E,45,5D,FB,F5,99,24,75,C4,BB,F5,91,3B,21,C2,B5,F3,02,FD,D4,D5,9C,69,6B,E3,5D,6A,E8,78,93,47,51,54,10,31,9D,78,FB,8E,A0,D4,4D,6D,2C,40,CA,3B,34,03,0F,F9,40,22,C2,4E,8E,7C,72,78,FE,85,8B,78,B9,AA,3C,0E,85,E1,1D,3A,33,B5,5F,2F,16,32,0F,F1,5B,62,12,90,77,C8,71,A1,FD,32,5C,93,0E,BE,77,05,55,C6,E1,8B,95,AA,C2,AF,BD,6F,3A,8E,8A,4D,56,2E,09,D9,9F,1D,7E,2F,23,6D,BB,35,A9,87,56,51,EB,2B,18,44,E9,49,93,91,FE,96,55,4A,D0,3D,64,89,5F,5C,B8,DD,7A,CE,45,1F,B6,9D,81,2E,E3,81,FA,28,48,09,0D,44,B8,B7,F3,BC,97,C1,B6,E2,6F,5C,FA,C0,BD,2A,B0,81,72,39,32,BC,2F,70,84,C5,6C,CF,01,1F,FF,3A,3D,15,84,A6,40,60,68,9C,66,95,CC,CA,57,4D,37,98,11,93,5A,4A,5E,10,E7,87,D4,E2,66,FC,67,90,E3,6E,BF,EB,DE,93,81,5A,D8,1B,26,1A,90,DD,60,9D,0A,2E,8B,69,41,7F,C6,29,0D,1F,4B,9C,A1,82,FB,A7,BC,6C,69,12,D7,33,6C,5D,C8,FE,EF,17,BB,39,3F,BD,9F,C3,EE,CD,AD,E4,10,25,EF,6F,9B,3A,4E,F0,7D,B8,4E,97,3E,C0,FB,3C,FF,84,23,C5,7E,22,7A,85,F8,65,CE,3B,B7,8F,9C,B4,A4,24,02,4E,78,A1,57,D3,E4,03,FE,A4,AA,87,74,81,62,51,99,A2,03,57,10,C6,15,6F,89,64,E2,A5,07,7C,6A,BF,1B,4A,0F,55,92,C3,C6,C5,4A,1C,8E,BC,4F,DC,4A,57,D7,21,FE,24,24,F2,A3,98,49,EA,85,10,D4,E3,7C,A0,7F,ED,AD,E8,DD,9F,D5,89,D8,E9,0C,BA,ED,43,86,39,A5,6A,29,2B,56,B1,1C,ED,56,CF,64,60,C4,D9,DD,A6,21,4E,87,F0,DB,77,DC,C7,4A,F1,4D,75,B8,4A,19,FF,82,63,9F,16,51,30,19,9E,54,32,59,DD,B1,6E,E8,35,FB,DA,01,9E,BA,37,28,34,05,78,E1,69,3C,25,8B,C7,8A,33,7C,C4,6E,3A,B2,24,49,91,8A,39,5A,54,65,CC,45,B2,0D,B7,0C,57,46,53,2E,61,39,EC,75,D3,FA,7B,AC,79,48,DF,86,9C,F7,36,8F,B0,5C,9F,BF,60,ED,7D,87,5E,B0,92,9D,F2,02,88,6A,3A,16,84,8A,EE,DF,44,EB,82,C1,9C,85,B4,00,63,7A,CF,A3,5D,5E,86,41,DC,E0,A2,FC,C5,E1,4E,79,0E,71,1D,33,7D,9E,EA,99,57,FA,2D,62,F2,A0,97,54,14,40,19,D1,F3,1E,B6,C2,AC,B7,51,8E,E0,55,32,68,23,89,4E,81,BF,7F,6B,3D,0A,89,0A,94,A8,0F,9E,07,05,28,D3,49,48,B2,46,EC,39,DB,7C,AF,79,0F,8C,3A,06,98,B4,5E,8C,94,54,81,11,BA,0D,83,5C,4C,AC,6B,8C,14,70,70,77,BE,6B,31,E2,A8,FD,F5,A0,D9,1F,25,A2,E5,41,DF,C7,31,AD,A3,69,05,04,47,62,7D,16,5F,D3,4F,BF,1E,DA,2B,11,E0,2D,3E,33,46,FB,09,2B,20,9A,5D,A9,CB,2B,E9,21,F7,79,43,CB,E3,E3,E3,90,4A,5C,34,E9,EF,ED,C7,C8,D4,97,EF,76,AD,FB,6A,FA,EA,58,15,80,93,41,8A,7A,41,A1,F0,D4,C9,B5,AC,AF,13,FA,C8,10,FC,DF,EF,4F,63,B4,4F,E2,33,05,1E,BE,A7,1F,71,9F,75,AD,8B,EF,D6,B3,61,E6,5E,95,D4,1D,D5,B0,78,51,30,C6,4E,94,A0,F5,58,D0,59,D1,5C,5D,C3,AC,D3,40,AD,9F,99,9E,3C,DD,A9,CE,B0,2E,85,60,3B,36,96,9E,C9,BF,2B,C3,1A,A7,8C,AC,01,2B,C0,2C,9C,C4,9C,16,4F,65,64,CB,2A,F0,1B,02,7A,91,6A,96,39,03,A5,FA,B9,DE,97,3A,55,67,4D,C2,59,59,18,8C,43,30,46,43,0F,A2,6A,B0,AB,9B,31,AA,79,C8,61,8A,FA,D9,E6,A8,A3,F1,54,40,82,4E,E2,B0,64,52,80,5E,79,EC,81,B3,FF,1C,2E,58,72,E6,3C,46,B5,80,40,48,40,52,76,B1,D5,17,AE,36,4B,34,F6,31,D0,99,C9,B6,30,8A,B8,26,FA,D8,66,40,8B,04,89,F8,4F,3C,35,A4,3A,DE,E4,75,89,A5,30,2C,CE,24,D9,20,2F,13,FA,4E,D3,90,1B,A2,EB,29,04,25,C1,9B,CB,5E,41,58,FE,DC,69,80,60,49,F1,E5,18,6F,F9,CC,21,19,94,F8,C2,CE,5D,6D,E2,88,2F,D5,D1,1B,7D,9C,1D,73,1B,06,20,0E,1F,78,7E,C9,01,09,AB,08,55,CE,19,14,2B,73,EA,2A,00,30,DB,A0,07,13,0B,D6,5D,DB,F2,8B,83,50,24,CF,37,EC,40,B9,5E,61,AB,E2,C3,96,76,1B,46,0B,D5,47,6A,50,DC,74,DE,FC,00,14,7F,6A,AF,79,7A,28,71,B0,F5,AD,AB,95,A0,D8,18,43,EC,77,30,01,22,98,51,92,60,D2,F8,E2,85,1E,52,89,E2,F5,62,E9,BB,43,B4,FB,9E,08,7E,FD,9F,7B,67,75,E4,42,52,DD,BD,E4,F0,93,22,18,3B,60,C0,C4,A6,FE,3C,CC,66,B5,0C,06,43,C9,8C,3A,B1,AA,7A,6F,0E,D9,C5,56,E1,97,C2,1D,65,4B,D6,A6,81,D5,4D,CB,2A,5B,95,8C,19,B9,3A,19,41,00,C4,1B,E6,A1,20,75,4B,55,2C,C1,0A,AE,9B,E5,EA,E4,E1,53,D9,A0,AF,19,1E,16,AD,CA,08,DD,62,2B,7C,80,B1,E2,48,35,48,D7,E9,A9,14,0B,FF,79,2E,03,3D,0F,27,01,20,CC,7B,C3,F8,C0,2F,FE,12,04,63,E6,04,70,FA,A6,42,36,15,D9,0E,91,9C,D0,30,12,E7,F3,E5,90,F8,DD,B8,63,3B,9B,B8,F6,A9,BF,CB,C9,02,AF,27,F2,80,7B,F0,00,14,12,60,03,79,FB,48,C3,AB,62,0C,28,0E,57,F8,93,E9,A7,5A,FC,8F,11,A2,8B,9D,E8,17,86,31,55,0A,76,92,2C,F1,E5,00,FD,55,C6,50,AC,DF,44,52,BE,05,06,C3,BB,E4,43,B3,DC,17,51,F3,21,7D,18,B9,F4,B9,2E,8D,85,B6,E0,B6,C3,FB,E0,36,51,DC,BA,89,21,57,51,A3,8B,77,45,0D,AB,73,53,1D,1F,59,57,71,A2,A5,56,63,9B,31,46,C9,7F,E5,B2,AD,20,A4,D3,AC,0F,24,63,5F,F7,94,C1,FE,D5,F5,E5,0E,D4,21,52,0C,BD,70,85,64,C0,AB,73,E5,12,3F,92,2C,FB,98,92,FE,89,B1,A3,3C,A1,36,6A,EF,B0,E5,9F,F3,4C,78,89,08,4E,FD,2F,82,BE,EC,47,13,D7,3A,A8,8E,F5,60,A5,62,4C,E5,52,1B,C2,03,77,31,39,0C,05,04,16,A6,AD,0C,64,54,92,99,DC,B1,37,6B,5C,E7,79,CE,C5,9F,C9,AC,CB,3D,F1,D3,79,79,BA,0E,4D,55,79,94,99,8C,8C,EF,1C,74,76,E1,B9,4A,A2,66,A4,8F,8F,9D,92,3B,A0,14,39,E9,E6,CC,7B,E2,7E,80,A0,D8,54,28,C9,04,0E,DD,09,44,1A,7C,F3,98,12,64,5A,F7,A4,67,CE,BB,3C,A9,A6,78,9E,D2,F1,88,4C,CB,7F,CC,E8,FA,A0,81,97,E7,B4,C6,55,B3,A8,EE,54,AA,1A,D3,93,74,A5,28,C8,63,85,7A,67,94,C4,B8,6A,61,67,3D,A4,B2,27,AB,0B,DE,96,53,02,E2,8F,D2,D2,EA,A7,6E,B8,C7,F9,1C,39,16,33,9F,35,C5,C8,B6,3B,B9,DE,32,A0,D9,62,99,68,7B,1C,BE,9D,23,3D,5A,5F,4D,C3,32,2B,C2,B9,AD,4E,CD,52,3A,2A,9F,CA,C2,94,E5,BC,04,A4,B3,79,B6,EA,07,AB,1D,E5,AC,60,5E,B6,23,D7,D8,08,A0,38,38,22,90,7F,25,59,C4,FD,3F,2D,67,1E,D6,BF,4D,73,14,B1,C0,27,4E,54,A4,78,B4,D4,D9,F6,AE,BA,2C,D9,09,E5,11,41,EA,8E,8E,CC,25,6C,B6,99,C2,9E,8F,75,C3,B3,C3,DB,4F,25,E0,0B,D2,50,E1,B3,25,D1,3A,63,19,75,29,B0,D1,48,52,2A,A1,9A,1A,2F,6D,AB,9C,FF,6C,51,E3,40,33,58,06,82,D5,54,77,52,07,DC,FB,18,38,82,71,A3,8E,B8,EB,09,19,50,A5,A4,A9,1D,CB,62,01,D1,28,A3,D8,CC,6E,02,F8,98,4A,17,94,AC,CB,4C,BD,4A,3A,53,CE,76,2E,6D,D2,33,0B,BA,37,11,3C,B9,66,2B,33,A2,0D,9F,8D,D7,DB,B0,34,A5,F0,D4,66,73,6A,4A,4D,C4,FB,8A,28,47,A4,7E,69,AB,A5,68,FA,F0,3D,B1,5D,86,69,E0,FD,D2,60,1D,22,00,5F,CE,53,7B,E7,32,72,26,79,DF,AD,8E,C5,EE,72,B0,AB,E9,99,2B,1B,75,9D,96,DC,8F,0D,EB,C1,03,06,A1,8B,96,36,5D,E5,68,D2,BB,60,82,7E,E2,E0,E6,EC,C2,5F,CF,B2,E3,B2,32,86,00,37,29,DF,15,9F,F7,C2,B8,9A,9E,AF,76,78,2E,B5,79,3E,48,E8,8F,44,01,84,56,96,8E,78,E2,BE,D3,3E,AE,EB,66,D4,5A,47,3D,C5,F2,FB,45,78,81,58,64,6F,BA,C8,02,C6,9A,EE,B6,1A,CF,2E,20,DE,BB,61,F0,BB,8A,9F,43,8A,5E,48,39,0D,74,F4,7D,4F,93,19,DF,C9,03,2D,E8,9B,91,E8,ED,A5,D1,7F,5E,57,E7,9C,76,53,DF,57,C8,9B,5D,66,A0,8E,05,F8,B9,82,20,B2,AE,F1,4A,96,C3,30,C3,DF,F4,6C,D6,E9,BF,1B,76,B6,28,CA,33,9B,6E,5A,04,92,50,6D,5B,66,08,A0,F0,9F,A4,63,25,8B,5D,F5,11,92,AA,EE,45,3A,4A,E3,BB,8A,55,A6,33,A0,03,9F,BB,06,B8,23,78,49,5C,7C,1A,57,82,79,4A,B3,1F,56,95,1F,D1,09,83,60,D1,03,AD,8A,8B,E2,15,59,3B,B0,F5,74,59,4A,8B,A1,C0,DE,15,34,FC,C7,B3,7E,76,D2,08,0C,A7,D1,93,14,CF,76,65,7B,B9,A9,52,44,52,2F,BA,37,C3,7E,A2,6F,53,41,A6,B6,E4,DB,6C,C6,32,F2,A7,93,E7,42,B3,06,D2,3A,43,6B,7D,1A,28,82,8D,0E,AB,19,6A,55,B7,CA,A0,FB,53,3F,63,6A,59,22,30,DA,5D,A2,99,50,E2,7B,60,76,49,C9,3B,C2,C4,5A,C9,60,EF,67,F2,A4,93,F8,63,66,94,CA,06,BA,0E,B3,2C,78,CB,02,56,3B,C7,ED,C5,FF,65,B6,CE,64,53,C2,A0,F0,65,14,73,14,F3,18,90,47,AD,1C,C0,C3,AC,6B,DF,46,74,71,25,BE,46,67,71,E3,6D,2B,66,38,02,F7,3E,86,04,0B,6A,36,D4,60,40,64,7C,82,19,CF,1F,12,4D,06,3B,4F,96,ED,E4,A1,41,A8,58,5B,A9,17,9A,F3,D4,25,4A,3D,F3,C1,75,41,EB,48,59,26,5C,D6,6B,CD,D9,E4,60,54,D2,51,E7,91,A7,FC,49,BD,C8,7E,E7,62,0F,21,3B,CC,62,2F,A5,E1,8B,3E,F7,07,CB,B9,93,DF,6D,0C,F5,1B,29,F0,AA,69,C5,E3,FA,1F,53,34,0D,41,98,43,B9,1A,7E,69,0E,37,CB,53,CB,2B,9E,F1,A2,11,69,39,F8,81,A1,9D,94,3F,DE,28,DE,F2,CD,FC,FA,01,1D,5E,E0,1F,D4,FB,6A,C3,47,03,20,0D,88,18,D2,7C,18,5B,4B,8E,02,DD,C9,7A,45,51,74,14,37,06,EF,ED,76,B3,F3,A1,AE,6E,54,DC,F5,38,AE,6A,AA,1B,13,9C,88,8B,67,49,04,45,3D,4F,9B,0E,C1,1C,04,C2,FC,86,12,A7,CA,F8,EA,D5,DD,78,35,AA,63,DF,0C,F3,70,C8,82,AB,7F,E4,7C,83,31,A8,70,92,76,B2,A5,E8,D3,E4,AB,65,F0,20,9D,6B,71,AF,B8,71,9F,63,98,2D,9B,11,1F,99,E2,DC,56,E3,D4,87,74,9F,39,98,82,63,2B,7B,75,B7,34,AE,19,BE,D2,5B,2A,53,54,81,28,3A,20,82,8F,1A,28,82,EB,1A,AF,A3,6B,48,88,76,C8,57,6C,83,3A,1F,B3,1B,38,BF,EF,C3,4F,58,FC,3F,CA,5A,F1,80,81,D3,6D,AE,AB,40,85,85,71,B0,D7,E3,67,5F,E7,6D,1F,92,4B,D2,A3,79,2D,FC,EA,7A,03,BC,94,06,79,66,46,C1,27,18,46,D2,08,CD,FE,53,41,50,55,50,25,75,86,ED,00,14,A4,3D,FC,B7,E2,CD,A9,AE,54,E4,42,09,27,01,E4,73,1A,A2,7C,39,90,5C,C0,72,76,95,3C,3B,6C,40,2E,5D,6B,37,56,1E,BA,78,63,9A,B0,FF,38,2E,E5,FF,0E,66,7C,EB,C8,9E,47,FA,D2,95,24,5E,22,83,6C,24,A6,BB,2F,7F,AB,88,6D,06,F7,10,2F,AD,9D,FC,AB,A0,15,BA,7B,AE,88,01,DE,1F,29,FF,E3,4D,51,8F,1D,4C,47,E4,53,69,A1,D0,08,9D,1B,A9,F0,6D,6F,83,AE,A4,0D,00,DC,42,59,29,99,D3,D2,69,34,A5,91,F0,A7,36,41,5D,4F,5E,AA,28,82,33,4F,48,3D,93,11,83,C5,56,6A,46,69,ED,32,5C,DC,A6,22,22,8E,18,36,DA,AC,37,FB,AE,93,6B,2E,3B,89,26,47,97,5A,35,69,AB,AF,B2,3E,31,91,CA,67,14,DF,70,31,BD,00,00,9F,0C,BE,05,B1,37,75,62,24,57,E9,98,D6,99,25,4E,34,BB,43,36,52,FE,81,B6,85,18,06,24,14,A9,41,31,75,54,36,42,67,E7,DC,2F,49,1C,9A,A3,9E,09,3C,46,89,15,37,C4,D6,EA,C9,AC,9F,DE,FF,31,2D,67,9A,CB,3A,7B,F4,01,A0,D2,0C,A8,1B,DC,CA,A5,4F,1F,B8,C5,A2,16,F8,CD,9C,3D,83,AC,D4,BA,BD,B1,F4,26,42,A9,41,08,8A,DB,28,D4,DE,55,02,55,66,87,7F,B3,EA,9D,5A,6F,40,73,75,5F,34,98,B8,EA,10,E7,B5,07,AC,33,D4,77,66,A7,D1,56,F2,C5,AB,FA,C7,FD,13,B7,9D,1B,E3,80,38,1C,03,EE,DC,C6,5A,4A,02,2C,CC,BE,23,E2,1C,B2,3D,43,EE,4A,91,38,3A,67,2F,25,DC,BD,1D,4C,EF,01,0D,6B,CB,E0,3D,46,62,62,E2,86,8A,7C,32,35,64,3B,4D,F4,77,7C,C1,B3,3A,03,C6,D1,19,36,B0,EB,D8,60,EC,06,4D,AD,13,EE,C5,72,02,75,21,88,49,23,AE,1F,23,0A,87,D3,02,A0,0F,2C,F9,56,BC,5C,3C,2A,FF,49,7F,7A,54,4F,C9,10,FD,6B,C3,4D,04,92,3E,C2,68,E5,DB,DE,90,D5,F4,69,B6,FE,3E,AE,E7,54,67,93,41,C0,00,8C,A6,FB,6D,3D,A4,B8,BB,50,C3,3C,D3,E1,4C,26,98,D1,71,8F,28,08,B4,3F,91,1F,33,E6,E9,FC,B2,B7,23,4F,D1,47,9F,70,6C,19,A4,32,98,8D,EB,3B,AA,8D,B0,BE,F6,72,14,07,A1,29,0E,46,17,2D,16,5C,14,65,6B,9C,9B,4A,64,A2,C1,F6,80,BF,39,0A,10,AF,84,4B,FB,85,E1,A9,5A,2D,CB,6B,AF,E8,C0,BF,85,BF,62,97,A7,3B,22,70,59,25,2C,68,F0,99,9F,8B,D0,4B,CA,7C,3C,2D,6A,5B,FB,F3,24,62,09,AE,1D,A0,46,6A,50,1D,1A,45,64,34,A1,50,1D,00,DE,48,52,C9,55,63,E4,6D,17,1E,37,96,91,75,6F,DA,23,76,91,04,A8,FB,7E,27,E4,7F,BF,BE,6D,E4,75,D5,01,FD,65,F3,CC,59,17,8A,8D,57,D3,DA,93,4D,F7,65,A5,BF,29,F3,95,B4,D6,C5,2B,D7,F0,E1,E9,B3,DE,C4,9C,5F,EA,B4,20,0D,B2,87,FA,F3,8B,20,B7,8C,2D,64,33,7D,72,15,92,7C,5F,80,EF,45,CC,B7,27,E8,F9,A2,78,B6,40,80,82,10,43,80,25,68,01,E1,A7,9B,F9,4B,B9,AC,8D,2A,07,2A,DB,9C,A0,88,C4,E5,F3,99,CA,24,B7,8C,35,75,E3,06,50,77,9C,D7,87,A2,42,28,6C,EC,BF,94,9C,CB,F4,7F,12,0F,DC,C6,59,D1,9E,F0,DD,EB,FF,3A,30,16,70,1B,7B,CA,06,3D,AA,47,CF,29,EA,8C,9E,7B,8D,AB,81,4B,14,63,3C,BF,D9,E7,43,4F,75,6F,16,E9,83,FF,C4,99,37,CE,A5,5C,75,7D,21,A8,A0,25,BA,A7,DE,48,64,65,18,C3,B4,F6,A8,71,F4,F3,E4,27,27,64,49,76,6A,6F,60,B3,F7,AD,23,54,19,B7,4D,4A,D8,A5,3A,20,B0,D6,72,83,CE,DD,E1,84,C2,D5,21,D2,B0,87,5D,0C,DE,D8,F3,17,83,34,37,2A,4D,08,05,C5,49,49,11,A1,92,D4,5A,A5,29,1F,AB,E5,E5,29,D9,EB,5B,FE,1D,5D,04,F1,D5,B4,8E,11,E3,7D,5B,32,B4,E1,DA,A7,A5,3C,36,A0,3C,68,D7,69,C6,45,32,94,E4,05,26,35,06,F4,33,A1,39,7B,48,62,75,14,64,B0,44,82,65,93,78,E3,48,9A,2E,F9,6E,01,6A,5E,09,93,D5,84,D6,66,D4,AA,64,8E,60,C6,ED,70,02,26,2C,C6,AF,D2,FA,08,FB,CB,29,57,B5,FB,08,AA,F8,D9,2E,35,A1,28,45,F2,4C,9F,38,B8,E5,7D,FA,BA,4C,3C,BC,7E,FC,21,AA,1D,B4,9E,92,5B,02,B3,10,21,FE,20,AE,6F,38,99,06,FF,89,70,33,E6,A2,54,0C,2D,B3,AB,F9,01,72,C2,35,B1,49,9D,65,E0,71,BB,38,D6,B9,1A,DE,22,0F,E9,A4,97,B9,8B,E4,94,22,CD,AF,81,30,FB,CD,57,82,79,A7,E1,C8,37,16,BF,A3,FD,67,C2,E0,69,FA,99,CE,03,7A,EA,2A,B3,BF,F9,89,94,7E,A3,32,78,34,17,7A,FD,94,63,B6,EE,1B,9E,48,C7,0C,96,08,26,34,38,C4,CA,D0,99,26,8F,4A,C0,98,EF,6F,B4,0E,FE,D5,64,C7,95,22,5B,B5,66,71,99,18,D8,2D,A9,76,97,0F,F7,2E,81,FA,FD,4D,92,1D,A3,DC,E4,DE,7D,7D,AE,DE,06,65,52,47,79,A1,59,9A,35,F2,C9,99,81,E5,3F,DC,0F,23,67,F8,17,E1,A7,30,28,02,07,CC,95,59,2D,E6,3E,A0,4F,11,9C,19,39,3A,46,3E,6D,00,D6,0F,6D,B0,93,E7,A8,03,D2,61,06,CF,A7,93,2B,7C,1B,70,38,9C,FF,56,FC,DA,09,A7,AE,99,8D,A1,7D,72,7A,69,3F,08,8F,B3,6C,3C,B2,C5,F3,DF,AF,46,19,14,48,1D,04,91,1A,6B,AF,81,C8,D9,78,1A,F7,41,41,F8,D1,B9,98,AA,96,00,D1,5A,10,B9,FC,7B,15,C7,8A,64,51,B5,3D,26,C0,A3,69,67,55,71,01,A1,48,83,51,AE,B3,2A,3E,F7,EE,9A,4B,72,B2,26,A2,27,B4,7D,5F,E2,F3,BC,E4,52,55,A7,12,D3,54,91,0A,7D,8F,36,0E,69,D2,D8,89,90,0D,2F,1D,15,DC,13,F9,7D,E1,07,B2,1F,3D,82,81,A3,3F,85,E0,1C,B5,BF,10,33,2B,C9,E5,CE,2F,EB,7E,30,81,2C,BD,D0,35,E1,8E,5C,C5,E9,CA,06,01,73,2B,4A,8E,F0,90,26,17,1B,E7,0D,31,5F,0A,2B,3D,FE,00,A8,61,30,CD,63,82,A3,E6,58,C2,92,E9,17,57,B8,90,8A,D0,C2,12,B3,70,4E,EF,9F,56,72,21,2D,8D,EC,4D,42,B2,A6,D0,72,22,0B,3E,60,7F,34,97,22,64,DE,15,0A,A0,34,45,72,4B,24,E7,2B,3E,F8,58,DC,8E,75,D1,BF,46,37,68,C1,E5,1F,25,C5,0B,1E,5F,9F,F4,AB,BF,FB,4E,35,D5,E3,F2,75,10,2E,A5,03,7F,33,1E,9D,91,D5,D8,11,60,10,6C,B6,F2,8C,F0,68,94,B8,85,3C,EF,B2,DA,AE,4F,FA,02,2D,2C,DB,E2,7B,46,60,3D,D2,37,97,E5,01,C6,54,A0,1C,E2,2B,0C,D5,0C,6B,CF,99,ED,E9,0B,9C,D9,F6,24,A2,DC,F1,02,3F,BC,02,45,5A,EF,92,10,7D,55,EA,77,AA,5C,08,25,71,38,1F,63,5D,A1,0C,6B,F4,1B,62,C2,DF,41,17,BE,F7,FC,06,62,C1,26,19,96,6A,20,BC,96,CE,1A,F6,E4,97,68,F0,E3,76,83,4F,2D,D2,58,94,89,64,3A,81,36,2F,B8,54,78,F1,B6,73,66,78,26,A7,27,62,08,6F,A7,B4,28,40,03,A8,A9,B5,08,4F,7A,6F,30,95,C6,C3,99,11,16,A1,0C,AB,9E,14,31,10,4F,99,AF,E5,8B,42,7E,40,CF,2D,FB,07,6A,78,A9,05,49,19,8F,CB,36,87,90,E6,8C,DA,DC,64,34,0E,F5,BA,D2,26,F7,92,31,DA,AF,9D,0D,D3,DA,1D,24,F1,68,6F,C1,A9,AD,5D,78,8A,19,9A,46,83,13,8A,1F,79,2F,B9,CE,1C,00,1D,92,57,4C,A9,B9,F4,35,8F,27,16,5E,44,1A,6F,C5,8D,29,4F,DB,8B,3A,F7,91,A4,31,45,C6,4E,CD,F4,6D,02,3A,74,61,4C,47,7C,CA,7E,51,2B,1E,93,C3,1E,3F,DF,17,94,BC,EB,81,6C,E4,CA,F2,55,B2,80,9D,84,78,83,D7,5A,A4,2B,DB,19,CB,7B,6D,BC,B3,9E,13,DE,75,A6,4D,72,81,15,19,5B,CF,C8,67,B0,BF,62,05,7E,64,7D,27,5F,44,F3,D9,18,91,EB,7C,C1,70,14,6A,4A,5F,4E,93,E0,4C,B5,4D,8D,D3,B8,93,E2,6A,D3,CE,C4,96,0D,B6,5D,BD,68,D6,D5,D6,20,D7,46,CF,93,A7,7B,0E,2A,47,A5,B5,18,3D,E9,74,1B,23,8A,5F,7C,7F,76,09,F5,68,39,91,0E,A4,40,F0,76,B0,06,EE,B9,C1,CB,56,5F,43,06,57,6D,04,7C,AA,2B,D2,2B,97,57,F6,B8,3D,E9,8A,13,4F,0C,C7,3C,86,77,2B,C7,24,25,DA,F9,D5,3E,6B,B4,8F,87,88,98,FD,56,C5,CC,02,6F,98,B8,CB,26,5C,63,98,92,C4,2E,B9,A0,C3,23,63,DD,CC,B2,31,5B,70,CA,89,6F,AC,B2,96,C0,9B,F5,20,04,A7,FB,4D,05,60,A8,E3,7A,2F,21,12,A9,CA,39,96,99,A5,14,93,13,55,D9,C9,AE,CA,0B,02,3D,7D,87,04,C6,43,4C,22,AB,C6,CA,0F,FD,8C,63,8A,0B,65,0A,B1,0F,FA,CE,56,8D,8D,32,9A,4B,C0,9F,84,92,04,F3,65,B4,1B,B6,A6,A6,36,0E,05,F0,6D,C0,96,D4,5A,94,38,87,47,3C,A4,DF,58,76,94,33,E3,7D,64,35,F2,86,0E,71,2D,8A,20,28,B9,67,0A,CE,3B,F6,2B,DA,C9,B9,CB,90,D4,63,DA,5B,03,F9,DF,3D,1E,BB,25,E2,3F,1F,54,68,A3,52,4F,C2,61,31,2F,3D,A5,BE,D3,DB,46,5A,98,9E,37,B7,3D,DE,DF,DD,6E,E8,A3,A8,9E,8D,78,C6,E9,55,9F,C6,64,F2,B8,5C,4B,40,CE,51,E2,0A,F2,B9,70,89,11,E3,3A,8A,30,2F,E9,B3,41,9F,B4,FF,05,CA,F4,E2,17,EE,9C,33,41,67,86,7E,08,DB,27,AD,A3,B4,13,95,74,0F,68,2F,77,E5,74,9E,76,E9,2B,0A,13,DF,E4,F6,9A,EB,93,B2,E6,4B,69,A1,8E,03,63,81,0D,3A,41,2B,12,FC,8E,E4,26,BA,80,E5,A7,F5,D2,FA,C7,DF,A6,DF,45,84,A0,07,D6,4F,1A,48,DF,1C,38,A5,98,3A,3D,E8,6F,CF,27,BD,6C,DC,6F,54,29,24,C4,35,CC,D7,D9,46,19,80,67,04,84,DA,3C,26,AC,F4,D2,F4,72,7A,3D,7A,09,59,0F,4D,B3,97,4A,17,23,D7,66,74,18,DF,32,88,4F,D6,72,B6,5E,E6,16,95,11,6A,82,23,D8,9D,EC,4A,20,F2,B1,EC,E3,44,0B,15,FF,3F,9F,80,1C,FF,ED,1D,D8,9C,AD,7B,EC,F6,6F,45,D5,48,7D,A1,92,BB,89,8D,67,1B,1B,2A,2F,D7,5A,4E,20,77,EB,EC,9F,89,AA,9A,0B,A0,D1,92,29,A8,87,79,D1,D4,5E,5E,A0,B9,3A,B8,79,73,4B,32,ED,B0,B7,20,87,47,A0,E1,32,A1,22,B8,78,85,63,CC,55,E9,34,34,FE,05,3F,A2,40,B4,F7,23,F8,ED,D1,1C,13,27,04,EB,70,D8,E0,8C,44,14,7F,0E,1C,FA,4F,A3,5B,F0,4D,8D,A0,BB,91,DC,DF,6C,1E,42,C0,83,4A,CF,99,5E,75,97,35,84,1E,C6,8D,F9,1B,5D,2D,56,69,B3,44,3B,FA,99,E9,DE,36,AF,11,81,46,1F,F1,CA,04,D3,26,76,B2,97,23,8A,85,74,04,DD,38,49,5F,07,07,E7,7B,7F,68,60,8D,2E,FA,A7,DE,88,8B,FD,DA,E1,A3,4E,FB,07,99,DF,96,B2,FA,08,89,BE,06,2A,02,19,FC,B0,24,6B,60,99,C9,41,68,FF,71,57,3D,97,2F,98,83,32,73,28,EC,9B,DD,57,E8,9F,06,AD,B3,81,33,08,7A,E2,2E,48,A8,02,12,99,93,E9,22,EB,A2,08,63,B8,EF,D4,E6,33,F9,3F,CF,E0,7C,CB,58,F6,F3,85,93,03,C4,83,A6,70,68,C4,81,E8,CD,01,22,E8,7B,B9,33,0C,FA,F7,7B,B6,98,DA,15,62,CC,87,9D,5B,BD,13,72,4B,F0,24,0C,4D,A5,77,94,19,E7,77,ED,71,29,D3,4B,73,98,84,D7,0B,6A,96,ED,45,AF,45,26,14,FA,47,0B,AD,F8,B7,1E,6F,D9,E5,90,3F,D6,F9,94,65,79,06,C4,0F,79,85,50,93,DC,58,F4,7A,D8,8F,DE,86,3E,95,E0,E4,DE,CC,65,FE,F7,4B,87,BC,3A,6D,3A,39,05,C4,74,F5,EB,E7,CB,AD,EC,DD,CF,97,5C,74,E2,7E,EB,AD,77,D4,7F,B3,8D,1A,DB,9B,6F,60,0B,72,F3,B4,DC,06,DF,DA,60,87,EA,2C,57,93,B6,FF,92,B8,34,65,6C,91,5A,4C,0B,E2,7E,26,60,03,FB,D7,9B,F8,9C,D4,58,A8,43,E5,9A,98,C5,08,CF,C4,56,C3,CE,94,B5,58,B8,34,E1,76,2A,8D,BD,51,CE,13,9E,F3,2F,58,44,85,BF,5D,05,22,21,AA,F5,05,F5,AB,77,C2,26,9D,EA,D8,A9,F9,03,45,7E,A7,13,5E,CD,57,6B,14,61,A9,C5,85,90,A9,5D,59,9B,3E,C0,02,3C,CE,64,08,6C,F3,7F,54,D7,9D,D7,1F,6E,76,A1,61,DF,66,19,3C,4D,20,30,30,6D,6F,BB,FA,F3,E0,DC,CF,7D,FE,8D,0C,9D,11,72,04,8E,42,33,B2,40,73,6F,88,87,D0,C8,21,0B,E7,5D,9E,52,8C,44,CD,92,85,3A,BE,47,74,E6,74,0A,B1,96,59,A8,B8,F3,2A,F0,BC,EE,56,1B,89,05,B1,C2,FB,C1,2D,07,40,C6,B7,77,B0,33,42,90,37,C6,DA,8B,91,06,F0,86,4E,C6,66,2E,8F,FC,46,82,ED,B8,FE,57,31,08,F1,A2,B8,48,85,7C,89,A8,EE,1D,F9,0C,DD,68,7D,31,6E,42,10,F0,C5,02,F5,B5,C3,DB,4A,E0,DF,3B,F0,5E,CE,82,17,CB,BA,91,48,DD,D1,C8,AE,93,EE,A0,0C,A1,E0,ED,3A,CF,1A,3B,26,4C,3A,67,12,0F,A7,10,45,BA,5E,D1,06,24,D0,CD,47,AF,D6,90,99,B4,D4,65,D6,66,B7,E9,54,49,93,11,76,4E,08,74,77,E3,14,A2,D5,0D,98,59,DB,1B,9B,98,B6,2A,A7,75,88,6D,0B,F4,13,0C,A8,0E,F3,DA,FD,1C,27,72,4B,4A,DB,92,3E,27,29,E5,A5,F5,08,20,D4,43,FF,F5,A9,2D,C5,CB,CD,A7,81,D1,E0,9F,55,4C,0D,B1,FD,2C,B0,CE,1F,61,A1,E8,DD,40,FE,2E,98,67,C1,C2,2B,F7,37,80,7C,7A,2C,1E,E0,B7,61,CA,67,D0,1C,AB,24,D5,72,EE,D2,F9,B9,7E,49,B2,4A,90,66,CA,79,CC,6B,81,0B,83,BC,21,6C,5E,37,42,F8,A3,D6,CB,9B,89,E5,85,93,37,BB,9D,BB,A8,A3,10,6B,19,4F,31,10,60,F6,26,28,71,56,38,29,8E,36,6A,BB,0C,CE,D7,09,B6,2A,4E,6E,81,16,66,13,00,72,11,C2,8C,A7,62,85,BE,BB,38,32,28,D5,F4,E5,A9,F3,0E,F9,DF,9D,99,3E,6E,45,8A,B1,72,EE,D2,B1,56,DF,64,67,0A,55,EB,39,45,1F,C2,6D,56,5A,39,B1,C3,AC,B2,33,71,4A,CC,66,10,46,0D,90,02,DD,EE,C3,7E,1D,6E,1F,2D,1B,EE,77,37,30,49,0C,35,ED,05,1E,1F,83,48,52,4D,C2,E1,80,8D,AF,17,65,8B,1E,C6,96,DC,94,85,89,DC,8B,01,0C,BD,F2,79,A1,D9,61,8C,EC,D0,08,B6,C0,BA,65,CF,34,20,EA,90,29,29,D4,F1,0E,43,2B,25,72,9A,7A,50,0E,D3,A7,4F,88,9E,E8,30,47,5A,6E,1E,11,0E,66,57,51,2C,72,0A,62,A7,50,AA,E6,5C,C5,8A,F0,65,A3,78,F0,2F,80,BF,47,BA,8E,95,CD,39,9C,3A,91,EF,55,56,9F,83,9D,9F,C3,83,13,12,C1,C6,12,31,8C,AB,FD,21,7D,98,8A,AA,21,1E,C2,26,83,A1,DE,2C,C0,B7,68,D8,CD,0A,B7,8E,F6,BF,49,54,BC,32,B7,37,1F,A3,9E,E2,BA,B2,16,4E,03,DE,4F,38,D0,09,B1,04,0E,06,75,D9,5C,91,8E,B7,F2,A3,33,B0,62,88,A2,70,D9,B1,8A,7E,B2,6D,59,9E,55,44,50,D4,E3,E7,D1,E1,B1,61,B6,37,02,3D,97,6B,7B,52,41,B8,72,ED,5E,2D,8F,06,9D,54,11,9E,57,A8,56,A3,6D,90,B5,85,A1,6F,AA,30,B3,F4,23,ED,29,D0,EC,6C,EE,9A,65,99,0C,83,C2,38,4E,F0,9B,3D,44,5D,3B,2A,2D,C0,8B,00,08,C0,E8,99,CA,4C,57,54,5A,54,C6,70,90,EB,E5,82,12,A0,70,11,90,30,DA,3B,AF,ED,BC,2A,63,52,93,8A,E2,63,08,F9,D0,E1,60,B6,AF,2D,E9,77,39,B0,35,AB,93,81,8D,06,C7,B6,30,82,EB,DD,CB,D1,29,8B,C0,6C,FC,77,4D,C3,C6,03,37,8F,D8,AD,A0,60,F7,52,03,25,B4,D5,16,37,E6,34,B2,C5,2A,0B,51,C1,E6,36,0C,83,70,7D,30,93,E0,C9,86,C4,05,11,29,22,CA,CB,1B,36,CC,66,AA,2D,9F,DF,DB,2D,FA,2D,7F,DD,54,2D,19,B6,0A,0B,78,C8,A8,DD,F3,D3,70,BC,F0,0C,8D,DD,A5,47,A7,57,71,10,95,CD,1F,4C,13,C9,EA,C6,34,F3,9A,AD,AD,6E,3E,23,11,8E,17,FE,F5,F5,33,BD,02,0B,80,DD,22,D8,80,2F,BB,1C,15,1F,23,61,92,B0,58,AF,4A,CE,72,6D,1D,1E,0B,CF,C1,22,75,59,65,A2,95,D1,90,9D,26,A5,40,CF,D6,A7,FA,38,23,2A,03,4C,BF,ED,A9,43,3A,8A,42,80,33,9E,04,69,F6,CA,A2,15,7B,01,18,35,9F,76,C8,AE,56,B1,39,96,E8,54,8B,B9,82,D0,BC,88,4C,22,57,CF,9C,00,6D,3B,78,7A,51,30,1F,00,0B,7B,CE,CC,90,27,1C,1B,03,25,4F,61,D1,FD,C4,82,BD,CB,A0,C7,C4,29,8D,14,55,E3,D5,4B,CE,C2,F7,35,D8,92,59,B1,13,5A,CD,18,7D,AE,A9,9A,B1,4A,1F,62,E1,B6,DE,56,44,41,13,DA,80,6E,42,BC,BA,7D,DC,6C,F4,4B,76,5D,7B,BC,46,4D,0D,00,10,51,8D,4B,8B,B6,F3,85,23,B4,9A,CC,9C,03,38,6E,E9,AD,BB,7E,34,52,E4,CC,B4,2E,57,81,F1,9A,6E,04,A4,11,2E,19,2A,4C,7D,97,91,66,AB,D3,B7,A3,13,DF,5F,12,71,AD,58,94,61,74,6E,74,7C,04,96,84,A1,51,27,55,47,63,12,AF,3F,61,29,E1,4C,4E,71,7B,6D,C1,B0,47,A5,4B,FC,7C,40,20,A1,CB,E5,CA,4D,AE,35,A7,FF,CD,BD,DE,C8,B9,EE,04,71,0F,CF,54,CA,1C,4A,40,9A,D0,71,AA,17,F4,E8,62,C7,C6,4F,12,78,57,E9,CF,0A,9B,8C,5A,97,DC,C1,83,26,0B,DC,A2,43,D5,4B,C6,F7,95,D9,84,17,F6,C1,53,8D,19,EB,18,64,08,0D,CA,78,1E,8F,95,BA,CD,DF,C2,B5,7D,58,49,56,65,A8,68,B3,E1,DC,CE,99,EF,E7,FA,67,D7,C8,7A,E6,2E,30,0C,58,5C,5E,E7,A2,AD,07,46,A5,7E,87,90,05,F9,D7,1E,5D,AB,87,3C,65,8E,22,74,E1,FF,29,2F,DA,02,1F,DE,CA,54,55,21,43,19,66,B1,27,40,6D,70,22,B2,D9,CC,40,C0,10,9A,C0,C4,D9,97,BF,82,B2,FE,6C,8C,42,57,00,10,C4,8A,5D,51,AA,52,54,B8,BC,2E,87,28,7C,C9,65,01,C8,E6,62,5E,CC,AD,37,C4,0E,7B,3C,FA,72,77,64,F7,F1,35,91,D3,73,D1,6D,4A,48,A4,B0,84,B2,AA,D3,DF,66,E8,04,90,B9,C8,55,48,70,B9,23,1E,93,90,FC,2A,18,53,D6,E8,5E,D7,6A,40,64,F3,E8,83,AB,65,09,05,67,36,B4,1A,CC,7B,F1,5C,0E,9C,E6,CD,DB,90,DA,A3,FC,2F,64,6A,F1,09,73,D2,9F,63,BA,0B,E4,2C,AD,87,B7,07,CE,F0,F4,83,FD,48,1A,F8,62,CD,A7,72,C4,0B,7C,13,A2,14,6B,E2,24,6C,46,80,54,38,6C,5E,B1,92,53,FB,A9,2E,0B,EB,0E,A5,59,71,98,E5,5C,9D,0F,F1,03,C5,35,B4,C0,6A,D5,7A,1F,E9,1F,03,D9,0E,6F,34,2F,5B,F1,B2,5F,31,24,7A,86,53,81,D2,7B,FC,D7,01,CA,FF,57,BF,53,71,D2,2A,A2,29,29,9C,0F,1B,99,AA,50,FB,D7,F5,02,47,03,8C,B7,28,C5,6E,3D,B5,C3,CB,CD,28,34,8D,44,84,32,6B,46,19,4B,47,DC,00,BE,D0,0B,8F,01,2C,6C,02,D0,19,0D,92,A1,9D,02,E1,CB,D7,96,CB,01,95,CC,94,7B,C7,D7,44,9C,4F,29,CF,0C,81,B4,AC,D3,25,FF,8A,ED,0B,EF,0F,C1,FA,FA,DA,9C,32,5A,32,A1,ED,FB,E4,54,C1,36,22,7A,C5,3C,53,9E,42,8C,12,EF,66,75,5D,EE,DA,D7,67,F9,19,79,EB,09,83,29,81,B4,8C,AD,B8,62,89,BA,55,13,B4,00,77,28,36,38,EF,28,95,2C,41,8A,F4,31,FE,43,35,D0,38,FB,4C,A3,F6,31,CE,55,50,42,63,7D,C6,09,95,04,C3,71,3F,E4,36,F9,1E,6A,C2,0B,49,6E,AE,0F,9E,8A,F8,BA,52,95,94,DB,76,F6,09,C0,46,B2,A1,5F,61,78,D7,CC,DC,E4,23,93,EA,6C,80,4D,D3,FF,FD,27,2D,2D,04,19,40,24,F9,AF,05,10,01,87,6E,F3,F6,F9,39,A3,B2,D9,E8,B5,C2,83,DC,50,39,E3,F3,D2,51,CD,E0,B3,C4,12,D7,3B,62,01,B7,A5,10,3D,E2,FC,66,0A,A0,39,5D,DD,CE,B7,03,69,69,0E,DB,A9,7B,2B,7E,0B,2F,F6,4D,9F,21,C8,20,52,DA,50,53,DF,FC,4F,1F,21,55,F5,10,D8,73,DA,87,AB,E7,96,42,F2,8C,8D,C6,72,6C,90,67,E2,FB,97,1B,31,F6,54,24,C4,8E,FF,F8,72,C3,63,B6,63,D8,0E,36,78,51,9C,AB,5C,1D,5E,DD,3D,6F,8C,88,60,75,94,0F,45,D6,DC,C0,51,9A,5D,C4,04,CD,19,9F,2F,4C,2F,C7,2C,A8,2B,F7,EB,20,60,1E,86,71,48,BA,0B,A0,C0,F8,2F,60,F4,56,35,26,16,AE,2A,EA,B0,13,BA,78,05,9B,C7,2D,AE,6C,CC,1C,5D,BD,FD,DA,DB,2D,D8,A7,40,55,91,02,92,CE,CE,5C,4A,7C,F0,A7,EF,33,75,69,A7,DC,32,7E,0A,A2,9D,2E,76,F7,0C,98,AE,A1,C5,EE,A1,57,5D,EB,14,80,7E,19,D8,0C,9F,00,61,AC,64,F1,BA,23,6D,8B,15,06,2A,B8,FE,2B,27,6D,92,88,AB,6A,21,75,55,72,D8,1C,B2,C4,8B,F4,C3,73,5D,C0,4E,67,FF,3C,28,23,7A,25,0E,21,0B,FA,A2,62,1B,11,38,DB,5D,C6,21,18,EE,20,4D,03,EA,DB,72,44,D1,A8,50,42,BF,50,AA,FF,33,1E,2D,29,C9,0C,60,E4,D6,F4,44,BE,79,66,B1,06,37,AD,8D,32,77,D4,81,33,D0,1C,B0,E6,F8,F6,BB,CF,56,4B,25,A7,2F,EE,7F,90,6E,8A,11,44,D2,B0,E8,6C,88,92,5E,13,3C,06,DC,1D,A3,F1,E0,F2,AD,3E,9A,C6,13,8B,5A,EC,BD,DE,0F,CC,B3,24,FF,19,E8,42,F5,C7,F7,0A,AF,A7,DC,EC,A2,E1,3C,98,77,60,DD,21,E2,22,49,B8,1B,3E,97,C6,64,52,37,62,49,A0,BF,8D,92,B3,FF,86,7F,08,12,24,61,E3,95,38,29,13,6F,19,58,0B,FD,9E,6A,BB,01,A9,11,CE,1A,5B,B1,18,62,1D,D1,44,88,13,83,36,BD,3B,0F,4C,EE,D6,92,45,94,EA,11,27,A2,73,A7,12,78,DA,50,32,77,1A,05,3A,10,CC,9A,B1,19,74,63,49,9B,32,29,BE,12,DB,4B,5B,5E,0F,75,94,35,AD,50,93,98,B1,B1,40,0E,2D,EF,F2,55,ED,12,56,53,07,58,9F,06,BF,89,55,D3,E5,FD,9F,A7,D8,C3,D7,CB,18,43,CE,F4,AC,1D,DA,0A,ED,B7,99,E4,35,C7,93,31,3E,5D,35,7B,EE,D0,EE,25,16,46,E3,A4,88,19,CE,4D,84,EB,86,34,65,24,5D,AF,19,0B,27,CE,CD,31,C9,57,41,88,B0,19,BA,E9,E8,AD,CD,A1,3E,AA,11,82,79,B3,93,3A,89,FD,71,8C,84,7F,8C,90,51,C8,0A,44,78,B8,E3,2B,4D,42,AA,03,23,24,C6,C1,02,1A,AE,2F,55,D6,34,C9,B2,DA,D1,5F,17,9F,31,32,B7,76,53,87,78,6F,36,65,39,48,02,56,19,7B,DD,55,17,A8,3D,E9,32,8B,46,56,BA,AD,4A,AC,D6,99,06,7A,E8,C8,E2,ED,57,38,CB,73,E6,18,A5,3C,FE,50,E5,61,85,4E,C1,60,E7,5A,88,FE,26,95,29,F8,00,48,AE,43,64,B9,A5,CC,2C,D9,97,7B,86,7D,8E,5B,55,B8,AB,A8,E5,C1,18,4A,4E,9F,AE,CF,C3,4D,D7,B2,90,C4,DA,7E,BB,4E,58,F5,6F,19,DF,3F,06,14,11,87,14,20,EE,04,AE,AC,A2,07,41,33,AB,33,AD,43,11,D9,62,15,6A,46,2E,EB,6F,51,EB,FF,94,7D,54,0C,40,7A,95,CA,0B,9A,B1,90,1D,44,2D,00,C5,79,DB,6F,CA,FD,B3,D8,98,46,B7,58,25,F1,C9,12,FA,36,B8,45,76,1F,73,11,F4,04,F4,10,56,E8,A7,89,05,77,C3,2C,ED,86,3E,83,D7,32,9B,EE,B6,4A,C4,13,ED,43,58,E3,68,F1,70,D7,54,13,01,41,3A,11,D1,51,93,F4,4F,33,F9,B7,E4,55,3D,4F,AD,A9,37,7B,EF,80,19,5E,04,FE,54,48,36,CD,06,3A,FD,99,B8,A4,3C,2F,32,87,0A,34,27,68,F9,52,5E,DE,BF,C0,B2,67,98,E1,F0,F8,52,39,C8,DE,2F,3F,FD,39,BB,EA,9A,4E,16,6C,A0,16,FA,27,05,3F,F7,A8,2A,DC,C8,C5,AE,63,2F,DC,86,BE,69,94,49,9E,E9,FC,2F,D4,12,D8,2A,02,B1,B9,F1,03,C8,AD,E0,30,7F,5D,2F,61,9E,3A,02,B2,61,99,32,7E,A3,E6,0C,D7,85,EF,1B,BC,69,67,E5,96,C7,79,62,0B,05,A2,B1,81,B6,B5,25,4E,D7,2B,E4,6A,43,BD,85,5D,F7,4A,8A,7F,AE,E5,E4,C7,9F,71,36,E9,84,85,CF,1A,7D,F9,AC,7F,EA,FA,44,74,C4,94,BE,DA,B6,5A,DD,09,B4,E8,D8,60,5D,4B,60,EE,82,78,E6,96,2E,79,D2,06,A0,D5,13,38,F7,07,0D,8A,5D,DC,12,44,13,54,93,46,4D,CE,C3,93,96,6C,65,3F,A2,E9,DE,0F,F9,1D,A4,35,5B,DE,60,E9,56,D7,AD,3D,04,FC,76,3F,4C,48,64,42,1D,B0,37,50,38,A9,3D,D5,8D,1E,0B,53,A1,2A,69,47,24,09,18,04,0B,25,1F,FE,3E,82,E4,FE,94,67,D8,D6,F8,A3,B9,7C,5B,D5,C0,DA,81,D3,30,7F,2D,19,52,7A,33,07,33,9C,32,1A,D4,D1,40,78,2D,D7,C1,E7,E5,7B,0F,01,C0,53,F9,57,DD,D1,A2,93,98,97,D2,55,A6,B4,60,78,02,61,6F,13,C5,15,CF,64,BA,9F,DE,8D,B3,1D,14,9B,6D,73,A7,B3,B7,77,FF,33,DE,68,E7,BC,60,88,C1,AF,AB,D2,41,EB,3B,AD,4F,CC,77,2A,DF,65,DB,DB,88,B4,C7,E9,88,67,D3,1D,B7,54,BF,43,C1,71,73,1F,ED,8A,EE,5A,DF,05,00,E5,C3,E6,85,C3,F6,A8,CA,20,1C,C7,2D,53,9A,CE,C8,CC,07,EF,28,C7,2E,CF,5D,90,17,66,CD,C5,50,A8,D0,10,1C,1A,51,56,A2,58,56,7D,7E,8D,6E,2C,D7,E8,4F,47,8B,81,2D,04,FB,6A,21,4D,A1,A4,E9,DA,53,D4,E4,55,E5,0A,C5,F7,0D,EC,0C,DC,DA,F6,D4,84,00,46,5F,8D,7D,01,90,BB,6E,D1,34,1B,D3,9A,82,A8,12,B2,A8,CD,51,DA,C3,B8,0A,E6,8D,1F,F1,A0,3D,75,D2,A1,AE,33,B1,DC,2D,E5,FA,D4,9C,D2,21,FB,BA,33,88,75,52,2F,5C,BB,69,E9,07,EB,E6,75,F8,F9,29,94,07,90,72,23,C6,A8,47,2F,65,F1,37,B5,97,17,33,84,62,8A,3F,34,08,88,87,C6,F7,12,22,88,3F,A8,3B,4B,87,63,F9,A2,1D,68,D5,0B,B1,78,D1,F0,62,88,87,B7,11,34,9E,79,26,F8,B4,7F,5E,12,6A,85,5A,9A,A0,F7,31,28,2C,D1,A3,74,82,6C,B8,58,74,1A,3B,9A,52,88,8B,D8,64,5E,25,FF,97,E3,F1,2B,BC,78,58,B4,BE,A9,9B,F9,6B,E3,91,A6,53,68,3A,B6,8F,23,6E,25,32,0D,C5,81,0A,E7,40,FD,B4,59,7D,7A,9F,8C,E5,70,60,C7,CF,F0,CF,4A,43,0A,AE,49,13,FD,5E,42,66,89,3B,82,0C,48,12,05,20,5D,0F,0B,1A,D1,44,82,F0,31,66,64,F0,A6,C1,12,52,77,8A,32,AE,D5,9B,98,40,E2,DD,4A,C8,B2,81,B1,D4,65,E0,D2,D1,01,4E,C4,8E,95,21,2B,D7,40,F6,E6,42,1B,17,60,3F,F1,59,35,5D,7A,B7,DD,AA,AF,2A,4E,33,B0,27,E8,26,19,FD,57,A8,8B,E5,52,78,E2,7E,7F,B6,EC,CD,0D,4C,13,25,B9,D7,70,B7,72,FD,36,4D,A5,17,55,07,73,EA,3C,F9,82,7D,B1,5B,06,89,0B,9E,BB,E5,FE,50,75,06,1F,F4,51,CA,B4,03,C4,8E,B2,F9,AC,7D,52,29,FA,96,20,7A,62,1E,2B,FB,B2,1F,92,4B,24,28,0A,04,D1,96,04,AC,68,47,17,48,D8,65,C1,E9,8B,C9,4E,11,45,31,8B,AF,BA,F8,AA,72,01,D1,1D,B8,F3,5C,1D,AB,7F,59,1E,4B,DF,09,24,B6,DB,78,69,29,FE,F1,0C,53,DE,9B,7B,25,48,68,C3,86,D6,DC,5B,6F,61,87,61,A8,28,C3,95,D0,13,B3,68,CE,A3,FE,8E,B3,82,07,92,B7,85,54,49,7F,64,F6,7D,8D,92,E4,53,71,4F,4F,A2,68,67,7D,AB,74,2D,0C,8D,5A,55,7F,E3,5E,B7,A9,16,5F,FD,EE,39,7A,7A,16,B3,61,02,B7,39,5E,59,0D,B1,42,F2,77,C4,4F,6E,CF,6A,35,C1,B0,42,D3,A8,4F,16,31,E8,BF,96,32,D7,77,95,B2,12,2A,46,BB,3E,3A,6D,1A,45,E9,4B,E5,34,3A,6B,48,B1,D1,3F,2C,8A,9F,22,64,5F,EE,A7,35,90,D2,80,85,D4,C2,4B,D4,86,23,5E,5A,1D,6A,16,1B,14,18,F0,C4,A1,55,A4,1A,5F,CC,96,54,C6,6F,A7,66,5D,7F,EA,A2,A0,FA,CC,0F,71,33,C7,59,B6,0F,0E,99,9D,62,4F,DE,7A,4E,F6,94,00,36,0F,1E,3C,1D,51,0F,FC,93,98,BC,4E,93,3A,94,2C,B5,DA,03,B1,38,08,9F,82,73,7A,F3,8A,B4,40,5F,79,D0,C0,15,0A,7E,30,90,37,89,E7,13,3E,F5,E7,6B,76,28,CB,AF,49,48,27,CB,90,03,AF,07,CF,F5,54,04,EB,39,0B,F0,4C,B2,F5,01,F9,98,E8,AD,6D,B3,8C,67,C2,03,39,78,D9,E2,E1,89,5B,BA,E8,A6,34,7D,39,7B,FF,A3,4C,54,EC,FD,CC,E6,35,B3,7E,73,45,14,C3,C0,17,70,C1,D7,FE,57,3B,35,2A,88,A8,9F,24,19,DE,1E,C1,2F,47,A9,D8,EF,25,CF,23,A8,2E,0A,21,B4,52,B1,A2,06,CB,8F,D2,2E,51,BB,85,CF,47,8D,61,B5,B1,AD,F3,E6,1C,4C,E6,3D,DA,9F,54,4B,69,C7,3D,75,F6,2C,E6,01,67,53,0B,5C,05,30,59,EA,CC,A1,01,85,4B,82,DB,95,01,01,DD,5B,91,80,79,C8,EB,ED,01,8B,34,92,58,CB,B8,B1,B3,3A,1B,E2,56,2B,33,7A,0C,FB,54,97,8C,BC,6C,41,B8,FE,09,CA,A6,38,F8,5A,70,0F,FA,95,28,CC,20,A5,59,FE,06,32,47,C5,32,BA,BE,C8,B5,91,57,9C,61,ED,D1,8C,35,7F,53,17,58,38,04,3B,40,A7,A6,52,61,D3,B4,BB,9C,44,48,EA,B4,82,36,AD,98,19,FA,CA,51,F6,D7,38,1B,13,EE,55,CA,F5,75,0E,00,3D,68,9C,13,9A,A2,9B,69,B7,86,3B,E9,FE,2D,0C,3A,1C,FF,CC,C0,71,C8,E6,EA,E5,17,E1,CF,63,CC,20,E9,0F,A7,35,DF,DD,13,2A,00,90,BA,09,14,CE,62,DE,06,5F,2E,35,53,FC,AB,20,2B,FC,7F,73,F8,ED,96,A9,05,EC,BD,6A,DE,C8,FC,2F,3F,D3,7F,2D,2C,33,AA,CE,31,D8,8C,EF,CA,B3,C3,D0,85,86,DF,08,DF,AD,E9,BF,96,2A,12,46,59,D0,C7,D4,C2,3E,49,4F,D8,93,12,61,48,32,41,FE,C0,52,CD,52,ED,24,EB,1B,96,E3,F9,6A,A7,2E,8B,05,E8,6A,9C,49,6E,D7,71,56,68,E6,50,B6,9F,C7,1D,99,A8,66,94,38,9F,5B,B8,AF,35,DD,F0,D3,EC,63,02,2F,8F,F3,6E,6D,9F,A3,6D,6F,7F,22,94,DE,A9,B2,32,DA,31,8E,0C,16,30,C8,A5,48,7D,38,8C,11,F4,54,B6,E7,5C,DD,BF,16,6F,DB,6A,A7,D2,2B,3A,3F,3D,BD,44,42,8B,55,30,4C,D9,DD,B1,60,1C,B6,BF,A6,06,5B,FC,5F,C4,1C,8F,17,5A,9F,34,17,CA,35,99,8C,CA,44,92,37,35,CF,DE,E7,1E,CE,44,38,A5,3E,FB,85,BA,D1,B0,DD,AE,4B,E3,9C,62,E3,5E,DE,32,08,A1,1A,2E,0A,70,16,46,01,4D,6E,AF,25,63,3F,7F,6B,79,64,88,89,98,58,1B,D4,A3,F7,5E,42,3B,12,C5,44,B0,DC,66,A0,87,46,7D,FA,06,52,7D,8A,BC,A1,69,D9,A3,C5,01,67,27,11,77,C2,C8,1C,3F,CE,75,72,CE,60,11,A6,13,95,D7,9F,09,1E,7F,B9,99,81,05,19,9D,08,A4,E0,22,C6,F6,BE,D2,08,E1,6C,0D,ED,89,8E,FB,74,76,5D,7B,F6,F8,5F,CF,2E,5D,5C,0C,1E,9B,85,48,4B,7E,DF,72,29,31,8E,63,1D,72,35,D1,B5,76,B5,32,AF,40,49,1C,9F,28,26,F6,FD,5F,8F,67,48,6C,FA,69,27,B3,2D,05,7D,01,EE,CB,39,5B,03,C5,C7,ED,32,30,2E,A6,8E,9A,AD,C0,39,FB,9C,D0,27,F5,52,50,7A,38,B7,D6,AA,E3,7A,98,54,DD,25,D3,3D,48,59,2F,AF,A2,FB,78,F9,DD,FE,71,ED,09,19,F4,AA,87,AC,FF,0F,AF,FF,4B,B3,A7,FD,1F,9B,10,0A,D1,EE,4A,D4,BD,60,B7,27,C8,77,1D,18,24,95,D1,61,F5,22,1F,72,98,A4,10,4C,A1,40,07,A3,1A,40,69,F7,97,F4,82,F8,5C,7D,17,3A,6B,F8,5C,6C,41,A9,CA,4C,0B,C9,26,CE,9B,A8,83,4E,F2,BE,ED,11,32,CD,1B,4F,43,22,0D,2E,10,2C,23,43,D6,4F,78,C4,DD,82,27,23,45,CC,9C,48,BF,C2,3D,FB,B6,E0,A1,11,F0,FC,0E,45,76,3D,09,6C,83,EE,94,4C,2B,98,68,63,4C,DE,8D,3D,44,AE,C5,57,B1,2D,41,10,D9,2E,9A,99,49,6C,25,14,37,0E,66,F2,6F,F4,E8,06,5B,06,35,00,14,E6,CB,8F,5D,44,9E,D2,64,63,3D,27,13,F0,0F,59,82,83,92,38,07,32,78,8F,9E,5D,98,2E,D0,89,7F,EF,A9,D3,CC,9D,F2,52,C9,E5,D4,C2,AF,CA,48,9B,89,EB,83,F5,7E,62,96,97,FB,DC,A3,29,99,99,A9,49,9E,6F,C2,80,68,C3,F5,EB,71,2C,DD,9F,9F,0D,3E,96,CD,08,03,ED,64,36,25,47,1C,92,91,8E,CC,A0,B6,97,AF,65,16,E8,07,ED,8F,D1,8F,2F,5E,4A,CA,86,D2,87,08,63,21,31,39,93,30,5F,BC,82,E1,6F,A7,AA,1C,32,EA,F2,FB,E7,A9,89,6F,D1,36,7E,6E,B7,03,EB,ED,29,F9,3A,7E,ED,05,00,4D,1A,CC,F1,A0,AA,FA,DF,56,1A,F4,8E,1C,EC,1F,CC,8B,8A,BF,D2,51,ED,39,BA,AE,13,05,8D,D5,8E,38,D7,AF,E0,61,6A,25,A4,C6,D4,D2,DE,84,DF,B7,FB,3A,2E,FC,EB,BB,39,77,5E,23,E3,88,71,F3,B8,25,B2,9A,C0,8F,62,33,9E,89,00,A8,17,8D,FF,7F,62,64,E2,4D,DC,47,E1,1C,FF,CE,BC,4B,48,4E,7E,97,27,A6,BE,98,F5,DC,65,1D,83,E1,09,11,2A,18,02,7A,F8,61,2C,B3,A2,CA,BE,57,F8,E8,85,52,F7,D3,A1,DE,61,9C,57,EC,1C,8C,77,65,6D,4B,96,16,8F,20,24,AF,84,AB,F3,BB,17,D1,93,07,B7,1C,B2,29,C3,5A,75,D8,8C,1C,3B,D4,EA,3D,78,48,DA,A6,BA,72,0D,FF,0B,33,77,9A,BB,55,30,2C,C6,C4,AE,B0,70,A1,8D,B2,00,03,3E,44,77,D7,15,F5,00,C8,28,AD,49,80,D6,20,89,F3,6D,32,C4,5C,33,8B,05,82,11,3D,10,E9,63,D8,3D,36,58,9F,9E,58,29,60,37,32,84,9D,6F,3C,C4,29,A4,D5,15,66,52,9E,37,F7,FD,1A,3D,72,4E,E2,F1,0F,7E,5C,49,60,9D,ED,CF,8F,93,8B,A6,D1,74,DF,70,C6,75,19,BD,52,8C,35,DF,66,D8,F6,AA,24,97,A0,57,4B,E8,C5,70,20,86,81,28,7D,0E,CF,72,6F,8A,F4,6A,21,B4,47,5E,99,93,D4,D7,CD,1E,6F,E2,B8,8A,65,F6,18,5D,FA,9B,74,4C,D7,64,AA,86,C8,59,71,DA,AA,B4,E7,E8,D0,E5,10,EA,38,AC,E4,C4,B6,7C,17,C1,A4,78,F7,E3,37,89,E2,4E,86,E9,4C,32,56,80,9C,C7,1A,AD,7E,C6,CB,D5,15,36,D5,56,65,BE,75,80,8B,18,27,15,8A,13,F5,AF,FC,A6,4E,FF,01,88,56,08,6D,E2,CA,3A,93,5F,F9,CE,40,B4,EF,78,80,15,E8,C6,F7,50,92,96,F7,D9,DD,17,69,FF,3D,01,38,80,92,08,A8,80,90,79,0B,81,13,9D,3D,6D,78,53,8B,64,22,48,D2,14,2D,48,E5,5C,E0,45,F2,81,5C,CC,80,46,DB,D6,95,8C,36,CF,2B,5B,63,6D,10,40,2C,45,FB,E7,E6,A5,DA,4E,BB,BD,FD,E1,37,4F,7E,AD,12,D7,2D,26,AB,15,7E,CE,D1,F4,0D,74,09,91,08,0A,05,11,35,FC,0C,45,C7,76,92,75,BC,D3,98,CA,A7,CA,76,B4,86,A8,35,88,3A,A7,BA,DD,1A,04,71,96,A2,A5,A8,71,FB,3D,8C,3C,56,AC,86,21,F1,28,85,FF,75,06,0B,43,A6,28,6A,79,0F,B2,0E,72,33,70,9B,A2,1F,2E,79,64,4B,45,95,2B,F4,4C,6F,AE,CE,1D,E6,83,8B,2A,19,76,47,A2,D6,74,0B,94,5C,42,E2,F8,44,71,C9,61,B5,6A,56,E8,9F,91,9D,DE,DA,43,1F,AF,97,BF,1E,2F,D5,A8,CB,E4,C0,C5,AC,94,F0,AF,0F,A6,7F,A6,3B,F2,14,2D,BA,4B,47,3D,CA,6C,CE,3F,54,83,4D,40,68,93,C2,41,AD,D6,16,68,44,72,A7,A0,6B,0A,5F,59,03,87,D9,17,2A,C6,52,E6,AD,8C,3F,03,55,6F,DC,E4,03,49,0D,56,8E,B1,09,1B,29,FB,FD,FA,4A,8A,69,A2,DD,BD,6A,9F,85,EB,44,A2,DF,BC,52,F5,74,02,2F,25,77,AA,6E,21,93,66,7D,31,3D,A9,BC,50,82,A0,09,A6,47,3A,6A,38,89,DE,1C,90,AF,98,A2,1C,60,3F,21,AC,9F,C4,B0,4F,15,ED,14,86,5B,38,D3,E7,68,66,AD,6A,8A,84,64,F8,60,AB,8A,6E,5E,3D,71,C9,9B,31,DD,D4,9C,92,E1,7A,CE,C5,14,D8,47,81,FD,91,96,C1,3C,E2,C3,12,C9,EA,96,65,F0,47,3E,B4,C0,84,02,08,FF,80,BD,83,72,73,10,E6,1B,00,47,50,BB,CA,BB,E5,8D,A2,D9,57,16,40,85,98,1F,31,2A,79,09,8C,F0,BE,81,23,F5,B8,69,D5,E7,B7,26,3A,DA,3D,7B,5E,33,66,7F,00,97,25,BE,CC,B5,E7,B8,2C,D4,98,20,39,C2,B1,C0,8D,D1,90,EB,16,05,90,CB,EC,DA,60,DA,8C,D4,F4,19,6A,48,36,0C,81,C6,9B,89,F2,31,77,96,E1,D1,7C,12,7B,1B,43,D9,BE,EA,75,DD,0C,7F,0D,EF,53,A8,B3,58,E4,33,C3,A9,D2,7E,97,40,96,D4,C5,14,E7,E1,63,A6,7D,26,A3,DC,D8,2F,F7,CF,F7,D2,AE,3E,3E,06,47,F1,65,F7,5C,24,90,B0,8E,2E,9C,C4,B5,D7,A4,33,BC,9E,34,65,DA,36,AE,53,37,DF,B4,41,2B,9A,6B,24,DB,7B,A4,93,0D,45,61,55,B9,4A,AD,D7,C4,20,93,D1,6B,CE,DD,DC,D2,F9,64,09,EF,C5,43,06,91,9F,47,DE,42,B7,AA,5E,9C,90,04,D9,B0,1B,71,63,84,E1,86,BD,3C,E8,62,D9,44,6A,4A,20,1A,62,87,AB,1D,82,FD,34,15,12,4F,3A,E6,88,BE,11,B7,42,07,32,8F,92,DB,EB,30,5F,0F,10,39,65,A9,4D,B9,BA,FD,72,1F,79,4D,C8,95,B9,27,9D,46,D4,18,25,59,04,40,BC,0C,34,8E,03,AC,D9,C7,53,B1,6A,1D,02,35,2D,58,2A,08,E8,83,2D,26,9E,98,C7,89,BD,A8,10,47,6A,D6,92,07,9B,F9,53,F8,0C,04,62,37,7A,91,22,44,AA,D1,68,97,62,FD,53,FC,47,76,4E,97,5E,43,8D,0B,63,2A,D9,D1,52,34,BD,75,BA,C1,91,8B,A6,DE,CA,D5,DC,BF,8C,44,AA,16,C0,C1,96,C8,84,7F,4E,05,71,31,B4,69,96,5A,9B,6F,60,49,CF,12,BF,0E,1D,1C,EF,92,C8,A5,7A,CE,A6,CA,55,D8,1B,62,F3,94,58,AB,3B,10,C2,7B,BA,AC,86,EB,99,65,41,43,5E,B1,54,56,0C,9A,CE,9E,21,3C,3C,1C,83,C3,34,A4,80,89,7E,A2,95,DC,74,04,EC,2A,DD,7C,47,7A,D2,EB,FD,97,0E,19,B3,92,C2,27,F2,A2,9A,1D,04,18,15,4A,55,D3,ED,4B,F1,B4,51,3D,5C,AB,33,2A,D5,15,F9,7D,94,3D,EB,7F,3E,78,5D,B7,0F,54,22,33,5D,10,8E,94,1B,DE,E7,EA,AC,31,1F,59,C7,77,CC,35,BE,E0,07,08,33,84,D4,90,08,C7,11,C4,AD,2C,6D,75,29,D5,AB,8C,40,82,88,A3,58,82,AF,85,AA,BB,53,BB,E5,14,42,1D,94,6B,FC,B9,39,AB,05,D9,57,8C,FE,EA,94,9B,09,36,75,62,3D,52,0E,FD,79,0E,0D,10,0F,20,D0,BF,24,96,16,6F,43,FF,D6,D2,7A,81,CE,D6,1A,5B,04,02,3B,AD,4B,DB,04,7E,72,96,69,DF,C5,17,CF,ED,89,DC,2F,5C,9A,1B,68,98,F0,DD,D7,40,33,4E,1B,BD,7E,1E,4F,DD,4D,DA,2F,67,45,2B,87,FD,4E,B5,A8,6B,06,CC,30,28,E7,AA,30,FE,9C,AF,E6,5C,4A,86,36,DA,86,8A,36,3D,34,F9,74,BE,EA,AE,98,DA,F0,EA,0E,12,E8,88,BB,D1,5E,5C,BC,D5,96,F0,BD,F8,3F,12,10,08,01,85,AA,77,0A,A7,D7,63,4E,8B,EC,03,E8,6B,C4,4C,EB,5B,4B,7B,76,01,0D,22,58,19,78,66,DC,8E,E9,48,A2,91,3B,C0,33,FE,09,82,6D,3E,88,2E,75,67,47,6B,D2,52,C8,1C,76,80,83,87,46,C8,DD,42,5F,EB,DC,9C,45,B3,15,D5,0A,DD,CC,15,9C,41,3C,C2,02,26,4C,8A,BD,90,BF,75,E3,02,2E,3A,67,0D,5E,FB,06,9B,C8,77,DD,CB,6F,5B,52,9B,37,9C,4F,D1,9F,BC,EB,46,8A,5B,D3,0B,FE,54,EB,80,20,E6,3C,AB,20,FE,7C,31,58,1A,70,4E,49,5C,02,A5,71,70,B1,DA,96,84,37,76,F6,0E,18,75,14,9B,D4,C1,34,C0,A3,5A,B4,BB,A7,B0,49,46,B4,46,B5,C6,19,BF,40,21,43,54,6B,2F,FE,B4,D8,65,7A,DD,53,F3,36,51,42,37,57,C4,4A,CF,D0,DE,0A,27,B2,91,B3,47,9C,67,63,7A,69,0A,D7,28,3F,50,62,A5,36,29,5C,47,80,74,1D,EB,FE,8F,B8,A0,5C,CF,B5,80,6A,3F,96,E6,7F,D4,C0,1A,5F,76,F2,05,51,F3,74,8C,50,09,26,C1,61,D0,B7,DC,50,DC,82,49,31,9E,6B,51,47,F2,19,28,2A,57,47,ED,79,1D,F1,3E,DF,83,B2,42,DD,16,F1,AD,91,24,72,03,D3,F1,FC,3C,28,EF,72,D9,B5,96,E1,62,3E,FC,58,B0,5F,DF,8A,1A,32,8B,D3,4F,DE,3F,E7,EA,F5,4D,93,93,F4,8C,20,ED,A4,7B,F9,91,5D,0A,81,FF,CE,CB,83,E1,6F,71,75,C8,00,FA,D9,D9,F5,DC,94,D5,A4,28,8F,11,7D,3A,60,FF,31,08,2D,2D,D3,76,31,C4,71,D6,6E,41,AA,8F,B7,CF,E4,7A,B2,65,F3,C9,66,CB,A7,E3,80,C6,BA,C5,6B,05,D9,B5,B5,3B,1A,8E,E2,C5,76,36,B9,0D,09,AE,C3,C6,F8,1C,3A,2C,09,07,56,74,A6,A8,9D,64,64,46,D5,E1,B1,AF,59,CB,FC,9E,D7,6A,48,5A,7B,E6,F0,BB,66,52,20,ED,2A,C7,E0,1F,15,73,33,A9,45,8A,9D,4D,AF,56,8C,59,3C,00,E9,E5,BD,8B,8B,EC,A6,17,F4,B9,20,A0,0E,ED,69,C1,15,A0,C5,60,19,C5,9B,86,57,FB,B7,61,2D,B9,E4,F8,4A,46,6B,26,71,14,54,F9,61,A9,E7,9B,47,8E,8B,28,93,60,49,E9,42,8C,6A,6B,7A,69,5B,5D,73,3E,46,98,B3,7B,85,D7,DC,2E,7A,D2,FD,C3,BD,AF,FF,4F,E3,AD,38,30,59,B4,FD,A2,AE,9C,B0,7C,AD,DC,39,EA,7D,E2,8B,F5,C2,B6,B0,77,EC,0D,D5,44,88,E0,C8,44,99,E3,04,08,91,89,1A,75,AF,A0,C0,3F,92,94,70,35,EE,09,F3,0A,E6,14,26,B7,0E,EE,4C,1E,90,99,16,5F,13,9E,35,FD,D6,EA,9A,B7,7C,89,74,B2,D9,F8,8A,28,50,BB,BC,52,E0,79,B0,04,BB,64,22,B3,5B,B4,53,B1,CD,32,88,12,12,62,31,A1,27,2E,22,D8,11,D1,0D,5E,DA,42,EC,FE,A9,48,E0,A1,81,E0,F9,AD,71,CF,5F,32,04,4D,FC,AC,A9,99,57,90,CC,9B,98,CD,A9,52,E0,72,FB,13,0B,40,B2,6F,F4,90,73,E3,79,6A,2F,51,F4,BC,63,FF,C6,5A,75,3E,CE,4B,65,EE,64,CC,5E,93,75,66,3B,73,4A,4C,60,B5,A4,E1,38,C9,D5,E9,0D,8D,B6,43,C3,CF,62,4E,74,E0,49,4A,DD,1B,39,71,B6,7B,12,56,F2,D3,21,C1,3E,37,F9,FF,3F,0E,2C,E4,1C,0E,EB,90,9F,0E,7B,8A,CF,92,3B,DF,FF,F1,37,53,84,C0,42,B9,34,C2,11,7C,79,9B,8A,60,07,78,11,DB,FF,DB,51,D2,23,5B,E1,36,46,60,94,E3,84,8A,59,29,C1,A6,A7,53,38,86,B9,A4,4F,13,65,F7,3B,ED,D6,87,4A,32,AB,06,17,6D,F1,50,09,D2,A2,5E,E6,21,5F,69,FF,EF,26,D7,EA,0A,CB,B1,F5,28,66,59,6A,D0,60,D1,E8,1F,F9,DC,67,82,D8,63,2E,55,30,AA,DB,D4,F0,84,09,8A,D3,00,68,C3,F3,12,6A,DD,B1,B6,52,E0,DC,D6,35,0F,B5,5D,99,80,B8,FD,9E,BA,E0,E2,16,BD,1E,6D,C0,1E,1F,9A,7B,1E,5B,FD,86,DE,EE,78,38,88,13,E2,85,11,CB,33,29,C4,B4,18,B8,B4,74,CE,EB,CE,76,9B,5E,7D,A7,86,D1,60,CA,2E,27,70,F8,C8,82,B3,B2,F3,9C,23,47,F4,D6,0F,33,A9,5A,F9,11,9B,E7,0E,68,32,07,E0,03,79,73,A2,6A,23,E2,3D,4F,79,AC,94,D7,71,9C,C4,DE,D9,F4,C5,01,D3,E5,F7,71,54,55,86,F8,9C,2F,64,F3,CD,C5,A8,54,5E,47,CB,BA,F4,31,87,A9,6E,FC,4C,BE,B0,D3,F3,D2,CC,1B,43,87,78,88,05,6A,7B,81,56,A7,E2,84,26,49,DF,30,02,93,05,0A,BA,C9,A0,44,60,D1,9F,F8,6A,F5,78,EB,AE,3E,8E,8E,A3,30,60,51,66,7A,E2,C2,AA,D6,27,A3,7C,48,AD,83,26,09,0C,3E,05,D8,7E,42,A4,00,1C,DC,BA,FE,8E,50,93,14,D8,34,AF,06,F3,AA,AB,2A,00,AE,F7,F5,89,8D,84,0D,EB,54,CC,F1,4E,A4,D9,E4,5E,B1,C4,81,8E,A6,B4,01,08,17,E6,D3,C8,45,B9,BB,04,EE,4B,17,44,6F,9E,FF,C6,92,3A,46,E8,B3,AE,E8,2A,E5,08,89,92,75,A7,0C,1D,B8,60,43,43,B1,F6,BE,0F,A0,28,FC,A5,AB,4E,EA,47,66,78,AB,BC,B0,9B,88,22,2A,9B,46,94,C0,29,D2,E6,6D,43,A8,01,D0,67,29,D1,C5,7E,3C,E0,E0,27,46,D4,69,23,72,94,E0,4E,E7,06,76,9C,30,AA,76,F1,B9,8E,03,B2,04,0A,49,1C,E9,6C,D2,48,7E,8F,88,A7,9C,23,2B,78,31,DD,88,10,DC,43,1B,1A,0A,B6,CE,CE,1C,16,05,6A,53,9C,29,6F,EF,D8,B4,5E,60,4C,F0,E0,FD,62,A7,4B,30,4F,BE,8D,00,DD,74,FA,82,75,C2,F2,EB,45,90,CA,74,4E,AA,DB,37,19,A0,9F,83,88,77,A9,67,12,1F,7F,16,89,F8,06,42,59,1B,BD,2C,09,EB,9A,6A,FB,6F,DA,AF,A0,68,97,37,40,86,02,28,18,79,0D,56,D0,4C,7A,F2,8E,4A,CE,F2,28,2C,D3,8F,1F,BF,BE,28,B5,CC,93,C9,F6,1D,A0,96,84,D3,92,27,BA,65,EB,4E,88,46,C3,62,9F,BC,4D,61,D8,33,15,39,B7,62,BC,6D,81,EA,B0,F1,3F,B1,EC,21,21,9F,82,03,C2,5E,B9,32,35,08,17,26,D2,67,55,20,57,77,C5,18,A4,B7,41,61,88,8C,30,2F,59,1B,4D,6D,59,B8,8C,9C,7A,7E,71,C7,36,E9,D3,66,DC,0A,C4,D4,96,7B,41,4A,F7,DC,5D,E1,1E,AE,8B,CB,4B,49,B1,A5,77,F7,B5,58,4E,7E,35,47,DE,E5,8F,DE,5C,6E,C0,F6,B0,9C,E6,1D,49,69,8F,DE,C9,50,5D,F3,43,82,07,81,78,40,B1,D4,57,1D,C6,E8,99,13,03,7E,5A,FD,D7,7E,49,6B,A0,48,B9,F5,7D,8A,C3,47,13,74,2F,77,9C,AD,4A,2C,AE,C7,90,D6,67,5C,0A,A8,09,AC,E4,FD,26,36,C0,CC,D2,86,43,FC,D1,36,95,5D,FC,F3,CB,73,A5,48,BD,80,D4,8C,33,00,30,74,4D,EF,31,06,DA,F2,A9,4C,19,EE,73,FD,83,F2,A0,35,AC,69,FE,E4,19,56,C5,B8,F0,19,D7,E6,1E,CE,A8,9C,B9,C9,EF,63,F8,B6,74,80,52,BA,E3,79,1C,9E,AC,69,9D,D0,58,BA,59,56,FF,82,F6,9F,07,EF,E7,8D,E9,A2,46,17,8E,8B,C9,2B,2C,CF,81,9D,D5,19,A3,A6,7A,67,00,01,C6,D9,94,78,01,32,65,E4,0B,CA,84,83,93,F3,92,4C,5D,7E,F0,B6,E3,97,50,E0,E1,BB,C5,07,A6,96,EC,E2,1C,5E,6C,24,A9,78,97,2D,F4,A4,5C,97,08,B4,E4,C4,D3,3F,A0,31,06,BD,B2,51,88,5B,14,87,7B,A2,EB,3B,80,E3,29,26,75,72,B5,C1,95,BB,A9,03,A3,57,FD,F1,2D,62,C9,B5,06,DC,27,5C,32,12,E4,79,4C,A7,32,E0,16,31,3B,39,47,C5,17,0B,7C,B8,20,E4,BA,52,D1,19,0D,F6,66,88,50,6E,32,C7,80,DE,FE,DA,C0,91,82,7F,2D,FF,DB,7F,EA,FC,22,B8,0C,49,C3,34,BC,73,D9,CC,EF,A3,F8,DC,CA,AC,64,7D,CB,21,90,93,BB,EE,6E,6B,3F,C4,EA,50,57,40,78,D6,78,55,F4,74,B8,DF,CD,BB,49,59,BE,1B,9F,D6,D7,B5,47,6C,A9,B6,51,32,9C,21,8D,0B,31,72,71,DF,16,E0,F9,DE,74,08,3B,A3,48,96,57,1B,23,AF,50,49,9F,BA,D1,85,95,74,62,03,BD,0B,77,EB,18,4D,87,F5,98,A9,72,B6,C7,AF,7D,37,9D,36,66,E0,48,C9,FB,09,42,A5,F2,05,F8,6E,3B,73,B8,D0,BD,89,4B,35,7E,6F,3D,78,CF,79,D4,81,30,4F,68,63,13,0B,D6,C5,83,0E,8C,16,F5,BA,E3,48,DE,04,5A,61,6C,24,B8,42,0F,4C,15,ED,C1,17,DB,97,EA,2D,36,F1,F3,EF,AF,5A,01,4C,57,9E,AE,39,68,96,AB,A9,C8,E4,C8,49,09,D3,FD,F2,8A,10,9A,D8,06,42,B1,1F,BD,74,6E,7B,07,CD,5B,E7,71,0D,DC,9E,6C,6F,A4,E8,7D,F8,C0,8E,F9,45,9F,1A,32,66,C7,31,61,6A,8F,03,0C,0D,A1,80,DD,62,75,F0,33,B9,0F,6D,B3,60,8D,8B,26,93,71,B8,62,DC,C0,87,5D,94,C7,C9,36,99,8B,16,44,74,F4,13,2D,73,35,16,E2,BD,F6,F3,54,C7,85,3B,4B,20,89,07,77,D2,C1,E3,FD,F6,60,61,52,AC,BA,F7,32,0F,8D,D6,69,23,E2,B2,E1,80,1F,5A,0D,12,B8,E6,E8,8B,8B,7B,BB,0C,E1,CB,F5,89,F8,D9,A5,93,AB,30,FD,C2,EE,A4,E9,B8,7A,85,18,15,2D,3E,54,24,05,9D,6D,5A,A7,9E,A9,96,21,37,00,D1,C0,6D,F2,B3,C8,6D,A5,EC,3A,93,42,FE,D6,9B,28,F3,22,C1,C3,C0,0C,D0,05,22,08,C4,05,7A,34,E6,48,AE,15,92,61,CB,8A,18,75,6B,60,04,AC,3D,30,38,94,3F,6E,C2,95,2C,B2,EF,F9,FF,D0,8A,D7,87,D0,CA,EC,2D,76,B8,B7,A0,87,21,77,B3,6C,8D,05,5A,CD,8A,4B,FD,15,BF,49,85,73,7B,CB,5B,71,A7,FF,8A,BC,D6,0F,A8,1E,A8,77,CF,4B,29,35,18,3C,0D,1D,AA,3F,BB,47,5C,82,2D,52,D9,83,BF,C1,5C,72,46,FD,F7,69,59,A5,EA,DC,68,08,C0,3C,BE,DA,C3,10,FC,CF,FB,31,00,28,3C,F6,4E,FA,B0,14,B1,4A,78,50,68,5F,73,8C,3D,58,FC,B6,D5,AA,DA,0A,FF,08,6A,32,4F,26,DE,FB,53,92,17,0E,D2,88,9A,AB,ED,84,0F,5F,B6,2D,48,73,02,F6,99,79,17,30,E8,17,9D,76,B8,25,52,61,0A,3E,1A,8F,8D,C8,C7,35,72,1C,1E,47,98,4A,B1,02,B5,7F,49,6E,80,8D,36,98,FA,3D,7B,2B,E8,9F,01,58,0C,DB,33,49,D6,80,BA,C5,1A,55,AC,B7,42,87,FB,1B,BD,AC,B7,D4,D2,68,2F,B8,25,68,99,CC,88,E4,A5,AC,27,53,B0,C5,A3,31,8B,F8,E3,FB,D8,2B,61,88,F1,67,A3,A9,BE,68,1A,D5,53,BD,58,13,D7,C9,0E,FD,5E,FC,48,33,60,65,DD,A6,2C,AC,39,F3,DB,33,BB,9A,76,72,0A,BF,C1,A3,1C,69,55,FA,9F,68,00,CF,3E,14,E0,47,1A,5E,5E,5D,F8,FF,67,82,B2,20,ED,06,BA,85,75,2D,58,81,2D,F9,7F,D7,12,9B,3D,EC,7C,B4,61,0C,77,8B,CE,D5,CA,1D,09,14,F1,6D,A1,67,5D,ED,0E,1F,72,C4,1A,67,7C,AD,89,0D,DF,62,C1,15,F5,61,F0,7B,5F,98,5C,FF,39,DB,5F,B3,9F,51,2D,14,E4,55,51,68,8D,68,ED,22,DA,80,B6,33,37,26,8D,44,23,19,DA,CF,DB,FD,5D,A0,22,32,BA,CE,39,A0,01,EC,DA,E4,A4,B6,DE,AC,B3,72,04,52,88,64,61,46,6C,07,96,39,C6,0D,34,97,E3,C3,4E,09,1F,89,CD,E4,71,77,AF,A1,2E,CD,B5,2D,16,8A,51,02,AC,78,31,4C,EA,41,15,33,CE,4C,00,01,45,52,1E,A9,B4,65,52,F5,5C,2A,00,CE,B9,65,30,67,22,12,84,4C,F2,91,CF,A6,E5,8E,E4,58,92,5E,9B,B1,2E,BF,42,8E,DD,CC,DC,38,FD,87,0C,9E,87,A9,DA,D4,34,9A,64,1A,7D,D7,18,A0,48,F3,0D,65,14,74,C1,96,85,AC,16,C3,BC,33,30,B7,37,34,46,EA,27,AA,FB,30,56,EC,58,AE,12,09,66,2D,99,75,43,DF,DC,7B,54,81,A0,F3,EB,A0,2C,A4,31,FA,39,B0,43,59,AB,49,66,22,16,E4,2A,51,F2,2D,97,69,DC,25,0C,E3,C3,9A,07,9F,95,5D,FE,FB,C2,8A,7D,8E,79,6C,A8,55,C6,C3,E1,9D,10,33,08,32,23,5E,51,AA,6F,DE,C8,B2,F9,F3,E1,3D,5E,41,CD,B2,CB,61,CD,E8,56,77,30,37,A1,1F,39,91,24,CB,A6,17,D5,54,A2,F2,7F,50,C4,E5,F4,C5,1D,9E,9B,93,2F,67,6A,FA,A6,C4,11,5F,D0,C1,9C,8D,41,42,40,99,46,1B,3D,1D,71,C1,10,FF,45,9C,F0,9A,6B,E5,10,05,E8,8D,1B,D8,3B,F1,B5,E6,12,56,BB,31,76,06,23,0A,AA,20,5B,65,0C,0A,9E,00,75,09,B7,B3,FD,26,91,E5,61,78,EC,F7,63,60,E7,10,74,72,78,55,AF,1C,BE,F6,E5,0E,30,13,5C,E1,7B,F2,29,FE,B9,0C,6B,49,82,54,F2,96,42,C2,84,0C,0E,2C,D3,7A,DB,3C,32,8E,60,E7,9C,1A,15,DC,42,17,07,E2,4E,97,00,B0,CA,E6,AA,01,EC,ED,CD,90,0C,2B,DD,C9,5A,A3,2A,1F,91,AE,93,64,54,F0,58,0D,F4,51,2F,E5,89,30,1F,03,F0,EC,7A,0D,9C,1D,FC,F1,4D,29,A5,E0,97,B3,54,23,6D,5A,84,5E,B4,41,A0,E7,D4,26,B2,F3,0B,C3,F7,A0,37,39,0B,0D,1E,A9,CE,62,32,59,87,A4,67,3B,6E,2D,80,81,CE,46,A8,36,75,35,77,9B,FB,60,1D,11,1C,08,16,9F,84,78,B3,CC,10,4A,25,64,7B,4F,C3,89,0E,D6,B8,7D,8A,9F,09,FF,35,79,3C,25,A1,D9,D2,42,10,A9,1B,83,CF,FD,F1,46,AD,1C,CD,E8,48,B3,63,D0,EE,34,7A,A3,0E,F5,62,82,07,58,17,22,AB,49,E1,4E,72,C0,2F,3D,66,BF,26,E7,CA,36,54,82,D8,F0,E8,54,C6,F8,41,3D,C6,14,A7,F8,46,03,21,70,E4,DF,E6,65,61,82,A8,EC,6D,40,EF,E2,13,1B,67,75,C2,7A,6B,24,7C,6E,00,DE,23,BD,91,CC,35,DF,06,9E,69,08,19,FF,74,7B,BD,E9,D6,58,B5,72,96,28,8F,67,49,88,AC,65,6E,18,DC,6A,FD,D6,F5,7F,26,70,F3,A5,73,13,8F,8E,64,D0,07,E7,F0,9D,2D,30,23,56,80,E7,C1,DC,ED,15,E0,E4,BB,FB,3E,DC,19,35,74,CA,65,79,25,72,ED,D4,37,62,32,41,54,B3,7A,2C,59,7B,E0,8D,D6,24,A1,4B,01,6D,BC,C4,58,46,8D,08,56,AF,A9,2E,2A,F2,81,35,79,9A,37,9E,3D,CF,BE,72,96,0A,20,A0,CA,89,F9,C0,72,E3,1E,F8,EC,54,60,55,73,DD,95,50,F4,24,57,DC,BC,0F,C5,51,EF,29,32,E8,B8,FA,69,3D,A6,FB,05,C2,2F,88,35,75,85,EB,04,6B,55,F9,6D,D8,9B,19,53,CF,B8,C9,F0,20,3B,5F,A3,CF,6A,49,A4,4B,E7,5F,DE,06,30,E3,27,04,60,6E,9F,9F,63,26,C5,86,5F,50,E3,67,D1,B6,BD,81,8A,0D,1A,7F,6B,EC,20,A0,0A,FC,1B,07,50,3D,8F,4B,CF,45,1C,98,C6,AF,5A,55,D2,8A,14,25,17,4D,F1,CA,66,CC,1C,A9,81,A1,FA,F8,F3,48,5B,EF,21,E3,C5,FB,B1,A8,80,E1,64,BA,F9,06,42,28,1A,CA,C2,42,99,8E,EE,CC,5F,E3,01,27,A4,0D,1A,75,14,49,CD,D2,43,80,E0,AF,B9,57,AB,01,60,34,1F,BD,35,8F,EC,BD,08,5C,FC,5F,0F,8A,E3,1A,99,66,F4,5C,0F,73,CF,7C,9D,C3,C7,D4,BE,06,CA,E6,DF,CA,F2,F6,30,10,59,78,AD,90,6E,F5,09,0E,2D,FC,3C,49,C9,BD,68,08,DC,63,8D,9F,21,20,0C,4F,40,27,8A,01,09,79,04,A7,D3,82,5E,B6,96,DC,67,9C,95,E6,1B,10,98,14,E3,4A,08,00,31,F8,A5,4A,C2,85,BB,6C,04,EF,7F,E8,89,77,05,EE,6D,48,61,50,85,04,E9,CC,12,AE,CF,2E,F6,5D,34,02,3D,E9,BB,45,75,98,50,D8,3E,44,25,A7,45,FA,80,52,3E,07,38,F6,3B,24,F8,43,11,4B,1D,3F,F8,AC,6A,29,49,06,33,CA,97,39,77,5E,08,41,65,CA,AB,DF,8C,12,89,A7,67,73,2D,19,83,A4,1A,E2,5E,5C,2A,7A,55,16,89,18,2C,B6,DA,29,23,BE,CB,5F,F5,E8,F7,AB,CF,7F,03,96,56,96,B2,4F,07,18,18,70,1D,A5,20,F0,36,75,A4,E3,72,F0,F6,65,23,C0,6C,ED,00,0D,99,DB,91,B7,47,EB,12,60,D0,09,1F,A3,42,4A,B1,24,AF,F0,CD,42,CF,66,2C,E6,55,BE,A3,3D,EC,2B,C4,A1,33,44,7C,39,21,05,39,36,F6,E5,58,A2,58,92,76,8B,88,39,08,94,BA,B1,E1,80,27,16,6D,E2,A8,2E,14,98,D7,B0,69,E0,4F,01,38,C6,00,B2,C8,3B,58,BA,D2,AD,09,C2,7A,A8,72,1D,E0,12,94,A8,80,E2,6D,11,F7,23,FF,0E,E8,68,B9,0B,5C,20,50,F3,AB,B9,F9,4C,57,6C,0D,F4,61,82,1E,8C,22,D8,E6,CC,26,71,46,2A,DC,A1,83,1B,9A,A9,41,23,BB,1E,FB,6D,B6,7D,E5,99,E3,3D,34,74,15,A7,9D,3F,5D,7D,66,F2,EC,2E,44,5E,A0,9C,EF,1D,0C,66,89,4E,82,42,D2,80,F9,88,E5,A9,BD,DC,95,60,27,C9,B9,34,DB,23,EF,D6,75,B0,1F,C7,A4,91,CC,54,E8,48,AA,1F,99,81,29,07,0E,8D,18,C6,49,6B,23,38,BE,78,B9,92,B5,47,C0,7C,06,DB,84,95,03,EF,7F,B5,5F,DB,BF,E1,6C,1D,3F,E8,93,CE,C9,05,B0,41,75,80,F7,3B,28,9F,E8,B5,81,D3,27,4C,4C,95,D3,46,1F,88,E0,65,8A,86,48,D0,8F,47,ED,E6,AF,73,35,56,71,9B,69,54,2C,68,E9,9E,F7,71,1A,5E,A5,17,C3,84,70,CB,21,3D,27,D1,FE,FF,AC,EF,93,11,1C,3C,61,DB,23,B2,24,C0,78,92,DC,19,F1,9F,78,11,8C,46,69,46,F8,D0,2B,2B,08,30,F3,BF,A8,8F,05,FE,A2,79,97,39,1B,8A,AC,63,10,6A,FA,4C,48,E1,E8,BB,4D,A3,04,1A,46,26,CF,3C,CA,6C,EE,6C,D0,63,5B,E3,31,A7,1F,36,83,24,01,B6,AC,2C,68,CB,FE,60,CF,43,82,AD,54,6F,45,3D,FB,96,D9,C1,B9,92,BA,3B,B7,87,7D,64,83,4D,86,C3,EB,04,DA,36,3F,85,F3,8D,60,86,7E,17,E0,9C,97,A0,85,92,B0,1F,E4,01,A3,B2,C6,8E,78,49,61,43,8F,CC,D7,B2,54,8F,8A,3E,E5,08,87,EE,71,2B,43,F0,66,D7,D6,55,C1,54,D8,01,7C,1D,B1,3E,CD,0C,58,70,FA,D9,D3,98,88,2E,92,1A,35,E1,1E,8F,40,62,D8,E8,C1,50,9B,EC,31,8B,27,0D,17,34,5D,5B,75,D1,D2,67,6B,25,80,73,C1,00,51,42,9A,22,78,C1,E3,E7,B6,40,76,3F,76,41,2A,5F,7A,0A,87,CD,5E,15,EA,B3,E0,D7,F7,42,C9,E1,15,8A,91,22,21,12,FC,D9,89,B8,15,C3,89,2E,49,2E,F4,BA,BF,DC,33,78,4F,13,49,C1,1B,4B,75,F0,E0,9A,55,FB,77,05,58,D2,37,29,CC,D0,2A,27,B2,A7,1D,9F,AF,28,CA,39,17,00,2E,0F,89,40,D0,18,FA,30,F9,68,28,83,71,AF,45,CD,D7,45,1C,FA,08,53,58,02,D9,F7,33,2F,C3,F9,63,93,9B,C5,4A,29,E8,AF,42,CF,C9,2F,C5,21,51,3C,5C,37,B3,AA,EF,29,C9,CE,8B,A7,A1,2D,6C,51,48,40,18,85,81,2C,E7,C7,4C,CC,31,24,69,8B,B3,5E,5D,5D,C0,E8,4C,4A,79,A0,52,24,58,CF,66,27,86,7B,D0,3E,18,40,6F,72,5A,A9,4B,4E,D3,D9,8F,93,05,50,B5,73,63,5E,B8,30,A5,DE,1B,01,20,D7,84,86,2C,B5,AC,4C,10,7D,1D,79,07,4F,A6,86,57,2C,CD,B7,54,AB,5F,73,96,E6,86,A8,54,C5,CE,A2,E8,4F,47,90,21,B0,99,38,C0,AF,10,DE,1D,9D,C4,52,83,35,C1,A6,56,72,1B,06,BE,11,48,6A,44,0F,6B,91,BB,3B,A4,2C,8C,51,03,59,F9,C5,86,A1,D1,3A,E5,73,34,E3,02,C5,BD,02,48,B4,00,10,EE,2F,69,8B,7E,8C,70,B0,55,DF,5B,3F,62,85,48,C7,86,69,D9,D9,4E,47,07,5B,31,6C,7F,44,7A,54,33,5E,AC,9D,C2,9B,A6,58,3E,00,7B,A7,E5,2C,37,65,D5,2F,26,46,46,87,7D,6D,21,06,F9,4F,B6,85,30,68,35,54,7D,AF,3B,B7,30,2B,66,89,4F,81,54,F3,53,F6,7D,7C,3A,D2,27,1B,9A,3F,79,4F,1E,50,45,13,F5,8D,7B,97,CF,29,95,B5,2D,C4,63,87,C0,4A,09,03,01,EA,07,E5,51,D7,C8,CD,21,0F,CE,14,6B,64,90,C9,8B,3D,EE,3B,03,CB,06,F1,3B,2F,C7,37,61,AA,3A,E8,1A,26,DA,34,09,63,FB,F9,86,C0,75,C4,58,04,38,41,95,35,CB,59,C9,78,86,64,D7,21,B3,56,EB,D1,90,18,F2,53,BE,C9,8C,D2,BB,91,A4,F1,F2,7B,38,E6,63,5D,0A,9C,4B,06,79,83,92,51,17,03,68,DE,FC,87,54,31,CB,4D,82,A0,C0,01,7E,AB,BD,53,2D,02,02,2B,FF,F9,BA,27,38,2B,3D,98,7D,DB,07,0A,F6,CE,88,13,4F,5B,EC,1E,6A,1B,52,74,7E,BB,3E,22,04,6E,FF,21,24,41,74,EA,A0,33,5E,C7,EC,B3,44,7E,6A,F0,2C,93,E0,08,0B,C5,35,AC,6B,AA,DB,C2,8A,EA,49,A1,B0,DD,3F,2B,D6,A0,B9,E9,1A,76,79,77,67,26,BF,56,F5,FD,4B,E1,AA,B6,52,AA,BD,7C,76,EE,DA,48,7F,C4,95,CB,A3,C6,DE,F7,FD,51,93,57,39,26,53,9A,4D,26,12,32,76,2E,F8,0C,8E,62,B1,32,AD,79,50,B6,82,55,85,67,9E,1C,50,F3,02,2F,19,7B,25,7A,1B,60,92,B6,AC,0C,FB,2C,B7,25,DB,62,5B,B1,2C,1F,A1,B1,C9,BA,98,4D,90,DB,2A,C5,A1,A6,B3,06,14,2B,7E,33,14,B9,D8,EF,CA,AC,8C,35,C0,01,89,DC,02,98,04,AF,94,41,0E,A6,95,48,53,8B,4F,96,3F,5E,4C,3A,B1,3E,99,88,7C,78,C6,B9,2E,87,19,27,E7,13,3C,6B,AA,AC,ED,6F,DD,5B,C8,46,8E,70,4D,79,C2,5F,D6,24,9E,54,A4,A7,00,FE,22,A5,AB,8B,B2,0F,C4,A9,7C,2F,D9,BA,9B,16,38,AD,A1,BE,D6,FA,EB,7E,72,CB,3A,1D,CC,65,38,1B,3E,16,1C,CD,E8,6C,B1,FC,1E,19,AF,E3,D9,B0,74,23,2A,9C,9D,55,91,F1,0E,2F,5F,38,78,61,EE,AF,44,EC,51,EC,EC,3A,64,72,16,11,76,AB,33,D2,D4,97,27,C1,7F,B5,85,36,E7,5D,D5,DF,4D,82,CC,5B,8B,EB,FA,53,5C,5E,5B,F5,B0,91,23,C0,AE,50,0B,88,E3,7A,D1,56,1F,3A,4E,DF,8C,A5,EB,58,77,45,ED,8C,7D,B1,53,2A,E3,70,99,5D,D4,D4,39,FD,FE,69,10,C5,8B,1C,E1,9E,F3,F4,5B,10,C9,49,6E,8F,C3,EB,00,07,B7,72,83,90,9B,35,A5,50,ED,9A,08,8A,56,B7,A7,C4,C6,16,E9,EB,81,F5,6A,14,F2,31,AE,29,D1,60,41,7A,EC,32,C2,AB,14,97,5A,36,1B,30,43,1F,3A,43,7B,1B,09,9E,8C,25,C8,D2,DA,CC,3F,03,E9,35,00,39,C7,85,CE,E8,D9,78,B0,91,6A,73,92,02,38,74,1F,1A,55,DB,CA,B3,62,D0,E2,BC,6C,D1,F0,B5,3A,8E,89,45,0C,71,9C,46,53,C6,88,5F,2B,15,66,C5,AE,AC,B2,62,C0,76,92,57,EF,0B,69,F7,89,39,7E,DA,52,7E,37,D7,00,02,33,3C,82,93,93,98,81,7D,25,17,76,18,76,A8,61,73,87,C6,23,98,94,2D,31,59,00,D9,7E,12,BA,21,C6,D9,48,59,9D,81,2D,B4,4F,AD,63,10,08,82,91,B1,F3,97,18,D5,8D,31,45,19,59,4A,1C,DB,2A,2A,10,E9,34,BE,27,FC,42,F4,33,D4,6F,F6,F9,87,E3,C5,7C,7D,05,14,5F,67,C3,F1,BE,50,DE,AA,A0,8E,A0,ED,03,73,9D,78,2F,95,1A,A7,53,BD,D7,83,93,02,95,3F,18,D4,02,AB,13,19,21,0A,C3,C7,56,CF,7C,A1,D2,94,B1,B0,2E,99,D4,0A,46,F8,84,C5,5C,81,C3,13,37,D2,03,DD,71,BE,1E,E1,D3,D8,0F,24,C1,82,4C,C3,29,0D,B8,79,D7,34,53,E8,22,85,F8,4F,8A,60,69,8D,08,3F,9E,D0,48,C3,30,5E,F6,73,85,5E,F9,BC,7E,1B,83,70,7A,8C,E7,45,CB,98,89,E3,D8,A8,04,8F,5A,5B,9D,84,5C,19,24,DE,A6,6C,BE,EB,31,8E,C1,D8,EF,0E,3F,4C,08,FC,8A,4F,24,C6,6A,98,96,A2,28,FE,9F,80,2B,2C,51,3C,6F,8C,B1,75,20,DD,52,E2,2C,0D,D1,A5,80,D1,F1,A6,EC,53,0F,54,6F,92,19,BB,9E,66,02,F5,3F,E2,7E,D2,E6,8F,49,46,08,D7,AD,ED,BE,93,02,93,DB,78,6F,45,F3,CB,7C,41,F6,1C,76,1F,4B,73,0A,B9,95,24,59,53,D2,6A,1C,8D,F6,89,DA,CB,34,04,3E,DB,29,8A,5E,09,CF,47,13,1E,45,E3,83,D3,17,7D,39,24,6A,96,67,78,15,6D,D6,FA,C9,35,8F,08,70,B5,B2,D4,50,9A,C8,88,75,EF,A8,5D,3E,FF,A9,66,33,2D,8B,DB,F0,38,0B,12,9B,1A,CB,FA,A0,63,A6,06,BC,1A,3A,EC,B1,51,AE,2E,3F,8E,37,10,99,20,BF,4A,BF,F3,E3,D4,F4,C3,0B,ED,73,3D,7B,3A,BD,3F,28,C2,28,B2,6E,D6,52,30,C5,58,51,21,BE,87,D6,BE,29,A5,12,5E,30,BF,2E,A9,53,1C,64,38,39,3A,65,9A,E3,95,A1,E3,3B,66,0D,90,38,40,9B,50,85,5D,14,C1,0D,D8,A0,71,A8,49,3C,3B,36,2C,50,E1,4A,AD,9D,C0,F5,76,B1,B4,8A,8E,EA,2A,7A,5E,FA,8A,CF,45,BA,02,B3,12,2E,3E,C6,37,8E,99,86,82,7C,F5,43,93,3A,E4,A1,BD,85,05,01,1F,14,B5,6D,46,A6,C4,A1,8C,DE,02,CB,26,B5,1E,FF,D4,C1,C3,5C,E5,46,8C,90,E2,BC,2F,BB,7C,FB,9D,3A,77,51,89,D9,88,C4,5F,53,63,80,57,67,BB,C2,4E,58,93,95,68,BF,53,CC,99,54,0B,14,67,09,D8,DA,D5,3A,A5,07,46,1C,A9,DE,1F,E1,8D,5F,88,08,19,B0,38,7D,E3,C8,58,C1,89,67,05,15,B0,DB,72,BD,F3,F2,DE,89,50,92,F8,AD,A0,F4,3D,B1,55,A4,FB,85,B3,39,B0,C4,58,3D,E2,31,E6,CF,81,78,59,27,82,C2,07,87,B8,0B,4D,BE,B4,CC,4D,5C,0B,29,73,F0,EB,69,D6,0D,EA,03,0B,5C,D9,74,A1,4A,73,9C,99,E6,7A,AA,C3,E9,A0,A3,06,00,DC,AF,99,35,F7,95,C2,BE,F6,DD,AB,7C,EB,4C,64,98,8E,DF,C4,08,7D,FE,6B,64,9A,5D,94,D8,BA,EE,35,50,EA,09,99,3F,9B,8A,D0,7B,76,65,57,11,05,7E,9C,5E,09,55,FA,CB,38,2F,DD,DC,B6,92,FA,3E,E6,A0,F3,A9,72,85,55,60,85,9B,AE,10,65,97,7C,12,64,B7,D7,2E,3B,57,D7,3E,A7,B7,B0,C4,DB,9F,42,4F,72,00,EF,07,41,12,60,4C,EE,40,FB,AE,8A,CC,7B,5B,5A,C5,1E,40,7E,E5,A3,48,8C,2D,AA,7E,6B,DA,0A,90,5D,16,1B,F9,4A,51,E0,71,19,36,6D,44,F2,C1,4B,62,CB,F2,F6,44,E2,61,FD,E6,4D,74,5C,33,AF,BF,9B,50,0A,26,E1,EA,07,62,26,E0,AB,C8,DE,FD,5C,12,62,96,D3,10,8F,19,28,0F,02,03,DB,F7,7E,99,86,94,BE,E9,2D,C1,EE,DD,62,94,5D,7A,9F,04,9D,0D,0A,0A,62,D5,96,D0,1D,6B,68,38,F9,C7,4D,0B,75,68,B0,87,BB,3A,BC,B6,65,46,6D,79,35,AB,27,8C,69,AD,70,10,30,54,5E,3E,50,56,CF,A4,2D,91,EF,41,4E,11,A6,AA,80,93,B7,26,08,4C,8D,B6,A0,74,07,7C,71,32,E4,97,3F,D0,5B,D5,97,9A,1C,F2,2C,F8,14,2A,99,09,B3,A2,AA,CC,E9,5D,CD,72,47,D9,7B,68,30,C0,6B,24,21,36,FB,AC,54,DE,AA,1F,86,1E,24,06,6F,BF,20,53,3B,7F,2D,0F,9F,B6,09,D7,78,46,8D,76,74,8B,5A,C6,57,66,8A,EB,C5,03,F2,45,85,AF,33,75,31,BE,68,FE,04,91,95,66,CC,89,B1,09,0C,AA,ED,C2,19,DD,DA,E8,DA,C1,E7,EF,99,AA,B8,C3,57,81,4A,02,ED,DE,B7,12,EC,A7,E4,1A,F6,C3,91,75,4B,9E,9A,D2,FC,D9,54,AE,4C,FD,A8,2C,94,A8,0A,50,3F,A0,A0,A1,9F,77,21,0F,9A,95,32,BA,25,21,44,88,46,55,6D,86,9F,56,FF,18,30,55,55,D0,63,12,F8,C5,50,81,A1,CE,B0,00,20,01,EA,79,1B,14,50,53,26,B6,B9,AF,AD,D1,58,5C,66,6D,24,3E,0B,52,4D,5F,E1,48,1C,2E,47,1C,AB,50,E0,8B,71,42,C0,0E,EE,40,22,1E,56,7D,B1,E3,65,D4,26,47,AC,3F,AA,55,44,99,BB,36,6C,DD,61,79,7A,A4,3C,58,03,DB,E4,8C,2C,19,18,EF,77,40,F4,4E,72,1A,02,71,2A,D8,46,0A,DD,CD,11,B0,DF,55,E2,73,05,65,98,63,9D,9C,C3,90,09,E7,F4,30,41,F2,07,13,3D,32,70,07,67,97,FB,EF,E7,71,CA,39,1D,85,08,6A,27,9F,81,D5,8A,3A,7E,F1,B0,2D,5C,C4,98,53,90,AF,48,59,F9,B7,DB,BE,69,C4,25,A0,30,7D,76,39,DD,33,CB,D8,32,A1,60,22,21,2B,2F,22,45,E5,9D,45,94,48,BB,E7,32,5E,83,ED,9E,8B,1F,D6,9B,57,D5,FF,D8,24,C9,AE,6F,4D,7E,E1,CE,48,73,BC,CF,E6,FE,64,50,D9,CE,BB,73,E5,ED,E2,6C,65,1A,B8,6B,96,4E,9E,59,6F,87,42,7E,91,2B,E1,36,D6,E3,B9,02,D8,12,5D,DB,35,81,82,EC,7F,DE,97,4F,AC,4E,72,85,58,64,34,08,5D,70,F9,27,46,90,4C,7C,FE,B7,94,04,43,97,FD,5A,B1,E2,C4,2D,66,C7,2E,44,7E,D6,F5,62,DF,D9,9C,96,28,06,E7,C7,36,83,51,FE,E9,C3,AD,01,08,97,3A,7D,F5,C2,81,4F,C9,FC,CE,B1,B1,66,A6,46,5B,C2,7F,98,E3,BD,F2,45,7D,1B,A8,57,B4,B0,41,1B,BC,1F,C7,78,C1,35,DE,36,26,A1,EA,E0,C6,A0,4A,CE,B4,BD,01,3E,24,22,5C,D4,4B,B8,6D,F2,1B,F0,24,CA,9D,09,FF,6E,7F,0E,15,09,76,BA,E1,84,82,0A,3B,31,47,A6,C0,67,7A,10,FD,41,0D,79,4D,E9,7C,8A,81,85,96,FC,91,F1,D1,39,D6,60,4A,96,68,13,64,20,AA,28,78,EB,6B,69,6F,53,B3,8F,7B,E3,37,B9,C6,39,32,E8,AD,4C,17,B7,D0,10,A4,B1,C6,10,E2,C9,CA,3D,B5,20,F1,28,65,36,39,6D,6F,16,70,FD,B0,20,A7,13,A8,B4,EB,0A,EA,30,20,52,ED,47,2D,B1,4D,70,33,E7,4C,E4,EE,16,4B,85,99,E7,A9,64,89,3E,44,B2,DA,60,C2,63,FA,A6,EA,1B,1A,CD,BD,94,FA,5B,9D,9C,E3,7A,62,23,0A,DB,79,FB,22,EF,B0,DA,34,65,C0,D7,DC,BD,21,C1,12,42,DC,07,51,39,02,22,0D,80,8C,69,49,BA,80,5F,37,61,32,DB,91,7F,A3,15,EC,0E,E8,14,86,64,92,BD,C0,D0,EC,32,42,EA,4A,B1,8A,B7,FE,E2,F2,F7,30,52,88,F8,90,1A,83,D0,D6,02,18,FE,E9,61,F7,55,0B,30,FA,8F,19,33,BD,94,FA,68,45,86,5F,9B,5E,A8,5F,EB,6C,77,50,6B,A4,A0,C8,BD,F0,74,27,58,09,94,E3,44,B8,09,26,94,B0,47,50,03,51,28,10,AC,F6,2C,D7,24,C1,9D,B3,9E,A1,94,38,A2,DD,21,39,D1,39,DA,CF,1E,69,6C,D8,45,9C,3F,97,AD,E0,1F,8B,2C,02,FA,FA,49,2C,3B,0B,02,31,25,EE,C6,87,A3,D9,5E,6B,86,E5,1E,87,F6,2E,77,CE,B1,5B,A7,29,74,3D,28,F0,8C,DF,A3,A6,66,B3,15,AC,1D,DA,A5,E0,77,39,2C,BC,45,4D,D9,0E,C8,D8,B4,7A,A2,FC,18,EE,B7,29,B3,B7,18,23,FB,2B,0A,D0,43,5A,46,29,C4,70,80,4F,A5,7C,28,B2,B3,71,0F,27,1C,57,6E,44,BE,3B,C5,90,0D,E5,AD,13,82,D0,D6,1A,C8,BA,23,B7,8D,9E,4D,0E,24,E5,A1,BF,39,60,58,93,85,5F,E6,A9,25,A4,B6,FB,C8,22,E8,A0,24,59,B8,53,7A,0F,7B,38,56,06,EE,64,9C,DB,03,E9,C4,D4,EB,A3,15,DF,C6,D2,D2,2B,D9,90,46,7B,6E,F1,60,BD,DA,11,88,DB,D5,0A,B8,6A,EE,8F,D4,D9,2D,6A,22,80,8D,62,5B,34,4D,28,6F,6C,7B,40,52,76,2A,57,45,3C,E6,1B,E5,24,C6,F3,31,13,65,3A,5E,9E,75,42,3E,53,D0,7A,8E,81,BE,3E,F8,88,F0,AB,DB,AF,80,59,CD,3A,73,33,D7,7C,44,B5,64,8B,91,52,2D,B8,9A,EC,54,8B,21,3C,4D,6E,62,23,06,3B,34,AD,A9,AE,C8,93,05,15,03,1B,D4,60,20,99,9D,8F,1D,14,FA,71,52,95,CA,82,05,CF,DC,0A,D1,85,73,3D,04,DB,B8,07,68,1D,5E,77,DA,7F,08,A3,BE,08,EB,EB,4E,B0,0F,55,4C,E6,6C,B5,9A,2B,CE,6C,72,C4,61,66,81,AF,8B,0F,F2,33,FE,E0,BB,5C,A9,CD,0C,F8,FE,95,0E,2A,D3,06,AF,20,7F,B3,73,AB,5C,4F,24,76,9F,3D,68,D4,21,D2,62,68,B0,B9,51,4B,BF,66,72,B0,0D,DD,EA,88,3D,CA,08,49,11,F6,8F,52,15,1B,04,1B,79,01,A8,AA,2E,9B,38,DA,36,F5,9B,54,FD,95,D1,58,64,4D,0F,2D,88,93,11,25,26,BD,59,7B,A1,4B,41,E1,21,33,A3,C7,85,3F,60,C0,1A,5A,10,FA,01,44,38,E4,97,EC,38,7F,74,8B,2E,5D,91,5F,A4,2C,6E,59,1D,BB,00,DC,48,2C,C5,08,30,BA,4C,F3,26,BC,F9,1D,10,A3,22,F1,06,11,86,B5,BF,18,5A,73,56,28,D1,9F,59,CB,C8,0F,3A,DC,3F,96,A4,35,49,A6,C3,88,ED,72,25,21,4A,33,E1,BF,42,B4,4D,60,BC,0F,F1,F5,9D,EA,2F,12,B2,F2,6A,31,96,C3,8B,5A,FF,6A,5F,C4,A7,B6,F1,DB,42,A3,7F,20,9E,52,D6,FB,F9,CB,F4,8A,F9,40,77,94,64,54,EE,FC,65,1D,E4,F0,8A,FB,6C,45,8C,AD,41,A1,90,4D,F3,09,57,5E,B6,B9,84,93,93,3E,8D,B5,1F,DA,0C,7B,62,04,E2,6E,BD,23,FF,22,4A,0B,B6,6F,D7,50,53,58,FC,9A,8A,50,9F,8A,4A,42,25,F9,19,95,B6,3B,9D,B7,6D,DD,80,E6,BB,B3,52,2E,6B,AA,CC,A5,E0,E2,49,67,3D,B0,67,9C,C4,C2,44,AF,C0,BD,70,20,84,49,6C,C2,42,FD,0B,31,DC,51,5D,6F,72,29,13,0F,87,AC,69,F7,BC,4F,E8,DE,BC,31,E4,D3,86,56,2D,22,E2,84,2A,C7,8F,88,A0,34,A3,29,2C,3F,27,3A,5D,B4,EF,84,46,C7,BA,C6,DF,65,AF,59,65,9A,E0,2B,24,7F,AF,4A,4B,0E,AA,92,A8,1C,25,C8,7F,F0,91,83,39,92,F8,3B,97,BD,36,EE,C5,BD,AC,27,42,93,26,43,B0,E3,0A,38,DA,6D,89,23,5F,00,D9,60,21,A1,96,A4,CE,B1,0F,83,0A,60,A8,FC,B5,B1,CD,34,E5,A6,B6,EE,07,0A,7F,C3,FE,4B,3C,35,4A,35,28,22,DC,F0,EC,D8,4F,37,64,AC,B4,3F,69,62,08,85,9C,BA,47,C7,3D,35,67,86,62,6E,F8,D2,EE,63,67,50,75,E3,A2,F8,89,B1,6C,F3,6C,DC,61,B5,9F,38,A9,70,B8,6A,B7,51,03,35,B9,81,A3,01,18,4C,82,C1,0E,96,87,BB,AC,CF,1A,0F,63,75,8A,53,24,99,9B,20,8F,B8,68,6C,62,ED,65,39,20,31,C9,C9,F6,D7,D6,B2,D8,EE,6D,5C,A1,C4,CF,E3,50,21,EC,61,94,45,AE,0C,15,DF,BA,DE,60,7C,A9,46,7E,F2,4F,D7,37,06,CF,59,5D,3A,5A,54,A2,16,4F,1C,0C,4B,F4,2B,2E,CF,B7,AF,79,78,79,D5,A6,46,66,65,02,53,47,F5,5C,7B,9E,14,D3,AF,FD,59,1A,04,09,F5,CC,B8,2C,9D,C3,36,11,70,43,F1,0C,D8,2C,18,12,E0,69,6E,AF,1C,2D,85,52,0B,83,9C,49,9C,95,DC,AA,88,02,19,8C,99,84,CD,13,03,EA,0A,E3,A5,B7,91,1D,19,17,77,DC,68,67,EF,91,23,5D,84,CA,A3,E8,0F,4D,7B,C5,72,66,9B,CB,44,6A,49,0C,3F,FD,D7,C7,1F,6E,8E,E4,91,20,29,09,C5,37,DD,4B,87,E1,D1,68,26,45,75,2C,47,E6,C5,BF,09,13,D2,18,04,0C,13,7E,69,30,02,3F,60,16,FE,81,B1,A2,DF,5C,BA,C8,79,55,D5,21,41,ED,8D,58,EC,E4,AD,1D,7C,EA,DA,70,41,95,57,7A,9E,C7,57,83,0D,A2,97,00,3A,96,FF,E5,BB,9D,F6,8D,A2,98,34,BE,02,72,6E,B6,34,3F,03,DC,7A,A8,87,80,AC,41,A6,1B,FF,56,69,BA,B9,9D,58,00,A3,A6,93,23,60,12,AD,52,1E,E6,C6,3A,13,8A,BE,FB,B8,A6,E5,AC,90,4E,A5,FD,FD,FF,2A,78,B7,8B,49,4C,4D,38,65,BF,62,D4,08,C3,14,23,86,1F,B9,76,8D,E1,3B,13,2F,F9,EB,FF,AD,32,AD,83,AD,48,C6,11,17,37,81,DA,FB,70,BC,58,AF,14,70,70,CE,7E,A4,45,05,DE,45,AE,43,8B,FC,00,60,64,07,6B,E8,DE,12,D9,14,A7,40,64,0F,08,68,A8,96,25,2B,7A,55,00,85,87,A5,08,87,F6,03,5C,86,F5,82,FA,14,3C,B6,2B,C8,0B,F9,40,6D,3D,F8,09,25,11,76,EC,7E,F0,73,99,DF,3F,C2,14,99,A3,94,7E,53,11,98,46,41,CA,B8,E0,7F,4B,4A,D8,2D,EB,18,13,19,8D,93,3B,87,B0,AB,3A,7A,69,AB,BF,E5,20,F3,6F,E2,82,3F,E6,4C,BD,BD,42,FB,55,22,AA,8E,57,48,54,FD,86,69,53,F9,A3,45,AC,45,4C,8C,00,08,B2,DF,93,DB,AD,54,F2,13,1E,4C,FA,0A,D7,EE,84,57,2A,86,69,5B,15,51,D5,69,33,5D,33,B0,EA,AA,5F,A3,AD,A6,0F,0F,4E,D7,E5,19,23,43,01,83,09,7D,58,97,6E,CC,05,0F,31,3B,73,27,F2,96,AB,9D,81,61,F9,09,63,79,BA,40,EC,A0,BF,7D,99,E3,79,D0,D5,98,91,15,A7,2C,D2,38,B9,37,82,99,15,A5,E7,FE,A4,9E,2D,E1,12,F1,93,C5,B8,2E,DC,2D,8E,76,43,CB,02,23,E5,4B,C2,CC,7D,A5,9F,29,B5,FF,EB,39,7F,66,FB,2D,8D,31,7B,60,30,1D,BD,87,90,5F,B2,4E,D9,3A,B1,87,67,CD,F7,26,69,01,98,5F,15,29,59,4E,1F,DF,A1,A2,ED,64,E1,C0,27,62,14,AE,8A,D9,B2,95,8D,28,91,5E,32,44,FD,32,3F,83,E3,33,0D,63,30,D7,5F,EA,6D,61,82,12,9C,7F,C3,76,1C,7E,DF,A5,01,4A,13,23,8E,BF,B4,A1,79,7D,73,E6,0D,7F,A0,55,32,BD,E5,6E,A7,4E,40,E3,5D,62,ED,BD,BF,D4,94,15,62,93,12,DD,A3,8B,BB,99,86,BD,69,18,E6,A2,1A,27,3F,6D,0F,E1,D9,15,AB,CD,02,76,B0,44,B6,93,2E,49,B8,C3,5D,DC,E1,54,4A,FC,A5,E2,24,F6,0F,11,E4,E1,DF,40,C4,A8,48,93,B2,8A,25,14,6E,9C,79,AC,AA,77,2C,42,AC,01,0F,F0,3A,65,04,E7,00,7A,66,65,FD,24,73,45,86,38,89,81,96,5C,31,A8,F7,51,30,8D,D2,08,FE,DD,BE,75,AB,8B,D5,90,4E,57,DC,51,1D,B1,E1,55,C4,79,02,99,4D,D0,51,61,A7,DC,A6,E4,35,14,8F,C7,62,34,B8,21,12,1F,AF,AD,CD,D9,1E,0D,58,CC,6E,B3,1D,38,20,50,3D,E8,59,61,22,50,4B,B6,A2,54,51,4B,ED,4A,E4,04,78,9A,26,B4,48,E4,17,2D,00,9F,46,8F,BE,F7,22,92,42,15,EE,6C,DE,26,29,E8,9A,FA,2E,4B,72,F6,19,D5,ED,C9,01,FA,FC,88,EF,60,62,F5,79,A3,2B,E6,35,8C,C8,44,9C,BE,24,56,77,D6,91,B1,9C,B9,7E,46,3A,77,A1,EE,67,BE,34,CC,38,11,DA,F0,03,5C,0F,E1,B8,83,51,CA,17,D7,C8,38,33,4A,C6,7D,EA,FD,FA,A2,EE,4E,80,7C,76,3E,C6,46,6F,27,49,7B,3C,32,E4,B6,B1,DF,63,E5,C6,FA,12,10,42,09,5D,8C,F2,74,EA,EE,84,1F,0E,ED,69,98,7B,6F,9A,51,2B,10,B4,87,7D,25,C0,3A,B2,71,7F,A0,FE,D0,32,02,CE,F4,C8,04,F7,7F,08,27,D2,C7,BA,08,5C,44,8F,6D,50,74,B4,61,B6,66,ED,F1,E0,AD,CD,9A,EC,8A,1A,19,50,12,62,96,05,4A,5C,43,00,53,89,37,78,88,B9,CD,CD,4F,73,D7,3D,B2,54,E5,5B,18,46,3F,54,1E,FF,84,49,36,05,24,A1,61,40,79,55,70,CF,EC,F9,AC,C5,91,E7,EC,F2,AE,0F,31,E5,3D,C1,8C,98,9C,FF,BB,F6,5C,C4,ED,E0,89,93,12,C7,5E,0A,35,73,CC,DE,86,A1,2F,95,9D,EF,D8,C8,F6,62,F3,27,1F,85,67,06,71,19,27,C9,BB,41,F6,8B,3D,B3,55,57,88,B9,0A,37,D6,6D,6F,10,75,A3,55,2F,AB,18,9D,F6,94,D2,CC,35,B7,D8,5A,E8,0C,1C,5F,C7,D1,14,94,24,DB,E3,9B,05,BC,6D,04,A1,05,5F,27,CB,1D,64,BB,3C,4F,F0,80,25,F5,46,FC,4D,33,C2,87,CB,FA,96,90,33,10,CC,59,19,8F,73,97,81,AD,24,4D,BC,2F,05,D7,F0,27,E6,04,B9,46,7C,C8,1F,A8,1C,F9,0C,5D,37,1C,B6,15,28,41,33,36,1A,12,16,CF,3A,81,02,BA,81,FB,73,EE,DF,C8,0A,F0,C4,FD,D0,C6,94,A0,EB,54,2A,BC,5E,A7,A8,D8,52,AF,37,A0,90,D4,CD,1F,29,AA,05,AB,A8,22,A2,C9,F0,AB,CE,59,DD,A7,B8,34,B9,6C,42,3B,8F,25,A8,F6,68,94,88,EA,83,45,8F,C5,A7,42,F2,58,DA,69,A0,DD,C8,6B,03,67,63,F0,00,D3,CE,83,01,79,CD,C2,F4,A7,ED,D7,1F,D8,FA,09,45,21,E5,0E,CC,EB,1D,A4,50,AD,6C,A7,4B,7D,85,9E,BA,7A,6A,24,53,5B,64,22,CA,92,E0,7F,DF,A0,C9,CA,E4,FF,C8,A9,F0,B1,8E,7C,23,61,CF,DF,14,47,82,9F,95,AF,95,70,32,D9,56,F0,87,06,82,D7,9D,04,85,38,DC,82,EA,CC,7F,55,A6,D2,89,97,0E,6D,F6,07,DB,D6,D9,F1,F5,3D,A7,C5,48,E5,52,FB,9B,E9,3F,12,C4,9D,3B,A6,3E,7B,E4,A3,86,62,FF,50,3C,90,84,87,FB,8D,01,43,B5,0F,A1,4B,3F,CB,83,B2,29,BC,22,AF,8F,F7,43,02,CD,58,0B,AF,1A,EB,14,3D,B1,A4,C4,31,38,F2,EC,49,F4,A3,41,43,61,0A,72,C2,6C,BC,B1,07,21,C7,3B,87,AE,DD,48,34,AF,8A,65,EF,D0,E8,10,CD,B1,2D,C0,F7,B7,CB,21,39,C8,32,2A,AD,26,A6,73,1E,D6,D1,54,3F,F9,F9,E7,07,58,E1,6F,1F,ED,CA,DA,82,55,83,FE,AD,B5,CB,12,85,8E,C5,E5,47,4E,C5,D3,DC,B2,41,22,39,2B,E0,68,61,3E,3A,28,14,D1,8A,38,1B,63,00,01,BB,71,03,F4,02,46,FD,45,0C,81,01,AD,34,E4,28,CF,74,EE,75,A9,33,9D,44,3E,43,3C,4D,98,94,34,02,1A,ED,4F,17,BE,13,F0,F0,FB,87,EB,EB,07,55,E3,DC,78,AA,EF,83,69,8C,3E,96,5E,CA,EC,5A,12,D1,56,E3,75,6F,3B,52,2A,F7,D2,25,2E,E4,BD,10,F9,83,41,B4,B8,44,F5,8C,9C,12,0E,12,AB,79,1B,97,7E,B4,BC,E3,EF,0B,C4,CF,04,A6,06,CB,F9,1F,16,2C,72,FB,06,91,0B,BF,73,B3,8D,C1,37,65,98,AC,4E,79,AF,6A,02,01,39,A4,90,9A,4E,E7,45,26,A1,F9,73,FE,66,BB,50,BC,71,D0,77,4F,37,DC,61,E7,52,AB,85,55,8F,E9,CA,A8,8A,96,E9,69,97,10,30,A1,2C,4B,21,5E,40,92,83,EB,9C,4F,5B,33,44,6E,DE,4C,AF,C0,4D,5B,B5,C2,6D,62,DB,3D,06,8E,CB,2B,C1,A1,79,BD,ED,EC,D4,AB,23,AA,2A,AA,6E,B4,F5,4C,7C,EA,CC,C7,85,7F,C0,0B,68,6E,9C,65,56,C2,1F,D0,13,45,25,C6,6C,D3,32,47,D2,75,45,EA,30,37,D8,DD,06,A4,8A,66,CF,DB,CF,A8,E4,06,93,02,D3,14,CC,13,63,1C,65,AF,E4,21,E0,EF,AA,F9,65,BE,53,F0,A1,B1,71,F9,A6,5F,DE,6C,D0,E1,B9,A2,C2,73,5A,76,98,09,1F,28,BE,E2,21,5D,F0,48,32,DF,AB,51,28,AC,CF,2A,27,4A,2D,FF,23,3E,0E,50,C9,5A,4F,FB,AA,9F,A0,24,F5,20,DC,03,93,27,EC,A7,E7,A2,89,09,AC,9B,C5,2D,7A,B6,DB,AF,32,90,3D,4C,6A,39,85,C1,22,75,3F,7A,14,85,E6,D9,9E,78,D3,1F,4E,F4,11,DA,59,3A,1C,20,47,0E,A2,98,59,42,AA,20,8B,B0,0C,8F,74,E9,09,A6,93,48,C1,94,62,19,6F,F2,47,8D,3C,80,D6,6A,1B,66,35,C2,74,79,B2,BC,7F,2A,09,57,F0,36,5E,E0,90,30,31,31,44,78,0D,16,92,49,3E,4D,EE,47,D2,52,FE,A6,A3,C0,5E,CA,9E,41,DE,02,3E,FB,5E,79,AB,0B,F9,60,BF,84,00,7E,1A,64,0A,7E,B2,CC,96,47,50,B9,64,E3,8E,2F,A2,1C,C1,3C,2B,2A,E8,ED,AA,BC,19,0F,EE,33,62,EC,74,5A,D8,56,B6,89,03,2F,7A,30,72,CA,B1,9C,DF,D4,3F,7E,71,23,3C,DA,B9,A2,8D,55,9A,D4,70,32,A8,13,E9,84,0E,38,59,2A,44,7C,34,C6,66,0B,C9,8A,CD,6B,B1,8B,A3,DA,D2,45,57,64,3A,B8,70,DF,D5,E1,B5,2B,24,EF,35,A6,C7,82,E0,C6,DB,0A,17,5D,85,62,41,B2,7A,EE,A2,15,FF,91,C1,0E,5F,89,B0,41,BC,45,B1,5D,26,05,74,EA,3E,AB,01,09,B6,D4,81,1D,D7,FC,DD,C9,4D,D6,A0,A8,D9,05,61,15,84,E9,A4,01,9E,E9,61,07,24,80,F5,09,87,8D,3C,87,BA,EE,60,45,A2,79,FE,0B,CB,EA,4E,09,DF,BE,B6,64,D9,49,F8,42,D1,57,CE,EE,2C,BE,DA,B5,66,07,52,EF,41,29,61,96,ED,83,60,6B,FC,9D,F0,4E,36,52,6B,E5,D0,20,2C,93,88,C8,A0,DC,0A,14,11,8C,15,16,76,68,92,9A,72,FD,B1,24,01,FB,1D,0C,6C,02,64,CC,02,93,C7,BA,6D,75,6A,37,7F,F5,D1,09,5A,52,D2,0F,AD,3F,33,3A,37,2E,CD,7A,1F,58,4E,C1,60,0B,97,E3,D6,A1,3E,29,42,DC,74,3D,6A,FE,9D,8A,6D,75,8A,19,41,62,04,52,9F,20,2E,3B,84,6D,CF,D4,CD,E6,5C,18,A9,F4,7C,53,E4,21,B4,78,B5,E3,18,3B,82,87,F8,CE,37,7A,2E,4B,5F,2B,4C,1E,EB,8A,C2,AF,08,44,C5,9B,AD,2F,39,5D,51,8B,34,5A,04,E9,5F,35,5E,C7,04,E8,8F,4A,8E,18,43,C4,0C,AE,2B,96,D5,15,44,08,60,59,47,E1,3B,20,C9,29,89,22,79,8D,98,84,8B,18,EF,42,19,28,5F,C9,6A,45,23,A9,BE,D7,8E,2A,D2,60,A7,CE,C1,E6,B0,E9,A5,2C,85,75,EF,24,B2,C3,54,F0,91,FE,01,6A,28,02,FF,69,C5,D9,9F,D0,8C,28,DA,74,6E,17,89,05,E5,5A,E2,06,B1,D3,AE,A5,8A,E9,31,4B,2B,37,1C,D1,A6,E2,4E,13,78,CA,8D,D9,67,F8,F6,9F,2C,B5,24,C4,D5,29,5B,B1,D1,EB,B3,44,AE,2D,93,1A,87,FA,5C,11,E8,F7,97,F5,FF,33,56,FB,6A,2F,19,71,45,35,81,F0,98,63,BD,6A,54,5B,24,7F,71,89,1B,BB,30,A0,35,A0,AE,49,F3,28,65,F7,D6,A7,12,76,30,ED,1C,32,C9,11,D3,EA,9C,5D,69,8F,30,31,20,29,28,8F,8D,31,6E,58,1F,0B,C4,C0,48,CB,A8,F9,06,AC,86,1E,E0,31,F6,7D,C5,01,0A,BB,D7,A0,56,F7,8F,20,B3,78,DA,E1,00,8F,C6,21,4F,1A,16,D8,E7,72,95,98,5F,CD,AB,97,C7,07,0F,8A,93,93,B3,19,42,15,18,CD,10,7F,DD,1F,80,AA,8A,F7,46,C0,5A,5A,E5,40,87,79,5C,FF,E3,7F,4D,07,C6,8E,B6,68,7D,7A,6C,04,27,AB,5C,44,2E,7E,E5,CA,95,3D,70,53,76,4A,86,5B,E9,D1,3D,30,90,32,84,13,88,6B,6D,9A,D7,85,C2,8B,D3,F0,96,22,4B,EB,41,CE,6E,74,E2,10,DA,F4,2D,8B,9D,84,02,12,B3,6B,2E,F5,81,B2,CD,A7,06,3A,EC,2A,A1,7E,8B,EB,1C,F3,F3,66,BF,CB,C6,18,BB,55,C6,7A,19,2F,F4,D1,67,DA,30,24,A9,0D,AB,1C,C1,AE,B6,73,27,B3,B7,44,5E,B0,36,47,7B,DB,7F,31,60,E8,13,0F,FD,D0,38,C9,45,55,61,3C,30,02,DB,26,E8,71,F9,58,13,4B,01,01,47,58,B3,EF,53,53,D2,73,60,8E,20,AB,57,70,49,43,1F,68,49,0E,ED,59,77,84,AB,07,70,86,3B,BD,83,CE,50,05,1E,F7,CD,6E,36,AD,E8,B7,B7,50,CE,F7,B0,4C,EB,AE,B6,9F,AF,9E,70,04,D0,9E,1B,9C,FF,A9,0F,E2,83,30,3C,CC,06,9F,C9,AA,A8,7B,27,43,B3,F9,B6,DC,05,AD,14,FF,0C,07,57,81,03,4C,7E,5F,4F,15,51,99,FC,61,3D,FC,40,43,62,F0,07,34,15,C5,0D,76,34,21,0D,87,45,2D,BF,77,A7,AE,CC,9E,6F,B3,58,2C,7C,4C,54,19,51,FF,47,5B,B9,66,F7,90,48,94,26,72,17,A0,4B,85,B0,2A,78,73,63,A2,68,87,BF,0C,24,75,A4,3E,87,85,82,FA,03,28,BC,29,DC,09,A5,34,B5,22,67,D7,DE,50,B4,6C,C3,24,53,A3,E4,37,24,55,4B,A5,AB,DD,92,5B,C5,98,E1,40,47,DC,A7,36,3B,65,53,C1,5B,6F,D6,85,4D,5C,60,DD,13,61,03,CD,BE,4E,C9,8C,49,1A,BD,BD,2E,C0,9B,70,A3,F5,B7,24,C3,02,78,3D,52,10,0D,74,49,21,0F,90,F8,72,1D,63,60,E8,EC,B2,AB,60,83,7D,C5,24,0F,73,D3,2D,4B,0F,95,B8,0A,B9,00,C8,61,6C,9B,6C,6F,0A,66,B4,80,A7,3E,9C,BA,36,FB,CE,5E,F2,F3,99,C2,30,20,82,CE,97,0C,C8,DC,E3,B7,16,F6,94,BC,C6,1F,9B,1A,30,41,E1,D5,16,39,2A,2E,06,9E,28,AE,C2,13,1D,5C,B3,F4,A7,27,59,05,11,DC,8A,07,BD,A3,BD,D7,57,FB,C6,93,D9,87,87,5E,91,64,05,4F,34,A3,F6,16,14,7F,E6,D5,E3,F0,71,AB,7E,9B,C9,F2,1E,AE,F7,61,29,01,A2,C7,AE,DA,9A,BF,3B,8B,B4,1C,41,42,B0,92,B8,AC,87,0C,8D,32,39,AD,38,E1,77,13,2A,50,4E,5C,30,97,04,AC,B2,7F,75,49,0D,A4,47,71,DF,EE,41,29,C4,59,52,1D,A6,1F,1A,24,70,62,05,D8,86,E1,2C,03,38,F7,13,72,C1,F9,39,BB,C1,43,83,47,9A,EC,17,9C,14,3F,49,33,92,3E,C1,FF,2D,6E,57,9D,03,04,CF,5A,3E,12,C9,01,BB,89,8D,15,D7,C6,38,85,2D,CB,26,DD,11,2A,36,8E,16,74,28,E4,FA,24,45,30,05,6C,4F,E3,62,82,A3,BA,D5,99,1A,D9,2A,37,17,59,C6,47,22,ED,53,E1,7E,E5,40,B9,7D,27,96,6C,E7,48,F3,70,9B,BB,5D,5C,D1,AF,8B,BA,55,AE,DF,F1,F5,52,4F,99,1C,F9,76,67,E9,16,A2,27,50,8B,2E,D7,A4,F1,FC,BC,1B,54,8D,75,00,E7,7F,1A,72,F1,5C,40,70,9B,4F,9D,FB,2B,33,42,F0,20,83,50,FD,E0,22,F8,C7,98,03,33,EB,39,EC,A8,78,7E,AB,B2,68,F2,2A,73,60,7D,A0,82,7C,3F,D5,B3,DD,65,2E,56,3D,E7,01,9F,A8,49,BA,D9,C3,C0,99,E5,0F,D4,74,E3,8F,AD,FE,78,00,1F,64,28,DB,07,F8,E2,05,B1,0F,37,AE,48,07,03,4F,7E,60,E3,60,37,19,A9,2B,86,8D,DA,CB,3B,E0,3C,AD,9C,04,FB,4E,50,E5,05,26,1A,83,6B,50,03,69,2C,18,92,44,4D,CA,5C,4B,95,EF,58,F3,BA,8B,E8,24,B9,78,6A,77,B4,09,69,42,11,00,E2,9B,D3,1A,62,27,92,CA,D8,B2,8D,E0,B1,92,0B,AE,DF,56,08,68,C4,E8,FB,E3,56,69,A9,BB,1B,2F,2B,EC,29,63,9C,22,62,84,F4,10,DE,A8,CC,1E,D9,72,AE,52,A3,DB,EC,2E,10,22,65,D7,44,5D,C6,23,78,52,B1,03,E1,B3,0B,3E,75,77,04,98,E3,8F,9B,6E,88,55,96,3B,E6,38,03,78,2B,EC,24,24,B0,E2,A9,E4,CA,C8,4C,BC,A4,98,E5,A3,09,09,C8,A4,F8,1E,D3,B8,C7,8D,EE,32,09,44,96,96,9B,B5,E9,70,3E,D7,12,3B,32,01,96,C1,D7,29,1D,25,55,21,7F,30,1B,7C,41,6C,4D,CA,1E,9E,26,4E,9D,21,47,CB,B1,47,06,06,F0,4D,94,BC,34,14,81,FF,E7,87,E9,18,31,D9,6B,73,0B,D5,C6,8D,A7,AD,EF,F9,D2,F4,70,1B,97,60,2A,96,37,02,31,98,23,B2,9A,68,B4,03,E8,DC,64,D4,4F,B9,85,E9,73,9F,26,D0,79,23,DB,61,67,E7,5D,D7,18,6E,E0,55,8F,8D,24,A0,C8,86,2D,71,55,3A,C1,B6,1A,34,AA,9F,4C,B9,26,FF,2D,09,2A,1C,32,9B,63,A5,55,39,D2,96,0B,EC,84,5E,AB,A1,5D,61,A0,1A,FB,37,7E,F5,FD,72,19,7B,83,E9,07,B2,F1,16,1C,DC,5D,66,9C,28,7C,AF,85,4A,05,EF,89,DE,F6,58,DE,0F,26,18,7D,5B,DD,C2,E2,34,2A,9A,18,F6,A1,58,30,4F,DC,8B,E9,DB,FB,5F,EB,72,9F,00,6F,EB,79,21,28,27,D2,A8,52,5B,4A,75,C4,E7,74,8A,5B,78,57,F5,27,D2,2B,13,E9,09,55,66,08,0A,E9,E0,B2,85,AD,8C,D9,90,3B,F9,67,02,20,66,92,84,5A,FD,B3,0E,20,39,F8,59,9F,4E,22,00,26,36,C8,93,A7,BE,7A,B9,1B,B5,F9,98,6F,96,CF,95,F0,14,24,48,85,63,40,41,FE,F9,3A,D2,B6,E7,5D,B5,86,91,5E,59,38,57,79,8E,A7,D5,96,66,E0,30,CD,61,CB,03,D0,DB,68,2E,15,3E,74,24,37,68,2C,75,7D,CE,24,94,5B,D5,C4,49,90,2E,74,46,D7,E3,4D,19,B3,8A,4E,E0,6C,B8,67,03,F0,58,05,F8,32,09,41,11,BD,4D,15,A1,C4,A6,5E,0E,6E,11,5F,40,B5,71,45,D9,7B,E8,4D,48,CC,FB,C5,33,E6,4D,E3,D1,7E,3E,71,D0,72,DA,35,99,45,83,5D,6F,E0,79,1A,48,C5,DA,88,E9,22,8C,D5,81,50,25,2C,6D,B9,4B,BD,5B,BD,73,4F,E0,2D,D1,4F,41,03,D9,82,E7,35,99,8B,89,61,C4,DD,FF,A9,79,BD,CB,0D,46,39,68,42,0E,A0,D9,03,91,3C,21,80,A7,4A,2E,A0,9A,9F,21,90,8B,2D,84,08,A1,5C,06,66,78,EA,83,8A,2A,1A,66,AB,38,AE,8D,62,DD,9D,65,79,CF,BE,A3,BB,93,CB,B7,CC,8E,95,91,A2,04,A2,90,B9,DF,DC,5E,E4,6A,FD,7D,C2,AF,B4,1B,D5,BA,61,10,17,71,75,ED,75,14,AE,7D,23,E6,C3,0D,D3,28,5B,21,EA,30,4B,15,7A,DE,D6,7C,75,7B,06,33,88,60,37,82,A9,6A,E3,AA,6A,F8,22,5B,BB,25,87,42,0D,2E,36,17,B3,C6,B9,0B,20,F6,46,08,83,9E,E0,8F,C5,CC,24,0D,62,F9,B4,53,B2,B8,EF,3D,E5,17,4F,DC,01,7D,09,06,FC,C2,5D,7C,F5,ED,FA,89,BC,74,EF,E1,FE,EC,77,CB,63,6B,59,ED,58,A2,B7,D1,A0,E4,2F,51,C5,7B,C1,CF,1E,0B,A2,86,88,B8,F6,DA,1E,81,13,46,72,60,2B,49,B2,B2,FD,4E,50,1A,97,F8,BC,80,D8,2F,86,89,57,C6,B0,B4,82,46,4A,E2,90,F9,49,13,FD,C2,C3,C4,C5,F9,0E,BE,5D,86,49,73,74,A6,07,5F,DA,E4,2E,5A,2A,67,BF,E6,2B,0D,93,74,50,7F,82,16,AB,A7,2A,C1,C3,3E,60,EB,96,F4,E0,BE,03,15,9D,F0,F3,D8,4E,EC,9C,EE,47,46,7C,25,42,02,26,AA,D8,1C,93,BF,DA,15,0F,80,EA,F7,DC,8F,66,3F,EA,01,36,B2,B5,71,7A,66,D9,2C,C6,24,B1,22,BD,50,33,38,F5,F8,DE,46,E0,37,B8,BE,17,FA,3A,01,61,1E,DC,4B,AA,52,F0,EC,1D,06,29,0A,C3,CB,0C,2E,33,6C,3C,5A,A0,C7,24,98,77,A7,9D,B4,52,84,DE,20,B9,D0,DF,F8,E2,3C,81,FA,A7,75,DD,85,A0,F3,F7,AB,29,08,5F,C6,53,0B,0E,B5,51,2B,82,57,DC,CD,DA,9C,17,4E,BD,47,8D,28,0D,65,CC,0C,2C,7E,8B,95,6B,01,28,6B,82,AF,DB,C6,4E,9B,09,1B,2A,72,78,11,1F,82,03,E8,59,16,9C,1B,94,46,5F,E2,E8,44,5A,E0,29,A4,CC,A3,82,23,45,66,ED,B9,50,C8,57,93,55,3C,52,5F,E4,D4,35,CB,43,D0,80,17,10,9E,FB,80,AB,83,75,72,B6,DB,B7,6D,1F,20,95,20,0D,38,18,07,18,1A,A7,3B,89,30,F3,32,35,D5,E2,E9,D0,5F,A2,04,36,A0,1E,DF,AC,D6,A3,6C,27,A5,2A,8A,6B,74,74,FF,57,DF,5F,FC,06,E3,6B,E1,0A,26,F4,CC,E9,4A,D4,FC,FA,BC,C4,62,A0,AE,A0,73,5A,EF,DE,E1,98,44,E3,72,71,AE,88,F6,92,6C,E9,92,5C,FA,B6,77,4B,75,AB,A3,04,3C,B8,BB,55,80,87,0A,36,F7,C1,3A,A7,FC,0D,20,29,D9,7B,F5,7D,30,89,14,75,13,74,18,F1,91,D9,D9,3E,61,9A,42,A2,2B,7C,D2,0C,FE,24,DA,2F,6E,56,5E,75,D7,A5,90,71,81,82,C7,69,0D,D6,1A,C9,EA,15,26,63,8B,AE,2C,D9,3A,95,18,9F,44,CE,24,9C,5F,8D,EB,8A,33,13,51,22,32,0E,67,BD,A1,86,29,D6,D8,1C,17,7D,90,5D,93,84,46,0B,15,F8,58,43,89,96,31,0B,D3,F8,97,71,BF,C0,D0,B8,F1,FF,82,CD,22,D0,DD,8F,DF,0C,BF,C5,00,E4,A6,00,33,28,C7,83,66,70,AA,06,C1,4B,DE,30,80,AF,F6,E6,40,79,5A,17,73,3A,16,8E,92,0D,6E,5E,A8,AA,6B,24,ED,BB,C8,D4,71,B1,56,D8,33,7B,CE,59,18,95,68,89,54,BA,BA,6E,C8,1A,B6,66,AF,74,20,35,B5,18,CB,83,F7,91,C8,E6,1D,8A,EF,56,57,7C,70,66,4C,CA,8A,CE,FD,11,ED,E6,EE,9C,D5,D3,65,5A,4F,CF,F3,3F,13,37,64,5A,E7,96,3E,70,F5,77,80,03,2F,DD,9B,3D,35,0E,DB,85,2C,65,49,3D,97,DD,7E,BF,59,10,91,87,DA,05,0E,19,A3,5D,22,3D,02,C8,5E,9A,93,7A,4B,AD,6E,D4,A0,20,D2,05,A6,01,EC,2B,A9,54,36,8A,32,61,DD,ED,B8,53,69,2E,DD,A1,16,86,F7,F9,F3,D1,10,92,8A,C7,21,44,F6,76,5D,1C,F8,F4,34,A3,33,50,BC,4E,3D,94,2F,55,8B,21,DC,CA,60,50,0D,AB,5B,DD,92,FD,CE,9F,1F,18,0E,46,51,AA,20,87,B7,A5,51,D7,43,59,CC,35,A3,C8,51,4A,4A,16,9C,6D,BB,92,7B,E6,85,5C,EB,6B,32,B7,9D,62,9C,15,3F,0D,02,06,CF,86,A8,2B,57,9C,6B,F9,43,2A,FE,A9,BD,45,5F,CF,69,57,A8,56,61,DD,FB,5B,FD,50,6C,1E,1E,76,F6,B5,75,25,42,F0,37,9C,95,79,6B,45,16,BB,25,D7,84,C6,5D,11,C3,39,D2,45,4F,17,B7,C5,2D,B1,69,9F,9F,8A,95,06,7E,C5,C5,A0,85,B3,E0,B8,0A,AE,EF,F0,CE,05,89,47,C1,6E,6B,A2,BC,9A,C2,E2,21,F1,8A,C9,E5,93,85,4E,18,7C,3E,A5,68,0F,00,9E,14,61,41,DB,03,D2,DE,B4,9F,AF,C6,00,14,37,BB,11,C1,59,B8,6D,0E,21,2B,60,96,CE,B7,A0,84,0C,AD,97,A4,D3,99,8B,33,3D,3A,F9,FC,6B,C0,8F,0C,C7,3D,81,87,CE,1A,5C,4E,BE,CA,B9,6F,B5,3B,1B,08,57,9D,14,2F,72,89,31,69,05,E9,FF,71,C9,46,28,5A,D6,15,FA,98,FD,FA,69,F4,D7,05,5E,14,A6,CA,FE,8C,86,E6,74,7C,C6,63,50,41,13,C7,0D,F0,79,BA,72,0D,0C,5F,D0,32,3A,5C,FB,81,A0,D7,CF,BE,E0,17,CB,D3,04,CA,46,96,01,0D,59,BD,16,2E,0C,BC,14,15,8B,72,78,C2,81,DD,DA,47,2C,76,11,D5,29,CA,96,0E,F4,A2,46,31,65,ED,C2,A4,9A,8B,DE,3D,B8,58,43,F8,B6,34,9F,A6,93,83,54,3E,FB,A0,CE,CB,EE,64,E7,E3,23,09,EB,54,F4,2E,06,DD,F5,56,04,43,6F,1B,6E,F7,B6,F8,63,A3,52,1C,1B,AF,B5,E3,11,0E,C0,D5,CE,A0,58,43,BF,90,6C,89,DE,BA,9A,28,BC,DC,89,30,39,AC,86,B4,F4,57,23,1F,19,CF,6D,96,D5,0A,0B,E5,36,EA,25,48,6D,4E,55,1F,C6,64,FD,F0,91,CF,01,80,F2,5B,5C,2E,1E,C4,4C,0E,F2,D9,89,BE,88,39,A1,3D,83,E8,39,F5,55,39,99,CD,F6,F0,2B,3A,74,B7,8E,31,4A,2C,2B,8A,D2,73,44,7D,6E,3E,7A,72,F9,C4,35,94,09,91,8C,1D,2E,26,9D,A6,A0,04,9A,B0,7A,73,F0,A9,9A,D5,15,EF,B3,D0,20,42,5C,F5,94,A7,44,46,9F,72,23,5A,96,BD,D0,D9,7F,3A,C7,EA,B9,D9,D8,C1,06,E4,6E,D7,76,C5,CF,EB,32,39,D0,37,F7,C8,7F,7C,F0,6A,68,A2,95,AC,8E,61,C1,CA,5D,65,12,4F,FA,C5,B0,56,7A,B0,97,C7,94,37,1D,4D,08,59,BD,DB,29,15,AD,F6,9F,82,BB,15,A5,7A,9A,3B,A2,38,B7,65,60,4C,4F,7F,C1,8B,2B,26,FE,7D,1C,20,AA,D9,B0,6B,55,F2,42,C7,8F,6A,2B,AE,50,3B,98,6C,AF,60,67,3C,9E,3C,6C,CD,C8,48,D7,51,13,F8,54,2A,72,79,E5,6A,75,A6,4C,60,33,EA,81,30,58,39,FE,65,DC,A0,99,6D,8B,E1,68,A7,25,5F,6F,EB,43,50,9B,14,5B,22,AB,EB,2D,66,D4,DE,53,C1,03,2E,90,AF,B3,30,C4,AB,2A,F8,4F,2A,F3,B3,4F,A7,5D,10,32,73,04,D4,79,FF,53,1E,D7,32,79,49,C8,48,3B,7A,C5,47,CD,43,47,08,C6,89,9C,9C,1D,A7,97,68,B3,80,B5,F7,96,8F,B5,47,B4,72,93,3F,F6,83,38,F6,24,AB,95,3E,2E,3D,31,A8,29,B2,6C,CE,DE,F7,34,57,B4,76,D3,2D,5D,69,DD,7F,72,BA,92,E3,C6,87,E7,47,D2,41,F7,25,4D,9C,84,CB,82,BB,CA,6E,8C,77,89,0B,7A,FD,4F,C4,3F,63,61,C6,17,88,7A,3A,ED,B4,34,CD,FA,86,54,8A,44,25,49,CD,39,37,59,0E,68,B9,6A,3E,BE,08,1D,C1,17,F7,71,BB,92,D4,E1,CD,21,79,DF,85,CE,E3,35,FE,83,9C,AF,D6,8A,BA,67,D8,41,03,EC,30,33,62,9C,0F,BB,A5,8E,4D,3E,7E,A2,F8,EA,7E,1D,A1,15,AA,DA,64,B9,DB,1E,D1,33,34,F3,5D,4F,8E,CE,F5,CD,B3,45,91,BA,18,3F,8A,8A,EC,B7,77,AA,9C,E4,24,BD,A6,79,03,ED,88,AE,BA,32,E0,6C,E2,1F,93,B0,59,E0,CE,5D,33,EA,5E,A7,41,EA,30,9D,75,CB,44,3A,48,98,8F,02,A7,C2,6C,89,80,78,B0,41,8B,44,23,15,D6,D7,9E,20,61,9F,0C,F0,EE,64,D8,A0,08,07,30,8F,2A,C4,D1,23,9A,67,32,42,D2,C2,AC,28,65,3F,A2,D3,92,FC,24,24,4E,49,5B,6C,A9,58,04,A5,24,4B,46,7B,4B,D3,ED,AC,CB,AE,C5,5D,FA,75,8E,B8,D4,3C,46,0A,A0,B8,15,F3,53,BF,C2,67,83,58,11,8C,A0,33,EF,6F,2A,23,F5,FE,DA,A0,A3,F2,8E,AD,2C,70,14,A5,49,83,2C,1E,F9,C7,6E,E9,FD,D5,64,E5,D7,79,1A,58,85,86,3B,15,82,5C,61,37,08,8D,95,EE,BA,04,5E,A5,E8,94,32,39,6D,F3,5C,79,55,49,7D,67,67,91,A8,FB,05,06,00,92,A9,02,93,92,03,D3,B7,AD,CA,A1,80,CA,AD,57,2F,56,D3,63,46,4D,72,ED,F0,0F,47,59,28,BD,A6,9B,95,8F,A5,E3,BC,42,A1,E7,BE,F1,9B,A2,01,5F,BE,88,7D,F1,8C,AA,B4,63,7B,40,83,B0,85,0E,3A,58,71,09,17,8D,4D,6F,EB,19,36,B4,71,9C,2E,A4,DE,BE,6A,47,4C,F7,AE,B7,93,3A,ED,8A,FF,35,DD,7A,A3,40,1C,7C,2D,1E,97,4B,31,04,FA,53,28,7A,54,08,46,71,6A,23,F6,88,B9,FB,8D,F2,1A,CD,B7,E7,DA,21,A4,99,4C,77,BF,F8,19,61,D0,5B,E0,B0,5C,3A,9E,15,8F,AD,58,CA,93,59,A8,79,F0,2A,1E,89,B3,21,64,68,73,99,AA,08,51,73,A1,D0,1A,14,42,FD,0D,EC,42,23,32,A6,C5,7A,C2,CC,6C,A0,1E,46,0A,82,47,11,54,60,7A,E2,08,99,01,B1,B3,40,68,D9,44,EF,B0,7F,A2,E6,79,6C,F5,AE,6C,8D,66,F6,10,E8,B5,51,B2,BD,42,95,94,E9,45,7B,61,46,87,1C,30,12,3F,BC,3E,69,A7,90,52,99,A3,EA,EA,78,4F,A9,86,67,4F,41,1A,AA,B9,26,39,12,96,32,9C,50,61,F3,68,90,DD,38,CA,74,C1,B6,C7,31,EA,D3,53,60,AD,4C,F0,CA,3E,0E,31,9C,D3,C7,31,9F,2A,8F,D7,34,A6,8A,0B,4C,05,7E,5E,40,73,47,08,D4,CF,1F,26,CF,3B,B5,75,61,E3,98,21,95,8B,3B,1D,82,08,53,C9,85,93,2B,96,B9,DF,7A,CF,C2,68,C0,84,3C,30,71,3C,39,53,F8,87,1A,76,45,24,8C,E2,56,56,1F,07,D6,47,B2,CB,BE,9C,26,29,7F,66,16,88,8D,A9,0C,AA,4E,7A,01,BC,53,BA,F6,1F,8E,AF,59,87,1E,B6,EE,99,B3,C8,38,E6,6B,E0,84,7F,38,38,F4,AA,D0,9A,4B,77,15,C4,99,73,A9,23,9A,7A,63,D4,F3,CF,76,D7,49,CA,F4,AC,65,99,DB,71,B4,9A,60,CC,57,9C,5E,1C,A3,A4,0A,12,16,1A,0C,AA,EA,15,1D,1F,06,7A,BD,36,3B,33,9A,94,AA,C8,95,4C,AD,7F,C4,19,72,B1,38,8E,24,A6,60,9D,71,17,2B,ED,15,D6,A3,D0,9E,65,7F,66,27,5E,58,1A,0E,4C,A9,EF,4F,1F,7D,47,75,1B,84,2B,B6,93,79,BC,3D,70,31,23,83,37,A0,FD,AE,54,32,25,C3,26,C4,45,B6,9E,C3,42,F8,09,2B,8C,9A,1D,79,85,68,51,A5,CC,10,3A,99,FF,85,C2,1F,A4,55,4C,FA,58,08,CC,BF,31,9C,6D,57,C0,CA,F1,FA,59,EA,05,25,EB,CC,0D,FC,97,A1,35,6C,0A,F3,50,17,2A,69,56,9F,AA,E1,BB,EE,27,EE,32,3D,CD,15,F9,07,AD,60,6C,96,69,9D,FA,39,67,C9,AE,11,B9,15,D0,32,12,21,FF,0B,F4,D6,09,DB,00,18,7F,40,A7,B0,FC,E3,1D,6D,BD,1D,BF,E0,35,92,50,4A,9D,25,63,3B,64,34,12,41,85,6B,25,D7,DF,3F,73,C6,69,7F,94,49,FC,15,EB,E1,74,5B,2A,86,83,37,03,43,E5,46,E2,70,78,3F,E0,7C,33,2C,39,2B,8E,76,F1,5D,5C,7A,34,C3,15,20,DE,CB,B5,6A,21,F1,EA,F1,24,99,D7,57,B6,DF,B2,63,00,ED,77,3E,E4,D7,AA,CE,91,92,09,8D,DA,72,CE,33,69,B3,9D,E4,0C,D3,D9,48,7C,22,FF,BA,9D,65,0E,51,AB,DD,AB,20,F9,3C,1A,5D,96,16,E5,52,75,67,33,F5,BC,99,81,28,2E,E1,40,7C,E0,E6,44,A2,B8,72,5B,65,87,9E,5A,20,BE,40,6A,EA,81,53,E8,29,94,2B,7B,4D,A3,AD,EC,D1,20,8D,7D,B9,2C,04,30,44,51,E4,2A,48,C8,98,2A,08,A7,6D,24,FB,3E,2F,A2,CB,50,CF,D4,4D,48,80,06,E2,D2,5C,4C,8C,F9,99,3B,96,0E,9F,61,63,C4,30,FD,05,D5,5F,B1,5A,27,D7,41,9C,03,3A,C4,9A,91,EA,F6,01,85,92,F4,94,37,AD,2F,AC,55,20,7F,8A,2E,14,17,15,0F,ED,36,A0,29,3D,A0,FD,76,2B,EA,08,17,F8,DD,63,F4,6D,1E,9E,24,A3,CC,9C,BB,40,AB,F1,C9,CC,9D,C5,7C,3B,9D,F2,87,79,72,4A,6C,7D,4A,AD,0C,26,5D,E6,25,8C,13,62,49,5E,58,CD,D1,5A,AD,41,9E,03,A2,20,AD,86,33,1E,57,A0,7D,3B,C9,DC,00,D2,10,CF,4E,B3,19,F4,5F,DB,03,CE,4F,54,10,1A,B1,2D,71,8E,03,41,42,78,86,97,14,65,00,21,7F,DE,8B,C1,B3,DD,2B,4F,BB,66,0E,FB,47,F0,8E,1A,0C,E3,F7,14,1E,2E,0A,A1,4B,46,CA,F1,A2,CF,C7,DC,A6,18,B3,49,05,48,6C,38,A0,D5,F4,BD,EF,4F,C0,0B,AC,7F,92,BA,D5,F6,82,E1,B4,25,2B,56,59,68,84,55,12,B2,05,CD,B3,BD,10,AD,CB,9C,7A,07,8F,1C,1E,38,00,04,07,B5,F5,7B,87,7E,45,21,08,9A,70,53,53,DF,D4,D3,A3,8B,A9,F8,8A,08,6E,08,81,74,EF,B6,EC,18,BB,8D,C1,42,99,91,0F,B8,94,C0,B9,3E,D1,20,63,82,3E,14,9F,70,30,74,D2,C1,E8,D5,E4,F3,C3,ED,58,37,9F,F3,12,FA,3B,F0,20,93,B2,6D,25,E9,F9,0E,F2,30,CA,A4,03,74,8B,D1,12,BE,3F,EC,03,96,30,8B,8A,3A,B9,3C,DC,C3,46,48,53,F7,43,C1,DA,48,9A,CB,10,CD,9F,82,3B,83,E6,83,C0,1F,13,F4,D8,A7,ED,06,9E,82,4C,11,79,DA,F0,26,F8,BA,7E,8B,8D,AC,9B,1C,E3,B0,81,EA,F1,14,D8,27,0A,EF,2D,19,FE,6D,81,9C,68,AE,AF,D0,4D,F5,2F,D0,81,56,89,28,67,57,F5,3E,61,77,D4,03,EB,75,28,0F,E2,FE,17,E9,C4,EE,67,A8,11,15,83,54,14,41,6D,9C,FF,B3,76,18,85,D3,84,55,FD,0F,56,3B,FF,DE,5E,5E,60,E2,8A,D3,5E,23,08,A6,56,F5,83,93,27,95,6B,0D,11,B7,DA,95,94,10,FE,1D,72,62,D5,8B,91,65,A2,B1,82,29,D0,18,94,A6,CA,64,AF,10,AA,FF,B7,41,94,D3,4C,F3,5E,E3,39,D0,C2,F7,07,7F,BF,F5,47,1C,1D,15,32,CE,68,D7,EC,BE,42,78,29,BF,3C,B7,0C,C5,EB,FC,F8,AC,A7,43,F5,A1,7E,BD,80,12,BD,4F,F3,11,57,73,31,74,D9,86,39,4D,11,86,FC,FA,2F,21,D3,B1,40,68,9E,32,D7,72,EA,A2,6E,75,C5,88,00,7A,3F,18,89,14,50,BE,BE,7D,18,27,80,35,F8,B4,8E,11,AE,78,3B,B1,BA,D5,34,FC,84,F2,9C,6E,3A,1A,06,07,51,DD,A5,7D,27,22,2E,E6,94,2C,E4,7C,FE,62,B0,FE,0D,49,0C,C5,7E,82,3D,28,08,B1,FD,06,FE,8D,46,15,24,81,08,1A,D6,28,E1,D4,B9,F0,AB,33,BA,FA,FB,58,57,77,BF,0A,5D,AC,90,8D,77,9C,64,CD,F7,07,9E,21,98,DC,B1,D4,EA,58,B1,F7,67,91,DA,BE,1E,5F,A0,B7,41,FC,31,78,F0,F3,F0,73,15,C1,B6,10,FF,08,55,B8,5F,1E,4B,00,31,DE,E9,A3,E1,CF,E1,4F,C8,52,02,9B,20,4C,47,CD,6C,34,1E,AF,82,96,D1,61,38,F1,BC,5E,06,94,25,F8,67,CA,7A,11,6D,99,BE,B8,BC,80,93,61,19,F2,06,F3,75,B8,0A,B9,78,69,2F,88,9B,61,52,5C,4F,66,13,66,0D,CF,21,72,02,DA,21,D9,67,56,3F,A5,24,F3,00,17,A9,B9,18,13,30,52,94,80,AE,75,EB,37,57,06,1A,9D,F5,B5,37,50,12,70,76,1A,15,4B,30,9E,3C,20,8C,F9,5E,9E,F1,9E,44,DE,50,4C,40,FA,33,C0,79,5F,52,72,D9,A3,71,2A,7F,B8,34,D9,24,94,E0,6A,82,71,8B,68,5A,02,F2,DE,E1,68,C2,35,DA,0A,41,83,5D,35,B5,F9,B6,8D,82,F9,82,56,C1,2C,65,D9,49,83,87,EF,39,EE,FC,04,DB,D0,9A,9C,6B,E6,C6,64,4A,4F,C7,35,0D,4B,1A,73,07,36,23,D5,07,72,88,E9,B3,B9,7A,7F,19,82,9E,CE,BE,4B,97,EA,36,D6,CB,30,8C,7B,83,26,6B,84,33,D2,7A,3E,0C,65,C8,6E,75,D4,AF,6F,08,41,BC,EF,2F,58,A0,6F,BE,67,93,79,D1,CC,57,73,F6,15,F0,8F,D8,65,54,34,9A,F7,60,8A,00,6C,1F,B3,8E,10,4E,AF,F2,97,1B,8B,19,D0,B5,E3,CF,E1,28,7C,5A,9C,03,C1,11,5C,49,A0,10,69,7A,70,86,BA,AE,63,01,78,AA,B4,4C,95,29,05,48,36,27,58,E9,27,30,CC,C9,9E,E4,35,1F,4B,7B,F3,6D,C1,B1,12,64,36,1D,B8,C0,76,14,86,A6,59,4A,1C,91,E7,CC,D0,34,F2,9C,E6,5E,F3,E2,5E,81,8F,48,2F,B4,8A,34,11,8E,A7,69,CB,35,F0,6B,4B,9F,46,33,D9,75,15,BB,44,70,00,29,51,9B,BF,FE,2C,9A,2B,CD,00,4B,B3,CB,0F,3E,9C,69,2F,EC,B3,9A,F0,98,65,D0,1B,A6,AF,B6,77,D8,C5,7D,CA,20,06,E1,6B,F0,07,33,CB,03,13,7C,30,90,4D,E5,98,06,2B,9E,4B,F3,A3,1E,9B,52,02,20,EB,C7,9C,88,38,32,8F,22,62,6E,D1,44,D3,B0,8F,FB,FE,4E,F3,9D,67,98,D0,BF,9E,B9,2B,D5,BF,96,AF,5E,B4,75,A0,D2,FE,F8,DA,6E,D5,75,E5,50,70,DC,89,A9,BA,8C,2B,42,74,78,95,C9,64,5E,CE,23,DE,BF,16,5D,11,CA,AD,3D,5D,AF,46,1A,4C,50,EF,5C,74,6C,98,2A,C5,4B,D2,71,35,AD,E0,09,B9,DF,A0,1E,76,7D,7A,29,88,DA,74,D6,4A,C6,A6,61,58,C2,1F,91,14,37,7D,AE,34,3B,FD,9A,6A,7B,5D,10,E1,C2,6A,20,91,BF,14,06,4B,D3,61,E8,88,77,E1,06,07,CB,6E,CD,10,23,CD,E4,EE,0D,55,5A,50,ED,BC,80,D7,BB,1B,CF,5B,96,90,40,F4,1C,B7,D4,AE,D0,DC,2E,8E,A2,34,6B,B7,D5,84,E8,5E,55,29,FB,5A,CF,58,DD,9A,C8,ED,46,99,39,6D,C6,29,79,D2,20,CA,E6,09,10,B3,84,5F,B4,26,B7,47,63,64,0D,05,6E,35,24,A2,38,CB,D1,9B,06,67,F4,6B,0C,CC,07,EF,4D,C8,79,CC,46,74,0A,3D,BA,82,A1,05,CB,4C,B9,79,77,BF,44,C6,7B,5C,33,BF,C1,61,99,9D,76,B9,1F,66,22,63,05,62,8A,84,B9,B6,53,59,07,E3,C6,5B,3B,41,CE,48,5A,BB,3E,00,82,77,DF,76,2D,FB,68,98,F2,E3,B6,AE,27,27,13,79,BC,03,03,C4,98,80,B3,9D,1D,C3,25,17,8E,E7,19,D0,61,A9,BC,A0,15,74,E0,AE,7F,BC,5A,8E,A6,D6,B9,79,EF,32,3B,47,6C,AF,CD,0E,CE,1C,4E,A7,9E,25,0B,A3,1D,A3,94,08,80,B1,2F,4A,30,D0,61,8B,40,A3,AF,BE,51,E3,7C,DC,0D,11,F1,6B,66,E3,DE,18,A4,E9,A0,D2,35,F5,34,73,F9,05,84,C7,7F,DD,71,38,25,0A,80,EF,B8,B3,ED,D2,D3,DB,C4,7B,AC,A0,54,77,4B,01,AF,04,6B,50,43,E1,F2,70,00,45,D6,B3,2F,74,28,54,16,82,E4,95,C2,1D,D8,0F,8F,53,20,4B,2B,86,39,8E,38,6B,2A,0F,81,AE,C8,2F,9A,F3,E2,E5,D5,2E,2D,45,0A,15,F3,2C,E1,7F,9B,AF,4C,7D,FD,89,F1,71,7C,94,CA,5A,13,52,E7,2F,18,F8,C9,0F,D9,0F,2E,67,8C,CE,1E,1C,15,C6,C9,7B,82,D4,C9,3E,C9,15,EE,3E,6A,1C,A5,97,72,81,9C,92,E2,84,E5,BF,16,55,29,69,06,7C,11,FB,38,D8,4E,F7,F8,92,2D,14,91,89,10,4E,4C,1A,2C,28,94,9A,C6,C6,AB,CE,5B,B0,15,A8,48,58,9D,58,CF,D3,72,CB,30,35,63,63,E4,73,63,21,73,D7,E0,43,45,E8,1B,97,53,A1,72,59,AE,00,BC,50,B7,60,FA,7F,CE,B2,B8,96,21,1A,B0,B1,41,A0,66,B1,9A,CF,7B,BD,43,1D,E3,32,0D,FD,08,93,2C,2A,2A,3B,BB,16,50,FF,56,73,E4,18,F7,49,10,72,20,EE,41,A6,F8,8B,FD,64,EA,F9,AB,56,53,81,33,66,B1,91,CB,EE,9F,68,BA,EB,14,FE,58,8F,7D,B9,8D,DF,78,A4,4B,11,C4,C7,D9,B1,ED,4E,47,85,CE,40,26,0B,C6,F4,E6,FE,8B,38,19,54,FB,85,6A,AC,64,E6,B4,35,C8,51,9A,4B,59,53,B7,8E,E4,1D,77,43,DD,C3,E8,9A,8A,F3,F3,C2,16,E3,E7,1A,99,57,70,04,36,98,84,1D,96,4D,90,ED,69,37,CD,01,49,47,8D,09,6C,22,00,D9,7C,86,F7,FE,5D,35,3E,0E,F5,5B,55,94,61,79,5A,06,CE,74,61,95,6A,2F,3D,1A,B7,E4,1E,7B,2F,78,40,DE,37,B7,64,16,0B,8A,90,6F,2F,75,69,1A,99,E8,2D,11,E8,10,E1,EE,B4,F6,80,7B,7C,FC,65,FC,CF,3B,A8,00,23,55,04,1E,34,66,F4,74,CC,A0,C9,D2,4D,89,51,65,46,4A,A4,0B,11,9B,A7,C5,AE,F2,2D,03,B7,47,D2,03,17,3B,6B,DE,1F,60,3C,4B,DF,BC,E3,D2,1B,A5,8B,1A,60,7D,53,84,76,E1,80,30,A4,EB,B1,F4,4C,51,B2,22,D0,64,F0,CB,F7,2D,22,EC,B5,E5,AF,80,BE,4F,BB,84,85,CE,AF,81,8A,B1,AA,3C,72,8D,B9,F7,28,1C,E8,A2,11,D9,0B,BB,92,FB,0C,60,A5,11,02,42,35,A7,38,C0,4E,10,27,CB,A5,65,1C,C4,76,8C,99,D6,01,3B,E2,84,BB,53,9C,5D,4E,0E,E9,5A,5D,EF,2F,EB,D9,1C,36,6A,16,B7,57,F4,DA,0C,B1,E0,C5,D6,A3,02,DE,6D,64,92,27,16,82,59,F0,F0,80,AA,30,BB,1B,A7,D0,D5,C6,4D,D8,0B,A7,9B,EA,97,28,52,87,A5,D2,03,7C,81,55,25,22,B7,4C,C1,44,77,41,37,76,4C,B6,33,28,C7,3C,34,47,39,F5,06,16,30,9D,9A,4D,8C,C3,DF,77,16,F7,AD,8A,54,73,33,09,16,1A,B6,6D,83,54,D5,5B,6B,D8,A4,EC,C0,F7,27,2A,AC,6D,1F,8B,4B,8D,E0,5B,A0,D6,E4,F0,8B,4A,4B,89,F2,8F,6D,90,8E,FA,B9,C2,D0,76,A4,2B,08,DC,9A,E2,F6,9D,78,05,82,6C,41,AA,6B,2B,B3,EC,CD,FB,48,E6,A7,8A,32,1A,54,8F,91,78,6A,CB,F9,59,A1,C1,47,73,56,39,24,CE,BA,6D,E0,88,44,27,F0,31,A7,A6,98,03,AE,27,35,36,01,7D,0E,9D,92,CB,57,C1,C4,01,71,64,23,E3,66,9F,67,56,07,69,BD,F5,FB,52,F9,F9,9B,A6,65,63,2D,DA,53,48,BC,68,C2,12,24,D5,D3,A6,F7,76,35,BB,15,24,B0,22,49,65,6E,48,BC,0F,30,7E,40,EC,5D,B8,D4,68,B6,37,16,5A,C0,53,35,42,C1,CD,CD,D1,3E,0D,1F,C8,2E,EB,F8,04,D1,E8,D9,49,23,ED,55,F5,29,91,CE,43,BF,25,C0,49,5C,B2,1D,A8,38,FE,0A,BE,E9,78,32,A6,9A,9B,EF,82,42,3B,51,76,37,6F,16,B5,20,10,AC,B0,78,89,DC,77,27,70,AD,8C,89,A5,9A,5C,1B,D5,5D,3A,19,F8,7D,2B,95,0F,41,82,A7,6D,15,1B,A1,2E,2B,5F,73,ED,6F,24,E2,10,BC,69,49,98,8C,11,57,13,78,EC,A3,31,3D,49,91,07,8C,61,27,9F,BD,B8,52,1B,2E,E7,FA,E1,0E,B8,24,36,E7,99,A4,80,D4,5A,FC,BA,95,97,1F,76,7B,3C,EE,06,E7,F6,A8,6D,C6,1E,D2,D1,B0,34,34,2D,CF,31,77,65,F3,44,1D,BA,69,7A,59,6F,4D,E6,85,F9,27,FF,44,7B,FE,08,03,10,43,27,6D,C3,D3,DC,F3,E0,61,9C,F4,FE,E3,D7,96,CB,A7,AD,8A,1B,58,B1,15,08,80,3A,14,04,25,6D,DC,CC,1D,33,A5,94,68,CF,09,03,6A,83,CF,96,9A,28,62,8D,73,79,4E,FE,F1,5F,A9,C6,06,11,7E,C7,C8,B7,B5,10,A1,F6,4C,67,46,B7,01,08,D3,D2,75,F6,0D,2A,DA,96,03,A7,62,B1,6F,49,0A,0D,BB,99,15,7A,20,53,11,15,6F,0F,BC,F4,2E,E5,E3,F0,E1,4C,F0,42,28,3C,5C,EC,96,66,33,5E,E5,CC,EC,FC,72,BA,DB,68,8B,FE,B6,76,D8,12,FF,48,41,DB,6B,58,35,06,4C,CA,81,32,30,DF,A9,C8,74,49,1C,E4,E9,75,87,73,8E,3E,5B,0C,08,E4,B1,DC,1A,46,F4,91,96,65,00,FD,F7,56,73,83,B0,F8,4C,E8,DC,0B,9E,26,34,09,23,9E,9D,8C,42,34,40,84,DA,3C,21,07,26,2B,2A,0E,C5,54,E1,AC,17,D4,F3,19,62,3A,4B,0A,1E,F1,EB,72,C6,C0,11,A3,39,59,90,6C,50,E1,8D,93,54,F5,78,8C,B5,EC,17,1F,6B,4C,92,90,14,46,79,62,1C,3F,B5,17,5D,0C,49,3C,5D,8B,97,17,23,84,41,B2,A0,E9,94,94,7A,A8,EF,15,27,89,E3,7C,B2,56,B3,28,57,FC,0E,B5,DA,55,19,EB,0B,2A,49,95,55,15,3C,2B,EC,4E,E3,12,74,D4,E4,77,5B,11,C7,37,D7,88,72,C7,61,8F,85,5C,14,87,CF,10,6E,6B,C8,FF,C5,B6,4D,BA,37,34,23,AA,64,3E,D5,72,CD,F0,23,EB,84,26,74,83,B2,E3,B4,E3,7E,5F,58,0F,16,23,85,A7,F3,3E,BD,7F,68,45,5C,29,D0,FE,BB,5B,DE,D5,34,E0,45,5F,4D,CD,91,92,CB,ED,98,45,07,84,18,72,95,41,1E,91,AC,DF,09,A7,6F,14,77,07,9E,2D,DD,F3,20,F4,07,19,6D,70,D9,8B,58,08,F6,7F,CC,CD,08,D4,0D,66,90,F8,BC,55,AD,6C,2D,99,39,42,41,10,8F,6B,D2,13,73,19,51,95,5E,D8,1B,34,CA,28,1B,0A,A6,02,E9,56,79,27,86,41,D8,BB,50,03,CA,5F,A7,DB,0D,4D,E9,EC,CB,A7,38,34,43,B3,A7,93,13,B8,96,EE,DB,C0,E2,1C,89,B3,BF,F0,AD,1F,6F,FC,BB,BA,7C,93,25,DB,57,DB,A3,D4,E1,51,5A,AF,68,E2,1D,09,88,D7,5B,50,1C,D0,D6,91,38,05,84,36,86,76,6B,CA,1B,E7,8C,C3,A8,A4,1F,F7,B7,56,8F,50,6F,17,C8,62,F6,3F,10,D8,7D,10,1E,89,90,CA,4E,0B,D5,C3,1E,4D,0F,60,E2,75,9E,7B,D6,24,42,2C,38,FC,BA,62,43,0D,7E,2A,2F,7A,2F,D5,D2,73,33,40,A5,96,C1,B8,B6,84,BA,05,4E,B3,01,AC,D8,90,72,A5,C4,D9,BA,4F,A8,62,7B,C6,6A,90,7F,5A,4B,10,DE,AE,2B,F9,A5,8B,3F,CB,F2,90,76,01,9D,7E,EE,E6,B2,DF,18,00,0B,EA,D3,2E,33,4D,51,0D,93,38,E5,73,9A,B3,1A,B1,B0,E1,F7,12,78,B9,F0,AD,1E,CD,19,0D,04,7D,B5,EF,14,BC,80,68,29,22,84,06,C3,CE,E4,F3,19,D2,46,08,2F,9E,F1,38,DB,F5,07,DA,8E,6D,18,D2,C0,7F,C6,BB,C7,3C,3F,E3,99,D8,7A,31,41,88,A5,E8,4A,D1,F8,83,75,7C,19,7E,F4,3B,92,89,3E,AA,7E,B0,C6,F9,FA,AB,5C,A1,7A,DD,8F,7B,26,4B,19,26,1D,EF,9A,23,4B,A1,B1,55,8B,FD,94,54,0C,AC,20,CC,19,FD,BF,4F,86,F0,CC,C6,C0,2D,57,9A,E1,E6,F8,C1,FF,AC,98,55,BE,1D,BB,B9,18,73,87,9E,B5,95,CC,B3,6F,10,70,13,21,FF,F9,AC,23,4D,52,3E,43,DB,C0,14,4B,2E,39,AF,45,03,C0,8A,C7,49,92,33,9B,53,1D,5E,E2,21,E5,D1,30,17,EB,BD,F6,48,35,51,1B,64,86,FF,D1,CB,50,9B,02,1F,8C,E7,D5,0F,4E,06,22,5A,DE,AB,8F,68,85,42,84,5F,2E,B2,55,03,81,01,1E,B6,61,2A,20,2D,DC,5C,98,2B,78,41,09,8D,94,99,3D,C6,B3,43,B1,BF,ED,0D,FA,11,99,B1,CE,AC,EC,46,F9,D9,7B,47,0D,86,D9,48,BD,92,99,5D,74,90,17,14,C1,9D,87,08,3A,2A,E6,8F,14,16,75,D0,A6,DC,2E,99,F3,54,7D,6C,2E,EC,25,C2,B9,C8,EF,C3,C7,5B,76,FA,5E,17,BA,73,78,F9,DF,49,6C,60,06,4C,B6,64,40,DB,1E,AE,62,CF,22,D8,85,36,E2,23,7B,49,79,59,98,CB,C1,58,C0,BB,C2,C0,C0,F3,6C,2F,F5,A9,19,98,C5,C1,3D,08,DE,82,A5,BD,67,3E,6E,C3,89,44,87,1A,51,EE,82,63,20,19,A5,D1,E5,61,3F,57,EB,05,5F,16,8B,C3,89,95,8F,08,6C,0D,4B,18,B9,B8,90,24,1E,A1,A7,A4,8F,95,FF,53,62,5B,9E,DA,36,64,6F,A5,F7,F8,22,DF,3D,46,B0,5D,6D,2E,27,C4,8A,D7,04,F7,FB,EE,E0,65,C3,F6,A2,81,0D,E1,07,48,5E,DF,04,48,FB,1D,4D,87,6A,48,09,2E,8D,56,D9,81,AD,EE,D5,94,B3,19,66,6B,85,E3,DD,9A,B7,A6,B1,6F,92,B6,23,CB,F7,FF,02,03,EE,83,6A,40,EF,4E,24,A6,41,16,50,0A,DE,A3,44,FB,1F,BB,AD,3C,32,47,77,C5,15,49,7F,7C,21,42,A3,95,C7,C0,D1,A7,E0,34,B1,49,2F,F1,12,20,28,E4,7C,61,F9,8C,9E,20,6C,5A,EA,A0,CD,38,80,CF,D1,86,74,0C,36,E6,5E,7B,97,73,06,97,D0,AC,11,D4,06,56,3E,15,AF,24,AC,38,F1,3C,CC,77,7C,3A,E6,19,38,5D,04,24,30,1F,A8,48,68,83,F9,A9,CF,3B,1B,52,D8,BB,C7,76,51,B4,8F,25,9B,C9,F7,49,57,95,75,9B,E8,FD,30,E6,4F,C4,44,BA,C0,FF,5E,BD,25,17,D5,32,D5,1D,1B,89,3E,C9,78,DD,03,4B,73,B7,9B,96,3F,86,8C,AA,DA,82,8A,50,D4,39,23,12,34,B4,52,5D,DF,09,02,45,A6,1E,29,63,41,05,CB,79,E5,11,B2,B1,32,DD,41,4D,4B,99,F4,FD,CF,3B,C5,96,23,28,D9,33,F6,82,CA,75,0F,B6,28,B7,A6,78,F9,2E,4A,37,F8,D9,C2,93,05,E5,BF,CE,E2,8D,75,11,31,D4,98,FB,D0,75,D8,6A,B8,B8,BC,0A,9A,05,B4,19,76,23,DA,0B,EE,45,D8,EB,F1,7F,BA,22,9E,1F,B2,29,4B,94,61,63,7F,7D,6E,90,2A,C1,C7,0A,15,44,3C,01,B4,25,26,D6,36,D7,83,2A,0B,F1,14,61,BF,DA,35,BA,A2,67,1D,C4,61,1F,C5,73,4C,DA,56,14,48,AF,7B,6F,2F,4C,92,D4,14,E6,C4,C5,15,0C,C0,64,66,DB,E2,45,F4,A8,75,AB,42,6A,90,50,6D,EE,CF,DD,99,FA,DA,B3,69,CD,32,B1,E9,96,C8,67,EC,89,64,58,A1,B6,72,77,D7,69,33,0F,96,4A,97,16,A3,1F,6F,E9,2D,F2,8A,E0,66,BD,F5,91,62,C4,6A,34,55,00,2B,18,07,55,CD,4E,7E,37,B7,51,AC,B6,CF,22,1D,BB,03,81,A1,52,52,A6,BD,17,0D,ED,86,5E,7B,EF,1E,95,17,B3,65,0F,08,C3,18,7A,86,3B,D2,8B,45,CD,69,5A,7E,05,82,6A,C4,C2,04,1F,1B,AA,42,D1,71,5D,E4,5B,E4,C9,E3,88,EF,2C,E6,6C,3C,AC,5E,7D,B7,EB,1D,D0,99,A4,CB,97,60,1B,73,4C,D9,39,43,DA,A7,E1,82,1D,99,57,E3,67,B9,84,17,43,79,95,F6,4E,40,62,8C,07,CF,A8,5F,E1,B0,85,D5,63,39,59,96,77,E9,6B,FC,2B,40,6F,3E,EA,E8,03,DD,4A,9C,78,A8,19,01,C1,2E,67,D1,65,18,06,0A,64,71,54,38,85,EE,29,01,44,1A,97,9A,F6,5B,F1,63,76,63,E1,2A,74,8D,4A,6B,F0,6D,A7,DB,62,1C,7E,60,57,3B,F7,98,7E,30,89,06,74,06,58,C4,0C,5A,D1,16,5A,9D,62,7B,7C,BB,AC,AB,A7,A2,30,47,51,C0,D0,B3,9E,99,00,72,67,7F,FC,F7,14,8F,46,0E,ED,D6,F9,B3,4D,17,28,C3,D8,FA,30,11,25,DD,45,24,D8,48,B4,13,46,B9,4C,3B,37,A8,62,12,82,5F,7D,9B,0B,41,80,AC,66,79,25,FC,2A,2B,63,E0,88,91,D4,96,83,53,6F,D2,06,E7,0C,30,A8,0C,19,FE,92,17,42,33,AB,A0,E0,75,66,8B,AA,7A,AC,91,63,77,26,0B,44,00,AA,47,6F,43,30,9A,04,45,F1,99,77,D3,D7,C7,AE,EC,30,34,3F,53,00,C6,DF,12,E7,D0,F6,DD,D7,F1,C4,CE,73,D3,0A,B2,12,02,68,95,23,52,8F,5A,9B,19,B6,72,4A,95,F6,91,E4,9F,A9,DE,ED,E7,C7,8B,8A,83,79,E7,E9,81,62,F9,22,7D,AB,1A,53,5B,DA,43,87,50,D9,DF,B1,C9,74,9D,3D,D6,CE,11,27,DD,78,4F,E0,24,F5,8D,75,E9,12,C0,54,D8,DB,60,94,46,B0,7E,0B,D9,19,09,8A,66,FA,B8,17,F6,42,3E,DC,F6,1D,4B,B4,D6,17,6F,F6,41,21,68,35,C8,C0,E9,31,E0,D4,7F,A1,6B,28,36,4C,C1,64,19,09,6A,7D,1C,33,F4,40,0B,D4,F1,EC,FC,34,0F,58,FD,85,E3,C8,06,41,5A,B9,FB,A5,3B,95,0F,14,5A,38,59,45,31,10,36,61,91,82,B9,48,3B,77,08,4E,B6,95,07,16,0B,97,12,FA,B2,0E,5F,0A,01,72,4F,72,28,EA,B6,2A,A1,5A,F0,8B,AB,AE,94,57,B2,BB,AA,9F,11,72,CB,6F,6C,05,DA,F9,8A,F1,B7,1E,FC,74,18,DB,C4,AB,76,29,BA,B8,1D,2C,42,42,75,FB,D3,72,76,02,DC,FB,5A,78,02,E5,B6,58,BE,AA,79,B1,2C,1F,6F,45,69,3D,16,2C,AE,17,2D,9C,BB,90,7F,E7,CC,21,C4,D6,A1,E2,3E,9C,53,29,75,6E,07,6D,F4,4B,BE,67,9E,73,A1,41,02,B8,84,6C,CB,93,7D,B8,8B,52,4A,A2,90,88,BF,2B,D5,43,18,F4,8B,CA,05,2F,20,CA,45,D3,FD,C3,86,64,2C,A7,C7,63,F0,9B,03,4C,52,0F,2E,5B,9B,4A,05,51,81,59,67,D7,54,93,69,A8,39,D4,67,86,AE,29,0C,AD,79,63,E0,80,D3,B1,2A,BF,A1,F7,50,C4,C0,A3,02,7B,8D,3D,85,F5,1D,4D,A5,BF,56,73,FD,3F,BA,E1,F8,9E,3E,BF,9A,CB,AE,D1,A3,6E,3F,FA,CA,48,05,04,C6,84,4A,27,0E,AD,49,B4,26,9F,86,9F,CE,B4,59,4D,9A,4A,6F,9D,E1,8D,81,BD,A3,35,01,4C,09,9C,79,30,CD,49,55,60,20,A4,79,E4,05,E5,E5,BC,66,C2,6E,5D,44,FC,93,35,36,D0,9E,9D,B4,35,95,CA,7E,ED,78,DA,6C,CD,72,7B,36,5A,D5,DC,A3,DC,DA,3A,99,4E,24,04,D7,3C,36,D5,AB,9E,68,E4,7B,1E,EB,99,25,E2,C2,32,BB,E4,42,CD,0E,10,BA,09,8A,CA,F6,B2,A2,0E,23,0E,2D,21,4A,78,FD,0D,F7,91,63,E6,DA,29,28,E2,F6,CF,DE,3E,F5,00,2B,06,72,61,03,F8,E1,61,07,96,8C,D3,12,47,4B,FD,F3,A7,B6,58,A2,21,9E,9F,B6,2E,F2,45,AF,91,09,45,E4,59,40,62,26,7A,7B,3F,D3,3D,93,88,C8,34,A3,EE,CC,DC,BB,68,97,4F,06,3E,3E,F0,63,51,F9,5B,19,34,03,74,1E,B6,AE,CC,3F,96,BB,68,82,06,72,60,F3,73,50,E8,2C,CB,4F,14,72,1E,B8,DF,3B,62,44,99,D5,64,6B,A8,EA,7A,F7,F9,96,E1,E7,B7,DB,DA,88,30,3C,45,BF,AB,3F,24,E7,F3,C1,93,91,03,87,88,6A,B5,B8,04,80,D7,92,44,02,62,A9,0A,4A,7A,11,9B,1A,7A,52,85,67,E5,C9,C0,9E,A7,DE,1A,E8,1E,96,F3,E4,82,F5,24,DF,01,E9,5D,22,BB,03,EA,DD,8D,56,0D,09,A5,BE,8E,1B,09,17,F3,1D,FC,47,0B,E5,42,62,9B,BD,8C,87,A1,80,C5,08,DD,89,CF,27,0E,10,9D,3D,70,4C,79,E4,3C,16,1E,6C,6D,67,4C,CF,F2,B5,5B,76,1F,5F,9E,2F,95,A5,D2,1D,66,36,1F,40,F9,CD,05,0E,9C,6E,D5,4E,75,87,82,B1,CA,F6,F4,1B,C4,A7,69,3B,DB,E6,29,CC,33,C8,6E,D9,A7,98,DD,3D,D7,A4,61,91,67,7B,6D,A0,B0,14,E6,58,C1,2C,D6,AD,C8,2E,2F,1C,5B,56,7B,EA,AD,5A,64,C1,10,E1,4C,94,27,1F,97,95,D2,A8,F3,9B,B9,27,53,23,6D,AA,39,DC,CF,DC,72,6F,33,B2,2B,85,94,5B,23,F8,20,0D,82,C6,D1,07,A3,9E,DA,B4,4C,8A,BC,BA,AC,5E,5A,57,D2,33,36,51,47,4A,C2,BA,A4,9A,C7,E7,15,28,EB,55,EF,5C,66,40,AF,54,7C,71,8C,06,FC,3E,72,89,E3,5D,B6,79,20,16,8D,81,47,68,90,65,10,6A,F1,09,C3,07,D6,E2,FC,90,C9,10,66,BC,34,3C,AA,50,19,7D,BD,75,A7,CA,8C,CB,21,13,31,02,64,3C,32,6B,8E,49,20,64,E3,79,08,DE,1E,41,02,AA,0C,3F,2E,EB,85,1F,72,DB,C6,B6,8F,43,15,B2,4F,4C,96,A5,AA,4A,0E,6F,E2,02,20,4D,AC,2C,7C,06,F1,E6,33,BA,22,47,3A,5E,3A,88,E6,04,A5,3F,A2,6A,F7,86,97,76,C6,A6,7C,12,D2,08,C2,0C,79,12,A7,1B,DC,4B,7D,84,60,D7,8B,20,07,63,7C,FF,44,81,6C,A9,2C,E8,70,E0,CA,93,BC,CD,35,7C,D7,22,6B,D0,D2,AB,00,A4,D9,87,99,41,9E,9E,F8,0B,B1,F4,F9,26,5A,53,DF,24,DD,69,1A,F7,B4,E7,CE,86,D0,2C,53,FA,B8,EE,2F,3D,08,34,17,4C,84,23,14,1B,9C,33,EE,69,5F,33,82,84,52,BA,DF,31,AC,96,C9,E1,27,75,05,00,8F,A5,23,F2,79,E9,A7,00,03,48,C0,C5,B9,B3,F2,FF,07,C7,A3,70,2A,23,30,D2,5D,5E,1A,70,E8,5F,49,BC,F9,FB,A3,72,28,B3,5A,0D,E4,EA,DB,28,A5,3C,06,62,AD,EE,7A,70,84,E3,5F,DD,4A,C9,13,3C,3D,C2,1B,FB,2E,2B,C3,DB,69,07,12,D5,F5,75,B2,27,54,1D,2C,C9,E3,BB,7F,24,52,47,1B,7F,AA,E1,FD,4A,FC,C5,17,CA,4C,F0,ED,11,2A,00,9B,3E,88,91,75,4C,C8,9C,93,44,00,27,88,5B,27,9F,60,F5,2F,D2,8D,6E,0D,80,CC,8E,2A,D3,4A,05,D4,1A,83,54,43,3E,B6,E6,2F,48,92,E3,B2,7E,70,4F,ED,75,7F,7C,48,51,D4,DF,CE,A6,B6,93,5D,11,B6,EC,E2,0B,00,F4,3C,6E,E4,12,87,E6,41,A4,B8,A1,C6,97,3C,6C,77,65,01,F4,D5,D6,DB,EC,25,EF,37,4D,E0,F3,D4,73,56,18,B7,8B,19,A2,5C,F5,FC,68,50,AB,6A,FE,83,F5,13,0E,E3,B2,AB,7F,B7,09,67,FA,46,B0,8E,7D,E1,7F,ED,7B,D3,84,96,44,EA,AE,05,9E,55,8F,0C,2A,27,5A,60,23,2A,6C,4D,38,39,BC,01,8A,B7,BC,2F,1F,2E,43,EA,35,11,33,C9,73,28,36,F6,E2,FA,B1,BB,9E,D9,D1,E9,82,6A,7F,A3,CF,5F,49,54,FA,A9,C5,C6,73,1A,20,EC,42,A5,73,8D,5C,D8,65,2E,49,EA,4A,D2,24,82,0D,0B,2E,B3,93,61,DA,29,9E,C7,FC,F0,9F,67,7C,78,48,7A,9C,03,54,08,6B,C4,E8,E5,10,FE,15,53,28,1A,FF,19,B1,1C,59,9C,F8,C8,88,C1,42,C0,91,9D,C5,4C,63,34,28,E6,B0,9F,63,4A,D8,AD,1B,02,04,EE,06,45,00,36,40,DB,BA,B4,D9,BC,E5,9F,30,94,81,F1,7E,BE,DB,26,70,78,8C,15,1E,19,F6,2D,E9,7B,A8,93,0B,4F,1A,01,AF,67,18,C5,C7,2A,52,04,E7,09,63,FB,1E,20,CF,2F,1D,17,B3,30,AF,65,98,6D,E7,5B,C0,70,7D,BF,B1,AA,61,FA,3E,13,3D,21,5B,2E,DF,4D,0C,90,BA,CD,01,37,2C,52,39,AD,2F,A4,6C,08,45,02,23,F2,4A,E3,86,53,0E,25,CD,30,3D,2D,41,C6,2C,5C,F7,F9,DD,DD,C0,8B,AC,25,7F,A9,CC,EE,4F,3E,F9,C1,84,02,8E,24,AD,CD,B5,BB,1B,D3,12,58,58,FE,06,E4,91,9A,DE,01,12,52,01,5F,44,7E,A1,DF,9A,81,05,54,E9,2D,E5,D3,94,94,B7,C6,3C,B0,A3,1A,6D,FD,5B,02,6E,08,EC,95,3C,78,69,8A,C5,C7,FB,39,A0,31,ED,D9,7B,21,62,C5,0C,92,0A,86,33,61,F5,76,B2,A1,96,81,63,12,A6,A2,DA,79,68,F4,29,87,70,0A,3D,F3,0A,8F,BC,B2,C5,46,AC,19,3B,26,41,18,05,6B,C4,31,ED,AD,B3,50,F1,4F,F1,FF,DB,C8,4F,8A,74,8D,74,BC,7C,EF,EC,92,37,BB,5F,C8,A7,63,52,A6,C4,B6,1E,6B,13,44,2F,0B,DC,CF,5B,1A,9C,D6,06,77,70,53,8E,FF,C9,D3,2A,4A,7B,BE,ED,BF,19,10,BB,0A,2B,F9,F9,8B,62,04,C3,CD,97,F4,A3,68,FC,9E,9B,69,94,CD,3E,5C,E5,4D,AC,EC,38,D6,C1,22,99,12,93,00,8E,5F,5C,1F,0C,28,1A,A0,62,62,00,66,9F,7A,7A,57,4F,F4,B2,A7,EB,A9,15,F8,2C,C7,3E,82,FC,57,30,99,CC,DA,1F,25,F4,59,63,27,49,01,1B,9D,3A,E9,B9,22,7D,53,A1,CA,07,CA,B6,4A,57,C4,DC,18,6C,D1,5E,FE,95,9D,1C,0C,61,74,6B,B6,5D,7A,61,BA,57,1B,F2,40,5D,76,48,3E,AC,8F,DB,80,27,79,16,37,CA,27,E6,6E,69,5E,B3,1B,76,F8,D3,0D,DB,5C,28,92,CD,02,81,7A,BA,D2,47,85,92,06,98,5D,4F,0C,54,82,58,8A,64,DE,C8,CA,D1,58,8A,1B,EC,35,A9,F7,2E,CE,58,AA,8A,09,E3,B3,6F,6F,8D,F0,76,CC,9D,74,C2,1A,68,42,EB,83,C6,8B,C3,FC,74,94,73,E0,60,2B,54,D8,BA,E3,6A,52,09,66,4E,F4,EE,B5,F2,F5,98,30,3E,10,C8,85,B4,92,C0,CF,47,73,C8,EE,8F,C8,16,56,E3,51,63,93,7A,52,FC,80,14,AD,74,64,10,99,01,CF,19,B8,E9,78,BA,B2,FD,B7,A3,51,09,2E,75,FE,A5,D2,F2,1E,C8,8A,51,F2,C6,44,5F,AB,89,45,45,56,FB,B7,42,DC,47,64,1C,B6,B0,0B,0B,06,95,28,4F,B3,86,5C,59,F1,FF,E7,C7,62,BA,CC,E2,0E,1B,CC,30,2D,D0,B7,4F,9C,4B,16,6D,82,C9,20,43,D4,93,15,6F,C5,13,FC,84,E3,02,72,69,0E,18,74,BB,14,C8,16,5E,DB,84,7B,83,E7,CC,E5,13,F8,95,1D,B6,59,A9,2A,EE,E4,AA,6A,4C,9C,A2,A3,8D,83,84,B4,C7,8E,7C,7D,F9,C4,CC,53,8A,E9,4C,9E,DB,D0,86,19,7F,71,5F,9A,07,12,74,51,0D,74,57,DB,B5,8A,06,B7,06,85,E5,B0,27,CF,7E,76,DD,8A,3A,95,E4,19,21,AA,66,A6,76,86,FB,E3,7D,8B,C7,66,F0,00,CE,FE,D6,62,F2,DF,98,DD,0A,3A,33,C6,1F,C8,7F,59,B1,B8,DE,1C,F4,49,1F,78,74,34,EA,A0,C9,09,F1,D8,11,5A,CB,0D,B3,6C,2C,CA,88,B2,5C,D0,F9,2F,59,E5,95,54,0E,0C,CB,19,69,E5,64,82,E9,1D,8C,BD,7F,8E,B4,E2,61,E8,A2,48,94,7D,58,E1,BA,8E,77,10,28,9A,A8,F0,31,61,A1,38,6F,A1,A8,C6,BB,73,04,3F,D1,F9,FF,3D,80,2C,C6,A5,57,06,E7,3C,3A,54,6D,C4,80,5A,7A,A5,1E,46,18,77,CB,52,2D,5F,40,8F,FC,16,17,5D,62,F6,47,5C,A6,36,DF,CD,C1,49,6D,FE,E7,A2,B2,BA,BF,8D,6F,B2,8E,18,66,E4,CF,83,F6,28,AB,A4,16,E6,3B,12,D7,BD,40,8E,86,AE,1D,76,5F,47,FD,57,5A,1E,95,16,DC,FB,91,44,2E,AA,D0,74,F0,D4,7A,DD,2F,AA,92,65,5A,96,C3,42,34,02,2D,D7,BB,03,3F,93,A8,FC,FB,08,16,D2,EB,88,BE,3D,94,EC,0C,DD,76,3F,F1,2D,53,F0,E1,8F,88,E8,4A,7B,B5,1B,7B,A0,F1,7B,17,1C,7C,2B,7B,B1,9A,6D,4C,59,D2,6F,FA,17,B4,6F,DB,93,E8,5E,1A,9C,0B,CC,9C,26,97,D2,C5,2F,89,F2,C6,DE,A9,08,C2,C3,B5,15,E9,6B,A1,58,A0,84,C2,B2,09,5B,2B,3F,22,B5,DB,AE,89,7B,9A,D9,B4,36,55,33,BE,26,61,19,F6,E8,89,83,AC,FD,F9,45,A5,A8,03,8E,D5,B1,EC,02,4F,EB,F8,84,56,68,1C,83,28,23,3A,EE,EA,19,DB,FF,66,DA,B8,18,CD,A9,19,96,5B,A7,73,5B,26,CE,EE,C2,CF,C1,FA,EF,33,2B,9B,59,A7,DF,E1,EE,E3,BE,4D,83,4F,E3,31,F8,F3,31,2C,7B,29,80,A7,D0,90,B3,37,B1,BB,DB,99,8C,92,37,74,50,F8,9F,68,9A,DF,53,A5,A7,B2,C2,7C,90,05,FC,A9,09,01,97,3A,E6,17,8B,8E,9B,47,FC,FE,DE,6C,BF,00,19,BF,32,F4,F6,CD,BD,37,B5,A7,A0,FC,0E,C1,75,8A,28,5B,A0,06,AB,2B,91,6B,89,53,B2,D8,C9,DD,B6,12,FF,F9,A5,19,AB,77,15,19,C2,AC,68,9C,08,4A,8F,58,7C,4C,BD,D5,8F,08,DE,E0,B5,AA,12,D0,6F,DF,8F,DE,9B,79,1A,3A,CF,B4,25,40,61,3E,69,CA,38,2B,D2,FB,35,88,29,F8,7D,72,48,5E,9D,B8,60,26,D6,8B,13,DD,70,0A,11,88,48,CB,F7,BA,E9,CE,62,2E,62,9D,8F,D9,FC,91,7F,C9,52,20,97,91,B0,E9,B6,5C,22,EE,B5,34,50,12,F3,3B,17,2C,A3,38,62,C0,29,20,DD,41,3E,49,62,40,FA,30,3B,87,F7,5E,46,6C,94,8E,3F,9F,74,84,78,AE,70,B6,94,1D,69,29,8F,1D,EF,3B,A3,79,B7,51,D6,FD,C3,DA,7A,18,C5,07,91,8E,9B,F5,D4,F2,3A,12,06,59,86,31,97,98,44,D6,57,82,E6,3E,2F,C9,ED,15,BD,DE,94,51,F9,5B,A3,1F,F3,1F,93,2D,17,37,96,4A,A8,9B,7F,48,6C,2B,F1,2B,F1,81,B2,93,0F,59,05,64,5B,C5,A3,88,FC,C2,10,3C,1D,29,C9,16,38,C2,10,28,E7,1A,14,B4,38,7B,CC,1A,21,1F,9D,3A,DA,BE,39,93,40,1D,E5,65,0F,41,32,E6,47,DA,16,55,FB,86,ED,55,46,E4,3E,22,FC,4B,C7,F9,59,08,D5,3E,81,D2,04,B1,DA,B7,99,4A,01,8D,A1,F1,CD,F5,03,18,B2,37,3B,9E,89,1C,6A,16,7D,F2,98,9E,23,EE,1D,81,6F,96,31,52,8D,F8,E5,0B,05,50,AE,E2,1D,0B,85,9C,B7,45,CF,04,35,82,B1,69,0B,0E,EE,5A,5C,29,8A,FF,8B,2E,47,A3,B4,18,31,AE,92,90,44,C1,21,EC,73,83,F3,3D,95,D9,DA,77,12,F8,9B,FE,9F,24,60,67,83,CE,D0,0C,EA,5F,54,3A,CF,C1,A2,17,C7,6E,8B,94,99,75,01,D2,85,49,D9,75,34,67,81,3B,E6,1D,04,03,54,20,FD,93,A7,5B,DB,FB,B6,86,87,80,A5,4C,D1,50,86,AE,4E,63,4F,49,EB,5D,1A,E4,75,8C,1E,BA,99,0B,D6,E7,84,FD,12,8A,39,01,B0,AF,AC,DB,00,9A,4B,B9,55,67,E1,E7,D9,37,63,A5,D0,C2,F2,60,6F,79,59,9C,BD,F9,57,B5,E4,C9,67,E8,F0,7E,F7,6E,2B,9B,57,F8,9F,0E,53,3D,83,B0,81,C0,8B,C0,D0,73,A6,93,70,34,69,DA,9C,89,A4,BC,7E,2A,F2,59,C2,88,79,C1,5D,43,7F,4F,5C,0A,84,6D,52,D2,4E,1A,2C,CB,E4,DE,E1,ED,38,A4,78,40,71,22,47,16,B4,54,22,BE,52,52,85,20,40,E3,C9,6C,05,49,B9,F9,EF,6E,6A,A1,AE,76,9E,DF,03,B0,D7,3C,E9,D2,03,4F,77,96,1D,43,21,B1,23,D6,4F,95,40,E1,2A,EF,7B,41,FA,8A,16,9D,B8,EA,D7,97,71,44,1A,BA,6C,B4,26,D7,DD,0D,55,9D,63,A4,5D,9D,B1,91,AB,DF,64,1B,F0,7F,50,87,1A,D3,25,54,E9,00,B4,04,71,5F,40,32,7B,7F,61,BA,4B,F1,39,67,45,F1,6E,0B,4E,17,89,D5,4B,B9,62,37,F2,65,0A,94,7A,A3,A7,C9,A4,6F,C9,2F,57,18,70,3A,46,1A,8E,3D,03,07,9D,D9,41,4E,15,A3,5E,F7,AB,27,E4,81,9D,AB,C2,F9,DC,F9,D0,02,E4,25,BE,99,27,8E,68,19,8A,78,A0,EC,5C,21,26,5E,30,E0,18,00,15,7D,59,0A,C8,30,4F,E6,4E,D5,FC,4D,A8,78,8C,8D,EC,18,1D,B3,0A,D8,4E,6E,66,F6,83,79,14,42,37,A6,58,1D,98,65,82,35,CD,2D,85,CE,84,C4,FC,07,7F,1B,C6,19,C5,5A,B3,AB,6E,8A,C6,C7,F6,52,B1,3C,B6,62,6A,4D,BB,AC,D6,3D,1C,58,67,C5,29,82,15,A9,16,ED,6B,3B,34,D0,8A,EC,19,28,FE,6F,F4,F6,B8,D4,71,B1,36,13,9B,23,9E,47,B5,94,94,9A,F1,BC,1E,CE,BD,1B,30,9A,8D,58,D2,96,71,F0,A6,9A,79,B3,81,56,A0,DF,15,EC,C2,FE,8E,23,4C,13,B7,05,03,85,0E,D4,0F,47,23,90,8A,29,E3,F2,1D,38,C6,3F,AB,05,68,6C,67,A1,C8,98,8B,0D,2A,CE,A2,62,DE,21,0F,29,59,18,54,C5,B1,6D,50,FF,C4,CB,7A,02,51,16,F5,6A,51,E7,91,1F,7A,EC,09,85,B6,BD,44,F4,61,B4,07,53,7E,77,83,58,55,DE,76,6E,21,C5,54,F7,4F,DF,49,09,13,88,16,A8,61,82,6A,50,E2,17,66,E0,26,2D,CA,AB,54,FE,BF,57,8D,3B,93,42,B3,AB,86,2D,1D,17,D5,C8,69,31,29,FC,DA,13,2A,17,9F,06,65,6F,24,4F,D5,53,EF,0E,75,44,23,51,34,C0,10,33,7D,91,C5,1C,48,88,92,C8,D7,CA,14,3D,ED,3E,0E,4A,9D,31,39,C8,CA,D9,77,68,67,61,B7,0F,DB,21,6C,F6,BF,96,C7,3D,26,65,A2,0D,F5,45,79,28,82,04,16,8B,5E,97,09,92,C7,22,CC,FF,97,88,9F,05,46,17,10,DA,13,A3,CB,B7,AF,E6,50,3A,C0,35,FB,A7,F8,F5,D6,27,D2,68,A7,E4,AA,EA,42,CC,02,E8,D6,DF,C9,20,5D,FD,63,F0,4E,3A,18,26,D5,C0,00,B8,AE,55,97,AE,40,8C,D8,47,C2,B1,36,92,78,41,7C,58,F6,3A,C2,2A,B3,C2,CE,99,0D,D1,EC,C7,A6,A6,DB,ED,F2,B7,62,42,1E,27,F1,36,12,29,32,8A,7E,FE,71,20,D7,BB,B7,7D,14,53,55,AE,5E,7D,13,82,91,72,E1,08,D1,12,CC,29,0F,3E,98,3A,8F,CB,57,0E,2B,B3,A5,E1,68,09,F6,4D,BF,84,AD,C5,FC,26,55,D2,72,10,E5,B9,02,69,F3,B5,D1,34,9E,85,56,F5,A2,7A,E3,29,DC,E5,A0,06,6F,0B,44,CB,77,B0,65,69,09,D7,2D,1E,99,52,9E,81,77,0D,68,18,16,EC,30,1F,41,57,E8,44,17,3A,32,82,C2,BB,57,2F,6D,D8,D4,AF,C5,A1,7F,A6,BD,74,6D,45,6C,5D,82,67,B4,E4,D3,94,A6,A4,D2,76,34,2E,FF,6B,3B,14,7A,39,7D,FF,70,DF,43,FD,BB,1A,CF,07,76,53,00,59,7F,57,E7,1E,D4,C0,E8,E6,80,F1,56,00,DB,A8,DA,1D,E4,3B,25,9F,78,7E,33,9C,51,F0,D6,0B,CF,D7,CC,D0,13,F8,4E,54,97,98,DC,E0,77,59,FD,3E,F8,40,09,D3,53,35,BD,6A,B9,DE,2D,DB,F7,08,C1,10,11,0A,94,7B,51,5B,52,76,76,54,93,88,68,44,E5,56,C3,DD,FD,C8,90,78,0F,6A,E6,B7,A1,5D,52,BC,38,6B,D2,16,4A,4C,C1,6A,2E,D0,90,35,1F,54,8F,95,8C,74,F2,AF,FC,E5,29,3F,94,BD,10,FE,5E,D1,19,1F,E1,81,5D,E4,17,6D,76,E0,99,F5,05,A8,5B,F0,E6,86,1F,90,B5,48,B3,30,67,58,60,8A,21,F7,9C,5C,1A,04,92,23,CC,82,F5,29,A2,13,A0,C4,CF,31,0A,20,9D,03,FC,5A,C5,19,42,23,68,54,9C,20,AD,3E,5B,1C,9A,D5,AE,21,67,8F,03,60,6A,7A,B8,E8,A9,C3,17,9E,51,6C,E6,8F,00,D7,F1,9E,12,D4,1F,CF,0C,F1,56,A1,6E,83,A8,7B,37,94,E7,D4,91,17,A5,5D,4C,71,54,A9,0C,DB,30,60,56,AC,E9,97,CE,45,39,53,8D,0E,56,E7,A9,70,3A,53,52,99,24,49,F9,31,73,25,AA,F3,8C,95,E8,5A,FE,4B,AD,62,05,8C,3F,E1,25,81,62,AE,E6,AB,98,9C,FC,43,65,F7,6E,31,97,2C,51,45,FB,1B,38,79,8F,53,B1,C4,63,33,F6,95,16,83,4C,91,8D,6A,1F,2A,24,51,2C,AA,40,F4,93,18,43,75,7C,C7,13,2D,DD,7E,70,B0,1C,6A,FF,09,59,CF,67,48,6D,77,EE,B6,A2,90,BC,21,A1,83,A1,00,5B,03,44,8A,AF,96,84,64,D5,0C,22,E9,EE,C3,28,DD,DE,F7,AE,37,06,1D,93,7D,49,52,F0,7E,CF,03,7F,3F,B7,E8,AE,27,96,8B,0F,74,7F,3D,54,69,72,02,0E,06,D9,D4,56,D5,56,38,3F,74,88,2A,2C,08,91,75,C3,3A,D7,09,DC,85,DE,43,2F,21,DC,CA,69,13,1C,40,A5,B9,15,AB,7D,E1,33,52,53,AD,40,ED,AD,BC,B5,83,8C,0D,79,AD,3A,DC,B1,41,0E,33,C6,D6,1A,F1,2F,08,AF,96,1F,44,54,E5,A0,44,52,EF,FD,C3,5B,02,E4,56,36,89,FB,DA,36,70,39,47,71,D2,B7,13,3D,09,1A,95,86,83,A2,34,38,F3,A6,11,B7,B7,AE,CE,83,E3,37,33,70,90,DB,47,D1,46,5C,9E,8F,9A,32,FE,67,80,57,79,1E,F1,40,E8,1B,A7,E9,74,2F,B3,5A,8D,72,E6,01,F3,A4,D9,BD,C5,E7,6E,32,72,00,E2,1B,B1,2D,D9,10,31,F3,D9,1E,9D,7A,FB,06,EC,62,44,A4,9C,E7,FE,B5,0C,5A,BA,64,1E,3B,C5,FA,53,38,73,EC,CD,65,5F,1E,3B,5E,84,5B,47,F3,3B,60,96,21,90,29,4D,4D,96,17,BE,BC,01,54,2C,36,85,5B,93,BB,FD,E3,E0,88,05,23,01,57,B1,1A,1B,F4,21,B3,05,4B,D7,82,EC,D4,66,AA,6C,55,C8,54,B9,95,6D,61,23,63,D2,CC,A4,2B,6F,3F,63,AC,08,EF,6F,CC,74,7B,70,3F,1B,89,CC,A6,C4,B9,BA,58,C8,2C,80,24,03,D1,81,AB,B2,B5,A8,32,B0,17,57,3A,D7,D3,F8,12,FA,5A,C6,C6,F9,9D,29,70,A1,42,B7,5F,CE,FF,5A,1E,D1,C7,39,1E,BD,32,0D,11,F4,B7,31,64,06,93,BA,2C,4F,A5,3D,51,F5,47,DC,B9,FC,7B,09,95,C7,28,10,05,D1,BC,25,F4,77,27,1D,47,40,3F,E5,E8,53,D2,85,2E,20,80,7F,AD,E5,B7,60,B4,E8,41,3D,D8,B5,CF,14,90,7F,D1,A3,C3,B5,3C,24,B3,BF,53,96,47,A7,54,A1,AC,DB,1E,5F,CC,32,F0,25,48,A8,53,9C,5B,20,19,96,FF,9A,17,AA,76,CC,D0,58,B4,9B,F5,35,6A,DE,E8,31,A9,3D,3C,80,18,35,1D,A6,D5,BD,C7,A8,1A,56,42,C5,0E,1E,9B,7E,E9,DC,45,E1,A2,BF,12,9A,A5,B1,C0,54,84,DA,42,42,67,94,98,C1,9A,D3,12,33,7F,FF,39,20,1F,87,48,14,64,CF,E5,C1,6B,FB,2B,B7,42,89,2C,C6,08,52,4A,0F,DB,0E,EA,CA,9B,02,6A,EF,8C,43,AC,1A,24,1F,68,78,70,1B,37,B8,5A,E8,66,3D,DC,59,B0,BE,B6,1F,D4,3F,FC,ED,30,48,BA,F4,1C,69,D9,C6,B2,F1,32,23,F4,B3,6A,31,93,45,12,55,E5,AD,D0,0F,CA,17,A5,EF,51,C4,FD,B5,94,F4,2E,D1,EB,7C,1B,0C,6B,6F,7F,1A,60,CF,6F,0C,E5,AB,4D,EA,E5,59,45,CC,B5,C0,F1,DE,86,33,DA,05,B5,E1,3A,81,F9,D6,CD,68,4A,F6,C3,78,28,14,B3,70,BA,01,53,73,44,1E,26,9C,66,EB,24,9F,AC,D9,D4,25,0F,0B,C0,E8,FD,00,EC,B6,97,C1,FA,EA,AE,8B,79,9A,25,56,0B,38,A7,34,B0,C0,C3,64,74,55,08,B7,DF,B7,2F,74,0F,3D,E0,F0,2B,5C,54,31,CE,4B,2A,CB,4D,9B,5E,9E,B8,39,30,2C,F0,1F,BF,07,E0,A6,EE,4E,A2,40,A0,D8,1B,81,5E,B9,52,61,09,DB,DB,26,A7,C9,A0,E1,F7,4C,43,AA,04,7B,F1,8F,18,B0,25,22,EA,83,0A,1D,72,53,56,FC,87,67,66,8C,BA,28,B2,07,D0,92,76,CB,82,03,5E,9C,78,A3,92,C7,F7,4E,53,A0,93,8C,7D,4A,E4,A4,DE,18,3E,CA,AF,9F,39,B5,31,28,7D,F0,4E,48,28,11,AB,7C,0A,0C,A0,E2,DC,AF,42,55,EB,35,08,CC,5E,31,B1,26,05,72,B6,68,A6,18,9C,D6,56,32,95,80,3A,5C,64,DE,C9,0F,E3,91,89,5E,94,CF,A4,0C,79,F3,21,BC,8E,61,23,F6,BB,3B,A9,82,BB,73,04,2C,E0,94,6B,22,C8,A5,15,44,9D,8B,49,E6,B0,EB,1F,92,E1,82,F8,56,CB,6C,F3,C1,30,66,54,B1,90,16,B4,65,87,E7,37,09,C5,11,BC,BA,7C,5C,96,4E,4A,B0,9A,F4,52,8D,12,47,4A,9F,A0,41,F7,6F,6D,91,BB,21,40,09,16,84,B1,C1,27,5C,27,80,B1,24,84,17,84,C7,75,E9,B2,14,EB,25,25,D3,CD,06,50,53,01,CF,5C,19,8C,4F,21,B6,22,A4,90,F1,1C,22,31,F0,E0,CD,F9,BE,0E,A6,E1,B6,28,44,ED,B2,18,4F,E4,A3,50,3B,7F,3C,76,C5,01,8F,CB,82,35,1E,AE,A5,4D,0C,1F,F3,4E,08,01,56,4B,0A,B3,93,36,49,35,C3,E6,49,41,83,69,E5,A9,98,46,29,94,BF,BF,EA,06,2A,0D,2F,66,E3,00,00,EA,FC,51,A6,BD,CC,4F,11,47,AB,E5,A3,1D,45,B6,B7,4E,BB,A6,45,FD,9B,BB,4A,CC,05,99,FB,C8,78,50,07,EC,44,1F,6B,CF,3B,42,EA,57,20,07,CC,60,5B,F9,2C,7B,D6,FF,C9,78,FD,5A,E4,F4,D2,78,2F,82,61,1C,EC,D1,66,E4,E1,77,5B,2B,41,63,3F,3F,B4,32,C3,FA,86,B3,79,1B,B4,45,18,5E,C0,0D,54,C0,4F,6E,55,8B,C8,65,64,1D,D6,86,3A,E4,5B,10,67,17,99,BA,D8,46,65,02,CD,4A,6A,60,93,FE,01,72,3E,D9,50,AD,B7,1B,39,12,12,3B,1D,FF,75,94,F6,53,6A,77,2B,F6,2D,A4,43,65,AA,2A,8B,CF,CB,8B,0C,90,56,C4,CF,D9,4F,D0,28,E5,FA,E1,3A,5F,DC,FB,2E,CD,21,48,AB,43,B6,0F,48,4D,D7,8E,2B,CD,3F,1D,5F,6A,FA,6A,7C,AE,7A,CB,65,D7,A9,E6,31,6B,E3,BC,B7,32,4A,F8,E2,DF,4D,65,C3,AE,74,11,F4,12,37,F8,58,D6,D3,86,A6,57,5F,68,83,49,6F,9C,32,1B,4E,63,A5,49,A0,3F,AF,B2,C4,02,FF,7F,3A,12,FA,B4,C3,61,AE,AC,63,B6,9B,36,DA,50,9C,D7,56,A5,49,DC,54,D9,08,15,6D,BA,EB,2E,0A,B1,16,2D,BB,56,94,2C,78,64,AC,A0,26,44,C5,9E,68,13,D9,28,3F,B4,60,F3,0F,98,7E,13,72,F2,8D,33,35,3C,C5,87,53,76,19,20,97,01,1E,7B,AD,B5,F5,01,F6,59,92,24,64,AC,62,F9,46,63,C2,5B,FC,30,16,17,FF,E3,F8,11,C8,EA,AF,FB,93,08,70,2B,40,E5,1C,F8,42,49,D3,32,6F,57,26,6E,87,78,FF,DF,93,31,C5,B7,35,82,7A,EC,03,61,21,08,DD,11,D7,5E,DD,2D,DA,04,91,7D,7A,40,C5,EB,3B,4B,79,8D,84,7C,12,DE,50,F2,3C,38,49,81,39,66,2E,DE,B7,C1,E7,A1,B7,37,90,DD,51,2E,8B,1C,39,EB,00,DE,D8,49,7F,C1,DD,6C,58,A0,B1,68,E5,CA,6A,90,B3,BB,3E,7D,15,6D,95,03,47,A4,FD,A4,51,CC,D2,9A,30,DD,F2,CF,45,59,C9,E3,0C,47,A1,02,70,51,CD,45,89,11,14,95,79,54,2F,71,76,7B,19,9C,E6,F9,B7,F2,8D,33,23,FA,C2,75,76,AF,80,9E,96,F9,7C,F3,08,4B,F9,69,CB,D8,1F,61,B8,39,B8,B5,26,27,BF,1A,A0,F9,25,39,E5,62,C7,1A,BA,FC,53,B7,FA,8A,DB,08,7F,9B,85,5B,BD,1B,3E,65,45,67,4F,24,63,59,08,7B,40,40,45,E7,83,4D,89,A2,D0,F8,5A,21,44,0F,DB,FD,CE,92,C7,62,52,C1,F1,11,9F,97,8A,EC,80,91,EF,55,D8,2B,5A,21,F2,0A,E3,86,3D,DF,A1,C8,71,DA,28,28,B5,D1,EA,CC,92,42,7C,67,4A,0F,18,3B,A8,33,0F,20,F8,44,9E,40,53,F5,65,A8,84,0B,80,14,B0,98,4E,41,F3,F3,88,47,D5,FE,08,FD,BA,53,56,A2,3E,D8,2A,98,29,35,BF,86,A7,35,0C,B9,89,0E,8B,CE,E1,67,E1,71,0A,3A,B6,0A,59,6E,13,BC,79,D2,6A,63,44,F0,0A,06,83,DB,B6,24,F8,80,91,11,76,6E,E6,8F,E2,CF,76,05,3E,A1,55,CD,0F,4F,02,2B,DD,7C,2D,6E,11,07,86,B4,51,93,B2,07,5F,20,DF,52,7F,70,26,23,66,43,88,0E,DF,F3,87,7F,99,49,B6,37,BF,4D,AF,B5,50,DE,5A,DB,25,9B,E0,C4,98,C1,29,E5,06,4D,C9,C6,8D,36,49,80,0D,C4,3F,EB,6C,FC,14,6B,B4,FB,D2,7C,2C,5C,49,0D,C5,A7,FA,3E,C9,73,30,F5,AA,FB,C3,CC,84,9F,BA,A5,D9,D6,DA,8B,DD,BA,E7,5C,77,45,8C,E3,82,C9,14,35,88,3D,A1,00,1B,1A,7E,4F,99,FD,2A,B9,02,35,6A,A9,D6,81,BB,76,CE,F1,12,46,4C,29,7F,AD,D0,F0,F1,C4,18,E8,C5,51,04,05,15,7D,4A,92,D3,38,2B,97,9D,DF,F7,A2,DF,DC,39,CF,EB,AD,9B,CE,46,F7,99,81,6E,0C,12,AD,EA,4C,11,B6,3B,28,D4,0C,F4,87,26,57,78,E0,52,F5,B6,A1,0D,98,31,35,62,EB,E6,2C,32,2F,49,56,E4,05,67,A2,11,C8,BF,22,8A,44,67,26,07,89,05,30,A1,85,03,91,3B,39,88,5B,D8,62,FD,B1,AC,E8,D0,CA,5D,A3,29,D3,D9,4F,26,A9,D1,B0,48,31,84,32,31,1B,63,A4,34,88,DC,73,3E,AD,DB,81,4C,AE,E4,E7,12,0A,E4,1A,3A,11,F2,ED,16,2F,22,BF,91,45,F7,55,74,66,8B,D2,68,57,53,37,14,BA,E8,62,2E,AF,23,22,03,55,DB,3D,C8,F5,D5,2D,2C,48,BC,78,E7,AC,25,A8,4A,36,D6,EE,34,3A,63,93,E1,94,2A,15,87,EA,AB,65,80,A9,18,FB,1E,08,46,99,76,9C,CF,15,B6,4A,69,4E,80,8D,78,82,56,4B,5B,6E,AA,87,60,8E,9D,98,16,46,34,DC,EF,47,88,72,B2,6C,A9,50,E0,BE,FA,49,6B,45,14,34,D9,03,31,8A,E0,8B,97,7B,F1,74,F9,45,29,8D,0C,C1,76,E3,76,0D,30,93,EC,48,28,D5,9A,FF,7F,61,94,F0,09,DF,00,51,DD,FC,0C,03,22,9A,E1,ED,70,D3,C8,D9,1D,42,73,E1,EE,77,C4,FF,61,D5,04,5A,F9,13,08,AE,1D,81,10,DE,F9,07,35,26,EC,E3,CB,D2,40,A9,31,E0,1B,25,27,5F,C0,32,CA,7E,18,B5,B3,B8,51,2A,86,2A,0F,16,A5,7E,10,93,B1,E9,F4,64,7D,07,75,D8,02,9F,B3,48,AC,C2,E2,84,E7,AB,C4,1F,C9,74,94,38,A0,38,95,20,0B,14,9D,5F,A8,B9,4B,BD,EE,60,54,0B,30,00,DB,FC,70,29,8D,E8,7B,29,A9,E3,F5,3B,98,8B,1A,B5,AF,BD,5E,D0,71,BD,F8,56,19,07,26,B4,0C,05,78,A9,49,62,62,DD,C7,7B,C6,EC,72,F8,CA,61,7C,50,3D,D0,11,60,68,2C,95,33,E3,3C,66,2D,A4,4F,D8,B8,67,10,8B,9B,CA,7F,CD,FF,30,FC,3C,D6,8C,72,CC,C3,38,12,39,87,69,D5,DA,F3,4A,FA,BB,E0,EE,D3,AB,69,7C,83,2E,A0,07,2A,F3,5A,5A,3C,3E,0A,5A,D7,5B,64,7C,B3,63,2C,23,F5,9E,BF,C7,B0,DA,D4,67,54,46,01,D5,C9,6C,AA,32,A4,28,A5,6F,99,DE,62,6B,1F,C0,05,2E,21,8F,9E,0D,AB,40,BB,F1,7A,5D,6D,22,3F,90,69,61,88,B1,DC,82,FB,6C,70,6D,5E,AD,8A,70,16,E2,D5,5C,F6,C6,95,54,0A,99,82,24,88,3C,E1,CF,96,18,05,64,1B,01,BB,36,36,0B,A2,E0,22,FC,7A,87,9E,13,B5,28,2C,E8,8F,41,BB,61,08,80,9F,DB,78,BA,1E,7D,CE,D1,10,6A,C1,AD,61,00,94,48,14,14,C2,15,42,51,81,B2,88,5F,8B,E8,5A,75,AC,08,75,8C,82,EA,2D,94,22,96,8E,E4,CC,0A,89,8C,42,E2,17,0B,CE,A9,06,6F,E0,CC,79,86,7E,6F,EF,9A,CB,DC,B5,C0,CD,65,FD,63,A2,66,CA,16,BB,F3,B0,40,CF,D4,C8,9D,DF,95,A3,8E,10,8B,96,73,F7,B0,C9,26,96,CA,40,5C,9A,C9,BF,07,32,89,18,F4,9F,6B,E2,AD,DC,F4,CF,D6,BB,D9,52,F5,F0,38,1B,35,9B,B5,CF,67,2B,D8,17,EB,74,61,F6,9A,6A,8B,48,75,9F,C2,CF,E3,80,10,7A,63,1C,F0,31,E1,09,8A,76,43,30,72,E1,2C,A5,3D,C8,39,CE,DE,8C,16,A0,E4,15,E2,94,C8,6F,19,17,FC,EB,EF,26,BE,AB,F7,F1,EE,65,2F,87,F1,8A,0E,34,46,DF,3B,8E,89,B1,17,EB,02,CE,5D,C7,EF,9E,52,FE,B5,E8,9E,6B,87,F9,A9,2E,AA,46,A9,C3,69,D8,12,05,10,B1,F5,DB,0A,05,21,AB,D9,04,D4,5B,C4,5B,3D,0F,FE,B0,5C,3E,87,A3,53,06,4D,E3,DA,30,41,31,3E,AA,DD,4D,8F,AC,48,71,EE,7F,CC,3C,AF,87,CB,AB,BC,73,B8,52,FC,61,66,A0,9F,1B,AA,B0,60,39,09,BB,38,CB,8D,92,8E,3E,B1,9A,B6,F6,B8,26,D0,FB,B9,B5,5F,29,AD,5B,DC,0B,8E,BF,58,FB,CD,C9,0B,2A,3E,20,0C,16,8B,CF,31,EF,55,BE,06,F0,C5,13,35,0C,55,69,73,BC,BD,03,E9,AB,FE,D5,94,56,9B,D2,2D,DE,F9,31,66,92,F1,9D,E5,0E,4E,28,AA,DB,24,18,42,CE,CC,3B,CB,36,F3,4E,DE,4D,EF,05,6B,19,B8,06,56,62,37,0D,60,10,8B,7E,1B,3B,E0,78,13,8F,4D,0C,D9,60,3A,D1,A2,85,C6,27,38,25,93,3C,A9,FE,DB,12,9F,EC,47,8B,CB,29,66,DA,A9,F9,AA,63,4D,A5,40,F0,43,96,5D,21,D4,B6,27,0B,E3,29,C6,74,D8,D5,18,64,F4,CE,1C,1D,47,8A,CA,56,26,BF,31,42,5F,99,CE,6B,4E,5F,86,CE,E9,E5,17,94,63,5E,12,73,6A,DB,D9,EC,39,C8,9E,90,B1,5A,B2,D2,C0,AD,3A,59,F4,06,91,98,8A,55,D6,2D,80,D7,05,D9,F3,03,AC,68,2D,5C,7A,57,3A,1B,43,D7,6A,AD,AF,77,F1,AE,5D,EE,0D,A4,70,15,48,80,ED,93,F2,D5,46,DD,99,6F,62,65,AC,B1,AB,C1,35,A2,4C,EB,B0,00,7A,24,DC,00,B5,2E,0B,72,E2,2D,68,A4,99,0D,27,1D,C5,81,9C,D1,5D,42,16,80,5B,1D,F9,3E,25,35,D9,0D,DA,B8,18,D9,96,7E,9E,35,22,95,8C,83,4D,46,9F,52,FE,D5,50,4E,39,50,29,D3,A3,BE,9E,B6,F7,99,61,96,82,2E,3B,31,28,47,3C,0C,97,43,C1,9B,7C,C7,6D,AD,7A,5F,0B,0E,F3,AB,A6,BD,4A,5D,0C,20,5D,81,B7,9A,95,73,81,A9,7A,8E,FB,8C,3C,B2,0D,D8,3A,F1,D8,0E,4D,D5,98,F6,77,E8,3A,69,0B,1D,0B,97,4C,BF,47,F6,2F,A6,E1,2E,B4,F1,4D,99,2A,C4,8D,89,BB,EE,8E,D2,EB,1E,93,EC,60,E8,11,CF,88,2A,37,AB,12,CF,7B,9F,9E,A1,91,78,F0,0C,B3,61,B3,FE,FD,8A,C1,43,5E,1F,6E,D8,76,5D,59,7B,00,0D,1B,68,88,2F,16,C3,47,33,C1,0D,6F,28,8D,89,1F,1F,32,E4,AF,21,21,4B,CC,F6,AE,30,1A,F5,B3,4B,26,B9,5F,81,FE,E9,4C,2A,D1,D4,76,10,56,EE,8F,C4,D1,D6,E3,0F,DE,B7,A7,FB,94,A3,21,1E,AC,44,8C,FC,FB,BA,8F,68,40,01,0B,0C,5C,54,2F,26,E3,F2,A4,97,53,51,EB,FF,CD,74,99,8D,B5,61,2F,49,A9,0A,E8,24,59,7A,42,BA,7A,E8,95,19,C9,53,6A,1E,B8,9F,16,58,40,0A,5E,F2,95,9D,1C,3C,4B,48,21,DE,AF,31,37,D8,60,7A,B1,2C,51,11,00,7C,F9,04,2A,29,B2,DB,60,F3,B5,20,B1,BE,91,26,02,09,95,F2,2E,40,CB,03,05,01,57,B7,2D,7F,2E,E3,A2,D0,93,45,75,2D,10,B0,19,61,DB,12,0C,45,40,E2,F6,01,28,60,43,65,1B,EE,70,4A,D4,B6,17,86,BC,B0,78,AC,30,9D,60,FB,2D,FD,68,BF,01,E8,D9,BB,B4,F4,4A,FA,73,7C,FC,91,47,6C,FC,A5,7D,51,E6,C5,BB,44,4D,0F,F8,59,6F,D8,BF,3E,86,D6,5F,7D,12,D0,AB,1D,11,7E,B1,51,D3,D9,17,53,5B,AF,00,04,D4,DF,E8,91,65,67,02,74,A8,90,5C,78,12,27,6A,7B,10,23,7A,D9,EE,FE,41,53,FB,6A,6E,9F,45,AB,8B,94,84,15,3C,8E,51,3F,66,73,57,6B,63,74,26,B3,4F,EC,08,41,A6,B0,8B,2E,80,9D,30,B6,12,13,49,5E,CC,6F,45,33,4B,0F,F8,FE,2B,3A,C1,D5,07,18,4F,07,F0,33,22,EF,5D,DD,4D,D3,BC,97,16,00,25,1E,2E,B9,0A,2D,59,8C,12,85,EF,6B,93,7B,9A,88,8E,AD,CD,D3,CB,85,8B,DD,9C,FA,01,3A,FE,F2,AF,81,E4,43,7D,38,22,AF,DB,A5,05,0C,F9,F7,E9,09,83,84,5E,AB,AC,4A,16,46,42,8E,E7,42,72,F0,A3,A6,7C,CE,AF,64,82,A8,ED,20,D5,7F,67,3B,0F,73,B7,15,EA,44,E8,7B,D1,B6,F3,EE,E0,D3,8E,DB,B8,8E,4D,88,24,DC,4C,6A,C3,53,DE,40,29,CE,12,18,B6,9F,AE,43,26,A5,59,5B,CC,A7,68,00,AB,2D,AC,45,A0,0E,DB,1C,67,96,3E,4D,AB,70,48,AF,3A,EE,02,CE,DE,A6,2D,4A,86,55,BE,99,21,78,45,D2,33,E6,92,C2,7B,25,D1,93,CB,28,EB,8A,80,07,84,BA,3B,4C,4B,5E,4D,C7,64,E0,C6,C4,0F,71,67,73,7F,FD,AF,D0,51,E7,6E,B2,FE,37,DC,66,05,53,D4,BB,84,C4,48,F7,F0,B5,50,64,E5,F6,4D,32,47,B7,94,3E,30,52,B5,19,1B,6A,17,44,88,8F,23,06,65,D7,74,86,51,12,B2,90,B4,DD,24,4E,AA,C2,E2,DE,CC,82,CA,4B,29,9C,97,8D,F9,F0,BA,13,D2,98,0C,97,7C,80,67,88,CE,35,43,F5,CB,EF,91,26,EB,11,7E,E7,3A,6E,02,EF,38,2A,FF,1D,02,75,33,8D,51,3B,01,6B,34,92,20,1C,9B,99,23,04,65,03,12,5F,07,D2,0C,7A,0A,06,04,AC,C9,9C,C2,40,90,C8,EC,54,D7,CB,6D,C0,E6,E4,85,5E,38,6D,5E,26,2F,2F,40,41,2B,15,4E,16,D4,99,70,B9,80,D2,CC,60,29,1B,9C,E0,1B,4A,47,C4,01,CB,52,30,D2,2B,34,89,D6,FB,43,B3,DE,C1,CE,74,AF,FD,B7,AA,93,F6,CE,AD,AB,8B,A3,5E,1F,C2,73,D7,1E,8C,B2,B7,A6,DE,0D,6A,25,64,64,55,DA,EC,E1,CC,9F,F5,BA,7B,CB,E1,0F,C7,E3,D8,21,8F,86,AD,16,4E,BF,F5,AE,02,A0,7F,AF,0B,72,92,F7,84,46,32,70,FA,FC,A7,5D,91,55,92,4C,5C,E6,1C,6A,B3,8C,3E,B0,35,8E,FD,45,04,7D,17,2D,C1,A8,FA,32,55,95,A0,50,AE,72,6E,5B,09,DE,81,03,55,AA,29,DC,CA,B1,9E,A3,77,78,CC,96,49,19,E2,32,AE,9D,02,1E,CE,95,AF,37,D0,5B,F3,D9,A7,99,30,97,72,16,51,B3,E0,D0,88,39,BC,E6,CC,30,F4,82,4A,73,5D,27,BB,A7,5C,26,69,AE,A2,6F,0A,A9,C2,D3,76,AE,6E,D6,24,A5,85,8B,F8,F2,D9,6F,2B,53,E2,E2,51,FB,83,54,46,D9,0D,EA,D1,80,14,D0,B9,70,E2,7E,BA,DF,CF,2E,41,0C,28,75,7C,19,AA,65,92,7F,30,BF,12,96,D4,3C,8B,AF,88,19,36,24,F4,B3,E2,A6,A6,12,A3,57,7F,2C,69,E8,91,98,BE,17,3C,1C,17,C0,45,88,9A,6C,47,84,D2,58,A2,57,5C,E2,D5,F6,39,CB,5B,63,24,DC,81,91,59,0D,96,FF,66,46,77,BA,8A,C7,B7,96,FF,7E,2D,6F,AF,27,FB,17,79,5D,3D,20,50,6F,50,A0,96,A8,65,2D,35,E3,99,DC,3B,8D,08,CE,88,86,62,96,C1,9B,EA,FE,B1,3C,67,00,B5,42,2B,F1,F5,A7,9F,FA,11,0A,C9,EF,06,56,46,22,47,A3,9B,EB,9F,44,11,BE,AB,DC,0F,5E,F0,86,CB,C8,3F,85,9B,16,8B,4D,B6,F7,B1,E9,F1,86,A7,40,0E,27,77,FD,7C,7F,66,DD,3F,43,DB,B3,50,60,0C,DD,44,A2,AE,80,60,3C,9E,70,6B,B7,0C,25,C7,0D,E3,37,B5,B9,50,80,6F,B4,11,59,09,4E,0E,19,16,07,8A,F3,A1,C8,55,74,D2,9F,0B,9C,C7,95,5F,F9,E2,83,E1,64,85,84,9E,36,15,2C,EB,35,70,3C,96,81,02,82,D9,46,61,57,26,01,1A,BE,E9,2C,0F,B1,05,30,05,A8,D0,72,42,9B,AA,00,53,23,82,1C,6B,81,AB,9A,E2,44,58,5F,CF,71,7C,76,C6,AA,B6,48,17,B3,C9,5D,D2,B4,96,0D,2E,A2,E9,C7,DF,65,34,04,37,B6,42,0D,C0,67,6C,CC,5A,DD,CA,9C,5B,69,CC,A6,21,63,D6,FC,0D,E6,25,A5,C2,9B,8E,34,FA,C2,A5,EA,15,C2,CD,49,F4,7D,49,CA,5C,33,D0,AF,EF,31,69,F6,60,6C,6C,BC,7C,F4,C5,28,88,54,04,C1,03,1F,C6,1C,CA,AC,61,30,0B,98,3D,6D,AF,9B,62,EA,67,FA,DC,43,91,F4,A0,CE,73,09,49,BC,D1,90,D9,A4,54,F7,E6,2D,C8,17,46,C5,65,44,D8,C1,E1,79,B3,7C,64,A8,9D,8C,CE,AF,7B,65,2A,5A,DE,F9,52,AB,2C,85,F1,78,B8,2B,81,3B,2A,07,AD,0C,8B,D6,88,79,8A,BC,B3,4A,35,9C,73,54,AF,2C,DB,B4,7F,B6,EF,30,B4,75,D7,23,14,B3,BA,B9,AD,F8,5A,66,DB,D0,5B,88,22,3C,63,90,AC,E3,CB,95,51,C8,3B,86,C4,79,92,A7,7A,DF,6D,CE,A2,FA,0D,D6,C7,0D,E8,EE,0C,1C,42,80,6C,48,FC,6A,07,E2,3A,A5,6B,92,B8,8D,65,49,AC,03,7D,CD,16,BD,1B,71,05,69,33,CA,E0,58,F4,4E,60,A6,9A,1E,69,47,7D,3E,35,96,80,5C,EB,80,CC,B8,C8,84,0E,00,31,30,40,18,96,40,02,8F,2F,C3,B4,26,27,12,C5,2A,28,94,32,E4,5A,FB,E6,98,E2,AB,21,0C,FF,E3,60,50,FF,93,EE,2D,27,47,41,88,4E,E7,E6,86,C2,7E,39,21,FD,19,DC,EF,B3,3F,B5,1F,AA,4C,D4,07,0D,85,0B,42,0F,47,FC,EF,4F,5C,36,94,93,C5,3B,74,F7,EE,0F,D4,A8,E9,84,90,4E,C5,99,FD,D2,73,9F,16,9C,65,EC,6A,02,04,93,65,61,CD,52,A9,83,9E,88,02,EC,6D,D9,8B,1D,38,8D,0C,18,63,7D,06,B6,C3,6B,BC,57,B8,8E,A0,25,A8,E7,60,37,4B,EB,E9,84,24,1B,6A,70,4F,D3,AD,F7,4D,42,2A,32,FD,8F,7B,21,FE,55,2A,F8,1E,3D,97,D5,77,AB,81,AE,A9,3D,69,6D,AC,54,59,3B,36,92,81,77,56,5C,27,25,AC,85,03,D2,30,60,50,99,49,3C,9F,74,AD,6D,07,94,63,18,20,69,AB,99,60,93,47,05,01,4D,9A,8C,73,97,04,4B,67,9F,EF,3D,A5,07,71,66,BE,D3,55,D8,69,16,37,15,85,09,91,81,75,F5,EB,B6,59,D0,D9,59,CB,CB,C8,13,DC,E9,86,DF,1C,62,C7,25,9E,4E,0A,4D,79,89,BB,7A,93,04,06,FA,E3,38,D3,76,A0,95,B4,AF,15,71,A9,C5,FB,8F,52,34,C1,EF,47,8C,35,D5,02,99,D1,0B,C2,A2,A0,4B,5A,78,0E,16,5E,9D,26,A3,18,4F,25,10,30,4F,2E,DE,DB,CF,A9,DD,66,32,98,34,6B,6A,7A,12,82,82,60,23,F1,91,A8,B3,9B,6B,4C,50,CE,A4,61,CC,8C,C8,5A,C9,7A,C0,F1,78,F4,46,7B,92,BE,C3,1A,2E,7C,27,D1,28,6E,47,AE,AC,90,1D,DF,AF,88,17,8B,46,79,34,D3,74,E5,68,49,D4,52,D7,C7,13,BE,AD,80,AF,DB,5F,C9,08,D7,49,98,58,5D,79,DA,67,36,96,B4,A6,EA,AF,B1,04,96,00,FD,D7,C5,CA,18,4E,B4,43,79,50,26,D7,AB,A9,EA,9E,06,88,20,F4,62,F2,15,EF,C7,A4,21,2A,FD,35,F6,94,A4,15,E6,1F,F0,0F,A6,DF,FE,FB,17,9C,1C,E9,82,AE,B1,57,7C,83,DE,8E,FD,EE,0D,ED,84,1F,78,60,46,03,12,5C,B9,19,1B,16,37,C8,0B,7C,90,CC,79,A6,42,D7,55,5F,69,71,CB,71,EC,AE,E3,43,DC,7B,0A,A1,5A,EC,6C,F0,FB,C4,43,00,29,3F,25,52,32,C8,80,0B,95,1C,D0,0E,3B,D4,F2,4F,0B,1C,EB,0E,70,8E,98,2B,26,D5,9C,05,D7,86,E0,C8,4A,0D,3F,6A,A5,EB,B2,B3,90,32,BC,71,23,1E,07,F9,43,46,93,3C,A0,B2,92,E6,B5,24,0E,D6,B4,9B,67,A5,96,7A,43,24,E9,D0,EA,52,81,9D,49,B4,12,7D,16,54,AE,20,8F,0A,51,13,F6,42,ED,60,5A,3A,20,7B,AA,30,F2,50,76,0C,16,E0,DC,2B,0D,74,82,E8,8A,F7,0C,C6,59,58,41,93,E6,3C,6E,57,9E,BF,25,4E,89,A4,54,34,F0,45,4A,DD,25,80,15,1A,73,44,D4,53,2D,B9,EC,05,FC,FA,BC,3E,7C,6B,DF,BD,4E,5A,89,18,B9,CE,C9,56,FA,EB,70,60,39,D0,98,83,19,00,59,D8,8D,07,EE,44,06,BC,5C,EE,0A,EC,B2,2E,6B,B6,10,A0,24,56,D3,55,2B,4E,20,BA,E8,8D,72,7A,5F,97,3D,6A,57,A6,60,60,77,BC,1F,7F,B7,2B,48,BF,58,D1,85,3D,E1,A6,E7,EE,D0,58,F3,89,D9,7A,74,8C,61,85,76,01,5C,66,9F,5A,F4,BB,97,24,A7,78,23,DD,F3,B1,94,05,4D,49,5E,E6,7D,5C,23,59,13,D5,C4,7B,7D,FB,D9,92,FE,6E,10,CF,A0,21,A0,05,AC,E4,FB,97,52,42,B4,78,5F,61,63,45,D7,79,94,C9,13,FF,92,14,04,E3,BA,A4,B2,3D,27,63,C7,8F,C2,67,CA,A0,FC,6D,13,09,59,1B,4A,98,3E,7E,7F,FC,EC,63,6F,54,53,69,DB,2B,9D,9F,59,11,6B,47,0C,D0,F3,1B,BF,56,02,1C,E4,1E,75,36,61,80,2C,93,CB,D7,5B,54,2F,1F,A2,EC,BF,AC,8D,39,5C,A3,31,1A,D2,5D,2B,66,30,8F,18,25,F2,BC,DD,75,18,B2,BA,74,4B,AC,16,6B,72,0D,C4,20,05,33,F1,FD,EE,3C,B2,EF,16,27,03,A3,9B,A7,72,33,98,ED,EB,43,CA,CF,F3,FA,C1,F1,F2,4F,40,7F,8C,6E,40,81,EA,76,49,FC,73,FE,08,AC,EF,17,B4,16,A8,88,84,0A,C1,A5,01,07,7F,23,8D,F9,DF,06,3B,5C,10,31,3C,83,13,73,F7,47,B7,24,65,35,75,0B,6A,27,AD,1D,46,C2,0E,39,F5,B3,37,23,27,17,C8,12,D4,90,0B,D8,C8,B0,1F,0F,F8,01,FE,A1,77,6D,27,20,1E,8E,00,0D,B9,0B,5F,91,CE,9A,7E,7F,2B,05,37,85,B8,1A,9E,44,03,12,0F,26,14,11,E7,9E,F7,15,22,C3,43,53,D8,77,1D,2B,B1,BF,A6,3C,2A,01,1E,5B,E0,9C,00,B9,36,22,3D,06,24,52,D2,C4,83,0E,86,E2,12,C0,C1,5D,20,E8,03,DF,53,B9,33,60,6A,E4,D2,22,28,DE,C9,8F,31,12,F7,19,48,20,1C,DB,9F,34,D6,C7,A7,D0,D1,AA,6A,F3,92,22,74,E6,CC,BE,BA,A9,05,B4,D4,49,59,78,3C,D5,70,AA,0D,9E,EA,7C,04,AC,E7,0C,D3,99,F5,AF,6B,00,BE,43,72,99,12,0E,0C,EB,04,5A,66,BE,1E,AF,A6,E8,43,C4,D8,57,0A,6D,2E,C1,30,D8,35,70,50,79,BA,9A,7C,C4,6B,F0,DC,9F,20,37,48,91,33,88,9F,4F,0C,93,C2,0A,3A,06,C1,12,C4,68,DF,A6,89,A9,F0,C1,C0,90,35,4B,D6,E7,0F,03,3F,0E,81,D4,F8,42,F4,83,DA,B6,63,4A,49,6C,72,D8,E1,E4,1B,9C,F8,66,A1,F6,27,B4,3A,19,9C,B3,8B,12,4F,2B,B6,10,8D,AC,B0,54,FE,A7,6A,AA,07,FF,13,6F,FD,69,EB,B8,DE,5C,0F,14,4E,6A,CA,5A,1F,8D,F0,AB,23,6D,F8,25,FF,4E,B8,4F,97,DF,CF,44,98,08,0D,6A,0E,E7,E8,7E,A5,31,C0,0F,8C,7A,FC,36,0D,DE,28,57,96,1B,F8,C9,CD,89,8C,DC,EE,EC,09,4A,70,40,EB,67,AA,A2,88,D9,B5,60,9F,F8,B7,5E,87,59,6B,BB,2F,26,2D,89,82,F0,5D,CC,59,D4,44,7E,D7,14,A6,C1,3C,5D,9C,AA,14,4B,41,D9,25,8A,2E,7D,79,15,D5,D2,05,A5,F3,54,B6,E8,F8,CC,61,AF,0E,C1,75,9D,89,12,D0,9D,A8,49,FF,6E,A9,33,0D,82,72,B1,AA,69,54,D5,29,6A,AE,DA,91,B7,CB,DB,07,63,E8,95,6D,D7,0F,F3,5C,13,D8,38,76,29,41,E3,A0,73,CC,C7,F9,C9,9A,17,99,BE,74,5A,04,BB,05,58,5B,A1,FD,61,4E,AC,30,18,32,78,76,6C,37,8C,FF,0A,FC,AA,D7,A8,D0,D3,76,86,D0,48,B2,46,09,A7,8D,E3,10,89,FD,27,45,0A,DE,05,DB,9B,08,F4,36,46,1E,B8,F0,11,C9,D8,B1,5B,1E,CF,FA,79,F4,20,54,58,26,BF,CA,26,AF,F0,00,FB,57,BB,BE,19,AA,23,6C,84,D4,2C,D3,6E,1D,69,36,DD,F2,99,D6,36,A7,D6,D0,66,4A,2E,1E,D4,37,C8,A8,C9,23,3F,A6,D8,E2,CB,0D,1B,F5,F0,C5,81,F3,26,7C,47,C9,F8,D9,9B,4A,27,D3,AE,5F,9B,81,36,7B,B2,2E,6A,A7,1E,C5,99,2E,01,FA,77,BD,08,5A,6A,54,8F,CF,0B,B1,3C,FF,23,BE,38,7C,60,D0,C0,25,4A,EA,4F,4E,F0,89,5F,93,43,36,A7,15,EE,0E,AC,EB,BF,C5,07,98,92,4F,C7,6A,1B,F9,BE,2B,75,CA,1F,07,D1,DE,18,CB,41,BA,B1,E8,64,2E,D5,B0,34,A9,A8,7C,D7,E3,5D,49,65,0D,06,4A,80,5E,E9,F9,03,CD,31,D0,94,42,79,3B,C1,FF,98,7F,37,31,45,AF,94,FC,EA,96,23,D1,95,39,F4,53,59,9B,CA,85,E3,6D,81,16,4F,98,7E,AD,C7,9E,AD,9A,A1,AE,B2,2F,A2,D6,AA,15,02,51,5D,D2,CA,25,5F,92,6E,1C,67,A7,0E,66,8E,D3,D1,A5,FF,96,6B,09,0D,4D,CD,14,40,C8,38,53,F8,D5,42,B5,3C,FD,71,13,4F,AF,6E,B0,4F,0D,2E,BC,02,FE,56,59,97,A9,D5,84,D4,3E,A2,A9,A5,55,2D,9B,DD,20,69,BF,CE,57,12,20,5B,EC,E2,6D,F9,0D,C8,B9,06,C7,43,97,A9,1B,8E,1C,2C,B1,45,F4,F6,B3,CE,5A,9B,B5,2D,2E,27,47,AB,06,92,EF,6D,D0,8E,34,A4,0C,55,0D,CE,C2,A6,D7,D8,0E,9D,1D,9C,B2,84,22,A5,75,2F,FB,3F,E9,42,31,A2,28,F4,7F,3F,2E,0D,B7,C1,87,2A,77,12,75,E4,A6,AC,C2,46,AF,13,C8,12,4A,CA,99,DD,1F,5E,2D,28,D2,46,00,B1,A7,50,31,FF,4C,93,75,19,42,EF,F3,0A,76,CE,47,1D,26,51,86,ED,D4,56,31,4A,E5,7B,B0,7B,82,ED,0C,A0,35,28,9A,E8,76,10,BF,55,5B,A7,A5,BE,6A,11,46,41,5A,9E,F6,7B,96,B7,1E,63,99,06,FF,B4,CC,22,82,A4,A6,C7,CF,57,40,22,8E,A4,34,6D,77,57,FF,DE,1D,ED,D4,69,F3,95,93,C5,18,B3,70,02,4A,C7,14,8E,26,EC,6E,E1,59,CC,0D,D4,7D,E4,8E,40,2B,5B,01,DE,B7,8D,49,35,D3,43,FB,3A,17,A9,CF,51,D7,27,7D,A8,ED,66,DA,EC,A6,73,07,E4,AC,FB,E8,2A,C1,38,D9,AB,4C,08,07,4D,A6,22,1D,40,BE,F2,39,96,BF,B6,74,6E,B3,B2,E6,16,34,66,16,EF,0F,A6,EA,65,DC,28,3C,FE,3F,39,67,9D,A0,A2,2E,D9,C1,D8,AA,B4,C4,89,ED,7D,1E,48,0B,82,45,15,1F,88,24,71,0C,62,D0,62,9E,F5,AD,6B,95,65,12,46,DA,59,F4,49,FB,11,93,BA,6D,AE,72,9B,B4,DD,F2,02,FD,31,AB,95,08,B4,D5,2E,4E,57,A4,67,77,D2,86,DB,42,5B,34,E5,43,EA,86,11,75,A2,72,48,1B,B5,C6,1C,5D,A7,B9,D0,C4,15,4D,80,97,4D,30,2A,42,58,2D,9D,22,63,D9,5D,79,6D,C8,40,C2,37,AD,3D,FB,82,1D,84,6C,8D,3E,51,71,AE,F1,A7,7F,70,45,4B,9D,50,B2,7A,18,A3,BD,FA,EF,A6,7F,F6,46,29,39,D2,B6,C5,6B,94,C7,01,5A,2E,C5,88,8C,7B,20,67,3E,43,AE,CF,A8,29,FD,A0,EE,EC,04,88,39,C5,1E,D2,35,C2,FA,8E,53,34,35,B1,93,4D,63,C6,01,6F,1F,8C,BD,99,34,A6,9C,93,FC,B8,FE,54,5F,13,5C,6C,D3,51,95,6A,EC,A8,F0,6F,C4,B5,41,4F,5B,EF,E3,FB,C0,19,FB,70,72,FA,33,CE,F3,09,E8,9C,51,34,4B,59,8B,A7,67,E2,FD,EE,3F,9A,DA,2B,A5,C1,2A,00,CD,96,C9,1D,77,F3,30,86,6B,A8,62,6A,73,8D,88,1F,7F,40,23,91,0F,EC,48,85,CC,24,18,69,D3,ED,4B,7D,C0,E6,FB,D7,F7,C2,16,8D,59,96,95,53,3D,49,6D,19,55,01,96,68,80,37,65,80,C9,AC,04,3D,11,04,D8,6F,91,2A,89,C1,47,20,D8,C1,8D,E1,7B,58,80,B5,7E,D0,32,5D,03,80,8D,10,A5,A0,32,8D,7C,59,F7,7E,4D,5D,52,75,A9,F2,1B,13,7A,14,9F,0D,36,65,78,15,E9,C3,11,4E,3E,A1,3B,EE,FA,7F,77,00,DB,0E,2E,B4,7A,01,FD,D7,FA,85,BE,02,5E,8A,08,0A,1E,15,71,D5,16,C2,A7,78,0F,EC,09,43,45,B0,95,19,57,2D,78,AD,5D,F4,5D,37,9B,25,BD,DF,1C,93,35,5E,08,12,AC,95,DF,42,3C,99,C0,71,DB,56,F5,F5,1D,6A,78,50,FD,F4,9E,52,CE,B7,2C,66,C1,61,B3,1F,5D,62,74,55,90,95,06,CD,9A,6E,AD,A6,0C,BB,20,DC,3C,70,F6,C1,1B,2C,94,B7,2A,5D,7A,C6,E5,D7,2E,A8,36,15,26,F1,57,28,20,E3,5C,25,88,28,5A,8E,A3,0E,5E,9E,1D,03,56,AD,EC,CC,A0,4F,53,EC,CB,33,D0,35,E3,64,8E,61,22,3F,2B,E2,C0,4D,85,BA,4D,A5,33,34,91,4C,CE,5D,4C,10,01,4F,3F,85,CA,2C,43,E2,AE,11,BA,BB,5F,AB,D0,87,91,60,24,95,88,34,BB,16,E7,C2,8E,04,B1,36,A0,D0,A8,A5,89,78,9B,CC,DA,40,16,EC,6F,7E,25,FA,68,81,1E,33,CA,66,F1,FE,AC,CF,8F,A2,D3,29,D0,7E,19,02,4E,B2,B1,C0,C1,BD,8E,51,B8,C1,16,FC,DC,25,FA,F5,97,0D,DE,16,95,3A,1D,F6,77,F5,1A,53,DF,AB,2B,01,19,E7,5C,75,D4,1F,44,EC,5C,2F,CF,49,CF,A3,37,3C,6A,DC,33,2F,C9,F0,E2,BC,A6,80,61,97,6A,E0,44,B4,1F,66,47,57,C6,64,57,B6,CF,84,0A,68,AA,E0,8B,92,9B,98,35,B0,D9,7D,2B,98,3A,EC,52,BC,8E,89,E4,D0,D1,E1,74,32,7D,53,B5,27,04,94,A0,03,0C,90,33,C4,2E,19,5E,DD,1E,58,76,CD,54,62,0C,46,FA,2E,EA,5A,AF,5A,43,AF,BB,20,78,DB,61,84,46,55,FC,78,41,31,FC,41,36,31,39,7F,BD,F9,E3,D5,D4,63,B0,5A,82,28,49,7D,58,AE,3E,36,93,DA,75,13,84,B5,95,5D,68,79,0A,F2,2D,CC,A4,69,17,8B,C9,7A,55,A0,BD,1F,EE,0E,AB,51,6B,60,14,0B,4B,89,9C,23,A9,5A,27,56,3C,FE,43,04,57,FA,03,0D,B0,41,BA,94,59,27,FF,93,EB,77,5E,E7,18,98,46,65,10,71,D5,EF,39,42,4B,3C,B1,4E,D1,5F,66,7F,19,39,86,35,08,0C,09,06,17,D5,49,0E,1F,24,7F,39,DB,8D,67,B4,80,D9,C3,E9,E8,00,B5,AC,C1,D1,3E,53,F6,7F,4F,F0,05,02,29,8F,36,22,24,8D,61,B5,38,16,72,A2,79,3E,7A,83,BA,5D,2E,9C,CA,96,F5,C3,DF,D5,BD,4E,D6,2B,CA,CB,64,F9,47,06,02,A7,43,05,D6,ED,24,32,3F,61,7C,8E,95,4E,E5,75,46,85,CA,3B,59,B0,7A,36,2B,8F,61,EB,B0,5C,66,E2,57,BB,60,E6,09,05,69,C6,60,74,43,CB,DC,23,5D,DB,C6,9F,C1,2C,99,F3,77,59,00,0D,7D,05,3E,D6,B4,45,B4,B8,C0,B7,0A,71,D4,E7,EC,02,96,4B,0C,9D,E7,4C,C9,86,24,77,17,EE,DA,BD,69,70,CA,85,DD,41,28,5D,8B,A4,21,2E,D5,24,13,20,D2,E9,A6,B4,74,D1,4B,14,14,3C,21,1D,5F,84,94,58,84,0A,50,05,E4,D2,00,FD,81,84,1B,C7,9D,83,A3,03,1E,37,E3,99,89,91,C6,37,E2,86,63,CD,94,4F,ED,DE,63,EB,F2,68,68,BB,43,B7,F2,2B,0F,F9,E2,88,36,EE,A2,B7,0E,49,65,DB,93,E1,0F,6E,CB,5E,58,A7,EA,24,B2,2F,BC,3D,6C,39,14,0D,F1,45,2E,FF,C8,BD,17,89,1A,FB,C1,4D,0C,3E,F3,1B,84,63,81,B8,8A,50,3A,A0,D7,26,DC,39,5E,E9,03,F6,DE,76,59,1D,DE,95,4B,78,4B,72,51,5F,F2,39,6B,8F,FC,A3,99,95,A1,E5,42,EB,4C,CC,CD,A5,04,47,C2,DC,24,E3,F0,44,50,EB,D6,2C,6D,BC,20,38,26,17,3D,40,C2,BF,9F,56,07,49,24,D4,90,CB,F5,A8,53,3B,47,D9,29,BC,C5,E5,C3,88,D3,9E,AF,D3,7F,4E,33,12,D7,B3,C3,28,09,7A,5B,74,B0,B3,34,61,70,86,A0,CA,7C,DF,E4,24,E7,7A,03,67,CA,8C,C1,7A,45,DA,B3,F2,6E,1C,81,A0,C1,FF,2F,BE,81,69,CD,33,1E,03,54,BC,63,D2,8B,1D,87,94,37,FF,8A,D1,9A,FE,4A,D2,06,ED,9A,2B,E0,1B,54,7A,55,19,2D,B0,9C,80,A2,39,FF,51,84,53,E0,0F,04,76,6D,D1,5E,B9,39,35,EC,50,9B,B2,27,97,5C,4C,8F,46,BD,E0,63,7C,4E,3A,0F,37,75,C4,AD,91,10,47,98,C1,C3,BD,B2,74,81,C5,2A,72,3A,F0,A4,9E,64,DB,55,A9,EC,20,81,33,5B,36,4F,C2,B1,5B,FD,70,D6,76,43,D5,95,08,2E,83,F2,96,3F,9C,5B,83,0D,03,2C,C1,A6,BA,F3,14,76,E6,19,8F,59,99,E1,B4,CC,AA,29,DB,06,ED,3C,9C,F0,59,96,E0,FD,33,D5,89,EA,C2,23,47,6A,0E,68,B3,82,26,08,5B,6F,76,D3,8F,14,01,8D,3E,B6,C7,F9,A5,DE,75,99,29,41,75,13,26,D9,F8,C1,71,1A,9F,C9,9C,77,F7,99,71,E1,16,82,46,60,55,10,51,B1,1B,5B,12,83,72,6E,C5,E3,CC,C3,44,7C,B9,37,9D,CE,C8,F8,9B,63,0C,94,CA,FA,7C,C5,23,B4,7A,68,B5,6C,EA,A3,84,6A,5D,77,67,38,A8,C8,DB,4D,FB,9E,DB,4A,CC,3A,EF,89,6E,C6,48,06,43,0D,AD,FB,9F,72,67,D9,24,AA,DF,94,FA,63,3E,74,02,11,C1,FD,A2,31,5D,ED,16,73,51,91,50,AA,8A,10,D6,50,BB,38,C6,46,09,6E,43,D8,1B,9B,08,D2,34,34,14,4D,A1,47,A0,B6,53,96,E7,FA,0C,BE,FF,C1,02,29,C9,34,14,10,B3,FC,7A,85,0A,AB,5B,BF,7E,25,25,91,33,68,5E,69,E8,BA,32,A1,5C,5C,B0,BB,BD,0A,94,12,4A,30,13,C9,05,EC,9C,6B,AB,F5,9B,B8,90,90,0A,4B,4D,74,53,AD,1E,C3,94,A1,8E,3E,8A,A4,D5,87,F3,7C,00,1F,64,6B,16,F7,F4,F6,20,39,4C,BC,10,2B,43,75,F9,51,DD,CA,50,11,FE,81,AA,40,AA,B4,86,D9,0A,01,84,95,4B,56,08,0D,53,FC,4E,FD,0B,A6,4A,D5,FA,8E,59,5C,67,BD,FA,98,97,85,89,36,13,A7,9E,0C,B2,6C,95,21,18,93,5B,9A,E6,75,A9,4E,06,AA,79,D3,AD,C3,15,2B,00,00,03,1D,07,0A,DB,B8,94,28,F8,93,07,84,0A,E6,5C,CF,94,62,FB,84,B1,ED,A3,3B,C3,96,2D,3F,4D,A3,A2,68,FE,B7,B6,32,D5,FB,15,05,A2,42,71,57,8B,68,8E,87,52,80,ED,D4,30,05,33,EC,84,35,3B,CD,F0,66,56,A1,09,84,15,A6,96,5F,00,B2,15,0E,7E,5A,0F,2E,55,CF,B2,DD,97,BD,19,62,57,49,D9,7B,F0,19,6A,16,07,D1,43,01,C7,86,73,BF,91,8B,CE,8D,E5,C9,B5,F6,E9,4A,3A,59,A5,4D,82,65,BA,30,49,6F,6E,90,B1,F6,5C,DD,37,74,C4,58,71,EA,F7,D6,1E,43,AC,49,40,4E,BC,1B,A3,91,62,B9,C9,E1,1F,DC,7F,43,54,8A,C3,75,67,84,81,D5,E6,12,E6,5C,2E,53,F4,CF,0B,52,F3,AA,A3,81,4E,D0,8B,D5,F6,45,C5,26,D9,D7,5B,79,2C,19,96,AF,4C,E2,B4,81,79,86,E1,E5,D5,1A,90,CE,B0,B3,A3,22,2C,79,22,A4,58,23,05,B9,5F,B5,50,E3,46,9A,A1,31,37,F1,02,60,AA,1D,1B,17,94,87,6B,60,54,E3,95,BA,D2,44,E5,28,8C,5B,8B,A2,0C,6A,CF,3F,62,05,41,AB,E1,39,1D,2A,C0,71,78,AC,7A,04,92,B0,5D,C4,F6,A1,BE,CA,B7,41,E9,F0,63,38,4C,03,5E,5B,9F,79,23,30,FF,4F,1A,56,7F,3E,C6,0F,E4,29,51,A1,48,98,F5,10,38,BE,BE,9F,93,03,14,85,CA,95,F5,27,FC,10,F2,E8,B8,7F,44,99,32,A3,D7,97,29,7E,D8,C8,9F,5F,76,19,60,AB,E4,81,B0,10,11,F0,D1,65,94,73,33,1B,2B,F9,19,09,2F,5E,39,F2,94,FB,B5,A5,13,D8,D3,56,6C,4E,28,AA,FB,B7,43,C2,FA,76,23,AF,A5,2C,A7,D4,5A,FC,E5,33,D0,C6,AE,08,59,33,F8,5B,DE,4B,5C,21,E5,90,C1,20,E4,5E,CC,54,5F,B5,97,25,4A,71,59,5A,C2,16,50,CA,80,90,A7,1E,42,EB,CE,F8,AE,85,2C,D3,1A,B5,63,CD,3D,F1,40,9F,27,73,AD,89,11,27,39,A6,CF,28,3F,7C,D5,D9,5E,72,83,F3,14,6C,57,69,7F,A4,A2,EB,1F,49,43,52,E9,7C,64,97,19,86,BD,CF,E6,3D,DA,59,E7,94,0E,49,18,DE,F2,C4,4A,5A,98,61,A4,0D,48,61,00,4D,8C,54,67,9F,A3,9B,AD,B1,FC,FB,4F,AC,21,C4,81,52,FF,00,82,AF,FD,E5,96,C3,2B,EA,3D,37,BD,7A,80,A2,6E,9D,67,34,49,97,5A,2F,40,32,2F,4E,05,A4,C5,8F,31,A4,2B,2B,F3,79,CF,5F,8C,59,0A,CB,41,70,B6,A7,FB,EF,07,06,C6,45,12,15,1A,CE,3B,0D,A6,FC,37,8B,0B,96,B0,48,91,0B,13,3A,CD,EF,28,C7,A0,9A,EB,8B,47,41,7C,5C,F9,32,7A,EC,BB,91,1D,34,1A,6D,7A,95,5E,EC,26,FF,CA,A6,54,7E,34,33,A3,01,06,E9,CD,B5,EC,C6,59,40,BA,6D,65,BB,56,ED,A3,12,55,E3,B0,BC,7E,92,0D,A7,00,4F,B6,F0,D2,3C,D7,27,44,03,3E,79,7D,69,54,FE,2E,A4,AA,FA,4D,69,22,80,6D,38,61,4E,D6,E1,1F,70,F4,56,5D,21,7E,9B,1A,94,3A,D3,34,C5,B7,2B,70,60,EA,B4,E3,BE,28,46,22,76,87,1B,CD,12,B3,52,57,33,C4,51,81,C9,D2,EA,29,9F,77,F0,AD,E1,2B,14,81,DB,1E,61,1B,1E,10,E1,A6,D7,5E,17,48,FF,3F,4B,62,6D,EE,B8,C7,C4,26,19,40,7E,1F,F6,A0,A2,B2,13,5C,69,38,B9,27,35,B0,73,20,D1,79,C6,65,EE,47,5E,A5,65,C3,B0,3D,A5,50,FA,ED,CD,1D,BD,6F,4D,98,6E,3B,A4,65,6B,05,98,7C,E5,7F,E6,AC,4B,2F,8F,87,C0,D3,D9,09,28,89,F3,3C,E7,10,44,22,BC,94,FF,17,73,13,82,AC,51,AA,DE,29,D6,0B,3C,CD,7A,BA,76,52,38,47,68,99,A9,F2,DD,6C,52,64,B8,4A,05,C5,05,74,DE,EF,A8,9F,9D,0D,E1,B2,F1,96,05,B5,14,0C,68,42,CC,32,AD,EC,E2,39,6C,B4,4F,06,DA,B5,B6,DC,C8,F0,6C,59,ED,BF,D0,57,DE,D1,05,71,DC,8F,40,E4,FB,46,B8,4D,D4,52,8F,55,9D,10,3C,34,15,0F,7C,DC,A4,64,07,12,2A,48,D9,EC,9A,89,22,A6,8C,C4,D8,C1,12,BD,FB,FB,8D,E8,25,D3,52,F7,18,3E,AF,81,95,19,86,95,D9,57,25,43,58,08,A7,2D,29,99,48,BD,0D,D9,A3,92,39,F1,6F,74,B9,F6,8D,65,B7,ED,F1,85,2C,B0,CA,DA,BE,CB,8B,B5,AB,C1,90,31,AB,74,B3,BF,53,D5,F9,DB,1B,24,8B,CA,85,99,18,37,0C,C4,AE,7D,5E,2D,8B,35,A0,3A,44,DD,69,67,B0,1E,AD,63,92,3F,55,B4,3B,84,A2,46,65,51,22,6B,BF,7E,5C,54,21,87,FD,E1,DC,AD,09,88,11,01,8A,98,C2,E8,A9,C9,05,FB,CE,CF,94,64,15,85,D8,63,04,B4,92,39,64,E4,3E,89,6B,6A,74,E6,43,87,0D,1C,AC,14,E4,13,4F,1A,18,79,23,AE,81,7B,A8,66,E4,1D,4E,9F,25,A0,93,AE,3F,6B,40,03,95,A6,C7,53,C8,26,5A,1B,AE,52,C1,95,6B,7F,82,4D,61,2D,BB,E3,33,78,15,16,6F,C4,C6,6F,31,65,D6,86,52,A2,52,8F,30,81,03,DB,0B,01,00,2F,49,37,9B,60,74,91,B9,79,9B,94,14,24,47,7C,C8,78,6F,58,2D,74,23,82,DE,7A,1D,FD,3C,81,53,07,A3,83,07,97,60,2C,2F,7B,06,4B,B4,AB,18,47,7D,D5,76,29,EB,8C,63,DD,B5,AE,58,16,89,DC,37,5E,6A,4F,7C,45,0E,64,CE,43,AC,A5,C0,2F,D5,61,93,FB,B3,99,51,8E,BE,E8,7B,8D,63,93,63,57,77,25,67,29,6E,00,7F,F8,F7,03,9B,D8,32,0E,47,23,10,F5,03,E5,D8,F9,DE,CE,CD,18,C8,57,00,EF,85,3E,60,82,33,3D,F0,A8,5A,C1,CF,F3,61,16,5A,8D,71,45,17,08,B7,9C,70,10,B6,CE,BF,C9,B1,B5,97,15,ED,2D,42,7A,91,99,9C,72,D4,99,86,0E,0E,2B,82,A6,C3,AB,4E,B3,A6,83,18,0A,B2,F2,25,9E,08,27,6A,6F,39,2D,DB,12,BE,CD,73,17,EC,5A,3D,BE,FD,98,9E,85,FF,21,51,18,DF,A9,A5,0B,60,3D,34,D8,EB,B8,E5,09,11,C8,A6,07,18,40,DC,57,22,D7,AA,A6,AB,7C,06,31,68,B7,D6,4C,4A,D2,14,AE,4C,4D,C1,2A,58,E2,C7,6B,F8,D7,DD,39,60,09,DC,77,98,70,3D,67,C7,E6,20,13,9B,85,F1,98,CA,9F,71,7C,45,D1,3E,5F,0B,13,7D,04,95,A7,77,37,BB,40,6F,3F,CD,DE,6F,AE,E7,7D,88,74,9B,C7,8E,97,7F,C0,33,F8,E3,83,73,F9,92,D4,63,47,CB,30,91,71,70,BB,3B,7F,E2,A1,FF,E8,84,EB,93,50,A7,D1,B1,20,E8,0C,22,B0,35,37,5D,F3,CA,FE,FB,FF,4F,A5,E2,0E,65,88,09,7E,CB,CA,FB,E3,7C,88,80,25,9A,E7,B6,D9,D0,00,5C,DE,A6,D4,26,B8,0D,92,B9,31,ED,CD,80,66,13,F0,56,2C,FC,10,8D,87,4D,7F,5B,CE,2A,FD,66,95,19,F1,9F,A3,F7,AC,41,36,0A,E8,5C,03,D1,56,04,E2,6F,63,41,DA,79,1E,42,6F,8C,5B,82,10,A7,AB,6D,43,9D,6C,55,CC,FB,5F,FF,08,5E,58,67,79,30,09,F9,7A,69,21,E1,0B,4F,FD,B8,9C,FD,05,1B,9D,6C,3E,4C,F2,AD,06,91,A4,AC,2E,76,01,AF,D4,AA,D6,E0,61,8C,17,9C,F4,A6,8F,53,9B,2B,97,6F,88,05,87,A5,EC,39,4E,13,CF,E5,3D,B8,B4,E2,07,46,A1,8F,E1,F1,1E,61,A3,DD,44,71,7C,96,EA,6F,E6,B3,5A,24,CE,67,88,58,61,95,38,CC,54,5E,18,38,9F,5B,8E,5D,8F,FF,B3,D2,58,42,D8,3C,4B,A4,52,C4,2F,BB,D8,AE,C7,16,47,DE,56,C0,5E,3B,45,E3,0F,6D,50,E3,AE,D2,51,DB,02,B7,8D,22,D7,A3,56,3C,47,16,09,2F,4A,3D,1E,4B,9D,F6,17,1C,04,0F,17,EF,EC,27,EF,F6,D6,C0,4D,D5,4C,0C,F3,00,12,3F,6E,CA,E2,BD,84,16,21,6D,D3,68,42,F2,4A,93,3F,49,AA,EC,51,87,25,57,33,93,D4,71,90,BA,DD,4C,CD,5A,2E,C7,38,1C,30,85,21,6D,3D,00,E9,AC,94,B4,C2,DF,00,9E,0D,B7,22,33,F2,72,35,4F,13,D4,30,BB,4D,B4,1B,54,C3,A7,1E,EC,CF,40,8B,64,74,3A,8B,5B,2E,0A,DA,25,4A,77,3B,0E,5A,D1,87,91,59,4F,A4,CD,FC,CB,53,E1,97,31,7C,89,1E,DD,24,F8,8B,18,2A,EB,08,A6,46,6C,7C,D5,22,13,DA,7A,BF,64,CB,1E,AE,60,49,47,A5,1A,E3,A7,DC,42,AE,C6,DE,82,FC,AB,B2,55,DF,D1,8E,84,00,F9,54,25,10,79,95,65,AD,05,46,21,34,A2,E4,BE,2D,6E,8D,FB,2F,7C,94,A3,DB,F6,CD,C6,3F,07,F5,A9,32,CF,07,62,2F,F1,C7,0B,A7,D0,15,AD,35,5A,07,6A,2C,C0,2D,3D,0D,8E,ED,96,15,37,30,9B,17,03,AB,1C,55,A7,4D,F9,62,CF,55,0F,B3,4F,12,88,B0,5F,1C,76,4E,38,AA,02,BB,BA,7D,2B,62,48,39,69,8D,37,73,95,50,9D,77,FA,56,F3,EE,FB,EB,53,8B,C0,CF,50,F3,17,82,91,D1,22,2B,92,AC,12,5A,82,5C,4F,53,6B,4B,78,3C,BF,59,3F,2A,DB,92,5F,F1,42,01,98,57,B7,FE,DF,D5,2E,BE,BB,F0,9E,B0,80,3C,6E,A0,38,78,A4,0E,52,15,60,3A,3C,84,04,DC,EB,67,37,55,91,DD,79,65,FE,36,0A,7A,14,A1,B4,FA,2D,BA,69,60,6F,BB,6B,94,5F,4C,67,74,92,F3,9D,54,98,0B,3E,A5,F2,0F,E3,67,CA,9D,28,73,3B,44,63,59,33,0B,6C,A3,75,FB,0C,0D,79,B9,BF,2A,7E,B3,03,F5,33,6B,DE,DD,E8,4E,A5,32,12,92,D5,5B,81,EC,D7,5B,2A,29,2B,75,64,4A,8F,92,58,9F,19,B3,6F,A8,A5,45,D8,5F,4C,AB,B1,DA,8D,EB,0A,30,07,CB,A4,B3,A9,28,D6,B8,A3,6C,1F,09,1F,F3,08,91,3B,F5,E9,F0,0F,33,78,8A,97,91,1E,E4,B8,16,38,AE,B9,0A,14,32,BC,EE,A0,89,3E,D9,DE,1D,F9,83,5E,B4,50,98,6E,CE,BF,1D,0A,A2,2F,F4,92,F7,51,9E,B2,C5,F6,91,36,31,73,C1,8E,A3,57,29,73,94,0C,FE,6C,9B,15,92,F9,3B,D2,CC,A6,C4,82,D3,75,08,A2,50,DE,4A,6F,99,3D,69,EB,2A,8F,A9,6B,C5,A1,70,CD,5C,C3,9F,EA,27,5D,6E,CF,00,0F,FC,D6,45,9A,05,0A,01,59,53,D6,72,D6,D1,CF,51,38,5B,B5,64,65,5D,AD,AD,2E,B3,36,B7,BE,BC,2A,79,1F,28,DD,C1,1B,B2,88,89,37,5B,4B,FE,E6,56,14,3E,67,89,9D,CA,D9,91,78,05,73,DD,38,A7,2C,E6,01,DA,8D,A2,B3,99,CC,C5,A8,4A,A3,EB,79,A3,49,23,09,85,5F,B7,D0,38,E9,F4,E5,F3,51,D8,9C,08,25,C6,87,9F,5E,CF,DD,8D,EA,FC,BB,4C,77,98,91,F3,0B,54,99,A6,C2,31,D1,0D,7D,04,1F,F8,32,8A,09,78,A8,7F,27,59,60,E5,AB,F4,35,C9,73,04,51,39,EF,96,DF,84,A9,17,25,A9,EE,B9,10,F9,0A,95,EA,9C,5E,B6,6A,2B,44,0B,64,BE,E3,09,7E,CE,C2,3B,B1,AD,74,E5,EC,B0,EA,EA,D5,BF,D7,5D,1C,DD,53,FE,86,75,29,FA,B1,A5,67,4B,73,EE,E3,30,FA,14,EA,FB,EE,5F,91,03,38,A0,7E,E1,52,15,E8,AC,58,0E,E8,51,63,F6,7C,32,DF,8D,A6,5D,C9,93,39,9F,19,9D,E9,3B,F0,CD,D1,D5,DC,B0,32,A9,A7,6F,39,C7,3D,67,47,29,9C,78,A7,DD,F8,A2,54,F4,E7,82,EC,F8,15,90,B3,AE,01,0F,3A,4E,E6,A3,FD,6E,D3,B3,B7,6C,B7,3E,A4,99,85,01,FB,17,7F,FC,18,F3,EE,47,D0,E5,4B,EB,4A,94,63,BB,0B,E2,74,47,B5,8B,B9,E7,A0,5A,35,DB,FC,39,F0,66,6B,93,23,7F,15,A3,5F,B2,DE,C5,6D,07,D8,E2,60,BA,12,BC,DE,79,FE,B3,92,64,D6,23,F5,E2,E9,E7,33,1C,EC,AD,B1,38,03,44,1B,FF,43,80,2C,FC,23,F8,7F,F4,2E,CC,D0,1C,85,F7,D8,8F,7A,F8,7D,75,3A,53,64,E9,4D,BD,82,E1,41,C3,A9,BD,42,D7,78,9E,E0,31,CA,EF,39,6F,75,39,D7,EB,28,B5,47,37,00,28,6D,DE,6E,03,9A,12,A7,80,D3,1F,18,D6,43,9F,94,53,7F,2F,5A,7F,D8,34,64,93,69,F0,D9,EA,A5,D0,7C,69,22,9D,C5,1A,FE,C9,84,2B,14,A9,6D,41,DE,33,F9,D8,24,57,6D,7C,1A,29,4E,3B,ED,A3,59,E1,BC,39,29,37,67,99,4F,25,E7,2A,21,C5,58,A8,59,81,52,FC,43,15,A7,9D,3F,EC,4D,AA,37,1F,BA,1A,D8,58,43,12,46,2D,58,51,20,0C,4C,AC,D4,22,1B,1A,E2,B8,31,CC,6E,A0,17,64,11,1D,65,B6,EE,E1,1D,50,4A,05,3B,95,3F,07,4D,12,68,6C,A6,A3,88,AE,1A,5F,6E,FB,EC,5C,F4,DA,07,A2,44,76,1E,9E,B0,7F,E4,A4,79,F8,4B,63,4A,A7,F2,07,2B,F7,92,1E,C6,3C,95,4A,6B,E2,62,8A,B6,08,C1,D5,35,DD,74,53,21,DC,3A,87,05,3D,71,04,C6,9C,63,C0,97,45,2B,9F,03,CB,3F,23,CB,1E,4C,AD,04,5F,47,6F,E2,4E,65,EE,B1,92,B6,DF,DA,07,79,36,31,9A,03,16,3D,3A,27,8F,A9,36,06,3D,7A,F0,1A,7B,38,D1,13,57,71,2E,3B,28,67,19,93,98,0D,BB,38,68,ED,EA,00,51,72,B8,B0,F3,73,C0,E8,27,3C,0C,77,AE,03,95,56,2A,A6,D1,7C,28,3E,D1,F4,21,8B,D1,3C,5C,FA,3A,2C,01,04,2E,3D,64,7F,AB,A9,C1,3C,C6,C6,17,23,0A,EA,0D,CF,91,FC,E3,25,F4,CA,E9,DC,79,0D,08,D3,54,02,7A,E6,26,16,DA,C0,ED,F8,FA,05,F9,21,0E,33,07,8B,89,C5,5E,04,84,75,31,5F,06,1C,F4,12,8C,43,6F,40,4B,A0,43,5A,79,24,08,5A,BF,1B,8C,05,27,8A,6D,1D,43,F6,8C,CB,FA,F5,48,13,3A,9C,2C,A5,BC,8E,B0,D6,40,62,6F,3E,97,29,BE,BC,16,50,2B,22,13,CB,F2,EC,4B,F5,3E,F0,DC,2F,17,0D,E1,1E,82,EC,9E,02,DD,3F,71,59,42,7F,D9,01,75,53,99,41,A1,07,DB,CE,06,7E,7E,E7,EA,68,3E,15,1D,C2,83,11,04,9D,A5,BA,1D,6B,66,BC,D0,F4,92,F4,40,3C,11,0E,B0,60,28,D2,1A,91,58,0C,28,2C,06,7B,B9,E1,0F,09,A9,7E,BC,5E,64,7D,D4,4D,55,8C,81,BA,C1,B9,FF,6A,DF,26,62,77,95,F6,7A,DB,CE,60,3D,80,8A,A2,CC,EC,37,0F,36,93,36,62,F4,02,51,9B,15,A5,EF,E2,BE,F9,27,EF,9C,8E,3E,E1,51,B7,A9,6C,6B,C4,C8,58,33,F9,8E,E3,08,75,80,B4,2B,D6,E8,F9,B1,46,E5,49,35,8B,B0,95,19,53,1E,82,13,9E,6F,95,04,0E,B8,B1,0F,89,3B,92,56,90,DF,FB,C1,EC,33,CC,C1,A6,F8,59,AA,B1,3E,48,B5,E9,83,69,BB,54,64,6B,87,E5,19,D3,9F,FD,46,2C,FA,B9,52,64,BC,A7,96,EF,D9,F6,31,CA,6F,F6,D6,B6,F1,1E,05,C6,C4,60,DA,2E,63,3C,83,E0,AD,87,5A,EF,F5,D0,A9,DA,C6,21,FC,B0,12,7D,89,4E,F9,7D,F2,BC,C2,4D,EA,18,83,63,7A,2D,63,FE,A2,01,F0,62,F7,60,BC,29,0E,09,D4,37,46,A1,C8,24,B1,BB,43,9A,E6,0F,A0,00,16,21,B3,99,5B,3F,3A,C1,88,0C,EC,B5,67,DC,CC,7E,AF,93,65,A9,CA,7F,E5,F1,10,E7,E8,34,F7,97,6B,9C,25,91,6A,1E,D0,2C,B7,01,B5,34,F7,30,A7,6F,1F,5D,30,F7,B4,BC,A6,83,C3,36,FF,4A,CB,64,83,C8,7F,BC,DE,CD,91,E1,E7,F9,8B,22,5C,FE,8B,3B,12,1C,F0,7B,C0,AA,20,84,05,85,48,1B,68,F2,D0,81,F8,1B,BF,3C,66,19,64,B7,94,F5,B2,FF,F4,E0,AE,0B,0B,F1,8E,DC,6E,9C,4A,83,A6,43,6E,FB,E7,82,2F,23,FF,0E,FE,43,91,53,CD,D2,08,92,B6,70,59,38,B0,DE,D1,18,28,7F,7F,AF,FE,DA,35,21,17,F1,EF,BC,3B,FB,14,74,A0,B1,25,6C,64,FB,DF,40,24,91,C4,6D,77,8B,E3,F9,04,7A,D8,F5,82,73,30,DF,14,A0,3F,8B,23,2C,B7,51,E9,D9,3A,71,39,6D,CF,83,02,FC,C2,E2,4E,1E,EB,5C,EA,EE,85,D8,F7,3C,8A,7D,96,41,AB,0C,B8,DB,A5,71,00,A2,D0,4C,A6,33,90,45,CB,CE,ED,81,DC,C1,20,9D,5D,79,12,FB,8C,17,FE,11,65,0C,A8,65,9B,C3,A3,94,79,05,F9,34,18,3D,18,C9,AE,80,39,23,AF,A9,BA,1E,4D,57,12,22,3C,12,8F,42,3C,DA,4F,8A,17,87,D4,74,16,9E,39,04,96,84,E4,F0,61,EC,98,A4,A5,C7,1F,4A,CE,70,7B,E8,16,20,A5,AD,7B,71,41,02,4F,CB,24,34,70,D8,4A,67,50,16,EB,FD,09,0C,07,34,3E,4C,B6,D9,AF,6F,0F,9C,BA,87,05,A1,0C,69,97,8E,18,22,B4,75,3C,5F,9A,79,6E,0C,A8,67,4F,62,DB,E6,78,9D,BD,CF,97,94,74,40,AB,C3,05,13,42,FF,D1,2F,E7,46,B0,41,F6,93,0D,F1,E7,49,7A,A9,88,15,F4,C9,E8,EA,59,55,3C,2C,55,60,82,44,33,16,F6,16,7C,56,59,E9,87,2C,80,1F,1B,1D,98,D6,53,1B,EB,05,06,D5,8C,66,AF,9F,91,9C,2B,AA,27,D9,3B,FF,CB,89,18,B8,21,3F,C2,AE,F6,38,79,CF,F3,90,C7,C2,35,B0,B0,35,DE,02,73,65,E2,D9,FC,75,D5,56,C0,B3,B7,F5,AB,1D,23,73,7C,F5,9E,02,17,97,20,6F,1E,20,8B,24,80,B9,DF,A6,C5,ED,BA,DB,12,1B,86,54,2C,86,FC,DF,73,4D,47,68,2C,F6,78,C1,6B,28,F7,08,27,72,41,BB,16,B3,66,2C,98,81,EA,1E,B9,4C,4C,B1,77,53,38,44,82,8F,27,7D,CA,C9,83,43,32,2B,39,11,04,48,9A,A8,6F,DD,8C,5C,E3,8D,66,FA,E3,DB,F2,BF,C4,47,E9,A0,87,08,68,A7,75,20,81,3D,63,D1,19,66,3C,C3,8F,BD,F3,8D,5C,4C,C6,F3,0F,13,04,EF,10,1C,DE,FF,92,4F,E2,77,BE,2E,9D,3A,47,AD,D1,D7,76,9C,0A,1B,1D,DD,6E,B6,69,7B,41,9C,36,19,E3,A7,4F,F6,B5,2B,E5,0C,00,18,27,B7,E5,71,FD,98,BA,A8,06,36,9D,5A,0C,3C,74,B0,13,28,F8,37,B8,29,04,C9,2D,B7,08,53,FA,7C,58,5D,97,BD,7F,B2,55,F1,D5,C4,3B,A8,18,02,F8,D6,8B,7E,A0,1D,79,55,75,AB,77,D6,E1,F8,2D,A5,5F,AE,D1,0A,7F,DC,55,67,CE,BF,3D,F0,E0,63,F8,3C,3F,06,79,D1,DB,C1,DB,AF,DD,E0,18,27,F9,81,B5,9D,EB,9E,CC,3E,7F,6C,9F,8C,C1,A4,B5,55,63,79,9E,DF,59,AE,D9,12,BC,6F,75,10,2F,BE,5C,95,CE,1E,36,01,E0,DF,E4,B6,C2,5F,65,CD,B8,AB,AC,EA,A2,E5,79,32,76,E3,B4,E1,67,53,70,A1,D6,88,04,A9,22,50,FC,7D,6A,0E,38,58,EE,5D,91,83,53,83,EC,B2,D5,D2,75,22,F8,CE,43,98,0A,5C,08,D2,F6,6F,67,86,4A,C3,22,28,2D,94,31,3F,EC,37,60,90,B8,0F,CE,20,ED,F1,3C,49,67,42,3F,58,0A,2C,8A,D5,85,F5,66,44,CF,6F,26,47,A1,7A,85,4B,4D,C4,84,EF,83,9C,87,D6,9A,6D,56,CA,47,11,51,6D,5B,91,B9,63,78,4C,80,4C,A5,31,5D,85,60,87,12,F7,D8,E8,E9,B8,7A,E0,C3,B6,4E,D4,A4,3A,22,06,E5,18,D5,BD,02,C5,9E,4D,DD,41,09,97,35,A9,E4,AF,A1,C3,A5,A3,E2,1B,AF,9B,43,F0,B9,27,2C,D1,F8,4C,C3,9B,4B,B0,AA,8D,7F,E3,58,89,40,2E,4C,88,36,B6,03,E8,5F,87,C4,9C,D0,E8,1D,07,A7,6C,91,4C,4D,CD,39,83,FA,5A,2D,94,3F,AF,D6,08,53,4A,AE,DF,B8,E2,15,FF,D7,11,C8,A5,66,AF,88,50,BB,C7,75,5E,72,B5,37,E7,88,F3,0B,56,47,3D,BD,F6,35,B2,FB,EB,85,DF,11,86,93,6C,A6,D7,3C,30,2D,F4,6F,E3,B2,13,6C,BA,BA,F4,67,10,0A,E1,50,3C,B3,43,DD,CA,70,32,33,B0,09,08,40,CF,C4,D2,09,52,00,B2,A4,91,A9,49,00,3B,4C,61,3F,2E,C9,C7,BA,34,8E,AC,37,06,34,B3,00,DA,A8,FF,E1,BC,F3,C0,4A,5C,6F,85,CA,72,11,AC,63,A8,60,6B,BA,27,4B,19,D8,D7,0C,23,CE,82,E2,A9,A3,0A,9D,39,E6,9C,EF,3B,03,E8,D4,C1,DF,93,70,91,75,50,CD,C9,CB,C9,57,38,33,7B,C9,FF,76,DB,5E,50,46,62,11,28,5B,61,11,89,88,7B,F5,04,71,14,D7,59,6D,79,60,2E,C7,A3,72,11,B1,D0,02,EB,97,BB,16,B8,F7,5F,50,09,08,F4,FC,11,C4,24,C3,45,3D,3B,04,90,BB,41,62,58,9D,D0,29,BC,68,B7,CB,47,55,42,08,43,72,0F,A1,2D,3A,8E,FD,4A,3A,67,C8,28,10,1C,80,24,C0,30,EA,4F,55,7F,59,86,01,7C,26,9E,92,08,80,9C,02,81,6B,70,92,52,34,4C,B0,55,14,2D,15,CB,75,7B,87,C3,63,41,22,13,73,AA,69,A1,FD,BE,19,06,91,D3,E3,60,5B,33,B6,B0,C4,A2,71,DE,A5,57,84,14,56,8E,4E,78,54,FC,0A,A4,8F,8A,2B,B5,65,0A,87,60,BD,49,97,66,84,F0,7F,9E,DD,1C,64,88,3F,4D,36,12,A3,88,AF,90,C7,E5,D2,37,E7,C0,21,32,00,2F,8A,B2,92,2C,8E,3C,E8,BF,63,63,67,FD,2A,AE,5A,D2,83,2A,FD,82,65,49,E4,42,81,F9,C2,81,44,A8,6B,AC,2E,30,2A,4F,95,D1,F4,05,A2,65,7B,70,73,30,BB,3C,0C,DD,F3,34,6D,17,1C,2A,AB,CE,FE,F9,8A,3F,5B,A0,67,8A,1A,C5,AB,8B,6E,E4,D2,55,63,B4,61,2D,36,0C,C3,A3,84,A0,D1,DC,73,FF,09,56,49,BD,8A,C8,1A,61,15,79,B0,AA,9F,D2,1C,FC,EC,E3,F5,B5,51,DF,20,C8,08,7B,98,0C,9C,93,A9,51,13,20,B1,5E,CF,16,C1,5C,75,DC,E6,B5,9D,B7,31,1B,EE,DE,E0,AD,71,E1,26,97,CE,37,88,0A,59,EA,53,46,04,84,8F,C3,CC,2F,68,F0,87,DC,3E,01,8F,05,AF,D8,3E,30,9E,BB,91,85,01,98,65,1A,F4,F7,22,E3,1D,3B,26,43,30,8B,5A,1B,B8,A7,D9,9E,68,58,24,F8,C8,AD,71,D4,69,CB,95,7E,BD,AF,23,A9,81,49,69,62,07,AB,78,33,8A,6D,03,9E,54,79,52,95,27,F7,B1,3A,D6,46,3B,0F,02,04,4C,4D,E3,D8,5A,D1,FF,1E,91,E5,8D,18,EB,49,B9,D3,A8,D7,40,DC,C7,AD,EB,70,77,71,82,EF,5D,EF,49,42,42,1B,B6,24,33,E7,C2,4A,F3,62,65,8A,57,4F,A4,44,F0,76,2B,CB,0A,74,28,33,EB,77,00,50,4D,DA,5D,04,4E,85,40,E7,4D,79,69,44,B3,9A,74,C9,76,E6,3C,9A,FE,AF,F4,48,8A,C9,40,62,1E,35,CF,F7,CB,3F,0D,4B,BF,D5,BC,20,E7,41,A8,D2,3F,E1,2B,B8,FA,5F,B3,D4,46,DB,8D,81,31,DD,FC,AE,3E,52,74,22,05,34,19,1F,7D,04,6A,0B,31,E0,55,D1,28,7D,A0,E3,80,42,2D,13,B0,B2,5F,3B,5C,E6,BF,CA,04,C6,E1,30,4F,9F,92,FF,06,31,4A,50,AB,3E,ED,06,F2,15,BD,66,E0,19,00,10,13,88,CF,30,EE,47,25,FF,E2,E8,5D,99,31,25,F3,5E,42,6C,38,31,7B,84,8A,DE,C7,19,4D,AC,56,0F,8F,CE,EA,FA,01,ED,5E,1D,3C,44,F8,43,07,97,9C,2A,D2,DE,2F,D3,B3,86,9C,85,38,F4,3C,B9,51,77,E9,E7,A1,9C,A7,4D,18,C7,DA,73,DF,71,E2,E9,7A,68,62,AE,EE,E3,05,33,93,7C,88,B2,F6,3F,B6,57,88,B8,51,F4,36,94,10,9D,DF,95,84,5C,C9,07,E4,D3,63,CE,C8,EF,36,A2,71,8B,7C,70,58,C8,8F,06,1A,09,17,37,3A,5E,19,11,F1,6D,42,B3,B6,09,4D,E9,D6,3E,EB,CD,3D,48,85,2F,C8,9A,A1,D8,82,A8,F0,D0,0E,D2,A8,EE,DA,B6,24,2F,7D,B8,C6,70,AC,CD,FD,7B,19,52,87,DA,7E,FC,3D,D1,22,75,F7,87,29,9A,5B,A2,10,3B,44,15,26,59,62,C3,FD,04,90,CD,B7,69,77,C3,40,37,10,3B,16,38,18,37,AF,B9,0F,45,5A,01,7F,22,4A,AA,15,B6,4B,4A,7F,83,6C,27,A9,B1,E0,DC,10,49,43,91,96,39,63,B2,B7,AA,97,19,75,9D,1B,31,B2,11,2F,25,ED,3A,0B,7C,46,BA,D4,FD,7E,B0,50,97,1F,8A,C4,5B,49,48,7D,5E,D8,04,B9,8B,87,27,45,9D,21,FD,11,B9,7B,91,CC,3A,93,28,FA,4A,FC,36,56,2D,9A,53,93,1D,08,4C,8E,55,61,35,4C,D7,44,D8,E7,F9,C5,CE,14,45,DE,C1,19,BA,0E,DE,47,69,76,A1,A4,15,4B,BA,30,9B,75,54,25,A2,25,DD,F7,02,2B,F1,FB,1D,2F,DE,D3,A3,15,37,17,B3,31,4B,2E,D5,C9,14,12,27,BD,B7,BA,08,25,41,FB,7C,E9,D5,55,7A,07,44,3D,C4,20,E4,E6,CD,71,EF,34,2F,B5,D8,D0,A3,9A,5E,E3,C6,DD,F8,A8,93,9E,C2,43,8A,8D,4E,36,A7,9E,5E,FD,31,A1,ED,B8,2A,9F,F5,35,06,59,8A,F3,84,D2,13,6F,39,2E,CF,CB,83,29,7E,53,D0,73,1E,EC,9B,81,43,98,3C,48,21,D3,44,D7,5A,24,34,02,C8,45,F0,B4,7B,CB,D8,E4,8C,C0,64,AD,84,37,C9,D7,9B,A0,BA,DE,92,12,18,05,DF,AF,E7,5E,F2,C1,9A,FC,C7,5D,79,2B,D3,CB,1B,6F,56,EF,FF,55,91,10,27,60,E2,7A,EE,4F,2F,D2,85,CF,08,F6,D2,BF,DE,44,59,E7,0E,87,19,6D,A7,C0,09,CD,DF,4B,04,F0,7E,E0,60,44,10,9E,55,F9,32,3D,FC,D5,D5,45,7E,44,9D,2A,4A,7A,E5,BB,0A,50,C4,06,ED,52,14,35,A7,63,C7,D1,EE,49,78,D8,EA,BF,38,58,C9,ED,7A,72,96,C8,C8,E8,06,95,4A,B7,46,A4,1D,2E,81,AD,37,B8,1F,37,20,86,5D,16,9C,71,07,E2,41,69,A2,0E,AC,6D,BA,BB,88,A1,AE,7F,BE,AC,68,3B,09,CF,C5,5C,7A,8D,87,DC,9C,7F,5D,27,E5,2A,F8,24,12,A9,A0,25,DA,84,66,98,8D,44,1B,F3,FD,79,3B,B3,0D,0B,A6,0D,4E,06,37,B2,D2,3B,66,31,EF,BF,93,D8,29,3D,36,F4,5E,63,BB,12,D6,2C,B8,BF,70,E7,B6,30,7C,89,AB,16,69,EA,CF,4F,AC,95,22,32,14,BF,C4,AF,AA,B7,2C,1B,C5,99,B4,16,F7,4C,A4,9A,98,27,9D,ED,67,D2,13,15,40,EE,BE,AB,C8,C6,DD,39,20,82,24,A1,22,6C,FB,B4,71,C0,C4,51,7D,66,7A,78,2E,0B,9B,1A,8B,E9,6A,69,45,8D,80,1F,A3,7D,86,5D,6A,57,90,93,D9,92,24,08,0C,E5,6A,C2,71,1A,C1,47,DF,21,DD,FF,58,8D,78,B4,FF,B7,81,C3,52,1B,2D,18,04,9B,B7,44,AA,3B,22,44,44,2B,FA,32,0D,4A,91,0B,C4,B0,D7,B7,77,F2,4C,6D,77,5B,F9,30,80,5B,B5,92,D8,27,8B,33,3F,AA,76,3C,7D,DA,40,0D,70,F0,1C,81,12,0A,45,DB,FF,5A,19,1B,26,BC,9A,C3,5B,E4,48,0D,27,8B,3E,63,44,C0,92,B7,BC,11,78,E6,C8,7B,97,92,3F,99,F0,8D,98,CD,86,48,85,A6,72,F0,73,21,4A,12,40,D5,F8,56,FB,C0,B4,84,26,FF,C6,D1,B5,65,DD,66,96,97,08,53,70,75,B6,FE,0B,6E,6C,13,7A,45,18,E4,EC,9A,49,5A,82,72,13,39,B4,1B,C5,E5,B8,DB,CB,26,88,8B,D8,EE,AB,94,41,0D,51,83,CD,1B,70,DF,6E,ED,D0,76,B1,EB,78,9C,EE,97,F1,87,C9,1E,45,B9,08,D6,0B,ED,6F,97,99,F7,A6,84,70,D2,6D,6C,2B,DF,78,AC,BA,72,9E,94,31,0C,8B,08,C0,6D,11,52,9A,00,DB,08,69,85,9E,23,9E,EA,26,5D,BE,4E,04,9D,2D,9E,08,24,92,7C,37,9F,F9,8D,FD,D3,5B,F8,B3,94,4B,3A,90,01,75,FE,05,DD,32,BE,40,25,07,0C,F7,3D,21,D1,AA,5E,2B,15,BE,37,C0,B6,7F,BB,01,86,09,A9,D9,13,5A,2C,5A,8C,0C,09,08,0A,77,97,1D,72,81,FE,6E,3F,52,52,DC,EA,C8,7B,AC,89,7E,20,83,46,E4,E2,35,26,80,B7,1E,52,FF,D1,99,87,F2,5F,B3,37,01,23,99,32,B2,70,63,17,AF,E9,4A,93,48,3D,D7,9F,E0,31,61,F5,32,16,DE,DD,F7,87,62,73,48,3A,62,40,9A,97,5B,8C,85,15,31,13,FD,7D,FE,0E,B8,26,32,37,0F,87,4C,B6,24,EF,0C,E2,A6,B3,15,34,C0,6E,8D,A8,A5,60,3C,89,47,A0,56,C7,0D,41,9E,85,B8,2D,7F,31,1F,4E,CC,6E,49,A6,74,DC,F0,2F,FB,AC,C5,E3,50,34,CE,F2,7C,AE,3F,CE,1F,29,7B,93,0B,30,FA,F8,2C,B1,05,F4,CE,E0,6E,BA,13,E3,E5,2C,CA,3C,28,8E,73,E5,1A,E8,C7,A4,D2,C7,31,31,9D,9A,AB,5C,8F,67,9C,E9,63,82,66,8E,E5,B9,4A,7E,04,2D,07,03,CB,A8,2D,C5,C3,26,9F,C9,57,04,63,08,BA,0B,7C,AC,E2,CD,CD,21,82,75,2B,5E,C0,EB,33,57,6E,98,A1,C3,0D,4D,D5,5D,38,19,0C,8B,8B,60,85,70,B6,32,B1,17,3D,F3,0F,75,AC,89,5E,79,71,41,DA,B2,58,BC,31,45,A3,20,A4,AE,D2,FF,13,6A,57,E5,74,20,FD,6E,9A,42,06,F9,A0,DB,19,11,70,FA,48,B7,DF,3A,B6,C1,99,27,B3,7D,F8,03,7F,9A,A7,71,0E,8A,72,77,11,07,74,31,C7,0A,EA,58,6F,DD,3F,4E,B2,FE,C3,E3,0A,04,C7,A1,CA,6A,EE,40,0B,91,37,D8,63,A9,AB,F9,4A,7E,FC,A7,4F,E2,CB,62,8C,5B,54,A9,A2,A0,F3,68,3C,7D,3F,69,42,87,DB,0E,C2,2B,01,00,F8,AE,FE,20,F4,0E,2F,D4,F7,1D,EC,CC,AA,7B,F4,AD,D8,E7,4A,BA,D8,9C,8F,5D,75,02,35,C4,38,C2,51,07,84,D6,4E,85,BA,7A,B6,14,05,8A,25,06,FD,3B,05,19,CE,6C,6F,8F,9F,75,70,8E,12,57,0E,35,A8,0A,E9,84,74,07,69,41,C6,39,8A,35,5C,79,83,63,00,98,78,92,3B,A2,B9,62,F7,73,33,79,A7,11,83,3B,C6,2F,37,43,92,24,D3,0E,78,6B,00,AF,C8,ED,C5,5E,95,5B,CE,4D,D4,4C,1A,CB,E2,53,70,FE,18,B3,7F,39,A7,73,94,86,84,E6,74,4B,52,71,82,64,6A,6B,B3,9D,22,95,82,AB,FF,88,F5,EE,0D,A9,CE,F3,FB,C8,66,75,2B,50,5A,4E,BC,4F,74,CF,23,5F,F4,57,C4,5F,0E,52,24,45,56,DE,9F,43,F3,55,F8,BA,92,DF,2F,BD,71,45,1A,24,DD,38,59,72,80,E3,CD,DA,83,AD,C8,B7,6A,31,1F,8C,BC,32,24,CE,94,EC,B7,B8,92,65,1D,DE,58,6C,E2,FE,4A,FB,3D,60,CB,4A,12,57,EA,58,9C,5F,B9,DA,DA,8A,26,3E,49,11,B1,2B,14,C0,6C,25,9C,15,79,D6,77,5F,8A,AA,C1,39,86,DD,4F,BF,49,54,EB,27,89,95,8C,50,32,20,CE,98,4F,C1,DC,B6,48,D2,FA,EC,52,5A,39,C1,B4,4D,3A,E2,7B,59,64,E5,95,74,A6,2F,29,44,56,9A,E8,AF,62,94,87,7B,E4,37,1F,28,AB,5A,F3,42,46,81,23,6C,97,BC,85,15,16,3E,7F,FF,FC,DF,CF,26,A2,EA,CC,27,B9,60,69,CB,C9,5A,3B,B6,F7,DB,2B,44,62,7E,16,94,BF,F5,74,50,1B,82,8D,21,A0,3A,61,ED,D3,21,36,1B,16,A8,8C,39,5A,F1,CE,55,64,6B,A4,F6,94,A4,84,58,62,F9,B5,EC,4F,01,EE,85,96,BF,70,EC,3B,CB,BE,4F,A2,60,75,68,7A,60,86,92,DF,58,15,69,00,B6,C7,BB,F0,04,8B,0A,F4,99,AE,F6,32,B5,D3,5D,FB,6D,40,53,70,57,76,6A,72,88,10,5F,A0,8E,BC,EC,5E,16,D3,C3,6D,2D,19,AF,B1,E6,6F,AE,93,51,CF,A0,59,14,57,F0,5D,10,72,5E,2B,5E,55,F8,40,E5,FB,5F,E5,CE,2A,5B,C4,9E,CF,B5,06,90,5A,D3,25,D7,E4,56,BB,C7,E9,F6,B0,87,FB,E3,41,37,2A,BE,D9,27,0E,D3,C5,BF,3B,74,B2,EF,16,2D,28,5E,43,81,1E,81,52,98,90,4B,03,36,CB,47,02,AC,0D,CE,E4,CD,C4,79,47,E6,10,B5,38,AA,0B,83,0E,98,F1,AE,F2,D4,80,F3,D2,2B,67,45,4A,40,73,AC,C1,F5,9E,28,B3,58,1B,5D,B2,C0,8A,4F,0D,4A,5A,7C,6D,88,6C,57,B3,F4,18,FB,73,FF,3B,72,3B,D8,57,12,8F,25,C3,69,AA,81,0E,13,A5,09,BE,B0,1D,85,AE,EB,05,10,A5,B1,EC,70,E8,34,16,D4,5A,2E,E0,03,9B,B2,43,DC,A3,3E,AF,FF,37,F7,F1,B4,6F,59,A7,51,49,08,D1,C6,1A,83,5B,C1,04,BC,7F,34,7F,6B,DB,40,4D,EF,C1,0D,6B,D2,4E,6B,E4,A3,B4,A1,6D,A4,30,1C,67,17,3F,88,F9,B4,9B,EE,84,32,1A,07,F2,D8,FF,36,3F,28,EF,70,4D,2B,59,50,33,FA,9F,93,E8,1C,7C,D0,48,41,17,86,C3,6D,CA,25,C7,61,9F,C9,7C,F0,B3,60,AF,DE,D5,20,9A,B8,2A,33,AE,90,C1,CB,DB,0D,35,92,41,F1,24,52,71,14,6F,EF,0F,A7,9E,70,BB,5D,82,0E,9D,D9,F4,94,BF,53,EF,0D,83,E7,CF,F1,97,46,BB,FF,AA,BB,F2,50,72,C6,98,0F,8D,BB,C2,87,EA,DE,69,1C,18,51,AD,FA,75,A3,DF,63,9C,43,3F,96,92,2B,05,0D,68,07,44,D0,44,20,61,D1,78,A9,CC,6B,A6,2A,29,2C,BB,27,5E,5C,E8,71,B3,59,D5,6F,ED,34,72,0E,94,3A,18,36,C7,BF,A5,14,99,18,79,1D,57,5D,60,95,C5,0E,7B,8A,1C,DC,91,CB,AC,49,7B,1B,D3,DE,2D,44,8A,1F,20,D5,54,EA,49,16,E7,D9,8F,61,5F,E1,59,40,B9,AE,B2,0F,89,DA,EB,C3,84,F2,0C,6B,9D,ED,5E,3B,F2,D4,7E,AF,AE,82,76,E0,6C,28,9E,1D,FA,91,E7,1C,30,83,62,9E,C8,A7,FE,28,3F,02,FB,25,9A,C4,01,19,FF,5C,A1,8C,4A,B0,AE,56,8C,89,59,D7,B4,9C,11,A6,0B,96,71,97,F2,5B,62,E1,FD,FC,85,CB,0B,96,DA,EF,E3,9E,7A,E3,18,31,16,62,2B,9A,6C,07,8E,CC,BF,B9,2C,CE,19,77,D8,BA,D1,4B,5E,F1,DF,0E,6B,89,73,2E,35,98,96,81,26,98,65,C5,80,10,95,9B,1C,8D,4D,E5,9D,EE,17,34,F2,95,44,18,D4,50,30,A9,D6,41,C0,62,3A,32,25,CA,7C,40,FD,F7,83,8C,91,D1,97,44,D9,66,D7,88,7E,A3,8C,1D,F6,65,65,44,11,67,8B,3B,71,4E,AC,69,17,DB,CB,C6,8E,B3,31,01,34,F4,3A,DC,30,41,BA,D7,FE,C2,7C,67,3D,50,B6,F3,69,87,9B,89,83,FB,58,0F,14,34,BA,11,8E,8E,B4,45,1E,69,2F,3C,44,DC,F5,8C,02,DA,0B,F8,1E,FA,16,CF,AC,0E,DC,31,82,05,4C,C7,F1,1D,35,B5,6F,8D,A7,14,49,D4,C4,36,D1,88,47,2A,EE,0C,5B,CC,FC,71,2E,6B,97,92,09,D1,51,FE,B6,2E,4C,A2,1A,83,29,BE,B0,EA,8A,64,C6,00,F2,32,85,3D,DC,E6,5C,E0,42,05,C8,6F,F2,69,8B,E4,22,D0,9C,AA,34,9E,46,A4,35,A8,2C,86,09,62,7E,85,78,12,6A,07,4C,C4,BC,EC,4A,D9,A7,B4,9D,C0,AA,A7,8D,B3,F2,E6,92,D0,C8,30,FC,E7,57,90,B6,00,9F,05,E4,87,80,5E,82,1B,C2,74,97,A4,91,BE,F0,BA,EA,8C,98,6B,FA,D8,7F,77,07,3B,FF,6C,BC,11,B7,6B,CA,54,6F,BE,6E,38,3C,58,C9,D3,76,28,26,15,FA,42,C7,26,D5,87,43,1F,E2,26,DE,07,4A,1A,26,BD,33,F2,85,44,75,42,91,B7,FD,DC,54,4C,02,65,8A,31,9E,07,A9,70,0C,9F,E6,04,F3,DE,CF,79,9D,A9,2C,8D,DF,DC,BF,45,AF,C8,0E,0F,44,DC,CE,79,B8,12,6D,67,93,DB,C4,F8,E0,DE,22,1E,B5,32,AF,41,5A,70,C4,83,18,E9,4E,96,9D,FB,3B,36,A5,69,41,28,B8,1C,7B,E9,7A,60,C5,0A,32,19,A6,B7,C2,F1,22,30,EF,41,7E,08,A1,9E,0F,90,D6,A8,CA,31,B9,2A,27,15,9C,13,9E,0E,39,E0,CB,47,96,4C,0E,27,A6,68,5C,7C,FC,13,B2,22,19,35,28,8F,45,C6,EE,23,4B,89,9E,B3,B0,F3,89,D6,53,C4,F5,31,F4,FF,83,97,8D,C1,A0,11,61,66,91,F1,31,A0,DC,AC,18,B4,B1,5A,E8,5F,9A,E4,2A,BD,DB,45,F2,33,A2,E8,6C,1F,0C,8D,85,AB,A3,82,1F,9B,2E,DB,CE,77,67,42,83,5E,7A,BD,C3,C5,02,00,1F,9B,DD,6F,E8,2D,90,73,AB,59,CA,08,39,C8,61,DA,56,10,1C,BB,51,9D,E7,F2,AE,A6,CD,37,CC,84,11,1D,FB,73,00,6A,D9,88,03,AB,FE,4D,DF,85,65,4D,38,85,89,B4,9D,F6,9F,84,15,42,1B,F9,E4,D8,31,90,92,C7,01,25,41,08,11,01,A5,23,49,25,06,AC,92,49,F4,C0,19,EE,00,F6,1C,10,96,76,31,F2,39,08,2D,D2,7E,F5,1A,70,D6,25,91,6F,3F,12,F0,17,4F,24,6A,21,B6,FF,F5,26,97,89,51,47,C8,7B,09,AD,C0,1D,6A,E9,5B,B5,B9,AD,C8,73,BD,2B,60,B3,4A,8C,1F,25,15,74,2A,38,4A,F0,F5,4A,BD,3D,9C,A7,EA,9D,74,E2,6C,37,E9,51,12,65,49,1D,1B,E4,7E,92,10,9C,EB,EA,03,8F,CE,FD,70,0F,1C,F5,38,09,2D,9C,F1,C9,32,01,1E,1A,10,D5,48,AF,B4,8A,64,A7,C2,DD,9E,A7,09,DE,DC,E8,47,32,39,41,5F,7F,02,AB,20,CC,FE,1D,6F,3F,74,3C,3B,E7,3E,9F,1F,D2,68,4E,53,0B,63,C4,0A,16,5D,4C,4D,54,15,95,3E,71,37,97,FF,9A,2E,16,4A,07,14,57,26,99,8E,AE,1C,5F,C8,3A,D3,E4,24,24,1D,53,B9,E8,06,A4,00,B3,17,BE,BA,14,E9,B2,38,61,0F,1F,D8,A7,A9,92,20,7E,44,7B,60,D1,36,72,49,32,55,FA,1B,CA,E5,13,1C,A0,3E,4E,A9,AD,C8,F1,19,D5,27,EE,F1,D9,E6,59,3D,61,76,EF,21,05,C0,31,F5,53,3A,89,82,6D,E6,19,32,6C,4C,D5,3D,91,B4,5E,32,3D,19,65,41,70,8A,BE,E9,9F,45,75,94,1C,D1,00,70,0A,56,4A,DE,32,3E,29,F1,03,1F,1C,44,43,E3,84,A8,27,7A,21,56,31,D5,D8,DA,25,82,C9,84,97,9C,FB,6B,38,7F,20,19,9A,C7,8F,54,4C,21,7F,B3,81,9B,F0,59,99,86,20,2F,A5,7B,AA,B6,12,A8,C9,43,47,17,BE,4F,3D,3A,7D,F1,C3,55,9F,4E,87,C7,0C,EA,15,72,4E,70,30,7D,C9,F7,55,DE,4B,7A,DC,F2,BE,A9,B5,41,B2,1B,75,09,B4,85,B8,A1,EF,98,F8,28,74,78,E6,F1,29,7E,E9,44,F6,2B,4D,65,18,F2,C1,D3,8B,45,B0,E4,95,EC,24,18,D4,C2,12,94,B2,D0,C3,23,19,B9,B0,95,AF,CC,4D,C7,60,F5,3B,A5,27,37,D3,78,2B,C9,E9,F8,BF,52,24,5D,0B,A4,00,6E,BE,12,FB,24,76,61,ED,09,54,D9,44,BB,76,64,5D,AF,23,6F,89,AC,D9,54,12,2E,32,58,83,24,01,C1,21,F7,F5,BF,A2,9D,64,34,E4,74,E5,FF,04,FC,67,F7,42,9A,41,EB,6E,EB,E2,E6,F1,98,7A,09,D7,28,B9,B6,29,4E,42,76,9A,B6,B3,A6,1C,60,40,F1,E6,41,BA,56,74,F7,69,4F,55,98,E0,7B,26,80,81,F7,43,95,8B,BC,D0,C8,F5,54,98,8B,C0,DC,2C,99,3E,9D,DE,CB,28,10,E9,C6,EF,6D,40,93,7F,C2,FA,EF,1F,24,22,72,92,A7,60,8A,3D,AE,BC,FF,92,1D,52,B0,C1,D2,53,FE,D5,46,AB,1B,2E,B5,1A,F8,7F,1C,E1,67,24,61,5A,B3,A8,21,FD,08,12,CB,5D,0F,BE,84,8D,F1,DD,2F,7C,61,42,97,73,48,79,33,9B,70,8D,FC,DD,65,48,37,FE,38,E2,27,E1,68,D9,34,FA,31,BA,9E,2C,8A,C4,9A,07,E0,0F,BC,DB,21,50,FC,B0,6F,69,02,23,13,C1,B6,12,66,44,0A,30,FB,D6,2F,12,07,91,15,FC,3E,83,74,17,A4,B9,4D,29,16,5C,59,0C,A9,A6,B8,D7,20,C7,64,EE,4A,BD,CA,1C,48,EF,76,06,23,22,F7,72,24,1C,0A,23,17,D2,CB,04,D4,BE,FB,78,57,3E,F3,B1,30,10,8A,ED,F7,A3,75,C0,58,3A,61,36,32,EA,39,B9,9F,12,7F,15,EC,70,5B,9C,02,AD,43,D8,66,54,91,27,6A,28,D7,E8,1D,DF,5A,5B,79,E2,AB,E5,6A,1C,E8,9D,70,83,0E,E4,B4,E2,F4,3B,0C,B4,2C,B7,55,61,F0,1C,0D,EB,D0,73,ED,C7,0D,76,D8,6C,EB,F5,AA,5A,62,50,28,C7,A4,99,01,F5,3D,68,19,49,08,C6,B1,B5,9A,A4,3B,22,C6,81,4E,05,8B,F7,23,20,A3,21,7B,3F,BE,55,D3,2C,1F,FB,8C,23,71,F9,3F,44,EF,50,5D,71,28,08,8D,54,93,BB,61,6B,33,CC,FE,CF,4F,34,A7,71,6A,BC,E1,F5,96,E4,A0,FB,E3,BF,3E,DD,8C,1D,99,ED,73,A0,ED,A1,DD,55,FC,5D,AB,FE,1E,87,27,D1,DF,02,C8,76,EA,19,59,96,D0,F4,27,1C,07,2C,E4,25,D0,34,E1,08,F9,D1,8F,BC,34,60,23,6D,36,9B,ED,DC,2D,C9,B4,AD,60,E5,1F,6B,1D,A9,07,A6,13,E9,6E,B0,FE,D6,39,A9,64,49,3B,6B,57,20,A6,5E,0B,7D,AA,6D,64,EE,D0,F7,B1,15,72,59,B2,AE,77,2C,0C,73,E0,34,3E,CA,1C,9E,8F,47,10,53,50,BF,C4,5E,8A,A6,87,E2,F7,31,A8,73,5C,49,38,F8,7B,C8,F3,11,6A,0E,5E,3D,F5,4C,4E,EF,79,C5,99,65,4A,6B,38,F7,12,4C,26,95,AF,48,5F,DC,25,5B,2B,E9,DE,B9,18,E6,4C,6D,CD,72,70,D3,2C,E7,85,0E,4E,3A,15,9C,FD,89,78,74,52,C1,4A,94,41,CB,00,3D,BB,1B,7D,B0,70,0A,DA,DB,68,E9,CD,B2,90,39,12,92,DA,0E,53,10,55,1F,EC,C7,FC,42,BD,4E,96,90,2B,70,2F,F0,F0,8B,15,51,E4,DD,9B,03,30,96,6A,99,F1,8A,87,EF,5C,ED,F4,7A,91,75,15,0D,88,6A,9C,17,11,C0,23,81,8E,20,72,1D,0F,CF,49,88,E0,EF,5E,1F,CB,71,FD,09,C0,7F,6D,2F,D7,49,E0,41,AE,00,A7,80,AD,B6,8C,59,84,B1,35,2C,B2,70,F5,97,9C,AE,A8,47,EA,E6,9E,27,53,D3,72,5A,C1,29,43,6D,69,0E,F9,A0,70,C6,71,FA,5E,EC,BA,31,02,33,DE,29,BF,1B,5F,9D,B3,03,1B,CB,2B,37,2D,7F,82,98,A6,37,70,B4,EE,45,9A,A4,D5,A3,3B,74,42,5C,D7,D7,EB,0B,7D,90,83,1F,4E,2B,05,37,FC,EA,0B,1A,1F,3D,9C,96,C9,18,73,4F,65,03,31,00,2E,A4,FA,07,6F,70,F1,F0,E4,96,38,AF,94,9F,30,C5,E3,0B,21,CD,73,AF,A3,96,87,24,E0,FB,78,6D,34,11,93,0A,BD,45,6C,60,F0,4C,5B,90,08,2C,CC,6A,EA,51,D6,87,06,85,C7,E2,0A,CB,C6,1F,D3,0A,E8,EE,CD,7E,B4,0B,07,34,1D,6C,D4,05,84,BE,18,F2,60,99,A4,AB,45,DE,97,DD,77,45,5E,3A,1B,3F,1D,CF,DB,FB,D5,3C,E8,7B,D3,BE,A8,5F,5E,66,2D,1C,6E,4A,BF,56,F0,AB,0B,66,28,9C,57,3C,2E,D4,5D,C6,E5,3F,43,52,C9,A7,5C,7F,F6,DC,20,9C,CB,F7,B3,55,6F,55,06,70,9E,73,70,78,C1,73,8B,C0,BB,71,D4,EF,1E,C8,94,64,D0,58,8A,FC,03,98,21,48,58,3F,37,2C,99,3C,C0,E5,DF,92,2F,6F,1A,40,3A,52,11,A5,2A,1A,BB,5F,44,CA,02,C2,AA,48,0E,04,C7,6F,F7,AE,5C,25,8B,8E,52,88,4D,85,12,85,24,68,CF,C9,76,9C,75,EB,1A,83,45,1A,E7,E8,04,59,D9,B3,CD,4A,4D,58,FE,37,FE,59,27,8B,3F,88,54,63,58,03,79,42,49,68,1D,39,A4,E3,91,C6,4C,E2,E1,9F,20,3D,AE,7F,17,CE,E3,E5,03,48,5F,7E,42,E2,67,CB,76,1C,BC,36,95,00,02,62,5A,FE,87,DC,A0,39,1A,FA,9B,10,3D,E2,F9,ED,2D,7A,88,A8,72,C3,8B,E5,07,64,57,43,BC,D7,0A,1A,87,B8,69,FD,B8,36,9D,E8,8A,09,46,56,E8,CD,B2,46,1A,D0,08,06,A9,44,E6,BA,25,5A,38,D2,7F,D0,2C,46,81,32,2A,4A,28,47,25,B6,7E,4C,A9,64,22,57,5A,07,29,59,3D,26,52,93,4C,FD,B2,F0,36,AE,29,4E,2D,11,82,06,84,0B,0C,14,FD,9E,7C,9F,E2,6D,A5,CC,DA,65,C1,79,EA,1E,10,5A,AC,48,F2,B6,E2,89,5A,3A,54,6E,DF,77,F7,4E,F7,AC,81,21,E9,45,43,BA,C4,8E,7B,5B,F6,EB,97,BE,18,DA,10,88,D8,1D,BE,45,17,8B,77,5A,F2,B9,59,CE,5F,32,60,60,48,D8,B9,71,DC,64,5D,E4,69,99,C4,C0,3D,FE,A4,17,88,EC,83,D2,C9,69,46,FB,23,BC,65,6C,EB,AB,D1,5B,89,C0,1E,3E,69,39,AD,F0,1F,4D,DE,3F,F0,82,DD,8D,48,BC,14,66,A7,50,12,3E,AF,0F,BD,41,6C,A8,98,58,83,9A,D4,EC,0B,8B,5F,41,96,59,58,C2,EB,55,EB,B5,B0,BA,1C,0A,CC,49,24,21,FB,4D,DD,38,B3,F1,41,BF,B9,A0,CE,81,25,65,DE,6A,11,5B,21,E5,3A,2F,BC,68,9B,E7,0A,18,53,C0,F1,06,BA,9F,1D,E7,D9,A8,E9,09,62,2E,64,05,BA,5C,6C,E1,BA,42,32,A8,88,51,17,84,C3,E6,DF,93,DA,92,91,4F,FF,CE,E2,E9,3B,A2,72,91,19,0B,12,7E,08,7D,EE,4A,DC,F2,3E,10,49,6D,1E,00,E6,17,EE,9B,73,F6,85,AB,C7,49,32,1E,8A,04,74,89,66,7B,22,BD,3C,E3,BE,CC,2C,7D,02,4C,1C,D8,71,AF,8D,ED,6C,DD,01,A7,32,55,BD,0B,20,68,8B,9E,E7,13,24,57,26,E8,D5,92,3B,AD,33,90,AD,65,76,05,12,C7,0E,07,9C,56,1F,E6,87,0A,A9,57,40,70,44,EE,74,4D,E7,2F,03,A2,F7,9F,84,66,71,FA,8F,E4,D2,A7,DB,F2,59,5D,B4,10,0A,DA,D5,BF,20,FF,44,EE,AF,89,AE,3C,B5,15,C2,59,FC,B2,F0,F4,19,4B,24,DD,55,39,78,58,56,2F,62,7A,15,EA,4E,24,96,74,D8,6F,4D,F1,ED,6E,BB,33,D8,2D,BD,D6,33,DB,B8,00,54,3D,47,1C,6E,EC,2D,D8,2C,8C,FC,99,F4,16,BB,89,A4,B5,7E,C1,8B,DD,C9,01,E0,27,28,77,91,D0,C8,61,82,70,39,07,98,EC,F9,B6,82,B8,BC,48,CA,E9,27,6C,20,E2,9F,66,5C,CC,CD,56,CC,F6,44,9D,F5,3A,78,52,81,56,BA,56,A5,23,06,35,4F,C5,C2,B3,9B,62,C3,C6,0A,20,08,46,C0,3D,64,72,7D,ED,DE,09,37,50,66,EB,CF,07,00,20,0F,A2,01,A4,A7,B3,7C,D5,24,9E,8B,E8,FB,53,5F,45,D9,0A,65,CD,B3,A8,0F,71,D6,26,81,C1,2F,34,13,DD,2F,E8,22,4C,2A,2F,EA,BB,EB,F5,4E,E9,23,03,11,E1,BC,5D,07,0A,13,71,6A,12,59,30,6A,6F,65,B3,F9,E1,9F,4C,DE,A7,D6,9B,2D,5D,47,60,8E,9B,8F,08,57,68,FA,4A,BB,A5,DB,DB,E9,CF,DA,8A,F0,9A,FD,7E,89,C6,EE,F7,15,CE,80,F4,59,E5,D6,0D,77,2E,F5,B2,77,89,E6,4C,CA,19,01,9F,BC,48,35,76,1A,8B,BF,00,A4,05,32,6A,21,53,DD,FB,B0,B8,98,D9,B4,B4,5D,97,1E,56,84,95,67,3D,0C,C8,AF,A6,F9,13,58,E9,6D,40,55,C9,DB,BD,6E,1E,2A,DC,F2,75,FB,38,E4,A3,89,D4,EC,C1,93,50,E7,F5,BC,94,09,72,7D,FD,09,DB,3E,31,5E,D2,26,E1,54,4C,84,22,E2,18,3C,2E,A4,55,1D,B6,1F,3D,DC,A6,1D,44,76,3A,9C,14,2F,3B,CF,A7,B4,F7,80,6B,52,D5,36,1A,D1,6A,2F,E8,FC,33,53,3F,E0,B4,C6,3F,06,D9,61,8F,E1,2F,62,16,EF,94,A0,94,FA,40,FF,79,32,83,D2,28,BA,C2,B2,5F,DD,D2,9B,BE,FC,2C,44,6A,CC,B2,B3,86,53,17,AC,F5,D0,DC,4C,2C,52,DB,8F,FB,75,E4,E6,45,B2,33,B6,65,4F,CA,55,9C,EC,C6,A9,99,FD,0C,E0,F3,8A,7B,8C,78,03,61,AA,FD,25,C2,55,95,BD,44,16,BB,AC,E5,92,6F,94,4D,0A,1A,A7,0C,BE,FC,08,6D,8A,EF,B0,8E,54,7F,1D,1F,C0,6A,69,68,F2,BA,5D,21,48,7B,C7,29,3B,0C,BA,4E,41,FA,A3,5E,44,AF,37,F9,AF,BC,D3,6F,AD,EA,A4,3F,45,41,BF,9C,D7,F2,0D,41,D0,BF,C3,D0,5A,E3,3B,8E,B4,3E,35,79,F7,BF,91,9C,13,F2,96,4F,7F,BB,D3,5A,EC,4A,F9,D6,CB,8E,7D,A1,08,DB,A7,97,C3,22,9F,38,FA,B9,E6,5F,8F,82,3E,A9,14,8E,F0,0F,7E,81,B0,41,B7,7F,6F,78,19,1B,C6,16,B0,17,34,8F,5C,73,14,FA,F2,43,E2,26,59,59,5E,B8,3A,49,DD,65,80,26,9B,E2,BB,04,CA,DD,79,5F,8D,2E,CD,FA,62,9E,6D,38,CD,1D,4D,FC,87,65,50,07,EA,5E,26,BB,2A,F3,C5,63,82,C3,BE,EB,DF,93,CB,0C,BE,F9,B2,57,A0,7C,8E,A6,11,30,B9,60,AF,63,E2,4D,A4,59,2A,63,CF,86,0D,AF,9E,4A,E9,EE,C8,A0,9E,19,7E,4F,83,33,ED,16,6C,74,7A,5D,F2,1D,01,F5,D9,E5,D0,4A,E0,0D,61,FA,80,3A,E0,80,86,F3,FB,12,6D,B0,10,32,59,C1,6D,1D,EF,74,C7,BC,E3,19,78,B9,81,6A,5E,4B,A5,16,3E,50,79,0F,38,3F,D1,68,6D,79,BC,15,00,20,B6,4C,51,19,1D,FE,D2,49,94,CC,75,68,68,90,0F,A1,3A,E4,37,CD,92,4D,E6,88,08,14,FA,D0,C1,E0,4C,99,BC,19,AD,85,E5,D8,85,0F,6C,D3,21,F7,4E,B1,6C,D2,2F,45,A5,37,C4,5F,3C,9C,9C,37,93,1E,D6,E9,E5,1A,47,50,CD,35,E5,7F,39,12,7D,85,49,AC,07,D8,F9,D5,2E,77,2A,F0,0B,48,61,60,94,02,78,C6,57,E7,30,5A,A1,BC,D2,20,61,0F,1C,85,80,BE,21,1B,9C,AF,94,EE,F3,5B,B0,B0,27,5A,8C,16,C5,57,25,8D,C8,CD,FD,27,D0,41,FB,E6,65,8B,F4,C4,1A,98,9B,81,F9,7F,E7,30,BB,41,B2,9A,BD,1C,5A,90,2B,7F,5E,93,89,BE,C6,BE,41,E8,3F,0F,0B,CD,F5,F3,4E,80,08,4D,DB,41,8B,0A,D2,C7,D2,85,71,DA,39,97,C6,AB,88,31,85,F9,1C,6B,68,E3,52,16,52,BF,76,40,75,8D,10,D4,D5,7C,92,E5,CC,47,99,B8,3F,B6,CF,B9,ED,CE,B1,44,2C,6B,3F,11,7E,66,60,87,22,C2,6D,75,6A,C5,0D,F8,F3,5A,B1,03,D3,AD,9A,6C,30,EE,E9,7F,B2,96,1B,BD,50,FB,F7,DB,28,D6,EB,4E,6B,1F,19,D3,E9,C4,5B,2E,12,D9,62,99,D2,9B,18,3C,37,D4,2A,88,F5,1B,DB,02,02,2A,9A,77,19,82,85,69,F6,45,0C,73,D2,A2,F8,17,A5,33,30,FA,63,6B,40,CC,A7,6B,92,7A,7D,F7,24,B0,19,DF,B1,DE,8D,85,94,50,EB,B3,0C,5D,65,60,14,3C,38,DB,D4,0F,AF,43,60,00,11,49,D9,AE,EE,DB,DF,4C,65,E1,A9,65,4A,74,14,9A,F8,05,FA,6F,88,8D,12,D7,84,94,57,6C,7F,7D,2D,1B,74,F5,BF,9C,50,8D,ED,58,14,25,53,B2,A8,50,50,07,28,EE,DE,C1,6B,38,63,0E,8C,CA,D9,DE,D1,83,42,8B,7F,ED,AD,9A,45,A1,59,1D,19,CB,B6,C3,D0,8E,16,EF,A9,0B,81,44,26,05,84,BE,E2,86,F6,D2,0B,1B,55,AE,E1,0A,63,BC,3E,E8,E0,28,73,34,6E,BF,F5,15,45,B6,D3,4B,64,1F,94,8C,5C,D5,2C,45,64,1F,13,44,45,26,07,FC,2B,22,3A,18,0C,C1,27,7A,93,5B,42,7E,1C,24,E4,4F,21,3A,EB,C0,E7,17,6C,92,46,22,FB,36,E8,25,40,E3,54,95,2F,66,79,AA,82,83,BF,B0,F6,6A,C9,1E,34,82,4D,0D,3E,F0,45,F6,6F,6C,16,26,10,69,DA,5F,8C,CA,FD,89,6A,5B,02,13,0F,7C,33,EA,9F,66,BC,B2,8E,9D,23,D1,0A,A1,4E,6D,EB,01,03,37,0D,2B,E6,5E,86,68,33,DD,F5,95,2E,3A,CE,77,64,C3,AA,14,AC,43,6D,AE,E7,76,C5,7D,80,75,58,08,B1,F9,2E,90,F8,3E,77,92,66,C5,78,D5,3E,08,13,7B,F7,36,31,5D,58,8A,D9,A0,FC,EE,A3,D7,8A,9E,A3,9A,DF,28,2D,F1,65,A6,CD,2B,2A,25,0F,04,E4,7E,13,F4,4B,D3,13,C4,B5,AC,0A,6A,EB,F9,9B,2A,37,81,4F,E3,A6,86,AD,66,80,1A,6D,6D,3E,39,67,26,BB,8A,D4,B4,30,8B,75,26,C3,15,20,E3,EF,D6,87,2F,BC,E1,56,C7,E9,13,64,FE,93,36,9C,71,12,D6,5F,27,C3,CC,78,AC,75,FE,CC,BD,6A,DE,47,24,76,1C,69,2D,8F,A3,3C,DF,AE,AD,B3,6B,E9,66,47,85,0E,E6,5F,E1,EE,ED,84,B9,29,98,D6,38,59,2A,84,F2,3B,CD,F2,4A,30,0B,92,50,F4,3A,DD,76,70,79,47,C3,65,92,F6,1A,BB,A0,BE,66,FB,5D,3B,00,5E,73,D3,D6,9A,F6,07,A1,3D,5E,BA,9F,6C,72,11,AB,D8,D5,C9,AA,CA,F2,A9,08,24,97,78,60,A6,6B,C1,B6,15,FD,7E,32,69,2F,21,F5,92,0D,58,60,58,37,EB,B3,30,48,DB,DE,D1,B9,82,34,FD,D7,97,F3,9A,83,94,CC,94,12,8A,C1,F7,63,68,2D,6E,31,EC,CC,79,38,A8,75,94,C4,73,2E,BE,BF,D1,54,0D,81,9E,AC,47,DA,98,70,4A,85,34,F3,6D,8D,03,A7,58,4F,76,3C,67,BE,DF,3D,C9,0C,7A,12,A4,CC,DA,43,CA,EA,20,36,7B,19,70,7F,3A,C7,2C,89,77,7D,CA,2C,66,C6,F0,51,FF,35,45,8D,01,D9,70,B0,C6,48,03,B1,F2,A0,76,4D,B3,D9,4C,21,EB,4C,E5,9D,E1,43,74,8A,BB,60,03,96,D1,E8,70,86,7F,C4,51,F3,28,6C,BC,2A,61,AC,40,94,5D,93,8C,02,DC,04,07,58,A2,07,3E,B6,CC,87,76,92,3F,67,F2,D9,B0,83,17,6E,1B,38,8F,47,73,35,A3,2E,17,C4,74,23,A8,73,BD,7F,60,85,CE,86,5D,4E,32,9C,0B,2C,62,2C,36,A3,A5,CF,DE,9D,98,18,DD,EA,8B,93,BE,E2,A8,66,35,77,8B,D5,82,32,E5,31,BC,5D,B6,01,74,C6,24,79,26,13,AF,4A,31,F6,58,C7,78,51,63,D3,B6,94,9E,15,F2,B2,8C,FF,34,E9,63,34,C6,D4,A7,2A,F4,BE,2E,41,DB,10,79,19,93,4A,BB,12,AF,37,CB,2E,CB,50,81,72,A1,FA,D4,37,78,2D,0C,FA,50,80,00,BF,11,5C,2A,16,2F,2B,65,5F,7A,30,9C,35,11,6F,97,A2,EA,C7,13,0B,3C,43,55,A3,A2,48,F1,B2,C3,72,34,51,F7,46,D5,EC,6E,03,62,70,52,A2,07,88,1F,EB,A0,F9,92,F0,7F,3B,D1,CB,89,54,84,EE,FB,7D,2D,F0,C2,03,C7,11,03,59,AD,2D,25,6E,2C,75,7D,DC,36,6D,9A,CC,E1,C3,7F,3F,E8,1C,13,1B,6C,44,2D,B4,83,9C,86,55,88,41,C1,1B,27,DD,02,51,2E,C6,5D,4D,86,48,7D,AD,56,99,72,80,F0,61,A0,83,F0,E1,16,3F,93,C4,EF,C9,F9,E4,75,75,60,33,28,DA,3A,BC,4A,0E,04,87,FA,CB,C4,98,1E,75,A2,FE,85,97,C0,6C,23,13,5F,19,5F,94,16,75,56,49,14,EB,99,E1,0D,46,E2,23,00,BA,0F,9F,0B,50,6D,A3,88,FE,D4,B3,A7,8C,A3,5F,AA,60,06,AE,D6,19,72,26,B9,69,76,37,5E,C4,53,47,73,49,C5,DC,32,A4,C3,F2,D3,26,26,0F,8C,AB,F3,DB,9A,F3,E2,9A,E1,0D,9C,8E,92,F3,34,29,CF,9E,0F,F8,B7,44,FB,35,1A,06,F9,5F,78,F6,32,67,BD,FE,05,E1,85,09,E3,83,BC,41,55,F0,AE,5B,BA,F8,1C,01,AB,3B,29,4F,FA,02,67,8E,A8,FD,9F,B9,5A,B6,7E,02,32,86,CD,53,53,9B,91,72,87,5A,E2,AB,20,FD,50,80,CD,E3,E5,48,14,36,0B,F8,07,DE,FC,CA,82,76,D4,11,76,23,7A,76,A5,05,0D,53,28,76,94,F9,DC,B6,4C,34,7B,5F,1C,E7,8C,B8,21,A7,A0,77,48,C6,13,54,B6,8A,83,2A,DD,99,0D,17,36,A3,32,72,DC,C1,07,32,F3,C8,F0,35,F1,3F,AC,4E,15,FA,39,D3,90,B0,B7,FA,66,DD,B2,F1,21,AF,C5,A8,23,0D,C3,EB,86,1F,F6,76,26,24,7F,D3,2E,C6,13,AE,4C,6D,BC,F7,81,E2,F9,00,8B,B9,A7,6E,C8,45,F7,1F,7D,12,EE,FF,E6,E4,B2,C4,F1,16,43,FA,F7,22,74,50,A0,13,C0,BC,64,A1,F5,33,7A,BA,CF,10,6D,8C,E9,DE,41,5E,7B,90,43,6E,0D,07,3A,0D,A9,54,56,12,61,74,86,81,A8,77,48,F1,E3,3F,10,72,04,55,63,3B,C8,AC,00,EF,7E,05,73,37,93,1A,F4,14,4C,4D,EE,44,CA,96,AD,91,3E,C0,67,8A,01,4A,90,F7,A8,EC,DF,3F,69,35,A4,90,1D,C1,5C,60,A3,36,84,66,0B,C6,72,D8,5B,3E,E9,96,D9,A6,E2,03,95,C6,ED,75,85,E6,00,FA,20,9F,15,F6,3C,D8,EC,27,1D,75,07,2A,50,4E,B7,B3,BB,CC,B3,06,57,7C,21,38,74,9D,82,73,76,34,1C,88,C3,6F,17,0E,97,F1,85,87,66,35,6C,02,B7,A9,6E,26,05,D0,A5,8F,06,40,9F,01,CC,29,6E,CA,16,20,EF,23,20,1F,69,54,5C,E5,82,11,02,47,93,0B,C6,F7,F4,62,1A,E3,C9,90,70,89,EB,B7,CF,45,94,85,0C,51,0B,15,56,14,69,5E,45,4A,35,C5,DE,65,5A,7D,7E,71,DF,12,97,A8,5B,6D,6F,3B,3A,B9,92,A8,84,57,3E,9B,0F,4B,81,0E,9E,BA,B9,FB,20,8F,16,A3,1F,76,54,DF,9A,AF,17,0B,DD,3C,D4,D2,13,1E,C1,2F,F7,75,11,42,16,70,F6,0B,FB,3A,7C,40,57,44,84,66,62,89,FC,97,50,88,D1,75,66,8C,90,6A,2B,DA,90,15,F8,F5,0D,76,D7,CA,A9,BD,05,6D,26,D3,70,57,CC,C6,BD,CB,BA,13,F9,45,28,14,4C,32,34,52,9A,55,28,45,E5,4E,D6,2F,E7,C3,22,93,73,AB,F4,4C,EC,75,54,64,DF,34,09,B2,68,D3,48,A8,E4,82,EB,B9,02,B7,0B,56,DE,65,FA,86,6B,FB,E6,09,4C,59,8C,83,99,C8,C3,94,98,F9,42,03,F0,CD,37,E2,2E,53,2A,98,24,1A,99,21,4B,06,F4,B8,70,1C,5C,C7,A3,E0,C7,14,C6,6F,81,5B,4B,DF,7B,C8,AB,9E,46,44,2D,50,AB,EB,23,19,D4,DA,E0,1E,B8,84,E8,F3,28,F6,40,F1,A8,40,27,F4,69,2A,4E,CF,FE,30,5A,FD,22,4F,85,2E,FA,3C,B5,06,16,16,69,76,EE,6F,2F,8D,AB,6C,E5,40,7C,9F,73,26,59,E8,73,5E,0A,97,F0,19,53,F3,52,A4,4F,92,77,8B,3F,75,79,A4,5D,2E,C6,36,83,FD,B1,48,D5,A6,67,95,40,36,E8,5D,8A,74,EB,DB,1B,C0,76,E2,50,09,C2,B5,0A,6B,B6,21,FB,EC,34,0A,27,21,60,83,3B,7D,ED,8E,B5,F7,1B,DD,9C,CD,47,44,60,A0,92,EE,A4,EC,C1,A5,6C,88,0B,18,90,22,44,BB,2A,FC,9C,A0,24,1E,E1,34,49,63,64,EB,3D,59,6C,25,93,67,36,E1,A7,C9,96,52,17,B8,C5,6D,CC,60,0C,62,25,DE,4B,C4,CC,56,25,B8,2D,FA,98,BB,4F,60,C7,0B,0B,78,C0,03,12,2A,F6,6B,68,BF,1A,2F,18,24,58,E7,AE,B0,4A,2E,AA,D0,4D,FD,7D,B1,2D,8A,67,2E,2D,69,6C,69,84,7D,60,97,56,CD,78,9F,90,F4,28,D3,E7,44,B7,11,92,D0,23,07,17,85,28,B5,74,9C,E3,F2,AA,64,F1,4E,EA,E7,6B,45,BA,14,86,96,53,DE,2A,42,CC,B9,D6,DD,84,22,3C,C5,48,EA,12,E9,43,C7,32,67,2F,86,D8,D0,6C,22,17,2D,77,91,AE,29,7C,25,CF,C6,C7,C2,92,72,56,26,47,51,C2,0D,CC,4E,B1,05,86,3D,1D,42,FE,AF,AE,FF,D0,A0,8D,14,AD,6D,0E,C1,9D,EB,1E,6B,05,3D,0E,F2,33,6F,3B,C5,47,AD,34,6C,B7,CF,96,5B,1E,B8,77,2A,3E,9E,55,41,69,F7,32,CB,64,27,1E,A7,F1,DE,8D,18,7D,7C,2A,2D,27,58,48,B8,1F,E4,0B,2B,A5,B0,1C,19,80,11,13,69,3B,92,1F,3F,E9,C4,3B,43,39,FC,52,66,5C,EA,D1,18,9F,ED,AD,62,1D,24,A1,85,DF,69,CD,48,E8,E7,0B,F1,8B,1F,6A,87,4B,3A,C6,BF,A1,00,50,19,53,80,33,AF,EB,71,B7,6D,C9,4D,7C,CD,DE,F4,A1,7F,A3,54,5D,19,67,1E,A1,3B,5A,58,AC,FC,51,45,5A,2E,3F,6C,29,37,A2,52,2F,5A,9B,A7,D7,A2,3A,DC,DE,EA,9D,83,64,A8,27,BB,39,8B,2C,29,C2,8F,11,A1,4A,48,8B,6C,7D,C1,1D,13,AC,BC,76,2F,B3,BD,05,9C,EF,37,6B,01,AA,4B,63,B7,69,41,41,8A,D5,43,FA,7D,B5,FA,AF,A1,05,D7,FE,35,68,0D,C8,01,40,E1,63,B6,3C,BC,FC,B0,D5,22,3F,37,F7,A4,13,56,77,90,D4,CE,16,88,E4,7E,64,CC,B2,87,8D,99,C9,B0,AE,77,30,37,11,CA,BB,C0,61,B6,7E,5C,3F,45,0C,ED,A2,A8,19,94,29,7A,0D,BC,3F,17,6C,F2,6F,87,3E,17,F2,45,CC,72,88,F1,16,64,8A,DF,8C,00,69,A2,05,6B,49,AB,A1,73,4D,AC,20,6B,CF,E5,3F,04,CA,A6,67,93,E9,05,B7,F2,29,9C,FC,D7,60,2B,49,1A,EA,A1,95,4E,D0,34,E8,2D,8C,1A,76,F2,04,2E,1F,8F,D1,57,99,86,1D,32,8F,D1,39,3E,77,CD,05,17,82,E7,43,0E,07,0B,4F,9F,A1,34,E4,90,A5,50,3B,5E,AE,11,3D,5F,98,F8,F6,67,1E,62,38,EE,94,B1,CA,FC,E2,A6,63,A6,E6,44,08,BB,10,11,76,E1,CE,92,0A,CA,67,1F,D3,A7,4E,F8,3A,64,1D,C7,37,14,49,FA,E6,BA,15,9B,86,75,C5,CA,6A,65,FD,07,58,31,60,69,4E,1A,CF,A5,75,7F,29,DB,41,37,72,6E,A3,51,CE,DA,65,82,CC,39,B8,9C,F7,95,A9,AA,16,0A,BB,C4,FD,E0,E7,98,C4,27,CF,BE,A0,99,46,47,92,50,9F,DF,72,5C,FD,E7,17,5F,DA,21,C0,36,D8,16,22,CE,1B,60,C3,25,67,32,11,7E,A2,E7,44,21,AF,F1,0F,26,9B,73,97,EB,64,27,90,C4,F0,A0,6E,FF,55,FC,FD,71,05,3F,8A,B7,BE,53,0B,87,8E,E1,CE,33,03,E9,69,07,80,C5,5D,83,16,0F,0B,45,30,7F,9C,C3,02,B8,B4,B1,A4,72,35,15,84,E4,DE,A2,26,73,38,F0,D7,60,2B,15,CA,B9,37,DC,21,29,F6,CF,46,14,DD,C7,8D,C7,50,2F,17,58,16,23,5E,A3,B4,2D,DD,18,6D,D8,72,1B,F2,F7,14,AA,27,BC,CD,FE,DC,C3,AE,45,A1,CB,5D,D5,65,BC,53,8E,39,0A,9A,E3,38,03,1A,7E,C4,98,24,E8,88,92,0D,16,F3,D4,92,81,7F,5F,CE,BF,7E,18,1D,A1,E2,7E,A8,D7,64,B0,8C,8D,A3,99,B9,C0,C0,B2,FD,88,70,A9,7B,2D,2B,39,E4,BD,E5,3D,F9,53,E2,5E,5D,2A,1F,61,2F,47,B9,43,FD,34,D3,FB,37,80,B6,2A,90,52,7B,AF,85,5E,9D,94,29,E7,1A,E4,47,7B,E5,83,A1,DA,C4,44,8A,74,63,56,B7,AD,38,B7,7A,75,99,5D,BA,D0,C2,EC,2F,C5,51,3F,AC,E4,B5,FC,43,FF,2B,0B,75,A3,A3,8C,EE,B2,96,67,55,AE,2D,41,B3,5A,8B,13,9A,5C,9D,FA,C7,E8,3C,09,15,FA,20,2C,ED,0A,70,DC,F9,2A,C3,D1,CF,E0,BA,DB,6B,FF,89,E3,AD,D3,12,D2,01,DF,EC,32,94,DE,86,18,7D,15,71,6C,CE,42,DA,B2,D1,0B,F3,B0,A3,FA,86,1C,76,C2,54,36,23,6E,17,81,CC,79,86,08,AC,E9,D2,D2,45,0C,D4,77,49,C7,BD,AA,BD,62,34,12,D5,94,36,9A,C3,07,57,39,8C,7A,72,CD,EC,78,5B,29,55,44,A9,88,75,FC,EE,85,94,59,F7,2E,3D,F5,7C,CF,12,F6,EF,01,73,ED,67,59,0F,E9,45,43,C4,69,02,4C,8B,DD,95,CB,B0,45,ED,69,77,E0,5F,6D,45,DE,56,E9,D1,70,07,D8,72,50,D0,EA,67,08,94,F8,70,5C,D9,D3,3A,D4,3D,B3,AC,E6,D0,2B,B7,5C,C4,3F,91,28,D8,58,51,8D,A3,CA,FA,0D,DA,7F,B5,BB,93,94,60,96,23,55,FB,80,BA,F0,32,67,10,8A,2F,4D,7C,55,FD,19,82,9B,55,F9,49,69,C4,B1,D8,D5,95,6D,3A,52,09,FD,7D,53,EF,3E,A1,00,C5,8B,FD,E9,F8,3A,2E,12,C5,FE,41,7C -roundConstants = 28,50,D2,6A,38,5F,17,24,61,65,AA,54,50,E3,33,91,39,ED,9A,B4,57,8F,E9,C0,62,BF,47,11,94,0B,30,36,FA,8B,B6,F8,86,2D,C9,A3,66,9D,E0,BC,67,4C,A3,2E,81,E2,47,5B,40,C4,32,61,F0,A1,0E,B8,E6,CB,24,38,65,3D,33,38,39,FE,01,78,B1,E0,8D,59,61,8B,CF,FF,EC,EA,8F,8A,5D,BB,D1,29,59,29,08,0D,4B,1B,B0,9A,4A,44,17,43,69,EB,5C,F1,C0,70,FD,06,DA,8C,29,CA,A5,63,D3,DD,9E,18,5D,DC,9E,ED,74,9D,2E,2D,C9,9C,74,50,F3,49,3B,0E,A4,BB,30,61,2B,E6,F9,2E,B1,B4,A7,57,20,2E,86,4D,EB,0A,FE,AD,19,E9,05,7C,6D,48,9F,E0,E2,86,C2,ED,ED,C6,79,67,17,E0,71,0C,60,7C,A6,95,00,07,9E,F1,9F,FC,00,EE,1B,0B,FC,EA,13,BF,97,1D,E6,25,D1,D9,D4,68,9E,7C,9F,A6,B9,0A,CF,DD,92,83,39,0A,E5,FB,1E,17,32,35,5D,3A,B2,9C,E0,D4,6B,26,75,D5,1F,68,D7,36,EA,49,1C,55,F9,DC,27,A6,C6,AC,59,A3,5F,84,7D,B7,63,0B,1E,1C,58,73,CE,40,CB,7F,C3,A5,B2,95,55,1F,51,40,BA,8C,8B,16,EB,09,33,95,B3,C7,F0,93,CF,A2,EE,89,10,49,66,FE,25,4E,1A,9D,5C,BC,7D,77,76,25,A4,37,24,B4,93,99,97,B8,AE,0D,B5,D8,DA,E7,D4,AC,0E,C9,00,97,81,3A,65,47,0C,80,86,66,DE,EB,57,17,04,C4,81,6D,74,99,6A,C3,72,78,E5,CA,47,93,49,AF,62,56,76,46,46,22,1D,78,05,CC,EF,40,84,F3,FF,50,1F,A1,7D,6A,1B,BA,ED,1F,DE,B7,CC,EA,ED,CF,79,23,D1,13,77,89,BC,59,26,CE,5C,50,F8,FA,6C,3D,9C,F1,48,9F,00,18,3F,40,B1,D7,AD,D6,D4,F0,A1,F1,1A,9A,50,9D,2E,B6,F9,4F,0C,65,50,4B,E3,37,45,44,51,B1,11,FF,14,F9,D2,5B,FC,71,7C,5B,95,81,20,4A,CA,F8,9F,A2,33,50,74,B1,BC,A2,21,2B,8C,89,D9,4E,AB,71,12,DD,E1,5F,74,F9,90,24,D0,7B,AD,83,86,8C,54,AF,52,DC,49,45,DE,8E,B3,1F,A5,A1,73,15,C4,05,AE,F7,EE,9F,A4,2D,1F,53,6B,07,F7,72,71,10,A4,49,FB,47,07,1B,F2,65,5C,2F,22,72,7F,21,C3,2A,7A,FF,61,30,C3,5B,CD,88,D1,29,36,22,E5,47,04,75,32,44,CE,3F,9E,8F,31,84,47,D1,3A,F8,48,71,3A,2E,AF,1C,B7,5B,56,53,1D,42,6A,15,3F,AD,94,3D,36,5E,65,C1,C2,23,D6,70,B0,00,E1,8A,89,79,F0,E6,73,8D,D3,EE,53,00,B3,47,C7,5B,E4,FD,56,08,B6,57,3E,D4,CA,FF,B0,FC,2C,52,CE,56,10,87,1D,AA,08,ED,68,FB,18,46,B0,A3,5D,B0,96,A5,4B,25,FA,6F,B5,4F,9C,08,D6,ED,86,F6,C5,8C,B0,13,C6,02,CA,15,01,00,89,77,BF,51,9E,BD,C7,BE,30,33,5C,BF,90,70,D4,37,7A,68,B5,D3,1B,CE,29,CF,50,33,5C,BF,3C,16,43,E3,27,B7,C4,DB,48,BF,4B,FD,EA,26,D0,F0,50,75,8E,92,C5,C1,DA,09,CD,2C,E3,4B,4B,F6,E6,DC,08,59,9E,9C,F3,3D,00,19,B2,C5,50,52,84,08,54,63,FE,5E -keyMatrices = D1,35,FF,D3,AD,35,CB,67,3A,02,1A,68,37,F6,C3,FC,54,7E,5A,1F,24,47,52,ED,78,61,12,81,00,62,9D,19,4B,FB,9A,58,91,7F,6C,33,9A,A9,20,FE,4F,B3,9A,0B,7C,2E,B5,93,EC,88,18,BC,BA,F3,9A,2F,03,B1,2C,18,E6,EB,F1,83,5C,78,2E,B8,5D,A5,DE,05,05,B5,9F,66,A9,A3,50,35,08,44,5F,95,6C,E8,DF,08,22,45,2B,2F,9B,82,9D,55,2A,DD,59,2B,5F,F1,6E,78,9F,0E,09,94,A1,79,E5,4C,16,BC,54,59,32,AC,2F,C0,A9,54,66,51,D6,22,2E,D1,60,34,27,3F,12,40,43,F3,A1,17,30,CF,77,92,B2,9B,D0,29,8C,73,51,9B,B4,79,22,1E,60,0C,BA,A2,EC,87,23,7B,87,C9,45,EC,C3,D7,AB,D8,C4,80,31,6D,0B,DB,98,2E,7B,8A,30,93,3C,54,03,16,1B,2E,44,A9,07,FA,62,27,9F,4D,B3,8B,91,D6,7B,D2,3F,07,F3,3D,8D,17,D1,19,FD,CA,F1,4C,25,DF,E5,C1,47,88,8A,B8,03,C5,AD,05,E7,E6,1A,0E,29,C4,98,A3,5A,61,11,8E,B8,32,F0,A8,40,5D,00,20,D6,DE,FA,B7,D3,5D,B2,D1,57,BC,E2,C9,04,C9,C8,20,1D,3E,98,A8,55,1D,4D,00,CB,1B,92,96,4E,83,13,92,9E,8C,9A,0E,5A,D8,05,D0,61,69,CF,56,09,F3,C2,6E,0F,A3,6B,85,90,D8,93,07,72,1C,3D,66,81,1A,1E,16,EC,84,62,3F,D3,7A,20,9D,6B,9F,EA,F5,49,5E,E7,6F,D3,33,D3,5B,1D,92,DD,57,F4,98,C2,D1,71,43,15,D5,78,91,3A,8A,94,8F,FC,42,EF,32,C6,CF,2E,98,02,DC,58,DD,E5,68,F7,C6,BF,F6,64,58,EE,EC,E5,F6,BE,5A,C1,3C,36,F1,1D,98,09,CF,67,4C,28,F4,9C,BB,F3,1D,1C,F7,FB,B5,E7,92,8A,72,C0,E2,3E,FC,D0,76,10,3F,44,CF,7D,8C,5C,03,A4,AB,0F,7C,7F,E5,A5,95,93,F4,F9,E6,8F,37,DA,F3,49,00,B4,8A,63,D6,BE,DE,69,99,B8,58,25,59,A3,72,E9,BA,ED,6B,9B,DF,01,16,08,5A,C0,33,8B,62,07,F0,90,1B,FA,FA,FC,79,18,09,A8,2D,00,75,9E,57,50,E2,8F,3E,3D,E6,03,54,B9,FD,EF,FA,F8,FF,EB,87,5B,11,F7,A8,AE,89,0F,AB,B3,96,6D,CA,0F,46,81,68,34,99,3B,A6,58,A3,FD,A2,F9,AD,6E,E0,07,94,E3,13,E9,D1,5D,8B,9E,55,47,CA,A3,78,0A,1C,1E,12,2E,0F,53,19,3C,5C,B5,93,E5,7F,41,38,D0,5D,F2,2C,D3,73,1D,82,43,BB,E1,1C,70,A6,56,CE,4F,0F,2B,6B,4D,F9,36,4F,7E,96,A8,70,27,9E,0F,11,1B,2B,0F,EF,8B,9D,AF,EE,CB,3F,C5,7F,57,1A,0E,D0,8C,0B,3D,A7,4D,C5,AF,AB,15,4C,7A,35,56,D8,F8,FE,E3,C1,7D,9D,6A,CB,35,F0,3F,49,08,95,43,A3,8C,93,38,90,55,17,0A,4D,04,4F,30,A4,EB,CE,53,1E,6C,33,AA,7B,12,37,05,DD,E2,B1,0A,F1,FA,0C,61,E3,EB,11,3F,DE,BF,46,56,07,4B,E7,0C,D3,CE,82,59,8E,36,5D,B6,E6,AF,B4,DD,26,21,60,D7,29,30,8B,45,F3,EF,81,EC,0A,8F,CA,0D,2F,79,22,71,27,ED,9B,65,D5,92,A6,57,9D,24,CA,0B,6E,A4,05,C6,B9,E3,D2,BA,62,6E,61,8A,81,44,1D,0F,A0,5E,6B,9F,B0,78,15,29,39,76,32,41,B7,4C,D7,A5,50,30,8B,92,4A,10,0A,A7,BE,D8,16,C3,B9,39,25,80,54,A1,AF,32,ED,3D,CA,B8,0B,6A,54,AD,D9,6F,B0,A8,18,87,34,8E,89,E2,45,5E,07,CB,17,14,57,7C,62,86,39,2F,D5,56,0B,2D,0F,7B,1F,15,06,D7,16,A6,B0,00,A5,D0,58,92,52,B0,3A,FC,4F,24,42,84,E2,56,DA,F0,ED,E5,8D,2D,0A,C9,29,48,40,45,8B,05,4E,AB,62,7C,8C,89,71,A3,F0,46,99,65,9B,41,F0,93,DD,BA,66,4F,74,6F,53,F1,1A,74,B6,97,A1,7F,C9,7F,FA,78,43,9B,09,F1,C7,45,CC,14,00,4C,CB,AB,DF,B8,A6,C1,0F,68,CA,64,4F,C1,B8,33,60,86,F3,2B,FF,68,01,D4,2D,F5,09,0A,33,7E,DE,B3,93,04,0E,F5,37,C0,31,83,A5,C6,F9,C5,93,4C,47,FF,D6,BE,50,3D,FF,0C,D8,32,49,53,89,FF,A5,4B,71,16,F0,A8,77,53,79,D2,F5,35,D0,71,02,3D,7C,F4,06,CB,95,1A,C6,87,9E,66,A9,50,D6,D8,FC,13,6D,08,90,98,27,84,D3,78,0B,79,C6,FC,A5,58,10,A1,3A,4A,9C,42,43,5A,4A,E9,06,4F,59,58,4A,B5,35,FE,85,F0,16,70,6A,B1,F9,41,5E,27,81,58,71,89,87,F3,AD,46,6B,45,8B,6B,E8,9F,CE,28,FB,B9,13,2E,9C,BE,01,7C,64,6E,5E,19,79,44,AD,D5,E8,9F,04,12,8F,A7,0E,02,E1,B0,21,2E,64,AB,BA,7F,DF,86,D6,FD,94,D6,24,4C,21,56,4A,C2,65,97,6F,A9,63,1B,A4,2B,72,05,A3,80,27,80,27,87,B3,0A,41,F6,F4,F4,03,D5,C8,20,27,71,38,5C,CF,CC,90,4D,D9,00,66,24,02,0E,02,8F,9B,4C,50,D7,1B,7E,FF,BB,B2,80,DD,E8,DE,74,2C,F8,D2,D1,ED,CF,7E,B1,E9,DC,C3,92,E2,8E,CC,62,B7,62,02,9D,8F,D6,8D,F9,24,03,43,34,B0,69,07,6A,4A,CB,62,36,71,11,C0,89,B1,4D,28,A7,9D,C5,B5,A1,02,04,AE,86,8D,A8,5A,3B,42,E1,B0,01,BD,89,63,B4,2D,8F,2D,5A,70,C9,D0,D2,5E,C4,D8,35,69,76,DF,07,2F,B2,41,58,AD,A6,A0,39,9B,A0,9D,1D,90,CF,10,E7,0C,6F,54,1C,80,E5,8E,A3,68,DB,1D,BB,BB,8A,44,84,04,DB,C5,AD,F8,A4,B2,E3,BD,60,3F,75,6A,A1,57,CE,8B,16,C7,4A,EC,8E,31,E4,86,C1,BD,AA,33,62,53,CB,A9,ED,55,3A,A0,BF,FB,29,8B,74,1C,7B,63,2B,F8,01,4E,A1,2C,B7,FC,04,6D,5F,0A,D4,EF,4D,FD,13,88,B7,5C,2F,B8,1B,05,17,36,93,E0,04,38,33,85,C3,B7,5D,79,41,8D,7F,0F,40,06,8F,74,5B,11,F9,41,BF,FC,3E,17,31,E9,09,F9,D9,C8,68,31,8F,AF,D0,17,B0,57,8E,74,30,6E,60,1F,92,DB,A6,70,24,2D,0A,1D,80,F0,4E,24,D5,3D,BF,12,BE,4D,4E,2A,E0,16,18,92,65,7C,C9,D8,1C,2D,51,9E,DA,12,DD,19,17,55,76,A9,4D,BD,81,AD,20,CB,FC,BF,CF,B3,2C,D9,81,6D,95,E2,AE,C0,35,F9,5F,E4,BE,1C,E2,B8,58,40,0B,20,64,C4,F2,7C,F9,B0,27,3C,29,1A,B8,E2,42,EE,BA,46,41,2D,CA,72,18,70,CC,DA,30,05,3D,96,7B,5F,0D,E5,D7,FF,4C,CD,BC,95,45,75,9F,25,7E,B5,69,9D,EE,E4,C7,44,CE,39,01,AB,A2,1D,7C,2F,5C,ED,ED,2B,92,F8,2F,01,6E,C0,51,8C,BA,2B,32,07,E1,06,5A,00,0F,00,C9,E0,CE,2F,E9,B9,4F,BE,E8,A6,4A,2C,6C,4D,7F,C7,1B,62,DC,4E,40,E5,AE,0E,C5,D3,6D,2E,A6,7A,8A,23,46,A1,E6,96,AB,F5,BF,D4,C9,ED,63,58,47,78,E9,56,BD,A1,59,44,46,51,03,93,F9,08,22,92,AE,5A,9D,55,43,13,FD,EE,4F,A2,4B,67,C4,41,17,89,6B,34,6E,E4,62,2C,86,3E,AD,8D,88,54,F2,34,08,96,33,19,74,DF,DA,47,42,D6,66,35,10,4A,2C,5F,D3,3C,6A,42,DE,A1,7B,84,8A,A4,32,8E,95,FB,C6,73,1F,C5,2F,C3,88,93,46,D3,7D,39,52,35,A8,16,B0,9F,D1,16,DB,24,57,E3,C7,2F,8E,15,C9,BC,68,F0,B2,87,C7,8D,64,0A,2E,23,F5,64,EC,5E,D9,9D,08,E3,77,48,EB,C6,8C,1E,5B,44,E7,28,DD,94,00,D9,D8,24,F3,34,1E,28,91,1E,5E,DD,00,97,9B,29,D2,5A,F5,AB,88,44,A3,B7,B5,4B,C9,3A,A2,17,28,7A,47,D0,2F,67,8E,32,0C,08,FC,9C,96,F3,F8,FC,0C,C0,06,7F,56,D8,45,EE,04,B6,0C,5A,DD,D1,A9,EE,70,1D,7C,A2,CA,00,D9,DF,05,F6,82,EF,7F,05,62,18,6F,75,14,AC,4A,E7,74,E7,B3,15,84,CF,B6,21,77,8A,08,70,D0,C5,D3,DE,70,20,ED,1E,E7,03,66,97,55,2A,20,C2,63,A5,09,C4,6F,15,94,70,D0,DD,EF,05,10,86,19,93,A3,5C,D7,38,98,A1,49,C6,DF,6B,06,5C,D3,7D,A7,6E,29,30,92,88,53,28,42,D3,CC,4A,FA,3F,C3,CA,4D,D0,A3,35,04,EC,59,AC,F0,35,1C,04,94,A2,98,42,86,1C,93,48,EF,1C,F4,C9,58,B2,82,D7,D8,9A,AC,2E,93,C8,20,36,A3,79,91,75,18,3D,C0,DD,EF,BE,0F,75,45,FF,D8,4F,E2,AA,44,2D,30,DB,FB,FE,14,D6,F4,AC,22,47,2C,84,F9,FC,F4,5D,F2,76,1F,A7,2C,88,61,BA,46,79,4A,39,71,7A,78,94,E9,09,19,15,86,34,94,BE,51,0F,0F,3C,B0,09,15,9C,64,38,0C,05,73,08,D6,B5,D6,67,2E,99,77,31,A8,70,7B,3A,AC,91,06,97,83,4B,A1,2F,8A,E6,DA,C6,12,58,EB,5B,B1,74,57,33,7E,DD,D3,4D,26,CA,11,F4,34,E6,E2,53,FA,4B,87,C9,A1,DA,41,79,D9,97,B9,1D,32,29,85,D0,8F,81,A6,F9,F4,94,3C,70,35,A8,0B,3C,26,09,4D,AE,DD,71,4C,E3,A7,00,72,31,B6,4A,A0,99,CF,6C,57,B3,63,D0,1F,DF,5B,FE,4C,D9,95,A9,80,17,73,94,75,A8,F7,A0,FF,0B,50,64,F5,0B,70,A8,BF,C0,5E,DA,2D,FB,8B,12,3A,AC,CB,0B,95,F7,EE,28,04,7D,78,9F,B5,90,69,C2,05,E1,2D,2F,9D,F8,78,63,A5,E1,51,44,6C,86,57,6D,07,62,D5,34,E0,80,B7,36,4F,B2,DD,6C,25,51,F6,BB,0F,9F,CE,56,1C,47,E2,82,15,52,A2,78,22,4A,63,AD,9F,38,0E,39,04,3D,33,AC,89,1F,80,FF,18,DB,C9,F6,4D,94,D5,E6,16,89,09,90,D6,6B,E9,D3,AB,5C,1E,F6,EF,0E,DA,09,1A,9B,21,2D,74,B9,9C,5C,85,2F,4A,32,D1,EC,12,7E,DC,E3,18,26,6F,9F,25,65,AA,CA,3E,3F,BA,57,BB,6A,1B,A2,62,A9,83,D8,0D,E8,E1,7F,91,69,01,57,B6,EB,F7,B0,84,DB,E8,E6,90,F0,4C,E9,1C,9A,BD,14,FB,15,89,F2,48,02,3A,C4,54,A2,73,D3,21,7E,25,C4,C0,1C,C4,88,D8,E1,18,78,A4,A2,7B,E9,9E,81,39,4D,E8,64,7E,AB,D6,89,3A,88,EF,94,9C,4D,BA,49,DF,A1,79,AC,10,3B,D2,83,43,83,DE,96,E6,8E,26,6F,83,72,C5,9D,19,28,72,C5,60,7E,9F,24,62,B6,58,2B,E0,0F,25,D8,3D,BE,14,B3,FE,B6,24,C7,F9,2B,C3,F1,EE,2E,02,F1,A6,3B,6D,E0,E2,AF,EF,5E,D7,50,5A,19,2A,D4,78,0D,04,EB,BA,55,80,6C,F3,A6,AE,13,64,5E,51,A8,10,DE,B3,92,2A,7D,CB,C0,DE,CD,AE,C4,5A,AB,7C,79,69,2F,75,E6,5D,4C,46,09,72,A6,4C,CE,7E,6F,12,16,40,A3,C7,F2,D1,D4,E7,52,B3,6F,35,04,29,B9,DD,67,9E,89,85,6A,8B,C8,71,BA,8E,FF,02,AA,37,DF,16,92,7F,22,9F,35,57,18,07,BA,55,80,E2,86,CC,4F,0F,73,D9,21,2A,4C,32,33,CB,F3,59,21,E3,22,C4,F7,71,3A,1E,F5,B9,19,B6,A2,45,04,C7,40,67,AB,2A,30,10,22,E4,D2,9E,4B,06,52,8D,A1,36,FD,BD,92,7C,D9,A5,ED,EE,68,DC,82,31,BE,8E,33,7B,18,0B,81,2D,0C,A6,74,15,C8,7A,6B,F1,69,CB,2F,CB,73,81,96,B6,6D,6B,5D,58,FB,02,66,7A,2E,3A,08,06,67,86,04,ED,CB,55,31,F9,65,34,79,45,21,B8,22,D0,19,08,5F,9E,DE,B8,D6,ED,39,60,DB,9E,12,C9,3F,29,6B,9B,93,56,D5,53,18,C4,83,11,3B,6F,04,55,90,18,00,C0,4A,0F,66,FF,DE,69,0B,66,8D,0A,AE,CD,43,8E,59,1E,33,78,9D,4E,98,88,B6,B6,E6,9F,BD,78,BA,FE,10,C0,54,EF,16,50,DC,30,53,06,F5,87,AC,0E,E9,C0,B7,1B,B0,B4,F7,DF,03,BD,B8,46,9D,B2,7C,48,F0,9E,6C,22,50,B9,E7,C4,D6,F8,67,AB,4E,BE,C7,D8,FE,C3,7A,91,8C,2D,69,EE,12,A9,9C,FF,0F,5E,25,58,08,7A,20,2A,E6,9A,52,6D,36,97,6D,98,5D,47,0B,A3,4E,AE,E5,30,23,53,D0,5D,9C,2D,87,ED,F4,C9,A3,B9,4C,4B,77,C6,0D,D1,46,82,2A,09,4D,B2,EA,1D,8C,42,2E,D8,8F,D2,0C,27,D3,29,0E,6A,0B,11,3D,F6,73,4B,0B,30,57,ED,B8,78,61,3F,45,96,90,DC,2D,F3,BF,DD,68,A9,C3,07,27,E0,6B,73,B0,19,A1,F6,5E,07,BF,5C,82,B3,93,8F,0B,7D,F9,F6,7E,1E,05,6B,DC,3C,A8,C1,A0,F1,94,BC,2D,73,B1,93,2F,71,BD,65,23,BB,8E,08,3E,A5,FA,50,AD,D3,AE,71,11,AD,D0,C2,5F,79,FD,97,13,A4,6D,A7,E7,8C,A2,CA,18,8E,C6,F7,E8,B1,D7,8F,D0,86,74,1D,E3,09,68,16,5A,86,8F,49,9D,88,D7,DB,17,4B,48,34,2C,6F,50,34,F8,A3,E9,34,1F,93,82,DA,B9,B6,67,7C,0F,D8,AB,A1,C4,84,49,0F,18,54,8A,ED,64,A3,69,EE,33,1C,B9,7A,DE,3F,25,BB,39,8E,F9,11,6A,6B,8D,47,37,1E,5A,F5,8F,6E,C6,B9,AA,9E,56,1C,CF,A3,2A,1D,34,FF,F3,B9,1D,38,DB,D4,37,6B,05,AF,11,F0,B9,88,62,DD,53,DF,0C,DE,37,86,E1,46,B0,1B,B2,68,D4,96,11,1F,6E,F5,4C,FA,AB,7E,93,E5,93,3E,87,03,69,1B,FC,F5,E5,C0,C2,F2,7C,A2,44,23,EC,18,22,41,EC,4C,2F,0F,19,FC,6B,31,59,41,7F,AA,AA,17,F9,AD,5A,00,0F,72,A7,17,BF,64,CA,EB,18,78,62,8A,36,2F,04,04,DE,4A,76,BC,16,66,2E,47,98,1A,54,AA,5E,A0,BA,5E,C6,E6,D6,60,9F,27,26,C0,ED,9E,EB,C0,59,DD,6E,EE,72,84,9A,23,A9,1D,14,32,06,3E,67,B0,86,33,EC,A6,79,DE,2E,CB,5C,53,42,4E,F0,1B,3B,DD,22,E7,C0,CC,8B,C2,CC,C5,54,0D,8F,B6,F8,A2,C2,0A,4F,56,56,73,B8,EB,C1,92,59,E7,DF,C6,8F,F0,84,DD,0E,91,E6,A4,9D,F4,77,CF,01,B8,A9,D0,59,0E,08,CA,52,30,7D,FD,12,A9,CE,EC,39,04,49,1C,F6,36,F0,BB,CB,49,29,9B,9F,6D,1D,3D,75,0D,B3,B6,E1,72,1A,A0,84,FB,C1,F4,9C,15,31,38,50,07,C3,E3,E6,07,61,F8,43,65,92,A8,75,E4,C1,F7,5F,A8,EA,69,25,90,93,BB,A3,41,3C,6B,A7,95,2E,33,DF,EA,E6,F1,4C,B6,D5,D0,CC,9B,E6,C0,49,28,58,A6,CD,2E,5A,D0,3B,60,61,91,D3,7F,58,F2,CA,44,8F,DD,3B,7E,50,D1,B2,02,25,37,2A,40,67,7E,9C,F8,88,CB,ED,E6,36,17,E1,CF,1B,68,93,8F,6F,B7,76,64,7D,FA,69,3E,20,0D,91,70,4B,E9,D0,52,F8,FC,D2,26,7F,E9,27,A7,CD,5F,F7,26,38,FB,7C,72,86,3A,C4,9D,18,09,CD,D4,08,AC,CF,92,15,23,A4,3D,1B,20,70,DB,64,37,AC,69,FC,1F,7F,0E,F3,B6,48,F1,AE,D1,25,51,A5,3A,B8,9D,0E,0C,3A,43,5A,E2,0C,97,38,7D,18,26,90,AF,27,68,32,85,5C,A2,41,BF,6F,37,59,F1,E0,FC,5E,6D,18,A3,B0,9D,2D,4F,09,6B,9A,23,09,5F,B5,2A,42,22,4A,AF,34,55,D8,83,95,1C,C3,DD,9A,EA,52,A8,ED,2F,54,D3,BB,AF,8F,BB,4F,C7,29,57,2E,1D,A8,C7,07,B7,1A,75,7D,67,AF,BF,84,DC,88,B1,62,19,AC,FD,B1,A1,EE,86,79,56,E0,4E,A4,4F,71,76,B7,D2,77,3A,FF,AD,09,F2,6A,5D,F7,D7,92,DE,DF,EF,C3,DC,9D,81,BB,61,69,50,47,B5,3D,54,3D,BE,74,FD,6B,DC,23,C3,87,4E,C7,23,3D,A9,4A,8A,18,E0,E2,4B,19,98,21,C3,58,37,88,1F,FA,56,57,47,DC,02,D8,E9,2E,31,6E,9D,9A,47,B0,F0,7C,D5,5F,E9,3F,83,CA,9A,97,A2,26,C9,F3,A9,58,C3,EE,8B,50,94,51,53,1E,D6,C8,91,02,89,7E,87,6C,DE,ED,C1,A1,95,8F,87,C0,C3,B5,5F,04,01,CF,CD,E8,B1,1A,A3,2D,33,B2,F4,6C,12,00,36,9A,62,16,60,7E,4A,E6,F0,3B,C6,07,12,B0,46,8A,45,AE,AA,77,73,C9,FE,0F,EF,1C,0D,2A,31,4D,F0,6C,23,3A,43,1E,BD,1A,DD,F6,97,3E,81,30,EC,A3,9B,C5,A9,EC,41,9E,4D,BE,53,FA,67,7C,D0,BA,77,FE,35,AE,25,F9,19,27,09,B0,6C,AE,DB,62,80,F7,DC,58,78,9F,A9,BD,E4,07,67,54,8C,5C,E9,91,9E,A3,BC,6D,29,32,38,EA,2C,63,21,44,3E,2B,87,5C,9E,09,AB,22,1A,E0,33,47,1C,B5,CF,76,0A,36,58,A4,C9,80,BB,1E,C4,29,95,24,45,49,54,57,E5,25,DA,0B,6B,6F,A4,5D,FF,F6,DE,E1,F4,6B,89,60,E3,7E,C8,5E,3F,19,FD,38,F5,8F,D4,D5,6A,BF,E2,80,9B,CF,2D,2C,1F,A9,60,5E,FE,9B,8D,76,5A,7B,AC,A0,42,C2,A6,39,73,E5,C7,1A,0E,7E,69,4A,50,75,A2,04,21,CD,95,A9,74,B5,F5,E3,F1,90,5E,B4,38,08,EC,AE,BC,ED,09,89,E6,41,DB,BE,49,AC,8E,6A,9A,DE,77,6C,AE,38,3C,FF,5A,3F,76,E7,53,13,3F,A2,32,7E,3B,D5,2D,3D,95,72,7D,B6,EF,CD,CB,DE,36,82,BF,10,8A,B9,7A,4B,7F,F5,A9,6F,43,51,3E,2F,EC,AF,C1,F4,FC,31,BB,05,1E,14,F7,2B,66,B6,F4,12,54,47,F3,52,B2,72,E9,7E,88,F9,57,D4,92,BF,CE,E7,CE,9D,52,E2,87,2B,C2,0B,FB,B2,63,2E,0E,8A,E3,9C,DE,56,93,C4,70,DC,4C,3E,15,B1,44,BB,C9,2E,6E,6C,72,60,31,A6,95,26,EA,2F,14,D2,DD,61,C8,45,0A,A4,E1,8A,16,5B,88,21,10,3F,D7,3A,2E,3E,7D,93,E2,7A,92,0C,D4,10,2F,AA,C4,FE,04,2B,EB,FC,AA,BF,47,19,B8,5F,4C,0A,EB,73,E3,7E,5A,67,27,DE,F1,E9,02,56,99,82,4E,DD,EA,EF,2C,D0,DC,F2,61,6B,1E,C7,C2,70,0E,20,D8,5F,47,C2,0C,01,B5,DD,2A,66,83,74,9C,EB,A7,5F,0B,4F,6A,91,67,88,5F,31,A6,CF,FB,49,D8,0C,B2,77,67,37,86,E9,8B,79,F5,C8,DB,0E,DA,23,33,66,67,ED,C2,70,72,BC,4A,A9,C4,4D,C0,A1,C7,1D,AD,51,16,1F,37,F1,FD,AC,99,E6,7A,72,E2,2B,BB,AB,A3,9A,9E,A6,19,94,FE,84,3A,37,13,E4,AE,80,39,02,F2,B8,5C,EF,0A,7B,EF,87,FC,A9,F1,F3,9A,8B,82,0D,61,3F,F6,7D,8E,30,B1,24,69,F5,04,47,B3,77,30,9D,5D,A5,6A,EB,D6,57,E6,7F,14,FF,5A,24,67,FD,FC,CF,E6,BF,A0,3F,4F,A3,CE,3C,79,39,47,67,23,03,B1,05,0D,82,82,3E,B7,24,4D,8D,CE,7B,31,30,12,83,D4,86,9C,DE,45,3D,06,7C,F9,FA,F8,BA,CF,02,5C,9C,6C,E0,2D,CC,6B,18,E8,F2,49,16,37,35,E7,36,5C,7A,D8,7A,32,0C,69,A3,84,9A,30,59,54,1B,64,C8,8A,C6,01,00,33,A2,5D,E7,D8,C4,85,34,CE,17,D6,07,E1,A2,7A,34,EE,58,92,38,95,31,A8,44,E6,BC,F3,C1,7C,22,E8,95,36,96,42,15,6B,59,0F,9F,78,8C,4B,63,9F,20,A5,9F,57,05,FD,64,0F,4F,1F,3C,93,F9,A7,45,0F,2A,5E,C3,15,66,FC,D4,F7,5B,59,AB,43,06,C7,0B,EF,46,36,D8,23,AD,71,CA,A3,D3,AE,39,1F,42,45,5C,BD,E2,FC,29,99,B4,FA,95,60,40,21,21,22,54,9A,56,BB,E7,8D,7A,70,51,E6,0C,34,45,0D,E9,38,5F,6C,E5,0F,10,9B,C5,99,AA,74,2C,A9,66,B6,DF,82,3F,E5,44,C5,AC,E3,79,79,A3,D9,2C,F8,21,DC,50,68,7D,8D,7C,AB,35,E0,0C,2B,15,18,B0,6F,BA,0C,A2,92,8D,C7,58,5C,D3,AD,DF,DF,5B,64,5D,24,61,BE,4C,C7,73,A2,7F,39,D1,5A,2D,D4,91,38,03,BB,76,81,6D,73,2E,A0,2F,09,8C,04,A4,63,26,B3,D2,AE,72,EB,1D,22,B2,BF,73,BC,E3,15,D6,F0,4F,73,92,4F,B7,F8,BC,D8,BF,84,42,38,FD,93,E7,73,95,46,3F,8F,64,C8,A3,D5,08,A6,E6,14,44,AF,63,E9,13,AE,75,B3,88,38,8D,FE,1E,DC,1D,71,BF,CB,78,41,61,24,BC,CF,CA,4C,58,E0,F8,BE,26,A6,9D,5B,7D,AE,D0,C8,06,41,B5,58,8C,7C,C4,8D,DC,D2,7E,0D,09,A8,E4,32,39,C3,3D,66,9F,43,14,34,09,08,7B,EB,98,F1,62,CB,17,D7,8D,E9,60,FD,2C,4C,5E,ED,99,C1,50,84,B9,CE,80,16,42,5A,56,8F,74,51,3B,EA,39,F8,72,AF,DA,51,ED,22,31,6C,E6,49,49,A6,C4,C9,0B,B9,4D,29,15,C0,E1,68,DD,6B,B9,2C,0E,B1,1D,D6,D0,48,6F,50,53,C2,64,83,EB,02,E8,D0,CE,64,3E,E3,F9,5B,DE,87,82,0C,FB,B2,C0,6F,FF,B9,AF,5C,58,18,9B,AB,19,81,12,59,8A,37,AF,62,AA,EA,7B,A4,4C,C3,54,31,1C,95,AC,47,3A,A2,63,95,9A,C3,CB,DB,B9,A0,72,4D,20,7C,58,F2,C6,8A,0A,30,D5,35,F1,BD,CF,4D,78,46,B9,15,A9,3A,E1,42,79,19,B1,18,51,67,52,D2,3E,B9,DD,A2,62,4D,0B,2B,EA,CA,F5,7A,27,04,43,3B,CD,66,D6,F6,9C,8D,DD,54,68,C1,24,3F,D6,E8,77,DF,A0,DD,68,08,0E,7F,BF,E9,C9,0B,E2,C6,E1,FA,37,7A,3A,BE,D2,23,6A,8F,7E,28,C0,43,06,88,95,21,1E,12,88,4A,8F,2D,09,E0,EA,65,9B,E3,04,EE,02,4A,82,02,0C,1B,DA,B9,B6,79,7D,90,D8,7D,AD,FA,CC,F2,E2,E7,2E,AE,11,45,D8,86,DF,C8,66,C6,06,4B,D5,4A,67,31,33,8E,FA,E3,7D,6A,8C,38,4F,1E,9D,5D,87,BE,2C,60,42,11,8B,DC,2C,E2,E9,80,16,92,9C,A1,8E,8D,A6,30,00,19,D8,ED,DF,7D,1D,D5,3A,1D,D2,E0,6F,6B,5B,E7,1D,28,D2,26,0C,A1,02,CF,A8,70,B6,C0,E2,2C,34,10,B2,CF,F7,CA,26,94,22,21,87,E0,B3,51,56,E5,03,BE,40,88,28,6D,32,BF,F3,A9,67,7B,E3,65,A1,95,A2,78,5A,04,1E,C3,04,3E,45,69,C4,18,A5,8C,34,F8,B2,8A,41,65,73,13,7A,68,7D,62,0B,9A,B4,4C,32,4B,59,8D,BF,3B,6D,35,27,FF,7D,C5,AF,22,26,94,23,C2,74,58,F1,63,2E,0A,DB,38,D0,69,24,EA,85,C5,C2,7F,C3,2F,B3,3F,17,26,47,4D,CA,BA,26,0F,E0,A0,3D,3E,BA,6F,E2,B5,D1,E3,E7,D5,8E,15,15,41,AE,8F,40,D6,88,83,61,88,23,38,C2,0B,46,10,46,28,E9,15,65,BA,27,FB,F4,2C,76,D6,B7,6C,8A,B9,29,06,9D,DA,BB,45,62,04,32,C3,81,90,11,7B,FD,85,43,E8,5E,A9,C5,67,06,41,83,B4,6E,D3,DE,D9,4F,D1,81,AB,37,33,AB,28,58,19,8D,E0,63,ED,21,0A,3A,EA,58,4F,D6,D2,AA,F8,9C,4E,EB,9A,C6,2D,F8,37,9D,64,B4,4E,1A,42,BA,74,4E,BB,3B,C0,DA,B5,56,1A,2F,AE,5F,EB,64,B4,EA,96,70,8D,3D,66,41,66,C9,30,E9,04,13,13,D5,52,D0,89,7D,C0,39,3E,AD,E9,FE,81,ED,32,63,80,2C,C5,B3,51,22,E1,39,C3,F2,25,65,F9,7B,98,8C,77,11,0E,E3,7A,EE,44,3B,DE,F9,8A,32,88,BB,23,32,E8,24,C3,08,F6,97,AF,6B,AF,F7,4A,E8,ED,7F,94,F3,BD,74,43,48,2C,4E,75,DE,04,AE,0B,4D,E8,78,F8,01,2E,0C,12,55,2A,CD,47,96,CF,31,B6,56,17,C0,E9,BA,FB,B9,FD,3C,3A,CC,D5,08,8E,5F,51,5E,28,E6,9B,D7,86,E3,C1,9D,3C,3F,41,4F,2F,D3,4E,10,1F,82,4A,AE,40,A5,6F,66,6A,D4,68,06,14,34,B9,8A,A2,2A,76,7E,A7,34,C3,0C,55,84,0B,E4,31,97,79,31,10,F5,55,C9,FA,D1,CD,34,D2,59,0D,B4,A9,F1,67,0B,09,67,A4,0D,CE,67,92,E6,7E,94,AC,46,CB,45,28,98,79,53,66,63,AB,05,9E,2F,95,52,C9,F8,79,02,4A,23,08,B7,CB,26,88,E3,48,5A,63,74,6E,AD,1D,89,EC,F9,10,87,9A,99,D0,C0,36,F2,29,D0,D3,F7,58,6F,68,0F,6B,1F,08,73,08,E9,1A,FE,2B,6F,D8,39,38,DF,A1,E1,E1,7E,CE,97,A5,4D,6C,54,30,0E,B7,38,84,98,93,BE,4C,DC,81,FF,74,12,B6,A4,ED,08,C7,BD,FF,B2,96,C4,1D,D0,5C,A6,F3,D5,A1,B6,51,1C,D6,EF,E7,AA,AA,D0,84,02,D5,F3,E1,74,0B,A9,FF,6C,59,A8,CF,85,8D,FC,D5,1A,6B,2C,53,B7,C6,91,22,71,41,24,D2,AA,29,28,CB,BE,52,D2,E9,88,54,89,7B,06,4D,D9,FE,43,1C,A8,B6,5D,F1,E8,AF,0F,90,B1,88,42,80,C4,A1,F1,BA,09,02,47,E7,17,C4,4B,2C,96,71,2E,1F,C5,1D,5F,96,46,E2,19,9F,F6,62,4F,E8,B2,17,91,62,2A,20,5B,13,82,A6,50,52,96,4B,9D,E7,FE,68,B4,BD,BF,BF,30,52,CB,BF,1F,67,49,82,07,94,76,4A,73,BA,30,3F,4B,27,D4,7C,E7,00,47,E0,AA,64,8C,74,C7,FB,39,B6,DE,33,89,36,0C,F2,EA,A2,9C,3E,03,CA,B1,29,70,0F,D9,89,49,ED,8F,6E,E6,4D,AE,2F,C0,00,A1,2E,02,87,0B,C3,ED,76,BF,B3,7E,33,3A,68,C8,45,31,C8,BC,1B,35,89,DE,A2,B5,C4,81,67,89,72,02,B9,EF,85,06,F8,F3,96,93,95,A4,AB,4F,C7,3F,4F,E3,E9,30,61,8F,92,0F,82,8F,2E,8E,3B,CC,4C,B9,60,DA,88,16,1C,2B,5B,49,23,4B,04,73,8D,7F,F4,A5,5F,B3,BB,8C,2F,51,77,F2,80,A4,19,50,38,5D,17,FD,E4,11,24,BA,AD,8E,C3,2C,FF,97,EC,37,31,E2,B8,80,6B,06,4F,59,74,26,DA,2E,6E,19,72,D0,A0,5C,44,C0,56,D6,65,4B,AE,FE,9A,96,F1,9C,03,E9,67,72,4E,9D,2F,7B,3E,32,17,C1,22,15,4E,7B,75,83,F9,5A,DE,C0,19,F3,83,F8,7F,A7,EC,1B,4E,37,2D,5B,A0,2F,02,E3,CC,EE,2C,68,D9,57,F0,10,06,F5,D9,D5,75,C7,9E,59,F2,81,78,F5,1B,19,A8,69,14,9A,0D,52,97,16,F9,69,5F,02,8D,14,A4,23,98,E7,6A,70,BE,53,3B,39,03,3F,2A,17,B9,1E,1F,50,C5,CB,46,7B,AE,B4,87,62,2D,69,2A,06,63,F9,E7,F9,89,86,C6,66,D3,DC,02,57,D6,00,C9,EB,FD,F9,59,11,DB,5C,4A,E6,E4,E3,84,75,41,20,E5,A7,8A,33,5A,B8,5A,7E,C1,48,6E,B8,18,BE,04,47,8C,79,A0,FC,0D,D6,49,F0,B1,C7,17,EC,78,76,55,5E,29,91,B6,2B,DB,44,E2,08,F6,F4,87,3E,84,DB,23,91,5D,CF,FA,EA,F0,51,3F,E4,8C,6B,8F,C6,42,1B,DE,4C,61,41,75,76,2D,B0,E5,3A,11,EB,41,AA,5E,8B,03,02,ED,CB,FE,54,53,7B,37,80,74,BB,1A,7E,3F,CF,1A,37,78,C0,5A,F4,05,26,58,BA,28,3A,CE,26,DA,E6,72,BA,71,EB,97,E4,8C,E7,55,23,1B,7E,97,39,62,A7,22,AF,EC,28,97,21,33,33,3D,71,2C,F4,0D,E9,2C,30,F6,08,C4,62,AB,4B,5C,68,9F,F7,4C,3F,11,20,D9,99,CB,58,44,81,46,75,02,97,14,00,2F,23,7D,20,83,C7,F0,2C,E7,21,B9,63,AE,FB,74,AA,2A,25,16,22,6F,20,89,FD,41,16,A5,84,DD,77,C1,25,26,51,4B,FF,0A,C6,86,A1,AD,90,78,F5,0E,06,F8,89,67,DC,48,B5,06,17,A2,C0,11,4F,31,28,46,C6,1B,6C,F5,05,D2,DC,15,22,56,9D,69,45,77,1F,41,C5,3C,E6,43,C0,CE,06,C2,41,D8,5B,45,AA,E9,8D,4C,DA,C8,FB,20,67,8E,5B,4F,1F,C1,07,8B,81,B2,67,B7,D5,77,97,87,64,A1,AB,FE,AB,50,59,F9,EE,3C,E9,27,CD,EC,09,C6,D0,1B,27,B9,CC,17,5B,1B,EA,FE,4C,5E,4F,55,95,60,5E,60,27,B7,07,3B,FF,C4,E7,D8,E0,B2,6A,A0,95,08,54,23,29,6F,35,27,44,45,D2,10,61,3C,44,2B,0B,00,89,2C,D5,5F,9D,C1,36,9E,6D,16,AF,47,C0,72,DF,0C,73,12,78,B7,74,21,85,1C,11,35,41,D0,A0,32,59,2D,31,5A,18,93,F2,35,13,B5,53,64,55,83,20,15,E7,82,B5,DA,5C,56,82,31,95,CD,AE,70,C7,E2,63,0F,BB,AB,8C,69,39,71,DD,29,55,7E,A2,71,94,01,5A,B5,4B,83,4D,A7,67,36,D6,01,08,37,3A,67,3B,6F,46,D0,E1,30,71,89,60,20,16,A7,A6,1F,BC,AB,F3,B2,98,23,10,32,B0,77,31,35,D8,BF,FE,CA,E8,CD,E5,E7,9E,19,3F,34,7A,91,2B,0B,B3,89,86,4A,16,1A,8A,37,85,7F,B7,CF,39,DB,55,A8,F0,A8,12,AD,F0,09,36,62,72,6E,F4,A7,DC,FC,C1,1A,73,7F,0A,63,60,B1,51,2B,D9,CF,02,24,2B,01,A3,96,50,F2,0E,99,0A,77,A6,4C,03,79,E0,AD,BC,FD,C4,78,2F,08,D5,11,37,21,37,28,C5,8D,C6,4F,6F,D8,15,9F,7E,36,C8,D3,13,93,11,7E,B3,8A,85,BA,06,39,4E,F8,AC,E9,69,53,38,77,8E,3D,69,44,E0,B6,8D,E5,DA,C2,DA,65,1E,84,3A,95,EA,43,47,62,18,EC,85,F8,98,C2,D9,AC,D0,10,47,BB,C1,E4,47,13,2D,8A,AD,F5,24,50,21,A7,C2,49,74,F3,4E,AA,CC,82,4E,E2,FE,0F,4A,A2,CE,55,78,38,2C,29,79,25,FD,0D,CC,0A,B5,A0,04,30,64,96,F8,36,BD,6F,80,CB,1F,8F,8B,25,E1,2D,30,8D,75,A4,D3,57,3D,CB,8E,CC,68,DB,F2,A0,3C,05,FF,04,CF,E9,E3,CC,0C,70,7F,64,4D,72,0E,BF,B3,27,0D,08,99,EE,6A,B6,D3,8B,7E,EA,94,E6,E8,2D,74,EE,5A,FF,6E,8E,BB,82,DB,55,09,CF,6C,96,2F,13,F7,58,BB,9D,48,98,87,1E,AA,FE,57,6A,FA,A6,9D,38,D3,63,AE,78,4C,4C,6A,E6,75,EF,DE,F5,85,AD,B4,9D,55,45,94,79,E5,92,C3,6E,85,95,D5,96,BB,8B,D5,0B,24,1D,2B,4F,F6,8A,D8,DA,70,F6,E6,88,61,26,E9,BE,96,FD,3D,C7,6D,31,B4,0A,78,F6,8B,1A,E8,65,9D,5C,DC,37,12,1F,C2,A1,C8,6C,EE,29,72,52,8E,F1,25,E7,16,1E,38,09,FF,28,8D,FB,68,CB,50,03,50,89,DF,39,92,BD,6A,96,19,2C,10,4A,C8,58,8C,FA,0C,1C,B9,0F,F6,19,D6,16,C4,B3,BA,D5,A5,AB,6D,C9,C0,77,79,CC,18,09,4F,EA,9B,3B,13,DC,8D,41,C7,69,A6,D6,1E,F0,01,99,B7,79,6D,86,78,0D,C6,08,8B,54,CD,0D,94,C4,2C,00,38,5F,BD,A2,BC,0D,07,D7,F5,E4,41,E2,46,42,BC,AA,CE,14,0B,64,95,43,75,8B,8C,BF,F2,7B,A4,72,9C,75,01,60,E9,FC,28,F2,B5,6C,B5,AC,96,56,E1,F5,23,23,AB,85,AE,93,56,65,F0,90,0F,2B,3E,3E,40,BF,03,91,AD,79,3D,FF,50,D6,41,FA,4B,73,44,08,2C,A4,20,C5,5E,D0,FE,65,8C,78,8F,D3,CA,BB,BC,6B,4A,84,91,12,52,42,6D,10,A2,F6,08,C7,12,CF,F9,49,F1,29,A3,43,83,06,62,B0,C8,F8,34,CB,E7,90,32,4C,40,C3,4B,FE,2A,01,DE,BD,41,A8,20,8B,4D,3F,F1,CE,03,83,F9,E7,35,E6,28,B0,95,77,48,21,03,00,52,72,1F,09,0B,44,DF,85,66,83,7D,9F,FC,2D,60,8B,A3,35,11,9D,7A,9C,DF,A4,83,EA,D2,A1,B7,8E,28,19,7F,10,CD,58,46,0F,0E,78,C4,61,8E,F4,21,A5,BE,B2,86,5C,BA,05,77,13,74,56,19,E7,05,2F,B5,8A,85,E5,D9,8E,50,3B,D9,EF,76,99,E4,B2,B4,EC,72,7F,1E,79,25,F6,1D,E5,68,4B,49,C5,00,97,05,BA,FF,98,53,F0,D6,44,6D,C7,D9,0F,78,41,05,1C,18,6D,18,4E,17,3C,05,8A,D4,0D,B2,FF,40,9F,E6,A5,BD,88,D1,2D,62,9C,D8,7C,5E,75,1E,B6,3A,E2,5A,F1,AE,95,3C,D3,3C,65,34,6E,BD,44,62,44,98,00,EE,4F,4A,EB,81,95,C1,E5,B0,29,A9,F9,78,C8,16,50,F5,BB,56,01,32,A9,FC,54,15,DD,A9,10,91,DA,9B,30,B9,A1,F8,EA,14,4A,91,29,60,00,98,65,34,F7,95,92,F4,79,82,15,9E,36,71,A1,1D,3E,42,80,98,AA,44,8E,EF,8C,1B,6E,41,E4,2F,C8,AB,C7,7C,2D,B4,6D,77,F4,43,A7,2B,E9,6D,6B,12,CD,BC,D4,E2,98,18,A5,8E,98,9C,8E,BC,16,7A,09,61,A6,4F,94,E2,81,7C,A5,E9,2D,13,7F,20,08,7C,6A,A3,60,E5,9D,76,3D,03,63,02,8D,A1,05,8D,62,9E,28,3F,98,AE,62,58,66,F2,A3,31,14,50,FE,3D,8F,89,F0,18,FB,94,97,90,C6,D2,8F,9D,A0,71,C2,D7,6F,1A,91,C7,DB,FA,21,B8,8D,AB,B5,EA,C2,0B,CB,76,44,00,72,BC,08,75,40,AA,A1,A8,4A,B5,DC,86,13,A6,A7,22,33,EA,CC,51,F7,3C,B3,8A,9C,80,B0,03,C2,C2,38,BE,B2,D3,D3,AD,4D,21,28,2B,7D,83,93,72,39,06,95,02,DC,52,22,BD,86,60,35,78,7F,6B,6F,26,C6,AF,ED,8E,B5,58,AF,EF,EE,97,75,B2,53,ED,F2,79,2C,4B,B5,11,DF,23,58,C7,22,FD,27,3A,2E,00,56,EF,85,CD,3C,1F,72,9E,37,51,CC,BB,59,2D,2A,0A,32,4C,35,33,1B,09,7A,58,26,4F,8B,0C,D8,E2,FB,97,66,BF,28,71,93,5E,05,DC,B9,54,40,C0,95,EF,82,AE,21,6C,60,9F,07,FD,83,E5,2B,8A,4E,3D,B3,66,71,DA,FD,08,D5,DB,B8,3E,A7,32,76,63,CF,B4,EC,B8,95,F9,D3,0E,14,80,57,AF,B2,27,CE,87,7E,44,4A,2D,DA,A6,8B,54,C0,48,FB,42,B3,08,07,25,57,7E,99,31,31,3A,7C,3C,AA,FC,3D,B7,82,91,6B,F3,DB,B4,99,44,B2,10,54,07,BE,36,15,95,B4,07,23,2F,EC,45,1E,F7,9F,CD,FB,AF,18,98,1B,3B,D8,83,20,EF,B0,3A,F3,28,80,F5,B0,F4,30,2E,CD,9A,9E,4B,78,79,65,EF,9D,D5,33,99,95,F2,D5,14,53,C2,6A,7F,31,84,74,7C,5C,DE,91,54,28,8B,83,B0,FE,24,AD,6A,61,59,8B,85,DB,DE,19,AC,E6,70,4E,5F,B9,15,4A,2A,4F,AD,DA,62,EF,60,FA,9B,B0,F6,05,00,55,CA,25,2C,59,B4,40,A3,AA,1B,AB,F2,02,78,C7,A7,43,24,67,1C,83,E0,17,C0,CC,9E,FF,0E,CE,37,02,61,82,EC,68,71,28,EE,B6,77,60,8D,26,92,61,A9,EF,B8,33,FB,A3,99,D6,E1,F4,1D,86,12,EF,1C,83,FA,85,E4,35,24,00,05,C2,41,5B,61,3F,03,D6,01,9D,7B,A8,06,71,D0,C3,5F,51,B3,57,30,6D,80,EB,51,28,68,77,29,A6,2D,EB,21,64,F6,18,27,BA,FA,90,6F,47,71,91,C9,33,A0,35,1B,C5,35,C4,F2,23,61,4C,56,7C,08,76,A6,ED,8F,9E,19,FB,BE,A0,DA,6A,93,E7,5A,FF,DA,8C,9A,60,68,9C,AE,0D,5F,6E,11,3C,EB,0A,29,74,04,60,36,D6,1C,B6,98,5A,96,68,68,A6,8D,A7,07,84,B6,57,42,E4,23,C2,7B,71,69,56,DA,DC,B6,CB,81,17,AE,7E,0E,51,D8,F0,86,3D,7D,10,0A,7B,91,D0,CE,9B,65,3D,41,3C,E1,9F,26,B3,DB,85,AE,C6,70,80,9B,0B,7C,97,00,C3,F0,99,3A,AB,21,0F,67,08,7F,5A,B0,E2,34,AA,3B,E6,40,0F,7F,85,FB,D8,8A,D0,CE,33,35,4C,6E,2F,2C,C7,25,69,EB,D1,94,F6,BB,F3,00,0A,19,6E,A6,B4,E1,F5,94,5F,66,02,D6,0B,1E,A1,62,42,4D,73,3E,31,FE,58,8F,17,82,F0,25,E8,40,07,D5,6F,81,D3,FA,F4,EB,28,6D,88,25,83,05,92,EF,45,24,02,8C,E5,F8,D4,79,74,A9,FA,37,0C,82,A5,A9,5E,A0,DC,B6,D3,93,22,E5,C4,B3,F6,63,CF,0B,06,85,AC,0A,76,22,A4,6F,2C,3B,D4,A6,B3,A1,83,F7,37,68,F2,58,9A,8C,AB,88,20,C6,C9,6F,04,64,B4,9F,B1,FE,93,E4,79,AC,F6,D2,68,14,79,18,BB,CD,FC,20,24,30,3C,33,B1,B4,CB,AE,1B,A7,FD,81,3A,A1,80,8E,4E,15,91,B6,2C,85,CF,1D,3D,33,16,6D,2F,63,FE,7A,CE,5A,B0,58,F7,A7,A1,5A,03,EA,A3,8B,9B,6F,9A,02,9B,25,2F,3D,8E,D5,A9,3F,AE,AD,08,D1,C5,F9,CE,E3,C4,CE,AF,32,CF,FB,00,70,93,E6,D1,1D,50,5C,3C,93,57,7F,76,2B,BA,86,92,A3,FD,C1,B1,C0,9C,50,53,30,07,E1,AC,37,E0,65,3D,AB,81,B7,0D,B5,3B,D7,FB,48,BF,66,08,DA,76,5D,BD,AE,1E,BE,ED,79,C6,B6,10,5A,F2,0F,CC,ED,C6,E4,2D,5B,11,1F,15,A0,3D,07,AE,A7,F8,0E,5D,58,C4,8C,A1,56,0F,E1,E8,8A,F4,3E,14,35,2E,27,64,B4,7C,33,6E,72,CA,89,2A,23,D0,45,A5,86,3F,EA,23,3A,65,6C,7A,69,C4,62,1F,B9,3E,0A,C4,F6,F0,34,A8,55,38,6B,AE,8F,0C,8E,E6,EE,86,8D,05,A4,D8,B6,55,58,53,4F,56,E2,CB,52,67,1A,FB,E0,73,60,43,D4,64,77,1E,DA,93,48,B4,12,4E,FD,2C,9A,9B,72,AD,DB,51,73,3F,55,37,99,43,26,B6,2E,9A,E3,CF,9E,FE,17,7B,EE,CE,8C,69,71,F3,CB,AB,38,4B,59,E2,0C,F0,33,E4,F8,44,0B,CB,E3,7A,2B,35,E4,ED,61,EE,D8,FB,2B,45,FF,F8,90,84,A6,98,70,7F,3A,C5,AA,4D,14,0A,60,39,D1,67,FE,BB,D8,E1,68,24,92,3A,E0,5E,8C,06,DA,10,75,1C,69,65,0D,4B,1C,88,4F,D4,05,6B,D7,36,46,83,68,CA,B4,64,C6,50,8A,25,FE,29,27,EA,6D,94,A8,1F,27,2E,BA,E2,0C,69,1D,BC,89,A9,ED,7E,5D,5C,34,C0,7E,9E,DC,71,9B,63,C9,A4,BF,BD,06,5A,21,34,BF,82,BA,1A,4A,9B,D3,78,A0,0C,D0,FB,1E,4C,4F,95,7C,A9,47,BA,7B,EF,38,83,9A,6A,46,CC,4C,36,1F,E4,DB,23,03,09,0B,D0,8B,D2,39,92,13,F8,A9,F9,56,B6,B4,CB,5B,CF,9D,E8,0C,EB,EB,8A,B2,27,32,1B,9E,A6,62,9B,84,0B,19,AC,C6,B0,DF,BA,BD,67,FF,0C,02,F9,E5,74,2A,E5,8C,FD,F5,A9,E4,60,7A,6A,43,E6,A4,68,6B,88,AD,F7,71,29,2B,0E,95,B3,58,57,43,CA,40,4B,6A,3D,78,71,F8,A1,8B,F2,63,B1,9F,78,6D,09,9C,C7,C0,90,CE,9B,65,0C,21,5D,69,6E,83,EA,06,E2,04,2E,1E,A3,79,64,FC,5E,B6,DC,AB,02,FB,74,C4,35,18,BA,49,64,45,35,30,D7,AC,45,90,F6,BB,10,54,92,7C,19,01,C4,36,A5,11,4D,31,96,C4,CF,25,EB,A1,94,AA,C5,61,96,51,EE,2B,66,52,52,27,0D,1F,D7,3E,15,FC,52,56,B8,21,F4,7A,56,2B,70,8F,72,0E,3F,D8,07,2C,E7,33,13,C6,C2,95,C7,F1,25,87,AB,51,40,09,B7,39,12,32,0F,09,57,59,FA,1F,EC,33,DB,8F,82,D0,EE,B5,55,23,E6,4C,64,00,44,8A,E8,07,EB,4E,DA,88,12,34,70,46,B0,B9,8C,AC,B6,AE,3F,69,02,CD,EA,42,80,45,69,74,B3,14,28,4A,49,CA,6B,82,72,0F,07,4B,A4,AF,D0,78,F8,2C,CE,E0,8C,C6,19,0A,E1,48,3A,92,BE,A6,B1,58,5A,9B,AB,32,9A,64,DA,5A,D1,98,34,44,BD,40,B1,3E,77,B6,DC,E2,4F,F1,1A,3E,E2,BE,58,13,0A,3A,E9,55,15,03,61,05,19,AE,DA,A5,BA,38,EC,DD,47,C8,7B,B1,73,64,AF,9B,FD,C1,81,A7,15,23,FB,07,CD,D8,8A,A9,BB,95,CB,6A,14,A1,79,77,00,C0,92,B0,D6,2A,78,52,0C,83,26,BF,10,41,AD,FA,FA,1A,8B,19,DF,0C,78,28,6D,FF,0B,9F,9C,A9,7D,31,39,0C,F5,34,9B,BB,C8,7A,6C,E9,3D,C1,A4,FE,C7,80,2C,85,B2,6F,E7,89,20,60,C6,31,A5,73,8E,BC,FD,E8,F6,AA,D0,63,8C,21,F2,C4,76,D7,FC,77,C1,B7,CA,24,03,D3,7E,FA,12,D2,B8,6B,0D,73,86,FE,07,AE,EA,E7,D9,B8,A7,4F,86,05,99,84,88,A7,C8,0C,5F,D1,52,93,A8,D9,68,8B,A9,E5,8D,3B,D4,31,7D,89,12,1A,13,50,2E,3F,71,E5,B9,A5,C6,DC,DD,57,98,CA,7D,7B,E6,D9,89,51,36,98,AE,05,30,71,F2,D1,22,D5,37,8C,8F,BF,ED,D1,50,89,91,47,E2,21,B9,19,6A,BC,61,89,B4,93,6D,DE,FC,D6,37,86,F3,FA,16,C3,22,58,5A,74,28,1D,EE,A9,A7,D6,B4,AB,68,5B,C4,C6,CC,68,62,89,20,03,C6,6B,0D,B4,25,31,4A,3F,7B,BC,86,C9,1E,92,DF,45,0D,EF,87,60,C9,66,A3,B1,AB,4A,2A,9F,87,42,3D,5A,D7,F6,5F,1C,46,34,36,85,BE,5C,D1,BA,FB,50,7A,D1,86,A8,15,53,DA,3E,7B,ED,F9,F4,C1,F3,CA,1A,62,11,03,80,44,FD,32,AB,9B,00,8D,9A,C0,80,00,36,14,26,A8,4B,14,79,AC,65,F3,08,1A,4C,0C,15,19,3F,E7,79,AB,7B,74,8A,64,95,C9,3E,6C,5A,0E,B3,4A,8B,93,6F,2F,19,4F,96,67,95,55,B8,02,0F,95,8B,24,9F,DC,34,08,0E,AC,95,D6,29,6E,5F,42,54,A8,00,72,2C,11,8C,15,8B,74,0D,6F,04,72,6E,70,06,CD,91,36,18,F1,76,1F,DF,85,37,29,E1,20,8A,FA,08,6E,F3,5B,C1,17,DE,89,9C,D7,CA,C3,0F,9C,AD,52,15,43,CD,A2,E6,4E,E6,26,DB,A4,5B,83,B0,5D,AF,11,23,AE,23,3F,AC,7F,B9,9E,2A,C1,27,BC,51,A7,70,18,41,1F,9F,0A,A9,28,19,B9,5E,36,26,F7,BB,5A,9F,C8,7C,50,5D,98,B2,ED,C8,32,CA,DC,5A,02,CF,92,15,67,79,B2,18,66,FD,3E,55,48,1F,18,FD,B8,03,C8,5E,F6,B8,9D,3A,9D,5C,FC,3B,40,00,CE,2F,D9,A5,59,9D,B9,E5,BC,73,7B,8E,9C,C9,79,18,0E,A0,83,6B,F6,24,8D,22,60,E1,5C,39,FF,A9,BA,02,63,6C,35,89,D1,8D,47,95,58,A8,15,46,FE,D9,5F,4B,7D,F1,0A,74,DB,E7,81,B5,1A,95,3D,B8,53,F3,CB,E3,42,ED,62,32,03,7D,87,77,6D,10,76,2C,78,A3,F3,EE,74,75,53,95,AB,98,53,13,13,80,4D,27,D5,6E,14,48,15,83,2C,AD,01,90,42,27,B1,32,D4,DA,4B,7F,FB,63,E1,A2,E6,DE,B7,C5,08,7E,B1,6A,9F,3B,AA,D0,0F,87,8F,F7,95,00,B9,CA,7B,E0,48,29,EA,D0,2E,8C,E5,0C,FC,5B,B7,D8,2B,8F,DD,F0,F4,74,85,66,77,76,4D,6A,2C,FF,0D,92,01,6D,A6,08,45,38,53,18,26,50,38,ED,CE,00,C2,EB,EE,8D,16,25,D0,34,97,E5,3B,4E,BC,BC,16,75,71,39,CD,5C,F6,20,FE,7B,61,FB,36,6D,24,29,F5,8A,2C,42,94,6D,97,95,FE,CD,5A,63,88,0F,C2,89,FF,E0,F5,A6,DE,8E,36,88,0B,BF,75,68,C9,2F,B0,41,D9,34,49,18,98,CC,65,66,59,93,00,DD,F4,0B,EE,26,76,74,37,1C,78,A4,CB,3E,A1,4C,D4,48,71,C2,0D,94,10,B5,F2,5E,C8,FF,D0,54,B7,A6,6E,92,D5,20,40,7E,3E,B2,74,28,78,9C,64,5A,69,B0,FF,DE,FB,C0,BD,10,6F,A5,2B,F8,40,6B,F3,7E,15,4C,12,D6,6A,8A,EF,F0,01,82,2C,2E,D2,94,F5,4E,C6,48,32,42,66,08,B0,31,C2,E9,84,9F,49,10,CF,A5,6E,1B,8A,3D,41,FB,16,0D,3D,DD,66,0D,B7,E5,EE,E3,1E,94,99,8E,BD,59,1D,26,00,68,9D,56,6C,37,73,4B,08,3F,B5,35,84,62,5A,01,D0,99,58,8B,64,46,4F,50,61,0F,92,F7,75,5C,E2,CC,66,6A,1B,C1,72,0F,BA,47,94,25,F9,EA,D0,56,DA,98,7F,E8,1A,94,5B,77,E1,E6,95,E2,B0,BD,2B,94,FF,2B,C8,C4,B5,8E,FE,ED,B6,D1,60,C2,A1,5E,B0,DB,3E,2A,56,52,77,AE,81,29,F6,51,6F,0F,98,FC,8C,02,7C,60,7C,61,FB,05,A8,44,57,3D,A0,46,87,07,78,D5,85,11,27,2C,14,5E,0C,2B,34,9C,50,33,ED,65,5C,C5,C9,2C,82,C8,FF,9A,42,F2,E0,70,C9,E7,88,71,50,68,B3,78,ED,F2,59,82,E1,F7,15,8A,08,28,5C,AB,26,C2,FF,54,00,79,45,AC,89,16,A0,EE,81,08,6B,89,D5,29,2F,13,DC,0F,91,A3,9E,A1,5B,FB,BF,31,57,AB,0F,55,C1,EB,DA,01,0C,BA,7A,A4,77,A1,D0,61,45,03,33,47,1F,AD,08,A0,95,54,90,D0,DF,65,67,D7,8B,B6,8E,09,4A,08,A6,62,C4,6C,94,DE,8C,12,38,8C,19,FA,61,F3,E0,3E,C2,4B,43,8E,A1,B3,F1,14,14,41,71,94,73,10,D2,A9,65,37,2F,5C,A3,22,EF,9C,23,AD,99,69,49,AB,13,27,39,AC,32,06,9E,4B,0A,38,51,8C,B6,19,4C,BE,1E,C4,BE,DB,BF,17,58,A6,6A,BD,AB,1A,1A,DE,24,A9,5A,A6,3D,BA,92,A9,D9,9A,5F,5A,60,DD,00,2C,81,D9,02,97,26,7C,96,15,94,24,49,B1,80,99,8E,D5,C4,36,B8,29,7A,6C,79,32,5E,DF,C3,B1,3F,C9,39,BE,16,4F,15,F5,AE,2B,19,A4,A3,07,07,4B,21,42,EA,2B,F7,8E,B4,0E,0E,86,A5,56,1C,95,6C,18,EB,8E,DE,AB,91,25,8E,55,07,D1,C1,B8,6A,FE,5A,73,C8,49,DA,91,04,CD,2E,A5,EE,06,5C,23,89,D4,E3,FC,3F,CE,A6,A9,A3,D9,04,57,2F,8E,03,E6,2C,4A,AE,52,E2,E5,E9,E5,51,F7,B4,06,59,30,31,30,52,E3,43,2C,6D,8A,97,C3,FC,A0,5E,88,B5,76,DF,E8,EE,96,CE,18,11,DA,26,A2,29,2F,F4,96,78,9D,4F,84,DB,F7,33,98,4F,F4,45,1A,E2,CD,81,79,9B,4D,15,17,8A,01,21,A2,54,A3,7C,4F,1F,C2,CB,63,90,98,D9,FB,32,FA,A2,40,7E,B8,F9,B2,D7,29,30,74,9F,B7,23,C5,00,6E,68,61,9E,93,C7,85,3C,27,02,7A,BB,AC,FA,C2,2C,26,85,8E,4F,37,45,E8,D5,DE,DE,7C,72,F5,EF,51,2B,12,05,9E,DA,04,9F,D1,7C,1F,44,89,51,72,BD,82,74,CB,22,11,14,26,48,F2,29,49,C7,73,57,FC,2A,34,A1,90,48,B5,F4,4D,E0,05,47,72,34,17,AB,1B,15,10,7D,D8,B1,2B,CA,01,2B,8E,75,6C,ED,5F,58,98,31,68,3C,EB,1F,BA,F6,BF,26,23,C2,44,7E,89,5A,6A,3E,AF,12,BE,C5,D0,71,6C,85,FC,27,59,D1,C8,B6,6B,00,21,BF,67,99,CB,D4,D0,23,3D,29,5A,A7,43,CE,8C,6D,E9,66,62,D8,D5,FB,33,BB,5F,34,E5,50,F4,49,5F,0F,00,6A,DC,EC,24,27,E9,30,04,25,BB,5D,E6,D0,EE,15,1D,74,EB,6A,5A,DE,25,BD,DB,B9,39,70,22,A5,34,4A,6D,37,AB,34,97,E7,19,7E,D4,58,46,FB,5E,DF,B2,40,9B,2A,98,81,79,04,A6,24,4B,AD,E2,31,55,32,74,BA,25,BE,8C,CD,07,64,D1,86,7B,C8,2F,EE,C4,F9,71,7D,09,0B,C7,10,DD,C3,7A,31,9D,95,41,1D,01,BC,19,A4,CE,DD,95,37,47,86,79,13,2E,0F,61,79,8E,45,D9,5E,9E,49,12,6C,3E,9E,DD,A1,A4,69,D6,07,F8,D6,D0,69,6A,29,90,D9,93,1D,BA,44,72,4C,F7,7F,2A,97,10,03,E7,4D,D4,47,27,8A,D9,D4,89,B1,AF,EA,A2,0D,3B,02,6B,2C,2D,AA,1B,4F,F5,A7,BD,1E,47,87,41,09,02,E1,EB,9D,F8,BF,3C,7E,76,80,5E,5E,0A,E8,EC,DA,95,F4,F9,E2,AF,85,37,A9,5D,56,5C,E9,5B,E1,C0,75,7B,DA,BE,EE,AB,11,BF,AA,C1,3F,60,D2,24,13,7C,7E,E2,92,76,6B,95,73,6B,A3,2E,A3,1B,B1,13,B5,1C,64,D6,F2,FB,6E,D4,0D,CF,9B,4B,DA,0E,CC,C5,88,CE,43,52,96,D5,B3,FB,1B,4C,1D,5F,C0,F6,2C,A2,9F,7C,84,8B,13,13,10,F0,02,F0,EB,0D,B9,37,75,23,20,3C,42,00,72,4E,3F,47,C8,1D,55,C0,F6,B0,18,8C,A8,78,55,55,13,B3,8A,F4,1C,26,40,1B,D9,2C,BF,A9,06,0B,38,EE,5D,DB,FE,BB,64,51,CC,3A,BA,C2,6D,41,E8,C6,00,DC,DD,82,15,84,12,34,44,E1,B4,78,12,62,72,58,7D,93,FC,83,1F,67,FA,35,3D,13,8E,23,C4,0B,56,57,55,1C,BF,0D,7C,F6,68,B3,4B,40,A7,4A,CE,58,F8,68,E9,4F,7D,AF,93,14,3F,5D,DE,FF,B5,81,D0,CA,B5,C7,F7,7B,CB,EC,29,9D,96,8E,F4,85,76,C8,2E,D3,DD,CF,46,78,0D,EC,23,C5,04,51,3F,C4,15,49,DA,45,5B,66,BA,66,46,BC,40,75,A0,7D,3C,EF,86,20,0F,7F,15,B3,6D,15,A4,2E,49,D2,A7,FC,D9,21,0B,D3,8A,4B,C7,39,9B,26,7E,54,AF,03,AB,02,1A,EC,07,A9,16,42,39,BD,D9,F0,11,71,37,F6,A1,FF,E7,BC,CC,8E,25,C6,34,A6,D2,33,35,47,94,9A,A2,8C,75,6F,D9,B6,10,F1,4B,8A,76,D2,CC,22,1D,80,55,60,B9,23,64,CE,03,E5,E5,B8,C7,99,68,5D,A9,35,2C,C0,A0,B0,88,1F,4A,67,66,34,BE,4C,F0,59,1D,E1,78,E4,D5,A1,31,D2,CB,48,FB,9F,D3,D1,02,36,E6,69,58,12,58,6D,23,68,BD,DE,1B,78,1A,D4,3D,4F,2C,93,25,9C,7A,25,BD,BA,D8,09,06,7A,4B,42,95,34,AB,86,4D,95,9E,EC,55,FA,F4,1A,73,C6,98,79,61,90,F5,31,B0,0E,DF,1F,55,65,D3,FC,D7,6C,A1,51,84,BE,24,CB,47,01,A0,35,68,AA,F4,64,49,9D,30,74,4B,1B,83,F9,51,DE,1B,6F,54,DE,11,54,12,37,7A,35,27,DB,13,B3,99,56,5F,75,8D,62,ED,E9,00,7D,BB,DF,FC,6C,78,7C,A8,22,AB,B2,7D,A5,C7,01,DC,E0,D8,59,21,39,C0,8A,7A,95,34,AD,A1,96,A9,50,EE,41,3B,39,01,D2,39,86,BD,5B,A8,83,97,79,42,15,BF,DE,93,A3,0D,9E,3C,28,51,2A,BD,FB,96,83,20,0E,8E,95,59,53,8B,5D,F0,8A,11,AC,D1,27,3F,B4,16,FB,5A,D3,BD,82,27,77,37,00,A0,D2,A2,E1,55,45,EA,4D,58,ED,E2,D3,03,A6,92,5B,23,D7,CF,21,56,3A,CF,53,9E,42,B0,01,4B,19,FB,2C,39,37,5E,36,ED,AF,64,00,36,67,B6,F1,24,CF,00,C2,65,8E,6E,8C,5E,D0,73,2B,66,D8,A8,9E,98,E2,89,0B,A8,80,0A,BB,54,CF,91,1F,22,7F,D8,CA,3A,C3,E3,FC,E1,52,E5,07,E1,6A,BC,4D,6A,97,AA,50,E2,1C,EE,04,0B,21,51,85,10,EF,8F,F7,C3,7D,E0,6E,B2,18,40,0D,B1,E6,A6,30,D1,83,57,C5,52,00,E8,33,47,C3,50,F1,EA,31,E8,93,57,23,C6,42,C2,DC,A6,45,B2,1A,9D,47,F1,F7,54,50,FB,8A,C2,40,E1,F9,85,AD,E2,C8,32,ED,AB,24,1B,28,A9,5A,FA,D1,3C,4F,1A,F6,68,C0,15,5A,17,DB,D2,7B,D9,63,7A,A0,FF,55,6D,4C,66,FF,27,D8,C0,81,2F,CA,9E,B6,61,15,25,A3,6A,3B,65,98,83,3F,B6,18,A7,11,2E,B1,36,0D,C3,9C,12,25,DD,05,B3,2C,8A,28,8F,4F,4B,2E,60,CB,AE,A7,12,9C,A8,B7,77,82,5E,53,30,A3,4C,1B,EC,8F,C4,97,4E,C2,DC,85,BF,F9,F9,7B,45,32,A6,29,B8,22,DF,FA,25,E2,61,AF,FB,28,82,86,06,9D,15,02,AD,40,E3,72,70,B2,B6,E3,C3,0D,5C,13,AD,E8,19,B2,65,06,52,64,1E,C1,E8,E0,37,F8,F9,8D,5E,CE,08,9B,6B,73,15,56,4C,9E,21,36,87,1B,A4,89,BE,D2,31,E8,C6,92,2A,09,A1,D1,70,B7,84,A2,62,08,67,F1,E1,EE,9E,26,82,C5,F6,B9,39,21,6A,A6,06,8C,A7,C9,39,78,FD,5A,73,6C,96,6A,C2,47,B8,0B,59,0D,BE,7A,3F,E7,E5,D8,00,BD,33,81,A3,7D,62,48,3B,12,7F,EB,47,E0,54,56,24,EB,CE,AE,0D,9F,27,B5,25,3F,C7,78,B5,E3,83,21,F3,8D,4D,8F,91,91,7A,FF,BC,9D,07,0E,41,E0,05,8F,0A,F1,76,A3,2F,87,B8,99,FC,A1,72,4C,F0,C3,2C,36,EC,75,A4,43,19,34,B5,D4,E5,24,8D,26,36,B5,27,1C,F5,DA,5E,99,6B,01,E0,89,A3,90,4C,C9,90,4D,CB,45,71,51,E5,6E,4B,EC,FC,04,EF,11,72,B6,80,40,DE,24,0A,BA,02,54,B9,E5,98,ED,70,F7,52,D2,00,AF,14,AC,B1,F1,0F,BF,A6,A2,85,4A,8C,10,C8,F7,24,F9,66,DF,D4,A0,67,E9,01,8E,32,73,7A,9E,79,72,56,AB,27,5F,93,73,9C,E4,03,8A,16,F9,B9,9F,5C,C0,BB,15,C9,CE,D4,F9,37,22,B9,4B,91,A8,5B,BB,0D,5E,36,39,AF,80,25,78,4E,5C,F5,25,1E,F5,C0,38,77,BA,E8,A3,57,FE,5B,2A,89,59,B8,CE,80,9C,7B,7B,9F,44,C3,67,8E,7A,BB,E8,D7,52,0D,D0,18,CA,9B,04,3A,99,3A,5B,A9,64,FB,7B,7B,67,8E,1D,80,13,A0,25,2D,A7,81,1E,A6,C9,08,BD,D2,34,D7,BF,FB,90,0D,E8,46,32,AB,4E,5C,78,F0,4C,08,DD,1D,93,B9,82,EC,FD,25,91,88,CC,F8,46,58,00,6C,8B,98,C1,D5,6A,6D,AA,C2,B4,A8,CA,A3,5E,8B,45,3C,D2,D1,29,C9,FF,5C,A7,E4,62,4A,6B,70,A0,FC,88,40,A4,B4,53,E0,BE,B0,C7,F2,37,C1,B5,EE,73,01,E4,76,02,57,A7,BA,1B,44,DD,EF,11,A2,46,D8,46,7B,58,1A,18,71,7A,5D,00,B4,89,CB,3C,61,EC,D7,38,2B,DF,C7,68,DA,7A,47,A7,40,83,BB,67,71,DE,95,5D,AD,39,7A,20,44,86,F4,78,DF,1B,E1,0B,7A,28,8E,FA,93,DC,69,21,63,B6,2D,DC,5A,FA,33,58,25,C6,0D,2E,87,F5,7F,94,39,A3,93,DE,6D,60,4B,37,21,9E,09,F8,A6,F2,82,51,51,CF,F8,10,08,A6,B9,1B,6C,3F,BA,E4,28,6F,9D,2E,99,08,53,97,B8,A9,A8,50,01,47,8D,91,1A,3F,26,20,A1,C2,2F,E1,5B,96,00,1B,63,1D,6D,14,C7,C2,E8,43,C0,39,54,F5,66,CB,46,81,AB,30,72,00,5B,D1,67,63,9F,B4,EE,AC,7B,18,20,12,EF,6F,47,C2,D4,CC,8B,F3,19,70,14,6D,31,5E,BA,2D,13,29,82,69,2D,AA,84,2D,CD,EF,74,4A,23,8C,97,EB,12,0A,93,6A,5A,8F,83,5F,66,CF,3B,60,C0,B7,F3,3D,8A,73,5B,D7,88,DD,C7,4F,85,C1,9B,77,0E,A9,29,8F,C8,E1,DD,30,C2,CF,D6,D8,72,42,3F,EB,16,83,1A,36,AC,AB,EF,E5,9D,3F,31,BF,20,53,7F,2D,0E,28,EC,98,E0,D7,16,74,B9,59,B7,CC,BB,29,A1,2E,DF,87,60,75,49,29,7B,3D,E9,F5,DF,05,23,0F,3C,A3,32,B6,0E,28,3F,63,38,BA,AA,CE,6F,E1,A4,C8,80,6E,1C,06,42,A4,00,6B,38,12,DC,27,B2,4C,ED,09,95,75,FF,5A,32,42,BA,81,B8,F6,32,DF,04,C7,F7,2E,0A,00,B9,AC,48,FB,5E,3F,50,08,EC,DF,6A,B8,FF,95,8C,38,04,02,87,A4,6B,32,BE,13,16,1A,08,5D,5A,4F,88,C9,84,5F,8B,35,1B,EA,67,1F,16,56,22,2D,DC,01,A0,94,23,53,B2,56,DA,77,33,01,9F,B1,CA,CD,F6,7A,D4,62,95,B1,05,63,A6,9C,15,C7,BB,FF,83,9C,C1,59,01,40,05,AF,C3,96,6B,CD,B6,CA,1C,AB,6D,8F,6F,CD,D4,74,25,6F,A9,1F,86,86,ED,CC,EE,23,D6,52,FB,B8,46,4D,82,17,F3,B8,F2,7F,6A,C7,FA,E7,F6,40,3C,DC,76,9B,48,30,13,75,67,20,91,67,FB,CC,F7,20,22,A6,4B,08,93,AB,93,3A,28,23,9D,E6,18,B4,0A,F4,E6,B9,61,A8,0E,8C,B3,69,D7,39,8B,77,23,C8,A0,1E,3B,8D,2F,D2,5D,9C,4F,3D,35,58,B9,A5,31,F0,13,E0,5F,91,B0,17,C3,5E,E2,F2,F8,00,8D,2F,05,E4,4A,14,10,EF,30,B8,6E,BC,BE,89,07,68,3E,F8,42,5C,85,09,22,8F,A5,DF,80,4A,74,58,C0,43,E6,4D,33,BB,94,03,5B,F9,DB,47,01,88,78,43,D4,C0,2F,A7,68,23,D6,5D,C4,EA,5B,A4,47,86,15,ED,9A,01,F5,F6,41,58,A7,F0,B6,83,C9,43,B0,5C,EC,76,F9,79,4A,63,49,E7,4D,45,6E,44,78,9C,78,49,95,7B,8D,3A,F9,B4,89,E6,20,50,5C,69,B8,35,42,A6,0D,1E,03,C4,77,7F,C1,A3,A7,5F,30,25,63,CE,80,8C,5D,DF,AD,9F,A1,A2,49,1A,56,60,40,96,08,D2,11,3C,2A,D5,45,9F,2C,A0,4B,9C,82,AA,B8,13,35,28,E5,6D,E7,84,D0,96,8E,A4,5E,14,8D,CC,19,BC,55,79,F6,2F,11,A3,F7,D6,BE,72,42,98,DE,3C,46,A0,20,40,00,7D,B2,12,64,06,87,4F,25,BF,80,D0,6F,65,AA,E9,D3,A9,B3,1F,34,62,D9,AC,FD,E4,2D,B3,0A,48,56,C4,3F,95,BA,8B,F0,FA,5F,E8,D6,C2,CC,69,9C,AE,A3,ED,90,92,AF,C5,4D,CA,53,B9,B8,BC,69,4F,12,B4,4B,DE,7C,E0,9D,60,A8,69,57,54,3F,B7,F7,6E,95,BA,C9,CB,A1,BF,04,4B,70,EB,CA,CC,C5,F9,DE,0C,7E,90,BA,A8,34,C9,F5,7E,6C,F3,BA,01,B3,A2,4C,31,5B,5F,E3,60,B4,57,5F,0E,A0,30,8B,59,C7,23,94,51,80,13,1C,AF,18,1F,46,48,7A,98,01,86,8D,E6,00,7A,02,B5,EE,0E,10,3A,B3,B2,18,30,CD,33,1A,F6,07,FF,3C,E1,6C,CD,60,67,5D,29,A5,B6,68,2A,A6,74,7B,5B,84,62,EB,FD,6C,BE,F6,4E,CA,8F,04,B8,AA,67,2D,DB,04,30,3C,6C,4B,FE,0B,68,FB,FF,EF,8E,96,85,42,9B,4A,09,B5,E6,93,A2,11,6D,CB,2B,ED,47,5C,8C,BA,E2,7F,89,B0,83,5B,3B,52,80,C0,40,D6,A9,BE,4A,C9,D3,41,1B,9F,5C,C8,A3,F1,9E,98,ED,A7,36,8A,13,80,6C,CD,A3,2D,5F,88,17,A2,26,3D,07,53,7E,BD,5B,00,62,13,33,35,E8,DB,B2,38,00,70,B1,5F,25,E5,78,6B,E5,3D,4F,98,3A,B4,F2,D5,10,5A,18,4C,91,7B,F4,D6,26,E7,B6,84,65,07,0D,62,CD,53,3E,76,73,8F,D0,89,69,0B,70,78,6F,F2,4D,79,9D,9A,72,B0,18,67,A5,82,88,31,AD,A6,29,03,4B,D2,3A,95,7C,EF,EA,CC,AD,BE,FE,C6,D6,7B,3C,C9,43,90,68,28,D8,6E,56,93,68,6D,14,47,40,D6,6B,9F,94,80,89,29,07,22,B0,71,98,3C,D4,F6,3B,96,8A,3C,FF,AE,D8,00,C8,58,8A,46,F4,D7,FD,2D,58,C3,3E,D8,CC,B8,4F,B9,E3,31,25,2D,5E,9D,6C,60,40,21,CF,D6,EC,C4,6C,62,BB,CD,F7,98,D0,82,40,D7,AD,D7,7A,86,CC,37,EF,5C,FD,00,CF,CD,81,74,D7,79,45,1A,67,4A,8A,C6,A0,AA,5F,AF,E4,98,16,FE,77,8E,0B,F2,CA,7F,70,50,EC,36,59,16,85,92,3F,40,BC,D8,75,7A,90,97,D6,5C,B4,72,88,11,D2,9E,94,36,19,07,20,BD,BE,52,15,0F,05,DB,9D,CE,2B,22,D8,FB,E7,F9,F9,C3,45,45,9C,9C,B7,76,7D,8F,FD,73,F2,89,8D,CD,78,F7,CE,3A,8A,76,0D,8A,DD,DA,1E,2A,34,3F,D2,A5,D5,05,E9,D3,A7,E2,3A,3B,86,28,C0,C8,F6,32,B4,C9,A7,F2,F0,F3,28,7A,9E,2C,CE,24,8E,71,F7,A0,9A,E8,00,6F,38,B4,1F,C0,DA,33,9F,3C,6E,77,EB,98,9C,A2,C3,A4,9A,F4,7C,73,D0,A8,1E,CE,A1,ED,8C,71,81,CC,2A,36,50,F1,B3,62,A6,30,E5,4B,42,BC,64,CF,2C,EC,9B,13,1A,F5,79,06,33,37,33,0B,8E,37,05,05,7D,F5,5A,F3,F8,04,CA,DD,67,4F,EB,14,D3,00,8F,07,71,62,97,B8,22,B1,E5,39,BE,58,2B,99,9E,91,DF,E2,DB,17,91,02,FA,C4,54,07,39,D5,6C,4D,A9,9F,DF,C5,D8,B6,03,A8,80,03,AF,2A,7F,D9,14,71,15,70,40,D6,8D,B1,C4,65,F9,C4,A0,DD,47,5C,BE,37,FF,23,BC,35,A0,DB,72,1E,AD,C4,46,0C,26,2B,F7,8E,8E,5D,DE,1E,38,A6,3E,A8,C4,43,99,1E,3B,1F,A4,49,7E,A1,DC,F0,2E,B3,C9,35,A0,51,36,C1,2A,26,B4,84,C9,21,24,30,68,8B,53,49,5C,7B,87,09,0E,E7,F5,20,90,85,36,23,6F,90,D0,CC,A0,00,DC,5A,3D,E5,7E,CA,BE,4A,21,17,65,7E,70,C9,8A,98,76,3D,0B,F8,3E,E0,9A,01,D6,08,79,EB,E4,60,CC,44,9A,B3,7E,34,38,92,4F,8F,0C,2A,F5,11,A4,5E,6E,A3,77,60,16,B5,0C,B3,D6,0B,6C,98,18,55,E4,AF,83,95,7C,CB,01,8A,A9,26,49,73,9F,4F,B5,A0,CB,2B,D5,7A,5F,74,01,03,C7,BE,5F,D3,AD,E3,CE,CE,A5,D4,CC,8E,10,D7,5B,4C,2F,6F,A3,DB,E8,5D,96,19,D1,64,B2,02,31,C2,52,50,E3,DD,58,2A,E0,D7,69,CF,92,49,B7,04,16,1D,11,47,C5,1A,BA,F1,92,C8,5F,10,AC,BF,91,BC,1F,A3,63,B9,BB,55,71,E6,32,AC,DA,1E,FD,67,62,65,58,69,38,9C,14,55,5B,9D,1B,34,0B,67,B2,A0,78,24,5D,87,5A,87,3C,F4,DE,49,E3,18,DF,5C,89,54,0B,69,BA,18,B9,54,55,D9,BD,09,E6,DB,D2,C9,66,D6,1A,AA,22,DC,B6,F6,AA,D7,CB,82,55,F6,57,63,4B,DD,4A,AE,0C,DB,86,BF,66,64,EC,AE,90,6F,D9,B0,D5,74,12,DA,EA,F3,D5,28,B6,1F,D4,68,DA,A7,3F,66,0C,A3,8D,B0,F1,4B,1B,DB,7A,11,B6,52,AA,6C,D5,6C,6B,E0,4D,28,66,DB,38,C0,43,A8,CE,7A,A8,BB,43,B2,9D,59,B9,8C,D6,76,BA,A9,CB,6E,9F,29,2E,BC,34,D9,7B,C9,CD,56,73,03,CB,9B,D1,5B,9F,E0,36,E9,17,E3,94,C6,E2,1F,B3,A7,55,90,14,86,18,01,25,B1,21,9F,BC,20,FE,72,32,C6,8E,E9,69,AF,1C,59,F2,96,E4,7F,D6,31,12,C9,40,7F,49,1D,83,80,FB,23,2A,68,27,A0,D2,AE,53,E8,1A,E0,8D,57,96,A1,28,87,90,A0,9C,0E,53,42,DE,3B,32,68,ED,DA,CC,F3,25,1B,FF,D4,12,67,17,23,ED,05,6F,BF,B9,FB,06,D9,89,E1,76,67,39,86,A3,62,9C,09,BB,C5,BA,1A,C0,BB,83,AD,E5,A9,4F,75,F5,78,B1,7B,01,06,B2,5D,AA,93,02,D9,0C,4E,84,39,A0,2E,DF,C6,B4,B6,0A,7C,8A,CF,15,7E,89,09,53,76,7B,B9,7C,AD,0A,83,DC,B3,A8,76,1B,F4,2A,B5,7E,DB,BC,5D,E0,7D,86,0C,38,DC,22,A0,6C,D3,9E,A7,5A,90,B2,2C,A2,A9,FD,87,0D,C3,1F,CE,3B,9E,5C,61,BB,B4,A6,98,DA,CA,6D,64,EB,3A,FB,B5,C1,1F,9C,6F,8F,2E,90,50,8D,09,FE,97,26,63,4F,66,9A,93,D3,04,99,31,AE,58,27,4A,99,A5,C9,93,5D,46,DF,23,DA,AF,97,D8,0A,3B,32,C5,F7,26,B2,53,B6,3B,02,EF,51,54,0B,0E,C0,4C,CB,82,CA,21,10,59,A6,94,0E,6D,DC,B7,68,72,DE,A2,BB,D1,94,7F,E9,B9,35,53,33,95,8F,DD,0D,AD,87,65,AD,FE,62,7D,F4,F8,9E,9E,AA,4F,AA,D8,72,9B,5D,59,4D,1A,5C,FB,42,73,1D,D7,01,D3,FC,C0,1F,FE,D8,B0,BB,66,80,8C,7E,E6,BF,83,64,F6,F2,FD,81,9F,59,D2,78,2F,F4,63,EA,00,BA,BB,66,9D,B6,83,7E,CF,4A,7F,4F,C0,8B,22,E5,EA,07,32,86,41,6D,69,D0,30,95,D5,2F,36,52,BA,0D,24,42,64,5B,18,DC,5A,D7,34,A1,8C,36,6C,19,81,BC,F5,71,56,0B,0A,25,83,AB,10,40,08,5A,75,3B,13,A8,B9,0A,17,F1,88,39,EC,EE,5D,17,9B,F4,AD,83,FD,B4,5F,40,0E,0D,8E,AE,7C,D3,48,B6,C6,93,14,47,6C,05,FC,6D,77,F2,82,DA,0D,F4,72,14,5A,DB,C4,E8,FB,B3,25,3E,F0,84,D6,02,8B,2C,27,FB,F0,7F,33,2A,50,39,59,04,B0,E0,E6,B3,6C,B9,62,3F,AD,DF,03,23,C9,12,A2,76,8B,47,EE,A9,13,92,DE,79,63,4C,B7,54,ED,79,F7,5B,3D,C3,9A,D9,39,97,23,D5,A4,D1,6B,76,2F,59,58,6D,64,2A,49,76,86,62,57,5C,9E,35,EA,71,DD,5F,7B,F5,03,A6,4E,9D,62,B0,F4,70,9F,E9,DB,7B,DA,78,22,29,F6,29,6B,A7,06,28,0D,FB,FB,E6,F5,42,94,98,02,F6,6C,C4,28,26,C7,41,69,35,28,60,E3,B5,C1,10,7B,E3,E9,20,F3,A8,70,67,E5,1E,BD,AA,EC,93,08,F2,30,FA,44,94,E2,E1,8B,CB,E5,FF,B2,F2,75,87,14,1E,76,DB,FF,C4,38,8F,DB,19,E3,4D,29,F3,4F,81,9E,22,0D,D3,C9,B4,70,95,52,62,F6,83,49,CA,E6,37,B6,AB,EE,C2,43,1F,23,03,39,02,52,CD,03,F6,D3,0B,A1,F4,9A,40,CD,67,00,73,64,50,A0,33,47,D8,F4,05,E1,23,12,B0,F7,3E,DE,59,42,7B,B8,F8,BB,DF,02,6D,85,73,C5,F6,F4,B9,09,F4,44,E5,1B,6F,32,23,76,B1,36,6F,D9,1C,D2,AA,3A,F3,5C,25,08,67,77,16,B3,B9,13,4C,92,EF,18,04,9D,C7,86,A7,4E,4F,F9,A5,E1,DC,D9,00,3C,F4,FC,A8,25,CE,0F,00,56,BE,B6,A0,FB,0D,1A,03,6C,9E,4F,0D,0E,62,4F,CA,BB,23,72,E7,5C,D9,BD,75,4D,5F,A7,58,D4,31,E0,E2,2F,99,14,73,F3,58,89,51,76,D7,C8,8A,C4,65,35,FC,AE,4B,C7,78,3C,B8,24,4F,AF,97,6F,A0,DB,87,98,83,BA,73,E3,76,A3,AE,08,86,7E,79,B4,F7,E7,B1,E9,FA,0E,8F,72,F1,4A,F1,13,BB,82,BE,F6,D8,E6,3F,16,1A,0D,BD,59,7F,14,29,28,9B,C8,41,EB,73,DA,8A,86,9E,E1,28,60,49,00,ED,AE,D9,33,25,8C,44,29,24,D8,BB,A3,1A,C4,B1,DE,2B,9F,C5,BA,92,6B,82,DE,BF,4F,A2,8F,1D,2C,E5,8F,D8,4E,19,A7,C3,76,93,9D,58,33,25,20,70,E1,80,17,54,F6,1F,B5,39,7C,02,72,B2,E9,2C,6B,CF,A7,FA,A3,1B,73,7B,60,E7,9B,12,9A,3A,84,48,38,4A,FE,CD,99,91,A0,A1,A2,26,F6,1B,AD,5F,B2,75,56,61,B9,DF,F7,0B,D1,42,3E,DC,06,6D,DA,5D,51,D6,65,A2,4D,7D,C8,76,0D,5E,19,E8,37,5E,C8,DF,B1,B5,56,D0,15,73,BA,9D,5D,E7,58,47,19,9E,F7,38,D8,1F,BC,3A,FB,9F,D7,B3,8A,6D,46,AD,0B,F3,01,15,CE,FC,78,88,F8,97,6E,82,C8,8C,C2,E0,5F,BD,B4,6D,2F,A6,9F,FB,69,8C,4A,FB,DF,9D,9B,14,CE,10,02,73,50,75,41,CF,A5,61,BB,D2,77,DF,48,00,CA,13,92,C7,40,23,FF,95,F3,3D,55,A6,52,6E,4C,54,04,6B,0B,DC,B3,EB,AF,4E,47,11,1C,2E,41,FC,79,9A,BD,E7,CF,86,17,28,AE,AE,A6,F0,18,FC,3C,34,7F,79,F3,4E,6C,CC,1C,BF,2A,71,93,29,CF,BA,0B,14,C4,23,F9,4D,A8,3F,49,8C,A6,2C,30,2A,96,0A,DD,8B,E1,0C,10,0E,7F,EC,E3,D2,13,B4,4C,38,4E,D1,E0,5B,D7,72,31,4B,4A,B8,DA,7D,9B,F4,16,61,C3,B3,F8,C2,94,BC,6C,A4,A3,9B,E4,3B,7E,BB,A1,F5,44,94,43,F3,05,48,F1,97,59,50,0C,3F,B7,3A,D1,45,D2,3A,FE,2D,97,7F,5A,70,84,23,A7,26,B0,D8,02,1E,40,1F,B6,AD,4D,31,95,8A,13,46,71,D5,FB,F8,BA,36,7E,A2,09,88,8B,EB,48,67,F9,FE,14,DA,D7,7B,83,BF,2C,E5,8A,65,DB,43,75,F9,C0,8D,DC,23,D1,38,E8,7A,38,4F,46,05,06,4E,11,A1,C5,35,C8,BE,5F,EC,9B,F8,B4,7E,5F,E7,BB,A9,11,2B,3B,19,EC,51,C2,5B,D3,B9,31,91,00,07,66,6E,8E,F5,83,9C,6F,99,D6,7F,1F,E1,CA,04,EE,CC,F1,65,9A,AA,B9,5B,9A,31,A3,0D,58,83,AE,26,5B,A8,B3,68,0B,2C,75,44,63,5C,D6,EE,5A,13,74,A3,49,6A,D8,BC,B1,AA,D7,7B,CF,BA,12,27,2C,D5,40,AD,6C,46,DC,6E,1C,73,8A,F7,6A,DF,5B,62,85,58,21,AA,F0,D0,D7,D6,14,BA,E1,03,D0,17,2F,40,E3,22,24,87,70,D2,37,C2,AF,AF,83,2A,59,AB,FE,47,CE,D0,CC,35,5C,2D,20,38,AE,9B,3F,1D,0D,64,D2,EE,43,4A,D0,F0,7F,A2,CE,2E,76,C3,9A,91,0D,AF,37,F4,33,28,1E,58,16,17,CC,C9,73,DA,8C,92,77,FE,54,39,F3,81,F4,C9,C5,96,DB,7F,3C,61,CE,4D,75,CB,E6,1A,1B,E5,4B,47,09,2D,42,CE,0D,81,AC,51,B9,62,6B,EE,6F,36,08,79,02,9B,18,A2,E5,AA,C4,C7,A1,8D,98,00,7A,69,02,34,43,F0,40,62,E4,CD,0E,6D,96,02,30,15,D3,BD,13,27,FC,CA,76,C0,C5,89,4D,43,CE,37,FB,8F,94,B1,D6,6B,2D,6E,AC,19,0F,5D,38,9A,5E,F1,29,B5,CC,B2,CD,8E,2F,E7,1F,57,A7,64,C8,9B,C5,43,37,EE,26,CC,99,BB,61,8A,2B,DB,53,87,71,06,A7,F1,99,87,99,09,65,1C,5E,9E,0D,9A,54,B9,9B,4B,DA,E6,06,69,EB,21,97,2B,06,75,F3,6A,BB,04,38,0F,36,11,80,E7,90,C8,01,4B,B5,78,4A,2A,7A,83,C9,A7,5F,DF,BD,FC,59,38,AF,14,95,CF,BC,AB,59,BD,F9,ED,7D,C5,30,82,ED,3E,44,2B,56,60,5B,7B,1E,50,F2,65,1C,01,52,E1,82,05,EE,B4,E8,BF,6E,E2,13,4F,06,52,AA,21,9E,C8,99,EA,55,E9,F8,5A,69,0E,8A,7A,C9,A5,92,51,A3,4A,91,13,7C,60,85,5D,CA,AF,B6,18,00,B1,F8,1A,17,E1,9E,B9,F9,3E,24,76,0A,00,56,C4,15,92,9B,A1,AB,80,30,BD,32,32,EA,9C,F2,AF,33,23,90,E9,BA,5F,77,21,98,4C,69,CC,7A,3E,FD,87,B9,42,FB,26,80,CA,AC,21,11,4F,CB,7B,5F,F6,96,4C,AB,16,70,15,09,37,9E,51,AE,25,8F,38,45,F4,BF,2B,53,13,AF,8A,FF,56,A9,E9,8F,B4,79,32,BF,14,10,DA,B1,50,7C,0C,7E,03,28,20,87,00,BC,55,01,0A,4F,FF,EF,52,00,A0,30,D6,1C,BF,F8,5E,61,FA,60,25,17,85,63,CC,0A,CB,60,59,DC,B4,54,C9,65,52,56,65,B9,DB,40,A3,4D,6E,13,63,E4,6B,5E,BC,EE,E7,C6,EE,55,39,24,98,E5,62,09,77,AF,47,E1,4A,9E,AB,2C,C4,60,40,11,F4,26,3C,57,67,66,43,D6,F0,C0,AC,73,AB,E7,27,92,AA,57,06,7B,AA,B4,EC,07,46,45,61,DB,DC,BD,12,D3,33,1A,6C,CA,6F,A2,C9,41,32,B4,48,A2,CF,E5,F5,DF,A1,61,F3,9C,CE,24,60,62,3A,DC,62,7F,14,95,63,B2,28,DF,A5,AE,FA,C6,F0,2B,8D,36,53,0E,2E,2B,5D,4F,50,D7,D9,00,3C,B6,80,01,50,0F,6A,92,DC,30,BC,90,8D,87,7D,76,F2,39,ED,07,6C,2F,2D,BB,A3,EB,F5,61,E3,BC,D0,93,91,7A,22,0B,4F,30,2B,12,BF,00,91,92,90,53,D4,2D,C1,AD,1C,93,A4,D0,15,F7,3C,1D,2A,0D,18,BB,F0,6E,2D,33,76,D2,C0,0E,8E,6A,33,6E,25,5F,4C,80,9B,6D,C4,C8,ED,10,94,60,40,3F,47,71,0D,C4,B6,A7,C7,7C,F4,FD,08,FF,D0,28,0F,8D,EF,64,13,BF,AA,30,DD,22,13,A5,9C,96,38,74,7E,F2,35,AE,FD,70,AD,7E,80,FE,59,79,F8,CD,DA,DF,ED,B5,C0,18,F2,46,A0,CF,15,2E,36,A3,FE,30,96,64,C6,29,F0,C1,6B,DF,ED,6F,1A,B3,C1,70,78,49,0B,84,B7,7E,27,E5,81,9B,53,4E,1A,6A,B2,0E,23,46,81,A1,42,93,07,41,5D,73,BC,AA,55,98,0F,D7,ED,45,A0,B1,C4,F7,C5,44,D0,D8,EB,7C,58,2C,25,EE,A3,54,79,F5,99,76,3A,16,6B,C2,34,3F,81,26,4A,1C,FC,3C,82,34,FA,34,51,BD,40,FE,31,33,D1,DE,11,B1,50,C3,21,7D,AB,AE,B2,EE,CE,3A,81,85,38,56,C2,2A,EA,75,E3,13,E5,3A,B1,03,5D,5C,09,16,9B,91,B0,B2,2C,25,60,B1,EE,4E,12,42,25,FA,49,41,A1,31,AA,B2,56,D8,90,35,D9,39,03,B2,89,2B,9C,CB,29,E9,B1,74,46,D6,1E,DC,89,85,E5,2A,10,2D,94,42,2E,2A,AC,DE,36,7F,42,00,37,BF,0C,17,3B,D7,D3,38,F3,2B,6D,05,8A,D5,AB,D6,91,5D,AB,22,FE,D5,86,ED,1A,48,D4,B7,82,89,5A,AD,E9,CE,16,30,8E,D5,3E,31,CB,53,BB,1D,CD,0E,BD,CF,DD,0E,68,8A,7E,A3,4C,C7,99,FF,66,DA,65,B1,B2,56,D3,DE,39,F8,CB,97,67,3B,4B,8B,BD,96,59,9F,2E,BE,2B,55,68,A9,0D,1C,09,44,FA,93,68,78,65,6A,65,F3,CB,85,9F,22,07,E1,E5,D5,E4,39,43,2B,22,7F,55,9C,8D,8F,2E,6D,2B,11,D5,92,EC,DA,48,16,B5,39,67,EC,CF,84,30,B0,17,46,28,7B,DB,CB,F1,E7,89,B5,4A,9F,24,53,1C,8F,54,EF,92,71,BC,15,9B,EC,37,2C,2A,0E,BF,52,E7,94,14,7B,8F,05,0C,48,D0,2D,B0,D2,96,A4,F2,1F,CE,E8,81,10,35,C8,23,F8,47,C6,2D,E8,54,59,3A,86,27,E2,C7,EF,42,40,03,38,FB,27,B6,66,C7,54,ED,3F,27,6A,A1,06,3A,4B,A1,CF,54,0B,F0,1A,CF,2B,38,B4,9A,13,09,19,59,E8,F0,29,17,67,67,0C,47,F5,ED,78,33,53,73,ED,7B,4B,A8,F3,D4,37,3A,31,65,C0,48,AF,CD,10,7F,36,BD,32,4D,2E,E1,FF,CC,1F,58,F5,A9,CA,C2,03,D1,65,6B,89,0B,99,23,FC,55,4B,B0,EC,79,36,AD,FC,B4,48,0A,9B,25,2E,EB,82,10,EE,7B,52,07,53,39,3C,35,0C,B5,96,8D,9B,74,1B,E7,34,FE,D3,EF,61,E1,78,BF,E9,D4,0F,8B,AB,E1,49,86,B8,85,B3,59,43,00,22,9B,45,08,47,5B,74,A2,C6,BF,73,C9,FC,10,EA,6D,92,77,65,86,5F,7F,44,06,19,58,54,2E,5B,70,03,14,85,27,5B,9B,AC,9E,7F,D3,09,57,20,8E,D5,94,4B,26,5F,9A,75,D1,AC,9A,7E,28,50,AD,24,E6,4E,57,DD,9E,2D,3A,C3,EE,FC,58,6E,9D,BC,11,31,B9,64,3A,7F,E5,9A,12,15,36,21,0C,45,96,63,45,55,56,7C,C9,67,89,EB,CE,9E,19,CE,F2,51,5D,AD,C5,C3,9F,F8,90,17,64,2F,E8,16,71,69,36,35,FF,EC,35,DE,1B,87,CC,8B,1A,B7,16,2C,36,EE,C1,AD,86,D0,1B,78,3B,D5,B3,1C,30,11,45,54,27,6F,51,F2,4B,68,1F,C4,AA,6A,EB,DE,42,1D,5F,84,92,68,F2,74,E6,5F,ED,1C,35,55,7B,0D,EB,DB,23,EC,02,3D,68,27,E5,BB,A1,4E,B4,84,EE,9B,C9,C3,54,4C,FA,B6,7C,AA,7B,1B,60,FC,23,B3,87,21,40,92,A1,65,D7,E1,CD,D7,69,8A,59,6C,47,F0,05,D3,D7,52,EC,96,00,D0,6B,B9,25,49,C3,C0,5B,3A,DD,E4,5F,E9,42,B7,1A,71,D7,CC,8A,48,E6,84,B1,E1,56,CA,0E,5E,AA,26,7C,20,0B,0A,A9,21,2D,8F,40,F3,3C,78,AE,BD,89,2A,E5,B0,49,4A,2A,34,D7,CA,39,DF,77,41,73,EA,05,65,7A,B7,1F,44,47,F9,4E,82,1D,A5,C0,34,8C,8F,FE,8A,E9,E1,C6,37,48,64,08,D5,3B,DC,BA,69,8D,63,2A,DA,79,B9,34,3B,5E,48,2B,57,8C,61,71,84,FD,31,2B,75,7B,08,21,F9,CA,20,B0,39,03,BC,52,8B,35,28,92,1D,1E,AE,01,68,82,4B,97,BA,B0,FA,24,5A,71,F8,75,08,7E,A2,E5,F1,AF,91,73,F9,DE,D8,27,5D,8F,03,C3,52,A6,77,5B,A9,1F,13,88,3E,D9,ED,85,5E,D3,EF,78,58,D9,72,1D,9D,7F,9D,2C,AF,AE,A0,B9,7B,03,44,F3,BF,08,5D,B1,A0,AF,13,37,EB,A0,81,5F,27,01,54,A5,0B,8A,0F,43,93,CE,E7,31,66,C9,C6,74,F8,6E,BF,23,1C,C6,C4,8C,7F,6D,68,92,01,18,51,07,F3,EF,83,59,57,F5,83,85,FC,31,FF,9B,94,A8,C1,EE,40,AA,A7,BD,CB,7E,7F,B4,17,9F,AB,B9,B3,7B,7F,E0,B5,5A,8B,93,11,97,61,BA,30,C4,83,C9,A1,C6,15,F0,6D,C9,4C,66,D2,8C,F1,9D,DA,1D,E6,64,2B,45,D3,4A,F2,C7,8B,57,32,FB,4F,69,0F,92,29,0B,AE,9B,1B,4E,CB,78,97,BD,5A,4A,BD,65,EA,8F,73,1E,73,82,86,75,3C,71,84,F3,DF,2E,EC,B4,A5,3C,D2,F3,48,AC,E3,B6,69,BD,10,FF,59,A6,2E,E1,DD,36,F3,3C,43,86,7C,27,FD,44,BA,E9,F6,F4,E2,58,33,5F,6A,D9,0D,2E,69,D8,06,9F,1E,4F,3E,8A,75,83,AB,C5,CD,79,0F,7B,89,C2,BF,48,F7,59,DD,A4,2F,B7,AE,C8,A3,05,17,B7,01,BE,72,82,5F,1F,1B,F8,9F,73,D3,4E,63,04,DB,FA,8C,82,D4,69,10,6B,5B,B6,24,CC,00,33,B4,C4,6D,E6,11,00,58,81,DC,A3,5E,8A,04,2E,77,E9,5C,17,85,18,40,C4,79,E4,7A,16,AD,41,5D,B5,7D,D7,A5,7E,56,53,EF,76,1D,80,9F,2B,89,60,46,25,37,A3,7F,3B,25,1D,F4,36,BE,C3,08,6E,7A,CD,36,FB,27,EC,25,46,BD,10,57,DE,88,6F,FD,B0,F8,D1,93,AD,1A,55,2D,3D,B9,E2,D3,6D,5F,B4,08,C5,E2,4C,20,54,A9,95,BF,7F,5B,0C,73,97,84,A2,57,2F,40,45,5D,3B,ED,28,EA,59,40,F0,3B,50,07,D0,69,64,91,DA,C1,CF,5B,05,69,32,24,2B,47,18,0C,4C,B6,2E,FA,5F,26,C9,FF,13,6E,C4,2D,E6,F2,8B,F6,E8,94,9C,5A,E3,33,08,B8,9B,E8,33,E4,D0,39,31,2F,92,C6,D4,4D,07,44,D5,98,9A,9A,AA,5E,3C,96,C3,BA,8B,DD,01,9E,6F,33,BE,81,78,70,5B,07,58,BF,7E,40,17,C4,BB,11,73,1E,F9,4F,D8,99,35,D1,E8,77,FB,AB,4C,C0,6D,D1,23,C1,98,4C,DD,42,39,6E,DC,DB,9E,D9,71,FD,3E,2C,AE,C6,70,89,8C,60,A2,63,40,8B,EE,C4,55,3F,E5,ED,B8,BB,66,57,0F,D3,CA,1C,F7,FC,14,AD,77,45,81,C0,CF,D2,7D,6F,36,B6,1B,6B,90,01,74,49,F9,08,72,23,E4,AE,0B,A9,BE,AE,44,08,C0,62,C7,95,11,6D,41,84,4A,68,F6,3D,78,32,6F,6C,08,D4,AE,B2,5D,94,3A,FC,1B,F3,47,B3,F0,27,08,53,63,AA,BC,AC,2D,B9,7D,F6,8A,F2,F7,94,65,9B,74,A0,72,6F,AA,EF,B4,EB,B1,EF,13,FE,C9,14,F2,40,E8,01,EE,7C,90,32,65,4D,CE,93,74,26,0A,D7,EC,BB,75,CC,42,95,0D,B9,C7,07,8A,BB,ED,BE,EF,33,FD,73,5A,BA,C3,54,31,59,3A,8D,E2,7B,25,B2,5A,B1,1D,B0,5E,80,61,DD,5E,62,43,74,62,1B,4F,0C,7A,D6,8C,48,C8,5C,A2,14,EC,2E,B1,F0,0A,6C,81,63,68,F3,A2,49,41,7D,7D,B5,BB,3A,39,84,E9,C7,12,A0,34,8B,C4,BA,E6,D0,F1,40,AB,4F,96,1B,98,38,F8,1A,29,EC,BB,D7,B7,94,C7,F6,BD,D7,DE,16,28,2B,A6,E5,13,09,30,D2,41,EA,1A,3B,4E,1A,7D,CD,17,5D,62,FF,1E,0C,4E,EB,AF,04,F7,33,1E,05,53,44,D4,6D,44,68,9B,7B,8D,BF,74,36,7E,E4,8C,CF,B7,18,58,10,C5,0B,30,21,BB,6D,50,C1,47,08,5A,3C,B1,3D,BF,DA,99,56,1A,A1,CC,F5,DA,6B,D0,58,88,D3,EC,76,18,D1,94,85,B7,98,E4,C2,38,A2,D3,32,B8,9D,93,3E,70,83,43,06,AC,41,30,6C,49,C8,2E,77,00,B0,96,F6,9E,66,02,2B,AE,7A,3A,F3,56,C7,BD,55,AD,D9,60,19,06,1B,06,2D,8E,36,FF,D3,FC,D3,7A,60,55,3E,99,5E,16,4B,26,34,DC,83,7D,48,14,95,38,FF,8B,2C,31,10,5B,A8,5F,1D,8E,45,28,A7,64,CC,16,0C,D5,65,20,AC,B9,75,CF,6D,F0,F9,0F,93,B8,8E,91,C8,B4,E6,57,FC,55,7A,41,7D,81,2D,98,BF,F0,0F,3F,7E,64,22,9B,5C,A5,1B,33,2E,86,3E,B9,FD,4F,EB,D8,B1,C8,36,B4,A5,33,6C,C7,75,51,31,75,95,A0,21,B7,45,C8,30,0D,3D,56,C5,21,B9,EE,15,DB,AB,D2,8B,51,12,AC,C2,2C,36,49,E9,32,F8,17,49,73,CD,52,57,2F,B5,82,F6,7A,77,70,FD,95,69,CF,60,C5,8C,3A,CB,A1,6C,B0,1E,26,8D,D4,FE,3A,42,B8,F6,DE,D1,58,FA,28,25,7D,07,0C,FF,99,B4,89,F0,D2,9F,D4,29,1A,B9,F5,DE,81,4A,B8,DC,C3,62,F3,CA,4C,F5,4C,3E,D3,D0,78,77,4A,82,D9,4E,BC,D5,F7,83,3A,A7,4E,53,9D,51,22,B8,B4,99,DA,4D,ED,C6,E5,5D,DD,30,D0,08,36,96,0B,2B,3B,27,28,65,6A,8E,41,29,16,07,AD,39,7C,72,23,B6,BD,8B,EF,11,FD,16,33,83,16,F7,30,C7,3B,47,7B,4F,0C,6E,99,9F,DA,67,04,F8,52,86,9D,5C,50,2C,65,12,F6,C9,19,98,3A,29,F9,5F,5C,30,57,D0,D4,65,EC,4F,39,89,48,8F,42,33,9C,12,1C,8F,8E,50,77,33,70,DB,7E,3E,10,F1,84,1B,FE,0B,26,29,FF,C8,80,11,A8,4F,8C,99,8D,6B,40,55,54,74,EB,F1,B9,B5,34,69,57,FF,27,BB,9A,CB,0B,E9,F9,CE,91,BF,AC,91,E2,AC,06,50,33,47,EE,8F,E1,81,39,A9,FB,12,E6,C9,DA,5F,4E,2F,A9,03,AE,CE,95,E9,FC,0C,14,92,D0,D8,21,47,A4,0E,26,AC,5B,15,2E,20,32,11,A4,1D,5F,89,45,5F,ED,C5,2E,02,25,36,9E,96,3F,46,9C,7D,27,3C,D6,A1,D7,E8,10,36,EF,AD,3B,E9,6A,9F,E1,6C,D7,F4,82,91,AE,59,7C,99,21,C7,C2,8B,4E,D4,87,5B,F9,80,22,3A,89,E1,9A,67,36,B7,1E,F0,8E,84,57,91,F5,EB,99,2F,9F,6A,7E,7F,72,89,E4,00,61,49,11,1D,0E,2D,F2,3B,AF,3E,52,2B,09,25,AF,D7,99,C5,0E,09,73,4D,6D,53,AD,99,3E,3D,03,69,48,EF,B0,68,6E,4E,7B,AD,8C,80,31,6E,EE,3E,A4,20,C2,2A,95,DD,23,5C,6C,B0,E0,57,D9,66,F6,22,4F,79,06,7B,55,01,B6,4E,6F,59,89,25,2E,03,72,93,64,CF,C0,EC,75,C7,96,76,52,70,A7,EC,D4,3C,45,7C,DC,49,CE,EB,4D,8C,D7,3D,15,A7,0F,C2,AC,DB,D8,AB,B5,67,D0,DB,C8,7E,81,3D,1A,7B,CF,9D,9F,0C,07,9E,00,A6,82,11,2C,C0,AB,1F,A8,D5,27,E5,3A,38,12,C2,FE,35,D1,7B,17,D2,DB,40,CE,2C,B4,19,51,7C,BF,F1,93,FA,EF,90,91,44,4E,7C,2D,C8,41,13,37,6B,B2,71,B3,BE,4A,AD,F5,C6,5F,C7,7A,1F,40,88,9E,41,FD,8C,CB,C9,E8,C5,FA,1E,A5,23,00,7E,4B,75,4B,B2,6C,F3,F1,33,D4,C5,40,EC,40,21,1A,D1,66,40,C7,3B,40,D3,BE,4B,01,A1,91,3F,4B,5E,19,B9,EA,F4,74,90,C2,06,42,E1,9F,86,BB,6A,7B,79,06,35,00,F1,81,FD,86,BF,B0,FB,28,F8,84,3F,35,3B,77,40,9D,FA,FF,BC,EE,2A,66,03,E5,7C,A6,29,CF,DB,93,51,A0,86,17,B4,32,C7,AC,31,80,B5,73,8F,57,5A,D8,51,06,3D,CB,60,CA,B7,40,E5,F0,B4,2C,F4,B5,D3,44,3C,AE,E3,2B,3D,BA,BD,19,84,57,FE,F4,51,10,BF,5B,E7,CA,2E,89,62,AA,92,62,4D,72,5F,CF,A9,F1,F9,3C,8C,10,89,22,E4,44,F9,F4,A5,C1,8C,6B,79,86,7C,1B,0C,48,3F,E1,E0,AE,4E,69,1E,77,04,9B,22,AB,68,FB,C2,A5,74,8F,62,75,8C,4C,CF,B9,9B,13,88,E4,65,45,1B,9B,C8,3F,A7,00,75,9C,95,CD,98,FE,87,37,48,B2,0E,FE,65,15,2B,B4,2D,F8,C0,2C,67,C4,BE,7D,5E,9E,22,4B,7A,84,10,11,83,C0,8F,80,D5,FC,1F,01,82,93,10,6A,BB,98,B1,62,9E,04,9C,EC,E2,8B,1F,7D,53,4F,57,2A,8B,77,7D,99,7C,83,6C,F6,04,59,3D,85,E6,1D,90,61,33,86,0B,3D,77,FE,0D,B9,AE,FF,26,7C,63,3B,9A,9B,68,5F,12,BB,E2,DA,7C,D4,C8,78,AF,E9,A9,99,38,09,D6,BF,1D,77,63,E7,76,25,CE,B4,8E,BA,D7,02,CC,69,BD,80,27,C4,2C,97,ED,29,47,3F,25,44,C3,5D,87,5B,48,73,50,E0,23,68,88,BA,73,2B,2A,5A,A6,F9,D4,C9,60,E5,84,6A,48,63,69,95,9F,DF,13,FE,BD,17,B5,47,36,8C,CF,FB,B6,41,90,E0,F9,EC,F0,C7,DE,5D,B3,55,2D,39,6F,9E,2A,3A,85,CE,CA,A0,97,5C,3C,EC,64,CB,9C,0B,A8,E8,33,52,4E,24,BA,B0,87,90,1F,B1,AA,58,6A,F4,CF,AB,5A,52,A5,FC,9B,53,54,B7,A1,68,7F,5A,77,44,66,4F,43,B7,41,40,41,A3,39,25,FF,AA,F2,60,46,79,B8,7D,5F,DE,32,15,52,00,5D,BB,76,D7,84,6B,9F,97,3E,6B,BD,74,4A,65,9B,87,38,DB,B2,18,73,9A,12,2E,31,B5,5C,12,51,ED,E7,51,A3,67,4F,87,E1,75,2D,8D,14,0F,09,9C,A3,BF,93,E1,53,D0,E5,8C,AB,DE,FD,A1,36,87,BD,0E,82,C8,00,A5,A5,49,17,31,1B,CB,98,EB,8D,F3,65,07,EA,95,2D,24,7B,99,31,89,9E,BC,27,98,0A,F8,F6,07,A8,35,94,DC,AE,3B,73,CC,3F,1D,2E,45,FF,CA,4D,24,52,C5,B1,00,AF,F8,FE,EA,93,B5,E1,89,40,99,D9,A8,BE,64,15,45,A4,43,A5,57,E9,84,93,DB,20,A3,88,A4,8A,9C,5B,BA,35,24,26,F6,82,FD,02,0D,B6,C1,43,78,E4,BF,93,50,D4,91,44,53,30,95,54,3E,8F,52,AC,0B,DB,42,69,F5,77,CF,95,84,79,0D,5E,23,02,05,E1,43,09,C2,E1,3F,4C,CC,47,8F,D6,F4,AF,BE,82,71,90,54,F7,6D,8C,DA,AB,D3,6B,92,2B,4E,0E,8E,E6,8C,A5,7E,0C,9F,4A,B7,92,7B,77,21,EB,DF,2E,FF,42,FB,0F,FF,36,74,A5,04,4D,42,E5,99,6F,C9,E3,BE,33,35,13,6E,23,69,81,36,58,74,6C,A9,6A,EE,1C,F4,A9,64,96,CB,B3,8E,DD,65,69,27,63,50,2B,52,0F,24,73,84,BD,B6,E1,FD,46,5F,72,8D,7D,8C,8E,CC,9A,60,82,24,72,35,15,BE,B6,1F,74,0C,B7,95,53,A8,01,99,C7,94,00,17,31,AB,85,72,F8,75,B5,56,20,43,1A,92,CB,99,AF,F2,68,07,5E,92,6B,5E,0F,0B,D3,5B,CF,8A,38,37,7D,02,F4,E4,E6,7A,75,2A,59,C0,12,E0,08,8A,02,87,CA,37,6E,4A,CD,A1,15,34,60,A0,8D,21,A4,93,5E,18,06,94,01,B3,3C,16,14,D9,B5,1E,5D,27,5D,97,52,3F,ED,64,AC,2A,E1,E5,22,CC,13,FF,8C,37,A8,0A,7E,84,26,1D,92,DB,4D,EF,A7,FB,3E,6D,CE,68,A7,31,04,31,DF,7A,C5,7A,7E,CB,CA,8C,5A,87,29,FF,7D,AA,86,47,64,C6,31,E5,8C,53,39,AF,B8,63,45,D4,6A,13,E1,98,78,9D,85,52,28,40,A7,99,42,D5,20,52,3D,B3,99,C2,8D,89,AA,2D,04,67,3F,06,94,A0,FE,2E,78,53,E3,A1,1A,DC,B3,AA,66,F7,F4,E2,97,44,71,DD,0D,FF,AC,92,DB,7E,1F,D5,75,45,02,45,DD,71,12,C7,DE,74,3F,CF,12,6D,7A,89,91,B1,3A,1F,E1,5E,B6,33,38,AD,4F,15,0C,9E,9C,3D,C9,A3,62,E9,16,FF,48,43,05,B9,96,C1,6B,25,D1,AA,F6,84,A1,97,96,4A,AD,BC,31,BF,F5,1C,B1,59,34,85,CB,CC,67,ED,CB,60,47,A5,DA,BB,7D,DB,E7,9D,E0,D6,D3,1E,8D,DD,7F,41,93,A7,2E,BC,CB,91,34,64,AA,0C,83,EE,FA,75,0B,68,17,A4,1E,69,EF,70,D3,D1,69,1C,EE,C3,DC,14,58,97,3A,0C,48,D8,AE,8E,81,82,7A,F0,4C,00,E8,0D,42,E4,B6,1B,FA,7C,C7,AC,64,AA,0C,79,92,F3,65,2A,8B,A6,3C,C3,04,0A,D0,DB,15,CB,47,92,62,09,1C,76,6E,53,6A,73,C0,69,3F,92,F7,82,87,84,65,83,78,B5,81,67,18,EE,FB,C9,84,D2,C6,AC,A7,1C,21,76,67,B2,5E,8A,75,BC,49,F0,68,7C,EC,8F,0D,83,7E,92,5E,78,84,5F,15,D2,8D,3D,82,D0,21,D6,D9,36,5F,CA,E5,46,2E,9C,A6,F3,33,3E,A1,22,E5,77,83,86,62,65,23,31,80,32,E0,65,01,CA,75,C9,F7,73,60,20,1C,48,CB,EE,0D,E6,63,93,8B,89,07,41,47,3D,82,BC,23,5C,76,51,92,E1,B9,EF,FB,38,4B,EE,29,11,0E,8F,73,19,A4,50,AB,D6,AB,96,6A,AD,E7,BC,5C,1C,61,39,D6,86,77,84,58,12,C9,CE,84,0E,24,EC,EC,20,B3,C3,B9,E9,DA,64,CD,66,DE,00,DD,E5,EB,ED,2E,AD,A0,8C,A9,A8,35,35,7C,C1,18,37,21,C8,04,CA,43,D9,83,87,7B,EC,34,3F,B3,2E,88,3C,C6,E2,9C,49,A0,65,F9,85,32,4E,2F,98,4E,2E,17,7E,68,EE,6F,B2,03,83,03,FE,A1,7A,DC,2F,4E,CD,C1,A4,EC,E0,A9,19,7B,25,77,20,5A,6B,C4,2D,C0,22,05,8B,05,AB,10,B8,1C,39,76,70,E7,18,64,4C,49,1E,58,70,3B,63,C2,BD,41,F2,49,F9,48,2E,70,5D,93,AC,CB,C9,9D,F8,20,B6,CC,B5,EA,65,07,DE,8D,B9,CD,9A,EC,87,92,1D,A6,AD,85,12,8D,64,0D,A7,E6,E8,93,03,D9,39,A0,F7,82,D1,90,14,6C,E9,7F,C1,B0,6D,6E,E9,98,D0,50,5C,B3,DD,47,5C,6D,1F,F3,BE,1E,30,A2,ED,47,89,C3,79,AF,82,E7,05,FA,E0,8D,AF,6B,A1,AF,C8,9A,E7,6F,8E,98,FA,D8,12,02,84,CD,47,3F,80,47,18,55,48,CC,91,C7,80,20,8A,EB,42,4D,34,FF,80,3A,3B,9C,8D,94,72,74,E6,F3,78,8F,B3,9C,6A,4D,4F,5B,F1,08,FB,89,26,A7,30,7F,2C,AF,81,E7,F7,BD,72,DA,D7,C4,60,01,C0,E4,32,CF,A0,CD,CF,FD,B4,A3,70,C8,A5,C2,0F,CE,40,31,01,97,84,CF,E9,22,1B,65,8B,78,F9,DC,3D,CD,F2,30,4E,94,86,6E,AA,95,FC,06,C9,AA,7E,F8,06,53,8D,BC,86,B9,44,2F,FA,AC,C0,40,76,DC,07,B7,F7,C1,39,5B,DD,DD,C6,B7,CD,B4,F2,60,64,F9,72,F1,49,9A,93,17,C2,72,4D,30,63,3F,2F,BA,7D,53,ED,ED,BE,AB,7E,1D,45,9A,EB,B0,67,BA,2A,1C,71,9B,5D,FF,B8,93,2E,BF,D9,67,07,1F,68,11,58,A2,4B,17,E4,7E,37,F6,18,73,66,23,3B,8E,E9,C5,6A,F5,92,7E,52,4C,51,58,B6,D6,AA,17,CD,1C,C0,D5,B0,03,4F,28,25,D7,E8,7D,AF,7D,A7,12,7F,29,AE,DE,96,64,BD,7E,81,6B,6B,36,6C,4D,97,FF,D9,ED,71,E1,B1,8A,6B,B4,29,7D,70,8A,69,5F,4F,1C,51,1F,49,3F,54,F0,21,34,4A,80,E5,F4,63,C2,AF,CD,89,1C,6F,B2,C3,99,2D,09,40,B3,90,60,BC,45,9D,66,FF,09,D3,A5,FB,E0,C7,DC,90,8C,75,9B,8B,D8,A2,C2,E1,C2,B6,AD,73,94,EA,C0,AE,0B,D7,86,A1,76,98,26,DC,83,E8,B4,61,E5,10,E0,45,06,03,0F,BE,9C,39,02,F3,57,41,63,7A,FA,1C,08,58,5D,69,0C,53,D1,06,A6,E6,21,1B,C6,DB,74,DF,2C,25,47,6C,76,09,61,C5,47,81,E8,D0,AA,AD,79,10,3F,5C,BE,ED,A3,A1,96,2D,B8,82,B6,11,30,F4,4F,89,BA,D1,43,AF,F9,95,B9,F8,CF,AC,84,82,2E,2E,EE,47,43,7A,13,52,3D,5C,70,11,0F,A3,FC,54,4F,86,65,7C,99,7B,B2,D8,04,3C,18,45,49,F3,95,F1,3C,DD,59,2A,1F,25,E3,2A,3D,AE,56,8A,41,C4,C8,AF,69,79,73,ED,47,C8,E8,B4,0B,A9,C8,42,0B,C5,E4,5F,90,F8,88,CA,3A,CD,A0,65,62,93,FB,8D,F1,A1,38,78,4F,DD,1C,FF,65,62,3A,E9,E2,C8,4A,7B,BE,F6,90,F2,DC,6A,C8,DE,54,EC,54,D8,46,F2,B8,9E,02,71,B3,9A,1E,64,A1,C8,60,B5,8D,3C,AD,6D,A2,C0,22,F3,51,A2,04,F5,6C,D8,59,C9,18,23,24,6D,B9,43,CC,71,7E,0D,81,A0,94,94,41,2B,66,3E,3E,9B,38,A9,34,A4,80,48,F7,71,C2,FE,1A,25,F3,48,33,61,BC,BB,80,C6,65,BF,09,0F,EE,37,1E,9E,F3,4E,A0,A8,00,12,BB,7E,00,D9,87,49,A5,5D,23,EB,8D,3B,2E,D4,0E,FF,3D,9E,5A,92,5B,C0,39,97,E7,5D,F6,35,8A,EF,55,3B,CB,59,6E,3C,3E,A5,B5,CE,13,F7,08,57,E7,1E,8F,B3,87,DD,97,AB,21,57,DB,66,08,17,39,12,91,F5,28,B5,19,3D,48,7B,DE,6B,96,12,66,5F,EF,F4,87,36,2A,3D,2B,4B,62,D6,E8,03,8F,31,E8,1D,2E,C5,01,B2,69,84,9B,F5,23,A3,CF,FC,5E,BB,01,99,A7,04,2C,EF,B0,3B,F3,0F,FF,E9,DD,ED,85,F8,9F,0D,1D,AC,46,C0,9F,F2,34,CE,4A,69,98,99,37,F1,F8,14,96,D0,78,6A,61,65,B0,C5,1A,C5,F3,8F,A4,2F,4E,16,0C,F9,36,A3,ED,D0,1B,C2,31,9D,D0,B8,56,B7,EC,78,47,1A,B6,4D,3C,61,D1,63,FE,A3,84,47,89,63,BC,0F,8F,58,35,EE,86,A4,EF,78,13,09,8C,1B,6C,4C,1F,67,67,BF,5D,0A,63,C5,4E,1F,61,84,37,A2,E5,2B,8E,0E,62,98,F1,B9,94,02,59,E9,6E,83,3B,FA,A2,CC,80,CC,08,ED,D1,CF,B4,AB,6F,F0,F9,F9,CB,09,35,43,37,36,18,70,8B,E5,01,3B,13,1C,60,51,83,AE,A0,D2,78,76,A1,B9,3C,D4,BC,F0,44,9C,67,E0,4E,70,B7,95,B1,2C,C3,42,B6,04,A9,FD,61,CB,85,CD,FF,6D,CA,5E,76,F0,19,5E,39,4E,95,AC,49,3E,B8,4B,D8,BF,95,EE,A6,0C,37,21,5D,1E,FA,1E,A2,20,A2,B1,C6,89,43,28,12,8E,9A,58,58,59,DA,59,B0,91,9B,22,21,F4,73,7F,4D,C8,85,A2,88,1B,DC,00,AF,C2,D5,DC,93,5C,E9,B6,A8,16,F0,5C,8C,BE,62,97,A4,12,F0,50,5A,31,CE,7E,F9,5D,BF,D8,F4,33,88,0A,4D,E9,1B,24,CF,31,33,F4,B2,61,11,66,62,8A,23,D0,04,33,A9,B2,39,40,E0,78,C3,6E,B8,73,78,D7,B6,B2,95,67,DE,B1,9F,B9,7A,D6,72,3F,2A,D4,9E,72,97,98,6B,82,FD,9C,05,1E,E0,20,F2,73,5D,1D,01,F8,AA,BC,91,9E,AC,CF,8A,D5,95,DE,BE,68,5B,BA,E0,EF,37,62,9D,33,CC,61,25,F1,5C,56,D3,E0,FE,E5,EC,C7,DE,F1,4F,B6,9B,10,2A,40,F6,6B,78,73,E8,40,8D,EF,DA,E2,6C,6E,D8,EC,E9,6F,E8,9F,E0,F3,8F,59,E8,AA,5A,88,7E,69,9D,08,E7,69,11,3B,80,79,52,1B,0A,F2,25,84,8A,7D,DD,68,4B,F4,17,DC,EF,33,07,3B,13,69,DD,A3,4A,C6,DE,89,46,8F,22,A1,79,B8,33,2E,C6,FA,CD,CE,4A,70,4E,B5,B8,52,D0,9F,D4,F6,EE,08,F7,2D,78,16,11,B5,7C,35,92,A5,60,00,DB,10,DA,49,8D,8D,4D,5A,53,AF,01,43,B3,8E,7E,1A,F1,3A,43,29,88,96,1F,B5,19,F6,0A,F0,E4,70,E8,D6,10,8B,41,8F,7F,86,16,6B,1B,B8,A7,FA,CE,14,36,D2,5E,0F,74,EE,FA,F1,D0,23,AD,54,64,65,A1,3C,E1,B6,FC,B2,5E,30,69,4E,1D,6E,56,1F,B3,45,42,B3,4C,52,9E,1A,A0,21,A8,9B,75,6F,55,B0,95,AD,88,BB,A6,9D,1D,01,07,59,E8,B4,4F,9E,36,E8,12,4E,09,23,EC,7E,FE,78,E9,A3,20,FC,F6,70,1C,53,73,32,F0,CF,48,E5,D9,84,9B,D3,B9,8C,F3,89,1A,7C,E7,42,6D,BF,9A,1B,91,CA,89,9F,56,DF,B8,1C,32,26,05,24,8A,0D,74,4A,1C,5A,2F,30,46,05,3D,71,F7,D4,4C,36,13,5E,CC,79,78,44,D1,DA,81,0B,EB,3A,44,50,B2,1B,05,61,49,64,B0,B9,CC,60,1A,7E,DB,13,AF,5A,38,FA,2E,81,9D,7B,22,53,3C,F9,33,FD,1B,66,7C,86,18,86,7C,7E,83,75,AA,16,C3,A3,1C,31,D4,8F,92,96,A6,8C,92,25,28,CC,07,25,8C,A8,71,98,CA,5A,A4,B2,41,77,BF,05,AB,BF,90,77,7B,A9,1D,EC,F0,66,0B,EC,E0,6D,C0,18,CC,B9,51,30,BB,47,99,93,F3,03,C6,81,6D,16,99,27,63,26,DF,C6,6F,E0,0D,6F,DA,5C,79,2E,39,4F,A2,37,EA,B8,53,03,29,7F,EC,46,86,BB,22,75,86,58,1C,D9,1C,1A,6F,6D,59,8B,30,FD,5B,9B,22,1B,18,8A,C8,10,A5,20,6C,25,6D,5A,4E,37,26,C1,77,D7,29,23,94,14,5C,B8,32,E2,08,BB,6B,2F,9D,80,31,CA,6B,F5,82,DF,AD,62,91,20,AE,25,CE,6B,4B,9C,67,7D,29,17,45,06,35,A0,00,DF,A0,C6,EC,2E,A7,A4,DE,65,29,C3,DA,46,5D,79,FC,C7,33,8D,13,B9,9F,D5,74,D0,F2,66,54,AE,D4,00,30,92,E4,9D,33,67,2E,8A,E9,6E,94,5C,3A,DD,5E,CB,9A,1F,1C,1F,ED,5F,75,8B,94,AD,67,6C,CA,B0,21,F3,B1,67,6D,CB,C8,62,E4,A8,96,86,C2,ED,BE,38,83,37,ED,5B,11,5F,D3,00,E9,54,6B,9F,E4,12,94,ED,FC,5A,A7,62,8D,DD,A8,9A,B8,A5,DE,12,E0,B5,E0,B5,80,48,3F,7B,1A,2F,2C,10,5E,2C,24,13,BF,D9,47,2A,10,AC,84,17,92,C7,5C,32,30,E5,E2,05,15,B6,21,5A,EA,58,C9,BA,55,B9,22,8B,CB,AF,8C,27,62,AB,26,47,70,DE,82,D7,54,1E,6D,4C,58,CD,D3,22,E2,A2,61,26,E5,AB,18,7C,55,24,B2,D1,9C,C5,C7,48,BC,82,5E,32,11,BB,BA,D9,DC,BA,03,79,7B,F4,90,1F,22,F6,60,46,95,08,2E,0B,95,00,C7,80,BD,BD,C1,5E,FF,66,9D,71,1F,DD,81,FA,D8,06,5F,20,51,D6,98,C2,48,06,37,2C,95,B1,B8,CC,EE,DE,CF,B3,3A,9A,48,F4,0B,EA,7A,75,63,54,0F,93,8E,AA,19,01,D9,36,0E,2F,DC,30,83,E9,FE,DF,2B,17,F0,FA,00,BD,CF,CC,98,C2,BB,7B,F9,97,95,A1,FC,B7,0E,64,C6,E6,DB,A6,89,99,A8,4E,D9,79,FD,9A,F4,32,45,A4,BE,2C,76,5F,BB,6F,3F,B2,28,25,63,93,F1,7D,1B,19,AB,0A,7A,A0,D4,C2,9C,FA,28,A7,6D,08,D5,A8,44,10,BB,9D,98,5F,33,02,7F,1D,9D,E5,79,EA,A8,4A,E3,A6,43,CC,E3,D3,F0,C5,24,F6,CD,36,AB,8F,31,F1,50,B9,31,81,C0,6C,77,3B,17,51,6F,BE,59,6E,66,28,D1,BF,4D,60,A9,E6,C2,C2,11,A6,44,96,DC,46,FE,B3,0D,84,25,9E,35,D1,81,78,B1,B2,B1,7B,FA,4E,D5,F4,24,FE,D3,4B,A4,81,79,46,C4,2E,95,62,CD,F4,F5,20,D0,C3,0F,A7,F1,18,80,FD,79,D4,6D,30,00,4C,47,86,27,BB,D9,22,03,FB,BF,3F,36,41,49,49,B0,BC,48,B4,85,2C,45,3F,29,AC,AE,43,01,FE,2B,99,88,5D,7F,08,B4,6D,F7,31,D7,20,52,91,96,63,8B,FC,48,17,A4,3E,FF,BC,A4,BD,B1,43,24,9D,61,DD,0B,27,04,AE,81,70,A4,C2,52,18,E2,8F,DB,B3,33,D1,FC,60,11,10,94,91,7E,58,42,0A,C5,10,6D,09,0C,51,A9,7F,C5,9E,CF,00,D3,AD,D7,E0,F5,EF,20,02,61,AB,E9,74,B0,30,9C,9E,0F,4C,DE,85,33,AF,30,75,2A,72,88,CC,DE,0A,C2,CD,A0,86,FF,41,7C,77,A2,5E,BA,68,C3,A1,F3,EB,A5,7E,A9,26,C4,29,80,A8,58,11,E9,C9,40,27,85,EC,4D,AD,71,97,6B,35,F9,A7,70,3C,39,CF,88,AC,58,AF,E2,05,72,BB,FD,6C,80,15,09,57,4A,10,8A,0F,C1,C3,2E,8B,87,A8,6E,8B,07,B0,6C,FA,B3,21,82,56,C8,F4,A7,6C,8D,82,69,3B,CA,F5,8F,4C,DF,B9,44,3B,2B,07,99,47,19,0A,29,43,4C,44,CD,E5,79,BD,88,46,A2,F5,E9,16,09,BA,9C,C8,B1,5C,D5,D7,4F,68,E6,43,5E,78,AC,95,28,25,A1,16,68,5F,D7,CE,D7,4B,A4,6A,FE,4D,36,B9,27,A7,7B,78,51,B8,2C,8A,68,91,9C,E6,81,69,92,A9,5C,A7,20,51,F4,0C,F1,05,21,00,C1,B8,20,05,98,F6,06,B3,28,3F,4F,EA,27,DF,5B,F4,CE,50,1C,B5,F1,10,6D,4A,B9,47,F1,A5,80,71,02,69,8A,65,DC,0C,A1,FD,C6,6B,C3,D1,CD,B1,0F,F6,B3,30,83,97,F5,41,57,81,AC,09,62,B3,DB,CB,2E,75,2A,5F,1B,4E,16,46,4A,50,52,7D,F1,05,91,8E,BC,D3,73,1F,F6,09,EA,97,D8,47,3B,73,FC,53,D8,A4,69,CC,DD,E4,66,60,82,0B,B4,30,3E,48,FC,36,B0,CA,06,F2,B7,B3,E2,D0,05,88,60,CE,4B,50,89,A0,32,B7,B5,25,3F,FB,B5,72,8D,BD,77,9D,CA,5D,28,0B,BA,F4,9F,21,EA,9C,FE,67,A9,DE,44,1C,8B,54,4D,AC,D7,F7,0C,F0,FC,DF,AA,DE,A1,CF,2B,48,0A,8A,66,D4,10,70,41,DB,75,45,3B,31,30,1B,DD,12,C2,A5,89,9B,67,FD,76,FD,AA,6B,CC,3F,3D,61,A3,C2,68,32,52,99,6F,F8,F5,73,8B,59,47,0A,42,53,FF,7A,D3,D2,1D,7D,8B,62,E1,11,70,71,18,D1,DA,D3,32,BE,45,34,DB,7D,15,B3,06,9C,4C,55,50,C6,63,72,68,2E,F5,43,28,5B,D6,20,59,61,6B,D8,04,98,C1,8C,6E,1E,22,EE,01,7F,1F,BA,39,10,91,74,2E,66,5C,F5,E2,DA,3F,C6,E7,3E,02,6A,42,95,BA,4D,FA,BE,47,C0,CD,76,2E,D5,4F,8A,CE,4C,2E,A1,FC,71,F8,A2,F4,C2,A2,09,49,B8,84,92,90,7B,13,F2,27,CA,36,93,A3,70,8E,07,04,78,7C,8A,9B,0C,42,28,C5,C0,EF,AC,E6,0F,26,DA,8B,81,84,87,68,0A,9F,D9,F5,30,03,B1,03,26,4D,FC,14,8D,C8,D7,4B,CD,41,B5,B7,0F,F1,8D,21,65,DF,3B,E2,66,D7,42,E0,F8,52,34,58,F2,38,23,AA,A9,2A,F1,6F,9D,14,DD,8D,B3,D9,E2,60,B1,C6,D9,03,1B,EB,F5,54,8F,BA,4E,A7,7B,39,AF,04,D7,C2,9F,F9,B6,21,A0,55,4F,15,5A,F3,7C,E9,D9,33,87,A5,CD,53,D3,3E,77,4E,28,6D,FB,64,59,CC,21,B6,82,DE,C4,64,1A,00,91,8C,33,7E,5D,5A,3D,AE,0C,1D,2E,EB,C8,F4,CD,DE,A1,4B,36,5D,EC,22,BB,36,07,02,6E,46,3E,5A,5F,6E,A0,0A,95,2B,62,71,BC,1E,03,2C,42,F5,46,B6,4E,B7,21,82,4A,BA,B4,CC,D8,22,36,19,D1,CB,71,A5,66,AB,50,7F,55,99,2A,4C,51,2E,82,A7,16,58,03,6D,2D,18,80,08,90,65,89,48,B6,5D,36,BB,4B,EE,6C,80,C1,C9,F3,04,23,D0,BD,15,4E,1C,37,15,20,79,A3,47,7A,80,A4,6C,33,66,D9,81,5B,45,14,80,8F,06,47,DE,6F,CD,CF,40,4E,58,FA,D8,32,C5,0B,CC,69,03,C8,6B,D1,C1,FA,19,0B,FC,B4,16,25,F4,C0,D5,8A,DA,D4,B7,A1,75,9F,F5,FA,42,D2,B2,86,BB,96,4A,F2,3D,C2,7C,43,3B,59,50,2C,25,7B,12,01,3B,F7,65,30,F1,FA,79,90,1A,F4,ED,5D,05,BD,C7,C0,2B,7C,D8,AE,AC,20,05,F5,15,4A,27,9A,13,C2,80,FA,67,A6,1D,71,1B,8E,C6,7C,26,5E,C4,DE,FA,70,E5,AE,50,90,1B,F2,FE,FC,FF,BC,FA,7D,BB,A6,20,DB,8F,70,18,8B,60,5C,E4,73,DD,21,EB,15,5A,23,A3,BF,04,6D,68,0C,04,EC,1A,DB,36,50,C1,86,ED,66,55,2E,31,56,E7,1F,73,B9,8E,6B,77,1B,D5,63,DE,36,1A,35,68,06,42,31,6A,0B,15,32,63,D4,AB,79,46,03,12,47,07,09,7C,35,D7,75,FB,34,68,7F,1F,69,9D,3F,67,DB,45,D5,21,1B,23,BE,15,79,60,C8,72,4E,22,D5,48,D3,6A,6A,13,3C,C5,0C,27,10,2E,D8,D6,C3,46,0F,C0,5F,09,6F,78,94,A4,D0,9E,DF,49,5E,3E,84,FE,D0,8C,13,0F,48,0E,E0,23,20,12,51,3F,0C,FB,24,11,40,00,9F,EB,35,6E,A3,74,0D,13,F8,F6,F0,82,2D,2A,C2,BA,43,96,BB,06,3F,16,BA,03,05,42,CC,27,8A,CD,9E,61,13,F1,58,33,FA,DF,CC,29,2D,5C,B7,36,5A,CA,C1,04,1C,83,B7,98,3F,FF,60,C2,73,0B,B6,09,98,6F,4B,79,15,48,E1,2C,3A,C3,B7,EC,D3,3D,82,F2,7D,FA,E4,05,40,00,75,49,8B,A0,31,90,CD,C3,E0,C6,FB,36,97,0C,E4,B0,43,C8,9D,63,FC,31,96,4B,9B,C2,D5,A9,A9,BE,7B,F3,CD,29,EA,46,AD,29,8C,43,DB,33,71,74,3A,6C,AC,AD,D9,82,51,81,50,B9,6D,69,1C,6D,21,7C,04,9A,E4,0C,3F,DA,AC,0F,C9,FE,7E,8E,F5,F9,F0,1C,A7,83,49,FA,CA,69,43,A5,0C,3C,47,90,7F,14,78,76,D1,69,8B,C1,8E,DA,14,CF,77,3C,2D,1D,81,85,6C,A9,6E,D2,EA,51,6C,10,9C,53,91,C5,CE,BD,37,84,F2,98,BA,50,BF,F9,A0,EC,7F,CC,D4,58,28,CF,82,3D,F2,78,6D,60,4F,A3,56,0B,B5,0B,85,76,78,E0,13,1D,41,29,14,D0,12,D7,23,89,64,C3,EF,71,44,40,41,40,02,79,75,70,BC,49,F8,73,9B,C4,ED,B3,F2,83,22,BB,08,36,EF,70,84,A2,F5,FC,3A,05,B2,73,A8,EC,1E,8C,BD,37,FE,75,86,4D,74,F7,8C,D4,B7,07,E8,DB,AB,08,9C,72,23,F5,B9,CA,75,1E,26,51,DC,C9,2D,3B,97,7A,11,99,72,D8,40,37,0A,49,1C,2B,57,4D,37,78,78,15,7F,AA,FB,7B,B5,7C,4C,7A,03,3E,68,B5,F5,DD,83,47,9F,6C,A9,1D,E5,C1,81,9C,0A,78,74,24,2B,11,6C,9E,8D,47,97,6E,CD,6B,DB,86,32,27,FC,79,CE,2A,39,BC,45,6A,4A,23,70,D1,27,F2,60,DC,C2,20,85,32,ED,C7,31,89,17,8B,C2,53,D8,39,CD,52,6E,6F,3B,9E,B6,E1,3D,92,AC,94,4B,42,09,9E,2B,4E,A1,BE,5E,5C,36,AE,AE,BA,F3,B7,F6,49,F4,63,B6,AD,F2,3B,01,07,15,12,EB,26,2E,CC,36,50,9A,22,CA,E3,FE,92,C9,C7,F2,75,F7,8E,9B,44,CE,3F,87,DB,4F,C3,3C,E5,05,CC,C6,CD,13,74,4D,BA,CC,C2,C1,90,8F,C0,18,07,88,BC,D6,08,8A,1D,6F,E5,69,9E,91,E3,9B,0A,B7,94,65,FB,4D,BD,B4,A5,2E,59,78,78,BB,5B,1B,7C,7B,04,51,8F,AA,C6,6C,E1,BC,01,69,EC,3B,0F,47,C9,E2,FA,7B,02,92,35,EB,49,8D,36,26,6C,40,50,09,75,46,87,B1,0B,38,AB,3E,BD,8C,C8,EB,68,F8,DF,57,19,08,58,A2,D6,7C,3A,04,31,71,06,EC,2A,D7,90,9E,FC,47,75,99,B6,ED,A0,30,7D,22,C4,B1,DB,B9,37,9C,85,59,22,31,F5,31,EB,A1,92,D7,32,B9,00,14,CE,13,D7,6F,08,07,BB,8E,97,57,FE,F6,09,D3,2B,E3,33,31,6F,0E,3E,3F,B8,13,B5,BA,A4,3D,CA,36,71,07,09,DD,20,60,71,29,4D,F2,0B,4B,DF,6D,E8,1A,33,C9,D0,B7,7B,70,AD,33,0B,B4,02,3F,AD,C8,A9,64,B6,37,05,DD,9C,CF,70,A5,5E,C1,2B,52,73,10,AC,DC,1E,CD,36,6A,2F,0B,91,B7,D9,43,70,D4,57,24,DE,61,82,86,8E,75,1E,B4,3E,59,F5,70,C9,88,19,95,2C,55,29,56,ED,C2,49,2A,C7,A9,FE,1B,3D,A7,AA,21,99,3D,EC,BB,DA,DD,99,14,8F,74,B0,8B,FA,E9,56,3F,32,AD,63,47,62,5B,9D,3F,19,C6,0E,6F,4C,20,6D,8D,75,E9,78,C5,37,E9,3F,E7,45,F7,4E,88,8F,E6,42,D9,DC,44,5E,44,C5,8F,C7,B3,BD,0C,F4,20,FB,49,B2,6B,67,6A,18,D3,1B,3A,0B,D3,7A,4A,C2,D6,08,18,08,CD,C1,BD,80,E6,F8,BC,4D,71,88,95,B0,EE,A5,53,B1,A4,15,89,CF,A6,EA,CB,16,D1,42,2E,84,56,1A,D3,86,1C,CF,BA,65,15,CC,D5,D9,3E,B9,7D,D0,43,A5,3A,2C,15,56,CB,41,16,E9,C0,E2,C9,D5,EE,1C,7F,52,35,EF,A9,C9,53,39,82,07,ED,CB,BE,B3,5B,7A,29,FB,0C,15,1D,D0,C5,09,E4,56,AF,EC,B8,2E,9C,85,D9,A8,BB,FC,88,5A,DA,97,9D,ED,C1,E9,23,FF,56,48,C8,A4,02,0E,E2,1F,C8,1A,39,35,2F,2F,60,15,E8,9A,C3,B8,8D,8A,8C,9C,23,6A,7B,5D,5B,1D,D1,5A,4C,33,65,E0,62,51,E5,D3,68,61,05,B3,51,82,08,73,59,FB,20,AA,48,A0,61,E2,3B,5E,17,25,8E,72,9A,51,96,CF,3A,A1,4E,4E,1E,0B,80,F9,68,CA,85,7C,3A,98,C3,04,B2,17,3E,92,C6,AD,A7,C0,5A,25,C9,47,CE,5F,2E,97,C0,A2,54,F4,CC,53,84,56,CD,EA,D1,BC,BA,16,00,34,ED,0A,7B,49,40,E8,53,B9,08,4C,F0,C6,9C,CB,2D,6D,98,1B,84,96,9A,63,C7,3E,85,42,C3,48,32,92,56,70,B7,45,A1,12,90,C6,3C,97,CB,CB,05,FD,32,92,CF,18,85,7F,90,5E,2A,B7,4D,2E,38,37,19,E3,4A,D3,2A,12,55,78,6C,A7,18,C9,BA,55,D3,B0,CD,3D,FD,EE,7B,E0,60,1A,90,0D,4D,01,AD,5E,DC,05,9F,D1,89,B6,B3,6C,FA,03,49,F3,D9,22,40,05,B7,0A,B5,59,32,AB,0C,88,11,27,0E,53,F3,87,2A,FE,07,56,58,A6,F3,AE,58,97,1B,F1,E8,F0,69,7F,DB,8F,16,11,01,7B,C9,96,7D,1A,F5,B3,32,59,7F,99,1A,F1,26,44,2A,27,09,04,9B,0B,BF,EE,F1,52,0A,97,6A,93,7C,6F,88,0A,4F,FE,19,E7,28,4A,30,71,95,24,B2,43,73,3C,53,F5,99,C5,81,32,B6,F2,66,23,27,4A,04,D8,47,BA,C7,C8,C9,3E,76,44,65,65,E4,7F,E0,FC,72,54,64,B6,11,DE,49,69,8B,82,8B,F2,32,10,EB,91,79,79,57,15,BB,32,44,7F,CE,65,CE,EB,5D,66,AA,87,42,A1,04,83,4C,6E,C5,43,69,87,F8,1C,A7,88,5F,16,CD,57,F4,D9,4A,AA,D3,47,1A,C2,DA,F2,7F,5B,8B,9A,1C,F3,B8,FA,91,E7,34,12,03,63,21,C1,73,78,D2,8B,C1,1A,DB,AC,BF,65,30,53,1E,8B,21,56,18,7C,2D,73,29,B0,E8,CF,5A,DA,15,9F,21,0D,90,C0,6F,AE,D5,D6,B6,3E,B6,00,8C,71,FF,7E,0C,8F,FD,32,6E,33,FC,CC,2F,B8,B3,84,7A,18,CB,F1,50,D5,2D,0D,41,11,22,F7,3A,53,5A,7B,18,00,9B,BE,53,57,4D,BA,03,19,95,C2,67,89,67,13,86,75,29,49,2D,7F,37,5D,E4,B8,D5,7A,D5,06,89,CB,4A,1C,E0,CC,99,15,B9,71,85,33,53,CC,7F,FB,15,48,45,94,AC,75,FC,BE,70,7E,28,39,CB,B4,EB,4F,6F,6E,96,DB,10,49,D8,48,21,68,F3,8A,18,0F,4C,91,D6,23,4E,B8,1A,DD,02,5D,F4,2C,18,9A,E1,AD,E3,88,D3,DE,8C,7B,CC,DF,4C,A1,3A,15,36,FB,1C,58,AD,8F,75,65,0D,A7,E3,19,BE,5B,01,77,A3,D9,26,81,96,A1,3C,63,B5,C8,52,9E,24,05,CA,ED,7F,97,F5,D9,CF,CD,6A,D2,F2,79,50,D2,79,84,DB,63,CB,52,CE,B7,04,80,57,6A,CF,D8,D9,36,54,E6,37,E4,09,2C,94,6C,FD,C6,89,C1,F8,D9,3A,BD,DE,C6,41,4A,62,92,EA,07,A0,7E,06,61,46,5A,B2,E4,C6,A6,2B,C0,A1,D4,27,F0,4D,06,62,97,34,67,6E,A5,FB,08,9C,7C,92,79,7D,9C,C6,A1,F1,F0,2C,78,35,5D,B0,3B,91,0C,27,3B,2B,49,2F,9B,A0,36,6D,EE,15,3D,64,E0,5A,BA,81,F4,E1,16,30,34,18,9E,68,22,EB,BA,31,D0,0B,38,24,4F,2F,2E,07,A7,90,3B,6B,B5,9D,72,36,B5,9C,C5,96,9C,02,E5,5C,4E,5F,6D,93,BA,3D,5F,2F,3D,AE,B2,41,25,2F,A0,52,5F,F7,71,43,E7,E8,32,FC,3D,3F,8A,CA,7F,57,C1,9A,DA,02,42,05,4E,0C,28,05,AD,B0,A1,28,1C,73,4C,33,0F,FA,07,E3,93,6D,14,22,56,12,1D,8D,F7,41,1F,FF,3C,89,95,93,FB,76,7B,47,16,E6,D7,C8,A5,03,EA,03,E4,2C,9F,03,84,0D,87,D3,00,46,77,06,4A,84,61,3D,50,24,D5,B3,C8,47,3B,8B,32,32,3A,3C,8E,0F,50,43,B9,64,53,92,64,4C,CE,10,EA,50,DE,8A,96,37,92,87,2F,36,EA,44,D7,BF,3F,67,84,1A,F7,DF,D9,D8,C2,63,FB,34,FC,CF,E1,6C,05,D0,3A,4A,3F,71,D6,0F,6B,DE,6D,DE,FE,6F,8F,64,F2,5E,06,5E,0D,D1,E5,BE,8C,D9,7A,B8,11,67,A4,22,8C,36,A6,42,7B,06,EA,F7,95,C4,71,39,7C,78,AE,D1,C4,41,85,8F,96,DE,A5,43,E9,8E,C2,79,EC,B3,E0,89,10,23,89,32,6C,63,6B,23,A6,7F,0B,B1,C8,77,99,4A,ED,5B,64,5F,1D,A7,28,99,AE,B8,09,AE,49,F6,EA,2F,F5,A6,BE,A1,77,7F,39,6B,C0,A3,42,BE,2F,FF,44,D2,12,25,35,ED,F4,FF,79,3D,C5,D4,64,61,AA,58,BC,32,C1,45,E0,8E,F7,76,2A,0B,4C,89,3D,0C,92,80,9A,78,88,94,70,EE,B4,CE,E4,59,C2,7E,1B,81,8B,E0,8E,C1,FF,1F,EF,83,6C,11,52,56,54,8D,09,D1,93,37,05,C3,54,7F,B5,94,E6,DF,83,BE,21,DB,A4,93,D3,11,E1,EA,0E,DF,12,8A,8D,DD,CB,8A,B6,7F,6E,F7,55,7F,ED,17,23,61,30,20,09,72,D7,54,D1,CB,68,63,61,BA,98,64,45,52,72,3B,10,BD,13,5B,63,10,93,21,73,52,F9,6D,5D,AE,BC,7F,0E,21,EB,7E,4D,F0,BC,33,1A,6A,C4,D0,4D,F0,6C,CF,E5,74,37,C8,FE,44,ED,ED,B0,90,94,62,AC,3B,7D,79,09,12,D7,8B,8E,AD,6D,50,F7,1E,44,74,A6,B3,A4,E6,F0,E5,C4,33,6B,98,98,FE,DF,ED,11,43,ED,D3,39,8B,35,AA,51,59,F3,D5,3F,50,22,65,4A,FB,9D,18,5F,65,3E,D3,27,5C,B6,B9,33,2E,AE,B9,AC,0A,C5,77,5F,F6,51,98,1B,8F,B6,4C,01,C8,C0,2B,82,E9,5F,35,7D,A5,E0,89,79,87,0C,42,FB,55,7B,50,CE,EF,B8,EE,D0,38,21,E1,C8,D1,80,13,B4,93,68,C7,B2,91,C4,30,87,41,6A,27,3A,18,A4,2F,AC,3C,E2,7E,51,35,EE,DB,D6,F1,1E,F7,0F,0E,6E,C8,9A,21,AC,81,60,12,36,1A,04,BD,CD,3F,20,1D,8D,1B,9A,3C,30,3E,79,0B,F5,92,38,F0,F6,67,E8,57,85,F3,B8,42,DD,AE,D8,CE,80,20,5A,39,55,FD,B2,65,D8,DB,22,F6,0C,AC,1C,9F,28,59,5C,6A,0F,3D,FC,06,15,2B,CC,48,6C,AF,C8,76,1E,39,83,63,2D,49,04,06,A9,D3,59,AD,83,85,F0,53,BF,D5,FD,5B,F2,8B,E1,0C,BC,D9,55,5D,5C,8F,96,33,45,DD,FC,92,07,F7,FD,A4,0D,15,32,DB,60,D0,A8,55,05,B7,89,1E,E0,E7,2E,5C,B2,CA,9D,50,C9,49,8D,1B,BD,17,48,EB,6C,3D,ED,09,A4,42,38,E1,6B,9B,68,2B,A8,4C,B1,CE,2A,46,94,27,51,29,4F,34,53,1A,17,46,CE,7D,9A,B9,1B,49,1E,51,4B,24,53,DF,FC,71,0E,D4,6D,26,DB,29,8B,0D,4C,E8,19,35,90,5A,01,3E,DF,2A,B8,9C,4C,20,F4,1D,FA,FB,B0,D0,B8,E5,92,14,21,15,E9,D1,73,13,CA,BB,3E,F6,F5,0F,56,8B,81,32,65,D1,87,57,30,A3,F0,46,DF,86,4B,21,9B,E4,FC,62,BA,CC,55,A4,72,D3,2B,78,00,E1,A3,EE,63,B3,0E,92,93,3E,E2,40,C8,41,6A,F3,9A,0C,81,69,DB,FB,EB,BA,E7,FD,24,EB,0C,8C,9B,DD,92,8C,8F,95,7C,18,9B,72,08,4C,C1,B5,0E,DB,2D,B8,EB,7A,8A,EC,77,CE,36,2E,D8,2A,57,BA,FE,52,AA,EE,05,FD,61,03,CF,3B,1B,B7,8F,46,64,7C,18,E3,76,18,C4,44,A8,2C,6C,82,31,16,8C,CA,CB,7D,89,2C,CC,3A,4D,AF,48,6F,F2,2D,5F,3D,7E,FF,08,9D,CD,CE,06,86,FD,42,A7,B7,27,B6,FC,F4,C3,DA,51,87,83,E1,D7,74,C9,DD,62,C6,9C,8F,9B,46,FE,11,05,E1,EE,07,BD,30,FD,E2,03,71,D9,21,11,AF,0F,3C,CD,B7,E0,E3,DE,A9,C6,58,A2,B1,3D,85,32,0B,9E,BE,BB,F7,9E,FB,0F,E7,36,C8,77,74,45,73,D2,83,52,05,44,3F,30,11,78,22,01,0D,7D,6D,48,B2,6F,15,8A,86,60,CA,66,A8,F8,0F,96,EB,D5,19,2F,27,91,A2,23,CB,34,06,7B,EE,8F,FF,1E,F9,C1,81,4C,93,42,EB,AB,88,A5,81,3D,15,4C,42,AE,13,AC,25,44,57,0B,9D,95,0A,5E,4F,66,17,34,97,DE,E9,9A,4B,F1,95,C4,75,FC,AB,1C,9E,27,4F,6B,4D,47,12,A3,C3,9B,2C,5E,80,6B,A3,CF,58,5B,3D,91,68,94,C0,92,07,FD,4D,7D,3C,6F,03,A3,FF,43,64,2D,8D,94,1F,F7,FD,C6,E7,27,69,81,CC,DB,3E,33,E6,1C,9E,EB,E0,0A,E5,89,31,0D,BE,85,9D,27,AB,BD,5E,B5,46,95,A9,50,E6,E6,DD,92,4F,9B,B2,F7,72,EC,CC,AF,96,85,D8,89,1B,0B,29,01,90,77,07,E9,E1,9F,DC,42,01,31,8F,A5,32,6A,44,6D,DA,FD,00,DA,6F,CD,C1,9F,7D,57,39,95,EC,CF,D6,85,66,B1,DA,93,14,19,9B,00,3B,BF,78,7B,64,DA,69,C7,2E,3C,62,29,96,B6,54,04,04,C5,8E,C3,36,52,75,C4,8A,FF,59,6A,84,7E,F4,0E,70,DF,2F,A0,E5,27,5B,F1,CF,BD,A1,F1,0B,0A,86,2C,41,04,CD,83,6C,4C,7A,C7,40,A3,10,49,5B,8D,CA,81,88,E5,06,0C,C9,74,B4,13,BE,7A,1F,03,B8,06,57,E4,4B,72,52,7A,FC,4F,A7,CF,55,A9,AF,84,51,AB,BF,AD,4B,58,36,E6,5E,31,F1,65,BA,9A,B0,A3,A8,8A,61,87,6A,2D,89,A4,BD,4C,EB,8D,55,5C,B6,7C,26,4A,17,36,BF,50,9A,9E,38,DC,07,71,34,7D,9F,29,61,61,D7,E0,78,3F,2F,83,F5,B1,3E,D0,C7,83,D5,F0,97,DB,BE,9D,C4,12,39,CF,B6,5C,A0,22,C0,BF,28,A6,F8,33,55,40,61,C6,AE,B6,07,98,F9,41,A8,12,DA,73,9C,BA,AF,AE,D6,74,19,80,0D,5B,6E,28,4C,2A,B9,5F,CF,F1,D2,48,FB,AD,21,5D,5E,ED,34,5E,07,DB,1D,D6,D8,06,EB,D6,DB,CC,80,0B,89,DE,79,A4,BB,54,F8,34,5F,0E,2B,09,84,A3,A6,21,52,0C,83,6D,E0,3D,0B,C3,6C,EA,A7,54,EB,CC,2E,AF,0B,AD,31,02,5E,CC,9A,BF,72,74,1D,EB,A4,66,56,42,24,D8,89,88,FB,97,BD,3F,BE,60,BC,86,AB,9E,A6,09,95,73,E5,FC,2E,A3,5E,86,D3,AC,47,24,4A,FA,81,3C,13,04,AA,FC,6B,DC,3D,6C,5B,12,90,80,E9,36,8B,20,38,DD,17,69,D8,45,9D,38,C7,A0,A5,0A,31,0B,AD,F6,59,CA,72,14,34,D3,A0,F2,34,5C,DC,16,D8,CC,A4,D8,B9,B1,94,66,F7,AA,36,15,ED,29,38,4D,42,E7,A3,A2,0E,09,A0,C4,F3,AF,17,29,09,DC,A0,F2,2E,D1,A3,6E,38,11,50,2D,FF,14,BF,04,CE,3D,06,73,F2,09,1C,60,27,37,8A,6A,E6,C1,B8,3E,40,14,69,9C,C1,FD,AD,38,A7,1D,FF,E6,CC,FD,47,D4,30,22,60,CA,48,D8,0F,76,64,BF,BB,87,AB,C8,49,FA,49,AC,6F,48,8C,C6,51,E4,9C,5A,21,F6,73,54,DF,A2,92,50,2C,99,3E,F1,35,8E,83,06,28,0D,D6,85,2E,A0,7C,F0,1A,7F,32,D0,77,3A,47,5B,C4,E0,F8,D4,D6,A6,03,90,30,D2,7E,22,D3,70,65,B2,DC,A7,B5,57,E4,EF,8D,A6,07,D3,A6,A7,13,98,CB,FE,85,7F,0C,94,22,69,C0,8A,09,3A,AB,B5,B9,5A,9D,CA,24,8B,B0,90,36,4E,CF,8A,3E,5B,52,38,47,2A,C7,66,AA,F6,88,93,86,63,DA,5D,9C,B5,8C,09,EA,85,E1,DE,89,A5,5F,FB,50,EC,F8,90,51,3A,CB,2D,49,05,98,55,8E,BF,69,2C,F1,A1,3A,1D,4D,B6,09,90,97,E3,E3,BE,E1,CD,F6,5D,AB,19,22,4B,63,F0,C2,87,41,0A,64,2A,C7,90,F5,9D,48,75,FE,15,17,33,F9,68,51,B7,2F,71,59,0C,D9,0A,19,B5,3C,FB,4D,49,6D,32,0C,F6,79,CE,B4,77,A1,6D,46,F2,4A,91,41,C0,E9,B3,3E,C5,4F,5D,97,D3,65,BF,EE,DB,6E,27,67,26,0B,E7,C6,BC,C4,95,23,CE,68,65,4E,AD,49,7C,A3,50,12,A6,67,ED,2A,DC,0A,02,54,39,6A,9C,BA,76,D0,6A,BF,70,4E,E7,E3,5D,26,D3,51,DA,33,25,5B,1C,48,AC,04,75,1E,EC,3C,74,26,0E,86,A8,FA,81,44,01,50,C6,1D,AD,1F,97,6D,71,7E,78,2F,6D,24,F2,62,45,BB,CA,E1,CD,99,4C,36,CB,62,A0,1F,25,03,99,E8,65,32,EA,A0,80,3F,53,E6,EF,75,85,15,C6,C3,58,AC,41,31,FF,83,77,F5,00,5D,E4,17,EA,3D,3E,19,18,C7,8E,26,97,A8,FB,73,9A,EF,3F,0D,B7,79,9B,35,EB,4A,5C,04,61,6D,FE,74,18,FB,F3,81,82,1D,54,23,7B,E7,2A,1C,AB,17,76,04,E4,BA,D3,46,66,D8,F2,2A,CC,82,56,70,6D,D5,CA,59,94,1D,B8,36,D8,8B,64,4F,7B,0A,96,06,16,F7,3F,6B,FE,25,06,D0,4A,A8,E4,0A,AB,85,AF,6D,39,A8,03,D3,95,2C,95,30,8B,0A,15,23,0C,FE,49,9D,92,41,9C,69,EC,CE,CA,EC,A1,32,5B,60,E8,D6,31,24,C8,66,D7,A0,70,3C,1A,2D,91,7B,7E,F9,82,15,1F,F3,7F,D8,D2,6B,F6,DD,54,3C,AE,E2,39,F6,DB,7F,0C,B2,9A,F9,5C,50,8A,54,A4,D9,E9,DB,DF,81,5E,5F,3F,68,1B,C5,AA,23,E8,B9,6A,F8,54,8D,50,95,91,92,12,01,6E,3E,3D,5E,D0,54,97,F6,B6,62,67,CC,49,4A,D3,9E,8A,CD,71,C6,E3,B7,A9,21,4F,73,05,6D,F5,26,71,4B,66,FA,C3,72,1A,E6,4F,C4,25,31,7B,FD,90,57,1B,21,DA,A7,24,06,40,8B,94,87,7A,66,E8,41,9E,A4,3E,DB,B7,3C,EA,F7,CB,CB,0A,9A,D4,6B,02,A3,72,8D,05,78,BE,85,54,47,C5,04,66,77,3A,2A,3A,7E,EC,CF,E7,40,83,E8,27,68,10,17,33,4D,3C,56,5B,42,D0,B7,96,02,1C,B3,7F,36,D5,12,A5,69,23,65,74,B6,98,94,13,1B,94,8D,DA,96,0B,C9,1B,6E,AC,0D,D5,FD,FF,7A,B6,C5,17,66,12,29,6A,74,BE,59,F7,12,02,FF,25,10,00,75,91,90,10,F3,2C,19,9F,78,A4,B2,0F,E8,1C,8F,08,19,85,C4,CF,C3,8D,E2,6F,F3,17,94,0F,5B,2F,43,AA,A9,8E,20,0B,C6,BD,13,A5,40,EE,CA,A3,05,29,63,B9,D9,92,81,F0,57,85,C3,85,E7,61,EF,C3,17,BE,34,F3,11,DF,E7,F4,65,2E,24,C8,8B,96,B4,57,AD,92,BA,F2,8F,71,D5,FF,5E,5B,CF,6F,21,CC,C0,44,C9,8F,84,49,63,91,FF,56,84,57,58,07,35,D0,4F,A2,FB,C9,EE,96,19,2D,98,38,43,B2,79,17,A4,C8,18,6E,31,F0,41,E9,96,8D,3F,FD,CF,B5,8A,18,B4,F8,6E,F4,46,AE,CA,7E,64,1F,24,0D,62,7B,2D,B6,24,29,1E,E1,C9,5B,1C,70,52,96,49,D2,6C,B6,BF,EE,6A,56,AA,0F,F6,C9,19,4E,E9,EC,37,83,F1,97,D1,A1,BB,52,23,A1,73,16,04,E6,7F,1E,82,14,3C,26,64,C9,C4,21,B4,9D,63,48,2D,C0,F3,A9,46,30,D3,83,0D,8B,24,BD,A9,5E,DA,1F,04,D5,6D,14,6D,55,CD,F0,AF,E7,08,78,9A,F7,31,4E,B5,15,8F,A8,5F,15,00,CC,CD,F7,8C,0F,40,D7,CA,2A,12,83,FC,EC,B2,AC,F4,32,7F,05,55,A0,E0,35,C4,7D,A0,39,82,1B,54,B4,6F,70,BE,13,3A,E6,B7,47,DD,AB,64,86,73,FA,70,43,E1,E9,2C,FF,5C,88,B5,36,A6,71,17,59,B1,9F,A2,17,CD,FD,88,2D,07,8E,DB,23,5E,12,ED,1A,6B,CD,01,F9,1B,F0,D3,69,76,36,37,C5,55,63,ED,26,50,CD,ED,15,71,D7,E6,2C,CB,A0,43,7D,51,6D,12,6B,F3,6E,2D,83,14,B2,4C,39,12,04,37,2E,9B,C6,3E,28,5D,D4,D5,CC,DD,BB,A7,33,D0,99,4B,AC,53,65,76,A7,A3,93,A7,97,03,42,3A,58,3C,31,0F,5F,CD,B7,D0,9D,79,C2,0E,A3,33,0B,BB,40,EE,7F,C0,11,6A,C3,4A,32,70,FE,C1,E0,65,00,DE,E5,F3,51,3E,0A,4C,7B,E6,37,B0,F3,04,F7,16,34,38,90,76,87,28,98,98,FE,EE,67,79,C3,5B,7A,FC,60,83,F9,D7,2E,BD,65,7C,86,8E,57,6C,08,8E,16,32,07,6F,7E,75,5C,2C,08,8B,04,28,58,66,D4,15,F6,0C,23,F2,8E,2D,CD,46,10,D1,03,60,80,61,42,54,BA,4D,48,06,74,CB,42,E8,F6,63,7A,4A,52,88,14,01,BF,4E,74,AD,DE,EF,F6,E6,38,AA,74,7D,94,E8,90,35,8B,52,D8,08,13,8C,59,8C,70,84,D7,E4,A9,8E,8A,D2,9C,38,86,C3,A6,6B,26,18,98,88,E9,82,B0,DD,64,1E,EE,82,DE,C1,B6,D0,22,57,4C,F2,50,D2,91,4E,7D,25,39,29,7D,DC,31,7D,66,07,61,14,76,D6,66,70,3C,01,18,33,07,66,AE,9A,C4,33,56,12,79,10,B3,94,25,DC,05,DC,C2,1F,77,B7,B0,39,7D,F2,89,0B,E4,03,DE,FC,9F,41,01,BF,03,38,17,A5,47,4B,6D,76,FE,5F,FF,78,9B,8C,F7,52,2B,9C,80,6B,11,34,C8,AC,D2,6F,BE,17,57,8B,B5,54,81,00,1A,DE,7A,31,79,9C,14,78,CE,12,8F,DD,5C,40,EF,C9,ED,34,4A,D6,97,BF,09,AF,07,D8,22,FA,31,5B,13,80,ED,12,C5,FD,07,12,7D,C2,8C,19,E9,3A,22,DA,29,67,67,F7,E9,A8,DF,51,21,84,13,AB,BF,B6,EA,24,ED,D7,41,0F,0C,75,19,4E,4E,B4,E7,BC,E1,3D,27,CC,5D,D8,9B,F7,4A,5D,FD,7B,69,C5,30,A8,59,44,A9,DC,E7,6E,9B,A4,DB,3F,21,0E,8B,C0,27,44,7F,C8,32,70,1F,94,E4,80,7F,C8,8E,3D,3C,E7,D2,CC,73,87,D8,78,CE,FD,7C,96,CD,FA,E1,C1,CD,58,7D,A5,B9,88,23,A1,2D,CA,40,47,37,5E,07,1C,C5,60,32,CA,5D,83,AC,81,E0,92,77,6F,E8,50,33,99,89,2C,DE,1E,93,46,96,20,9E,36,B3,D1,5E,3D,12,AC,01,E2,2E,3E,74,FB,7C,F5,D6,2E,B3,49,4A,71,6A,3A,0F,94,AD,0F,38,A2,0E,74,0F,CC,8A,16,74,96,F7,01,F3,B4,C4,9E,DB,5F,4F,89,4A,28,D4,86,13,71,42,86,42,12,31,AF,99,6E,48,D1,54,AD,FE,A5,24,73,BE,75,57,DB,54,D6,75,F4,3E,96,B0,F4,E1,93,0A,EF,FB,2E,BA,B0,46,B0,EB,7A,6A,39,FF,9C,EE,E8,43,3E,76,E7,45,67,C3,19,E3,0E,32,4B,B2,44,8D,C0,71,56,00,7D,86,98,B5,A0,47,CA,52,4A,3D,F8,CB,B8,8A,C4,BC,AD,5B,4A,13,F5,20,FF,61,8B,74,5A,E0,93,8C,B1,30,B9,A5,17,52,A0,60,8B,22,F6,25,3D,C6,B6,82,56,E7,48,28,95,DA,B4,EE,9C,48,48,08,F8,0F,E1,DE,48,32,ED,83,BC,DB,E0,3B,DE,B4,A5,C0,92,70,5C,03,68,22,EA,6F,8A,26,9D,E3,01,AA,65,C2,34,36,0A,23,B3,D6,76,53,26,07,C6,96,2D,89,EF,BC,37,A9,74,81,23,4B,C8,E0,CC,F7,95,CB,CF,3E,FE,2E,31,08,49,2A,37,19,4B,FE,7D,E8,78,05,A1,97,32,CA,09,A3,0E,C9,26,A7,B2,9B,61,01,90,A5,A5,44,A1,38,07,62,1F,02,FC,C5,E6,46,EA,27,39,1A,1A,83,1D,EE,B3,02,94,66,E2,30,D9,9F,C9,27,BF,8C,24,90,C3,43,CD,F1,AD,56,21,8C,35,18,BC,27,B4,07,57,0D,EC,AE,22,CB,BA,EB,50,8F,0F,5A,88,41,48,C1,9C,32,99,09,15,22,2E,E6,C6,30,37,CC,EB,3F,48,52,3C,AD,F5,91,EA,A2,81,FF,60,B4,AB,C2,CE,A8,9E,22,69,99,95,5F,9E,C0,F9,A4,08,DD,D5,C4,EA,83,9E,B4,D8,57,0B,1C,66,1B,52,38,DB,58,70,C3,39,E5,D5,53,AD,D0,2D,27,5F,B6,BE,41,AA,44,F0,01,D1,70,76,FC,7C,F2,00,06,B0,8B,24,AC,B3,6A,8B,E6,57,4E,3E,8F,6A,9D,D3,42,87,67,A0,29,70,18,BE,67,CF,A1,01,E0,EB,6E,3A,8B,48,A5,5F,B9,DE,33,92,09,16,2A,E0,A0,10,9E,16,39,D4,6B,EF,DF,BE,00,45,C2,55,B2,81,44,23,D7,5A,1E,9E,D0,7A,28,98,15,92,13,97,B6,E2,7B,35,E4,77,F7,65,27,69,C3,90,2C,47,02,13,28,B6,4E,EF,AB,69,FD,EC,C0,C7,F1,01,00,D2,34,D2,84,A3,E5,95,2C,97,FE,24,48,38,44,17,27,64,E8,E4,03,88,E5,6D,95,09,14,58,9E,99,9A,B2,9D,1F,7E,C4,D1,EB,4C,9B,9E,0A,4E,EB,88,09,93,86,84,EE,8A,6B,E1,81,DE,98,7E,86,0E,FC,CB,2F,CF,02,FC,C6,60,93,FD,E4,2A,83,19,1D,51,03,22,96,4C,8F,EC,92,17,6F,11,F4,7A,4F,80,FD,05,14,DB,C5,29,69,C4,75,B4,2A,6D,D5,79,D4,E2,48,59,A7,18,47,BE,45,4A,B3,DB,8C,41,CB,E9,33,E8,E1,0E,4F,72,AE,EB,50,F0,31,FE,F0,5D,1C,59,F1,AE,80,1E,2D,2A,79,A6,B9,7C,8D,92,CA,91,4A,FB,2E,DD,6E,E3,8E,51,C3,B5,E6,A9,C3,28,A8,E4,DE,37,AA,81,5C,1C,BD,FF,DF,70,EC,19,D2,28,76,1E,E8,58,3E,FD,C4,10,5C,B1,3F,3A,69,D0,FB,3D,28,93,DC,B5,77,FF,93,23,C8,63,7C,2E,E6,73,90,64,E4,1B,38,4D,BD,74,0E,8F,75,F6,48,75,AC,55,A1,27,60,0B,F9,15,C0,38,8D,02,CD,C0,04,B1,88,27,AC,26,7C,A4,BD,61,C0,EE,5F,B5,13,8D,C7,16,41,96,54,1C,2E,09,38,08,4B,66,7A,E5,6A,06,02,DE,2E,71,76,13,11,19,69,A0,D3,3D,B0,5A,82,FB,1D,E3,2C,96,65,0F,0F,AF,B7,FD,09,08,81,8E,50,34,EF,D5,C4,9E,6B,75,91,4D,4C,4A,37,79,5D,3C,66,80,79,5A,9C,2C,D2,BA,F5,4F,AF,9B,67,44,49,E2,BB,3B,5F,FA,67,F1,DF,92,DE,BE,87,9E,B4,54,DB,F3,BC,22,3F,0D,26,4D,33,C7,B0,50,5E,5D,E6,79,15,B7,CC,8E,C6,83,B2,FB,AA,6A,0B,1F,DF,8B,7D,C4,A0,D2,5B,72,C3,A9,D0,60,7C,55,02,D1,35,A6,27,AB,B5,F6,94,43,3A,F7,37,C1,F3,D2,3E,9B,29,39,EC,1F,6D,08,C7,7E,AC,A1,D2,3E,A6,6D,28,85,09,C0,E1,A7,C7,9B,2A,19,D0,EB,5C,35,3B,54,44,8E,35,D7,DB,6D,93,EC,52,52,40,C4,48,B1,0F,E7,DA,95,52,F7,05,99,7E,5F,C2,BC,CB,24,E6,AB,4D,F5,8C,66,A0,83,EB,4B,37,07,C8,0C,7E,C9,8E,37,0B,E8,36,94,F2,7B,FC,61,C9,5B,19,58,BF,86,A4,D6,94,9B,DB,34,BD,4A,F8,FA,CF,73,5F,F8,2D,45,8C,EE,7A,97,20,C4,3F,D9,CC,85,BA,94,72,6D,65,BC,65,AE,AA,1E,E0,D4,F9,AC,20,1A,99,A3,80,83,4E,07,25,C4,CA,A2,9E,14,DC,A4,FE,60,83,E4,4E,ED,CF,48,5C,69,0D,CE,3E,37,4B,24,EA,B6,37,5E,75,0C,B1,8F,68,3E,47,0B,A4,54,DF,76,C7,E5,F8,A0,B4,60,7B,27,F7,6A,7B,04,5D,15,DC,4F,69,F7,5F,BB,7E,F2,74,FB,3B,63,65,E7,1B,67,0C,84,AC,D5,87,9B,86,C2,F2,DE,83,C1,09,27,EC,12,CE,D1,E4,9E,F7,27,A0,AD,4C,05,78,FD,B8,10,7F,0F,58,68,1B,66,1D,30,15,D9,ED,55,FE,6B,D2,9B,77,5F,26,76,72,3D,9C,BD,86,68,EE,2B,92,20,5F,AE,3E,DD,06,CD,59,E5,C5,E8,26,D7,79,07,C9,EE,B5,E2,4A,91,21,49,CF,2F,D3,AC,16,96,7E,68,90,41,E8,AE,27,3B,4F,13,60,53,91,5B,CC,21,D9,17,00,37,66,58,DD,1A,4D,A9,A8,50,A4,72,67,E5,B8,CC,DF,A3,2D,98,56,D0,6A,7B,6D,75,65,FC,BD,4C,40,2C,E6,AA,EB,C5,ED,8D,54,A7,CD,04,BC,85,7B,DB,47,6A,1D,0F,B7,6A,A3,36,81,EC,6D,79,92,89,3E,49,5D,B7,4B,D9,C0,E4,32,E1,29,1A,F0,C3,2D,CB,26,A3,23,58,8E,BB,A1,A0,BD,3A,99,92,1F,A2,D4,2A,90,BB,F7,4D,4A,94,0D,E5,AD,FC,88,E0,30,25,0A,A0,31,0B,1E,09,58,60,02,57,F3,7A,5D,E9,9B,80,2F,F4,94,DA,C7,6F,74,DE,32,6A,31,01,B9,4E,58,86,92,7C,A1,C2,ED,AC,D0,C3,DA,68,83,E4,23,2A,43,E4,94,F5,20,58,90,79,E9,11,46,6B,A5,6A,1A,7D,F1,4C,F0,A3,DF,7A,8E,61,08,CC,0D,C0,85,20,04,5F,CA,C8,4C,E1,6C,2D,FC,D7,A3,13,CC,D6,B9,A5,39,ED,6C,83,54,FC,B7,05,1D,16,48,E9,E8,07,31,F4,B4,27,D8,21,4E,0E,7D,BB,1C,D5,A0,99,C1,D4,1E,D9,AF,13,7E,70,B5,83,26,A7,D7,FE,5B,F7,15,7F,6B,37,25,11,6C,96,EC,34,95,7F,26,61,B5,5D,62,41,94,AB,B3,5B,04,53,A1,27,40,01,B2,47,7A,F0,F2,F7,0C,5E,72,3A,B2,3C,3B,56,75,25,FB,72,97,C8,1D,0F,6A,0F,70,CB,67,34,D9,A5,F2,43,44,94,F4,4E,12,BD,D0,F3,4B,8F,E2,67,E5,E3,BE,49,40,72,7F,A8,A2,19,78,C4,D8,1C,B5,B2,CD,50,60,87,F9,2B,79,7C,8C,95,64,B8,2B,BE,45,B6,FA,D0,F6,7B,A5,A9,2A,AA,F1,E3,CF,26,11,64,EF,B2,59,45,F5,8B,46,A4,21,34,F0,1E,D1,35,4B,B8,60,BF,06,F1,45,CF,31,FC,A2,14,35,46,A9,42,DC,88,05,A2,54,2A,98,9B,03,11,62,6A,57,6A,54,FF,78,31,2F,36,A9,08,8B,11,DF,8E,FA,0B,D2,18,34,9E,C6,49,7A,B1,93,DF,69,10,F4,C1,D7,8C,5B,CE,65,CF,B3,49,56,7B,BC,BE,D9,5A,B0,09,02,38,AD,EC,16,4B,91,DD,27,07,25,BE,1F,56,1E,E0,2B,92,75,FD,D0,A3,30,9E,21,8E,29,C1,4B,C4,96,C0,79,0E,D0,CE,E6,9E,D9,5E,B1,76,8E,4C,5F,C1,4B,FD,C6,D6,96,1B,8E,28,17,1F,77,01,7E,3C,9A,7B,75,D4,AA,E8,C7,B3,EB,35,98,3A,DA,35,43,B9,E0,63,B5,83,1C,43,96,0B,92,64,CA,1C,86,0B,D3,05,3B,30,0F,06,A5,D7,DE,1E,4C,19,FD,6D,F4,34,DA,49,C2,E5,62,2D,B0,68,C6,47,EB,F6,DF,A4,1D,A6,37,A0,B9,4B,66,C0,DA,A0,CD,EB,AA,85,4E,BF,83,24,D9,19,7D,0B,1F,33,B4,E2,5A,56,AF,56,02,B4,C9,2F,6E,7C,04,4D,D4,49,C3,1D,11,0F,FF,3A,13,C1,EB,5D,74,57,7F,5A,92,2C,D8,0D,17,21,41,96,4F,74,A9,26,CF,BA,F9,94,25,CA,B6,99,FE,A5,25,67,A0,11,8A,14,10,15,9C,43,32,FF,32,C7,68,6F,0A,85,F6,0E,31,72,B1,E7,9C,30,D3,10,4E,45,84,35,54,20,ED,9A,0E,EC,B3,60,72,01,02,EA,87,13,F8,C8,7F,9F,B1,95,BE,F4,14,72,4A,61,28,85,D5,07,A0,13,1D,3E,28,5D,CE,05,EF,6D,F4,7D,F8,B2,86,93,20,12,5F,3A,D0,90,31,A1,2B,EA,0E,EF,66,FD,4D,86,89,DC,4A,91,B8,F4,32,36,41,B9,63,56,F8,11,41,74,A2,E6,31,CF,25,96,20,A7,45,E6,3E,2A,39,53,6D,02,66,BF,F0,89,17,94,BA,20,DF,19,60,CD,6B,99,2E,E0,E4,A3,47,33,BE,95,D4,E7,DA,2B,81,3B,8D,F1,FF,7D,F8,30,E1,78,06,4F,5F,12,50,60,F1,DC,C4,6F,AD,AD,F8,EF,E1,7A,FC,D7,D9,0A,10,B2,3E,85,DB,14,B5,59,AF,A5,42,69,7A,53,23,6F,46,65,0D,D3,7E,7B,B3,F8,E9,2A,87,6A,A0,70,77,71,78,E4,7D,BB,4B,52,05,B4,EF,46,F9,48,FC,A7,2F,E2,53,8B,F6,E1,E1,51,C0,A6,20,D9,8B,74,B0,2C,7E,9F,87,90,EE,45,79,DE,5B,A1,F6,85,33,81,0A,F3,B9,3F,FD,6D,D9,35,CB,5D,66,1F,62,58,1E,0B,2A,85,66,FC,93,2E,8D,72,C7,0A,C6,42,FA,05,85,61,F9,79,9A,54,88,73,55,73,9D,6C,78,D9,5F,EE,2A,A1,A4,D1,0A,7E,28,14,97,CB,BB,39,D3,A4,B4,98,57,FC,F9,68,27,73,C1,9A,05,7D,D9,3E,0A,8E,25,94,7C,EE,E2,1E,14,23,28,C1,FB,E7,8A,03,E1,01,44,49,3B,02,9D,D4,C7,DC,B9,C2,43,31,20,80,9C,B8,46,2B,2D,24,B5,AB,52,B8,08,CE,CC,FA,DC,D6,45,EA,F5,A6,F4,7A,B4,11,7E,FB,E4,05,41,6A,C6,D2,40,DB,16,49,08,C1,44,80,4C,21,88,C7,9F,FA,77,A0,B7,71,61,E1,D6,E6,A5,5F,E2,A8,85,2F,E5,2E,45,17,D9,CA,74,4F,AF,FF,7A,58,9D,CE,90,BB,C8,22,0D,B6,81,04,19,F9,24,5E,20,EB,BB,62,67,37,5A,62,C6,15,60,D1,2F,05,2F,62,00,9C,55,E0,87,03,DD,7A,9D,F5,36,F9,AB,3A,59,0F,A9,0E,E9,58,FA,0C,D4,90,23,52,21,39,D0,99,10,32,12,93,73,7C,20,10,02,46,B2,4A,FE,52,57,87,1C,64,07,4B,B9,7F,33,F4,88,01,B2,2B,92,E1,A4,9F,68,18,2B,D0,F3,50,E3,E1,94,FD,4B,65,8C,EB,F0,12,A8,5A,C4,58,67,4D,63,11,B6,75,BF,0B,2A,32,4D,C7,76,BE,03,5B,D0,75,BE,91,A8,BD,39,48,AF,4D,59,DD,57,55,FC,9E,3F,A5,75,6C,5D,49,43,0A,E3,CA,73,AD,BD,58,77,8A,78,9F,2D,02,12,79,C5,96,5D,7B,3C,4E,F9,3C,A3,FB,58,63,B0,11,AD,3E,8C,A6,9F,BA,6A,FF,29,31,76,F2,F9,5F,56,FC,03,E4,BE,E5,B9,EE,E3,58,0F,67,19,3E,33,22,E1,D5,F3,D2,42,6E,E2,C3,E8,9E,9C,5A,8F,79,85,B5,4D,B0,54,97,27,F7,D9,4B,32,0B,EC,9F,82,72,38,21,98,14,E9,0A,30,EC,D9,23,DE,25,23,A1,ED,37,8D,C0,92,CA,9A,B9,91,9F,28,2A,3A,95,50,7B,E4,AC,79,A9,E6,57,84,A0,92,36,03,D9,49,85,0C,7D,CF,2D,A1,7C,A1,5B,DA,BF,7F,75,D9,DD,47,D4,02,CE,EB,8E,9B,15,00,91,A0,24,7C,90,29,55,70,AA,E3,1B,5E,55,CC,2C,FE,41,1F,A5,57,B0,D7,52,8D,6F,06,5D,27,B5,67,F8,31,5B,06,5E,AB,04,96,D6,C4,FA,0F,D3,A1,57,78,5D,E2,DF,EC,F3,1A,08,C3,79,B6,5C,A6,8F,38,6D,1A,25,42,76,71,EC,16,C7,D2,50,0D,8F,8D,DC,F6,1F,0D,12,85,8C,A1,97,95,F4,D1,20,06,2D,EC,32,61,B7,CF,3E,48,FE,2B,86,5F,1F,C7,B9,B0,2F,1B,08,95,B0,9E,58,61,73,0C,F9,69,F3,64,14,B3,37,70,F7,1A,5E,11,FB,E6,60,09,EA,6F,94,E1,A2,6A,95,DA,3E,4B,D2,FA,D5,D2,6C,A3,0A,8B,86,2E,69,7B,CD,88,65,9E,FB,D4,0E,4A,A4,AF,E3,70,FE,9C,D0,63,28,76,90,B2,07,95,FB,54,86,53,61,E2,3B,6C,FC,5A,14,CE,5C,9B,18,51,FF,01,00,7B,C7,18,01,52,0A,C0,C1,E8,D2,8B,4A,EE,C5,6C,1C,F5,13,FE,11,D0,33,5C,1B,AA,4C,B0,2F,47,D2,AC,B1,C0,AD,48,6E,9E,08,42,BB,FF,A9,15,8A,02,94,F7,B1,5D,C8,E6,2E,FB,DB,1E,43,BD,B9,89,32,7B,22,9F,D4,DD,AD,19,4D,67,2D,2A,8C,D2,29,0C,0B,37,D4,8C,86,F4,3E,4D,FB,2A,2D,13,E8,09,00,7C,2E,1E,3F,AB,DE,62,0B,F9,F0,5E,1F,1D,F6,7F,7D,26,4C,89,C8,FC,EB,84,14,BD,FB,23,20,30,5A,17,5D,D0,57,48,54,7C,80,2B,0A,5F,74,DF,1D,1A,D4,8E,9C,01,69,83,1B,54,57,73,8B,96,BE,EB,AE,0E,B0,95,E0,52,F6,81,24,C7,3C,1D,DD,59,44,B2,4A,6D,DF,C2,A5,D9,A9,67,62,10,17,AE,34,A5,94,08,32,2B,2F,6E,4F,87,70,AE,32,76,E2,73,60,07,86,6B,3F,D5,3A,15,1A,9A,CB,C7,9D,21,B7,A5,15,39,D3,81,68,9F,75,E6,05,AF,17,8B,37,35,64,E2,9B,26,8E,58,59,D4,3E,29,DE,5F,3D,34,06,EC,0A,FD,43,D6,1E,46,F1,7D,B4,BA,28,6D,FA,8D,26,2D,A5,D7,FD,3C,D7,1E,50,2B,38,96,08,CA,8F,58,DB,77,5B,85,B0,35,84,AB,DD,59,55,D5,10,26,88,C4,99,8B,E7,B4,25,34,D1,71,9B,3F,82,89,AB,0D,DA,96,CF,8B,6B,E9,5F,65,B9,EB,8B,BB,58,60,D8,D2,5F,F3,22,B3,A0,BA,28,3F,1E,AA,EE,54,DB,B7,A5,4C,05,B6,97,74,73,EA,BC,8D,70,B0,91,C5,E6,73,79,F1,0C,83,87,C3,54,03,A9,BF,64,F5,AA,14,7D,38,FD,FE,0B,32,15,D9,99,3C,BE,0C,44,49,6E,14,1B,AA,7C,CF,53,BC,44,55,B5,9B,DB,3D,6B,62,E0,8A,C8,A2,7A,DF,A2,E2,0D,CC,7C,3F,72,70,B4,B2,D7,06,CF,BC,D2,AA,EE,BF,D8,0E,6C,F3,07,C3,34,11,C7,80,27,A4,B7,3A,27,F8,FE,CA,92,FF,B6,2C,F6,22,96,C4,C7,99,32,16,64,A7,DE,C3,63,22,04,E4,A9,20,AA,00,27,0E,5D,A3,B5,30,3D,4C,DB,AE,2A,E6,39,5B,A3,86,0E,74,7C,2D,27,7F,86,E6,C1,7A,E0,86,55,A7,2E,C8,A2,2E,72,74,21,68,32,AE,86,28,DA,6D,4A,C2,AB,49,07,6F,2D,51,2D,B1,15,08,33,25,81,DB,2E,57,EB,F3,FC,57,B3,91,BC,70,17,B1,0D,88,66,A6,6A,EC,A8,00,81,41,D6,DE,AC,69,70,CA,5F,1D,AA,B8,E8,4A,F5,6B,A8,5B,00,5B,EF,A9,8C,B5,6F,F7,49,F1,E1,6E,05,12,8E,F8,34,09,34,7A,F2,59,BB,A8,67,BF,E9,7F,F9,42,CE,35,B5,B2,E7,27,DB,04,BE,82,7D,8A,32,05,19,D2,60,66,54,A4,26,EA,D2,40,74,CE,DC,D0,4F,32,8E,B3,F0,09,16,62,4D,CF,AF,EF,15,93,32,C4,D2,AA,FF,DD,53,11,BF,F8,4D,5B,B6,7A,16,EB,6C,E1,98,B8,CC,00,8E,C8,49,3F,75,03,DD,EE,B4,66,6B,4B,2B,D9,EB,65,CC,3E,DC,5F,01,C9,F6,52,92,BC,55,38,C9,5B,8D,E4,99,D2,8A,2A,5F,D8,41,12,59,5A,E7,15,72,8E,A2,A6,70,75,CD,FD,27,88,A9,C6,4C,A1,1A,4C,AB,42,CC,F9,FC,1E,31,DC,FD,4B,C2,24,44,72,25,E5,94,5A,8D,87,89,84,3B,C9,70,AD,7C,D5,EA,0B,66,49,8E,34,0E,DD,4E,B2,82,75,F3,5C,6C,40,72,E3,F8,01,15,20,28,CC,B7,AC,B1,0E,63,20,82,F6,BB,26,52,6F,E1,B0,79,92,3A,42,6A,13,14,64,B0,F9,29,59,42,8B,AF,2B,CC,8D,36,31,B9,3F,6A,EC,9E,65,2E,ED,3D,25,81,04,17,F3,4A,90,76,81,9F,C8,92,8C,27,01,58,67,BB,EC,51,F6,39,4E,EC,0A,5A,F6,6C,87,EA,12,26,3C,86,B5,87,35,55,EA,1E,06,DD,AF,68,DB,E5,D7,C8,B7,89,F8,06,41,68,03,4D,5E,52,C5,F2,F3,3C,66,44,76,D1,AA,94,82,4E,53,E3,B6,EF,07,31,1C,01,BD,50,DE,7F,2A,DD,7C,4B,04,4C,41,96,A0,1D,C6,64,4C,94,D8,2E,0E,97,21,77,40,CD,88,7F,73,26,65,9F,BC,85,A9,52,B9,7C,5B,C7,6C,29,B5,83,46,D1,46,A0,3A,67,5C,FA,75,54,37,80,FF,0B,A9,EA,DA,7B,A0,D4,F6,DA,EA,50,8B,E7,DF,AD,9B,7E,94,7E,35,36,C9,A8,C8,AD,D1,58,24,FF,07,A0,E8,3A,2D,B5,67,4A,15,17,39,6B,DD,41,A3,B9,BD,EB,04,28,0E,29,61,77,A9,16,6D,08,80,47,7F,8B,07,96,91,BA,5B,66,16,A6,4D,4D,25,90,FE,5B,F6,33,B8,B2,70,39,A9,1A,D6,77,43,90,C1,6D,B7,D3,69,18,4F,EA,B7,91,50,68,6F,DE,FD,D8,08,D8,64,C7,2A,7E,B4,DC,E0,D8,DC,F4,14,63,76,18,93,E3,68,FC,7C,37,86,39,2F,E5,8C,82,9F,59,EB,2F,75,9F,E2,B2,F8,FB,8E,65,51,F6,48,5A,20,B1,24,F1,3B,5C,E7,D0,BB,20,1C,59,C3,6C,52,FD,D0,81,28,82,9F,77,DD,8F,A6,B1,1A,58,EB,91,CE,94,EA,FF,D2,EE,A8,62,7E,D1,71,53,6F,51,52,19,39,08,7D,61,B7,B1,A2,E8,C0,AB,F9,A0,01,F2,3B,E2,F1,69,21,D9,CF,50,81,E7,1D,F2,72,42,5B,50,24,14,EF,6E,16,AB,E6,F4,23,6D,67,6B,03,27,35,1A,93,1F,E0,2B,BF,0F,1F,75,2F,03,87,63,70,D1,DE,DA,BF,92,CA,84,1F,AB,57,BA,BE,7C,0D,3B,79,DF,9F,35,A6,F5,B6,F9,13,A1,D4,C5,65,D9,8E,17,43,6B,A1,DD,AD,29,9A,1F,9F,E9,67,85,10,50,61,58,E1,B8,26,31,FF,C7,7D,1D,D2,51,79,00,ED,18,10,A3,A7,D2,C0,96,B4,97,07,FB,4F,BE,1D,05,B7,C4,3A,55,B6,5E,B8,1F,26,F5,E6,56,35,F1,90,E9,CD,F9,E1,AC,C3,E3,4A,8A,65,62,41,93,0D,CE,F6,BD,A2,4B,72,F2,15,D8,F0,DE,31,B3,CA,39,7A,A3,8F,8B,DD,F8,18,C9,DC,01,37,A6,26,53,80,C2,25,53,50,01,0E,16,1B,FC,4D,E7,F9,02,CD,27,65,1B,7D,8C,BB,E9,3D,72,A6,AE,B7,35,8B,3C,C8,6F,B5,17,73,2E,EE,BD,FB,EE,95,93,27,4C,71,ED,FF,86,CC,FF,A5,E5,03,28,48,66,83,73,B0,B2,9F,A6,49,BD,44,AB,48,72,E0,88,D5,65,83,AA,EF,A4,27,B4,10,A8,D7,69,94,60,47,04,2C,08,FC,0D,3C,AD,89,E4,D5,4D,E4,15,5C,17,53,65,0A,F4,71,09,38,D6,2F,AF,35,79,61,E8,F8,8A,F2,37,7D,A3,62,23,43,69,EA,2F,E7,98,D6,03,6D,0F,22,B0,45,74,A7,B5,1C,ED,A4,E8,47,19,5B,9B,47,A8,44,EC,30,EA,00,4D,1D,D3,F0,A2,CB,4F,9D,CF,F5,08,89,6D,E0,4D,8A,95,04,D5,84,DE,76,79,08,81,AC,54,E9,1A,46,EC,F7,89,58,40,6C,04,49,C3,57,D3,8F,1F,3A,6E,83,27,ED,CB,FF,74,20,22,E3,51,0B,92,7E,A8,A8,BC,2C,70,C1,B6,93,61,E2,E7,13,B2,1F,3B,62,76,4C,F4,34,E6,6B,04,BF,5A,DE,16,F8,A7,55,51,DB,60,56,B8,1E,61,8D,51,0E,C8,85,0F,F2,F8,65,67,82,4C,44,47,43,78,71,4E,64,51,25,6D,8F,EF,88,62,FE,1C,E0,99,E7,50,6F,EA,69,7B,40,05,5F,D3,B3,34,AD,08,06,7C,5D,BE,07,AC,AE,F1,4F,A1,5E,55,BF,EF,BA,F9,D8,3F,71,98,41,2F,21,13,BE,2D,4A,4E,EB,39,24,98,61,49,AE,AD,C6,08,3A,2F,60,F2,68,55,F8,D4,73,4C,05,D3,D8,34,BF,57,FE,D0,F8,CB,2D,0A,56,B9,8B,D5,E2,BE,75,5C,8F,D0,2A,E2,0E,C1,61,99,61,99,EF,35,51,B6,75,0B,66,77,A1,DB,68,02,BA,94,9B,4A,2B,F0,1D,24,67,E8,68,C1,C7,95,19,25,A8,BB,DE,57,F2,59,46,CD,8E,DA,64,C3,23,63,10,6F,7C,E6,6F,2D,4C,EF,ED,34,29,C7,95,57,94,A3,06,06,A3,0D,A6,DC,C5,CC,0C,56,22,B1,03,95,A1,17,97,32,D7,DB,DF,DA,DA,7D,6D,FC,EE,BA,E6,A1,C4,11,6F,EF,BD,21,58,AE,62,AC,03,F1,32,A5,5C,FA,CC,E6,86,68,CA,B1,23,A9,0E,C1,7A,7B,CD,E5,D7,BC,62,4F,99,45,B2,8A,A3,2F,96,D4,98,D9,DC,89,EF,A4,83,45,3B,C8,87,FD,63,1E,47,0D,F0,12,09,6C,07,2E,1E,63,DE,D9,01,16,6A,1D,1A,17,EB,30,0D,B0,4D,ED,65,43,09,B2,98,00,0E,F7,A3,9A,6F,F4,0A,34,A1,A4,49,DD,79,88,E6,86,DB,BF,5A,F7,5D,6C,5D,1E,6E,00,79,B7,2A,C9,F8,34,9C,2B,26,38,40,77,AB,9C,1E,9B,17,76,A9,79,CE,F5,0F,E9,2A,F7,16,05,AB,E4,02,50,2D,37,52,D9,62,09,F5,30,56,F9,2B,E1,4A,8F,91,3A,CB,06,08,96,F8,F7,EB,18,67,C0,CE,9D,5C,A2,2D,CB,54,EA,C8,7A,03,8C,AF,3F,89,CD,0D,5C,C5,9A,4A,C3,83,05,5D,FB,E6,C3,ED,61,AB,CD,55,B7,99,6D,83,2A,9F,D9,0F,4F,C8,B2,B9,A6,57,D0,09,EC,B1,AD,9B,50,57,41,29,23,B7,05,20,F0,D9,5E,BA,62,63,29,AA,2B,0D,90,7A,E4,70,3E,64,FF,D7,EA,8D,73,69,8E,2D,4A,0B,CB,17,1D,91,52,A1,DB,A4,99,B1,77,36,BF,C8,4D,64,A4,1D,87,E0,A9,90,C7,E5,71,30,15,07,AC,3F,02,A1,5F,C9,57,95,D1,62,95,AA,EA,B3,6D,39,8F,7E,47,AF,DD,E1,0D,FA,51,CF,40,53,86,1C,E8,D0,DF,21,50,D8,68,17,61,84,A8,50,B5,35,44,60,1A,31,78,C6,FC,6D,A7,31,E4,DF,F0,74,DD,03,5B,E7,14,2F,A6,AB,90,72,F2,07,1C,D7,4E,57,02,C4,BD,C2,15,0F,3B,08,39,BF,EA,53,F8,0C,82,AA,72,07,60,2D,C5,FB,6D,7C,C1,D8,B8,AB,BA,18,EC,F4,CE,81,C3,99,A6,04,5C,D9,F1,1A,99,58,6E,36,99,62,67,42,8B,A5,8B,C8,EA,45,C6,84,B7,DE,14,D0,B9,85,E6,43,E4,90,97,8C,4A,9D,FC,D6,6A,93,26,2F,C5,25,C8,2C,00,78,DA,0F,85,84,A4,8B,EE,7A,9F,75,0C,DB,1B,AA,7D,E6,DE,16,1E,7E,38,D6,1E,F3,B0,B7,36,EB,A7,07,9D,2A,49,C3,32,44,64,4A,E4,A7,A1,D5,67,46,C8,BC,3F,23,54,E4,46,06,88,EA,3A,F2,6C,43,0F,84,AA,1B,31,82,29,0C,21,73,25,02,46,83,4A,E3,E1,31,0B,BF,7E,6B,F9,72,FE,1C,11,BB,18,44,F6,24,B3,14,A7,8E,CA,47,2D,28,08,56,D8,B4,D9,29,03,BD,B3,51,3D,74,55,23,E4,6B,FC,87,36,D5,8D,F4,04,18,3E,E5,55,63,6C,93,7A,B1,12,B7,A2,D7,79,E7,2D,B9,BE,AA,EC,2D,D7,22,3D,32,27,C5,E3,EC,BB,CB,2A,41,00,83,B6,44,72,D1,46,92,F9,29,50,20,72,57,38,F1,55,A5,17,5A,86,69,BE,A9,81,AF,11,11,F9,37,44,16,4C,2C,F6,68,41,19,3B,30,F4,F6,7E,4A,42,F6,38,59,86,E6,D2,71,4E,E8,26,A3,6A,21,F2,4F,EB,2F,27,E9,22,DE,D6,94,95,B3,EF,1E,63,3C,C0,51,BE,E4,31,56,4D,EB,71,92,AE,FF,D8,AB,F5,0D,85,5D,03,FE,15,38,CE,0D,31,E4,5D,79,77,D6,0F,5B,7D,D4,B0,C7,12,76,B5,E6,57,1B,24,FE,70,37,9E,1A,32,2C,27,F5,38,23,89,E4,28,42,4F,6C,24,59,CA,CD,E4,96,68,04,B7,8D,AA,42,E2,ED,31,E1,91,CE,2C,A4,DF,E2,72,90,59,5C,69,6B,10,62,BE,9B,03,FF,ED,A1,B4,E9,71,5A,04,0E,5E,D5,ED,2A,1F,DA,B9,D5,06,90,03,21,A7,56,12,64,9D,9C,2B,28,CD,64,02,7B,99,46,DA,A6,F0,26,4F,F7,CA,C4,B3,1F,27,7F,29,AB,78,55,B4,87,E7,92,35,46,21,2D,CD,77,2A,66,54,A8,CC,73,E8,74,B3,91,9F,62,69,7E,18,B9,28,DD,C2,EC,06,23,0C,F8,B8,DB,78,FE,BA,61,A8,43,E4,9A,DF,1A,80,20,A8,37,3B,B5,1A,22,46,A9,62,4A,DA,FF,B9,B7,E9,83,83,C0,B6,4A,A0,B0,C3,5F,BC,D9,50,A5,10,23,51,2F,8B,93,08,06,AE,75,D0,DC,74,55,6A,E6,B8,5A,3F,5D,D2,6A,EA,DE,61,7D,31,4B,F1,30,06,98,1C,EC,D1,7E,E4,83,BF,42,91,9C,32,A3,07,53,6F,92,D8,A6,78,F1,2D,8D,3F,2A,17,A8,9A,43,5D,E1,31,81,57,76,24,EA,7B,FD,D7,E8,84,62,B1,C8,91,ED,A8,EE,DE,40,FC,23,60,05,D3,1C,43,47,5F,CB,E3,61,5C,D0,42,A2,18,F6,A8,A3,05,5B,2F,D9,D2,D6,4D,8F,3C,B2,24,77,4C,1F,0D,9A,DD,29,65,11,D3,7A,E8,F7,CB,CB,70,72,00,EF,BB,28,76,D9,C7,58,79,56,B0,EB,32,91,78,31,6C,9B,A1,05,A2,0B,C6,D6,67,3C,37,F0,62,C6,C2,FF,51,37,4F,89,1B,2B,2C,0A,62,6B,BE,D3,7F,7B,FC,A6,B3,D9,C7,A7,9D,63,50,5A,D5,3C,A7,FE,3C,ED,D3,5F,98,CB,87,24,22,54,44,9E,5D,F9,4B,62,D1,75,0E,3D,DD,85,B5,C7,AF,87,59,22,46,05,7F,00,E5,01,BC,4D,BD,31,3D,0B,73,C6,3A,01,DB,DD,0C,B5,94,75,3B,97,8C,B8,5E,0B,F9,BA,79,9F,2B,A9,1C,31,4C,ED,98,DD,91,1D,11,42,57,E5,08,06,02,39,7E,98,15,A6,91,E5,73,DB,05,C8,E7,73,BC,89,7B,93,E5,BA,75,C1,15,60,77,45,4E,91,69,9A,55,DE,00,7A,33,07,A6,34,5E,42,0A,7F,94,30,CA,AB,70,DA,6C,C4,5B,DE,A2,32,62,FB,AD,AF,87,2C,F5,6F,44,25,E8,D1,99,59,CC,58,16,A7,BE,8E,69,1E,EE,6C,FE,67,B7,BE,98,6F,AA,F9,A6,AA,56,52,17,7C,43,B0,F2,E4,F2,3F,5E,5E,4D,15,D9,5A,85,D3,89,55,27,3B,FB,5D,1B,53,40,7B,84,57,FA,EE,8D,7B,83,A1,38,CC,08,D7,E9,D9,DF,29,83,DB,61,C3,6A,A5,DC,67,4D,D4,73,40,BD,26,53,C2,93,FA,0A,E3,16,CF,1A,74,90,F2,97,05,3B,9A,C7,4A,05,1F,BA,B5,80,B9,7C,E4,C3,2A,62,AC,97,DF,08,7B,A4,9E,EE,7C,68,7D,ED,1B,96,C7,9E,29,0E,D2,52,E4,CB,35,7B,D4,C4,32,A6,4E,BC,90,1C,B2,2C,94,96,12,6E,DA,3A,C7,7C,B9,27,CA,F3,71,7C,D2,43,A3,47,8C,E4,C0,14,C4,17,0A,9C,B6,39,9F,2E,D6,56,27,A8,2C,B4,09,7C,75,48,71,2B,DF,D1,81,DF,AC,35,B3,46,5E,DC,1A,07,66,CF,D3,08,56,14,E2,B5,D1,41,77,A6,17,7A,26,CF,F3,7C,79,BC,51,C7,CF,ED,18,F6,6E,B9,D7,36,56,17,25,C1,A0,A3,D2,7B,ED,AC,A7,16,9C,D6,AF,9C,7D,5B,FD,ED,46,88,18,9E,1C,12,A1,11,48,06,2C,94,7F,7E,03,EE,7B,05,62,E2,AD,3C,11,8F,41,45,5A,0F,3D,6A,2C,A0,3F,1F,23,A2,2F,16,C2,81,BC,DA,E4,2D,C4,D9,57,10,CF,C7,7A,1C,09,DE,D9,8D,C1,D2,E9,A5,08,D2,FC,D9,D0,92,D6,AB,D2,73,B2,86,C0,CB,F1,B6,8F,61,D5,AC,CA,3E,45,DB,27,51,AD,A3,DA,A5,08,3E,A6,19,4E,28,BE,ED,C7,A0,36,E2,C5,C7,80,88,2C,22,9E,47,CD,CA,5E,D4,68,67,5C,F8,87,45,1B,D3,8E,C4,09,FA,02,0E,68,BA,B6,1F,9E,A3,27,54,06,DE,8C,F6,BD,D0,65,11,10,1E,D6,40,C3,6F,6B,56,81,8C,4F,98,5F,1C,B0,BB,EA,62,47,7A,EF,9E,CA,C7,BB,0C,48,52,80,5E,83,54,4D,61,0C,30,00,33,E0,4A,22,5A,E8,F2,AD,97,C0,4D,B1,C8,77,C0,AE,F5,95,AE,08,35,3C,D0,AA,0A,99,28,B8,F8,E9,CB,9A,07,E1,0F,92,16,27,52,55,D9,CB,FB,86,18,3F,77,3D,2B,4B,78,78,1D,24,1E,89,FB,E9,FE,CC,94,B2,D9,CE,91,45,61,BC,35,0C,EF,E4,B4,20,55,0E,A4,A9,18,F4,BF,9C,2E,54,F4,83,10,12,BC,E3,A4,18,E9,3B,09,0E,DA,5C,59,54,68,D2,1A,98,E9,6D,05,5E,AD,86,05,1D,3F,22,54,BD,C3,23,5E,7D,FD,E2,8E,64,1D,21,C0,8E,FB,05,20,E6,0D,94,54,25,5F,8A,41,41,CB,3C,DE,2D,C4,EF,5D,A5,4E,50,AB,7A,C2,32,D3,3B,0C,E0,F2,48,EF,02,BF,6C,48,6C,DF,F6,F6,C4,1F,C3,00,D2,0F,AB,F5,09,EB,6B,F7,6E,1C,AA,AA,37,36,84,C8,8A,B3,25,18,C4,30,5E,2A,6A,00,AA,36,65,1A,7B,42,40,DE,69,15,03,A6,85,02,60,52,99,77,A1,8F,8A,54,88,A2,D1,71,37,82,47,E8,54,BF,5E,6E,BE,4E,CE,B2,9D,5A,85,51,74,32,4B,D4,F5,6B,9A,15,CD,14,6E,07,F5,09,C3,1D,A0,7B,E0,10,D8,33,FA,16,26,2E,82,7B,93,A0,2C,FA,81,68,96,CF,6C,4A,68,D0,C7,7D,E2,5B,9C,32,7B,8E,4A,49,36,09,38,12,51,7D,95,46,32,4F,D2,E6,4B,32,2B,10,1E,BF,C1,C9,93,37,AD,FF,0A,48,BC,25,58,A8,3D,D9,24,03,77,65,E2,97,48,4E,CF,B5,BF,15,44,6D,A9,7D,FE,78,41,9E,32,97,F3,6C,7B,22,30,23,C8,33,E3,C2,9A,90,9A,59,C3,B6,AC,F3,58,34,9A,C5,7D,DB,6E,4C,BE,C7,19,76,7E,00,AA,6C,2F,20,21,CC,8E,A0,65,01,46,9F,D5,83,DF,5D,8D,74,F5,90,C4,9E,AF,17,A0,12,53,7D,41,1A,F8,F1,02,5D,96,1B,DC,6C,B9,4A,5F,34,72,E4,C6,CC,6A,7C,68,D7,26,DA,27,AB,40,F3,FE,82,44,09,DE,39,DC,73,19,4D,A1,90,48,13,62,9C,6B,97,26,58,2B,3A,9E,97,1E,B1,DE,2C,ED,CF,1F,77,F9,DA,3C,75,EF,C0,17,0C,1F,23,8C,AB,4A,28,0D,43,05,D2,FE,A3,60,EA,1C,E2,B4,49,F4,EA,94,11,09,F2,77,12,30,9C,52,B7,CB,0E,AE,0E,11,D5,53,21,3B,C2,C8,B3,E5,AE,1F,B4,62,70,02,E6,8F,78,79,08,34,C6,12,65,02,C1,75,75,6A,81,76,12,DC,9B,7F,5D,FD,A5,0D,FB,49,FB,ED,E5,AA,99,94,12,17,26,6C,17,01,11,1C,BB,F3,12,C2,04,94,36,3E,5C,AC,C4,BB,C5,58,4A,2C,9D,7A,26,96,38,A7,61,8B,56,85,73,9C,B5,E9,06,3C,A4,60,1E,5D,AD,7E,9C,71,C6,EF,2E,B7,15,27,24,8A,94,87,C0,29,05,AF,D1,A8,79,93,1C,E7,57,81,BE,0A,71,34,51,D0,10,BD,27,26,1D,D8,9F,A7,C5,2F,18,01,1B,5A,C0,95,B7,C1,86,50,27,83,95,17,0D,E5,B7,4B,50,5D,30,BA,0C,E4,5F,46,37,7E,1B,EB,92,B2,28,01,05,9A,94,34,24,CB,1B,32,AB,B8,18,93,8F,18,D0,8D,15,6A,5D,E3,69,68,B0,97,F1,44,4B,45,9D,0C,52,C8,04,7E,91,13,F9,C5,DF,69,72,DF,9A,51,3E,15,B9,59,90,25,24,3D,8A,C9,3F,1A,E4,7A,81,B8,89,09,1D,8B,CB,57,5D,0B,C1,6E,05,A2,4A,DF,03,B3,B2,B2,F7,D0,94,64,E8,34,40,52,38,A0,31,7E,F2,7E,B4,7D,BF,90,08,2D,0C,97,22,6C,DA,90,DD,9E,9F,1C,21,9A,03,EF,D0,2F,16,CD,82,9A,1E,F5,D3,C4,56,9C,37,10,9F,02,0F,BB,23,8B,5A,38,4F,B2,E5,B0,88,F7,A2,15,6C,8B,CB,14,E6,41,52,FE,D6,07,DF,DA,F5,4B,24,C5,DB,2A,0A,8D,7D,57,15,C6,83,42,C6,E6,24,40,54,09,C2,5F,4B,0B,98,B4,E1,9F,3A,94,93,3D,30,D0,90,5C,75,04,61,40,E1,7A,45,43,49,CC,09,AB,A4,92,22,7A,F2,67,52,72,DC,4B,C0,C2,7B,92,9B,29,57,5A,EC,C6,23,ED,17,B8,ED,DC,F5,4D,31,51,9E,15,EE,28,CB,E0,8A,92,03,8E,43,B1,8A,68,7B,4E,D1,F7,67,5B,F4,98,73,FC,C6,19,A5,67,0A,31,00,C3,ED,DE,73,28,B0,3C,C3,02,70,F8,6F,DA,0D,7D,98,54,A7,38,62,98,7A,E9,22,FE,61,B4,4F,66,B6,24,D7,3A,9E,99,9A,24,47,47,50,52,4D,DA,5B,FD,79,F6,8D,53,82,6A,7A,B1,57,D3,FB,A4,16,D7,1F,0D,BC,3B,FF,DA,52,47,8A,CF,82,C7,D7,ED,56,F8,66,51,86,BB,9B,80,92,CD,8B,B9,3A,B8,3A,96,01,0D,C9,D6,DD,4D,46,31,C5,99,A6,95,46,85,10,59,F6,AD,D6,22,23,FD,DB,25,AF,42,B3,05,A8,DD,33,26,00,65,F6,A1,D7,93,42,8F,CA,36,1C,48,9E,75,23,15,6F,F6,EA,13,62,00,BB,56,90,AE,0B,47,D8,E8,74,0A,F6,B3,8E,C2,1E,29,EE,63,58,D5,6D,E0,1B,F0,57,30,6A,52,AE,43,18,5C,61,F6,E5,09,A0,8E,D9,2F,5F,FB,7C,CF,BD,2E,1A,C2,AF,01,80,2D,E0,0A,B7,D6,C3,39,C3,CB,27,FF,3D,A6,CC,2D,C7,4C,FC,A0,B4,09,27,44,40,77,FA,57,A9,4A,72,D1,45,00,A8,E2,BD,BF,DF,E7,8E,7A,72,72,CC,D8,79,48,59,F0,97,A1,98,59,92,C9,D6,97,07,47,88,5C,39,3A,25,DD,3B,71,79,70,A0,EA,61,E1,79,43,FA,B6,D6,CE,EE,99,88,C4,D7,D3,82,3D,C0,23,13,7B,08,7C,31,43,BE,B2,87,68,BE,29,C8,D8,B5,D0,9B,BC,78,60,47,0B,0F,B8,2C,81,A4,88,EE,AB,D7,77,59,E7,30,92,57,66,6E,71,EB,EE,82,DD,78,BB,94,A6,A3,C6,7B,DD,A0,25,AB,F4,C7,51,C4,F4,D1,15,DF,88,6C,B1,F6,19,6B,79,E8,92,C9,8D,05,9E,81,12,7F,AB,DD,03,05,F0,A3,80,A7,6C,57,D2,60,EC,CD,09,9C,AE,5F,7D,35,28,B1,A8,3C,49,AC,C5,D7,56,41,D0,13,73,D2,43,9A,6A,43,01,84,57,91,A4,48,0E,CA,B1,1A,AB,D4,46,7B,78,07,DF,E6,BD,AB,FA,D6,AC,90,51,33,17,22,F9,E1,73,CD,30,B1,C0,D8,FF,CE,EE,F6,9D,19,67,D6,0A,C6,36,41,4E,72,B4,E1,1A,24,0B,EE,76,08,15,77,A5,D0,25,4F,ED,FA,1F,66,92,4F,AF,BD,CD,56,F5,B8,43,BC,4E,6A,B8,BC,33,00,DE,F2,D4,14,57,FA,37,A8,9A,4A,0F,B0,39,3A,AD,AF,FD,E5,94,93,AD,95,38,3B,AE,D3,A6,17,19,AD,15,BE,BD,E7,A6,D7,C4,8A,F6,A5,57,B7,A7,AA,5A,8E,A2,0E,17,39,0E,F7,D8,32,62,50,A2,75,31,E5,B5,AB,74,3B,D3,E8,93,85,A1,AE,9C,4C,E7,A6,AD,A4,C6,06,41,1A,09,8B,48,A5,54,71,AE,57,7F,35,D8,65,48,32,B7,98,30,87,6B,D6,01,AF,87,87,0D,09,47,AA,E6,2E,EA,0A,B0,41,EE,4F,F4,B1,E6,B5,A6,EA,3C,96,53,C1,46,24,63,E6,21,46,5B,86,15,3F,74,BA,C6,4F,D2,1A,DF,68,80,D5,AE,C1,1B,2A,58,F2,81,35,3D,C0,B5,68,03,AC,71,B7,09,73,FC,5F,FB,1B,D0,66,57,FA,9C,D5,B4,3C,46,13,E8,8D,E8,4F,02,63,79,0E,CD,3B,35,38,96,DB,A2,E6,6E,39,08,47,73,04,A2,B0,25,67,A8,E5,9F,DC,B9,C0,C9,6F,30,E8,F4,74,D1,40,8F,18,0D,E0,A1,9B,30,C6,2D,B8,A8,A4,FD,B8,91,05,50,F4,FB,27,BF,D5,72,45,C3,C0,F7,24,70,4D,F7,7E,71,2B,4A,A2,17,A0,7B,E7,07,D2,24,87,81,89,65,D6,B4,A5,7A,F9,8F,14,B5,73,0D,D6,09,F5,43,18,89,C9,0A,99,5B,CA,06,D4,31,CA,7F,AD,EA,DB,78,16,50,AB,88,3F,20,62,50,59,2D,4F,62,19,9F,27,FE,06,EE,35,E9,8F,2B,7F,A9,15,AC,94,B5,22,3E,0D,5E,91,97,CC,3D,00,19,84,5E,14,1F,CB,78,6D,07,4F,AE,12,00,4D,EE,77,2F,3C,F9,85,26,FB,8F,DD,F8,F3,A7,1D,09,8F,F0,1A,A1,9C,DB,E9,1A,A8,58,A4,39,E6,EF,FF,3E,76,4C,32,A3,10,9E,51,C5,30,F9,73,10,F5,F8,98,50,19,F5,43,D1,F9,CA,94,51,79,D5,F5,C9,61,05,CB,F9,20,4C,C0,02,31,F5,7C,F2,83,32,9B,A6,A8,8D,8C,22,CC,AA,0C,D1,C2,93,88,13,79,B4,0F,E0,74,E0,C2,15,8E,92,71,BD,1F,CE,89,49,8B,39,35,9C,08,A6,6C,C7,33,91,B7,C7,CE,43,DF,9A,CB,CF,B0,4E,16,9A,D6,2E,6E,76,07,68,90,0D,34,1E,5F,AF,05,6A,2D,D5,78,75,B8,BF,C7,06,DC,B4,B0,3C,5E,9B,C1,DB,32,1C,E4,AC,4F,04,A4,EE,0A,9E,62,0A,77,8C,4E,2D,21,77,FC,73,8F,12,37,BA,73,8C,61,09,09,75,0A,DA,D2,1E,56,E4,FD,D6,83,40,EB,63,46,4B,41,62,18,03,90,68,90,68,58,AF,88,E6,22,71,4F,B3,3B,68,C9,8C,8A,A5,8B,72,98,C0,75,50,1F,D3,7B,C6,95,6C,4F,28,1E,D3,02,87,FC,95,FC,99,45,84,07,A4,C7,AB,E5,C5,A7,D7,64,B2,B5,64,8A,65,53,F4,D2,CB,11,D1,6D,9B,D3,BE,79,F3,53,8F,2D,F6,81,93,50,94,7E,BB,CE,FB,33,01,A6,71,D6,D6,17,91,9C,BF,9C,9E,42,0A,4E,BA,02,39,36,43,AA,79,F5,5E,A3,1D,D4,FF,2A,2D,E4,6A,FB,0B,AC,EE,B5,6E,F9,52,9D,DC,53,E2,09,45,FC,C6,A6,75,BA,34,2B,8A,67,2B,5F,18,09,63,24,54,DB,9F,FB,29,34,E7,50,3B,32,22,2F,E2,2D,81,F0,CC,86,81,A7,DB,B4,9C,FF,67,1A,D7,E2,E7,04,62,E2,04,6E,10,B6,ED,01,9C,76,C5,16,5E,41,29,BA,3E,2C,5D,58,ED,DD,6C,6D,82,02,96,6C,67,3B,D9,A5,88,57,DA,5D,90,45,E0,84,05,EA,06,43,7E,F6,D3,97,7C,E1,3E,25,26,C8,12,42,CD,1E,46,D9,56,0C,2F,3E,E9,50,A5,FE,66,D5,44,AC,5D,38,3E,97,60,6E,E4,29,CE,D5,88,E4,80,EC,FD,EC,02,BF,86,0A,1C,B2,25,5E,FA,F0,27,B0,A0,9D,FF,E4,35,9E,8D,E4,3E,D0,7C,AF,01,F7,6E,5C,4C,81,60,BB,0E,D2,08,8F,10,26,CB,0E,71,D9,11,0F,DC,15,77,D6,EF,36,18,6E,DF,F4,2D,93,46,34,9D,93,A0,94,BE,09,1A,B7,E7,B3,56,E4,5B,4B,08,A6,2F,09,58,1E,1C,7A,17,A1,51,E8,D2,0A,8E,57,3E,07,35,C6,55,23,FE,5C,FB,2C,1C,77,A3,F8,57,B7,14,FB,B0,C3,2B,B6,56,6F,10,1A,40,8C,5A,D5,C7,65,DA,70,2C,CB,4C,4B,9C,F5,8D,C0,52,DE,20,59,A9,41,CE,A2,06,29,D8,80,3F,33,BA,67,EF,F8,EE,E5,7D,70,A7,8F,96,17,BF,A8,F3,7D,22,ED,AD,BF,50,24,39,2E,47,AA,10,36,FF,18,F8,75,63,54,87,CD,63,3C,30,68,CF,59,FF,EE,2D,28,9E,8D,FE,86,B0,39,70,35,54,CA,F1,1E,B8,F6,0D,B4,CD,6D,DC,FE,B3,5E,45,B9,06,19,67,36,5D,B6,2C,B0,2F,BE,0C,60,D9,88,B0,AE,23,19,77,44,F3,1B,A9,E3,20,2C,98,DA,39,D6,FF,78,6C,87,BE,63,9E,AB,15,95,77,91,7D,0C,02,43,DB,63,A0,47,F4,59,30,81,98,B7,AD,26,3D,5E,17,2E,46,13,12,88,D6,70,9B,E4,AD,68,FA,DB,5E,D4,C4,BB,65,E5,96,D9,83,C6,D8,8D,03,F3,F2,6A,80,FD,98,AF,6D,2D,EE,FB,B2,DA,54,72,E9,5F,C4,2A,72,2A,EE,5E,E6,8F,02,29,C2,88,A5,BA,74,54,E8,63,96,A8,27,55,86,A9,1C,B6,29,90,B7,1B,E7,38,A5,85,80,C9,66,E1,3D,D8,4A,6F,25,F9,C9,AA,BF,6A,F6,B0,26,6D,FC,55,E4,FB,57,4F,06,73,89,7C,26,44,77,F5,24,33,CE,FD,16,31,40,ED,D9,99,E7,7B,CE,F3,94,0C,AF,15,48,28,20,06,C6,C6,32,D2,BB,8F,EB,15,69,A5,1E,E5,31,68,85,4E,35,D6,23,01,2E,92,5F,5C,90,E2,57,8A,9D,7F,70,05,AA,27,CC,07,05,7F,94,AF,B7,3B,0B,62,EA,D9,2D,26,57,C1,B5,51,CC,3B,3B,DF,63,13,E8,1C,CF,0B,E7,4F,89,57,1D,3D,7E,80,FB,02,8A,B0,8F,2C,09,FA,31,F1,AA,5A,2E,A2,A7,8A,7A,E0,1B,25,6E,C1,D6,3E,86,E2,E3,97,92,BD,EF,90,CE,E8,F5,8E,97,B8,82,B9,30,89,E3,60,B6,B5,73,F9,19,AE,F7,85,84,D0,FB,08,5E,D2,DF,86,C8,26,2C,F1,5C,C7,DD,51,A1,0B,0A,C3,D5,B3,99,30,A7,E2,FE,2B,DC,7D,0B,A1,29,2A,D9,A9,2D,54,2A,5F,70,3D,A0,29,C9,73,78,76,1E,77,92,1E,1B,C4,1F,F5,57,D1,AD,D3,11,A3,C7,07,F9,36,ED,FC,3D,24,6C,00,FC,3E,F8,93,61,F6,72,3D,12,DD,83,D5,74,40,14,9B,DF,C2,2C,F9,DA,79,4E,3A,38,5B,74,29,82,88,F7,9F,B8,A7,D0,C2,E0,F0,C1,B8,CC,19,99,5F,22,EB,0F,A5,3D,CD,32,73,19,4F,B1,CB,B8,E8,6E,A9,75,89,8F,E7,99,56,77,53,E5,33,15,6C,38,A6,02,3B,E4,12,76,94,65,EC,DA,27,EF,91,B3,02,56,79,A8,AC,8C,FD,AE,AE,1A,5B,73,90,46,2F,AC,34,D7,2B,AD,65,EF,19,47,48,7C,54,32,91,95,EA,BF,6C,FE,EB,C9,36,C3,7E,0F,0A,34,3B,54,6F,5F,37,4E,63,D1,87,6D,25,C0,82,8E,D6,C6,C3,EE,35,FA,E8,79,39,C0,CE,95,3A,6F,3E,6E,28,6C,E0,E9,3F,8A,A9,CE,D2,8B,FB,F2,49,E9,AD,ED,C8,4E,D8,B8,EF,C1,55,5A,7E,4F,E4,E1,F5,C8,1D,EC,FE,21,62,A3,93,B0,75,0E,C0,F4,01,3C,AE,E8,6C,D4,6D,02,C3,E3,71,18,06,97,C1,F4,3A,DA,FE,ED,BB,17,6B,48,2F,78,A6,92,BF,F1,AC,51,DC,F9,91,1A,BE,03,27,42,3F,FA,4C,57,0B,E2,9E,90,D5,CF,36,80,87,D0,2F,FA,CB,89,CF,DC,93,65,A1,22,67,73,46,BD,75,83,26,25,B4,28,A7,71,19,BB,28,24,67,89,5F,80,A8,25,F4,4D,5E,E8,16,5E,71,7C,70,F2,C7,31,77,C0,CA,8D,A1,0F,31,CA,49,26,CC,2B,42,6D,78,B0,3B,61,07,54,69,8A,3C,DE,5C,28,EE,00,05,F5,F5,02,43,7A,93,BF,DF,9D,CB,60,EF,EE,84,3A,22,69,44,AC,8A,23,49,58,11,10,19,21,C0,93,45,8D,9D,57,B2,19,A5,F8,F3,7C,3E,4C,1D,C8,87,FE,09,79,67,92,36,75,84,77,4A,C7,CD,B3,E2,7D,9A,E7,B3,15,DA,9B,49,F6,33,B4,E8,25,A6,55,45,C1,3D,39,3C,6D,B5,65,E5,AE,08,2C,2B,A4,CF,BA,E7,09,C8,22,3B,CE,03,91,9D,36,E7,4A,A6,B3,71,4A,54,9D,90,0E,9A,C5,98,30,CE,24,21,81,30,03,AA,B1,75,E4,86,10,59,A4,10,F2,E4,9B,B5,39,27,74,1B,D7,92,E6,19,D8,F6,AC,63,63,31,40,0C,8E,04,7B,BF,62,94,67,D0,B4,FC,40,34,75,0F,71,B6,44,E0,BD,49,02,BB,81,F6,BF,79,41,2E,E1,88,D4,EB,A9,D6,6F,CC,8E,57,0A,18,8B,14,72,B3,93,64,5C,9D,3D,87,25,AE,0D,6A,66,BA,B0,3F,2D,8A,45,B5,B2,F2,43,E7,7B,56,EE,7F,68,81,2C,91,50,D7,B0,C8,B5,5C,6C,8A,BF,4E,0E,AA,1A,54,94,1A,91,C8,4B,7B,AC,2A,18,22,D3,B0,E9,2F,38,31,24,A4,3E,03,9F,BB,39,56,77,1E,82,E7,C1,20,64,62,97,0F,50,CB,06,81,10,AA,95,80,39,6E,70,9B,8A,48,6E,9B,39,4B,52,7F,41,EA,2F,42,7D,18,17,3C,8A,76,A8,2C,42,5B,05,02,26,AD,3A,56,AC,ED,FA,3A,97,34,2E,7E,B4,E9,E4,ED,D1,32,3B,E7,A4,37,FF,D2,26,C9,9A,D8,D4,38,17,21,7D,B5,05,C7,58,0B,00,AB,D5,D0,A6,8E,20,64,1E,FF,99,BB,5F,89,D3,96,9A,50,C7,63,23,DA,FC,A2,16,08,83,1D,1D,75,F8,BE,D7,89,56,F4,5D,B4,16,42,2F,27,9D,72,31,61,76,8D,2B,1C,F4,84,52,27,3F,75,CB,5B,B2,04,F4,40,C2,6A,C9,55,D3,41,D0,96,96,55,8F,12,71,0C,A8,93,F8,61,9C,FC,1B,83,25,AF,CA,D2,50,80,60,38,09,A1,2C,EA,96,C6,CB,A2,E1,9A,55,95,85,1C,5D,C5,01,CA,97,F0,80,AD,51,C9,DA,4B,F4,26,6F,99,76,1A,46,63,EC,02,C9,F5,4D,AD,4A,F7,50,96,F7,7E,1A,65,19,08,AE,A8,FD,B5,B7,3C,86,D6,ED,5B,7A,B2,F3,86,E5,41,B4,7A,C7,90,AB,F6,18,8B,56,16,CF,CD,AE,77,63,AA,D5,74,76,D7,AA,16,17,DD,6B,33,8B,72,07,C3,FB,AA,8F,05,3D,EF,80,1D,DB,08,0F,3A,CF,5B,41,7A,BB,D7,FB,63,31,B1,35,E6,D8,F8,AB,56,8C,3E,2C,D1,8A,90,C0,33,75,E7,46,9C,29,F2,CB,6B,BC,59,E8,48,B6,59,54,9E,08,CA,9B,BD,3C,12,0D,33,78,E2,86,29,9C,F2,65,87,AE,AE,A6,9F,36,EF,C4,42,2D,4E,0D,95,7E,43,78,07,98,93,55,26,D8,F3,8D,97,01,85,C9,5D,D0,C3,D0,9A,9D,F9,72,04,47,4E,1F,53,EF,25,44,07,CC,14,7A,0F,C4,3B,0C,8F,E4,7E,37,11,8A,D4,C6,3A,68,01,55,49,E2,40,6A,34,27,CB,42,FC,D4,F4,C6,9D,B1,02,8E,C1,57,31,73,D0,B0,A1,A3,18,07,34,F1,AF,C7,01,A3,EB,09,EF,A3,8A,FE,7F,A9,DB,2B,E6,11,52,61,8E,ED,9D,86,63,14,7B,FC,DB,4D,06,46,4E,5F,93,CB,DD,6D,CD,3D,10,DE,CD,DF,F9,8F,CD,93,10,BD,26,76,99,89,C6,E5,90,92,94,F9,89,4C,32,89,19,63,1D,C4,42,55,E4,CB,22,4F,D3,CE,5C,CE,F7,CC,CC,F0,14,C3,86,F5,B8,14,8F,16,AC,D9,7E,15,97,9E,39,3E,7F,39,73,DB,79,00,FE,C7,53,3F,4E,4E,84,69,3E,1F,03,73,17,49,96,A2,85,A2,D8,49,80,B3,3B,59,17,43,8C,57,CE,F5,DB,C6,1E,6D,37,6B,A1,D1,52,4F,B3,97,12,32,23,F9,F6,49,3A,EC,D4,4D,2A,7C,35,80,A3,B5,4A,43,9C,7A,80,75,FE,E0,DD,EB,9A,4B,0A,27,DE,A0,76,23,FB,FA,AE,BB,57,97,CF,0D,D0,6F,A6,48,88,15,3E,17,AF,0B,4B,5F,46,0E,39,4F,B3,97,14,BD,75,71,5F,46,EA,84,58,31,A4,E2,31,90,09,59,3A,A7,28,BF,FC,87,75,DF,46,8D,33,10,DC,97,AB,01,70,BB,28,0E,BA,91,44,19,CD,8F,BA,0E,74,3A,AD,A3,AB,31,ED,68,C8,78,89,E2,5C,F6,59,98,1A,23,91,10,1B,A9,FD,47,46,DE,44,22,C0,B1,4F,75,6F,D2,38,A1,B8,43,71,7C,EE,07,8C,E2,C7,ED,16,5F,E2,45,FC,D9,6F,34,D8,CE,D3,8E,63,50,71,39,DA,64,85,88,18,7B,8A,3E,D8,FB,1A,09,F4,DA,B0,13,46,D9,95,AE,AC,68,6F,0D,FF,5B,47,8D,00,93,28,A9,FD,B2,19,B6,C6,3F,28,E4,3B,95,1D,33,7A,A3,4E,F6,32,B3,B3,41,F1,89,41,33,78,2D,51,18,29,64,16,42,89,6D,C5,8B,16,DE,64,A6,6E,C2,30,74,97,29,82,89,8E,42,18,A0,9E,09,AD,B7,BE,DE,02,B4,5D,EE,5C,F8,36,76,94,6F,81,C9,38,7B,39,95,33,AC,42,CD,0B,45,57,B7,E6,49,9A,AF,AF,C1,16,0E,12,81,B2,0F,15,6C,AD,31,14,E7,31,04,98,BF,56,45,B8,D8,46,91,3F,AF,50,EF,41,87,CB,C4,B6,0A,AC,F4,E6,B7,A5,52,DA,DF,82,61,0F,59,89,CB,89,D8,7F,68,3A,34,49,48,BB,5C,6E,EE,6D,01,1C,0D,79,CF,72,61,9B,1E,8F,BC,FB,0A,63,93,59,8E,70,C6,49,7B,AC,57,C9,CB,5F,65,A7,F5,6E,1A,25,B3,A9,F7,C7,C9,81,CC,94,F9,F3,85,26,49,D1,AC,37,CE,D7,BE,CD,C0,DC,3B,23,69,91,7C,08,4C,B5,DC,AE,35,A3,E4,FA,87,EB,3A,85,B4,5E,F6,C6,8D,6B,D3,CF,61,5E,04,D1,C7,81,E5,2F,F9,86,02,AD,6B,6A,29,54,B8,25,E0,AB,79,C6,14,2B,2A,C7,76,8B,0B,CB,43,60,BD,5A,13,30,3D,30,61,42,B8,E8,AA,8C,41,29,90,5E,DF,68,45,CD,8B,1D,DC,9E,CC,16,19,6C,9E,C0,84,F9,C2,3C,A4,09,B3,3B,64,02,13,5A,B4,C5,24,BB,25,A5,5A,91,27,B9,50,3B,3B,0E,02,D1,AB,02,CA,FE,D5,71,36,56,20,39,3E,5C,11,95,31,6D,6B,C4,1E,7D,06,6C,93,90,BF,BE,1B,9C,AD,AE,1F,37,23,3D,DE,CF,95,DA,1E,F5,25,5D,1A,37,C1,A9,15,14,0B,9D,3A,CE,AA,C6,D5,A7,DA,B5,A9,9E,64,6E,AC,9E,64,7A,38,6E,86,85,0D,9F,45,64,E5,2A,33,3B,F5,25,2F,66,97,2F,55,90,00,11,5B,DC,BC,3B,6D,15,12,E5,D6,25,A2,AC,9A,56,38,22,7E,65,F1,E7,E9,FB,42,CB,22,C3,44,99,01,B1,7F,0E,45,B3,1F,A5,F4,BD,9A,81,BE,51,50,49,FE,A4,2F,A3,C6,90,E7,B0,75,21,73,81,9F,88,2F,49,FC,3A,BC,9C,EE,65,80,CF,FE,49,A0,86,4A,BA,8F,F5,95,4D,63,DA,CE,23,0D,AD,E7,B6,A8,FE,5C,D1,A3,81,3F,61,A5,35,41,8D,AC,38,8E,6B,09,CB,0C,CA,DC,B8,A3,2B,9C,03,0F,D3,F7,4D,49,4E,73,2B,BA,54,59,0C,C8,2A,18,F1,CD,21,BB,F4,43,F0,08,12,65,5C,47,CE,F2,29,01,42,AE,5B,4C,A1,B0,66,F2,D6,6E,F1,C5,22,8A,60,AE,4B,20,BF,ED,4B,8E,6A,FF,A2,EF,1D,57,11,12,56,59,78,82,84,20,13,A2,16,FE,4A,54,FE,B5,B1,B3,0D,23,D8,5D,58,F4,D5,85,0F,35,19,6D,5F,B9,A2,5C,59,F1,32,F9,87,0F,25,88,EC,14,CF,FA,3D,8E,CD,C3,39,24,0A,AD,EA,2E,61,99,46,89,CC,4C,EC,5D,47,E9,DF,E7,44,51,53,D7,F4,BC,E6,E5,74,CE,86,46,B1,F2,DC,94,EA,CF,AD,D3,EC,D3,C8,C8,07,03,D9,86,E3,4D,2D,6F,B5,FE,C9,3F,09,70,38,FF,A1,3A,8E,DA,54,D3,62,B0,4D,47,EC,D4,92,E4,44,FD,82,32,F2,95,6A,F0,F1,89,E0,0A,C0,C8,9C,4F,C4,A7,DC,FF,C7,AF,F0,76,99,75,39,90,4A,CE,F6,F4,E1,76,CF,83,4C,36,D1,05,F2,84,EF,BD,5A,07,9F,1C,4D,DD,9E,15,1C,32,36,DC,17,6C,75,6A,B9,1B,84,32,58,8B,14,E5,8D,A6,77,2E,37,77,20,8A,1E,7F,64,82,A0,FC,2C,C1,EF,C1,A4,2C,E0,98,AE,C0,7C,D4,2C,15,40,13,CC,C4,7C,EF,B4,2F,5F,60,FE,0C,5D,2E,D0,12,54,C4,C7,95,93,D4,74,FD,BD,9F,4C,78,62,60,BC,A9,1A,AF,AD,18,51,4D,A2,4C,DD,8E,A0,2C,53,68,17,DF,47,E6,20,39,47,D5,D5,A3,74,66,82,5B,02,3D,87,72,03,95,06,2D,D6,57,A9,5A,91,19,75,F9,BE,B1,E9,C4,CC,95,1C,F3,3D,45,96,E9,80,AD,8C,68,FB,92,B1,69,09,59,D6,BB,33,26,36,B5,AC,22,8D,C3,DC,03,BB,13,EC,CE,A8,0D,5C,FD,89,D4,02,B7,68,E4,FF,3F,D3,D0,06,60,F1,FF,D8,B5,CF,20,05,4A,A0,10,E4,F6,52,A6,A7,D3,52,3D,2D,9A,B5,66,4A,A4,8F,10,46,FF,BD,AD,32,C9,CC,CC,86,A3,C5,8B,78,C0,62,2E,4A,5B,11,C5,04,31,54,BF,CC,07,D2,A1,4D,DA,C5,38,72,CB,6A,B5,21,E2,52,E7,C8,BF,70,41,98,67,76,C3,5B,DA,04,4E,8B,1E,A3,4F,01,E0,8C,0C,F7,8B,03,60,79,CC,F3,55,A7,37,37,1A,5A,E7,CE,7F,05,C6,CC,27,A4,AA,11,B0,BD,FB,ED,57,AB,2C,8D,9A,AE,5D,C9,96,D9,29,D5,1B,BD,B4,82,8B,EE,C7,57,5B,A6,FE,7E,ED,B4,BE,38,9D,9D,B5,5E,62,99,40,6A,F5,5F,29,42,2D,AD,31,50,DD,B3,BC,9F,83,14,62,5C,24,9F,63,4A,1A,3C,A6,73,BF,AD,02,6F,B4,75,47,A1,D7,3B,73,BB,6C,63,3F,15,0B,E9,45,30,66,3F,F8,74,8E,8F,70,D9,9D,BE,27,F4,89,1F,62,3C,B5,F1,E1,21,EC,43,21,79,7E,22,81,B3,9B,78,81,53,91,61,16,A8,94,93,52,0E,77,52,60,EF,A3,AC,0A,96,CC,0A,EC,42,5F,17,8C,4B,E4,27,E7,6E,F5,7F,43,CC,C9,C9,5E,25,46,5E,5C,15,50,05,46,D4,0E,F0,E1,F3,19,DE,D4,49,50,83,4B,52,DC,D4,B4,33,A1,CD,E3,33,FC,8D,A8,FB,30,7E,D7,4B,8E,C7,B1,13,8E,43,B0,C1,81,77,1C,4E,03,66,A2,62,4A,0E,1F,AE,E2,F0,72,F3,3A,B3,5F,0C,4A,8B,D0,34,3E,B9,5A,E2,C3,CF,67,CB,08,FC,F5,A6,E5,9A,78,6A,65,DB,F7,08,D0,F6,89,AE,36,F4,E0,DC,12,FF,CB,48,F8,F8,64,C3,F8,9A,0E,05,64,57,3E,07,59,20,7A,71,C1,E6,00,53,44,3A,A2,F4,E7,1C,56,72,A2,6D,FB,0C,BF,A2,15,4F,2C,E7,27,EC,AC,CF,57,7A,BA,F4,3D,2F,2B,4E,D0,B7,D4,36,B4,D9,13,67,3B,0B,4F,C4,60,A7,26,33,01,95,40,C5,DF,CC,40,33,F5,B0,CC,08,0A,B2,28,4A,2C,E3,79,0B,39,A0,CA,FE,B7,C8,18,2C,72,AA,A4,91,4A,23,EE,DC,E7,61,68,9B,0C,95,2D,9B,F9,8D,27,17,08,19,B3,54,15,62,CF,2E,87,0F,0B,E5,D6,72,A1,FE,1D,6B,CA,37,81,ED,2A,63,B7,41,B0,8E,4B,7B,A4,45,28,E5,AE,DB,47,35,5F,F8,64,5F,C7,16,AB,B4,5F,C8,08,B0,2C,9C,30,89,85,46,31,69,5C,E8,C3,68,D0,FA,58,2B,63,61,11,FA,49,37,B5,38,CE,08,7B,29,93,AF,7E,38,09,4A,FF,C8,15,FD,27,9D,1D,6F,A3,39,AF,A5,2F,E3,68,39,5E,A1,61,24,D8,34,5C,72,13,0B,76,6E,86,6B,23,D3,19,E3,C8,D9,7F,36,D1,8B,D2,4F,A4,D1,02,AF,03,4A,1C,29,0A,CB,12,77,B7,B5,2C,F2,BA,4C,62,9C,FE,14,2F,AE,3B,77,A8,16,84,D0,46,26,35,26,16,73,EF,3A,23,E6,D2,2B,C6,F1,2C,9F,D2,6A,21,8E,A1,90,32,0C,DF,DB,DB,FF,5D,26,5C,8F,D7,76,7C,79,CC,73,91,76,CE,E2,AE,D4,4E,7D,79,90,AD,88,DE,CA,22,50,F9,7B,BC,94,26,A1,32,FB,3D,07,06,FE,27,16,1C,C6,1D,58,9E,0A,24,18,4F,20,1F,DF,2B,D3,49,03,AA,95,DA,D4,9C,5B,16,D5,1B,05,D8,21,B0,88,92,34,BF,C3,09,D2,90,8D,FB,1F,E0,0B,A9,BC,40,10,BF,E4,DA,CB,E9,4B,D9,4F,D9,62,B3,9A,28,DF,87,0F,B1,57,E3,E0,17,19,30,EB,8E,7E,D6,EF,E8,36,C3,46,FB,67,F8,65,3C,FC,82,A3,72,66,AF,8F,7F,11,52,46,EB,34,3F,E5,84,B1,C7,5A,2B,B6,94,1D,DC,C1,D6,4A,1B,86,68,12,94,AE,EB,82,DE,53,F4,D1,56,D4,2C,1D,B3,2E,AA,0B,97,A1,04,E8,E8,0A,90,62,CE,F9,10,57,78,CC,DD,11,31,64,76,8E,EA,D0,AF,25,29,AF,85,2F,B5,86,3C,3B,F4,84,33,F9,8D,9B,62,E2,3F,E9,67,97,0D,79,4D,EC,04,EC,DA,9F,D7,B5,EF,87,FC,EB,8C,0F,24,86,AC,7C,B4,3B,14,94,4D,B2,99,AF,7B,BF,F9,20,66,9F,E5,43,03,DA,BB,29,EE,7C,F1,28,A6,38,EE,78,D8,38,A8,CB,31,9C,5A,3F,11,42,C8,2A,83,78,CF,97,F4,F0,1E,58,C5,22,8A,AD,9E,B2,42,9F,33,8D,B0,91,59,C7,42,01,D3,C9,FE,24,6B,64,DC,27,B5,78,B4,41,3E,61,07,0E,E5,8E,EF,8B,51,A4,2E,D6,F8,63,53,44,04,95,28,84,B6,11,4A,10,D1,CE,3A,1F,D7,9E,DA,8D,79,8E,08,5E,96,82,73,4A,AE,66,2F,E6,B5,27,DF,C4,FA,08,40,5A,48,2E,AD,10,9B,61,00,91,C6,0E,5F,D0,C7,EF,65,DF,59,B1,A6,70,74,96,BB,C7,D5,2F,F1,D7,32,2B,1B,B2,F7,2B,F3,54,A1,BF,F7,35,81,65,9C,86,84,60,5A,9C,C6,7A,6C,CB,8C,0C,BA,83,BB,22,84,60,A4,84,F1,B6,85,5C,EA,D9,3D,2A,EA,0A,2A,F8,CA,16,D0,82,BF,D4,D5,9C,6C,53,B1,26,AB,9C,F6,D7,5A,27,86,47,52,C0,C6,27,40,4E,D0,06,01,89,63,01,C9,B2,14,82,AD,68,78,8E,55,C4,EB,DD,59,02,F7,97,96,F3,7E,21,F7,76,1D,C4,80,82,04,78,91,33,46,54,B0,99,5B,68,2B,F4,3B,66,68,3D,01,82,3D,4F,48,FA,97,F9,AE,17,38,D6,DB,22,9C,5A,AF,7A,D0,E2,86,D0,8A,9F,19,97,55,09,54,09,3B,82,BA,99,0D,47,48,F6,FD,85,D1,48,32,3A,B4,CB,69,E0,90,42,3E,C2,CD,3C,6F,3A,CC,78,E6,35,F5,1F,61,BF,14,EB,AC,4B,AC,05,BA,20,45,40,B7,92,28,F6,E0,F6,66,DA,8A,D1,D0,DD,11,18,49,4B,EA,CB,86,B0,F5,FD,97,71,64,34,13,A7,E5,48,06,08,AE,17,DB,B4,EA,AB,58,D3,00,BD,BD,4D,A7,E3,11,E4,3C,D9,62,2A,67,7F,1C,4D,21,A9,37,8E,28,82,6D,1D,9A,92,6C,F5,72,0E,C4,A8,C7,B2,4E,A2,84,5B,CF,03,54,DC,18,6F,4C,DF,CA,51,EA,FC,FC,4F,04,0F,C3,4C,09,43,20,2C,F8,06,74,EA,4E,80,F9,DF,C4,05,73,8C,6E,A1,54,B5,5D,14,44,A4,0C,11,15,D1,6D,7F,D7,0F,BD,CB,97,5F,71,9F,B2,84,D9,A4,89,03,FE,59,F2,F6,74,42,96,05,B4,A8,DA,95,17,46,58,11,0B,46,57,22,56,FD,5B,C9,07,1D,25,BB,1A,1E,A8,57,B7,0E,C9,84,18,2C,60,02,2B,5F,42,91,5C,26,2E,55,FB,12,C9,7F,96,F1,C8,54,2F,4E,6D,13,49,8F,C4,DE,D2,C2,85,6B,50,64,CF,36,41,99,4F,40,7E,AA,C1,33,66,3A,FE,F2,4E,29,A9,E3,2B,FD,38,6D,DD,02,46,16,1C,9B,29,53,0F,3C,A6,B7,BA,33,F4,AE,46,42,84,EF,50,E7,15,60,CE,CF,D9,E1,C8,71,B6,9E,71,9D,2C,22,9A,9B,0E,F6,27,D0,61,4C,53,4D,5B,09,62,7B,FF,18,B0,47,BB,79,EE,78,EB,C5,B9,39,C8,0D,9E,0D,27,0F,4A,D2,2B,11,6A,10,22,4C,9A,AF,8E,9F,30,5D,24,EA,5F,3F,54,B1,AB,00,F4,E6,EB,9C,A1,CC,B6,93,7D,3F,2D,A2,2C,92,F9,78,27,02,13,94,1A,A9,DC,D1,39,13,6D,79,B5,89,87,D6,69,88,B6,7F,CC,EE,AC,8F,3E,6D,E1,55,77,4D,84,92,DA,1E,F6,52,CD,30,F9,99,2D,44,C9,F0,71,0B,51,EA,57,03,B0,21,75,5E,A4,DD,51,B4,A5,76,E6,3F,51,92,9F,E7,58,65,7A,38,F9,D2,46,01,48,BD,D1,8D,C3,AC,5D,8D,2E,20,E1,40,C0,33,6C,1C,67,F6,85,E4,05,95,0D,A1,A6,FB,DA,EF,EE,DF,1A,74,DC,42,0D,39,33,26,02,DC,F6,B0,A7,81,2D,0B,D6,D8,A0,DD,74,CB,D3,6D,1E,BA,04,EE,B2,E2,D9,85,F2,38,8E,55,31,87,24,DD,08,85,FE,D0,F2,C3,1C,58,76,6A,9C,E3,C1,66,C1,65,55,F2,DF,FD,BB,4C,69,92,F0,2A,54,DF,91,70,B3,03,0E,F2,90,7D,28,C7,0C,E8,0B,26,52,31,47,2C,93,61,E8,89,D6,11,90,15,28,B7,E5,A1,2F,B0,7B,88,67,A7,03,FF,54,AB,CB,AC,C0,79,C1,A7,D5,C2,9C,8B,B4,3D,DC,90,D5,32,86,0B,83,09,77,F2,BF,63,27,11,18,62,D6,C4,D0,F2,63,58,30,93,9E,AC,E1,C4,25,B8,EC,35,CD,3A,35,CB,FB,8C,7D,D0,EA,64,BC,FA,1A,92,31,79,9E,D0,1B,85,D2,31,49,FF,ED,E3,42,7A,D8,4B,04,59,04,EB,3D,40,97,CD,F8,8D,7F,E1,CF,6F,36,15,8A,EA,44,38,A4,AB,AA,6E,9F,AC,27,0A,B4,C0,E4,D0,34,EF,B8,B4,7C,35,0F,74,73,90,CA,F5,7A,2E,D4,45,B3,72,4E,A1,37,8B,C1,BE,3F,3B,21,63,78,90,39,4C,70,30,B1,B7,9C,1F,90,09,F3,E9,D0,35,9E,15,94,D2,A2,16,51,07,F7,F1,96,03,6B,04,82,19,6D,E6,EB,42,9B,C2,9D,76,ED,85,32,B3,6F,61,FA,81,25,F6,53,C1,5D,7F,91,7C,07,93,0D,99,7C,C1,BC,A5,E5,C9,49,8F,19,7A,E0,BC,79,D8,50,67,B2,47,9A,30,CA,34,6A,E9,CB,68,37,9E,30,49,DF,35,82,A6,F3,C0,58,42,29,4A,CF,FF,84,F6,1E,9C,9F,C1,56,DF,2C,1E,E9,BF,0E,86,30,DC,E6,4E,43,0C,EF,D2,52,7F,45,C5,F3,20,C7,5C,D0,67,AA,E9,F6,06,6D,45,98,E5,70,D9,A8,C4,71,89,5A,7B,FA,E1,0A,0A,AA,F1,A2,15,BE,85,31,A9,59,CC,C4,1A,77,B2,46,CC,1A,D7,EF,47,01,A5,81,43,FF,66,4D,0E,9F,77,BC,8E,2A,AF,05,51,60,84,D9,4E,13,CF,63,C5,7C,3F,29,27,A8,6D,FE,C2,EF,E6,95,B4,18,C2,D6,F4,B3,CB,91,2C,0A,3F,29,97,71,55,9E,91,EC,2A,FE,ED,D0,FE,12,5B,17,F0,F3,C9,1D,44,54,08,BB,82,37,46,16,87,58,29,5D,84,9C,CC,2B,24,91,CE,A6,06,45,9A,FD,B1,5A,DF,90,E2,16,C0,37,71,19,E4,40,4A,F2,CF,BB,08,C6,7C,18,3A,3C,6D,FD,88,EA,2B,33,87,B7,31,E1,C1,75,A3,24,41,E3,9B,FD,39,2D,A9,76,DB,D2,36,78,B7,18,30,4E,F6,D1,32,78,A1,F0,C3,E3,2C,8F,92,7B,8A,4D,8F,F6,46,60,A8,B6,52,36,4D,FE,CF,70,84,6B,6F,97,8C,71,E5,5F,CA,F0,AB,A9,BA,07,F5,F3,FF,9E,99,AC,87,C1,9A,64,F8,99,61,99,63,ED,56,A4,AE,B1,14,6E,79,BD,A3,45,5F,89,94,48,37,B6,E7,46,E4,54,EE,8C,0F,76,EC,C0,7B,91,DB,1E,92,27,78,9A,2D,07,B2,36,E8,AC,A4,84,90,D4,C8,20,A8,2B,34,08,3E,F8,EE,F4,D8,BC,4C,99,03,51,33,9B,8E,FC,95,9A,67,90,C2,2E,9A,68,80,25,15,62,9C,7C,77,C7,2D,0B,15,D0,F1,48,F8,6D,40,43,81,FC,3E,D4,34,D5,0B,27,82,23,9F,61,F4,37,73,31,CC,0E,DF,4B,39,70,FF,11,3B,96,C0,2F,AD,08,42,62,FE,78,9B,95,DD,59,82,BF,4D,32,F5,56,CF,1F,08,B8,1F,F7,B6,44,C2,83,94,8C,43,97,A2,CF,67,5E,C7,0C,E2,27,90,5F,9E,F8,96,03,48,9A,12,F2,4B,43,F6,B4,B5,27,59,1D,9D,65,DE,72,7B,1B,3A,8C,DA,4D,1D,50,77,57,67,0D,AB,40,73,2A,EB,7A,66,DD,A1,DD,20,65,D1,3D,E9,B2,E2,B3,C1,82,CB,BB,AE,9E,7A,5D,2D,94,50,5B,A0,BC,68,1B,DB,FC,55,71,AC,75,50,4F,89,82,DA,B7,6C,26,9B,D1,29,F4,6B,C3,31,A4,1B,E7,9E,A0,CA,3D,1C,97,15,23,21,E5,88,26,88,C2,A5,85,A4,80,74,F3,47,90,4C,C3,1D,4D,3D,63,C4,68,41,6F,50,A7,D5,E2,A7,B5,E3,7C,10,B1,50,F5,7E,5D,33,54,42,D1,54,2A,17,D4,D9,29,EF,52,EA,66,75,69,50,75,F0,85,8F,EE,46,37,0A,E4,E2,95,BB,62,3C,26,A9,7B,28,9E,E5,B5,38,75,93,CE,6C,64,06,A9,1D,63,1A,59,EC,78,23,E6,EB,0C,D2,5E,C9,D5,B4,66,EB,CA,3D,91,D7,97,9C,96,73,BF,5B,E9,EB,5A,5D,76,AB,37,68,CE,45,57,A2,48,CF,12,45,1A,02,C0,7E,E9,BE,F6,DA,75,69,06,74,8E,06,90,C7,63,7A,38,59,77,35,A3,AD,93,A8,6E,81,77,81,28,E3,2D,64,7A,90,3F,E8,4F,E6,8B,AC,3A,9D,B5,7E,F4,32,17,A5,73,C0,F6,6B,0F,A1,85,C9,17,0B,DF,00,45,50,39,74,07,D0,BB,DC,95,18,4A,0A,9D,0A,92,09,F9,8B,43,CA,CE,8B,CF,D9,4A,68,0F,FE,E5,21,F1,E1,F7,DD,C9,6E,7E,DF,36,2C,91,3E,EA,F3,8A,B0,A1,B4,A5,67,02,EE,4B,AD,E6,0C,C2,A1,64,DE,EC,05,72,3F,17,41,5C,05,8F,A5,AC,21,CC,B1,96,97,DF,CB,B1,02,CF,EB,8C,0A,2F,68,81,00,CA,2C,31,AA,41,38,65,91,2C,6F,B2,BA,51,D9,D6,6E,DE,64,34,17,B5,B5,34,C6,5D,53,1C,94,E6,57,F5,8C,1D,A7,D2,86,84,D3,37,EC,F0,E6,05,5B,A8,64,2E,EF,75,04,80,A5,3D,D6,59,3C,EF,B7,CD,44,77,CF,94,A2,D3,E8,2F,A1,B7,F9,BE,A3,67,D5,41,48,75,28,29,C2,C2,B3,6F,2C,DF,3D,BE,F3,F3,E1,59,E4,D6,06,05,FA,A7,08,7A,06,0C,EF,F9,1C,FF,FE,4F,F6,BA,3A,12,25,FF,85,B2,25,82,25,A1,87,11,62,0E,35,57,44,AB,43,C1,DE,9F,76,A8,FB,08,D8,C3,2B,CB,DE,E4,CF,39,E4,07,AE,8D,85,70,BE,F7,23,AC,66,57,0F,01,3A,1A,D3,9A,4A,70,82,F8,45,92,CE,56,0B,CD,BE,5C,00,75,77,6C,2C,3F,43,4A,DA,90,61,D9,41,C1,D4,C4,07,70,62,5D,BA,78,49,9B,5A,48,5B,96,16,EB,4E,71,C5,FC,76,DB,4F,F4,B1,55,38,73,6B,0B,E7,09,F8,52,8E,7A,EC,8A,79,18,0F,60,E1,2F,CE,B3,A8,FE,7D,2E,18,A0,43,4E,C8,01,31,B6,0F,FF,8F,A9,48,27,F4,F4,B8,A4,D1,13,14,DE,D6,B0,99,C0,DC,B3,24,EE,FC,71,89,FC,20,E6,95,B4,92,4B,3F,D0,23,0A,69,18,4E,72,4E,20,F0,C7,C6,32,FF,16,67,56,6C,21,D4,CD,98,C0,73,3A,D2,8D,76,3C,68,3D,B8,84,B8,36,CC,EC,62,65,0D,7D,01,93,B8,E3,6B,C7,FE,7E,42,BD,D0,10,8F,43,7A,38,A8,F0,85,27,54,1C,B5,50,27,E4,14,73,CB,60,79,E1,F0,BD,2E,F2,AB,6A,FC,63,4A,B5,02,B7,6E,65,86,4B,98,F3,E5,EC,FC,FE,9D,F8,F3,9F,6F,34,32,CA,2C,BF,6F,4B,E5,05,00,65,98,A4,DE,9E,F6,5F,97,AB,16,E8,83,E0,61,9A,47,27,50,86,3A,61,A4,77,3B,8B,F9,CF,24,1E,14,34,E1,CB,B1,04,D9,59,2A,16,03,00,D3,93,54,91,F1,42,06,24,7B,50,60,0E,ED,EF,F0,E7,F4,0F,9C,AC,6B,3F,EE,39,BC,58,90,03,6D,6E,05,61,4E,88,D2,81,4D,EC,8F,A1,42,55,CB,43,0C,A0,60,7E,C0,0E,19,F7,BA,7E,6B,D3,88,C0,0C,B8,36,4E,D7,00,4C,95,F6,F6,49,49,64,22,77,03,92,62,1A,AB,91,C7,03,B8,30,06,5F,36,52,0D,DD,34,44,13,E7,1B,68,F0,21,8B,A1,8E,C0,AA,62,8F,05,68,F9,38,EF,4A,A2,51,30,A3,89,53,70,32,7B,A5,58,6E,B9,75,27,39,15,17,5B,37,BF,0D,1F,D6,FB,8C,66,8C,F2,36,67,8A,1C,CF,28,46,DF,66,83,D4,8D,FE,0C,D8,1F,A7,C3,93,FB,CC,BD,1C,0C,22,17,A5,AD,17,77,A1,55,62,63,CB,FC,85,9D,F6,07,7E,E8,E2,66,42,26,01,92,55,11,32,FC,DC,BA,F1,21,12,BD,78,41,C9,C4,70,CB,AC,8B,18,8C,DE,33,1A,54,6A,91,BC,3E,43,97,CD,73,86,12,48,92,C2,63,21,3A,DC,4D,CF,54,62,08,A5,E7,22,49,6C,3F,35,21,46,25,56,00,2B,D1,10,0C,05,BE,DB,10,96,69,F7,2D,7E,A1,F2,F2,50,B3,8F,FA,98,28,1B,B7,09,BC,1B,8B,CB,69,E3,2A,36,33,91,E4,66,2B,86,70,1A,3B,55,28,9A,C1,54,79,BD,C4,C0,E5,89,FE,7A,C2,3E,1D,C3,2F,A4,8D,4C,89,D8,62,15,C2,16,CE,44,86,98,F1,4D,26,CF,CD,85,CB,98,F4,98,23,8B,66,8D,59,01,72,F8,59,83,B3,19,EA,9C,D7,B2,AB,E0,5B,C5,92,94,81,DD,CE,E2,3D,90,D6,40,C1,C2,91,FC,52,65,6B,4C,7A,F4,ED,42,8A,32,F4,A0,3F,F3,1B,DB,E2,2B,81,8B,3D,3C,BA,41,3B,FB,69,47,55,42,4A,B2,4F,88,58,1A,CE,63,64,E7,E3,02,8B,09,30,ED,F3,B6,F7,19,BD,9A,5B,79,89,EC,16,11,01,34,4D,78,E2,E4,34,99,BF,84,50,36,79,4F,FF,C5,77,7D,78,84,D7,0D,EF,7A,9C,4B,07,33,F2,CC,16,FC,B9,17,E5,A2,10,C4,B9,E7,E6,D9,AD,8D,78,18,D3,A0,A7,08,28,9B,A6,FD,50,27,1C,5D,7C,42,67,28,EA,33,C9,93,69,F4,60,4F,BB,12,4C,2B,36,67,39,50,AE,34,D5,18,5A,A8,E0,C7,40,21,3A,4A,87,28,93,5E,E0,40,77,79,35,02,AA,36,B4,7F,77,5E,32,DE,19,38,E0,07,07,C4,3D,6E,B8,FB,FB,97,35,62,C9,D9,98,62,89,C4,41,AE,D9,9A,4D,77,67,EB,99,D9,B3,85,FD,76,31,BB,FC,4F,47,10,ED,99,A5,B4,97,4D,9F,28,EB,4A,EF,4E,23,94,39,6D,F6,A6,2C,4E,DF,D5,C9,54,AB,20,66,70,63,38,42,C8,92,29,BB,DC,E2,D4,D6,0E,1C,14,37,DD,74,9C,16,62,28,BA,44,FE,D9,83,8B,A1,C8,40,1A,F8,4F,16,32,82,B8,1E,A6,DA,E7,90,E1,12,B7,B4,54,6E,DF,B8,86,A2,BC,E9,CC,07,9B,9B,D1,18,4F,B0,48,A3,4E,87,E9,78,C7,C4,CB,FE,3B,EC,C6,24,33,DD,6D,0A,88,9E,2E,BE,40,61,48,E0,90,84,D9,12,A1,B1,19,0D,04,E2,F6,AD,BB,C1,11,77,3C,83,A5,E5,EF,D3,41,46,5C,2C,7C,90,EB,20,E5,1F,FA,5E,94,FB,DA,64,DB,BB,B6,AD,0E,0C,35,7E,BD,B5,FC,17,FE,07,C0,59,68,B5,80,61,C1,D6,6C,F0,31,63,54,25,16,38,4B,E1,80,9E,50,13,1C,2D,CB,1E,D1,48,19,46,1C,F7,63,23,A6,2D,D9,18,9B,91,12,E5,E5,4A,86,C2,07,6F,6A,D3,BE,92,8F,88,33,EC,02,46,7D,72,BB,E6,B4,CC,D2,55,BE,A8,5A,01,F9,0B,13,DE,9E,55,E2,E8,21,B3,C4,BA,9D,77,2D,44,A7,D4,A4,89,75,DC,EF,4B,A9,D6,D2,BA,DD,D1,5E,BF,90,50,F6,C9,EB,E2,05,DD,27,80,9E,1D,9F,6A,2E,EC,D5,77,98,2A,66,B3,DC,5B,C7,8C,5D,AF,BE,E5,D0,97,D8,3A,D0,4E,EE,C0,20,03,6C,6E,5F,5A,F3,01,E5,D4,E8,1A,22,4C,17,4B,E1,06,DA,72,9C,A4,B2,08,70,69,27,01,5C,2A,FC,F3,94,9D,E1,C5,79,49,C8,1A,E2,9C,A3,EF,53,BE,DF,CA,74,36,65,EF,FC,81,40,1D,DE,FD,37,C8,7F,9A,F0,B2,6B,D9,24,28,FA,7D,8D,D1,8E,1B,51,46,12,BD,90,B5,3B,76,87,96,8B,28,94,B4,7B,8F,46,43,51,0B,E3,60,37,E3,6A,18,8A,AE,D0,0F,A0,2F,21,40,5F,AD,30,25,5B,73,D5,49,FE,B7,F2,61,62,15,8F,EB,93,10,65,8E,70,E1,C0,C8,C1,5C,4F,BB,FB,21,ED,BA,0F,B7,77,E0,D4,F4,B7,D1,61,6E,D9,5C,E3,6D,5C,98,88,BA,31,13,28,BB,21,3D,1E,34,0A,8C,18,C9,B8,3D,20,AA,F3,63,6C,51,1A,98,88,82,67,ED,F4,E9,92,96,BA,13,90,C3,50,1B,DB,1D,F3,91,7E,AA,02,AE,F1,08,58,BD,3E,2A,E2,2F,93,73,E9,76,A6,81,CF,E0,92,CB,D2,F8,DB,F0,81,C3,89,05,DB,89,D6,2E,CC,42,BA,B6,D5,58,33,25,97,6B,14,80,3D,35,63,66,11,A2,93,52,AF,79,E7,3F,E9,21,65,9C,48,03,45,80,B9,F1,38,A6,73,E9,AE,3E,6E,E9,81,DF,09,99,52,2F,94,80,79,1A,69,53,2C,C1,93,05,91,2A,14,D2,43,1F,4E,10,91,14,28,5F,3E,32,8C,D8,32,9D,E3,B2,C9,05,25,FE,58,C7,C0,98,4B,94,67,A7,38,1C,91,72,B3,01,65,D5,1D,96,9E,7A,40,A5,19,BD,3C,63,65,40,62,BA,F8,88,D2,87,60,B4,5B,7E,86,3A,8F,DD,90,88,B0,27,74,DE,66,17,74,A3,40,83,9A,5E,70,66,88,C1,B3,0E,B0,D0,20,0D,51,7D,4C,97,58,17,46,B6,BB,2D,D3,84,66,52,8D,40,0A,2A,88,18,6A,7A,37,55,EB,AF,18,52,18,73,FC,13,CC,34,74,45,4F,F7,0D,BE,DE,D0,E7,6C,1C,09,A4,D3,6A,7A,12,AF,5A,D5,17,0D,70,8D,71,D2,43,E0,03,D9,7C,17,0D,21,70,1E,34,80,9A,8A,92,D2,3E,10,6C,C9,8D,D0,2B,61,8F,10,D9,50,65,5A,49,CD,3C,67,9B,C2,31,52,1C,B5,01,44,A7,61,FB,01,B2,80,A1,EA,F5,6F,E4,5D,43,4C,2F,35,44,D7,9B,65,93,57,1C,D9,45,AE,0F,0D,8B,52,BC,7F,32,49,06,DC,92,79,44,49,D5,DC,58,7A,FA,9D,42,31,79,D8,F4,30,6F,E1,8B,B0,E8,96,9F,9F,E4,92,A5,98,E5,68,8B,48,6F,F2,99,89,51,FE,7B,C4,39,95,82,70,20,78,71,17,87,F5,82,3F,0F,BF,C6,93,08,DC,9D,99,8E,A3,2E,1D,98,31,0F,F7,66,1B,C3,A9,BD,D6,F7,C5,14,B9,0D,9D,92,FA,E4,AF,A0,AF,E8,52,ED,82,99,A7,82,AA,09,BF,FF,07,4D,A2,B7,5F,42,75,0C,DB,94,4E,1B,5A,0E,99,C1,8D,FA,80,82,65,E5,CC,5C,AD,13,F9,C0,B0,27,7C,A8,58,D0,28,3A,4E,61,59,74,34,DE,9E,20,14,88,3E,E2,D1,24,81,8F,BA,6D,61,43,F4,8C,54,EC,B3,AF,F4,43,E1,8F,65,F1,2C,00,29,64,1F,77,B5,0D,15,60,99,B8,61,BA,42,78,9F,1A,CB,36,DB,37,CE,4A,16,20,84,3C,24,F4,CA,0A,52,EC,34,DC,DB,E1,BD,0E,0A,2C,74,45,80,68,F5,61,93,0F,8E,6B,D9,68,29,3B,23,E2,C4,89,80,29,E3,E0,E8,83,1C,4A,AF,8F,5E,64,31,0E,93,C0,36,7C,8B,06,A2,43,1B,2A,C0,7B,8A,A3,BF,BD,11,2F,16,73,71,D3,8D,A2,AA,C9,22,9C,86,81,9E,91,DD,F9,74,23,51,25,7C,FE,37,C1,13,77,49,BF,90,41,D3,5C,0E,D0,91,31,0E,E6,DC,BF,D0,6C,35,A9,46,1C,D0,20,0F,A8,5E,C9,4E,7A,88,29,7A,0C,0F,1E,27,32,F3,2A,D1,24,C4,E2,46,5A,A3,AD,24,B4,E3,F3,7D,C1,A1,01,30,E9,05,E5,8B,6B,22,A3,44,E7,8C,95,F7,DD,B5,70,12,C6,B0,54,BA,BD,38,5C,38,C4,C0,29,07,A7,FE,F1,E4,DE,ED,C9,59,52,04,79,CC,5F,67,CC,5A,FF,BC,31,6C,C9,EF,98,1A,C1,88,8A,E7,47,15,80,87,FD,0B,D8,65,63,45,A0,F1,05,4E,E6,E6,AF,F3,1F,B9,0E,2E,64,7E,3D,3F,B2,A4,C2,38,69,DD,95,B4,74,45,B4,7D,E1,0E,AB,CE,ED,EA,33,9A,0D,44,44,17,A5,AF,FD,38,17,1F,B7,44,BA,69,77,7F,FB,01,AF,48,A3,E1,59,33,2E,4F,08,D7,44,3B,C4,80,BA,39,53,8D,B2,22,7A,40,2C,FC,13,13,23,8D,49,27,2A,10,05,15,16,69,B6,13,E8,68,0B,D7,2B,F3,BB,13,8D,B7,B4,27,68,22,AA,95,70,DE,EB,34,4C,93,55,E9,56,C9,5E,7C,18,EB,89,07,28,BE,3E,1B,39,6B,9B,20,E7,2C,7B,46,3C,58,E8,A0,7D,94,53,12,E7,27,B9,F2,AC,51,15,1C,E4,E9,1E,2A,3B,0A,91,CA,51,08,45,42,55,BD,E6,BE,41,11,76,14,1E,B3,78,D8,96,1F,36,FF,1D,11,82,75,02,07,73,97,5F,F8,54,25,9A,03,FC,D5,CD,FB,D5,05,DD,F4,C4,D2,DA,86,F2,22,67,1C,2D,BC,B9,FF,B4,AC,38,99,53,D5,CE,3C,CB,9D,3D,41,54,E4,57,D1,1D,E4,39,E2,D0,70,FE,94,16,14,46,D1,26,6E,2A,66,4F,17,59,B0,39,8E,20,FB,76,45,AE,0C,20,89,2D,7D,00,E9,59,0A,47,27,6E,AA,93,BB,D3,7B,3C,0C,D0,F5,E4,C8,D7,CD,BD,7A,FD,3A,3F,E3,57,44,21,6C,CA,98,D9,7A,BC,4B,CB,CD,F9,77,B6,4A,34,F5,2E,CF,AC,18,75,46,A6,AD,77,6F,60,7D,39,4E,73,D0,55,6D,D4,B8,E1,3A,2E,51,7A,F8,34,79,8E,DA,51,1D,A5,38,21,9E,66,3D,F2,03,57,25,68,34,8A,C6,7B,A7,1E,AA,6A,56,3B,77,4C,69,D5,ED,1B,C2,E8,BD,74,0A,A5,70,2E,C9,65,22,89,50,AA,6D,5C,D0,B3,9C,A7,38,9F,DF,D8,42,16,50,49,6A,25,B0,49,02,64,31,6E,67,67,EB,A6,D2,00,A0,58,4B,27,C8,78,9D,05,7A,DA,AB,B1,13,3C,B6,37,B1,0F,AF,92,23,9F,A5,D1,95,F1,A6,A6,A3,A9,75,9B,59,84,A8,C8,D0,C4,83,EA,09,F4,CA,AD,69,35,06,DF,5C,75,65,83,8B,32,DB,7A,69,B2,AF,14,56,FC,84,F3,FE,FF,0B,7C,CE,DF,E9,C8,F8,CD,24,05,97,BC,A1,78,AF,1D,4F,06,5D,3E,D7,FC,A7,4C,A1,5C,9B,71,40,FB,6E,15,55,47,5A,E6,50,3D,3C,94,F9,11,05,58,39,BD,0D,B8,CF,75,35,9D,69,91,39,DE,1F,D0,D7,F3,B5,F6,3E,08,47,B3,F9,D4,CA,97,A3,DB,24,C7,8A,A7,FA,1D,EE,56,D2,9A,91,D8,B8,E1,7E,2A,E0,7C,45,9A,DB,12,DC,F2,9E,E3,46,43,CC,EA,C4,E4,45,89,BE,53,C2,2C,EF,F6,3A,FF,37,85,7B,8B,07,FE,C7,83,EC,FC,5F,A1,CA,C6,B7,E7,68,9E,14,C5,40,1E,BC,BD,DC,18,CF,7C,71,13,FF,C8,FE,93,29,26,A9,2A,6D,2B,DF,83,95,EE,75,C0,A6,6B,CA,1F,BD,AA,BF,25,34,39,D2,A5,96,AE,E7,75,C5,2C,51,E6,E5,19,5C,15,47,DF,2E,71,09,2F,B0,A7,67,67,54,B6,66,F8,F6,E1,D1,42,50,53,0E,78,57,A6,4C,3B,0A,0C,0E,30,83,3D,D0,8A,18,7B,FE,5E,5F,C0,4C,E0,80,CF,0E,B6,12,DA,94,A0,2D,7B,3F,D6,3A,52,94,91,5A,55,94,D3,10,CF,1A,00,9F,C3,3B,32,26,34,85,71,8A,6C,28,84,EA,E1,66,53,74,4F,4D,C6,58,65,78,6B,34,EB,EF,88,11,6C,13,EE,7C,D6,1E,CB,E1,4D,7D,B9,68,27,43,6B,58,43,D3,6A,53,04,BE,1E,7C,E6,70,CF,99,70,2B,01,3E,04,F3,8B,22,FE,B9,D2,3E,FD,F6,5B,FB,16,AB,15,43,D9,F1,5E,5C,83,C9,19,6F,F1,81,39,2F,4D,6D,10,57,8F,B8,37,DF,3C,1A,91,A6,8E,44,CE,C9,43,85,B0,D5,13,9C,4D,49,5E,0C,E5,75,72,49,D1,A5,D4,A3,3C,F6,A9,AF,2C,F5,A9,E5,6F,B0,7C,AC,02,66,90,E2,E2,B5,C3,F4,F9,E9,D6,DC,0E,B1,CC,70,5F,99,84,52,F3,FA,6D,D5,09,97,D5,71,E2,0D,90,A4,EB,02,45,45,5B,2B,51,C6,2F,31,67,3A,FA,07,EA,D7,0E,E4,69,90,CB,2D,7F,99,1C,2B,58,57,96,AE,53,35,4D,41,70,58,B2,28,4F,3C,DD,0E,53,69,8D,33,F6,B9,4C,93,36,03,C4,D9,BC,8C,80,BB,B9,25,88,4C,1E,82,07,B3,AC,E1,8F,75,2F,99,14,83,B4,21,7C,E0,F1,26,4A,05,24,0A,BA,CB,F0,4E,5C,CC,84,60,93,4A,62,C3,DB,94,6C,10,37,BD,AA,B8,92,40,DD,7D,9F,BD,A1,C3,91,DD,D9,C3,B1,67,71,86,46,C3,B3,37,A4,EB,F8,22,DC,2C,8D,41,15,A6,5A,3E,B4,87,5A,AD,28,E3,9B,25,BE,D7,7B,5E,85,12,74,81,55,7D,14,AF,62,D2,3D,C8,FD,74,37,9D,48,E3,3E,88,82,32,2D,5C,BD,D8,EA,EA,47,95,40,E0,00,76,7D,87,CE,D1,4C,05,FE,D5,27,05,5D,EF,0E,86,0D,79,66,C1,90,85,8D,A9,10,17,8A,AC,70,6F,A2,EA,6C,5B,E2,74,D2,86,35,E1,F0,54,77,73,56,0C,36,F8,EF,9E,4B,CA,8B,F0,A1,12,5E,1A,11,FC,6A,38,66,EA,09,91,27,27,92,35,2F,3C,A0,75,6A,4F,02,A2,F3,8A,A6,01,72,5A,C8,A9,B3,9D,27,84,1C,E8,A5,C4,23,48,14,89,9C,42,8C,53,CE,E4,67,EC,34,61,F2,FE,DE,86,EC,56,4B,DD,D2,BB,0F,44,5A,3B,DC,5D,2D,1C,A8,60,F4,99,9E,6B,CF,2F,CB,51,D7,C1,CD,B7,15,31,6B,0F,58,A2,22,F7,F1,76,97,7C,E3,68,81,FA,F2,BB,94,F1,95,E2,7E,8D,46,FD,63,FC,E2,4B,71,C7,93,65,B7,A2,7D,9F,65,25,8F,A9,2E,E3,47,7A,6B,BA,86,BF,32,89,99,D5,17,E4,D1,F9,E2,80,C7,25,72,A4,AF,93,10,65,83,4B,FF,07,C5,A2,86,21,15,1D,F2,4C,4A,D9,40,AF,AD,87,EB,EF,33,F2,D3,D4,B3,15,C1,24,AF,3D,74,9B,4F,72,A7,8E,EF,FE,F9,94,27,B0,44,A4,1A,86,CF,A6,45,58,1A,D0,B5,23,95,EB,C0,2B,1F,91,61,E0,5E,11,03,55,9B,1F,44,D7,DD,BE,BF,F3,1D,F9,4C,FC,B6,E4,25,8F,CC,68,D5,43,48,73,62,88,C7,48,3F,6E,E9,34,41,6C,89,0D,E3,2D,FA,D6,39,06,60,54,80,B9,27,B6,F7,46,99,A7,4C,99,EE,AF,BF,17,AE,33,4A,17,AD,F3,26,F8,E4,93,78,A5,E2,3A,24,8C,D0,20,E4,25,7E,1F,C0,55,EF,CF,6F,8D,AB,5E,77,1A,88,FC,4B,3E,11,3C,83,5D,4F,1F,96,83,08,DA,D1,7E,C9,25,60,6C,6F,BF,2C,83,CC,94,A4,1A,C3,2B,68,8F,4A,BD,56,43,64,E2,DC,6F,3F,35,E4,E1,B6,C1,D7,97,84,6E,26,B0,0C,99,E6,45,41,42,AD,2B,9E,AB,16,E0,7E,93,50,24,E5,19,7B,F6,46,7A,25,A6,DC,3D,62,AF,8B,3C,93,4E,74,12,55,C9,A3,83,17,B5,B8,F6,C8,72,43,2E,D9,5A,48,28,63,12,86,49,74,E2,B6,7B,32,D8,97,2A,FE,50,2B,D2,04,56,76,1B,6C,F9,66,33,A8,5D,9E,FE,6C,76,9E,C0,66,E9,4A,6B,FC,02,44,DD,DC,07,84,6B,17,B4,79,72,16,AC,50,7D,3F,2F,A6,8D,58,89,E4,D6,32,36,28,13,53,2E,F2,FC,C1,21,A8,A4,E1,B3,92,A7,02,D6,A5,87,EB,3A,FB,3D,4C,3C,F9,8C,8E,C0,60,E4,45,85,03,90,F7,C7,79,6E,9E,C9,1A,7A,19,0B,05,B4,EE,C6,C2,88,59,AD,1A,9F,BE,57,E3,48,B9,78,FF,BD,2A,40,0F,68,70,48,D3,9B,3C,07,A3,D8,0D,CF,9E,A7,88,7D,2B,E4,87,A1,B3,B6,0F,88,69,C7,8E,B0,B5,DB,2F,69,89,FA,DF,E2,25,5B,17,5F,61,5D,6C,0E,95,35,08,B6,25,A2,9A,E2,22,8F,AC,19,8C,DD,DC,25,91,FB,9B,DB,D9,FD,EE,BC,B4,CB,2E,69,AB,0B,C3,B4,73,E2,BC,62,F5,81,7A,9E,A4,32,A6,08,43,05,D5,40,B5,F5,0C,81,4E,C2,04,4C,47,5E,6E,35,C0,9C,62,52,6A,86,F8,5A,E6,2C,53,DC,AF,E6,55,69,70,05,19,5D,63,DD,22,ED,B0,13,28,3D,42,AC,02,EC,6C,1B,06,4E,8C,A9,14,54,ED,F8,03,3F,EA,0D,74,F9,10,C4,A9,9A,BF,CE,F4,2F,EA,C7,DE,13,69,C8,8E,4F,B8,F5,C4,F2,CA,58,A1,E3,C2,61,77,63,61,84,84,94,B1,A1,6E,C1,8C,87,4E,14,CC,DC,1B,A4,32,42,9B,C8,E3,32,DA,8A,11,FF,5C,C0,DD,55,3D,18,F3,C5,60,AE,B7,63,BE,7B,04,18,95,AA,31,F1,22,D7,44,9A,0A,45,6F,6A,A5,A0,73,8E,7C,91,FC,E7,DA,E8,CA,F6,60,66,91,C3,A8,B3,3C,09,D2,87,CC,9B,5B,B1,38,CE,91,71,54,25,73,8E,1D,EE,3B,E6,67,A0,4F,36,01,74,AD,92,F6,A9,52,66,47,EC,70,B2,8D,A2,6D,BD,3F,87,46,95,04,D6,DF,AE,3F,BA,5B,F4,1C,AB,23,F1,F6,84,F3,97,72,BF,0D,32,B3,23,9D,FA,E9,7B,0F,72,F0,BD,39,2B,25,16,04,11,DF,4C,E0,59,C7,9A,9B,9E,07,13,D0,00,AE,E8,B8,A4,C8,D7,86,91,C2,13,EE,62,5B,A9,9F,70,7C,E8,55,E2,A2,5F,32,BB,49,34,18,45,3B,65,D3,18,D8,56,2E,27,6C,29,04,D2,90,80,E6,13,4F,4F,BA,31,C3,23,53,B3,42,4A,E9,A9,0A,C3,39,37,25,4C,71,F6,88,4C,DB,B5,E3,79,56,AE,5A,BB,27,DD,9B,16,3A,58,66,67,48,1A,50,DF,90,68,90,62,34,36,08,28,F5,AA,4C,A9,40,97,A4,32,9C,F6,AE,FF,25,AA,4C,81,E8,34,21,7A,D9,5F,29,B2,FC,2B,A4,A0,66,67,7C,73,17,C6,0D,B6,7E,62,84,99,F8,B3,9A,BA,A8,42,5F,8E,A3,D6,99,3E,D8,5A,4A,38,54,B1,92,71,AC,CB,AE,81,2A,D8,C7,72,A2,A5,DC,A9,F7,ED,D1,48,2E,81,62,EE,46,78,FE,8E,67,F9,D6,30,AD,DB,AE,B8,C3,F7,66,CA,A6,0E,BE,F2,04,BC,FD,38,5D,6E,81,52,3B,CC,90,56,E6,B7,98,A1,31,C6,61,BC,8F,71,32,BD,0B,68,23,C5,03,E6,59,91,D8,BC,7C,AB,D9,B6,35,74,EA,08,22,92,79,4B,82,6A,E4,0A,50,75,DC,F6,87,15,30,DE,1D,19,AC,8A,F8,F0,C9,1F,42,E8,4F,BE,FA,9D,47,59,C4,D3,47,E4,86,A0,56,17,4B,51,1F,62,58,77,CA,3D,6F,A1,D0,FD,95,B2,6C,9A,BF,A8,A0,3E,D0,39,3A,75,B2,66,56,EB,79,85,F3,57,E6,88,8E,53,56,E4,A2,F9,1B,F9,53,D3,DA,E4,F7,C1,A6,79,FD,5F,6F,F0,B2,E7,02,F3,29,C4,91,0F,DB,AE,BF,13,B6,48,BE,03,2B,4E,0D,E3,E9,72,DC,AE,F5,1D,41,75,3A,79,31,AF,71,92,FE,85,5A,93,F2,6C,92,3E,85,35,1E,DE,0E,11,2D,14,DD,60,60,52,7E,AA,FE,A6,8B,96,3C,8A,20,DE,8C,5E,E1,62,FB,EB,6A,E5,19,D5,EF,F0,B4,61,CC,B3,99,6E,41,A9,6B,24,1A,9B,53,AE,63,B8,12,0D,54,6E,7C,14,D2,0F,7E,9E,E0,0C,AD,B8,16,60,17,97,57,AD,BF,22,F1,42,D3,C2,49,56,D8,9B,B0,C5,97,70,E3,73,FF,D9,54,26,AC,AE,58,D4,BE,3F,02,73,C3,7D,36,12,B7,EA,5B,2F,12,69,A7,C5,23,0A,EE,1E,86,A9,23,8F,F0,3B,09,61,21,2C,22,71,77,4B,41,8F,07,1F,EE,62,1A,55,A0,6F,CD,BA,C1,A5,11,19,28,00,D6,33,7A,D2,E0,08,AF,9C,0A,BC,19,73,F5,DD,6D,12,A5,3D,76,88,10,78,4D,30,EA,F7,7D,3E,AB,A5,CB,8B,2E,D2,7C,29,78,FE,57,B7,47,1E,F6,B0,E5,70,2F,25,B6,D6,A0,ED,9C,2B,76,B5,7A,CC,E1,7F,8B,2E,30,B5,71,AD,04,4F,76,FF,94,BB,5A,70,64,68,3B,79,A0,FD,3D,8B,E1,B4,F2,1E,96,AE,C3,36,56,7C,78,F5,6A,3C,9E,92,6D,DF,24,98,18,CF,C8,9B,1A,8A,1C,41,C2,00,3F,EA,A2,28,1F,7D,98,9A,A2,37,C0,9B,9C,AD,2E,61,F2,F5,34,40,B7,57,83,C4,FC,11,2D,F1,12,5C,2B,6B,14,2C,85,BF,2B,F9,81,CB,F2,A9,97,58,EB,30,E9,39,78,D4,F7,87,D1,E1,99,6A,7A,CD,5A,F2,7A,D0,FD,3B,E7,A3,54,33,15,A1,54,F8,D8,3B,65,0F,F4,A4,AC,CC,23,4E,D2,C8,9D,50,11,28,A1,87,74,82,29,43,B4,79,0E,06,20,1D,F2,6E,CF,F0,A2,45,40,0F,7E,B4,3E,2C,67,0F,1B,BF,CE,E2,6B,92,45,73,9F,E9,82,90,C2,AD,E9,8A,BB,57,29,29,46,E9,75,9D,86,EC,24,F9,DB,DE,D2,9A,C1,EF,6F,52,A7,BD,9C,07,17,ED,D9,2C,E6,FD,C0,C8,39,93,A6,39,CA,C2,E4,1E,16,4E,5F,46,E9,E7,97,E7,2C,46,76,7C,19,96,6D,CA,58,4F,79,9D,75,7D,FF,82,28,4A,2D,39,0F,02,E7,AA,CB,09,F1,F5,E3,97,E5,BC,51,74,63,64,A9,80,E3,41,3C,A4,28,42,CE,53,E9,B6,05,FC,B6,C0,F8,F3,34,B6,F4,1B,0E,B8,11,8F,4C,8B,D4,DC,C5,16,1C,1B,53,3D,C9,F8,8E,6D,9B,F1,24,A5,56,76,45,1E,EA,29,87,22,A5,95,43,B0,FA,C1,7E,23,FC,73,39,6F,C1,CA,63,A7,02,30,D4,28,47,47,0F,C0,61,60,3C,47,E5,7A,A4,B5,0C,FD,52,91,C3,85,A1,14,FB,E3,2F,8E,AE,30,77,EF,4D,D9,EE,9C,BA,EC,70,04,16,7A,B0,E7,52,6C,76,FA,EF,30,C7,64,5A,B7,65,5E,6B,D6,A2,05,FC,96,18,0A,68,73,6C,E4,14,4C,0B,CE,F9,B3,08,78,07,91,2E,4C,7A,2B,B0,F2,52,8F,75,BD,CE,CB,52,7A,CC,A8,02,95,5F,59,BE,95,16,7A,07,6B,D2,E8,EA,38,44,30,CF,B3,3E,73,30,45,CD,04,B5,47,6D,40,BD,0E,5A,08,23,29,C1,96,70,CD,F4,03,08,C6,AF,2F,16,93,03,84,81,C0,31,D2,EC,FD,91,D9,F8,EF,70,C0,65,F3,0B,17,8D,8D,6C,A2,5D,29,7A,10,9B,78,88,E1,4B,9A,A3,98,A0,3C,D3,31,73,63,B5,27,6F,01,ED,6C,E9,A6,EC,D6,FE,32,B0,1F,D4,FA,18,11,73,38,CF,70,6F,FF,A6,62,49,F3,E1,E1,DA,55,15,E1,3B,92,18,66,DC,06,63,2E,E9,89,77,11,C8,49,4C,6A,DA,E0,62,AD,13,1F,A4,DB,0E,AF,E3,CC,C8,D7,E8,2A,CC,F8,32,1E,2B,17,77,9D,63,8B,2B,F3,12,61,40,F9,08,54,1C,E4,53,80,2E,AC,90,7C,1F,FA,C1,E3,E6,24,A2,8D,22,B6,D1,F7,0D,96,17,EE,56,E1,13,BE,AC,7F,A3,1A,96,B3,87,F3,80,6C,E3,DE,85,E7,3E,33,92,7E,BE,B0,3F,7D,65,A5,F1,7B,5B,00,3D,B2,FE,DD,89,80,55,AA,CB,71,02,B4,B5,3F,B3,58,7D,39,0E,38,33,61,B9,55,32,82,23,FE,37,36,B3,14,B4,44,74,95,B1,8C,84,92,46,75,56,EE,03,38,9E,49,E8,AC,CE,C4,E8,74,FE,26,A2,E4,91,68,A8,11,28,B8,04,0A,05,3B,BA,4D,31,20,B8,E0,80,45,E9,51,F0,2F,F9,19,64,35,46,0F,01,39,E6,DB,6C,1B,DE,9D,1C,C1,40,A5,92,DD,B4,93,D5,56,50,49,29,05,F9,8E,DC,C6,00,41,A1,7D,5A,97,C4,94,27,F0,C3,87,38,90,47,23,AE,60,69,0A,EB,2D,A1,11,6F,E5,2C,AC,C5,1E,B7,93,AF,BE,82,E1,CA,9C,57,B9,43,73,D9,00,AC,44,46,C5,C2,A9,27,C7,D5,19,36,B2,91,36,02,AF,30,F6,55,A3,F1,0D,67,E7,05,0A,E0,0A,E4,B6,34,43,A2,98,D2,82,C9,EA,60,75,34,AF,F3,24,C9,3B,A2,1F,DD,D7,D3,8D,1B,2D,6B,16,E6,29,06,B3,B0,FC,5B,86,BF,5B,F6,31,C7,B1,C0,8D,D3,94,C0,20,FF,7C,BE,C1,FA,95,BF,FE,AD,BA,33,AA,4B,E6,41,77,D2,21,3F,B0,72,8E,2F,27,C0,8E,2B,3C,62,76,A5,9F,04,7F,DA,85,F7,D9,16,84,99,F5,B2,BE,F8,5F,89,10,86,A2,62,D0,B9,E6,D8,73,E4,5B,4D,A4,C6,A9,0A,19,DE,91,D5,D7,D2,4D,A1,7D,3C,76,DF,5A,64,38,AD,B7,C6,FD,A4,F2,55,BF,51,F6,D1,E6,50,3A,E5,49,11,EA,06,92,71,67,B4,A8,54,5B,75,07,D3,FB,B0,05,64,32,49,E2,BB,C9,29,93,9D,18,2E,50,EA,C1,13,61,AC,0A,31,B2,E7,36,14,C6,2E,A3,2C,C1,E3,4A,7B,04,D3,E0,AD,2C,D7,87,F0,72,D9,CF,41,CF,E9,67,40,37,F3,9F,04,19,BF,BF,40,2D,3F,AB,30,07,B5,E1,2C,E9,0B,AA,1C,89,58,5A,29,18,87,11,67,F0,AE,8E,BE,25,23,18,38,31,0C,94,42,ED,66,57,DB,E6,76,C8,29,ED,C9,C2,EC,56,6E,3C,72,36,33,CE,82,BE,80,F3,05,6C,6C,4F,91,C0,5C,6D,7B,C6,AC,AA,45,A7,18,86,EB,E4,C7,6B,40,5B,9C,7F,A3,BC,BD,8D,38,E2,80,AA,BF,4B,04,7D,89,39,39,6E,A5,FE,2F,0E,95,54,51,36,64,47,69,E2,92,94,D0,32,48,53,E9,67,F1,5A,21,E7,EA,92,2B,07,D3,DB,EB,51,3B,4F,10,9F,3F,6D,D2,42,23,9E,8C,05,94,B8,3D,13,1B,02,80,7A,21,34,18,4D,EF,25,3C,F9,DA,F5,03,14,DA,53,A6,CF,51,77,30,9C,21,EC,B4,6E,D6,72,FC,EA,D0,AD,EB,97,22,1D,A7,0C,ED,3F,7A,E5,7D,D7,8C,48,4D,49,39,3D,A2,0B,9D,AF,1B,F8,EB,A2,60,5B,4E,AA,07,69,4E,C1,6C,53,46,91,DA,EB,81,9B,F3,90,F9,52,F6,CB,17,09,3B,DD,A5,F6,2A,30,D9,3F,BC,20,E7,09,63,78,1C,ED,39,4E,0F,E9,4A,2D,7B,9F,9A,0D,D9,1D,B5,5A,EC,9A,FC,A9,95,7B,28,49,04,D3,63,13,05,6B,F7,E0,A6,7C,3A,BB,11,2B,92,AF,1D,56,2A,9A,FC,F1,05,2A,45,5E,43,E2,7E,80,DE,17,1B,01,22,E8,32,8A,6F,9E,3C,66,EC,89,7E,09,0B,2B,A4,15,AC,F7,51,C2,EA,CD,4D,4A,E8,79,BB,2F,3B,21,81,0C,2C,69,C3,46,A3,00,6D,BA,2D,C4,63,4A,08,68,3E,61,94,37,AE,E7,37,B7,13,FF,A1,34,6A,CB,8F,B1,A1,A9,D3,AD,A8,62,A3,6C,21,75,88,E0,68,55,BE,04,5A,51,F5,C2,8C,1B,F1,93,88,3A,30,84,17,C5,10,28,C6,DB,0B,B3,C7,67,D7,B6,B0,53,2E,09,2B,6F,AF,86,CC,EE,21,BC,E5,7F,69,85,60,D7,9E,8C,1F,24,DE,AF,27,26,FC,F5,BB,80,E8,73,43,8F,40,92,B4,F7,08,EA,2F,C3,72,2C,73,8C,FC,CA,4C,E4,92,8A,05,6E,B0,A2,B3,CE,EE,02,A0,17,2A,EF,23,CF,CA,13,1A,77,EE,87,7A,1E,E5,59,39,C5,C1,24,C6,D4,A7,E7,34,F1,9B,0B,7B,1F,F8,36,96,DB,61,E3,C0,1E,77,74,22,71,05,E8,2E,36,26,D8,1B,2C,D1,8A,1D,A0,60,1A,67,08,4A,CA,92,77,B8,E9,49,C7,EB,FD,B6,CC,51,61,C7,6A,EB,DE,83,22,60,4C,7C,68,D2,02,D1,3B,BB,30,24,83,14,80,B5,94,17,0F,1B,10,5C,41,B6,44,11,B4,F7,54,FD,F9,6D,E7,AD,FD,11,0E,0F,FA,60,BF,47,89,EB,9C,5C,57,44,60,10,AA,75,4F,07,CF,C8,37,9C,D1,1B,B4,C7,F0,70,FB,3F,CB,46,C5,75,2C,BB,7F,93,C9,A5,B5,70,1C,19,18,C7,12,F3,13,A3,EE,0E,72,A1,CF,6A,67,1B,29,B6,6A,15,B4,C9,C1,63,08,38,7B,C2,01,38,61,3B,8A,54,3D,95,99,90,66,B2,3C,22,81,5B,4F,A5,53,3E,A7,DE,6B,CE,BE,82,B0,0A,A2,7D,45,E4,B1,41,C8,3F,FF,77,D6,0F,14,9E,2F,A6,C6,40,FC,CF,BB,6F,2D,F7,E8,23,76,7F,35,40,34,41,14,60,F5,17,8B,F1,1C,96,81,62,D8,1E,79,EB,07,51,21,1B,0B,27,A0,7A,B9,9E,D4,29,67,9E,77,0B,93,C2,63,00,AF,8A,2B,9B,7D,A7,92,33,2D,34,1A,15,23,29,79,AE,61,A7,5A,4A,2A,23,25,D7,B2,55,97,A1,7C,80,49,E0,95,06,17,15,1F,07,05,21,7D,4C,E1,E5,E4,F6,9D,31,40,8D,4C,12,0B,13,8E,6E,17,F9,DC,3A,94,64,6B,52,0A,20,0B,C1,BA,67,F2,F6,A4,DD,0F,BC,EA,D5,E1,AD,69,0A,46,1C,E4,6D,3D,0F,AD,21,2C,6B,85,DC,96,AD,D6,FA,34,D3,55,62,CD,22,50,C7,89,86,69,2D,C5,64,01,23,8C,25,D4,13,5F,87,E9,9A,19,D5,12,D2,FF,DB,88,A1,66,72,50,2C,59,D7,72,17,3A,E8,44,08,A6,31,96,9E,78,B9,D5,46,17,2E,9D,BA,4B,5A,E4,94,F1,4B,03,CF,F3,4E,D9,B8,D9,95,E2,E8,8E,A6,E0,BF,86,44,A6,26,0A,DB,21,13,CC,EC,6E,B0,F5,58,E3,E7,13,88,96,F2,31,30,44,EA,16,14,EE,D5,A3,C8,C8,1C,4A,30,CB,19,C8,D1,65,97,F5,B4,C6,99,2E,AA,1E,CF,3B,2B,4C,69,F7,69,F3,E0,C1,EC,7E,F3,37,FA,24,AD,46,90,97,BF,E4,79,CC,EA,56,A7,3B,D8,4C,9C,29,F0,84,EB,02,8A,07,82,DB,2B,82,DD,3C,F7,CD,FA,52,C7,07,17,CB,6B,16,49,7E,82,C2,B4,90,72,31,9C,47,B5,46,53,C2,C0,97,B7,68,AD,05,D5,0C,E3,82,0C,F0,8A,70,5A,3C,12,6F,C6,FF,95,7C,BF,7D,AD,B1,7E,70,BE,8D,21,67,35,77,6E,3E,7B,2C,04,68,B9,8B,11,3A,5D,A7,22,D2,28,4D,57,0E,04,E6,77,6E,74,B7,4E,07,48,EB,65,F9,FC,4B,38,B1,D5,0E,18,36,37,79,E2,E7,6B,00,DD,1B,DB,D7,68,B4,90,BF,E8,EC,75,52,7E,C9,53,3C,1D,7C,EB,AB,94,3A,04,68,7D,7F,B7,08,22,1E,4A,6D,B0,03,B8,B6,2F,73,FC,25,00,7C,FB,AA,93,B9,97,B9,92,C4,39,B9,29,BC,F1,75,E6,21,58,03,61,D3,AB,0A,4A,12,9E,94,DD,09,DB,22,6C,1D,09,6E,1F,79,0D,D9,D9,10,E0,90,EC,DC,DA,36,41,25,2F,09,3F,C5,E1,D0,54,C7,0E,2E,DC,A7,FC,61,D5,6D,89,E5,33,B4,7A,2B,6F,77,3B,E8,7A,B0,20,E6,17,E9,BC,5C,E7,C7,1C,1C,54,66,11,B4,A0,83,94,28,BC,59,8F,FF,76,13,AE,5B,B4,07,E9,CB,6B,40,17,4D,31,82,50,0B,D2,61,E5,C1,EB,C2,D4,8F,45,7E,BF,10,14,82,91,FE,DA,51,44,DB,B1,E2,0F,D3,BE,9D,6B,AA,C1,A7,01,28,29,67,05,ED,43,F1,C7,93,D8,0A,1E,61,F6,AF,FF,01,B0,99,DF,6A,F7,07,CC,CE,CA,E8,8B,91,6A,38,A2,AD,AF,60,B6,39,52,E2,E9,EC,ED,8D,FF,3B,C1,C2,43,8A,C7,5E,FA,29,D5,0B,8B,F4,06,2D,E6,4F,1A,F2,64,8E,9C,E3,E6,B7,44,33,75,C8,43,A3,81,43,78,82,35,B1,3F,89,EB,94,FF,65,B4,05,0D,14,05,7F,84,3C,E8,7F,FC,63,FF,B6,D0,E1,ED,51,BB,D8,DD,FC,5C,14,AA,3F,01,9C,60,95,F3,7A,0D,93,96,61,C4,58,C4,53,94,A2,80,E1,6D,4E,F7,10,E4,10,22,17,7F,14,32,50,DC,06,80,88,D6,BA,83,32,69,8A,E7,32,A3,2A,0A,67,1E,A0,CB,54,82,7F,DE,27,D2,94,8F,A8,51,94,7E,44,42,5A,34,57,49,3D,75,4A,3F,D2,A3,18,6A,D4,D7,3F,55,BC,22,AC,75,DD,F0,93,2C,78,35,60,D9,F8,33,EE,BC,AD,E4,63,81,C7,1D,7F,8C,65,23,B0,D0,A4,6E,AE,FD,56,AB,D3,B6,5C,00,EC,7E,7C,5F,C5,7E,00,40,EA,A7,DE,E0,74,BB,E4,EE,B1,7E,8F,4B,03,3F,88,9D,73,B3,6D,C1,EC,F4,D4,A7,E2,A7,36,EF,8C,54,80,DE,E4,1F,92,FE,28,E3,4C,6A,48,77,17,C5,CD,FF,57,6F,48,AC,53,C3,7A,57,38,D5,F1,89,8B,35,7A,A7,EA,18,BE,6D,83,87,A0,9C,F5,AE,8E,0B,32,5B,88,54,48,25,A0,FF,19,3D,28,A8,6C,D2,13,3E,B1,40,78,95,02,3C,89,BC,1C,48,1F,05,D0,57,59,A2,9B,32,22,EF,89,3E,C3,83,22,6F,46,B3,37,62,F4,82,70,FA,3A,7B,F6,6D,20,DD,A7,5B,BD,79,F8,B8,B4,1C,C6,64,E1,74,01,49,5E,85,7B,9D,07,2B,D8,9C,6B,FC,02,87,56,1E,6D,64,2A,54,0E,37,5E,95,D5,3D,EF,9D,DC,C8,B2,1B,09,2B,19,01,22,BC,CD,1A,CE,28,85,C6,93,AA,7E,E4,B8,A5,7B,0C,7C,DA,99,97,E5,E1,64,E4,DF,64,9F,A1,8F,F5,B6,CF,C3,E9,FF,A0,63,5D,C0,39,2A,87,00,59,26,F1,36,47,21,E5,4F,D8,18,86,A7,86,83,23,42,3D,67,04,E4,28,C7,A6,43,89,E9,46,39,8A,27,A2,78,AD,5E,E2,35,9C,CC,ED,84,7E,2E,AE,1F,D0,1F,B0,A3,7A,72,53,22,8D,52,74,58,92,50,D1,7F,5C,A3,08,F3,CD,A0,0F,E0,A6,40,6A,8A,63,6A,6D,F2,83,FD,9A,62,70,1E,41,0F,AE,CB,30,BC,2D,15,4B,89,A0,0B,90,91,1F,E3,61,42,82,90,0E,80,C4,F1,F0,30,59,DB,A8,1B,38,1B,9D,B8,00,F6,6D,2A,CC,7F,00,12,D2,F3,10,7E,75,FF,AD,DE,1D,F6,69,2C,45,04,55,11,02,46,83,EE,A9,F1,EC,60,40,8F,27,8B,3A,84,40,B7,EA,9A,56,05,E1,C6,5A,49,8A,3D,C7,CF,F8,DE,72,FD,8D,87,D6,7C,A0,C3,36,AF,D3,BF,B6,D7,9B,22,FC,D5,6D,72,3A,53,A6,62,1A,3A,18,E1,04,48,9B,8E,84,2B,1A,2C,8A,7A,51,85,CD,9D,7A,15,2A,69,F5,4A,B2,DD,67,CC,38,8E,CA,16,1C,89,A4,DE,DC,5A,4B,4E,71,4E,7A,40,10,CE,E6,6B,A2,FB,AC,47,67,BE,BC,45,F8,E7,80,B9,93,45,0C,3F,8D,3D,3A,F2,44,8C,B5,A3,96,FB,45,86,1A,5E,92,A0,2D,5B,28,C8,0D,33,18,F0,FA,33,50,96,1D,CA,A1,09,91,A9,03,A1,51,D6,79,65,FE,20,77,29,21,82,5D,76,38,8C,0B,A1,A4,6B,12,86,DA,C0,62,21,29,09,A4,C7,1A,10,5E,04,94,F8,07,D9,C4,B4,F7,86,81,6E,8C,79,A4,98,EF,6F,B4,38,A3,EB,4D,3C,BE,A3,30,C7,0F,EE,83,08,27,86,A6,23,4D,81,CB,06,95,49,6B,D9,26,E6,D4,F1,8B,DA,F2,87,F9,D0,8F,99,FF,B8,2E,5D,66,56,B3,A0,0D,DD,C1,93,65,86,55,44,6A,C2,9B,5D,C4,53,9C,F6,8B,8C,7D,04,ED,4D,FD,1F,DE,4E,BD,2F,EE,A2,09,E2,C1,45,13,37,D4,B8,0B,5B,A5,C0,31,E1,CE,8D,3C,00,48,0B,66,CF,FC,5B,9F,FD,EF,E2,42,F1,C1,26,08,55,AF,DA,BC,32,62,52,4E,B2,74,89,D8,BF,E0,C4,58,71,C5,C6,8E,BC,2C,DF,3D,8D,80,C6,B6,04,D7,E6,7C,02,E9,4C,DB,87,27,16,BD,9F,72,8D,62,D7,45,56,DA,E2,E8,FA,E9,62,34,47,05,BF,6C,EC,C3,44,06,6F,C2,7D,4B,98,25,49,54,FA,0C,15,BB,90,5B,57,80,E6,77,28,07,34,5F,A1,22,D2,92,1B,D6,A9,AD,A8,D5,6A,47,27,11,B6,8E,B8,0F,6C,EA,6E,D6,EB,36,CD,0B,E6,3D,58,02,36,82,F7,D7,9D,6D,75,9A,80,F6,87,1D,E4,A0,7D,FA,82,01,C3,43,4E,88,BB,14,CA,27,65,91,41,70,8E,F0,C1,6B,3D,CE,71,81,0D,FD,BA,BF,73,CF,FD,12,CA,4A,D7,31,D7,09,48,60,E2,F7,44,50,C3,DE,1B,3C,0D,F8,B1,72,D6,F3,CD,BB,51,EB,8D,F8,07,88,4C,8F,61,AB,F6,23,B6,36,23,98,35,F2,0E,21,8C,92,B7,F4,50,53,9B,35,AD,66,50,29,98,A4,47,B6,46,B6,BE,5D,D0,A7,F4,08,26,A6,44,DC,B9,D3,71,96,A8,E8,35,84,43,FE,29,48,BA,8C,DE,86,A1,B8,04,19,CB,09,19,31,43,95,D6,E5,EF,94,2A,3A,A1,37,5D,D8,12,E7,CA,1B,FF,77,C6,11,37,F1,C8,BC,C2,7E,6D,FE,0E,00,DC,31,D9,C8,BF,22,6C,44,1A,EF,1A,F0,6B,52,F7,F5,31,71,05,FD,8C,DE,33,3D,67,95,A5,8E,83,20,BC,22,8F,45,36,41,E3,3A,6D,62,9C,27,B6,7D,E7,12,E9,BE,52,01,33,5E,F7,92,07,F1,D9,0F,13,92,F6,B3,93,A6,64,9C,0E,15,B9,6A,AF,09,07,F5,2A,07,18,92,F7,89,6E,D5,40,48,5C,81,50,CA,15,BC,9A,04,7F,F5,D1,36,16,86,C8,67,6D,08,78,91,B7,EB,48,5C,73,51,C0,DF,76,CB,5B,73,DD,3A,15,0E,03,FA,CC,A0,61,35,A1,42,EE,E3,EC,D6,0C,39,66,97,AB,B0,22,AD,53,F7,D4,64,FF,F7,52,A7,DD,57,9B,B2,EE,4F,07,94,46,CA,01,58,0D,C7,37,93,21,1D,6C,77,9A,DF,63,D0,92,0A,C1,63,D7,BF,8D,F9,86,49,26,BE,A7,7E,22,CD,99,B2,6A,73,9F,61,07,32,AC,A8,87,ED,85,B1,C9,F7,FB,9E,28,3E,C9,7A,B6,17,69,11,DD,4E,19,72,F4,D0,06,56,66,72,DD,B3,15,0B,94,9F,2D,64,BE,D9,A3,EA,6C,D8,FF,C8,FE,31,D0,54,7A,18,EE,CB,12,C3,2B,F8,4C,F2,55,23,BA,64,16,9D,DB,10,78,E5,E9,9E,A3,8C,3A,06,CB,FC,24,90,15,6E,AF,41,3A,4C,B5,CD,93,C8,E8,F1,EB,82,5B,97,33,EC,1B,C7,2A,67,DC,71,C7,58,CF,B8,DF,31,BE,D8,E5,E2,85,94,96,11,84,B9,82,AC,58,69,62,05,0E,C6,20,51,4E,E4,25,9F,F2,B6,FA,84,17,8C,E4,2A,FF,E5,4C,82,49,56,E0,72,29,90,B6,89,DA,17,DC,B2,4F,85,FC,35,17,DA,09,C8,E4,30,B7,9B,5B,35,AB,A1,9F,1F,0C,96,38,1A,AB,C7,B1,BA,54,E5,31,E2,60,63,B9,FC,35,41,FE,3D,1B,2E,B9,A9,04,DE,75,A0,6D,10,34,0D,24,AF,2F,DB,A2,57,66,6D,EE,B3,56,DC,F3,67,FF,A5,59,6A,E8,93,DC,49,8A,BA,B2,2A,34,D5,27,BD,68,F1,E5,14,E5,86,02,9F,39,2A,86,9B,67,81,89,06,DB,1D,99,33,BB,87,78,7A,4A,8B,E8,3D,3A,FC,A1,88,B8,58,8E,0B,E1,95,2A,B6,E3,A4,5B,58,F3,DF,9D,4C,EA,6F,57,75,42,32,4E,A0,F1,6F,59,FE,D1,84,22,73,FA,AA,02,2A,14,CE,33,D4,42,40,4D,5D,17,B0,1A,3B,36,B9,E7,3B,19,05,34,74,47,98,48,4C,04,3B,15,B0,A9,BE,51,04,4E,31,29,ED,FF,B2,A1,1D,F3,80,F5,ED,B2,8C,AE,DC,50,76,FC,C1,F0,BC,13,34,A5,08,B5,E6,A7,61,BB,4F,04,D2,38,B1,CA,E8,57,C3,D0,A2,30,74,73,1A,90,DC,5D,39,BE,1B,E0,C0,DE,B8,26,2A,49,2D,5D,72,53,48,E7,D0,53,E2,66,91,96,F6,FA,3B,5F,0E,05,8A,4A,9D,71,97,8A,65,56,4B,69,6B,8E,1D,17,F0,2E,42,41,F6,CC,A7,C9,19,08,B8,F8,EE,CF,47,BC,F9,BD,EB,CE,22,E2,86,87,26,F5,91,8A,AD,7A,B2,AB,64,15,02,12,56,09,57,4E,5B,40,E6,21,20,C4,63,B0,78,37,05,C9,9A,93,11,C3,CC,37,5E,36,5B,4D,F5,A8,17,30,CE,3A,BA,B3,74,22,D8,7F,F2,C3,3F,B5,39,D5,48,B7,26,9F,FF,B7,5F,A4,A8,21,95,4A,04,33,57,4A,A9,8E,02,74,DB,19,2F,8B,80,55,BB,70,23,72,97,28,A3,BA,AE,76,F8,F4,7D,38,79,54,81,EC,B1,57,72,8C,A2,D1,03,DB,0A,6A,BC,38,EB,7D,E8,2B,A3,AD,CC,4D,3C,B3,5E,33,B1,AF,CE,0F,8B,FB,DC,68,01,65,29,35,26,7B,2B,31,C3,4E,A3,1E,DB,91,1D,37,1C,72,22,52,67,75,62,08,4F,C9,94,D3,39,3C,2C,F1,F5,0C,BB,EB,4C,A8,41,7B,F9,38,5A,5F,18,3C,CD,21,0E,61,3A,EA,11,70,47,C0,2D,95,65,24,30,23,97,15,08,81,2D,14,CA,38,67,95,12,2F,9A,56,6B,C0,0F,7A,4B,2B,1D,1B,B4,6C,43,76,2F,F9,94,69,47,EE,3A,89,C6,22,D4,01,BF,C7,BC,AF,ED,F1,ED,3B,9E,04,58,66,D6,6E,28,10,1B,6A,11,E7,CA,5A,EF,01,C9,A3,0D,08,42,58,C9,B7,F9,B8,F4,DD,F2,47,AD,92,1A,81,E7,34,D0,94,72,A6,8A,2E,F0,B8,58,36,BA,F5,A5,C1,2A,1E,60,48,A1,29,48,E1,C0,6D,6A,DC,96,B5,D9,E7,DE,99,AC,00,F0,47,E4,B0,CF,91,31,7C,4B,1F,26,B2,67,67,25,6F,72,C2,2C,33,5F,85,3F,A6,AA,22,7B,DE,6E,68,53,33,29,8A,81,F7,A5,8C,2A,B8,B5,D6,5B,48,D6,CF,1C,80,E6,29,6B,2A,4C,21,1E,86,CC,60,F5,3D,58,43,88,F3,83,00,CC,09,B1,29,98,16,07,33,C9,54,95,3F,18,C2,98,19,0B,DB,69,97,9C,AB,11,64,59,93,B4,82,1F,92,67,0B,69,69,4F,2A,34,55,DA,6C,9C,2C,38,62,B0,BE,DE,BE,65,FA,BB,BD,97,ED,6F,F4,8D,3D,5F,D4,39,4D,1B,B7,D0,88,75,7B,1A,E2,A9,22,30,0F,BF,F7,A2,52,9B,59,C3,DA,90,4E,3D,97,71,AC,11,D7,DF,DA,39,31,95,73,6F,29,73,C9,61,B0,B2,8B,E6,E6,A7,4C,74,FB,E0,AC,FD,42,FE,81,01,21,F8,D5,09,DF,61,A8,BF,9A,C9,D3,77,E9,7B,CF,2F,D1,31,9E,50,9C,5C,E8,E6,CA,84,A7,16,F8,84,14,54,74,72,6D,BC,6D,96,A9,D7,C6,F1,E6,57,80,BB,FD,BE,B1,C3,5C,7F,65,9B,66,B7,24,1E,A2,AE,E6,C9,9C,3B,64,F7,A7,1D,3E,75,5A,37,73,A4,07,D9,F6,F5,C2,6C,FF,85,F8,56,69,09,24,47,59,0E,33,68,B1,82,91,EE,C4,17,43,61,A2,0B,F5,61,06,B8,28,5D,ED,72,88,9E,66,63,33,8A,07,7A,D9,F9,B9,28,DD,EF,B5,0A,52,FD,FB,0E,0B,D6,1A,E9,3A,00,F8,07,6A,C5,21,B2,D6,2A,F9,B5,5C,48,66,A8,67,FF,C6,5A,B6,D8,BF,A8,A0,0F,DD,29,96,FB,F8,DF,2B,F9,58,78,BC,0E,9D,66,7F,EC,8B,F0,4C,64,2B,23,0F,3B,45,4B,5D,8D,1B,FF,4C,AB,DE,77,D5,96,48,0F,A6,C9,61,3B,53,73,F9,FE,3D,18,65,37,88,73,52,97,2A,6B,E5,2E,E6,30,88,D8,03,A7,E0,48,86,28,B9,80,FB,92,DB,F2,CA,3C,5D,26,47,50,7D,B2,EE,E8,9B,1B,91,A0,00,D0,06,B8,AD,75,7D,F6,7D,18,52,71,0A,D8,A6,D7,47,6F,7C,E5,99,00,BE,2F,CC,60,51,B0,F0,8E,1F,00,FB,2C,81,1B,61,BE,3D,05,EF,E7,62,80,9A,E6,1C,72,7B,7C,3F,DF,41,28,A8,5F,7B,F5,B6,47,81,1F,1F,85,A8,1E,22,57,37,64,69,B2,66,66,3A,2F,66,43,23,86,BF,21,8B,9A,22,B1,31,AA,8B,C9,FE,F6,97,18,2D,D2,22,58,4F,18,17,1B,8C,6B,B7,B9,57,C0,35,A6,39,CA,DC,13,EB,59,1E,BF,B2,B8,D2,D4,E2,6B,D9,8B,9E,09,D3,FE,E9,DC,88,18,F8,4D,AC,D5,BF,33,AA,B3,45,DB,D4,8B,E1,7F,A7,2A,B0,84,F7,73,5B,1D,BA,B3,19,5C,FC,3C,5B,28,10,C1,65,A0,16,93,16,64,B0,B5,2B,62,83,DB,4A,80,47,D4,3F,30,77,BC,DF,38,72,8D,17,3E,B6,AF,C8,DD,DA,18,2D,BF,6D,26,CE,F1,8E,7F,36,1A,18,3B,D2,35,22,FC,47,DF,DD,EF,C3,98,B4,0A,06,C6,09,B0,AB,EA,F0,34,C6,CF,6E,90,29,7A,59,2C,BD,E1,7C,05,A6,4F,FC,93,6A,CB,D1,C3,29,20,FA,AA,B5,AD,9E,F8,5F,8A,A3,89,7E,2D,D4,16,F8,1C,A9,31,63,65,ED,50,09,B9,A0,33,67,39,EC,7D,94,3C,9C,1D,42,25,5A,ED,11,4D,AE,FE,90,2C,1D,6C,DE,C4,68,B3,8E,DD,EC,BF,B2,28,57,97,CC,1B,BA,B0,80,59,0B,04,4B,5D,73,0C,0B,7B,08,C2,AB,0D,28,36,7A,70,30,D7,35,78,09,3B,11,40,75,11,05,CF,33,58,03,39,44,68,2D,57,A7,17,4A,1F,E7,73,48,D8,1E,62,BD,59,6D,39,27,13,73,69,9D,A1,0B,18,07,2A,AE,CA,80,20,12,9F,F0,28,C4,E1,39,9A,0E,77,F1,46,E1,28,1A,16,E2,DD,81,B8,5C,BC,31,A8,ED,21,DF,91,55,D9,0C,FA,FB,68,A3,F5,CA,D9,76,01,C4,E7,84,A4,D4,2B,6A,99,FD,2B,28,6C,FF,DD,3A,21,42,62,46,EC,C8,EE,62,40,04,CC,D6,EA,90,B7,0C,13,F6,75,7C,80,31,A3,6F,35,4D,92,C1,29,36,20,E9,B4,4C,72,03,41,A6,28,82,1B,81,38,AA,3F,45,66,B4,C7,C3,EB,FC,37,13,6D,44,DF,B1,8C,24,F9,8E,AC,9D,32,67,82,C4,27,47,14,42,9D,A3,D3,CB,7E,1C,00,73,D0,5E,D7,28,01,B3,6E,15,11,9E,7E,31,49,E5,E2,E1,AF,99,5F,CA,66,B1,A0,D4,3D,D6,E3,46,95,D8,AA,D7,55,26,9E,EF,B7,96,20,B0,56,41,DC,6A,21,4C,8E,D1,79,46,F9,7C,4A,87,55,70,D1,07,8C,57,E1,A9,D4,98,09,BB,77,B0,7A,3D,09,80,EC,05,08,12,71,E7,EB,C3,F6,4C,C4,22,92,A2,C4,EB,6C,01,97,2D,9B,7F,5E,B3,FF,30,53,1C,A7,55,48,38,32,86,C5,BE,DA,19,66,AB,1C,DB,6E,C2,DA,33,BB,12,FF,18,32,49,38,54,AC,2C,41,E0,5D,88,6D,D8,E0,01,48,EE,F1,6F,87,43,FC,7D,EE,52,51,6D,F7,9A,84,DC,8F,92,6A,9B,8B,13,70,7B,03,E6,EE,09,9F,47,D5,45,DB,E6,08,F4,D5,3F,7A,41,5F,95,CC,35,F7,55,C9,E5,9A,B0,A3,D0,F7,DB,E5,50,BD,57,11,77,4D,3B,4C,40,EB,E3,24,4A,AB,6E,09,BD,88,80,52,CA,2D,AE,CF,68,A0,49,0C,D9,C9,BD,86,FA,C4,C6,08,19,00,21,AB,36,A4,B8,49,D4,10,74,B2,A6,73,C6,AF,E3,12,EE,13,49,FB,0F,F7,69,33,64,E6,70,5C,1E,3C,96,2F,92,8A,8E,39,5F,95,8A,1D,99,A8,5A,CE,D7,65,6E,6F,EB,E6,2E,F0,8B,A5,3A,68,15,94,F1,D4,13,A0,96,AC,39,88,36,FF,9B,AE,09,B5,01,0F,80,28,11,84,B2,EC,51,3C,12,17,D3,3E,A8,CA,F5,85,B4,2F,EB,A7,3C,98,A4,18,4A,DC,AD,E9,C6,DF,73,58,A6,40,EA,DF,D5,2D,8E,80,2E,97,E2,1D,BC,3A,E7,6B,D1,02,D4,4F,62,6D,E5,15,19,4F,DC,7D,6B,4F,EC,5D,4E,5F,8C,1F,8F,C7,92,42,A7,87,E2,C9,96,D1,A9,5E,EB,EF,3D,47,AC,E9,4B,62,4F,47,82,2B,AF,63,4E,00,22,0A,DA,06,59,68,95,32,55,12,F9,48,D7,A4,2C,A6,89,7F,CB,E2,06,97,1D,C5,62,E2,60,F0,78,96,74,06,C7,9B,90,F5,74,79,7B,30,14,F5,41,9A,EE,AE,38,E1,4E,FA,B4,7F,DC,54,59,77,A1,AD,4C,B8,BF,9A,55,56,2D,25,B7,2E,D4,9C,DD,08,3F,69,14,A3,2E,74,AD,9D,5A,80,41,99,FF,1D,FD,9A,2C,2F,B6,01,3E,8E,49,F2,8B,A5,C5,92,E5,82,F6,00,19,09,8D,48,03,BE,AF,B8,09,B0,DE,1C,AD,92,D9,63,35,DB,C8,28,3A,83,DA,55,14,4F,AF,86,13,95,1F,3B,84,E1,AE,16,9E,48,C0,1D,E4,9B,80,24,17,C1,EC,3E,27,11,14,84,15,2D,FE,40,03,AD,F3,14,43,CF,E6,35,69,C1,30,4D,53,62,F1,A3,C5,F7,01,E6,54,5A,16,29,26,F8,40,F1,F4,D3,96,C5,96,10,CE,C5,60,F0,66,B6,38,FD,A9,77,B3,AA,F3,64,87,30,C4,55,90,8C,72,24,82,E8,A1,D5,E5,48,60,A2,DF,02,FA,63,26,F8,E0,C6,8C,7B,80,B2,73,45,5A,B7,DB,66,EF,2B,E9,6A,C4,0D,15,AD,66,60,1A,BE,22,7F,80,81,78,63,9B,76,5E,D7,0D,83,D4,47,C6,24,BB,D3,B6,CE,70,8F,D2,C5,EC,AC,71,85,8F,62,36,65,DD,8A,0C,43,89,3A,93,46,D9,F2,F9,C9,AC,4D,79,C9,89,37,89,66,39,71,50,E9,AB,A8,A9,66,14,E8,E7,95,76,D3,D5,D8,C4,89,C0,99,46,A8,15,A0,DD,9C,20,0C,46,9B,26,69,08,64,85,D4,1D,17,07,A8,1A,60,CE,63,B9,97,E1,A5,BA,3C,8E,21,93,4C,DD,7E,45,4C,8F,6A,95,98,B6,93,A7,81,8A,20,8A,8C,BC,FF,51,28,E3,9A,B5,5A,09,22,C0,E9,2F,11,9B,2E,1F,EF,0C,C3,82,64,4C,6D,02,4D,E8,5F,63,0A,EC,91,4E,9E,58,78,DD,C6,FF,C8,5D,83,84,BC,70,FB,67,35,36,21,82,CE,1A,F0,47,F7,E4,76,15,F2,23,0E,86,D4,B5,3E,84,12,FA,A3,D5,AF,29,04,45,EC,BB,30,36,8E,3C,E0,AF,67,30,5A,A9,7C,A1,19,0A,97,E4,D1,F2,96,1F,7C,84,0B,C1,86,62,7C,BD,4C,95,D4,84,D0,B4,8E,BC,2B,23,B4,62,CA,C0,DC,3B,24,32,18,97,93,20,06,17,DE,D5,F5,92,D1,8C,17,31,C0,CF,64,98,72,B1,22,86,49,96,72,C2,D2,1D,5F,C6,20,9C,D0,40,48,30,09,78,B6,61,53,97,46,D4,9E,0F,84,B0,74,12,9E,C9,E3,22,F1,95,B2,1A,8C,82,10,07,E9,40,9A,5A,E4,C0,CF,E0,FB,AE,FC,72,D9,68,89,63,15,BC,AE,80,28,2F,94,38,74,40,2C,D3,87,6F,E0,B3,7E,DD,C1,AA,6B,73,5B,A2,49,10,F2,C8,1D,74,B0,93,73,4A,71,7A,AF,B7,38,A9,E0,A3,D8,A6,6B,1A,10,36,63,55,E4,C1,CD,19,11,38,94,C5,BF,E4,7C,6C,35,42,1E,15,CD,5B,2E,0B,44,8C,7C,50,C5,65,E9,DA,E7,DC,F1,1C,C4,F4,23,B0,2B,AE,EF,EC,38,92,9F,DD,F4,53,7C,FE,A0,83,AE,75,77,94,7A,26,F5,7C,D1,F8,01,F5,09,8E,4A,E8,D5,C6,97,73,4A,35,32,CD,FA,B7,F0,40,69,63,2D,BD,50,89,6D,AF,5B,CD,CC,B6,0B,E5,3D,72,AA,42,3A,B5,23,54,63,CC,9D,C1,C2,88,C1,A6,8B,F4,0C,36,28,C4,BB,49,CD,8E,A4,57,B0,31,5E,6A,A4,48,B3,A0,12,8D,EF,AC,05,B9,02,56,18,55,B4,7C,5D,5C,C7,DA,E4,68,27,27,EA,AB,91,0C,86,0E,D0,2D,26,8E,47,AF,F8,AA,61,26,03,14,93,A7,DF,76,54,86,E6,00,4A,76,25,2B,E3,8E,B9,D3,36,A4,DC,75,5E,B1,D6,65,0F,F4,D9,B7,FE,E0,17,21,33,B5,50,47,27,3B,A0,30,FC,CA,33,EC,84,60,46,E4,00,6E,68,35,F3,89,47,9C,87,D8,72,D9,CF,89,A8,54,18,D9,BD,3C,49,2A,3A,7D,F7,1B,78,8C,4F,19,A5,9B,D4,1E,B1,D6,F6,3E,B7,20,68,58,C8,F9,07,4F,95,5F,02,3E,C3,5B,F8,11,64,E7,6D,14,81,31,ED,5D,10,FF,5D,5C,25,D8,8A,86,CF,A1,81,DC,8D,8B,DC,BC,03,89,D4,2E,25,7E,78,B7,20,D9,A0,B0,6A,FA,CD,2A,E0,10,55,ED,99,F1,53,48,FE,21,9B,D3,95,DD,C7,D8,9E,04,85,AB,5D,C6,E8,C3,2E,53,08,9D,AC,3E,DC,B9,25,36,E8,9A,99,61,29,A9,CE,23,97,9B,6B,C0,31,F8,3E,C6,8F,C7,87,56,40,55,D1,6D,7B,84,3A,DC,FB,6A,7E,02,98,B6,7F,1A,39,50,54,65,06,B3,AB,88,02,94,93,BD,73,D4,D3,F9,7B,A6,6B,6B,1F,28,08,AB,B3,41,43,DA,20,4E,9E,C4,88,38,CC,13,06,F8,4D,08,91,40,65,BB,D5,6C,95,2D,E5,4F,BE,6F,83,DE,A7,A5,64,DB,6E,E1,27,8F,C0,68,AB,A1,14,AE,64,1A,4E,A9,54,2E,12,95,23,2C,0B,A8,14,B6,A0,4D,AC,4F,11,BF,BF,A4,FF,79,26,4D,37,51,A9,5B,E8,73,70,30,35,1D,40,6C,FA,D1,A7,30,D0,F5,A5,46,CF,5C,2B,BE,B9,F8,8B,AD,08,6A,66,54,E5,7A,EA,46,4E,53,4C,59,6E,AB,0F,16,0A,D9,DD,0D,4D,F5,78,BE,55,A8,E6,18,C4,A8,C4,73,CB,27,62,A2,B3,9E,2E,0D,B7,B1,39,23,2F,2C,3E,C1,61,56,37,06,B8,1E,A4,C3,ED,6D,33,DC,1A,99,C0,05,9A,45,09,25,EF,9F,8E,1F,EC,8A,97,FA,2E,C0,1C,56,48,50,B5,66,14,68,E6,88,E6,E8,CA,7E,EE,DF,CE,06,79,2D,58,C5,28,8B,15,C4,22,F1,41,38,1E,16,A2,5A,29,80,A7,65,2F,66,4B,56,9A,F4,4B,E2,96,7F,42,78,87,F2,26,DC,8B,8F,DE,46,38,E9,A3,DC,3C,9E,3D,5C,7C,F5,CF,4A,22,D0,67,DC,C9,8E,76,2D,12,06,D2,16,86,20,97,84,9F,BE,5A,FF,B1,FA,AA,8C,E9,F8,B8,57,E2,06,27,BB,E3,F9,E0,E3,87,81,60,F8,84,F5,D0,DF,96,BA,1D,5A,A6,CB,9A,11,E1,6D,92,CF,F3,45,78,34,80,D3,46,82,09,10,E8,3A,63,85,A3,95,1A,7E,17,17,5E,B5,9B,64,F4,2F,E1,41,64,BD,B0,0E,42,B6,E2,28,0E,E3,E8,1F,55,C9,FB,67,2E,06,3C,09,22,C3,07,49,E1,B1,C4,DF,1F,32,ED,A6,70,06,CF,6C,AB,C8,FC,AF,A4,D6,1B,77,7C,76,0F,D8,CB,6D,81,6F,BE,26,F3,5D,E0,3E,B1,A5,8C,88,5A,02,BD,2E,A3,27,79,32,54,70,3F,50,B4,B7,A8,63,81,45,24,5F,23,5F,48,CD,E8,DB,47,07,36,5B,66,B7,02,EC,49,64,95,12,06,B7,41,53,7C,2E,A5,A8,D6,2B,B8,5D,E7,29,EA,51,1E,FA,8B,9C,A7,35,D4,CF,CB,42,8E,12,13,D8,30,59,BF,AC,05,55,E2,C1,1D,27,30,A8,95,7C,8A,53,2E,07,0A,41,B3,F7,CF,80,DB,34,71,87,56,85,A7,2A,1D,5F,2D,3D,E8,E4,18,C7,CD,3F,B5,F3,F1,D4,4D,36,39,EB,E9,CD,9C,2C,2C,48,B7,9B,57,1B,EB,44,99,0C,F1,A7,04,22,D4,4E,57,64,C3,9D,D8,C2,6F,27,A3,5E,A5,E6,FE,0F,B5,3B,5B,AB,42,38,E5,AA,AF,BC,B7,7F,EB,BC,23,F8,E8,31,8A,B0,78,3C,3F,D4,87,F8,68,67,C2,31,5B,65,FA,BF,5B,85,C7,38,7C,13,86,6B,76,72,1D,52,F0,02,1D,E6,FF,CC,B4,CE,64,2C,E6,C0,DB,88,4B,00,FD,78,23,9D,3B,1D,2D,F2,EC,09,4D,95,58,4D,54,88,1A,03,A4,B4,84,5F,98,C3,6C,BF,4E,EC,6B,9E,0F,2D,11,34,B0,16,91,FE,4B,B3,95,F3,04,14,AC,78,FD,95,5C,D0,A9,B8,5C,C7,75,41,EB,98,D6,71,80,A5,32,99,B6,E2,8B,E4,49,01,92,ED,8C,41,91,DC,65,1C,D8,9D,A6,35,E5,CF,B3,3E,3B,59,1E,11,9E,A8,E3,DE,33,6B,33,68,1D,37,78,35,E1,90,C3,01,DD,65,7F,87,54,70,59,BB,AD,5B,27,1D,3E,0E,01,C3,7D,C9,D3,17,E3,E0,0F,BD,E3,11,3D,2E,46,1F,B9,FC,96,C6,B8,7F,7D,09,F9,62,C4,D2,26,30,46,98,91,9A,01,BB,80,7E,F0,7B,B3,44,19,C0,1C,77,B5,D8,62,7F,7A,F8,35,E0,A8,A9,88,63,17,6E,F8,4B,41,4D,1C,2B,1C,89,48,3B,A6,D4,88,24,9B,5A,1A,8A,07,B1,A9,02,49,5C,AB,ED,14,2B,52,D2,C3,ED,A8,CD,3D,8F,BB,11,13,BC,EF,78,D8,51,3A,AD,62,46,A6,F6,8D,99,16,1E,B3,6F,D7,81,D2,26,E2,11,B8,7A,FD,AD,DF,92,ED,2A,F8,F0,FE,27,43,EF,1F,7E,00,8C,B7,7D,D4,21,D4,13,63,70,8D,BB,CB,B5,26,8F,87,81,EC,10,63,1B,A6,3A,E9,2B,A0,6A,B5,8D,C0,EA,74,4C,DD,D0,03,B0,01,10,E2,3A,D4,DE,5C,AA,EF,02,AA,6D,AC,26,BF,C4,0D,4F,93,2A,50,9B,C5,9F,5F,23,0F,1F,EA,CA,39,1A,1F,6E,03,BC,68,A2,E1,25,72,27,47,F0,0A,E9,12,F9,99,8E,5F,0B,62,A7,50,99,9D,6B,7B,E3,18,5F,D1,DD,F2,1B,6F,BA,8A,01,50,AC,43,F4,E7,7B,92,1B,0E,F2,67,53,BD,2E,1D,57,09,4D,4F,D5,00,E0,9B,E3,20,07,C3,91,84,7E,6C,1A,FF,DE,D7,B3,62,D2,CD,C2,A0,97,37,4A,69,4E,8F,A1,D0,FA,32,1C,DE,35,AC,23,67,90,FE,28,5A,68,CF,3A,BE,38,07,21,53,B5,2B,15,38,AA,45,60,B6,A6,55,7D,56,FD,FD,D9,4D,E7,09,0B,B8,20,61,B5,D0,0D,51,8E,4F,EA,98,D3,34,22,FD,54,C2,6F,F6,11,82,10,64,41,D5,F4,67,D9,15,EB,C9,7B,D7,5C,40,E2,EC,5A,EF,8B,22,1B,02,91,54,5B,83,53,00,DE,4B,91,E6,D4,3F,77,F5,F0,61,C0,26,CB,6B,B7,D6,70,40,D0,0E,C7,C6,15,06,A7,9B,C8,BB,13,BB,28,11,EE,CD,FA,FA,BA,90,D2,7B,66,C0,D3,A7,F6,DD,1E,82,C4,34,FE,5C,0C,F0,45,50,FD,FD,4F,34,45,F4,71,16,37,29,AB,AF,32,B6,69,09,7D,0F,24,F1,14,15,E5,56,F8,2D,8C,79,1D,86,25,21,3C,6B,3E,36,1B,CC,71,88,DF,50,A5,B2,67,9C,B0,FE,33,28,2A,C1,D3,FF,54,20,AB,1B,D0,A5,2B,59,D3,C4,E8,0A,B0,2A,6D,03,43,DC,2D,0F,84,A6,2F,7C,0D,A1,88,95,A5,95,F3,D3,4A,F9,57,C6,0B,56,74,50,E2,61,ED,83,9C,2C,6E,2D,65,04,6C,78,BD,9A,64,B8,B2,43,5E,E3,E2,05,FB,7F,D1,B4,1D,68,5A,1A,C7,95,DF,CC,7C,77,7F,90,86,BF,39,FC,61,FB,DE,AA,2C,B8,A5,FA,71,71,F4,6B,EA,80,FC,AC,7A,AE,F4,D8,5E,F7,69,69,BD,6B,9A,B3,4D,76,B5,79,C2,0E,7E,B8,F4,F0,F0,3F,66,6A,77,22,99,F4,CB,E2,79,50,50,C8,31,0E,93,7C,B0,24,52,E9,FC,68,01,F4,69,EE,91,E0,B4,A8,91,CF,DF,24,8D,B8,9C,1F,BB,CB,1E,0C,FD,38,82,80,F6,E0,42,0F,E1,BA,AE,08,75,C7,5C,A8,36,4A,62,65,43,B6,5F,D6,A2,84,86,92,12,E0,3D,02,9D,53,3B,54,34,59,CB,A7,A9,D1,7E,33,1A,5D,99,48,D5,62,D6,AE,CB,17,65,66,64,06,0A,49,FE,E8,9E,B1,2F,B1,6E,BE,26,DD,A5,C6,11,95,96,F4,9C,15,76,A3,6A,0F,F8,FE,6C,0C,1A,F5,FF,71,0A,43,21,1E,01,F0,A4,BB,52,43,84,7D,C6,0F,11,C7,08,EF,33,4F,56,E9,AB,7A,81,23,C3,38,09,FD,9F,4E,F8,54,E3,C9,09,D9,02,16,FA,3A,F8,BD,EC,CF,AF,2D,FF,1C,C1,4D,A1,15,95,E9,BC,71,33,E4,9A,9E,46,4D,16,60,E8,2B,59,01,70,4E,CF,2C,76,A8,AA,63,40,8A,68,65,D8,7B,E1,BB,1D,26,26,38,32,99,26,E3,3E,F4,FB,43,AA,08,3C,4F,0B,4F,B8,52,6F,31,72,FA,7A,DA,E7,15,90,A9,EF,1F,87,74,F6,84,C5,9C,4A,5E,E9,06,E7,5D,AB,37,D7,F4,5F,7F,4C,C1,41,78,8B,EB,41,26,FF,AB,DD,F8,7B,8C,36,E9,DC,58,DE,27,49,45,F2,8A,64,B8,47,E0,E8,13,92,D2,0C,3A,60,CE,41,07,AD,4F,93,64,68,69,D8,36,22,02,C7,7B,78,E5,43,BE,DE,46,1A,AE,22,CA,6F,E5,2C,1E,45,AA,1A,56,A9,A7,77,72,D3,D3,05,51,E1,1D,57,1F,C5,80,58,BD,66,7B,BC,F6,C5,5E,D8,C7,C4,1D,CA,8C,1E,E2,71,22,DA,A4,19,01,A0,AB,B1,18,7D,BE,09,EC,9A,55,FE,19,11,EB,C7,61,18,A1,DD,F2,AF,B0,00,10,2F,F8,D0,39,0B,C4,84,57,EF,E7,3A,A1,E6,3A,2C,3B,93,16,37,B2,03,3F,50,CD,AC,57,89,00,B0,AD,DA,DB,9B,C1,C2,52,46,CB,6E,B3,B4,AC,1E,F8,09,18,85,88,C9,AF,15,68,8B,36,14,CB,0A,BF,48,4D,C8,E5,7B,EE,AB,7C,9D,28,80,E2,96,24,EC,F3,03,A2,60,DD,06,35,87,7E,10,95,1D,94,40,F8,DD,B3,C1,4C,B6,FB,09,46,21,3E,D3,9B,7F,34,7F,FD,48,C0,32,5C,F3,29,24,D9,38,A3,16,D9,E0,03,60,37,EF,31,B3,C0,21,B5,B9,F8,8E,A4,BC,ED,C2,38,A2,7B,DA,A9,4A,98,FA,CA,D7,3D,FE,D6,73,BA,91,B3,A7,73,74,8B,42,85,DE,A4,66,55,73,5E,6F,39,B9,3D,18,D5,F5,88,82,B0,18,06,7C,BB,8C,44,61,92,1F,94,ED,75,04,A6,86,DC,E2,A6,AE,5A,CF,26,46,5A,06,B2,D5,D7,CE,77,7A,3A,50,24,2C,E2,BF,12,8D,D9,32,55,BA,30,54,DC,1F,7F,62,38,78,64,CF,A5,4E,44,06,7E,B4,B9,F2,C6,E9,32,70,26,20,9C,AA,A1,B0,CC,09,9E,8D,0D,2F,64,53,BF,62,C7,0A,40,DE,E4,42,95,D5,3D,9E,58,08,7E,32,16,36,37,7B,20,F4,4A,68,3E,45,D7,37,CE,3F,09,11,F0,D1,84,FF,67,EA,E3,2E,EB,87,CD,1E,0D,38,C1,A6,A5,2E,46,D9,B8,D1,1D,4D,B1,F6,27,1A,D3,07,07,E7,11,0C,2B,D4,18,89,A3,6B,93,84,5F,1D,F3,BC,2F,44,06,BA,DE,E3,34,62,41,6C,B2,83,BF,66,68,71,F9,13,3C,E3,F5,DC,D0,BF,2B,EB,BD,26,32,55,9F,86,B0,C9,A6,29,82,6D,6F,10,72,AE,32,96,0D,9A,F5,AC,1B,73,8D,54,82,69,42,91,72,31,1D,07,06,85,61,13,F8,22,76,12,81,D7,6E,72,3F,D6,88,52,59,70,39,53,40,7C,C6,A4,4C,DD,64,0D,F9,7B,8E,9D,67,0A,17,D3,7F,91,24,2D,B5,40,5C,F7,A8,A1,88,8B,53,A9,26,1F,D3,97,65,D4,06,52,02,CE,05,0C,16,85,92,53,66,D6,6D,FA,A2,1C,A8,BA,6D,0A,9F,EF,BD,4C,CB,5B,B1,7B,DB,04,38,6C,59,79,26,BE,F9,6C,4D,A6,06,E3,EE,99,EA,8E,19,1F,A6,3B,63,71,67,4E,CE,68,98,29,1A,B1,EB,05,0F,C3,15,B0,F3,BD,26,D7,89,85,61,1A,B0,DB,91,69,23,A4,C0,4D,BC,5F,D9,3B,D6,02,2A,D4,E1,55,09,AC,BC,D3,60,FA,C6,86,E6,E1,85,4B,E7,B6,FE,63,80,AD,CB,44,7C,BE,0C,33,2B,63,D0,3C,CE,0B,7D,81,4C,6D,E4,E5,7F,BE,8C,6F,82,31,91,73,DB,CB,29,4E,CD,49,9C,CA,4E,1C,F8,52,5A,C6,42,1B,1F,91,58,BC,B3,D7,A9,35,A4,A6,CD,22,B1,01,7F,D6,AB,CA,5A,FD,F6,9E,35,D3,2A,17,31,9B,D3,C9,57,3A,67,44,78,42,35,C0,F5,D5,14,35,7B,41,BD,6F,60,5F,3B,8F,C7,46,63,91,6E,FB,28,78,27,46,16,AE,46,E6,ED,E7,29,6C,B4,DF,12,1F,FB,11,8F,C4,77,3B,C6,C7,89,12,66,9F,2A,B3,16,EB,67,C4,9A,0A,68,90,A7,7F,0B,C9,98,88,9B,77,61,EB,8D,10,AC,A7,D2,B3,ED,B5,DA,C0,92,03,07,66,26,EF,0E,05,51,ED,37,D7,1F,B9,1D,FC,64,31,3C,6D,34,42,08,71,55,C0,7E,35,8B,99,C3,AB,A5,F1,BC,A1,4D,6D,F3,DF,6E,B6,8E,E0,15,39,2C,00,D2,AB,95,06,F2,E9,38,EF,4F,9F,41,D8,C8,07,08,82,67,65,0B,D8,A8,7A,30,29,1F,30,5E,68,F7,95,E2,B9,8B,6F,03,E4,DC,1C,68,37,C0,24,1E,B2,D3,46,C3,20,8D,69,28,CD,0B,A5,96,4C,ED,66,35,01,E8,76,4A,79,C3,CC,44,E2,3B,CC,51,C9,E2,05,D3,5C,7C,46,88,E1,C0,2E,CD,58,43,DF,3C,29,9E,B2,52,B4,5C,E4,98,09,51,DF,C5,FE,93,22,D5,65,C3,6E,8B,CC,BE,1A,7C,86,33,99,A7,B6,3D,46,6C,D7,3D,B0,3E,A3,CF,2D,8B,F6,E9,70,33,01,D5,1A,86,B0,BC,B5,CB,FF,1A,12,AA,00,21,36,05,67,26,52,DC,6E,79,E5,8E,9A,85,AA,BE,49,F5,70,A5,F7,F4,12,F9,44,AA,FE,65,1B,01,95,AE,44,43,C2,7D,31,BA,4D,21,58,03,41,25,B7,F4,C0,0B,69,C8,0D,1F,0C,53,C7,2B,7E,E7,93,26,22,59,DE,82,9D,58,88,54,9D,B5,C9,16,58,FC,E5,7E,87,E9,42,F2,F0,77,6F,F2,48,D3,85,C0,D4,B1,D4,B6,48,42,54,86,C9,02,79,EB,19,DC,A9,CF,E6,FC,49,70,77,30,25,D6,11,A6,F2,CA,71,BD,F2,5A,E3,16,AB,63,A5,C0,81,5A,21,1F,FE,7B,99,7C,17,EC,5D,BA,89,A3,34,0F,13,45,8B,60,D7,94,55,EC,FE,07,CC,6C,F0,9F,D9,88,8E,5B,20,41,1D,31,0C,07,85,EB,D3,75,53,CF,38,1C,65,E2,2F,41,28,81,97,40,47,F4,1D,1B,7D,F2,EE,ED,55,DA,E6,C5,C7,6D,28,A7,A0,D6,57,14,9B,DD,D6,E6,24,D0,F3,B7,9E,0C,3B,8D,3E,6B,72,A4,E2,EE,D5,8D,89,36,60,F2,CC,0D,05,28,F3,27,74,71,32,21,55,F4,F5,04,F4,ED,7A,16,01,8F,D4,24,81,27,98,5C,59,02,4A,53,B2,9D,2A,AD,2E,C7,B8,8B,8B,F9,63,C1,4F,E7,A7,31,04,8F,05,8F,D5,7B,FA,A8,B9,F4,D5,81,0F,D7,42,1B,9A,8F,85,04,5C,0E,A7,EF,3D,4C,65,CA,B4,4F,42,0D,88,4D,47,AD,8B,18,C2,4A,BB,6B,FD,22,CC,76,96,86,CD,4A,BB,C2,E1,79,0B,94,AA,73,2F,B0,79,06,EC,A0,95,9B,E7,57,E9,23,9A,51,8D,E4,49,8C,A1,5C,6D,30,0D,28,A2,7C,60,5B,15,52,E5,6B,60,DB,7A,43,C9,95,32,80,02,47,A9,08,02,EA,0E,FA,07,AE,A2,D3,2B,E4,ED,5D,8D,D2,66,66,D3,D6,AC,E6,A9,F2,18,4D,3D,D4,65,E0,75,B5,CD,11,A4,82,CD,6A,D1,90,1D,6F,11,24,A2,C8,7C,E8,4C,BF,AE,A9,57,CB,71,AD,98,1E,5E,3B,75,BA,F9,5D,31,3E,F7,AA,46,01,2E,0C,89,3D,00,3B,93,44,F6,6E,BA,5D,C8,E7,FB,3F,47,82,88,C5,E1,8A,B3,CA,4B,BB,12,A9,A3,57,A3,B2,95,64,C6,34,F4,C6,29,26,E3,07,F7,B7,42,68,67,C9,C1,5B,60,5F,D5,DB,13,B4,C6,5C,E2,30,E3,A9,AA,D7,98,AF,76,E3,87,6E,44,D6,51,EB,ED,95,B9,C5,25,8C,19,6B,4E,64,B7,81,39,30,79,0E,AB,B2,92,1D,11,EF,C1,66,FD,51,45,96,FD,06,18,49,88,1B,73,BD,4C,6D,FE,F1,42,97,ED,64,F6,BF,A4,58,D7,03,05,E5,03,91,20,64,1E,37,07,6B,84,20,DE,12,5F,6E,F3,88,C4,6F,CE,2B,67,87,0B,43,6F,E2,CF,16,C4,EB,AA,2B,E8,58,CA,40,D1,3D,95,9F,3D,5D,E6,F7,68,23,A2,98,6B,87,5C,91,6F,0C,8D,62,5A,77,CA,56,6B,E7,D9,8B,2C,E8,B4,7D,29,3C,00,AC,EE,03,46,AE,73,EA,83,EB,A8,30,2F,AC,00,E5,9C,40,B9,E7,A0,00,74,2A,0F,4D,B3,0B,69,4D,C5,A0,3F,3C,5F,11,25,60,74,B3,85,4E,3B,8E,4B,36,3E,B1,09,8D,E6,B3,D5,B3,AC,F4,47,B0,2F,85,6C,98,14,C2,1A,A9,20,55,0C,E4,CB,EE,1F,70,EE,75,EE,B8,34,56,A3,59,1D,80,C0,93,3E,5E,11,E2,50,54,F1,E0,8C,94,06,14,0A,76,2D,3B,C1,50,50,EE,97,75,BF,94,F5,7E,9B,7E,3C,0B,48,40,EC,16,EA,53,EF,02,4A,96,7C,94,80,1E,9F,D6,1E,7A,F7,B8,14,1F,F4,CB,2F,C0,1E,57,2E,3B,5E,C7,29,45,B8,2E,6B,62,C4,E3,43,36,F9,0F,FC,3F,E1,FF,DA,D4,51,F9,C0,AA,17,00,38,3E,95,A9,12,7A,E3,9B,7C,5C,33,B1,B4,6F,30,C8,63,45,3B,4E,23,F2,E5,CD,BC,39,AE,B8,BC,AE,42,82,BB,1A,40,4B,AA,9A,B6,6F,D9,78,DE,E0,2F,0F,3D,CC,08,F1,7D,27,00,30,A3,B0,14,A2,EF,DF,88,57,87,1A,86,13,21,5D,F6,85,29,FB,A5,88,D0,11,34,44,F5,F3,6E,B7,EE,33,BB,3F,59,89,DC,4A,DC,40,92,91,BB,0C,14,0F,E3,95,6D,13,18,D0,4A,5D,C1,EB,5A,BC,6F,D0,0C,D7,F4,A9,7D,16,CB,F9,7D,C1,35,BA,86,05,44,3D,5E,CF,CF,2C,EB,CD,41,66,70,C5,09,FD,BA,59,EF,7E,8F,EB,A6,C8,2A,08,A3,D8,E8,7D,12,B6,F6,91,E4,C7,DF,E1,CC,6F,6B,BE,BE,D3,D9,0A,97,01,D5,75,39,62,CA,3A,20,1A,6B,68,51,87,DA,D3,93,D0,A7,DB,74,FB,A6,B1,F5,29,FA,43,4C,7A,7D,FE,26,A6,BE,1D,B3,3D,9E,B8,B7,1D,C3,6F,80,CC,E8,56,DE,C4,03,6E,F1,69,25,23,76,2C,E6,24,90,43,A4,1D,F9,33,71,74,C4,0F,62,4D,5D,DC,61,6E,9A,C7,3D,7B,57,1C,4A,EE,C7,24,09,09,93,65,C5,0B,82,89,DB,90,6A,5D,69,4A,06,C5,73,5C,83,EC,E4,5A,71,D4,C7,9C,60,19,2A,90,F0,82,4A,5B,BB,20,EF,BB,64,A4,BB,2D,38,1E,A5,5C,1A,99,0C,78,BC,FD,0E,FC,F4,A1,DA,3B,BE,71,1F,79,9B,50,0D,58,7E,2D,C6,DB,21,58,E3,4D,FC,49,E2,24,6C,48,97,43,E0,FC,17,A0,11,3C,B4,17,F1,70,7D,25,D3,62,55,67,68,89,F7,C6,74,29,4C,7F,50,42,84,1E,E7,DF,EF,8E,05,25,25,78,04,59,69,D0,9A,E9,39,7C,54,2F,5F,93,57,2C,0F,1D,BA,66,F5,91,BE,EE,C0,5D,3A,70,60,08,07,DE,0D,E9,8D,EF,D6,93,D7,E0,6B,7F,AB,FB,44,01,37,F7,47,84,1E,6D,D8,13,62,DC,23,B6,92,81,D9,F6,62,FC,6A,89,9D,42,8D,AD,AD,44,02,31,18,C4,0B,42,68,10,0C,6F,2A,BF,A8,FF,80,CC,18,E5,D2,21,9B,2B,39,80,00,C8,EF,14,8B,89,36,6D,11,95,32,0E,22,F1,67,20,D3,61,F0,24,1A,3B,F1,02,2C,48,03,3B,4D,0A,45,84,AF,13,A4,CA,C4,8E,41,6C,DD,7E,59,73,41,A7,8F,09,74,41,29,57,98,AF,B6,8E,4E,37,25,74,37,24,C0,72,05,B3,C7,5B,6B,94,CF,38,B7,E7,AC,BE,91,03,6A,70,77,B5,C1,BB,14,EE,2E,0F,1A,A6,71,43,64,5C,8F,C8,00,54,09,79,4C,E0,1F,83,45,98,64,D6,35,47,11,DA,6A,91,EC,5E,B6,48,87,02,EA,AC,53,3E,E2,B2,84,50,B8,ED,D0,B5,D1,1C,C7,24,7F,84,7E,45,7F,42,71,86,6A,A2,9D,48,D1,49,4F,FD,5D,84,48,4F,2F,67,5E,23,1F,CA,2E,65,D7,14,18,F0,10,09,37,20,66,7D,A9,72,04,4F,02,8A,5A,D1,31,E5,D1,17,A7,C0,ED,18,13,89,75,26,11,1E,AA,7C,17,F3,38,E7,D4,13,C7,0B,A1,19,49,80,D5,E5,BE,EF,4B,E2,7E,D6,CF,7A,1A,4C,9C,3B,70,51,8F,E1,DB,BB,FF,33,C1,E2,EA,1D,35,18,27,AD,C1,1D,8F,84,76,0B,03,FD,57,C8,B0,0D,C7,AB,19,F0,D1,9D,8D,9D,11,FF,E6,55,98,23,99,43,C1,53,6F,A3,7F,EA,29,F1,44,87,B3,B4,6C,EC,73,BB,2F,D0,7C,A8,BA,73,99,8B,A1,56,08,E2,FE,20,B1,91,A9,FE,07,97,9A,51,FF,D1,9D,BD,8B,A4,7B,99,5E,E2,4A,9C,73,83,2E,2E,8A,77,E2,BA,8A,CC,39,BA,27,FC,70,7E,19,14,44,C7,F7,80,A0,F1,AD,2D,54,3A,15,DF,53,F2,C2,27,57,14,9C,D7,5D,14,BA,92,9C,2B,23,E1,C5,23,F3,5F,4D,93,C2,E5,B6,FB,6E,AE,2F,7F,28,6A,05,3D,F1,32,35,E1,44,B9,79,1B,42,76,29,F5,20,87,68,D3,E3,6A,7B,EF,16,68,AB,02,64,D3,93,86,D8,F6,EC,E9,98,72,FA,45,D4,6F,05,8A,03,5F,2D,98,C6,30,A4,0D,B3,3A,2B,4E,07,19,85,36,67,3D,C0,C7,A0,D6,C0,06,B2,67,94,39,15,DA,66,2D,B3,28,DD,BE,D7,0C,1E,F4,D0,9A,5B,B8,4B,2A,C2,88,A5,EC,59,0A,89,47,B1,98,05,3C,16,D8,9D,20,27,00,99,47,C0,BB,C8,81,4B,AC,46,AE,F5,4E,BE,ED,2E,B0,95,4B,03,56,B1,E1,37,84,65,49,30,56,07,16,0E,C7,37,2A,17,24,59,C8,AA,6B,07,E2,CB,7C,50,8D,88,D3,03,D5,03,6B,D8,FC,05,9C,AE,65,55,FD,60,13,28,F6,EC,B5,39,33,91,5D,C2,F7,1D,36,61,65,25,85,F4,68,AB,A8,A9,2C,A6,73,C9,DE,28,17,F2,AC,AD,F9,E4,56,0D,AC,CF,1C,EB,00,95,CF,AD,EF,4F,CF,DA,F0,68,0C,34,5C,07,65,FC,F4,E9,E9,B0,B9,A5,EB,E2,F6,98,8F,91,0F,04,9E,19,E3,07,55,40,7F,A7,F0,05,87,B0,6D,44,A1,93,B7,E0,A7,46,15,DE,6E,8B,0E,06,C6,79,D5,4E,F2,E1,C8,77,9B,C1,72,46,B9,8C,70,6F,EA,03,17,35,40,C3,AA,B2,EB,58,41,6B,4B,70,5A,83,A0,C8,F2,90,37,9D,3C,72,13,07,1B,96,24,9F,6D,86,3E,48,FE,3D,CF,DC,CB,A5,C7,C5,60,A3,27,22,6B,23,0D,26,C1,60,97,93,50,71,26,F4,17,D7,CE,10,DA,31,A7,86,BC,E9,8C,F5,DB,D0,89,91,A1,A8,9F,9B,1D,4D,EE,E1,62,6A,33,52,DC,48,FE,E6,34,C1,00,65,94,E6,73,30,19,EF,5A,7B,D0,EE,7A,25,6D,C0,4C,61,07,B6,CF,F3,78,70,79,F3,5F,3A,45,59,A2,CB,7A,C7,6E,13,C1,4F,84,5A,7E,3A,8D,DC,3C,08,BD,D7,96,FD,39,5D,99,54,D1,95,C8,7B,AA,BA,CF,84,C0,C3,2A,04,F4,8D,1D,5A,7B,49,30,E6,08,FA,DA,BB,1B,F9,D5,E4,3A,E2,4E,10,D2,25,3A,DE,17,B2,C5,6A,5C,91,B0,08,3D,0E,8B,6E,BE,E1,BB,CE,B6,83,50,7F,DD,5B,D2,CD,AE,86,9D,44,7A,38,2C,91,C2,11,9D,2B,08,EB,6E,88,6B,F4,87,49,16,09,B9,64,97,85,64,84,21,1A,57,8E,84,E0,F3,3A,A6,D8,D2,DE,B9,EC,E3,CC,05,07,77,C5,6B,84,73,93,CA,4B,4C,72,5D,5F,AC,D6,DE,F2,94,C4,B3,AC,DB,B2,BB,54,82,52,D7,74,09,F2,5A,08,11,36,97,C6,2D,3D,94,23,6B,34,E0,1E,05,26,EA,CE,F6,74,A8,5E,40,3F,22,C1,7B,1A,5B,6B,10,ED,38,0E,8D,4B,C2,F6,0D,2D,A9,E9,BB,8A,0C,A5,C7,0D,AD,3B,99,AC,D6,72,48,C2,4E,4C,C6,2F,C1,DF,44,BD,9C,C3,8D,0E,FF,DD,1E,8E,96,72,40,B5,72,A9,A7,8E,44,96,61,18,02,18,DE,95,3B,5D,E5,B1,69,7B,F9,2A,E9,29,19,8D,5F,C1,72,FB,A8,A0,97,DB,1D,BE,76,A1,B7,93,9F,D9,46,56,EC,43,46,BA,12,C1,84,2B,C1,8A,18,E9,9E,AA,17,7C,F3,40,23,33,14,21,71,1E,D8,72,37,41,2D,09,A0,79,4B,71,27,74,1B,BA,0B,46,5A,82,9B,2D,CA,E0,C2,1D,4B,E8,EF,05,4F,D2,A6,BB,4B,DF,2D,3C,CB,1A,6C,05,90,C0,A8,55,13,FF,39,E8,69,1D,54,86,50,EF,B7,CA,14,56,8E,4C,F1,92,65,0E,06,A2,94,D2,D6,16,1E,84,26,9C,C9,CC,83,80,75,8B,B7,FA,B3,D2,47,D5,68,85,77,AD,98,A5,17,93,E2,FA,6C,64,AC,8B,8D,6E,FF,07,C1,99,09,F3,C5,58,53,1A,4A,64,01,A4,AC,08,FA,B2,4F,14,05,AB,E4,33,D3,8E,85,09,5D,57,E8,D7,CA,1C,F0,D9,E6,AA,4F,D7,FE,8A,30,EF,DB,56,12,7E,19,5F,88,54,E6,8D,F2,C7,32,8D,5B,86,87,80,C0,58,D5,D2,16,00,CC,EA,62,DC,15,82,D0,19,80,54,42,10,A3,02,A6,B1,05,CE,8D,9B,C3,6C,26,BF,75,22,E1,3E,F5,94,31,EF,98,99,8C,A2,54,F7,E7,D5,51,27,1C,AA,DB,13,22,32,AA,DC,C7,2D,E6,A8,E7,0D,6C,23,77,8E,70,BF,76,9B,12,41,77,B1,01,F5,26,61,B4,6C,41,48,19,E0,19,73,55,57,6A,67,BE,CC,48,32,D0,80,F3,D6,31,E0,28,F6,53,FE,85,0A,1A,CC,E7,DF,24,B3,74,EC,70,DC,D8,3B,C7,F0,E9,12,97,92,19,02,A3,1A,C0,D5,FD,F1,A7,46,B7,B5,E0,0D,13,3E,67,F2,EC,B4,DA,6D,DA,76,14,EA,63,D4,13,11,2F,7C,B8,63,89,0C,C2,E2,6D,1E,42,D1,F2,75,AC,66,3B,30,D9,93,F5,E2,78,A6,60,1B,7A,98,85,C9,05,39,0F,74,4E,41,5A,99,F2,46,15,C2,03,11,81,1B,E4,98,E5,26,D3,2F,E8,E6,C2,9C,0B,9F,D3,89,2E,D4,95,2B,D2,E5,52,9F,57,68,0F,0E,1D,FA,EE,5F,50,CE,24,85,B7,A3,9B,81,9A,10,BE,42,3D,08,D6,8B,A0,61,B6,4B,49,5C,6C,3B,28,78,20,1F,D4,EF,AC,74,60,E4,5B,48,1A,A1,EA,0F,6B,E4,DA,6A,27,07,73,4E,84,6F,9B,63,0D,4E,4B,47,52,75,3B,8D,D6,DB,26,B1,58,77,3A,1B,70,5B,B6,90,5F,25,4B,C3,9A,C1,B1,98,05,AA,E0,A7,BD,B3,7A,7A,70,A8,55,7F,24,9A,E2,58,E5,BA,06,A7,EF,E8,BB,CB,FA,A2,A2,8E,2B,7D,23,43,D3,DF,17,E9,32,1C,C8,A7,A6,F0,39,EE,FE,97,83,2B,26,77,8D,91,F2,2B,42,2B,31,82,FB,24,71,3F,7C,7F,36,40,57,10,A4,06,E1,94,46,48,B9,25,0C,45,81,E6,23,98,B9,FA,05,BD,BA,D1,BB,65,E6,34,02,FC,A0,81,EB,05,9B,A3,2B,68,B7,75,5C,21,CC,03,80,F4,D1,3A,0F,BA,97,E8,16,D0,FC,FD,D1,75,94,4C,B9,FE,5F,33,51,CC,CD,A4,1B,6D,87,94,FE,16,60,32,46,5F,8F,16,32,90,FF,B3,08,5F,FC,A0,BD,CA,0C,FF,31,3D,BF,72,A9,99,64,CD,B2,05,85,9F,D8,6F,88,2C,48,08,0A,9D,43,78,37,A1,65,C1,25,DC,78,E0,B1,5B,07,8A,17,08,86,3C,BF,0A,AA,A5,6A,AD,3B,3F,F6,4F,CF,72,72,83,D4,0A,FA,3C,E1,3E,A8,17,69,C7,4C,4C,50,73,A9,B3,C6,68,17,CB,19,95,72,93,25,90,EF,48,2C,48,7E,14,EF,9B,81,3B,97,77,09,B8,80,67,33,84,FB,B1,39,F4,7D,42,66,55,6A,D3,97,D0,AF,5C,EF,99,41,C1,DB,3F,15,5D,15,80,FF,69,35,B7,A4,3A,0C,1E,ED,7F,BB,70,0B,44,88,39,84,BA,37,87,B5,5F,6D,9F,65,BE,70,FF,AB,37,E0,E2,D2,46,C7,A2,CF,20,65,FC,CE,D4,C1,3C,63,0A,CA,18,9C,DC,48,A4,4A,7C,13,67,BC,4F,43,D1,D8,0C,FA,A1,27,59,EF,D1,67,54,7A,1E,71,99,6F,E5,3C,15,D6,3E,48,BC,6B,31,A6,BB,25,6F,67,49,97,63,31,FD,67,A0,CE,22,3C,89,C1,60,C6,7C,A7,85,64,44,66,73,5F,33,B5,D4,04,B6,B4,AD,81,97,A3,26,DC,CC,70,2B,22,80,BE,B3,9B,61,AE,4A,4B,29,48,28,C6,15,B6,63,FF,A1,50,4E,01,0C,68,1E,DB,E0,BE,C6,B2,D2,2D,0A,19,A5,D5,DD,41,14,5B,B8,A7,36,E0,39,7A,77,70,3F,56,BC,97,7A,9F,7F,09,57,48,13,8F,3A,CD,A6,98,C2,AD,E5,05,C5,05,1C,85,D8,95,83,6E,5B,F9,57,AF,65,C2,00,E4,B9,7C,B9,A7,6E,6D,D7,04,18,52,3F,F9,07,3D,4B,54,A1,4C,3A,DF,47,CE,1A,1C,AD,B6,7C,4C,87,C9,98,77,DC,C8,B1,1F,E7,7E,65,04,4E,34,04,02,48,E6,40,A8,CF,18,0C,C1,99,7B,F7,44,33,68,16,66,88,11,58,EC,5C,41,9E,0C,98,54,B0,73,EB,9C,07,3B,BB,8B,4E,AA,91,01,39,67,A8,53,DA,08,12,30,61,95,5C,DE,89,FD,64,07,22,00,08,DB,90,75,D8,9D,9D,A1,31,07,64,21,60,CB,EF,6F,A7,A7,E7,E3,FB,57,97,B7,EC,30,7B,F9,27,D4,CC,09,B5,C1,F8,3A,60,85,D7,B3,90,DA,F2,4D,EF,B3,BE,BF,9A,71,FD,02,07,98,8B,04,0B,30,BE,D3,B6,2C,F8,32,91,91,E7,2F,1A,6B,E0,35,30,AF,1C,6B,89,42,3E,63,75,98,71,1F,6C,B8,C1,58,0D,54,B4,C8,AA,C1,2D,8E,87,E5,2C,EC,24,A0,93,88,10,BE,3E,F1,E5,06,A1,FE,C7,84,5C,31,90,8E,6B,95,28,1B,1C,E2,64,D1,21,0B,04,82,B3,E2,A2,0D,5E,E5,DB,78,F8,6A,0D,7D,96,70,93,F4,15,A5,50,AA,DB,61,B2,4C,60,0C,9E,CD,2D,4A,14,74,6F,75,1F,3A,A5,D8,4F,9B,06,7F,E6,39,9B,B2,95,70,3F,75,ED,EB,20,BD,BD,57,40,60,07,97,9F,6A,69,70,74,2E,52,3F,84,68,09,7D,B4,9C,41,4A,EC,3A,27,65,F0,81,66,C9,6E,7A,71,EB,97,06,62,E8,DA,63,AF,55,84,38,F6,CE,C5,A9,5C,92,2D,76,13,C2,C0,DF,1E,98,A1,6A,B3,B9,21,A6,54,98,88,63,00,F6,F1,16,F8,8E,F0,77,E7,B7,B3,65,ED,2A,CA,26,01,A1,28,85,8B,45,9C,93,FA,0E,F0,ED,55,01,8D,0F,74,3D,CB,F6,E1,A8,E9,78,EE,3B,9E,BD,CA,05,E9,85,3C,DE,A0,74,73,0E,2C,57,61,01,9A,4E,E0,10,AE,10,3A,B4,9B,3D,C2,A3,15,2B,B6,63,21,4D,7E,18,1D,2D,81,FF,32,29,BC,F5,73,2C,71,94,86,09,A5,C3,22,25,8E,58,D6,AE,28,61,CE,B2,EC,87,35,C9,53,7A,DB,2F,70,DC,CD,D7,A3,29,85,4C,B7,28,8D,EF,2C,07,EB,77,87,E7,B8,FE,90,70,9A,91,45,89,05,E5,92,7D,0A,C9,F4,53,99,AF,37,56,54,29,2B,12,97,C3,AC,39,4A,24,10,91,8B,7A,A4,BA,CD,C0,C7,AB,07,57,F6,8D,50,F2,1F,F9,35,12,82,33,32,33,47,43,54,84,4C,09,BF,13,0E,75,3D,A6,E1,11,55,39,EA,35,41,AF,FD,E8,E2,AF,36,E7,36,22,BC,05,E0,D6,FA,0E,4A,E8,3D,8B,19,5C,97,A9,CC,3C,F1,87,AD,FB,C0,C1,03,41,32,29,7B,04,F7,38,4D,DA,71,61,3D,73,BD,00,32,D5,6F,1E,7E,71,81,CB,09,09,D4,28,8E,15,6D,BC,DA,DD,78,DE,68,64,47,2B,DC,F7,64,AB,00,A5,8D,C4,59,B8,70,EA,C7,FF,A7,0C,39,08,3E,AF,98,B3,40,46,17,5E,60,C9,15,72,A2,3D,51,0D,D5,29,11,02,3B,A8,B7,F8,4C,86,65,BC,BC,41,C6,2E,30,2B,A0,B8,E4,6B,7C,FC,4B,C9,06,16,1F,9E,9E,6E,5E,8F,B6,8F,FA,0E,83,F3,E3,04,3A,7A,47,98,EF,D9,D9,BD,8B,2E,6A,38,6E,19,48,C9,7F,F4,A1,F4,AC,0D,96,B5,77,19,79,BC,6D,18,81,5E,5E,80,31,C3,9B,65,5C,78,EE,03,3E,40,5F,1D,D4,72,82,0A,F9,0C,D9,7A,CC,0C,7E,77,0B,D2,51,F7,94,29,B6,FE,57,56,11,EA,FB,18,AC,02,EF,74,6E,DC,B2,62,38,65,EF,18,CF,25,2C,D7,9C,6C,11,F3,CD,A4,40,15,5D,CD,92,BD,F3,81,56,38,19,C8,7B,EB,EC,DE,EC,9A,DD,43,C8,E2,1E,8E,29,7F,30,3C,12,8B,41,DB,C4,F4,C9,52,AC,BD,C2,89,EF,0F,A8,87,71,81,85,C0,5F,24,A6,A3,1D,D4,57,44,B4,59,78,BC,B0,AD,90,67,47,86,C3,9F,B6,F9,76,7B,7E,4E,53,AB,56,B6,03,36,B8,D3,6D,8D,23,6B,C8,EB,7F,98,8A,71,68,12,2C,53,54,D7,16,DF,F8,25,8E,04,D2,6B,3B,D2,4A,60,55,F0,2E,87,49,F8,F4,1B,41,C0,69,A3,7E,53,3A,C4,5F,02,88,50,CF,D1,CB,FA,8C,06,DF,4E,4C,E6,E7,69,07,33,3B,DA,F8,ED,1C,66,E9,AE,29,D1,FB,F9,80,F1,52,71,A6,53,BA,CB,8C,8B,9C,6C,09,58,F4,E3,1F,DC,88,90,90,58,77,52,E0,7E,5F,E4,9E,61,5F,6A,1C,45,CB,A8,A3,59,92,EE,AC,0B,9E,AC,13,B7,72,29,4E,04,40,51,1E,32,17,C8,74,71,F8,C6,A2,91,FE,DA,FD,96,0F,FA,70,13,7D,52,0B,78,41,AB,E8,51,77,8B,EC,F5,40,D1,A7,38,CE,59,CC,1C,69,8E,1C,94,8D,06,C5,05,DB,B6,FF,95,56,82,D3,C8,E4,4F,66,88,FA,1B,85,72,D7,CE,73,F3,D0,5E,82,7B,BB,FA,82,97,90,F2,26,40,BC,86,63,DB,78,79,43,BF,8B,17,52,E6,5F,B9,6A,98,26,CF,5A,AE,7F,62,41,D6,75,1A,5B,0A,03,85,13,9B,9F,F5,CD,0E,59,9D,A5,81,3A,F6,4D,83,DA,3A,EE,C2,74,F8,08,1A,CE,D1,89,C4,25,21,0C,49,2A,E4,1B,E1,03,4C,77,BA,AB,32,34,23,70,9D,A3,4E,AA,6B,5C,5D,54,79,0C,25,DB,7F,0E,08,A7,4E,67,60,57,12,E1,C5,35,A7,00,DA,94,5E,6D,ED,8B,A8,42,43,B3,26,35,30,33,C6,8B,E9,BC,21,B4,D2,BA,AD,4C,26,19,FB,CA,8F,43,E8,DE,E8,C5,FE,89,76,2E,97,9F,03,28,26,AF,ED,51,6A,7F,84,F1,A2,D0,99,C1,63,6B,3C,32,AE,A3,0A,FD,5D,29,A2,02,EF,1A,B9,26,4E,46,98,DF,DA,24,FF,00,53,2E,DE,56,BE,69,7B,5B,4D,BE,2D,45,9A,AA,77,02,98,06,06,CA,A5,A3,77,03,0D,99,3E,97,E1,47,DA,63,AB,63,8E,C8,5C,0C,EA,10,79,F5,69,9E,1C,5E,EA,58,75,F3,02,E3,00,B2,69,F2,18,FC,08,8A,FA,42,7C,FE,C0,C2,3E,CC,5B,A8,2E,A6,2D,74,D9,7E,F3,25,E9,AE,BC,EF,F0,92,B1,00,B2,66,92,E7,4E,B6,85,28,7B,B6,77,9B,10,4A,F2,08,41,38,C0,88,30,C5,13,D1,76,EE,97,46,A7,3C,B9,ED,CC,E3,8B,B0,CD,93,AD,9E,9C,AE,86,AC,8B,CE,E5,86,36,CD,FC,BD,B0,31,9E,69,A2,61,5B,8F,38,59,E7,DC,11,EB,B3,12,31,15,CC,27,10,89,37,65,07,9F,E3,4B,B4,B3,32,25,69,FA,34,47,9A,EB,0A,96,4D,FA,BD,B3,A4,D4,39,92,65,54,D4,5A,51,53,82,31,87,80,0F,CD,57,B6,16,F8,89,E6,01,23,EB,5C,BF,06,B0,D7,D2,BB,52,59,18,4E,F3,98,60,10,C9,3A,88,1E,F8,B4,81,28,EE,37,3D,DC,C1,1E,B5,E2,E1,39,AE,2D,3B,49,18,A6,E7,65,6D,41,E0,0B,F2,E1,B1,5C,A2,49,E2,98,02,59,33,3E,CA,E8,D9,88,DC,F6,76,8A,95,FF,9B,2A,A7,F2,1D,BB,5A,CA,E1,DB,8D,87,11,8F,23,C5,6D,9F,65,A4,FA,F8,9F,B7,30,F0,6B,26,FC,EF,7E,2D,D4,93,B5,A8,22,80,A0,5B,93,08,CD,E9,F4,C4,BD,2A,55,3D,C2,C3,A1,83,C8,DF,12,4F,4D,23,DF,FF,AD,CB,7C,4E,D9,F7,5C,D0,1B,15,74,DB,3C,F6,7F,5A,1A,99,22,C1,9E,BD,A3,FF,FA,96,E6,0C,A8,14,CD,77,6E,27,CE,8D,7A,F1,44,B4,B5,0C,DE,67,70,52,DD,B8,BE,78,18,95,CF,21,0B,A0,3C,1F,AE,55,AA,E8,79,10,05,C3,E9,14,FF,AD,24,CC,88,F1,A8,39,BA,F6,8C,27,2B,2C,3F,E2,16,11,DC,F5,BB,D6,3F,70,AA,19,5C,D7,7C,8D,9E,D1,E3,42,AE,40,58,1C,F8,08,92,18,76,2F,3D,4A,BD,CC,0E,5A,B2,19,24,62,B7,40,0C,8F,9D,A7,98,5E,AB,47,1D,F3,C3,DE,58,25,4C,BC,23,55,9F,7F,47,55,57,10,AB,38,03,43,4B,38,5F,0F,FB,63,5E,B6,3B,7C,F2,00,6F,85,6B,1E,D2,3A,5E,CA,CF,6A,45,9D,8B,AE,46,2C,1C,F1,26,A0,14,2D,BE,01,CE,37,5D,1F,C6,11,99,C2,D3,AB,B7,EB,8B,E4,F2,65,24,BE,A5,E1,F8,D7,BD,5E,C0,6A,26,D3,B8,66,1E,93,4B,E2,91,01,9B,3E,CE,DB,28,2B,80,44,D5,7D,02,33,36,E6,B1,F6,35,A1,A3,B8,77,D7,91,EA,AA,C9,BC,68,91,E9,5A,CF,7D,04,72,F9,FB,73,A8,05,31,C8,F4,36,1B,CD,2D,C3,FB,E3,67,B3,2F,69,22,73,1A,7B,5C,A5,05,B2,AD,F8,CE,0F,AC,B0,E8,BE,5E,D2,45,E8,4D,2F,B9,A9,B1,13,1E,D5,35,57,7E,B9,AE,CD,0D,D2,4A,54,43,2D,C5,8B,03,1F,AB,DC,44,3C,79,87,4F,11,BB,98,01,F0,3D,A9,B7,17,C3,50,91,38,9A,67,C3,8E,A8,33,1B,CB,22,40,3C,8F,7D,89,37,B7,48,89,2B,41,76,08,A2,10,C0,2E,5C,6E,98,BC,96,1A,36,CC,0F,7A,07,D7,C3,4A,75,7C,18,7A,FA,57,97,C7,8A,2B,4A,C9,E8,C4,B4,25,7D,3C,EB,D0,32,9E,DE,0B,01,ED,9F,C8,72,26,49,62,08,4C,D5,B9,4D,C2,B0,82,B9,82,8C,BD,61,A4,CA,24,FF,49,80,2C,0F,BE,3A,C1,D1,A6,9D,2C,72,80,80,29,E6,46,2A,FD,7F,DB,64,C5,04,5C,FA,48,DC,8A,99,86,D7,F3,09,D8,33,64,F9,ED,82,9F,E5,91,AA,B7,E8,31,BF,00,94,54,27,20,4A,A6,BE,53,4C,A4,8E,3E,FF,79,DC,1A,84,18,A4,4E,5C,17,BB,9F,59,29,02,E8,96,ED,A3,D8,D9,FD,4D,34,54,E9,40,B2,39,86,B3,3B,08,DF,9A,95,63,72,3E,5C,B7,D3,AE,C3,E8,22,98,EB,E5,A6,B9,A8,02,3F,35,A7,56,81,E1,EC,79,88,16,BE,19,18,FE,4A,15,EA,DE,38,98,A7,E2,97,52,F2,77,3D,84,AE,D0,BA,15,BD,59,16,A9,A1,C2,0F,E0,BB,C6,D2,70,0A,CD,E8,00,B7,57,96,94,18,41,0B,FC,FF,A9,42,A6,27,31,FC,C9,12,EE,28,C6,D9,04,A6,D0,FC,4C,5B,C8,B9,86,AC,89,B4,02,5C,86,D8,05,95,D6,77,57,36,32,48,2D,D9,64,05,CE,00,49,56,32,43,29,42,44,9B,D9,ED,A3,09,2C,BC,1A,43,B3,C5,9F,94,68,86,70,B7,25,14,E5,1C,5E,D5,A0,5C,A9,22,D2,EC,C8,72,7F,72,74,5D,46,32,44,27,96,EE,D5,C5,48,35,0F,94,3F,CA,78,E4,63,D5,E6,4A,7E,2C,19,16,70,F1,44,FD,CB,68,C0,CE,E3,24,A3,1E,1F,AE,D3,D9,25,F6,26,1D,40,D4,6D,5D,CF,4C,A6,5B,F2,0C,C4,66,7F,2E,DF,E5,F0,57,41,E6,43,B3,07,BC,14,83,C7,C8,83,F9,78,B6,54,28,11,CC,30,25,1C,28,B1,25,08,7B,CF,76,D1,8D,FF,7C,A6,6C,31,54,9B,4B,7B,49,1A,CF,32,93,92,11,2E,1D,E6,7B,6F,88,D9,D4,ED,F9,96,AC,A3,E3,95,76,A7,41,81,37,C1,A7,08,5F,ED,C4,8B,F0,D7,B1,A2,63,8C,7C,52,F5,36,0D,A2,A1,3E,43,64,B8,66,4E,41,1A,44,34,D4,FE,95,05,B2,2A,7A,BE,B0,BF,EE,3B,D9,4B,B7,D4,EC,77,72,21,F9,51,01,92,40,65,A9,8B,59,14,B7,EC,6D,62,4B,A8,6E,53,4C,29,24,2E,F1,64,A3,E0,6A,BC,74,09,BA,6C,E4,4A,25,94,D7,92,13,2B,E9,C1,DE,80,2B,06,38,CB,5B,D1,BC,94,82,A1,58,E2,E1,E4,B9,FB,DB,B4,77,38,9F,1D,2F,71,74,2D,D1,DE,74,FB,13,A9,88,A4,55,E5,0D,E2,D5,AB,FC,D0,76,AE,27,B7,BF,42,FC,A1,37,58,60,12,EF,C1,02,D5,B1,3D,D3,EB,AD,64,B7,0E,7A,46,2D,82,38,A2,4D,CA,6B,BE,52,0C,C7,D1,14,A2,DD,F9,02,4B,7E,17,34,85,83,D0,52,0B,5F,8D,08,A1,37,8B,2F,B7,AC,5E,F9,78,CC,63,D7,DD,82,68,E8,EE,60,71,20,E4,00,AF,13,A9,09,7A,8C,CE,5C,EA,83,28,17,E6,29,10,7A,4C,DD,CA,10,C3,D5,D3,1F,42,1A,82,2D,2F,B3,66,A3,42,25,C0,E0,FD,6A,EF,5F,7E,96,26,C4,64,FA,CF,C6,52,F2,BC,F1,80,D8,78,91,40,09,31,63,0E,17,5B,38,EF,45,99,8E,20,A4,1E,53,03,1D,19,F0,96,60,8F,2F,2D,AC,0D,0C,77,46,15,C8,E5,B4,3D,D7,98,C3,79,61,F9,A2,70,61,FC,53,F5,DD,8B,CB,2F,93,FF,8A,8F,74,4F,AA,EB,06,FF,A7,D4,C8,76,1C,22,65,0B,13,22,E3,93,E7,69,D6,5C,20,A4,FF,34,98,B3,67,95,50,CD,6F,AC,0B,E9,B4,D7,64,41,2E,A3,71,03,B3,07,FB,46,2D,47,A6,A1,F6,65,18,52,E8,DA,D2,43,2D,9F,EF,05,4C,7D,9A,8C,49,F6,85,2A,1C,BF,05,A1,E4,4A,59,A4,46,60,E7,99,ED,B5,84,54,EC,A2,71,BD,ED,58,82,C4,7A,06,DC,A4,31,75,28,F9,6A,C9,46,6D,81,03,35,C7,8D,8F,CE,67,7F,D6,27,08,D1,66,5A,3B,FE,30,69,4C,F3,C9,99,70,B3,82,AD,A1,AF,A6,72,72,66,D0,A6,0A,66,B4,2A,BC,0A,B2,21,FD,7D,AF,CC,13,31,84,C7,1E,FE,22,50,B1,D1,B1,FE,4C,09,54,12,FA,C5,F8,21,59,2F,07,D5,67,18,3D,57,A8,05,64,AA,9E,C0,3D,A3,CD,6A,56,5A,86,5E,DF,32,F3,8A,22,93,DB,8C,1D,B6,3D,27,27,86,8B,4B,6B,4A,30,FF,26,05,A0,3B,4F,E5,CF,2F,F8,59,00,80,3A,EC,7B,F6,4D,B1,AE,E7,12,AD,55,24,3B,4C,48,0D,E7,4F,FC,6E,AA,A7,D8,D6,72,3E,CE,3E,58,D7,D5,28,F1,EB,AB,72,8F,AF,D8,3E,CC,1F,D8,14,52,24,78,E8,51,D5,BD,E2,0F,4A,D1,A6,AF,65,89,04,69,46,85,BE,FE,72,2A,A4,72,26,A5,79,6E,E5,29,F0,33,A1,86,45,70,C7,47,01,55,91,04,9F,C6,DB,46,65,B1,62,36,88,B8,B8,6E,A8,99,2F,35,E5,91,17,D2,19,DA,DC,C2,AC,A6,12,DD,C8,7E,34,3D,EB,8A,52,26,AF,C2,77,38,76,F4,B7,DC,45,CD,37,95,C6,C1,7C,74,8B,4A,C1,90,99,43,21,83,8D,74,CD,68,1A,CB,FC,E0,51,E5,15,5E,E4,27,A9,B8,D6,C3,17,27,45,E4,93,4E,7E,CB,45,26,81,3A,8E,D8,CB,25,77,54,86,63,A9,DB,A9,54,B8,72,AD,39,5D,32,60,6F,F7,E0,22,AE,10,1D,FD,8B,5C,C2,68,E4,80,FD,E3,75,C3,2C,A8,92,B9,3A,4A,50,3B,17,10,6C,70,3E,29,A8,26,2A,53,89,A9,36,7D,BB,26,6E,D3,E6,0A,28,E5,B4,A3,51,08,3F,F5,41,42,47,01,92,83,07,DA,93,7B,05,40,E8,64,29,25,7C,C5,48,15,D1,15,1F,05,F9,C5,F4,5A,3C,14,1D,4B,AD,AF,8F,69,60,8A,22,B4,16,D5,D6,A1,2C,83,D7,5C,4D,38,8F,70,19,AA,04,4F,57,D0,CC,A2,38,30,86,CA,1F,3A,8C,2B,3A,BB,90,15,83,20,D2,DA,2D,3E,C4,C2,2F,B9,8C,9D,B4,EE,84,E5,4B,BB,50,1E,2E,BB,AB,A3,0E,82,71,E5,7F,47,52,C4,A9,A5,E9,6C,76,76,9A,8A,08,30,1F,2F,24,9A,FE,A5,57,95,A2,66,0D,0C,C0,10,1C,F5,BC,36,F2,33,85,88,23,9C,65,C0,BA,6A,7B,85,DF,A2,32,20,29,F1,7B,37,1D,CE,3A,7E,52,30,83,E2,2E,33,83,FC,91,A9,C1,67,F1,30,05,64,AC,E8,0C,7C,86,F6,81,AE,8E,65,32,A1,36,46,7D,7A,F0,DB,DA,24,34,48,01,4C,8D,7B,20,AF,57,B1,5C,62,E8,F9,94,2F,93,B5,A9,69,9F,3D,A1,B1,84,D6,ED,03,0B,78,96,7B,0C,3D,31,DF,BD,C2,03,8B,D1,82,B0,CF,98,E4,F8,C0,98,C0,67,D4,C0,45,2F,4B,F5,81,EC,45,5B,0A,C8,B2,B1,AA,D4,33,85,4F,BF,D1,B8,50,8F,14,2E,74,AC,A3,77,F6,5F,EE,45,38,A5,E6,0E,CE,D0,7E,ED,2C,CE,6A,3C,AA,89,BE,E2,FD,4E,38,A6,37,64,57,7F,83,DD,EC,F0,80,47,4D,B3,8D,9B,92,A3,14,DD,56,2D,8D,55,A3,93,5B,8B,73,7A,E2,EB,A7,B5,BE,9C,ED,E7,C2,32,B3,98,16,A2,44,C0,76,97,AE,92,75,E9,2F,41,C6,B8,37,AE,1E,62,A5,2B,73,76,32,37,00,BE,76,59,76,64,9A,63,30,72,C5,68,C2,79,D5,21,23,2F,CF,A1,62,3A,ED,99,D4,A9,7A,41,AC,1A,45,00,40,04,9B,4B,D0,74,14,78,B8,F4,46,B0,0E,B4,DE,08,0E,FA,33,22,B0,A2,0D,74,1D,CA,F5,5D,60,25,4E,0C,A1,C8,5B,A9,61,1A,CE,C3,C5,5B,7E,F3,95,B8,79,38,BC,DF,D9,F7,A4,D3,1B,9E,ED,8F,59,67,63,64,9B,D6,47,E1,49,C8,A9,DA,D8,69,B2,79,F8,43,E9,34,C2,48,95,33,DE,1C,39,21,53,4C,66,79,42,1D,2D,83,B9,47,BC,40,C0,C6,90,84,4E,2A,23,85,05,F9,DE,67,E5,1C,B3,31,4F,49,37,C6,30,71,FF,18,DB,33,11,E1,39,74,3D,E0,56,B1,75,D1,BE,D8,29,8E,6E,F4,92,4C,07,60,41,AE,61,30,18,30,56,E3,04,D2,AF,5E,12,D8,5B,8B,B7,0C,DB,59,90,98,C7,57,2D,B6,D1,11,32,49,16,A8,54,78,F1,9A,DB,96,8F,C6,48,72,65,5A,80,A7,13,F7,86,88,10,C6,F1,99,1D,9C,DA,1B,3A,DE,69,FF,13,8F,AB,91,D9,CC,38,E2,D5,CC,05,7E,E2,89,1D,C0,11,78,53,62,9C,63,AB,3D,7E,56,3A,7A,63,62,D3,A2,48,FA,49,2E,6B,7E,7F,C8,5B,6D,E6,95,32,12,2D,CB,3F,6A,26,B5,75,CB,87,69,7A,03,D2,40,B2,0B,E2,18,74,E1,0C,96,84,E0,78,1E,DD,15,FF,8F,1D,CE,F6,7C,A6,C9,1E,9D,16,31,4F,3B,2F,B3,9E,D3,61,21,11,93,7C,BA,95,F6,0F,BC,A6,04,5A,39,43,76,C9,CC,F2,4F,80,B4,47,60,63,CD,0E,D6,3B,16,56,2F,A8,75,9F,7A,F8,48,51,2D,E0,1E,86,E8,3E,38,2A,D4,DF,6D,9F,8B,AC,C7,1A,C5,6F,B8,A2,44,6B,BD,FC,3A,7B,22,5C,00,35,75,B6,2E,8C,65,9A,80,5B,37,38,77,0C,06,97,97,8A,FC,2D,98,60,11,3A,34,40,E3,96,30,3E,D3,78,CB,D8,76,04,27,1D,5E,F2,B1,E6,0C,32,85,D7,0E,D0,3E,93,E7,7A,66,A9,49,AA,3D,33,07,2E,D0,8E,6E,63,1B,E2,10,16,3A,4D,B7,2D,A9,58,98,86,8F,67,AB,29,4F,A2,8A,90,68,90,1E,CA,DD,4B,79,FA,48,AA,7D,0D,4E,1E,35,49,98,A0,5A,1D,20,7E,44,C0,81,80,C0,0C,29,2A,72,2F,2F,FB,95,B6,40,E2,E0,35,54,4C,B8,0F,FC,7D,7C,2E,3D,2B,BA,4A,59,6D,1A,C7,F5,57,3D,29,07,B9,2A,8B,75,0A,92,54,27,DC,23,D4,35,5F,84,A7,9E,59,AB,6B,AA,62,D8,7C,EA,69,BD,65,21,4B,53,3E,76,0B,B7,76,AF,30,71,06,2E,3E,5E,BD,35,A5,F0,23,D2,8B,78,56,FD,76,64,5F,78,66,50,48,F3,66,00,21,8B,51,0E,F0,A3,C1,F0,AA,5D,F0,2D,62,53,CE,94,A3,F9,78,E2,39,9C,04,34,BC,F8,91,11,DE,E1,34,B0,E6,81,7B,7D,36,CF,01,EE,92,0D,B2,7D,C5,29,98,14,35,F4,7D,95,0A,A8,9D,75,AD,4C,A0,E7,42,09,37,53,B4,84,32,13,77,C1,94,59,77,75,87,1F,64,7B,B5,33,F6,DD,BC,A8,80,7C,A1,6E,DA,9A,A4,E8,C5,D0,6F,10,EF,5A,E1,4B,1F,16,45,BE,16,25,3B,71,FF,55,55,6C,F6,C5,2A,4D,E9,89,5C,8D,24,8C,F2,59,5C,E7,19,63,83,25,7A,A0,2B,BC,99,07,C6,12,22,E2,29,74,9C,68,68,CD,92,FA,F7,99,32,C8,39,2A,80,C1,40,A1,0E,DF,80,0E,00,95,3C,B9,A6,6C,47,64,E7,98,82,DD,50,38,DF,5B,C1,51,F6,9F,C0,1B,37,F4,86,64,30,26,36,64,B1,FF,E0,CB,24,35,03,FF,54,EC,64,BA,A1,34,89,70,05,4B,BF,CE,EA,68,84,B8,35,50,AF,50,C3,4D,AE,0E,5C,8E,71,17,6C,A7,2C,D4,C9,46,22,D3,71,FA,F6,5C,FB,6B,D8,1A,C0,06,FD,B8,5E,81,3C,5A,18,23,22,67,21,45,C1,B7,21,77,31,2C,81,71,7A,0C,46,29,94,E5,A7,D9,E5,E5,7B,5B,0C,2E,09,3A,FF,A4,AB,0C,56,41,53,6E,02,7C,36,F4,89,1C,A6,49,BD,A0,22,D0,E7,3C,65,F1,90,E5,C9,7A,EA,BE,F3,7C,0B,3B,4C,D1,68,10,91,08,04,22,69,1B,C9,B7,06,AA,2D,4E,B4,B6,94,37,D4,16,24,6B,20,C3,D9,9B,04,01,72,DD,56,E2,F3,6B,A7,44,17,3B,5F,15,73,82,BF,3B,E2,E4,49,C7,2A,62,33,4B,AA,6F,42,8A,E5,FD,C3,0D,9A,D3,05,99,6C,39,73,A5,BA,61,FC,9E,64,20,3C,0F,F4,FD,28,CE,32,A1,AF,2A,F8,6C,87,36,6F,6F,E0,57,43,67,E4,D8,23,9B,68,ED,C6,EE,5A,4A,AF,2A,0B,6D,BE,5C,B5,17,C0,FC,7C,F3,C5,E3,B6,3E,DC,77,94,6E,A4,E1,4E,6D,9D,BB,B6,A2,BC,BB,4C,70,89,33,26,FA,62,67,1D,B3,79,56,95,A8,E6,33,DF,AE,6B,A1,59,D8,E3,69,47,66,45,FF,62,4A,16,1D,91,FB,2A,56,3B,9E,4E,69,9E,57,33,4A,F2,A0,8B,EA,36,5F,0F,C2,C7,B0,CB,88,35,09,1E,E7,79,18,6C,5B,A2,3C,26,7D,7C,C9,F1,35,3A,91,3E,FC,E4,BA,74,95,31,2D,0B,BF,A3,91,0C,07,09,02,BC,B1,BD,BF,42,9B,ED,E0,2A,B9,05,C1,C0,C6,AB,0C,47,54,7E,26,31,2F,D8,78,58,04,8E,C0,B0,42,5F,EA,F8,E4,B2,DF,CD,83,D0,1A,F8,9E,EB,0C,A2,54,4E,DE,66,1E,72,62,83,09,F6,46,F2,EF,11,25,A9,D3,25,0B,69,78,BF,5D,CA,97,08,33,3C,23,46,4C,69,3B,F3,29,7E,A3,63,03,2C,F3,D5,27,E8,B3,14,71,97,55,4E,69,0B,B2,35,A3,CD,5D,70,40,08,D6,2B,5F,AC,9F,F8,3A,A4,37,DD,39,2E,05,E8,EC,94,CE,19,6C,D1,C2,C7,1E,2D,90,31,FA,91,0B,56,64,DF,F7,3C,41,48,66,BE,2C,0F,7D,C1,ED,74,17,C6,ED,E1,E0,CA,18,26,0D,06,8B,66,98,A9,4F,BE,55,2B,39,E5,A1,24,18,52,7A,6A,9C,24,32,9E,E7,CC,40,FF,03,9A,5D,1B,F2,95,9E,0C,FF,76,A0,EE,54,03,E6,B8,55,60,B1,20,B6,03,5E,22,0B,B5,2B,73,21,B9,8D,9D,EE,38,4C,27,F8,9D,FB,D3,7C,FD,8B,26,30,7B,7D,D8,D6,B6,D6,3A,CF,81,47,53,C2,F3,C7,47,62,1E,FE,3C,69,FC,FF,04,EF,9D,38,AF,DC,76,D6,A1,A4,98,0C,66,4E,1A,50,6A,27,E6,7A,94,42,C9,86,92,53,89,3F,0F,B8,3D,92,BB,7F,90,53,FA,36,D1,0C,63,6D,CC,F9,22,BC,9F,AA,BC,3B,53,68,E1,84,0D,E0,B7,0F,43,5C,5D,3B,07,09,46,9F,0B,8F,3A,6E,EA,1D,B2,0C,9D,3B,39,E0,F8,2E,EC,B9,2D,EC,13,D2,A6,E7,FB,94,E6,AD,94,30,C3,25,CB,57,16,5F,B2,8E,7F,46,8D,AE,B4,BB,2E,01,4A,C5,AB,7F,72,41,9E,C0,FF,1C,43,CA,3C,AD,48,F5,A9,13,81,73,47,92,2E,24,DE,5A,03,76,44,44,63,51,37,36,32,04,ED,BC,A3,AE,32,E1,8E,30,67,CF,DD,51,D5,A8,A1,F9,96,02,B9,BC,F2,DE,9E,3F,4A,B7,B6,C5,BB,CC,49,2C,6F,1A,E1,F7,BF,1B,52,D5,EC,30,56,F5,15,B8,83,E7,5F,B7,C4,94,44,49,1C,F4,E4,46,70,B8,44,83,E1,80,93,97,BC,D9,B2,77,1E,D2,98,76,47,90,0C,7A,F4,CD,D6,C6,27,B8,20,14,BF,D1,A3,A1,44,C7,A6,77,F3,87,A0,A0,C9,57,35,40,95,BF,91,05,11,66,61,B1,2E,43,46,C4,B8,0A,3D,A4,91,88,B5,4C,B1,A1,71,06,F5,8B,86,6E,96,E1,04,51,06,E5,75,4A,A0,00,F3,8E,72,62,DA,76,18,E5,8C,81,BD,8F,9D,76,CA,BB,50,8D,74,C0,7C,F0,18,E6,EB,B7,B5,BD,FE,85,F4,6D,03,51,3E,10,74,F3,56,6D,36,37,4F,6A,FD,8F,B2,33,81,74,34,CA,2B,19,CD,6F,2C,4F,73,87,88,5C,A3,ED,D5,FD,03,9B,9E,90,76,30,A4,7A,E6,92,6B,D4,29,58,27,69,EA,2E,0A,D2,83,7E,04,0D,0F,79,5D,D4,1E,56,A5,8C,4A,8F,F0,CA,51,DD,DF,83,C5,D4,11,FE,F5,D1,BD,A9,0F,7E,88,D8,19,AC,30,16,D9,2E,74,1F,B9,38,12,18,13,E1,35,DE,56,73,DB,57,E6,10,82,7C,8E,EB,2F,92,60,01,B1,1F,0D,01,D8,2F,1A,C8,BD,FA,C0,F9,6D,4D,8D,2C,97,95,FC,50,CF,93,54,4A,46,F7,10,61,C6,C2,4B,EA,01,B6,C1,92,9C,0F,FC,83,DE,4B,7F,B6,BA,3B,31,24,12,DF,EC,22,CB,45,5B,E2,AE,77,96,C3,65,D8,E8,EA,46,18,E2,04,E4,9E,FC,CD,05,38,E1,CA,8B,3A,51,DE,14,18,CA,D5,43,3E,E9,50,FA,4E,2E,13,EA,E7,06,C1,EC,DE,E5,43,42,E4,B1,47,CB,BC,2C,A9,97,49,CC,73,97,0C,50,29,2B,75,E9,31,14,C0,C2,7C,BD,4E,68,5B,9E,4D,EC,EC,3F,43,E7,A0,9A,4E,55,26,E0,A1,69,EC,F3,93,C1,EC,B9,39,10,30,8B,AE,83,9E,4F,A1,18,B2,BF,FE,D3,0A,55,4C,B1,33,92,72,7C,19,28,58,62,70,84,9C,DA,BC,DA,6F,4F,BF,1B,38,91,E4,22,F3,76,77,DD,74,D2,DD,A0,5F,64,7B,59,EE,63,24,D9,CA,83,8D,E6,1C,5A,4A,83,94,3F,3E,C9,3C,2B,F0,4E,98,89,28,48,6C,B7,95,F9,61,0B,66,20,2F,9A,E1,F8,04,42,B6,BD,79,33,D3,3C,19,06,1C,5B,FD,A3,CC,DB,4D,49,61,3D,18,AB,AA,9A,B7,9A,3B,01,95,78,87,96,CB,50,02,31,E9,3E,04,5E,D6,E7,08,60,9A,8F,01,A9,14,8E,3B,93,83,5B,ED,60,A4,E3,63,54,44,63,B8,FE,01,6D,CE,F8,A5,A3,12,86,4B,25,5F,81,15,1D,B2,70,39,07,7F,0D,21,7F,07,EF,16,F4,8D,4D,D3,B3,FB,72,26,7F,C1,74,60,96,EC,0F,8A,B2,40,F2,0F,38,12,E2,DB,5E,B9,E1,41,64,06,2F,F0,0C,D5,E1,A4,DD,B7,CA,AF,51,53,3C,95,22,C9,4B,4B,90,50,3D,91,F9,FC,E0,00,22,06,C0,CE,C5,47,81,D5,81,27,FE,CB,0D,D9,F1,FC,85,53,44,31,B6,77,F1,40,57,59,35,5F,E3,D5,19,D9,DC,F9,5A,D5,C6,65,C3,71,0D,12,26,E9,16,20,54,09,25,97,41,3E,48,8B,99,86,DB,F8,31,EE,46,C1,14,9B,09,24,4F,AC,06,A1,FE,2A,67,B7,58,C0,A4,D1,AD,77,CC,EA,F8,3B,19,31,67,FC,80,B3,FE,03,FF,20,52,5B,D9,FE,31,0C,8A,C5,FE,9E,CE,78,4B,A2,2D,81,15,48,4F,03,70,05,CD,CA,5B,C9,C3,F7,7D,58,12,88,89,BE,9D,FF,1F,68,07,1D,D2,6D,7D,2B,FA,44,01,A8,D0,1B,A7,DD,28,D1,26,81,33,64,4C,65,C5,6A,D0,19,E8,29,4B,EE,83,BA,4B,BE,F9,03,F4,8B,D0,73,29,4D,35,07,63,BB,E0,E1,E9,EF,A7,29,C5,56,BE,2E,E0,3B,DD,7D,F8,36,FB,C4,EE,82,81,87,87,B8,4D,8A,E2,87,4D,BF,48,08,EA,2F,24,52,87,D1,5A,14,34,E7,17,13,AB,D4,D0,2F,FC,19,D9,0A,8D,E8,3B,88,19,B2,A3,B5,DF,F3,22,63,1F,40,30,C9,6D,28,11,5E,83,C2,3B,C9,B3,56,BB,C4,46,DE,50,09,E3,6E,4A,D6,2C,F5,EC,5D,CC,3C,CE,01,40,EC,6C,D7,0A,36,E2,69,B6,3D,CB,22,50,E4,D1,5E,4B,0C,23,5F,3C,86,6B,13,D9,46,48,BA,6F,89,E8,53,06,9B,3B,5E,15,DE,F4,5B,8E,A2,7D,0D,7A,72,94,8F,82,46,F6,FF,05,68,F4,FC,A8,F2,5B,DC,55,FF,B8,5D,F4,73,3F,EA,88,E4,5B,40,73,D0,E0,3D,E6,1E,DE,78,42,A0,B7,87,AC,F6,0E,9D,2E,05,F1,88,F8,AB,58,8C,70,0E,85,EE,7D,3F,11,BA,07,DA,4C,6B,DD,61,94,5D,6D,2F,D9,91,8B,71,3A,C8,3B,BD,E8,34,CA,E2,42,5A,6D,87,42,8B,18,4A,DD,40,62,E6,24,45,51,3A,F3,F2,0F,37,9E,8B,2F,38,FF,27,B5,F4,FA,D7,11,45,15,22,F9,14,81,E5,C3,7B,7F,17,E0,11,76,A1,73,6A,39,2E,33,C9,B8,BE,64,AA,C6,3E,59,5B,3A,68,AC,CD,30,26,0D,6C,65,9E,6B,9E,A5,E4,43,76,7D,0E,CF,1A,25,A3,54,92,ED,99,75,49,0B,B8,86,60,C2,95,38,BE,50,75,C5,1D,C4,4F,AA,7B,2F,46,05,73,AC,0C,0D,4F,7C,AC,2E,F8,10,67,C7,B1,1F,0B,BB,98,F9,C1,39,BB,3B,00,7D,F1,A0,13,9D,88,1A,F8,A2,0E,82,A2,B6,B5,2A,49,A2,3C,1C,8F,D9,A3,FB,8E,48,99,37,06,39,43,D2,77,FB,A6,C5,FC,80,46,7E,4B,F1,14,7E,3E,24,DB,C6,53,9D,2C,C8,79,69,82,CC,8F,BA,C1,BB,6E,36,28,84,32,08,BB,0E,1A,A1,CA,9F,E2,07,51,E4,13,2E,9F,0E,90,F1,43,11,29,69,C0,93,A9,7E,1C,58,E7,55,C1,E8,29,FB,99,2E,A9,A8,56,44,2B,37,8E,88,81,32,41,D4,DD,93,F8,EB,72,67,DE,E0,7D,8F,27,1A,AA,C9,EE,6B,03,1B,41,EC,3F,1F,59,81,B4,22,68,42,19,8C,A2,42,79,79,1D,1A,80,D6,77,B1,B7,59,DE,F1,9E,76,83,23,E8,64,C4,F0,33,E6,54,25,82,0B,1B,FF,A2,04,5B,B2,BF,74,0B,98,66,53,0F,F5,5B,68,C1,93,E4,22,26,04,A8,85,8C,78,B2,15,85,D8,45,D8,E3,C1,35,D6,75,1F,2D,EB,CE,6D,1F,2A,AB,12,46,61,D8,43,20,80,F2,EB,2D,CE,25,52,60,F2,30,FF,E6,22,6D,38,E2,7D,46,76,FB,FF,34,45,8C,67,35,A3,FA,39,55,26,D9,B4,DB,17,FB,1E,3D,3A,12,2B,C9,65,D5,61,4B,70,B5,8E,E6,4C,3A,83,87,69,82,0C,AC,A8,4A,2F,3E,D7,2D,3A,0B,EF,97,D6,5E,D5,B9,63,4F,F7,E3,90,93,9B,CD,C8,C6,73,39,B3,06,57,E7,E5,15,D3,2A,4C,97,BC,69,D1,DF,72,0B,3D,09,84,29,FF,99,E8,90,48,92,DA,85,24,0E,91,04,CB,D4,03,9F,69,CB,7A,8D,00,D6,48,32,19,79,C4,C4,83,DA,BB,0C,39,04,10,6C,C8,15,0E,59,EA,B4,8D,07,73,98,91,4C,75,F9,D0,4C,90,72,E4,D4,CE,B1,7A,F6,57,1D,2B,47,40,33,1F,C9,70,9C,0B,C2,23,55,D4,DA,21,7A,85,B3,55,A3,86,D5,FD,A4,8A,81,A6,92,12,28,CF,A1,98,65,7E,9C,6B,23,7F,6B,6C,04,4F,6F,23,03,03,A7,6D,0F,45,89,12,77,06,ED,BA,63,E1,E6,C5,D9,C5,1A,40,88,95,3B,EF,3E,F4,E3,7E,65,6D,D3,AB,CD,85,8D,9C,9F,67,EF,D5,99,3A,A8,59,22,02,05,AD,8A,91,06,C4,C1,92,03,74,9B,B2,F0,FC,58,05,E4,64,6C,BB,B8,7F,32,01,26,8F,B4,FE,E5,84,BE,17,D0,8F,0A,AC,7A,D2,AB,DA,F2,3C,95,09,3F,35,DB,C8,83,CD,DA,03,E5,33,BF,AD,EC,A8,20,92,F0,E7,22,B0,5D,D6,2C,17,80,9F,9F,B3,DF,56,D3,A2,24,32,C2,58,89,88,43,F3,0D,FC,4F,95,07,F2,35,34,FA,A8,4F,A1,F9,2E,5F,BC,89,91,1E,ED,D2,7B,75,1A,20,28,75,DA,B8,B9,70,BE,62,CC,0C,19,D9,15,E9,47,19,12,BB,66,DB,C4,42,91,81,6E,F9,7F,0C,92,56,DC,7B,97,D1,F1,F0,43,D5,18,C4,98,14,9F,B3,B4,F3,00,E1,06,88,EE,CE,7C,26,09,44,40,B3,F9,07,23,E6,82,CF,9A,00,46,B0,05,94,0C,AC,A4,F7,BE,E4,4A,EB,B1,72,FB,86,D8,9F,67,EB,10,BE,D5,E5,D7,8C,9F,DD,0E,D0,B0,AA,D6,2A,3F,D1,B9,9C,E1,BB,FF,AA,F3,22,46,D6,B7,89,C7,5D,BB,30,C4,51,06,54,F2,25,6A,3D,03,A9,81,FD,8E,66,5D,59,5E,C9,F0,3B,7F,2D,AE,1F,BA,58,D2,BE,B4,C8,B4,15,23,45,A9,00,CB,1D,C2,E7,11,F3,90,AC,A3,B0,AF,11,E6,31,45,53,3B,59,45,E9,AB,08,AC,B3,0C,4E,0B,50,A6,D0,79,8B,9B,0E,58,4C,8D,EB,4C,38,55,F9,51,4C,D9,59,D5,71,B2,1F,C7,75,80,46,A1,D6,28,0C,E5,A4,F8,21,0B,63,70,60,C8,98,BB,C0,CA,A6,52,EF,72,0B,81,43,DF,5C,C9,F3,57,6F,48,BA,65,7D,39,D5,82,F2,AC,3D,3A,A8,0A,11,EC,CA,4A,BC,0A,BB,72,1F,19,DE,63,A9,62,00,DC,09,85,FA,ED,BF,23,6C,EC,4A,75,B2,E9,91,66,45,18,9F,20,C5,D3,A6,D8,0B,CD,24,67,3D,C6,DB,C1,09,3F,4E,EC,E1,89,40,70,1D,CD,00,CD,6B,C6,99,0C,01,6D,25,FC,C2,09,3B,6F,55,67,3A,0D,FA,EA,D9,95,CA,F1,14,3F,60,74,D6,8B,8B,E5,CE,DB,7B,09,6D,20,EF,68,B2,86,2C,C1,9B,16,D4,88,40,62,D0,21,05,92,89,A3,DB,E4,C0,1E,95,19,83,7F,FA,C0,CD,DF,0A,9A,17,14,C4,59,5A,5A,77,D8,4C,6D,0D,4E,EE,4B,47,92,C8,4D,2E,3E,D3,7C,C4,63,20,B0,DF,49,C0,9D,1D,E5,E2,3D,26,33,64,0E,8C,97,FD,09,82,96,8C,36,7C,45,76,67,BB,F7,36,9C,3C,D8,22,FD,61,14,92,CE,9F,89,B6,EA,A3,CF,AD,EA,4A,00,40,E5,CB,83,59,15,51,54,64,51,0A,5C,83,4B,5D,05,80,38,D5,65,83,F8,52,C8,4D,91,DE,0D,E6,2A,FC,68,34,EB,65,57,44,6B,42,79,AB,C5,52,06,14,63,7E,2B,37,71,98,5C,18,2F,82,85,20,00,FD,BE,4A,35,A7,B0,13,D6,91,FA,E3,F8,71,8A,EB,4B,17,37,76,84,38,11,B6,D9,0E,1E,05,9B,9C,F2,BB,E5,47,0C,0B,C1,CC,BA,82,BA,8D,3D,F4,83,BA,74,D2,C6,E5,B0,3F,B1,9A,FE,A1,68,8B,DB,C3,2E,97,45,E1,0B,E1,59,00,34,5B,13,D3,CA,63,9E,DC,D4,BE,FF,D9,FD,A8,94,93,9E,EF,47,DE,A9,6A,1B,05,7D,41,D0,AA,E4,E8,B4,97,A3,AB,20,29,E1,A8,21,27,EA,9E,80,02,92,B4,D3,5A,34,B8,16,41,35,8D,51,65,AF,38,8C,8E,29,49,6C,01,6C,7E,11,8B,75,BB,29,8C,22,1F,18,8A,88,B4,AE,A5,06,C3,15,72,91,DF,62,F5,82,8F,0F,01,38,88,43,6C,33,A2,77,EC,55,6C,C4,CD,5A,15,27,37,EF,2C,8C,C0,B2,FB,07,D4,75,84,38,6A,9F,51,58,6E,3F,39,32,D0,F7,C3,06,D4,81,F1,E9,30,E3,E9,E7,29,10,C7,F4,70,6C,F3,AF,B0,D8,03,A6,AA,63,D2,38,02,73,AE,AC,01,36,B9,86,C0,12,2A,03,E0,81,7A,EA,64,91,E3,CF,D6,6C,77,D0,80,68,68,21,A3,98,3C,CD,48,BB,37,E0,8C,7F,C0,C4,3A,D3,EA,FD,79,6A,A5,C0,72,33,9D,FB,46,26,A0,AB,3A,0B,13,16,2E,33,59,B0,3E,A8,E4,C6,89,E6,A7,22,5E,AE,96,E5,C5,A6,DE,4F,EE,22,90,36,EA,00,9A,04,E7,74,4B,84,27,C6,8A,A5,51,11,82,AD,CC,A0,A4,0E,1C,E9,47,39,6A,AD,99,0F,2F,11,FC,3B,79,A2,05,4E,49,D0,57,BE,D2,D9,58,C7,8F,59,35,57,D2,F3,44,F7,D9,A5,66,0E,C0,32,D7,B8,F0,14,19,37,E8,AD,C6,C5,C3,89,EA,8E,DA,9B,C1,78,1C,5A,33,C3,40,65,2B,C2,90,D4,1C,19,F7,0F,B3,65,F6,E1,55,9E,AA,A2,D7,CE,52,4B,5C,11,83,E7,65,BB,5E,33,5D,3A,EA,6E,EC,1D,36,B4,42,F0,2C,E5,10,8D,82,08,E4,CD,B0,9E,30,11,B1,CB,5F,19,41,DC,CC,D9,DE,BB,A3,9B,BD,EF,07,44,10,50,44,90,6D,1A,CA,86,3F,07,18,67,83,04,BE,A9,CF,00,35,38,F6,92,CE,67,B0,D0,FF,7A,46,86,18,DC,53,5E,45,6C,98,44,5E,B9,C9,3C,6B,D5,59,C3,4E,0D,B5,E2,3E,61,05,45,36,34,BC,3B,67,52,9A,59,D6,89,FD,00,79,DC,05,CE,AE,C0,D0,15,E7,80,AF,93,11,2F,F1,62,B5,82,B9,51,4E,A5,FA,1B,41,31,08,77,06,E7,05,27,09,4C,5E,98,28,10,EF,6B,17,01,1C,40,2D,E4,66,68,F4,E9,4A,FA,83,3C,90,94,D0,80,A1,A8,B7,02,AA,14,F6,16,AA,B3,96,D7,50,AC,33,FE,03,74,6F,ED,B2,B8,91,1C,0A,65,BA,85,88,CB,3B,E6,EA,2F,F0,DA,31,90,8A,9C,E0,ED,B7,30,B3,63,A2,67,8D,4D,20,47,9C,4D,14,57,9A,32,4A,F9,0B,4B,5A,67,BA,B9,C2,DC,00,61,86,C5,84,4D,C5,F4,AD,6F,4E,81,E0,E8,EA,05,1C,ED,83,58,1D,1F,1F,29,02,08,75,E2,41,2D,A4,C6,44,51,A1,56,9F,26,48,AA,C2,8E,CE,C0,35,D2,15,EB,5A,67,2E,02,CA,B0,C4,89,6A,E6,AA,55,61,2D,02,8E,45,A4,C1,0D,2E,97,AD,B7,89,7A,5D,D0,ED,BF,97,B7,67,B9,74,0E,88,0D,ED,0B,09,B3,20,03,D5,EE,E4,86,10,CD,72,68,5F,30,ED,E3,F3,97,2C,EC,02,E8,59,59,5F,AB,D3,34,9B,E6,DA,C3,6A,E5,51,B2,7A,6C,CB,86,50,78,16,5B,2D,20,F7,1E,BC,B7,50,8A,31,4E,AA,AF,82,70,B4,79,05,EB,53,D9,24,38,FC,3B,50,57,D3,27,8B,9D,B6,97,ED,77,49,F0,5C,E5,F3,DC,B0,FF,0A,CC,10,E8,CD,62,DE,33,E5,D6,A5,A9,D1,76,06,2B,35,DA,84,65,E2,23,97,6F,5B,39,5D,C7,FC,49,71,27,30,BA,BD,5B,5B,A9,BE,1E,C6,56,B7,EF,2E,78,F0,70,DC,38,33,03,06,D4,A8,3B,58,30,E3,AB,C2,E9,F8,63,9B,49,9C,9F,11,FA,EB,86,1C,80,ED,2C,2C,15,4E,3B,93,B2,CA,45,AF,CA,F9,87,16,1A,25,63,7E,62,C2,B9,B4,A3,35,5B,C7,A1,8D,AF,05,FB,E2,A2,B7,F5,E2,66,C7,00,FB,E9,A6,43,95,06,FE,22,CD,3E,AC,76,0A,D0,D1,BD,10,B3,64,AC,7D,7C,52,38,BD,3A,C1,AD,94,F8,8E,F7,B2,E9,22,DC,97,19,96,88,83,FB,F2,7D,28,D9,99,0C,21,1E,03,13,05,10,43,89,CB,A5,48,81,1B,E1,4C,74,80,D3,E1,96,20,0E,E2,1B,BA,5F,1A,24,C2,29,37,34,49,CE,6B,9C,48,18,AA,A4,64,07,9B,E0,FF,D8,3F,00,5D,44,47,93,6C,DA,AA,23,A7,3C,8C,D5,61,C6,34,7B,C2,06,27,2F,CD,E4,78,8D,3A,17,1C,FF,17,5F,0F,C7,2E,61,CC,43,A5,B3,A1,C4,4D,19,79,5A,CE,16,C4,A8,65,B2,D5,3A,9F,24,80,02,2D,0B,54,1F,F5,4B,86,6C,D3,A8,D5,59,A3,43,E2,F4,8B,4E,34,EB,45,12,96,D8,8A,BB,6D,B5,FF,3A,AE,95,7C,65,3E,2B,72,7F,32,E7,33,11,0B,2A,6C,E2,B9,B9,41,DC,6C,46,85,1E,8F,3C,5F,DE,8F,9F,DE,DA,CE,5F,F3,D0,1F,07,8E,D6,00,FC,2C,F6,85,3A,87,53,9E,1E,23,8E,08,DF,1F,1A,6A,CC,35,83,72,A9,25,CA,C7,00,BA,DB,B9,05,C5,1B,C3,E4,33,75,BC,E4,E9,76,28,C7,74,00,81,59,8C,F3,F8,12,61,C8,35,06,BF,68,5C,25,F5,DD,AF,04,E6,10,4F,91,8C,C7,99,87,E1,53,B9,84,4F,85,1C,B7,A9,9F,24,3D,77,FB,37,B2,49,46,E1,DF,E5,4E,1A,B5,9D,DE,6D,69,21,E4,BA,FB,0D,86,0F,66,80,F5,E8,4F,1D,AF,AD,30,6D,8E,9A,65,B9,B6,B8,E0,59,F9,7A,1F,0E,DD,AF,ED,6A,C9,E1,C4,9D,3B,E1,C3,48,86,1F,4F,9C,73,33,CD,48,01,18,E7,53,FB,AB,AA,69,6A,F8,96,D2,85,7B,AC,29,A7,3A,03,7C,6F,EB,45,91,3A,FA,12,64,A3,C7,B9,38,2E,7E,89,E8,21,1B,AE,5A,14,85,BB,CB,78,5E,69,84,AB,09,2A,6F,07,40,04,79,A1,55,AF,8D,52,4A,4E,B5,82,C6,1B,AF,0D,DB,85,99,9E,5A,04,4A,A9,2E,B5,12,D8,CE,CD,F3,C6,3C,1C,74,7D,EE,A1,08,A7,B6,FC,BB,59,73,67,71,BD,E9,B7,05,68,56,A6,BE,08,92,A8,25,25,AF,7F,28,A7,0E,55,C9,0E,60,7F,BD,D3,39,C4,56,92,F7,2C,D0,CE,11,74,A0,54,B0,FE,F4,54,6B,2E,63,1F,AD,5D,A8,75,7F,64,F8,1F,25,F8,A9,EF,12,19,BD,1B,28,0D,79,E4,2F,7B,74,C9,8E,80,7F,31,FA,AF,D0,EE,9C,F3,43,FA,4A,9F,20,43,BC,DF,7B,E9,AF,B2,77,E4,0E,8F,A6,9D,27,70,B1,E4,9C,9D,14,2C,D3,10,51,36,58,84,4D,F5,9D,0A,C4,E6,41,AC,36,55,C3,DA,59,6B,26,2F,B7,CB,C3,D5,F2,CF,ED,6A,A1,3E,39,FA,4F,5D,8E,57,64,0C,21,20,67,17,DE,E3,CC,3E,EE,BE,39,54,A3,01,42,A0,03,84,53,46,55,9A,49,63,52,8B,3A,25,D4,95,9B,18,C7,E6,B9,B1,84,B1,79,9E,D2,A1,04,D9,4A,DF,38,EF,9C,9F,92,2E,BE,C5,FE,B1,34,E1,8F,B7,ED,DB,20,A2,04,DC,66,53,78,F1,6B,63,48,C0,E3,12,1A,5D,A5,46,D0,F8,A0,A4,16,77,28,B7,FF,A1,91,6C,75,53,4B,A4,3B,70,C4,6A,40,53,C9,93,ED,56,3C,2F,C2,C9,51,A8,83,39,E4,52,D0,6F,DA,E2,E7,D7,72,5E,2D,24,99,70,82,6D,74,8F,00,E8,84,A5,F5,3A,6D,76,C2,28,72,39,4C,A1,26,C7,8B,37,B3,4A,90,BB,A6,BD,70,20,25,D6,7F,CB,4A,36,B5,00,92,AC,22,3B,EC,9E,FE,5F,C9,E1,AE,FE,70,90,5C,16,E2,B2,9A,0E,59,53,B1,EE,45,2B,C7,B4,1E,B4,3E,FB,F0,B5,83,AE,5C,19,C6,46,C6,96,C2,03,2B,3A,2A,D3,EB,30,9C,C8,9B,AA,6A,B6,CF,10,25,F2,FB,11,F1,16,81,B8,1C,89,9D,7C,E3,AD,48,29,82,5F,E4,65,E7,B6,D3,73,E3,B6,3A,14,4E,60,8C,CE,0F,A2,67,08,76,81,7D,53,7C,0D,32,C8,99,36,8B,D3,7B,E4,59,DD,54,8C,C9,F2,76,3F,3C,5F,C5,0B,83,76,BD,62,B5,8F,4A,62,14,21,95,2F,F6,35,E3,E4,85,16,FC,82,C4,F7,A0,71,4A,40,BE,60,F7,B5,46,78,CE,BA,CF,23,0A,ED,50,E0,70,0D,CF,DC,E2,02,A0,41,27,7D,D0,F2,04,EC,11,B6,D8,A3,44,99,EE,30,2E,BA,A2,AF,BC,1E,2C,D5,32,1F,53,95,28,48,BF,50,C8,B0,5D,94,6A,2C,61,85,67,F9,B3,5B,1A,9F,68,B0,12,C6,31,73,26,92,3D,1A,73,8B,73,AB,D8,E2,1B,25,50,52,98,A1,DF,96,66,16,CE,72,7E,28,6A,32,32,43,DC,48,B8,D2,89,B8,57,94,28,80,5A,45,5A,F9,CA,E0,A4,02,7B,E3,6E,3B,31,C3,03,6C,15,FD,89,6D,EF,54,79,AE,95,3E,45,17,73,1F,BC,79,C7,81,10,E8,EB,43,99,EC,C9,09,6A,2E,25,CB,5C,D0,E8,B1,9B,5F,D6,1A,83,D2,0F,28,69,22,70,31,7B,FC,1D,74,C6,54,6D,AC,62,9D,4F,04,10,B5,39,D1,E5,88,4C,4F,D5,F0,00,F1,54,51,65,94,5E,A7,75,6A,A2,7A,15,0F,DE,A9,2F,AD,43,E5,D9,1F,C9,A5,34,42,41,CE,BB,9A,90,D5,5A,26,71,8A,A4,A6,FB,F7,1A,71,3E,3F,85,7B,C4,AC,C6,A9,63,0E,A8,8D,21,C3,5E,35,7D,7A,A1,D9,8C,9D,75,C7,3B,0D,B1,57,63,B7,AA,E0,3F,06,54,1D,77,62,76,E8,40,B4,4B,26,7E,0E,69,FD,D7,4B,D5,44,DC,12,FA,67,88,15,92,76,34,09,90,F2,84,4C,98,49,51,F7,DE,50,AD,D5,51,DC,A3,38,48,A0,FD,08,4B,66,CA,0F,A5,FE,AF,37,72,69,F7,77,1F,21,90,1F,6A,28,FA,C3,EE,26,44,C4,1A,6B,F2,D2,80,F4,3C,81,2D,C0,1D,BA,31,65,6E,8C,9F,A3,3C,F8,2A,7F,07,73,EE,A8,2A,D8,6B,A3,14,05,79,7B,70,F8,1D,EA,B5,F9,38,FF,DC,D4,47,86,F5,BC,63,BC,05,B2,FB,02,A0,1F,0D,13,27,74,ED,12,A8,C6,82,EC,50,9C,28,CB,39,4D,7A,9A,1D,54,FD,58,09,2D,B2,1D,05,88,BE,E7,62,64,14,C9,DC,60,63,5B,64,77,48,65,CE,51,16,9E,B1,CC,09,94,A8,C0,C3,31,1F,A9,EB,CD,C7,80,2F,6E,8D,8E,63,0C,A7,61,DF,65,F9,96,B0,D7,2C,3D,B9,3B,24,10,E0,60,8F,C1,B7,0A,0C,2B,3E,2F,F4,E1,3F,C1,71,1E,4E,EF,A4,31,E7,51,F0,44,39,AF,A0,9D,09,0E,78,D6,B6,0F,2D,7B,BF,98,63,F6,BA,B1,14,49,3E,62,36,F1,13,41,02,BD,20,AE,D8,7C,3C,84,B5,9B,8A,CB,53,28,AA,FC,27,09,9C,EA,48,2F,1C,8F,B4,B2,26,1F,DB,40,1B,B4,CF,27,FE,73,14,4A,26,CD,38,C9,41,DD,94,8E,0C,76,8E,49,50,89,BE,6A,EF,40,4D,A9,60,BF,1E,7B,22,5C,4B,82,3D,7D,E7,79,0C,BD,AF,9D,FD,04,CC,22,2E,99,F3,5E,04,67,EF,B8,B7,26,00,DA,25,12,1D,DB,F4,E3,0C,3A,60,DF,0B,3C,94,57,1E,A6,F3,93,01,7F,BD,40,F0,F6,16,27,99,AB,30,74,5D,2B,9E,E6,E7,AF,74,8D,BB,A9,84,85,0B,C3,3B,19,8D,CA,43,17,E5,9A,D9,8B,A8,63,1D,98,AC,09,35,45,AC,60,19,14,D0,E3,77,F0,8B,78,5F,A2,E8,34,2D,31,B2,7E,4A,AA,17,FE,16,66,DF,0A,8C,87,C1,79,F4,1F,02,90,3B,9F,10,04,0C,F4,4A,17,6B,25,49,16,ED,6E,D7,EC,A5,EE,C3,75,82,5E,44,B8,D8,6A,21,4C,86,52,AF,46,51,20,6C,97,D6,CB,CF,17,13,DB,77,57,48,4F,AD,58,C3,0A,06,1B,C3,91,E9,60,2E,8B,2B,2C,B7,89,CC,30,AD,02,4A,51,A4,05,2A,4D,02,E6,AD,B4,97,B3,4F,52,1A,1B,A3,9F,91,90,46,11,84,B7,4D,EA,8D,DC,0F,FC,42,6B,32,67,C3,EF,91,E6,C3,D1,3B,0F,07,0F,54,C0,0F,B5,7E,6C,73,8F,E2,AD,83,A6,7A,FB,A2,48,9B,DF,0B,FA,01,DE,D2,14,37,E5,35,88,D9,C0,98,D7,22,F0,55,CE,12,85,19,B0,40,B1,E1,FE,A0,96,AD,B7,A7,E8,A1,1D,73,65,F6,36,7C,31,B0,90,2D,27,F0,4D,C8,9A,9C,BC,5A,E2,4B,84,3E,45,03,CB,14,C7,BB,34,00,CF,77,13,78,76,99,F5,94,7B,7B,BF,66,60,89,DB,7F,F8,A7,5C,2F,3B,A5,73,F9,58,35,82,CD,57,A2,F2,09,B0,12,A1,03,CC,FB,AF,E4,E9,0F,62,A0,D7,B0,5A,94,85,33,04,27,14,36,A8,2B,45,DA,50,46,80,2E,B0,84,C9,5D,19,64,2E,E5,1C,E2,8D,32,D6,DA,26,D4,CE,E6,59,33,F5,52,D0,CC,70,68,C5,FB,89,95,C1,74,F5,4D,7A,BB,E5,9F,16,C0,38,BC,68,7F,97,C7,26,E9,22,12,77,19,BF,4B,10,E9,15,C7,7C,B6,F0,88,32,3C,E6,19,A0,B8,9A,16,38,B1,49,61,5F,A3,B5,B6,CF,89,6F,84,EF,B6,D3,E1,D8,B6,BA,A1,1B,28,E2,54,34,B1,EA,D1,27,3A,3C,29,07,14,E2,37,34,5D,52,1E,15,EC,6D,1B,C9,58,94,21,D5,97,46,C4,DC,A6,64,BA,52,E9,1A,26,74,2B,FA,63,4D,97,1E,E6,D5,60,4E,C7,F4,47,63,E1,C3,D0,81,06,70,A6,6A,82,D9,7D,B5,5E,14,1F,D9,CB,22,2B,9A,7C,13,7A,04,0E,22,F5,60,3B,BF,F2,96,96,0A,3E,80,4A,7B,9B,EC,D7,5B,C7,02,9D,9F,5E,33,90,9A,92,AF,31,F5,D1,4D,8F,AF,FE,C8,EA,AE,75,B3,95,B0,4D,E2,3B,3E,9A,7A,F2,07,6F,D1,CA,FC,19,6F,33,C2,57,01,76,5F,74,93,F4,2B,98,51,05,AE,64,56,CE,04,66,8B,C5,91,3D,45,4D,AE,73,0A,0A,B8,D3,89,62,10,B8,62,94,1B,CF,DE,61,39,5C,4E,3C,5E,1B,E9,79,E9,39,C5,09,60,4F,01,74,AE,06,1A,1D,43,9F,D6,5A,B8,EE,AA,98,51,CD,DB,65,F1,00,CF,77,C9,40,7E,18,8D,94,DB,9D,09,7C,10,D6,FF,CC,74,18,B8,04,20,61,2F,F9,7C,11,2C,3B,64,E4,0F,99,A4,97,CC,5D,5D,DC,44,32,F6,B0,08,A2,AF,49,9C,91,D0,96,27,B0,51,7D,F4,C6,9E,77,BC,B0,89,21,E8,A8,27,01,BD,FA,42,16,38,47,B5,09,EE,D1,26,EE,08,A0,8B,BC,31,62,F5,EB,B2,D8,E5,C5,86,27,3C,6F,E0,2E,7F,AA,BA,1A,E0,24,1E,8A,A8,E0,1B,34,35,6B,C1,C8,44,29,8F,D9,45,26,F5,7A,2A,50,A7,49,7E,68,39,28,9E,4D,83,8D,C1,A0,7F,2C,D0,2C,2D,90,4E,3D,D0,55,1A,DA,23,AD,FF,3E,1C,D3,C1,2A,C3,01,D8,B8,83,91,AD,50,17,79,69,53,75,0F,AC,9D,40,1F,2F,B0,CF,D6,55,34,FB,FA,57,2D,92,54,68,13,BE,58,8B,66,91,4F,D6,56,59,0B,ED,CD,16,2E,C0,A7,4C,1B,21,B5,8D,E0,A0,59,BA,5E,B5,16,AE,2F,64,6C,DB,AB,75,6A,11,4F,50,2A,6F,FC,72,C0,A9,CA,51,35,0B,CD,8F,63,8A,B3,24,21,6F,9F,0C,A8,70,E0,C4,93,50,51,32,3F,E4,56,AD,A9,26,D1,59,2F,89,25,25,5D,BC,CF,63,F5,85,5C,5B,86,24,92,B7,26,DD,9F,8F,F1,8B,BD,B9,8B,1D,D5,72,9A,31,4E,BC,C5,60,CE,7B,8A,17,74,BA,30,86,9B,12,30,39,88,0C,77,84,6B,AE,8A,D4,04,B7,1D,C7,A2,E1,F2,94,34,C8,DF,57,B7,F6,D9,9B,88,96,D0,65,43,67,D8,C8,BF,05,6A,00,88,4E,43,BD,0C,3E,86,D2,98,14,0D,43,D1,E7,C6,73,AE,AE,32,68,9A,BD,0A,80,A0,FE,DF,DD,07,36,71,11,28,37,7F,D1,B0,F1,79,ED,53,51,66,33,20,58,0F,82,AB,CC,C0,C0,C4,C8,C1,09,50,19,EA,F4,DF,C4,DC,76,CD,59,05,A8,4C,A2,58,AA,50,AE,EC,E7,EF,26,16,3A,3C,07,CE,87,61,A7,5D,40,16,77,5E,58,6B,BA,22,95,B2,10,5B,38,72,8A,A7,97,B0,9C,14,71,B4,83,BD,1C,0E,4C,D8,4C,4C,5D,B6,78,60,56,5E,94,9E,B9,35,0E,31,A3,86,1D,B2,A3,78,04,86,00,25,8E,27,C7,68,0D,DC,EF,20,7D,00,22,F2,8F,10,A9,EA,A6,C8,A7,33,20,CF,0D,BC,3B,DD,29,D2,EF,D4,D2,7D,29,13,3F,86,8B,34,49,B1,18,C5,10,F8,3A,71,EB,66,36,11,E6,01,15,49,E7,34,38,24,C6,6B,88,2A,EF,3D,99,59,02,6C,B9,71,8F,7F,C9,1F,E8,E6,85,30,07,F2,CD,82,B8,D1,A5,EA,1F,D0,7B,33,69,EF,09,EB,6D,39,24,82,0E,5C,38,D4,8B,59,9D,6A,B1,0B,8D,62,50,3A,9E,D9,23,C7,4B,14,02,11,5F,43,5E,38,20,7A,78,4E,36,33,3F,27,50,AC,93,5F,A5,36,DA,A4,F8,E4,92,D8,09,8C,50,46,54,14,A0,15,38,58,DD,A1,52,C6,DF,37,37,66,24,B6,B8,CC,0E,8B,36,38,A6,58,4D,FC,F5,2A,E1,F1,2F,EB,D2,E1,0E,B2,22,2B,DE,6C,3E,6E,DF,7F,22,D8,F8,FA,5A,AB,4C,24,A3,0D,28,CD,0B,F1,8A,C5,35,D9,3C,4D,38,E0,53,B5,2A,4B,51,F7,F2,4E,75,99,7E,E5,B6,2E,21,68,5D,9B,3C,F4,8B,49,CA,C5,D8,17,5D,8D,31,80,3F,56,26,8E,65,86,77,30,CE,20,27,6C,B6,D5,80,58,8A,11,E9,9E,5F,F2,33,4C,80,AF,77,C9,2E,21,67,7A,3B,9D,EC,54,A5,A4,62,C0,56,10,52,01,67,C1,8E,9D,8C,6D,01,FB,07,78,DB,95,1B,67,AF,D5,00,9A,5B,FB,67,54,56,A0,5C,54,2C,52,19,47,F2,97,AC,A3,59,7B,7A,4B,59,55,25,C6,ED,70,D3,E3,AA,27,3B,6C,D8,CE,C8,42,FD,34,DA,1F,6E,2A,67,1E,90,D0,12,5D,3C,17,EC,F9,56,86,FA,71,E1,6D,A3,2D,0A,A3,71,C9,AF,BD,F2,18,76,61,31,3B,2C,77,95,65,F6,B6,12,15,F4,66,1F,65,23,12,A9,86,1A,B2,6D,7F,7C,BD,A0,ED,A6,6E,E3,C6,CA,30,78,F6,03,5C,0D,1C,C9,90,75,A1,AB,BB,99,CE,2E,C4,E4,C4,33,94,CA,F2,24,F0,6F,E0,22,46,D3,42,D8,CD,45,23,78,C9,7A,EF,53,2D,75,FD,77,B9,95,BB,5C,C0,22,69,5C,BE,D7,30,22,27,26,08,E3,63,8B,C5,6D,06,A7,3F,2C,BB,83,6B,FB,50,26,C3,58,C8,F9,62,78,5F,C7,6F,EF,CB,88,29,DA,89,CB,BE,CA,5B,57,3C,6A,B8,4A,05,3B,21,7B,55,FB,13,A7,5D,8D,DF,97,3E,0D,88,CB,7C,A5,57,9F,BB,C1,74,FB,A7,7E,5A,34,3A,DA,64,0C,C1,1E,63,93,F4,06,40,BC,98,54,25,AE,D2,FC,38,C1,24,F6,46,B2,73,29,4D,F6,FC,64,5B,C1,C4,CE,00,6B,3D,81,CE,6C,72,F8,F8,33,8B,92,2B,C9,4D,0F,EE,CC,AE,D6,44,D1,95,A5,A9,34,C1,CE,53,50,E5,CA,07,02,4B,8B,01,CF,A7,06,57,98,83,2C,6E,F2,BC,30,5C,E8,57,AD,36,16,91,CC,D3,49,35,A1,66,47,4B,2C,34,12,BA,D5,A5,72,A2,3F,64,54,22,B8,D0,FA,37,0B,8C,8E,BF,DF,60,BB,34,BE,73,59,E1,52,12,35,00,91,7C,44,E6,D4,2B,EA,07,91,8F,20,EA,3F,1E,6D,8A,D3,00,C0,06,77,E1,BF,27,E6,BD,B9,C4,02,36,BE,79,C5,FD,1F,3A,B7,D3,DD,07,F5,83,26,12,6D,00,E2,E9,8B,5F,89,A5,43,6C,95,47,69,05,D1,A3,4B,ED,37,24,2F,5C,47,5F,EC,5F,A6,AE,41,5E,2F,87,1A,2D,CC,7F,42,8E,2D,6B,4C,09,56,6E,59,6F,4D,21,80,5A,77,55,80,C9,41,9F,24,7C,B4,8D,B4,A8,E6,2D,10,1D,22,3E,AD,5C,2F,AE,6C,90,72,F1,B8,82,2C,F3,69,E1,35,5C,1B,F5,74,5E,65,4F,ED,C3,0E,78,10,71,A2,71,E2,33,94,74,37,16,95,D8,56,08,BE,B5,1D,95,5B,04,87,F6,91,FC,7D,A8,E0,D7,D0,12,DC,42,4D,24,9D,1A,27,A4,45,60,BB,85,25,61,2E,E4,7D,65,EC,96,7A,6C,AC,67,62,69,7D,5B,8D,8C,63,71,4A,F8,F7,3B,4F,1B,71,E3,47,6D,56,10,F5,52,83,35,CF,C5,9F,3F,E5,93,1A,4D,E5,B8,42,43,A6,07,D2,D1,48,72,95,73,5F,FC,B9,60,DB,D0,E8,C4,23,71,CB,3C,B5,05,F7,91,94,42,99,B0,09,99,A5,CA,70,92,CE,8C,3E,0D,BD,20,EE,ED,D4,6E,02,B9,E4,80,78,04,17,CF,C3,62,A1,50,38,25,BB,72,B0,B3,03,BA,91,9F,35,1D,96,4D,F1,AF,17,47,23,92,A7,71,F4,84,B5,FC,75,56,2A,90,FE,F0,DA,CC,82,B3,EB,B5,61,DE,A2,4A,48,8C,31,EA,0C,02,89,76,36,57,23,0D,53,DA,C0,FB,96,A2,9E,9B,D6,D9,9C,75,D3,43,40,0A,D6,BD,E0,62,A6,33,A3,72,F5,6B,52,61,46,86,18,EB,29,E2,10,8A,3A,E9,40,AA,5E,1D,EA,AE,1E,0C,1C,A0,05,40,13,B9,89,6C,5E,E7,FE,5F,68,C9,03,70,71,23,E7,58,1B,EA,3A,D4,A3,2F,1B,02,D1,4A,AE,1C,5E,BA,95,63,79,DF,B8,B8,C1,03,27,AF,0B,DC,0C,8C,BB,58,1F,B0,D3,5A,B5,20,BE,9F,73,3E,BB,A6,28,BD,75,70,72,F2,B7,F8,39,38,22,58,7D,C5,68,D5,EA,6A,BD,CD,67,CB,31,3D,BA,6F,5C,05,14,51,0B,DE,1A,83,F1,F8,39,FC,0D,AD,4D,31,29,8F,06,B1,BC,FA,68,38,AD,B2,B5,45,E8,D9,82,62,02,CB,8E,99,27,8C,B2,E9,50,0D,8C,94,8F,8B,B7,12,48,95,CC,92,47,E4,4F,03,2E,F6,F8,62,E8,44,EB,92,C1,9C,6A,B4,32,DB,F6,C6,51,67,82,D4,3A,4D,2D,07,33,52,B1,34,39,F7,65,10,5E,06,64,91,5D,DF,71,B9,8A,BD,5F,37,B8,51,F6,32,2D,07,2B,D3,4A,78,27,7E,26,E1,89,96,C9,E4,7D,65,86,0E,28,7E,07,7D,95,E9,91,D0,62,F4,D5,43,BC,7C,AA,08,4B,6D,CA,91,E8,8B,00,AE,A5,B3,34,21,4C,0B,88,13,86,A3,8D,BF,9F,B4,5C,79,9F,89,C2,BE,5E,E2,83,30,1A,AA,28,27,D0,50,BD,33,3C,18,FE,F8,2D,06,52,D6,24,D4,EE,B0,BE,CC,A1,69,6E,A0,08,33,B7,F0,37,F7,12,50,0A,F2,C6,2A,D3,C3,48,DF,CE,8C,2B,31,B5,8A,A4,CC,73,2B,E6,D6,97,02,01,54,05,C6,04,18,5C,E6,62,CE,22,03,9C,4B,6A,96,BE,7A,08,E1,E3,86,42,72,A8,B4,AD,E4,AD,63,EE,D9,6F,9E,78,7D,2C,6D,D2,02,AE,EE,02,3D,C4,19,64,E3,C1,82,FC,D9,B5,E4,49,CC,6D,B9,CD,B9,4E,B9,0E,B6,5F,05,68,EF,A6,3B,F4,BB,42,45,81,8E,FA,8C,0B,17,32,AA,F9,E2,D0,EB,41,1A,79,AE,86,21,FF,0C,10,8C,CC,41,27,0B,08,94,61,DD,4A,C6,1D,A2,F9,54,C4,95,AA,C7,99,A1,CE,32,EE,57,84,28,12,AE,D7,C3,20,FE,69,3E,64,A3,A3,3D,B0,01,6B,01,EC,6D,B4,22,F3,A3,B7,B4,88,48,CE,07,67,50,7F,96,35,BD,7B,FF,32,58,60,CB,7F,63,E7,7A,1D,1F,A3,06,FF,8B,75,62,61,6A,D7,63,0C,7D,42,80,68,03,7E,4F,B0,F1,0F,5E,AC,35,EE,24,EB,17,3E,BF,7F,70,86,92,60,27,31,D6,78,44,41,4D,C8,5D,3C,C6,67,F7,3B,1D,E7,C6,43,F0,25,28,C8,C1,69,DA,84,37,E7,3F,B0,E3,3A,77,FF,AE,E6,A5,72,5C,45,2E,D6,22,71,C3,28,C7,58,0C,62,D8,8D,EE,05,82,0D,23,FF,63,2E,52,7D,31,E7,37,81,F1,9A,73,63,FA,47,E3,F4,A2,D0,C3,D8,73,A1,45,94,F1,E1,30,6D,DC,6B,D1,55,37,24,CB,EF,3A,33,89,06,33,A2,11,FC,5C,EA,C7,39,F4,89,78,11,D4,D9,51,29,97,30,AE,C1,13,8D,DB,54,41,13,86,BA,BC,55,91,23,39,83,C5,0E,2A,6A,AD,3B,BC,28,E4,4E,3F,02,50,03,7B,D0,B3,DD,33,17,B8,BE,F0,0D,C2,AE,12,F3,B7,36,6D,62,DF,B8,31,44,96,57,EB,62,25,29,0F,90,39,90,1B,55,A1,C3,4A,B3,8B,DD,F6,50,30,D2,73,AF,6D,9A,B6,36,C4,19,A8,65,D0,49,4C,50,61,9F,B6,58,81,BC,26,E1,0D,40,BA,DE,98,C0,F0,4C,8C,90,31,48,8F,96,FC,6A,90,95,9C,86,9D,59,29,4D,A3,62,32,E9,62,66,65,3B,82,0A,87,60,B3,58,CD,41,59,AD,6B,DB,98,57,02,80,78,EE,4A,03,F0,80,01,D0,EC,0D,44,9E,E9,32,05,DB,A3,C8,63,A5,B8,CD,6F,59,10,64,A4,37,F5,2A,03,78,1F,E5,D5,94,11,F2,ED,A3,47,D4,7D,FC,97,75,3F,51,A6,75,0D,70,15,9A,1E,88,F1,A6,27,B9,CF,8A,0A,D3,14,19,06,22,FC,C0,72,E0,24,B8,3B,F7,C9,72,0C,2B,CD,4B,2C,3E,1E,6C,EA,4B,4A,44,74,E4,BC,75,69,DD,05,67,CD,01,0D,B2,29,77,A3,75,9F,E8,89,CF,68,26,BF,0B,BE,3F,29,97,7B,0C,BB,95,33,FE,29,ED,0A,0B,B0,70,9C,1F,6E,7E,7C,C6,D9,15,EE,10,41,EE,FE,8A,14,06,54,49,DA,38,30,27,12,EE,66,22,E2,02,4E,BD,C7,A7,53,BF,3C,12,0D,0D,CC,85,92,30,A2,AE,96,44,DE,06,0C,30,B7,4E,44,EA,0C,44,4B,14,E9,93,2B,68,11,18,CB,EC,B2,3B,02,53,DF,A9,65,D9,5A,A7,70,3E,58,A6,92,FF,3E,23,A6,E7,76,01,45,4F,1D,E7,BF,BC,7A,8D,FF,2D,D5,89,17,CF,0F,81,44,07,B1,56,95,5F,EA,D0,65,B5,56,EC,D2,71,3B,3E,BD,1B,C1,52,55,1D,F9,6E,6C,AC,63,45,6B,A0,0D,06,43,3E,3E,DC,D8,3F,3F,39,A9,20,72,8F,E6,F7,E0,57,B0,BC,60,F3,8F,BF,17,D8,3E,8B,B6,8B,E6,4B,14,33,3C,7E,DF,B5,07,97,F1,DE,46,E4,51,E2,9B,0C,3B,D5,7D,E7,7B,02,BC,DF,70,CC,7C,80,1B,D6,4D,C3,11,D5,BF,0D,6E,0A,13,31,36,1A,41,E8,38,04,17,EC,C9,B5,28,8D,8C,01,0A,6F,AC,D4,09,58,88,6E,80,55,BD,AC,BD,86,2D,FA,44,DE,C7,60,4F,00,07,53,04,EB,1C,35,C5,03,DE,5C,1F,BA,CF,DA,EE,B1,05,9B,04,A5,16,E6,11,62,3E,D7,9C,B7,D3,80,66,45,80,D0,48,0A,F1,89,8F,B4,BB,70,40,0A,81,67,3F,1A,FA,48,74,46,72,AD,B2,83,AB,ED,B7,B2,05,BD,8C,85,76,8E,5B,4E,E1,8A,0B,8D,5E,11,28,7A,17,01,27,DB,94,17,D9,11,09,85,F1,2C,2F,F1,41,D7,9D,BE,11,34,1F,CF,CF,CE,62,B7,A7,9F,14,7A,7C,4A,D8,59,DA,9A,AA,3B,D5,AA,5F,F4,91,44,C2,48,82,E2,B3,C7,34,19,3A,08,EA,42,E7,F6,71,D0,5F,48,C2,64,2E,DB,98,C4,10,52,40,F7,E8,E7,B5,1A,A3,F9,A1,92,FB,F2,45,07,D2,7D,C8,D2,A3,4D,8C,5D,1D,B4,01,90,2B,3A,2D,2C,0A,62,48,98,83,9D,0A,2D,63,D5,C6,BD,1D,B2,E7,1A,E6,9E,A4,36,59,23,3C,99,C3,E3,17,60,90,8E,13,6A,3D,C4,30,0B,37,64,08,5D,32,74,41,21,63,78,70,B5,29,3E,72,82,F1,56,4D,D2,26,45,AC,C8,50,BB,8E,0B,6E,1C,62,01,8D,12,41,12,57,67,F1,20,96,BB,61,40,5B,09,4E,31,1A,91,1E,1F,1A,42,73,74,60,6F,7A,15,E0,47,FE,54,AB,DE,41,03,C8,8F,38,D0,78,96,D6,68,5E,52,A2,79,15,9D,14,57,3D,27,9B,67,D8,BB,97,71,B2,AE,5B,73,22,84,E4,A4,BD,93,9E,10,41,12,A9,53,30,E2,80,59,72,E3,B6,3E,0B,D4,C0,E4,4A,0E,C8,67,53,70,CF,A2,F3,0D,45,9D,9D,11,0E,3E,9B,0F,BF,CE,0D,B0,5A,B1,21,CD,C1,A1,AD,67,02,0B,DF,41,AA,20,8E,1B,42,DD,C6,19,3E,96,16,19,0F,11,C5,62,F0,C6,80,45,AC,40,6F,3B,29,B6,35,DF,B5,20,76,D4,E5,0C,EF,DD,88,16,6F,66,D8,99,41,48,66,99,32,DF,4C,47,C0,8A,09,82,82,AB,9A,0A,79,05,DE,67,B7,83,3D,71,23,88,93,60,35,6A,FB,65,93,F5,EE,1A,D6,C9,7C,91,5F,D5,06,EA,C8,00,29,A5,71,2C,F7,C3,AE,2E,2C,99,52,13,63,30,1F,B8,22,74,E9,3E,A5,A3,B4,70,E7,1F,C8,15,C3,DE,1B,08,7A,6F,B3,CB,81,94,A4,BB,E5,9C,03,8E,8A,B3,A5,73,27,56,3C,10,A6,CB,2B,45,09,A2,D4,E4,3F,55,BF,93,91,D8,A9,59,30,5E,FD,DB,63,BE,B6,34,1D,28,02,3A,7B,B9,26,06,1E,66,6C,5C,5C,59,AB,2F,08,5C,39,87,B3,20,7A,FC,A9,28,17,DE,57,7A,7C,AE,30,90,4A,5B,88,91,C8,41,4C,E7,B4,8A,BB,EA,BE,4B,EA,BA,F4,A5,FD,D7,63,63,B2,7A,7D,59,36,B4,61,A6,C7,F1,CB,5B,3F,6E,DF,C2,A9,B2,B8,54,19,1A,4E,21,5F,FC,00,35,7B,1F,72,2D,31,68,2C,65,34,E8,68,88,30,2B,80,D0,B7,E5,16,55,30,F0,51,B2,08,17,BB,8D,68,C3,E3,51,97,EA,17,EC,5A,C0,46,1E,08,91,54,85,9E,01,2C,AA,B1,E4,98,76,58,6B,29,BF,C1,16,E3,9A,53,80,A0,3D,FB,A9,2A,46,53,4E,11,33,88,93,9E,3A,BF,FC,FF,9F,9C,7B,9E,3F,48,3D,4F,25,44,F0,DC,D7,14,E1,C1,D9,71,10,90,E8,1D,AA,67,70,0D,52,12,DA,E4,E6,1B,4B,DD,9B,A2,DE,AB,D1,8E,D9,49,DA,E7,2E,B4,6B,52,E0,71,9A,38,EA,BE,A1,79,FF,F1,EA,BA,3F,97,B8,85,3C,00,17,BE,6B,EC,76,F0,42,DF,7A,4A,A3,12,29,FD,E4,A5,C0,A2,04,DF,D0,12,72,1A,6D,44,98,0A,40,D5,65,C7,B6,D3,22,AF,AF,D5,F8,09,A7,C4,36,B4,D5,76,1D,03,06,51,6B,8E,1F,64,D7,E3,7A,31,D3,F9,9C,BD,0F,F9,76,9F,DE,61,6D,63,C6,90,71,0E,CB,3E,F0,F9,93,C4,12,04,FF,D0,B9,00,16,27,39,8B,38,72,93,C8,0B,D3,F4,33,0B,27,52,F9,C2,2B,2C,40,62,9E,57,A6,D0,88,32,34,BF,48,A7,B7,AD,B8,2F,63,79,84,36,D1,F5,1C,3F,AC,7E,CA,41,C2,B0,C3,8F,EC,CF,42,E7,CC,0B,BA,97,8F,D1,A9,89,54,E9,51,15,0F,1A,E9,E4,BA,FA,5D,E3,2D,4F,3C,84,7B,B0,D4,ED,20,D4,2A,2B,45,B4,9F,BD,F0,70,0E,0B,87,5F,90,3D,53,92,3B,05,F9,DC,E4,80,CF,9F,04,D8,1F,CA,B6,67,1C,A4,89,CF,2D,F0,DC,F6,7E,FD,D2,F8,13,AB,5C,8B,24,9A,6C,24,CF,F3,07,B8,E2,9C,40,93,EF,5E,1B,FE,9D,43,CF,E5,05,DC,3C,93,1F,37,DD,B1,EE,46,26,0C,71,B0,FB,C0,77,67,1F,1D,47,A9,68,F2,3C,7C,D8,FE,45,B8,4E,86,27,90,E9,83,28,8B,7A,F4,C1,26,2C,52,62,8B,27,C7,D7,12,9C,57,CD,55,FA,01,57,26,25,81,0A,DE,1D,83,4B,39,A2,0E,8E,EA,2C,A7,01,4D,43,A1,D5,CA,FA,40,BD,D0,44,DA,2D,37,FE,1E,5E,31,8F,8E,A1,12,FD,FF,33,D7,81,79,FA,EF,64,EF,8A,7A,BF,F3,A5,C7,AE,3B,09,CC,BB,89,89,5D,25,25,44,10,1C,14,46,43,31,DD,1D,5B,6B,9A,36,28,C5,0D,A8,B4,AA,5D,12,4B,36,51,67,9C,78,BD,FF,04,AF,85,6E,AA,74,B9,D0,D9,1D,2C,38,C8,B4,E2,B0,C9,BD,E6,9C,11,72,7D,FA,DE,49,3B,0B,35,8E,68,89,7B,BD,53,DF,2A,07,FD,9C,6B,A6,5E,CF,CC,4B,85,2E,AC,FF,1E,0E,F5,46,DF,E7,3E,70,8F,E3,53,38,82,BA,33,41,7A,DF,CD,19,33,F9,BD,07,07,84,40,A0,AF,6C,E4,20,A3,DE,29,A1,C8,62,77,E1,1B,8F,4E,9D,96,CC,11,40,72,11,88,E4,03,41,73,A1,68,35,4C,E6,3C,90,6E,7E,9B,66,86,C5,3E,AD,99,90,3E,F4,7E,4D,64,5A,87,DB,FB,0C,56,E0,EC,87,A6,71,04,CB,76,4E,A7,FE,F9,E9,A1,2D,6A,97,58,8C,48,66,6B,56,A7,FF,D0,F0,78,95,B3,E6,55,80,6D,29,DF,B2,2D,1C,57,DB,13,79,B4,EC,06,1A,06,E9,09,AE,AC,07,59,79,64,A2,74,88,66,E4,32,64,43,45,87,76,AC,DC,FA,04,05,5A,0B,B4,85,5C,2E,56,21,C1,F9,C7,AB,CE,C2,44,46,7B,2D,31,C9,69,03,50,0D,76,CC,B7,48,B4,8D,64,AC,E2,27,6F,3E,77,CA,FA,88,51,19,88,DC,B1,4D,FC,2F,30,C4,F5,E1,63,32,4C,4A,BC,B4,EA,C9,15,6C,82,9E,A1,13,E9,79,E3,AA,6B,8C,FC,71,6A,05,8A,3D,A5,06,36,4B,D5,DA,7D,5C,FF,13,33,63,A7,22,1F,9D,9D,5E,5E,FB,13,18,90,8F,DD,A5,71,01,F6,6A,38,98,D2,05,DB,16,39,E2,B8,57,23,7F,13,78,B3,F2,BF,DF,52,EB,00,A2,D7,6E,50,4E,E8,AC,17,64,69,4C,88,40,DF,B8,3B,97,14,5B,0C,A0,2A,0F,16,53,2A,10,8F,B7,11,92,F1,9D,76,92,28,B9,F0,07,17,41,AE,80,9D,E5,FC,C3,14,16,A9,ED,E0,D7,16,D5,DE,78,2C,09,D1,0F,15,36,E9,B1,F6,C0,09,0C,D7,7B,F2,BC,58,AD,DD,8D,74,60,C6,3F,D6,48,1E,35,02,61,E9,BA,E3,A4,65,39,00,1F,CF,FC,BE,0A,30,C9,76,1F,49,D2,B5,2A,59,E8,30,9C,13,6E,5D,39,E1,93,E6,1B,40,7A,2F,CC,B1,D6,13,72,04,91,C4,73,33,01,33,FF,42,71,A5,05,6C,36,F8,7F,3C,68,4D,B0,44,2C,9F,E9,80,19,66,46,20,78,1B,B1,7E,FE,EF,C7,31,DC,B8,17,48,3F,4E,32,D2,D1,90,0A,89,BB,E3,B3,48,61,34,19,44,6E,C6,E7,1D,DF,1D,8F,CD,70,56,AF,2D,38,C4,00,0A,40,9C,A6,F2,90,FB,0F,95,AC,9E,FC,32,F5,5C,DB,AF,F1,CC,C9,44,67,B9,91,63,E7,08,97,6D,8C,67,DA,3E,A3,56,8E,EA,15,0C,06,3B,D2,4F,E1,00,22,3F,7C,82,BA,D7,DE,0E,93,6D,BA,6E,9B,65,78,46,AF,36,C1,1E,B5,CC,98,5C,3C,3F,C0,9C,A3,07,8F,9B,30,BA,C5,12,47,12,05,5E,75,5A,44,A4,83,41,62,54,E4,06,EC,E6,F4,AF,20,73,54,80,6E,BD,84,CA,FE,A7,14,11,3E,BE,82,EB,E8,6F,74,C8,F2,68,6D,BA,0D,4C,75,FB,47,39,9F,44,7A,66,4A,3B,A1,8B,62,DE,D3,38,98,FA,28,6F,C4,58,3B,23,9A,E1,EC,0F,E0,51,14,78,20,03,0E,B2,2E,52,79,B3,EB,64,4F,42,06,00,A8,A0,8F,40,AC,22,03,5A,06,A4,A9,5C,42,EA,75,52,3D,A6,74,FE,8B,55,BD,98,9B,25,6F,10,A5,4B,B1,44,17,AD,9F,F2,75,A2,B8,75,77,3A,39,B7,49,CA,30,A3,EA,8B,3A,B3,5B,B7,08,EE,0F,7A,89,3E,DA,0B,CE,12,D4,91,FB,66,AC,82,5A,F6,16,CB,7E,86,84,B7,D3,23,60,C8,50,94,2F,C4,78,1C,B6,4D,97,CA,B5,96,52,0B,19,73,48,B3,3A,AA,AB,93,38,62,36,50,E8,A4,28,C1,9F,53,73,22,F8,2A,92,8C,39,BE,92,BB,1A,07,AB,E0,7A,44,B4,22,8A,7B,15,5A,CD,4F,14,E9,72,64,69,95,67,15,9E,D6,6C,A7,97,4E,B6,C4,9A,4E,9C,26,0C,0C,32,7D,D3,28,0F,77,78,2B,5A,7C,90,AA,86,17,9D,6A,78,08,78,DB,56,30,D5,3B,25,68,9F,F7,9A,A2,2F,C5,6E,08,18,62,80,68,E2,58,03,6B,39,82,90,5A,2B,8E,BF,A4,29,83,D7,E9,80,65,ED,9F,95,B3,CF,D6,9C,21,82,F7,E7,46,28,E2,45,EB,F9,D8,58,66,F3,32,CC,1E,48,98,0B,0A,82,87,95,6A,D1,4C,59,77,54,57,86,E3,64,27,3F,7E,44,AD,07,60,DE,7A,F5,3C,92,33,5A,B8,16,C2,20,FD,76,DF,EE,D2,F7,A1,52,F0,85,CC,5C,00,65,A4,B5,B4,BE,3B,6A,92,95,2A,D1,48,80,E5,49,34,0E,6E,A7,9C,78,2A,1B,87,EE,6F,C5,F0,43,3A,D4,2D,95,82,AD,57,81,BF,06,F6,21,56,90,CF,36,BF,74,55,AA,B2,27,70,1D,8A,36,E4,87,F3,E8,9A,A0,75,34,61,5E,91,9F,E1,70,EB,D6,59,49,C2,49,B7,9D,6E,C4,D1,9A,88,BA,FA,D6,4A,C7,47,1A,11,53,AF,2D,1C,24,8B,D5,16,93,27,D1,08,DB,DC,6A,D0,73,EE,51,8C,3A,74,44,DB,D8,54,7B,9B,11,5E,14,8E,6F,FD,D5,14,AF,9D,17,FB,8A,F8,7E,49,D1,F1,35,58,A6,90,00,44,4E,C6,46,15,3B,45,BE,9E,9B,DD,9B,2F,4C,95,F7,92,42,90,A4,98,93,41,97,9D,E7,09,C5,DB,A7,47,E8,68,77,76,85,BE,E7,67,7A,EF,6A,D6,F9,AE,85,95,47,EB,C7,64,FC,10,B8,72,44,26,F4,BB,A8,A1,1C,B1,BF,DD,CD,A6,0A,6A,2C,CA,FC,F9,50,20,7D,3E,FA,E1,79,45,DA,E3,44,96,87,4C,1A,21,6C,32,A2,B9,37,1D,36,47,38,DE,9F,5A,76,48,77,86,E0,7A,03,93,88,B0,66,B8,12,D0,D6,78,66,E5,2B,0D,D5,24,CC,8C,30,1E,44,8B,7A,BA,36,9D,14,F6,CE,57,2D,54,1F,2E,F1,1B,1F,A6,BA,15,D5,38,C0,1A,23,F1,7E,11,FF,ED,D5,31,B3,76,7D,34,0B,E1,88,00,44,EC,ED,99,10,BC,CE,46,61,BD,04,28,E2,F1,CA,09,F3,B2,50,1B,C0,49,05,3F,1B,10,55,41,E2,4F,AB,C6,CE,C7,94,88,C6,87,BE,3D,0C,80,92,B0,83,23,A4,1E,67,CA,07,62,01,1C,4D,56,FD,DF,15,2C,10,9A,EB,83,25,C9,F1,F6,76,B4,1A,36,E2,4C,73,3F,B2,F4,0C,6D,A5,07,DC,01,E6,3B,47,92,20,7B,12,58,DA,9D,2A,12,6C,BB,AF,AB,BE,8B,0B,84,2F,85,2B,9A,E8,6D,8A,B4,E2,40,81,E1,C3,00,43,B8,23,BA,D1,D4,F7,5F,B8,62,EA,53,BF,79,7C,CB,18,6E,59,2E,F2,5E,2B,C5,87,F2,BF,D5,87,00,05,0D,88,8E,58,EE,CC,FF,27,18,B5,25,05,11,45,D0,28,8E,3C,3A,79,27,A9,D2,57,14,C7,E5,44,FF,EB,5D,BC,E4,79,BD,8B,57,27,9D,6E,2D,F4,AA,79,54,18,DC,03,21,63,96,9D,7A,E8,49,9A,A5,07,FC,F9,82,E1,89,83,FA,4B,79,3C,08,4B,69,A4,77,D6,05,93,85,50,46,F1,4A,AD,A6,7C,CA,79,32,DE,0F,B6,08,C6,1D,7A,2C,30,24,B2,1F,C8,22,64,76,18,66,74,E4,E6,14,69,DE,2F,75,B1,DB,49,A7,81,14,E8,3D,05,40,2A,6B,51,A0,E3,7D,F0,DC,E9,D8,E4,AC,EC,14,6B,F4,28,68,55,45,C7,FA,44,8D,41,08,23,72,42,46,14,29,05,4B,AF,02,9C,AE,01,29,F4,B3,99,EA,3F,DD,AD,F1,28,E5,E9,89,68,E6,40,14,A4,D4,46,E5,B4,27,D1,BF,22,17,64,42,8A,10,5A,31,B8,4F,3D,AC,F6,1C,1A,66,5D,13,3D,C1,A1,43,4C,B9,A5,7A,28,5B,97,81,6B,66,95,9D,08,E4,24,F7,4F,1C,F9,B9,4C,4B,F2,E7,F8,41,D4,30,A0,85,06,4A,DF,09,E7,11,A3,85,6C,63,AD,14,87,1C,FC,AB,D0,BF,7A,53,EA,3C,68,3A,B5,D9,5A,E5,CC,54,FF,42,FB,D3,EB,1C,A5,D3,B8,DF,4A,0B,1B,B2,0B,47,C4,6E,4C,8D,31,97,1D,7B,EB,64,2C,2C,8E,82,B4,F6,BA,23,B7,6A,05,4A,21,4A,3D,F0,8F,29,E8,43,64,A8,9B,10,1C,29,87,24,3E,BB,00,CB,EF,AC,78,AF,3D,06,CA,EE,AD,E3,3C,46,56,B4,1F,09,CD,5E,0A,60,7D,E5,47,A2,29,C6,90,67,E4,33,9D,0D,B4,D7,CC,92,E3,FA,53,8B,F4,F3,99,4F,BF,EB,42,12,D3,D7,AC,C0,38,9A,21,AA,15,7A,3D,9B,3B,D7,5B,4C,FD,B5,FE,9B,09,12,87,11,3E,5C,EB,7A,99,5D,1A,E9,47,31,18,82,A8,33,B2,8C,BA,8F,87,59,2A,5B,50,3A,76,B7,A2,80,D8,1B,8B,7C,03,55,C5,40,F7,C5,4F,39,6F,93,E2,FE,FF,DD,A8,EA,4F,D7,76,53,82,25,3B,15,FD,16,BD,88,10,14,57,DA,81,9F,45,1C,7A,33,76,E3,EA,3C,0B,A9,75,4D,FC,B6,8D,A0,0F,18,F4,8F,78,58,61,0D,94,4C,75,F2,46,51,1A,40,A4,57,4F,05,C9,DB,92,F5,0B,F1,AB,C7,04,2E,FB,2D,FD,3E,12,B2,6F,7E,8B,6E,F8,74,A5,63,2B,BE,FC,ED,C2,38,AE,A0,39,24,37,96,17,55,82,08,46,6E,9F,59,1E,3F,85,EA,5D,46,34,4A,6A,B0,5F,BC,F0,42,6B,8D,BA,24,7F,D1,9D,AF,A4,2B,FF,B1,12,62,52,BD,92,D0,CA,CF,BF,3D,18,1D,DA,7E,49,D9,9C,CF,F1,E8,22,EA,68,AF,62,DF,C5,9E,A7,E6,8D,BB,5C,6F,9A,98,B6,2A,AF,0C,1F,CD,88,CF,82,AC,84,BE,CB,40,D9,A0,70,F0,46,A6,18,EB,94,D8,75,09,36,BC,F4,4B,52,48,D4,DD,F2,82,EA,2F,62,E4,50,65,BC,64,BF,85,53,8C,6D,AA,55,2E,F3,89,A2,E9,73,59,4E,38,73,5A,EC,D5,FD,EC,A3,B9,F8,D4,84,FF,EA,6F,E2,94,8A,8D,2F,EC,13,9C,C4,CF,A3,19,E2,9F,97,F3,0D,CF,B1,AD,E7,97,93,41,D6,9F,6C,30,DD,18,29,FB,A1,0D,C7,2B,5A,CB,68,2D,31,B6,4A,C4,81,F9,34,2A,77,8C,44,BE,A0,F1,FB,62,43,4D,89,94,B1,47,ED,D2,09,87,E8,F6,DB,13,3C,9D,00,2F,69,69,C5,88,01,DF,90,3D,89,2C,A5,82,28,4B,E9,3D,F5,60,A2,EE,C3,5D,6F,EA,D0,32,5A,15,5A,2B,70,F1,E3,5A,64,E3,6A,6D,3F,EE,1A,0A,71,CB,A0,C7,B0,10,61,2F,6C,F4,3D,B9,2C,EC,C3,7D,53,2E,E4,46,C3,73,88,76,34,3E,A0,C3,86,2B,07,DE,12,D8,CF,9D,D9,5E,31,F8,2E,3D,BA,FA,5E,67,5B,6C,D9,F6,91,E7,CC,8D,86,F3,B2,B6,F3,7C,B9,8E,3C,88,D5,F0,E2,CA,D5,95,9D,EE,60,EE,D5,C0,38,C7,D4,C5,FB,07,17,EE,C4,BD,08,8C,03,A0,30,D1,D1,56,93,4E,34,75,11,6D,BA,7D,F5,E4,24,45,A5,1D,DC,A7,A1,65,6A,31,6E,58,A8,F6,4C,EA,BD,37,22,63,98,1E,6C,E6,22,EE,13,13,F2,CC,2D,47,93,3E,F2,8F,0C,86,FE,9D,56,CF,32,03,43,CB,6D,91,7E,82,BD,CD,0D,9E,B4,FA,AB,7B,3E,45,4E,A5,DC,FE,B6,FA,64,86,0E,D9,D6,D5,88,07,FB,69,BD,7A,6D,66,21,6C,4E,45,23,06,57,31,28,DF,2E,2B,3A,19,97,A1,03,93,A5,9D,4A,5F,54,9E,71,0F,19,73,BE,F7,90,0A,44,9B,17,3A,BC,E2,23,F9,CB,F0,4A,FA,71,4D,16,65,9C,66,7B,28,43,7D,38,D5,E6,D5,E7,54,9A,AC,60,78,4A,6E,18,86,79,5D,F7,25,B0,4A,07,42,74,CB,80,48,55,05,68,F6,7E,1B,0F,BE,82,F8,97,65,B5,CD,80,B9,94,51,97,DC,B5,F5,E1,64,17,26,DB,79,09,B3,CC,9C,BE,65,70,E1,82,46,24,3E,07,C5,8F,A0,B3,81,F4,E3,B4,8D,F0,8C,AC,9E,CF,8C,E9,BB,8D,4C,49,2C,FC,F1,3A,E2,AA,64,39,3F,38,69,6D,60,B8,D6,1C,D1,B3,14,DC,E2,50,77,37,94,D1,C6,54,2E,D4,79,32,ED,5C,2F,06,FB,88,ED,3C,0C,E5,9C,FA,5F,54,AB,73,21,7F,BA,96,69,30,8E,64,65,B8,46,2F,0B,F1,F9,73,E2,65,C5,B1,5F,C8,A8,E0,57,23,26,45,5A,E2,B1,49,FF,9A,05,9E,21,F6,00,DA,95,BA,77,A3,BE,7E,D4,18,D1,B3,F2,6B,5B,A3,0C,A7,9B,FF,7C,4B,AD,D7,4E,30,0D,A3,B3,AF,65,D5,6F,C5,9F,E8,2C,62,3E,72,98,88,E1,E5,8B,D0,33,42,E1,4A,88,2E,6F,EE,25,7B,25,0F,F5,90,9E,FB,30,8B,A9,02,69,99,B5,0B,E5,5B,FD,60,D4,56,F4,C2,5C,C6,8C,7F,66,DA,26,0D,DB,5E,A5,94,EF,5B,94,89,B8,A7,6E,9A,47,70,48,AA,18,53,57,10,CB,CB,64,49,43,67,46,B1,0B,4C,C0,9D,F4,02,2B,46,7C,65,43,A6,AB,8B,B6,70,8A,38,86,32,16,83,D7,7B,0D,91,9B,CD,78,39,65,5C,2D,4B,09,3C,D0,6F,61,4C,B8,80,0B,4D,99,3E,4E,20,A6,8B,9A,EA,C4,C3,E4,FA,5E,04,CC,24,57,C7,6B,44,2D,C1,60,87,B0,BF,6B,D6,AD,CF,F1,D5,EE,41,DD,19,EA,D9,68,55,47,19,77,E9,E9,50,F6,80,D1,82,12,3D,8E,DD,25,AE,E0,D8,89,FA,29,FF,D8,64,15,D1,65,11,F6,4F,38,38,84,AF,5C,D7,25,C4,E1,AD,55,9C,2D,5B,1D,6C,A4,5F,7B,B2,DD,BC,3A,43,D5,00,20,03,66,DA,ED,91,63,28,3D,D2,98,CF,63,02,19,13,53,D6,D9,8F,E5,1B,61,11,8B,93,93,90,EE,43,4B,4A,BC,89,02,28,3B,FC,16,AF,52,ED,EC,1C,74,D4,B8,5D,75,65,2D,81,09,0D,F1,EC,3E,14,B9,38,04,B5,08,18,BF,4A,B5,A9,74,44,7F,34,5C,E9,93,2E,DE,9B,9C,3C,95,10,27,19,6E,EE,2F,C9,4A,76,69,94,3A,18,1C,BE,14,03,A4,82,7B,1A,8A,6C,41,E3,84,E6,E7,56,BA,4A,73,99,77,66,68,92,0A,30,FF,E5,AD,63,1D,23,B6,85,B8,2C,79,E5,A1,6E,F1,20,C8,86,A6,91,58,78,B6,3C,8F,D6,91,F3,08,E2,4A,08,DF,D6,BF,13,32,F6,32,AB,CD,A5,70,7F,D6,46,2C,5C,7B,02,0B,A1,A8,78,FD,54,09,FA,44,17,93,84,CC,D9,FA,B9,DE,CF,32,42,A9,A7,2C,1D,15,36,3D,A8,22,86,29,EA,F1,13,A4,83,8B,A1,3D,12,F8,94,FE,AB,41,56,E3,43,99,B3,10,48,83,D4,4E,8C,E2,E4,98,D4,96,3F,04,F4,48,AD,E6,4D,61,CE,0E,26,3B,AF,5D,CA,34,BD,70,10,41,04,F8,48,42,C2,5B,C1,A4,38,37,FB,17,E4,A0,C3,3B,41,6A,B8,AA,F9,FE,34,B4,B9,AD,77,6B,CD,1C,2A,F4,8A,71,90,45,5F,1B,85,98,CC,C3,46,AC,D6,65,90,4F,46,15,39,EC,88,C2,AE,43,6D,A4,FD,DA,E3,B2,24,EB,A5,7A,00,9E,63,B7,52,04,01,C4,F4,7B,A4,88,57,59,D5,57,B7,41,98,E1,B4,82,A5,2B,80,CC,D2,A1,4F,A1,CF,8D,F5,0A,6D,02,C0,DE,31,82,FC,80,4C,28,5C,85,29,8E,1C,74,BC,20,9C,2B,B4,E7,FE,5C,EF,95,35,95,2B,83,AD,11,5F,E0,60,36,69,31,B4,87,F3,9A,D5,41,70,C0,DA,84,6D,38,04,2F,7E,36,9C,0A,5A,84,EA,76,E4,38,71,D7,06,96,EA,30,AA,59,7A,F1,26,47,CA,F3,AB,E4,D4,7E,73,1D,94,DA,6D,78,0D,DB,43,E7,81,75,54,BF,BF,7B,3E,32,B2,1F,5E,15,6A,FE,D4,CF,A2,F8,23,FC,68,F2,2A,97,0C,3C,43,C0,C3,0A,B2,42,02,C4,23,2E,85,15,8A,4F,55,49,6A,F6,DD,C3,92,5F,B0,C0,E6,E6,CB,6B,A2,C0,89,78,A4,F9,55,D8,9C,CA,0E,5A,7C,14,58,A3,A3,1D,96,F7,A4,58,91,AB,00,A6,90,4A,53,64,B2,6A,EF,C8,63,8B,C6,3D,7A,28,C1,5A,66,99,A6,6E,20,35,07,F1,51,CB,D7,3C,D9,29,4D,F2,27,35,54,6F,23,E3,D3,2F,CE,5C,25,95,AA,17,48,E3,6E,14,04,42,B4,62,63,BB,E5,8B,DB,55,AD,86,22,D7,15,81,75,CA,71,0B,99,2F,86,09,A9,26,78,BF,6C,C6,B5,54,05,72,D3,CC,34,20,AC,29,24,5B,16,9C,D4,9E,23,13,29,2B,B3,DB,42,87,4F,3E,32,0C,9D,07,8C,54,01,E2,C2,7F,E6,42,71,73,F5,B9,61,F6,20,0C,C9,FE,27,52,15,1E,E9,A0,63,92,E0,A3,E6,41,F3,05,56,87,0E,62,A2,FB,02,7A,5C,97,EA,CF,DA,7C,88,95,5C,27,13,6D,5C,1E,A5,A8,9B,1A,DD,54,FB,CA,47,D1,02,BC,B3,0F,98,8D,38,21,01,A9,0F,E0,CA,E0,C1,12,12,B2,53,CA,1C,E0,1B,1B,ED,FD,99,9F,83,06,28,1F,50,E9,D3,3B,60,E6,0A,17,81,1E,7C,D9,56,BA,F7,DA,7A,A1,AE,40,BE,61,8C,64,4A,3D,3C,2C,89,3B,DA,7B,17,12,39,2F,A8,4F,87,7D,2B,6D,BD,D9,C1,AC,A1,9F,53,EC,E2,8E,6D,6F,0E,49,E6,07,F0,09,88,9A,4F,8C,29,D9,08,35,9A,9A,D4,81,25,74,51,90,34,30,AD,01,ED,D9,09,66,D2,79,70,95,73,20,42,69,91,6D,19,7E,5F,69,28,0B,5F,08,92,C6,FB,D5,C8,F4,60,73,46,22,E3,97,39,22,BE,A8,7D,30,85,4E,2B,89,DB,00,58,99,37,D4,66,D1,BB,21,5B,5D,44,90,BB,FA,7D,FD,53,31,C1,DF,E0,6D,F8,36,92,6F,3A,2D,83,EC,AE,CA,1C,9E,FB,B1,55,DF,A9,1C,F0,9F,7F,5B,7C,EA,0B,91,6E,5B,FC,78,8C,7E,15,E9,EF,38,32,80,B0,76,DE,2F,52,5E,63,00,34,0C,01,C7,9A,52,C2,87,D4,9F,5B,6D,D3,3B,EB,B7,F9,18,22,EF,8D,D1,20,D0,50,11,EC,C4,27,46,35,5A,04,30,3B,98,A3,18,BA,C4,4F,20,12,AA,23,39,4A,C6,B7,DD,27,E6,0A,4F,BE,8D,90,F2,32,BD,F1,5B,EF,1E,7D,F2,AE,57,F8,D0,1E,04,59,8A,D9,99,E1,6A,DF,F5,56,C9,82,03,93,BB,54,42,AD,AA,19,7C,87,48,3D,10,CA,FE,0A,3B,AE,66,83,3B,04,D4,F1,68,F5,AB,D3,97,78,56,89,7C,9D,FA,18,66,E9,3B,7A,CA,9A,1C,C9,4D,DB,3E,CE,CD,06,9D,3B,73,A4,9C,79,32,41,C4,50,89,C1,BA,BF,A1,91,EA,A9,63,6D,26,50,CD,FE,B7,C0,5E,76,CE,1F,14,B6,14,06,91,47,D5,1D,35,0D,68,F4,FC,2F,92,8C,1B,42,80,D7,36,20,5F,79,29,D3,D3,85,A8,BD,62,F6,F9,F1,7E,54,20,7B,81,74,BE,1A,3F,68,F6,FB,7D,3B,1E,5F,8D,8B,80,4C,79,29,6B,CA,33,F2,CC,46,69,AA,F4,87,88,98,A1,80,77,96,E9,F5,AA,DB,D0,89,A7,F3,16,E6,2A,51,4E,0E,DE,0C,9B,2D,09,07,2C,AB,7B,1F,53,7B,7A,79,62,6E,30,E7,37,94,A7,B3,E3,2F,4E,93,27,69,10,29,1F,E7,57,68,8C,B9,23,33,06,E5,84,90,F7,84,1A,81,F0,98,D5,D7,41,E3,86,66,D2,FF,91,CC,76,C0,A4,6C,18,D3,FB,98,0E,12,04,9D,74,56,E9,5E,85,02,8E,2E,49,C5,6C,B7,16,D2,64,4E,1A,33,92,E7,4D,7C,DE,D6,3D,6A,40,B5,81,2E,6B,16,02,83,06,78,90,82,3E,EC,16,D9,6F,D4,12,A5,19,C1,3E,81,B1,A5,A6,47,38,09,48,EE,C8,C3,7B,8D,1A,6D,B9,51,40,20,AD,FA,C4,09,9F,B4,D0,69,C9,0A,DA,F0,E4,7E,90,DA,FD,9D,C3,60,26,2A,3B,9F,E1,F9,DB,61,E5,83,1E,13,6D,71,1E,6F,7A,B9,C8,08,3A,96,29,AE,23,17,99,10,92,E3,20,98,93,F0,32,02,FC,A2,82,3F,21,DE,72,9C,C0,75,43,2D,BB,B0,74,40,D8,06,D4,08,A6,32,D8,56,CA,4B,DD,F9,06,92,E7,2F,5C,F8,3F,21,DB,93,8F,2F,7F,22,EA,BE,66,E5,14,51,10,D0,CF,ED,08,A4,E0,A3,05,BC,FB,D5,E0,AA,91,A3,04,D7,A0,D1,0F,19,D3,24,E3,CF,60,65,01,0D,89,AC,35,D9,5A,29,30,21,5E,A3,AD,9F,4B,D2,59,A1,80,95,6A,6D,3E,05,66,9B,34,BA,EF,6D,54,60,91,AF,EC,4C,1C,17,D3,22,A6,43,29,59,CC,27,A9,37,CD,BD,B8,83,22,64,45,33,44,FC,9D,4C,28,4A,15,37,32,B5,AA,61,21,B9,79,C3,19,24,D5,67,4A,39,3A,99,58,A8,67,BE,B4,E9,5E,92,C0,A2,71,26,31,96,0C,93,D2,03,25,27,B9,60,8F,5D,79,8C,B9,04,67,B7,4A,F4,43,DF,74,52,9F,D7,0F,3E,F8,2E,51,7E,0A,91,FD,44,8C,EB,A8,E4,C3,CD,43,C6,95,CE,83,02,CD,B3,DC,2A,4D,95,47,A4,D9,51,B0,62,A9,C6,D4,84,DD,21,92,90,92,D1,5A,2F,EE,74,2B,47,6F,66,B8,A9,8E,95,01,1A,58,68,D8,44,AB,E6,5B,61,CD,B9,68,79,90,BF,E9,76,7D,2B,A1,D9,DC,07,3C,46,B3,7D,B7,9F,2C,AE,F9,A2,E2,26,63,4A,7A,5B,13,68,B8,06,A8,5F,FE,64,90,18,2E,63,B6,E9,31,9C,C6,0B,12,D0,58,E7,D1,72,F0,B6,2A,3E,1C,B4,87,2D,24,66,21,C3,82,5E,BC,7A,36,58,19,DF,59,EB,EF,8F,BD,28,09,D7,FB,CB,BD,68,78,76,87,D4,BF,87,D4,43,5D,C7,15,EA,51,F8,AF,15,2F,0C,40,E3,74,67,33,F9,49,FC,6C,03,38,BD,E4,63,B7,18,7A,CC,D0,04,C7,40,D1,D3,50,21,45,5D,EC,63,51,A4,55,60,6C,62,82,AF,A5,5C,FE,79,7E,28,2C,21,2A,FC,75,0B,FF,B6,F5,CC,5E,5A,85,0B,F0,44,06,10,E3,67,2D,24,D9,E3,B6,64,0A,93,A0,3F,C6,CD,EE,60,8D,A2,78,A2,6C,3E,34,29,1B,60,A9,BC,40,3C,1A,84,77,47,55,A9,4D,5C,32,1B,B2,F4,C1,49,BD,C7,82,A4,C5,40,BE,57,F8,05,C8,7F,08,52,EF,AD,46,74,7E,88,86,5B,97,ED,7E,BF,81,0A,B3,BD,2C,29,85,77,7D,AC,4E,F9,99,FA,FC,AC,6C,21,AE,56,F9,A1,7A,69,8D,4B,A9,56,EE,A1,5A,6E,0F,3F,37,29,5D,34,FF,87,0C,BA,BF,7C,A5,F7,43,A8,EC,44,72,72,84,E7,8F,8B,1E,28,88,B5,67,13,26,3D,7A,44,0B,E0,B2,A4,EB,CA,AE,8A,0C,15,56,F3,98,87,A6,C2,0C,AE,7C,58,C1,70,EC,C6,B1,8F,24,A7,11,E9,10,2C,F1,3A,1C,60,9A,09,35,46,57,67,07,2B,57,71,49,47,D6,A5,C1,1E,E0,BC,B8,0E,02,3F,26,B1,C9,53,90,C6,C6,86,B0,C0,31,50,5B,47,49,D0,40,44,D0,16,1C,14,C3,C9,62,97,4C,1B,7A,D5,80,DD,94,71,D2,B4,EC,0F,C2,30,75,41,22,2A,2F,B0,1B,56,0A,0C,29,4E,B7,23,BB,98,25,C8,E0,21,9A,94,58,68,63,32,9D,EE,91,95,01,B7,DB,42,52,16,94,26,A6,B4,41,AB,BF,54,62,16,0D,6A,9D,52,4B,CF,23,38,AC,B1,E2,9D,BF,4B,71,9F,B9,CF,37,6F,8F,B8,A7,F7,07,8B,E9,E6,3C,97,82,7F,4A,62,2C,DA,35,97,5D,95,35,07,66,A8,74,0C,08,A5,3B,6A,7D,94,5F,02,01,E8,89,BF,D7,F7,3E,F6,9A,21,5F,D4,DC,BD,6D,12,0D,67,04,50,B7,C7,5B,BE,3F,FA,E5,5C,32,8F,2F,F2,BC,5C,8D,80,D3,C2,B3,2E,B6,EA,EB,E4,68,80,F4,57,64,CA,E8,CD,5C,8B,20,CF,E7,C7,1B,B9,EA,45,F8,3C,91,8D,8C,7D,F1,AA,73,59,59,88,7C,10,27,CE,D5,3A,EB,9A,16,D2,B1,C4,53,8B,DC,65,59,FA,52,3A,45,B9,FA,41,4D,6E,0E,C2,EC,91,0B,DE,FA,E9,E8,4E,87,21,96,A4,EE,61,2F,53,21,C9,CF,64,D4,82,BF,52,A3,02,A4,07,75,ED,33,46,7A,7E,3B,17,E5,5F,92,11,F3,C5,64,AD,FB,36,C7,BA,40,F6,A8,79,14,C1,20,E0,F1,E5,64,BC,BC,37,C1,EB,C1,45,AC,A1,75,40,C8,32,AC,3E,06,14,4E,47,BF,E4,3A,C2,82,B3,A3,9A,EB,EB,E1,E3,FA,4C,9E,A5,18,1D,BB,B9,76,A0,F3,E1,98,0A,D3,DF,3F,33,99,C1,B9,55,5F,DB,54,1B,D5,38,65,CB,0E,73,ED,F3,36,DC,C0,C2,CB,38,5B,2D,09,CE,C9,35,3C,16,AE,AA,24,87,6F,44,E1,93,3B,22,18,4E,85,E3,03,2D,8D,4A,1A,24,48,E5,2F,D8,F3,53,47,C3,36,8C,F1,70,6C,5C,8D,BA,5A,55,37,52,F2,F0,8C,34,55,66,B1,D9,42,C7,D4,0B,AE,2D,23,EC,4F,37,26,B4,62,9C,5D,C4,9B,D0,12,50,9A,38,3C,78,0D,BE,46,EF,8C,4F,D2,28,E5,B9,C2,6B,99,D4,3A,22,5E,FE,42,D9,AF,8F,74,BB,B6,F5,CE,11,4E,16,16,2C,75,A2,C9,5D,05,8F,79,D0,47,16,88,ED,D8,9D,B6,04,B9,C6,EE,BC,03,32,3A,A0,EB,7F,3F,52,74,E1,1B,E1,23,6D,3F,63,9C,47,73,EB,71,E2,9C,9B,5E,11,20,B7,60,52,97,59,4C,DD,38,4A,E9,14,00,3D,7F,E6,F7,3D,78,69,EF,2C,23,C7,78,28,84,25,8D,43,20,85,83,1F,0E,11,F0,73,11,EC,4C,43,FA,BD,2A,E5,E6,7C,91,84,CD,0A,41,C9,E5,43,C6,FE,A8,CD,99,92,7E,84,37,77,83,E2,93,95,7D,C4,B1,8E,4B,76,26,9A,15,1A,41,D3,65,6C,98,1E,43,72,D6,28,4C,BD,4B,91,D8,DD,D0,6A,39,F5,BE,22,58,32,8B,70,83,64,D8,98,FD,56,3E,96,18,09,16,4F,7A,5D,29,B6,C6,F7,71,6A,C5,69,EA,DB,2F,43,BD,9C,FE,BD,E3,01,9C,1D,91,61,CF,BE,93,07,2F,1A,1C,9F,F9,55,17,72,1B,0C,54,79,25,E6,EE,70,8D,7E,00,79,8B,7D,30,3B,17,C3,BE,23,80,85,5B,40,FE,18,07,BC,9C,08,EE,4C,88,FE,9E,5E,68,B7,AD,B2,18,FF,DE,DC,0D,27,E4,23,1D,75,14,03,F6,43,58,F3,2D,78,E1,CD,E6,93,46,17,E7,2B,C9,58,ED,90,37,9F,B2,E2,18,90,07,F3,84,25,F6,5D,71,8D,69,77,3C,ED,92,96,64,81,F2,F4,BD,86,7A,AC,60,03,AA,6B,8F,59,A9,E5,ED,99,4E,DC,6D,1A,32,5C,77,68,8D,51,6E,B4,6C,9F,C2,2F,85,23,FB,D9,31,67,3D,4A,76,4C,61,62,9D,CF,D1,E5,33,5A,6C,45,F7,2C,9A,74,77,02,0A,EC,67,1C,23,8A,03,21,6B,44,D5,D8,43,67,4C,D8,98,6A,9F,8E,C5,C1,8D,D3,5E,82,5A,56,30,4A,D4,47,5F,8E,05,64,A4,69,AE,F3,76,9B,7D,12,1C,85,CD,53,54,2D,9E,D5,AA,89,90,09,2B,A4,67,C9,E5,EC,BE,24,64,C7,A2,5C,F3,65,9C,D5,1B,D2,14,19,17,A2,A4,42,54,D2,6A,8D,D7,77,6A,D1,B9,5A,D3,E5,21,49,F7,48,E1,13,BD,D6,BC,F5,BB,09,0A,C5,B8,C5,F7,E2,FF,32,EF,EC,08,58,EE,8E,AD,82,96,86,AE,EF,CA,8E,0F,26,B6,14,8E,F2,70,7E,B8,21,E7,17,56,07,A1,A0,96,B2,F5,1E,6D,FE,D2,66,D7,2F,A9,0C,95,9B,B7,D8,79,99,DD,16,63,2F,6A,1C,03,89,6F,F9,54,0B,78,3A,95,02,3B,EF,BF,73,2B,5F,3B,EB,5F,D3,09,01,D7,1E,A2,25,FA,93,3B,ED,05,01,CC,1C,DA,8C,1D,76,58,03,CF,FA,8A,C5,00,41,DB,91,1E,DC,98,08,50,C2,04,1B,80,A4,E1,60,13,C2,6B,4E,A9,51,3E,2D,7F,31,68,0B,F7,8A,3A,6D,71,50,FE,41,F4,00,74,6D,B0,4C,53,0C,51,5C,85,02,7A,6C,58,3B,B2,86,04,46,84,BF,C8,BE,61,75,1A,8C,0D,94,C8,5F,58,AE,73,46,62,B7,37,74,AD,52,89,EE,07,00,69,08,6A,02,5E,51,5F,24,13,78,DB,A3,6A,C0,CB,EC,02,97,9A,74,87,AF,91,47,54,18,2A,03,B0,30,A3,F3,59,C4,E0,A5,44,56,B3,96,FC,B6,BE,7C,5A,F4,DD,38,0B,66,35,D9,E6,5C,DB,7C,0A,E7,EE,92,A6,9B,9B,1F,35,37,85,51,3E,25,73,40,62,DE,81,BF,4B,70,8E,34,28,5D,9B,0B,50,EB,BE,FF,1F,32,C7,D6,8C,AA,3B,BF,80,9F,A1,52,7A,80,47,B6,BA,BE,68,56,81,C7,B6,74,63,59,3C,9F,79,C5,67,2E,08,2B,BB,F9,10,6C,40,F9,26,5F,D2,F3,52,9E,8E,CE,5D,DE,A1,D3,EC,FF,54,5C,0E,0E,50,D6,45,8A,05,21,FF,D3,58,F7,83,72,B8,96,2B,0E,0D,5D,76,65,02,0C,61,A4,47,9E,80,CC,80,EA,B8,36,06,22,4E,F6,1B,6F,A6,22,80,B8,92,3A,1B,6A,82,D4,22,03,DB,F7,4A,61,D8,EC,20,DE,93,1C,D0,39,F4,C5,02,49,07,B4,93,F6,71,9B,40,1B,69,F4,B9,02,0F,01,21,7E,96,23,BC,6F,11,43,9E,8A,91,B0,95,C2,3C,64,A6,7D,D0,D6,47,DC,A1,EE,95,02,11,6B,E1,78,4E,42,37,8C,D9,8F,3B,D3,96,65,F1,B5,2B,CE,7B,60,2E,68,2E,36,95,14,07,AA,2A,61,09,32,EB,8A,F3,70,7C,C2,FE,BC,FD,7B,5B,71,9F,CF,92,87,9D,8D,C9,58,62,ED,12,72,2F,AE,1F,FD,B6,3D,C6,80,F1,2D,32,1A,44,15,33,DD,92,E3,26,3A,70,56,A9,85,7F,50,4E,94,CD,6A,72,D6,D3,A3,16,5A,E6,27,13,B7,1E,10,B3,8D,C2,20,AE,AD,4B,87,12,A1,81,B8,E3,77,28,65,98,EC,43,43,2E,52,91,04,1A,AF,EE,1F,57,67,0A,DA,61,31,1C,09,DD,B9,B0,7E,0F,D9,6B,3B,B8,A7,0F,02,DD,B1,61,B9,F7,2F,3F,BD,A4,66,A8,69,83,AC,09,45,0A,4B,49,4B,3E,B6,52,5E,8F,2E,95,40,95,FB,76,5D,DB,94,A1,4A,04,FF,A7,E5,66,BE,03,7A,31,C3,6F,34,72,AF,D6,2A,8A,74,6E,E4,84,0D,E5,93,C8,88,E6,E3,7A,F4,9B,54,C3,CB,00,39,2D,06,76,E1,D9,EF,27,64,F8,A5,49,EB,BC,89,35,24,4B,47,23,BA,1D,82,64,EA,7A,93,28,9D,47,C9,DF,6E,71,BD,CB,8B,E5,94,4B,EA,A4,E8,1B,8C,A9,8A,09,E7,4E,51,F9,63,9E,49,75,EB,E7,EE,35,B5,53,E5,D4,34,16,AA,79,7B,20,6D,9A,2C,DB,D1,B9,2C,52,C3,16,E3,03,C5,75,82,22,E3,7F,37,6A,6D,9E,D4,90,3A,DD,E4,57,03,CB,2F,92,5F,8D,47,FA,CC,5D,9E,B9,B9,26,D4,1B,85,9A,25,22,04,CC,45,AD,AF,0D,D7,48,F0,2C,6C,71,01,8B,3E,87,A1,D2,D1,38,28,8E,D3,5D,01,89,2C,3A,77,14,7A,A1,5D,37,2B,75,4F,2D,51,94,8A,A9,0C,26,5E,0F,BA,3D,75,75,18,D5,36,2A,77,02,8E,77,B5,F3,6F,49,6D,74,F3,3D,C0,FF,45,BE,F7,25,9A,E3,05,3C,24,36,B7,7E,0A,52,4E,27,B0,C9,BC,30,0A,8E,FC,BA,79,5C,F0,B7,6F,6D,B5,96,4E,86,BD,DB,F2,62,7D,AC,90,F8,84,01,00,D1,8B,CD,CC,9E,4F,48,F0,1D,06,75,AE,FC,EE,FF,98,00,95,21,12,F9,3A,83,A3,A2,63,2B,1A,67,D7,E9,F7,47,9B,C0,10,FD,3B,F4,8F,5E,17,D3,34,32,58,24,31,43,9C,86,87,14,92,99,7E,F4,71,1C,E3,87,29,23,7C,7E,AB,9F,3E,53,D3,BD,81,72,17,B7,F0,0A,FF,6A,38,2B,A4,A7,1A,1F,80,D0,0C,56,45,CD,0C,35,AD,73,60,3F,A1,A4,E5,45,9B,2C,31,D5,75,6E,57,61,EB,64,40,F5,BD,46,ED,2D,A9,AA,24,B1,75,3A,9C,DD,9B,22,AC,28,E6,04,87,07,BF,52,0B,A9,2E,05,13,12,CE,34,B0,DB,23,CF,D5,3F,C5,FE,21,EA,30,29,7A,A3,53,F0,F6,BF,EA,DF,90,FD,DF,0B,D6,78,F9,80,C2,8F,F2,41,47,19,55,1A,93,65,D4,66,29,CC,48,29,2C,9F,9E,51,47,CC,D7,21,FA,A1,64,1E,CE,45,9E,A0,D1,7F,29,52,DC,76,99,D2,93,87,0A,39,99,3D,9B,8F,62,0E,51,EC,6F,64,2B,0B,5C,95,55,1A,C1,88,02,F8,1E,CC,79,57,51,2A,BE,50,D3,E6,A1,B6,5C,9E,C7,10,5F,CF,83,00,57,D6,1C,A2,A9,2B,54,9C,89,C7,A9,AA,78,C0,56,48,1F,86,A8,FA,9D,62,91,08,E8,61,5F,25,A4,A7,3B,C6,F8,A5,E3,CD,C8,60,FB,90,0E,02,A0,BF,BE,C3,1D,96,1D,86,43,1A,47,3F,01,CA,45,4C,EC,75,7B,84,72,09,95,E5,7B,5E,34,E6,D3,0E,C0,8E,00,BE,AC,DE,47,46,31,8B,FC,87,5B,B2,39,88,7B,5A,4B,78,77,14,EA,70,E2,DA,5E,50,B5,B6,F3,34,2A,58,A1,2B,8C,BF,0E,13,A6,0A,69,A8,95,A2,AC,19,44,11,F9,76,37,CC,77,05,9E,0D,1F,D9,4F,7A,40,2B,D7,BF,92,C4,56,62,0B,3B,B7,8A,F3,DD,6F,0E,3C,86,43,88,72,02,6A,34,89,05,D2,8E,81,5A,DD,6A,CE,D6,51,0A,A2,4B,EB,11,13,A5,34,13,F6,F1,11,38,FD,FE,43,32,BD,93,0B,5E,65,DB,0F,F5,01,D2,78,D8,F9,5C,5E,1F,E2,51,CB,1C,4B,DE,97,DA,8A,AF,48,A5,F0,2D,F7,7E,D1,69,E2,4B,C7,9A,A5,5D,6F,65,A8,96,66,AB,41,D1,C0,40,66,00,68,EB,CC,BD,B6,CC,66,73,F3,A1,9E,17,FA,9A,43,8D,3A,1A,05,3D,4A,38,23,D7,00,72,30,80,31,B2,BC,79,C4,CC,9A,68,4E,92,75,2E,79,DE,AF,34,3A,84,AB,75,E5,FD,6F,DC,BD,62,F8,9D,B3,6A,CF,93,7F,C7,F0,85,F8,FE,8B,47,98,2C,11,0D,03,78,D1,D4,56,00,75,D7,AE,34,75,03,54,86,47,CB,EC,5A,74,A8,F5,09,F2,EC,96,19,FC,EA,8A,9A,82,A1,6D,41,E2,C0,45,5F,35,76,10,B3,70,70,3D,E8,00,FD,9B,2E,87,3B,F8,29,EA,84,8F,39,2A,99,46,17,71,90,E0,05,8A,65,41,B5,4A,BF,97,2B,74,81,A2,DB,63,10,80,87,33,7B,A4,DC,A5,59,70,2E,90,24,4D,94,EB,DE,62,E3,68,CA,07,DC,51,60,49,8B,FF,25,96,B2,E9,3B,06,7B,0C,E0,90,C0,61,B0,13,4F,C3,90,19,7F,D2,89,87,44,94,3E,C7,25,66,C8,27,74,2B,B7,07,87,7E,83,0B,98,FA,AF,28,08,7D,86,AE,0E,92,8C,5F,27,D2,D3,5A,F9,1E,FE,16,69,B1,C4,FF,15,57,05,26,9D,AB,48,2B,3C,35,FB,F6,8E,73,72,72,11,AA,EA,18,85,1D,61,23,28,5A,AF,D7,01,C5,E4,83,70,75,9A,E9,C3,9E,8C,75,1E,D3,F9,4B,BC,2D,91,B8,16,D7,24,8A,FE,3C,4C,D7,41,5A,E9,AE,B0,01,38,C5,6F,C4,F8,E5,4D,D5,A5,87,EA,29,84,B3,70,A2,90,D7,81,05,5B,E6,88,6D,57,E3,31,F5,8D,23,AF,68,FE,F4,F5,1F,63,13,87,E6,6F,92,4D,9D,8D,DE,5D,F4,3F,FC,11,91,76,35,C6,CD,11,63,D0,CB,A6,27,35,62,49,94,75,E6,0D,27,82,C1,B1,40,84,A3,34,79,FB,29,C9,34,FA,65,BC,B2,65,9D,5A,D4,98,8B,BA,72,4F,F2,63,4C,0F,52,D4,E7,C7,2C,DA,EB,67,44,FF,D1,63,86,5E,B1,4C,A5,A6,C2,E5,77,2F,FE,96,AD,D9,A9,DF,30,9A,2B,4C,8D,C3,8A,16,EF,25,FF,EC,89,C5,29,3A,9D,6E,6D,01,F1,9E,AC,6C,5B,5A,34,0E,67,2E,CD,42,9E,F0,F0,B6,57,DE,7D,32,C5,3B,F4,2A,A6,15,BD,BF,9D,CC,FD,B0,13,6E,1C,D3,0D,3A,79,81,26,05,01,29,E6,0D,6C,25,66,5D,AB,0B,50,4C,79,AD,D0,21,16,22,58,93,BB,52,76,EE,48,E3,08,AE,21,4F,30,61,EA,33,12,0E,D4,6A,C0,90,3C,78,D0,BB,69,8E,00,94,FF,30,0A,14,59,FD,9B,DA,82,14,13,2F,B8,54,BD,96,CC,9C,F9,91,14,7A,87,78,6B,D1,51,D9,2F,32,F2,83,CB,E2,73,96,63,F0,25,00,86,D6,5D,A6,20,6F,B9,BD,8E,B2,E2,3B,AA,38,34,96,D0,6B,36,08,D7,DF,99,02,C9,BC,99,66,8A,48,BF,9D,F1,D7,8E,55,72,B8,FC,45,04,A7,C8,B6,64,87,B2,57,40,65,FD,33,89,A6,C3,07,8A,A1,E8,53,F8,FE,33,ED,82,05,3E,5F,26,61,09,48,F2,F2,E3,A6,AF,23,6D,77,52,FC,9A,02,37,54,6A,76,D7,1C,38,45,7B,C0,57,6D,B6,E1,04,FE,B9,B5,87,3C,7B,75,1A,45,4D,2F,97,B1,97,EA,F1,02,31,25,A1,BE,7D,D3,C4,B4,AF,28,05,F5,82,31,C3,AC,A9,6B,DD,E8,FC,D9,A7,C9,C3,32,CC,23,17,74,96,EF,81,0B,33,41,CE,FE,EB,BF,FA,E1,68,3D,26,22,71,AD,AB,D5,0E,AB,70,62,A3,DB,A3,85,78,E9,8A,C7,21,A5,A2,02,46,D1,1C,01,73,5A,88,90,2E,0F,89,78,95,3D,5E,DD,DE,FD,D9,D4,7B,D6,52,07,6B,98,E8,F1,1D,14,6D,E0,BF,4D,C2,98,B8,E9,D0,28,ED,AC,7E,20,A6,F3,DD,5F,E7,40,84,DB,5E,C0,4B,67,56,6C,5F,F8,BE,53,4E,7C,8E,2D,B0,7B,7B,E0,6F,C1,13,BD,B5,96,5F,E8,B4,78,C7,70,FE,DD,60,EB,E3,22,B0,D3,F2,5B,D4,AE,AA,39,32,29,4E,90,F1,7B,71,7A,A1,17,21,C9,3E,B3,BE,50,C9,B7,30,78,03,B2,97,B7,41,91,54,7E,F8,7A,36,32,1C,68,CD,09,68,D5,BE,00,B2,2C,9A,FD,FA,8D,9A,8D,1F,7F,05,FD,75,87,6E,EA,47,70,57,30,B7,54,E9,F7,C7,5E,A1,36,7B,68,67,91,15,B9,A5,BE,06,7D,84,09,52,0C,4E,44,4B,D6,A3,75,33,3F,7B,24,CB,DF,9F,64,A3,78,79,9D,4E,C3,84,46,37,0E,45,09,56,78,BD,65,0F,CF,49,01,A7,A7,A3,02,8B,9F,B5,B6,B6,34,37,F5,69,77,6B,D8,3C,16,DE,C8,6E,3B,45,49,49,31,09,4F,95,F6,31,2D,13,F4,56,1D,CE,55,62,92,C4,89,32,83,CE,B6,45,16,35,55,F9,E1,3F,6F,2A,BE,02,05,5B,3D,06,FC,8D,54,94,33,00,0D,00,E0,EA,4C,6E,2E,45,8C,49,0D,BC,B8,2D,EA,50,F3,65,BC,A5,C4,A0,1D,93,1F,C6,56,BC,D2,B5,D5,4C,FC,7B,A8,2B,1A,73,44,36,AD,40,9E,A7,B6,8F,4E,DF,4A,CA,3E,6F,8E,85,09,7B,38,56,6E,A6,B1,84,BD,5A,B6,DA,E8,05,C2,EB,8D,7E,D1,DD,C3,85,BE,EA,06,73,46,3D,D5,44,8A,62,80,65,2A,40,5B,57,C2,84,30,C6,7E,4C,D8,89,BF,91,60,AD,1E,6E,C0,BA,1F,9F,4A,B7,A7,55,68,9C,4A,70,8E,5D,CF,57,02,B1,5B,D0,C5,B6,3F,F8,1B,95,77,4B,93,52,A1,A3,9D,59,09,95,13,AA,C8,09,4E,8B,33,35,FB,AC,48,33,EE,BF,5B,91,94,50,5B,03,83,3C,C3,49,33,8F,6D,E9,AE,85,06,7F,C6,8A,F7,CD,6B,27,E1,9F,06,C0,73,EE,3A,68,E7,BD,3F,AA,D7,51,B4,E9,ED,91,AC,17,2F,8B,D6,FE,47,C1,9B,32,DB,25,FE,00,24,81,E7,CD,FE,D3,2D,D9,8A,B0,C4,FC,FF,17,C6,6C,6D,B9,6F,C3,91,6F,0C,52,59,E6,11,F8,79,B3,64,31,7C,20,F8,77,AF,16,22,CB,36,57,1A,EA,65,A5,E7,9B,87,42,AA,96,41,B5,8B,0F,34,55,DB,07,63,CB,BA,4C,02,3F,79,92,A5,66,0F,F2,50,54,90,79,8D,BA,A9,55,31,8E,34,CF,02,DE,6D,08,72,11,3C,18,44,4D,7E,91,4D,10,38,24,0F,C1,B8,B0,E4,B1,88,86,4F,C5,2E,50,B3,C6,B9,89,63,20,7A,47,D9,08,12,8D,5E,10,54,C1,F0,C4,C4,ED,80,5C,CF,49,B6,2D,06,05,A9,69,E0,8B,33,E5,EB,65,18,30,3E,8C,4B,28,97,E5,9B,48,C3,45,B4,03,47,78,BE,2D,C4,8E,70,D6,12,40,4D,75,75,31,95,0B,17,3E,1E,C3,33,C9,49,13,8E,BD,6F,68,24,07,8A,5D,00,C7,E1,AF,02,7C,A1,5F,80,E6,7D,50,39,48,A4,1B,EC,3A,3A,CD,15,F8,F1,89,FF,95,E3,5B,93,FF,B4,45,FF,8E,2C,7A,BC,96,AA,32,14,A3,F1,A8,C7,69,C9,1A,DD,4C,0D,25,4B,74,47,13,95,13,C0,32,80,BA,6C,34,40,48,8F,CC,A8,2D,01,93,3C,A0,9F,C9,F5,BF,D9,55,F2,7B,68,08,80,0B,92,FD,CC,6A,5B,9C,0A,D9,09,46,ED,5C,42,E8,FD,6E,8D,1C,61,5B,D5,CB,B6,32,A5,CD,A7,46,0F,1E,C4,DB,7A,0A,C4,F4,FA,1B,9A,8E,E4,C0,C4,A5,9B,79,F0,5F,29,FC,B9,47,25,93,CA,D6,56,0E,83,84,D6,57,CD,03,A8,CD,89,2E,68,04,82,82,FF,3F,C3,A0,67,70,A8,69,18,BE,1C,B1,D2,E5,E7,CC,94,B7,2C,ED,C2,3A,8B,42,BD,D8,5D,B5,3A,FC,45,E9,F1,18,BE,BA,C0,7A,53,53,8F,2C,28,28,3F,38,63,A0,C3,56,B4,5E,75,93,F7,0D,7C,45,C3,70,8D,1E,AC,AF,22,03,00,51,FB,68,B9,22,A6,AA,10,69,A7,6A,2A,B3,74,86,79,BC,6E,5D,65,78,EB,BA,9E,5A,C6,25,41,A3,C2,BE,53,95,D5,71,3F,B5,30,E7,EB,D2,D8,A2,A8,07,1F,14,F8,3D,DB,04,75,98,25,BA,C2,98,28,C8,AC,69,96,22,6E,43,FE,70,BE,84,6C,98,07,B6,53,1B,A7,C0,BB,40,1C,11,D5,17,17,54,46,E0,C3,6E,C0,4B,22,04,D3,3C,5B,E9,EE,08,4D,C5,B9,8F,63,84,71,62,F2,C3,DC,5C,86,96,E3,05,C5,33,BB,96,D2,D6,E6,94,01,0D,43,56,DC,7F,0A,86,A5,EB,43,05,6E,DC,0D,E3,D1,6E,5E,42,6B,F0,26,8F,F7,E7,19,B3,36,8E,B1,BE,79,5B,30,11,E0,26,71,9C,95,E8,71,F6,0D,C1,65,70,88,F1,29,9D,20,BC,F7,D6,D9,4F,3E,CA,8E,E8,98,30,13,CA,A1,B5,F9,76,BD,71,66,1B,D7,DD,72,B4,D8,A2,F7,DF,DC,A4,78,94,A1,89,32,FC,7C,61,13,3C,08,06,CE,83,0F,47,51,98,53,4E,30,B7,3B,09,5D,CC,29,63,57,70,EC,A4,50,B2,D8,9C,1A,F4,D4,09,55,02,3F,FC,A3,D9,41,2E,D5,EE,75,B7,3B,E6,B6,A2,BC,BC,3B,33,C8,C4,F3,8D,21,FA,26,87,EB,44,6F,DE,8F,28,5B,E2,92,5B,60,A4,EB,D8,48,C7,9E,1B,F0,F9,C8,6D,F1,C8,77,75,97,EE,0F,0A,C9,1E,E2,80,A1,2F,99,66,39,09,60,DD,AA,E7,86,95,5F,DB,EC,3E,F6,CE,82,BC,C3,06,76,25,22,28,71,FB,AC,E5,D4,77,71,B2,16,DB,2C,1B,8B,B3,1C,73,24,BA,F8,8D,F1,7C,CB,67,F1,A8,92,53,BC,29,E5,DF,D4,F8,5F,10,38,79,38,FF,4C,8A,F6,61,14,58,38,F9,38,72,DB,9F,AB,42,AF,09,AE,08,84,8C,AC,7D,3E,9F,D7,36,38,20,8A,27,49,D7,5E,7B,51,19,5A,29,5A,AF,93,CD,C4,4C,FD,6C,5E,52,C7,4F,06,DA,7E,DD,CB,23,EE,C2,08,B1,A2,6C,18,C1,80,48,C9,7A,48,09,65,76,11,82,D8,21,F2,39,AA,87,10,46,8A,CC,5B,2D,56,D3,0D,05,B7,B4,78,4D,6F,D3,D9,07,9D,F0,41,27,6B,E2,9C,6B,14,84,5B,4B,D3,BF,9C,C0,C5,40,62,ED,E5,EC,98,72,2F,25,22,F8,FF,51,81,54,1E,10,F2,BA,48,81,12,D8,D4,BA,72,7B,7D,54,C7,F1,63,A5,97,E5,1A,65,8B,07,19,FA,09,2C,39,9E,20,2E,EC,DB,50,FC,2A,76,40,C2,06,87,76,45,7C,3F,C4,16,45,E9,F9,DA,6A,0A,90,7E,D4,77,A7,0A,CA,74,9E,91,4A,B5,B5,BB,2F,8D,68,87,4E,6F,D6,E6,23,99,88,D1,ED,93,C7,89,78,DA,5A,F9,6A,FD,62,F9,64,E4,49,6F,30,D4,1B,47,45,1C,A0,3A,AA,24,41,9C,1D,B6,92,B7,D2,7A,42,4C,86,75,5B,29,05,26,A2,8F,1B,C7,6A,3F,87,B0,C8,DA,79,2C,97,3B,1C,B3,BA,2D,93,90,DE,91,A8,9B,AA,35,AA,47,FD,37,35,63,91,C6,8E,22,5A,04,57,AF,21,8D,E1,64,CB,FF,DA,92,47,31,1B,2A,87,73,CD,BE,43,58,EF,09,F5,4E,12,5B,3C,B9,AB,50,CF,14,FF,C4,FD,7D,EE,94,26,58,F9,5A,C7,94,36,2A,62,86,D3,BD,23,E5,89,77,CB,24,5D,EF,BB,9A,E9,7A,C7,2A,C7,AD,89,5E,62,33,91,C4,13,52,C5,1C,02,70,FF,F4,E0,EB,1D,67,6A,8A,AF,D6,68,1B,EE,5C,6F,F7,71,FC,C1,D8,BE,36,1B,06,C5,04,23,EE,3D,B6,17,A2,80,F0,37,01,61,89,63,46,1E,21,16,03,BB,63,9F,96,C2,66,34,1B,A6,8B,46,06,4A,06,DC,AA,F7,84,FC,41,F1,F6,E8,71,3E,F1,F0,2F,6D,D7,E8,B5,9B,72,09,71,35,90,C0,05,8A,CA,86,89,45,78,80,DB,10,DF,40,A1,74,9F,75,5D,CA,08,39,93,8D,A4,EA,36,43,85,31,A8,D3,86,44,F5,36,89,CC,9D,DD,68,D5,0A,BC,EB,A0,44,FA,F8,BB,78,26,40,66,65,21,2D,6F,C0,97,2E,76,16,4F,C2,93,43,E2,83,55,B5,F0,66,02,C3,2D,CF,92,35,3E,21,7E,7B,58,76,85,E7,83,44,80,5D,64,91,EC,DA,4D,61,B7,02,07,93,FE,2D,D6,D9,BF,46,2A,EE,72,06,E1,CF,DD,E7,2A,A9,6E,D2,E9,D7,DE,E1,39,92,C3,0C,62,94,FC,A7,1A,84,61,E7,B7,85,2B,9B,A9,98,F3,5D,C2,A5,9A,B2,68,21,92,50,2D,76,F1,2D,26,88,D8,33,CE,B9,5B,B5,42,1F,BC,B7,6C,96,46,B4,0A,DE,B0,0D,96,07,04,64,D2,BD,BA,21,D9,06,71,6E,F6,FD,97,4E,C3,A4,E1,CB,F9,87,5A,F0,D6,9C,D1,E1,BC,8E,51,28,17,7A,F5,FF,DF,E0,4F,96,8A,FC,EB,3F,9E,E9,8D,07,2D,81,73,AB,2E,E8,A6,DD,DA,38,22,A9,DE,03,41,06,0F,14,C7,C3,90,F2,92,EA,8F,08,5C,19,4B,A0,36,D8,85,CB,F0,1B,F4,C9,9E,21,92,E6,6B,D1,3F,8F,7D,8C,D7,06,46,39,DE,06,6B,B6,96,D6,73,A9,FB,00,38,B4,B3,4E,B8,88,94,E2,D1,EC,67,F2,20,1C,1E,7B,9B,5B,D6,54,78,08,8A,3C,1E,5D,8D,F5,93,A4,66,07,C8,D2,CB,39,81,C9,F9,60,BC,6D,7E,9F,F2,FD,2C,2D,09,26,42,00,19,D3,1D,8C,5B,43,98,75,FC,01,ED,2C,22,EB,EF,11,D4,A6,E6,D7,E3,FC,78,7B,B0,93,61,18,92,91,40,39,6E,46,E1,5C,D2,3F,01,77,29,89,3A,A2,FD,DA,F0,43,BF,96,3D,0F,E4,46,C8,BF,20,FC,6F,0F,DB,4A,2E,8F,BD,80,43,C9,57,DD,C3,12,BB,EE,3C,D1,91,55,1E,A2,42,5C,31,47,9F,E6,65,E7,A9,9F,99,4D,4A,2D,94,AE,37,70,36,E9,D5,02,47,60,B0,55,E6,72,EE,E2,3C,EF,5B,74,E0,00,6A,5A,11,D4,DD,31,B7,D3,65,5A,AD,56,DF,D9,D5,0B,94,99,1E,D7,31,A7,1C,0E,31,10,B1,43,0A,C5,90,EA,AD,03,3A,1B,3B,78,EA,C3,35,B2,D7,B6,2C,A5,3D,19,4A,6C,94,A3,DA,A4,65,FB,E7,DD,93,7B,69,5C,5D,F3,26,0B,32,CC,3D,26,1A,63,2B,A1,EE,11,DB,C0,0D,A2,DF,01,CE,1A,58,09,A4,06,B3,7B,C2,0F,17,D7,37,ED,00,A0,73,29,23,BF,07,BD,62,E9,D3,45,85,F2,1D,AB,C7,66,E4,8D,A4,F6,C4,81,5A,09,E6,BF,50,48,4F,8B,24,0D,47,CE,E3,33,D2,B0,36,5C,BF,DC,11,4F,4C,BA,FF,0F,6F,13,4E,61,9F,E1,40,B3,9D,15,71,9C,43,8B,73,7A,20,A7,15,8A,CB,7F,18,06,D5,8D,AB,AC,FC,C5,0C,C1,A7,D4,EB,6A,77,E1,1D,5D,19,1A,17,0F,A9,D7,33,17,82,ED,AF,3F,E1,39,A5,9A,36,4A,82,96,9D,5C,81,03,9D,21,C2,B8,60,74,4B,55,51,C6,92,B3,8E,CC,23,E7,BC,1E,A5,3E,BF,AB,88,09,4C,24,E2,36,9B,03,38,EE,E8,89,0A,44,B7,98,BA,96,29,4B,66,64,3B,63,B1,19,4C,39,26,D8,C1,7D,DA,DC,7A,DD,A9,73,B1,3F,97,9F,2D,41,70,87,97,18,DE,90,21,AC,28,CD,EB,0A,D1,CD,DE,49,14,AB,C5,69,4D,37,21,04,E4,0C,D6,9E,CE,41,37,2F,4B,40,7E,95,98,EB,22,8D,2B,ED,5E,CA,61,CA,B5,22,61,B6,78,C8,4E,7D,6B,12,A7,29,3A,59,A9,A8,D2,E5,EA,22,00,11,63,FC,2B,9D,B0,B9,AD,54,21,89,46,C1,A0,4B,15,90,3E,05,EC,C9,DA,D1,DF,48,58,BB,36,12,C4,E7,CC,9F,E3,F5,5B,06,B3,7D,15,99,49,01,73,2F,51,A4,D6,3A,98,87,3E,B1,6E,2B,EF,26,B6,84,83,71,93,2A,96,D6,C3,54,3D,5C,C6,48,FC,28,B9,63,E7,D1,E3,C8,57,ED,E3,6C,79,B4,F0,FC,5D,6D,7E,36,DC,47,AE,25,58,FF,7B,37,F4,08,C6,4C,70,2A,67,E7,52,B5,65,2C,D1,2D,BF,36,73,86,4B,86,4F,D4,E9,22,BF,FE,C8,47,24,AA,21,A4,82,0B,99,C7,AB,30,36,E1,CA,F6,4A,67,C1,4E,2B,35,CA,26,A1,99,8C,6C,32,9D,5C,52,CF,7C,EC,E1,3E,C9,7E,7E,A5,2A,39,A6,32,09,E5,2C,1A,D7,83,F2,E5,91,6C,F3,6F,C1,27,9C,15,0A,7E,4E,B0,3E,F5,E7,1D,36,89,10,E1,A7,0D,11,E4,D7,56,2A,44,1D,27,D7,46,9D,D2,73,3F,8C,8B,64,95,4F,67,B8,8C,49,FE,1E,BB,03,B2,0E,08,54,97,6B,2B,5C,56,1F,7C,29,1A,94,87,0B,27,DF,C9,75,38,AF,FC,2A,34,8D,5D,33,C2,D6,48,75,89,63,1A,B2,2B,84,17,BA,EC,16,81,AB,5D,2A,3C,3A,29,60,35,44,7D,0F,71,75,7B,C0,0E,FB,F6,5C,97,AD,22,4C,D3,7F,22,D3,CC,80,87,1B,12,7C,04,96,D7,75,E4,CD,E2,45,CB,51,3D,5F,13,55,05,49,E6,58,1D,64,3E,F7,ED,00,87,94,FE,3B,D0,F4,ED,B3,81,FD,9D,B5,11,B6,91,B6,D5,99,CA,72,E6,66,CD,32,65,26,5F,FF,BB,B5,AD,72,4C,14,A7,4D,28,A0,BE,13,E9,AA,40,5D,82,0A,8E,70,DE,1A,84,71,F3,60,CF,84,B1,8F,CD,99,13,0D,E8,64,F7,03,AB,C0,3C,33,26,4D,5F,4D,6D,13,A0,E3,FE,C0,82,6E,AA,E5,5B,27,BA,F3,8D,19,76,8C,2B,D3,BB,9C,F0,24,1A,3C,73,86,7B,49,47,8F,6B,58,4E,49,D5,46,EB,FE,41,E1,37,48,4B,82,AC,2D,A4,31,EA,FE,F8,23,FF,ED,35,F1,21,AE,CB,28,A9,4B,D3,A5,8C,D1,70,69,F2,50,03,0E,73,F2,F3,B2,71,47,B0,9E,B7,5B,99,3C,96,6E,C0,FC,44,E2,79,BD,7C,73,CE,E5,EE,39,A9,76,0E,4E,C0,C8,52,1D,00,7D,EB,B2,63,E0,67,AE,3E,B0,C9,8B,62,62,D0,C5,32,E9,68,C8,4F,34,1B,B5,21,01,A2,37,2A,CC,86,3A,9F,55,94,48,A4,AA,E6,D3,F5,67,D5,2D,64,9E,53,F2,EE,90,10,3E,FE,9E,F3,66,A9,40,77,65,25,A2,74,BF,97,60,79,61,4A,14,34,90,62,D3,FE,12,35,7D,93,F0,5B,B6,9D,9B,23,0A,81,40,9C,6B,72,6B,7C,97,03,7A,16,B4,DE,54,24,85,B2,21,A2,CB,64,A0,B6,30,B4,CE,AB,70,8D,76,00,1A,4B,8B,D2,37,01,36,B0,D3,F3,61,E2,06,97,10,76,D9,C8,8F,A5,20,94,DC,FB,68,E0,97,03,EC,92,60,EA,57,40,15,6C,40,5B,AB,7B,5C,CE,93,F8,3E,CB,A6,9F,F9,AF,CE,22,03,68,74,7D,DE,7E,FA,0B,77,01,2C,94,0E,4F,38,DA,FE,53,C2,5F,A7,1E,7C,D9,D8,6E,C6,63,7A,D3,A4,A6,46,AE,6E,B9,A9,F2,8C,2B,C6,C4,62,DE,57,63,8F,7C,A2,73,E7,F1,6F,A9,F3,E2,03,6F,CD,02,9B,CD,12,BA,6C,E9,09,2D,EE,7B,C2,C4,91,7E,62,84,B4,DC,1A,D8,FE,7D,D1,01,57,E4,29,8E,31,61,F9,63,32,AE,1F,81,A5,F2,B0,34,C5,9B,BA,10,C0,0C,7C,AA,66,6C,1D,A9,E2,76,79,E7,6F,E1,79,A8,3B,1F,EA,4A,2C,8C,79,58,97,27,00,D4,B4,73,2C,8C,14,CE,E8,88,28,D7,E1,C5,DC,F1,CB,6F,A4,52,42,23,C9,AB,F1,C5,36,D7,4F,87,45,89,65,EF,1D,0C,5B,6C,9E,5B,32,DB,07,17,29,0F,FF,D6,B4,7B,FC,14,64,15,FD,66,92,33,9C,30,B8,02,8B,22,0A,4F,37,DD,A2,AD,3E,97,4B,BF,E3,C7,10,3B,3D,32,A5,06,11,DD,B9,DB,DC,65,5F,85,F8,A1,E5,65,49,6A,AA,36,12,BF,32,BA,93,9D,B5,CD,9D,33,DC,63,1F,43,BB,A1,A2,BF,64,40,2F,B0,80,CF,04,CA,42,BB,3A,FF,7C,3B,0F,6E,E6,6D,3E,AA,5C,5C,5D,EC,61,83,F9,8D,95,38,68,A0,FF,05,71,85,25,61,25,E3,74,B5,0B,B3,73,70,A0,D3,15,E9,17,B5,9C,0A,2E,52,62,98,26,BA,9A,26,D1,7D,31,4D,5C,61,C6,8A,95,CC,FA,42,67,7E,79,FD,F7,63,98,36,33,AA,1F,11,47,00,A0,6E,EB,84,CC,84,AA,E3,70,7D,ED,C0,2F,48,00,A0,2C,36,9B,97,DF,8B,FE,7D,8F,C6,F4,17,C7,02,66,E8,A6,B6,30,05,6B,E1,3A,C3,1A,4F,AE,CF,91,F6,89,64,3B,E1,66,89,62,62,8D,B6,05,3F,47,0C,BF,8D,33,F3,C1,5D,9B,32,F1,B5,6B,99,7E,C8,2A,F1,FD,4B,1C,7E,F2,24,80,51,FF,E0,34,E7,8E,DF,6A,C6,D7,FF,39,0D,E3,53,5C,1E,8E,37,0B,F0,7F,EB,3D,3A,0D,57,B5,01,75,40,C7,81,17,43,99,AC,7B,D2,F1,4F,CA,B9,EA,75,EF,A8,DA,77,D6,E0,4F,76,4C,2A,39,58,21,F3,70,64,BC,C4,9D,6C,41,7C,86,48,B2,43,BE,33,5E,9D,3C,27,05,D1,44,D9,1A,4F,8C,DE,31,EB,44,66,0E,07,32,10,FC,50,CD,BB,80,BE,4C,D9,6B,BF,3A,B8,95,FF,09,46,51,8C,3B,6A,61,5D,00,98,52,9E,90,54,41,A1,35,53,22,49,87,98,86,4B,D0,D7,1D,62,46,A3,F7,55,B0,C2,A3,92,C3,74,AA,16,69,3B,99,73,7A,F4,7C,83,40,79,61,A7,87,31,16,E0,0C,DB,74,1A,04,3D,EC,D9,07,41,CC,B8,D3,93,3B,2A,FE,3F,85,36,5B,C3,DD,5C,4F,5C,C4,F2,BF,11,51,F1,FE,34,91,C6,85,E1,F2,9E,7D,4A,2D,B3,78,06,28,8C,2F,5F,80,55,3A,CF,5E,CC,F8,2D,49,1D,D1,5B,77,3D,4D,4E,FA,9F,8E,DA,A1,7C,96,A9,2D,F6,AD,81,4D,BC,69,88,97,A8,98,A2,9E,7F,1A,95,B6,8E,C9,0D,29,34,86,1A,23,5D,6E,3E,0F,10,35,AA,98,81,CA,EB,7D,EF,82,A6,BF,37,05,55,58,9D,B6,05,88,39,9B,EF,05,B7,CD,CB,9D,CD,42,2F,C8,31,33,D7,75,DF,79,6B,60,0B,B7,F8,13,4F,01,F0,75,72,8A,97,8F,08,1F,BF,E9,98,1D,FA,FE,24,34,43,21,D9,8D,85,63,A2,BA,73,93,8A,94,16,06,11,F3,1B,77,9C,F8,4F,F2,C6,C5,AD,F7,AD,99,5C,7B,A7,D3,7C,7D,60,B4,A2,DE,BF,D2,E3,C5,E1,D0,28,EF,87,31,13,A8,72,D4,E9,E3,8E,FD,A5,C2,33,C2,24,22,86,0C,43,EA,17,2B,AB,2A,FB,B2,EC,E7,AE,6B,C8,01,CF,2F,F9,29,38,B7,47,0C,C4,6D,F6,51,54,BC,A4,72,61,B9,2C,AF,7F,2F,92,17,A3,B0,C2,F7,E5,33,EB,90,9F,6C,9E,1A,FF,FF,D4,92,28,6B,F7,45,88,03,99,5D,CA,6A,78,29,E1,DE,3C,00,34,77,AA,09,42,02,BB,BF,82,7A,B8,0D,6B,42,D1,97,D8,BF,0F,54,E2,5C,69,36,28,1B,CF,4D,43,C6,00,B9,6C,68,BE,7B,CD,E1,CA,86,F8,A8,DB,E1,99,57,B8,DD,66,AD,7A,2B,20,2D,8E,A8,2E,71,87,3E,2D,B4,15,72,66,34,C4,34,B5,65,19,60,1B,8C,BF,8D,52,BA,CC,F8,5F,D6,B6,C2,8E,3C,8E,E9,E0,80,3F,2C,97,FC,4B,75,9B,DF,5C,D4,89,A2,01,03,D3,0A,F2,7B,5E,39,E1,2F,7B,AD,A5,75,CC,BE,92,67,C6,75,98,A9,A0,9D,3F,45,EE,79,DD,A9,6B,F9,E9,4D,A0,12,02,3C,68,85,5B,D3,0F,74,3D,74,29,E2,F3,EA,15,06,8E,6F,AC,9C,D6,62,8C,84,98,FB,F6,8A,73,07,2E,C0,C7,6A,64,AE,B3,63,A1,B9,36,B4,01,0C,6E,F8,F3,77,AE,DF,95,0E,85,E5,2E,CC,23,D9,AE,0A,C2,12,DC,1F,E1,0F,80,99,70,60,11,28,DA,AA,C6,0A,EE,60,64,93,28,E2,3C,BC,57,B8,05,5B,4B,C1,EB,CD,BB,8E,37,9A,00,67,6B,5D,C1,13,D5,9D,66,17,44,E5,82,A5,6A,F8,E0,7A,69,50,5F,37,88,C9,62,8A,26,C6,ED,85,D4,F7,57,64,52,CD,70,1B,D3,C9,AE,78,A3,F6,3F,FC,D7,65,2D,A4,FF,86,35,66,50,0D,5A,63,F0,36,EF,AB,E2,86,5D,78,67,2F,94,93,B9,08,D8,AB,63,38,CA,55,CC,AF,6C,8B,F3,9B,D1,18,22,59,41,2C,4A,13,C6,90,46,21,F0,13,27,42,23,31,D3,DE,1C,0B,0C,70,02,31,C1,48,29,53,13,81,79,DB,97,DE,B1,ED,F7,96,7A,06,54,7E,54,37,B2,49,26,1A,9A,22,2B,EC,FE,4C,2B,AB,38,A3,3C,54,5A,38,98,04,2A,9E,29,B5,25,4E,67,F9,30,72,70,31,B0,11,C0,86,22,59,DA,02,27,4B,7B,E8,08,83,53,D4,A8,F1,1C,E1,00,7E,6B,61,34,65,2F,FE,A8,9B,71,B7,3A,39,42,F6,A0,6C,83,58,F6,96,06,A4,1A,79,7F,CF,A2,26,90,05,16,53,04,B0,29,30,52,21,1C,41,4A,77,9A,2F,C9,6C,69,AE,05,73,46,96,F5,FA,C2,D4,13,8F,09,29,82,33,5C,3B,4A,0D,41,F2,2A,BC,E0,02,F1,33,7E,B3,26,5E,F8,A6,29,A4,F8,C0,C2,68,73,64,90,1F,F0,53,43,2E,F4,72,D7,E8,3C,9F,B0,2E,82,E3,96,76,DE,D4,50,6B,CF,1C,CC,CA,25,98,67,36,F5,2F,0D,FE,FA,10,C2,1C,80,DD,EA,70,A4,DB,A2,42,53,8E,6D,32,30,32,10,3D,9D,64,79,2D,6C,96,A4,E9,B1,4E,96,1D,7A,EF,2A,EE,EC,B0,71,57,5B,D7,8C,FD,02,78,41,7C,E7,14,B7,21,4C,42,88,6A,8A,EA,C3,33,E5,3F,E3,70,D2,0A,B1,D5,E3,BC,5B,FF,25,94,55,51,1D,2C,52,6A,3A,B2,78,2E,78,0C,A9,8C,EA,1C,C0,34,CD,31,A7,71,06,85,82,22,66,BB,FC,88,05,5E,29,BE,96,99,89,68,B6,64,BA,E6,20,DD,98,A3,2C,3F,B2,5E,5B,D7,AB,5C,CE,1B,A5,71,FA,56,19,FA,AB,4C,48,D2,43,7C,2D,1F,9D,14,48,CA,46,8A,D1,F0,D9,84,D0,60,B3,F3,49,AB,F1,1F,64,B1,94,A4,E5,7C,16,00,07,72,11,2B,D0,08,E9,EF,1C,55,F7,54,A1,78,5A,97,38,31,5A,9E,34,19,E8,FE,2A,51,BB,F9,2B,F2,94,EB,6F,47,04,54,52,88,1B,35,6E,CE,99,F9,71,91,9C,64,CC,F9,84,80,3C,26,16,BC,C7,73,99,E7,25,1B,CC,F2,1D,99,F1,47,BC,77,16,90,2A,3D,32,1D,A5,3C,26,D8,06,6F,0F,D9,0C,CF,F5,34,99,4E,92,34,51,5B,22,1B,E8,17,AA,D9,0E,23,42,4A,44,D1,37,1E,4B,63,FF,97,EB,DE,CA,27,D2,05,65,48,17,46,15,B5,56,68,E5,3A,23,3A,AA,71,BB,49,F9,87,BD,F2,9E,61,A0,7D,CB,28,2D,2B,70,0F,5D,8E,D9,A4,93,BA,AA,68,58,31,53,43,96,66,60,C7,FA,EC,6E,CD,50,72,7E,8B,FE,E6,36,50,80,FA,42,52,43,16,9D,C3,08,3B,94,E1,08,E0,0F,2C,E4,A4,F3,87,89,A7,5E,06,E6,2E,39,27,E4,74,AD,BB,55,1A,5F,7C,89,EE,8A,B3,CF,70,44,3B,A0,9B,DC,76,7F,92,F5,A3,12,50,C2,37,95,A5,A7,24,E3,CC,90,12,33,E6,EE,05,9A,B2,A9,CA,B9,FE,AA,AC,BF,F4,78,B9,17,A7,66,23,47,9C,25,A2,86,08,8B,44,F6,9B,BE,D9,A0,EC,E5,48,0D,6E,FB,36,14,4A,48,1A,DF,23,6B,0F,FB,BE,DF,17,E7,12,F4,DE,98,B9,94,79,9F,A9,99,01,9E,D8,BA,21,EB,97,F1,CD,C5,24,88,AF,71,9B,FB,05,26,42,E5,7A,A6,45,F8,4C,89,D9,BE,1B,89,14,04,60,EB,14,BF,C3,5D,9D,1F,63,05,02,90,BA,25,07,4F,88,A1,AB,22,E8,2F,5B,96,9A,A0,1D,0C,4C,19,FB,54,7D,45,70,29,1D,35,B5,B6,12,79,5D,97,D9,91,11,78,64,87,B8,9D,CB,59,17,DD,22,27,CF,6A,5E,53,A4,E4,26,A7,C0,36,F6,92,63,34,CF,03,FD,C8,39,CC,92,FE,A4,7B,EC,8A,C2,16,44,26,34,D0,0A,96,D6,C5,F6,1D,12,2E,48,82,6C,74,63,2D,07,3F,50,F7,58,35,56,4F,F3,8B,52,55,2C,5A,EC,04,90,48,C1,D0,1D,16,39,E3,8D,A0,64,CA,3E,94,51,B6,8D,95,2B,CC,3D,15,0E,1C,82,49,FB,7C,1E,72,94,28,4C,09,84,51,BF,52,87,BC,D1,29,05,EB,09,9D,FF,E0,76,D4,2B,36,7B,70,EB,AF,46,2D,08,CC,4C,42,4E,AE,73,B1,A5,AF,74,1B,D1,B4,DD,D9,59,A8,EE,27,99,27,65,D9,E0,FD,6A,65,14,F6,FD,8E,14,66,FD,AC,71,02,DD,A3,56,CE,75,47,15,49,BA,0E,88,3C,54,74,AA,52,DE,36,8D,6E,B5,AC,E9,98,CB,14,B3,7E,C3,59,E9,60,BE,B2,B1,5E,09,59,6E,DF,E5,42,57,E7,C2,46,B8,E2,6A,05,B2,D3,68,83,4E,13,1B,36,41,C2,F7,DB,A6,60,6C,E5,78,31,0A,85,54,9A,68,9F,44,20,05,52,33,4D,F6,B2,7E,E7,1C,DD,8E,35,CE,73,E1,0B,E0,4D,EB,90,D2,10,10,21,E8,1C,9A,A4,A1,BE,BB,8E,34,DF,54,3F,92,32,62,E6,B9,E7,CF,A1,92,C8,F1,29,1E,D2,8F,FA,7F,FB,2E,5A,DD,AB,48,CE,C9,3F,54,C1,1C,7F,1E,6F,BD,19,47,46,C1,BB,3B,FF,4A,F3,59,DD,4A,30,A7,4E,69,C0,E1,AF,CA,A6,D2,14,EE,F1,2F,9F,60,22,91,51,65,8A,1C,2D,CE,DF,4B,CB,21,B9,9D,FD,73,22,CB,14,F6,19,F9,B4,1F,F4,D1,8C,46,59,BC,37,CD,64,3B,D2,45,F4,6C,1E,06,8B,03,CA,6E,04,6A,32,C2,44,36,6E,8F,26,6C,1B,70,51,CD,0F,39,B6,2B,DA,49,72,E2,EE,A2,CF,46,74,94,B0,7F,B4,36,71,20,98,3E,23,A7,AB,03,14,48,2A,4E,1E,8B,0E,29,12,8A,43,0B,B4,8B,F4,70,80,9D,70,EC,6B,DB,C7,9D,6D,C7,72,64,86,5D,52,D2,BC,76,96,50,45,86,3F,E1,3D,C2,8F,69,9E,88,AA,5C,B8,25,24,9B,E0,B2,61,EC,9E,98,8F,D5,CB,04,C8,CD,66,C1,90,AB,AF,0E,BC,7E,30,51,83,8B,7A,88,D6,84,61,2F,D5,25,8C,97,1E,FE,51,B5,47,A3,AC,35,15,77,E3,87,40,52,EE,41,A6,73,D3,5A,98,9A,79,05,95,A3,92,14,9E,48,1D,8F,CE,78,7D,5E,A6,42,D0,CC,B2,8F,DA,CE,E0,16,94,31,40,4E,EA,0B,6C,77,7F,11,D7,E1,70,9A,E2,60,43,94,AA,43,A1,EB,54,7B,E3,9C,E3,BA,E0,7A,71,88,03,4F,B2,BE,BB,6B,4F,80,2F,7F,47,B2,EB,10,7C,EB,A3,C4,27,6A,41,EF,49,27,1D,D0,87,15,91,44,28,A3,D5,8F,83,A1,B9,22,CA,59,D8,E8,CA,1F,EC,4B,DA,1B,4C,29,59,FB,77,44,88,6F,FF,5B,08,4E,E3,18,9F,35,1A,05,F1,5D,D1,40,26,9B,66,35,11,FC,25,AD,30,7A,97,2B,7C,36,1A,35,76,36,62,BE,D5,E6,4E,81,16,D3,AC,F4,C9,25,B1,4C,89,5F,9D,D3,47,FC,B3,1E,C9,9C,55,82,38,C5,CC,E3,01,0F,AD,56,E3,00,02,D0,02,CA,58,9B,59,29,20,DE,6F,1F,EE,0A,82,A2,B9,8D,59,BA,D2,8C,89,83,2E,1B,77,E2,40,8A,67,A7,9F,92,C2,2E,D3,2A,66,80,77,D3,C1,2E,89,99,91,34,38,27,69,10,B0,1F,5F,A6,2D,B0,6F,5A,FD,C4,5C,89,61,46,B0,D0,69,9E,B7,D2,73,7A,B6,C3,07,6B,70,5A,AB,70,20,F5,A8,F1,5E,9C,99,98,15,F5,D6,8A,FA,17,AD,AD,03,54,E0,49,8F,88,B6,2C,13,84,4F,9D,45,21,0B,EE,77,D3,6C,E6,D4,C5,99,3C,3B,FE,0B,07,E3,07,DD,8D,C7,C5,EE,1A,05,AD,15,F7,9E,6F,0F,A8,7E,55,2B,3F,E7,EB,70,C8,64,F4,D2,8F,A6,E9,0B,D9,21,8D,53,55,8C,66,42,2B,10,EF,ED,62,49,E3,28,57,2C,CE,AF,B9,B4,E0,00,8C,81,38,A0,9E,DF,25,58,43,56,10,B2,53,D0,7B,77,53,00,2A,90,C9,25,12,3B,92,88,BE,5D,77,9A,48,3B,A4,22,D8,8B,DC,05,F7,3F,9C,D0,6E,AB,6D,27,23,49,EA,AB,51,56,8A,82,79,FC,8E,09,18,D5,7E,2A,C4,BA,9C,49,00,BA,F2,52,48,C9,A2,60,85,1E,D3,3D,2F,69,BB,28,C7,18,68,E2,EB,3F,9C,EE,2E,58,E2,C7,8C,B8,B4,48,C1,AF,30,E2,6E,EB,4D,AC,96,FF,32,EA,4E,09,25,B6,5B,5D,67,72,62,2C,D0,D2,8B,30,63,2D,04,FA,C2,C8,10,9B,DB,63,A5,63,00,04,9A,A8,4C,A1,BC,80,79,69,C0,80,C6,02,C3,34,EE,97,D3,AA,9B,1C,F7,3C,D4,D3,94,78,51,2B,A3,2D,30,5E,69,D8,1D,92,F9,34,9C,74,FD,F8,A6,AB,BC,F9,42,62,F9,39,A4,11,DF,BD,7B,B4,4A,67,E6,72,16,74,44,5E,A4,04,F2,FE,45,19,84,1E,99,48,8C,8A,59,79,0A,0D,E7,57,89,2D,38,23,6C,80,1A,81,17,60,A2,C9,F8,FB,42,39,5F,10,29,BB,0F,66,3F,90,EF,86,D8,A0,D3,1B,3F,9D,08,55,28,58,16,18,84,E7,5A,67,8D,31,82,24,9F,29,14,A9,B7,B3,D8,D4,59,C3,35,C0,D0,06,4C,04,B9,B4,2B,61,44,1F,85,19,9D,34,11,6C,C5,48,05,29,F6,AF,8D,E8,25,17,95,55,75,EF,BA,CB,7E,41,D1,EE,6F,9B,72,19,44,A4,41,DF,4A,B1,D1,91,29,D4,25,44,72,05,EA,E6,09,71,4A,71,EB,02,2C,C2,31,0C,1A,0D,4F,B2,E7,4F,7A,27,2C,DA,2B,63,98,A1,7F,DF,A2,0D,0B,24,23,E4,66,82,83,63,E6,43,23,0B,0E,C6,3B,0F,B8,90,70,9E,B0,89,94,2C,C6,88,DB,96,CF,14,21,C0,62,EF,96,7D,67,94,86,0A,9A,3C,24,C0,42,1F,1A,80,91,6B,A4,E9,77,5E,2F,2A,DD,1E,57,29,19,4A,ED,52,C9,93,B2,9F,E8,3B,69,20,E4,04,E3,E2,89,6F,7B,40,54,3E,B7,6A,E2,BA,77,15,53,CC,80,5C,F1,44,56,96,6C,7B,18,F1,8D,EC,A2,F3,C7,7C,6B,7F,87,44,1A,82,6B,F1,A9,9C,D7,5E,FF,30,99,80,D7,CD,FD,EA,64,EF,24,FE,66,C1,30,C3,F7,A2,D4,8D,D1,DD,E0,9A,3E,F1,B8,87,76,AF,FF,61,DF,38,10,09,E3,36,76,24,DF,9D,BC,9C,16,1D,D8,08,B0,45,90,EA,3A,1D,83,D8,58,77,4D,B9,B6,2F,95,71,7B,FF,1F,5D,A2,6C,90,1C,B3,58,B1,3A,4E,40,81,BE,52,FB,9D,9E,46,D2,D4,02,A1,AB,C9,0B,90,C9,3C,13,0A,58,AC,74,BA,11,9C,02,75,CE,84,D2,D1,17,B1,3B,BA,BD,84,6E,46,84,1D,EE,9C,F2,E8,93,F1,91,19,1A,5B,DC,F0,C3,69,6E,B0,DC,8A,F7,82,0A,BF,6D,D0,6D,9C,52,D4,DD,DC,D8,38,21,C7,F2,64,7A,35,0D,69,B0,D9,73,A7,4F,AE,E5,60,72,EC,DE,26,CC,1A,76,76,91,2B,5D,9D,5E,42,57,42,27,E7,F8,98,B4,DE,FA,68,60,1C,FA,B1,D6,E4,5D,C6,00,18,81,85,62,77,ED,A9,D5,03,F3,DD,64,CC,16,53,41,45,0D,45,A2,27,C7,47,50,AE,16,B8,55,5B,7A,03,F7,F2,60,23,A8,96,86,7A,4A,4F,EF,31,B1,66,55,74,65,C8,70,DB,31,E8,9D,2D,E6,B6,01,AD,FF,09,82,DB,E7,0B,12,6E,E4,1A,5C,0E,5F,66,BB,13,09,40,68,AD,60,92,F1,90,21,A1,4F,F0,FE,DE,7E,21,52,41,15,20,1A,EA,4C,CE,CC,E5,A4,41,B0,BC,22,9C,7D,0D,72,52,D9,5E,3D,F5,76,CF,8A,D7,82,2B,7D,26,AE,04,5F,B3,52,FC,C6,80,4C,6E,F4,7E,DB,45,B2,53,5A,A9,84,72,B2,D8,BD,29,CE,A6,C7,39,E8,92,01,CA,39,19,14,3B,AC,97,74,BD,3C,D9,85,EA,5D,CF,58,69,31,EB,13,A2,EF,C5,8E,88,94,D7,39,A9,21,05,05,D2,0F,A7,9A,11,C8,D7,AE,26,CA,92,8B,DC,1C,A3,1B,62,90,ED,F9,C8,6B,EA,FB,3B,FB,A7,59,7F,B8,AF,44,37,EC,A2,2A,16,18,34,01,7C,A8,70,14,0E,D7,02,0A,67,FC,05,46,7D,C6,D6,29,CD,78,0A,61,00,48,FE,EB,65,7A,F2,A5,03,B4,5F,37,F0,03,21,AB,57,A0,B5,B3,9A,39,88,27,AF,DD,0F,80,BB,E9,1A,5F,A7,BE,E6,C5,AE,31,96,C3,2E,C4,FE,78,89,5B,8D,28,5F,24,0E,6A,D4,56,87,CD,49,D2,DA,12,B8,2E,EB,72,8B,EF,AB,48,B0,20,FB,1E,06,0A,41,4E,1A,9B,85,F2,7A,C4,7F,5C,13,45,27,54,D5,E2,C0,D6,27,AD,FC,44,4E,00,74,31,1D,B5,A8,BA,49,18,F1,8A,9C,F7,9E,C8,6F,0B,B7,9A,90,0C,B9,C9,1B,B7,4F,EA,06,8E,65,23,B9,63,BB,F3,F3,E6,E5,22,2E,92,30,AC,31,71,AA,6B,18,16,09,67,32,A2,C9,E1,2D,89,66,1E,43,E7,D2,67,3D,FD,EB,C3,C9,50,30,DD,62,D3,D5,7E,7B,67,2D,AB,77,27,B6,12,BC,05,F4,73,A6,00,E6,7C,1A,FB,05,1B,AC,97,28,15,26,28,51,C9,3E,BC,18,B7,3E,2B,6B,72,79,5D,9E,F5,FA,D3,CF,CC,67,77,30,B3,B5,C5,FE,D5,9F,31,47,84,12,81,17,22,16,DD,8A,62,8A,72,AA,DB,EF,6E,B2,82,1D,11,46,A0,70,6B,93,8C,6A,86,C8,D3,EA,60,D0,0C,57,96,44,D2,20,51,FD,C8,6E,BE,65,52,FE,DF,12,82,8E,0B,63,3B,AE,7D,8D,87,90,AB,81,09,A7,CA,4C,A1,5E,4D,F8,D2,B6,70,70,A1,41,76,68,B1,6F,0E,9F,61,5F,E1,AC,F3,45,33,DC,A6,75,CD,16,CD,FA,23,73,6B,A7,97,23,68,3D,D4,A7,B2,27,E3,BC,54,BD,95,FF,9B,72,E1,41,98,89,40,8D,D4,17,F8,67,A5,8D,E2,B7,BD,9B,29,BB,4A,D3,18,69,F2,CC,28,CD,44,97,6D,54,85,30,41,05,F8,A9,09,F5,D8,61,15,AC,53,AA,34,4E,D8,31,4A,51,18,38,B7,53,5A,7C,CE,4B,3B,66,1D,58,4C,34,5D,1C,03,EA,E3,C0,26,EA,76,27,98,89,58,97,82,AB,8E,FA,7D,05,BA,DD,A3,E3,6D,F9,13,C4,C9,EA,AB,D1,77,0A,AD,0B,C1,E3,62,40,DF,19,12,54,B5,9B,42,F8,95,86,8B,90,DE,D6,B3,26,31,80,02,A6,3B,DB,F6,E2,46,EC,85,B0,31,98,CA,50,90,F6,DA,C9,30,9C,17,16,3E,22,DC,A1,D7,FB,AE,FA,34,DC,C4,56,8C,68,EA,93,04,25,65,10,98,06,8D,FF,DA,9A,0E,84,68,88,00,A0,0D,13,77,4D,4D,42,CB,67,E5,9F,1A,28,34,5E,FB,65,67,59,95,3E,86,58,6B,9D,28,82,E8,8C,13,AF,FB,B2,DD,88,68,C1,1C,6B,5E,F8,29,03,D8,80,CC,25,A4,8A,C1,3D,69,3D,24,35,66,FA,FF,01,73,91,7D,32,D6,FA,BB,FD,D4,A7,FA,EA,BF,60,C0,7F,88,41,0E,55,7B,0B,F8,6C,0A,B3,A0,8E,00,4D,CA,D1,49,42,A3,88,7A,5C,F8,0C,CC,48,CF,67,15,F5,63,13,D0,C0,8F,08,9E,28,3D,42,E6,85,84,F4,93,18,06,AA,B7,61,11,39,86,BA,23,C7,2E,B9,F8,3F,3F,BA,80,DD,7D,70,BA,10,3E,66,27,BA,32,AA,69,53,F3,2C,87,69,E6,EC,78,F4,01,22,B1,1D,79,6A,DC,9B,0F,5C,D1,D0,A4,DF,6B,B2,F1,1A,50,AA,55,FD,7B,60,C5,2E,5D,5C,9B,92,1F,2D,F1,CD,50,35,02,5A,B0,32,35,9C,0D,40,1C,90,4A,AC,16,D2,BE,DA,10,57,93,C3,23,5B,64,8B,46,1B,33,67,85,55,6A,C9,73,03,27,FD,FB,A6,68,07,03,56,C6,C8,79,3F,07,F0,2B,0B,6A,FE,31,28,ED,FC,30,32,6A,0A,81,94,AD,23,B7,20,95,F0,D3,B7,C7,E6,DE,1D,3A,9E,E0,7D,B0,7E,C5,D6,5B,5A,C9,74,8B,9C,82,CF,33,B3,C2,9D,C4,8E,1D,6D,98,2A,B7,18,88,FD,2A,99,82,01,1E,80,46,7A,CA,E9,3D,77,C6,D9,6A,97,F1,4C,75,33,C3,E7,C4,3C,DB,0A,22,D1,F8,C5,85,AD,F7,49,21,22,3B,BA,45,EB,1D,BC,A5,07,4C,BA,FE,99,63,19,A1,EE,6E,3E,1F,B1,1D,C4,33,F2,01,B3,BB,05,D1,36,6F,B6,DA,6A,C9,04,9F,DA,34,1F,00,71,E5,C2,21,48,6A,5B,4B,B3,76,90,E5,EF,A0,B1,30,19,9D,59,D4,3A,C2,D2,16,39,D9,96,60,DC,F8,21,BF,F5,0F,8E,88,0F,1E,21,19,C3,A2,84,01,05,BA,B7,C0,9C,BD,82,5E,23,02,5B,5B,79,E1,D9,97,B8,86,34,D1,5F,B3,2C,25,4E,AC,D2,65,FD,63,1A,02,C6,1B,B6,A6,C1,52,EF,1F,1C,52,6A,F2,51,D6,96,66,32,E9,84,8F,59,51,78,B0,03,96,7A,12,92,F9,40,64,EF,23,ED,2C,E2,25,A0,24,3E,12,27,DB,2F,E6,D8,84,8E,61,10,E7,97,C3,DE,0A,DE,CD,66,93,2B,FF,F3,7D,70,E4,06,F3,92,86,DA,3D,7A,AC,0D,3B,21,99,46,CE,E3,3D,A8,C7,E4,6F,C0,84,DC,01,BB,62,E2,FD,E4,55,DE,8D,53,65,74,B9,5D,B9,31,65,CC,33,4D,C8,DB,9B,33,3C,3D,10,B9,F4,AA,58,41,32,93,51,13,2E,04,6A,F2,46,0D,F4,68,C4,A7,3F,53,59,1A,C7,27,FF,54,5F,F2,AD,92,6A,18,07,2A,43,8E,0A,A2,52,FA,FD,B3,17,50,1D,6A,37,21,B7,D3,16,10,B4,21,7D,83,10,37,CD,AA,C4,06,B9,FA,E6,11,21,83,7F,1B,03,BD,12,6E,4D,A0,24,26,08,14,BD,2A,56,68,D0,D2,16,73,0C,0E,CB,68,32,4B,96,4A,95,2C,16,67,15,62,C0,A1,AD,B2,10,83,9F,D5,8C,29,B7,90,A4,BB,39,F1,9C,48,E2,4A,71,EA,1C,3D,88,6A,56,60,16,0B,13,3E,99,17,EB,66,FE,82,37,A1,B6,9B,69,C2,68,C8,6F,C1,1F,7B,D8,65,C9,22,D2,A8,69,0D,CB,17,76,0C,F7,9D,83,86,C4,59,23,05,17,28,84,62,8C,03,3C,FD,86,A2,77,B7,04,B7,5C,3A,0E,98,CE,B9,09,5C,A9,4C,55,9D,46,6A,B9,55,0D,88,02,ED,5D,5B,DF,21,AA,0B,4B,CF,36,64,06,90,BA,71,42,A9,40,E8,59,1A,10,05,F5,C6,6F,8A,F4,FA,1B,28,09,52,58,20,3F,8C,43,0F,47,78,76,05,31,9F,8F,61,50,95,D7,30,89,2C,69,D3,B7,30,A1,0A,0E,36,F1,97,EA,A9,80,92,6A,11,7F,30,B4,09,FE,8E,B8,0C,99,F6,A7,1F,3A,06,03,B7,4E,F2,58,83,4F,F5,7E,C9,C2,F9,AD,36,5E,90,57,7F,ED,BB,CE,C2,DA,43,DD,1A,E8,A0,B9,67,CA,6D,AF,84,18,47,97,4F,B6,9B,AE,A2,75,04,DC,E9,1C,72,C6,5D,4A,53,2E,D0,41,00,32,7D,56,67,83,B8,E2,D2,38,1D,14,50,09,B9,81,62,3D,2B,B6,0F,DF,65,66,79,C1,46,EC,10,0F,EE,1C,B9,EA,4E,A3,3A,FC,1D,5B,F0,B8,31,82,33,23,D2,E6,3F,95,B6,C5,6E,65,A7,81,6B,F5,87,87,70,C7,E8,AD,30,B4,4E,25,07,63,DA,F9,33,6B,C8,0D,42,47,7D,73,B7,DD,09,D3,9E,96,56,74,A4,A3,9B,75,2A,33,23,F5,7D,75,A1,92,A5,4E,14,B0,ED,7C,50,1C,62,C4,5F,08,34,70,24,1E,35,5B,0F,3F,73,0C,98,35,CF,DA,8C,E2,60,7C,4A,BD,AB,5C,5A,12,9D,F0,7B,A0,24,02,AE,ED,5B,CB,B7,61,44,0F,37,75,BF,40,FC,46,CB,FA,DD,43,36,91,52,1B,5C,32,88,5A,CC,68,D3,C9,67,77,15,62,BF,F3,B6,5D,64,3B,E5,56,00,90,FD,DB,19,48,4A,AD,63,87,63,EC,C7,51,FE,F7,CB,10,33,08,96,B2,81,D0,62,1D,64,12,26,92,7A,8F,27,94,F3,8E,E3,EB,76,D8,66,3D,64,E7,1D,EC,FC,51,91,0B,D2,B8,D6,3B,06,FA,67,97,4A,02,40,D5,59,58,80,AB,DB,41,9E,A1,33,B6,CB,48,13,36,07,5B,99,A1,0B,DA,02,3F,4F,1F,C3,21,54,FA,CF,9C,13,16,77,47,1F,51,BE,94,F3,8C,C3,B3,24,C1,37,7F,FD,2B,6A,8E,3A,25,7C,DA,35,3E,22,F9,46,D0,02,6A,21,6E,E2,27,19,62,0B,04,1E,0A,03,99,5D,C5,9E,C5,F9,FC,97,00,6D,AB,A5,6D,A7,64,99,0A,D3,F6,09,5C,5C,8D,1E,5A,74,30,52,04,64,59,2B,D3,77,9A,52,86,3A,A3,93,F6,95,98,DD,63,76,B2,19,C1,6F,1E,C1,0B,22,5E,8A,B9,50,59,D7,28,23,B5,C2,0E,C1,31,95,5F,58,CC,02,98,3F,36,11,27,C6,51,1A,25,A1,23,0E,3F,60,C9,0F,24,77,D4,8B,75,BC,29,F9,A9,16,89,DE,30,6D,61,44,7F,84,D7,E0,5B,54,D4,55,4D,0B,11,52,73,15,9A,DB,A5,67,F6,90,85,9B,04,85,47,A9,6B,C4,BA,8C,71,88,18,5E,FB,0E,C8,F8,BD,7A,63,50,F2,3E,AB,1C,C9,14,74,B1,37,85,98,90,E2,53,4D,6C,52,86,0A,82,FA,39,43,E6,CF,CD,E0,7D,78,26,FC,03,D0,29,E0,58,9E,FE,0D,0E,1D,DA,04,01,45,B6,D0,40,92,A4,7C,08,C0,9B,B7,CB,ED,49,26,57,00,D3,8F,C5,F7,A6,A4,02,C7,18,D2,19,53,5B,AD,98,E8,35,33,32,6E,2A,26,7D,8E,08,65,13,86,30,CB,5A,C6,83,8E,BB,72,53,E1,C6,30,63,03,C0,91,7F,93,A7,1E,85,2A,A8,2E,C3,94,3E,07,45,BF,CA,7F,96,E3,5D,4A,A4,74,B1,DD,7B,C9,8B,F0,C9,AB,19,82,48,0E,91,35,BF,26,94,DC,37,13,CC,ED,4E,70,10,D3,A1,71,C6,82,A7,CF,BB,9D,E7,BC,3D,EA,07,31,A7,62,AB,F6,05,CC,A9,80,C8,02,75,14,79,61,3B,6A,EF,F8,78,64,6D,4E,AE,AC,1E,89,39,1F,0A,6B,5F,DE,55,B3,E8,A9,F0,9B,D6,00,7A,66,65,75,55,79,57,A8,2C,02,8C,1A,3F,20,D2,C3,99,C6,77,D1,9B,41,46,92,67,47,C5,2F,85,0F,AA,37,7C,33,39,20,8D,00,31,9D,25,B1,90,1C,93,2B,C7,EF,8D,33,B2,8C,B5,DD,8B,CE,91,EB,AE,26,E8,6F,88,DB,4B,3B,70,11,F0,C0,6D,14,4F,F8,16,8F,C6,D9,2F,0E,C6,8A,8B,F3,59,B6,F7,45,D2,21,E7,E5,92,83,C6,12,2A,0F,A3,6C,3D,3C,5A,C5,3D,47,9E,77,E5,06,10,F6,56,50,34,64,47,1A,AB,96,83,B3,80,98,4F,0F,AD,2A,8D,86,7C,16,B7,87,10,0C,13,16,19,3D,AB,92,05,5D,9E,98,CE,D8,3A,55,FE,8E,96,9C,95,CA,19,E1,28,36,2C,5F,C8,B7,44,35,C2,06,D4,41,3C,2B,07,99,2D,B7,E1,59,54,16,36,17,0C,8D,2A,3E,85,39,14,AB,40,FB,78,F3,66,FC,62,4B,D8,5B,B7,0D,8E,A4,E0,6A,06,E4,8B,68,34,34,FE,B6,AB,7F,55,12,94,6D,43,1C,31,CF,35,F9,B5,CC,DE,8A,0F,B8,A5,22,93,94,4D,13,B8,7B,42,F7,02,10,34,43,79,D9,18,FE,0E,F3,E2,EF,3F,8F,B3,65,49,54,C2,26,01,EE,E2,40,85,E7,96,43,D3,4D,31,C9,F3,42,EE,06,2D,D4,76,3D,8F,C1,9C,A5,EB,19,22,5F,1F,05,9A,8A,C9,25,16,AE,28,BB,FD,35,FE,03,0F,B0,44,97,78,6B,1A,58,8E,84,00,F7,D3,80,AB,3A,07,A5,EB,BF,33,E9,A5,45,64,19,B0,A9,D5,1A,42,32,C1,97,44,E6,EE,A9,67,E7,EF,2D,D8,70,47,A1,BD,90,34,88,85,F4,DD,D5,20,C9,EB,CC,43,E4,93,2E,39,47,7E,5C,57,58,15,FD,B3,2D,72,E7,4F,C4,F2,23,B7,C1,71,CF,1D,56,7C,13,C6,26,6B,9E,FC,B7,1D,A2,59,43,B3,02,2B,CF,21,26,10,BF,59,39,2A,FD,F7,23,0B,1A,C0,C0,0B,99,5D,BD,A9,31,9A,58,57,0C,B8,F7,0B,45,7B,9E,0C,16,6E,2D,B9,C4,FF,C8,31,34,72,B0,9A,55,AB,CA,3C,E6,26,99,2D,E3,4D,96,43,49,E9,92,E7,FE,52,3F,79,AD,EA,87,52,9D,C0,52,A4,59,2D,E0,27,63,36,9E,F0,F4,16,3C,C7,11,C3,68,26,EA,CD,11,62,6C,27,D4,3E,DA,73,6B,FB,4A,FB,BF,23,B0,13,61,B6,27,8A,BF,51,A5,11,5F,61,25,10,22,E2,06,15,07,51,95,7D,B7,E4,5D,A8,54,61,44,98,34,9C,92,17,A6,41,BA,BA,83,0C,C1,31,40,7F,18,4D,77,44,39,E4,F8,76,DA,22,14,36,0B,60,8D,A9,75,60,79,1F,D4,26,33,EE,0C,C4,D3,45,F7,C2,CB,2A,1E,67,63,1C,20,B8,34,15,ED,F6,03,6F,42,CB,F0,5F,91,31,A7,79,0B,F9,2D,96,E2,48,23,85,A4,0D,A8,57,80,1D,9C,13,65,9A,31,6D,B6,23,4C,58,35,B5,D6,47,F5,C2,00,86,E9,19,47,1E,F2,BD,89,8C,ED,09,61,0E,90,45,C6,81,C4,C3,54,57,29,4A,A8,DC,21,D3,6E,4A,C5,5E,BD,55,3C,14,5A,B0,75,32,48,57,BF,2A,C1,19,E4,2F,6D,75,F7,7C,0F,75,F2,5E,53,2C,21,B2,4B,32,2F,A4,E4,C8,DC,97,BB,72,A1,8B,E5,28,92,96,43,82,6D,79,D2,81,F9,FB,8D,01,3F,D3,93,C0,4C,25,A2,72,D2,92,25,B8,A2,8B,84,0C,64,6C,18,9C,14,1B,AD,F3,BC,7D,D5,C4,7E,62,3E,48,5A,0B,C2,6A,17,31,4E,79,E2,65,D0,7E,17,10,EC,54,05,2E,AB,06,2F,70,B4,71,6F,C1,FE,BB,59,20,FE,36,FC,AF,0D,F0,74,66,3B,ED,C4,20,79,FD,C2,7A,74,68,20,C7,5E,EE,59,68,4A,46,14,71,F6,45,9B,0C,5B,FE,56,D3,AF,43,11,AB,B2,91,43,35,80,7E,E0,AA,9A,82,9A,6D,95,77,78,60,82,67,BE,1D,07,E6,0E,E2,0E,3B,E2,23,1E,5F,64,04,CE,A9,23,31,53,FA,EE,AD,FB,5D,71,91,08,1E,44,A9,38,7B,8B,34,48,4F,51,BF,F7,B3,18,44,06,45,60,86,B9,CD,02,C4,3D,73,F9,0F,FC,41,EF,C5,CA,4F,5A,A1,BD,61,78,4A,DF,56,71,8B,EE,5B,6F,40,B0,E6,DC,FB,71,B5,2E,5F,61,25,2A,36,7B,79,A6,DD,A6,31,EB,88,26,55,AE,BC,5F,65,9E,EA,2B,DA,AC,60,23,A5,5F,22,09,45,6B,29,D1,56,DC,E5,9B,53,29,41,46,C3,70,0B,46,2A,7A,7B,9C,56,E6,9E,2A,A1,A4,17,B8,5B,71,FD,04,CD,13,90,7F,88,67,90,1F,68,3F,A4,DA,74,C8,4F,D0,DC,BD,07,D5,1D,50,27,2F,15,42,6B,CA,DC,75,08,91,58,8C,23,48,94,C3,24,25,6D,DA,16,87,63,43,94,C4,7B,F2,E6,07,1F,8E,A5,6E,35,3B,6E,90,F4,2D,61,B6,3B,DE,AE,6B,11,B1,40,E8,03,90,03,D6,4B,1E,87,11,C9,37,53,7A,4B,4B,01,38,13,BC,18,EC,E4,8B,5F,4E,7D,6B,96,BE,3C,1B,E4,29,4A,C9,75,09,19,EB,96,A1,F4,BA,CF,38,0C,C4,5A,3F,55,70,FA,F7,C1,FF,DD,2A,76,57,F1,1C,B7,41,38,C7,A5,89,AA,5B,71,80,8C,52,F0,D2,A6,0D,51,6F,F9,AB,1C,A3,19,E4,B7,FD,93,8A,87,F7,2D,B2,5F,98,F6,CF,98,78,55,FF,31,2D,EC,15,F0,D7,3F,CC,1F,C8,D8,C8,9B,F5,0A,A2,E1,58,6A,FC,99,B1,A8,D0,A2,5A,FF,E4,82,E4,5C,78,B6,9B,DD,58,5C,86,87,73,30,61,CD,DD,8F,66,D4,23,C4,20,F0,67,EB,95,F6,26,FD,09,E6,C5,23,BB,40,3F,A4,8E,80,68,26,AF,54,0E,58,7B,28,04,E4,E3,EC,17,80,83,75,9C,FF,84,AB,26,B1,76,88,DC,67,D8,B4,7F,77,08,14,6D,EC,C8,13,25,68,E9,5F,3A,BE,FE,B0,30,98,1D,5F,5B,E6,D0,AD,81,2C,76,59,B5,3E,A4,BF,05,08,51,9D,74,4F,17,79,A6,B7,40,AC,9E,C8,6E,6B,83,0F,55,82,16,A9,6E,9E,3B,63,4F,74,9F,74,D0,94,F9,4E,AE,DC,69,D0,BE,D1,1F,20,52,07,4C,0C,93,0D,29,BA,A0,F3,F6,14,7D,44,E0,42,23,8B,0F,A4,99,67,CD,D4,13,3C,F0,21,20,70,76,EC,33,7F,B0,E2,B3,59,93,3B,07,F4,93,E3,7E,3F,6E,49,C6,D9,46,70,DB,79,97,F2,6B,D2,93,67,5C,91,B9,5C,BD,16,F2,49,AC,E3,13,D5,36,EC,7F,68,3D,14,13,52,C8,5E,62,51,1D,C5,22,77,E4,A3,61,09,E3,82,E4,A9,CA,91,31,F3,3D,B6,2C,BC,AF,AE,4E,E5,BC,F1,43,E6,2B,CE,FD,18,C0,1C,9E,FA,84,9E,8F,06,5C,D0,24,79,A2,88,E3,B3,6F,5D,D2,6D,7F,71,1A,A0,8E,4C,19,8F,D4,F0,C7,54,72,53,B2,A3,E6,36,F8,9F,1F,80,0B,95,28,FC,D5,AA,2F,97,D5,7E,83,8B,6E,98,12,C5,24,AC,F3,9D,4C,AE,D2,2B,50,03,58,95,85,02,CA,AC,F0,0E,1D,E9,7C,57,28,B7,48,37,10,80,A8,17,0B,21,7D,2B,BF,6C,FF,5E,A7,91,6C,AF,C0,74,E3,85,85,36,F2,3C,6D,1C,1D,66,93,B3,63,1E,B9,1A,A1,96,D1,DA,76,64,16,66,94,0B,94,E4,29,C6,9E,C9,85,53,5C,B2,D8,68,8F,43,4A,F1,19,F2,C8,28,18,3C,12,8E,38,BE,9F,F6,41,FF,0B,06,F2,B9,18,DF,7D,41,C5,1C,54,17,62,16,8A,00,92,32,18,D7,FC,5F,05,83,CF,4F,C8,13,0C,DF,55,7F,96,21,B2,54,22,CE,2E,01,28,B6,79,56,23,9E,21,9A,38,99,3F,88,2A,43,6B,79,B9,4E,63,92,9F,AE,C1,F0,AF,D0,21,71,5B,85,17,09,A6,6C,02,92,96,89,64,EF,1A,E5,F9,10,2E,CC,46,27,53,A0,A3,A9,15,C6,53,74,2E,FA,4C,38,2D,6F,A6,5D,C9,26,77,08,9F,15,90,FA,9E,61,0C,8D,B0,95,E8,40,2D,98,13,2C,6B,AD,C1,FC,C6,40,4E,FA,5C,9C,64,6F,15,A8,79,7A,9F,D8,77,FB,9B,19,11,B6,AA,8E,31,3B,6B,B5,0A,F9,87,52,70,43,EC,07,06,0F,DC,B8,A0,24,7B,99,F0,18,30,D3,B5,FC,BB,4E,C9,7A,88,A8,FB,5A,83,F8,F3,3A,D4,3E,16,84,F8,5D,63,F8,6D,B2,A1,F3,1E,67,F2,A1,55,59,1B,10,10,49,8B,E1,6A,67,4D,BF,FD,46,B9,24,0F,B1,71,81,AD,D1,2C,D0,DE,7E,38,CF,99,94,4E,7B,2A,8E,E9,9A,F5,D2,F0,D5,D8,44,88,AB,AA,13,F8,7F,50,57,82,AF,9E,6C,24,29,D7,4B,B6,B4,FC,CD,6C,D3,03,FA,46,56,56,6D,2C,70,40,2F,2F,2A,02,EB,69,35,10,7D,D9,A9,93,92,C6,CA,8C,C2,CE,F5,1A,77,16,53,37,9C,46,BB,63,28,31,20,B9,5C,97,F4,53,87,6E,71,A5,CB,59,27,F9,AF,5B,54,AF,75,E1,79,85,07,6B,2A,E0,B7,FC,7E,B6,EA,D4,94,42,39,BE,9E,CD,AA,78,66,FB,22,9E,3B,8E,88,A2,84,B5,5F,62,E4,51,28,A4,93,1C,C2,A3,5D,2E,34,F2,E8,E8,9A,61,94,0E,B7,C1,46,00,FE,E0,CF,05,30,81,BB,7B,3D,49,A6,D0,BC,72,29,9F,D9,22,D1,CF,31,D9,7C,A6,1F,D4,9A,2D,51,A9,DB,8B,E2,65,16,3B,FF,0A,AA,81,DD,9A,FD,ED,33,CD,D6,83,E9,C5,FD,C8,1F,3E,ED,00,02,F8,5F,7C,7F,34,3C,6C,1E,13,AF,E3,56,9D,7B,9B,5B,72,1F,8F,28,8F,56,0E,CF,53,07,5B,31,6B,0E,32,F2,5B,1E,7D,C8,D0,22,BA,7E,1E,4E,4F,4F,F7,BC,41,85,05,C0,11,F9,ED,7E,9B,53,48,F9,93,3C,A9,00,2C,8A,6F,39,59,9F,FB,C6,20,03,4D,98,11,DA,4C,E0,B7,60,F9,6C,BB,DB,B2,46,6B,5D,B8,9F,8B,B7,80,4D,6D,5B,65,7D,EC,00,96,1F,CA,58,81,65,4A,44,3E,E0,57,91,1E,F1,E0,9F,B5,FC,37,18,15,BB,51,C6,2D,2B,54,4D,C8,E8,09,61,42,6F,DF,61,90,BE,C4,83,1C,51,E5,B1,1D,EA,D7,42,E3,9C,15,01,D0,57,86,2B,50,C8,D9,81,33,A6,AD,D7,5F,55,80,E9,49,BC,D2,49,F3,65,8D,FA,50,33,02,E7,A0,7A,76,94,69,17,F6,0D,52,B0,CE,08,81,0A,1B,23,04,C1,07,BD,36,A8,66,8F,EF,D8,AB,6F,F1,9E,B5,90,38,3D,65,12,FF,05,04,0F,8F,F0,28,3C,FE,54,6C,32,C2,B4,14,64,17,22,CA,11,41,46,C6,27,ED,DE,4E,18,55,BF,97,90,E1,81,EE,D2,3B,DF,AE,01,D4,C9,F5,E0,72,52,23,20,1C,F7,FB,2F,71,FE,6B,52,AB,BB,A1,F1,87,46,74,CF,6D,00,C4,C9,28,AE,5A,FF,61,35,40,BC,89,2A,51,12,52,8A,69,4A,EF,8F,20,19,72,D8,E1,C7,53,3D,D1,96,29,6B,6F,ED,F9,69,CF,F2,AC,5B,00,ED,00,0B,0F,7B,E6,FE,5D,95,78,79,AE,4B,D0,11,8A,FA,44,15,34,AD,E6,E9,C3,5D,6F,7F,81,E0,9C,56,FB,A8,0E,46,96,9B,50,8E,57,55,CB,DE,F0,BE,6F,5E,F8,8C,C6,77,9D,53,83,3A,46,7E,83,24,9C,F9,9C,10,B3,46,BE,72,B2,CD,6C,0B,8F,73,4D,75,F3,8A,84,40,94,5A,F7,46,21,2F,2D,DA,C2,67,42,A4,63,27,AA,73,77,54,93,A7,7F,51,A0,08,E1,C0,4E,B3,5F,9C,57,C4,A3,CE,25,5E,25,BD,CB,2A,D0,BC,F4,A3,48,4A,5D,56,46,F4,DC,C7,D1,F1,E0,B0,75,56,F1,14,31,6B,35,BD,58,76,21,0C,26,77,25,19,28,7D,C1,AB,B0,EF,24,AE,AE,AA,7F,5D,48,23,F2,D5,89,70,6B,D4,F3,7A,A5,66,67,33,D1,06,C0,E4,B0,FB,05,0D,67,CE,7A,A6,C7,BF,0F,62,10,7F,F9,55,81,0A,32,F7,CC,12,60,E7,CE,C3,1A,3F,32,8E,19,36,FB,EB,45,E0,FE,53,45,97,35,87,D6,BE,D5,07,FA,B0,5A,E5,16,38,91,6C,71,B5,B4,31,13,62,E6,8A,75,3F,08,A6,C0,42,F5,23,A0,E9,93,D9,39,B8,64,B5,EA,DC,FC,AF,16,10,0D,40,85,90,24,E5,95,A6,F8,E7,B9,E5,BA,F2,3F,D4,93,A4,6F,4A,E6,CD,67,74,49,74,46,83,4D,3B,4F,6B,76,F9,55,AD,50,DD,E8,48,13,D4,6E,96,1C,71,B6,AB,DC,B7,97,E5,67,07,DE,12,4C,94,BF,B0,96,DD,CA,BE,9F,4D,83,B4,01,06,A0,9B,9C,E7,45,29,D7,35,BE,DF,A9,95,01,1C,1B,58,8D,33,0B,3B,B5,6D,EE,34,FC,89,BD,AB,F7,30,70,69,27,D8,14,A2,32,52,3D,EE,11,0F,62,D9,F0,72,2C,2D,EC,DB,94,55,03,F6,E6,2E,38,6F,66,15,95,E6,DE,B2,82,8A,9E,96,88,39,32,E1,EA,0F,07,1B,78,F2,5A,C6,A6,2A,B2,E5,A2,56,29,C2,B9,E3,F0,88,96,E4,57,E6,D2,75,83,81,36,5F,3C,CC,B6,E6,61,D1,96,10,A4,82,BF,81,B6,47,4D,B8,55,7C,F6,00,C7,0C,35,FD,60,D3,36,F8,80,AD,EE,00,68,7D,A5,19,AE,DE,00,F2,B6,76,C3,DB,F4,7A,D8,D0,FD,EC,08,16,EC,02,06,76,A0,45,D3,72,05,B5,8F,62,E2,45,98,C0,C1,09,C9,AE,E6,C0,33,55,A2,4A,1E,20,BC,EC,01,9D,7A,FA,E1,52,7B,9E,EC,14,2C,AF,41,FF,92,BA,27,70,2A,57,4D,66,5E,1C,02,5D,83,16,08,6C,6C,69,A5,07,CA,CC,28,04,3C,D0,74,41,63,2C,97,B4,E0,2D,CA,80,FD,4D,50,D8,91,5A,81,0D,85,86,52,64,90,5C,50,C9,34,FA,F4,EB,36,7E,D9,F2,7F,6C,DB,1B,AD,06,30,D3,C6,D3,09,70,71,C5,1D,55,D5,04,05,9B,E8,EF,97,9E,62,44,76,6F,82,D6,71,C1,BC,D9,3F,AA,89,83,1A,A5,14,40,CE,EE,AA,35,28,B5,00,A7,27,F6,ED,35,4A,2E,58,60,81,9D,EF,0E,78,BD,2D,50,38,D3,20,8E,80,4D,36,BA,CD,50,59,FA,0F,FC,CC,40,D2,88,69,70,63,FC,4B,D1,11,22,CE,63,2A,BE,B5,23,54,F5,CE,22,C1,8A,AD,87,75,14,6A,C5,61,25,BD,6F,C1,A2,85,06,26,A9,1B,86,77,83,4F,9C,54,C5,32,FE,05,2B,9C,AB,C0,02,AA,2D,84,BE,4B,C0,06,3A,98,FE,47,A2,1D,32,11,CC,45,B0,99,A9,B1,33,67,18,A2,0C,39,FE,B9,32,96,4E,EE,24,54,6F,F7,00,DB,18,53,2A,EB,B7,B3,B0,D8,5D,FE,3E,7E,F3,69,DF,57,58,18,C1,75,A8,52,3E,29,5A,B3,E2,8A,A9,1D,E5,2F,B1,9E,01,3C,76,D8,3E,25,35,1A,17,F0,10,66,B9,CA,84,99,ED,D9,75,9D,1E,44,B3,19,15,E6,FB,88,43,96,AE,74,90,54,8C,7D,C0,D7,C1,10,03,CF,93,C4,F5,BF,13,06,81,D0,79,5C,75,67,FB,CB,D2,29,CC,4E,2F,11,8C,E8,FC,FE,80,7F,3F,BE,67,CF,75,8F,EC,8A,AB,26,38,B8,A1,E1,AD,B3,F1,BA,46,F1,F5,DD,63,A9,49,C8,91,DA,9D,CD,02,74,F7,AA,08,9F,60,39,A2,EF,94,30,D0,60,EA,D7,19,22,AE,CC,88,F2,BA,CC,40,1E,AB,CE,F0,2B,53,A4,9A,BC,C2,18,0D,4E,36,81,D4,90,CB,54,76,FD,74,46,6C,A8,DD,C6,18,05,A7,C3,19,FC,A8,46,D0,1F,D0,6A,42,CE,58,55,03,8C,FF,4A,7C,01,31,20,7D,1F,80,CE,0E,06,29,4F,E7,6F,84,91,AF,AE,57,DC,DE,9E,C6,02,FF,7B,53,4B,C9,32,8C,55,84,B9,BB,31,8E,DF,72,E5,2C,05,ED,AA,2B,E6,D3,0E,53,34,14,07,6F,9C,81,4B,28,38,4B,F1,CA,4E,6F,D8,2A,1B,D0,AA,FA,CA,0A,6B,7C,EC,EC,C7,AD,D1,F4,2F,9A,9C,2A,85,6C,AD,B4,9D,F6,28,CE,B8,7F,31,3B,F7,A4,98,3C,BC,2F,0D,B6,84,71,6E,D7,D5,25,9D,58,17,B1,A4,09,82,B2,4F,F5,86,EB,77,18,3D,9A,11,DC,D4,46,09,AA,A7,D7,C7,61,2D,6F,FC,4A,E0,3D,47,6E,82,03,D6,FE,07,A9,29,4C,06,58,B6,20,7D,5E,25,D7,D0,7E,8C,52,3E,11,5A,3A,6E,10,85,CD,06,1D,22,29,69,21,5D,FF,4D,DF,71,68,9B,B5,6D,F5,A0,B8,D6,8A,80,26,2B,1A,26,F5,DA,90,19,95,FB,03,43,0E,18,E7,76,B8,83,69,CD,B3,F6,01,2E,EB,15,CA,23,31,E5,2D,27,A2,C5,79,BA,06,73,20,03,C6,15,4E,05,A7,DF,52,CB,E6,02,62,3E,DD,DB,74,14,D0,6F,B4,C2,0E,6C,EA,5F,4A,1A,1C,42,36,00,10,8F,9C,72,11,B2,E6,3F,3C,83,CC,7D,FF,F5,81,00,CF,D1,B2,E9,6E,7C,52,F6,37,AB,A9,E8,91,B3,22,D4,10,B1,1C,94,09,4F,A5,DC,07,34,E1,A9,36,0B,8B,97,B5,FE,97,04,EF,CA,2B,7B,89,37,EA,CF,87,CC,CC,01,2F,84,3C,7C,BB,25,2A,40,07,F6,69,84,9A,DC,43,7B,B1,FD,18,2D,24,EA,49,A1,4A,11,6B,58,16,2B,1C,FA,7A,66,9D,63,DC,AD,5E,88,C4,88,41,88,B9,B5,3D,7F,F1,A2,43,E5,44,2F,C1,A1,86,E8,BE,A3,D9,17,00,E2,2E,6C,73,4B,9E,B1,4E,57,B9,69,22,A9,E1,66,79,76,83,33,35,49,DB,7C,73,DC,CE,93,87,E2,9A,EF,7D,E0,22,A7,02,35,F0,BB,C5,4A,C6,37,5E,F4,A0,EE,B6,6F,46,B2,07,0A,FF,28,37,16,9C,DD,B1,F4,29,A0,2B,86,5A,9E,9B,E5,F3,C9,46,53,C9,0F,BB,44,70,39,08,CB,86,72,81,6C,AB,43,7E,7C,CC,5F,46,8F,97,08,C6,2D,E9,E1,CC,FA,FE,5C,E7,EF,74,7F,CB,74,7C,23,A6,4D,B1,A2,0E,E6,6B,82,78,20,33,37,FE,DA,45,CE,06,AC,79,C0,72,2C,7B,32,38,BF,61,C3,02,F6,B8,0E,7B,AC,05,A4,2D,A5,98,CD,02,CA,D1,30,C4,96,97,8C,00,8C,85,5B,40,29,55,E3,F4,B8,0E,9D,4C,4F,0E,5D,38,11,56,81,BB,0C,7C,26,A6,02,E2,61,DB,21,46,15,C7,4B,97,8A,FE,04,FA,52,97,57,09,1E,1A,1A,25,EA,96,42,6E,B7,36,8F,F6,3D,EA,22,FA,85,30,F9,79,26,EB,5F,7F,3E,5F,17,B0,41,4A,89,B9,15,96,DD,E7,17,DE,39,14,94,A6,DA,3A,D4,82,10,5F,18,52,FC,61,01,74,02,DA,EB,C2,EE,3E,0E,AA,71,E9,5F,CB,B7,DE,47,D3,EA,C8,8E,3D,93,CF,4B,70,9D,86,4B,70,5E,5B,3A,C6,4E,E2,74,5C,C9,98,68,5D,8F,2C,B3,F0,87,C2,EF,E5,45,E5,EA,24,FA,DA,43,89,C0,F9,49,8F,1F,C1,3A,B3,1A,40,0B,3B,C1,3F,75,31,50,06,49,93,C2,ED,EC,C6,9B,05,60,A0,9F,8C,3F,59,90,F9,6C,64,B3,55,22,94,1B,00,E9,68,9F,59,5B,89,28,E1,A5,88,98,1B,5F,92,22,5D,14,66,57,E5,28,79,83,6F,02,1C,37,EA,F5,0A,CC,C5,A6,8B,70,57,56,1B,64,BD,FC,EA,BF,06,3E,FA,22,67,D7,40,2E,AC,21,D2,8D,87,E7,BE,BD,8D,22,C2,19,F5,60,6A,03,69,A5,A9,7E,89,D5,91,10,80,C7,0A,6B,D6,95,2A,50,88,9C,5F,F4,49,9B,6C,C4,1B,97,45,77,A3,BD,55,A6,B1,A1,25,12,B7,7A,0C,8C,AD,BC,FB,42,50,5E,45,36,51,95,77,F7,41,85,2F,D6,A9,81,43,2E,76,AF,05,22,E2,26,56,F7,E3,F4,94,24,E5,50,1A,38,E1,FA,47,A6,F5,2E,2B,5D,2F,F6,DF,A4,FF,74,9B,89,39,F0,B1,B9,04,67,5F,86,77,39,C7,ED,99,F3,BA,7D,66,20,63,83,61,17,46,A6,0B,B2,8F,95,46,EF,D8,98,B3,67,0A,26,99,34,2D,AA,29,82,96,C4,03,65,7F,DD,19,CC,7E,4F,7B,88,D0,BE,C7,65,67,9C,7F,77,62,F1,87,1C,FA,BE,B4,7F,F7,DC,34,24,88,28,F9,14,78,DE,AE,52,99,DE,3E,31,05,39,A4,E0,7F,76,E7,16,7C,0F,EE,06,7D,6B,B2,AE,C4,C3,65,F4,12,C8,B2,25,E7,32,56,80,C1,EB,43,DC,E9,34,16,FB,1B,A6,B0,61,AE,9D,A0,2D,90,6F,C2,39,30,02,91,F8,C7,D8,A7,17,9D,62,8D,E6,66,D3,41,2F,DF,F0,56,8D,D4,F8,3B,7D,27,B2,E6,34,63,C0,66,DA,BA,92,E4,7A,17,98,EF,A8,83,3D,18,12,34,79,AC,59,5D,C4,45,C6,24,D8,61,32,F0,31,60,1F,FB,96,7C,B8,FD,7F,4F,78,EB,E0,2C,32,99,F0,24,B9,E6,5F,17,AF,8A,60,AC,F5,6F,D0,CD,27,2D,2A,CC,87,15,31,12,E8,0C,68,C7,D8,80,CF,AF,B9,5A,4E,EE,2D,09,7B,9C,9C,1F,91,4A,80,19,28,9F,99,07,21,92,79,CA,B3,D6,49,B4,DA,FD,CB,3D,AC,72,1A,99,BF,CE,CD,0B,94,6E,2F,53,15,A5,B7,55,27,15,14,C9,D9,E0,D6,A6,BF,3D,39,EB,45,E0,65,E3,CE,47,05,F3,8C,F3,62,62,14,18,CC,3A,EC,03,5E,70,DF,52,2C,F0,D6,AC,49,46,41,BE,D2,E0,C1,43,CD,F3,E4,50,50,B0,A6,60,B1,D4,56,49,0E,19,61,5F,95,5B,CF,48,CF,99,86,A1,B9,2B,DD,73,B1,5A,DB,75,AA,51,81,01,14,29,DA,49,10,DD,F3,C8,B7,E8,C2,F2,91,29,72,04,EE,53,AA,4A,15,8E,8C,5A,F6,71,5F,DE,D4,ED,A2,2C,0C,22,02,70,A1,EF,D7,DC,F7,83,C9,C3,DB,18,CB,3F,F6,8A,AB,9A,A9,92,B5,70,94,C1,43,57,71,CE,D0,9C,30,54,7C,78,B0,01,CC,91,07,CE,E5,CD,35,0E,68,AB,BD,36,57,9B,B0,F2,16,58,56,40,EE,87,B1,E2,CD,F9,AB,05,18,F4,F5,CE,42,8E,25,98,F5,62,C6,74,BC,47,EB,1E,26,80,41,A7,38,4C,6A,3C,D7,32,9A,DD,9D,E2,73,04,6F,9C,B0,EF,09,28,D4,E5,79,DE,BB,38,7A,37,14,9F,7E,92,EF,C3,3B,BA,00,F9,3C,0F,27,5E,3A,7E,01,72,4A,2D,77,01,60,AF,80,30,10,3E,75,DB,18,08,E7,6E,32,65,1B,6E,99,52,52,14,54,C9,12,5A,92,8B,53,06,AD,1E,B6,D0,B2,F8,0A,B7,2B,EB,74,DF,27,6B,5B,A5,51,91,BE,AA,BB,84,F8,04,22,6D,4E,39,8C,E5,AB,C1,77,BF,56,75,DB,0C,ED,96,56,65,0D,44,04,45,19,16,F9,A5,F9,6D,2D,2D,FE,6C,69,DD,F3,4E,AF,FF,03,EF,FC,D3,00,6C,D3,62,03,F1,D3,BB,53,3B,75,09,77,B0,D8,0B,C1,EB,DE,81,80,65,34,E1,25,8E,B1,69,BB,0C,1C,B9,36,B6,FA,58,94,05,6D,9F,2C,FE,F2,A0,06,57,67,5B,A8,ED,F9,B4,FD,38,2A,D4,1C,E6,00,5B,47,8C,FF,EC,8B,D7,2A,AA,C7,DC,E8,1F,B8,EA,0A,B1,5A,A2,6C,4B,9F,59,E2,1C,89,1A,7E,15,84,70,0D,30,58,CD,D8,8C,71,13,9F,F2,F5,E7,8C,4E,E1,19,C4,D6,97,00,62,78,E0,E3,58,0D,61,91,2E,BC,AA,03,D6,5A,D4,15,F3,B8,B6,97,62,62,9C,45,80,C0,70,6F,73,68,50,71,9A,89,48,53,66,73,4D,77,90,34,3E,DB,74,23,36,AD,C4,AB,C1,64,25,7B,26,EE,4B,63,B3,72,6F,CE,4C,30,8C,21,AE,D5,A4,BE,0B,85,E9,B4,98,D4,46,33,2C,31,14,CA,FA,A9,56,34,9B,33,FB,C1,5F,BB,8B,39,28,00,65,D9,BE,C7,22,91,7E,42,43,A5,25,C9,26,BD,88,E3,76,17,33,74,4D,0F,32,A2,C5,64,56,78,4B,D2,7F,87,A2,9A,7C,14,AF,DC,B4,78,5D,58,FF,B0,C9,74,30,E6,81,31,7B,64,1A,5E,A1,B5,87,49,82,08,FC,C0,9E,0B,FC,88,52,F0,FB,BA,0E,B9,2A,FA,AF,4A,82,AB,B7,E3,9C,E8,5F,87,C3,00,1A,62,78,DA,E1,F8,22,0B,E5,F1,E7,A6,FC,FE,29,BA,44,01,EA,D8,C8,4A,5F,6D,6D,4D,68,B7,43,95,84,35,67,8C,53,12,40,7A,5B,F6,C7,66,A8,02,8D,52,CC,43,7D,57,7B,CA,F8,08,E5,61,40,88,27,CB,11,B2,FF,DB,B0,1F,9A,C5,A3,44,B2,EC,3B,B9,B5,DA,A0,AD,37,4D,84,E1,03,AD,4F,F0,D5,CA,CD,3C,81,5C,F4,0C,4C,4C,6E,01,4F,C3,95,BC,82,45,AC,F4,F6,84,4B,FD,73,F8,54,D5,B2,4B,CC,B2,A7,0C,FE,EE,D0,D9,E6,DC,D0,8F,29,CD,C9,B7,FC,6D,0F,33,6E,B5,A9,AE,FE,48,86,37,98,AA,97,B1,C9,16,85,BC,71,94,CA,52,14,7A,28,DE,7D,B1,FE,FA,A0,12,6A,D1,83,6B,5F,E8,9E,B4,A7,89,85,20,71,B2,51,AC,3D,18,CA,6C,83,0B,68,E7,6F,F6,96,29,01,43,7C,AE,E1,42,DE,A1,41,D5,59,50,C2,0F,0B,5F,0B,8F,B3,AD,12,A5,85,EF,D8,91,B6,C7,24,3C,9C,1A,71,6A,1B,26,2F,48,26,D4,29,84,C0,7D,B0,51,33,43,B5,EA,83,C5,8B,CC,7F,99,AC,90,50,4D,77,D5,69,D4,F5,3C,D3,8A,A1,26,00,E0,AD,F3,42,85,D9,F1,06,6E,A3,18,BE,56,74,5E,FD,35,38,57,A1,F6,C4,AE,CC,D7,4C,2D,99,61,F9,89,7B,C7,F9,D7,64,6C,16,1B,96,C5,2F,D8,86,AE,FE,34,07,E9,E2,32,15,2B,D0,CB,77,AF,1E,7E,98,16,0D,B5,20,68,5A,BF,D1,E2,0B,37,8E,AC,B5,0F,A0,CF,63,15,DC,81,F3,AF,F7,A7,18,2B,E8,7E,C4,33,36,2B,B0,B6,63,A6,A0,60,1D,11,32,13,94,D9,D7,26,AD,9B,FC,89,6D,4D,FB,0D,9D,44,E7,E8,61,99,16,24,26,FD,64,0F,51,D2,41,0B,BC,9C,7E,89,4F,68,0B,72,D4,DC,72,97,29,E7,E1,2E,4F,CA,B2,6A,8C,34,E8,2A,BB,52,42,CA,69,A9,C1,2E,AB,E7,45,3E,00,DF,40,97,7E,F6,5B,1D,92,5B,2E,E8,21,E5,70,5A,54,8C,2D,A2,AB,27,EA,1F,8A,8C,4E,E6,56,57,89,B6,26,0D,57,6C,FA,9A,AD,67,45,F7,D4,C4,46,10,9A,B6,47,4F,CC,8A,97,7E,73,88,E1,EF,CB,64,43,94,CD,80,00,0B,5A,56,1B,E1,92,73,10,5F,13,24,B0,B3,53,72,DA,E0,D6,41,81,22,9C,8B,C0,70,F1,70,08,D0,DE,3F,2E,61,5A,4C,42,76,EB,0C,FB,67,27,1E,B3,8D,06,35,E6,EA,7D,5D,98,4A,97,FE,42,13,DC,E3,48,85,90,FC,1B,89,71,F0,19,4C,3B,D9,03,31,7F,A0,32,39,5D,42,2A,BC,40,3B,B2,A8,2C,C5,58,CF,31,54,4B,85,AD,51,E0,84,02,B9,98,53,32,92,4B,78,3F,14,54,2C,25,CC,C0,71,88,39,19,7E,EF,E6,50,0F,E2,B8,74,96,E0,47,BA,10,1B,09,D2,E4,E4,50,F9,6C,D2,B4,9C,85,30,15,04,79,34,C7,24,56,8C,F5,B4,C5,DC,23,22,3F,60,2A,E0,BF,84,9C,85,34,88,A6,51,CE,D8,60,20,FF,BB,A3,8E,8C,C7,6E,DE,4A,D6,0C,4B,09,37,52,F2,74,E1,6D,D0,DA,88,3F,49,8E,B8,9D,9D,BD,73,10,E2,D3,E1,47,28,72,6B,64,0A,73,CC,A2,AA,A3,17,57,24,04,91,87,B6,F9,FD,08,94,D7,7E,7E,1D,5B,2A,A9,15,68,FB,79,C9,25,4A,B3,75,71,BF,11,B3,2F,F7,9F,CD,5C,CB,77,A3,D0,48,4B,F8,52,24,A3,C9,2F,34,4F,FF,55,A9,89,A0,8D,F7,9D,BA,AA,E6,CC,37,B9,98,A0,34,64,19,A3,15,BB,EE,43,AC,AA,E6,71,A9,4D,B8,B1,91,C7,BF,27,FA,D1,05,D0,65,B7,EB,2D,60,50,E7,D0,07,3C,71,33,40,83,22,21,2F,C5,92,9B,B5,BF,07,33,5E,20,07,04,26,8C,32,E9,73,73,D2,90,F2,D5,06,55,50,AF,7D,C6,49,99,F5,C0,80,BA,E6,8D,B9,77,59,5D,0A,5C,6D,CD,CC,03,65,CE,EC,9A,A6,D2,AE,B5,8C,75,A5,DA,76,1C,34,75,ED,3C,49,45,4B,BE,75,CE,E3,65,3C,78,48,26,36,C8,F1,7C,70,09,57,F2,22,2B,EF,DB,DB,6E,97,AE,7F,04,7C,4E,36,71,1F,0C,DF,E2,D6,F4,C4,8C,72,13,3F,CA,34,A6,01,5B,8C,5A,AA,EC,85,86,20,70,80,D9,C1,27,1A,4A,A5,16,6D,F3,16,6F,76,8B,A4,02,2A,BE,D6,FE,31,F8,46,B4,29,E4,55,8E,AF,90,85,3D,0A,90,E6,3F,D2,2D,7B,37,97,86,13,A6,83,CA,A4,A3,3A,87,5E,1F,C7,C9,D5,A0,4B,67,23,C5,53,63,9B,C6,26,3B,82,E3,70,F0,F2,1B,50,7C,BC,39,C3,BC,2B,D5,45,99,7E,3C,19,C8,5C,CE,FC,84,51,8D,97,D2,60,76,E5,E9,39,99,ED,1F,5D,7C,47,9F,E5,44,F8,29,94,7F,C8,D6,FA,B5,60,F8,F7,2E,A7,12,A5,95,A3,56,32,ED,7E,E1,E3,50,9A,30,A7,C9,AB,74,9A,C9,BB,86,54,C6,A9,DF,52,B1,7F,A6,92,DA,F6,30,F7,4B,AC,52,E6,C7,EB,96,F3,F1,01,B0,D1,76,E8,28,2B,02,41,87,66,0C,4A,98,82,F8,97,68,B6,31,BF,92,F9,74,67,7A,66,D2,2A,5D,45,44,C4,D6,50,4B,8E,C5,BB,F6,3C,E2,27,DE,74,27,B3,8B,C7,1C,48,FD,8A,D9,BF,57,45,F6,2F,DF,A5,7A,7E,9C,97,48,32,C2,9E,4C,19,79,B7,3B,4A,D3,1C,A1,7C,F6,1B,B0,D8,8D,91,A8,E6,1F,FC,38,44,C9,B9,B4,D6,D0,13,34,74,7C,C2,A3,5E,90,D5,A5,D9,C3,0B,FB,02,C3,76,FE,62,51,CA,E7,B5,71,87,4B,63,7D,A9,24,F9,6E,F9,4F,21,08,09,7C,3E,0A,7D,28,0C,A9,C0,66,78,49,96,B2,B7,6E,7C,05,3B,77,70,3A,03,F0,A6,62,93,C6,45,1F,50,F3,38,DB,98,47,58,A2,DF,37,5A,14,12,35,34,3D,F3,F9,F6,8B,03,FE,9A,C4,31,0C,DB,09,8B,8F,A5,25,54,C7,41,64,2E,58,D9,53,43,37,DD,74,A7,C5,00,68,B6,89,8F,45,29,3D,C4,10,A2,35,E9,2B,0F,71,9B,48,7D,58,95,C5,56,1F,51,BA,33,EE,93,D3,63,C8,14,9C,F6,96,90,65,5E,35,16,A6,AE,71,20,4E,10,65,9A,D9,F9,5A,AA,F4,06,96,B6,96,CA,47,CD,4C,DB,DA,10,DC,6E,08,D9,D0,64,88,32,8E,EE,DD,F1,F6,88,1C,2A,39,80,8D,C4,E9,1F,D3,C9,FA,61,78,57,98,3A,6C,2B,31,86,DF,C3,56,21,89,90,8C,5C,6B,94,69,DF,B7,96,00,8E,7B,08,5A,F4,4B,AC,5E,6D,6A,EF,11,45,E8,7C,87,2B,48,D9,2A,C6,78,58,72,AE,2D,10,39,98,6B,10,90,D1,2B,2E,D1,A1,4B,F1,B5,44,DD,66,6A,C2,55,CF,56,52,78,8C,54,71,8B,AB,7A,76,BE,12,AC,F0,58,23,76,08,F1,BE,93,46,42,08,8E,FB,03,6A,63,5F,1E,23,CF,03,E1,78,3B,8C,27,47,AA,9C,9C,B4,62,FF,A1,D9,D5,EB,57,41,0F,78,11,10,BD,1A,AD,72,C3,AB,9B,94,54,3D,90,03,3E,EF,8D,65,6E,F1,F2,B7,3E,91,59,2C,50,29,CB,3B,4D,2A,21,CD,65,AF,00,0E,7E,73,69,2C,4A,B5,10,27,80,9F,34,48,E8,70,1B,C2,BC,82,98,B1,44,A6,4F,3E,1D,5F,0B,E0,74,82,52,5C,48,91,9F,E6,68,FF,1D,1F,06,F8,B5,0D,2F,84,9E,48,36,CF,B5,A7,F1,B7,D2,8E,5A,20,A4,D4,DF,92,62,C9,56,B7,6F,CC,5F,4E,D5,06,85,A8,87,0A,BD,C9,A0,19,3D,45,F7,67,0B,89,21,36,C4,FE,6C,D7,47,89,F4,20,7F,FF,55,D6,57,41,7B,5A,9F,9B,90,CB,27,A9,F0,33,6F,14,A9,93,90,3D,C8,21,03,B7,10,84,E4,A5,D3,BD,4A,C1,15,A2,91,57,CF,8E,BC,76,2C,2E,C7,67,77,F8,1E,81,DA,62,45,60,49,31,EC,88,A2,7D,85,DA,60,B3,B8,55,AD,1C,E8,32,0A,CA,73,F2,13,72,D4,CB,98,BA,4F,A4,EA,12,47,69,6C,84,40,A8,C1,66,F1,A4,C3,A5,FE,4A,9D,99,3F,82,91,02,1C,14,06,EB,72,9C,69,EB,AC,D6,30,65,78,FB,5A,F8,8C,34,E3,7C,F3,AE,DD,30,68,E7,C4,39,6F,29,B4,58,BC,44,84,10,E8,B1,C5,73,2C,9A,68,08,A3,90,0F,25,7B,D6,9F,A0,3E,9B,42,B9,36,A8,7E,80,4C,65,B3,30,65,D4,BD,04,9D,E4,5B,5B,BE,98,5D,61,66,88,C0,71,76,00,B2,D1,55,D7,E2,AE,35,5B,AF,43,E3,0F,C6,63,1B,47,12,0A,9F,56,12,BA,45,FF,B9,4A,E6,D4,D1,F8,1A,43,94,C2,09,24,F3,39,73,5E,8D,C2,82,59,8D,18,6A,56,A8,75,6C,6B,E0,4B,62,FC,01,52,4F,6A,C6,E3,F7,52,F6,E2,C4,B3,8C,4A,96,1F,4B,04,D0,5A,3F,E7,67,7E,EC,E7,E6,1D,80,06,1F,20,48,D2,9E,2C,C4,22,AD,73,F3,41,1B,14,18,3C,D6,E4,35,58,1D,55,FF,85,A2,B7,CD,29,FF,A0,88,2C,0C,D9,92,B6,E1,C0,E5,76,05,09,63,76,0C,0F,FD,DD,25,86,7B,0F,0E,D7,96,D8,17,89,AF,24,12,93,78,6D,A0,24,65,DC,28,34,67,E2,58,12,CC,FD,21,6A,E5,07,84,BB,37,BD,19,7B,2B,68,CC,9F,9F,2E,A6,C3,40,CD,4C,EE,66,9A,51,D7,E0,06,22,EE,88,DB,E2,84,9F,01,02,48,CF,06,02,A3,D6,35,04,4A,67,E9,A2,29,BA,FE,20,BF,4A,6A,24,C6,E8,3B,3C,8A,8F,5B,BB,AF,74,38,8F,B2,AD,21,78,B5,24,A7,28,79,EB,3F,BC,A1,E9,92,57,AE,F6,D2,F0,D4,C7,F7,06,5E,73,D0,4E,65,BD,29,61,34,EC,81,C2,E0,76,2D,CE,7A,D2,81,E5,A1,F1,D8,FD,95,AA,15,EE,AD,B5,EB,18,4C,A6,6A,7F,51,CD,15,3B,97,55,CD,72,8B,EF,15,70,F8,C3,E9,BD,65,34,20,67,A5,DF,6F,1F,99,DE,34,9E,0C,57,2D,4E,75,95,F0,EE,DE,DB,76,7A,EB,0C,2B,95,B1,29,FB,34,E8,81,76,21,46,F7,63,B2,EC,1B,C5,55,A3,A1,3C,2F,F5,D7,36,53,F7,67,7F,B9,92,BA,DE,32,F5,E4,4E,FD,F6,53,10,18,7B,09,B8,6A,14,CE,9B,B7,EE,00,76,D3,53,C7,D8,F4,EB,AB,EB,99,FF,85,A5,B5,99,FC,DC,A4,9D,1C,A6,08,8E,61,A1,E3,D2,27,F5,AC,95,05,B5,5D,45,80,78,FD,4F,80,0A,55,5D,5B,3E,AA,DD,E2,CE,1A,C0,CA,4A,5B,21,04,FD,9C,6D,C1,A9,06,E1,3E,42,85,A4,B5,C3,B5,18,4B,56,5F,D2,00,4E,79,A5,87,44,ED,FE,56,B0,E8,F4,DF,FB,C9,F7,10,C1,9E,C0,D6,8B,E4,12,AE,30,63,01,A6,0E,23,A3,44,A5,E9,BE,5E,84,2D,7A,A0,3E,26,78,9D,8C,7B,DC,A5,EB,A9,C5,05,D0,33,36,01,99,B4,7C,53,CD,C9,03,42,5C,65,58,84,C5,4C,B7,16,6B,EA,33,ED,1C,9E,0C,8E,31,11,F9,F6,D1,EE,09,28,85,69,E4,7F,1C,4C,6E,B1,9D,E8,AA,14,4F,19,2A,E5,2A,26,35,07,15,F3,BA,1C,B7,97,6B,07,EF,00,59,94,5E,11,93,B3,20,22,CF,80,7E,2B,F0,47,4A,A9,F8,1E,A3,7D,D0,76,F3,E6,4C,6F,7B,67,CF,12,B5,F1,28,CB,61,AF,19,9D,86,08,79,A4,75,A0,0C,DB,6A,54,53,10,E6,FF,27,24,7A,EF,52,E9,53,09,8C,37,85,D8,0A,19,35,F9,04,1D,88,7E,96,19,3E,08,0E,B8,AA,CC,6E,25,20,18,23,65,4E,F1,F0,C5,99,FB,E0,95,C4,3F,2C,C5,8E,47,7A,9A,83,AF,7D,52,42,DD,9F,62,A7,79,14,42,AF,15,2B,0A,4E,F6,30,EE,E7,70,D4,09,13,AD,D0,6E,96,CB,AF,5D,93,BD,10,68,D1,09,80,91,82,03,1A,2A,F5,04,40,97,D6,C4,3D,C1,EF,44,FB,11,CC,4B,0E,B1,D2,57,DB,6D,68,DF,C1,B5,56,DE,88,EF,57,31,A8,A7,2D,83,04,F6,6D,86,84,F3,11,76,6F,AF,7B,FC,49,1A,FF,4C,1A,39,B2,9C,27,1B,FE,78,A3,C5,54,D8,2A,A6,95,5E,6C,A4,4B,8F,EB,B2,B8,D9,44,12,A4,7B,C4,1F,D2,AB,18,A1,F6,E2,8E,73,A1,7C,FC,77,7B,48,98,52,F5,62,88,4D,EB,03,B4,3C,00,A8,BB,EE,EF,C9,15,05,B1,A0,4D,AF,2F,D5,1E,EF,D3,4D,EC,B1,40,C8,53,08,F0,98,0A,F5,C7,90,E8,E5,89,B1,7E,3A,4F,17,CB,01,94,17,21,07,6C,FA,C2,C6,47,DF,60,2C,9C,D4,C1,47,37,12,AF,C1,6A,51,4D,07,1F,EC,DF,FE,08,9A,31,17,6F,5D,AC,49,7F,09,1B,42,75,84,57,F3,96,0F,82,7A,41,59,84,29,3B,5F,66,E4,F6,05,38,A0,3B,05,C6,F0,58,8C,63,69,04,2A,D5,D7,80,35,A1,D9,5B,23,C9,82,10,C6,3E,FD,14,ED,F2,F2,92,F4,E6,A6,4B,41,DD,4B,23,07,3E,58,03,57,33,B4,69,3F,05,8E,50,F2,C4,A9,2C,F7,31,06,AA,F6,26,B1,30,BE,48,B7,04,E3,8E,E8,90,32,E4,88,66,30,70,58,D2,05,3A,9C,55,DF,BE,59,1E,E2,72,F7,8C,D2,DC,38,74,8B,07,48,56,1B,33,6E,0C,6A,6A,CF,B9,26,0F,89,AE,F4,34,3C,CC,E9,C8,F8,F6,FC,F1,3F,9E,EB,57,C7,62,28,C7,13,F3,F7,23,E0,71,24,08,01,5D,A7,9D,3A,5F,C2,41,44,7B,00,E8,A5,CB,1B,48,03,91,00,0C,77,FD,48,DD,03,9D,AF,72,83,D1,BD,F5,42,5D,F2,AD,8E,D9,B7,33,54,5D,79,40,44,FE,21,27,B1,05,7B,4F,CA,98,F2,F3,93,3D,77,2C,28,C9,FB,C4,F8,8A,84,75,79,93,FB,94,40,82,1D,B4,D0,E4,56,D1,A0,B4,E3,C6,5B,05,AF,D2,AF,00,09,AB,38,E3,14,D3,A4,63,72,3B,7E,18,6A,81,70,F5,44,42,5E,B5,71,CC,FE,B7,DB,1F,A1,B5,0B,64,68,66,12,83,91,24,C3,76,E0,2F,13,8A,38,24,A2,27,66,09,99,54,DF,A4,FB,1F,CA,66,BD,A5,89,11,E3,E5,8D,49,D0,68,DE,58,0E,B5,0A,D1,DC,8D,40,DC,E0,E3,11,E0,78,7D,63,91,3D,D2,01,52,DE,16,01,1E,2B,61,87,A7,72,B7,7E,33,39,98,B8,18,DF,98,33,84,ED,A8,CE,2F,EA,2D,3D,63,A4,AC,4D,29,28,5A,90,49,5A,6A,D4,A6,05,D8,11,76,D6,8B,92,CD,4B,4F,49,CE,B2,D2,8D,C7,FC,15,4A,DD,09,B8,85,76,50,C8,E0,E6,70,1E,F8,B6,C8,21,27,1D,2B,2D,D9,76,D4,CB,27,0A,CC,C7,63,58,1E,3C,AC,01,45,1A,FB,3C,29,C2,3B,9F,1B,DD,39,D1,D5,02,CC,A0,AF,A5,56,9D,B4,3F,47,70,4F,C3,CF,3E,C5,3E,58,D7,41,3B,AD,5A,3B,60,89,BC,5F,5C,1D,5B,4B,E0,44,78,7B,90,D9,40,1C,BD,D4,7C,C1,08,4C,84,0B,EB,41,76,18,CF,F1,A9,23,24,E8,6B,A0,08,6C,90,FC,44,2E,DA,5A,77,39,DF,DF,15,30,63,24,4B,32,6A,33,82,1C,23,AD,E5,51,1E,FA,31,84,33,5C,D3,B9,35,DA,71,BC,D9,83,B3,05,2A,E5,CC,68,5D,2E,94,CC,12,17,7B,92,EA,DA,37,A3,54,C7,8B,6C,C9,24,41,93,56,C3,2F,69,70,F2,DB,86,B5,49,8B,FC,86,22,3D,16,50,BA,F4,94,08,C9,8D,7C,89,A5,F2,F9,BB,14,4A,09,6B,84,89,AA,B9,75,C1,7C,5D,CC,4A,C3,8B,AD,17,FF,A0,8C,0A,4A,3B,06,26,A1,3F,88,DA,9A,16,C9,0F,F8,89,61,FD,F8,34,0D,AD,59,13,AA,D9,A6,AB,89,C2,A3,EC,5A,37,BB,08,1D,96,E5,4B,DE,D4,37,91,B5,07,72,7D,A6,1C,5D,2E,0D,C0,3A,F0,55,11,F5,96,EA,AC,20,C8,88,69,0F,EA,B2,41,13,5A,72,5B,45,3E,F0,43,72,90,85,F3,FF,04,0E,83,9A,54,54,E7,FC,03,CD,A2,51,B4,8A,8D,2D,13,01,E7,39,DC,59,13,89,0C,8B,48,47,B8,65,E8,02,14,00,D2,6D,29,E8,38,93,94,37,AF,BF,51,33,9A,31,96,5D,3B,0E,42,BD,C2,16,5F,F4,0E,B0,7B,2D,18,52,3E,07,46,2B,4A,B6,B7,04,1F,B0,E7,31,17,D2,A7,F2,84,33,D9,44,05,EA,4D,73,4A,C9,44,A2,83,02,1E,ED,32,63,B4,C5,89,B7,ED,B2,7E,75,DC,75,8D,0B,80,8B,FC,DC,1E,22,EA,68,3B,4B,8F,61,53,F3,D3,0A,B1,33,8C,97,FB,B4,BD,A1,3D,E6,B5,CD,7F,8E,E6,8E,35,ED,58,9B,A7,D0,84,78,00,6A,8E,52,A6,67,AE,68,B1,75,60,A3,C0,7A,3F,30,55,2D,76,73,E9,49,1E,7F,71,53,A0,C4,9C,A1,97,4A,52,44,63,21,37,21,0D,1B,A0,20,DD,C0,18,90,B1,F1,41,1D,EE,6B,72,27,7D,2E,DE,9F,D6,CD,78,94,30,35,C6,EE,10,10,14,2A,B2,85,70,97,AD,21,BA,89,FB,5A,1C,04,55,9E,87,1D,A9,57,D1,8B,E2,3A,3D,38,E7,BF,8C,DB,19,B3,8F,31,4B,1F,6C,FA,3B,7F,90,5A,83,27,3A,17,91,B4,DE,4E,06,4F,7A,5E,BF,12,9E,7A,9B,54,F8,E9,C5,54,10,95,31,92,A6,A6,7D,AC,34,94,0D,C4,52,8F,09,79,B7,58,BF,29,42,15,DD,E5,3D,5D,99,A9,D7,00,2F,E1,98,A7,51,36,93,D2,C1,49,03,CD,CC,A3,87,F6,FC,8B,D4,09,2B,5C,56,FC,0A,6C,D8,2F,3C,19,A9,59,BF,EE,74,90,53,13,FD,8F,7B,FF,FC,12,CB,7E,5C,3C,D1,C4,DE,C3,ED,89,2B,E7,F9,3C,84,A3,DC,B3,75,32,1E,50,71,6B,07,1E,8B,B6,3C,C1,C7,23,53,1B,DA,85,1E,A4,A5,D3,7C,B4,9E,B2,AB,2E,8E,A5,DC,6D,48,74,8C,73,97,98,F5,9B,F2,E8,63,97,17,91,32,08,9A,34,20,14,4F,5D,E9,CE,65,18,15,B4,B8,BE,24,95,D4,53,64,09,22,82,F6,D4,E4,92,54,42,7C,20,75,40,7F,DD,8D,9E,BE,5C,92,BE,0F,75,8F,B1,FC,4A,52,D2,E3,D2,52,6E,83,4E,45,42,A1,A9,65,25,10,90,CA,DB,23,2F,BB,6B,0F,8B,47,DD,24,CE,D2,36,59,E2,C3,89,CF,3E,D7,59,06,38,C9,F1,A1,CE,31,B6,C3,B1,FA,0B,9F,B4,38,B3,83,31,E7,86,D7,4A,CC,25,3C,02,CA,31,4A,A7,D6,42,06,3F,A1,1D,6E,7B,AE,F7,7B,7D,17,6C,EC,91,F5,20,51,E2,FA,1C,E3,E6,7E,1E,CA,48,74,22,A9,7C,AA,09,73,70,A0,1E,5D,F4,A2,8C,24,73,89,C5,35,0E,E2,8D,03,5D,F8,80,02,55,E2,47,25,4B,71,5D,D8,57,FB,AA,D0,96,1E,DC,4C,F5,DE,8A,99,8D,2B,1A,3F,AE,3A,4B,74,B7,03,E5,32,CE,FD,78,73,22,7C,86,F6,F1,C2,C0,6E,1C,80,2B,F6,00,0E,D8,E7,76,38,55,44,95,A1,49,73,EB,17,28,FC,C5,2E,AB,92,3D,2B,2C,EC,54,29,08,A9,A4,27,66,A4,A1,FB,57,DD,C0,45,3D,C0,B9,79,33,5E,2B,DA,40,FB,62,8B,48,07,F3,9A,CF,8E,DF,3C,E7,EE,25,2F,39,9B,DD,B0,D4,06,04,B6,FD,56,1F,E6,3B,29,A2,D6,E3,FF,99,84,5F,44,C1,7D,34,32,F3,32,E3,8E,02,F7,C7,FE,E9,65,53,A2,47,5E,44,0E,DE,5D,3C,D9,76,87,F2,38,0E,38,8E,65,AC,07,94,CF,C7,C0,23,21,E8,36,B6,63,FC,81,F7,83,10,1C,A0,90,CF,2A,4F,26,C6,7C,1D,B7,42,05,8E,C9,A8,99,B5,66,DA,00,4D,B7,AE,5D,AB,56,65,5B,C5,A2,55,AE,95,0A,B9,38,0F,B7,6D,1B,E0,BE,AD,9A,9B,D7,7A,94,C3,22,1C,40,8E,F5,AF,AB,C6,4F,A3,14,7E,CB,09,30,A4,F3,8B,F1,9A,B0,35,7A,58,BD,DA,2D,6E,0F,7F,F0,97,DD,36,90,C5,42,4C,DA,1E,08,A7,57,AA,EE,E2,33,7C,41,07,06,FF,AE,32,5C,FD,CB,2F,B1,14,3F,57,CE,A5,85,68,66,6B,F3,74,FD,28,0D,E7,67,56,5D,DA,12,2D,7F,AD,B0,AA,54,25,DE,79,26,6A,93,C1,03,66,28,F9,F7,8A,E2,59,FD,96,C7,95,FC,B6,CB,F4,69,FA,BE,6D,9A,A1,93,BC,03,6C,B9,22,F7,37,E6,E3,F1,25,AD,D3,4D,94,65,E5,A6,F9,F1,6D,B9,C2,63,54,F5,6D,38,5C,7A,E0,14,7C,03,36,55,6C,2D,25,0D,2B,B9,4E,99,FD,73,6D,2E,76,7C,26,C7,D3,B6,1A,57,EF,A1,99,FE,EF,23,A8,8E,4D,7A,DA,B3,9E,6C,36,56,53,D6,4A,5D,10,D2,B1,B6,90,FD,A0,2A,2D,3F,B6,53,E6,8D,5C,D5,9B,B4,4C,51,95,EA,F8,BA,D1,E3,E2,7D,84,C3,D9,82,7F,91,36,38,BA,FF,C3,34,64,5A,6B,1A,70,D0,BB,6D,AA,B0,A0,90,5E,46,9A,F5,3C,9B,C5,34,69,11,54,B5,48,D3,F7,E7,B4,E6,0D,DE,94,A8,9D,30,04,B1,B9,F2,19,0A,47,77,0C,E9,42,07,9A,4D,A7,49,2B,9A,CC,28,13,48,9D,4C,3E,90,33,7D,A8,55,BF,75,B7,6A,E5,46,38,56,AB,DD,72,83,A8,70,B3,DB,06,5A,A3,02,E3,7B,01,AD,BB,05,81,AA,50,01,E0,EC,F9,80,FE,C3,D1,DA,E6,D5,B1,1B,D7,BF,AB,8A,E7,DA,E7,C2,7A,84,88,35,7E,52,F7,DC,DE,D6,AF,E7,5E,92,32,49,D1,6C,17,68,2B,FA,8A,8B,CA,70,14,2A,73,0C,1A,DC,02,7E,B8,D8,0D,AB,7E,1F,1E,1C,B6,0C,54,52,BB,C3,5E,50,7A,AD,F3,98,C1,5A,20,07,05,57,D6,59,92,AD,41,56,B9,82,E2,F5,8B,8A,ED,81,84,80,47,31,2D,D0,6F,F1,E7,1B,DC,2A,10,3F,A6,E7,C7,D2,B3,A3,36,33,7F,69,9C,A0,0B,45,73,C2,06,44,E0,85,26,F6,43,DB,5C,F3,8B,C3,56,DD,5E,74,EF,1A,32,EA,6A,A3,58,B8,22,29,99,2A,0F,71,95,80,96,03,E2,14,D6,F7,37,C2,D8,FB,17,89,5F,A2,19,C3,09,B1,90,D7,13,0B,47,AA,EC,F1,1A,76,92,8E,B9,FC,00,13,30,9A,8A,D4,98,5C,B9,53,BD,3D,DA,4C,76,5B,2D,B1,E7,0E,C0,58,C0,80,B0,E3,97,A7,A4,2A,CF,01,8B,00,ED,75,46,A5,42,E2,16,E3,43,AF,13,0A,86,EF,62,8B,56,7D,65,A0,60,68,61,96,13,5B,30,CC,25,31,62,8C,F9,84,9D,90,EC,E6,BA,F9,38,64,CD,E6,B1,03,F6,66,FF,81,16,52,F9,88,A2,01,75,35,BE,9B,62,27,1C,71,74,81,C7,C4,D1,DD,0F,4E,3D,30,F6,BB,67,23,E3,DB,E0,68,27,6F,1B,EC,AD,B2,E0,4C,B8,3B,3C,00,02,2A,DF,63,E3,0D,4F,46,E8,1B,26,E4,1E,F7,54,F9,DD,C4,01,81,D0,A6,9F,71,8A,E0,5C,B8,1F,5E,13,2B,8D,F5,BE,01,F4,29,15,87,97,2D,28,2A,ED,FC,D2,23,BE,0F,92,BC,A3,E3,7E,4E,C0,D1,83,29,1F,2F,0A,D5,EF,3B,3A,08,E5,0E,07,8E,7E,45,FB,72,A1,9C,9B,D8,83,89,3E,D4,C8,63,3A,54,E2,70,58,EA,43,9B,12,12,03,6F,11,FD,34,9D,A0,04,42,02,05,CB,4A,71,25,76,12,A7,D9,74,DC,A3,20,A9,B7,E6,EE,0D,BE,60,20,14,91,89,B8,2F,3F,3D,A2,80,DB,33,0B,70,B5,2D,4B,8F,45,EC,E9,75,A5,53,CB,E7,7A,B9,31,41,A1,7B,EF,11,66,C3,4A,82,5C,AD,46,FE,D7,C0,C3,B3,91,CE,91,89,ED,CC,F1,EC,54,82,8B,23,89,46,80,4B,9B,34,D9,FA,60,D7,AA,55,40,96,8B,4E,FA,E7,33,9F,75,DC,9D,15,D9,11,8F,38,9C,88,EE,54,C5,2D,15,07,A4,C0,C4,04,7B,9F,D8,6C,3C,CA,30,A1,BD,8E,C1,6F,AD,D2,00,01,21,44,CD,B3,04,09,A8,AF,2F,97,0F,73,E7,36,2C,4B,79,C3,55,2E,27,01,64,69,56,EC,09,A5,04,FF,EF,8E,77,C1,97,E4,05,16,BC,72,AC,96,CE,6F,5D,AD,01,E9,62,18,D3,1A,D6,86,B7,27,A0,B1,5A,17,A0,AD,02,BB,F0,4D,DB,81,4D,E0,99,12,C6,F3,22,1E,D4,B6,3F,80,B1,38,0E,F3,30,E7,21,93,19,18,F8,92,BE,94,30,72,CC,76,2E,31,04,7C,A4,8D,2D,BE,E0,BE,3E,20,96,71,BA,F7,86,F2,FE,92,E3,8E,CE,98,35,CF,A0,E5,EA,6F,85,E9,71,8D,8F,FF,49,A4,17,01,A8,A0,A2,79,7A,10,84,A6,AD,92,EE,63,22,F4,CF,17,CB,FE,85,00,A2,A7,6C,D9,0D,48,8A,B4,77,EA,0A,26,B6,E8,A3,33,19,A4,0E,75,E3,CC,D2,9D,F9,10,3F,56,28,60,12,55,0B,4C,01,F4,51,4D,16,E8,AA,9D,3A,99,6E,89,4D,4B,77,09,01,3C,F0,02,BC,11,DC,AA,FD,92,59,B3,04,26,C5,DB,D7,5F,20,08,C7,D4,D4,87,49,A4,69,1B,5A,6F,ED,A8,38,52,7B,B0,80,B4,44,54,46,6C,CA,0E,21,21,D2,F1,D8,8A,17,FC,B2,97,9C,5D,58,92,14,FF,56,0D,CF,9D,DF,C4,04,91,2A,48,1C,EB,4E,03,70,3A,10,F7,1D,AB,45,30,B5,F5,7D,FC,53,BA,6E,57,90,EB,30,8F,6A,A2,A0,83,79,D8,24,B7,7F,A9,52,39,90,CA,CC,89,5E,3C,F7,8E,C9,98,18,0A,79,A2,10,70,F0,68,9C,3B,44,C6,99,B0,3E,19,14,B3,ED,43,1C,3F,E9,7C,5F,59,5C,CC,60,36,5B,D4,9D,83,EB,4C,04,AA,71,AE,FC,37,A3,C8,60,2C,46,DE,A3,3B,58,98,94,0D,2D,5F,E8,C2,7D,FB,44,02,D5,68,B3,EC,E2,9F,E9,37,77,EC,0F,A3,74,18,D6,18,45,9D,C4,BC,85,BA,E3,85,83,E4,38,0B,F6,22,1F,7B,70,BE,5B,E4,F1,AD,8A,12,A7,50,80,CE,42,EC,32,6F,00,EA,E5,B2,22,EE,EA,5A,63,48,C3,73,21,83,DB,A3,F0,25,CE,D4,39,ED,D0,8D,DD,36,ED,1D,D2,87,C0,2D,93,04,FA,8C,0F,A1,03,7A,C3,26,20,12,1B,2E,12,CC,8F,59,08,32,20,8B,3F,8B,3F,CB,C4,2E,0E,53,2C,1A,04,F1,E7,D5,FC,5D,0D,A4,A5,38,69,C5,4F,D3,D8,AC,7B,09,C6,A1,94,A4,D9,55,4F,A8,25,DF,AF,97,CF,8F,A9,85,FB,37,CE,92,96,0E,24,D6,0C,1B,07,1E,CD,62,0E,36,DF,77,A4,D7,74,B3,FA,4A,8D,2D,21,5A,2C,01,F6,69,45,F6,DA,CC,03,52,F8,F1,D6,35,4A,25,06,D8,33,1F,A7,84,7E,E2,AF,E2,0C,76,F4,60,F1,AB,E7,9F,CB,4D,0D,AE,F2,92,29,D0,52,DC,5C,5C,AC,B5,ED,71,05,01,ED,81,2A,4F,EF,A7,17,06,46,58,ED,F3,75,D0,EA,39,70,93,E6,13,A9,8A,5C,6A,0E,DF,CE,AB,E5,DE,84,F6,3B,24,9E,98,0B,D7,A3,76,6C,85,40,59,8D,3E,92,35,DB,0F,23,DB,61,88,16,18,4C,2D,DC,1D,52,1E,63,2B,5A,61,98,7D,99,AF,DC,9E,13,C2,37,04,E7,35,F9,0E,BF,B0,90,27,CB,17,3C,30,AB,16,C9,43,05,8A,78,4B,9F,5B,06,DE,F3,DF,3A,CC,2C,E0,28,9F,23,E6,01,8D,6F,BC,37,CE,DA,BD,03,E8,6A,CA,25,E3,99,C8,61,23,4D,23,D3,9D,90,36,8D,57,E3,BB,F5,B6,C3,39,54,A5,AC,5A,CE,71,FE,80,7F,C4,AD,78,69,27,EB,AE,D3,ED,84,93,1E,17,B4,75,CF,EB,0D,2A,B2,2E,B8,A5,21,06,1A,D3,81,D2,E0,13,F0,39,93,8C,26,F5,1A,6B,6A,4C,D3,13,1E,11,0F,AD,96,A3,FB,0D,B1,1E,A1,38,F4,4C,67,5F,7C,92,45,88,E4,9E,FC,F8,AB,C2,7A,14,D0,AA,7F,1F,D1,04,09,6A,7E,F0,30,3A,34,82,C0,12,21,48,FD,B8,B6,A8,84,E7,44,4F,BF,C7,A3,F9,9B,D2,25,7B,E7,BE,1A,3A,0C,00,82,1A,99,65,4A,0E,6B,20,40,F0,3F,E1,0A,D0,E9,C0,B9,EE,4D,7F,77,E8,39,AE,64,CA,74,43,0B,E6,E0,2F,9B,94,8C,78,CB,25,EF,CD,84,DD,19,79,3E,2D,78,1F,F4,B2,C6,44,94,34,BA,D1,9D,5E,34,F9,34,CA,93,03,0B,D2,DB,57,62,F6,96,41,27,7C,B3,22,CE,0E,7B,97,87,1F,EC,9A,25,C9,FC,ED,36,2B,38,C1,BE,B3,AD,A2,0A,FC,A6,6A,75,B9,6C,39,98,FE,28,09,52,CC,B7,09,22,61,F3,2E,8E,41,D7,DA,6C,0B,AB,E5,71,5F,CF,AD,EF,DA,36,CC,4B,B3,5A,2F,C3,50,3B,7C,27,F9,AC,30,85,15,D0,64,2C,48,7B,BA,67,70,B3,42,6B,FC,10,35,D8,81,6E,2C,D4,09,60,4E,EE,D3,8D,53,A2,07,16,47,89,AD,4B,AF,47,1F,B0,C4,4F,8D,B7,C0,C1,13,5F,30,BF,BF,3D,B8,6B,91,18,86,65,6F,D2,27,DF,45,F0,7D,05,3D,7D,2D,E3,CD,34,98,C0,65,AF,6A,F9,91,48,9B,D9,13,4F,B3,6D,1D,48,10,2B,52,72,FD,61,0A,91,1A,FE,6F,7B,EE,03,26,8A,22,86,1A,95,58,B3,1F,6C,95,EC,99,55,6E,F4,49,00,E8,8B,90,A2,2A,D9,0B,94,E4,1A,A5,54,24,B9,05,AF,44,AD,47,8B,3C,8A,CF,D4,B1,75,F8,91,8B,0C,9B,BD,80,59,D7,C2,FB,22,34,1A,15,F0,43,6F,60,84,90,EB,9F,0E,06,4B,0E,E0,05,A7,31,61,D9,F7,52,0E,A6,A4,AF,DC,3E,36,90,B3,6B,6D,6D,8C,E4,02,2A,F8,2F,76,C6,54,6B,C4,48,20,2B,3E,E5,24,6B,76,4E,EE,0E,DC,98,72,F7,24,CF,10,EB,58,14,FE,D1,ED,B4,E4,32,C1,3D,F1,FA,D2,B1,D6,5B,14,83,A5,EB,C4,BF,80,D7,9B,B2,DB,7B,55,99,94,37,CF,C0,B4,E5,62,4D,2E,8C,08,9E,2F,C6,41,F9,9E,48,A9,FE,CA,0E,7B,92,65,C4,05,48,EE,61,A4,4A,38,3D,B4,77,0C,EB,B2,76,0A,19,22,9F,AA,10,22,B8,F8,1B,47,26,2F,5A,C4,8F,F3,24,4B,CD,1A,63,D0,26,66,24,A8,BB,AF,41,29,85,11,E6,47,21,67,68,CD,F8,73,14,7A,18,37,E5,3E,4A,34,AA,2B,C7,E2,7C,AF,A6,BC,FB,9B,BD,23,AD,7F,7F,02,A5,10,CB,D0,88,0D,D3,B0,31,E7,50,A2,08,7F,4B,D2,30,E5,B0,2D,DC,B5,82,C8,03,B3,B1,A8,14,8E,D3,8D,71,60,29,9E,1E,40,AC,67,7D,C7,72,62,D6,41,A2,D2,22,91,8E,0C,DB,A6,88,F0,E3,A2,70,D5,CB,EB,1B,B7,0D,75,D0,32,D4,84,BF,AC,08,A8,39,13,50,1B,82,39,2A,46,6D,5E,49,90,82,54,FA,E1,9A,F7,B1,CB,67,17,F9,3B,5B,FC,3E,06,56,0C,9D,ED,B7,C6,01,70,28,19,AE,72,72,30,AB,73,A1,4C,2C,41,54,0B,90,31,4B,13,AE,B6,3E,C9,AF,85,BB,B8,17,C0,1D,75,D0,C8,8A,2B,87,DB,98,8C,7E,A2,72,B9,C8,3B,DD,F5,4B,AC,DE,5C,3B,61,5D,3A,6D,5F,14,6F,F3,27,F8,29,4D,36,45,2C,E3,33,0A,67,7B,7D,83,5B,64,A3,1B,F4,42,56,16,9C,CA,EE,87,02,58,82,C5,80,FC,7F,F4,6F,4A,25,16,08,33,F1,37,B5,F5,D7,9C,13,C5,8A,79,D1,F4,5B,1B,2E,1E,87,D7,94,E7,7D,5F,46,7E,68,BE,0E,85,8D,35,76,8A,D6,D9,37,6A,EB,C1,74,D2,DA,14,C2,DA,94,1D,F5,B8,98,78,2D,14,88,3C,40,B5,16,EF,15,1E,AB,E8,8F,00,7A,47,20,F2,BF,45,74,7F,72,D0,B3,C8,16,EC,7E,DD,90,FF,C6,AB,A9,20,BD,B7,62,FC,01,F9,14,97,DA,3E,59,D9,90,47,79,5D,C8,87,01,12,4E,D8,CB,64,38,32,58,B0,84,49,99,D3,CB,AE,28,E9,F1,DA,2C,5C,01,52,EA,E4,4A,55,4F,49,4F,27,1B,77,F4,AC,11,2D,72,71,59,99,B6,73,E0,BA,48,DD,95,7C,C6,7F,57,0B,5C,A4,A0,C9,82,0D,A3,2E,4C,E2,BD,12,E8,B4,C8,95,59,8F,9C,7C,A8,D9,D6,B1,98,7E,FB,64,C3,7B,C1,A7,A2,8B,0D,2F,16,AA,5C,CA,B8,8F,C1,11,48,D5,12,F0,BF,95,2E,8F,7F,6D,04,6D,32,0E,01,E3,AD,32,11,84,9C,12,64,80,B1,6A,07,CE,52,4D,65,A9,B5,78,A7,D9,2B,A8,AE,C8,35,67,00,E2,6D,5A,D4,EE,3E,B6,44,17,A3,50,2D,BD,BB,BE,D8,4B,A8,12,4A,44,B8,33,BB,4F,A3,EC,87,D5,C6,D9,C0,72,DF,DC,6C,C2,D9,80,FC,A2,8F,0E,E8,3C,2D,D0,03,7A,49,ED,81,7A,91,6A,70,47,96,33,F7,F7,BF,14,5D,55,93,EA,18,F5,6D,57,08,0D,B0,82,5E,9E,F5,EC,CF,E2,4C,35,3D,33,04,B8,D9,AE,15,CC,EE,E8,5F,39,AD,7C,A3,D8,75,A2,08,14,2C,6F,13,46,C6,A1,16,6D,BA,60,F2,8E,6F,35,F2,DB,40,14,40,87,2B,49,4C,D1,26,72,0E,D2,52,74,62,12,03,D0,2D,94,F5,67,56,F9,3F,B1,CA,DE,72,73,9B,7A,BB,49,EF,8F,0A,19,2C,38,09,C2,7A,8C,BE,6C,AB,2D,F0,D5,01,CE,41,3F,FF,0E,9C,0E,19,BF,4D,C9,E6,02,82,9F,98,E5,FF,55,B8,20,B3,9E,EA,BA,E9,B3,3A,78,1B,D8,CE,60,08,1A,B4,E3,84,D3,FF,3E,A1,7D,56,B7,7A,3C,6B,DF,18,B2,E5,3C,B1,37,77,85,B8,E0,AC,09,F8,57,CB,09,8A,6C,34,E8,73,9E,2C,D3,B5,B7,1D,E3,55,3D,C3,F8,F8,35,5E,89,36,20,66,92,60,48,83,F8,9D,24,F6,AB,E8,48,51,7F,C2,8B,05,F3,CA,A6,AA,10,69,99,F1,35,3E,2A,DD,91,3D,2A,6D,C3,37,35,32,96,34,42,B2,97,38,67,AE,23,8F,B7,66,0D,EA,AC,3E,5C,2B,D1,3B,18,1B,3A,83,EC,D2,20,D5,33,91,F3,B8,D0,EA,FC,9E,F6,BE,26,F7,BC,D4,57,DE,0D,A3,FE,17,D6,47,1C,E5,58,34,24,25,94,E3,93,44,5B,A2,15,58,B7,12,2A,CE,62,C9,38,DC,4C,F5,F3,92,0B,FF,74,D4,EE,95,EE,24,B3,85,57,87,38,02,BD,4D,16,B0,8C,EC,D2,06,D1,EA,41,15,DA,54,08,A7,C1,84,CE,04,78,86,49,CE,7A,11,B6,C3,10,FE,78,2A,47,13,7F,7C,F1,2B,BD,A2,63,5F,4A,E3,F8,4A,37,33,94,8F,6D,D7,63,1A,75,A3,EE,DA,7C,DD,30,C8,2A,1B,91,97,BE,2F,C9,74,08,DD,4F,27,75,2E,13,C0,6F,A9,3A,C0,C0,EC,70,D8,71,20,5E,46,89,50,40,6F,04,DF,AD,62,DD,CE,8C,C6,44,03,71,08,A8,9E,98,67,6B,09,27,4F,5D,D7,AF,69,0E,08,C8,5D,3D,83,45,F5,48,B1,E7,E4,8C,AD,F4,5E,2F,14,D6,6C,2B,3F,E5,2E,3E,5D,A0,9C,9C,2A,23,CE,CC,4C,86,6E,09,19,7C,AB,EF,1B,CD,B1,58,FA,E2,B7,72,05,CF,0F,71,34,2C,BC,C2,41,AA,D6,F7,16,71,02,5E,2B,BC,65,0B,09,EE,65,7D,46,A4,DC,AB,F6,61,41,23,85,2F,1B,81,88,51,64,43,5E,2B,3E,72,29,2B,9F,9F,07,CC,5B,69,70,5D,E4,CC,C3,C1,B7,A0,63,DB,CF,45,2C,D8,72,EF,C5,2E,09,0F,4F,60,BF,8D,2F,A0,E5,FC,A9,52,58,BC,DB,C9,16,8D,18,28,98,9F,1D,AC,3D,4F,89,69,F7,CD,B1,D4,E3,6C,38,43,70,F7,A6,9A,31,C1,09,4B,D7,9C,D0,31,3C,74,A3,67,3A,D9,7A,3B,68,55,66,05,D8,51,60,33,94,B4,2D,83,AC,60,6C,96,29,E0,F3,2A,AC,5B,96,35,02,DA,CD,44,B5,3E,82,24,D8,11,96,3A,78,11,49,46,62,C0,20,92,E0,0A,96,29,EE,BE,F7,EF,13,0D,24,60,62,77,31,70,47,65,83,3B,B0,C1,4C,E3,B3,2E,5E,85,DF,36,0B,31,A7,B1,0F,03,A1,80,B8,4C,49,91,23,78,B3,DC,4D,1C,66,04,EC,F4,96,64,72,13,99,BA,6F,77,67,DB,CE,25,07,D3,74,D4,5E,2B,AE,C7,AD,56,59,CB,6D,BA,BE,0C,1C,90,67,03,C4,E2,BF,BD,21,00,C4,A1,B3,7A,33,DA,13,9B,BC,A7,60,99,00,1C,6A,A2,C7,CF,F3,89,4C,14,C7,70,AE,C6,31,54,BF,AD,33,05,66,26,D9,87,7D,0F,87,E1,9F,D7,CF,7E,90,BB,A5,B4,B5,9B,46,F2,5B,D9,6B,79,DE,B9,44,19,64,DA,A9,DE,F0,CB,CE,9C,9C,2C,5F,1F,2C,03,90,76,BF,A4,4A,20,AB,63,D1,41,79,D2,70,4A,AC,8D,0C,CF,53,98,B5,8A,A9,50,4F,4D,D2,4A,7E,D3,14,7E,70,4F,0A,1F,23,4D,FD,87,5A,3F,17,E7,31,54,BC,02,3B,07,2F,0F,1B,68,52,09,19,89,6B,D2,4A,94,E9,93,4A,02,D6,4E,EC,E1,86,92,D8,95,12,E4,C4,66,18,81,91,84,FC,B6,0C,BF,FE,6B,62,D4,6C,F9,53,01,39,44,02,01,D1,14,3A,84,2B,DF,F5,37,83,59,D2,82,4C,3F,FD,9A,9B,2D,D5,08,EB,33,45,45,D4,44,5A,87,BD,82,AF,34,98,25,7A,47,B2,8D,61,F9,11,AA,FF,A7,FC,C0,C8,BE,65,74,4B,8C,B8,C4,A5,55,A4,FD,D7,DD,E6,17,24,68,34,50,8F,6C,17,8E,78,02,1A,E2,E1,1E,24,F2,73,C6,66,13,16,44,B9,B1,C0,E7,EE,CC,3E,54,C2,A4,62,79,5F,6C,D8,B6,0C,2F,15,1C,0A,D5,9B,0A,07,09,71,60,B8,69,B2,56,88,62,31,15,67,86,2A,B6,18,3C,D8,7D,A4,D0,DE,D3,F9,4D,6F,25,5C,0E,53,10,9E,CB,6D,15,D1,1C,04,66,A0,88,D7,4F,2F,DA,74,0C,85,5C,68,E3,03,6F,AF,9F,56,2A,B6,B3,20,6A,1C,17,DA,84,BB,9F,8C,E9,89,17,C0,59,3D,45,0C,7F,55,D4,79,D6,E7,C5,C9,40,12,75,5C,6B,0D,64,E8,74,4C,8B,4A,9F,3E,CE,B2,35,DC,A2,0A,D6,1D,5A,E2,A7,EF,93,64,AF,DC,88,AE,BB,E7,62,56,82,65,CE,15,DA,55,18,9C,AF,FA,64,37,2B,38,BC,59,7F,48,D8,4C,4B,30,04,01,07,65,43,1A,10,AA,55,B2,7D,14,61,FF,62,AE,E4,45,22,D0,52,A7,23,23,33,93,14,F9,F4,66,32,03,CA,6A,19,78,C5,6B,35,41,A7,A1,1F,AC,BA,01,51,D0,E2,79,AE,9A,96,73,6B,81,DE,CA,28,74,04,49,68,89,CE,77,F6,80,18,D5,15,71,2F,DD,B2,4C,88,3A,BE,3F,2B,F0,47,E4,95,77,0D,D0,E2,59,31,12,1B,56,8D,B1,48,92,C0,A7,2B,23,53,20,16,80,5E,3F,E4,C5,B7,32,C7,EA,01,81,3F,F9,5D,14,A4,8A,6A,07,D2,CC,D6,65,AC,3C,83,C5,81,B7,5A,AF,3F,DD,5F,89,73,73,7F,06,97,B6,18,FA,4B,40,CE,80,42,F9,AE,1F,C3,C7,79,10,DB,DA,F2,42,26,0E,7E,50,17,6D,FE,42,DE,55,54,85,E9,19,35,D6,70,5B,BF,39,B2,62,59,90,A0,3E,7E,6C,CE,6D,07,F3,57,EA,0A,F5,E6,64,AD,CC,6A,E2,0E,29,A9,C1,BB,76,EC,A1,52,DB,77,C4,E0,09,1D,29,2D,55,89,28,BE,4D,A5,20,EF,C4,C1,17,F9,77,00,29,70,4F,47,A9,29,86,FD,A1,42,9F,E6,81,11,36,EF,CB,30,75,ED,ED,89,D0,A0,9D,7C,8C,B2,B0,AB,D9,76,95,22,1F,3C,9B,EA,A0,25,CE,34,87,EB,8A,21,50,B3,15,74,BF,CB,70,CC,29,5D,5F,20,A2,9D,B8,80,14,13,7F,FD,40,62,ED,46,AC,08,B6,48,A8,9E,5B,EE,A1,D8,79,00,46,66,32,53,63,DF,A6,9A,B6,C0,6A,02,EC,CD,A1,23,A4,B3,89,D1,3E,86,7B,F0,17,3D,17,9A,45,EB,24,67,DD,B0,31,A2,B1,52,0E,2E,D5,D5,5C,77,3C,A7,AA,FE,D3,35,98,A9,25,5C,35,26,2C,89,4E,B3,B8,D3,C2,52,50,88,86,6D,D3,93,46,1E,73,BE,FE,73,5C,67,40,8B,65,14,D8,AC,98,2B,5F,D8,A4,CD,9B,CF,4E,87,DE,8C,29,9D,61,4F,C5,01,31,AB,CF,64,F4,F7,D2,01,9C,23,AF,D5,C5,16,9A,36,7D,B6,D7,68,F7,FD,7F,EA,F5,41,5F,8B,4E,A9,F5,1A,C3,B1,AF,46,26,80,D5,A3,E2,75,0C,75,10,B2,2F,34,41,10,3D,A0,7E,45,A1,10,64,5D,80,5F,64,5A,C5,A8,13,9C,22,7E,3A,48,16,8D,86,28,2A,D8,5F,81,3B,41,ED,8F,AB,AE,20,28,41,1D,EC,33,3A,F1,E2,A9,2A,29,89,4C,45,3A,E9,10,60,96,0B,D7,64,67,46,39,8C,C4,B8,53,68,9B,28,B7,14,96,92,93,FC,3E,80,2E,19,D5,30,E4,70,7C,5A,93,2A,5D,D2,7A,A9,2E,8D,17,8B,D9,89,1D,FA,87,0B,6C,52,60,28,1F,C1,54,BB,EE,AE,8E,66,47,20,B6,44,B6,6F,29,06,6A,FC,5D,36,14,61,80,32,EC,D8,80,0F,7D,24,ED,3A,F6,5F,C3,F8,5A,3F,5C,22,13,32,6B,14,3C,7D,E5,53,48,6A,10,3C,D6,41,D8,5A,57,AA,AE,67,DB,01,F5,25,A5,D2,73,60,73,3D,31,BE,8A,0B,F4,46,47,43,84,F4,4C,EA,E4,C9,89,1C,A6,39,78,69,9A,58,47,F1,E8,A8,79,D5,60,7D,08,43,82,9E,5A,C8,55,85,CF,6B,6A,94,2F,AF,2D,06,54,26,5D,CE,BA,17,DC,EB,A7,CA,1C,54,43,1A,14,BC,5A,D6,46,CB,B3,20,C0,C2,0B,72,96,E1,AA,22,EA,91,24,F6,83,01,8A,22,B0,C2,5F,05,CD,C1,1A,E1,98,AE,56,86,BC,BC,DC,9F,B1,2D,D5,B2,5B,C3,48,28,74,0F,D1,04,F6,71,72,2A,50,A6,C6,D3,F8,D3,17,DD,4D,89,37,EB,B0,C3,5A,E0,D5,FA,A0,27,56,F0,47,3B,4A,2F,49,86,D6,BD,67,E4,CE,08,04,A7,96,0B,94,D0,57,F8,6E,D3,82,A9,33,FC,29,CC,A0,58,2C,82,DF,1E,4F,4D,88,2F,D9,59,F3,39,97,BF,35,0C,EF,ED,0C,36,36,AA,1B,54,BE,54,A8,86,3F,26,3C,9B,89,3C,C5,34,9F,49,F3,A4,65,B8,7E,72,60,34,70,E6,5A,F2,CF,19,05,D9,D0,FC,F3,4C,2B,62,3F,F2,74,5F,E5,90,5C,A2,B8,55,20,82,D9,F4,3F,06,D6,7F,5C,0E,62,A4,AA,B9,1D,50,07,74,B4,27,2F,8D,46,73,B5,B1,2E,26,75,EE,31,DA,3A,0A,8B,83,69,8D,CF,3B,96,D7,2F,98,A3,12,B2,D3,32,67,12,42,B5,29,D8,65,E4,D4,F5,41,93,2E,73,B4,F1,31,81,1D,3F,6C,2B,C9,08,28,8C,F6,C2,0D,CF,98,97,CA,77,4A,1E,82,F5,76,8E,DE,05,6D,E3,37,D8,E9,34,9A,BA,EF,55,33,24,50,7E,71,95,CF,D1,1F,A9,B4,9E,0A,D3,1D,39,84,F2,AD,9D,B9,34,72,5F,78,74,B4,9C,47,00,74,02,31,86,EC,A6,B2,8E,5F,8F,0F,64,1B,37,D3,7E,1E,3A,14,10,D8,9E,D2,20,47,41,6A,28,7B,C8,B6,70,66,08,F4,8F,39,42,A4,D5,57,B1,AD,45,57,67,80,3B,8B,74,B1,2A,B1,B5,B0,A4,9A,50,F5,68,AD,7E,AB,B0,A3,89,9B,B7,71,47,82,BA,DF,26,DF,05,61,4F,31,F4,36,74,C0,39,EF,04,76,00,A8,99,63,72,3A,5F,DD,9A,31,CD,0B,0E,10,B3,65,76,94,61,99,D9,B2,76,30,5B,6F,7D,00,AF,59,05,46,82,78,3B,F5,F7,49,85,88,FB,EB,E5,B1,0E,BD,BC,BC,5B,F2,7C,F5,46,08,7A,D4,87,31,34,84,66,8A,33,32,3A,A7,A6,A2,8C,A8,3D,5F,55,DF,79,06,E8,1F,E1,4A,2F,45,56,0E,44,E6,70,08,D0,9D,E5,C0,FD,93,30,3C,DF,59,67,7B,12,E1,CC,CB,5C,B4,20,0A,4F,30,7D,B8,EA,45,3C,92,A8,8E,43,E0,F3,7C,28,B0,ED,CD,A3,B7,C0,E0,F4,1E,C2,89,77,C9,1F,88,9E,10,20,06,3B,D4,2E,B3,84,07,25,36,25,35,17,EE,42,66,FC,F7,3F,D0,84,CA,F3,FB,5F,F3,14,9A,A5,25,EF,6C,9C,78,80,9F,B7,1B,1C,84,4F,1A,A9,0A,FE,B3,56,50,94,33,7D,01,72,2F,66,41,AE,EF,CA,6B,B0,DB,40,BB,76,D1,E2,DB,29,EC,11,DB,A2,20,31,5F,3C,66,F3,A2,B8,E0,E2,F3,34,E6,36,03,F0,83,FF,B6,23,8F,9B,E1,D3,ED,B1,43,70,9C,0A,CB,DA,0F,16,36,8C,3F,5B,AB,00,76,AF,DD,16,05,BB,C2,D5,97,FB,77,27,FC,56,C1,B9,81,97,27,2A,A0,11,E6,C2,81,78,11,E5,C6,9B,8F,1F,1D,F4,74,0E,52,AE,69,E1,F3,8D,43,71,AC,4C,8A,95,78,4D,31,D0,C6,76,27,2F,94,F1,41,04,95,94,CD,D9,F0,5C,12,5C,D4,F1,03,ED,FB,3D,BF,41,0E,E0,FF,E6,22,CB,DD,D8,D8,A2,09,16,21,98,65,A4,BE,4E,90,25,BB,C4,DE,69,9E,1F,85,FD,0C,B4,C5,8C,30,57,84,E8,27,4C,0A,06,44,07,20,BF,67,75,BE,CE,B6,BB,1F,04,F3,3C,B3,36,75,6E,EA,FD,66,5B,BE,ED,82,89,57,2D,61,2B,D8,51,90,09,54,68,4A,C3,58,09,A5,F2,5B,39,8A,88,C4,93,F5,E5,17,E0,D1,03,EA,64,6E,11,D8,36,66,4A,00,0A,7C,74,8C,64,D1,89,3E,D8,EE,2D,B8,B8,9F,BE,2E,9B,11,59,84,7B,C8,65,3F,16,F6,B3,7F,3E,BE,A0,C5,E6,7D,F0,75,79,4F,BB,81,DA,AF,48,71,B8,2D,FC,46,21,B9,A6,BA,96,7E,D5,52,46,87,83,29,9C,CC,50,7D,79,D1,FC,8C,10,05,D8,C6,EB,A3,A1,7E,07,13,A1,D4,CE,9A,E1,46,E1,C6,9F,07,FB,DE,CB,28,22,30,65,E5,67,47,11,AE,93,07,29,6A,BC,AC,21,83,20,25,16,11,A3,4B,F5,E1,8E,49,E6,80,CD,DD,60,8D,5B,1E,20,F9,01,02,41,93,6A,6D,35,7C,62,27,2E,8E,59,AD,89,02,54,BC,9A,EE,F0,39,C8,CC,1F,03,77,61,1C,17,45,93,98,22,49,D7,DC,7B,A6,A2,F0,14,34,C4,FC,DC,77,15,66,DB,32,97,56,64,B6,3D,23,16,8B,6E,4A,4B,3C,39,33,41,D4,EC,53,69,C6,53,D4,F8,50,52,FE,86,3F,A1,A9,8F,1E,12,04,E9,A5,C7,D2,4E,E9,6A,3F,5D,9A,D4,EA,6E,67,0C,DB,97,FE,2A,78,5D,6A,C0,2D,31,1B,EB,75,61,14,7E,CB,5D,63,88,E2,0D,A4,D6,BC,2E,4C,AA,E4,DB,7E,52,04,A1,5A,86,3F,CD,C5,3D,4B,35,77,A2,9B,4B,4F,2E,5A,42,AC,B2,95,B0,95,E5,3F,CE,BC,5D,5F,1E,CF,26,F3,4E,EF,BA,CF,BC,BE,E8,3F,95,60,A5,72,4A,55,2E,5B,9B,22,D9,47,27,66,61,1D,AF,D5,70,02,B3,17,BD,40,2C,22,88,D2,52,B5,7C,B6,C0,40,8D,58,A4,55,37,38,3B,9A,EE,D7,1B,14,C2,6C,C8,89,0E,46,B6,A4,B3,C9,E3,FB,76,14,AC,35,6B,1D,E8,2D,F8,61,24,98,62,02,38,66,90,45,7D,6F,E7,FF,1A,8B,1A,1C,17,2C,01,A8,DC,CB,42,F8,EB,04,CA,BC,68,66,65,31,1B,E9,1F,A6,87,24,F2,BF,80,E9,0A,39,6C,88,05,6F,5E,20,B3,08,C4,AD,C2,70,FA,76,FF,2F,A5,9F,C6,EB,AD,9E,41,CF,E3,FF,FC,CB,B7,EB,2D,82,AD,F3,26,BA,DC,AE,71,03,02,99,BE,CC,71,5C,47,D6,92,26,87,F0,48,DC,0D,7E,87,38,EF,29,D8,C1,43,15,14,81,B5,B6,48,B4,51,17,24,6D,62,CA,92,DD,27,69,C8,3B,F9,00,59,70,0A,43,AC,6A,F0,53,E7,15,EA,10,65,5E,53,A3,21,C5,EE,9C,81,A2,E4,02,5A,B2,72,48,41,42,5C,2E,28,DC,05,D7,7A,B4,33,66,F8,31,6C,E1,F6,56,D8,91,40,18,66,4C,01,37,6E,2A,C5,3B,BE,65,8F,0D,4E,68,1E,C7,B2,CC,E4,A0,05,57,7A,2B,C1,AB,13,48,80,33,43,1B,41,C4,19,18,7F,56,41,A6,30,37,04,41,49,3C,D3,2B,18,DC,73,E8,AF,B0,F2,20,06,6D,CE,AB,46,4C,58,53,95,1E,25,58,B8,A2,DB,1E,CE,F7,3B,FB,43,AC,87,0B,DD,D2,71,22,BE,7C,F5,39,C5,27,CF,4B,5E,B1,C4,D9,19,59,8B,23,F9,A5,A9,9A,5F,BD,74,5B,B1,65,74,20,38,68,02,92,93,B4,0E,C7,DD,25,59,7B,4B,10,69,D8,59,44,B6,3A,EB,09,B5,71,F7,E9,06,37,8F,F6,2D,93,CA,77,51,5D,52,54,C3,5B,9F,0D,E5,CD,84,FA,28,BF,EF,C3,77,D6,B3,B6,49,91,87,B2,EE,20,62,E9,A9,E9,EB,BD,AB,9C,B0,07,83,72,09,AA,3D,41,32,CA,55,FF,4C,DB,F8,A4,00,24,97,44,F6,F4,08,4D,0C,46,2C,0C,5A,5A,35,0F,26,E0,C0,2E,D6,5D,F0,94,10,8A,DC,8C,C7,EB,0D,AB,08,E3,25,6F,46,12,24,5E,F2,E0,43,F4,46,5D,77,B7,EF,42,BD,AE,1B,CE,B6,A7,A4,84,27,C3,80,95,23,0D,03,01,47,AF,49,54,9B,08,C6,E7,13,2B,B6,A3,52,5C,23,2B,36,F5,24,61,E0,DD,5A,67,71,E8,DE,66,4C,F7,88,D1,ED,13,48,BC,48,E2,19,B1,89,4E,32,4D,FA,48,99,8F,11,85,40,4E,99,CD,20,F4,16,CF,1D,7D,A1,9E,96,D9,7B,7D,5F,A3,B7,31,EC,E4,DC,28,35,07,4C,00,24,B7,AF,7E,39,70,BA,D0,21,B5,7F,DD,14,20,F2,AB,F1,00,AB,96,82,24,5E,31,05,DF,2C,22,F6,E5,96,2E,17,91,52,C3,31,32,62,2F,2A,B4,8D,FA,31,61,D4,BD,72,DA,3A,66,C1,00,8F,50,55,B3,83,26,CB,63,B7,3F,6F,03,DA,9D,B6,AC,4A,00,F6,CA,AD,27,D7,9E,5E,EA,07,44,89,A6,37,CB,CC,B4,FF,A4,05,04,CD,8D,CA,64,7E,46,8E,35,D3,0D,BC,65,4B,4F,88,ED,19,E3,64,D3,D0,17,EA,D5,20,D3,F5,E4,7F,C2,E3,BA,7E,47,EC,D2,74,44,17,5C,8D,6F,35,D4,38,0B,94,1B,6E,E2,F5,4E,A0,6A,2D,A1,4C,D8,4A,8D,73,20,6B,0D,D9,F4,BB,98,57,A0,FB,AB,DF,5B,17,73,BF,71,4A,A3,56,9C,DC,C7,8A,48,3B,33,17,19,A0,72,D9,78,32,68,3C,6F,0A,A2,FF,0E,38,F2,56,E4,55,7B,77,38,20,0A,27,F4,6D,3A,0C,A2,CC,F3,42,82,05,5D,CB,78,2B,F0,66,73,2F,01,8E,DC,96,15,E9,F0,64,84,89,B1,A1,E1,37,EE,3C,0A,E5,36,EF,B1,F8,66,09,58,32,8E,0D,73,1F,55,2F,62,07,02,D2,3D,0F,E2,7D,CB,D5,83,AF,F8,31,E6,4F,48,6C,5A,F8,09,F3,FE,C4,E6,D2,07,3B,EB,3D,36,FA,6B,93,AD,12,48,A4,AA,6C,29,51,F7,F7,E0,A2,97,E5,06,52,BC,82,98,A1,CF,A5,AD,41,CC,CD,BE,DF,E4,13,42,25,3B,93,4F,B0,9F,D4,00,9F,26,62,33,47,9C,B3,10,93,5D,3F,9D,25,70,94,A6,8A,4A,DF,0E,2C,4B,C6,9C,12,9B,FA,70,AD,C4,11,10,0C,F4,80,94,78,9D,31,1D,84,94,CD,6A,AA,9F,D8,93,2C,63,E2,FC,9E,BB,F3,2B,11,98,53,AB,A1,6C,87,DE,97,0D,5B,38,DF,1A,20,56,B4,54,B9,BA,EF,7B,39,7B,1D,57,BD,DA,2A,8B,03,5E,10,AD,A4,FB,10,9E,C8,7A,B0,21,56,51,72,89,39,52,1D,77,BC,DD,04,A9,EF,E0,EF,94,3E,4E,65,B4,A7,3E,A3,2D,0C,C9,A7,6C,7E,1D,33,F8,8E,43,64,00,D3,81,08,15,72,07,B9,30,C0,47,25,47,0C,66,05,6D,E9,51,6A,A9,1A,4B,10,CF,03,82,16,B0,6E,62,68,6B,CB,E3,86,5A,FE,81,34,29,6E,16,05,C1,E9,52,B2,57,B3,E2,09,66,55,7B,41,3B,BE,C6,BA,28,15,50,D8,B6,F5,E7,C2,E2,AA,A2,61,8F,33,D6,3C,B5,2A,4E,33,35,7D,68,11,BB,EB,77,C9,FA,8B,C1,42,A3,63,FF,09,95,F9,7A,7D,FB,30,8D,5B,B3,1C,2D,E8,B2,44,A7,B2,0D,20,90,FE,0E,E6,78,7A,DB,EC,70,2E,DA,DD,A8,81,5B,E6,4D,BF,F7,BF,DE,1B,F7,DC,EF,03,36,FA,A6,3C,49,72,DC,4C,2E,C5,81,9D,52,8C,40,17,CE,D8,3A,58,3D,EE,73,29,EA,56,44,09,2D,9A,46,F7,F6,92,50,2A,3D,54,45,9C,72,ED,26,18,E8,5B,5F,A4,47,C0,0F,FE,56,82,B6,DA,04,94,1E,B9,94,54,E1,7E,FE,07,10,22,77,2C,B6,2E,A0,86,60,4B,6C,4C,93,34,56,1E,11,7E,CE,DF,BB,79,76,B5,D0,59,59,E9,CF,AB,9A,D5,2D,88,84,6A,58,46,D4,80,B5,59,EB,85,C9,5E,A8,BC,52,C6,CA,E8,D0,01,25,D6,43,80,76,39,12,5E,CD,93,B2,5C,72,56,5B,25,3C,06,0C,C2,E0,6A,1A,C1,A7,0C,AC,5B,79,F1,F1,79,66,EB,07,53,0E,94,EC,07,08,13,12,ED,19,6C,AF,12,43,DB,5E,7A,E4,DC,3C,3E,7B,38,67,BB,A9,9B,14,F3,B5,C0,26,D9,B2,56,F2,4F,1E,47,D7,3A,AA,AA,BB,69,5E,62,5A,3B,02,79,B2,B7,F5,7E,E6,44,1C,3A,D4,D3,15,8B,AE,B7,B9,CC,12,7B,86,8D,55,D1,2B,CB,95,C7,A6,B4,DD,3D,5B,4E,3F,76,2D,41,B0,B5,57,1C,90,0A,8A,00,13,01,47,FE,F7,AF,BB,65,89,16,EB,5F,14,E4,8D,F3,90,26,C1,91,F0,A2,5F,1B,86,64,68,49,F5,AF,5C,A9,43,77,3C,D3,F5,F6,F5,1A,6C,EE,DA,FD,07,F7,3A,50,D1,3A,23,84,7D,4D,17,DD,9A,E0,67,90,BC,CF,53,73,D1,EA,E5,5D,86,B8,35,72,64,13,6E,BA,00,F2,9B,F7,5A,F7,E9,61,58,4F,42,F2,6A,ED,0E,BD,AE,E9,07,43,F5,96,60,1A,71,52,8C,BA,84,8A,FF,5F,A6,6F,BF,8C,71,99,C5,FC,5E,8D,9B,E2,4D,B3,58,B5,56,26,F4,13,D1,2F,35,FD,9F,42,09,B9,E7,24,8C,CA,58,39,DF,96,A5,5C,A0,55,03,64,FC,B3,4C,15,B0,9A,7C,B2,91,3C,04,6C,AC,50,39,63,40,0F,34,44,22,06,D2,4D,8F,77,F3,D7,2C,A6,4B,DE,BD,8B,04,0D,D1,3A,03,4B,93,5C,00,05,09,3D,B6,AD,36,1F,28,3E,5B,96,2B,D1,A8,54,8A,A4,5E,91,44,C9,E7,E0,1F,92,91,68,10,B4,73,62,2D,E5,F5,50,7E,5A,1B,56,CA,3B,7E,84,4B,75,78,CC,F3,D3,CD,61,47,A6,E6,A0,D8,C3,C9,A6,3E,C7,50,F7,13,5F,82,7F,44,36,8E,25,E5,26,42,C4,2D,97,F4,74,67,34,B4,DB,41,DE,C0,84,F3,1B,1E,22,E4,92,8C,A5,12,74,0D,E3,2F,29,2A,7A,32,08,97,EC,78,E4,9D,F6,29,76,70,56,68,90,21,94,25,8F,0C,F1,76,00,D2,E4,99,EA,84,B1,AB,96,5E,77,90,73,8A,F1,0A,13,5D,0B,7D,86,56,8D,56,17,47,73,EB,A5,AF,C7,A2,48,58,8E,ED,F8,E4,78,74,2A,56,F7,B6,7A,B5,B2,9C,D4,B8,94,3A,69,79,01,C3,79,A8,DA,56,7E,0F,64,35,14,BD,C8,3E,C4,8E,27,25,10,39,CF,4D,A5,E7,5B,69,CA,EB,91,5C,A2,30,AB,39,A2,D6,B7,A1,06,8C,0B,C3,60,F7,48,6F,AA,6E,8D,FA,DB,B3,5D,BF,89,DE,77,2C,72,0B,FE,B4,A3,34,60,8D,7F,1D,3F,4D,FC,B9,69,17,07,0E,7A,3B,7C,CF,91,06,60,34,3F,05,F2,7F,B1,69,30,BB,50,47,83,A9,CD,BF,63,5B,B3,08,A8,39,C0,4F,E5,B0,10,01,DC,86,92,F5,9C,87,58,83,FD,63,5D,D0,69,AA,D8,76,9B,B6,98,33,44,1C,2E,E0,12,6E,B6,90,0B,9B,0B,FF,89,F8,55,4C,DC,29,03,5E,20,4D,AB,48,16,F2,EA,1E,0B,1B,1A,E4,A4,DE,72,33,89,9A,67,5B,72,21,3B,E0,43,05,5E,E9,A7,86,67,3E,7B,54,68,5B,B5,35,EC,AE,1A,D5,2D,23,01,B6,73,06,45,46,7B,A9,5F,0B,98,E5,F5,1F,DF,49,D0,21,37,0B,F9,D1,A7,52,90,AE,1C,E9,0E,0A,29,E5,9C,75,BB,C8,14,60,33,8C,AC,C9,95,92,BB,27,C2,5C,01,A6,C2,7A,FB,CC,41,82,9B,F4,29,C0,C8,C1,1F,58,A5,5B,82,AF,FE,AC,4E,FC,93,82,CB,2F,33,F4,35,77,73,A4,C8,DD,0C,B5,BE,26,0B,60,C6,7B,56,DA,17,A3,47,FD,D6,2A,F8,B6,31,AC,E8,9D,71,38,0F,B2,BC,B2,22,CE,B8,C8,77,44,60,D4,C0,BC,84,53,65,BB,02,8B,FB,BF,85,ED,83,8D,EF,63,10,87,1F,CC,5C,CD,6C,29,7F,23,86,5F,78,79,50,1E,6E,38,52,84,9E,F5,41,13,BD,8A,84,1F,26,06,E3,B5,59,E4,C7,A0,50,8B,D4,C0,4A,AD,D1,D1,76,A1,E2,45,9E,80,57,E9,BC,EE,05,9F,02,21,F5,AA,39,51,33,49,5E,63,E9,65,28,63,2E,3D,EA,25,05,96,77,AF,EC,E4,FC,07,4E,BE,B0,D2,AE,C1,68,73,70,4E,21,91,34,7C,E7,BD,55,C3,D5,A4,D4,51,94,D3,34,2F,E3,72,C2,20,AC,55,A5,FF,B9,BD,AE,BB,F7,E0,04,96,D2,AB,39,EA,A0,82,D1,5C,4C,A0,B0,28,0A,B2,09,E6,F0,6B,64,6D,75,D7,4C,D0,3B,12,07,AA,11,BB,DA,CA,E3,B9,6F,A0,4C,2A,DA,A8,4B,E5,9C,F3,A6,81,35,16,87,DC,70,C8,AE,60,E6,6C,28,9B,5C,8C,9B,C3,96,98,24,19,85,DE,54,52,F3,34,3A,8A,11,8D,97,19,E8,CD,21,77,AD,A1,93,AE,DC,C0,E2,B4,4B,89,86,28,98,CB,D4,B4,2C,7B,3A,02,CA,44,ED,3B,5D,44,69,D3,88,B4,EF,0F,24,A5,05,4A,F0,31,73,94,3E,3F,DD,D6,AA,CA,A9,83,1F,9C,1A,16,7D,28,28,CA,50,B1,BB,78,F8,B5,7B,66,6B,19,F3,88,41,41,32,F3,90,B3,F3,10,30,CB,9B,6A,B2,F9,17,B3,A1,74,56,1D,CF,45,63,03,9E,80,18,B3,46,5F,EA,E4,F4,DC,EB,E7,9E,19,7F,F4,A1,F5,CE,BC,D8,20,6E,94,82,E2,20,99,BD,65,AA,F8,13,5F,45,F0,67,50,B3,9E,C3,1C,F7,75,6A,C0,AD,7B,E4,2B,B3,77,3C,13,BE,F1,A5,A9,13,2B,FC,A9,CD,E2,CA,64,04,29,A0,E5,EF,DD,9B,75,DE,7C,B7,9B,29,44,83,A4,14,FB,0C,35,DF,3B,AB,C3,8F,96,CE,93,05,64,0D,BE,4F,76,DF,D2,73,E6,94,1A,8E,FB,8E,1D,CF,9C,A7,F1,8B,9A,AD,3A,85,86,05,3C,06,E5,AC,B6,4B,8D,17,1B,80,4F,DA,5E,AA,F1,D3,5D,DC,54,D9,89,50,39,91,23,31,D0,F6,C4,7C,1E,52,4A,8F,AA,AC,0A,D1,16,AF,7C,CC,9F,6F,39,6C,A5,F9,54,41,55,EC,A0,13,EA,FE,FD,2B,98,BF,1E,7E,B6,8F,0B,91,AF,05,94,90,DD,B1,B9,3E,D2,37,3E,C3,16,2C,D8,A3,20,E3,CB,88,15,98,88,AA,B8,7E,56,4C,B9,68,9B,7C,EB,5C,39,54,9E,03,62,17,F6,F1,AD,30,80,B0,F9,07,E3,A1,7B,4A,D1,10,CF,E6,BD,2F,2D,A3,0B,34,35,F8,F0,83,09,39,20,A4,D8,0A,DE,73,D8,BB,9E,1A,FE,30,D1,9C,A3,DC,8C,D5,2F,A4,55,54,40,B6,FD,E6,80,82,14,4A,E6,5C,9B,2B,F0,89,93,44,BC,9A,36,4B,0E,25,E5,53,2F,93,DE,42,53,86,34,6C,AF,A6,32,87,1B,9A,45,26,8F,A6,ED,C0,7D,C8,DD,ED,A5,6C,4E,13,DD,27,17,8C,7A,64,5D,54,9B,C4,8D,54,7F,FB,0C,37,05,63,11,5B,7F,1F,48,75,85,82,05,6A,DA,1E,7D,2C,76,A7,C1,EB,1F,E0,24,CB,9D,26,24,71,EB,58,C0,C2,4B,DB,D1,9D,B1,AA,C4,35,6A,6D,07,92,00,46,23,27,E2,60,D8,4D,B6,79,16,74,82,6B,2F,13,7A,8D,30,E2,F5,72,EF,8C,BA,04,A1,D3,D3,F1,E6,4F,2E,11,E9,CB,AE,A8,76,A3,31,BB,73,4C,EE,28,F7,08,D1,D3,00,8E,4E,6C,50,B4,84,01,44,17,45,A5,4C,68,5C,29,F6,A4,BC,A9,2E,78,FF,76,40,C3,A2,AC,DF,E6,CD,ED,A7,30,5B,04,7E,B8,46,DA,B9,48,9D,7E,9B,3F,2F,F2,E1,8A,D0,10,CB,A9,D8,D5,82,EA,B5,CF,0D,29,40,26,FA,9C,5A,12,F1,B9,04,DE,50,2E,2B,9D,80,16,2E,94,98,DB,42,99,C1,94,4E,03,8B,1E,81,1E,11,78,F9,AA,B4,11,D2,A2,B0,B0,BE,69,3B,55,1F,CE,98,A0,3D,86,AF,3C,0C,10,5F,75,3D,16,57,10,46,D2,98,0E,0A,2E,8C,6F,D4,18,A9,49,B9,3C,67,5F,6C,02,A8,D8,6B,D7,9E,F4,43,9F,F4,2F,1B,EF,D4,8F,32,42,24,2A,C2,36,36,18,6C,E5,1B,99,8F,F8,27,97,4D,3E,CB,88,CC,92,2B,AE,9D,94,92,29,63,43,75,BA,33,84,D5,2C,C3,6E,6F,2D,9F,A9,F9,72,15,02,94,9E,90,4A,0C,37,A6,AE,C3,F0,72,57,10,1B,7A,C8,E7,7F,29,0A,12,BC,01,C8,BC,D8,10,EA,D8,31,9F,CA,A4,01,6F,11,B6,40,EF,A1,4F,79,28,83,AD,7E,65,A5,BF,2A,33,3E,89,CD,3A,09,02,B0,42,BE,76,E3,05,DC,1B,F8,65,0F,5F,04,E1,55,4E,38,1D,29,73,56,DD,FE,DB,D2,6F,65,16,FB,C9,A4,93,0C,C3,0D,B4,C4,02,01,2B,BC,03,0B,62,9D,14,14,18,CE,84,D3,46,5F,CF,3E,8A,91,35,EB,72,29,FF,73,0D,20,A2,73,21,B7,6C,23,F7,F8,1F,47,1F,89,9B,69,1B,BE,1E,F2,85,D3,85,D1,57,D0,E7,E6,55,20,2E,A9,EE,E0,A1,51,F5,01,C4,70,0C,20,F6,B9,1A,44,E2,81,C7,89,F2,EA,4F,F2,D9,03,27,56,0C,E0,E5,18,56,AE,92,75,08,E0,51,98,EC,E5,10,C6,7C,E1,44,85,46,0F,9B,63,E5,18,EC,9D,84,CC,80,6F,16,00,23,E3,4F,DE,AF,48,2B,E2,EF,CD,64,E7,34,88,19,49,B6,91,E9,8F,02,7E,E3,9D,73,A0,EB,BB,63,7A,FF,B9,AA,73,5A,89,53,16,E7,62,97,64,BC,17,BA,A3,60,9A,C4,7C,18,0E,7B,09,18,EA,35,3A,FF,9F,86,C4,7C,68,69,22,09,71,77,AB,A8,FB,93,9F,AF,78,3B,7C,B1,61,73,D1,A2,B9,18,9A,15,7D,33,7B,42,9F,32,C6,93,27,1B,38,F6,B8,D4,97,64,8E,67,0F,6F,CC,2D,31,13,AD,46,E6,68,31,11,2D,88,48,70,D5,05,33,84,DD,37,E1,67,CB,23,B9,04,D9,22,66,E1,69,22,87,FA,E5,08,29,B0,1F,4A,AD,A9,35,E5,E2,B5,21,1D,E1,5E,45,95,08,B1,D4,99,4B,11,10,16,7A,AC,35,0C,C7,5C,2F,25,2D,37,8B,AD,A1,C2,AB,DF,69,40,DB,FB,A5,2D,EA,6E,93,14,E0,B9,A3,C9,68,08,78,9C,E2,0B,C6,AD,76,2C,17,83,C3,49,6B,76,55,9B,82,D7,E2,0D,E5,56,ED,17,4F,4B,A5,E7,77,88,8A,CF,39,BF,29,23,EF,B2,70,D7,4A,7E,24,06,AE,E8,6F,59,3E,5C,B0,24,0B,74,9B,80,1D,B1,D8,D5,EC,39,EC,8F,C9,E6,28,E2,CD,76,E4,A7,98,8E,0C,A9,30,7A,26,F0,22,36,A7,E9,1E,9D,A9,25,7D,B3,10,FB,E9,6C,7C,84,91,24,AA,9B,AC,B9,3B,5A,5A,30,D5,F9,1F,89,3C,80,86,AD,15,27,AC,21,A1,57,9E,D7,BC,9B,F3,4A,4A,A0,EB,FE,FA,E8,73,20,4A,8B,20,E0,70,1F,66,0C,71,56,15,C4,2B,EC,6A,F3,B7,B1,CE,3A,A6,A5,60,80,06,4B,B0,E5,FE,69,2F,80,98,80,96,52,34,E6,0B,1F,01,EB,69,5B,04,44,7B,AB,B1,FA,72,1C,64,0D,CF,D1,92,DA,79,84,FB,8C,18,C9,30,88,3A,EC,DA,BC,31,D2,5E,B0,57,B1,1B,9C,58,59,08,03,80,9B,1E,3A,ED,E7,98,5B,C9,F9,3B,35,03,83,7A,52,DB,CC,22,7C,CF,C2,26,6C,FF,BF,EE,47,8B,F6,51,08,43,95,5D,5B,EE,D8,8D,D3,21,D6,E9,F1,2F,F2,CD,9E,75,B1,53,C7,FE,3B,2E,E7,52,23,F9,D1,39,F9,AF,D7,99,F2,19,53,85,C9,49,79,58,B9,4D,0C,0F,17,C7,87,26,4E,1E,06,FA,82,24,1A,B5,AB,8C,8C,69,C0,89,99,DB,A8,9E,58,D4,80,E8,80,64,63,B3,96,5D,27,FC,C3,A7,00,8C,44,B8,D7,64,D7,2B,D7,96,D7,75,FE,0C,71,15,A1,48,0D,E6,C9,BC,F6,56,DA,6F,62,3E,7C,9E,74,DC,C2,95,07,7F,70,BC,D2,76,50,03,FB,DB,51,B1,7F,C8,B2,E4,C2,48,16,70,F3,D8,E7,05,46,E2,E8,C7,AD,56,92,0A,D7,98,FD,9C,F1,F5,39,70,B4,CF,A2,E1,DC,57,03,F8,5C,53,47,D5,7E,0E,20,A7,9A,52,7A,8C,B8,DA,3A,1B,9A,40,FE,5A,2A,6F,5A,80,23,8E,61,7F,7C,F6,20,1B,94,A4,CE,06,F6,F8,C7,2A,26,65,76,58,18,08,01,54,AC,05,31,E8,E9,2A,5B,CD,C0,FB,8F,DF,17,C5,24,6F,88,FF,C4,46,9C,D5,4F,C5,70,C0,74,F3,B7,00,C5,55,DD,A1,21,AB,D7,6F,E9,EF,2E,6B,AD,D4,1F,8F,6B,A3,16,B1,22,E3,07,7A,45,BD,89,DA,31,7E,15,73,C8,6A,F6,E9,B6,DE,46,58,64,A8,FE,96,81,9E,2B,FF,56,C4,30,C4,5E,F2,63,62,70,AE,D9,87,09,C8,50,E5,FD,C9,CC,60,EA,40,FE,78,41,B3,3A,F9,1A,35,C9,5C,18,A4,A5,12,FD,17,95,54,F3,65,BB,A5,B9,62,EA,76,76,FE,E5,22,35,91,51,BB,7D,9F,D5,CD,C8,62,26,FE,7B,4A,BC,0D,14,A6,86,69,AA,D7,FD,22,10,29,8D,7F,11,E0,1F,58,F6,0F,9B,E5,21,B9,BE,7B,BB,AD,AA,FD,B1,A1,13,4E,01,5D,EA,90,2C,34,69,BB,F6,26,D1,25,92,65,BC,A9,7B,FE,B9,40,CC,B3,EE,BF,B0,D2,6A,D7,F4,C6,BB,1F,78,99,D8,1D,58,81,F3,B7,BD,DB,84,6F,6A,87,A3,69,56,CF,5F,AB,99,DB,A2,D5,10,8B,EF,C9,33,B9,00,36,DC,B9,DD,B4,28,9D,B7,01,E9,77,6D,47,6B,B6,B0,A1,E6,24,5F,9A,EE,4E,36,AD,09,7C,6F,6D,9C,D5,70,45,D9,23,91,67,9F,38,D3,B5,34,70,F5,55,20,92,2C,3D,93,84,1D,CE,39,3C,E4,FA,53,9B,2E,81,E1,0E,67,88,46,DC,3A,7B,32,7E,A6,62,91,2A,2E,0D,32,8B,47,17,6F,5E,BD,89,14,71,20,6A,F5,81,C9,8C,61,88,11,BF,23,B6,2D,A4,1D,EC,BE,76,63,E2,D8,14,4C,1E,4F,7F,74,38,BF,EE,31,AD,79,92,EA,62,21,C6,C5,26,ED,74,CA,2A,11,98,DE,9C,7E,25,2C,32,6F,B2,03,C2,BC,26,0A,62,98,DF,96,5E,5A,B6,A5,2E,5A,10,95,F9,9F,C2,16,86,E7,B7,1E,5C,6F,46,C5,23,AB,81,84,22,17,CA,D0,6E,E1,2A,99,CD,60,4E,40,96,9F,B8,3D,36,44,23,1A,40,DC,66,C5,5C,38,92,9D,6B,36,B2,24,77,EC,29,18,A3,9C,9E,D6,4B,11,74,7E,91,FD,90,72,19,01,C0,45,C1,8F,1F,24,6F,BA,03,98,4E,39,A1,C3,FA,69,37,1A,2F,6D,D8,D4,43,18,7C,BF,F7,01,77,3B,31,63,64,6F,24,9B,1F,86,48,1A,28,FB,28,96,0A,4E,45,3B,E2,02,82,27,A8,C1,92,CE,BA,97,B4,0D,A5,EB,91,97,0A,F9,AD,6E,8E,FB,53,BE,72,E6,D8,15,E7,6A,45,E6,65,FD,95,2C,75,6C,8A,08,DD,D9,F5,BB,D4,AF,C6,DF,62,F4,4C,7E,F3,D5,84,A6,5F,CC,DF,3B,BF,A6,FF,D3,F2,97,AD,0E,55,C6,79,F9,E5,69,B2,3E,F3,81,35,52,1A,75,6F,58,C6,26,86,BC,33,F9,84,20,D3,62,A8,61,39,7C,19,1D,B5,52,92,25,4A,2C,47,DB,23,44,01,85,9B,AE,76,39,7A,E4,EE,16,55,DF,80,3E,DE,A8,8A,76,03,B3,CA,6C,CB,E2,10,82,10,BE,39,85,BD,1B,0F,ED,17,25,33,D8,76,8A,AB,24,05,77,34,AA,89,A6,09,EF,DC,9A,C8,CA,0F,6F,6B,DF,DE,79,88,C4,23,07,BB,85,41,40,0C,10,92,B0,FF,41,08,C2,3F,33,10,02,E7,8B,BA,A6,7E,A0,14,3F,9E,AC,67,07,82,E2,24,2A,1E,57,EB,AB,6F,BA,71,E2,13,6F,8C,0F,8E,9F,FD,0D,D9,FB,91,FB,72,B4,B5,13,FD,4A,B6,AD,59,BE,58,D2,8B,E4,0B,15,F6,5C,8D,C4,B7,4B,4A,F1,65,D0,C8,B3,77,FA,D7,4E,51,55,84,00,3C,27,25,6E,B5,7E,A5,39,D5,54,EA,97,39,C5,42,0A,61,D4,A0,32,AC,78,50,9B,1C,1E,25,A2,DA,ED,77,5B,5D,70,4C,11,40,E7,DA,86,0E,B2,6A,EF,AF,C7,3A,24,57,77,6F,8C,51,50,60,A7,8C,FE,11,72,19,E5,BA,4E,21,B4,03,13,A8,8F,91,8C,9A,2F,A4,C6,E7,42,04,75,2B,A2,7D,03,5C,D1,25,E0,D5,E2,D5,26,B5,E9,94,34,0B,90,91,65,9B,2A,26,84,67,75,5F,A4,08,BA,0E,AE,4C,9E,98,43,A0,3B,53,96,68,EF,66,92,27,31,55,9C,80,14,39,DB,48,0D,AE,D5,BE,E0,AC,BB,DB,B3,41,B8,41,DD,EE,EA,06,D4,5A,F4,92,FC,74,4F,AF,17,F3,1A,1B,D3,AE,AD,AA,84,45,C8,35,27,93,52,E3,8A,AE,6C,0D,F1,B8,FE,FF,E8,B6,CE,90,E5,51,91,07,01,AE,09,A2,BE,92,E8,70,A0,02,08,6B,34,28,0E,E9,D6,38,C7,4B,CF,79,E4,F1,3D,2A,4C,0D,17,F9,2A,EF,81,5E,06,1A,15,45,66,BB,E0,5B,EC,96,FF,38,AD,EF,55,36,E7,B9,DB,02,FF,D7,C8,75,D5,AE,30,65,D4,56,9F,82,47,B2,71,A8,28,AF,6E,E1,C3,7F,A0,4E,03,E2,6A,EC,1F,18,91,5E,F5,4E,BA,8A,9B,05,90,DF,C8,FD,91,29,F5,61,E2,F5,3D,6A,5F,A4,B5,C7,DB,EC,B0,1C,00,55,2B,D4,CA,E4,B3,13,4E,E3,FD,19,25,4A,08,99,FE,19,08,38,AA,71,BA,A5,3B,52,7C,64,B1,D4,E2,8A,D3,30,39,5C,87,84,E5,DA,59,69,7F,14,32,A3,93,B1,83,EA,A8,2D,69,02,37,79,F1,65,48,0D,63,C6,71,BC,59,01,DC,70,CA,45,57,94,5A,8C,49,D5,65,94,EF,27,F7,88,F3,D4,E3,FD,AA,5F,26,21,66,15,08,21,53,E5,37,85,51,89,D5,F4,FC,25,4A,F1,D6,C2,A6,3A,36,17,80,2A,3B,A6,AB,42,16,A2,24,28,48,B9,62,69,4A,0D,8A,15,5A,4A,6D,FC,6B,41,2F,6A,80,FD,22,14,25,B0,A3,93,F4,2E,47,E7,06,66,E8,EA,BE,04,9A,25,DB,08,45,83,09,E5,24,81,04,FA,A6,DD,BC,50,3F,CA,C5,06,8E,E7,82,35,03,30,4A,6C,54,A5,B4,0D,43,14,2A,B3,13,18,CA,2F,26,D5,C9,56,D6,E0,91,8A,06,01,55,69,15,6D,29,85,58,E4,9F,75,7C,A3,EE,FA,D6,23,0E,A9,28,8F,E1,AE,73,A3,42,42,65,80,26,46,44,73,BF,14,28,CB,C9,F8,D7,CB,10,5B,7D,71,E5,E1,A7,F6,78,48,3F,C4,8D,DA,CF,F0,BF,81,22,14,78,22,AE,8F,50,94,AA,F3,4F,61,86,F7,24,48,58,51,99,DA,8E,AA,6E,11,73,1C,C7,34,E1,C5,6E,35,77,49,B2,78,40,DB,72,68,38,9F,AF,6D,2F,53,0A,22,61,0F,85,36,BC,E4,56,D3,A5,D6,73,4C,56,65,15,23,D1,E7,2A,11,40,9B,E5,A2,D8,D7,CA,38,77,88,85,25,B3,41,E3,90,71,90,3F,07,61,55,A5,97,D3,F6,29,F3,56,58,9B,A7,40,AF,9B,F6,40,59,78,41,A2,97,42,3B,0C,87,BF,05,04,87,A3,57,44,4D,18,86,93,82,97,1D,17,2D,E7,CC,57,6E,69,06,B1,1C,AD,3E,D5,05,31,7C,59,82,6A,89,F9,9B,BB,E8,7E,43,90,38,94,44,D8,C3,34,59,19,A1,C2,2E,67,4C,13,11,67,15,60,EC,1A,D6,99,AF,C8,C7,DC,86,D8,F9,FE,44,E2,98,A0,A0,53,4F,9B,62,DE,0C,74,43,69,BE,F8,D3,A8,99,5F,90,65,97,53,0E,94,C1,1B,78,D2,48,12,CB,FF,5D,7E,D9,1E,2E,A6,66,FA,08,EE,4A,A8,83,EA,F8,B8,E4,15,C6,94,62,75,1A,63,0C,6E,35,98,57,92,2F,D5,F5,85,50,A9,91,97,50,72,47,C2,15,D0,00,51,B6,44,9E,03,0E,30,66,2D,AC,3C,68,63,FA,1E,52,CD,68,1C,AB,3E,F9,14,8C,62,4B,72,BC,08,1D,D1,C8,CA,9B,7D,DC,6F,21,E3,F9,A1,E4,91,77,2E,34,FF,A7,3F,39,73,CF,8A,B0,8E,DC,DC,B2,AE,31,A2,FC,5E,D2,01,72,D3,9E,3A,7D,F0,8F,94,43,AD,8B,A9,18,BB,D7,87,97,33,C1,DB,A3,AD,00,19,5A,93,43,B1,3C,F2,BB,EE,0D,2C,EA,C1,3C,D6,31,7F,DE,87,01,68,AC,E3,0B,51,06,50,B8,79,E6,E8,F1,9A,69,D9,2C,44,C5,BA,DC,6B,70,33,A6,77,A1,44,8B,E4,94,C9,DD,E6,FA,DA,3A,4A,EF,5A,5D,CD,C4,EF,C9,79,6E,3B,94,F5,47,BE,61,D1,4D,E6,DD,BB,E8,81,7C,24,CB,5C,50,17,4E,25,F3,74,98,54,A2,02,0D,FD,6B,C4,4A,2F,96,96,01,A6,05,CB,1E,89,98,02,47,E8,9B,20,A4,9C,85,01,F1,95,8D,69,4C,6E,DA,A8,FF,B2,CA,5F,CF,34,AD,00,96,FF,AE,EB,49,C3,D8,1F,53,65,03,A6,18,E7,58,EA,97,AE,72,AE,F8,5F,0D,3B,18,0E,F3,5E,ED,8F,BE,AD,6A,60,68,F9,B2,EA,70,B1,C3,0C,03,D5,8C,E2,1C,EC,FA,80,B4,CF,22,54,17,38,31,E1,64,89,0B,A3,4C,AD,07,C6,9C,05,B0,DD,90,D0,F9,B1,99,1D,B7,04,35,76,53,3D,97,07,46,84,3C,03,35,41,A0,8E,64,2A,67,35,97,AD,E1,C6,DE,45,70,DB,5B,6E,4F,44,24,29,E0,C7,12,48,5B,7D,01,A8,5E,08,AD,38,B1,DC,85,CC,21,85,A8,7B,44,2A,2B,76,B9,76,83,B5,26,72,F4,1F,B7,C4,AA,11,C5,8A,7C,10,62,E3,23,62,6E,E2,AD,96,EC,22,F6,FA,C8,B1,DE,B6,5A,7A,46,DB,5F,CE,55,7D,C1,4A,8C,29,DF,9C,7F,AD,7D,97,AA,31,A3,26,72,F2,B7,D8,F0,3C,F2,B1,92,C2,F1,09,05,F0,2A,09,B0,34,D8,87,E6,97,7F,CD,B9,3A,D5,C6,C0,84,B5,0D,43,7A,69,7C,4C,9D,02,75,97,B0,D6,47,4C,D3,31,39,E0,AF,A1,AF,B6,B8,89,1C,8D,06,B5,04,48,BD,90,C6,6C,E0,72,6A,9A,B0,C5,96,6B,71,49,01,0E,7E,C1,37,F1,6D,40,26,8D,6D,94,9C,94,2A,41,37,E6,9F,6E,62,90,55,E3,29,00,96,32,EF,42,78,4A,C1,FA,67,63,11,76,DC,2B,73,FC,19,02,79,A6,38,C9,09,41,27,49,C4,A3,C4,0D,5E,53,B5,F8,D5,F4,40,71,1F,5B,66,C6,95,29,12,01,35,99,2C,7C,19,B8,F5,12,F0,A8,D5,56,40,6F,2A,F7,05,B3,1B,67,E2,A0,B1,1A,8E,33,EE,11,B2,43,AF,CD,FE,86,F9,2D,11,33,27,44,DE,CD,58,1B,17,11,37,17,ED,80,EC,D8,B4,4D,3E,20,30,FA,F6,93,BA,06,09,FF,D4,D0,44,D9,7D,32,93,6D,E3,AB,CF,32,28,3D,B0,B0,CE,1F,75,0E,14,7C,D5,13,CA,01,5A,3D,61,34,2E,7C,6E,F0,30,FE,EC,9D,B5,50,DD,E1,24,BD,73,57,FA,CF,C6,2F,BD,B3,12,85,87,0B,77,53,5C,37,70,EA,E0,B8,D7,AE,82,35,77,17,3C,2A,A1,58,BD,60,92,6D,51,05,92,5E,7C,7D,2C,3A,BF,BD,7A,B3,B1,CF,32,F1,72,74,5F,78,CF,56,05,8F,A8,BF,89,C1,5E,AC,83,83,FA,27,6F,6C,20,68,8C,29,4B,C7,EA,BA,63,FA,FF,16,B1,19,38,4A,DA,B0,4A,C5,8D,EF,5F,C2,CC,57,9C,CE,A1,9B,BC,52,5B,99,89,A3,36,C6,F0,64,0F,AC,74,97,15,BB,6D,19,BA,AA,7A,CF,7D,9B,28,1B,A7,33,93,A2,B3,08,4B,A8,04,A5,8F,F6,34,6D,56,51,7C,A4,62,20,77,CE,78,BD,E9,B4,7A,75,56,7E,B1,3D,6E,0F,F8,BD,99,62,BA,E7,FD,3E,DF,BF,32,8A,50,18,22,51,84,F2,B8,E7,8E,A7,75,4D,98,6F,26,42,F1,76,22,B9,25,65,6C,D9,EC,02,F7,0F,C4,2C,52,17,EA,F1,B8,72,A3,D7,CF,13,CE,EB,7A,91,EC,15,A0,1A,A6,19,B2,77,83,82,F9,BB,DF,3E,9C,60,D3,52,10,48,1C,D7,5C,1F,22,C1,91,8F,09,14,10,0B,54,07,D4,B1,5E,12,BB,C1,20,D7,C5,E1,D0,DD,20,61,B7,1F,EC,15,33,52,66,F8,74,2B,EA,4A,D3,AF,04,2C,85,7A,0F,42,32,F7,59,89,52,80,8E,76,B9,EC,98,19,FA,A4,24,03,55,3C,A7,0C,B6,87,A2,93,CA,D9,7C,0A,AE,13,79,25,FC,D5,E4,C2,DB,8A,55,27,82,1E,AA,D3,D8,9F,2F,DB,6E,04,78,58,E4,07,19,85,3D,F6,BC,B6,18,33,2C,58,A0,E6,A4,6C,8C,28,1D,D0,2C,B8,F6,7F,A1,42,B2,39,E3,AA,81,D5,CE,00,EC,37,28,7B,77,3F,FE,94,EE,B1,1D,2A,B8,EB,88,3C,44,88,54,C9,D6,55,5E,0F,83,5F,62,8F,67,1E,AC,EC,63,80,B2,58,8D,84,9C,BE,53,33,C1,4C,38,36,9E,B1,7F,72,10,3A,F9,F0,A7,DE,DC,49,75,4A,4F,0E,C1,39,F1,9D,C8,08,1D,0B,10,46,9E,39,59,AF,FF,AE,B2,6C,BD,D4,64,20,B9,CE,A6,8C,83,9B,3E,C7,AB,A3,26,1B,FD,45,E4,DF,D5,E2,36,13,B1,2B,68,CA,5F,08,BB,BD,1B,93,AA,A9,FC,64,D0,95,55,4B,43,74,55,5A,BC,26,FF,43,18,C9,EA,77,9F,FA,A3,8A,7B,5F,35,69,9F,1D,4F,85,77,40,DF,74,79,F6,B2,D2,9A,EE,7B,DE,B3,0C,A1,0A,C2,FE,AC,AF,06,A0,AB,7D,3F,8D,E6,B1,F6,05,07,B4,83,77,00,A9,8A,A4,10,E6,27,FA,68,D9,CC,3B,99,24,1C,B5,48,8A,DD,66,DD,EE,0B,C6,D2,CF,CA,6E,B5,15,1B,48,0D,7D,65,28,05,F4,AD,D3,F4,D0,6F,E0,56,4E,34,EA,92,8F,01,84,5B,DE,75,34,C1,93,D1,CB,70,81,30,84,84,70,A9,A4,7E,AA,D0,44,B0,6C,BE,E4,B9,F6,4D,89,DE,39,98,77,E9,5B,E6,A3,0F,4C,8F,9E,DC,67,6C,8C,B3,39,9B,24,5A,D4,49,17,C8,5A,CC,BD,88,F9,45,7A,70,E3,18,34,BA,DE,6E,2F,03,BC,4A,43,8E,43,09,7E,E6,88,80,73,26,E6,F4,54,8E,BC,67,70,42,1A,16,74,50,A0,53,E8,53,68,F7,13,2B,B6,76,31,27,D5,11,B4,06,3E,E4,B6,FB,36,53,70,38,1F,BE,A1,D5,F0,99,E3,F7,47,99,A6,CB,39,68,BA,D1,5C,A1,2E,CE,04,3C,9E,8F,DE,EC,53,FA,33,6C,05,5B,F8,36,B6,50,7B,37,07,FD,9A,55,DA,5B,62,42,60,03,10,42,B8,84,A4,4C,D7,21,93,B6,32,7C,B5,FD,E6,B6,CC,DB,D0,1A,E4,B0,5F,2D,9E,FD,98,5A,95,B8,6A,0C,0D,15,A5,3A,A4,3D,D0,03,B5,F7,59,D5,31,21,52,FF,EE,04,40,5A,C0,FD,6A,A5,7B,C7,82,0A,A0,CE,A4,DE,ED,71,60,D4,6D,92,7E,5C,B1,FA,C0,F1,5C,C1,97,1C,40,17,0F,4C,D9,AC,12,77,06,BF,82,08,E2,94,E4,41,A9,7C,80,3F,EF,D3,9D,AB,D5,FC,F3,64,CA,94,C5,E5,3F,57,04,6B,0D,19,44,4C,4B,99,2D,0B,F7,16,39,89,45,A0,5B,A8,DF,24,1B,5E,15,CA,44,6D,20,B5,8B,46,44,AC,14,77,A9,90,FE,5E,B2,45,A7,D9,3E,81,69,FB,A1,AB,FA,3D,8B,EE,77,D1,16,23,B7,A1,90,2E,0A,69,DE,B4,75,C3,67,C5,24,D6,52,1C,D7,B3,51,E1,52,17,3E,CC,E5,30,C3,5A,10,CA,59,FF,60,BB,FC,39,75,2F,72,C3,3A,42,B7,7F,14,2C,58,F7,BD,F3,B2,D3,C2,CA,8A,C5,BC,99,1C,D5,09,0E,F9,24,62,57,9C,D6,B5,7C,05,33,76,7A,6C,4F,DD,55,17,C3,7A,9D,D0,B1,57,CF,79,B8,37,A2,5C,4D,7C,05,8B,0F,20,BF,5D,81,30,8A,EE,0B,08,A9,19,7D,26,4D,FD,57,5A,DC,23,D4,BB,C3,C4,BA,22,06,86,74,FD,CF,A6,7A,57,32,11,0A,A4,60,87,64,4E,AA,F8,82,D0,F5,86,DD,E8,63,02,36,13,4D,59,FA,CD,9F,78,58,5F,37,02,74,03,B7,05,39,3E,C4,71,39,BA,66,68,10,AF,F9,E0,10,4E,04,19,34,07,3E,D2,30,01,5E,53,02,4A,5A,02,E6,93,F5,F1,9D,BB,ED,0D,D5,3E,F0,69,5C,0A,B3,DB,31,DA,BB,41,B4,C8,AC,09,D6,7C,19,F5,C0,01,79,8A,52,B0,91,72,A0,3D,C0,AD,89,B8,AB,44,AD,05,C9,5A,97,3F,83,99,0E,44,41,DC,D8,8E,7A,51,9B,87,65,F4,1A,F9,E0,39,3E,AA,87,94,F0,00,F5,4C,75,82,04,B4,45,65,65,37,4D,8D,24,86,1E,D3,5A,8F,1A,06,20,AA,9F,CD,A1,98,2F,C2,22,54,0B,D5,07,C1,18,E5,5B,20,5D,A9,8A,15,47,4E,C7,45,37,9D,37,48,1D,E6,F3,20,CE,15,18,40,02,75,6F,1A,C9,EA,31,70,EA,0E,2D,FE,CB,70,D9,02,DA,2E,DD,04,ED,01,5D,26,4D,78,AD,A0,42,61,86,AD,77,1D,00,90,EE,A7,11,D2,28,AB,45,8F,99,A7,3B,54,9C,0D,06,20,D9,F9,01,E2,62,C6,3E,3B,5E,6F,48,02,18,9A,B7,DF,48,5C,10,03,61,2A,AC,09,E5,C0,3F,59,1C,51,D8,D2,B0,92,8B,E5,B2,15,4A,D7,E7,98,B6,EF,5A,9F,72,2B,5A,96,7B,61,CB,75,94,50,2C,A1,C1,FC,59,31,BA,56,DB,16,FF,98,4F,93,14,77,1F,A9,97,B9,E9,DB,34,3D,0B,73,0E,E2,4D,A5,CF,9C,0F,79,44,DB,D1,5C,76,0D,F1,F3,15,9E,CC,DC,02,5F,E8,9C,BE,14,91,FE,AD,3A,96,13,92,08,81,64,F5,38,D2,EA,E5,77,DD,F5,F7,89,C2,9A,6E,03,0C,66,90,10,57,FB,CA,7D,57,38,67,7D,9D,84,54,94,10,FD,9B,18,E9,F4,25,ED,B7,7C,83,B6,C5,73,75,D2,6C,82,6E,44,0C,2A,6A,E1,A4,81,F4,33,8F,AF,EC,F4,08,C3,E4,B7,C5,DA,B1,31,E9,67,97,2A,21,CD,B8,69,F8,9F,49,1F,93,40,97,76,6F,D3,F7,A2,0C,1B,DD,43,2B,6F,65,4C,69,37,8D,48,F3,64,D3,56,3D,B1,70,06,14,C9,3C,F1,46,5D,D8,08,7D,B3,D9,BC,0D,BF,0A,EB,D4,FF,89,A5,35,12,7C,DF,7B,48,52,7F,59,D2,B4,F7,A0,FD,5A,64,AA,BC,04,36,AC,8B,D3,FC,E1,35,95,9E,C4,36,66,45,03,56,D8,5F,71,E6,D8,21,D7,88,7B,34,79,CB,22,2C,B6,EF,97,1A,87,13,3D,9A,16,8F,E9,65,34,4D,65,14,5C,DF,1E,6C,7E,4F,71,FB,9F,66,F2,CB,C0,6C,14,EF,45,A5,B8,EB,CF,13,61,77,D7,D2,88,8C,1A,29,34,83,78,6B,97,75,B3,B3,5E,B3,24,5F,88,4A,2C,84,A3,66,AD,EA,F3,72,62,A3,41,07,90,76,B9,CC,32,24,23,71,14,11,FC,81,E7,6E,2F,EC,CA,35,DC,F4,0A,29,BC,C1,73,14,93,95,D6,6D,CD,ED,D1,D2,40,45,7C,8F,31,96,A7,3A,AF,EF,12,4C,B8,E4,DB,4B,51,55,42,FD,36,9B,AE,0A,07,CF,23,62,07,31,25,8D,B9,87,4B,DC,C3,E9,88,39,55,B2,A7,3D,A8,AB,E0,C7,56,E8,0C,DC,B1,F3,6E,D1,16,DE,B0,94,69,F3,41,A7,9D,5F,05,6C,F6,DD,D4,1B,99,69,65,27,4B,70,2B,04,41,58,E6,72,FB,B9,3B,68,FC,73,B9,CF,E8,06,2B,3B,78,55,64,E5,AF,64,D6,5B,43,90,B9,C9,79,8A,68,4F,33,D3,D6,6B,0F,1A,ED,04,AA,D6,70,74,EB,3E,95,1C,4A,9F,93,2D,F3,BF,9C,BE,26,E2,42,35,D6,9F,9D,6B,DA,1E,E1,49,4A,D1,97,0D,C6,B4,8A,71,47,2E,2B,0B,50,D1,01,DE,CF,CB,DF,60,43,80,77,1B,20,70,8F,8D,23,DC,B6,A1,21,21,4B,C8,14,E7,3A,40,72,C3,49,77,B2,76,6D,59,61,C4,C7,38,7B,D1,03,B8,5E,6E,22,9E,1A,1D,5D,D3,22,25,13,52,61,C6,44,12,00,76,2E,50,D6,78,12,C3,C4,69,C8,4D,89,B1,AE,14,8B,19,B2,F7,6E,6C,66,78,A0,9D,4F,8B,BD,20,AB,0E,0D,FA,75,EA,DE,84,09,C1,CB,B1,D7,05,8B,EB,FA,D4,DD,9E,29,BE,3F,03,EE,57,D7,67,87,CD,4D,82,A6,19,A3,F8,F0,8F,F4,BB,A7,53,4B,C5,FF,5A,4C,8B,F5,F5,B3,3F,E3,22,FF,02,37,7F,61,49,F5,E5,0E,08,7E,15,9A,CA,06,BF,AE,48,0B,CB,93,79,C4,71,F4,52,BC,81,6F,4D,0D,A4,04,32,79,DD,9F,64,38,59,35,83,67,29,7C,BC,07,E6,28,9D,DC,8F,7F,8D,2C,25,17,1B,FD,D8,6B,53,30,2B,EE,33,47,70,05,DB,7A,8F,17,5B,57,30,D7,7A,24,4A,03,7D,AA,25,4A,AE,6D,CD,3F,DD,3B,E9,F7,89,60,6E,5A,F2,1F,FB,F9,58,C0,88,FF,AA,A8,72,00,9C,F7,CC,CB,8A,51,66,6E,77,22,50,B0,AB,77,FD,C5,6E,F1,74,21,78,43,D1,52,3F,CD,39,10,07,95,F1,2C,D6,CA,8C,41,8E,E2,F6,C4,E3,60,7C,CD,DB,F0,CF,A0,61,9F,08,B6,DB,91,BE,60,B4,A7,4D,82,D0,CC,EE,5B,CA,70,B9,63,94,6F,15,72,B8,7C,DF,96,16,87,5B,6A,04,16,DB,DA,F6,9B,9A,1E,68,A9,CE,63,BC,40,7B,07,A9,45,2B,18,60,6E,1E,91,80,B7,F6,E3,60,04,1D,7A,C4,32,BD,AC,EB,4C,7E,1B,1F,FC,E6,87,51,CA,58,6F,4F,BC,0D,F1,BF,08,5E,50,16,E0,86,3F,82,F4,FC,A3,B5,EA,4A,45,94,34,64,29,A9,87,33,15,8A,72,0F,0B,E6,12,D6,EE,DF,B4,FD,98,53,F1,71,02,02,9A,88,26,C5,90,C6,8A,AF,50,EA,AD,07,0A,7C,90,E2,5C,0E,CA,1D,A0,27,D8,1E,68,2B,F0,62,44,FD,4D,06,9C,4F,06,04,A4,CB,96,93,AE,F1,72,5A,77,7E,92,62,99,72,18,7A,DB,69,28,9E,08,D7,A8,0A,28,1D,92,63,3E,71,08,5E,18,87,AD,20,D2,F2,2D,25,FB,57,56,47,E0,EB,43,FD,4D,B3,23,CD,12,34,BC,BF,3E,83,E2,AE,B6,E9,C3,9F,0B,AF,4F,EF,3A,3B,0A,CB,C9,1C,F4,5B,54,A4,5F,C6,A2,47,E3,1A,E0,23,C8,3B,B6,8B,5D,B7,97,AD,88,65,E1,AA,51,55,EB,4F,D6,14,F5,09,94,BD,92,8D,40,DA,CD,5F,DC,E9,82,CE,17,7A,CB,0D,1B,2E,63,D9,30,4D,53,CB,1D,1A,20,6A,D4,A2,C5,33,84,BE,07,B1,AB,53,E9,C2,5A,FA,B3,66,5B,D7,70,FC,12,AF,0D,C2,03,19,9B,34,FC,CE,04,0B,75,44,65,8A,83,FE,5D,BC,CA,F2,8A,1D,22,18,C4,6C,C5,CC,5B,89,07,F1,29,9F,45,CB,99,02,D6,2A,A9,8E,B0,D7,2E,6F,41,3D,88,3B,7F,2D,E4,E7,8F,3D,93,1A,A1,4A,4B,EF,64,11,1D,2B,CB,E9,A3,1E,8D,21,22,E8,67,A7,7F,80,0B,43,DD,B8,C0,BE,9D,A4,7F,22,AB,38,6D,AE,22,15,17,91,D1,98,2E,5A,73,E4,53,85,39,8A,6B,C4,56,39,98,07,61,ED,DC,EA,4D,06,8D,BF,9D,EE,62,D5,6A,85,C1,33,04,BD,D2,7D,8B,22,F1,1A,79,8B,F6,DF,DD,70,75,BE,CA,52,14,5F,30,83,52,F9,77,9A,3E,DC,67,B8,20,EA,2C,5E,81,4C,16,20,EF,47,A3,16,86,36,EA,16,5C,0E,FC,A7,14,4F,F4,AA,57,C5,4A,8D,D4,41,9A,C7,7B,74,23,4C,3A,7A,79,06,A6,05,74,CF,9A,87,58,9F,3A,2E,3A,88,9D,2B,3D,80,CA,82,1F,20,87,E9,B8,2B,A3,78,C9,93,99,4C,70,6A,01,AB,B2,77,11,E2,73,19,F5,DE,DE,A4,FC,12,E4,EA,AE,71,CB,B4,31,1C,D1,90,F9,20,52,CE,02,E8,66,95,C3,1E,12,60,80,D7,3D,D5,48,5D,E2,A8,8E,2F,D9,B8,09,48,9C,2C,53,29,EA,9F,79,84,E9,1C,2C,03,87,0F,85,C6,FA,92,FB,51,A6,EF,C6,76,C7,9B,A7,9D,DA,F2,58,1F,2D,45,13,54,6B,E7,32,3F,66,60,F1,C4,8D,E1,2E,48,0E,03,3C,7B,8B,11,A6,84,E8,EA,37,8E,68,5A,D2,B3,1B,22,BD,09,AF,F7,BC,53,62,B3,AE,5B,17,07,37,D7,DF,0C,CD,D0,DF,2E,D6,FF,32,31,4D,5B,37,6E,E9,24,E9,A1,5C,4F,60,F1,96,0D,D5,4C,D8,FA,99,7F,1C,C1,36,34,53,8D,9B,2D,A8,3D,06,0D,12,2E,56,5D,8B,0E,15,4E,DD,BB,44,67,33,52,19,CA,EB,70,63,CD,FB,18,B2,91,BA,99,45,67,A6,A2,FB,AA,1B,02,EF,46,3F,C7,7E,50,0C,D3,F4,3B,AD,F1,BB,73,94,4F,05,3F,31,FA,C8,41,0A,9E,74,E6,A4,F0,F8,FD,7C,DA,F4,3E,A3,A3,E1,DF,DC,FF,CA,B7,14,34,02,73,A8,3D,3A,1B,DB,19,BD,0E,8C,7F,FE,E7,5E,E7,9D,2F,C7,B0,B6,E2,3C,63,34,75,44,15,36,A6,96,E7,F5,9D,20,46,23,D0,4A,CD,23,71,6F,F7,0B,58,DB,7C,1F,F2,D3,08,57,87,39,79,94,EB,A2,44,31,BE,CD,AF,AB,75,F7,7B,57,E6,45,00,85,F4,40,E8,78,B1,2F,1A,3E,94,0B,80,88,E5,44,DF,4F,3C,45,B3,B1,DB,66,5C,DD,D4,30,41,02,72,8C,74,46,CC,1D,56,2E,A2,19,33,D4,E9,E3,9F,BE,D2,9E,1A,8D,3F,0C,EB,63,D5,A7,63,7E,4D,5A,C4,71,89,4F,AE,67,EC,27,83,95,57,09,7A,F9,3F,04,18,5F,B7,C1,33,84,22,12,31,14,1E,A0,2E,D9,7B,C8,01,60,C2,5D,08,94,C0,43,A2,02,D8,21,21,27,F7,36,59,E8,3C,1B,6D,A0,AE,C7,5F,42,44,B4,51,53,2D,E8,25,66,20,77,63,58,AB,D3,14,F7,9F,F4,19,08,E0,D5,BE,31,CE,FE,D3,A2,28,53,55,76,58,C9,AD,65,0C,F5,DA,FC,02,49,E0,27,B5,F0,8A,E2,4D,3D,A3,4F,8C,31,BF,30,07,60,DA,18,7D,A1,69,8A,6A,24,6D,95,2E,E0,E8,F4,C7,29,6F,C4,F4,47,A8,A5,60,11,82,D7,0B,B9,2A,3F,02,CB,D2,F2,1C,E9,D1,D5,42,2A,9E,6F,9E,FA,5A,A9,B4,06,CC,D1,23,8E,E3,E7,43,52,1A,DA,7E,00,16,D0,6E,A1,F7,67,E2,49,BC,A3,BB,AA,0E,EC,98,6F,9B,72,8D,E9,14,E1,38,8D,BC,E8,E1,F1,46,90,CF,DB,69,77,0D,50,2F,E9,6E,E7,42,F7,9D,31,39,53,B1,1C,07,77,00,EA,47,3A,6C,50,AA,B2,E8,2C,FF,7F,9B,98,94,0D,D0,9A,2A,1C,28,3B,59,D3,42,61,63,58,41,E6,A1,0F,9E,32,B2,11,10,69,6F,14,F7,7A,18,DB,EA,15,B0,EA,14,9E,EC,A9,F7,14,3B,8E,87,65,62,C0,3E,D8,9F,C2,D4,D3,F7,31,AC,FA,A0,11,3F,0C,C7,A3,7E,8D,47,ED,65,26,92,CD,FE,E0,B2,BC,26,94,9C,99,73,BD,3E,B3,4A,A7,7F,FC,C9,4A,71,9D,1C,E6,E6,78,CC,E9,8E,1A,FC,7B,DE,DE,5F,E1,E2,79,48,A1,04,61,4A,3A,85,FC,70,EA,3A,BE,43,2F,F2,CF,61,2A,FF,1D,14,8D,81,17,3C,0A,1F,26,61,72,84,DE,E4,39,C8,A5,F9,A6,7E,46,E4,D6,12,47,3F,1B,F7,7D,67,BF,18,46,9A,25,96,51,7A,34,04,91,95,09,E1,0D,69,2C,25,6C,59,8D,D0,5D,42,6B,90,AD,84,FF,14,32,61,CF,0D,B9,A1,5A,23,D9,5F,49,A1,88,0F,D5,28,14,B8,9D,BB,33,85,3A,E8,89,EC,AD,BC,39,6B,AF,55,49,42,64,6F,95,E4,36,CC,6F,A1,24,F2,A3,A2,CB,CC,51,9A,19,37,E0,E1,47,83,A9,9D,6A,53,A2,19,37,D8,0F,E7,1D,FF,08,B8,F3,A0,A4,08,7E,27,A2,75,2D,EA,23,D4,76,EA,60,A1,16,3C,3A,3B,88,A3,AB,EE,A5,C1,EF,9F,F1,EA,56,32,B1,F2,11,A1,EC,CC,29,0C,1C,4A,DD,8F,9A,F9,C2,0E,0F,53,27,34,00,EC,50,5D,B6,2D,26,D2,FD,A8,CE,AD,16,C1,EF,42,AD,EC,19,F8,B4,69,41,4F,D4,60,9F,44,48,37,0D,39,41,CB,4E,AF,A9,CA,ED,97,93,4D,1C,6F,7A,C7,62,ED,63,BA,D8,23,94,29,58,2F,12,63,9B,07,A7,BA,E8,7B,AA,6D,48,E5,72,9E,41,77,72,6D,6D,E4,09,1C,90,96,A7,10,60,A5,48,52,68,2C,79,97,26,0A,FE,F4,DC,1E,94,86,28,89,EB,26,15,65,A7,7C,81,03,09,D5,FD,8E,10,97,DE,96,1E,CA,B0,48,98,CD,BC,0C,63,1F,4A,5C,3A,45,EE,01,37,43,5E,37,0F,87,D9,11,60,D8,6F,5B,63,27,A9,55,58,C6,BD,F8,7C,D5,B6,0E,1D,FC,62,15,BE,CF,B9,70,01,23,21,56,44,37,EA,E3,8A,32,7F,AA,85,31,29,38,A0,AB,4C,FB,F4,73,1E,75,63,9A,19,1F,7A,0D,FB,B7,B3,22,BA,9B,99,26,07,F6,0A,29,80,82,F5,43,FF,95,56,05,37,17,4A,6D,13,92,9F,8E,C7,96,51,42,BC,13,56,14,84,98,86,2A,CB,CA,0C,06,69,F6,4F,30,40,B6,C2,1F,17,AD,B2,E0,C1,CE,C1,6E,79,ED,78,64,64,2E,20,30,B8,B0,78,CF,6D,6A,6F,6A,74,FD,EF,C4,B8,B4,26,C8,A7,4C,67,9B,27,63,0C,B9,54,DF,59,EE,88,5F,39,DC,C0,3C,50,B8,FE,C1,3B,35,8F,0B,11,DD,E3,0B,EC,A9,B5,AB,E8,9A,B0,A5,CA,48,A5,38,35,F7,A3,33,98,C6,7D,3C,B2,8E,72,BD,D8,AA,88,65,C7,AF,F5,5E,2D,7E,54,81,7C,19,6D,3E,90,80,C5,CD,45,63,C1,A0,3B,DA,E3,C4,C7,07,87,4B,27,B8,A0,2A,27,8B,1D,F9,28,8B,44,88,FA,92,FB,98,60,4A,1A,D8,84,2B,A2,8E,38,3B,ED,0E,C8,35,E9,1C,31,B6,FA,06,6F,21,4E,10,17,18,D5,7B,7E,A4,6F,84,AA,2C,EB,1B,27,A1,65,C0,B0,B0,6A,06,60,F3,C2,45,7E,0D,61,9E,8B,E9,B3,1D,5E,84,36,5A,98,D3,4A,01,5E,2F,81,F0,1D,9D,BF,87,55,CB,32,A3,47,5A,CC,F4,18,E0,EC,CE,C0,FC,C2,3C,3F,76,1F,BB,0C,61,6A,D3,B7,71,0D,5D,A0,27,A9,9B,35,3F,B9,AC,B4,DC,25,85,40,33,EB,2F,F5,86,62,90,5F,08,53,CD,B0,E5,2D,7D,99,C8,C5,5A,4C,CD,C8,B8,26,52,9B,D5,38,3D,CE,09,AB,2C,1F,B6,D9,FA,16,3D,1B,1B,0F,47,20,92,8B,3A,DF,11,37,2E,72,16,59,12,1A,76,9C,5A,C5,CA,C1,63,5F,BE,EA,1F,58,37,36,FD,45,DF,DE,3B,13,EA,89,8C,C4,41,C4,0C,C7,D7,D2,0F,D8,69,3A,DA,6A,E4,C2,F2,41,85,10,30,4A,BC,86,65,91,31,8D,53,46,3A,6D,4A,87,34,5A,02,43,04,4D,F5,7D,0E,5E,BF,BC,79,A4,AD,A2,AB,5E,5B,7A,E9,F2,77,8B,44,E3,32,C8,6B,56,C3,22,33,26,F8,97,D6,71,0C,B8,5D,38,F1,C5,E5,6F,FF,88,69,9D,52,D4,39,24,31,A6,B5,4A,CD,46,1C,61,39,5C,65,2F,0C,47,8F,76,CC,78,01,51,F7,8B,6B,BB,01,3C,0E,10,DB,6A,EA,A4,D8,99,9A,4B,2B,F9,BD,18,2B,83,76,48,50,91,E8,2F,3C,09,53,A7,A3,76,E9,F3,61,CD,6E,3B,D7,B6,A3,4B,2B,13,A0,23,08,59,61,6D,10,D4,4A,6F,B4,56,D3,37,52,4F,5F,85,74,43,77,97,00,8A,B4,AC,E8,A5,6F,0C,68,7C,34,64,EC,16,D6,06,50,2D,11,D4,D8,2B,B0,D2,06,39,79,40,74,25,85,CD,F4,4D,A9,31,CF,CB,29,A1,12,3C,75,63,DE,A7,35,2B,AD,3C,8D,9B,07,FA,7B,C9,81,AE,19,DD,8E,43,91,20,7F,CB,35,FA,03,36,0B,88,B0,C7,F1,31,03,25,DC,BC,3C,08,85,05,23,93,7E,D8,F8,26,F4,7B,42,0B,E7,B6,03,D8,4E,8A,F5,16,58,DD,9B,00,14,E2,23,6F,53,53,CC,0B,82,4C,8D,9F,A8,E8,E1,89,A8,B5,B0,F4,51,C1,A7,B7,ED,FD,DF,0E,78,1B,56,AF,01,6B,70,BB,01,A0,21,48,E1,D5,28,F2,21,0F,A6,FD,BF,74,2E,FD,A3,6C,08,4A,64,2E,5E,0A,60,2D,53,14,40,B2,E9,29,A9,6C,9B,3B,02,C7,1F,02,39,15,D7,68,0A,98,CD,0D,7B,7A,A8,93,7C,6A,60,73,81,95,D6,F4,63,0F,97,F5,98,71,A5,84,1F,4B,40,38,EE,8F,6E,19,4C,25,F2,54,1D,40,F1,64,E4,40,D0,84,E6,3B,60,76,A5,9E,E2,E8,7D,42,A5,ED,17,DA,C6,79,13,88,B3,75,5D,5B,79,74,DF,0D,54,48,BA,35,9E,E5,4A,85,4C,0C,E7,C9,D7,CC,2B,AA,44,48,94,B1,3F,06,30,A5,D8,16,92,B6,A5,C2,C2,CF,BB,0D,47,59,83,75,9C,82,42,E0,9A,E5,78,DD,03,87,EC,83,3F,96,B1,0E,31,ED,75,1B,AE,9F,77,30,5B,92,8C,1C,5E,1F,38,89,3E,66,1A,2D,77,DE,25,E1,72,F8,C0,F4,44,E1,C5,0C,FD,26,BF,41,63,CB,85,A9,FB,4D,CA,6A,BA,6F,E9,34,28,8F,2D,14,2D,26,D2,CC,E4,22,DA,21,29,6D,73,56,4A,55,CB,30,75,C8,E7,0E,15,B1,21,A8,24,38,3C,ED,63,C2,13,4C,5E,5C,8C,5C,5B,10,69,C6,B9,D7,63,20,45,9B,06,89,03,92,A1,CD,70,E3,24,CF,F2,F1,B8,C9,7C,4E,CB,6F,17,3F,5D,1B,A8,E2,A3,BC,98,94,07,61,44,F9,41,88,66,FF,7D,24,F7,DB,F0,85,CB,20,45,7B,85,B4,E6,DD,52,DA,AC,AD,CB,74,33,E4,78,2D,F3,76,AC,A2,B6,2B,BE,4F,54,B9,42,7B,42,4B,F0,DE,83,5F,62,CB,D8,2B,D7,F2,E9,21,AF,1F,C1,3F,C5,C8,07,A3,19,DD,D4,80,B0,F8,E0,6A,68,48,56,13,87,5E,12,E0,53,DF,70,24,D4,1D,7F,55,70,AF,61,26,92,EC,79,C8,B8,09,12,44,52,6B,51,5B,4A,93,4A,80,72,10,0D,7D,25,17,42,14,28,70,BD,FF,8A,9E,41,60,6B,02,4B,C4,C2,99,6D,F1,7B,C3,63,82,ED,18,30,F4,C4,63,81,68,39,94,DD,C2,E6,F6,CD,6D,F8,FE,22,E7,2C,24,31,38,31,0E,DA,D4,68,7A,4C,02,3A,4F,3F,BB,90,D7,32,B6,15,92,4E,96,B8,79,B6,BF,7B,8D,12,D7,AC,36,88,67,41,BB,4C,2E,86,50,93,C6,33,B6,6C,03,1D,BA,17,FE,BC,39,B5,6C,03,B6,AB,90,E1,15,64,59,3C,AE,44,63,61,84,C9,64,74,4C,AF,3F,E6,33,FC,AE,F0,A1,33,82,2E,10,BE,75,E6,5E,BC,92,62,6F,20,E3,29,4D,77,3D,4F,76,DF,03,92,E1,F4,D4,FB,E6,40,15,D6,BD,D4,53,D6,F7,52,99,38,12,DC,BD,06,06,73,12,77,FD,07,2F,A7,38,0A,4D,A7,F1,DD,C4,E6,B6,08,E8,2F,BF,A0,A7,F3,1A,1C,E4,33,34,05,AA,4A,14,69,28,34,37,52,80,3E,E4,E8,67,22,D2,E4,91,54,67,82,A5,E8,63,91,D6,8D,C4,84,39,A1,57,21,27,BF,0E,DC,91,BA,12,83,CD,36,8D,E7,CB,42,8D,5E,7D,B1,AC,3D,E8,C7,F7,F2,16,06,C0,B8,BB,3D,74,54,0E,3A,D7,F6,D3,B9,89,C2,D6,59,7A,B0,51,F8,38,03,FE,A0,CD,E9,3E,4D,C6,79,43,48,FF,2F,1A,D7,0B,DF,EC,31,22,1B,61,E6,B0,15,3F,8A,B3,68,0B,82,52,7E,9D,3C,A9,C2,65,37,BD,42,37,DD,44,24,BF,E2,5E,BC,3B,5E,43,0A,39,5E,23,1B,93,53,79,06,4F,21,8D,D2,6E,74,E2,E9,D4,3A,50,C9,EA,63,58,27,EB,9D,AB,41,A1,EE,6F,0A,18,1F,C4,BD,16,17,D6,75,E3,01,17,CD,9B,0B,8C,D9,E3,CB,66,BE,84,C9,38,0F,71,1E,56,B4,8A,CF,E6,25,97,11,BA,28,9F,B0,11,9D,C7,FB,B1,FC,9B,52,25,12,E3,C9,23,C0,80,DC,11,E6,AF,2C,DA,DE,A6,85,E1,FB,09,20,5E,73,A5,D8,7F,67,70,8A,49,25,C9,5E,3E,F8,28,DE,39,5B,55,CC,90,F9,E3,1F,07,B9,EE,63,14,34,A7,B4,A5,B7,8E,E7,D7,94,DC,B6,E6,16,23,8E,D9,D1,01,A6,30,AA,EA,38,2B,7F,84,E3,04,F2,AF,8C,8F,C0,84,A4,9C,62,5C,98,4C,E4,7C,43,80,A2,7D,71,F0,1D,71,57,F5,AA,ED,60,B0,DB,6E,AD,57,73,BF,C6,14,22,00,40,0A,DE,65,70,1F,B7,C3,C0,CA,98,A4,6E,FB,48,96,05,D6,1E,31,F8,F2,0D,D1,2D,02,82,8D,0B,29,80,18,F9,30,97,8B,69,7E,06,FF,B8,70,03,E7,B4,EB,D7,A9,63,22,CE,38,CF,88,FB,A7,5E,0A,80,2D,BC,2A,5A,CF,50,0F,53,9D,B3,FB,7D,EA,BA,9D,2C,9A,B3,60,C6,6D,56,DA,5B,80,AC,3F,DB,0D,79,C5,31,44,3A,FD,D7,20,D4,E5,E8,2B,E5,FD,45,9A,03,4E,20,79,4D,3A,13,EF,49,66,21,8C,56,33,82,0B,33,17,54,11,F7,02,9D,01,CA,0B,C4,98,E2,16,60,B0,68,92,07,36,20,75,40,3D,10,CE,F9,89,60,20,B8,34,ED,19,0B,AC,53,12,7E,F5,AF,DD,47,AD,AD,B9,AC,CE,0C,38,D5,64,66,21,41,5F,03,AC,6A,FB,26,90,BE,6A,4C,79,28,C4,86,F7,B0,27,96,A8,C3,DB,B1,EA,C8,0A,62,4E,73,A6,99,07,66,2C,7F,2E,E8,23,75,34,D3,D5,07,D8,5C,8B,5F,8A,F0,2D,4B,9F,4C,8F,9F,6C,6A,37,A9,0F,D0,9D,1F,FE,5E,B0,07,3E,F2,06,EF,C7,32,04,86,7C,26,BA,99,36,D0,F3,26,16,C7,87,FE,F4,9E,D7,C5,CF,4C,90,97,3C,12,7D,DE,E3,7A,ED,25,C0,38,6A,C3,BF,83,85,33,2B,DD,25,C6,63,EF,C5,F9,33,9C,E7,50,CE,0F,79,AE,2F,A6,B4,E1,08,66,D6,57,12,3D,42,57,95,2D,28,D8,07,9E,44,4B,2F,E9,FB,78,45,36,8F,F5,54,0A,9D,58,51,C0,43,60,DE,4B,18,7B,B8,23,02,0B,9C,9F,3C,01,F1,AB,15,1B,66,C0,FB,42,A8,53,37,74,00,B0,AC,2C,BA,41,03,60,1B,E4,2E,87,60,A0,B3,F1,91,E9,1E,32,52,EE,0A,AF,A6,49,FD,15,7B,55,3B,32,4A,A5,1A,A1,00,F4,75,35,E0,49,E8,E0,34,5B,CF,C0,B3,4B,33,3E,F9,5E,F5,A0,E7,7F,41,1F,C7,B8,D3,16,B5,B7,8A,48,CE,C4,DA,BB,2F,34,40,12,2D,C3,32,93,A8,9B,1E,FD,EE,60,36,8A,20,06,B9,54,E7,C5,81,F8,14,5F,64,1E,26,71,FC,3D,E6,AC,43,4B,1D,36,3F,3C,14,C0,AF,20,45,4E,FB,C6,8F,89,A0,CC,0B,7A,CC,F0,7C,B7,FD,61,BC,F1,83,74,41,FE,7F,67,A9,9E,1D,D5,93,13,1A,88,74,A8,C7,F5,22,E8,73,06,6D,55,AD,2E,08,FD,15,67,AF,C0,DA,E8,8A,61,A1,B0,63,0E,CF,6B,4F,F1,0D,BF,62,35,66,0A,5B,13,3B,18,5F,41,F2,8D,35,AF,3C,EE,0A,79,3E,3B,EB,C0,5C,A4,F4,73,1C,4D,E6,0F,39,87,AB,80,45,7B,8A,14,26,1E,95,86,C3,5C,FF,60,7C,EE,8A,6E,1E,2F,14,83,BE,D2,02,0C,A8,7B,C3,47,27,78,76,7C,12,A5,E8,B0,8B,08,56,5D,C3,80,D2,34,19,52,6F,EC,E5,89,C8,6F,63,12,F1,6E,E3,FB,58,CE,C4,19,79,C2,F3,CE,39,6D,B4,3A,F1,89,F1,E1,80,C1,69,C4,7C,D2,40,CC,50,CA,39,B2,41,04,18,90,47,4A,8C,DD,0C,A5,14,98,D9,A7,38,BA,6F,49,A6,88,9A,7E,F4,96,80,F4,3E,4A,FD,20,B9,1F,2D,2B,43,30,BA,16,87,B5,2C,C4,02,46,0B,E4,AC,05,93,64,F1,C5,F4,EF,75,06,81,3C,65,84,C9,03,02,A9,1F,15,78,46,05,23,43,BC,EC,83,67,2A,0C,8F,6E,B6,AC,5A,69,5F,0E,D4,1F,85,59,CF,52,C3,CB,F6,01,FD,FA,28,15,F2,AC,4D,03,31,AD,06,36,C6,35,87,77,79,B9,D4,BF,5F,FE,5C,65,88,99,40,9B,5E,6C,AD,45,EA,3D,DC,A0,9F,CC,44,39,72,45,5B,25,44,B2,3E,FB,AA,6D,CD,38,B6,29,A0,66,33,1C,3C,EA,F9,56,BE,3C,B5,78,55,06,DA,0F,B8,7A,59,7B,84,FC,6F,57,9B,30,68,BB,66,5E,A9,6C,FD,B9,5D,D9,69,2F,49,94,53,94,EA,C8,20,3B,59,A1,DC,FB,22,F8,57,95,0B,49,3F,FD,D7,27,FF,81,40,1C,98,BF,9A,0F,07,5B,AF,2B,65,53,3A,92,FB,B9,15,D0,2B,25,28,71,B6,40,37,B8,0C,C0,90,6B,C4,A9,9D,F7,14,A6,01,86,54,D8,26,A8,7A,C0,B6,36,06,8E,84,46,A1,EC,6E,AC,87,6F,3D,B9,6C,E9,47,1A,75,E6,E1,4C,D7,48,5B,42,07,04,AB,A5,47,2F,12,6D,CD,FC,EA,86,9E,82,C3,13,07,A9,0B,9B,F1,BD,BF,9D,44,26,82,81,6A,3E,5A,AB,E8,E3,55,55,8A,61,A1,79,08,AD,90,71,3E,CD,7D,56,7A,33,66,58,5A,0A,DC,75,A3,13,11,EB,D5,2A,95,E3,85,1D,97,32,32,1F,B1,64,6A,15,C0,C3,EF,AA,8D,C0,6E,7F,DE,83,00,83,CE,B8,3B,57,DC,A9,1A,01,94,76,7C,6C,12,83,23,C5,E1,D5,74,EA,3F,F9,8A,0D,68,41,BA,41,5F,55,BF,2C,4B,6E,52,04,8D,AD,3F,BC,95,97,36,7C,6A,13,BA,DC,65,95,3D,96,3C,5C,6F,14,72,B7,9B,B7,43,B8,2E,5D,C3,72,7C,9A,C6,00,4E,8A,FF,AB,5B,7B,AA,28,D3,21,31,1A,63,C9,5C,0A,99,16,76,71,A2,A0,34,CE,C0,07,DE,C4,10,D7,7C,CB,DC,C6,18,31,01,85,9A,FD,10,86,27,FF,E2,42,83,26,2B,6F,58,79,76,31,9B,CE,0F,9F,6D,FF,F9,81,B8,35,8F,2A,3B,5D,B6,E6,C3,AD,3C,F7,CD,9F,11,4B,BB,B6,CB,FC,4E,6F,4B,23,84,ED,81,B0,1F,92,5B,D4,B6,D6,E0,F7,99,0C,8C,36,55,18,5C,F2,B7,13,56,0E,4B,35,01,0E,92,34,23,69,40,71,FE,22,94,28,DD,AA,C9,D2,12,BB,C6,8C,ED,BD,95,95,9D,1D,19,9B,D9,F1,BE,4D,F0,D6,97,82,2C,28,21,CC,82,28,0B,E8,58,96,97,0B,72,30,1E,E2,65,66,85,28,5F,50,AB,52,0A,C1,AB,BE,9B,6E,A3,F8,D7,EB,F8,6E,D3,22,04,67,50,B5,03,63,B5,55,3C,46,9C,29,54,4F,10,D5,A1,98,38,8C,D6,80,90,6F,7F,B7,B0,87,0B,76,CA,1F,3B,0A,AB,6F,6A,ED,17,6A,0E,30,7C,89,F1,24,C2,7E,93,8D,88,06,E7,C8,98,70,68,6D,BD,C3,51,83,C1,5D,B6,8F,25,BE,56,70,45,33,10,F8,5A,FC,7F,6B,EE,47,39,3F,CE,41,9E,F7,09,4C,C1,47,B9,37,67,65,44,65,D4,16,B4,2E,24,56,7F,80,9D,0F,7A,18,F7,CD,E9,03,8F,A2,9E,EF,06,DD,26,CD,F4,9F,C7,6C,5B,7D,FA,7B,AC,03,8C,AA,38,C8,5F,D2,4F,3F,E0,0D,84,12,C1,E4,A7,BA,DD,7D,AA,1D,05,FE,E5,91,B4,50,7B,B0,DB,ED,14,BD,5F,21,C9,80,72,DD,8B,E8,0F,EB,CD,C5,2C,8D,D6,34,30,26,59,58,A6,10,BD,BC,C7,49,73,92,F2,9F,46,00,3A,2A,2C,52,0D,6C,4F,D6,F6,2C,1C,C9,EF,4B,1B,99,F6,6C,33,39,A4,44,22,8E,23,7E,6A,93,66,86,9D,B8,E9,AA,59,40,DF,E5,4B,FF,F3,CA,88,ED,D4,7A,22,BC,62,2C,C0,1E,A5,B6,77,92,81,A3,AA,7D,85,0F,95,78,BC,A1,D0,E6,E6,E3,37,DB,F6,DC,CA,7B,35,06,57,4D,0A,C7,ED,7B,88,D6,DD,81,B4,02,F7,59,FE,92,2C,94,37,BB,B7,94,2B,63,DB,2F,91,84,C8,8F,0B,92,05,C3,79,CD,9E,42,59,C8,F1,A0,1A,8F,64,6C,F1,AD,B2,91,19,E5,03,E6,39,66,DC,57,86,E4,93,70,EC,E7,D9,24,92,45,56,34,F4,20,68,77,BA,D7,68,C7,BF,C2,A6,23,8B,6E,DD,45,43,E1,E3,51,4D,63,52,5D,15,E0,C2,80,89,2E,FD,7B,C9,9F,0B,85,3B,DA,0F,BB,A6,43,3B,F0,77,7E,94,6E,62,C1,30,F0,2B,E0,E7,9B,39,EF,B2,C8,5C,1A,C8,54,30,E6,59,74,88,DE,23,BD,D4,92,BA,51,53,8F,E5,B1,60,2E,77,C5,35,66,97,DD,A3,9C,DA,DE,08,A4,6F,92,D6,5C,14,3C,A8,CA,F0,20,0A,77,B5,90,5F,FA,1C,B3,18,1F,B2,72,7E,56,C4,8F,14,9E,11,22,6E,CB,A5,89,E9,50,56,CF,F2,90,1F,A0,9E,1B,24,F2,BB,BD,DA,E0,D7,77,F6,91,E2,0D,5D,5C,F4,C8,A6,C5,F3,44,6D,10,8A,D6,B0,55,DD,AA,1D,4D,47,7A,07,6D,39,C0,B4,50,D7,CB,F5,C5,B6,A1,BA,EE,DA,61,72,5F,C0,D5,EC,F0,8F,6F,F6,18,9E,1E,A7,06,3E,C7,EB,3E,D9,17,57,9B,13,28,A0,DC,05,04,7F,AD,AF,6B,D8,F8,10,78,B0,F1,44,44,B0,69,D0,AF,7C,2B,3D,BA,D5,04,C3,CE,F6,BC,CD,AD,A2,1C,AC,DB,CB,E4,DC,10,29,8D,E1,03,1E,25,D3,BA,18,CC,BA,7B,B0,F9,2F,5D,1A,BD,CA,A8,8D,B9,72,44,9D,2F,A8,EE,DC,F3,76,A4,0F,A5,71,31,95,2E,E8,9A,5D,84,D7,B0,40,94,1D,F7,3A,4D,D3,08,2A,1A,CD,73,14,97,3C,88,4A,4C,4A,5E,38,AC,E3,11,14,63,47,58,69,CB,B7,67,F6,CF,15,AA,F6,05,14,0B,B4,C5,40,9F,19,9E,C7,06,1D,C1,68,E8,85,32,41,9F,F3,56,66,1B,55,57,2F,38,2A,57,D6,FB,5A,8E,15,09,70,83,8D,E8,4B,AA,D8,9B,C9,17,D1,88,FC,F2,9D,8A,DA,E1,D6,85,E1,4A,1E,8C,F3,D2,7E,72,8A,72,1C,6D,13,ED,C0,3F,70,F3,66,DF,34,01,AE,5E,D6,E0,FD,5F,A4,01,28,53,0E,2B,6A,07,88,B0,48,05,9C,36,5C,AA,0B,D6,C6,6E,81,5C,99,8F,07,6C,76,24,51,98,64,BB,34,5C,BD,1C,A5,04,B5,78,2E,F3,0B,B7,31,6E,9C,D8,8C,8F,97,03,90,35,17,AC,3F,21,79,DF,CF,DB,2E,74,5A,A3,40,76,B4,0E,92,EF,BC,E7,83,BA,4E,43,41,1A,6B,B8,E8,C3,1A,E5,22,0E,06,EE,AE,CE,63,27,D4,5F,46,21,19,8C,DD,EC,7D,AA,5E,9E,02,7D,57,8E,94,1C,1B,B1,70,53,5F,B9,AA,D9,94,E4,AC,CE,2E,41,E6,10,EC,50,70,D8,33,0C,AD,EC,B1,06,DE,1B,C1,F0,9A,A0,72,1E,9B,E3,50,AC,3E,22,65,A9,3F,D5,57,AC,88,32,1C,BA,27,4C,6B,F7,E9,79,4B,75,94,8B,22,C9,F6,1C,06,88,50,70,23,3E,8F,41,2D,01,12,E6,C5,C6,37,16,90,1C,82,A4,66,A3,F4,2B,DE,35,F8,B8,C1,37,EB,6C,F1,68,94,93,4A,9F,78,46,93,5E,35,C5,15,95,7C,C0,D6,23,69,DC,BB,EB,5A,27,BF,11,27,D6,DA,39,D3,BC,A7,07,07,51,9E,5E,04,D2,7B,6D,D0,71,65,61,CB,8B,AA,27,5C,60,0A,64,D8,D4,CC,30,AE,DE,32,9C,48,E7,08,C4,9E,ED,9F,76,CD,4A,3E,7B,BE,E0,30,05,4E,64,38,0A,CA,12,BB,AF,40,9A,75,14,81,CD,33,56,FB,59,41,46,86,BA,F7,55,3C,FB,09,14,22,9B,B8,72,27,CB,82,BF,B4,95,DC,31,89,BE,E1,26,10,0E,2D,E5,89,A0,2F,E8,54,9C,A2,0F,6B,D7,6C,B9,9A,41,CF,83,29,73,8A,2C,88,0D,9E,74,44,53,2B,4F,F3,F0,63,14,0B,74,F5,8D,2E,BC,23,C5,60,85,F6,96,F9,5A,D7,B1,89,94,47,DE,3E,8A,0D,64,00,6B,A7,11,65,8C,DB,A7,F8,65,F3,ED,F8,2B,61,E5,D9,14,C0,77,57,ED,1B,E9,B8,DE,00,6F,4E,5D,86,02,30,65,83,2E,E5,97,07,2D,D8,D3,9D,58,15,70,6D,74,47,A4,02,07,BF,D5,D3,62,E0,98,6D,7D,AC,BD,55,88,F6,9B,5A,0A,58,9B,4A,4B,A0,79,95,63,D3,8A,E7,78,A8,79,C3,26,56,8B,F3,BA,1B,9F,44,75,E1,E9,28,A1,C3,9C,A0,37,7E,55,C4,10,39,B9,ED,F6,1E,40,25,AB,57,D5,2F,1F,4E,4D,ED,E0,BB,7E,E7,E7,50,67,81,DA,DD,21,79,84,91,8D,60,BF,C2,55,2B,21,21,F6,BE,DC,65,47,E4,76,D2,58,99,F3,DB,AE,E6,8A,72,39,7D,EB,D1,22,B8,E7,13,58,A3,92,EA,57,05,84,9F,CE,CF,36,12,79,85,A5,63,36,99,2A,CD,DB,02,F7,F8,76,BC,D5,BA,E4,91,81,A6,0F,6B,FB,6D,9A,36,DB,47,EA,00,9D,AA,09,B9,03,57,05,62,3D,0C,47,3A,F1,46,77,47,41,BF,66,24,A4,32,33,64,69,6F,02,6E,8B,23,01,DF,47,DD,C6,39,A7,8A,D5,9E,94,D0,EE,26,1C,8B,2E,19,11,C7,D3,48,AB,71,ED,11,76,57,E8,58,74,7C,A7,60,8E,D0,B6,44,9C,F0,5F,3A,0F,03,6C,7F,DE,D3,1B,AA,73,43,7D,7E,DB,D0,64,B4,52,46,52,A9,E5,36,42,2F,AE,4A,EC,45,BE,86,73,B4,01,F0,BD,1B,C6,C9,57,F6,BC,32,28,77,75,3C,24,0A,D0,DF,67,7B,0D,28,C9,10,11,DC,26,C1,78,1C,10,59,29,1A,85,4B,C0,6A,88,A1,ED,3B,36,FB,D9,0F,8F,A4,01,A1,0F,E0,78,07,98,95,3B,08,6C,B8,D1,B3,F8,6A,80,FA,53,3C,8F,A8,94,0A,1A,3F,52,68,33,31,EE,99,A5,91,74,E1,96,EC,5C,FE,93,2F,3F,77,9E,5B,6E,CD,A9,70,54,04,CE,8F,A3,EC,AE,F2,DC,E3,B3,2C,90,28,96,05,D4,06,11,F7,24,0F,BD,51,7E,EC,F9,B8,52,C0,C0,2D,71,8D,87,D5,02,EB,8F,59,56,11,65,72,91,3E,E6,C4,2B,FB,EB,2D,42,FA,7B,22,01,F8,F8,2A,B1,73,EF,86,5D,28,74,D7,29,EF,CD,89,C1,39,15,52,48,B2,7D,30,98,6B,5B,29,F6,E4,93,CA,9D,2F,DE,A6,52,B6,DB,C2,7A,5D,49,CC,79,49,A6,5F,EF,FA,84,CD,58,DF,38,08,4E,35,C6,BF,8B,68,A1,33,DD,C4,7A,CD,7F,EC,68,62,72,35,4B,44,BC,BF,EE,D7,12,0A,58,D1,77,65,3D,37,59,D2,EE,FA,82,EA,79,B6,B7,3B,CC,F0,FE,29,CA,2D,FB,AA,62,F2,F2,75,9C,57,84,B3,D7,AF,C6,81,30,EF,02,B7,65,41,5D,DC,70,D5,4C,D5,CC,FA,00,44,CD,21,17,96,8E,19,98,AF,97,64,34,E0,6A,BC,92,07,BE,3A,9E,3F,BC,B9,2D,FB,25,91,10,83,20,60,37,99,27,5E,9F,BC,37,85,B5,59,36,D8,74,94,0F,06,2A,53,71,71,6A,CE,AF,6D,8B,4D,16,1D,C0,33,ED,04,75,FF,CB,B7,E8,60,B6,3C,E1,A9,77,D1,06,9F,D2,BB,86,EE,F3,5E,B8,7C,AC,DD,A9,A3,CB,59,24,65,AC,A2,97,BE,42,74,25,7F,43,4C,E1,A1,99,97,4D,27,A5,8F,DE,92,B7,B8,12,99,8F,A4,1C,E3,5A,9E,36,A5,DC,28,B1,A0,DF,2A,4D,47,9F,8F,1F,E1,D7,AE,7B,D8,E1,61,30,CE,F5,BD,1A,4C,E1,61,49,74,D6,B8,4F,6D,AA,1A,B0,C8,FD,AE,B8,94,C0,5F,C6,B1,40,DB,02,D4,CA,EE,C2,CC,81,AA,D4,7B,21,D0,79,74,44,F4,AA,6B,D5,2E,FB,02,56,BD,63,70,01,FE,B0,29,99,E3,58,55,29,B2,8A,06,83,B3,F8,FA,95,8A,41,3F,EA,5B,12,6A,A9,8C,1A,DA,6F,63,16,1E,8F,84,DC,E6,DD,CE,C3,3F,A5,05,3B,39,D2,06,F5,D6,18,E5,BA,CB,A3,51,8F,38,54,1B,C7,D0,B8,D9,A1,FE,3A,FD,B4,95,09,BE,27,9E,1B,1F,3D,C0,5B,A5,DC,AC,2E,70,94,B0,4F,17,D4,45,D7,22,FB,A1,40,18,29,D6,10,6F,C2,1C,62,90,52,DB,4D,05,63,01,9B,2C,F1,2C,20,E2,5C,1C,41,CF,7A,A1,09,CB,48,00,94,44,42,4B,FE,81,B6,17,64,20,C9,58,B8,17,28,05,00,5B,85,A0,CC,65,DD,7E,23,00,38,12,41,95,9B,C7,C1,E1,8D,F7,09,46,5B,9E,D5,D5,50,CD,1D,5C,1C,2F,D7,44,54,F4,84,4F,29,95,61,1C,FF,AE,A1,6E,33,4F,79,D2,DC,0D,E9,73,BF,7F,76,1F,A8,DE,07,DC,ED,8D,8C,90,89,1B,F4,A2,D5,07,07,D7,A4,5B,C4,E1,0F,35,4B,92,C9,5A,A1,69,72,8F,B2,39,AC,18,27,32,A1,AE,AD,96,C6,5C,5D,E7,EC,20,BA,4F,2A,3E,2F,C4,E3,4C,5F,E5,A8,20,47,10,59,DA,2C,6E,48,A2,65,D2,1F,18,38,5D,F1,38,2C,6C,B0,F3,D4,7C,19,BE,E3,CA,3B,8C,DD,EB,56,4E,08,2E,18,E4,87,2E,FC,95,61,56,95,CC,14,A5,F2,00,DE,63,83,29,05,E8,2A,10,54,B7,22,82,93,19,33,9F,D2,37,1C,B3,1C,58,79,A4,C5,44,94,5E,87,4C,EF,4B,D4,00,6B,42,D0,99,01,AB,A9,40,DA,19,BE,8D,8A,2D,99,4D,D9,94,F2,F1,88,19,C1,2D,05,44,E3,F6,11,53,FC,37,A8,1F,F1,43,84,28,D1,D8,81,45,DD,A8,03,25,5B,42,F4,AC,CA,2B,9D,81,F3,EC,24,6A,EC,EE,23,B8,BE,51,2F,1B,DB,9B,22,16,D1,58,C7,AE,A1,40,D1,F1,DE,11,DD,F1,00,98,6F,55,46,0D,05,87,52,62,48,B6,B3,8C,1D,E3,80,15,4C,52,4A,1D,00,BE,BC,24,E5,0C,54,DF,D5,19,BE,A6,6D,D0,64,7C,31,4F,6C,BA,80,30,D5,7E,8E,A7,30,3A,3F,A3,94,D9,2B,72,82,2B,C0,98,46,6C,3A,E5,1D,E6,3B,BC,8D,82,C4,A3,D5,3D,79,DF,9D,06,FC,C4,E3,51,E6,6E,80,50,5C,47,46,19,AC,9C,03,BC,D2,8D,B7,42,C1,F4,2C,33,00,A5,35,90,A3,26,1B,1D,BF,C2,02,D3,47,7A,B0,BD,92,CA,5E,F1,6A,FE,F4,07,A8,67,2D,49,2B,0D,C8,10,9F,17,0B,39,A3,E5,29,5D,3C,75,34,91,07,4E,AE,AE,C1,5C,8D,06,4A,F9,B9,33,E6,30,2F,CE,47,4F,1F,36,70,17,0C,61,B2,19,EA,6C,56,B7,DC,24,10,CB,B1,E8,CF,5E,A5,14,1E,37,6B,14,1B,DC,56,DD,44,37,E2,B6,18,DA,A4,EE,91,AC,BE,E6,9A,09,B1,3D,DA,A5,41,54,16,99,4E,D4,6E,53,F9,6C,1F,5F,EC,74,FE,D2,BF,EB,8C,0A,36,71,06,8A,75,0B,41,FF,DD,68,8D,90,BF,BF,38,86,3A,99,45,9F,01,36,01,D0,8E,CA,E7,72,9A,AD,97,49,7D,7E,04,A4,25,C7,CD,6A,0D,02,D6,05,AA,CB,D8,68,C9,7C,4B,1F,C0,D5,D4,FB,4A,E6,C3,1E,2B,B0,ED,C6,FC,AA,32,0C,0C,7B,81,36,DD,D7,3A,80,F6,FA,36,39,98,E3,F6,B3,97,FE,43,62,26,1D,EE,AF,D6,00,0B,93,DB,A6,1C,5E,B2,7E,94,E6,88,AD,53,BC,2F,CD,14,5D,EC,7E,7F,3F,6C,CC,FE,69,F9,E2,76,8A,3E,2B,71,E9,3D,13,62,90,3E,5B,1E,26,E8,54,FD,B1,E8,44,8C,E8,AF,AD,FA,39,6F,B8,BC,7F,28,3D,0D,E0,20,F7,B8,77,EC,92,77,48,27,D2,38,F6,AD,2A,93,97,27,D6,95,CD,7C,B3,56,65,AB,E8,DA,C8,8E,AC,93,88,66,E2,C2,6D,3B,AB,A3,3C,6F,4E,D2,07,DB,C9,46,DF,66,2C,50,2E,BB,46,B3,F1,AB,41,04,1A,D0,72,B3,BC,2B,8C,CB,CF,A2,88,6A,D3,F9,7D,25,8F,1E,2E,ED,E5,50,A2,8F,0A,53,64,48,5A,AA,20,7B,FC,CE,58,08,77,CD,1F,8D,AB,41,BA,0F,71,B8,57,44,3A,25,20,BD,94,EF,1D,FC,3D,11,BE,0F,50,B0,40,F6,E2,F0,06,CB,86,A9,0C,05,BA,9F,00,F5,9C,A7,19,3E,06,4C,F1,3A,8B,44,8D,47,BD,75,F8,3C,8A,4D,D9,33,D1,F0,36,5E,F5,66,71,3C,16,0F,92,80,9F,D3,E4,5E,07,12,E4,75,EA,35,86,95,73,EA,3C,BF,3C,F6,4E,A9,8B,90,51,93,7E,66,9E,93,9A,84,5F,39,1B,CB,05,CC,A3,ED,9C,14,1F,40,2A,42,F1,3E,5C,8C,75,BE,08,3C,97,4C,5E,7B,1B,7A,04,41,BE,9A,D3,82,12,82,C9,C3,00,B3,EB,C0,19,82,19,94,70,15,74,88,B5,60,6C,5F,E7,82,2F,7F,76,D8,D1,C8,D8,B7,75,3C,AD,E6,B5,0D,FA,B1,CD,45,01,D0,F1,5B,5E,2F,C2,5A,5C,EF,7A,F2,B2,27,4C,64,D5,A0,50,EE,3E,06,F8,96,2E,9D,9B,B7,A7,4D,9D,04,2A,FC,B8,AF,68,6E,7E,67,F5,B4,66,81,55,BF,E3,CF,AF,CB,71,BF,02,02,AB,E8,C3,49,DA,84,D2,A5,C6,8E,FD,B5,51,63,50,B0,6B,8F,FE,B7,77,0C,A6,42,FC,28,EB,C0,D5,C2,C6,B0,6E,18,B3,C8,1A,0C,76,9E,AF,F4,30,AC,09,47,3F,C9,EB,DF,E2,FB,54,A8,A9,77,AE,04,99,79,9F,B8,63,88,1E,83,11,42,9E,C7,12,10,C7,AD,BB,3E,15,AB,AD,71,08,0B,55,73,49,7C,3F,8B,8D,89,0F,77,E7,28,2C,E2,1A,4C,ED,D3,2A,D3,B6,CE,3C,50,B3,83,B7,7B,7A,6A,E7,56,63,C4,19,29,00,4D,F0,2F,99,89,3F,CF,D2,BF,7D,B2,72,3C,5F,53,AE,B1,2D,2C,1C,F8,18,67,8E,B9,A6,DD,53,6F,C3,18,F3,C1,84,A6,E2,BC,16,24,53,11,40,E5,C0,36,BC,50,34,8A,FD,85,62,7A,88,F0,22,72,8C,42,14,34,70,43,75,51,69,29,A7,18,98,73,B4,46,B3,5D,B4,AF,5E,3D,45,3E,03,37,B3,FD,4B,7F,28,40,FC,00,D7,2B,D2,8F,F6,08,48,E8,31,42,35,88,AF,BD,58,F6,E2,EB,50,18,60,6D,A2,11,8B,43,B6,7C,3A,92,70,A9,0E,D6,2C,3D,9C,4F,CF,5F,CA,98,A8,6C,23,2F,D3,22,56,15,FF,2A,9C,57,7A,6B,2D,23,57,27,85,62,5B,F1,61,23,3A,06,47,B6,3F,EB,9E,70,EC,81,7A,50,E2,7F,4A,66,BA,E0,F8,21,AF,B0,6B,31,84,1D,8F,94,2C,3D,1A,37,49,CB,FA,A4,0F,68,E7,59,4B,29,81,2E,73,D8,90,2C,12,B6,49,F2,88,85,F9,2B,8D,E1,79,4E,7E,F8,D6,DB,B4,DD,8E,0A,B3,89,5B,0F,BF,51,F7,77,0D,0D,AE,F2,05,F9,10,C7,33,86,81,62,3C,87,64,89,CE,6C,AC,5A,6E,1E,0B,92,D9,ED,A5,60,83,B4,CC,9A,98,AE,F0,AF,08,38,42,B6,3D,12,1E,49,8E,D0,8A,DF,6F,82,A3,88,8A,D9,5B,16,43,11,43,B3,D6,9A,81,32,BD,21,6C,C1,35,B0,1A,EB,93,BC,88,46,7C,BA,8E,96,73,0E,4B,BF,D3,CB,B7,D8,A1,B9,44,B2,AB,E9,95,EE,69,35,57,20,67,48,06,25,A9,55,B4,10,80,91,7C,81,C4,73,68,79,51,98,1F,74,4D,D8,4A,BE,F8,7A,3A,CA,16,A9,E2,C1,9C,EB,E7,A7,57,B5,86,06,C5,6F,C2,0D,92,5B,55,F4,BD,BA,C8,F8,20,41,4B,D6,7D,D7,8D,4E,6F,AA,47,6D,06,33,B0,05,9B,37,E9,6A,D6,7B,C6,29,5E,67,D8,65,7C,C0,34,A7,97,77,AE,9E,C9,95,03,F4,9A,9D,F0,EC,68,8A,8B,A7,6A,4A,88,30,9A,2D,A3,CC,8E,02,98,EB,93,5A,0A,15,27,19,A3,AC,35,4C,01,8F,6B,22,66,2A,99,D8,02,C3,51,0E,DE,75,62,44,C1,D6,64,01,11,FF,1D,A4,40,7B,B3,DD,40,DD,2C,D0,D8,52,4D,34,B1,0A,0B,8D,8F,0F,B3,C4,C0,34,6A,CE,D9,9A,FA,77,D7,F7,E8,08,5F,D9,EE,D3,03,E4,5B,FE,BB,4E,92,B0,D2,89,52,7A,BC,C4,B3,54,F3,20,87,95,AD,30,FE,FE,05,E6,31,87,33,B6,AF,44,98,0D,8A,86,CF,65,6E,31,90,AD,6A,92,C5,1D,1F,99,48,1F,25,6F,BA,A5,AC,E7,15,B5,56,27,C8,04,30,8A,24,39,51,DA,A9,5F,D1,D8,4C,A6,A6,20,FD,A3,94,6F,49,DF,19,11,4D,72,C9,66,99,8B,CE,B6,C1,14,8A,D9,89,A3,BE,BE,60,63,39,E6,D0,7E,14,E4,81,42,A2,F1,8B,B9,ED,38,52,9F,CE,A1,E1,22,B2,E1,7D,37,1D,77,81,34,B7,D5,73,CC,F2,D0,39,1B,2A,DF,3B,D3,25,B9,A4,25,E6,92,D4,A0,B0,7C,BA,F2,64,CB,11,7E,0E,7D,CF,0D,73,EB,A8,C8,59,C3,7B,49,49,C4,16,C2,91,32,EB,EE,92,BA,BC,B0,47,49,17,2F,4A,08,5B,99,C4,4F,14,A9,0D,FC,3E,DB,E3,F1,6D,65,9B,E4,11,59,26,CF,B3,9D,86,01,86,D5,53,2B,10,F1,79,CE,D9,B9,EE,20,60,4D,5D,5F,D2,34,9B,96,B4,2D,3B,3F,11,9D,94,14,54,B5,21,8A,55,D1,88,73,41,1C,6F,E4,0C,42,BB,4F,47,28,87,08,1C,1D,1B,83,DA,8F,96,5B,EE,89,DF,46,DF,E9,11,27,5B,B8,9D,11,DE,F1,28,36,92,D8,D3,4E,92,D7,6E,33,D2,FD,29,BD,D7,F0,1D,C8,CE,E0,AE,B5,8F,88,FB,C3,53,F0,76,A8,0D,BB,89,1A,27,1B,5D,93,04,37,E4,FF,CB,1D,2D,62,0C,2D,6C,C8,FB,4C,E2,6A,85,77,EF,CE,84,81,DB,57,A3,FC,8B,48,00,D2,6E,55,82,9D,BC,DE,6B,7C,CC,16,E6,FD,93,86,E9,C7,20,C0,0C,7E,88,6B,50,CD,B7,00,9C,19,7D,DD,59,DE,D6,A2,0D,93,C5,2C,29,38,31,3F,21,AF,DF,27,A5,1A,3F,E7,B3,3C,DA,3E,18,14,F7,07,12,2D,32,B6,42,7E,73,FF,5F,F8,D1,56,A4,2F,8E,0B,31,5C,65,54,7F,D7,F4,8F,9E,21,F6,7A,EA,D5,44,26,F4,EE,35,A1,16,50,76,95,6B,FB,26,26,C9,C3,51,38,0E,0A,E2,6A,A3,34,5A,B0,9B,D0,DF,C4,86,F2,7B,CC,6C,4F,49,17,5D,D7,75,CC,9C,B9,6E,ED,37,DC,DC,FC,9F,EE,94,3B,FC,33,33,0B,24,AE,3D,37,C2,40,DD,BA,A2,E1,FA,5A,09,4C,FC,11,B7,A9,6D,23,E9,7E,75,DE,B4,E8,82,67,2F,0D,EC,78,1A,13,F4,13,64,F1,6F,06,10,97,3E,E9,33,F6,6E,95,3E,7F,57,BB,EB,35,A3,E3,6F,35,CD,88,05,F8,98,35,4B,4B,1F,BD,9C,89,55,E2,9C,81,D8,C8,EC,C2,F6,D8,EE,CA,6D,47,55,9E,CC,14,14,A0,74,69,84,7A,4C,7D,6D,65,E9,5F,0A,CE,70,7D,D5,4B,E1,49,AE,21,6A,B6,9A,B8,9A,77,E7,AD,62,F2,F4,01,C6,3F,DA,D1,9F,D3,AF,5C,BE,2F,88,7C,B3,92,8E,65,03,4F,DE,52,22,72,1E,5B,01,B7,60,14,59,53,0B,19,6D,60,50,F9,A5,CE,54,ED,2E,85,3F,C7,3F,18,6F,0F,EF,26,C1,1C,3C,01,B7,F3,F3,A6,A5,B8,B3,C7,2A,AB,9C,B4,B6,78,82,D7,F5,D7,3C,6B,1A,4E,69,2F,98,62,26,F4,2B,FA,49,0E,47,DD,5A,69,A2,D8,05,41,B6,96,63,39,AA,97,34,E2,40,11,75,B3,6F,0B,E4,2B,0B,E7,A4,31,D8,21,A4,30,E6,8E,D4,E3,D2,27,40,A2,A4,26,26,D0,42,0F,A4,7D,D9,2B,41,A1,53,A8,DC,F4,70,1E,47,D1,4A,0F,E8,40,12,F8,E8,D7,BD,4B,C3,25,5B,FF,BE,8B,31,C2,56,61,F8,9A,87,73,86,49,62,96,12,25,14,A4,0D,D6,01,85,50,59,CC,82,9F,28,4A,93,19,3D,E7,A1,4A,F2,2D,9C,F4,1E,74,B6,8A,DD,62,60,B7,74,41,68,D7,93,1E,52,E7,F8,86,AD,03,2F,83,5A,37,B1,7A,20,54,00,45,19,E5,60,16,B0,45,7B,BB,C8,B2,96,31,55,10,E9,04,08,0F,D7,B5,EA,C9,F6,70,0E,4E,22,D4,C6,D1,11,B4,21,2C,59,42,64,1A,7C,DF,7B,A3,9D,75,B2,78,BD,CD,6C,4E,0D,93,C5,F7,39,FB,0C,BB,B8,66,6F,A7,0A,56,9C,76,D3,F0,DB,71,E3,40,63,34,99,07,CD,04,7E,FC,B7,CB,71,9C,89,A5,1A,88,74,0F,7D,64,F4,EF,32,C5,92,2A,62,81,EB,0D,6D,9C,77,8B,D5,4F,4A,FB,3C,F0,01,DE,A8,B1,29,89,1B,D9,83,E4,04,D4,82,E3,86,D7,17,D7,FB,DC,01,30,75,10,4E,91,B4,F9,BE,25,39,F1,AD,02,F3,2D,27,D4,0F,FE,A6,AA,6A,AA,08,8C,6F,89,EC,CA,F1,EA,E2,B0,61,74,1D,1C,A3,3E,2C,0D,8A,40,78,8F,DB,7D,AC,6A,08,BC,5A,2E,6D,68,BC,2B,72,3F,C7,A1,65,F4,B9,57,A3,7D,AB,80,B4,5A,A3,C9,72,36,EE,EC,79,33,F0,01,B0,B9,A2,68,5C,33,2A,20,43,5F,1B,B7,5C,BA,E7,5B,76,04,21,1B,45,A1,C7,97,90,28,C3,40,87,16,37,67,1D,3C,E1,0E,A8,96,7A,19,E0,D3,DC,77,FF,CA,4B,1C,2E,C9,CA,9D,02,10,F7,4A,A2,88,6D,19,AF,02,AC,91,69,F9,D4,E7,F1,5D,7D,1F,23,DD,CB,83,78,47,99,E0,4B,11,8A,A8,57,E3,18,0F,E1,82,A6,78,31,07,85,AB,01,97,8B,4A,E1,0E,91,E3,32,ED,8E,04,24,A2,D5,09,90,4C,4B,CC,02,CA,B5,9B,D1,3B,83,45,F1,39,54,E9,1E,93,C8,59,B0,12,CA,0E,9D,C0,F2,17,FF,A6,69,BC,F8,8B,9E,A3,32,77,65,70,4E,8D,0F,AC,08,3B,41,56,5B,70,F2,7D,EA,4D,B2,63,F4,0D,C9,48,98,4C,92,14,19,CD,02,D8,A6,D3,C7,4C,3A,C3,04,89,41,C5,5B,2E,96,59,F3,07,67,06,AD,E9,BE,F5,7F,54,55,A3,89,B1,83,70,91,9D,2B,89,1B,27,E5,CF,58,E1,0B,7C,11,31,71,00,34,BD,5D,AD,61,81,36,7D,D6,A1,8E,2D,BC,BE,A4,C3,C7,4B,5E,BC,65,05,F3,AD,27,54,BE,DD,ED,25,06,6A,F8,24,3F,76,1E,EA,3A,85,DA,F5,49,45,0F,0C,8C,E5,98,A9,62,9B,3E,8D,52,61,56,CC,82,45,19,8C,3C,48,C7,1D,35,D4,A1,78,9E,29,31,61,77,0D,49,1A,33,7A,AB,22,E8,7C,39,5D,1E,69,E0,BE,8E,AE,26,9C,C4,BF,A6,05,2F,44,DB,1A,89,48,6A,D9,EA,F0,C4,BC,A1,AE,88,8E,73,F6,BA,36,D6,4F,85,F0,17,5A,A8,62,A1,9D,12,0E,E3,44,EC,E4,94,30,A3,3D,A0,4C,49,71,A9,EA,10,92,06,67,FC,CC,CB,4F,A8,5C,44,4C,6D,8F,6B,40,DC,0D,1A,A1,DB,84,55,9F,45,9D,52,0D,42,C7,AE,E0,DC,20,0C,69,F1,02,5F,E1,C1,A5,0C,A0,D2,47,A5,73,17,72,99,2B,49,C1,DF,40,F6,8D,4E,5A,79,84,00,00,65,69,61,9F,71,B4,1E,94,5E,6A,C3,05,21,55,98,99,7B,D9,DE,6E,B2,E2,A8,44,E5,4C,5B,49,45,83,F3,37,98,33,AE,10,3A,1C,76,97,22,15,6A,DF,9F,89,A4,09,93,82,8D,D1,B8,02,DF,21,F9,F1,8F,1B,2F,00,95,CF,67,07,17,04,07,AD,47,F8,52,9C,88,0D,6C,D4,3E,6E,0F,18,82,19,37,9F,31,70,9F,BE,7D,C7,30,B0,A0,D2,FC,E6,D4,4E,D9,77,BF,8E,28,85,62,04,B8,E2,AB,30,A3,6D,EB,C2,BF,61,2B,12,2D,FE,22,2C,CC,17,B6,94,EB,05,01,54,68,5C,BE,53,4D,A2,0A,9D,AE,90,FE,35,86,15,6D,B0,9B,6B,58,0C,6E,65,9C,AB,D9,61,EE,03,4F,C0,88,71,C2,31,B3,38,24,65,74,AB,68,1B,19,8F,DD,6E,88,AC,40,6E,4E,F8,F4,63,DE,AD,23,72,CA,65,B5,DD,C0,E9,03,E4,4F,C4,26,91,8B,F6,B5,58,D3,15,B9,5E,0C,32,DA,AA,F2,89,13,54,F5,6B,88,7B,EB,72,90,59,F3,4A,5C,AD,1B,0E,70,6F,78,DF,64,25,2A,9C,6C,16,64,D6,64,77,09,63,C7,01,4A,DC,11,A6,C8,27,98,FE,FC,0F,71,F1,45,90,A6,AB,10,8F,FE,9B,24,6D,85,E0,63,3B,DC,A1,83,08,83,C8,C7,89,6E,02,B1,F7,6E,0E,6E,40,AB,32,32,1C,01,11,70,36,B9,20,FD,C5,3D,E5,21,B5,19,65,84,CC,02,45,A0,73,6D,5E,C1,0E,FD,AF,34,63,B1,09,C7,09,FC,33,2F,BD,C5,DA,DA,FC,1E,5E,90,DC,22,DD,48,DA,3B,FC,D7,2D,98,A4,41,CC,3E,DC,5E,F9,7D,59,6D,68,68,C5,D0,56,77,A4,76,DD,DF,18,9C,1F,08,09,60,7D,2B,00,43,45,AE,62,90,AF,D9,47,57,1E,15,64,65,3D,EF,A0,3C,CE,80,02,9D,73,3C,8D,BE,12,71,19,43,07,D4,80,C6,98,17,3F,B4,80,D2,27,55,ED,74,03,BD,40,A3,5D,98,23,23,5F,33,92,9E,81,70,A6,79,20,B8,66,60,A5,D3,BA,FD,61,D8,0B,35,1C,FA,2A,E1,7D,FE,01,C5,F1,D1,76,55,9D,D0,AC,03,98,6B,0E,05,55,98,D4,D3,33,4C,10,AE,8D,5E,6F,FE,1E,40,5F,93,CC,32,D8,8F,1A,A0,36,AC,41,24,08,CC,CF,7D,B1,75,38,07,C3,51,E8,AB,35,00,70,9A,40,D6,75,2F,58,7B,59,E7,57,35,ED,B4,3E,C0,58,9D,86,9D,6C,21,78,EA,70,87,20,C7,50,10,18,8B,56,45,5F,3E,B5,95,86,29,FA,E8,21,C5,9D,FD,15,49,87,A5,83,D4,9F,B4,AC,D4,7E,B1,F5,21,C3,3D,6A,88,43,C9,C9,5B,D3,FC,F1,77,48,A6,55,FD,09,6A,27,C3,19,37,D0,A5,1C,6B,00,E6,06,90,BC,5B,A7,59,2E,74,E5,1F,C6,F6,12,72,A4,04,C9,CD,27,84,2D,A1,AC,E0,1D,9C,7F,DD,20,34,05,23,D9,8B,5A,CF,89,29,0D,B5,C4,8C,04,A6,A4,61,AA,59,4C,48,83,25,C2,F3,10,80,3B,8E,F5,64,21,E4,09,C1,45,3D,95,2A,63,C5,B0,45,2D,EA,7E,EA,C4,61,6A,F1,BE,85,76,EB,8B,2D,08,41,6B,88,06,19,76,8C,D7,BC,01,79,73,66,E8,0A,B8,7F,F0,2C,C0,D5,77,2D,91,DE,84,AC,7F,6C,AB,7F,EF,CE,44,83,CB,F6,D2,C5,3B,FF,A3,59,1D,45,7B,A9,56,0E,A2,77,F6,39,B7,CE,E3,97,25,7C,CA,6E,B5,61,DB,24,30,CF,07,74,00,F8,B3,67,DF,B4,F9,F3,6B,C5,ED,71,F3,17,DC,CB,AB,07,B4,5D,09,FB,57,66,E5,80,0B,3A,F5,05,98,3D,7C,BF,EF,18,AC,EE,E4,CE,10,0E,0E,DC,39,74,49,C4,10,02,AB,52,71,29,54,FB,05,5C,73,39,61,23,50,FF,59,5D,55,D8,83,CC,D3,83,F9,D2,90,AB,EB,A7,BD,8B,3A,81,ED,90,33,2C,09,8B,34,77,89,2C,0B,4A,8C,1A,56,F7,38,C2,7F,49,A2,8A,E6,DC,0E,87,5C,83,85,E4,58,9B,40,68,77,63,9C,09,2A,B1,14,AC,1F,1F,95,13,9F,16,A4,E4,B2,FF,E9,C4,1E,14,B6,D1,26,A0,28,06,55,30,FA,43,0D,0D,F2,0F,68,68,8D,33,14,7A,70,3C,A1,0D,83,6A,BF,EE,48,02,A9,B0,A0,B0,98,CC,B9,AA,02,DD,6F,AD,45,83,F1,E4,34,3D,71,B0,C6,16,0E,D0,3F,2A,4C,A1,DD,E2,3A,48,36,63,3F,CE,DC,07,B1,7E,C2,0C,CD,8D,64,49,8C,C8,C2,76,92,F2,92,7F,85,66,D9,47,52,38,3B,2C,9E,D4,DC,16,DE,81,E8,7C,38,71,0C,D5,C5,6E,06,E9,AA,C4,AB,37,96,F1,25,9B,87,77,1E,F5,0B,0C,0F,0D,A2,20,B0,44,E1,E7,2A,0D,F9,CF,78,48,29,5E,E7,78,69,BB,B7,30,A0,23,31,E2,9D,DC,8B,60,44,97,10,1F,5B,43,5A,C6,F8,2C,16,0B,0E,CB,2E,4F,9B,19,40,27,E9,6F,AB,C1,8D,3B,EC,FD,49,B4,77,9D,6D,24,71,57,29,BD,22,34,DB,EC,66,11,ED,F4,0B,76,F4,B5,49,F1,9D,70,BA,FD,79,1D,4C,EA,7D,1B,4D,D1,8A,35,4C,38,3C,24,DA,D9,B0,75,09,FE,04,3D,B7,FC,FF,97,49,03,22,E3,DF,7F,9A,BB,9D,D4,FC,18,3F,C9,BD,61,12,98,60,98,06,A2,AE,3F,8A,A8,57,52,96,C2,A4,53,E9,DE,54,F5,3C,81,F3,7F,6C,4B,7D,89,D5,B9,12,F5,B4,08,78,53,F0,04,74,BB,8A,BF,91,06,D4,91,AC,0A,F2,E5,F7,A0,51,08,41,D1,31,96,DD,9E,5D,65,26,A0,A2,F0,99,71,CB,1F,59,8D,0D,81,60,35,97,F4,E7,0A,7A,D7,CD,0E,19,E5,AC,61,5A,4D,67,E2,0B,A6,6E,06,2B,14,9A,99,EB,94,56,A8,9E,17,75,82,43,3D,26,14,F0,E9,10,48,62,6E,04,D5,26,29,7C,AD,82,D5,F3,03,9D,80,80,51,35,4A,BE,E5,82,A5,1C,86,C8,ED,B0,28,C9,96,1E,BE,C7,EB,E5,8E,26,AC,E8,5D,76,C7,98,1D,E8,D2,04,F7,F4,39,FE,83,EE,CA,E0,26,34,64,E4,18,4D,47,8F,10,DB,9D,87,09,1D,29,6D,36,34,08,8E,43,01,47,79,14,BE,BC,0A,08,88,AD,44,9C,3D,2A,84,E9,AF,0E,D4,55,C4,5C,6D,04,C7,B8,DA,1D,40,AC,60,E0,80,13,6E,35,7A,09,77,D6,B2,18,3A,D1,1D,CB,49,27,DD,B8,9C,F2,A8,ED,9C,71,22,75,99,6E,6D,5E,7D,06,9D,B2,BE,A5,EC,A8,4F,8A,38,02,50,A5,1D,AC,9A,62,80,4B,DF,BF,EB,DE,CF,46,94,2A,88,C2,FA,0E,2F,8C,35,28,FD,86,EE,AE,A2,F6,95,15,D2,D8,1D,B9,0B,AE,CD,31,DE,A3,7B,99,03,97,73,5A,1A,4F,C3,3A,9D,48,65,66,FF,27,BD,9A,FC,CF,3B,50,68,02,A0,EF,67,2A,CC,91,24,C4,51,B2,46,5B,0B,F7,66,B0,67,86,38,AF,6C,24,A6,B2,A0,B8,88,F7,98,71,39,A5,97,CA,F4,44,71,BF,98,2F,69,D7,04,BA,BF,EF,EF,68,F5,8C,8A,32,20,C8,38,A0,E4,A0,03,ED,64,CE,20,89,79,AA,7A,8C,F2,7F,7F,A7,90,D9,B8,48,44,E1,BF,3B,C5,39,DA,13,12,78,D2,54,D1,7E,99,1F,2E,B1,4C,48,09,C4,B4,E6,AA,FF,AF,E5,2F,11,5B,22,2D,B6,90,FA,CA,58,8F,95,82,B8,28,08,BB,AC,78,8E,22,78,E7,C7,68,01,9E,A7,2E,97,DF,24,9A,3A,10,7D,71,26,60,26,33,7E,2C,DA,A4,AE,34,4A,25,7A,4C,B2,D1,B5,53,4A,22,A7,37,23,7A,45,3A,B8,0F,F0,3D,61,72,6A,61,06,5D,46,98,DB,B1,C7,0D,8A,38,C9,D5,CA,2F,59,72,0B,FB,A6,94,6E,11,DB,6F,D5,24,32,ED,03,77,5E,90,7A,24,6B,56,48,55,93,19,9C,55,86,90,E9,FA,58,93,2F,ED,67,E8,38,8A,47,26,72,E0,CE,79,B1,D7,ED,EE,AA,BB,CB,F6,D7,F8,2C,FE,6D,D5,47,91,60,DE,BC,F5,E2,3A,FE,43,49,D9,1A,44,17,98,20,02,FE,BF,41,04,0A,2E,FE,62,5F,5E,E0,E4,31,94,48,E5,FD,ED,78,AA,11,FD,DA,77,BB,B7,B3,62,43,AC,1D,BB,73,A7,5A,9F,8B,D5,BC,F3,D7,2A,5B,E7,19,6A,52,24,14,3F,A3,2B,B0,17,39,C0,A8,32,F9,15,91,7D,A1,A7,FB,81,66,C1,76,DB,87,88,61,9B,76,7D,A1,82,6B,3D,42,BB,3D,8E,61,CA,9A,D3,21,78,B5,28,8E,69,31,D1,43,12,4D,31,77,90,EC,37,F1,DC,0C,45,E0,12,6F,C4,E3,4F,D8,1C,E1,A4,FF,95,62,FA,06,E7,F7,EE,F8,74,D3,DF,F4,3C,D7,41,F9,4B,F3,6B,BD,C1,C3,A7,51,07,2A,09,27,EC,AB,6A,C9,83,36,70,2E,4D,2C,66,43,55,BA,25,F5,61,0F,0C,DC,5F,3D,DC,BB,B2,56,04,57,D0,D5,1F,AF,9E,33,AC,6F,38,36,DF,1B,9E,F7,4E,BE,F9,93,52,7C,C3,2E,E5,1E,16,52,D2,FB,A9,C2,1A,BB,D5,A4,2F,C4,1E,ED,50,41,01,27,3E,50,CE,FB,49,31,EE,92,48,64,8B,7F,49,DE,30,5B,43,97,62,7D,7E,DC,BF,46,89,DA,49,42,F1,49,DA,85,7C,4B,65,86,B5,5E,B9,C4,19,E4,23,6F,61,77,47,E1,74,C5,FE,7A,9C,3D,71,54,DF,A7,B2,9D,FD,DD,94,AD,B9,34,3B,DC,8F,B9,E0,51,0F,2A,B5,95,16,3D,18,2D,A2,F6,7E,DB,74,94,BD,8C,7E,EC,2C,E3,F9,54,4D,3F,EB,B4,67,50,79,30,CD,4A,24,B8,9F,55,0A,38,98,C9,5A,01,A7,BB,81,EB,15,AA,AE,35,2A,96,60,90,C9,47,35,7D,6D,51,0C,DE,02,66,7E,4E,6E,7E,5B,1C,EF,90,AB,55,1F,9A,0E,06,E3,38,6D,06,72,F5,8B,A3,DD,DB,66,68,FB,55,92,9D,69,EF,EF,2D,E7,C6,B4,C8,35,63,80,35,7F,E1,14,F0,AC,11,DF,FA,1A,FC,EA,DB,86,1E,6C,9C,8F,C7,4D,56,99,74,5D,99,A3,D4,20,80,97,E1,C9,91,F6,5C,D2,93,80,00,2E,1D,BA,02,6B,DB,F6,6F,F1,A9,D7,1C,EC,E5,C0,D8,E4,FD,BF,EB,50,4F,67,AD,6A,09,86,82,CB,DD,2F,30,7A,7F,75,0B,97,CF,EE,56,75,5F,1B,EB,04,DC,97,54,13,51,11,81,64,D6,3B,67,6D,62,81,00,D4,43,B3,DF,45,1A,63,43,A3,E5,2B,9E,F5,65,F7,98,5B,83,8C,58,5D,65,10,AA,17,32,22,39,68,23,FF,ED,93,EE,A1,14,BB,EB,54,0A,42,24,05,F9,B9,69,B3,92,09,26,C2,84,C0,8F,0F,FC,95,A7,4C,15,35,DF,F7,1D,84,96,B1,5C,F1,0A,D4,C9,60,D8,56,3C,99,6A,1E,2F,07,7C,B8,5B,7B,27,F6,8A,DA,D9,EF,AD,88,3E,3A,DE,BA,52,1B,4E,E9,D2,EA,0E,C5,75,C6,53,B0,11,69,7B,93,E1,A4,73,B3,FE,67,07,D9,3A,A8,E8,A3,06,B3,95,E6,00,98,7F,90,D9,CF,77,99,E6,5E,F4,8E,4E,F8,BA,08,B9,80,1F,BC,CB,7F,A1,06,60,D2,31,55,C0,58,D6,C9,67,7B,45,FB,68,A8,9C,92,C3,EF,63,1D,D1,5B,E0,D0,5F,E8,3F,9E,26,68,67,ED,E8,D1,EE,3B,96,06,8A,4B,BB,B4,CB,84,80,3E,38,D4,0A,3F,E7,5E,BA,F2,C2,DC,4A,E2,84,A2,A3,E3,75,AF,C2,97,A3,3A,8C,09,94,DF,E7,60,96,42,FA,6F,C1,80,2A,41,FA,28,DD,A0,F2,60,D1,94,28,E4,B3,B5,EB,6A,50,70,1E,D7,0D,49,4F,75,14,2B,AD,AF,67,40,16,4F,52,B0,E5,18,F8,B6,CB,46,0C,14,CD,CA,DA,2A,DF,F1,4A,78,24,ED,3E,8A,7F,8F,D7,18,CD,E5,70,87,F1,C4,7C,52,F7,BE,88,7D,42,8C,54,9F,DD,27,59,E2,61,5A,F0,AB,0A,9B,8C,86,54,37,A5,B2,18,BE,19,D0,8A,36,0E,32,F1,E1,09,48,6D,7A,3B,0B,35,23,EB,2D,81,9C,BD,6A,EB,05,CC,C0,1D,AC,32,26,C6,B1,5A,D1,41,3B,5F,3D,56,91,6E,6F,86,8B,C2,EF,29,8B,64,14,E7,79,98,68,A5,B8,DF,64,BF,06,4B,D8,81,42,AD,1B,EA,52,6B,C3,75,BA,F1,63,06,B0,42,42,78,57,3C,DC,5C,7F,E4,2A,03,E0,C0,67,79,D6,46,C5,61,9F,EB,1D,34,62,A2,1D,4D,D7,85,DF,D7,E8,DA,1E,26,E2,EF,56,9B,7C,0E,F1,ED,D3,95,83,B0,4B,2E,34,19,30,C5,BB,A6,60,75,72,B5,08,3D,AD,69,DF,88,46,DB,C4,F6,16,F9,C3,1F,9C,04,62,B0,9B,93,A4,39,D2,37,E2,60,47,59,D1,4B,6A,21,64,AA,2F,35,CB,84,74,EE,DA,11,6B,D1,3D,5E,A2,DF,B2,8C,49,ED,BA,A0,62,2E,3F,AD,A2,64,57,95,E6,3D,02,DC,21,B2,2A,3D,C2,AD,E0,A0,62,CC,E1,74,79,1F,21,01,27,8B,E6,E3,35,98,7A,29,D5,56,8D,B3,58,9D,E1,5E,A8,2E,4F,F5,4F,EF,3D,0E,56,4B,B2,12,52,09,4D,1B,F4,EE,B1,B8,48,20,CB,FB,6A,5F,F3,A0,6C,27,D8,98,C4,A4,46,F1,40,80,FB,E6,B0,B0,7C,36,13,CA,D8,1B,33,68,E4,5D,31,71,B9,3A,68,A7,97,94,04,A4,A3,91,6A,CA,FA,18,F5,2C,89,0B,79,34,BA,9B,30,30,5F,88,5E,56,18,B4,77,0F,97,80,F8,4B,BC,5E,97,F3,F9,24,55,9A,0C,81,E1,F2,F0,0B,B6,87,34,2A,D7,09,75,A1,72,5C,83,D6,7D,F2,E7,B9,8E,3F,8E,B5,99,B0,23,DB,B7,82,F0,AD,F8,BD,00,FC,27,68,E8,C8,71,F7,45,5F,B9,93,32,C7,57,5B,84,56,9B,D1,24,A4,77,80,76,AB,97,4B,A0,69,43,A7,04,F4,AA,98,C4,C2,0B,1A,92,0D,55,F4,5A,E1,24,6E,04,F6,35,BF,61,0B,77,49,CF,08,BC,87,B3,0E,49,38,6A,5D,23,20,C0,29,A5,96,DD,CB,F9,13,17,70,C9,A7,F5,73,A6,30,DC,E5,16,B9,FF,6E,EB,09,A1,23,9F,3D,52,F7,64,08,E8,6F,B3,4C,E6,13,2D,06,9B,62,F5,3C,F0,38,A6,46,B2,90,3A,14,8C,B0,79,E8,ED,35,EA,00,20,81,BD,82,F4,EE,6F,1C,FB,0B,2B,45,6C,C0,F5,3A,B6,FB,F7,9A,8C,16,4F,B5,D8,D5,E3,0C,70,22,BB,5D,54,FC,A5,79,F4,85,D4,B9,3D,8F,EF,18,7F,48,44,48,2D,99,F2,D8,97,57,79,DB,D1,AE,15,62,5D,15,69,27,25,7F,F5,80,27,37,5D,74,7E,B0,18,C7,AF,05,52,B6,0B,C6,51,AB,C9,5E,26,08,D1,F5,CE,64,00,7B,34,D9,4C,D7,99,A3,A1,F5,E5,18,8C,65,DA,47,57,C4,91,91,67,12,8E,CF,CB,0A,14,6F,84,CC,95,5E,BF,4C,6A,6A,76,C3,09,3A,6F,4A,D5,9E,35,0A,D7,0F,A8,E1,0E,E9,75,61,7B,AE,B7,2F,14,B9,93,D8,5E,04,92,31,80,8C,2C,DE,17,74,B8,3D,BD,C2,D6,30,DB,CF,7E,38,83,D8,84,8B,D4,A8,CD,50,EC,BD,77,3C,F3,2D,8D,B0,42,E3,D8,56,D7,F4,8A,35,D2,14,DF,CC,F8,18,8E,51,16,6B,55,F1,93,E9,25,62,CD,73,1B,72,84,4F,31,66,93,9A,05,9A,37,D1,62,23,D3,F0,28,73,90,A5,9B,A5,D0,00,C8,A7,65,3A,6B,E2,92,DC,A8,D1,58,63,BB,FE,88,28,E4,F6,25,22,72,A4,C9,2C,DF,E2,84,71,64,08,3E,D7,82,14,00,52,B0,50,C9,30,0A,67,3D,6C,FF,9C,84,39,60,67,21,66,97,B5,78,B5,69,F6,99,6F,85,F0,00,B4,6F,33,32,6E,97,9E,48,3A,09,4B,92,F2,0C,80,67,D8,D3,32,AC,9E,EC,F7,A5,35,6A,0A,EC,00,25,07,52,A4,DC,ED,3E,1C,CD,2F,8B,A6,50,7A,E7,09,48,F6,33,0D,09,14,05,4E,DF,26,3C,47,15,AA,38,99,1F,DA,E3,D0,4B,38,A9,87,2D,57,F4,64,4B,D7,9A,0B,53,25,F4,BD,7D,3F,E2,29,18,92,38,FE,E0,A6,1C,58,01,83,59,7A,A7,6E,91,B7,06,9F,AE,DD,C2,E2,EA,55,51,0C,7A,D5,AE,BF,0B,32,15,68,CE,D0,17,BD,7D,21,75,A8,71,28,4D,22,66,39,2A,76,8D,0C,C6,98,9A,0A,64,37,C0,15,A6,9D,CF,1A,F6,8E,6F,58,EB,1C,FA,C5,39,F0,1E,2F,7C,7F,E5,68,BC,C2,D1,19,5D,05,FD,55,9E,A2,B5,D2,5F,F9,38,FC,0F,A8,D6,39,E9,47,43,32,5D,B2,CE,CE,62,8B,16,6F,D0,80,85,E3,54,BA,6B,A0,8F,40,1A,DF,88,41,73,6A,A9,B2,BA,5E,3F,44,CA,48,20,0F,CF,FF,B0,59,4A,DF,5B,39,63,2F,42,CE,D8,DC,1B,22,C0,FC,00,35,78,A5,72,38,BF,30,7A,E4,40,E2,38,0C,0B,27,8C,C0,57,6D,16,BA,70,39,92,90,2E,A4,50,D0,87,0B,A6,99,A4,80,2E,B9,33,42,D3,3F,70,0E,84,C7,36,02,B2,61,54,FD,E7,1C,48,EC,6F,74,17,A5,A4,7D,2A,16,F2,D4,E3,FA,BE,D3,53,0C,BA,21,FE,48,2B,36,34,B9,CB,5B,1E,73,B1,60,C0,87,4A,90,E8,15,2F,7A,AC,C3,7B,E2,2A,C0,69,C9,E0,62,16,4C,E2,B4,59,14,2B,DE,97,19,35,BC,2A,F2,2F,FA,AD,43,03,82,4F,43,03,6C,B3,6C,CF,E2,0A,60,84,A1,CF,9E,90,20,C9,63,16,09,BA,2E,84,58,B8,F4,4A,36,08,C4,5D,D5,BF,99,B9,88,32,F1,46,B0,60,7E,F6,94,8B,B7,90,4D,CE,26,FB,07,88,47,34,5A,8E,EC,33,33,12,23,CF,23,F5,98,B9,5F,73,4A,03,FC,5F,48,1C,46,92,30,ED,BA,9E,C1,A6,E3,E7,94,E4,2A,E4,46,7B,25,50,3D,08,33,4C,C3,82,CD,14,2F,A4,49,47,12,C5,EF,59,D7,61,9F,C6,ED,AD,00,5E,AF,3C,05,E0,CE,07,48,93,A9,49,8D,37,92,83,C5,CD,BB,A1,05,3A,0E,A4,1F,4A,1D,9D,BF,45,53,EE,CD,04,69,B2,25,FD,6C,F0,8D,DE,59,D9,EF,2B,72,75,9C,6A,23,1C,40,35,5E,56,C7,D7,2D,C4,33,16,0F,C7,AE,39,34,BD,A8,76,0E,A9,D8,DC,A9,F6,13,BC,FD,BD,EE,0B,DC,74,A5,83,D6,EF,CB,56,43,88,B7,1E,35,87,BE,8B,B3,1A,8D,5F,87,48,76,28,A2,AE,0F,A8,6A,93,DB,D1,4F,86,EB,46,AF,B4,49,0E,4A,70,CD,4A,29,4F,B3,9B,C3,F3,AA,25,59,EF,E7,B0,2B,24,85,C7,7C,4A,71,35,36,CD,8D,2B,70,A6,16,2F,72,E2,2C,6C,4C,74,DC,A7,B7,34,52,AE,87,BE,C8,C1,51,06,16,CD,2C,45,F2,F7,B3,BC,84,BF,4B,9A,F2,9E,76,FE,BF,9C,22,C9,96,01,8F,E0,74,72,90,25,46,61,5B,16,2A,D3,5A,5D,59,59,94,61,5A,47,43,D8,C4,A6,54,57,E2,2D,03,16,A5,B2,57,B5,79,B9,0F,F7,7A,E6,35,11,9B,E7,A6,52,7B,F9,A1,8A,20,BF,2A,00,AC,29,61,E3,29,60,6E,33,C9,4A,99,A2,6A,AE,7D,9C,D7,C9,B6,FB,0D,C3,39,BF,A0,81,DA,E1,10,E4,B9,79,42,6C,AD,2F,BF,D3,F0,77,A7,5D,39,42,28,85,9E,1B,B8,DC,64,00,CB,B7,9A,D2,A7,E7,B9,A1,F3,F9,46,BC,E7,CC,F3,04,80,FD,3E,F3,97,DF,6C,59,62,D0,86,6E,6A,66,66,F5,6D,D0,4F,D5,D5,1E,4F,46,B6,74,F2,DB,37,42,5F,31,E6,99,78,C1,DE,DD,D2,E5,70,6C,38,0B,07,1D,8A,AE,C2,81,85,BE,6C,AD,D9,2A,93,2D,51,92,7F,37,D0,F9,12,43,A8,68,86,36,EB,6B,63,F2,C6,76,10,1E,3E,28,48,39,AB,4A,F4,1A,1B,FE,23,15,28,B3,D2,8D,4E,59,24,5A,AF,E3,5B,8B,7D,BD,A2,07,7E,93,7D,B7,FB,71,0B,6A,B0,1C,A3,49,F9,AE,DD,3E,67,47,DB,C2,38,1D,13,FA,19,41,CF,3E,4C,38,B9,B1,84,CC,64,59,F9,E1,99,50,BC,3C,FA,38,4B,A2,1E,AB,6B,C4,4B,35,D6,36,C2,C5,FC,9C,D8,53,B6,37,6F,7D,91,48,7D,94,AD,30,33,A6,7F,E5,0F,CB,CF,87,24,20,19,EA,00,3C,7A,8B,84,95,E0,E7,DD,05,1C,7D,8D,E9,AE,96,51,BA,4D,E5,D8,BA,9C,42,AE,09,E0,A3,74,21,FE,47,0E,D7,89,51,50,DD,2E,91,2A,DF,7C,13,2E,2D,29,10,93,D5,0F,C8,E5,49,CC,75,7F,95,7C,9B,18,51,60,3C,FD,F5,9B,B2,98,91,0A,0D,C2,1B,99,E0,E2,21,97,EE,F7,95,D6,9F,B0,9B,34,27,50,B2,7A,00,4E,7D,4E,06,2C,69,63,6B,63,DF,47,6B,3C,9B,D4,FA,D0,B2,DD,E0,50,31,7E,0F,FA,3C,BE,8B,07,87,7B,A8,5D,1C,A3,5D,E3,2D,E7,19,45,56,AC,6E,09,36,AF,D8,22,36,83,F2,FC,53,F9,50,BC,3E,8B,CA,71,F0,8B,1D,33,CA,67,D2,61,E3,96,92,35,73,E7,8D,FE,BC,28,C6,DB,B1,30,EF,F7,A0,15,2B,1E,7D,16,E8,D2,E9,2D,1B,5C,0F,55,E6,D5,EA,E3,59,E8,EA,AB,15,21,0B,2E,95,1D,08,0C,6F,66,66,96,21,E0,67,F4,4C,EA,A5,E0,7B,6C,3C,7E,C5,63,42,AF,C1,0D,31,6D,46,95,6A,B5,46,5D,33,B1,74,31,E7,19,F9,E5,0D,6E,F8,96,94,FE,20,BD,17,E3,1B,77,3C,0B,CC,0B,DC,B6,A8,73,79,F6,39,E3,13,A5,F3,DC,03,E3,CD,F0,F1,D5,17,64,09,67,17,0C,2F,14,F9,90,8C,F3,2F,25,90,72,F7,87,16,24,34,3F,3D,75,18,E8,7D,B3,7B,F2,8A,36,01,B1,8A,33,EA,24,AA,FF,45,8C,89,B9,D8,BE,CB,8E,C0,53,58,75,82,16,59,2B,BE,25,E7,48,67,F1,19,32,F3,F9,0A,DF,AC,34,00,0A,47,C8,BD,48,4F,D9,A2,27,08,67,2D,87,54,9F,D8,ED,B3,35,35,E1,D8,F7,C3,3D,48,25,33,4C,8E,77,EF,82,DF,F2,8C,86,5A,50,8B,B3,1B,BE,CF,22,12,F6,0D,7A,D6,4D,42,31,B8,2F,9A,1F,06,29,DA,6B,7C,25,54,30,86,B2,E2,34,21,00,74,95,DA,1E,FC,7B,EF,8B,F5,27,C3,5A,FD,04,E8,D5,73,25,32,97,F8,55,EF,CE,1F,F5,B4,5D,FF,7A,74,1E,30,B5,BA,ED,40,9B,99,3D,1C,90,2B,B9,21,01,E1,AE,76,C4,39,D1,FE,48,BE,24,52,B7,9C,3B,C8,A4,78,65,AC,6B,C1,35,9D,66,48,42,60,F4,60,6E,A7,76,8D,03,7B,F1,21,D6,76,96,3A,4A,C1,A9,61,82,27,64,1A,91,05,3F,6E,A2,13,4A,F4,09,8C,D6,99,42,BA,04,BD,92,D1,F5,FA,AC,9E,DE,66,45,DD,8F,A3,50,31,96,53,F7,0E,C5,A6,F3,DD,06,CD,7B,3A,0D,05,19,A4,97,47,87,E4,11,FC,33,FC,B6,1F,28,07,87,35,C5,D9,3F,E7,1E,94,C6,9E,0B,63,3E,46,B8,D4,D9,1D,9B,B3,2F,03,B4,90,E7,43,A9,09,8D,4B,29,6A,25,BD,91,D7,E0,48,87,EB,34,0C,96,C5,C1,B3,8D,5F,60,4D,67,0B,93,0A,C0,BA,35,FD,1A,D8,2D,B3,7D,06,4D,09,94,66,50,C8,A5,26,ED,9F,E3,B2,9C,62,F8,DE,BB,8E,37,CB,C8,D9,FD,C5,B1,9A,D9,B2,05,51,7E,5C,B8,D8,DA,68,BF,A5,BE,78,EA,A0,CA,87,2B,B6,8C,F6,E4,7B,91,07,A1,E3,A4,5B,7D,1F,D7,5C,11,F2,57,9A,89,D2,4C,AA,E5,84,FB,2F,2D,05,B8,34,88,48,B1,E0,8E,88,13,EC,E7,F3,29,B9,CC,A7,35,2A,83,BE,19,2D,07,F7,AC,54,6E,70,4D,89,F1,88,77,0E,04,72,C4,30,EE,0C,A5,40,6B,D6,8D,E8,EC,00,54,61,07,27,15,AD,F0,36,03,1D,9F,FA,1E,82,51,6E,76,D8,FC,EB,4D,F6,A1,4F,10,68,EF,AB,B3,B7,7F,E6,FC,2E,D1,21,94,BB,FE,A5,A4,60,9F,8D,69,04,4F,37,E5,DC,30,6A,BA,74,F5,5B,EA,FD,09,AD,C9,A6,0D,E1,23,9E,AB,97,7C,9D,99,99,80,5B,4E,D2,F3,94,4E,1C,F8,E4,48,BC,A9,CA,A3,E2,D2,4F,84,7C,03,5B,75,25,80,9F,C1,AA,CC,4A,DA,6B,EB,38,FA,DF,5D,93,D0,D7,5D,56,6D,67,23,1C,8A,4E,82,8E,58,B4,B9,39,E6,58,DE,1A,2A,37,7E,07,26,47,31,D3,70,A9,CE,C8,8D,DF,B9,15,DC,34,9A,74,C0,9D,F0,38,86,55,D8,D1,AE,87,46,E8,5D,63,F9,14,4E,47,AB,C5,6E,F9,BB,40,E0,33,9C,6E,01,B3,12,0D,D6,BC,90,C6,4F,B8,D9,86,86,8E,C6,84,35,D7,2A,31,A3,52,71,63,33,B9,BF,17,46,0D,8D,ED,C9,AA,96,D4,EF,58,85,C5,62,02,6C,4D,6E,BD,DD,F3,F5,15,92,02,AD,21,F9,C3,7A,49,37,F9,6B,88,B1,14,C2,8E,77,EB,E4,F1,2D,CD,09,17,B4,C0,EC,18,1B,B4,44,34,FB,05,81,D3,6A,2F,FC,09,82,F2,6A,84,85,EC,03,27,52,72,59,32,30,BC,BF,8D,AA,6F,2F,A3,2D,7F,39,5B,CF,25,F1,68,42,98,34,A4,7B,5E,20,EE,9E,31,E2,C4,A0,D9,24,3E,FF,56,0C,91,AD,D3,18,1E,CA,01,D7,0B,A3,A2,24,B4,DE,34,E1,C5,A2,04,8E,E3,84,F7,42,78,86,DE,F2,BF,2C,CD,34,97,4A,E4,59,0C,F7,3A,A8,6A,30,D2,2B,30,AB,D2,92,84,EC,31,B5,24,68,81,11,56,5B,8F,78,1A,FC,40,C3,58,BC,89,92,D7,52,CC,7D,3F,65,89,60,C4,CF,A6,0D,1D,7B,A5,16,78,8A,4C,52,37,09,A6,52,84,B7,C2,59,29,B8,59,93,E2,96,80,E7,3E,02,AA,C9,DB,A3,50,1C,5C,9C,ED,CE,6F,BA,8C,44,8F,3C,0F,94,B7,B5,89,64,F3,3E,6C,F6,F6,02,C6,4C,05,77,A1,18,CD,F5,61,53,AB,99,52,6E,26,DE,A2,D7,A7,85,C0,FA,C5,CC,8D,6B,B9,10,6D,60,27,CC,B9,A9,47,AF,F5,43,50,70,46,C2,57,6F,74,A0,7E,1A,75,6B,A7,65,9D,C4,F1,25,DB,3C,C8,A8,EE,CB,23,79,44,67,AF,5A,AB,CB,EA,EC,4B,2F,9A,D6,C8,64,09,34,19,9C,D6,23,C0,44,0F,D3,C2,7E,9F,0C,73,04,12,41,10,C4,9B,90,B8,F4,CC,05,69,AD,23,BF,8E,2E,5C,02,6C,92,E7,4C,D3,02,CC,F4,AD,65,20,88,BD,8D,B1,52,81,38,57,D5,B4,BC,5F,95,CA,9F,A8,B0,9C,18,14,89,E1,4F,71,47,C2,B0,63,5F,F5,2F,6F,54,A0,7B,A5,D1,25,FA,14,D5,08,DB,05,E6,76,69,2A,A8,73,6E,89,93,D8,0A,E3,03,E9,1C,DB,F8,09,41,1A,C4,45,33,F5,8E,4A,DB,E1,C6,63,B0,0B,21,1F,55,91,E5,5A,09,35,7E,0E,39,F9,1C,0D,19,59,46,0D,8A,CE,36,F1,2D,6D,90,9C,0A,61,73,E6,10,A9,D6,7F,77,33,0B,A0,4F,8C,48,D6,81,66,FD,B5,69,B2,8D,81,09,72,C7,1C,1B,86,2B,B9,1C,AF,EB,E9,81,65,DC,33,4F,C0,8B,99,95,F7,30,F2,13,7C,D8,FB,FE,1D,93,E8,5B,4D,D7,AA,9D,87,72,E0,3C,3C,DC,AE,F5,FD,6A,A0,18,E2,52,3C,59,B7,A5,01,CB,85,63,81,C9,1F,66,94,B6,0E,CD,09,35,43,A8,AF,D2,73,2F,53,E0,19,68,8D,97,D0,BA,68,9D,CE,A1,C3,5F,CF,04,B5,9C,C6,AC,53,6A,7C,EC,1F,15,E5,48,20,24,88,33,E2,D8,E9,F9,B3,0A,34,48,A2,F3,A7,8F,C8,B6,CC,DD,27,A2,A1,8F,3C,4C,62,88,9B,0D,3C,C0,A9,B4,AF,9E,39,E7,9B,0B,6A,BC,1D,97,5C,E8,40,1E,90,67,35,9F,88,C4,17,69,08,74,B8,98,B5,E3,E4,E9,70,C4,27,F1,63,4B,17,E8,61,5B,72,86,37,B0,34,AD,5A,5F,F6,22,71,6E,67,24,3C,45,73,C1,05,E0,B8,08,B8,01,B0,36,58,D1,4C,98,8D,89,22,68,63,98,27,79,1C,0E,C8,14,76,FD,E0,24,BF,4D,56,2B,7B,B3,88,14,5B,33,B2,BA,4C,F6,70,73,65,5D,79,9E,5E,90,27,A5,46,C5,98,B9,A0,A4,97,D3,EA,5A,3F,24,2D,ED,49,DF,B0,A3,5F,7D,E2,AD,77,25,5C,AB,25,CC,26,93,18,E5,A9,41,07,EB,A3,67,36,05,E8,F1,5B,2D,52,9A,04,1D,AF,A1,56,C5,6D,8D,5E,B5,86,99,4F,83,35,C7,25,F7,2F,2D,2F,C9,6A,73,82,8E,4B,72,4E,C3,89,E1,84,00,C5,AE,E6,BC,93,21,87,70,2A,64,07,DC,57,A7,92,8A,11,73,8E,45,00,2E,7F,F4,5C,30,FD,9D,73,57,28,3B,5E,26,14,12,C8,25,34,2A,15,48,E5,60,C6,A3,E9,C8,9A,0E,16,49,49,EF,1D,91,33,E9,A9,EA,54,FD,25,A5,2B,3C,70,D9,10,11,23,7D,DF,0B,5D,14,AB,B7,E2,3C,B7,61,67,7A,0C,DE,DD,83,F2,D3,AA,07,4D,DD,79,D6,A2,DA,CA,6E,6F,15,55,D1,C5,70,88,A4,CC,DD,BD,81,34,44,F2,57,9F,0A,CC,FA,77,7F,64,36,38,4E,9D,72,3B,16,BF,9B,DA,7C,FE,03,2E,E8,9A,54,97,A4,67,56,82,F7,F3,3C,C4,FE,C5,7E,61,D2,29,AC,00,6C,55,AE,CE,84,98,6F,7C,63,39,67,97,1B,23,22,2D,50,6B,8F,AC,F0,C4,73,7C,48,EF,EC,68,B5,21,47,89,FC,6F,50,6F,B9,B9,97,77,C2,BE,4C,5B,B2,01,3E,0E,EC,56,33,89,8C,11,4F,FB,36,E4,6D,C8,85,D6,1C,89,E8,CB,CC,10,83,AD,C2,E4,3B,14,65,90,84,E9,41,DD,61,07,78,12,9A,AE,DF,D7,A9,1F,A0,96,30,BE,00,8F,33,4E,DB,40,39,8B,35,87,45,8F,FD,68,27,C0,95,17,6C,6C,2F,32,F9,6F,7E,15,AC,CC,4E,05,9B,98,8E,D9,81,18,42,DD,8C,96,0C,3C,FD,A8,25,A7,61,8F,65,61,E6,F7,1D,15,24,23,20,06,90,7F,93,76,24,F7,59,58,EB,11,79,10,D8,9D,84,0B,AF,56,38,57,13,C9,75,35,3B,C8,54,8E,80,1C,6F,46,57,63,43,D5,0D,11,54,15,F4,8F,14,2C,28,0C,C0,FD,65,A1,3C,35,0C,52,6F,88,C8,CF,39,DA,F6,BD,14,4D,53,75,2C,B0,9E,55,81,0F,4E,B9,57,9A,48,FE,8F,FD,64,88,CE,6C,43,1F,CD,84,39,F1,8D,61,B3,06,C1,39,D2,82,DE,FF,BC,99,98,1D,88,28,E7,46,EE,EA,C6,18,8E,22,BB,3D,09,E2,06,9D,B0,10,36,D1,CF,8B,3C,22,21,E2,48,D7,2B,64,06,03,CC,F1,7F,82,67,FF,F7,90,66,9E,62,15,81,A8,1D,EF,FA,6F,1A,20,A1,F0,DA,6F,A8,57,46,41,07,74,07,B6,F5,F2,AC,DB,8E,EE,B1,44,F9,6A,AF,03,48,FA,B0,8E,04,8F,15,D5,73,50,AC,2A,3F,CF,B4,C7,03,2C,AB,9C,A8,67,E7,71,B2,3B,80,99,EC,56,05,6C,32,8E,95,B6,23,33,41,92,08,93,15,0A,BC,78,09,8D,9A,87,65,BB,D2,11,77,EF,8B,C6,48,32,39,70,10,7A,21,32,67,F0,AE,EF,9B,C6,45,32,CB,28,17,80,CC,37,D9,21,02,90,C7,C4,3C,3B,A5,F7,A8,C1,59,0E,25,20,3A,58,F8,94,45,D7,A5,91,86,2D,93,5A,DE,D9,97,C4,B3,6B,02,39,EA,28,8A,A4,74,9A,AF,7C,C9,A3,3F,87,97,47,52,4C,70,09,C4,13,B2,58,15,1D,14,B0,31,4C,7A,90,EB,24,14,07,7E,F9,DB,F4,0C,8F,37,49,63,C5,FA,6F,28,16,D0,68,EA,24,68,22,54,26,37,4C,FC,6E,28,80,AD,57,86,D9,6A,16,99,8C,9B,49,D8,79,52,97,E5,8F,A6,55,A3,EC,FF,25,55,DE,0F,FF,50,B3,61,DE,A6,F8,2D,E1,F0,71,85,F0,9B,4A,6D,8F,DA,30,85,05,B4,FF,A4,49,67,13,F6,BC,A8,CE,23,9A,84,AD,A1,E1,F6,2A,50,48,B0,84,B4,54,6F,E5,64,43,41,EE,05,A4,2A,6F,0F,93,8D,24,CD,D4,05,31,AC,CA,53,2F,AB,9F,29,6D,4C,7D,40,BA,A8,DC,5D,ED,C0,C0,D1,F0,E8,58,EC,82,F1,E0,AC,0B,9B,E5,E6,B0,E0,BF,D5,9C,CD,8A,75,CC,6B,A1,54,E9,4B,7F,54,D9,16,03,85,CB,D9,2E,05,78,0E,6C,FC,A0,77,D4,96,37,32,30,6C,52,A4,2B,17,C2,88,45,17,0D,1F,A8,E2,B9,C8,0A,57,BD,EC,AA,F6,FA,21,DE,AA,EE,3E,E6,DD,67,E7,F6,DB,CA,74,78,12,92,06,E9,B6,38,69,8B,ED,ED,62,7E,67,BE,20,1E,46,FD,33,91,14,EA,23,A4,A3,22,5D,D0,A2,D4,E0,84,32,77,3A,DA,64,51,BD,58,83,E9,1F,71,31,44,9F,05,C6,15,EF,B9,29,6E,4C,B0,16,C8,05,F4,1C,23,A7,03,09,0F,EA,E3,CE,3B,F3,D5,1E,EE,05,C6,A7,41,84,B8,8A,47,45,30,B7,3C,2C,68,9A,C5,27,6F,05,3C,CB,B4,80,2B,41,6F,68,19,03,50,54,A7,AD,39,A4,F9,A9,0D,14,32,AE,CB,E3,FB,BA,8C,3F,FD,60,D1,B9,3A,65,5E,B3,45,BF,1E,03,94,CC,50,46,4D,09,FC,85,B5,4C,48,42,2E,0B,63,91,83,62,68,B8,73,63,CC,66,74,F9,19,08,FC,89,4A,E2,06,6B,8F,11,5A,36,E8,67,8C,F3,31,F6,33,12,A4,1B,8C,D3,14,9D,55,FF,04,8E,7D,52,EF,9B,48,55,D9,62,2E,AE,BF,B4,58,DB,53,3B,3B,2E,18,8F,3A,D8,E2,0E,B4,09,F5,59,A2,C9,40,29,E6,3A,BF,E6,8B,90,F7,E4,5B,46,5F,A7,8A,CC,1E,2F,B6,D7,7C,DD,E6,57,AD,B1,0D,0B,50,A7,51,C9,67,2D,B8,10,68,2D,B0,3F,0A,ED,7A,57,6C,3F,98,87,8B,06,E0,58,4F,47,CC,10,A6,72,11,FA,A2,B9,D5,6C,B3,5F,DE,00,CE,A2,72,96,11,05,A2,6C,A6,9D,04,87,67,94,FB,9C,C0,FB,DB,24,38,FC,0C,42,CD,7E,49,F8,5B,B3,E4,3C,31,74,8C,FC,70,64,A5,8B,66,0C,70,AB,FE,A8,6A,81,7A,78,CD,54,D9,B0,97,F6,25,49,AE,86,57,D3,93,B6,6A,60,5E,EC,35,A4,12,00,FD,05,35,E7,0F,2F,2F,CB,5E,7C,0A,D4,1A,18,92,36,26,16,AE,82,10,20,79,0F,66,05,82,92,3B,59,E7,06,66,22,00,AD,42,E0,97,3B,C2,44,AC,1E,9A,90,7A,09,BF,39,21,21,35,D8,6E,CC,61,23,06,BE,DB,63,0D,A7,5B,4B,B2,D6,C0,E5,0D,7F,1A,C4,8E,79,0E,7C,E1,7C,CA,46,65,18,4E,8A,16,56,5C,E0,99,3A,D1,CA,8B,C0,BD,79,07,44,75,33,2C,8B,73,94,5B,E6,5A,6D,35,20,71,20,B3,F2,16,47,D8,8E,EB,1A,36,ED,18,92,F3,72,01,18,DB,9E,0D,78,CB,E5,A6,24,E2,E2,53,33,1D,93,24,FE,40,E6,64,40,BB,A9,49,D7,FA,73,2B,BC,F0,3C,64,EA,B3,0B,C4,4E,01,FF,45,AC,FC,A5,65,BC,41,98,82,C6,E3,EB,EE,51,5D,B7,30,20,67,2A,09,34,67,19,44,B7,AD,D9,58,F5,FE,BD,3F,14,E7,A0,E6,64,98,15,01,AE,99,96,CE,B8,78,5E,C9,A3,A8,1A,26,89,DA,24,60,F6,CD,86,EA,8D,89,43,80,B0,35,0E,C4,D9,FA,C6,5A,CD,93,9F,70,F4,39,F0,D1,13,FF,A5,82,A1,3A,DF,FB,D7,1D,54,55,5E,0E,81,BE,6C,AE,19,93,47,FE,E9,EC,4E,64,72,54,61,4F,CB,68,9D,CF,3C,2D,B7,65,7F,2F,03,A4,7D,EA,3C,6C,05,DA,3D,8F,85,08,8C,D3,90,67,BF,95,E1,2E,70,A5,65,1F,B0,B7,11,2A,6B,29,7E,4D,E9,2B,E5,12,4F,36,52,FE,06,CC,DC,91,91,B0,01,F7,F3,C1,82,1D,5B,44,9A,CD,B8,67,80,53,B7,58,C9,C3,56,51,43,42,17,3C,3D,2E,22,59,93,A2,B8,53,AB,D2,50,00,56,3B,62,F6,F3,84,2E,F1,65,52,0C,B2,B8,F0,F4,81,51,93,1D,85,19,57,CF,63,95,34,92,15,07,BA,78,7F,6E,2B,0E,72,5B,50,E7,6E,A8,09,31,2A,4E,A4,00,A3,54,D3,8C,30,FE,D9,54,A9,B3,F2,BB,5B,22,76,CC,19,F1,8A,D0,1A,07,B0,67,C5,0B,31,A3,60,83,BA,6B,9E,25,0E,5A,0C,7F,17,26,DE,1A,3F,9F,F6,25,FE,36,08,83,6D,BA,E5,DE,08,78,64,FF,63,60,59,D7,06,B8,D7,84,CE,89,F9,AE,21,A1,7F,01,FB,CB,E9,54,49,BD,2D,68,C8,40,76,22,AB,20,6E,C7,6D,76,D8,CA,96,36,92,0D,26,36,2F,E7,65,F6,02,08,2F,F2,EF,5B,AA,19,4E,12,67,11,1D,2F,E3,D1,12,08,35,8D,8E,7F,59,00,A0,9C,2F,01,5D,ED,F3,13,0A,AB,6E,6D,09,46,5F,3F,E2,FA,A3,B9,A0,2E,BB,DF,F2,69,78,C6,10,07,53,E3,CA,6F,36,07,FB,F1,21,27,5A,DA,23,01,48,5E,B4,34,C0,A8,F9,89,64,32,6D,25,FF,1D,5C,4E,30,01,0C,58,58,2E,88,8C,B5,3A,6D,A9,FB,D2,D7,98,67,3D,E8,B9,78,EA,07,98,64,B6,4E,BE,B8,79,63,C9,04,3C,4F,B2,27,F3,37,B2,96,29,0D,FB,3A,1B,5E,CA,E6,90,AE,FC,72,76,1D,88,D8,AE,96,E8,02,97,F0,0E,2F,77,87,74,75,84,1D,96,35,2F,F9,3E,1C,86,98,8C,0C,BA,51,2F,7C,5A,B1,85,0E,50,3A,45,7C,00,FA,AD,84,10,AB,42,95,AE,13,21,B2,CC,B1,28,92,E2,93,3A,47,13,63,3C,18,45,87,8B,67,2D,B7,62,21,6E,B7,55,80,81,11,B9,5E,F0,3E,EF,77,49,4E,2C,45,ED,6B,79,01,42,EC,4B,2C,78,A9,B1,08,D9,3E,0B,61,52,9D,EE,B1,A5,20,77,C8,C9,89,51,A9,31,2D,C0,89,E0,AB,81,31,1D,95,F4,A8,BE,7E,8B,EF,D5,F8,24,69,0D,A2,63,00,AB,9B,CC,BF,A4,9F,96,FC,E5,B9,36,86,39,60,F0,CF,B8,59,DD,82,A6,D5,5A,D5,05,B8,BE,D7,47,56,59,C8,D8,DF,8C,AD,D3,97,5A,D6,4B,B7,4A,A6,68,B5,95,5A,26,FD,BD,D6,2B,D5,5F,39,CF,24,7A,41,7D,F6,75,92,48,2D,A2,3A,2B,8C,CD,E4,77,C0,E0,F8,1A,37,4A,90,47,C2,79,A4,16,27,B6,C7,DD,2F,36,F7,23,11,30,08,0C,1B,DD,D0,30,DA,10,E2,C2,65,92,0F,CA,B9,9E,D8,6D,F1,50,46,13,03,24,64,DB,C5,B6,9D,A7,D2,0B,56,F5,75,F4,35,1F,2A,FA,59,F8,6B,C0,28,CB,04,74,44,AD,46,3E,1D,CB,3C,84,09,B3,00,BA,5B,16,42,3B,B4,5B,8E,DA,FC,D7,C8,ED,A4,11,46,67,1A,38,5B,CE,8C,FE,00,3A,65,A1,EA,24,22,53,30,89,16,9B,65,77,77,DB,B7,69,30,80,A0,2C,07,89,FC,75,53,92,97,90,18,B1,6C,30,97,A1,19,48,BD,96,8B,DC,48,40,A9,8E,B3,6F,83,50,37,B5,2A,B4,FB,D7,2E,86,81,2A,39,F1,62,69,60,0E,E5,38,A6,2A,25,3E,26,B1,D3,A5,FB,FC,05,C7,B0,4E,BA,FB,63,78,7F,E5,8D,1F,A6,51,53,57,78,E7,37,7C,96,DB,C8,3D,EF,29,A1,E0,C4,34,D4,10,6C,F8,57,9A,6A,E9,6F,26,B1,C7,E9,A2,4F,B8,EC,42,CE,E8,8F,2C,57,20,DE,07,F4,56,8F,02,6F,03,F6,DB,B1,4E,01,DD,AF,A0,9F,AB,23,0A,D4,E1,D5,7D,94,87,BC,F8,7A,05,63,32,ED,79,9D,4C,AA,80,B3,67,1A,82,1E,B2,F1,A1,36,DC,31,67,8A,04,1C,F3,B6,DF,4D,E0,86,54,D8,BD,A2,42,94,DC,3F,50,4A,CC,4C,9F,27,FF,D7,55,3F,EF,B8,F8,62,D3,9E,21,54,12,07,9D,A4,91,05,53,98,D2,3A,22,B9,EC,2A,21,77,98,A3,21,81,BC,FC,8C,12,40,75,DE,9C,54,3F,9C,09,40,E4,45,EF,09,75,C0,79,C0,07,28,35,2A,D2,8F,8D,80,2A,81,E8,E8,FD,7D,AC,C5,19,97,F5,FC,9F,C8,2D,7E,9F,10,E9,4F,D8,16,03,10,49,CC,FB,8F,40,E7,49,FC,37,0E,B3,16,70,71,1C,38,01,91,CF,B5,BC,D8,69,C0,05,73,3E,71,F8,3F,BE,AF,6C,80,08,06,11,F0,22,60,A0,24,A4,70,C6,90,7E,63,FD,CE,A4,0A,03,26,D6,06,1D,97,1A,E2,D5,75,21,CE,DD,05,1F,89,43,96,39,06,91,A3,1C,9C,6D,F4,57,AA,6C,9A,A8,66,FA,D5,A9,33,37,F1,54,DE,91,FE,DF,E4,30,9B,1C,F2,92,44,C5,68,F6,A8,63,6B,5D,B4,8E,A4,C0,3F,55,7A,3D,EE,A2,97,4B,EC,B9,7E,CF,CD,50,C6,ED,79,31,A1,52,EE,02,48,A9,D1,1D,DE,7E,21,60,EC,19,66,F2,A9,6A,6B,74,42,89,25,A8,E5,B0,CD,7B,C1,7A,52,38,9B,16,27,51,4D,60,29,CE,DA,2E,F2,F0,B8,E3,5B,8C,41,C5,F1,0D,3A,B6,A1,5A,D7,FC,3D,F1,C7,96,5D,9C,DE,F2,F6,B4,6E,B6,95,E6,24,79,07,20,62,5B,76,26,BD,DD,8F,2C,53,5F,1E,13,1C,DB,80,7B,E2,B6,69,0E,BB,5B,E1,68,83,40,CF,33,2F,35,36,31,7D,CA,28,37,6F,44,37,99,2E,71,56,E5,A9,B9,A8,18,59,07,BD,04,45,DA,4E,1F,34,62,38,14,25,66,EA,5D,BB,04,08,5D,D9,03,90,89,5E,6B,55,D8,E1,98,A4,FB,90,34,3F,47,4D,7A,48,08,8E,99,09,C6,29,98,34,49,34,44,BD,B4,07,D1,A7,D5,81,DC,78,5E,E7,EA,41,4F,72,C1,83,AB,72,91,FC,A9,ED,54,FB,BE,63,FA,EB,27,96,76,7D,98,90,86,BB,C1,89,B9,CF,49,0B,28,5A,94,A1,5A,1D,C1,51,C0,52,50,49,C9,70,34,7C,3A,6A,91,36,57,10,4A,2A,AE,71,77,DD,A3,02,02,CD,62,F4,D8,F1,0A,46,D4,57,88,C5,2C,A5,CB,F2,92,5B,1C,FC,30,3E,AF,6D,C4,A9,91,DC,D6,DA,35,19,18,A4,31,09,F0,E9,56,1B,AF,1B,08,F3,27,D9,0F,3B,D5,21,B0,AC,D3,2A,4F,4D,CB,D1,4D,67,5B,89,BD,09,F6,27,55,E2,A0,AA,60,7B,58,2C,65,C4,4F,40,AE,DB,8B,B4,A4,75,B0,6D,E9,E7,25,CD,E4,99,E9,5F,ED,4B,8A,82,F9,9C,B2,29,AF,E1,8E,79,F7,2E,48,BB,9F,62,34,75,86,8C,96,F8,4E,96,4D,34,12,D9,6F,56,37,FB,4B,F6,7F,30,6F,77,05,85,CE,F1,94,EE,50,90,E0,EF,1A,6A,B4,DA,BC,2D,56,68,91,AC,36,66,D4,53,7A,65,24,99,98,7B,FD,C5,B8,43,3C,AB,89,2C,60,E2,F4,C8,CE,B0,AA,69,B9,7C,11,14,04,DF,57,7A,1E,51,16,BE,EE,31,8D,79,C1,EB,A7,A9,A0,2E,85,A1,58,72,58,BC,67,1F,48,36,30,0D,31,3B,8C,68,59,A9,86,43,A2,63,BB,5E,7B,17,F7,93,9D,CE,74,82,0C,27,D4,33,C2,CE,5F,E3,7B,BD,F9,26,99,35,D3,E9,4E,87,3F,80,51,E8,66,66,AC,C7,FD,12,E7,87,65,EF,AC,5D,AF,B2,6B,77,2B,A8,BC,22,66,74,39,32,20,1A,AF,94,00,B6,83,C6,64,7F,93,43,5E,CD,33,17,D2,31,06,74,1F,7A,61,69,ED,57,45,4E,62,1A,08,62,26,AB,E1,9F,D3,06,06,09,69,72,4C,67,68,1E,D8,36,FD,CC,CA,0C,16,81,2E,51,EC,7B,AE,40,80,46,FA,5C,E5,88,D8,A9,C7,7B,57,E7,C3,EB,36,F5,85,D2,D0,A2,0B,84,6B,7C,DF,DC,9F,B0,B0,7F,3F,7F,5F,35,10,CC,F6,B5,DE,E6,3B,E0,33,10,3D,58,A5,01,37,3C,B6,D9,04,8E,E1,6A,48,3F,78,5C,BD,12,B3,2C,D1,C8,80,BC,88,A2,4C,22,3F,08,27,F3,F1,6A,C7,E9,38,E4,85,E6,D7,87,DD,42,50,56,6B,BC,A2,29,ED,F8,F9,D1,71,97,43,0E,94,20,0C,40,31,4F,08,94,44,F2,51,7D,23,80,9A,5D,44,DF,7E,2C,E8,58,2E,31,70,3D,08,AE,31,48,CA,8E,07,72,68,22,69,A7,11,84,F1,AB,5A,B3,99,79,69,9C,D4,3B,8D,A3,30,10,EB,D3,11,F3,3A,B9,51,2E,57,6C,7F,0B,96,23,B0,67,3D,75,7F,97,60,47,39,89,9B,2B,97,75,7C,C5,72,82,0C,73,A1,7F,DB,C8,48,93,43,86,04,ED,E5,72,07,D3,74,7B,EA,FE,F3,30,7A,D4,22,F4,E7,74,C1,E4,54,53,1A,AF,5F,F5,63,C0,F4,C8,B0,58,B9,90,44,30,F5,68,F8,F5,D5,13,21,65,F2,7A,13,E6,C5,4D,0B,3C,C5,5E,60,BE,0E,8E,0D,33,3C,1E,54,42,3E,2D,EB,4E,AE,5B,36,6B,D7,28,67,25,6F,11,99,BB,F8,E2,CA,FE,11,51,22,90,CF,58,41,82,AA,47,BA,B5,86,7D,17,9C,9A,9B,6A,D8,0F,BC,75,35,28,79,A7,8E,5A,65,F1,58,75,BF,37,B3,52,F6,5C,00,50,43,A1,AF,FB,E6,95,D2,AD,44,C4,4D,3E,A2,91,A0,F2,C1,C6,E9,14,A0,86,6A,39,B0,44,0E,91,3F,F3,F1,FE,BA,E4,DD,E2,74,C1,C1,C9,8A,E2,15,27,55,BD,F0,A5,D8,35,B9,5B,6C,57,B4,61,83,24,C9,62,C0,6A,42,E3,FE,D3,99,CD,ED,9C,DE,E2,7E,22,7B,FC,F6,20,68,B4,39,6B,14,37,3F,68,05,E5,65,D8,11,10,83,C3,44,37,67,05,49,BE,AF,AD,35,A2,B2,A3,C4,7B,60,BF,7E,5B,37,95,D1,F6,AE,97,42,21,29,3C,89,B9,E1,2C,C6,EA,F3,C3,D1,50,54,5A,83,95,22,AA,47,03,32,D8,00,F7,76,46,D4,C4,16,BD,80,14,1F,0B,8A,DA,D7,65,86,36,2D,F7,F1,1C,83,B0,FD,04,92,56,DA,F2,B9,62,E3,47,34,BD,52,24,D2,2B,2D,B9,F7,08,5E,60,3F,71,C2,CB,F8,35,C3,DE,DD,CF,9C,8A,4C,BD,43,DF,0B,46,87,F1,84,CC,F0,3A,B0,89,D5,D9,2C,E0,9E,FA,F5,EA,50,53,D6,26,12,B2,6A,D9,9A,87,47,A3,CA,24,7F,5D,AD,8B,42,F2,03,97,75,26,E6,EF,F2,9E,DF,6E,7A,B3,FA,74,D9,53,1C,40,8C,0F,6A,29,59,BC,ED,39,23,70,E2,19,5C,F0,39,0E,2C,4C,3B,06,4F,DA,BF,B3,F0,F2,64,48,E1,F3,ED,27,05,BC,CF,B3,6F,8A,0E,27,3F,DE,5C,13,F3,FF,A4,9B,89,3D,AA,FE,20,BA,AE,B0,78,79,A6,71,39,84,5E,00,6D,96,26,D6,26,8E,AD,D0,4B,30,97,2B,D8,79,4B,78,51,61,60,D2,60,5F,E0,DD,E7,21,8D,0F,F4,FF,D2,6C,DC,3E,B7,55,76,2E,61,B6,29,9B,96,BA,27,F4,7F,3E,2D,9E,65,1C,BD,66,DD,CE,42,28,B6,BE,E2,20,93,A3,74,C1,28,F6,C7,67,05,5F,2A,34,67,15,F1,F0,17,AC,66,AC,73,50,3C,B7,72,63,6D,A8,F7,B0,EB,B6,7E,7B,92,CA,33,C8,31,8C,A9,78,06,04,54,E4,99,BF,62,63,6D,5B,66,6A,F0,28,6F,94,A6,6B,BC,BB,3A,24,24,C0,32,80,A4,2A,DB,39,06,50,28,28,59,EB,7E,CD,8F,2C,58,D9,51,37,C8,F5,38,5B,3D,A3,D2,3E,BA,AE,E7,5B,F5,53,07,D3,F8,F6,8F,17,42,37,BC,3A,4A,7F,E7,5F,AF,CA,59,2B,E4,60,81,4B,8E,6D,60,14,9C,8E,4A,34,40,85,F3,50,C0,5A,62,4C,08,D8,27,D2,DA,8A,8D,44,B6,C6,95,6D,79,37,3C,EF,BF,3D,2A,FC,CA,77,29,4B,1F,26,0F,B7,C7,9E,3A,92,FB,EF,4B,6B,5E,0E,F1,5D,6E,13,8E,4C,0B,EB,DC,5A,CF,B5,A3,99,FB,87,39,05,75,08,4F,23,AE,EE,8C,37,3F,F0,8E,A8,2E,A3,FE,52,17,73,93,1F,D1,B2,11,55,A8,17,0E,57,C9,47,D1,AD,88,19,C7,64,F7,B8,7C,26,D6,DF,AC,DF,C3,B6,9D,1F,22,51,A0,4B,2D,83,DB,D0,C7,04,2C,CC,D6,F3,69,8F,6D,7A,08,2D,08,4E,F3,CC,25,52,10,D6,6C,0E,82,B5,83,B9,B1,71,02,E5,34,B2,FC,4A,65,2F,0B,78,28,F9,8C,98,DB,6B,0D,9F,F5,E1,EE,7A,24,C5,0A,C6,1B,E8,ED,2F,8C,10,45,E6,D1,9E,78,AF,BA,DA,FF,2C,06,02,77,05,60,45,E1,8D,8A,14,92,06,A1,65,A9,2A,B7,3E,F2,C5,DD,D1,A2,39,8C,85,27,05,7C,E9,5A,FA,BC,9E,F7,5C,20,B0,C6,2C,40,28,36,59,88,E5,00,1E,94,1C,BE,84,74,C9,33,7A,EA,E4,72,E0,BE,4E,34,29,BB,F5,D4,83,B4,04,E7,D2,2E,89,A0,1E,2B,5C,C9,9E,E1,E2,5D,FF,91,3D,7A,9F,BC,5F,0E,C9,5A,6A,DD,FD,C0,09,7E,5D,B4,D3,B3,63,4B,BE,ED,4D,C0,1E,DB,D9,DB,4A,EF,D7,58,2E,47,1B,F0,17,B6,D7,EB,DB,4C,E6,E3,20,28,39,42,32,1B,AE,81,1D,8E,E5,BA,21,71,A1,C6,8A,5F,73,78,50,F8,F4,63,E5,A7,BC,33,4A,87,BA,E4,43,18,55,D3,1C,35,CF,57,9A,53,B1,4E,64,72,8C,B8,AD,E5,EC,BE,49,F4,BA,69,66,D1,79,26,05,2D,F1,74,0F,51,4E,14,62,A3,69,07,7C,A5,61,70,8A,73,C0,AA,96,3B,A1,1E,D9,35,EF,62,CE,42,5F,5F,B2,FB,D4,F3,25,D7,D7,8E,D1,61,B5,3A,8B,E5,D5,17,51,42,7E,41,3C,A8,ED,6D,F4,69,01,7F,F5,F9,BF,2C,D4,44,91,98,15,6C,6C,43,89,AA,D6,B4,B6,0B,55,75,D5,8E,42,FC,88,AF,17,D7,0A,55,C7,19,16,F5,BD,9F,74,86,92,2A,F4,5F,F6,6D,A6,32,9E,81,50,0D,46,8D,66,D3,1C,54,37,94,91,30,5A,44,42,5B,34,52,89,97,2A,AA,56,1C,F2,42,15,9B,04,45,48,84,CE,7C,36,17,55,C7,CE,31,5E,1F,F1,88,A9,28,98,68,C0,15,82,F4,5C,8B,6E,96,B9,F3,2D,CF,77,DB,82,0E,AA,34,DA,11,BD,10,E7,67,ED,A9,B7,34,B4,EC,18,01,09,AE,18,DA,22,8E,05,5E,83,02,DB,0F,F4,6A,6C,E0,EF,52,67,48,02,BA,01,02,C5,0E,68,0F,66,DA,0C,A1,4A,7C,76,EB,EE,E3,65,E0,80,E9,A8,B9,CD,73,28,DE,05,C7,4E,BA,CA,3A,6B,C4,EE,F3,75,65,23,CE,12,2B,72,C0,8B,BF,D6,4E,6F,78,EA,8F,39,08,CF,C7,78,2C,D9,B7,49,C2,44,32,7A,32,F5,64,69,61,74,5F,59,DB,3B,78,1C,D8,FD,2A,07,22,DB,0B,D5,02,EA,8A,A6,7E,B9,5B,C6,0C,2D,A9,7B,F5,CE,EA,41,E0,4B,0D,21,29,A2,65,AA,12,DB,5E,33,91,A1,04,34,E5,C3,B5,3F,95,B8,09,7E,4A,94,C3,FE,F6,2A,77,81,10,DE,FD,1B,DF,97,CB,92,56,38,18,EA,C6,DD,9B,F7,9A,2A,A8,99,07,12,CF,D6,F2,9E,68,CD,9B,DA,77,67,6A,23,F0,A5,3E,4E,2E,30,CC,2A,9B,57,B8,89,FD,DA,97,B5,BB,AF,FF,E2,05,91,DF,A5,34,33,AE,3E,E8,5F,70,45,92,82,18,53,B1,CB,63,2A,DC,BC,5E,58,0F,40,B4,42,FC,0F,4F,55,3C,B6,89,3F,0F,74,64,0B,37,42,B2,53,69,78,D1,E8,B8,71,35,1E,DF,4C,6F,29,9F,E1,F9,61,2F,EE,4F,59,2D,97,4C,EF,D8,CC,76,45,D5,E1,D2,D9,09,B3,20,28,62,8E,BA,4E,C7,BC,9A,79,EC,EC,DB,02,09,5A,CA,3B,42,65,3B,F6,A2,D6,C2,B0,DA,52,C5,D0,E3,69,C0,20,13,14,51,EE,5A,1D,2E,23,D2,96,F6,27,66,C3,29,8A,90,78,DD,29,12,3E,8C,80,CA,62,8F,7E,B9,87,37,6C,4A,68,B1,CE,E3,5D,40,31,E9,3B,94,20,37,83,61,C4,F5,56,64,CE,43,74,2C,A9,31,D1,4A,79,01,E9,8D,57,25,D6,AF,49,6E,10,7D,03,46,21,AE,6B,57,B0,8C,5F,13,A2,4C,BD,F6,AE,C8,87,96,77,E2,4E,7A,92,25,99,7A,A5,55,7D,7C,07,BA,88,B4,51,D4,ED,13,9D,D0,C8,61,39,17,3A,03,41,7D,B7,52,EF,9F,65,19,DE,38,02,BA,2A,D6,00,87,72,F0,4F,F9,AB,E7,68,FF,87,C1,4D,40,0F,7C,9A,FE,6A,A8,62,37,6A,50,C4,27,BC,77,9F,08,92,81,47,A2,B7,DA,2B,BF,03,D4,3E,DE,C0,FD,39,4C,3A,F7,F5,C2,7F,EB,CC,C0,0F,F7,E3,F9,36,77,4A,68,E6,F3,B2,81,20,14,1E,76,7D,26,84,5F,1D,43,E2,E1,8D,DB,45,3B,64,CE,D8,13,C7,41,D0,AA,AC,34,15,00,A7,B9,6B,A4,EC,C5,72,2F,45,89,57,BE,38,74,D3,A0,7F,88,9A,92,B3,0B,90,56,62,42,57,16,4D,B0,29,93,94,15,1A,5E,6D,D7,6A,C6,95,B0,75,BE,54,51,1B,7B,2B,07,7C,AB,38,22,6B,38,A4,0F,14,76,12,20,D5,1D,D0,6E,26,FD,B1,B7,F5,8C,BB,ED,7F,5A,44,32,38,6A,E1,E7,CE,07,51,B8,D2,B3,A0,95,40,83,FA,1F,41,29,0C,6E,6F,9A,75,B5,FE,A8,00,4C,10,A5,8A,5A,2B,D2,55,EC,A1,ED,05,8D,55,CB,43,28,A5,16,AF,3A,9B,38,20,8E,35,59,52,2F,98,58,66,1E,00,37,EF,DD,FC,FC,C5,7E,4F,64,5A,0A,C2,A5,9F,E0,7B,7D,94,92,A8,AF,37,C8,1A,36,66,F0,D4,64,E1,79,0D,DA,6C,1C,79,B1,87,4E,30,C6,A2,1D,D4,DB,A5,FA,4A,68,54,30,47,54,B2,60,12,E6,5D,82,0D,0A,7E,89,58,99,15,85,E5,8E,57,6A,E2,D6,DE,B6,4E,35,71,92,3D,18,F2,61,A0,59,3D,4A,B1,79,92,B6,79,57,96,95,5C,6A,3F,2B,C2,B3,56,EE,52,FC,14,04,23,E0,98,4C,F1,32,4B,BB,CF,22,B3,BC,02,33,66,CA,12,C9,BC,0C,CD,D3,40,70,2B,11,6D,84,67,71,AB,71,2B,62,84,2F,70,08,E6,35,63,AF,5F,11,E3,5D,74,39,70,72,D0,A0,29,C2,36,38,6B,82,66,D4,E4,DA,49,EF,92,6D,A3,71,F6,59,D1,D9,EA,C6,6A,14,31,6A,6C,A4,46,86,4E,B9,5F,80,D4,FC,41,4C,A0,05,1F,70,B2,39,76,B4,56,3D,4D,20,05,F9,50,90,34,14,EC,29,9F,CA,B7,18,F3,0D,58,82,ED,83,AB,09,72,5E,29,D2,F5,B5,31,50,FA,E8,84,5E,C5,77,3E,60,D3,D4,51,AB,71,13,80,D8,F0,0B,7C,DA,F2,49,CC,46,59,63,9E,B4,07,F0,DF,45,B7,BE,52,5E,7C,DF,69,8B,CB,46,0F,1D,10,FB,2C,6A,80,F2,C6,84,60,61,ED,09,1E,5E,A3,D3,E8,A2,28,ED,B7,71,BE,B7,43,93,2F,CE,1E,9C,98,63,38,3C,4B,E7,B2,F7,55,35,12,E7,ED,0D,B8,42,D8,44,FF,9B,7A,E2,50,D9,44,00,5E,28,61,2A,80,F8,41,8B,16,56,07,25,C5,B0,4A,8F,27,FB,8E,D2,08,CD,77,8F,09,83,67,76,0A,61,D9,BE,4F,1C,C5,BB,15,1E,32,D3,5A,C2,00,0D,1F,93,F8,B2,63,8F,C7,67,DC,76,25,B9,30,65,30,E7,8A,43,3C,3F,78,67,BF,29,61,16,68,54,30,B1,19,2E,EC,A8,07,13,58,5F,4F,8F,C9,66,2B,A5,C6,2A,3F,6C,8E,4D,0C,43,CC,4B,5D,40,B5,73,A4,0B,A9,83,69,75,83,DF,C0,26,BB,12,97,B9,DC,63,E5,57,AF,31,F4,C9,EB,36,CD,C4,0B,21,33,04,AD,C9,D2,0F,AD,91,B5,5F,2E,2C,71,2A,66,7C,BD,DA,7C,EE,EF,C7,83,AA,D0,FC,22,C9,B0,C9,E4,FE,4D,5E,69,68,97,D0,12,AB,07,A0,DD,C0,AF,51,99,EC,7B,44,94,2C,60,BC,CE,68,E9,B9,57,95,50,09,83,7F,5F,2F,CB,CC,72,25,54,8B,C0,D4,39,33,A3,E1,25,E4,A6,73,F0,5B,BA,AD,DE,0B,0F,11,ED,D3,49,8A,43,09,61,87,B1,A9,29,F8,83,E0,38,98,C8,45,4D,CF,94,0F,33,D4,E6,EA,A5,C4,94,E0,A7,0B,64,B1,AD,27,9F,0C,90,52,0E,2F,33,B6,B0,E5,97,A8,A3,E5,8D,8D,E7,80,D2,52,F1,F1,7A,B5,75,83,23,8D,F7,6B,2A,F3,10,44,06,DF,CC,7C,66,E9,C7,37,EC,00,A7,E5,16,42,29,09,C5,BC,FE,50,46,FF,38,48,F6,DF,35,D0,45,43,82,32,92,19,2F,8D,8E,33,FE,06,77,36,9A,6F,F1,BF,F9,2E,D6,A2,4F,BB,FB,E0,57,3B,27,07,DB,18,B7,E2,91,DB,1D,A9,9D,50,D7,55,9B,66,18,94,66,9C,4F,55,A1,EB,7B,3C,28,84,AA,69,2E,D5,28,0E,A3,4B,15,53,6B,F0,0C,45,94,79,27,16,1E,84,88,8F,0F,52,48,FD,AA,A3,AD,F4,6C,89,0E,DF,BD,C4,20,F7,81,E0,31,76,7B,C4,10,2A,AA,DC,46,C5,A5,2D,70,AA,AC,E0,A5,C5,22,EE,55,CE,1A,1C,0D,6D,53,F8,75,BF,02,77,52,16,73,32,88,8A,22,3F,EE,16,A4,BF,F2,84,CA,58,00,F7,F0,56,7E,B8,AD,52,E1,61,C6,78,9E,0D,9F,70,5C,4D,2D,A5,CB,A4,A9,A9,1F,E7,F2,99,9D,16,CE,29,F1,D4,9E,4C,59,F8,11,B0,3A,F7,7D,7E,84,4E,0A,E6,36,F2,2A,46,B1,5B,5F,25,33,EA,D6,88,1E,4B,81,EF,55,B8,50,B7,AD,4E,C4,68,CB,39,87,D4,C7,0E,36,E1,4C,42,41,99,8A,BF,A2,1F,9F,33,16,EC,38,13,7A,67,10,21,68,85,E2,38,74,B8,3D,0B,EF,B6,03,D4,C1,12,47,25,E9,D8,99,FF,A5,6B,6A,85,2E,0E,32,4E,2E,27,5C,2A,33,9F,01,6E,DB,FE,45,32,72,ED,DD,06,10,5A,F5,2C,B6,60,C2,04,56,64,EA,CA,BA,EB,C6,34,7E,DE,1C,93,77,F9,EA,4C,E2,38,2E,5B,53,BA,F9,F2,03,9A,FB,3A,AD,22,04,C1,59,57,5A,75,56,72,92,0C,75,44,68,71,56,C0,3C,4D,0E,CA,D0,29,70,9A,DA,B8,EF,BD,88,B8,AA,69,B8,A0,F0,D8,34,ED,C3,B8,95,38,21,E9,3C,05,A0,2B,44,FA,BC,C5,F4,1C,DE,B5,FC,CF,EC,62,C9,AE,4B,A0,C3,05,78,29,CC,7A,83,C5,7B,BB,E5,41,86,FC,F0,8A,D8,44,D4,C6,97,A8,5E,8F,DE,6C,65,CD,0C,90,AF,61,A4,EC,4E,97,85,4F,C7,56,2B,1F,4B,8F,BC,13,D7,4A,57,3C,06,C1,9B,81,30,7F,72,20,95,9A,97,96,6D,87,93,7A,2E,52,27,07,8B,CD,CE,AB,1D,29,11,61,CF,1C,37,8F,D7,3D,F0,38,5D,D6,57,7E,E5,54,42,31,B1,FA,F9,64,24,E5,C2,A8,C1,BE,C6,DA,18,3C,8F,5E,6A,E3,4C,8F,AD,D7,F2,92,1F,19,81,7B,BE,9A,9E,35,E1,8B,C6,78,1F,8B,2F,8E,BB,9C,9F,6F,2E,90,B0,E8,C0,BF,5E,AD,AD,00,A0,9C,B6,B9,4B,36,F6,75,03,FA,8A,2F,27,BB,78,68,71,57,42,97,D2,93,66,31,58,4F,0A,DD,D4,9F,0B,F8,2C,CD,BF,07,07,CD,7C,8B,DE,7E,3D,A7,29,2C,28,B3,9E,26,82,56,E5,2A,65,00,3C,8B,28,11,4F,5B,90,A8,99,27,87,E3,FA,45,75,E0,30,59,6E,35,73,7F,AA,27,B3,83,31,AB,39,AC,8A,03,94,85,8B,98,53,DC,C4,11,22,8D,D3,B0,C7,B8,5F,AB,82,D8,46,C6,BA,76,A2,B1,9F,F5,D9,33,6C,01,86,C4,80,A9,95,2C,36,50,36,58,1C,5B,DD,7D,B6,9B,E2,71,64,BC,50,DA,75,17,35,95,21,AD,6A,D8,31,96,60,AD,E4,DF,6F,1C,16,BC,17,A1,D6,FE,E9,8E,BE,B7,8E,A5,AD,1C,FB,A2,5B,1A,6B,6D,34,F8,A1,ED,C3,6A,89,47,15,9C,80,36,5F,B1,DD,E3,92,4C,57,39,6E,AB,6A,DD,D1,1C,33,02,82,AA,FB,09,34,C6,26,EC,8A,3B,5D,F0,4A,42,DE,1E,9B,EC,8F,E5,F8,50,21,D4,2A,9C,BD,36,41,DC,B9,45,7C,7D,3B,87,75,6B,3B,37,81,B2,18,59,B5,CF,96,12,15,C4,A2,BC,E3,5E,DA,81,F9,06,FF,BA,0C,25,FF,CE,0F,F4,71,31,C3,4C,DD,A9,49,F4,53,E5,9C,34,08,97,24,14,05,68,24,5E,B7,66,22,7B,9C,7F,CF,FE,9A,5D,E4,85,51,25,0E,CC,68,28,13,55,4B,22,EB,FD,C3,3F,21,9E,1F,3E,64,68,13,85,A1,60,C6,66,60,9D,52,B0,8B,15,D4,9A,72,5C,C0,C9,DD,0E,B8,7F,FD,38,C8,51,0D,E0,D9,95,10,DC,74,80,2C,AD,22,14,B0,91,50,7E,9E,65,7A,1D,AE,69,D2,2E,64,8D,25,3D,67,C8,51,80,3A,F4,EC,F8,AB,FB,07,1C,8F,59,A4,0C,6A,30,A5,B7,C4,54,F0,E0,E2,44,26,95,F5,00,38,4F,FA,47,95,3C,F2,78,97,D6,BA,36,23,5D,F1,D5,FC,4D,8B,61,33,FF,02,4C,10,BC,5C,0A,0B,F5,9B,12,AC,BD,01,20,8C,B0,AC,EC,6F,42,8D,89,97,D3,AF,4D,19,0D,B3,45,5C,46,D8,0A,E9,2D,0D,0F,D4,07,58,54,AC,62,6D,EA,8D,14,22,3B,16,B5,5F,64,7F,CE,2D,9B,EE,C4,65,C3,16,05,4A,7F,F4,9A,2D,22,34,DB,7D,05,8D,65,68,A2,AD,86,AD,97,78,A6,1C,6E,F7,EB,4F,03,0F,96,14,D7,1A,62,FB,B0,24,EB,CF,46,92,FE,89,84,6A,00,8D,5B,EA,AB,AC,B3,F0,4D,53,C0,59,9E,F0,41,40,D5,E6,64,0D,5F,64,1C,A1,78,98,05,90,4C,1F,5D,DE,39,EB,65,D4,10,47,04,52,83,0A,3C,67,48,4E,6E,ED,B0,8E,D0,1B,D0,F2,58,FF,0A,7C,38,C4,78,C8,E8,02,1B,36,3D,D4,64,65,B6,CD,31,FB,CD,F1,7E,EA,AD,F0,92,30,C7,C0,A7,56,85,C7,2F,90,CF,0E,A0,F1,26,A1,2C,72,31,88,93,4F,AC,9C,5F,25,30,3B,6E,C0,92,C9,E4,61,D4,4F,15,BE,68,F1,E1,69,3E,85,0A,AD,DB,B7,91,22,B4,5A,6E,D4,0E,76,78,B5,D1,4C,7C,D4,4F,F8,E4,45,88,70,A5,3E,16,A0,37,F6,74,58,2A,E9,E5,33,F3,84,C1,F2,C6,40,D4,AA,99,27,1E,5F,71,D5,85,C1,52,76,55,69,76,DD,61,EC,13,63,2E,26,98,59,CE,85,A3,7C,48,E7,EA,74,C0,21,CD,89,61,13,9E,05,A1,9D,C9,43,12,54,86,9C,A2,B8,78,4E,CB,0B,23,D4,31,04,F6,79,81,AF,95,42,75,19,73,76,1D,24,F7,63,6F,1D,4A,A9,05,F2,BE,06,9F,BA,DA,68,92,9C,BE,1E,83,E1,33,4A,6A,AB,36,3A,0D,B7,39,CE,CC,39,53,B1,18,1E,86,08,F0,B6,86,7B,94,6F,5B,0A,58,AA,E2,D6,ED,89,1A,7F,19,9C,0F,8B,23,01,41,CB,96,B1,4D,FE,8B,6C,5F,2A,1F,4E,90,4F,43,C6,26,9B,A4,57,BA,21,C9,E9,69,33,9E,65,1F,09,B0,19,C5,19,43,7F,B8,31,68,85,AE,49,FF,6F,B5,E3,D0,33,0E,16,C5,F2,E4,F4,FA,B1,B2,B9,B7,83,92,89,CC,07,58,5D,AC,C8,1B,29,6D,B0,4D,D7,E5,49,4C,F6,04,4F,C3,C2,8D,6D,93,65,5B,A7,0A,CB,5E,14,EF,0C,89,4C,95,98,F0,93,8A,6C,A8,43,9E,BC,BC,B9,A8,73,A2,69,D3,EC,8D,46,1C,C8,CF,64,4C,24,98,80,67,88,FD,3E,D8,60,DE,5F,32,3D,2B,43,41,AC,89,64,63,3F,61,C8,97,8C,40,FB,97,77,04,86,3C,56,1A,8A,66,3D,03,03,E0,83,C5,1C,9F,FE,9E,F2,07,08,24,6D,3B,1C,75,4D,1A,53,5E,BB,22,42,5D,E4,87,D2,B7,EA,1F,5B,B8,3E,82,87,17,8C,6C,4B,EB,99,0D,4E,DA,AD,86,49,B4,35,84,40,F2,07,12,82,97,B8,E4,B5,67,EB,2C,FB,9C,62,79,6D,DD,D6,22,C2,E3,AC,85,FD,73,57,3B,F1,58,D1,C4,E6,64,C3,42,22,8B,71,2B,6D,1B,F8,20,67,E2,44,8C,A0,33,F8,90,AC,CF,E3,EA,F1,1E,30,3A,85,03,FB,EB,DD,BD,A4,A6,96,2C,86,27,A6,16,7C,FE,12,01,FE,A4,5E,7A,C6,4D,0B,D6,FC,C1,25,D8,FE,94,3E,3B,23,7B,5E,47,E8,44,23,A9,9B,10,56,7F,0F,E9,5E,15,F8,C1,60,4F,CF,DB,33,B6,34,85,80,7C,2E,FA,88,BA,82,6E,64,F3,E4,2D,B4,40,AF,91,85,6C,DB,73,B6,EC,5B,48,E9,B2,B1,66,A0,26,0F,F8,2B,B7,1D,7D,32,49,43,13,BE,69,01,65,DE,82,28,F0,FF,15,44,31,7B,5B,9E,C7,BD,F4,50,9E,69,35,D1,43,07,12,1E,9A,FA,38,A6,C5,3D,7D,08,50,A3,56,2B,48,39,07,72,15,18,C4,F0,BD,A9,7D,43,CF,FE,CA,E1,0D,CC,BA,D3,6E,51,19,96,6C,B6,BB,23,50,ED,DD,85,9A,0E,DC,82,C9,D6,AB,C9,01,FF,62,5E,5B,38,5E,A9,EC,69,E7,19,AD,BF,05,2A,7C,EE,70,81,6D,0E,41,DD,39,F0,CD,DF,C4,3D,C0,4F,5A,50,00,68,E7,AD,19,E3,25,5A,53,8C,C1,E0,D6,C7,78,31,26,09,93,61,7A,B7,72,F3,28,96,79,E8,1B,11,EC,68,85,CE,41,EE,71,00,48,6A,6C,14,FB,6E,EA,07,00,68,43,4D,A4,6D,E3,A3,A9,03,5E,38,6F,8A,BF,4A,DC,5E,CB,B4,8A,CE,88,00,8A,6C,49,D3,9B,0B,D4,07,9C,83,2B,EA,DB,C6,61,8C,93,EB,E8,6E,2A,CD,56,EF,F7,51,81,9A,D2,B2,40,F9,48,70,21,CE,60,79,9D,38,AB,4E,53,E3,27,12,78,89,7A,04,6D,B7,D4,CF,F3,E7,13,78,12,9D,B8,08,81,3B,0F,F7,79,A3,D3,7A,67,C2,3A,DA,47,C8,D3,CA,5F,EC,FB,6E,E6,5D,AE,85,DE,40,4A,F9,6A,C6,96,ED,7B,A9,EB,09,CC,09,F9,D0,9F,BD,BB,C8,F5,A7,8E,8D,12,60,85,75,55,1C,EA,02,29,98,01,8E,11,A4,1D,A9,8E,37,40,3D,9F,9B,68,E7,EE,7F,5D,F6,A1,C7,C7,02,53,5A,51,52,99,37,32,14,A9,75,7B,08,8B,BB,6D,C8,1A,9E,E5,1D,BA,68,79,5A,BA,C0,2A,16,95,BB,8F,AA,3D,C3,7A,96,F4,69,85,1C,7C,FB,A2,71,E6,26,EE,92,D4,4B,EC,0E,06,1F,5D,CD,5B,57,49,5E,E4,4C,38,76,F4,7F,F5,D6,B7,66,A5,F4,48,14,BD,B8,AE,9B,BF,0D,73,AD,43,DA,4A,6E,87,F8,DA,A7,41,F8,BE,C5,8B,AB,D9,91,4A,3E,1C,0A,5D,16,EA,8B,A1,00,34,73,8F,5A,0A,53,6F,B1,FF,3D,1D,B2,2C,72,1A,DE,42,C3,A0,F3,08,39,A1,7B,52,AA,AC,F5,94,9E,B7,BE,85,A6,D3,CB,12,B3,35,81,20,9D,B8,FF,91,99,E7,77,4B,E2,90,BA,9D,F8,F6,38,06,B5,FF,46,A7,B7,49,71,06,62,14,35,0D,FF,1F,33,F0,B9,05,9D,E0,FB,38,49,49,36,94,CC,67,8B,06,BD,0D,29,43,DB,77,9A,1E,AD,68,92,1C,A5,61,63,C7,86,C2,F5,3A,20,D5,BF,7E,6E,D1,F0,5A,CC,7C,8D,D1,ED,5D,56,68,B1,6A,33,D0,E5,86,52,45,00,11,68,68,CB,04,42,0B,AC,E1,FB,27,36,5F,2E,BE,EE,41,CF,1F,6F,EF,BF,8C,B8,36,44,F6,7D,C0,FF,AD,F4,E0,82,74,A7,77,12,07,FA,93,DE,84,0C,C3,BA,72,5B,01,86,5F,4F,F1,47,EA,5F,CC,17,EE,7E,2D,8E,0C,07,09,99,80,F5,E1,98,94,72,48,79,4C,2A,19,B6,21,DD,D6,1D,FA,91,2C,E9,96,05,17,D3,DA,81,6E,FD,BB,92,83,A5,E7,C9,84,8E,A3,AA,51,71,1A,6D,86,B7,02,EA,87,58,AB,D6,CF,E1,2C,E7,9B,31,2C,33,F1,89,F6,35,41,17,BF,4E,0A,D7,F3,C1,3C,D2,A6,34,7C,D8,DC,0D,BD,50,E2,BF,22,E8,43,3E,80,EF,13,61,4B,6A,F1,8F,48,29,D1,5E,1F,EF,E1,D5,2A,DC,FC,76,4B,CB,00,10,08,06,2C,D3,52,CB,2F,CA,73,85,32,06,79,8B,32,A0,4D,C9,11,86,B8,9A,29,A2,38,F9,E9,0A,AC,0A,7D,CC,2B,35,26,E3,9B,15,0E,B4,B5,68,FA,B7,2A,B0,30,D4,5C,0F,4B,3D,EA,EC,97,70,D9,1E,1E,21,A1,79,90,EC,52,F9,44,02,EA,BC,82,73,41,1B,10,00,8F,20,79,4F,8A,C4,55,79,C9,FE,B0,80,F5,6E,86,5E,90,25,9B,33,DE,64,CE,1D,74,80,6E,71,4D,8E,65,7A,D9,B2,84,67,F6,A6,5B,09,EC,6C,73,79,40,11,9D,F5,78,A4,6C,E1,7C,A9,B5,D5,ED,E4,90,6C,01,53,1C,CD,81,46,D0,52,BB,21,8D,14,81,52,F1,2F,53,5A,79,8D,59,73,4E,E2,CC,3A,CE,16,80,64,22,83,A6,54,D8,B2,E8,71,47,75,83,D4,68,11,EB,82,ED,76,07,FA,4E,2F,B1,F9,1F,A4,96,ED,0A,D0,DA,32,5B,B0,27,5E,00,AD,43,EF,ED,11,AC,E1,35,2E,A7,09,6E,8D,4B,2E,C1,D8,BD,36,B9,C6,13,26,2F,3B,F1,DF,C2,78,9A,A0,72,CC,D8,4B,E2,65,4D,94,C6,E3,59,B4,E2,26,F8,99,C5,48,D0,8F,BF,82,02,B6,00,37,5B,E4,A5,46,13,B2,F0,C9,9E,2B,E0,BF,DB,05,87,AB,8C,97,DC,4A,FB,9A,51,6C,D9,D0,F5,CF,B3,9A,A4,A7,E7,9C,5C,99,5F,B8,FB,9E,EF,BB,10,36,11,41,B0,F0,67,1B,B8,C6,A9,77,ED,20,33,40,B8,A9,46,35,0F,01,82,B9,E9,EF,46,2E,52,32,18,AF,71,2A,26,FD,31,91,54,3E,14,9D,AB,04,F0,7F,92,B2,B0,1D,1B,6A,A5,29,81,61,63,43,B2,5F,84,F9,EF,31,C5,82,1F,5A,A3,31,9B,A7,13,50,02,85,A4,A4,4C,14,23,41,68,C5,E2,B2,16,B7,80,88,94,E7,D1,99,A3,65,7E,CE,9D,FB,51,37,2F,D0,0B,40,3F,E6,AD,EE,28,10,F9,8F,16,60,4F,4B,EE,1F,10,EA,6B,86,22,1B,17,EF,6B,83,B9,3F,83,00,68,96,B6,C5,56,E7,D1,AC,F7,C6,C6,85,C8,6F,74,AB,3A,BE,5F,1C,03,CD,01,59,E9,CF,18,2F,BE,BD,23,DF,10,17,C4,43,62,40,77,70,02,9C,9D,9A,8A,AC,D9,F5,17,90,D5,3E,2D,63,87,00,23,1C,AB,FF,D5,F2,CF,42,52,81,E6,B2,DD,7C,FF,78,F0,57,E3,19,28,C9,F7,27,DC,A5,72,EC,85,7B,79,55,22,00,40,8C,1B,58,BC,FB,38,07,0E,56,B3,C1,2E,2E,E2,AE,61,F7,55,AF,86,8B,63,C4,EB,A7,BC,EA,CE,94,FA,15,96,7F,55,3A,5E,63,2E,89,43,45,0B,A1,56,8D,8D,6E,A1,92,9E,64,9E,A5,7D,88,BF,64,FA,EE,05,10,30,E6,9E,14,B3,2D,5E,03,70,C2,CB,32,C0,9D,8E,C5,65,FC,43,A7,39,5D,02,7A,D8,B9,84,09,4C,A3,D8,A0,3F,04,D2,96,FD,6C,5D,CA,60,ED,A0,69,FD,C8,69,72,CB,C1,7D,98,55,55,C0,64,68,75,03,D2,55,5E,FA,33,3C,D7,9A,52,E4,7E,49,75,75,BF,23,62,D7,3E,16,25,2F,41,21,93,E5,19,2D,CF,2E,82,47,DE,71,77,2A,99,16,45,7D,3E,DA,10,48,EE,D9,AF,25,C5,A3,67,7E,A9,E8,11,A4,A8,4D,21,31,3C,1B,B6,C1,6B,AF,99,4D,93,46,9C,CA,AA,19,7E,E3,75,3A,24,01,BD,FD,28,FC,02,0D,F5,C3,D5,DE,7B,9C,21,3D,1B,0E,52,23,6D,D1,49,D6,DF,61,8E,28,FC,58,32,2E,B4,CC,EA,D3,99,99,B9,27,90,85,BC,AE,61,0B,B6,6A,2E,B1,80,CB,40,64,F5,03,AB,42,90,10,52,52,5B,D4,69,82,BD,59,DD,CF,92,3E,53,FB,6F,13,D5,BA,6F,DC,EB,C8,78,31,E5,86,2E,E6,36,07,88,25,E8,A0,35,81,A5,BB,27,05,C9,E4,F2,84,1D,EB,61,51,1B,4A,D1,B1,00,BF,D6,1F,A7,37,C5,5C,F2,56,C4,5A,0A,A4,8B,9D,2D,E7,23,B8,35,3B,AA,31,63,91,B7,A5,15,F2,1D,D4,D0,8F,AB,AD,97,08,69,90,A4,B9,98,D0,48,98,D3,23,B2,18,D4,EA,EB,F0,87,C9,81,4A,2A,7C,42,22,86,DE,7B,4A,74,41,22,9D,EE,1C,1B,02,2A,22,5F,A2,89,43,75,60,3F,2A,A7,FA,14,D9,E2,0A,0A,AB,6E,36,6F,2E,5A,97,94,DA,75,40,22,03,77,43,22,7F,95,F8,B6,90,28,AF,B1,EC,06,7E,14,99,A2,B0,1A,56,00,45,23,C9,F4,E6,49,D5,69,22,63,00,46,CA,AC,7F,DD,18,16,2A,CE,2F,C7,30,CE,4A,F0,E1,A2,A0,3F,7F,28,2F,1E,71,46,83,30,79,98,52,81,D5,00,24,C8,05,8E,1B,58,02,B7,F2,E4,7E,F9,C2,B4,11,31,2B,5D,CC,9B,3B,49,32,FB,6D,F2,88,54,DF,19,EB,D5,23,CB,92,9F,60,AD,EF,F7,04,27,7D,76,17,53,11,59,08,EE,C7,85,89,2D,04,64,68,C6,0F,8D,A7,FE,36,FF,77,56,88,4C,5F,77,3D,C7,F3,55,21,44,83,C9,91,BB,D0,7E,B6,AF,A1,B0,98,35,7F,95,51,03,DC,09,E4,55,DB,AB,14,1F,42,72,04,0C,D5,2E,9A,EB,67,80,E9,8F,E7,F7,A5,5A,6D,99,28,69,97,21,D6,37,ED,06,00,5E,D8,A7,71,8F,97,DC,AB,45,DD,7B,E0,95,EB,8F,29,29,1B,18,2D,47,CE,19,A1,9D,88,1B,E8,2C,05,F7,49,07,F8,F9,D0,CB,77,7C,B7,BB,0C,16,46,4E,FD,0E,F1,48,20,E3,FB,46,E1,28,78,35,30,54,BE,2B,72,1B,E9,2D,F6,FE,2F,B5,02,A3,48,C7,CA,FD,5F,D4,A0,B0,5A,52,B9,9C,7F,52,09,DA,0D,BF,C0,B8,60,84,05,E8,8C,99,09,71,EE,94,B2,87,20,15,B1,D9,56,8A,C4,1C,B8,1E,CB,F9,62,CB,D8,99,E6,C5,45,19,C7,2A,85,24,E7,2A,72,68,5A,35,45,6D,87,53,86,FC,B0,C5,86,4D,D9,7E,B0,2A,97,80,48,8E,48,51,01,A3,E2,93,C3,70,49,D0,DE,25,59,D4,A6,B3,AC,DF,B3,1D,E4,52,06,85,11,96,D1,51,42,AF,B7,18,02,69,AD,59,FE,D7,BE,9A,AD,53,4B,8D,38,8E,3D,AB,C5,35,20,F4,65,11,AB,75,A1,3F,67,82,BE,47,89,86,D4,47,B6,5D,3E,67,81,56,E8,F4,BB,55,A6,AF,17,3F,B0,E6,52,96,DB,D9,22,34,2A,6A,6E,93,32,6A,53,CA,EA,E9,5E,97,58,5A,2A,AD,7C,8D,24,3B,32,DB,84,AE,15,A9,A4,83,EF,39,A8,B1,A5,5B,CE,21,84,EC,80,B2,0E,37,B8,13,7B,B7,B7,C2,B0,44,8C,97,C1,1B,2D,EE,3A,22,5B,C9,D3,C7,5A,99,1A,2E,19,50,AA,2C,C5,C1,93,C2,D6,B9,66,57,F6,D4,1F,00,C4,40,7D,18,50,F7,15,3D,4F,B9,81,44,F9,D5,83,26,E9,D3,D0,27,30,D3,79,29,21,30,20,6F,6C,0C,19,BA,E1,CA,1D,9B,E5,69,92,F6,9D,C5,72,4F,4B,E2,81,21,CE,2C,E6,50,B1,FD,FB,1A,DA,53,EA,13,D5,14,F4,21,3C,5E,26,24,D2,0A,10,E1,AF,C1,1B,1C,4C,8B,C7,FE,55,C2,E2,96,67,91,8D,42,22,9F,94,E6,30,56,52,46,78,84,E5,7A,C0,EB,53,89,28,74,2A,86,62,6E,7B,BF,8B,09,63,D1,3F,E3,36,BF,0D,F4,0A,74,5B,8C,4D,8B,6A,1B,E4,A1,E6,D9,1E,02,68,2C,AB,35,D0,46,52,09,EE,11,5C,A0,A7,DB,88,D4,D2,0D,EB,0A,05,1A,39,C8,2A,69,56,6F,E7,65,B8,CD,CD,2A,7F,29,D8,AF,3E,10,A7,58,20,5B,E0,7D,DA,20,EF,30,F6,2A,51,CD,46,49,FE,B9,F5,D4,49,EE,04,41,B1,FA,BA,C1,F1,7D,AD,67,80,6E,39,85,B1,8E,64,18,07,2B,CB,E8,18,41,79,86,97,E0,16,FC,32,E2,14,E1,AA,FF,23,EF,3A,80,FB,A4,29,B3,81,54,66,14,81,08,D7,71,93,50,21,B6,28,2D,51,D0,58,D3,0B,12,C8,84,1C,EA,76,2D,4B,7D,9C,CB,14,7A,2E,AC,22,BF,42,0F,30,CC,F8,2A,A7,1F,37,E4,17,94,2A,FC,E2,5C,88,D0,E9,D4,25,E2,C6,1C,62,B8,72,82,30,C7,F1,AD,94,B1,79,D2,AD,42,07,0A,18,D4,DC,3F,02,13,B3,8D,96,AD,5E,86,45,7A,31,46,E7,3A,AB,68,47,70,B9,09,E5,B6,3C,7B,48,A4,02,C7,AA,38,48,B1,4F,D3,2C,99,8A,A2,E2,62,33,BC,F0,AA,EC,7E,D1,7F,7F,44,FD,43,AD,4B,71,B7,04,57,33,55,66,75,21,E3,4E,A8,42,C3,EC,78,85,5C,13,E0,83,A7,DD,D9,5C,DE,57,7E,07,3E,D0,00,2B,03,28,B9,B1,FB,14,F2,21,47,68,39,F1,5C,EF,FA,A1,79,EF,DE,05,DC,A0,87,62,2B,A3,09,96,EA,3F,EA,D1,D5,E1,69,C3,F9,11,B7,58,18,64,74,3F,6D,59,7B,27,26,69,C8,78,A8,CD,FA,B8,11,82,5F,8C,E2,EC,AB,56,43,FE,76,1C,C6,7D,6E,24,04,D5,B0,3A,15,CD,21,45,B5,68,2C,B1,B9,C3,81,11,D2,CA,65,45,60,E5,8E,9F,D7,35,A1,6D,B6,D6,89,A1,68,4E,F0,F8,C2,8C,5A,FA,DC,3A,0B,74,38,A6,CB,44,35,35,F6,3C,42,76,4F,B0,B7,63,18,12,B7,70,28,2C,00,74,E4,88,96,CD,1A,5B,4B,50,77,26,07,BA,98,77,AF,21,A0,DE,5E,60,2E,83,CC,EF,00,FD,95,E7,4F,7E,45,0F,17,7A,E2,A6,9A,F1,69,18,A8,01,27,79,27,8E,28,BC,EC,43,49,A1,C7,C8,AC,90,3F,05,D2,E3,B8,09,6C,A8,E7,44,5F,08,05,AB,4A,6D,9E,93,24,27,D3,43,2E,C2,D0,22,89,8E,77,39,58,35,A9,94,DE,A6,75,0E,D2,A0,1E,3B,C7,F3,E5,2C,65,CA,75,C4,28,AC,B0,F3,94,B1,1C,AB,2C,29,18,D9,E2,71,92,F8,C2,96,E0,8D,9D,4F,92,59,C7,74,E7,33,F7,E2,83,3C,E5,BF,C9,42,0C,C6,6D,5C,5F,8B,6C,66,61,C7,03,36,28,F9,92,B5,ED,FF,44,E9,A9,EB,81,55,80,62,61,77,EF,17,8D,D9,1C,4E,2E,29,67,78,F6,E4,67,BC,E2,41,86,F4,DD,2D,DA,DC,CB,E7,19,0E,5C,4B,C4,05,08,EB,DD,D4,7A,D2,CF,EF,BD,64,A1,71,FE,7D,A6,3B,59,E7,F2,84,3B,34,44,35,F4,0D,9C,F3,16,C0,3D,DC,C3,17,E9,14,FA,E6,E1,6B,01,F1,C6,4F,CF,C1,81,29,1B,18,23,5D,FA,9B,80,68,9C,24,7F,A3,84,C9,73,6E,8C,CE,E3,C2,99,B5,6A,30,A8,B2,20,23,30,45,C5,3A,D2,9B,1E,8E,6E,2E,D8,84,D6,1A,3E,E2,8B,C4,42,6E,B4,43,5B,97,3C,44,FE,E3,B5,E9,AB,10,75,3D,C4,53,67,63,57,74,55,AD,81,C5,BF,76,FF,29,96,15,53,BC,D8,47,29,7E,B6,A2,2A,9A,BC,E9,2E,10,94,93,1D,D0,37,72,4B,2C,39,87,13,40,8D,46,DA,09,0B,D0,CB,FC,96,47,F4,30,F3,D3,1F,28,D3,E1,F0,03,48,3F,95,56,42,73,FC,4B,6C,58,5F,56,D3,D6,92,11,D7,FA,7D,92,4D,F0,CC,E2,D8,A5,F5,2B,7D,4B,36,6D,04,E6,DB,2B,5C,8E,C6,AC,51,48,A6,A7,26,ED,ED,7C,A0,C3,3A,8B,2B,8A,CF,46,83,54,A3,18,F2,93,66,7B,35,47,6D,C7,A8,D6,E5,66,9C,34,D1,DA,56,38,E2,CA,22,4D,3D,52,67,E0,6A,FA,10,5F,21,43,D0,95,35,35,72,E6,FA,0A,5D,88,2E,B4,C8,48,8D,24,EF,D7,39,AB,7D,03,1C,39,46,DE,F3,93,19,1C,D3,7C,21,A9,5B,16,DC,44,20,0A,47,B7,45,53,79,69,62,2F,2C,A2,66,07,32,C5,3C,D8,59,EA,26,50,2D,6C,B9,4C,14,F1,A2,34,A9,12,AA,73,A0,E3,D1,9B,C3,13,AC,1A,2F,1A,93,E4,E9,F6,A5,1B,79,D2,91,EF,B5,72,99,7D,D2,CD,7F,1D,3E,C8,FD,38,C2,50,C4,5A,47,27,2F,1F,DD,B7,B8,1B,C0,C4,B1,90,6F,8B,BD,3C,08,3F,C0,6D,09,5E,B4,A9,E8,09,2A,DD,3A,FB,D5,1F,D5,EA,87,86,C0,6E,78,1B,D4,CE,63,BF,77,49,19,E8,55,4D,C9,74,AC,89,E6,28,28,74,8F,0F,3C,54,F4,B8,7F,8C,1C,EB,1C,B4,B5,B0,05,51,A3,1C,D7,23,66,07,DF,8B,C3,DF,6F,28,38,A5,18,7C,B5,0E,F9,03,76,0D,0D,8A,DC,2E,23,B8,28,8F,A2,82,37,10,0E,EE,CF,8A,61,FB,62,1D,BF,A7,13,23,F8,22,3D,7E,91,F1,20,51,75,CB,20,9A,61,32,57,AB,D3,F8,4B,96,E2,0A,D2,75,35,BC,AA,28,42,D7,DB,C3,59,60,C0,3D,84,FF,C0,52,86,F9,2F,66,6D,E9,2A,79,FD,93,D5,DC,E4,65,30,F4,6D,55,FA,4E,36,F6,61,BF,75,9C,3E,3C,43,FD,56,0D,3D,1F,83,EA,C8,3E,FA,81,B6,79,ED,E7,4D,7F,86,D0,18,9F,1E,C3,8F,06,18,6C,98,FF,AB,33,F6,69,D7,98,BC,AB,9D,F1,EF,65,C5,CF,BC,7C,B1,07,94,E6,8D,B9,DA,2B,DB,7A,18,7A,F3,6E,9D,0C,F6,6D,CF,8A,98,C1,7F,66,D2,9F,57,21,EE,22,6C,09,1A,65,9F,B0,90,6B,C1,53,5F,C6,9D,5D,57,FB,F8,F7,8D,8E,3C,67,D7,C1,F8,DF,31,9A,01,47,ED,F7,3D,99,B3,91,A3,6D,6B,E2,A1,33,63,37,15,EA,01,00,BE,39,5E,ED,E8,11,BE,37,B5,ED,CC,1A,49,72,C5,CF,29,CA,F3,78,E9,C1,20,FB,A0,2D,3F,A2,F6,B5,49,47,28,B0,AE,96,AD,55,93,12,C2,FF,59,85,6F,C0,29,E3,12,08,67,30,20,1E,BC,39,69,FC,A3,C3,81,97,5F,31,AB,BF,09,3B,5D,EE,68,25,4B,B6,24,11,C8,22,2E,09,8A,AF,9D,8D,27,D2,3E,BD,C8,E8,12,23,6F,41,03,AC,1B,02,ED,48,2E,40,7A,DE,F5,FA,F0,8C,73,85,DE,14,D5,C5,97,9F,38,28,6D,1F,C0,55,8C,7D,E1,CB,1E,64,C8,A3,D2,A4,02,C3,F0,0C,17,61,73,BC,5B,62,13,C9,5C,10,71,03,7C,5C,20,3F,07,17,71,70,4C,61,0C,CC,EA,2D,54,0F,A8,89,65,61,BE,4B,34,C7,02,5B,C1,23,90,DB,79,48,68,7A,19,DE,ED,5E,6E,FB,EA,17,0A,78,64,EF,BF,3C,B2,FC,85,BF,8A,79,63,F6,1D,07,35,8A,61,99,52,76,EA,0C,5E,BF,6E,D7,40,39,17,CA,4C,05,64,48,1F,B5,9B,7A,A5,33,E4,C9,4D,4E,F5,D2,E1,29,28,F0,B6,E7,10,15,75,D2,9D,80,EB,00,F7,AA,1F,75,AC,51,4B,13,25,DB,8E,EE,DF,1D,2F,28,6F,53,BE,DD,C2,25,90,80,D6,0F,51,5A,FE,8E,21,C3,78,EB,8D,68,84,4A,95,B4,3B,90,DE,29,F3,AF,9C,0C,4D,6A,74,0A,30,23,F6,07,CD,3B,C9,C7,57,1B,DB,2C,FB,F2,0F,8B,6C,ED,49,16,B3,02,D7,14,33,BA,7F,AB,DF,8A,4A,FD,35,75,4F,35,E4,4C,E9,8A,F8,FE,24,39,65,0A,B5,4C,AF,D3,0F,F7,09,B8,9E,5B,46,73,95,86,9C,D4,21,3A,F7,4F,E4,4B,90,FE,D6,2C,F4,3C,52,3B,7F,1A,ED,D7,69,BA,C7,05,84,E8,6F,F4,A4,B9,4F,3D,DE,A4,54,4B,15,1A,B2,F1,3B,B4,61,22,37,14,E4,2C,C4,CB,E2,ED,DE,51,1D,91,7A,45,81,40,09,11,EC,B8,6F,44,6C,28,FD,0C,D2,92,D3,76,A0,C9,53,1C,CF,76,F3,9B,51,29,2E,83,75,AF,C0,17,CA,5A,25,B8,7E,F6,7D,6F,3C,FF,F9,E6,5C,14,D4,85,8F,EB,AC,C9,62,FD,52,80,9C,84,AE,69,14,24,5E,A7,8D,9C,9C,54,82,AE,E9,C1,30,BB,FA,83,01,B4,B8,3C,57,A9,D8,DC,56,FA,ED,BE,CE,88,17,18,9A,66,85,E0,33,65,88,21,47,74,43,32,D8,3B,01,72,00,A8,9E,74,F2,20,17,F5,F3,80,EE,DE,9B,22,92,5E,93,0E,6F,78,19,C6,21,EE,B6,E5,A8,11,2D,06,D2,09,07,D7,53,ED,AA,7B,07,38,C3,CA,92,68,E9,C1,36,03,CA,C6,52,A2,28,C8,CD,CC,73,5D,D0,FC,D3,1E,8B,29,58,4E,A8,1B,86,AB,57,F7,B4,A8,D1,08,A9,AC,56,84,4D,7A,0E,33,60,B4,78,F5,A9,4E,C4,9D,40,A0,8E,61,FA,CF,12,58,84,3D,A1,D4,AA,78,E4,81,8E,DC,42,E2,62,4B,BB,20,A7,86,15,17,52,DD,1E,27,43,D8,E6,30,33,B9,D0,B5,72,3E,3D,2D,9A,FD,4C,C3,37,FB,35,64,02,E6,A1,78,56,4E,56,38,FA,53,83,39,D7,97,47,09,41,F0,CE,E4,75,0B,94,B0,69,64,E4,D9,2A,6B,CB,7F,CF,C1,FC,60,7B,05,1F,0A,B9,4B,B0,32,5A,0C,30,82,5D,10,AB,8D,D9,3B,E2,B9,ED,F2,F4,50,EF,42,13,65,6E,5D,B0,7B,69,A3,89,5B,F0,EE,A8,BF,06,B0,71,54,1B,A5,A2,B4,6B,DC,FD,61,8E,7F,E8,F2,EE,B6,02,32,B4,CE,0A,26,02,8E,5C,04,D6,0B,C4,B4,76,DA,EA,90,23,40,B2,B2,F9,C5,DF,17,6F,8C,4D,EA,82,36,4B,99,79,02,1D,7A,05,35,0E,6B,58,10,D2,C1,8C,7D,0C,EE,41,E5,0D,50,39,7C,CE,EB,83,DD,9A,19,A2,E4,B9,B5,71,4A,D2,31,48,39,C0,B0,7B,8D,58,D5,37,98,7F,8B,1A,7E,4F,1B,55,CD,30,27,2D,EA,21,DF,64,3A,CA,B4,AF,BB,10,B5,CE,A1,4E,6A,2D,63,F4,4E,49,DB,EC,D5,7F,F8,7E,69,83,8C,7A,C4,BF,67,71,1D,EC,E3,53,60,75,B2,88,FF,DE,42,12,FB,AA,85,92,7B,51,91,4A,52,7E,2B,51,13,35,4F,01,3E,2F,D4,34,63,3F,14,4D,AE,56,95,D6,74,5A,39,34,8D,ED,E9,72,79,B5,25,22,AE,06,EB,72,8A,E7,FE,D1,61,A2,54,53,38,65,7D,2D,EC,A7,47,56,E3,B4,9D,B6,4A,F4,A3,6C,D1,EB,50,EA,39,8C,28,EF,C2,C3,AE,4D,BC,94,84,CB,6A,EC,E3,9B,C4,1A,73,70,14,EA,41,52,E1,1D,2F,2A,53,21,74,0D,51,AA,E0,06,CC,C5,03,19,5C,97,33,5C,4A,28,BD,3F,3C,59,86,38,24,60,4A,6D,BC,0D,5B,D7,81,2F,17,12,3E,32,E8,10,0F,89,86,18,E1,35,FE,73,38,1E,E7,7F,68,9A,42,A3,F4,66,51,78,3B,9C,B7,D0,DE,17,C2,E4,DF,07,F6,C5,1A,D7,7A,EB,1D,96,B7,65,DD,B9,57,80,C9,D3,E0,30,D8,46,6A,C5,8B,0F,B5,50,96,E4,BA,B9,29,A6,BE,4E,25,C3,3E,CE,9C,22,77,C6,62,D5,F2,76,78,4D,7D,5E,E8,A3,1F,27,A7,46,0A,43,3A,9D,05,EC,5F,9E,74,3E,19,68,57 - -linearMatrices_full = 46,CD,26,E0,D0,32,B0,16,F1,5A,B4,1F,81,1F,0A,26,0E,51,A7,1A,33,60,76,CA,4A,6E,61,CF,CA,35,FB,30,0E,8F,84,79,45,5E,AF,8A,12,CE,9E,36,94,2F,63,E2,C0,82,44,99,D2,52,7F,25,D5,9F,80,F2,D4,C5,A1,43,D7,4A,8E,F0,BD,1E,AE,07,3C,01,1C,1D,53,64,6D,30,9D,9B,6A,29,49,32,9D,44,A1,91,4D,75,16,FF,1C,C1,34,55,2E,9C,FC,09,1F,6B,EC,10,DC,0E,D5,64,F5,B4,A4,A6,62,42,D4,63,53,34,31,B0,54,40,12,64,F2,BD,45,41,A5,8E,95,82,97,00,F3,09,C7,8B,75,AC,1C,DA,07,95,FA,5B,18,29,74,57,43,F1,C2,7F,A7,23,65,16,C2,34,06,26,D4,0D,5E,51,B9,78,C1,67,92,EB,52,2A,FD,A4,69,D5,F7,65,98,6D,EC,2A,39,C3,5E,A0,43,5A,B7,13,E0,86,6C,60,FA,B6,3A,85,54,9A,BD,0C,E5,08,A5,41,68,A4,D3,D3,FA,3C,F0,38,1B,DB,2B,E1,5A,F0,C4,5D,FD,0C,24,8E,2C,F0,E1,D9,30,83,4F,B5,4F,66,33,29,97,71,A1,71,66,12,58,79,B5,FA,2C,79,59,43,F8,E7,F4,91,8C,3F,0B,49,EC,88,1A,FC,CB,73,3F,14,26,7F,A6,D6,D9,69,32,B7,19,79,E2,5A,EF,2B,33,E7,FD,57,FD,3D,73,BA,46,F4,3F,D4,D3,44,66,92,2A,62,71,4E,7F,2D,34,7D,07,7B,2E,84,24,1D,01,DE,39,A5,63,E9,03,B4,F2,84,ED,9F,D7,D7,6A,31,C4,AF,B4,36,94,BB,C8,94,83,55,71,C7,3D,98,BF,8D,BD,BB,65,AA,92,07,8B,88,E7,F3,A7,30,EF,48,7F,42,73,7B,E5,D9,9B,79,4A,C2,68,8E,70,FE,88,DC,25,24,16,7D,58,CE,06,E6,15,EE,7E,7D,AB,12,CE,B0,EA,94,8A,9A,2B,4A,D4,B2,E7,80,B8,8A,D3,6C,C8,0A,7A,99,77,FE,D0,1B,CF,72,D2,9F,A3,28,5E,0A,96,4F,76,5D,BA,22,80,CA,26,15,A3,0C,CB,7B,0E,F2,5E,56,E2,D5,61,F8,E7,78,1F,C6,F9,77,5F,13,FF,0B,BD,F9,09,FD,BB,31,E4,24,E2,71,D2,DD,9A,73,C0,E9,E2,60,7B,BE,5C,64,48,1C,50,20,FE,C1,68,39,F5,E8,E2,C0,1B,92,91,70,25,89,18,26,CD,3D,06,8C,41,9D,50,69,DC,36,30,78,31,A0,2F,25,1C,95,63,E5,84,F3,B0,78,2C,AC,16,6C,90,00,F7,23,95,B5,1E,C7,49,03,08,ED,7F,8F,60,99,72,F5,B8,6B,CC,D4,6E,67,49,C7,C0,43,47,E3,DC,FC,05,D0,5C,83,3D,E8,47,ED,18,1D,66,E8,26,D4,79,32,C4,F2,45,9F,FF,15,BE,04,1F,3A,93,CF,2A,A0,D6,3C,45,06,3F,D1,59,9A,F6,3E,5A,7B,B1,EB,29,92,88,28,D4,9B,9B,09,DD,1A,F9,D2,BF,0C,7A,DD,AC,4F,E5,F8,AE,55,0A,13,80,F3,E1,BD,A9,B3,87,89,8D,2A,FC,7C,8C,BC,41,27,D6,41,30,13,34,54,F1,CA,04,67,76,41,71,E5,85,1B,C4,B6,2D,66,40,FB,14,50,55,EE,AE,EC,BA,99,99,DF,2E,44,41,1C,CC,1F,57,7D,84,4A,F3,E7,F0,F0,5D,A2,0F,9B,F9,2E,B6,69,4A,92,3C,29,34,D1,3F,91,EB,BD,C5,79,4D,A5,EB,5D,3B,48,9F,24,97,5D,54,4D,DA,17,8B,BD,B9,68,4E,5C,A8,2F,6B,49,88,E1,4D,3B,B8,E8,21,9E,87,0E,35,FA,13,D0,E9,53,42,69,0B,6A,48,9D,CB,8F,7E,72,21,04,5B,80,C5,9E,22,77,36,D4,20,C6,80,D8,BA,C0,6E,D2,6A,13,25,20,0F,8F,29,AF,9C,7D,48,91,B3,62,75,A8,6C,F0,21,FE,1D,7F,EF,CD,3F,A7,40,CF,6F,C9,12,31,28,99,2E,50,B0,44,5A,8F,03,2C,19,18,6B,16,C4,B8,40,21,10,6F,F1,C2,3A,64,E3,39,91,9E,DF,6B,40,C1,77,FE,EB,E8,03,DA,1E,70,F3,7B,C4,A1,FC,E1,53,9D,18,D6,80,FE,50,2B,8B,EC,71,2B,D1,31,17,D3,6B,6A,0E,77,F1,5E,FB,C3,32,0C,3C,C9,84,1B,D0,BD,52,99,B9,B6,F0,35,03,5A,29,0F,BD,58,F3,EF,11,C4,68,B6,A7,62,CE,13,15,60,FB,7E,BA,93,F9,0F,62,E3,F4,28,FF,F9,FC,27,9D,2B,A7,CE,C4,E4,FC,F4,39,1E,4E,E4,E0,24,19,F9,90,A3,B0,87,7E,4C,5B,40,A6,0C,61,27,EE,6A,E9,9E,B6,9B,3A,E7,9E,42,C2,56,8F,57,91,17,5D,B2,98,6C,96,0B,E7,56,3D,97,57,CB,9D,3D,02,39,8F,62,58,79,BF,91,9B,13,F2,93,3A,4F,85,60,1A,86,E0,D1,4D,6B,16,4A,2A,6A,47,26,DA,FA,7E,6B,54,34,A9,4E,F9,94,21,A1,AA,99,8F,E8,36,48,00,E9,EF,C5,D8,A7,D3,AB,5C,C9,96,AF,4A,D6,BD,14,6B,43,BE,C3,A9,60,B2,32,84,F2,E0,C5,49,C9,1A,1C,A5,8F,DD,E2,96,C1,1A,AC,4A,BF,D2,64,4F,B6,47,61,1C,A7,D9,04,31,99,56,68,5F,8A,77,30,3F,85,97,20,41,8B,BF,0A,30,61,44,0E,44,EF,AF,D8,4C,6C,CB,CE,4D,15,86,4E,03,02,46,57,71,F8,9A,DA,3C,28,10,41,85,D4,3E,87,46,A9,00,CB,7B,6E,61,F9,DD,40,27,B9,FB,48,6F,39,D4,CA,2B,35,AD,41,0A,AC,96,1B,31,1B,96,8C,1A,DC,A3,78,67,95,84,1E,73,BC,A1,5D,D8,BD,08,BA,2E,1E,06,3B,47,C5,B1,8B,7B,CB,77,55,C7,5E,B3,F8,FD,3B,C4,64,AA,BF,D8,69,C4,38,87,0C,79,71,0C,C5,35,CF,0F,E8,0F,93,B6,1E,E4,59,5F,C6,1A,8F,C8,44,89,8E,AD,5E,45,4A,96,19,C3,4E,A0,40,B1,3C,00,E5,A8,E7,A1,16,64,7B,87,14,35,08,F9,10,DA,3B,E7,20,AF,C4,9D,DA,5C,7F,FA,4B,B2,9C,22,E3,15,BE,83,4E,E4,14,51,34,FA,8D,A6,E6,B4,48,C7,54,67,F4,0A,68,07,0C,B4,13,CC,74,D4,76,35,B3,E7,9F,42,46,9C,AF,7A,36,97,4C,94,5C,64,F5,D5,7B,39,57,0E,E0,B3,78,0B,ED,8A,B5,A9,0A,9B,BC,FD,27,A5,2A,96,40,CC,CC,81,62,38,2D,61,5C,2B,0C,DC,1C,AE,11,4B,AC,87,1A,CE,9A,EF,83,6D,84,3D,90,B7,C0,24,C0,1F,6C,CE,2A,EC,44,1A,72,FF,E3,05,D8,49,5C,C7,0E,3D,25,E8,8A,5D,DA,89,6E,47,92,E2,C6,C3,3A,AD,74,68,E0,1E,8C,5E,57,6A,7D,8B,B9,E6,07,55,B9,46,01,10,71,24,A7,4A,C4,19,13,2E,D4,41,DE,59,C9,A4,A5,27,5E,0C,DE,83,27,32,2C,BC,92,06,39,5C,42,9D,B6,2A,5D,CC,D3,B6,C5,C6,21,46,BA,9D,AB,83,D5,A4,15,AE,C4,0F,53,B0,B0,A5,0F,8F,6A,58,4A,99,58,2C,E7,AF,4C,76,40,C4,2D,8A,C3,F8,6E,8D,EB,D0,AC,E7,A1,52,48,06,D0,9E,D5,04,B7,57,70,B0,2F,DC,FC,0D,B0,14,80,94,9F,D4,50,38,3C,9A,99,88,CB,69,F3,3D,5A,16,AF,92,19,27,37,14,4E,BA,9A,F3,D3,C4,2E,59,2E,CA,52,87,E1,20,F1,3B,CA,F5,67,6A,C7,D4,A4,9B,4B,BF,15,57,D0,96,76,A0,BB,A8,BD,13,41,0B,3D,58,3C,3F,DB,DE,CA,95,60,5F,D2,C2,13,45,E1,E2,21,B6,29,14,F6,7C,45,F8,65,CA,FB,A4,CA,5A,A6,27,60,9E,33,21,5F,54,5D,97,0D,5E,C0,87,10,27,EC,D5,2C,71,8C,BC,5D,A2,0A,F2,E0,C0,BF,11,74,0C,7D,43,2F,81,CD,3E,85,D3,B1,7D,DA,40,5B,C4,02,AB,3C,5E,A9,20,A1,60,B7,65,68,83,E4,02,B2,D8,66,7B,F7,1F,EE,2E,F4,C1,BE,9F,F9,57,1D,78,4B,5A,B1,DF,E3,2B,13,4A,0A,ED,9B,0B,B8,DD,5D,52,1F,37,BA,39,7A,60,7F,52,DB,02,DF,95,43,A5,36,3D,F2,B5,BA,DA,72,E7,24,3D,4A,34,4B,E9,A5,3C,5C,5B,35,4D,24,80,0A,45,0D,BC,6F,D5,EB,2E,67,6B,2D,3E,67,5D,0E,00,26,A4,51,1A,C4,93,C1,B8,BC,14,B3,DB,CB,25,45,37,EA,4B,D8,B8,E2,AF,4B,00,A2,95,F7,55,B7,00,C3,6F,D8,40,AA,9A,39,22,59,58,5E,5C,61,DC,5B,7F,D4,BA,18,94,88,AB,B9,A6,A7,62,09,57,48,6D,74,2B,87,0D,15,D6,11,EB,72,3B,D0,C8,5E,12,02,60,A4,E9,27,83,0A,C9,1D,E3,36,D4,E3,74,57,D6,91,FA,EE,79,4A,EC,0A,43,87,37,2D,8F,41,FD,94,E8,86,2C,E5,42,77,22,BA,45,08,25,A5,DA,8A,BE,BD,E3,BA,76,2E,76,BE,A6,33,93,2B,50,7F,A2,30,42,5D,93,41,87,1F,4B,CD,CA,06,C4,9F,27,86,FC,16,A8,6B,E2,EE,99,6D,2D,8B,0B,71,61,95,9B,FA,02,DA,91,1C,0D,40,9A,94,6E,75,FD,70,3C,F5,A4,A9,0E,53,53,ED,57,92,A8,21,BF,13,01,B0,3C,8F,BA,5A,E7,A2,B6,29,D5,5C,97,F2,15,FF,4F,11,09,4F,AB,CF,56,4D,C7,60,3F,E2,05,F1,6D,0E,90,0A,9F,4D,39,0D,BF,FA,7D,30,31,E5,51,0E,56,36,55,7B,97,E5,52,B9,03,B2,FC,4B,7E,08,B1,48,A6,AF,B7,E6,51,EE,26,79,55,70,86,93,EE,22,50,25,99,7A,EE,F7,3E,A2,C3,A8,CA,9F,FC,D6,87,67,60,A1,0C,7F,D3,5A,6A,38,EE,BC,11,61,46,07,DF,BE,F5,60,4C,CE,78,04,66,24,96,33,87,09,B3,A0,D3,25,BD,25,E3,AF,EA,AA,0C,C5,AF,EE,DE,0B,7E,45,27,06,66,50,C3,92,D4,A4,67,57,72,05,4B,E4,5E,61,52,89,55,39,19,B6,E9,54,2E,A2,C2,C9,3D,5A,D3,F5,F6,20,24,07,C4,A8,A2,58,F0,76,7F,35,53,16,17,ED,90,D9,C0,E8,B3,D2,28,A0,73,75,2E,33,1E,EC,31,55,3D,4F,3B,6C,DD,E2,EE,7A,BC,9B,E6,29,FD,00,5A,A8,C3,7C,9F,F5,57,63,28,92,75,C5,8E,E2,DA,E9,04,B5,04,68,22,7D,BE,F0,7B,78,60,6D,70,59,A2,17,F6,42,28,4C,0B,77,00,52,10,63,FB,C4,1A,6B,62,C8,AD,81,C9,E5,F5,79,0A,5E,73,4A,F7,66,66,43,FF,9C,D6,A0,35,F7,E7,E2,F8,6A,F0,65,1D,9E,95,FA,3F,1B,8B,24,FF,60,78,03,1D,E0,CC,58,27,25,BE,A8,AC,DD,E0,5F,AD,1B,12,65,CC,14,9C,C7,1D,81,E1,BD,A9,88,50,B3,5C,64,FE,26,15,AE,46,FE,55,89,C4,0B,FE,9C,A9,B8,A8,19,BF,7F,A3,F2,1D,F3,66,12,5E,15,E9,89,91,56,6A,12,60,8E,61,BB,46,A5,7D,47,71,B9,61,45,53,88,9B,D7,92,F8,D6,24,BB,B0,9B,A5,CE,6B,E9,3E,C5,16,E5,3F,42,45,A7,FC,37,83,63,7F,CF,CF,DB,88,1C,90,13,E6,CB,0D,4D,B5,91,71,B8,9F,AD,6E,68,45,CE,9E,5E,4B,35,9D,E8,D6,32,8F,1F,39,70,AC,47,78,C7,1B,E0,3B,7A,F7,2A,F7,AB,B2,3B,57,4B,14,A7,DF,A2,3B,B9,1E,53,42,B5,BA,83,4A,37,16,5D,C7,F9,E0,37,F1,E5,60,02,B2,AF,D2,82,10,82,1C,01,89,74,35,84,92,F3,E3,05,26,D6,B3,F1,86,44,07,04,B8,5B,FD,A5,C0,ED,CB,1E,47,9C,E5,70,A2,05,68,6E,54,C5,85,2C,A5,EF,14,A2,F9,5C,19,CA,F5,97,B6,C2,F1,81,0C,DC,9B,2A,2B,43,2F,44,A4,44,39,E6,F5,1B,B9,12,C0,01,07,59,A0,93,C5,04,C1,99,DD,CE,5C,2B,1F,72,4B,10,C1,16,8B,F6,A0,8C,A9,A6,22,6D,B0,22,98,05,DD,40,94,B0,71,44,1C,EE,F4,BA,C3,4C,73,3B,D7,C2,1F,9A,73,3B,58,60,20,47,06,18,07,95,E2,FB,9A,42,62,ED,33,B5,14,9E,40,86,C5,76,77,85,00,C5,6D,52,79,39,58,FC,FB,E2,5D,63,F6,F1,02,47,3C,FB,C0,96,DD,54,CD,82,F3,10,CF,E9,F0,F2,40,74,93,6F,7A,49,A8,2B,08,77,87,26,25,50,73,67,C5,02,F3,03,28,10,6F,22,EB,B3,72,F8,9A,97,66,9F,04,AB,CD,F9,99,D6,1E,C2,40,2A,7B,EB,F1,F7,B9,6A,AA,73,DF,97,A8,CF,13,7A,4F,F6,4D,25,81,59,EF,AD,D2,EA,EA,E2,EE,F6,E2,E7,F6,B3,08,30,49,87,C6,47,86,34,A8,67,95,AA,2D,FC,FB,4D,89,9F,32,85,CE,CA,27,DA,BB,1D,76,B2,67,82,84,AE,F8,3A,70,DF,59,BC,81,02,CC,D1,FD,84,20,84,42,EF,05,7C,84,99,AB,98,4C,8F,9A,32,FD,AC,4B,2D,DB,F3,88,8E,8E,83,56,BD,7E,14,5C,46,95,B3,C8,0F,88,70,DB,88,53,F5,36,5D,E6,C2,5A,63,B3,7A,06,9A,86,41,E1,EE,F5,E5,A8,CB,4A,C4,24,A0,95,CC,90,7E,7D,E3,0F,03,53,C3,3D,A5,47,1D,59,CA,0F,D2,33,13,4F,B0,1D,7F,66,D8,C5,48,B8,AE,BF,5C,B8,92,33,0C,35,9A,96,C5,04,BE,22,B3,7E,65,E5,12,F9,FA,C9,95,F2,B8,B8,11,3D,42,9B,B2,29,12,38,40,B8,0D,5A,B2,11,03,F0,96,D1,B9,2D,0A,38,FE,51,72,4D,53,AE,C9,30,C0,AA,23,8E,FB,75,CB,AF,A3,93,F2,E5,14,4B,8B,F0,4F,17,1E,9B,05,48,A5,F8,DF,AD,3D,C4,8D,8A,46,52,47,31,D8,F0,E6,5B,4B,2A,B6,C1,35,36,5F,BD,93,0C,9A,CD,B4,F7,E5,B5,8C,32,99,83,B8,EE,D0,FA,6A,AE,0F,AD,AB,75,79,84,ED,D2,C4,B7,3D,2E,14,E4,F2,31,02,8F,46,7E,BC,DD,80,01,AF,10,D4,6E,CD,D4,1E,40,CA,A8,F4,5E,82,41,CD,79,58,68,BD,48,91,05,E6,52,1B,18,DA,DA,E3,25,8E,65,5C,AA,89,50,F3,78,55,B8,F8,C6,18,0D,C2,BA,C9,B3,FD,B5,C9,D1,F3,DB,D6,D1,D3,DE,CB,A2,AB,75,3D,89,5E,6A,99,63,FD,BB,89,E7,ED,A1,E9,6F,CA,87,1A,2E,0D,9F,B5,11,76,32,D3,03,91,AC,EC,1A,A4,1E,2A,E5,CD,91,E0,A4,2D,C5,F8,6A,CC,A7,8D,59,1A,47,A9,7C,31,A4,D8,CC,0F,C0,02,75,11,9E,B0,27,58,E7,7F,00,27,64,B2,41,30,7E,7E,CE,DA,99,8A,33,99,5A,6D,E8,04,7B,7D,71,4B,50,3D,40,8B,EF,3F,8A,C1,20,88,6E,55,B5,EA,3C,D5,B2,14,B7,DC,18,46,24,56,41,99,BA,C2,70,2A,EC,1D,F8,FA,16,6E,33,D6,5B,4E,96,F4,DA,39,92,51,A6,21,09,96,C9,DB,88,1F,82,9A,52,3D,A7,FE,BB,0F,72,7B,46,1F,52,28,B2,0F,56,0E,42,63,1E,3E,A3,1E,21,FC,93,CE,46,A9,F1,B9,A7,52,4D,D7,52,68,EE,6A,67,2E,4F,24,64,0B,5A,8F,F2,58,8B,CC,75,43,AA,0A,0B,5E,8C,CE,29,EA,A0,B6,BA,C7,B8,D9,22,1A,C8,56,C2,31,A6,D4,F2,6C,39,18,07,74,04,4A,53,25,F1,FE,EA,5A,7D,CA,FE,09,B4,73,94,50,5E,BA,8C,20,A4,27,44,BA,48,36,F2,00,7D,B7,06,65,53,64,30,DD,CB,5D,1B,53,20,17,BF,13,F2,E0,B3,47,85,2F,41,E5,4E,FE,8B,7A,A0,D6,FC,DE,9B,94,E2,B0,50,CC,71,7B,DD,D0,1A,BB,C6,05,A1,63,16,D9,C4,CE,57,2A,7D,26,7B,AA,6A,D1,FA,54,C3,15,DB,F5,B9,6C,E7,85,AE,D7,13,94,77,80,25,62,A0,B2,2A,30,9A,1F,DE,F0,84,47,D6,9C,C0,67,8B,A1,FA,D1,57,D8,F5,9A,3D,ED,1B,96,43,C8,C3,3A,34,D1,2F,75,24,98,FA,58,87,08,39,14,34,45,FD,CC,7E,88,3C,EA,CF,69,82,7C,D4,CA,D0,16,71,A9,D5,98,55,34,2E,17,E7,80,64,0B,2B,6C,B3,12,8C,A3,98,3D,DE,7E,09,15,27,F2,67,3A,26,B5,5E,C3,7A,94,B1,C9,03,8B,E8,87,84,E6,18,8D,B3,98,76,97,7E,7E,BB,9D,BC,A8,D2,B0,79,C7,8F,82,E6,71,68,7E,1A,03,69,F0,71,9D,69,C5,77,B1,31,7F,D6,89,68,08,73,BC,53,39,77,A4,4F,38,FD,CB,3A,A4,FC,7A,2D,75,A0,FD,41,22,80,6C,59,89,7E,F4,F7,8A,7A,87,7B,84,60,B2,5D,9C,82,17,7A,CB,54,BA,7D,10,68,F3,1A,98,AC,40,3D,7A,3B,27,47,04,00,6E,C1,CC,54,06,66,58,01,C1,EC,C0,41,60,4B,FC,C2,04,54,F3,66,E3,3D,2C,11,68,C3,DC,57,0E,65,5F,DF,1A,AE,C5,00,20,B5,3A,38,DC,21,6E,D1,5F,C2,E0,7C,1B,2C,04,5A,6F,A8,26,98,4C,E1,3F,73,C6,03,B1,D9,4B,98,EF,DC,D2,4C,5D,69,64,AA,30,20,9C,AE,E8,EE,64,2A,8B,F6,2C,AE,56,09,B2,E8,4E,07,29,88,3A,02,07,8A,2F,5E,AF,F2,E5,39,E8,D6,43,E4,80,39,02,E4,31,00,84,56,DB,AD,3F,D9,26,C2,25,04,D4,ED,02,0C,07,F7,76,43,B7,FB,96,58,B1,34,49,3A,8F,3A,B6,9D,CC,EC,73,D2,B8,CA,D5,3C,BF,09,04,CE,08,1E,2A,F4,44,80,08,C8,88,A3,85,4B,4A,62,62,B6,9E,1C,2E,6F,19,07,3D,45,62,58,6D,2D,30,3B,3D,E5,5C,9C,FE,23,91,BB,AB,4C,3A,AE,6A,98,F2,CE,DE,24,FC,BF,60,44,A7,DC,06,9B,3C,DB,26,C0,B4,F8,FB,EE,3A,E2,B6,9C,3B,F1,A3,C7,F9,32,E7,00,5F,D0,9F,FF,C3,D7,6A,53,C0,59,DD,46,BD,F6,C1,9C,26,B8,ED,AD,E2,DF,AB,FF,D9,DC,EA,A1,E6,80,F1,43,AB,C6,A8,B7,E0,F2,52,04,97,BA,1E,95,8C,82,3E,93,DB,00,F8,45,64,85,52,22,3C,7F,A8,DF,E2,91,A5,9F,82,F6,39,8E,D3,36,0D,E8,A4,A8,02,D3,01,62,41,36,08,E4,2E,38,0F,D9,B2,8E,A3,F4,83,CC,E1,A5,AA,D4,BF,04,13,BD,19,69,30,85,6A,D7,3E,6E,4F,D1,A4,3D,3C,ED,05,6C,AA,B0,1B,95,F2,B0,BC,41,09,EF,86,B1,25,AC,49,CF,40,46,EF,3F,A1,D9,DC,11,08,3A,8F,C7,4B,90,93,8C,3C,04,E1,98,68,A0,B7,28,FB,7C,17,87,9E,A1,E2,28,C6,64,39,2A,E9,77,41,9C,26,CB,E9,C1,AF,62,09,26,34,1F,AC,07,F4,C6,61,80,97,47,19,44,45,C0,2B,1E,0B,D6,73,8D,28,3C,C4,56,3D,0F,1D,23,FF,2C,4A,BB,2A,52,5D,10,45,EC,AA,07,6F,47,D4,84,2D,EF,E6,31,BD,BD,8F,02,C3,51,61,31,8E,1D,92,94,24,A4,D4,0D,06,FA,93,0D,CC,E2,C2,3E,D5,63,55,2C,65,E7,C6,87,9D,1B,B0,D0,B9,C4,9B,FA,32,20,0E,29,9C,08,95,F8,04,77,85,59,07,E6,00,18,EE,2B,23,A1,C6,6C,D0,84,B1,5A,40,B4,B0,C2,B9,11,F1,C1,C9,D3,D8,22,A4,26,85,37,17,51,7B,BC,E7,14,C3,8F,0A,90,2A,AC,CD,8E,58,7C,0F,8F,89,92,8F,1A,42,73,3D,BA,DA,40,59,6E,A7,ED,85,13,44,33,59,47,65,D0,89,A5,D7,95,38,32,81,59,68,7E,9D,BA,D5,88,2C,1F,AB,90,21,CF,55,52,43,1E,58,D7,B6,91,89,BF,EA,69,A0,B0,C0,EA,C0,B5,1F,3C,2F,5D,96,F6,59,60,05,C1,ED,DA,96,4A,34,DA,07,C9,63,F3,0A,06,38,F3,F7,C0,86,2E,5B,A0,50,2E,AE,CA,B6,F7,78,BC,DF,E8,5B,2A,DD,8A,3E,32,56,78,72,FA,25,64,EB,B2,73,2E,6E,6E,12,A7,8E,40,E8,F2,1B,7D,8E,AB,A7,BA,EA,25,6A,65,7B,D4,A9,F9,A3,B2,A5,17,11,94,32,BD,D6,87,7C,8B,75,85,5C,9E,F8,89,E0,01,86,B9,C6,41,3D,3C,3F,3D,4C,FD,23,9C,C6,61,1C,DF,DA,C7,47,1D,2B,60,A2,8D,3C,46,9F,69,85,A9,5D,80,8F,4A,65,2C,3C,38,F8,61,93,6D,5B,E5,B3,EF,44,C0,51,08,8C,F3,DD,28,3C,85,B1,1B,BD,9F,47,FA,F5,06,A5,43,BF,6A,A4,6C,15,92,20,AA,86,19,AF,E8,30,C0,4C,6E,4B,EE,22,79,BE,65,EB,0A,16,A6,E2,94,5D,D8,E5,A1,84,96,24,65,D0,BF,C3,33,86,51,26,89,E2,67,E5,EC,D7,F1,E3,5B,69,39,54,00,EB,43,70,51,5F,E3,C5,01,33,D0,5B,EA,8B,9A,39,6F,70,5A,AB,1B,58,21,43,6C,AA,BE,D9,D4,58,7D,05,78,2B,4C,13,CA,57,AE,6B,FF,56,0A,27,52,00,FC,E6,D2,3B,72,0F,C0,B2,39,31,6D,84,D7,6F,3A,D0,1D,6C,5B,C7,8C,A3,05,26,4A,38,E6,94,8B,3E,50,97,F5,49,38,2C,26,33,CC,2B,B2,05,C9,3F,F0,43,32,B6,E6,E3,69,27,AC,59,E2,E9,34,F0,F0,56,F2,28,9F,3B,20,CE,50,0C,D1,19,B9,17,6B,26,96,A0,DE,FE,93,E5,DC,B0,45,F3,4F,93,23,EE,D8,23,F5,E3,E0,E7,3D,9A,E7,90,2E,54,53,06,64,FC,22,EF,E6,20,E3,D5,37,92,65,1C,02,5B,31,0B,25,3A,ED,16,65,C3,FF,81,C0,48,BE,0C,05,3D,77,30,53,C1,39,5B,C7,F3,D6,B9,F9,41,36,AA,DB,62,2D,C4,4F,79,F9,73,BA,EA,4D,56,75,ED,47,3E,52,39,8B,85,06,A8,D2,ED,BE,EC,C1,5D,00,C5,F8,29,E8,B6,EF,E0,8F,FE,83,21,1D,A1,5D,F5,AD,7B,EE,95,52,CA,86,C6,E6,A3,EF,FF,29,B4,5F,2A,05,C0,C8,54,18,E0,D7,77,D4,B7,1C,47,23,14,4E,DF,31,87,BD,50,30,66,D5,25,3B,67,18,31,92,8F,EF,94,DC,5A,1B,A0,A8,EB,5E,72,7F,31,25,43,E5,80,99,AA,A6,AD,26,22,52,A1,50,35,98,E1,6E,7D,1A,91,B1,1F,C8,61,18,8B,11,9C,6B,13,86,91,68,FE,DF,F5,DD,B2,8D,00,C0,21,72,76,D8,27,DC,1B,E5,CD,71,98,AD,50,E3,C4,85,FE,3F,25,67,FF,A8,20,C8,7B,BD,8A,BC,A8,B3,E4,6E,40,5E,DC,B1,38,48,31,DE,76,8A,63,5B,57,52,C9,09,A8,69,F7,32,D3,86,95,CF,FC,15,8F,9D,27,31,04,A4,A9,6B,BA,FF,96,0A,83,8C,15,75,B7,CC,3B,63,58,75,B0,EE,22,39,B2,89,2F,D1,09,67,C4,FC,F1,FD,82,BE,1B,22,E6,8D,4F,A9,29,83,3C,BA,69,24,3F,66,AD,A2,78,AE,75,31,02,C1,28,E3,1B,6B,E0,3B,AA,A6,39,82,AD,D7,B1,EF,21,23,9A,96,3F,0E,4A,B6,74,8E,37,15,3C,D3,F9,0C,21,70,89,B6,51,9B,8E,14,A8,7E,55,77,F6,C1,70,F2,D6,54,C5,23,23,34,96,64,8F,DA,09,B8,67,D1,D8,0A,5D,53,4E,82,6B,13,71,25,0E,AA,60,FC,AE,D7,52,79,29,C9,15,7D,A3,48,59,01,13,BA,B6,FE,49,D1,B9,F2,CC,60,99,BB,3F,B4,12,26,50,6A,4F,AD,0C,E7,6A,32,CF,56,43,93,ED,5B,24,D7,E7,DF,CB,0F,77,07,6D,28,59,C7,47,2D,FF,E3,05,C7,12,CD,EF,9C,07,87,44,CD,8F,AD,8B,BA,D5,8E,D9,1A,3D,D1,5B,A0,15,7E,C3,55,98,6C,66,97,73,46,8F,9B,DA,C2,4F,E3,92,75,70,83,24,35,D3,15,27,5F,CF,68,75,C7,46,30,F5,74,4D,16,58,33,E9,58,F7,2B,CA,39,E4,1D,D6,7A,D3,84,B9,55,BD,D1,61,8B,A2,27,36,5E,4B,F7,27,0C,76,2E,F2,D5,15,04,6D,B0,A1,F4,01,35,1C,99,2C,9C,B1,53,D1,B6,59,6F,23,3D,8C,65,F1,2F,78,E6,0A,18,EB,4F,A6,3C,C7,B0,14,5A,F0,CF,BB,06,A3,07,54,F9,8B,C7,4F,2D,70,F2,FF,1B,89,6F,AD,D0,1E,71,E8,B7,AA,20,A7,E6,B5,BF,B8,17,3F,B5,CC,CC,44,09,02,8C,7F,7F,C2,EB,68,5E,22,AD,FB,EC,02,B2,C8,5F,0C,5D,D5,5A,88,EF,6D,C8,91,E1,23,6F,25,44,38,94,23,F7,9A,C3,22,E7,5E,7F,B7,97,1A,D5,1A,BC,E1,C5,BD,AC,A6,A7,19,05,D8,D5,5A,B1,45,A9,B1,6C,36,E9,79,6B,99,B8,8F,1F,22,5D,C7,24,CD,A9,B0,D1,81,F0,C6,A5,90,83,49,B5,6F,95,D8,4C,DB,BA,5C,2A,B3,33,46,A5,5E,31,1E,40,C9,16,06,A1,D6,72,78,01,4D,00,73,CC,4E,1F,47,65,6C,18,B2,B4,4A,E7,E7,25,8B,62,69,26,57,A4,22,C1,A2,5C,C3,8E,9E,49,00,FE,2C,19,BB,C2,A7,C2,A7,0F,7E,91,7F,2E,B5,A8,1A,27,3F,FD,CF,5F,C7,2A,E0,0C,96,48,5D,A3,E5,42,19,45,B5,E0,AB,FE,BE,CB,20,50,EC,05,E1,F0,B5,E0,9C,66,FE,20,AD,A5,9D,52,FE,72,58,22,99,C3,27,19,3E,AA,CC,4C,D4,10,0A,39,4F,F2,80,46,1E,64,F9,69,CE,73,EE,27,1E,D6,1A,A4,9D,0F,63,11,E7,24,84,33,E4,FF,A6,2F,66,95,C4,33,C2,73,F8,37,A3,17,C7,F8,D8,14,10,CB,64,B4,E5,18,83,C1,84,6F,10,E0,03,D8,AE,1D,15,0E,97,53,0F,26,EB,80,E0,CA,AD,75,4B,94,C6,67,37,60,7D,9C,16,E4,11,5F,B1,78,28,CB,FE,90,87,04,2B,96,97,13,24,4C,6A,57,9D,26,36,BA,C0,5F,64,AF,44,D6,0D,EB,FE,F8,9A,87,68,BB,BE,99,C6,8E,82,7B,E6,9D,18,C9,1D,6C,19,89,53,97,0E,D7,C2,86,56,B0,50,5E,FB,B6,E6,7D,DA,87,05,C1,53,F8,8D,A7,93,88,3D,E6,D8,8C,61,37,F1,11,37,3E,2D,F1,25,86,6E,06,55,AA,CA,EE,39,12,E9,D7,18,A6,DE,4D,92,E5,47,1B,7F,CC,D8,E4,2C,B7,3F,FC,F4,72,92,7A,3F,34,4D,62,8F,23,01,2F,73,FC,3E,D5,B6,2E,35,CF,82,6B,A6,4C,30,06,F2,1B,A0,C6,BC,9E,63,23,5E,50,17,02,9D,1B,43,6D,C8,F7,F1,D5,9C,2A,A7,59,D0,14,E0,CA,15,40,A8,26,47,21,41,0A,A3,42,A9,31,64,B6,08,4A,50,5D,DB,5F,1F,88,35,59,F7,FC,F3,EA,8F,B9,11,44,76,40,31,31,5D,B2,A2,3E,7B,77,76,00,BD,50,19,06,41,1E,C5,E9,C4,5B,6E,E3,87,0C,55,9E,AE,99,93,89,29,46,07,06,98,F6,60,00,0E,6F,0A,04,EA,5E,52,76,60,5E,85,01,A0,CE,6F,EE,D8,14,62,D5,2A,01,03,A4,99,CC,8F,09,5E,0B,6F,03,FB,F0,ED,40,11,A3,6F,87,9A,22,92,09,47,22,9D,9F,FB,84,A9,E7,00,5F,30,1F,AC,CB,D1,5A,79,0D,E9,73,DD,73,35,73,1F,A1,5D,3F,A5,D6,9D,CA,5E,04,CB,DB,03,5D,66,CE,8E,00,A6,6E,3F,E7,D4,6D,93,E5,2A,D9,91,89,58,67,BE,A7,F4,F2,60,60,CA,1B,8B,9A,A6,E2,48,8B,2F,6E,7B,96,2B,C7,B9,A9,90,95,EC,E5,BD,44,71,52,5F,AC,97,6A,9F,BA,25,33,61,C6,F6,AE,E1,79,37,9E,CB,17,47,ED,12,4A,03,41,35,34,F8,5C,1B,44,F6,72,D1,01,2D,42,F6,BF,D4,FE,2F,12,06,A6,D6,ED,5A,6F,1B,C9,DB,9C,86,3F,8F,D1,20,DF,F8,71,65,BF,77,B8,D0,B2,08,56,36,A2,53,03,AF,EA,15,6C,C1,6F,0A,8D,9D,AF,31,D2,4D,33,34,97,08,44,80,D4,38,9D,90,27,57,64,1B,86,D4,73,EB,B7,E7,8A,15,35,62,6F,E4,B2,D4,77,A4,37,DB,96,2C,F7,44,53,61,B0,12,14,90,74,34,6C,2D,72,1B,E8,97,76,68,CF,E5,B0,48,E6,D8,A0,C7,C8,8A,3F,22,EC,B9,45,53,1E,B8,DE,ED,BE,65,1A,1D,62,10,FF,0F,FD,B3,AD,A5,01,36,46,A0,71,3A,CB,16,C8,EC,5E,B4,92,CE,DF,91,9A,8E,5F,AB,EC,EF,C8,8F,EB,72,2A,C4,BD,46,52,07,30,02,F2,2B,2E,5A,E5,FB,94,B1,62,E5,05,3C,BD,AB,A2,E9,7E,CB,31,8B,81,E4,70,E0,A5,0C,03,FF,AC,E7,43,30,2C,C6,3C,E7,EC,EE,02,48,5D,24,87,8C,A8,B4,FE,D9,12,D1,32,E8,B6,6B,F8,0F,2B,1D,C7,57,A6,BA,B9,61,7C,7C,AC,6F,EE,67,98,45,0E,7E,6D,46,97,6C,09,37,E7,93,37,C2,41,23,88,49,A7,8A,AB,F3,11,58,8A,69,80,9A,B2,DF,65,58,9D,58,6C,38,60,74,C8,D4,39,D0,9B,96,18,B0,62,74,74,A5,9D,3D,EC,DD,9C,D4,82,EE,55,07,FB,92,A2,D4,60,27,3F,5B,D2,E5,E6,B6,C3,5B,70,8F,F1,FD,06,93,6D,A6,1A,F7,52,98,E1,19,BB,CF,3E,51,13,F7,A4,A7,88,E2,B9,58,00,3C,AD,AB,25,E3,03,23,B9,3E,11,61,48,20,A2,90,52,C4,50,7D,7E,95,27,12,FA,D9,B4,27,44,7B,CD,4C,9F,B8,16,F6,3F,C6,66,25,EF,1C,58,0B,43,2A,FA,4B,60,B5,2B,C7,C1,11,8C,11,45,F3,E4,1C,AF,13,A1,1E,9E,DE,F0,FB,2D,0E,66,84,99,A3,E9,39,84,E5,5D,96,CD,34,BD,AC,4A,46,6C,F9,14,47,A3,A0,98,CA,AC,7F,06,77,83,02,43,8B,82,63,CA,9B,B7,61,83,F6,CC,8F,F3,A5,B1,63,B5,98,11,40,AF,7A,7A,5A,B2,C5,70,58,DC,BE,B0,C9,4C,87,B8,7B,12,F2,23,13,57,D2,A5,90,21,3C,19,ED,A7,1D,F0,AA,95,24,05,5D,4D,AB,22,35,CA,B5,07,AA,A1,62,B0,57,68,A3,55,7C,F9,6C,3F,0E,F3,97,9F,01,F5,F0,56,87,14,3E,DD,BA,61,A2,FB,C5,4E,1C,CD,43,C6,7A,A7,38,75,1A,09,32,C2,9F,21,01,FC,5A,0A,A1,3C,C8,36,25,75,61,A4,B5,DA,A4,4F,5D,EA,52,0C,9D,CA,2C,53,CD,DC,18,B2,0A,38,05,14,01,01,9A,A8,4C,6C,46,8A,BF,3A,F0,C5,94,1A,29,9B,7A,F4,29,87,3C,09,93,C8,98,5B,64,5E,F0,3A,EC,7C,45,10,AB,37,B5,D7,DC,F6,DE,D1,82,C5,EE,05,E4,71,E2,5F,0E,49,11,D3,BB,33,2D,63,4E,DF,A4,F3,F8,F1,A8,8A,6E,4E,9E,3F,B8,1C,9D,C1,D6,A8,07,04,A1,A1,00,CE,A8,82,50,A9,5A,5C,BD,8B,7A,50,C2,2D,BA,5A,92,67,AF,21,05,7E,22,37,9C,C7,E5,1C,16,A8,1C,43,B9,36,0C,EA,12,D1,9A,E7,18,D0,6A,2A,4A,F7,6D,E1,8B,63,94,77,3A,29,34,30,FB,48,0B,D9,E7,40,E0,96,04,ED,CC,1D,32,E4,CF,15,66,34,78,7C,79,E1,2B,4E,CC,27,50,68,B3,5F,F7,4C,5E,2D,70,91,0C,9B,99,AB,A5,93,6C,CE,10,D1,9F,27,0B,E8,F7,2B,09,0D,AF,E1,14,76,B8,FB,CE,3B,FF,F4,7A,19,32,FC,FC,22,F4,9B,41,06,D7,F4,D6,70,29,84,23,C3,54,C4,D6,EA,1D,D6,AC,5C,7B,DE,A8,77,BB,53,23,C9,08,65,C5,31,0E,05,C9,46,C9,EA,6D,5D,49,32,4C,13,38,D2,F6,F8,19,70,54,42,7F,91,6F,8D,37,E8,41,CB,95,60,75,A7,2D,A2,0B,D2,83,C3,0D,59,8A,6B,FF,4D,9C,9E,FF,55,04,26,3C,3D,86,EA,FE,CF,C5,20,E1,0D,64,CB,9F,35,50,B9,24,94,35,CF,6D,D8,6A,3A,88,16,90,58,90,20,EA,6F,26,7E,1C,A5,7E,DD,F0,5D,BB,A5,62,E8,93,B2,95,8A,CF,2C,9A,D9,BF,FD,16,D0,0B,8C,C8,0F,38,18,7B,AE,0D,55,AF,C9,75,3D,E2,10,49,7E,12,08,CB,39,1C,6D,54,93,AE,05,38,67,3D,08,D6,C9,50,47,6E,26,DA,5B,AE,74,C7,92,8B,F4,56,AF,65,F3,E9,86,3C,CF,0D,85,FF,3E,AE,EF,71,13,58,FC,AE,2E,8C,85,CF,C4,10,E4,E0,E2,1E,8D,D9,C8,F9,96,6B,19,EE,78,AC,58,05,29,65,EF,B6,D5,2F,EB,15,32,21,98,15,01,57,A2,61,6E,6E,10,36,D9,A7,A8,9C,14,6B,9A,5A,05,F1,05,89,4E,34,03,E4,55,89,50,E6,82,3F,06,2A,57,50,B2,83,8F,EE,71,3D,97,17,98,B5,4B,BE,B1,26,79,E4,AF,53,05,DD,9F,9C,D8,A8,C8,4F,62,39,37,60,6F,2A,FE,62,FC,58,98,6A,B7,2D,38,FF,D1,1B,A4,98,B5,3C,4A,4C,7C,DF,56,6E,D2,81,8D,4A,46,9D,C3,50,9B,A3,BB,BA,42,37,7B,4A,12,6F,9F,14,54,63,B8,A8,A2,8D,13,19,2E,BF,04,6C,09,0B,C9,76,CA,F3,89,00,54,50,EB,E0,39,1D,AE,DE,8F,9E,8F,F4,92,57,11,B7,2F,20,29,F8,12,1B,CC,D9,DB,46,3A,9D,57,2C,FF,E7,01,3C,16,C3,74,DD,3D,77,EB,FA,8B,83,E5,91,21,43,37,9F,7C,B2,18,00,A6,B5,6F,D4,24,1F,14,B5,4D,3C,55,6D,FF,17,AA,D1,FB,4E,18,E6,7F,DF,0F,B8,32,9E,4E,5B,AF,B3,26,D7,9A,CB,DB,9A,1C,82,BC,A7,36,08,17,6D,84,B0,33,85,65,C3,89,EF,5F,9B,85,68,CC,5B,AE,27,61,0C,26,C5,65,4B,10,F2,DA,1E,9B,44,27,DA,D1,E0,64,09,9F,48,61,07,F6,BE,66,97,56,53,0E,EE,48,B6,50,DC,FB,32,02,70,53,E7,68,C0,8C,D6,DE,03,B6,2C,5B,7B,B1,5C,74,6A,DA,66,87,17,C2,0A,21,C8,87,A5,61,E3,0C,80,17,05,34,32,F4,AE,65,50,27,1E,03,C6,92,6D,99,2B,1B,1A,6B,8F,18,AF,6A,AD,CA,3F,E8,BB,CD,B2,BF,43,68,6B,2F,DD,C4,1A,CC,8B,11,CD,57,74,A8,7F,72,F6,BB,9C,EE,F5,E2,76,54,1D,35,A5,1C,B8,74,A6,11,6C,AE,4B,7F,BE,5C,59,91,09,F3,5D,21,DF,6B,C5,B1,CC,6B,0B,32,C3,22,17,15,4F,BE,93,CF,E8,C7,CC,59,C6,B9,5B,FB,C4,FA,11,84,95,55,A0,45,33,48,9B,79,E2,00,29,36,79,1F,60,43,63,92,13,F0,73,6C,E2,BF,49,3B,CD,C3,97,34,44,19,FB,74,08,09,FF,56,CE,AC,1B,A3,8F,F8,9A,4D,48,19,83,37,60,80,75,4D,B6,8F,30,1B,8C,25,F1,63,5D,79,0C,51,8E,73,1F,F5,49,C0,3A,54,D3,77,D0,B2,9A,7B,AA,A7,F9,4F,3C,78,D6,AF,12,92,49,E2,C4,42,6E,01,F3,5C,1F,38,E6,29,E6,FF,3D,61,7B,7D,13,F2,F7,E1,24,A4,91,8D,E3,7D,0E,7D,E5,2F,4D,40,25,FB,F8,36,10,10,EF,C6,3A,9F,AC,DC,76,D3,4A,2D,61,01,D2,E7,0F,4B,38,98,DC,CC,37,D2,51,73,B8,0E,9E,37,82,F3,AC,58,A6,E9,6B,A8,F0,FE,28,E5,31,9B,6C,99,EC,47,78,B0,F6,7F,CA,48,93,DD,2E,F8,64,DB,DD,6C,88,C3,21,AB,C0,37,29,F5,5A,7C,3B,41,1F,55,2C,BD,46,21,7E,85,CE,0B,4D,A9,36,81,0D,4C,B9,54,94,8D,4E,B6,3E,59,7F,AA,74,57,B7,4B,1A,0D,DE,A3,66,0F,EA,FD,FF,B4,D1,86,0B,76,3F,A0,2E,54,E9,68,2A,3B,A8,EF,5F,5F,98,FE,B1,55,FC,76,08,1C,F3,C7,DF,4B,24,F2,F5,F4,8A,63,5D,B4,37,4E,81,17,77,B1,D8,B5,8F,FB,E6,18,F3,40,3A,DC,F3,1E,0A,89,21,54,6D,35,2F,3B,B6,55,8B,29,0D,55,B8,BB,B4,76,79,1B,FD,DC,51,CD,56,F6,F4,3A,50,EE,40,8C,5D,21,67,23,49,D2,19,CE,FF,8C,1B,50,1B,81,87,E7,EB,0A,D7,AF,15,10,CF,65,5C,B1,C9,B3,00,64,A4,13,68,82,12,2A,57,57,9B,42,DA,AA,13,11,86,9E,C8,DF,37,3A,16,E4,5E,DA,4D,E8,3F,F9,5E,02,CA,FE,2A,24,31,BF,38,12,7B,A6,3F,40,03,A1,C1,E4,92,D8,60,3B,84,00,AA,F6,97,07,A7,A1,91,17,22,8E,04,4C,88,72,E2,25,83,ED,06,36,90,CF,17,24,82,13,07,93,D6,0F,82,0B,6B,91,8A,6C,1D,9E,2A,1B,54,53,5F,55,53,5E,09,92,8D,E4,2B,99,02,29,98,7E,94,37,3A,C0,EF,1A,55,4D,4B,08,FF,09,D2,6E,0B,BB,6F,D9,92,30,75,F4,7D,2B,67,D2,9B,9F,F6,FE,93,A4,63,F7,19,5E,11,02,50,A2,53,B2,7D,08,19,7D,68,86,18,51,A1,F2,AA,83,37,5A,66,FF,72,FA,5E,C3,67,56,2C,AE,EF,C4,9C,C0,D8,48,EE,31,AD,11,2C,AE,99,85,AC,65,23,D1,A3,67,49,34,6E,29,1E,2C,1A,98,12,45,0B,C8,35,DE,59,6F,8E,AB,20,5A,1E,76,43,F1,C0,1B,05,07,10,98,0D,41,E5,B3,8F,00,1E,C2,29,2F,71,32,5E,D3,3B,60,03,E5,F5,E2,98,48,79,E0,E8,73,14,28,47,7B,04,EC,F6,78,B4,1D,73,F1,E7,34,6E,89,63,8A,7B,C2,C2,6A,40,DC,62,B6,92,F5,70,57,A3,A9,A3,1A,15,BE,BB,10,57,BB,5D,F3,78,67,41,2B,0D,E1,B2,5E,3A,B4,74,F8,BD,84,62,25,35,99,44,B3,85,33,D5,EF,E8,BD,E9,D4,24,78,19,5D,D4,7A,5D,D4,5C,FF,F2,5D,5D,CC,45,83,DB,1F,6E,31,58,07,EC,AC,66,98,00,26,A1,A6,12,CF,90,B6,FE,DB,77,DA,ED,32,8A,2B,0B,AD,D5,A4,90,DB,4A,55,8A,01,ED,8A,0E,8A,5A,AE,28,71,FC,96,EB,02,56,35,57,81,2C,25,C4,BE,20,B3,48,78,7E,0E,A9,DA,2A,FF,A9,C0,22,2C,BC,2D,29,76,10,5D,A6,DA,4C,70,0E,5F,9C,EB,9A,94,A9,6D,3C,40,5A,AD,B1,E6,04,9F,F7,AC,C6,56,74,94,98,38,0E,7A,AB,6F,42,3E,E2,8C,14,8B,36,0B,8D,F5,1A,09,64,3C,99,1E,81,D1,99,38,35,BC,8B,8C,17,78,8A,93,A1,E6,B4,7B,DC,4E,4B,C7,AA,AB,D3,6C,9A,9B,40,4E,A7,A6,6C,68,36,5E,A6,85,D9,5A,FD,56,8C,5D,3E,49,56,98,0B,80,76,2C,41,BB,65,95,F3,56,61,0A,DC,9E,04,8F,D0,E8,AC,87,AF,D8,15,20,7A,E2,DA,2A,F5,94,DE,0D,8B,5C,B6,91,F9,CA,6B,F1,58,E8,34,3F,07,2C,57,1E,B6,D6,13,59,A2,E3,DC,C6,7E,CC,C2,E7,66,F6,DE,40,4E,32,E5,CA,9B,1F,EB,EC,2F,A5,74,54,62,0C,FF,99,41,89,C9,57,44,50,6C,73,41,B1,D2,65,74,B1,1C,AC,A2,CB,A4,D1,D2,CA,46,B3,64,E5,04,66,D5,C0,2C,A5,01,83,C1,D7,13,E7,BF,37,14,3D,C6,9E,96,9F,07,62,AE,F1,B6,56,0C,31,FC,62,6D,04,A4,6A,A0,24,64,11,D7,7D,86,48,84,82,D1,DE,31,BD,BA,5D,11,38,D2,DB,10,56,19,C6,45,7E,A2,5C,37,20,67,8E,03,FD,32,58,E4,55,89,ED,A4,67,C0,98,19,0B,90,D3,0B,49,C3,7E,A4,ED,02,A8,24,17,02,A2,03,3A,B9,0F,70,CA,38,B9,E8,3C,D1,72,1C,08,9B,73,70,50,7F,4B,4F,77,55,D1,10,50,EC,04,A5,D8,7E,1E,30,BE,88,26,A7,88,61,05,34,27,F9,72,A3,B8,3D,13,B8,09,6B,AD,59,C9,FC,5B,4D,F6,EF,67,F8,55,94,A1,2A,B6,8F,E5,FF,E0,AD,58,60,0D,53,59,F6,6F,F8,5C,7B,2A,20,17,4F,41,75,22,A9,65,78,45,61,5A,BE,DE,15,A3,EC,47,7A,45,A3,A5,9F,A0,56,E3,C6,61,CE,7B,8B,91,13,D3,22,EF,9A,3D,74,4B,24,B8,1A,9F,F6,19,3A,6D,B5,A0,5C,0C,C5,AE,20,19,68,7D,2F,BD,4F,69,2F,54,57,1B,15,4B,B8,42,30,90,81,32,6E,21,AC,A3,66,71,84,A0,65,47,2A,1B,0C,D9,7C,72,62,EA,0A,BD,6D,89,71,28,A4,93,77,6A,A8,73,CA,B6,7D,C3,5D,3E,F0,E7,69,1F,F0,8C,D2,75,4B,6A,41,84,AF,FF,CA,E8,F0,BC,0F,F2,99,4E,B2,E3,3A,1A,0F,88,A5,B8,E2,16,E6,7A,F8,96,82,37,68,7E,C4,87,50,65,31,74,4B,14,B5,6F,49,40,31,A8,45,C5,C6,67,C1,70,80,C2,E5,5F,58,E3,E5,66,E6,CC,77,B1,EF,9A,45,F1,73,94,37,39,E4,D1,20,96,25,7E,4A,5F,DD,6C,95,41,6C,52,02,8D,EE,D7,EB,F4,D8,38,5F,71,7A,A4,D5,E6,8C,15,CC,37,DD,B6,CE,67,74,B7,E5,66,9B,F0,42,FE,AE,25,A3,AF,71,A9,ED,DA,57,5B,3C,7D,B9,46,22,96,52,A0,40,FC,3E,BA,66,29,AE,37,CF,BF,F1,D8,A4,D7,2A,AD,CA,A8,11,9B,2D,AC,22,5D,EA,E8,84,33,51,A7,26,19,A2,A3,77,B5,92,BE,89,87,6B,02,67,F8,D8,B7,D2,BA,15,6E,15,B1,7D,EA,B4,78,73,F2,AD,38,CD,DE,FA,C8,FB,9C,FF,34,88,11,0F,3D,43,2D,80,58,E1,ED,6F,11,25,3F,25,83,32,53,3A,9F,17,D7,03,2E,FA,28,37,AF,3E,CC,84,7C,2B,FD,47,B1,1E,CA,CF,95,35,58,E3,C8,A1,1E,F4,D2,18,93,86,3D,04,DC,E0,8F,02,18,E4,6A,F6,43,E4,3D,58,62,E7,B2,7D,7D,0E,81,1B,E4,9D,61,DA,CB,67,16,3C,9E,59,72,D9,37,07,D3,85,E7,78,2E,CA,A4,5A,F7,D9,74,C1,37,E1,AC,92,F8,0E,DD,6E,1A,13,29,2B,21,17,05,72,DC,C8,68,C8,F7,30,BA,6B,DC,FA,F4,E5,20,C6,95,ED,2D,D6,EA,B5,D0,D1,0C,E2,80,7D,7B,2B,A9,C8,2D,71,D1,6B,16,CA,13,71,8B,3F,9D,10,DD,4C,DB,B6,A1,D2,59,5B,1F,E7,BD,1D,C4,E7,0B,2F,42,87,80,81,F7,28,3B,80,A0,DE,3D,A7,CC,69,14,F0,66,74,A8,9E,1D,4B,7C,F0,8B,6E,4D,ED,5A,0C,86,EA,DA,F6,D3,33,AA,EB,BA,F4,F7,39,20,CA,FD,9B,86,4D,50,CD,E3,29,09,74,11,B4,0C,F9,7C,85,FE,C4,98,09,37,37,02,64,F7,84,37,20,D6,CE,EC,60,72,4A,73,D9,98,A9,D7,0A,B7,01,E2,3D,62,91,4A,7F,C2,C0,50,DE,9E,A8,F9,50,59,94,70,F2,EA,CC,E6,0E,3E,EA,BA,08,98,AA,6B,A8,B8,E9,C5,6B,54,EE,BD,BA,BE,A5,45,CC,03,A2,82,43,14,6D,F5,2E,5E,8C,D7,35,5C,78,0B,F6,DE,58,09,E3,E9,A9,BD,09,4E,48,B0,7E,77,9B,B3,10,56,35,7B,A3,E4,11,A1,19,CE,D3,35,8A,EF,D2,E4,37,31,F7,C6,D1,34,93,06,1B,9A,FB,4D,9C,2C,AE,6C,EE,A8,AB,16,AE,75,98,D8,84,95,65,56,20,E9,FC,70,D1,10,A2,D7,FC,37,AD,26,E8,44,C3,42,CC,18,C3,59,C9,3E,77,0D,FB,8B,27,D1,A4,97,41,B9,D7,58,4D,C6,CA,51,53,8C,37,AA,7B,E2,BA,42,9B,3D,EC,81,8F,BB,06,46,10,39,76,F7,73,A0,D0,7C,35,7F,64,28,C0,AF,A9,80,B8,B7,6E,25,50,CE,DD,0B,E0,18,EA,29,D7,27,CD,B0,9D,44,DF,53,40,F7,D6,98,63,60,57,73,03,30,A5,F7,37,5F,14,88,9C,60,9D,EA,00,E1,DE,DE,3B,1D,05,15,03,63,CA,33,6C,08,69,5E,6F,90,CD,50,79,53,A5,66,76,DD,55,12,49,B7,9E,18,49,D9,D5,7E,FE,1B,7E,B7,DF,61,46,63,5C,C9,91,F9,86,AF,D3,34,F7,9D,6B,2E,59,51,90,20,D9,6C,3D,3F,2F,8E,76,3E,33,F5,27,B6,25,FE,AE,AA,84,49,69,BC,02,A4,58,47,34,F5,E5,50,A8,CB,93,26,5A,A2,07,16,4C,C4,C7,46,9F,38,D6,77,E0,8A,0D,58,AB,BF,E6,F3,AD,27,DC,27,4E,A2,AD,3F,BB,0D,87,B1,97,E3,21,09,32,10,2E,3C,82,99,11,81,0F,45,D4,E0,35,3F,76,EB,55,7D,54,F1,4C,36,BA,DC,4E,E5,02,7E,87,B6,7C,11,6B,0C,9D,12,B3,F0,1A,9C,26,75,2D,3F,94,06,E3,DA,30,B4,72,2C,9B,4A,E4,31,D8,47,3E,CC,18,CF,62,9C,4D,E5,31,B6,D5,FE,E6,9A,96,70,C9,D4,5E,AC,1D,69,3D,79,00,CB,24,3E,FA,14,43,03,A2,62,FF,31,BA,30,7C,3A,45,DD,0E,89,66,8F,EA,52,DB,12,3A,33,1D,E8,98,BC,FA,C4,61,0B,50,63,E9,E3,CD,D3,18,B8,77,7B,59,47,46,63,37,6D,3A,7A,89,E8,71,FF,11,28,8F,70,B7,90,EC,C4,78,9B,92,54,86,B4,4E,14,48,CF,E5,30,45,61,07,03,3E,8F,B2,4E,C4,BA,0E,18,D2,66,82,25,6F,61,DA,5F,5E,59,8D,E4,7A,5C,AE,8C,DE,07,02,DC,57,1A,C7,23,BB,AF,92,83,6D,98,57,F1,98,AC,06,79,14,95,4F,E6,EA,78,9D,AE,D4,3E,43,8F,E8,0E,E9,7D,6D,EC,E4,E5,46,8E,02,1F,00,A0,C8,7D,AA,DC,6F,45,2A,67,08,C4,50,26,E6,C4,7C,98,CD,B3,D2,20,ED,3D,15,3B,6A,31,3D,76,39,EE,24,30,80,5B,82,4A,8D,CB,21,FF,D7,66,FA,94,32,A0,CB,9F,36,1B,83,48,BA,D0,F3,24,8D,E3,22,29,B1,16,0A,F1,E9,AD,DA,10,1E,B9,61,33,A0,F1,A6,03,7E,BD,FB,A6,A9,A9,A7,7A,33,38,02,3A,FD,47,0F,C3,9B,0B,4D,1B,FA,84,60,31,0A,DD,35,F9,30,91,E8,E3,4F,69,E1,03,95,AA,E9,E4,CA,D9,C0,EF,6E,6E,AA,91,A4,94,EF,9F,90,E9,17,A0,34,33,88,92,A1,67,B5,BE,65,CE,02,4A,63,31,49,77,A1,91,DA,5E,93,9D,0A,0E,D9,6F,FD,B6,B0,BD,3F,F6,ED,FF,64,D3,E2,EE,2A,55,AF,41,60,96,CF,EB,7C,41,6B,79,29,50,22,CC,1A,D0,F3,73,E8,1E,49,76,F3,BC,BA,67,73,31,AF,9F,7F,E8,35,48,57,EA,F5,12,F5,F6,48,70,FC,F7,48,5B,C4,8F,C3,5C,54,42,91,66,72,54,5E,22,EF,94,DF,68,0C,9E,B8,ED,04,74,82,28,92,D5,D9,12,91,9D,4A,8A,0E,33,D7,74,D9,7B,C8,9C,29,6A,FE,11,83,5C,69,D1,67,4A,CA,85,A0,4A,F6,EC,60,59,B3,2F,56,2F,7A,BC,C4,AD,A9,D8,CB,2A,52,1B,B4,01,73,76,E1,C9,65,D0,E5,60,B8,5F,70,11,19,15,DD,25,94,7B,D3,E1,7F,BC,F6,D6,92,B3,FD,E4,1E,D6,23,CA,04,E0,E8,20,58,1E,39,61,13,13,9C,19,4A,E5,5A,3A,C9,71,DD,F4,C8,B4,F4,DB,4F,0C,FA,85,E3,12,4D,A4,6C,73,F6,C3,E0,60,C0,D1,B3,0E,46,48,6E,64,31,C3,EF,3F,E0,1D,FC,E4,F0,CA,10,6F,4A,7C,FB,94,5F,E2,BF,B6,4C,56,CE,59,5E,98,74,1A,5E,6A,43,92,C7,00,AA,E1,3F,B2,82,30,48,AB,9D,81,91,6D,DB,C8,67,90,B2,88,75,26,31,8C,40,34,7D,08,EB,27,B8,90,E8,8A,8E,90,E7,76,78,AB,92,26,E2,35,1F,56,7A,B2,0A,2F,16,F3,02,24,A3,AB,33,88,A4,81,0E,8D,EB,AA,96,4A,FF,85,1B,ED,4C,5A,C7,95,B1,75,93,F7,89,F6,13,9A,DF,1B,5E,45,81,10,52,00,53,45,4E,18,BC,3E,CD,32,9F,E6,8F,E8,26,2E,2A,D8,8B,45,E0,52,41,39,9D,F6,31,6B,98,93,35,5E,01,14,EC,20,51,F6,2B,D3,9A,FA,09,10,FA,51,D3,1E,85,40,E7,2B,2C,89,9F,21,A5,D2,9A,4F,27,89,55,1B,75,08,9A,DC,41,94,CF,6C,47,D1,41,0C,A9,D1,30,B9,74,34,5B,78,D0,27,06,0A,58,39,A3,81,6F,F4,90,73,BC,C3,74,44,9D,FF,66,8A,06,C4,D7,03,B0,85,13,C7,F8,2B,12,AD,2D,66,94,61,24,AD,80,1E,7F,8F,3B,BB,6B,18,32,54,59,FE,7E,7F,03,94,80,02,B1,88,73,5F,D2,5D,44,A6,12,3A,41,B4,DA,14,7A,7E,57,28,A6,40,DC,83,13,63,95,B3,FA,0E,D8,11,F2,45,9D,C3,2E,36,42,C9,0F,4A,C1,0A,87,08,E4,C2,68,63,AF,C0,AD,B0,2E,2E,72,9D,F8,7E,AE,15,3C,76,76,CC,72,F2,59,DC,08,D1,46,4F,20,A7,70,CF,7C,9D,58,F7,F1,20,B0,14,59,2F,12,AC,21,8D,36,00,DA,03,8E,69,AF,B6,F0,A4,4A,7C,56,58,17,51,17,1A,EF,BD,68,A7,5B,32,BB,F2,5B,73,54,59,A4,DB,71,79,78,61,E0,04,55,1E,63,3E,3F,EC,AB,46,32,D4,15,DA,5C,EA,24,E6,53,74,9C,27,DC,A4,03,FC,AA,01,8A,63,AC,F4,C7,26,EF,8D,9F,BA,AA,A2,F6,06,DF,1A,30,26,B0,88,80,FC,8E,47,05,6A,6C,5A,39,F5,62,5B,BB,73,4C,66,77,C6,AD,56,09,19,C1,F5,5B,AA,A5,3B,00,43,E7,25,AF,DF,89,B5,08,75,E7,65,8B,C7,65,0E,45,5B,F9,00,39,BE,C7,1F,77,FF,7D,3B,08,64,32,CF,C5,67,EF,8C,5D,F8,52,8C,03,21,8B,4A,25,CD,30,96,F1,E0,0D,8B,57,AF,A6,75,F9,A8,F5,F3,98,16,73,D9,05,07,5C,CE,3B,AE,8A,88,CA,2A,E7,A3,4C,14,B4,59,15,49,32,64,4A,4B,8F,F5,DB,D4,30,D5,94,FF,E3,9D,56,73,76,4E,F8,E3,8B,0C,57,3D,5C,03,4C,78,D4,61,C7,75,84,9A,9C,B2,8E,AB,96,E5,A7,2A,B6,FE,7A,9E,7D,94,FB,2C,CC,FB,4D,7B,7A,D9,37,1D,0B,81,8B,3B,A3,3F,48,AB,BB,2A,CC,21,46,D6,C5,1C,E9,45,2C,16,61,46,37,39,71,ED,94,F8,87,EE,81,67,21,19,DA,D4,8E,53,44,4E,9F,F8,56,E9,58,E2,38,63,1D,B8,35,CA,A3,1F,B4,06,2F,A2,C4,0D,12,84,6F,B1,3A,9B,4F,CA,A8,E3,B1,33,D0,47,82,A9,08,4D,FE,03,4D,65,5F,97,3A,98,84,A6,CA,E3,65,6F,9D,EB,E8,7B,15,49,FF,C4,43,54,3C,27,E0,85,A3,EB,71,4E,AC,7D,1C,48,71,FB,26,28,14,7D,EC,F0,8A,E4,39,78,A3,D0,25,4A,1E,05,07,A4,C6,0A,48,94,1D,AD,64,BC,2C,A5,EF,76,B4,B2,C5,C6,0D,FB,06,13,9F,D3,7A,7D,4A,42,5D,07,60,74,14,A3,18,93,38,66,C0,E1,3A,97,D1,7F,ED,A7,99,AD,DF,87,80,3C,13,FB,39,68,F9,94,10,2E,70,3F,9B,F7,4F,41,C1,F0,DE,A6,DE,62,1F,31,72,80,5C,6A,A2,AA,16,0B,41,53,A0,E3,05,E3,F7,53,1D,C5,64,A5,0F,E6,F7,70,63,C4,47,73,56,DC,AD,70,13,4A,9A,F8,22,FD,66,BF,FA,A5,DD,C7,D2,15,9D,A6,7B,CB,BE,9F,C8,F2,A7,AD,47,7B,85,EB,33,ED,AB,3D,8E,B1,1A,C2,9F,F5,21,43,EE,9B,99,D7,64,2E,8A,A8,F1,F0,DF,7C,F2,56,8A,A3,B3,18,EA,93,39,09,9D,7C,DF,E6,EB,6A,A3,A6,59,E1,84,45,B4,28,AB,C5,0B,F8,CD,1B,F0,07,54,6F,AE,58,58,4C,22,52,62,D1,9B,4B,E8,EB,5F,B8,49,6D,B9,E0,7F,DA,9B,33,D8,7B,43,96,42,7A,69,A5,DB,73,3F,83,AC,E6,9D,38,12,DC,EC,9C,DB,7F,B6,23,E8,AE,D4,99,C5,74,74,B4,1F,E6,29,BF,8B,9C,66,7B,4F,38,87,EF,A8,D8,CD,06,41,1B,79,35,46,3E,3B,1F,9C,24,E3,36,C4,93,29,8B,72,A5,7B,9E,11,D2,EF,5C,1C,8B,1F,70,3A,05,64,58,D3,AD,0D,47,BA,D0,04,75,EB,27,DD,C6,6A,DE,25,07,44,C1,6C,37,E0,81,E6,1F,B7,62,77,26,E0,E1,42,36,E7,B4,D2,57,DB,A7,D3,79,22,7C,93,06,09,52,74,35,04,CB,F2,FF,65,24,27,2A,D9,0E,28,2B,9F,66,65,45,4E,F3,96,B5,91,F2,24,69,EE,0A,99,2D,72,1C,B6,5D,02,61,6F,91,37,5A,8F,F0,24,9E,0B,B4,BB,07,37,A0,8C,FE,FC,5E,F6,AA,0A,AF,C9,3A,49,B7,87,79,49,69,C8,18,55,E3,A0,C6,70,78,55,83,19,5E,3E,7A,DB,4C,B4,C8,F6,3E,6E,4A,BE,11,DC,6D,7E,5F,61,22,A1,84,2A,2A,A5,93,B6,55,3D,22,40,DC,EA,4B,4E,7E,BA,C3,CF,8D,38,0E,41,86,C9,20,E8,4E,A2,44,EE,25,A3,01,87,59,58,35,E3,9D,7B,EE,5E,3C,EE,03,95,E8,B6,71,EE,A4,01,0D,B9,E7,28,21,E7,73,AE,96,63,82,00,6C,2E,A8,1E,92,C1,F7,64,6B,77,91,69,E5,C9,DB,83,94,05,DF,A3,64,D0,D1,6E,6C,2D,5B,0A,92,F5,BC,31,EE,5C,7D,02,A9,9A,9C,38,F8,03,1D,C2,EE,99,B2,5D,62,D9,87,AA,C0,E8,E3,93,44,1B,78,CB,C2,02,FB,2A,9D,F9,EE,D2,44,20,0C,72,9A,0A,79,6D,47,CD,D4,BF,EC,A7,6F,E1,03,41,E0,77,03,6E,8B,21,69,8B,EA,41,59,54,7E,29,BA,CA,6F,5F,C3,82,E2,78,28,62,35,04,0E,E2,84,CF,34,58,F2,2B,7A,5D,5C,32,43,01,12,39,5B,7E,6F,58,D1,6D,BA,A3,3B,C4,50,EC,44,EC,51,41,26,EE,FE,20,95,2F,31,E1,B2,F2,F6,4F,F7,EC,56,E8,6D,08,21,6D,05,4E,69,3E,5D,A8,58,6A,E4,00,C7,65,23,3F,FF,92,D9,F2,3A,92,A4,9F,9B,87,7D,09,9F,70,43,F3,58,E2,5E,00,80,33,C3,00,7C,FC,6C,96,A6,DD,27,80,5F,02,6C,56,67,1C,6D,7B,73,D8,98,D9,2A,5C,B3,15,1F,3B,43,B9,39,36,65,16,6D,96,8B,B1,06,1A,CA,03,0D,33,2B,95,06,71,61,B9,83,63,91,4C,6D,6F,C8,9C,F0,14,E9,5A,C3,E2,37,5E,22,FF,38,19,BB,CC,79,26,EA,28,9F,E9,61,DE,E3,05,04,29,A3,78,2C,03,1C,44,3A,5D,0A,06,9F,AE,51,27,A1,5E,58,B7,61,F8,34,19,FA,10,11,A1,9F,78,96,85,08,4F,7F,14,59,42,6C,33,8F,BE,44,F5,F9,B8,18,79,D5,C3,33,57,1E,79,88,B5,10,D4,E1,02,B6,04,95,A2,8D,16,51,59,98,DF,28,40,28,38,AA,76,9E,34,B2,AA,11,38,1F,03,70,48,13,1C,C3,B4,98,3D,DF,65,AC,12,92,56,BB,A0,11,8A,7E,8D,CD,14,F7,2A,5C,66,C8,1E,7B,07,FA,92,C8,F4,51,A9,2E,99,AE,B2,96,05,CA,8B,08,46,07,A4,28,C0,8C,E6,57,23,17,D2,BA,AA,CD,08,6A,72,D7,7C,B1,F8,1F,32,78,93,72,6B,12,3C,F0,9D,AD,B1,C0,7B,2B,29,56,B1,38,40,AA,4C,CD,7F,F4,85,82,90,1B,30,53,A3,56,EE,13,B5,C5,14,93,01,1F,FA,69,16,40,E2,0E,A1,8D,CF,02,A7,97,DC,31,D0,65,7D,E1,FA,D0,E9,BE,D3,DB,7A,E0,2A,99,40,C7,9F,FE,32,A6,AA,4C,6D,60,A9,FA,8D,B8,94,42,FD,E0,A1,D4,26,14,A5,5A,D2,A6,DD,23,62,C2,F6,DB,10,8E,A5,36,63,36,2B,42,FA,ED,50,17,6C,0E,C9,25,63,75,29,73,6B,1F,52,06,07,ED,73,86,0F,9D,E5,78,68,A8,1C,A4,5D,60,D9,AB,F1,42,DF,E0,1B,2E,10,45,97,58,C1,1A,E4,84,9D,61,9B,ED,E0,75,36,2F,B7,99,A3,51,BE,30,F8,19,F7,86,00,33,95,F8,C6,E5,D7,DF,AF,3A,88,0C,BD,E6,CD,DF,33,1C,6E,0F,7D,09,CE,CB,60,CB,45,6F,E7,7D,03,23,FF,E9,B0,5B,67,F4,EB,A5,5F,55,EA,11,E1,52,A7,87,0D,34,AB,AB,31,9A,83,08,92,29,FA,37,C8,57,3D,9B,A7,80,56,4F,E5,AF,59,AC,DC,0F,C5,74,E9,67,20,F8,08,E7,81,05,7F,FA,6F,1B,C7,44,7E,C7,B1,85,62,F1,D7,E6,24,AC,CF,BA,D6,EE,D5,D9,0F,24,7E,C1,A7,EF,7C,0D,70,4C,B6,D0,47,F2,36,71,5C,5D,BE,72,A5,AB,61,29,F7,9C,CC,FA,EE,4E,A6,97,5A,9E,AA,31,8E,2F,AE,51,33,06,CA,91,3B,B4,93,36,C2,FB,2C,6E,6D,ED,C3,00,83,E5,2C,00,A2,85,3C,66,4E,31,53,30,7E,89,9D,A0,3C,1B,8A,E4,5A,DB,10,66,93,82,8C,33,13,4F,67,11,32,F6,57,9F,8B,D1,92,D4,9A,9F,DE,7A,76,B2,7C,1C,F2,2E,7E,6C,05,5A,2C,F1,00,33,60,FC,E7,7A,60,F6,09,2B,09,BA,20,F4,CB,B5,8E,BB,A9,80,22,C3,E3,DC,47,99,39,97,B7,B7,1D,F1,07,A9,C2,93,7A,7B,E1,D0,30,47,BF,0B,83,76,A9,52,FA,46,AF,FF,0E,EB,60,01,70,35,5C,F9,03,CE,F8,90,85,B4,EF,71,1B,A3,6D,EA,06,30,28,5B,E1,60,54,45,20,53,D0,5D,3B,A2,0B,18,1F,47,C5,19,92,B6,1D,16,07,CC,D2,8D,5A,75,25,98,A0,D1,5B,F6,E2,2A,FB,56,03,16,D4,00,0F,C5,07,44,C5,47,31,D8,2D,85,59,21,96,16,FE,4B,F5,67,04,8E,7A,D0,4B,11,39,02,81,B5,39,21,D1,75,D5,19,CE,91,00,3E,60,37,83,F9,FF,D7,A0,AF,3F,A7,8E,00,76,9B,65,DA,DE,57,03,5F,42,91,32,AA,6D,8D,DD,8F,22,EE,CA,22,8A,3D,28,88,F8,50,F9,13,15,D8,3F,B7,62,B5,C6,31,49,15,18,15,33,3B,6B,34,1A,06,31,D5,3F,A1,19,66,F8,42,8E,3A,1B,85,B0,51,14,C7,DF,E4,C7,E6,BA,08,46,E6,7C,56,A8,3F,E9,43,C9,7A,7D,6D,09,22,03,81,23,01,B6,70,DD,86,A0,41,4B,E4,FA,2C,57,CD,2B,A8,85,89,E8,33,36,0E,2C,5C,62,7E,7C,E5,09,B9,62,78,2B,A7,C8,2F,DE,D0,E5,CE,A9,80,52,BA,63,AF,AC,3F,78,70,8F,27,8E,34,E2,A3,92,90,6C,51,FC,68,04,55,82,AC,32,AA,73,B5,60,7C,58,18,0B,EA,37,ED,2B,16,DE,F0,4C,74,9A,85,1E,D8,A7,94,D8,74,2E,DF,BE,B6,B7,5F,3B,C6,59,04,D5,4F,18,E8,46,C7,6D,32,CA,0C,3F,9A,42,61,F8,D8,34,F3,01,04,51,B4,D4,70,90,27,02,ED,FB,81,07,6A,6C,99,D8,7C,A1,45,D9,D4,3F,3F,99,E2,11,FF,4F,98,C5,A6,38,81,0D,95,FB,4D,3F,A7,9A,59,D2,4D,FE,82,8F,15,46,7F,CB,C4,40,DE,AB,63,8E,5C,50,4A,98,0C,F0,C7,A9,1D,7D,F6,51,31,01,68,4D,83,76,73,79,FE,AB,FF,65,1E,95,26,E8,DC,04,DA,8C,AD,A6,5B,CF,3D,97,28,2E,AF,19,22,8A,00,7F,D2,3A,41,62,84,6C,F3,4C,BF,67,7A,74,BF,12,88,CA,D6,7D,99,FD,B3,B9,84,A8,1F,B9,7B,A9,43,AF,45,A2,7E,52,FD,39,6A,2F,62,46,B3,66,2D,48,6E,D0,C5,DE,0B,8E,7A,71,16,4B,D2,36,D0,A6,63,85,95,CC,41,F9,99,67,B9,28,4F,EF,48,81,E6,5D,8A,86,58,C0,4C,DD,78,F1,29,B6,83,56,D4,F6,B2,63,5B,76,6D,BB,99,EF,5F,B7,24,BD,B8,0D,31,89,CE,77,9F,CF,3D,75,88,00,9C,48,AE,9C,7F,F8,C5,A5,5B,19,5E,EB,F5,1D,16,2D,5F,A6,82,E4,19,F3,F2,CD,4D,45,44,57,D1,77,80,7D,6E,AE,88,BA,6D,62,59,59,C5,D7,1E,24,B8,44,0A,26,00,3C,0A,C2,55,B3,C6,3D,F7,E7,B2,41,92,58,26,97,F3,F9,22,42,59,35,BD,7F,ED,74,7F,32,AA,4B,7A,DA,83,5D,9B,21,20,96,02,B9,B7,62,DA,A5,5D,BD,4F,21,52,08,6F,56,7A,F9,34,B2,13,39,84,EF,C1,37,3C,B7,9A,46,BF,F5,A9,53,E3,5A,DC,CA,46,16,0D,42,B1,7B,3C,2A,2B,9A,6D,E3,E6,AE,1E,46,9F,0D,7C,93,AF,CF,B8,E1,66,AA,1F,59,AE,E5,DA,BC,FD,5D,C9,C6,27,D4,2C,04,86,9E,D0,27,82,31,D9,A0,0A,BE,CC,ED,E1,76,14,36,89,3C,58,21,4E,FF,AD,6D,8B,6B,70,B1,73,83,5E,0E,53,69,25,E4,36,AE,A6,9F,A5,8F,C8,36,AE,A8,35,6A,4C,90,39,D8,88,3C,1C,72,06,ED,97,9B,2B,9A,5B,B7,D8,19,58,6F,03,8C,23,DD,9E,A7,4F,0B,06,CC,EA,2D,23,3A,53,48,F1,19,64,C8,3E,64,75,27,77,F4,39,08,90,A0,DA,E4,54,7E,E3,17,53,43,DA,46,46,6D,54,4A,22,BD,63,7E,3A,66,2D,EC,36,CB,65,3C,DA,3B,5E,EA,8D,DE,62,DB,71,9A,B4,B6,D8,A9,C2,9F,47,57,86,05,04,D8,56,DC,0D,2D,ED,FD,69,8D,D2,74,E9,BD,95,51,7E,59,26,10,52,CC,3D,F2,94,6B,9F,74,9F,AD,9D,A9,66,83,0E,C0,F2,D7,8E,4F,F9,9A,A1,17,16,BE,4C,5B,83,45,99,3F,3B,50,71,45,78,A1,E6,8B,44,DF,3A,F2,C1,91,46,69,8E,C7,FB,7F,6D,37,C0,B4,12,54,49,89,28,0D,D0,51,78,AA,6A,4D,89,23,59,B5,5E,F1,51,FD,83,1B,5E,F4,B2,10,1D,25,32,C0,DA,12,3B,43,1C,1F,EF,97,E2,3E,FE,BC,05,65,B8,A8,69,B3,7E,D9,73,F6,B7,87,71,7C,B0,B1,5B,0B,3D,27,9F,8D,00,0D,5C,CA,C3,10,06,FD,A7,08,61,74,52,8D,CE,56,99,60,45,3A,37,55,A1,EC,EF,29,4D,B6,E9,04,02,18,5E,AF,DA,BC,46,62,EC,67,E0,A4,17,D4,63,85,1A,3E,8B,E6,A4,96,33,5F,80,BD,8F,D6,2C,53,25,34,9E,35,8B,BE,92,A4,D4,BF,8A,5A,21,FA,63,B6,4F,3C,9B,66,25,66,49,27,1F,58,E6,D8,7C,FD,13,6D,FC,85,4A,35,89,5E,02,87,30,41,37,B4,67,B6,CE,5F,44,B6,39,16,38,60,66,97,06,40,8C,8C,BB,1D,51,7E,C9,20,FD,A0,E3,06,1F,6F,D9,18,CC,CA,75,D7,1F,CE,3B,4E,00,5C,E7,D0,C6,84,16,6C,89,DC,D1,85,72,40,AA,7E,10,22,F0,60,1E,A3,6F,39,47,92,C2,CE,F1,93,F9,2B,0C,59,64,E9,41,47,B4,1D,6E,A9,A5,69,2B,CD,2B,DA,6C,F1,EB,E8,61,77,63,65,C9,5B,6B,24,9C,0B,9C,8C,FB,BE,F3,37,09,FE,42,4A,C2,83,27,09,06,27,E3,E5,89,B0,DA,EE,16,95,FA,13,6C,68,A1,49,BA,7B,C7,E9,D9,40,70,2A,0A,91,35,04,E5,33,9B,EE,95,B4,F7,1D,6B,04,71,6A,27,21,F5,FE,F3,1F,56,8A,C1,F8,94,46,E5,A2,E2,D8,24,7C,85,45,38,45,76,F7,C8,28,77,42,E4,59,C1,FB,97,64,2F,E7,BE,C3,31,48,A6,3B,45,19,4B,71,9A,15,89,7C,13,D6,5D,B5,63,9C,B7,8E,F9,87,F6,4E,3E,01,4E,87,65,C3,C5,C7,46,48,90,FC,F7,1C,AC,55,87,ED,59,07,D4,86,DE,8F,F6,AF,62,6E,A1,2D,92,ED,E5,04,DF,1C,35,F5,04,67,49,97,3B,1E,2D,1B,4C,3F,4C,15,DE,E4,18,9A,A2,39,13,C0,B5,DE,3E,9D,80,6F,DB,A1,6A,63,71,92,10,70,F7,40,46,1C,FC,D6,E8,0B,16,3B,A1,FE,DB,A0,A4,57,C8,9F,D5,F5,E5,32,49,EC,CC,ED,34,38,DB,55,45,E0,89,DF,36,66,81,26,E6,8E,ED,99,AD,4B,34,7E,57,26,F4,B8,A1,B1,3E,D8,5B,4F,6F,17,F8,5C,72,86,28,D1,73,B8,A9,C4,5B,DE,5B,82,9C,29,BA,CB,5E,17,07,78,6B,37,2A,9E,26,15,E3,E1,98,DB,BB,08,FB,8E,04,99,AE,A9,12,6E,5F,4C,A1,80,3F,C4,D6,7F,FE,70,55,A6,92,FB,31,1C,0D,D1,96,37,47,5F,2F,84,8A,10,8A,62,6E,20,5E,95,3E,D0,FF,B4,5A,E8,E5,5E,A4,E2,D6,F0,80,07,D8,47,00,B4,2E,82,CE,80,0F,E1,B4,72,65,94,31,67,C3,6A,9F,53,DE,42,D5,9F,F5,EF,1B,D2,1D,E4,68,7C,AD,17,32,EB,6F,F6,E1,3E,42,0A,12,85,36,86,D2,29,2D,37,AE,45,C9,0E,5B,77,F4,DF,E4,A2,6B,8C,B7,28,C3,1A,3F,10,7D,2B,7B,E5,D4,6C,6B,ED,20,84,6C,A0,70,6D,DB,42,24,15,90,CC,C7,F8,1B,87,73,94,A6,0F,89,7D,7E,6F,A4,96,55,0F,AE,F2,51,6F,20,FE,69,17,D9,ED,A1,90,91,6B,29,FF,D5,AC,89,09,F4,B7,66,F3,83,B7,66,A2,20,6C,74,7B,C2,E3,6E,FD,96,3A,4E,6D,E8,93,6C,FA,08,11,64,02,86,46,22,07,F2,E0,E7,24,77,56,A0,53,9C,BC,CB,6A,7E,D4,D5,17,FB,5F,D9,EA,98,95,23,47,0D,32,DA,0A,53,CD,23,FF,49,99,8C,5D,8D,76,EB,00,0F,1A,11,B3,30,6C,0B,39,A0,FF,C6,74,B1,04,6D,A0,CC,58,82,12,02,5C,4C,77,7F,D2,25,3F,75,45,5C,E1,0F,EE,1E,F5,BD,9A,FA,7E,2D,1D,2A,82,65,86,3D,8A,87,C2,31,5C,92,ED,EC,F5,A9,9D,29,D7,8D,2A,39,A1,15,22,D5,4D,9A,D5,7B,F8,1A,43,96,A9,04,6D,5C,00,92,FD,29,EB,EC,A7,35,0E,D9,7B,B8,F8,72,03,C4,F6,7F,82,5A,20,38,29,B5,05,B9,C8,BE,48,F9,74,AA,79,CA,EB,A3,38,58,6C,09,C7,D1,A2,B6,6E,DD,49,F0,16,C7,0C,D7,93,3D,CA,BF,4D,8E,8F,53,70,3C,51,B5,34,AD,E5,56,63,46,42,D6,F1,31,85,1A,FA,AE,15,EF,39,3F,B5,4B,0A,D6,F3,E5,30,AA,8C,42,6F,11,86,3A,07,96,6D,E0,CD,58,68,57,19,0B,E5,A2,5F,E1,EC,82,D3,BB,1D,8E,FC,AB,99,F0,4B,60,5E,B6,0E,C0,E9,A1,B5,32,EE,BA,8C,C9,7B,97,EC,92,36,21,BF,E6,43,CD,75,C5,21,19,ED,60,EB,51,B0,D0,D2,86,B4,D0,AA,17,00,1D,E6,9C,A7,EF,9B,57,DD,47,CA,F3,DE,59,3A,C0,17,16,36,22,C6,F2,49,76,4B,A4,1F,AA,D0,01,2E,37,20,75,E7,45,16,86,B1,DE,89,E4,E8,EC,6C,1A,6F,7B,1F,5F,E1,C1,5F,E0,22,02,40,BD,14,3B,29,75,4A,46,23,BF,E6,7C,A2,13,3E,2B,D0,3A,7B,18,42,86,53,59,73,0A,73,88,4C,CC,A5,63,5C,05,3C,26,A8,CB,EB,E5,4E,F9,33,D8,7D,D3,13,02,D7,6D,2E,46,BF,DC,B7,FC,6F,1C,55,0F,27,E3,79,52,17,38,EA,98,5A,06,1D,E2,47,7B,18,06,DB,35,CF,B5,E2,5F,2D,1B,4F,60,1E,05,C9,54,38,4A,5F,B3,31,50,17,59,8D,FD,D8,3E,73,55,F8,83,51,15,44,D9,8D,7D,75,6D,69,2E,8E,83,86,E3,58,A3,63,12,59,D8,0A,BF,87,3A,E0,DA,C3,B6,0B,65,45,7C,4A,D6,D5,3B,E5,C2,06,0A,03,B7,8E,19,C5,1C,13,47,E5,0B,6C,E5,90,01,37,71,A7,61,5A,85,D3,B7,90,AB,2C,53,3C,B4,C1,7E,E7,72,3A,30,04,1F,72,80,57,D2,CD,04,60,EF,C0,52,73,46,46,D8,BE,B4,7D,B2,23,16,9A,B2,2A,80,DA,93,88,BC,5C,EC,1E,8F,00,AB,EF,B3,8E,8F,4E,80,0F,2E,1D,F3,6C,4E,1B,D6,39,96,46,15,CC,FC,33,1B,F3,CE,2C,62,8B,05,40,4B,F6,9F,B1,BA,3E,19,5D,55,6A,A9,E3,4E,C1,F7,AB,DF,75,47,BC,83,37,4D,AA,C5,00,A9,82,54,25,B1,FF,E4,E4,4A,44,E9,FB,D6,92,6B,8F,40,A0,FE,59,95,C7,08,3A,F8,69,45,E9,C4,62,16,C7,27,17,3B,08,06,14,1A,BD,39,E9,E0,B7,78,B5,1D,03,57,A1,E0,EC,FF,C4,64,8D,06,9D,3B,10,4C,37,99,D4,FD,C3,3C,A8,5C,88,06,F7,75,92,2E,B4,FE,58,FC,A0,03,3F,EB,DF,4E,32,E0,17,B4,30,54,AF,E5,FA,19,FD,2C,2A,F3,E1,37,E1,94,C3,8C,37,E9,81,29,67,73,7F,66,70,E8,8E,A2,76,CE,FF,EB,10,A9,6C,6E,D4,20,14,1B,81,F2,B0,E6,CE,FA,6A,06,C0,3C,5E,F7,33,08,09,1B,D5,1F,0A,38,10,06,01,72,3B,10,16,02,AA,96,A7,DB,54,EC,C2,6D,9A,73,C4,01,FB,BD,75,5D,48,0F,46,B3,F2,45,EC,7E,FC,55,05,2C,DC,B0,1F,BC,A6,6B,C0,D6,DF,85,A9,E2,CA,70,D1,01,2C,ED,C9,CB,1D,D2,49,5E,74,D8,0B,BB,B3,50,C3,35,72,F0,16,89,12,AE,67,93,3D,7B,30,A9,8E,BA,F2,7C,16,8B,47,F2,FC,69,C4,DA,2E,4D,34,FE,0F,8A,03,F9,82,D6,30,44,94,63,D7,E2,CE,7B,32,CF,9A,C8,6E,4D,AE,95,CF,C7,72,72,81,B5,67,EE,1C,4D,38,44,71,E6,85,37,B7,50,B7,2D,CA,7D,22,E7,27,5B,78,50,3B,3F,C1,36,F4,5D,C8,C4,58,E6,9B,A5,8D,81,C1,9D,1C,C5,36,96,82,59,D9,E4,D2,E2,EE,99,89,37,B8,D2,F4,5C,B1,4C,12,65,B2,5F,0A,06,27,44,7E,C6,A9,36,D5,BF,73,47,F3,29,84,77,D9,12,9A,24,24,59,6E,B7,16,B4,4E,B8,6E,12,BC,79,0B,F4,C4,96,0E,87,30,B7,98,57,37,B4,0E,49,5C,F6,9E,54,40,9D,2C,EA,15,3F,8D,6A,92,98,73,6E,A2,33,9B,13,A3,74,19,C7,C9,AB,76,07,51,EF,67,F7,3D,B6,AE,1A,A3,98,D6,E0,D6,FD,24,09,10,E4,F3,57,D9,2A,EB,4B,23,75,D5,E6,78,D6,82,66,29,96,2B,1C,2B,33,61,64,C6,95,A3,1F,02,20,23,4D,7A,2F,D4,BB,83,76,89,A1,C9,04,94,DB,39,9E,53,62,AE,3A,D1,3E,D5,FA,DA,9A,BE,84,7D,ED,42,8E,C2,63,4C,7D,60,8F,36,3E,3B,4B,ED,4A,E5,B5,12,65,0F,88,25,C3,80,06,A0,53,00,68,BD,27,39,E4,42,44,6D,E0,BC,B9,A2,C2,BC,3D,E8,66,F8,D5,F0,BC,1B,03,1B,D1,BF,D3,C7,29,77,9A,D6,09,8B,45,ED,C4,C3,41,DD,92,FC,74,EC,6E,76,63,77,52,B7,2A,40,04,27,07,30,9C,38,92,E2,5F,C2,B8,08,0D,50,0F,A6,19,40,08,2A,EF,36,3E,D0,AD,03,D7,65,1F,BC,2A,53,17,85,6B,33,F5,66,2A,55,E7,88,92,D1,B3,A6,88,08,0A,4E,A1,59,67,1C,39,A2,11,DA,0D,58,74,60,B6,B2,62,3A,85,6B,83,FA,AA,BF,2B,48,D6,0D,F8,75,BB,AC,4B,86,E3,59,0B,62,47,AE,EC,EA,08,85,6C,C7,A2,63,37,72,49,1D,51,48,37,76,38,68,11,85,60,CE,3E,9B,00,8B,1F,90,6A,92,EC,28,05,67,BC,70,7C,24,92,04,C3,14,4A,A2,F6,21,7B,F8,46,A9,45,26,8A,67,BF,58,73,F1,C8,2F,35,EB,E2,8A,3E,35,0D,27,BA,60,F9,D4,2C,76,C4,BB,9A,10,CB,6C,0A,89,52,6F,EA,23,5F,4B,BF,64,B2,F5,FE,AA,4F,3C,4B,03,E9,DB,7B,E5,B2,13,04,68,80,50,AE,6C,C4,53,4C,D6,C5,39,04,2B,5B,95,96,13,C8,D9,80,F7,DD,60,8B,06,DF,43,3D,AB,58,8E,8B,90,A8,B8,7B,BA,14,B3,94,7F,97,9F,98,21,6F,15,51,AF,D3,83,DF,B7,86,46,FE,7A,07,D2,FE,CF,C6,90,26,12,5A,66,60,28,7C,33,2A,ED,49,5A,DF,2C,0E,0C,62,BC,40,93,49,F9,23,27,31,16,C6,CE,85,35,23,82,44,DF,65,E6,B7,87,51,57,6F,9E,1B,FD,41,9F,76,EA,66,CB,62,E2,CB,4C,07,22,84,74,DE,30,58,18,B5,62,9A,BC,E0,F5,4A,16,4A,BD,51,FE,BE,3E,A6,59,91,85,60,6B,EB,F0,8E,8A,EC,3F,52,6A,19,84,7D,BF,74,EF,7D,96,9C,AD,B7,DA,06,8B,C5,3E,78,1B,FA,A2,8A,37,83,34,E7,53,BC,64,67,11,49,BE,5E,B1,55,8F,10,9F,B5,02,27,17,F6,95,31,4A,33,12,B3,F2,EE,5A,48,52,90,D3,CA,2D,B0,F6,8C,BD,0C,75,47,C6,71,08,32,37,6F,3D,08,BF,3B,DC,48,02,C5,66,1B,A8,F6,66,DA,69,46,40,00,5A,A7,D6,4C,5A,F6,0C,71,67,5D,FD,18,4D,6A,23,F5,74,0A,A8,02,B7,69,29,D4,A2,45,56,39,A6,DF,53,6A,B6,D3,AD,FD,AA,8F,13,1D,4A,B0,B5,2F,9A,25,7D,75,93,9E,99,2D,C9,9F,AE,FE,04,C2,C5,D4,87,A8,70,5A,A9,A7,D7,5C,DD,BC,A5,86,72,10,3C,CC,AA,3B,E5,F6,39,57,EA,17,63,4E,1B,E3,19,B4,C3,9A,28,9D,27,6A,26,C4,DD,55,C0,17,03,91,54,70,B1,0A,A9,75,B5,CE,35,E2,B7,DA,8F,D8,5F,31,29,05,DE,E9,47,32,5F,43,79,59,D5,4C,B0,11,A4,67,77,0C,5C,BA,0F,B8,DA,AA,B3,8C,56,A0,7A,91,83,74,43,3F,9F,43,D7,A5,21,62,1E,76,24,37,4F,86,B2,3C,43,2A,AF,8E,40,92,09,A3,48,B3,93,C0,D5,C7,7C,FC,55,B8,EF,E9,D0,7A,9C,88,B9,1D,38,B7,A6,BF,71,9E,78,0D,C0,9C,2C,3E,85,BB,57,EB,4A,EB,63,38,C8,3C,EF,DF,33,FC,AD,15,92,B7,69,C9,F7,C0,A8,77,3C,66,03,C7,5E,C5,8C,A5,B7,CA,EB,17,66,93,AF,AF,98,36,34,AA,76,6F,FA,40,42,58,33,47,1C,F4,A5,49,8B,99,B2,E7,AA,25,AA,F5,99,F4,C7,BC,68,96,12,FE,7B,14,8E,F9,D8,C4,E4,5B,9C,D2,B2,3A,34,8B,EF,92,08,24,F7,02,F7,F1,4E,F3,D2,CD,EA,F2,6B,CA,A5,A0,BE,57,4A,45,DB,54,9F,DA,5E,57,6F,21,70,83,F7,49,C9,86,49,2B,72,BF,E7,B2,CE,60,8A,74,8B,5D,65,19,82,8F,6A,1B,B3,07,61,A1,1C,36,10,17,25,45,BA,E7,D1,41,2D,91,C0,77,8C,57,19,C7,FB,DF,71,04,C1,8E,09,3C,22,B7,68,7D,73,15,AB,F6,28,69,06,0B,AA,82,F0,69,8F,50,9B,F4,9E,D0,7B,66,F8,8F,CE,81,33,F6,B8,DB,AF,72,29,39,A6,24,48,63,87,EA,C7,ED,FF,10,11,E2,5B,08,2B,19,FB,08,3C,57,F1,24,B7,8C,9D,E7,73,DE,24,26,15,63,7C,21,86,13,5C,7E,11,9A,DD,00,50,52,56,5C,1A,B4,D2,21,82,83,2C,91,56,56,F2,16,F4,7E,01,65,EB,3C,6F,FE,74,73,3B,EF,BF,12,18,E0,77,96,44,8F,40,8F,6C,17,57,AB,9E,E5,8C,0C,20,39,98,AB,03,2B,D2,C5,AE,B0,3F,52,7B,83,EB,AC,0F,1C,0A,F7,EB,10,B1,5E,61,74,87,FC,9B,B3,D9,A1,B8,35,EB,5C,E1,53,0B,D4,B9,15,F7,2D,9F,2D,49,C8,4C,E3,2C,A3,16,70,EB,CE,74,81,D1,19,27,3A,4A,B4,7E,6F,23,DD,1B,94,42,05,4A,25,D4,84,00,81,9C,15,13,A5,BD,28,2E,A3,D6,8F,B8,52,FA,83,4D,EA,48,41,42,B9,6D,26,87,8A,5C,B2,DC,A2,DA,78,73,4B,70,68,08,6C,7D,94,FB,85,D9,BE,42,7C,E4,D1,7D,E8,70,C4,DA,60,CC,C2,47,00,62,69,4F,87,CF,A2,B8,78,8C,4B,3D,66,BD,E6,24,9C,2B,82,92,21,63,B2,6C,53,BE,3F,EF,69,2F,BF,00,92,51,54,10,1D,11,53,19,9D,A2,78,DE,3F,49,BE,0D,33,AC,CB,E4,E2,B5,3D,E0,68,F9,1E,89,37,6B,6A,F2,65,28,CC,79,A6,DF,09,90,B3,B3,7D,A9,1C,61,18,6B,F9,02,D8,E9,80,E9,72,AD,FB,C3,6C,52,24,C2,7D,38,83,14,D7,4A,B8,5F,C9,CF,00,68,8E,67,C9,4F,E1,94,C5,3F,83,AB,54,01,27,73,F5,CB,14,53,4D,EC,D2,F9,64,02,64,88,A6,DD,EC,A2,F3,12,F7,9E,3C,C5,AB,73,23,34,A9,1D,13,C1,11,14,56,FB,E8,BD,C6,01,EB,60,CF,39,E6,A9,23,6A,1F,F5,A5,44,15,CA,89,58,11,A3,8E,D2,9F,0C,50,3E,DC,86,06,09,EA,82,65,6E,38,F9,0C,5C,18,9B,40,61,E6,19,FF,69,86,E1,75,C4,3F,C7,95,2D,0B,6F,12,34,39,40,46,6E,4C,7E,65,31,B0,31,84,51,37,0B,ED,80,AC,F1,1F,F9,63,BD,7E,90,CE,AA,16,A4,80,73,8C,D5,80,18,A4,84,05,98,54,F1,4A,9E,BE,73,3B,BD,65,CF,A7,39,17,2C,B3,9B,DD,FD,D2,CE,4E,E1,45,90,25,33,3D,94,63,06,85,60,A6,CA,AF,48,60,93,AD,1F,83,DE,AE,FC,A2,B3,67,7B,B5,FD,FD,61,AC,93,94,93,BB,2F,05,2A,23,38,07,70,DF,0F,CC,69,BE,66,F8,DA,6D,DD,1C,65,83,65,97,A8,88,4D,FF,BF,AD,A2,8C,F0,69,2E,21,BD,17,BD,21,DA,73,25,BA,E0,BA,E7,1D,10,CB,ED,EA,C9,87,7A,28,83,47,BA,3A,5A,4E,BB,D7,F8,C1,94,F1,FE,7A,F0,99,37,11,4E,79,44,D9,A6,F2,68,B4,6F,CB,24,C9,EF,2D,9C,23,E4,F2,C1,B4,C9,4E,71,BF,C0,E5,AB,A3,FA,E2,70,51,67,0F,A0,50,DB,2D,59,24,5C,BF,57,39,83,1A,C9,BA,44,83,8F,EB,92,C6,09,63,21,48,C1,66,F1,EC,0B,6C,1C,1C,C5,97,E1,F7,3A,95,90,B2,F3,4C,2C,6B,9A,B1,CB,17,B5,76,FA,DD,41,B8,CD,22,5F,AB,7B,59,3B,BD,BD,63,60,06,B2,7C,AF,BC,CD,9B,C9,A2,5E,4A,19,48,1F,BD,82,82,4F,B4,2A,AB,D7,A5,77,9F,82,C6,93,6E,D3,5A,77,3B,AE,8D,72,D2,09,F8,3A,EF,59,81,CF,BD,C6,5A,5F,DE,EE,97,0E,58,12,3E,43,FA,86,77,BA,4B,F4,48,E7,C3,57,35,74,60,5C,1E,5E,4E,EF,35,7A,6C,71,EF,AF,7E,DC,4B,26,95,56,6A,36,15,72,FA,D2,3F,5E,B2,62,6C,F1,F1,79,24,0D,5D,0C,A5,4A,A6,96,61,C5,A9,3A,8C,4C,DD,0A,81,D4,D0,82,97,E8,AE,D5,C5,27,88,3C,3C,D8,12,9E,77,2D,4F,D8,A4,00,43,E4,72,81,12,F5,33,0E,18,13,4F,AC,9F,93,D6,BB,A7,E8,FA,24,6F,CA,4F,DA,AA,EC,D1,8D,9E,B1,BC,38,F1,A4,99,C5,D0,36,D9,D6,C0,C8,44,91,96,1A,1B,9E,F8,1E,25,43,3C,18,EC,4D,9F,A5,E0,5D,72,5E,87,BF,9A,AF,81,8B,8E,72,7A,4C,99,1E,EB,41,1D,48,B2,D8,08,56,A1,EF,14,22,80,8E,4B,6E,90,5F,E1,B1,A7,59,7B,4F,0E,87,0B,C7,AA,3D,04,F4,6D,E1,A9,05,D0,5D,67,2F,D4,EC,D3,65,AE,3B,CE,8F,9E,3D,75,4F,CB,D4,DE,69,11,10,0F,26,4B,E5,22,C7,CE,EE,19,43,B3,6F,1C,AE,A2,41,CC,36,A6,6E,4D,DD,19,CD,78,A3,56,81,CF,BD,C2,90,DE,10,C7,68,AA,44,AE,46,BB,ED,6C,3E,6E,69,50,9A,6A,29,02,DC,4E,77,31,E9,0E,1E,5A,27,01,80,69,80,04,C8,4F,87,47,7A,61,D8,26,54,6D,4A,A9,40,F6,E9,13,00,3F,EF,40,5D,CA,AA,70,43,B1,AF,29,EB,25,B8,8E,B9,7B,4E,42,41,8F,75,14,BC,98,3E,36,FE,6C,02,55,C4,E8,2A,CF,F8,39,62,11,00,88,B1,6D,0F,40,1D,F0,F6,D0,99,13,8F,4C,DB,4E,8C,FA,CC,E1,80,F8,F9,50,78,04,C0,36,A0,FD,52,F8,FF,C8,62,24,29,7D,27,37,F9,5F,8D,6E,A2,F6,DD,28,C5,BA,6C,E4,E9,9A,89,42,FF,CC,20,F8,6F,17,5E,C7,70,06,47,A1,F7,9D,97,AA,31,0B,A6,72,35,55,ED,71,0F,A3,28,41,02,DE,6D,88,E4,43,B0,E8,78,D0,03,56,88,26,4A,BD,A2,EB,73,28,E0,92,14,D6,FA,D7,CD,60,03,C0,6D,F8,05,1B,50,E9,B9,02,BA,9D,F4,78,28,B1,32,2B,31,4C,36,56,7B,9F,03,63,9F,7B,66,06,5B,AC,8B,13,F5,4F,C2,54,D0,99,D7,10,86,94,7C,50,E5,05,60,AD,B4,54,FA,2E,8E,12,9F,EA,D2,8C,64,81,91,DC,D3,30,66,D1,0A,EA,F3,A6,F2,EF,16,DC,A0,E0,3C,74,CB,2F,B1,55,EC,EA,5F,EB,D6,A0,5A,02,23,A1,5D,88,62,4B,D3,7C,83,BD,6D,D5,70,75,7D,0D,D6,39,0F,1C,15,72,4A,02,C0,4B,10,B6,AC,2E,03,06,1A,49,D0,58,D8,AD,98,BE,B6,05,61,40,07,CA,A6,B5,49,B1,0A,C9,59,48,0B,3B,E6,A7,23,0D,37,4E,80,F7,AC,66,92,E7,7D,86,56,88,32,40,A8,16,18,EE,BB,52,94,FB,06,7A,62,79,DF,04,26,DC,DB,B5,60,49,58,D4,00,F5,B5,E6,6C,70,E7,91,94,2D,60,40,9F,F9,B9,4F,F8,B8,CA,72,FF,12,7C,DE,4D,2D,E7,95,1F,78,FC,E2,9C,66,45,24,D9,6B,7D,12,65,7A,B5,21,72,EC,5A,44,0C,CB,C2,09,2A,95,74,30,CD,CD,46,16,71,00,C7,02,FF,88,76,E0,BC,97,96,7A,22,DF,8D,C9,7A,25,3A,61,54,CF,9F,CF,38,16,FF,1A,76,59,05,B7,A0,19,4F,84,DB,C8,09,E6,D9,EE,BB,AC,F3,D9,49,84,C3,9D,2F,7C,21,66,F5,F7,97,BA,63,05,1C,34,54,AA,AF,67,D7,CB,30,F3,7C,83,7C,35,4C,61,F4,73,7A,9C,98,3E,52,70,9A,EC,EE,2A,65,E6,2A,0F,16,AF,BF,AF,E1,CA,6A,A3,53,AE,9A,8F,91,96,94,C0,00,A0,7A,5B,03,AA,89,35,BC,ED,64,5B,FF,1A,F3,E5,1F,B3,92,2B,00,19,17,16,26,3B,79,0A,41,28,B4,46,17,29,9F,6D,6F,06,25,B1,98,92,DC,AA,B1,54,06,05,B3,9A,91,98,73,68,B4,71,15,C7,FF,63,70,07,F1,19,40,C3,5B,41,E5,86,11,D9,47,66,D6,99,30,2A,96,08,83,A4,0C,ED,1B,DF,8C,7E,E2,F4,A0,09,66,07,17,29,FB,2F,FA,98,70,D4,EF,74,89,37,18,A8,46,30,BA,BB,F9,99,E7,09,52,C7,50,78,32,46,8A,85,08,8F,A2,90,EA,CE,43,CF,8D,01,6D,A8,78,C1,54,42,9E,3A,06,A3,3E,36,D2,E0,B6,E1,71,9B,D0,8B,D1,70,45,A3,63,E0,71,B5,4F,D8,13,B1,61,D8,36,47,89,DA,97,EF,A7,8F,F4,B3,43,9C,54,03,F8,3D,C4,EB,DC,CE,21,27,F5,B8,79,EC,F7,2E,83,54,41,AE,15,E1,14,23,7B,B9,99,FA,EA,60,C6,59,0F,C3,25,31,2B,43,E2,E6,94,A2,BF,B1,9F,97,93,BB,21,D7,E1,C8,F7,A3,26,CF,F3,8B,9D,26,60,B0,24,60,02,1C,5C,86,B2,2F,B6,A6,AA,F2,92,8F,D5,BD,CA,C4,2A,63,BE,78,65,56,91,F0,F6,E9,6B,53,22,9D,C2,F1,BF,CA,69,A8,AC,4E,C7,29,B0,D4,D5,52,33,5B,FE,A4,F1,BC,0B,13,CB,F4,8A,76,5B,21,88,15,80,37,0E,BF,6E,EB,E0,72,22,70,D6,BD,47,EA,55,8F,1F,F0,BD,DE,7B,5F,6C,FA,37,7E,1D,16,44,2F,6F,BA,A3,BB,39,CF,CD,F3,21,7F,CF,E6,73,BC,BC,24,D2,38,D0,60,4A,4C,B1,6F,FB,2F,0D,58,0A,04,3B,47,ED,F4,64,39,BE,91,F4,BF,DA,FB,50,CF,82,95,F4,59,D1,22,68,F9,49,54,07,AC,ED,76,D9,D4,1B,65,C5,F0,33,17,8C,E7,95,18,B4,FF,ED,C2,5C,4B,F3,29,0C,BC,A2,89,A1,5F,45,B0,4D,B6,83,A4,DA,C7,DF,CD,E6,80,5A,5D,05,41,22,E8,B2,CC,10,13,5A,BD,92,3D,C6,48,78,76,CF,17,95,8B,09,C4,E8,25,31,BF,63,EF,B6,E9,EB,40,1C,1E,3D,D6,54,D2,07,B7,BC,45,CE,AA,F5,6B,F1,51,B9,E8,18,7D,43,D1,B9,52,DB,9E,4E,9B,C6,26,DF,67,E5,61,F6,F5,BD,3F,52,5D,37,83,E1,67,89,24,85,22,70,BE,B8,A0,CF,9D,2A,14,16,70,E8,68,2F,73,20,57,47,07,A3,E7,66,BE,87,23,43,78,35,FE,44,61,33,4F,06,00,11,E6,5A,6B,2D,DF,56,6F,C3,CA,4E,4C,70,6B,90,40,4E,11,B9,A0,AE,AF,E5,EE,21,9E,DD,A3,47,EC,85,99,C2,17,25,AD,5E,8B,D5,9B,F6,69,E6,85,BF,ED,B1,2F,BD,62,82,D8,5A,04,6E,C9,B1,9C,A6,39,B9,4E,E7,E3,E7,CD,00,15,AC,EB,63,10,05,62,F4,44,AF,D9,BA,AE,1F,18,F2,0C,59,DC,E9,98,80,F5,C7,BB,55,9C,C5,F6,2E,96,34,39,9B,C2,BF,77,27,68,99,35,A6,1A,57,FA,7E,AA,1F,8F,DD,B1,74,B9,6F,2A,DF,46,4A,34,89,F9,72,8F,0D,CA,F9,78,9C,C8,44,92,CC,F6,B9,0E,51,A0,2F,1E,86,4A,AB,6E,0E,42,37,1A,43,B8,88,7C,47,44,15,9A,F0,82,50,8E,56,59,0E,9A,AE,7A,71,E2,C9,FB,B7,3F,51,FB,65,C8,B5,71,BF,32,8B,2C,9A,67,6C,BA,3A,EA,40,37,92,B4,39,4A,AA,06,6D,52,21,C4,A5,06,BE,0F,B4,60,5B,22,61,D9,1A,3F,5E,EB,5B,44,F2,2B,88,DB,77,4B,EE,FE,FE,4D,63,9E,77,A8,AD,62,B7,07,61,A5,97,00,69,FE,1B,A1,A8,87,DF,5F,8D,80,D8,D5,67,9D,28,4E,FC,4A,0B,A3,C8,04,BA,CA,DA,AF,C5,3A,96,67,10,16,A5,EA,D2,80,81,97,E9,20,B5,0C,F1,ED,1C,FF,75,51,FC,AD,EE,5F,CB,90,25,70,3C,EE,96,BF,14,2B,2C,52,01,D2,44,29,80,ED,57,19,72,D1,42,F2,0E,0D,3C,EF,B8,7A,A7,92,3F,92,FB,61,07,78,23,D4,A7,3F,BF,16,EA,30,DA,5C,D3,10,4B,4D,1F,5E,A1,FC,B6,E4,7D,E0,48,AD,15,63,60,5F,89,FA,AE,CA,DB,E6,B4,18,63,A3,E9,75,A4,E7,3D,10,0A,28,3D,4D,2A,E3,77,6D,3C,36,22,C3,87,E5,2B,1A,93,31,93,61,CD,98,3A,EE,BE,E0,2A,4F,79,C1,7F,E6,81,19,7F,B0,34,99,8D,E6,33,B4,04,F9,D2,B4,41,01,CF,80,99,BA,76,E5,55,F8,67,5A,F9,40,76,2B,5E,5C,A0,21,B7,C2,CA,EC,2C,43,25,93,3F,E1,FE,B7,66,CC,E5,02,2F,40,B2,57,C5,7A,D7,86,45,52,E9,75,5F,00,3E,DD,36,8F,B2,CD,DC,09,27,7D,91,20,F9,46,E5,45,08,B3,44,C1,BD,B9,D5,EC,AC,DB,89,64,C4,42,E6,82,0F,54,5D,2D,0C,F8,F0,B9,CD,FC,23,12,91,3D,70,D5,86,FB,7B,15,13,4C,20,CA,F7,B5,42,2A,20,32,D3,B7,B6,7D,1C,11,DC,15,56,29,D3,A8,D6,6D,A2,46,02,11,04,FE,3B,97,FF,66,CF,68,EE,4C,85,C8,BD,61,78,32,0E,9E,67,00,43,68,B8,DA,68,C1,EB,91,72,62,AD,33,57,0E,20,60,F5,23,D3,26,67,94 -linearMatrices_inv = E4,46,AB,6E,4A,3C,6A,14,95,79,B4,BF,5B,2E,F1,28,EC,DA,9F,4E,0C,D2,3D,7C,A7,53,03,D9,0F,7C,B0,94,06,BA,B0,84,50,1C,FA,2E,A8,63,3F,57,6F,16,C9,22,04,AB,AA,55,9A,4D,79,49,F7,C5,2D,61,C9,BD,DD,CE,C1,DF,58,56,63,B4,27,E4,57,4E,27,A2,C0,7A,64,B4,8C,C0,D2,02,5B,B6,D7,8C,37,03,6C,DF,30,A3,C5,D4,C4,10,F3,A9,9C,95,B9,21,93,DA,1E,00,4C,5D,01,C7,D0,00,2D,49,8B,01,6B,7F,EB,03,83,D0,D2,9A,CC,70,AE,C5,05,72,62,F7,48,3A,07,6C,23,E3,B6,14,14,A1,2E,8F,15,D8,AF,19,7A,FF,88,C3,F5,4F,5F,D9,75,31,10,30,48,08,A5,16,CF,E8,78,54,42,D6,6D,E3,52,F0,32,4B,C5,E4,90,54,C9,F4,94,A1,BF,BF,D2,04,03,1B,84,51,4B,5D,2D,53,76,66,CE,51,70,AC,AC,FA,FB,DE,C2,D5,EF,83,3D,8F,31,4D,2E,3C,2B,CC,49,5F,C7,B9,92,C0,1B,E9,91,BB,26,BE,FD,6C,A0,8B,C0,90,0F,F0,1F,C0,C4,8E,CE,18,18,D0,B3,5B,91,17,DD,C3,C7,FB,EC,5E,43,6C,1E,3B,6E,DC,3C,A3,64,EC,4C,44,12,B9,B5,99,51,85,B0,B3,3F,B9,4F,1C,94,18,22,B1,0C,7B,BD,11,76,15,28,4D,A6,17,5C,1E,44,CA,19,90,3C,E2,F1,1E,D8,BB,7C,77,FE,61,AE,49,6C,B4,DE,76,EB,10,99,4D,F1,93,CC,C6,32,B4,2E,D6,CA,88,3F,06,F2,CB,D2,83,0F,02,E9,E2,31,A4,A2,B8,5A,46,2F,75,02,D3,CA,B4,5C,B7,F7,BF,FD,23,AD,F4,2F,43,34,F2,EB,28,F0,CF,B5,31,8D,99,41,D0,EC,FD,27,63,76,C5,09,68,A2,45,E9,B8,7F,90,15,CA,49,99,2E,08,24,F1,A3,91,A3,B3,C1,59,41,38,27,5B,C7,F5,88,8D,9B,A3,33,CB,F5,59,78,69,1B,86,DA,EB,C9,21,67,1C,C2,36,BC,C9,8B,B2,31,1D,90,B6,24,A3,CD,FF,E5,7D,21,89,F9,46,19,5E,6E,C4,DD,C8,EB,7C,EB,90,E3,D3,97,86,3F,EC,91,61,4A,F6,13,C5,97,22,A7,1E,E4,97,88,1D,74,40,8B,0E,B3,6E,E7,83,42,3D,9A,42,B6,37,26,2A,B2,96,1A,68,6A,5D,4C,39,1C,17,93,B5,53,7E,09,95,4D,41,53,00,0C,B8,85,4A,1D,4F,E8,2A,30,68,DC,E4,C2,4E,E8,B5,F1,9E,02,A7,45,16,73,20,C3,C1,83,54,30,B5,F6,36,D1,B2,23,24,38,4C,38,37,68,C0,23,90,70,D9,E4,24,FF,2A,79,8A,5B,FC,17,AB,4E,83,95,F3,C5,D7,F1,5B,8B,F9,B4,C6,0A,1E,9C,17,6C,E4,63,BB,3F,83,88,2F,20,65,CF,41,74,56,0F,57,20,1C,EB,0D,F2,56,49,41,5E,E5,34,10,DF,09,0D,65,9F,17,23,3D,8F,B4,20,B7,06,A2,CB,85,7C,D5,1F,6C,1F,39,81,A0,FF,67,EB,3D,6F,8D,E9,8D,BD,EE,90,CC,71,AB,5C,8A,22,CC,E5,77,A9,E5,88,76,2F,8B,1C,2B,D9,FB,2E,66,6A,61,0C,0B,F3,E4,F5,DB,3C,50,8D,D5,EB,1A,15,5B,CC,A2,AC,81,FD,D3,52,9D,B0,A2,22,F7,59,2E,59,3C,12,62,AA,D6,96,A2,10,3C,70,DA,68,5A,D7,12,82,AF,3F,70,91,7B,AB,00,E0,7E,C0,8C,01,7D,3D,A3,7F,F9,92,E2,5C,28,D3,EA,EF,1A,91,16,BA,13,CE,70,45,26,F4,5D,90,E2,14,BD,86,3B,3A,64,0A,A6,46,B6,94,CC,02,C8,40,80,72,C5,EE,8D,4B,AF,DD,D2,97,FB,48,F7,D4,05,AC,95,3B,76,2E,65,5B,D5,18,E2,93,75,DD,C8,89,9C,99,71,D2,26,0E,46,1F,80,27,CA,4F,C5,A8,32,F0,24,AF,38,08,71,A6,3B,59,51,87,D1,C9,B6,46,37,2A,20,88,F4,AD,F6,F2,E7,56,9D,89,97,36,41,37,BD,CD,53,2C,3A,E3,D6,F5,1A,05,E6,4A,C7,C8,4C,21,63,BD,AF,54,2F,81,3A,DD,C9,FD,C8,71,43,C6,ED,1D,8C,28,63,79,E3,E2,F5,C1,DA,D4,2E,FC,D0,94,8D,BD,78,37,22,88,71,56,CC,1D,0B,F5,37,6C,71,07,19,46,C2,C5,E2,36,01,E1,56,BB,51,62,57,94,4E,B4,DF,EB,4C,3A,34,5B,D7,FC,9C,B0,E3,88,F9,9F,05,E2,0F,BA,18,7E,9D,DE,7F,BB,EA,81,ED,90,D6,F3,1C,57,38,65,98,2A,49,4F,32,82,85,F2,59,55,B5,AE,A2,98,50,59,92,43,E2,9F,7C,8D,AC,58,65,D4,77,73,7D,31,14,1D,D4,C5,67,64,57,D1,F0,D2,1A,AC,70,5E,48,03,3D,25,CE,55,3A,A6,00,23,EE,62,61,B9,77,DE,46,2F,B4,1E,61,C2,B0,CF,C6,FD,DE,8C,45,92,D4,E9,45,1D,7D,08,14,9A,AD,21,69,06,A7,01,9B,B4,CA,51,5C,5A,75,78,29,AD,4E,61,87,37,32,6E,E6,D8,BE,FA,88,62,B9,A5,02,81,22,06,21,C3,C9,E4,AD,9B,A0,F0,F2,73,62,AC,58,DB,A7,36,79,88,A5,09,49,99,B4,4A,FB,53,45,61,B4,FE,87,0B,68,A8,F0,A9,1A,B9,36,D2,E9,8D,78,6E,CC,39,BD,F4,53,CE,1D,E8,DF,A6,A6,90,93,AC,3D,A3,20,64,4E,04,28,25,8D,66,B5,E2,D3,ED,BE,07,9D,8F,CE,7C,DD,F6,F7,88,4F,CD,CC,F8,40,46,31,4A,CE,79,19,C1,69,9D,30,2A,88,82,B8,D4,0E,77,60,F7,00,52,51,51,03,34,A6,44,35,FB,A5,56,C3,30,6B,2D,6A,9F,99,61,5A,B8,7E,8B,89,69,73,9D,DA,F1,F4,1C,A0,26,B4,16,4B,9E,04,85,F8,87,C5,D2,68,2F,38,BB,59,1F,C5,6E,1B,91,42,FD,59,EC,EC,71,72,A9,6E,47,71,67,FA,A7,0F,03,C8,FA,14,E6,75,CD,B7,03,E1,0C,A4,8E,2C,EC,4F,40,E7,6A,17,A3,02,A9,90,0A,96,96,A1,97,7B,07,12,DC,9F,E7,EE,FF,FB,03,66,97,42,E9,FB,E9,2E,8C,3A,37,32,FD,84,1B,57,4D,20,43,3D,FD,37,99,AA,75,41,18,72,2B,02,93,81,98,21,A4,21,D1,F9,71,96,0A,05,07,25,02,F2,22,CF,74,E6,E4,A2,88,99,6E,84,B1,94,1B,F5,85,49,5F,E5,3F,2F,93,4D,F1,CF,87,B5,D6,3F,00,E2,C9,D0,BA,BA,B1,16,C4,08,3B,3D,D4,5B,3E,F1,E7,35,00,DD,7F,2C,E7,DE,FC,90,F9,64,73,CC,47,DE,45,3E,98,A8,F1,E4,23,51,86,A2,8F,AE,DC,BF,1F,86,7C,F1,0B,43,88,21,58,C6,9D,D8,DB,D9,6D,86,8F,3F,70,9F,3F,AF,AD,06,90,86,6D,59,72,C3,45,EB,C5,42,9E,AA,FD,C9,6C,19,02,0C,91,86,E9,A6,59,E8,7E,41,E0,C3,EC,45,8B,71,96,AC,BC,0B,DB,0E,DF,07,80,F8,1E,8A,A9,42,EA,7C,4F,C3,B8,90,BA,79,66,3B,99,0A,9B,E6,0C,2E,41,86,98,57,B0,7A,C2,EC,86,45,9A,AE,3E,22,32,90,4B,43,2C,0B,DC,B9,B8,9D,EC,AC,9D,9A,4C,C7,CB,53,E8,78,3A,D9,70,43,6D,8B,BF,F3,10,32,14,15,6F,51,3B,07,58,A6,54,72,D4,27,42,C3,2C,F5,24,70,ED,7A,1B,F6,49,BD,9E,43,53,27,97,F9,FB,B7,5C,D3,4F,C2,27,99,59,C7,F0,DF,EE,6D,11,61,52,14,41,7C,0D,AB,5A,EA,E8,DE,9E,76,61,5B,63,CE,3B,9F,91,32,33,F4,C3,9F,C7,C7,8D,FF,CB,E6,02,9A,E5,8A,90,0A,F9,9A,6B,6D,04,61,8C,D2,08,D5,08,A5,D9,2B,F4,49,99,A9,47,37,39,62,61,3E,C2,B9,8C,44,BE,AB,E1,45,02,C9,A1,2F,92,E3,A9,F9,16,02,FF,10,98,24,CA,5E,AE,81,94,BD,02,90,23,D5,B6,D5,E7,63,38,D8,AD,C7,A6,FF,B8,91,2D,B6,16,C8,7A,E1,8D,F6,BC,99,AB,61,49,8D,F3,9B,25,CB,3A,20,A3,46,A0,BE,D7,0F,E1,8C,26,D8,B7,1B,9F,10,9C,6A,98,0A,A9,2D,96,FC,FE,3A,FB,C8,90,40,5C,77,2C,17,60,02,ED,82,D2,74,C2,11,89,B1,AE,90,2B,16,1E,EB,0D,B9,EA,C5,F7,B8,64,08,76,B0,78,5E,3E,76,EC,57,78,A4,F1,D7,31,58,D6,C2,34,19,60,93,27,B7,21,B4,EC,42,52,3E,47,CF,D5,2A,CB,DC,81,32,13,D6,2C,7A,E8,BD,9F,EF,0E,03,23,59,D5,CB,41,A5,3B,8A,25,2F,30,93,A3,0A,35,EF,9E,D7,A6,A7,F4,41,C5,65,CD,CD,16,7C,7D,2A,D9,33,9A,9C,B8,F6,F4,45,58,16,6C,9A,8F,7B,16,E4,EB,5E,00,62,CE,71,C5,04,B5,FE,EA,77,5B,6E,4E,39,C1,A3,F7,0A,0F,B5,2D,B8,F4,C8,E9,D5,D5,DF,B8,57,85,1E,15,9D,C3,9F,3F,68,80,ED,53,11,9C,1A,18,52,6A,38,62,54,8A,68,A2,03,F3,A9,00,8B,10,61,99,6E,77,9E,6A,9F,E1,F6,A6,55,DD,2E,95,9D,B5,C0,F0,21,72,85,66,DB,BA,B5,05,2C,EB,4C,D5,47,DB,F2,48,E9,18,44,37,13,94,D8,06,D9,4B,B7,79,B9,6E,24,97,86,26,BA,B5,67,17,1F,08,38,18,5E,7A,D2,E1,5C,56,14,72,FE,21,C6,57,44,CD,25,4C,BE,53,11,87,B5,79,D4,94,CB,B3,09,E7,3E,E7,5F,AF,B1,D6,9C,2B,B0,71,70,E3,F2,7F,17,5B,A5,DC,F1,ED,B5,21,E8,39,F5,82,6C,1E,85,5A,33,AA,64,34,D7,06,A7,AB,FE,1F,96,F6,DE,51,E5,7A,B5,45,40,D8,E0,92,1C,E5,A3,12,78,24,BB,C9,30,D7,3C,89,08,55,43,CE,40,0D,25,86,FA,2E,39,3D,5A,0A,5A,B0,65,B7,49,0F,7A,73,E6,A8,25,B1,49,5F,EA,8E,64,25,E8,41,E3,CE,52,45,2A,2E,F3,EA,0F,4E,2A,56,91,BE,AE,48,D0,04,B8,40,5C,A1,1B,05,10,C9,A8,0C,9B,24,F7,91,9A,A0,1D,9C,86,14,6C,9B,1B,35,60,90,F3,E0,3B,D9,90,D7,08,99,95,A2,9F,D4,91,CC,77,58,E0,59,22,AD,4A,2B,01,50,12,1C,06,7C,F4,7F,66,ED,56,40,70,6F,D5,7A,69,A2,76,5C,22,51,B3,EF,7C,FC,50,DD,DA,E9,29,CE,D2,B7,FB,EA,82,F6,D5,F5,C0,B2,B4,CF,B3,F0,5F,2D,42,A0,AF,3C,4A,86,E9,24,F3,64,0F,7C,E0,25,C1,E0,90,F4,02,21,BA,1E,20,D8,28,FF,D4,F3,00,FD,41,F3,75,C6,00,63,C7,A9,35,E6,A7,A0,08,BE,2C,BD,95,AB,4D,49,84,A5,E3,CA,35,7D,09,EF,A1,32,F6,13,A6,F7,1F,71,FE,F7,05,00,FE,DA,24,E2,7C,DB,9E,F2,BB,8F,F1,CE,7B,5E,6A,DC,63,0F,0A,47,4E,FE,AD,62,05,50,D0,E3,44,20,EF,5D,18,5F,8C,BC,C9,A0,32,D4,CA,3A,A3,26,97,EF,8A,D1,57,02,E3,06,F1,DD,80,6D,CF,D7,1D,F2,E9,1C,B3,13,AF,2D,7F,95,F5,4D,27,31,51,4B,D7,4D,13,55,A7,32,9C,42,D9,2C,65,DD,DE,8C,EF,79,35,39,79,F4,9F,30,C6,26,03,D9,D2,92,F6,B1,E4,E8,A8,86,8A,D7,A0,80,4D,B3,C0,E8,BF,4A,02,8F,08,72,54,79,6C,74,3B,EF,70,D6,D3,76,EE,8A,1B,A7,A4,C4,4D,17,E8,A9,1F,F3,51,B0,EA,66,4F,3C,B4,9A,AC,86,9F,C1,38,4D,64,6A,46,BA,85,65,E4,7A,38,C7,A1,17,92,93,7A,46,16,F6,FE,38,6C,EC,E2,D3,F1,95,F7,DC,9D,E5,52,F6,54,A2,1A,72,44,95,14,E2,59,00,3F,99,8A,02,06,74,44,DB,E0,AE,5A,B4,E1,85,79,51,DE,90,27,93,A1,53,C5,B4,6A,48,1B,81,10,8F,61,6C,C6,91,DB,3A,F4,5C,32,CF,68,04,CE,4D,71,19,71,95,5D,A2,FB,E1,74,FE,52,F0,DA,42,46,6F,B9,7A,A4,CE,5A,DA,DE,9D,48,6F,2F,AE,48,29,78,8F,91,B2,C8,34,42,AD,A8,77,F3,74,83,29,4D,55,DB,C1,42,0D,05,57,C4,5C,09,1F,48,4D,07,A9,12,4F,81,5C,9A,5F,94,8E,46,7C,6F,B7,43,CE,23,AD,ED,20,34,32,B7,2F,77,64,A7,40,8E,D7,3A,56,D0,72,B1,40,64,E7,5D,98,72,65,A4,72,13,CF,41,2B,F8,56,AB,6F,B8,A2,87,77,35,2E,49,78,4F,92,40,74,56,B7,70,A0,82,50,88,66,38,FF,74,32,E8,4A,B2,FF,C3,1B,24,5F,27,5C,CE,E7,D0,1D,FE,5B,C6,F0,2D,E8,EB,92,E1,26,7B,14,20,F6,63,EC,4F,0D,B3,F2,5E,54,89,8B,70,A1,F9,F9,D5,87,3B,93,53,8D,10,D2,B2,35,E8,CD,A0,7D,80,9B,6B,72,E4,7B,7E,D7,F2,82,F7,F0,C0,B9,C1,FF,2B,7A,A7,B2,78,99,F2,26,87,43,D4,F8,9C,F4,46,B3,FC,BA,09,D0,6C,CB,6B,40,BF,FE,5B,49,0B,F5,AC,C6,72,3D,F4,3C,22,AA,7D,1B,1E,21,F1,EC,4E,01,E9,4B,EB,16,02,59,37,76,56,DE,92,4C,5E,20,A8,A8,FA,F5,0C,C2,63,DF,86,FF,EB,62,8B,29,3F,33,20,23,09,62,1D,68,F8,8B,7E,95,80,AF,96,39,33,36,9D,63,FA,58,E2,44,49,02,D9,22,CE,AE,ED,29,D1,43,D8,F7,CD,5E,31,85,F0,70,37,89,13,23,A6,0F,D8,2B,B5,77,EF,8A,F3,B6,71,CA,F0,B8,AC,B6,22,D7,69,44,DE,6A,A6,78,8C,B1,E0,68,BB,A2,94,80,27,0E,2A,05,4F,05,11,1D,DB,24,04,E6,D8,32,66,8A,E8,6E,8E,02,3C,31,52,BF,1A,79,2F,08,21,59,34,BC,90,56,EF,39,3E,73,01,EF,E4,DD,22,DD,66,05,11,A4,28,61,77,AA,1B,F7,CD,8B,E3,E1,D9,D9,21,27,48,53,2E,01,C8,9A,25,AA,59,75,18,C2,BA,37,2F,92,A9,FE,4F,AE,22,E6,88,00,1F,93,7B,99,F6,B9,9E,74,E7,1F,4E,33,91,50,5C,58,45,42,30,F1,35,B8,46,D6,EA,D7,2D,81,01,C8,64,0B,85,B5,41,AD,59,D5,46,90,3A,7F,5D,A9,EE,E0,15,2A,50,2A,43,20,A3,06,9E,23,53,CD,AC,FE,BE,40,EA,F5,39,CC,97,59,D7,23,6E,78,34,64,28,BC,C3,89,68,E8,59,50,64,1B,CE,F4,84,CD,D3,CC,F2,E1,AF,3A,D0,ED,6C,8E,F7,08,71,5E,69,51,DA,AE,DB,63,E1,FA,03,EB,13,F2,DE,CA,F9,3D,B5,36,7E,98,5F,0D,C2,F8,78,9C,AA,5E,95,21,71,A2,60,EA,09,A4,C4,4B,DF,24,8F,15,51,ED,B6,30,0D,7A,A8,1C,C5,40,92,5E,5C,ED,B9,4F,39,A1,09,D2,23,72,FD,5B,40,BB,F1,FD,AA,EF,2E,15,1D,EA,E0,9B,4C,D0,50,30,F0,A3,A8,4F,F3,45,A0,FA,36,07,D0,56,7F,1D,89,BA,B7,D8,AC,6F,D8,25,F9,77,AA,2B,06,8C,1A,89,85,D5,72,E6,90,15,6F,59,19,27,C6,05,26,88,5E,53,62,D0,BA,E2,75,E0,A8,85,1E,2A,77,C4,8F,82,FB,93,F8,05,26,2B,15,66,C9,F4,17,CC,F2,27,A1,0A,27,0D,93,D2,C9,0C,05,08,E7,9A,28,C3,B3,1D,ED,6B,09,7B,0A,19,ED,63,56,77,76,55,2A,02,C2,D1,D3,2A,DE,18,02,2C,17,80,3A,CB,A0,AB,01,FA,0E,9D,AC,EC,06,4E,15,9C,8A,44,13,D7,49,F4,D2,28,87,21,EE,77,52,9D,CE,BC,02,21,A5,83,B2,97,C2,51,CD,5D,75,A4,61,BB,1B,21,3D,E5,CB,D1,EE,18,37,F7,3B,E2,93,FA,E8,CF,D0,3E,1C,A0,48,E9,4C,7A,BF,A9,A9,EC,98,30,DA,94,B6,4A,14,B4,7F,C3,EE,78,E4,D2,11,6B,C2,2E,94,ED,1A,D7,8C,BE,AD,95,C4,63,96,86,0B,F3,64,9B,12,4A,0F,4A,59,17,9A,01,F9,8F,9B,5D,6C,27,11,5E,97,85,67,30,49,C7,1C,59,1E,7E,DC,CF,18,61,50,8A,87,59,FA,98,07,D6,FB,DA,40,93,19,92,24,0C,BE,13,34,D0,05,16,94,FC,F1,9A,19,DB,B8,9C,EC,8E,D9,A6,B5,45,19,EF,A3,55,5F,26,66,61,37,81,2F,B3,D2,20,66,23,2A,28,BE,07,54,E0,E1,12,C8,68,AF,FA,E4,51,0B,1A,9F,0D,75,92,AC,AB,BE,CA,13,86,70,9E,3F,4B,98,BC,3D,66,C4,F1,A7,BE,1A,03,30,59,30,25,BC,6F,20,85,75,0D,1E,0C,BB,5C,AB,2A,9D,65,0F,53,FB,2F,8A,FE,4E,DE,E6,79,B7,4D,84,7D,6E,9C,FE,F5,F9,8A,52,0A,A1,C9,13,34,D4,7E,D2,6C,DF,B2,E2,A3,8A,56,70,E3,2A,BF,DF,65,DF,C9,76,2D,B0,D0,89,E9,2D,03,E8,A3,7D,BD,B2,7D,92,8B,17,A7,7E,72,B0,5D,34,5A,CA,58,1C,AA,39,C2,C7,B9,E9,93,E4,08,75,AD,FB,1A,88,85,D9,C5,EC,B4,91,E0,A8,43,47,37,A4,EF,F8,22,D6,10,53,81,16,24,C9,DC,23,E5,CB,CA,54,31,12,5E,3D,0F,9A,0E,B9,64,DB,7B,3F,74,0D,8B,CF,3C,35,EF,30,20,8F,79,BE,0E,6D,F0,21,89,EB,7A,44,98,DE,B9,45,DA,6C,7E,BD,83,59,10,4E,F3,53,06,C6,26,41,D4,E0,E3,5B,09,6D,21,26,3E,8D,26,CF,26,2F,7B,C0,A7,60,E1,B0,3D,5B,58,2A,B5,10,B4,D9,5A,D0,37,36,5A,EF,67,07,92,99,F9,95,99,9F,D5,97,86,FA,42,F3,97,15,01,73,48,53,CD,9C,CB,72,A6,78,9A,6C,67,A9,B1,DD,DB,01,10,94,C0,49,C1,C4,E6,EB,69,C2,42,32,30,CC,7B,9E,30,35,C5,5B,4E,AC,B0,7E,8D,F4,41,0E,57,13,2E,74,7D,FB,17,C2,8C,0D,4F,A3,7E,6A,8E,9B,AD,9D,BB,F4,A4,A7,E0,65,8D,E6,00,83,84,9A,B7,A3,19,44,A1,6F,EB,F7,17,42,58,B0,1B,4F,27,55,9A,97,DA,ED,0A,4F,E8,82,40,0A,A8,F1,97,84,6B,F1,8B,86,41,48,55,1B,9A,FE,B5,6D,6D,93,9C,50,D7,D4,3D,BD,50,F8,BD,19,3D,3A,97,FC,85,EC,34,E8,7A,0F,C8,7E,4F,89,7C,9B,DE,81,77,AD,2A,7B,CD,B8,AB,E0,CD,24,D4,E3,E7,CF,A3,C1,EE,A9,57,C6,0E,61,F1,A1,B3,44,DF,9F,5F,04,DC,61,7E,A8,0F,67,7B,08,2D,76,55,5A,68,95,E1,97,F6,EE,28,5A,74,AD,39,BD,DC,66,E8,22,5F,CD,8B,5F,BC,CB,54,E2,84,1A,D7,05,CE,80,89,F2,02,58,7C,AB,2A,E3,DA,E6,D6,0D,AB,A2,DF,7C,2D,6B,5B,0C,30,53,8A,CC,B8,55,9C,F7,20,3E,82,82,D8,AE,4A,D2,4A,0A,47,F6,D9,9A,F2,9D,3A,18,B1,C7,55,7E,13,07,61,00,A0,CB,90,0A,52,6B,25,12,27,00,47,EA,59,90,C5,C9,1D,07,72,BE,D9,BB,C9,75,45,B1,B1,CE,FD,B1,1C,B5,5B,2C,FE,49,4F,4C,26,8F,14,CF,64,BF,B1,40,3D,AD,9F,79,0C,F7,0F,E5,80,0B,6E,CF,AC,73,D3,5C,18,BC,33,CB,70,98,C5,BC,AE,83,78,35,C8,27,4F,0E,A6,D6,15,98,98,93,12,93,D5,18,75,B0,25,1D,4A,90,A3,C8,FF,82,C0,4E,5B,BD,A6,84,03,40,BB,73,37,28,6E,2F,41,47,0F,B9,E1,F3,B2,F6,4E,41,2A,EE,A6,AC,56,2B,42,75,A2,86,05,34,6B,7A,88,5B,FF,BE,63,EA,EB,F0,FB,61,16,8B,36,FD,B7,71,54,33,AD,DC,76,7B,ED,CC,6F,42,43,D2,7F,B2,70,3E,55,FF,68,D7,0C,D3,A6,B2,0C,DE,F3,CC,D7,A9,EE,DD,D8,6B,3B,03,C4,83,38,C0,98,18,31,F3,2F,07,31,77,D5,40,C7,12,12,57,EE,80,99,0A,4D,5E,90,AF,41,A9,63,A6,E5,39,82,9E,99,D5,1F,32,CC,5E,71,55,70,E9,8B,4D,1E,7D,42,33,5C,87,49,22,40,E8,04,DB,FA,EF,20,3B,48,3F,84,CF,8D,D1,B3,E8,D7,B7,EF,35,8E,C6,2B,B6,3F,A6,77,76,CA,70,6C,C0,8F,6E,0B,22,AD,58,DA,2D,1D,AA,F4,BF,FA,50,69,66,72,CE,9E,82,23,DB,73,C1,01,53,67,CE,FB,D9,E6,73,51,57,76,62,62,06,93,FF,2E,08,ED,56,93,24,F5,67,5B,F7,98,C2,15,C9,36,42,8C,36,24,0B,7B,3A,36,2F,D6,99,9D,2A,95,24,F9,0E,30,F1,A5,D4,2A,5D,D7,B5,E5,4E,2B,65,FA,D3,A7,F8,12,68,CF,07,9B,77,00,D5,DC,7D,06,13,4F,92,13,67,4B,9C,D7,61,33,A5,5E,CD,2E,51,FA,80,31,55,23,40,77,CB,48,8B,4A,37,38,BB,CA,5E,52,EA,AE,D8,37,60,26,75,24,71,A3,E2,E0,A9,9D,AA,F4,04,72,E8,0C,1A,56,50,94,04,8E,9A,60,39,58,B6,9E,4F,44,41,5F,C5,BA,CE,19,D1,C5,2D,0A,E7,CF,22,2C,47,54,DB,08,69,B9,00,D6,7C,9B,E6,46,C5,E8,CF,5F,A1,E9,FC,8F,97,C3,67,1A,FE,1F,38,33,91,07,9A,33,3F,3B,20,AD,8A,5C,EA,9C,35,0C,F3,FF,A3,CD,39,1C,E4,6F,B1,29,DA,97,4A,E6,40,66,E8,7E,68,A3,35,30,97,72,DB,CE,9B,0D,44,87,B3,B4,33,3F,05,C7,CC,E4,69,99,BC,54,E6,9A,23,D1,5E,71,F5,76,7F,00,D2,4B,C2,96,2E,86,7B,D5,87,B9,1A,21,47,AB,A9,11,FF,27,21,FB,16,DE,D1,B8,D6,F5,FB,5C,2B,A3,DD,D3,6B,19,DF,FC,7F,A4,A7,EC,9D,B2,BF,32,A7,3E,79,35,E7,7B,B3,67,07,B8,4F,E0,99,BA,F7,C9,08,92,ED,B0,E5,91,13,9C,65,E6,12,2E,6D,8F,C1,B6,FE,2B,DD,07,E9,D1,FF,2D,CC,1D,53,DA,70,60,64,E0,4A,33,30,F6,CD,D7,6B,F1,DF,62,33,FD,30,67,CB,81,08,83,2B,32,3D,85,CB,91,DA,20,6C,CB,88,40,20,7E,3E,04,A9,C4,18,9C,C9,E2,D6,A5,E0,1E,6E,E5,94,90,36,2F,07,35,4A,48,29,6E,44,73,54,46,01,4B,8A,B0,A2,9A,B2,CD,BE,51,99,FC,0B,D8,64,DB,B3,4C,AB,97,65,FB,F7,1E,C0,E7,FC,3F,40,44,CB,F4,4B,72,66,FA,B9,14,BC,FF,FB,DA,5D,8A,8D,B5,3D,9F,0C,97,26,A0,14,F5,86,9A,1F,C5,8A,D3,56,53,A3,44,19,38,6C,78,EE,6C,6E,F8,9B,70,0C,48,18,59,2A,F3,95,13,57,07,03,57,61,B8,29,6C,C3,EB,A4,34,B9,75,69,B3,1D,8E,A5,AF,97,4F,BE,34,9B,F1,3F,74,E2,57,47,49,FC,71,CA,99,48,98,4D,38,D0,49,32,83,B3,34,50,B2,E1,53,D1,67,34,0C,E6,A4,22,C4,F8,F2,E7,B1,2F,50,30,FD,47,9C,0F,37,4A,8F,0C,7A,41,EB,C0,4A,EE,B5,A8,5C,37,A9,3A,81,53,54,E3,E0,F9,04,E2,B9,B8,9F,E1,26,AD,A2,85,90,DB,45,20,0C,D8,9A,DB,C8,0E,86,75,9F,91,29,33,EA,9F,18,D3,AD,5E,EB,86,19,BB,F5,9F,30,26,B0,92,3E,C6,A9,CD,D2,37,53,21,C1,D9,7D,4B,01,44,CA,A8,93,F9,37,16,AB,AD,1E,D7,0A,F5,93,8A,AE,D8,D4,95,EE,5D,3A,2A,B3,67,BE,BD,AC,9A,51,FD,DE,14,45,50,1A,8E,ED,AC,D7,7D,36,A1,30,B0,9F,F5,0F,B0,BE,B3,73,E7,DC,08,BE,57,53,7F,18,12,6E,73,2B,82,10,82,6D,E7,AB,B3,E7,E2,5C,60,FB,A6,D3,4F,96,61,46,60,76,E4,27,D7,D8,C0,63,D6,5E,12,76,20,EA,EE,B5,EA,CB,B5,CB,F3,1D,4E,15,3B,B8,06,EE,48,7B,8B,3C,03,67,CD,DD,D4,E6,1D,CA,CE,33,CF,82,27,DB,74,62,28,3B,25,F6,C8,69,BA,25,B7,CE,54,C2,D9,2C,E3,35,A0,C9,32,AB,B2,28,7B,6F,1C,69,48,4E,48,78,9A,4A,AA,82,58,6E,AD,25,6D,62,FA,FD,49,C9,7B,B6,5A,9C,33,AF,C7,C5,E6,4B,E4,BE,A2,3F,A6,DE,B8,20,73,A8,3A,31,BB,54,77,CA,1F,02,1C,65,82,6A,45,29,53,14,24,58,BC,35,30,2F,E9,96,45,62,86,01,C9,9E,39,10,82,F7,CE,9A,78,4D,57,E9,6D,7E,E1,E3,60,B2,B3,04,18,B8,FA,01,EF,D9,6E,9A,63,5E,E2,71,91,94,68,53,6F,A3,A1,87,F3,86,F4,E3,2B,41,8F,75,5C,62,F1,B2,B2,BF,28,2E,5D,C3,90,7A,3E,73,B8,21,68,CA,01,F3,04,80,B3,E1,91,16,FF,66,96,81,01,5A,6D,8A,38,1B,24,0C,E5,6A,07,CD,74,F1,D4,3E,71,90,20,DC,BA,65,42,CB,00,DC,5B,5D,73,1B,47,7F,46,ED,2C,A7,77,D5,8D,FF,98,B3,0E,2B,CE,40,EE,8C,3F,21,D7,2F,11,6E,63,52,8C,F3,C1,21,1B,3D,BB,29,BB,01,C9,C4,0D,BB,71,28,F0,3B,CF,C2,CE,AF,95,47,02,07,E1,CC,FF,17,80,64,02,BA,1D,12,24,04,96,A4,F8,5A,AE,27,B0,F3,89,7D,A2,9A,B3,42,49,3F,09,CA,F2,0F,44,45,7F,84,88,38,12,15,F3,92,E7,33,42,21,4C,83,00,3E,48,B4,16,5C,8C,AA,4F,1D,58,D3,FA,CF,C1,03,27,E8,A5,7E,79,48,02,96,67,4C,60,DA,34,47,EA,B7,B5,A5,68,8A,BA,01,3E,FE,24,E4,45,D7,84,F5,EF,C6,4F,12,CA,05,B4,DF,21,B9,DC,43,CD,B6,F6,17,5B,04,E9,F4,B3,EB,DA,22,5C,3A,E9,E2,F9,E5,EE,01,75,83,19,5A,65,34,B9,B7,4C,E5,35,66,14,9C,14,39,F5,A6,DB,A2,36,7B,AA,CB,70,33,46,CF,F0,08,0F,57,09,0E,6B,E9,E2,ED,92,A7,98,2B,0F,FC,80,A6,FE,BF,51,12,D7,44,C3,B0,1C,98,1C,A6,0A,23,00,F3,CF,83,93,61,84,7F,30,7E,39,75,67,4C,A0,33,CB,B4,BB,AA,EC,82,DC,62,E8,1A,AA,2E,3E,E4,01,7B,9A,18,64,96,2C,FB,76,DF,61,44,DD,14,B6,74,75,0D,8B,8E,2C,A1,05,E3,A5,B5,26,4F,F1,1E,0F,9F,65,EB,32,11,E8,5D,7A,C8,BB,C1,07,16,20,9F,33,A1,6C,8A,0A,88,14,ED,22,24,2B,26,83,47,F0,90,8F,58,E4,ED,C8,E8,2E,90,06,41,C0,19,76,B0,F4,66,D5,80,27,AF,23,CE,20,6E,53,CD,3F,F4,18,C7,A9,EA,62,45,5A,30,29,4F,75,3D,21,BC,F3,72,BB,30,83,1E,05,84,E9,7F,28,5D,7C,83,FF,F1,08,67,A2,A5,EC,19,8D,9C,0E,01,24,42,5E,AE,79,BB,A4,99,E1,CA,0A,6D,46,AF,00,0A,E4,4C,92,5B,EF,7F,EF,0E,7B,7A,54,AB,AC,66,A9,FB,9D,8C,2F,76,50,18,72,3C,BC,CA,77,BF,D2,48,84,65,3C,02,E1,DD,5F,FA,23,6C,DF,97,82,E3,AD,A8,D4,AB,AB,B9,F7,05,50,77,2F,92,6D,49,20,12,EB,5F,DD,4C,D1,81,0A,65,96,F9,B0,2E,EF,8B,21,77,84,E3,AE,44,D5,D0,A0,DD,AD,67,D8,CB,10,44,EB,76,B7,1C,87,FC,2E,B4,B0,73,2F,62,7D,9B,AE,15,61,9F,35,BF,C7,34,23,84,BF,BD,6D,91,8D,CA,DC,71,D2,9A,15,8E,35,E1,20,B6,83,09,B2,3C,8F,74,E3,B7,3D,F0,3C,15,7B,F1,CA,06,7B,00,C1,14,9D,19,E4,BB,13,FD,69,60,5C,A0,76,26,11,54,8B,26,1B,D7,D5,19,C4,96,95,08,66,A6,C5,F4,9A,4E,14,EF,5A,4F,6F,86,69,45,75,C1,1C,0C,36,64,31,82,B6,DB,88,15,DB,AD,37,4A,2C,64,91,89,1B,42,AD,AC,C9,D3,9E,E0,25,3D,A0,80,37,84,59,19,DB,08,4C,7B,45,C6,CA,EA,C6,C6,E4,C6,46,BC,4F,A9,6C,B2,A4,BF,43,1F,63,C7,CB,58,74,00,CC,D4,B3,51,27,D1,D1,3F,BC,B4,63,15,4F,41,E6,01,D1,89,DA,FE,5D,53,45,00,FF,0B,CA,D7,78,6B,27,6D,AB,85,45,AD,42,86,F4,76,48,DA,A9,7B,2B,DF,3F,F9,0C,E7,96,3A,76,79,40,7C,A4,26,30,6E,13,80,B8,C2,34,BA,10,0B,2F,10,48,6C,49,24,32,3D,10,A1,EF,18,D4,4F,9A,B9,25,18,83,C5,E0,C7,D0,7D,D9,31,9A,4E,EC,88,31,02,2F,B0,51,6E,51,9F,34,2F,83,4E,B6,F1,DC,FF,00,B6,66,21,81,23,29,2A,25,0B,AA,45,8F,AA,50,8E,17,C1,80,C4,9B,47,30,20,37,D3,88,40,D0,05,12,F2,11,49,28,B5,61,57,56,81,23,C9,05,D3,12,9C,6A,9F,AB,1B,B4,0D,56,BD,3A,8B,6B,E1,EC,B6,82,58,2C,0B,A2,A0,FF,36,4D,9D,FA,10,3D,54,32,5F,EA,8C,10,18,89,6A,31,1D,6D,54,69,5D,2E,0F,C4,FE,E7,B9,C4,35,99,85,D9,97,83,10,0B,19,72,DA,7E,25,B7,5F,64,A0,22,25,69,1B,B6,EF,ED,5F,66,13,51,17,68,A6,D2,AF,1B,EE,A1,2D,B9,28,9C,E0,EB,02,83,33,9E,AD,2F,DE,68,89,37,D6,A2,3C,D6,C3,D3,C9,9E,CC,D3,32,D7,0B,D3,69,46,29,05,8B,0A,A3,BF,86,27,5F,E6,DA,1C,FB,1F,B8,77,C6,43,E7,FE,D0,9C,49,CA,72,CA,13,EC,1D,F9,30,7C,10,D3,CD,B4,62,40,B6,09,B2,1C,AA,91,35,37,D7,86,4C,60,3F,B8,A4,40,17,97,60,04,FD,8B,81,B4,DD,D4,9A,58,28,07,87,03,25,38,AB,23,61,98,31,2A,DD,2F,B6,04,7A,69,59,34,45,1C,72,EE,32,0B,C0,E6,5E,82,91,64,07,03,4B,FD,96,02,E0,00,4E,FA,8D,BE,17,E9,D9,B0,2A,65,DA,BA,47,77,F9,70,A0,5D,52,4A,51,5A,9F,7B,BF,40,30,77,53,12,E5,64,E2,CD,65,73,90,06,54,D2,10,B8,01,22,47,AF,1A,FE,E7,4A,ED,F6,B0,98,3E,24,42,0A,38,71,BE,BC,45,4F,52,14,52,60,8E,3B,9B,93,0A,8E,51,F6,3F,E3,74,CA,AF,32,2C,1F,AC,40,2C,9E,FF,83,1B,D0,E3,87,BC,1E,CA,5D,3B,93,BB,D0,76,0E,68,1E,0F,5B,23,1C,22,A2,F9,C7,02,38,41,0C,06,F4,5E,16,34,AC,29,2A,91,9D,D2,7E,36,18,9C,0C,C4,D9,2B,BF,A8,28,BE,B1,CE,49,4C,16,4C,D3,5A,16,0E,F7,98,37,22,49,CE,6D,D7,66,64,30,0E,45,CC,A9,DB,E0,BD,E7,38,07,5A,92,6C,AF,00,9F,B2,FB,40,BA,DE,21,84,CC,32,7F,C1,5C,82,AB,8F,49,1F,52,3C,B8,AF,BB,1E,9A,35,45,B3,83,01,AE,BC,28,77,94,C6,73,0C,C0,5E,54,43,38,AC,AB,72,DF,FC,A6,8E,DC,A3,7A,15,B2,63,29,38,3C,2D,88,8B,F3,FC,C5,D7,82,43,FD,07,B7,EF,B1,72,7C,CA,D3,29,15,F7,16,89,45,56,80,E2,C2,2E,EC,28,4A,B4,8D,8C,C8,29,9A,32,AB,AA,AB,68,CA,38,CA,BD,02,79,36,36,35,6C,31,40,13,F7,94,FA,6C,52,F5,24,AD,1B,4A,BF,9B,FF,2D,C5,C9,C1,DF,7A,B1,29,79,52,1E,D7,15,9A,F9,AF,12,D6,06,86,11,70,2B,D6,2C,F6,B5,C5,7B,E8,66,19,F8,F8,55,64,D9,33,3D,6D,B4,94,CA,2C,7D,60,0F,A1,95,E1,B9,28,09,A9,5B,1E,F7,3E,91,45,69,64,3F,1A,BE,AC,BD,C6,33,AE,81,A5,85,7E,E3,3E,50,31,64,E3,74,43,53,F9,7A,9B,88,22,B8,8E,BF,44,14,30,5F,57,5A,94,08,02,CC,33,3C,4D,D2,05,F6,D0,C0,6B,DC,18,9F,F4,4B,98,BE,BE,B6,4A,6A,D9,96,12,DA,6D,B0,68,B4,BC,D9,F9,E0,3B,6F,D5,97,FE,C9,2D,37,E3,32,9F,3C,32,4E,97,E2,44,CA,93,FA,FE,F4,EF,44,12,10,BE,79,69,6C,DB,D7,41,F7,FE,3D,43,AA,9F,0E,2B,1A,D8,61,14,A0,8D,3A,E0,91,86,EF,37,09,DF,A0,02,9F,44,15,65,B6,7A,34,E1,44,59,1A,C1,59,29,BE,88,83,EC,CC,A3,ED,CE,5F,5C,48,64,70,63,8C,BD,E2,3A,CB,AA,E0,41,6E,01,54,17,18,B2,85,F4,DA,A2,9B,16,6A,E6,7D,D0,D3,B9,9A,37,6C,C6,F1,0F,C3,93,AB,60,53,88,A2,A9,12,8A,33,7A,C3,CE,0A,13,0C,5C,B4,82,D7,51,84,DE,AB,0F,33,E4,97,1E,CC,7C,F5,FB,CF,BC,AB,76,87,B2,E7,97,16,4A,C4,31,1C,2A,07,35,A9,1B,B7,07,F0,BC,87,0A,0D,A9,B6,7B,7F,51,71,48,9B,21,04,2D,3C,7C,CB,11,49,E0,1B,28,1B,3D,53,34,3A,AE,51,5E,0E,30,B3,61,7D,13,E8,AA,E7,2F,21,C2,C4,30,2B,5A,D8,2E,94,AB,D5,E2,33,4F,80,3D,AB,83,33,63,35,02,DE,83,3C,7B,3C,AC,09,A9,95,69,83,88,0D,7A,1C,D2,4F,B0,71,22,0B,32,39,51,C6,85,D2,A7,85,59,C6,38,01,99,60,CB,95,76,E5,43,D8,5E,4E,6D,47,57,55,73,DD,B4,33,35,41,14,40,F7,E0,B7,80,3F,C3,66,75,71,83,F3,A5,39,43,82,CC,DE,6A,29,B7,D1,6E,F5,D5,D4,3E,FD,04,B3,95,3C,E6,34,67,9E,22,A6,F2,E7,F3,5B,05,37,40,98,A9,07,F9,D4,77,20,85,12,F9,38,DE,8A,B1,D2,2E,C5,8B,37,50,4D,2D,F5,16,10,D0,80,27,1E,A8,0B,6A,28,37,00,B9,EA,27,D4,76,41,CF,AC,22,94,52,38,E8,9F,D2,6F,B8,CE,55,C5,D6,03,84,B0,B5,E5,B3,D0,59,81,1D,CA,E1,91,0E,55,15,D2,FE,ED,62,06,9B,C6,E1,E7,FC,C1,85,1F,00,AE,A3,06,8D,EC,96,01,25,E9,12,EC,64,10,69,74,E6,32,0D,B6,BA,32,8D,F6,FE,15,45,0C,F3,8E,16,60,5C,11,BD,2B,AF,42,FF,17,EF,3A,F3,8C,C5,B1,EB,9F,05,AB,CC,47,37,1D,AF,38,78,22,06,B3,59,B5,13,61,AF,08,E1,A5,EC,83,FF,50,98,51,E9,6E,18,C8,46,C6,31,C3,7F,6C,77,6A,CE,8A,7C,39,58,AC,1B,3F,F5,01,BF,09,AE,4D,45,7E,E9,EC,6A,07,27,65,0B,79,7D,F8,EA,9C,4F,70,3A,39,7D,76,6C,0A,5A,4D,B8,95,32,1E,0D,84,77,A0,2D,6C,EB,7D,DA,4A,9B,36,0D,53,91,BC,C4,C0,96,B0,EA,6B,28,10,F2,3D,BD,C8,11,D7,BD,70,54,0F,EE,DD,0A,42,53,96,84,77,7E,FD,58,A1,C7,3F,70,C0,7C,EE,74,47,BC,5A,1F,1C,AF,F5,D0,76,48,71,8D,05,BF,77,56,61,6A,B2,98,7C,26,5B,C8,5C,6C,F9,C4,3A,E8,39,4D,02,A1,C7,FF,E3,A3,47,CB,80,E8,CA,A4,DD,6A,F9,30,83,12,E7,C5,50,4F,0B,29,CA,FC,AA,9A,D2,C6,87,CB,8B,A7,F7,98,C5,C1,B4,BC,34,D5,82,79,F8,12,31,C2,5E,00,7E,61,41,90,FC,77,FB,22,67,98,1D,A2,F1,8E,08,CD,CB,11,78,2B,56,34,7C,20,11,34,FD,9B,55,9A,5B,DA,21,6A,87,21,2A,0B,EB,4D,E4,F3,89,28,9C,EA,D9,98,44,54,20,5B,54,33,78,1A,37,A3,1A,4C,C3,3F,5A,8C,DA,AF,9E,D6,33,E8,E2,7B,0B,8C,33,A1,55,35,C9,C0,D0,93,6E,64,37,86,66,3B,8D,BF,78,26,8A,27,DA,D6,91,AD,5A,3E,31,2F,61,E7,1A,A3,C8,1B,58,15,32,61,25,1E,2E,A2,AA,42,F6,C5,79,38,3B,3D,C2,AB,EC,7F,15,0D,B8,37,52,F0,41,07,55,08,16,6B,94,02,90,83,BF,F6,8D,AA,A7,D7,E2,0E,FF,98,0E,65,0B,2F,94,E0,E1,1E,AC,49,6E,5A,DC,E0,18,B0,6B,AC,77,79,88,78,42,CF,C1,B0,54,26,52,64,F6,3C,4F,A3,80,7D,EC,06,C4,72,CE,E3,A1,31,B2,F5,22,A0,EC,99,B9,8C,A7,6A,3A,04,50,62,0E,F8,74,02,1D,A4,8C,EC,9B,29,9D,93,A8,E2,9B,C9,4D,E6,7E,8E,C5,77,42,A4,54,44,FB,E1,99,FC,D1,53,05,9F,72,D5,9D,6C,99,0B,D4,0C,EA,AF,79,6A,12,3D,48,29,8B,97,01,68,07,68,32,73,F4,38,BE,05,D1,16,F4,1D,01,65,B6,BD,2A,E4,60,21,C4,37,96,F4,1B,60,97,02,3E,3E,C7,66,32,75,7E,48,97,D0,00,01,61,9B,60,A9,9A,AD,55,D5,2C,58,54,EB,15,BD,4A,B6,46,AB,F8,E7,4E,76,8D,84,17,29,97,B7,AE,14,27,21,03,8E,E1,0E,8B,B8,7F,33,63,BC,06,EE,7A,0A,B7,6D,8D,8F,D7,3A,14,82,18,06,63,46,36,97,3B,0A,04,60,C4,87,DD,A6,62,8F,1B,15,18,D3,5A,18,E8,84,BB,67,AE,0E,AF,0C,1C,91,F8,1C,9D,BD,82,F3,2C,D0,92,77,5C,E9,68,AB,21,92,90,20,A0,98,18,C9,6D,15,38,DD,D8,D6,84,11,8B,56,3F,14,BF,F4,B5,32,3A,11,B9,27,86,63,49,B4,FA,ED,DF,A1,43,57,6C,A7,C0,5E,17,5A,B7,8B,FD,5D,99,92,BC,EA,8A,E3,6B,65,83,E9,AC,18,25,DA,09,88,AF,3E,4E,BD,72,41,BA,CD,D8,E3,3E,B5,3E,24,90,16,C1,84,9D,3D,18,56,52,3B,62,1A,37,F4,A0,C3,41,1B,89,85,67,D0,56,FD,F8,DC,0F,9F,EA,92,6D,15,48,7E,F7,B5,39,5E,6F,F9,6D,D7,C4,50,0D,4A,5B,A2,69,93,99,EA,5A,94,66,9C,B2,96,73,00,0F,06,09,A7,F4,E0,9E,F3,1A,53,25,E0,0E,EA,7A,5F,B4,A9,FE,AC,CC,DE,EF,AB,F1,E6,FC,4B,24,2E,4B,1E,4D,70,37,A3,86,F1,2B,BF,3F,48,82,F5,77,AC,16,C4,86,86,81,7E,A7,BC,C4,BE,09,96,67,FD,3F,8A,FB,8C,1E,F1,F4,14,02,29,71,9B,E5,20,A8,13,25,59,A9,94,7E,2E,46,C6,D9,54,BD,DA,69,26,54,05,C3,FE,E8,F6,3D,82,5D,51,9C,A1,C0,FF,7B,00,6C,59,16,A9,A4,F6,1F,5A,1C,A2,F6,CA,B7,E4,4A,95,AB,10,AC,A4,25,FE,15,DA,DC,AD,2B,A9,D3,F6,1E,4A,78,EF,E0,91,62,5E,81,09,0A,EB,DE,EB,7B,B3,EB,1C,FD,3D,FF,AC,B4,14,9D,A1,CB,8C,9B,0E,67,30,1D,F1,F2,BB,02,86,F8,B5,73,46,EE,23,34,85,68,18,1E,1B,69,70,6B,D9,BA,E0,25,FC,C0,4B,E3,8A,33,75,1B,A1,59,96,6E,76,B6,74,F2,87,60,60,45,C3,79,6C,45,5F,8A,8D,CD,FF,FE,18,81,04,4E,9F,02,C1,60,64,00,72,EE,6C,D1,9C,C3,CB,1F,C0,81,8B,05,1C,EB,3E,2E,C7,2E,FC,CB,E5,F6,45,D1,2E,9B,61,8D,BB,78,B0,4B,D7,EF,3E,89,4A,EC,CB,F0,13,D4,81,91,34,1A,76,47,94,80,B2,02,34,9A,2A,0D,9A,D6,87,59,AB,7B,4E,42,DD,90,3B,07,4D,91,30,57,68,07,48,6A,22,5F,45,C5,60,B0,AA,B4,ED,78,1D,CF,99,D0,5E,40,11,6E,CF,A2,84,E4,E6,3D,AF,46,F1,5C,17,42,72,65,E9,57,4D,83,1A,A4,B0,D8,5C,E1,93,6E,99,FB,37,40,62,0B,A9,1C,43,2B,23,D3,AF,F6,9D,05,D0,E2,A9,0C,95,66,13,4B,E4,A4,39,BB,E7,F8,62,B2,7C,C1,D0,32,94,1E,4A,3A,01,D0,DD,C6,F9,96,32,63,4E,8A,8A,51,39,9B,DC,20,86,AC,BC,F4,9B,41,AD,F7,54,84,A3,6D,8C,AC,0C,57,84,FF,0E,E2,46,C0,47,AC,14,D6,95,30,6E,EF,03,AF,EC,C8,98,2F,D6,25,7B,C0,30,4E,75,4A,DC,17,41,8E,D7,A6,2B,FC,7B,57,63,CB,C0,CA,9F,90,8C,79,56,E1,19,8A,6F,59,64,D5,A9,F5,EA,9B,AD,BF,AD,7E,B9,C2,58,2F,88,48,C5,5B,31,3D,39,2C,E4,8C,AB,ED,5C,0B,68,E2,A7,27,2D,6C,AD,4C,C3,7B,06,A3,A8,C8,6B,DA,70,09,3A,CC,89,F5,DD,E9,6D,10,22,74,74,D2,84,2F,69,98,D5,E3,42,FB,0B,EA,C6,03,F5,BD,11,DB,F9,9B,56,C0,27,B0,F5,1C,20,E2,85,22,5E,BC,9C,25,9C,38,35,54,E7,C3,45,EF,37,5B,CB,86,7E,93,2A,42,37,C4,6E,E9,4D,6C,8D,A8,5B,52,14,02,C7,01,48,45,B2,ED,93,E5,02,FC,26,82,95,4C,97,C7,56,21,D4,AD,AC,0C,34,CC,EB,01,4E,B4,FA,7E,AD,CB,8F,D1,EA,B1,26,AC,C1,94,B3,B8,1C,14,6A,1D,9A,B5,4B,60,D9,CF,2D,42,9F,35,D4,34,D9,A9,C4,7C,35,3D,EA,AA,7D,F8,CE,C4,7E,2A,81,50,03,74,DA,5E,C2,9E,9A,91,40,7C,43,2E,C3,9B,6F,F7,42,70,5A,3D,4A,80,E4,B5,74,7D,6B,45,C1,DA,41,65,AA,5C,3E,C2,5E,70,05,4A,89,3B,D8,9E,36,C0,11,2D,1E,76,50,69,49,FB,21,93,39,B1,95,06,A6,02,65,78,49,BC,BE,51,53,2C,AD,8C,4C,8B,D5,16,4E,2B,CE,D4,8F,D0,DA,1A,18,19,29,45,19,4A,0E,99,8B,F3,27,72,D5,E6,C2,A8,F1,EE,94,34,70,2A,50,78,94,EA,A2,F5,73,54,FE,DE,05,36,71,96,20,76,23,F0,C5,1B,85,6B,AC,CA,C2,FB,8B,0E,11,9B,78,45,21,42,A1,05,5E,87,B5,CF,77,EE,6E,7A,A7,19,9D,93,FC,E8,B5,18,99,7F,DD,EA,AB,B1,61,A4,26,1E,3E,44,18,E9,7D,91,81,07,6F,33,51,12,F5,6B,1D,C3,C2,08,4B,D5,C8,97,ED,D8,53,D7,0D,3C,81,57,83,6B,07,38,0D,C8,2E,63,5C,40,1C,DC,D4,BA,01,1E,92,0A,D7,92,6C,A9,E9,01,2E,B9,AD,05,2B,2C,8E,30,5A,6D,7A,4A,6A,0B,A9,81,A7,20,9E,07,F5,ED,E9,28,10,65,D8,F7,01,0D,2B,42,61,43,6C,12,85,16,D6,10,71,7A,F4,77,E1,E8,4C,87,A1,0C,1A,8F,70,3A,C6,5E,F4,BC,6A,AE,D8,00,1F,F4,90,C0,21,0C,1A,76,38,99,42,00,24,45,D5,21,4E,6A,AD,41,78,6C,AD,14,2F,F7,8D,F5,E6,E1,2B,BA,07,0E,AC,D1,DC,33,D0,98,72,75,6E,0A,26,FD,30,38,88,5E,D1,6C,C1,A1,59,F6,26,5F,FC,2C,A2,83,64,F6,83,9A,7A,8C,9F,83,02,4C,2C,94,31,12,86,A6,AC,3C,1B,3D,7F,BB,6B,E5,4B,DB,BC,57,A8,12,80,61,1A,B1,63,4E,0A,5C,4F,7E,AE,A1,EC,CC,EF,B2,B6,30,5B,B7,FA,48,A9,8A,20,C8,A8,9E,C8,E8,FF,16,9C,A8,5E,50,6B,29,C1,51,AF,A7,85,6C,9A,87,14,9D,07,F4,B8,FA,E4,0E,B8,74,6A,DD,AF,8A,C7,3B,56,95,4A,BB,2F,5C,95,B9,D2,A0,1D,D4,8C,F1,67,4B,DC,60,BB,AD,11,B1,8A,C5,2E,F2,80,31,6B,B3,FB,2B,EC,05,62,9E,17,A7,47,0E,77,9A,2E,B6,AC,5C,E1,35,61,46,F7,BA,B4,DF,73,7B,2B,02,F0,4E,4D,0B,95,24,29,27,C9,D5,9F,32,C1,25,BE,3C,AE,A3,B6,1D,38,FA,4F,51,44,B0,58,D1,7F,A6,4C,61,6D,80,CC,1C,F9,6C,2C,01,72,A2,30,8F,14,59,ED,3D,14,E6,21,AC,C5,85,8E,61,23,CE,8D,09,DD,FF,17,FE,AE,7F,BD,BD,CF,CC,C1,7A,BF,DF,2D,5D,3B,D8,9C,25,2E,B2,05,6F,77,9C,07,00,05,21,B0,19,BC,CF,87,6D,26,0E,5C,CF,8C,A5,FC,00,DC,22,EF,12,1C,1F,34,9F,C9,1E,4B,77,95,C0,35,C1,72,5E,9D,14,CD,19,6F,F2,AC,5E,5B,76,A5,20,D5,D9,12,06,9F,7A,18,AC,CF,22,A7,3B,3A,65,63,C5,ED,A1,45,43,44,1A,11,02,4C,BD,4A,E4,F8,10,9B,D7,AD,64,B1,B9,B4,34,EF,11,4B,BC,E6,F1,AC,35,38,9E,4E,F9,38,72,25,3F,19,7B,72,CB,C5,FB,5A,BE,3C,8F,96,8F,D3,3C,52,03,3B,73,ED,D1,2E,16,06,56,72,75,E5,B6,2F,9A,39,07,14,A5,BB,4B,59,24,58,58,19,63,61,D0,F3,75,A6,3F,62,AE,64,5A,3B,27,EF,71,0E,3C,BD,1B,A1,5E,B3,F0,F8,F5,CB,F3,B1,0D,7D,99,CF,24,A1,29,DD,8E,BC,20,0D,F0,4C,6E,B7,45,87,DB,43,F9,55,EE,3A,6C,E3,98,FB,DD,91,F4,4E,F5,DB,94,F3,D1,9C,AF,4B,3A,A0,24,3D,CD,E3,6E,EF,E9,69,34,40,EE,5E,49,53,6C,CB,54,52,D4,17,03,5B,76,CB,EE,B6,12,F1,6B,3A,6C,CD,00,47,59,7F,F7,5F,16,FB,71,3D,0E,10,C8,10,CA,CA,BB,9F,C5,7A,3D,95,D5,5C,43,0E,88,F1,4F,7F,05,28,03,63,51,C6,1A,BA,A8,06,F7,71,6F,FC,0A,AC,9C,0A,9F,43,68,7A,8A,FA,04,7D,9D,CA,F7,19,1A,03,DF,8B,13,E9,F5,B5,2F,10,B8,0A,DD,4B,90,3E,EF,59,F0,F2,36,F7,BA,B4,1A,B8,B6,5B,1B,78,B8,5E,13,C6,F5,21,D2,75,96,65,CB,0F,F8,D6,3D,1E,83,B9,56,B8,A3,28,18,9E,3F,5A,22,B9,6C,7A,69,47,96,81,BE,99,66,F6,26,19,3B,20,C4,E1,5F,43,31,FE,CB,45,3A,BD,B8,2C,B7,B7,16,BC,F0,63,E8,BA,1A,0C,23,06,4C,81,E0,DF,EF,90,15,DA,31,EA,81,38,4E,3B,B4,97,9F,90,F4,BB,2D,3D,D7,40,8D,7E,02,1B,47,11,D8,4C,87,FC,70,66,22,D4,06,55,F3,50,99,68,66,2A,44,0D,56,CC,AC,E4,F4,57,B9,93,CE,EE,4B,1D,A7,5D,AD,0B,B8,2F,F2,AB,A3,F6,7A,AB,0E,79,7B,9A,C3,72,57,9D,FB,10,A1,D3,6F,B9,A0,E8,54,BB,8D,F7,08,23,28,03,D1,41,1E,BB,EC,D1,00,A2,E3,E7,39,E1,F9,75,3D,85,BA,A5,6F,36,70,B4,92,98,74,57,98,BF,DA,CC,6D,ED,A5,CF,7A,04,C7,44,FA,EC,05,80,6C,D6,29,CA,C8,42,87,B4,54,B3,B3,B8,9B,C3,C1,63,17,8D,76,72,3E,4B,0B,AC,89,0F,6C,4E,FE,E3,30,A8,7A,47,F6,12,EB,FB,7A,5E,4B,D2,A5,79,C5,7E,2E,AC,74,C9,24,7C,AB,F3,02,90,2C,41,AB,79,9D,41,DF,41,96,C3,F5,71,CC,31,F6,28,FA,0E,27,A5,5B,17,D7,5E,7B,C5,0B,69,29,FC,51,A2,70,96,00,7A,F6,9F,13,5C,39,FB,04,7B,80,E6,92,34,79,7F,2B,39,03,6D,92,E3,69,D0,48,D8,EE,BD,7A,5E,AD,3A,EE,BC,4E,AE,2C,EF,1F,22,7A,5D,5E,54,84,6D,7A,B9,17,E2,EC,E0,91,A7,96,5D,B3,A3,AE,4B,0D,AF,7E,E5,3E,53,1A,8D,96,B9,A9,BB,3C,5A,90,C1,F2,B0,13,2F,A8,BE,25,6C,7F,2A,5E,29,1B,49,4F,1F,CC,A4,76,85,9E,AD,C8,42,98,84,5C,4A,A2,66,B6,E4,75,0B,01,5D,51,40,EC,BD,95,F3,99,9B,09,38,9A,F7,25,3E,2B,CC,E3,DF,FC,18,38,8C,E7,AC,F1,3E,8F,95,F8,DD,B3,0F,0A,C8,07,E4,18,A8,EC,A0,AB,76,76,0A,57,87,80,BD,6B,21,62,E3,47,77,F2,B4,E7,E1,B8,BB,30,57,7E,93,FE,27,FD,57,AE,66,52,93,6E,38,B2,40,81,81,46,52,CB,35,D5,BE,9A,F6,8D,7C,B0,E1,25,D8,8D,FB,DD,92,3C,88,CB,6F,B7,FE,0E,56,C1,7D,94,9A,FB,AD,89,E6,16,91,2A,C4,E0,DC,9E,99,D6,5D,FE,4F,B4,B8,BD,C8,70,47,B3,97,9E,92,2F,8F,7E,9A,6D,95,30,D9,B2,1F,B7,3B,65,AF,76,98,07,28,1A,EE,C3,19,71,4C,87,73,F3,68,B7,C5,9C,93,6A,69,30,B9,90,D7,F5,ED,2A,CF,81,FE,24,8A,6D,B0,DB,61,97,95,BC,92,83,9B,39,32,77,EE,85,E2,39,96,1A,69,9D,F9,72,AD,2C,D8,C2,58,02,53,E2,51,46,42,FE,C6,9A,A2,E1,3A,EB,F2,50,EB,63,F1,25,DE,81,F8,E0,41,68,FF,6D,F4,07,EB,85,00,5B,5E,BD,0A,D0,75,5A,26,20,8E,A4,66,6E,AA,2E,4D,8A,B5,3E,95,7D,A3,91,0E,61,03,91,00,75,B6,6C,4B,68,32,2B,33,2F,1A,48,56,B5,F6,37,B2,95,C9,5C,E2,D8,F5,46,D5,77,51,7A,69,A0,F6,F3,F7,AE,29,14,C5,C1,FD,1A,D6,11,CA,74,86,70,06,27,95,8B,7F,D3,A1,59,67,05,77,A7,D5,3F,28,3D,73,97,7F,BE,29,FE,A5,8B,73,23,1F,67,5D,3F,C5,5C,5D,F9,DE,65,4B,92,24,9A,72,37,A0,56,C5,E5,91,0E,50,0C,9D,58,C8,74,A4,00,F5,C1,86,BE,CA,05,3D,C9,06,F3,7C,4E,37,3E,6B,CE,9A,DF,ED,57,8B,F1,1C,DA,48,17,DE,55,67,42,46,DE,CC,47,E8,2D,0C,38,45,C1,59,BC,FC,30,1A,C9,FB,3F,3F,99,FA,90,8F,88,6A,AD,4B,6F,97,9C,1C,23,43,60,3F,7B,63,EE,17,45,7B,66,21,54,CF,06,A4,02,D7,4C,14,BB,F5,F2,DC,99,7F,BE,48,56,EB,14,00,53,DD,84,95,09,56,50,9A,FA,96,A3,A0,AD,26,D2,AF,2C,16,E3,B4,C6,B2,67,94,4A,B8,F4,B0,20,33,A7,93,21,08,59,51,C1,04,DE,64,CF,4A,B2,98,46,2D,B8,55,91,A3,9D,DF,10,4A,4B,C7,42,DC,94,A3,01,95,E4,91,12,4D,50,55,AF,30,CD,D4,3A,B4,88,DB,4C,A4,01,04,21,EF,6C,69,BB,A0,95,A9,B1,B5,56,E4,56,20,FF,18,06,CC,39,E2,E6,EE,8A,52,8D,CA,4D,A5,C2,4B,3F,48,26,16,44,09,8D,5F,F1,DD,05,E6,49,6C,08,62,11,B8,8E,BC,C5,94,9D,F0,B3,E5,73,11,C2,D8,F9,C0,DB,FA,42,80,85,49,3C,6C,8A,1A,D5,F3,BA,11,65,D7,8E,61,68,E3,2B,C7,73,FA,A0,BC,18,1A,91,AA,9B,FF,83,37,D5,E3,E6,A7,79,2C,89,F5,0A,B2,AC,37,4F,C8,35,F7,11,A3,A6,AB,24,F6,C7,F4,55,7A,0F,A0,43,C0,85,0A,E3,9D,B3,51,4C,E8,71,CF,29,A1,05,57,46,57,18,86,2F,48,E1,6E,BC,E9,AE,54,D5,7A,22,BC,D1,BF,BB,94,24,71,B5,A0,06,68,6E,F0,3D,9B,3B,9A,04,59,2F,36,11,79,09,9B,70,6F,4E,55,69,BB,C9,EF,6E,74,9D,C4,8F,64,3A,B2,19,DE,FB,4B,95,51,01,F2,CC,D5,AF,9C,19,70,B9,9F,53,CC,FC,18,AF,72,F9,69,16,9F,5D,0B,CD,58,D2,26,BA,ED,C7,01,AD,53,80,93,71,54,7C,23,9F,5C,CB,23,79,EA,67,1B,E9,AE,AD,F3,4C,D1,95,DE,0E,8F,D8,D4,F2,69,9F,79,68,8E,1F,92,7E,0F,1B,B8,2B,A1,2F,5C,DA,BC,5D,AB,F9,19,34,03,CF,40,83,55,9C,FC,B9,D0,C5,6E,08,17,B7,7D,EF,6F,AE,08,14,71,E6,DB,9A,9D,E6,5E,D2,56,C0,BF,96,FC,80,72,D7,28,C3,E8,03,BB,FF,FA,82,DD,68,3F,7F,0E,B8,54,88,A1,92,E1,28,31,AE,59,A4,F4,CB,7F,C0,4E,17,E5,43,48,9F,53,17,4F,83,3B,98,B8,80,B8,22,03,83,40,70,ED,55,93,67,50,C1,80,84,AA,51,37,90,6A,58,CC,79,4C,C1,D7,68,BC,BF,B2,49,85,5F,BA,15,FE,06,15,9B,E4,5C,93,C9,DD,C1,4A,92,12,DD,11,CC,52,26,B9,1C,8C,DD,A9,5D,E5,6C,D3,06,CF,4E,8F,22,D4,17,A9,37,F3,A1,83,8C,85,71,88,B1,C4,ED,0A,88,1E,F7,EC,14,7C,90,19,B5,DF,C3,73,CF,48,4D,05,D5,E2,84,1E,76,9E,4D,C4,48,37,58,57,42,4D,D5,63,C5,23,4D,F7,50,60,D9,C1,FC,85,42,C1,92,A2,CF,A9,7F,F5,A3,7D,BA,39,72,63,11,EE,DB,90,72,66,27,07,FA,0C,87,E9,74,D3,25,5A,CB,25,68,95,DC,79,CF,A3,CB,5E,04,CE,34,C2,09,AE,38,87,2C,D5,F1,66,BA,93,25,17,DE,74,80,F1,5B,0D,A7,DC,DE,CD,94,CC,E1,52,72,88,45,2B,CC,67,EF,0E,6C,8D,56,29,97,8E,42,4B,58,46,86,CC,D9,08,C8,2B,BC,B5,3B,6C,A7,3F,C0,19,F5,5E,30,0A,46,7D,8A,3A,2A,5C,26,97,B9,34,DD,9E,C7,8C,54,32,35,2B,2B,77,F1,D8,72,4C,01,D1,42,E5,9E,BB,17,64,E7,C1,29,5D,60,B9,CF,38,E0,3A,30,F2,C0,5C,EE,19,5C,B7,13,D9,87,3C,73,33,BE,D0,F1,5C,A7,67,0F,35,F1,50,23,00,F0,D7,75,51,AB,98,0F,59,80,63,46,0A,5E,B4,8E,4B,BB,54,59,FA,CB,88,F1,8C,2B,92,CF,D6,BE,CD,88,84,DA,D6,EE,F1,49,E8,EB,29,7A,AF,6F,C4,64,D1,4A,05,F9,45,6C,52,48,86,B2,27,62,D0,8C,4E,AD,5C,2D,05,63,FA,DA,80,AC,E1,E1,62,71,C1,48,49,F3,72,5D,02,59,7F,22,AD,4E,71,81,9F,13,D3,F2,1D,FD,03,34,9B,98,7D,18,AD,70,60,C2,01,70,7F,DF,EE,49,F1,79,1C,06,06,01,BE,DB,1B,78,39,46,54,AD,07,B6,6E,9D,D9,F6,D3,5E,45,92,96,0D,59,00,EA,23,8B,30,FE,84,A4,F2,BE,D5,70,AC,CB,C0,23,E8,D2,04,20,4A,79,CB,75,DA,DB,6B,09,37,E8,48,6D,E0,0B,6C,B9,50,B3,B8,D2,13,BA,8D,6A,1D,5E,2F,3F,A0,DC,9F,CB,67,59,4E,26,3C,1C,94,F7,52,EE,99,95,9A,53,8A,9C,26,FE,2A,6E,6B,D8,70,A7,4A,F1,89,2D,B3,52,52,BC,BD,A5,FF,74,CE,FE,F1,F0,CA,FB,3A,21,5D,67,41,66,B0,D5,C2,D8,64,F9,1F,DA,34,ED,A8,6C,7D,3A,03,CF,D0,10,93,D8,BA,DA,F7,8C,D8,46,5B,0C,01,FF,87,81,94,85,2B,CD,F0,12,61,D4,C6,92,0C,6B,9E,AD,D6,32,0D,BC,86,4E,52,04,60,A5,D8,03,CC,7C,77,EF,F0,EB,37,CF,0D,EC,E3,E0,AF,1D,F9,E2,DD,83,76,44,7E,6E,80,87,E1,68,5B,86,AA,19,09,3E,1A,48,72,1D,D8,B4,7D,8A,5D,F1,FE,71,A9,3C,4C,A6,65,45,C1,A9,6B,40,ED,EC,69,71,25,76,EB,63,0A,8E,FB,11,D2,0A,48,1E,11,F3,3C,28,F3,29,00,BA,91,55,D7,96,2A,81,01,B6,AA,B8,8B,2E,07,AE,EA,29,33,72,1A,90,23,6C,1E,B6,B7,49,26,07,03,25,EB,34,54,C2,25,44,C7,32,4F,D9,5A,41,61,32,EB,F2,45,63,93,A5,14,9A,B6,5E,F1,DC,9C,88,26,4E,FF,28,B5,F7,14,51,C8,74,EC,6A,CD,14,41,F9,F0,A5,A2,95,34,95,18,9C,CE,D8,F9,59,16,7D,1F,2B,22,7B,6F,4D,BF,13,6F,04,E7,20,9F,9A,1C,43,18,31,52,C5,E3,5D,8C,E6,6E,3E,08,33,C9,48,3F,41,52,5F,65,80,A0,97,F3,E3,CB,20,31,E5,93,FB,DB,21,92,26,17,1B,96,2A,3C,87,EA,31,9C,F8,FD,10,E9,9B,2A,D8,EF,98,4B,F1,01,FD,5E,72,FB,C9,59,48,57,24,1F,FD,23,FF,C5,C0,08,E3,B4,B4,92,21,D0,F1,B4,B6,DC,12,59,6A,D7,18,52,AB,BF,C2,C0,C5,1C,BC,E3,10,09,6C,01,57,F1,37,D3,1F,C6,13,01,39,16,D0,1A,12,E6,2D,61,86,E7,BC,1F,F2,A1,B4,AF,15,B4,31,33,0F,B5,88,4D,EA,45,09,FC,2F,55,23,DB,96,0A,77,CF,7D,8D,2A,4D,17,B8,2D,A8,84,7D,24,F5,46,09,94,9C,88,E0,EC,CA,34,38,B6,67,B8,DB,CD,C9,CC,A8,E0,70,03,83,D5,BB,88,14,B4,16,20,65,52,6A,5F,85,13,43,E2,AE,D9,7E,55,F3,C4,F6,0D,B8,7F,C6,B5,AD,C0,E5,05,AE,5E,80,C2,95,FA,4F,88,23,A5,96,D6,87,C0,0A,C0,31,27,AD,29,A8,0E,3E,42,F7,36,9C,F4,89,36,98,E1,91,A9,89,BE,8D,89,CC,AB,50,3E,D9,95,E9,94,75,6E,90,20,B9,33,6D,A8,30,A6,71,E9,59,A1,C8,82,C6,03,1C,15,A7,D1,0E,D4,4F,57,7A,36,2C,24,F3,5E,F3,D6,5D,C2,88,A8,50,E6,9A,D9,71,41,B1,D5,98,F4,0A,F6,DC,2B,39,81,A5,3F,DD,C6,19,92,6C,79,66,BD,6C,77,DA,0F,F7,89,7F,F7,D9,CC,22,F7,54,FE,8C,91,D8,0E,F5,2B,92,74,3D,F2,9F,E4,48,DA,37,03,FF,E3,FA,57,61,D9,66,75,33,BF,67,9B,5D,3E,AB,8A,28,5C,33,54,38,F5,E5,18,4C,B7,F6,FA,86,F5,A7,61,66,54,7B,8F,F5,1D,17,CD,AD,B9,CA,1E,38,97,43,AD,C1,A5,FD,96,9F,EC,8F,3D,B5,8C,9C,EE,7E,AB,26,63,BD,5B,CA,41,03,76,69,78,EF,A8,06,8E,29,3F,42,7C,1A,72,B5,B0,36,BD,A9,8B,1D,CA,FF,B0,91,59,4D,5D,D3,80,33,2D,69,CA,74,98,1A,B4,BD,76,28,80,59,D9,92,4D,1D,2F,7E,98,D3,E2,F9,4C,D3,4A,44,F7,8B,02,64,AE,7D,22,B7,51,84,2D,3A,A3,AB,FB,19,A7,01,DA,90,EC,5C,C3,0E,14,17,7C,1D,7A,30,98,FB,D6,79,BD,8A,65,9B,24,1A,03,D0,7A,1F,0F,EC,3B,6F,D6,EB,08,6B,89,87,4A,64,9C,1E,8B,47,56,71,B2,88,49,6B,45,A8,13,7F,03,29,97,EB,91,8D,80,31,E4,F0,3A,B6,6E,F8,E8,C3,4E,4C,A0,A9,06,16,06,BA,08,92,58,20,0F,C2,A4,8A,7A,B7,3A,F3,A0,CE,05,5A,6D,26,39,30,C8,EE,F4,86,D4,FA,01,1B,2D,DB,76,76,72,31,1F,70,CE,EF,52,39,CD,8E,63,C6,85,98,52,4F,07,0F,5C,43,B8,C5,93,E9,89,2D,5B,A4,7B,60,F6,77,F0,0B,26,94,9D,94,CF,DF,6E,FD,13,CA,C9,19,C1,D8,8A,12,B0,B5,40,58,73,26,D3,7C,C1,C1,27,ED,09,67,9E,E6,A1,31,A8,26,C3,DA,7D,00,0B,C3,2F,D5,96,F8,92,55,DA,B9,83,21,1D,3F,A4,DE,D9,0D,E8,A2,9C,06,4E,A4,E6,1A,CD,0C,FB,EF,A0,1B,F0,5E,50,3A,82,35,74,86,CB,AF,08,DF,5C,02,EC,B6,05,4A,2F,D8,14,EC,CF,6D,A5,48,FD,C2,7E,56,B8,93,6F,73,BE,A1,36,E3,91,31,87,0F,16,CF,DE,0F,CA,FC,1F,D3,C1,48,FF,77,98,46,E4,92,EC,BC,88,3E,11,5B,54,14,EB,9D,91,92,4E,4A,1D,A7,6E,91,68,A0,03,3F,71,42,F6,2E,56,AD,59,04,E0,15,53,D2,E1,26,67,B6,62,BC,90,87,66,9F,91,C5,00,C9,E7,12,37,04,4D,DE,4C,A0,41,B1,30,AD,97,6C,EB,E4,C9,27,AE,DD,50,C3,0F,58,EA,48,A4,80,8C,39,04,46,F1,CF,F4,E2,64,63,BD,62,C4,A8,EC,1F,A0,B9,A7,9C,7F,05,38,24,E6,3A,1B,81,D6,38,7A,FC,42,E1,6E,4B,19,41,12,0F,E7,A4,B8,9D,06,88,06,44,5B,70,55,59,53,E0,74,9D,12,C4,F1,24,2D,B0,8B,26,FD,1F,1D,0F,E8,1E,7A,86,5F,D7,FC,9C,8C,93,82,FC,BD,05,44,67,CA,41,12,73,17,EE,32,B4,16,E7,2E,52,22,96,70,A6,2A,18,32,BA,A1,BA,90,58,65,8D,E6,2D,8C,BC,59,54,67,FD,1C,21,19,E2,3B,76,E7,64,2E,C6,EC,1E,E8,D8,62,55,C1,37,04,79,CD,FF,59,98,A3,36,BC,44,C0,20,AB,28,C0,56,B6,64,EF,C9,DC,3B,53,B8,06,5C,0C,20,7E,4A,49,6D,3B,64,42,C5,91,DC,49,33,8D,33,EB,74,4C,DA,8D,FF,F8,EC,5F,D0,5B,D4,68,9B,D0,2C,53,14,BD,AE,4A,A7,CA,1D,50,4C,2E,F2,8C,88,B0,94,15,38,CC,FA,9A,0B,7A,39,0E,FF,68,2F,09,30,B2,F7,8B,34,2B,48,4A,88,07,BC,FC,C4,B7,CE,F0,FC,AB,F8,DC,65,1E,55,30,13,91,0F,A9,59,E1,19,78,4A,E6,D0,0D,02,15,19,CB,94,EA,DA,5C,DF,AF,15,5F,63,AA,4F,25,55,18,63,D3,C2,DC,56,7B,BF,9B,BF,6A,F7,29,4C,74,49,76,ED,7B,AD,1A,C6,BA,3F,9E,2A,C3,5F,CB,C5,3F,78,9A,BA,F1,A5,5C,9C,7B,98,F8,75,20,FA,A7,DA,4D,36,7E,6A,3C,64,CB,E0,37,9B,81,52,86,42,B7,1B,A9,91,D1,ED,A9,F7,E2,E4,1E,7B,43,B8,AB,31,85,D4,40,6F,A8,3C,53,43,14,65,32,1C,EB,99,7F,07,BD,A8,BB,F9,62,3A,A9,57,99,DB,EF,D5,E6,C6,62,7A,D7,E6,42,B2,DA,47,A8,5E,9D,75,D1,B3,AE,9C,18,1E,B0,F0,DE,6D,4A,BF,33,6B,B1,A6,84,79,66,8B,E9,61,E3,A2,95,36,D9,25,E5,BA,9F,D3,BA,10,6C,74,C2,45,E0,D7,E1,F0,EB,A6,26,D2,CD,6F,E0,4B,3A,3F,19,1F,54,72,D8,B7,D5,22,DE,8D,4C,5B,3A,39,E1,37,37,A2,3B,0D,DD,CA,61,DA,3E,89,7B,6F,45,64,4D,9F,D5,2A,E0,E8,24,C1,9C,C8,D1,88,D5,14,DD,30,8A,24,F7,12,8B,CB,01,CB,26,26,BF,1B,58,6D,AA,EF,B4,CC,2E,37,BE,B4,64,FB,6B,8D,A6,59,71,70,24,DC,95,E8,AB,79,0D,AE,56,6F,4A,79,20,F3,A4,DD,D0,52,22,7E,A7,A8,82,2A,C0,61,77,13,B5,77,65,6F,6E,A8,D8,6D,55,7F,D7,D9,90,6A,F1,1A,2E,D9,BB,BE,29,95,57,EA,9A,77,4B,BB,FA,10,63,17,2E,61,91,84,21,42,7F,96,24,41,64,86,9A,5F,DA,18,C4,79,D2,F2,C3,C5,43,79,0B,D5,9E,84,66,67,81,96,29,3A,E9,0D,C2,6E,EF,83,A3,10,E0,2D,B8,33,1B,8F,2B,57,5E,BD,D1,FB,74,C1,77,2D,D9,88,AB,38,DE,81,D8,73,37,3E,A5,7B,5F,B6,FB,27,D5,88,8E,34,43,42,A2,EA,B8,50,C2,78,73,7D,03,92,02,77,6C,B9,A2,D0,D0,47,25,DC,DD,EA,64,C4,DF,24,F5,66,81,D4,86,1B,48,46,2C,2B,CA,C0,68,CF,3D,AB,18,17,E9,C3,88,15,40,4D,B8,97,D6,A3,21,8E,E8,F8,72,75,37,5B,88,B1,01,DA,75,92,54,08,D5,CE,E8,0D,AB,67,74,1C,66,CE,5C,FD,8D,89,1B,D1,7F,1A,3D,E8,CF,3A,59,B4,16,DC,6C,2C,7B,B9,F2,00,15,E6,F8,5E,AA,3A,B4,57,40,8A,AA,12,6F,8D,6A,BE,68,79,6B,FA,3C,F8,CA,88,49,FD,EE,70,C3,1F,E8,4B,CA,31,D6,16,40,58,58,DB,FC,81,84,ED,C8,EB,27,65,5D,0C,A0,43,87,24,D0,4E,A7,75,13,36,EC,B6,7F,7E,E4,0A,3A,89,13,23,D0,9F,09,12,1A,67,95,62,69,46,BC,FB,CB,0C,EA,85,BB,A6,6B,8B,91,78,E9,0D,EB,D2,32,83,0F,A8,C6,3D,90,A9,FA,DA,D2,EF,59,32,36,84,4C,5B,F7,59,62,E1,21,AC,5E,27,ED,F4,2B,AB,C1,CF,C1,5C,0E,D7,68,55,1C,58,30,CD,20,74,FC,D9,0D,C5,23,90,91,3B,01,59,E7,2D,5E,8E,4D,01,3D,EE,54,44,10,7A,D7,A4,5D,45,02,A5,2E,09,79,ED,C9,A9,65,16,B9,A0,03,03,D7,FE,28,11,EF,93,7C,55,A2,FD,09,1A,F5,09,DB,5A,92,4A,CF,F1,30,4F,ED,A4,7F,C1,43,66,35,01,BF,CF,57,67,D3,03,26,58,E8,1E,2C,C5,AF,FD,EE,6D,7D,75,0D,AF,F9,8A,B3,03,36,73,E5,AE,E5,3A,D8,F1,06,3A,E1,D2,32,F3,D0,E7,AE,9C,54,0C,41,D0,28,F6,D0,B1,89,AF,88,47,21,6D,98,66,8E,1E,6F,5A,FD,25,28,B6,7C,3B,E5,46,AF,3A,4C,58,F6,6A,03,0A,6B,B6,0F,E8,00,90,A3,8A,87,14,C4,11,2D,34,DC,96,DC,32,43,F6,9C,6D,88,E0,6D,E5,D2,7F,CA,FC,BB,F4,B8,E1,3D,EB,C6,FA,3A,D3,B7,80,E6,B6,4F,9F,C3,2F,A9,96,70,E4,C1,E0,00,0C,81,CB,93,5C,8C,24,23,95,CA,1D,27,1F,FE,96,00,8B,9B,65,A9,91,06,B7,DB,1E,BA,61,70,BB,39,3E,40,42,EB,BE,11,94,83,55,21,94,9E,08,50,28,E7,E1,47,5C,1E,E0,F5,74,07,5F,78,D6,83,65,57,56,1D,E2,73,F6,50,CA,8A,5F,AC,B3,39,E6,FE,15,CA,AC,96,E4,5B,D4,CE,12,2A,6D,68,9B,8B,04,70,A8,59,5F,74,7C,39,C8,A3,88,EA,A9,83,FD,1F,0E,69,D3,2C,D3,8A,41,5D,DC,E5,ED,8E,9D,E2,91,4B,1D,44,19,EB,A0,ED,C8,BA,9D,8F,D1,85,17,69,C9,F8,92,AD,31,51,B3,EC,8E,FD,21,E7,CF,ED,20,9F,55,92,CA,FB,54,64,E5,E5,C3,FC,42,87,C0,E0,F9,B9,CD,14,E2,58,3F,B0,74,F1,E5,45,02,DD,C2,A9,F2,A4,EC,89,46,1B,C5,FE,91,2C,FE,09,AC,9B,CE,6C,67,F6,F9,23,C5,C1,FC,B6,E0,3A,FD,05,37,17,13,67,84,79,39,BE,06,BE,CE,EB,A2,0A,AA,0C,02,D8,6C,A3,B9,91,56,D7,08,A8,FA,8B,70,0F,98,78,AF,E6,22,BA,26,9E,CE,95,A9,92,E7,18,11,9C,F4,3C,4E,87,BB,FF,54,87,AA,BD,48,63,04,72,46,6D,5E,06,96,19,BD,9B,14,33,08,26,F9,D3,31,B2,CC,60,28,89,BD,EF,A4,FE,A9,69,B9,52,9E,B6,25,A2,B9,18,E0,84,FE,50,18,45,0C,E7,3D,19,FE,EC,0F,37,1F,AC,80,31,E1,72,4F,ED,EC,80,C8,F6,13,13,FE,16,AC,61,98,58,FA,96,C9,4E,71,CB,B7,D1,2F,4A,A3,89,78,0C,51,EC,64,E3,20,05,51,77,2B,E7,B7,15,AC,07,E7,E1,AD,C3,D4,7E,BE,5B,0A,9E,71,E3,FA,7D,7E,97,6C,A0,15,D7,68,34,D6,92,55,17,DD,18,E5,03,C0,BA,53,16,82,D6,68,E6,EE,81,7C,A7,01,24,02,FE,A6,48,1E,98,E4,A3,7F,21,B8,0E,BC,A9,53,93,F9,96,CD,B8,E9,1C,7C,0D,3A,47,10,19,B4,7F,6C,6D,63,90,93,14,C9,A9,E1,BE,D6,B0,57,DB,8E,BD,EF,75,E8,17,70,68,D8,5D,64,60,8E,C3,A1,A7,18,91,47,88,48,C0,8D,B3,DA,B5,97,B8,09,F7,FD,27,D7,50,1F,BE,62,13,F3,C4,6F,B6,8A,D5,C2,ED,3F,B1,32,C4,BC,FB,21,7D,3D,30,1F,B1,9B,0C,D0,0E,50,BC,35,51,F6,0A,56,27,64,FC,F2,25,9D,3A,C3,E1,20,D7,64,38,9A,7A,A0,13,57,AE,32,9A,33,7C,2E,51,E8,F1,C8,90,1E,A1,F1,9F,18,5B,60,22,57,48,AC,CC,4F,FB,5C,B2,1E,F9,7A,4F,BB,52,A5,38,E2,1C,C6,27,AA,E9,57,54,7A,31,B8,9A,8F,DD,2B,7E,E8,5C,5A,B5,F5,97,B4,D3,87,2F,4C,FE,6C,AA,0A,9A,9A,03,01,68,B7,95,AA,5C,F5,AA,F3,F4,79,79,30,9D,2F,7B,96,01,86,A8,4D,38,85,16,DD,25,46,76,FB,3A,FC,5E,D7,C2,17,D1,85,68,97,BC,7E,46,4F,37,35,BC,88,2D,50,86,47,A3,C1,DC,D4,66,50,D5,1A,D7,0E,73,89,70,BD,62,AE,F0,1F,19,72,54,16,DE,2F,DB,6F,E6,B0,18,73,55,99,92,5F,7A,74,52,3F,16,46,6B,72,4F,43,43,24,07,CD,E2,9F,E0,DB,A4,9D,A6,52,13,3E,0D,F6,8E,A6,99,11,A9,2C,7E,63,DA,05,6E,F1,F2,19,50,88,79,98,58,23,DA,1F,3A,4B,F0,5D,43,E6,E7,37,B0,04,C4,AC,4E,81,F8,B7,6C,3B,90,E8,33,46,F2,D0,0F,5B,DE,C1,1D,EA,2E,45,FB,F9,CC,8A,B0,1B,93,6D,80,85,01,EB,CA,61,5B,36,1D,6F,E6,17,00,C1,7E,C9,2D,C0,8E,28,5C,4C,4A,0E,3F,2E,FD,25,04,82,10,B3,E8,45,42,DC,A7,CD,A9,00,E3,0F,27,63,57,1E,1A,F2,90,78,A3,2E,0B,17,DA,89,5E,CE,59,CA,56,F4,E4,84,53,0A,4D,09,42,03,53,A6,A0,4B,D2,F3,F2,18,0B,9D,DC,8A,25,F6,F7,76,30,92,3E,2F,AD,54,E4,AD,02,3E,2E,97,67,CC,F8,8B,3C,87,C8,77,2C,6E,9F,63,5D,C6,9F,E9,3A,4F,00,BB,9D,D1,56,1F,A9,C4,13,F5,C7,DA,8E,C0,BE,70,B2,4E,B1,51,39,FD,EA,3D,41,40,FA,31,26,48,C1,C6,93,98,CE,E0,80,D9,89,3B,7B,AF,76,94,A2,16,2E,E8,D2,16,98,D6,3B,14,90,AD,3D,9D,9C,51,B2,41,74,BC,1D,90,09,45,CC,C4,F5,A6,13,85,E4,F1,83,3E,E7,CD,06,21,47,85,36,89,D4,D4,06,2D,33,1D,EF,6C,D4,96,84,F8,A0,1E,3D,4D,71,5B,81,C1,88,6E,F9,7F,3F,03,BA,CF,C4,7C,8F,E1,A6,A2,52,8A,D9,58,B6,E7,29,C9,88,BB,22,7F,B7,AC,72,6C,E0,5B,F5,BB,2E,5E,50,4D,60,B8,FA,1D,11,DC,AE,FA,DB,92,DD,6D,2C,66,81,AE,60,82,ED,F8,02,A2,B9,37,A4,CE,CC,50,F8,E6,EA,DC,73,8E,74,C4,2B,1B,C8,31,14,4F,8E,45,10,BF,47,0E,7B,BE,1D,1C,4C,0C,85,11,67,39,A5,3D,3F,D6,00,FB,00,68,B0,16,76,5A,CF,81,5D,2B,F0,42,52,29,72,87,3D,2B,22,84,17,1C,CB,69,F6,21,86,49,2E,CF,3A,C5,10,B1,5F,B1,63,59,B5,9B,A5,F3,2A,A1,28,A4,16,3C,DD,B1,1A,7A,D9,88,8D,A5,23,04,0B,F6,90,56,06,D0,86,1A,B2,D9,55,82,2F,3B,DB,07,DC,93,4A,6B,AF,84,47,52,47,B7,9C,1A,4D,82,A4,79,AD,B6,EE,28,39,38,19,A5,FC,43,D9,7A,4A,CC,7F,AD,54,5A,BD,F6,9F,F6,25,7D,BC,83,89,00,C0,CD,DF,09,05,1A,66,25,9D,A0,88,74,22,62,6A,E2,C5,A7,C9,E6,D2,02,0A,0E,A4,82,7F,1B,30,BC,51,3B,DE,69,88,39,63,9A,60,B4,7F,57,4E,4B,F9,EA,BB,78,DB,D2,A4,EE,5C,9A,88,8B,F7,B9,73,98,95,D6,7F,23,D2,33,5C,EB,53,FA,8B,91,D5,5F,5B,9A,33,61,52,E7,B7,EC,66,B3,FC,A8,19,FB,11,10,9D,20,4D,44,08,2E,7A,80,8D,E2,E4,BB,FD,45,63,7E,73,00,A3,70,0D,B1,6A,3F,8F,A4,13,C8,D5,97,5B,9C,22,3B,83,2D,BD,EE,B5,AA,23,63,64,3A,26,62,86,BC,FD,FF,D3,38,F8,5D,79,92,AA,30,0B,0A,0E,85,42,CE,DA,AF,60,EC,73,DB,8A,B1,4B,8A,D9,7F,37,93,A7,08,A5,C1,A3,94,39,B6,A6,F6,BD,F9,99,FE,A6,2F,F8,A9,0E,34,3F,E8,0C,35,04,A8,7B,F2,19,CE,DC,8F,14,30,3E,38,97,F6,A8,52,ED,A1,92,E0,4E,DA,9A,0D,66,5E,44,4B,41,0E,0D,C2,14,64,8C,20,37,62,3D,5A,4D,AA,2E,6A,2E,97,C2,4E,AD,4B,B9,E6,A3,35,61,9E,1A,30,5F,85,44,54,64,35,E5,0E,FE,9C,88,F1,3E,70,22,5C,1E,83,2B,82,C9,3E,0B,78,8A,6B,93,B2,5E,CB,BC,A3,CB,39,38,80,DC,79,6D,E0,26,1A,1A,A0,44,A2,03,13,F0,62,FC,EC,13,03,B0,DE,D6,80,E0,6E,CB,CB,59,79,5C,D5,19,9A,DD,A6,74,BB,35,EB,A1,87,EC,47,ED,1E,B1,1C,39,05,5F,FC,B0,C8,EE,17,30,64,EE,24,DF,61,DB,F2,11,81,EB,91,2B,87,4D,EF,61,34,FD,98,0F,16,B6,C8,80,48,9D,11,F4,A4,3F,E3,CD,FD,AB,8C,81,15,32,D8,21,98,D8,4B,88,65,5C,86,FE,89,2C,D8,5B,0B,49,0A,B0,79,83,47,B9,F4,E3,23,A7,F2,6F,1A,DE,7D,D4,EF,E6,82,CD,51,2C,9F,77,4A,EC,65,F3,5B,D6,F8,75,14,DF,52,D1,23,EB,09,E3,74,42,90,99,53,B3,15,80,DE,80,AB,FD,BB,F8,B2,70,BD,4C,81,BA,B9,E5,71,C0,0D,6E,58,61,78,CD,78,7B,7E,31,2A,87,A7,A5,40,AE,30,D5,40,D6,2F,E5,B3,5A,AE,28,72,0D,D9,6F,98,0E,29,42,64,A4,E1,D9,DD,E2,00,6A,5C,EE,00,99,94,03,2D,70,56,C7,51,70,30,1F,C7,F4,AC,C5,D1,F9,DF,FA,DF,75,1C,D4,FB,DA,B8,C3,4A,1E,F0,31,55,90,45,B5,4C,2C,BF,E8,0C,C3,72,78,18,19,4B,09,F7,07,89,39,95,85,07,34,F6,62,F1,5A,92,45,32,15,1C,9A,BF,6C,6F,79,AC,28,24,98,F7,4C,7E,6D,10,C3,73,27,79,00,C4,66,07,68,16,53,BD,B4,27,BB,77,8F,9C,E9,34,48,61,2C,EB,8C,74,2A,D9,3B,54,E2,F2,06,4B,09,E2,29,3E,0F,1F,A4,51,99,DE,74,5D,CA,1E,41,EC,DC,99,6B,2A,91,C3,A1,DE,B7,D5,98,E4,E4,93,3A,37,E4,B5,99,E7,EC,04,62,3C,CD,CB,81,32,98,8B,47,CE,A5,50,B4,FD,13,AE,D7,B6,03,FC,EC,BB,C8,77,8F,52,C9,ED,0B,FD,F6,5D,A4,E4,12,6D,FB,FC,7E,AC,AE,1F,89,18,2A,95,53,2F,10,01,2F,96,57,3B,31,C3,EB,86,DA,E3,54,C7,50,51,29,79,DF,A0,5A,7D,78,61,96,0D,18,39,30,1C,DD,03,8B,07,0C,82,E8,7B,46,21,83,2C,36,79,5A,AA,12,7C,38,E9,BB,06,FD,84,50,A7,28,0C,AB,42,87,C4,BC,D0,4D,76,06,48,38,44,D6,63,C2,AC,A2,AF,1D,87,75,47,71,06,FA,A8,AC,D6,EB,2D,AC,EE,A5,24,CF,3C,A7,B6,FF,51,73,5E,E4,BD,59,89,66,86,08,2E,E9,EF,D6,C4,8B,2F,EB,04,B7,9C,3F,8A,E3,FA,ED,C5,CD,E4,82,DA,FE,C0,55,74,C2,9E,95,AD,9F,C1,5C,03,A7,3A,90,23,6E,1F,68,07,FD,E7,E6,6C,EB,16,40,57,7E,C2,90,08,19,54,F2,C4,13,1E,33,BB,A6,CD,54,2F,0A,8E,A1,6E,2B,5E,B0,3F,B3,3F,1F,CE,AC,4B,FE,EA,86,29,70,4B,91,AE,71,6E,07,9D,C5,A8,07,CC,73,79,85,90,9C,EB,2B,CD,11,01,74,44,E6,2C,43,0A,DA,A8,03,0E,E2,EB,47,AA,EF,66,66,3C,06,41,39,57,94,3C,5E,65,9F,60,EB,D6,DF,95,84,A4,05,D8,6A,20,FE,BC,73,D9,AF,00,42,18,85,63,81,8D,2B,80,86,2C,78,9D,D9,E6,02,24,15,39,92,1C,25,EA,B2,2E,7E,9D,29,A8,5C,41,C4,08,13,C6,69,F5,CF,60,46,67,47,63,7D,D4,FD,C2,D8,9C,F9,0E,1A,24,CD,62,CF,2C,6C,22,30,B5,14,80,1A,B3,9C,2F,02,17,FD,7C,1B,F0,50,C1,4B,EC,26,A9,12,2A,EB,68,A4,E7,79,AF,00,74,D4,93,47,86,E9,92,FF,6A,21,FE,97,32,5A,4B,93,26,FC,EA,FD,08,B3,8E,0C,BC,9D,8A,5C,10,6F,2B,73,C1,EB,6B,C0,16,28,31,2F,17,A1,B6,E8,E6,AD,A5,93,69,57,29,BC,9F,A1,65,6A,21,85,5E,D6,2B,16,62,14,D3,1A,D6,35,C7,5A,00,A3,69,98,67,86,BC,AB,FD,22,DA,7C,F1,FA,E3,D8,B0,6E,AB,98,E2,87,E6,A5,73,1E,6C,F2,B7,16,32,61,4C,96,83,58,2C,A2,48,EA,3C,CB,4F,C0,69,75,BC,37,27,F2,EE,83,04,EF,20,CD,16,A3,5D,6E,69,A7,7F,61,B4,BF,68,74,7B,8F,30,B7,15,85,2D,CC,BA,F2,39,99,73,71,CF,62,D4,6E,41,AA,87,4D,98,57,D4,C2,DD,F0,1F,78,53,7C,AE,3A,82,6F,F1,45,31,E5,36,5A,69,0A,F9,33,C1,69,E2,3E,54,E6,26,26,9A,33,5F,76,9C,53,F1,7D,31,87,96,F3,A0,CF,F5,FC,3D,B9,51,79,AC,7C,2C,60,34,2B,65,10,29,38,2F,87,BF,FA,83,86,EC,2F,CE,94,E3,8A,71,42,EF,9A,28,28,76,21,86,A3,6C,BF,0B,5F,BD,49,94,25,C6,80,CB,D1,8B,5D,9B,C5,FA,44,14,41,28,FC,08,B7,EA,B8,CA,8B,A7,03,65,5D,81,97,F5,D6,CB,80,7F,E7,E3,48,2B,D1,F1,BE,21,B0,A9,77,E7,DD,05,80,B9,8F,F3,2B,05,A6,07,CC,5E,3E,F9,86,F8,DF,81,A8,80,35,A7,76,20,6B,E5,6A,26,40,27,80,A7,E2,B9,DE,E2,0E,90,CC,BC,52,7A,F6,42,B1,A6,73,9D,09,45,C4,A5,E2,99,2E,8E,D0,04,B5,07,0A,30,7E,96,B1,34,87,8D,99,3C,C9,5A,24,35,CC,82,79,46,4F,45,E9,0E,EA,66,D1,35,81,21,0A,86,43,B3,07,68,4A,13,35,3F,D0,C3,13,E0,FC,21,21,6E,7A,88,44,CE,BE,F3,57,9C,F9,07,44,0C,49,A6,D5,9B,92,5C,9B,09,D7,D1,E7,57,E9,38,D2,14,B1,20,50,FB,58,F1,CD,D7,10,41,1C,5F,2D,84,52,71,04,E3,A3,1A,94,1A,38,2E,8E,9B,8C,BF,03,99,AB,9F,E4,99,F7,CB,E5,96,F3,18,6F,A2,A0,83,61,9F,08,85,27,66,26,21,F7,CC,51,23,A8,E5,CE,DB,74,99,B8,2B,71,83,72,69,F2,E4,3E,30,DE,62,44,50,80,A2,1F,C2,1B,12,A8,48,F2,14,A3,16,77,00,6A,C1,87,5D,0D,A8,B3,7C,CA,51,FE,ED,0A,2C,31,BC,55,5C,FE,85,4C,11,F8,ED,01,6C,50,24,3E,10,CB,31,FA,B4,93,41,33,37,14,96,0A,63,18,70,9B,D3,5A,3C,3A,D7,0D,A2,88,4A,17,1B,B7,20,FE,A0,11,5A,37,21,32,E5,A7,F2,5B,84,AB,EA,F9,2B,22,8A,04,9E,1C,36,D4,D2,54,FC,84,DA,F7,9A,55,D4,B4,95,85,37,F0,2F,26,50,FD,59,D3,B3,93,75,37,5D,D6,30,8F,4A,E3,40,4E,66,70,30,3E,3C,52,43,0E,84,4E,80,DF,8C,48,16,41,30,86,A9,6A,37,4A,E8,70,F7,61,79,6D,3D,2C,80,BB,4A,3C,4D,B2,79,EB,8D,3A,E2,75,86,57,94,F4,8E,23,80,F2,3A,C5,12,58,92,27,51,D3,B1,7F,D3,74,D2,84,C0,66,6F,5B,66,0D,27,BB,57,08,A9,4C,74,F2,5B,25,A9,EB,9F,9D,02,D9,71,15,51,34,27,26,35,9C,77,24,70,8B,58,59,97,40,D2,94,1E,FB,5C,B0,E5,CB,A0,A6,4F,45,AC,77,26,2C,84,56,22,68,99,6D,7A,AA,91,46,29,5E,D3,9D,0D,0B,12,55,4E,C6,C2,91,14,F3,96,3A,CE,3B,98,2C,16,34,28,57,01,5E,A4,88,71,F5,02,33,90,EB,C5,BC,AB,E2,28,95,A9,BD,6F,15,AC,DB,D1,B0,09,2C,1C,15,0A,1A,FC,44,B7,84,EA,00,93,B0,7E,25,F1,B9,16,AD,20,F1,BF,4A,30,B1,FD,7E,E9,89,AB,14,24,67,50,2A,44,BD,AE,97,5A,5F,D1,7E,A4,65,46,55,3A,96,1F,F9,69,A8,8F,A0,E8,4D,DE,D5,DA,39,C5,61,B2,3E,1E,5F,D4,FF,17,A3,BF,09,DD,66,0A,C5,74,AA,5C,80,8B,47,32,87,1F,99,43,94,EF,5D,7F,96,9A,C9,B9,54,50,64,89,57,76,C0,2D,A4,B7,6E,B7,E2,8F,7D,90,4F,25,39,BA,11,51,AF,77,1D,72,AD,D2,3B,48,EB,70,A7,1A,9C,71,EC,25,AA,16,33,D3,A0,A9,0D,1C,63,9F,9A,68,F7,A0,BA,24,2C,52,82,1B,BE,7D,F6,7C,BA,76,BC,3A,74,6C,5B,BB,EE,43,70,C7,90,D7,AB,F7,53,AC,C2,85,5A,CF,F9,8C,9F,D7,D7,0A,94,B9,C7,1F,B0,BC,F4,94,93,60,67,C9,96,BF,CB,82,9F,5A,6B,A8,41,1F,3D,FA,35,60,5C,78,05,07,A2,D5,A9,D3,A5,07,4E,F5,92,64,CC,3F,B5,17,1A,BB,D4,FD,1A,A4,87,53,15,6F,17,F1,F7,7A,2B,A5,E9,EF,5D,05,FC,25,E6,87,3C,AE,E4,26,BE,5F,C6,86,12,27,EE,4B,A0,77,95,BA,58,41,06,0E,E2,E8,09,0D,47,75,8C,1A,F7,33,D6,49,CB,FD,E1,1C,CD,E9,BA,44,33,55,B8,E0,9D,4B,27,37,D7,D3,71,3D,8C,C1,55,D3,B1,66,99,7C,A5,52,CE,18,84,BA,7A,E4,62,8D,7E,35,C9,50,06,83,5F,0C,2F,6D,8E,A5,22,30,51,AF,64,92,EE,AB,0C,1B,C8,0C,03,8E,C9,D4,EC,52,86,3F,20,1A,AA,E1,32,19,CC,38,68,DB,09,3E,F4,56,ED,32,A9,62,7C,38,82,A9,66,C4,59,BA,BB,5F,AB,B4,FB,71,C2,42,4A,60,D6,D0,AF,E1,87,72,3F,C1,17,D5,54,13,39,4E,FF,D5,AA,C1,EF,40,AA,BE,8F,9A,0B,65,EE,74,ED,F2,EB,C6,AF,D5,AE,9B,67,F9,C1,23,25,13,1C,30,43,C0,2D,6A,47,10,8E,C1,A1,40,FA,13,73,0D,C3,6F,81,D5,E0,EC,12,DB,68,DB,64,4A,79,A0,AF,B9,4D,E1,D4,0F,75,D6,E9,5F,B9,F2,39,CD,9E,FB,73,DD,03,CC,E9,2A,B9,43,AF,88,96,B2,50,E8,EF,D3,B9,BE,A6,EB,F3,8C,82,E8,2B,01,75,DA,18,D7,04,80,B1,95,07,DF,F1,A0,41,7D,8B,DE,53,DB,8B,CB,D4,9A,90,41,29,6E,37,E7,0D,78,C8,4F,F3,17,30,FE,5A,A1,8F,73,14,25,76,EF,16,B5,AF,DE,6A,3F,14,27,7B,93,98,06,EC,15,34,90,B9,A2,C2,26,D2,C3,0B,5D,1A,BE,EB,64,20,EE,90,C6,BB,99,95,80,8A,95,CD,28,50,B0,C3,AF,3C,92,61,AC,D2,7D,3D,6C,4A,DA,ED,C0,CC,CE,54,DB,9E,A0,7B,68,D0,0A,C8,3F,A0,25,A5,78,FB,76,B8,E9,29,8A,C6,8A,69,B2,C6,49,D3,1D,A9,07,BE,63,96,36,AF,2C,65,22,47,F7,F2,3B,0F,67,53,D3,2C,02,B1,4D,AF,D7,DC,79,11,D7,43,A0,85,D4,13,A3,45,3E,23,FB,6F,DA,B8,2E,45,68,F9,E0,50,63,FE,CB,CA,ED,DB,5F,78,9A,05,76,1F,55,FF,94,D2,88,98,F1,F7,DF,9A,74,15,CE,EC,29,44,A5,C0,E9,B0,5C,A2,54,A6,6D,C0,F2,5F,A2,04,44,B2,EC,8B,EE,11,38,C3,D0,F5,08,C8,EA,36,CE,07,43,08,14,B2,B8,BF,33,E4,90,9B,B7,AE,F0,CE,A7,9D,61,BC,EC,51,27,4D,DB,54,43,14,06,E3,4E,F6,A2,7A,CF,C0,9C,8C,4A,3A,86,02,64,51,E8,E9,82,70,0B,AC,4F,72,88,E1,BD,58,8B,71,EE,83,3C,EF,59,FF,D1,E4,0C,B2,E4,00,B4,22,F3,3A,66,97,BD,D8,AE,33,B6,A3,92,2B,C5,47,4B,E0,23,FC,E8,B7,4E,9A,61,D0,CC,A0,A7,12,96,2B,8C,9B,B3,50,4A,F0,5E,05,19,B0,92,89,61,5F,5A,7F,97,D1,70,64,DD,89,E7,6C,3D,49,6A,7C,2B,CF,13,50,30,7E,1E,81,4F,2C,01,49,F9,00,96,86,79,FB,B2,95,71,F2,6C,9F,99,F8,76,5A,B8,87,1A,2E,B8,C6,A2,6C,3A,B1,53,5C,E2,C7,AD,86,E4,89,BA,B5,AE,66,C9,48,34,E4,E0,92,64,59,BC,AF,37,40,29,13,C7,BE,5F,78,E7,76,09,40,AF,98,98,CC,B3,FC,83,A5,EA,90,1F,20,4C,F7,14,EE,3A,4B,31,1F,3A,B3,B8,AB,70,A8,3B,73,AF,F4,41,34,B7,7D,FE,D1,D8,86,96,1A,01,7F,2A,CE,48,48,6F,B8,2A,8D,B8,FB,14,DD,6D,F2,7B,A4,82,A7,9B,8A,48,9F,8E,D5,BF,FC,C4,F8,8E,0D,A2,E6,5E,F6,DB,DA,01,D7,80,E6,34,EF,FB,43,80,F5,E9,60,D2,B9,B9,C9,7B,E4,FD,B9,54,E9,59,EC,94,E8,11,4D,F1,BA,84,89,63,43,D6,21,A2,A2,0D,19,20,17,98,4D,4B,17,9C,75,ED,B8,26,80,FE,22,F5,66,9A,4A,31,1F,EF,1F,4D,14,B2,0E,6C,22,09,A2,EC,F6,9B,1A,D2,23,62,AF,FE,9F,9E,FD,AB,2A,47,62,87,96,A4,95,BD,7B,A0,DA,55,9F,2C,F4,C5,51,64,1E,A0,8F,D1,62,53,F3,84,5A,DC,EC,15,15,7C,F6,7D,4F,58,5A,43,39,6A,9E,BE,9F,B3,07,B5,F5,F1,0D,88,87,D1,0D,E0,C3,08,92,2D,E6,E5,35,02,46,50,27,4C,F5,E4,C8,6C,0F,00,4F,2E,7D,38,A6,23,C8,25,A6,09,2B,11,EB,04,55,FB,A0,A3,58,EB,8A,EF,64,C5,D4,71,03,44,AC,53,CA,1E,B4,54,61,C9,A6,C9,B2,87,1A,56,CB,16,9C,20,C8,9F,06,3B,07,6E,91,D3,CA,B4,2E,76,4A,28,FA,2A,19,97,F8,3B,DC,2C,19,61,85,67,6B,D8,89,EC,35,AB,F0,0E,DC,A2,B3,C8,65,26,A9,3D,4C,13,6C,A3,0B,5D,0E,8A,03,AA,3C,B0,50,91,5A,C4,D3,C7,48,B4,A8,67,34,31,8B,62,8E,F0,3B,F9,9D,3C,32,08,D5,11,C9,FF,C7,8E,06,45,9C,5A,C7,5D,7D,14,D4,C7,6B,4E,27,8D,97,09,F7,F4,6E,5C,CF,EA,F5,10,77,7A,0E,D0,F7,F2,C4,E9,BF,A7,4A,89,28,C6,E9,95,FC,C8,EF,BC,F5,0F,0F,29,63,4E,21,FC,74,2E,72,A7,4D,5C,92,E9,7D,FE,FE,F6,C4,D1,9E,37,9E,71,E6,B6,B7,94,E6,F1,34,73,16,36,1B,90,A0,C6,53,A7,5B,F2,A0,C4,70,F3,BA,48,08,94,3C,0A,31,9B,F8,BD,79,8A,4B,1B,6A,D1,FD,77,8C,CC,1B,4A,09,82,30,52,87,45,AD,2A,DD,78,46,30,BE,CB,8B,9A,10,41,63,AD,19,70,2F,E8,60,E9,42,C9,4D,C1,EF,E4,39,7C,FA,7E,6B,79,42,BB,A8,32,1D,3D,43,77,1C,4C,DD,8C,2F,42,F3,5E,4F,81,4C,AA,39,8B,09,CC,CF,30,01,C5,15,AC,68,60,43,1E,09,43,49,9E,EF,15,D8,FC,BE,79,E8,B8,4D,F2,82,74,E6,2D,4B,FB,D2,98,99,B2,08,F1,9F,46,92,63,68,6A,D5,E5,D1,99,82,6F,7D,92,86,C2,E1,3D,CD,A9,10,AA,7C,61,0F,7A,B2,81,E7,C5,CC,2B,98,67,E5,E6,CE,33,E9,F5,C6,A5,4C,BB,BB,14,D3,6E,34,68,10,FC,11,14,82,C5,49,6B,DB,07,A9,AD,BA,35,59,BB,7B,D3,AE,16,BB,84,40,42,D1,AB,7A,F9,80,8E,76,FE,EB,C9,AC,96,99,2F,4F,79,1D,44,97,D7,F8,43,24,72,2F,8F,81,0C,47,19,04,ED,10,1E,6B,13,54,1A,7E,FF,9F,1D,11,26,C8,21,A4,23,FF,FF,2A,A0,7D,C5,ED,DF,82,AB,D9,CB,05,DE,12,36,F7,D6,F5,95,C1,3D,26,0C,5C,FE,1C,23,D6,B7,CC,D9,43,67,FD,D4,42,09,BF,7B,47,15,F3,5A,CB,0C,BA,74,E9,34,FD,76,B4,64,36,7F,25,CD,40,F9,69,C1,33,62,E5,FC,1B,66,B1,05,5A,00,45,70,80,9D,AB,D1,78,BA,C1,2C,51,95,0D,0A,ED,99,2E,94,B8,07,2C,C0,A7,C2,14,2C,30,9E,6D,0E,C1,8B,83,0E,D4,17,98,02,8C,2B,27,24,E3,8C,6D,4B,93,C3,A8,31,5B,4F,C6,01,D3,3A,D3,D2,97 -roundConstants_full = 23,66,52,D3,DD,AE,BB,20,2B,51,D1,DF,DA,58,84,BF,B5,32,51,FC,EB,20,6D,2E,C8,72,8B,78,E5,35,93,69,B6,AD,F5,09,4E,09,15,CB,A6,D1,4E,D0,4A,6F,92,15,34,1D,E7,61,32,09,F6,BD,72,94,C2,DD,DA,A4,A5,1A,2B,16,A4,25,C3,EA,B4,5C,04,CC,8A,0B,B2,28,5B,17,B6,9B,79,2E,AC,20,5F,BD,BA,D5,4E,23,B0,7D,26,A0 -keyMatrices_full = A4,C6,13,A4,43,CD,72,E1,18,04,D6,A9,38,FA,F9,21,E6,6C,9E,0F,58,1D,B6,81,A1,06,27,72,E8,C8,CA,9D,B7,03,5D,EB,10,CC,FF,3C,B8,F0,60,BE,3E,72,20,FD,41,B5,05,ED,A9,8E,7F,2B,69,77,7E,90,C1,C2,58,77,1F,58,34,74,AE,B9,0C,43,14,6F,B2,9A,11,DD,68,B7,6C,46,57,0A,83,59,CD,88,D5,4F,99,99,73,6C,27,F7,B2,20,26,2C,A5,B2,95,E4,E4,35,3F,79,C0,18,60,30,CA,45,5F,2F,0D,C1,E4,09,69,26,56,9E,23,F5,D2,02,F4,C6,82,40,58,E2,35,87,21,0B,A9,78,93,E6,D3,4E,4B,81,FA,3C,46,C1,32,5D,39,FB,BE,4B,0A,CD,94,18,F8,28,78,68,0E,A4,42,56,C6,80,22,07,F4,4F,55,45,3F,A7,F6,AE,28,24,23,8E,75,E4,28,B1,45,27,DB,F6,93,D6,A8,7F,0D,71,2D,17,27,B0,C9,7F,3B,BF,C2,48,CD,32,DF,46,1A,65,62,06,A9,EF,D7,1E,78,5E,3D,17,C7,D6,0F,6F,59,CB,38,2D,30,4A,2E,27,31,EF,B4,86,1F,EE,8F,96,0E,A2,C1,3B,25,47,18,8D,7B,16,C9,01,A6,37,6F,7B,55,F4,5D,F6,A3,80,9F,EB,55,2A,06,33,70,7C,B1,8F,A3,58,DD,56,B5,19,A7,AF,56,DD,4B,4A,FD,1B,9F,40,90,91,40,A4,14,AC,44,C9,DE,E9,14,6A,BA,F6,90,58,BA,B9,E7,07,7B,99,25,E1,A1,54,E1,C1,1C,DA,BA,AC,E5,63,A5,98,DB,1C,D1,7F,DE,D7,41,86,9D,D3,B1,00,EB,58,A8,58,11,77,5E,77,8F,01,63,14,20,80,BF,7E,E4,96,A9,1B,22,84,23,05,1F,6A,FE,71,03,90,3E,A6,A5,F0,02,FC,40,66,D3,BF,A2,FE,DD,40,D8,91,81,3E,25,38,45,54,82,54,E9,E4,89,2A,7B,DE,32,27,91,80,5F,FD,95,53,41,85,91,58,A9,9C,86,0C,E5,A0,16,F3,D8,97,1A,69,6F,B6,8E,5C,78,6E,07,77,05,AF,86,3E,B9,0B,D2,87,DA,CC,EA,A9,A5,CA,47,AD,AD,1E,1B,55,A0,8F,C4,83,31,56,3D,54,A9,CE,36,A4,D1,73,41,1E,C1,AC,7B,29,C8,A7,37,2C,52,B9,E2,A6,59,19,C0,B9,60,75,27,57,C8,37,72,5D,B4,98,3E,3B,49,7D,E2,75,B6,C3,C2,25,50,B9,AC,D9,4C,D5,23,06,B7,BC,B3,31,90,7C,F3,5F,EF,D7,9C,DC,56,65,76,49,10,17,22,8C,DB,56,05,3C,02,25,3C,77,C5,51,F4,F6,63,CA,E6,81,F6,EE,AC,7D,4A,02,76,31,42,F8,E5,B2,5C,05,A9,72,12,31,25,3D,0A,67,F0,F4,F9,6D,20,24,54,02,EA,8B,70,2C,2A,D1,5C,74,FF,28,6F,5A,D3,EB,9C,6F,42,AF,16,A6,26,50,05,8D,00,6D,0F,31,C8,0E,AE,39,4E,3E,86,38,A3,43,AE,A1,B0,C6,6A,D4,AF,B9,7A,26,D6,FB,27,8F,B6,56,B3,EE,60,27,3D,80,39,9B,09,E4,B3,DF,4F,37,A2,B2,E2,7B,C3,A3,C8,07,13,31,BE,F8,94,86,B3,60,B2,3F,0C,B6,FC,6D,85,12,9E,00,2A,D4,53,B9,7C,55,01,3A,F8,5B,89,24,B3,66,FC,26,4B,2E,15,42,32,4F,90,A0,99,2D,65,36,F1,5A,C1,49,25,BB,BF,81,AA,C0,95,8F,51,FE,14,60,F8,18,87,08,98,75,DC,6E,90,E1,57,B4,29,93,62,47,A6,8E,BB,5D,66,35,AE,2C,0E,84,5D,D6,C6,7B,C4,5C,3A,A7,01,55,F5,AA,44,B3,C8,97,B7,49,4A,0E,60,73,4D,4A,44,F1,90,78,C0,9F,21,F7,6D,31,B2,4C,54,A7,04,3E,E5,FE,F8,6D,18,B6,4D,0D,00,92,01,79,BA,13,51,0F,2B,24,A4,62,B9,4A,B1,4B,21,CD,EE,12,80,39,6B,EE,EF,40,31,14,96,5F,FE,73,90,CE,ED,73,7C,73,8B,51,AF,D6,C7,7F,BA,60,9E,D4,63,80,24,D9,B0,A2,50,F4,AB,F7,5B,AB,77,CD,B0,13,0D,89,5A,B9,72,1C,B3,C1,B9,C4,70,AA,A7,D5,27,E1,7F,AF,A9,A8,67,48,48,D8,44,59,A1,92,A8,DB,19,14,E2,69,BC,99,B0,D0,A8,A1,7E,9E,34,17,6C,81,C7,C6,1F,0A,B4,A9,D1,6C,A8,B6,18,B7,F3,0A,C4,2D,1E,42,A6,EF,18,24,62,AB,F7,0B,A1,47,25,4E,1A,CD,EC,DD,3E,BE,A7,0D,8A,AB,41,26,7E,E7,08,30,E1,0F,94,5F,66,4D,36,7C,68,EF,91,AD,1B,F6,B7,13,1A,C7,95,DA,AA,7C,4A,02,A6,A6,C8,F5,C7,E4,F3,A8,1B,D4,D7,81,C3,96,E3,62,5A,78,58,58,24,37,3C,CB,16,B7,8F,8E,82,47,A5,44,8B,CA,E0,0E,4D,10,5A,90,89,CD,1C,C0,C1,DD,35,A3,DF,D8,8F,CC,0B,D6,E1,F5,A1,99,1A,80,87,18,52,CF,76,5F,77,1D,0C,A5,4D,ED,80,0F,50,D0,47,26,82,43,E8,85,53,67,EA,03,54,A4,9E,4E,1C,EE,74,1F,93,53,41,AA,99,28,C7,DC,4B,3D,8A,C8,EC,C9,73,42,C0,02,DD,19,A4,A6,75,4F,29,E6,83,E4,EE,95,EC,A3,B6,BA,FD,68,2D,7E,6D,91,16,E2,CE,EB,8C,30,4F,13,31,57,D0,56,9A,D3,6F,E2,F9,C9,E3,8D,BB,FE,3C,53,DF,3C,DE,1F,B7,A4,CE,5F,AA,59,EE,EB,EA,58,C3,45,F1,1D,35,D4,DA,87,8D,5B,01,28,1F,10,17,41,4A,5D,24,FB,0C,13,53,DF,11,3D,83,C8,7F,73,62,FA,28,A0,3E,3E,E2,72,32,40,0E,B9,88,FB,47,DF,17,D0,8D,7B,A7,B2,0D,51,46,41,61,49,23,AE,1A,46,CD,A7,63,FF,B5,F6,7E,38,EC,9D,C9,1F,7A,DE,83,F9,90,B2,B5,8C,9F,CB,11,53,22,BB,77,64,67,2A,96,73,2C,1D,0D,01,AF,7B,EF,AC,43,9D,1E,80,BA,E3,0F,05,89,46,2E,6B,5B,91,87,B6,C1,12,74,94,DC,4D,83,6D,2F,74,1F,24,0B,34,E2,3A,B4,B5,C1,6D,A7,B1,89,C1,77,9E,41,0E,B5,37,EE,52,52,65,39,C4,D3,8C,64,13,FD,31,AF,40,9D,0C,11,83,00,41,6D,27,E0,F9,D2,15,2D,B2,8A,6D,C8,E9,27,B5,68,0F,BB,1E,7C,D9,6E,CE,13,A4,CD,6B,AE,CC,EF,64,47,2C,D1,DC,45,05,83,5E,A2,74,15,AA,85,40,56,3B,70,7A,56,38,DC,D8,A7,D3,EC,EF,03,A9,11,D2,5A,E6,D4,F0,F2,DA,0C,04,4D,13,2B,C2,3A,9A,DD,BC,E8,28,85,27,D7,6E,FA,F9,B3,37,AA,03,CD,62,74,7D,9C,0C,59,93,04,D9,F6,A0,0C,45,92,19,9F,4A,DE,BD,F4,BA,55,50,93,74,67,9A,C0,8C,81,84,A7,B5,EA,CB,17,6A,55,BC,3D,A0,CB,F7,86,25,9F,89,F4,80,74,42,C5,4C,D5,BF,AB,80,FD,54,21,C7,E0,0E,F3,4F,A1,FF,AF,1C,39,1B,E5,0B,87,F7,E3,8F,D0,BD,05,59,5D,6F,BC,65,D4,48,AB,7A,24,2E,DF,54,B8,EE,95,4C,9C,DC,7F,77,8E,12,D7,5E,61,38,86,15,72,24,1E,BF,65,D2,19,A0,E3,9B,32,67,68,D9,E7,76,55,18,97,78,B6,BE,42,32,F3,25,3C,CD,B5,73,C5,66,D6,CA,50,3F,6F,57,A0,93,D2,30,E9,B3,57,4A,A5,BF,2A,0B,C8,B1,1F,69,C5,6E,0E,04,2E,E0,AE,A7,7A,35,90,64,4A,30,78,99,FA,E6,F2,B6,52,67,EE,79,6C,6D,85,86,F3,D0,16,88,B7,70,C5,FD,4B,6F,71,80,10,73,4D,0D,08,95,69,11,A5,CF,47,53,E1,15,0C,0B,E2,A6,16,41,A7,B5,02,F2,77,38,A7,22,95,6C,66,94,40,7B,22,ED,DB,08,5D,8A,E3,E5,59,80,52,92,89,0F,09,A7,AE,8E,CF,55,9D,2F,25,9F,F1,31,AF,9E,D2,F1,FD,F7,C1,62,FE,58,E4,0D,0E,3D,08,44,03,EF,54,AE,E2,05,DA,62,E5,15,3E,93,53,21,23,71,1A,4A,56,DB,19,25,EC,67,7D,84,2F,EF,CE,CB,0E,EA,F5,AD,34,44,BA,AA,45,35,DA,30,0D,CA,DE,CA,26,8A,A0,06,00,60,B1,59,C7,F3,7D,8B,E9,EA,EC,0C,14,F3,8B,7A,62,EB,45,AC,87,9B,8B,FB,1D,49,F7,2C,36,36,FF,A0,43,8E,70,36,05,A8,94,FD,45,28,DE,45,2E,D8,5B,7A,90,7C,29,E0,14,47,7B,51,EF,5C,71,83,CE,05,54,01,5C,6B,9B,CE,D1,3F,EA,34,17,55,77,BD,3A,7C,6C,FB,C5,4F,CB,60,40,31,6F,51,05,88,81,FC,0E,5A,75,46,CA,4E,6D,AA,45,3B,73,64,0B,7B,BF,77,91,A0,69,F2,D6,37,4A,4D,18,72,E2,56,EF,D8,3A,9D,C7,97,15,75,04,91,42,67,5A,E5,F8,8F,93,35,40,63,81,96,64,33,C0,94,95,2E,2F,B4,37,55,D0,6C,0B,8E,0A,43,6C,1B,97,4B,BB,B3,BA,2A,B0,69,1D,0B,36,F6,C1,2E,F8,64,C2,6D,41,55,08,3D,18,AD,D1,02,8F,34,DB,CE,E3,DC,0B,AB,F0,7A,68,8E,3E,5E,05,06,4D,F3,DA,73,97,65,BC,1E,01,B2,8D,08,A8,9B,91,4E,52,02,B3,FC,FC,76,EB,3E,DB,43,3B,A8,A9,CB,EF,34,F0,5D,A8,BD,F3,E2,E8,95,FB,F3,88,B4,A8,21,8A,F0,E6,E0,BE,34,4F,7C,3A,50,97,32,E0,68,27,90,00,23,A6,64,D5,FD,0F,65,67,04,7D,CA,F0,94,D5,46,D0,E7,11,92,7E,CB,28,0C,F3,DE,D1,7C,A9,58,D8,F8,B5,FD,F1,B0,E9,B4,A2,BF,81,99,CF,F3,A7,16,57,4B,2E,AD,05,EC,06,DB,94,B4,0F,55,24,6F,B0,37,FE,8B,12,8E,CE,B0,FD,A5,C5,CB,35,3D,F3,FA,E9,D9,E2,21,E5,FA,5B,16,26,01,0A,38,5B,6E,AC,4B,5B,68,01,4C,E0,0C,68,E8,A4,68,D8,B4,7B,4D,E1,91,0A,2B,E2,0E,BE,BC,79,62,E2,7E,15,FD,6C,00,0E,30,73,B9,9B,85,34,FF,4D,5E,C2,AF,EE,51,0B,4D,A7,F0,41,26,2F,08,F1,99,12,7E,93,FE,A5,0A,A2,C0,49,13,1E,9D,A3,1A,41,90,20,9C,57,5E,AC,54,A0,88,ED,77,D9,EF,31,39,EF,12,37,AF,DA,CD,0F,B6,B9,51,EF,76,31,C6,D4,2F,ED,F7,95,23,26,6A,DE,DB,D5,0C,4C,8B,C7,5F,C7,A4,18,13,99,4A,1A,1B,51,75,44,F1,7E,5F,B9,77,1D,FE,7D,52,E1,1A,C0,BC,EA,97,90,42,B7,E1,74,FB,7F,A3,94,2C,AA,3D,7F,C3,F9,A9,3F,F5,D2,5D,B7,63,C7,1C,25,D1,61,46,23,FF,A6,76,3E,8C,2B,57,30,B2,05,CA,90,87,BC,B0,CE,2D,7B,FF,AB,76,D2,DE,5B,FA,19,47,BE,DE,1A,71,84,0A,2C,99,66,DB,4A,49,BA,75,65,E6,68,29,0C,70,76,D6,5E,69,63,DC,87,1E,46,12,DF,99,63,4D,A4,0D,7C,6E,01,8C,47,AA,0F,AB,57,ED,C9,C2,C3,CE,D5,CD,6A,14,DD,BF,43,A6,66,1F,C7,89,F0,CA,37,EC,4F,79,CA,C3,A5,EE,45,D5,87,6D,EA,90,40,F3,CC,4F,D5,BB,6E,BD,79,4F,18,66,27,FA,6A,9B,7F,64,91,69,B9,17,28,65,B4,11,F6,DD,BA,6C,DB,5F,ED,1E,86,49,0C,A0,F6,38,4F,4B,7D,77,71,9A,32,F9,CB,42,BB,FE,EE,62,7C,9A,02,BD,52,4B,2E,13,CA,3F,FE,78,E5,E9,9A,6A,CF,20,CE,EF,02,7B,B8,CA,10,B6,EF,61,4D,C7,BA,96,1D,F3,92,9A,CE,1D,5F,B9,54,9B,C9,25,A1,96,CE,F4,29,0E,CB,4A,08,2D,20,C7,6D,B3,5F,67,DD,53,CD,D6,1F,D5,A8,10,F3,80,3C,E2,4D,E6,96,81,71,E9,E9,89,98,89,82,93,E1,A7,11,94,B2,88,65,5F,8B,43,32,DB,65,87,EC,F0,8F,14,DA,B6,D9,2E,60,4F,8D,94,20,7E,9B,2C,C0,2F,31,F6,28,83,25,ED,42,D7,2B,BD,DF,23,55,AB,FC,AC,6E,6F,C8,AF,75,67,8B,D7,84,DC,57,D7,8E,5B,A6,67,FC,76,27,0A,87,F1,FB,95,B9,1F,F2,9B,99,08,6D,88,E2,F1,9E,AC,A3,80,56,E4,CF,7F,B1,49,37,09,F2,4C,28,B0,6A,DA,5B,2A,8F,99,0A,E7,11,0D,43,B6,E7,01,06,02,D8,72,09,ED,A8,8E,08,D9,D2,13,D5,22,EB,D3,A4,EC,D3,B6,CA,41,0B,98,E8,6F,EE,E9,34,7F,8B,99,B6,6D,32,A7,4B,5A,FD,9D,B1,FB,C3,25,E9,16,67,61,3A,73,01,A3,C7,58,90,FB,9F,31,4B,78,2B,9B,FF,1B,46,A8,25,CE,6C,BA,5A,01,37,A5,EC,0F,48,C3,6A,D7,F2,20,6E,81,39,E8,A9,8E,54,77,26,A3,1D,A1,B4,2A,B7,D5,BB,FA,30,AB,2C,84,F3,04,6E,33,8C,0B,B4,84,BB,98,DF,46,63,61,D1,18,97,86,51,BB,72,EF,67,77,A3,71,A0,66,FB,93,17,63,14,D1,2C,32,9A,35,53,39,0A,7D,CD,CF,D5,35,99,E7,2C,EB,2E,93,28,3E,44,18,55,C6,3B,0E,64,95,1D,D5,AB,5F,63,D3,B0,A1,C6,EA,DB,6C,31,B4,E7,64,AE,CC,AA,20,1F,A6,4C,59,69,DF,19,60,F3,8D,BC,40,7E,85,A8,2E,54,75,58,DC,C6,AF,2E,BE,25,A8,4F,3B,A9,61,01,A5,7E,AD,79,7E,F6,2F,E0,33,15,07,24,B1,75,15,F1,1C,8A,51,2E,70,56,D0,E5,10,F4,8D,20,2E,D7,5A,ED,B8,27,76,10,6F,E1,73,CE,2E,18,C2,9C,13,E7,3C,9B,62,77,36,00,F7,D1,62,1C,1F,9F,95,1C,B0,8C,80,9A,13,D5,33,DE,DD,C0,91,3A,B1,64,5F,B2,D9,FD,17,E0,ED,1B,A7,C7,6B,1C,D1,C7,89,12,78,B4,DF,DD,BE,04,F2,BF,7D,32,A5,72,1F,26,F2,82,80,15,B7,2A,C1,5C,AA,0E,F0,A9,50,02,D7,B1,78,D4,D7,B3,3C,97,55,AF,D6,A1,A2,F0,56,10,6E,5E,94,CE,CE,5D,D6,62,15,64,8E,6D,87,93,4D,8E,B3,25,83,E4,CE,D0,79,09,41,31,5D,F4,F9,DA,F6,17,AA,72,AE,06,8B,99,9F,3A,49,9D,36,F3,77,A9,80,BC,70,0F,8E,DD,FE,CE,23,3A,B3,D5,DD,EB,67,B0,7C,ED,1A,25,16,82,51,D3,81,E7,2F,D7,2A,3D,CD,3A,6D,5B,CC,C1,36,9A,21,8C,62,F9,C2,35,C9,18,56,84,78,91,AE,95,C8,97,79,C4,2C,37,AF,F4,4D,CD,B9,3E,66,50,14,D0,2A,12,74,9F,E2,89,B4,36,6A,12,A6,8D,2B,3B,F7,2E,2D,D5,98,54,CA,F9,57,2B,53,34,F4,D9,0A,8A,D9,C9,63,20,79,76,8D,C6,AD,12,44,60,A5,2F,CF,73,40,E6,07,72,01,27,F0,7A,A6,8D,75,29,14,90,33,5D,7D,C6,7F,41,B6,60,A7,CC,EC,CD,E6,D3,FE,7F,20,8E,CC,CD,B3,B1,E7,5B,C7,86,EB,40,60,73,F1,21,6E,37,01,7B,86,1D,BC,D5,DA,1F,23,A3,91,F3,44,15,BC,17,02,B7,AB,60,75,7F,8E,EC,3C,8C,2C,23,1A,1C,ED,2D,BB,98,A6,BB,1D,9D,57,56,48,37,22,33,F1,D0,EF,37,B6,45,E1,5E,7E,1C,E7,9B,F2,83,14,7C,8C,5F,C3,AE,17,2C,45,55,59,F4,38,34,FF,05,B8,44,EC,5A,05,AF,54,83,0C,90,23,05,AC,64,95,7C,02,1E,EA,DF,67,B6,3E,60,14,E7,42,26,DB,98,B2,46,38,B7,44,D4,52,DB,2E,A1,35,25,45,E7,7C,E4,8F,E6,09,15,68,B8,3E,A1,7B,E9,05,5E,16,DA,C1,3A,95,AA,59,C7,66,75,24,14,86,7E,8C,BA,88,10,6F,35,84,E1,0A,E2,15,49,4F,CD,D9,11,61,BE,95,47,25,88,36,6C,E6,A8,7F,F4,9D,F1,97,95,F3,62,F1,37,27,13,EA,58,70,A8,BD,68,33,2C,39,0A,F2,DB,3A,2C,FD,76,33,9D,55,D3,EC,E1,A8,FA,34,47,8F,77,39,A9,32,EC,07,82,2E,15,1F,1F,E2,56,A8,3F,24,87,95,A0,CE,B1,26,ED,C3,43,3F,98,7C,4A,E2,C5,E2,AE,75,C4,22,8F,4F,64,25,FD,72,39,05,4A,28,CE,F7,EA,02,DB,8A,53,86,CB,12,C4,7B,F9,48,90,09,2B,08,81,B7,D4,41,93,71,70,C1,89,B2,45,C7,47,91,B5,6E,97,82,73,BD,AE,77,5F,38,50,BF,42,D8,BD,6C,51,D5,0E,F5,6B,F0,52,67,5D,74,DC,7A,30,9A,DE,22,1F,31,AE,57,59,2C,A3,71,EC,7A,F3,2F,19,E9,69,E6,00,5E,65,7D,0E,8D,37,DC,DA,3E,CA,13,E4,73,A2,BB,10,A7,99,49,AF,D5,27,81,45,A6,30,8F,77,EC,F1,84,C2,C8,06,D4,72,36,7F,EA,8F,06,DE,27,3E,8B,E7,39,10,DF,8C,64,1E,DD,18,43,79,8A,53,77,54,2E,52,87,87,9D,52,01,B7,20,57,B7,73,F7,FA,84,5A,7A,80,6C,8B,EC,CD,A0,DD,ED,BC,57,0A,A3,30,A9,72,BE,55,8E,9A,43,B4,40,7B,A4,60,A3,E0,23,02,7E,92,71,59,05,DA,D8,8B,96,E5,1E,62,F2,36,48,A3,DB,66,F7,DD,9D,AB,16,55,50,AD,74,83,51,B5,56,31,AF,42,13,6F,8A,0A,73,24,D0,F4,E9,0B,22,B9,D3,75,31,4E,FC,36,05,B1,F3,20,E5,92,DE,AE,88,26,2E,97,EF,A5,85,8B,1E,3D,BE,44,F5,61,64,58,6A,65,D2,22,13,FE,6B,E4,A3,44,F9,42,01,01,CE,15,9A,82,5F,F4,84,4C,C6,55,C8,F1,A1,0B,3A,34,A0,D5,07,53,4E,4E,47,6A,64,A6,82,3E,57,4C,DD,05,FB,AC,5C,B7,A5,40,D3,28,66,3A,77,ED,E3,9F,21,91,D6,19,B4,E5,F6,25,AC,5D,72,ED,D3,4A,AD,2B,19,AB,92,BC,37,51,96,11,BC,21,3F,5B,53,BD,3A,AB,55,F9,C7,C4,A3,44,07,F9,5D,08,8D,E9,8F,35,3A,87,59,96,7D,EA,CA,CB,2A,9A,28,44,FB,1D,3B,F2,38,0F,68,3D,39,F7,B4,72,43,ED,D2,53,F4,C9,82,5B,F8,83,FA,77,55,64,62,CD,2D,34,A9,D8,4F,80,88,44,1A,34,E9,89,CC,ED,AF,C6,19,C5,32,3A,D2,B2,36,A3,E9,A6,CF,A8,C1,FB,A3,BA,22,E2,95,1A,45,7F,B9,86,77,13,DE,BE,90,BD,92,B1,80,27,9E,6E,ED,20,2D,59,5A,7D,CC,85,E4,D5,E2,03,E8,25,19,00,77,8D,3B,8D,FB,18,AB,D2,3F,D8,7B,E3,CF,E6,8F,5E,CE,0B,6B,CB,D7,75,68,EB,B8,B4,57,6A,F7,C1,C0,D0,AD,9B,AF,2A,11,D7,BF,1A,CD,1A,53,5F,24,60,06,A3,EB,50,FE,48,B8,F3,58,51,75,81,F2,69,59,16,06,88,91,4D,73,A2,3C,0B,8B,20,9C,2D,87,63,F0,16,94,0E,85,8B,51,E3,47,82,80,C7,6D,0D,4D,CE,04,BE,79,67,ED,14,A0,25,FA,25,14,74,51,EA,6D,F0,BC,A5,48,38,BC,DC,C8,41,07,5C,B2,1C,F4,8C,D1,7E,C2,CF,08,F3,2B,3C,94,14,C4,E4,45,C5,6D,C4,FC,AA,83,58,52,BD,DD,21,D9,D2,3C,E2,05,19,61,BF,38,D4,33,88,BD,80,95,54,9D,4A,AB,EC,7E,C5,74,EF,9A,B0,9C,81,AE,4D,D9,51,C9,FD,C0,4B,B4,25,FC,F0,71,35,10,A2,C3,86,78,E6,18,AC,93,CA,57,96,F3,D4,5B,47,B0,6E,2C,AB,78,66,93,ED,3F,19,AD,B2,09,25,F1,C1,AD,39,AA,13,88,28,35,CE,8C,C0,32,12,21,36,42,FB,A4,F0,11,A6,AC,B0,AE,E9,33,CD,8B,6F,80,11,37,70,F5,E1,7C,5C,E7,B2,92,BA,32,82,2C,6F,EB,B6,FE,66,F4,B3,46,50,2E,0C,6F,E9,B3,FD,84,9B,56,92,2E,B8,6E,50,1A,20,59,BB,85,69,4F,83,25,4E,23,F9,31,44,4E,BC,0C,2B,F5,B6,E6,45,7F,D4,1C,AF,B9,B5,8E,86,2B,08,CF,00,3E,D7,5B,3A,63,3B,05,51,CE,82,9D,81,E3,EC,32,C3,DA,77,75,24,E2,A3,84,72,DB,A3,B8,3E,EA,EA,21,F6,96,92,A5,BF,B8,AF,97,8F,DE,45,85,41,AE,E8,DB,40,05,BF,B5,8A,E6,AA,D9,14,14,80,C3,75,F9,13,41,52,9B,DC,FE,43,0A,39,B8,53,64,DF,A6,2E,B7,7A,67,2D,D5,5C,89,10,D7,A3,BB,C0,31,4B,35,38,1C,09,28,AE,A7,86,F8,84,1F,2D,2B,3C,F9,D4,3B,01,EC,2F,BE,31,A3,06,A5,AF,10,1A,D7,6F,0B,8C,03,64,A2,F8,B5,23,28,D2,0F,8E,41,6A,4F,11,74,B0,24,39,9D,0B,90,E8,DE,03,0C,FE,01,FC,66,70,3A,27,93,37,FB,09,A7,4D,A2,EA,41,79,26,75,C6,C4,91,9B,EF,3F,23,F7,3C,28,0B,07,4A,4E,DC,AD,AD,89,96,D4,42,13,71,BB,D1,B1,F4,EE,47,39,6B,25,BE,74,74,30,59,4F,A5,67,D8,7A,1B,B9,A5,23,2E,D9,A5,3B,B7,81,B7,48,3C,72,06,BB,2C,AD,48,CC,7B,92,8A,9D,B9,E5,DA,B6,C0,8E,67,19,E3,FC,69,0D,F7,85,A6,21,1A,60,C3,BE,19,F8,C4,81,B6,68,81,B4,CF,11,52,A1,9B,26,C8,0E,81,BF,29,14,F3,CC,C0,CF,60,87,02,7D,80,BB,EB,A5,BC,E6,72,05,59,09,9E,7F,EE,AF,5C,33,6D,23,5C,A6,4A,AE,17,6E,FA,A3,88,7E,26,DC,1A,DB,B3,FD,CD,7F,F4,FF,76,72,B9,DF,DF,C3,02,FB,CA,96,87,58,68,C7,0E,C7,0B,7E,38,01,82,7A,E1,E1,E2,9F,59,0F,EF,3A,E5,1B,4D,40,52,40,EF,76,C2,5E,93,D8,8F,54,8C,4D,9D,CF,0E,5E,30,03,D1,1A,C7,70,71,1F,92,B1,BD,55,98,E9,39,31,13,23,75,A7,28,8C,51,39,FB,E7,E3,40,1A,EA,9C,AA,56,18,17,91,EB,21,84,CE,7D,72,B1,A6,D1,BE,CA,15,E9,40,FE,1D,20,20,34,6E,97,7F,CB,F4,49,DB,ED,0D,0D,3F,3E,AF,35,64,69,84,0C,BC,CE,2C,A7,3C,F1,E1,D7,63,1F,AA,A3,D9,F8,F5,0A,C7,25,21,5F,6B,B3,CC,CF,14,36,5F,77,CC,E1,9E,46,66,1D,68,E0,34,15,05,59,50,F6,9E,5F,C0,1E,51,63,C2,85,F5,92,A4,7D,85,72,30,F5,95,42,A6,A3,D1,E5,79,5A,85,39,05,BD,25,07,21,30,C9,41,6C,CA,77,2A,6B,BF,B4,33,30,9F,CC,93,9A,71,FB,2E,4C,48,B9,E6,25,18,D7,5A,C2,D5,4A,15,36,F0,31,A4,1C,E6,2C,EB,9B,3E,DD,D4,35,59,D2,45,B1,38,56,90,43,C5,AD,C0,11,6F,92,A2,1F,AA,20,B9,08,D4,D6,1A,23,9D,3A,E4,D8,10,51,F3,8C,90,AD,B8,E1,F1,AF,42,28,6A,12,B3,AF,51,9B,6C,FC,DB,B2,5E,5A,38,79,1B,19,DF,D5,B1,82,E4,5C,04,F5,6C,9A,44,94,D7,6E,53,24,15,B8,2A,F1,D1,C3,BC,DB,57,82,45,1C,41,C0,2F,ED,B6,89,12,D0,96,32,9A,1F,E5,6D,D6,8F,2C,3F,21,DA,AF,C2,0A,F5,E9,27,5D,FB,19,CA,76,2E,5F,9C,A8,C2,67,43,03,E5,BC,51,AB,A8,64,E3,F8,9C,58,88,6B,FF,4C,B0,69,C0,C6,22,C1,0F,6C,60,A3,3C,0D,16,02,85,F9,43,7E,04,D5,F3,C0,72,9D,F1,16,D4,B3,4E,52,17,45,4D,FA,BB,4F,B1,22,2A,7D,EE,F6,E5,8B,33,4C,A0,6E,5E,59,87,A6,4A,24,39,6E,5E,4F,1C,FD,96,58,E9,A7,67,25,B4,6C,7B,9C,75,79,68,E0,84,60,91,96,70,7E,C7,2C,9D,9D,7B,81,22,61,03,22,67,A6,5A,AF,B8,EC,B9,7F,EB,F7,4F,06,29,2A,11,3C,C0,B4,0C,A8,06,42,E2,7D,1C,09,A1,5B,5F,CD,2C,A5,48,47,55,40,2C,E8,C5,E4,03,CB,24,4E,7D,18,DC,96,EA,D1,0A,B3,49,67,05,9E,0B,73,67,7E,FE,B0,DE,7B,60,56,F6,86,3F,DE,85,9C,D8,38,60,CA,3B,53,67,75,6F,67,4A,61,44,E4,B8,49,81,92,D7,A8,BE,56,59,78,2D,89,A6,AE,E7,9C,33,CA,EE,0B,39,BB,37,98,EC,5F,F4,6A,95,BE,E6,13,4D,6D,69,09,BF,79,6F,1B,51,F7,33,65,DC,03,34,0D,57,D6,9E,50,DF,B5,5B,B0,F8,CB,1F,52,DA,87,12,FD,50,04,5B,78,87,DD,48,63,FF,7B,EE,B2,B9,E3,A9,0B,37,1F,F1,83,B6,AA,23,F6,DC,C8,D4,46,4A,98,EE,C9,7E,3B,C9,72,E3,60,D5,D9,4F,E7,CA,E3,6C,07,23,53,44,13,2A,0A,F7,C0,0C,DC,CD,04,A5,27,27,14,0C,CC,0D,D5,C2,0B,51,C9,E7,E7,FE,98,03,C5,52,8F,62,E4,38,39,C5,90,19,8E,44,EF,AF,05,2C,A3,BE,C0,8D,EE,58,B0,70,D1,C8,1E,01,E7,85,48,14,B4,23,57,70,67,60,A4,58,99,22,FA,66,EE,4E,9E,2B,4B,96,C5,48,AC,2D,89,F1,E2,0A,81,C8,4E,E9,EC,A7,F5,15,19,38,57,C5,06,7A,EB,C9,D1,33,2D,6B,08,0B,2C,C9,82,50,46,71,43,1C,E1,FC,51,E7,D9,AD,BF,BE,A7,2A,7D,59,0D,9B,32,B2,53,1B,AD,F1,44,B4,4E,5F,14,B1,4C,13,85,50,6D,60,1D,9E,DB,54,C4,74,8D,7C,CC,37,B0,7B,15,04,B9,10,8F,27,D3,B5,15,5D,08,92,08,79,53,23,69,03,F0,27,14,1E,BB,D6,69,47,58,39,02,47,10,AA,55,B7,71,5A,39,D9,6C,6E,8A,1F,4D,04,E1,E7,1C,16,CA,81,4B,2B,74,52,A1,1A,0B,1A,D0,5C,28,A9,6D,65,C1,88,20,3D,FB,26,2B,A9,43,BC,79,85,15,80,DF,36,2C,B0,54,18,C3,0A,72,3F,5E,F6,D6,45,18,DA,6C,98,42,60,A6,78,73,A8,B7,93,F0,25,25,2C,0A,D2,C4,4B,23,8B,B2,9B,1B,42,6C,0F,51,47,3A,50,52,E0,9E,1E,8F,92,F8,4C,61,A9,88,26,05,B4,58,20,73,9D,F7,52,93,70,E4,D1,1F,DC,8D,6C,08,D2,B2,1B,10,6F,FC,87,DA,1D,E1,CD,E7,BD,61,F1,6D,01,F1,6E,0E,FE,50,05,71,E5,F5,46,79,79,B0,93,68,E8,8B,AC,39,8E,24,79,54,B7,D9,81,CF,10,FC,99,E9,BD,08,7F,8B,0A,A2,6A,75,CC,B5,44,96,96,96,85,BC,AC,A8,E0,EB,A8,1D,49,20,58,6D,99,AA,E8,96,B2,AE,B4,7B,8C,8A,47,8C,6E,CE,2A,C7,39,59,72,32,F9,75,45,80,EE,04,F7,1E,48,43,62,B4,09,99,9D,F3,B1,BB,EA,68,4D,94,54,77,40,9E,AF,D2,5A,BF,41,24,35,CC,61,C4,25,1E,49,05,A5,43,C3,3C,4F,86,F1,6C,F2,BF,62,51,D5,5D,D4,2C,32,9F,39,B4,7D,D4,F0,10,54,71,01,9C,60,5D,94,DF,33,4A,7F,C6,1B,D2,BC,64,64,B8,8E,0B,EF,94,D9,BD,11,D6,01,C6,8D,F2,3B,F5,99,75,EC,C0,4E,0A,C7,3A,76,56,79,A5,09,42,E7,CE,75,13,29,7B,F1,EB,74,92,A5,35,59,0B,D8,6D,1B,5A,A2,B3,A5,6D,E0,40,72,4B,8B,8C,73,54,78,E6,E2,76,A1,03,AB,6D,7A,2F,56,22,CE,CD,26,83,E5,87,EF,87,2A,36,3F,1E,5F,22,4D,F3,90,52,BD,AC,5C,F7,42,51,19,06,B4,DE,B6,FB,81,54,B8,44,D8,FA,A4,30,8E,B7,2A,72,E0,00,13,55,4C,86,CD,50,4A,B4,9E,ED,EA,B2,BD,86,A2,C9,16,82,EB,1B,34,06,7A,17,B6,D5,A8,54,D3,66,4A,4A,F9,9E,D3,B7,03,B0,20,6E,4F,EA,B2,0D,EA,42,6D,26,B2,4B,9F,64,2C,D7,83,53,4D,12,AD,50,31,D6,B4,DF,31,92,6C,98,C3,27,74,8B,FF,95,30,45,A2,A0,B6,28,A4,CD,C8,62,07,4B,EC,D8,68,F9,43,52,4B,49,D6,75,AC,29,33,FA,CE,95,82,4B,F4,1F,E1,33,3E,E5,EB,D8,71,E5,A9,90,C1,4A,39,7F,F4,77,89,B5,ED,D3,B2,AC,79,54,52,DC,FE,3D,87,42,10,27,99,C4,5D,B0,EF,8A,C7,B2,C1,43,52,A4,76,1E,78,96,9E,E2,86,85,B7,20,1A,89,F4,A3,34,59,F4,C3,C5,1C,3D,66,62,E1,00,5B,40,92,9F,B3,1E,A1,8A,9A,B7,A8,89,7F,83,6C,FF,E1,7D,67,92,5F,52,09,E8,DB,8D,A6,CF,CF,74,51,5C,93,69,F5,7D,B2,4E,3D,03,B6,2E,15,E4,31,80,2F,55,AE,E0,EE,11,56,8B,CA,0B,C8,84,ED,11,DB,9C,DB,BC,68,4C,CA,97,1C,60,17,52,73,DE,61,03,C4,30,45,17,66,5C,64,F8,DB,21,75,F1,A9,B5,2A,56,62,30,77,90,8C,9C,A4,5F,18,F4,FA,2E,98,D6,62,6D,CD,3C,6C,DD,92,D5,09,ED,C6,B3,4C,95,95,54,34,D1,6C,35,4F,41,80,AD,73,F5,00,69,C2,84,15,E2,36,22,F4,1D,AC,41,EC,1F,A1,E2,28,88,7B,01,69,AC,52,60,2C,CA,6B,97,C5,B8,48,B7,6A,96,CE,7D,8A,60,9E,D8,1A,C5,61,B5,B1,D3,A4,1F,B2,DB,AC,0E,AD,9F,F8,E1,56,35,3D,7D,08,47,19,0B,8C,D0,20,11,01,3E,70,F1,84,4E,7F,D5,01,A0,EC,30,8E,33,6F,FA,0F,52,58,43,B3,E0,94,1E,38,C6,D2,43,74,BD,9F,09,36,39,BD,80,59,84,D7,7A,F0,CB,BD,F7,C7,3D,D1,C8,0F,E8,78,6B,60,69,2D,65,F3,A9,BB,32,72,B6,7F,67,FE,05,CE,09,EC,05,86,72,33,B1,FC,1F,7D,08,89,1B,D4,29,73,A3,17,A4,B5,A1,6E,5E,C7,96,36,8C,1E,6C,FB,22,A5,FE,C5,BE,31,E2,11,B5,69,65,B0,92,F1,2A,8E,BE,0B,AC,92,3B,CB,AC,46,FA,28,F3,20,FE,57,F6,CA,D9,86,A6,47,AF,BC,16,04,3A,92,8C,FA,7E,5F,A7,2A,6B,6E,F5,8D,76,C8,CB,7D,E7,88,C8,C9,CC,48,A2,DC,58,5D,44,5E,2C,EA,26,E5,E2,6A,3A,E9,FE,81,5E,FF,BE,3D,31,E4,95,C3,5B,68,B3,06,63,91,CC,D9,CB,63,3E,FC,0A,77,D7,79,04,01,68,36,C4,3D,61,C5,67,C9,75,92,CD,95,3D,64,85,64,DD,EA,3B,BE,74,08,1F,D1,38,2F,0F,AF,1F,B5,4D,85,EC,95,54,A0,6F,52,D3,09,2A,05,DF,72,6A,70,4D,87,C9,B8,E3,E0,BD,71,F7,1D,FB,38,5D,AF,DE,B7,F8,8C,8E,DF,06,F7,25,DF,BA,AF,FE,1A,85,E8,2F,66,70,CD,91,DB,32,AE,B2,86,E5,56,6D,15,F7,28,CB,86,9F,54,15,12,2E,51,AF,C3,05,BE,FD,EF,11,E0,EE,A5,37,AD,34,54,5B,93,BE,34,35,A1,B6,65,29,A3,AD,A8,E7,22,DF,8A,FE,82,6C,A6,5E,2B,89,DC,22,79,88,A6,83,39,A1,35,67,94,0B,EB,BB,D7,AB,2A,F2,06,9E,BA,99,34,D7,BC,47,D8,84,C9,38,DD,56,55,BC,A9,EA,E3,56,16,DD,D9,4B,E4,D1,43,55,3A,10,65,A0,F8,48,DC,0E,C6,53,6E,86,E1,F3,D9,30,CB,C4,51,E2,6B,63,82,84,91,A5,EA,31,78,A9,7C,9B,CB,AF,64,53,01,2F,73,7C,9F,0C,6D,FD,50,08,CA,45,DB,ED,D3,60,AE,CF,73,9A,A3,B0,96,27,38,82,46,78,CD,42,E3,0C,60,FF,97,23,4E,8E,DC,01,DC,32,01,1A,25,71,3E,99,3D,08,46,5A,2D,9A,2E,66,8A,51,D9,45,1B,36,5D,D1,A8,F8,E9,8F,5A,24,3F,F3,9B,50,BF,B9,01,11,86,CA,71,77,4B,F4,7D,2A,83,27,FD,DA,FF,6F,B6,B1,04,C6,02,09,79,00,6A,51,BA,15,99,EB,77,C1,58,9C,2F,2F,DB,98,F8,67,DE,3F,57,23,28,BA,F3,EC,E8,9C,A2,97,22,D7,08,15,76,45,49,81,4B,8D,41,6E,1F,60,74,E9,7F,65,7D,E3,E9,60,9C,5B,BB,9A,16,98,83,F7,D5,73,E2,DB,B5,A8,80,C4,D8,47,6D,BE,B4,7D,46,1D,28,16,54,4A,54,34,9B,13,CF,BA,96,40,D6,A5,30,A3,F1,B8,52,A5,EB,55,E1,89,53,3E,FF,E7,0E,63,2A,7E,8E,0E,1B,40,EB,03,7A,DA,03,B1,7C,AD,15,79,0B,FF,01,14,8D,6A,17,A1,5F,96,78,CA,8F,AA,3C,BC,70,C4,8E,04,0E,A3,A2,08,BC,C4,4D,2D,7E,C9,43,D4,7B,75,54,5E,C4,6F,A4,C6,DD,93,7A,68,8C,D8,0B,C4,A8,2D,E0,02,B2,91,AC,D3,43,86,BF,5B,33,75,A1,BB,C9,D3,9C,12,12,9C,81,3F,03,11,78,C6,C3,D3,2D,58,5B,BA,02,60,E9,9E,6C,FC,78,72,C2,17,A6,D8,82,97,66,7B,80,22,D9,49,51,7A,5C,FA,C5,14,D2,2C,84,A4,D5,86,09,53,05,7B,0E,E7,19,9A,E9,C2,E1,E3,8C,1C,09,30,75,4F,6D,E3,31,75,06,3B,78,AD,82,F8,10,50,69,AD,75,D0,F3,8E,7D,6F,CB,E2,69,1F,14,26,F2,41,32,97,55,BF,BE,8C,6D,07,E8,16,82,77,3D,AF,79,6B,20,9D,A2,E3,39,42,CE,32,CB,DB,5F,66,E3,40,59,D5,3C,D1,B8,AF,10,2C,73,7A,C1,B0,43,BC,FC,63,FC,BB,D5,C9,13,69,AD,1F,7C,BE,1D,EB,47,ED,0A,C6,06,42,EA,DB,B0,18,A3,B3,5A,DA,82,6A,A9,FB,61,73,6B,93,D6,DB,1D,C4,6F,8F,99,9D,E5,0F,E1,40,5E,90,1A,28,2D,A1,E8,4F,CE,C5,B0,5C,06,25,80,67,24,58,33,A1,AE,5C,58,EC,BF,6C,53,9D,30,FE,A2,74,7C,ED,68,9F,57,4F,8C,48,65,C8,37,0A,59,D4,8E,89,D2,6C,88,07,85,8D,C7,24,1C,4F,8C,05,73,81,AC,3D,DF,73,EE,0B,35,A9,38,0D,82,62,25,45,00,32,3C,BE,B0,9B,3A,AA,BE,AD,8B,31,56,AE,6E,7B,4A,A5,FC,16,B4,3B,7C,66,1A,24,1C,F4,1C,A0,5F,CB,70,CF,F9,2C,27,3B,62,EB,95,F5,33,F1,2A,45,93,60,25,C3,94,80,C8,A5,99,EB,96,0F,2B,16,61,1A,42,FD,B9,6A,73,A5,AE,3D,D4,2E,DF,8D,36,EC,02,55,C1,BC,EC,D3,12,D9,6E,F2,04,21,B9,0B,48,89,70,39,FE,5B,DA,0C,FC,B3,FB,63,54,88,F7,EC,79,16,97,83,DE,AC,9F,76,54,EF,9C,82,2A,25,A8,62,C2,09,E9,52,E9,D9,16,A6,2C,20,24,A2,AF,21,BD,79,9E,5E,A3,D4,28,74,72,2B,9E,DF,14,D9,74,72,09,16,87,E8,ED,5F,3B,66,CF,DA,1A,E4,07,A3,46,39,90,0F,9B,29,26,73,FF,FE,D3,24,8B,02,D3,C5,59,9E,79,A8,68,45,DF,A1,6E,ED,E0,AF,3D,E4,4F,09,A9,C3,4D,04,B4,EC,E4,6D,77,02,6B,99,96,50,3D,F7,BC,00,A7,90,46,74,3E,4A,85,A3,16,5C,B6,31,B7,67,60,11,D2,02,D5,FE,0A,29,87,2A,A0,EF,63,3F,40,C3,1F,2B,3B,17,C8,5B,BA,B6,F6,71,62,DD,F8,79,B2,52,1F,FB,04,43,DA,4C,30,BF,0B,3C,63,13,C4,BD,82,F6,10,66,69,C5,B7,23,78,45,A4,BA,54,7A,E8,6F,CA,E9,F8,E8,08,96,4F,AE,8C,80,28,0E,C4,C9,A8,F5,40,32,4F,19,B8,9B,17,99,5E,D5,94,83,A2,A4,F3,1F,EF,DC,FB,57,99,3D,F0,8A,56,EC,B3,9F,D5,6C,0D,E1,39,5E,81,D5,2F,83,7B,E1,F1,13,F6,31,22,33,8F,1A,13,20,88,F5,EC,95,37,C3,F9,6A,BC,02,9D,68,46,1C,0D,68,2E,DC,EB,6C,16,E3,31,26,7D,52,C7,52,A8,32,0B,F4,57,99,24,18,BC,21,A0,B2,05,E9,E1,47,E7,B4,6D,6C,8A,C4,F3,1E,C6,F2,B8,CB,67,27,A1,BA,A1,20,F3,94,7C,C2,BC,9B,BB,44,5F,62,62,D4,60,F2,9E,A4,B6,82,69,AF,8C,6D,94,72,CC,D4,D6,08,33,F6,E0,3A,68,E8,C7,4F,E2,88,2A,84,BE,5D,0F,E5,81,48,0A,F7,64,21,70,1D,A7,91,A9,FD,51,03,8A,23,65,74,2C,43,42,49,3A,17,24,2F,C6,8A,44,C3,B5,17,81,4E,BE,73,B0,C3,4F,2B,F5,7A,FE,3B,EB,15,6B,8E,DF,D9,66,7F,A7,D9,83,B9,27,5D,13,A4,FF,58,11,D6,A8,C6,6B,37,65,A9,8F,29,B3,81,0E,10,B6,33,97,FD,62,B2,26,98,91,BC,86,41,71,69,87,FD,3B,3A,66,77,E5,09,4E,1C,4C,DD,02,C1,C3,4D,07,92,FE,D4,74,79,92,03,D4,8A,A3,31,96,E7,A7,96,1D,7E,94,A6,06,78,64,8E,82,8D,FF,86,D1,A9,E0,37,00,E5,D1,BC,A3,64,7E,86,63,1E,76,F9,16,1F,F7,28,71,9C,73,6D,24,9F,B6,9F,39,A9,DF,4F,D8,97,49,DF,72,AF,0F,55,7A,30,E2,11,F7,7B,BF,F5,89,42,2F,05,C7,72,1E,62,DB,AD,E9,54,44,6E,05,1A,9D,20,1A,B1,35,BB,D7,41,C7,16,BE,94,50,5D,C8,8D,3C,BE,A6,EF,E7,BA,F4,9D,2C,4A,F9,C2,05,26,AA,25,4D,53,10,02,E9,BD,7F,85,C6,76,24,83,22,90,32,DA,51,A6,E6,FD,B6,1A,3F,B2,84,8B,C9,51,14,A4,96,EF,E6,CF,52,F7,BF,73,64,9C,C7,04,90,F0,5B,4C,E9,32,D1,1A,80,28,3F,CA,88,12,FA,3D,AC,B3,9A,06,F7,CF,F1,F7,40,CB,B0,42,04,7B,B9,EC,5D,F1,1F,E3,1B,83,46,B2,38,2E,A4,07,DE,86,39,95,0E,A1,0B,64,5C,60,A1,4D,43,DD,41,CA,65,42,5B,DA,C2,52,52,A3,A8,84,57,51,87,48,F8,1B,6A,F6,6C,12,DB,25,AC,37,55,EE,2C,B1,B7,D1,86,0F,4B,A4,10,DF,61,11,9B,50,29,13,56,0D,D1,8D,8E,64,84,C1,B1,95,7D,58,B3,F2,CA,E5,F1,30,18,B0,F4,7C,6C,6E,9E,5B,16,FD,71,84,6F,69,61,DC,91,0D,50,91,84,09,35,B3,F7,FB,F0,FB,D7,21,97,E7,7E,74,68,5F,23,50,28,33,61,11,C8,1B,E7,18,84,52,03,9F,F9,BC,92,8F,D6,59,FC,5F,2B,DE,2C,C2,63,88,D4,C4,85,B0,81,71,04,0D,76,56,B1,B5,9C,B9,54,93,03,4C,EB,4F,4A,69,A5,77,10,BF,18,CA,EC,13,95,BD,3C,F0,A0,4E,01,28,08,9D,57,07,DF,00,A3,F9,2A,74,31,7B,FD,5C,2C,4C,81,D8,CE,36,63,A8,B7,E8,F9,D3,7A,DD,75,86,A3,A7,14,33,34,F4,C5,8A,75,2D,E2,33,6B,BF,B7,FB,2C,11,CD,A3,65,D6,00,36,37,02,A0,6E,B6,8E,54,15,70,12,50,51,D2,1E,1E,31,DF,18,2F,76,14,1E,42,66,6B,52,F8,60,9E,03,DE,30,38,95,38,45,B6,0E,0E,BA,F3,36,22,66,34,D7,F3,75,9A,2E,5F,55,A5,1F,CF,6B,B0,5C,C1,22,13,7C,D3,A6,3D,45,53,4F,8A,83,33,2B,0B,F3,D4,6B,D5,DA,3C,31,93,82,BE,22,D7,34,86,22,5F,1B,03,CB,53,C5,16,CF,AF,3B,6F,3D,9A,FA,27,CC,F6,02,12,A4,F6,48,C6,48,21,00,36,B8,89,C6,3D,0B,66,8D,F5,0A,AE,91,42,BC,17,48,3A,6F,88,A5,80,AD,10,80,09,AD,8A,56,9A,A5,AD,79,94,CB,78,E2,A8,C2,B2,66,E1,BD,F6,C9,82,63,4F,84,EA,A3,4A,B3,A2,CB,E0,CD,8C,D5,9D,3E,67,81,98,D9,1E,36,F3,E3,DE,9C,DB,F5,94,F4,5C,1D,2D,FA,3F,BF,F7,21,FA,1C,B9,C0,9F,36,8A,E7,D6,21,F3,3F,49,B8,20,7D,99,65,3F,A3,24,0A,7F,92,5A,FF,8C,38,4B,9E,D1,6A,15,51,50,06,47,B3,C3,76,90,B4,BF,86,3F,35,20,AD,19,E6,C3,DC,B2,D9,18,66,38,9F,FB,F2,78,34,B7,7F,CF,ED,AB,66,16,FF,CC,D0,D9,03,46,2B,C9,3C,E2,28,95,17,CE,DC,E9,9D,8E,E4,AE,4E,D6,0D,15,38,ED,B5,8F,97,D9,83,F1,2F,A5,F8,4C,33,F5,F1,0D,01,41,E2,D7,CD,55,6C,EF,DD,C3,80,ED,49,49,5D,BF,12,AD,91,6A,E1,6C,BB,4F,65,34,38,30,85,CB,56,04,83,BC,FF,F0,81,F7,37,7C,07,76,C3,97,B7,71,1A,4A,26,55,0B,CE,68,DA,68,63,74,10,F1,00,55,E8,23,B6,8B,9B,43,3F,CE,7A,BB,FD,03,17,C2,29,91,0A,C8,46,79,9D,09,80,EE,04,39,F4,B5,7A,61,18,45,8D,33,A0,50,1B,4C,4B,40,64,DA,E8,B9,0D,E8,A4,BC,75,44,9F,41,FF,9E,D2,05,62,E8,E0,75,CF,8A,AC,CE,CA,B2,F1,41,5E,8C,ED,A8,F0,63,87,31,2C,1F,D2,39,69,C0,44,E6,3D,42,08,E2,AE,53,86,B2,88,F8,E5,C0,30,37,21,5F,4D,8D,D8,29,FD,B3,A4,04,03,40,C5,AE,41,5F,07,D8,E4,6E,B7,D2,0D,AF,1C,8C,33,0D,26,DF,7F,3C,1A,ED,79,39,69,7B,D6,62,9A,6B,4D,55,89,E3,9B,D5,EF,08,FD,3B,D0,8D,44,22,5D,5B,EA,66,B9,B4,2F,8B,FC,8A,CE,51,B7,E7,E3,91,D1,45,37,42,D0,9F,D8,8B,56,7C,AF,B1,E7,5F,DD,D2,F1,15,77,4C,12,B9,3F,DD,00,F2,F9,0D,2C,D3,96,7F,13,A7,FA,94,3F,0F,F4,79,17,11,6A,97,28,7E,63,5C,3F,0B,2C,8C,72,64,26,E0,B9,4A,0E,6C,3F,6A,34,6D,EF,7B,CB,22,7F,B9,25,E2,4A,AB,01,75,AE,41,3A,9E,D2,3F,7A,5F,4D,FB,5D,BA,83,15,CB,E9,11,A2,4F,A7,D3,9F,78,49,45,23,FE,AA,E2,09,34,88,B8,B3,42,31,E5,74,5E,97,55,70,B6,8A,B7,F3,D1,5B,61,82,AD,FF,8A,A7,A3,A5,F8,50,29,B5,01,1E,73,FC,53,65,65,DF,12,DF,CD,51,40,18,2A,8B,40,49,41,BE,2B,F2,3C,B8,CF,33,95,2C,C3,04,7B,54,76,51,45,7C,D5,2F,A7,8C,3E,F9,D2,F6,82,49,09,44,84,2E,7C,22,0C,D6,4C,C1,11,AC,EC,7B,5B,98,6A,9E,0D,F8,05,18,1D,20,A8,76,69,D3,36,64,54,B4,BE,47,A8,93,3B,66,4A,6E,C0,98,C8,11,B7,F7,EB,EA,5F,05,F9,3B,B5,7A,7E,28,FF,9A,2D,50,98,A8,D6,D7,BC,57,A6,8D,F2,D1,E2,3A,F4,E4,3D,AD,E9,7C,CA,65,5C,D8,A8,A3,CB,6B,C5,16,D9,D8,60,4F,EC,2A,5E,BE,49,72,1D,F7,E8,1B,CF,75,21,53,A1,64,28,5B,8D,69,42,1A,5E,03,04,B8,F4,83,BE,84,CA,CF,79,D9,0C,00,B8,92,90,5C,D3,BA,DD,E2,56,7D,01,62,69,77,80,8B,0C,B6,3F,F0,85,35,42,59,8A,CB,2C,1A,BD,3C,57,A9,DB,EE,00,B5,0E,DB,B1,0A,80,6C,10,55,4D,AE,43,E3,13,65,0F,30,0E,7A,5B,6E,4C,4B,F6,FC,2A,66,2F,16,71,3C,56,FB,53,87,84,83,EF,CF,2E,36,FC,B4,CA,9F,74,46,06,CD,FA,44,E8,39,B8,DA,A1,53,5C,51,60,0C,5D,21,3B,F4,FF,B9,DB,5E,18,A4,27,B4,F0,21,59,17,53,1B,4B,D1,F7,64,61,33,6D,01,B3,EF,2A,0B,28,FE,59,37,78,77,C8,7E,F0,68,6B,F3,34,FB,C1,D1,A3,F7,46,A7,7F,98,07,82,41,78,34,B8,50,0E,EE,28,D6,2E,D8,36,7F,E2,24,8D,7A,A9,D6,A2,1B,A1,80,48,E9,68,37,39,DD,70,2F,33,E7,0C,7D,C1,F9,DA,46,A7,8C,55,03,DE,58,A3,FD,AA,D9,A0,C7,5E,6E,23,90,9D,0D,88,24,85,11,88,B0,EF,E4,43,FA,14,EC,1F,F8,BF,66,FA,9C,A2,75,AB,D7,31,CF,F4,58,2A,55,01,70,B8,21,BB,08,34,95,45,FB,B9,86,0E,2B,26,F2,84,DB,17,0D,CD,59,8B,19,93,4A,40,93,AC,1E,16,B1,1C,F3,4B,D9,62,7B,95,58,4D,CB,62,52,7B,EA,7F,72,F8,CF,AD,C5,31,6B,28,2B,C7,E1,F0,50,72,CD,F2,69,81,54,E3,BD,36,E1,CA,FC,77,DE,54,7C,E1,F9,D9,B0,AE,FF,85,2F,6D,17,C9,84,E9,4A,AD,EB,A7,94,D1,59,9B,FB,E6,0C,3F,FD,BB,51,33,D2,65,59,9F,35,F2,8E,5B,20,86,17,99,A2,31,6A,50,BD,EC,DD,14,9F,12,B4,25,22,9F,B1,C2,93,89,40,8A,43,11,61,95,8F,C0,32,69,74,CE,87,7C,87,38,DF,DD,77,2F,76,C4,12,4B,38,C8,8B,CE,E8,BB,E1,7E,66,82,63,80,D4,B8,B2,72,3D,F9,CB,0D,03,45,0A,80,46,9B,24,08,CE,A7,AB,1E,1C,46,86,FA,21,C7,93,B5,5F,C2,34,C8,67,B8,9E,60,09,56,93,9C,0C,6C,29,70,94,2C,05,C1,CF,C0,F5,3F,C8,0B,3A,5B,10,12,56,E5,80,16,07,46,50,F3,7F,33,72,9B,A1,86,12,C9,9D,41,09,61,B5,D2,20,A6,83,CB,41,52,E5,9D,4D,EB,1D,D9,69,6C,2D,30,BA,46,FD,B4,B4,FB,BD,C2,61,DD,18,0D,5B,B2,E6,A6,03,39,8D,12,1F,F8,8B,22,1F,7B,CC,9C,12,64,42,18,43,CA,79,05,1C,94,5F,03,74,EC,9B,55,7E,D6,C5,47,19,FF,B5,F2,2F,CD,1F,DF,2F,57,69,64,E3,57,D6,75,CA,43,27,B8,CC,F5,1F,AE,63,20,30,7B,F1,8D,07,58,64,0C,37,EE,86,4A,1A,9E,B2,AC,90,86,B3,55,5C,2A,33,53,01,12,1C,E0,65,9D,45,7A,82,C0,00,A5,FB,1E,0B,C6,DB,71,5A,BC,5A,21,C5,F0,26,F7,DB,37,4B,A2,57,3E,55,99,C8,B6,3D,5B,C5,26,E5,34,57,76,85,B2,04,94,F7,1C,59,59,DE,FE,22,94,C5,AE,9C,67,95,C6,01,EA,5D,58,5D,14,7F,A9,11,11,AD,26,86,C5,A1,B9,8C,84,E1,E5,66,15,DE,0D,67,5D,CE,C0,9A,8E,8A,D3,D7,B0,61,41,B4,B1,52,5B,D5,C1,EA,BF,65,9B,F2,21,68,C7,62,A0,88,35,D2,77,99,14,BF,59,F7,24,41,8F,C1,AA,B7,33,2E,C8,AE,2A,3D,EF,3C,9E,84,1F,14,4E,9C,8B,31,DB,9A,44,86,C8,2E,17,71,5E,90,B7,E0,FD,3B,E5,43,9B,0E,3D,46,FE,F1,B1,3D,06,47,C6,DC,A9,02,42,EF,4B,15,16,99,FD,CE,91,D7,D7,5E,A8,A2,FD,A9,52,B1,E2,7F,78,11,3A,AB,AB,A4,53,93,A6,7A,A1,EB,8E,83,35,76,90,FE,45,33,F6,C4,E9,D6,E0,C6,80,C1,0A,12,BF,08,E8,D6,FD,C4,3C,DD,3E,A8,02,A6,DD,6F,C5,8E,B4,53,19,25,72,CF,09,4C,53,44,5E,7C,C7,C6,8D,D4,24,D4,89,D4,73,50,53,91,C1,F4,78,3B,E2,86,00,A1,49,58,93,1D,7E,EF,A4,6D,CE,D5,31,BB,31,E8,A5,14,5E,22,E9,BD,EF,ED,68,A5,E0,B6,DD,EC,7F,EE,BC,75,54,AE,33,0B,F7,76,77,FE,81,39,03,29,4E,02,BB,C0,57,24,47,B1,FE,5D,C2,66,C4,18,78,50,CF,87,2C,F9,6E,3B,2B,B9,7B,C6,F2,AD,86,53,FF,A6,DC,D5,92,B4,54,91,B6,6E,FB,A3,B4,60,83,DF,56,2C,E6,17,1F,57,58,E6,96,9F,94,8A,27,62,4F,F5,EA,69,E0,69,7E,2D,12,D7,95,CE,E0,62,8E,12,A7,DF,A3,CB,7E,93,7D,4A,93,70,CF,E0,E2,4A,10,7A,72,9F,F9,64,3D,D9,68,3D,1D,DB,2D,AF,28,E4,DF,C8,70,89,B4,F1,94,4E,A5,64,ED,7F,02,DB,09,10,D2,04,AF,BD,71,3B,BC,E3,48,C4,24,5A,37,BF,B9,B3,AE,43,2C,C3,B7,52,51,AE,ED,89,E3,51,13,EE,ED,C8,A9,1F,FA,D8,48,9F,90,1C,BE,51,9B,B8,DE,31,19,24,DD,73,09,3B,AC,C4,D7,2D,30,89,B5,A2,6F,0B,60,FA,16,DE,8D,99,1D,62,A9,93,03,2A,56,A5,5F,EC,9B,B1,45,90,EB,48,F7,17,E8,97,7F,13,16,01,EB,77,B6,FF,E1,A2,45,CE,52,95,DD,3B,19,01,68,0D,9F,53,77,87,B9,CD,A2,18,DD,21,51,A9,58,23,C9,D8,5E,3E,DB,2D,7D,CF,9F,E7,BB,6A,8B,76,B5,72,48,5F,9D,4D,B5,14,0A,D6,E7,E7,5B,F8,51,00,1F,B6,25,8C,36,6B,80,4E,D7,02,6F,8A,73,1A,4C,12,9F,E8,DC,FE,7B,AB,B4,9B,3D,20,7A,BE,7F,4F,F3,55,FC,30,47,41,49,D9,3D,82,FE,5C,02,E8,C1,57,B2,17,B5,29,F5,62,BC,C7,74,5F,1D,AB,5D,59,8F,47,5B,83,04,E2,DC,F9,59,9E,4F,44,B5,61,91,63,CD,34,2A,B0,F7,2A,6C,50,61,64,71,1F,91,1F,45,40,DA,FE,80,09,5D,A1,C6,8E,76,44,78,D7,92,F4,89,52,AD,53,FF,CE,90,7F,23,8C,F8,78,E5,94,C9,18,99,00,D9,68,88,84,69,E2,83,98,54,AC,71,BE,F5,DE,58,F2,A9,2B,73,56,E0,D9,45,78,ED,68,68,59,7C,4B,F5,56,ED,43,5E,80,E3,D7,AF,C9,23,A5,28,06,BB,1A,FA,1C,A9,52,12,95,6D,5A,DA,F0,9C,3C,90,77,B5,17,EA,FE,A9,47,CE,70,26,6C,6B,10,71,A8,F1,16,8D,5A,55,D2,98,BB,95,1A,AF,D1,9E,F7,72,ED,03,9F,7F,B6,81,80,7F,74,C9,E4,7D,65,79,D7,61,50,C0,B2,A5,B7,5F,EC,04,AC,1B,A5,0B,22,83,53,81,5F,54,ED,CD,F4,6C,52,85,D6,F0,C2,03,FC,04,E7,40,4D,40,81,B3,B6,1B,87,CC,50,CD,C6,50,2E,DE,76,C6,B3,29,09,47,0D,9F,23,2F,56,F7,3A,EE,53,94,33,D4,E6,54,79,A5,B2,90,49,F5,51,09,C7,B2,C2,CA,F9,4C,44,69,FD,4A,B0,24,17,1C,40,F0,50,17,6F,F5,FA,4F,4E,EE,6A,73,AE,AF,04,BF,2F,13,F7,47,B8,14,9C,EC,49,7B,5A,17,95,76,33,75,43,B9,26,36,2F,A1,C1,F0,47,8F,89,43,F5,A0,12,33,47,8E,6A,5E,B9,58,F9,30,F2,C8,0A,78,09,28,72,E8,1A,7D,0C,8F,76,AA,8E,F8,EE,D8,AC,00,53,B9,CB,10,C0,44,1E,B4,EE,9B,7A,06,A9,17,C2,05,F2,97,01,FF,2F,64,73,BF,AB,16,5D,15,90,53,2C,95,BB,D7,F7,36,A0,2B,C5,B2,A1,36,78,A0,14,0B,9C,99,CE,11,C2,0D,26,C4,AC,F1,6D,AB,51,3C,D7,82,81,4B,D3,31,0C,4F,94,7F,39,C6,9E,30,C6,0A,0C,CF,48,6F,46,C4,51,3E,B9,25,E8,31,76,53,B7,41,D9,6B,62,21,E3,75,A4,39,81,F8,58,01,70,DD,57,34,F5,88,23,A5,FB,5C,EA,5E,A7,98,2A,59,87,B5,B4,B2,73,84,EC,DE,67,4A,78,CE,65,7A,54,CF,5C,FD,E1,F5,73,5A,2B,31,7D,10,95,1D,D3,FC,2C,77,C9,10,21,DE,4C,12,27,EA,5E,4F,B8,19,5C,F1,27,D6,02,55,32,6A,4E,63,84,F9,C0,43,77,23,C3,CB,2E,15,BF,C8,D0,DC,40,7F,28,06,7B,7D,F3,62,CD,4B,18,19,4D,67,1D,91,B8,B7,49,B0,E9,B5,24,27,5D,78,38,B4,54,C8,7E,A0,6B,38,89,95,9B,6A,A6,6D,9E,75,8A,AA,C0,39,28,E9,53,C7,E5,D6,08,15,2E,F1,18,3E,38,89,DB,29,48,A1,B1,D8,62,63,85,84,06,2A,74,5D,A1,71,9D,17,CC,C4,D0,12,01,FE,B4,89,49,AE,0A,C9,BA,27,F9,CB,62,26,54,28,FC,55,49,D0,C5,C8,5B,2F,40,85,E3,1E,07,26,00,D5,50,FF,03,3A,A0,D4,A6,8C,2E,52,92,F6,3D,1C,D9,A8,68,0C,8D,EB,66,C7,D6,95,46,F9,F5,0D,97,54,66,EA,B4,E5,03,31,CF,64,25,6B,66,63,A7,3D,11,D8,FA,BF,AA,90,E4,45,77,32,0B,2E,A9,AD,59,C9,1F,B2,ED,8C,1A,D5,8C,E0,52,BA,B4,1D,27,D4,EC,9C,1B,AD,75,05,C2,42,AA,FE,0E,31,2D,98,EE,83,99,38,33,98,24,D2,08,51,88,44,45,F9,4F,6B,87,1E,E6,E1,96,A0,0D,DA,F9,35,7B,9F,E9,39,D5,B0,A3,28,43,02,D1,09,A7,46,14,B7,16,05,49,89,FA,E2,4A,E1,A4,B7,DD,69,37,D3,7C,CD,A9,1F,AB,9B,FF,55,B3,ED,B9,EE,4E,02,38,2F,47,20,FF,DA,BD,24,F7,3A,E2,37,A7,BD,56,A8,FE,0B,02,1B,46,FC,76,30,9B,D8,0A,1A,36,45,A4,7D,81,DB,02,27,20,E3,94,51,51,6A,C9,D9,68,3B,C0,A7,24,95,7D,33,9B,DD,D1,76,C5,8B,72,32,84,05,CE,0E,DF,A4,C8,9E,12,C1,5A,46,B5,6D,90,DE,0A,51,DF,0A,FE,31,20,6D,F5,19,CE,3E,AD,50,45,CA,F1,BB,AC,E6,0B,54,0B,D9,E2,F8,D0,12,CA,C4,2E,11,5A,8E,67,9C,44,84,84,15,9E,10,1E,6A,15,EA,5D,93,80,CB,22,BF,E1,46,2B,A6,EB,91,0E,60,A3,D4,12,64,40,5A,C6,95,89,23,E1,39,A8,19,5F,BB,0B,75,15,66,44,43,2C,90,DD,51,26,B0,2C,1B,BF,58,79,E7,CE,57,93,F7,D7,EB,25,E7,E9,2F,4E,65,48,10,1B,E6,2C,7C,33,88,5A,4D,B6,4F,DE,BD,D6,66,32,DE,75,42,10,A7,A7,A3,AB,47,E1,13,CE,84,E0,6B,E8,11,28,EC,D7,F7,2C,61,CA,75,78,2F,3F,EB,DE,BF,6F,23,4E,77,6D,7A,AC,65,C5,89,BD,87,5A,15,32,7F,E9,6D,92,26,E3,FC,6F,10,7A,46,3E,84,3F,92,02,66,4D,3C,C3,9E,07,AE,8E,1E,6F,EB,65,41,68,13,1D,F5,E5,5A,DC,80,12,E5,9C,D6,05,72,80,2C,FE,1F,C0,99,97,04,E1,DC,03,47,6B,4F,7A,13,8B,FF,B5,9F,30,3E,08,F2,5B,D1,47,B8,16,75,13,F4,94,E4,32,EC,54,71,9B,69,A5,E7,38,57,3D,20,81,EB,A7,08,4C,0C,96,CB,50,F8,46,B9,FF,C1,AD,48,19,0F,D3,A5,27,2E,26,05,B1,1E,D5,72,C6,F0,94,3A,A7,F3,73,DC,96,E0,02,26,71,CF,08,BD,10,72,CE,96,00,BA,2F,B5,6B,F2,93,41,3A,0F,92,F0,3D,9A,0D,5C,CE,1A,0D,7F,E3,1D,CE,61,E3,5B,60,26,51,F0,B5,8C,B5,63,74,B9,0C,CD,35,8F,A6,B4,86,38,40,19,D9,AD,86,E6,FC,0E,D9,3B,38,37,E1,35,39,14,8F,7D,E2,C2,51,22,15,35,90,59,11,BB,03,53,2D,75,36,CA,81,F7,C4,AF,E6,25,39,B1,EA,FB,A4,4D,6C,F9,36,35,B4,8D,9D,4F,31,4C,37,07,7B,62,A2,36,16,77,E8,67,D2,98,EE,CA,32,5B,88,49,78,36,DD,F9,A4,89,82,6E,DF,72,02,B8,AA,9A,27,E5,8E,63,3D,35,C8,A2,2C,FC,7B,B5,64,3A,89,67,CF,04,E0,45,09,96,DA,E7,E6,90,78,AF,6C,32,06,42,2B,51,7B,66,AE,6F,06,0F,34,9B,80,4F,3F,1B,C0,09,BA,59,51,57,D1,79,CC,1F,8F,2C,F3,AA,8D,A8,DF,90,59,F7,8E,01,3E,0B,06,BA,44,C4,A2,AF,58,FD,F5,5D,2D,D3,66,B3,56,3C,DA,61,B3,B8,2B,7B,2D,C1,E1,1D,13,0A,D0,E1,9E,1C,A9,EC,D4,64,FA,58,07,83,FA,2B,05,61,8B,BA,E4,74,DC,FA,94,03,69,F7,83,CD,84,75,0F,C8,D7,F5,11,DD,D6,31,ED,06,A9,D9,F3,3F,53,AE,70,95,2F,C2,5F,6B,40,5D,0C,A4,40,E3,F6,83,C4,75,CC,61,3D,E5,C7,93,0D,7D,B4,D2,01,D4,F0,20,C7,D2,A2,5C,4F,DC,04,8A,C7,76,67,0A,C9,98,C9,A0,D3,F1,CE,8B,B7,8E,07,90,9A,66,18,8A,37,26,2B,DB,2E,C8,97,86,F3,BF,F3,46,F9,37,C4,4C,D0,A6,87,68,AE,A9,17,02,3A,52,66,DE,84,19,62,AD,BA,09,B7,3E,8C,99,7B,68,9C,B4,83,B4,1B,62,94,C0,C2,98,34,68,E7,05,89,EF,7F,D6,40,AD,00,DA,9C,62,81,F4,08,46,57,42,91,80,81,7E,EE,F5,35,1B,88,0D,97,08,28,DF,CB,1B,F2,A3,CC,AA,51,1C,D1,8E,5D,8C,2F,3C,9C,34,13,23,7D,69,CC,64,FF,09,5B,D1,42,48,4A,BC,59,A1,A6,46,73,F3,13,46,C7,E5,B5,B9,87,67,CB,E6,DB,78,6F,47,84,28,07,7A,82,AA,36,42,B9,04,E3,9F,4B,94,22,F9,E9,FC,AE,07,0F,77,82,1F,BD,F7,4D,3D,25,4C,3D,B1,97,2B,B2,47,CD,90,DC,81,0F,F6,D6,66,43,70,04,8A,1B,CA,5B,C8,20,A9,29,10,2A,22,7D,9E,3C,69,10,76,75,B5,22,76,8A,45,AE,6A,F9,11,13,7E,60,FC,B3,87,97,70,4F,B1,EA,C7,77,6E,B5,C2,5C,C5,3D,24,9E,73,23,C7,08,4C,7B,82,2F,3A,A0,95,16,F5,E1,28,EE,6C,44,CB,C5,00,D7,5E,0E,7A,83,E0,F1,16,EC,28,7F,FB,91,E8,EA,19,56,28,95,AF,F5,72,A8,6E,D4,27,E4,90,3B,F7,3E,81,99,E4,BA,CB,19,9D,38,FD,7E,7E,48,59,B4,74,4F,CF,0F,49,99,F9,FF,0B,FB,6E,10,46,AA,CF,03,9F,05,92,BF,F1,1A,F5,DF,90,70,DA,95,9D,FE,0C,0D,3E,3A,E8,D8,16,A2,C7,15,77,8C,F3,43,0C,5E,8F,06,B5,C6,E4,27,75,D3,B7,8B,3A,1B,45,AE,1E,93,B7,B2,34,C8,84,D8,83,A9,FA,C0,DA,F3,6F,91,64,C6,8F,19,F4,2C,69,03,FD,FF,CD,CC,0D,49,23,40,1F,E6,42,E3,BA,E9,C7,9E,7D,AA,5A,D9,DB,57,1A,8F,50,15,69,80,7A,05,3A,EE,5E,E3,76,04,09,EB,C8,B5,08,C2,7D,6E,F0,D0,DC,E4,60,5F,F8,89,4F,15,5B,2C,F2,FF,30,EB,08,5D,04,85,FA,20,43,BA,9B,3D,82,C0,8D,F2,7B,6D,10,72,7F,FE,08,88,02,86,18,1B,69,1E,47,80,80,4D,40,BA,3B,C6,9F,31,3B,03,13,98,E2,A1,2D,DF,30,A3,8A,70,A6,12,9A,E2,6C,BD,53,50,33,8A,8D,97,04,1B,0D,67,A3,B5,6F,6E,3A,13,D4,BD,5A,1F,15,5A,8A,B5,5B,49,4A,FE,DA,B5,A6,8A,92,DC,82,2E,E2,3F,18,52,2D,1B,DB,D5,46,7F,47,A6,5E,ED,0D,51,25,0F,29,C0,ED,75,7E,4B,19,5D,70,E6,E1,D9,A2,7A,B9,2F,21,A0,23,B2,D1,33,B7,01,0D,1B,7B,EC,09,0E,64,DE,4E,58,8A,C9,64,3C,DE,09,AD,DD,0A,24,E6,7C,34,B6,F7,6E,EA,A1,F5,C4,7A,D3,5F,30,CE,DA,59,4D,6C,91,DB,F2,2F,5A,F6,3F,27,5E,F3,C8,96,B8,8E,53,7A,81,5D,A2,E3,12,96,35,B0,94,34,2C,59,9A,DF,E9,7E,FA,A9,F8,AC,9A,76,47,79,66,07,B2,EE,AE,03,B1,38,0E,51,0E,D5,1D,AC,30,62,30,25,AE,14,71,29,A3,D6,E6,7D,E3,D3,55,D2,A3,6F,A4,A2,78,9D,29,B3,8F,A5,DF,00,AC,AB,3D,D1,26,47,87,C8,F7,9A,21,13,68,9E,C2,87,23,C8,81,F3,CD,DA,7E,37,AE,E2,DC,F0,B8,82,18,B6,A1,F2,05,2A,49,71,D8,E3,CD,53,88,D0,86,08,74,FD,C7,4A,21,E6,41,79,2A,D3,29,A9,09,33,49,17,4A,11,A7,21,7A,CC,27,4F,1D,DD,DC,53,AC,58,40,C5,0F,C6,53,1D,A4,C8,C7,03,95,B7,24,F8,5D,77,70,AA,D5,C0,F1,78,2A,89,90,09,56,37,85,83,A9,39,6D,CF,48,04,01,D8,F5,9C,9E,79,EA,08,C1,2F,28,4B,60,9E,F9,08,03,F4,14,CB,71,24,30,B4,E2,06,0B,B3,3C,5F,D9,20,34,FE,58,76,D6,0E,64,01,75,F4,73,50,D1,73,07,4D,52,38,08,D1,44,CB,83,D5,28,DD,53,2F,27,01,58,A6,66,F0,79,24,FA,43,0D,AC,B3,25,B0,AD,02,02,2B,43,B9,B7,72,C9,7E,14,3C,B4,82,F9,AA,D4,05,3A,5C,E9,14,93,4D,38,77,0A,70,74,67,7E,7A,FC,6B,49,B4,CE,3A,1A,19,9A,91,EC,6A,14,C2,C6,89,8F,B7,27,DF,17,7A,7F,C7,C0,DD,8F,D5,5F,B8,4A,A0,94,FE,36,D0,B5,66,67,C3,F6,EF,66,6C,82,9C,E5,57,43,1D,80,EA,78,BE,EB,DC,EE,25,28,D6,E4,F4,B8,84,D3,D4,E6,EE,C4,B0,E2,8A,8D,D8,97,C3,3D,F3,47,E7,DB,4B,A5,BA,09,6C,48,AD,2C,4C,7D,07,6F,4F,85,6B,64,34,BB,53,3F,3A,A4,DF,9C,D2,7C,74,2F,B4,FC,12,56,51,91,4C,9D,BD,34,1F,19,2B,83,DD,60,A8,8A,0E,92,45,A1,1D,BD,A5,48,31,B2,B5,01,8D,4C,98,B1,1F,C2,F4,02,53,E1,F4,7B,23,5B,14,0C,AC,79,B7,D0,D1,D9,A4,B9,5A,E1,8F,74,E7,EA,96,D4,CA,CB,E2,4D,18,23,51,EF,13,1F,1F,2A,FC,62,5C,DA,4E,4F,0A,91,D8,09,BE,0A,32,B0,08,54,05,5E,5E,BB,34,14,24,56,2E,C1,8E,55,13,0C,2C,32,4B,D8,88,E4,93,51,5F,4D,11,8F,B7,B8,33,6E,AB,C4,07,84,F8,19,FD,CB,53,2D,FE,EC,23,30,F3,6C,76,49,8E,01,10,56,C4,25,FD,E0,52,C3,63,DC,11,DB,ED,44,A1,F9,0B,32,13,96,AC,09,BB,AD,B3,B6,8C,6A,C5,0C,F7,78,17,5F,00,4B,8D,8E,AF,C9,0C,4F,E2,D8,E0,21,67,DC,DE,78,76,30,0D,53,DF,BA,1B,31,65,CB,C3,A3,E4,11,21,32,A3,97,C2,AA,EA,21,58,64,2B,9D,EC,20,B6,48,53,7E,E8,3B,BE,C3,20,78,E8,BC,3F,9F,B4,24,28,F0,9A,D9,18,02,94,6F,77,A6,EC,58,97,74,64,B3,7A,26,7D,60,59,1A,87,54,77,05,AE,51,52,B4,B7,31,0D,21,43,8D,1C,79,5B,25,6E,35,37,26,27,F0,DD,7E,AA,6A,D4,6B,A0,2C,AC,F3,CE,B7,85,D8,FB,52,66,BE,63,56,BD,02,B5,4D,29,00,E9,4F,4F,24,6C,1F,85,C5,47,17,2E,2F,2C,BC,3C,DA,31,E8,BC,97,84,7B,5E,40,06,85,4A,A6,04,19,FA,DA,AB,1D,BB,CB,1B,BB,C5,90,F0,10,9E,38,DE,CD,E6,A6,88,B9,C3,29,D9,28,D2,D0,A0,E8,5E,A8,95,3A,D3,82,5B,6D,74,A5,C8,94,B6,D7,88,52,CD,48,64,34,90,9B,BD,1E,C6,F0,9D,D0,B1,B3,B3,7B,F1,2E,9C,87,F8,D3,AD,0F,C0,1F,FE,02,95,94,34,F2,D3,0F,CD,2F,14,97,AC,DA,86,D2,99,DB,AC,95,74,57,B1,F1,C5,3D,75,97,2D,C6,E0,EC,4F,D8,CE,79,51,87,1C,DF,B5,CF,1A,8F,03,31,31,58,23,51,C8,90,89,47,1B,A2,1C,FC,E8,F7,F7,1D,5B,61,A0,09,F7,DE,21,44,0A,5F,7B,7D,68,EB,A9,FB,E8,6A,1A,45,9A,FA,AC,51,6C,70,9C,52,91,AF,DB,5B,B2,AE,5A,7A,41,84,E4,91,F1,73,AA,FE,B4,52,41,2E,AB,93,D4,B4,4A,5C,16,EC,EC,57,0D,B4,D0,A9,80,77,8E,4F,33,F9,F7,1F,05,3B,59,DD,F4,1C,65,67,EC,52,3E,90,A0,57,33,11,C1,07,DA,6D,93,70,AD,6C,E1,23,10,45,B6,F7,A5,4B,43,A3,AD,4C,B1,9A,01,78,08,C3,1D,04,77,79,AA,C7,CB,5F,23,71,76,24,33,F5,DF,AB,F9,33,D2,60,9B,E2,C5,3E,57,44,1B,6E,73,E5,43,3F,45,16,88,C9,BC,A8,CA,D2,77,3F,F9,4E,FC,CD,1B,58,6E,94,C6,8F,55,80,8B,C7,88,1D,09,B2,03,0B,B7,12,34,29,AB,FA,46,80,61,08,60,70,4A,AC,16,25,4C,F6,C3,F2,8E,E7,92,31,FB,0D,6B,77,C7,84,BE,9C,06,95,47,99,60,82,57,8A,DB,E1,8B,2B,82,19,5B,E7,9F,40,B9,34,AB,92,5E,B9,95,3C,54,0C,AE,09,F6,E5,19,19,34,15,4C,E9,34,15,77,BC,2A,80,72,93,9D,AD,23,54,FC,4A,41,9D,35,66,1A,A3,73,50,79,BB,FD,E7,B4,8D,B8,6D,AC,6A,CB,C6,C7,8F,00,FC,A6,D6,35,0F,1C,29,C9,0D,3B,0B,7E,F0,25,8E,83,57,36,FB,10,9D,DF,C3,12,1C,78,A4,BC,34,27,98,96,BA,D8,39,CE,E9,BD,0F,FB,82,36,B4,7C,73,43,AD,A2,F3,6F,A1,95,0A,F9,A8,E0,74,2E,EE,D0,7A,D1,8C,92,4E,98,C8,5B,8B,C5,64,01,BF,41,F8,83,0A,CB,31,A9,34,FE,DA,6B,FB,8B,93,3F,3C,A5,BA,A3,C4,A8,CD,A9,9D,C6,E7,A4,3B,B5,96,6E,DE,A2,2E,BA,96,55,74,08,DF,03,4B,6E,27,24,7D,12,4D,FF,C8,DA,D3,BF,D1,94,02,75,9C,B8,B4,ED,D9,C0,17,22,48,C7,18,9C,7A,07,34,62,CD,91,55,B4,F3,94,29,91,1D,93,98,D1,0D,AB,34,91,68,EF,15,50,F6,B2,C4,17,17,E6,9C,53,1B,B9,01,2D,D9,A7,69,9A,49,E2,F7,E1,68,69,66,F4,4F,C5,A8,42,69,8D,C6,28,14,80,A8,BE,2D,E8,99,76,BF,6C,47,9D,C6,C8,E9,E0,F0,B0,90,64,28,15,70,F9,44,D3,A0,A2,76,49,6D,97,1C,D3,51,8B,1B,9E,2C,74,5C,D5,CC,79,6A,CE,AE,DB,64,CA,06,16,D8,51,F1,31,9B,41,70,C5,94,FB,D3,DB,94,66,FC,D7,02,0C,E8,A3,8A,04,06,03,42,DA,C6,3D,13,1D,D7,A6,0D,D7,B2,48,95,C2,4D,1B,5C,FD,A3,E6,95,FF,FE,CE,56,F7,58,EE,BC,E1,CB,B2,2C,D4,92,16,8A,AB,3F,DD,F3,6E,F3,3E,78,32,51,B3,36,30,EE,9B,56,39,04,2A,70,3D,B9,AD,C0,50,86,B2,69,6E,69,93,0C,66,0E,EF,C0,1B,50,DE,76,DC,8C,EC,FA,FE,BD,63,A6,C8,11,FC,66,14,78,7A,76,9B,71,4D,46,FC,5E,38,3F,62,74,53,BD,D6,F5,43,89,3F,D5,6B,83,87,10,B8,8A,FD,27,52,9F,31,C2,07,84,55,5D,B1,8C,9C,2B,33,C3,7E,CB,63,11,55,98,0C,F0,AB,00,34,25,F7,74,94,8E,D8,4B,18,75,5D,A2,2D,7F,09,BB,63,1F,D5,F9,0C,9C,D4,CC,FC,D7,F5,C0,BB,AB,05,6B,5C,0D,97,92,88,0E,4A,5C,CE,99,12,7F,47,E1,B5,96,10,BB,A5,3A,9B,2F,E4,AF,F1,2C,F2,5E,5B,1C,9B,73,2F,5A,C2,1E,40,FD,5A,92,EB,CA,DC,26,70,60,E9,76,EC,BD,31,F3,50,38,3E,A6,05,7D,38,3C,1D,12,2B,84,A5,86,2D,D5,46,51,FA,CD,EA,7B,3B,78,2A,46,0F,60,42,1B,CD,E5,B8,DE,3B,D0,46,1C,F0,50,59,49,A8,FE,1A,D2,B6,3D,8E,37,4D,FE,8F,3D,A4,BF,51,3D,92,EE,DC,0F,6F,7B,4A,CF,F8,9B,F4,8F,1A,D2,CE,D5,B2,97,CB,6F,59,44,47,DC,00,DF,9D,EF,E2,6E,AB,BA,FD,F7,80,31,AC,D1,0D,87,CD,01,CB,03,D8,63,8F,DC,83,4D,07,77,1A,A0,D2,E7,5E,ED,0E,72,45,AC,8C,3F,68,F2,A1,EB,D3,A9,52,85,9C,E2,D3,9F,92,C6,8F,08,1C,5F,13,A3,73,69,42,AC,97,EE,FF,6E,AF,3C,DB,09,A5,E3,A7,8D,37,3D,40,8A,B7,1C,37,B2,F7,04,72,10,A5,EC,B0,DD,46,44,1F,57,79,98,0D,7D,8D,05,76,52,77,51,A8,85,02,BE,71,38,E3,08,F3,58,23,82,E7,3B,86,75,86,08,FA,DB,47,47,CD,DF,1B,20,70,F1,88,B0,55,0B,D9,E6,9C,F4,0E,71,22,3F,FB,EC,8F,36,7A,4D,4A,43,1C,C8,15,1F,BA,B0,F6,3D,AF,1D,EA,54,C7,1F,0B,8A,42,5A,B3,8E,09,0B,13,D8,29,A7,1F,04,70,82,17,DF,0A,B5,C7,60,15,E2,C6,F9,FC,59,1B,7F,4C,5A,F7,EE,E2,73,8C,50,B5,3A,AC,45,C0,6C,12,78,93,0B,B8,E4,4D,9B,57,14,04,62,0B,C1,27,6B,4D,58,71,FD,DB,F5,72,53,85,65,70,DD,01,83,B0,1A,ED,5C,70,60,D2,54,27,C0,51,4B,E6,93,1E,14,18,98,9C,8D,BC,DF,D1,2F,6B,BF,4B,5F,EB,C4,74,05,85,EA,99,87,33,02,EE,47,7D,42,78,F8,A7,14,91,34,38,CF,C7,EA,10,4E,E5,65,85,6B,74,43,9E,3D,95,7B,6A,57,80,5A,32,FF,04,42,E2,BA,DF,51,95,F9,88,67,28,8D,5F,19,7E,06,49,AD,E5,A8,2F,A6,7F,70,E6,88,6E,8E,2B,9F,14,82,48,BA,CF,DB,98,3E,C9,32,A7,09,BD,6D,75,8B,DD,92,28,3F,33,61,AE,B7,B2,16,D7,8F,F2,85,A9,07,F9,C6,83,39,07,3F,A0,65,4E,DC,75,49,1E,94,F9,AC,BB,63,2C,C9,0D,FF,2B,34,4C,D3,5E,6F,30,E3,AA,BF,5F,C7,B4,0C,19,48,30,1B,94,48,17,72,F2,55,D9,4D,0C,1B,6A,E4,B8,22,17,FB,4F,93,BF,ED,97,CB,C0,67,9C,75,F8,8A,89,B5,89,0B,B6,77,FB,F9,CD,F3,AE,71,D7,2B,D3,B7,C5,F5,54,9A,E0,3D,EC,D7,9D,E1,68,52,E8,41,E3,9D,E3,80,EB,70,26,26,99,77,1D,B2,FC,8F,30,DE,D2,2D,91,96,A4,C6,5C,BE,34,AF,A7,6B,3D,D9,50,FE,09,5B,FF,84,D1,70,B7,BA,0D,F2,6D,1D,99,D8,C6,F6,2E,CF,A4,EB,D8,02,C9,BE,AC,FA,FA,28,FC,CA,27,FA,7E,43,BA,19,4C,AB,1C,11,44,FE,E0,B3,6A,92,F4,05,89,EF,AE,B4,40,90,CF,5E,C5,D3,7A,7A,9D,23,1D,B3,18,9F,99,A5,A8,49,53,23,87,D0,F6,42,94,55,3C,27,DD,F2,2A,57,68,52,64,E0,F6,C1,F8,E3,E4,FF,8C,C7,0D,E7,31,53,4E,85,59,39,39,8E,14,10,3B,0C,B0,C0,AE,F7,73,DC,49,18,52,07,84,2B,83,53,99,D7,56,CD,6D,90,0D,4D,EB,BC,C6,EF,45,28,CE,4C,87,E1,FF,B7,E9,EC,0C,DB,2D,48,21,79,11,81,1D,E9,E7,2A,C2,5F,36,17,92,7E,F0,21,9B,D7,4B,35,3D,00,F9,6C,8F,E0,29,14,99,10,7E,D1,C7,E6,7E,61,24,48,19,0A,65,91,EB,E4,A0,2F,64,EA,3F,4A,35,88,B6,B7,83,6E,7F,5D,66,70,B5,1A,16,64,85,68,5B,D5,1C,1B,AC,89,A2,35,2D,E0,37,D2,5A,3C,12,14,94,00,24,73,6A,B8,78,E6,9F,22,F9,EB,FD,20,15,F5,A9,3B,EF,60,95,FF,1F,D2,7F,78,FF,D8,B4,AB,9D,A2,B7,0E,CA,E4,B4,CC,AF,DF,E6,62,16,71,EA,BC,22,65,E5,63,38,37,C8,AD,20,61,B0,7B,F2,B0,CD,E7,CD,16,9A,AF,86,9B,50,95,06,80,08,3C,2C,75,A3,54,A9,2A,29,08,9D,71,94,60,6A,F5,5D,AF,23,95,B4,BD,E7,B5,B1,F8,F7,94,7E,D1,41,50,B6,0B,34,80,D3,DA,7D,A0,2C,58,75,68,3B,A6,74,6B,EB,6B,0F,B2,92,2C,F6,8E,13,97,73,CE,31,EB,69,F1,D6,02,69,D1,DA,A3,AC,84,36,F8,CC,82,36,58,BC,EB,52,1D,D5,EB,E3,BB,2D,69,14,9A,D2,E4,47,26,D3,77,56,6A,D4,A2,8C,A4,3E,79,5E,2F,C7,13,C4,20,BE,02,E1,90,82,37,C4,58,A6,92,AE,37,AB,F5,E2,5C,0B,E8,85,A5,B9,5F,28,13,BD,BB,B8,30,0D,99,5C,2B,5D,95,7A,58,B1,34,EE,B4,58,38,8B,67,70,BA,CF,4C,F2,8A,87,8A,0E,35,83,55,4D,A4,34,BE,5D,08,5C,E2,3E,C0,A0,D8,CC,AF,6F,D5,98,29,2C,FA,F9,2B,0A,B0,E2,30,8F,6D,F7,D3,95,81,78,24,E1,1E,29,0F,BD,42,11,C7,79,9C,B6,D6,AB,86,E4,1D,8E,5E,17,1F,2E,38,16,84,29,0D,42,6D,DA,2F,AB,73,04,70,8F,C5,17,4B,05,26,8C,77,00,55,7C,1C,BC,9F,56,EC,2C,69,7C,B2,7B,A0,46,8E,F7,3D,1F,A7,FE,FB,2D,A9,94,72,28,4D,39,D9,86,B4,76,5B,0F,CB,D8,09,B4,2B,F4,13,2D,F6,B3,A3,87,2B,90,D6,C0,A2,09,14,DB,61,82,F1,22,0D,DC,F4,FC,FE,FE,9A,36,08,05,A6,EE,C6,0B,70,34,B9,92,22,BB,6E,9B,72,98,DB,03,E7,E5,22,C1,96,05,59,DD,1D,2E,B4,24,3D,3B,93,B1,6B,F4,5D,B4,00,A1,4C,AF,45,D9,12,07,22,01,68,9E,84,98,8F,64,33,A8,31,8F,96,74,03,B8,BA,C1,E9,B8,CA,B9,2A,8C,57,73,14,12,35,DE,56,E7,F1,27,98,49,3C,95,91,0F,52,8B,F7,BC,65,11,1C,B0,C9,88,D0,A6,72,7B,E1,E1,7F,85,F5,03,4A,86,77,66,FC,D8,EB,B3,01,2B,37,97,4F,16,A6,34,B9,DD,A5,47,7B,DE,D0,37,B9,0A,52,4C,E9,2F,30,F2,FE,78,E7,E6,27,5E,57,FB,F3,1A,90,47,20,B1,FD,E7,B2,19,34,0B,B6,87,F3,E3,45,2C,6B,3F,26,E6,59,97,14,50,0F,D0,2F,A2,E0,0A,85,48,D6,E5,27,3B,C3,35,A7,18,A0,07,65,22,C0,D7,4C,15,14,F3,B2,EE,C1,B1,7D,2D,DE,05,45,32,94,05,88,6C,FA,D1,F9,60,D4,07,3B,64,5C,FA,62,AC,5E,A7,E0,4A,FB,C1,D6,05,F8,3F,2F,D9,C4,F2,E9,09,53,18,BC,AB,19,53,A7,85,24,91,93,91,08,69,CE,FF,9C,E3,55,CF,9B,CD,B8,4D,00,30,B1,DD,3C,8C,5A,9B,96,82,D4,9F,A4,86,E5,6A,FF,9F,C0,F0,5B,1F,0D,63,8B,AC,E2,48,65,1E,FD,43,78,19,6D,3B,0E,AB,A7,5A,78,FF,63,01,9F,5F,12,6B,D5,54,0F,A3,92,87,24,98,59,1F,48,82,20,C7,A3,5C,79,5F,B4,E6,AA,35,71,68,5B,E3,9D,DF,FC,E4,8D,CD,0F,B3,90,F2,69,DA,40,F1,13,DD,75,DA,5E,30,A9,56,BF,0F,76,93,B6,5D,88,4B,47,9E,E8,09,AF,B6,41,D5,38,87,3D,72,CB,0B,B1,13,A1,4F,22,E3,2C,3A,C2,96,4C,51,88,49,01,77,F7,5C,5B,5D,4E,18,AF,5F,3E,37,B9,1A,88,F3,FA,36,FE,77,11,80,A6,33,4C,E6,D7,D0,16,A5,90,59,5F,BC,21,38,F1,E6,C5,54,2F,18,88,E2,26,9A,1B,C3,62,C0,B5,B7,46,79,5F,4C,2D,4A,C7,20,42,13,4D,79,F3,85,C2,B8,18,D3,69,63,ED,B2,1E,AF,43,6D,CD,8D,CA,30,DD,13,D1,C6,C8,D0,25,0A,BE,F5,01,45,5B,97,5C,60,48,F9,FC,C0,59,A0,BA,88,D3,A1,B4,26,C3,00,24,CF,7D,1E,8B,BE,D4,25,7D,E0,B9,53,3E,85,4B,8B,29,F3,28,9C,CD,66,79,16,30,7E,6E,91,1C,55,77,11,EE,09,7F,3C,84,5E,1D,1D,05,C9,78,A9,67,5A,B0,7A,A5,4B,75,DD,A3,BF,8E,BE,F5,BF,87,CE,41,FC,48,EB,7C,8C,70,46,D0,39,E7,0F,7C,80,76,59,02,94,E1,A2,5E,99,9B,90,93,B3,C1,83,B0,7B,C6,68,DD,AE,FB,45,D9,E3,29,E4,19,50,32,F4,5A,19,E2,74,51,E2,8C,91,5A,A9,01,2F,68,C9,2E,F3,1F,26,46,75,F9,A6,F2,CE,58,36,3B,2E,A0,8F,15,40,14,85,67,43,B2,26,01,60,53,39,DC,BB,90,E0,CB,1E,86,F9,13,E3,AE,EA,30,F7,45,87,DE,63,85,1C,B6,EA,FE,0B,E0,EC,10,69,25,6D,C1,42,92,7C,EC,D5,62,9E,D0,7F,53,12,EA,AD,AE,39,50,E9,E6,FE,7E,C0,B8,62,74,76,EC,BF,26,D6,15,39,01,B0,61,AC,88,EA,55,93,E2,FC,77,96,DF,61,90,29,E6,2F,EF,AD,F4,35,1F,94,8B,B7,59,89,C7,8B,1D,7C,DF,47,6F,5F,27,44,6E,1A,CC,0E,0E,09,D9,6E,95,8C,94,86,52,58,BF,E4,E2,65,61,74,3F,82,E6,CA,79,F4,A7,EF,67,B0,8F,C8,EE,08,71,C7,D3,0A,96,D7,A9,05,1A,68,8C,0C,E0,CF,D9,9B,3F,31,70,31,FD,63,D7,6A,AC,9F,1B,CF,1B,8C,2D,15,A1,CF,44,C4,5F,DB,EC,85,09,FD,3B,D6,BF,8C,77,1E,3A,3C,8E,32,8B,BD,FE,02,15,7C,FA,93,9F,6A,A8,69,A4,A7,C6,58,D0,00,1B,E5,86,5C,95,FF,FE,5A,AB,5C,C4,27,D2,4D,FC,CA,73,87,A8,31,0F,F9,F3,D9,E8,3D,21,A2,6C,E9,03,31,84,3D,E9,AB,7C,74,31,CD,9E,E5,3D,27,95,D5,93,AA,2D,E2,6B,69,02,E0,18,7F,E6,64,53,51,09,11,FD,6C,16,08,3D,00,EA,5A,65,F3,17,A6,94,E6,CC,FE,B3,F2,F1,B5,B6,A8,72,76,15,EC,F0,16,B8,11,83,09,C9,37,B5,B5,F2,D9,0E,EA,42,E7,99,24,C4,B2,37,D4,98,6E,54,7E,AF,D7,6F,14,CB,6D,E2,23,B5,D9,03,3F,40,6C,1B,B5,45,40,BC,56,3A,C3,DD,F1,C1,72,2F,3E,7D,47,CE,98,27,D0,BA,00,95,2B,49,95,48,7D,78,B9,8C,A9,96,A3,1B,C8,81,C8,C6,C3,15,A7,E1,DF,D7,9C,57,7E,5C,42,6C,5E,F2,CF,96,20,9D,59,31,29,1F,60,AE,72,D7,C3,5F,3C,66,86,D0,F8,22,98,E9,60,7E,8C,C8,A6,BF,4B,44,7F,DD,0B,B6,04,1C,17,13,2F,B4,BD,F2,2B,38,6A,53,4B,E1,DF,43,57,8B,93,8D,B0,E9,BA,E9,FF,C0,37,2C,9D,7E,CD,E7,A5,41,63,83,09,FF,E1,AF,E3,2E,50,F8,9C,0F,91,39,43,5B,60,A7,F1,CD,8D,71,38,F5,E3,5D,C4,0D,5A,40,6D,56,63,82,25,B1,51,C9,EE,C0,FC,32,AE,E6,D1,6E,62,D5,E0,45,55,46,D5,A4,D2,39,89,BC,F4,A0,17,06,E9,41,5D,96,51,7E,16,BC,D8,45,81,C5,E6,C2,AD,FB,0E,63,B8,0F,61,2A,93,B9,C6,46,56,DD,5B,D6,C2,21,A4,3D,6C,3F,D3,EC,32,16,F1,7F,C8,DA,14,80,7E,A6,89,ED,5B,D9,80,FA,DE,B2,0A,07,E1,D3,DD,E8,68,D1,4F,D7,A6,51,70,AC,A6,E2,E1,B5,39,80,C1,62,E8,73,CC,15,23,A3,D2,F9,18,71,AA,97,3F,11,58,64,70,7B,34,CD,4D,82,E9,BE,81,D7,0E,8C,36,62,2A,01,69,34,A8,EC,F9,80,B7,17,D9,10,F1,4A,D5,9E,21,26,A4,C6,36,D7,CD,AC,9B,54,2D,5B,A9,7A,2A,02,F3,59,17,F0,80,39,02,F0,7B,31,80,F3,77,D6,18,82,04,EA,68,FF,51,68,2E,C1,ED,E9,38,D4,DF,CD,F6,7D,43,76,AA,DC,D5,EC,E1,7D,2B,8F,F5,7B,03,55,6E,31,02,96,49,E4,FB,9A,55,93,F2,96,5C,01,1D,B3,35,A0,00,FF,2F,3E,77,95,73,46,A2,0F,93,81,BD,94,68,C7,6C,63,2F,A2,23,5C,3C,84,CE,68,5E,E3,02,62,2D,40,48,87,B8,7E,C4,19,2A,18,89,9E,FA,22,C4,99,70,AA,41,AA,A6,A4,B8,40,03,2A,AA,4F,47,45,E8,21,D7,63,CF,86,D3,80,3A,17,65,50,15,37,F0,EE,1C,F2,14,41,58,77,38,83,5B,86,7E,98,F6,D3,D9,10,59,57,83,33,EC,70,89,64,49,EC,42,BE,9E,1F,01,26,B1,79,A3,5F,23,14,09,0B,0B,23,64,D9,8B,2F,CC,7C,A9,B0,68,6C,D1,1C,C1,B9,5B,F6,B6,C5,F2,C9,8E,D6,0B,E7,C5,EE,BF,F9,6D,F1,AB,CF,0C,74,6F,CC,56,A3,75,27,B6,CB,93,B6,F8,60,A4,A7,4E,31,01,48,0F,15,F2,6F,EC,B1,28,79,A7,D0,0B,97,0F,D5,53,AD,5B,1E,90,0B,EF,CF,91,08,9A,1D,1C,61,38,18,96,16,64,F6,F4,D6,08,6A,61,27,49,BE,CD,1C,68,0F,27,E1,BE,01,D1,FF,91,AF,E0,2A,6B,57,83,A5,26,B3,7B,51,2E,5E,CE,C5,28,EC,19,83,5A,95,9A,02,6E,5D,03,6D,1B,5C,CA,22,B7,AC,2D,4C,3C,07,90,64,BF,05,BD,4F,84,9A,17,E2,46,7E,CD,F9,D8,C1,5B,47,39,67,FA,1A,7A,50,8A,AE,19,1D,0B,3F,11,C3,F5,A2,F3,9B,D8,82,66,7C,65,68,F0,2C,60,CE,A0,A5,02,9E,EF,F8,06,4D,A2,EE,E6,C4,FF,2E,CB,CA,F0,30,69,65,D9,07,A2,BC,15,AD,EF,64,24,81,D4,D7,04,46,7C,D4,45,D4,6E,18,0F,D7,F9,DB,06,A2,E9,B8,00,35,A6,23,E4,1B,30,4D,7D,60,B5,9E,3E,65,25,95,07,C2,AC,DC,4E,44,F5,95,59,5B,7A,A0,A1,58,D8,1D,0F,38,F7,8D,5B,32,BE,56,FC,2D,C9,9D,D9,64,68,2B,03,B8,5F,D6,66,62,64,08,58,8F,32,72,58,48,FB,A9,5F,D8,09,2D,3B,23,05,4E,43,AB,00,1F,DF,2A,27,BC,FF,8A,11,5F,7D,91,AC,14,E1,EC,D2,8D,1D,3F,EE,88,9C,55,1C,68,42,EE,55,5B,DF,21,86,E6,9B,03,7B,90,75,7B,7C,9A,9E,05,BD,CE,0A,3E,BB,57,22,04,EC,68,FD,3A,14,BC,45,D4,F4,6A,C2,C5,84,87,83,E0,54,33,E3,16,FD,F7,C9,3F,C3,B9,48,08,90,93,3A,F0,40,71,C9,C8,1C,E0,F4,C3,FF,DF,83,5A,69,E2,E5,84,D4,5F,B5,B8,79,09,83,84,6C,84,26,5A,EE,E0,6D,63,72,66,B9,2E,F5,11,0B,CA,6E,D4,31,1B,5A,91,4A,66,CD,A2,69,81,07,3F,E9,3B,ED,44,2B,57,68,82,B1,41,7F,AE,B8,12,90,2D,D8,E3,F3,2B,E0,07,ED,84,EC,B2,90,FC,72,A7,5C,C5,57,35,8C,A2,8C,B4,83,C5,59,CC,F7,47,F4,8D,D1,89,4F,A8,5A,3D,F5,60,65,70,FF,F4,AF,AD,E6,5C,5D,E2,DC,40,C8,69,E9,8B,14,07,8F,26,4B,8A,DB,55,21,34,F1,94,03,59,19,18,36,C6,B2,8B,1B,D9,B4,34,5B,19,0F,02,E6,C6,81,0F,1E,19,8C,7B,53,D0,35,46,AA,7F,10,FD,FB,36,FC,E3,4E,4E,CC,86,0C,40,00,1A,45,B5,36,EB,ED,E3,00,75,8A,F4,91,B4,C5,0D,CF,8D,DA,65,D8,0A,92,97,67,A3,A5,A8,01,A9,B9,0F,BD,98,AD,4D,29,C6,8B,85,E8,AB,CF,17,27,9D,7F,1D,F7,9F,FE,7A,29,27,03,04,70,EF,BF,E2,90,E6,3B,9F,9E,92,81,A7,E5,05,F0,5A,D5,0B,02,E4,02,1A,93,22,E3,BF,C1,1F,4A,7F,98,AA,5B,63,AF,2E,FB,91,26,15,A7,25,83,B5,1C,48,CD,0C,B2,2D,89,3A,69,CC,3B,A5,39,16,A4,A0,2E,D4,0D,64,4A,3C,3C,71,2B,BE,68,9E,EE,56,B4,AA,B6,FF,9B,BC,72,4F,92,E2,F9,60,54,7F,A8,17,AE,9D,0C,41,C8,33,51,C9,22,2F,CC,AF,31,03,E3,6E,05,E0,04,BA,5F,09,55,89,9F,C4,9E,27,1E,5D,7E,25,D9,A9,7E,65,AA,51,B1,A5,D9,2F,F8,79,63,9C,4E,5F,06,CA,4C,36,78,69,21,40,E2,B7,7D,C9,78,8C,4F,82,A5,0E,10,59,66,66,1F,09,6B,38,26,57,77,3D,A9,3F,9E,7E,70,00,52,F6,3C,72,F5,60,58,AB,F1,6A,68,7E,66,F8,D0,15,5C,C2,3C,1B,42,CF,83,AD,15,A3,41,F5,DF,F0,1F,B6,99,1F,C9,01,F9,6C,24,D3,71,B9,B2,CC,89,AD,AF,91,B3,CE,E4,39,4D,3C,1B,48,74,5B,C1,2C,10,9A,22,3A,C1,FC,68,7D,A6,AD,2C,B1,BB,28,2A,AC,4E,C0,A0,BC,EA,BD,F3,B6,05,8A,5F,0D,BA,88,C5,E8,7C,EF,CD,76,6E,4E,EC,FE,8E,8A,7A,0D,D8,E1,CB,B9,E0,85,0E,FD,9E,00,9F,99,35,A0,35,87,F0,21,05,B5,25,29,63,A7,C5,60,FD,24,3C,AA,02,5A,96,F8,E1,B5,80,4F,9D,95,FE,AC,E4,AE,E3,55,B6,B7,4F,05,ED,CA,EE,76,79,DF,DF,89,23,7F,1A,70,F3,93,97,B5,F9,59,05,A7,BD,2C,DA,5E,B4,4E,38,42,26,69,67,F2,76,0B,11,7E,B0,01,81,28,84,79,27,7C,2F,F1,AF,80,1C,23,E9,C7,2E,CD,1D,D1,04,33,4E,11,16,92,B0,A3,64,D7,17,A6,7D,BB,4B,1E,F8,55,E9,BC,AE,96,34,10,B5,55,34,A4,52,9F,EE,26,5E,82,F5,D9,CC,69,0E,A1,5E,C9,C4,E6,5A,B2,96,56,40,53,1F,D9,AE,38,84,A7,9C,5E,F4,EF,5D,15,6A,08,BE,C0,72,B5,04,6C,31,D7,7F,88,6F,AE,3F,B3,44,3D,4A,2E,8E,AB,5D,DF,1C,A6,CD,A6,C1,2F,01,D9,29,9E,7F,2B,C6,E3,84,49,0D,1A,10,0E,24,02,44,33,61,EF,78,50,34,03,82,6F,A3,6F,32,22,85,C6,79,C0,59,11,BC,40,0D,EC,32,9B,35,49,1B,9C,6D,98,D2,C6,15,BD,D8,97,BC,39,D7,3C,56,91,C1,55,80,32,D1,78,49,43,16,B9,4E,57,14,71,08,7B,54,2F,31,ED,46,92,5B,89,A4,C7,0F,14,3A,13,35,DD,10,7E,DF,22,EE,F6,4A,A8,1C,1F,3F,50,67,7A,9F,A6,DE,AA,5D,B3,DD,06,89,EC,EB,6C,2A,D1,10,9B,BF,F8,25,53,CA,FC,A1,1A,F3,1A,B1,F9,7C,68,A1,02,B2,E4,D6,09,7C,D8,D4,A9,CA,34,13,F7,91,AB,52,4E,1A,16,2B,F4,F4,0E,27,35,B9,DC,94,5B,53,66,7A,5D,7D,9B,14,90,1F,C4,9C,0A,2F,4F,79,8A,C8,04,02,6E,03,3F,BC,27,BE,78,7C,34,DA,77,DF,72,1F,6E,23,AA,25,6E,40,81,B6,81,B7,E8,67,3A,33,62,CB,E1,9F,ED,D5,E0,D0,FB,B8,51,BA,3E,56,03,C6,D3,8D,96,A6,EE,EA,57,1E,CE,AA,94,31,59,BE,15,7B,E4,CE,C6,32,E7,03,B0,34,BF,40,08,0A,CE,2F,7B,AA,00,9F,7D,E4,84,E4,85,1B,A5,D7,30,F9,64,6D,FD,CF,CB,40,F3,4D,E1,BD,BE,38,01,2A,10,58,F3,54,C5,35,79,A6,61,7E,66,E0,E2,5B,34,0C,AC,31,FE,53,B1,FE,BE,94,1F,C3,49,FA,D7,FA,39,F0,2A,7C,F4,08,B1,18,18,F1,23,B8,DE,F2,00,23,72,D7,F5,FA,4D,CF,8A,96,16,51,0C,AC,21,64,E2,1E,27,44,B9,9F,82,FE,59,C0,1E,ED,9F,BE,90,A4,5C,47,27,3E,AC,59,B4,12,5E,F2,2F,7B,23,65,5D,50,5F,C4,A0,54,40,E8,4D,0E,37,5C,27,92,A3,E9,CF,72,B8,7E,42,89,6C,68,A5,AF,78,6C,12,C2,12,1E,05,15,6C,49,23,72,A1,8A,FA,B3,F9,BD,52,48,CD,9F,08,B3,44,70,09,F3,39,FC,9D,A5,C8,CD,A3,43,62,8E,70,AB,06,80,C5,09,1C,0C,63,8B,97,D0,06,08,5C,B4,A3,8F,7B,A3,B9,65,DF,94,B9,27,09,32,A6,CD,94,8A,77,54,1E,71,0E,D7,C0,9C,35,57,AD,11,FB,A4,65,C8,48,B0,6E,59,43,BA,D0,82,9E,AA,1C,23,C0,33,30,8B,7D,68,26,53,6F,5F,64,40,EB,0D,95,40,2C,6D,0A,9E,2F,B1,8C,50,16,10,7F,75,72,B2,9B,98,63,40,99,EF,D0,E6,21,34,96,24,60,00,35,57,B4,98,C5,40,A9,C3,8A,D8,01,CA,A8,3E,0D,2D,FC,67,2F,49,16,F0,B5,3A,D0,3C,24,48,12,F8,50,C8,F0,BB,FD,2E,BC,B4,5D,75,C5,4D,42,5A,EC,3D,F1,9E,8C,B3,08,D6,95,BF,D9,29,6A,0B,3C,3C,47,44,9B,A8,87,57,F8,00,63,7B,50,A9,08,45,9C,CF,F0,2E,15,88,21,18,51,B1,5E,04,18,BE,7A,1B,EE,A7,79,A1,87,56,05,52,9C,D1,9E,F3,A6,F2,0D,8C,8E,A7,6D,EF,A2,05,66,F3,20,70,62,EA,80,80,60,21,7F,0D,87,A8,2B,9F,F5,20,B4,18,BB,A8,5F,9C,F8,6B,4F,EC,24,E0,9B,80,2B,CF,B1,E7,7F,57,49,8C,CB,64,B6,FD,3C,F7,6A,83,57,0B,80,70,09,25,D2,A7,EB,24,64,F3,31,F8,9E,FF,1D,7C,0F,D7,34,DD,1F,42,64,D2,0F,1B,7C,31,8B,06,8C,78,0D,7B,C6,98,94,08,21,FD,48,DD,29,AC,4D,0D,A2,9B,24,8E,09,70,09,61,E9,DB,1B,BB,D7,F7,26,9B,E4,82,4A,B8,05,59,A1,DD,B2,39,99,36,24,72,08,48,B8,3E,3A,44,AF,0B,DD,92,83,A9,22,22,BA,EC,ED,32,6D,68,73,F7,2B,3B,72,3C,8F,46,1C,06,F9,FD,DA,C3,29,EA,A1,49,F9,B7,A0,9B,3B,C3,F6,38,B3,BE,A1,54,E4,4E,EB,A9,CB,44,ED,2A,C9,D7,3C,5B,53,9B,52,E3,DA,48,A9,87,E0,D1,89,D6,46,DC,22,8F,48,2D,6E,76,9B,63,08,29,21,3B,BA,34,F1,92,D6,A8,2A,2C,3D,D0,34,BF,78,2C,BC,5C,B9,AC,31,3C,4E,9F,51,1E,88,CD,8B,65,EE,A1,C3,10,F4,A8,2A,7F,32,92,9B,DC,2A,3E,93,90,1D,B1,DF,32,16,18,51,57,20,EA,E3,F9,B8,95,8F,BE,E6,3F,47,C8,74,27,B3,5F,C5,7D,68,E2,45,D2,5B,72,F0,04,34,CC,AA,3E,23,50,3C,8F,9E,11,12,A3,D6,6B,3C,B1,3B,91,F5,7F,CC,5F,D3,50,9D,C2,47,71,67,D2,6E,42,17,A3,FB,99,F8,34,32,F5,48,5B,53,97,A4,51,BB,7A,D5,7D,08,EA,C5,D4,F6,FE,30,8B,83,F5,A9,56,67,5C,07,36,21,30,0A,E1,3C,51,F4,A9,39,4F,D9,71,D7,74,C8,02,14,0F,1A,6D,76,E9,6E,E8,EC,75,3D,EA,2C,25,DD,45,ED,83,2A,7A,E1,E9,DE,8C,14,59,86,B5,73,CF,CE,F0,DA,8E,20,88,B7,6B,E1,D1,4A,2D,A1,24,C1,42,D2,42,C9,C9,C0,5A,CF,9B,5A,98,FF,53,44,64,C2,58,F7,5F,3F,C9,B5,8B,93,58,BB,F9,82,5C,87,07,55,28,B5,29,AA,98,46,E9,A8,A3,77,E0,72,9A,38,FB,85,A6,57,28,B5,2D,B6,09,64,94,D9,D1,1C,BB,94,24,BD,07,96,BA,1E,E9,97,5D,04,2C,EA,E0,18,60,70,F1,23,42,CC,A5,28,0B,F2,A6,1E,67,F0,0B,8F,0E,79,D0,AC,E1,74,A0,96,5B,9B,70,1A,32,B8,B4,DF,19,B1,28,4B,46,FC,CD,52,4D,D8,7B,C8,94,0F,5A,E8,45,8C,21,2B,C8,9E,F5,11,4E,94,61,0C,FE,6E,EE,1D,7F,08,47,95,A9,88,62,7F,B3,52,21,1E,4A,63,29,EE,E4,12,66,6B,D8,9D,54,5A,B4,39,C6,1A,E3,BE,98,98,6A,DD,97,F8,B2,FD,5A,74,29,80,AD,4F,DB,EA,A6,7F,25,61,CE,48,28,D5,1E,5A,37,46,E9,D5,8B,C0,F3,40,1C,D7,D9,BC,E4,37,04,E0,4C,78,F4,E1,05,AF,9C,DE,4A,A2,9E,CA,61,08,4B,4F,D5,7C,77,AF,C8,A3,F4,0F,AC,D2,44,4B,2E,31,9E,F8,E4,82,C9,3E,73,42,F9,77,40,79,CB,60,52,EE,C8,AA,6A,86,E3,3D,C5,A2,4C,CA,52,03,DE,5C,F1,B2,97,02,51,66,65,47,07,46,A6,BC,AB,A9,C0,3D,61,EA,6C,F2,61,21,D4,A3,5D,1B,26,3D,E6,0B,04,27,6D,24,D1,76,B7,B2,24,40,11,E9,D2,4C,3B,0E,BB,7D,05,92,F2,96,B7,FC,82,A8,B5,9F,58,05,C0,B2,8F,76,9F,DD,AD,36,51,47,5B,A4,52,90,39,0A,C9,E8,2A,36,FF,64,CE,D4,5C,72,34,9B,77,F9,2E,1F,4F,8B,D8,1A,5F,20,2E,73,9F,67,23,42,05,F4,11,A2,6D,04,03,5D,73,09,84,F6,8A,0D,40,D3,2B,BA,E4,A1,55,5C,70,1F,F9,0A,4E,F7,39,26,91,A3,43,88,FC,6C,61,E6,92,5E,B7,37,D2,93,00,AB,45,E4,4A,9B,55,82,1B,CB,2D,9D,5E,40,C6,F2,73,81,18,28,C6,63,9F,B9,ED,2B,FE,57,09,CC,BE,94,BA,EB,52,4A,54,04,85,05,2D,CD,86,19,95,13,22,58,D6,AF,DD,80,63,AF,3F,9D,6B,4C,40,4E,CE,BF,83,55,5A,71,9F,3D,AA,C2,35,03,F6,3B,15,C0,04,13,D4,62,B2,50,EC,7A,9E,8E,21,E8,31,DC,C9,F9,A4,D5,D9,82,3B,7F,38,0A,E0,F5,DE,C7,33,5A,15,F1,7C,80,42,E0,61,00,B8,87,38,43,70,AB,33,9F,59,93,F2,2C,86,E3,BB,FE,85,E7,3A,67,34,3D,28,6A,D2,6F,EB,CD,D5,92,4C,BD,E7,E8,5A,A4,39,21,E1,6E,D1,E6,F5,69,E3,4A,CA,C9,41,C6,0E,F1,91,E6,DC,A2,14,DC,FD,75,DE,51,8B,DB,A2,C9,27,EA,B1,60,59,2D,91,AD,44,BD,53,3C,96,4F,AD,F7,DB,42,50,53,1E,BF,BB,0E,C8,97,4F,09,6F,AC,25,BF,0C,D5,83,30,B9,C1,61,93,9E,35,BC,BE,09,28,51,EB,5A,6C,65,91,43,E1,80,B7,8C,4E,F8,FF,2F,5D,70,57,58,5F,8E,E1,29,BC,A2,ED,4E,86,B5,64,CF,81,BA,66,27,26,ED,E1,FB,2B,6A,32,14,4E,4C,29,5A,E6,1F,3F,1D,71,AE,D6,12,F3,81,B2,F4,E2,02,3F,AC,C0,A7,39,68,9A,B8,B7,6A,B7,E6,63,FD,E0,AA,13,FF,76,BD,B1,C7,4B,31,A8,80,C2,51,EA,31,7B,9D,D5,89,D6,7C,8C,A7,1C,76,31,D0,ED,C5,15,06,2C,FD,79,A5,78,FF,01,AD,8E,E7,E9,A6,B2,2A,D1,0D,57,01,2C,28,7E,DC,93,33,70,BF,68,37,F7,FF,C4,C3,55,6C,2A,C5,60,6E,A6,5D,BD,42,F8,25,03,AC,3F,1C,99,42,FC,FA,DC,87,51,CA,35,C4,FF,50,50,2F,77,A1,76,23,81,7F,59,D4,CB,D6,18,43,07,85,50,EA,7C,4B,A0,C7,9B,90,2D,2D,69,9A,C6,05,0A,80,0C,EF,EF,ED,15,EE,1A,8E,39,60,77,D5,0A,C6,26,EE,50,2A,7E,9C,6B,83,EB,64,C0,FA,63,F9,DB,94,0F,76,15,62,97,0E,23,09,4D,36,88,7E,D9,26,20,C0,4E,7D,91,27,0A,40,33,CC,4C,02,7D,A0,71,DB,7A,19,BD,F5,5A,73,64,2B,CE,38,0F,50,CE,3E,40,3D,04,6C,08,1B,EE,EA,EE,87,A0,58,C2,F6,0A,66,8B,1C,20,64,48,60,B3,B7,CA,9A,F1,80,7B,0B,78,C7,F6,67,97,6F,11,C2,CD,53,E4,83,CC,60,35,CB,6C,70,E5,25,8B,E2,74,72,F0,A4,C6,3A,4B,A4,EF,EE,9B,B0,AD,D3,1A,C9,27,65,C4,3B,48,D8,47,71,79,3A,6B,1B,48,E6,34,C6,67,5D,D0,F6,42,06,9E,97,C6,BD,F5,C7,30,67,A7,DE,37,7A,78,44,98,54,CD,A1,1F,46,90,FA,B7,4D,5A,72,EA,E0,9A,A3,18,F4,61,A4,B6,94,67,A9,BB,3B,A9,DA,04,33,40,8B,26,E3,4A,C9,4D,86,74,04,8B,3C,77,91,6B,B6,64,86,D0,C1,3E,A4,F1,8B,2A,5E,17,F6,B6,6D,08,53,4D,85,B8,96,5A,07,9E,DF,4F,E5,BB,D5,10,AB,B3,6D,3D,0F,2E,F0,66,EA,75,11,C5,5F,8E,9E,74,5E,66,43,26,34,E4,77,F7,88,2C,D0,1D,B7,13,EF,3C,6E,83,E1,A4,C3,74,20,1C,4B,46,52,31,27,BD,18,FF,95,F8,2A,A6,C6,0D,F1,D3,3E,D1,6A,C2,75,B7,74,C5,31,2F,90,BE,DF,B8,D6,61,A8,A7,9E,98,43,37,97,F2,69,8A,7E,9B,56,1A,9B,73,1D,08,B4,71,42,5F,C4,89,18,C0,1D,92,23,C6,8D,E3,4D,98,44,4D,3F,22,B4,E4,FF,6A,29,37,38,9D,59,13,61,47,74,E4,BE,1C,E3,B9,CC,39,FA,1C,47,0E,C2,47,F2,9A,31,95,FA,CE,DC,2E,15,27,29,F0,69,EA,F4,BC,71,68,71,FF,6A,C7,5B,58,CB,86,F2,B7,60,30,8B,FA,29,69,6F,47,1E,3A,CC,AB,5A,5D,55,81,66,0C,33,E3,24,09,34,B1,E4,9D,91,A0,21,C1,B6,F3,82,A5,85,EB,70,3E,5E,76,21,97,48,D6,B7,14,76,E6,6D,7C,9B,B8,4E,03,5B,AA,78,51,06,EF,DA,89,F4,BD,3A,4B,58,3C,B2,D7,E0,69,F6,24,8A,BC,96,30,3D,D6,04,11,5B,D7,55,97,C7,97,6E,52,0D,2A,8E,31,27,12,9B,20,E9,46,27,32,32,7C,57,D1,F4,3A,8B,42,48,72,12,01,CD,7A,9B,1A,BD,7A,9C,44,59,B2,58,9D,42,3F,4C,E3,2B,86,21,B2,DB,E0,5A,0F,41,87,DB,78,44,CB,D0,EF,06,73,0B,DC,E3,1F,6B,0C,E1,35,E4,BA,3A,D8,36,3D,F1,93,1E,BF,76,BC,06,F5,55,07,57,E9,C2,8B,55,B5,06,B7,D3,5C,B8,D9,2C,0D,B1,12,0E,A3,EC,82,12,A3,73,E5,AF,20,3A,59,67,4E,0E,90,3A,3F,A9,39,1D,71,E4,8B,AC,6A,E2,94,2D,DC,8F,9C,74,20,24,0C,63,A1,25,59,9D,7C,07,60,C0,A7,DF,74,40,CD,74,96,F8,5B,A4,17,78,D7,7C,1A,17,D5,B0,9D,C8,73,0D,92,43,19,B4,18,18,C8,84,3F,4F,C3,0B,A7,4A,35,C8,58,A3,E2,B0,BF,D2,8F,2D,B6,AE,BB,F8,17,99,F9,40,FB,E0,2D,26,75,96,19,8F,38,4F,9C,86,97,52,86,E4,21,94,2E,B4,CD,CD,AB,65,D6,83,03,17,C1,9C,D7,9A,5D,6A,F1,FA,AD,F3,8E,26,E6,8C,1A,15,91,AA,0B,F1,BA,B1,4E,EE,47,07,19,67,D5,2F,AD,DA,44,C7,4D,42,EB,F3,24,70,45,4A,EF,7A,E0,E2,9F,5F,A2,26,83,E1,4C,53,3C,48,A9,C0,A7,7B,C0,16,0A,B6,D2,F2,49,10,A3,FE,6C,54,1D,E3,89,D7,60,15,2D,0C,03,3F,4D,CD,A6,5E,70,ED,3F,B7,2A,E7,21,C7,01,42,DE,A7,72,BC,F9,2A,1C,78,FE,78,9E,20,80,9F,83,EA,D9,1A,FA,D1,78,99,32,B5,F7,FB,DC,75,83,BC,34,0A,82,85,5C,9E,2E,03,8D,4A,C5,82,86,8E,AA,1A,B9,F0,AB,B7,B5,59,58,07,26,8D,DD,5E,8F,52,1C,8D,D0,63,B0,8D,CA,C8,63,6C,FB,6A,8E,02,D3,54,32,F1,D5,F8,A5,AB,EE,4F,6A,3E,D2,2C,F0,08,2B,DC,F6,AF,8D,C3,A5,60,3C,D5,2E,87,44,18,48,B1,99,7A,26,45,06,1A,88,2B,05,73,CF,EF,B4,35,DF,AF,43,0F,8A,53,9F,FA,11,D6,0D,A8,82,B1,1C,2A,FD,FF,2C,BD,88,A3,C5,31,3D,68,73,C8,ED,F6,82,A0,28,F6,52,B7,5C,82,64,92,9C,89,19,A6,13,5B,F7,E4,1D,E7,DB,3B,3E,45,13,49,0C,FE,43,BE,5D,7D,E4,E0,99,91,18,8E,F8,62,36,DB,F3,BF,36,81,6E,5F,5F,76,D9,80,D9,91,DE,21,32,CC,B3,9B,73,BD,F6,C2,B4,9C,40,F0,EC,25,A3,78,4D,AD,C1,20,42,D3,BA,AD,10,43,B0,3A,F9,6C,4A,6B,13,32,71,AD,C1,40,31,C9,B0,75,04,A0,A6,53,E6,2B,59,D9,D7,7D,42,36,B2,68,6A,DD,C6,95,38,E0,C0,14,19,5C,82,3E,3C,62,CE,D8,77,F7,FF,61,73,E7,62,BB,C9,0E,7E,67,14,85,8B,7F,55,DF,B8,5E,4E,31,CC,21,2D,C0,5A,8A,24,60,E5,E3,E5,05,5D,4C,3F,39,71,40,1B,C7,AC,0E,2E,91,DF,12,EB,BA,30,4D,B2,5B,5A,6E,63,B3,5C,01,2C,F4,5F,D5,1A,4A,8E,8E,9E,D7,C7,1C,B8,46,B4,31,0F,A8,4A,38,E6,6E,5D,DB,5E,3F,CE,83,A4,A4,78,77,71,28,06,37,ED,B0,89,39,7D,6A,19,40,F3,BC,A2,98,60,FA,75,F8,E0,A1,B5,C6,95,8D,67,91,67,15,DB,68,8F,72,E6,0D,BB,8B,A7,6B,CB,D9,71,0B,9C,5C,F9,DC,CA,7B,45,9F,14,35,CE,58,CD,73,47,9F,83,07,EF,DD,EA,24,CE,E6,FA,D6,00,EE,56,51,45,76,B9,D4,71,88,A5,22,4F,BA,02,75,B9,1D,8D,CC,2F,58,F4,42,75,8B,13,6D,3E,BE,7F,19,7F,30,6A,57,D2,E7,EB,04,6F,C1,5A,ED,5F,E8,48,0A,A0,B1,4E,49,5B,51,33,0F,2D,6C,9B,A4,24,6B,E3,C0,38,E1,44,A5,80,69,CD,74,08,EB,E3,73,4A,90,1F,AC,DE,44,BF,B1,03,5F,AD,16,38,4F,13,3A,DA,4C,17,BA,AE,48,D0,40,D6,3F,64,E1,85,67,DC,31,3D,C7,25,BB,B3,EE,52,8C,9F,7B,A5,7A,DA,F2,EC,4B,23,31,D0,1E,22,0B,C5,B1,04,B1,A9,41,0A,86,1E,9B,98,C0,46,2F,ED,5A,0F,03,47,F8,AB,76,70,7B,71,20,6D,C3,7D,78,E4,96,24,C6,AD,68,81,79,A9,6E,76,8A,EC,C1,9B,21,00,22,69,F7,DB,13,8F,51,DA,E8,30,C0,6D,4A,70,78,4A,B6,A6,3A,F5,36,DF,64,AA,B0,79,F7,CE,02,20,E9,CA,C5,12,BA,43,5C,5E,7D,E6,C7,63,CD,18,A8,D4,A2,1D,B0,8E,54,F9,D5,F6,23,CB,8A,77,97,CB,06,18,C6,53,08,0D,CA,65,F2,3B,DD,07,A3,7E,44,E0,90,37,55,8E,48,77,6D,D3,0A,8D,C6,E9,27,44,F0,19,18,BC,29,F3,16,96,29,B0,D0,C5,14,79,AC,22,94,AA,27,81,5F,BB,06,FD,8A,18,23,A4,11,38,11,FC,11,24,6B,42,29,E3,48,2F,F3,BC,20,07,1E,13,A4,24,05,54,8B,3E,92,25,64,77,FC,01,26,1B,85,54,3A,D7,C6,2A,2E,BB,86,49,36,AE,43,DB,D6,50,F8,FA,A7,50,DB,B4,FD,CC,36,C1,1D,94,45,F5,BF,BA,8B,CE,86,B7,F6,CE,7D,3A,EE,88,F1,9A,F0,61,A7,6A,95,DA,A7,11,22,7A,F0,E7,A2,9D,68,4D,50,24,10,EC,11,BD,09,11,2D,CE,CA,CA,86,65,62,D3,31,0C,51,8F,7F,63,FE,4A,64,2C,78,41,1A,F6,11,C0,63,46,52,02,9F,9C,64,93,43,E4,77,BA,81,B2,7C,F5,F2,C9,DB,B5,76,91,63,02,92,A2,11,19,A7,8D,C3,29,44,CC,7B,21,65,BD,F9,46,0F,6A,35,4F,10,26,7E,43,87,9E,BE,7E,1A,CA,8D,E2,2F,CA,55,E6,17,2F,36,10,AE,F4,3E,5D,03,4A,7B,CC,5A,8B,A7,00,D1,3A,49,C0,46,3F,36,5D,87,18,8C,85,6E,F4,FF,D6,BD,7C,85,1A,B7,26,F3,86,39,FF,59,9D,ED,27,F8,3F,63,E7,4C,E2,2F,3C,8B,FF,4F,95,27,5D,D3,AD,63,8B,29,78,2C,39,7F,4A,91,FF,91,82,59,EC,25,21,01,43,00,30,7D,1E,42,31,0E,B3,A6,50,42,FB,71,27,BB,24,41,65,5B,8A,2C,B1,28,E2,DE,5C,3E,EB,1A,33,BD,87,7B,25,45,4A,69,4E,5F,94,85,E2,C5,2F,7F,E2,BA,E7,4E,FE,58,69,68,FE,43,FA,D5,43,A5,38,09,96,31,BA,17,35,6D,94,94,26,6C,94,96,2D,BA,03,3E,C9,C8,83,00,30,6C,AC,2A,66,77,DD,10,B9,8C,39,F1,40,82,34,D1,88,3B,6D,E1,77,E0,6F,75,BB,29,B3,99,08,D0,E1,C3,95,51,BB,46,9E,FE,EC,68,F5,53,4A,3A,CA,BE,B1,9E,3B,A4,BE,7E,39,A6,F2,49,56,BB,A8,D6,35,0C,DC,AF,E7,0F,44,5B,08,3D,DF,02,C6,C8,38,AE,1E,03,8E,C1,B7,57,BA,9C,95,0A,DB,86,3F,99,C0,3E,BF,DC,92,6E,11,21,01,C7,9D,2F,5D,AB,96,09,4E,E6,26,F4,2E,B7,BD,FD,A2,60,F0,60,21,D7,A6,97,59,96,59,6B,FD,AB,E4,1F,87,F3,C7,3F,1C,18,30,41,DF,E9,E5,22,BB,97,EC,C9,7E,6D,F1,CF,46,23,D1,73,B6,12,9D,37,E4,F5,0D,F2,59,A5,3F,90,A9,B1,D6,8A,2B,24,B3,6A,BA,51,D5,B6,79,E7,F8,B7,E7,17,A0,A0,33,F0,66,A0,F1,7D,20,88,3C,EE,78,E8,62,CB,F7,64,57,3A,87,B6,86,92,3D,62,76,D9,E2,B1,2A,F1,F3,33,4B,E3,D7,F9,1F,42,35,0B,C0,3E,A7,AE,FB,B7,EA,79,43,36,2A,CB,E7,D4,DB,09,9F,0A,8A,3A,E4,F2,98,78,D6,60,11,B3,C0,86,F3,4F,BF,42,68,4B,7D,5F,B7,1E,21,1F,8B,DB,A2,83,11,FE,7F,6F,9E,DE,C3,31,81,20,95,BD,B4,B2,E4,C9,72,3F,20,54,4C,81,1D,38,C7,8F,29,D3,95,72,93,B8,A3,52,6D,68,AD,F4,34,C1,6A,8A,C3,6D,B0,14,BF,8E,F4,0D,E6,BE,B4,24,92,B1,D9,15,5D,80,63,07,01,CD,12,8A,7E,08,CD,CD,0B,A2,15,E7,D7,07,C8,D0,91,A1,72,3B,CB,D4,45,7A,3B,55,38,8A,7F,F6,3E,52,50,7A,D9,03,F0,AB,C5,86,0E,24,6C,0F,E8,E5,43,55,99,6B,CF,35,3E,D7,6D,FB,65,92,7A,13,12,05,9D,62,39,BB,4D,A6,92,42,EF,20,10,25,26,A4,61,E5,12,F3,93,47,FF,02,E1,94,8A,CD,EB,6C,4A,68,1B,D8,1F,B2,C8,2F,44,CD,57,F1,CE,15,FD,5E,42,1B,9C,7B,BE,12,59,90,70,29,FE,13,3C,8D,AA,D2,63,94,6E,3C,04,45,57,61,EE,0E,D3,B3,FC,70,22,DA,29,65,4E,0B,AC,A5,C1,F4,79,46,D7,89,7B,D1,60,E0,80,2F,7A,A2,98,93,4E,F7,71,B9,EC,AF,7F,03,14,67,87,E0,F4,F9,67,23,C9,1D,0F,29,19,40,7B,94,88,21,79,B4,0B,57,93,A9,D8,E6,8F,47,E2,78,7D,0B,FF,D3,CE,07,1D,B7,16,F8,0D,9A,1D,71,2D,EC,5F,AC,FE,AE,60,16,55,45,C5,F6,06,1D,07,5C,CE,06,06,77,15,D3,79,10,7C,F6,63,B6,A3,ED,63,81,B3,2A,75,69,35,37,7C,B8,0F,E4,E1,79,C9,34,4E,12,23,88,60,18,DE,F5,E0,4C,27,9B,7B,83,87,DE,28,72,BD,FB,F1,84,57,E5,AD,53,61,DD,32,C4,40,DB,8E,FD,D6,29,08,6B,0F,DB,F8,3F,F7,F4,68,28,69,B8,FA,82,DC,7E,7B,A6,BF,A9,60,1D,8F,16,3A,C5,CB,E4,A4,46,49,30,C0,3A,40,67,D9,48,09,B0,AF,BA,61,11,88,43,19,0E,5B,61,5E,48,3D,F5,50,DD,3E,91,D1,BA,A3,2B,3E,DD,7C,76,05,55,22,77,22,F6,3B,B5,BF,72,99,A1,96,6E,ED,C1,EC,7A,9B,4C,ED,B0,AB,63,DE,71,36,18,2D,EC,35,A4,69,69,59,BE,16,14,48,E6,97,0C,48,A6,F8,39,C3,AC,40,B7,D6,8E,A2,51,74,08,0A,4C,83,8A,17,A1,73,81,42,BD,8C,12,2B,20,6E,81,3E,39,CA,52,0C,E5,CA,F1,D2,9F,ED,B4,0B,29,40,98,6E,41,D4,E1,31,BC,FF,FA,BA,1C,0D,C4,EC,59,6C,1F,70,7A,BC,45,2C,CF,D7,11,F0,41,64,C8,C5,8A,98,00,52,75,67,2C,9A,A6,35,43,C2,DF,BB,0E,01,DA,57,51,B6,C8,76,2D,E9,23,EE,2E,45,5C,40,C2,1F,30,BC,F8,E6,1F,9D,82,05,11,89,87,C8,15,5E,93,DF,DC,26,69,8E,1C,47,C4,F4,53,C2,5A,62,F6,FA,00,73,81,EE,8B,83,9A,D6,BE,84,B2,79,96,2B,11,A0,2D,68,B0,65,4F,02,DF,6B,9A,C1,46,3D,32,C0,58,ED,62,B9,86,FC,79,65,BB,AE,A8,BF,D6,A6,B0,1D,7F,6F,4A,51,8B,F4,B1,81,C2,5D,B7,05,FB,AF,D7,E0,A6,AC,05,19,A5,47,F6,A7,B0,75,37,82,81,83,3F,08,A4,BB,7C,27,89,C6,EC,78,BF,10,4B,D2,B5,87,9F,69,51,83,30,30,AB,B9,FD,24,A6,3D,31,C7,27,9D,47,76,A0,DC,F9,95,3C,A3,6D,08,79,E8,77,6F,40,24,99,28,42,91,A9,02,6D,EC,F3,E3,B9,C1,0F,C8,7B,79,71,31,FB,49,ED,52,18,7D,3F,83,47,C3,DF,E6,A4,AE,61,B1,5A,68,F4,C7,F7,68,24,FC,6C,6F,54,34,D2,48,08,2A,53,C4,B8,6B,D7,2E,78,FA,5A,B8,B5,01,7D,04,AE,11,10,C0,3A,40,8B,7C,83,F8,AC,60,41,AE,F1,BB,7B,B2,16,79,69,6F,7B,6E,5D,D1,3E,62,E1,D1,D8,1A,0A,E4,50,B5,11,DF,A6,77,AF,6B,CB,AA,CB,7E,A7,F4,AC,AE,CE,FC,EB,4E,BE,A7,88,5E,CE,1F,E6,3C,44,A7,15,33,81,1F,B0,18,C9,49,84,A5,4C,2D,E2,BF,39,EA,86,E0,D0,4C,3F,DF,90,CD,B0,07,48,5C,91,E9,83,E2,FE,BF,4E,29,D6,C0,F8,AF,75,91,49,45,B0,5D,F1,17,12,03,DD,BD,E0,46,29,39,D1,89,E0,1A,6C,9B,C6,84,F3,68,22,00,11,6A,2C,45,88,EA,FD,60,0F,9A,93,8B,C9,7A,6E,79,FD,01,C8,E6,47,B1,B0,8C,22,B0,07,E3,F9,D3,17,C7,E2,D6,AA,6A,B5,47,C5,64,84,49,F4,56,8B,BC,CF,23,82,E1,AF,17,A8,A1,FA,27,A0,BC,96,05,D1,A8,A5,13,0F,07,53,76,D3,F5,E7,70,9F,46,D5,8C,34,6E,11,37,6D,F7,60,63,74,C5,FD,87,EB,93,CC,A8,1A,64,AC,33,89,09,7D,0E,94,B6,C9,C4,7F,2A,8E,55,68,D5,15,BB,B7,FC,B9,D5,AE,8F,DA,DD,96,8D,D5,2F,E7,9C,4C,41,0F,FB,2A,06,76,CD,4C,3A,B6,F8,92,0F,66,8C,3A,E7,DE,62,BC,D1,19,2B,6E,66,22,53,EF,12,81,23,52,4E,E9,93,8D,20,28,50,E1,02,14,CB,13,80,72,F4,17,66,6A,F7,77,E4,05,8A,15,FF,93 -keyMatrices_inv = 31,1E,6F,5D,2A,A0,57,EA,41,0C,0A,45,F9,83,52,C8,50,6D,3C,BC,22,65,B2,C8,0C,D3,59,1F,A9,36,7B,50,C7,00,CA,13,B8,59,CD,82,DF,D4,65,BA,28,FC,03,6C,A0,DB,AA,A8,22,06,7C,65,1D,75,45,B6,5E,F4,C4,10,FF,B5,C8,15,0D,43,B9,F4,1C,4B,EB,0A,C3,41,FD,F7,03,60,F0,D9,5F,DC,AC,81,5D,0D,0C,1E,AB,50,B5,BA,FE,62,16,69,ED,EA,E3,66,F2,9F,75,D4,1B,8E,19,E2,3E,FE,63,47,20,64,6A,B5,3C,8F,1C,26,4E,75,FB,AA,D8,BA,47,19,66,85,A1,87,88,57,8E,C8,F2,68,79,54,C1,76,C7,3E,35,47,0C,8C,4A,57,1A,92,FE,25,89,F8,D6,36,27,7A,16,56,6A,91,89,D4,D4,25,BB,56,0E,61,F1,D4,C6,3D,BC,D9,75,1F,3C,F7,BE,6C,07,F8,73,12,A2,63,35,A1,F0,91,B2,9C,F9,EC,14,0A,6B,50,9C,F7,5B,EF,01,3C,3B,4C,B4,EC,93,D0,E6,B1,7A,55,4B,DE,66,90,89,C6,EC,7B,CF,04,E2,0A,0E,D8,E7,09,54,16,ED,AC,89,10,CE,10,6B,4D,22,89,11,5C,F0,E9,91,4D,18,D8,3C,F9,1A,00,14,3D,68,78,DE,C4,01,21,9F,A3,F1,19,15,93,C5,11,23,18,DA,4E,1F,47,79,69,AF,0D,CB,34,6C,38,0D,BD,99,25,76,5B,B0,C9,8C,2B,7E,2B,10,2D,63,42,5D,40,9C,03,D5,98,6E,4E,DD,A6,98,43,E1,61,C2,F2,33,68,5D,2B,DD,9F,BD,79,7C,0C,1D,5E,3A,E7,57,86,D1,D9,4E,88,F3,DC,FF,0B,02,39,19,F5,D8,75,1E,9C,32,C9,3C,9B,1D,1F,47,87,5E,BF,DC,3B,E1,7E,E4,B5,F1,59,71,A9,35,D9,54,CA,46,B5,AC,DD,50,4B,59,F1,84,0A,7E,41,DD,0A,E7,13,2D,8B,49,55,7E,05,6A,E3,AA,4D,E2,45,AD,F0,C8,9D,01,3B,77,30,13,94,BC,90,11,D2,52,76,C8,9F,6B,4D,1C,9B,AA,AC,56,A7,E1,E0,1F,26,63,70,C7,4C,05,77,A1,1B,1A,AF,68,FD,0F,02,7B,70,D4,FA,1D,2D,86,34,2E,4E,17,51,11,BF,37,BC,74,19,A9,77,CD,FB,0C,34,6A,86,6F,E3,04,E0,51,01,B5,45,63,C3,EC,D3,03,48,5E,9A,BA,EA,1B,F7,9C,41,8A,AE,1C,C5,EC,D2,8B,D5,99,6F,35,7F,48,42,77,AE,14,D9,AE,DF,FB,5C,0B,7D,26,C9,4F,D9,3A,1C,0E,AD,73,7D,0B,C4,E0,7D,6E,D0,52,85,B2,D2,60,3D,33,AC,42,7E,47,95,03,E3,C8,DD,59,AC,A2,9D,37,FA,09,A7,89,08,5E,7C,85,67,05,A8,A3,B7,11,C6,66,39,2F,87,9F,C7,EE,66,D4,5F,F8,33,A8,53,C4,5C,95,13,AF,E0,F0,7D,89,40,81,91,BC,EC,5C,C8,59,6C,29,E1,6E,23,59,1F,EA,78,6B,DE,E3,17,35,1C,10,77,98,5A,C4,6C,9C,21,1C,6C,C4,65,98,E5,86,EF,C5,F5,63,EE,FE,29,0C,33,64,14,41,5C,26,41,F1,76,AD,49,D4,D6,11,38,5E,51,75,EC,AE,00,79,38,C0,9B,8A,6E,53,EA,68,38,32,55,C2,C5,05,D2,EC,55,B1,56,E2,39,48,B0,3C,6C,70,D3,5C,86,DD,B7,A7,FD,03,A3,22,83,AD,10,AE,3E,15,18,30,0E,ED,2A,89,D9,FA,F0,C3,B3,13,5D,5C,FE,3B,9E,57,3F,F3,8B,01,71,B4,5D,42,C3,41,A2,1C,0C,AC,2C,83,D3,58,A8,A8,29,DA,3C,E9,4C,E2,BB,F4,E7,CB,69,DE,1F,2C,78,AA,9E,B0,06,F9,14,BB,70,4B,4E,8C,6E,6D,C0,1D,41,7D,F0,25,0F,ED,09,E2,42,44,8D,66,FE,94,AC,D6,FF,43,95,66,60,B8,0C,E8,E1,EF,37,1B,35,65,C5,AF,1D,59,58,C1,A5,50,14,8C,01,A3,9B,E1,33,65,11,60,37,FF,8F,AB,3E,57,FB,70,C4,FA,B7,36,57,87,C9,C5,B7,7E,D4,A5,95,7B,EE,59,E4,F3,34,AF,EF,C5,EC,47,0E,FE,AD,FD,18,73,A7,04,2A,C0,21,A0,43,7F,6B,7D,7D,9C,1A,E4,88,2B,E2,9E,BF,8B,41,66,E8,02,08,02,1C,6A,92,D6,1C,6D,FC,22,29,B6,4C,7C,AB,06,FD,C1,6A,EC,B6,8E,0B,D4,6D,14,AC,D1,80,AF,A5,B6,3C,30,F9,C3,8B,D1,65,EC,8A,4B,8A,9A,43,C2,67,10,F7,00,E1,63,26,D8,D2,B7,FB,80,58,36,53,F8,6A,A4,5D,6C,DE,7D,8B,CB,25,61,B2,2E,59,4E,04,B4,3D,5A,E2,52,5C,EE,76,30,EF,59,03,DD,43,F7,F9,B1,1A,B5,16,40,A5,F4,19,9C,26,D3,7D,95,0B,06,FF,7C,48,68,44,6B,17,D6,05,EC,AE,E5,DD,BB,09,DC,F6,87,BC,A1,B1,2A,71,CB,57,3B,13,49,80,82,EC,ED,56,10,9F,E2,C5,1E,5F,E7,BD,8C,E2,EF,3D,CB,AB,5C,22,10,72,2E,09,B4,F7,2A,00,74,1E,8E,CF,5F,50,25,C8,6D,70,BE,80,D3,CC,73,D0,67,F4,25,3B,87,1A,0F,43,01,96,C1,F0,33,4D,94,34,83,DF,1D,13,BF,01,05,B9,EC,82,C6,A2,AF,F0,1C,EC,D7,8E,6A,6A,C0,68,58,29,6C,BE,8B,A1,69,DA,87,C4,19,A9,FC,0A,12,01,61,1B,DC,44,0C,33,12,CB,73,EC,5A,60,F8,F9,6B,9D,79,94,2D,35,C3,CE,9A,2F,52,05,38,3F,EB,8B,6F,95,AC,99,75,2F,F3,D2,22,AC,72,31,2A,A9,F5,68,51,F1,9D,51,9D,61,04,23,8E,EC,D9,7A,65,8E,07,D4,43,B9,22,8C,9C,4B,0F,25,2C,B3,BA,88,FB,97,EC,F2,2F,FF,71,C3,49,B6,4C,28,62,FD,89,C8,C4,6D,D9,D5,68,EB,74,18,F2,D1,A6,65,1B,51,ED,FF,3F,6A,79,CA,4B,67,E6,54,FC,C8,6B,F7,53,AC,F4,81,4A,2B,A9,B6,88,54,5E,FC,EF,07,82,A8,04,37,D9,9C,06,83,2A,83,04,3D,16,4B,C5,AB,A2,2F,48,A2,6C,60,04,16,BD,6A,AC,0F,4C,24,86,3F,70,7D,93,CB,4F,36,AC,E6,F9,1F,4F,0A,18,45,9E,45,A5,5A,20,0A,AA,24,63,57,7A,BF,7A,7E,01,C3,DB,6C,36,3B,22,9B,68,4B,87,FC,66,78,D5,57,C9,4D,8D,BA,3A,36,E8,95,AE,5E,F8,FE,F3,D6,0D,87,87,6F,1B,F1,12,7B,32,6C,FD,F0,6E,73,4F,C2,92,94,20,A6,11,57,35,DB,E0,A9,72,A5,D7,FE,80,00,AE,A1,45,2D,84,E5,A9,3B,04,7E,F6,BC,2E,CB,10,DE,85,F4,0E,B9,19,60,CC,C3,02,5E,27,F2,B0,5B,ED,A9,E6,BD,0E,0A,EF,A0,51,54,EB,2A,B1,B9,A7,12,35,EF,12,E3,13,FF,E0,AA,CC,47,71,C8,BD,53,EE,29,35,D7,78,D5,BF,B4,90,E7,7F,C7,F4,ED,68,FC,2C,B1,86,E4,23,8E,EA,A8,5E,93,8A,07,28,86,1C,B8,60,46,9F,9A,D2,AF,2A,97,91,14,57,D9,51,66,B2,7C,D9,CD,6E,63,19,CB,64,91,17,C2,03,0E,10,8E,6A,0B,98,DA,5D,83,14,B3,7D,9C,CD,85,8F,B0,62,2E,7E,8B,14,CD,2D,85,59,9F,2A,67,4C,77,86,52,2C,E3,E4,33,4E,2C,7F,23,07,C1,88,45,F6,4C,C4,B1,6D,85,46,72,FB,FA,49,00,7F,35,21,E4,50,8D,24,3F,00,E2,FF,CC,47,03,67,56,9C,4F,39,AA,62,31,C0,31,85,44,60,ED,AD,12,00,03,D9,7D,49,9E,21,A8,70,34,D5,F7,2A,72,20,02,7E,7F,A0,74,81,19,58,21,8F,27,29,7C,E8,0D,9A,80,9F,EB,4E,D8,31,50,F5,7D,32,90,C3,2E,88,66,4C,DF,53,9F,E5,14,A9,0B,62,26,12,5B,49,C2,AD,52,FD,C9,06,E6,AF,87,09,9B,7D,8E,B7,5D,C1,34,29,86,7F,6C,0A,23,26,0B,00,FB,97,D1,0D,87,52,34,B3,4E,C5,CA,4E,ED,61,69,E1,8D,D2,81,9D,71,43,69,CA,3D,30,71,5C,A0,B2,D5,56,25,59,5B,C5,BE,3B,AC,D9,3D,BD,85,AD,D2,D0,AF,D6,9D,35,23,7C,44,7F,11,CB,94,1A,6A,3F,CA,E2,AA,E3,4B,DA,57,F9,49,C8,1F,A6,04,07,9F,43,CA,9F,31,0E,B7,70,42,56,4C,45,ED,62,B5,73,E6,A4,1D,7D,4A,F6,92,2B,D6,3A,81,88,EF,10,53,27,A2,3F,A7,4A,9F,B9,04,FA,D2,AE,E7,FA,C6,49,3B,4F,9B,28,6D,52,28,B8,27,7E,21,78,98,74,71,4E,43,37,49,4B,A3,17,F8,A0,0D,AE,57,21,1C,1C,44,E1,15,6B,B9,B7,71,77,C5,68,72,ED,40,59,10,D5,A5,87,2C,4A,BB,B0,B5,23,61,D2,DA,83,AA,66,6D,2A,67,28,85,EE,19,45,BD,37,97,6F,C9,44,A1,3C,F7,33,B2,E8,39,7F,F1,47,C0,CA,26,49,50,A0,4C,E9,8B,FA,37,BD,18,A7,54,38,E2,78,E3,84,8C,57,61,AE,BE,6D,FA,F2,AE,03,95,E9,CF,E5,35,1E,06,2F,17,1F,04,07,32,14,44,DD,32,0C,AF,3B,D2,6B,7D,31,C4,48,0E,92,A5,0C,01,5B,E5,7A,8E,51,A9,F5,CC,DD,4B,CC,F0,7B,31,0E,66,86,8A,99,A8,C3,E6,B3,DF,AF,0D,AE,D6,05,AD,68,F7,9F,D2,5D,5E,EE,6A,3E,30,E2,ED,9C,C6,38,60,08,0D,CA,FE,63,D2,22,CA,69,26,04,40,C8,0F,A4,1F,DA,B0,3A,3F,33,4B,C2,DB,37,99,DC,CD,E9,38,16,93,E7,86,20,98,EF,C7,E9,04,61,51,79,EE,7B,2D,8B,39,B9,7C,BA,66,48,15,6C,59,8E,1F,83,E1,E7,4F,80,BB,AF,8C,E9,A4,88,1C,C1,A7,BE,11,7B,C7,6D,84,F4,3C,02,E7,56,51,AE,3E,8F,F3,49,69,8B,D3,0C,43,81,97,50,D2,5C,87,0C,F7,91,0A,78,BC,41,76,1D,C9,E5,78,9F,7B,67,D3,43,4D,CA,F1,52,65,80,8D,36,C6,5A,CB,CA,B3,6C,F6,4E,E8,72,55,88,E0,E1,0F,6C,84,79,D9,8D,8E,7B,AF,B9,24,45,D5,83,28,6D,2E,25,32,F7,1F,95,5E,15,D1,A7,19,46,E5,6E,68,41,A6,34,08,D3,02,2D,B8,9C,BE,57,51,40,2C,62,D7,3F,8F,2E,BF,B1,47,39,C2,1C,7D,41,4E,18,59,FD,BB,87,0D,12,90,D6,A6,27,78,31,B9,7C,8D,59,FB,88,7F,5D,D5,D0,BF,FB,F9,66,C1,5A,5A,1D,EC,AB,64,25,4D,34,D4,3B,4C,AF,3C,43,F2,FB,92,88,85,5E,EF,C3,76,71,8A,BD,BB,2A,34,C0,77,10,12,64,8C,23,B3,07,A4,9E,70,36,E6,E7,3D,C9,5B,34,68,22,30,CC,60,A4,C1,D2,75,6D,A8,56,11,F1,41,68,F1,CA,3B,1C,31,BA,6D,2B,CF,8F,34,94,F8,03,BB,14,A4,10,E6,27,4D,52,14,94,16,0E,9D,B3,D5,1F,56,53,71,C7,E9,84,75,EF,AA,68,77,2A,1B,F8,D2,26,11,30,F1,DB,A0,56,7A,04,0D,0A,B7,9B,5E,81,5E,68,74,5C,87,D5,2D,FE,FF,ED,13,0E,4D,DB,B1,D8,51,C5,6C,38,AA,A3,36,4C,BD,F7,3E,31,06,A9,52,A3,D6,B2,F4,A9,A0,9A,1F,61,B1,3F,53,76,A6,15,00,25,8A,12,FD,04,C2,A7,56,A8,15,E7,6B,BF,2A,D2,EF,62,EE,E1,B0,52,D8,96,05,BC,4F,43,91,12,AA,F6,6F,D4,4D,8F,BE,35,B2,9E,CC,E2,15,DA,ED,73,BC,33,D6,B0,65,B0,D6,39,B3,88,86,B6,81,A0,E3,4C,83,6F,DC,A1,34,CA,67,49,99,4E,46,41,38,A1,FF,D5,23,CD,72,21,EB,AF,3E,BD,A9,47,54,F4,B4,E5,60,BC,8F,CB,23,29,A7,9F,5B,D6,DA,41,B8,08,7D,7D,36,3A,9E,E7,66,91,16,59,44,B6,4C,90,C0,46,89,18,4D,69,ED,73,71,B8,4A,CB,95,7C,34,EA,D0,4F,1B,83,CE,73,73,6E,21,9C,B2,1C,DF,1F,A4,4B,16,DF,33,BD,3E,D5,D2,E0,5E,1E,5E,85,00,04,B0,85,9D,44,6A,24,D0,F2,4E,5C,1D,D3,0D,A5,31,FE,25,C4,5F,CC,A9,86,CB,E9,D8,FA,77,68,9E,FA,C9,9B,63,48,0E,CF,F2,20,7E,13,AA,C2,13,71,34,C0,FD,A3,B5,E7,68,16,9D,67,80,AA,9C,D6,FE,9F,C5,09,A9,A5,FB,DE,90,0A,86,E5,34,7A,25,32,F7,74,85,64,E6,62,9E,8C,F4,F9,E2,1E,02,17,F3,EF,49,58,71,A9,A4,92,8A,31,94,B1,F1,D2,8D,71,4A,CE,89,AB,4E,61,CA,42,E5,61,F5,32,8F,AA,2C,7A,B5,83,8B,86,3B,41,E9,5C,04,02,8B,5F,4E,09,54,BA,0E,13,C2,5B,1B,27,32,41,67,60,C1,43,5B,47,08,70,0D,72,BC,52,02,BB,92,24,B6,2B,60,AE,2F,99,F5,C9,A7,99,C4,5F,C0,78,01,C2,80,C5,ED,C2,9C,26,4B,B6,45,97,FA,FE,6E,1A,4D,34,55,E4,9C,6B,0D,50,C7,EC,2E,0F,60,17,04,5C,92,13,64,4B,4E,5F,32,E0,10,32,41,3C,9D,36,85,F5,3A,0E,27,A2,AF,82,1A,03,AC,B0,E1,E2,FF,7F,EB,17,54,C3,D0,68,36,D1,2F,35,3D,D4,85,CC,7A,B6,78,17,70,99,2D,61,27,8C,97,D6,CA,8E,75,6C,82,72,9D,A2,74,4A,1F,1A,99,F2,04,B2,0F,1D,24,BB,F3,FD,73,C2,72,0A,56,7B,B7,C8,1A,98,17,76,69,D6,03,FD,DA,90,71,33,45,50,1A,85,3C,BD,BD,B1,0C,18,1D,68,9A,0C,9E,C1,EF,F9,E2,31,DF,FA,61,0E,71,A3,CC,6E,9B,B4,F8,A5,9E,D3,A8,B2,48,9A,7E,04,4F,E6,1A,AC,E2,6D,93,9F,37,38,C4,B3,1F,AB,B1,8E,B5,67,2B,13,94,DE,04,40,3F,96,AF,0B,99,D8,E6,6F,B1,2B,74,F2,7A,E9,EF,8C,B7,5C,67,28,3C,66,0E,8B,49,06,78,3E,33,18,19,08,A7,C7,31,FD,56,81,35,06,33,FE,68,BD,2C,65,A3,A2,96,AD,F2,5E,E5,69,6E,95,80,DE,F4,9D,CF,24,B9,4E,1D,F5,32,8B,CC,C1,70,1A,73,6C,E0,AE,34,DD,A7,90,86,B1,22,8C,64,26,F0,29,8F,A7,9E,7A,0B,65,03,B8,01,73,DC,89,6E,31,E4,7E,5A,71,66,F2,42,DD,EE,36,E5,75,49,4C,3A,36,F0,9E,C5,C2,B4,E5,75,FB,26,02,45,D7,D8,64,33,F8,6C,50,2A,71,0A,20,43,73,0F,FC,9E,0E,34,86,74,4F,54,F7,1F,D2,3A,30,AE,7A,2F,B9,86,7F,CA,78,A5,D9,8F,2A,F6,55,E6,1A,30,73,BA,0A,E6,AF,8B,3C,78,35,FD,6C,5F,3D,3D,4E,8B,DB,C2,E3,8B,47,D2,23,2D,4E,99,C4,66,6A,73,BB,8E,66,EF,4E,3D,A9,6F,09,6E,4C,A3,19,95,F8,3F,69,28,17,F2,E5,CF,BB,7F,8C,44,A4,E7,8D,BB,F7,BA,A1,54,F3,64,38,45,95,34,0F,28,31,36,A6,E9,06,EB,F2,37,FB,CB,02,D0,EE,BE,F6,0D,0A,DB,9F,F8,D6,E2,DD,05,2B,21,18,51,1D,C7,3B,DC,B1,71,8D,D7,45,D8,17,ED,4D,38,11,B6,10,64,6C,DF,E6,F5,91,F3,55,A1,29,AC,91,5C,9D,C9,3B,E8,BF,44,7C,EF,E0,B3,C9,5E,98,B8,A8,35,F3,6C,35,50,FF,3F,B1,06,6F,2A,B6,94,3A,59,A9,5E,36,CA,AA,B8,DC,5B,2D,E2,6E,37,5A,6A,6A,39,63,61,14,18,FA,C7,2F,9E,53,7F,51,7E,FB,BF,19,BA,BD,66,9F,83,AB,F7,FF,48,26,6D,7B,00,C4,3F,0C,6D,BD,A4,A8,57,E1,D4,95,CE,B0,5D,E7,70,0C,D0,E7,C7,61,14,1D,31,CA,70,C0,BE,1F,52,8F,8D,21,01,EE,34,8B,DD,22,49,58,9C,D9,D2,72,30,BC,4A,47,04,1E,17,71,28,68,15,07,18,BD,9D,C2,8F,E2,E8,E9,53,67,DD,7F,95,F5,83,E3,23,B4,B9,97,44,53,CB,15,3D,48,C7,F8,39,ED,B5,D8,33,64,93,AF,83,EC,20,DC,5F,4C,B0,59,D2,E1,51,2B,46,E6,2F,67,45,E5,2A,36,8D,41,2C,16,49,5A,83,68,14,E4,67,99,39,66,83,66,1F,F8,25,8A,14,E1,F2,52,F7,F0,92,87,3F,97,89,85,DD,93,5C,57,4C,E9,A3,DC,C9,09,79,FD,D1,9D,16,9A,4B,64,F2,F1,22,D6,1B,2A,79,AE,81,2A,C2,75,AB,36,95,00,94,B5,38,8E,E1,8E,5D,93,E3,F4,17,8D,7C,3E,08,56,66,CF,07,CE,80,E1,3E,C8,FF,1B,6A,B2,92,0F,A0,90,D2,BC,BD,30,CF,FD,3E,BA,19,58,94,36,BB,40,EB,80,CB,17,D2,3D,B5,DB,36,51,1C,D2,2B,05,54,E3,1A,A7,DA,74,62,01,13,94,93,72,1D,7F,FD,DA,96,AC,55,0A,2D,58,DC,C6,42,0B,93,64,84,68,97,CB,3A,D8,94,E4,99,26,F0,7A,8F,04,47,7B,02,43,85,20,39,44,81,B6,87,12,EE,5E,F4,2C,39,D6,C9,13,ED,58,88,F6,5C,DB,98,F0,AF,93,1F,B2,80,6E,11,FC,02,84,56,84,C4,64,64,0E,1A,99,09,14,16,32,18,16,8A,BB,29,A1,44,B0,83,E8,41,E7,49,51,76,46,77,F4,5C,B5,DE,37,6C,BF,5B,29,4A,EF,3A,AD,A4,6B,D4,73,71,0A,78,2C,C7,3D,44,DE,05,07,86,38,B4,75,1F,DB,2F,A8,DD,3A,36,BC,01,96,38,A5,DA,82,D3,DD,DC,26,DB,8A,6C,E3,30,D0,88,F7,B6,30,98,3E,12,A5,AD,5A,B3,B7,7E,45,B0,7B,BD,FC,B6,5D,9A,95,9F,F9,DA,66,A8,87,F9,E9,3E,AE,E1,AF,F2,DC,E3,BD,49,D5,02,29,B6,30,72,99,00,AC,3A,EA,82,D6,B0,4A,B8,D1,56,A7,6F,4F,02,DE,86,89,2C,D2,E2,C0,D2,B0,5E,7E,7F,03,2F,DE,42,85,94,1A,66,C3,C4,35,E3,A3,14,AA,92,A4,10,AC,09,44,9C,7E,16,BB,3D,78,2C,46,BA,F5,FF,20,C7,90,56,EA,04,1F,08,54,82,C5,73,4A,AD,24,42,86,7A,1B,55,3D,C6,92,AB,1D,E2,5E,68,E1,2C,36,89,5A,AC,B9,6F,47,9F,A7,09,A6,44,CF,F3,36,24,23,6B,07,F3,FD,05,72,3C,6B,02,DA,52,0B,38,01,1E,AB,5A,64,66,EE,1F,4F,0E,8C,98,AB,D2,D7,00,EA,2C,7C,3D,77,FF,B7,BD,B3,BF,FB,5E,BE,F4,1F,E0,4E,27,9A,C8,5D,1E,6D,21,DB,B1,6D,D8,A1,C0,E8,34,93,A3,F4,FF,E6,EB,09,DE,AF,73,F2,91,F4,91,B8,38,F8,E0,60,8B,07,23,84,69,95,98,C7,F9,4E,F6,70,9B,C2,85,8D,B3,1E,15,00,F0,96,E8,8A,7E,59,6E,95,1B,26,B3,6D,7C,EA,72,08,54,5D,54,85,CA,FC,1A,32,7E,6C,79,D5,FD,52,15,E5,12,E1,1C,0A,77,D5,5E,57,5B,0D,AD,D9,4B,68,36,17,8F,4F,FD,49,3A,EF,89,6E,A8,E6,12,F6,EA,5C,8B,0E,C4,CA,EC,F3,82,BD,74,E2,5C,77,4F,5C,3B,9C,91,18,1B,08,2D,53,83,38,65,30,D0,86,44,71,FF,3C,9E,04,B9,7B,33,C6,F0,B1,A6,38,9B,66,B5,A6,2F,CB,24,CA,7F,A5,0D,87,02,C5,A0,A5,5A,61,B7,EA,84,1E,CD,49,3F,4F,73,A0,C5,2C,2C,C3,69,57,62,88,52,88,C5,D7,4B,A0,45,B8,75,AA,5B,37,D4,57,F3,46,45,12,02,0F,98,71,33,61,55,F6,03,96,90,B2,F1,9E,CA,00,5A,3B,E7,91,9B,A5,1B,3A,5D,52,DC,2F,7D,48,96,1B,67,87,85,8B,EC,B6,EF,8B,DC,D8,A0,DB,9A,74,88,4E,E3,47,77,B3,D1,A7,E8,F5,37,60,B1,B8,DF,CB,71,2C,86,66,29,A0,8F,6F,65,D6,04,F7,8F,C5,01,1E,8D,EB,19,3B,0B,97,41,29,96,70,53,BF,39,4C,45,9F,25,A7,EA,F4,67,41,41,F7,FE,D1,49,33,66,20,1F,3E,3E,3B,D8,20,30,E5,E9,AA,11,5E,1D,3F,CE,14,72,A2,7A,37,A2,51,A2,15,95,F9,7E,90,50,76,39,75,67,79,5D,2A,9F,A9,CD,A7,34,E3,4C,43,CB,4E,FC,BC,C8,2F,30,2F,7D,49,69,29,BF,1A,9F,73,D3,96,CE,56,15,ED,07,3D,22,D5,28,33,CE,A2,AB,E4,C8,02,69,67,90,53,ED,CC,AE,AE,72,13,2D,55,9B,8E,70,1F,27,22,8A,97,F7,E3,A4,91,43,4A,16,1B,0D,A6,91,F7,C9,29,F1,23,0D,AA,A7,ED,C1,76,73,17,6C,6A,11,3A,62,1D,0C,14,6D,EB,33,8C,B8,A9,49,24,82,0A,4B,AF,7E,26,3F,7A,6E,96,E6,FF,99,45,F2,63,35,FF,5A,70,FA,29,AB,64,74,3B,FE,F5,B9,68,3C,D0,B8,5A,5D,BE,CC,90,7A,F3,0B,E4,D3,ED,3F,A3,23,D4,1E,9B,4A,4A,A3,05,C9,25,52,40,1A,A9,04,AB,5B,7C,68,A4,99,4A,4E,FD,5D,4F,FE,E4,8F,B6,99,4A,81,23,41,06,C1,E5,A9,70,A3,EA,96,C1,D4,2E,00,74,01,C9,E5,21,A6,B7,B6,FC,CC,98,C6,AB,52,A5,B6,C0,CF,F8,B7,15,2F,FA,8F,BB,6F,AE,2A,9D,22,3D,3D,F4,C6,07,7F,BE,32,AC,90,7E,6B,D4,26,54,1C,E4,96,44,AD,32,5B,FD,84,2F,12,3A,98,AA,7F,55,D8,67,A9,CD,12,95,05,64,CB,F6,96,CF,CA,16,FA,E3,9D,11,9A,99,71,93,9E,BE,E0,76,86,34,D9,1B,F2,73,C0,7B,F5,5A,CE,85,E3,6D,92,E7,9B,A6,6D,5A,B3,23,0C,6C,78,9F,FF,64,DD,F3,15,00,1F,48,AF,AD,C1,A7,60,3F,72,59,28,95,76,28,BB,96,C1,D8,D9,EB,70,97,AE,A7,1C,88,45,88,67,A6,98,EC,C3,7E,AE,3F,8E,31,3C,41,28,C4,4C,F7,27,50,F0,3C,A8,0A,09 diff --git a/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL5.bin.properties b/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL5.bin.properties new file mode 100644 index 0000000000..945773c7d6 Binary files /dev/null and b/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL5.bin.properties differ diff --git a/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL5.properties b/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL5.properties deleted file mode 100644 index 17aed124ed..0000000000 --- a/core/src/main/resources/org/bouncycastle/pqc/crypto/picnic/lowmcL5.properties +++ /dev/null @@ -1,10 +0,0 @@ - -linearMatrices = 4B,05,69,80,CD,70,7A,CE,50,12,76,02,9D,73,20,D0,AE,45,20,83,A4,56,D9,3D,FD,3D,50,44,DE,C3,94,A3,ED,44,42,06,D4,85,FF,14,50,8C,8C,8F,1E,ED,4F,26,71,66,7E,2B,6C,44,54,1B,38,C4,15,BA,69,60,56,86,69,E0,52,32,3F,43,80,E3,E9,2A,65,D0,35,9D,95,DF,73,C8,BB,AE,E4,A7,4D,8B,C4,15,23,BF,35,3E,A5,5D,91,0D,34,A9,A1,51,1F,64,FF,53,65,77,87,03,84,81,F7,9D,FB,E6,2F,59,29,A5,AD,79,D8,58,B0,22,ED,E4,C1,0C,E7,03,EA,C3,72,0A,23,DF,11,29,B8,E8,43,83,D2,C7,9C,3E,69,DA,0A,E4,88,8B,78,B6,55,19,77,10,F4,B7,35,73,26,1A,4E,A7,9B,66,E8,53,52,96,6B,B8,17,FE,25,2F,EC,F5,94,AA,95,2B,38,B3,6D,C4,54,B4,E1,C6,9E,C2,70,20,A9,CC,BC,6B,B7,36,AA,73,DE,89,B9,FF,59,AE,92,80,9A,C8,27,81,B6,8B,07,0A,6C,19,01,61,8C,E0,73,AC,A3,DD,3C,25,68,01,C6,70,22,F6,1B,26,E3,34,05,DF,F6,0B,52,B5,59,F1,B9,85,7D,9F,6E,34,DD,4C,D1,A9,70,DB,5C,49,50,A3,79,77,02,E2,20,F6,5E,C2,B3,E9,14,29,F6,F7,8A,26,3A,89,ED,D7,01,C3,92,9D,69,31,45,DB,2D,A6,A9,BC,64,57,A4,9A,F4,11,33,01,08,4C,59,5B,1C,D9,2D,1D,62,19,58,45,1F,61,E7,62,F1,89,67,71,92,6C,E0,DC,01,18,C9,7F,CD,97,6D,27,66,42,F7,E8,A7,F3,A8,3B,15,96,8E,03,A8,CE,38,7C,51,A9,1B,B2,C4,A0,33,06,07,BA,0E,30,D3,04,86,F5,02,D5,F8,C5,20,06,B4,F3,08,4F,57,DE,2F,0F,2D,86,EF,8B,44,38,55,D6,30,FA,B7,5E,E7,7B,7E,10,D1,AA,87,D1,2E,04,31,3B,A3,7E,29,C6,19,0F,71,14,B1,51,81,34,90,B0,06,DE,8C,7B,3F,34,DC,76,26,BB,A7,77,1C,40,7A,69,5D,B2,7B,CE,B1,BB,11,C3,3A,B0,29,C2,15,8E,15,6F,7F,63,B0,ED,49,33,52,A3,DF,6C,35,70,5A,B4,F3,DD,8C,42,D5,B8,80,A4,8E,CB,B6,C7,14,E1,54,B4,37,82,37,FB,03,E5,72,DB,E0,B3,80,C2,CF,36,DE,A3,AC,37,E3,F6,24,64,A3,9C,60,28,15,22,FF,0B,73,20,FD,A9,B7,C1,2E,51,03,67,3A,6C,D3,78,ED,D2,7C,B6,91,31,AE,15,7E,E4,82,6D,88,48,16,A7,A5,A8,D3,FC,75,B7,D7,29,32,CF,10,DD,6A,63,58,1E,E6,82,79,79,CC,62,62,0F,56,37,71,4C,2C,6C,AB,BF,0E,5B,49,F2,D4,BE,43,6A,10,1D,74,84,33,CE,5C,5F,DF,8E,BC,7C,32,75,75,D9,01,DA,C5,0D,4F,53,E5,7F,12,B6,84,53,45,C3,63,27,13,D0,E2,F0,9D,EE,95,9E,19,96,41,65,8A,2A,D9,43,75,61,0A,A2,9B,74,6C,87,3E,4D,DB,F4,16,E4,15,83,98,7D,C6,FE,DF,28,02,EE,3B,78,20,71,AA,10,20,25,C4,67,1E,D4,02,98,F1,0A,05,19,DE,2B,B2,D4,EA,1F,71,16,91,C6,E3,DF,85,6F,02,38,43,90,84,FA,00,00,BB,81,93,AB,5B,E5,6E,58,1F,8E,8E,DA,48,23,DB,37,69,D5,7F,50,D2,E2,CC,B8,D0,0D,36,00,0C,3D,1A,BA,D4,44,C3,38,98,74,78,F6,A1,13,F2,11,42,B1,D4,3D,23,51,66,7F,D7,9E,5F,A8,42,8D,FF,32,B0,F8,7F,50,11,D5,A7,26,9C,AC,28,D1,75,3F,B7,5E,A8,CE,97,6E,A4,F3,AB,65,B3,FA,27,4E,79,D0,8C,A4,E1,F7,C2,05,CE,02,81,96,84,A0,24,D9,0D,39,35,63,5C,F5,88,1C,85,E0,8A,6C,F0,CB,F3,C0,9B,41,38,87,4C,75,48,03,B9,B7,EC,87,74,82,AA,89,92,98,3F,74,28,E5,9C,BD,31,0A,0E,74,D7,A1,57,5D,31,E5,68,83,1B,7D,D2,45,07,1E,46,12,49,62,14,99,C8,A9,BD,7E,88,67,54,5E,31,83,07,2C,06,08,6D,C5,A3,2E,1F,79,3A,4B,8D,EE,F4,3B,91,89,E3,A4,8A,62,54,2F,62,4E,A5,45,ED,17,8A,5F,19,AF,24,62,93,F8,37,82,8E,DD,15,62,16,84,03,67,53,A6,14,DE,8F,CB,F4,E7,43,11,F4,05,84,E7,35,2E,FB,18,03,24,8C,19,59,CA,92,47,A9,D0,7B,F2,1D,84,1E,2C,D2,0C,39,E0,75,86,60,EF,A7,E3,57,7E,40,F6,45,13,83,26,91,1C,E4,5B,68,06,C6,99,4D,96,A7,16,E6,D1,8B,2F,9F,24,49,0A,29,2B,40,41,08,20,34,1E,AB,4C,2E,BB,46,9C,2F,96,7E,23,7E,A4,D8,A9,37,1C,BA,E7,12,9A,A9,21,A5,07,B9,F8,E0,F4,7C,BB,30,64,1B,DB,9D,88,BE,A2,24,74,B2,38,8C,28,26,EE,8A,38,1C,F1,8A,D5,00,DD,35,54,6D,52,04,D1,44,3D,3E,78,7C,B5,74,B9,73,7C,55,0F,0F,6F,16,37,0F,3F,53,50,A0,6C,EA,90,28,3D,4D,BE,48,CC,AF,A1,6D,7C,E4,D1,63,E5,22,1E,4E,F6,E6,60,BB,7A,6D,DC,B9,C7,4F,78,90,38,FB,0D,E3,AB,4E,F2,38,D8,BD,F2,EA,C4,98,A2,00,53,4A,0F,F8,91,54,2F,50,9E,8F,C2,DC,A4,5B,E8,58,98,49,66,1D,3D,BD,CE,7D,5C,F6,5C,21,AD,AE,EE,D5,27,61,84,02,83,5E,86,71,C2,80,59,3D,17,81,E2,91,87,34,4F,2A,A9,2C,26,CF,58,BF,25,D7,A8,34,58,F1,41,68,CA,4F,2C,D5,18,94,81,B5,4F,0F,44,95,83,6D,A6,4B,4F,EF,8D,4B,FA,1F,9C,B4,3F,FA,17,29,CC,32,69,11,BC,47,78,CB,DE,C3,20,BA,B4,78,28,59,C0,9A,A5,AB,F6,7A,56,D5,39,33,0C,85,AB,F3,CD,47,BA,35,F1,F1,04,59,13,B8,79,E3,FC,EE,C1,22,3E,12,65,04,AA,84,7C,3A,68,08,1D,1F,75,A1,BC,25,87,DF,E6,1D,9A,AA,14,72,95,31,E8,DC,2B,03,B6,91,36,C8,2B,E7,C2,D2,B7,8E,4B,D1,0E,F4,A5,ED,51,1A,76,D4,00,6A,A7,06,55,DE,BC,38,D6,85,C8,36,41,CC,B4,76,C0,16,F7,B8,60,EE,22,A0,27,CE,2C,49,F6,15,89,E6,FE,B1,DC,56,91,2C,86,0C,DB,51,B7,8B,C6,F5,20,61,CA,0E,40,56,3D,63,B4,46,54,CB,BF,2B,87,7A,9D,F7,EA,5C,29,71,2B,E7,6D,03,7A,39,D9,5E,FD,09,E2,6B,FF,A8,23,34,CA,50,EE,61,F9,8B,76,3C,5B,AD,B1,37,7C,0A,A9,69,C7,E4,A6,C1,72,2F,FC,7F,9E,DA,14,29,78,25,2D,70,F3,8D,2C,24,16,8B,19,92,37,D2,68,16,65,81,D0,3C,8B,04,5E,5D,47,68,8A,84,36,C0,1B,81,F9,4C,FD,EF,12,E2,F8,F4,6E,EE,43,C9,C8,8B,CD,2E,20,1E,6D,1F,05,30,23,F3,FA,D2,3B,11,F8,03,08,DD,20,5A,39,F1,E4,AD,40,83,E4,DF,4E,67,A7,AA,AA,F1,81,4B,02,D1,56,5F,E2,82,E7,BC,B8,69,E5,56,D2,C6,BD,F4,18,43,D5,72,07,71,44,C2,2F,4D,F4,48,C7,AE,19,B9,45,2E,CE,7E,18,A0,E7,76,0F,1D,BB,41,3E,7D,50,F4,03,1E,49,8A,F4,1A,D0,88,C7,6A,67,B1,41,FD,7B,43,06,A7,16,18,14,0A,8E,D1,F1,FF,10,C8,A2,7A,37,46,81,B2,6A,41,1A,3A,4E,4B,9F,EC,FE,C1,94,B4,ED,6D,F9,AD,63,9A,FE,B0,F3,DD,B2,7E,21,39,41,BF,C5,C0,6A,6F,FC,E1,1F,07,29,46,06,B4,A2,6A,36,CF,51,62,FE,45,A4,66,F1,0F,16,F1,CD,B1,9E,E2,43,FF,78,A1,C3,C6,FE,AE,B4,70,14,D6,1F,67,B1,93,73,24,D3,AD,F6,79,90,1A,AC,EB,2A,4B,B7,39,F0,29,61,7A,8D,5A,2D,49,4D,E3,F2,07,6C,0C,7F,9D,DB,E9,80,67,61,7B,80,CC,A0,D9,54,5B,75,63,ED,08,A4,5B,D7,B2,CA,7A,A8,C3,DF,BB,AE,7C,D6,62,D0,F7,99,95,8A,FB,D0,DB,5A,A1,77,66,AE,2F,BD,97,5F,A0,A8,4D,AA,25,05,82,BD,76,0E,B8,F8,4D,AA,E2,4F,B3,EE,2D,6C,E8,70,C9,CD,91,AF,2F,CE,16,8B,C4,D7,05,9F,B4,89,56,18,6B,E8,A3,9D,63,45,56,31,01,CE,D7,B1,13,CF,2A,BE,D5,CD,F1,3E,79,4A,AD,F4,10,C8,B6,74,31,25,88,6B,0A,6C,C7,8B,34,D2,75,AD,81,77,F2,63,1A,2D,05,F8,41,25,59,3D,45,F3,E7,B7,80,77,43,6C,E8,4F,04,7B,B2,05,33,57,1F,B4,76,5E,70,42,87,33,75,3F,85,DD,82,D0,90,70,C8,02,9F,4B,18,A6,13,5F,D5,F6,D6,75,47,07,B5,33,0D,C8,52,AB,C1,6F,0E,06,70,B5,EB,A5,BC,6E,7E,0E,7A,9D,D0,9F,7F,E9,AF,B3,B5,80,7E,A3,3A,9D,29,D6,C3,CF,FE,93,D0,65,CD,BA,36,B9,B7,2F,29,10,A8,FD,80,D5,B9,D1,24,4A,86,D5,A7,60,C0,5A,2F,27,66,9D,5B,0B,67,03,B0,7D,41,08,9A,0A,78,D7,3E,F8,5A,7F,68,54,0C,16,B1,EB,3D,BA,92,24,60,D5,36,5C,78,6F,4B,D7,6B,03,74,59,7B,B2,82,F4,EF,FD,4F,CF,32,63,47,59,53,A2,48,81,62,8D,4F,7A,20,AE,CD,24,C3,5B,9D,C4,43,05,5C,2A,20,F9,A1,A7,8D,B0,42,20,8C,77,7E,DF,F4,0E,77,1A,1C,0F,EF,BC,F9,FA,B9,43,21,5C,52,D4,7A,6A,DB,CD,91,5C,B1,8C,EF,09,CD,FA,B3,72,38,7A,AF,09,D6,3F,FB,8B,80,27,F1,9E,5F,15,A3,CC,2D,62,19,65,CD,B2,FB,55,04,17,E6,87,5D,A6,0C,E8,EA,5F,83,FC,2E,B7,D2,96,9C,CC,C2,D2,00,A0,FF,4A,0A,A1,08,B9,E9,81,EA,A3,C2,17,88,41,B6,5F,FC,76,46,C5,38,1F,44,5B,89,67,3C,C1,AB,AA,4D,F7,84,98,35,A2,99,66,93,BF,5D,F6,BB,D0,0D,78,9B,DC,56,EE,CC,C8,40,FD,D0,07,D7,71,B6,1E,C7,33,93,0C,81,7D,90,B3,48,CD,D1,94,EE,13,08,A6,88,13,AF,58,EA,D3,87,96,1A,1C,50,00,1F,C5,07,19,AE,2E,61,19,1B,4D,21,32,F5,02,5F,B0,C1,7E,5F,FD,F6,B6,18,B5,C4,0A,53,C2,9F,96,98,1D,D1,13,B1,FC,99,CB,C7,79,E3,98,4A,09,FE,4A,FC,B4,A2,26,6C,0A,AD,2A,CF,DF,2C,5E,3B,54,A1,FE,2A,0E,0E,69,1F,51,1B,7A,CA,E3,A0,EC,12,F9,B3,07,21,7B,42,F3,CB,E2,22,0F,D2,D3,22,9D,AC,E2,24,DA,FE,58,CD,B4,FA,15,CF,24,8D,F7,BF,6F,F4,03,5D,0F,8F,65,BE,5B,A7,42,0C,7A,07,EF,D9,C6,75,27,FF,9E,15,BA,40,D1,BB,DD,98,C8,8F,B1,35,02,19,7C,B4,E9,E6,FA,2D,2F,47,EF,10,1D,8A,08,7D,6A,38,8D,9E,9A,66,73,1E,24,CE,AF,B2,EA,6D,38,D9,D3,E2,F8,74,FC,0B,62,91,43,6E,35,20,06,C3,3E,9F,0E,93,12,DD,81,CB,64,C8,50,AA,FA,43,DE,69,A1,EC,5D,A2,1D,AD,88,AE,D5,1B,44,A2,24,7F,D6,4E,D6,01,07,A2,4C,AD,58,52,E5,FB,37,AE,5A,D6,6F,90,01,8F,8A,C8,9D,BE,75,C6,98,D2,B3,E8,AA,73,E3,83,0B,32,64,84,DC,B0,CF,98,2B,91,48,81,2D,73,FF,43,37,71,15,84,50,01,95,F5,B7,21,8F,4D,3A,67,7A,3B,AE,2E,F1,C9,26,0C,C8,48,19,64,73,79,7F,6D,06,28,4C,2E,4B,A6,3D,99,DE,DA,A5,40,AA,BC,4C,2B,87,43,DF,FE,B1,F1,61,86,6D,C5,52,23,43,1F,D1,DE,A6,F8,D6,DB,24,1B,90,A0,7D,68,AD,18,35,4D,2A,E5,38,99,6F,91,BE,23,DF,74,26,07,14,76,4A,C2,8B,7C,BB,AA,0E,87,13,47,F6,3C,2C,A1,2C,FB,AA,C9,FF,BF,0A,5E,26,F5,52,13,6E,58,A7,4A,B6,DB,AB,45,C0,DE,D2,53,A1,B9,FC,76,1B,39,88,F7,0A,AD,17,5D,93,45,F4,C6,E3,AC,9F,19,D2,E8,C3,A2,D7,6D,01,61,4E,72,F4,BA,4F,C9,7B,3C,AF,F0,5D,8E,9E,99,9B,5E,06,C4,7F,2D,1D,BD,33,AE,35,4F,B2,1F,0E,FB,4E,D6,A3,63,74,C2,C8,36,E4,7A,63,B3,A2,1D,27,A0,30,0A,53,A5,BD,7C,52,C9,4F,E1,DC,F4,3D,30,3E,20,E9,73,41,36,AA,A5,95,78,37,B2,4A,A3,65,C6,C0,EE,B0,67,DF,A6,C4,2D,ED,06,5E,D6,87,14,B0,B4,7A,58,63,61,D7,DA,0D,12,A2,CA,8A,1A,3B,5C,94,3A,2B,D6,59,5B,10,B5,2A,24,BA,1C,25,03,1A,D3,EE,19,D4,FA,10,7B,52,EF,9A,21,F6,B1,AC,44,60,F5,9F,7C,C0,CB,7E,64,53,C4,C2,D2,00,D0,CB,A5,52,D0,56,36,8A,19,19,92,7F,19,6C,3E,32,2B,CE,3B,6A,F0,5C,E1,67,3C,A0,F6,CA,14,E3,C4,1A,7C,0B,B5,00,FA,EE,78,29,FB,A1,47,AC,80,D5,80,59,7C,93,4C,31,0F,FD,E8,36,E8,05,B0,92,B9,37,29,6F,AB,00,87,EA,E5,A3,BA,1D,49,32,6C,2F,64,77,79,4E,E5,29,9F,86,C9,09,4F,0F,F3,5A,60,F1,6D,DB,4D,94,14,69,35,14,C1,1B,C6,BC,C9,E6,13,4C,DD,80,1B,BD,84,1F,B5,86,3B,15,AC,F8,F9,85,67,26,C4,C3,15,3F,FB,95,68,87,9C,36,DB,79,6B,85,E1,59,D8,D4,20,76,2B,29,1A,8D,A5,7F,27,A7,F5,CA,82,33,94,A8,5A,3B,F1,90,58,69,F4,A8,47,A9,DF,80,82,83,E7,3D,3A,F0,C6,B5,3B,99,A1,0B,D8,C5,3A,C4,D2,37,F3,2C,FB,2F,78,4C,E2,D7,A4,8C,5B,67,74,61,15,91,10,09,AF,F7,06,CB,C7,D6,43,DB,04,DD,F1,B3,2D,61,8B,F0,AB,6C,21,69,D6,85,0B,97,9B,0E,D4,92,37,35,67,89,21,ED,1C,00,9A,F8,9A,E1,AD,95,AF,45,0A,CB,82,84,95,3D,E5,B6,AA,F5,9E,FD,51,BA,FD,29,E0,04,FD,55,90,29,D0,03,D6,EF,40,E7,55,F9,1E,F2,07,C3,56,10,7B,1B,C0,CD,40,F7,06,99,83,A6,45,3F,62,0E,5E,17,21,6A,2E,A3,63,6F,F7,F1,DD,4B,C9,C2,62,0C,5E,84,0A,57,10,90,93,46,4E,60,1F,0A,2C,6C,3D,7D,24,66,23,64,98,66,5B,38,A8,74,A9,0D,50,E2,DC,06,86,0A,98,83,0F,6B,05,CF,68,C6,D6,D2,51,46,2A,E5,D0,EA,88,58,5E,4E,DF,2E,59,AF,2C,A9,B1,DA,B8,01,75,16,3C,0A,5E,06,88,73,66,B9,AB,E1,6F,91,28,BC,0A,77,77,41,40,E8,6E,B5,4C,D0,FE,8B,2E,9C,EE,9B,BD,21,BF,49,CC,E2,E4,E1,63,39,08,74,74,64,B8,A6,12,0F,08,79,3A,0D,8A,61,61,B7,5C,6C,32,C1,17,89,07,33,3C,40,97,F1,13,F9,04,9D,21,A5,EE,75,3A,CF,31,FF,1D,B8,62,88,25,2E,86,3E,CD,F3,19,5D,15,43,6D,4A,FD,57,83,53,B7,BB,B4,7A,8D,03,F6,6D,89,42,F8,59,55,4C,96,AB,46,F2,8D,80,2B,28,FB,DE,6C,9C,B9,72,E5,B2,35,3A,E8,C6,53,96,73,8E,D6,0E,CA,2B,C8,FE,D8,E8,79,CC,33,76,4F,63,E7,FC,07,C8,7B,1B,B6,8E,1F,21,B6,3F,BE,44,55,56,78,16,DA,21,B8,73,9C,1D,1C,2F,F0,33,C8,AA,E6,66,C9,32,F8,F1,2E,31,D0,C4,B0,88,E8,7D,69,3E,DE,1C,10,77,56,B5,FE,C0,20,2F,3A,25,C0,52,EE,E3,82,F9,BD,24,8D,7B,AD,DC,8B,0A,35,D3,8E,3B,58,A1,6E,EA,0E,AB,93,75,C1,DA,B5,EB,82,6D,C6,EC,52,E3,13,C5,24,0D,33,A9,5A,98,25,50,5F,67,D7,AC,D4,BC,DB,2D,D9,E9,E7,EE,08,98,85,D2,51,51,04,E0,D4,B6,73,56,68,E2,68,AA,A1,31,DE,EE,57,58,B4,34,15,2C,37,27,28,D7,88,B4,40,0D,6D,0F,C1,B8,AB,0F,D8,3D,F4,9D,06,53,37,FC,14,4F,FD,2A,91,A9,C1,57,04,13,80,7A,2E,98,65,62,1C,32,60,CF,53,1C,20,3D,E3,D5,F4,65,CE,22,97,91,10,6F,1D,2D,45,DB,06,EA,33,23,77,93,E3,8C,A0,7D,86,74,4E,16,78,E6,F9,1E,B2,7A,7E,18,B8,E6,0A,DD,0C,EF,3A,2A,28,99,97,A0,0F,B0,14,11,A3,16,E3,CF,06,92,CF,AD,E6,E4,19,F1,36,2C,94,09,37,C9,4E,8A,15,9D,09,C1,8D,D0,82,2C,7A,8B,76,FD,4D,C4,50,DE,54,B2,98,31,4D,32,99,26,DE,21,C9,AE,66,9C,7B,71,67,C8,A2,45,2B,9D,96,0C,5E,0C,27,AD,1B,C8,64,78,66,18,53,B7,63,FA,37,69,8C,CA,09,17,7C,92,4B,D1,00,6B,4B,71,42,E4,C0,61,18,AD,A8,08,29,B5,0E,92,BA,C3,F2,9F,BF,8F,E3,B4,43,CD,CB,00,E0,B9,1E,93,61,10,21,2E,EE,AF,E4,B7,23,9C,AB,A6,4C,02,93,53,59,6C,71,23,13,0F,1A,E5,15,0E,0D,DF,EC,A7,4B,5F,97,9D,30,7C,56,35,21,E7,AF,42,D4,BC,71,71,53,57,69,94,B4,52,F3,EB,61,3A,11,F7,CF,00,85,E0,E6,16,D5,0B,1D,8D,70,A1,13,9A,F6,FC,91,88,F0,89,88,57,56,4F,DB,03,D3,E6,D5,39,C9,EE,88,2B,04,BF,09,CC,E0,39,E1,D9,7D,EC,F2,F0,5C,73,79,24,44,26,F1,DD,6E,7C,59,AD,C5,F7,46,96,26,96,DE,97,D9,A6,09,23,1F,E6,A8,27,27,2F,C4,69,4A,78,4A,1D,40,0B,A3,0C,3A,DF,83,A1,BD,A9,BD,78,22,B5,E2,77,2A,C1,12,27,3D,E1,FD,80,B3,09,52,84,4C,D5,B2,B9,05,C0,53,A4,B2,AD,4D,4F,94,5C,91,12,83,7A,1A,16,B1,6D,B5,8B,41,85,13,56,7E,56,F9,2B,68,E8,AA,E4,E0,D1,AB,88,E4,25,6B,5C,A0,19,01,7E,46,25,72,16,33,CD,E2,41,9F,F3,4F,45,45,B8,A3,FF,87,79,07,14,35,CC,47,2C,66,53,75,05,25,6B,BF,92,80,34,6C,CD,9C,E8,F5,44,65,A9,28,CC,C8,00,FE,BA,F5,C5,A0,8E,71,90,E3,CC,3C,42,F8,F0,83,9A,F3,7E,C4,46,C2,23,75,1B,97,18,04,97,78,66,CC,FD,B2,D5,9A,EF,91,E9,D0,BC,36,18,A2,60,2E,6D,14,DD,87,23,4B,E4,62,31,A8,0E,5D,F9,42,CD,FE,1B,C3,3A,94,88,3C,F8,0F,5B,DD,E8,69,DB,68,1F,95,10,31,8F,E8,AC,E1,EF,09,59,FE,4F,A1,17,E5,F7,70,73,8D,56,0B,01,92,99,28,C8,BF,5D,D1,66,62,D9,0E,0E,C9,B2,28,66,BD,9A,B4,31,28,0A,02,C4,EB,EA,15,AB,F3,35,D8,01,8D,25,F2,A9,80,85,F1,92,A4,10,09,9E,6F,12,46,F8,00,34,F5,0E,F8,78,32,F2,5C,C6,FC,F1,DF,F0,AE,A0,CF,AF,B2,6B,A7,89,D1,E0,82,36,1C,BD,4D,08,52,DA,8F,9A,36,51,72,19,DC,9B,39,45,27,53,97,3F,3F,C5,19,55,B9,87,85,25,4C,84,35,5B,9C,E8,17,C4,F0,93,E5,2C,CA,D2,14,62,3C,6E,2D,68,2C,78,F2,F1,CD,40,B6,FD,48,6A,C7,1A,88,D1,DA,62,B7,C9,AC,DE,B2,4D,0D,73,19,86,7B,25,66,6A,F4,15,93,B6,81,9F,B6,99,E3,A6,9A,12,D3,F8,61,6D,11,51,66,F3,A0,38,A0,97,DB,54,C7,02,C4,69,61,2C,E5,ED,01,9E,78,0F,02,F6,11,C5,18,7B,B9,D2,FA,9B,80,9E,0E,B1,D9,0B,B0,27,CD,59,E7,66,48,48,8D,89,75,01,D8,A2,81,DD,55,F2,65,9B,90,55,E6,FB,27,BE,A4,1A,99,5B,A7,57,64,C4,75,64,1A,96,D0,62,6D,8F,E3,0D,92,8C,9A,C2,B0,0D,EE,2C,08,2D,C9,1E,B9,78,16,5E,82,73,7C,8E,53,40,01,51,2D,F6,EC,D5,47,18,21,A8,B3,8C,28,89,41,B7,0F,69,AE,92,B8,99,02,F0,DE,E2,2A,2D,D5,EB,DE,E1,34,E0,C5,E0,76,B5,2F,6C,26,5A,15,DE,2F,A3,D6,21,B1,9E,CE,20,49,72,10,A6,66,A4,C2,B6,EE,F7,03,1B,30,5E,B0,E7,AA,61,25,1E,63,A4,A0,0C,93,AE,9F,5D,6A,E1,6A,7F,51,1C,58,B6,CB,4F,F8,68,3A,E4,C5,74,CC,5C,2D,01,A8,CA,90,F6,99,EA,0F,29,56,67,09,C6,9B,56,2D,04,E7,2C,3F,E3,23,8E,72,C5,3D,58,10,96,D1,78,CC,4C,BE,96,0F,49,1E,C3,79,2F,42,AB,93,39,59,EF,42,D8,F9,78,DE,24,DC,38,08,DA,CB,EF,C0,7B,DC,20,14,35,2C,38,F6,BC,96,E6,27,61,54,59,C0,30,B8,5A,CE,62,D0,A8,6C,6B,8E,B7,6B,93,5C,94,31,1E,29,6B,69,EE,E8,76,17,4A,3E,41,43,1C,0E,79,1F,30,D9,26,5E,FB,41,0C,26,1C,5A,36,99,19,68,65,91,97,5E,83,7E,89,D3,E0,CC,D6,FE,48,CB,EE,A8,13,D5,CA,71,20,A6,F7,0D,E2,99,82,3B,02,BC,73,65,1F,86,08,1E,8D,32,7A,73,55,54,78,65,74,8E,2E,EF,F3,C5,B0,4A,13,D4,F5,30,DA,B8,9A,80,EC,F3,E3,D5,B7,63,16,B5,55,8D,65,10,D8,D8,9A,8B,AA,C9,4B,61,2C,09,19,03,82,DE,6F,07,BF,B0,08,22,E0,E2,A4,7C,6D,E9,D1,0C,45,5E,3A,E4,44,9F,CC,AF,90,E8,B5,AF,78,52,48,13,76,6A,96,B0,1F,E9,BF,8B,29,24,81,53,AB,D1,2D,F3,FC,99,B3,9C,69,30,2C,39,88,C2,F9,64,AD,92,9E,E9,8F,8F,10,83,B2,2C,67,71,43,C6,62,63,A4,73,49,DC,F4,79,D2,A4,F8,36,C8,19,F0,75,9C,33,E2,ED,81,04,A3,36,AD,D1,A9,B9,8F,DF,2D,18,FB,EA,07,BB,EF,59,1E,37,72,C4,3E,72,4E,42,B9,D7,2B,A4,FA,05,C7,7D,93,C9,79,D3,21,7E,86,8E,7D,CD,09,69,51,A3,7D,66,DB,6F,21,42,09,E5,5D,46,E8,66,F5,77,5D,A4,D3,5D,51,36,50,40,8B,B7,29,47,3D,23,BC,16,56,87,1B,A1,BB,9F,B4,24,24,6E,61,0E,9C,3C,71,14,6B,73,99,76,0C,B4,3A,73,46,47,EE,52,F5,40,C7,70,71,5E,76,07,6E,79,60,33,D4,A4,AF,62,24,8C,2A,AA,A3,3C,C3,DB,CB,8B,46,C9,B4,AC,78,E1,D9,03,F3,96,66,55,E6,EB,6D,8F,25,90,E6,CD,73,9D,D5,17,44,36,0D,58,DD,41,21,7E,9B,24,05,A6,DF,D4,B1,EA,84,11,07,1D,DB,65,07,3B,6F,F7,87,2E,0A,EB,6F,4A,D7,CA,5C,C5,41,3B,BE,9C,D2,9A,B9,18,A8,73,E7,54,F8,48,3B,81,36,D0,2D,5C,2F,AA,3C,00,A5,F6,D8,B7,D8,47,DD,BF,00,CF,CD,A0,66,55,63,6C,51,50,13,64,73,72,E6,A8,E8,7F,6F,FF,93,43,B5,5E,25,3B,F9,CD,C2,32,EA,0C,E4,92,8E,F1,B8,27,74,0F,37,59,5B,CE,08,97,0E,D5,40,74,9A,87,B9,FC,CF,4B,80,BB,EE,D6,EE,1C,67,48,03,C1,7F,39,2D,0F,09,2E,BE,99,95,56,F0,89,73,A3,B8,B6,BF,58,F4,87,4E,E1,CF,AF,F1,47,5C,63,EF,D6,FC,94,57,02,F1,5A,69,50,44,12,C4,F7,B1,0D,6B,E4,E8,BF,DD,84,11,28,3B,9D,9F,8D,C3,63,8C,3A,43,2A,F9,A5,AB,13,F1,75,DF,BE,3B,82,AC,AD,15,75,BC,E4,B0,62,8A,29,60,1D,28,C3,3D,31,96,DF,75,3B,2C,44,9B,5B,9A,79,3D,A1,2E,95,92,EB,D9,F5,78,D1,58,BC,18,C4,D1,62,14,C3,36,50,78,11,BB,FD,AE,84,77,1F,59,B8,52,27,38,A2,63,3D,4A,C4,86,BC,FB,14,E2,72,A6,9B,02,5F,80,D0,15,84,DE,CA,29,39,A6,EE,F2,4D,37,2D,A1,01,F3,03,7B,83,98,93,D1,A3,B0,C3,4F,55,75,CB,2A,CA,D8,4D,32,1B,A9,D5,CE,98,B1,DE,72,2E,EC,49,3A,63,B1,A5,19,89,EC,E5,58,E0,32,E4,CC,18,D7,19,EC,75,55,EC,DB,FF,2E,E8,EC,8C,50,2D,FA,27,98,EE,EF,1E,72,28,A0,5A,6C,78,F4,E4,88,37,A1,B2,B5,4E,23,54,DD,73,EA,97,B7,B0,F9,0E,9F,65,E9,55,36,FB,A8,BD,21,F9,E6,4B,15,50,15,F8,70,7F,6F,6F,CF,C1,94,9A,A0,9E,89,87,0B,41,5A,8B,64,89,C4,53,17,6A,F3,69,E8,D0,B5,6D,F1,18,D4,F5,37,8A,CF,63,4B,01,D0,D9,B3,F7,4E,89,A4,0C,FF,1B,DE,20,A6,F3,E4,64,F0,A1,07,C4,FA,3D,0C,5D,B6,2C,34,7A,DC,E2,73,15,7A,62,71,EB,27,A0,87,B3,70,25,23,00,AE,A2,4C,6D,F7,0B,35,11,D3,51,2B,9A,79,1A,FF,EC,45,C2,28,FB,BD,44,9E,4E,C2,E0,F9,E8,97,92,96,F4,A5,08,52,2B,EA,CD,8F,6B,49,A7,8C,F7,5B,58,21,1B,1B,E7,91,A9,69,D0,2F,2B,EA,6F,9E,03,FD,41,4B,C9,51,9B,5D,F8,E0,48,C9,DA,81,ED,59,58,B9,27,94,95,6B,38,32,55,20,61,4E,2A,B1,C6,F9,43,A2,8D,CF,A2,CA,C2,C3,3E,55,FF,B2,DF,88,9B,57,10,7E,FA,94,A6,C2,29,F7,92,77,1B,84,C3,B3,AD,BA,FA,B8,4E,0C,A0,10,F8,1D,DD,4F,C5,47,B6,D5,B7,8E,F6,F8,71,A5,7B,C3,FB,9F,01,03,14,BB,4F,86,47,42,12,61,0D,7E,E3,1F,55,7C,CA,88,3F,D9,84,13,2B,75,6D,75,3D,F6,43,31,62,37,98,9A,62,35,B7,90,6B,28,9E,CA,DF,F8,7D,73,39,DE,E9,8F,56,BA,C7,DB,9E,57,6F,DE,47,0A,CE,24,9F,FA,4F,97,02,04,B7,BB,51,78,F7,3E,5A,57,65,BF,F9,50,00,60,C6,D1,A4,2E,9E,CC,35,D7,5A,3F,9B,C9,D6,85,41,49,93,10,FF,3C,14,A1,17,C1,83,E0,4D,4B,06,A1,16,B0,1E,B5,D7,12,3D,A4,CD,19,47,B1,09,51,8F,58,98,C6,47,3A,D5,33,06,C2,1E,25,9D,69,5B,AD,B8,BF,3D,2A,C8,9F,07,89,06,A6,85,A7,36,88,61,FE,88,06,46,CD,26,E0,D0,32,B0,16,F1,5A,B4,1F,81,1F,0A,26,0E,51,A7,1A,33,60,76,CA,4A,6E,61,CF,CA,35,FB,30,0E,8F,84,79,45,5E,AF,8A,12,CE,9E,36,94,2F,63,E2,C0,82,44,99,D2,52,7F,25,D5,9F,80,F2,D4,C5,A1,43,D7,4A,8E,F0,BD,1E,AE,07,3C,01,1C,1D,53,64,6D,30,9D,9B,6A,29,49,32,9D,44,A1,91,4D,75,16,FF,1C,C1,34,55,2E,9C,FC,09,1F,6B,EC,10,DC,0E,D5,64,F5,B4,A4,A6,62,42,D4,63,53,34,31,B0,54,40,12,64,F2,BD,45,41,A5,8E,95,82,97,00,F3,09,C7,8B,75,AC,1C,DA,07,95,FA,5B,18,29,74,57,43,F1,C2,7F,A7,23,65,16,C2,34,06,26,D4,0D,5E,51,B9,78,C1,67,92,EB,52,2A,FD,A4,69,D5,F7,65,98,6D,EC,2A,39,C3,5E,A0,43,5A,B7,13,E0,86,6C,60,FA,B6,3A,85,54,9A,BD,0C,E5,08,A5,41,68,A4,D3,D3,FA,3C,F0,38,1B,DB,2B,E1,5A,F0,C4,5D,FD,0C,24,8E,2C,F0,E1,D9,30,83,4F,B5,4F,66,33,29,97,71,A1,71,66,12,58,79,B5,FA,2C,79,59,43,F8,E7,F4,91,8C,3F,0B,49,EC,88,1A,FC,CB,73,3F,14,26,7F,A6,D6,D9,69,32,B7,19,79,E2,5A,EF,2B,33,E7,FD,57,FD,3D,73,BA,46,F4,3F,D4,D3,44,66,92,2A,62,71,4E,7F,2D,34,7D,07,7B,2E,84,24,1D,01,DE,39,A5,63,E9,03,B4,F2,84,ED,9F,D7,D7,6A,31,C4,AF,B4,36,94,BB,C8,94,83,55,71,C7,3D,98,BF,8D,BD,BB,65,AA,92,07,8B,88,E7,F3,A7,30,EF,48,7F,42,73,7B,E5,D9,9B,79,4A,C2,68,8E,70,FE,88,DC,25,24,16,7D,58,CE,06,E6,15,EE,7E,7D,AB,12,CE,B0,EA,94,8A,9A,2B,4A,D4,B2,E7,80,B8,8A,D3,6C,C8,0A,7A,99,77,FE,D0,1B,CF,72,D2,9F,A3,28,5E,0A,96,4F,76,5D,BA,22,80,CA,26,15,A3,0C,CB,7B,0E,F2,5E,56,E2,D5,61,F8,E7,78,1F,C6,F9,77,5F,13,FF,0B,BD,F9,09,FD,BB,31,E4,24,E2,71,D2,DD,9A,73,C0,E9,E2,60,7B,BE,5C,64,48,1C,50,20,FE,C1,68,39,F5,E8,E2,C0,1B,92,91,70,25,89,18,26,CD,3D,06,8C,41,9D,50,69,DC,36,30,78,31,A0,2F,25,1C,95,63,E5,84,F3,B0,78,2C,AC,16,6C,90,00,F7,23,95,B5,1E,C7,49,03,08,ED,7F,8F,60,99,72,F5,B8,6B,CC,D4,6E,67,49,C7,C0,43,47,E3,DC,FC,05,D0,5C,83,3D,E8,47,ED,18,1D,66,E8,26,D4,79,32,C4,F2,45,9F,FF,15,BE,04,1F,3A,93,CF,2A,A0,D6,3C,45,06,3F,D1,59,9A,F6,3E,5A,7B,B1,EB,29,92,88,28,D4,9B,9B,09,DD,1A,F9,D2,BF,0C,7A,DD,AC,4F,E5,F8,AE,55,0A,13,80,F3,E1,BD,A9,B3,87,89,8D,2A,FC,7C,8C,BC,41,27,D6,41,30,13,34,54,F1,CA,04,67,76,41,71,E5,85,1B,C4,B6,2D,66,40,FB,14,50,55,EE,AE,EC,BA,99,99,DF,2E,44,41,1C,CC,1F,57,7D,84,4A,F3,E7,F0,F0,5D,A2,0F,9B,F9,2E,B6,69,4A,92,3C,29,34,D1,3F,91,EB,BD,C5,79,4D,A5,EB,5D,3B,48,9F,24,97,5D,54,4D,DA,17,8B,BD,B9,68,4E,5C,A8,2F,6B,49,88,E1,4D,3B,B8,E8,21,9E,87,0E,35,FA,13,D0,E9,53,42,69,0B,6A,48,9D,CB,8F,7E,72,21,04,5B,80,C5,9E,22,77,36,D4,20,C6,80,D8,BA,C0,6E,D2,6A,13,25,20,0F,8F,29,AF,9C,7D,48,91,B3,62,75,A8,6C,F0,21,FE,1D,7F,EF,CD,3F,A7,40,CF,6F,C9,12,31,28,99,2E,50,B0,44,5A,8F,03,2C,19,18,6B,16,C4,B8,40,21,10,6F,F1,C2,3A,64,E3,39,91,9E,DF,6B,40,C1,77,FE,EB,E8,03,DA,1E,70,F3,7B,C4,A1,FC,E1,53,9D,18,D6,80,FE,50,2B,8B,EC,71,2B,D1,31,17,D3,6B,6A,0E,77,F1,5E,FB,C3,32,0C,3C,C9,84,1B,D0,BD,52,99,B9,B6,F0,35,03,5A,29,0F,BD,58,F3,EF,11,C4,68,B6,A7,62,CE,13,15,60,FB,7E,BA,93,F9,0F,62,E3,F4,28,FF,F9,FC,27,9D,2B,A7,CE,C4,E4,FC,F4,39,1E,4E,E4,E0,24,19,F9,90,A3,B0,87,7E,4C,5B,40,A6,0C,61,27,EE,6A,E9,9E,B6,9B,3A,E7,9E,42,C2,56,8F,57,91,17,5D,B2,98,6C,96,0B,E7,56,3D,97,57,CB,9D,3D,02,39,8F,62,58,79,BF,91,9B,13,F2,93,3A,4F,85,60,1A,86,E0,D1,4D,6B,16,4A,2A,6A,47,26,DA,FA,7E,6B,54,34,A9,4E,F9,94,21,A1,AA,99,8F,E8,36,48,00,E9,EF,C5,D8,A7,D3,AB,5C,C9,96,AF,4A,D6,BD,14,6B,43,BE,C3,A9,60,B2,32,84,F2,E0,C5,49,C9,1A,1C,A5,8F,DD,E2,96,C1,1A,AC,4A,BF,D2,64,4F,B6,47,61,1C,A7,D9,04,31,99,56,68,5F,8A,77,30,3F,85,97,20,41,8B,BF,0A,30,61,44,0E,44,EF,AF,D8,4C,6C,CB,CE,4D,15,86,4E,03,02,46,57,71,F8,9A,DA,3C,28,10,41,85,D4,3E,87,46,A9,00,CB,7B,6E,61,F9,DD,40,27,B9,FB,48,6F,39,D4,CA,2B,35,AD,41,0A,AC,96,1B,31,1B,96,8C,1A,DC,A3,78,67,95,84,1E,73,BC,A1,5D,D8,BD,08,BA,2E,1E,06,3B,47,C5,B1,8B,7B,CB,77,55,C7,5E,B3,F8,FD,3B,C4,64,AA,BF,D8,69,C4,38,87,0C,79,71,0C,C5,35,CF,0F,E8,0F,93,B6,1E,E4,59,5F,C6,1A,8F,C8,44,89,8E,AD,5E,45,4A,96,19,C3,4E,A0,40,B1,3C,00,E5,A8,E7,A1,16,64,7B,87,14,35,08,F9,10,DA,3B,E7,20,AF,C4,9D,DA,5C,7F,FA,4B,B2,9C,22,E3,15,BE,83,4E,E4,14,51,34,FA,8D,A6,E6,B4,48,C7,54,67,F4,0A,68,07,0C,B4,13,CC,74,D4,76,35,B3,E7,9F,42,46,9C,AF,7A,36,97,4C,94,5C,64,F5,D5,7B,39,57,0E,E0,B3,78,0B,ED,8A,B5,A9,0A,9B,BC,FD,27,A5,2A,96,40,CC,CC,81,62,38,2D,61,5C,2B,0C,DC,1C,AE,11,4B,AC,87,1A,CE,9A,EF,83,6D,84,3D,90,B7,C0,24,C0,1F,6C,CE,2A,EC,44,1A,72,FF,E3,05,D8,49,5C,C7,0E,3D,25,E8,8A,5D,DA,89,6E,47,92,E2,C6,C3,3A,AD,74,68,E0,1E,8C,5E,57,6A,7D,8B,B9,E6,07,55,B9,46,01,10,71,24,A7,4A,C4,19,13,2E,D4,41,DE,59,C9,A4,A5,27,5E,0C,DE,83,27,32,2C,BC,92,06,39,5C,42,9D,B6,2A,5D,CC,D3,B6,C5,C6,21,46,BA,9D,AB,83,D5,A4,15,AE,C4,0F,53,B0,B0,A5,0F,8F,6A,58,4A,99,58,2C,E7,AF,4C,76,40,C4,2D,8A,C3,F8,6E,8D,EB,D0,AC,E7,A1,52,48,06,D0,9E,D5,04,B7,57,70,B0,2F,DC,FC,0D,B0,14,80,94,9F,D4,50,38,3C,9A,99,88,CB,69,F3,3D,5A,16,AF,92,19,27,37,14,4E,BA,9A,F3,D3,C4,2E,59,2E,CA,52,87,E1,20,F1,3B,CA,F5,67,6A,C7,D4,A4,9B,4B,BF,15,57,D0,96,76,A0,BB,A8,BD,13,41,0B,3D,58,3C,3F,DB,DE,CA,95,60,5F,D2,C2,13,45,E1,E2,21,B6,29,14,F6,7C,45,F8,65,CA,FB,A4,CA,5A,A6,27,60,9E,33,21,5F,54,5D,97,0D,5E,C0,87,10,27,EC,D5,2C,71,8C,BC,5D,A2,0A,F2,E0,C0,BF,11,74,0C,7D,43,2F,81,CD,3E,85,D3,B1,7D,DA,40,5B,C4,02,AB,3C,5E,A9,20,A1,60,B7,65,68,83,E4,02,B2,D8,66,7B,F7,1F,EE,2E,F4,C1,BE,9F,F9,57,1D,78,4B,5A,B1,DF,E3,2B,13,4A,0A,ED,9B,0B,B8,DD,5D,52,1F,37,BA,39,7A,60,7F,52,DB,02,DF,95,43,A5,36,3D,F2,B5,BA,DA,72,E7,24,3D,4A,34,4B,E9,A5,3C,5C,5B,35,4D,24,80,0A,45,0D,BC,6F,D5,EB,2E,67,6B,2D,3E,67,5D,0E,00,26,A4,51,1A,C4,93,C1,B8,BC,14,B3,DB,CB,25,45,37,EA,4B,D8,B8,E2,AF,4B,00,A2,95,F7,55,B7,00,C3,6F,D8,40,AA,9A,39,22,59,58,5E,5C,61,DC,5B,7F,D4,BA,18,94,88,AB,B9,A6,A7,62,09,57,48,6D,74,2B,87,0D,15,D6,11,EB,72,3B,D0,C8,5E,12,02,60,A4,E9,27,83,0A,C9,1D,E3,36,D4,E3,74,57,D6,91,FA,EE,79,4A,EC,0A,43,87,37,2D,8F,41,FD,94,E8,86,2C,E5,42,77,22,BA,45,08,25,A5,DA,8A,BE,BD,E3,BA,76,2E,76,BE,A6,33,93,2B,50,7F,A2,30,42,5D,93,41,87,1F,4B,CD,CA,06,C4,9F,27,86,FC,16,A8,6B,E2,EE,99,6D,2D,8B,0B,71,61,95,9B,FA,02,DA,91,1C,0D,40,9A,94,6E,75,FD,70,3C,F5,A4,A9,0E,53,53,ED,57,92,A8,21,BF,13,01,B0,3C,8F,BA,5A,E7,A2,B6,29,D5,5C,97,F2,15,FF,4F,11,09,4F,AB,CF,56,4D,C7,60,3F,E2,05,F1,6D,0E,90,0A,9F,4D,39,0D,BF,FA,7D,30,31,E5,51,0E,56,36,55,7B,97,E5,52,B9,03,B2,FC,4B,7E,08,B1,48,A6,AF,B7,E6,51,EE,26,79,55,70,86,93,EE,22,50,25,99,7A,EE,F7,3E,A2,C3,A8,CA,9F,FC,D6,87,67,60,A1,0C,7F,D3,5A,6A,38,EE,BC,11,61,46,07,DF,BE,F5,60,4C,CE,78,04,66,24,96,33,87,09,B3,A0,D3,25,BD,25,E3,AF,EA,AA,0C,C5,AF,EE,DE,0B,7E,45,27,06,66,50,C3,92,D4,A4,67,57,72,05,4B,E4,5E,61,52,89,55,39,19,B6,E9,54,2E,A2,C2,C9,3D,5A,D3,F5,F6,20,24,07,C4,A8,A2,58,F0,76,7F,35,53,16,17,ED,90,D9,C0,E8,B3,D2,28,A0,73,75,2E,33,1E,EC,31,55,3D,4F,3B,6C,DD,E2,EE,7A,BC,9B,E6,29,FD,00,5A,A8,C3,7C,9F,F5,57,63,28,92,75,C5,8E,E2,DA,E9,04,B5,04,68,22,7D,BE,F0,7B,78,60,6D,70,59,A2,17,F6,42,28,4C,0B,77,00,52,10,63,FB,C4,1A,6B,62,C8,AD,81,C9,E5,F5,79,0A,5E,73,4A,F7,66,66,43,FF,9C,D6,A0,35,F7,E7,E2,F8,6A,F0,65,1D,9E,95,FA,3F,1B,8B,24,FF,60,78,03,1D,E0,CC,58,27,25,BE,A8,AC,DD,E0,5F,AD,1B,12,65,CC,14,9C,C7,1D,81,E1,BD,A9,88,50,B3,5C,64,FE,26,15,AE,46,FE,55,89,C4,0B,FE,9C,A9,B8,A8,19,BF,7F,A3,F2,1D,F3,66,12,5E,15,E9,89,91,56,6A,12,60,8E,61,BB,46,A5,7D,47,71,B9,61,45,53,88,9B,D7,92,F8,D6,24,BB,B0,9B,A5,CE,6B,E9,3E,C5,16,E5,3F,42,45,A7,FC,37,83,63,7F,CF,CF,DB,88,1C,90,13,E6,CB,0D,4D,B5,91,71,B8,9F,AD,6E,68,45,CE,9E,5E,4B,35,9D,E8,D6,32,8F,1F,39,70,AC,47,78,C7,1B,E0,3B,7A,F7,2A,F7,AB,B2,3B,57,4B,14,A7,DF,A2,3B,B9,1E,53,42,B5,BA,83,4A,37,16,5D,C7,F9,E0,37,F1,E5,60,02,B2,AF,D2,82,10,82,1C,01,89,74,35,84,92,F3,E3,05,26,D6,B3,F1,86,44,07,04,B8,5B,FD,A5,C0,ED,CB,1E,47,9C,E5,70,A2,05,68,6E,54,C5,85,2C,A5,EF,14,A2,F9,5C,19,CA,F5,97,B6,C2,F1,81,0C,DC,9B,2A,2B,43,2F,44,A4,44,39,E6,F5,1B,B9,12,C0,01,07,59,A0,93,C5,04,C1,99,DD,CE,5C,2B,1F,72,4B,10,C1,16,8B,F6,A0,8C,A9,A6,22,6D,B0,22,98,05,DD,40,94,B0,71,44,1C,EE,F4,BA,C3,4C,73,3B,D7,C2,1F,9A,73,3B,58,60,20,47,06,18,07,95,E2,FB,9A,42,62,ED,33,B5,14,9E,40,86,C5,76,77,85,00,6D,DC,B8,F3,76,D1,3A,5B,59,66,9F,A1,D3,72,01,28,37,CB,C1,81,4C,B7,05,29,F2,28,DC,D8,8B,34,27,06,E5,58,80,B3,B8,DA,CB,12,2D,EC,9A,4D,26,42,F4,ED,47,59,50,8D,E5,41,C1,09,17,9D,21,3F,33,D4,58,C1,26,84,AD,10,8D,26,9C,BB,78,0B,69,8F,61,DF,3A,3F,3A,E9,91,97,AD,88,80,50,E7,08,0B,D3,A2,EF,8D,15,6A,CA,64,0E,25,5C,D4,B7,CA,7E,F6,D9,E8,C3,77,34,4F,B7,F8,AD,0E,CD,81,E5,41,13,95,0F,77,2E,60,51,0C,39,6D,B4,A3,FC,25,2A,15,E1,0E,0C,0F,E3,11,24,6E,72,44,60,45,2F,25,84,43,05,2A,7D,51,FD,03,11,F5,3E,08,B7,7C,11,B5,C1,C9,0D,44,B8,78,95,9C,43,DB,B1,F9,4B,D0,DD,3B,B1,59,A7,9D,03,6C,D0,B8,23,06,30,70,91,24,46,8D,34,65,73,51,E0,21,BE,CA,C1,5F,BF,3D,25,2C,91,1F,A0,1F,1C,BC,FB,49,AE,B0,A9,6F,B2,C5,BE,1D,FB,BD,15,3B,E7,BD,26,DF,A5,EC,D3,F8,F7,41,14,BB,3E,77,05,1A,02,EA,DD,DC,D9,91,F5,6E,BB,DD,6F,8E,4E,1C,8B,BF,13,78,EC,80,DD,87,D2,9D,C6,2E,EE,BA,A5,5E,63,FA,3F,01,9A,30,E3,86,EF,89,EF,A6,10,4F,4A,97,1E,37,C8,18,2B,54,BD,D6,2A,C9,B8,8A,FF,E0,88,42,2D,46,98,A2,C9,B1,5E,07,8F,AB,E6,5D,E0,EB,DD,6F,CE,91,2A,6D,57,5F,27,FE,09,C0,B0,C3,50,F1,0E,45,AB,D9,79,80,D7,DA,3D,DC,3E,08,6C,69,66,57,D1,26,70,5D,3D,14,D8,22,FE,6B,1A,37,D7,DE,37,70,D1,D1,FC,5D,79,98,54,FF,57,2A,AE,03,D2,07,79,F8,45,F3,16,DE,25,48,88,D6,12,FA,46,B7,B2,8C,36,CA,82,33,5B,EA,A2,D8,AF,6D,0C,71,37,8E,4A,E6,51,9E,7E,62,37,A9,34,D9,E3,FC,56,13,BE,1D,DF,4E,84,13,0F,DB,A1,78,E1,AD,C3,84,3E,69,1E,59,6D,92,1E,61,97,2E,F4,7B,15,A0,11,58,BD,20,FB,65,56,1B,DE,D5,07,71,83,7F,79,E4,58,08,AB,28,07,13,0D,4A,88,23,C0,AE,EB,24,9C,A9,51,F9,8A,B5,A0,FE,33,4E,11,E2,F0,78,A8,06,DD,B4,92,E7,37,99,CD,C8,23,5F,6B,17,73,12,8C,AE,03,F7,28,A5,0D,2A,FE,E7,B8,E5,46,89,27,12,9F,B6,E0,18,70,CA,2B,66,E1,A3,0A,2B,1B,51,D4,15,37,86,48,F5,FE,95,7C,41,72,0B,13,72,5F,D5,68,E7,8F,EC,C0,1E,9E,F2,16,5B,9B,C8,A9,35,64,82,EE,67,A8,9F,0A,3B,63,B2,8B,3B,02,3B,09,14,AF,21,FA,6D,BF,62,6F,89,A0,68,74,7D,9C,F8,5D,80,23,69,6D,D5,E6,9F,0C,5D,EC,1F,F9,1C,8A,E5,7C,49,D2,39,3D,7A,9E,7B,F6,FA,C7,F2,3F,10,C0,C0,D6,E1,83,E7,A8,01,89,27,B5,C8,65,01,2C,E4,A0,16,93,31,7A,C2,DB,CB,26,5A,A0,96,AA,2E,58,D7,B9,AF,8C,54,81,90,B5,54,05,1D,FF,CA,34,DD,5C,05,55,76,2F,FB,35,6C,1E,F8,6C,49,B3,A5,35,A7,EB,18,47,FC,73,5A,F1,C2,97,F5,30,31,CE,EE,44,17,BF,46,65,AB,49,45,E5,52,A0,8A,E5,DF,FB,2C,60,0D,BD,4B,EC,B0,62,30,01,27,1A,DE,39,55,E0,01,85,F9,CB,E8,C0,43,92,B3,51,0D,E7,B5,A6,A3,A1,B2,A3,C0,7F,6B,D6,CD,B2,6F,A3,6A,70,23,08,04,C1,D5,2C,C1,AC,FC,16,B6,02,F2,7F,33,89,F9,1D,D3,DA,7F,3C,59,64,30,BA,12,DD,97,A6,4A,98,52,A2,EE,A4,75,C2,0D,44,17,1F,84,81,DB,DC,8E,0E,4F,44,9E,C5,BE,89,75,C4,FB,D7,73,E4,5F,83,F0,72,5B,A8,BB,30,E9,A2,67,3D,E7,17,06,2F,C2,F9,4A,CE,65,D4,A4,AE,32,95,C5,EA,87,3F,A3,BA,30,F2,CE,46,59,66,F7,98,1F,46,28,A1,D5,26,80,4D,94,4A,A9,49,80,6A,1C,92,69,EB,6D,A9,25,E0,9C,88,DF,8D,C9,56,A7,42,C0,58,6D,07,12,28,D3,84,EC,1E,23,36,C2,16,68,20,44,1F,13,8F,60,6F,55,6B,5E,E0,E2,93,0B,78,38,28,9C,D1,C5,A0,F1,1C,1F,8C,7D,2A,95,A4,66,C3,48,F8,D2,AA,1A,F2,FB,6F,98,FF,85,A7,85,A9,60,FA,EA,0B,7A,55,A4,99,A6,C6,41,EC,63,FB,A3,62,E6,A7,8A,83,E8,CD,85,A7,F8,99,8F,B3,65,F0,CA,D7,C9,7A,F8,61,8D,95,19,A0,78,10,1C,62,54,98,FE,B3,D0,B1,39,C9,92,C4,20,01,0A,89,1D,CD,E1,4D,6E,44,B3,13,74,6F,13,30,DE,D2,94,89,C1,FC,3B,29,5E,8C,E2,75,35,71,F7,EB,AF,67,9C,B4,28,E9,76,DD,5F,C4,5C,A1,B8,05,BD,F6,69,CB,57,B8,21,A0,92,7B,65,D1,09,DC,2B,F5,6B,53,58,C5,3A,58,9F,7E,A6,26,FE,A1,CD,E2,00,26,C7,1B,F5,33,F5,69,D0,61,06,03,C5,27,73,72,B4,5E,F2,17,F7,BD,7D,5A,6F,59,56,C4,CE,6F,45,B4,B1,8F,8F,76,52,D4,29,A2,B4,F3,2A,DE,C5,10,47,94,F7,F8,CA,11,79,E7,4C,21,20,12,B5,EE,6A,3A,C2,6B,2D,05,36,73,85,B2,8C,42,E8,D1,5E,DC,53,06,D6,12,C6,26,7F,87,CF,EC,8A,0E,98,51,A8,98,E7,17,A4,DE,7A,FF,78,D6,20,67,26,2F,B6,8A,96,0E,34,31,D9,6D,C1,31,75,2E,E6,B9,5E,9B,14,B0,75,EA,B7,10,1E,8F,57,B6,37,70,BC,7C,16,1E,79,F0,8F,0B,DC,91,B3,38,6A,B7,B0,61,C2,18,5C,D7,75,E6,8E,CA,1A,DB,70,7C,5B,2E,7D,1E,CD,6A,7F,CD,E9,6A,43,B2,05,17,69,A7,AC,B9,F9,59,45,5A,FA,27,B4,14,8B,E1,FC,19,D3,A5,4C,53,AD,32,35,02,7B,1C,47,1D,02,16,48,56,15,24,AE,7F,F0,27,37,2C,10,AD,78,A2,BC,3E,FE,20,8C,C9,97,43,8B,0C,DA,90,4B,91,7C,E9,9D,0C,36,23,94,55,12,EB,C0,2D,83,46,31,6E,3C,62,39,79,39,A8,D9,6B,54,75,2E,94,66,AC,3A,0E,1F,54,53,77,37,F6,1A,08,4C,F6,37,19,8A,F2,98,F9,18,B6,40,1E,23,ED,C1,33,08,4D,B1,97,0A,A8,6E,B8,39,ED,25,8E,38,7A,69,89,BE,B6,31,A8,F1,19,80,A1,99,6F,69,B6,3E,CA,C5,07,93,EB,7D,7A,CC,23,68,D1,E2,40,86,5E,7E,1E,CA,B6,38,D4,77,BB,CC,D7,BA,2F,93,6E,58,B7,89,AA,74,1F,BF,83,EE,A7,43,24,E7,2A,F9,AC,EC,D8,AD,E8,B5,50,48,9C,A8,D8,F6,B4,9E,10,D2,B8,74,D1,CB,3B,92,A7,D0,A7,29,7E,A2,E7,D9,D0,C5,C7,AE,B0,83,28,03,74,6F,15,5B,88,C1,4A,9D,2C,44,26,9C,ED,F0,1B,E5,7B,7B,09,38,A5,2A,0B,C0,97,41,E8,FA,B2,40,49,91,6A,34,DD,9D,1B,93,B5,32,44,77,7D,63,7D,70,1E,43,5B,8D,2E,AD,8F,B4,6A,82,1E,FC,85,45,0E,6D,41,85,43,61,12,52,68,2B,EB,C2,C1,5B,AB,37,0E,38,A0,36,B4,F8,6F,ED,03,1A,4B,87,0D,4D,B4,A1,1C,26,DD,6F,5B,89,CD,54,71,12,08,ED,02,EA,AB,92,77,65,8B,EA,B3,DA,4A,1D,F1,1C,A0,03,5B,52,97,F7,48,DF,23,6C,6D,48,55,EE,E3,B9,4A,2F,17,79,8B,88,D6,F4,FD,FE,44,B5,E4,EC,55,57,4F,DF,2A,4A,9F,D4,A5,36,9D,9B,F8,25,A3,B4,0E,D0,5F,01,88,EA,A3,08,83,A4,CE,17,95,4C,D7,D0,67,37,74,02,02,B9,29,A3,EA,1A,93,42,29,2B,22,6C,C9,A0,4B,80,4B,4A,B5,2A,D5,85,8A,7E,20,33,97,A9,E0,92,DB,64,4A,0B,10,13,02,5F,7B,5A,3E,F5,36,C7,B0,D5,C4,64,AB,5F,40,BC,97,87,78,69,A0,45,05,E3,84,AE,41,32,01,E8,B2,D2,E1,28,C6,EE,AE,E3,B8,72,D4,92,9B,59,43,03,ED,E7,2D,46,AC,66,2D,F7,B9,C8,C7,AA,FC,46,B2,D8,DA,86,D5,D4,20,52,36,0D,67,D0,E8,2E,AA,65,03,F4,7D,0D,A5,89,28,F3,D0,20,F6,29,B7,7D,87,07,D4,BC,74,6F,46,69,7D,49,D4,86,C9,62,49,C3,EA,BA,85,AA,97,72,66,BB,B5,FA,0F,65,AC,CE,11,CF,26,29,F1,3D,02,5D,58,5A,2E,6C,01,77,78,00,89,F7,EE,02,F5,53,56,B4,F0,01,CD,4A,8D,67,29,F8,71,19,80,7B,90,4B,C1,9F,AF,CF,6A,9B,22,B9,07,1E,FB,F7,D7,87,63,12,17,54,E3,56,25,4D,B4,9E,AA,6D,90,0C,F5,AF,28,65,81,F0,C8,4F,EE,AF,29,91,5A,E0,30,8F,68,A5,2F,20,FA,5D,C8,B4,DF,42,0F,EB,74,60,E1,85,E4,6A,29,42,D3,EE,D5,FB,F4,87,EF,E6,57,57,0E,F8,0E,45,AB,3B,9B,F0,4D,78,27,97,6E,5F,F8,4E,CF,9D,33,BB,BF,3C,C8,87,AF,9B,17,22,16,FD,81,B1,18,BA,48,94,DE,3F,3A,2C,77,09,5B,46,DE,37,A0,81,D4,29,9D,D0,D8,27,AF,DA,D1,D4,2D,B0,58,D0,3D,79,CD,A6,D5,D3,49,9B,62,03,47,BD,DE,74,45,A0,4B,8A,7F,00,1C,C1,85,B1,53,BE,41,B6,5F,89,09,2B,4F,0B,7C,E8,57,4F,20,A2,41,42,8B,AC,76,09,C4,E6,52,F0,C0,26,7E,DE,D7,85,2B,34,DF,54,08,56,9A,C4,19,1E,E2,D9,9B,3A,E3,0D,88,D1,D7,34,B3,8F,C2,81,71,51,EF,AF,A8,DA,69,B3,A3,85,EF,76,4C,20,75,0A,AE,C1,C7,C3,90,23,86,7B,4A,37,12,4F,65,0E,B9,BA,E0,7E,8E,68,D5,88,A1,D0,E2,C6,DF,E3,01,B4,9C,68,6B,57,62,9E,18,A2,C9,58,97,A2,C6,5D,1F,F4,58,F0,85,BE,4D,C5,84,39,58,8D,15,9A,C6,79,0B,08,46,79,73,D9,59,0C,9C,8A,B0,76,12,D4,F3,90,95,D9,B3,56,48,4C,D2,2C,CE,01,20,AF,D6,C9,38,19,27,01,3B,D9,45,18,7C,03,64,C0,BB,06,13,CE,B9,13,56,C7,FB,62,1D,D2,19,F8,9A,DA,27,B9,62,63,A6,7F,61,C3,7F,E2,4C,36,C3,27,4D,2A,FF,63,86,8F,7A,D8,27,22,7D,61,87,35,D1,19,D8,21,25,DC,ED,57,61,08,65,3D,64,9C,EE,F5,A1,2B,C3,CD,0B,18,AD,D7,48,94,B1,6A,58,2E,69,34,D3,B8,B4,C7,7C,D4,6F,B3,E5,34,C7,8F,B2,72,E0,DB,FC,71,3C,70,EA,24,35,00,8C,B9,31,AF,1E,9B,5F,A5,47,C7,67,97,62,9E,F8,17,64,A0,44,C1,47,28,74,A4,99,16,0C,1E,74,11,1D,50,75,30,2C,87,0C,3E,46,F5,FA,FC,25,AD,00,FC,C2,5F,33,D4,C9,EE,AE,F5,AD,4E,81,3B,6E,3C,30,F2,FB,D0,45,AC,A7,CC,76,BA,FF,47,27,95,08,8E,D1,86,BD,1A,89,B7,81,C6,06,24,F6,42,2D,BA,70,83,CE,B9,1C,90,FD,4D,A4,7C,A0,AD,06,BE,B4,38,B7,1F,E7,43,D3,FA,2E,23,14,62,13,59,39,33,10,5C,28,38,25,A8,D8,65,94,9E,41,35,DB,48,34,09,5C,42,63,2C,E6,4D,43,BC,03,2D,3E,60,8F,26,9D,98,70,9A,ED,BF,54,B6,C8,E3,3D,13,A8,CB,B3,4B,63,7D,3E,AC,B5,BE,9F,9F,8B,64,E1,D5,BF,15,59,1E,86,FB,65,C8,77,E5,D3,EA,01,09,D8,B4,AE,43,9C,2F,51,B8,C3,9E,C1,D3,6F,AF,63,16,6E,12,06,8E,97,3A,E7,40,0A,0C,5D,24,D6,80,DF,E5,E9,60,7B,08,F2,FB,68,73,54,D0,19,1D,F1,EE,54,E7,74,25,36,E0,70,DF,F2,EC,E8,2B,25,B7,D6,26,4A,DA,AE,CC,D7,E5,48,2D,21,C2,1F,0E,23,99,11,06,7B,00,8C,0E,7B,35,68,4F,C7,AB,07,12,19,14,82,A3,FD,65,3E,AE,9F,D5,6A,17,28,46,1E,87,76,6F,FA,7E,FA,8A,07,A2,3C,42,EE,E4,8D,EE,DD,F7,8B,ED,D6,D0,8E,FE,2E,C2,61,AE,12,02,D5,81,EC,3C,32,79,C9,0C,96,7D,EF,CD,E9,E6,B3,67,63,AA,B8,8D,A9,AB,C9,92,E3,0A,17,42,80,02,AB,80,F7,5B,9D,DC,86,A0,F1,BF,38,6C,BF,94,70,1A,BD,12,56,52,3E,B6,CB,F6,07,A2,3C,9C,A6,A8,0E,26,04,0F,A3,06,1E,41,DA,CF,04,7B,B0,53,A1,EC,BF,30,E8,A7,AC,29,F4,C3,A8,A0,C0,58,79,20,19,2D,5E,43,BB,EB,EB,19,08,F5,6D,B2,14,1A,16,41,9E,5E,19,22,99,A7,14,26,D7,69,F3,FA,C0,8F,93,84,CD,37,31,A6,CE,3A,E5,87,AC,DB,DC,CB,BF,2D,89,94,9F,AC,57,CA,04,4B,A2,BE,AD,F4,FB,09,AA,D5,82,0F,06,DC,F6,21,73,20,45,77,29,06,32,25,0A,7C,EA,50,11,A9,66,EF,94,AF,D3,62,14,6B,14,6F,5A,B5,0F,F1,E4,7F,22,99,7A,55,F6,14,EE,56,8C,0D,17,EC,35,A9,0F,9A,83,83,E2,FE,E1,0E,52,7C,95,93,23,80,64,08,B1,FF,50,9F,E5,87,A6,4F,A6,41,7D,2C,0F,B3,1C,D5,27,37,25,38,31,56,F8,44,C5,CE,7F,CD,70,BC,8B,DD,62,6B,70,99,28,6A,3D,64,FF,C1,B1,F1,ED,E5,C9,D0,64,4F,4C,A0,1C,90,8B,78,E6,3F,73,17,10,3E,97,D3,B3,19,80,E6,B6,D2,4D,C7,AD,3D,CA,20,48,4A,77,51,6D,23,13,A3,9B,EC,64,F7,B2,C7,3B,B6,ED,2C,56,18,F8,FC,93,84,FA,FA,6C,08,F4,F3,D3,F2,B3,B4,21,09,2F,AD,38,A4,D0,E0,85,11,85,D7,DB,00,66,E6,1A,56,BE,0E,FD,A1,65,F8,9B,9A,65,2E,15,E4,60,33,A1,93,11,F6,FD,55,F6,F1,6F,E1,80,BE,62,5C,5B,6C,26,8D,73,D8,B6,96,74,E9,EC,E9,0B,79,C9,15,F3,6E,B8,54,AC,B6,E1,AE,21,E3,7C,3E,46,37,74,C9,A7,C1,17,4E,CB,FE,54,69,0E,16,6B,6C,2C,CA,89,EF,EB,08,28,85,3A,36,81,48,19,86,3A,F5,2D,E0,38,6A,20,81,52,D3,E8,DA,B2,8C,48,2D,54,67,7E,97,4D,FD,BD,67,B7,BE,41,F5,7D,65,13,30,D4,87,CC,B9,FB,17,B4,D1,BF,C1,E0,25,C9,0A,1A,DB,B3,3A,C1,7D,CD,79,74,F0,99,42,77,C7,0D,6E,23,85,F8,15,24,87,8C,FE,CB,A6,AE,6C,47,18,06,9A,66,6E,5E,45,8E,ED,78,C4,F3,03,58,6B,C1,F5,07,1E,8E,F6,E9,B1,7E,54,15,2C,11,F9,57,17,04,A4,BA,B1,EE,D0,61,D6,F3,DA,9C,82,A6,A4,35,85,10,44,B4,1B,43,8B,74,3E,6C,4E,D8,41,A0,C5,5A,0F,43,3D,64,2A,8D,9A,BB,6D,7C,B4,8C,8B,45,2B,95,3F,B4,0F,2B,4C,7C,5D,2C,61,66,F3,9D,46,F3,9C,BA,C8,8F,77,C0,E9,EC,D8,B1,A7,FE,3A,50,54,E3,EF,01,A7,FD,4E,5C,5B,04,A9,A9,56,83,40,33,4D,DA,BF,69,FB,B5,E6,07,3B,34,BC,84,EB,E1,DF,4C,27,40,2D,73,02,F9,58,C6,D8,65,18,1F,4B,58,0A,62,DD,8F,E7,A8,29,D0,1C,29,FC,FC,74,93,B6,4C,4B,B5,72,56,FC,5D,BE,81,E4,B2,6A,EB,1D,54,00,E8,29,46,54,B0,15,E4,CC,FF,7D,3C,8B,3B,50,18,97,F5,07,27,88,76,0F,B7,64,0D,3B,C3,AE,5E,BF,30,E7,E1,40,E1,D5,9C,5A,66,16,BE,82,AE,33,09,46,EC,4B,33,EA,17,32,FC,F6,56,79,3B,FA,CF,11,80,B3,71,C5,A1,72,68,27,05,67,36,26,C6,9B,79,B8,64,96,4A,9F,03,80,78,8E,AD,3D,23,70,16,B6,DF,15,8A,74,E6,D2,B1,98,7A,EA,DC,ED,94,0C,9E,AB,E9,EA,6F,12,00,0D,20,E1,C1,D1,83,47,0D,18,CD,E2,2A,8B,E8,99,8E,A2,ED,C2,1E,49,04,2A,5A,0A,E0,4E,64,47,81,A6,B2,18,0D,A8,AC,22,6E,08,29,C5,F4,2F,BF,96,7C,DA,57,6B,8A,FA,EC,14,A8,8E,A5,E7,15,FF,EE,BF,DB,25,7F,DA,95,1E,B2,F4,50,21,58,9F,86,48,BC,1E,A8,22,2B,39,F1,64,0D,1C,78,18,0A,0B,2E,A2,EA,C2,AE,9B,76,34,6D,31,E1,76,F7,6D,7D,46,43,B8,08,80,98,EB,F9,97,82,34,46,3D,85,AA,D3,4F,31,19,1F,01,4E,48,45,03,0F,D9,4D,B7,23,5B,97,0A,24,AA,57,8A,3D,7D,F2,1A,0A,BF,17,EF,0B,8A,75,C7,CB,5E,43,E8,5E,09,7A,32,AB,6D,0E,0C,27,30,9C,8F,2E,80,12,D2,5F,83,C1,5B,45,38,88,D1,1E,DF,9A,7A,89,F7,C8,0C,5A,3F,39,CA,D4,18,E2,82,61,EB,B3,06,AD,77,6A,F9,2B,0B,80,2E,BC,44,CF,2C,4E,18,4C,67,41,AA,91,6F,13,C3,C5,74,B8,E3,62,85,45,C0,DD,7D,F0,EB,EB,8B,49,7A,3B,5C,D1,89,74,DB,25,54,ED,68,40,EF,5F,6C,2A,8B,F6,B1,3D,FA,CC,5E,02,91,2E,F3,5E,22,29,5A,37,D1,53,69,95,E6,81,2F,06,95,FE,F3,57,99,64,2A,C0,E7,3E,30,F6,53,19,AF,86,86,3E,62,7D,A4,4F,D1,DE,A0,14,6F,B5,7A,34,8C,95,15,7C,A8,57,36,7D,24,29,71,5F,4B,74,FB,46,61,E7,E0,20,9F,9D,49,17,2E,88,8B,86,1E,63,45,71,6D,48,CB,3B,CF,BF,A7,73,A5,3A,4B,8A,02,5D,E9,1D,10,B4,85,B4,41,E6,8A,8B,31,4C,69,AE,44,79,60,AA,74,B1,5C,50,C6,C0,BB,51,39,75,D0,86,B9,FC,0D,8A,86,17,F5,E9,E0,71,61,7A,76,5C,ED,86,18,94,CD,48,8E,1A,91,77,4F,63,52,48,33,57,52,88,AC,3F,75,47,F3,A8,6E,48,93,60,C7,90,41,51,77,AF,C5,16,A9,60,89,8A,52,7C,F5,95,57,31,25,2E,73,66,EB,23,82,0F,1C,52,CD,61,7C,EC,DD,F0,91,9A,0E,35,CD,B2,2F,24,E7,8C,C0,9E,B3,BD,0F,B0,D4,B3,12,6C,9C,3B,45,0C,08,5C,FA,30,A4,BA,FC,38,53,CD,C1,56,2F,84,3C,EB,0E,59,DC,B7,3D,D6,E6,EB,81,7E,83,C0,41,DA,5C,AF,D3,CC,0F,E7,86,D5,FF,9D,68,DF,70,6B,AB,EE,D5,D6,B1,9C,11,35,48,F3,DF,F9,77,B4,3C,CB,9F,2F,A3,4E,F6,92,AC,D7,D8,27,17,AA,90,CD,DF,71,F3,80,9F,51,71,74,EE,01,51,4E,B7,B3,A2,99,7D,C4,66,91,7F,70,DC,DA,D3,ED,7D,A1,CC,13,D4,7D,12,4C,53,72,38,15,13,64,62,10,8E,D8,73,15,27,D9,30,C4,E0,E8,92,FC,10,01,0A,2B,16,E9,16,23,F5,E0,A9,FA,37,49,CD,AF,59,84,1A,EC,57,63,1A,A8,29,A4,E9,A6,F1,F1,61,D7,23,D5,51,E9,EB,7E,E6,68,2F,A5,5F,04,E0,5E,07,A8,4A,49,64,E7,2D,95,20,54,54,5C,60,E9,5F,A9,02,26,CF,AF,02,70,6C,5B,DC,3C,79,5B,FB,B8,5C,A2,B9,E8,D3,E3,42,E0,74,F3,CA,D8,4F,62,68,9F,2B,DF,E9,16,36,72,F0,D8,6C,B9,89,FE,A2,D9,44,A7,26,05,47,55,4E,60,1F,19,A2,E6,72,3B,0E,96,76,62,5B,14,8F,A4,81,E5,9F,56,85,93,D0,AC,E5,FC,D8,FC,FC,18,84,AF,CD,08,32,3F,B1,E7,99,C4,77,8D,57,BF,2C,AE,80,63,9E,11,C1,38,1A,04,C0,FC,24,B5,9A,BE,13,62,34,86,E5,C5,3D,9B,FE,F7,74,41,01,4E,B5,E8,01,88,5E,C0,A8,C8,84,8A,73,B3,5B,91,30,13,54,ED,B4,02,DF,8D,23,A4,25,F4,45,BE,4A,74,99,7C,FF,26,2C,93,BE,D8,BA,68,C7,9F,F8,C5,6C,08,2D,CF,44,FF,3A,CE,5B,D9,AD,EB,0F,46,76,67,42,A6,74,43,18,7E,FB,2E,1B,94,6D,47,0C,CF,57,D6,1B,3E,1F,E0,0F,86,F7,10,47,7D,46,34,B1,38,72,7A,E4,24,E2,99,DE,EE,E2,3C,EA,69,EB,5B,6B,6D,0B,79,10,1C,79,6A,FC,7D,D9,7F,2A,1C,A5,4D,6E,0F,9B,90,3D,26,5D,33,34,2A,DD,11,7A,17,56,6E,91,A3,88,5E,77,44,6E,0C,F7,A1,91,FA,49,F0,4C,51,FE,AE,74,B4,D9,44,8D,02,92,2F,F8,DB,A2,A0,99,26,06,BF,31,69,A6,DF,66,7D,8A,85,31,8B,75,BC,27,F3,DC,9E,15,93,33,0C,F7,69,F3,30,CC,13,6B,51,47,A0,69,DA,A6,F0,27,4A,BD,09,1F,AB,1E,92,77,67,79,06,C0,E8,1F,A8,90,56,53,26,B3,A7,43,2A,A2,70,A6,A1,A0,42,22,F6,6C,EB,D9,10,00,96,2C,90,DD,08,3C,B5,DF,9A,5B,D0,AF,F3,F8,C9,EF,91,3D,D2,58,0B,6E,85,A5,C3,16,AF,CD,0A,6E,31,2E,9B,D3,2E,0D,5B,E2,F4,13,B2,23,A8,29,9D,E0,A9,20,45,18,5D,93,AC,A4,63,CC,A0,3F,65,EC,6F,B0,1E,E7,3F,8E,23,C0,E7,C0,E7,AE,0A,A2,66,CE,10,4C,5E,0C,84,E2,AC,2D,23,DF,56,EE,86,85,44,95,04,82,1E,98,10,10,E2,30,1C,E4,BB,3D,4B,BB,83,A8,DA,03,78,BB,67,DA,B3,2D,10,F5,8F,FD,21,F1,23,70,74,95,66,7B,4C,06,63,B1,48,8E,6F,D7,E1,A6,F5,A8,C8,D4,1E,25,14,70,05,F6,0C,8F,03,A9,18,A0,00,6C,11,29,D7,74,71,89,27,7A,1C,F4,0F,EA,63,61,DD,B0,E6,20,9D,33,2F,05,62,C5,3F,72,4C,3E,A6,A5,C6,80,9F,54,01,19,3D,26,17,75,CC,76,4A,B7,67,E9,BD,1C,A6,4C,96,30,DF,D4,EE,C8,35,FC,0D,76,18,0E,8E,D0,EA,D8,03,0F,74,C7,AC,8D,48,5E,9F,40,F5,2B,C6,2D,18,9B,5C,56,1C,7D,72,58,4A,2A,EC,2C,F6,61,C3,2C,7B,5B,61,5F,7E,B2,4C,3B,1E,FA,49,19,42,10,88,90,B5,79,67,5E,DE,22,CB,79,6D,7E,CA,49,CC,C3,12,00,DF,3E,A8,F3,FE,7F,78,74,70,C2,DF,F7,37,FA,E7,A4,28,EF,6A,92,C5,B6,41,EC,F0,1B,F4,4F,5B,03,6F,EE,51,AA,92,A9,BD,2F,CE,01,0F,DE,72,52,4D,E8,47,0E,66,E8,1C,0E,85,BC,26,11,4E,26,BE,C0,C2,8F,23,91,69,76,93,C9,C4,A4,C7,A7,BE,12,56,0D,E5,35,A0,6F,AD,97,3A,6F,C9,6F,A7,25,F9,A5,74,F2,37,86,BB,A0,74,20,25,2C,F3,C5,E7,90,DE,F4,DC,17,EA,AE,9A,03,31,0F,C0,03,CB,B3,DA,C5,3E,9E,42,F4,79,B7,55,92,29,DF,43,0F,8C,83,04,A7,8D,7D,03,F8,87,B2,2F,F7,59,18,BF,0E,98,46,E1,93,9B,21,6B,03,A3,BA,36,C6,B7,80,C3,8A,87,FA,B6,08,23,8D,BC,52,CE,44,73,23,F9,17,20,B7,C1,E2,D6,7D,64,2A,1F,68,3C,6F,D8,81,D4,AF,D7,61,D1,4C,57,60,FC,0A,D0,A1,A1,85,DE,76,5D,72,FE,D3,74,FF,29,F8,36,08,1A,EC,B4,A5,E7,4D,43,54,2A,74,A9,C1,7C,EB,E1,DA,9A,85,D7,61,BC,98,BF,B9,AA,1D,0D,D3,8F,27,53,27,4A,E6,58,A3,50,D0,DE,A4,C7,4C,BA,74,AD,28,AD,77,99,A2,20,4D,48,6B,A9,EA,B8,45,F7,12,B7,33,4E,C6,6B,CB,EA,FE,FC,22,70,76,47,C4,3D,BF,9B,94,2D,8D,64,D5,90,61,8F,7E,BB,A8,E6,73,71,7D,9C,8C,D7,F9,47,E1,DB,7D,D2,2B,0A,B7,24,32,8F,AB,33,E3,8C,3E,7D,A5,FF,BD,B6,99,58,B7,23,29,16,EB,D0,08,2C,66,08,99,1D,F3,86,74,C7,E7,1D,48,F8,54,1E,83,94,BA,15,6A,A1,74,26,D8,09,FA,17,0C,3E,4A,8C,46,92,85,CA,B7,40,92,0B,18,03,2A,5F,21,2B,C2,8E,A5,2F,1B,54,82,B6,0B,0C,4C,1F,BA,06,D4,27,7C,E2,1B,23,6D,07,81,1B,D4,0C,F6,BA,85,0D,A9,F1,71,15,FC,62,DB,13,52,FD,04,72,5B,FD,2B,D9,00,30,0C,C3,BF,D2,9A,FF,0D,FF,15,9F,50,59,D5,10,D5,67,F9,CD,7A,CA,B8,CA,D5,82,96,FE,74,07,7F,BD,C1,16,55,B2,CC,D4,09,06,17,16,3D,0F,C7,CB,70,EF,9B,33,E7,56,D9,82,F2,E4,DC,06,B6,77,64,C3,38,29,EB,D7,27,BD,EC,37,0D,71,03,09,58,72,54,FC,FF,6B,D5,C5,0F,B2,1C,8B,90,C1,A6,26,16,F4,1A,2A,A0,6C,DA,F5,55,1D,F3,E6,D7,B7,95,29,80,6D,CE,E0,B9,6D,29,A7,E8,1C,5A,7F,D4,9D,F4,75,8C,8B,47,00,AF,59,CA,DA,EB,0D,2E,18,15,69,1D,F3,62,C8,8B,8C,12,96,23,89,AC,2D,2A,EF,62,F5,A3,79,D5,11,1F,F1,08,46,CA,94,F7,55,3E,4D,26,03,35,DC,F4,9C,4F,15,EC,AA,D7,E0,F8,15,10,A0,E3,AF,F4,94,C5,8D,79,D5,8A,C1,17,49,47,4A,B7,3B,37,B9,C4,EA,A3,E2,43,E2,66,D1,E4,A2,AA,D4,C4,E1,92,C1,D9,08,63,71,C7,F1,2F,73,CB,42,FC,DC,10,6B,BA,71,D8,E2,96,29,98,09,8C,AF,0B,2E,87,40,28,A7,7E,50,C2,E5,C2,6F,9B,87,AE,0E,1C,DF,67,53,49,55,E8,A8,1B,04,08,BF,B0,5C,66,03,B6,AB,A3,B1,AE,39,1A,A7,68,67,FD,28,EC,8C,7E,6D,5C,17,C0,D3,5F,F7,F2,BD,8D,52,47,1D,EE,36,E8,12,A8,F5,F5,A2,68,21,A6,8E,AC,16,3F,E9,0C,9A,AA,C8,38,C4,77,E9,5C,A4,5B,E3,C4,53,B9,09,B5,88,30,C0,02,42,B5,8E,33,8E,B5,23,3A,F1,8A,D7,99,B4,0F,44,6D,3F,9B,67,D8,B8,F1,72,75,B6,23,3D,22,95,A9,D5,26,27,C5,57,90,AB,12,89,B5,62,70,60,5D,2E,66,40,88,96,DA,6B,8D,C5,97,B3,44,3C,CE,72,3B,C2,56,25,71,8E,86,FC,45,8B,65,65,01,8B,BE,19,4B,59,B0,B5,CC,D1,67,53,3A,2A,0B,DE,7A,DA,8A,A7,77,1D,FD,FD,BA,69,1B,2A,1E,E6,D1,03,F5,E2,F8,EC,EB,BE,D5,FB,A6,BD,F8,47,6E,B7,11,36,0E,2B,DD,33,2E,47,FC,51,C9,2B,27,AD,B5,4C,0A,36,D5,24,C4,C8,80,DE,81,CD,78,DE,A8,50,53,B2,42,9D,20,75,8C,8F,AF,EE,AF,14,6E,9A,6C,CF,BE,78,0C,70,F2,15,AC,AF,34,73,C4,ED,24,9C,88,91,35,7C,B6,3B,C5,4C,FA,EA,68,CC,34,86,AB,45,A8,FF,34,1D,64,BB,45,1B,E8,16,7B,78,8B,D7,EC,58,DF,47,D4,EB,3D,D4,18,DD,ED,BF,F8,74,C6,D9,4A,3E,E7,4B,64,F8,41,64,AA,C8,0A,DE,BC,06,43,39,25,6A,19,60,4B,4F,42,C6,DD,2C,8A,DF,8E,AE,68,6E,02,6A,5B,48,C9,A6,42,AF,4E,15,F8,B1,D8,EE,7C,0F,B7,E6,75,FB,C7,18,40,2C,09,E1,6C,F8,E0,83,22,26,36,8F,C4,14,C7,0C,4E,3D,CE,AC,56,FF,A7,E7,EB,AB,F5,65,40,11,AA,99,1E,A4,7F,75,00,C6,9C,42,32,53,A7,D0,18,63,89,7F,2F,12,E1,A0,AF,19,97,26,69,1A,89,89,27,9A,5E,72,4E,5C,D5,43,C7,3E,FB,B7,DF,36,B7,E3,28,2E,F5,64,97,7C,2D,54,69,0C,AE,C6,70,85,D2,5B,89,E5,63,44,58,6E,A5,9E,60,F3,11,97,F3,8D,12,EE,AC,BB,CA,2D,03,71,23,DB,79,E6,19,40,D7,CE,A3,80,76,CD,81,26,8C,DA,37,0F,2A,DF,F4,55,6D,EA,F4,B3,0F,6C,24,F3,E2,7E,83,C7,84,30,06,97,E6,01,27,34,DB,08,2D,EE,54,CD,7F,51,27,1A,7E,5F,92,90,B4,B2,0B,9C,2F,42,4E,0E,EA,B0,73,A6,89,DC,E6,CE,5E,7A,07,30,2F,75,CA,63,95,CC,53,D3,78,EC,CC,33,7E,35,5F,04,DD,A9,EF,87,23,AE,D8,BB,19,3C,A2,5F,A6,BF,4F,50,86,AF,31,E7,D7,E2,39,6B,2D,C9,5F,4A,B2,C5,A4,A0,E2,5A,F5,71,FA,7B,47,2A,F5,60,5B,B6,3F,5C,91,62,72,B0,64,93,40,48,44,B6,E2,B2,9C,E8,DA,42,5F,DF,8F,12,6E,8B,EF,EC,7B,8D,61,F5,91,E9,AB,5D,93,C4,AD,57,88,B8,56,29,74,8C,3B,1A,18,BB,81,D5,B4,6E,41,C7,D4,D8,C6,4B,91,01,6B,B2,DE,F0,D0,34,C9,62,34,26,B7,28,50,E7,BE,65,79,53,EE,14,3E,AD,69,03,DE,56,73,6D,C7,58,F5,8D,E7,D3,F1,C0,6E,A7,83,2E,3F,B7,7C,BD,6F,36,CB,98,5C,24,76,76,C6,57,0F,F4,22,D5,77,57,26,88,68,75,40,EB,7C,13,D4,D4,C2,EF,9F,74,32,2C,0D,90,B8,2A,2F,CE,00,3D,C0,9C,F8,AD,70,E4,8D,42,2D,EB,68,33,8C,E2,20,92,56,1D,8C,BF,06,54,CE,FA,18,A0,2F,3F,BF,07,AB,DE,64,3B,3F,3B,05,AA,3C,9A,B0,91,3E,FA,51,F1,1F,7C,C4,08,79,FA,11,16,D3,0B,B8,44,B8,B8,64,EA,95,4E,BE,5D,C9,B9,B8,7B,67,6C,35,29,51,A3,E8,47,C8,77,08,33,EA,AD,93,55,D0,D0,00,19,1A,AA,D7,AD,A3,2B,FE,C3,9E,0A,45,EC,3D,88,96,AA,5F,BF,D2,32,6E,3B,41,10,AA,43,85,57,B6,6D,3C,06,C3,84,B7,4F,5F,B8,13,8C,1F,4A,9A,D5,2D,E4,CC,13,EC,8A,EE,86,24,32,13,D0,DB,66,74,B7,8E,FA,42,5A,AD,8F,76,29,7D,15,90,4D,21,E2,02,44,3A,0C,51,BD,65,0F,E3,E9,3A,CD,9B,A5,77,4A,44,B9,B7,D6,D0,D6,BB,AA,F2,7E,3F,30,8A,8C,D9,D0,C6,71,25,8B,27,18,8B,46,7D,CE,3C,54,64,E0,DF,FD,44,F9,F2,F0,44,15,F0,84,FD,6C,46,B6,60,BB,D0,0E,C7,A4,D9,75,0B,A3,01,C7,BF,73,0C,D3,58,7C,30,05,96,4A,6B,41,9A,A6,DC,A0,70,7C,C4,43,73,B9,8D,1F,18,31,7C,B9,96,75,4D,72,23,EC,ED,67,86,FA,18,95,90,0A,BD,70,45,B0,A5,D9,29,E2,98,7D,73,2E,5E,25,DE,DD,E3,D9,E8,08,31,C5,F4,C1,B0,EC,7E,95,9F,9C,A7,03,CD,5E,95,50,3E,59,93,BE,6B,BD,4B,15,6D,22,FB,4F,B3,45,BB,06,F5,9C,A3,6A,F6,0A,AC,AC,F9,B3,44,01,EA,1C,B3,97,E5,4B,8F,B3,37,59,0C,41,53,C8,FA,48,EE,07,5D,53,E0,BF,F0,48,B3,FE,33,2B,83,16,03,B3,D3,D8,51,E0,A0,DC,74,4F,39,49,68,DD,A5,A0,6F,1F,93,39,DE,9A,77,AF,85,2D,B0,45,21,49,D4,79,77,31,6D,C7,04,E3,2A,0A,1D,F1,FD,7A,A8,35,2E,44,D2,7E,2E,89,21,F6,C9,2A,F8,22,53,CC,35,11,4B,6D,E1,FB,6B,F0,15,A7,A1,9A,9F,2A,59,17,A8,C5,09,EC,4B,2A,BD,C6,F5,9D,96,B1,0F,CA,E2,48,28,3C,35,32,C5,D7,8F,CE,A8,CC,9E,F6,D2,51,2C,F6,06,EC,E8,E6,26,8C,27,00,E5,6B,CC,B9,60,44,8B,0D,FD,9D,89,A6,20,E7,5F,77,66,10,CE,8C,BD,1C,DC,A0,81,62,2D,B9,7F,30,DC,FC,D9,6A,3B,59,41,B6,A9,F2,B1,C5,46,E2,3F,46,1A,4E,B2,C4,43,02,74,83,4E,6F,1B,5C,85,A4,D8,62,FB,88,AB,86,FA,7D,17,03,3F,E8,F9,5F,12,D2,D2,4E,12,04,98,D1,5C,A0,02,AE,D4,98,94,97,16,D7,A1,F3,1A,0B,D7,8E,AE,01,81,A3,33,A6,0B,AC,BF,4A,B6,E0,7E,01,0D,CE,EB,03,FF,21,98,DF,43,13,AC,59,4E,7C,58,B7,76,2B,F0,DE,9D,1C,20,2F,B4,05,41,43,50,E7,52,8C,7C,FB,03,B5,CF,AD,89,A2,C1,0B,88,37,21,95,31,D0,6D,A4,74,10,43,BF,2D,DC,1A,8F,1E,C7,9C,D8,0B,11,F9,FA,B1,67,DD,18,13,24,D0,C7,A6,BD,19,34,9F,10,2C,09,C3,B0,60,68,B8,26,8E,48,CF,E3,F0,F3,92,72,04,F8,8C,C4,54,E7,47,69,2A,88,28,11,FB,EF,20,5F,F3,68,8E,5F,04,10,9A,72,29,F9,B2,7C,F3,90,13,0D,B0,4A,BD,2D,17,C7,C1,3A,16,7F,B2,AA,F5,C0,2F,F3,91,F0,74,44,A7,65,94,10,C5,02,F3,18,D3,CC,21,DC,CE,F0,B0,C4,96,46,EE,D5,CE,5E,62,E0,08,5A,5D,21,09,0A,F6,E8,DD,E6,6C,E0,D7,7B,0A,93,9F,18,A0,C9,4F,84,C9,49,D1,5E,9E,DC,C8,5B,D5,B0,0A,F3,0B,55,34,C6,0C,27,8A,9E,22,47,F1,1E,D5,32,BE,2F,EE,71,03,BB,C5,69,04,F5,AB,03,D3,9C,B7,10,8A,F0,C0,55,72,36,23,3E,72,1F,E4,4C,5F,3B,03,26,CF,9F,BD,57,ED,2A,03,56,97,72,1B,7F,D0,6C,C2,99,B8,73,6E,D8,82,4C,0B,36,78,22,A5,DB,36,DA,95,A2,DF,50,12,83,71,05,0D,93,1A,5D,E3,FA,AB,55,99,9A,89,D9,26,52,FB,84,7F,36,67,DA,5B,A4,ED,FA,9D,7B,66,B1,D7,95,83,DB,22,0A,11,C1,7C,20,6F,61,07,C7,1E,20,10,A0,C9,ED,49,57,88,31,36,2E,4C,70,8E,A1,32,0E,59,B8,DA,E2,58,A3,AA,7F,BE,84,EE,8F,91,00,5A,03,D7,06,C3,FD,B6,F0,21,2B,5B,7B,57,28,02,9A,87,F7,E5,EB,16,DA,B3,1C,22,2B,D2,4A,F6,34,17,F0,DB,88,E5,7C,37,39,21,91,DE,7C,F3,54,4F,DF,89,E2,0D,21,F3,2D,A5,F4,C1,55,F8,FD,23,79,80,6A,42,08,03,2D,D1,48,7A,71,1A,37,89,08,A3,56,99,24,BB,B5,9A,F5,BE,4A,07,A5,ED,E6,D2,D6,47,0C,AF,65,4C,6C,A6,9E,41,6E,F6,B6,C3,32,6D,8A,D4,34,D3,F7,5A,DC,8F,3C,90,C5,71,B8,23,F0,C6,32,E7,F4,76,86,88,06,BC,D0,F5,C5,EB,8F,DA,CC,D2,EC,E7,E5,A9,5C,F5,7B,79,1F,F4,65,35,5D,54,99,69,88,3A,2A,A5,8C,3F,94,FD,37,7E,82,35,4F,9A,F1,DA,6D,84,4F,61,23,9B,18,FA,3B,3A,78,98,BC,80,3B,B8,79,44,1E,A6,B9,6F,B9,9D,70,6D,30,5E,D5,EC,E0,08,DE,F6,86,DA,5C,29,C1,72,BC,DC,A6,97,9F,2D,B5,84,48,7B,F8,1A,C9,96,E6,7F,22,54,FE,60,FE,BC,5F,1B,35,15,5A,B1,B5,8C,DF,CF,53,98,C4,54,20,44,E2,F8,65,A2,6A,AC,FF,C3,67,5D,CB,F4,F6,C3,1D,3A,E8,4A,5B,0F,5C,AB,D6,E6,EC,B6,55,93,18,44,8B,C5,4D,BA,55,9D,51,D7,8B,22,08,FC,F8,56,09,71,8C,0F,C3,D2,15,B2,B8,BC,5B,83,71,39,1D,11,10,CF,7F,9B,EA,0F,B0,77,86,2F,4C,99,FF,86,DB,74,EE,5A,37,8C,D4,86,7D,A0,16,08,17,83,04,B4,51,AF,76,CE,8E,53,12,1D,00,2C,9D,53,05,59,96,A0,20,C9,12,42,55,C1,3F,90,05,46,C4,28,84,1F,6D,E8,DA,B2,90,80,5C,D5,D4,AE,E7,48,9A,5C,37,C9,E8,46,FD,AF,22,F1,A0,92,1B,A7,07,F3,EC,A8,76,9E,A3,A9,22,A5,A8,34,09,F5,0F,EA,C2,24,9F,7A,B8,F3,AE,89,12,26,7D,09,06,C5,63,D6,01,13,35,35,6E,A1,5A,80,0E,35,5B,B6,E6,18,6E,E5,95,7A,9D,B6,D5,91,7E,54,5C,35,4C,8D,76,8A,0A,F9,3A,A1,4C,BD,8D,A3,82,2F,EB,7D,EE,BC,C2,8C,C5,5A,8E,04,13,38,97,25,CB,80,66,8C,DE,7A,6F,1A,4C,8F,7F,65,78,19,C5,A5,95,A7,DD,B1,9C,8B,54,91,42,6C,CE,EF,1C,EB,F0,51,22,05,76,5B,8E,D2,58,22,D9,AD,BD,53,B5,69,D8,52,BE,E0,5E,83,8D,23,C2,BD,15,60,63,05,C3,CB,92,22,73,EF,DE,6A,85,6B,AA,EA,DF,1D,5A,43,BD,97,C6,26,28,76,0A,58,19,6C,6F,30,C8,53,08,AF,2E,3F,8F,70,86,DF,42,55,1C,1A,3E,0C,0F,14,76,70,9D,4F,77,9A,14,11,0B,CA,42,12,DC,92,99,6A,0B,9B,77,E7,F6,41,52,D4,4F,4A,A7,B8,C4,2D,B4,23,E1,06,BE,57,1B,C4,2C,A0,2F,6E,0C,56,5B,4E,04,B0,B6,DA,8A,3B,97,2D,34,0F,E4,B6,80,32,A9,D8,F8,04,FA,48,C7,06,32,43,87,AD,BA,4A,A3,DB,CC,16,B5,B9,A6,C7,66,01,1B,30,68,CE,AC,2A,19,43,6C,13,63,64,0B,FF,1A,D8,3B,C3,BA,EE,79,52,68,6B,4A,F7,9F,44,A5,D3,61,E7,66,56,A9,F8,13,A9,3D,74,BD,13,85,4F,B5,DF,43,D1,58,43,50,24,4C,60,ED,5F,32,25,52,49,FE,76,24,24,A1,06,34,C7,BE,81,4C,62,6C,3E,01,0B,0D,7C,99,0A,7F,7A,2D,AF,51,2D,DA,26,4E,DE,F1,54,01,AF,23,EA,82,4F,1C,7C,06,3E,E6,11,A9,56,5E,A2,09,B1,DE,E4,0D,19,C2,AB,39,07,30,D5,FB,4A,8B,C5,CC,75,A0,BA,44,98,5B,50,5E,D0,3E,EE,96,7B,23,92,3E,49,F6,CB,B4,DE,31,1E,67,F2,CD,74,8B,D4,53,39,A6,A0,DF,6E,4F,62,F8,0A,CD,6F,EF,C4,8E,51,94,14,03,E5,0E,16,9A,BD,74,23,47,BC,7F,3E,E6,FB,97,4D,9B,D7,03,04,71,58,2F,82,66,F7,FC,F1,29,7B,EB,45,3B,9B,8C,6E,D9,1A,C8,A4,F3,D5,8F,DD,CB,76,2B,42,6A,2D,E9,17,91,EB,6B,99,F5,F9,BA,BC,2A,CC,FD,99,D8,D1,4A,29,60,40,73,6B,43,9B,B7,23,3C,AC,27,D5,C7,47,1B,19,4F,EE,C5,82,4F,08,CD,8F,03,A4,24,24,45,AC,CD,55,D9,75,0B,9C,C1,3C,DD,9C,C0,82,7A,52,8A,F7,78,0C,91,9E,99,BD,3F,60,FF,73,99,7C,17,06,20,C8,4A,D1,EA,FA,16,8C,02,98,DE,65,2B,DE,3D,33,8E,0D,32,48,47,E4,F5,B0,B9,80,ED,67,7A,B5,70,1C,E1,40,E8,31,E5,75,03,44,99,1C,26,0A,DD,CD,0F,EC,E2,DC,BB,0D,B4,83,71,43,8B,A5,45,5A,33,29,BA,CA,6F,5F,C3,82,E2,78,28,62,35,04,0E,E2,84,CF,34,58,F2,2B,7A,5D,5C,32,43,01,12,39,5B,7E,6F,58,D1,6D,BA,A3,3B,C4,50,EC,44,EC,51,41,26,EE,FE,20,95,2F,31,E1,B2,F2,F6,4F,F7,EC,56,E8,6D,08,21,6D,05,4E,69,3E,5D,A8,58,6A,E4,00,C7,65,23,3F,FF,92,D9,F2,3A,92,A4,9F,9B,87,7D,09,9F,70,43,F3,58,E2,5E,00,80,33,C3,00,7C,FC,6C,96,A6,DD,27,80,5F,02,6C,56,67,1C,6D,7B,73,D8,98,D9,2A,5C,B3,15,1F,3B,43,B9,39,36,65,16,6D,96,8B,B1,06,1A,CA,03,0D,33,2B,95,06,71,61,B9,83,63,91,4C,6D,6F,C8,9C,F0,14,E9,5A,C3,E2,37,5E,22,FF,38,19,BB,CC,79,26,EA,28,9F,E9,61,DE,E3,05,04,29,A3,78,2C,03,1C,44,3A,5D,0A,06,9F,AE,51,27,A1,5E,58,B7,61,F8,34,19,FA,10,11,A1,9F,78,96,85,08,4F,7F,14,59,42,6C,33,8F,BE,44,F5,F9,B8,18,79,D5,C3,33,57,1E,79,88,B5,10,D4,E1,02,B6,04,95,A2,8D,16,51,59,98,DF,28,40,28,38,AA,76,9E,34,B2,AA,11,38,1F,03,70,48,13,1C,C3,B4,98,3D,DF,65,AC,12,92,56,BB,A0,11,8A,7E,8D,CD,14,F7,2A,5C,66,C8,1E,7B,07,FA,92,C8,F4,51,A9,2E,99,AE,B2,96,05,CA,8B,08,46,07,A4,28,C0,8C,E6,57,23,17,D2,BA,AA,CD,08,6A,72,D7,7C,B1,F8,1F,32,78,93,72,6B,12,3C,F0,9D,AD,B1,C0,7B,2B,29,56,B1,38,40,AA,4C,CD,7F,F4,85,82,90,1B,30,53,A3,56,EE,13,B5,C5,14,93,01,1F,FA,69,16,40,E2,0E,A1,8D,CF,02,A7,97,DC,31,D0,65,7D,E1,FA,D0,E9,BE,D3,DB,7A,E0,2A,99,40,C7,9F,FE,32,A6,AA,4C,6D,60,A9,FA,8D,B8,94,42,FD,E0,A1,D4,26,14,A5,5A,D2,A6,DD,23,62,C2,F6,DB,10,8E,A5,36,63,36,2B,42,FA,ED,50,17,6C,0E,C9,25,63,75,29,73,6B,1F,52,06,07,ED,73,86,0F,9D,E5,78,68,A8,1C,A4,5D,60,D9,AB,F1,42,DF,E0,1B,2E,10,45,97,58,C1,1A,E4,84,9D,61,9B,ED,E0,75,36,2F,B7,99,A3,51,BE,30,F8,19,F7,86,00,33,95,F8,C6,E5,D7,DF,AF,3A,88,0C,BD,E6,CD,DF,33,1C,6E,0F,7D,09,CE,CB,60,CB,45,6F,E7,7D,03,23,FF,E9,B0,5B,67,F4,EB,A5,5F,55,EA,11,E1,52,A7,87,0D,34,AB,AB,31,9A,83,08,92,29,FA,37,C8,57,3D,9B,A7,80,56,4F,E5,AF,59,AC,DC,0F,C5,74,E9,67,20,F8,08,E7,81,05,7F,FA,6F,1B,C7,44,7E,C7,B1,85,62,F1,D7,E6,24,AC,CF,BA,D6,EE,D5,D9,0F,24,7E,C1,A7,EF,7C,0D,70,4C,B6,D0,47,F2,36,71,5C,5D,BE,72,A5,AB,61,29,F7,9C,CC,FA,EE,4E,A6,97,5A,9E,AA,31,8E,2F,AE,51,33,06,CA,91,3B,B4,93,36,C2,FB,2C,6E,6D,ED,C3,00,83,E5,2C,00,A2,85,3C,66,4E,31,53,30,7E,89,9D,A0,3C,1B,8A,E4,5A,DB,10,66,93,82,8C,33,13,4F,67,11,32,F6,57,9F,8B,D1,92,D4,9A,9F,DE,7A,76,B2,7C,1C,F2,2E,7E,6C,05,5A,2C,F1,00,33,60,FC,E7,7A,60,F6,09,2B,09,BA,20,F4,CB,B5,8E,BB,A9,80,22,C3,E3,DC,47,99,39,97,B7,B7,1D,F1,07,A9,C2,93,7A,7B,E1,D0,30,47,BF,0B,83,76,A9,52,FA,46,AF,FF,0E,EB,60,01,70,35,5C,F9,03,CE,F8,90,85,B4,EF,71,1B,A3,6D,EA,06,30,28,5B,E1,60,54,45,20,53,D0,5D,3B,A2,0B,18,1F,47,C5,19,92,B6,1D,16,07,CC,D2,8D,5A,75,25,98,A0,D1,5B,F6,E2,2A,FB,56,03,16,D4,00,0F,C5,07,44,C5,47,31,D8,2D,85,59,21,96,16,FE,4B,F5,67,04,8E,7A,D0,4B,11,39,02,81,B5,39,21,D1,75,D5,19,CE,91,00,3E,60,37,83,F9,FF,D7,A0,AF,3F,A7,8E,00,76,9B,65,DA,DE,57,03,5F,42,91,32,AA,6D,8D,DD,8F,22,EE,CA,22,8A,3D,28,88,F8,50,F9,13,15,D8,3F,B7,62,B5,C6,31,49,15,18,15,33,3B,6B,34,1A,06,31,D5,3F,A1,19,66,F8,42,8E,3A,1B,85,B0,51,14,C7,DF,E4,C7,E6,BA,08,46,E6,7C,56,A8,3F,E9,43,C9,7A,7D,6D,09,22,03,81,23,01,B6,70,DD,86,A0,41,4B,E4,FA,2C,57,CD,2B,A8,85,89,E8,33,36,0E,2C,5C,62,7E,7C,E5,09,B9,62,78,2B,A7,C8,2F,DE,D0,E5,CE,A9,80,52,BA,63,AF,AC,3F,78,70,8F,27,8E,34,E2,A3,92,90,6C,51,FC,68,04,55,82,AC,32,AA,73,B5,60,7C,58,18,0B,EA,37,ED,2B,16,DE,F0,4C,74,9A,85,1E,D8,A7,94,D8,74,2E,DF,BE,B6,B7,5F,3B,C6,59,04,D5,4F,18,E8,46,C7,6D,32,CA,0C,3F,9A,42,61,F8,D8,34,F3,01,04,51,B4,D4,70,90,27,02,ED,FB,81,07,6A,6C,99,D8,7C,A1,45,D9,D4,3F,3F,99,E2,11,FF,4F,98,C5,A6,38,81,0D,95,FB,4D,3F,A7,9A,59,D2,4D,FE,82,8F,15,46,7F,CB,C4,40,DE,AB,63,8E,5C,50,4A,98,0C,F0,C7,A9,1D,7D,F6,51,31,01,68,4D,83,76,73,79,FE,AB,FF,65,1E,95,26,E8,DC,04,DA,8C,AD,A6,5B,CF,3D,97,28,2E,AF,19,22,8A,00,7F,D2,3A,41,62,84,6C,F3,4C,BF,67,7A,74,BF,12,88,CA,D6,7D,99,FD,B3,B9,84,A8,1F,B9,7B,A9,43,AF,45,A2,7E,52,FD,39,6A,2F,62,46,B3,66,2D,48,6E,D0,C5,DE,0B,8E,7A,71,16,4B,D2,36,D0,A6,63,85,95,CC,41,F9,99,67,B9,28,4F,EF,48,81,E6,5D,8A,86,58,C0,4C,DD,78,F1,29,B6,83,56,D4,F6,B2,63,5B,76,6D,BB,99,EF,5F,B7,24,BD,B8,0D,31,89,CE,77,9F,CF,3D,75,88,00,9C,48,AE,9C,7F,F8,C5,A5,5B,19,5E,EB,F5,1D,16,2D,5F,A6,82,E4,19,F3,F2,CD,4D,45,44,57,D1,77,80,7D,6E,AE,88,BA,6D,62,59,59,C5,D7,1E,24,B8,44,0A,26,00,3C,0A,C2,55,B3,C6,3D,F7,E7,B2,41,92,58,26,97,F3,F9,22,42,59,35,BD,7F,ED,74,7F,32,AA,4B,7A,DA,83,5D,9B,21,20,96,02,B9,B7,62,DA,A5,5D,BD,4F,21,52,08,6F,56,7A,F9,34,B2,13,39,84,EF,C1,37,3C,B7,9A,46,BF,F5,A9,53,E3,5A,DC,CA,46,16,0D,42,B1,7B,3C,2A,2B,9A,6D,E3,E6,AE,1E,46,9F,0D,7C,93,AF,CF,B8,E1,66,AA,1F,59,AE,E5,DA,BC,FD,5D,C9,C6,27,D4,2C,04,86,9E,D0,27,82,31,D9,A0,0A,BE,CC,ED,E1,76,14,36,89,3C,58,21,4E,FF,AD,6D,8B,6B,70,B1,73,83,5E,0E,53,69,25,E4,36,AE,A6,9F,A5,8F,C8,36,AE,A8,35,6A,4C,90,39,D8,88,3C,1C,72,06,ED,97,9B,2B,9A,5B,B7,D8,19,58,6F,03,8C,23,DD,9E,A7,4F,0B,06,CC,EA,2D,23,3A,53,48,F1,19,64,C8,3E,64,75,27,77,F4,39,08,90,A0,DA,E4,54,7E,E3,17,53,43,DA,46,46,6D,54,4A,22,BD,63,7E,3A,66,2D,EC,36,CB,65,3C,DA,3B,5E,EA,8D,DE,62,DB,71,9A,B4,B6,D8,A9,C2,9F,47,57,86,05,04,D8,56,DC,0D,2D,ED,FD,69,8D,D2,74,E9,BD,95,51,7E,59,26,10,52,CC,3D,F2,94,6B,9F,74,9F,AD,9D,A9,66,83,0E,C0,F2,D7,8E,4F,F9,9A,A1,17,16,BE,4C,5B,83,45,99,3F,3B,50,71,45,78,A1,E6,8B,44,DF,3A,F2,C1,91,46,69,8E,C7,FB,7F,6D,37,C0,B4,12,54,49,89,28,0D,D0,51,78,AA,6A,4D,89,23,59,B5,5E,F1,51,FD,83,1B,5E,F4,B2,10,1D,25,32,C0,DA,12,3B,43,1C,1F,EF,97,E2,3E,FE,BC,05,65,B8,A8,69,B3,7E,D9,73,F6,B7,87,71,7C,B0,B1,5B,0B,3D,27,9F,8D,00,0D,5C,CA,C3,10,06,FD,A7,08,61,74,52,8D,CE,56,99,60,45,3A,37,55,A1,EC,EF,29,4D,B6,E9,04,02,18,5E,AF,DA,BC,46,62,EC,67,E0,A4,17,D4,63,85,1A,3E,8B,E6,A4,96,33,5F,80,BD,8F,D6,2C,53,25,34,9E,35,8B,BE,92,A4,D4,BF,8A,5A,21,FA,63,B6,4F,3C,9B,66,25,66,49,27,1F,58,E6,D8,7C,FD,13,6D,FC,85,4A,35,89,5E,02,87,30,41,37,B4,67,B6,CE,5F,44,B6,39,16,38,60,66,97,06,40,8C,8C,BB,1D,51,7E,C9,20,FD,A0,E3,06,1F,6F,D9,18,CC,CA,75,D7,1F,CE,3B,4E,00,5C,E7,D0,C6,84,16,6C,89,DC,D1,85,72,40,AA,7E,10,22,F0,60,1E,A3,6F,39,47,92,C2,CE,F1,93,F9,2B,0C,59,64,E9,41,47,B4,1D,6E,A9,A5,69,2B,CD,2B,DA,6C,F1,EB,E8,61,77,63,65,C9,5B,6B,24,9C,0B,9C,8C,FB,BE,F3,37,09,FE,42,4A,C2,83,27,09,06,27,E3,E5,89,B0,DA,EE,16,95,FA,13,6C,68,A1,49,BA,7B,C7,E9,D9,40,70,2A,0A,91,35,04,E5,33,9B,EE,95,B4,F7,1D,6B,04,71,6A,27,21,F5,FE,F3,1F,56,8A,C1,F8,94,46,E5,A2,E2,D8,24,7C,85,45,38,45,76,F7,C8,28,77,42,E4,59,C1,FB,97,64,2F,E7,BE,C3,31,48,A6,3B,45,19,4B,71,9A,15,89,7C,13,D6,5D,B5,63,9C,B7,8E,F9,87,F6,4E,3E,01,4E,87,65,C3,C5,C7,46,48,90,FC,F7,1C,AC,55,87,ED,59,07,D4,86,DE,8F,F6,AF,62,6E,A1,2D,92,ED,E5,04,DF,1C,35,F5,04,67,49,97,3B,1E,2D,1B,4C,3F,4C,15,DE,E4,18,9A,A2,39,13,C0,B5,DE,3E,9D,80,6F,DB,A1,6A,63,71,92,10,70,F7,40,46,1C,FC,D6,E8,0B,16,3B,A1,FE,DB,A0,A4,57,C8,9F,D5,F5,E5,32,49,EC,CC,ED,34,38,DB,55,45,E0,89,DF,36,66,81,26,E6,8E,ED,99,AD,4B,34,7E,57,26,F4,B8,A1,B1,3E,D8,5B,4F,6F,17,F8,5C,72,86,28,D1,73,B8,A9,C4,5B,DE,5B,82,9C,29,BA,CB,5E,17,07,78,6B,37,2A,9E,26,15,E3,E1,98,DB,BB,08,FB,8E,04,99,AE,A9,12,6E,5F,4C,A1,80,3F,C4,D6,7F,FE,70,55,A6,92,FB,31,1C,0D,D1,96,37,47,5F,2F,84,8A,10,8A,62,6E,20,5E,95,3E,D0,FF,B4,5A,E8,E5,5E,A4,E2,D6,F0,80,07,D8,47,00,B4,2E,82,CE,80,0F,E1,B4,72,65,94,31,67,C3,6A,9F,53,DE,42,D5,9F,F5,EF,1B,D2,1D,E4,68,7C,AD,17,32,EB,6F,F6,E1,3E,42,0A,12,85,36,86,D2,29,2D,37,AE,45,C9,0E,5B,77,F4,DF,E4,A2,6B,8C,B7,28,C3,1A,3F,10,7D,2B,7B,E5,D4,6C,6B,ED,20,84,6C,A0,70,6D,DB,42,24,15,90,CC,C7,F8,1B,87,73,94,A6,0F,89,7D,7E,6F,A4,96,55,0F,AE,F2,51,6F,20,FE,69,17,D9,ED,A1,90,91,6B,29,FF,D5,AC,89,09,F4,B7,66,F3,83,B7,66,A2,20,6C,74,7B,C2,E3,6E,FD,96,3A,4E,6D,E8,93,6C,FA,08,11,64,02,86,46,22,07,F2,E0,E7,24,77,56,A0,53,9C,BC,CB,6A,7E,D4,D5,17,FB,5F,D9,EA,98,95,23,47,0D,32,DA,0A,53,CD,23,FF,49,99,8C,5D,8D,76,EB,00,0F,1A,11,B3,30,6C,0B,39,A0,FF,C6,74,B1,04,6D,A0,CC,58,82,12,02,5C,4C,77,7F,D2,25,3F,75,45,5C,E1,0F,EE,1E,F5,BD,9A,FA,7E,2D,1D,2A,82,65,86,3D,8A,87,C2,31,5C,92,ED,EC,F5,A9,9D,29,D7,8D,2A,39,A1,15,22,D5,4D,9A,D5,7B,F8,1A,43,96,A9,04,6D,5C,00,92,FD,29,EB,EC,A7,35,0E,D9,7B,B8,F8,72,03,C4,F6,7F,82,5A,20,38,29,B5,05,B9,C8,BE,48,F9,74,AA,79,CA,EB,A3,38,58,6C,09,C7,D1,A2,B6,6E,DD,49,F0,16,C7,0C,D7,93,3D,CA,BF,4D,8E,8F,53,70,3C,51,B5,34,AD,E5,56,63,46,42,D6,F1,31,85,1A,FA,AE,15,EF,39,3F,B5,4B,0A,D6,F3,E5,30,AA,8C,42,6F,11,86,3A,07,96,6D,E0,CD,58,68,57,19,0B,E5,A2,5F,E1,EC,82,D3,BB,1D,8E,FC,AB,99,F0,4B,60,5E,B6,0E,C0,E9,A1,B5,32,EE,BA,8C,C9,7B,97,EC,92,36,21,BF,E6,43,CD,75,C5,21,19,ED,60,EB,51,B0,D0,D2,86,B4,D0,AA,17,00,1D,E6,9C,A7,EF,9B,57,DD,47,CA,F3,DE,59,3A,C0,17,16,36,22,C6,F2,49,76,4B,A4,1F,AA,D0,01,2E,37,20,75,E7,45,16,86,B1,DE,89,E4,E8,EC,6C,1A,6F,7B,1F,5F,E1,C1,5F,E0,22,02,40,BD,14,3B,29,75,4A,46,23,BF,E6,7C,A2,13,3E,2B,D0,3A,7B,18,42,86,53,59,73,0A,73,88,4C,CC,A5,63,5C,05,3C,26,A8,CB,EB,E5,4E,F9,33,D8,7D,D3,13,02,D7,6D,2E,46,BF,DC,B7,FC,6F,1C,55,0F,27,E3,79,52,17,38,EA,98,5A,06,1D,E2,47,7B,18,06,DB,35,CF,B5,E2,5F,2D,1B,4F,60,1E,05,C9,54,38,4A,5F,B3,31,50,17,59,8D,FD,D8,3E,73,55,F8,83,51,15,44,D9,8D,7D,75,6D,69,2E,8E,83,86,E3,58,A3,63,12,59,D8,0A,BF,87,3A,E0,DA,C3,B6,0B,65,45,7C,4A,D6,D5,3B,E5,C2,06,0A,03,B7,8E,19,C5,1C,13,47,E5,0B,6C,E5,90,01,37,71,A7,61,5A,85,D3,B7,90,AB,2C,53,3C,B4,C1,7E,E7,72,3A,30,04,1F,72,80,57,D2,CD,04,60,EF,C0,52,73,46,46,D8,BE,B4,7D,B2,23,16,9A,B2,2A,80,DA,93,88,BC,5C,EC,1E,8F,00,AB,EF,B3,8E,8F,4E,80,0F,2E,1D,F3,6C,4E,1B,D6,39,96,46,15,CC,FC,33,1B,F3,CE,2C,62,8B,05,40,4B,F6,9F,B1,BA,3E,19,5D,55,6A,A9,E3,4E,C1,F7,AB,DF,75,47,BC,83,37,4D,AA,C5,00,A9,82,54,25,B1,FF,E4,E4,4A,44,E9,FB,D6,92,6B,8F,40,A0,FE,59,95,C7,08,3A,F8,69,45,E9,C4,62,16,C7,27,17,3B,08,06,14,1A,BD,39,E9,E0,B7,78,B5,1D,03,57,A1,E0,EC,FF,C4,64,8D,06,9D,3B,10,4C,37,99,D4,FD,C3,3C,A8,5C,88,06,F7,75,92,2E,B4,FE,58,FC,A0,03,3F,EB,DF,4E,32,E0,17,B4,30,54,AF,E5,FA,19,FD,2C,2A,F3,E1,37,E1,94,C3,8C,37,E9,81,29,67,73,7F,66,70,E8,8E,A2,76,CE,FF,EB,10,A9,6C,6E,D4,20,14,1B,81,F2,B0,E6,CE,FA,6A,06,C0,3C,5E,F7,33,08,09,1B,D5,1F,0A,38,10,06,01,72,3B,10,16,02,AA,96,A7,DB,54,EC,C2,6D,9A,73,C4,01,FB,BD,75,5D,48,0F,46,B3,F2,45,EC,7E,FC,55,05,2C,DC,B0,1F,BC,A6,6B,C0,D6,DF,85,A9,E2,CA,70,D1,01,2C,ED,C9,CB,1D,D2,49,5E,74,D8,0B,BB,B3,50,C3,35,72,F0,16,89,12,AE,67,93,3D,7B,30,A9,8E,BA,F2,7C,16,8B,47,F2,FC,69,C4,DA,2E,4D,34,FE,0F,8A,03,F9,82,D6,30,44,94,63,D7,E2,CE,7B,32,CF,9A,C8,6E,4D,AE,95,CF,C7,72,72,81,B5,67,EE,1C,4D,38,44,71,E6,85,37,B7,50,B7,2D,CA,7D,22,E7,27,5B,78,50,3B,3F,C1,36,F4,5D,C8,C4,58,E6,9B,A5,8D,81,C1,9D,1C,C5,36,96,82,59,D9,E4,D2,E2,EE,99,89,37,B8,D2,F4,5C,B1,4C,12,65,B2,5F,0A,06,27,44,7E,C6,A9,36,D5,BF,73,47,F3,29,84,77,D9,12,9A,24,24,59,6E,B7,16,B4,4E,B8,6E,12,BC,79,0B,F4,C4,96,0E,87,30,B7,98,57,37,B4,0E,49,5C,F6,9E,54,40,9D,2C,EA,15,3F,8D,6A,92,98,73,6E,A2,33,9B,13,A3,74,19,C7,C9,AB,76,07,51,EF,67,F7,3D,B6,AE,1A,A3,98,D6,E0,D6,FD,24,09,10,E4,F3,57,D9,2A,EB,4B,23,75,D5,E6,78,D6,82,66,29,96,2B,1C,2B,33,61,64,C6,95,A3,1F,02,20,23,4D,7A,2F,D4,BB,83,76,89,A1,C9,04,94,DB,39,9E,53,62,AE,3A,D1,3E,D5,FA,DA,9A,BE,84,7D,ED,42,8E,C2,63,4C,7D,60,8F,36,3E,3B,4B,ED,4A,E5,B5,12,65,0F,88,25,C3,80,06,A0,53,00,68,BD,27,39,E4,42,44,6D,E0,BC,B9,A2,C2,BC,3D,E8,66,F8,D5,F0,BC,1B,03,1B,D1,BF,D3,C7,29,77,9A,D6,09,8B,45,ED,C4,C3,41,DD,92,FC,74,EC,6E,76,63,77,52,B7,2A,40,04,27,07,30,9C,38,92,E2,5F,C2,B8,08,0D,50,0F,A6,19,40,08,2A,EF,36,3E,D0,AD,03,D7,65,1F,BC,2A,53,17,85,6B,33,F5,66,2A,55,E7,88,92,D1,B3,A6,88,08,0A,4E,A1,59,67,1C,39,A2,11,DA,0D,58,74,60,B6,B2,62,3A,85,6B,83,FA,AA,BF,2B,48,D6,0D,F8,75,BB,AC,4B,86,E3,59,0B,62,47,AE,EC,EA,08,85,6C,C7,A2,63,37,72,49,1D,51,48,37,76,38,68,11,85,60,CE,3E,9B,00,8B,1F,90,6A,92,EC,28,05,67,BC,70,7C,24,92,04,C3,14,4A,A2,F6,21,7B,F8,46,A9,45,26,8A,67,BF,58,73,F1,C8,2F,35,EB,E2,8A,3E,35,0D,27,BA,60,F9,D4,2C,76,C4,BB,9A,10,CB,6C,0A,89,52,6F,EA,23,5F,4B,BF,64,B2,F5,FE,AA,4F,3C,4B,03,E9,DB,7B,E5,B2,13,04,68,80,50,AE,6C,C4,53,4C,D6,C5,39,04,2B,5B,95,96,13,C8,D9,80,F7,DD,60,8B,06,DF,43,3D,AB,58,8E,8B,90,A8,B8,7B,BA,14,B3,94,7F,97,9F,98,21,6F,15,51,AF,D3,83,DF,B7,86,46,FE,7A,07,D2,FE,CF,C6,90,26,12,5A,66,60,28,7C,33,2A,ED,49,5A,DF,2C,0E,0C,62,BC,40,93,49,F9,23,27,31,16,C6,CE,85,35,23,82,44,DF,65,E6,B7,87,51,57,6F,9E,1B,FD,41,9F,76,EA,66,CB,62,E2,CB,4C,07,22,84,74,DE,30,58,18,B5,62,9A,BC,E0,F5,4A,16,4A,BD,51,FE,BE,3E,A6,59,91,85,60,6B,EB,F0,8E,8A,EC,3F,52,6A,19,84,7D,BF,74,EF,7D,96,9C,AD,B7,DA,06,8B,C5,3E,78,1B,FA,A2,8A,37,83,34,E7,53,BC,64,67,11,49,BE,5E,B1,55,8F,10,9F,B5,02,27,17,F6,95,31,4A,33,12,B3,F2,EE,5A,48,52,90,D3,CA,2D,B0,F6,8C,BD,0C,75,47,C6,71,08,32,37,6F,3D,08,BF,3B,DC,48,02,C5,66,1B,A8,F6,66,DA,69,46,40,00,5A,A7,D6,4C,5A,F6,0C,71,67,5D,FD,18,4D,6A,23,F5,74,0A,A8,02,B7,69,29,D4,A2,45,56,39,A6,DF,53,6A,B6,D3,AD,FD,AA,8F,13,1D,4A,B0,B5,2F,9A,25,7D,75,93,9E,99,2D,C9,9F,AE,FE,04,C2,C5,D4,87,A8,70,5A,A9,A7,D7,5C,DD,BC,A5,86,72,10,3C,CC,AA,3B,E5,F6,39,57,EA,17,63,4E,1B,E3,19,B4,C3,9A,28,9D,27,6A,26,C4,DD,55,C0,17,03,91,54,70,B1,0A,A9,75,B5,CE,35,E2,B7,DA,8F,D8,5F,31,29,05,DE,E9,47,32,5F,43,79,59,D5,4C,B0,11,A4,67,77,0C,5C,BA,0F,B8,DA,AA,B3,8C,56,A0,7A,91,83,74,43,3F,9F,43,D7,A5,21,62,1E,76,24,37,4F,86,B2,3C,43,2A,AF,8E,40,92,09,A3,48,B3,93,C0,D5,C7,7C,FC,55,B8,EF,E9,D0,7A,9C,88,B9,1D,38,B7,A6,BF,71,9E,78,0D,C0,9C,2C,3E,85,BB,57,EB,4A,EB,63,38,C8,3C,EF,DF,33,FC,AD,15,92,B7,69,C9,F7,C0,A8,77,3C,66,03,C7,5E,C5,8C,A5,B7,CA,EB,17,66,93,AF,AF,98,36,34,AA,76,6F,FA,40,42,58,33,47,1C,F4,A5,49,8B,99,B2,E7,AA,25,AA,F5,99,F4,C7,BC,68,96,12,FE,7B,14,8E,F9,D8,C4,E4,5B,9C,D2,B2,3A,34,8B,EF,92,08,24,F7,02,F7,F1,4E,F3,D2,CD,EA,F2,6B,CA,A5,A0,BE,57,4A,45,DB,54,9F,DA,5E,57,6F,21,70,83,F7,49,C9,86,49,2B,72,BF,E7,B2,CE,60,8A,74,8B,5D,65,19,82,8F,6A,1B,B3,07,61,A1,1C,36,10,17,25,45,BA,E7,D1,41,2D,91,C0,77,8C,57,19,C7,FB,DF,71,04,C1,8E,09,3C,22,B7,68,7D,73,15,AB,F6,28,69,06,0B,AA,82,F0,69,8F,50,9B,F4,9E,D0,7B,66,F8,8F,CE,81,33,F6,B8,DB,AF,72,29,39,A6,24,48,63,87,EA,C7,ED,FF,10,11,E2,5B,08,2B,19,FB,08,3C,57,F1,24,B7,8C,9D,E7,73,DE,24,26,15,63,7C,21,86,13,5C,7E,11,9A,DD,00,50,52,56,5C,1A,B4,D2,21,82,83,2C,91,56,56,F2,16,F4,7E,01,65,EB,3C,6F,FE,74,73,3B,EF,BF,12,18,E0,77,96,44,8F,40,8F,6C,17,57,AB,9E,E5,8C,0C,20,39,98,AB,03,2B,D2,C5,AE,B0,3F,52,7B,83,EB,AC,0F,1C,0A,F7,EB,10,B1,5E,61,74,87,FC,9B,B3,D9,A1,B8,35,EB,5C,E1,53,0B,D4,B9,15,F7,2D,9F,2D,49,C8,4C,E3,2C,A3,16,70,EB,CE,74,81,D1,19,27,3A,4A,B4,7E,6F,23,DD,1B,94,42,05,4A,25,D4,84,00,81,9C,15,13,A5,BD,28,2E,A3,D6,8F,B8,52,FA,83,4D,EA,48,41,42,B9,6D,26,87,8A,5C,B2,DC,A2,DA,78,73,4B,70,68,08,6C,7D,94,FB,85,D9,BE,42,7C,E4,D1,7D,E8,70,C4,DA,60,CC,C2,47,00,62,69,4F,87,CF,A2,B8,78,8C,4B,3D,66,BD,E6,24,9C,2B,82,92,21,63,B2,6C,53,BE,3F,EF,69,2F,BF,00,92,51,54,10,1D,11,53,19,9D,A2,78,DE,3F,49,BE,0D,33,AC,CB,E4,E2,B5,3D,E0,68,F9,1E,89,37,6B,6A,F2,65,28,CC,79,A6,DF,09,90,B3,B3,7D,A9,1C,61,18,6B,F9,02,D8,E9,80,E9,72,AD,FB,C3,6C,52,24,C2,7D,38,83,14,D7,4A,B8,5F,C9,CF,00,68,8E,67,C9,4F,E1,94,C5,3F,83,AB,54,01,27,73,F5,CB,14,53,4D,EC,D2,F9,64,02,64,88,A6,DD,EC,A2,F3,12,F7,9E,3C,C5,AB,73,23,34,A9,1D,13,C1,11,14,56,FB,E8,BD,C6,01,EB,60,CF,39,E6,A9,23,6A,1F,F5,A5,44,15,CA,89,58,11,A3,8E,D2,9F,0C,50,3E,DC,86,06,09,EA,82,65,6E,38,F9,0C,5C,18,9B,40,61,E6,19,FF,69,86,E1,75,C4,3F,C7,95,2D,0B,6F,12,34,39,40,46,6E,4C,7E,65,31,B0,31,84,51,37,0B,ED,80,AC,F1,1F,F9,63,BD,7E,90,CE,AA,16,A4,80,73,8C,D5,80,18,A4,84,05,98,54,F1,4A,9E,BE,73,3B,BD,65,CF,A7,39,17,2C,B3,9B,DD,FD,D2,CE,4E,E1,45,90,25,33,3D,94,63,06,85,60,A6,CA,AF,48,60,93,AD,1F,83,DE,AE,FC,A2,B3,67,7B,B5,FD,FD,61,AC,93,94,93,BB,2F,05,2A,23,38,07,70,DF,0F,CC,69,BE,66,F8,DA,6D,DD,1C,65,83,65,97,A8,88,4D,FF,BF,AD,A2,8C,F0,69,2E,21,BD,17,BD,21,DA,73,25,BA,E0,BA,E7,1D,10,CB,ED,EA,C9,87,7A,28,83,47,BA,3A,5A,4E,BB,D7,F8,C1,94,F1,FE,7A,F0,99,37,11,4E,79,44,D9,A6,F2,68,B4,6F,CB,24,C9,EF,2D,9C,23,E4,F2,C1,B4,C9,4E,71,BF,C0,E5,AB,A3,FA,E2,70,51,67,0F,A0,50,DB,2D,59,24,5C,BF,57,39,83,1A,C9,BA,44,83,8F,EB,92,C6,09,63,21,48,C1,66,F1,EC,0B,6C,1C,1C,C5,97,E1,F7,3A,95,90,B2,F3,4C,2C,6B,9A,B1,CB,17,B5,76,FA,DD,41,B8,CD,22,5F,AB,7B,59,3B,BD,BD,63,60,06,B2,7C,AF,BC,CD,9B,C9,A2,5E,4A,19,48,1F,BD,82,82,4F,B4,2A,AB,D7,A5,77,9F,82,C6,93,6E,D3,5A,77,3B,AE,8D,72,D2,09,F8,3A,EF,59,81,CF,BD,C6,5A,5F,DE,EE,97,0E,58,12,3E,43,FA,86,77,BA,4B,F4,48,E7,C3,57,35,74,60,5C,1E,5E,4E,EF,35,7A,6C,71,EF,AF,7E,DC,4B,26,95,56,6A,36,15,72,FA,D2,3F,5E,B2,62,6C,F1,F1,79,24,0D,5D,0C,A5,4A,A6,96,61,C5,A9,3A,8C,4C,DD,0A,81,D4,D0,82,97,E8,AE,D5,C5,27,88,3C,3C,D8,12,9E,77,2D,4F,D8,A4,00,43,E4,72,81,12,F5,33,0E,18,13,4F,AC,9F,93,D6,BB,A7,E8,FA,24,6F,CA,4F,DA,AA,EC,D1,8D,9E,B1,BC,38,F1,A4,99,C5,D0,36,D9,D6,C0,C8,44,91,96,1A,1B,9E,F8,1E,25,43,3C,18,EC,4D,9F,A5,E0,5D,72,5E,87,BF,9A,AF,81,8B,8E,72,7A,4C,99,1E,EB,41,1D,48,B2,D8,08,56,A1,EF,14,22,80,8E,4B,6E,90,5F,E1,B1,A7,59,7B,4F,0E,87,0B,C7,AA,3D,04,F4,6D,E1,A9,05,D0,5D,67,2F,D4,EC,D3,65,AE,3B,CE,8F,9E,3D,75,4F,CB,D4,DE,69,11,10,0F,26,4B,E5,22,C7,CE,EE,19,43,B3,6F,1C,AE,A2,41,CC,36,A6,6E,4D,DD,19,CD,78,A3,56,81,CF,BD,C2,90,DE,10,C7,68,AA,44,AE,46,BB,ED,6C,3E,6E,69,50,9A,6A,29,02,DC,4E,77,31,E9,0E,1E,5A,27,01,80,69,80,04,C8,4F,87,47,7A,61,D8,26,54,6D,4A,A9,40,F6,E9,13,00,3F,EF,40,5D,CA,AA,70,43,B1,AF,29,EB,25,B8,8E,B9,7B,4E,42,41,8F,75,14,BC,98,3E,36,FE,6C,02,55,C4,E8,2A,CF,F8,39,62,11,00,88,B1,6D,0F,40,1D,F0,F6,D0,99,13,8F,4C,DB,4E,8C,FA,CC,E1,80,F8,F9,50,78,04,C0,36,A0,FD,52,F8,FF,C8,62,24,29,7D,27,37,F9,5F,8D,6E,A2,F6,DD,28,C5,BA,6C,E4,E9,9A,89,42,FF,CC,20,F8,6F,17,5E,C7,70,06,47,A1,F7,9D,97,AA,31,0B,A6,72,35,55,ED,71,0F,A3,28,41,02,DE,6D,88,E4,43,B0,E8,78,D0,03,56,88,26,4A,BD,A2,EB,73,28,E0,92,14,D6,FA,D7,CD,60,03,C0,6D,F8,05,1B,50,E9,B9,02,BA,9D,F4,78,28,B1,32,2B,31,4C,36,56,7B,9F,03,63,9F,7B,66,06,5B,AC,8B,13,F5,4F,C2,54,D0,99,D7,10,86,94,7C,50,E5,05,60,AD,B4,54,FA,2E,8E,12,9F,EA,D2,8C,64,81,91,DC,D3,30,66,D1,0A,EA,F3,A6,F2,EF,16,DC,A0,E0,3C,74,CB,2F,B1,55,EC,EA,5F,EB,D6,A0,5A,02,23,A1,5D,88,62,4B,D3,7C,83,BD,6D,D5,70,75,7D,0D,D6,39,0F,1C,15,72,4A,02,C0,4B,10,B6,AC,2E,03,06,1A,49,D0,58,D8,AD,98,BE,B6,05,61,40,07,CA,A6,B5,49,B1,0A,C9,59,48,0B,3B,E6,A7,23,0D,37,4E,80,F7,AC,66,92,E7,7D,86,56,88,32,40,A8,16,18,EE,BB,52,94,FB,06,7A,62,79,DF,04,26,DC,DB,B5,60,49,58,D4,00,F5,B5,E6,6C,70,E7,91,94,2D,60,40,9F,F9,B9,4F,F8,B8,CA,72,FF,12,7C,DE,4D,2D,E7,95,1F,78,FC,E2,9C,66,45,24,D9,6B,7D,12,65,7A,B5,21,72,EC,5A,44,0C,CB,C2,09,2A,95,74,30,CD,CD,46,16,71,00,C7,02,FF,88,76,E0,BC,97,96,7A,22,DF,8D,C9,7A,25,3A,61,54,CF,9F,CF,38,16,FF,1A,76,59,05,B7,A0,19,4F,84,DB,C8,09,E6,D9,EE,BB,AC,F3,D9,49,84,C3,9D,2F,7C,21,66,F5,F7,97,BA,63,05,1C,34,54,AA,AF,67,D7,CB,30,F3,7C,83,7C,35,4C,61,F4,73,7A,9C,98,3E,52,70,9A,EC,EE,2A,65,E6,2A,0F,16,AF,BF,AF,E1,CA,6A,A3,53,AE,9A,8F,91,96,94,C0,00,A0,7A,5B,03,AA,89,35,BC,ED,64,5B,FF,1A,F3,E5,1F,B3,92,2B,00,19,17,16,26,3B,79,0A,41,28,B4,46,17,29,9F,6D,6F,06,25,B1,98,92,DC,AA,B1,54,06,05,B3,9A,91,98,73,68,B4,71,15,C7,FF,63,70,07,F1,19,40,C3,5B,41,E5,86,11,D9,47,66,D6,99,30,2A,96,08,83,A4,0C,ED,1B,DF,8C,7E,E2,F4,A0,09,66,07,17,29,FB,2F,FA,98,70,D4,EF,74,89,37,18,A8,46,30,BA,BB,F9,99,E7,09,52,C7,50,78,32,46,8A,85,08,8F,A2,90,EA,CE,43,CF,8D,01,6D,A8,78,C1,54,42,9E,3A,06,A3,3E,36,D2,E0,B6,E1,71,9B,D0,8B,D1,70,45,A3,63,E0,71,B5,4F,D8,13,B1,61,D8,36,47,89,DA,97,EF,A7,8F,F4,B3,43,9C,54,03,F8,3D,C4,EB,DC,CE,21,27,F5,B8,79,EC,F7,2E,83,54,41,AE,15,E1,14,23,7B,B9,99,FA,EA,60,C6,59,0F,C3,25,31,2B,43,E2,E6,94,A2,BF,B1,9F,97,93,BB,21,D7,E1,C8,F7,A3,26,CF,F3,8B,9D,26,60,B0,24,60,02,1C,5C,86,B2,2F,B6,A6,AA,F2,92,8F,D5,BD,CA,C4,2A,63,BE,78,65,56,91,F0,F6,E9,6B,53,22,9D,C2,F1,BF,CA,69,A8,AC,4E,C7,29,B0,D4,D5,52,33,5B,FE,A4,F1,BC,0B,13,CB,F4,8A,76,5B,21,88,15,80,37,0E,BF,6E,EB,E0,72,22,70,D6,BD,47,EA,55,8F,1F,F0,BD,DE,7B,5F,6C,FA,37,7E,1D,16,44,2F,6F,BA,A3,BB,39,CF,CD,F3,21,7F,CF,E6,73,BC,BC,24,D2,38,D0,60,4A,4C,B1,6F,FB,2F,0D,58,0A,04,3B,47,ED,F4,64,39,BE,91,F4,BF,DA,FB,50,CF,82,95,F4,59,D1,22,68,F9,49,54,07,AC,ED,76,D9,D4,1B,65,C5,F0,33,17,8C,E7,95,18,B4,FF,ED,C2,5C,4B,F3,29,0C,BC,A2,89,A1,5F,45,B0,4D,B6,83,A4,DA,C7,DF,CD,E6,80,5A,5D,05,41,22,E8,B2,CC,10,13,5A,BD,92,3D,C6,48,78,76,CF,17,95,8B,09,C4,E8,25,31,BF,63,EF,B6,E9,EB,40,1C,1E,3D,D6,54,D2,07,B7,BC,45,CE,AA,F5,6B,F1,51,B9,E8,18,7D,43,D1,B9,52,DB,9E,4E,9B,C6,26,DF,67,E5,61,F6,F5,BD,3F,52,5D,37,83,E1,67,89,24,85,22,70,BE,B8,A0,CF,9D,2A,14,16,70,E8,68,2F,73,20,57,47,07,A3,E7,66,BE,87,23,43,78,35,FE,44,61,33,4F,06,00,11,E6,5A,6B,2D,DF,56,6F,C3,CA,4E,4C,70,6B,90,40,4E,11,B9,A0,AE,AF,E5,EE,21,9E,DD,A3,47,EC,85,99,C2,17,25,AD,5E,8B,D5,9B,F6,69,E6,85,BF,ED,B1,2F,BD,62,82,D8,5A,04,6E,C9,B1,9C,A6,39,B9,4E,E7,E3,E7,CD,00,15,AC,EB,63,10,05,62,F4,44,AF,D9,BA,AE,1F,18,F2,0C,59,DC,E9,98,80,F5,C7,BB,55,9C,C5,F6,2E,96,34,39,9B,C2,BF,77,27,68,99,35,A6,1A,57,FA,7E,AA,1F,8F,DD,B1,74,B9,6F,2A,DF,46,4A,34,89,F9,72,8F,0D,CA,F9,78,9C,C8,44,92,CC,F6,B9,0E,51,A0,2F,1E,86,4A,AB,6E,0E,42,37,1A,43,B8,88,7C,47,44,15,9A,F0,82,50,8E,56,59,0E,9A,AE,7A,71,E2,C9,FB,B7,3F,51,FB,65,C8,B5,71,BF,32,8B,2C,9A,67,6C,BA,3A,EA,40,37,92,B4,39,4A,AA,06,6D,52,21,C4,A5,06,BE,0F,B4,60,5B,22,61,D9,1A,3F,5E,EB,5B,44,F2,2B,88,DB,77,4B,EE,FE,FE,4D,63,9E,77,A8,AD,62,B7,07,61,A5,97,00,69,FE,1B,A1,A8,87,DF,5F,8D,80,D8,D5,67,9D,28,4E,FC,4A,0B,A3,C8,04,BA,CA,DA,AF,C5,3A,96,67,10,16,A5,EA,D2,80,81,97,E9,20,B5,0C,F1,ED,1C,FF,75,51,FC,AD,EE,5F,CB,90,25,70,3C,EE,96,BF,14,2B,2C,52,01,D2,44,29,80,ED,57,19,72,D1,42,F2,0E,0D,3C,EF,B8,7A,A7,92,3F,92,FB,61,07,78,23,D4,A7,3F,BF,16,EA,30,DA,5C,D3,10,4B,4D,1F,5E,A1,FC,B6,E4,7D,E0,48,AD,15,63,60,5F,89,FA,AE,CA,DB,E6,B4,18,63,A3,E9,75,A4,E7,3D,10,0A,28,3D,4D,2A,E3,77,6D,3C,36,22,C3,87,E5,2B,1A,93,31,93,61,CD,98,3A,EE,BE,E0,2A,4F,79,C1,7F,E6,81,19,7F,B0,34,99,8D,E6,33,B4,04,F9,D2,B4,41,01,CF,80,99,BA,76,E5,55,F8,67,5A,F9,40,76,2B,5E,5C,A0,21,B7,C2,CA,EC,2C,43,25,93,3F,E1,FE,B7,66,CC,E5,02,2F,40,B2,57,C5,7A,D7,86,45,52,E9,75,5F,00,3E,DD,36,8F,B2,CD,DC,09,27,7D,91,20,F9,46,E5,45,08,B3,44,C1,BD,B9,D5,EC,AC,DB,89,64,C4,42,E6,82,0F,54,5D,2D,0C,F8,F0,B9,CD,FC,23,12,91,3D,70,D5,86,FB,7B,15,13,4C,20,CA,F7,B5,42,2A,20,32,D3,B7,B6,7D,1C,11,DC,15,56,29,D3,A8,D6,6D,A2,46,02,11,04,FE,3B,97,FF,66,CF,68,EE,4C,85,C8,BD,61,78,32,0E,9E,67,00,43,68,B8,DA,68,C1,EB,91,72,62,AD,33,57,0E,20,60,F5,23,D3,26,67,94,23,66,52,D3,DD,AE,BB,20,2B,51,D1,DF,DA,58,84,BF,B5,32,51,FC,EB,20,6D,2E,C8,72,8B,78,E5,35,93,69,B6,AD,F5,09,4E,09,15,CB,A6,D1,4E,D0,4A,6F,92,15,34,1D,E7,61,32,09,F6,BD,72,94,C2,DD,DA,A4,A5,1A,2B,16,A4,25,C3,EA,B4,5C,04,CC,8A,0B,B2,28,5B,17,B6,9B,79,2E,AC,20,5F,BD,BA,D5,4E,23,B0,7D,26,A0,E5,97,F3,7F,50,6A,A2,77,13,D2,2E,2D,5B,BD,3A,C8,6C,A0,3D,D7,C4,55,55,22,72,58,FF,99,29,69,1B,7B,21,EC,BD,58,EB,0A,5C,B4,41,98,F0,7C,AD,6E,3C,FD,CE,7E,8F,F2,84,4E,FC,A4,32,DC,BB,D0,A6,97,65,9F,36,2D,29,AC,DB,1D,1A,70,2D,C3,A1,92,72,28,4F,7C,40,48,39,C4,59,3B,3F,A6,4E,6E,05,60,2F,55,F9,F8,98,39,2E,28,C0,BC,84,4C,96,18,B6,A9,C4,E6,65,A8,72,90,82,79,6D,DE,BC,1D,93,D8,13,69,46,FE,E9,BF,DB,81,AB,66,D7,FE,13,4A,21,F7,A8,5E,F4,0E,AA,3D,EE,B2,8A,33,72,C5,CD,3D,07,4C,13,6A,DC,22,28,B6,DD,F6,BB,F4,12,F9,F1,E1,27,1E,DA,81,CF,D1,79,6E,08,26,6E,7B,8E,8B,CB,59,FF,A4,34,1D,52,18,BF,52,4F,AF,71,1B,9C,3C,21,9E,F1,F5,48,CA,42,6D,52,36,64,B9,DD,E4,1A,73,55,71,9C,B7,AB,8F,CD,10,27,DD,96,B7,50,16,92,EA,5F,4F,4A,19,05,C7,7D,CB,93,B1,6B,25,EE,A7,7A,E7,EC,7E,89,E4,EA,F6,C8,A7,7F,CE,7E,E7,96,EB,50,0C,9C,E7,65,99,7A,A9,CE,EB,73,72,30,3F,10,CE,2E,45,98,87,7C,52,20,23,54,6D,64,7C,A0,F3,CB,58,C3,CF,5D,51,47,2F,4B,C9,E0,46,45,C7,43,85,2C,57,20,57,D1,C3,82,19,E5,F5,B5,62,B9,02,22,57,E4,D4,12,B8,7D,B7,E7,6A,12,AF,9D,F3,E1,73,81,3C,A9,E1,A0,A8,32,07,91,C4,85,84,EF,DE,EC,38,B1,1E,A4,54,36,FD,4F,4E,0C,B7,C1,EE,27,0B,88,17,D7,62,3C,E4,51,3C,E5,72,E9,4D,42,1D,31,11,99,DF,FF,34,C4,D4,54,5F,99,94,26,07,3C,95,E3,11,F9,78,F3,11,80,D4,C6,5F,05,41,A9,C4,88,F6,30,4A,E0,69,D4,32,CF,E6,97,FE,72,56,24,C9,88,85,88,21,A6,21,EB,FD,2C,59,29,B0,DC,1B,02,F4,E9,35,8F,A4,0A,E2,BD,C7,CA,FE,10,1B,C2,01,87,12,E3,DE,B7,2D,61,06,B9,53,01,A3,4F,4E,6E,FA,8E,7E,D0,B8,5F,36,54,28,85,C8,B8,EA,64,87,84,AF,25,58,E8,63,D2,88,A3,7A,76,EB,FD,00,C3,BB,EB,F6,33,2A,09,77,21,1E,5E,A6,1A,12,62,D0,D0,30,35,DF,3D,55,A8,0E,3E,BA,C6,56,DC,D8,C7,56,D2,FA,66,E2,6E,1D,A8,0A,5F,C9,48,5D,05,E6,06,23,4C,CC,43,ED,2A,C3,26,C8,87,0E,E7,15,82,3F,68,F7,C9,9A,97,47,17,F2,B5,89,88,0F,D3,47,17,0E,B0,03,AC,50,56,15,A1,45,2C,50,CA,0F,4E,4C,D0,7A,3D,7C,49,46,F7,8A,2B,F4,92,79,71,CE,16,AE,C6,ED,40,74,07,5B,3E,45,B6,B8,5E,1E,5D,BC,14,53,43,24,EA,04,D2,10,86,21,22,97,E7,66,74,75,6D,D5,26,85,2D,F9,96,D0,0A,6D,A7,12,38,3F,FB,B9,DF,CF,04,D0,8D,52,B5,1C,56,60,3F,0C,51,CB,67,A6,1C,6E,33,58,A1,09,94,3E,34,05,6A,CE,72,98,8D,40,F1,9F,6C,1E,A4,EE,AA,CD,91,C0,65,76,37,83,AA,E8,C3,C9,A5,B5,66,E0,69,55,7C,53,3C,89,E6,47,2D,85,8A,66,64,FD,A2,03,DD,F5,40,F6,14,99,12,82,8B,60,95,74,C5,FA,94,28,71,FF,4A,28,64,1A,2C,09,D4,59,69,CC,50,0C,03,B1,D1,08,A8,CF,4A,E0,88,84,77,8A,E5,B6,EF,FC,EA,15,30,F3,5E,F9,73,98,3F,3F,E5,89,46,2C,1D,C4,FF,A9,5B,CA,1E,78,81,F0,69,8C,65,18,0C,88,CB,00,A7,91,CC,6D,45,6D,05,8F,D9,C9,23,5E,2B,0F,BE,BC,DA,5C,99,3A,59,7C,2C,09,37,C2,1D,E0,40,77,FB,29,A1,42,ED,0A,B0,E6,21,1C,82,38,81,EF,B4,79,FB,65,65,59,6A,9E,3A,8D,EE,B0,2C,D8,2E,08,F5,49,91,B7,2A,F9,20,AA,FE,33,19,AB,72,42,5D,2B,C0,9B,1D,53,A0,CC,FB,12,30,46,77,B1,11,C9,6E,6E,50,F9,AE,D5,09,3E,61,A7,E4,CD,1C,00,C1,24,AB,CA,39,83,A0,1B,57,89,EB,84,BB,3B,54,F4,F5,94,D0,0E,7B,88,7F,EE,AF,5C,33,6D,23,5C,A6,4A,AE,17,6E,FA,A3,88,7E,26,DC,1A,DB,B3,FD,CD,7F,F4,FF,76,72,B9,DF,DF,C3,02,FB,CA,96,87,58,68,C7,0E,C7,0B,7E,38,01,82,7A,E1,E1,E2,9F,59,0F,EF,3A,E5,1B,4D,40,52,40,EF,76,C2,5E,93,D8,8F,54,8C,4D,9D,CF,0E,5E,30,03,D1,1A,C7,70,71,1F,92,B1,BD,55,98,E9,39,31,13,23,75,6C,24,A4,AE,86,6E,06,E8,B0,E5,5D,B1,30,CD,B5,FB,C6,91,9B,90,EC,7B,27,1C,8D,41,DE,4F,83,9A,EF,D8,B1,53,7B,F7,E7,B2,A5,FD,C1,CB,DA,3C,04,F0,48,BF,CD,60,2D,1A,F3,6C,EE,42,F5,B8,60,3B,C6,1D,E5,6B,B8,3A,C3,C7,84,8C,38,DA,08,91,0B,77,DD,07,16,88,65,17,1B,3B,E6,24,18,03,C9,53,7F,85,01,05,63,CB,7A,2F,04,93,EC,E4,24,9B,9A,12,09,9A,A5,68,85,4D,6A,17,4B,CC,0F,E8,B0,F8,A7,6A,D1,6A,85,1D,9C,C0,A0,AC,4E,5B,89,E6,56,7A,FC,91,2A,8F,6F,15,8D,09,B8,B9,D6,61,19,E6,9B,1A,06,3D,7C,34,8D,F4,10,14,B1,BA,18,36,6E,EF,C0,CF,2D,6B,FD,F8,90,C0,D0,BA,2F,32,A8,CE,CC,64,5D,BC,0E,7B,AE,0C,43,AC,B0,53,00,FD,D3,37,87,B8,9A,B1,B4,A6,29,D1,35,58,9F,93,C2,E4,2E,71,D9,07,86,0A,0F,A8,D4,23,CA,00,9C,8D,1F,A9,95,B6,D1,73,DC,1C,10,45,82,ED,53,E6,97,E1,25,B4,26,73,1D,4E,F1,95,2F,C3,46,70,4A,BB,7F,06,C0,46,CB,A2,71,18,19,9F,94,96,4B,E2,92,37,B9,B1,04,C5,5F,4F,D5,A6,3B,8B,44,C6,FF,48,9E,55,28,CC,BA,C3,42,21,C9,F0,0C,4B,C3,26,88,8C,E2,51,31,0A,A8,F5,E6,3E,33,FD,6F,A6,8B,90,55,E6,08,04,D7,77,3E,EE,18,48,CA,1B,63,C0,77,9B,5E,3F,86,99,77,81,E4,AA,2D,D7,ED,BD,1A,6D,ED,F5,06,C9,7D,D2,2D,A8,3B,11,71,62,10,56,41,53,F5,CF,8A,D1,15,AD,74,D7,5E,2E,1C,70,C9,31,82,80,CC,63,03,45,8A,AC,F6,74,8F,F8,9E,68,32,3F,BD,AF,01,AC,61,EE,18,6C,9B,C0,D9,E4,EE,D5,6E,18,CB,AE,42,96,49,D1,FC,19,45,C0,08,DE,CA,0A,FE,AF,D8,01,EB,C4,F7,6B,00,CC,BA,80,5D,16,2E,9D,17,04,DD,A6,89,ED,A5,CD,CD,34,BF,03,BF,25,51,D3,2A,2A,EE,B2,2A,2F,E4,C2,D1,02,0A,3E,A4,1B,60,13,2D,82,07,07,34,25,F8,79,69,B5,66,56,5D,DB,F9,33,0A,4B,67,49,26,39,9C,A4,48,16,EA,D0,C6,09,7F,2D,6C,42,AC,0E,B7,8F,9E,71,7B,F0,B9,8D,35,04,FA,05,6A,04,3F,1D,77,0A,EE,C1,84,57,6D,58,79,8F,02,18,FF,C3,6B,93,23,2A,07,D2,7D,4A,7A,2B,62,05,BB,0E,D9,0B,CF,2E,20,76,3C,FE,C2,6E,3A,F4,EA,C7,D5,AF,E2,0A,9A,22,EE,26,DC,A1,A4,56,A0,1D,A8,EA,FD,7D,00,E0,EC,59,2B,97,30,BA,A1,62,38,7C,BA,E6,06,76,7C,CA,98,00,61,23,7F,84,74,1D,BA,8A,E4,F2,09,17,E9,2B,E6,AC,6E,BA,92,6C,EE,4E,F5,91,BA,59,F8,7D,22,09,38,28,B5,93,74,CD,DC,7E,BE,A2,E0,52,8F,24,DC,99,EB,30,EB,01,4D,90,64,D0,AA,D3,D4,4A,92,34,00,46,C7,C3,9C,46,12,BD,53,27,75,85,54,5C,63,3E,BE,82,05,C8,C5,C5,E0,A6,02,1A,F3,70,B0,A6,EE,92,93,00,8E,18,54,F8,C8,70,80,07,9E,7B,55,33,AE,28,34,D7,32,CA,48,5E,2A,85,F9,4B,4B,A2,C8,D8,44,F1,A1,C1,52,F4,73,F5,9F,F7,45,7E,AD,0C,2F,08,EB,E5,35,68,6F,A3,FA,F9,F0,C3,87,70,DF,0E,3B,99,4A,A7,E1,87,43,A3,5B,C6,8A,A2,85,5C,72,21,50,85,71,DC,67,56,8F,7A,FB,A4,74,D4,DF,2C,7A,5F,63,03,E5,4D,FE,AC,C3,F1,C1,AE,E0,AA,B0,EC,34,24,4D,95,7A,FD,8F,57,00,1B,F2,06,94,42,91,62,01,5D,75,55,72,83,B1,D9,9B,D7,A9,EC,E6,A2,B2,01,CC,F9,41,FC,3B,CE,D3,3E,A4,C9,97,A6,2D,74,CF,0E,D2,D3,CF,AD,26,70,35,32,6E,C8,A5,C7,F4,66,EE,63,B1,4E,12,C9,A5,4C,BA,B7,B0,AC,F2,A8,DE,A5,18,67,33,60,B9,16,1D,17,67,19,9D,9B,3C,4C,53,06,A0,F0,B2,14,8F,C3,9F,28,A1,53,E5,15,B6,77,EA,1B,3E,40,32,22,42,FF,24,96,0B,C7,39,24,A0,11,DD,FA,A2,85,B1,90,04,43,47,83,6C,2B,AF,B8,0E,23,77,B7,7F,E4,55,AF,E1,D6,74,C0,4F,B0,02,58,C9,82,E5,C4,56,1B,CA,17,6C,C2,A6,75,FA,19,7C,3B,C5,1E,0E,77,25,31,46,D5,7D,42,AA,27,8E,6A,72,E3,7A,0D,97,10,27,C9,6A,D6,9E,C1,04,FA,0C,8D,AF,9B,74,65,E7,63,A4,4E,A4,27,0E,56,5D,68,29,10,C2,AD,48,C9,4D,7D,F2,62,B0,D5,88,82,64,26,6B,06,81,29,7A,AF,74,12,52,47,2A,0F,ED,4E,CE,67,28,47,74,F2,AC,67,75,BB,66,F0,50,EB,1E,DA,75,7C,85,4E,18,E4,D7,14,CF,8B,D2,6C,16,7A,D2,9A,29,E8,00,AD,A8,03,71,60,34,21,EC,67,77,35,86,75,64,78,E0,34,D2,66,CE,3F,19,0B,00,F9,52,16,BC,0A,7F,2A,18,64,FC,1C,C0,3D,19,45,7C,6D,44,B8,7D,6A,95,4A,49,C5,AC,21,49,1F,12,D3,17,05,1C,43,1F,C6,B3,30,64,3B,C8,29,ED,68,E3,F3,5A,D2,4F,C0,0E,52,7F,C4,F5,FB,1C,50,FF,F0,D4,CB,7A,E1,08,64,75,ED,1D,BE,C6,C5,64,BC,1A,A2,EF,09,33,D8,20,D5,81,E9,59,CB,47,CD,90,D5,95,93,71,C5,89,B7,3A,AB,4F,48,73,4F,2D,E3,99,29,C1,7D,A9,23,71,54,22,F7,44,8C,13,EA,28,CB,8B,09,9E,BC,FA,3D,F2,66,51,65,2F,D2,56,97,1B,4B,F0,5A,73,AA,7C,86,6F,14,19,F8,CD,CF,7C,AC,57,D6,2D,8A,B8,08,4C,90,0B,7F,34,FB,2D,4F,2D,36,12,60,28,FB,7C,DB,B3,6F,C6,F3,8B,64,22,A3,C4,FF,52,0A,AC,7D,A9,21,D4,8E,61,FC,63,80,B1,83,92,A2,6D,DE,E3,8B,FA,E2,9F,58,76,55,12,4A,59,70,1E,A7,BE,05,7B,F2,7C,C5,E8,AA,10,28,A7,33,48,FC,9C,DC,64,43,75,F8,02,29,97,92,60,13,47,34,DC,B3,3F,16,C6,5C,2A,C5,F4,9B,94,6C,2F,4D,BF,1C,83,15,54,EF,8E,36,E0,BF,E8,5E,57,92,17,EA,19,BF,61,31,6A,ED,53,1E,72,D6,E1,54,F4,6A,B3,87,73,69,C3,E0,DF,14,A0,16,22,A0,99,70,85,A1,F9,22,95,62,C1,1A,80,72,E9,9D,80,8A,D2,EE,B1,F4,12,89,4B,42,02,79,B8,4A,95,B4,DC,95,54,CF,D9,CC,68,56,BB,09,72,10,60,53,D8,B9,56,DD,15,EE,72,E1,F3,87,F1,3C,68,68,17,CE,DF,28,CE,F3,57,DD,1A,75,94,FD,FF,C5,06,FA,75,84,F7,B7,11,0A,5C,90,36,95,6D,7B,0A,2E,42,C0,04,72,7C,76,C0,B7,2B,38,FC,8B,2F,64,FE,EC,C7,8F,EC,21,A0,0B,FF,8F,05,19,85,52,D4,00,DF,77,8A,E5,D2,6B,94,15,21,AF,F2,BD,51,0E,C9,AE,0F,F7,73,F3,E4,B6,12,BD,2D,76,B0,88,13,75,1B,79,A1,13,86,1A,FE,C9,A7,73,AA,7E,4C,51,52,AC,E3,D2,0E,16,9B,57,9E,F9,20,7A,77,AD,5F,B2,20,C4,66,9D,E1,8A,C6,7F,E7,F5,4F,22,9C,97,37,BE,DF,F3,23,32,41,47,80,D6,A7,B4,05,DF,42,D0,9D,30,AB,04,9C,BF,54,5B,24,01,32,AE,5A,E2,81,55,F1,CD,68,37,14,C1,76,AE,D7,02,7E,DB,24,C0,A6,09,36,1A,D7,BE,B1,88,D6,83,38,BB,C8,C6,A9,60,FD,B7,08,D2,8E,9E,E8,DF,CC,AE,9A,9A,CD,4A,A7,A3,34,75,0C,27,E0,A1,80,14,99,AB,9C,68,AF,6C,5F,6F,4E,17,69,FD,5D,14,99,FC,A9,41,C0,E2,45,AB,76,22,BA,61,6E,CB,39,C1,D6,70,23,01,26,59,C1,9A,0B,FD,E4,CF,5B,FC,9B,A4,76,08,C4,73,80,AD,66,EC,E2,C7,47,69,02,36,40,4F,45,FE,A7,F6,24,A2,F2,E8,F9,75,81,37,15,B0,18,92,03,33,52,B6,8B,62,64,81,B5,AB,80,BD,84,D7,CA,5F,ED,1B,94,37,B5,7D,D9,51,B7,54,A9,00,7F,B7,3F,F4,99,25,EC,65,5F,5A,B8,61,D2,54,A8,AF,78,9C,7F,76,EF,AF,FC,B3,9F,F8,30,7A,76,86,3E,05,DF,76,43,97,72,A1,92,22,19,57,04,61,E0,D8,C1,A6,B2,AE,BC,95,17,78,85,72,E3,57,B3,C4,5F,D0,B8,60,ED,00,58,0F,85,EB,BA,50,C3,8B,7B,3C,C6,7A,97,E6,6B,2C,48,F1,F9,7B,AF,9F,87,D7,5E,2B,28,73,F0,EF,69,23,25,FB,49,73,86,EE,67,54,78,E8,B7,3C,A5,F8,F6,14,8B,F1,81,72,94,E8,F8,76,4D,28,22,B3,F7,48,80,2D,47,6D,07,DD,D9,90,A5,C1,32,C3,9E,F5,38,5C,2E,E4,BA,34,93,13,14,F7,F1,A4,5C,63,47,25,32,3A,8C,37,88,02,54,A1,54,49,BC,2B,08,60,82,95,A8,59,60,88,C0,2A,36,61,D5,23,6E,B2,FD,71,FF,61,1A,60,F6,09,5B,2A,6A,9E,A9,AA,B6,E2,9D,61,72,C2,64,E7,6B,DE,43,AD,0C,33,21,40,AC,E1,5B,A1,44,64,C9,D8,1C,CA,33,AB,A2,A8,95,FC,CF,AA,58,41,2D,49,E7,20,CA,9C,66,83,41,D0,A2,39,C5,92,CC,FE,76,49,76,D7,A7,46,E0,B4,C3,72,A7,81,F4,11,69,E7,EE,B8,90,DE,E2,3D,D2,9D,65,3E,1F,15,27,EA,9C,E7,7B,59,4F,75,2D,B0,7C,F1,B0,C8,0A,DA,EE,0E,D5,03,1C,4C,BC,8D,51,D0,B7,F5,20,1A,07,0A,1B,3D,75,49,57,22,3C,D4,D6,0E,53,16,4A,3F,EE,97,6D,E7,E1,53,7E,21,E4,AD,AD,08,36,61,E9,B1,6F,40,08,7E,4B,09,D8,CB,55,08,03,41,A0,EE,15,82,00,FD,03,7B,AD,2E,D4,9D,87,BC,77,B2,39,9F,63,05,3F,0B,D6,FB,76,C0,43,72,6A,33,82,7E,22,D2,99,52,E3,B7,33,1A,2F,E4,69,ED,6B,DA,5A,28,91,2C,7D,54,90,52,77,6E,7F,21,9E,22,52,2A,64,37,C7,A4,C4,21,1B,A1,C8,8B,8A,27,1F,62,5D,33,39,B1,89,63,70,3B,78,1C,28,12,3F,FA,B1,C4,F5,78,01,F8,70,6E,4A,F6,23,2E,BA,C2,AB,89,3B,F4,1C,AD,45,FA,AF,EE,F9,41,D8,91,6E,11,4E,D5,D4,F3,4F,36,5B,30,EB,80,20,97,F2,9C,4C,90,95,DA,BE,9A,9A,6C,BD,2D,FE,1B,76,9A,65,53,A9,22,41,10,4A,66,A0,5B,1E,24,AD,00,8B,74,2C,C5,B9,3A,AA,A7,F9,0C,DE,56,60,0B,DF,D5,BC,DD,A4,21,AF,B3,AF,D7,51,10,5A,D9,C1,F5,87,C7,E3,F7,0C,33,7D,42,F2,64,9E,1B,00,54,54,10,07,50,1D,DD,61,47,A3,14,AB,5C,12,64,40,DF,9D,8E,80,E9,21,67,A4,34,4F,34,0F,EB,40,62,C8,98,D0,78,E4,DF,AA,7E,11,03,9A,0E,F6,6E,FD,CF,01,4C,72,57,E4,5B,CD,E7,7C,80,7B,70,88,44,37,01,B3,E8,0A,FC,45,F2,E7,73,F9,D1,C3,FF,C8,03,99,A6,39,B5,5B,5A,10,2D,D2,8D,03,87,FD,B6,7A,B4,71,07,F2,64,3A,50,7C,6F,B1,C4,A7,1A,8C,4C,E9,C4,E6,2C,E5,18,95,8B,0B,54,70,E9,F7,0C,91,80,51,DC,7E,7D,0C,1B,CB,DE,CD,0E,AB,29,5B,04,61,AC,9B,03,37,4D,C2,85,53,27,57,18,C6,DC,BE,17,CC,5B,D0,EA,37,81,72,FD,8E,0B,D0,7C,30,30,F3,03,67,A8,2A,E7,53,6B,88,B4,2D,6B,C9,C0,01,01,16,8A,A1,6D,E6,32,5E,6D,C4,F5,22,E8,F2,DE,74,09,44,8A,A4,F1,80,D1,38,56,96,A9,06,30,81,B7,4F,44,D4,CF,07,BB,71,DE,C4,D3,AD,D2,1E,75,3F,A2,79,79,09,77,5E,9C,BF,A2,EC,68,3D,99,58,7F,C7,D6,E4,DE,C9,E7,10,54,0F,04,E2,69,17,25,5A,12,6F,59,9C,21,32,C4,7A,77,3C,0B,CD,FE,7E,08,4A,3F,3E,41,71,1E,BA,00,04,7C,03,F8,C0,A5,D1,15,8A,42,EF,C2,9B,31,4A,9A,6F,4A,5A,42,C9,F2,0A,B2,C3,0F,F8,D4,51,66,A8,BD,D6,8B,29,7D,88,38,FC,59,E0,69,2F,4B,86,67,34,55,D6,1F,84,DB,41,41,F1,09,A1,FA,CB,AA,1C,FD,B3,67,3F,BC,1F,B4,0D,30,AC,F2,90,F3,27,DE,2E,D2,E5,BE,01,91,8F,89,E3,39,AB,BB,E3,11,80,17,8A,C1,EC,DC,87,49,7A,24,52,26,EB,3A,51,BD,38,CB,9D,93,6F,98,9B,C7,4F,CE,76,8A,C6,7A,D2,4F,70,79,99,D9,29,71,C6,24,06,A4,5F,AB,05,D8,90,14,DC,CC,66,A9,14,1D,EC,58,23,2D,EB,84,E4,39,6A,54,99,22,74,5F,AB,18,16,C4,C2,01,AF,1A,19,90,91,FF,9E,85,DD,C0,15,64,C6,76,F2,86,C9,0C,D5,64,2C,7D,EB,AC,BA,FE,34,08,E7,0D,CD,5C,F9,69,47,A1,33,C4,7E,09,F3,CE,88,34,A8,FE,B4,CD,C7,4C,9C,77,4A,29,7A,84,BF,C0,F3,DF,6E,2A,AB,C6,B2,8E,7E,20,CD,85,4A,DC,9E,64,2C,0A,2F,78,F3,93,DE,24,5E,58,A4,5D,64,C8,C8,BA,1B,BE,B0,AB,C3,AD,70,7F,8B,0C,EA,A9,94,1E,D1,39,07,44,A4,52,53,DA,71,91,6C,1A,8E,85,DC,B0,6F,48,19,8F,DE,F3,E2,17,8A,62,A3,BD,65,48,FA,B9,49,BD,01,7B,15,7A,A5,E5,BF,B1,81,17,16,2F,8C,47,C9,D1,63,52,39,B2,6C,84,02,D1,D8,1F,92,D1,6E,ED,53,8C,3E,C2,03,23,93,78,8D,A2,65,38,9C,52,B4,4F,0F,86,BF,F6,D0,0B,0E,0F,0A,D7,C7,87,F0,D8,9E,DB,EA,FC,EE,BD,E7,4F,B8,63,11,6D,B0,27,48,4A,57,98,5D,B2,87,D7,F2,82,D4,29,03,85,80,6A,88,A0,D0,6D,B1,22,E3,8A,BE,46,93,40,89,B1,30,62,EA,4B,81,7C,BB,BE,44,3A,2A,A8,54,A7,39,E1,C7,99,A7,33,F6,32,3E,CF,16,3B,A7,24,1B,43,16,A3,E1,70,C8,43,97,49,57,F0,85,E2,9D,56,D1,62,80,66,23,49,21,54,13,05,E4,2A,2A,29,C8,5A,33,D1,A6,5B,E2,DD,C8,8F,68,8A,CD,4E,2E,61,DA,E0,75,E9,96,94,50,CF,AB,A0,B6,E8,A7,F2,C4,42,8C,B1,FE,FA,0E,4E,85,B1,65,C6,07,0C,FE,84,41,FD,69,88,69,34,F6,E3,69,FB,BC,43,42,4A,C6,14,BD,12,0C,33,5C,A1,3F,70,B0,0B,57,B7,F5,B1,C7,78,DB,42,8B,EB,8A,32,17,CC,AB,60,BE,DE,EB,71,C9,9B,81,F5,BF,7C,3C,20,74,CC,AC,F0,8F,CC,EB,FC,1C,5F,14,C0,BE,9F,5A,E4,93,93,5D,C6,44,D7,C4,EC,69,10,80,7D,C4,62,80,3B,23,F4,8B,12,9F,F1,C0,57,C2,AB,B6,1F,9F,57,84,64,94,C3,7F,69,9F,7F,CF,14,A1,F0,28,A0,15,AA,76,27,DB,D5,66,D0,2F,89,15,1A,CD,A3,8C,02,67,DF,8C,02,B4,A2,EE,17,A8,CE,1F,83,58,40,C7,2E,75,20,D4,9B,11,96,87,94,29,FA,C3,17,13,8E,BA,E4,D6,6F,2A,78,85,76,B4,99,82,0E,07,9B,05,51,F9,F8,E6,8A,1F,87,F8,EB,27,D1,ED,3A,C5,14,F2,C8,F4,B1,A3,53,C5,21,D0,28,7E,82,02,A6,22,F3,19,B4,E1,82,0D,2D,1A,54,D1,28,48,0D,58,69,6B,8E,45,F1,70,DC,B0,65,8A,87,46,B8,5C,04,8C,A6,E6,FA,06,DB,43,B6,0C,37,ED,A0,8D,E2,A4,A4,AD,22,8E,A8,1D,B4,D3,66,62,A8,DF,13,20,DC,8F,A3,AA,E1,19,26,A5,91,AA,A0,B1,14,6B,B3,2A,78,76,40,A0,15,E7,A2,E1,27,34,F1,A9,B6,89,5A,16,C9,86,D9,7F,5A,BC,51,AC,77,5B,83,C7,2B,68,DB,04,FC,35,F8,66,C3,46,C4,7B,3A,85,1F,7F,77,FE,97,85,64,F0,77,7A,37,5D,33,D6,A0,EE,7F,F4,21,16,BF,F5,D7,C3,EE,B6,30,4B,76,E8,7F,91,24,40,9F,09,E1,4B,CE,6B,4D,1B,A6,22,C9,2A,3A,4F,B6,96,A1,55,29,39,99,DE,45,B4,07,C6,D9,92,C7,5B,01,1F,3A,D7,4F,33,99,BD,B4,6D,EA,1B,DA,8E,F3,38,12,F8,E7,B9,DF,3F,86,F2,86,92,51,48,04,6D,AF,5E,6E,5E,00,2B,DD,73,1A,6C,10,CB,68,60,80,15,F5,B4,46,F6,41,12,73,FE,52,0E,C5,3B,28,C9,B5,CA,DB,8D,8B,EB,3C,89,48,C8,CA,C0,75,41,33,46,C9,4E,15,B1,2A,88,9D,04,CA,EE,68,CE,DE,67,6B,2F,38,74,D6,43,12,E3,C8,F5,07,5F,65,66,03,B0,28,31,A0,D6,AC,50,5F,D0,11,D1,FA,F3,20,C2,0A,9D,EB,C7,E7,FC,C1,8C,39,09,C6,5A,72,A6,68,18,54,F9,2B,CB,B2,E1,2B,FF,37,58,96,71,E2,28,6F,6D,7B,CF,F2,B7,FF,42,D0,93,53,A3,36,76,74,D0,CB,D9,27,90,07,DA,91,33,EB,60,A2,51,0A,5F,44,C1,9D,B5,2B,30,D3,5C,EF,D9,57,97,9F,1C,22,A7,AA,34,87,E1,08,3A,29,BC,77,D5,4C,E6,DE,AF,D4,BB,ED,19,E3,AA,D6,D7,68,AD,FD,F4,46,E2,60,FE,64,64,04,1C,A8,04,95,2B,09,6F,1E,0C,37,1F,56,C3,AB,98,0C,6C,55,B4,F5,B6,5F,3B,64,B5,6F,5E,FC,E5,89,74,B4,E1,5A,CD,68,3C,52,FA,0D,EF,22,F8,97,8F,24,BC,E7,1C,D1,9F,FA,89,88,E0,BD,54,6A,E1,4C,44,9C,88,2F,C1,DA,0B,D7,7D,C8,98,2D,52,63,0B,62,CB,75,FD,DE,34,63,B7,0A,1A,9F,64,49,4A,41,FC,1A,D7,D2,34,BE,44,78,6F,04,0A,81,7B,91,FF,31,10,EC,F0,9F,15,6A,F1,A3,E2,61,69,FF,0F,3D,D9,74,50,DE,2C,D3,B8,36,D3,52,6D,4D,AA,0A,DC,7E,5C,C3,2A,B9,64,CE,31,0D,7C,06,1C,B4,77,98,4C,A1,AB,6B,BB,8B,E3,D1,EA,09,CB,C1,23,50,89,72,A0,15,12,B0,DC,B6,54,67,71,95,1E,CD,53,25,53,7A,74,84,8B,98,C4,EB,A5,DA,EB,4F,6C,15,FE,AD,26,E6,94,2C,8D,7C,0A,64,24,3E,3E,E7,79,A7,56,92,C8,82,DA,63,D1,A5,1F,51,0E,DA,48,57,92,3A,C5,6E,A9,E3,F5,5A,EC,17,A8,5A,1E,64,A3,B5,C6,AB,6E,C5,EC,21,5B,E3,E9,61,AA,DE,80,51,32,05,FD,13,FE,51,66,46,ED,9D,25,9B,34,F5,10,C2,24,42,22,93,67,5A,CD,0F,02,19,1F,D1,4E,A1,5F,FF,BF,C4,51,47,87,9E,41,46,C4,8F,DC,E3,0C,13,55,F0,73,E7,16,96,17,F4,C0,3A,24,2D,DC,77,47,03,CA,8F,1E,6D,64,93,88,5C,58,7B,9B,8D,A4,31,38,AD,38,BF,94,47,87,36,44,81,9D,8A,9A,1A,D5,F1,00,45,3A,6B,80,E2,87,B1,90,FB,8A,4B,13,F2,51,8E,F7,FF,4D,C4,A5,D5,F6,4E,05,B1,C3,6C,73,91,64,E6,4D,CB,E5,FC,18,FD,BD,B2,EC,FF,FC,0C,FA,F9,E4,96,CA,6A,3D,7D,B5,C6,4B,EE,24,14,12,3A,2B,01,0D,EE,CA,20,A7,7F,39,91,1E,D2,9A,2C,E3,75,33,51,67,B8,07,CD,88,C7,AC,09,C4,04,58,14,0A,31,57,B5,78,88,49,8B,07,4E,B4,42,D3,C9,BF,F8,CF,F7,20,1C,9A,94,9E,60,24,DC,05,30,60,56,3F,E3,1C,D1,75,51,82,0C,D7,1E,A3,2B,01,D4,F6,6F,EC,BE,AD,BA,B0,47,22,5B,05,2A,8A,E2,09,85,00,3E,CA,0E,52,65,A7,AA,3D,FC,38,C6,D6,3A,6E,A1,1B,99,59,D4,28,C7,7F,54,61,0F,A8,A0,49,D8,4A,62,92,2A,1A,41,86,52,4E,D2,D9,B6,8B,56,EE,3D,D3,40,79,C7,86,2E,49,24,9A,A3,76,BC,F8,8D,E2,16,05,39,41,58,0E,F8,E0,84,F0,56,3E,EF,8A,0F,D1,B1,B3,92,F1,77,AA,DE,D6,19,BF,38,20,18,EC,36,D6,0C,74,A2,0D,61,1F,B0,CA,94,8F,32,F2,0C,C9,F1,CA,D1,6D,0D,5A,6C,51,EA,4D,89,AE,3B,6B,E2,DE,E0,9D,29,78,EB,96,EA,27,8F,40,4E,96,A9,C2,0E,51,30,52,34,F4,6E,F4,FA,68,56,E8,C7,2B,09,8B,F1,B3,06,F7,79,A7,D5,EC,FC,A6,AE,1F,1E,C8,1C,00,AC,13,8A,6B,3B,B0,C8,D5,86,90,CD,5E,69,12,D4,58,7B,D8,2E,29,28,8A,BF,0D,8A,61,A2,64,45,9B,56,4F,73,8A,AB,C5,48,55,2F,01,D6,C9,37,CC,8B,31,DF,C1,72,77,CB,FD,D7,E2,F8,15,81,B6,A1,63,19,E9,A1,F2,39,11,F8,B9,61,5D,39,C5,B4,BE,FE,A7,B4,A9,19,33,3C,F5,6B,2D,43,DE,35,B7,75,67,E3,FD,EC,0E,38,96,28,FE,57,A6,D1,60,48,87,C7,A9,68,DB,BB,20,47,77,64,8F,F9,77,D1,C9,EE,60,F2,95,5D,D5,B1,06,39,4D,F3,40,52,A0,E6,F6,12,F9,36,F1,F1,30,14,49,08,04,8C,B5,54,DA,AD,CC,51,27,2A,1F,F8,FE,44,70,81,7F,96,20,46,01,BB,EA,F3,21,54,C0,5F,84,F8,82,57,24,B4,D8,BF,F9,B8,76,BB,CA,78,94,7D,E9,EC,2F,FF,1F,67,1A,42,27,1B,32,29,85,0A,AD,16,36,4A,6F,C6,02,03,88,94,86,0D,A5,55,60,9F,F0,E4,F6,05,72,A6,43,A8,68,6D,AB,54,26,2F,EE,25,0D,DD,67,41,57,51,08,F5,6D,39,4B,D5,96,96,E8,84,2D,15,B2,1D,21,2A,BE,8B,1F,B1,3B,38,24,14,E1,B5,22,7E,E7,BA,0A,72,3E,62,7F,B4,12,42,78,8F,17,C7,64,AA,FC,8E,94,79,CC,E3,29,49,D9,A7,84,D3,C9,BF,D7,13,B8,7B,1A,B2,72,B6,EE,C9,D6,F2,79,85,E2,7F,08,D9,7A,C5,C4,32,16,6F,C1,7D,D9,2F,22,99,60,EF,DF,DE,09,0A,4B,93,74,80,B3,4B,CA,43,1F,68,FB,3D,6A,9F,15,31,B3,9F,EB,E1,1D,36,E4,C1,68,AD,C4,56,D2,83,BC,DD,D8,7E,5B,25,F6,E7,06,79,5E,BF,94,D9,CF,7A,1F,2D,1B,51,3E,55,90,90,67,B6,E6,B0,E4,3C,8C,2B,A2,57,5C,6F,B9,37,50,07,B7,C5,C4,8E,AF,5E,89,36,B7,49,10,0E,E8,EF,5C,95,D9,0F,3F,48,1F,E8,80,68,EA,26,E9,7E,0D,38,4F,82,09,61,97,12,5A,55,E7,38,8B,0B,21,C1,CF,A4,E8,81,BE,60,71,13,84,C4,1A,96,FE,84,A0,3F,0A,29,77,9F,6C,E6,26,61,78,EA,8D,3C,C7,94,28,BC,9A,FE,5A,35,AB,1A,13,53,D3,E7,91,6F,52,25,07,5D,E2,BF,97,C7,C9,EA,FF,A4,63,00,42,85,38,13,EF,FB,4F,62,66,D9,D1,6D,8F,0C,87,EF,8E,8B,A9,11,40,3F,38,9C,EC,18,06,6A,6E,44,51,F9,7C,53,6E,8E,C3,9C,A6,90,CD,73,F5,E0,3C,9B,58,60,45,40,FE,9B,EB,52,91,AD,E2,CC,F6,95,84,52,90,06,9F,25,DD,31,B8,B2,69,57,83,98,C0,40,8C,F7,AF,F2,0D,0A,03,7E,DC,BF,66,4B,D1,7E,AB,D2,41,95,7F,04,89,61,7D,98,69,43,EA,28,53,B7,BD,72,B4,25,92,0F,52,AC,04,48,28,45,E4,8D,69,C3,C5,69,88,AE,D3,07,05,72,BB,94,53,5F,30,36,C5,A4,85,AF,C5,05,30,1A,00,22,8F,FA,B7,F3,91,6C,5E,ED,9A,34,03,80,66,16,A7,C5,0F,72,3B,05,87,E3,66,83,3F,C6,2F,F6,E5,A3,C0,0B,EC,BB,1A,F7,FB,4D,A4,FC,91,CF,EA,2C,67,FE,4A,E9,E8,A0,4F,0D,33,2C,0D,08,07,F1,08,54,53,CB,F2,75,90,C8,4B,0A,C6,2D,82,79,83,5A,2C,CD,48,77,A9,8E,24,8F,37,28,D6,2F,42,16,7A,96,A6,B2,55,85,DE,36,15,DC,FB,F0,E1,72,9A,44,40,44,BF,42,93,91,07,F9,15,E0,65,BB,82,56,74,D8,7A,5D,D3,87,22,82,00,A1,CA,9C,25,2E,A7,44,7E,32,B2,55,7D,D3,15,88,36,1A,CA,C3,69,1D,E4,E6,78,BF,9C,62,5A,2F,4F,CA,84,C8,6A,2E,2A,AA,09,3E,8A,71,32,9C,FF,78,A5,C9,73,A4,2A,7A,DE,84,D9,A5,07,C4,72,9D,BC,62,D6,21,09,43,95,55,D6,6C,AB,FF,DA,6C,5A,DE,AC,8F,33,91,8A,2E,7B,D9,1E,BB,BE,3A,19,18,E7,E5,A9,0C,34,BB,26,CB,FA,58,32,00,9E,48,E6,D2,96,CA,CE,D7,6A,7C,E1,0B,2D,16,2E,AD,D5,40,27,52,94,A1,E5,B5,8E,27,B0,0D,D9,57,2B,48,2C,9E,96,14,F7,D7,FA,6A,3B,43,25,26,1B,A0,BB,3B,54,DD,51,E7,3D,57,52,E4,C4,22,40,20,5E,4B,F1,CE,E1,9B,3B,04,C2,C6,94,46,54,51,D9,FC,74,C4,5F,76,14,CA,56,0F,0C,B8,6E,EF,E7,14,B7,A5,7A,BB,3B,F1,6A,EB,70,E8,7A,C4,32,53,23,FD,B5,B4,D6,30,EB,F2,A2,57,A9,71,39,E1,87,B4,60,E7,08,BF,47,6F,72,24,5A,37,22,A2,23,33,80,FE,E1,E0,11,7D,56,68,73,E8,DE,3A,46,03,2F,5A,84,C5,98,8C,5E,D8,20,7B,20,31,60,B9,F5,FB,01,A0,E5,9E,16,F1,1F,15,6A,0C,06,1C,1D,55,02,A3,61,4D,04,07,DF,14,0A,F5,5D,BB,A4,56,B1,86,C4,0B,8C,CF,4B,90,C2,AD,03,95,4A,14,1B,B6,7E,B2,5E,E3,E5,01,9A,12,98,AB,AC,7A,4F,52,42,D8,AE,B8,C1,48,6A,BF,ED,F4,98,7E,A0,FF,60,62,C0,26,B8,15,B0,CA,3F,5F,85,EA,6E,86,D0,E3,AA,5F,95,71,0B,4C,9A,05,DC,AF,E1,04,64,33,E2,36,5A,7B,13,2B,9E,A3,01,06,40,DA,D6,06,5C,A4,BD,FD,76,50,68,E2,E7,50,AF,BC,92,2F,75,B9,8D,F1,6A,51,AA,B8,69,FD,AD,2F,57,2A,06,AE,90,B6,E7,85,E6,7C,E2,89,9B,C5,D1,1C,B9,54,F5,2E,C1,FC,46,1C,EF,87,79,45,E5,82,33,BD,78,F1,8B,DC,20,E5,7F,4C,2F,8B,7D,F8,4F,37,C3,06,CD,59,51,2F,DF,AC,B1,AB,B0,1A,92,16,54,4C,8E,97,36,AF,B1,45,67,16,C7,6B,6A,D2,E5,93,20,C1,B0,99,37,26,40,A6,DD,57,8D,98,E4,CA,4A,F8,3E,BC,75,BD,EA,6F,FD,BD,F9,A8,86,DB,86,1E,69,76,AD,A7,AE,D1,D4,94,12,5E,26,28,40,7C,25,54,D6,F9,63,84,7F,C9,4F,E3,37,CF,E9,FD,7D,9A,47,65,C2,C2,F4,F4,44,66,F4,29,75,E4,87,64,6E,03,72,74,98,42,E9,10,C2,4D,64,A1,58,ED,10,D2,B3,83,AE,4D,DE,99,89,BF,1E,90,EC,9B,03,DA,F3,40,04,DD,42,52,C8,1B,0D,A2,E1,6A,1D,09,F8,CE,C6,29,8E,3D,86,E4,BD,5E,5F,CD,6C,9E,D2,0C,44,81,EA,4C,BA,A3,F9,88,FA,96,BD,32,CA,F8,C5,85,03,4C,42,20,B6,C1,7B,CA,6A,6D,39,EA,F7,3F,9C,7A,9D,96,FD,86,7C,E5,C1,34,7C,B1,20,20,5C,12,35,25,CE,05,97,51,6E,F9,B0,39,13,33,E1,E6,BF,62,85,E7,C1,59,09,81,53,43,8C,A6,35,E4,95,3F,9E,C7,A2,0B,07,A5,3C,E8,0E,21,BA,61,DE,47,8A,87,F6,CC,88,8B,14,05,0F,16,C2,72,36,13,71,FA,81,3E,48,41,B7,95,9A,32,06,7E,F2,F8,AC,1E,69,BD,97,EF,E8,B8,69,97,36,EE,F5,F3,A7,75,26,73,3C,38,C2,46,BC,47,43,D7,A7,55,BB,A0,25,4D,09,46,E2,AC,D3,E9,52,DE,58,C1,69,D6,B5,3C,4B,12,D3,76,E5,4F,BB,20,6A,FD,D4,B3,F7,FC,61,6B,BC,02,42,FA,52,BA,D3,32,90,4C,57,D7,22,C0,24,03,91,6F,A4,55,21,54,7E,6E,CF,54,CF,9B,DB,7A,06,76,EB,D9,61,EA,85,D8,F6,2B,53,2A,4B,43,DF,FA,DC,3A,A0,F4,41,6B,CD,EE,09,B3,BA,7D,19,CC,65,78,51,F2,65,30,46,82,2B,55,0D,C4,6F,50,9A,59,53,5F,4F,69,C3,57,00,AD,F9,C3,04,58,63,1D,81,DD,DA,10,22,F8,F2,1D,C2,C2,69,E1,66,06,C0,7E,C8,1D,B7,46,F1,9B,56,84,05,B4,19,8D,0E,92,8F,C8,4A,AB,77,97,5A,4E,62,AE,05,74,67,D4,99,F2,4C,9A,2E,BC,BB,40,13,1E,F9,B8,1E,6A,3D,D3,0B,24,65,02,D8,06,27,1B,32,8D,AE,2F,54,F9,5B,91,77,87,10,E4,23,4C,DD,48,07,9D,75,8A,B1,66,B8,12,44,26,85,42,0D,8A,67,07,1C,7A,20,99,02,78,21,07,65,DE,EF,66,3A,BB,38,FD,F4,34,B0,97,71,F6,FD,32,D9,90,AF,13,BA,DA,54,70,3A,B3,A3,D2,14,F9,B7,73,4E,75,3F,A6,0B,C8,53,E5,95,6D,E1,D3,08,20,8C,91,86,5C,83,69,4B,A4,F5,DA,7C,A6,F5,12,73,60,7E,80,8C,50,70,78,F5,FC,3A,31,60,85,F8,84,17,28,E3,05,51,E1,89,20,08,68,59,24,F8,3D,C4,18,D1,58,00,55,CA,11,FD,73,A1,58,20,A5,41,22,34,C3,68,39,DF,9C,0E,C3,87,04,AF,81,08,3A,FC,7D,00,B7,8F,13,D5,BA,80,FE,78,7B,EB,D4,4A,D0,93,D1,8C,6D,D4,40,33,7A,FA,02,EC,E2,95,6A,D9,C3,D4,D4,F1,F8,DE,C5,8A,36,42,70,75,7A,D6,5B,C0,E7,04,EB,1D,2E,D6,75,FB,94,D4,3F,39,B1,D4,20,9A,A8,F8,A5,29,59,9A,90,E0,79,6C,A6,A1,3A,0F,48,05,90,14,45,AC,DE,51,E3,10,69,19,41,D5,1C,22,E8,C7,CF,8D,F5,09,CF,BA,1C,D3,AB,39,35,CF,7F,E1,BA,F4,1F,55,03,D4,D1,8B,A0,AB,CC,57,7F,5F,E7,45,A9,39,D2,A3,FE,08,6D,D0,7C,16,91,E0,B5,6D,99,4E,5F,DD,D6,84,90,E4,05,A5,97,0A,28,0D,C9,A0,2C,0C,25,1B,0F,C7,5E,16,B9,FF,AE,AB,61,58,6E,19,3C,1F,AF,F5,30,2F,89,3E,68,5A,AC,37,83,B9,66,FC,55,FD,44,59,EE,11,D5,47,6F,13,5C,2D,B1,2B,5A,5B,BD,7E,72,D7,30,5A,B3,71,C1,8A,42,F6,CD,BB,E5,8D,8B,E7,63,7E,39,C4,B9,27,48,A4,BE,F0,D6,9B,BB,14,A9,FA,83,2B,20,D6,A6,61,24,3C,00,34,D6,9F,F7,45,29,1A,4A,B0,EC,BE,E2,5B,24,54,BA,B3,64,54,00,44,63,48,2C,45,91,6D,82,33,F1,FA,09,FC,2F,21,91,17,D1,67,82,9C,29,61,68,C8,96,6E,EB,BB,CE,FF,D4,56,A9,92,B6,4F,7D,08,A6,40,7F,C6,E5,0E,61,A8,54,6D,EB,E2,70,9E,79,DC,2F,83,0B,94,3B,9F,F3,1B,61,75,9B,A3,55,D5,0D,BF,BF,00,08,2D,23,11,75,9C,BA,D8,C1,7A,95,5E,EF,2B,FD,90,BF,10,5A,24,E8,7D,DC,6B,BD,9E,40,0D,C6,26,10,BE,4A,0A,46,67,47,88,DE,90,1F,28,EF,99,BB,BE,4D,17,7B,12,5C,6C,E4,2C,A1,62,5D,18,97,94,A7,D1,49,1F,7F,F0,60,68,9C,9C,3A,BB,A2,24,42,B9,2C,63,12,CB,75,A0,BD,AF,1F,25,C3,B5,1B,47,A0,D6,1D,94,72,B8,F5,20,BA,AF,4E,7C,6E,9E,D1,D8,2C,38,53,26,7A,AD,1E,C7,4D,98,74,4A,3F,04,F5,FB,CF,C7,E0,43,77,3B,5E,CD,5B,75,4D,A7,2E,F3,F7,4C,9F,B0,8D,26,CF,DC,3A,FA,CC,48,F0,E2,BD,73,64,F7,B5,61,F0,17,0E,C7,60,69,DD,9A,4F,69,A7,1C,4C,BB,86,86,04,AA,F9,96,C9,26,C5,2A,9D,10,29,33,42,BD,28,49,EE,8B,31,57,43,E9,0D,36,14,A8,3C,8F,28,C1,73,11,72,7B,81,A2,C1,B9,17,16,94,8B,36,C6,40,27,F8,14,C4,24,58,9E,9B,CB,75,11,73,AA,2D,96,FD,24,DF,8B,FE,7D,F0,79,AC,33,7F,3C,9A,B7,88,78,3F,69,73,2C,64,FE,77,89,E6,4E,E2,31,D2,98,9E,59,18,AE,03,01,D7,E9,95,1D,C8,9A,E6,5E,D8,E4,59,E3,B9,34,0D,64,A2,D8,AB,91,EF,1C,9B,1F,84,9E,03,F0,6C,35,57,AE,55,D0,59,38,B3,52,B0,E8,7A,09,5B,E0,5F,B4,8C,5D,75,68,94,BA,3C,A0,1D,78,81,0E,22,1F,D0,88,74,03,A7,6D,99,8D,E9,B8,F7,75,58,E0,FD,FD,80,E3,BA,E9,3E,30,0A,3D,A4,A0,4A,7B,06,F9,05,C9,E0,01,94,66,48,D0,57,5A,96,2E,B8,59,61,BC,D5,92,E7,51,79,48,C7,13,C2,7E,45,FF,3F,AD,20,FD,8C,26,6F,8E,F7,A0,1B,B4,A9,BC,D8,8E,FC,89,AE,6D,76,18,42,82,3C,25,D7,61,64,5E,8E,6F,5D,26,AE,B6,81,2E,2E,7D,24,42,17,94,5C,67,AA,4F,FF,89,90,00,ED,D8,70,B1,F6,1B,BA,64,EA,03,88,63,98,09,4C,0D,B6,75,04,63,71,8D,29,65,35,76,5F,B6,F5,7F,10,DB,89,67,92,54,E5,EE,3C,20,DB,91,5F,C6,D2,CF,A7,CE,18,C2,DB,59,94,20,09,20,FD,86,07,1D,5C,97,2F,6B,28,D3,91,3D,2C,13,F8,51,D9,BE,AB,4E,B2,A7,1F,B7,27,74,D7,EE,32,C3,E4,E0,A2,AA,1A,F9,C6,E6,3B,CE,83,31,69,09,1E,B1,8F,7E,FE,03,29,C9,AC,97,AE,FF,8B,F2,7C,AA,5E,AA,DD,5E,86,7D,C2,8E,81,A6,B9,3D,CA,20,78,87,39,A8,F4,BC,7B,19,46,6A,1E,34,39,F8,0C,3E,BA,21,DD,89,25,26,A8,99,34,B5,EB,16,F1,82,27,51,7A,B1,84,29,E2,A5,88,BF,0D,26,1B,46,E7,51,63,F6,C8,E0,2D,D6,E3,1B,20,88,3E,38,A4,E2,6C,88,8D,85,6D,8D,1B,1C,85,44,DB,58,46,44,5C,40,30,8B,D3,24,0B,D8,96,DD,DF,FD,63,04,73,56,09,E5,34,A7,16,88,17,AE,D2,73,4D,70,9F,98,01,59,B0,10,7C,94,FD,80,CC,4F,76,1C,05,C8,CA,43,14,80,CD,B1,15,67,59,8E,3C,49,9E,A5,9E,B2,94,BC,7C,CE,12,2A,88,F1,C0,21,25,09,EE,58,BE,EA,CA,29,30,17,C0,D3,C3,D9,2F,8D,60,85,5E,C8,2F,83,E2,3F,1C,CB,10,BB,35,0F,0D,31,49,21,E9,F4,92,05,CD,52,4B,EA,30,C1,32,05,C7,F3,EC,19,02,0D,3B,04,0F,7E,FD,24,FA,82,DA,EC,9F,24,5E,9D,2E,70,A0,D1,07,06,70,A6,E0,40,1A,B2,EA,64,A9,AD,F7,5C,B6,59,B1,A3,77,45,63,53,06,14,35,5E,F8,65,02,B3,A8,6F,B1,3B,57,19,F9,D8,4B,7D,D4,ED,3C,DE,B6,CB,CA,85,E3,BC,6B,2C,38,00,83,CD,76,E9,55,F6,62,4D,F2,B7,8C,04,53,0A,1B,87,AC,09,A0,39,71,ED,18,5C,30,21,AF,1C,26,0F,48,E7,8F,D7,D7,E7,9B,F7,89,06,CB,55,F4,C9,54,21,C1,11,7A,ED,87,9A,A6,81,5B,13,AE,83,4B,86,31,E6,C8,71,0D,81,CE,A7,5C,B2,64,49,19,4E,08,27,38,82,3C,68,1F,89,39,83,78,93,E0,E9,1B,BA,F8,24,09,7F,3F,74,9F,9C,03,B9,2E,47,49,37,F3,2B,66,20,25,AE,36,82,E6,46,60,98,8D,AE,CD,6A,74,36,CD,AD,AE,22,64,F1,30,9C,B8,2E,9A,E2,7C,EF,FB,7B,68,52,BF,AB,D7,67,C8,34,AF,2E,05,82,6C,B6,7C,8C,54,C4,9D,17,C4,CF,83,84,A4,9D,F0,83,5C,E5,A6,C7,0B,78,6E,3A,E0,F7,4F,B8,A1,AB,74,0E,ED,BE,53,77,2B,82,76,DC,32,98,C7,05,6A,0F,DD,85,F0,85,18,EC,B0,74,43,4E,79,DC,48,03,C5,2B,14,5C,20,4F,16,45,D0,C8,B1,F5,0D,24,80,4B,D2,56,0B,F9,E2,41,C0,18,F3,81,66,DC,BF,2F,8C,D2,B0,47,B3,79,C3,49,68,DA,FC,38,D1,E4,C7,F0,45,4A,4F,93,B7,7D,B3,4F,61,1F,D6,5F,4E,7C,6D,5E,3A,51,10,CF,19,29,FF,04,55,D7,B8,8D,C5,09,C2,50,02,70,CF,24,94,5D,C5,2A,01,46,36,CD,10,46,5E,66,C2,BF,D4,F8,AD,EE,59,FE,E9,09,D7,CB,E8,52,AE,46,65,9D,69,E6,16,94,09,90,61,CD,85,A3,E5,94,49,24,F9,E6,E9,1D,B3,B7,04,8A,F4,5C,FF,78,20,D6,2A,9E,8B,31,37,19,9C,76,5C,9A,A2,14,D7,FF,3D,A2,EF,37,BF,92,95,EF,87,0B,DE,7C,FB,9C,B3,DB,C1,63,1F,CF,12,7E,31,F5,3D,90,39,77,EC,D0,CF,64,73,03,F5,D4,1D,0D,43,AD,ED,E7,07,2C,86,5A,67,70,46,BE,01,C5,A8,F5,95,83,71,9D,00,08,A8,8E,64,03,2D,C6,15,0C,B8,B1,65,31,D3,9E,37,71,E1,D6,50,01,25,64,0F,AE,39,5B,8C,D6,9B,32,E4,DB,18,C7,61,BB,93,8F,56,71,79,4C,32,FF,E8,59,08,3A,F0,3D,F6,4E,BD,CE,25,C9,3D,56,35,C7,4A,04,1C,88,38,74,C8,26,CF,F4,22,AB,C4,4F,CA,EE,F2,17,04,86,DA,EC,C4,DA,B6,EE,DD,F0,DD,10,4A,33,29,62,25,3F,0A,1B,51,2E,D0,A4,24,6F,AE,F3,21,DB,C1,4C,B9,9B,CB,92,B7,00,BB,C3,66,57,94,43,CF,A3,78,9D,EE,FA,20,5C,05,4D,9A,BF,7D,82,FF,BE,CA,38,3A,47,A4,EF,27,4C,63,28,58,C2,EE,CA,60,11,79,63,41,BC,ED,6B,4A,F5,57,23,3F,01,12,82,13,98,F1,07,81,FE,C3,E1,A8,FF,94,06,09,0F,67,BB,BB,61,18,55,50,D1,1E,51,01,E0,9B,AD,A9,A0,F4,1A,E7,9B,A3,96,07,34,58,85,C9,D5,BD,BD,F6,B5,F6,08,C9,10,B2,44,F9,60,00,E4,0E,1F,BC,A8,E7,51,17,56,A9,01,B3,3F,31,C1,BC,52,B1,88,EB,4F,51,AD,0E,30,B6,FE,23,85,05,86,11,68,D8,6C,9A,09,AF,9E,B7,D4,7B,07,F0,35,12,51,A9,65,B1,F3,7C,37,D9,D4,C8,C1,3D,E7,34,DE,2B,22,53,0F,45,C2,2E,B6,3E,D4,F6,C7,05,A1,26,66,38,59,55,C0,3C,65,31,7A,34,AF,30,57,64,DC,22,61,EE,12,9D,0D,4A,AD,72,86,DC,B8,FD,D7,43,AA,95,16,C8,52,7B,70,D7,7C,DC,01,EC,0C,09,B4,A5,7E,BD,2A,D2,A1,98,B5,D1,56,A2,8E,CD,AF,83,0A,4B,FA,95,6D,D6,57,08,CC,60,F5,45,3B,D2,5B,D3,32,C3,1A,1A,3D,A3,EB,D2,19,DE,7C,F1,41,D9,62,40,AB,54,2E,8F,20,3B,45,DD,5E,D4,24,60,A4,3A,2A,EB,6E,06,FE,67,00,C2,D7,EB,29,06,80,CA,25,DD,64,D7,4B,E9,68,0F,9B,02,66,42,5C,2C,5E,CA,D2,84,CA,94,CB,B2,90,D5,A9,02,FC,31,A8,75,79,4F,F7,0B,04,D4,01,50,55,86,22,1D,7B,B1,5A,A1,9B,D7,7C,B6,B2,B5,DE,19,1C,72,B3,62,52,37,B2,BC,42,0C,21,35,7D,F8,E3,DE,D9,A3,4C,66,A8,A0,30,E3,14,2F,D4,9C,52,CC,69,ED,B6,83,B9,56,27,50,46,35,FA,F6,14,73,48,74,9B,84,F0,B9,56,5B,F9,93,13,C5,D7,AC,B0,DF,66,4D,EF,D0,76,8B,8C,1D,A1,36,0B,C4,B6,C0,8F,BC,74,AE,1E,82,CF,E0,22,10,0E,AF,B9,05,80,4F,0C,92,09,4E,FC,7D,80,22,9E,C3,67,08,A3,7B,50,A5,0E,BA,CA,E9,FC,C3,92,B7,B1,80,B4,0E,E4,A3,00,E1,92,A5,25,FC,04,91,79,F9,2E,A8,0A,B7,08,ED,C7,5B,51,3B,7B,0D,A6,2A,44,50,F1,5D,1C,EE,82,EF,7E,F9,C8,07,4C,F5,65,EA,6B,7E,31,6A,71,14,D7,A4,17,51,86,1F,7E,3E,56,C1,C8,E0,A1,A5,85,28,58,FC,31,07,F6,4F,F0,60,76,BE,12,02,89,5A,28,F8,2E,FB,BF,EC,D3,A2,95,32,44,B8,96,D9,B1,A1,E0,38,7F,EC,23,92,CC,AC,54,35,82,C0,B2,8C,56,2A,35,81,AE,3A,D2,3C,6F,43,A8,C3,54,8A,D4,41,FC,47,15,02,0E,83,A6,39,BE,5C,66,28,F6,60,57,49,B7,62,62,8B,A7,F3,F5,0D,33,D5,E9,DD,43,33,C2,5C,11,89,F3,19,AF,62,1A,97,49,0D,66,82,27,9E,C5,B0,8B,D2,11,51,1D,E1,8F,65,8D,E9,48,A4,D2,2E,E9,A2,9A,76,C8,48,3F,F3,C7,23,06,4D,AA,5E,5C,50,A3,A8,25,65,17,3F,42,F4,F7,4E,DA,1D,A8,DE,6E,98,80,8E,9A,C7,8B,F5,CB,54,B1,2E,F2,51,8A,62,F8,A9,5C,BD,11,73,4E,60,B3,65,4B,B7,A9,84,D1,1B,0B,71,E3,FD,D7,1B,4B,25,51,B2,5B,D5,7F,EE,B6,5F,BE,CA,E7,EA,A8,62,8F,D3,A7,55,CE,17,DA,24,03,2E,72,C6,0E,5A,69,BF,25,C7,9E,DD,19,94,9E,76,C1,FB,1D,FA,1F,E6,36,FD,56,4B,B6,29,98,DA,EF,F1,BC,E3,8F,AF,9E,EA,E0,88,3C,8F,AC,3A,A9,67,53,08,DF,69,E1,02,7F,DA,31,6E,AA,E8,5B,1A,1F,78,2D,E2,51,4A,82,09,16,5E,55,12,5F,CF,EC,6A,3D,AC,71,E9,BD,0D,7B,FE,CB,AC,EA,C4,3C,FB,A5,F5,C5,D7,E8,27,E3,01,7A,4E,A7,FA,8C,92,58,9A,7F,6B,44,C3,E6,45,3A,F2,48,7B,B7,03,3A,7A,0C,C1,AA,A4,16,13,28,71,4A,64,D5,39,CA,E6,6D,69,04,81,ED,C2,EB,1A,F1,7C,64,7F,BC,E1,40,B7,0B,AA,16,9F,DE,47,68,7E,BA,C4,11,25,30,D0,58,54,DC,73,0D,66,0E,3D,BC,F5,92,D2,1B,4E,D8,49,2C,F8,2F,C3,07,C8,ED,06,85,F7,7F,B1,F4,04,05,26,37,92,3F,8B,F4,8D,81,95,4B,39,04,34,D2,7F,3F,E1,EB,3D,74,DB,E6,31,35,92,70,07,10,42,C9,81,8C,F7,F5,F6,9A,A2,B8,DF,70,69,6E,F0,D2,E4,EF,B4,B5,BF,FF,5D,79,CE,7E,81,70,86,AF,8C,15,79,02,3C,92,97,59,7B,D1,57,54,DB,BA,43,5E,3B,9E,16,DF,FC,94,F4,49,B7,15,6E,AE,54,C2,AA,D8,22,5F,5B,F4,3A,E0,EE,54,CF,93,E4,75,9B,36,A6,D5,DD,20,B3,B7,99,51,1C,EA,19,98,BA,DC,28,FA,F2,A5,90,1B,50,D3,6F,D4,B8,A0,C8,59,D5,84,A3,EE,63,F1,D5,62,35,97,AD,33,4E,02,A5,C9,7E,4C,E8,C4,41,81,78,9F,D6,78,87,37,B3,FF,8E,F2,56,C6,E9,C4,DA,16,8C,FD,E8,F5,8F,05,E3,2C,A6,C4,D4,04,88,33,49,28,6E,24,9F,DA,D3,37,94,5A,A1,3F,A9,F6,F9,FE,EA,3C,25,17,61,6E,EF,DF,C8,EF,8F,D2,3B,85,21,78,87,8A,EE,75,81,9C,FF,41,CC,AF,EC,56,04,43,81,77,7E,13,65,DC,20,2F,F1,52,C3,D1,49,B1,28,67,21,94,CA,61,26,02,16,73,05,D8,1A,B9,0A,11,25,39,67,59,72,B1,8A,BE,38,9C,0C,0F,E6,49,EB,5E,CD,FE,81,35,44,E6,DB,55,F0,A8,4C,8C,C9,9D,CF,CC,BA,33,97,69,5D,01,DF,D2,3E,B6,A0,9D,73,69,84,9A,05,5A,31,2B,FF,95,0C,B8,5A,2F,F2,63,F8,0D,22,8E,58,E6,46,7F,0B,B0,68,B8,EA,DE,0F,01,C8,A2,BB,32,6F,47,58,C6,70,74,07,98,83,92,FC,96,31,F8,D9,1D,32,4B,AE,5A,69,1F,BD,E8,E1,99,9F,67,CE,C2,5E,27,A2,64,64,B8,46,EB,B3,1E,73,A3,09,CC,C5,23,0B,C5,E7,3D,7B,58,B4,05,F1,42,87,2C,D4,26,BD,ED,A7,E1,AA,5A,20,9D,83,1F,70,9D,01,43,60,E4,A0,72,68,77,B6,44,70,8C,22,41,64,AC,89,D9,A2,3B,CD,3A,35,06,FF,25,36,8E,99,E9,DC,CB,41,35,CE,95,BB,5D,5A,42,EF,95,57,57,0A,93,56,D4,1C,4F,D2,BA,35,6D,70,2F,80,DE,A0,D1,E0,CB,B1,76,E3,BD,A3,9F,7D,25,48,A5,FB,83,4E,26,37,90,11,7E,B3,FB,F5,F2,10,13,87,7E,37,A8,D8,26,CC,4A,32,ED,59,1A,B8,86,74,C3,36,54,AB,A3,98,88,0D,0A,A7,FA,FB,D7,9D,0A,D2,40,17,CB,AD,4E,BB,35,16,6B,89,D3,03,A4,B8,EA,EC,A5,82,2A,03,60,FF,F8,FD,25,7A,39,7E,66,03,2B,47,63,E6,4A,D9,A6,C1,D5,11,91,8C,A8,96,81,7C,AC,A7,D0,25,04,33,98,BD,F0,89,A6,41,F8,F2,47,5A,40,25,5E,4D,E7,BA,27,3D,FA,85,D8,90,8E,74,2E,10,8F,54,98,9F,FD,B6,7B,36,8F,2A,85,91,99,02,AA,D1,73,42,96,E8,52,12,87,38,F2,BD,F0,D6,8D,4B,E1,2D,4B,F8,FC,09,91,C4,43,CC,56,F3,69,4B,F0,F4,E4,C5,0E,B2,62,84,2E,2A,2D,CC,46,02,C2,E0,26,96,2D,B8,E5,3B,C0,E3,6E,5C,2E,53,A2,3A,0C,6F,33,A2,37,C9,32,72,80,CB,8A,FB,42,F3,E4,FA,1C,76,86,AA,EB,55,43,57,01,45,53,F0,8C,6E,66,5A,BF,1D,68,83,A2,32,50,2E,C1,47,FD,83,DF,31,B5,7B,F7,96,AA,93,A7,5A,1B,9A,44,70,9C,04,B9,91,F6,D8,0B,BB,C4,A2,BB,90,6F,13,1C,38,68,E9,7E,13,7C,87,44,D3,8D,5C,95,E4,77,BE,08,43,6A,36,6C,CE,C2,07,CF,CC,7D,F1,03,2D,71,A6,11,56,9F,33,79,5D,D9,12,89,4C,56,D9,B2,E2,D3,0E,89,32,BE,BF,B8,20,3C,FB,BE,AD,D2,6C,BE,1F,7A,30,82,92,2E,A3,6F,B3,3C,C4,C9,30,EB,96,14,2F,91,8D,8C,61,8B,6F,2E,2A,62,2E,08,BE,97,07,86,A7,82,CC,B8,D1,7C,1E,AE,2D,FF,18,C6,EF,C3,F6,6B,E3,3C,92,37,78,DD,F0,22,FE,0A,FC,0A,74,99,25,0A,AC,E3,23,B9,91,2F,E2,60,51,EA,BF,44,D4,FC,6C,C0,23,42,F9,5E,E9,21,B7,C1,DD,81,24,00,71,10,C6,94,1C,05,0A,DF,43,67,E0,EB,4B,F2,33,64,26,E2,E2,7C,F6,7C,2B,3D,9C,CB,C7,FE,42,34,4E,01,6D,D5,86,C5,7D,B7,45,82,31,56,F0,1A,D4,6D,E9,F3,6F,C0,22,04,77,16,69,76,98,3B,7D,E5,CD,66,BE,C1,B6,85,49,36,F2,63,2E,37,62,E2,60,2D,87,92,EA,F3,6E,F2,BF,94,26,FD,67,51,84,69,EA,21,C9,FD,65,5A,12,CD,8B,69,35,C0,7C,57,FC,56,FC,87,EA,E5,39,91,AE,6B,B1,69,C7,DF,F6,04,FE,5D,05,FC,88,E4,67,0E,EE,58,37,AF,79,40,28,F4,E3,6B,72,4C,72,02,D0,C3,42,9B,19,9B,68,7C,15,5F,D8,C8,61,ED,00,6E,34,25,B8,BE,BF,60,02,41,1A,25,EB,04,A1,35,E4,63,AA,AF,7B,9D,7E,D2,AC,10,17,B0,75,1A,83,FD,76,F8,22,17,77,0D,FF,FB,AA,A9,EA,6E,0B,ED,F5,75,72,DE,F7,1C,2B,A0,D9,63,64,A8,C0,17,AD,BB,7E,6B,62,16,ED,8F,8D,75,A6,DD,F2,05,71,5F,CD,E0,48,B4,F5,91,78,4C,E8,DA,11,2E,B1,9D,7D,A3,90,11,2E,C5,2E,9C,D6,62,56,4D,ED,F1,61,28,A0,18,CC,CD,E3,9B,97,49,43,1A,84,68,98,03,43,18,3D,EA,FD,15,B2,0A,E0,08,FB,4E,37,82,F9,A0,FA,9D,81,0A,A4,8D,BA,D0,EE,D5,9D,AE,65,67,5A,4D,07,66,95,36,2B,ED,87,D9,D0,B5,F5,42,CD,0A,99,B7,2A,DE,FC,FF,58,A7,53,E7,C2,53,49,7E,B4,CB,51,C9,AC,74,58,B0,A2,BB,CD,5A,2B,02,4A,38,B7,1A,9A,F5,5D,A0,FB,28,9C,AA,1F,19,53,27,B3,A3,D2,FE,87,CA,BD,D2,C0,10,4A,5A,68,5D,E6,48,9B,8F,31,37,F9,40,D3,43,48,A1,8F,FC,77,75,1F,6D,21,56,88,A5,32,41,E3,5F,0E,8C,39,DE,5C,1F,65,9B,6B,B1,D1,87,E8,07,6F,11,C0,E1,9D,63,45,99,AB,56,60,70,AE,F1,A1,14,2E,5C,05,79,05,41,92,A8,EF,8E,9B,7F,85,99,A3,03,1D,4F,FC,F5,42,4F,5A,93,B6,50,AE,FD,08,48,1F,B9,51,B7,66,6B,12,8F,64,50,1D,DF,19,50,CD,FF,C7,88,D5,45,04,E3,24,33,27,B4,F6,7A,52,3F,2C,1B,0A,4B,7E,06,DF,E2,7B,37,76,90,93,57,6D,43,DA,72,FE,38,93,8D,97,E4,51,77,8F,B3,CD,05,A7,28,A6,C3,DE,F4,DC,AA,93,27,46,9B,6E,B8,09,18,FE,AA,CD,3F,46,1F,49,B9,06,C2,B3,93,5D,BC,1A,05,D9,F1,4E,B4,86,D5,5A,E6,35,09,D1,84,BD,64,1C,6E,FA,6E,98,45,DA,C1,57,D0,21,DC,4D,E2,82,8B,13,C8,15,EC,FF,84,C1,F0,69,65,5C,61,66,DE,45,2C,2A,9A,8A,B0,06,07,87,FE,5A,B0,62,AD,74,07,56,C4,46,BB,FC,49,5C,6A,1D,4B,C1,42,50,D4,F8,42,3D,2A,28,2C,BF,52,33,77,6B,61,CA,65,BC,62,4F,86,72,6B,E0,36,D9,0D,AB,62,61,9D,26,D9,C5,6C,11,22,57,34,50,03,17,A7,90,45,51,42,A7,5E,B9,BB,E4,96,3F,67,CE,5A,F3,84,32,A7,FC,A7,BF,42,4E,A9,28,05,AF,F3,B3,9C,1D,11,28,A3,D5,98,EE,A4,28,62,A3,99,CE,61,D0,B0,69,D0,0F,95,E8,75,73,93,EE,D8,1D,74,15,46,FA,F5,84,DB,7C,5C,F7,75,32,FC,69,8B,52,3C,BA,20,29,4E,17,0F,AD,82,9E,EE,FC,B4,46,31,5B,AE,87,E9,0A,87,45,01,08,09,C6,A8,2F,10,54,30,FF,D0,6A,69,9E,98,D1,EC,6D,47,DC,2F,4D,94,23,31,5D,AA,12,FA,65,A9,11,12,5F,30,99,72,1E,1F,4D,0B,33,1A,D7,8E,0B,E1,DE,CA,EE,4D,04,41,99,E6,E4,78,4B,9B,FD,FF,63,81,BA,92,85,E0,B2,EC,41,8F,46,44,61,C8,F9,12,FB,F3,AC,64,69,F6,C7,BE,77,F8,EF,16,8C,22,C8,ED,E4,A6,E0,CF,DC,52,E9,95,0A,96,CE,64,C1,B8,1F,B2,FB,BD,97,93,55,D5,76,4E,74,08,99,A7,30,31,53,09,C3,7F,4A,09,1A,23,C5,35,0D,2B,00,5C,65,9A,4A,70,BE,48,EC,30,E4,D3,8B,D7,68,53,78,05,33,91,40,8C,19,04,28,E8,14,C7,65,FC,63,75,F3,6A,B3,65,18,D5,42,8E,C3,99,43,66,B4,33,48,56,57,7A,B6,51,C4,1B,E6,F1,0C,78,20,60,BE,17,F1,2C,DC,99,19,9B,EF,C0,43,F0,03,96,9B,79,F5,9F,0D,FD,BB,ED,A3,49,AC,D7,27,6B,89,39,DC,2F,FA,DA,22,1D,1D,48,BA,14,62,A6,99,65,96,09,70,44,8C,BB,FC,4F,31,43,AB,B3,7F,70,E9,54,81,9E,B7,55,32,43,74,67,D7,4D,04,5B,02,E3,F2,CB,AE,8E,54,20,29,CA,59,21,45,81,BB,50,F8,5C,AA,5B,A4,3E,26,5D,22,CB,2B,07,5A,A0,C4,20,1B,AB,CF,79,59,8D,16,D5,63,48,7E,79,8A,3E,E7,CB,A2,14,DF,D0,6C,54,BB,8C,5D,FE,83,59,A2,F7,DE,88,F1,7A,EF,0A,4B,D3,8D,11,BC,69,F1,EA,7F,5F,58,63,9B,54,02,DB,70,7B,91,84,FC,94,38,A7,72,15,B2,AF,C3,66,CC,7C,15,D5,36,70,2A,D8,7E,FF,53,07,FF,CB,E3,5E,FF,A7,AC,58,66,BD,48,09,4D,39,2E,6E,E2,59,05,A3,D3,F9,EB,02,9B,98,62,5F,27,E4,AB,0C,CE,F7,31,7D,51,AD,26,9A,D7,48,C1,89,DB,D3,B6,90,AA,26,7C,38,26,26,34,5B,3C,93,69,BE,E5,5B,49,48,01,1E,EF,5E,F5,90,2C,12,AF,6F,9D,6E,0C,A7,EF,E7,B7,6D,5D,BF,1D,67,87,68,48,77,A0,41,49,EA,F4,3A,B9,78,05,C4,64,91,0A,76,73,12,54,DC,6D,09,F3,3E,E2,00,10,B8,C2,A2,A6,61,CE,F3,B9,D5,DC,57,06,95,FF,20,0D,53,4D,E3,B2,79,28,4F,9F,AE,F4,5C,A9,23,46,AF,80,53,80,05,2A,7C,66,92,DA,BD,7E,DE,E7,16,D8,53,CE,2F,E7,9B,CB,E2,E9,2F,3A,A6,A0,82,2C,AC,C7,E3,07,09,BA,C9,F7,32,43,E5,3F,97,79,5C,E1,53,16,41,CC,C3,E9,78,48,78,AB,11,2E,01,05,EC,45,E5,60,5B,0B,B3,25,23,C5,09,71,A3,BB,81,D5,0A,49,AC,E6,85,5F,D8,53,D2,74,42,53,AD,82,AF,66,6A,14,21,29,91,99,F6,30,CF,E7,74,20,BC,B7,4A,E5,DF,4D,4D,0C,8F,CA,17,46,7A,4B,C3,2C,AF,5E,34,63,89,BA,E8,97,9B,EF,11,B9,50,D8,20,88,F1,03,64,81,66,3E,9F,9B,33,F5,2F,5E,D2,48,1B,54,9B,E2,9C,3A,E7,96,92,AC,94,F4,F4,29,87,9B,24,F3,C8,04,EC,00,E7,69,4A,7D,3D,17,25,14,2A,45,AD,2F,5A,7E,AD,8B,5F,DD,AA,EA,A1,4D,76,7B,9D,17,98,54,E8,72,18,8B,24,22,E8,F1,08,E7,0B,6F,3F,ED,21,75,6C,9B,61,4F,31,F5,F2,49,22,31,1D,BA,56,11,23,F3,22,9B,57,8D,9B,A7,B6,38,B9,EB,C8,D4,AC,1C,5F,D7,F5,A4,78,9B,13,66,54,A8,99,CC,9E,C8,41,EB,E6,8E,A0,AE,95,EC,EE,45,34,F6,1C,13,A0,D8,85,1E,A9,5B,D0,4A,53,07,7D,9D,63,54,3D,E2,1C,64,E9,A5,10,1A,D4,32,C8,18,FC,E3,35,92,FE,9B,87,0C,FD,C2,3F,0C,64,33,D3,70,8C,43,71,2D,7D,7E,C4,81,4F,27,82,B8,5E,B8,6C,47,96,3B,2C,BC,8E,01,DA,35,0B,95,B4,37,02,48,F7,4A,FD,5E,D0,09,B2,86,77,DD,E5,BD,3B,FC,EE,62,19,F1,61,0E,0B,8F,C8,BF,85,C7,62,13,DC,D5,10,B6,FD,2C,64,BE,70,FC,C2,92,FC,1B,84,FB,1D,6D,CF,94,DD,81,DC,D5,53,3E,03,C8,3F,B0,4C,EB,35,A7,6E,53,CE,86,0C,39,01,A5,EE,56,2C,76,DC,2A,82,D7,DE,0C,63,B6,87,9D,A3,09,4A,53,B4,75,5B,10,3D,25,F9,08,08,CF,0D,A5,EE,B1,AC,B7,0F,39,6B,D0,63,9F,C8,58,E0,24,BF,B8,08,58,1E,55,5D,B3,B0,09,ED,9B,EE,4B,8E,A6,E1,50,1C,6B,7B,D4,BB,F5,0B,0B,6F,79,75,80,2E,BF,7B,F6,40,4E,45,9B,A6,60,00,1D,79,9C,B9,1D,93,56,33,82,76,9E,7B,4D,BD,6B,92,7F,3C,B0,C4,42,DC,23,61,1B,B6,F7,DA,23,E8,8B,73,57,B5,92,69,90,FC,B4,60,FD,3F,3B,62,8F,97,C8,19,8E,1B,79,45,CD,25,3E,F4,6C,E3,C0,C9,62,4F,20,94,F7,95,6A,44,24,F7,D3,E2,60,C5,2E,C0,FE,4C,14,E8,9F,CE,FE,E5,FE,9B,97,FA,00,1A,D9,24,89,99,0C,74,AB,07,76,E0,7A,39,66,C7,80,10,63,36,20,D3,7D,52,82,73,65,2D,C2,7C,CC,53,A9,D9,40,C0,27,4C,3C,8D,E3,03,01,52,40,A1,26,03,87,A9,38,92,C4,CE,34,53,69,FA,BA,72,8B,64,16,06,1B,49,17,5C,77,8B,76,FD,EE,49,60,29,D8,68,AA,84,AD,2B,A0,22,29,72,76,97,62,D2,41,3E,74,6E,25,7C,59,B7,15,84,24,B5,B0,CE,64,C4,11,E0,80,CF,78,DB,D8,65,88,05,39,A7,67,2B,33,3E,22,A3,54,8A,8D,97,95,3F,CC,08,01,43,8A,33,D3,B4,4E,17,78,73,F2,7E,CB,52,A6,82,8D,EF,1B,FF,64,12,99,94,99,C4,AA,3C,CF,C2,4C,AE,E2,ED,7F,E5,E9,37,91,83,B1,01,B6,AC,7C,C2,C2,D7,31,0B,9F,F0,36,99,5B,B1,60,B4,EA,D3,E8,8C,50,BB,5B,CE,50,9D,42,10,9A,21,CF,6E,C8,14,B1,B9,4E,CC,BB,71,8C,2F,0C,8D,49,59,D0,90,6D,2D,BA,7A,5B,B6,45,E9,9C,93,0D,06,D6,AA,03,86,B9,B3,92,38,F9,64,BF,C0,BE,49,25,AD,DF,6A,27,95,FC,2C,13,4D,0C,46,0A,A2,22,80,80,BD,E8,72,0B,8C,9F,B6,9E,3D,AF,17,15,43,67,AB,77,38,E1,51,D3,2D,35,89,DD,5E,A9,54,0A,1E,D3,5B,52,9C,75,68,2A,B1,09,A1,A2,4D,EB,56,C8,CD,F5,5A,1A,D7,92,CC,8C,DF,59,DC,75,BD,2D,C7,A3,06,4D,5D,9E,16,2D,95,F4,C7,5A,8C,AF,84,48,1A,33,91,F8,0C,76,13,77,D4,D3,8D,BD,B3,76,06,0D,EC,09,04,04,F8,5A,15,C7,BF,67,07,15,1C,67,26,01,42,6C,1C,0D,22,BE,6A,4B,01,34,60,53,28,5F,50,0F,0A,0F,06,88,E7,35,68,CF,0C,A6,21,2D,43,61,A9,36,E5,76,58,D1,95,1C,4B,93,15,1B,3A,EA,59,43,75,DC,52,90,A7,C2,63,1F,71,E4,82,E9,ED,B4,1C,58,7D,42,2F,E1,DC,94,54,AB,7F,DA,EC,6F,4C,D8,FA,E0,D3,AB,BC,49,12,96,73,D2,84,B1,71,F6,E2,8B,1F,47,A9,ED,6B,E0,65,8D,BE,61,1B,71,5C,91,DB,DD,F2,18,8D,67,34,87,CD,1A,7C,38,A2,4F,14,D2,9F,06,1F,F2,6D,23,E6,1C,38,04,38,44,C8,9A,C7,0E,04,41,43,48,5D,1B,9F,DE,95,41,05,75,2F,09,5D,D0,B7,81,62,58,8A,F0,C5,7B,9E,E9,72,E7,32,EB,BA,9B,4E,D2,10,53,13,46,D5,92,CF,BC,2C,53,18,BE,AF,38,30,78,03,0C,DF,5A,98,5C,56,FA,B8,1D,61,A1,16,4B,2F,56,42,11,76,EE,D4,D2,70,4E,8D,6F,42,F5,9D,41,86,84,06,BA,A9,F6,8F,7B,80,32,A4,7A,3E,30,66,C1,A3,8C,24,90,B2,35,C4,22,60,44,22,E4,92,FB,FB,52,02,2B,7C,1D,2B,1F,69,82,F0,9D,7F,40,62,A5,C8,A5,C6,7B,5C,89,F7,60,81,27,24,BE,D4,50,85,52,25,BE,A6,56,02,0C,3E,52,F8,DB,29,D8,2C,C6,23,BE,15,84,04,E1,8F,F4,7C,83,D4,59,50,5E,36,87,ED,33,30,06,2B,3E,D9,77,D9,BE,79,17,18,EC,DB,CE,50,E9,A2,52,FF,6A,CC,BE,51,1A,06,58,F2,B1,C5,5B,0B,C0,32,FE,ED,AD,A7,A2,D6,CE,62,E4,64,78,27,88,93,A1,DB,BB,DD,42,E3,45,46,D4,A7,21,76,46,9A,E1,D0,CA,A1,E9,63,16,64,73,F9,70,B4,85,1B,17,9D,A1,ED,D5,67,99,19,97,4A,89,DD,A1,F3,A1,A1,65,F5,3E,3D,39,C5,6C,4E,26,F3,25,FD,14,E8,9C,26,49,1D,6C,36,0E,57,3B,57,4B,BD,0A,2F,D2,D9,EB,F1,4E,10,71,52,1D,7C,C8,26,5E,E6,AE,2E,D1,C0,07,D3,53,C8,63,5D,8C,5A,22,58,D7,F0,3C,25,A2,C0,2B,B6,F7,21,1C,08,F9,73,6D,E0,A2,77,2F,43,D4,71,79,79,86,E6,28,7E,0E,ED,A2,03,23,BF,37,BA,CC,C5,3D,3F,5D,38,84,C4,C6,C7,20,59,A4,AA,0C,B3,52,91,32,09,B8,76,03,7E,92,0A,AA,38,AD,4F,78,98,36,30,C8,47,8B,A6,A6,FD,6A,C1,75,84,A2,68,2C,F7,A9,EA,7B,C5,B3,C5,5A,75,44,45,AD,4F,D9,D8,C0,25,87,2C,31,2C,3E,55,79,04,DD,FC,2D,E8,6D,AF,F6,A1,EC,BF,E7,22,77,5E,6C,25,2B,89,CD,4B,3C,15,B2,05,0F,DB,1B,A5,0B,53,E9,E6,76,B0,5A,A1,8A,60,A9,04,CE,F7,07,AF,75,67,85,AD,D4,B8,B3,46,36,1F,5F,3B,03,2B,A9,DE,2B,7C,1A,3B,33,F5,63,FA,B2,79,3C,64,34,0A,8E,5D,65,2D,26,CC,0C,7C,0C,03,E1,FA,32,3B,B1,7A,C3,4E,03,0B,95,98,63,B9,B4,8D,34,56,BC,70,3C,AD,40,0E,F1,8C,14,BD,0A,7F,3F,53,77,D7,2A,E0,9B,4E,CF,86,88,6F,BD,F1,25,70,6F,47,8B,07,85,97,F6,23,CB,28,1C,34,73,54,1B,7D,A6,5F,2D,07,21,FD,37,1F,B6,04,5C,32,C5,8B,FF,56,F8,35,FD,33,0F,C5,F0,B9,FD,67,46,48,F4,64,33,48,11,63,AD,AD,57,2C,FF,AD,FB,30,64,11,F4,F1,9F,17,7F,BC,55,9E,B3,44,78,D4,13,99,9F,E6,49,3D,AA,A7,66,18,28,10,6D,4F,14,A4,7E,1B,E1,EA,55,0E,88,79,F1,E4,12,41,D1,57,E8,04,B2,0C,C8,3B,F6,EC,AC,AE,6A,EB,AA,E3,3B,0B,94,02,6F,65,61,BA,67,B3,CB,4B,D2,A1,8D,CC,B4,26,B2,21,E7,D9,B1,73,54,AD,79,95,48,F7,6A,03,98,95,A8,F6,A5,B8,CA,6B,5A,EA,CD,55,65,F9,67,5F,28,4A,A7,CA,5D,68,C7,8B,CC,54,DB,0A,E3,44,15,34,C7,B0,86,5A,E9,95,AF,1C,F0,0D,6A,00,DA,3E,26,B6,C5,28,CD,4B,64,1A,32,8D,E9,E4,B2,97,1C,8A,A0,57,CE,4B,A6,C8,F4,48,AD,4D,B1,FC,B1,B0,CB,F5,3A,96,1C,C3,44,62,2B,75,8B,D5,0B,0E,A6,E8,DB,F2,AF,27,63,F5,22,5F,A8,A4,E2,7C,DD,D4,88,F7,84,A9,D5,78,95,22,45,91,00,61,91,1D,20,AE,94,D1,E9,F8,3E,83,59,9F,27,12,71,1F,2A,7F,78,91,6E,D0,A6,58,E1,3B,D5,45,F0,46,8F,D3,5D,21,65,02,30,55,C1,D5,E5,07,16,91,E7,86,74,1B,4C,05,6F,20,D8,39,A4,DD,5D,F1,46,4A,D6,CA,43,B4,FD,1E,64,E3,0C,1F,01,D5,03,07,FB,B1,28,9E,FA,3B,45,EE,28,C9,96,9A,4D,1B,15,11,D9,4A,74,54,3B,96,14,47,00,79,DC,B9,35,78,1E,20,80,2C,16,AE,31,6C,99,E8,55,AA,39,A1,78,D8,4A,7C,C9,A9,B4,58,37,C8,F6,7E,22,71,D0,D0,53,0C,51,FD,98,0E,A0,A1,36,E2,02,07,32,07,E5,D8,B9,62,19,40,CA,13,07,1D,7E,4E,10,EC,44,FE,DB,7B,3B,AC,E3,C5,B6,A1,B2,70,C2,83,79,2F,50,43,7D,C7,A8,F1,1C,84,55,E6,BD,08,A6,13,E9,1E,58,D0,56,BD,29,EA,AC,81,4E,49,CB,D4,7B,E3,24,86,A5,3C,61,52,EE,2E,E6,DE,EF,78,06,F6,28,90,1F,95,C2,4D,1B,5C,FD,A3,E6,95,FF,FE,CE,56,F7,58,EE,BC,E1,CB,B2,2C,D4,92,16,8A,AB,3F,DD,F3,6E,F3,3E,78,32,51,B3,36,30,EE,9B,56,39,04,2A,70,3D,B9,AD,C0,50,86,B2,69,6E,69,93,0C,66,0E,EF,C0,1B,50,DE,76,DC,8C,EC,FA,FE,BD,63,A6,C8,11,FC,66,14,78,7A,76,9B,71,4D,46,FC,5E,38,3F,62,74,53,BD,D6,F5,43,89,3F,D5,6B,83,87,10,B8,8A,FD,27,52,9F,31,C2,07,84,55,5D,B1,8C,9C,2B,33,C3,7E,CB,63,11,55,98,0C,F0,AB,00,34,25,F7,74,94,8E,D8,4B,18,75,5D,A2,2D,7F,09,BB,63,1F,D5,F9,0C,9C,D4,CC,FC,D7,F5,C0,BB,AB,05,6B,5C,0D,97,92,88,0E,4A,5C,CE,99,12,7F,47,E1,B5,96,10,BB,A5,3A,9B,2F,E4,AF,F1,2C,F2,5E,5B,1C,9B,73,2F,5A,C2,1E,40,FD,5A,92,EB,CA,DC,26,70,60,E9,76,EC,BD,31,F3,50,38,3E,A6,05,7D,38,3C,1D,12,2B,84,A5,86,2D,D5,46,51,FA,CD,EA,7B,3B,78,2A,46,0F,60,42,1B,CD,E5,B8,DE,3B,D0,46,1C,F0,50,59,49,A8,FE,1A,D2,B6,3D,8E,37,4D,FE,8F,3D,A4,BF,51,3D,92,EE,DC,0F,6F,7B,4A,CF,F8,9B,F4,8F,1A,D2,CE,D5,B2,97,CB,6F,59,44,47,DC,00,DF,9D,EF,E2,6E,AB,BA,FD,F7,80,31,AC,D1,0D,87,CD,01,CB,03,D8,63,8F,DC,83,4D,07,77,1A,A0,D2,E7,5E,ED,0E,72,45,AC,8C,3F,68,F2,A1,EB,D3,A9,52,85,9C,E2,D3,9F,92,C6,8F,08,1C,5F,13,A3,73,69,42,AC,97,EE,FF,6E,AF,3C,DB,09,A5,E3,A7,8D,37,3D,40,8A,B7,1C,37,B2,F7,04,72,10,A5,EC,B0,DD,46,44,1F,57,79,98,0D,7D,8D,05,76,52,77,51,A8,85,02,BE,71,38,E3,08,F3,58,23,82,E7,3B,86,75,86,08,FA,DB,47,47,CD,DF,1B,20,70,F1,88,B0,55,0B,D9,E6,9C,F4,0E,71,22,3F,FB,EC,8F,36,7A,4D,4A,43,1C,C8,15,1F,BA,B0,F6,3D,AF,1D,EA,54,C7,1F,0B,8A,42,5A,B3,8E,09,0B,13,D8,29,A7,1F,04,70,82,17,DF,0A,B5,C7,60,15,E2,C6,F9,FC,59,1B,7F,4C,5A,F7,EE,E2,73,8C,50,B5,3A,AC,45,C0,6C,12,78,93,0B,B8,E4,4D,9B,57,14,04,62,0B,C1,27,6B,4D,58,71,FD,DB,F5,72,53,85,65,70,DD,01,83,B0,1A,ED,5C,70,60,D2,54,27,C0,51,4B,E6,93,1E,14,18,98,9C,8D,BC,DF,D1,2F,6B,BF,4B,5F,EB,C4,74,05,85,EA,99,87,33,02,EE,47,7D,42,78,F8,A7,14,91,34,38,CF,C7,EA,10,4E,E5,65,85,6B,74,43,9E,3D,95,7B,6A,57,80,5A,32,FF,04,42,E2,BA,DF,51,95,F9,88,67,28,8D,5F,19,7E,06,49,AD,E5,A8,2F,A6,7F,70,E6,88,6E,8E,2B,9F,14,82,48,BA,CF,DB,98,3E,C9,32,A7,09,BD,6D,75,8B,DD,92,28,3F,33,61,AE,B7,B2,16,D7,8F,F2,85,A9,07,F9,C6,83,39,07,3F,A0,65,4E,DC,75,49,1E,94,F9,AC,BB,63,2C,C9,0D,FF,2B,34,4C,D3,5E,6F,30,E3,AA,BF,5F,C7,B4,0C,19,48,30,1B,94,48,17,72,F2,55,D9,4D,0C,1B,6A,E4,B8,22,17,FB,4F,93,BF,ED,97,CB,C0,67,9C,75,F8,8A,89,B5,89,0B,B6,77,FB,F9,CD,F3,AE,71,D7,2B,D3,B7,C5,F5,54,9A,E0,3D,EC,D7,9D,E1,68,52,E8,41,E3,9D,E3,80,EB,70,26,26,99,77,1D,B2,FC,8F,30,DE,D2,2D,91,96,A4,C6,5C,BE,34,AF,A7,6B,3D,D9,50,FE,09,5B,FF,84,D1,70,B7,BA,0D,F2,6D,1D,99,D8,C6,F6,2E,CF,A4,EB,D8,02,C9,BE,AC,FA,FA,28,FC,CA,27,FA,7E,43,BA,19,4C,AB,1C,11,44,FE,E0,B3,6A,92,F4,05,89,EF,AE,B4,40,90,CF,5E,C5,D3,7A,7A,9D,23,1D,B3,18,9F,99,A5,A8,49,53,23,87,D0,F6,42,94,55,3C,27,DD,F2,2A,57,68,52,64,E0,F6,C1,F8,E3,E4,FF,8C,C7,0D,E7,31,53,4E,85,59,39,39,8E,14,10,3B,0C,B0,C0,AE,F7,73,DC,49,18,52,07,84,2B,83,53,99,D7,56,CD,6D,90,0D,4D,EB,BC,C6,EF,45,28,CE,4C,87,E1,FF,B7,E9,EC,0C,DB,2D,48,21,79,11,81,1D,E9,E7,2A,C2,5F,36,17,92,7E,F0,21,9B,D7,4B,35,3D,00,F9,6C,8F,E0,29,14,99,10,7E,D1,C7,E6,7E,61,24,48,19,0A,65,91,EB,E4,A0,2F,64,EA,3F,4A,35,88,B6,B7,83,6E,7F,5D,66,70,B5,1A,16,64,85,68,5B,D5,1C,1B,AC,89,A2,35,2D,E0,37,D2,5A,3C,12,14,94,00,24,73,6A,B8,78,E6,9F,22,F9,EB,FD,20,15,F5,A9,3B,EF,60,95,FF,1F,D2,7F,78,FF,D8,B4,AB,9D,A2,B7,0E,CA,E4,B4,CC,AF,DF,E6,62,16,71,EA,BC,22,65,E5,63,38,37,C8,AD,20,61,B0,7B,F2,B0,CD,E7,CD,16,9A,AF,86,9B,50,95,06,80,08,3C,2C,75,A3,54,A9,2A,29,08,9D,71,94,60,6A,F5,5D,AF,23,95,B4,BD,E7,B5,B1,F8,F7,94,7E,D1,41,50,B6,0B,34,80,D3,DA,7D,A0,2C,58,75,68,3B,A6,74,6B,EB,6B,0F,B2,92,2C,F6,8E,13,97,73,CE,31,EB,69,F1,D6,02,69,D1,DA,A3,AC,84,36,F8,CC,82,36,58,BC,EB,52,1D,D5,EB,E3,BB,2D,69,14,9A,D2,E4,47,26,D3,77,56,6A,D4,A2,8C,A4,3E,79,5E,2F,C7,13,C4,20,BE,02,E1,90,82,37,C4,58,A6,92,AE,37,AB,F5,E2,5C,0B,E8,85,A5,B9,5F,28,13,BD,BB,B8,30,0D,99,5C,2B,5D,95,7A,58,B1,34,EE,B4,58,38,8B,67,70,BA,CF,4C,F2,8A,87,8A,0E,35,83,55,4D,A4,34,BE,5D,08,5C,E2,3E,C0,A0,D8,CC,AF,6F,D5,98,29,2C,FA,F9,2B,0A,B0,E2,30,8F,6D,F7,D3,95,81,78,24,E1,1E,29,0F,BD,42,11,C7,79,9C,B6,D6,AB,86,E4,1D,8E,5E,17,1F,2E,38,16,84,29,0D,42,6D,DA,2F,AB,73,04,70,8F,C5,17,4B,05,26,8C,77,00,55,7C,1C,BC,9F,56,EC,2C,69,7C,B2,7B,A0,46,8E,F7,3D,1F,A7,FE,FB,2D,A9,94,72,28,4D,39,D9,86,B4,76,5B,0F,CB,D8,09,B4,2B,F4,13,2D,F6,B3,A3,87,2B,90,D6,C0,A2,09,14,DB,61,82,F1,22,0D,DC,F4,FC,FE,FE,9A,36,08,05,A6,EE,C6,0B,70,34,B9,92,22,BB,6E,9B,72,98,DB,03,E7,E5,22,C1,96,05,59,DD,1D,2E,B4,24,3D,3B,93,B1,6B,F4,5D,B4,00,A1,4C,AF,45,D9,12,07,22,01,68,9E,84,98,8F,64,33,A8,31,8F,96,74,03,B8,BA,C1,E9,B8,CA,B9,2A,8C,57,73,14,12,35,DE,56,E7,F1,27,98,49,3C,95,91,0F,52,8B,F7,BC,65,11,1C,B0,C9,88,D0,A6,72,7B,E1,E1,7F,85,F5,03,4A,86,77,66,FC,D8,EB,B3,01,2B,37,97,4F,16,A6,34,B9,DD,A5,47,7B,DE,D0,37,B9,0A,52,4C,E9,2F,30,F2,FE,78,E7,E6,27,5E,57,FB,F3,1A,90,47,20,B1,FD,E7,B2,19,34,0B,B6,87,F3,E3,45,2C,6B,3F,26,E6,59,97,14,50,0F,D0,2F,A2,E0,0A,85,48,D6,E5,27,3B,C3,35,A7,18,A0,07,65,22,C0,D7,4C,15,14,F3,B2,EE,C1,B1,7D,2D,DE,05,45,32,94,05,88,6C,FA,D1,F9,60,D4,07,3B,64,5C,FA,62,AC,5E,A7,E0,4A,FB,C1,D6,05,F8,3F,2F,D9,C4,F2,E9,09,53,18,BC,AB,19,53,A7,85,24,91,93,91,08,69,CE,FF,9C,E3,55,CF,9B,CD,B8,4D,00,30,B1,DD,3C,8C,5A,9B,96,82,D4,9F,A4,86,E5,6A,FF,9F,C0,F0,5B,1F,0D,63,8B,AC,E2,48,65,1E,FD,43,78,19,6D,3B,0E,AB,A7,5A,78,FF,63,01,9F,5F,12,6B,D5,54,0F,A3,92,87,24,98,59,1F,48,82,20,C7,A3,5C,79,5F,B4,E6,AA,35,71,68,5B,E3,9D,DF,FC,E4,8D,CD,0F,B3,90,F2,69,DA,40,F1,13,DD,75,DA,5E,30,A9,56,BF,0F,76,93,B6,5D,88,4B,47,9E,E8,09,AF,B6,41,D5,38,87,3D,72,CB,0B,B1,13,A1,4F,22,E3,2C,3A,C2,96,4C,51,88,49,01,77,F7,5C,5B,5D,4E,18,AF,5F,3E,37,B9,1A,88,F3,FA,36,FE,77,11,80,A6,33,4C,E6,D7,D0,16,A5,90,59,5F,BC,21,38,F1,E6,C5,54,2F,18,88,E2,26,9A,1B,C3,62,C0,B5,B7,46,79,5F,4C,2D,4A,C7,20,42,13,4D,79,F3,85,C2,B8,18,D3,69,63,ED,B2,1E,AF,43,6D,CD,8D,CA,30,DD,13,D1,C6,C8,D0,25,0A,BE,F5,01,45,5B,97,5C,60,48,F9,FC,C0,59,A0,BA,88,D3,A1,B4,26,C3,00,24,CF,7D,1E,8B,BE,D4,25,7D,E0,B9,53,3E,85,4B,8B,29,F3,28,9C,CD,66,79,16,30,7E,6E,91,1C,55,77,11,EE,09,7F,3C,84,5E,1D,1D,05,C9,78,A9,67,5A,B0,7A,A5,4B,75,DD,A3,BF,8E,BE,F5,BF,87,CE,41,FC,48,EB,7C,8C,70,46,D0,39,E7,0F,7C,80,76,59,02,94,E1,A2,5E,99,9B,90,93,B3,C1,83,B0,7B,C6,68,DD,AE,FB,45,D9,E3,29,E4,19,50,32,F4,5A,19,E2,74,51,E2,8C,91,5A,A9,01,2F,68,C9,2E,F3,1F,26,46,75,F9,A6,F2,CE,58,36,3B,2E,A0,8F,15,40,14,85,67,43,B2,26,01,60,53,39,DC,BB,90,E0,CB,1E,86,F9,13,E3,AE,EA,30,F7,45,87,DE,63,85,1C,B6,EA,FE,0B,E0,EC,10,69,25,6D,C1,42,92,7C,EC,D5,62,9E,D0,7F,53,12,EA,AD,AE,39,50,E9,E6,FE,7E,C0,B8,62,74,76,EC,BF,26,D6,15,39,01,B0,61,AC,88,EA,55,93,E2,FC,77,96,DF,61,90,29,E6,2F,EF,AD,F4,35,1F,94,8B,B7,59,89,C7,8B,1D,7C,DF,47,6F,5F,27,44,6E,1A,CC,0E,0E,09,D9,6E,95,8C,94,86,52,58,BF,E4,E2,65,61,74,3F,82,E6,CA,79,F4,A7,EF,67,B0,8F,C8,EE,08,71,C7,D3,0A,96,D7,A9,05,1A,68,8C,0C,E0,CF,D9,9B,3F,31,70,31,FD,63,D7,6A,AC,9F,1B,CF,1B,8C,2D,15,A1,CF,44,C4,5F,DB,EC,85,09,FD,3B,D6,BF,8C,77,1E,3A,3C,8E,32,8B,BD,FE,02,15,7C,FA,93,9F,6A,A8,69,A4,A7,C6,58,D0,00,1B,E5,86,5C,95,FF,FE,5A,AB,5C,C4,27,D2,4D,FC,CA,73,87,A8,31,0F,F9,F3,D9,E8,3D,21,A2,6C,E9,03,31,84,3D,E9,AB,7C,74,31,CD,9E,E5,3D,27,95,D5,93,AA,2D,E2,6B,69,02,E0,18,7F,E6,64,53,51,09,11,FD,6C,16,08,3D,00,EA,5A,65,F3,17,A6,94,E6,CC,FE,B3,F2,F1,B5,B6,A8,72,76,15,EC,F0,16,B8,11,83,09,C9,37,B5,B5,F2,D9,0E,EA,42,E7,99,24,C4,B2,37,D4,98,6E,54,7E,AF,D7,6F,14,CB,6D,E2,23,B5,D9,03,3F,40,6C,1B,B5,45,40,BC,56,3A,C3,DD,F1,C1,72,2F,3E,7D,47,CE,98,27,D0,BA,00,95,2B,49,95,48,7D,78,B9,8C,A9,96,A3,1B,C8,81,C8,C6,C3,15,A7,E1,DF,D7,9C,57,7E,5C,42,6C,5E,F2,CF,96,20,9D,59,31,29,1F,60,AE,72,D7,C3,5F,3C,66,86,D0,F8,22,98,E9,60,7E,8C,C8,A6,BF,4B,44,7F,DD,0B,B6,04,1C,17,13,2F,B4,BD,F2,2B,38,6A,53,4B,E1,DF,43,57,8B,93,8D,B0,E9,BA,E9,FF,C0,37,2C,9D,7E,CD,E7,A5,41,63,83,09,FF,E1,AF,E3,2E,50,F8,9C,0F,91,39,43,5B,60,A7,F1,CD,8D,71,38,F5,E3,5D,C4,0D,5A,40,6D,56,63,82,25,B1,51,C9,EE,C0,FC,32,AE,E6,D1,6E,62,D5,E0,45,55,46,D5,A4,D2,39,89,BC,F4,A0,17,06,E9,41,5D,96,51,7E,16,BC,D8,45,81,C5,E6,C2,AD,FB,0E,63,B8,0F,61,2A,93,B9,C6,46,56,DD,5B,D6,C2,21,A4,3D,6C,3F,D3,EC,32,16,F1,7F,C8,DA,14,80,7E,A6,89,ED,5B,D9,80,FA,DE,B2,0A,07,E1,D3,DD,E8,68,D1,4F,D7,A6,51,70,AC,A6,E2,E1,B5,39,80,C1,62,E8,73,CC,15,23,A3,D2,F9,18,71,AA,97,3F,11,58,64,70,7B,34,CD,4D,82,E9,BE,81,D7,0E,8C,36,62,2A,01,69,34,A8,EC,F9,80,B7,17,D9,10,F1,4A,D5,9E,21,26,A4,C6,36,D7,CD,AC,9B,54,2D,5B,A9,7A,2A,02,F3,59,17,F0,80,39,02,F0,7B,31,80,F3,77,D6,18,82,04,EA,68,FF,51,68,2E,C1,ED,E9,38,D4,DF,CD,F6,7D,43,76,AA,DC,D5,EC,E1,7D,2B,8F,F5,7B,03,55,6E,31,02,96,49,E4,FB,9A,55,93,F2,96,5C,01,1D,B3,35,A0,00,FF,2F,3E,77,95,73,46,A2,0F,93,81,BD,94,68,C7,6C,63,2F,A2,23,5C,3C,84,CE,68,5E,E3,02,62,2D,40,48,87,B8,7E,C4,19,2A,18,89,9E,FA,22,C4,99,70,AA,41,AA,A6,A4,B8,40,03,2A,AA,4F,47,45,E8,21,D7,63,CF,86,D3,80,3A,17,65,50,15,37,F0,EE,1C,F2,14,41,58,77,38,83,5B,86,7E,98,F6,D3,D9,10,59,57,83,33,EC,70,89,64,49,EC,42,BE,9E,1F,01,26,B1,79,A3,5F,23,14,09,0B,0B,23,64,D9,8B,2F,CC,7C,A9,B0,68,6C,D1,1C,C1,B9,5B,F6,B6,C5,F2,C9,8E,D6,0B,E7,C5,EE,BF,F9,6D,F1,AB,CF,0C,74,6F,CC,56,A3,75,27,B6,CB,93,B6,F8,60,A4,A7,4E,31,01,48,0F,15,F2,6F,EC,B1,28,79,A7,D0,0B,97,0F,D5,53,AD,5B,1E,90,0B,EF,CF,91,08,9A,1D,1C,61,38,18,96,16,64,F6,F4,D6,08,6A,61,27,49,BE,CD,1C,68,0F,27,E1,BE,01,D1,FF,91,AF,E0,2A,6B,57,83,A5,26,B3,7B,51,2E,5E,CE,C5,28,EC,19,83,5A,95,9A,02,6E,5D,03,6D,1B,5C,CA,22,B7,AC,2D,4C,3C,07,90,64,BF,05,BD,4F,84,9A,17,E2,46,7E,CD,F9,D8,C1,5B,47,39,67,FA,1A,7A,50,8A,AE,19,1D,0B,3F,11,C3,F5,A2,F3,9B,D8,82,66,7C,65,68,F0,2C,60,CE,A0,A5,02,9E,EF,F8,06,4D,A2,EE,E6,C4,FF,2E,CB,CA,F0,30,69,65,D9,07,A2,BC,15,AD,EF,64,24,81,D4,D7,04,46,7C,D4,45,D4,6E,18,0F,D7,F9,DB,06,A2,E9,B8,00,35,A6,23,E4,1B,30,4D,7D,60,B5,9E,3E,65,25,95,07,C2,AC,DC,4E,44,F5,95,59,5B,7A,A0,A1,58,D8,1D,0F,38,F7,8D,5B,32,BE,56,FC,2D,C9,9D,D9,64,68,2B,03,B8,5F,D6,66,62,64,08,58,8F,32,72,58,48,FB,A9,5F,D8,09,2D,3B,23,05,4E,43,AB,00,1F,DF,2A,27,BC,FF,8A,11,5F,7D,91,AC,14,E1,EC,D2,8D,1D,3F,EE,88,9C,55,1C,68,42,EE,55,5B,DF,21,86,E6,9B,03,7B,90,75,7B,7C,9A,9E,05,BD,CE,0A,3E,BB,57,22,04,EC,68,FD,3A,14,BC,45,D4,F4,6A,C2,C5,84,87,83,E0,54,33,E3,16,FD,F7,C9,3F,C3,B9,48,08,90,93,3A,F0,40,71,C9,C8,1C,E0,F4,C3,FF,DF,83,5A,69,E2,E5,84,D4,5F,B5,B8,79,09,83,84,6C,84,26,5A,EE,E0,6D,63,72,66,B9,2E,F5,11,0B,CA,6E,D4,31,1B,5A,91,4A,66,CD,A2,69,81,07,3F,E9,3B,ED,44,2B,57,68,82,B1,41,7F,AE,B8,12,90,2D,D8,E3,F3,2B,E0,07,ED,84,EC,B2,90,FC,72,A7,5C,C5,57,35,8C,A2,8C,B4,83,C5,59,CC,F7,47,F4,8D,D1,89,4F,A8,5A,3D,F5,60,65,70,FF,F4,AF,AD,E6,5C,5D,E2,DC,40,C8,69,E9,8B,14,07,8F,26,4B,8A,DB,55,21,34,F1,94,03,59,19,18,36,C6,B2,8B,1B,D9,B4,34,5B,19,0F,02,E6,C6,81,0F,1E,19,8C,7B,53,D0,35,46,AA,7F,10,FD,FB,36,FC,E3,4E,4E,CC,86,0C,40,00,1A,45,B5,36,EB,ED,E3,00,75,8A,F4,91,B4,C5,0D,CF,8D,DA,65,D8,0A,92,97,67,A3,A5,A8,01,A9,B9,0F,BD,98,AD,4D,29,C6,8B,85,E8,AB,CF,17,27,9D,7F,1D,F7,9F,FE,7A,29,27,03,04,70,EF,BF,E2,90,E6,3B,9F,9E,92,81,A7,E5,05,F0,5A,D5,0B,02,E4,02,1A,93,22,E3,BF,C1,1F,4A,7F,98,AA,5B,63,AF,2E,FB,91,26,15,A7,25,83,B5,1C,48,CD,0C,B2,2D,89,3A,69,CC,3B,A5,39,16,A4,A0,2E,D4,0D,64,4A,3C,3C,71,2B,BE,68,9E,EE,56,B4,AA,B6,FF,9B,BC,72,4F,92,E2,F9,60,54,7F,A8,17,AE,9D,0C,41,C8,33,51,C9,22,2F,CC,AF,31,03,E3,6E,05,E0,04,BA,5F,09,55,89,9F,C4,9E,27,1E,5D,7E,25,D9,A9,7E,65,AA,51,B1,A5,D9,2F,F8,79,63,9C,4E,5F,06,CA,4C,36,78,69,21,40,E2,B7,7D,C9,78,8C,4F,82,A5,0E,10,59,66,66,1F,09,6B,38,26,57,77,3D,A9,3F,9E,7E,70,00,52,F6,3C,72,F5,60,58,AB,F1,6A,68,7E,66,F8,D0,15,5C,C2,3C,1B,42,CF,83,AD,15,A3,41,F5,DF,F0,1F,B6,99,1F,C9,01,F9,6C,24,D3,71,B9,B2,CC,89,AD,AF,91,B3,CE,E4,39,4D,3C,1B,48,74,5B,C1,2C,10,9A,22,3A,C1,FC,68,7D,A6,AD,2C,B1,BB,28,2A,AC,4E,C0,A0,BC,EA,BD,F3,B6,05,8A,5F,0D,BA,88,C5,E8,7C,EF,CD,76,6E,4E,EC,FE,8E,8A,7A,0D,D8,E1,CB,B9,E0,85,0E,FD,9E,00,9F,99,35,A0,35,87,F0,21,05,B5,25,29,63,A7,C5,60,FD,24,3C,AA,02,5A,96,F8,E1,B5,80,4F,9D,95,FE,AC,E4,AE,E3,55,B6,B7,4F,05,ED,CA,EE,76,79,DF,DF,89,23,7F,1A,70,F3,93,97,B5,F9,59,05,A7,BD,2C,DA,5E,B4,4E,38,42,26,69,67,F2,76,0B,11,7E,B0,01,81,28,84,79,27,7C,2F,F1,AF,80,1C,23,E9,C7,2E,CD,1D,D1,04,33,4E,11,16,92,B0,A3,64,D7,17,A6,7D,BB,4B,1E,F8,55,E9,BC,AE,96,34,10,B5,55,34,A4,52,9F,EE,26,5E,82,F5,D9,CC,69,0E,A1,5E,C9,C4,E6,5A,B2,96,56,40,53,1F,D9,AE,38,84,A7,9C,5E,F4,EF,5D,15,6A,08,BE,C0,72,B5,04,6C,31,D7,7F,88,6F,AE,3F,B3,44,3D,4A,2E,8E,AB,5D,DF,1C,A6,CD,A6,C1,2F,01,D9,29,9E,7F,2B,C6,E3,84,49,0D,1A,10,0E,24,02,44,33,61,EF,78,50,34,03,82,6F,A3,6F,32,22,85,C6,79,C0,59,11,BC,40,0D,EC,32,9B,35,49,1B,9C,6D,98,D2,C6,15,BD,D8,97,BC,39,D7,3C,56,91,C1,55,80,32,D1,78,49,43,16,B9,4E,57,14,71,08,7B,54,2F,31,ED,46,92,5B,89,A4,C7,0F,14,3A,13,35,DD,10,7E,DF,22,EE,F6,4A,A8,1C,1F,3F,50,67,7A,9F,A6,DE,AA,5D,B3,DD,06,89,EC,EB,6C,2A,D1,10,9B,BF,F8,25,53,CA,FC,A1,1A,F3,1A,B1,F9,7C,68,A1,02,B2,E4,D6,09,7C,D8,D4,A9,CA,34,13,F7,91,AB,52,4E,1A,16,2B,F4,F4,0E,27,35,B9,DC,94,5B,53,66,7A,5D,7D,9B,14,90,1F,C4,9C,0A,2F,4F,79,8A,C8,04,02,6E,03,3F,BC,27,BE,78,7C,34,DA,77,DF,72,1F,6E,23,AA,25,6E,40,81,B6,81,B7,E8,67,3A,33,62,CB,E1,9F,ED,D5,E0,D0,FB,B8,51,BA,3E,56,03,C6,D3,8D,96,A6,EE,EA,57,1E,CE,AA,94,31,59,BE,15,7B,E4,CE,C6,32,E7,03,B0,34,BF,40,08,0A,CE,2F,7B,AA,00,9F,7D,E4,84,E4,85,1B,A5,D7,30,F9,64,6D,FD,CF,CB,40,F3,4D,E1,BD,BE,38,01,2A,10,58,F3,54,C5,35,79,A6,61,7E,66,E0,E2,5B,34,0C,AC,31,FE,53,B1,FE,BE,94,1F,C3,49,FA,D7,FA,39,F0,2A,7C,F4,08,B1,18,18,F1,23,B8,DE,F2,00,23,72,D7,F5,FA,4D,CF,8A,96,16,51,0C,AC,21,64,E2,1E,27,44,B9,9F,82,FE,59,C0,1E,ED,9F,BE,90,A4,5C,47,27,3E,AC,59,B4,12,5E,F2,2F,7B,23,65,5D,50,5F,C4,A0,54,40,E8,4D,0E,37,5C,27,92,A3,E9,CF,72,B8,7E,42,89,6C,68,A5,AF,78,6C,12,C2,12,1E,05,15,6C,49,23,72,A1,8A,FA,B3,F9,BD,52,48,CD,9F,08,B3,44,70,09,F3,39,FC,9D,A5,C8,CD,A3,43,62,8E,70,AB,06,80,C5,09,1C,0C,63,8B,97,D0,06,08,5C,B4,A3,8F,7B,A3,B9,65,DF,94,B9,27,09,32,A6,CD,94,8A,77,54,1E,71,0E,D7,C0,9C,35,57,AD,11,FB,A4,65,C8,48,B0,6E,59,43,BA,D0,82,9E,AA,1C,23,C0,33,30,8B,7D,68,26,53,6F,5F,64,40,EB,0D,95,40,2C,6D,0A,9E,2F,B1,8C,50,16,10,7F,75,72,B2,9B,98,63,40,99,EF,D0,E6,21,34,96,24,60,00,35,57,B4,98,C5,40,A9,C3,8A,D8,01,CA,A8,3E,0D,2D,FC,67,2F,49,16,F0,B5,3A,D0,3C,24,48,12,F8,50,C8,F0,BB,FD,2E,BC,B4,5D,75,C5,4D,42,5A,EC,3D,F1,9E,8C,B3,08,D6,95,BF,0A,1A,51,49,A0,B2,D3,9C,DD,75,1B,DD,E2,90,A3,19,F0,61,BF,47,D0,A9,44,BC,2F,B1,B6,6E,BB,87,31,62,38,1A,6D,A5,30,2B,BA,23,C7,2E,16,14,83,33,3B,A8,C5,DE,C4,57,B0,79,42,B0,7B,F9,8E,B8,0A,E8,D9,0C,09,94,CA,57,51,B6,68,A3,EC,14,B7,B4,EC,16,9B,73,37,53,BF,91,1C,2A,43,E2,F0,AF,3C,B1,99,B2,ED,F6,4F,0A,B2,95,DA,DF,06,D7,38,05,93,EB,83,76,DE,F7,64,0D,68,C3,D6,93,61,82,0F,52,F4,01,28,56,BF,EB,1D,85,94,92,EE,48,63,44,8A,C3,5C,AE,74,50,E6,B0,DC,93,69,77,15,44,1B,19,D2,4C,E0,D7,5C,4B,78,A5,FE,5F,3F,CD,4F,89,0B,64,52,DA,4A,2E,67,AF,D4,18,51,45,F0,D8,F6,E7,11,6F,F4,02,B1,EF,EB,4B,A6,8A,B2,37,16,DE,8A,CC,B8,36,B2,96,D9,C4,0E,6F,8E,47,B3,85,1C,A0,6D,B0,39,D9,48,8B,BB,D6,47,B1,44,7A,44,4C,7B,EE,24,2F,50,5E,3B,CB,04,A5,9D,A7,3F,D0,89,02,F6,4F,50,3D,A6,01,7B,FE,E9,43,DC,09,C8,06,E0,7B,39,95,51,7F,B1,F2,B6,4C,78,3A,A7,E3,BC,6B,85,CE,68,CB,7C,DD,80,2D,4D,35,B7,2C,A4,1E,59,1D,3A,4A,80,F8,3D,18,06,7E,BF,D0,59,F5,24,26,BA,F8,43,D6,AC,50,24,A5,F4,62,0F,EC,0F,B7,6E,6B,25,9C,19,62,14,E4,2B,A0,7B,70,99,95,0F,F8,82,8C,AD,35,CA,89,16,15,5F,F5,8A,1C,9F,B4,7D,AF,FA,57,FC,13,DD,3A,D3,8E,8C,F4,3D,8B,0B,11,F9,98,E6,C2,00,16,76,64,37,8D,CC,D9,84,78,AF,46,9D,A5,5D,F9,FD,FF,DE,44,00,D2,99,14,E1,E6,69,45,68,09,71,46,4F,5A,5B,42,DE,16,3E,D6,EB,EB,92,31,37,19,EB,19,B4,3B,52,EF,5D,27,EF,68,7A,96,72,ED,9B,05,48,F8,78,E2,F0,CF,23,6F,F3,9A,16,A3,C6,D7,BD,65,98,CB,99,42,86,82,29,73,47,5A,97,75,21,25,78,AD,AF,13,30,ED,34,E9,B1,7F,B2,1C,E0,EB,60,2B,34,2D,D7,36,02,1D,6F,2F,39,5E,26,70,C2,5F,EF,EB,B8,B5,09,07,9F,D3,71,73,34,72,D7,F2,84,DD,D0,3A,1F,89,D5,2C,83,57,BB,F3,88,4B,61,FF,63,2D,12,B9,0F,05,98,F4,01,B4,D5,37,2F,6C,EA,55,A4,89,E4,27,C3,A4,36,43,53,08,18,B8,DB,2B,49,10,05,73,D4,F5,4C,DA,D5,B4,DA,04,DF,00,3E,0E,9F,32,92,4C,AB,EC,D7,C0,28,B2,AD,47,5D,60,E5,41,D9,0A,6C,3A,F2,B2,2E,6F,90,04,7B,5D,88,C3,A7,FA,AA,F8,AA,7D,CC,7C,55,35,98,26,FB,FD,02,E5,85,BD,0F,9D,40,6D,D9,C3,C4,82,9A,84,00,10,CE,C2,7C,54,7D,64,5B,8C,E8,8F,08,27,7F,49,49,99,6C,D7,B4,30,6B,04,16,02,72,95,2B,BA,E5,C9,B4,86,A8,DE,28,C2,33,6F,76,71,3E,EE,D1,C2,6C,45,DC,56,9C,F6,86,DF,70,8D,10,CB,92,8C,A4,34,F6,23,98,57,B7,A1,2D,B7,7E,10,4E,92,0F,73,0E,E6,27,B8,8E,87,3A,89,C2,04,28,6D,4D,5D,82,ED,B0,2B,C6,90,07,F4,86,37,4C,8F,A3,0B,B4,B1,39,9C,03,A1,29,0B,0F,27,20,C4,3C,99,5A,DF,C1,D7,4D,CD,4E,69,2E,C4,BE,16,EC,D6,97,BE,5C,1E,99,2B,1A,47,F2,D3,EA,8A,2E,B5,6F,C1,E3,9C,9D,08,DF,63,9F,A2,8F,91,1D,14,33,2E,39,61,4C,92,9F,83,09,94,8A,91,1E,E4,26,11,78,14,C9,A8,CA,6D,2A,CD,C8,C0,97,96,05,FB,F5,35,B3,A1,C0,77,CB,B9,EA,55,54,01,CF,4F,64,61,8D,1A,2B,E1,4C,25,D1,4F,CD,AF,8D,E4,E6,6F,3E,DE,37,5E,F1,C9,06,3F,5B,69,97,1B,49,7C,F0,03,63,57,D6,4C,9A,B8,94,EF,A9,AB,8D,D9,8F,B4,20,07,C1,92,50,49,CC,E8,4C,C8,7A,C1,E4,CF,0F,AF,88,07,61,50,0E,CA,8A,58,6F,DC,7E,62,DC,97,3C,A8,29,C0,CA,65,FA,71,8C,49,18,E6,98,1A,41,F6,54,80,4A,90,9D,AE,C2,90,FA,15,60,57,23,12,69,80,13,1A,17,D7,3B,45,1F,46,15,1E,41,1F,E2,19,72,A6,57,6F,6E,09,24,50,4A,2C,CA,FD,0D,94,34,54,3C,8E,B7,F6,96,3F,9D,88,D1,EB,CC,8A,7E,A8,9E,31,A0,E8,E5,4E,B5,C9,25,54,B8,2B,F9,0C,EC,62,92,14,8D,93,A5,8B,6D,F7,FD,12,FC,2D,BB,25,35,D4,A6,BF,50,E8,62,A1,66,E1,01,E1,5F,59,D4,36,B0,19,D3,5D,8E,52,72,E3,A2,9C,7B,D1,36,0E,8B,EB,5F,D7,D8,F3,FC,C4,2E,63,00,8C,2D,AC,CF,7B,AD,CD,0F,CE,CC,1B,99,B8,AB,E9,AA,71,C5,E9,8B,8D,48,FE,E5,15,BD,06,9E,8D,8C,63,00,E3,AC,C8,D6,AF,42,05,9A,B2,83,7C,08,95,53,F4,89,05,A7,51,84,EC,19,31,9F,AB,4A,1B,10,22,71,D2,CB,DE,15,49,2B,3A,22,A8,1D,7B,6D,8B,72,FD,2B,0A,82,B5,5C,4B,E5,11,FF,96,80,4A,C4,40,92,EE,CC,8B,99,21,4F,23,DB,EB,46,FC,6D,79,4C,4A,E6,F5,DC,FF,26,07,0F,85,87,BC,EC,AD,6F,6D,5D,26,00,DB,B2,41,1E,1D,80,D5,60,0C,3D,8A,BB,69,63,83,69,19,60,6D,9F,05,9B,C0,C3,62,E2,29,28,54,B7,54,8B,68,75,F2,76,71,99,99,50,1D,AD,A3,ED,67,BC,54,36,83,DA,00,51,23,E7,D5,31,E2,45,7A,04,53,72,1E,E0,C4,3E,9C,2A,6C,FE,2E,62,47,19,84,6F,F4,2A,06,DD,56,9C,1E,95,BE,C9,97,07,D1,00,B4,71,CA,A9,17,65,08,96,FF,2D,1D,CD,AE,41,1F,27,E0,8F,F4,12,CC,79,23,9D,41,FB,8C,8A,E3,9A,01,51,57,EF,47,57,C6,CB,58,F9,5A,39,A3,03,00,4F,4E,A5,C4,2D,0B,49,89,1B,C7,88,37,89,82,1B,8C,AF,25,7C,84,CD,B1,70,F0,EB,95,2D,D3,AB,A8,75,34,8B,06,D5,63,06,C8,71,EF,EB,E6,34,23,B1,29,26,B5,AF,F3,85,D7,97,97,80,BC,50,7B,4B,1B,3D,93,91,1F,A7,9B,DC,43,52,0D,77,16,C7,C8,FD,B2,CA,0E,0D,87,A2,BE,D3,E0,47,9B,BE,A6,FA,AA,3C,54,70,A1,27,96,DE,67,D5,EA,C7,27,CD,DF,E2,5A,CC,CA,AB,3F,B8,20,4B,B9,D3,43,1F,17,AC,1D,DA,48,E7,F5,6E,EE,0E,1C,C0,FD,F8,B9,DC,66,3E,FA,47,2D,C6,B5,66,72,FF,65,F4,66,42,65,FF,94,64,6E,67,5E,EC,5D,54,58,38,E4,BD,D3,69,2F,F3,81,FE,D5,4A,64,E5,CC,15,86,4C,D9,03,C3,16,69,5E,DA,6D,B4,86,28,7F,19,D9,F7,80,8B,04,02,04,A2,DA,E8,1D,42,E2,C5,6F,A5,21,C6,E8,B0,2B,90,C8,BE,19,0C,05,A3,70,C6,F2,CB,92,F7,D1,80,B5,C9,46,D4,3F,0C,AF,E9,57,8F,9D,39,18,AB,FB,00,B6,4F,67,EC,8C,12,4D,6D,6E,7A,E7,2A,25,B9,76,5F,4A,E5,80,E6,5E,EE,F0,B9,4C,D4,C5,43,47,BA,90,92,55,FC,D6,22,40,4B,EA,58,0C,BD,61,0D,8F,06,5F,33,BF,3D,9A,F8,8E,9F,8F,F0,FD,02,8E,BF,EC,83,4D,E0,62,E0,21,6B,08,58,7F,D1,F4,08,68,AA,96,22,53,F5,F6,E5,C2,97,2B,3F,34,A9,38,45,0F,AD,8D,66,94,E9,54,B6,07,E0,29,46,18,A2,9F,4D,7F,79,32,D2,5A,40,85,0E,2E,D8,61,BF,86,5F,B3,CF,14,E3,13,D0,E4,25,BC,FC,70,F0,CB,AD,51,35,77,78,9C,92,0A,E4,AB,4D,59,86,9A,AA,BB,E2,CA,A2,51,03,2A,EE,E4,2D,AA,13,77,4C,BE,35,77,BE,15,87,05,2D,70,BF,33,DD,0B,8D,DE,86,AF,FA,87,9E,8A,B9,56,51,B9,29,6C,EA,23,44,F9,93,C0,BA,D3,19,02,E1,3C,C4,4B,9F,B4,D8,C7,0B,C6,1C,F4,7A,35,EB,70,46,6D,44,F8,34,90,80,A9,64,75,89,14,6E,1F,A8,CF,6E,62,8F,A8,5F,46,C1,0C,D5,06,02,F4,8F,3C,DD,55,D1,EE,94,5C,E4,38,1C,BE,9F,96,DF,FD,BC,47,55,97,68,1A,A7,35,DC,74,DB,1B,3C,AC,A6,F3,F0,72,4C,A6,85,6F,A1,54,FD,E8,4A,AF,ED,71,69,9D,24,19,87,6B,A5,FA,2F,38,AC,9D,3E,E0,01,36,02,B7,B5,BF,E0,05,71,48,DA,B2,23,59,9A,0D,A1,CC,5A,61,D3,9F,86,66,8F,4C,E0,BD,FE,44,67,06,7F,B2,F4,5C,56,9D,D8,DA,AD,9C,6B,A6,BD,8B,25,56,17,89,EE,99,EB,5D,F0,EE,71,A8,F9,CE,C8,34,51,B2,99,CA,2B,79,49,6C,1F,B7,13,D8,A5,EF,25,DA,9C,7E,2C,9E,BF,8E,84,24,F4,8F,98,D8,01,69,5D,1E,78,92,E6,89,53,E3,3B,0B,B5,6F,DB,27,B3,22,80,B7,4B,FF,D2,4A,74,B6,61,9F,8C,83,5A,5F,A5,6F,D4,D1,1B,A5,B7,EB,C9,A6,52,B4,05,C2,D7,20,DE,76,12,2A,F0,60,C5,3C,65,04,DD,80,40,A9,2F,68,7C,E4,41,D1,C0,3E,54,83,3C,2C,54,F2,26,C6,00,62,9D,56,AD,DF,A6,A2,2A,F8,E9,C2,7D,EC,17,BF,B6,E7,F7,05,85,37,54,ED,6E,1D,B5,50,1F,75,D4,40,AC,27,00,51,1E,75,F9,96,5F,F7,E2,DA,93,06,32,01,EA,67,E8,3E,AA,D3,67,C2,B2,21,8B,82,4E,CC,D9,88,E8,51,29,12,59,39,65,58,0C,AB,CE,D8,AD,54,4F,D0,5C,CC,51,13,9F,86,D7,77,F2,89,18,D4,E3,A1,6E,77,73,31,2B,C8,82,7C,C7,48,C5,39,CC,96,4A,13,4E,93,71,A9,25,8E,E9,6D,38,55,2E,FA,9F,3D,A3,AA,AE,C0,9B,F2,09,53,AD,0D,7D,2B,12,C0,51,2F,D2,C7,32,96,2E,EA,A8,1D,C9,49,C8,75,7A,B9,14,0A,E7,78,0B,6A,7C,30,7F,57,B7,61,F7,E0,1D,53,D6,CD,3E,A3,DA,AC,CA,2C,02,75,7B,CA,40,EB,FA,6D,A4,EA,86,74,DA,9A,C7,EF,8C,28,E4,3F,39,DE,FA,87,EB,A7,1D,C0,B3,BA,92,72,B8,D1,69,8F,25,E1,AE,13,E9,2E,3D,39,7E,FF,9D,FB,D5,1D,95,A3,34,B0,83,58,EF,DB,93,B7,C6,3E,2A,E9,46,FD,86,2B,DE,9D,55,E6,77,B2,26,38,39,1E,74,D7,C6,47,C3,24,A5,5C,10,BC,38,5A,53,3B,F1,EE,EA,45,F7,DE,51,82,34,96,BA,CC,CA,77,4C,5A,76,12,61,63,B9,12,E1,56,40,DE,A3,C4,96,13,9A,D3,31,78,BB,FE,18,8A,E6,43,69,5C,B9,70,CD,30,35,DD,CD,E2,E3,8C,85,C8,AB,96,F6,F2,1E,F1,9A,69,6A,C8,4B,39,40,6E,BB,EF,B4,BB,0B,23,B7,F2,A2,8C,C6,3D,A0,81,63,1D,AA,A9,91,18,12,1C,51,94,28,50,22,0A,35,D6,09,C1,3F,61,ED,27,8D,82,7C,DD,83,D1,12,43,31,24,50,41,BA,51,DF,0E,65,23,90,31,09,DF,CF,78,4D,49,16,70,DF,FC,58,78,43,8B,D1,91,1C,18,3C,04,77,8C,7E,7B,44,C8,F7,E0,B3,9F,4F,98,79,67,FD,38,2F,59,E2,34,80,EB,1E,9A,C0,92,09,BC,A5,54,F4,6C,59,C7,4B,20,BD,D5,06,41,49,B7,34,B2,AD,2B,65,80,D7,A0,7A,3B,9F,A7,AB,A1,B1,A0,69,E9,61,26,3D,E9,83,F7,1A,B4,6C,EE,00,15,0F,9C,43,28,FA,24,AB,27,EE,E3,BF,A2,FE,F7,FE,0D,88,AC,B7,49,F7,BE,7C,F3,8C,CA,F5,68,58,D0,E2,2E,82,6A,8D,9D,C5,8D,D2,9A,5D,C3,D8,1A,FD,CC,5D,0E,B2,36,BB,4F,EC,49,EC,DE,66,88,73,47,65,7D,1C,0F,31,4D,8F,34,DA,A5,75,BD,37,6E,97,AF,2D,74,FB,8D,34,6E,81,09,88,F8,0D,67,D2,C5,17,B8,62,F3,CB,28,CF,FA,FC,AF,96,51,63,D5,5A,F7,E8,28,C8,EC,96,3D,09,A6,39,C4,9F,4A,FA,4A,BE,17,15,5C,5C,14,5F,5F,04,10,99,B4,46,4B,49,2C,5A,DB,D7,CB,C2,4B,98,26,84,20,AA,B8,65,EE,03,55,6F,49,D2,4C,B1,7A,72,10,F0,60,E6,1C,BF,D1,AF,C5,6F,03,B8,DE,D4,F4,5F,51,0C,15,CF,C9,D1,ED,D8,69,6B,C7,EB,BE,F4,6B,8D,4D,F7,03,82,43,B4,BF,01,83,5D,90,2E,E1,B5,59,1D,50,38,23,26,6F,FE,7E,1B,A7,C9,BF,E7,AF,E6,49,DE,86,DE,CB,F8,22,AE,43,62,C0,BD,1F,26,64,0A,C4,49,E8,48,6A,60,7B,A4,3A,E6,23,4B,DB,9F,E0,54,38,F4,76,70,13,9B,AC,93,09,5F,F0,45,D3,18,61,B2,04,84,A8,2E,71,7C,E8,7E,3F,26,C3,C5,A6,EF,42,21,20,C3,AE,2A,41,4E,D3,46,A7,EE,AF,BD,53,D9,EB,DB,C8,11,2D,17,26,0C,B5,5D,F1,EF,2D,E5,81,29,3D,6C,C5,C8,26,0D,ED,1E,84,E9,B8,9A,0F,71,EA,9A,DF,25,9F,63,3E,F7,DC,36,26,4C,F8,8E,68,FA,3A,B8,DA,0A,71,60,EF,7A,E2,E5,6C,99,0A,86,5F,74,1E,6C,38,59,EC,EB,08,1F,0F,20,A0,38,82,C4,F8,97,DA,DE,57,6F,DE,2D,93,75,3F,36,72,9A,79,51,2B,AE,1A,B0,D1,7F,AD,79,53,08,A7,C2,6D,C5,FE,56,9E,FA,17,F6,44,71,0D,6D,A8,FE,BF,34,1C,0B,C3,DD,6C,8B,9D,C3,FD,45,3E,D4,2B,B6,F3,4A,D5,6E,E2,13,1F,EE,49,8A,92,E2,ED,EE,43,ED,C5,71,60,75,06,B7,8E,5A,51,67,FE,9A,E8,58,9A,94,B6,3B,53,2D,4A,7A,B7,F1,B8,F8,C5,32,05,99,C9,C4,88,7E,79,1B,E3,2D,23,79,2C,FD,94,36,F4,6E,F2,E0,58,16,F5,11,D2,8F,9F,5E,2E,18,C7,FC,DF,BE,87,67,9A,02,BE,3E,F9,70,F0,A4,40,97,4E,FE,CD,AC,76,B0,8A,27,32,B4,A8,29,99,84,8D,DF,36,11,3A,AF,22,99,72,53,2A,B6,D0,F1,E0,94,A7,37,9E,A8,54,3D,85,BD,27,8D,29,85,74,65,E3,5A,BC,24,B0,7C,B5,AE,0D,B0,A1,D2,F3,73,BF,74,61,28,7E,76,7A,12,60,96,75,5A,5F,2C,F1,F3,42,7B,29,28,BB,28,0A,1F,85,8C,D5,E9,9D,20,32,E0,82,CC,A4,F1,90,16,49,8F,7D,9A,8B,47,37,C2,36,1F,F0,4B,FB,47,8B,4F,DA,EF,78,82,1F,B6,9D,84,92,ED,B7,6D,D5,DB,86,A5,5F,08,F9,BD,0B,7E,AF,2E,F6,1C,37,3C,5A,AE,7C,25,A2,1D,DB,B5,39,46,07,78,66,24,33,C2,98,6E,EE,DD,CC,E4,A5,4A,44,8D,34,51,FE,B6,41,87,CA,BD,B1,D4,64,C0,A7,40,AD,03,26,A7,26,62,95,21,07,6D,E0,8F,07,E9,F6,32,32,9F,5B,AC,77,3F,C5,A6,D9,D3,2F,9D,59,AE,9F,B4,FB,53,84,DC,BE,4C,24,65,64,85,00,F8,1D,76,83,D0,3A,1B,E6,E0,3D,22,F8,64,FD,31,BE,79,C7,55,76,BF,CE,44,1B,FB,EC,59,AA,13,62,63,B3,DE,E3,D0,32,3F,22,2A,B8,FB,15,A5,F1,EE,B5,9A,D7,79,97,C2,4D,F9,83,AE,6C,59,7A,A0,D1,19,FB,90,7D,80,4F,F3,92,FB,92,1F,26,99,25,2C,B8,A1,5B,2D,EB,F5,BD,D9,65,9C,80,C9,10,B3,0F,9C,A6,60,77,1E,1F,B3,10,2D,2E,66,EC,70,45,27,AE,A9,92,1D,98,A6,78,72,93,8C,B4,F9,71,39,76,AF,C0,57,40,77,A3,5C,88,95,BB,71,23,A0,F9,24,CE,B1,C8,6C,8E,58,30,75,64,9F,8F,BF,15,31,EC,C5,6C,2D,19,F0,B4,DE,92,50,3E,E5,5A,F0,32,CE,F5,57,F4,1A,3B,DC,0B,E2,4A,FA,71,37,F3,2F,E1,D0,7C,CE,FA,77,A9,22,2E,23,0B,08,E6,2D,4A,DC,BD,B5,DD,8A,2C,14,49,F2,7B,5B,44,B6,EF,F1,AD,D0,3D,D4,20,68,17,3C,12,91,AF,D3,9A,35,FC,29,D5,62,8B,31,E2,EE,79,B5,5A,6D,CD,C0,08,3F,FF,97,C0,F1,DB,06,00,DB,2B,D1,42,0D,4A,DD,75,06,38,68,4A,FC,0B,13,24,44,5C,31,70,51,DB,14,A0,DF,04,FE,DA,CD,E5,52,63,11,B1,6F,52,67,EB,17,D7,D0,24,AF,3C,B3,68,58,59,BA,2A,6F,14,9F,18,A9,AE,2F,E4,6D,07,34,BC,7C,6C,3E,00,07,3B,B6,4C,4A,17,14,97,5B,B1,2D,15,74,BD,64,6D,DE,D4,75,01,C6,4F,ED,E9,66,05,63,AB,FC,FD,0D,51,90,0F,AB,90,41,99,97,05,FF,BC,ED,65,DF,12,41,9E,6E,21,BB,0B,C9,4B,FB,1C,C4,6C,41,CF,DF,A9,AA,13,F0,FD,75,56,19,FF,9B,AF,35,02,02,EF,E3,B8,0B,22,59,10,E5,60,B9,61,B3,63,C6,3F,FF,9C,C7,43,CC,B0,8B,AF,C4,38,AB,7E,41,C4,ED,31,BF,52,FD,20,F3,FA,CE,77,FF,4A,3C,4D,8A,51,B4,5F,DA,54,E2,A4,D2,02,D1,D5,85,88,AE,CB,E0,00,82,96,31,73,2F,E6,E8,1C,1F,40,99,DB,BC,D0,53,E5,AB,52,EA,FB,60,0F,B1,CD,6F,56,03,AB,01,FB,A2,6E,BA,72,6E,F9,7B,81,12,35,CC,89,EA,2E,7D,4B,E9,25,06,4D,7D,30,33,6A,AF,E0,29,61,4D,82,65,81,DB,8C,6B,67,AE,3C,4B,8F,1C,24,ED,E0,8D,A8,81,1E,96,96,F8,82,14,65,CA,CD,5D,29,E9,0C,3F,C3,8F,42,97,C5,06,77,D6,95,3D,04,BF,39,78,A7,10,8A,44,B8,2A,EC,92,57,31,3D,7C,CB,55,F2,26,B6,24,F7,2A,B9,B0,94,BF,37,38,90,73,A1,DC,74,74,B4,D2,3A,34,3E,E1,A3,ED,E3,66,BC,96,C8,DF,00,28,86,07,76,D6,E6,2E,F5,1C,BF,17,09,05,3D,E1,75,3E,71,2E,73,6C,C0,99,C5,17,25,4D,43,CB,87,10,47,6E,D4,75,89,09,AF,A5,D9,BE,1B,49,89,53,81,6C,75,15,8D,4A,89,A9,5E,09,0C,CE,0F,81,DE,DB,A9,81,37,5A,90,36,D8,A0,F3,84,01,29,94,EA,A1,0F,8A,90,0B,23,98,E2,91,05,55,EC,9E,6F,58,A5,23,D3,58,2D,07,D7,21,12,99,08,DE,3E,44,ED,FB,DD,B0,F4,92,9C,7A,AC,B5,C6,D5,1B,D5,DC,F2,26,7D,95,33,4D,E5,E6,AD,32,6C,B7,7C,E5,32,8C,EC,76,25,FD,BA,F3,5D,0A,20,04,38,51,DA,9A,1F,36,8A,51,47,D9,40,0F,CE,0E,A8,63,DC,76,EC,A0,EC,94,DB,88,FB,10,70,F7,68,47,39,6A,2C,19,30,C2,A7,B4,8A,F3,8B,CE,C2,57,FB,7F,DD,90,BF,65,26,64,D3,06,60,FD,D4,99,92,23,1D,01,5D,C8,71,42,62,A4,22,7E,4E,8D,80,9F,A1,43,19,38,4E,8D,AF,10,52,CA,22,A1,A3,E4,AD,3C,D0,73,3D,2E,6F,F5,38,CB,E5,AD,20,78,CE,89,F4,05,15,63,6D,57,CC,72,97,7A,A2,F3,8F,DC,55,B1,31,A9,AA,2B,48,2C,34,83,62,41,FC,EA,B5,27,A1,81,A9,1A,C4,DA,5C,61,50,98,E4,B1,88,C5,A6,B2,96,31,07,5A,5B,48,5A,54,2A,7B,02,4D,E5,89,7F,95,96,05,DA,7B,EE,81,41,CB,E5,32,69,CD,3F,38,F6,97,1E,E7,47,15,81,2D,95,91,FC,C2,32,EC,1D,AB,D1,B1,58,65,7A,9D,A8,B0,2F,19,38,25,4D,E6,F4,B3,5A,EE,5E,F0,51,46,53,27,50,E0,AC,A2,FE,DC,33,B0,9F,F3,49,14,08,4E,9F,41,5E,29,60,D6,2F,06,B0,3C,46,F9,E4,96,71,0D,D3,5F,AD,28,84,EA,B1,44,EE,E3,6F,17,D5,85,14,7A,DE,B3,DC,0C,56,F0,34,3C,5D,5E,41,30,59,26,AD,3B,51,9D,5A,9E,AC,EF,03,67,C2,06,33,0F,42,77,85,68,6E,A2,13,54,48,90,9E,CB,AD,CB,1D,EC,62,DC,18,1B,B4,D1,7F,4A,06,C4,F9,C3,A9,68,EC,1F,9E,6A,D6,17,51,B0,0F,3C,11,B1,E9,AF,7D,AF,4F,69,5E,0F,F2,F7,C1,93,C3,53,C7,49,69,B7,67,DA,A0,C5,7E,C8,AE,01,0A,0E,AD,3E,22,43,F5,EF,37,DF,05,98,FC,88,53,49,A6,25,A0,39,48,B6,2E,3E,46,78,82,9F,47,A9,33,34,B7,08,9B,FA,E5,D5,86,82,BB,69,8A,CE,B8,51,36,06,67,FE,3A,58,5F,F7,69,0E,3A,09,7D,9F,99,26,70,F6,34,65,E0,B9,12,58,76,07,59,86,AD,D6,14,94,0D,D9,2F,BA,E4,30,10,02,9E,77,5F,89,59,36,28,D0,63,F1,01,D6,10,21,98,E8,E5,47,AA,F3,47,20,21,74,35,92,E9,5D,DA,58,BB,46,16,6C,E6,18,10,AB,61,0F,48,AA,15,BF,36,18,29,F6,7D,87,9B,F7,A5,78,BC,2A,13,DC,40,E9,48,6E,1A,9A,A9,2E,74,98,59,04,0F,95,A8,62,EF,07,40,70,87,3B,AB,23,73,3B,2D,01,E3,5B,A7,79,8B,0B,FC,9E,64,EE,D6,D0,B8,60,9E,1D,7D,81,66,21,71,C1,46,9A,DE,26,65,ED,09,C9,E5,2B,29,0C,D4,77,7F,D1,D5,73,67,D7,7F,65,77,6E,E7,36,39,8E,9D,BC,19,AA,43,E6,90,E7,DB,07,94,B3,EB,D4,29,5A,40,95,8C,00,57,90,E6,8E,21,A6,34,43,BC,92,6F,F2,97,FF,38,B7,D6,A4,3E,8B,12,A5,F9,70,8A,EA,F2,12,72,17,28,15,FD,72,83,1D,77,18,91,59,52,46,97,7E,3D,29,C3,4C,C2,E2,B5,73,9B,72,81,3E,00,8C,85,2E,93,63,1B,C6,88,CB,EB,26,62,B4,E0,88,11,4C,84,D8,8B,BD,88,C9,90,38,64,BF,C5,B4,A4,97,B7,7E,18,61,F8,82,7D,6D,C8,2D,C0,B3,4C,A7,2C,00,02,D5,B9,75,BD,34,28,B3,A1,5F,67,FF,46,8F,9E,9C,4E,7A,73,74,CC,63,FE,6C,99,F1,3E,1F,34,6D,03,04,B4,1F,0D,EC,E5,23,90,A5,49,0E,E1,6C,78,52,D0,4C,2A,DA,2F,0A,77,8F,D8,74,F6,EE,3E,AA,57,26,5A,D8,0C,DD,DF,90,97,48,47,62,A3,71,F5,D8,94,A2,10,04,26,D2,12,24,6C,D0,0A,C8,AA,15,B4,79,62,C2,77,A9,1C,29,33,D5,5E,23,00,BF,E8,13,78,7D,61,A1,C3,0A,7C,77,87,76,BA,B5,89,D1,26,78,A6,3B,F4,F4,38,B2,FB,9D,17,38,E4,57,78,51,47,09,5D,84,25,00,94,E8,78,86,78,E9,1D,38,3A,42,B1,92,B7,B6,51,01,BA,FE,4A,3F,C9,9E,37,AF,85,5D,11,F3,93,50,4C,C6,7C,2F,B7,C8,9C,B5,BD,C5,5C,6A,E5,D3,A9,1F,79,5D,8E,65,F0,67,49,CA,44,6B,90,4B,D1,56,3F,21,1B,E0,FA,80,75,01,8E,F3,B4,17,0E,85,EE,27,EC,7F,94,C1,3D,8A,2E,CE,49,39,24,65,1A,25,CC,7E,91,C3,64,BE,A0,7A,B5,B7,3E,4D,B3,41,53,EA,8C,DF,0A,E4,96,61,82,5D,12,83,67,72,6E,F3,20,F1,E2,94,20,62,26,5C,60,7D,D9,3C,2F,6C,A2,42,C2,BA,07,22,94,5D,A2,9C,05,93,0C,AD,94,0E,77,B4,BC,8F,CC,3D,09,84,F9,81,C4,11,F9,A5,F6,41,26,21,0B,10,54,B6,69,76,2B,DC,CC,01,11,43,C7,D5,9F,F7,61,67,1B,B0,65,E0,9F,11,F5,5C,4A,BC,D4,C7,7F,8F,DF,F5,3A,D8,58,AF,7B,D0,B3,32,7F,BC,0E,B2,7C,CB,47,AE,47,5F,D6,61,1D,20,5C,27,6D,DE,1B,56,4D,82,02,05,1A,93,87,F4,BB,81,B3,99,9A,31,8B,EF,B1,82,28,57,5B,5B,42,12,83,D9,6A,99,C4,21,2C,64,E8,D3,28,7A,5C,97,9D,BE,D8,62,E2,02,D5,ED,64,29,B0,AB,D8,8E,94,10,28,B5,B3,C6,EF,7C,54,CF,72,54,4A,70,B4,70,3E,92,9A,FB,49,59,62,19,4C,B4,A9,2A,79,F5,62,40,5C,B6,B6,A1,2F,66,15,50,21,D0,2F,9B,22,94,84,40,30,8F,25,66,8A,2E,30,56,6D,C8,DA,8F,3A,BC,90,90,49,BA,B9,A5,D8,C7,8A,72,46,A6,54,5F,D0,1E,DB,B4,13,72,12,3D,48,18,A2,4D,C8,CE,52,D5,6A,87,9C,B6,62,13,46,31,B5,7D,37,09,0F,B1,3A,41,7C,EC,36,19,5F,51,0D,23,52,6C,54,B9,83,59,84,E1,67,B8,91,39,2C,A2,D9,3D,E9,F8,26,69,9C,02,77,E8,59,53,E0,D6,2D,2B,D4,59,43,23,DA,8C,89,A5,1F,D0,AE,44,A7,01,A8,94,4B,CC,E3,17,A4,B1,26,4F,5E,B3,35,FC,31,3B,67,DD,52,4C,42,D7,05,05,5A,97,3C,90,83,AD,2C,E1,AD,23,9B,59,76,F8,A2,1D,FF,C6,4A,ED,01,62,E5,5D,9E,10,14,69,E2,30,0B,34,5A,20,89,7C,C3,AF,32,F7,D0,B1,7A,D9,65,4C,FF,72,C7,E9,01,82,EA,A2,2F,69,AF,AD,93,C4,D7,AA,69,CE,43,AE,4E,3D,62,25,76,E2,69,43,A7,7E,7B,6D,29,00,9C,0A,7E,1B,02,09,42,7D,DA,E9,B2,E3,FD,EA,19,86,DE,32,1B,32,C4,E6,34,FC,DA,98,29,16,C2,31,9D,21,EA,96,0F,1B,AB,A3,6F,84,25,FB,AD,AF,C4,B0,1C,5A,99,A6,06,52,58,B9,A6,08,0B,FA,05,1F,41,79,73,40,B1,C8,00,24,C1,BA,43,E6,94,6F,7C,14,96,85,51,75,ED,D9,FB,A5,66,48,0B,87,05,86,AE,41,2A,38,62,54,83,78,B2,2C,84,F1,F4,47,08,8F,9D,E2,38,3E,C7,2B,84,2F,62,10,0B,F4,B1,52,21,C2,5E,57,8E,14,B2,49,BF,30,C0,57,9A,51,E0,A9,E7,81,46,04,C5,39,E3,7F,45,56,D8,E6,B5,A0,12,D6,9B,7E,00,10,FB,47,C1,CE,DC,53,AF,97,1C,44,EC,F2,69,64,47,EB,EC,BF,53,4D,AD,34,2A,50,98,1D,C1,56,24,BB,74,73,33,90,D9,AA,CE,09,1B,A4,F1,75,BA,00,A3,CB,9E,29,52,E5,53,57,B1,30,CA,0B,8B,1C,78,9E,AA,D4,E6,9E,7F,54,91,87,35,CC,68,BF,B0,21,9B,52,77,84,98,9D,B6,D4,49,73,C6,44,4E,BC,49,91,7E,85,F5,A4,4B,31,05,79,AD,65,E8,D2,3B,F6,0D,94,61,83,E0,B0,C7,22,BC,69,DA,2A,56,D9,B8,19,5B,CF,FE,C7,6F,9B,49,8D,CD,27,A3,41,36,92,34,4B,81,1C,CC,FA,33,B4,C1,EB,41,41,E9,03,A4,7A,27,CE,B7,A7,87,EA,AD,F8,E9,05,3A,6D,F6,C1,F6,82,A9,0B,39,14,F1,7D,90,32,CA,AA,64,2C,A5,5A,6F,BB,1A,F5,16,47,6B,96,DD,FA,2F,B3,BE,D3,0F,F4,66,CC,49,CC,58,04,7F,59,20,71,1C,56,83,E1,34,07,4B,04,FB,CB,1B,70,0D,4A,6B,29,F2,AE,C4,C5,19,85,33,72,1B,06,AE,C9,DA,99,D8,6B,25,CE,E9,65,BA,00,85,84,7C,3E,CC,E2,FB,A2,4E,C4,27,9F,86,4F,04,46,07,2E,54,57,F3,D6,D7,49,02,48,F2,7F,28,16,F1,54,1C,37,A8,70,76,63,18,FD,C8,EE,12,04,16,43,7B,D9,8B,3C,11,26,BF,C2,8E,AB,29,7F,A5,D9,33,D6,B0,EB,F3,AA,5E,99,B0,9C,B7,52,E5,1D,D8,A2,AE,23,ED,EA,1E,18,1A,55,5D,F0,EE,36,05,D4,67,FD,17,20,28,1E,FF,87,D0,49,B8,2F,E5,51,5F,4F,52,F8,D3,F9,66,B3,0B,8D,6D,B7,49,3E,C4,D0,B2,3C,1B,6C,EE,20,D1,6A,A1,7D,9A,F0,34,AC,9C,EF,18,95,4B,79,8E,58,78,06,A8,44,39,64,65,31,9E,5E,34,71,2F,23,D3,C3,E0,63,63,EE,FD,AD,CE,4F,0C,80,DD,D4,AF,F1,BD,81,D7,0B,6C,2D,85,F7,10,A8,EB,14,1D,3B,71,2C,97,65,EF,27,22,CB,AC,14,5F,E1,71,E9,0B,3C,BB,00,48,5B,51,D9,75,83,7D,5C,CA,5C,D0,C3,41,A6,CB,C3,1F,8C,51,F2,20,99,13,81,92,41,17,4B,F1,07,68,4D,7A,B1,00,7E,51,50,16,3A,32,E7,DE,B0,60,CB,06,7E,CE,2D,B2,70,0F,81,78,E5,7B,C7,48,59,24,B2,59,44,85,29,A0,B4,2B,E2,A6,C0,BC,70,4A,3B,DB,C6,D4,FC,D9,90,11,F9,F1,6B,E4,0F,82,F6,E3,A9,6D,64,34,81,6B,12,36,57,6A,50,50,3E,19,14,9A,DD,07,A0,44,2C,6F,1B,F8,23,82,F5,23,73,C5,8C,6F,E4,E6,4E,E2,E3,32,37,C4,9A,78,3C,8F,F8,DF,4E,55,DC,E8,BC,98,9F,8A,93,51,D4,F0,7A,5A,70,2A,FE,48,06,06,BB,88,C2,BA,D5,8D,4D,B9,51,EB,17,04,47,A8,3B,E9,1F,55,C0,EB,5C,89,8F,77,DA,E2,17,A5,65,A7,6E,A2,80,AF,9C,D1,16,05,79,58,19,C6,E3,8C,DE,7E,B9,14,2F,3E,E0,13,F7,8A,69,13,D2,F0,09,DD,0C,3B,51,6D,0E,65,2F,58,F0,EC,7E,B0,4D,5C,62,4B,DA,5C,F6,D1,3C,41,56,69,E2,8D,2E,D7,20,AA,C6,D5,00,AE,85,D7,87,25,1D,0C,84,E7,49,60,0D,F8,3F,C8,CC,23,98,26,32,49,BD,24,52,65,98,E5,5D,4E,C0,27,97,26,D3,51,37,D0,CB,B4,2C,5A,03,FE,B5,6F,B4,FE,C4,43,B7,10,A4,A6,94,1B,D9,18,11,24,0F,FA,68,92,F9,D6,58,02,97,CD,09,27,28,17,7A,59,D4,52,95,A4,03,C0,B4,EB,5A,35,12,0D,60,4A,5B,CE,31,D3,85,78,F3,F0,0B,12,B6,97,E4,B7,16,ED,ED,EA,11,DE,09,E4,87,ED,50,BD,48,7F,0D,07,6E,21,22,76,12,47,02,00,A4,10,D1,0F,5D,0C,1E,7F,18,B9,0B,50,16,EF,C3,11,09,0F,D7,20,AF,58,51,F0,88,49,47,92,AB,0E,06,F2,84,9A,B3,17,79,A8,60,EF,AF,D6,79,80,DB,EE,42,CE,6C,58,74,E4,08,BD,74,4D,3C,B7,F7,5B,4F,CF,B9,B3,49,09,2D,61,17,96,50,D2,E9,E3,EA,F8,3B,2C,52,AE,C7,56,46,E4,CF,09,F4,D8,C1,46,4E,3D,B2,CB,7C,92,8C,A5,01,D3,91,9D,09,F0,32,B7,6C,57,C1,F8,25,B9,BA,49,86,C2,39,FD,60,CB,F4,2A,C9,CD,08,54,15,22,94,03,8A,7B,5E,26,17,70,8E,D0,27,54,3C,CB,F6,D5,43,00,98,83,62,CA,EB,53,52,F0,B4,81,29,B7,4B,EF,74,11,23,7A,FB,9F,DD,0E,E6,64,F1,80,1E,42,5C,9A,11,A9,CC,D3,3E,5D,0A,34,50,E7,F7,94,BA,EB,52,4A,54,04,85,05,2D,CD,86,19,95,13,22,58,D6,AF,DD,80,63,AF,3F,9D,6B,4C,40,4E,CE,BF,83,55,5A,71,9F,3D,AA,C2,35,03,F6,3B,15,C0,04,13,D4,62,B2,50,EC,7A,9E,8E,21,E8,31,DC,C9,F9,A4,D5,D9,82,3B,7F,38,0A,E0,F5,DE,C7,33,5A,15,F1,7C,80,42,E0,61,00,B8,87,38,43,70,AB,33,9F,59,93,F2,2C,86,E3,BB,FE,85,E7,3A,67,34,3D,28,6A,D2,6F,EB,CD,D5,92,4C,BD,E7,E8,5A,A4,39,21,E1,6E,D1,E6,F5,69,E3,4A,CA,C9,41,C6,0E,F1,91,E6,DC,A2,14,DC,FD,75,DE,51,8B,DB,A2,C9,27,EA,B1,60,59,2D,91,AD,44,BD,53,3C,96,4F,AD,F7,DB,42,50,53,1E,BF,BB,0E,C8,97,4F,09,6F,AC,25,BF,0C,D5,83,30,B9,C1,61,93,9E,35,BC,BE,09,28,51,EB,5A,6C,65,91,43,E1,80,B7,8C,4E,F8,FF,2F,5D,70,57,58,5F,8E,E1,29,BC,A2,ED,4E,86,B5,64,CF,81,BA,66,27,26,ED,E1,FB,2B,6A,32,14,4E,4C,29,5A,E6,1F,3F,1D,71,AE,D6,12,F3,81,B2,F4,E2,02,3F,AC,C0,A7,39,68,9A,B8,B7,6A,B7,E6,63,FD,E0,AA,13,FF,76,BD,B1,C7,4B,31,A8,80,C2,51,EA,31,7B,9D,D5,89,D6,7C,8C,A7,1C,76,31,D0,ED,C5,15,06,2C,FD,79,A5,78,FF,01,AD,8E,E7,E9,A6,B2,2A,D1,0D,57,01,2C,28,7E,DC,93,33,70,BF,68,37,F7,FF,C4,C3,55,6C,2A,C5,60,6E,A6,5D,BD,42,F8,25,03,AC,3F,1C,99,42,FC,FA,DC,87,51,CA,35,C4,FF,50,50,2F,77,A1,76,23,81,7F,59,D4,CB,D6,18,43,07,85,50,EA,7C,4B,A0,C7,9B,90,2D,2D,69,9A,C6,05,0A,80,0C,EF,EF,ED,15,EE,1A,8E,39,60,77,D5,0A,C6,26,EE,50,2A,7E,9C,6B,83,EB,64,C0,FA,63,F9,DB,94,0F,76,15,62,97,0E,23,09,4D,36,88,7E,D9,26,20,C0,4E,7D,91,27,0A,40,33,CC,4C,02,7D,A0,71,DB,7A,19,BD,F5,5A,73,64,2B,CE,38,0F,50,CE,3E,40,3D,04,6C,08,1B,EE,EA,EE,87,A0,58,C2,F6,0A,66,8B,1C,20,64,48,60,B3,B7,CA,9A,F1,80,7B,0B,78,C7,F6,67,97,6F,11,C2,CD,53,E4,83,CC,60,35,CB,6C,70,E5,25,8B,E2,74,72,F0,A4,C6,3A,4B,A4,EF,EE,9B,B0,AD,D3,1A,C9,27,65,C4,3B,48,D8,47,71,79,3A,6B,1B,48,E6,34,C6,67,5D,D0,F6,42,06,9E,97,C6,BD,F5,C7,30,67,A7,DE,37,7A,78,44,98,54,CD,A1,1F,46,90,FA,B7,4D,5A,72,EA,E0,9A,A3,18,F4,61,A4,B6,94,67,A9,BB,3B,A9,DA,04,33,40,8B,26,E3,4A,C9,4D,86,74,04,8B,3C,77,91,6B,B6,64,86,D0,C1,3E,A4,F1,8B,2A,5E,17,F6,B6,6D,08,53,4D,85,B8,96,5A,07,9E,DF,4F,E5,BB,D5,10,AB,B3,6D,3D,0F,2E,F0,66,EA,75,11,C5,5F,8E,9E,74,5E,66,43,26,34,E4,77,F7,88,2C,D0,1D,B7,13,EF,3C,6E,83,E1,A4,C3,74,20,1C,4B,46,52,31,27,BD,18,FF,95,F8,2A,A6,C6,0D,F1,D3,3E,D1,6A,C2,75,B7,74,C5,31,2F,90,BE,DF,B8,D6,61,A8,A7,9E,98,43,37,97,F2,69,8A,7E,9B,56,1A,9B,73,1D,08,B4,71,42,5F,C4,89,18,C0,1D,92,23,C6,8D,E3,4D,98,44,4D,3F,22,B4,E4,FF,6A,29,37,38,9D,59,13,61,47,74,E4,BE,1C,E3,B9,CC,39,FA,1C,47,0E,C2,47,F2,9A,31,95,FA,CE,DC,2E,15,27,29,F0,69,EA,F4,BC,71,68,71,FF,6A,C7,5B,58,CB,86,F2,B7,60,30,8B,FA,29,69,6F,47,1E,3A,CC,AB,5A,5D,55,81,66,0C,33,E3,24,09,34,B1,E4,9D,91,A0,21,C1,B6,F3,82,A5,85,EB,70,3E,5E,76,21,97,48,D6,B7,14,76,E6,6D,7C,9B,B8,4E,03,5B,AA,78,51,06,EF,DA,89,F4,BD,3A,4B,58,3C,B2,D7,E0,69,F6,24,8A,BC,96,30,3D,D6,04,11,5B,D7,55,97,C7,97,6E,52,0D,2A,8E,31,27,12,9B,20,E9,46,27,32,32,7C,57,D1,F4,3A,8B,42,48,72,12,01,CD,7A,9B,1A,BD,7A,9C,44,59,B2,58,9D,42,3F,4C,E3,2B,86,21,B2,DB,E0,5A,0F,41,87,DB,78,44,CB,D0,EF,06,73,0B,DC,E3,1F,6B,0C,E1,35,E4,BA,3A,D8,36,3D,F1,93,1E,BF,76,BC,06,F5,55,07,57,E9,C2,8B,55,B5,06,B7,D3,5C,B8,D9,2C,0D,B1,12,0E,A3,EC,82,12,A3,73,E5,AF,20,3A,59,67,4E,0E,90,3A,3F,A9,39,1D,71,E4,8B,AC,6A,E2,94,2D,DC,8F,9C,74,20,24,0C,63,A1,25,59,9D,7C,07,60,C0,A7,DF,74,40,CD,74,96,F8,5B,A4,17,78,D7,7C,1A,17,D5,B0,9D,C8,73,0D,92,43,19,B4,18,18,C8,84,3F,4F,C3,0B,A7,4A,35,C8,58,A3,E2,B0,BF,D2,8F,2D,B6,AE,BB,F8,17,99,F9,40,FB,E0,2D,26,75,96,19,8F,38,4F,9C,86,97,52,86,E4,21,94,2E,B4,CD,CD,AB,65,D6,83,03,17,C1,9C,D7,9A,5D,6A,F1,FA,AD,F3,8E,26,E6,8C,1A,15,91,AA,0B,F1,BA,B1,4E,EE,47,07,19,67,D5,2F,AD,DA,44,C7,4D,42,EB,F3,24,70,45,4A,EF,7A,E0,E2,9F,5F,A2,26,83,E1,4C,53,3C,48,A9,C0,A7,7B,C0,16,0A,B6,D2,F2,49,10,A3,FE,6C,54,1D,E3,89,D7,60,15,2D,0C,03,3F,4D,CD,A6,5E,70,ED,3F,B7,2A,E7,21,C7,01,42,DE,A7,72,BC,F9,2A,1C,78,FE,78,9E,20,80,9F,83,EA,D9,1A,FA,D1,78,99,32,B5,F7,FB,DC,75,83,BC,34,0A,82,85,5C,9E,2E,03,8D,4A,C5,82,86,8E,AA,1A,B9,F0,AB,B7,B5,59,58,07,26,8D,DD,5E,8F,52,1C,8D,D0,63,B0,8D,CA,C8,63,6C,FB,6A,8E,02,D3,54,32,F1,D5,F8,A5,AB,EE,4F,6A,3E,D2,2C,F0,08,2B,DC,F6,AF,8D,C3,A5,60,3C,D5,2E,87,44,18,48,B1,99,7A,26,45,06,1A,88,2B,05,73,CF,EF,B4,35,DF,AF,43,0F,8A,53,9F,FA,11,D6,0D,A8,82,B1,1C,2A,FD,FF,2C,BD,88,A3,C5,31,3D,68,73,C8,ED,F6,82,A0,28,F6,52,B7,5C,82,64,92,9C,89,19,A6,13,5B,F7,E4,1D,E7,DB,3B,3E,45,13,49,0C,FE,43,BE,5D,7D,E4,E0,99,91,18,8E,F8,62,36,DB,F3,BF,36,81,6E,5F,5F,76,D9,80,D9,91,DE,21,32,CC,B3,9B,73,BD,F6,C2,B4,9C,40,F0,EC,25,A3,78,4D,AD,C1,20,42,D3,BA,AD,10,43,B0,3A,F9,6C,4A,6B,13,32,71,AD,C1,40,31,C9,B0,75,04,A0,A6,53,E6,2B,59,D9,D7,7D,42,36,B2,68,6A,DD,C6,95,38,E0,C0,14,19,5C,82,3E,3C,62,CE,D8,77,F7,FF,61,73,E7,62,BB,C9,0E,7E,67,14,85,8B,7F,55,DF,B8,5E,4E,31,CC,21,2D,C0,5A,8A,24,60,E5,E3,E5,05,5D,4C,3F,39,71,40,1B,C7,AC,0E,2E,91,DF,12,EB,BA,30,4D,B2,5B,5A,6E,63,B3,5C,01,2C,F4,5F,D5,1A,4A,8E,8E,9E,D7,C7,1C,B8,46,B4,31,0F,A8,4A,38,E6,6E,5D,DB,5E,3F,CE,83,A4,A4,78,77,71,28,06,37,ED,B0,89,39,7D,6A,19,40,F3,BC,A2,98,60,FA,75,F8,E0,A1,B5,C6,95,8D,67,91,67,15,DB,68,8F,72,E6,0D,BB,8B,A7,6B,CB,D9,71,0B,9C,5C,F9,DC,CA,7B,45,9F,14,35,CE,58,CD,73,47,9F,83,07,EF,DD,EA,24,CE,E6,FA,D6,00,EE,56,51,45,76,B9,D4,71,88,A5,22,4F,BA,02,75,B9,1D,8D,CC,2F,58,F4,42,75,8B,13,6D,3E,BE,7F,19,7F,30,6A,57,D2,E7,EB,04,6F,C1,5A,ED,5F,E8,48,0A,A0,B1,4E,49,5B,51,33,0F,2D,6C,9B,A4,24,6B,E3,C0,38,E1,44,A5,80,69,CD,74,08,EB,E3,73,4A,90,1F,AC,DE,44,BF,B1,03,5F,AD,16,38,4F,13,3A,DA,4C,17,BA,AE,48,D0,40,D6,3F,64,E1,85,67,DC,31,3D,C7,25,BB,B3,EE,52,8C,9F,7B,A5,7A,DA,F2,EC,4B,23,31,D0,1E,22,0B,C5,B1,04,B1,A9,41,0A,86,1E,9B,98,C0,46,2F,ED,5A,0F,03,47,F8,AB,76,70,7B,71,20,6D,C3,7D,78,E4,96,24,C6,AD,68,81,79,A9,6E,76,8A,EC,C1,9B,21,00,22,69,F7,DB,13,8F,51,DA,E8,30,C0,6D,4A,70,78,4A,B6,A6,3A,F5,36,DF,64,AA,B0,79,F7,CE,02,20,E9,CA,C5,12,BA,43,5C,5E,7D,E6,C7,63,CD,18,A8,D4,A2,1D,B0,8E,54,F9,D5,F6,23,CB,8A,77,97,CB,06,18,C6,53,08,0D,CA,65,F2,3B,DD,07,A3,7E,44,E0,90,37,55,8E,48,77,6D,D3,0A,8D,C6,E9,27,44,F0,19,18,BC,29,F3,16,96,29,B0,D0,C5,14,79,AC,22,94,AA,27,81,5F,BB,06,FD,8A,18,23,A4,11,38,11,FC,11,24,6B,42,29,E3,48,2F,F3,BC,20,07,1E,13,A4,24,05,54,8B,3E,92,25,64,77,FC,01,26,1B,85,54,3A,D7,C6,2A,2E,BB,86,49,36,AE,43,DB,D6,50,F8,FA,A7,50,DB,B4,FD,CC,36,C1,1D,94,45,F5,BF,BA,8B,CE,86,B7,F6,CE,7D,3A,EE,88,F1,9A,F0,61,A7,6A,95,DA,A7,11,22,7A,F0,E7,A2,9D,68,4D,50,24,10,EC,11,BD,09,11,2D,CE,CA,CA,86,65,62,D3,31,0C,51,8F,7F,63,FE,4A,64,2C,78,41,1A,F6,11,C0,63,46,52,02,9F,9C,64,93,43,E4,77,BA,81,B2,7C,F5,F2,C9,DB,B5,76,91,63,02,92,A2,11,19,A7,8D,C3,29,44,CC,7B,21,65,BD,F9,46,0F,6A,35,4F,10,26,7E,43,87,9E,BE,7E,1A,CA,8D,E2,2F,CA,55,E6,17,2F,36,10,AE,F4,3E,5D,03,4A,7B,CC,5A,8B,A7,00,D1,3A,49,C0,46,3F,36,5D,87,18,8C,85,6E,F4,FF,D6,BD,7C,85,1A,B7,26,F3,86,39,FF,59,9D,ED,27,F8,3F,63,E7,4C,E2,2F,3C,8B,FF,4F,95,27,5D,D3,AD,63,8B,29,78,2C,39,7F,4A,91,FF,91,82,59,EC,25,21,01,43,00,30,7D,1E,42,31,0E,B3,A6,50,42,FB,71,27,BB,24,41,65,5B,8A,2C,B1,28,E2,DE,5C,3E,EB,1A,33,BD,87,7B,25,45,4A,69,4E,5F,94,85,E2,C5,2F,7F,E2,BA,E7,4E,FE,58,69,68,FE,43,FA,D5,43,A5,38,09,96,31,BA,17,35,6D,94,94,26,6C,94,96,2D,BA,03,3E,C9,C8,83,00,30,6C,AC,2A,66,77,DD,10,B9,8C,39,F1,40,82,34,D1,88,3B,6D,E1,77,E0,6F,75,BB,29,B3,99,08,D0,E1,C3,95,51,BB,46,9E,FE,EC,68,F5,53,4A,3A,CA,BE,B1,9E,3B,A4,BE,7E,39,A6,F2,49,56,BB,A8,D6,35,0C,DC,AF,E7,0F,44,5B,08,3D,DF,02,C6,C8,38,AE,1E,03,8E,C1,B7,57,BA,9C,95,0A,DB,86,3F,99,C0,3E,BF,DC,92,6E,11,21,01,C7,9D,2F,5D,AB,96,09,4E,E6,26,F4,2E,B7,BD,FD,A2,60,F0,60,21,D7,A6,97,59,96,59,6B,FD,AB,E4,1F,87,F3,C7,3F,1C,18,30,41,DF,E9,E5,22,BB,97,EC,C9,7E,6D,F1,CF,46,23,D1,73,B6,12,9D,37,E4,F5,0D,F2,59,A5,3F,90,A9,B1,D6,8A,2B,24,B3,6A,BA,51,D5,B6,79,E7,F8,B7,E7,17,A0,A0,33,F0,66,A0,F1,7D,20,88,3C,EE,78,E8,62,CB,F7,64,57,3A,87,B6,86,92,3D,62,76,D9,E2,B1,2A,F1,F3,33,4B,E3,D7,F9,1F,42,35,0B,C0,3E,A7,AE,FB,B7,EA,79,43,36,2A,CB,E7,D4,DB,09,9F,0A,8A,3A,E4,F2,98,78,D6,60,11,B3,C0,86,F3,4F,BF,42,68,4B,7D,5F,B7,1E,21,1F,8B,DB,A2,83,11,FE,7F,6F,9E,DE,C3,31,81,20,95,BD,B4,B2,E4,C9,72,3F,20,54,4C,81,1D,38,C7,8F,29,D3,95,72,93,B8,A3,52,6D,68,AD,F4,34,C1,6A,8A,C3,6D,B0,14,BF,8E,F4,0D,E6,BE,B4,24,92,B1,D9,15,5D,80,63,07,01,CD,12,8A,7E,08,CD,CD,0B,A2,15,E7,D7,07,C8,D0,91,A1,72,3B,CB,D4,45,7A,3B,55,38,8A,7F,F6,3E,52,50,7A,D9,03,F0,AB,C5,86,0E,24,6C,0F,E8,E5,43,55,99,6B,CF,35,3E,D7,6D,FB,65,92,7A,13,12,05,9D,62,39,BB,4D,A6,92,42,EF,20,10,25,26,A4,61,E5,12,F3,93,47,FF,02,E1,94,8A,CD,EB,6C,4A,68,1B,D8,1F,B2,C8,2F,44,CD,57,F1,CE,15,FD,5E,42,1B,9C,7B,BE,12,59,90,70,29,FE,13,3C,8D,AA,D2,63,94,6E,3C,04,45,57,61,EE,0E,D3,B3,FC,70,22,DA,29,65,4E,0B,AC,A5,C1,F4,79,46,D7,89,7B,D1,60,E0,80,2F,7A,A2,98,93,4E,F7,71,B9,EC,AF,7F,03,14,67,87,E0,F4,F9,67,23,C9,1D,0F,29,19,40,7B,94,88,21,79,B4,0B,57,93,A9,D8,E6,8F,47,E2,78,7D,0B,FF,D3,CE,07,1D,B7,16,F8,0D,9A,1D,71,2D,EC,5F,AC,FE,AE,60,16,55,45,C5,F6,06,1D,07,5C,CE,06,06,77,15,D3,79,10,7C,F6,63,B6,A3,ED,63,81,B3,2A,75,69,35,37,7C,B8,0F,E4,E1,79,C9,34,4E,12,23,88,60,18,DE,F5,E0,4C,27,9B,7B,83,87,DE,28,72,BD,FB,F1,84,57,E5,AD,53,61,DD,32,C4,40,DB,8E,FD,D6,29,08,6B,0F,DB,F8,3F,F7,F4,68,28,69,B8,FA,82,DC,7E,7B,A6,BF,A9,60,1D,8F,16,3A,C5,CB,E4,A4,46,49,30,C0,3A,40,67,D9,48,09,B0,AF,BA,61,11,88,43,19,0E,5B,61,5E,48,3D,F5,50,DD,3E,91,D1,BA,A3,2B,3E,DD,7C,76,05,55,22,77,22,F6,3B,B5,BF,72,99,A1,96,6E,ED,C1,EC,7A,9B,4C,ED,B0,AB,63,DE,71,36,18,2D,EC,35,A4,69,69,59,BE,16,14,48,E6,97,0C,48,A6,F8,39,C3,AC,40,B7,D6,8E,A2,51,74,08,0A,4C,83,8A,17,A1,73,81,42,BD,8C,12,2B,20,6E,81,3E,39,CA,52,0C,E5,CA,F1,D2,9F,ED,B4,0B,29,40,98,6E,41,D4,E1,31,BC,FF,FA,BA,1C,0D,C4,EC,59,6C,1F,70,7A,BC,45,2C,CF,D7,11,F0,41,64,C8,C5,8A,98,00,52,75,67,2C,9A,A6,35,43,C2,DF,BB,0E,01,DA,57,51,B6,C8,76,2D,E9,23,EE,2E,45,5C,40,C2,1F,30,BC,F8,E6,1F,9D,82,05,11,89,87,C8,15,5E,93,DF,DC,26,69,8E,1C,47,C4,F4,53,C2,5A,62,F6,FA,00,73,81,EE,8B,83,9A,D6,BE,84,B2,79,96,2B,11,A0,2D,68,B0,65,4F,02,DF,6B,9A,C1,46,3D,32,C0,58,ED,62,B9,86,FC,79,65,BB,AE,A8,BF,D6,A6,B0,1D,7F,6F,4A,51,8B,F4,B1,81,C2,5D,B7,05,FB,AF,D7,E0,A6,AC,05,19,A5,47,F6,A7,B0,75,37,82,81,83,3F,08,A4,BB,7C,27,89,C6,EC,78,BF,10,4B,D2,B5,87,9F,69,51,83,30,30,AB,B9,FD,24,A6,3D,31,C7,27,9D,47,76,A0,DC,F9,95,3C,A3,6D,08,79,E8,77,6F,40,24,99,28,42,91,A9,02,6D,EC,F3,E3,B9,C1,0F,C8,7B,79,71,31,FB,49,ED,52,18,7D,3F,83,47,C3,DF,E6,A4,AE,61,B1,5A,68,F4,C7,F7,68,24,FC,6C,6F,54,34,D2,48,08,2A,53,C4,B8,6B,D7,2E,78,FA,5A,B8,B5,01,7D,04,AE,11,10,C0,3A,40,8B,7C,83,F8,AC,60,41,AE,F1,BB,7B,B2,16,79,69,6F,7B,6E,5D,D1,3E,62,E1,D1,D8,1A,0A,E4,50,B5,11,DF,A6,77,AF,6B,CB,AA,CB,7E,A7,F4,AC,AE,CE,FC,EB,4E,BE,A7,88,5E,CE,1F,E6,3C,44,A7,15,33,81,1F,B0,18,C9,49,84,A5,4C,2D,E2,BF,39,EA,86,E0,D0,4C,3F,DF,90,CD,B0,07,48,5C,91,E9,83,E2,FE,BF,4E,29,D6,C0,F8,AF,75,91,49,45,B0,5D,F1,17,12,03,DD,BD,E0,46,29,39,D1,89,E0,1A,6C,9B,C6,84,F3,68,22,00,11,6A,2C,45,88,EA,FD,60,0F,9A,93,8B,C9,7A,6E,79,FD,01,C8,E6,47,B1,B0,8C,22,B0,07,E3,F9,D3,17,C7,E2,D6,AA,6A,B5,47,C5,64,84,49,F4,56,8B,BC,CF,23,82,E1,AF,17,A8,A1,FA,27,A0,BC,96,05,D1,A8,A5,13,0F,07,53,76,D3,F5,E7,70,9F,46,D5,8C,34,6E,11,37,6D,F7,60,63,74,C5,FD,87,EB,93,CC,A8,1A,64,AC,33,89,09,7D,0E,94,B6,C9,C4,7F,2A,8E,55,68,D5,15,BB,B7,FC,B9,D5,AE,8F,DA,DD,96,8D,D5,2F,E7,9C,4C,41,0F,FB,2A,06,76,CD,4C,3A,B6,F8,92,0F,66,8C,3A,E7,DE,62,BC,D1,19,2B,6E,66,22,53,EF,12,81,23,52,4E,E9,93,8D,20,28,50,E1,02,14,CB,13,80,72,F4,17,66,6A,F7,77,E4,05,8A,15,FF,93,20,80,67,36,9E,6F,B2,FE,92,FD,36,55,CA,80,4E,6C,33,AF,4C,B9,A4,3E,A4,1E,9C,6B,59,54,64,E7,72,6B,8A,36,C6,44,75,1A,EA,5A,EC,A9,61,C7,F9,81,FC,9C,89,F5,09,35,D3,92,9B,14,28,A0,B0,B3,50,7C,22,DF,29,E9,63,AE,53,BD,9E,D6,4A,5D,70,DC,18,10,4D,AE,10,6F,A9,96,13,CE,2C,DA,21,CB,1D,9A,F0,3E,58,FC,47,5A,3F,3F,16,B8,0B,38,E0,88,2F,EF,03,6B,B7,01,0A,C5,26,9D,02,09,BC,3B,10,52,E0,43,0D,D0,A4,B7,65,8E,5B,1B,0D,CF,40,CB,2B,0D,AE,94,AE,59,EE,A4,C7,8E,00,20,32,0B,F5,AC,CD,B8,09,B5,54,A1,55,B0,3C,D1,49,E2,47,C3,6F,EF,98,AB,54,EF,C0,AB,AC,16,5C,D8,FD,AE,66,30,28,02,B1,9F,C4,27,5D,BA,E4,48,8E,3E,D4,44,6E,86,1C,61,0E,50,DD,4C,DF,59,8F,A0,10,3B,F9,9F,6A,C8,D8,DE,02,8C,73,18,72,E6,DD,3A,C6,91,3E,0B,B5,7E,6B,94,01,3F,35,35,7E,F1,18,14,8B,49,0D,EC,12,3A,AA,EC,40,94,4E,2E,3E,BF,33,D3,26,42,F4,94,C9,6C,9F,BB,9E,A3,C4,AA,97,F3,10,21,1B,AF,FB,3C,6A,91,F4,0D,D8,55,09,48,16,48,79,30,B2,47,73,59,CA,9B,5D,CE,6D,4A,A5,5C,64,80,B8,26,4D,7D,77,65,20,8B,12,96,6E,58,C2,78,7A,50,FE,D0,0A,0B,62,C7,6C,64,73,C9,32,30,A1,57,F5,7D,05,F4,E0,D3,FF,67,E7,BC,36,E6,4C,29,17,CB,E7,BB,2D,C2,D0,3E,D0,5D,C1,5B,89,CB,25,4C,50,E7,89,5B,6A,6D,29,6E,D3,30,E0,34,3B,4F,22,47,B7,FE,EE,91,A2,45,11,A9,8B,E6,73,44,87,1A,AC,1F,DF,3F,D4,68,46,32,FB,F7,74,EE,32,C3,69,5C,7E,43,58,CC,CD,24,51,B1,8C,5F,6D,52,30,8C,28,FC,06,63,EE,34,68,E8,75,71,B4,44,71,25,38,97,02,80,1E,97,16,90,1E,E2,62,65,29,A8,F0,DE,7F,88,66,6A,56,BC,76,97,70,A5,B6,91,1E,D1,47,AE,BF,8E,FC,F2,49,9B,35,A8,36,D9,B4,62,3B,D6,20,D3,FF,1F,4D,AD,07,0A,37,84,BF,86,FB,DF,2B,74,BA,8C,19,4D,5D,34,EF,99,20,33,E0,82,32,39,99,65,3D,EC,38,83,62,5B,49,0F,5D,BE,5A,90,57,2B,F4,9F,BE,C4,0D,CA,0C,49,2C,AF,60,4C,64,04,00,48,C4,C6,A2,3C,44,2B,B8,9B,B8,47,4B,91,EB,32,38,37,A6,CC,64,95,83,D1,B3,1E,7B,20,BD,55,39,D8,4B,54,6C,B5,67,C4,04,D5,2D,ED,E8,C6,F9,FD,7D,81,40,3C,3C,6B,58,A9,7C,8D,68,A9,20,81,80,35,31,50,F3,DF,B0,FE,92,A1,2A,B6,D1,6F,7B,25,83,21,36,E2,D0,9F,49,F7,4E,3C,51,37,52,A1,20,B8,EC,E2,24,AB,01,85,96,41,09,CF,42,8F,D8,BA,3E,42,52,CB,81,A4,D6,7E,C1,1E,3C,F7,86,FA,E4,99,D9,52,96,38,9F,9A,A1,83,35,9E,86,9C,36,06,C9,46,59,14,69,21,4F,EA,61,A6,2A,3F,90,BE,9F,BA,ED,CF,AD,65,63,11,8C,44,4C,A5,89,6D,E7,D5,1D,4C,A7,BC,F8,74,E5,3B,6B,79,D2,06,C9,06,65,8D,22,95,74,16,29,B2,37,98,87,99,FC,24,AC,97,41,BF,C0,32,1A,D9,A8,40,16,A7,72,43,BC,89,3D,1B,B2,A0,1B,1F,4A,CF,F5,27,85,31,66,2E,69,60,CE,54,8D,50,A3,44,84,89,BE,5A,C6,00,A1,D6,CA,2F,D3,6E,CF,BF,F6,81,92,83,AE,E7,C8,5E,8E,DB,90,D5,20,FF,01,62,73,40,AC,3A,4D,A2,FD,44,84,71,69,EE,98,D6,7D,3F,5C,85,24,A6,D5,3B,2B,49,32,CB,3F,1E,EB,ED,9E,98,BC,10,63,AB,A6,DB,C8,60,A1,EB,E3,4C,7A,9A,6C,DB,AB,B4,4B,F1,E8,F6,2D,A0,DF,20,B0,E4,42,56,02,E6,12,E9,E4,3E,D4,26,59,FA,0F,2B,00,B5,46,AA,70,04,0D,4E,AC,D0,C5,07,46,E3,F6,CE,9D,69,7B,13,85,08,4C,58,D1,B9,40,2D,F1,3A,72,08,1B,19,72,47,8E,C8,DB,C8,2C,9F,6C,82,41,01,30,A2,B2,1C,C3,A2,22,52,ED,D6,D9,A0,1A,92,B5,95,F6,7C,F8,87,21,7F,39,F3,FC,04,FA,0D,2D,B0,A8,FA,4E,41,6F,EE,52,3E,F3,25,BD,34,0A,09,82,FB,4B,65,84,40,6D,3C,08,89,D1,D9,41,00,FD,67,9D,FB,51,09,6F,A1,F1,1C,14,B8,35,54,10,AC,C8,7A,0F,53,74,A4,0E,7E,66,D3,10,48,47,99,B0,1D,55,09,FE,61,9E,2A,1D,12,A3,C5,0C,0E,DD,B3,20,3B,C6,6F,A1,CE,67,4E,F1,72,53,D3,9A,C0,03,15,53,E6,A9,BF,A2,08,E8,33,C0,6E,67,9F,F1,7D,AF,E5,97,A2,51,F7,C2,29,AA,85,CD,D0,77,AB,4A,C9,A8,38,30,51,26,88,C8,5E,7C,A0,C3,22,E2,35,81,0E,F6,CB,58,D1,31,6D,BA,40,AE,8B,B9,80,40,A7,DF,9D,4D,E2,25,20,F3,A0,0D,B5,7C,69,20,0F,30,B2,16,DD,0B,28,32,4E,C3,00,E8,60,EA,F4,32,AD,71,07,FD,04,62,6F,A2,57,CE,04,F0,C1,D4,88,75,CA,73,24,15,9B,36,AC,7C,E9,B7,1E,44,A7,A9,DD,DC,A8,41,AB,8B,79,6F,B0,F9,B9,2A,AC,36,C0,22,5C,9F,71,42,19,78,D4,36,D1,DE,3D,A3,B2,D7,36,62,0A,74,05,67,D0,4D,A2,12,88,C4,78,F4,F5,35,8E,4B,EA,98,30,91,01,5C,2F,55,30,68,98,AB,6F,AC,1E,8E,CA,C8,80,D9,1E,33,4E,63,3C,F0,C3,01,9A,EF,E9,FD,DD,F8,9F,FF,39,75,24,FD,81,DF,D0,3C,2D,97,62,2C,03,F6,22,52,4D,38,43,E8,7D,8D,A6,77,B7,09,F5,6B,81,B6,CD,1B,88,C2,C8,07,FD,08,C7,81,D2,13,D5,07,49,AB,E4,CF,D2,CA,96,67,A7,81,5F,ED,0E,AD,1B,9D,72,DE,B3,C1,6D,F1,A2,59,CE,F1,01,D6,7A,B2,9B,F7,D4,F2,A7,D1,59,D4,05,D8,25,89,B4,7B,27,EC,41,0A,91,EE,F0,E2,40,4C,78,40,D8,3D,0C,BD,79,A7,AF,F1,CA,A8,2C,17,29,6A,89,01,59,03,FB,DE,1C,C5,F7,A6,DB,2F,52,C5,50,F4,58,38,28,62,B8,21,E0,E6,B4,F8,8A,4E,1E,1D,3E,E1,EA,67,3E,43,27,94,D2,18,22,78,68,79,40,D0,35,63,3F,0D,58,19,E7,20,F9,82,4E,0B,C8,EB,B4,12,9A,A6,25,20,3F,11,93,5E,F7,28,3F,24,59,62,F2,01,B7,E3,FE,A3,88,E9,68,CC,A2,83,4D,56,C1,0E,41,04,0B,90,14,55,2E,C6,6D,1F,67,1B,51,D4,D2,F0,A1,6C,2D,20,B1,FA,F9,6A,81,10,57,C0,03,CF,6C,6B,31,33,A1,C5,C8,81,AA,D4,57,14,4D,42,44,21,CE,0F,1E,7D,8E,95,FE,9A,E0,40,A1,D4,83,C4,3E,D9,CF,2C,C0,8D,86,DB,01,01,29,B3,D2,89,FF,1D,79,CC,49,A4,11,4E,C9,60,12,BA,E0,1F,50,54,A7,32,AE,FB,24,87,AA,B5,5F,34,E8,47,CC,8B,36,16,58,71,B7,34,42,D1,B5,2E,7C,82,DE,D2,41,1E,FF,83,CE,F8,CC,66,F7,85,5F,59,13,2A,D6,F1,F5,49,1B,CE,93,70,26,03,F2,FD,4C,99,B4,BC,AE,7C,2F,4D,88,75,4B,AB,A9,A3,81,AC,C5,C1,48,62,87,54,A3,8E,7E,06,73,BB,DE,BE,2E,82,83,56,3E,A6,92,5E,90,2F,75,F7,4F,19,5C,EE,8C,0C,31,EB,8E,CE,D7,4E,A2,43,E4,06,2C,16,98,0F,D7,FD,28,4D,7A,22,7E,1F,95,80,E8,63,49,1B,02,62,FA,3B,C7,96,F4,9E,2A,38,6E,BC,B4,4F,63,43,A7,EF,C3,39,C2,71,3D,F0,C4,29,D0,B9,BD,DD,75,8A,A2,F5,46,77,20,B2,B5,33,21,68,91,D8,1B,71,1C,E1,1C,C6,1A,C4,83,C6,A0,2E,D4,30,89,CF,16,7E,BB,8C,AB,A0,DD,02,5E,D5,C6,48,B8,6D,0E,8E,2D,73,E4,52,EB,43,6E,8E,3A,A7,7F,B0,49,5C,15,7A,DE,1A,DF,C5,B8,87,5C,B9,20,C4,93,83,37,15,C7,7C,6F,1B,1A,A4,1B,18,34,D3,2C,7E,12,F6,2D,DF,98,B1,67,10,45,8A,9E,15,87,AB,8D,10,53,77,C0,87,EE,9D,14,45,61,07,53,B5,F5,F4,58,67,45,CC,27,5B,5E,96,39,02,17,F8,E3,D8,13,5A,1D,81,4A,CB,68,42,CD,39,B0,F8,3E,6E,EE,3E,B6,15,3C,B3,4C,2E,A0,1D,90,9A,1D,9B,F3,E1,2B,A6,67,A3,F1,0F,38,2F,62,6F,1E,35,CB,03,E8,22,F3,C6,D9,05,6B,AA,5A,34,80,C5,EB,1E,F1,F7,67,D2,42,D2,3B,93,65,56,6C,85,11,56,C2,A3,4B,D1,2C,C2,D2,6E,83,BC,F0,50,03,3D,AC,0E,89,46,50,6A,FB,8F,3A,08,64,69,73,14,D9,91,68,CD,6A,28,1E,9E,8E,73,47,38,C4,8D,A6,E9,49,51,DA,6E,9B,84,D9,59,AD,7F,34,06,CD,2F,99,80,17,D9,D8,2C,10,5B,DF,BA,AF,68,02,10,A0,EB,49,AF,C5,0A,22,F1,74,A1,28,1C,BF,9F,37,A4,70,DC,05,29,76,B4,5E,D6,DB,02,AC,32,6B,FC,13,F4,D8,BF,C6,79,06,06,4C,5A,5E,89,3B,81,32,EF,6B,23,A4,C9,80,F8,B1,F0,34,D3,90,BC,FF,1A,4C,56,CD,3C,05,56,17,09,66,32,5E,BE,3D,44,04,9D,26,30,E4,79,2C,8F,95,2E,02,C2,08,32,BC,A0,FE,98,75,5F,4D,E7,4D,76,2C,06,6D,4E,C0,3B,0E,42,C5,33,18,01,16,8A,32,57,B1,10,93,EC,39,3E,A4,46,3E,DD,A7,08,CD,EF,77,03,46,C3,DF,E1,FA,E5,49,F5,46,EF,8A,6E,68,56,42,1D,B0,E4,25,AD,72,53,1E,D4,97,26,C0,8D,91,F9,FD,32,83,10,27,C5,2F,E8,39,1A,84,D2,E7,EB,55,A3,D3,1B,8D,AB,FE,C2,A7,B8,AE,B3,7D,85,F2,21,B4,FF,41,A3,77,B6,27,F0,FC,4B,62,DD,6A,DA,71,AB,77,D8,06,1B,D8,18,73,0E,66,E6,33,D0,92,8E,84,47,4B,38,55,F6,89,7D,74,DA,40,1A,54,46,38,46,94,3F,4A,E3,95,57,8E,E7,63,B5,2A,DA,94,21,63,22,20,C0,79,24,C5,69,08,0A,F5,7C,39,2F,7E,72,58,E8,D9,0A,9E,09,38,EC,3D,90,6B,DC,52,EC,69,1C,EE,27,98,4E,4E,B3,44,57,39,CA,B4,AB,B9,1B,A4,78,8A,7B,B9,84,F5,01,D2,BB,13,20,5E,1E,9A,AC,FA,BA,AE,D4,FC,19,12,7B,E8,CD,92,D7,E4,D8,D6,26,A5,36,31,67,B5,2B,4A,E2,14,4A,EE,F9,81,0C,C7,0F,B3,22,FB,48,D7,35,8C,20,AF,67,1C,3F,3C,38,F4,96,FB,58,0D,87,0E,43,12,88,51,89,60,17,DF,5F,D3,8E,98,EB,99,03,45,23,DB,04,FC,AC,63,91,0A,96,0C,3E,21,20,2E,DA,88,E3,62,74,7D,AC,59,50,24,EA,14,24,85,05,51,C0,67,AC,35,72,5F,33,F2,C1,C7,B1,37,EE,1F,82,DF,80,92,F3,C4,4E,B3,84,5C,93,F2,BD,26,32,8D,5E,30,AD,12,5C,DA,F5,7B,6E,EE,62,63,38,EF,4B,7D,BA,4C,DD,5A,B8,2C,C9,AD,4F,EE,33,66,17,6B,21,9F,6F,6B,A4,A5,21,A0,30,D4,31,25,CD,D5,EC,8A,18,41,1A,FE,DC,E8,4B,66,EF,B2,5D,B1,FB,B2,93,33,3F,B4,42,4D,7B,70,EA,83,C4,84,21,5E,BE,34,16,BE,5D,94,0B,BA,2E,F2,3C,58,D0,B1,77,85,50,70,D4,2C,AE,F9,AD,C9,05,45,EF,97,07,C9,CE,64,1A,94,CF,C6,9A,49,34,3D,DF,73,63,AF,4E,D9,BF,11,D6,94,A0,91,75,EB,49,A5,94,19,71,73,80,5F,11,EE,70,B7,D6,96,A0,DA,7E,F6,6F,F4,03,EC,FC,7E,6E,EE,B7,BA,91,B2,A9,75,2E,91,F9,8A,3E,F1,E1,F2,6E,4C,C1,EB,FE,DE,15,1F,B3,04,F9,B0,22,2F,BF,FF,1A,CC,79,32,2C,42,D5,96,A1,FA,00,2D,9D,BB,BA,6F,B9,7F,FD,BD,45,FE,CB,F3,AA,FB,01,B9,91,92,FF,0C,3D,B9,54,CE,D4,56,8C,C6,3E,24,4D,B9,10,51,67,71,3E,C3,7F,54,37,CC,F6,99,B9,38,44,8E,24,61,27,E4,86,E5,AD,6F,A9,44,C0,E6,68,1D,3B,2C,9A,85,3C,C3,27,86,50,AA,82,F9,26,63,83,58,76,75,3C,E7,E7,4B,56,1D,63,A8,94,36,C4,4C,D6,16,46,D1,B6,4D,43,3F,93,43,A8,BA,01,F2,93,75,AB,CC,0B,72,E9,D7,90,02,2F,69,70,AB,EA,94,8E,F3,4B,DA,45,A2,71,66,29,9C,07,01,27,FC,8E,F8,5C,9F,D3,FD,18,A4,C3,E4,49,87,56,06,53,A9,AA,03,D4,65,AE,6B,99,A4,01,A9,C7,37,8A,43,20,5D,33,65,2C,6C,C4,F0,AB,83,7D,5E,FA,3E,3E,71,26,80,BA,4D,26,F1,D9,20,66,73,C5,10,82,5D,2F,D6,C5,B6,F5,F9,85,73,F8,88,71,E0,CC,B1,47,EB,D2,CB,DB,CF,59,04,55,C1,DF,A7,9A,96,38,B5,CE,A2,CD,0E,DF,09,E3,2C,A8,36,96,73,8A,9A,10,07,89,42,AF,55,4F,43,CF,D7,D1,93,59,FD,86,70,A3,29,44,3B,A2,E2,05,54,3C,61,33,A2,CE,B8,F0,4E,D4,22,85,65,02,DE,EF,E3,B5,7B,A7,3A,26,C8,76,39,07,D3,9A,1A,30,80,35,1B,E5,07,AD,1E,63,A6,9C,D2,8F,B0,D0,F7,B8,9E,26,3A,67,7E,D3,28,2E,C8,13,09,FC,E8,0A,8F,E3,21,82,67,1E,53,EC,F4,5E,00,50,A4,AC,68,13,F3,BA,AC,10,A4,6B,8C,5E,F4,E2,99,59,67,E2,9D,C8,53,27,00,AC,A1,82,79,60,8C,4B,57,8B,A4,5C,08,08,BD,AA,B4,65,3D,BD,2E,9A,4E,9D,3E,69,A2,B8,17,8E,95,DD,08,20,70,FD,C7,6D,60,E3,DD,3E,E1,4D,D3,C9,74,74,15,F2,09,8C,FA,CC,CB,7C,64,31,FA,31,59,FA,DA,08,28,9B,6A,81,72,6E,E0,F1,4D,9D,84,AB,D3,0A,EE,E5,F4,6A,51,4B,A1,9B,50,39,C0,AF,98,E2,47,1E,85,8A,77,DF,9C,73,0D,4D,09,6C,5B,F5,46,80,3B,6A,F8,BD,20,70,E8,0D,EB,6F,69,E0,59,B6,84,E4,21,68,E1,43,6F,A7,16,90,3C,51,D1,1B,22,BE,0E,FA,81,07,F4,3C,BD,02,38,41,64,84,1A,1B,72,74,41,52,E8,96,13,B4,B0,13,7F,02,70,5A,59,BC,C7,83,78,2F,B7,10,60,A1,DD,74,75,00,5A,D0,DE,36,ED,A2,E4,3A,46,8C,B0,17,A3,90,43,E0,DA,C8,37,B3,E9,04,C7,78,8F,AB,2D,E0,5E,55,70,58,6C,EE,3B,87,B8,A3,78,68,4D,8B,9F,EB,62,C7,32,55,12,21,CD,1B,3C,60,B2,96,99,92,49,E2,FE,0E,A0,27,00,87,0D,98,B8,1E,3F,8A,9B,DF,7A,1C,3A,30,84,1F,16,9F,D8,54,02,61,44,14,43,67,8D,C9,BF,9A,FB,EC,E1,58,CC,E4,1D,6D,27,85,9D,B9,B3,A2,CA,EE,8C,F2,DB,86,49,69,38,03,4E,DB,7F,83,90,B2,04,CC,B3,4D,6F,E0,C9,BE,F5,0C,3A,31,6A,B0,9A,E4,EE,7F,C8,CA,9A,07,BE,8E,50,53,BF,5D,D2,48,6B,AF,A4,40,2E,94,AA,B2,41,A7,1E,D4,7D,38,08,8D,53,0D,AC,17,65,4A,EB,C3,8A,BA,29,36,C2,E1,84,F4,03,DD,FC,A6,EB,5C,61,DD,E0,FB,58,D4,21,4E,98,79,BE,54,44,61,D3,D3,57,5B,53,0A,29,4D,88,C5,41,13,15,26,DD,3E,87,07,6B,2F,FD,3A,07,38,03,34,85,DF,73,0C,98,A0,DF,33,E8,07,E6,42,9A,C0,11,19,43,1E,02,DE,E2,9A,8F,B7,FD,67,F2,B3,9D,47,DD,99,5A,1D,3D,B0,F9,D1,7F,5F,42,11,BC,30,EC,36,FD,8C,13,55,B1,5C,34,CD,91,DC,D2,6A,33,DC,A3,BB,A5,23,85,2C,66,7E,9D,32,61,83,EB,D4,33,CA,EF,CA,B0,FE,5A,25,6F,98,09,0D,9B,D6,F5,89,CD,00,14,82,1B,A3,F9,A6,92,06,41,E4,79,70,BA,85,E5,D7,8A,4F,A7,40,B8,D8,DB,E3,78,3F,F0,A3,9B,AE,D6,20,DB,80,4D,DD,38,06,BC,27,A6,5A,C6,0D,33,55,FE,5C,44,DF,59,DF,20,FE,2D,A8,46,28,09,CF,F2,7C,F7,03,1E,DE,76,D9,55,21,69,46,7E,A5,02,EC,F8,22,65,81,E8,3C,C8,6F,A7,22,FA,E6,30,A0,26,3B,A0,E4,CB,9D,50,BC,78,D2,66,16,54,56,55,4D,FB,99,60,D5,BD,E5,9F,BA,B3,16,1A,BA,82,D8,87,C9,31,0C,37,37,63,F3,86,BA,07,0F,EB,BF,35,F9,8C,71,D6,22,87,35,5A,74,CC,DE,30,97,7C,ED,30,9A,2B,80,A1,8E,71,44,4A,06,F9,3F,DB,D3,11,4F,0B,E9,46,FD,45,26,E6,26,D6,68,5E,DE,F5,BA,87,E9,41,15,12,BC,7F,36,AB,4F,18,48,3D,86,EA,3C,8F,B9,E2,C0,6D,6F,EE,AB,CB,C8,89,7C,66,8D,67,39,7F,56,D2,08,A9,74,C2,63,14,D6,82,1E,E6,0E,8B,55,1A,5C,BC,85,F1,82,06,D9,D1,CC,3B,D6,03,B1,E2,80,43,EC,CE,E5,B2,F8,D8,63,4A,76,B5,BE,E6,21,ED,2B,0E,D1,E8,81,67,B4,7A,F5,61,80,4A,83,52,FF,1D,A9,4B,01,3B,25,00,F6,95,71,94,14,1D,FA,3E,D3,21,EC,5B,84,51,BF,9C,BB,EA,97,B3,A9,A8,BB,1B,83,05,72,DA,A7,1E,19,F8,8B,0E,9B,8C,28,AD,BB,F3,28,FD,80,52,A4,AC,7C,E9,CB,7C,19,75,8B,85,8B,56,16,8B,EB,95,7B,06,CE,E4,5E,A6,5A,98,16,7A,3E,CD,99,6F,23,90,1E,BE,F5,68,B7,3E,1A,A4,1E,29,A2,07,97,10,FB,7F,99,CA,55,DB,07,5F,7A,A9,BD,0C,43,7E,8D,B9,CC,5F,FF,EC,6D,43,BA,CE,C9,08,2B,D9,7C,1F,3D,BC,31,97,C0,DC,6C,7D,92,13,8C,92,A8,28,0C,95,7C,0A,27,6D,EF,02,8C,FC,64,CD,00,AA,19,2B,7F,C7,C9,14,94,72,8A,83,E5,39,F1,A5,4F,E2,D3,2B,C3,3F,14,EF,D3,62,E0,C4,38,29,04,4D,DF,C6,1C,C6,57,A0,DC,AD,2F,E7,29,B5,DD,83,18,91,1A,CC,73,A1,20,DA,AE,D4,17,BA,B0,5B,34,2D,A1,3A,E8,DF,C6,E4,6E,5A,7D,27,AB,54,CC,03,0D,10,3A,6C,23,93,B4,56,7A,DC,D5,13,F6,60,25,D5,F4,A8,51,93,46,2F,C6,16,71,88,6C,52,E9,DE,77,F5,E0,F9,3D,00,78,43,19,2F,71,ED,B3,89,BA,D7,34,F8,D1,18,3B,6E,72,00,A7,3F,85,87,F0,90,14,6F,22,58,68,BD,F0,2C,8B,A3,E4,7B,B3,37,22,D4,4F,30,7B,8E,8F,54,89,F9,22,3B,73,33,E0,4C,E3,EB,79,47,E2,E5,4C,7F,73,DA,44,77,3E,C5,8B,2D,CC,78,B4,5D,BE,1C,76,AF,6D,0C,3C,F7,E3,CE,EB,1A,90,52,9E,47,40,51,54,1F,59,E3,48,BB,84,54,BD,AF,E8,F6,9A,CF,20,3B,2B,92,D2,AC,9E,68,4A,1B,2D,A3,DC,12,D5,44,F2,57,B5,20,8E,91,33,5A,D2,F8,74,43,30,33,27,6E,6C,DD,D7,9D,D8,7C,89,26,49,ED,26,48,2B,4A,14,DB,14,49,76,22,76,D0,A6,53,D4,0E,78,16,9D,7A,7E,89,31,7A,D1,D1,E2,87,FC,AC,EB,75,AC,73,19,53,CC,0C,C7,F6,84,3F,72,F4,00,F3,88,2C,A1,3E,6C,FF,5B,F7,56,A4,8F,F4,24,12,42,35,E1,E6,34,AF,37,63,E4,01,7C,D5,DC,66,22,57,F6,8B,46,BF,26,53,97,24,19,A5,EF,31,02,8B,63,54,20,CC,D8,76,C4,C7,5F,F8,8C,05,AA,EA,9D,53,9F,1B,15,42,FA,5E,03,C2,AA,4E,4C,91,E5,DD,A0,53,19,F7,AF,63,D2,A9,64,FE,98,49,04,20,D6,7E,24,B3,7A,FA,AB,01,69,80,B0,92,50,8D,45,60,26,96,7E,3F,9D,3C,E6,D5,92,92,34,43,B7,8E,40,CC,EE,09,8D,FD,CF,2D,B5,B1,07,DD,3B,93,CE,FD,52,1F,AF,DE,B8,3E,E2,25,B4,C8,81,93,92,AB,57,E5,15,61,63,29,99,B3,4F,B3,14,7B,B7,2D,56,06,31,5B,0B,F9,59,1F,53,1F,9E,29,6D,CE,31,07,D2,C9,80,DD,26,7A,80,59,38,7E,1D,2B,71,A2,64,6A,56,75,82,3D,B1,36,87,69,B4,CD,9D,58,4B,1C,9C,B0,F6,46,23,C0,5B,E8,44,38,92,32,BF,70,7E,EE,5E,58,B9,11,EB,77,DE,66,7D,79,F7,D3,18,08,FE,A3,53,56,5F,2A,47,F2,FF,D9,61,93,BE,D5,41,FB,1A,EF,90,1A,69,5A,1F,57,44,60,07,E3,E2,B4,F4,54,B3,3A,0D,AA,DC,97,4B,7B,9A,EB,6A,FA,0E,82,3B,F8,82,B8,A4,22,BB,93,58,7F,B1,92,D3,79,DC,1A,7F,5F,C5,FD,4E,3D,CC,2A,D2,77,B5,18,2C,43,14,20,B2,E9,FE,1D,0D,6E,09,90,6C,7B,6D,7C,F3,58,BB,FD,FF,1B,22,4F,B9,CB,B3,12,38,69,1E,C6,9D,16,C2,28,A0,36,B9,15,51,FF,6B,F6,D3,F6,83,D0,0F,6C,1D,1C,DF,46,1B,D8,F6,C1,C9,C9,60,FD,EE,FE,D3,57,B1,9D,06,95,2B,A5,56,FF,94,59,44,4F,BB,D3,A0,6C,68,96,A4,F5,39,43,8A,10,EA,9B,09,5C,7C,B8,4D,DA,F8,FD,67,3E,14,10,60,14,A3,10,1E,DD,D9,69,5B,33,9D,F1,91,DF,36,BB,9E,43,C8,38,20,50,DE,88,86,D6,BA,6D,AD,43,2D,3B,0A,A9,88,FD,4B,35,3B,BB,83,36,7C,78,15,C6,25,D3,59,05,DA,58,06,6F,A7,D7,91,65,DF,EB,26,3F,DA,97,C6,36,87,FE,89,D5,42,A5,77,D3,71,C3,2E,91,FA,FC,CB,C8,5D,6C,0E,26,EF,38,16,5F,60,33,AA,C4,44,C4,74,FF,7C,BC,7C,C8,13,4A,35,4B,BB,59,10,61,A8,22,A8,12,5D,6D,9C,EB,BC,83,5A,BE,FA,B3,87,82,97,F1,B9,2D,A9,AE,CB,59,BD,38,B8,9E,A9,FC,BD,3C,FF,59,5F,12,67,C3,59,44,54,E3,D2,FE,4D,D8,13,83,C4,09,69,13,34,2B,0E,BB,20,75,8B,FA,DC,0A,94,DA,1A,20,A7,F8,A2,85,C7,03,E8,8E,E9,A5,3D,3D,C6,8C,29,A4,E2,6A,7A,3B,78,12,F3,44,6B,D5,7E,A8,06,59,32,CD,0D,08,38,44,8F,2D,87,4F,78,1D,8F,B2,F1,97,DE,20,B4,AF,E9,68,92,FA,EF,87,DC,0F,91,8C,3C,6D,74,69,4E,E0,4B,6B,C6,02,55,3F,B9,27,80,40,F9,C1,82,1E,D2,95,32,96,A8,68,9C,0D,DC,7C,A5,ED,AD,F1,E4,44,7B,33,94,18,11,9F,EA,3A,8C,E9,2C,F5,E4,4B,D1,5D,39,F1,97,AA,5D,89,F6,91,6B,AF,1A,91,A6,E3,44,5C,65,40,E9,46,8F,ED,0C,68,53,4D,F9,55,15,5C,DD,91,E2,1E,5F,F2,47,0F,62,E0,A6,BB,DA,D8,A4,CF,8A,2E,0D,40,C0,91,43,58,04,0E,65,32,31,BF,40,C3,78,BE,49,6E,B1,E4,E2,4A,D0,79,7D,C1,21,E8,EF,D4,72,CD,34,EC,42,EE,35,AF,35,3D,9A,6C,28,81,D9,BC,D7,1D,38,1C,8F,CE,35,19,D5,D9,C0,CB,D7,18,CB,46,57,EE,31,BC,0E,9C,7A,A6,0C,21,A0,44,12,DD,92,58,07,F6,77,4A,35,33,40,71,88,FF,C4,7F,53,B9,D1,16,0C,6B,49,79,07,3D,97,A0,8A,C8,48,37,4A,04,2B,F8,C4,CB,28,F1,77,C0,58,A4,E7,CC,9A,2F,14,AD,EE,49,36,AF,B2,A6,85,FC,5E,7A,69,55,96,EC,0C,C6,EB,E5,43,7C,2C,B9,4B,9A,03,7D,9C,87,95,4D,CA,02,2F,C5,DC,48,68,9B,D2,A5,FC,9F,1A,F8,75,9A,84,0D,61,58,73,A4,22,85,A4,5C,89,DC,BD,97,6C,6E,BF,F2,0F,33,6D,1F,C9,5A,B0,B9,B4,46,09,F8,18,B0,4E,D1,F5,FC,13,4B,A4,90,94,07,2C,E3,60,49,8D,4D,A0,CE,05,2D,A5,BF,DE,64,47,E7,8F,BE,A8,67,28,48,12,C5,44,95,63,96,58,06,F9,D3,5F,91,1E,0C,E1,DE,93,A8,53,31,D9,3E,BA,FE,E5,D5,20,9E,80,E4,D7,25,7B,FD,C0,72,0D,AC,D9,D8,9D,2F,4B,33,61,88,2D,75,CF,2F,FB,62,40,33,AB,A6,7C,A9,7E,C2,F0,63,D9,61,51,9B,82,9F,16,A5,DD,55,11,EE,EC,3F,F4,26,2C,6B,89,09,F4,89,A5,EA,55,F0,0C,2E,8A,0C,56,C6,98,7F,60,4D,59,08,C8,B6,37,7C,26,7E,CB,BC,0A,24,94,D9,A4,4D,76,36,70,96,F6,FB,DB,52,5F,B6,E5,DD,03,69,B8,70,03,DA,49,6A,EC,20,4E,5D,36,21,EC,D8,1B,1C,AE,E1,5F,18,97,2F,B0,01,3F,8F,6F,2C,5B,4D,93,08,36,9C,B1,4E,CA,EA,9F,C2,08,B1,0E,2E,DF,FA,8D,2B,EA,C3,1C,D0,4A,3B,F2,4F,2B,23,19,A3,DA,57,A2,38,C2,61,26,C9,2B,A9,0A,7C,5C,34,4A,3A,52,CA,A1,53,1A,A4,87,B8,1D,24,55,9C,28,16,92,95,E7,48,C4,CB,F0,53,DC,4A,9C,B3,5F,AA,5E,84,35,D5,AA,C2,01,02,B0,B2,E6,1F,06,F8,FE,D2,D1,C7,CB,16,76,77,55,EB,4F,CD,0E,7E,47,5C,30,17,30,F8,46,A3,AC,3A,5F,92,85,6C,E0,F6,E1,46,FA,E8,5F,18,CB,50,F6,25,0C,58,3C,FB,C2,9F,DF,A1,EF,7F,8D,23,E2,6A,97,66,B8,D8,E8,39,9F,FD,C6,9E,C7,46,E4,17,69,E7,43,7A,D3,76,36,A4,CB,A3,14,DB,45,84,23,F7,53,FA,68,10,17,AD,EE,85,AE,8F,29,A4,89,E8,EB,A6,48,F5,94,68,EA,31,E0,42,61,60,6E,E7,48,DB,F5,84,BD,61,A5,61,15,8D,F9,03,D9,0A,62,8C,9E,29,15,79,B9,AC,B0,64,62,51,92,90,11,36,EE,8E,7D,52,FE,9B,27,9A,AD,BC,39,74,6D,F1,FF,49,B0,60,B9,EB,3F,15,F2,67,C8,E4,22,1F,97,59,5A,90,06,F3,88,D2,D1,DB,07,BD,0D,8A,4E,0A,2C,E4,75,80,23,C0,79,D5,51,DA,D8,E8,33,43,7C,CA,2B,6F,79,E3,A5,66,F4,28,58,E6,18,A5,57,54,D0,59,6C,B5,C0,47,0B,10,64,E2,C1,12,70,BE,32,90,C1,06,64,2C,92,42,DB,F4,94,9A,E0,19,90,03,5E,6E,F6,19,1D,68,57,E6,C9,34,7F,67,92,90,A0,54,4E,17,42,48,B8,D0,6C,F5,53,9D,91,4A,EB,CA,6F,40,CE,06,18,10,55,26,71,80,A7,9B,1A,34,A0,F9,92,13,62,8E,69,83,28,1E,CE,C7,AD,30,5D,8B,14,D7,9C,93,BC,E5,2A,FC,8F,6B,1C,9E,9B,D7,E4,35,69,9A,04,A2,17,47,78,AC,FF,94,AC,E3,90,CD,4A,67,D8,A5,A7,80,2A,BC,DD,E4,70,FB,3F,F6,FE,3E,DB,4F,AA,07,20,2E,FC,88,ED,61,3B,3C,2B,35,D0,E4,2C,6D,76,34,B8,59,43,9B,AD,B7,C1,FE,81,48,F4,79,BD,62,16,A5,DD,70,4B,05,67,5A,7A,CE,B6,EE,41,85,E8,E2,2D,BD,7E,06,2A,5F,E6,91,39,30,6B,97,0D,10,AF,5C,5D,43,25,35,D1,08,5D,8D,1A,45,A6,3D,50,10,49,B4,95,B3,3A,23,40,9D,A7,0F,CE,70,B6,3F,7A,C4,CE,1F,CB,B4,8C,1D,C8,9E,5E,8A,7E,AA,C5,13,8D,96,F5,78,83,FE,59,1F,BF,ED,C7,D1,94,7B,D9,16,90,C9,CF,B0,B6,AB,7A,E3,B4,F8,79,19,FC,0F,D6,EE,9B,23,62,32,17,C4,28,0F,2F,C8,82,7F,6B,82,61,C3,81,05,83,48,54,5A,C1,D6,EC,CB,E4,C2,C6,83,28,FC,20,44,1A,1E,E6,63,02,8C,09,A3,34,2D,F4,10,4B,65,B3,2A,B7,AD,07,35,FB,7E,46,70,AB,5A,78,77,31,49,B9,F0,AD,83,73,18,F6,C6,C6,84,93,F0,E2,02,13,F6,9E,C8,37,EE,5F,3D,21,1E,E6,35,36,F9,0D,0E,31,C8,E5,C6,E9,38,CF,84,55,0D,E6,B2,E4,69,CF,C0,D8,47,D6,D1,A4,7C,61,0A,F3,4E,16,7C,1F,41,27,78,C4,68,C2,C9,38,80,D6,3D,12,9D,00,70,93,0A,35,BE,9A,60,12,60,59,49,F7,83,89,C7,38,3C,F8,73,80,F6,FA,85,A6,88,4C,B2,D4,40,96,67,D4,A5,3B,14,47,A0,45,75,68,8E,FC,DF,B7,68,43,95,74,15,73,E7,02,DB,E3,B4,C7,18,FB,04,95,FA,DE,5C,52,6E,96,77,67,AA,C4,A5,B4,8A,6B,1D,16,94,E0,E7,5F,B3,B6,74,1D,BB,90,FA,DA,B7,CD,41,AE,33,45,1A,0F,90,5A,DE,C9,2D,16,BC,F7,9B,DD,C4,68,4E,5D,D0,26,13,B2,89,D5,D0,26,90,9B,DE,1F,D7,38,E6,80,EA,12,57,FA,D9,E2,37,8D,A5,4B,D7,A4,60,B6,69,0C,17,DB,D4,6C,8A,12,DD,7E,6D,4E,FB,B8,BD,CA,BE,8A,0B,EF,5A,F2,58,0E,BE,01,A0,81,6F,4B,E8,F3,9C,DE,57,93,AC,07,54,55,D7,1B,ED,7F,29,2E,A4,EC,AE,DC,9F,B6,1E,E8,38,45,51,A4,9D,C5,A3,ED,33,30,23,BF,53,3C,43,F7,40,C6,FA,8C,FF,81,E6,6F,47,70,3A,47,56,13,6E,A6,1B,D8,0B,60,5C,D0,3C,6A,B3,B5,E6,F7,FF,52,C0,11,FA,B2,21,1F,A3,0B,B6,D9,C6,7F,49,68,9B,8D,BA,8D,C9,1E,06,94,B6,34,62,AB,6F,98,55,A0,94,23,3C,B2,08,A2,E0,7B,E7,CE,9D,2F,2F,8F,6D,DC,5F,DD,84,3A,56,5F,AF,63,E3,CA,7C,95,EF,87,B1,14,28,54,2D,9B,8C,2F,AE,B1,31,AF,8F,8B,23,19,20,05,DA,43,88,37,D7,BA,27,AF,C7,6F,DC,DF,E1,20,B5,D2,4F,A6,03,79,1D,DC,53,A6,D1,99,22,BB,3C,CE,C9,7A,BF,C5,27,C7,46,A2,DE,BF,61,40,9B,E0,10,E3,D5,F2,33,C4,25,88,91,4C,62,E7,BA,AA,81,3E,0B,22,81,8F,3F,88,57,FF,99,24,5D,2C,07,FE,1B,2D,98,CD,34,3F,E3,9E,0D,EE,A9,1D,D9,68,12,37,CB,37,26,AB,C1,B7,6A,9E,0A,83,49,FF,C5,5C,9D,F7,DC,4D,DF,EF,23,AB,83,65,85,20,17,22,44,24,8A,53,E7,E0,29,D1,9A,24,8D,0E,75,A9,53,F4,10,0D,D3,33,F6,97,3C,72,A6,AD,6C,B1,A5,7E,56,5B,AE,0A,74,2B,69,2A,54,23,A4,BA,97,E0,18,84,62,D1,2B,DB,B8,F3,6B,7F,84,22,11,2C,F6,19,F3,3F,D7,41,E4,39,89,FF,FA,C1,E6,AB,C3,1B,0C,6F,F0,48,8C,37,C1,E9,58,04,97,9A,42,F8,53,AE,9E,59,AC,B0,F3,09,05,92,39,8B,A5,93,B0,D5,29,40,AD,02,21,9D,88,AC,F9,35,C0,DA,D9,3C,F2,77,3D,6E,E8,A0,F9,2B,39,8F,16,5E,65,DB,53,E6,B6,C1,0A,AE,B8,C9,33,EA,DB,5C,74,19,F9,AA,8A,1F,D1,75,C2,9A,28,5C,4B,43,D5,C5,F5,B9,40,FA,7B,2B,05,2E,3E,83,92,33,DE,DF,6C,6D,8C,64,BC,66,AD,84,2B,9E,5F,A8,66,19,66,F8,8B,99,92,88,54,A4,71,48,4F,F8,4B,22,E3,EB,4F,2D,A2,0A,E4,2D,DA,A9,3A,11,D6,97,5E,D7,16,B8,73,83,E7,79,1E,66,3E,A5,2F,31,4D,D3,07,F1,0A,A1,9F,49,3D,1D,7D,88,04,19,6C,3B,65,20,69,ED,9B,5F,1B,C6,D2,5F,98,A6,D5,17,24,52,03,59,4D,D1,E9,7A,3F,47,F6,BD,2D,D3,83,CE,56,AD,FF,5B,7E,C4,23,32,1D,E7,0F,32,02,35,23,38,C0,EE,BC,61,E9,84,25,5B,B4,70,B6,8B,35,BF,C3,B1,A3,54,26,0D,BD,52,F1,93,C7,16,E3,9D,51,7C,CC,D7,4E,76,FB,F1,91,68,FD,9F,0C,1C,CF,15,2A,D3,3C,62,93,97,5B,54,BF,D7,45,2F,C4,76,E3,FE,40,48,82,6C,39,F2,E4,63,5A,70,44,79,5A,0F,49,26,A3,FB,75,C1,C3,A2,26,15,27,C7,0F,A9,9B,EC,83,AA,4D,36,F7,4F,D2,1C,23,6E,AA,43,00,8D,2B,89,33,46,B7,B8,4C,C8,12,15,35,77,27,B9,9A,EF,28,66,3A,09,7E,9C,E0,B7,3B,56,01,30,3E,41,9C,A7,CC,57,5C,AA,9C,86,94,38,37,18,AB,BB,36,79,50,9F,7E,BE,BB,31,70,FF,AA,61,F0,09,00,E3,83,F9,D2,31,92,3E,6B,3C,90,EB,61,67,76,67,49,C7,47,3F,B3,0C,1D,8B,A2,F5,A7,E0,8B,4A,AE,5D,3E,95,95,7B,10,EA,A8,F2,79,D1,97,3A,A5,2F,61,51,6F,56,65,D7,2C,88,4E,D1,6E,F2,7F,DA,F0,51,85,5E,73,5D,61,2F,3B,2F,48,2A,02,D3,71,EB,17,B2,ED,EA,E9,2A,6F,80,E5,F8,9D,D9,68,5F,27,C4,01,2A,C0,E7,F1,98,C1,28,A4,30,A4,FB,F7,06,53,CE,63,42,3E,1F,0B,8E,71,6C,19,29,97,B8,59,B6,D2,C4,40,00,6C,D7,9A,4B,64,CB,3A,78,24,36,FD,FF,B6,F3,A5,57,DA,66,88,CE,57,08,80,25,50,6F,20,19,18,E6,CC,FC,5E,24,7D,B5,52,11,91,9E,B4,C0,29,BE,CC,09,91,FF,3E,BF,60,B5,6A,7E,5D,5D,03,F0,29,7D,2C,31,EF,B4,43,B3,74,F3,F2,C6,C5,E3,57,E7,32,23,A2,08,AA,E2,D6,FD,1A,4F,4E,6A,E2,68,6A,31,BE,35,E1,13,4D,05,99,42,03,DD,12,EE,AC,AB,B6,C1,65,77,B1,22,D4,C8,63,71,18,1C,81,E4,CB,FA,EE,91,5F,23,42,06,32,9C,6B,34,4F,3B,0A,D9,EB,2B,50,EE,69,69,96,6B,9D,37,55,CF,0A,88,47,24,B1,5B,20,6E,9E,C9,6F,DD,28,D0,93,35,99,25,D6,57,40,86,25,33,41,30,B1,96,FA,C2,BE,82,0B,F7,30,6D,BD,4E,FC,06,B5,62,FB,91,FB,E7,53,E1,CC,BC,C6,D1,82,D1,E2,E7,2A,6F,6C,BD,69,4A,6E,8B,FB,0E,4E,EB,73,44,23,88,6B,42,FA,89,33,CC,59,23,A1,F6,26,DA,2B,D6,B9,99,54,60,10,51,DB,B4,E6,AE,94,D7,25,72,64,89,84,78,FF,5B,48,C6,62,74,60,A0,2C,CC,8F,6E,67,99,F8,4C,27,86,99,28,58,D4,A3,3F,8B,7A,17,B8,F5,72,2A,C0,1A,45,66,05,4F,B3,D2,F8,33,25,5C,9A,68,15,EF,C2,4D,2D,CE,F7,C1,27,0B,F2,D0,AF,AF,47,4B,E2,28,9F,30,92,30,33,60,A6,10,CB,46,26,81,D7,59,E2,85,43,0A,C6,84,F2,17,41,26,63,49,04,3C,67,2F,42,55,AA,BE,5D,F9,D7,FF,FC,89,12,A3,BA,AA,69,86,1A,2B,C1,2E,3F,69,60,CF,8B,91,3E,D5,45,F0,A4,E5,E5,0B,2C,16,96,AC,91,8E,BE,07,ED,B0,9E,BD,EA,3C,25,98,CE,19,99,94,91,98,88,22,15,22,3C,89,D8,2B,A9,65,9A,02,E7,07,61,17,6D,6F,4B,06,6C,6E,40,60,34,0B,95,1C,8E,3F,41,AF,5B,DD,7F,02,29,43,48,6A,F5,98,F8,58,11,43,3C,89,A9,C3,60,1E,16,D7,CB,29,7C,C9,A5,CD,30,E3,70,93,77,1F,0E,B8,73,19,4E,9A,2F,19,CE,65,1B,B8,4D,D9,37,E0,B2,B2,B4,2E,86,18,84,4D,98,8A,73,ED,FF,EC,DB,1A,42,A9,DF,1D,4E,6E,B3,FB,2B,A9,F8,62,F5,DA,B2,0D,BA,B8,29,6C,EA,54,FB,BA,FD,29,0A,33,3F,33,61,02,70,FE,0E,33,CC,88,70,BB,A1,66,C3,93,02,4D,55,B4,D6,CE,17,DA,25,F1,36,DB,51,18,9A,48,DB,AC,44,D2,87,17,F8,94,55,3D,F0,FB,1E,9F,68,0C,25,8F,CA,9B,51,BF,A4,D9,71,67,94,13,A6,85,19,69,E0,00,F3,E8,0C,26,21,CF,1E,B3,11,54,42,03,3E,5B,59,51,78,82,CB,DF,34,BA,70,0B,AF,44,7B,49,74,50,80,7D,C4,0A,E4,B2,A7,C3,0C,33,B6,21,52,6E,40,57,0E,3C,0D,7F,6D,62,50,10,C3,53,A8,35,76,AC,69,FD,B6,5C,AB,02,DF,75,AB,49,8F,28,A3,85,EB,24,B8,80,0A,BD,C9,A4,01,73,23,7D,9B,EE,7E,DF,50,E2,D5,7C,D3,F3,4F,FE,BD,AE,A2,25,00,DC,9D,03,7C,18,83,FC,45,10,EC,43,5E,79,9D,78,EC,33,0F,D9,DB,92,0D,6B,82,C7,B7,51,C6,74,81,83,E8,AC,50,19,F3,36,C3,E0,4D,F3,00,D3,45,F1,7C,0C,AF,D0,94,A5,92,00,A7,AF,CE,79,49,19,D5,C9,A2,4E,47,29,DA,E4,DA,55,C4,E0,15,42,CD,18,5E,18,AB,01,23,90,BA,88,C3,BE,2A,7A,48,11,A6,92,DA,90,3B,BC,91,8F,F3,A7,BA,46,E5,A7,74,40,B9,23,D1,B3,06,C2,48,1A,91,FD,9D,9E,49,28,25,9F,F1,FD,0C,F4,A0,49,65,CD,6F,2D,D5,9E,D6,80,06,E3,B7,BF,FC,9B,13,F1,73,1C,C2,E0,13,A8,0C,CB,CC,46,17,E8,1A,08,37,05,B3,32,02,7A,3B,74,DF,E9,7F,78,C2,6A,10,CD,78,6F,28,CC,6F,25,DF,B6,A6,C8,25,64,07,DE,61,B9,6F,C7,E2,01,FD,44,FA,F6,54,BA,4B,0C,26,0D,44,B6,4A,E8,65,C1,74,FB,8F,86,65,18,00,73,60,E8,0B,9C,A9,77,34,88,76,26,94,E6,64,CE,3F,A1,2C,72,51,7E,7A,93,EC,51,62,EF,BF,16,A1,CF,43,18,E5,35,C5,4C,94,70,B9,59,44,B1,EE,CD,BA,E9,B2,00,E2,4A,31,81,AD,58,32,6E,4B,1D,88,90,1C,79,E0,91,86,95,C3,32,19,62,7A,09,12,CB,9C,04,F9,4C,D9,D0,A0,8E,85,85,1B,54,88,DD,A2,61,AA,23,4D,E1,4B,98,2E,09,F7,1F,78,A3,A4,48,04,57,C5,5E,0A,B1,67,C4,DA,15,C8,BB,58,33,49,9E,B6,92,40,96,57,CB,4E,5C,57,93,56,F1,2E,E6,77,8F,85,36,07,5C,AC,8B,7E,78,D1,1A,03,0F,93,35,52,12,5E,49,90,93,3C,59,D7,55,B7,AB,7F,FF,5E,0C,4A,EB,AB,D9,75,4C,42,D8,40,00,BC,27,15,E4,60,42,0C,E0,A2,18,08,2B,17,A7,8B,33,3F,77,D3,B1,D4,2B,F3,56,FE,0F,54,3B,D8,57,2D,EF,BD,1D,5F,46,4A,F4,3B,FE,B7,6A,BE,13,E5,3B,E4,E6,88,9C,E8,23,B9,15,2F,FE,FA,5D,3C,7D,5D,15,62,FF,10,1A,D7,56,3D,3D,44,63,F3,90,35,7F,F2,E3,DB,10,C1,08,C1,E1,E4,55,D2,F6,36,B1,C0,26,79,43,5B,0E,29,D3,86,55,14,2F,4C,D8,FB,9A,87,BC,E1,4A,C6,D9,D5,61,E2,77,46,DD,C9,FE,2B,9D,2E,AC,21,5B,40,52,E9,31,AA,B3,13,F0,D5,9B,6B,F3,8C,8D,2F,AC,38,FC,3F,47,02,9C,56,B9,2E,DE,3D,79,15,43,DB,03,2F,E3,98,26,28,6D,45,C8,E9,BB,1F,64,BF,21,CA,54,C6,EE,00,1D,BD,71,AD,8A,C5,64,8A,3F,11,C2,0A,94,A6,D9,6B,43,7E,54,D6,1A,3B,FD,32,61,75,7D,15,62,C3,26,16,E7,D2,12,41,2A,F8,D3,2E,F6,0D,1D,AC,E0,17,0E,5E,95,21,A6,2D,AF,98,DD,CF,B8,CD,3D,F6,B8,9B,DF,2B,EF,76,58,73,68,53,94,E9,45,8F,E9,AD,44,52,33,40,4B,C9,D3,EF,82,1E,D7,D4,45,8E,D2,83,14,40,AE,EE,EC,B9,00,A6,94,07,5C,8C,D7,39,AD,39,0B,5A,BF,30,C3,6F,FB,A9,78,29,F8,8C,15,77,4F,7F,9D,4D,82,8F,22,B4,F2,54,F1,36,97,CE,65,1E,D5,74,23,43,B7,1F,AA,70,72,78,EF,AE,04,F8,40,F8,B6,92,0C,13,65,F4,3A,6A,BB,B8,0B,E8,79,BA,87,F0,AC,05,F6,06,BB,83,60,91,0F,DF,6D,6E,3A,8E,41,3D,A8,45,5E,DF,11,23,DA,4B,4E,38,67,D1,E4,F6,E9,F3,19,51,E6,6C,50,41,8D,05,56,07,31,CD,CA,21,FF,73,AB,47,EF,E4,1C,1E,4C,12,5A,06,C7,25,18,72,EF,CD,B8,12,1D,FD,A2,6C,79,E6,C9,2F,58,4C,83,07,A7,CC,CD,46,B8,EE,22,9B,CE,F0,8B,0D,87,6E,E6,67,32,D0,26,B9,9E,BD,EB,9C,9C,59,8C,13,90,AC,0F,E8,7B,8E,F5,B1,6C,F8,64,59,3D,FA,BA,0A,C1,C1,F4,F7,81,CB,4F,0A,39,F5,98,35,7D,C5,2B,61,53,8D,1A,82,43,79,4E,BB,06,FD,AC,65,C6,B0,3F,34,3E,D6,D0,3B,51,B8,C2,CF,2D,A4,14,05,CB,C8,30,A8,6B,81,E4,5A,EE,E3,30,42,72,9F,76,07,8D,16,28,22,BB,06,9C,6B,D0,73,BC,D0,2A,DF,03,06,F3,1A,01,9B,36,61,CE,9C,EC,3C,F7,31,6D,B5,24,89,AA,A4,1E,17,80,16,D3,42,4A,D7,BD,62,58,13,CF,5D,B9,5A,A6,14,E4,8B,1D,08,E5,45,57,D0,6A,D8,E1,67,4F,F8,1E,A6,4B,39,3E,BB,D9,71,D6,95,92,BF,C0,BD,EC,B6,EA,7E,AC,A9,30,0A,AA,B9,3E,29,F9,57,2C,C4,25,9A,5B,72,C6,07,C4,6C,7E,F0,A2,2E,4D,D3,00,FB,D9,35,60,BD,B8,1F,EF,8E,3A,81,D5,44,1C,DB,0D,8B,ED,0B,1E,C6,8A,B0,C1,7A,2A,7A,A1,98,D5,28,2C,CE,F8,77,97,F0,E5,73,6C,8C,06,F0,C1,B8,BA,2A,0B,38,0F,CF,D9,58,05,A5,F0,9A,27,02,AE,2E,26,7D,B7,3B,CC,88,B4,DA,11,DC,5F,16,F7,70,4B,C6,B7,BF,D7,CB,5F,3C,6A,4D,13,8B,31,43,C1,77,3A,AB,B2,C2,F6,BB,A6,EC,2B,4C,E7,CB,1E,2D,0C,85,81,D1,EB,1F,4D,92,AE,E3,30,2D,A6,1C,55,A2,95,96,48,1D,C7,E7,A3,10,86,0F,C7,75,15,4D,1E,FE,35,37,F5,98,C5,8D,D4,94,C6,5B,1F,5F,68,48,A7,BB,23,92,E3,BB,F2,4E,73,EF,7D,73,2E,8F,B2,E3,3E,CA,4B,3A,1F,30,6B,99,93,F0,03,20,1B,2B,DC,7F,72,B5,7C,8A,36,74,2B,F6,B2,56,FD,1F,FD,7F,95,0A,61,50,E2,D3,FA,8E,50,3E,2F,61,C5,C7,DA,F1,F9,12,54,94,A2,A3,61,D3,8B,4F,B8,4E,9E,73,78,D7,2A,2D,7F,40,44,60,A1,9E,90,1B,85,A9,56,7F,51,62,4B,33,F6,BF,55,D7,EA,BC,FB,2B,AB,DE,8F,B6,20,0E,4C,1A,F4,45,50,DA,4A,F4,7E,5D,0A,D9,F8,82,ED,D5,6D,1C,C4,12,ED,17,FE,EE,FC,EF,C2,82,BC,CF,80,CC,AC,72,20,AA,81,E9,3C,9F,BA,C3,91,B3,41,C2,55,08,FC,2E,C5,AB,28,35,15,F8,63,D9,28,54,A5,7C,9B,E9,84,B3,3A,A1,9E,2E,B7,38,57,4D,68,C9,4B,FE,86,E0,96,10,BE,56,33,3B,A6,E3,50,B5,30,5F,A3,FD,C1,FB,D4,48,F5,E7,3F,A9,FA,51,31,AD,58,D6,29,19,B7,AF,B5,F6,16,8F,16,86,E5,4B,6A,61,47,99,55,FE,E8,C2,5E,BB,C2,48,78,2D,EE,CA,7B,FE,B9,24,EA,76,BB,6C,67,5D,A6,1C,59,5E,66,7C,12,11,57,89,FC,7F,AE,20,16,9E,79,EC,08,E8,E4,6D,23,B1,9F,E7,88,A7,5A,91,1F,30,75,9B,77,78,29,32,87,66,3B,91,3C,F3,1D,D1,8E,7F,DB,AA,7D,A9,43,82,1F,1E,12,4B,70,F8,13,9E,F7,9C,2B,CC,E2,83,6E,60,BB,C9,31,9B,AB,55,5D,EA,A9,90,20,24,5D,5F,18,EC,2E,60,2C,E9,28,E9,4E,9B,E3,75,63,8F,AA,52,3F,14,E2,26,FD,82,71,E6,2B,6E,65,37,9C,8D,54,E4,66,D6,D9,31,A6,26,2B,4B,5E,3B,E5,27,D2,1A,AE,C6,2C,AF,EA,70,B4,86,0B,79,CA,CB,FE,D9,26,CC,C2,5C,07,F0,F7,F8,35,E8,03,1D,D3,9C,5B,47,4A,A1,47,C6,0B,CB,AC,45,EB,E2,B7,49,58,2E,7E,02,C5,BA,CD,88,8B,5C,CB,73,14,79,4D,58,10,59,3C,10,4A,72,C4,50,51,FF,F6,4E,5D,D4,7F,99,BF,27,BB,33,E7,A1,F9,F5,CC,9B,B0,7F,8E,40,90,E2,AA,F7,54,05,95,2C,A9,42,2F,68,19,BC,9A,0F,BD,30,8A,FD,F1,AB,65,84,79,0F,6A,3E,78,6F,8F,18,0B,1F,AC,4F,11,C1,19,25,84,8A,AB,75,E2,B4,6E,D1,69,63,B0,59,1E,E4,28,A5,68,1C,49,67,9C,AC,74,F7,09,64,53,2D,49,80,09,BE,58,46,CA,78,A5,8A,EF,E3,69,FB,5B,CF,CE,0A,22,CC,07,BA,5F,E5,90,C9,E4,24,0B,DD,56,07,CA,12,8E,26,0F,F2,EF,44,34,57,3A,75,0C,1C,F8,D9,17,7E,C7,10,BC,93,D7,3E,B6,73,7F,6D,53,43,65,67,3D,0D,9F,D2,79,CD,95,5A,6A,B1,12,6A,05,51,B0,DF,63,CD,F2,F6,48,F3,15,61,59,0D,B8,E6,70,F2,3B,FD,92,3C,BB,B0,26,93,6F,68,9E,C8,F5,C1,F0,79,ED,A5,E4,0A,4E,9A,F0,6A,0A,49,BF,EF,58,09,1A,A6,1A,A5,B6,9A,86,39,99,DA,E4,E9,CB,26,F8,DB,D4,DF,23,86,C2,E5,07,14,FC,10,2F,EB,3F,DD,95,11,C2,57,03,1F,A7,BC,28,01,D3,A8,60,54,7E,86,53,94,0E,0E,4C,17,4C,0F,E3,5B,11,F1,CC,47,6A,27,68,C4,29,EE,15,AD,8A,0B,08,EE,8E,07,47,B8,33,59,10,E0,B5,0D,E0,18,B6,85,0D,E7,1C,B5,7D,A0,C3,47,52,AE,B8,73,A6,0B,50,C7,DC,DD,EA,9D,51,9C,46,1D,FF,36,23,DB,D8,87,0F,98,F1,AE,0C,F2,E0,3E,54,66,E1,84,A5,20,8C,E4,14,CC,0E,79,B7,F1,43,45,41,54,E3,5C,1F,B8,8E,E3,0A,7C,C4,42,CD,BE,AD,3C,48,AF,0F,63,96,A6,1E,6E,AD,2F,21,56,88,A0,FA,C9,A1,3B,E4,38,D7,A0,12,8A,F8,9E,DF,9C,5A,B7,0C,AF,95,F1,EB,D4,F1,CB,27,6B,3F,0C,7D,1A,9C,98,47,4A,3A,65,2A,B8,70,50,C5,3F,61,5C,81,3B,D1,1C,1C,8B,10,24,F0,2A,80,6E,99,5E,3B,09,CB,44,E4,75,76,B0,1F,E1,52,47,04,15,BD,B0,E6,4C,8E,8C,BD,97,59,8E,13,1C,BC,5F,5A,29,FD,89,87,13,0F,AB,BD,76,B7,0C,6F,9D,40,56,7C,1B,0A,3D,B5,38,A1,60,04,3D,4F,D5,91,B4,1E,A3,FF,B5,45,AF,1D,1F,11,87,21,9E,B9,8F,69,F7,43,C5,EA,D6,69,09,E8,7A,0A,45,B6,A3,F0,86,8C,0E,D2,44,F6,AA,6B,59,48,3C,A9,21,94,4C,23,71,4E,B6,3A,8D,CC,66,8E,37,E5,E7,51,8C,1C,AB,78,1A,8A,CA,E1,35,35,49,0C,73,DD,56,8C,97,CF,97,9B,BC,A0,E8,F5,26,5A,D4,A2,1F,62,33,0A,99,FD,C9,DC,2D,A1,0A,AB,85,1B,55,6B,05,7A,50,0E,1C,82,AF,AA,58,FA,23,80,C1,51,AA,95,C3,54,A8,B4,A0,52,14,4D,35,2D,CE,7E,CE,78,E4,B9,B3,E1,28,9B,3E,05,4D,4C,C0,94,54,92,B3,12,49,5A,DD,40,59,14,C6,B4,4E,7C,B5,FB,C0,E7,E0,5D,31,1F,EF,4E,04,8B,95,17,2E,5A,3F,38,EB,6D,72,84,75,DB,E9,A0,FE,B5,58,7F,1B,4F,DD,05,70,B7,92,04,7F,B2,F1,22,E0,FA,C5,3D,E0,36,15,D6,A8,63,87,6B,BC,C1,1E,E6,AC,57,9C,F0,55,76,A0,06,09,B0,94,C6,1E,F5,2C,ED,69,14,C5,E3,55,57,8F,05,54,8A,B8,35,0C,11,2D,CC,AE,37,8B,8F,56,84,1A,02,5F,78,E2,D3,1E,23,2F,B9,26,3C,1A,DC,24,AB,58,5E,41,41,1E,05,4D,38,97,61,07,A4,A9,51,19,9C,3E,03,30,54,D6,AC,65,E2,85,0E,B0,05,04,F6,30,9E,D4,AC,28,5D,09,D2,1D,8D,05,95,05,9A,0D,02,0D,9D,C4,4D,C4,91,B5,3E,01,4E,9F,53,E0,F9,40,C2,81,90,63,F0,65,FF,7F,B7,25,9C,83,FB,0A,6C,2A,DE,F4,E8,5F,82,1E,1C,D6,B4,05,BB,E1,58,C7,5F,47,C9,93,C9,CD,4E,9F,35,4D,6C,D1,0A,F2,FB,C1,41,15,43,7A,BF,BD,E4,A0,8B,3B,C7,25,7A,3E,DC,0D,1E,E7,8F,AB,EB,88,3C,84,FE,9D,B1,CA,FB,25,45,AF,BD,79,EA,6C,58,66,1E,03,CF,A6,63,1E,6B,3B,E8,EC,BD,73,D9,40,93,1D,4D,A0,D3,38,EC,2B,68,23,F9,46,9F,2A,13,0A,5D,22,10,38,34,DC,3E,74,EF,57,50,22,13,81,B2,B3,0A,2D,C6,21,CF,E8,6A,80,C9,AE,54,2E,B5,ED,6D,AF,2E,73,E9,0E,5C,D6,BF,10,E6,2F,9C,A3,00,E6,F9,AC,A9,AE,FE,45,17,02,47,FD,95,8D,D0,B6,07,8B,4D,25,29,8B,65,6D,0B,DE,97,38,4A,37,A4,D0,A6,5D,12,72,4D,B6,1C,29,AC,7D,12,EC,79,A0,37,04,DF,52,35,58,D7,B5,82,A0,39,F8,E5,55,0F,39,93,83,30,A9,0F,28,F0,12,EF,40,8A,59,E0,90,AA,67,BB,C2,C5,5C,8F,95,FD,03,00,8D,54,0E,ED,0A,27,96,F4,D0,B5,98,C2,EB,86,04,31,66,05,59,84,D4,B8,33,A5,F5,EC,65,D4,B9,D3,F1,8E,B5,FD,7C,6A,59,42,DD,92,32,CB,1C,8B,CB,DE,DB,54,C8,52,E5,C8,47,0A,7F,D4,5C,38,69,FD,10,6F,00,88,93,90,4E,55,55,67,A7,E5,D1,95,16,65,B9,2D,E0,93,06,E9,DA,4C,DB,E6,ED,28,66,2B,C2,79,0A,A8,90,7F,13,E2,35,B8,BD,43,F3,EC,A4,55,7A,B5,FF,0B,7E,7C,EB,9A,EE,CF,AE,4C,C5,9C,F6,42,D2,B3,23,B0,4B,95,65,D4,BF,D4,70,12,5E,13,8A,40,0A,12,DC,BE,01,F5,D0,1F,B5,3B,D3,02,89,79,62,1D,E0,63,6A,A7,7C,20,F1,84,69,C0,F4,A6,60,B6,C5,BE,4D,81,6F,F6,C3,D1,65,13,2C,9B,41,92,4B,65,44,28,92,A6,EA,15,DA,51,AC,CD,39,C0,2E,AE,D0,7F,B9,2B,1F,70,F0,D6,B7,BB,C4,65,A6,1A,25,80,2A,E4,C2,BC,6E,64,A1,F9,3C,F3,F2,EB,70,69,2C,01,1B,F2,EC,24,3B,81,9C,D0,2E,2B,A3,0E,BF,03,33,28,47,2A,FE,1D,A8,C7,A0,8A,F4,AB,16,F3,EB,45,F8,04,36,CB,3C,84,CC,53,DD,81,E8,28,6F,E6,D7,B6,CF,C2,5E,16,A3,6B,3A,02,B4,7D,D8,5D,77,B1,51,44,7C,11,F9,AA,E3,F1,98,88,44,16,BE,C4,3E,BE,08,B8,BF,75,8D,5D,C9,D0,A9,D9,29,DC,8B,4B,3C,EA,39,EE,97,67,BE,4B,F7,CA,CC,F9,A7,57,EF,17,C0,1F,D6,71,C2,EB,7C,25,6A,9A,21,F5,ED,EE,DB,EE,E8,C5,BB,D4,B2,D8,95,4F,79,D8,A1,74,47,FE,45,38,B4,BA,94,FF,2A,C6,12,1A,E5,38,CD,35,1E,1C,8F,63,46,8D,33,18,02,39,7E,F4,38,85,8D,39,05,D4,87,2E,76,B2,80,27,29,D0,89,50,C2,E4,A4,82,C7,BD,31,E3,14,EA,34,D3,81,27,8E,F0,A1,82,C1,AA,94,B0,25,8D,9F,15,94,87,E2,0A,BB,FB,47,A2,5E,D7,16,37,90,8E,11,D5,8D,3D,A5,7C,50,EB,C7,2A,6A,30,34,63,91,03,AB,C0,62,F2,B5,5A,EF,AD,F1,EA,AF,A7,37,46,AF,25,4D,6A,A4,F2,EE,6E,89,2C,36,68,8A,08,0E,AC,BA,41,3B,62,A3,14,40,C3,5D,F7,BD,81,E5,81,2A,79,8A,CB,BD,33,9C,06,63,97,81,C5,C2,4E,B9,54,50,40,C9,F5,0B,CD,EF,7E,24,5D,36,FF,83,C5,09,1E,92,9D,3F,E2,A6,A9,A1,D1,38,07,CE,0E,78,1B,A0,77,51,AF,C3,10,CC,26,E3,02,91,4C,EA,63,85,FB,B1,A8,23,D6,9E,4F,E4,45,C5,DC,86,32,8B,B8,5C,87,B9,29,FA,0E,ED,25,0B,DD,9A,59,9E,36,62,9D,FE,AC,E3,CA,94,60,E9,C2,25,9F,1B,B2,E4,6B,1C,04,33,98,49,A2,4E,5B,64,79,0D,BD,D7,23,70,19,39,75,A3,58,A7,DB,18,BB,EC,7F,E6,7D,B4,F9,E2,F8,B2,21,A8,FD,66,E2,23,1B,B8,35,BB,FE,22,C2,1B,63,D3,FC,29,19,2D,14,BF,B3,81,56,05,E0,20,66,E2,F2,01,82,27,30,78,FD,CD,6C,22,F8,06,B3,A3,D7,BA,37,83,19,06,0D,C0,04,B6,D2,9D,58,29,9E,24,55,CB,99,F8,10,C0,E1,7F,4B,98,49,2F,96,4D,F4,4A,10,70,37,9A,F4,3D,01,46,37,CC,9E,CB,BF,5F,BE,99,43,C8,88,18,E5,E0,9B,42,44,9D,57,E3,F8,A2,7B,EA,BB,67,FC,DA,CE,FE,3D,F3,05,B0,35,35,14,9A,0B,99,F6,A0,37,03,0A,B0,64,72,D2,16,EC,68,03,94,C2,66,A1,FA,FD,3B,64,44,2C,D2,AC,F0,AA,F4,6B,17,58,19,BA,27,09,26,31,47,B6,71,B7,EF,9A,53,4B,66,7D,8B,74,5A,43,6F,DA,EE,0D,11,96,0B,1B,1E,1C,1A,3A,66,F3,5A,2E,41,EA,FD,E3,C1,72,D1,29,B3,FA,9D,BB,C5,86,45,DC,BC,E4,F9,64,4A,80,FA,E7,60,22,4D,EE,96,BC,A8,C5,F7,E0,90,69,04,8B,0D,76,F3,89,16,D9,EB,DD,89,6A,0A,6F,41,72,FB,A4,32,1A,FB,C7,97,18,3D,15,B5,A0,1D,9F,AA,E0,64,67,FE,28,F0,07,DE,EC,3F,4B,35,9F,50,62,9B,FE,06,1A,E6,F0,C5,80,16,73,21,E0,5F,F3,6A,F4,C7,F3,CA,A3,4D,9D,B6,A1,CF,C6,E9,83,62,A7,9E,77,B5,3B,7D,7C,15,FF,ED,57,7C,2F,0E,E2,72,BA,63,84,C5,02,05,CE,84,B5,B3,2F,B1,8F,2C,E6,CB,30,AA,D4,C3,73,64,90,8E,7D,F1,0F,32,C8,A1,EF,A8,6B,2C,04,78,C1,85,E9,B2,E2,44,86,91,C9,0C,7B,D6,71,C7,7F,93,F7,EB,69,04,86,76,82,75,15,22,D0,D2,F0,34,0C,98,3E,A2,D4,81,E0,A0,B8,A1,25,7D,08,2E,AC,65,7B,6A,1B,BE,57,73,FA,5A,A9,26,64,E4,94,87,1B,6D,6B,CA,6C,3B,A3,53,72,C5,11,E4,29,B4,CE,73,A4,B4,2B,40,B4,88,FB,A1,01,FE,02,0A,3F,C6,BA,DA,8A,EC,69,70,20,A5,01,EA,56,E1,CA,9E,96,E3,54,CA,9F,B1,B4,03,44,BA,24,D5,23,B9,5A,26,8F,1F,AD,ED,B6,79,70,11,3B,49,DA,BC,18,F2,91,3C,3D,67,B7,89,97,64,F1,9A,89,0F,B7,CF,EA,21,B5,25,9C,F9,B9,38,68,B6,DD,3A,64,4B,71,07,43,B9,50,82,2F,B4,97,AD,9D,AC,FD,8E,C0,90,9D,D0,8A,70,E3,BB,1E,3D,36,C7,AB,A4,87,7B,1F,C2,54,B2,BB,89,EA,FB,C6,1F,A7,C7,A4,30,8D,74,70,DB,7D,70,C5,5E,2A,E9,19,EA,45,2C,26,02,35,F6,81,E6,BA,69,DE,CA,31,8A,B4,48,29,68,4F,C9,02,D0,1D,5B,EF,10,3F,1A,B3,14,13,7F,78,24,82,CD,78,30,0B,E4,A1,73,41,EC,6B,C2,7C,EC,E3,19,5D,96,7A,82,46,70,A3,14,EC,B0,70,98,DC,74,BE,56,55,0B,6C,50,39,71,B6,AA,B2,EB,60,39,A4,B6,53,31,EB,00,96,4A,45,39,62,BD,A5,54,02,52,87,44,7F,7F,5E,F4,4B,82,2F,8D,3B,ED,F4,C0,97,27,45,9A,E5,84,B3,EB,D0,2A,87,6E,DC,77,EC,C4,B2,65,3E,FC,AE,ED,E0,16,E1,F0,CF,2C,0D,19,08,F7,D3,86,AA,C0,FF,0D,D3,1A,D8,22,AB,E7,69,7D,CD,78,E4,97,95,DA,D7,FC,5D,5F,DD,AB,C9,B7,7F,01,A4,00,77,C0,7F,DB,27,BC,5B,B3,EB,68,8C,3E,13,17,52,F3,25,15,AF,26,64,2E,42,C0,96,E2,8F,6C,44,46,40,40,A2,31,F6,E1,CE,34,CE,1C,F2,C7,7F,C6,FA,77,94,33,66,49,FA,77,BA,FC,BF,D4,B2,0B,27,FA,12,37,EF,2F,64,B4,41,52,59,42,76,BD,D5,5C,04,84,DC,E5,D4,67,3B,96,5E,5B,3A,26,C5,E4,11,49,B6,13,17,04,BE,6B,91,FB,A8,57,E7,F2,84,9E,3C,0C,EE,C8,8D,C8,67,CA,9F,E2,8E,99,C7,3A,64,7B,E9,C1,59,B8,0C,BF,B6,41,47,CE,49,01,CE,D8,C8,26,0E,5D,31,7C,33,D1,E7,97,0E,11,EC,84,F1,4F,12,B4,66,B4,F2,D8,6B,92,B4,7D,78,15,B8,EE,42,29,BE,16,7C,D8,D1,9F,F8,AE,B7,5B,13,6E,4E,1E,F3,48,14,50,CC,4C,0A,32,F9,A1,1B,11,FF,28,CC,BA,AA,A1,E1,4A,89,3C,88,8D,DC,96,FD,6B,13,84,43,0D,12,ED,9D,F8,3A,AE,F4,69,A9,FF,D2,10,BF,BD,77,02,60,23,3D,B1,84,82,A5,7D,9B,05,09,4B,70,D4,21,46,C6,58,9F,FA,6B,35,3F,E1,EF,03,41,33,28,79,B4,54,EF,69,35,5E,40,CA,15,99,45,72,6C,87,04,EF,9A,69,F9,8B,6B,13,F2,6E,82,C3,5A,82,CC,49,0C,59,52,74,37,07,CE,2A,49,30,98,2B,28,0C,55,AF,9E,6B,EC,EA,B5,1D,7B,D8,F2,E0,87,18,55,ED,95,25,44,7D,FB,90,8E,57,C2,83,EE,67,6D,37,F5,E7,6A,FC,8C,D0,28,18,7A,FF,60,50,87,BD,F4,22,5B,A5,69,04,36,4F,39,44,D3,A7,F2,C9,88,E9,21,6B,45,6C,0B,A1,73,FD,2E,2E,66,D1,C2,22,F0,4C,DF,D3,3B,9D,95,F0,6C,56,E4,D7,12,E4,A7,68,FC,E5,F1,DF,B2,29,A5,40,A1,A5,EB,13,7C,C0,22,CD,4D,BE,9B,30,07,A1,28,96,A1,7B,E4,AD,DF,95,6C,44,97,E4,98,54,8C,D1,96,F6,1F,A5,89,AA,A9,43,FF,97,21,A6,77,03,5A,6F,DA,3F,CE,CE,B0,58,98,E4,6D,D3,19,86,35,F5,BA,99,67,E1,C9,3B,C3,96,D9,2C,F0,58,33,88,23,3A,81,A6,B3,7D,76,73,8A,2E,09,AC,62,51,5E,38,ED,94,EA,D3,8E,29,2C,25,38,B0,13,CB,8C,61,12,31,2C,92,3F,1A,62,99,DA,A5,46,9D,07,5E,21,3D,53,18,61,21,89,22,6D,0C,F8,6C,E7,DF,72,32,D2,20,B5,4D,06,9F,98,DC,34,5C,9F,F1,59,84,DC,9E,BB,69,42,E0,0B,DE,BA,C9,56,CC,11,03,43,A8,B8,73,2B,CE,FE,77,5A,38,64,2C,50,F6,31,EC,DA,32,B7,F4,B4,35,B5,D0,24,41,BF,7B,CC,35,A3,4D,05,04,FA,C2,C7,27,23,D9,F2,C4,48,29,BE,59,40,D4,59,47,64,D5,A9,18,EE,F1,50,DD,C5,C3,3E,B2,08,1F,8E,E9,96,F5,9C,8B,60,08,C6,51,9D,CC,08,5C,3A,2F,41,14,E0,F2,49,96,09,E9,2F,C5,8A,C3,E9,F0,66,6E,1D,6B,AE,A8,CF,52,31,2C,1B,45,B5,B4,67,92,B8,B7,41,6C,45,F6,A4,B9,CC,23,71,87,8B,7A,30,57,99,06,45,3E,3D,06,BD,50,51,44,00,90,05,63,C8,6C,94,9D,B7,79,69,5F,CD,D5,E8,B2,D8,FD,70,91,1C,85,2B,42,11,9F,67,DC,76,92,EB,6B,DC,11,E3,64,6B,00,6B,B2,AF,4B,B3,7F,D6,34,43,AE,99,A0,2A,6F,FE,2D,51,30,DA,A4,51,61,56,AF,E9,00,41,51,5C,07,BB,D1,5D,80,1B,BC,1B,92,6D,09,B3,20,1A,92,D9,7D,46,BD,13,FC,C5,24,08,BC,2C,BF,49,AF,5E,51,E7,84,78,4D,5F,9F,1A,19,F3,4E,9D,BD,43,FD,87,CE,53,F2,71,9C,C0,AC,43,CB,63,86,4D,BD,FD,34,BD,3A,35,05,2B,0C,35,7C,4A,A8,05,58,F2,56,A9,8D,F1,D8,91,FC,4F,2F,DA,A8,68,B1,1D,F4,38,E7,32,25,E1,39,8B,66,61,1A,B8,7C,4A,20,0C,F3,E3,2D,80,DA,72,9E,5C,F4,8F,D0,5E,CA,8D,88,28,38,B5,3E,59,AD,31,88,CB,5D,83,40,21,D2,DF,FD,A2,3F,86,26,BF,34,C8,90,54,77,B1,78,E5,42,28,6E,7A,DE,D2,F8,F0,AE,B7,2B,D8,E2,6E,48,EC,65,B4,0E,9D,7E,2E,69,65,B7,71,0C,C4,D2,9D,DB,60,A1,D6,1A,07,D5,52,25,C3,88,32,5C,D6,71,10,BD,E9,45,A5,F4,1D,F3,45,36,28,27,F6,DC,74,74,C0,F5,D1,E0,84,6E,D2,D6,EA,36,20,CF,B3,EE,80,F3,6F,14,94,63,0E,F4,78,E4,5A,AB,B2,3E,34,C3,54,4B,D4,DE,D3,E5,52,7B,99,0A,27,BC,AC,7B,EE,64,B7,6D,C0,30,22,AD,77,35,21,E2,02,AD,C3,90,6A,5E,0F,06,D5,9C,61,A6,FB,44,F8,EF,55,9A,94,C8,5E,F8,48,75,F5,48,AE,5A,B9,3B,07,AC,4E,1B,91,34,7B,C5,E3,7B,17,C9,12,DA,65,27,C6,55,0C,4B,CF,6C,04,F0,67,B6,72,1C,D1,2C,D6,72,5E,E2,CA,FC,05,34,14,A0,7E,ED,23,CA,71,4A,CC,C9,E4,A6,0A,17,B7,E8,96,1C,CF,47,F7,F5,67,B6,1A,71,32,BA,59,A0,50,E6,57,82,81,2A,33,27,B9,2B,BD,E4,02,95,14,31,B5,1D,C6,94,D5,19,FF,46,2F,99,3D,53,9C,0F,D3,1D,C3,ED,08,58,98,55,FF,73,E4,2F,C0,CD,37,01,98,2A,FB,BE,E7,7B,5E,C4,5B,49,72,70,F2,E6,B7,65,13,EA,14,B9,F2,AA,E6,E1,98,01,ED,90,07,2D,7A,27,10,1E,E3,E7,65,E5,0D,B1,4D,E8,6B,0E,BE,20,8E,11,EF,1C,34,B8,2E,8A,87,CA,BD,31,82,71,EE,26,27,31,F2,7E,BC,DC,33,BA,AE,23,8B,E2,86,8C,74,77,AC,D9,BA,5C,5C,A5,42,E1,D4,1C,B6,16,CF,1A,D2,33,41,AA,15,74,8A,64,85,E1,84,A2,64,29,BF,2F,3D,81,AA,9E,40,27,1E,AB,49,DF,B7,7C,CF,C2,BC,21,8F,AA,21,64,67,36,32,90,5B,A5,6B,C2,8C,B1,EE,0A,C9,C3,28,6A,70,51,DF,35,62,4A,F9,BF,2E,DF,92,C4,5B,30,70,57,EE,65,97,91,84,C7,35,1C,97,C5,20,3E,15,BC,40,2A,16,0E,3E,BE,B1,66,CA,FB,6A,B8,C5,87,55,2B,30,ED,8C,9E,71,6B,D5,DE,F4,4C,08,7A,30,B0,12,76,72,A3,67,42,1F,B6,37,5E,BA,75,F8,75,6C,BC,74,73,2C,F7,C6,B2,7A,BD,FD,2C,6B,13,8E,DF,94,C5,F2,E9,0B,EE,C6,11,48,6D,2D,83,5F,E4,77,13,17,18,FB,AF,A0,80,03,90,16,8E,16,1C,C2,C3,9A,BA,98,38,9A,50,C9,34,8B,68,3B,69,07,2B,7D,CB,67,46,E5,12,AE,D8,42,5D,FF,C9,A5,B3,57,9D,F6,63,B2,EA,7A,E1,8B,7B,01,25,A9,FF,75,0B,76,D5,63,70,D5,21,A8,3F,F7,99,98,F9,8C,B1,85,61,A2,15,4F,1F,D0,E3,BC,79,31,F6,91,9D,14,E7,C9,E8,24,36,47,38,8D,76,5C,BC,7D,ED,23,4B,7A,BF,AE,F3,72,3C,0B,FC,AC,D0,61,5E,03,16,F3,7C,E3,2C,F3,A5,C3,8F,57,E6,A8,22,B2,25,B5,9A,EA,D3,F9,8A,30,89,EA,91,2B,B7,0B,DF,64,FA,AC,2F,2B,EB,01,91,6B,AE,92,DD,0B,25,29,4C,18,79,B4,70,2A,AC,3C,83,9D,7E,02,9E,D2,F2,53,DB,72,2E,A9,CB,D8,52,28,F5,02,EA,D4,0C,D7,77,4B,43,D8,EB,8A,F8,D6,66,03,E4,9A,FD,BD,3E,AB,17,BF,3E,A6,F6,14,20,0E,79,95,FF,38,FA,3B,EC,C5,36,9E,73,AD,AC,57,95,44,A1,59,7A,E2,80,A3,91,45,72,52,E8,33,C6,C4,83,EE,A3,D0,0F,5C,66,6E,74,55,C4,8E,46,00,41,31,EA,0B,A1,DF,2D,46,89,FA,00,22,42,8B,23,B2,B9,D6,12,A5,CB,36,FE,41,B9,51,FB,F1,61,6E,EE,2A,E5,FB,93,17,A2,45,38,8F,05,4D,D7,E3,37,F7,3D,E0,C8,FF,7A,D7,D8,92,FD,0E,22,EA,85,2F,B6,A6,74,2D,EB,A2,29,46,7F,DC,DF,C7,8F,41,38,E5,5C,4D,63,40,03,0C,CD,F9,5D,6B,D0,20,78,DF,FB,0A,9E,C8,72,C9,90,46,BC,B8,81,29,DD,89,D4,78,45,B4,A2,75,78,26,78,36,41,6C,BA,F8,2A,28,D5,F1,EA,BD,01,1A,D1,A0,BF,D8,D7,CE,58,F0,A9,61,7D,78,00,96,26,03,C2,16,AF,59,D5,4A,39,68,9B,9D,78,31,D1,34,6F,07,16,2B,0D,5C,92,7E,B9,6D,F5,15,4A,DD,4E,6B,90,CC,18,F0,E5,DE,8F,83,D2,FC,2F,37,86,A0,F6,AE,0E,22,B1,21,38,24,14,75,C4,DB,2E,D9,FF,A5,03,25,53,06,FB,C3,E8,2F,45,02,7B,75,E1,12,42,8D,3D,9C,7F,E3,3F,19,98,EF,C9,B1,79,A2,AD,E2,85,84,4E,1C,6E,DE,B0,54,D3,16,28,03,F8,22,25,F3,42,86,80,40,69,A4,C2,72,89,CC,49,F5,76,F5,65,08,8B,85,C7,6E,58,94,D1,50,BF,91,99,DE,EF,FF,0A,F0,13,E5,B9,08,6E,6D,C0,38,27,47,C6,99,9C,A1,AE,2A,FD,F7,89,15,8E,BB,6B,94,D0,AB,4B,39,89,35,5F,0C,37,9C,34,43,8A,A8,23,47,B8,A2,DD,AC,9E,C4,06,11,2D,DC,A1,32,9B,23,E1,2F,4D,B4,64,70,BB,86,D7,C7,F1,44,E4,E9,19,B6,A3,9D,3F,AC,69,57,EC,5F,45,36,72,D0,FC,E6,BB,ED,A4,50,97,7E,E4,00,1C,6B,49,49,FA,6C,F7,FA,FA,7C,4C,81,D7,2D,7F,FB,85,C6,30,70,23,FA,9C,67,C7,BC,BD,F8,7C,42,D8,EA,ED,E4,61,A3,64,ED,DB,43,70,20,FD,4F,29,F6,BD,0E,3D,59,33,C1,A3,E9,2E,CB,2E,88,30,93,78,03,1E,59,74,82,F2,23,3C,86,95,BF,1A,10,B1,3E,BC,45,24,AB,64,BF,70,E1,87,22,5C,37,A9,26,82,2E,50,5E,22,D5,49,93,D9,00,38,ED,80,11,46,94,45,82,83,4D,BC,49,6B,E9,27,D5,05,D8,41,F3,AD,A1,1A,3E,56,1A,C9,91,DA,8F,8B,D4,D4,50,86,46,5E,EC,B7,19,EE,70,CD,27,55,3A,A7,A5,D6,26,0E,DD,08,06,20,33,9B,11,3A,58,06,D8,62,58,DB,BF,C3,B6,6A,10,04,85,8F,F5,C8,A7,FB,8F,C9,73,3F,A7,F4,D8,88,24,49,F5,79,32,BA,46,A1,58,8C,77,79,E6,D6,14,D9,9C,23,AB,60,81,DA,5B,F3,E3,A1,05,E5,6F,61,67,0D,54,0B,83,6A,D8,EC,F6,16,43,DD,6F,48,D9,AA,9C,4D,BB,8C,01,9C,DA,19,C0,50,CD,B0,72,4B,CA,15,92,DB,9B,53,83,5D,41,08,8E,2D,8F,39,3E,CE,31,06,78,7A,E7,32,10,3B,54,C2,56,DB,20,72,D4,4D,E4,96,B2,C5,F9,46,44,D8,AD,92,69,9C,7A,3B,EC,D8,59,31,C6,B2,DB,8D,AF,7F,FE,5F,91,A1,8D,45,D5,52,B3,EC,63,D5,69,95,D1,D6,7E,E3,51,7E,13,92,77,0E,A8,ED,75,2A,C3,38,9E,AB,82,47,80,9B,21,C5,69,D2,10,0F,F5,83,FC,05,45,C7,1D,02,FA,71,12,81,97,82,4E,37,67,C4,EB,49,6D,16,BF,C2,94,95,B5,92,94,73,DF,52,16,89,59,EF,26,42,86,1A,C9,F3,BA,6E,DB,1C,F3,0C,9A,47,4A,1A,55,92,89,E9,4D,71,32,74,89,51,CC,70,DE,67,2C,0A,53,34,B4,B9,29,AC,62,3A,D8,82,9B,AC,B1,A1,43,B0,49,F8,60,BF,1B,F8,70,EA,D3,F0,07,3A,16,CD,3E,27,AE,94,1E,F9,20,42,2C,D4,F4,3C,25,04,60,5F,E5,81,8B,E3,4C,F8,03,94,A2,FA,3A,DE,34,5E,56,D8,1F,BE,07,76,B9,7B,32,45,F2,A0,86,11,78,CE,F0,6C,ED,2F,5F,D9,8C,27,AC,83,00,44,3D,B9,34,4C,75,BC,C8,F3,BF,C5,DC,52,5B,AC,18,43,54,78,67,F1,21,EF,B1,90,EE,BB,BA,38,AF,6D,34,94,78,6D,57,89,6B,50,32,34,B3,99,58,51,A5,9F,A3,16,A6,EE,93,15,9E,DD,5B,22,A8,50,82,CB,11,83,D2,5E,0F,D7,D7,57,2F,6B,E2,1F,D9,90,9F,EC,8F,01,55,80,1E,DF,9E,69,70,D5,11,63,3A,3A,67,F5,3A,84,53,7C,8D,65,A1,22,35,A8,17,C6,80,66,4A,ED,47,B9,9F,32,CA,2B,58,4C,55,44,2B,9E,A7,97,0C,9B,71,8E,10,09,1E,FC,E0,CC,57,39,69,CB,6F,1D,36,84,C2,12,79,BF,F7,DD,1C,82,E5,C5,D5,D7,01,89,12,57,FB,F0,60,AA,1E,35,5E,F4,49,50,E3,6C,58,8F,31,FE,18,E6,6C,7C,36,37,EC,15,14,09,26,9D,FF,08,EC,00,18,9D,27,10,84,B4,27,9D,FD,89,E9,46,D2,DA,2D,8A,5A,96,3C,7C,E1,C4,5F,01,6C,13,D7,90,2D,BB,76,4B,5E,C9,B2,F9,7E,B9,26,EC,55,06,9B,8D,EB,25,8E,A0,75,A5,B4,3E,EF,7F,13,4F,03,07,63,F9,FA,D8,3E,85,20,52,08,8A,26,93,1A,42,D6,03,A1,06,96,CB,89,E4,4E,A3,1C,C2,19,06,5F,8D,A6,16,45,01,9C,BD,36,C3,0F,E6,81,44,30,68,25,40,19,61,11,EF,9E,FE,97,B9,09,85,D8,89,F3,C9,0E,8B,4F,56,8C,86,4D,53,81,03,C7,4B,12,2C,EA,9C,23,F3,78,B7,33,4C,CB,97,F8,52,F2,0D,4E,9C,B6,11,D0,29,C7,2F,5E,3F,1F,27,49,3F,57,09,0A,FE,A7,51,C5,AF,07,62,12,6E,8E,9E,64,1E,73,C8,7D,4C,1D,14,26,D9,8A,1A,55,DB,42,8E,1E,23,10,56,E4,2A,E8,00,1C,0C,99,A7,7A,F8,F2,7C,36,9B,77,91,F3,C5,BF,E4,56,E8,D7,4E,AC,B6,2E,1C,3D,60,76,50,C3,B0,E1,B8,51,FE,5B,43,F2,2C,BD,E8,11,0E,F6,66,AC,6F,3B,2E,DE,9A,B2,D7,AB,F2,7B,C9,61,1D,3A,6B,9E,41,25,0F,50,87,F7,32,F4,A2,0F,61,FD,7F,70,71,64,87,2F,26,74,0D,D4,A8,EA,BA,37,FA,0D,CB,7F,68,1C,17,31,09,55,C0,B8,7F,15,47,DB,FC,24,28,21,28,EE,D9,9E,21,60,3D,2C,3C,E4,D0,6E,61,4B,85,55,EC,BC,C3,68,93,F6,8A,CA,5D,87,59,11,57,A3,4D,32,F0,C0,72,69,8A,7D,0D,A6,45,FA,3B,D5,2F,09,F7,3A,25,40,5B,B5,57,93,AB,19,97,F1,F3,A1,51,E6,A2,AA,AE,EF,0E,28,E7,20,7C,AE,AA,3C,A1,03,97,98,6D,72,5C,C8,3B,A4,5C,0E,D4,80,66,FC,3D,D8,DC,45,F2,2D,7B,5F,80,44,9F,2F,82,21,75,D0,D9,28,34,02,C2,35,F8,70,44,D0,38,CE,1E,2F,6A,B7,87,69,46,3C,85,D2,8A,98,AA,7D,7D,78,55,3E,3E,42,03,8C,A7,B1,AF,92,F6,29,03,D4,6F,98,9B,79,B7,ED,44,F7,E4,1C,9C,A6,E5,C9,0B,8C,2E,C8,C3,C2,EB,4D,83,3C,3B,9A,56,F6,8E,98,90,5A,F5,28,6A,9C,B3,48,07,46,D9,C9,79,C6,29,F2,4D,41,64,D2,81,6A,98,D3,E5,9F,3D,A8,FF,07,18,D3,CA,8C,1A,5C,31,DD,1B,82,BA,BF,6E,E6,E1,52,09,B5,6B,A0,8D,4C,18,95,FA,3E,87,06,4A,75,0A,1F,E7,39,CD,BD,2D,A7,BF,A7,24,4E,1E,94,62,CC,DF,C5,54,FE,94,3B,BE,5C,36,27,55,98,59,EC,B3,11,94,F6,EE,D1,F8,38,26,F4,97,85,A9,0D,6D,D3,85,C9,D3,24,55,3B,03,B7,40,68,F5,2E,64,D7,98,02,66,2F,94,EF,58,C3,9D,D7,37,62,A2,23,05,8B,41,BD,CF,3C,68,93,11,CE,5B,45,58,BC,76,C4,79,30,57,5A,D5,68,76,27,27,23,F0,FE,BD,A1,4A,9E,68,FF,41,FB,DA,41,09,18,B6,F7,07,3D,BA,81,9A,72,09,15,E7,AC,B1,E1,61,94,A3,4B,C3,E3,3E,96,68,39,1B,E0,41,C3,1B,E6,AF,67,9E,0F,3E,10,9A,36,21,94,69,E4,C9,58,2D,8D,D6,A1,85,CA,70,DC,2D,DD,0B,9C,FA,2E,CE,63,E2,92,04,5F,6F,C4,EA,2C,FB,9C,AE,2E,C9,66,3C,AD,2F,25,23,49,A0,D1,D0,D9,38,06,71,F4,0D,74,B0,32,46,20,69,2D,D1,9B,75,86,2F,D5,09,E9,FC,20,FE,FF,8F,AF,5C,48,14,3F,E9,77,94,FD,A9,BF,89,BB,40,24,FE,25,B0,2E,15,96,0B,1D,F9,64,9C,DA,E7,DE,E2,8C,24,D9,44,EA,E9,28,BD,44,91,37,13,67,14,A5,71,CF,A8,6A,6E,A6,7E,31,F6,96,82,41,BA,67,E1,EC,B2,55,3C,D2,E0,B7,67,A4,43,A1,5D,F1,D9,F8,C6,C5,90,BB,32,C7,2F,0F,CE,8A,C6,1B,6A,B6,9C,0C,E1,84,EA,E5,71,A6,3B,C7,D1,B5,0B,05,06,04,60,3E,DA,3F,75,37,04,14,4B,B7,15,42,FA,F1,4A,1E,F2,02,1C,BD,5A,91,7C,6B,CA,DE,D6,76,7F,17,D8,2B,3C,32,5A,1E,3E,C4,B9,E2,16,4A,57,D6,E6,03,4F,0C,CC,50,06,3B,FC,80,AD,A7,E3,23,6B,D0,68,B6,26,AB,6F,C6,48,69,D6,FB,E2,0C,63,C3,FE,E2,2D,86,F1,76,03,30,F6,65,DE,52,C4,53,31,64,12,85,76,6D,FC,35,FE,15,09,CD,0F,88,25,D9,54,3D,B3,40,9D,CA,F3,A2,55,12,33,A8,36,A8,D9,53,D0,97,2C,CE,05,39,67,62,90,F0,06,BB,F5,9F,A2,AA,70,7C,3B,3D,14,39,FC,18,A0,F7,9E,FF,D6,4E,90,F9,12,7F,A7,E3,59,6D,B4,8E,67,F1,D0,4D,E4,F7,C7,25,B7,F8,62,11,01,25,FC,32,34,EE,25,F1,3E,1E,A5,0B,FF,2D,D9,08,E7,08,9D,54,96,37,D6,B9,2B,D0,09,86,75,8C,55,59,19,E2,D7,52,3D,1A,22,06,B2,EA,10,9E,97,24,37,F6,6A,97,FA,CE,A2,BF,CA,04,89,6A,DB,56,CB,13,4F,6E,6B,DD,8E,EB,95,2D,44,25,C0,E9,E5,04,D5,07,E9,39,C6,84,A9,0A,A4,62,A2,14,8A,B0,2B,0E,0E,E3,9C,CE,89,5D,DB,84,28,98,61,C3,6A,A4,16,DE,51,40,F3,9B,31,2D,AE,13,AE,20,14,CF,9B,B7,DE,BE,23,D1,8B,23,32,C1,53,3C,AD,20,20,1F,AD,CA,1C,D0,5E,AF,F4,7D,92,BB,11,FF,9F,04,A8,F9,F1,4A,C3,F6,F5,3A,E2,9F,6D,E9,06,7B,36,10,9D,71,10,0C,9F,9B,0A,FE,59,F6,3C,A7,81,00,3C,26,34,FF,C1,CB,29,58,9D,97,9C,98,20,C3,16,43,06,43,68,2F,D5,C9,5F,1B,70,2F,DB,1E,1D,6C,0A,0A,29,94,B1,CC,54,E4,EA,34,11,BE,E1,F9,F9,74,36,C9,C2,BD,E0,A9,4A,71,98,46,77,38,C7,CC,4B,77,D6,54,E8,A3,DF,20,26,FE,7F,69,1F,D7,59,60,FD,A9,1E,0E,AB,4C,37,A3,12,C5,D4,2E,AA,03,EE,09,9C,7C,9F,DA,32,88,19,05,28,51,A7,B9,CA,B9,13,91,4B,8B,09,B1,67,30,60,52,14,92,4E,23,1D,01,C0,B8,C3,FF,77,45,45,F7,D6,C5,70,50,B9,90,63,8E,04,62,D8,D0,19,D0,D0,1E,83,4D,03,51,A1,61,6E,FE,12,7E,50,44,A6,AE,81,9C,8F,D7,F4,26,FB,18,7A,04,66,9F,8E,B0,E7,57,8D,1C,98,AA,7B,29,4B,CC,C0,80,6A,09,5D,C8,63,50,E3,B2,0F,20,E6,41,0A,D7,89,29,69,5D,E6,63,3B,D4,4D,37,2D,1E,F2,82,A4,D0,8F,9D,B0,60,18,01,58,9D,49,3C,9A,19,2F,62,35,26,8D,8E,2F,0E,C9,2D,CE,01,2E,B5,C3,A5,79,46,F7,FF,C4,4B,C9,A9,FA,64,1E,D6,AB,8B,16,DF,8F,E5,50,EF,63,9D,39,B6,1D,1A,E3,D0,7C,3A,FD,63,66,26,7E,DB,0D,7F,F8,96,21,4D,B1,EA,40,50,6E,29,53,46,D6,F8,D3,D9,DA,61,1C,C1,32,2C,C0,D8,2D,4E,B4,97,D4,84,31,24,1D,40,58,98,FA,79,64,65,B7,D0,6E,E0,D4,E4,14,FB,E4,1D,56,5F,3D,2A,D9,F4,3D,8C,6A,99,EA,A1,DE,41,3D,24,91,9E,BF,D0,63,75,E3,99,40,41,6A,2B,A5,96,49,61,13,AF,89,8D,9E,0D,A9,DB,7B,FC,3B,4E,60,97,98,60,5E,C8,F8,AB,3D,6D,82,1C,1F,BF,AD,6C,E2,8D,0B,E4,30,4E,69,6D,4D,0A,3A,D7,41,94,C3,2D,DB,D6,A3,D5,3A,70,E5,96,F1,32,D4,88,72,CC,2C,0B,F6,0D,B5,80,95,BB,9A,07,3B,7D,B5,F3,28,31,79,A4,55,78,C2,32,A3,AF,6B,E9,68,7C,99,4B,CD,DB,3E,BB,35,B1,66,2A,E5,1A,E3,C3,BA,06,21,B9,F7,AD,AC,63,27,21,EE,6F,5A,19,69,9D,7E,81,C5,9D,1D,FF,5A,0A,2C,BD,5B,1E,56,DF,97,07,3D,ED,FF,38,68,EC,BE,15,2E,86,0A,96,02,0A,9C,0C,FE,7A,F8,A4,D5,DA,D8,E6,2B,7D,0C,88,30,A9,DC,E9,4C,BA,46,82,72,DC,DE,C9,46,26,B4,F1,CA,BA,E4,3A,C4,B4,09,82,4F,4E,F1,28,E4,F4,FC,6C,C1,E8,B6,E7,18,8B,88,9D,58,04,02,87,CD,94,0B,07,BF,DC,62,3C,A7,77,DD,F1,C4,08,4F,7E,EF,49,2B,A3,03,16,55,2B,7B,4C,A0,26,E8,0E,E7,30,AA,60,76,E0,52,C3,B8,C2,A9,28,B4,C0,B4,3F,34,0D,D0,3D,C3,67,D4,4D,41,EC,AD,8C,E1,2A,E7,A4,AD,59,AD,9E,E4,E3,C6,28,C6,EB,12,58,2C,9A,21,45,E0,71,94,90,CB,94,73,08,59,F9,A5,2C,E9,76,B8,B5,C6,00,5B,4E,89,32,7B,3B,B1,D1,03,13,99,4A,72,EE,C3,E1,B6,28,8F,A3,FE,FE,C1,0A,15,CC,C3,E4,18,2B,7C,AD,D5,1E,87,71,BC,68,07,EE,0E,B8,BF,45,B6,DA,A6,92,69,81,B1,09,13,B2,93,65,FB,87,B0,92,36,DF,56,F0,88,52,9D,E5,84,26,90,62,A6,70,04,86,E2,5B,3C,EC,E0,98,EE,83,48,C7,B3,EF,9D,06,B5,85,A2,97,A9,A4,3A,45,8F,68,C5,C4,7B,23,A5,F9,69,6C,24,B6,89,B3,A8,70,DA,3E,0A,9C,51,03,11,19,54,68,F7,D0,E3,05,86,75,A5,91,EC,9F,B7,65,20,67,6D,22,70,9E,42,7E,96,A0,3E,80,52,0C,E6,75,A2,EF,58,79,70,58,0F,E0,67,AB,B5,E1,1C,BB,48,16,33,B4,B6,DF,38,3E,02,09,C3,DB,74,7F,D3,31,25,11,B7,0E,5E,DA,38,42,89,8A,CA,FE,02,6D,A9,C3,74,52,C4,4B,9F,A3,1B,F1,62,13,63,11,B1,69,FC,38,2A,60,21,87,98,80,3E,F1,47,6E,2D,37,A2,39,37,15,DE,E4,F3,48,38,A3,86,FC,4E,4C,D6,BC,82,0A,33,27,28,08,F6,F9,FE,2E,A4,E7,F1,E0,09,D1,74,BE,41,82,CC,64,0F,03,DF,3C,A1,01,67,6E,99,6D,F3,87,D2,E3,48,61,D7,30,4F,C8,47,A2,A0,67,01,D1,63,97,00,D6,19,22,74,49,FC,21,4B,55,BE,1A,5C,53,6D,D2,F1,DD,AA,34,0D,66,8D,BE,34,27,D3,E4,9A,50,C7,7D,A5,E9,C0,79,B4,C6,BD,9A,10,AA,D1,E8,B6,83,7E,07,62,19,1C,71,38,D6,0A,71,38,44,07,5A,01,C0,21,A6,56,26,FC,E4,A5,4A,EA,C9,71,57,85,9A,3A,6B,F0,D4,1B,96,24,35,0E,13,69,7C,AD,E4,8B,76,53,F5,3F,D5,FD,3E,EF,49,44,6C,CD,78,A5,42,EA,3B,BB,B6,9C,B2,1E,FF,82,3D,38,1B,62,B4,DF,EC,70,E6,C0,58,F1,D8,49,0D,2D,D0,DC,8E,0B,DC,DF,4A,49,99,FA,E0,2F,91,2B,D6,EA,99,4B,C6,C5,DB,82,4B,D4,30,36,CE,F5,F3,57,63,38,A0,4A,FA,DF,ED,96,97,3C,AA,8D,06,8A,74,24,5C,A8,3D,7D,92,45,F1,CC,AA,C5,8A,B8,23,53,5A,33,19,BC,69,08,20,11,6A,E7,3F,77,76,A4,BD,3F,7D,35,EC,22,FA,81,FE,F8,DF,0B,55,AC,7F,82,14,48,A3,B7,69,9A,33,B7,2F,8B,3D,B1,FA,EB,4E,89,01,32,62,F4,D2,CC,1E,64,6B,ED,A4,22,C9,CB,9A,8C,6B,9B,3B,EE,59,85,82,3C,37,F0,F2,A0,5E,E1,CC,7F,C2,23,38,92,90,78,81,B7,41,E6,54,12,AC,76,7E,C1,7F,7F,06,19,9D,F0,90,21,A9,BD,10,15,83,86,AE,F3,03,6C,42,BF,52,3B,04,82,CF,D5,F2,A4,9F,AE,B8,FD,C5,C8,59,BF,31,16,CB,9D,F5,C0,D3,17,C2,4C,2F,3C,C1,97,ED,0E,54,0A,73,6B,41,6C,F4,47,F1,21,C3,13,C8,53,D5,F6,75,BD,A2,9A,EE,D3,01,FB,0F,7D,D0,FB,01,95,73,CD,25,61,09,C1,57,25,59,1F,52,9A,D3,9C,B0,BF,A0,49,75,A2,70,AC,0E,18,1F,F8,18,38,57,0E,8B,45,03,FA,B5,18,EA,11,46,23,82,99,D2,45,92,EA,A2,1B,B7,CD,30,E7,18,AA,EF,F4,63,7F,66,89,D6,01,AA,B0,26,F3,D5,FA,0C,F2,8D,87,B4,9B,A0,3A,FE,57,59,10,DC,EF,1B,DD,C6,02,01,26,F4,0E,44,8C,13,16,DF,59,DE,F3,4A,6B,08,93,DD,D8,45,7A,D3,EA,B3,4B,17,7A,9C,A2,6B,BF,1B,5B,9F,36,73,E2,EF,94,61,21,47,AA,AE,7F,FB,D1,B4,98,34,86,EC,C4,3B,18,88,AF,3B,BB,27,80,90,8A,19,45,4E,71,60,B3,1F,46,6F,33,DA,A0,44,FD,5D,1D,0E,19,F6,E5,24,71,51,20,58,1E,5B,F3,69,33,75,3D,42,59,06,DA,10,7E,E7,5D,78,52,16,AF,5F,9A,0C,F5,78,8E,CC,9A,91,59,0E,4E,22,BE,36,45,0F,3F,E9,EB,B6,FE,0A,15,FB,00,22,6A,D4,A1,7D,4B,55,0C,FF,13,12,D5,EE,6F,4D,92,78,6F,16,45,DE,FC,02,9F,EA,C1,B9,BD,5C,D3,6B,E2,AF,CF,9B,D9,D2,DB,F8,D7,9F,55,95,4E,44,71,C0,2E,B6,7D,F4,58,DF,2C,B5,B9,25,9D,BA,09,18,36,61,1F,B4,87,14,FB,60,3A,9B,7E,55,00,F9,3F,3C,C6,44,29,6C,1F,0D,C6,96,EB,71,EB,56,BF,17,0A,B5,FE,A4,39,EF,B3,B8,3C,E3,53,91,81,C6,B7,15,5A,22,40,94,05,FF,B9,E5,AE,96,E6,16,CE,A3,53,6F,4A,83,13,D5,37,6E,78,4C,7D,DF,F2,96,21,FE,E7,F5,21,09,29,7E,31,B8,A6,29,16,6C,36,7E,4C,78,2F,76,6A,28,EE,3F,D4,76,E6,A0,95,21,6A,0B,15,8D,D3,50,83,40,7C,99,F6,6C,C9,BC,2F,94,E9,23,90,62,17,53,8F,9C,04,55,66,C6,4F,36,E7,CE,A7,1A,63,FD,9A,46,B3,27,9D,80,49,8B,29,10,0B,49,F3,67,3B,75,06,22,3D,F1,E7,F4,CC,75,C7,1D,5F,0F,E2,59,10,13,F9,27,80,B4,FB,FD,D7,BA,B8,AB,F5,B4,2B,0C,D3,C7,A7,28,37,30,18,AB,F8,93,18,C2,72,FF,A4,90,4F,A7,CC,11,EC,CF,BE,C3,CB,60,78,4E,5F,F0,A9,2D,63,B3,56,C1,69,2C,F7,A7,F7,57,CC,E5,29,7E,89,F2,BA,94,5C,67,C0,87,35,5E,91,F0,67,3A,06,23,27,B5,6F,B5,6E,65,72,2E,E7,BC,D7,F2,AE,B7,88,0C,BE,24,74,44,B9,52,2A,40,C1,F8,62,7A,F8,83,47,6A,50,3E,32,CA,A9,1C,7A,E7,DB,AD,55,E6,12,06,7F,C3,18,F4,77,92,DB,D1,D2,85,01,B5,9D,86,0F,70,50,1D,21,90,61,77,8F,FC,D0,57,2C,88,28,D0,A8,CC,2A,43,AC,70,4F,18,D6,96,27,8A,A8,70,5F,32,F0,A0,F8,0F,AE,5C,7F,45,A0,67,A4,C5,FE,57,19,3F,F2,3F,45,D6,E4,C8,A0,C2,FB,07,FC,DD,32,4D,BA,3C,C2,CF,31,C1,08,65,F5,4E,A1,54,E5,25,4A,5A,76,71,BC,08,47,B4,52,3B,82,19,9B,8F,94,4B,A2,9C,CA,CA,17,DF,C2,A3,1E,0C,83,4C,98,E4,F0,21,E0,0E,0F,8D,03,92,A5,4A,F6,31,2B,C1,A5,CF,12,2F,56,84,19,97,50,B2,90,4B,08,D3,98,F0,BD,85,87,DF,BA,C6,9F,83,E8,77,FA,12,98,8A,0A,BF,79,40,A9,BA,04,3F,A4,89,4B,9B,3C,23,F9,15,84,22,C8,DB,46,7A,D9,A7,6E,0C,DF,0E,9F,23,FF,96,F5,CC,9B,72,D5,39,20,91,AD,DC,72,C5,5E,EA,65,9C,DA,AB,77,C1,D6,E4,85,CA,F2,D6,0E,2A,0D,8E,DB,76,7E,93,3A,3D,F3,3F,99,FD,F3,A7,E0,00,44,53,79,21,77,27,6B,0E,60,3A,A2,51,CF,4F,87,E3,9F,CA,47,DA,13,B5,38,1B,F8,74,9F,66,E9,25,03,20,89,04,D4,99,6E,C3,56,B9,BD,BB,2F,59,BF,D1,3E,C9,08,35,EE,4A,77,35,E2,79,D2,78,EF,C5,55,18,44,6F,CD,47,F6,45,DF,11,56,D2,ED,F6,A4,7D,32,A3,E9,9B,CD,1C,92,6F,4D,19,D0,30,53,E4,F5,1E,B0,E4,8F,4B,EF,82,B9,FE,C2,20,2D,35,4A,A4,16,3F,D2,57,7D,7E,90,59,F4,27,D7,D5,AC,2C,C0,5C,C0,61,CE,7B,77,5F,F0,E4,0B,35,C6,FF,01,49,41,F1,B1,23,A7,0D,36,8B,AC,C5,BA,53,61,86,D3,C9,1F,68,B1,81,61,EB,56,7B,EF,EF,B9,1F,64,5D,9A,17,50,2B,34,B5,A8,D8,AF,05,49,70,9C,9A,81,CA,B4,77,0C,7C,84,A5,99,5D,7F,B0,E1,08,A7,19,25,C6,F0,E9,B4,6A,43,F7,7C,30,04,14,DD,4E,D5,90,1C,71,38,55,5F,A1,0A,E3,F1,1C,44,E4,1C,21,44,74,4A,06,73,71,99,E0,3A,28,86,14,3B,19,81,73,5C,B6,D5,26,79,E5,5D,75,36,E2,B7,2A,29,39,E6,08,66,68,3E,E7,B1,15,44,AE,E8,08,3F,8C,3B,6D,6F,E8,98,0F,93,BE,65,C7,50,87,FC,3E,86,47,43,C2,6B,57,01,F9,92,33,11,A3,16,F2,D9,0A,5C,F2,86,E6,41,8B,6F,67,68,3C,0A,15,C6,85,ED,01,D7,F3,E8,15,E2,36,89,81,29,F2,36,05,00,72,6B,65,64,7D,91,BE,44,4A,FA,13,BA,16,BC,61,46,FF,FA,72,E0,18,DF,AB,80,D6,19,9A,8F,D1,FC,F3,E4,96,FD,B2,F5,09,95,D2,A3,ED,6F,67,34,27,DC,0C,E0,85,DD,DD,75,41,DB,6D,8C,28,63,30,37,FD,BB,98,55,4F,30,47,17,0C,B1,46,5E,3E,02,02,EB,7E,22,D4,6E,D0,3A,96,A3,EF,A0,34,21,48,E6,D2,53,C7,37,19,FB,C8,2C,4F,67,3B,76,E8,4F,D3,9D,F9,FE,C3,F7,33,F4,F8,AB,A6,64,47,75,02,E9,AD,8D,9D,28,7B,79,D4,E8,82,15,E9,7E,E1,3C,FB,7D,DD,7D,D1,4C,96,CF,4E,71,6F,CE,86,FF,FD,D6,20,5B,4A,11,97,1B,1C,86,E2,AE,67,81,A2,B0,B0,C2,29,FD,41,68,D8,C9,A5,C1,64,D0,3F,ED,76,3F,59,F4,16,10,4B,A0,6D,CB,95,5A,53,68,E3,9F,8F,86,62,2A,28,C7,83,5B,F2,6D,9C,0D,5C,E2,0C,C5,6F,B8,FC,5B,E6,2A,8C,3E,14,9B,27,1A,4A,8B,FC,5B,5B,3E,E3,10,2F,B0,D9,76,9E,E3,DE,E3,AF,0F,39,0D,1F,B8,8D,7B,86,60,5C,B4,91,0B,38,5C,DA,D4,5E,C9,BA,EE,44,39,AE,A9,A1,BD,35,77,1F,8B,03,07,A3,37,0F,8E,FA,5D,CE,0B,BF,52,75,6F,74,BB,51,44,57,93,36,67,E5,17,72,09,E0,15,6F,C3,3C,4B,4D,1E,EB,2D,F9,56,7F,94,D3,71,4E,FF,91,53,27,BC,F0,52,5D,17,A0,C4,6E,F5,E7,9B,27,F8,27,68,5C,B8,14,63,DB,70,F7,1B,90,D4,C6,76,07,71,F2,70,F7,0F,D5,32,2C,1C,94,DD,77,F7,96,DF,F4,AB,7C,0F,00,BD,E8,F9,6D,A8,42,33,04,6A,2D,FE,F3,A1,A2,55,96,51,43,11,EB,4F,C0,31,06,BA,8C,C1,DF,64,87,72,D7,98,6F,55,63,0A,4A,9B,79,C1,9A,7E,E7,EF,49,6B,67,E7,86,6F,6D,42,CD,79,D4,CA,18,5C,3E,C3,71,11,FE,25,6B,FA,48,61,1E,A6,45,FA,25,34,BE,8C,42,95,6B,34,0D,CA,53,8F,55,56,60,C4,C8,09,4C,25,6B,AA,45,F6,71,CA,B3,61,09,87,B9,EB,D1,AD,18,E5,E9,BA,D8,D7,CD,18,A4,BE,C3,7A,35,1E,03,DB,BF,79,1E,90,56,C6,19,22,D8,46,CC,28,D5,8A,3D,35,92,AF,F1,53,BF,78,88,68,5A,3C,14,9D,23,3F,DD,C2,CF,B9,E1,9B,52,02,E8,2F,F1,F3,BE,C3,12,B2,60,EF,67,F6,3C,E7,5A,D3,14,E7,A5,83,E8,B4,DA,D4,D0,AA,91,BD,1E,50,F9,AA,22,41,2F,AA,5E,AC,7E,15,72,D4,74,30,F9,D2,54,E3,80,07,58,D1,90,12,D4,62,B9,B8,4C,22,55,89,89,E7,3F,1E,86,85,8D,CE,E9,FA,D8,B8,19,98,66,BE,FB,52,69,BD,C2,5C,23,8C,02,7B,8B,44,BD,1E,95,58,87,36,A4,78,FC,94,37,AB,7C,50,C5,C0,A3,C3,41,70,3B,D7,A4,4B,8D,74,6A,7A,C5,BE,4B,87,58,A2,4A,FC,E2,7F,73,A7,33,F3,9B,33,7F,FF,1A,D5,8D,8B,F5,4C,6A,5D,55,5C,A8,B4,C6,2B,7C,A4,65,00,38,58,0A,65,F5,80,04,B5,5A,92,47,83,66,06,63,D4,6D,D7,D3,96,29,90,37,48,CC,E8,3C,AA,80,3B,37,46,F2,A0,26,E8,E5,E4,98,66,57,7E,2F,07,28,EA,C1,74,8F,BD,CC,43,C0,0A,3B,AB,9B,0A,97,D0,B6,2C,95,31,C0,2E,68,DA,D7,38,70,80,2D,67,7A,EB,33,AC,89,89,F7,19,22,3D,99,DE,1B,16,76,C9,B1,4D,67,A0,3D,14,AC,5F,80,A6,25,4C,65,8F,92,87,4C,85,E3,E5,BA,C7,8E,7A,45,8A,DF,AE,E8,30,55,05,66,55,02,62,85,A0,B8,41,DB,14,7C,57,E5,1D,DB,93,58,95,90,3F,DD,EF,81,16,B3,F5,F0,2E,3E,25,F8,12,C3,6E,FA,75,1E,D1,B0,1F,48,08,5B,57,BE,33,89,88,E2,5D,08,0F,0D,20,08,49,06,1C,51,5F,D9,FD,CA,DD,01,D0,D2,55,8E,10,17,78,DE,A6,89,0B,34,F4,86,97,DF,01,2D,4B,EB,97,BE,07,C7,02,D3,3E,F5,47,CE,9A,74,D3,F0,8D,05,7E,DE,5A,C0,C5,8A,37,4A,D9,BF,06,B5,80,6A,F6,4D,09,0F,80,AF,BB,D5,B1,C5,C2,1F,B0,27,A0,12,E5,13,F5,A6,DB,64,3B,1B,A5,7F,65,9D,5C,36,A6,2C,BA,32,DB,14,1D,1B,61,F6,5A,60,09,90,91,EB,0D,08,78,C2,E4,7F,86,A2,DC,BB,76,48,1F,FB,C8,F2,26,7C,2D,02,93,20,78,E4,3B,A8,FD,7E,D8,3F,9E,B9,1C,74,8A,C6,28,02,0D,CB,76,AB,D5,02,EA,10,BF,FC,F1,3A,FB,3B,4F,88,47,98,E7,34,C3,6A,E8,E4,C0,69,2B,FA,40,A7,AA,EC,5F,51,97,2D,DC,1E,A5,60,50,13,1A,1D,9E,17,A9,BA,9A,CA,42,EA,E5,B5,8F,4E,EE,88,E5,71,75,8F,88,21,C1,9D,9C,FA,EB,D1,05,45,32,DC,65,0D,FE,59,26,DF,B0,05,37,11,50,62,A6,47,D6,A4,6C,C4,C1,3B,00,81,74,3B,C7,1C,F6,56,88,CE,00,D6,AD,0F,A8,04,63,2A,29,D4,E6,32,A7,F7,A3,2A,0A,E0,48,22,04,AE,B0,0A,57,F6,1E,67,3C,23,1B,D5,2B,BB,EA,F0,75,02,E8,6E,03,0D,9B,D0,1D,88,23,17,66,79,D0,75,2C,6C,F1,38,11,31,88,85,DD,19,2C,89,DB,36,14,F0,FC,DF,6A,9F,12,09,84,2A,F0,F5,DE,C3,8D,9F,E1,7B,07,EB,EE,8E,82,C1,D3,AB,75,02,03,17,83,05,5F,38,1E,E0,2D,04,E1,FA,9F,31,F7,0C,37,84,B4,9D,AB,78,83,03,E0,53,28,72,15,99,91,3D,8C,65,B1,5B,B5,B0,8D,B1,AE,07,13,FE,C6,ED,97,8B,C9,1D,49,F4,C7,51,42,19,BE,C8,D8,81,EF,97,BA,03,01,93,6C,8C,57,A5,69,76,C7,B9,86,1C,9D,C4,5E,46,08,28,7D,4C,5E,3D,1A,F3,39,78,F9,D7,9A,69,E2,84,27,93,A2,1F,62,3F,93,94,FB,8C,A4,0F,0E,3A,7D,3F,70,4F,CA,30,5B,6F,EE,86,13,12,7E,4A,3A,EA,43,5F,30,A0,BC,D7,3C,4B,60,AD,75,E2,DA,BB,8E,F8,54,BE,9F,B8,B6,23,CE,2E,66,E8,F1,34,13,4B,75,80,1C,CA,72,C1,9E,94,44,84,90,86,8A,C5,00,C6,D4,E8,83,65,31,DD,29,F0,03,63,63,7E,11,7E,02,7D,53,9D,DE,1C,EE,30,FC,D3,34,9D,B1,02,2B,6E,9A,9F,26,6B,C3,B9,4C,31,98,7A,9E,7A,8F,F1,CC,4E,56,92,4E,A3,EE,7F,75,8D,6D,E0,00,58,9C,10,7E,B6,D4,95,3C,A3,E6,AD,03,C3,45,33,8C,DB,EC,0D,A5,2E,E3,B0,22,2C,97,CC,69,DE,64,D3,2E,FB,D2,FF,16,67,24,5A,2C,6E,76,7A,AF,DA,75,19,8D,A2,FD,50,FF,F8,61,3A,F9,A1,81,9F,71,02,8B,51,BA,9C,83,25,73,BC,BE,EC,91,7F,00,EB,6D,1A,3E,01,07,6F,76,4F,49,21,A0,4B,F9,72,9D,A3,9A,1E,82,44,3D,48,A2,F8,FB,F4,9A,85,EB,CD,66,C6,AF,99,96,83,9F,03,33,81,78,03,46,F1,F6,6A,6F,94,33,3A,83,8C,19,E1,C1,16,79,18,0D,78,89,B8,5B,AB,A9,BC,E5,DA,76,76,CE,B4,C7,12,D8,79,D0,F3,E5,13,53,BA,B9,75,CA,16,1E,07,C2,2B,1A,DC,9C,6A,F2,F6,AA,CF,29,7F,E1,C4,10,D3,0B,BF,38,75,75,F2,45,1D,C7,D7,72,E8,E0,89,F9,38,F2,77,90,50,C5,54,79,36,97,BB,CA,11,29,BF,2A,2F,37,A7,12,BC,CE,B8,C6,BB,08,6B,58,26,4A,4A,A2,E0,B7,BF,E9,1E,B1,94,0D,BF,7B,3E,9A,1C,FB,22,DD,A9,99,59,70,2C,48,E8,59,1D,06,7B,47,F4,14,9C,EB,97,2B,21,08,7A,AE,CF,4E,4C,B7,4D,59,31,59,AE,D2,ED,30,38,8F,60,E0,DC,C7,4C,16,1E,B1,57,59,D5,4B,DC,37,98,6C,A9,21,40,B4,20,92,69,3F,81,85,51,12,8D,85,83,D6,22,41,44,33,30,B2,9D,E1,86,86,55,49,0A,75,41,DB,98,E1,6B,F6,10,A9,67,B2,2D,CA,3B,7E,7C,35,69,3E,F7,36,25,D3,87,FC,88,5A,F9,EA,54,75,B0,71,95,80,4B,33,8C,7E,18,80,E5,B8,36,1F,7F,96,58,22,55,1D,0B,5A,11,99,0B,3D,5D,EB,54,E6,E2,9A,C8,1E,53,6B,76,D8,48,94,9B,5D,E3,8F,F4,36,04,73,AC,27,B2,9A,4A,24,10,FF,93,E0,E4,76,35,EF,32,BA,56,84,5F,EE,61,60,6D,1B,3D,12,BA,0C,C7,20,F8,55,28,15,75,D0,8B,6A,9C,76,80,D5,0A,E6,24,22,FF,DE,DC,5C,B9,25,9D,7B,3A,34,28,06,3A,95,11,95,0A,0E,35,C2,04,2A,3A,3E,13,A2,89,EE,DE,BD,1E,FE,15,A1,71,74,02,30,75,6F,80,18,ED,55,E9,6A,7A,06,50,26,E2,5F,2C,31,57,BB,54,0D,DA,DD,8D,C8,D7,82,F9,BB,CF,F2,9E,A4,3B,2D,E2,DB,C4,77,FE,29,99,E5,9A,F6,D3,E0,BC,04,19,24,19,1B,46,5D,DD,E4,39,AB,7A,E1,1D,7F,6E,1E,3A,71,5F,12,3B,8C,AB,92,2C,51,D6,69,D8,B2,4B,AB,6D,AE,4A,0E,3B,7D,D3,A3,E0,9C,B6,ED,26,2B,2F,B3,3C,9B,18,3A,78,F5,26,94,15,FA,B6,05,F1,9C,B0,5E,1C,96,30,6A,CD,F4,BA,42,3B,50,0D,C1,F2,D8,BA,B1,66,E5,CC,70,D0,E5,5B,05,5E,A9,BC,A2,8C,38,1D,E1,6C,86,AC,3D,A7,A9,5B,4E,CE,2E,1A,5F,31,2E,F6,BF,3D,12,CA,19,13,89,B8,DC,9C,34,D8,E9,9D,85,89,A2,2F,0C,93,41,35,9B,8F,0A,29,A4,E0,40,03,31,C5,1B,5E,E7,3D,FE,62,04,14,36,0A,42,BA,B1,3A,19,2F,E3,19,27,BC,15,5A,30,72,79,E5,2B,EE,63,81,EC,1A,EE,0A,B9,99,B0,62,39,1D,1B,43,2F,25,94,CE,79,68,0E,F2,07,F8,05,BF,8A,1D,DB,F3,3F,69,5C,82,05,59,16,61,68,FC,75,75,13,F4,ED,00,E8,FD,82,2D,E1,94,8D,9B,CD,83,DC,B1,AF,FA,5C,C6,3B,3F,8D,E8,64,EA,8E,8D,1F,3C,4E,18,B4,A0,41,6B,37,5B,B2,27,C4,C2,CB,5F,31,85,0D,F3,97,BF,C1,82,83,88,7D,54,1D,DF,C8,BE,0C,18,92,5D,D2,F6,96,9A,AA,53,6A,DB,96,47,EC,C9,FD,2B,A1,55,FA,43,B1,8A,42,B9,01,BF,AA,4C,F7,48,B5,44,48,5E,BB,AA,8A,97,CA,42,55,F3,4E,98,74,99,22,BE,C4,4B,A5,47,F3,EB,3B,8B,02,C3,3B,C0,FD,44,27,89,72,3E,60,8E,64,B6,F8,2D,E3,3E,62,2D,6E,96,6B,CE,12,D2,92,B8,C8,AA,3D,6E,7A,58,B1,44,92,34,83,43,D8,32,EF,30,9F,EA,B5,3B,B7,04,E6,E0,CF,11,ED,CC,B2,E1,4E,CF,DD,BB,2D,2B,4A,53,87,7C,FD,AB,E1,EF,30,94,07,CB,29,6D,57,70,1D,49,AC,73,03,DD,4E,1F,E3,DE,34,48,41,4C,37,41,40,0D,09,2B,5F,66,65,40,B8,D3,86,F7,36,D1,B6,27,D6,FC,1E,49,97,DC,26,55,B4,B6,55,FD,90,CE,28,BA,FF,8C,EF,0C,00,23,CB,34,D5,32,2C,53,0E,4B,20,C8,5A,70,29,DB,72,3F,07,8E,0B,6E,2D,0A,B9,7B,C0,CE,D6,C4,0C,C6,C0,C3,12,E7,4C,40,F6,03,EE,AF,69,FF,98,BB,23,23,8F,65,70,82,C4,C1,E6,CD,8C,C6,40,EF,F9,B6,AB,80,68,C6,64,F3,A5,6A,9D,AE,62,6D,55,13,1D,28,17,1B,83,BD,E9,96,EE,26,EA,35,69,C0,B9,B4,9A,E7,2A,6F,FC,BD,EC,7B,44,33,25,A7,37,AE,02,EC,B6,D5,05,47,44,9F,15,C4,CF,4C,0F,33,43,9E,5C,A9,3F,2D,C6,68,F8,56,A7,B9,ED,CC,D6,E9,3B,82,F7,3F,C1,08,2A,FF,C5,3E,04,A2,C6,63,EA,1B,54,4B,87,BC,A6,25,54,72,57,5E,DA,F2,65,A3,3F,B6,AA,3B,DA,AC,F4,C5,2F,B9,57,22,ED,02,DA,2D,DB,3D,26,C2,BD,F1,2B,E7,88,64,81,CA,54,0D,76,9A,51,9E,8D,5C,C0,33,30,87,FE,DA,78,E4,B2,E2,39,09,E0,7A,C3,F0,24,93,03,25,4C,46,5E,68,8D,38,D4,E8,55,39,6C,86,61,ED,36,89,15,E0,01,A1,C1,A6,B5,12,A3,85,4C,87,8C,A1,8D,41,BD,B9,B4,F9,4F,AD,DD,E0,DE,9E,E0,B0,A6,26,1A,07,4F,62,A4,BC,66,CF,79,C4,AB,F0,3A,B3,51,4C,97,BC,3F,5A,FD,92,45,C2,96,29,BE,AB,9C,56,A1,E8,83,02,31,13,5A,42,D9,08,35,96,F7,8A,B5,07,8B,D5,BF,63,45,87,6B,7E,6A,82,BD,48,73,E8,E8,10,25,ED,C3,D3,33,A1,56,84,30,3D,70,A7,B5,8A,E4,46,B3,5A,16,08,31,EE,D5,34,29,B0,C7,EE,2A,6F,AC,F4,CD,99,5F,12,08,40,C2,61,D7,0A,CC,7D,99,99,29,49,43,F4,E9,9C,E4,3B,3D,6E,3B,1A,D7,A3,C5,B3,E5,B4,EF,0B,2F,26,0D,F0,1D,2E,A4,DD,18,30,10,FD,DF,53,56,95,DD,75,01,64,D3,9D,C5,47,35,BB,C6,A5,76,BB,9B,3E,F3,70,55,49,D5,92,82,E5,46,94,87,69,5C,86,4D,FE,17,A4,0A,23,CC,30,45,B7,2E,13,50,58,1E,BE,EC,DE,5C,3D,31,C4,FB,B7,26,BE,CA,EC,9C,01,31,DE,FC,DD,C5,9F,DB,71,9E,5E,DF,E8,65,1C,A1,0E,34,E0,90,F1,F3,61,40,E3,4A,28,3E,2B,75,A2,2C,55,B8,70,25,CF,C5,7D,B4,0F,78,DB,66,61,F9,30,C7,2F,1E,9F,1F,A8,4F,D8,59,B5,64,C3,2C,E3,C6,4A,33,7C,3F,16,DE,10,67,34,9A,C7,93,08,13,D6,56,04,9B,68,63,78,9D,B1,F2,C9,7F,6E,94,11,A6,11,4E,01,07,ED,68,C4,1B,A9,F5,75,DC,BD,65,09,46,E2,24,FD,82,F6,23,78,DA,46,F8,70,A6,2E,4C,34,C4,61,56,E3,EC,73,C6,7D,63,25,32,06,B6,03,F7,46,AB,35,DA,A5,B0,12,91,05,E7,22,97,D5,0C,5B,6D,12,EF,C7,E4,A3,DA,46,1B,49,94,CA,FE,47,2F,84,48,4D,28,60,62,BD,89,EF,B8,0A,BC,1C,40,29,21,E6,DB,CA,C7,AC,5C,E1,E8,A1,71,D6,92,42,1C,1F,92,3A,A4,F2,1C,EF,7F,B3,03,72,99,0B,36,37,31,B8,84,D3,58,A3,25,94,18,E9,48,23,83,76,40,61,82,78,D6,31,86,52,D0,74,F3,82,59,FE,26,B1,9A,D6,69,FA,91,EE,9C,C9,3E,EA,BC,90,79,55,BB,27,24,F4,12,BD,59,70,47,BF,05,A0,46,D2,6E,2D,63,62,DB,77,F8,2D,2E,B6,F2,EC,14,E3,47,65,A0,E4,80,53,1E,A0,74,2E,17,A7,49,0C,FF,7A,82,7A,43,24,F2,75,0F,A9,97,5D,57,BF,B8,B0,0A,67,8E,B8,C0,61,01,AD,1E,A3,E9,67,02,EF,3F,E1,6A,5F,61,0F,92,61,93,28,FF,65,B0,5C,9D,8C,CA,73,BE,00,DB,CC,FF,73,7F,F6,F1,40,59,39,DD,F0,90,E4,D8,54,9B,F3,3C,D0,0D,81,3A,61,2B,FB,0D,89,F1,FA,67,18,AF,9E,73,A0,A5,AF,FF,F5,0B,3F,53,99,CD,0B,0E,12,11,2C,F8,E8,41,C7,A1,76,D6,0E,3A,D1,55,26,00,06,80,04,BC,07,4F,B3,EE,0C,3C,D4,B2,91,EE,D4,D2,AC,42,74,99,18,CF,1C,09,AE,CA,F5,89,FB,1E,A1,0C,45,B2,E7,C3,36,EB,D4,EF,D3,0E,D4,82,AE,2B,41,2B,1E,17,36,BF,2B,76,63,DC,27,74,AF,61,F3,75,AA,09,9E,F1,15,AB,25,2C,77,AB,62,3C,8B,F7,1B,F7,EF,BC,B9,6E,1A,0F,DD,48,76,C2,A2,D1,7E,97,AF,7F,2F,BC,80,44,79,8B,7C,01,F4,67,B4,CA,C0,3D,15,20,04,A3,76,D1,25,2C,FF,41,E2,E8,01,F3,C5,37,20,3D,0D,4A,07,B7,EB,33,92,84,1A,58,C3,C4,B9,28,3A,A6,3F,5A,7E,64,93,4F,F0,55,9C,4F,D2,60,87,10,01,A1,F4,46,8A,6D,7C,B9,3E,5F,5D,CA,2E,FA,99,80,C0,A3,EE,39,14,46,EA,F1,53,54,BB,56,D1,39,2B,9B,4A,2C,89,E5,FE,46,0E,C7,67,94,92,38,08,19,57,CA,12,CF,14,C1,2C,C8,D3,02,57,EA,CD,BC,B8,2C,E3,25,FB,BE,A6,3D,A9,2E,3D,CC,D4,02,EF,7E,BE,A6,CB,C6,04,D9,59,38,A5,96,9C,A6,E3,13,29,17,CA,5E,40,4A,85,3A,D4,12,F4,5B,2C,64,78,F6,D5,70,50,DA,34,9C,13,A8,5D,30,EA,A2,52,DE,D4,F1,6F,95,FA,69,3B,67,2C,41,EA,9C,6B,F5,B2,D2,B1,2A,19,3B,0E,52,C9,81,0D,23,19,6B,08,FA,94,67,EF,A1,1F,C4,71,AA,7A,1C,C2,85,1C,F8,41,0B,A5,92,D9,0D,C4,7D,25,65,A9,5A,2C,10,76,5D,2A,1C,FF,7E,0F,AF,1C,8E,33,13,9F,DD,06,56,A5,04,FC,6B,4D,B1,88,AF,A8,88,75,BC,1F,EB,BD,97,8F,5B,D8,EC,BD,57,C7,67,00,1C,2B,CD,A7,A1,E1,08,5F,F9,14,17,27,33,8A,55,E9,B1,4D,D9,8F,AA,24,2D,21,F5,E6,AD,66,0D,E6,84,AC,33,AF,13,07,42,91,93,12,29,6B,AC,38,78,EE,DD,2E,2A,1B,D8,1E,84,DC,70,7D,7B,1A,04,34,68,68,BC,A5,A1,CB,3B,8F,EE,AF,A0,F9,46,1E,1A,E8,AE,3D,C4,0F,1B,7A,D0,7F,12,13,8A,E0,1B,AF,0E,47,D5,6B,57,A3,9A,F7,84,1F,B7,3F,9C,98,F7,C4,1E,88,D6,EA,A6,86,99,E3,51,3F,46,89,F6,FD,28,76,19,44,3E,E2,AB,CE,CA,DF,AF,45,1D,52,6B,2D,77,60,6E,F5,B8,5B,68,69,CB,18,3F,8A,07,E2,7F,53,22,E0,D3,5B,A6,C7,43,B0,A2,38,D5,97,00,C6,2F,50,7C,84,B7,99,DC,78,0E,0E,29,F7,AE,1E,53,0B,C2,D3,CB,BE,3D,2A,8A,61,43,CE,4F,79,98,3F,AF,0C,73,5C,E8,51,5B,01,BF,60,98,58,E0,12,05,F7,A6,1C,36,C3,0D,8F,09,74,03,4D,4A,5C,15,18,3A,33,37,EF,91,C3,EB,12,39,C1,80,82,63,89,DC,B7,56,48,CB,72,9B,32,68,1C,BB,1A,DA,A3,56,F7,BF,CF,38,1E,C1,DB,95,D3,78,7D,2B,2A,FA,D3,CE,0F,D6,74,4E,23,53,C5,F2,D7,15,4A,4F,F2,B9,10,88,AE,BE,5D,7C,00,93,3F,DA,5C,D3,3F,FF,49,B8,AB,2E,A0,20,5D,3D,3C,67,12,10,A1,CE,17,6F,7C,CB,D2,4A,C4,49,C0,29,BA,D5,FD,4E,A2,F7,29,9B,AE,AD,6F,15,EC,1C,D0,CC,1A,B9,A7,21,91,43,B0,11,24,3D,1C,2D,4B,BD,E7,FE,58,42,09,4C,1A,17,A1,4C,8D,96,02,10,F8,89,92,76,9B,61,7D,6D,64,37,68,0F,44,E5,CF,6D,34,50,53,61,D7,51,1D,68,5F,9A,43,FA,C5,DA,68,16,42,3E,22,E9,27,51,95,8C,27,77,FF,2D,FB,C3,E7,76,58,8F,56,92,0C,37,B9,33,18,07,A5,1F,56,09,73,16,E8,56,F5,AC,27,E7,C7,ED,87,09,73,81,9B,8C,C8,7C,D1,02,C9,33,9A,7E,72,69,18,AC,D5,99,C6,60,A9,24,F1,CF,52,B0,8B,7B,31,CA,BC,4B,5F,AB,9B,DA,FC,8F,E1,7C,A9,08,0C,72,85,EB,61,98,95,9B,94,06,D7,5F,04,88,FE,96,BE,16,4C,E1,63,80,F6,57,F7,D4,84,12,19,F8,97,B9,8E,71,C5,DA,56,90,33,CB,1C,15,80,D9,01,91,48,C2,AB,F7,2F,3C,AE,AA,00,96,F1,97,71,C2,35,3D,D8,F7,EB,0B,6A,09,B2,CC,C9,9A,7A,7A,BE,13,19,19,6D,67,47,5B,96,69,10,AB,80,25,53,E9,95,D2,7D,E6,77,D7,E6,D7,AD,A7,EE,77,AC,E0,EB,05,15,66,E1,6D,F7,31,53,C4,E3,DC,E0,74,D3,30,29,5F,4E,97,9D,16,4F,2E,CF,CE,63,9F,E3,57,C4,AE,6C,CF,54,4D,6D,23,EE,EE,4D,EA,B0,A2,E4,4C,2A,D6,27,ED,53,6E,19,C8,64,2E,0E,2A,1A,ED,B2,1F,07,99,A0,3C,02,37,ED,C3,C0,6F,B8,52,3C,1A,36,F6,D9,DA,00,FF,7E,D5,07,71,B2,37,A9,7E,B3,E1,B2,1B,BA,99,23,1A,EF,92,74,7E,27,83,BB,4A,9F,DB,97,7E,8F,33,4A,56,7B,2A,2F,CF,0A,4C,6C,A5,19,F5,C2,96,16,27,87,33,2E,EA,C9,8B,05,BD,DE,C3,C9,84,83,B2,D6,B5,29,5F,07,07,51,ED,77,6F,E7,24,22,23,4F,ED,50,14,62,2B,6D,65,A2,F7,4E,8F,DB,52,34,7F,18,BC,5E,5C,0B,C9,5D,FA,BE,08,BF,D5,AD,33,B6,A6,59,6F,C7,EF,44,ED,F1,23,1E,8C,A4,5D,9D,18,5D,64,36,2C,39,F3,88,8F,92,50,12,1F,92,29,74,E3,F0,69,57,EB,5A,E5,0A,94,FC,F2,00,54,E2,B7,80,06,E2,8F,AD,1E,3E,25,B5,7E,2B,33,7B,C0,54,20,33,0D,86,E9,58,BC,40,5C,E7,08,B1,4E,55,E8,1A,60,E5,13,B2,1E,18,82,B0,EE,0E,A4,51,9F,E1,C0,17,5E,D4,25,ED,87,2C,50,E0,EE,BE,7C,88,C3,07,2D,51,AF,F9,EB,2B,F3,D4,88,D7,B2,23,09,17,07,6C,F1,7B,08,BA,C6,17,81,DE,F6,7A,C3,19,15,DD,A6,93,9A,D1,CA,55,77,5C,98,C5,45,BC,10,A7,64,3E,FB,D4,F5,9B,D3,FF,E1,93,62,35,82,CF,5C,72,C4,F4,BE,7C,5F,28,64,29,8B,4C,F1,8E,27,3D,DC,06,FD,6A,B2,A0,9D,BA,FC,20,83,0A,90,AC,14,01,A1,68,AE,C5,E2,43,75,B8,41,5E,43,3D,90,B3,47,E2,3E,DF,DA,D6,33,DD,DE,32,08,18,86,EF,85,19,C6,EC,F9,1F,49,03,AB,FD,C7,B7,44,88,42,86,00,FB,65,37,6A,1E,75,A2,83,C2,1C,E7,86,E9,93,57,9F,84,8B,85,94,F6,0F,DA,7D,9B,0B,AC,00,5F,33,56,C6,B8,21,E1,5E,EB,0B,54,1D,4C,DE,C1,6D,0A,7D,B6,CF,BF,27,47,9B,E5,B9,27,6F,06,F0,A6,F7,25,65,A9,48,9A,98,20,1C,3D,0B,8B,2D,B6,06,4A,76,AD,51,D8,04,5F,6C,2A,DF,54,78,BF,38,AD,EF,5E,6C,A1,D1,1A,C4,FC,0A,4A,17,1F,AE,15,1A,C7,F2,AD,3C,30,64,65,9C,FF,F7,C8,DC,BD,FF,0B,AA,EA,41,39,C3,F6,BD,7F,54,54,FC,0C,F6,6F,8C,F1,C0,71,7A,22,A9,6E,7E,40,25,60,DC,85,55,94,45,19,B8,04,29,1C,07,69,37,4F,65,91,23,44,ED,F0,66,53,34,14,C5,73,A0,08,CA,03,74,BB,3D,F2,1D,82,22,DF,0A,1F,65,14,3F,A3,1C,98,BD,7C,05,68,44,CA,AF,65,19,A2,7D,1E,D7,1F,2C,FE,1B,7F,D5,E1,79,29,3A,BF,22,A6,8C,90,4D,52,0A,79,A3,FB,2A,71,90,7E,33,2D,6A,98,E6,37,35,BC,8E,4B,C7,ED,6B,D4,91,8C,DB,5E,46,D3,01,C7,0A,B9,F6,60,AA,08,3B,6D,C3,8B,D1,5E,FF,D1,3B,A6,4E,78,66,EA,D2,AC,8C,9E,7F,22,9E,6A,86,E0,B4,9C,6F,4A,8C,0D,CC,C6,1F,88,47,62,93,A8,EE,E8,FB,EE,3A,A9,02,24,3D,04,73,72,73,1F,9A,A0,DF,82,72,B8,1E,0F,2D,54,2A,5D,6D,E0,A9,91,FE,BA,E2,1A,98,7C,A7,68,E0,36,6C,9B,59,37,36,53,1E,A2,DE,F7,1B,44,E2,79,4F,27,84,02,64,57,67,21,86,68,2C,4F,10,FF,A6,D4,25,99,3E,5E,EB,3C,1F,DE,40,90,F6,26,10,31,15,20,C9,AD,8B,7E,80,AA,A6,34,47,2A,8E,AE,0A,86,F4,B5,56,70,F6,EE,74,DB,46,FA,47,BE,78,9D,B2,02,2A,C9,49,EB,93,0B,C1,03,0A,E4,0A,29,22,34,F5,C3,02,E0,55,73,8B,E8,8D,D0,D5,B8,A9,22,A3,1E,65,70,4D,81,AF,93,F9,5D,A9,F8,54,F8,9D,5D,3C,FB,55,70,0A,D8,28,D3,4D,21,C8,0D,4C,8C,5A,BB,26,7A,EE,2E,51,BC,E1,65,BE,14,11,35,3D,4D,E0,7E,C7,6A,D6,F4,65,CF,E4,15,5D,E7,E0,BF,E8,D8,0E,DE,C0,E1,7A,15,9E,0A,B8,E4,FF,76,D8,54,79,12,0B,63,CF,59,BA,31,88,92,87,43,17,24,60,0B,A6,70,F7,FD,80,3B,E2,E3,9F,CE,85,4E,76,1B,7E,0C,F0,40,69,DC,81,3A,AC,34,CF,D7,21,56,A0,3A,0F,26,E7,17,FB,70,49,B1,9F,1B,57,EC,FF,F6,61,26,AD,84,50,77,13,D9,8C,11,CB,DE,F0,52,6B,19,9E,9F,52,09,65,25,02,35,72,A5,21,2A,B3,83,D1,4F,74,49,D9,23,48,90,BF,07,0F,19,41,50,4C,8D,B1,18,FF,FF,10,3B,3B,10,FC,21,D8,78,52,1A,54,15,CF,FD,DE,0C,60,EC,DB,84,C0,4E,2F,56,1B,83,2E,CF,60,66,CF,AC,1B,41,2E,DA,5A,B8,A6,EB,12,0A,AF,89,1E,9F,20,C0,C0,70,62,16,08,E4,B7,B7,7B,D7,8B,AE,01,0A,AE,D5,D9,1A,67,44,BB,53,79,C9,2D,D9,B1,20,2B,85,99,37,69,51,D3,43,B2,08,10,50,1D,8B,25,87,EF,92,41,E6,A4,5F,E3,D8,B5,44,91,45,1E,F8,7F,A8,AB,29,6B,3F,64,10,07,0D,15,F5,78,3C,2E,FC,96,60,42,7A,76,58,16,20,02,38,1B,AE,9F,58,BF,3C,BA,46,03,DD,86,83,CB,01,23,3F,33,15,09,95,2D,7A,B7,61,DB,25,91,FE,4D,1C,5E,DD,01,D6,EB,16,19,2A,3B,F5,EC,7E,04,1D,37,3A,40,BC,B1,BD,6F,55,A0,FF,EB,19,03,1E,3A,58,68,DC,C6,48,5F,43,FA,A6,FF,C8,D5,25,5A,B1,18,E4,33,D4,7E,BE,85,FA,9E,17,99,C8,28,7A,24,8F,6B,96,08,9C,97,EC,02,99,78,08,4C,DD,3F,07,18,05,3C,B0,EE,8E,13,67,AC,D7,FE,85,D7,DF,41,08,B6,62,D0,1A,B7,E8,29,07,07,8A,A2,9B,B6,02,D8,FB,69,A2,C4,6A,89,E5,FE,BF,E1,6D,4E,2D,70,81,69,FB,6A,21,0D,BD,00,11,F3,1E,3D,3A,58,96,B7,92,CE,53,D9,8D,92,3E,7A,82,70,28,2F,B1,79,47,51,C3,F8,B6,A5,22,5B,55,E5,5E,AA,D0,A7,E4,92,65,FD,2D,D3,EB,17,E7,DF,B0,4C,CF,D2,E5,1B,01,7A,09,12,BE,C9,49,4A,9C,86,0A,1F,C3,92,7F,D4,D1,69,AE,C8,19,E3,74,B9,5B,F8,06,39,13,7A,AE,B0,83,1F,2B,FF,A6,57,DE,82,39,3C,E0,AE,BF,26,7C,9E,B6,0F,A8,2A,FA,60,D9,DA,87,DA,3D,EB,DB,8F,05,E4,4E,6F,DD,DC,BA,33,A1,72,5A,94,E6,86,D4,24,4B,B4,93,50,9A,4C,E3,48,2F,47,E4,53,2A,22,70,58,82,5B,08,9A,70,FE,53,C0,33,09,90,A3,17,01,20,1D,2F,2B,79,AF,74,3B,B9,6A,43,3A,1C,59,FF,32,E8,E8,B4,DA,94,97,0C,33,8D,20,89,4B,E2,E5,7E,D2,40,53,00,4D,9B,5C,82,D8,54,37,43,1E,73,CC,2E,E3,E1,4E,40,93,7F,6B,88,19,C8,5F,BD,DD,D5,8C,32,2A,D7,0E,B1,AA,65,C9,E5,26,CF,C5,63,88,81,DB,5D,9E,40,01,66,41,3C,11,31,D8,A1,1B,D6,17,B1,2F,39,05,3D,01,F2,B2,60,0F,7C,9B,FC,89,66,7C,1C,05,79,FE,DC,83,C1,84,59,33,A3,75,81,18,52,E0,1D,37,68,B0,83,A0,0E,D6,14,77,E6,34,9B,C6,00,46,63,8E,5A,C1,85,D2,A8,5F,C1,D2,82,3F,91,BE,FE,9F,40,3F,93,19,70,41,B5,A5,28,62,66,75,E9,E7,A3,C2,98,D5,81,89,8B,04,3D,BE,C0,BC,26,7E,6C,CD,E9,03,E8,1A,52,56,61,96,4F,F6,6E,75,71,99,CE,75,0F,EF,B0,3A,BF,DB,08,9B,96,34,37,C4,3D,2D,D0,1E,B4,E7,CE,D2,53,01,07,50,B8,12,A2,1F,5C,DE,91,25,FD,B6,2C,A5,5C,AF,9D,12,53,D2,21,FD,A7,7D,28,8B,92,F8,B3,9A,C5,96,C8,DD,F4,9C,2C,8B,39,DD,BD,57,BF,E0,83,E3,88,73,D0,81,0A,4F,FC,A3,D7,B1,CB,09,8A,49,FF,07,BF,29,4C,CA,3D,BD,3D,7C,1C,A5,03,3E,48,17,7D,76,7C,3D,CB,8E,82,D3,72,9B,3A,AD,AE,2B,45,08,D8,DB,DE,3D,F5,AA,29,41,18,2C,0C,D9,CA,5A,B3,91,59,76,8B,93,6A,5F,49,E3,20,D3,A5,A0,3F,46,F1,B9,78,F2,8C,CD,B5,1D,05,DA,F7,56,7B,D4,E4,27,AE,7B,9E,39,B1,78,A0,28,88,AE,7F,50,45,26,CD,43,A9,CF,92,70,10,DD,FB,E3,86,4C,29,1E,11,8A,67,17,0A,47,3D,B5,CA,6F,13,B9,AA,50,4B,7C,44,5F,69,D3,F8,7E,62,4F,1C,FD,2D,18,07,58,98,F0,43,BC,F5,32,A3,73,96,EA,25,CB,22,01,B2,3D,45,68,A4,8A,1F,AB,88,6D,08,39,A9,31,C9,88,39,8F,DC,44,AC,CA,B6,96,2D,89,CF,3D,AC,66,64,E9,0C,51,A6,0F,59,7B,04,50,0C,E3,A6,E6,4C,35,DA,F0,23,20,55,7C,1B,90,0F,E5,67,EA,53,EB,76,4D,E9,95,D9,2E,C2,FA,A6,52,7A,30,BD,8F,CB,84,6E,F9,C2,F8,E0,A9,32,B4,9B,62,E4,F2,C4,29,0F,95,C5,89,3E,C2,98,86,DD,F1,94,C5,59,65,1E,DB,AE,01,CC,8C,FC,05,4A,38,D6,DC,93,44,0E,96,B3,B6,4A,93,83,EC,60,FE,42,50,60,3F,87,73,38,63,FA,7B,BC,48,92,98,12,35,1B,B3,4F,2D,70,EC,4A,36,B0,A9,E1,52,03,1F,4B,BD,57,7C,CD,48,6A,F5,30,80,0A,11,BF,E2,B9,87,6D,35,B0,39,C1,09,42,3E,7D,39,39,2A,A9,78,EC,76,A9,D0,F9,5D,0B,9D,D7,A1,80,21,36,1C,76,54,DA,84,1C,B4,BE,BE,80,EF,70,4A,B6,55,B4,8D,3B,98,E2,39,59,13,5B,19,61,96,B0,79,F9,66,40,EE,66,B3,9E,CC,D1,E6,AF,50,DF,09,CF,4B,59,AF,40,03,7C,8B,D0,9E,54,D7,10,39,C4,27,E0,2D,F5,16,FC,CE,67,A6,13,7C,9D,DB,1E,85,4C,7D,06,3F,87,FF,86,D3,DC,F1,E2,3D,77,83,92,36,74,A2,B8,7A,C0,E4,6E,04,74,1A,D9,19,35,D0,40,DA,D2,A1,D0,A6,22,8C,20,91,2D,FE,B5,88,38,C8,34,56,A5,A4,45,D6,0A,6F,26,6E,5F,C8,B1,8B,01,3B,98,6A,19,3B,28,38,C7,72,DC,0A,4D,6B,2A,DD,6C,9E,E6,48,8F,82,26,93,E6,1B,5A,2D,C2,3A,D9,90,40,B4,63,3D,2B,CF,F6,DF,B3,A8,0E,CD,FE,87,E0,58,3A,A4,CA,11,AE,13,DE,79,F7,F1,E6,D1,83,82,F2,64,4A,C3,5A,0C,C3,F7,8E,4A,30,7C,F0,32,46,F0,6F,7A,C5,CD,4E,55,5F,32,05,CD,BB,95,AA,67,FC,32,2C,B8,7A,46,56,95,9D,1D,EB,06,10,05,BC,94,B2,C9,85,76,D5,B9,8C,28,A3,97,5A,61,02,7A,5C,D4,67,B4,43,96,31,CE,23,E1,32,D3,98,4E,6B,A9,3C,0F,32,82,12,DD,8A,90,8F,61,98,10,3C,00,80,70,E3,5B,6E,F7,68,0C,EC,06,EF,C5,44,11,05,AC,6C,DB,0A,8C,57,3B,06,EE,18,F5,82,E4,52,CA,5F,5B,B6,8D,D2,4E,90,7C,C8,A6,36,4C,B3,F0,48,D1,5E,30,55,5C,91,99,99,26,C8,E4,EF,41,94,E8,F5,F9,53,42,C2,E6,25,8F,F5,34,AF,4B,FA,7E,D1,A5,C2,8C,A0,45,80,C9,CC,82,E0,48,7E,5F,92,36,71,C1,30,16,C4,1C,1E,45,CC,C5,A2,39,B7,B6,52,99,D4,CC,35,DC,D4,E4,FD,3A,56,DA,BF,A6,23,54,92,26,CC,64,7E,30,CE,C3,0F,68,D1,31,12,D6,D8,41,27,A5,31,6B,54,68,C1,49,57,29,13,B7,D6,32,5E,AA,5B,0B,C6,BD,70,22,77,96,E2,D3,69,02,51,21,F2,B0,86,17,33,D4,7B,3E,4D,6E,3E,91,0C,C2,B6,1A,22,30,45,38,C0,4B,F5,86,BB,C1,A1,03,54,2A,10,CA,32,BE,79,79,11,A9,BB,A2,95,06,3F,CC,4F,3E,25,E4,BD,3F,47,02,8A,C1,E6,C2,28,6D,76,56,39,F0,07,C8,2C,95,B7,83,ED,5D,1D,08,5B,0E,12,48,61,17,A9,21,6D,62,24,6F,5B,F2,61,9B,E4,D5,A0,E4,73,D5,28,44,15,DA,93,D8,E1,85,41,27,A7,BC,E8,08,36,9E,60,7C,A5,62,93,AA,C7,23,41,33,EC,42,79,94,4D,6C,C9,FF,75,30,9F,32,A6,1E,0E,B3,37,4B,0D,2F,1F,33,A5,90,5E,57,49,70,0D,16,F2,65,37,2F,EB,93,66,26,F0,5C,C1,56,1F,59,D4,0D,68,46,DB,52,61,C1,64,1A,99,CB,5A,2D,22,88,64,E8,CD,10,E6,A0,66,D3,02,C5,E5,4C,59,18,B1,1D,85,E4,51,1E,77,CF,8D,E2,47,EB,9C,C8,EC,A7,84,AF,F1,60,CA,16,3E,94,4E,B5,EB,0D,4D,80,E0,87,70,F1,80,01,E7,E9,E5,E6,72,44,B2,C5,7D,74,0D,CF,70,45,A1,51,26,CA,84,6F,DB,40,6D,26,34,55,99,0D,F0,05,12,18,2C,46,4B,F2,8E,9E,16,21,F3,71,EE,A5,06,9F,31,D9,58,DB,29,B3,7E,98,84,72,66,58,2C,93,CD,40,83,C5,7E,D3,2A,BE,7C,37,E7,8F,6F,8B,F2,92,BE,80,E5,B7,6C,5A,12,E5,8F,E9,4D,B3,61,33,CA,ED,79,82,AD,83,49,4B,4F,BB,08,1C,34,8E,C5,71,2F,74,A2,C3,94,4B,9F,39,C9,8E,70,E1,60,62,58,55,5F,52,A4,29,2A,B6,40,D1,3D,04,AD,2E,C6,E5,3F,4B,B8,D0,5E,58,CB,C3,9B,EB,E7,DB,30,86,50,4C,D7,06,FD,3B,23,38,48,4F,CF,76,BA,5C,AB,ED,BE,2B,92,DB,EE,86,69,D2,3E,B9,49,99,C3,C2,72,58,0F,71,C4,FB,72,CB,F4,CB,E0,20,13,CC,EB,05,8B,7A,8D,7B,44,11,A1,3A,E2,02,F6,AF,D4,68,CC,3B,06,45,59,C4,03,18,64,BA,89,54,2A,65,D4,D1,EB,3E,F1,4F,B8,53,23,D4,53,18,35,D0,A2,7E,5C,0C,B5,28,43,F7,5D,17,0A,B3,DC,28,7C,ED,88,34,D7,48,B0,5A,3F,3F,0F,56,F6,B6,9A,94,AE,79,DC,14,F6,6C,47,35,EE,1D,3C,3D,2F,6A,5F,77,39,9B,BC,0D,2B,C0,4D,FD,1A,60,BB,DF,63,74,15,27,61,25,6E,57,25,0B,7E,D0,B8,C3,9F,70,A4,2D,C0,02,36,47,3D,E0,C0,66,78,DA,27,D5,75,23,93,AA,68,39,67,40,78,DD,42,B7,22,50,1E,40,70,61,3A,1E,64,75,F3,64,87,CB,2D,C5,DE,91,CF,96,E4,EC,00,18,74,F6,66,36,F2,69,4D,99,F3,C1,7F,7B,30,AC,7C,87,B3,63,92,25,69,B1,12,64,7E,21,3A,AC,2C,35,0C,6F,C5,62,D2,B3,F1,1E,F0,06,75,52,51,62,77,9E,8A,96,A1,55,8A,D6,97,BF,5A,07,25,54,51,AA,58,F4,93,3F,EA,F1,F2,96,2A,63,6F,10,69,01,6E,51,73,E2,DA,7C,E0,E5,12,46,DB,BC,28,25,89,7D,A9,33,A8,3A,CE,D4,22,E0,29,9B,BD,DA,C8,B7,45,9B,A1,BD,78,FB,A4,E5,D7,EB,73,CA,5C,81,2B,53,51,00,15,9C,55,8A,C4,56,3C,33,2B,92,20,C3,72,1D,9B,EC,30,FB,4B,10,B7,9E,96,56,82,A8,1C,33,2B,63,E9,20,06,40,B4,62,BF,31,4B,7E,65,37,7D,11,73,26,77,54,FD,B3,64,7A,EF,63,5B,EB,78,F4,B1,DD,7D,1F,44,6A,86,FD,E4,33,2B,D6,A3,62,85,2F,E7,30,A9,77,1C,85,DA,5F,F0,1B,FC,B1,1C,0D,99,A1,07,69,C7,DA,26,71,5C,F3,DD,7D,D4,87,E3,43,5D,3F,85,16,AC,07,81,46,86,E1,DD,E9,29,95,7B,A7,1E,2C,50,A5,FF,43,8D,62,C6,70,73,0B,C3,0F,13,3A,0A,AF,47,1C,41,1E,05,CC,38,6C,8D,F1,AE,1E,2D,B7,45,57,3E,92,5F,7B,6C,59,41,61,BD,18,0B,C7,B1,BA,26,54,0A,B9,3D,05,09,9E,09,32,06,53,4D,64,6E,22,06,E8,03,6A,30,1E,F9,26,EB,0B,61,DD,FE,FA,2C,B3,61,5C,F4,63,69,86,65,A2,96,4F,04,20,4E,27,18,4C,FF,68,59,6E,39,85,AF,CA,1F,E5,F6,78,1D,26,A0,1D,82,F1,DF,B2,0D,EF,93,B9,D2,DE,84,B9,58,2E,4A,FB,34,9B,2C,55,C9,0A,72,6E,7C,F3,0D,D3,A0,36,D7,D0,F1,CA,F4,44,EE,65,E1,87,11,B7,7C,9D,AD,F3,83,15,0A,3C,22,86,AD,F0,03,AE,5E,C7,98,31,60,3F,8D,9E,F3,3F,E9,A8,DA,88,5B,87,2C,D0,12,30,47,5C,65,18,98,02,B2,8C,35,E1,BC,44,6D,F7,F6,42,94,7E,5E,20,17,D9,6D,C3,79,2C,E1,8B,65,99,40,12,9B,50,F9,D4,EF,48,C4,C9,AF,25,75,DC,DE,71,D7,5E,74,51,5A,65,A6,F7,1E,AF,11,2A,AA,2E,E1,FF,27,C7,5E,F2,3B,EF,4F,7B,9B,B9,BE,42,4B,11,A6,77,69,7B,C8,79,42,A3,E8,A3,2D,26,11,9C,20,5F,E4,39,57,BF,6C,BA,25,02,E6,FE,0B,B4,4F,58,B0,64,39,A5,DD,A6,93,10,5A,35,34,0A,FD,C9,2B,96,D5,A1,E7,2E,F4,07,3A,86,8B,66,CD,BB,78,89,E8,61,70,5D,8C,26,4F,5B,6F,A7,D9,B7,14,27,4C,36,39,2D,1A,A8,FE,29,E1,97,BB,53,51,1C,8F,61,8B,CF,8C,B8,72,79,E0,D2,DC,58,CC,F6,37,03,66,5C,D8,BA,D3,7A,F5,F8,2E,95,60,09,EC,BC,CF,16,BF,63,B2,65,97,96,17,14,03,5D,99,95,E2,2D,D6,AA,DB,73,E7,73,91,DC,A6,A5,2A,3A,57,19,42,C9,94,13,E2,90,68,19,6D,4A,84,03,B3,3E,85,52,54,3B,A6,37,FB,8E,2E,F9,C5,68,58,AD,83,31,20,18,76,48,78,8F,3A,03,6A,9C,D1,1C,6A,D6,FC,BC,3F,3F,1B,70,7E,0A,56,54,AE,19,EA,77,13,81,6B,72,6D,9A,52,D3,0B,EB,64,5E,07,31,DD,A7,31,83,96,87,B6,4B,8F,B6,35,6D,96,36,09,5D,A0,AA,69,7E,A4,D7,5A,6D,E3,2F,12,D5,E4,D0,26,8A,1D,34,BE,70,44,59,93,B2,8D,8F,8E,5B,FB,62,6F,17,57,6E,38,35,09,1A,C0,DE,EA,0E,05,CB,7D,7D,90,2C,8D,E7,29,69,4C,4F,36,37,E0,02,15,87,5E,F6,5E,36,C8,1A,F0,DD,09,0A,91,15,35,78,5D,51,03,F1,99,7C,50,EF,8A,89,85,D7,81,0E,A6,EC,76,52,B8,67,00,41,DD,F0,C8,4A,3B,38,A9,88,12,39,94,33,BB,7D,03,30,09,62,8E,8A,FD,F4,47,81,76,58,F7,FD,05,67,6D,18,9A,17,DB,74,91,02,04,F7,01,4F,78,B0,F1,E6,32,3F,A3,94,7A,36,30,C9,FB,EE,78,B2,FD,99,0A,4C,93,49,0F,84,4B,86,51,D0,8E,BF,B8,F4,49,2F,38,EC,D3,4B,FC,8C,91,10,81,6D,6B,CC,F0,9C,C5,5C,55,08,85,A8,11,B6,3D,3D,6A,D0,95,CF,7A,62,48,05,C1,15,DC,DB,E3,9B,90,19,4B,4B,DA,FF,DE,04,99,E1,6D,CF,D4,34,50,1B,70,13,B9,D8,4E,8B,F3,FA,A3,53,D2,FD,2C,B9,77,2B,BF,27,28,CF,05,1E,11,5F,C7,7C,80,70,83,17,86,F3,F3,9F,B0,78,F4,83,9A,23,FE,E3,01,46,A8,13,2D,A7,59,20,C1,31,C9,8B,02,4C,C9,46,9F,3A,A1,10,9E,25,72,B6,C2,43,AE,AE,AE,6E,FE,0B,2C,19,0A,92,77,F5,37,F5,1F,1A,D6,A9,44,48,0C,65,42,CA,44,48,5F,EF,DA,50,16,1F,6E,06,B0,01,15,54,EF,12,1E,14,72,73,DC,B4,5A,83,02,48,35,73,3C,CF,C9,22,47,9D,9C,2D,51,EE,F0,03,27,01,50,AA,27,98,F4,29,A2,0D,50,F7,63,A6,73,51,4A,6A,12,78,8F,11,C4,5F,57,BD,4B,30,C4,2B,F5,78,AF,78,25,88,90,8A,24,A3,3F,B0,08,8F,EE,91,18,3A,CC,06,E0,2B,A8,5E,97,4A,44,03,E9,F1,2F,45,5E,BF,F0,DE,33,C7,0A,E5,AC,CE,53,2D,BE,66,BD,2A,1C,76,C5,DF,8B,E8,64,7E,F2,21,1A,5B,2C,97,53,4A,A2,F1,00,63,20,66,4C,79,3E,C5,6D,36,48,D9,0F,7F,3D,64,E0,EB,98,BF,ED,C6,04,02,05,90,00,02,4A,51,18,7D,5C,2C,3A,1D,5C,70,0F,68,52,59,6D,87,58,50,33,2E,6C,83,B5,08,16,4B,EA,44,CF,69,23,FC,9C,DB,4F,C1,75,20,71,BC,BE,59,C5,DE,84,A5,2E,3E,93,1A,59,55,8B,A5,5A,49,42,1C,32,72,8D,08,DF,29,B5,59,71,47,1B,A6,0C,5B,B6,87,D2,13,B5,3A,6F,77,53,7E,C6,D3,7D,BD,49,61,D8,1B,C0,87,D4,F2,2E,D9,5A,60,BE,C8,1B,C4,3C,5F,63,C2,30,01,FA,7E,4D,50,5F,A3,6E,6B,8E,86,C4,60,B7,E9,6E,15,85,22,A2,3B,19,C9,5F,C3,57,E0,63,3D,BF,05,42,84,77,5F,87,96,B8,74,5A,19,16,68,E2,F0,3D,FA,50,C6,48,DA,6D,6F,C7,F8,E3,47,FC,EC,32,76,6D,B3,C5,F3,3E,01,95,C2,2F,46,6D,1B,A4,9C,85,12,31,0F,81,56,11,9A,68,F6,01,32,C6,D1,DB,10,8F,4D,EB,6A,D5,57,55,FF,FC,C4,7A,0D,07,36,06,CA,57,50,99,B0,6D,DC,94,60,6E,D0,21,40,5E,7F,9D,46,E9,68,6E,5F,FB,C6,9B,76,E8,21,4D,8A,DD,36,3C,78,EF,28,FF,F1,8E,4C,14,6D,8D,9D,9E,A5,4B,91,A1,6B,A8,4B,D5,89,96,6F,E0,DB,CF,08,FA,5A,F6,7C,61,5A,3F,1B,A4,D8,7C,CA,1D,C5,67,8D,05,86,D3,6D,A5,FB,A2,73,49,80,0F,C3,FC,AB,30,6C,B9,05,CD,20,3E,72,5C,D3,DA,A8,07,1A,BA,8C,D5,91,04,B0,F7,2D,68,79,91,86,B9,96,8F,0C,19,07,C3,D9,3A,77,7E,0D,DD,21,E7,EE,D2,9F,05,E7,12,F7,87,BC,F5,C5,3D,7E,C7,1C,E6,14,46,C3,CC,F6,22,55,62,95,7A,D1,59,C3,6E,71,10,0C,6B,04,05,41,56,79,87,E8,D8,3C,CE,2E,8F,7B,27,EA,82,D5,8A,A9,95,C1,C0,90,37,77,79,7D,45,EF,DA,D3,C6,A9,CA,CE,E5,C4,75,76,27,4A,B6,F8,CF,73,BB,47,DC,11,07,98,BA,E3,DF,7E,5B,14,53,3C,46,5F,1A,DE,6D,AC,B5,02,17,7A,07,53,B9,C8,E9,E2,7B,1C,D4,30,4D,49,0B,8B,A2,9B,03,2B,55,FD,96,E2,EC,06,94,46,EF,7A,BB,C0,FE,04,6E,6F,AB,DF,EA,5F,3D,8B,BB,16,63,A2,1F,00,E1,21,5F,58,41,AD,97,DE,57,23,BC,23,E3,22,99,B9,B2,FA,38,09,35,66,97,04,DA,1C,C1,90,2C,F8,71,10,57,C6,F9,44,B5,E3,8E,9A,6D,A2,9F,65,D8,91,42,80,77,CF,0B,24,5D,FA,C2,F2,C6,7C,C8,8C,3E,28,CC,78,9E,10,A8,30,74,51,96,3C,E0,03,3C,69,EE,A2,18,5A,2F,A8,D5,93,25,C2,67,AD,D5,E9,74,88,45,4F,32,5F,DD,25,C2,72,56,3B,82,94,4B,43,96,FF,D4,9F,70,1E,E3,0F,11,01,8B,41,80,95,C5,B3,AB,48,42,B0,33,C0,4C,54,C5,47,6F,13,09,26,B2,22,45,29,BF,D5,09,29,77,8B,00,A9,54,C5,3D,C5,B9,A8,F4,3B,F3,EA,0D,8A,88,FE,64,21,49,5A,AA,F8,71,84,D7,DE,B8,05,69,80,58,96,12,0E,14,A7,89,DE,72,6B,57,52,40,62,72,B7,4A,73,3E,B6,89,9C,BB,68,89,96,8F,80,3B,B0,6B,71,DD,2D,5D,7C,6F,A5,78,FD,C2,CD,47,2D,57,0E,D0,06,17,CE,B1,95,9B,18,69,67,2A,C3,C0,FB,03,DE,E5,8E,AA,0E,20,67,2A,44,A0,BC,2C,67,BB,80,9E,1B,29,34,5E,33,4C,32,89,08,D2,8D,E1,A6,17,A2,0D,E1,67,52,FF,98,9A,B6,C8,C2,2D,33,36,BC,CC,DA,5F,90,F7,E7,C7,B7,6B,B8,3A,50,7D,58,5B,91,BF,04,44,93,6F,BD,CE,E5,0F,F4,16,4E,40,B3,A6,3A,F9,9C,4A,24,62,63,6C,23,C3,F6,68,87,D0,B7,67,D1,B3,83,BA,E4,EF,4D,4B,44,0C,BA,13,6B,22,76,7F,0B,0E,A2,0C,CD,90,24,2B,29,79,68,A8,27,A8,C7,57,8B,DA,D8,5C,CA,C5,37,1F,E5,BA,C1,2A,0B,98,A8,C8,BC,23,45,D3,40,42,C0,C5,9D,BB,42,79,97,40,9C,81,1D,74,3E,20,F2,6A,55,9E,B8,9E,C4,2F,5F,54,FE,D3,BF,89,BE,EB,9B,85,AB,31,56,FB,EF,FB,A2,81,2E,1B,C3,A8,E4,10,0E,12,38,3A,D8,B1,64,08,F7,14,98,8D,9F,33,BE,E4,96,1F,D1,DE,28,08,98,0C,67,05,F1,31,55,6E,82,42,BF,34,8F,3D,32,5E,8F,5B,8B,F6,31,D7,76,6E,BB,47,80,E9,5A,E1,F0,6A,29,8B,C6,78,48,BB,C3,53,50,8F,C0,56,A2,29,98,29,4A,0C,FA,C9,E7,B9,13,FF,CB,B9,65,D2,C5,FB,F6,04,F8,26,37,05,E8,06,B9,47,BD,A6,D0,CA,4F,A1,07,E9,24,19,09,BB,2B,49,34,44,48,00,EE,E8,61,F8,47,5B,B9,D0,78,56,99,39,98,E1,C0,E1,63,CA,65,81,A7,6F,FA,15,23,D4,A8,B5,B8,A1,C5,4E,6A,29,06,99,70,25,F4,E7,AA,38,A3,56,9B,92,4F,87,C9,13,18,8F,74,CE,31,F5,FD,9C,77,15,4C,59,D7,46,C5,AE,04,25,33,78,C9,51,2E,88,43,74,92,2B,1F,81,67,87,7E,3E,6F,AD,FE,0A,82,EF,D7,73,3A,5A,E4,16,AF,47,7A,37,16,22,5D,68,83,C2,FF,FC,09,A8,BE,34,FF,79,9E,BF,CB,B3,1E,AD,D5,69,63,B9,08,3E,B8,F8,BC,4E,35,33,AE,23,F9,3B,CA,4E,EA,E6,2C,5D,A5,30,D7,EF,E1,DE,94,9D,0A,57,2E,E7,EC,50,0D,94,D5,20,68,96,C0,D0,A1,A4,55,34,50,94,DE,03,73,00,12,C4,90,EC,B8,3D,C8,75,55,11,0C,FE,E4,9C,79,C7,07,27,22,54,40,8B,27,24,98,2A,69,6B,D3,6E,4D,9D,05,1E,14,43,10,F6,08,79,72,FF,73,70,AF,05,36,83,EC,C0,55,54,E2,A4,28,09,E5,9A,4F,15,F8,B6,87,A9,61,DD,9F,F7,81,BF,20,45,62,DA,85,9A,13,CC,A2,5C,AD,AA,83,CB,B2,9A,94,45,BE,1A,08,B3,3F,6A,84,8D,43,F9,1A,D4,08,71,97,9F,B0,55,13,4C,0C,0E,CC,4B,78,63,D2,1A,51,74,5F,B2,C6,23,DF,F5,BE,C2,EA,3A,2D,D4,F8,65,60,61,28,AB,93,BB,68,42,CF,FD,25,D5,7B,40,1E,8B,F2,9E,24,39,31,C6,58,C5,48,E2,5E,CB,52,E9,84,D7,FA,A8,F8,7A,7A,DC,9A,16,44,AA,1F,F5,6E,DD,31,02,7F,4E,1E,61,2D,F4,BC,4C,05,63,7C,02,87,1D,D4,E3,85,C3,BE,3E,ED,C8,67,FD,96,BC,5D,38,06,89,26,F8,C4,9F,E0,34,A7,E4,46,B4,8A,75,1F,F5,5A,68,BE,10,81,E1,4C,6F,E9,A1,86,B5,5B,8F,FD,E8,3A,C8,16,CA,75,BE,BE,38,E4,3D,C6,20,46,19,35,59,CC,15,A7,20,69,3E,BF,12,98,79,A3,BD,07,BD,80,57,64,A5,4F,F3,1D,86,C1,39,19,1B,EE,9E,19,0B,3C,66,D2,63,2A,D9,9C,E8,8F,7F,0A,8B,44,1E,4E,E7,D8,3F,67,75,46,CA,9C,E2,8E,67,53,B8,83,34,BA,1D,84,4F,CD,BB,87,ED,BC,22,88,8B,3C,15,AE,64,F0,40,DB,F9,19,31,93,27,E5,E2,27,21,06,52,71,1A,BC,98,48,D2,C3,78,F3,09,2B,B6,5B,A0,D7,7D,13,F2,ED,E4,8F,BE,DD,D4,C6,7E,D5,CA,5C,70,57,C6,C2,0E,31,20,FF,F2,E6,9A,CC,D6,B2,8B,F0,19,07,2E,4F,F9,F1,A6,D0,40,EA,8E,7B,78,8E,B5,28,EB,59,5F,E1,69,EA,11,58,93,F4,6D,8F,23,D5,C9,44,47,DB,0B,7C,FA,EB,62,17,E5,C2,9F,C3,5C,F5,AA,96,AF,46,D0,05,10,94,B6,B5,3A,79,E6,F4,E2,B4,5A,A5,73,07,69,D1,E6,4D,7F,AE,A3,A2,2D,FA,06,2C,F8,A7,3E,D3,EA,D1,D7,21,05,8D,91,DF,70,B9,36,38,31,9E,63,34,D7,B2,EA,C3,11,7F,A8,8C,0E,6B,27,52,2C,CC,28,8A,1B,4A,35,90,F8,E6,2D,43,E9,BF,FE,DD,82,6E,05,48,F1,C2,A9,6C,C1,34,79,34,76,88,63,AA,65,66,E7,BA,EA,A1,7D,B6,55,A7,50,D8,81,91,03,C3,34,D7,34,E2,86,6A,CA,5D,56,EB,DC,1A,3D,EE,92,D8,9E,49,6C,D6,BC,A0,69,0D,A7,0D,DE,AA,BA,2B,AB,C9,92,21,B0,8A,76,57,35,CF,B8,C6,FF,A1,9C,9A,CF,74,8E,07,A3,24,05,83,9B,6E,3C,05,5E,F5,1E,3A,F6,0C,4F,97,C4,C5,86,8B,9C,62,3D,5C,9A,61,BD,10,17,7C,2A,90,0A,74,5F,39,B3,2C,BF,10,FD,39,D5,6E,92,03,CF,96,17,90,27,2D,28,9B,15,A2,31,9B,A4,39,B3,3C,08,09,46,63,2A,9E,7A,B9,CB,9B,8A,70,95,A0,CB,D5,B6,61,AE,5E,BA,69,8A,C6,53,5C,EC,11,8C,54,E9,B4,DF,B7,AE,CD,65,A8,3B,00,96,6C,7E,46,BC,9D,C7,8C,F1,A5,80,4E,A7,C8,7E,BF,7A,25,D6,61,81,2E,F8,77,7F,89,2F,7F,54,78,B3,9A,23,FC,F0,05,19,96,E3,F0,57,D7,47,81,0C,DF,39,D7,85,F8,89,ED,1B,C5,2C,2E,34,11,76,5A,34,14,D2,2F,57,AB,35,EA,91,97,75,96,3F,0B,84,77,FF,26,E9,CB,E9,12,26,8F,0D,3B,49,52,4D,D7,8E,34,5D,7E,DF,64,37,D4,0F,C3,2B,F3,8C,AB,5F,13,9D,E6,0C,65,96,9D,50,CD,9E,4C,9A,CB,A5,FB,47,8E,16,DC,EE,14,8A,76,30,67,5F,F4,F7,6E,1E,51,60,FD,7F,BA,63,16,0D,9E,3D,CA,40,6A,32,97,F5,30,11,61,17,22,72,E8,C8,AF,7F,F3,56,D8,45,A3,34,19,A0,FC,3C,4F,8D,09,DC,73,20,1F,38,86,69,6D,F6,D4,32,D5,76,71,0B,1B,8F,83,9F,DB,9B,BB,34,33,62,A7,3C,8B,58,81,5F,31,83,27,54,22,B1,B5,CB,E1,1F,C8,AD,6C,CC,32,9F,12,CE,BE,AD,16,54,FD,D1,73,88,11,40,18,FC,6D,EE,B6,80,DF,A6,C1,D1,BA,B9,82,E9,1E,1D,5F,69,06,47,22,2B,D8,29,8D,68,B8,EC,C5,45,F8,30,3C,EE,F2,7D,B1,71,12,20,53,E8,FA,79,DD,25,35,B1,7C,F9,31,EC,EF,BD,93,87,69,ED,0B,1D,F2,38,84,5B,14,AD,A1,FB,B3,B7,82,50,C3,A7,62,6F,79,83,08,B1,37,9E,E2,F8,C0,F9,7B,33,6E,4C,C0,26,E0,8F,3A,5D,1A,1D,17,24,AA,5B,28,58,12,83,5A,6D,10,AD,D0,01,EF,EF,7C,AE,7B,52,59,63,B0,2F,2E,72,16,9E,14,80,50,09,9D,CD,A4,84,20,0D,AC,12,CA,79,92,A2,F9,34,26,B8,36,D8,FC,4D,11,85,06,16,05,C9,17,82,58,D7,C7,70,D6,48,4A,06,F6,2A,1A,FF,DD,2B,14,61,49,A6,1D,F6,BB,AB,F8,77,51,B9,4E,A3,66,18,40,3A,71,56,CC,69,43,B6,7B,7F,20,B3,3F,44,10,EE,6B,44,27,2F,59,A0,F6,BD,D0,D0,0D,AF,6F,65,66,D3,30,B7,0B,D8,D6,68,4A,5B,6E,C2,41,CD,11,90,D1,A3,8D,8F,12,AB,41,D4,BE,B9,39,B6,A3,75,42,33,5E,9B,09,22,87,E2,11,ED,C8,5D,28,7D,5B,EB,53,C4,38,50,5F,4F,64,48,8F,0D,54,DF,D5,68,37,3F,05,23,C3,A2,58,C5,46,1E,88,DA,AC,7D,0B,46,04,D8,F0,5C,1A,08,B8,AB,E6,3C,AC,51,A0,50,F4,44,E3,6F,D6,E1,4C,7B,23,C3,B6,9F,2D,6F,F4,9C,09,E7,66,59,37,82,15,BF,99,12,D6,2C,D2,DB,E4,E4,8C,33,84,C4,A4,4C,05,B3,1E,6D,60,CB,56,F7,73,DC,22,8C,52,C9,96,67,17,C9,E7,C9,A6,71,E6,F8,B0,71,F1,44,F6,9A,AC,AB,58,28,F3,43,63,16,C5,55,E9,95,54,82,CA,40,28,28,A0,E5,4A,3A,1D,EA,32,59,EC,21,36,D1,E3,D1,51,78,29,22,1D,2A,64,C6,39,A1,CC,4C,02,56,52,F3,20,DA,35,76,1C,B9,B2,08,85,7B,21,F7,02,5F,A5,71,8E,BD,F8,93,F9,8F,E6,D7,26,88,3E,78,2B,8D,75,82,14,A1,CC,02,37,A6,DF,6E,42,D2,CF,18,B7,19,3E,83,B7,17,FD,C6,CE,EC,B5,AA,04,04,C4,76,75,73,63,64,6C,B1,8B,0D,9F,87,D5,1B,16,A4,57,99,8F,9D,28,F0,A8,1D,26,0A,22,9D,A4,7F,2C,F0,E6,B8,98,F5,C0,E6,23,1A,2B,6C,BA,28,9B,0F,66,FF,89,F4,84,80,C9,0A,53,66,5E,4B,DA,1C,EA,F8,59,05,A8,73,9C,A7,19,1E,5F,28,CE,C9,58,EE,AA,73,6A,43,1B,D2,17,BA,9F,E3,C9,35,6E,FB,DC,2B,3A,F4,E8,C3,64,CE,B1,93,23,D5,9C,E9,3A,6E,C5,55,27,1E,01,7B,4D,21,E9,EE,F2,A2,FB,37,B0,35,B2,4A,1F,D0,75,2A,34,5A,83,E3,79,4F,A4,E5,21,5F,7A,ED,B1,B4,C8,1B,AB,E2,B7,8B,17,D0,7E,9E,C5,4D,1A,89,91,F3,84,C2,96,8E,AA,33,11,1C,B6,A9,AE,83,21,3E,5F,3F,F7,ED,1A,53,9D,2E,6B,74,9D,A3,C9,35,85,80,32,D6,7E,0A,83,53,A0,97,C7,99,3C,C4,98,62,26,80,5B,60,83,4E,C2,20,EB,D9,52,9B,96,A7,76,6C,29,35,FA,8E,D2,60,9C,41,77,FF,03,5D,C4,C3,49,53,0D,4A,E9,32,34,D3,2C,44,5C,9D,64,8B,22,40,AB,22,85,CE,0B,81,21,A7,06,7E,FE,B4,EB,44,F9,AB,5C,9F,8C,C6,8C,97,B1,3A,2F,AF,E6,1C,03,78,FA,EE,1D,B3,FF,C2,D2,68,6D,BE,9B,6D,B2,A1,D4,1F,D6,2F,07,9D,AB,30,03,95,14,81,3B,DC,C0,E3,97,4A,96,D9,12,49,D8,56,62,3A,AF,50,4F,C5,09,FE,A7,46,64,23,4F,FB,CB,C8,EB,4D,56,8E,98,57,76,0B,0A,02,CD,C7,68,25,E1,C8,7A,74,A4,C7,22,A7,22,09,04,25,34,C1,7B,1C,0D,2C,B1,82,DF,2C,55,55,79,80,38,AE,D1,D1,99,03,44,6D,D1,13,E8,75,CA,02,5A,16,28,6E,60,F8,DC,2F,FF,4A,C1,99,11,D6,69,77,CB,33,B9,79,99,94,BC,8D,AD,9F,B9,7F,19,65,1F,DD,3F,5D,E0,70,53,5C,D8,A6,D7,5D,33,A2,2B,9A,35,82,6E,AA,A5,70,6C,84,E0,EA,99,B6,BC,7C,6F,11,27,3E,E0,48,68,27,94,74,70,B8,01,1A,F0,62,70,44,18,EA,9C,CE,06,B7,1C,68,77,4E,87,79,D3,74,7C,5C,94,2F,F0,77,8F,E4,15,DC,CC,A5,CE,88,45,9D,A2,16,25,7F,84,96,91,CD,08,D3,CE,35,CC,95,84,3A,6C,76,29,47,4C,CF,C1,86,77,BE,A5,A6,76,45,8C,C0,FF,4E,A9,30,4A,C8,21,6B,1C,77,DE,C7,A6,AC,4D,35,E3,1A,3E,6D,AC,3A,9D,1A,05,58,EC,E1,F7,D5,69,F5,2F,90,AB,BB,60,6A,0C,F4,94,7B,F0,01,32,E7,B6,ED,E5,A6,D3,49,BF,5C,AB,01,6F,63,3B,DA,7F,9A,6A,B6,76,8F,80,65,E3,96,1F,C5,F6,26,50,F0,0A,81,DB,18,40,DD,DB,E7,76,EF,12,4F,E5,F3,6B,0C,09,A1,55,3E,17,68,8D,FE,44,85,DE,C5,68,03,CC,57,0A,E3,94,7E,F8,5E,FC,ED,A0,59,7B,0A,0E,4D,6B,46,C1,42,61,EC,0B,C0,35,C3,CD,C6,65,39,88,EB,CE,5C,DB,A2,95,97,17,DF,64,43,44,47,9C,B2,F6,D6,C6,B3,CA,E2,A0,1B,C7,0E,10,A2,5B,6E,F6,0E,DA,8E,AB,12,F2,CE,1B,F4,FC,A5,E8,09,89,FF,39,21,4E,97,DB,86,11,20,34,1E,CC,D4,4B,94,9F,2B,60,57,99,65,2A,14,F3,1C,BB,A3,3F,D7,10,9F,CE,AC,A0,81,91,9B,E1,D3,50,47,C6,A2,5C,62,76,FD,6B,27,AD,83,D5,32,4E,D4,8A,30,BE,AC,13,26,05,7E,65,DB,04,7A,93,AF,6A,53,F9,90,0B,2E,0A,68,36,9E,6C,E2,77,24,30,82,6D,8A,14,10,F1,C6,BA,5B,30,A3,38,A0,B6,8A,37,35,F2,0E,25,20,F6,2B,C5,F8,DA,BD,68,76,7A,B9,46,59,23,CB,A1,71,9A,70,B7,7F,82,12,23,01,BD,81,A0,F4,DB,97,5D,D6,87,60,5C,E8,ED,A7,2B,95,7E,B6,EB,9A,BA,2E,9F,C4,26,22,7C,CA,13,BD,89,66,4D,36,9D,47,F8,BC,06,77,FB,1F,4D,86,AD,BE,02,12,2A,C3,5C,81,7E,8B,F4,D4,D6,77,E5,A9,CF,E6,C0,BA,D2,54,CC,AC,5F,39,52,24,6A,A1,A4,73,11,99,45,F3,7C,D3,57,58,E7,CE,0E,85,61,46,C6,9B,4B,C0,3F,00,39,E6,B5,7B,A2,06,95,8B,B2,BB,0E,B0,9C,3F,40,78,10,04,21,63,F7,6A,93,C0,22,EF,93,5C,28,E0,4B,48,F5,FA,7B,92,4D,FD,64,1C,7A,79,FA,2D,61,49,A9,29,01,2F,CF,09,B9,81,97,0A,50,F1,87,45,56,EB,6D,CB,0A,31,B3,E4,00,C8,D6,9E,9D,E8,94,F9,27,41,87,CC,9A,8E,BE,40,02,80,FC,E6,A3,43,AB,87,1A,EB,DD,96,23,36,E7,C5,BB,5F,DE,85,3D,59,3F,37,27,81,2D,EC,73,30,6E,F0,01,2F,EA,78,A2,33,6D,6F,C5,6A,6C,86,7A,74,58,4B,DA,4A,CD,C0,CA,AD,E8,33,93,FA,CC,EC,7B,1B,AF,06,47,A4,49,C6,AA,2F,D4,A5,9E,A7,DC,9B,C3,83,2A,A0,36,8D,BA,48,B6,B6,0F,2E,EC,A8,17,77,5E,A3,62,84,A0,63,C2,62,EF,86,1F,6E,34,A5,5A,96,2E,9A,3C,E5,21,96,17,F5,9A,D2,1E,9B,98,97,A8,D2,6B,BF,CF,00,AB,CD,2C,65,8F,8D,43,03,07,90,E2,B7,CD,87,B2,3E,6D,E4,37,D9,74,EB,BF,52,D6,6C,25,0A,52,D9,CB,FC,A4,35,06,25,E8,FA,2C,4C,19,F1,40,9D,C3,1F,AA,46,31,2F,06,D9,99,0F,F3,7F,C7,B0,C6,D0,63,7D,8F,DB,8D,FC,06,C8,7D,04,9D,6D,AF,CF,5B,92,02,E4,25,1F,31,0E,68,D8,16,2C,33,7A,A3,82,94,56,51,42,F8,E3,2A,C4,48,40,9A,75,8C,A5,35,60,F0,AE,A7,F9,2A,C4,16,C8,94,74,B8,E1,F2,0F,DF,58,AD,62,E8,80,92,7C,07,B0,17,1C,94,E3,A5,81,1B,17,18,5B,60,FF,DE,23,A3,B6,A2,29,2E,3B,9D,40,D6,7B,19,FE,F2,5B,78,90,CD,68,A0,C6,49,91,D3,AD,5D,77,6E,70,3E,E4,90,1A,35,5D,C1,8F,9E,20,AA,E5,48,83,DB,BC,9D,D1,5C,5E,13,22,FD,D9,E3,60,F2,26,B3,8B,0A,99,CF,53,C8,3D,ED,73,B2,CA,E2,29,1A,7B,0D,7D,59,4C,83,B3,A4,A7,8B,D2,81,F8,8A,6D,C2,BA,39,B5,B8,31,32,03,7A,7C,CA,1F,0E,FF,F6,7A,C8,95,45,24,AA,6D,31,01,59,4D,54,1E,CB,83,DB,3A,35,DF,36,AB,1D,7A,1C,A8,2C,DF,00,5C,72,4B,C9,B1,61,0B,6D,60,3F,61,96,30,F5,EC,23,6D,11,60,4D,FF,AE,1B,5E,3C,C1,1C,F1,1D,7C,97,BC,57,8D,3E,7A,A3,78,C2,6A,A0,7A,05,5D,AC,C4,AC,15,01,97,C5,72,E8,AA,40,33,69,27,42,8E,DA,E8,93,5F,A1,03,DA,21,A9,03,15,F4,DE,9F,80,A3,75,DB,76,98,86,AE,C4,7B,2E,8D,B5,0B,92,E1,8F,4C,F5,6C,0E,2D,69,D6,89,C2,04,28,16,80,BE,62,8D,5D,8C,14,F9,D9,9E,15,2D,99,AA,5C,26,FE,4F,FD,3D,4F,94,90,C2,3F,04,41,09,17,90,23,AB,11,5B,54,1D,27,E9,B0,89,F6,9C,2B,5E,59,B9,01,FC,8C,42,C3,42,53,A6,1A,5C,BC,9B,56,15,F5,FF,13,8E,FF,5F,74,82,93,87,C2,E6,72,D7,0C,7B,2C,DE,63,7B,C8,E3,EC,89,40,44,1E,B2,62,3B,B2,A5,BC,9C,64,F8,7A,CC,74,51,63,F3,AE,1F,06,D2,7D,E8,21,C8,AD,7D,05,F3,DC,C6,07,E7,EF,7C,21,41,9A,03,6E,61,4D,D6,8B,C8,42,3C,D4,E1,DA,38,56,CE,5B,EB,71,89,85,56,D6,6A,85,66,D0,9A,F7,20,93,28,4D,14,71,7C,E3,17,7D,92,20,A4,F8,D5,56,46,84,C3,45,01,AD,4E,8A,6C,9A,59,18,50,AC,EC,9A,61,D4,C8,DA,E8,D5,B0,A6,FB,5E,16,C9,91,1B,21,F3,3B,06,07,4D,7A,92,B1,62,CC,20,DB,11,D2,05,67,3E,64,D3,AF,48,41,86,C6,4A,56,10,06,CB,86,4C,DD,C2,CE,76,68,AD,6D,9E,3C,66,20,AA,CE,DA,FE,4A,CF,9F,49,E7,8F,CC,D1,AF,F1,20,37,B8,42,EA,33,BC,AE,4C,C8,A9,5E,E9,F9,5B,87,61,5E,82,38,99,B8,F8,B7,87,A0,F3,C5,79,E6,4B,FC,85,7D,B4,48,96,C4,1A,86,F6,31,31,71,FD,32,BD,26,C1,6A,60,95,A3,05,9D,59,9C,58,2C,41,DE,3C,24,D4,99,8A,51,A6,B1,9A,B0,14,6F,F2,72,55,5C,C4,17,C0,8F,31,2A,CA,90,7C,83,54,33,7A,6C,6A,E0,07,94,45,8C,E6,80,42,AA,E2,DA,55,1D,87,B9,CA,F4,0B,62,5D,EF,C6,C0,B5,18,04,5C,AE,9E,E4,D9,52,56,20,82,F4,47,0D,CE,5C,49,7B,4B,08,81,A7,96,AB,0B,57,95,13,3F,E6,7A,6D,39,78,1B,AF,8D,D5,19,57,32,80,13,28,5D,77,4E,49,9C,92,A8,BE,41,8F,41,DB,83,C2,5B,9A,06,6E,DB,58,8C,F9,61,96,65,5E,A6,08,86,8E,6C,B8,FD,A2,68,D4,D0,48,E9,52,53,1E,77,09,4C,44,C1,1C,6B,F7,90,33,E9,3E,09,0B,5A,F9,FF,C8,99,2E,9A,77,7D,56,97,B3,7E,FC,25,9E,2F,55,2D,15,18,F2,17,32,D1,7A,EB,A0,53,B1,F6,C7,B2,72,24,0D,F0,4C,62,DB,40,DC,00,28,60,AE,B7,8A,90,3D,36,7A,7F,06,BD,F6,05,E0,DF,AC,C0,C6,15,F5,BE,03,E1,98,8B,6E,15,EC,62,25,E3,CF,39,02,94,F9,1E,92,40,6B,BF,60,4B,AD,20,EC,44,B4,D0,FF,2A,1D,E1,AA,A5,D8,C5,AD,45,94,27,5A,0C,6F,9C,BE,2F,08,8C,7D,3B,93,72,E7,2F,E1,86,26,80,AA,C3,E6,4C,2C,88,C3,00,8F,8E,86,15,CD,98,58,E2,E2,10,5C,40,AC,2C,79,86,23,86,28,B3,86,59,E9,2A,18,5A,15,59,11,5F,15,16,6D,27,1C,E3,40,1A,16,1B,A4,49,18,90,CB,17,AC,C6,53,ED,B3,EB,AA,9F,F1,71,00,59,36,F9,B6,DA,17,94,7B,4F,2B,59,DA,F0,0D,EC,BF,7F,C9,B7,4A,82,35,91,84,B9,6F,EC,FB,7C,7C,D4,3F,D6,29,A1,4A,6C,02,1F,FC,A1,13,8D,47,1E,77,95,26,EB,6D,1E,1E,07,45,3A,01,A6,80,A7,BD,7C,00,45,CC,9F,C7,8D,11,B6,05,8F,E7,FC,4F,B3,B0,2E,53,40,12,3C,4D,E9,96,DF,6E,31,85,A3,86,BB,0F,DB,5B,EC,BA,94,37,BA,AC,9C,43,F5,94,3B,01,A7,4E,49,A4,B4,AF,0B,A8,1F,7E,54,B1,77,2F,EE,14,00,92,D3,E4,3A,2D,50,11,4C,0A,75,48,AE,4D,05,1F,47,9E,CE,14,CD,DB,06,30,E5,87,64,58,1B,A4,A6,C6,47,1F,CA,94,CD,93,E1,69,53,A9,FF,49,93,AA,B1,54,75,81,C2,A5,7E,C5,1E,53,D2,F0,C1,31,6A,12,F2,60,FB,B6,F4,0C,B8,A8,36,45,59,0D,16,10,E6,D0,39,69,A6,B5,B0,50,49,F0,3A,65,CA,A5,2E,4E,E3,8A,73,20,26,43,4C,52,7C,64,DD,EA,35,25,0E,38,86,6A,06,C6,40,B2,2E,83,3D,D7,B5,7F,E0,16,1E,6F,40,DB,37,B3,98,7A,F6,69,26,E1,72,2A,87,F2,23,3C,7B,21,EF,D9,46,1E,E6,BB,06,9E,24,04,05,47,CC,F1,EE,20,77,A8,1C,2A,D6,3B,0E,67,59,8F,19,EB,58,6C,09,80,74,B8,C8,57,5E,FB,00,55,78,A5,AE,D7,6F,10,EF,45,2F,77,65,B8,EE,AC,BD,BC,57,4A,90,64,06,4E,95,61,3E,B8,82,09,AA,20,1D,A7,2E,EE,A6,00,8B,20,F9,A1,1F,B9,CA,D6,C2,2A,0F,6D,A8,F7,5B,D6,6D,A2,2F,CF,76,61,FF,0F,E6,09,30,86,61,29,36,E3,FE,36,DA,A8,D8,9F,5D,5A,A2,C1,AB,5B,46,D1,81,B7,F5,DA,59,55,97,0B,1D,9F,73,0D,12,72,14,BC,B5,6C,47,C3,D4,7B,D6,63,C5,A1,28,39,79,D5,D2,2F,9C,5C,D9,49,10,4F,12,EF,45,A7,89,E9,5B,9A,17,1D,EF,0A,C3,68,D3,1E,60,1A,FD,75,3B,B3,AF,F2,EA,CF,14,FF,93,73,26,39,81,0D,22,15,4D,13,7F,2D,80,34,6E,BA,7A,22,05,F3,D1,1E,36,DE,9B,11,A7,39,BC,38,0F,07,52,CE,15,80,C4,A9,4C,54,39,EC,E8,6E,84,4D,2F,31,E3,B3,A2,1F,23,82,EE,4A,8D,BC,27,88,BC,80,5E,3D,C2,D1,15,15,90,FD,27,09,6A,38,AA,60,21,08,83,D3,54,7A,7D,90,4E,FB,BE,88,61,B8,E8,6E,93,D2,AE,13,45,DA,A4,33,FA,19,97,B5,5A,AD,69,FE,F9,65,57,6B,38,B5,E4,95,D3,7D,33,3B,A1,7D,21,61,45,10,A4,62,C5,3E,82,FE,0C,F7,BB,F9,AF,D9,E1,00,D6,94,C5,5A,41,A9,99,A2,51,AD,BB,19,CC,9A,EF,43,C8,93,3F,77,0C,6A,60,85,A6,C4,48,79,A6,82,24,7D,5F,C8,89,62,3B,35,AE,1F,1D,63,26,87,3E,06,FF,0E,19,16,78,69,2D,43,46,80,F9,AA,C4,76,19,6B,D7,B0,54,46,CE,CD,1F,B7,BE,7D,05,55,FD,82,70,9B,B6,31,62,84,24,39,7B,10,4D,89,1E,1D,4E,3D,26,CD,74,42,3C,01,EA,9C,19,22,44,45,A7,60,5F,39,2C,D3,01,96,85,43,B2,48,DD,EA,8B,DD,18,C9,38,F3,36,7B,2A,46,78,73,8B,DE,6C,D8,80,3E,48,2C,06,98,E8,A9,EE,FE,21,32,70,61,DB,C0,20,C4,15,B8,B8,9D,51,1C,92,1D,87,A2,C7,E6,56,DD,61,BF,27,37,F8,D4,4B,57,74,24,42,AE,0E,70,9D,D2,46,1B,75,4D,01,DD,7E,B9,0F,E4,0D,37,2C,3F,05,FA,62,F3,C1,B9,D3,A5,AB,04,A5,8E,76,64,78,E2,EE,7E,C8,3C,63,95,93,5D,E4,61,52,B6,99,DC,F7,F2,B0,33,4C,80,D2,B3,F2,C9,C9,0F,58,FB,AC,8C,C1,55,B6,C3,57,3A,A1,52,2F,D7,9C,FF,F2,92,22,E6,EA,87,CE,AA,2C,8B,6D,B4,F4,34,FA,DD,40,32,D3,44,40,F8,89,36,44,3F,6D,3A,53,DC,19,75,C7,2A,D8,7E,6D,EF,A4,7D,4C,10,E3,54,AF,5F,9B,F6,5E,C3,3B,B9,F5,ED,18,20,61,35,6B,71,7D,E5,89,D9,60,99,39,12,83,FB,38,00,D0,23,F3,80,BB,C8,B2,9D,5F,81,92,61,94,2D,50,23,21,50,81,FD,A3,7C,F5,BA,EB,6F,1E,2B,2A,10,4C,49,BE,ED,CA,66,59,AB,3A,C5,18,01,43,BF,87,68,22,A6,3D,5D,D0,7B,12,C6,6A,AF,E6,33,01,ED,E6,68,2A,C9,BE,B2,8C,22,68,25,97,15,AC,2B,99,9D,F7,62,AA,FD,5E,DC,16,45,0F,C2,64,4E,4C,7A,97,63,54,D2,9B,F0,EA,AF,FE,FE,82,24,02,60,4E,B5,F7,8B,2A,3D,78,55,91,21,D3,5F,FD,59,D0,FE,C6,00,AA,4D,68,3E,12,14,2C,D0,8D,53,1A,1B,3C,74,68,A3,F2,66,D7,2F,29,46,14,46,77,45,DF,FF,DB,C7,D5,31,F2,FD,FF,07,6B,54,73,27,81,AF,3E,01,BA,FF,3F,28,D6,FB,E7,9B,A5,2A,7E,AE,22,EC,33,8D,92,06,30,A0,58,A8,C1,B5,8B,C8,F5,14,12,9D,B8,1B,7B,CC,DD,BB,19,EE,6F,ED,C4,5B,DC,83,EE,37,3C,EE,C9,9F,44,E8,FF,F5,36,D4,91,3C,7E,EF,C7,A1,44,76,2B,F2,1C,00,27,92,7B,1E,76,12,F9,06,CB,F3,D4,06,44,B0,54,25,16,B3,14,99,C7,B8,88,42,EA,D7,56,DD,E6,AB,8F,ED,CB,7D,6A,6D,3C,B4,51,C1,61,66,2E,3B,31,BE,D6,1F,0B,EE,1C,69,CF,0A,81,F0,45,74,04,93,CC,90,5D,34,6D,FD,53,1B,A0,CA,7C,2A,5C,30,29,B5,CA,49,95,D7,BC,4B,55,F7,94,76,03,0C,F3,8D,28,16,2C,90,7B,6C,B8,00,F1,FB,C9,3A,64,1D,D0,CB,D3,BF,9D,64,53,73,80,C7,2C,B8,23,9B,BB,3E,E3,AB,C5,72,09,1A,5D,A3,DC,5F,16,14,A4,1B,FF,D8,B5,41,B3,57,4D,30,E1,E2,E5,20,80,2B,A7,BA,94,8A,5E,D4,89,C7,08,31,58,74,14,46,04,C1,7A,96,C7,BC,E8,16,C6,D1,35,54,A2,8E,A2,EA,41,E3,02,A1,61,84,A3,FD,E3,21,89,8D,01,E2,1C,08,E2,53,C3,DE,00,D6,AC,3C,92,A7,3A,65,7E,95,39,C7,26,DB,EE,9D,A9,7B,AC,07,78,80,2B,EF,56,31,BF,E4,E3,C3,84,4C,35,E9,70,29,89,A5,65,1A,CA,18,E8,9B,6D,C1,26,28,89,83,04,87,FD,18,3B,EA,E1,0C,02,51,30,D5,2B,11,13,71,D6,20,FF,B9,B2,30,CF,6B,16,BE,C1,29,CC,BA,1B,F9,6D,D8,77,91,20,A4,9F,1A,16,C0,3F,FD,24,DD,0F,BA,FB,1B,68,38,A7,78,F4,55,1E,CB,CC,53,20,AF,2F,4E,91,2B,3B,C8,D5,E3,99,9A,A4,39,AC,5E,2A,70,81,A9,04,F2,54,8C,A3,6E,1C,1B,5A,0D,74,F8,8B,FA,19,D8,C1,4D,5D,2F,3D,BE,45,10,E2,D6,FF,6D,8B,2F,76,C5,9C,A3,9F,FF,3F,1E,C8,76,76,32,50,01,B9,D0,75,6E,BA,C9,B0,8E,9C,E0,A4,3D,B8,91,E9,EE,A1,B4,59,19,6C,A1,09,13,9F,4D,2D,EF,C6,22,F8,33,2F,16,76,7E,16,39,5E,E9,36,18,82,9D,F5,95,E2,EF,65,F3,9D,49,18,D2,35,E5,96,A3,21,72,46,F3,FC,97,98,21,80,AD,4A,97,A3,29,14,E0,32,44,F8,9F,88,43,4D,80,C4,67,C2,B0,10,9E,25,DA,07,F6,EB,50,10,F8,78,3D,03,72,DA,69,A0,90,84,E1,8F,E1,C4,F8,A1,61,89,60,12,2B,BC,3A,F8,BF,50,8C,30,48,A8,34,E5,0F,2D,C0,8D,9C,38,19,9A,B5,58,52,2E,63,EC,A5,CC,24,7A,32,46,DA,0E,1E,A5,67,62,0C,5E,F5,68,6B,F0,D3,56,24,51,D6,70,40,39,B7,93,9F,1E,4D,85,72,39,2A,92,1B,E8,C0,A6,25,AE,E7,F8,6C,8E,A9,96,A9,7E,93,BF,70,C5,54,40,73,E6,D1,47,3E,C0,86,E8,77,2D,06,B5,16,CE,42,94,98,1F,44,D1,4C,82,8E,E3,3A,BA,39,A0,FD,F1,0E,B6,ED,31,5A,94,CE,87,59,55,5E,84,B1,63,3D,6F,00,68,88,42,DA,12,0D,F6,A8,94,75,1D,6B,E3,37,55,59,88,C7,EE,F6,03,18,B7,25,B0,3C,AD,90,C5,97,A7,27,9E,5D,0C,70,77,C5,3D,5F,FD,B3,69,16,9A,96,DD,45,88,A0,BD,0A,E2,12,88,E0,6D,29,69,49,94,F4,CB,4A,8D,C8,95,6F,38,2B,0A,55,31,0D,F3,2D,39,8F,F8,3F,79,E0,D4,A5,41,0A,BC,FD,42,02,56,11,38,9F,E1,1F,D6,FD,CD,7E,B9,AF,71,F3,90,E0,CD,09,DB,EB,ED,22,96,1B,DF,DF,9A,D7,53,93,4C,5B,B6,B5,4A,5F,D1,7E,DB,5B,18,EE,50,0D,8F,FF,84,DA,72,64,D9,30,A4,6C,1D,0E,4C,EB,C8,07,48,45,E4,27,60,98,CE,05,EA,95,E2,74,03,D0,0F,B9,48,DB,CE,33,2D,7D,78,BB,51,C7,AC,E2,C9,4E,33,7A,D7,EC,E4,DD,D5,BF,03,15,62,51,3F,9C,D4,E6,FB,AE,5B,C1,4D,4B,B0,5D,CB,68,94,82,8E,59,F5,F2,A5,A8,15,1A,F6,C5,DD,DE,4E,55,96,90,E4,7C,53,9D,31,C7,6B,6A,96,DA,56,B1,9D,17,1A,D0,35,EC,2D,AE,14,B7,D7,E1,C2,34,10,0A,E9,47,46,42,E6,B6,D5,74,DC,EC,C1,4A,BB,A1,9F,67,50,9B,AE,85,B9,1D,C4,01,CC,10,47,B7,5F,BA,26,F6,35,45,49,37,BF,9B,08,13,9E,9D,01,4D,95,E5,BD,15,14,77,73,6E,53,01,8A,5C,31,52,11,9D,9F,00,65,39,F0,93,DC,7C,B6,3A,89,00,6A,22,47,BE,E3,21,F3,B7,B5,B3,80,4A,3F,C7,CC,ED,F8,69,D3,0A,AB,E8,04,5E,80,20,B6,09,88,E7,F7,7B,53,2A,B3,FB,C8,E8,A1,BC,FE,D5,1A,EC,F9,33,0E,7A,E0,DF,FF,25,C2,0B,1B,ED,E1,5B,41,A3,E7,EE,3F,96,F5,36,14,0C,E5,66,49,7D,CD,91,01,8B,E6,DA,D2,16,1A,67,C7,FA,C5,A2,CE,47,CF,3C,71,4B,98,E9,8E,A7,DE,64,A1,F6,0F,C9,91,A1,D4,AF,F7,73,8A,4D,00,4F,98,8E,FA,CB,B9,36,BC,B3,F5,25,8C,03,C2,16,C3,DB,14,90,96,64,26,3F,A4,03,6D,0D,2B,9C,98,FA,56,60,ED,59,48,04,E6,07,CB,6D,60,AB,3F,22,8D,61,B5,2C,DB,FE,4F,10,C6,CB,24,92,EA,EB,12,47,97,F7,90,4E,C5,C2,D2,E2,D5,E2,9F,CD,B0,CD,CD,61,AD,5B,B4,4B,67,6A,F9,2E,69,3C,42,CF,52,84,84,12,50,56,48,BA,D2,4F,77,94,36,46,5A,19,67,CE,19,B1,E8,82,CF,AF,D5,B3,55,A6,46,11,25,41,A3,DD,4E,B0,21,D7,63,37,45,4F,C5,EC,45,80,0E,E6,A8,9A,46,FA,9A,57,11,FE,6C,C1,14,35,48,4D,EF,0A,3A,A0,13,A8,2C,3F,FA,55,C6,94,AE,D0,CD,54,19,E2,D4,A9,8A,5D,22,DD,4C,17,A4,02,EB,8A,C1,C1,87,3C,7F,5D,B6,B7,B7,46,A0,6D,6C,1C,50,44,00,CC,01,27,95,5B,A3,18,24,6C,27,48,41,48,A1,1B,AA,58,BB,A1,5F,CC,15,AB,2F,71,A5,F0,0A,B3,6B,77,95,D1,5A,CA,4C,D9,BA,09,00,F1,EF,60,64,07,FA,39,69,FA,A4,54,20,E8,D6,F6,55,6C,E5,03,1C,BB,A7,C7,D6,D2,E8,D4,F7,E7,38,FB,B6,9B,00,EA,D9,EC,33,DA,45,82,BB,B1,2C,88,ED,E9,5A,88,F0,15,F8,B9,A3,33,5B,5E,8A,F0,7D,9C,F6,C5,E7,ED,9F,40,7B,B6,1D,AF,C4,7C,4A,FA,0F,86,47,F4,EA,C6,BC,3C,92,6A,9A,45,26,AD,95,23,B7,1D,70,C5,D6,7C,66,ED,43,DB,A2,74,B3,DB,48,61,A9,67,89,58,27,37,C8,79,D1,14,54,EB,1E,B2,31,A8,31,36,42,16,DE,0E,49,06,F2,0C,F6,9B,CD,14,A5,78,62,10,68,EB,57,E0,CF,58,81,B0,72,B8,03,D1,AC,DA,BB,14,58,55,8A,13,1B,03,60,0E,8E,85,BD,0C,6E,34,76,5E,E3,05,DF,BF,E2,12,C4,57,A0,54,D3,63,EE,8A,B3,6B,DC,54,65,0F,B0,A2,38,2B,3F,69,30,87,BC,39,F8,3D,B7,16,49,86,53,DD,AE,20,E3,BF,9A,F6,12,E2,C2,19,25,87,49,FB,C0,14,D0,4F,13,54,F8,98,54,2E,63,14,0D,60,E1,BC,01,F0,6C,0F,EF,19,36,18,A2,2F,90,FE,D0,F7,1B,C7,00,D6,0E,90,8F,E2,70,1E,A9,A7,AE,F7,13,3C,AD,95,04,10,E9,A6,8B,6B,C2,8F,92,E4,F3,F2,CA,27,4B,16,A5,55,1A,78,CE,10,B4,0C,70,2D,07,27,88,7A,30,D0,37,9E,9C,E1,3A,73,EA,68,EB,2E,96,5F,66,76,85,7E,C5,DB,E9,E7,72,EC,E7,21,E2,13,7B,22,0F,AA,09,3A,72,DD,60,57,B0,14,6C,43,B8,37,AE,E6,F3,C7,16,76,1A,8B,1D,1E,2E,27,3F,E6,F6,C1,A4,C6,12,B9,9C,1D,69,36,0C,56,99,70,CE,15,D8,02,69,3D,96,13,4D,E5,50,67,B8,E1,87,19,E0,5B,76,CC,33,57,C4,7E,D6,3F,E8,BE,78,39,0B,A9,8E,5B,E1,51,34,E3,FE,00,65,19,C2,F7,C3,FF,29,C9,0A,08,64,A7,03,3A,05,81,E6,E7,CE,EE,24,D1,1B,AF,51,17,AC,E7,DE,7B,57,32,BB,A3,D1,68,5D,3A,9F,45,CA,71,DD,F8,05,F1,D2,82,7B,76,68,84,54,18,7E,9F,DA,73,F0,98,BC,74,88,D2,25,6B,58,BE,59,86,96,0A,C4,50,5F,47,E5,32,12,43,35,F3,9B,41,C5,B9,D0,F1,2A,40,93,12,BC,72,50,2F,11,F1,89,0B,E6,E4,F8,3F,68,C3,F9,6D,98,B4,C3,92,FC,84,28,14,6C,21,15,B2,23,A8,03,5F,54,02,2D,DF,AD,E0,3E,D2,05,08,52,96,94,82,3C,A1,A1,18,EA,99,D9,D4,4E,88,0F,F1,E8,BC,AE,CE,6E,42,7E,A9,0F,2A,B9,91,4C,A8,D3,8A,A0,63,71,28,19,02,82,4E,D3,C0,CB,CB,A8,79,45,D5,94,1C,C3,FD,B6,04,2F,D6,23,73,FC,B8,FA,83,F8,19,03,CE,F7,3F,F9,CD,52,81,0F,1A,35,C9,EF,75,06,E7,46,68,03,01,42,8F,B4,52,4A,FF,F8,79,75,9C,E6,05,7A,C7,96,AB,72,82,72,B8,53,2E,D1,6B,D8,FA,BA,65,4A,1C,4F,5C,47,B9,F0,FE,63,C9,AC,35,21,5B,42,E0,4C,EA,21,77,3B,7B,24,2E,76,20,21,82,C3,59,69,6B,5A,D8,17,48,2D,74,A9,51,1A,F6,96,05,88,D2,A3,BB,1F,CB,41,6A,3F,50,A1,B8,06,0C,14,FD,9C,4D,BA,27,22,04,CE,8A,DD,0D,29,A7,54,E7,8D,AC,F6,4E,0C,8A,81,FC,18,A8,08,CE,41,EB,65,49,32,CD,74,1C,1C,11,35,E4,E0,21,CD,EB,FC,84,52,E2,A9,B4,78,EE,D6,C3,C0,35,A1,53,2F,E1,0E,36,7E,33,17,38,3D,29,CF,01,1E,F0,FF,E5,48,69,B8,17,C8,A8,10,FE,DF,31,E0,6A,66,38,3B,8C,54,65,5E,14,E3,34,55,34,69,90,6C,61,22,95,69,83,5E,5B,BA,55,BD,ED,09,CE,D7,7A,12,17,87,2B,4C,1D,89,82,1A,C5,55,6B,47,44,5A,31,22,31,6A,F5,FA,1E,DD,95,00,A1,8C,66,64,0A,0D,62,2D,08,B9,B2,6E,59,2D,F9,14,59,11,16,82,A5,3C,31,C0,89,AC,DB,F0,D6,FB,17,5C,2C,A4,2F,68,81,5F,F0,EC,DF,9B,83,F5,1C,C5,63,44,51,E5,37,85,A4,5B,6D,2A,32,D0,27,89,EB,CC,96,BF,40,83,DF,D6,09,1C,25,7B,90,E3,CD,C1,4B,4F,D7,D6,C0,28,E4,E4,F8,A7,2F,BD,5C,E5,B3,C4,3B,E5,E7,F8,56,FB,FC,AC,56,48,EE,39,8E,E6,DE,D5,69,57,99,BD,E4,62,B3,16,1B,32,B2,65,00,3C,F2,1A,21,E2,3D,60,19,8D,9A,5D,38,67,96,4E,FE,20,8A,09,92,B3,A0,94,88,42,89,56,21,DE,12,AD,C3,20,92,16,55,E8,18,47,B5,5A,64,19,6F,8B,DA,05,9F,74,E7,F5,1E,46,6C,BF,41,2F,9B,22,19,9E,57,5A,2F,AC,99,DA,07,B9,D2,F0,FA,6B,FE,68,D9,2F,D9,D9,A6,D4,71,A4,EA,E5,66,2E,90,3F,11,CE,4E,2A,80,8F,46,98,D0,B8,24,99,3D,C0,A0,61,C7,0D,6A,1E,6D,D6,2A,D1,33,0B,34,84,EB,76,0D,91,F1,63,E6,9E,86,89,05,E9,4D,E0,6A,F8,76,14,BD,49,F7,44,4A,64,D6,C9,8A,3E,00,2C,16,93,31,2D,26,33,4D,03,A6,1A,01,D2,59,56,B9,AD,CE,E6,C4,C0,E8,AC,BE,95,AF,42,DB,5B,D8,48,8F,86,8E,21,7B,E2,29,F6,83,70,E7,0A,30,06,A1,75,00,02,68,16,C2,37,4C,3D,2B,2E,23,D2,49,E5,E7,6C,07,41,04,99,14,85,B8,DB,23,D3,67,F0,B9,C9,44,F9,92,8E,C4,0C,CD,1D,2E,49,56,16,B1,81,07,65,2F,1B,69,55,EC,70,E6,CF,BB,92,25,C5,F2,E0,4D,09,5D,E8,47,5D,12,76,66,ED,50,85,DC,32,5E,6A,53,EA,BC,23,70,7C,F2,44,9A,F8,AC,00,80,D2,F3,FB,A5,0D,63,5C,11,94,6D,FF,48,B9,C7,5A,7C,E6,B8,74,69,5E,49,34,C0,4A,D7,D0,82,76,6D,62,A2,2B,35,4B,20,DA,B5,2D,00,AC,65,10,6A,FF,59,C8,14,90,5A,ED,C4,DA,32,B5,92,98,D6,5A,4F,51,6D,51,32,E9,B0,85,39,93,9C,50,F5,BD,C3,0D,48,50,D5,03,B4,E3,38,9A,93,C3,CA,1C,9C,33,3F,8E,DD,05,04,92,E6,D2,C6,F1,BA,C9,59,14,85,C9,5E,CA,FE,57,81,04,DB,F5,3C,48,4D,B0,60,5A,3C,A0,ED,84,5D,9F,5B,7D,E4,B3,AA,CA,26,99,D4,B7,05,6C,29,D4,2C,C0,D2,4F,F6,B8,F8,7E,89,A7,3A,82,54,A3,52,4B,4B,B2,4D,F5,4D,E4,7D,CD,3E,F4,03,18,B9,9C,ED,01,AD,93,07,C7,3F,EC,51,75,10,B3,63,FC,06,B1,F1,50,44,7C,B8,4E,D7,E2,33,54,7D,8D,23,9A,73,8A,CF,AA,36,43,60,D1,FE,1C,DD,D6,F3,35,C1,16,AD,46,29,E3,1E,14,BC,58,8F,F8,B7,35,AA,C8,FB,83,43,A4,A8,EB,E5,CB,FF,2B,A7,06,82,9E,6B,9E,FA,34,BF,F3,11,EB,0D,A3,09,AB,FE,11,ED,7C,3D,B5,C5,53,CF,DB,27,C7,13,D3,01,14,90,F3,E2,CD,37,A6,64,7A,C4,4B,43,CB,FC,6C,C9,C3,D0,0B,EC,03,8D,49,3A,DB,58,04,8B,FC,70,96,FE,8C,F9,58,A6,3A,4C,DB,75,DA,07,AD,75,A9,F7,B3,39,8D,A1,12,D2,8D,79,80,B1,25,BF,04,1B,9B,5A,07,1E,2F,69,A9,48,95,E5,AE,E0,11,A7,E2,C5,AD,B6,E8,13,D8,CA,66,A9,CA,F7,D0,66,73,D7,63,3E,33,78,55,DF,2B,21,06,59,FB,29,23,17,6D,89,2E,9B,81,83,0C,2B,9C,C2,E2,15,CF,F3,06,14,C0,14,CF,A8,DF,D8,76,B9,BE,73,7F,D5,BD,F8,20,65,72,CC,3A,F7,EF,E6,F5,A7,ED,AB,7A,E3,40,8C,E4,82,E6,14,A9,BE,18,A2,48,B6,9C,65,82,44,48,5E,9B,69,F0,F7,FD,A3,59,57,EB,77,C3,FB,97,F5,EE,09,66,08,41,BB,23,85,43,CE,D9,54,32,0F,04,D5,8B,0A,DB,5E,8A,FB,63,CA,CC,46,E5,A6,51,C6,43,52,FA,62,DA,AA,27,AA,97,5B,80,4F,BB,32,36,6D,51,C7,85,46,FA,7E,2B,A9,CD,2F,15,3A,D2,3F,68,91,53,D7,11,50,0F,67,1A,F5,C2,10,A1,B9,E3,8E,7D,E6,7B,5D,00,92,CB,2B,9A,1A,0E,95,3C,80,3B,C4,F1,7F,07,BD,C9,90,F5,42,CC,D6,35,E2,AA,5F,A9,C9,BE,D0,CE,CE,AF,55,3A,27,80,78,7A,33,1E,E0,76,B1,7B,2D,55,61,C1,39,DB,CB,6A,97,05,EB,E7,8A,2B,EC,20,FD,04,1B,E7,0F,DA,4F,13,03,60,E7,43,C5,DA,CB,8F,3F,D8,E0,3A,6D,0F,4A,59,52,31,29,25,CE,9C,7A,39,C5,2D,C2,98,61,1F,DF,80,AF,57,26,2D,F3,FB,01,4A,7E,9C,6E,9C,DB,5E,B1,A0,0F,41,F8,59,F5,DC,76,3A,CD,19,95,60,4F,5F,12,A6,DC,76,D6,8E,24,B8,06,79,87,D4,95,46,BB,E0,AD,2E,E4,99,25,66,F1,FC,1F,48,51,4E,B3,A2,4F,BF,21,93,E7,C2,FA,E9,42,B1,72,82,A6,74,70,62,D8,1F,A3,44,77,96,23,42,61,DC,7C,F4,EF,3F,62,68,52,F8,E3,4A,BC,4B,C5,61,68,05,44,C0,09,E8,F6,38,81,F3,EA,58,B8,24,78,E0,28,95,9E,59,0E,29,26,84,FC,8E,23,20,30,75,36,95,52,1B,80,3E,5A,9A,74,5E,62,A0,1A,EF,47,BB,FC,43,54,3B,76,94,6C,7F,5B,1F,2D,6D,54,81,89,99,34,04,94,A3,8C,DD,F6,8A,D2,7C,17,89,9F,E8,BD,DC,F5,B5,41,53,90,CF,2A,7C,AF,C8,18,7C,38,E6,0E,5D,F4,86,4B,B5,A1,4E,E3,DE,DF,43,08,4E,74,49,D4,AB,42,EF,5F,C0,E8,E2,85,77,5B,F7,12,6B,21,13,81,00,3E,4F,4E,4D,90,50,E5,49,D5,F4,7E,AC,CF,9D,05,7C,32,8E,7F,30,B7,B6,A9,21,E4,51,79,17,57,87,82,B3,B1,60,03,09,5F,DF,63,7C,0F,C3,66,0E,4B,20,DC,C0,62,7C,28,D0,EA,75,5B,2F,AB,C8,72,CF,07,B3,A9,40,50,27,6D,8B,E8,C7,0D,D5,31,53,48,F6,CE,24,DA,4A,6E,1B,C3,AC,70,62,97,95,02,AE,55,50,CC,73,3D,CB,DF,1B,1E,B3,C2,9B,D0,26,52,62,28,31,03,49,33,B8,44,B1,A7,9E,23,12,29,9A,34,02,46,A7,31,68,2D,99,23,AC,46,94,80,88,99,CF,B1,D7,51,3E,9A,83,B1,04,C3,16,B7,A0,10,0E,C2,F7,2C,6B,92,3F,A7,0F,8D,24,C1,3D,87,32,BC,FA,27,37,2D,BA,94,20,CB,C3,0F,A3,B5,F6,07,C7,49,6C,2F,72,E9,16,E9,D8,CD,21,54,A6,2B,CB,E8,85,C4,95,12,29,B9,EE,CF,49,97,1B,0E,A6,75,CC,50,B1,53,1D,8D,E8,82,5B,0C,3F,33,A1,17,1F,5E,CA,A9,90,C9,28,E6,7C,86,28,E1,56,37,E0,F5,77,63,A1,66,FE,59,33,1E,1C,54,F8,08,3C,D2,8B,51,27,C0,9A,F1,96,5E,7E,1F,A8,FA,AB,FD,96,5B,1C,99,32,25,86,6D,B0,4B,B0,0C,B3,B0,D2,AA,C4,AB,07,8B,B9,E2,0D,7F,DE,9A,A6,8A,A2,B4,A6,DA,A3,88,F4,79,75,0B,2C,24,BD,52,F4,12,33,DA,42,BE,4F,8C,69,A5,AA,E1,F2,A2,CA,0F,C9,1C,19,09,30,50,C6,F4,82,88,22,73,AC,75,69,4E,E8,EF,64,96,E0,43,10,82,13,35,A4,94,AD,2A,DB,40,4D,82,82,A7,5B,0C,E3,8D,96,DC,EC,BF,A3,B9,8E,79,2F,04,8D,F5,B5,9F,32,9E,CE,21,55,65,6D,0B,26,10,C8,DA,6C,78,EB,55,DD,80,63,99,D0,89,4C,99,E9,51,74,0B,67,56,2D,08,12,C9,E8,81,F0,40,36,13,73,F1,58,03,C5,DC,05,7F,0C,BA,D4,51,24,C6,4B,EF,7C,35,EA,6E,36,B0,7B,AF,86,7A,5D,9E,D4,8A,EB,A7,64,4E,8D,6C,8E,31,3D,AF,4F,7C,4B,81,72,F2,05,41,2B,DE,3C,1D,18,24,92,71,57,4A,0D,30,FA,5E,20,75,8B,36,0F,59,B9,6C,76,D1,69,7D,23,97,0F,71,40,AB,56,2C,54,C4,C0,53,0F,E9,64,B3,89,1C,8F,10,10,BF,49,8C,7A,90,E0,80,98,99,BE,81,53,3B,A8,E6,25,AD,0E,40,E6,45,D2,B1,1A,B4,CC,4A,FD,1F,7A,61,A6,78,CE,FA,E6,DF,31,52,EB,BD,A5,06,E8,75,C8,4C,B4,46,3F,EE,03,2C,91,3E,7F,9D,87,5E,A0,FA,4B,65,BD,89,EC,67,C0,25,69,DA,FB,68,8E,F5,90,30,F5,C7,C9,2F,47,31,47,56,FF,9B,D8,53,67,1A,96,09,8B,84,8E,A3,CF,DC,BA,E3,10,3C,0A,19,E5,71,F3,CE,13,F0,CE,04,72,82,25,BC,BD,7A,AA,65,41,DB,0B,FD,28,25,3D,76,1C,8B,42,C2,6D,5D,92,8C,86,EA,40,D5,B5,5D,83,07,03,8D,AE,26,28,E1,4F,9F,7C,A2,A8,72,0D,9D,F7,84,8D,B6,EE,AE,5A,D5,73,D8,45,01,D4,50,40,D9,4A,82,7D,21,59,56,03,7E,D9,B3,FA,3C,D0,6A,05,A5,FC,63,DD,2A,1D,E3,CA,0A,65,7B,37,60,F0,C9,F7,05,CB,8D,B1,59,03,42,EC,6B,6C,97,31,B5,DF,21,F3,34,31,7F,50,83,01,79,50,34,48,37,D8,44,C0,47,50,04,5A,97,37,9F,10,7A,C2,78,15,D1,F4,87,94,D5,45,65,17,B1,7E,5B,07,81,DE,90,A5,6D,F9,69,5E,CF,4A,E5,B2,84,1E,4D,43,A5,68,E8,A2,59,F3,B0,DE,85,DD,0C,4E,B3,95,B8,28,E9,BB,9E,C1,D8,59,85,E1,3D,2B,75,04,DE,BE,05,0F,96,14,95,18,EC,77,5B,2C,D1,93,D2,6A,64,6B,36,37,F5,86,26,21,2E,CD,DB,B3,06,31,8F,6E,85,6C,A2,E2,82,B0,61,4B,15,9C,79,9C,8F,52,54,0A,2E,09,EE,A9,BE,5B,01,AB,75,C4,76,77,EB,20,26,BF,06,00,0D,9A,C7,DE,3B,87,A7,86,32,BE,67,1D,10,3D,FC,65,A0,42,F2,A9,0F,45,F4,7D,AB,8B,7C,5E,C8,0D,C5,5C,0A,C2,90,AB,C9,43,03,54,68,75,13,F2,21,97,1F,7D,CF,00,86,62,54,40,B1,32,4F,1B,98,C4,D0,37,18,9C,5A,7C,27,C1,CE,B5,C3,63,1D,9F,D5,13,64,C2,6F,65,97,6A,3C,34,DE,4B,DA,2F,FA,9E,7E,5E,97,7F,64,9F,FF,2D,AA,2B,BE,8A,DB,1C,78,41,C0,6D,0A,3C,77,D4,A3,C4,1F,6E,B5,D8,2D,27,C1,1A,F3,14,BD,1A,4A,C8,95,D1,9F,DA,8E,0C,78,89,A3,44,79,0D,7A,D4,3F,74,B7,A8,29,7A,D1,09,76,FE,3C,F8,12,22,06,6A,F0,A9,11,E1,0C,3C,5F,48,8E,7F,E8,17,88,C9,C7,D9,24,8E,EC,3E,5F,3D,30,9C,24,DE,0C,4F,EA,1C,87,7A,27,F4,8F,23,16,57,3E,85,63,7F,D6,E7,5D,B9,31,A7,36,B6,95,49,9A,63,2A,D7,DE,D8,86,FF,AA,C3,87,96,34,54,F9,F7,A2,75,03,02,07,28,F0,3D,ED,E9,0B,A6,84,F2,35,33,81,6F,0B,B0,F9,0B,7C,55,F3,9C,A9,6D,E0,7B,9E,64,EB,70,C0,CF,96,83,06,8C,90,EF,59,C3,C0,7B,F7,BA,CD,BA,DB,A7,F0,2E,6A,77,58,BA,8F,18,71,3C,A9,A9,C8,A6,BF,AB,E4,8D,C7,6F,10,12,96,69,0B,08,02,BE,32,D5,71,78,29,9A,51,8A,A2,EF,7D,71,6A,C0,C7,E0,07,2B,B9,AC,DD,49,12,3B,8D,39,21,73,AC,8F,D0,96,5F,95,5F,37,18,C0,9B,F3,79,7E,21,07,A5,AF,4C,F3,B0,2C,32,11,F0,5E,D4,CB,A8,04,F6,69,48,65,88,61,AA,A7,ED,6F,04,5F,C5,94,0C,A3,5F,E9,59,43,D0,6F,44,D5,38,E4,6C,31,96,51,5B,F8,23,DA,F4,DB,22,C4,37,11,78,68,7E,BE,4E,1F,8F,D3,4C,26,11,0A,B9,BC,18,F9,21,C2,30,62,3F,9F,63,E6,80,9B,41,E9,A3,5A,11,AA,5F,48,E0,24,B5,20,47,DE,07,9B,66,D4,1F,BF,BF,1F,74,78,06,ED,A4,1F,19,E1,C6,29,D2,AE,8F,04,E3,5C,FA,9A,8D,3A,18,56,B3,72,76,60,7A,7E,69,0A,B9,A3,59,FF,EC,0D,0D,29,E3,6C,48,6E,65,CF,2D,87,F7,24,EB,29,02,2C,16,AC,E7,6B,66,11,0D,1B,FF,39,CF,48,5D,FA,0E,F0,9F,72,46,27,87,A7,44,65,C5,6B,21,3F,18,79,5B,42,8E,45,AE,FD,77,35,DF,F0,E4,10,23,6E,6B,09,F8,E4,EE,8E,C1,85,4C,7E,43,EC,E3,DA,86,3D,4C,90,D7,3B,61,71,42,3E,1E,69,8D,98,88,D8,52,F0,D9,50,18,AB,78,8D,C2,AA,5F,BA,D6,DD,34,A7,7C,9B,5E,8A,62,63,90,42,D0,97,FF,C7,8D,FB,30,81,74,F0,3A,4D,3A,52,BA,43,40,CC,F3,9F,A4,B2,06,C9,E2,0E,BD,8F,2C,0D,84,40,E6,41,2D,71,90,69,4F,CA,43,CB,84,E8,38,27,8B,C0,AF,8D,F0,8C,49,17,EA,BB,BA,1B,EF,46,A3,A8,7E,B9,72,61,68,22,91,15,FF,6A,55,70,95,6A,E9,11,E0,88,99,D1,C6,7F,03,4E,80,4D,EA,D7,32,DB,63,8B,EB,EA,85,DC,EE,35,E9,6C,15,70,2E,26,89,24,87,3B,4B,86,47,CD,C4,E7,CF,46,5A,7A,7C,36,15,FC,5A,CB,E3,04,1C,F4,41,97,5E,D0,4C,63,E2,DF,AD,09,D5,C7,B1,27,46,50,7B,25,2D,7A,F1,55,2D,07,EA,A3,D5,16,74,77,67,F1,AD,98,F6,79,3C,12,BE,DE,AE,E3,B0,B0,04,3B,3A,35,12,19,8D,7B,B0,E2,ED,60,1F,BF,F6,BC,06,CA,E1,A9,A5,4B,34,FA,EB,63,CA,4F,DF,06,62,5F,38,40,0F,58,18,60,08,27,99,F3,D3,DA,37,0B,42,5B,81,B0,30,D1,12,3F,DE,F6,1B,AD,5D,E9,50,5D,F6,CE,8F,3A,5C,3D,A6,EB,C6,50,EB,08,F4,03,22,7E,F4,9B,9E,33,9B,A4,B2,E1,B1,BB,F7,92,F3,52,24,05,95,48,A9,5C,63,90,FE,04,8A,68,49,42,B3,62,77,5F,C9,AF,95,BE,14,D1,AB,E5,1B,31,E0,B1,10,6B,A9,49,55,80,7C,4A,28,56,D0,C5,E5,43,ED,95,FB,68,CC,BD,5D,A5,42,A8,A1,F2,FC,A0,E4,1C,34,67,07,EC,9C,3D,22,DE,7B,61,57,9C,57,3A,C3,9C,F3,52,42,92,81,B2,2F,80,E3,1B,08,8B,B0,06,77,EB,4B,AA,F6,13,92,28,67,79,BD,57,9F,71,05,D6,F2,9A,B6,C8,53,1B,97,D0,A4,FC,BF,DF,61,3B,50,72,6D,C0,3F,66,55,07,F9,BD,5C,E4,B1,07,85,53,EC,37,AF,06,0C,3A,93,12,09,1A,BD,94,BA,AD,63,C2,12,4C,A0,BC,83,2C,2E,44,86,37,1B,6A,F4,36,14,2D,21,B3,4B,15,17,14,7D,05,CA,14,79,21,3E,49,14,3F,67,3E,FA,C5,BA,92,17,7B,05,A1,6C,EE,26,A1,75,57,F5,36,DD,5E,08,81,2B,4B,43,76,84,81,79,AD,EA,46,C0,DC,82,49,4F,CB,18,A6,F3,1A,4C,51,77,D3,C7,BB,C2,CC,9F,E3,A9,17,45,87,CA,23,72,99,71,49,2A,F8,95,8A,C1,EF,01,1E,0C,C9,C1,E5,DC,93,38,F4,6A,5B,59,B7,E3,77,76,F2,D9,D1,21,34,ED,40,05,7C,B0,FE,C5,99,D8,69,D7,F3,D0,4D,5B,B0,9E,6C,81,01,99,3E,65,FD,C1,E8,F4,6A,16,A0,83,CA,5C,61,92,01,B3,8B,0E,C9,4C,0C,BE,30,55,AF,B1,F5,B1,5E,39,02,E6,C2,80,BA,1E,00,51,18,2D,88,75,A8,8E,CC,0F,CF,41,67,C8,1D,01,E8,32,42,56,71,77,22,F8,2A,7B,61,E5,C6,A5,21,51,00,57,4C,EB,80,07,04,E6,12,36,46,38,4F,C0,EB,A8,80,73,03,91,51,C2,E9,6B,47,51,B9,96,D9,7B,FC,1D,5B,6E,8C,00,C1,F4,09,0F,59,D9,00,3E,78,A0,65,74,43,EB,10,2C,26,A6,13,6B,DF,FA,6A,D5,5F,09,87,59,1E,75,B0,68,E6,9D,7F,78,97,2D,6E,E2,53,2A,10,01,20,89,57,77,A1,C7,FA,C8,3F,B2,4E,24,C2,78,A0,55,34,74,55,FF,65,E8,06,71,E7,D2,A5,4A,30,BD,BA,A3,88,E9,9D,44,76,67,31,D7,38,1A,E9,12,72,E4,4E,23,4D,55,08,9D,F9,20,35,B6,D8,44,66,61,86,4B,72,E4,D8,CA,D4,A3,84,C0,1B,A3,F6,CA,28,5E,AE,A9,D2,93,E9,02,F6,0E,6F,A6,5E,A8,A5,FD,24,99,19,11,02,E1,3A,02,A3,E5,FB,95,B1,CC,17,4A,B5,E4,28,92,17,03,B2,9C,06,D4,9C,94,13,77,BB,52,47,AF,F0,88,34,19,F3,94,FF,94,4D,14,0E,5C,04,F5,7A,BC,51,DB,0F,9D,14,03,3C,1A,4A,42,B1,8F,9E,F1,87,94,37,5B,D3,53,0A,68,F5,3B,97,27,73,85,C1,DD,D9,05,BC,8E,C3,D9,4C,64,A9,F4,56,81,21,33,58,5C,E3,59,DF,AC,B9,14,A0,C9,08,D2,B9,0B,8D,D2,80,86,23,6B,B0,DD,2B,B6,75,DC,05,61,4F,62,9E,74,DB,17,D7,F9,82,1B,DE,59,DF,5E,DC,5A,5A,FB,92,BB,78,3B,CB,18,D1,E5,08,9C,B7,AB,DB,52,29,49,E3,72,80,9D,CD,48,47,02,26,19,DA,C2,30,DD,E3,8A,A2,35,DB,92,B9,27,E7,9D,4F,30,5D,2E,70,3B,3C,B0,1D,80,48,AA,9C,34,AF,63,9A,37,80,B1,8E,4D,A5,B2,C0,92,79,37,E8,05,F5,B6,0A,C8,A5,82,1F,FE,BC,7E,16,7E,F8,D3,4F,7A,25,BA,13,41,2C,9C,E5,6C,6E,A2,97,66,2E,13,6C,77,A5,DC,C0,E7,20,4E,87,8E,16,49,72,45,21,51,3D,AC,A0,5D,80,36,12,6C,90,30,4D,03,0E,8C,7F,4D,79,C0,38,21,43,DD,CC,F5,94,EC,8D,AE,DA,80,F9,94,0C,83,FC,89,AB,A9,0D,71,32,FD,12,24,35,98,91,8B,3D,91,EE,EB,13,A2,0E,E0,48,9A,81,B6,CA,0B,A1,A5,CB,DB,AD,72,45,D5,34,87,9B,EF,33,38,D0,70,3A,05,21,66,2B,E9,BC,3F,13,90,B3,DC,10,20,57,3E,51,30,C8,E8,C0,4D,C8,53,62,51,3F,84,A4,98,2A,5C,76,8A,DF,5A,E2,8E,41,90,5C,E4,B1,EF,D4,20,52,5A,74,6B,E9,B6,B8,42,CE,F0,F0,3C,3B,F5,A9,99,B3,B2,7F,72,59,C2,E6,C2,DA,CC,82,2A,52,DF,D0,F4,96,FD,5E,C4,F2,97,E8,15,D3,85,9A,B5,A2,C3,66,72,F9,90,AF,41,F3,ED,A3,46,C3,42,B4,2F,E3,98,69,42,35,9E,4B,40,6A,AA,E0,88,28,74,C8,F8,26,DE,D1,27,5D,BC,49,62,49,DF,BC,AF,D2,12,44,D2,E5,BA,A5,C2,D4,2A,DE,D7,52,5E,64,FF,6A,A0,07,E4,41,4E,37,F2,83,BB,2C,06,0E,EC,C5,13,A1,7B,29,D4,84,EE,0C,4D,6E,E1,41,10,89,EE,DF,F4,81,DD,B2,67,96,63,B8,3C,67,0A,D3,AA,81,01,B7,5A,57,5C,DB,7E,0A,8A,C6,78,8E,8C,DC,96,6B,98,06,ED,55,F6,B4,B7,8D,4C,9F,6C,CC,46,6F,DB,5F,AC,F5,4F,6F,92,5A,70,EF,C7,F3,5F,CA,9C,57,4B,E2,D6,A8,A6,90,ED,58,52,9F,30,31,FE,7F,29,65,5C,DB,C9,CF,BF,10,96,66,B1,02,6C,21,C7,3D,E8,D3,D3,62,FC,B9,24,7E,91,92,BA,31,04,42,33,D3,AB,41,99,FF,1C,62,21,31,D4,C0,59,FF,B0,CE,80,63,FB,03,03,11,EA,99,1A,25,9D,89,A3,C7,7A,99,7B,4A,6E,E0,89,85,53,28,5B,45,E3,D8,7B,27,FE,DC,8C,CD,8E,38,13,83,B4,CE,22,0E,A2,FC,65,34,BF,89,A1,C6,24,28,83,62,D9,C3,18,D6,36,E6,41,44,DC,B1,36,22,6D,5F,38,78,D9,C1,12,DB,0B,A9,CB,EE,BB,80,4E,36,38,BA,06,68,5C,B3,48,FC,6D,CD,FC,13,FC,9A,F7,21,A1,4D,93,3D,82,52,5D,39,51,84,21,91,D0,35,C3,92,99,09,CC,39,0C,1B,40,AF,19,4B,F9,0F,F2,DA,77,3E,FF,F8,67,CC,E1,21,71,74,8E,91,1F,A2,43,8A,D3,BF,D2,01,25,C0,DB,FC,B9,3F,5E,D3,4A,02,52,BC,90,2A,37,79,D9,DB,72,EB,62,2F,7C,80,D7,44,DD,07,02,FF,8F,5B,3C,8D,25,4F,76,46,D2,6E,95,D5,C7,2F,AC,85,FD,66,50,B7,EB,38,9F,F8,40,06,62,52,31,A0,46,D5,06,03,E0,FF,9C,8F,3A,A6,F1,ED,E4,0D,DF,01,F2,10,56,49,AC,56,00,73,4E,D3,1F,40,03,F3,91,3D,44,29,01,44,DC,70,77,DD,0B,B2,E4,08,CF,B2,15,C4,DF,EC,01,54,B9,8E,FF,71,BE,66,63,A0,49,0B,58,60,36,CE,89,81,65,51,6B,3F,4D,E1,57,4D,60,AC,A8,9F,B7,9C,6C,0D,37,CB,5F,C8,CC,30,5D,EB,CE,F9,BA,07,27,2B,88,DE,84,F1,66,92,27,C8,D2,83,08,F7,98,06,EF,71,DE,05,FE,7C,89,07,26,C2,1A,93,CC,B9,96,27,CC,D1,8B,A4,08,D4,62,73,2E,9E,51,8F,34,9F,93,C3,ED,FB,5E,DA,3E,A9,39,78,39,66,3F,DC,71,BD,05,26,53,FC,25,BB,78,41,07,B3,1C,59,6E,BD,93,B3,12,42,69,3E,94,6A,6D,4E,F4,8F,D8,9D,9A,B7,C9,32,E9,55,EB,CD,74,AB,50,8D,F8,9C,17,1A,6F,36,20,08,5D,FC,73,55,F6,1E,91,69,BD,72,75,F5,70,63,1F,57,9B,D1,9E,E4,56,F3,D8,DC,6D,C7,56,D6,1D,D9,BE,AE,C8,1E,1A,3E,D1,29,78,A9,9D,3A,80,27,BB,24,88,A7,1C,4C,19,5F,F3,87,D2,1C,43,20,3B,89,A6,30,F5,74,45,90,38,29,42,D6,21,07,E9,F6,E9,D2,30,59,E3,7C,27,7A,42,D2,45,E5,88,64,C6,B2,DD,53,EB,D5,77,B3,A3,89,A3,E8,0D,E8,1D,70,2B,5E,9C,45,AF,45,49,86,EA,CD,E6,71,4E,AD,FB,2D,80,0B,BB,9C,CA,3F,16,4F,3F,11,95,49,EE,5B,E5,D9,CC,31,77,18,85,9E,A1,82,46,D8,95,87,91,F0,92,A8,D4,7D,E4,3D,04,E1,14,A9,D3,C7,34,A7,C1,35,D6,5F,91,7C,9C,A3,13,4A,F8,F7,6F,2C,39,0C,EA,C1,2E,45,94,A0,39,B4,62,F0,29,B6,BD,25,24,1B,F5,EB,A3,58,F8,03,D3,7A,CF,00,E8,7E,C0,7D,92,25,33,0B,5A,6C,06,AA,29,DF,EA,2A,6E,9E,5B,36,20,AE,43,48,86,FB,E1,A0,B7,68,C0,29,81,D8,40,8F,3C,1D,49,79,0F,AD,A8,1B,A5,01,5E,0B,46,66,FE,8F,E5,AF,CB,25,9A,FA,87,61,13,09,6E,42,D2,1C,33,00,37,45,95,C8,8A,54,FF,8F,E5,4C,40,7F,5F,01,47,1C,59,5C,D4,6C,2E,5D,7C,EF,35,C6,2E,8F,1B,39,17,45,69,52,01,CC,E6,58,24,D7,32,42,45,2B,9D,98,9D,98,CE,44,DF,EC,BE,52,5A,50,49,75,CA,37,F7,44,61,BD,B7,D2,43,49,6E,BF,03,B4,45,6E,99,53,71,E9,99,01,21,12,AF,25,A6,B2,59,BF,A2,34,A1,94,DE,7A,56,A4,77,E5,18,EB,CF,7F,FD,07,BF,9D,D4,3D,62,52,EC,7A,1D,AC,D6,D7,16,E8,B7,7D,65,BE,17,E7,A3,C0,FE,C0,89,A9,F9,76,F3,D3,74,6C,47,17,80,B0,A0,5E,FF,22,C5,F6,A8,04,2F,5C,28,07,A5,4A,57,9D,FC,EB,87,13,CD,A6,24,79,C7,BE,98,79,97,01,16,66,F9,0D,76,C7,0E,73,70,0B,72,8F,57,06,87,7B,91,18,E5,06,00,3C,B0,DB,B1,7C,81,F8,D9,16,27,93,87,7D,DB,1C,15,20,43,36,7E,45,C2,31,46,CA,CB,43,D8,74,1C,A3,BE,49,EE,C7,AF,55,98,8E,61,B2,6C,14,AA,1C,FD,C3,A7,9E,A4,D8,A3,1B,71,73,33,2C,D7,A0,2B,14,0A,BB,DB,93,C8,C6,6F,51,B4,F2,B4,86,42,E0,66,4D,8C,37,CB,9A,34,7D,7F,24,9E,2E,64,8E,FB,56,5E,AA,7E,EC,63,51,60,C4,1E,F8,88,00,90,82,A0,7E,11,FB,69,73,4A,4A,24,B0,D5,7E,B5,24,40,40,A1,E5,23,8A,12,91,7E,DB,0E,F4,4D,BA,2D,FD,A7,0F,7B,E8,42,B0,66,D5,06,20,3F,8D,94,7F,96,8F,1D,C8,44,AF,F4,A3,E3,2F,80,24,30,EE,8A,90,17,A6,9D,D7,9A,CD,0B,8F,6D,9A,B1,8B,C4,D9,E0,DF,44,7C,39,CC,6A,4A,EC,6F,37,A7,47,A4,69,FD,49,2C,07,FD,2A,D3,C5,81,56,50,C5,07,FA,AF,D4,02,E3,21,25,D9,7D,D9,73,FB,36,4B,B5,9B,32,5A,A1,E0,6F,6D,07,A3,A8,A1,41,85,B6,69,0A,54,F6,82,90,DF,5C,AA,38,D1,AA,82,0E,D5,81,03,7E,80,3C,0C,21,F7,CA,54,E3,44,93,E0,FE,1D,C3,20,8C,9D,0D,A7,11,6C,B3,8C,23,CC,2A,70,AB,D5,C7,57,64,57,87,E9,D2,31,75,E2,34,0E,68,A5,43,A8,C2,D1,9E,7F,8F,74,9B,16,B8,BB,54,F5,D3,FD,95,4C,C1,63,66,9E,6F,A8,4E,05,6F,EB,23,5E,21,2D,47,F3,DA,84,9A,2D,5E,DC,B3,B3,C6,1A,EC,5A,1C,9C,BB,E7,AF,33,61,26,B2,87,39,8A,F7,43,A4,55,66,B0,D4,16,0B,50,B8,AA,B9,85,11,F7,ED,B2,BA,5A,B8,FC,9D,73,96,E9,86,9A,B1,12,96,69,7A,20,6C,EE,BD,79,AA,BF,A4,0F,4C,A4,7A,88,AC,BD,9C,5D,85,FD,6A,F5,45,BC,5B,1F,99,6F,09,1F,71,FD,AA,09,69,B2,DF,4A,2C,36,1B,19,77,16,4F,85,1E,00,5D,FF,3A,64,F9,03,3F,AF,F5,C3,C6,B7,75,30,46,1C,7F,2E,20,AE,EB,FD,67,AB,22,D9,F7,D4,C6,0E,92,21,C5,0E,ED,B5,EC,5F,B8,86,FD,EC,01,42,34,A0,7C,9E,59,F3,19,CA,65,52,34,65,5B,FE,28,47,29,36,D2,88,1B,04,E6,0C,79,FC,9D,C8,5A,8F,A9,DE,2A,6A,D5,AF,FD,AA,C2,61,26,BC,8B,89,6C,A0,A1,35,66,13,10,5C,5C,A6,F9,1D,69,F6,05,80,60,BA,7C,77,CF,1C,1B,5B,56,52,42,EC,12,57,B6,8F,3D,D1,C3,09,F4,DD,3F,B8,37,AF,4A,8A,54,D9,42,39,9F,CD,82,E6,EA,E5,73,69,E3,8E,DC,7B,FF,D2,E7,27,18,BE,23,B9,C9,FE,F1,D2,F6,7B,41,6C,49,BB,A9,32,2C,6C,F1,31,CF,49,8B,CC,A7,18,53,7F,2F,E9,1D,F4,C1,FA,9D,74,2B,1F,09,BC,28,33,A1,F6,AF,C6,8F,D6,C5,BB,55,73,DE,01,83,35,C7,92,20,A7,78,D4,76,6A,61,72,F6,39,10,06,DF,2A,3C,06,E4,9A,D4,13,ED,FE,2C,AC,18,B0,2A,F0,D4,A0,50,CF,74,D8,42,96,0E,71,97,38,E2,FF,0F,A1,48,63,23,A1,9F,08,A6,F3,6E,66,6F,A4,D0,A0,F0,74,11,C4,17,9E,36,19,FF,D6,AA,A4,DF,3E,47,2C,4A,76,0C,65,24,0B,5E,9E,9B,40,04,BA,C9,75,04,55,05,99,4F,01,FD,6D,E7,8A,04,E7,8D,F1,D4,07,D0,E2,10,CB,59,60,41,AB,31,1B,46,1B,32,93,4C,89,4A,45,36,85,B1,C3,58,EB,9A,40,B5,7E,0B,F5,50,9B,4B,A9,56,D5,F8,CA,00,29,75,8B,A4,92,E4,E2,D2,F7,C2,2F,29,51,7B,93,F5,9A,15,45,1B,F3,F7,8B,0B,A3,5F,5F,B0,9C,90,D5,56,9B,37,ED,0D,4E,BD,00,67,07,1A,2B,3F,53,E1,7E,37,CA,23,88,32,81,00,3B,A7,26,5B,64,50,A8,3B,21,D4,6D,35,15,B1,7E,0D,A0,25,E1,66,81,5D,69,AF,BB,D7,2F,47,E7,BA,B9,15,B6,91,F4,A9,4A,A7,5B,DC,26,6B,19,D7,EF,16,A3,F4,FF,F2,F4,66,E7,0E,05,4C,9E,E0,03,B9,A7,D8,4D,E5,B6,D5,FF,64,93,0A,5F,67,63,50,77,AD,E2,10,54,76,A6,2D,E1,75,6F,EC,37,4A,BA,55,56,90,19,18,00,80,D0,9D,E6,6D,EE,7A,DA,33,E1,CA,28,7F,7F,0D,6D,F7,0D,E4,2F,9F,BE,C8,93,3F,1B,F7,37,6F,51,11,26,31,44,C4,D4,5B,2A,50,8F,ED,46,14,02,99,94,32,5E,7C,F4,FF,97,B7,96,77,EA,ED,AE,53,00,1F,0E,C0,AF,02,46,26,E2,83,AD,0C,1E,20,FC,03,BF,B6,05,0D,D8,99,1E,1C,95,00,B3,15,7F,38,85,E8,86,99,36,1D,2D,08,BA,80,BC,E3,03,B7,29,E4,F4,AA,57,F2,D7,34,9A,71,B2,66,8D,A5,C2,1D,D4,B2,68,9D,43,B5,C9,AB,72,B2,3A,99,EA,52,78,61,B9,74,03,BF,CE,A6,94,CA,12,A7,49,C2,68,49,AF,36,3B,41,D9,C7,52,BA,19,B3,96,CD,3E,B2,C0,9F,5B,CD,C4,D3,30,D2,4A,D9,42,57,5C,C1,56,79,C7,70,1D,64,96,75,CB,3E,A7,86,01,56,86,71,1E,4C,8A,4B,CD,68,46,90,D2,F8,0E,E3,18,16,47,04,BE,A7,6F,C5,B9,E1,68,97,24,83,0A,63,48,C4,28,1C,02,0D,99,52,E0,99,95,32,73,90,D2,A0,8F,BB,2B,8F,A9,5A,91,C3,D2,57,FB,11,DC,61,71,61,A2,E3,3F,AE,EF,42,AC,AE,87,07,21,BF,41,9D,0B,AD,09,2C,73,98,8F,FD,4A,1A,E6,E3,CE,22,C1,00,63,F1,9F,30,9F,D4,BA,9F,6D,24,77,0E,13,63,9E,6B,84,C9,B8,7E,EE,E8,8F,00,41,8F,39,BB,1E,C8,79,D9,C6,4D,39,C7,6D,99,64,1F,A7,31,10,54,B8,7E,C1,13,2F,55,58,EC,C3,62,6B,30,26,F5,D4,74,18,BD,24,37,5C,D7,93,E3,84,2C,21,39,6C,37,C6,08,13,1D,7A,7A,B5,44,31,93,AB,45,E1,5D,B1,2B,AB,F6,05,2C,32,14,4A,7A,60,7C,C0,EA,5A,90,D2,A6,DF,A2,ED,57,AC,A0,A5,B4,8E,EF,0E,4B,C0,2F,3F,2A,3A,72,C0,BD,51,22,9F,40,1A,5A,B9,7F,C4,24,FA,B5,A9,DC,7D,FC,A9,DF,35,3F,72,44,7E,97,55,26,AA,8F,5B,BF,95,FB,70,B8,89,97,36,EF,5D,9F,C2,9D,2D,54,13,11,D3,1F,4C,2B,AD,B7,C0,C9,8D,C2,68,E5,79,5C,A6,C4,91,F5,F4,09,78,4E,52,AE,ED,37,B9,8F,AD,65,E2,6C,48,5E,95,7E,BA,EF,32,A9,3C,5E,4A,F4,F7,20,B2,AC,46,F5,CD,4A,06,37,5B,AF,05,F7,7E,43,E4,90,EC,DF,37,15,A5,12,D2,3F,BB,81,84,80,8C,F0,ED,CE,B0,35,59,3C,F1,03,D0,47,13,90,39,DC,AA,2E,A0,E8,D4,42,FE,5D,8F,59,E7,59,15,E6,CE,5F,C8,CE,94,BD,F9,02,38,18,F8,B9,70,A8,39,C7,7C,94,12,91,67,68,3C,38,5C,3D,51,4C,04,08,C0,A9,3F,3F,26,C5,54,25,81,C6,C0,4A,97,77,E8,FE,34,F7,34,5E,F7,56,F7,03,19,38,81,D6,C3,95,36,34,A6,24,AA,A5,B8,26,04,9B,4E,B8,3F,7E,77,18,65,B6,0C,3C,37,60,ED,1D,24,9B,3B,59,07,08,5D,3C,18,D2,A7,61,A5,E7,FE,6C,B4,76,BD,EB,44,0A,B4,43,4A,39,62,3E,D6,EF,6D,83,DB,B9,CC,DF,9E,76,1C,E0,33,85,17,C8,62,D5,FF,52,90,8E,50,3B,FA,BF,FA,A7,1E,27,1E,D7,E9,B7,2B,D6,9C,D9,B5,58,0E,C7,75,18,11,6B,7E,07,20,D7,07,24,CC,98,0C,37,31,71,C4,E1,E5,0D,EC,F2,98,A8,0B,99,5F,1B,C8,96,53,C7,F9,EF,E5,6C,D8,3E,D0,CE,94,63,9F,31,DB,DB,22,5A,28,4E,C7,A2,7B,AD,BA,86,28,63,E2,BF,A0,96,2C,88,12,63,A7,7A,36,D0,2F,1E,30,F7,39,7C,3B,C1,3E,31,2D,38,AA,77,F5,A8,A4,62,59,11,F7,D0,A8,68,8A,89,8D,65,EC,D1,64,86,A1,DB,0D,1F,DF,12,4E,B5,D1,18,42,8B,BF,68,90,AC,4E,4B,12,77,2E,6B,86,91,80,39,7B,E0,B2,30,FD,A7,24,A3,0C,C6,C4,F0,1B,9A,59,F5,44,6C,60,8B,71,93,8F,86,E1,30,B8,58,61,56,E0,D3,B1,8B,80,28,9B,85,98,92,F2,A0,12,56,B8,A4,EC,60,8B,55,FE,57,62,65,67,7B,EE,6C,05,C2,E2,7F,57,FB,90,7B,BA,51,93,32,3E,7D,B2,0E,28,3A,B1,14,4C,0E,A9,53,7D,48,AE,0C,6E,C8,79,08,98,91,4A,F7,0B,42,3F,83,27,80,53,A8,4E,DE,91,E5,3A,E7,6F,CB,7D,2E,81,54,03,DC,04,C8,7C,09,E3,EF,09,90,68,19,81,C2,2F,2A,E1,9F,11,24,9F,D2,25,16,18,D2,83,5F,2C,F2,C9,1C,39,39,DF,74,4C,F3,02,18,77,5B,57,B0,09,25,8A,10,CB,E0,93,C2,AE,3F,19,32,93,2F,05,44,DE,C4,98,9B,5B,7A,AD,73,AB,BE,E2,CC,ED,4A,97,7A,C4,2D,68,84,02,E6,AC,08,05,68,DF,53,FC,8C,45,61,32,C4,29,BC,7D,4B,9C,36,5F,7E,7C,B3,21,FC,64,6C,9A,36,67,9D,21,97,DB,46,72,5A,A3,8C,39,83,C0,3F,89,D7,A9,BF,04,D6,ED,0C,5C,FC,0A,1B,EB,FC,5C,89,F1,BF,30,9B,F7,84,2B,3C,99,03,8E,1D,A2,61,01,9E,B1,9D,54,5D,1A,BB,AC,AA,2A,71,4C,C2,23,D4,79,75,A3,54,53,AE,C6,5F,23,34,B0,E2,3F,EE,00,BA,CE,2B,BB,56,98,CD,29,C6,BB,E6,ED,EE,39,98,C6,AA,40,FD,EF,CA,A9,6A,5B,76,B3,87,14,21,6B,5E,D7,15,AE,3D,9F,82,2D,81,94,C4,F5,99,B6,31,30,03,FA,B3,43,34,16,FF,F6,90,78,FC,3A,32,CD,D1,B2,A5,D5,AC,C6,C7,17,C3,8D,12,C6,9A,1C,5D,00,8B,77,39,F5,16,C6,1A,93,22,03,C6,7F,DE,35,57,68,58,4D,98,70,30,EC,8B,55,0E,57,A3,55,A1,D1,51,8F,A5,80,E5,37,86,CC,AA,22,BB,61,FC,E3,AF,15,56,61,2B,4D,15,0E,EB,21,E4,24,E0,10,DB,17,1F,FD,55,FF,4C,54,D1,69,5F,17,61,2B,27,BA,57,CA,4A,2B,A6,F7,C7,5F,63,4E,EC,E8,F5,AA,58,AF,17,D2,8E,A0,7D,D7,1E,0F,E5,79,72,00,EF,E4,5D,C0,C3,45,20,1E,C7,04,55,C8,99,B3,4C,2D,41,BF,AF,9B,21,9B,C8,AA,BE,62,5A,2B,1C,04,6C,64,21,76,CC,81,C1,5D,3B,6D,34,D1,0F,DA,92,B6,24,07,AC,4D,81,D9,F4,B5,7D,F6,B6,C9,85,87,3D,BB,83,13,0E,23,AD,32,E0,11,63,5E,23,2F,3F,75,C7,86,6D,53,85,6A,5E,82,09,FC,D9,81,72,D6,87,F4,1A,51,A0,40,45,B7,2C,11,D3,26,86,18,3E,05,0E,DE,3C,D9,1B,90,45,6D,55,E6,1F,AC,3D,D5,14,BD,0E,5A,FC,3B,B8,4F,32,F4,69,1C,B1,B1,00,90,4B,9E,D2,D5,AC,06,F1,2C,10,56,0D,0F,C5,5D,39,E9,8C,00,65,1B,FC,F4,F2,8D,6E,91,C0,15,95,45,42,CB,E9,CD,D2,E8,76,78,8A,EE,D5,0B,BF,97,D7,2E,15,B1,81,FC,87,AC,B3,8D,70,F2,9E,6A,0E,BD,19,6A,0A,3F,B8,BE,E9,DB,C6,63,7A,15,69,D8,09,D2,A2,34,16,F0,94,8E,E8,59,7B,6B,1F,6B,D1,BC,DB,10,85,C6,8F,2D,45,4E,4E,A7,86,C2,F4,A3,31,AB,30,9E,BF,AB,DF,AB,D0,F4,51,17,8F,3D,18,CA,F5,F1,80,0B,D7,2E,95,7C,9D,09,92,AB,87,DD,8D,D0,4E,71,FE,0F,93,60,BF,31,30,94,B0,CB,C6,EC,DD,99,D0,BF,20,6F,B3,9B,FC,AA,28,82,00,D9,9D,36,AF,7E,FF,40,28,C7,1A,98,DA,9A,7D,E9,39,C2,CF,1C,C0,41,85,73,34,7D,AA,14,DE,79,8E,32,E2,C5,1C,5D,26,60,8A,0D,DC,6C,78,42,36,96,15,6D,B6,59,C0,D7,EE,63,FF,FC,3A,22,5E,47,44,37,CE,4F,7B,8D,90,8D,94,EE,74,27,00,91,A6,57,17,34,BC,15,FF,72,9B,E3,3D,F5,46,F4,98,B4,FE,31,91,C8,62,F8,5C,FE,65,C3,64,E2,72,EA,B3,6A,F7,D4,F0,D3,BF,90,FE,E2,30,D8,9A,F9,CE,3F,D7,53,59,8A,45,07,D8,12,A6,89,5C,DF,E1,2E,75,42,10,29,04,61,A0,81,12,0F,FD,F0,5F,18,74,9A,34,D8,4D,6F,C8,B6,09,17,37,14,47,ED,70,E1,89,3F,E5,2E,7B,9D,E3,23,BB,F8,07,FE,34,9A,8C,B4,E9,DD,23,00,75,09,E9,A1,51,95,0F,91,71,91,0B,25,BC,67,3E,73,2D,C5,C1,A9,2D,C3,08,8E,FF,85,B4,62,0E,3C,8C,A4,A9,7A,9F,E5,29,2A,EA,06,EE,48,46,08,3F,84,60,43,2D,64,2F,0F,63,D0,B0,3C,7E,FA,17,DD,48,22,9A,FC,8E,19,84,F4,C9,20,39,A7,44,18,A1,1F,8D,44,77,91,0A,6A,3E,9F,AA,99,FE,55,DB,36,30,A7,A4,CA,1F,F9,02,D4,48,76,FB,C8,A4,EA,71,C1,3A,40,2E,97,1C,00,9D,EE,28,40,05,9B,DB,02,F0,AB,9C,EC,35,40,F9,FF,F7,4C,40,93,E4,74,E8,C0,DA,80,9B,86,39,1D,00,5A,B4,24,88,7D,FE,A4,BE,0C,CD,6F,B6,99,72,FC,4C,9C,65,D5,0B,56,4F,53,9F,AC,E3,EA,9D,14,61,16,32,A8,17,7A,FF,8D,20,7D,2E,AB,84,8E,B0,B5,6B,22,E1,C7,2E,09,3D,46,6E,4F,68,DE,49,C2,2F,6E,A9,23,82,14,F9,65,6D,D1,29,2F,17,7D,E0,92,36,70,CB,23,09,06,EA,61,DC,59,DA,AE,EA,85,28,85,05,86,0C,AF,C7,A3,30,83,83,6B,05,FE,22,9F,68,23,BD,5E,7C,42,A2,12,45,AE,78,8B,AE,00,60,3C,54,7B,9A,3B,82,A4,84,A3,6C,8A,B1,50,53,32,52,EE,93,1A,B9,CB,19,64,3C,5D,D0,3F,CA,85,F6,9D,41,66,50,E8,10,9C,D0,71,ED,7D,1E,FE,44,2E,83,B7,A9,0B,DF,E9,9D,B4,9B,61,82,47,24,DF,70,38,3F,4A,F3,EA,C3,CF,CF,DE,2F,E1,10,BA,E4,E0,85,3A,B1,51,8D,51,CD,2F,CF,D4,51,F6,B6,7F,33,49,1C,14,3F,F3,F4,31,76,92,DD,77,30,96,7A,90,98,26,4B,51,BD,03,0F,28,82,23,8E,53,03,2D,E2,83,5D,94,5D,FA,CC,96,B6,76,F6,31,1C,39,B1,1D,E8,4A,0A,5E,66,EB,03,91,70,79,66,D6,EC,8B,8E,29,9E,DA,2C,1C,58,6A,7F,1C,4D,1C,31,CB,2E,8D,C9,E4,3A,96,6A,67,46,7A,D3,4A,7C,67,EF,DB,CB,6F,9D,8A,56,B7,3E,D5,D0,E6,6E,57,06,A4,AA,7B,45,4F,B7,20,22,62,67,7E,90,C9,E1,42,FC,75,A4,E0,30,C7,65,3B,4B,67,54,EB,D1,BB,18,D9,FA,2B,BE,28,27,17,43,10,B8,16,3B,9A,3C,AE,8F,81,36,CB,3A,AC,D5,6B,05,A1,32,0D,1E,97,65,F3,8E,16,0C,A1,7D,4E,29,1E,93,04,3C,1E,C5,11,DF,6E,08,63,D2,F7,73,A2,39,38,D0,E6,22,50,AC,24,2E,82,E4,EB,2A,3B,9F,CB,DF,83,84,B6,C2,68,54,8B,2C,03,DB,DF,EB,22,BE,2F,B7,03,A5,DA,62,43,CF,08,37,25,C4,28,C9,B1,1A,C5,18,76,7E,82,14,52,7A,35,84,BA,33,F3,E7,DF,EC,CE,01,0E,BC,16,F6,CD,85,1F,79,E8,9B,3C,D1,86,EA,6F,3A,7C,C7,49,D6,A0,49,F1,1D,3A,92,BF,6D,A9,0D,8A,88,40,E8,04,3F,92,74,38,E1,EA,B0,77,FE,43,16,AE,05,0E,A8,D4,5C,6E,38,9F,65,AF,E7,63,67,9A,58,0C,60,B4,3F,79,16,DC,01,CA,68,66,EC,94,FC,90,90,37,C4,41,8D,5A,B2,4C,7B,06,F2,F3,77,61,BA,78,3A,AD,4C,BA,49,26,0A,33,D5,A3,E9,8A,2E,D3,CA,17,4C,99,0E,70,41,64,1A,25,AD,1C,86,0B,90,3E,F0,36,AD,5F,97,A0,73,90,81,59,74,02,57,D4,08,18,3C,D4,6A,C7,D7,EF,D4,18,12,0F,5B,0E,11,29,AB,39,9C,9E,D1,D6,9D,C3,4E,05,8E,44,25,10,D0,BD,3F,7F,0E,DC,FD,12,B2,D1,1A,E4,79,A3,E1,5B,6F,F0,60,9B,E1,01,58,F0,AA,0D,AE,30,CC,C5,DF,B2,AD,56,30,FF,AE,FA,D3,5E,80,4C,26,6D,00,23,3D,6B,E7,C9,FF,30,FC,26,0B,FF,8A,48,93,F8,6F,F1,89,68,9C,85,3E,14,93,1B,5E,29,5A,49,8A,56,0C,52,8E,44,9B,46,4B,10,EB,67,C7,77,12,9F,09,CE,DC,70,26,EA,C5,A4,EB,54,FB,7F,5F,4D,B4,AB,CC,3F,CA,94,9C,3A,A2,55,53,0C,EE,1D,FC,AB,06,73,EC,6C,A2,84,73,62,4F,56,C4,60,F3,01,55,EE,13,4A,21,5B,FF,27,F5,B5,8C,BC,C2,B3,B6,C2,2D,28,EA,B9,71,22,35,5A,D8,F9,DD,D0,9A,BB,1E,FB,95,49,9B,FB,2F,D5,CC,E6,D8,67,33,42,7B,2A,C2,F6,50,19,49,51,08,0D,E6,58,EB,68,33,9D,44,93,6D,92,24,79,87,89,E4,DD,12,E2,B0,13,9A,60,95,02,84,E8,B6,27,C1,4E,F8,95,4F,36,92,EA,9E,13,1A,C2,AD,6E,9F,38,8E,E0,7C,03,1B,BE,4C,31,83,74,21,80,98,F8,FC,B8,64,C2,A6,88,34,97,87,30,C6,10,9C,0F,93,FE,F5,06,52,8A,03,D0,84,85,3F,F5,C8,C7,DD,6C,62,F7,3A,31,51,7A,4D,45,00,D0,64,BE,78,1C,F2,63,81,89,F2,E7,6F,2D,FB,31,51,93,5E,FF,61,3E,60,44,A2,86,0F,6B,3A,A6,CD,A8,AC,32,47,B5,F8,EF,E9,C0,9A,E8,FF,23,DE,25,F9,4C,96,76,D3,5E,E4,C3,5D,00,19,76,9D,6F,EA,72,61,D4,AF,4D,3B,D2,D4,FD,5B,97,A1,9D,57,4F,53,5F,24,B9,63,BA,27,DC,83,C3,D3,3E,1E,7A,36,38,82,EF,55,23,3D,F7,EA,37,50,CD,D9,46,8C,94,B8,E8,2C,C2,A0,04,C6,BF,8A,AF,19,E9,18,46,28,D9,A1,78,FA,5F,E0,8C,E0,22,57,FC,C8,7E,EB,78,22,2D,A9,02,FA,6F,3C,B5,DC,92,DA,EA,04,0E,88,37,67,45,04,4B,C8,DF,38,27,8F,06,FE,B7,A5,84,E4,58,B6,96,2A,57,C5,3D,36,17,56,24,3A,BC,BD,DF,A4,63,17,5B,21,D9,9E,FD,D2,FD,0F,40,F7,18,66,08,C2,F6,0B,8E,0F,FC,E3,EA,C9,8B,0C,62,8B,D5,03,BF,08,6A,9B,28,3D,89,66,6C,CA,29,11,79,DD,89,85,04,86,2B,19,E9,CE,AA,61,A8,94,39,36,AA,68,1B,EB,AE,A2,BC,25,2C,29,62,51,B1,9F,39,A6,33,69,40,AE,2E,66,CE,15,15,8F,A1,D2,2A,30,B5,50,0C,39,7B,C9,B6,17,35,31,C9,67,9E,BE,15,BF,16,AC,7C,77,A8,2D,49,B2,47,C9,E2,0F,D9,F2,FD,F9,2C,6D,55,8A,75,07,79,12,DE,CB,CC,2D,DC,49,02,E0,D0,BC,C1,01,7B,70,9C,9D,B4,2F,C1,B3,69,E5,B2,BD,28,74,86,D7,A2,54,51,D3,45,BE,2F,C4,C8,58,AC,33,16,F1,38,50,B3,70,E9,B6,4E,59,E9,52,B8,97,45,73,43,0A,9C,04,6A,3D,93,59,8E,E6,7D,B5,1C,BE,8F,D4,BC,0B,07,22,0D,35,1C,4D,40,3B,44,FE,B2,8A,12,EC,91,7E,DA,06,8B,BE,70,F2,ED,28,5F,1C,93,5A,DA,7B,3E,8A,91,68,BA,6E,DF,55,0B,88,C6,F9,BF,2F,3D,B6,45,8A,6D,52,14,3E,97,F3,C9,61,90,C1,E1,37,49,D4,EA,70,6F,20,31,9F,CF,57,5E,DB,CC,F2,40,58,FD,30,E3,59,2F,4F,E6,67,CE,F1,EC,D7,AA,0D,41,CA,34,50,9E,34,D5,22,AB,C2,27,74,A4,D6,82,FC,EC,79,3B,95,EF,E7,68,5E,C8,1F,B9,FE,6C,51,CA,DE,07,2C,B5,BA,2D,7D,03,71,6A,D3,90,A7,35,EC,8B,85,55,46,3B,EC,8B,03,9A,7A,A7,B9,75,2B,19,57,76,1D,76,28,BE,EA,C9,0C,1D,53,33,D6,F4,B5,AF,C6,B2,0F,F0,32,C1,C8,A0,37,33,E8,50,56,6E,53,BA,E4,22,9B,1D,05,7B,6F,9C,EC,34,08,74,47,F6,D5,06,08,E0,5D,6A,76,5F,E1,F4,C4,29,17,71,BA,F8,9A,CB,40,B8,27,21,0A,8F,15,39,78,E5,B0,AB,64,0F,98,79,3F,03,F1,A6,E0,E9,3C,D6,BC,A6,7E,1E,BE,E4,4D,34,43,65,19,48,7A,88,30,E7,FA,8A,96,86,06,80,55,08,E9,33,E7,7E,EB,1A,26,80,E5,AA,FE,4E,5C,B4,49,9D,41,DB,E1,13,D1,4D,D1,8E,EE,80,48,A0,30,CA,3E,24,DB,F6,56,9A,18,0E,B9,62,88,BF,DA,D2,09,16,EB,20,E4,86,37,0B,51,76,83,4E,95,9F,C4,1D,45,3B,48,4F,6C,E4,AC,7F,35,D6,8F,9B,54,8C,97,0B,6A,56,35,C7,FF,26,52,8A,39,F1,F0,E8,16,80,EF,D3,98,24,56,EB,D0,04,53,26,D8,C4,5B,2A,37,B7,32,5F,52,8C,DC,9A,BF,18,7E,5A,8F,C7,90,11,C6,33,4E,1D,C0,83,08,87,C9,8F,E6,2E,C8,18,3C,A9,91,12,B7,9E,3C,E3,48,D6,66,DF,C7,9B,EE,FB,0E,AA,D6,06,13,5B,3C,E1,32,5B,C3,4D,00,98,42,3E,AF,8F,EA,F1,60,47,9B,46,0A,30,36,9D,E2,06,BD,DD,16,B3,6B,EC,00,68,23,C9,6B,22,01,C3,4C,31,BD,22,C4,87,5E,9D,7B,34,EA,AA,B9,F6,D2,F5,9A,69,D8,11,9B,1D,EF,BE,ED,38,55,4C,0C,C6,53,D6,86,51,CF,26,BC,39,DC,DF,68,FD,F3,6E,5A,94,4C,68,DF,B0,12,1B,4E,FC,F8,CE,4B,EF,A2,87,E6,3E,74,C1,48,06,83,E0,5A,37,F1,76,F2,1C,2A,F0,8A,FC,73,BD,07,BF,CF,A3,EF,E9,6D,13,38,1C,CA,84,16,24,50,35,BF,5F,79,F3,D2,89,7B,55,9E,CF,D5,F4,98,2F,7C,EE,EB,7C,93,21,78,C2,CD,6C,AA,47,38,05,FE,EF,A5,0C,49,63,F6,2F,5A,2F,4B,E0,DB,9A,A4,44,E6,66,E2,E4,96,54,F8,62,04,A3,9D,7C,66,1A,33,8D,D4,FA,34,08,4C,31,30,FD,4B,3E,D8,20,C7,EA,93,E7,85,E3,99,04,03,99,19,5A,F2,30,72,C9,F7,64,CE,70,CF,A6,A8,E7,B7,92,49,12,64,2A,21,E5,C1,AD,6B,90,DB,26,BE,94,34,7A,69,F9,32,BE,E7,6B,4D,03,D4,6D,16,FE,78,EE,C2,5C,C8,48,09,EC,78,03,FA,E0,E5,E4,27,2D,71,31,E5,0C,EF,57,CF,E3,00,B6,80,F8,B2,07,04,69,C5,2B,C6,57,49,E0,42,ED,60,D3,05,E1,2C,54,DF,1D,C0,39,8F,F6,5F,D1,60,B0,8A,9D,F8,3A,2B,FC,54,60,D2,15,67,0F,50,0F,12,6D,92,B0,2D,1C,EB,5D,71,9F,48,2C,B8,4E,D6,93,CA,25,4E,C3,6C,11,3B,DF,2D,AA,10,66,3D,61,F9,23,97,95,31,E8,55,60,BC,7C,72,02,AB,BC,16,98,F9,6F,9E,AB,3C,6A,B0,D9,8F,0E,52,FA,E3,53,12,91,9F,A3,62,71,1D,63,D2,19,85,A1,A8,4C,CE,00,FA,11,5F,3E,0B,EE,50,9F,49,C8,B8,0A,62,57,05,36,61,92,C8,88,A0,AB,19,32,47,7F,8F,CC,DF,B0,AE,F2,FC,79,CD,0B,39,58,6B,D8,1F,DF,29,AC,E1,F2,06,52,22,82,B2,20,6D,9E,61,B5,83,6C,4D,22,66,9F,31,8A,E0,E7,67,8A,07,59,21,36,92,95,87,90,D5,36,C7,09,A6,0F,E2,92,B9,E0,9C,7C,0E,10,3A,F2,78,08,B0,3D,F4,3B,70,84,AC,78,11,B5,A5,08,E4,B3,AE,E3,59,8C,53,72,67,A0,1C,B3,4B,05,A2,69,10,B5,C4,B3,6E,E4,06,DE,D2,D5,7E,E3,2D,06,5C,E3,46,EE,1A,B7,1D,EB,EB,52,2D,8C,00,1D,DC,DB,6A,90,FA,24,0C,B2,94,15,97,78,DC,26,A6,FC,35,E1,67,D9,BD,EC,2D,3A,FE,97,EF,1F,53,2A,63,60,24,F1,F6,9A,38,02,38,E7,DF,FD,B2,F7,63,FB,85,4B,7F,7E,F4,D3,25,61,CF,08,04,F1,A3,1A,4A,3A,CA,C8,52,4F,E5,6C,0D,F8,F1,C4,6A,C7,0D,06,F4,60,75,41,32,E1,AA,4D,BA,30,07,F5,93,2C,4F,CA,DE,84,CD,28,C1,52,89,97,0F,B4,41,F7,33,4E,EB,09,33,CF,67,8E,DE,FA,88,8C,F8,91,8A,74,59,C6,9E,89,F1,0A,77,BE,F4,53,25,FF,F4,97,7B,01,AF,DC,40,E8,84,CA,88,A3,F3,1F,90,87,6E,24,52,2A,D0,D1,F4,48,9B,EF,16,7D,DC,F9,CE,2C,23,BD,EF,3C,F0,AF,21,27,F7,AA,56,70,6E,6A,9E,A0,9E,C0,75,75,25,7B,A9,D6,E6,5B,F3,C0,5C,B4,87,8F,C4,BD,6C,3B,0C,24,3F,88,82,E0,1B,B9,3A,BB,5B,74,1C,63,27,B8,19,12,81,88,CB,00,05,C9,7F,B0,28,8F,73,A2,2F,2E,62,C4,8B,C7,1A,F1,B8,F7,73,DB,F4,34,53,7F,40,02,35,9F,35,BB,54,6B,F9,11,1F,BA,DC,C4,5B,44,D0,A5,10,AF,80,4E,AA,96,29,FE,ED,EB,89,EC,A1,6A,13,EC,81,36,C0,BE,22,32,98,A5,EC,00,8A,5E,DF,54,3A,A2,B4,C1,52,1F,75,08,D0,F1,DF,41,2F,EA,07,86,C8,C3,28,26,CE,3D,44,09,9E,0F,B4,2B,FC,F5,56,6A,F9,BA,57,87,59,4E,09,55,B0,FE,76,E7,5B,C3,5A,93,FB,44,BA,9D,55,14,34,28,89,3F,BB,2D,B9,32,19,20,D9,72,44,C3,A5,6B,20,0C,42,C7,FD,F5,E3,96,F6,FE,29,17,D8,66,82,67,D4,78,44,2E,56,25,99,1B,F4,BE,44,11,AC,B9,66,45,74,F8,66,71,DC,D5,B5,15,EF,92,91,59,54,D2,6C,1B,FB,31,43,3C,26,84,86,64,8C,30,22,82,88,5D,66,DC,45,43,EC,12,52,67,14,8D,61,6D,22,68,94,4A,BF,6A,31,22,C5,AD,BD,EC,5C,F0,F5,2E,86,36,7B,DA,37,98,5E,58,E8,28,D3,44,DC,75,2A,AC,14,C1,28,AA,D5,46,B1,94,FD,72,48,FB,2A,1E,34,88,AD,90,9E,86,16,FC,73,3A,4F,D7,0A,11,9D,A4,C4,71,64,56,C6,13,DD,B0,99,E5,41,61,91,5E,A5,E2,08,3F,89,82,A0,44,70,BC,7E,87,05,B1,07,FD,A4,E2,AE,29,96,2D,E3,1B,95,90,26,0B,3F,6C,E2,0D,50,08,13,9C,C3,B1,80,84,6A,AC,B3,35,D7,4D,C3,D4,BD,B0,F8,57,1F,51,8A,AB,7C,EB,5A,E5,C5,3A,9F,EE,4A,CB,8D,AA,C3,62,F0,8C,E8,17,07,9F,B4,9A,49,E4,68,2C,1A,93,A3,C9,28,C0,66,C9,25,A3,41,4A,4D,6E,B8,85,D3,4B,A9,66,8B,B7,A5,88,C4,CB,38,89,63,80,88,DC,83,74,0B,AF,90,03,BD,85,82,3D,7E,E4,3B,D0,B3,45,90,FD,5A,7B,48,04,87,E4,C6,2E,EF,A5,0A,D5,AF,E3,E3,C0,6C,89,22,00,FF,E7,FE,69,4A,2D,B3,BC,2E,74,0A,98,BC,1B,B2,6D,90,3D,9C,D7,9E,1A,4C,55,39,B5,7C,09,B3,AA,87,2C,C0,21,C8,20,98,18,46,18,5A,47,3A,0B,74,C7,0F,2B,CE,9B,EE,E1,6E,E5,02,F4,0D,BB,F4,A6,39,9A,05,2F,50,79,A3,E1,79,43,7C,3C,38,89,D0,7F,DE,5B,96,59,EB,29,6B,38,76,7E,31,9B,4F,57,45,90,79,B8,F7,A4,6B,A5,AF,F3,B6,9E,40,7A,DC,7D,03,09,71,37,EC,17,20,46,CB,B4,C8,06,B3,43,CD,E9,DB,76,DE,C8,07,10,F3,E7,B3,12,91,FD,45,5B,A4,9A,48,E9,DD,74,F9,7F,1B,35,EF,E8,4C,0E,3D,5E,6A,81,29,8F,92,24,52,F4,FE,59,4B,0A,65,9F,76,DA,8D,36,38,21,49,7E,05,49,86,88,7B,80,74,5D,49,6E,69,D1,80,55,BC,99,84,0C,8E,D3,44,B5,89,6B,F8,47,EA,AF,D4,09,84,99,74,B9,73,86,D5,67,9C,27,7F,62,60,C3,73,D1,4F,65,91,D5,11,77,6C,F7,47,72,0B,2C,F5,C9,70,D7,DD,3E,49,CB,45,51,65,E4,62,9A,39,8D,9C,CC,B1,E0,2F,61,8D,43,B7,4D,8E,65,CA,D4,73,AC,34,3B,7A,16,40,EA,B2,2A,6B,A1,0B,48,EC,79,E7,8F,2A,00,D3,78,56,9E,7A,E3,A9,0D,88,9D,16,52,63,4B,4C,59,85,10,DD,64,34,81,F6,DD,97,1D,E9,0F,EA,CE,73,0B,9D,01,67,E5,62,B9,5A,6F,50,C1,D5,EE,31,26,DA,C7,10,9A,E7,D3,00,A2,97,96,C2,DB,3D,33,99,95,8C,E3,DC,9D,CE,CD,FA,A6,9A,0E,FF,B3,0B,AD,A6,1A,4C,D7,1F,AB,3F,22,4A,AA,3C,C1,9B,8C,71,C2,AF,A5,BC,63,E9,BD,80,EA,3E,DA,E9,E3,55,52,9B,97,03,09,4A,0B,AF,D4,B1,73,12,08,DD,F2,2A,10,64,BC,D1,01,4B,01,84,71,46,FE,D2,8A,71,E4,B8,0A,EB,8C,55,C2,F4,D7,E7,B5,3E,35,30,54,04,0F,51,4D,B6,06,07,B1,50,73,B7,54,20,86,92,ED,93,C5,57,EF,8B,1D,7B,76,CA,13,E3,E5,81,26,A0,A9,0F,3D,D9,E1,69,52,9C,9A,91,B8,21,93,11,CD,6F,D3,F7,C8,ED,4B,68,D6,48,8A,AC,1B,2D,86,17,09,91,38,6B,15,A8,A2,E4,FF,89,DA,F3,26,14,50,85,73,19,B0,C9,AB,9A,0C,28,5D,5A,78,92,91,54,1D,3B,5B,AB,5B,91,37,3C,27,D8,29,64,1E,9E,99,BA,BC,5D,2A,5B,7E,7D,B1,12,5B,72,FF,6F,F8,82,F5,19,20,92,07,B3,F3,DA,2A,6C,A0,DB,73,0A,39,61,6F,03,20,A6,82,60,E8,02,F4,38,FA,C3,F5,A6,8E,44,5D,81,FF,4A,2F,9C,AD,B9,8D,16,E3,86,DD,81,F0,20,7F,AA,4F,7D,86,7E,94,08,3B,7D,99,74,B3,19,3B,B3,54,78,80,62,9C,12,0D,89,29,9F,5B,54,9B,1F,24,20,FB,42,6C,27,3B,24,37,7F,51,69,70,AB,0B,22,9B,01,18,DE,F6,A7,06,C9,F0,C9,60,53,B0,3E,96,BD,05,DA,43,99,D2,84,14,77,98,32,22,79,39,46,B4,EB,E1,38,0D,C5,19,3A,50,D0,22,24,B8,FA,46,65,C5,16,D0,39,C2,71,DB,88,78,E0,2B,7D,3B,DB,AE,44,38,67,61,A8,33,B0,06,AE,43,17,2B,61,8B,90,B2,C5,E2,9C,8B,34,5D,23,E9,E8,8E,9A,9C,11,25,2E,5D,33,AC,EC,D7,E7,77,13,12,0D,46,A5,A5,9F,8C,70,A7,B4,49,AD,C5,CA,4F,89,B5,FF,D2,F7,30,A8,DF,8D,DE,2E,7E,25,6E,7C,74,B9,C5,F5,30,03,F1,97,F9,55,57,3F,68,09,04,D0,58,7F,27,CD,74,2A,9E,6F,B9,BF,AD,4C,0D,65,79,0B,C7,1A,AE,5A,CC,5C,70,98,8B,CE,64,AD,4D,25,85,53,1C,6B,4F,9E,B0,FF,D4,F6,A0,1A,5F,95,74,62,F8,80,3F,59,D4,8D,41,FA,96,13,C4,5F,24,01,83,54,C4,47,1D,92,91,62,83,82,BD,DC,5E,15,98,F7,4D,76,EB,6E,F4,C1,E9,39,CD,0F,83,5C,2F,97,C5,26,35,85,01,B4,94,38,5E,60,ED,8D,08,A0,40,92,71,95,85,2B,C7,AE,EE,35,95,3A,90,11,FE,6E,90,1C,AF,02,F3,DE,6E,3A,C9,AB,68,CD,08,AC,A6,2B,6E,D3,F7,91,6D,2A,2F,0E,84,6A,BE,48,FF,77,97,68,E0,FB,FF,42,F5,37,7C,BE,F9,95,17,F3,7F,42,F5,CC,EE,27,07,6F,4A,E0,BF,8E,15,32,00,47,39,C6,A6,81,56,2E,BA,F9,A8,3E,40,0C,88,6D,87,71,94,33,11,2B,E0,F0,C0,FB,AF,36,16,F6,04,0D,F7,2B,99,75,18,E5,73,C3,7E,73,64,12,A6,30,9C,92,5A,17,BF,85,99,44,46,6B,4B,66,3B,10,D1,B9,B1,D7,1D,EE,A2,04,E4,C2,EF,B1,EE,B8,91,4E,61,BB,D3,3B,53,27,84,87,66,6B,5B,CE,B7,D5,8E,0F,E0,01,5A,11,C6,94,E9,6A,48,1A,5A,5B,F2,F4,A1,44,21,C0,3D,7D,17,51,DA,08,45,BF,82,E7,3F,2C,46,37,89,F0,C6,5E,E9,D3,09,40,87,A3,13,1E,FC,E7,72,E6,AD,AA,0D,51,E6,AA,3D,F5,F4,81,32,BB,88,DF,DB,01,B8,CA,6A,F6,E8,42,D5,30,0D,6F,AB,E2,5D,DE,F8,00,B5,F0,29,BE,E7,76,26,61,1D,37,67,38,E1,77,C9,EF,C0,8D,16,64,1E,6E,43,3D,3C,4E,65,CD,DC,36,11,E9,33,09,AB,23,CE,6D,1D,83,0D,A2,6E,D0,BF,D3,58,46,29,C3,A0,B6,C1,E2,9E,66,21,C5,5F,A7,91,E6,8B,CA,A8,F2,16,3A,2F,28,AC,35,64,C8,0C,CE,B4,A7,F5,10,44,A5,19,55,93,D1,FE,2D,8F,36,2A,82,41,44,FB,25,06,5D,B1,5A,DE,1B,26,7F,92,81,C3,0C,C9,30,DA,F6,86,0A,5B,3C,A5,AF,FE,5E,74,E8,43,3B,D6,BA,E8,C6,AD,E4,28,51,8A,F3,26,4A,6B,8D,FB,D1,55,AB,BA,4A,B5,1D,51,C6,79,30,C0,CD,82,9A,D2,8D,CC,30,3E,EF,84,8B,3A,B1,93,FD,F3,7B,7D,A5,A0,90,1C,F3,37,33,98,0C,01,8D,CE,9E,E8,BB,F8,9D,E8,12,C4,E4,95,3E,42,66,10,AA,E6,F8,1B,22,C2,B5,7F,74,8B,78,C3,BA,D3,D8,E4,5B,F5,2E,2A,83,E8,1D,82,8B,CB,7E,C8,83,77,C0,3A,9D,C8,D0,8F,04,77,E4,E4,2D,26,01,65,C7,5D,90,82,81,B4,E5,53,31,A5,FF,9D,1C,DB,16,6F,C1,BC,0D,BE,52,08,C8,56,9B,73,CF,5C,E7,B9,49,93,90,3E,3B,8D,32,70,79,62,03,4B,2C,D8,A3,B5,57,09,D6,21,EE,11,83,8B,EA,50,BA,D9,A8,D4,FE,CB,31,48,46,B2,26,BA,FA,DC,3F,F3,BD,4B,4D,19,EA,00,78,2E,5E,99,FE,DB,56,EA,26,92,5E,9F,BE,38,39,B7,E0,08,C8,F4,04,68,AA,6D,F3,95,4D,7B,65,2E,0F,16,D3,61,75,80,FB,D5,AB,57,DA,9B,E9,93,BB,6B,C0,F9,31,50,D0,26,88,DB,40,4F,18,FD,88,4F,79,FF,9D,42,A3,8F,0B,99,8E,69,1D,01,10,E5,94,E7,FB,40,5B,64,C7,30,02,47,60,96,EE,7E,78,DD,9D,69,B5,94,DD,8B,EA,41,8B,A4,D4,B5,F3,51,D8,6F,A6,D0,5D,C2,86,F2,96,98,40,2B,8C,15,61,51,C0,B2,36,79,D4,4A,99,33,BC,AB,5C,27,AA,E9,B4,2A,2C,07,3E,99,4B,54,C0,20,4C,C9,A2,0A,F1,0B,B3,36,F3,5F,CC,D9,99,F7,1C,C0,D3,7C,93,38,2C,50,74,F9,F8,9A,92,9A,58,C2,1A,51,C0,AD,61,A2,80,7A,56,05,7B,68,91,8D,3C,0E,B8,4D,9A,DB,CF,22,D5,95,00,55,AA,9C,6B,E0,D6,38,51,40,2D,F1,F3,B8,FB,42,09,66,DD,E4,BC,EC,58,40,74,23,52,83,E8,08,E4,7A,70,67,64,B3,23,30,96,BF,34,29,80,E4,CB,B3,41,2D,03,42,7A,DE,60,91,00,3F,15,BF,4A,1C,4E,45,0F,DB,B2,20,A2,7B,D2,26,66,39,AE,25,A0,F4,DB,50,7E,92,41,C5,E0,D3,C3,88,BC,A2,9C,DE,B3,A1,C7,3A,A2,38,35,30,41,6D,87,A7,B1,B1,AF,D8,7B,91,DF,4A,66,12,89,A6,5D,55,B9,64,27,40,5F,85,E2,17,9F,46,D6,F2,C3,BB,CA,E6,79,CE,40,19,78,69,2A,A1,B8,67,DE,88,D3,29,90,A3,D2,E0,E2,5F,4C,71,83,93,24,87,B9,67,26,92,47,F8,32,11,09,38,49,88,11,F8,69,F1,32,8F,A9,AD,99,81,C7,6A,9B,A6,9F,53,84,C3,36,20,77,5C,DF,E5,FC,56,43,E6,A7,CB,20,72,53,74,9F,FE,71,C4,14,39,EC,C5,D7,03,8F,05,C7,0E,98,E5,B0,E9,34,8C,57,7B,17,11,2A,E7,5F,93,27,9C,34,F1,BF,49,06,67,48,DC,4B,9D,85,BC,DC,00,C5,C9,0B,F9,47,FF,B4,93,BF,72,54,28,33,6F,79,43,4E,74,C3,8B,8F,54,BA,DA,5D,30,02,06,2F,D8,A2,CC,5F,23,3B,1C,9C,94,F3,2D,93,80,35,BB,DB,3E,AB,31,C0,77,50,FA,6E,FF,CB,B2,52,22,BE,B6,6A,40,03,47,B1,0A,B1,A6,31,14,58,8A,91,8C,00,BC,DA,C9,91,C8,56,8C,2D,14,F3,8B,93,D5,D3,DD,21,AF,6B,C6,90,F1,71,FC,99,A2,4A,F4,DE,31,86,4E,1B,A5,3B,16,F3,CA,1E,1C,E9,2C,F8,6C,09,71,DE,E8,F5,FF,74,35,6E,9D,3E,F6,DC,06,D8,6C,91,AE,70,D5,F2,6B,D5,25,DF,C6,C7,0F,FF,0F,2A,87,AA,71,FC,D4,35,4A,78,5C,F8,84,D3,6D,55,5A,94,E9,57,71,C7,C0,C1,73,E9,5B,A1,AA,7C,EB,A1,AC,5C,2F,43,AC,2A,5D,A6,26,23,64,7B,67,E1,D8,64,ED,B7,13,83,93,B6,25,4D,C1,CE,8A,D4,9C,5B,E0,92,6D,0A,31,7C,1E,41,D9,9C,C6,98,69,F2,48,F4,4C,27,61,22,71,85,9C,36,EC,1E,45,13,8C,1C,A1,B3,C4,91,6D,C9,88,02,77,A4,9F,3D,5F,FD,72,7B,88,EF,53,B3,6F,B1,EC,9A,4B,54,05,D6,F7,B9,45,3F,93,33,24,A0,00,77,CF,61,60,51,11,87,40,30,12,CA,37,F7,34,DA,32,4F,BF,58,26,D2,4E,84,5F,2E,4F,CF,C4,C2,04,7F,76,11,6D,5C,86,84,22,88,59,3C,BE,26,76,78,F5,02,E2,60,4C,62,66,BF,FF,3C,AC,32,7B,F3,0B,46,34,EF,E3,E9,57,5D,3D,21,C1,F7,11,70,19,A2,18,A9,39,FF,8E,B4,42,55,9A,43,2B,D2,9D,78,DD,7A,25,96,D0,57,5E,D6,1E,5E,E1,02,51,51,7F,DB,61,BC,D3,7A,AF,08,B9,91,30,3F,FF,41,D6,FF,00,37,9C,8B,D1,25,09,85,C3,49,DA,FC,0F,B6,B2,94,2F,3E,AA,0D,8E,9D,5A,7C,F5,9C,33,4A,BB,1D,D4,F3,53,68,5F,54,83,C1,D0,8B,56,D8,3E,DE,83,1C,3C,2B,77,17,8B,43,95,FF,A6,77,7C,5B,50,43,A6,83,50,81,92,BA,38,22,BC,4E,78,07,45,A0,D7,3F,ED,1B,97,91,4A,1A,F0,68,C8,98,F4,0A,2C,76,31,FD,33,BE,B4,9D,BB,C4,F4,89,4B,AF,1A,ED,49,E0,21,D3,99,1F,E5,B8,92,2A,10,BC,BA,90,A6,7C,4C,9F,47,7C,4D,48,A3,C3,4F,FD,45,4B,10,91,77,9B,87,31,14,3F,20,2E,F7,01,46,87,DB,C9,C4,F1,E4,F3,7C,29,17,86,D4,46,F9,B9,8D,CB,F8,27,E0,03,E3,08,22,5E,3A,77,F0,EC,DC,F7,48,08,D6,E9,9D,69,38,57,30,06,61,64,E5,45,3F,D0,7C,E5,99,3D,C3,91,F8,8D,31,10,61,33,5E,3D,24,7C,F3,F9,4F,C0,52,6E,0E,AE,7E,D1,AF,27,C8,26,5C,DE,5E,D7,AC,3B,10,38,FB,7C,C6,6F,17,1E,D7,A8,7F,FA,89,E5,A5,B1,CD,EB,3E,A5,39,1E,E3,07,52,3A,86,8A,93,EB,BE,D2,6E,D3,D4,9C,30,2C,94,98,89,1C,85,DA,E0,A5,59,79,38,AC,13,D5,13,F8,A4,AE,B1,FA,CA,C0,DE,36,F2,8D,0E,FB,90,AB,6C,86,99,02,62,56,C0,EF,F2,0F,E1,6A,CA,89,35,DD,40,46,B3,5D,00,17,D4,34,F9,38,AB,16,A5,7D,89,50,D2,DD,B0,F0,E1,D9,EF,CD,AC,6C,16,25,E3,A2,B1,37,5B,62,7E,8B,B9,C4,B0,E3,B4,D9,DF,5F,CD,02,22,05,93,30,42,1A,1F,7E,AB,8F,E3,27,35,60,D7,D0,27,AA,1B,A1,B9,8B,2C,9A,D0,E6,64,95,56,78,D0,D3,35,14,2D,81,F2,4B,69,49,6E,44,44,66,A5,10,CD,88,0A,49,CC,6F,D6,11,E7,B3,B7,0F,67,E5,25,20,F7,0E,3C,2F,57,96,EF,4F,0F,FA,E0,72,D2,15,45,0D,1D,80,4F,FE,12,45,A8,72,71,C9,E8,60,6F,6A,A5,D6,3D,C9,7B,88,79,C7,33,FA,25,71,9B,02,FB,39,9A,51,AB,40,49,95,8E,50,75,E3,B5,B2,73,75,DC,25,00,F3,BA,AB,0A,83,3B,9C,50,B9,79,DB,BA,F5,B3,13,6D,CC,69,93,E1,B3,BD,76,64,C0,4F,39,F1,1A,04,08,1B,6E,FF,D1,ED,61,82,B5,B4,C6,12,16,5F,75,F1,95,A6,3C,D7,FC,D5,C4,FE,03,43,A1,E5,C0,35,06,43,30,73,C8,C2,A5,9D,CF,5A,62,8D,F2,52,34,8F,CF,AA,EF,DE,56,E3,C7,DF,FE,35,6E,6C,A2,3C,28,90,F7,6D,58,01,AE,54,1F,DF,1D,E5,2B,AD,19,F4,D5,D6,58,EA,A4,55,D2,37,FC,6E,10,54,4D,4E,74,4D,BB,1A,EA,5F,27,41,06,DD,DD,49,DE,F2,14,6F,1E,E3,56,6F,39,8F,C1,01,83,63,AC,7C,39,DB,FB,54,C8,78,D6,00,49,D5,75,2E,D3,1D,F9,2E,50,1D,6B,B1,58,A3,9F,F4,EB,97,9B,DB,2E,1E,DA,33,28,54,0A,6D,1B,C9,5F,6F,03,B5,FF,42,41,A2,67,76,DD,FE,68,8D,21,04,33,B4,6C,F8,AA,3E,4A,56,82,91,FB,26,EA,19,A9,3B,1F,6E,BE,3E,39,D0,73,4C,C5,63,FC,76,64,76,26,92,AE,89,69,5B,64,73,1D,23,C1,CE,D1,CB,CD,71,58,98,30,1B,DD,F9,34,97,08,18,1A,D2,CB,48,A3,54,0A,38,D4,5C,4D,AF,C9,BC,FF,3D,FD,EE,AE,41,3C,65,66,3B,3B,FF,DF,6C,C2,F7,F5,76,BA,05,F9,61,D8,DF,B0,B8,CA,DB,9A,16,FF,A4,41,AB,82,19,04,13,F4,1D,D5,52,7F,1A,28,DC,37,88,B2,D6,5A,62,5C,63,AF,D4,ED,C1,D0,F9,79,A1,51,E1,07,F2,57,D7,3E,21,86,AB,09,49,39,2C,E8,8D,B6,0F,54,41,85,93,FF,4D,B2,2F,F1,1D,7E,B9,53,B7,2D,88,EE,27,19,35,AA,5A,39,87,3F,9E,B5,04,3E,03,91,AA,8E,9D,CD,D8,C0,A3,7B,6E,79,99,2B,A6,64,1D,8C,B3,CF,74,33,51,3D,63,15,7B,51,FB,B2,52,A4,2A,C4,69,BB,EB,D1,53,68,09,C3,3B,DA,A8,54,17,7D,4D,65,4F,68,DD,AA,50,B2,CA,FB,9A,08,F7,AE,A9,84,AE,BF,5F,89,CD,F0,6F,D9,66,75,B5,03,81,49,C9,14,57,C1,D3,65,9B,62,21,DB,AB,B7,1E,60,3E,49,13,3D,14,1A,B1,4B,E1,03,64,04,64,FF,24,F6,2D,2E,0D,E0,4E,DA,6E,41,31,17,D2,7A,17,2A,F5,46,C8,CA,24,07,67,1B,B6,EB,10,3A,BE,94,DA,DF,C6,9E,DE,CE,7F,F4,3C,3D,A5,F8,50,8F,D7,96,56,61,E4,6E,44,25,F2,65,DC,BA,2F,E8,39,B1,AE,A3,28,16,B8,72,9F,44,3F,B1,00,58,5D,09,C5,49,F2,E1,F7,F0,D1,94,07,75,5D,9E,93,BB,B1,5F,5A,E6,B7,0D,0A,F8,6D,A3,A7,78,CF,A3,01,FF,BC,E9,9D,EB,AE,11,6F,CB,BD,FB,F3,B8,78,36,8B,52,0A,06,33,D1,E2,36,EF,41,02,E0,A6,18,49,EE,48,D0,06,79,62,3B,AC,F9,91,64,81,77,F4,20,8C,BE,79,97,82,FD,71,22,F0,88,C8,DD,20,49,94,C4,C9,57,2A,A3,29,89,14,8D,7C,91,A3,38,8E,40,BB,B8,93,6E,CF,9D,4F,E0,E0,45,31,73,37,EC,5F,DC,1C,79,4D,A6,CC,7B,8D,67,50,2F,26,BE,83,3D,47,35,C0,66,B3,E3,9E,A7,7C,4C,3D,C2,78,CF,CB,C9,1B,90,AF,5A,47,D3,15,B6,11,7E,95,16,54,7B,40,7D,C7,1D,AC,FC,E8,37,9C,B2,4E,69,D4,03,99,26,E9,3C,08,3C,AA,87,FE,08,A4,F2,B2,9C,07,C4,BC,4B,AD,99,22,B9,6C,FF,BD,06,E0,9F,1C,E9,95,1C,F9,E5,40,0F,72,45,F1,6C,AB,8D,E0,FC,D1,75,EF,09,BA,06,C5,B4,48,25,DC,14,E8,F0,6D,1B,E2,A4,76,C1,38,A9,F8,40,E1,0A,BC,5A,6E,4A,C5,76,5A,70,0C,F2,C2,0B,EC,08,1A,AF,0E,B1,6C,93,FF,61,C7,0C,10,17,A0,2F,77,1D,6F,7F,2A,70,74,E8,3F,12,31,A6,C2,3B,3D,EC,BD,4E,3A,49,E6,04,44,36,38,B5,D4,35,7D,01,75,60,27,CD,EC,41,5C,46,F5,22,28,00,99,90,72,BB,1D,A2,A5,E6,90,8D,E5,06,02,5B,5D,97,77,76,F5,FD,CC,DB,28,2C,B4,9C,52,EA,75,2A,4A,29,96,17,F1,61,23,71,BD,D8,11,43,FB,5B,2F,57,FB,91,7F,84,32,36,06,6B,93,A7,80,DC,20,31,C2,D2,0C,B5,F0,34,3E,AC,70,73,17,C3,D1,7E,ED,73,E2,20,3F,E0,60,35,46,4F,34,2E,DE,84,7F,71,A5,5A,A4,C4,F8,41,73,9A,12,B5,0E,85,A2,CA,E4,2E,C8,75,92,DE,62,D9,C4,2F,80,59,55,DD,8D,42,3C,A6,6B,F9,03,53,11,04,13,0A,EB,71,A9,01,4E,8B,AA,34,7F,34,C6,13,3F,FE,B6,5C,0F,C2,CD,61,AE,08,45,C4,6C,8A,A4,88,C5,E9,44,01,C7,9B,52,55,49,62,53,C7,23,78,2F,96,91,2D,0C,29,F7,F4,C3,39,FE,A1,87,5B,70,91,3F,1B,36,E4,F1,D7,F7,19,1F,70,7D,75,27,F4,8C,2B,35,CB,B6,20,45,0C,35,68,D6,0A,FD,CA,DD,ED,C7,03,F2,5F,FF,DD,A7,90,43,6E,55,96,12,03,83,88,00,55,2C,DC,3A,D0,A5,66,47,AF,20,E4,86,90,38,63,7E,B6,D5,6D,AA,C0,C4,20,2E,0F,6D,31,D3,95,35,E9,68,27,4C,D4,F8,B5,95,05,DF,A1,A5,E7,23,20,8B,32,D3,91,6B,15,B2,92,E3,95,AD,3A,F0,74,E4,11,E2,FC,8C,5A,3D,FA,D6,C8,06,7A,21,5E,8C,88,4C,47,D3,57,A5,E3,21,8A,D0,58,C8,07,BC,64,2C,84,8B,6B,18,10,AA,97,C9,1C,0C,09,D9,67,B9,85,2A,CB,D9,98,21,58,70,DD,DD,7D,58,2E,C1,F9,BA,B3,69,DE,CC,E2,71,55,EE,CE,39,A2,D8,4B,32,81,A1,CC,AE,A8,F9,35,76,F9,43,14,64,55,80,A2,DB,86,AC,2A,33,BF,0A,3F,F4,9C,70,DB,66,2A,6A,16,4D,45,A7,1F,73,FA,D7,DC,DA,AE,16,B4,97,35,53,F7,B9,3F,F1,CF,AC,8A,6B,49,25,6C,33,C1,FB,06,3C,3B,26,56,13,8B,00,28,D6,51,9C,AA,15,CA,9B,34,B8,B1,09,72,32,8B,2D,8D,53,CB,E3,DA,A7,D4,6D,14,F5,EA,E9,A4,A9,F9,43,C7,A7,2E,AA,1D,6E,62,0D,E7,19,36,50,C3,3F,80,C0,BE,7D,DD,8E,54,F8,57,43,D9,07,D3,EF,F4,7C,02,19,35,65,33,4B,05,00,C6,68,31,D5,48,D2,53,9A,47,63,0A,9C,9E,13,E1,45,FE,DA,9B,F3,7C,25,3C,A3,60,DD,6F,44,98,4F,44,72,B0,19,36,B5,1E,CF,B8,F9,60,72,B8,0F,FB,A4,1D,2A,84,AC,27,8A,A7,96,97,D8,7F,1D,99,0C,D9,41,57,EA,A0,00,7F,4E,FD,E1,9A,F1,05,ED,DC,F5,D2,B4,C4,F2,1B,04,C5,8A,02,4B,86,D5,C4,7C,6C,59,80,1C,D3,F3,81,1B,09,2F,EB,6B,3B,E1,9D,FD,87,A2,D9,39,35,88,35,19,42,BC,10,C0,74,C4,30,36,51,64,40,53,F5,8A,0B,A7,2A,0D,AE,3A,9E,AE,65,15,F2,AF,21,2F,4E,93,E6,89,47,E3,1B,A3,0E,78,68,41,EC,2A,DF,C6,51,57,92,3D,56,EB,A1,EB,C0,C6,79,B5,8C,03,2F,F0,F5,F4,0D,D3,5A,1A,C5,B0,33,B3,9B,E5,31,37,73,88,E3,B4,B4,B0,0E,CE,FB,44,3F,13,C8,A0,51,89,07,E8,81,CE,4C,C6,16,14,C9,AB,06,BD,72,F4,A3,A8,2B,48,68,9C,05,54,5E,3E,8C,1D,1C,09,EC,60,49,CA,BA,54,F3,2B,A7,30,96,20,30,5C,ED,D9,AF,52,22,E6,4C,98,25,5D,30,D7,EA,2D,7B,8B,D0,DA,0F,0D,F2,4E,8E,AB,1E,E3,C4,88,9D,C3,05,49,88,7D,14,39,7E,73,D9,9C,12,5C,D8,18,73,D4,6B,7A,59,D0,17,FC,44,97,51,D8,7D,BD,16,D9,C3,EF,22,A5,98,A9,AD,58,4E,D9,16,D3,BE,87,01,B4,24,23,6D,1F,D8,52,11,F2,88,88,2B,C4,49,85,62,69,1C,E3,9B,D5,0D,DC,B5,43,2F,9D,6F,8E,9A,43,F2,11,9D,41,ED,87,4D,35,2C,1A,4F,10,9C,8C,6D,4A,30,4D,61,98,EB,E1,D7,AF,39,7B,4F,D8,4B,20,E9,97,0C,06,27,74,65,57,15,2F,E8,31,18,7A,F2,82,98,0D,65,A6,6E,83,CB,AC,71,D4,C8,76,30,FC,66,71,4E,90,39,24,65,E9,89,CB,29,25,4D,9A,0C,51,04,35,ED,72,1D,05,14,BD,D5,82,BB,E2,3F,E2,AF,04,F6,28,73,49,6F,D7,D5,D0,9E,F3,CC,0A,F6,45,72,B9,64,86,FB,E2,49,15,4D,C0,A4,23,56,4F,EC,1E,66,2D,BF,47,97,6E,F0,AB,C2,7D,1F,22,F1,42,9A,61,DC,58,A3,24,95,0E,37,87,0C,8B,0F,31,65,92,6A,C9,03,71,48,F9,51,EA,E4,A3,CB,80,85,74,A0,76,D1,C7,E7,91,90,AB,A1,2E,CB,9A,E1,98,FC,A7,2C,C3,64,1B,23,8D,EA,3C,AC,FD,71,FA,06,5C,DB,03,C3,9E,61,42,98,CA,9F,12,9D,17,27,20,8A,CA,82,FE,F6,CD,1E,C6,7E,4D,12,CF,89,C5,B2,DA,DF,2E,87,14,63,C2,C9,DE,9A,8F,9B,88,7B,13,13,BE,F3,18,9B,BC,68,BA,1A,BB,77,EE,CA,18,5F,4D,05,BE,E9,EA,9C,D2,15,D1,EE,37,A5,AD,B0,73,9F,5A,A0,83,4F,67,EA,57,47,F8,01,99,17,5F,FF,38,05,87,B1,BF,F1,62,AA,59,E9,68,8E,C5,FC,1F,AD,5E,64,2F,D0,8C,DA,A3,6D,60,12,45,11,00,DA,F0,66,98,1B,DA,7F,0F,46,B2,9D,CD,DB,52,62,3B,05,6F,91,D3,EA,E2,F0,38,A1,99,1F,C5,3F,B5,A1,38,14,7D,14,B8,8A,47,3C,B1,3E,12,0E,E5,1D,4E,6D,87,B2,7D,93,04,EA,50,A1,99,14,4A,B3,D5,56,5A,85,64,46,A3,67,64,C7,F7,21,3D,F4,35,C2,66,EE,04,40,46,8D,F6,1C,C9,4C,D8,F4,34,39,9C,15,F3,5B,B5,2A,A5,E1,11,78,8E,9E,DD,ED,E2,B7,DF,BF,CF,33,45,C4,82,EF,19,0F,2E,DD,E0,AF,D3,AB,4F,6F,62,7A,30,DB,B1,FA,2D,A5,BB,88,EE,74,CD,1A,99,DE,A2,A3,9D,FD,4C,33,22,68,48,75,74,DA,85,55,80,46,C4,41,1C,4C,60,22,18,3E,31,21,C5,CA,A9,F1,C1,26,60,93,90,B9,FE,06,61,70,0D,B4,42,CD,79,BA,20,AE,A0,2C,24,B7,ED,5E,CD,7F,51,C5,3E,DD,1D,D2,EC,73,2A,26,55,41,8A,87,39,B8,4D,46,7D,61,17,9E,B8,8A,68,CC,5A,86,F6,B6,AF,04,A3,5D,35,60,5B,03,E2,8C,CC,0B,B4,83,92,AD,42,B9,36,9E,79,26,02,3D,C1,AD,8E,09,32,CC,1E,6F,14,D4,76,6B,00,34,7A,1C,9E,C0,AA,C1,B2,58,04,BE,0D,0B,8A,C8,95,54,EF,D1,E6,C4,A4,A1,29,08,E2,22,68,81,E6,4D,D6,13,16,6F,91,89,28,9A,6F,D9,2D,93,2C,E0,9E,A9,ED,84,C0,79,43,55,7D,94,F8,72,21,82,90,58,FD,8B,39,B6,D5,75,E0,78,5F,7A,23,B9,A7,9B,90,A0,D5,BE,4D,EF,3D,29,AF,D6,9D,7F,D4,CD,25,F9,F4,DB,7A,BE,A5,A7,58,56,9D,EF,E5,2A,B4,DA,32,B9,E3,21,72,89,35,B8,6C,F4,55,22,B6,73,CC,69,8E,31,E6,DD,4F,F5,42,0F,45,C6,2B,4D,B1,45,3C,59,54,6D,2A,52,3A,3A,71,1B,09,08,E8,B9,50,A9,E8,7A,C4,52,E7,B8,10,5D,06,AB,D1,49,48,CB,DA,FE,9F,58,E4,1E,07,C3,58,7D,6E,8D,BF,F3,B6,6F,97,CE,7B,C8,E2,AC,5B,45,CA,EE,1D,24,02,E4,95,FF,A7,80,E5,E3,1B,C8,87,64,D6,BF,41,E2,A3,A1,8F,C2,DC,6C,2B,E4,C2,06,DC,B6,FB,BF,A5,08,8E,60,F8,EE,4F,50,C5,F1,8A,02,46,66,25,63,98,D5,CE,6F,0C,C5,B5,D2,3D,31,AF,2E,87,5D,29,51,9F,FB,15,EC,27,A0,94,DD,58,E9,FF,3F,9C,49,62,1D,CD,3E,FE,45,A1,1F,53,96,62,9B,7A,ED,5F,39,EE,02,3A,3D,7F,71,84,9E,A0,3C,0F,68,DA,B0,43,22,31,48,E8,81,1D,93,01,E5,55,9E,72,61,58,D1,CB,58,A5,F8,99,4F,35,4A,6C,E2,CE,1B,A7,E6,CE,A1,AD,CD,64,42,BA,E2,2F,23,D8,10,0C,DB,F1,54,90,08,56,7D,C6,08,5F,4F,AA,56,72,EB,68,38,3C,EE,DB,C1,06,96,E7,94,8A,06,C0,31,A5,3E,3F,C9,9C,E1,5B,7B,69,2D,DC,F1,69,A5,1C,87,1A,E4,93,24,77,52,1C,4C,65,0A,DC,5E,40,DD,89,0E,A9,7F,6A,DE,2C,67,05,13,9C,FF,9A,06,15,73,D7,F9,0B,7D,E3,A3,82,2E,FC,FC,4D,86,1C,85,8F,42,F2,A1,FC,3F,C1,6F,D4,B1,89,37,14,08,AA,A1,71,BC,6C,BB,F2,62,B2,9B,91,D7,7C,9C,3F,80,56,A2,3C,B9,93,AF,F6,D0,CF,DA,1C,F4,9D,C9,9D,36,6A,70,1F,07,8F,6F,29,E5,DC,C0,02,3E,33,69,25,85,F4,BE,D2,71,17,A3,3B,9D,C1,13,6B,6C,1F,33,5D,36,57,B3,4B,51,B8,39,D2,44,29,4D,B2,48,7E,E6,3B,FC,A5,A4,B9,B8,D9,62,71,00,9B,24,C3,25,D4,B4,C7,44,DC,D2,62,F1,C1,16,79,9E,DE,BF,00,CE,04,A5,89,9E,A6,56,BC,2F,97,F5,1F,05,02,A5,37,E4,A7,7E,51,66,01,E0,95,8F,C7,D2,B6,96,D2,F7,1C,30,F2,FA,7C,71,02,D2,36,8B,47,DA,57,1A,90,C4,2D,29,35,9B,68,3F,C4,50,76,4F,B8,75,85,6E,5F,2C,C4,94,72,85,CF,A8,11,2B,7B,F9,19,6D,57,8B,7C,BE,3A,98,5E,AD,0B,B4,07,6E,CE,43,A4,D3,F5,80,FA,1B,78,56,EA,06,27,A6,C3,7D,E5,70,5A,06,2B,14,D6,B9,AB,88,30,95,57,C6,F4,3F,D2,65,B0,08,8B,A1,5C,44,EA,D3,B4,61,C1,10,96,A5,FA,BC,AE,E1,87,1F,37,1D,E7,FE,95,A6,6D,C4,E6,63,50,13,93,0C,C5,93,5E,CC,C0,CD,6E,53,0D,D5,72,75,AD,9A,CE,F5,79,A4,8C,40,E9,DC,86,99,B2,63,39,E7,7D,7A,DB,2E,94,78,96,25,1C,A4,87,07,57,B6,7C,E1,5D,26,F7,D0,7A,A5,5E,67,AF,82,2C,5E,32,8C,14,30,04,AE,5C,B9,98,B4,48,AB,80,B5,3E,A1,92,DB,51,D2,EA,5A,BB,69,81,55,EA,23,9C,F1,4C,D6,FD,FC,B5,C1,04,E2,EF,3A,2B,20,DB,1C,B2,F6,1D,87,A5,70,6D,9E,35,28,AF,D5,A8,B1,65,6C,25,0C,ED,26,D1,80,C6,D3,F5,4F,26,90,5A,81,D7,30,0E,6F,CF,67,C7,BF,55,72,E5,C4,2B,C1,ED,DE,4A,B4,3B,7F,71,89,34,A7,B2,8E,BB,58,32,E7,46,52,E1,5D,05,34,F0,CE,FE,6B,1B,CA,1E,59,B1,0A,8D,EA,2F,20,99,E5,95,84,9D,CB,6F,EB,1F,25,0B,74,0B,77,F7,B5,C6,24,69,8E,58,4F,AB,49,86,93,95,9D,EC,7D,18,42,CE,8F,CF,15,B3,31,6F,63,74,62,9C,07,0A,64,EC,AB,7C,17,E6,33,E0,61,8F,F5,4D,1F,94,4A,97,E5,AD,E1,C8,11,9A,D6,EA,FD,1C,5B,76,1F,12,FD,DA,65,D8,14,3D,55,4A,04,A5,B6,69,0B,AB,77,B0,71,15,98,9E,9E,70,90,96,5A,C5,AC,B6,95,7D,33,5F,11,C4,62,AE,AE,A2,95,FB,78,AB,A4,D2,09,25,BC,A0,CE,F6,BF,1F,84,DA,A4,60,DB,DB,31,D3,8D,7B,69,A7,27,12,E2,54,C1,1E,0A,80,8A,31,42,D1,08,88,FD,75,0E,6C,5A,BA,B5,07,40,21,FC,7C,64,D1,D3,E9,80,0E,8B,B4,8A,FC,97,D5,28,5A,66,B5,D6,65,C1,60,FC,ED,4F,FC,70,7C,EE,AC,06,8B,1C,F4,0F,AE,E6,80,73,0B,7D,5A,CE,7C,04,43,8A,47,E9,8B,78,40,12,CF,F4,94,3D,E7,60,E7,89,C3,E7,8D,42,44,C3,62,77,FE,C5,13,DD,FF,31,1C,41,1F,42,04,0A,94,68,99,1E,AC,2E,63,65,7B,9D,5C,4E,6A,3D,3D,7A,50,75,A1,F6,AB,E4,C0,E3,36,7A,C0,D3,76,8B,EA,B3,A1,A0,57,84,BC,C2,3C,98,86,D2,BE,96,A7,C8,F6,35,55,45,FD,88,A9,D9,C0,A6,D6,8A,01,74,C6,57,AD,43,EC,C3,08,EA,0E,5D,A1,6F,EB,71,3B,2A,99,B9,B1,AF,1D,3E,D3,7B,C6,9E,35,02,EC,54,AF,2E,87,F9,A7,BF,D5,E1,77,6B,FC,92,61,20,21,0C,26,99,D0,90,34,55,2F,B8,4E,B6,36,27,C6,06,EC,65,C8,12,02,5D,78,CA,68,56,6B,4F,C4,72,74,76,5C,5D,AC,AA,FB,34,FB,78,42,E0,8D,E3,08,74,26,5B,15,DB,E3,B1,A7,9A,53,CC,35,D2,AB,81,CD,6E,6B,C0,06,92,E4,ED,87,7D,09,E8,FF,9B,31,92,D8,4A,70,5C,B9,71,03,B1,2B,F7,01,A1,40,CB,0B,E3,10,F7,77,D0,A0,5E,FF,44,BD,DF,51,79,25,9A,4A,8F,76,A7,79,DF,D5,C9,99,CB,E0,1F,76,97,44,65,40,95,0D,E2,68,29,A9,49,82,9A,B9,0A,3F,55,D6,9D,83,3B,C0,D5,BA,A8,0C,55,A4,F0,8C,60,D8,77,C4,71,7A,D0,19,94,8B,D1,D4,F1,B8,CB,22,F0,2A,16,81,4E,E3,BD,42,63,23,C1,1E,FC,67,E5,25,92,E2,09,DE,B9,1A,1E,29,AE,65,23,BC,75,09,D8,FD,E7,68,7C,D3,14,5A,D6,09,A4,E7,95,A8,85,55,68,4C,0C,68,5C,C6,B4,D3,D5,8B,54,45,E2,77,00,78,F3,3D,48,3A,64,29,CB,27,DB,29,3B,DF,A6,9E,F7,1B,4E,52,CD,81,DF,1D,D2,91,C7,DD,A2,81,B9,5D,EA,99,25,F9,90,AE,74,BC,20,95,F9,32,97,24,AE,5B,F6,88,DD,5D,9D,62,37,84,31,F2,C8,38,68,4C,83,35,7C,B9,30,FC,C9,A6,70,DF,EA,3E,BB,9F,5B,1D,3A,70,C1,A1,A7,8C,AF,7F,84,0C,18,5E,72,E2,96,6B,EB,BF,90,DF,81,56,8A,4B,C5,B4,C9,05,27,0A,F9,45,A2,BA,CF,FD,DE,D0,0B,46,61,AB,AF,BD,CD,AE,2A,F8,52,E4,32,95,7F,98,16,14,B1,9A,9D,E3,82,D0,FB,33,4F,F1,8E,0B,0C,EE,F3,C2,5D,56,B1,64,A1,D2,08,B7,CE,AA,72,03,8B,01,A8,7B,83,A8,AB,E0,2F,B8,77,2F,D6,AF,20,38,B5,23,C3,C8,91,2D,79,3B,37,4C,95,76,96,9F,EC,4A,1F,27,15,2E,27,16,A2,41,35,84,8B,1B,ED,E7,85,E4,4D,FB,1E,91,E8,D5,31,AB,70,F9,75,2C,7A,F6,87,03,A4,A3,B3,C7,0B,D5,AE,52,1D,42,1E,FF,1D,BB,C8,6A,91,43,9B,3B,DF,31,A8,AC,F0,6E,96,BF,FE,27,C2,E7,EB,BC,04,A4,88,71,E4,EF,58,1C,B9,8A,A6,46,CD,11,A9,D1,71,CC,6A,BB,47,0D,67,A1,A3,81,75,F9,5E,EF,8D,12,81,A3,4D,F1,4B,74,E4,53,F7,B6,15,83,BC,04,51,F5,26,18,83,5A,46,9B,1C,AD,89,29,82,95,B5,9D,7E,DC,6D,16,48,4F,58,F2,30,65,54,F2,5F,1B,CB,29,42,8F,2C,43,D9,79,57,74,5A,18,78,EA,6A,0C,FC,15,58,01,75,18,AF,2B,5E,33,11,52,90,68,A8,E0,0E,DA,45,97,1D,04,64,F4,D0,7D,4F,60,A0,5C,0A,2C,F0,B8,25,88,50,7D,B4,9D,EC,25,C7,6F,14,EA,5C,EE,BA,89,14,04,4F,E6,54,05,A0,55,B6,0C,E1,09,B1,7B,49,19,12,FE,8F,FA,E4,2E,F8,EC,68,CB,8C,9E,76,4F,43,DC,AB,3E,79,02,9D,BB,89,73,73,C3,8C,38,57,7C,7A,2C,68,D8,C6,F0,BB,27,53,4C,3A,70,FD,F1,A8,AA,C9,D3,44,D8,83,B6,58,7C,A4,F5,E5,BD,F4,44,FC,E4,CE,D1,59,58,BA,79,CB,53,7D,08,DC,ED,35,FF,C0,D3,D1,99,1A,8E,5B,D2,82,F7,CB,5A,F7,20,6A,AA,81,7A,30,F5,24,6D,D2,D4,42,7E,75,D7,87,11,7B,42,B3,8F,F7,35,34,98,0F,7C,C9,C4,C9,69,76,05,E7,10,40,15,D6,1B,95,5C,3B,2C,B7,BA,44,3A,1D,A3,43,22,87,81,57,6C,D5,6F,26,F9,55,09,39,3A,DD,FD,B6,1F,11,55,50,3B,50,C0,2B,BE,D6,C6,78,BD,91,69,C1,11,85,10,6F,19,BC,AF,61,84,80,C5,31,28,8C,18,0B,F6,DE,38,41,1C,1E,8C,88,4F,7F,07,52,08,94,57,7B,87,61,6D,4E,D9,42,B1,48,28,9D,AE,FB,2B,E8,7D,A9,DD,62,7F,7A,78,18,44,AF,3E,D8,3E,E3,43,8A,77,5E,3F,75,D7,9C,69,F6,8C,87,DD,DC,DB,B5,A3,08,C0,61,C9,32,BF,4A,36,D2,62,C6,C7,4E,B0,99,EF,7D,CD,1D,70,05,4C,EF,40,EF,7F,C0,B3,AC,B2,D4,9C,83,1D,1A,EF,E8,37,89,DF,96,5B,38,99,AF,3F,7A,C1,02,52,A1,75,A5,ED,5F,A5,4A,C2,DB,64,0C,1B,98,67,C1,E0,6E,21,67,63,EE,89,94,D1,2A,86,25,B5,B3,44,0D,02,39,CC,4E,74,83,73,92,86,6F,37,89,DD,42,7C,29,B4,A4,9C,12,A9,56,54,6B,55,85,37,1E,A6,25,7E,54,77,D0,96,4C,24,E0,FC,3C,DE,51,7D,73,2C,77,8B,EE,D7,46,5F,3C,87,4F,1E,D5,88,4F,18,23,83,6C,24,A4,9F,62,D1,9F,63,E0,67,63,AF,FB,E3,0B,E5,CB,39,F5,8C,10,BE,7F,EF,BE,5F,52,E0,D8,62,68,6E,8B,C3,AE,F0,9E,55,81,6E,AB,5A,84,47,FB,88,69,39,DA,C4,26,A3,89,D6,9F,8B,84,1A,DE,3C,79,E6,B1,25,4A,E7,D1,5E,78,93,63,00,9B,16,23,9C,36,45,BC,26,91,1A,08,DC,BB,F7,E8,DB,46,86,E8,B8,0C,68,C5,3E,75,9B,09,A2,39,1D,68,F6,EF,7A,AD,AA,CB,57,DF,89,23,81,C9,0F,FE,75,22,A0,32,48,FF,98,68,E4,12,7A,5E,8D,E5,39,4A,5C,3F,5D,8C,16,4E,2E,B1,A3,03,60,19,2E,6B,39,83,BB,D7,3F,BD,71,0D,D8,C4,DA,85,76,E4,2D,06,BC,82,62,CE,3A,18,FA,B9,5B,11,85,AB,A9,91,3B,C0,45,AD,D2,DD,8E,9E,63,8E,38,AB,6F,10,B0,35,88,17,9B,B0,60,86,66,54,08,C6,9C,7D,2B,A0,29,2C,CF,90,9C,30,17,C9,F7,7B,78,C7,88,7A,2E,0B,56,D7,00,F9,9D,8E,05,74,72,6E,E7,03,6F,1D,AD,28,60,B7,57,6C,13,4A,11,5E,7C,7B,C8,B0,DC,6E,B4,9D,0A,35,C6,9F,18,74,72,F3,A4,06,5A,B9,A5,C7,CB,35,74,C0,C0,AA,A2,5B,3E,EA,1A,46,43,E7,D4,C9,CB,D5,65,11,9C,6A,54,6F,43,BE,E0,29,B6,0F,4F,CD,82,D6,81,4A,AD,45,73,6B,94,32,5E,2A,14,A4,D7,13,30,3E,F4,39,9A,57,18,96,06,AC,1F,4D,0D,34,47,90,18,E8,48,D4,88,69,02,F5,0F,FC,47,BC,7C,25,54,17,3C,26,52,2C,B0,A3,44,5D,CF,AA,37,B8,A1,46,5A,4D,32,C1,3E,5A,C4,12,BC,40,7F,68,14,4A,AE,59,95,59,89,B1,07,57,69,08,9B,FC,47,F0,8D,84,8D,7E,2D,44,71,F4,42,E9,AC,26,58,98,50,E9,2D,40,F1,89,FC,A2,FB,28,6C,38,6F,53,A5,66,87,B9,B6,80,19,06,98,CD,19,6A,87,D5,1F,FE,53,04,1B,2A,60,1D,0D,E3,C4,57,4A,BA,DC,25,31,13,B6,55,2A,10,A5,07,35,F3,79,BC,44,ED,6F,93,F8,49,7E,66,23,96,85,AE,99,E4,75,97,24,84,7B,F6,F6,03,98,B6,31,FF,2C,11,03,C4,31,35,06,DB,95,52,2C,16,FE,4F,FA,48,73,F6,63,ED,9D,25,BD,EB,E4,69,56,E2,20,6C,4C,CD,47,98,CB,E8,EB,EC,98,85,8A,C8,B2,B1,E4,47,7B,21,A3,20,2D,FD,CD,B4,50,1B,37,1F,88,56,A6,3B,B8,1B,63,84,01,9D,97,4C,E2,31,E4,7E,CF,8A,65,EB,2F,5D,58,39,C9,8F,8B,4A,E7,CD,FF,4D,D8,7D,A8,67,BE,84,12,2E,64,A6,EF,08,E3,59,E6,92,FB,58,B8,0B,52,B8,89,3F,89,B6,6E,C6,DC,CA,11,2C,67,CA,77,25,5B,D1,F1,25,C0,B0,8E,AF,CC,BB,BB,A5,46,09,8A,19,CC,69,02,56,EF,1D,5A,5A,A6,FD,B4,07,DC,B0,DB,E5,21,0E,93,BD,AD,27,01,C1,27,D7,C4,8E,88,08,7D,55,4F,4A,63,A2,63,B6,7A,62,C2,0D,F1,5B,94,C4,DD,67,02,82,89,FA,5C,54,9A,27,FF,80,81,5D,5E,E6,13,B3,9B,F8,0D,DE,44,B2,41,A1,DE,85,8D,20,25,ED,B6,F5,2A,06,81,4B,CC,E4,E0,44,1D,D3,59,13,39,41,FF,6D,93,B7,F2,D6,34,4D,D1,06,B5,03,8D,4C,2B,08,F5,9E,96,AB,52,EE,75,54,D6,7D,DC,D8,58,03,35,A7,8C,BE,CD,C1,6F,4E,14,F3,B6,AC,91,3E,AC,1E,5D,F2,66,EE,08,9F,EA,25,6B,B9,D0,B9,43,F1,A7,83,78,75,65,B0,A8,17,6F,63,3A,E2,01,8E,FD,C9,05,8A,8A,BC,BB,0A,C9,68,A4,BF,08,5F,AB,F2,C0,FC,FD,B4,05,1F,BE,4A,26,08,08,3A,2A,8A,A4,A7,98,CA,88,21,62,69,96,28,7D,F7,0B,FE,27,60,CC,9A,68,4D,A1,7C,29,0D,10,8B,2D,4B,0B,BF,F7,85,C4,7E,82,B2,6B,2B,A9,6F,45,CA,2E,99,F3,D6,AD,1B,F8,CD,CF,40,CF,EF,59,85,C7,C6,0F,8F,78,00,5E,51,E5,9C,69,2F,8B,C1,E9,B8,FD,C9,3D,02,9B,73,94,00,41,2D,27,69,07,34,7E,EF,94,F2,5E,AA,47,41,68,38,95,AE,FD,30,E7,1A,6D,5C,5B,B8,47,B1,84,B0,CD,D5,44,D8,53,EC,2C,2C,90,21,8B,99,11,B4,F9,27,C6,A2,DE,AE,38,55,8B,27,73,53,13,DC,A4,B6,9C,20,DA,72,3E,C8,42,33,E9,C0,9C,E7,03,8B,3C,DB,72,31,33,EC,5A,D6,48,08,AD,65,66,91,C6,D7,9A,49,C8,B9,5F,DF,EF,DE,DC,83,28,A8,0E,93,E5,3C,9E,00,04,B6,B4,34,3C,45,46,0D,07,2B,D1,78,CF,A9,70,A7,17,57,86,01,50,90,D2,D6,1E,2E,54,8E,03,61,EB,F7,99,D9,73,FF,AD,29,CB,F5,9C,23,FF,EA,A8,6D,94,94,2E,AE,4A,51,6C,70,99,48,11,12,40,5A,44,7E,B6,8F,08,AF,3A,6E,5B,B3,8D,68,89,22,01,8D,CB,2A,DA,2D,30,AD,2C,7C,92,CC,AC,20,58,5B,72,9C,AA,A5,4F,21,45,0C,D2,94,A1,FF,45,4F,42,F3,12,94,3E,AF,64,D6,B2,EC,82,22,A4,79,46,D9,E8,90,3F,99,36,51,1F,28,AC,3F,02,A0,85,66,97,08,48,2C,F6,CA,B8,3F,D3,3B,B7,54,F6,8A,BE,A9,59,18,7C,89,76,A6,37,E5,47,6E,C7,7B,DD,77,3A,D0,55,B7,9A,ED,92,A5,14,05,16,FB,9B,43,76,5E,76,CD,64,8C,D3,32,39,02,97,6B,A4,DC,4D,D7,6D,9C,1D,A7,68,AF,1D,37,61,35,77,D3,FC,FC,6A,74,99,92,2C,B8,86,6E,9B,0A,97,76,DB,23,88,F0,22,F9,7A,D6,70,F0,2A,19,79,DA,11,04,0A,4A,30,C0,F6,28,C0,D8,12,17,20,08,0F,EB,F8,74,F2,D5,A0,FD,4B,FD,80,94,0D,29,24,9F,6B,DF,C0,41,1E,BF,25,BF,D0,81,6B,99,3B,61,38,61,69,61,22,94,84,35,38,79,C3,E4,BB,9F,54,33,28,85,20,C1,84,B1,D2,38,CD,D9,DC,B3,D5,7F,FC,DE,C8,03,BB,F2,0D,27,B6,7F,4E,3D,E1,07,5C,1E,82,E4,42,92,7E,6B,43,9C,17,CB,3D,FE,31,70,D8,22,E1,E4,44,93,F8,C9,FC,88,42,64,F7,AB,26,48,B1,05,6F,85,43,AF,63,2D,E2,10,C0,E4,B5,E4,B7,50,5E,ED,F7,26,FD,42,DD,70,56,9D,EB,5F,6E,B2,CD,29,5D,68,72,4E,EF,B0,FD,5C,62,35,B5,E0,BD,A3,B1,FF,12,A5,ED,B6,30,FA,EE,B7,2F,94,08,1B,1E,12,D5,33,11,D5,58,C1,A6,38,9B,39,B9,3B,3A,CA,0D,A9,73,B8,B8,23,48,E9,3D,03,59,7F,2B,F1,7D,49,60,F4,B0,14,A8,59,C9,0D,AB,9B,A8,CB,BF,24,4F,A9,36,E6,8D,3A,79,46,54,48,71,7F,CE,D2,E4,75,0B,F4,FD,31,A5,94,1C,EB,A5,60,BF,1D,E5,A3,9A,4C,9A,D0,C6,AC,CE,17,1C,9F,E2,57,3D,EB,53,27,B1,F4,C6,F6,DB,3B,23,97,3A,93,EB,45,85,60,F1,C4,A8,83,88,88,84,0B,D5,89,6A,AF,0E,D2,7B,A5,3F,81,0B,0E,EB,A0,13,F0,67,C3,20,85,A5,50,D9,E4,CD,B2,B0,EC,42,23,30,41,1E,12,9B,00,BA,B5,F5,F1,0D,F5,3C,2B,64,9E,C6,03,9E,CE,5E,14,B5,7F,F0,55,97,0E,24,54,90,5C,7A,28,C3,09,34,E6,9E,F2,48,71,D9,87,7E,4D,AA,C5,E1,51,58,07,04,B2,19,1D,8A,F4,B3,13,F8,FD,D3,E4,D1,E0,F5,5E,0D,52,A1,FD,4A,04,37,75,DA,8B,AF,57,14,C7,7D,A8,76,66,77,31,60,80,4F,95,44,BD,E7,8F,81,12,28,D1,D4,32,D1,21,03,D3,5F,F0,E3,0B,A4,34,14,F8,21,68,96,C1,68,52,1F,CA,80,88,92,F8,6E,AB,22,53,39,E5,D1,C8,21,3F,45,2A,85,4B,C7,27,09,27,85,4A,5A,FB,37,F8,4D,B3,81,08,64,9C,EF,AB,9D,D6,78,AD,2A,2F,00,A2,EA,70,D8,FA,EC,8C,A1,06,A7,15,0C,C5,1C,90,24,CB,56,70,9C,5F,F1,3D,9C,17,39,65,3D,D3,E4,9F,B2,EE,71,C1,2D,A9,16,AD,09,6D,CF,5A,CE,38,37,DA,EB,8D,0A,A0,BA,4C,1B,49,F3,60,CF,A1,08,D0,6E,AE,D9,1C,C3,2A,7C,B9,3E,94,1F,B0,E3,F3,43,08,6D,DB,27,4A,2C,3E,A5,0B,A9,EC,AB,20,E8,F9,AB,E5,28,9A,E6,5A,B1,46,98,F4,AB,28,E1,B9,9A,48,BA,4F,95,F4,3F,5A,38,BA,F6,82,5E,64,6D,FF,2D,17,3D,F0,26,51,51,4A,27,09,47,A7,48,24,92,FB,DC,24,FE,1E,C3,82,55,0D,4A,C5,09,88,3C,03,37,3F,86,30,7F,57,E1,9E,70,E0,53,25,DE,46,0E,F9,23,CE,DF,51,F4,11,81,A8,55,DC,64,16,7B,52,13,D6,DB,DA,B1,E5,23,95,2D,5D,8E,5A,5A,B9,B8,87,B8,63,C9,F4,3D,0D,52,32,31,D2,6A,33,ED,ED,BF,62,21,4B,AC,71,DC,B6,77,87,B0,7B,D4,72,F7,97,F0,21,28,D5,9D,28,89,26,A6,63,57,D9,C9,AC,05,3A,48,3E,BC,83,AF,17,9B,76,04,7F,B6,B9,B6,6F,B4,E7,41,D7,D1,8E,53,01,A4,56,D9,7B,0F,69,51,55,4A,B0,3E,37,43,7A,EF,6E,8C,E4,AF,EB,4B,0E,6D,69,26,0F,77,D5,D7,9B,9E,D9,D8,8A,A2,01,D0,62,0B,17,3B,E7,EC,C9,A2,10,F6,8C,8F,3B,CF,1F,0D,63,27,5B,7F,EE,4A,D6,5F,01,5C,26,CB,69,F0,99,4B,3F,CB,D2,5C,24,E4,15,CF,2E,1A,6E,F8,D4,B9,40,AA,8E,7E,B5,A8,0A,4C,02,CF,DF,A3,19,B8,8F,9D,1A,6F,F6,5F,0F,62,B9,33,37,2B,38,A0,53,0C,DD,9D,10,AD,39,DF,2E,8E,AA,FB,91,48,4C,55,B4,C8,C5,8E,DF,15,2C,40,05,EF,71,25,C3,02,1E,6F,19,FE,9E,DD,6A,1D,D2,31,D9,39,83,0C,4C,AE,A4,59,BB,93,0D,49,69,B3,5B,EF,1B,37,8D,CF,90,35,88,13,72,BE,46,DB,A7,51,5B,2F,9F,66,30,04,19,C9,0C,66,89,D4,1F,9F,8A,18,23,21,53,70,CC,5A,F6,4F,1F,7A,16,8C,15,17,CA,6C,CB,45,18,A6,43,B6,C7,A6,64,CE,F3,2E,B8,75,32,59,B7,DE,64,35,C2,AB,F5,92,53,90,73,3B,D4,D8,30,EB,4F,6D,D2,FA,60,C7,45,43,63,63,9B,D0,3D,A2,99,14,F1,8B,00,33,B9,73,5C,B1,D4,D5,E2,68,A7,B1,D6,F0,27,E7,42,A2,07,BA,1A,4C,2C,BA,10,68,92,8F,28,5F,D6,B7,5B,CB,A7,11,AC,57,3F,53,3D,DD,3B,B4,68,AD,6D,38,8C,A5,77,41,B2,DD,BD,D2,AC,4A,3D,20,4F,A0,94,DD,C8,72,2F,37,00,26,2C,CF,A4,DF,A0,F8,CC,A6,A2,2C,39,F9,A5,EE,69,52,CF,62,1A,4D,E1,D3,72,B2,D6,8B,CE,C6,FA,E0,F1,5D,B5,C4,1B,B8,86,6F,A7,DE,65,03,93,51,72,38,74,6A,1F,87,DB,29,1D,29,8A,79,D6,71,A2,78,9C,F3,EC,FB,0F,96,48,99,93,FB,FB,3C,AA,7E,5C,85,A6,14,F4,41,52,23,AD,EA,4E,DF,88,2C,E3,5E,11,0C,EC,02,CE,61,F8,A7,2E,A3,B2,7D,86,65,D1,F0,D3,A9,E7,E1,F9,78,1E,74,CC,81,56,3B,10,0C,5C,3E,11,A1,88,FE,62,3A,90,F1,87,10,2E,36,21,DA,DA,14,FD,FE,F7,C3,97,A9,59,99,E9,FE,E8,38,BC,A0,C1,12,41,A9,77,23,21,54,4C,08,6C,73,9D,03,93,9F,EF,A8,50,73,A5,D7,29,69,13,A5,1B,99,9D,CF,E6,CD,FD,C0,14,DF,65,8A,7A,BB,7B,E1,2B,03,50,32,FC,11,22,75,55,5D,DA,62,36,CF,50,44,E5,9C,E7,4F,B5,3A,A4,03,B1,A7,89,8C,96,D7,08,5E,79,81,0B,AB,58,E4,60,1E,BE,43,3D,1A,33,D5,C4,EB,1B,DD,66,A4,AB,06,35,40,35,83,B3,6E,76,BD,0C,89,96,7E,00,91,DB,99,81,2E,85,8C,B6,62,93,9F,04,BE,D9,F7,50,13,76,15,7D,52,38,BF,5C,B3,20,FC,1D,D5,A3,0A,26,C3,E2,51,15,6A,DA,B8,74,37,09,3D,1E,68,C5,60,FA,49,E0,B0,A1,27,16,C4,AA,2E,EF,5E,D6,A8,FD,A8,78,46,C2,A5,1E,2F,0C,2D,F6,07,51,3C,58,0D,16,62,B7,32,27,37,D7,17,EB,DA,2E,67,F2,B0,F5,BE,A7,D8,1A,45,B8,57,30,23,4D,C6,59,B6,EC,76,56,52,B4,47,39,6A,4B,77,D0,5E,0E,62,E0,05,0B,D1,66,45,3B,90,A0,E8,D2,A4,FB,45,0F,3B,D0,6E,34,AA,49,68,7D,09,E0,66,D7,75,8F,3B,9C,D0,ED,A5,E9,30,5C,F0,37,B4,FC,D9,88,C7,26,2D,3A,12,D6,15,49,44,29,66,8E,AD,8F,90,27,00,66,4B,CA,24,69,FE,4D,44,69,69,2E,0F,86,1E,95,A3,98,2F,FC,DE,E5,88,B1,8B,2D,56,E9,0D,38,3D,A9,80,C3,1C,00,74,8A,0C,72,84,B3,DC,90,17,9B,01,3D,5E,4C,CF,3D,FA,6F,E1,64,8E,7C,33,18,8C,E6,1B,D6,CA,F5,0A,A6,77,62,BF,18,5C,62,2A,6E,E5,A0,5C,F4,0B,8A,38,45,D1,AB,00,97,16,EE,86,95,81,1B,7D,7B,3C,D2,81,58,94,B3,B8,E1,FB,28,0E,4E,FD,82,F0,92,D1,94,73,07,9F,81,60,29,24,BB,30,7F,41,14,8A,6F,1B,26,D3,91,FD,9A,36,A6,09,EA,AA,A6,A6,75,63,D5,74,13,BF,7C,E8,33,BC,4A,81,7C,FA,65,1C,70,A0,90,E2,60,A5,18,69,9F,F6,FF,5E,06,6B,2E,2F,9C,92,A4,F7,83,C4,1A,9A,BE,01,8D,A7,9E,85,54,C8,C7,78,75,BB,FA,44,61,BC,07,2D,1B,D0,CF,D3,9C,B9,5E,E5,E9,06,02,1C,E6,A7,84,A5,08,05,80,0B,20,9C,D4,92,13,DA,53,9A,C5,0C,35,5C,E2,80,42,8A,5C,28,65,47,73,D0,90,A8,F0,C4,91,DE,A8,35,63,C8,21,62,EB,25,BB,06,BF,D1,38,46,A6,B4,D4,F1,B1,A7,13,7B,FA,CF,72,6B,A8,EF,4D,6F,BD,C8,66,7B,59,A9,F4,FD,F3,E5,52,03,7B,9D,CB,9E,1F,59,79,85,FC,8C,47,0D,41,2E,CF,DC,35,C7,9D,D3,74,B7,10,73,C1,2D,3C,CD,30,8A,0E,B0,64,03,AA,5B,14,46,DF,A6,96,61,85,B8,36,9B,58,94,D7,28,34,FE,F5,6B,2E,E6,38,7A,55,37,B1,99,CF,29,B8,F5,CA,40,66,FF,50,66,48,7F,7D,28,38,8C,2F,32,86,FA,FE,55,FB,19,B3,FC,5B,BE,DB,B6,13,0F,B4,24,9E,E7,DA,B2,F0,97,C9,8A,27,FB,49,16,A3,69,96,6C,58,C9,83,62,72,51,62,F2,97,E0,FB,2D,8A,82,67,91,BA,1F,9E,A2,3D,4E,65,A5,5A,77,C6,7C,0F,7F,8C,46,CD,A0,83,F3,ED,32,62,FA,8C,CA,52,F0,C8,84,25,5D,FA,E3,E8,1D,55,59,D1,A1,E6,68,58,94,5C,E3,AF,0E,46,74,69,2A,E2,0C,FA,E5,A7,46,27,EE,FC,B6,D1,77,9E,CF,DB,51,37,2C,6B,02,85,19,24,4F,F6,F9,4E,25,AE,69,5D,60,E2,B4,16,05,9B,47,4E,12,E4,12,D5,72,94,75,72,4E,A1,15,87,58,2A,93,D8,2F,93,8A,F5,70,A8,DE,3D,E4,B9,5F,62,4F,CC,7C,CA,40,1F,A5,35,78,7D,8B,B7,AA,CC,68,56,58,4B,A3,AA,1E,2F,C0,CA,ED,5D,E4,18,26,FE,8D,09,2C,06,B3,E5,33,7C,38,81,B1,79,2D,15,8C,6F,05,3B,AA,24,05,75,21,08,1C,DE,51,FD,40,AB,C9,70,F2,CB,8A,A1,96,8D,3D,50,E9,6A,7C,69,D5,38,DB,75,54,DA,6A,91,F2,F7,93,E0,C0,54,A7,C8,F3,C0,0F,43,49,CB,67,5D,E9,AC,77,A3,DF,CE,30,4C,E5,BF,98,A6,EC,49,26,0B,A3,9B,72,B6,E8,95,32,0C,3C,B8,B4,FE,54,56,7E,E0,58,6E,D2,3F,9E,4B,60,5C,AE,BA,A2,D3,1B,0C,13,52,69,89,D0,3E,6D,47,4F,37,E8,15,A3,64,32,5B,C4,3F,92,31,54,F3,71,2D,62,4A,0D,D7,C6,7F,F7,2F,DD,5B,E7,E2,A9,F7,6B,A9,1F,3E,58,62,5E,A8,57,4B,34,A2,E3,B8,7F,B7,F8,79,DF,01,4A,AD,99,16,AD,FA,A3,E7,EB,25,E7,A2,C0,44,B5,99,64,C6,C9,70,38,7C,85,65,3E,8F,D8,B3,BE,1E,86,2C,52,51,13,5A,07,73,88,B7,0D,C4,E8,0F,20,CA,69,21,33,B5,F1,4A,6C,EE,B1,1E,19,93,3F,09,98,AB,76,A5,7C,F6,B5,27,11,3A,06,31,7E,10,09,25,3F,1D,FA,46,F3,5E,0C,BF,EC,E1,E8,AB,CD,47,C4,72,A2,4B,4D,A2,E0,25,D8,7C,E8,52,09,2A,C3,5E,DD,9D,2F,6A,56,E3,D6,F2,4F,8A,72,3C,42,6C,04,F8,9E,10,DD,15,09,4F,11,96,F0,B9,55,2C,8D,06,5C,3F,06,3E,16,E6,77,FC,FF,C1,A1,A8,62,4C,7F,96,90,75,04,17,E0,DB,A2,A0,D2,13,DA,F2,2F,EE,F8,F6,D7,D6,F8,55,1E,15,E8,A1,77,04,DB,78,B2,F4,9C,16,6C,4B,B4,FE,80,F6,B5,F0,AF,29,DA,F5,CE,29,36,09,9B,AA,00,8B,1B,CA,42,65,67,00,0F,5D,88,AB,53,30,DA,19,B0,97,72,55,69,E8,4E,7E,D1,FE,BB,18,1F,C1,FB,BB,72,3B,D7,8C,6D,31,49,74,C4,8D,CA,9F,FA,B4,9C,83,8C,63,8E,18,78,D6,13,62,0A,00,65,E6,C4,E6,8D,27,0E,8B,47,D4,EE,A9,B8,D4,35,FB,4D,48,B7,C6,38,61,72,2A,B9,94,5E,02,C4,74,82,4D,EE,E9,06,35,87,31,45,8B,33,9B,EE,A2,57,56,17,0C,B4,22,9A,43,DE,2A,3A,18,FB,F9,77,28,91,E9,8A,3C,CB,B1,16,1B,A0,E8,68,39,A4,B9,FA,E1,53,B5,75,65,A2,10,C8,40,53,A8,5D,62,A2,59,0A,C8,4D,85,43,8A,4A,D7,5A,54,3E,A7,B6,F1,96,11,50,09,8C,5A,7A,3B,4F,9D,14,E0,CD,2B,BE,2C,01,6C,9B,62,B5,51,2E,EC,E3,0A,5B,CE,E6,7C,7B,F2,E5,99,F7,BE,6B,08,2B,C7,FD,BC,36,3B,90,66,84,8D,77,AB,85,0E,9C,B0,DB,4A,FF,2C,BE,69,C5,32,A5,A4,CF,C3,A1,51,12,39,BE,7B,43,E7,3E,BD,69,06,A0,BE,BC,EE,A6,19,B9,DB,CB,99,86,79,F1,E7,C3,E4,1E,E0,F5,F0,CB,6F,B3,9B,43,BC,DE,57,D0,17,60,CA,DD,E8,D0,8E,EE,F2,A5,21,30,D5,52,F4,C2,DF,E8,0E,D7,DC,9F,B5,5D,B2,95,93,3B,74,C8,8F,C5,7D,CD,97,92,D1,07,40,88,03,9B,70,70,81,79,8B,25,9B,4A,36,26,B9,FC,3F,9C,4C,D4,1D,23,4E,84,EB,67,7F,19,9D,8D,CD,A7,13,2F,7E,78,0F,0F,99,E8,3B,F8,C4,5B,E9,C5,E3,87,98,9E,B7,F6,B3,F2,25,F8,17,88,F1,FE,84,03,F2,90,E1,0A,1B,84,F5,80,B1,5D,ED,43,E1,B3,A2,C8,BB,8D,E9,DF,86,3E,27,6F,1B,F1,00,75,94,8F,1C,3E,CB,46,A0,5F,73,91,B0,31,AE,3D,3C,35,6C,1A,4B,DB,4D,96,1B,CB,DF,DA,25,98,76,DB,1C,A1,D8,B2,15,5F,F1,12,F7,E8,39,8F,70,B1,5E,2A,DA,DB,48,53,8B,5E,89,7F,27,0B,1C,06,E4,BA,81,2E,B3,75,0A,9F,80,4D,13,86,74,AB,B3,75,7B,63,F0,8C,E0,E4,E6,1F,35,99,34,4F,2A,9A,3E,C7,99,67,DD,C7,87,E9,9B,4C,EA,27,46,B5,A8,59,E9,26,1A,28,50,12,4D,C6,4E,62,2D,C5,1D,8C,27,10,52,2C,75,53,BA,36,05,9F,FF,B1,A8,C0,42,63,30,44,4F,CD,D7,B3,57,48,D4,D9,3B,41,E2,08,BB,CC,25,BB,09,81,66,26,60,CD,90,73,9A,CA,85,9A,27,E6,FA,12,E6,17,A9,E4,A1,62,A3,B1,5B,35,5A,EB,48,DE,8F,C9,4B,45,9B,A7,67,30,B2,B6,4D,05,11,82,E9,9A,BA,68,8A,E6,74,C2,0F,8C,C4,4D,CD,CA,2B,D2,23,8E,4C,22,0B,A1,DE,D8,58,24,AA,B1,39,EA,64,28,28,80,1C,ED,1B,FA,44,F3,F9,C5,27,7D,02,43,2A,5B,B4,D5,B2,2B,3B,EB,F3,9A,28,A4,10,4E,81,FB,B4,17,4F,C9,B8,2B,BD,79,B9,3E,40,E0,F8,99,70,41,9F,56,16,E9,43,9C,43,76,1C,6B,DC,A9,0E,2B,5B,9F,86,91,8B,0F,2E,00,B0,2A,07,FF,A1,35,02,7B,31,01,07,40,7C,20,6F,25,DC,5E,82,E7,66,9E,54,6A,70,98,DA,56,86,3F,D9,F7,66,78,26,4F,08,F1,BE,F0,19,F9,93,FF,4F,30,B3,D4,DB,46,79,49,D1,89,59,4C,A5,A3,BE,56,74,84,F5,EB,53,D6,9A,BE,0A,16,FB,13,A7,8F,50,27,F3,6B,05,9E,B5,6F,D7,34,0F,73,E3,A0,56,F6,30,EE,74,C8,2C,6C,1B,0A,0E,AD,48,6F,F7,BD,3D,9E,98,AF,AF,95,4E,C0,55,40,63,4D,03,BD,3D,14,9C,F5,78,DC,DE,AF,09,17,98,E4,D9,44,BA,11,8E,03,AD,E3,39,3E,25,22,2C,B4,F5,F2,EE,49,12,D2,01,38,96,64,D2,69,C0,B8,E5,F6,B1,53,DE,91,DC,EF,94,E2,2D,40,90,08,6C,10,63,1E,00,1A,5C,37,4B,BA,24,F1,8C,01,9A,2F,A7,19,C0,C9,F6,6B,AA,6B,08,60,F5,D0,60,AE,C1,3A,DC,A7,85,00,36,B2,CB,8E,18,74,53,B3,04,27,C6,B3,A0,14,8E,BF,55,E7,BE,03,C6,B5,3D,04,A2,D6,B8,DC,66,08,BB,F0,F0,94,BD,53,36,4B,BD,9E,AE,9D,14,9B,45,A2,27,3E,4E,35,CA,5A,56,16,19,93,39,B1,82,04,E7,BD,1B,D3,F3,A3,06,F9,6F,DA,86,C4,DF,8E,38,6F,5F,47,EA,3D,1C,0C,45,1D,8B,A6,58,54,51,D8,E8,91,A2,B6,9B,D2,6E,20,8E,7C,D0,0A,DB,AD,8A,CA,38,9E,C5,62,AA,4C,94,26,42,04,CA,FF,20,1C,4A,60,4C,99,01,58,08,66,CB,98,F3,67,3F,C6,F3,82,AA,44,35,48,2E,0B,0B,ED,F4,C3,2E,28,23,33,7E,31,0C,A1,D3,8D,1D,62,9A,99,9D,C2,CE,15,C3,AF,33,A2,BB,7A,17,87,53,95,95,8D,C5,10,9F,82,B4,33,53,B1,41,7D,59,2A,CF,DB,27,11,15,EF,B8,0F,30,06,A9,1C,D7,7B,24,2C,3F,3C,12,A1,D3,A9,E7,E5,A4,13,28,04,DF,43,E2,E8,41,B0,00,EB,DA,C2,3B,A8,59,F3,67,09,0D,B9,E6,0A,C8,D0,14,85,DA,2C,B9,10,30,34,58,DD,3D,36,71,5F,DD,BC,56,B9,5B,A0,E1,E4,83,DB,84,38,DA,E3,79,39,AD,A3,5A,16,E5,02,79,FC,01,3B,96,91,B0,BE,27,53,9B,DF,ED,84,DD,40,2E,58,EA,73,7F,6D,46,DA,72,3B,F2,49,ED,17,45,C2,5A,B1,FA,28,F7,02,B9,B4,D2,FD,AC,9A,42,E1,DC,CA,F2,05,AA,99,0D,3B,E6,E3,AD,0D,43,DA,B2,2E,EC,6A,1C,A3,69,96,7B,0F,45,12,1C,4B,42,3D,EB,9E,E7,F7,E7,2A,CD,3B,ED,12,1F,40,90,F0,1C,D5,E0,85,85,69,EF,7D,0B,51,81,FC,93,4A,01,10,E7,A3,59,09,59,EF,91,48,2D,14,01,DC,69,0C,B5,C7,96,11,65,EF,F9,AF,2A,CD,7F,D5,E1,C7,B0,5C,32,15,0D,83,92,A8,F4,73,FB,23,2F,3F,51,B4,7C,01,36,B7,EF,D5,1C,1E,2B,42,5C,FA,CE,F2,2C,79,A3,C9,AE,6E,64,68,45,B2,50,72,5D,19,E9,74,03,FA,06,B4,AB,BB,82,16,53,4E,21,6F,30,6C,AA,C6,95,BD,B5,15,3E,62,64,F9,71,B2,0B,C8,6C,94,0C,DE,CE,56,8B,39,E6,2A,1D,31,E5,EC,83,4A,94,17,56,69,79,06,6A,2D,C9,53,22,1C,F1,3A,E6,3C,1C,88,1B,8E,6A,5D,77,C2,0C,3E,13,77,82,CC,07,DA,6A,AB,10,98,4A,49,17,71,76,58,99,E0,BE,AB,D2,F4,BC,24,FF,A3,49,79,E3,9C,6B,76,83,06,A2,92,1C,81,88,ED,FE,4E,0C,3F,46,9B,B7,53,87,0C,D2,C9,33,D3,A5,45,FB,F0,36,E3,EB,E7,1B,9F,2B,1E,6B,03,C2,6C,76,45,4A,4E,04,34,0D,44,07,67,C5,55,6C,1E,04,37,7A,05,E9,8F,33,D5,1E,24,12,B3,C6,EE,3C,E1,80,7E,CE,92,30,93,D7,8F,83,B2,80,9C,37,CA,23,18,64,95,F0,DD,B9,B0,AC,0D,65,0E,AB,BF,BB,64,B4,02,E7,A5,68,59,43,87,77,C5,B8,DF,A3,5A,58,8E,71,3C,85,98,F1,33,0F,43,C5,02,E5,38,DF,AC,60,D8,60,05,EA,FC,FB,23,82,AB,32,51,92,DE,5C,AE,10,84,8C,61,A9,E2,AC,68,02,93,C3,ED,1E,C6,07,EF,3C,90,2B,51,58,17,AC,6D,06,F7,03,0B,6B,7B,71,16,EB,A9,C4,35,07,80,CE,9A,B7,3F,0E,C4,E2,E8,B5,BB,5B,DD,6B,EF,CB,87,FD,4E,FE,ED,43,1A,E9,1D,17,2C,AF,18,74,62,6B,18,5C,CF,69,9E,A8,68,16,8B,EE,01,14,1E,4C,52,22,FA,BE,51,19,09,3E,D4,1A,0E,94,91,32,7D,C9,35,E2,2F,92,4E,B9,23,ED,10,C6,28,E2,EA,A8,45,99,82,48,DA,AD,8E,28,A1,3E,94,0E,C5,6E,3E,DE,74,A2,86,1D,B2,5C,80,D5,C7,27,3E,EB,2F,F2,C0,82,AD,35,EB,11,DC,2F,F3,B7,9C,F6,E5,6D,06,BA,79,DF,49,0A,84,B6,5B,C8,36,5E,E4,9A,43,FA,D0,C8,F5,BF,D5,9E,39,AF,7B,54,BE,89,7A,70,AC,49,83,CD,D0,17,6A,5D,6B,FD,7D,01,08,05,9D,68,24,E5,D2,0D,B6,B7,EB,A5,48,42,67,93,77,F7,F3,47,7C,F4,0C,1E,D5,14,41,63,4D,5B,8C,16,F5,09,AE,A9,CB,F1,55,92,32,A7,AE,B2,AC,53,EC,94,07,86,0D,AD,3B,12,27,4C,08,5C,C1,12,18,D5,CC,EE,A5,25,45,49,8C,AD,F9,52,5C,CB,05,6A,D6,1B,EE,32,B8,E0,0F,97,CC,A5,CB,04,01,31,B8,76,56,67,6C,93,19,C9,00,AB,57,E8,60,ED,FF,9E,C9,F7,47,D5,BE,C5,C9,CD,B9,6B,86,CC,5A,1C,3A,75,32,A1,EF,52,8E,AB,22,2E,4E,A4,2E,44,DC,99,0A,70,A6,94,9F,39,30,62,21,CD,9C,FC,80,FC,B2,96,D9,3B,63,93,DB,18,07,DA,F0,C0,67,A6,F0,85,2E,25,20,36,EE,38,11,2C,CC,77,30,06,D2,B7,FC,E6,72,4A,F0,83,AF,45,B2,0F,A9,63,81,F7,42,12,6A,6A,BE,21,25,A1,3D,85,80,39,2B,D6,EA,FF,56,DE,01,FE,10,94,20,FC,B3,58,36,DC,C0,8D,FD,61,E8,B2,42,E8,92,60,B2,55,F5,DA,38,EB,06,C5,D7,6B,B3,53,DD,65,DA,B5,C1,D2,0E,4A,FD,0F,E3,6E,19,FE,CF,3F,05,B7,08,5F,00,9B,46,75,D1,63,F8,3F,8A,98,D2,C5,1A,FB,A3,6C,F4,34,89,EA,B3,F1,BD,56,30,5E,FF,5C,B1,DB,85,32,20,0E,49,2A,80,90,5B,DA,69,03,B4,53,86,CC,98,A7,4B,BA,24,EF,FB,A1,54,E4,FB,6D,D2,37,D7,C0,DA,4C,D4,C5,45,25,53,80,8C,6C,34,FF,7E,69,D1,51,2B,B6,21,16,35,A9,27,AB,67,2D,61,C2,C4,AF,BA,BA,CF,DC,F7,B6,16,E0,7A,C1,29,F9,E7,0B,C3,57,BC,3C,20,FE,8A,4C,DC,7F,DC,4F,65,D0,DC,78,ED,24,9A,56,70,68,A1,44,8A,76,CB,41,18,25,17,27,A0,2E,60,25,26,56,61,3F,C9,EA,42,BB,EA,A4,CA,FA,0D,E1,45,D6,76,8A,5D,27,BB,81,AC,38,D2,71,BB,7E,80,C1,80,C6,E5,63,34,20,0B,B0,C7,75,13,D7,F0,FD,0C,06,26,AF,54,33,3F,B1,2F,F7,40,4F,C1,80,48,5E,13,1C,3C,82,50,5C,10,F6,19,80,A4,0D,60,F9,45,62,FF,83,DD,A3,6C,C3,D4,C6,F2,F7,02,85,ED,5D,F9,DE,F7,DF,09,62,D8,90,2A,91,F1,DB,70,C8,BF,F0,85,58,CB,64,3D,ED,C1,D3,4A,1A,E0,23,88,C7,5B,93,54,D2,BD,70,29,68,8E,B8,96,1C,B9,35,28,BE,B9,E4,CF,5D,3D,60,3C,13,35,60,0E,BE,91,8F,39,BB,C3,AF,B2,E6,3C,B0,A2,AB,C1,68,B7,D5,C8,8A,B2,E7,4B,8B,97,DA,C8,D3,77,D1,AA,7F,2D,0F,CA,07,14,33,8C,A1,A2,E7,27,67,D0,B0,CD,E8,F5,5D,85,2F,C5,85,08,65,E5,4B,48,75,6F,2A,E4,AC,A6,29,56,ED,6C,5E,5A,92,F9,98,03,28,A6,66,FA,13,64,E7,11,10,A5,40,36,45,72,D5,14,A8,37,1B,2F,B7,09,47,AD,D0,D9,EF,C8,DA,BE,69,C9,0F,05,8A,E1,86,CA,31,52,2B,22,36,C7,CB,0E,5B,B8,EF,ED,17,2A,F2,7E,AD,E0,04,71,A2,75,90,87,4A,5B,4D,B4,24,C9,6F,14,DB,6C,5A,7E,7C,DC,46,94,64,AE,5C,AA,9D,26,E7,30,0F,4E,38,70,8E,0F,91,F8,31,EE,87,E2,FC,4B,A2,DA,CB,BD,8C,7C,C2,E4,B3,35,32,97,9D,09,16,21,14,29,C7,BC,19,11,FE,CB,ED,50,D6,CF,1B,84,E7,02,F4,98,E1,E8,7A,E0,E9,20,20,E2,67,54,FF,F0,E1,8F,D1,24,E2,31,02,2E,10,FA,91,37,14,0B,F5,02,CC,AC,94,F9,03,03,55,CD,2C,6B,03,1C,05,18,74,2E,39,F4,44,D5,0A,DB,4E,0D,08,FA,A1,B1,68,08,E7,55,9E,5B,8F,EC,9C,E7,BC,45,14,58,C6,1D,06,CE,6F,CD,69,B3,86,77,C4,77,DC,AC,F6,52,6E,4C,A6,0C,27,04,EF,75,7C,B8,CC,9B,A8,BB,72,3B,0B,66,31,72,4A,9D,EC,03,EA,F4,46,9A,00,BF,71,88,AE,14,F7,93,39,25,59,E9,59,BC,6E,B1,B6,1F,F3,85,6D,AD,5B,EA,2C,83,6C,6C,EE,76,2D,FF,75,A4,CA,25,14,84,07,9A,AF,43,47,26,EF,EF,69,D6,C0,5D,1E,CA,A0,88,84,64,03,52,E0,AF,1B,78,73,30,1C,A3,BF,0A,6D,83,41,D9,86,31,E5,8B,34,AA,14,E4,D8,1A,3E,5A,87,AD,FA,21,FF,6D,18,74,D3,24,EF,F3,FD,DC,97,E4,FD,DF,D4,94,DB,2D,9D,CA,55,E3,1A,F5,43,1B,0A,39,BE,00,3B,08,BA,60,AB,1C,E7,AC,C5,E7,A6,C5,35,30,5E,A2,6D,7E,B3,1B,E3,D7,0E,91,E3,53,C7,CF,97,72,5A,EC,F4,53,BB,01,6D,D8,FD,7A,A7,3D,49,91,0D,4A,70,22,DD,06,3F,D7,C4,96,7E,75,CB,4A,B1,32,7D,66,FC,B7,1B,60,15,01,DD,4D,39,72,8E,40,C2,3C,F9,CA,6E,A6,9C,BF,E4,01,EB,87,F0,37,56,54,A7,5A,04,14,94,30,F1,C1,E7,B6,39,22,BA,57,87,43,BD,67,6E,54,DA,7A,79,8F,65,94,7D,43,57,47,09,DA,9A,60,ED,01,69,90,A3,B0,0E,C9,9B,3D,CA,B4,DD,E1,6F,EF,A7,73,4C,B1,03,B6,91,8C,1E,84,89,6C,E3,24,15,44,02,4D,04,9E,C6,15,3D,DA,FB,CA,A4,0E,D8,B4,4F,69,67,F5,98,44,15,F8,D7,ED,53,CA,F9,B4,97,DE,4E,D6,87,1B,52,4E,F1,47,6A,B0,09,DB,B8,FC,2C,FF,BA,93,D3,AB,5F,EB,D0,9B,86,54,AF,4C,92,E4,A6,90,7B,8C,38,C9,BF,22,CF,AF,4E,E4,38,41,71,25,76,16,6D,2C,85,AB,E1,4F,DC,96,31,E8,BF,E9,6A,98,28,B7,EC,29,1E,37,B2,2E,51,39,3E,13,EE,1D,58,D9,00,F8,FF,3D,19,00,0A,1F,2D,99,AB,F5,87,91,E9,7E,66,28,5C,DC,58,19,F9,BA,C7,DB,0E,A0,AF,64,2D,16,E6,CF,EE,0E,D4,45,B9,B7,9F,79,A9,D7,F9,02,E0,D9,7C,29,C3,A2,F8,CC,E7,54,99,D2,6C,0F,9D,2C,C3,08,09,7E,67,EC,71,FB,16,3E,1D,94,10,2A,98,EE,C9,74,70,88,00,81,FD,43,C9,26,4F,37,71,D9,8E,56,F2,86,95,93,A2,24,10,DD,99,3E,A1,A6,3E,76,A0,96,2C,A6,09,C5,9D,A7,B2,53,8B,90,34,7B,A5,E4,7B,3B,E1,27,9F,75,39,09,C7,2D,3D,92,2F,AE,B7,DB,07,01,23,F4,FC,F3,DB,98,04,3B,F7,BF,39,CE,DE,B5,A3,6B,A4,6D,C9,FE,37,5C,94,5C,5D,92,E4,2F,BB,AF,A7,7E,CC,3E,A1,5A,23,54,80,64,17,60,79,F9,06,01,F3,4A,72,1A,7A,CF,FB,8A,E0,E0,D3,D9,7D,5C,66,EB,19,99,27,19,56,E1,12,99,35,BA,93,A9,A3,C5,3E,25,E2,CC,9B,1F,81,5E,24,F0,41,95,D7,12,8C,62,D0,F9,B1,29,00,7F,A8,16,5C,11,7E,A4,77,11,56,B4,E9,D3,38,AC,A4,C9,D1,76,37,C0,DC,50,DA,8E,55,4D,0C,1B,74,75,0C,99,31,65,22,FB,7D,CD,6E,C5,FD,CE,9E,A6,BA,98,1A,81,A1,FC,DB,8D,60,D6,EF,EE,2B,82,2F,93,6D,A1,97,18,65,DB,7D,39,48,84,09,55,F9,DC,A7,AB,CA,00,94,45,6B,A8,B7,24,42,68,B4,A7,99,D4,E4,50,59,A6,83,7E,2F,47,E8,F0,86,F3,45,86,3E,8A,12,2E,10,A1,2F,F4,72,BF,06,80,67,E8,EE,EA,16,EF,FA,5D,5E,E8,EC,F8,E1,63,89,DB,2F,BF,9A,96,5C,AF,BE,41,56,95,1A,49,08,48,49,94,A3,5F,5F,CA,B2,CF,8E,E7,F4,54,E6,C1,FE,93,A0,56,6A,15,A0,E0,7C,B9,04,5D,D2,2C,F9,38,05,59,2B,2C,72,81,3A,EE,83,51,48,42,5E,A5,C3,5C,D2,C2,7E,D1,86,2C,02,11,B3,AB,D4,D3,88,8F,99,7D,03,3D,4D,64,56,24,98,EB,58,0B,E9,76,BD,56,6D,EC,77,81,0C,D3,6E,12,F0,BC,C5,90,F4,9B,02,9C,74,08,09,D1,D6,48,4C,00,EB,41,E0,E8,1B,CE,BF,B4,DF,58,20,C5,79,7F,F4,4E,88,CE,22,21,43,6A,9F,25,EE,9D,CE,1D,77,56,CE,D5,48,F4,E7,00,0F,28,02,66,2B,FB,6C,23,66,66,E6,63,0E,B9,D8,7D,6D,7A,FB,A9,51,88,53,6B,12,19,89,B2,9E,B7,FA,CB,CA,E4,AE,92,98,71,7A,91,40,CC,88,1D,C6,49,97,ED,46,B1,1D,AE,5A,97,B5,67,FD,11,16,BA,4B,9C,D6,7A,2E,1A,D7,48,2C,3F,25,01,62,34,E2,5A,3A,6D,A4,F0,C2,AB,B5,2B,17,E2,95,55,93,2A,ED,5C,CF,27,0D,56,36,52,B1,F1,55,84,F5,1F,B6,23,D5,11,0C,DA,48,5C,EA,38,2F,5A,85,93,A2,BA,3D,92,05,25,36,9E,F4,0C,77,8B,D7,98,D1,BE,96,70,64,E5,32,D7,D6,88,99,80,C5,CD,CC,39,8E,F8,76,CB,96,F6,DB,2D,E6,74,E2,3D,02,53,E9,3B,B8,80,E8,75,9A,7D,BA,05,F9,8C,71,A0,98,3F,C1,DC,9A,16,E8,FD,8F,45,72,36,6B,B6,F6,92,AF,E0,0E,16,10,47,CC,F2,6B,7C,85,6B,E5,7F,D5,F7,AF,62,2E,C1,CB,B1,ED,B0,B8,75,25,0B,35,8B,94,C6,ED,D4,0A,3C,06,82,22,C9,F6,C7,DB,C2,FC,A8,4F,C1,10,A8,83,5C,63,87,5D,81,B8,87,6D,EE,5C,0A,AC,BA,4E,08,5A,99,B0,27,C1,51,C9,7B,FC,25,C4,23,AA,59,51,64,AB,46,0C,70,5F,05,9C,AD,91,01,A6,61,24,16,5C,A4,10,18,0D,90,EE,C1,CC,6F,35,E1,AC,E1,D0,AE,B3,11,09,E4,36,BE,A8,F2,D4,BD,48,23,CF,35,ED,2F,D7,2D,7A,FB,3D,27,03,EE,B2,0B,B0,43,B3,AF,23,79,79,FC,07,03,48,E2,2F,5E,47,0F,66,CE,26,4A,8A,B4,01,F0,91,A8,C0,60,A6,7F,A2,10,C4,8E,3C,81,54,FD,C4,67,35,F5,4F,42,38,48,21,95,88,E1,66,28,93,E8,E7,28,15,14,22,77,77,AE,4C,98,2E,F9,29,30,C2,EB,6C,8F,E2,35,E6,A6,C9,D5,8D,98,72,D6,7D,44,93,5A,C7,1A,80,06,07,BF,BE,CE,54,75,6D,27,6B,67,76,73,60,7F,73,06,9C,9C,B5,84,B0,BE,DC,AB,E5,39,73,F8,41,0B,20,E5,54,06,63,66,89,9A,6E,35,3C,AC,C9,7E,18,0D,B4,63,96,F3,9D,94,16,2A,D7,DD,92,1B,72,95,2B,4A,23,12,BA,2F,FA,8A,CC,DC,12,38,75,AA,45,B6,F8,CA,CB,BA,9F,8C,6E,36,F9,D2,7D,41,A3,D2,17,E0,6A,4E,C5,4F,CB,D3,2E,A5,A9,0B,2B,83,CF,B4,0A,37,51,68,22,B1,58,95,F9,3F,7A,4A,72,6D,E4,A6,C5,B3,0A,29,49,DF,1D,92,17,32,FF,8B,27,45,66,F0,4C,A2,1B,3D,4A,3D,6A,BE,03,67,4B,60,CC,35,FD,AA,8F,DD,43,B7,72,4B,BA,25,05,7D,54,DA,5D,9F,8E,E4,B8,CC,FC,7F,CC,42,EB,39,26,F9,3A,6D,1B,D8,FE,C9,5B,7C,69,E2,D7,F1,44,81,19,CF,17,00,8F,9E,34,E1,0F,3B,DC,ED,AB,0A,74,9D,F1,D3,75,45,33,C4,CD,0B,4D,BA,6F,EE,FC,06,26,3C,2F,41,8C,8D,DE,A0,29,B7,4A,B3,A7,06,9C,BA,F9,5A,FD,4B,CF,B3,5C,0D,E8,A4,AD,1A,09,EA,3F,C2,CE,61,A6,DD,3C,2A,EC,73,19,04,B2,51,83,5E,56,BA,B7,FB,D8,56,63,F1,96,AC,D5,10,C5,8B,48,3C,E2,5F,75,EB,50,92,C7,68,1A,1A,AC,7F,84,0F,05,4F,43,77,E4,31,4F,15,A5,14,63,C1,67,C8,B9,DE,61,28,00,11,B8,D3,39,87,11,F2,45,74,89,E9,09,CE,72,EA,F5,BC,D0,B4,FF,36,BE,63,89,CB,17,6D,82,BD,06,08,33,5B,FC,D0,17,4C,7D,1E,75,47,AB,F4,EB,09,E8,2A,D3,A5,CF,93,C3,8C,D1,CB,C1,94,F6,E4,D5,E7,D8,C9,CF,BF,11,F4,FF,D5,EE,F5,2B,38,28,39,71,C6,89,4D,11,3A,DF,DF,79,80,61,F5,20,85,F1,D0,20,6D,82,B5,BC,37,CA,34,CB,FA,7E,7A,29,DA,F9,57,33,E2,BE,ED,26,82,73,F3,C4,B4,84,89,06,AB,8D,0D,3A,36,B1,FD,07,1F,3F,35,15,92,4D,B7,51,4B,16,34,28,C4,71,DB,21,62,C8,45,AB,B0,D2,3C,32,CB,59,8B,0B,7B,F1,DA,EA,21,1F,0E,E7,FA,65,F3,30,E2,75,B8,19,AC,97,DB,21,B3,19,22,7F,6A,57,78,95,33,05,88,F1,23,A3,61,F2,DD,51,50,D9,35,CD,6F,8B,8C,AC,15,CE,8D,1B,7F,BB,F9,E8,A5,8C,58,FE,3C,CA,A5,DF,28,AF,4A,91,56,9C,38,26,D8,1B,90,40,4F,D9,3D,18,E1,76,A3,E5,5D,FF,96,A2,B5,DB,E2,E8,BF,C4,C9,CF,D8,4A,BF,0C,D1,30,4A,EE,59,50,9B,35,59,15,99,74,98,16,3A,0B,40,34,5E,5E,36,5D,26,5E,4F,6D,52,AE,1C,17,06,85,17,72,2A,7A,12,73,30,72,D3,A4,9A,66,15,DE,02,EE,E0,C6,B2,54,D2,BC,EC,DA,2C,F9,71,1A,D2,7C,7A,F2,1B,72,DF,9D,C1,C5,72,C3,D1,8B,7C,B9,4B,3F,E2,84,BA,BD,22,BB,F1,B9,C6,20,BE,54,23,5D,7F,62,FB,FB,CE,F1,26,8E,FA,17,6B,7B,4D,67,25,F8,FA,3F,7C,2C,2B,52,07,BD,B3,9C,D1,53,24,AE,91,F5,AA,77,BE,B7,26,EC,55,A1,98,C8,29,1C,0B,E2,3D,B0,D2,91,FF,1A,F3,12,B0,FD,46,14,19,D1,18,7B,58,3B,2C,0B,D2,26,FB,A2,B4,7A,72,30,7B,F5,2F,A3,9C,F0,F3,7A,0A,2C,44,22,C0,5D,F9,9E,A3,92,C0,33,D7,21,D3,02,69,3E,5A,3B,C6,89,48,67,FC,4C,83,60,BB,9E,92,34,D4,B9,BC,48,FC,08,88,EE,C5,F8,33,2A,54,CC,FA,D9,AD,3E,8E,3C,F7,73,5D,B6,37,30,B4,7D,89,15,B1,73,46,72,A7,06,DC,E0,27,B2,CE,16,F0,1F,56,DC,A7,46,9B,30,42,01,06,8D,FD,2A,04,B3,3E,FE,E9,3F,F6,30,F1,21,07,D6,1F,12,05,CB,2E,02,48,3B,63,F6,2B,FE,5F,D8,20,7A,EC,84,3E,4D,A5,44,B9,07,DD,9E,C3,43,03,F8,EA,3C,3E,33,4B,56,DD,76,2B,F5,00,7B,FD,9A,5A,C1,16,E9,BA,6A,C5,4A,BB,29,5D,D5,CC,AE,EE,2B,21,5C,0C,8B,D2,CE,33,D9,CE,97,DF,3E,3D,57,57,53,DB,8F,03,06,E5,36,A9,B5,C1,C3,C1,6A,FD,28,CD,6E,3F,84,11,84,41,F6,60,DF,36,CE,40,76,04,97,40,F1,9D,10,DD,46,9C,65,6A,61,1F,B2,3C,0F,81,15,91,05,3B,0E,E0,4D,E1,8B,AD,C0,1A,D0,3B,A8,4D,41,02,BA,5B,35,AD,50,48,F1,48,BB,2D,25,16,5F,42,46,80,93,4E,B7,BF,DD,3A,4B,91,C7,09,13,4A,79,F4,29,CB,4A,D3,61,AF,55,99,3E,D9,EA,76,D4,1B,9C,A5,7C,30,D8,73,EE,E7,AE,BF,34,B3,03,71,16,DC,BE,39,E1,18,9E,98,40,33,5F,7E,1F,71,45,92,8C,0D,52,3B,7B,05,44,0A,BA,93,DE,F5,81,CC,55,79,1C,B6,16,AD,4A,F9,D5,AC,68,2B,07,B2,05,D9,98,8D,FA,A0,DB,2F,27,A2,FD,0B,6E,61,6E,90,72,A1,A0,C5,81,4A,B5,40,6F,00,B9,FF,BA,04,2A,B5,84,4B,2D,2D,60,51,87,A5,64,BA,C1,72,DB,24,4F,A6,A0,A9,50,84,3E,26,CE,5E,F7,58,69,65,B7,47,34,74,4D,3D,36,03,91,39,DD,E7,F6,4E,4A,43,40,B8,4D,2E,77,0E,F9,6A,FD,FA,CF,C6,AC,E4,AF,AA,15,0E,36,8F,E4,AB,82,FE,51,D4,F5,28,5A,C1,53,F3,66,77,06,1C,A7,9E,11,4C,AC,A2,B3,6D,1F,F9,B5,8C,52,19,06,CC,6C,C3,79,37,B4,F1,3D,0F,1E,4F,C8,72,DC,B1,01,16,05,CF,40,EB,AE,0A,92,59,13,3F,4A,81,AC,9D,C0,CC,DE,4F,03,7C,BE,9A,14,F1,2E,22,EE,34,21,F0,D0,66,48,5D,58,78,62,2B,40,02,D7,FF,84,40,4D,FE,4E,3E,86,9F,0E,AC,34,EE,E4,77,B9,24,9E,41,79,CD,31,FB,96,D2,34,E4,E9,18,E3,70,B1,E4,31,7F,DD,AE,80,0A,FB,FE,65,CC,E4,49,A5,A1,5B,67,A7,A2,87,89,1B,D6,42,D6,3F,39,66,2A,DD,80,36,D1,05,4A,BB,CE,D5,3A,4B,40,E0,02,E5,A4,84,8C,F1,84,49,BF,4F,60,33,9E,47,D5,C4,4B,86,C5,35,50,8D,F8,75,C5,42,2A,D2,FF,46,56,3E,1F,16,3E,99,47,29,38,AE,6A,0A,40,35,D7,0F,87,25,2B,37,6C,85,BD,66,4A,AF,A0,1B,03,45,80,BF,62,EB,6D,D5,3B,CA,D8,F4,52,06,F6,27,05,0D,68,08,45,FA,E6,03,9C,29,3E,89,E9,7F,10,17,0D,D4,55,8A,71,DD,E1,B7,25,8D,2F,4D,AF,5A,FB,33,03,55,B5,CF,33,0A,F0,66,76,AB,82,98,8D,81,C2,69,A1,A2,42,66,E6,EC,75,EC,99,B2,20,04,B7,97,8D,C9,25,E3,9D,B8,B2,8C,CD,C1,FB,C5,99,15,1B,9D,42,77,38,EB,0A,56,26,0A,7B,43,EF,5C,E5,1A,28,34,CE,73,A0,14,0A,DC,55,6C,CB,55,0A,D6,D5,93,C2,A5,20,BA,9A,F3,4A,B0,04,42,C2,CF,C2,3A,BD,17,B0,2C,D7,F7,9E,98,FD,1B,A7,25,43,37,96,CF,34,19,6C,AD,91,43,0E,69,A2,52,26,FA,B6,DA,A6,20,33,48,8C,AE,F4,A5,96,A5,1C,EB,CE,9D,61,29,58,AB,4B,73,7D,D1,A5,17,CB,6B,62,8E,BF,96,F9,2F,4C,74,BF,1D,73,A2,C1,D1,BB,00,AC,0A,81,45,16,9C,8D,AB,FC,88,27,E5,E6,3A,0F,8A,37,8B,EB,6C,65,A4,2C,BA,8F,35,5F,5A,EA,D0,1A,E9,60,AB,F6,1A,18,88,AD,9F,A0,82,C5,7C,65,DA,B3,C4,DB,0F,6C,B1,CD,41,22,6B,30,BB,40,10,03,43,47,84,4C,A6,5E,5C,6C,5B,E5,AE,6F,35,6B,EF,D4,80,E2,4D,C8,33,EB,76,42,DF,49,06,94,60,A2,13,5D,D3,F6,B2,E5,2F,F4,A5,93,7C,CE,46,2B,B6,E3,2C,53,7D,CD,2F,2F,A7,73,2C,18,91,4F,19,2B,3B,D0,16,D3,7B,64,92,4F,77,AA,E0,D1,2A,1E,16,26,1B,A1,EF,CA,92,80,6F,8B,A8,EA,ED,00,B0,84,0E,08,44,9A,CE,AB,0C,50,25,DF,28,D8,B3,2F,4A,5D,C1,1C,C5,00,BE,5A,A1,1C,FB,DF,BD,84,A7,71,60,23,0D,30,8A,09,7E,D6,C1,64,99,F2,A9,D1,DD,15,DB,85,3A,36,C1,99,CB,24,EB,47,98,01,FA,E4,9B,BE,06,69,D4,18,A7,5E,8C,09,DD,5E,07,B4,4C,43,4E,39,98,6F,A7,93,82,5D,CA,6C,0F,DC,F7,D4,5C,A9,A0,61,32,03,F8,25,2E,DF,A1,D1,9A,EB,50,49,22,BB,6A,84,5E,12,88,3A,B3,8D,E2,18,DD,66,C9,48,50,39,B4,80,A2,65,41,25,98,0C,F6,1F,86,09,5C,4B,35,3A,6F,AB,09,FE,49,95,3E,DE,D3,7E,6F,F8,84,B2,68,97,8A,DE,EB,B0,05,8E,C6,BA,E8,E8,05,28,DE,4A,24,5F,F6,1C,38,E0,29,1B,6E,C4,60,E4,90,D7,A4,F6,A7,96,BE,6C,B9,3D,52,E5,AF,78,B2,F1,A0,FE,65,D7,55,B3,5D,29,7E,EC,90,41,EF,D7,AB,52,4A,6B,C3,0C,EA,76,9E,B4,5E,EF,2B,96,0C,40,EA,EF,66,0B,36,6B,15,ED,71,7F,81,44,CC,79,15,E6,D3,6B,C6,D3,6B,EF,CB,AE,E7,35,40,7E,57,F8,A5,CE,02,56,9A,A9,22,94,B2,11,6D,01,6F,46,E6,98,79,B5,8F,9C,F4,8F,D2,9D,ED,98,35,C5,E4,F2,06,38,04,0A,21,BB,82,14,FA,24,3A,EE,83,18,A9,52,30,18,04,6B,4C,68,95,BC,E1,48,09,F5,38,3B,F2,03,E7,D6,2B,85,57,7D,1F,9B,2C,4B,4A,CA,4D,DA,62,7D,5C,B8,FC,B4,4F,99,0F,41,22,12,63,57,E0,E1,D8,C6,13,5E,64,17,EF,2F,8A,75,56,D4,8D,49,B9,8F,A0,EE,21,04,D8,C4,F0,E9,AB,3A,5C,D5,81,18,70,BF,CE,E7,D2,6B,9D,D8,CF,10,FD,C0,02,68,BC,3E,57,A1,D5,5A,21,6A,4B,D4,9D,F2,60,63,7C,F2,8E,C7,9A,0C,FB,8E,3D,15,F0,D3,5E,47,E0,6B,A1,19,24,17,73,28,98,08,56,57,CC,D5,C9,89,8B,93,4A,3E,09,C6,62,16,D5,65,5D,48,D2,86,3A,32,32,5D,83,06,65,22,C1,25,2B,44,50,BD,FF,DA,E2,A6,8D,F9,48,5F,3B,01,A1,CA,72,3A,EC,8D,10,DA,5D,8B,52,DD,9D,AE,39,96,E3,06,52,3B,E1,8D,6A,0D,4A,2F,69,ED,C6,33,BD,D6,5A,B0,AE,27,F3,AE,AB,21,A8,78,ED,6D,17,8A,5A,F4,97,C8,76,D8,84,B5,23,09,42,2B,56,F0,76,17,C7,2A,3C,0C,48,65,11,C7,F0,5C,80,D9,7E,3D,73,80,CE,92,0E,AB,4A,57,F2,CE,89,D5,3E,55,14,2E,4F,95,8E,4F,85,70,2B,D9,00,BA,60,0E,C1,C5,5F,71,F5,28,EC,3B,3D,F6,A6,A7,CB,5B,F4,2E,2D,B2,B8,30,59,89,EB,AC,C9,CA,06,13,2D,E9,D2,4E,9E,3E,9C,97,2C,F1,83,CD,E3,B2,00,5F,D2,2C,FE,80,0F,51,18,AD,41,28,21,FD,9D,87,DE,F7,47,C4,78,D9,C7,06,4B,A1,3D,E5,27,20,AC,41,44,4C,F8,32,A1,70,6B,A8,6E,DB,8C,93,5D,54,D3,50,B8,49,05,5E,DC,77,A5,65,07,D0,49,35,00,C6,18,7F,B1,34,FC,54,0D,66,66,C4,96,CF,A2,72,E7,55,8A,E2,26,0C,E7,49,91,6F,32,0F,E2,A2,A2,88,E6,0A,AE,1F,91,E7,06,12,10,06,23,B4,84,F8,B9,61,29,25,BA,FF,83,06,3D,44,FF,94,38,19,AC,D4,34,12,86,4B,6B,2A,99,BC,4E,EA,DC,F7,64,27,B4,AE,01,F1,D7,96,73,D2,93,17,40,3E,5C,32,73,5B,71,6B,48,96,65,BE,4C,27,DC,D2,46,DA,D6,9A,89,1B,09,62,92,19,08,D5,12,39,7B,7A,09,E5,21,43,41,5C,5F,64,1B,82,D8,1C,03,B4,1D,99,42,AF,D0,6C,DE,BB,CA,CE,0E,94,E4,04,28,A7,92,87,D8,CB,43,8C,3D,07,60,D1,F8,10,2D,C5,D0,39,9C,7A,17,EE,38,7D,93,AB,3B,1D,A2,6F,C9,57,D3,3C,32,C2,9E,35,A2,99,F8,15,DF,AF,7E,6E,0B,85,32,C8,62,40,D9,F1,E9,9E,94,8F,1A,DC,6F,9B,28,09,D5,91,21,90,02,78,C9,7A,B8,F7,18,EF,0B,78,7D,DE,5E,0F,BA,2F,27,B1,55,4D,1A,45,F4,C3,16,C4,11,5C,D0,B1,8E,A1,F9,1E,FE,CC,C3,8C,3D,A9,92,5E,8A,EE,C5,18,17,27,F8,B5,96,9D,23,4E,E6,B1,26,1E,F7,A4,6D,C0,9E,A5,5C,25,01,8B,7B,44,2E,4A,E2,34,40,E1,1B,31,6A,3C,62,DB,CF,24,2D,52,36,D7,6F,02,A5,5B,DF,66,5E,51,A4,45,D0,D2,C1,97,79,18,93,68,E6,6D,4E,05,C6,4B,3F,BF,C9,43,4F,C0,0F,68,08,20,6A,75,64,41,4E,A3,3E,63,01,B1,7E,45,AC,7D,F1,76,E5,5C,F3,F4,55,2F,7B,23,95,A1,15,1D,51,B0,D5,44,81,B8,B8,7F,AD,61,1F,40,97,EA,D6,EC,67,AC,E0,EE,F3,B5,55,02,C1,64,06,55,94,FA,A4,DA,DA,0F,5D,3E,C0,7F,A1,0D,E1,01,04,F4,F4,03,4C,A1,BC,E5,33,41,D7,2B,41,E7,A4,39,FD,2A,13,CB,72,4C,47,B0,B9,A9,5B,94,BF,FC,F5,9E,D3,1C,45,67,46,DF,F2,DF,DC,61,B4,51,9E,5A,98,70,69,F6,85,D6,97,FA,E8,97,AF,BB,99,0D,EF,8A,E3,99,6F,82,EC,7F,2D,E6,BA,BC,C1,29,A6,50,A6,2D,23,04,2A,E0,C3,A4,36,7B,F0,48,48,52,87,6D,BD,8C,E4,47,ED,24,FF,D6,3F,41,CE,0B,4C,4B,1D,81,3D,95,E4,2C,7D,F8,43,72,44,58,25,4D,66,D2,F6,51,16,2D,52,87,2C,4F,9F,3D,2F,3F,E6,30,5D,53,10,E6,9E,4A,77,A2,0B,5F,8B,5D,03,42,C3,10,41,DF,44,5F,BE,08,4B,92,CD,1E,1F,19,85,6B,30,48,0C,6F,3C,1B,1E,D7,C6,52,3D,C3,B6,C8,3C,5C,56,A3,ED,7B,70,E5,5F,C9,96,7B,89,F4,FB,5D,81,CA,DC,57,BA,DF,B4,0F,33,15,BE,D5,A2,DC,CA,31,02,F6,A8,B4,34,6D,27,0B,6A,D3,C4,99,9E,E1,1D,86,ED,C0,D0,04,BB,36,E3,D1,99,D3,A0,E6,C9,60,55,D8,09,BF,7A,36,C2,E4,47,D4,CB,C8,40,EA,2A,57,92,F6,32,24,E7,A6,DA,E8,5F,C2,B7,A2,39,B9,98,91,DA,AB,6A,9A,96,5E,A9,E3,48,6B,7A,F1,5A,AD,E2,2C,F2,FA,7D,AF,86,19,11,43,7A,CA,46,48,D2,11,0E,2B,AC,DD,72,69,88,F2,E7,01,83,07,8C,44,B2,32,0D,6E,20,72,6D,61,DA,EC,E9,C7,6F,0D,11,36,10,F3,9E,8D,A0,03,F1,91,CA,34,7E,28,50,DB,69,F9,FC,86,82,DC,61,70,8B,30,81,66,73,26,0A,8D,94,E5,81,D7,12,27,0C,FC,F3,75,73,AA,27,F8,76,CF,16,06,14,87,A7,CA,6B,18,B7,36,F4,80,E3,B6,9B,17,F8,D8,7D,D6,0A,83,64,0F,9D,29,44,17,7C,1A,E7,7E,F0,01,9D,CE,1B,88,40,F5,76,29,CA,0E,BE,38,26,7B,6E,23,78,2E,D5,FC,9C,23,CA,E6,51,E4,21,C9,2A,9B,46,68,C3,40,1D,77,C3,12,9D,7B,8B,E7,A0,75,65,2B,04,9E,E5,6C,4F,E8,6E,56,5F,17,31,A5,0A,32,C5,F7,3C,CF,69,0C,63,24,D6,6D,D1,8B,6E,5B,5F,7F,B4,1D,81,50,5F,0C,8B,0A,BF,87,36,BB,C9,11,1D,F0,30,B5,97,08,DE,2D,B7,5C,B7,75,98,29,87,0E,4E,B6,8D,47,13,20,C4,D9,BD,49,52,21,93,3A,F3,18,5C,A3,A7,71,8E,8F,25,3D,3C,40,3C,AC,40,21,CA,32,A5,C8,F7,D9,E0,B8,5E,3E,E7,7F,6A,CF,9B,A0,1B,2D,DB,94,5F,F7,55,7F,6D,C9,D9,7B,D0,81,AE,92,36,BE,5A,EF,68,30,D6,8F,34,36,9B,94,4F,EC,14,4E,96,C9,59,36,26,BA,1B,5E,15,A8,05,5A,5E,ED,32,E8,05,55,62,18,A2,DF,42,7E,C0,0B,31,EF,69,95,A4,A0,BF,4D,89,97,A1,04,38,A2,57,3D,53,63,AE,B3,3E,6A,63,87,9B,00,50,65,04,FB,B4,C2,70,22,C6,98,A3,DC,1B,25,3F,3D,6D,80,43,0F,5F,2E,8D,9F,D1,53,44,15,22,01,52,6D,53,82,08,71,9B,CD,70,C0,B5,EE,13,82,B7,DE,AF,56,8A,6C,F9,5F,D6,A2,9D,96,C0,8E,25,6A,9A,B4,A8,5E,CB,B1,3B,AF,10,C0,9C,98,2C,1A,1E,8A,A2,BC,A9,97,E2,F7,1B,16,D8,9C,91,08,43,1D,B3,CA,30,59,AF,7B,1A,54,FE,54,9D,26,64,E9,DC,28,8C,B9,DD,CE,F9,DF,B7,11,24,6B,F5,81,2B,4F,48,7F,0A,7B,DC,D9,40,80,3D,41,AD,43,5A,EE,55,32,72,8F,97,8D,48,3E,2B,5E,53,E6,C8,7E,95,22,E1,7B,8B,A6,31,1A,D3,92,E9,21,2D,C5,68,48,A9,8A,C6,C9,E6,8A,9D,F6,91,98,38,4F,39,7C,FC,1A,13,A8,E0,29,BE,89,F7,30,95,96,4E,52,69,61,69,8F,65,7C,33,20,D3,54,91,A3,C7,2A,AC,1B,6B,67,63,F4,57,D2,71,97,D5,57,5C,68,6A,90,C4,2A,F5,21,79,99,A0,BC,E1,7A,98,3E,BB,18,DC,53,2F,84,94,C2,F4,0C,0E,A9,F2,05,A5,C6,20,ED,B5,A6,A3,9E,6C,74,38,8E,C7,93,DE,68,BA,1C,C3,91,05,29,D0,49,09,38,43,02,90,58,24,82,73,C4,98,05,B5,82,E9,A8,87,99,DD,7B,A8,CF,CD,40,5A,E3,C2,51,14,18,ED,AE,E2,17,01,D7,E9,B0,4A,26,0A,D3,9A,8A,42,DB,1E,D3,82,8F,C1,2F,F3,06,DD,67,CC,D6,51,5F,41,50,C0,E1,61,0B,1E,12,A4,8B,F2,F4,A1,08,B1,80,03,B8,1D,88,66,80,BB,14,FB,EA,33,4F,AA,54,23,8C,60,83,DE,97,50,D1,64,CD,1E,76,56,CC,60,A9,F6,6F,B3,47,14,85,DB,9F,57,9C,B0,BC,AF,49,1F,31,ED,37,8E,78,E5,D6,00,7C,41,57,0D,E5,21,2F,BD,F3,70,77,96,9F,2D,D3,96,9C,96,22,A1,2B,52,83,0C,A0,6B,B6,84,A1,FF,CC,53,C5,D4,CD,F5,20,35,71,9F,51,9C,BB,BA,25,E2,93,2A,57,79,1B,46,50,D1,51,C7,69,12,AC,50,F2,46,56,6B,57,21,2C,17,1C,73,E7,72,91,14,EE,51,16,E4,83,2A,5C,23,B3,0C,4D,E1,CE,D1,AB,DB,4F,A1,6B,22,4B,01,74,77,FB,61,D6,BF,82,EA,4A,35,1B,0F,BE,EE,20,B1,48,0F,74,DC,1F,07,B5,6C,43,46,AF,1C,63,88,50,86,B4,C7,13,1B,D0,E9,FA,7F,B8,7D,35,9C,4B,A4,76,83,AB,36,B9,63,63,21,45,E5,2E,F2,56,5A,26,C4,B6,12,1E,F9,EB,C0,54,B9,99,4D,4C,A5,1D,B3,8B,A8,02,61,9B,5A,53,3A,0B,78,F1,A5,CD,5F,EE,8C,E5,26,6B,09,2D,06,3E,60,2A,00,63,54,F4,82,77,73,C6,9E,B3,B5,4C,6A,8D,A5,F1,64,01,48,AC,3C,13,1E,88,FF,96,BB,2B,3A,14,92,5E,0C,CF,4B,B5,73,85,CF,E0,64,CA,F4,A2,88,99,21,2B,A0,B6,38,70,16,0A,4A,AE,44,6F,1E,AE,85,99,05,18,70,72,65,8C,9D,B0,D5,92,F3,5F,3F,BE,E9,B5,8E,70,39,2E,4A,E4,67,82,3C,50,E4,B7,D3,21,F2,2D,24,3F,9B,F4,BC,21,F0,04,AE,17,12,E6,B3,4D,53,93,AE,04,63,B6,57,1A,3F,44,98,B5,FC,84,D7,FF,75,E5,D1,0F,E5,1E,A3,BF,5F,15,C1,46,C1,DC,9D,53,4A,98,DF,CA,1A,60,87,15,FB,48,A5,62,84,F2,65,AA,62,B4,3B,2E,C9,62,CF,AF,6C,C4,BE,CD,99,07,68,57,44,D0,89,A6,EA,4A,B1,A3,50,35,C7,F8,85,84,1A,3C,DA,D1,FF,90,32,3B,CC,92,55,CD,A3,12,C3,F5,AC,D7,E1,95,E1,32,FB,75,C2,7F,2F,CD,A4,06,90,69,FD,5A,83,B9,BB,FE,81,BE,71,0E,38,DF,48,3F,91,83,31,37,9B,14,40,44,17,BF,AE,71,82,C8,27,23,D8,A6,97,FC,71,40,86,25,8D,16,68,A8,CB,C2,AA,77,CD,F8,AD,98,B7,36,47,CB,E6,76,FD,A5,CE,92,85,C9,9E,0A,5B,2D,3E,C3,30,C5,6D,7E,74,52,8A,52,65,50,1B,8C,D2,27,5D,D7,28,BE,A0,FF,63,8A,5F,DF,2D,D8,1B,99,7A,C5,34,73,32,3D,42,E3,B4,32,76,90,99,D2,38,F8,B0,33,FF,27,63,D5,EC,17,E3,0C,1F,AC,F4,CD,CD,EB,64,7F,DB,FF,7A,FE,72,C9,C9,C0,C1,1C,65,AC,41,8E,05,4B,C9,E7,C2,43,4E,03,5B,3A,59,75,9E,7F,15,45,FF,80,6B,AD,BD,12,08,A8,C7,00,96,69,53,64,3A,8F,80,59,FD,68,99,1E,51,99,72,F4,AA,3D,48,0B,A6,62,2C,3D,CA,2F,CA,3B,EA,59,6D,D5,40,CF,8D,92,43,B7,FA,B9,B3,C3,CF,52,97,F8,4B,BF,89,86,30,F2,29,9D,07,B0,FE,09,A6,BE,2A,9C,5F,EE,0B,AE,FE,63,29,85,42,DB,59,FA,D8,C7,0E,4B,8A,1E,3E,53,B7,21,B3,0B,CE,A6,A0,19,6F,A2,ED,0B,53,DC,A5,1D,45,8B,AD,F3,C9,6A,6B,33,C3,09,D9,8A,16,F8,24,7F,6E,5C,D8,28,32,34,B1,E6,EB,8D,8C,7E,DA,65,10,F3,87,05,CF,F8,86,54,01,2E,15,23,A2,EA,EB,60,BB,4D,29,B6,15,6F,CB,8D,57,80,C5,AD,71,6B,8A,55,2F,C7,87,AD,41,32,95,4C,5D,52,E1,9E,13,C6,DB,38,4B,18,FB,BE,6D,51,C9,91,99,0B,74,49,76,C8,6C,13,14,EB,C6,5F,88,A2,CA,09,43,B4,03,ED,0E,8B,96,C3,F8,2E,9E,E5,74,64,3B,EA,EE,7D,9E,97,F9,D6,83,21,0C,00,ED,2A,55,97,C1,83,87,24,6C,02,D8,03,90,D0,B5,2A,85,5C,F4,2E,3C,14,D4,DD,03,32,B7,E7,C1,50,F7,C1,43,06,D4,2D,B7,58,0A,2F,54,16,47,02,E6,E0,BE,C2,D7,70,B4,C1,7D,78,50,E1,EF,7A,9E,04,2B,8B,58,DC,25,E8,96,8E,A4,68,54,36,20,32,60,17,DD,5B,EA,AC,22,B3,4D,7E,BE,4A,3D,95,6C,44,2A,A4,D5,C6,62,0D,03,AA,2A,14,6D,BA,59,27,2A,CC,6F,56,13,1B,BF,AF,29,BB,D9,B0,B8,A3,C6,33,0F,62,BA,5E,94,D2,4E,7D,5E,DE,3F,CF,0F,24,CD,65,E8,F4,40,EE,27,C2,24,6D,76,24,89,21,F1,5F,1A,7E,6D,F9,A9,EB,7C,57,05,E7,E3,33,F9,D6,48,AA,BB,EA,CD,13,18,FE,7E,EB,41,31,3C,FB,F0,00,D9,56,F4,04,55,21,6D,9E,44,48,74,BC,A2,20,A6,C8,0E,4A,A8,21,E3,44,33,57,F1,CD,4E,E2,BC,B5,9B,B7,93,3C,FA,73,9F,05,3C,57,26,BC,C5,BA,DD,76,EA,68,B5,7B,1A,38,C7,10,C1,98,8F,AC,98,DB,53,BC,AE,5A,5D,08,80,EE,51,49,A9,8A,95,EC,BE,40,F6,DF,75,78,06,AE,4C,87,FB,4A,D3,81,59,C5,0A,D4,49,92,C4,DF,C3,75,A2,62,E6,7A,E4,95,AE,B1,FD,5D,BB,78,76,76,E8,5B,92,C0,8D,0F,EC,70,9F,9A,FD,B7,45,D6,BD,7A,C0,C4,23,7E,35,E6,9F,54,87,96,2A,51,68,0D,72,11,0A,9E,9D,AA,58,40,D4,9A,FF,D3,D9,09,08,CC,1D,60,E1,11,8C,BA,2F,6B,48,F9,FC,77,6E,52,7B,55,01,35,73,64,5C,C3,BD,35,84,E2,F1,24,6F,96,F1,59,10,B5,E6,44,78,97,1B,BE,B7,37,52,EC,4A,44,11,4B,98,22,76,A5,D8,00,1D,FD,5B,3D,8E,BC,89,12,1B,E1,58,57,E4,64,26,2B,D4,C5,15,41,01,7B,85,C3,C5,0D,5F,1B,BB,79,3C,20,9F,96,D6,B8,9D,CB,6E,79,63,13,87,65,73,5B,42,11,7C,56,F2,71,78,5F,5D,2B,5A,15,9E,AF,9A,7A,2C,D3,8F,0B,BD,40,7A,14,DE,E2,38,93,F6,F0,AE,C2,F2,E0,91,AE,F9,1D,F9,13,1A,1B,E5,26,9A,0E,36,C2,27,CB,CC,64,F6,8F,B3,2C,38,18,E3,85,28,FC,6D,D8,A2,0F,F5,69,37,D8,7B,59,B1,AC,13,1F,8F,41,CA,EC,21,66,F3,29,7B,A0,91,E2,27,E9,F0,6A,D6,D6,4B,A1,FA,28,BA,1E,51,B1,E5,03,0F,0D,0D,2B,EE,23,A0,AB,C5,57,D9,B0,28,A9,DA,F7,70,59,FA,8D,9E,8B,5A,16,70,38,F1,CF,2B,98,89,3D,00,75,08,27,A5,B2,8B,C0,AA,10,97,A8,85,5B,91,84,70,99,85,7F,46,8A,BE,2A,91,4E,33,5E,A0,32,3C,B5,02,D0,B6,20,B9,D3,14,0C,78,46,55,B9,29,FD,8A,2A,FB,C5,2A,2D,43,27,BD,43,9C,34,39,97,76,C6,01,6B,3C,05,AE,4D,19,A9,B5,1A,C3,EE,6B,BE,CC,70,79,B9,B9,3D,A5,05,BB,CC,C2,8C,36,BA,3A,23,CA,15,AB,E2,76,62,71,21,A0,53,C2,23,02,B4,BF,02,6B,29,64,83,D2,F4,16,F3,07,6D,E3,A4,66,EB,C8,31,95,FB,00,79,FB,1A,94,81,E8,01,34,C4,AB,FE,4E,96,75,7A,EC,E7,FF,FB,0C,5A,3B,2C,33,F9,16,EC,D1,9E,A3,44,B0,73,4C,F8,99,80,FB,7C,91,C9,EE,25,73,AD,C4,1B,65,23,37,35,16,A7,BE,25,DD,F1,F3,3A,96,95,49,CF,5B,9B,09,9C,13,83,F2,37,DA,9D,25,8B,DB,44,88,A8,61,B5,09,1E,78,AE,28,2F,DF,25,86,A1,55,4A,42,28,91,62,B8,39,50,F0,8B,9E,94,A5,D1,6B,18,AF,A0,44,3B,38,FE,A8,AA,5C,AF,FD,2D,5B,C7,A8,6B,03,F2,4C,97,40,47,07,EB,BC,9B,07,72,42,E2,53,30,EB,1D,CD,42,7A,99,B8,42,FE,A3,FA,E2,1F,62,70,11,C1,C8,69,64,59,B7,B9,8D,2F,8E,ED,17,AB,F9,FD,6E,44,18,3F,91,3C,2B,1F,EC,31,17,6C,5B,96,56,86,47,09,BE,F2,16,0F,39,C5,77,10,BA,E8,2A,E7,B1,4F,E9,0A,96,E2,B5,42,BC,AB,5B,25,00,A0,5D,AE,AB,28,46,F7,A1,AE,57,78,65,8F,5E,A6,2E,32,BF,65,99,9E,83,E8,71,51,D1,16,41,B9,CB,9B,F3,87,DC,66,50,1A,21,66,AF,F2,7C,D4,0B,9B,0E,29,97,8F,02,B3,8D,4E,4A,25,4C,62,5B,00,EC,36,EE,3D,2A,43,41,17,61,EF,A3,35,A8,62,DF,1F,FB,92,F5,65,1F,C2,8F,A3,B7,E2,B8,FC,C4,58,A7,40,6C,4F,2F,83,C4,BA,7A,11,BD,A8,69,DA,8F,9F,34,16,98,79,14,AA,FC,BD,C1,A2,DD,28,EA,D4,C8,58,75,6E,61,98,99,BB,ED,0C,15,B3,95,9D,FB,53,1A,32,56,92,4E,E5,B0,12,E8,49,7A,63,45,DC,6B,12,83,E4,9A,9F,1E,7A,DC,C1,2C,96,78,6F,76,D9,72,E2,FE,D7,C4,0D,BC,EA,60,CF,F0,06,9A,90,CD,7C,8A,EF,D0,BB,9A,D3,75,58,FB,04,71,6F,5A,B6,09,A2,20,2E,4F,56,4C,80,44,59,E0,C3,C0,E4,F4,4E,70,00,34,44,C2,E9,B4,13,C3,5F,C0,84,07,5D,6A,95,7B,DD,C0,A0,88,2F,BD,51,7E,A1,F6,F7,07,F5,A9,E8,57,65,7F,D5,B2,9B,99,19,5C,77,C0,EB,7C,94,DF,75,F2,E4,80,8A,7B,BB,23,95,9B,14,34,5E,A3,23,A4,64,4E,27,2F,2C,70,B7,23,00,65,06,BE,AA,AD,A9,48,EF,03,CE,16,36,65,17,AC,47,B5,3C,97,05,01,B5,3D,68,A3,73,C6,09,AE,81,40,2E,F7,C2,E5,74,28,61,89,4F,15,A5,43,6A,E9,1A,05,2D,AA,8E,59,00,6A,B8,9C,84,78,40,00,61,DB,60,CF,0A,E6,B4,BA,90,C5,B2,EE,74,7A,D6,A7,6D,CF,3F,33,F5,76,39,C6,D2,A1,D5,EB,0C,37,F1,43,E0,C5,54,7C,19,98,63,DE,22,69,9D,CA,09,6F,8E,80,5C,B7,16,9A,3C,5C,CA,E2,DF,4E,95,1A,42,72,70,C4,DD,44,9C,A6,9F,F6,C7,40,1D,E8,B8,5D,82,FE,E7,DE,53,0A,30,33,84,3D,2C,A1,C4,E2,66,B3,54,50,2C,E3,CE,46,C6,F5,AA,71,FB,48,6B,51,3B,36,48,A2,C4,8E,A5,7C,E0,D2,A1,C3,3A,B9,E5,C2,A1,81,D9,08,DA,1A,7E,02,59,EA,9C,09,E9,5C,01,51,09,6E,43,56,01,79,E0,3C,BC,2A,58,B9,2D,43,CD,30,E1,C7,6D,BA,86,BF,DF,E4,6E,06,59,2A,8B,AA,8F,30,02,B9,C7,9F,21,7D,91,47,0D,88,E1,96,29,24,BF,C9,8C,17,D7,95,07,5F,B1,07,59,3B,04,70,24,04,56,A0,63,3E,D3,68,64,9E,94,C1,3D,2A,55,79,93,69,8D,81,43,17,4A,3A,25,52,35,B5,F0,63,A4,10,06,F1,B2,FB,26,B3,5A,8A,4B,92,74,7F,F8,B7,41,09,07,56,59,03,DC,24,30,EA,AD,18,2E,9F,FA,6D,37,52,8B,5E,47,30,15,97,EA,42,0B,99,77,E5,15,98,D6,A6,16,72,C2,8F,0E,6B,07,66,4D,99,B7,DB,01,BF,A4,31,C0,02,FE,4C,EA,1D,AA,2F,45,8F,3C,1C,9B,42,0C,09,D6,4A,72,EC,C0,17,DE,3E,C6,28,B6,79,A6,F7,2B,75,52,E3,51,0F,19,39,D3,6F,1F,58,E1,FD,CD,CF,C1,A2,32,95,10,59,A6,C1,D2,D4,D9,E3,AC,85,24,77,F8,32,84,6D,E7,B3,74,9E,0D,26,15,FC,A6,07,5D,C9,31,C3,1B,75,3C,5B,1D,C6,3C,80,D7,29,40,A9,16,9F,42,CB,3E,2B,F9,8D,39,C9,EC,40,AC,70,0A,5D,C9,C4,88,5B,11,93,07,E2,9E,A4,13,4B,48,C3,D1,32,05,2C,6A,60,A4,7C,27,39,5F,A6,7A,8E,9B,26,E0,47,67,82,60,63,AD,F2,E1,4F,5D,13,2B,5B,93,D1,E2,27,9D,B0,5B,7B,7A,83,5B,06,21,70,3C,E7,D1,3C,8C,02,CF,A5,F8,E0,6E,1E,B2,C9,AA,0F,F3,71,C5,42,E0,61,E4,25,7A,4A,AB,82,95,00,10,94,B4,B8,C5,CA,06,11,4E,18,CA,76,31,56,78,76,97,E9,C0,DD,E7,23,74,18,7F,9B,F5,D6,93,93,A4,14,BF,5C,38,BF,EE,3A,FA,71,B2,98,26,39,C9,32,2A,D8,8C,58,20,CA,4E,71,00,D2,BF,83,89,89,D7,45,91,0A,B3,FB,D4,A5,B2,DD,5E,6D,95,FB,3C,80,4B,1E,15,98,7E,39,FE,38,1E,5F,78,33,FE,18,7D,24,C6,B5,AD,29,B0,95,7F,C3,35,70,89,5C,2D,95,6F,B3,6A,C0,62,11,F2,D6,70,96,7A,CB,01,46,BE,D8,64,3E,43,8B,CF,02,46,0A,32,AA,70,65,9A,53,91,32,F6,B0,3E,DD,C4,FE,8C,0C,32,C6,49,DB,93,DA,5A,B9,BD,8C,CA,69,17,57,F0,1F,DF,EF,73,EA,C2,63,B7,C2,8F,55,9D,76,8F,23,AF,DB,B7,63,DD,B0,E0,3E,2C,FD,1C,54,54,6D,33,31,55,5A,E3,53,9D,FF,41,86,9E,90,9C,17,BF,D0,84,25,A7,10,3A,9D,3C,29,73,78,E1,7E,67,B4,F9,8B,CA,32,E2,5F,23,86,49,B9,77,14,91,C9,A3,9F,D9,15,E9,31,35,A1,66,18,69,50,FE,1F,53,B3,0A,91,C1,32,70,55,E3,9B,83,D1,5A,A7,09,78,39,A3,2D,67,23,D8,6C,EA,94,22,FD,CF,22,25,BA,D8,68,06,22,87,6E,F9,BF,D5,5B,DA,BA,2A,8B,75,2E,A5,6A,BE,48,84,9E,C6,2D,7B,A5,EF,E4,8B,2E,FC,EF,3A,20,8D,FD,14,C7,60,1A,4B,D9,00,58,A7,68,57,D7,18,D0,3E,15,87,39,40,9C,2A,C0,5C,91,4B,C5,34,18,A4,0D,D7,38,34,FD,45,3E,82,2D,26,1E,23,5F,B7,17,9D,E3,1E,52,C2,6F,66,0E,88,18,2F,1B,A1,FA,C2,2E,CF,BB,72,F7,44,ED,74,9B,EB,1F,09,BB,89,74,88,4E,27,9A,82,3A,7A,33,EA,D2,AA,68,D1,DD,28,D4,BD,2C,12,11,8C,18,67,AD,43,9B,78,E7,B9,D3,21,21,6C,D5,DB,2A,B2,48,84,E6,05,32,FF,64,4B,51,5C,95,85,FC,B5,7E,CE,59,38,62,47,36,6A,11,6F,2E,63,C0,44,97,CE,8A,5B,81,AA,DF,A7,B4,32,CF,60,01,44,6D,9E,A0,B9,54,E7,1B,E2,8F,C0,53,C5,5F,D2,B2,23,76,8B,81,79,62,14,D4,72,3F,D1,38,0A,AF,02,EC,90,98,49,B7,4B,C3,8C,6A,3A,98,CE,AC,D7,97,BE,FB,E3,70,97,15,3D,56,EC,05,EA,49,5B,B7,84,9C,03,66,3E,1B,08,14,B2,EA,7B,5B,88,00,0B,CB,3B,3A,5B,AB,4F,FC,75,53,6D,EC,D2,88,AF,65,D2,36,C4,3F,1B,39,A6,05,F1,EB,1D,B8,1D,D4,2C,A7,0F,1F,3E,B4,5E,C8,35,8F,7A,42,4D,61,38,F6,82,15,52,71,B3,8F,C9,CA,15,6F,A9,EE,DE,1B,A7,08,8A,A4,B8,C1,D3,BF,14,DC,2D,BB,B3,3E,D5,F4,5B,12,75,45,62,67,64,80,9C,1D,85,A5,0E,3A,4A,C1,0E,65,53,6C,84,BA,30,30,55,B1,1B,7E,27,91,0B,D1,91,8A,BC,58,64,5F,94,F5,40,AB,58,5D,D8,58,D3,72,C4,17,7E,4C,2A,2A,AA,96,5B,64,66,1F,1D,3F,10,02,B6,38,89,F0,25,1A,5C,1B,86,A7,CD,0B,61,B8,FB,CD,8A,F7,90,39,8D,75,57,52,EA,37,0A,A2,3D,D1,A2,9A,69,9B,6E,CD,96,BC,F1,7D,96,7C,CC,4F,E4,49,2F,60,79,B6,6A,B6,4D,32,67,FA,EF,E4,6A,25,37,B6,9B,D9,30,B5,3A,8B,4A,20,C3,EA,86,B0,98,C9,D4,06,4B,40,D5,F6,D0,51,1A,F6,6B,D3,00,7C,41,D6,E5,CD,91,28,20,09,ED,FE,CA,68,C6,03,A1,F9,8C,57,85,E0,06,3D,E3,4C,F0,3B,7A,03,9E,26,F0,11,AB,D7,15,1F,5C,AE,10,75,BB,9B,C8,22,29,0D,E4,10,51,41,B2,52,BD,F6,8C,6D,2F,3E,EF,26,84,9B,5F,BC,F1,67,6C,A7,F3,02,A2,BB,81,74,A6,E5,66,ED,7E,11,68,81,C1,92,09,9F,61,8B,5A,AA,20,2C,A6,30,F0,E5,C6,E2,7D,51,B5,96,1F,C1,FE,70,C8,FC,36,8B,4B,79,F2,73,A9,9B,49,F5,5F,00,45,D9,22,B3,18,49,44,56,65,CD,44,A4,3D,19,6A,A6,AE,BA,DF,D2,6E,BC,91,2B,DA,9B,74,7B,84,EE,BA,A5,02,6F,1A,95,CF,A7,5F,89,C9,79,C4,B8,F1,0B,19,C9,D9,64,AE,18,69,91,BF,EF,51,47,50,F9,2E,BA,D6,DD,4F,27,63,8A,26,D0,34,B3,CD,CF,C3,A9,42,FD,5D,40,BF,B5,8F,B3,89,C4,44,63,5D,7B,A1,63,D0,25,26,DE,B2,2B,6C,DA,7C,53,F7,6F,5E,40,87,65,91,67,77,12,A0,9D,0F,F1,03,C5,35,B4,C0,6A,D5,7A,1F,E9,1F,03,D9,0E,6F,34,2F,5B,F1,B2,5F,31,24,7A,86,53,81,D2,7B,FC,D7,01,CA,FF,57,BF,53,71,D2,2A,A2,29,29,9C,0F,1B,99,AA,50,FB,D7,F5,02,47,03,8C,B7,28,C5,6E,3D,B5,C3,CB,CD,28,34,8D,44,84,32,6B,46,19,4B,47,DC,00,BE,D0,0B,8F,01,2C,6C,02,D0,19,0D,92,A1,9D,02,E1,CB,D7,96,CB,01,95,CC,94,7B,C7,D7,44,9C,4F,29,CF,0C,81,B4,AC,D3,25,FF,8A,ED,0B,EF,0F,C1,FA,FA,DA,9C,32,5A,32,A1,ED,FB,E4,54,C1,36,22,7A,C5,3C,53,9E,42,8C,12,EF,66,75,5D,EE,DA,D7,67,F9,19,79,EB,09,83,29,81,B4,8C,AD,B8,62,89,BA,55,13,B4,00,77,28,36,38,EF,28,95,2C,41,8A,F4,31,FE,43,35,D0,38,FB,4C,A3,F6,31,CE,55,50,42,63,7D,C6,09,95,04,C3,71,3F,E4,36,F9,1E,6A,C2,0B,49,6E,AE,0F,9E,8A,F8,BA,52,95,94,DB,76,F6,09,C0,46,B2,A1,5F,61,78,D7,CC,DC,E4,23,93,EA,6C,80,4D,D3,FF,FD,27,2D,2D,04,19,40,24,F9,AF,05,10,01,87,6E,F3,F6,F9,39,A3,B2,D9,E8,B5,C2,83,DC,50,39,E3,F3,D2,51,CD,E0,B3,C4,12,D7,3B,62,01,B7,A5,10,3D,E2,FC,66,0A,A0,39,5D,DD,CE,B7,03,69,69,0E,DB,A9,7B,2B,7E,0B,2F,F6,4D,9F,21,C8,20,52,DA,50,53,DF,FC,4F,1F,21,55,F5,10,D8,73,DA,87,AB,E7,96,42,F2,8C,8D,C6,72,6C,90,67,E2,FB,97,1B,31,F6,54,24,C4,8E,FF,F8,72,C3,63,B6,63,D8,0E,36,78,51,9C,AB,5C,1D,5E,DD,3D,6F,8C,88,60,75,94,0F,45,D6,DC,C0,51,9A,5D,C4,04,CD,19,9F,2F,4C,2F,C7,2C,A8,2B,F7,EB,20,60,1E,86,71,48,BA,0B,A0,C0,F8,2F,60,F4,56,35,26,16,AE,2A,EA,B0,13,BA,78,05,9B,C7,2D,AE,6C,CC,1C,5D,BD,FD,DA,DB,2D,D8,A7,40,55,91,02,92,CE,CE,5C,4A,7C,F0,A7,EF,33,75,69,A7,DC,32,7E,0A,A2,9D,2E,76,F7,0C,98,AE,A1,C5,EE,A1,57,5D,EB,14,80,7E,19,D8,0C,9F,00,61,AC,64,F1,BA,23,6D,8B,15,06,2A,B8,FE,2B,27,6D,92,88,AB,6A,21,75,55,72,D8,1C,B2,C4,8B,F4,C3,73,5D,C0,4E,67,FF,3C,28,23,7A,25,0E,21,0B,FA,A2,62,1B,11,38,DB,5D,C6,21,18,EE,20,4D,03,EA,DB,72,44,D1,A8,50,42,BF,50,AA,FF,33,1E,2D,29,C9,0C,60,E4,D6,F4,44,BE,79,66,B1,06,37,AD,8D,32,77,D4,81,33,D0,1C,B0,E6,F8,F6,BB,CF,56,4B,25,A7,2F,EE,7F,90,6E,8A,11,44,D2,B0,E8,6C,88,92,5E,13,3C,06,DC,1D,A3,F1,E0,F2,AD,3E,9A,C6,13,8B,5A,EC,BD,DE,0F,CC,B3,24,FF,19,E8,42,F5,C7,F7,0A,AF,A7,DC,EC,A2,E1,3C,98,77,60,DD,21,E2,22,49,B8,1B,3E,97,C6,64,52,37,62,49,A0,BF,8D,92,B3,FF,86,7F,08,12,24,61,E3,95,38,29,13,6F,19,58,0B,FD,9E,6A,BB,01,A9,11,CE,1A,5B,B1,18,62,1D,D1,44,88,13,83,36,BD,3B,0F,4C,EE,D6,92,45,94,EA,11,27,A2,73,A7,12,78,DA,50,32,77,1A,05,3A,10,CC,9A,B1,19,74,63,49,9B,32,29,BE,12,DB,4B,5B,5E,0F,75,94,35,AD,50,93,98,B1,B1,40,0E,2D,EF,F2,55,ED,12,56,53,07,58,9F,06,BF,89,55,D3,E5,FD,9F,A7,D8,C3,D7,CB,18,43,CE,F4,AC,1D,DA,0A,ED,B7,99,E4,35,C7,93,31,3E,5D,35,7B,EE,D0,EE,25,16,46,E3,A4,88,19,CE,4D,84,EB,86,34,65,24,5D,AF,19,0B,27,CE,CD,31,C9,57,41,88,B0,19,BA,E9,E8,AD,CD,A1,3E,AA,11,82,79,B3,93,3A,89,FD,71,8C,84,7F,8C,90,51,C8,0A,44,78,B8,E3,2B,4D,42,AA,03,23,24,C6,C1,02,1A,AE,2F,55,D6,34,C9,B2,DA,D1,5F,17,9F,31,32,B7,76,53,87,78,6F,36,65,39,48,02,56,19,7B,DD,55,17,A8,3D,E9,32,8B,46,56,BA,AD,4A,AC,D6,99,06,7A,E8,C8,E2,ED,57,38,CB,73,E6,18,A5,3C,FE,50,E5,61,85,4E,C1,60,E7,5A,88,FE,26,95,29,F8,00,48,AE,43,64,B9,A5,CC,2C,D9,97,7B,86,7D,8E,5B,55,B8,AB,A8,E5,C1,18,4A,4E,9F,AE,CF,C3,4D,D7,B2,90,C4,DA,7E,BB,4E,58,F5,6F,19,DF,3F,06,14,11,87,14,20,EE,04,AE,AC,A2,07,41,33,AB,33,AD,43,11,D9,62,15,6A,46,2E,EB,6F,51,EB,FF,94,7D,54,0C,40,7A,95,CA,0B,9A,B1,90,1D,44,2D,00,C5,79,DB,6F,CA,FD,B3,D8,98,46,B7,58,25,F1,C9,12,FA,36,B8,45,76,1F,73,11,F4,04,F4,10,56,E8,A7,89,05,77,C3,2C,ED,86,3E,83,D7,32,9B,EE,B6,4A,C4,13,ED,43,58,E3,68,F1,70,D7,54,13,01,41,3A,11,D1,51,93,F4,4F,33,F9,B7,E4,55,3D,4F,AD,A9,37,7B,EF,80,19,5E,04,FE,54,48,36,CD,06,3A,FD,99,B8,A4,3C,2F,32,87,0A,34,27,68,F9,52,5E,DE,BF,C0,B2,67,98,E1,F0,F8,52,39,C8,DE,2F,3F,FD,39,BB,EA,9A,4E,16,6C,A0,16,FA,27,05,3F,F7,A8,2A,DC,C8,C5,AE,63,2F,DC,86,BE,69,94,49,9E,E9,FC,2F,D4,12,D8,2A,02,B1,B9,F1,03,C8,AD,E0,30,7F,5D,2F,61,9E,3A,02,B2,61,99,32,7E,A3,E6,0C,D7,85,EF,1B,BC,69,67,E5,96,C7,79,62,0B,05,A2,B1,81,B6,B5,25,4E,D7,2B,E4,6A,43,BD,85,5D,F7,4A,8A,7F,AE,E5,E4,C7,9F,71,36,E9,84,85,CF,1A,7D,F9,AC,7F,EA,FA,44,74,C4,94,BE,DA,B6,5A,DD,09,B4,E8,D8,60,5D,4B,60,EE,82,78,E6,96,2E,79,D2,06,A0,D5,13,38,F7,07,0D,8A,5D,DC,12,44,13,54,93,46,4D,CE,C3,93,96,6C,65,3F,A2,E9,DE,0F,F9,1D,A4,35,5B,DE,60,E9,56,D7,AD,3D,04,FC,76,3F,4C,48,64,42,1D,B0,37,50,38,A9,3D,D5,8D,1E,0B,53,A1,2A,69,47,24,09,18,04,0B,25,1F,FE,3E,82,E4,FE,94,67,D8,D6,F8,A3,B9,7C,5B,D5,C0,DA,81,D3,30,7F,2D,19,52,7A,33,07,33,9C,32,1A,D4,D1,40,78,2D,D7,C1,E7,E5,7B,0F,01,C0,53,F9,57,DD,D1,A2,93,98,97,D2,55,A6,B4,60,78,02,61,6F,13,C5,15,CF,64,BA,9F,DE,8D,B3,1D,14,9B,6D,73,A7,B3,B7,77,FF,33,DE,68,E7,BC,60,88,C1,AF,AB,D2,41,EB,3B,AD,4F,CC,77,2A,DF,65,DB,DB,88,B4,C7,E9,88,67,D3,1D,B7,54,BF,43,C1,71,73,1F,ED,8A,EE,5A,DF,05,00,E5,C3,E6,85,C3,F6,A8,CA,20,1C,C7,2D,53,9A,CE,C8,CC,07,EF,28,C7,2E,CF,5D,90,17,66,CD,C5,50,A8,AE,84,6D,57,C4,D6,61,DE,AE,8A,27,57,5B,E1,84,00,43,42,42,EF,FE,8F,88,EC,0A,78,30,37,EA,00,18,10,11,52,F1,43,95,83,76,E2,45,CC,11,95,93,7C,8D,85,26,DC,38,C2,8B,05,00,11,30,A6,8A,AD,75,D3,2B,08,6F,AB,F3,C1,A8,F1,F9,14,42,44,76,EB,39,93,0B,84,F0,4B,67,22,D0,83,6D,55,8A,25,A9,F7,92,0B,02,28,CB,FA,8A,6F,84,BA,8F,55,E9,3C,32,A5,9D,15,75,AA,BD,FB,DB,2B,36,F6,3B,D0,7B,1F,FB,F7,EC,35,CD,9B,6A,20,34,E7,C2,BC,9D,15,A2,29,F2,FB,6F,36,8D,13,D1,CF,C7,EF,B5,ED,7A,09,47,5B,97,AD,33,7E,E2,E6,12,19,DA,E0,BD,63,73,6A,1F,48,C6,0F,BE,F7,2B,56,73,1B,EA,A6,71,A3,77,B0,53,B2,EF,E8,86,BA,DC,53,30,9F,48,4B,CA,62,76,A8,20,57,2B,C1,AA,EC,2E,5B,81,72,1D,39,73,16,BE,4E,4F,58,7B,9E,4F,0E,F6,9E,05,21,18,2B,28,9C,7F,C7,83,42,AE,32,BD,70,37,14,E3,86,D3,F6,D6,3F,78,BF,5A,36,60,28,D6,D2,6A,8A,6E,07,D5,E7,E0,0D,7C,3B,FF,F4,60,B1,67,B8,BE,39,F9,62,09,24,A8,18,DF,0A,10,88,B0,E5,FE,67,C7,3A,17,5C,AE,42,99,D0,4D,54,6E,8F,56,28,7F,98,24,B1,82,B4,1A,CA,03,2E,AD,C2,09,BA,B5,8B,06,95,56,9B,49,AC,88,CC,E2,48,0D,45,33,C2,8B,25,CA,75,6E,74,7D,0E,92,D2,D0,69,54,08,DE,90,CA,15,C3,C3,52,A9,8C,9F,56,55,88,C2,EA,B3,19,F9,D2,36,79,DC,B5,92,B3,EF,1D,B0,3A,3C,1C,59,A8,B2,99,77,7D,DC,16,1B,99,AD,6A,74,8C,EB,FA,3B,B3,FC,D8,2C,CE,31,2E,2F,99,BA,2B,4A,19,81,DD,2B,A6,DD,BE,C8,22,BD,5B,9D,B1,AE,D9,BF,66,78,AC,E4,92,39,8E,0D,A5,BD,4D,11,43,A8,FA,63,7A,7C,29,96,BC,20,37,4B,07,45,B8,EC,C7,5E,83,83,7F,1E,29,45,DA,A0,70,46,39,56,E0,DB,EB,9D,6E,FD,35,FE,F5,8F,CE,EB,53,E5,59,0C,D4,54,6D,6C,84,E9,AC,58,75,94,4A,D4,2F,71,39,AA,57,87,F3,CB,19,4C,FE,24,A2,68,48,3B,6A,F6,3C,80,89,4C,45,68,1D,EE,C8,1A,E9,F3,B7,C3,77,31,E3,85,62,A2,5F,D6,1B,12,AE,25,B5,5B,79,C1,CD,4A,C3,8B,6B,A2,84,FE,F9,99,DF,EE,17,8D,3B,9F,61,25,75,FA,D6,7E,45,B0,DE,3F,8C,FC,49,AD,D7,D9,75,1F,54,6C,83,56,EA,7A,60,5C,FF,B1,C5,10,8B,EC,AE,E1,A2,27,24,7F,0B,7B,E0,30,4A,0F,AD,71,79,6D,22,C0,4D,FD,E3,2D,FD,AD,CB,34,03,DA,1D,15,31,A3,65,FE,14,C9,C5,21,E1,3F,17,60,EB,FE,7C,BF,56,19,7C,F1,19,60,B0,B1,F7,52,47,37,A3,FB,F1,B8,29,FA,16,D6,BA,DE,D9,A0,AF,43,1B,76,6C,EA,FF,24,14,55,6C,D5,E4,72,6D,3D,BD,16,02,33,E5,8A,80,07,8F,6B,CD,65,56,5B,4E,D1,D9,7A,4E,66,DB,A0,78,28,3D,08,76,1E,B4,26,54,34,B7,BD,AF,7C,5E,C7,38,07,28,A2,F5,5F,F8,66,C2,80,A7,B5,A7,A7,02,92,46,31,7F,DF,7E,DE,91,5B,E4,FD,C5,7D,15,03,B9,E9,EE,14,16,59,7B,59,EB,ED,6E,6E,6E,A1,30,73,A1,B9,3E,17,02,00,D5,D2,4D,6E,D7,55,12,F9,10,BA,B6,CD,6F,F9,BF,A0,88,40,80,39,27,DF,7A,C2,6F,39,ED,FD,0B,CF,08,AA,00,78,61,14,4E,C2,28,D1,DC,D5,49,0C,9E,70,FD,96,5F,79,C9,61,AD,21,67,8B,8E,8C,AF,52,B1,2F,92,70,C9,37,59,E4,A0,49,D0,6F,73,17,76,F6,A7,B7,B0,CE,ED,7E,2C,79,F8,AC,9E,A8,4A,9B,1A,B7,AF,F4,A3,92,E7,9C,2A,1A,06,F0,54,9A,75,5D,61,9A,1F,E6,E1,0A,AF,B6,AB,CA,81,F8,86,FA,DD,DB,F3,D7,2B,CC,50,E1,C8,51,D9,72,DE,60,E7,5A,8A,04,6D,87,CC,18,6D,23,4D,8D,DD,C4,B0,68,3C,71,FD,7B,4C,DD,A8,B3,F4,FB,D7,A2,A4,88,EA,D8,E3,F4,D1,68,F9,76,45,D4,E4,58,F7,C7,C2,B8,45,47,87,03,EE,82,F6,8F,D2,E0,5C,EE,6C,3D,3B,34,53,91,1C,8A,BF,4C,21,71,79,95,43,E6,3A,08,77,7A,BC,89,C3,30,B6,44,77,C5,D1,14,B2,6D,F8,05,27,CB,95,C2,30,60,49,C9,B5,F0,C2,B4,23,59,66,0B,D1,23,F4,48,4F,3C,83,A8,65,A2,95,20,5F,D6,34,8F,FB,A2,DB,07,92,41,F5,77,16,86,CA,57,AA,59,2F,13,A4,C2,F0,DF,6A,17,DD,85,19,03,D5,8B,C7,79,3C,E2,62,21,47,0F,6C,03,7F,A5,42,2D,2F,6C,2E,7C,56,4A,8E,1B,E9,3C,88,D2,F2,EE,54,7A,CF,AF,29,ED,D7,EE,66,B5,4D,98,24,7A,C9,57,68,95,37,87,8C,7B,41,AB,D7,55,C8,9C,42,69,3E,FE,9B,35,C8,4E,3D,BC,75,3C,E6,FE,8A,BB,B4,EA,7C,28,71,1C,39,A2,03,EA,6A,2E,F9,19,25,AE,00,C2,BD,8D,44,EB,D1,71,AE,AB,76,34,F5,15,95,34,C6,9A,53,D5,97,B0,D8,AE,76,36,A3,CE,62,4C,FD,F0,F0,DF,EF,02,EB,DC,1D,93,20,38,00,4B,97,89,C9,F5,0A,C0,85,AB,9A,53,C3,8A,78,89,10,91,2A,B2,06,1F,47,FB,56,60,33,52,78,DD,C3,89,8D,20,32,1C,28,22,D3,FB,9C,A6,F3,CD,74,CF,C1,A5,95,9A,1F,A9,FC,56,24,7E,85,2B,08,58,62,36,F3,3F,B3,BE,BD,B7,29,60,E7,B1,70,6D,6A,E8,5F,26,8D,40,56,39,9D,4A,83,D6,97,94,0F,88,32,95,BD,D4,51,CD,1C,7A,65,4D,9C,22,AE,16,27,F6,6C,7C,48,0D,BC,3A,A5,98,3F,F7,4D,84,47,1C,5B,AC,07,7A,0A,0E,FE,9E,86,8C,D5,A2,A1,35,F8,B7,97,5C,85,CE,12,C8,F8,A5,01,19,1B,6D,DD,16,29,94,2C,4B,CA,B8,D4,AB,0D,A1,8D,41,BA,C5,4A,96,82,A2,3A,4D,00,4D,A9,1A,A2,EF,E8,CD,B5,DC,68,98,76,26,0C,40,CD,CA,D0,F2,52,8F,EA,E0,5F,C0,22,C3,8B,29,FE,48,7D,C9,3A,F7,DC,33,80,3A,89,C7,9A,1C,73,3E,B8,AA,BE,B9,03,C6,D0,1F,30,79,46,DE,BE,4E,B2,D2,0D,4D,72,B8,6E,25,40,F9,51,77,33,4A,6D,40,50,AF,C3,34,EB,67,20,B9,9A,B1,59,97,EF,55,C2,5E,B6,B5,F3,CD,43,52,B8,9C,43,78,39,8F,F4,DD,83,96,93,82,D7,6E,49,6F,63,A9,21,A6,83,43,00,04,56,60,36,B5,94,80,D9,46,84,4E,9F,7F,02,6B,43,DD,05,78,B1,48,C8,D3,BB,C4,06,D1,49,D2,FE,CA,61,67,E0,63,BC,BF,DE,40,49,EF,8B,48,07,84,CC,27,5B,BD,08,68,D8,68,32,FC,85,5B,01,FC,65,E6,8A,DA,4F,C4,7E,7D,D4,46,CF,33,E8,C0,53,6A,6D,C2,8F,77,2F,6F,C3,33,85,7A,EB,29,6E,FB,A0,B0,7F,25,4B,B1,22,50,C1,6B,C9,A8,76,F0,CC,41,75,6D,7D,2A,1D,60,18,8A,B6,53,02,BA,74,48,A0,A4,6C,24,0A,85,F5,62,CB,0A,99,DC,FF,A3,E3,77,51,0B,16,E8,B9,CE,E4,A2,C8,18,97,5D,E5,0B,AF,06,17,DC,37,DA,B2,10,20,67,1F,0E,2E,BB,45,11,0D,B7,89,8F,C3,59,BF,7D,7B,D3,BF,5E,2C,48,98,BF,56,F4,D8,E5,85,79,36,23,C4,7A,A4,7E,0E,0B,8F,77,F9,D5,47,3B,2F,22,03,6E,68,A7,29,E3,B2,29,85,C0,EF,25,07,66,4C,19,A7,7A,61,9A,F6,19,63,F0,CC,CB,C8,1E,18,9D,BE,90,8E,65,DC,E2,D2,B8,1C,5D,50,14,CA,CA,47,6C,D6,21,B6,55,DB,DA,C9,E1,4F,48,A1,5A,10,C7,09,40,B0,43,42,BC,18,A4,6F,7F,C7,C3,8E,7A,E0,2B,3F,09,BC,FD,AD,E5,DF,D9,34,01,71,AA,A7,6E,8D,CF,10,7A,8F,33,48,7D,C9,D8,4B,D7,F6,85,0C,AA,EB,B7,A7,D8,15,9A,06,DE,71,72,B3,4D,F2,0D,22,A4,6C,6F,5F,95,17,5C,35,11,03,00,A5,0D,08,BE,35,99,C5,42,79,9C,A8,EE,00,91,FC,50,EA,61,91,CF,5E,69,71,76,CB,43,59,EB,44,C1,15,32,0B,90,6F,F3,3F,9B,48,F3,7B,E4,05,FF,62,6E,2E,85,08,7F,E9,5C,BA,9E,B7,2B,92,E6,E9,D2,B8,A8,6E,99,D2,B0,0B,F6,E1,01,47,23,13,A4,D2,A1,0B,D3,B8,22,24,58,44,A2,06,68,23,E5,DF,5E,7A,5F,25,EB,42,39,11,08,D2,4D,A6,1D,08,7C,42,FF,F8,A2,9A,25,EE,AD,3D,05,FB,C3,24,80,44,4A,89,46,25,6F,4C,F7,E1,AA,F3,78,1D,63,83,02,86,F2,A4,FD,B9,1C,A9,06,13,C9,A8,67,A5,67,28,E4,93,1F,4B,0B,92,01,D8,09,46,EB,09,27,61,9C,A6,04,1C,30,DF,11,C0,11,FE,0E,6F,EA,8C,79,20,C2,C6,22,5F,87,B7,DF,89,92,F0,01,B3,3E,D1,BE,38,61,90,FE,1E,66,22,62,31,88,B1,43,3C,C3,84,EE,35,A0,9B,09,94,41,FA,B4,10,4B,59,DE,77,47,19,B4,CB,F7,E1,39,12,FD,48,30,4A,03,87,85,95,CD,A5,D2,1E,94,20,73,0E,A4,93,D3,21,6B,C2,43,C0,1D,A9,54,DD,7A,3A,01,F4,D9,22,FD,EA,77,02,C5,E1,9C,4C,82,B0,6F,8D,56,FF,77,FC,93,44,37,57,E9,B3,EA,D8,38,4C,2C,10,35,5D,38,93,52,4D,3E,0B,3B,A7,C7,1D,B2,08,DC,01,B2,24,F4,96,53,E7,17,6A,7C,E1,3B,25,0A,44,FD,BA,DF,35,61,84,66,0C,82,08,53,9A,CD,81,41,40,F3,49,63,6A,3F,8C,45,C3,35,D8,DD,69,8D,2E,33,D6,9C,2E,EF,49,E0,7B,1A,2E,C1,F3,5F,F6,85,E7,45,BE,E2,B3,D1,E8,6E,E4,16,D0,85,4D,47,7C,AA,FF,79,84,0F,B0,DA,C2,C4,C5,A5,B4,D0,C7,FC,DE,FD,F7,B4,73,9A,B7,45,09,D4,2C,A9,DE,D1,CA,D3,62,34,AD,9C,E9,57,63,38,7D,EE,0D,64,1E,6D,EB,62,E7,95,78,77,C5,6B,2B,BC,E1,48,E9,B1,7F,19,C1,F5,15,8B,BC,62,41,08,18,45,11,F5,CA,09,3C,CD,91,74,34,E6,2E,7E,2A,FF,C2,FF,6F,70,57,21,35,C3,4A,8A,B8,BC,C2,3D,FB,A7,DB,23,21,EA,3C,0E,D6,C7,EC,00,00,28,C0,F0,77,AD,29,FD,C9,52,2D,98,6A,94,5B,96,25,0F,AA,E9,94,A6,74,27,F7,F9,B8,B7,80,A9,E6,D8,97,4A,12,80,00,3D,25,82,55,85,D9,4C,C7,8E,2A,FC,AF,06,AF,C3,88,D8,3C,16,BA,A6,D3,CC,AC,C6,8C,7C,D4,09,64,2D,EB,A8,E8,62,24,8F,13,97,9E,45,B3,F9,FC,1C,A4,D5,8C,A3,78,DE,2D,B0,9B,0A,55,29,12,18,5C,7E,F8,06,77,35,89,CB,C8,FB,A1,E4,4D,90,DC,28,FF,AF,48,67,D4,00,3E,2A,A7,C6,C0,AC,AE,B2,AD,64,52,8B,95,7D,06,B9,90,70,5D,BE,E8,55,87,47,AE,8D,1F,58,13,A5,A5,8F,42,50,CE,2C,B5,F7,54,62,89,04,25,65,6C,CD,DF,C2,FB,28,1F,F7,2B,86,4E,7F,EE,A7,4D,35,F5,7F,87,1D,FF,1C,F4,82,19,89,36,16,1C,5B,E2,98,A7,BD,16,96,23,2C,CD,9C,35,76,F0,71,A8,84,0C,7E,4A,17,DA,22,1B,8A,53,90,4A,94,E3,6A,B6,18,23,CB,99,F2,A3,7F,64,6A,87,03,82,6A,1F,BE,07,C7,F3,5F,CD,36,13,F8,58,6E,93,0F,71,B1,55,DF,AA,E2,27,4C,53,E5,A1,47,DB,EC,25,DC,04,FE,39,AF,D3,5E,91,C9,86,71,C8,D0,A8,A7,7D,E7,61,45,58,EC,89,71,31,7F,11,0E,6B,BE,8B,91,E4,71,85,BE,02,D9,3A,FC,26,B6,79,1C,61,4A,8D,17,E0,C4,6D,D7,29,21,E3,C6,75,D3,5E,BA,31,90,86,C1,3E,2A,86,27,03,87,26,72,75,DF,DB,99,CF,DC,08,74,4E,59,A4,0F,7F,51,A3,15,3D,8C,35,A1,E3,D3,58,1A,E9,E9,45,22,09,9E,4F,DE,A8,A6,3F,5A,36,17,16,E7,7F,3F,D8,E8,8C,ED,CD,11,7D,52,67,DA,AB,42,28,C0,13,61,10,E0,79,28,CE,8E,4E,9A,20,79,59,BB,03,DD,34,2F,F3,9E,34,79,29,F5,F2,BB,54,FB,9B,A7,EB,69,42,FF,3D,8E,DF,0E,A5,95,2C,42,BE,3B,56,DA,88,B8,CF,3F,03,E1,FD,D7,E5,16,7F,2F,26,E3,C4,25,A1,B2,3F,1A,AE,63,56,2C,AA,30,09,43,71,FB,C1,F6,3F,A8,98,8B,C6,AE,2A,C3,57,2D,C8,52,3B,8C,39,CD,01,F5,63,FB,0E,04,88,ED,CF,EC,B4,36,7F,16,73,8F,D2,56,8C,F0,28,49,66,99,D1,56,8D,28,CC,6A,28,8B,5E,4A,8A,AD,64,E0,6B,EB,EC,B6,5D,DE,2B,22,DB,C6,30,7C,FD,EA,90,9F,9F,96,7E,F4,DC,B2,3A,0E,7C,DE,67,91,B3,C3,80,07,8B,FC,29,6A,F0,C8,EE,88,25,F2,2D,24,9F,82,E3,CF,0A,05,8F,70,55,BA,E0,9C,F3,C6,8D,33,C4,61,CC,18,61,24,FA,31,60,54,0A,15,DA,51,32,8F,A7,69,A2,D6,F0,56,7B,7B,51,A0,0A,BD,C6,77,21,0E,6A,16,52,C0,28,D4,77,D1,06,EF,51,28,F2,F0,9B,CE,F0,CC,77,BC,2A,57,BA,50,C8,91,BA,B1,8F,FF,A4,1A,CC,F5,AC,00,EB,CF,B3,65,B4,11,69,84,BC,37,95,B0,D6,AA,74,21,D1,3A,60,17,77,A0,85,91,B1,98,43,D2,99,60,9A,3C,E9,71,F0,47,DE,EE,59,61,8B,72,84,8F,CD,5D,A9,E5,5E,B5,75,4E,67,C9,4B,5D,5C,9C,F1,B1,C8,73,A6,09,3C,29,09,31,2C,72,1D,51,5E,49,6C,37,25,F4,E8,A6,A5,9F,98,70,C8,4F,66,95,20,F3,FE,EE,1F,39,3A,C3,46,A6,4C,A5,CF,78,BD,77,02,E9,3F,81,CA,0D,95,CC,84,A7,85,2A,A9,DC,CB,9C,7A,65,F3,2B,54,4D,22,72,97,C8,6E,45,58,6B,F1,2E,20,54,BA,C3,D3,5C,D4,5F,08,E2,A0,C2,07,E0,6A,00,CE,36,AD,0A,5D,9E,8B,26,83,04,0F,97,61,6B,BD,6F,3D,FF,1B,E4,7A,1F,DB,2D,E1,64,24,7B,F6,D9,34,C7,94,8E,C3,6A,65,B4,A2,C6,F8,42,78,EE,EE,3E,1D,E7,BB,EF,91,37,C9,2A,98,CB,3D,3B,30,1D,C2,FD,36,99,05,31,62,1A,FA,74,EE,F6,DB,62,BE,48,08,4A,15,C6,C1,82,CC,BC,95,44,1C,7E,3F,F8,AE,60,60,C7,59,4F,08,B0,59,AB,1B,5A,FF,00,3F,D7,9E,41,54,D3,6D,51,BA,2E,65,B7,22,E5,DD,55,13,08,BB,D6,5B,8E,A1,4A,31,F6,72,40,C7,BA,23,D1,31,23,27,9C,04,59,D7,EB,C5,D9,07,AD,E5,2E,11,A1,F5,3C,31,90,B1,16,4F,9D,2D,EF,B6,49,94,CB,41,ED,A0,04,42,7D,21,C1,19,0A,A9,DC,90,61,CB,9A,6F,D9,37,F2,EF,42,0F,55,19,0C,75,51,A6,D1,5D,F3,B6,A7,5C,22,11,19,AA,73,D6,28,C2,69,A5,60,AE,AB,53,72,72,11,43,58,1C,45,F2,84,0B,2A,40,A0,F9,4A,B4,BD,59,8C,01,7F,80,92,17,71,EA,3D,EF,EE,3E,D9,8A,E4,D4,F3,DC,04,95,70,B2,A2,50,E9,C4,85,3E,6B,D0,62,BF,75,B9,7C,31,35,1D,7C,81,51,21,92,8B,A6,7B,08,BC,7B,68,BF,FE,FB,1C,F9,13,88,73,43,7F,A0,54,47,14,6D,87,A1,5A,41,C6,DE,08,B0,10,8E,0C,E8,22,D8,8F,CF,40,53,72,E3,7A,9D,7B,95,5B,C8,13,F2,EC,11,26,1E,E5,35,05,62,96,E5,F4,A6,09,45,69,F8,5F,39,18,BE,6A,41,3B,A7,08,92,BC,6C,77,DA,80,39,C6,81,CA,37,AF,FA,20,A2,BA,9D,11,DE,36,FB,D7,62,CD,96,52,4B,6F,42,8E,18,1C,99,06,19,AD,A1,85,19,C8,65,B6,35,14,6E,9C,DB,81,40,38,10,64,7E,F0,CD,55,71,52,9B,39,A4,95,8A,42,B2,41,A4,EB,8F,E9,03,64,D3,CA,54,8B,6A,BB,92,D8,41,04,46,5F,F8,CF,15,6A,72,0D,FE,95,3D,75,3E,D1,D1,19,DB,C5,F9,87,92,C3,A8,F4,58,B0,48,D7,92,32,53,3D,E7,BF,B2,FF,F1,F8,88,24,BB,3F,18,75,F2,EB,73,09,CA,D7,42,19,E3,FE,A5,19,DB,49,9E,F2,96,DA,D3,17,8D,98,F1,D1,BE,D4,83,DE,66,CA,86,D5,8F,DB,DB,63,3E,57,65,9C,65,F3,86,DE,77,4D,A2,7E,F8,A8,3C,5E,56,20,62,F1,87,BB,7F,A0,A6,F7,F3,96,27,C0,11,B2,75,3D,06,64,6C,57,22,0D,0A,6E,B8,B4,DC,FA,B4,DE,83,C7,10,DD,2A,77,43,C3,C1,6A,AD,CF,31,D7,90,F0,AE,DF,C1,35,DC,AF,20,E7,06,A0,67,88,F5,66,66,85,D9,8D,01,6D,AA,63,6D,79,EB,54,9F,E0,CD,C2,F6,31,47,92,FA,4C,E9,FA,8A,0D,CF,3E,45,07,91,B9,B6,3B,6A,ED,22,C0,5E,93,4D,23,A7,16,3B,F7,CB,EB,EF,22,4E,77,A9,9A,8A,7B,04,EF,1B,96,75,97,0B,AF,CE,F5,47,E2,2A,81,22,A7,CB,D3,B6,98,2E,24,97,38,A5,E6,7C,87,D7,0C,D1,56,10,4C,3B,07,FF,74,2F,6D,E8,CE,EF,79,38,CC,5B,5A,1D,9D,0F,D9,91,B1,AE,6D,B8,C5,49,76,44,A0,58,62,70,8F,81,8C,36,5C,06,41,AA,A1,6B,0B,54,F4,A5,89,68,9D,78,C8,7B,58,3D,60,EE,86,23,3F,FC,E8,07,FE,13,A7,96,7A,17,14,4D,11,CB,C2,E0,8F,24,04,59,B2,2D,65,CC,AC,22,EF,05,4F,B1,1D,95,39,31,2A,0A,AD,0E,53,06,2D,5A,61,49,D2,21,62,12,E3,25,E6,65,47,E2,C1,98,62,64,8E,B7,75,A1,E3,02,BF,18,A9,1F,3C,53,C3,B8,0B,1D,9F,47,1B,55,E0,42,E2,19,7D,F1,0D,11,7A,21,AE,18,D8,89,89,EE,3A,22,E9,B7,F5,FD,AE,56,CD,4D,A5,50,F5,2B,C7,31,77,AA,23,85,AD,56,6F,CE,24,41,68,3B,75,5E,67,1E,43,30,8F,8F,93,45,2E,7D,B6,0E,8C,DE,F5,E3,E7,C0,A4,CF,E4,B5,2B,EA,B2,03,92,45,8C,77,84,A5,69,06,8E,83,88,E5,CB,BC,87,FA,7F,58,80,CA,61,4E,EE,0A,D2,4B,3B,7C,FA,3F,F3,EF,7D,84,BC,87,F4,C8,E9,77,32,F3,5A,E3,EA,A5,CD,60,14,EA,6F,71,AD,B7,98,DD,8D,5D,2C,7D,38,66,58,F9,75,00,10,9E,D9,ED,2E,DF,E8,42,7A,03,DD,79,B6,9A,E6,04,DE,2B,1C,AF,73,97,02,25,78,AB,7C,A2,7B,95,1E,25,53,7C,33,42,DE,F6,81,AF,57,96,3D,C2,35,18,E3,2E,56,CF,14,95,32,13,2F,63,4F,1E,03,AB,8A,09,2F,42,63,BE,BF,A3,A7,66,B2,55,9B,28,9F,4D,08,5D,5B,88,70,4B,CA,BD,98,88,D3,E6,5C,CE,60,23,BD,BD,61,F7,E6,91,CA,BE,73,84,62,DB,21,41,91,3D,31,FF,A6,CA,AB,C4,BC,64,4C,67,CA,5D,72,EE,A5,89,7E,EC,C5,1E,E8,B3,05,94,80,ED,6C,46,76,81,C0,9B,0A,35,3E,AB,7A,CC,A7,2B,03,24,2E,FD,8D,45,B8,D4,4A,66,F7,3C,EB,54,44,85,B4,AA,F5,34,CC,CE,F2,BC,A9,4A,3E,2D,DB,87,AB,F7,68,8B,1F,A0,BE,0D,63,AE,5B,BF,F1,25,D8,1C,27,7C,04,BB,BC,41,26,94,72,50,47,19,4C,0C,3D,F4,C3,2D,93,9C,41,98,64,B4,EC,84,92,75,4F,16,1E,52,E1,88,8B,7A,9E,D6,C0,DC,89,80,1C,ED,E5,58,39,00,9D,C0,CF,33,51,91,06,7C,8C,50,36,7E,0B,18,16,09,B4,24,F3,E3,99,02,86,BC,68,A1,04,55,25,88,69,5E,50,29,0F,4A,46,57,2F,E8,4E,61,A4,2C,8C,E3,45,D1,59,8E,48,20,8B,AE,BF,86,4F,D3,A6,7D,14,96,36,40,19,96,D4,DD,6F,7B,D7,EF,EF,CA,36,2C,0F,2B,D0,B8,9B,C1,F0,7F,15,BC,24,B7,B5,19,3E,10,DB,F5,41,4A,BE,37,FC,AF,1E,1E,85,93,CD,DF,71,D0,76,87,FC,3E,CE,A0,82,A8,63,1E,2E,06,D8,9B,C7,E7,17,EA,90,4B,7A,44,BA,04,B2,E0,F4,2E,50,86,53,A1,DF,E5,9F,7A,99,7D,50,B6,15,36,D3,94,7D,F2,54,C9,15,69,5F,CD,D7,D4,BC,00,98,FF,65,1D,86,6D,6E,F3,78,00,DE,63,23,03,8E,B7,EF,54,89,FE,54,BE,9E,09,2E,B5,D7,3D,90,EF,14,CD,DA,1D,BC,BE,94,86,C8,E7,46,BE,AB,D4,8E,3B,2D,55,F7,BD,6C,6F,B4,7C,2C,22,CB,5E,C0,09,EB,89,83,BC,39,B4,9F,60,EE,EE,17,9F,11,72,D0,8C,98,C4,7C,18,5A,E2,4B,FD,49,6C,F4,68,7F,80,FE,79,67,FB,1B,51,0F,C0,D0,23,92,08,67,33,DA,78,A1,B7,D4,16,BC,26,A8,33,E3,91,51,65,4D,A4,4B,CC,C0,40,F5,B9,FF,29,E3,24,C2,47,57,EC,AB,55,87,3D,79,F4,51,49,21,DE,23,AB,8C,FA,A3,24,FA,CF,A9,94,F2,26,0E,2F,09,9C,4C,E2,7B,83,38,9F,D1,F9,3F,8D,BE,53,8C,00,57,8A,56,90,E9,6B,2A,FE,FF,AC,4C,E8,F1,5C,6C,52,03,0C,17,F9,37,06,19,EF,14,B4,50,1B,CD,EC,51,69,AC,7B,14,00,34,A0,42,3A,FC,FA,6A,52,91,6E,61,0D,B1,72,39,3A,C6,89,FC,6E,FE,69,9C,B1,E5,1B,4B,E5,C8,AF,DC,9D,5E,C6,39,EA,1A,20,E2,14,92,4D,17,EB,3F,36,97,AD,AD,69,E5,24,79,04,78,3F,B8,95,B3,E4,6D,48,5A,1F,B5,45,A3,BA,05,94,92,41,AC,99,FB,6B,6A,76,85,5B,AE,A1,B7,D1,4B,C0,CC,63,5E,44,86,0C,DF,88,92,78,B7,1D,CB,AF,0F,A4,9B,71,04,C3,B0,0B,10,F5,06,61,09,7E,FF,78,AE,B0,A2,4D,D4,1B,52,8F,73,15,0F,44,02,12,75,8E,E5,96,08,7B,EC,AC,0E,6E,4C,25,15,58,B4,FF,AB,CD,B4,0A,DA,A0,09,CD,DF,78,49,45,65,D5,C9,C8,E7,AB,DC,04,0B,8D,24,6D,10,06,A1,C7,7D,45,22,3A,8E,14,15,F4,6A,9C,3B,B8,9A,86,71,6E,5F,6F,1F,CD,53,38,C1,51,88,07,63,B2,C4,D0,84,4C,C7,2D,B9,A2,B2,CA,57,23,07,8C,0B,2C,97,8D,A5,84,5B,63,67,4E,99,C1,09,5D,D0,C7,60,CD,0A,C7,BB,BE,71,3B,0A,17,B5,F7,CC,2A,D6,C7,02,81,46,16,0F,E8,9C,AC,4C,09,32,FC,82,81,B7,50,41,38,E2,B0,31,7E,0E,0B,40,51,1B,5B,94,61,CC,7C,36,E5,3C,BF,CC,FB,56,BE,15,CC,95,1E,E7,B7,0A,08,6A,A3,D4,55,0C,1F,69,17,E4,7F,72,A2,91,C4,0C,32,9C,35,F2,40,8F,AC,79,10,36,6B,60,B5,77,55,67,81,1E,99,B6,94,BF,F0,96,07,E1,39,7B,CB,56,59,E2,74,66,BC,C1,E2,43,BD,84,CA,81,5F,11,4E,6D,0F,13,4A,B1,64,A0,5C,B4,39,40,B2,92,9C,E9,10,DA,D6,AB,C8,BB,40,09,5A,DF,E5,1F,DC,54,4C,EF,36,2F,48,7F,00,4B,BD,E6,FD,F7,FC,63,E4,CB,26,9D,37,D7,29,C4,60,81,9F,1E,4D,09,B0,9B,99,87,03,25,ED,AB,D2,29,C0,F8,4C,26,79,04,32,3D,8E,A9,E8,34,2B,4E,76,3B,F6,41,54,EF,5A,A8,A9,23,54,E5,27,AC,3A,01,34,FA,E7,50,21,92,6F,D5,4C,1C,56,E9,49,FD,AC,A9,22,6C,6B,EC,61,A6,B1,1D,DD,01,8A,66,50,2E,37,93,DC,AC,4E,1F,C3,9B,54,FD,DD,B4,5A,9E,B7,3F,46,0A,2B,99,D7,1E,71,76,9F,7B,F4,45,91,DB,BC,A2,95,EC,D9,11,B4,3F,C0,6B,22,01,EA,16,49,41,22,88,A1,A8,D7,3C,1C,36,FA,87,1E,4A,02,A1,F6,C6,16,60,D7,64,1E,72,F5,99,D4,56,0B,57,D6,24,1F,C5,4A,B9,8F,C7,A3,02,9A,47,5C,EC,C3,4F,E5,F2,A0,C0,CB,AF,F5,5A,A7,A6,C8,3B,E4,49,7E,F3,63,93,BB,F7,41,F2,6A,F1,31,EC,2F,4B,B3,F7,7E,6C,BB,8F,49,1A,78,87,97,DD,1F,34,9F,1D,C2,3C,F8,5B,6F,82,5A,EE,3D,1B,93,A6,5F,ED,FB,F6,38,C5,36,4A,BA,AC,88,EB,F2,07,AD,90,A4,7E,9E,38,BD,BF,0F,F4,45,21,70,43,95,FF,80,78,8D,04,70,A8,37,07,B2,B0,46,10,BF,BB,07,05,83,BB,20,8B,77,6D,FF,F3,A0,CB,A6,0A,34,AE,62,EA,64,08,10,48,96,76,2D,3A,74,B9,F0,D3,CD,00,85,CB,36,88,7A,61,3D,90,21,E3,17,94,86,35,D1,45,F1,CB,3E,A5,50,48,3B,8B,7E,5D,EC,9C,04,80,D8,E6,FE,A7,73,4A,DB,2B,E3,A4,A3,32,85,1E,24,1D,5D,04,22,B9,7A,CF,6D,33,70,5F,39,83,36,23,91,12,F7,A4,5B,D9,B1,F3,3D,35,C5,AB,AB,D7,AA,20,27,6A,5E,8D,B2,F1,76,D1,8B,0E,9F,C8,A3,88,42,3F,1B,1D,B7,64,29,5F,C1,8B,91,40,BA,10,AB,FF,12,27,F6,60,E5,E6,2C,8D,75,08,6D,26,D4,B1,6F,0B,F3,D1,84,85,22,94,5F,71,95,00,83,9B,C8,D0,C2,44,64,5C,23,48,C0,AC,CB,29,BF,A6,02,B6,03,62,BC,63,89,D8,75,D9,B8,6C,91,48,08,B5,3A,F4,44,71,36,65,D3,83,71,03,34,BC,0B,3A,15,E9,35,F8,D3,A2,B6,5F,31,FA,3A,96,33,22,91,27,3A,90,1F,FB,71,44,2A,48,B9,BC,26,01,00,7D,FC,33,98,6D,D3,FA,C6,74,7F,48,A6,B7,AD,7E,04,A9,ED,FD,2F,F4,C9,91,CA,08,E6,3C,43,36,91,35,67,40,77,B7,99,7C,22,5B,EF,25,E1,08,37,76,06,A8,E1,35,48,64,99,F5,C6,28,92,E5,30,F7,49,C5,30,78,3E,EF,02,A2,A0,AE,F8,21,2B,87,C3,FF,35,FC,08,39,9C,97,A3,3F,87,5A,0A,C2,CA,6B,CD,3D,14,EC,D1,D0,6B,0D,F3,51,7C,AA,AE,A5,44,E1,AA,2C,F1,3D,86,72,C2,1F,83,86,A8,1C,77,AA,F0,72,67,7B,23,0B,AF,1D,91,2F,CC,A2,29,76,06,BB,71,AD,9E,20,7C,BE,FD,E3,55,78,A9,CA,03,8F,1A,8D,EB,C8,0F,5B,8D,2D,ED,5B,E8,00,B8,D0,5C,B2,47,07,C3,33,A4,6C,56,9F,8C,60,11,21,D5,39,04,92,9B,A6,CF,01,9F,C6,C8,E5,D8,7A,C2,E5,85,89,77,18,B0,B1,82,37,B3,42,5E,7F,A8,4E,09,EE,3F,70,A3,1B,54,46,89,CD,89,CA,BE,EF,CB,BB,B8,96,93,FF,7D,B8,41,A9,0B,CF,AE,24,AD,6C,D1,E6,5B,3F,48,C6,33,49,B1,16,8E,C3,DE,73,8E,F0,FC,86,4B,38,3D,A1,53,5C,C9,99,99,70,F3,CC,E7,A5,D5,8B,5A,09,49,C4,EE,0F,61,31,C1,C5,11,29,17,96,CC,58,5A,53,C9,68,96,DC,09,C3,B3,B1,AB,30,17,AA,30,E4,31,BB,49,5D,ED,3A,78,F7,BD,3A,30,A1,FF,9C,84,A0,39,80,4F,CB,72,33,6F,5A,BB,A9,45,72,29,38,1D,BA,83,0B,C5,E6,0A,8A,6D,EA,45,C0,3B,6F,26,80,1F,16,4F,80,FC,D7,84,DE,00,37,B5,4A,31,31,08,86,FE,65,7B,55,C7,5C,94,FD,87,3F,AF,D8,4E,67,89,22,81,5A,23,0A,BB,D7,B8,17,00,BA,74,6D,86,67,94,48,44,F2,06,69,84,A5,62,F6,26,05,C1,B1,A5,16,3E,6A,B5,15,36,3C,AC,77,83,8B,92,4C,C4,97,77,7E,A7,E4,C4,0D,2E,E1,C6,39,CF,57,BB,B7,9A,B7,A6,5B,E4,E1,77,C6,24,2C,11,F7,81,FF,57,60,C1,06,65,98,D4,73,61,78,C0,CE,1B,F5,47,A6,26,DE,A3,E2,4D,A1,C0,C0,85,66,81,17,80,46,6E,0C,80,45,B5,2A,15,B3,13,62,9D,E8,B6,E6,92,09,90,02,C7,B1,70,3F,A0,1D,37,10,6B,01,6C,72,2B,43,A2,60,52,F6,85,E4,A1,C1,5B,F3,57,AB,2B,03,D0,78,3A,9B,37,F2,25,D8,AD,C4,4C,55,9B,07,B0,F5,53,8C,20,20,54,D2,9E,F5,35,81,3D,77,72,83,8C,4B,F5,D2,46,07,BB,59,B7,49,2D,C7,AD,86,E8,3F,20,17,FE,CB,2D,7F,02,20,A4,FF,38,AE,22,54,4E,2F,55,51,3F,EC,30,C5,0F,A1,D5,BF,B9,62,B6,A6,43,13,32,5B,6B,A1,80,F2,A9,A6,CF,C3,B7,6F,79,19,14,A7,8A,50,AD,85,42,66,9C,9F,F9,F5,21,D3,3A,61,2F,6F,0B,AA,5E,6E,BA,3D,2C,7A,E0,04,F9,1B,31,D8,49,F1,F3,E1,05,93,F0,5A,57,85,C2,0A,92,19,2C,60,A4,4D,F8,17,73,C2,FF,C4,10,F2,A3,BE,7C,05,70,C0,46,1E,33,F9,96,3B,1C,6D,0A,D5,10,2B,BD,32,EE,F1,02,46,0D,D6,41,73,7A,C6,AB,49,22,B9,0F,3D,45,33,DE,A1,26,F1,5A,DD,83,3A,4F,5E,AF,FC,67,E0,27,02,17,27,53,68,84,B0,53,03,E5,79,EC,51,E6,76,2A,5A,7B,2F,F0,3B,C8,9C,F5,53,13,2F,D5,34,31,67,73,DA,9B,82,55,2E,04,E7,CB,88,68,D8,CA,C6,05,6B,B7,7D,F0,D8,86,6D,12,42,50,C3,8B,B4,AE,4C,EE,D7,43,FF,F3,A3,9B,41,7F,3E,AE,35,B0,F1,C6,3C,DA,E7,C2,0C,B9,D8,05,1F,16,93,22,DA,34,14,B9,AC,E2,E4,AE,97,13,63,08,F8,D0,60,0C,D4,8F,5B,CA,BE,93,CF,4C,DD,C4,C5,8E,E6,FA,C7,1C,3D,56,BE,FE,C3,D2,17,90,88,AF,16,0D,72,81,2C,8C,82,B3,B3,76,D6,11,E5,C9,F2,78,A7,CA,A4,2E,2A,6E,FE,F4,63,6D,46,D2,93,3E,A9,37,50,A8,04,5F,69,C1,CD,78,84,72,35,44,7F,EC,1B,AC,4C,5A,F6,54,3B,07,0C,2B,1E,49,EE,E1,2E,20,36,6B,FB,05,05,E3,10,B4,6C,ED,2D,12,9A,EB,D9,4D,2E,D9,D6,8C,0A,94,38,B0,92,34,EC,B3,DA,61,05,09,36,B7,8F,76,EE,B8,C1,56,8F,66,D1,0A,D8,81,30,27,5D,66,0C,B2,AE,6B,5E,F2,45,F9,BF,03,81,59,DC,5D,0E,14,8F,F9,C6,65,77,32,47,CE,79,FC,F0,75,1B,DD,10,CE,A8,AF,37,51,7E,EE,93,3C,61,42,56,F9,6F,A1,41,D7,E1,F8,50,DF,75,7A,C8,F5,8C,22,13,83,EF,AF,99,1B,EC,7F,0F,D5,6C,3D,1B,E3,52,B2,19,9E,CB,9C,EF,78,77,F9,03,38,BC,66,BB,1C,73,56,03,BF,CB,67,66,D2,C7,16,9E,64,76,87,AE,CF,2C,77,52,F0,2F,AA,74,8E,9A,75,06,ED,1D,E0,96,9A,C1,E6,D8,17,10,17,28,4C,43,CA,05,CB,B7,5A,82,E4,CE,20,AB,57,49,85,BD,42,5D,2A,73,DB,AE,27,70,4D,B2,A4,23,06,5B,DC,22,A7,AB,EE,CD,8B,C5,A1,CB,CC,20,A3,E7,D5,17,0E,99,8A,E0,25,5D,3A,33,4C,DE,7C,37,CF,2A,43,71,67,5A,3E,4D,3E,25,B3,86,4C,DF,3C,90,72,F4,9E,B4,99,62,0D,A3,B1,4E,56,AB,2C,FD,0A,E3,14,69,56,0D,CF,02,44,99,FC,0B,B6,46,00,F2,10,F4,CC,C1,C2,25,42,E0,76,9A,4A,0E,40,62,87,58,AD,53,EF,C0,2E,8A,A3,E1,47,2D,35,15,BE,CB,1A,B6,89,C2,0C,9D,42,E8,B7,AC,A0,7E,0F,4D,9D,CF,89,C0,90,76,3B,14,BF,60,97,4B,0C,B3,12,55,4B,B8,08,12,A1,D1,70,65,A3,A9,38,39,C0,B9,B6,31,50,E2,C9,56,84,6E,31,A4,48,93,0A,0D,04,16,EB,12,61,9B,E4,AA,3A,6A,90,0B,D2,7B,35,20,88,CF,F7,A7,A3,EE,BD,BE,95,45,52,20,A1,E8,B9,32,4B,51,66,68,FC,C3,E0,46,89,DA,2B,34,9F,18,18,70,7B,A5,A9,B6,79,9A,71,3F,2D,AE,F7,51,B3,81,D9,F6,29,F8,C1,A9,92,53,6D,9A,B1,60,8A,80,13,B8,1D,08,1B,C4,F4,5E,7E,3B,38,05,53,59,39,4C,DC,6F,12,F1,48,D3,AE,AF,E5,F5,17,8E,60,CD,0E,FB,A5,11,14,EE,A7,68,A5,4C,72,B3,FB,72,34,89,98,6B,70,8F,21,D7,09,D4,92,3A,08,31,19,CC,47,C7,7E,2D,91,5F,15,89,1F,9F,93,A1,96,D9,34,2D,AC,1A,8B,97,51,F4,C9,1A,34,B1,7B,D3,5E,13,77,FF,A8,65,80,27,B2,0A,69,E1,AD,7B,8E,88,D9,CE,92,E9,79,81,A4,F3,42,61,C0,8B,58,9A,EB,15,7B,49,D6,41,A8,BC,82,AA,3C,54,BB,90,AD,0D,8D,59,95,DB,E0,76,D1,51,58,5C,60,B7,EC,0B,8D,BD,9C,23,21,F6,9F,52,D0,0C,7E,1F,0B,64,67,90,AA,BA,7B,AA,26,11,0C,2B,C6,D4,CF,5A,5E,EE,54,CD,D9,08,CF,C4,D8,5D,BD,1A,17,FC,27,F9,29,DE,10,97,76,42,62,61,92,40,FF,3E,D8,89,4E,74,A5,53,61,A4,47,92,CB,76,DF,AF,AD,54,61,5E,DA,1B,24,B2,2C,59,17,CE,2A,E4,13,9A,FA,DA,D5,C4,5A,05,71,F9,F3,85,84,DD,46,52,E5,E7,2A,56,54,7D,D4,A4,21,12,2D,52,D5,DA,A9,D9,D4,1A,BB,49,AB,B6,3B,1A,58,A8,F1,1C,BA,38,37,9E,3A,42,A2,10,54,8D,32,C8,DD,27,71,F0,24,00,73,FD,51,90,D3,84,E7,9D,25,DB,93,DB,23,64,A0,FA,F3,DC,27,53,7E,A2,3C,AC,69,03,DF,B2,D9,7E,20,64,FD,A0,BB,F4,42,6C,5E,1D,1F,D1,75,7A,14,91,7A,D8,DB,66,F3,68,0A,44,C8,8A,13,FD,92,9D,C8,50,8D,21,6B,9A,76,19,99,17,60,EF,88,18,2E,F0,15,FC,05,1E,BD,91,E0,50,AD,EF,65,04,6F,39,BE,CF,46,B5,2C,72,F0,95,CF,C5,A3,54,8E,07,0C,93,6A,3C,0F,C7,38,19,9D,1B,46,83,F0,5D,6D,10,29,9B,0D,5D,5B,7D,E6,B1,92,BE,1B,AD,D7,76,A8,95,EB,E8,17,CB,01,B1,00,56,5D,CD,3A,F1,30,2B,63,D1,79,DA,AB,D0,66,32,5B,B0,C1,00,1A,2A,17,DD,F0,52,90,86,56,FB,48,18,20,13,CA,DD,1B,52,FF,39,70,34,EB,30,46,30,E7,42,E4,61,5F,62,D4,C3,EA,3D,7D,9A,F4,4A,9C,96,D7,44,EB,B7,05,54,A1,8D,BC,82,56,AD,10,6A,BF,97,1A,EA,7C,83,3F,78,2E,D6,16,8B,E8,00,3B,C5,17,F4,8C,D0,BF,F7,2A,19,88,67,A7,66,AF,09,80,18,AE,8A,D0,64,99,1C,2D,52,ED,0E,89,EE,8F,85,DD,17,DE,AE,8B,4B,F9,14,E1,5B,1A,D7,9A,0B,4C,0A,4F,88,46,B4,C1,FD,75,58,25,6E,F2,6F,1F,15,AC,E9,A7,04,35,00,69,32,8A,32,5A,C1,62,23,C9,CE,16,31,FD,A7,7B,6C,A6,DD,5D,39,42,49,6F,EE,E6,51,69,92,93,DB,26,A8,0D,FA,AF,85,A7,8E,8A,33,72,E7,46,3F,E8,C8,D8,2C,06,81,BE,75,E1,EC,E1,AF,90,17,A5,55,C9,A0,31,C5,33,EA,1D,8F,14,CF,ED,45,F7,98,5B,7F,8E,1A,2A,13,35,5D,F7,43,85,32,2D,30,F8,4D,2B,AD,A9,EB,26,5D,3B,D1,FF,57,16,94,F4,08,C3,3C,5C,CC,A7,21,A2,21,7B,70,32,FA,AE,A4,F6,EB,F8,F0,D1,AE,12,DC,17,43,83,F0,CD,DC,C6,3C,DA,51,D5,9C,60,8C,7D,28,7F,BF,8B,BB,72,99,B2,15,37,09,FC,72,F6,F1,7E,92,A2,12,D4,A0,6A,0B,20,CF,06,7A,9D,E4,49,2C,31,E2,84,90,6C,F7,AC,9E,F6,F7,96,28,AB,2A,41,16,6A,1E,11,07,3E,61,4B,5C,4A,6C,92,3F,E7,0B,C2,0C,3D,AA,03,BF,4B,F9,45,5B,99,81,A6,59,C6,CD,FB,A1,E8,D0,F4,F0,99,F8,B7,50,B1,BD,D0,7C,F5,D9,2F,E7,12,49,C0,EE,2C,A5,DA,1A,8C,B8,D0,D8,2C,DB,2E,98,35,3A,3E,74,C3,E2,16,11,AE,13,60,F9,AE,BD,5C,50,1B,8E,4E,DF,9D,86,8E,78,3A,2C,A9,62,4C,8E,46,3D,48,A7,F7,E4,FB,85,7B,97,14,32,97,6A,C1,76,0F,CA,17,AC,D6,71,A4,9B,85,46,7D,FF,91,EE,E3,35,3B,9E,66,38,7E,BD,ED,2A,07,E5,B5,D2,BB,A3,29,F2,E0,2B,26,6B,CA,75,F6,DF,6D,6E,98,64,A5,F5,7D,04,E5,D0,BB,DD,F4,01,E2,3C,25,AC,FE,EC,F9,7A,39,E3,E1,11,A3,1A,98,BC,FE,8F,2E,BC,EC,A1,32,C4,57,BC,41,CB,BE,8D,B1,A9,2E,F5,62,04,A5,A3,6F,0D,34,A4,D8,AB,25,B7,C2,4A,8A,B4,93,02,36,D2,E8,77,84,6C,7D,47,07,2F,AD,EF,04,77,43,DA,F1,F1,20,E0,2C,17,A1,E8,BE,9E,8F,90,51,2D,4B,44,29,94,D4,8B,D5,4A,9A,C8,5A,08,DD,5F,2C,A5,DC,42,BF,A7,46,10,A3,DE,4C,25,AD,2D,13,A4,07,BD,D2,05,59,2E,62,96,8E,16,04,4C,53,9C,88,35,51,9A,C1,BC,55,35,24,EF,2C,E1,49,35,F8,D2,B3,C4,03,F5,F2,3C,34,08,9C,D4,0D,D2,F0,28,C8,38,C1,E9,AF,0A,6E,E9,AF,54,4B,79,1D,8C,49,BA,B2,9B,76,40,E9,F1,2C,F9,85,1A,33,D6,84,04,88,3C,A2,78,88,62,1F,67,6A,4B,5F,54,AD,FF,11,23,3A,60,54,29,34,E2,A3,74,B8,4E,F4,C7,2A,3C,DB,78,5E,81,3F,96,5C,3B,18,CA,DA,62,06,CD,F5,A6,A1,BD,75,C1,08,A4,4B,A7,E3,4E,A7,4C,AA,73,69,41,3A,27,B6,59,F0,F4,4E,EF,B7,80,BC,13,B6,E3,97,E7,34,CF,99,CD,56,0C,FF,16,92,B8,EB,4B,10,7C,43,68,3D,F0,8A,40,CA,20,6E,63,2F,05,38,88,23,F7,33,57,AB,07,16,1F,16,ED,BA,FD,02,04,0B,A1,11,15,86,0B,AD,4D,90,9C,DE,5E,1B,1F,C4,CF,73,72,D5,A4,8B,79,06,9D,87,EB,D4,C9,07,31,89,40,23,C3,14,BC,34,1E,BA,FF,C9,5A,87,AE,2B,04,8A,36,27,07,64,77,88,D3,74,DD,9C,29,89,8F,2A,15,1E,18,A3,E2,F6,FB,F0,89,18,D2,ED,6F,C5,DB,1E,E2,0D,73,26,56,0F,D4,1A,F7,BD,A2,6A,B1,46,78,6C,FE,FF,C8,C6,C7,A9,5A,EE,27,D6,E6,59,58,AB,D2,D3,BF,4D,21,6B,EB,00,23,E4,94,E4,3D,EA,5D,A5,79,DF,AE,75,AE,7D,01,13,0D,14,18,DD,FD,AC,57,4B,7C,07,05,CD,3F,35,84,87,5A,B3,7B,4B,94,0D,09,F7,01,07,1F,B3,EF,AD,EA,04,91,C1,A0,8F,CF,09,79,C6,FF,1F,95,C7,F5,48,1D,84,08,6A,72,B7,D8,FF,D0,82,2A,18,02,25,83,55,EB,97,1B,23,7B,12,7A,8D,6F,7A,82,FC,49,3F,EA,93,BE,64,BD,B4,B9,35,6C,8E,7F,DC,2A,2C,B2,28,C1,A3,8B,56,B9,C7,E7,72,A9,52,1A,F7,AA,36,CA,43,B1,6E,D2,BD,FD,AE,83,73,54,8E,3A,4F,2F,86,11,8E,73,1C,8F,8A,1D,72,DD,1C,3E,50,E2,5B,35,09,09,E2,0F,D0,CC,1C,8D,76,BE,94,C0,9A,A3,A2,49,2A,D7,AC,9A,80,93,89,4F,B8,17,44,74,75,9E,69,AE,8E,54,E4,E6,4B,2C,6A,F4,FF,48,C3,29,DF,A9,27,AC,71,64,26,09,6B,AC,28,4A,D0,D5,D0,6E,F1,3E,C1,60,7B,74,EC,33,BC,E8,FA,5F,35,A1,2B,48,E7,EC,C8,DE,D9,B5,10,89,70,71,37,59,9C,DE,69,A4,56,1B,CA,27,8E,CF,A1,50,A6,4D,54,94,66,DC,0B,23,79,4B,20,48,34,B8,2F,72,66,62,27,C0,5D,88,9E,00,72,CF,35,FF,EF,16,1F,BB,F5,26,5E,00,80,2B,AE,51,BB,5A,CA,38,9E,37,F1,84,22,1B,90,85,A7,D9,96,1B,67,EB,9E,9C,3C,EC,CF,B6,D4,F5,73,E3,FD,40,FB,77,6D,EE,16,09,A8,A7,0E,03,8F,77,27,C5,35,81,29,AC,38,74,A0,2E,FA,A5,0D,8F,85,46,9F,04,32,72,18,50,C6,6A,FC,39,BA,6C,08,B5,27,D5,10,54,38,41,F5,8C,3F,F3,B0,F9,46,C0,D5,35,D8,99,AF,E4,6C,81,F6,7C,12,67,34,F7,52,ED,61,C7,C7,2F,F8,CF,B3,47,0D,E2,D3,21,7F,FF,40,7C,58,B6,F8,B5,F9,D3,D1,4D,A8,AF,AC,6C,F3,74,D4,07,C6,03,8B,2A,95,53,25,A3,A3,2B,3C,A9,C1,76,C2,0B,8B,68,71,8F,04,63,52,1E,A9,BD,07,09,D9,6D,13,B8,A4,08,9A,98,99,55,60,59,DA,FF,07,5B,77,B5,23,54,54,B7,0F,5A,6A,3A,05,BE,97,1B,96,E1,DD,01,CC,35,EF,AC,1A,B4,92,4D,9D,CF,3D,FD,24,BF,E6,4A,63,72,DC,51,9B,28,2B,FC,48,A8,71,4E,14,05,82,FB,8E,C0,42,36,D9,F3,3C,27,18,A4,AA,3A,9D,FB,50,67,0F,52,0C,4F,AB,DB,19,DA,B6,8C,DD,E6,F3,D7,F5,64,68,9A,3E,1D,70,45,B4,F2,0D,10,04,15,E4,E6,35,CD,7E,07,7D,B0,81,67,EE,74,51,F8,3F,8B,7F,FA,9E,3C,BE,79,2C,C0,21,3E,09,D3,B1,20,E3,B0,ED,98,A8,E7,30,BF,36,DA,FE,9C,66,2A,86,B5,9E,14,09,A6,AD,67,FC,77,41,81,A6,C2,A3,57,99,BC,EA,BE,38,18,A8,7B,A8,C0,EF,D6,B8,6D,68,A7,47,CC,EB,D8,C9,2F,06,10,1B,2A,0E,1F,8A,B3,DE,3D,F6,F4,80,35,1D,E6,6F,06,97,E4,DE,9D,89,3F,62,8F,FD,AA,B0,63,F1,5F,DD,0F,A3,FC,19,51,8F,B1,33,BF,FE,B5,C6,6F,9D,E6,0F,7F,FC,62,51,AB,B6,7E,F5,04,3C,7B,4A,10,A7,63,EE,D2,D5,D9,68,7A,FE,3C,FC,63,8E,C1,91,44,38,CC,19,0F,05,52,15,AB,CB,09,1D,FE,12,55,CF,8D,AE,D3,D7,9B,DE,A7,9D,94,AF,E9,21,F4,38,D5,36,61,08,16,DA,A3,8E,35,9D,19,0D,1D,A6,5B,6E,5E,4A,F1,BD,95,22,C9,9B,C5,01,DB,08,E9,9E,8E,07,0F,5F,60,1E,AE,75,DA,7F,08,03,44,94,06,25,EB,0E,D8,93,E5,E7,9E,BF,1A,71,62,F8,B8,86,68,A1,4E,51,F1,AC,67,3D,2C,51,BC,7C,A5,49,13,6D,F1,27,93,2D,89,13,91,E5,20,AC,68,9C,67,4F,D9,B1,C4,F9,4B,AD,00,EE,7B,FF,4B,D1,FF,10,38,05,E9,15,63,63,F7,02,87,24,06,21,F7,FF,97,21,0C,8E,57,B5,BD,38,33,4F,8B,67,C3,83,7F,16,B8,DC,95,DB,CD,50,EA,34,8B,89,16,B1,21,2B,1A,6D,95,DE,C1,2E,1B,48,94,BB,EE,3D,64,D7,95,1D,71,8F,0C,E2,0D,7F,36,D6,89,D1,4D,FC,EC,71,60,CE,53,D1,54,5C,4F,C3,58,2A,F1,36,32,10,30,25,6A,F6,90,4C,0E,99,A5,6B,59,F3,67,6C,DB,DD,8C,7D,01,BE,44,90,00,C2,B7,6A,FB,A6,02,C2,86,67,6E,82,1C,D6,13,FF,D1,E5,44,EC,14,AA,CD,54,F5,3F,56,A5,19,6D,69,37,24,FE,88,3F,A4,BD,16,D9,0E,17,28,EF,10,6A,28,0A,7F,39,16,2C,42,19,E2,EB,BF,F1,A5,34,EA,5E,9D,AA,EA,D9,2A,9C,DB,BF,D4,67,1C,E4,FF,2E,D3,AA,1A,9E,3A,8A,E0,CC,21,58,7B,61,A8,84,9C,61,A5,B8,86,7A,5E,AF,1D,BD,8D,5D,C5,F1,E1,61,99,DE,BB,C0,7D,5F,EA,6B,98,E2,C8,E2,11,8C,0B,A0,2C,34,E8,7E,BA,25,A3,33,6B,14,F2,0A,AF,9C,CD,80,DF,0D,38,CB,64,3D,1E,47,E2,9B,84,83,AE,A5,EC,30,30,49,CB,59,CC,53,05,1E,19,D8,D9,21,4E,E8,43,B4,01,D0,E2,81,80,CD,18,DE,3D,0E,50,82,97,8C,27,4C,3D,81,B5,98,EB,DC,42,E2,6F,A3,87,BD,49,2C,DB,ED,AB,60,7F,B3,D9,09,88,DA,16,DA,DD,E5,B0,4E,1D,4D,48,C0,CA,38,73,B8,82,D5,B6,01,7C,85,3C,2E,0A,FD,E6,A3,6A,0C,36,74,C6,21,65,2A,CA,AB,BC,6B,42,FA,2A,8A,81,80,45,30,DD,B1,14,1B,D9,E5,59,92,59,4B,F6,37,B8,4E,4E,DE,4E,73,E3,8D,24,65,47,28,F8,FC,96,3F,8E,47,AF,22,F7,07,DB,FD,32,20,AC,6D,36,37,3F,A8,57,DC,4B,70,BC,B8,BA,C2,26,37,6F,9D,C2,BD,05,6B,9B,6B,49,30,4D,DB,AA,EC,50,59,76,92,D2,FC,52,B4,F7,A2,37,42,8D,03,53,09,06,B8,A9,17,E7,CB,9D,88,7C,7D,E8,25,E8,DF,7C,7C,0E,36,BD,AD,D3,B9,66,A0,35,78,B1,CF,90,AE,4A,BD,40,CA,CA,F2,00,F8,A1,30,DD,B2,36,AD,C9,42,11,61,73,FF,CC,9A,E8,E0,20,8C,77,32,48,FE,7D,D0,F0,69,4C,B1,F1,0A,A7,0E,8E,7A,27,75,F7,08,B0,41,79,38,2D,0C,07,E7,38,A5,D6,AD,8D,8D,B0,84,B3,37,BC,D4,E3,E8,25,7E,AB,18,38,7F,88,06,37,42,0F,3F,6E,A8,71,9A,20,3E,AD,91,EA,DA,F7,2F,1C,90,02,F8,92,E5,3E,6E,5A,FF,B6,51,F2,2C,8F,04,A3,8C,49,3C,B2,74,6C,CB,E0,69,60,81,9C,74,CE,CD,C1,BA,CF,63,E1,EA,49,87,7A,18,1A,74,62,4C,C3,87,F9,98,8B,0F,17,5F,73,13,B5,58,1F,90,FB,78,EF,4D,24,43,47,B1,9F,3C,A0,D3,3D,E9,78,02,1A,35,83,92,98,55,CC,78,01,BC,24,59,67,86,EE,5A,5F,2F,A1,4C,9B,7A,79,4D,D0,EE,BD,76,E3,65,2C,A2,B4,16,C0,67,D8,A4,3A,2E,44,75,08,37,31,0F,8D,49,AF,08,C6,D3,7F,8C,00,B6,90,A3,BD,BB,52,19,52,A3,31,E7,A9,62,CC,CF,E7,31,D2,CD,6B,B8,F2,E4,3B,A8,35,8C,D0,61,54,56,49,1B,DF,4C,E1,88,1B,A3,DF,26,BD,2E,5C,C0,9F,D5,B5,3D,2E,23,10,C1,8B,0D,DF,C8,C3,BA,C3,D7,2D,A3,2B,F4,D5,16,43,BA,05,0F,D7,33,0D,CB,8B,85,86,6A,9A,DB,DE,C1,68,55,23,CA,96,FC,B7,9D,B7,A2,9D,9F,3C,14,F0,02,83,A3,22,0E,D8,AF,9D,27,D3,6E,AF,55,13,A6,E9,BF,CC,FD,74,13,3C,EA,DB,6A,17,0E,74,1F,FF,15,EC,29,94,30,7D,A5,28,6C,15,4E,68,BA,C7,2E,35,F7,D2,DD,3F,07,09,0A,BC,5C,9D,5B,8C,63,20,3B,41,74,70,95,CD,7C,CD,EC,0A,75,8C,22,D8,A8,6F,1B,D2,EB,7E,44,0B,CC,23,6C,F5,80,DC,19,0F,20,BB,17,1A,89,97,75,DD,B1,DA,2B,95,AB,4D,30,36,91,18,85,61,D8,A1,66,19,D0,5A,84,02,EE,2B,7A,73,BA,CD,C1,0B,B2,D7,E2,D7,02,53,48,85,A0,52,41,C6,28,0F,7B,81,19,13,44,B1,5E,33,E3,78,C9,EF,30,F9,79,7E,2E,3A,D1,39,D3,15,A2,5E,EC,0B,D1,96,10,4B,40,38,5C,31,C5,24,C2,E7,E9,58,98,46,A6,D9,F5,5B,61,0D,6F,4A,73,E6,A5,C3,DD,BC,C8,3D,1E,48,D8,A4,19,66,DB,FC,2F,F0,17,2E,20,90,38,15,57,03,84,6B,73,16,B9,E2,E1,08,46,65,AB,BA,3D,1F,7C,2E,20,47,61,41,9F,E8,45,B0,83,6D,19,8D,D8,1E,EA,E5,95,4B,B1,CB,20,C2,17,5E,84,A6,E6,FB,F8,33,69,C9,95,33,CD,53,D4,4F,97,4D,CC,DA,41,A8,47,C4,55,07,69,59,77,60,BC,C4,CD,D1,74,8A,A8,85,37,BD,81,6D,9D,42,0A,3B,18,3B,5B,0C,4F,52,0E,9C,66,D3,39,4B,07,AD,4B,CE,A4,9F,E1,D6,48,05,19,E8,56,B0,9F,95,60,F9,76,CA,BA,5F,B1,8D,F3,C8,62,25,31,51,87,5E,57,F3,39,36,32,5A,E9,45,17,5D,CB,E2,6B,C6,04,99,42,8D,70,16,4B,6C,58,AD,0F,AF,48,3B,AE,F7,7D,9A,CD,1A,FF,F2,F9,76,32,56,B8,62,FB,6E,6A,F8,9D,1B,5B,FC,CE,16,BC,D5,4D,84,38,A2,AB,2C,74,05,C8,C7,67,AC,0F,8C,54,D7,79,72,43,5F,E0,97,E2,93,A7,B7,C8,06,0B,50,00,9C,C7,13,51,9A,72,8E,66,FF,0D,45,AC,5D,B6,1F,C6,4A,63,B8,EB,FD,0A,B0,D8,26,4A,5A,C7,93,22,4C,2C,23,AA,36,25,72,14,F1,75,0C,A6,B9,9D,56,B6,58,68,26,BD,93,5F,01,B2,3B,47,48,D8,CC,27,95,09,24,28,15,5D,5B,E0,95,7C,66,60,E0,C1,7A,AA,DF,08,C1,7A,93,D3,2D,54,9E,B0,3D,E1,60,13,63,B5,44,78,E6,60,30,EE,13,FB,9F,FA,16,89,6D,75,F9,D8,C2,D4,4D,43,2B,5E,55,21,62,41,4C,AF,1E,65,6B,16,B8,F3,C2,B4,87,84,52,B6,A8,27,6E,64,5F,D0,C5,FA,97,B5,F0,36,D2,20,BE,E0,26,3A,74,0C,6D,30,10,58,7E,C1,D1,88,8B,67,E2,FC,C3,CB,E8,BF,18,DB,52,3B,74,7F,E8,85,B1,8E,58,16,43,00,BD,04,83,32,4D,CC,A5,13,AF,A0,4E,B2,74,EE,21,9F,0E,46,1C,F0,A8,7C,12,A1,B7,81,81,E7,0C,9E,3D,F7,9F,EE,4E,59,A0,46,0B,95,69,B2,AB,93,C6,42,17,F7,8A,BA,E3,B9,C5,E0,0E,8F,A4,F3,30,08,AE,EC,5A,78,64,F9,76,65,45,41,29,29,FA,49,C8,DE,8B,86,DB,7C,27,BE,9D,A0,28,4D,62,65,3F,7A,6A,C3,76,55,8A,5B,A8,1B,1E,94,39,A7,B7,6E,BF,78,2D,4E,3E,0B,CF,17,85,4E,A8,63,4E,E5,D5,5E,69,A6,A0,7C,91,72,B0,2E,4D,3C,D2,3D,3B,3C,6A,79,1A,F3,BC,F1,A2,B1,BA,00,3A,B3,45,88,10,03,17,4A,6E,15,06,22,E6,1D,68,BC,56,4B,70,3E,43,0B,48,0E,E0,11,C2,8F,50,AE,8F,03,D3,E5,EB,76,9F,B6,4A,35,05,34,0B,62,09,E2,26,5A,1C,2B,76,21,8E,E6,B6,4F,5D,D3,5B,46,3E,89,4A,B4,27,42,24,9D,44,2D,01,02,AF,F1,81,0D,26,5B,A3,41,58,4E,0C,73,84,C5,12,24,15,5D,CE,9B,9A,C2,0B,1F,3B,3E,2A,3E,BF,D1,5E,1C,AD,77,C2,65,5B,B7,4D,8B,92,0F,0D,72,64,45,8D,0B,83,3F,EA,E3,15,9E,0D,85,8E,19,3A,99,5E,35,C4,8B,76,47,E3,0D,D6,22,92,28,42,51,B5,70,87,F1,F0,BF,5E,51,90,D1,9C,66,A4,8C,14,9A,AC,08,30,53,18,25,CB,C9,99,47,E7,C1,E3,9B,6F,73,43,01,32,66,ED,75,CD,C3,ED,69,B5,41,A5,0F,CF,6C,D0,F0,CD,2B,FD,3D,63,D5,25,6D,E8,09,9E,96,49,30,D2,BA,34,1E,21,9A,E2,E6,DB,3B,09,4D,AA,AF,BD,F0,9A,38,DE,B0,CB,A3,3B,F2,10,E4,A8,A7,8E,1C,C1,20,CF,C5,73,73,73,4D,CF,40,61,7C,82,4B,99,D9,7A,2F,8D,BB,A8,CD,F4,A3,EA,2D,57,82,8F,8A,0F,B2,B6,25,8A,78,69,F9,43,15,0D,CE,6D,7E,DE,9D,A7,DB,02,9E,64,3A,09,13,B7,78,5F,59,FC,1A,9A,9E,5F,B1,5F,55,9E,A7,79,1B,C8,F8,57,28,41,11,B4,95,ED,78,39,EC,F3,32,0C,79,73,17,69,E3,9E,83,3B,68,B8,2F,C5,E1,FD,FC,4A,AB,3F,4C,1D,19,60,2B,83,94,DA,F7,FC,3C,82,39,E5,7F,AE,CD,85,FF,06,5A,DE,08,41,F2,8B,AB,4A,CB,37,EC,A3,4F,80,91,2F,EC,91,1B,E4,1B,9A,78,ED,DA,41,C3,26,03,F9,C8,7C,6D,7F,61,78,6C,EF,A7,96,0F,67,C8,02,9D,96,8F,EF,75,6B,BF,C0,89,27,A0,3E,DE,2F,A1,18,ED,E6,3B,F5,F4,3D,EE,8A,6F,F5,E3,EB,6D,F9,5C,FC,56,23,1C,76,D1,6C,BD,A6,26,3C,41,48,A3,F1,64,68,20,88,EE,1E,09,0C,90,E2,36,D4,0C,FA,86,CB,D1,7E,C6,73,98,C0,16,13,A2,AE,66,93,90,B2,32,D4,D0,7C,EE,15,FF,79,D3,E7,96,B3,1D,FF,CC,91,6A,E2,84,11,8E,0F,FB,87,89,DC,40,71,95,49,32,59,26,DA,97,DE,0B,CA,B0,A6,88,F3,33,A2,14,CD,2F,F7,13,AC,04,86,53,36,90,DD,5A,1A,A5,61,52,AA,FE,87,9D,56,F6,34,9A,9F,DD,A1,0C,BD,56,24,85,9E,0F,9B,C7,A9,21,B7,AE,CE,1E,B4,A6,C1,94,74,7C,E8,FC,A4,3D,C0,F5,1A,0B,FF,EC,55,68,0C,12,F5,2B,7C,FB,A0,F4,5B,EA,A6,25,D0,1B,61,85,79,43,F2,F3,86,67,11,9F,E4,3E,80,CB,F6,E8,10,50,B9,CE,04,F0,1B,EB,5F,E5,17,EF,48,88,51,B6,33,B0,34,8B,87,75,08,7E,D1,5E,FC,91,78,1B,65,0E,9B,50,8C,D7,6D,88,72,69,E0,7B,B3,8D,44,EA,2C,C1,35,32,19,7A,91,40,66,8F,80,06,3A,46,B9,DA,E4,A1,68,65,AB,10,A2,32,0A,23,ED,A7,F2,9E,7E,40,C5,D2,01,B4,D3,EB,85,43,F0,F9,E0,3A,32,A1,D9,C8,BA,E4,08,C8,E0,D6,9C,20,F8,D5,B8,F0,C0,24,B5,65,74,36,5E,DA,41,E0,21,FB,7B,5D,7C,81,C1,8D,4C,06,14,2F,CE,C7,BF,5D,5B,66,F8,93,B5,3B,71,69,32,F9,E0,AC,0B,3B,58,2A,CB,59,7D,0B,16,94,7D,FF,78,AA,D3,C8,B6,2F,7A,4B,BC,4F,68,8E,EE,C8,83,BE,63,27,51,DF,F0,B9,91,EF,16,54,CC,79,F1,0C,0C,8B,90,60,A4,40,D3,CF,FC,4A,19,AC,11,90,81,93,9D,B0,D2,05,21,E7,96,C1,99,14,4D,49,CC,E3,66,C0,C3,00,08,1B,2B,6D,F5,11,08,47,F2,2F,49,F4,0E,3E,E8,57,EB,F0,36,AF,8C,3D,1E,55,30,6C,FA,DE,7C,B4,6A,82,23,F9,7E,42,79,87,6D,99,67,4F,51,C2,9F,28,AB,C2,29,9C,15,45,53,F1,D3,D1,8B,E3,6D,B1,2B,E0,61,D4,85,09,56,7F,2A,78,A2,96,01,E8,98,5E,2B,6C,80,B1,2F,53,DF,C9,B2,E2,3F,5E,D0,7D,FE,96,9E,52,B2,EE,56,83,AD,50,4E,64,15,3D,CA,1E,AD,49,42,85,CD,1B,8A,B5,45,6C,BA,1A,FA,46,8A,27,51,32,45,ED,70,8F,2D,1A,AA,CA,B5,EB,D4,8F,9B,75,5D,42,EF,E1,5B,CA,85,E5,08,87,C5,30,E4,75,B2,96,D1,BD,A4,E1,26,45,D0,7C,27,F0,B7,02,30,B2,59,3B,16,97,0E,AF,D0,30,12,2E,72,DD,69,A6,2C,8D,D7,6F,05,89,F0,AE,5F,B0,D7,C8,F4,67,15,F9,B3,8C,B2,C2,30,A9,8F,DE,90,00,25,A5,69,E4,FD,E9,95,76,C6,72,5A,85,8F,69,2D,CE,39,50,9E,93,53,5B,49,12,53,BE,05,D4,85,FC,F5,8E,09,09,78,46,26,33,2A,5B,20,54,E7,C6,24,BC,44,7F,74,97,9D,01,8B,62,59,82,BD,03,68,21,C8,47,BE,8E,27,1D,50,C8,49,B4,F5,96,74,E9,24,30,CF,90,07,17,46,F5,83,C3,A1,F6,EE,B0,6D,AA,BD,14,42,0D,56,26,21,07,0C,82,F0,26,E7,4F,8D,3B,C2,FE,B6,B0,D3,50,54,FD,DB,13,BC,53,72,C0,8A,5E,51,5F,84,2C,5A,0E,C9,25,F8,A1,06,B4,ED,3C,93,DC,5A,8E,30,ED,F4,70,EE,C4,88,FF,FE,31,68,E3,BB,26,AC,EC,91,75,E2,B6,3E,55,A0,03,0E,3A,AC,C8,1C,04,40,E8,66,9A,DC,3C,92,AC,5D,46,40,15,7D,47,04,70,7F,BF,96,05,9C,87,F4,95,80,53,D7,0D,DC,4A,64,77,62,B4,D4,CD,76,FC,F7,18,7B,91,6B,40,97,0E,DF,7B,07,3F,E3,53,C2,3C,A2,0A,7E,1D,2B,F9,A0,3A,4F,66,A1,39,AD,19,BC,84,2E,2D,C0,C9,7D,79,5B,67,06,74,EF,55,28,8E,5C,D7,88,33,74,9C,5C,04,D5,50,08,69,FA,76,D3,3F,51,6C,DF,CE,CF,24,96,DF,F5,04,50,73,9D,24,FE,28,02,15,1C,A5,5B,1F,EB,10,01,55,EC,5E,69,DB,1A,F1,74,3B,08,FA,3A,00,E3,6F,2F,C9,A0,F9,96,C6,BC,81,EC,54,02,AE,16,28,E4,39,F1,E1,D2,42,9C,9F,E8,10,1C,40,35,A8,B3,58,6C,C8,1F,3F,46,44,12,4A,E7,97,4F,A7,CF,86,70,22,CF,6B,FF,3C,E4,C3,37,47,CB,52,6F,03,CE,01,95,4F,6E,AA,F0,F4,8F,DF,CB,95,98,45,FC,5B,5F,A6,8F,1B,89,69,AB,7C,75,ED,E6,23,04,C5,B7,0C,B3,2A,EE,9C,58,DB,38,EC,86,25,26,D1,46,D8,E8,3E,16,7A,92,14,E8,7A,2A,57,94,94,26,68,B3,61,EC,B1,2F,7E,80,5F,80,97,B3,20,26,D7,C4,6B,10,EE,46,93,28,7C,63,BA,8F,91,5A,7D,7E,F5,6A,18,75,DB,6B,64,1F,B0,F4,1D,15,FC,21,5B,4A,0F,63,53,EE,D3,12,4A,8A,88,30,42,1B,4A,B1,F6,C3,CA,07,19,83,98,10,76,B6,50,2D,DF,0A,BF,59,3A,93,9F,9A,CE,D0,EB,91,8C,C6,E3,8E,F0,78,60,C1,9B,1F,8E,A3,71,FA,24,37,34,9D,26,8D,9E,E8,AF,7C,ED,63,97,A0,1E,A8,3C,8A,FF,F1,E2,76,26,6D,24,52,3C,40,C0,44,22,83,BB,F1,7E,DF,95,73,12,EB,4B,5D,00,61,32,20,61,46,44,6B,E8,0A,D4,70,72,AD,58,9C,CE,09,65,EE,B4,13,70,52,B9,EA,AE,A6,80,9D,23,22,B3,CC,AA,27,7F,9A,A8,8E,89,7B,CA,FD,C7,10,30,36,31,20,B9,1D,C7,C7,79,DD,B3,1F,C5,6B,07,EA,01,97,EE,D4,C2,D1,25,12,D5,66,7B,79,B7,76,4B,4E,90,C5,9B,A8,4F,F8,3C,1C,8C,92,D6,51,5C,04,2E,1E,D0,57,75,DE,45,1F,01,B9,AC,33,C8,74,B3,BC,6E,A4,6A,12,28,AC,1D,D5,AF,F5,BA,D7,72,94,A0,A7,A8,7F,4B,66,1B,D9,23,4C,4B,EF,1D,34,8A,27,7C,98,AB,42,27,D1,97,C9,39,C3,9B,E5,7E,BA,A9,47,7F,F0,85,3F,14,5D,A9,98,85,BA,B9,0D,65,21,F6,B9,3E,96,6B,77,6F,5F,E2,A9,28,84,AB,51,2C,8A,33,08,68,BE,A3,81,53,5A,A6,1F,B0,9C,BF,7C,26,7E,B9,34,8C,5C,B8,DC,B9,B4,C1,08,B8,EC,77,DB,7C,93,14,19,38,82,7E,56,5F,2C,E1,FE,B7,D5,23,F5,7A,BA,D5,49,3E,7F,F7,80,DF,B5,70,69,E2,33,6C,30,BD,0F,9A,55,A1,5C,4B,BB,3B,88,01,95,A4,57,EF,EF,00,46,F6,A0,A5,EB,F6,0A,C7,FE,45,33,66,EA,9B,D1,1F,CE,7D,DF,79,07,11,A1,FA,45,17,0D,61,25,1C,DD,E5,B7,67,9D,FC,D1,AD,19,A3,D5,C4,B0,85,2D,71,EE,03,60,B7,9B,AF,6D,CF,A4,07,1B,77,D2,7C,88,46,9B,E2,69,F8,FD,AC,EA,E3,E6,C9,D9,36,D0,53,BC,B2,61,AD,15,49,8D,0A,A6,20,20,FC,AE,D3,E5,73,B3,B0,DC,86,E2,E3,B9,AE,CD,7B,B0,8B,6B,48,E1,BC,43,6B,A5,1A,E9,46,9E,3F,E5,E2,33,BD,11,BD,8C,8B,25,59,ED,B0,EB,98,04,15,B9,6A,CB,1E,E8,F8,3B,F3,0E,D1,0B,55,92,85,1F,CE,54,9B,38,BC,EB,77,77,E7,CE,68,76,91,41,15,2C,83,E0,6E,D1,23,EC,2F,BA,85,CB,CC,61,36,CF,39,10,C4,D6,4F,64,E3,BB,94,74,9A,79,C8,9D,B8,FE,51,F7,73,10,03,3D,C2,18,F2,CC,C0,B8,FB,10,BA,1A,6E,66,2B,70,70,03,B8,C1,1E,D9,A2,A7,D2,7B,21,C0,46,48,F0,3E,E0,5E,3E,BF,28,F0,AE,9F,48,21,28,70,0E,6D,43,E1,45,40,AF,57,D3,6D,AC,00,DE,D2,D2,BB,DD,D8,79,55,65,C5,54,D2,F9,C7,67,9E,B2,F7,76,28,C5,A8,A3,30,37,77,A0,39,0C,A3,D9,C0,C6,8A,29,81,2D,D5,6D,90,E0,89,19,C8,A3,F2,BD,A9,EE,ED,7C,FB,7B,40,21,78,49,86,71,45,4C,E6,97,14,61,D4,72,D8,52,FE,CF,ED,51,99,5A,90,7E,FC,99,97,E9,D3,63,C7,2B,BE,01,19,B5,06,D3,75,A9,E8,60,95,7D,DA,48,1C,C2,F6,09,13,4E,36,03,B9,27,D3,1C,07,F1,E6,05,A9,E5,6E,92,AC,CF,34,62,D3,A7,C7,F5,36,14,F5,A4,9E,1C,4F,8F,87,79,1B,A8,36,BE,FE,4D,CA,F7,C5,FB,5E,40,51,52,39,02,11,5F,E5,D6,96,25,F5,3B,B7,35,BA,11,D5,DF,85,5A,ED,15,2A,7F,AB,30,FF,59,05,0B,35,16,B5,1D,77,1B,01,87,95,E2,16,87,A7,BF,DE,56,70,8C,DB,30,A6,73,49,0F,27,D9,9E,E5,B7,29,06,B8,9C,46,FB,30,5C,92,76,76,BB,85,8B,57,28,19,A3,4E,26,67,C7,52,38,CD,A4,97,99,4C,3A,A6,31,89,1F,5D,02,7D,C7,12,FB,9B,EE,42,14,15,D6,30,A3,34,D2,58,00,D0,14,ED,32,B8,E9,03,CA,68,6D,A4,6B,F1,12,20,C0,13,9B,CA,B1,11,BB,51,9F,3E,B4,2B,E6,48,79,A7,58,66,CF,A7,37,14,32,40,17,40,FD,8B,C8,4B,60,AB,78,24,C6,FE,49,0F,EB,30,1A,C9,56,A7,B8,79,AE,89,6F,9E,D0,A4,FC,F0,D9,B9,6D,72,97,82,C6,5F,98,32,A5,65,26,E0,F2,E0,AA,39,DB,60,E0,5F,51,5C,AC,63,18,93,D2,D9,2D,37,0E,73,DE,BE,DF,BF,5F,F2,E9,72,3D,E2,E7,AC,92,92,58,EE,84,35,76,2E,60,54,4B,9A,13,9A,5B,82,94,9B,38,5C,92,01,15,2F,44,F8,A0,46,53,43,40,3F,2D,C9,1F,06,09,87,06,A2,DD,AD,FD,69,A0,67,88,E5,9A,95,64,33,02,A7,B2,77,76,52,15,29,34,6C,89,8F,09,18,E4,65,72,12,46,97,8F,CD,DD,1E,29,1C,DC,3E,66,64,A7,D9,D8,2D,BB,D7,74,F6,10,66,6B,DF,EE,D7,D0,FE,09,66,01,56,D4,60,BE,FF,65,E2,F0,17,12,C6,E9,C4,1E,F6,3E,F7,99,74,45,E0,F1,CA,1C,55,E6,ED,28,7C,2F,37,8D,B0,A3,CE,8C,84,B9,20,3E,68,B8,85,D9,3E,F9,54,B8,BC,B8,F2,2D,FF,F7,8B,EB,8C,12,56,C9,B4,46,B0,CA,C7,52,33,56,F5,66,DF,28,20,77,1B,03,FA,36,93,17,E2,05,7C,C7,20,67,81,74,CE,BC,8D,6E,43,75,25,15,DF,AA,B2,1E,3C,CE,EB,B4,77,E7,02,59,DD,40,64,2D,1C,D6,53,AC,B2,59,B8,9C,85,FD,B5,3C,2C,D6,87,8B,D7,3D,BF,2D,BA,3A,93,5B,84,68,97,A2,BA,3C,AA,DC,37,92,5E,7A,4A,82,7C,9A,93,83,AF,A5,75,DE,B9,79,C7,D0,AF,3E,6B,AD,79,DD,ED,88,D6,88,F2,83,76,A2,87,3F,B6,BF,55,C5,27,D6,3E,A9,94,13,CC,FB,7C,3D,03,15,DB,DB,71,75,D9,B5,D3,E4,76,7E,7F,44,99,32,A5,13,03,81,E1,60,52,37,86,68,8E,F7,8F,E5,4F,22,6E,89,FD,2A,90,C1,7C,CF,56,E0,DC,86,4F,64,18,58,4C,7A,51,70,1C,83,E3,D7,BC,C8,C8,3C,54,2D,1C,37,5C,99,F4,DF,B5,7D,09,51,68,08,4D,B9,25,DB,43,02,EB,8E,F4,D8,25,2C,CF,2A,87,DE,B3,08,44,8C,E9,42,B6,CD,62,9C,BD,81,E0,2E,8C,26,16,4F,98,6B,AB,DA,37,E1,A7,94,3C,51,7E,DE,83,EC,E6,E0,1E,DE,F0,70,6F,7B,5E,EB,E4,FB,9A,79,FA,68,AE,DE,75,9D,11,7E,32,73,5B,EE,56,EC,D1,DC,BC,1F,A5,55,71,F3,71,59,42,7C,14,B2,17,E3,7F,2A,CE,07,31,A8,BB,A7,3A,D7,33,FD,D0,B3,4A,37,C6,E0,92,42,B1,72,0D,DE,AA,08,3B,F5,65,23,2D,93,98,D3,F8,CB,19,DA,13,62,87,7A,C0,03,87,82,AB,C6,DE,6A,69,B8,C6,00,04,1B,9D,FE,D2,86,1D,BB,AC,B2,91,6C,89,1A,C8,69,C7,AF,09,70,B2,85,09,DE,6D,0A,5D,F3,FE,63,33,24,64,18,AF,5A,8E,18,17,D7,F0,CC,55,B1,6E,B7,12,27,B7,E2,2B,00,86,29,15,CF,BE,9C,10,51,1F,67,1D,A6,8E,6C,A6,B0,F3,D2,A8,1F,2C,28,8D,4E,66,0F,EA,EB,FB,65,10,C5,16,A1,E3,77,BC,93,7E,2A,3F,03,7C,2E,15,F1,AE,CB,E0,D7,A5,DB,23,97,37,D2,E3,2C,27,66,25,28,9A,6C,49,83,15,3B,3E,69,86,38,87,02,8B,A6,3B,F2,2F,0E,10,0B,A8,22,78,20,F2,FD,65,35,85,D1,82,C6,BD,D7,02,A7,9D,85,46,74,78,32,61,6D,03,58,98,B3,3E,51,A2,9C,3A,46,4C,9A,D9,27,67,8E,67,20,04,58,4C,EA,27,86,1C,40,41,F9,5D,87,58,B2,DE,11,A2,4F,C1,55,FC,6A,F7,A6,C7,C0,55,64,3B,FF,E2,47,9F,7C,AC,B9,21,5B,51,36,8F,A9,68,47,4C,22,C4,51,AF,B4,AB,CF,72,56,52,A4,5E,C8,B6,36,74,D8,8C,65,FE,6C,12,75,6A,06,B5,14,7C,D1,02,11,77,E4,EB,3F,C3,62,F8,C4,7E,DE,1D,6C,7F,CE,90,0A,06,87,0A,9C,C1,B3,9D,B2,59,D0,16,27,8D,94,E6,8F,75,A1,66,D5,85,CF,46,3A,D3,81,BD,AD,57,0D,6C,11,DB,D9,60,E3,A4,7D,78,25,76,3A,EE,6A,8B,9D,E8,EA,EE,BC,DA,07,B2,CD,76,6F,4A,EC,7C,24,8F,DB,7D,FD,9D,DF,95,01,53,A5,07,6D,A0,9C,D9,01,CC,45,39,FE,26,70,92,ED,6C,67,A0,94,7B,AE,18,6D,60,67,FF,99,1C,66,2E,F8,D8,08,0D,02,B1,B3,81,90,DA,36,68,41,F7,BB,7B,A8,D3,A7,CE,EA,F4,D5,18,11,CF,CD,A0,2B,58,F1,A5,3A,94,D4,C8,72,48,1B,57,4F,36,E7,B2,3E,62,FD,56,76,8B,5E,5F,A9,FB,90,C0,B1,D3,C5,DA,F1,35,1F,67,60,1F,71,4B,37,79,B9,70,3C,9C,D1,AB,85,49,2E,2A,6C,50,89,A6,7F,EC,28,08,92,20,03,FA,C8,67,48,ED,9F,28,F9,3A,90,DA,F8,69,7B,68,FC,3C,98,58,67,2E,54,2D,8E,1F,EB,B6,82,42,2F,04,94,53,CE,F5,A8,3A,B8,1A,94,BA,46,1B,14,0E,D8,6F,D3,65,3A,52,03,6C,F8,DB,41,2A,E6,8D,CA,82,D7,69,09,AA,78,54,6B,12,FB,0F,2D,CA,92,2B,4B,18,CF,3D,5B,28,B3,30,2E,38,83,21,09,CA,A3,41,F3,DE,A5,34,84,D6,F9,33,84,C9,D4,19,50,8A,C8,2E,F2,61,82,13,1E,0F,49,AB,90,F4,9A,3F,8A,CE,C4,19,4C,8E,E4,93,74,01,D2,EB,C4,FE,9A,EC,2A,D8,AA,67,F5,74,C7,F3,3B,9C,0A,9B,BD,77,AA,71,19,DF,39,03,64,82,A4,11,AE,C3,26,B3,E1,72,2C,BE,37,BF,C2,DB,6A,C9,51,DC,AF,E6,6B,C3,CA,01,9E,E9,E9,39,A9,92,94,3D,8F,75,AD,F5,86,58,03,07,B8,17,05,F8,06,3A,77,46,3A,CB,DF,AA,7B,20,20,59,44,4E,64,71,84,19,4A,67,6D,17,2C,41,AB,66,AB,93,3E,1F,58,DC,4F,9C,8E,B6,64,E4,85,7F,AC,E0,6F,3D,CF,E0,3D,65,66,85,34,2E,CA,54,F1,40,B1,55,80,B4,50,96,87,E4,60,07,69,0C,12,45,27,75,63,08,70,04,F3,78,1C,21,01,61,A4,D9,E6,B9,45,0D,A4,56,A6,E2,4E,6A,A8,69,EA,D9,2A,DD,1F,75,19,A9,E9,66,43,8E,E9,03,E7,49,9F,F1,9B,90,DB,4C,45,87,C2,6D,13,F3,0F,85,E5,3B,99,A2,2B,38,79,AD,6F,16,61,D9,3B,AC,E2,34,19,C8,8A,BE,38,71,0F,E4,2E,58,3D,9E,B7,45,81,C1,49,83,C7,F4,E8,F5,62,4E,4E,BA,9C,B3,0A,34,7B,13,17,9C,47,24,73,F3,05,41,2A,FD,46,8C,7A,DD,9F,50,72,37,1B,BD,BA,11,3D,DE,42,88,C3,F2,7A,2C,18,18,C5,75,1F,23,70,B0,4A,45,57,17,E0,5B,37,21,1C,CD,02,EA,41,91,77,12,B4,EB,9D,C8,AA,45,4F,EB,22,D5,78,1A,0F,C3,50,46,95,4D,83,FB,EF,C0,6C,B8,BA,CF,29,04,E6,8A,AE,9B,34,8B,6C,16,2F,35,99,4F,CA,1F,61,A2,04,55,C9,85,B9,20,5C,A8,64,D1,3E,89,72,83,82,EA,3F,18,20,01,8C,8D,49,06,35,C4,A4,2A,D3,7C,79,0A,8F,1D,DE,90,B7,F5,F6,F5,F6,14,09,20,DC,6C,27,5C,0E,49,C9,99,EC,77,9B,78,61,DC,D2,5D,E1,7C,C6,A3,1E,C1,FC,7C,0C,9E,8C,35,8E,D4,99,BE,F9,08,9A,63,D5,58,EF,CF,B4,BF,39,5B,C5,12,26,70,57,68,E6,11,DB,92,AE,C2,88,6F,48,21,F7,D7,53,97,55,4D,BB,BD,F1,E4,F3,66,1F,87,CC,3A,8C,74,2C,5F,04,94,FE,48,8C,EC,19,A5,F5,7D,4A,31,05,F6,22,E5,1C,2A,E5,DF,00,46,FA,27,84,B4,C1,03,A9,53,70,5E,DB,AD,73,18,8B,76,00,39,CB,7D,C5,73,3C,73,3E,9A,78,8E,FE,B1,79,42,CC,80,58,70,C1,01,2D,71,00,79,24,E0,8B,0E,FD,34,D4,E8,CD,92,75,E1,5D,AD,63,7C,47,CD,C3,42,B4,0E,C3,83,65,38,A9,F8,9D,CF,43,6A,32,ED,DA,13,4B,AE,B0,05,07,48,E6,22,2D,41,A5,FC,ED,62,BF,70,C6,FA,4A,29,C0,A9,13,0C,25,25,32,AB,40,5F,BD,A8,E9,02,7C,09,49,09,62,3D,45,53,FE,63,FE,DE,C4,B0,E4,07,A2,B9,0A,4D,23,60,D3,A0,A6,3A,C0,5D,3C,9F,1F,5B,86,68,22,08,FB,65,D5,95,31,98,EE,B3,2B,6B,35,5D,AD,F0,47,A5,27,95,23,63,36,5F,88,5E,00,52,FD,77,1D,E6,D8,F8,01,06,56,5E,64,25,AA,24,49,F6,47,58,60,F8,75,59,E1,7F,EA,C3,0F,E0,74,40,0B,69,9C,FA,58,65,E6,2A,C2,B2,CA,3F,6B,63,E7,08,8B,CF,58,3E,06,25,9C,12,15,C5,C0,F1,BC,C4,CE,EC,51,20,A9,94,AF,9D,5C,0F,64,C9,E5,BF,60,0A,CD,B8,AD,DA,AE,E4,42,BC,2E,6F,55,B6,75,16,63,65,5F,8E,6A,93,3E,44,47,B2,AD,9C,C1,51,E6,31,3B,62,60,52,0B,F1,87,64,00,CE,28,EC,88,2C,94,3D,8A,30,06,11,2E,65,17,19,06,DE,BA,FB,C5,C4,9B,75,D8,2D,80,08,9A,95,D7,8E,E4,38,7C,89,F7,29,4F,0F,89,B3,51,7E,EC,FA,34,2D,28,E5,03,56,4D,E2,F9,C2,F0,58,EF,9C,09,F9,AD,42,F7,72,6A,EC,60,39,EE,B7,B2,88,37,73,2B,AC,90,14,08,11,DE,AA,7C,74,09,A3,BD,D2,E8,D5,34,BD,23,AE,65,85,B4,A7,51,F4,85,D2,36,8E,C1,69,DE,38,E3,00,B1,4B,3A,73,84,2A,3A,00,E5,97,8C,42,3A,96,98,3D,83,18,9E,4A,60,74,6C,CC,4A,DD,39,FB,20,30,97,FE,A8,EF,7F,D8,38,F8,CD,0D,6F,80,38,76,D7,FE,83,F9,84,1C,AD,16,68,93,D7,A2,02,34,CD,C7,2C,FD,01,7B,53,10,43,B2,14,99,AF,9F,10,73,01,48,46,14,B1,35,86,56,CD,53,3E,7F,6C,B1,C8,69,A6,EB,2F,9E,0F,11,8B,CE,AC,7D,63,8C,20,78,6A,DA,8C,26,99,72,70,05,C2,11,6B,AB,0D,0E,3D,FA,0A,BA,25,CC,3C,03,37,FB,72,A5,57,62,76,F7,F8,1B,BF,B1,26,CC,5D,03,FD,D6,89,50,A9,55,1C,42,DA,EE,5E,BE,C6,20,31,8C,5D,82,9A,FC,D8,14,7C,09,B8,4A,5C,09,23,14,2F,08,C3,18,59,C2,51,ED,AD,3E,71,88,39,B7,99,6A,86,67,EF,FD,42,7A,65,95,64,D9,C6,25,AE,D1,CD,77,32,1A,02,0A,99,B2,00,51,C7,D4,52,9A,2A,80,9C,AB,1E,F5,B2,06,27,BE,88,F1,7D,81,1A,B3,5E,EC,61,7C,BA,B9,F9,4A,4B,14,5D,A2,87,CD,F7,38,69,E9,A7,3E,0A,2E,E4,F4,B9,22,5A,4C,C8,6F,B1,CE,32,79,C7,3E,E9,EE,6B,91,B7,7A,CA,B4,99,CD,C1,D5,08,EE,B1,BE,6D,0A,F4,5A,7F,CD,1C,DE,11,5F,32,48,79,B9,7D,0E,74,AB,36,82,43,5B,D1,31,8B,3E,5F,77,B9,F7,00,BA,C4,C4,8B,00,DF,25,F8,A0,F9,DE,13,39,96,66,E0,A4,FD,82,9F,7A,4A,EC,CA,ED,DE,9E,4B,37,EB,98,EF,E7,A1,CC,50,20,F3,6F,40,E1,50,04,3A,AF,0A,CA,D2,33,41,46,EF,B2,8C,EB,C9,D7,D8,BF,FC,1C,AD,C4,2E,20,41,7C,0C,C2,6A,1F,E8,45,5A,AB,1B,B2,DF,90,26,9B,B0,BF,21,D4,C7,92,00,7B,97,F7,3C,98,9D,8B,A4,7C,36,70,F7,A9,B2,1E,DA,19,1E,CB,B0,CF,0C,7F,DE,33,31,21,0C,69,A2,2A,B3,E7,4F,34,6A,DE,C0,10,63,16,2C,D2,B6,20,39,00,80,65,C9,56,3D,ED,39,97,0D,AA,63,CB,DD,62,60,1E,B6,45,47,78,07,5F,E1,3D,44,73,8C,DF,9F,4B,0F,6A,A1,FB,5C,B2,D2,BC,77,D4,F6,D0,21,FD,9F,47,63,A0,9E,0A,23,34,57,7E,89,58,66,74,9D,C5,C5,50,84,61,4C,BA,9E,35,D8,0A,8E,86,85,CA,F2,67,E3,D3,21,1D,3F,BD,4C,BF,44,A9,3B,DE,DB,6E,0B,4C,20,77,FC,A6,27,A3,74,BE,79,74,F5,F7,DC,98,A6,43,17,90,EB,10,C4,F8,1E,79,03,45,EC,30,F4,18,F0,C3,92,62,35,DF,1E,23,8C,DD,B9,ED,09,BD,1A,88,CA,A5,CA,04,EA,28,50,BF,C2,BA,EE,1D,4F,13,43,85,34,62,61,23,19,ED,47,AE,8E,86,C7,9A,B3,EA,77,D7,29,C1,46,14,FD,DB,32,DE,1F,0F,EA,C9,80,47,03,87,3D,A0,58,B5,29,8B,81,93,1B,82,E6,CD,C6,6C,1F,4B,FA,E7,7F,68,C3,99,BD,E8,BB,EF,40,A8,3B,AE,06,76,E3,EB,5E,2E,D7,CF,15,6A,3B,69,D1,5D,BA,BE,A9,3C,9B,EE,07,33,BB,F9,1D,43,73,B2,78,8C,C9,BC,A0,82,A9,55,F2,AB,FD,8D,04,54,62,4C,BF,CC,AF,FF,7F,E6,14,5F,E6,98,38,7C,75,86,7F,DB,A4,8C,56,5C,3C,F8,9D,44,BB,F4,BA,46,6D,0B,17,2F,5B,FD,A2,B6,C7,87,0B,37,53,BD,F2,C1,05,F1,61,B4,C0,A3,41,7E,91,80,4D,E4,E5,CB,5B,C2,E3,26,14,90,E1,70,6D,4F,1E,31,09,0F,D7,60,87,6A,62,66,33,9B,21,EE,4B,DF,3D,59,D7,6F,5A,04,FC,9D,FF,20,CB,6A,6C,3B,C7,62,C3,A7,E4,B5,18,93,08,C4,47,3B,23,F1,B5,B0,82,81,95,D1,FF,BD,C4,0A,2B,E0,8B,A9,A8,11,5C,B6,73,E6,78,E6,5A,97,68,76,C7,E4,59,17,14,78,0C,D0,68,87,12,41,33,70,2F,EB,1C,A0,1F,34,0D,4A,65,0E,18,CC,1C,FB,E9,E7,9B,BB,24,A9,6D,D6,7F,61,08,83,2D,D9,E7,85,58,41,8A,01,1D,AA,55,61,AD,74,C8,1C,60,E0,2D,9F,E6,45,F9,EA,97,1F,88,B4,2D,8E,88,D5,0D,3A,03,A5,0F,E7,5B,A4,EA,2B,8D,97,AB,85,7D,3C,30,55,FD,3D,04,13,EA,EC,C8,EC,3C,23,F4,AF,B3,3D,F2,95,74,5B,1A,A1,EC,3C,09,4B,FF,74,D4,2B,4D,81,8B,D1,BF,B6,00,4D,A0,9F,70,33,5A,12,FF,4A,1E,D7,7E,BD,93,FB,AD,7D,9F,DE,BC,1C,00,CB,67,03,17,97,23,99,E1,37,EC,70,CD,FA,58,BE,1D,A0,4D,CB,ED,14,F0,86,79,91,5D,2D,11,F4,59,E3,67,B0,90,40,DD,AD,D3,18,FD,F3,1E,D9,EC,1A,FB,E3,46,D6,5A,7A,1E,0D,C9,87,97,24,5A,05,EB,5B,E7,1B,66,60,62,60,FC,F0,D8,CB,37,D6,3F,03,97,DD,91,A4,72,D6,F9,83,29,4A,32,B7,98,74,CC,51,60,5C,41,5C,CB,A0,32,2D,75,73,35,6C,9C,84,84,E6,CA,1D,27,2A,08,F4,FF,6B,9D,88,61,20,11,E5,C4,05,68,2F,25,A9,8A,6E,16,CA,0B,A8,7E,0A,0F,1B,03,96,7B,54,64,05,D9,33,26,10,5C,6B,FE,B8,7B,9E,E5,DF,7A,8D,90,CF,9E,94,19,07,13,56,66,FE,AF,D8,57,9D,45,8A,4E,9D,61,7D,70,CE,EF,C2,13,EC,88,0D,29,B7,CD,19,AF,2C,34,99,0A,9E,E9,51,74,83,E4,B5,5F,9B,9D,66,6D,62,69,04,B3,C1,FE,14,B1,A3,DF,9D,63,FB,14,08,71,1E,E4,98,04,05,CE,3C,16,8A,8A,46,68,C1,E1,04,ED,05,69,14,58,FE,3E,1D,7C,F9,49,0E,13,8E,A0,1E,F9,F1,C7,66,07,16,01,23,B6,32,F3,45,D4,F3,75,67,B3,DC,E7,4C,6C,39,0A,DC,58,CD,0F,4F,3A,9D,FC,6D,F9,21,0C,C7,A5,B4,C8,15,B5,22,35,2A,27,96,4F,6D,77,57,C0,22,EE,8C,D3,B9,8B,50,97,24,4C,39,36,40,C6,C2,3A,38,BE,0F,0B,E5,96,BA,6F,A9,A7,E6,DD,D4,FD,38,5D,2A,85,DB,36,B1,1A,B3,23,46,E4,46,CA,4B,60,DF,ED,9B,7F,5C,E1,4A,A4,97,4D,B7,99,C4,DD,78,7C,13,5A,C9,3E,95,68,62,BC,CD,52,CC,E5,04,1E,42,47,85,13,9A,34,16,17,54,68,A7,99,28,BB,84,21,85,32,C1,81,21,23,17,C7,A9,8D,94,CF,D0,F3,5A,BB,34,5F,F7,CC,39,E4,E1,76,F8,D1,9C,A1,9F,68,58,84,94,E8,A7,E8,9E,6E,C7,BD,F3,EE,D0,04,69,D9,F6,B2,2D,E0,31,84,CC,6D,4E,7C,E4,4C,8E,9A,27,18,C3,C7,E8,8A,19,AE,1E,67,24,F6,51,48,A1,B9,15,8B,C5,89,FC,20,A2,C7,C5,89,F0,4E,96,39,9E,C7,BF,A8,7D,03,B1,14,7F,FA,F8,80,CF,F0,29,69,0A,6F,D7,E2,54,17,4F,F2,09,C8,91,54,2A,A6,71,0A,B4,A6,76,BA,00,4D,FF,2B,4C,A7,FE,2C,85,A5,F0,5B,B8,3B,91,9D,F7,EA,7C,F1,29,BD,B1,27,F9,D8,D9,5F,77,77,CF,94,59,61,2E,5B,89,68,92,46,90,2B,67,57,6B,73,F0,2D,2C,7D,F3,D8,7A,2F,42,43,58,C2,E0,89,2A,1F,FC,70,FF,A4,D6,8B,A2,EA,9C,51,F7,C3,64,3A,A4,FD,F7,70,DE,F1,19,66,8E,76,33,38,55,05,B1,F0,0F,78,2B,05,DD,FB,8C,27,87,C1,30,85,F6,0D,DF,B6,CC,9F,EB,0F,55,C9,B4,C8,7A,26,6C,97,40,E2,27,0A,54,51,59,C4,06,D1,1E,10,6C,19,FD,D3,73,25,72,6A,E3,48,18,AC,55,E3,32,32,DF,F7,A4,CC,00,91,92,7A,A7,4F,3D,B8,8F,A2,6F,54,8C,F5,4D,74,28,A3,F6,C1,3C,61,8F,8D,3F,4B,0C,4D,D5,3B,7B,49,7A,1B,11,CF,67,0C,36,67,D3,78,C3,80,3D,3E,77,7F,A9,35,25,24,B9,01,7C,F4,6D,C3,21,2C,BD,55,C7,B0,66,6C,05,8B,FB,41,E8,9B,2D,A4,3C,9E,07,57,30,E3,A4,3A,72,C9,88,45,23,2E,67,5A,B8,85,AE,87,04,6A,65,EF,68,DC,A6,F0,9E,2B,B4,39,22,27,21,23,6C,C2,17,C7,F1,1D,C1,70,54,15,9A,A5,D8,C8,F2,E9,E5,BD,D2,3C,B1,6B,9C,14,27,77,16,D0,61,B1,97,22,27,02,49,EE,DE,96,2D,E4,36,68,66,3E,95,CE,21,3F,B4,E7,01,95,F5,EA,DE,40,08,7C,6A,98,4B,4A,7C,15,59,32,B0,57,72,2F,F3,D5,51,38,81,45,4C,99,FA,92,06,FD,29,B7,8C,FA,27,4D,66,4D,DB,02,FC,81,A3,82,E9,F4,3D,87,1A,94,4E,18,68,37,E6,F8,33,14,9C,0D,83,F4,CB,94,DD,B7,06,B0,EB,D0,D0,CD,63,95,B7,D6,3E,D4,EA,7A,7D,EF,EF,2B,B4,F0,23,8E,BF,28,6E,D1,C3,D6,F4,7A,64,0E,D3,54,2F,38,4A,07,CF,60,77,0C,7C,1D,AD,54,67,7B,C3,96,6F,7F,10,6A,50,C2,96,46,4F,7E,92,87,06,0F,20,42,75,BB,4A,A0,74,E0,D5,0F,2C,FD,38,10,78,B1,60,21,5E,73,C6,8D,C0,3E,71,E8,09,B0,C3,16,98,98,7C,CC,AF,46,B5,09,0D,FC,F8,21,A8,37,17,90,E6,DF,2F,49,EB,1D,0A,70,85,E8,54,5E,05,AD,85,36,8E,35,B5,B4,F6,C6,EE,D8,CD,C3,F0,DC,D5,BA,D3,1C,1F,22,FA,2A,6A,FE,F0,79,21,07,16,9A,0E,F7,1B,2D,C2,8E,F7,FE,92,D5,9E,57,4F,9C,2E,FD,76,1E,B3,09,42,66,20,A8,BD,87,6C,0B,0F,43,BD,4D,C7,C5,02,45,79,22,21,6C,F4,4A,BB,B9,19,93,0D,4D,C5,0A,C1,C2,6D,D7,76,0F,61,89,50,04,00,96,A6,59,7E,25,62,02,BF,52,8F,BD,67,9A,D7,6B,6A,99,C3,6F,C0,3C,11,AC,8D,BB,4E,01,54,90,84,83,16,8C,D2,6C,61,13,3A,20,D3,20,D6,1E,6B,40,0F,2B,BE,5E,0E,55,BD,35,40,73,32,AA,24,4E,76,2F,5C,B8,2C,37,1C,C5,85,70,3F,79,21,BA,D3,14,7D,62,31,26,3E,E7,5E,10,9C,D5,CE,88,66,B8,B4,30,43,50,0D,F5,0A,38,46,4E,9F,D6,3F,35,FC,07,12,B3,DB,27,F2,2B,5C,10,51,7C,D5,BB,15,2C,CC,AB,96,D6,BF,84,2B,C2,4D,DA,66,C9,96,46,62,EB,0C,12,FF,59,32,CA,67,F0,0F,69,6A,8B,85,6A,EB,BB,B2,20,96,DE,87,9A,D2,FE,D6,09,0A,B1,CF,9E,4F,1D,1B,F1,17,3E,06,7C,6E,65,7A,B4,3D,1A,91,44,45,4C,70,1D,1A,0B,43,4D,1B,57,16,FD,4E,22,45,76,1D,8D,3C,69,10,44,A6,35,1F,06,0F,4F,C2,CC,3E,A2,3A,A4,70,7A,5D,1D,1A,0E,7F,C1,C6,95,88,BC,6B,CF,FB,3E,D2,EA,2E,1F,98,20,4E,0F,C9,C1,F5,90,66,65,9C,3B,67,D5,60,C4,FD,A3,D4,49,53,FC,92,D5,D3,43,04,12,5B,4C,5E,06,12,57,DE,E8,5A,50,4C,CD,79,52,21,75,ED,D5,33,FF,83,BB,C3,5D,C9,41,A6,AD,6B,9A,F7,C4,F6,3C,70,35,7F,B9,5B,63,21,51,5F,18,2C,7D,63,FC,68,26,9A,DA,10,2D,E4,76,D6,0C,AB,BD,C3,D3,DB,33,A9,4F,4A,AD,49,62,9C,7F,A9,50,97,6C,6B,D2,2D,B0,F4,9F,07,9A,DF,29,4D,04,3B,21,88,DD,AB,7C,1F,7E,B6,E4,63,A5,B3,CC,30,45,FF,85,A4,AE,C0,C2,F3,84,56,28,EC,9E,2F,32,20,26,50,FE,15,E3,AE,71,D7,18,3D,80,F7,BC,4A,96,04,13,B6,3F,04,14,0B,6C,85,01,7C,19,62,D1,9A,64,D4,40,9C,8D,8F,7E,E2,69,21,4C,F1,77,1A,EF,A9,08,6F,A9,DB,8B,7B,36,FE,CA,41,67,8B,91,2F,B9,34,02,29,FB,B6,F6,7F,9A,F4,52,B1,A5,20,41,9B,52,B6,2A,47,18,F6,01,04,45,6E,F1,CE,A3,B5,FF,7D,A2,E8,D1,D5,17,4B,14,FC,11,94,EE,FB,FD,97,3E,CE,A2,65,37,D9,77,4E,E4,8E,DE,67,8F,36,04,B5,D0,1D,13,23,AD,45,7F,74,51,D0,7F,2C,D3,DB,3A,55,CF,A6,04,3C,3B,20,94,6B,BA,08,1C,47,54,B6,70,95,7B,E2,6D,47,E3,8C,F5,79,E9,A0,12,38,79,E0,E3,BB,60,23,F3,4B,5D,5D,FC,DD,41,BE,FD,80,1C,CF,3D,2D,56,53,A3,9C,A6,06,BC,C8,61,AE,79,68,CE,9C,AD,6B,18,62,9A,99,02,26,B1,6A,46,99,12,2F,07,57,82,11,40,7E,18,04,54,03,F5,77,C0,44,4B,F3,BC,D2,23,22,3E,BE,54,EE,7A,D6,8A,80,70,9E,E3,B6,14,B9,9B,42,BC,B9,A7,E8,71,54,3D,8D,36,EE,D3,35,01,F7,15,29,B2,85,46,02,8D,0F,FD,AE,DC,9C,E4,83,A0,07,52,26,A1,79,34,10,10,8E,93,B6,14,F7,05,0A,61,EE,C1,2B,F6,B3,B2,C0,05,D1,04,AA,61,5C,79,58,1C,41,3D,14,8E,B3,5E,CA,25,E7,EC,EF,4D,97,24,B4,12,CF,E4,05,97,D7,66,69,DB,5E,DB,19,9C,BE,6B,21,7D,79,DD,6C,A6,F6,72,72,17,64,1C,F9,28,22,9E,D9,B2,77,F5,BF,DC,0A,6E,EC,AE,46,C3,99,B7,23,60,BD,E6,58,9B,DC,06,04,DF,E3,9F,61,AF,E5,60,65,0E,C1,CF,C1,5E,8E,09,8F,84,E1,17,9B,85,C6,C4,03,C9,51,57,B9,16,4D,F8,35,83,3F,29,FB,FE,F7,58,D8,CA,FE,36,00,DC,30,D9,05,C8,D9,3C,B3,5B,C8,06,14,A3,4D,DA,10,67,3F,EF,D7,B0,1F,7F,6C,E6,E7,DC,18,0F,62,36,14,45,AC,A3,52,2A,F9,4F,80,4F,3B,5D,88,51,8F,4D,C3,04,89,AF,AE,C0,7A,74,CE,E1,B4,90,B2,B4,4F,79,67,D9,14,3A,54,69,D3,43,A4,19,37,C3,2F,28,B1,71,6A,6D,7B,33,BA,9B,B5,71,6A,C5,B9,91,48,41,C3,F0,16,F8,01,71,20,43,92,B4,DD,38,85,7F,3E,78,2E,1E,EB,17,14,14,83,45,7F,AF,02,CE,28,32,4E,72,17,71,E8,B6,62,8D,C7,8D,1A,9F,72,C0,BA,92,0C,D8,47,11,CB,A9,22,6A,47,48,29,5F,CE,1A,5B,5A,D5,E2,51,1F,CC,69,E6,48,92,29,27,F9,31,DE,F8,F2,87,EE,A3,77,EC,0F,AC,58,EB,52,CA,2E,D3,69,3A,13,A5,CB,C8,39,07,36,C1,0B,31,59,01,FC,F0,F2,E0,8A,C9,AF,3A,93,97,97,04,93,3A,E5,E5,53,8A,1A,F0,7D,5A,E2,0B,91,43,D9,3E,6D,68,6D,FB,9C,98,0F,F5,AC,DD,7C,F3,3E,B2,E0,33,8F,1C,5E,34,43,E6,26,47,A6,88,8A,F3,CE,78,06,31,A3,71,FD,6B,30,59,11,9F,AE,5E,F2,FC,4C,FC,A3,4D,C1,08,9C,5B,C2,69,0D,AD,8B,DF,74,04,37,1E,55,21,47,5B,97,6B,3A,34,A4,C5,B8,23,F2,35,8C,D9,3E,AA,0A,8F,F1,DA,9F,77,3C,76,BA,42,F5,3C,70,EE,5F,08,54,04,83,E3,6D,3F,AB,71,F3,0B,04,BB,18,F7,24,E0,4D,DD,45,75,ED,9C,6E,AF,BF,60,62,9C,8E,FB,3C,9D,42,C4,68,C5,BD,C1,DD,AB,95,4A,39,9C,81,DB,2B,8E,EE,9C,47,68,F7,AE,36,85,D3,B8,FC,5B,FD,FC,E1,DC,79,20,56,CF,AF,71,DF,64,E0,D9,03,C2,5D,81,98,EF,3A,1A,AE,6C,C3,77,8F,A2,BF,77,8F,AE,85,48,91,35,42,64,9E,D4,E6,AB,BA,B0,43,CE,22,CA,69,A9,82,98,DB,02,98,AE,87,83,16,38,8A,67,8A,44,5D,4E,11,CE,45,16,9B,22,2A,30,58,9C,15,90,A1,17,4A,DE,BB,22,35,D0,FE,F6,DD,39,51,0A,59,0A,9C,C3,0F,A0,E1,35,94,28,3C,00,15,A0,B7,B4,44,50,26,C7,6B,37,D8,7C,68,61,2F,12,CE,38,F6,49,AC,34,06,64,68,D2,83,16,57,F2,97,E5,26,F4,92,E7,F6,38,23,82,4F,B1,80,CB,D9,F7,B8,79,E5,F5,D5,43,78,DF,FC,9B,BC,E6,95,76,61,E6,C0,6D,BD,DB,09,C7,89,20,A2,47,A9,4D,AA,51,27,A4,4A,98,F8,B3,5D,59,03,32,BC,7A,E4,1F,C3,80,87,22,3C,74,08,59,EB,AA,CC,38,5B,9C,6D,A7,89,F7,16,19,A4,CB,05,18,69,41,A4,CF,D9,99,03,D4,1C,30,68,92,B8,A4,2A,29,E8,1B,CE,5E,D9,B3,FD,B3,44,44,1B,BF,AE,AB,00,49,B2,7B,5B,51,B6,E7,BF,CB,3E,B9,8F,11,8D,BA,A9,E7,DA,04,70,E5,B5,72,27,63,50,91,3E,F9,3D,99,14,00,6A,70,AE,89,C7,0B,38,41,D9,37,47,1B,8D,9F,3D,1D,D1,51,ED,35,35,6E,2E,DD,F0,18,A5,5D,73,9F,63,E2,5E,F9,3E,EF,E1,14,E8,B0,F1,97,3F,D0,A7,C5,A8,D7,6A,AB,6D,02,65,29,29,7C,27,0B,AB,54,F1,BE,4D,E7,61,D4,C9,14,9A,5C,CA,CB,D4,D1,3F,C0,6C,B1,E6,F8,91,C9,F1,E8,46,74,FF,D4,4C,73,26,DE,F6,1A,C9,0C,FA,CB,76,C0,B3,4A,D8,ED,16,C0,B3,B6,F0,E3,EE,41,DC,A2,A9,09,7E,A5,9B,71,A1,A7,50,55,23,5A,7A,2A,8F,F0,98,E7,F8,9D,9C,E6,F1,B8,01,DC,78,E2,77,E4,C1,72,E4,6B,10,9F,1A,08,C4,C2,6F,B8,4D,16,92,E2,05,A2,C9,B2,40,4B,01,E5,58,05,56,CE,32,1D,90,E1,D9,AF,FD,09,2B,C2,00,68,2C,69,FA,A3,67,E3,D2,6F,BE,26,A3,EF,37,61,9D,BD,38,82,74,2D,CA,2E,93,CA,C4,79,BC,E8,79,C8,90,16,66,D3,20,92,DE,2A,16,84,ED,6B,0C,D8,0A,4C,92,73,6C,36,07,4A,C4,2E,68,02,FF,EF,88,C5,21,BA,DD,2A,A1,EE,D7,3F,D2,B6,EB,EE,ED,60,4E,00,9B,E9,56,7F,A6,0C,9A,E9,EC,75,AE,DD,B7,87,6F,5A,CA,8A,34,8A,DB,EB,7D,1D,6C,F4,8A,DD,AC,6A,CD,38,9B,7B,D8,CC,39,60,89,55,D4,0B,FA,FF,D4,93,30,60,B7,5A,0E,9B,84,67,78,D1,42,9D,F0,0B,67,1B,19,31,40,F4,AA,7A,CC,97,7E,67,B9,EE,3E,3E,43,B4,72,DA,A8,9C,D7,8A,42,FD,09,27,6F,65,F3,B6,AD,F0,14,AF,87,5A,13,D5,5F,CE,54,8F,82,5A,66,96,F5,2F,EF,8C,AB,FA,AC,E7,8E,F0,0A,68,54,CB,FD,0D,D9,5B,DC,1A,45,06,59,7D,09,AE,2C,6D,98,BF,79,90,82,4A,3A,A3,69,32,5C,79,F9,5F,EE,D8,AC,13,82,76,A7,A5,FC,A0,C1,72,9A,2C,A7,F3,EB,B4,0C,5D,2C,6D,39,11,FA,1F,01,0E,F6,57,8D,90,17,3E,6D,19,DA,57,CD,9D,F4,4B,FC,CB,ED,99,34,BB,A5,AE,91,FE,E0,A9,ED,6A,38,1F,37,18,9C,95,2A,B9,C1,5D,C6,BF,13,DD,B5,55,51,7A,CA,77,BF,E1,42,72,84,0E,11,D0,D7,23,67,D0,E0,74,60,77,06,16,4E,7A,22,23,AF,EF,9C,20,8B,F5,69,D8,06,EE,32,C0,0F,1D,D9,FB,44,E6,68,F8,F6,1B,CE,F0,7C,7E,1E,15,38,2F,E9,2E,03,70,A3,26,4C,8B,29,67,DE,64,A3,B0,C1,E9,96,A8,A2,5B,14,2C,61,AE,04,FB,83,B9,F2,80,C5,A7,08,7F,B6,80,5E,97,24,09,AD,29,DF,E3,C5,E3,FA,32,5A,D3,63,7B,11,0E,3B,BE,D3,AC,7D,07,70,44,2A,9C,AA,B5,C4,95,74,7F,69,33,A5,5C,DB,89,12,25,1C,F5,5D,31,D6,E2,03,27,58,60,3E,BE,37,F1,4F,32,55,BE,64,A2,C7,51,B3,E8,5D,3A,19,1C,28,F4,8A,2D,D6,85,DF,ED,06,94,65,05,34,0B,E5,1A,7B,73,F6,DF,BB,61,0B,3B,B4,80,AB,CA,6D,FC,BD,93,12,06,1D,4F,7C,FE,D1,7E,87,D5,8F,12,1E,AA,EE,35,85,BA,C4,7C,C2,3C,C1,60,68,F8,D1,0F,5E,43,54,A3,5D,73,FA,49,47,64,18,B8,53,F4,2D,9C,56,4D,31,6F,75,03,FD,EF,1E,70,42,FE,A1,49,A7,A8,3C,0E,7D,B9,3E,49,07,92,FE,19,AC,0F,43,FD,A0,87,D8,FD,46,6F,0B,2E,E8,4C,07,F1,A5,A2,EF,2E,E0,5D,EC,FB,31,8A,BE,7D,75,8A,F2,F1,65,9F,85,29,62,4C,E5,98,E7,A4,99,4A,A9,F5,F7,D2,AC,A3,29,C5,E6,11,5E,A0,DD,1C,1A,54,67,96,39,89,48,B2,67,01,D8,21,F3,00,E3,F0,3E,68,65,9F,B2,D5,F1,B9,8F,1E,7C,75,B4,AA,66,5C,1D,F3,7A,60,69,12,49,26,F1,CF,1A,A9,57,0E,C3,6D,3A,40,13,51,02,68,23,C4,D9,46,EC,AE,3A,53,E7,42,9D,2A,6F,A7,D4,89,A6,2E,84,FD,95,BE,5D,CC,68,36,87,4B,84,1C,FF,40,8D,6F,BD,A2,37,FE,1C,B6,F8,2E,AC,56,CD,D6,45,54,69,98,CA,93,57,4E,3C,19,57,DA,EC,2A,84,9E,C6,65,80,22,CE,2C,2C,02,F9,36,54,CB,31,86,7F,8C,CF,D2,3F,C3,41,E2,35,F6,35,5B,4E,6A,A0,91,95,D5,DB,09,76,8E,B6,48,B2,A4,50,C3,A1,90,4D,D1,37,96,1D,0A,FD,CE,56,56,F1,6C,91,E7,1B,C2,32,61,A4,4F,91,86,C1,4C,7D,F9,67,05,5C,13,AD,F4,E2,44,E7,90,6C,35,44,B9,62,F3,D8,6B,5A,60,B0,7C,C4,45,EF,87,1F,DD,CB,E8,FA,0B,0E,9B,D5,DF,D5,79,C3,A1,23,86,55,C2,47,E3,2A,A6,3D,D1,C3,D5,67,8D,68,49,83,A9,9A,7A,BC,AA,D8,53,69,5F,53,11,62,DA,78,88,3B,CE,EE,49,B5,FA,A4,FC,BF,FD,38,C6,FE,E3,6B,18,66,4F,AB,38,CA,4A,29,62,48,4E,13,72,24,AE,AA,E7,7A,52,12,86,F1,15,37,0C,C3,D0,14,EC,87,F2,B9,44,A0,D1,FD,40,45,47,71,9F,E8,86,5A,97,05,BC,B9,16,BD,E4,81,61,87,30,DE,5A,3A,62,1F,11,D3,30,0C,96,C4,1B,80,67,37,7B,A7,EF,BC,C9,44,14,9B,7F,D2,51,E1,B3,87,4C,C4,8E,B5,E9,25,98,A8,59,22,E7,6D,20,A1,FA,63,CD,B0,0C,4A,68,D2,3C,D0,E1,A8,0B,FA,A0,87,51,DA,4E,0C,3E,F8,06,CE,2E,47,A7,37,08,67,1C,C3,78,56,F3,40,73,65,BA,53,FB,DB,96,D4,10,A1,85,24,A1,20,CC,2F,A6,18,1F,43,12,89,38,7B,89,2E,06,E0,60,DF,FA,11,63,85,8D,D9,63,08,2B,21,D9,FA,FA,37,FE,F6,8D,59,9F,9D,C9,15,B5,F4,EE,2D,B2,A1,EF,FD,32,DF,9B,02,84,85,F7,3A,66,FB,A2,69,54,68,F0,10,AC,57,3D,D5,01,7C,3A,D2,B5,5A,DC,C3,CE,1E,37,98,12,8C,FB,2A,23,95,47,C1,83,74,63,18,1A,97,15,BD,80,F5,23,F9,73,72,E3,B4,17,51,D7,9F,EB,5D,84,F5,B3,89,DC,DC,BD,D7,1B,4A,65,68,43,73,99,C3,05,71,58,E7,72,66,FE,2A,DD,9B,33,4C,15,26,B0,92,EF,17,75,54,08,98,C1,AC,00,E3,9A,E5,2B,9D,AB,6E,67,16,9B,87,AF,05,8B,9A,AD,05,ED,94,91,80,B2,22,F7,AE,E6,13,33,E2,56,66,EB,D4,35,75,11,8F,74,EE,B5,D1,2A,D8,F9,43,EF,7B,70,E0,BE,27,07,C4,41,48,2B,3A,67,22,0C,45,40,41,C2,25,13,B7,EF,89,8B,DD,11,58,19,04,58,BD,04,1C,31,DE,32,87,42,3E,EB,43,00,42,B4,CD,B6,88,79,F0,B3,60,F5,BB,97,A9,1D,AE,0A,B6,B7,0B,3D,3B,7B,92,2C,C2,8E,43,01,74,B5,54,C7,FF,A1,13,89,2B,C7,6C,F0,C4,91,60,4A,53,3E,AB,0F,05,36,09,BF,B7,D6,41,45,F2,AD,F9,0B,73,73,DD,E7,C1,86,F6,E5,5F,DF,9E,D3,7A,80,ED,5A,80,6A,AE,D1,2A,C5,32,1D,0B,E7,93,4C,10,2B,01,A6,B2,E3,35,F8,91,64,46,72,B1,57,6A,E7,68,C3,0D,7B,AA,D2,F6,3E,46,47,76,07,5E,EC,EC,B8,7C,BB,B2,B1,72,5F,C4,97,04,F6,BD,28,5A,08,CE,18,FB,6A,40,A3,EE,29,CE,DA,7F,B9,E8,39,7E,9A,5D,85,47,31,93,FE,5F,07,56,1C,61,09,B7,8E,1D,52,58,C6,8B,F2,3E,A4,07,33,9F,CB,7E,C4,1D,86,4B,92,39,4B,B6,B6,C1,3F,7F,D1,87,4F,C3,32,B6,8E,2D,61,7C,74,AA,F0,03,F9,3B,FA,DC,8F,9F,59,86,80,26,AC,AC,99,9E,38,96,02,22,2B,01,80,C6,EA,32,99,83,A4,03,21,4D,2A,C5,8B,28,C6,BE,E7,B3,6E,3F,CB,06,EF,C7,9F,BA,C1,A0,30,D7,8A,25,E9,49,3D,D5,52,6E,4A,E5,A8,00,17,92,E6,B4,B6,8E,93,A3,4F,98,DE,60,30,08,86,4D,58,23,0F,EB,6D,B3,D4,DE,3A,0F,94,3F,B2,17,55,3E,81,6C,43,7B,D8,B6,88,00,93,80,7C,FA,31,A5,C5,C2,CE,50,80,5B,C1,1E,B1,C3,DC,23,CF,0F,CB,13,13,C9,5F,40,BD,FB,63,C3,BB,2B,B9,71,F8,71,EF,5F,9B,0D,99,92,EE,F1,A3,59,F5,44,AA,EE,B4,0F,FB,9F,BB,94,DA,E2,4A,C3,04,75,6B,25,3D,19,B2,13,DE,25,C3,A3,01,1B,00,14,B2,F2,FE,55,A1,60,C8,E8,0C,70,28,42,7F,0B,62,31,26,B4,6B,B2,DA,6B,F7,B2,7C,79,31,49,48,28,F1,F4,B2,A3,45,DE,51,E5,F1,F6,E0,E9,2B,48,11,A0,2F,EB,D8,1B,0C,0B,11,41,09,0E,5D,C8,B3,76,9E,10,24,79,1E,26,3E,C7,95,0A,D2,FA,E6,EB,CA,AA,23,26,14,E6,F7,9C,47,F9,0E,30,6C,1F,5E,26,5D,A3,4A,80,F4,B1,78,31,35,84,0E,45,11,32,0A,B5,57,FD,F1,29,61,C3,DD,6E,9F,C6,D7,00,47,05,98,33,92,2C,11,46,1F,8E,07,A2,D1,DE,4A,DC,47,52,96,79,93,66,B9,43,65,FE,A3,BA,D3,8D,E5,50,5A,5A,22,A8,3B,42,85,28,80,43,40,B1,01,DA,2C,DA,71,98,D2,68,00,29,CC,AE,E1,B2,92,06,E5,C1,04,4C,52,0D,85,68,94,60,2A,F6,97,9B,FC,F6,09,95,4F,AB,D4,11,40,CB,54,4A,82,47,C9,92,7D,6E,4F,40,50,EE,A5,88,CB,ED,B8,27,1B,17,62,7B,D0,C9,69,A4,A1,FE,AA,60,A9,6B,B3,90,38,05,4D,6E,AC,25,53,89,D7,88,19,6E,83,C1,3D,22,02,16,B8,E8,70,89,3D,8A,6E,1B,5C,2E,77,1F,91,38,41,08,98,2A,88,DD,12,17,0B,39,4D,D6,74,F2,43,75,C8,D3,83,38,81,91,88,52,D2,0D,FE,99,60,55,85,BB,67,D3,24,50,B8,87,C4,74,AA,78,D7,E2,AE,DA,0C,00,46,33,3A,76,EE,6F,D4,7D,35,CD,48,DA,15,49,F7,BE,82,C4,71,27,E2,4B,A0,3E,2E,ED,B5,86,8E,50,1F,02,DA,38,20,99,F0,87,27,9A,E0,E7,20,0C,D0,A3,8D,41,01,D1,11,1A,FA,C5,F4,37,EE,F7,56,82,68,49,0E,16,EA,57,BD,C1,F6,C4,E5,9B,3F,F5,4E,A4,38,4B,EE,54,B2,E1,9B,D1,D3,A8,8B,D8,32,CA,F8,20,A8,85,82,52,90,99,24,47,8F,4C,45,3B,DB,29,8D,4E,B5,8E,45,7D,E0,59,9C,CE,05,5B,DB,3C,9E,6A,A7,90,59,3C,7B,F0,73,72,50,CB,3F,9A,28,9B,C8,75,20,44,1A,D6,B3,FB,08,9D,03,7D,0D,98,A1,A7,14,CF,79,BC,6D,B7,69,49,75,BA,09,63,6A,95,35,AD,86,78,C2,0D,B6,F6,F8,91,B6,3C,F6,1B,6E,DB,36,A2,EC,39,EC,63,AB,1A,75,E8,EB,23,6F,2E,75,6C,E4,C6,84,F3,54,46,83,42,62,D7,3B,CC,EA,A9,66,CC,0E,11,A6,B8,5B,79,AF,84,24,A4,57,FC,1B,E3,A1,AC,3C,B7,64,09,92,80,C6,1D,71,9F,EA,9D,2C,B5,FC,2C,56,31,6A,C3,F3,88,80,93,5B,BE,09,97,5C,E3,FE,55,26,8B,D1,EC,24,DD,6A,BC,A4,14,4D,78,94,2D,69,50,D0,26,46,4A,66,09,1F,92,A4,81,72,4C,06,6E,5E,54,E8,6A,89,DA,64,AA,88,C9,AF,8E,7E,66,4F,EC,AD,46,98,05,BB,3C,E5,6F,78,CC,A5,69,48,9C,3D,99,59,AF,E2,73,56,79,21,AC,18,32,05,D1,A6,13,AE,50,A6,84,FC,42,17,7A,41,7C,82,36,56,9D,6D,BB,43,1F,48,B9,79,D7,3F,2A,08,6C,A4,CE,0A,93,2F,69,5D,00,8E,A0,B7,B4,84,92,9A,B8,4D,08,27,C2,66,AB,94,36,60,9A,BD,91,A4,0B,57,C0,1C,D6,62,83,4C,BD,84,DF,61,BD,41,61,74,E5,C5,03,CC,8F,97,D2,A2,18,95,4F,52,3D,29,25,23,E9,96,17,45,3A,F8,85,12,0B,40,34,C8,45,5F,67,8E,EE,96,FC,0C,C0,3B,62,94,0D,99,38,99,85,F2,1C,F9,CD,4C,2B,52,CF,F2,B9,09,71,12,5B,87,99,65,EE,E5,E1,5E,55,E8,3A,04,19,66,AA,27,2C,0F,EC,35,4D,1F,D7,9D,72,6C,90,9A,E3,DA,DA,10,6E,06,C8,31,DE,34,EC,57,47,EE,9F,79,D5,1E,C7,41,12,30,57,2A,9A,D9,06,FE,60,81,C8,E2,61,16,51,9B,BA,EA,9E,96,ED,A9,29,84,68,D2,EC,1A,79,85,92,E4,4E,9C,43,71,67,6E,B9,6D,A1,17,50,4A,36,05,66,50,92,98,E6,04,16,43,BB,DA,35,5A,4E,F6,C1,3A,19,1A,0B,04,C0,F1,FD,71,8D,C4,82,96,28,7E,A9,00,25,7D,24,64,11,18,FD,BB,AC,BE,A2,F1,C4,63,00,98,F6,09,BB,E5,DE,0A,B5,25,5F,46,B8,43,1D,50,F7,A6,88,47,DE,45,B5,F2,58,9E,BE,6E,FB,2B,AC,63,E2,55,FD,AD,4D,FF,AF,59,2E,7D,88,D2,75,88,BE,91,95,04,F5,FA,52,B0,07,61,F1,AB,CE,FD,DC,1E,32,5D,23,AD,2D,30,0B,C6,F7,89,8A,AE,B6,8E,89,A2,0A,1A,A8,D8,0F,BD,B5,A3,C4,B6,B7,23,06,3C,E8,C9,BC,8C,5C,C4,AC,EA,28,25,9C,9D,2E,5D,FD,0D,44,86,76,5F,1C,05,64,BB,A5,AE,0D,46,CF,34,C3,4F,12,A8,29,64,CA,28,43,EA,53,DA,4B,EC,E2,2A,B1,50,85,13,9A,9A,DB,6C,21,45,98,9B,AC,1B,00,86,2B,B5,19,60,B8,C0,33,EC,51,4F,93,0F,26,79,AA,F5,32,3A,52,2B,DA,8C,D8,04,12,8D,DC,9B,84,58,8C,38,78,EA,CB,84,3F,05,49,C4,63,83,98,CB,BF,66,3E,1F,2F,36,EC,E3,9D,E6,3F,00,DC,93,A8,55,B0,73,86,61,6C,D3,3F,DD,0C,C3,43,A0,C0,46,65,78,D9,A8,45,5E,03,43,59,9C,58,BB,C0,20,BA,C3,59,8B,20,A5,4B,17,D0,73,53,2A,D7,85,85,89,74,5B,17,48,FF,CD,42,4D,AC,4A,79,44,B9,66,DC,19,73,5E,27,91,0F,CD,9A,E9,CE,5F,E9,FA,17,53,C2,46,C3,10,D0,C8,03,D2,8C,45,3C,2E,EE,B8,AD,10,19,D9,E1,45,34,7C,7C,D4,21,89,B8,E1,43,87,55,60,96,CF,0A,25,7C,96,81,A8,C8,B5,44,C1,9A,24,FA,F3,5F,B0,9E,65,ED,CE,28,66,F9,BB,CD,08,37,A2,93,26,AB,6C,BF,35,8D,C0,81,F4,95,59,83,6E,F2,0C,B8,C3,38,81,61,2D,F7,4B,11,F7,95,FF,6C,65,A2,46,EC,87,A8,DA,23,50,BC,9F,E6,2C,6C,AD,A4,98,0E,B1,EB,CA,D9,71,0B,F4,14,8C,8E,46,54,48,8A,35,E3,F5,60,61,E7,95,10,F9,33,76,73,96,C6,3E,12,48,C7,11,BB,F4,2E,2C,33,D0,97,1B,D7,AD,AA,9C,E4,24,BD,A6,79,03,ED,88,AE,BA,32,E0,6C,E2,1F,93,B0,59,E0,CE,5D,33,EA,5E,A7,41,EA,30,9D,75,CB,44,3A,48,98,8F,02,A7,C2,6C,89,80,78,B0,41,8B,44,23,15,D6,D7,9E,20,61,9F,0C,F0,EE,64,D8,A0,08,07,30,8F,2A,C4,D1,23,9A,67,32,42,D2,C2,AC,28,65,3F,A2,D3,92,FC,24,24,4E,49,5B,6C,A9,58,04,A5,24,4B,46,7B,4B,D3,ED,AC,CB,AE,C5,5D,FA,75,8E,B8,D4,3C,46,0A,A0,B8,15,F3,53,BF,C2,67,83,58,11,8C,A0,33,EF,6F,2A,23,F5,FE,DA,A0,A3,F2,8E,AD,2C,70,14,A5,49,83,2C,1E,F9,C7,6E,E9,FD,D5,64,E5,D7,79,1A,58,85,86,3B,15,82,5C,61,37,08,8D,95,EE,BA,04,5E,A5,E8,94,32,39,6D,F3,5C,79,55,49,7D,67,67,91,A8,FB,05,06,00,92,A9,02,93,92,03,D3,B7,AD,CA,A1,80,CA,AD,57,2F,56,D3,63,46,4D,72,ED,F0,0F,47,59,28,BD,A6,9B,95,8F,A5,E3,BC,42,A1,E7,BE,F1,9B,A2,01,5F,BE,88,7D,F1,8C,AA,B4,63,7B,40,83,B0,85,0E,3A,58,71,09,17,8D,4D,6F,EB,19,36,B4,71,9C,2E,A4,DE,BE,6A,47,4C,F7,AE,B7,93,3A,ED,8A,FF,35,DD,7A,A3,40,1C,7C,2D,1E,97,4B,31,04,FA,53,28,7A,54,08,46,71,6A,23,F6,88,B9,FB,8D,F2,1A,CD,B7,E7,DA,21,A4,99,4C,77,BF,F8,19,61,D0,5B,E0,B0,5C,3A,9E,15,8F,AD,58,CA,93,59,A8,79,F0,2A,1E,89,B3,21,64,68,73,99,AA,08,51,73,A1,D0,1A,14,42,FD,0D,EC,42,23,32,A6,C5,7A,C2,CC,6C,A0,1E,46,0A,82,47,11,54,60,7A,E2,08,99,01,B1,B3,40,68,D9,44,EF,B0,7F,A2,E6,79,6C,F5,AE,6C,8D,66,F6,10,E8,B5,51,B2,BD,42,95,94,E9,45,7B,61,46,87,1C,30,12,3F,BC,3E,69,A7,90,52,99,A3,EA,EA,78,4F,A9,86,67,4F,41,1A,AA,B9,26,39,12,96,32,9C,50,61,F3,68,90,DD,38,CA,74,C1,B6,C7,31,EA,D3,53,60,AD,4C,F0,CA,3E,0E,31,9C,D3,C7,31,9F,2A,8F,D7,34,A6,8A,0B,4C,05,7E,5E,40,73,47,08,D4,CF,1F,26,CF,3B,B5,75,61,E3,98,21,95,8B,3B,1D,82,08,53,C9,85,93,2B,96,B9,DF,7A,CF,C2,68,C0,84,3C,30,71,3C,39,53,F8,87,1A,76,45,24,8C,E2,56,56,1F,07,D6,47,B2,CB,BE,9C,26,29,7F,66,16,88,8D,A9,0C,AA,4E,7A,01,BC,53,BA,F6,1F,8E,AF,59,87,1E,B6,EE,99,B3,C8,38,E6,6B,E0,84,7F,38,38,F4,AA,D0,9A,4B,77,15,C4,99,73,A9,23,9A,7A,63,D4,F3,CF,76,D7,49,CA,F4,AC,65,99,DB,71,B4,9A,60,CC,57,9C,5E,1C,A3,A4,0A,12,16,1A,0C,AA,EA,15,1D,1F,06,7A,BD,36,3B,33,9A,94,AA,C8,95,4C,AD,7F,C4,19,72,B1,38,8E,24,A6,60,9D,71,17,2B,ED,15,D6,A3,D0,9E,65,7F,66,27,5E,58,1A,0E,4C,A9,EF,4F,1F,7D,47,75,1B,84,2B,B6,93,79,BC,3D,70,31,23,83,37,A0,FD,AE,54,32,25,C3,26,C4,45,B6,9E,C3,42,F8,09,2B,8C,9A,1D,79,85,68,51,A5,CC,10,3A,99,FF,85,C2,1F,A4,55,4C,FA,58,08,CC,BF,31,9C,6D,57,C0,CA,F1,FA,59,EA,05,25,EB,CC,0D,FC,97,A1,35,6C,0A,F3,50,17,2A,69,56,9F,AA,E1,BB,EE,27,EE,32,3D,CD,15,F9,07,AD,60,6C,96,69,9D,FA,39,67,C9,AE,11,B9,15,D0,32,12,21,FF,0B,F4,D6,09,DB,00,18,7F,40,A7,B0,FC,E3,1D,6D,BD,1D,BF,E0,35,92,50,4A,9D,25,63,3B,64,34,12,41,85,6B,25,D7,DF,3F,73,C6,69,7F,94,49,FC,15,EB,E1,74,5B,2A,86,83,37,03,43,E5,46,E2,70,78,3F,E0,7C,33,2C,39,2B,8E,76,F1,5D,5C,7A,34,C3,15,20,DE,CB,B5,6A,21,F1,EA,F1,24,99,D7,57,B6,DF,B2,63,00,ED,77,3E,E4,D7,AA,CE,91,92,09,8D,DA,72,CE,33,69,B3,9D,E4,0C,D3,D9,48,7C,22,FF,BA,9D,65,0E,51,AB,DD,AB,20,F9,3C,1A,5D,96,16,E5,52,75,67,33,F5,BC,99,81,28,2E,E1,40,7C,E0,E6,44,A2,B8,72,5B,65,87,9E,5A,20,BE,40,6A,EA,81,53,E8,29,94,2B,7B,4D,A3,AD,EC,D1,20,8D,7D,B9,2C,04,30,44,51,E4,2A,48,C8,98,2A,08,A7,6D,24,FB,3E,2F,A2,CB,50,CF,D4,4D,48,80,06,E2,D2,5C,4C,8C,F9,99,3B,96,0E,9F,61,63,C4,30,FD,05,D5,5F,B1,5A,27,D7,41,9C,03,3A,C4,9A,91,EA,F6,01,85,92,F4,94,37,AD,2F,AC,55,20,7F,8A,2E,14,17,15,0F,ED,36,A0,29,3D,A0,FD,76,2B,EA,08,17,F8,DD,63,F4,6D,1E,9E,24,A3,CC,9C,BB,40,AB,F1,C9,CC,9D,C5,7C,3B,9D,F2,87,79,72,4A,6C,7D,4A,AD,0C,26,5D,E6,25,8C,13,62,49,5E,58,CD,D1,5A,AD,41,9E,03,A2,20,AD,86,33,1E,57,A0,7D,3B,C9,DC,00,D2,10,CF,4E,B3,19,F4,5F,DB,03,CE,4F,54,10,1A,B1,2D,71,8E,03,41,42,78,86,97,14,65,00,21,7F,DE,8B,C1,B3,DD,2B,4F,BB,66,0E,FB,47,F0,8E,1A,0C,E3,F7,14,1E,2E,0A,A1,4B,46,CA,F1,A2,CF,C7,DC,A6,18,B3,49,05,48,6C,38,A0,D5,F4,BD,EF,4F,C0,0B,AC,7F,92,BA,D5,F6,82,E1,B4,25,2B,56,59,68,84,55,12,B2,05,CD,B3,BD,10,AD,CB,9C,7A,07,8F,1C,1E,38,00,04,07,B5,F5,7B,87,7E,45,21,08,9A,70,53,53,DF,D4,D3,A3,8B,A9,F8,8A,08,6E,08,81,74,EF,B6,EC,18,BB,8D,C1,42,99,91,0F,B8,94,C0,B9,3E,D1,20,63,82,3E,14,9F,70,30,74,D2,C1,E8,D5,E4,F3,C3,ED,58,37,9F,F3,12,FA,3B,F0,20,93,B2,6D,25,E9,F9,0E,F2,30,CA,A4,03,74,8B,D1,12,BE,3F,EC,03,96,30,8B,8A,3A,B9,3C,DC,C3,46,48,53,F7,43,C1,DA,48,9A,CB,10,CD,9F,82,3B,83,E6,83,C0,1F,13,F4,D8,A7,ED,06,9E,82,4C,11,79,DA,F0,26,F8,BA,7E,8B,8D,AC,9B,1C,E3,B0,81,EA,F1,14,D8,27,0A,EF,2D,19,FE,6D,81,9C,68,AE,AF,D0,4D,F5,2F,D0,81,56,89,28,67,57,F5,3E,61,77,D4,03,EB,75,28,0F,E2,FE,17,E9,C4,EE,67,A8,11,15,83,54,14,41,6D,9C,FF,B3,76,18,85,D3,84,55,FD,0F,56,3B,FF,DE,5E,5E,60,E2,8A,D3,5E,23,08,A6,56,F5,83,93,27,95,6B,0D,11,B7,DA,95,94,10,FE,1D,72,62,D5,8B,91,65,A2,B1,82,29,D0,18,94,A6,CA,64,AF,10,AA,FF,B7,41,94,D3,4C,F3,5E,E3,39,D0,C2,F7,07,7F,BF,F5,47,1C,1D,15,32,CE,68,D7,EC,BE,42,78,29,BF,3C,B7,0C,C5,EB,FC,F8,AC,A7,43,F5,A1,7E,BD,80,12,BD,4F,F3,11,57,73,31,74,D9,86,39,4D,11,86,FC,FA,2F,21,D3,B1,40,68,9E,32,D7,72,EA,A2,6E,75,C5,88,00,7A,3F,18,89,14,50,BE,BE,7D,18,27,80,35,F8,B4,8E,11,AE,78,3B,B1,BA,D5,34,FC,84,F2,9C,6E,3A,1A,06,07,51,DD,A5,7D,27,22,2E,E6,94,2C,E4,7C,FE,62,B0,FE,0D,49,0C,C5,7E,82,3D,28,08,B1,FD,06,FE,8D,46,15,24,81,08,1A,D6,28,E1,D4,B9,F0,AB,33,BA,FA,FB,58,57,77,BF,0A,5D,AC,90,8D,77,9C,64,CD,F7,07,9E,21,98,DC,B1,D4,EA,58,B1,F7,67,91,DA,BE,1E,5F,A0,B7,41,FC,31,78,F0,F3,F0,73,15,C1,B6,10,FF,08,55,B8,5F,1E,4B,00,31,DE,E9,A3,E1,CF,E1,4F,C8,52,02,9B,20,4C,47,CD,6C,34,1E,AF,82,96,D1,61,38,F1,BC,5E,06,94,25,F8,67,CA,7A,11,6D,99,BE,B8,BC,80,93,61,19,F2,06,F3,75,B8,0A,B9,78,69,2F,88,9B,61,52,5C,4F,66,13,66,0D,CF,21,72,02,DA,21,D9,67,56,3F,A5,24,F3,00,17,A9,B9,18,13,30,52,94,80,AE,75,EB,37,57,06,1A,9D,F5,B5,37,50,12,70,76,1A,15,4B,30,9E,3C,20,8C,F9,5E,9E,F1,9E,44,DE,50,4C,40,FA,33,C0,79,5F,52,72,D9,A3,71,2A,7F,B8,34,D9,24,94,E0,6A,82,71,8B,68,5A,02,F2,DE,E1,68,C2,35,DA,0A,41,83,5D,35,B5,F9,B6,8D,82,F9,82,56,C1,2C,65,D9,49,83,87,EF,39,EE,FC,04,DB,D0,9A,9C,6B,E6,C6,64,4A,4F,C7,35,0D,4B,1A,73,07,36,23,D5,07,72,88,E9,B3,B9,7A,7F,19,82,9E,CE,BE,4B,97,EA,36,D6,CB,30,8C,7B,83,26,6B,84,33,D2,7A,3E,0C,65,C8,6E,75,D4,AF,6F,08,41,BC,EF,2F,58,A0,6F,BE,67,93,79,D1,CC,57,73,F6,15,F0,8F,D8,65,54,34,9A,F7,60,8A,00,6C,1F,B3,8E,10,4E,AF,F2,97,1B,8B,19,D0,B5,E3,CF,E1,28,7C,5A,9C,03,C1,11,5C,49,A0,10,69,7A,70,86,BA,AE,63,01,78,AA,B4,4C,95,29,05,48,36,27,58,E9,27,30,CC,C9,9E,E4,35,1F,4B,7B,F3,6D,C1,B1,12,64,36,1D,B8,C0,76,14,86,A6,59,4A,1C,91,E7,CC,D0,34,F2,9C,E6,5E,F3,E2,5E,81,8F,48,2F,B4,8A,34,11,8E,A7,69,CB,35,F0,6B,4B,9F,46,33,D9,75,15,BB,44,70,00,29,51,9B,BF,FE,2C,9A,2B,CD,00,4B,B3,CB,0F,3E,9C,69,2F,EC,B3,9A,F0,98,65,D0,1B,A6,AF,B6,77,D8,C5,7D,CA,20,06,E1,6B,F0,07,33,CB,03,13,7C,30,90,4D,E5,98,06,2B,9E,4B,F3,A3,1E,9B,52,02,20,EB,C7,9C,88,38,32,8F,22,62,6E,D1,44,D3,B0,8F,FB,FE,4E,F3,9D,67,98,D0,BF,9E,B9,2B,D5,BF,96,AF,5E,B4,75,A0,D2,FE,F8,DA,6E,D5,75,E5,50,70,DC,89,A9,BA,8C,2B,42,74,78,95,C9,64,5E,CE,23,DE,BF,16,5D,11,CA,AD,3D,5D,AF,46,1A,4C,50,EF,5C,74,6C,98,2A,C5,4B,D2,71,35,AD,E0,09,B9,DF,A0,1E,76,7D,7A,29,88,DA,74,D6,4A,C6,A6,61,58,C2,1F,91,14,37,7D,AE,34,3B,FD,9A,6A,7B,5D,10,E1,C2,6A,20,91,BF,14,06,4B,D3,61,E8,88,77,E1,06,07,CB,6E,CD,10,23,CD,E4,EE,0D,55,5A,50,ED,BC,80,D7,BB,1B,CF,5B,96,90,40,F4,1C,B7,D4,AE,D0,DC,2E,8E,A2,34,6B,B7,D5,84,E8,5E,55,29,FB,5A,CF,58,DD,9A,C8,ED,46,99,39,6D,C6,29,79,D2,20,CA,E6,09,10,B3,84,5F,B4,26,B7,47,63,64,0D,05,6E,35,24,A2,38,CB,D1,9B,06,67,F4,6B,0C,CC,07,EF,4D,C8,79,CC,46,74,0A,3D,BA,82,A1,05,CB,4C,B9,79,77,BF,44,C6,7B,5C,33,BF,C1,61,99,9D,76,B9,1F,66,22,63,05,62,8A,84,B9,B6,53,59,07,E3,C6,5B,3B,41,CE,48,5A,BB,3E,00,82,77,DF,76,2D,FB,68,98,F2,E3,B6,AE,27,27,13,79,BC,03,03,C4,98,80,B3,9D,1D,C3,25,17,8E,E7,19,D0,61,A9,BC,A0,15,74,E0,AE,7F,BC,5A,8E,A6,D6,B9,79,EF,32,3B,47,6C,AF,CD,0E,CE,1C,4E,A7,9E,25,0B,A3,1D,A3,94,08,80,B1,2F,4A,30,D0,61,8B,40,A3,AF,BE,51,E3,7C,DC,0D,11,F1,6B,66,E3,DE,18,A4,E9,A0,D2,35,F5,34,73,F9,05,84,C7,7F,DD,71,38,25,0A,80,EF,B8,B3,ED,D2,D3,DB,C4,7B,AC,A0,54,77,4B,01,AF,04,6B,50,43,26,A5,59,5B,CC,A7,68,00,AB,2D,AC,45,A0,0E,DB,1C,67,96,3E,4D,AB,70,48,AF,3A,EE,02,CE,DE,A6,2D,4A,86,55,BE,99,21,78,45,D2,33,E6,92,C2,7B,25,D1,93,CB,28,EB,8A,80,07,84,BA,3B,4C,4B,5E,4D,C7,64,E0,C6,C4,0F,71,67,73,7F,FD,AF,D0,51,E7,6E,B2,FE,37,DC,66,05,53,D4,BB,84,C4,48,F7,F0,B5,50,64,E5,F6,4D,32,47,B7,94,3E,30,52,B5,19,1B,6A,17,44,88,8F,23,06,65,D7,74,86,51,12,B2,90,B4,DD,24,4E,AA,C2,E2,DE,CC,82,CA,4B,29,9C,97,8D,F9,F0,BA,13,D2,98,0C,97,7C,80,67,88,CE,35,43,F5,CB,EF,91,26,EB,11,7E,E7,3A,6E,02,EF,38,2A,FF,1D,02,75,33,8D,51,3B,01,6B,34,92,20,1C,9B,99,23,04,65,03,12,5F,07,D2,0C,7A,0A,06,04,AC,C9,9C,C2,40,90,C8,EC,54,D7,CB,6D,C0,E6,E4,85,5E,38,6D,5E,26,2F,2F,40,41,2B,15,4E,16,D4,99,70,B9,80,D2,CC,60,29,1B,9C,E0,1B,4A,47,C4,01,CB,52,30,D2,2B,34,89,D6,FB,43,B3,DE,C1,CE,74,AF,FD,B7,AA,93,F6,CE,AD,AB,8B,A3,5E,1F,C2,73,D7,1E,8C,B2,B7,A6,DE,0D,6A,25,64,64,55,DA,EC,E1,CC,9F,F5,BA,7B,CB,E1,0F,C7,E3,D8,21,8F,86,AD,16,4E,BF,F5,AE,02,A0,7F,AF,0B,72,92,F7,84,46,32,70,FA,FC,A7,5D,91,55,92,4C,5C,E6,1C,6A,B3,8C,3E,B0,35,8E,FD,45,04,7D,17,2D,C1,A8,FA,32,55,95,A0,50,AE,72,6E,5B,09,DE,81,03,55,AA,29,DC,CA,B1,9E,A3,77,78,CC,96,49,19,E2,32,AE,9D,02,1E,CE,95,AF,37,D0,5B,F3,D9,A7,99,30,97,72,16,51,B3,E0,D0,88,39,BC,E6,CC,30,F4,82,4A,73,5D,27,BB,A7,5C,26,69,AE,A2,6F,0A,A9,C2,D3,76,AE,6E,D6,24,A5,85,8B,F8,F2,D9,6F,2B,53,E2,E2,51,FB,83,54,46,D9,0D,EA,D1,80,14,D0,B9,70,E2,7E,BA,DF,CF,2E,41,0C,28,75,7C,19,AA,65,92,7F,30,BF,12,96,D4,3C,8B,AF,88,19,36,24,F4,B3,E2,A6,A6,12,A3,57,7F,2C,69,E8,91,98,BE,17,3C,1C,17,C0,45,88,9A,6C,47,84,D2,58,A2,57,5C,F6,12,2A,C8,FD,FD,42,22,D0,D8,A2,F4,56,AE,5A,D7,E8,30,F7,B5,13,0F,2E,48,EB,CA,2E,77,17,21,87,8D,F9,D3,52,BB,7E,A1,BA,DB,49,16,D4,B7,B1,9E,0F,0A,E5,35,09,97,A2,46,F4,A4,E7,2A,36,C9,57,2A,98,5D,37,3A,34,E8,30,26,80,E0,23,E4,CE,63,FC,DC,63,8F,18,AA,9C,7B,10,61,C1,4C,B5,FD,D9,A6,B4,76,34,B1,11,E7,30,11,C2,A6,A6,AC,CE,E5,5B,00,E7,BF,4A,D2,4F,5F,93,77,75,40,8D,58,5A,32,71,E7,88,E2,34,7C,31,77,8D,B0,8A,F2,96,CB,9B,1C,90,AF,B2,D7,DE,DA,6F,22,7D,37,15,E7,F0,E7,6F,96,C5,5A,1A,59,99,E7,D5,BB,54,49,56,91,01,0C,C6,4F,A0,A4,C0,3E,31,88,8C,DC,73,A9,FB,F5,35,AF,8D,4C,B3,37,35,58,2A,53,C5,45,B6,7F,6B,30,CC,B9,E9,4F,68,14,5A,1C,CA,52,AA,55,1F,FE,CB,4C,13,19,80,67,47,BE,27,3A,A1,28,46,5A,99,04,E8,6C,9D,84,32,B8,D0,F2,48,0C,42,9E,B5,BE,CB,6D,5E,43,7D,25,53,A2,FE,70,79,6E,DA,58,71,E3,66,83,92,06,85,79,00,8C,75,5F,18,35,6B,4E,20,AF,E2,82,78,33,A5,7B,DB,21,32,C8,47,16,A3,1D,F6,DE,DE,3C,03,34,84,5F,B5,83,C7,EF,0C,01,11,BE,08,CA,AB,CB,F1,BE,65,F2,FE,69,46,D6,BA,3C,B6,53,EE,FE,6A,35,EB,23,11,9E,05,79,5F,D5,E3,5A,D4,84,E3,20,1A,45,91,F5,69,79,67,AA,BA,A3,58,4D,1F,1F,30,48,FA,6D,57,12,EA,EB,41,D6,E1,3D,9C,85,76,40,90,3D,9D,2C,58,2B,EB,14,F4,20,62,83,14,35,67,94,35,2B,DD,5F,78,5A,52,55,C3,7D,A1,BC,77,26,19,D6,70,0A,C9,B4,9C,35,85,6D,C1,BC,C1,B2,51,ED,24,29,C6,51,D6,D5,9A,AA,7E,D6,E8,3A,C3,F9,EB,EA,E3,72,36,D4,3C,97,A4,EE,7A,E5,55,F6,DB,9C,A5,0D,DF,E6,83,AA,32,62,8F,9C,E2,20,23,FD,36,6A,D7,D1,E1,17,55,E1,54,BF,D9,E6,FD,52,44,8D,BB,01,0E,59,A4,82,41,75,78,E1,C4,08,48,FD,BE,2D,42,CF,84,52,55,D2,F3,75,BF,34,9C,E5,CE,9E,D9,FA,9A,CE,21,DC,8C,BD,D3,C2,28,F8,54,D2,3C,3F,1B,A6,69,86,0B,FE,06,EA,30,56,23,36,13,2E,87,65,A8,23,3E,17,05,01,6C,CA,6F,B3,DE,B8,D0,A6,A6,65,1A,B7,38,DF,F1,E5,9E,F9,D6,64,1D,39,78,97,FF,53,CF,1A,1A,AD,DC,E3,D5,38,5C,7F,A3,A4,36,0F,1C,BB,91,D3,48,2F,32,AD,08,14,29,BB,B8,AC,6B,32,2E,8D,05,17,AF,28,50,11,CB,AD,CE,62,D2,EB,2D,0F,06,5E,A0,B0,74,58,31,07,AD,E7,EA,7A,64,A3,21,0D,D4,25,C6,3E,B0,AD,C3,FF,AC,F3,67,09,D5,0E,7D,09,EC,8B,E6,3F,63,74,31,A2,ED,02,8D,AA,75,2A,30,7E,AB,68,40,B2,77,D0,8B,F5,7B,FB,7A,27,AD,3A,AB,5D,DD,6A,1A,5F,43,19,36,BA,41,30,66,9E,2D,AC,B8,5F,6F,38,49,34,46,FA,F4,B8,B1,9B,0B,8F,4D,8A,37,C4,5A,B5,AD,4A,FD,B9,4B,13,5B,2E,0C,75,A7,3D,4D,66,95,D6,F0,8A,A4,59,08,E9,7C,A3,29,BB,A1,6E,08,37,64,D6,38,88,9D,53,BA,7D,3C,72,8A,0B,CA,A1,92,31,01,9C,8E,A1,2D,B7,8B,79,40,44,8F,C9,D3,8E,80,A1,25,90,FE,71,65,BD,07,2C,AF,E2,64,65,DB,4E,A0,F8,27,AE,C5,F0,53,38,44,51,6E,5A,48,95,98,2C,CF,F2,C1,9E,15,51,04,BC,46,39,FD,BE,1B,55,39,0B,13,3F,B3,71,2E,1C,91,56,CE,0D,B8,8E,B8,61,87,EF,FD,E8,40,6E,D5,03,3B,6A,39,F7,A0,E7,CD,53,34,34,FC,5C,C2,23,2E,25,DB,F2,7C,C1,B7,A5,6D,A7,89,55,AB,8E,5E,FB,EF,4F,CF,A2,53,3D,19,EB,B2,0A,16,84,C7,02,7F,9E,85,8F,47,3E,3E,B7,D2,7B,FB,D7,3B,03,00,B1,74,FE,38,1D,D2,09,30,93,2B,7E,B7,A3,08,78,ED,FC,71,01,A3,96,6B,36,FD,9E,46,32,47,A1,EC,79,6F,35,20,87,9D,EA,59,2E,4F,47,10,1F,C8,57,CB,A1,81,35,CF,30,D8,11,6E,6D,E8,46,BD,E1,FC,08,F0,FA,FC,D9,AA,36,91,DE,F2,CD,53,21,FF,40,D1,D7,38,DA,52,7F,20,45,C7,AC,37,4E,D4,3A,B2,A3,D5,13,2A,EF,70,13,64,18,BA,7C,89,31,CB,D6,95,A1,C3,5E,21,68,AE,2A,42,B7,EA,33,7D,95,B2,79,3F,35,3F,96,52,3C,F8,49,C9,E5,8A,8A,C2,BD,10,61,00,8F,41,4B,71,34,2E,28,0B,EE,90,09,F8,8E,8E,6B,0E,53,F6,B7,55,AB,16,D7,05,CB,06,65,D4,6F,02,52,3C,30,B7,A4,1F,19,EC,43,5C,D7,D2,75,7F,E7,4D,2D,02,E6,B9,59,7B,09,AE,79,E5,A7,2B,FA,B1,43,54,B6,AE,A0,B0,65,38,85,CF,29,34,23,E4,FB,D8,6C,CC,92,2C,60,8A,EE,45,33,30,7B,66,82,14,59,0E,E6,1B,F7,5B,AF,8A,2D,4F,12,C6,EF,1B,72,A7,33,F7,9F,9D,CC,4A,AB,4D,44,2D,F1,DD,4C,30,EE,1F,69,EB,9E,52,D2,E0,79,BF,21,B3,87,8E,FC,0A,61,31,EA,E2,FD,19,96,89,F0,9C,09,29,B5,A4,13,AC,70,90,88,97,09,50,7E,D5,C4,58,F1,E9,1B,F7,40,84,BE,88,76,E0,0E,8F,C6,07,19,B9,E2,2C,24,80,09,2A,4E,E9,EE,31,BE,EA,32,68,E9,F8,29,A5,81,05,B4,DD,93,17,25,01,F3,01,C0,CE,0F,76,43,28,1B,C7,92,19,EA,14,CC,D1,C8,6F,6C,E4,EB,B4,3A,79,FE,3E,ED,2E,10,63,96,55,7E,E6,0F,9D,04,0D,13,AE,C8,2C,85,EC,E0,B6,C3,D8,F8,95,4C,00,50,F5,95,DF,F1,AD,09,FC,90,A7,12,57,56,95,AD,4B,CC,7C,56,E6,85,2D,B0,7A,51,84,64,A1,CF,5E,7C,2C,A7,37,8D,E4,C6,55,25,D2,C4,9E,53,D5,6C,5F,93,B7,12,EE,9A,33,30,D9,89,C7,94,A4,1A,2A,21,BB,4C,83,37,63,91,C5,7B,92,31,00,06,36,4D,88,BD,86,F8,67,15,88,59,42,70,D7,A5,ED,AD,83,C4,3A,7E,65,37,A8,CB,9C,A6,7A,41,B8,B9,70,B7,5D,69,20,54,D8,67,94,60,4F,FF,BF,F4,60,FA,5D,D9,7E,B7,12,CE,7C,A2,41,F0,C7,D7,9B,4D,95,AE,44,37,41,A3,FA,69,BA,57,AD,C5,DA,77,32,D7,43,50,DE,EC,6B,38,01,C7,F6,20,E7,C9,46,EC,70,4B,65,F0,BF,70,80,CA,F3,A8,7C,00,11,33,D7,22,01,59,21,89,5B,26,C0,55,6C,79,11,92,7A,E9,8D,08,6A,1F,DC,A6,F7,F6,63,73,FB,F4,A2,EA,E8,D3,43,53,FF,E4,A2,B2,81,6D,13,26,18,77,C0,22,25,E0,E2,28,A6,73,19,1E,39,D5,F5,89,23,D5,57,6F,48,7B,CB,D4,CF,C0,67,EA,AF,81,54,19,E2,D2,62,7B,BE,34,2B,BC,1B,96,16,18,4F,52,47,CA,F4,99,DA,37,75,2B,EF,81,A1,9B,44,D8,FB,D3,E0,64,1E,7F,31,F9,80,E1,15,69,09,21,A7,15,1A,22,10,69,1E,D0,FF,B3,AB,06,6C,EC,BB,90,18,1B,75,D2,A3,EE,0E,2D,66,77,D9,D5,07,EC,84,64,EE,A6,B2,E1,3C,D3,76,F0,0C,7F,CB,D7,3E,D1,8D,18,9F,23,03,90,D5,E1,2B,19,6D,97,B4,6C,A0,F3,6F,D5,BD,FC,95,02,6D,9A,20,77,41,AD,C4,44,13,D3,58,3B,B8,53,8C,61,A4,C3,B1,D4,DF,5E,1C,FD,EB,2C,11,D3,EC,E9,EC,35,4C,1C,EF,0F,89,A2,53,8E,C0,6F,2E,0F,B4,9E,5E,26,FD,2E,D6,82,4E,34,3B,D8,49,AA,FC,C7,C3,A3,34,93,DB,73,23,31,40,EC,0B,38,A0,56,82,02,43,96,D8,4F,FF,39,92,C2,58,FC,6F,BE,5A,17,85,19,7E,48,0F,24,DF,99,5A,26,D3,3E,1D,92,51,C5,3D,E6,AF,EA,15,33,CE,48,FB,63,95,6D,7E,FA,6B,B8,E4,20,F2,BF,FD,30,17,07,8A,47,EA,82,88,23,14,45,32,33,EF,7D,42,33,7D,76,C9,8D,0E,DE,BE,D5,7B,BB,B4,2A,B1,EA,B5,02,87,C7,A9,7D,A5,BF,74,E7,F9,7F,52,A7,9D,09,A3,7B,85,C4,34,35,3D,F6,75,16,23,F6,48,27,1B,0B,E6,96,F3,43,C7,55,02,70,64,43,7B,4C,89,F2,52,AD,5A,E3,F3,B1,46,7D,44,98,D0,14,D2,79,23,B0,55,4E,FA,AD,FA,89,CC,19,A0,A7,B0,FD,E3,11,5C,57,40,7D,A4,41,54,AB,DF,B5,1B,14,D5,67,BC,8E,4C,41,B1,5E,A6,9E,01,6F,BC,12,3A,95,B9,AC,CB,7A,C6,4B,10,A7,2D,72,E7,A5,DC,A7,BF,8C,42,0F,DD,5A,5A,85,9D,F7,AE,95,5D,E2,8C,A1,1E,26,A1,8C,F8,F6,47,6D,EE,4D,83,A2,6D,05,C7,46,C5,C0,7B,F0,32,FC,15,32,19,8E,9B,6D,26,93,8E,65,F4,BA,B6,B1,75,8D,6F,BD,D9,5C,4A,68,C8,6F,74,A8,A5,9A,BE,D6,E6,80,C6,F2,23,4E,E9,1A,69,EB,7B,3D,27,A6,C1,64,70,06,8F,7C,28,3D,4A,09,F3,D1,68,BB,A7,63,A4,31,8E,78,7F,B9,46,60,51,A3,72,C1,91,4A,25,9F,37,E6,06,0E,39,0B,4F,2B,6A,F0,B1,64,61,C9,69,F6,75,4B,A8,D0,3F,56,42,94,9F,25,CA,14,89,B6,18,5E,3E,F8,99,CD,DA,00,D2,3D,14,FE,D1,4E,E7,6B,01,9F,93,35,85,88,8A,0C,9D,E1,6C,11,D7,29,2B,69,23,21,65,30,C3,08,FF,25,BC,90,96,6B,A8,15,52,6B,49,B6,A0,B2,E0,07,6E,39,C6,93,96,5E,B5,6E,45,BF,9F,78,42,E5,90,CD,65,B5,BA,5C,ED,9C,5F,1A,CC,33,8F,34,2F,42,D4,EC,FB,37,09,E6,84,22,90,0C,2B,77,AB,6B,A4,8A,10,F8,B6,72,78,87,DD,8B,47,CD,82,72,77,EB,B0,56,6C,CB,F1,34,03,1C,E2,8F,5A,B4,AD,70,0A,1D,57,84,37,BE,AD,A3,94,64,DD,97,6B,ED,8B,DB,2B,17,6D,7F,ED,7D,81,42,72,22,E9,B3,25,49,0A,7C,63,11,57,98,71,EE,3B,2B,1B,E5,1D,1A,C3,E2,8D,A4,9F,3E,D8,E6,34,A2,6A,F5,FE,69,92,58,19,39,51,0D,F6,92,92,BA,42,09,D0,E2,57,A8,26,0D,BE,41,7D,3F,09,27,F2,F8,91,79,21,FF,9C,23,B9,D6,E3,C6,D8,B6,59,65,8C,D0,CF,51,36,43,B1,65,50,B2,96,93,07,20,58,81,58,22,F3,4F,84,02,E2,AD,8A,C6,10,9B,40,4F,5B,E5,1F,9A,40,C1,DE,F9,DA,26,66,E3,8A,29,07,70,6E,44,EE,76,93,0E,08,92,1E,D1,F8,A2,C3,70,69,C1,A5,A8,C6,9A,AA,4A,2F,50,79,6F,51,4D,3C,3D,D2,B1,A4,2E,32,62,00,1D,37,DC,24,69,32,4F,E1,D3,2C,A0,30,B6,7D,9D,F3,47,E8,C9,C8,23,52,EE,13,A1,13,B5,1A,1C,A6,4B,B8,39,CC,B6,1A,0A,F1,B0,C5,CC,7C,7B,D3,4A,1B,F3,2A,E7,D3,D8,DF,1B,97,69,7A,45,5D,7F,FB,56,C5,9A,B9,F5,85,85,83,13,53,C8,9C,21,0E,83,04,61,49,4A,43,3A,D4,31,34,FE,FA,92,FC,3C,2B,1D,9C,71,99,A6,47,9C,11,1D,C2,21,42,7E,58,45,DC,F9,07,E3,EC,A4,C4,6C,A1,FB,01,72,D5,53,0B,C0,56,C7,5B,52,92,4E,9F,0F,18,19,A4,5D,B2,A2,D9,9A,D7,72,CB,90,FB,F2,27,54,58,B1,F5,77,04,A6,3C,CF,16,2A,C8,D1,B9,6B,61,B3,F0,6C,81,10,B5,A7,CA,AD,48,4D,82,99,4B,42,14,AC,84,A5,B1,BB,63,5C,AD,85,51,70,3B,83,AC,89,74,88,42,79,E0,FB,21,7D,2E,A1,F9,22,F0,78,A6,D5,0C,62,07,27,9C,2F,C5,A1,68,5A,B8,B8,8C,91,48,A1,AB,EA,CF,6A,7A,75,F8,6E,60,1F,E2,BD,14,C9,C3,56,B9,A6,F0,9C,FB,D3,52,96,A7,F6,41,5C,5F,D2,4A,F4,A9,47,19,73,44,4D,58,AC,AB,AF,9E,77,40,17,01,38,DE,F5,F8,39,BC,4C,A7,E2,29,DA,FA,F5,18,84,DA,C2,10,1B,90,40,A3,EC,EF,AD,C8,7F,3E,78,6C,C8,C2,D5,DB,D7,AD,02,65,7C,A0,19,48,73,84,F8,41,23,46,2A,A2,B5,72,6A,A0,93,05,43,88,63,3C,D7,E8,B7,F1,02,08,7B,2D,37,FD,54,7B,C7,1E,DB,4A,FA,3D,16,BA,7C,AC,B2,D9,C9,97,4C,FE,D3,B2,59,A2,A3,00,33,69,04,3E,CE,E8,8E,04,AB,F3,41,CC,42,A5,43,29,7A,12,6C,7F,98,10,9B,F4,39,9D,8E,CF,C5,A4,F9,7D,E3,78,A7,AE,D9,FF,30,79,8B,9F,03,AE,EA,2A,FA,AF,76,5C,D2,BF,25,BA,25,C2,8E,14,2B,D9,CD,AB,DD,F4,FD,57,FE,9D,84,83,9E,21,AC,32,DB,DE,E1,FB,90,0E,F2,3B,41,7E,D9,47,B4,97,25,DB,F1,32,4B,15,6E,46,97,F8,E4,82,56,81,81,6D,0E,48,B4,9E,76,9A,53,04,DA,CF,BD,C9,28,AA,19,47,EE,57,11,57,40,88,41,88,54,48,F7,F5,04,50,40,FF,01,37,7A,9B,76,90,F4,8F,39,8E,60,EB,5D,58,47,48,7E,4D,D9,FA,D6,B1,29,E4,CB,22,81,3A,E0,0C,BB,6A,24,65,92,02,5B,5A,3A,5B,2F,A2,74,6C,16,33,57,81,85,F1,7B,69,4C,B3,37,D4,45,25,1F,D3,BF,06,47,0C,D2,EB,B6,E9,81,56,39,6D,A6,8A,23,77,F6,B3,AA,75,7F,F7,3F,57,FD,0A,16,33,59,33,83,36,A7,31,AF,0E,64,82,99,1D,EE,C3,47,E0,B4,CD,FD,BB,14,8E,B5,2C,47,FD,FA,63,7F,E3,F5,25,E3,32,24,32,64,2E,3B,95,3C,A3,C1,28,1E,F8,8D,C6,8D,96,EB,83,61,BE,18,79,7A,14,21,16,7A,37,45,5E,C0,05,6E,03,13,AE,3A,04,4B,AA,38,47,2A,6F,CA,7D,1F,BE,B0,9B,95,AB,BF,D7,64,FB,D7,10,04,8C,D6,82,0B,63,33,FE,C5,E9,5E,35,6B,90,E8,E6,52,56,DF,7F,CB,7E,2D,0F,FA,99,53,5A,80,68,68,F8,E9,00,3D,48,59,1E,16,CB,B3,6E,26,30,3F,31,19,23,8D,E5,0F,98,88,58,52,95,ED,FE,69,16,DB,EE,C8,B1,8D,E7,B8,C7,34,F0,F4,61,0A,88,A9,66,C5,67,80,28,0A,3E,34,7C,49,BB,B7,A7,B4,DC,52,C0,CF,68,4C,90,ED,D6,CD,30,6F,5F,C4,49,F3,73,F3,87,63,4A,3B,B6,E4,0D,74,E1,AD,45,6B,60,1F,BF,96,3E,1E,C2,A1,1D,78,54,B3,F7,69,E3,0E,1E,33,F5,6D,AA,9B,F9,81,D9,71,B7,7F,50,29,48,15,AD,51,70,93,6A,30,B8,20,83,F2,57,04,45,D5,1C,09,20,57,98,F4,0D,C7,42,D9,D3,1F,C2,1C,A2,EA,8C,76,0A,E2,B5,BE,3B,47,4D,8D,7A,E3,BC,C8,A6,74,ED,BB,58,B8,65,5B,C4,D1,B3,A0,EB,BA,29,87,DE,27,B8,D8,43,AC,1C,C6,35,51,95,24,E2,0F,9A,51,11,A4,3E,3E,5D,FF,CD,E0,62,BC,D1,7B,1C,C7,9E,C5,59,9A,16,5F,E0,22,A3,5E,74,63,C5,3E,05,84,8B,2B,4C,80,84,9A,2A,98,B8,D5,6F,47,32,08,68,D2,08,12,36,A7,9E,93,8C,E7,7F,93,F5,35,29,3B,DC,3C,1B,39,DD,5D,D5,5F,61,EA,17,B2,5A,B5,82,E1,30,5F,B8,56,34,72,EB,EF,7D,5D,22,AF,81,67,55,78,D1,5E,D0,58,19,DC,22,3F,40,73,C2,B6,00,72,0B,B1,EA,67,D1,49,D3,67,FE,E7,B4,52,12,ED,39,2E,B7,8F,A8,26,DF,79,1D,24,8E,97,F4,03,12,DE,40,10,FC,EA,19,B5,7F,44,06,8B,66,01,FE,FC,08,C8,8D,88,BD,8E,40,77,12,86,A6,00,F9,F6,74,0F,69,65,06,11,BD,1E,2B,83,61,8A,02,DF,50,25,45,E2,75,45,86,DE,51,FD,43,E4,A7,13,C7,8D,4F,D6,55,71,1F,D0,66,7B,39,7A,D5,A9,86,5A,22,7C,60,54,E4,BA,3C,05,D2,97,C6,A9,AB,B6,BB,D3,64,71,9C,31,B2,78,5A,28,64,BE,85,AE,AF,63,45,54,92,E7,77,6C,32,B7,98,92,BA,72,2F,0A,39,7E,F8,AB,F3,A6,05,91,7C,D9,FE,BA,22,BA,D8,B5,8F,2F,3E,8E,EE,F6,43,6B,36,19,8C,63,68,BF,37,C0,E7,2A,81,EC,FC,F7,2A,7B,B4,90,25,6D,A9,21,83,46,50,32,EA,A3,BB,E7,7B,46,DD,A3,39,58,1E,CB,98,0E,0B,AB,FA,65,0A,4C,90,A9,DA,B3,EB,CB,2A,9D,E5,66,C1,73,24,A9,D6,54,E0,DE,45,C5,EB,58,2D,8B,AD,90,E4,62,60,59,BD,BD,22,8B,14,7E,55,C4,5B,CE,20,33,FC,3A,31,56,E5,47,B3,1B,D4,7F,D5,2D,D0,AE,99,28,52,00,CB,A1,02,BE,C8,33,D4,A2,01,86,F3,FD,4B,51,A7,6A,E1,22,60,98,B2,56,ED,ED,A2,13,E0,9E,74,02,23,E5,61,24,1B,E8,6F,98,E4,3E,39,2A,84,D0,31,E1,3C,71,46,E2,B2,B8,F2,1D,F1,72,F0,51,E8,20,28,59,A9,19,5B,5E,26,0A,77,2D,4C,50,E9,9E,C2,A5,72,92,A3,74,DF,A1,17,1A,A1,07,E7,40,44,23,F6,D9,D6,58,0A,2A,1E,96,7F,4D,73,B6,BA,76,A4,7A,50,48,35,EE,1E,87,27,E2,E5,FE,3F,D4,A7,38,44,95,65,E9,76,7E,B1,D9,04,5B,CE,B2,C8,68,CF,CB,97,03,A4,D3,12,F8,8F,E7,D1,12,22,C4,89,05,35,D7,64,06,13,11,69,CF,56,FB,BD,C1,BA,61,94,91,03,DA,48,0F,27,26,3C,F6,7C,80,AA,FD,86,66,BC,BD,C5,5A,46,13,AE,02,C0,12,7F,44,98,AF,46,40,D3,27,BB,6E,78,DA,E9,B3,AF,51,C5,55,E4,B1,ED,2B,07,F5,FB,03,C7,AF,14,FD,FF,9A,C6,D0,BC,62,F7,FB,29,47,98,96,F4,15,9A,A7,BA,6C,CA,F6,EA,8D,11,B3,C0,E9,AC,8B,05,D5,6F,B9,C9,70,A2,7A,45,FE,90,10,4F,5F,19,A6,F8,55,61,01,73,44,32,DB,CB,46,30,1C,1D,D9,D9,FF,9C,CB,84,08,69,46,CF,60,37,72,7E,A3,5E,11,5D,BB,8F,5D,7F,ED,AC,9D,A8,4B,78,31,B7,30,48,B4,CB,3F,76,8A,EB,A0,81,00,01,5E,74,03,12,BE,AB,17,86,0D,33,47,BE,53,67,A6,6F,A9,90,6B,8F,8F,39,B2,23,90,ED,1E,B4,E1,62,37,E0,3B,A1,E1,12,63,83,A0,D4,34,B5,09,34,E0,04,C5,53,5C,85,EB,11,1E,5D,1B,CE,9B,07,06,BB,54,EF,1B,96,D2,B1,BC,4E,D9,ED,81,95,B5,AD,A0,C0,A0,B3,1F,84,34,AB,C0,93,BE,30,37,85,B9,21,C6,3B,CB,21,AA,66,92,D1,18,7E,C4,A1,B0,58,90,E7,61,D5,CE,61,42,B1,00,A8,48,FF,5E,4E,4F,CD,1C,B9,5C,AD,74,3E,90,FB,D2,04,32,DD,71,F1,81,4F,E8,91,2C,69,B8,8B,EC,A7,56,11,64,DC,CA,5F,5C,FF,1B,BF,F3,BF,17,AD,0B,1C,BC,B2,77,DE,BC,00,13,0D,78,97,44,43,E4,B0,C7,58,91,71,14,D9,94,9F,5B,F1,48,C6,B1,CF,03,5E,B4,E8,56,A3,B1,50,06,9A,21,44,D4,A6,82,A4,2D,40,64,39,95,17,63,65,1D,D5,C5,E7,C8,9D,BA,2F,F5,D9,89,1D,F5,C8,D9,E4,FC,B6,36,80,C6,56,0F,13,BE,73,70,68,E6,71,EF,3B,70,6E,BE,30,36,E1,45,8F,BA,7A,35,6D,09,DC,C2,80,69,6A,AA,4F,2D,D4,19,94,1A,8C,E8,78,7B,83,28,B3,9B,22,D1,16,CE,FC,A2,D7,DC,E8,68,55,96,BD,66,05,5E,3B,4D,4F,E6,AA,C6,32,AE,45,99,52,4C,F2,64,E6,F3,6C,40,7B,52,CC,50,A2,61,CE,44,62,C9,C7,89,A8,25,AF,18,06,7F,1C,7E,53,D4,9F,40,6D,23,77,2D,04,C4,DE,A0,F6,E6,25,0C,7B,CB,E8,70,0A,10,4B,DE,3F,34,01,2D,8F,EB,3E,C9,4A,F2,54,AA,EB,D5,04,6B,E3,27,E5,8E,75,B3,26,B5,A3,BC,A5,AB,B0,11,D6,53,1C,9D,B8,3D,05,CA,A6,58,BD,5D,F9,74,B4,B9,BF,3B,BD,07,42,3F,DA,00,21,30,E6,A6,64,D6,36,4B,B0,D9,41,12,EA,42,41,3C,F5,49,41,E0,8B,35,C8,1E,DB,1A,1D,B7,F7,63,28,8E,FE,E6,DC,3F,6D,03,26,0E,BA,21,59,F9,FF,50,7A,A7,B4,5D,D5,76,0A,E9,3D,07,35,D4,1D,15,95,B1,AB,49,B1,5B,ED,D3,4C,08,2F,6F,BC,70,07,AA,15,A0,93,F2,9C,CD,88,75,BD,42,4A,B8,BC,A6,9A,8D,24,7B,1E,52,FE,55,1B,19,A7,7D,DB,95,A6,6C,50,4F,09,84,28,0B,93,77,06,2D,95,1F,EE,DE,63,52,84,4C,96,CD,51,13,33,F3,25,28,10,EE,CD,BC,93,00,BA,67,6C,7D,62,6F,95,8A,21,94,CE,3E,F4,46,FB,57,50,C6,AE,9D,E3,0A,5B,A6,D5,31,0C,11,F3,A5,DC,B2,DF,E7,09,05,EE,18,8C,F3,BD,CA,68,B5,EA,2C,EF,F5,D9,B9,18,B9,78,05,A7,E1,72,24,1D,B2,C4,4B,B2,F3,46,A7,06,78,B2,63,D6,54,2D,A0,DF,82,48,EF,55,7D,9F,0C,5B,66,9C,CA,1C,69,C0,CD,F9,6A,B7,41,EF,8E,F3,E7,D2,06,0A,9A,B1,0F,21,F7,E9,2C,F1,B5,BD,AC,43,22,F4,05,E8,04,84,0E,B7,CE,C0,F8,80,7F,5B,42,09,2D,4E,78,07,F1,3F,09,7B,F9,38,ED,90,4D,00,69,29,E2,DD,7D,1D,9E,04,DC,CF,47,9E,64,79,CE,F1,E6,4E,D8,51,B1,3E,B7,33,E1,50,24,9C,D5,2F,08,D0,69,32,9F,44,F9,4A,8B,C6,54,64,97,E0,50,86,DE,33,7B,5B,8E,4F,18,99,1B,AF,6A,9A,1D,66,E3,44,87,C9,36,DE,CE,E6,68,73,52,87,E2,C2,D0,B9,68,7F,1F,B6,37,C8,71,52,EF,8C,2D,A8,8B,24,39,36,68,18,25,08,D4,E4,83,85,D6,2D,3D,0E,8C,16,7B,D1,3A,BA,6F,FB,91,D6,2A,54,AC,41,62,50,2B,B6,93,2E,71,36,C0,52,E9,19,FC,C2,AD,11,67,29,4E,BA,78,3A,4D,AE,BD,1E,0E,2F,12,BD,A9,25,11,D8,BE,84,60,3C,BA,63,D2,95,EE,A6,D3,51,F6,39,77,53,06,F4,5E,26,C2,66,FF,4E,09,C8,B1,1B,9E,3D,2E,7D,5A,A6,00,F9,EC,DF,25,5D,50,E4,AE,BB,11,BE,57,51,1C,AF,4E,F9,4C,78,F2,0C,00,5B,A4,E9,BF,20,C7,B7,3C,5B,FF,24,9C,1F,1B,73,25,07,20,D1,C3,E0,5E,AE,99,C4,5D,A7,D4,84,72,4C,FB,72,41,DD,2F,F0,88,B1,A2,EE,6A,87,36,FF,D2,71,74,5D,FC,F3,E1,36,1F,31,12,82,6E,0D,B8,37,73,07,C2,C7,30,AF,DE,E0,23,36,74,97,E3,3B,DB,79,5E,83,7A,AA,ED,5F,63,E2,05,3C,CA,56,D1,EC,28,B8,F3,E4,91,7F,1D,C7,B2,C2,60,CA,6F,72,D4,D7,C4,1B,25,1A,98,D6,6F,A0,6C,0E,C0,89,0B,D9,FE,88,DF,4D,E1,63,CC,C0,43,BF,D1,FE,E2,A9,6A,A6,7D,84,20,68,20,18,43,22,92,92,CE,C8,F6,A0,86,4C,91,AC,59,5D,88,8F,55,FE,BB,8B,EF,AA,4C,81,78,98,90,9C,93,04,85,2D,C6,71,22,06,AB,C5,D3,72,FB,F2,27,D9,57,C8,26,10,C5,0C,BD,E2,A6,88,2C,C0,8C,91,04,6C,63,F9,EA,E8,10,99,B3,A0,55,32,C4,A5,88,79,3A,B2,83,D2,91,5E,81,FC,90,0F,30,06,DE,3B,2C,64,69,C1,22,48,DE,BD,CF,B0,49,87,C9,74,14,03,5F,5B,AC,6F,71,D6,9F,6A,8D,0B,C8,15,41,26,62,EF,6D,66,F3,A3,AC,E6,18,C1,60,0F,45,C7,4B,22,3E,41,C9,BF,24,FE,16,2F,C1,42,10,E7,EF,27,CC,E6,E4,B9,73,49,8C,28,88,0A,F8,14,CC,8C,64,80,FE,02,DD,D6,D1,50,FA,2D,6D,96,08,5E,64,21,A7,BB,C6,8A,8E,8A,19,F4,E9,06,29,21,5F,A4,53,A6,C5,23,AE,60,FC,A3,B1,B4,DF,5E,4D,8B,7E,96,B2,19,74,7F,42,67,12,A5,AD,C8,32,42,CE,31,34,08,15,23,63,28,44,42,97,F0,79,8C,16,B7,20,DF,26,F3,80,2D,8D,FF,E8,33,7D,2E,F7,7B,DD,3B,27,2C,78,FB,1C,8F,10,21,51,F0,E5,54,5B,A9,EA,9A,62,E0,A6,08,62,5F,70,C3,4A,D7,0D,2E,2B,5A,F7,78,E9,C7,DB,5E,0E,C6,31,8D,02,77,01,DA,70,59,87,10,81,64,5D,39,A4,2A,45,FC,45,4D,22,A9,09,18,C2,9D,F9,67,52,D2,82,05,E7,F3,91,92,AF,87,F3,03,19,4B,9F,06,9E,DC,F5,73,CE,FA,BA,21,18,7A,5F,0B,0F,41,49,E7,D2,EB,68,12,A6,37,15,D6,CE,24,9D,A6,93,ED,77,6B,1B,74,9A,7A,8A,3D,C3,76,CB,DC,3D,9C,5C,EA,7E,D2,46,16,FD,F0,19,97,5D,95,C7,A0,EB,53,CA,F9,A9,B5,E3,8D,85,5C,FA,1B,0A,1E,21,15,47,2D,40,20,03,92,B5,26,9C,8A,DB,C2,A2,8A,BA,53,A5,A0,80,D9,DB,13,C3,4C,38,65,5A,4E,A9,16,F6,2B,7D,9F,D0,3A,B7,05,12,AD,60,7E,CF,7A,F3,20,55,01,C7,B7,55,52,88,8C,EF,2A,A1,D9,6D,13,6F,46,83,8E,07,11,36,28,12,C1,B1,1C,92,09,CC,C3,DD,49,86,24,56,BA,D1,96,A5,4B,8F,F3,26,17,A2,DE,41,79,41,65,CE,49,7E,3F,87,B4,72,90,7E,61,D1,D1,11,98,63,A2,87,A3,B6,BC,EB,75,70,A7,E8,16,18,98,15,5D,37,83,80,67,BF,B8,71,47,17,2C,BE,9F,95,8C,9A,0F,ED,42,C7,E8,B7,4E,A4,A3,53,32,B1,ED,58,68,61,73,6B,D4,6B,62,52,3B,F3,85,88,09,26,36,DF,54,BE,6D,1F,C6,0B,D5,AD,D6,EE,88,F1,B8,0B,E7,4D,3B,94,B8,10,60,EA,50,05,AB,BE,3E,24,51,F5,9F,4F,A1,E3,45,FF,64,71,F7,09,5F,15,D1,FE,D4,20,8A,11,58,7E,B5,60,34,25,D5,57,E8,3A,3B,F2,5D,DB,84,02,2D,75,BF,8B,9B,21,FB,C9,02,ED,3C,0F,90,0C,01,C5,EF,EC,EE,A1,B5,6F,57,E1,4F,7C,DB,CB,3F,D2,21,5C,A7,FD,FD,C5,77,F1,2F,04,BA,57,4A,B5,D4,E1,B9,1E,17,08,02,D0,45,E4,06,9B,8E,80,1D,00,6A,C5,1D,28,1B,97,A3,E1,53,A6,F9,B5,E3,01,95,31,81,48,54,E2,6C,37,30,40,6D,65,6A,C0,CB,33,A1,A4,57,BF,C2,2C,BB,6C,84,D3,F8,04,33,F8,61,30,08,E2,4E,32,66,09,84,60,1C,2B,80,AC,E8,17,E4,0D,44,19,8B,48,81,D7,87,51,70,66,FD,99,29,40,A3,76,51,72,AC,9C,63,51,A2,76,CD,4C,D1,E9,0D,8F,5D,58,E1,AC,41,56,64,4F,78,EA,71,31,EE,28,46,9D,16,9D,CF,90,89,F8,E1,D3,EF,2B,27,5D,D7,0A,4A,0C,03,13,F7,C9,A2,2C,D7,6F,04,A4,8D,53,61,73,97,87,69,AE,36,9B,87,87,86,C3,A3,63,FC,D5,97,3E,50,D5,2F,69,ED,77,21,92,EC,12,DE,F3,BE,A3,E6,F4,C8,A1,C1,72,7B,8F,3F,AD,3A,F1,1D,26,7F,1F,AA,6F,C0,8A,16,B0,9C,3D,AA,92,35,80,E4,D3,03,12,A8,41,39,E3,7B,BB,30,96,5C,BC,E7,3E,1D,36,E2,33,33,D6,36,57,3D,96,D3,78,BB,1A,E7,75,E3,0B,84,B2,4E,B1,52,4D,C1,D5,FE,AA,E2,F7,3B,B9,2F,CC,04,1C,8A,21,2E,81,18,14,BD,99,BF,8A,28,E3,5B,A2,DC,43,77,75,F0,CF,4C,7F,99,04,0A,91,83,34,1E,0A,D9,C4,89,A9,97,D1,0E,A2,01,89,EE,7E,C9,6D,40,CC,78,A6,0C,37,91,32,DD,24,98,2E,AE,FB,41,88,97,49,25,81,4E,74,A9,7C,8A,C6,B7,47,4D,95,56,2B,4C,16,CF,37,53,AC,16,49,84,08,89,B1,37,1A,14,F5,8F,FF,A2,4B,91,D4,30,6F,F7,1A,4B,09,63,C7,2D,83,F0,C1,BF,CF,C0,56,A9,6D,5B,B5,58,51,FF,4A,98,27,69,E6,80,5E,F6,62,14,E5,A2,9F,35,0A,F8,6E,8F,8C,F0,90,9E,07,2D,75,B7,45,CE,67,4B,19,7E,AE,5B,A6,F8,DC,26,90,30,FA,CB,35,A0,35,43,90,51,A6,A6,D1,3D,A3,58,BE,90,C7,E3,33,12,D3,BC,50,53,A6,F2,8C,2C,5D,B4,42,85,E1,07,4E,E2,BD,37,CF,73,D0,09,66,75,A3,39,75,EC,47,D0,8C,A4,13,C6,49,E3,FF,93,39,17,F2,38,D3,F5,F8,79,8D,DC,1D,3B,6F,0D,48,D1,10,7A,01,77,89,30,2E,81,F5,39,10,45,B7,D3,E4,E3,F9,F7,F9,73,7F,95,F6,95,43,FC,8D,02,45,2A,D1,3D,77,A0,3B,0B,11,C3,94,81,96,86,51,22,3C,65,82,6A,DB,F0,59,F4,33,F1,0E,10,E3,C0,F9,1D,37,7E,CD,F5,D8,ED,0A,0F,13,C5,9A,D5,47,1A,CF,3E,44,4B,C6,8A,94,DC,B6,AC,C7,C3,FB,F0,79,D0,02,D9,7A,14,03,2B,3D,A7,DA,7E,9F,2E,61,2B,F6,86,87,DA,A5,82,EC,90,2E,28,11,62,E5,74,C9,53,E0,57,27,3A,F2,06,C8,09,F8,02,26,12,64,8B,96,DE,72,1F,95,7F,08,BA,C6,0A,74,90,2C,B0,EF,28,71,4B,72,BB,09,B8,93,C9,89,BB,12,13,FE,44,74,D1,8D,04,21,0F,80,45,9D,A0,21,28,83,DD,A0,59,92,3B,16,98,7F,3F,96,77,50,10,EA,A8,4E,A8,82,09,20,A7,07,D5,3D,59,B1,E3,09,C0,67,71,54,CA,AB,83,A2,52,A9,14,8E,DC,BD,EE,7E,D2,75,25,90,38,9F,06,5A,1D,98,40,B2,9D,7C,6D,1D,57,58,B5,4A,6E,88,28,75,B8,F7,0F,14,35,F3,5F,61,6D,15,54,62,59,10,5C,A7,C3,D9,B1,F1,CB,0F,E2,60,BB,15,E0,55,08,FD,5F,46,D5,A6,14,8A,DA,DB,3D,89,B1,F8,21,AC,80,33,6C,A2,52,0C,3C,B3,0D,8F,1D,72,EA,8C,40,EE,38,69,F0,20,6F,C5,EF,04,86,29,74,1E,3F,D8,F6,1B,45,C9,76,CC,2E,8D,BC,8D,26,5D,2A,55,09,2C,62,C6,56,3F,76,2B,8C,B2,B9,84,04,24,AF,4D,66,09,5A,E5,EA,4C,02,62,55,DF,C5,6C,8D,79,FE,32,A6,CB,46,3F,D8,F0,81,E5,2C,1E,02,7D,DF,51,87,45,4B,58,3B,CA,F7,74,8C,A2,4A,1C,82,C9,77,D4,C3,E9,8A,FD,E9,82,C9,D3,3A,74,12,29,F4,55,54,D2,BC,7E,E2,78,9E,E3,D7,73,A6,B2,34,7C,77,A4,FA,FB,98,D2,D1,EF,E0,B8,00,2C,1B,D1,FC,08,22,06,D7,95,FE,C4,E2,B4,D3,64,59,71,E8,95,1D,CF,0A,A1,C0,30,E1,F1,25,20,E6,5A,5C,D2,F6,BE,2E,6D,D1,1D,FF,09,00,25,82,BF,73,66,C2,1D,51,F2,F6,92,3E,8F,A8,1A,EB,05,B4,04,99,C2,C1,67,68,6A,64,B3,F6,1E,14,3C,67,6E,BA,CE,07,7F,47,BC,E4,B9,7E,18,28,89,40,23,A0,79,07,A3,26,35,F5,69,33,3A,D7,55,4C,53,2A,6F,F6,E0,3A,B8,0A,B9,3A,51,66,06,DE,4E,8B,AB,00,CA,63,82,AD,F8,47,CF,96,FA,53,A7,83,6B,6A,3B,0D,E9,D1,78,5E,43,D4,3D,D1,DC,E7,F6,16,5B,C6,AC,A9,4B,CE,F4,07,A1,1E,2B,0C,71,70,10,7C,EB,92,00,3C,09,93,AE,51,98,E9,37,2C,FF,99,23,34,E4,4D,6F,26,41,8B,FF,97,C3,29,57,D2,A1,BE,B6,00,57,AA,1D,1E,5B,29,63,DF,E2,43,68,2A,56,95,6C,B9,69,B9,4D,3E,41,AB,77,26,48,09,B6,5F,80,E0,3E,F6,A1,26,33,F0,89,C8,02,6D,79,99,96,98,4E,D1,11,7E,42,AE,C7,41,86,70,CE,C8,67,F5,6D,C6,8E,DA,32,70,E0,C8,C3,3F,1E,B7,2E,A2,44,2C,26,1B,77,48,14,03,3A,6B,F4,18,AA,FE,AE,B7,A6,25,CA,1E,6E,6C,3B,91,C1,24,DF,D0,31,17,B4,C1,D7,33,61,30,C4,AB,40,21,44,23,ED,0B,73,1C,65,CE,94,6B,97,57,7B,A2,C8,09,A9,58,E2,33,69,D6,D7,E9,55,8C,7B,46,38,07,54,7F,8A,A9,9D,9A,CF,D0,3A,75,AA,8A,68,66,53,CF,E0,02,1F,49,9A,38,49,DB,EE,AE,87,8E,9A,FE,7B,FB,F2,8F,BE,C8,47,5A,6B,3D,61,83,61,B1,3E,B1,7E,F4,E6,7B,7B,BD,FE,04,19,8E,37,7A,76,88,36,C5,39,81,F7,49,9B,60,40,01,25,F6,8E,72,F6,7B,F2,AD,7A,EE,8D,0A,CB,F0,DF,60,50,31,3D,E3,3A,8F,4D,67,DF,84,B0,0D,4D,51,94,F1,00,2E,5C,F4,75,D7,7B,DE,54,61,28,89,EE,94,79,90,D7,A7,14,35,D0,D7,C7,F9,3C,04,3C,BB,68,11,9F,00,04,14,92,33,B1,47,62,83,7F,38,C9,8A,A9,DB,1C,E8,6D,DA,DD,1B,F4,13,91,5F,EC,3E,AC,21,9B,F2,68,C8,30,88,2F,20,A5,2E,22,79,9E,4F,BE,F5,B9,E3,E2,29,40,FE,10,04,82,B5,B1,3E,AF,8F,3C,E7,43,14,C7,E9,E8,4F,F2,F4,A2,A7,3D,29,41,3F,5B,F9,58,10,4B,9B,BB,B4,2E,DC,AD,A0,B0,FE,FF,A9,06,66,5E,54,3D,EE,78,9F,41,9E,97,0D,1D,EF,23,A4,60,95,BA,C0,EE,A4,D7,CF,5F,51,0D,19,82,7A,06,73,AF,4B,5E,96,23,7B,99,5F,A9,56,80,31,35,98,9B,DB,7A,9F,46,61,A3,2E,08,DE,A6,A4,D1,DC,AE,FD,E3,60,22,68,5A,CF,AA,CA,BF,84,CF,25,61,23,29,3D,06,1F,A0,C9,00,4B,DC,B9,FC,A9,F8,77,3D,7F,EE,8B,10,07,1A,C4,04,83,A6,5D,DA,3E,BF,57,E1,7E,F5,1A,B8,4D,02,C5,89,87,A7,DD,C7,B3,26,D2,B2,08,80,8F,FE,27,CE,58,9E,DC,37,8F,76,40,2C,22,B2,A6,26,53,81,FC,B1,6A,60,A8,88,BD,A9,AA,7C,ED,4F,71,99,B5,22,43,01,14,75,AD,57,1C,A4,4E,E0,7C,E0,46,48,96,D5,09,26,18,A5,6D,97,7B,C2,40,8D,AF,81,AE,19,5E,36,5C,2A,3B,3A,90,21,C8,CE,BD,DC,64,B7,34,DA,C0,4F,36,53,A0,CA,4D,F2,57,07,F4,62,07,4C,9E,B8,66,C0,DE,B0,9A,C6,92,72,B7,A8,69,AC,CD,1E,E6,AD,FF,1B,02,BD,F5,C5,46,BC,96,5C,E4,D8,81,3A,6F,42,F4,FE,67,FF,01,E5,18,E6,F1,6C,17,45,E0,F4,F4,AF,66,6F,B5,BB,A0,7E,12,4C,DC,A7,A4,F3,D2,A7,98,7E,39,A3,79,19,BC,A4,6C,36,F4,93,0E,83,B8,79,D2,A0,53,C4,C6,C6,C4,A4,63,5C,5B,57,3B,70,8C,A7,2D,0C,87,E9,E1,B4,C2,9F,77,C2,CC,75,64,6B,68,91,DA,90,03,67,5A,F1,D3,38,57,8B,C4,CF,34,D7,6B,6F,2A,E2,8F,C2,07,0C,BC,65,86,AA,D5,9B,49,43,C7,49,BD,D7,3E,A8,92,F4,7A,03,B3,E6,CE,5E,71,20,A1,40,2A,61,30,4A,A4,A9,2C,79,1C,A9,A5,D0,6D,AA,3C,ED,03,18,B0,FE,5C,D7,F4,E1,C7,FA,F6,50,5E,3D,A9,6A,95,FD,54,DA,DC,63,8B,49,9A,AF,8D,64,9C,15,4C,01,34,5B,58,8E,47,44,C0,94,CC,95,50,88,2E,0C,26,B8,9C,23,7B,D0,C2,0E,20,C3,92,9E,1E,F4,CB,43,69,B6,4E,43,0A,E8,C5,2D,E8,A0,EA,BB,B8,AB,84,49,3C,C1,1C,2C,04,B1,D1,A3,A4,BA,31,8D,11,3A,1B,B6,01,FD,CC,39,23,61,33,1A,3B,74,14,1C,1B,FA,12,97,4C,BE,89,68,38,9E,33,0D,4F,FA,E6,1A,6C,6E,FF,4D,3E,AC,38,D6,5A,EC,01,B5,46,B3,56,DE,31,F4,81,C5,29,4D,7D,0D,01,EE,F7,03,7A,28,9F,51,7A,33,4C,26,97,75,90,1C,15,7F,DD,52,71,82,65,10,83,A9,A7,91,CA,F8,11,BF,F4,3E,CB,86,4D,04,CB,FF,F6,10,F3,E7,D5,E1,E4,74,6C,A9,26,35,30,24,73,B0,84,95,74,64,56,C2,52,58,8E,83,8E,68,AF,64,C0,3D,50,BB,66,3E,73,31,00,6C,29,9A,4B,22,F2,72,34,33,52,89,5C,32,DB,68,42,5A,AF,A2,42,24,09,07,66,A7,FA,0A,E4,D9,D4,28,EA,61,17,F1,D2,C5,13,7A,E7,A6,71,37,3B,B8,FF,CD,3F,61,74,BE,8B,F7,48,26,6C,D1,04,F3,B3,4B,92,2A,97,49,4A,FF,2E,DF,05,5B,72,F0,54,50,4F,55,F0,7B,3D,C3,AC,29,38,18,72,08,51,4D,48,00,A6,38,15,CD,08,7A,B3,8F,8A,48,4D,EC,AD,4D,B0,97,2D,AC,7A,86,4A,F5,F9,60,49,FA,64,31,6D,C5,7A,9F,89,D7,43,34,E9,A3,B3,5F,38,A9,D3,96,94,74,03,D4,D5,FA,B6,B1,C4,F2,F1,69,30,F7,67,74,D7,B4,76,CA,48,DB,F3,78,E5,90,00,F9,F1,9E,A6,99,50,3A,AB,35,92,1F,FC,5F,83,1C,C4,64,9B,16,15,1C,FE,90,91,05,0C,5E,CA,C3,55,E6,E5,D8,00,86,C5,6D,FF,BA,5B,8C,68,72,DC,EB,A8,CC,94,8F,BA,68,78,54,A5,90,56,77,08,B3,A9,92,43,3A,70,88,53,3B,75,C5,6E,0F,5F,F6,67,04,F9,CD,5A,12,71,C5,A1,BE,C5,C8,24,92,74,7B,EC,54,CB,9D,94,8A,3F,D3,98,6C,87,98,34,96,2B,02,0A,7C,01,25,E1,65,A3,F7,9C,0B,23,0E,FD,4F,1E,7A,88,C8,78,D7,B1,C6,DA,6C,66,11,B1,3D,38,DF,DB,4F,41,33,42,4E,98,F5,33,4C,4A,46,63,65,6C,82,F7,AB,A0,23,FD,F7,24,42,A3,72,77,32,7C,A8,00,26,BC,5F,BA,C9,33,0E,D1,E2,42,12,56,9D,40,EE,2C,F9,17,EB,40,58,9F,16,13,13,D2,3C,FE,FC,76,E9,87,CA,41,E9,25,99,6B,19,C4,07,B3,16,99,C0,21,C7,1A,A3,E2,97,65,8D,D8,EE,03,91,21,76,D7,2A,26,0C,35,D8,72,CE,8E,47,F3,E4,D5,06,CD,1B,F8,5C,3F,34,38,5A,16,93,B2,EC,C8,AD,3A,36,F6,99,15,3C,90,B5,1C,3A,76,66,21,38,7E,2F,81,DA,67,EA,6C,77,98,8A,F9,C7,8C,1C,C4,ED,46,51,70,84,1B,07,D8,C4,CD,7E,B2,86,92,86,91,F6,4F,DD,7A,0C,FB,95,81,60,D9,9F,82,20,AD,68,DB,84,53,53,50,6F,06,E4,C6,C1,8B,7D,C5,74,9A,16,83,7C,09,03,89,AA,F5,6D,3B,EA,DA,1B,31,D7,4E,E7,48,BB,AF,03,4C,90,CD,8F,3A,F1,C6,F7,54,28,5E,15,07,6E,29,3F,42,BA,BE,E8,E4,51,86,39,B4,D7,49,05,31,74,92,48,BA,04,0F,5A,24,2A,14,67,19,A7,F9,7F,DE,C9,E6,AC,44,1E,13,B2,43,BB,0B,F0,0F,47,8C,00,27,DB,8B,15,E0,C6,DD,EE,C6,A1,F5,BE,45,C0,F4,8D,8F,11,24,76,12,5B,A5,EC,2F,30,E6,A7,68,C8,9A,9B,1C,48,77,34,D5,D4,F1,0F,CF,86,8E,34,B9,DE,76,A6,87,43,CA,B9,0D,E9,D7,E8,CC,90,FA,F4,23,8C,37,DD,67,C5,FB,B2,FB,B0,89,5A,47,D9,59,CD,BD,37,6F,7C,5D,77,C5,06,5C,CF,63,22,AE,72,A2,FC,C5,07,4B,7D,DF,21,2D,97,C8,A3,FA,DF,3C,C7,2F,AB,42,22,14,42,30,BD,1C,10,72,CA,02,A2,22,40,6E,58,8A,0B,B6,2C,16,D3,25,D9,8E,42,E5,77,67,2C,EE,35,B7,A3,47,05,F5,34,36,A7,DF,11,69,B1,51,CB,FE,55,2C,46,D3,CF,77,11,9D,77,66,C3,31,5D,E6,D1,08,32,37,26,B3,AE,58,EE,1C,EB,A6,A9,81,6C,A2,F7,60,9C,B2,7E,3C,0B,F4,A4,E1,3D,9D,F5,2B,23,3A,EA,1C,E3,0C,4A,F6,49,BD,47,13,14,39,31,4C,EB,5F,52,52,53,B6,B1,8C,5D,17,E5,C8,48,57,15,A3,47,84,2B,67,70,A0,CD,8D,00,48,78,F1,77,D0,B0,C8,3A,5C,E2,6D,26,25,EB,33,16,07,72,43,6D,E0,65,4E,80,A6,70,19,C5,9E,58,53,CD,07,FE,55,DE,02,8E,68,6F,24,FF,6D,13,F4,5E,A9,42,25,89,2C,B3,B5,AF,24,B5,00,48,C9,30,02,E9,E2,25,76,AF,74,E6,ED,54,80,D6,95,58,D0,19,F4,D0,13,B5,BD,C6,15,8E,CA,DD,B5,A4,81,11,4E,9F,C5,49,4F,47,0D,4D,98,94,3E,A4,9A,C2,C4,1E,C5,02,AF,0C,7F,BE,04,F1,83,36,0C,0B,9E,D8,0A,1A,60,6E,26,30,05,45,A5,7D,A7,5B,76,43,93,86,C4,23,98,69,C4,24,90,CE,73,D1,DD,5D,82,7E,0F,95,DB,C5,4E,1D,6E,4D,19,76,B1,C9,3A,C3,89,DF,81,6E,03,3E,26,29,0B,9C,F1,2B,CB,94,18,13,4D,88,E0,33,48,13,82,BC,A3,10,AC,F8,CB,15,AE,E8,8D,07,32,BF,54,47,FC,65,D8,62,DB,08,5C,A1,AD,DD,0E,30,5D,89,E4,7F,D6,46,8D,52,13,BF,30,CE,3F,C1,07,1F,D9,D5,59,94,28,19,85,2C,D6,27,DD,89,2C,E5,AF,88,7F,4D,63,C8,B5,47,EC,EC,A8,BF,37,89,6D,D2,A5,C7,19,C6,9F,73,95,4B,CA,0F,72,0C,47,A7,90,42,BF,53,A7,F6,B3,2E,7A,44,49,3B,FA,3C,9E,3F,66,CF,51,0C,6C,A5,4A,CB,FF,ED,0F,80,E2,2E,57,A5,FA,E7,8B,79,F2,E9,53,18,C8,20,82,6B,C2,59,51,8B,54,AA,E4,8C,22,08,38,91,F1,07,7A,88,6B,E2,C8,78,4C,50,9B,83,10,82,1E,8C,D1,C6,30,E2,9B,D7,DE,7D,17,08,23,18,6C,F5,BD,39,0F,5A,96,8B,33,69,BB,C8,9F,16,2F,A9,2C,C4,40,2A,71,24,49,32,B3,D4,85,47,63,8B,AB,AD,25,26,39,9A,DB,D4,10,15,CD,72,D1,56,88,58,0B,27,0E,DF,48,2E,AE,D0,A4,81,F9,9C,6B,EF,41,8A,C5,2B,96,79,84,40,D7,E0,70,DF,4A,DA,4D,62,37,92,BC,01,42,6C,2F,E6,17,D6,BF,42,3E,79,C7,BB,33,4F,B9,8A,4B,2F,26,AE,7B,A7,99,71,21,2C,D5,A9,D1,73,9D,74,AD,CD,84,81,81,87,D1,51,50,0E,93,65,6F,D5,D4,15,54,70,5E,61,69,F0,BA,97,F1,C7,B2,D1,68,EA,B5,D4,AB,81,84,76,B6,64,61,05,F1,B4,9F,9B,68,D3,BC,BA,97,E5,82,6F,8F,10,00,71,E3,E2,B6,C7,B8,26,D6,FA,9A,15,47,2C,B2,93,C9,47,6C,26,7D,5B,25,2C,F0,97,72,60,80,CE,CC,70,1D,9F,9E,29,4E,7B,A4,97,53,FA,5F,F3,0B,5E,C1,99,FD,E3,2B,C2,DF,8F,1D,11,5E,72,9B,B1,72,93,8A,AC,A7,33,28,AB,80,12,AB,16,18,6B,48,1F,CF,EF,82,3E,53,AC,FE,42,C6,31,9C,DB,EC,F4,C6,8D,5D,7C,DF,E6,59,58,95,01,D4,DF,51,D7,BF,D5,49,A5,EE,17,B1,C7,4E,29,9B,23,39,21,07,EB,67,7A,4D,CC,2C,68,EF,63,B8,B8,46,CD,4F,5D,BD,EB,1F,A8,B4,1C,DE,92,0B,22,10,19,D5,44,5E,E6,AE,EB,87,7D,BB,26,A1,1D,A6,A4,D0,60,39,2C,42,4F,F3,E1,01,38,92,F6,12,2B,7C,A8,FF,ED,2E,2A,91,6F,0A,E7,D3,C3,63,15,E9,2F,A8,41,87,BD,4F,6B,94,0C,8F,5A,3B,A8,8C,C1,A1,99,42,F1,7B,53,F8,D0,45,3E,F5,6D,0F,6C,83,D0,95,C3,E7,5D,0F,E2,3D,E8,0D,04,21,81,01,30,53,D0,3F,E0,1D,83,CD,ED,24,47,5B,E7,FE,6A,DB,5D,58,98,94,15,A3,C3,BF,28,86,14,66,DB,73,2E,D8,CE,C5,54,23,A7,87,B5,C9,4B,EC,C5,D2,05,D8,67,7C,A1,4D,3F,3F,0B,9A,88,2E,37,29,D4,D2,B7,F7,A2,F9,A2,D5,68,4B,46,89,AA,9A,23,CE,EB,27,2E,90,B2,BC,7C,66,4A,8D,D2,2A,1D,A0,9C,C5,24,DC,86,D7,EB,08,21,1D,44,38,0A,02,38,D5,71,C8,29,04,78,92,80,80,6E,F9,24,03,DE,4A,43,DF,4F,ED,6B,89,45,F6,26,2B,F9,37,43,6B,52,8D,31,C1,13,85,E0,5A,6B,00,03,73,9C,6B,E2,BD,7F,D8,13,3A,68,86,24,DB,B6,37,80,14,1E,75,46,13,D9,44,A3,DB,C1,E1,07,47,E4,BF,59,60,93,E9,2D,07,43,14,83,FD,1B,FB,BA,11,E4,00,AE,A1,E1,88,D4,DE,D3,49,03,F7,2D,5C,F5,E9,77,33,33,D4,17,64,66,B3,0D,D4,8B,16,FF,CD,F8,06,67,82,B7,C8,4B,26,E1,5B,64,B5,7B,AA,E2,8A,D6,AE,91,64,19,1B,C0,8A,0E,8D,BD,96,17,55,3B,9E,27,42,A2,DB,66,C3,22,D7,5B,4A,92,4C,C2,22,F0,5F,83,F3,2F,32,B6,B3,F7,63,F9,EF,9B,E5,80,B5,12,0A,14,9A,4A,7C,36,6F,B6,B2,35,08,12,92,0D,A5,69,AD,3F,9A,A6,0C,9E,EF,9F,3C,4C,F2,67,46,42,49,23,FF,99,AC,86,91,23,CD,2B,0A,F9,2B,79,80,55,F7,33,0A,FE,65,99,E3,AD,C3,4E,32,CA,E9,4C,DA,79,6D,D7,BD,30,EF,82,74,FE,96,9A,2F,C9,CA,1A,83,3B,82,F2,81,BC,E1,47,D1,44,75,EA,21,AB,76,99,AB,B0,88,64,F3,EF,43,50,30,B2,BC,EC,E6,51,2B,3E,16,64,07,61,05,E5,37,EF,04,21,35,7D,FB,50,6E,68,31,47,6E,58,24,8D,37,E4,C7,43,21,E9,B0,95,CB,1D,39,D3,9B,B6,75,93,3D,6D,80,65,34,33,5B,D0,35,23,0B,47,E6,14,12,26,46,94,FC,1E,83,3D,BE,B3,01,52,5B,6F,B6,D3,6E,E2,51,C4,9B,CA,64,4A,6B,D7,E5,C2,F1,4C,1F,84,B7,A6,26,24,23,C1,70,CD,54,20,1D,9E,78,9F,B1,33,DA,EE,92,DB,C5,7C,99,63,DA,E4,D1,AB,2C,3C,52,B1,00,7B,13,F4,09,4B,90,84,0B,81,4F,18,2A,DC,5B,21,32,1F,AE,69,A1,13,B3,5C,E5,11,C4,AC,37,E7,82,AA,3B,C5,B0,A1,1C,8D,71,38,F7,09,CD,3D,B6,AB,1D,88,E7,E3,B0,D8,A9,A2,F5,DD,86,61,31,2B,B9,E4,B6,EF,EA,0B,DA,91,1B,A4,18,35,27,B3,87,D1,8E,33,03,6C,B8,0C,30,87,C7,A4,5E,59,4F,56,F8,CD,DA,33,9D,61,9F,34,91,07,7A,95,EA,82,B6,46,1C,9F,A3,E2,E1,EF,75,FC,D4,05,13,8B,65,C2,4A,8A,CD,F6,BF,37,AE,8E,3F,FA,21,85,DE,20,E4,3E,3A,AF,CA,D9,E2,EA,F8,23,C5,D5,00,99,66,D6,22,C1,FF,6E,F7,2E,C9,36,BE,8A,D9,02,34,03,4C,4D,DD,AC,F4,C9,BA,B7,07,62,37,C1,1A,98,E3,AE,23,A9,E4,C2,83,CE,11,E6,79,32,34,A3,F2,E7,BD,ED,56,F1,53,D2,5C,33,A7,62,C4,DA,D6,BC,D5,86,60,09,66,F4,C8,32,43,11,34,19,B6,3B,9C,13,31,49,73,1A,81,6A,59,28,72,2F,03,98,DC,52,E4,65,38,42,93,71,FC,6F,33,05,CC,34,F3,9D,3B,29,03,4E,26,04,BB,56,24,C4,81,34,60,7A,8F,E1,66,A1,50,92,34,F0,D9,BD,3E,CF,51,B4,54,89,8E,33,9D,BD,97,04,DC,F9,D4,30,B5,65,7D,EF,36,59,D8,2B,65,EC,1D,FC,42,00,1A,57,1A,BF,C7,6F,65,23,2A,CE,3B,85,9E,7B,E6,3C,F1,AA,B6,D2,CA,13,24,BE,6F,53,BA,59,A3,63,B0,E0,C1,52,94,24,A6,1D,FD,59,C4,B0,19,79,6A,28,E6,F2,4D,C5,FB,E9,23,36,CC,96,2C,74,43,89,DF,BF,DD,A9,FB,E6,64,5D,FE,F2,9C,33,9D,D4,73,38,35,C1,50,1D,52,3D,46,A7,9E,62,0E,D6,84,E0,1D,29,6F,E5,1F,DD,44,05,1B,03,CF,03,F9,41,2E,24,78,0A,D2,71,85,5C,F0,CD,54,40,D9,9B,F8,F2,80,A2,0E,C5,E1,ED,72,40,6F,0F,C9,05,AA,31,F8,1F,4F,50,F3,63,87,2D,0F,3E,60,7E,26,70,82,5A,6D,AA,93,6F,8B,CA,02,2C,F1,18,CF,0F,15,A9,9E,F8,54,24,37,EF,4F,9E,A1,F7,09,22,47,BA,05,55,79,E1,A9,41,CD,8B,F2,D3,44,10,A2,CE,EB,AC,BA,16,CB,08,0E,8F,FC,AE,AD,71,08,D4,40,3C,F1,5C,D1,67,1D,3C,84,0F,F5,62,38,4D,BD,35,AE,15,B8,F3,25,D8,B3,65,16,73,7C,D5,66,8C,90,CF,57,56,C1,A2,B2,36,FB,87,EE,93,D7,72,9F,B9,E2,A1,6D,0E,72,B2,EF,00,AB,EA,CD,79,6C,2E,4C,D4,8D,C1,39,03,F0,A2,A7,DD,E3,7C,86,C7,13,B5,B6,83,B1,3C,86,3E,8B,1A,44,D2,73,FF,B4,B5,26,5B,76,36,8B,89,D7,57,A1,0D,53,21,0A,87,FB,C8,E5,51,02,A5,D8,0A,DD,4D,DC,BA,C3,B3,33,F8,A6,98,B4,C3,1A,31,D8,AC,BB,5D,02,C6,73,D4,25,19,2C,66,80,E9,4A,49,59,C1,1B,AE,E6,3A,53,5C,D2,CC,61,07,B9,E6,58,02,5A,B4,A1,48,F8,F7,38,A3,68,F4,A4,36,1B,A6,24,79,E1,71,22,99,4D,43,81,0F,9E,33,35,C8,5A,E8,04,6A,E1,D0,26,62,75,6C,2B,B5,34,46,74,BA,E4,B1,F0,A8,58,5A,F2,38,3F,2F,25,D8,55,8F,E1,0C,D7,EB,29,4E,37,C5,AE,96,C1,C8,F4,D8,C8,CD,CE,48,2D,AD,2D,06,3D,81,07,F8,C4,6D,80,C9,2E,56,C0,ED,D6,FC,DB,A4,F7,DA,F5,69,20,B2,0E,EE,48,B6,98,33,60,CB,7E,F2,56,11,92,54,0B,58,6B,C9,14,A8,E0,73,04,7B,1D,CE,EF,07,48,39,2E,BE,23,75,09,1E,6E,92,C3,80,4D,B9,66,E6,F0,BA,4C,03,3D,F9,75,B9,C7,3E,BD,7F,F1,F2,88,FA,0C,A7,F8,44,C6,6B,95,73,59,D0,E8,36,9E,2F,5C,A2,FD,6F,1B,F0,85,72,38,59,E1,DA,29,9D,3C,9F,9F,A0,E5,D0,78,D6,49,04,B1,A8,00,9A,C7,F4,0D,23,07,C3,40,43,F5,CF,2F,CC,C0,C9,C4,61,84,25,9C,9C,40,03,A7,88,5D,7E,68,AD,E1,7E,DB,F6,34,6D,1D,54,67,C5,E2,3F,54,3C,3E,7A,73,F8,33,C9,CA,AD,CB,5C,44,06,18,B6,71,D9,A2,DC,5A,00,0C,ED,95,38,06,33,B5,CA,54,4D,61,A9,C9,DE,B3,4A,58,12,1F,D0,FE,32,C2,9B,3C,D9,59,05,70,8B,5E,F5,51,F5,CD,F9,8D,DC,2C,54,83,18,2C,F6,8A,3E,B2,5B,C9,85,61,C2,4F,0E,84,25,E2,63,D9,DC,2E,BD,89,11,BD,3B,91,73,0B,AB,94,46,3E,D3,A2,88,50,60,79,A0,B5,9E,32,DD,68,58,D2,AC,53,E3,E1,09,17,D7,84,32,B1,EB,CE,87,7A,5A,B4,C2,78,F2,0F,66,0F,08,0D,B3,E4,08,42,10,41,5E,E0,A1,E9,9C,36,64,C9,20,98,87,EE,EF,78,9A,50,6F,AF,7F,0E,8E,6D,9A,F7,2E,52,09,F4,90,BA,FA,89,18,A8,65,90,A6,E5,C8,09,06,50,19,AE,45,2A,43,EC,8B,3F,5C,CB,BA,E2,D2,87,B5,01,42,18,AE,7A,65,F6,5E,71,CF,F7,8C,4A,1A,6A,D2,83,C4,7D,77,3C,11,8A,ED,34,47,55,25,52,EB,91,47,95,81,E7,18,C5,3F,2C,8A,7D,1D,99,B1,5A,99,DF,C9,61,53,2D,97,21,8C,83,1D,51,89,FD,CB,6C,25,C6,41,7A,1C,EB,65,BF,59,F5,AD,34,0C,B9,EC,1C,D6,9D,4A,5D,F3,2D,C5,FF,A3,82,4B,44,CE,87,88,D7,7E,0A,09,06,7B,59,BF,C3,FE,8A,ED,AB,18,53,C9,B0,63,A1,9A,CE,4B,83,9F,60,73,48,70,C0,3A,84,55,75,03,E7,2C,AA,9C,5B,83,31,25,C0,4D,67,F2,F6,EF,23,44,6D,8D,5F,1C,8E,71,66,01,38,91,C1,73,93,55,7B,05,86,93,20,1D,6F,4C,5A,3C,DA,F6,1C,28,C0,B7,80,53,A7,CB,C5,6A,1C,EC,BC,BA,1F,AC,BC,00,97,86,AA,EE,1D,CF,93,2F,DE,74,9A,35,77,2A,1A,42,07,D1,AB,D3,7D,C5,7A,DD,15,9A,46,54,9B,97,D2,C7,BF,5D,F4,3D,A0,7B,57,82,48,15,90,37,D6,F6,8B,70,1C,A0,9A,5F,DB,1C,5A,A0,D1,AE,35,F3,60,F5,41,CD,2D,44,2D,2C,26,95,B9,85,05,B5,C9,95,FB,21,2B,68,28,FA,83,16,5B,38,68,35,21,8E,62,8F,11,8E,09,71,04,E5,CA,97,01,B6,2C,2F,2C,22,4E,6B,6A,10,3C,2D,11,D4,F0,E5,15,25,AA,D0,7E,54,2D,23,92,30,30,28,29,0B,04,FA,21,46,7A,83,58,1B,AE,A7,1A,74,29,34,75,81,23,E3,90,DA,FA,B2,AD,D0,E1,0C,B2,19,94,B1,77,DC,58,78,33,CF,81,80,BD,CB,33,F0,AA,9B,33,B8,AA,EF,65,A9,EE,E6,1A,7A,91,1C,10,A1,57,01,69,11,9D,61,1C,E1,D0,DC,69,EE,0C,E4,AF,83,52,F2,7E,6B,B9,53,5B,7D,CC,59,AC,A0,46,2D,E9,70,8D,A9,8D,AA,85,C5,CF,91,22,61,78,CB,F1,A4,65,3C,65,43,C6,90,62,09,03,2C,42,3D,B6,62,26,6D,67,67,C9,35,2B,65,49,E0,B6,AE,03,B9,88,95,A6,FB,A5,D0,D4,D2,39,71,56,D8,64,D3,94,91,AE,DC,BD,64,5D,D6,18,0F,BE,1F,C0,4F,26,0A,2E,DA,D4,2A,98,C1,F4,1A,2A,36,94,E8,C6,72,2A,9C,8F,C2,52,E6,B9,2E,E2,15,EB,11,DA,0C,94,0D,B0,23,B7,18,F2,08,95,8B,46,CD,17,11,FB,8B,53,B4,83,73,17,12,49,C1,95,C1,96,5C,E5,CE,5E,E3,40,E6,B7,B1,D1,F5,13,81,74,33,DC,3F,CF,0C,2A,B4,14,C3,ED,BB,C1,81,2C,35,80,DC,51,69,33,F3,12,23,C2,5C,F8,6B,02,88,D7,5C,18,35,8B,1C,70,F0,48,31,0F,E1,DF,BD,A9,17,79,3B,6E,A5,52,0C,61,B3,DB,D8,E9,B3,5F,9B,1F,C2,D9,B7,05,1D,8E,B2,8C,EF,8E,F5,C2,B4,58,FF,46,14,95,38,81,7B,C0,7D,EA,3D,7E,90,E2,B8,C9,84,51,5C,43,CC,B2,A9,87,70,C9,20,CF,0E,C1,22,CA,CD,B7,68,8A,E8,A7,D6,D9,F4,4A,7E,79,4F,EE,EB,86,40,27,52,98,13,30,59,94,08,7D,0F,2A,90,9D,E5,EF,DE,6A,CA,C8,3A,AF,3B,F5,51,58,37,27,55,6F,62,7E,50,60,F3,9C,E9,3C,37,65,B7,8A,3B,15,A6,86,3A,FD,9E,3B,4F,5A,4E,63,BF,C0,FE,CE,39,29,3C,BE,D6,49,E2,7A,26,4E,A8,2F,5F,BE,09,54,51,6C,98,C4,D4,19,A1,F5,22,CE,31,08,52,AE,07,39,20,CA,8D,65,78,10,F2,0C,44,8B,8F,23,57,67,D1,E9,AB,E5,53,1C,F3,FF,36,B3,87,5F,BE,FA,2F,2F,69,42,42,20,9A,1E,A0,91,76,91,8A,F7,AE,EC,A3,8D,8D,28,CC,28,2E,83,FF,E2,8D,8C,30,00,0B,40,BC,65,44,C1,34,6C,07,2B,4E,D1,BC,20,6D,8F,35,75,F4,F7,63,54,DD,58,94,E5,C7,A2,78,07,B4,43,33,09,BD,1C,26,15,1C,83,A9,17,C8,80,F1,B9,E1,CF,30,23,DE,B9,A8,30,02,0D,22,80,3D,33,F4,67,5F,20,41,1E,D7,3B,E5,25,C2,01,93,71,6D,04,A9,3D,5B,9D,BF,73,92,4F,7F,C2,4E,E8,BA,A5,B6,9C,D0,4C,C5,D9,24,9D,D2,68,94,E4,18,F4,3D,67,5B,80,D9,79,97,C3,20,E3,C9,14,87,2C,AD,C8,B5,5E,4E,BA,53,FD,67,30,EA,3C,8C,52,41,CC,F1,44,E3,F0,15,47,C9,34,92,7B,54,E9,0A,40,30,F0,80,CD,FF,E5,EA,4A,50,82,06,0C,25,79,E3,2A,A7,A8,F7,02,1C,4B,E3,FA,33,03,49,87,1A,7F,C6,F5,8D,D9,9A,CE,29,C9,60,DA,57,7C,1A,1E,EE,28,6C,CB,DD,15,E2,71,3B,4E,D3,2A,1F,42,BE,EF,41,5B,5B,4E,A6,18,7E,C7,9F,24,F6,75,17,E7,C4,AA,71,BE,EC,D6,14,C5,5C,CA,70,0E,A8,47,F1,B6,40,46,A5,6C,DD,B1,6F,65,8B,21,DE,C3,1A,F6,89,DE,10,C8,69,02,FF,F7,34,7E,C3,59,7C,41,64,06,A6,68,C0,A8,5E,AF,B5,4D,C2,4F,D4,B9,B2,5E,F6,7E,63,D1,EA,31,E4,66,F8,91,E5,CA,30,50,0B,35,46,3D,22,57,6B,02,B9,F9,E0,0C,32,FE,2B,E5,51,80,09,62,F8,7B,81,72,99,C1,05,ED,A1,EA,FD,54,E9,F6,A0,07,57,89,57,E6,38,A5,8C,FB,62,BE,25,1C,8A,3D,91,AA,1B,D0,E3,8A,41,76,93,E3,FA,39,2B,FE,93,BC,5D,56,02,7D,CC,F2,F3,A9,E4,AE,1E,76,58,75,73,9F,40,90,08,21,C8,F1,5E,4F,7B,8A,5A,A6,DB,4A,B2,E7,D0,AE,FE,E8,10,02,BD,DC,AD,4A,25,D9,50,03,E1,F3,06,06,B6,F5,BB,7C,D1,A4,8D,06,F4,34,DE,AD,04,8B,13,26,BC,7C,B1,79,D3,23,8D,B6,20,05,EC,CE,0A,A6,96,B4,79,D7,FA,C1,7C,9F,71,1F,50,88,05,0E,CB,57,A8,58,51,12,56,79,F2,DB,BB,00,B2,F8,57,CE,18,A2,1C,D5,35,06,F1,86,D0,A8,AD,D0,37,14,7C,09,42,FC,FD,F4,11,26,E2,FB,DC,C5,82,C4,48,46,CF,0C,6A,43,BB,FA,E3,50,B1,C3,D1,7F,2B,95,C9,40,CC,F8,BF,E0,C2,70,AB,83,97,25,71,9D,B6,D0,60,13,AA,ED,3E,FE,1C,D4,8E,0B,29,04,A9,74,21,8F,98,11,25,84,36,55,5B,CD,FC,7D,AE,1C,F7,99,7E,40,40,DA,B3,67,23,CA,87,B2,18,A7,02,F1,50,A2,9F,42,7E,8B,CC,E9,F8,C5,43,75,1E,9C,37,4C,62,63,6A,48,A3,A0,0E,1D,FB,AF,99,C0,3D,57,56,84,2C,C0,4E,72,F3,16,FA,AE,63,06,C6,5A,F4,C0,A7,25,14,8B,B7,93,C9,70,8E,87,21,B5,56,A1,B0,8F,94,4A,8D,56,52,2F,41,F7,66,25,2C,3D,5D,1B,BF,F9,2A,FA,F8,E2,E7,C6,E8,B4,B8,C2,E6,65,34,55,88,6B,BC,EE,AC,BD,99,93,9D,58,37,FF,2D,B7,6E,EB,16,8F,6E,6B,18,8F,39,4A,4C,9C,49,8F,8F,3A,B8,90,88,F7,FB,54,BE,54,1D,EA,ED,77,B6,10,BD,AD,D3,8D,1D,5A,68,7A,64,C1,63,58,66,A7,C5,DC,4A,A7,D1,CC,0B,D7,B0,9D,96,FE,C3,BE,91,92,FC,D9,F5,AB,8E,8B,D8,DE,0D,8F,61,35,BC,0F,45,8E,13,D5,84,C0,DA,66,4C,ED,DE,9C,C1,C0,EE,E4,03,24,85,AE,1D,9F,7F,06,0B,B9,05,C1,5D,9B,20,AE,0B,07,7B,03,45,69,F1,FE,73,B2,1C,45,06,DD,3C,17,B2,4E,96,6C,55,B8,F4,9D,3B,91,96,F6,2B,9F,65,E6,06,22,13,BC,0A,27,AF,2C,A3,FD,26,F7,E5,C7,5B,91,50,9E,80,F9,7D,16,F6,E4,D2,49,85,7A,4B,9D,76,E9,0A,A8,80,19,A3,0A,06,7D,4B,2D,50,34,CD,CB,D1,C3,00,71,88,3B,3B,BA,7C,FE,1D,50,18,D1,12,57,75,EC,EE,66,53,FE,0A,D9,0C,A5,82,7C,BC,A9,E0,79,DB,8E,36,FE,A1,7E,D1,00,74,BB,9C,4F,6C,79,7C,4D,1D,42,98,79,34,CD,0C,A6,82,F1,81,48,33,70,5A,ED,48,C5,70,C3,88,D9,8C,5A,E9,FA,47,73,A6,10,3C,BC,75,46,EB,AC,98,58,19,C6,74,0D,5C,62,24,23,90,3E,E5,07,6E,F2,67,D5,A2,DD,F7,98,A5,35,E3,8F,3C,BD,AF,E8,D9,CF,B5,1C,F0,1C,48,DF,D1,58,AB,82,69,B4,E7,EE,6F,4D,C1,1A,70,5B,5E,9D,8E,69,59,E3,21,E4,B0,86,57,53,A4,5B,C5,C5,A9,84,92,55,56,1F,41,2E,AC,51,DC,1C,F1,F3,E8,AF,8C,2A,01,C9,E4,BA,5E,1A,1F,43,00,99,87,1F,9D,9B,2A,B8,09,E4,9F,77,28,3A,7F,84,86,18,B0,F7,8F,EF,30,73,5D,23,C8,2B,B7,F3,52,29,72,F2,AE,07,1A,EA,7B,7B,70,B9,DA,05,64,5B,C4,74,ED,B0,E5,42,1B,AA,3B,D9,A6,87,A8,93,7B,B5,EC,22,9A,2F,77,CB,5D,60,7F,A1,0B,FA,A9,2A,D9,2C,AA,7E,B0,77,4F,15,51,92,65,EA,9A,44,81,92,BF,A5,21,D9,9E,40,46,AE,7A,80,2E,76,F4,A2,ED,37,B6,60,05,52,CE,91,9E,B2,D2,94,7B,93,DE,28,8A,7C,52,6A,D5,C7,10,0C,49,A4,EC,67,0A,75,4E,07,08,8A,99,FF,AB,9A,36,23,9C,42,13,E0,F6,12,9B,DC,EB,ED,F2,DD,58,A1,19,ED,06,3E,25,7F,74,AF,4D,09,29,EA,FE,03,71,27,20,A7,74,1E,0B,FC,65,2E,6A,71,49,D1,82,9B,67,67,2A,B7,18,62,9F,DF,9C,DE,9A,44,DD,C2,B0,9D,30,ED,66,49,1F,2D,C3,F8,F7,DA,ED,9B,10,E8,CB,56,02,64,D6,6E,C6,73,09,FA,8D,D1,F0,72,4F,95,50,06,7E,42,79,C5,D9,C2,CB,D3,03,75,EA,F7,67,0D,14,DC,ED,8A,90,57,08,2B,FB,55,9C,22,A8,84,A9,5B,2C,B7,71,B5,A1,C6,A6,65,3C,D6,47,42,EB,94,1B,5C,57,49,5F,D1,18,06,29,AE,E6,65,66,46,2A,60,FB,FF,49,07,AA,6B,40,F2,B8,BF,75,06,7A,F6,BF,03,67,60,1A,35,4C,1E,9A,FA,24,A7,00,86,45,CA,C0,B6,C0,15,82,B1,0F,C3,67,0F,5A,C2,D1,FF,ED,61,D2,BB,1E,36,BB,2F,BC,A8,17,19,FB,95,44,EE,34,2C,6E,9B,07,E9,31,CF,EC,10,F9,CA,2D,97,3B,DB,4E,54,08,DB,BC,88,0A,15,9C,DF,7B,C3,3B,A8,FE,E0,44,34,C3,E4,51,CD,27,03,42,5A,72,38,34,DE,16,98,21,55,B1,16,D4,9E,90,BD,E1,DE,D6,A7,44,F3,83,ED,A9,D5,69,B5,7C,43,02,90,B3,2E,24,C4,FC,E3,3B,27,90,FA,BF,6B,0D,11,66,C5,01,E4,DC,2B,84,CD,E5,95,85,34,41,35,34,5E,CD,9D,C3,0A,F5,65,75,17,7F,F3,30,3C,E3,52,61,D8,96,48,77,32,62,F9,84,78,25,81,9D,B3,D8,8E,C4,0D,88,58,A6,05,18,E3,B4,20,2E,AD,C9,99,42,09,2A,05,2B,30,37,B0,A5,C4,FC,08,F4,CE,B6,F2,5A,22,17,1F,1B,98,DF,28,E2,01,F2,AD,F5,41,11,F7,41,21,8A,DC,10,2A,AC,F4,07,42,7A,40,1D,09,74,95,84,DC,43,E9,6D,81,14,F9,6A,0B,D1,DB,6C,E0,59,43,AD,4D,3E,F7,7B,2F,52,1C,F1,8D,1C,FE,C9,D9,AC,1F,D0,27,17,69,AF,BD,91,C0,E8,07,0D,F4,03,7E,5E,83,DD,4C,7C,90,53,30,FA,46,FB,33,7E,DE,04,B8,31,1D,7D,E9,C4,CB,9B,38,3A,8B,63,DF,25,BC,E1,1F,E7,DE,50,2A,CB,AF,B4,12,EB,6B,90,F7,98,05,37,E3,9C,DC,D8,90,AB,AC,2D,7A,6D,FF,1B,D7,10,CE,50,6C,95,91,C3,E2,70,6B,A3,C1,C9,A0,7A,93,21,28,F1,57,2C,E1,65,61,67,7C,86,07,99,AA,FF,8F,CF,D8,E6,33,15,07,53,B0,38,8A,14,0D,58,49,D0,5A,62,E2,7D,31,67,A0,5E,EE,00,63,F9,B3,D6,24,E1,03,4E,22,05,09,69,87,CD,B1,8C,6D,36,A8,0C,71,30,C8,01,68,7F,B4,69,B3,64,15,3B,67,DA,3D,02,1C,7D,68,A9,C6,CD,05,DF,E5,18,05,A8,7C,4B,45,B7,BC,73,76,16,D8,A2,41,C1,DE,8B,A7,C7,BA,07,B6,6A,31,FC,E1,54,64,A8,5B,73,8C,7E,C8,34,ED,A6,9E,18,3F,18,96,FE,EB,00,E3,FD,CD,3B,D4,D3,AF,66,C5,8C,7A,23,A6,80,EE,97,E9,E6,A1,64,C0,74,2D,22,1E,C5,D4,4F,17,99,F4,91,22,1F,28,31,A8,2A,DA,81,EE,DD,BF,FB,EB,E5,29,5B,46,9B,DF,64,31,EF,3F,9B,9A,8D,90,95,56,A0,BB,A6,A6,AE,AF,45,9B,5C,06,2C,AB,66,AC,E8,20,C1,07,A3,36,89,11,74,D9,96,7C,E6,A5,CB,36,43,78,5A,49,6F,14,7C,4F,61,97,62,77,F9,95,9B,CD,4D,6F,CD,09,38,14,5A,27,A2,D1,1B,F5,5E,05,54,90,2D,2F,09,62,47,31,CC,4B,C3,F8,4C,2D,CE,0D,11,38,9B,D2,F3,0F,11,F4,94,D0,2E,D8,88,BA,CD,CE,66,F4,C6,BF,B3,FA,43,1F,F3,08,6E,2A,81,3C,B5,A2,16,90,A6,80,1A,63,96,4E,21,E8,DA,38,B1,23,63,EA,FF,49,FD,27,6B,65,5D,EA,25,F1,96,AB,28,25,E3,A2,CF,DC,E5,7E,A7,A6,BE,5E,B2,DF,9B,FA,29,C3,66,83,0D,07,51,34,DF,1C,CD,63,37,25,5F,5F,2A,41,09,CB,AE,F0,F7,E5,A2,80,71,AD,F7,08,38,91,E2,C5,41,C8,E7,BB,B7,45,97,91,34,2F,BF,2E,BD,DE,3D,A9,E5,CB,CD,94,18,ED,43,F1,09,F7,DE,3D,05,58,A2,BC,8F,AC,86,16,8B,09,9F,7E,42,58,AF,D0,72,53,41,FB,20,F4,61,FA,AE,BB,8C,09,56,23,4E,14,37,19,DF,89,F0,F7,D4,A0,4D,D1,AA,23,62,C7,80,7A,76,58,C4,1C,AD,CB,9A,BC,C3,46,E7,86,D3,07,E9,39,8E,DC,00,DA,FF,7A,DE,D4,13,74,DC,1D,22,CC,28,4F,2C,CB,54,08,CF,B1,29,51,2E,D6,A2,10,07,80,A8,16,35,A3,A3,83,D1,02,F6,91,C0,35,08,94,84,B7,A5,56,D6,7D,3E,9B,D7,DC,AC,D7,7B,2A,3B,5C,DA,4F,9C,E7,67,DD,79,BD,8B,DA,B6,F0,D4,C6,87,C9,73,3F,96,5B,85,42,48,E2,52,4F,F3,87,90,8D,A7,8D,84,40,83,63,E6,07,FB,21,9C,95,9B,07,FF,1D,E9,EC,4F,03,9D,D9,CD,BD,90,DA,E7,43,7E,67,C0,39,2E,E5,8F,DC,2E,23,64,67,45,CF,51,F3,50,24,46,11,9F,BA,B5,74,7D,E3,D6,EF,81,C5,37,D3,C3,9C,85,3B,2D,D6,DD,20,4C,2B,70,B8,B3,76,74,E0,D3,56,D9,E4,9E,A1,C0,FF,87,D2,B1,55,5B,63,C9,39,28,EC,41,8D,7E,A4,62,2F,B3,00,9A,F5,8F,03,91,22,89,85,56,70,5A,8F,04,A0,70,2C,61,F1,56,69,29,4B,69,E6,DE,65,FD,6F,4B,F8,DB,A3,B9,70,A1,5D,AF,78,30,AC,07,08,C5,E0,CA,0A,7F,3A,2B,27,F6,3A,55,68,D1,8B,A0,0B,D2,2A,3F,43,BC,2E,0E,0B,AD,BE,9D,2C,07,9D,6E,9E,B3,C8,4C,21,FC,4A,43,62,8F,2A,1F,B9,A1,F2,6A,66,9B,EC,9A,C6,89,30,9C,AC,38,A9,C4,AC,23,E5,C4,53,65,0A,D8,72,FE,97,B8,41,6C,CB,F1,A1,B7,D3,47,B7,C1,32,23,07,5E,A9,57,59,DF,E9,9D,E2,9D,39,10,38,D5,89,71,D3,D3,4C,D3,6A,41,96,F6,F1,F5,97,A9,73,5F,71,90,C0,6B,7E,B0,62,EA,4A,C7,CD,A6,D0,0B,67,26,8E,AD,CD,67,E3,A0,7D,70,42,84,64,21,34,76,E9,F7,A5,A2,CE,55,05,1D,B4,70,B7,E6,D7,63,18,F4,CC,F0,32,31,F4,E8,D9,A3,F6,C1,20,B5,2B,9F,94,52,47,0B,E1,32,5C,E4,7F,97,9B,41,86,F0,B4,63,4D,7A,CF,14,BF,24,EE,21,37,89,C2,03,E2,77,AF,D5,B1,7D,F2,67,C8,A4,89,C6,BF,5D,1C,2C,71,C1,77,75,03,B7,28,D0,78,A6,00,A4,F6,25,4B,57,FA,63,BF,32,1E,54,D8,FC,C5,1A,10,1B,52,F1,0A,C1,A6,44,3F,C5,62,93,BA,C9,8D,0F,07,31,09,61,6B,84,4C,8A,12,2D,A9,5D,F2,27,56,9D,9A,82,5C,B3,18,E2,D6,AD,FD,29,D3,18,50,B9,7F,30,81,20,AE,FD,98,6A,8E,4A,83,9B,63,08,46,9F,E5,49,8C,1C,10,9B,9C,AF,F5,C2,02,F0,99,33,AD,8B,DC,BC,62,66,60,42,92,95,94,02,03,3D,6A,16,88,1A,2F,FC,0F,E4,85,5F,45,4D,76,06,B2,C0,28,EA,29,06,8A,38,96,40,70,10,C8,DA,1C,0F,6D,E9,39,B0,B9,C1,B0,BD,FF,82,B3,1A,05,6B,54,0F,45,EF,34,CC,7F,74,B1,CB,2A,C6,C3,2B,E8,27,D0,47,5B,9D,DF,67,9D,45,86,00,C8,15,DB,EE,39,DA,08,CA,11,31,1C,D9,22,BB,6C,32,6F,01,D7,E4,98,D6,D6,7B,DE,EB,11,D1,DC,B6,33,1E,7C,B9,19,83,08,46,BB,AD,E6,7D,54,A2,58,F1,56,D3,EA,DE,70,3E,2B,00,19,53,CD,A7,13,29,04,31,5A,03,B6,EE,0F,C6,29,B3,51,13,FC,1B,9B,2C,9D,93,9A,10,3E,82,F2,99,85,DA,86,EB,4A,C7,0E,D6,95,41,5C,30,6D,1F,F8,AF,34,6B,D4,D8,D3,E5,36,82,8F,29,8B,DC,85,84,3E,8C,92,CC,60,1D,92,BD,11,3D,3E,4A,DC,54,F9,A2,65,01,EF,64,B5,BA,B1,3E,26,DE,0D,CA,D0,6E,FC,BA,40,E4,C8,BC,47,46,3F,FC,2A,59,B7,AC,5F,38,D9,B7,B6,B3,FC,C4,3D,E2,92,DC,38,D6,F4,B2,5C,09,B3,D0,A1,29,BF,C0,89,1B,5A,C1,1A,34,E2,B1,5D,50,DC,AD,A4,2E,9D,4F,53,A1,DB,90,2A,03,82,BA,88,AA,F4,03,1C,BF,80,E0,AD,F4,4E,5D,35,DF,C1,16,26,6A,9A,07,A0,2B,99,DC,15,8D,F4,61,C1,AE,58,94,C2,DB,C3,BF,6B,34,60,1B,6B,A0,CE,05,04,CA,B0,C8,39,24,13,E2,9B,70,09,D8,B4,F3,A5,D5,1C,46,DA,45,11,19,DA,37,D1,C4,A1,F0,75,5C,7E,C0,05,86,26,E3,32,96,08,F5,1D,0D,64,5A,35,F1,22,25,1B,77,E8,EE,B3,32,5A,D2,EF,ED,2E,62,64,E0,D8,4D,26,33,B0,9C,97,8F,16,22,3F,0D,DB,2B,AF,9B,AF,F0,AF,89,D4,88,83,79,DC,FE,37,56,E0,F2,DB,4C,91,74,AC,C2,2C,78,6E,7B,8D,B4,7F,02,C7,D8,F7,02,6F,BA,1F,09,D2,C0,C3,DA,99,CE,AC,17,0C,52,BE,14,91,44,C1,B6,4E,12,A9,E0,F0,BA,38,F1,DD,C2,7B,A9,65,1D,B3,FF,AA,62,44,87,80,04,4D,42,CF,9C,AE,D0,32,4D,70,0E,C9,D8,01,56,63,78,C0,02,84,4D,7E,A3,B8,39,FF,21,58,52,C5,13,C6,C9,E9,0E,34,13,59,D7,0E,C7,BF,70,D3,A8,CD,FF,42,CD,97,A6,57,06,34,CD,B7,C6,39,D8,5D,C3,F1,0D,04,7A,99,FD,49,40,B9,D9,15,EE,A2,B2,32,D2,9C,3D,2C,9F,BC,1C,16,58,88,44,A4,17,F1,CF,91,A0,7A,B5,17,E4,05,2E,F9,A3,5E,29,83,11,AB,DA,03,D8,B9,F0,80,48,69,64,99,EC,E9,52,66,16,3E,32,09,0B,EF,C6,F7,72,94,7E,51,9F,6B,A8,FD,5A,BC,56,F2,6F,5E,91,CD,C5,1E,0D,39,F4,0E,CE,BC,ED,E4,8D,C3,F6,3E,9D,37,3F,0E,C0,DF,29,8E,0F,F5,DF,12,6C,4F,F0,23,3B,20,08,1C,A4,0F,64,C6,C1,2D,14,E3,11,97,F7,B3,CD,25,66,4B,E0,63,AF,73,A5,6C,94,6F,B1,05,56,1A,41,D5,F6,55,7B,42,5E,6C,C1,7C,53,C8,4B,A0,76,3E,F2,26,E6,57,48,FD,F3,71,23,24,C2,80,8E,30,86,CC,D2,A4,82,B9,1C,CE,90,89,36,5F,A6,0E,78,37,A0,A0,32,B6,5D,40,52,5C,5F,59,26,80,1E,CD,10,FF,3C,A0,CB,1B,21,FB,C6,CB,7F,C4,78,06,B7,34,96,1C,97,58,93,43,1C,47,BD,50,9A,8E,E7,96,33,24,E3,6C,0C,90,90,F9,8C,CF,65,E9,6D,6B,59,64,65,68,2A,0C,09,A4,E1,1F,E2,37,79,5E,1B,F7,41,B1,BD,E8,70,FA,3C,C8,E4,55,36,E2,47,62,95,BC,43,09,85,35,74,F0,92,64,D7,87,65,48,D9,60,70,1D,6E,95,03,74,3F,28,19,95,1C,D2,BD,42,0D,C9,66,02,66,6C,A6,92,99,6D,3E,C2,49,DD,DA,36,FF,89,5E,F1,7B,53,C9,82,09,91,03,F4,B6,0C,0F,C5,DA,F6,18,E0,A9,BD,53,A3,7C,95,94,5E,6B,3A,49,FB,2E,13,14,62,92,8B,DC,6B,66,F5,B4,E8,B4,F6,F5,D2,70,27,E6,05,B3,44,3B,F5,5B,3D,89,A8,D8,84,BB,EE,E0,E9,55,57,C4,56,A3,50,A5,F3,C4,98,84,FA,95,F9,04,AA,EB,A9,E5,21,44,A2,43,9A,BC,7B,72,84,B4,A1,2D,93,09,51,89,B7,51,54,5E,16,64,9E,92,DC,15,88,5A,09,9C,5E,F6,9C,A7,A7,17,C0,EE,D2,D7,DC,C3,A3,56,47,CF,2E,24,03,CC,8D,46,A3,C1,7B,13,3C,52,CA,52,FE,C1,8E,AB,8B,29,ED,C4,81,FA,AE,50,43,11,65,49,7B,2F,0B,83,EC,BB,22,DB,C0,BE,10,F8,C9,19,5C,86,2B,F1,77,C8,FB,0E,89,FF,38,6C,70,4D,7B,B7,2F,24,2B,D7,12,1C,F2,EC,0F,E4,D5,26,36,05,14,7A,80,BA,DB,6B,14,F8,9D,74,AC,28,53,B8,A8,B8,05,FD,09,5B,4D,88,CA,28,EA,A1,C9,66,73,FA,CE,26,A1,EE,CD,CA,E1,20,81,D0,7B,71,0C,A3,68,E0,74,23,64,80,BE,4D,FA,E9,E3,30,3F,81,C2,70,0E,4B,99,D9,48,9A,D6,8C,4E,A6,A4,F6,69,9A,3A,7C,33,E1,39,82,73,04,F6,01,08,24,71,9F,8C,A6,6F,E4,1C,FF,8A,A3,FD,6A,E8,84,1A,1C,9F,67,4C,AC,0A,46,AD,C9,4A,B3,F4,EB,0B,14,16,13,4A,D4,36,45,22,3D,FA,37,50,74,A8,86,AA,17,48,66,D3,40,1A,95,82,64,A0,97,62,B4,5F,A7,6E,A3,40,3B,F2,55,64,74,CF,D7,D3,C8,52,7D,DC,6B,12,4D,47,DF,CB,49,6F,07,80,6A,A9,04,BB,06,8F,79,A2,91,23,CC,97,CD,FD,24,97,D1,E3,77,93,6E,28,D1,B9,19,93,DA,1F,2C,F9,7B,63,B3,34,F8,6F,AC,A9,97,38,28,F8,42,79,DD,FB,7E,6B,F3,F2,48,44,21,3D,6F,54,86,D5,1B,D3,84,E1,65,21,70,EA,0F,49,FB,63,3D,E2,CD,2C,D4,20,11,26,38,DC,9E,6F,CC,15,61,D6,2D,22,B7,7B,A4,0C,92,56,A5,62,81,B1,73,9A,27,1B,5F,FC,B3,43,02,9B,7B,A3,88,37,E3,96,3D,7C,1E,EB,3C,3D,8F,49,6C,F2,7F,A3,83,3F,C7,A6,21,7D,6F,CD,16,DE,3E,39,CE,4B,CC,00,24,8D,F5,F4,63,20,57,20,86,3E,6F,86,5E,09,EC,3D,3E,95,E4,19,B2,8B,19,09,13,92,3D,12,F0,0F,90,17,10,3B,02,EC,50,09,A3,57,9B,6B,EC,EA,C6,32,E8,B4,51,37,A6,C8,61,6D,A2,74,FD,9B,D8,CA,91,15,64,A7,08,1B,A8,C2,52,F2,ED,67,9E,73,66,35,82,E6,BE,D0,B4,CC,F3,4C,11,6A,F4,E4,94,71,41,18,86,40,7C,A3,70,51,B9,AE,02,D9,16,B8,47,E8,33,6B,9F,F2,84,9E,00,FD,F9,EC,0D,37,9D,0B,A5,88,D0,C4,1A,FE,46,A8,EA,4F,18,8D,E4,FB,82,FE,D9,BB,A0,5D,40,79,82,1F,A0,5B,D7,07,6F,3E,50,14,9F,52,3A,73,FE,C4,EF,93,11,1D,10,6C,4E,18,D2,AC,7C,C7,E1,E3,61,A7,03,26,75,15,EF,ED,F5,49,C2,3E,EC,B4,13,A0,B0,84,7D,5E,B8,A5,92,6A,29,BD,BD,B7,84,BF,51,FA,5C,86,6C,E3,50,42,C7,4D,C6,C0,A2,E6,A2,15,00,B8,E5,0E,21,D1,15,CF,8C,43,45,67,2D,0F,0E,1F,F8,E1,B2,AF,93,CD,1C,AE,13,A9,8F,93,70,3B,B3,64,4D,C6,3C,9D,4C,84,93,82,CE,99,13,F1,38,2E,FB,68,10,BD,34,5A,4A,41,9A,BE,06,DB,83,6F,A8,EB,10,79,D3,C3,56,6A,3A,74,93,A1,2A,5A,47,6B,11,25,F8,58,44,8B,BD,1B,59,15,9C,93,25,41,05,50,18,50,53,3E,33,62,D6,F1,73,85,67,83,CE,A3,D5,22,4F,E6,85,39,1D,1B,D8,09,28,2F,E1,59,34,8B,59,A9,F4,91,84,BF,69,0F,AE,EA,1F,0E,04,DC,D8,96,71,49,8F,A1,EC,A0,1D,F2,FF,15,8A,8A,D5,47,FA,8D,C9,24,97,D6,D9,4B,F6,C4,33,FF,80,8A,14,EE,87,D0,91,E4,FA,AE,70,F3,9D,66,C8,48,AB,EB,11,01,C7,2F,96,F9,72,80,93,99,F4,92,F1,18,14,79,6F,29,26,17,0A,10,83,CB,DE,BA,B4,92,EA,01,D2,12,82,DE,C3,7C,E7,A3,B8,FD,E1,F4,8A,F1,D5,1B,E7,48,06,18,7C,E8,8A,D9,82,43,60,44,CD,C4,56,BF,DD,DD,97,33,F7,65,F1,50,7B,BF,E5,14,1A,C6,F5,67,43,91,B0,4D,4E,1D,D7,8C,B5,EC,7D,80,AB,C8,CF,E9,EA,C2,09,43,E8,8C,80,B5,BA,F9,43,9A,CC,58,43,71,D9,5D,1D,9E,A8,CC,51,1A,1E,77,7A,78,AC,F6,F7,64,F3,9E,A2,BF,54,95,94,DC,E4,CB,D3,FA,D0,90,DF,7F,2E,1A,2A,ED,09,AB,F1,3B,02,50,82,D7,03,36,F3,FA,AD,13,9D,47,8B,62,F6,BB,78,83,E1,ED,E0,C7,43,05,08,61,C4,7E,14,9A,A6,D1,E6,49,2B,AC,31,8C,57,52,8A,71,28,C7,A5,EF,34,FE,C9,E3,DA,C2,7B,B5,C4,3B,66,BA,E1,3C,A0,88,AC,23,FA,2A,88,C5,7C,D4,6A,38,AF,C8,79,8E,14,79,06,FC,A7,EB,FD,65,0B,FC,AD,46,5F,83,80,6F,9F,EE,AA,EE,2B,6A,C6,7B,41,29,87,B3,67,19,FE,E5,41,5D,21,FF,7D,82,F9,32,B5,52,28,00,65,77,F8,BE,74,33,D5,AA,A5,D2,24,55,7E,A3,08,35,44,3F,87,43,98,03,E4,20,A1,CD,E8,71,C9,7D,D0,E7,51,80,35,B3,BB,B8,13,72,62,41,49,74,32,81,0C,8A,71,EB,43,65,63,47,82,66,AC,A0,9A,81,24,E2,51,48,4B,A0,04,B9,49,30,15,7B,6E,B0,D9,B4,B4,05,76,ED,08,E8,E1,D7,59,1C,43,19,37,AF,53,21,1A,02,4C,BA,9C,12,B7,C9,C9,8C,23,53,F9,D8,80,7C,77,10,B9,04,85,AA,24,65,0C,07,D0,84,06,7B,93,B6,0C,A6,E9,C7,A4,DB,D3,00,5D,15,3B,AF,31,04,00,B2,95,CB,2A,2F,1E,1D,7B,73,90,E7,62,55,4C,1A,39,2F,C4,FD,BF,82,11,BC,CD,7D,5A,13,F6,7F,AD,B4,48,94,16,F0,C3,ED,80,B9,78,23,DF,30,67,66,40,50,0A,BC,1F,17,24,85,E7,5F,20,D7,5D,AD,19,ED,F8,47,7D,4C,70,9D,16,9A,96,4C,30,87,14,88,0A,F8,1B,41,3F,14,50,41,AA,B9,57,77,5F,6E,D6,CF,FE,C7,37,66,CD,50,E0,30,5A,F2,07,AA,51,37,CC,D1,16,3D,45,A5,D2,D1,8E,96,BE,A9,F2,2A,EA,62,07,AB,78,33,8A,6D,03,9E,54,79,52,95,27,F7,B1,3A,D6,46,3B,0F,02,04,4C,4D,E3,D8,5A,D1,FF,1E,91,E5,8D,18,EB,49,B9,D3,A8,D7,40,DC,C7,AD,EB,70,77,71,82,EF,5D,EF,49,42,42,1B,B6,24,33,E7,C2,4A,F3,62,65,8A,57,4F,A4,44,F0,76,2B,CB,0A,74,28,33,EB,77,00,50,4D,DA,5D,04,4E,85,40,E7,4D,79,69,44,B3,9A,74,C9,76,E6,3C,9A,FE,AF,F4,48,8A,C9,40,62,1E,35,CF,F7,CB,3F,0D,4B,BF,D5,BC,20,E7,41,A8,D2,3F,E1,2B,B8,FA,5F,B3,D4,46,DB,8D,81,31,DD,FC,AE,3E,52,74,22,05,34,19,1F,7D,04,6A,0B,31,E0,55,D1,28,7D,A0,E3,80,42,2D,13,B0,B2,5F,3B,5C,E6,BF,CA,04,C6,E1,30,4F,9F,92,FF,06,31,4A,50,AB,3E,ED,06,F2,15,BD,66,E0,19,00,10,13,88,CF,30,EE,47,25,FF,E2,E8,5D,99,31,25,F3,5E,42,6C,38,31,7B,84,8A,DE,C7,19,4D,AC,56,0F,8F,CE,EA,FA,01,ED,5E,1D,3C,44,F8,43,07,97,9C,2A,D2,DE,2F,D3,B3,86,9C,85,38,F4,3C,B9,51,77,E9,E7,A1,9C,A7,4D,18,C7,DA,73,DF,71,E2,E9,7A,68,62,AE,EE,E3,05,33,93,7C,88,B2,F6,3F,B6,57,88,B8,51,F4,36,94,10,9D,DF,95,84,5C,C9,07,E4,D3,63,CE,C8,EF,36,A2,71,8B,7C,70,58,C8,8F,06,1A,09,17,37,3A,5E,19,11,F1,6D,42,B3,B6,09,4D,E9,D6,3E,EB,CD,3D,48,85,2F,C8,9A,A1,D8,82,A8,F0,D0,0E,D2,A8,EE,DA,B6,24,2F,7D,B8,C6,70,AC,CD,FD,7B,19,52,87,DA,7E,FC,3D,D1,22,75,F7,87,29,9A,5B,A2,10,3B,44,15,26,59,62,C3,FD,04,90,CD,B7,69,77,C3,40,37,10,3B,16,38,18,37,AF,B9,0F,45,5A,01,7F,22,4A,AA,15,B6,4B,4A,7F,83,6C,27,A9,B1,E0,DC,10,49,43,91,96,39,63,B2,B7,AA,97,19,75,9D,1B,31,B2,11,2F,25,ED,3A,0B,7C,46,BA,D4,FD,7E,B0,50,97,1F,8A,C4,5B,49,48,7D,5E,D8,04,B9,8B,87,27,45,9D,21,FD,11,B9,7B,91,CC,3A,93,28,FA,4A,FC,36,56,2D,9A,53,93,1D,08,4C,8E,55,61,35,4C,D7,44,D8,E7,F9,C5,CE,14,45,DE,C1,19,BA,0E,DE,47,69,76,A1,A4,15,4B,BA,30,9B,75,54,25,A2,25,DD,F7,02,2B,F1,FB,1D,2F,DE,D3,A3,15,37,17,B3,31,4B,2E,D5,C9,14,12,27,BD,B7,BA,08,25,41,FB,7C,E9,D5,55,7A,07,44,3D,C4,20,E4,E6,CD,71,EF,34,2F,B5,D8,D0,A3,9A,5E,E3,C6,DD,F8,A8,93,9E,C2,43,8A,8D,4E,36,A7,9E,5E,FD,31,A1,ED,B8,2A,9F,F5,35,06,59,8A,F3,84,D2,13,6F,39,2E,CF,CB,83,29,7E,53,D0,73,1E,EC,9B,81,43,98,3C,48,21,D3,44,D7,5A,24,34,02,C8,45,F0,B4,7B,CB,D8,E4,8C,C0,64,AD,84,37,C9,D7,9B,A0,BA,DE,92,12,18,05,DF,AF,E7,5E,F2,C1,9A,FC,C7,5D,79,2B,D3,CB,1B,6F,56,EF,FF,55,91,10,27,60,E2,7A,EE,4F,2F,D2,85,CF,08,F6,D2,BF,DE,44,59,E7,0E,87,19,6D,A7,C0,09,CD,DF,4B,04,F0,7E,E0,60,44,10,9E,55,F9,32,3D,FC,D5,D5,45,7E,44,9D,2A,4A,7A,E5,BB,0A,50,C4,06,ED,52,14,35,A7,63,C7,D1,EE,49,78,D8,EA,BF,38,58,C9,ED,7A,72,96,C8,C8,E8,06,95,4A,B7,46,A4,1D,2E,81,AD,37,B8,1F,37,20,86,5D,16,9C,71,07,E2,41,69,A2,0E,AC,6D,BA,BB,88,A1,AE,7F,BE,AC,68,3B,09,CF,C5,5C,7A,8D,87,DC,9C,7F,5D,27,E5,2A,F8,24,12,A9,A0,25,DA,84,66,98,8D,44,1B,F3,FD,79,3B,B3,0D,0B,A6,0D,4E,06,37,B2,D2,3B,66,31,EF,BF,93,D8,29,3D,36,F4,5E,63,BB,12,D6,2C,B8,BF,70,E7,B6,30,7C,89,AB,16,69,EA,CF,4F,AC,95,22,32,14,BF,C4,AF,AA,B7,2C,1B,C5,99,B4,16,F7,4C,A4,9A,98,27,9D,ED,67,D2,13,15,40,EE,BE,AB,C8,C6,DD,39,20,82,24,A1,22,6C,FB,B4,71,C0,C4,51,7D,66,7A,78,2E,0B,9B,1A,8B,E9,6A,69,45,8D,80,1F,A3,7D,86,5D,6A,57,90,93,D9,92,24,08,0C,E5,6A,C2,71,1A,C1,47,DF,21,DD,FF,58,8D,78,B4,FF,B7,81,C3,52,1B,2D,18,04,9B,B7,44,AA,3B,22,44,44,2B,FA,32,0D,4A,91,0B,C4,B0,D7,B7,77,F2,4C,6D,77,5B,F9,30,80,5B,B5,92,D8,27,8B,33,3F,AA,76,3C,7D,DA,40,0D,70,F0,1C,81,12,0A,45,DB,FF,5A,19,1B,26,BC,9A,C3,5B,E4,48,0D,27,8B,3E,63,44,C0,92,B7,BC,11,78,E6,C8,7B,97,92,3F,99,F0,8D,98,CD,86,48,85,A6,72,F0,73,21,4A,12,40,D5,F8,56,FB,C0,B4,84,26,FF,C6,D1,B5,65,DD,66,96,97,08,53,70,75,B6,FE,0B,6E,6C,13,7A,45,18,E4,EC,9A,49,5A,82,72,13,39,B4,1B,C5,E5,B8,DB,CB,26,88,8B,D8,EE,AB,94,41,0D,51,83,CD,1B,70,DF,6E,ED,D0,76,B1,EB,78,9C,EE,97,F1,87,C9,1E,45,B9,08,D6,0B,ED,6F,97,99,F7,A6,84,70,D2,6D,6C,2B,DF,78,AC,BA,72,9E,94,31,0C,8B,08,C0,6D,11,52,9A,00,DB,08,69,85,9E,23,9E,EA,26,5D,BE,4E,04,9D,2D,9E,08,24,92,7C,37,9F,F9,8D,FD,D3,5B,F8,B3,94,4B,3A,90,01,75,FE,05,DD,32,BE,40,25,07,0C,F7,3D,21,D1,AA,5E,2B,15,BE,37,C0,B6,7F,BB,01,86,09,A9,D9,13,5A,2C,5A,8C,0C,09,08,0A,77,97,1D,72,81,FE,6E,3F,52,52,DC,EA,C8,7B,AC,89,7E,20,83,46,E4,E2,35,26,80,B7,1E,52,FF,D1,99,87,F2,5F,B3,37,01,23,99,32,B2,70,63,17,AF,E9,4A,93,48,3D,D7,9F,E0,31,61,F5,32,16,DE,DD,F7,87,62,73,48,3A,62,40,9A,97,5B,8C,85,15,31,13,FD,7D,FE,0E,B8,26,32,37,0F,87,4C,B6,24,EF,0C,E2,A6,B3,15,34,C0,6E,8D,A8,A5,60,3C,89,47,A0,56,C7,0D,41,9E,85,B8,2D,7F,31,1F,4E,CC,6E,49,A6,74,DC,F0,2F,FB,AC,C5,E3,50,34,CE,F2,7C,AE,3F,CE,1F,29,7B,93,0B,30,FA,F8,2C,B1,05,F4,CE,E0,6E,BA,13,E3,E5,2C,CA,3C,28,8E,73,E5,1A,E8,C7,A4,D2,C7,31,31,9D,9A,AB,5C,8F,67,9C,E9,63,82,66,8E,E5,B9,4A,7E,04,2D,07,03,CB,A8,2D,C5,C3,26,9F,C9,57,04,63,08,BA,0B,7C,AC,E2,CD,CD,21,82,75,2B,5E,C0,EB,33,57,6E,98,A1,C3,0D,4D,D5,5D,38,19,0C,8B,8B,60,85,70,B6,32,B1,17,3D,F3,0F,75,AC,89,5E,79,71,41,DA,B2,58,BC,31,45,A3,20,A4,AE,D2,FF,13,6A,57,E5,74,20,FD,6E,9A,42,06,F9,A0,DB,19,11,70,FA,48,B7,DF,3A,B6,C1,99,27,B3,7D,F8,03,7F,9A,A7,71,0E,8A,72,77,11,07,74,31,C7,0A,EA,58,6F,DD,3F,4E,B2,FE,C3,E3,0A,04,C7,A1,CA,6A,EE,40,0B,91,37,D8,63,A9,AB,F9,4A,7E,FC,A7,4F,E2,CB,62,8C,5B,54,A9,A2,A0,F3,68,3C,7D,3F,69,42,87,DB,0E,C2,2B,01,00,F8,AE,FE,20,F4,0E,2F,D4,F7,1D,EC,CC,AA,7B,F4,AD,D8,E7,4A,BA,D8,9C,8F,5D,75,02,35,C4,38,C2,51,07,84,D6,4E,85,BA,7A,B6,14,05,8A,25,06,FD,3B,05,19,CE,6C,6F,8F,9F,75,70,8E,12,57,0E,35,A8,0A,E9,84,74,07,69,41,C6,39,8A,35,5C,79,83,63,00,98,78,92,3B,A2,B9,62,F7,73,33,79,A7,11,83,3B,C6,2F,37,43,92,24,D3,0E,78,6B,00,AF,C8,ED,C5,5E,95,5B,CE,4D,D4,4C,1A,CB,E2,53,70,FE,18,B3,7F,39,A7,73,94,86,84,E6,74,4B,52,71,82,64,6A,6B,B3,9D,22,95,82,AB,FF,88,F5,EE,0D,A9,CE,F3,FB,C8,66,75,2B,50,5A,4E,BC,4F,74,CF,23,5F,F4,57,C4,5F,0E,52,24,45,56,DE,9F,43,F3,55,F8,BA,92,DF,2F,BD,71,45,1A,24,DD,38,59,72,80,E3,CD,DA,83,AD,C8,B7,6A,31,1F,8C,BC,32,24,CE,94,EC,B7,B8,92,65,1D,DE,58,6C,E2,FE,4A,FB,3D,60,CB,4A,12,57,EA,58,9C,5F,B9,DA,DA,8A,26,3E,49,11,B1,2B,14,C0,6C,25,9C,15,79,D6,77,5F,8A,AA,C1,39,86,DD,4F,BF,49,54,EB,27,89,95,8C,50,32,20,CE,98,4F,C1,DC,B6,48,D2,FA,EC,52,5A,39,C1,B4,4D,3A,E2,7B,59,64,E5,95,74,A6,2F,29,44,56,9A,E8,AF,62,94,87,7B,E4,37,1F,28,AB,5A,F3,42,46,81,23,6C,97,BC,85,15,16,3E,7F,FF,FC,DF,CF,26,A2,EA,CC,27,B9,60,69,CB,C9,5A,3B,B6,F7,DB,2B,44,62,7E,16,94,BF,F5,74,50,1B,82,8D,21,A0,3A,61,ED,D3,21,36,1B,16,A8,8C,39,5A,F1,CE,55,64,6B,A4,F6,94,A4,84,58,62,F9,B5,EC,4F,01,EE,85,96,BF,70,EC,3B,CB,BE,4F,A2,60,75,68,7A,60,86,92,DF,58,15,69,00,B6,C7,BB,F0,04,8B,0A,F4,99,AE,F6,32,B5,D3,5D,FB,6D,40,53,70,57,76,6A,72,88,10,5F,A0,8E,BC,EC,5E,16,D3,C3,6D,2D,19,AF,B1,E6,6F,AE,93,51,CF,A0,59,14,57,F0,5D,10,72,5E,2B,5E,55,F8,40,E5,FB,5F,E5,CE,2A,5B,C4,9E,CF,B5,06,90,5A,D3,25,D7,E4,56,BB,C7,E9,F6,B0,87,FB,E3,41,37,2A,BE,D9,27,0E,D3,C5,BF,3B,74,B2,EF,16,2D,28,5E,43,81,1E,81,52,98,90,4B,03,36,CB,47,02,AC,0D,CE,E4,CD,C4,79,47,E6,10,B5,38,AA,0B,83,0E,98,F1,AE,F2,D4,80,F3,D2,2B,67,45,4A,40,73,AC,C1,F5,9E,28,B3,58,1B,5D,B2,C0,8A,4F,0D,4A,5A,7C,6D,88,6C,57,B3,F4,18,FB,73,FF,3B,72,3B,D8,57,12,8F,25,C3,69,AA,81,0E,13,A5,09,BE,B0,1D,85,AE,EB,05,10,A5,B1,EC,70,E8,34,16,D4,5A,2E,E0,03,9B,B2,43,DC,A3,3E,AF,FF,37,F7,F1,B4,6F,59,A7,51,49,08,D1,C6,1A,83,5B,C1,04,BC,7F,34,7F,6B,DB,40,4D,EF,C1,0D,6B,D2,4E,6B,E4,A3,B4,A1,6D,A4,30,1C,67,17,3F,88,F9,B4,9B,EE,84,32,1A,07,F2,D8,FF,36,3F,28,EF,70,4D,2B,59,50,33,FA,9F,93,E8,1C,7C,D0,48,41,17,86,C3,6D,CA,25,C7,61,9F,C9,7C,F0,B3,60,AF,DE,D5,20,9A,B8,2A,33,AE,90,C1,CB,DB,0D,35,92,41,F1,24,52,71,14,6F,EF,0F,A7,9E,70,BB,5D,82,0E,9D,D9,F4,94,BF,53,EF,0D,83,E7,CF,F1,97,46,BB,FF,AA,BB,F2,50,72,C6,98,0F,8D,BB,C2,87,EA,DE,69,1C,18,51,AD,FA,75,A3,DF,63,9C,43,3F,96,92,2B,05,0D,68,07,44,D0,44,20,61,D1,78,A9,CC,6B,A6,2A,29,2C,BB,27,5E,5C,E8,71,B3,59,D5,6F,ED,34,72,0E,94,3A,18,36,C7,BF,A5,14,99,18,79,1D,57,5D,60,95,C5,0E,7B,8A,1C,DC,91,CB,AC,49,7B,1B,D3,DE,2D,44,8A,1F,20,D5,54,EA,49,16,E7,D9,8F,61,5F,E1,59,40,B9,AE,B2,0F,89,DA,EB,C3,84,F2,0C,6B,9D,ED,5E,3B,F2,D4,7E,AF,AE,82,76,E0,6C,28,9E,1D,FA,91,E7,1C,30,83,62,9E,C8,A7,FE,28,3F,02,FB,25,9A,C4,01,19,FF,5C,A1,8C,4A,B0,AE,56,8C,89,59,D7,B4,9C,11,A6,0B,96,71,97,F2,5B,62,E1,FD,FC,85,CB,0B,96,DA,EF,E3,9E,7A,E3,18,31,16,62,2B,9A,6C,07,8E,CC,BF,B9,2C,CE,19,77,D8,BA,D1,4B,5E,F1,DF,0E,6B,89,73,2E,35,98,96,81,26,98,65,C5,80,10,95,9B,1C,8D,4D,E5,9D,EE,17,34,F2,95,44,18,D4,50,30,A9,D6,41,C0,62,3A,32,25,CA,7C,40,FD,F7,83,8C,91,D1,97,44,D9,66,D7,88,7E,A3,8C,1D,F6,65,65,44,11,67,8B,3B,71,4E,AC,69,17,DB,CB,C6,8E,B3,31,01,34,F4,3A,DC,30,41,BA,D7,FE,C2,7C,67,3D,50,B6,F3,69,87,9B,89,83,FB,58,0F,14,34,BA,11,8E,8E,B4,45,1E,69,2F,3C,44,DC,F5,8C,02,DA,0B,F8,1E,FA,16,CF,AC,0E,DC,31,82,05,4C,C7,F1,1D,35,B5,6F,8D,A7,14,49,D4,C4,36,D1,88,47,2A,EE,0C,5B,CC,FC,71,2E,6B,97,92,09,D1,51,FE,B6,2E,4C,A2,1A,83,29,BE,B0,EA,8A,64,C6,00,F2,32,85,3D,DC,E6,5C,E0,42,05,C8,6F,F2,69,8B,E4,22,D0,9C,AA,34,9E,46,A4,35,A8,2C,86,09,62,7E,85,78,12,6A,07,4C,C4,BC,EC,4A,D9,A7,B4,9D,C0,AA,A7,8D,B3,F2,E6,92,D0,C8,30,FC,E7,57,90,B6,00,9F,05,E4,87,80,5E,82,1B,C2,74,97,A4,91,BE,F0,BA,EA,8C,98,6B,FA,D8,7F,77,07,3B,FF,6C,BC,11,B7,6B,CA,54,6F,BE,6E,38,3C,58,C9,D3,76,28,26,15,FA,42,C7,26,D5,87,43,1F,E2,26,DE,07,4A,1A,26,BD,33,F2,85,44,75,42,91,B7,FD,DC,54,4C,02,65,8A,31,9E,07,A9,70,0C,9F,E6,04,F3,DE,CF,79,9D,A9,2C,8D,DF,DC,BF,45,AF,C8,0E,0F,44,DC,CE,79,B8,12,6D,67,93,DB,C4,F8,E0,DE,22,1E,B5,32,AF,41,5A,70,C4,83,18,E9,4E,96,9D,FB,3B,36,A5,69,41,28,B8,1C,7B,E9,7A,60,C5,0A,32,19,A6,B7,C2,F1,22,30,EF,41,7E,08,A1,9E,0F,90,D6,A8,CA,31,B9,2A,27,15,9C,13,9E,0E,39,E0,CB,47,96,4C,0E,27,A6,68,5C,7C,FC,13,B2,22,19,35,28,8F,45,C6,EE,23,4B,89,9E,B3,B0,F3,89,D6,53,C4,F5,31,F4,FF,83,97,8D,C1,A0,11,61,66,91,F1,31,A0,DC,AC,18,B4,B1,5A,E8,5F,9A,E4,2A,BD,DB,45,F2,33,A2,E8,6C,1F,0C,8D,85,AB,A3,82,1F,9B,2E,DB,CE,77,67,42,83,5E,7A,BD,C3,C5,02,00,1F,9B,DD,6F,E8,2D,90,73,AB,59,CA,08,39,C8,61,DA,56,10,1C,BB,51,9D,E7,F2,AE,A6,CD,37,CC,84,11,1D,FB,73,00,6A,D9,88,03,AB,FE,4D,DF,85,65,4D,38,85,89,B4,9D,F6,9F,84,15,42,1B,F9,E4,D8,31,90,92,C7,01,25,41,08,11,01,A5,23,49,25,06,AC,92,49,F4,C0,19,EE,00,F6,1C,10,96,76,31,F2,39,08,2D,D2,7E,F5,1A,70,D6,25,91,6F,3F,12,F0,17,4F,24,6A,21,B6,FF,F5,26,97,89,51,47,C8,7B,09,AD,C0,1D,6A,E9,5B,B5,B9,AD,C8,73,BD,2B,60,B3,4A,8C,1F,25,15,74,2A,38,4A,F0,F5,4A,BD,3D,9C,A7,EA,9D,74,E2,6C,37,E9,51,12,65,49,1D,1B,E4,7E,92,10,9C,EB,EA,03,8F,CE,FD,70,0F,1C,F5,38,09,2D,9C,F1,C9,32,01,1E,1A,10,D5,48,AF,B4,8A,64,A7,C2,DD,9E,A7,09,DE,DC,E8,47,32,39,41,5F,7F,02,AB,20,CC,FE,1D,6F,3F,74,3C,3B,E7,3E,9F,1F,D2,68,4E,53,0B,63,C4,0A,16,5D,4C,4D,54,15,95,3E,71,37,97,FF,9A,2E,16,4A,07,14,57,26,99,8E,AE,1C,5F,C8,3A,D3,E4,24,24,1D,53,B9,E8,06,A4,00,B3,17,BE,BA,14,E9,B2,38,61,0F,1F,D8,A7,A9,92,20,7E,44,7B,60,D1,36,72,49,32,55,FA,1B,CA,E5,13,1C,A0,3E,4E,A9,AD,C8,F1,19,D5,27,EE,F1,D9,E6,59,3D,61,76,EF,21,05,C0,31,F5,53,3A,89,82,6D,E6,19,32,6C,4C,D5,3D,91,B4,5E,32,3D,19,65,41,70,8A,BE,E9,9F,45,75,94,1C,D1,00,70,0A,56,4A,DE,32,3E,29,F1,03,1F,1C,44,43,E3,84,A8,27,7A,21,56,31,D5,D8,DA,25,82,C9,84,97,9C,FB,6B,38,7F,20,19,9A,C7,8F,54,4C,21,7F,B3,81,9B,F0,59,99,86,20,2F,A5,7B,AA,B6,12,A8,C9,43,47,17,BE,4F,3D,3A,7D,F1,C3,55,9F,4E,87,C7,0C,EA,15,72,4E,70,30,7D,C9,F7,55,DE,4B,7A,DC,F2,BE,A9,B5,41,B2,1B,75,09,B4,85,B8,A1,EF,98,F8,28,74,78,E6,F1,29,7E,E9,44,F6,2B,4D,65,18,F2,C1,D3,8B,45,B0,E4,95,EC,24,18,D4,C2,12,94,B2,D0,C3,23,19,B9,B0,95,AF,CC,4D,C7,60,F5,3B,A5,27,37,D3,78,2B,C9,E9,F8,BF,52,24,5D,0B,A4,00,6E,BE,12,FB,24,76,61,ED,09,54,D9,44,BB,76,64,5D,AF,23,6F,89,AC,D9,54,12,2E,32,58,83,24,01,C1,21,F7,F5,BF,A2,9D,64,34,E4,74,E5,FF,04,FC,67,F7,42,9A,41,EB,6E,EB,E2,E6,F1,98,7A,09,D7,28,B9,B6,29,4E,42,76,9A,B6,B3,A6,1C,60,40,F1,E6,41,BA,56,74,F7,69,4F,55,98,E0,7B,26,80,81,F7,43,95,8B,BC,D0,C8,F5,54,98,8B,C0,DC,2C,99,3E,9D,DE,CB,28,10,E9,C6,EF,6D,40,93,7F,C2,FA,EF,1F,24,22,72,92,A7,60,8A,3D,AE,BC,FF,92,1D,52,B0,C1,D2,53,FE,D5,46,AB,1B,2E,B5,1A,F8,7F,1C,E1,67,24,61,5A,B3,A8,21,FD,08,12,CB,5D,0F,BE,84,8D,F1,DD,2F,7C,61,42,97,73,48,79,33,9B,70,8D,FC,DD,65,48,37,FE,38,E2,27,E1,68,D9,34,FA,31,BA,9E,2C,8A,C4,9A,07,E0,0F,BC,DB,21,50,FC,B0,6F,69,02,23,13,C1,B6,12,66,44,0A,30,FB,D6,2F,12,07,91,15,FC,3E,83,74,17,A4,B9,4D,29,16,5C,59,0C,A9,A6,B8,D7,20,C7,64,EE,4A,BD,CA,1C,48,EF,76,06,23,22,F7,72,24,1C,0A,23,17,D2,CB,04,D4,BE,FB,78,57,3E,F3,B1,30,10,8A,ED,F7,A3,75,C0,58,3A,61,36,32,EA,39,B9,9F,12,7F,15,EC,70,5B,9C,02,AD,43,D8,66,54,91,27,6A,28,D7,E8,1D,DF,5A,5B,79,E2,AB,E5,6A,1C,E8,9D,70,83,0E,E4,B4,E2,F4,3B,0C,B4,2C,B7,55,61,F0,1C,0D,EB,D0,73,ED,C7,0D,76,D8,6C,EB,F5,AA,5A,62,50,28,C7,A4,99,01,F5,3D,68,19,49,08,C6,B1,B5,9A,A4,3B,22,C6,81,4E,05,8B,F7,23,20,A3,21,7B,3F,BE,55,D3,2C,1F,FB,8C,23,71,F9,3F,44,EF,50,5D,71,28,08,8D,54,93,BB,61,6B,33,CC,FE,CF,4F,34,A7,71,6A,BC,E1,F5,96,E4,A0,FB,E3,BF,3E,DD,8C,1D,99,ED,73,A0,ED,A1,DD,55,FC,5D,AB,FE,1E,87,27,D1,DF,02,C8,76,EA,19,59,96,D0,F4,27,1C,07,2C,E4,25,D0,34,E1,08,F9,D1,8F,BC,34,60,23,6D,36,9B,ED,DC,2D,C9,B4,AD,60,E5,1F,6B,1D,A9,07,A6,13,E9,6E,B0,FE,D6,39,A9,64,49,3B,6B,57,20,A6,5E,0B,7D,AA,6D,64,EE,D0,F7,B1,15,72,59,B2,AE,77,2C,0C,73,E0,34,3E,CA,1C,9E,8F,47,10,53,50,BF,C4,5E,8A,A6,87,E2,F7,31,A8,73,5C,49,38,F8,7B,C8,F3,11,6A,0E,5E,3D,F5,4C,4E,EF,79,C5,99,65,4A,6B,38,F7,12,4C,26,95,AF,48,5F,DC,25,5B,2B,E9,DE,B9,18,E6,4C,6D,CD,72,70,D3,2C,E7,85,0E,4E,3A,15,9C,FD,89,78,74,52,C1,4A,94,41,CB,00,3D,BB,1B,7D,B0,70,0A,DA,DB,68,E9,CD,B2,90,39,12,92,DA,0E,53,10,55,1F,EC,C7,FC,42,BD,4E,96,90,2B,70,2F,F0,F0,8B,15,51,E4,DD,9B,03,30,96,6A,99,F1,8A,87,EF,5C,ED,F4,7A,91,75,15,0D,88,6A,9C,17,11,C0,23,81,8E,20,72,1D,0F,CF,49,88,E0,EF,5E,1F,CB,71,FD,09,C0,7F,6D,2F,D7,49,E0,41,AE,00,A7,80,AD,B6,8C,59,84,B1,35,2C,B2,70,F5,97,9C,AE,A8,47,EA,E6,9E,27,53,D3,72,5A,C1,29,43,6D,69,0E,F9,A0,70,C6,71,FA,5E,EC,BA,31,02,33,DE,29,BF,1B,5F,9D,B3,03,1B,CB,2B,37,2D,7F,82,98,A6,37,70,B4,EE,45,9A,A4,D5,A3,3B,74,42,5C,D7,D7,EB,0B,7D,90,83,1F,4E,2B,05,37,FC,EA,0B,1A,1F,3D,9C,96,C9,18,73,4F,65,03,31,00,2E,A4,FA,07,6F,70,F1,F0,E4,96,38,AF,94,9F,30,C5,E3,0B,21,CD,73,AF,A3,96,87,24,E0,FB,78,6D,34,11,93,0A,BD,45,6C,60,F0,4C,5B,90,08,2C,CC,6A,EA,51,D6,87,06,85,C7,E2,0A,CB,C6,1F,D3,0A,E8,EE,CD,7E,B4,0B,07,34,1D,6C,D4,05,84,BE,18,F2,60,99,A4,AB,45,DE,97,DD,77,45,5E,3A,1B,3F,1D,CF,DB,FB,D5,3C,E8,7B,D3,BE,A8,5F,5E,66,2D,1C,6E,4A,BF,56,F0,AB,0B,66,28,9C,57,3C,2E,D4,5D,C6,E5,3F,43,52,C9,A7,5C,7F,F6,DC,20,9C,CB,F7,B3,55,6F,55,06,70,9E,73,70,78,C1,73,8B,C0,BB,71,D4,EF,1E,C8,94,64,D0,58,8A,FC,03,98,21,48,58,3F,37,2C,99,3C,C0,E5,DF,92,2F,6F,1A,40,3A,52,11,A5,2A,1A,BB,5F,44,CA,02,C2,AA,48,0E,04,C7,6F,F7,AE,5C,25,8B,8E,52,88,4D,85,12,85,24,68,CF,C9,76,9C,75,EB,1A,83,45,1A,E7,E8,04,59,D9,B3,CD,4A,4D,58,FE,37,FE,59,27,8B,3F,88,54,63,58,03,79,42,49,68,1D,39,A4,E3,91,C6,4C,E2,E1,9F,20,3D,AE,7F,17,CE,E3,E5,03,48,5F,7E,42,E2,67,CB,76,1C,BC,36,95,00,02,62,5A,FE,87,DC,A0,39,1A,FA,9B,10,3D,E2,F9,ED,2D,7A,88,A8,72,C3,8B,E5,07,64,57,43,BC,D7,0A,1A,87,B8,69,FD,B8,36,9D,E8,8A,09,46,56,E8,CD,B2,46,1A,D0,08,06,A9,44,E6,BA,25,5A,38,D2,7F,D0,2C,46,81,32,2A,4A,28,47,25,B6,7E,4C,A9,64,22,57,5A,07,29,59,3D,26,52,93,4C,FD,B2,F0,36,AE,29,4E,2D,11,82,06,84,0B,0C,14,FD,9E,7C,9F,E2,6D,A5,CC,DA,65,C1,79,EA,1E,10,5A,AC,48,F2,B6,E2,89,5A,3A,54,6E,DF,77,F7,4E,F7,AC,81,21,E9,45,43,BA,C4,8E,7B,5B,F6,EB,97,BE,18,DA,10,88,D8,1D,BE,45,17,8B,77,5A,F2,B9,59,CE,5F,32,60,60,48,D8,B9,71,DC,64,5D,E4,69,99,C4,C0,3D,FE,A4,17,88,EC,83,D2,C9,69,46,FB,23,BC,65,6C,EB,AB,D1,5B,89,C0,1E,3E,69,39,AD,F0,1F,4D,DE,3F,F0,82,DD,8D,48,BC,14,66,A7,50,12,3E,AF,0F,BD,41,6C,A8,98,58,83,9A,D4,EC,0B,8B,5F,41,96,59,58,C2,EB,55,EB,B5,B0,BA,1C,0A,CC,49,24,21,FB,4D,DD,38,B3,F1,41,BF,B9,A0,CE,81,25,65,DE,6A,11,5B,21,E5,3A,2F,BC,68,9B,E7,0A,18,53,C0,F1,06,BA,9F,1D,E7,D9,A8,E9,09,62,2E,64,05,BA,5C,6C,E1,BA,42,32,A8,88,51,17,84,C3,E6,DF,93,DA,92,91,4F,FF,CE,E2,E9,3B,A2,72,91,19,0B,12,7E,08,7D,EE,4A,DC,F2,3E,10,49,6D,1E,00,E6,17,EE,9B,73,F6,85,AB,C7,49,32,1E,8A,04,74,89,66,7B,22,BD,3C,E3,BE,CC,2C,7D,02,4C,1C,D8,71,AF,8D,ED,6C,DD,01,A7,32,55,BD,0B,20,68,8B,9E,E7,13,24,57,26,E8,D5,92,3B,AD,33,90,AD,65,76,05,12,C7,0E,07,9C,56,1F,E6,87,0A,A9,57,40,70,44,EE,74,4D,E7,2F,03,A2,F7,9F,84,66,71,FA,8F,E4,D2,A7,DB,F2,59,5D,B4,10,0A,DA,D5,BF,20,FF,44,EE,AF,89,AE,3C,B5,15,C2,59,FC,B2,F0,F4,19,4B,24,DD,55,39,78,58,56,2F,62,7A,15,EA,4E,24,96,74,D8,6F,4D,F1,ED,6E,BB,33,D8,2D,BD,D6,33,DB,B8,00,54,3D,47,1C,6E,EC,2D,D8,2C,8C,FC,99,F4,16,BB,89,A4,B5,7E,C1,8B,DD,C9,01,E0,27,28,77,91,D0,C8,61,82,70,39,07,98,EC,F9,B6,82,B8,BC,48,CA,E9,27,6C,20,E2,9F,66,5C,CC,CD,56,CC,F6,44,9D,F5,3A,78,52,81,56,BA,56,A5,23,06,35,4F,C5,C2,B3,9B,62,C3,C6,0A,20,08,46,C0,3D,64,72,7D,ED,DE,09,37,50,66,EB,CF,07,00,20,0F,A2,01,A4,A7,B3,7C,D5,24,9E,8B,E8,FB,53,5F,45,D9,0A,65,CD,B3,A8,0F,71,D6,26,81,C1,2F,34,13,DD,2F,E8,22,4C,2A,2F,EA,BB,EB,F5,4E,E9,23,03,11,E1,BC,5D,07,0A,13,71,6A,12,59,30,6A,6F,65,B3,F9,E1,9F,4C,DE,A7,D6,9B,2D,5D,47,60,8E,9B,8F,08,57,68,FA,4A,BB,A5,DB,DB,E9,CF,DA,8A,F0,9A,FD,7E,89,C6,EE,F7,15,CE,80,F4,59,E5,D6,0D,77,2E,F5,B2,77,89,E6,4C,CA,19,01,9F,BC,48,35,76,1A,8B,BF,00,A4,05,32,6A,21,53,DD,FB,B0,B8,98,D9,B4,B4,5D,97,1E,56,84,95,67,3D,0C,C8,AF,A6,F9,13,58,E9,6D,40,55,C9,DB,BD,6E,1E,2A,DC,F2,75,FB,38,E4,A3,89,D4,EC,C1,93,50,E7,F5,BC,94,09,72,7D,FD,09,DB,3E,31,5E,D2,26,E1,54,4C,84,22,E2,18,3C,2E,A4,55,1D,B6,1F,3D,DC,A6,1D,44,76,3A,9C,14,2F,3B,CF,A7,B4,F7,80,6B,52,D5,36,1A,D1,6A,2F,E8,FC,33,53,3F,E0,B4,C6,3F,06,D9,61,8F,E1,2F,62,16,EF,94,A0,94,FA,40,FF,79,32,83,D2,28,BA,C2,B2,5F,DD,D2,9B,BE,FC,2C,44,6A,CC,B2,B3,86,53,17,AC,F5,D0,DC,4C,2C,52,DB,8F,FB,75,E4,E6,45,B2,33,B6,65,4F,CA,55,9C,EC,C6,A9,99,FD,0C,E0,F3,8A,7B,8C,78,03,61,AA,FD,25,C2,55,95,BD,44,16,BB,AC,E5,92,6F,94,4D,0A,1A,A7,0C,BE,FC,08,6D,8A,EF,B0,8E,54,7F,1D,1F,C0,6A,69,68,F2,BA,5D,21,48,7B,C7,29,3B,0C,BA,4E,41,FA,A3,5E,44,AF,37,F9,AF,BC,D3,6F,AD,EA,A4,3F,45,41,BF,9C,D7,F2,0D,41,D0,BF,C3,D0,5A,E3,3B,8E,B4,3E,35,79,F7,BF,91,9C,13,F2,96,4F,7F,BB,D3,5A,EC,4A,F9,D6,CB,8E,7D,A1,08,DB,A7,97,C3,22,9F,38,FA,B9,E6,5F,8F,82,3E,A9,14,8E,F0,0F,7E,81,B0,41,B7,7F,6F,78,19,1B,C6,16,B0,17,34,8F,5C,73,14,FA,F2,43,E2,26,59,59,5E,B8,3A,49,DD,65,80,26,9B,E2,BB,04,CA,DD,79,5F,8D,2E,CD,FA,62,9E,6D,38,CD,1D,4D,FC,87,65,50,07,EA,5E,26,BB,2A,F3,C5,63,82,C3,BE,EB,DF,93,CB,0C,BE,F9,B2,57,A0,7C,8E,A6,11,30,B9,60,AF,63,E2,4D,A4,59,2A,63,CF,86,0D,AF,9E,4A,E9,EE,C8,A0,9E,19,7E,4F,83,33,ED,16,6C,74,7A,5D,F2,1D,01,F5,D9,E5,D0,4A,E0,0D,61,FA,80,3A,E0,80,86,F3,FB,12,6D,B0,10,32,59,C1,6D,1D,EF,74,C7,BC,E3,19,78,B9,81,6A,5E,4B,A5,16,3E,50,79,0F,38,3F,D1,68,6D,79,BC,15,00,20,B6,4C,51,19,1D,FE,D2,49,94,CC,75,68,68,90,0F,A1,3A,E4,37,CD,92,4D,E6,88,08,14,FA,D0,C1,E0,4C,99,BC,19,AD,85,E5,D8,85,0F,6C,D3,21,F7,4E,B1,6C,D2,2F,45,A5,37,C4,5F,3C,9C,9C,37,93,1E,D6,E9,E5,1A,47,50,CD,35,E5,7F,39,12,7D,85,49,AC,07,D8,F9,D5,2E,77,2A,F0,0B,48,61,60,94,02,78,C6,57,E7,30,5A,A1,BC,D2,20,61,0F,1C,85,80,BE,21,1B,9C,AF,94,EE,F3,5B,B0,B0,27,5A,8C,16,C5,57,25,8D,C8,CD,FD,27,D0,41,FB,E6,65,8B,F4,C4,1A,98,9B,81,F9,7F,E7,30,BB,41,B2,9A,BD,1C,5A,90,2B,7F,5E,93,89,BE,C6,BE,41,E8,3F,0F,0B,CD,F5,F3,4E,80,08,4D,DB,41,8B,0A,D2,C7,D2,85,71,DA,39,97,C6,AB,88,31,85,F9,1C,6B,68,E3,52,16,52,BF,76,40,75,8D,10,D4,D5,7C,92,E5,CC,47,99,B8,3F,B6,CF,B9,ED,CE,B1,44,2C,6B,3F,11,7E,66,60,87,22,C2,6D,75,6A,C5,0D,F8,F3,5A,B1,03,D3,AD,9A,6C,30,EE,E9,7F,B2,96,1B,BD,50,FB,F7,DB,28,D6,EB,4E,6B,1F,19,D3,E9,C4,5B,2E,12,D9,62,99,D2,9B,18,3C,37,D4,2A,88,F5,1B,DB,02,02,2A,9A,77,19,82,85,69,F6,45,0C,73,D2,A2,F8,17,A5,33,30,FA,63,6B,40,CC,A7,6B,92,7A,7D,F7,24,B0,19,DF,B1,DE,8D,85,94,50,EB,B3,0C,5D,65,60,14,3C,38,DB,D4,0F,AF,43,60,00,11,49,D9,AE,EE,DB,DF,4C,65,E1,A9,65,4A,74,14,9A,F8,05,FA,6F,88,8D,12,D7,84,94,57,6C,7F,7D,2D,1B,74,F5,BF,9C,50,8D,ED,58,14,25,53,B2,A8,50,50,07,28,EE,DE,C1,6B,38,63,0E,8C,CA,D9,DE,D1,83,42,8B,7F,ED,AD,9A,45,A1,59,1D,19,CB,B6,C3,D0,8E,16,EF,A9,0B,81,44,26,05,84,BE,E2,86,F6,D2,0B,1B,55,AE,E1,0A,63,BC,3E,E8,E0,28,73,34,6E,BF,F5,15,45,B6,D3,4B,64,1F,94,8C,5C,D5,2C,45,64,1F,13,44,45,26,07,FC,2B,22,3A,18,0C,C1,27,7A,93,5B,42,7E,1C,24,E4,4F,21,3A,EB,C0,E7,17,6C,92,46,22,FB,36,E8,25,40,E3,54,95,2F,66,79,AA,82,83,BF,B0,F6,6A,C9,1E,34,82,4D,0D,3E,F0,45,F6,6F,6C,16,26,10,69,DA,5F,8C,CA,FD,89,6A,5B,02,13,0F,7C,33,EA,9F,66,BC,B2,8E,9D,23,D1,0A,A1,4E,6D,EB,01,03,37,0D,2B,E6,5E,86,68,33,DD,F5,95,2E,3A,CE,77,64,C3,AA,14,AC,43,6D,AE,E7,76,C5,7D,80,75,58,08,B1,F9,2E,90,F8,3E,77,92,66,C5,78,D5,3E,08,13,7B,F7,36,31,5D,58,8A,D9,A0,FC,EE,A3,D7,8A,9E,A3,9A,DF,28,2D,F1,65,A6,CD,2B,2A,25,0F,04,E4,7E,13,F4,4B,D3,13,C4,B5,AC,0A,6A,EB,F9,9B,2A,37,81,4F,E3,A6,86,AD,66,80,1A,6D,6D,3E,39,67,26,BB,8A,D4,B4,30,8B,75,26,C3,15,20,E3,EF,D6,87,2F,BC,E1,56,C7,E9,13,64,FE,93,36,9C,71,12,D6,5F,27,C3,CC,78,AC,75,FE,CC,BD,6A,DE,47,24,76,1C,69,2D,8F,A3,3C,DF,AE,AD,B3,6B,E9,66,47,85,0E,E6,5F,E1,EE,ED,84,B9,29,98,D6,38,59,2A,84,F2,3B,CD,F2,4A,30,0B,92,50,F4,3A,DD,76,70,79,47,C3,65,92,F6,1A,BB,A0,BE,66,FB,5D,3B,00,5E,73,D3,D6,9A,F6,07,A1,3D,5E,BA,9F,6C,72,11,AB,D8,D5,C9,AA,CA,F2,A9,08,24,97,78,60,A6,6B,C1,B6,15,FD,7E,32,69,2F,21,F5,92,0D,58,60,58,37,EB,B3,30,48,DB,DE,D1,B9,82,34,FD,D7,97,F3,9A,83,94,CC,94,12,8A,C1,F7,63,68,2D,6E,31,EC,CC,79,38,A8,75,94,C4,73,2E,BE,BF,D1,54,0D,81,9E,AC,47,DA,98,70,4A,85,34,F3,6D,8D,03,A7,58,4F,76,3C,67,BE,DF,3D,C9,0C,7A,12,A4,CC,DA,43,CA,EA,20,36,7B,19,70,7F,3A,C7,2C,89,77,7D,CA,2C,66,C6,F0,51,FF,35,45,8D,01,D9,70,B0,C6,48,03,B1,F2,A0,76,4D,B3,D9,4C,21,EB,4C,E5,9D,E1,43,74,8A,BB,60,03,96,D1,E8,70,86,7F,C4,51,F3,28,6C,BC,2A,61,AC,40,94,5D,93,8C,02,DC,04,07,58,A2,07,3E,B6,CC,87,76,92,3F,67,F2,D9,B0,83,17,6E,1B,38,8F,47,73,35,A3,2E,17,C4,74,23,A8,73,BD,7F,60,85,CE,86,5D,4E,32,9C,0B,2C,62,2C,36,A3,A5,CF,DE,9D,98,18,DD,EA,8B,93,BE,E2,A8,66,35,77,8B,D5,82,32,E5,31,BC,5D,B6,01,74,C6,24,79,26,13,AF,4A,31,F6,58,C7,78,51,63,D3,B6,94,9E,15,F2,B2,8C,FF,34,E9,63,34,C6,D4,A7,2A,F4,BE,2E,41,DB,10,79,19,93,4A,BB,12,AF,37,CB,2E,CB,50,81,72,A1,FA,D4,37,78,2D,0C,FA,50,80,00,BF,11,5C,2A,16,2F,2B,65,5F,7A,30,9C,35,11,6F,97,A2,EA,C7,13,0B,3C,43,55,A3,A2,48,F1,B2,C3,72,34,51,F7,46,D5,EC,6E,03,62,70,52,A2,07,88,1F,EB,A0,F9,92,F0,7F,3B,D1,CB,89,54,84,EE,FB,7D,2D,F0,C2,03,C7,11,03,59,AD,2D,25,6E,2C,75,7D,DC,36,6D,9A,CC,E1,C3,7F,3F,E8,1C,13,1B,6C,44,2D,B4,83,9C,86,55,88,41,C1,1B,27,DD,02,51,2E,C6,5D,4D,86,48,7D,AD,56,99,72,80,F0,61,A0,83,F0,E1,16,3F,93,C4,EF,C9,F9,E4,75,75,60,33,28,DA,3A,BC,4A,0E,04,87,FA,CB,C4,98,1E,75,A2,FE,85,97,C0,6C,23,13,5F,19,5F,94,16,75,56,49,14,EB,99,E1,0D,46,E2,23,00,BA,0F,9F,0B,50,6D,A3,88,FE,D4,B3,A7,8C,A3,5F,AA,60,06,AE,D6,19,72,26,B9,69,76,37,5E,C4,53,47,73,49,C5,DC,32,A4,C3,F2,D3,26,26,0F,8C,AB,F3,DB,9A,F3,E2,9A,E1,0D,9C,8E,92,F3,34,29,CF,9E,0F,F8,B7,44,FB,35,1A,06,F9,5F,78,F6,32,67,BD,FE,05,E1,85,09,E3,83,BC,41,55,F0,AE,5B,BA,F8,1C,01,AB,3B,29,4F,FA,02,67,8E,A8,FD,9F,B9,5A,B6,7E,02,32,86,CD,53,53,9B,91,72,87,5A,E2,AB,20,FD,50,80,CD,E3,E5,48,14,36,0B,F8,07,DE,FC,CA,82,76,D4,11,76,23,7A,76,A5,05,0D,53,28,76,94,F9,DC,B6,4C,34,7B,5F,1C,E7,8C,B8,21,A7,A0,77,48,C6,13,54,B6,8A,83,2A,DD,99,0D,17,36,A3,32,72,DC,C1,07,32,F3,C8,F0,35,F1,3F,AC,4E,15,FA,39,D3,90,B0,B7,FA,66,DD,B2,F1,21,AF,C5,A8,23,0D,C3,EB,86,1F,F6,76,26,24,7F,D3,2E,C6,13,AE,4C,6D,BC,F7,81,E2,F9,00,8B,B9,A7,6E,C8,45,F7,1F,7D,12,EE,FF,E6,E4,B2,C4,F1,16,43,FA,F7,22,74,50,A0,13,C0,BC,64,A1,F5,33,7A,BA,CF,10,6D,8C,E9,DE,41,5E,7B,90,43,6E,0D,07,3A,0D,A9,54,56,12,61,74,86,81,A8,77,48,F1,E3,3F,10,72,04,55,63,3B,C8,AC,00,EF,7E,05,73,37,93,1A,F4,14,4C,4D,EE,44,CA,96,AD,91,3E,C0,67,8A,01,4A,90,F7,A8,EC,DF,3F,69,35,A4,90,1D,C1,5C,60,A3,36,84,66,0B,C6,72,D8,5B,3E,E9,96,D9,A6,E2,03,95,C6,ED,75,85,E6,00,FA,20,9F,15,F6,3C,D8,EC,27,1D,75,07,2A,50,4E,B7,B3,BB,CC,B3,06,57,7C,21,38,74,9D,82,73,76,34,1C,88,C3,6F,17,0E,97,F1,85,87,66,35,6C,02,B7,A9,6E,26,05,D0,A5,8F,06,40,9F,01,CC,29,6E,CA,16,20,EF,23,20,1F,69,54,5C,E5,82,11,02,47,93,0B,C6,F7,F4,62,1A,E3,C9,90,70,89,EB,B7,CF,45,94,85,0C,51,0B,15,56,14,69,5E,45,4A,35,C5,DE,65,5A,7D,7E,71,DF,12,97,A8,5B,6D,6F,3B,3A,B9,92,A8,84,57,3E,9B,0F,4B,81,0E,9E,BA,B9,FB,20,8F,16,A3,1F,76,54,DF,9A,AF,17,0B,DD,3C,D4,D2,13,1E,C1,2F,F7,75,11,42,16,70,F6,0B,FB,3A,7C,40,57,44,84,66,62,89,FC,97,50,88,D1,75,66,8C,90,6A,2B,DA,90,15,F8,F5,0D,76,D7,CA,A9,BD,05,6D,26,D3,70,57,CC,C6,BD,CB,BA,13,F9,45,28,14,4C,32,34,52,9A,55,28,45,E5,4E,D6,2F,E7,C3,22,93,73,AB,F4,4C,EC,75,54,64,DF,34,09,B2,68,D3,48,A8,E4,82,EB,B9,02,B7,0B,56,DE,65,FA,86,6B,FB,E6,09,4C,59,8C,83,99,C8,C3,94,98,F9,42,03,F0,CD,37,E2,2E,53,2A,98,24,1A,99,21,4B,06,F4,B8,70,1C,5C,C7,A3,E0,C7,14,C6,6F,81,5B,4B,DF,7B,C8,AB,9E,46,44,2D,50,AB,EB,23,19,D4,DA,E0,1E,B8,84,E8,F3,28,F6,40,F1,A8,40,27,F4,69,2A,4E,CF,FE,30,5A,FD,22,4F,85,2E,FA,3C,B5,06,16,16,69,76,EE,6F,2F,8D,AB,6C,E5,40,7C,9F,73,26,59,E8,73,5E,0A,97,F0,19,53,F3,52,A4,4F,92,77,8B,3F,75,79,A4,5D,2E,C6,36,83,FD,B1,48,D5,A6,67,95,40,36,E8,5D,8A,74,EB,DB,1B,C0,76,E2,50,09,C2,B5,0A,6B,B6,21,FB,EC,34,0A,27,21,60,83,3B,7D,ED,8E,B5,F7,1B,DD,9C,CD,47,44,60,A0,92,EE,A4,EC,C1,A5,6C,88,0B,18,90,22,44,BB,2A,FC,9C,A0,24,1E,E1,34,49,63,64,EB,3D,59,6C,25,93,67,36,E1,A7,C9,96,52,17,B8,C5,6D,CC,60,0C,62,25,DE,4B,C4,CC,56,25,B8,2D,FA,98,BB,4F,60,C7,0B,0B,78,C0,03,12,2A,F6,6B,68,BF,1A,2F,18,24,58,E7,AE,B0,4A,2E,AA,D0,4D,FD,7D,B1,2D,8A,67,2E,2D,69,6C,69,84,7D,60,97,56,CD,78,9F,90,F4,28,D3,E7,44,B7,11,92,D0,23,07,17,85,28,B5,74,9C,E3,F2,AA,64,F1,4E,EA,E7,6B,45,BA,14,86,96,53,DE,2A,42,CC,B9,D6,DD,84,22,3C,C5,48,EA,12,E9,43,C7,32,67,2F,86,D8,D0,6C,22,17,2D,77,91,AE,29,7C,25,CF,C6,C7,C2,92,72,56,26,47,51,C2,0D,CC,4E,B1,05,86,3D,1D,42,FE,AF,AE,FF,D0,A0,8D,14,AD,6D,0E,C1,9D,EB,1E,6B,05,3D,0E,F2,33,6F,3B,C5,47,AD,34,6C,B7,CF,96,5B,1E,B8,77,2A,3E,9E,55,41,69,F7,32,CB,64,27,1E,A7,F1,DE,8D,18,7D,7C,2A,2D,27,58,48,B8,1F,E4,0B,2B,A5,B0,1C,19,80,11,13,69,3B,92,1F,3F,E9,C4,3B,43,39,FC,52,66,5C,EA,D1,18,9F,ED,AD,62,1D,24,A1,85,DF,69,CD,48,E8,E7,0B,F1,8B,1F,6A,87,4B,3A,C6,BF,A1,00,50,19,53,80,33,AF,EB,71,B7,6D,C9,4D,7C,CD,DE,F4,A1,7F,A3,54,5D,19,67,1E,A1,3B,5A,58,AC,FC,51,45,5A,2E,3F,6C,29,37,A2,52,2F,5A,9B,A7,D7,A2,3A,DC,DE,EA,9D,83,64,A8,27,BB,39,8B,2C,29,C2,8F,11,A1,4A,48,8B,6C,7D,C1,1D,13,AC,BC,76,2F,B3,BD,05,9C,EF,37,6B,01,AA,4B,63,B7,69,41,41,8A,D5,43,FA,7D,B5,FA,AF,A1,05,D7,FE,35,68,0D,C8,01,40,E1,63,B6,3C,BC,FC,B0,D5,22,3F,37,F7,A4,13,56,77,90,D4,CE,16,88,E4,7E,64,CC,B2,87,8D,99,C9,B0,AE,77,30,37,11,CA,BB,C0,61,B6,7E,5C,3F,45,0C,ED,A2,A8,19,94,29,7A,0D,BC,3F,17,6C,F2,6F,87,3E,17,F2,45,CC,72,88,F1,16,64,8A,DF,8C,00,69,A2,05,6B,49,AB,A1,73,4D,AC,20,6B,CF,E5,3F,04,CA,A6,67,93,E9,05,B7,F2,29,9C,FC,D7,60,2B,49,1A,EA,A1,95,4E,D0,34,E8,2D,8C,1A,76,F2,04,2E,1F,8F,D1,57,99,86,1D,32,8F,D1,39,3E,77,CD,05,17,82,E7,43,0E,07,0B,4F,9F,A1,34,E4,90,A5,50,3B,5E,AE,11,3D,5F,98,F8,F6,67,1E,62,38,EE,94,B1,CA,FC,E2,A6,63,A6,E6,44,08,BB,10,11,76,E1,CE,92,0A,CA,67,1F,D3,A7,4E,F8,3A,64,1D,C7,37,14,49,FA,E6,BA,15,9B,86,75,C5,CA,6A,65,FD,07,58,31,60,69,4E,1A,CF,A5,75,7F,29,DB,41,37,72,6E,A3,51,CE,DA,65,82,CC,39,B8,9C,F7,95,A9,AA,16,0A,BB,C4,FD,E0,E7,98,C4,27,CF,BE,A0,99,46,47,92,50,9F,DF,72,5C,FD,E7,17,5F,DA,21,C0,36,D8,16,22,CE,1B,60,C3,25,67,32,11,7E,A2,E7,44,21,AF,F1,0F,26,9B,73,97,EB,64,27,90,C4,F0,A0,6E,FF,55,FC,FD,71,05,3F,8A,B7,BE,53,0B,87,8E,E1,CE,33,03,E9,69,07,80,C5,5D,83,16,0F,0B,45,30,7F,9C,C3,02,B8,B4,B1,A4,72,35,15,84,E4,DE,A2,26,73,38,F0,D7,60,2B,15,CA,B9,37,DC,21,29,F6,CF,46,14,DD,C7,8D,C7,50,2F,17,58,16,23,5E,A3,B4,2D,DD,18,6D,D8,72,1B,F2,F7,14,AA,27,BC,CD,FE,DC,C3,AE,45,A1,CB,5D,D5,65,BC,53,8E,39,0A,9A,E3,38,03,1A,7E,C4,98,24,E8,88,92,0D,16,F3,D4,92,81,7F,5F,CE,BF,7E,18,1D,A1,E2,7E,A8,D7,64,B0,8C,8D,A3,99,B9,C0,C0,B2,FD,88,70,A9,7B,2D,2B,39,E4,BD,E5,3D,F9,53,E2,5E,5D,2A,1F,61,2F,47,B9,43,FD,34,D3,FB,37,80,B6,2A,90,52,7B,AF,85,5E,9D,94,29,E7,1A,E4,47,7B,E5,83,A1,DA,C4,44,8A,74,63,56,B7,AD,38,B7,7A,75,99,5D,BA,D0,C2,EC,2F,C5,51,3F,AC,E4,B5,FC,43,FF,2B,0B,75,A3,A3,8C,EE,B2,96,67,55,AE,2D,41,B3,5A,8B,13,9A,5C,9D,FA,C7,E8,3C,09,15,FA,20,2C,ED,0A,70,DC,F9,2A,C3,D1,CF,E0,BA,DB,6B,FF,89,E3,AD,D3,12,D2,01,DF,EC,32,94,DE,86,18,7D,15,71,6C,CE,42,DA,B2,D1,0B,F3,B0,A3,FA,86,1C,76,C2,54,36,23,6E,17,81,CC,79,86,08,AC,E9,D2,D2,45,0C,D4,77,49,C7,BD,AA,BD,62,34,12,D5,94,36,9A,C3,07,57,39,8C,7A,72,CD,EC,78,5B,29,55,44,A9,88,75,FC,EE,85,94,59,F7,2E,3D,F5,7C,CF,12,F6,EF,01,73,ED,67,59,0F,E9,45,43,C4,69,02,4C,8B,DD,95,CB,B0,45,ED,69,77,E0,5F,6D,45,DE,56,E9,D1,70,07,D8,72,50,D0,EA,67,08,94,F8,70,5C,D9,D3,3A,D4,3D,B3,AC,E6,D0,2B,B7,5C,C4,3F,91,28,D8,58,51,8D,A3,CA,FA,0D,DA,7F,B5,BB,93,94,60,96,23,55,FB,80,BA,F0,32,67,10,8A,2F,4D,7C,55,FD,19,82,9B,55,F9,49,69,C4,B1,D8,D5,95,6D,3A,52,09,FD,7D,53,EF,3E,A1,00,C5,8B,FD,E9,F8,3A,2E,12,C5,FE,41,7C,28,50,D2,6A,38,5F,17,24,61,65,AA,54,50,E3,33,91,39,ED,9A,B4,57,8F,E9,C0,62,BF,47,11,94,0B,30,36,FA,8B,B6,F8,86,2D,C9,A3,66,9D,E0,BC,67,4C,A3,2E,81,E2,47,5B,40,C4,32,61,F0,A1,0E,B8,E6,CB,24,38,65,3D,33,38,39,FE,01,78,B1,E0,8D,59,61,8B,CF,FF,EC,EA,8F,8A,5D,BB,D1,29,59,29,08,0D,4B,1B,B0,9A,4A,44,17,43,69,EB,5C,F1,C0,70,FD,06,DA,8C,29,CA,A5,63,D3,DD,9E,18,5D,DC,9E,ED,74,9D,2E,2D,C9,9C,74,50,F3,49,3B,0E,A4,BB,30,61,2B,E6,F9,2E,B1,B4,A7,57,20,2E,86,4D,EB,0A,FE,AD,19,E9,05,7C,6D,48,9F,E0,E2,86,C2,ED,ED,C6,79,67,17,E0,71,0C,60,7C,A6,95,00,07,9E,F1,9F,FC,00,EE,1B,0B,FC,EA,13,BF,97,1D,E6,25,D1,D9,D4,68,9E,7C,9F,A6,B9,0A,CF,DD,92,83,39,0A,E5,FB,1E,17,32,35,5D,3A,B2,9C,E0,D4,6B,26,75,D5,1F,68,D7,36,EA,49,1C,55,F9,DC,27,A6,C6,AC,59,A3,5F,84,7D,B7,63,0B,1E,1C,58,73,CE,40,CB,7F,C3,A5,B2,95,55,1F,51,40,BA,8C,8B,16,EB,09,33,95,B3,C7,F0,93,CF,A2,EE,89,10,49,66,FE,25,4E,1A,9D,5C,BC,7D,77,76,25,A4,37,24,B4,93,99,97,B8,AE,0D,B5,D8,DA,E7,D4,AC,0E,C9,00,97,81,3A,65,47,0C,80,86,66,DE,EB,57,17,04,C4,81,6D,74,99,6A,C3,72,78,E5,CA,47,93,49,AF,62,56,76,46,46,22,1D,78,05,CC,EF,40,84,F3,FF,50,1F,A1,7D,6A,1B,BA,ED,1F,DE,B7,CC,EA,ED,CF,79,23,D1,13,77,89,BC,59,26,CE,5C,50,F8,FA,6C,3D,9C,F1,48,9F,00,18,3F,40,B1,D7,AD,D6,D4,F0,A1,F1,1A,9A,50,9D,2E,B6,F9,4F,0C,65,50,4B,E3,37,45,44,51,B1,11,FF,14,F9,D2,5B,FC,71,7C,5B,95,81,20,4A,CA,F8,9F,A2,33,50,74,B1,BC,A2,21,2B,8C,89,D9,4E,AB,71,12,DD,E1,5F,74,F9,90,24,D0,7B,AD,83,86,8C,54,AF,52,DC,49,45,DE,8E,B3,1F,A5,A1,73,15,C4,05,AE,F7,EE,9F,A4,2D,1F,53,6B,07,F7,72,71,10,A4,49,FB,47,07,1B,F2,65,5C,2F,22,72,7F,21,C3,2A,7A,FF,61,30,C3,5B,CD,88,D1,29,36,22,E5,47,04,75,32,44,CE,3F,9E,8F,31,84,47,D1,3A,F8,48,71,3A,2E,AF,1C,B7,5B,56,53,1D,42,6A,15,3F,AD,94,3D,36,5E,65,C1,C2,23,D6,70,B0,00,E1,8A,89,79,F0,E6,73,8D,D3,EE,53,00,B3,47,C7,5B,E4,FD,56,08,B6,57,3E,D4,CA,FF,B0,FC,2C,52,CE,56,10,87,1D,AA,08,ED,68,FB,18,46,B0,A3,5D,B0,96,A5,4B,25,FA,6F,B5,4F,9C,08,D6,ED,86,F6,C5,8C,B0,13,C6,02,CA,15,01,00,89,77,BF,51,9E,BD,C7,BE,30,33,5C,BF,90,70,D4,37,7A,68,B5,D3,1B,CE,29,CF,50,33,5C,BF,3C,16,43,E3,27,B7,C4,DB,48,BF,4B,FD,EA,26,D0,F0,50,75,8E,92,C5,C1,DA,09,CD,2C,E3,4B,4B,F6,E6,DC,08,59,9E,9C,F3,3D,00,19,B2,C5,50,52,84,08,54,63,FE,5E,D1,35,FF,D3,AD,35,CB,67,3A,02,1A,68,37,F6,C3,FC,54,7E,5A,1F,24,47,52,ED,78,61,12,81,00,62,9D,19,4B,FB,9A,58,91,7F,6C,33,9A,A9,20,FE,4F,B3,9A,0B,7C,2E,B5,93,EC,88,18,BC,BA,F3,9A,2F,03,B1,2C,18,E6,EB,F1,83,5C,78,2E,B8,5D,A5,DE,05,05,B5,9F,66,A9,A3,50,35,08,44,5F,95,6C,E8,DF,08,22,45,2B,2F,9B,82,9D,55,2A,DD,59,2B,5F,F1,6E,78,9F,0E,09,94,A1,79,E5,4C,16,BC,54,59,32,AC,2F,C0,A9,54,66,51,D6,22,2E,D1,60,34,27,3F,12,40,43,F3,A1,17,30,CF,77,92,B2,9B,D0,29,8C,73,51,9B,B4,79,22,1E,60,0C,BA,A2,EC,87,23,7B,87,C9,45,EC,C3,D7,AB,D8,C4,80,31,6D,0B,DB,98,2E,7B,8A,30,93,3C,54,03,16,1B,2E,44,A9,07,FA,62,27,9F,4D,B3,8B,91,D6,7B,D2,3F,07,F3,3D,8D,17,D1,19,FD,CA,F1,4C,25,DF,E5,C1,47,88,8A,B8,03,C5,AD,05,E7,E6,1A,0E,29,C4,98,A3,5A,61,11,8E,B8,32,F0,A8,40,5D,00,20,D6,DE,FA,B7,D3,5D,B2,D1,57,BC,E2,C9,04,C9,C8,20,1D,3E,98,A8,55,1D,4D,00,CB,1B,92,96,4E,83,13,92,9E,8C,9A,0E,5A,D8,05,D0,61,69,CF,56,09,F3,C2,6E,0F,A3,6B,85,90,D8,93,07,72,1C,3D,66,81,1A,1E,16,EC,84,62,3F,D3,7A,20,9D,6B,9F,EA,F5,49,5E,E7,6F,D3,33,D3,5B,1D,92,DD,57,F4,98,C2,D1,71,43,15,D5,78,91,3A,8A,94,8F,FC,42,EF,32,C6,CF,2E,98,02,DC,58,DD,E5,68,F7,C6,BF,F6,64,58,EE,EC,E5,F6,BE,5A,C1,3C,36,F1,1D,98,09,CF,67,4C,28,F4,9C,BB,F3,1D,1C,F7,FB,B5,E7,92,8A,72,C0,E2,3E,FC,D0,76,10,3F,44,CF,7D,8C,5C,03,A4,AB,0F,7C,7F,E5,A5,95,93,F4,F9,E6,8F,37,DA,F3,49,00,B4,8A,63,D6,BE,DE,69,99,B8,58,25,59,A3,72,E9,BA,ED,6B,9B,DF,01,16,08,5A,C0,33,8B,62,07,F0,90,1B,FA,FA,FC,79,18,09,A8,2D,00,75,9E,57,50,E2,8F,3E,3D,E6,03,54,B9,FD,EF,FA,F8,FF,EB,87,5B,11,F7,A8,AE,89,0F,AB,B3,96,6D,CA,0F,46,81,68,34,99,3B,A6,58,A3,FD,A2,F9,AD,6E,E0,07,94,E3,13,E9,D1,5D,8B,9E,55,47,CA,A3,78,0A,1C,1E,12,2E,0F,53,19,3C,5C,B5,93,E5,7F,41,38,D0,5D,F2,2C,D3,73,1D,82,43,BB,E1,1C,70,A6,56,CE,4F,0F,2B,6B,4D,F9,36,4F,7E,96,A8,70,27,9E,0F,11,1B,2B,0F,EF,8B,9D,AF,EE,CB,3F,C5,7F,57,1A,0E,D0,8C,0B,3D,A7,4D,C5,AF,AB,15,4C,7A,35,56,D8,F8,FE,E3,C1,7D,9D,6A,CB,35,F0,3F,49,08,95,43,A3,8C,93,38,90,55,17,0A,4D,04,4F,30,A4,EB,CE,53,1E,6C,33,AA,7B,12,37,05,DD,E2,B1,0A,F1,FA,0C,61,E3,EB,11,3F,DE,BF,46,56,07,4B,E7,0C,D3,CE,82,59,8E,36,5D,B6,E6,AF,B4,DD,26,21,60,D7,29,30,8B,45,F3,EF,81,EC,0A,8F,CA,0D,2F,79,22,71,27,ED,9B,65,D5,92,A6,57,9D,24,CA,0B,6E,A4,05,C6,B9,E3,D2,BA,62,6E,61,8A,81,44,1D,0F,A0,5E,6B,9F,B0,78,15,29,39,76,32,41,B7,4C,D7,A5,50,30,8B,92,4A,10,0A,A7,BE,D8,16,C3,B9,39,25,80,54,A1,AF,32,ED,3D,CA,B8,0B,6A,54,AD,D9,6F,B0,A8,18,87,34,8E,89,E2,45,5E,07,CB,17,14,57,7C,62,86,39,2F,D5,56,0B,2D,0F,7B,1F,15,06,D7,16,A6,B0,00,A5,D0,58,92,52,B0,3A,FC,4F,24,42,84,E2,56,DA,F0,ED,E5,8D,2D,0A,C9,29,48,40,45,8B,05,4E,AB,62,7C,8C,89,71,A3,F0,46,99,65,9B,41,F0,93,DD,BA,66,4F,74,6F,53,F1,1A,74,B6,97,A1,7F,C9,7F,FA,78,43,9B,09,F1,C7,45,CC,14,00,4C,CB,AB,DF,B8,A6,C1,0F,68,CA,64,4F,C1,B8,33,60,86,F3,2B,FF,68,01,D4,2D,F5,09,0A,33,7E,DE,B3,93,04,0E,F5,37,C0,31,83,A5,C6,F9,C5,93,4C,47,FF,D6,BE,50,3D,FF,0C,D8,32,49,53,89,FF,A5,4B,71,16,F0,A8,77,53,79,D2,F5,35,D0,71,02,3D,7C,F4,06,CB,95,1A,C6,87,9E,66,A9,50,D6,D8,FC,13,6D,08,90,98,27,84,D3,78,0B,79,C6,FC,A5,58,10,A1,3A,4A,9C,42,43,5A,4A,E9,06,4F,59,58,4A,B5,35,FE,85,F0,16,70,6A,B1,F9,41,5E,27,81,58,71,89,87,F3,AD,46,6B,45,8B,6B,E8,9F,CE,28,FB,B9,13,2E,9C,BE,01,7C,64,6E,5E,19,79,44,AD,D5,E8,9F,04,12,8F,A7,0E,02,E1,B0,21,2E,64,AB,BA,7F,DF,86,D6,FD,94,D6,24,4C,21,56,4A,C2,65,97,6F,A9,63,1B,A4,2B,72,05,A3,80,27,80,27,87,B3,0A,41,F6,F4,F4,03,D5,C8,20,27,71,38,5C,CF,CC,90,4D,D9,00,66,24,02,0E,02,8F,9B,4C,50,D7,1B,7E,FF,BB,B2,80,DD,E8,DE,74,2C,F8,D2,D1,ED,CF,7E,B1,E9,DC,C3,92,E2,8E,CC,62,B7,62,02,9D,8F,D6,8D,F9,24,03,43,34,B0,69,07,6A,4A,CB,62,36,71,11,C0,89,B1,4D,28,A7,9D,C5,B5,A1,02,04,AE,86,8D,A8,5A,3B,42,E1,B0,01,BD,89,63,B4,2D,8F,2D,5A,70,C9,D0,D2,5E,C4,D8,35,69,76,DF,07,2F,B2,41,58,AD,A6,A0,39,9B,A0,9D,1D,90,CF,10,E7,0C,6F,54,1C,80,E5,8E,A3,68,DB,1D,BB,BB,8A,44,84,04,DB,C5,AD,F8,A4,B2,E3,BD,60,3F,75,6A,A1,57,CE,8B,16,C7,4A,EC,8E,31,E4,86,C1,BD,AA,33,62,53,CB,A9,ED,55,3A,A0,BF,FB,29,8B,74,1C,7B,63,2B,F8,01,4E,A1,2C,B7,FC,04,6D,5F,0A,D4,EF,4D,FD,13,88,B7,5C,2F,B8,1B,05,17,36,93,E0,04,38,33,85,C3,B7,5D,79,41,8D,7F,0F,40,06,8F,74,5B,11,F9,41,BF,FC,3E,17,31,E9,09,F9,D9,C8,68,31,8F,AF,D0,17,B0,57,8E,74,30,6E,60,1F,92,DB,A6,70,24,2D,0A,1D,80,F0,4E,24,D5,3D,BF,12,BE,4D,4E,2A,E0,16,18,92,65,7C,C9,D8,1C,2D,51,9E,DA,12,DD,19,17,55,76,A9,4D,BD,81,AD,20,CB,FC,BF,CF,B3,2C,D9,81,6D,95,E2,AE,C0,35,F9,5F,E4,BE,1C,E2,B8,58,40,0B,20,64,C4,F2,7C,F9,B0,27,3C,29,1A,B8,E2,42,EE,BA,46,41,2D,CA,72,18,70,CC,DA,30,05,3D,96,7B,5F,0D,E5,D7,FF,4C,CD,BC,95,45,75,9F,25,7E,B5,69,9D,EE,E4,C7,44,CE,39,01,AB,A2,1D,7C,2F,5C,ED,ED,2B,92,F8,2F,01,6E,C0,51,8C,BA,2B,32,07,E1,06,5A,00,0F,00,C9,E0,CE,2F,E9,B9,4F,BE,E8,A6,4A,2C,6C,4D,7F,C7,1B,62,DC,4E,40,E5,AE,0E,C5,D3,6D,2E,A6,7A,8A,23,46,A1,E6,96,AB,F5,BF,D4,C9,ED,63,58,47,78,E9,56,BD,A1,59,44,46,51,03,93,F9,08,22,92,AE,5A,9D,55,43,13,FD,EE,4F,A2,4B,67,C4,41,17,89,6B,34,6E,E4,62,2C,86,3E,AD,8D,88,54,F2,34,08,96,33,19,74,DF,DA,47,42,D6,66,35,10,4A,2C,5F,D3,3C,6A,42,DE,A1,7B,84,8A,A4,32,8E,95,FB,C6,73,1F,C5,2F,C3,88,93,46,D3,7D,39,52,35,A8,16,B0,9F,D1,16,DB,24,57,E3,C7,2F,8E,15,C9,BC,68,F0,B2,87,C7,8D,64,0A,2E,23,F5,64,EC,5E,D9,9D,08,E3,77,48,EB,C6,8C,1E,5B,44,E7,28,DD,94,00,D9,D8,24,F3,34,1E,28,91,1E,5E,DD,00,97,9B,29,D2,5A,F5,AB,88,44,A3,B7,B5,4B,C9,3A,A2,17,28,7A,47,D0,2F,67,8E,32,0C,08,FC,9C,96,F3,F8,FC,0C,C0,06,7F,56,D8,45,EE,04,B6,0C,5A,DD,D1,A9,EE,70,1D,7C,A2,CA,00,D9,DF,05,F6,82,EF,7F,05,62,18,6F,75,14,AC,4A,E7,74,E7,B3,15,84,CF,B6,21,77,8A,08,70,D0,C5,D3,DE,70,20,ED,1E,E7,03,66,97,55,2A,20,C2,63,A5,09,C4,6F,15,94,70,D0,DD,EF,05,10,86,19,93,A3,5C,D7,38,98,A1,49,C6,DF,6B,06,5C,D3,7D,A7,6E,29,30,92,88,53,28,42,D3,CC,4A,FA,3F,C3,CA,4D,D0,A3,35,04,EC,59,AC,F0,35,1C,04,94,A2,98,42,86,1C,93,48,EF,1C,F4,C9,58,B2,82,D7,D8,9A,AC,2E,93,C8,20,36,A3,79,91,75,18,3D,C0,DD,EF,BE,0F,75,45,FF,D8,4F,E2,AA,44,2D,30,DB,FB,FE,14,D6,F4,AC,22,47,2C,84,F9,FC,F4,5D,F2,76,1F,A7,2C,88,61,BA,46,79,4A,39,71,7A,78,94,E9,09,19,15,86,34,94,BE,51,0F,0F,3C,B0,09,15,9C,64,38,0C,05,73,08,D6,B5,D6,67,2E,99,77,31,A8,70,7B,3A,AC,91,06,97,83,4B,A1,2F,8A,E6,DA,C6,12,58,EB,5B,B1,74,57,33,7E,DD,D3,4D,26,CA,11,F4,34,E6,E2,53,FA,4B,87,C9,A1,DA,41,79,D9,97,B9,1D,32,29,85,D0,8F,81,A6,F9,F4,94,3C,70,35,A8,0B,3C,26,09,4D,AE,DD,71,4C,E3,A7,00,72,31,B6,4A,A0,99,CF,6C,57,B3,63,D0,1F,DF,5B,FE,4C,D9,95,A9,80,17,73,94,75,A8,F7,A0,FF,0B,50,64,F5,0B,70,A8,BF,C0,5E,DA,2D,FB,8B,12,3A,AC,CB,0B,95,F7,EE,28,04,7D,78,9F,B5,90,69,C2,05,E1,2D,2F,9D,F8,78,63,A5,E1,51,44,6C,86,57,6D,07,62,D5,34,E0,80,B7,36,4F,B2,DD,6C,25,51,F6,BB,0F,9F,CE,56,1C,47,E2,82,15,52,A2,78,22,4A,63,AD,9F,38,0E,39,04,3D,33,AC,89,1F,80,FF,18,DB,C9,F6,4D,94,D5,E6,16,89,09,90,D6,6B,E9,D3,AB,5C,1E,F6,EF,0E,DA,09,1A,9B,21,2D,74,B9,9C,5C,85,2F,4A,32,D1,EC,12,7E,DC,E3,18,26,6F,9F,25,65,AA,CA,3E,3F,BA,57,BB,6A,1B,A2,62,A9,83,D8,0D,E8,E1,7F,91,69,01,57,B6,EB,F7,B0,84,DB,E8,E6,90,F0,4C,E9,1C,9A,BD,14,FB,15,89,F2,48,02,3A,C4,54,A2,73,D3,21,7E,25,C4,C0,1C,C4,88,D8,E1,18,78,A4,A2,7B,E9,9E,81,39,4D,E8,64,7E,AB,D6,89,3A,88,EF,94,9C,4D,BA,49,DF,A1,79,AC,10,3B,D2,83,43,83,DE,96,E6,8E,26,6F,83,72,C5,9D,19,28,72,C5,60,7E,9F,24,62,B6,58,2B,E0,0F,25,D8,3D,BE,14,B3,FE,B6,24,C7,F9,2B,C3,F1,EE,2E,02,F1,A6,3B,6D,E0,E2,AF,EF,5E,D7,50,5A,19,2A,D4,78,0D,04,EB,BA,55,80,6C,F3,A6,AE,13,64,5E,51,A8,10,DE,B3,92,2A,7D,CB,C0,DE,CD,AE,C4,5A,AB,7C,79,69,2F,75,E6,5D,4C,46,09,72,A6,4C,CE,7E,6F,12,16,40,A3,C7,F2,D1,D4,E7,52,B3,6F,35,04,29,B9,DD,67,9E,89,85,6A,8B,C8,71,BA,8E,FF,02,AA,37,DF,16,92,7F,22,9F,35,57,18,07,BA,55,80,E2,86,CC,4F,0F,73,D9,21,2A,4C,32,33,CB,F3,59,21,E3,22,C4,F7,71,3A,1E,F5,B9,19,B6,A2,45,04,C7,40,67,AB,2A,30,10,22,E4,D2,9E,4B,06,52,8D,A1,36,FD,BD,92,7C,D9,A5,ED,EE,68,DC,82,31,BE,8E,33,7B,18,0B,81,2D,0C,A6,74,15,C8,7A,6B,F1,69,CB,2F,CB,73,81,96,B6,6D,6B,5D,58,FB,02,66,7A,2E,3A,08,06,67,86,04,ED,CB,55,31,F9,65,34,79,45,21,B8,22,D0,19,08,5F,9E,DE,B8,D6,ED,39,60,DB,9E,12,C9,3F,29,6B,9B,93,56,D5,53,18,C4,83,11,3B,6F,04,55,90,18,00,C0,4A,0F,66,FF,DE,69,0B,66,8D,0A,AE,CD,43,8E,59,1E,33,78,9D,4E,98,88,B6,B6,E6,9F,BD,78,BA,FE,10,C0,54,EF,16,50,DC,30,53,06,F5,87,AC,0E,E9,C0,B7,1B,B0,B4,F7,DF,03,BD,B8,46,9D,B2,7C,48,F0,9E,6C,22,50,B9,E7,C4,D6,F8,67,AB,4E,BE,C7,D8,FE,C3,7A,91,8C,2D,69,EE,12,A9,9C,FF,0F,5E,25,58,08,7A,20,2A,E6,9A,52,6D,36,97,6D,98,5D,47,0B,A3,4E,AE,E5,30,23,53,D0,5D,9C,2D,87,ED,F4,C9,A3,B9,4C,4B,77,C6,0D,D1,46,82,2A,09,4D,B2,EA,1D,8C,42,2E,D8,8F,D2,0C,27,D3,29,0E,6A,0B,11,3D,F6,73,4B,0B,30,57,ED,B8,78,61,3F,45,96,90,DC,2D,F3,BF,DD,68,A9,C3,07,27,E0,6B,73,B0,19,A1,F6,5E,07,BF,5C,82,B3,93,8F,0B,7D,F9,F6,7E,1E,05,6B,DC,3C,A8,C1,A0,F1,94,BC,2D,73,B1,93,2F,71,BD,65,23,BB,8E,08,3E,A5,FA,50,AD,D3,AE,71,11,AD,D0,C2,5F,79,FD,97,13,A4,6D,A7,E7,8C,A2,CA,18,8E,C6,F7,E8,B1,D7,8F,D0,86,74,1D,E3,09,68,16,5A,86,8F,49,9D,88,D7,DB,17,4B,48,34,2C,6F,50,34,F8,A3,E9,34,1F,93,82,DA,B9,B6,67,7C,0F,D8,AB,A1,C4,84,49,0F,18,54,8A,ED,64,A3,69,EE,33,1C,B9,7A,DE,3F,25,BB,39,8E,F9,11,6A,6B,8D,47,37,1E,5A,F5,8F,6E,C6,B9,AA,9E,56,1C,CF,A3,2A,1D,34,FF,F3,B9,1D,38,DB,D4,37,6B,05,AF,11,F0,B9,88,62,DD,53,DF,0C,DE,37,86,E1,46,B0,1B,B2,68,D4,96,11,1F,6E,F5,4C,FA,AB,7E,93,E5,93,3E,87,03,69,1B,FC,F5,E5,C0,C2,F2,7C,A2,44,23,EC,18,22,41,EC,4C,2F,0F,19,FC,6B,31,59,41,7F,AA,AA,17,F9,AD,5A,00,0F,72,A7,17,BF,64,CA,EB,18,78,62,8A,36,2F,04,04,DE,4A,76,BC,16,66,2E,47,98,1A,54,AA,5E,A0,BA,5E,C6,E6,D6,60,9F,27,26,C0,ED,9E,EB,C0,59,DD,6E,EE,72,84,9A,23,A9,1D,14,32,06,3E,67,B0,86,33,EC,A6,79,DE,2E,CB,5C,53,42,4E,F0,1B,3B,DD,22,E7,C0,CC,8B,C2,CC,C5,54,0D,8F,B6,F8,A2,C2,0A,4F,56,56,73,B8,EB,C1,92,59,E7,DF,C6,8F,F0,84,DD,0E,91,E6,A4,9D,F4,77,CF,01,B8,A9,D0,59,0E,08,CA,52,30,7D,FD,12,A9,CE,EC,39,04,49,1C,F6,36,F0,BB,CB,49,29,9B,9F,6D,1D,3D,75,0D,B3,B6,E1,72,1A,A0,84,FB,C1,F4,9C,15,31,38,50,07,C3,E3,E6,07,61,F8,43,65,92,A8,75,E4,C1,F7,5F,A8,EA,69,25,90,93,BB,A3,41,3C,6B,A7,95,2E,33,DF,EA,E6,F1,4C,B6,D5,D0,CC,9B,E6,C0,49,28,58,A6,CD,2E,5A,D0,3B,60,61,91,D3,7F,58,F2,CA,44,8F,DD,3B,7E,50,D1,B2,02,25,37,2A,40,67,7E,9C,F8,88,CB,ED,E6,36,17,E1,CF,1B,68,93,8F,6F,B7,76,64,7D,FA,69,3E,20,0D,91,70,4B,E9,D0,52,F8,FC,D2,26,7F,E9,27,A7,CD,5F,F7,26,38,FB,7C,72,86,3A,C4,9D,18,09,CD,D4,08,AC,CF,92,15,23,A4,3D,1B,20,70,DB,64,37,AC,69,FC,1F,7F,0E,F3,B6,48,F1,AE,D1,25,51,A5,3A,B8,9D,0E,0C,3A,43,5A,E2,0C,97,38,7D,18,26,90,AF,27,68,32,85,5C,A2,41,BF,6F,37,59,F1,E0,FC,5E,6D,18,A3,B0,9D,2D,4F,09,6B,9A,23,09,5F,B5,2A,42,22,4A,AF,34,55,D8,83,95,1C,C3,DD,9A,EA,52,A8,ED,2F,54,D3,BB,AF,8F,BB,4F,C7,29,57,2E,1D,A8,C7,07,B7,1A,75,7D,67,AF,BF,84,DC,88,B1,62,19,AC,FD,B1,A1,EE,86,79,56,E0,4E,A4,4F,71,76,B7,D2,77,3A,FF,AD,09,F2,6A,5D,F7,D7,92,DE,DF,EF,C3,DC,9D,81,BB,61,69,50,47,B5,3D,54,3D,BE,74,FD,6B,DC,23,C3,87,4E,C7,23,3D,A9,4A,8A,18,E0,E2,4B,19,98,21,C3,58,37,88,1F,FA,56,57,47,DC,02,D8,E9,2E,31,6E,9D,9A,47,B0,F0,7C,D5,5F,E9,3F,83,CA,9A,97,A2,26,C9,F3,A9,58,C3,EE,8B,50,94,51,53,1E,D6,C8,91,02,89,7E,87,6C,DE,ED,C1,A1,95,8F,87,C0,C3,B5,5F,04,01,CF,CD,E8,B1,1A,A3,2D,33,B2,F4,6C,12,00,36,9A,62,16,60,7E,4A,E6,F0,3B,C6,07,12,B0,46,8A,45,AE,AA,77,73,C9,FE,0F,EF,1C,0D,2A,31,4D,F0,6C,23,3A,43,1E,BD,1A,DD,F6,97,3E,81,30,EC,A3,9B,C5,A9,EC,41,9E,4D,BE,53,FA,67,7C,D0,BA,77,FE,35,AE,25,F9,19,27,09,B0,6C,AE,DB,62,80,F7,DC,58,78,9F,A9,BD,E4,07,67,54,8C,5C,E9,91,9E,A3,BC,6D,29,32,38,EA,2C,63,21,44,3E,2B,87,5C,9E,09,AB,22,1A,E0,33,47,1C,B5,CF,76,0A,36,58,A4,C9,80,BB,1E,C4,29,95,24,45,49,54,57,E5,25,DA,0B,6B,6F,A4,5D,FF,F6,DE,E1,F4,6B,89,60,E3,7E,C8,5E,3F,19,FD,38,F5,8F,D4,D5,6A,BF,E2,80,9B,CF,2D,2C,1F,A9,60,5E,FE,9B,8D,76,5A,7B,AC,A0,42,C2,A6,39,73,E5,C7,1A,0E,7E,69,4A,50,75,A2,04,21,CD,95,A9,74,B5,F5,E3,F1,90,5E,B4,38,08,EC,AE,BC,ED,09,89,E6,41,DB,BE,49,AC,8E,6A,9A,DE,77,6C,AE,38,3C,FF,5A,3F,76,E7,53,13,3F,A2,32,7E,3B,D5,2D,3D,95,72,7D,B6,EF,CD,CB,DE,36,82,BF,10,8A,B9,7A,4B,7F,F5,A9,6F,43,51,3E,2F,EC,AF,C1,F4,FC,31,BB,05,1E,14,F7,2B,66,B6,F4,12,54,47,F3,52,B2,72,E9,7E,88,F9,57,D4,92,BF,CE,E7,CE,9D,52,E2,87,2B,C2,0B,FB,B2,63,2E,0E,8A,E3,9C,DE,56,93,C4,70,DC,4C,3E,15,B1,44,BB,C9,2E,6E,6C,72,60,31,A6,95,26,EA,2F,14,D2,DD,61,C8,45,0A,A4,E1,8A,16,5B,88,21,10,3F,D7,3A,2E,3E,7D,93,E2,7A,92,0C,D4,10,2F,AA,C4,FE,04,2B,EB,FC,AA,BF,47,19,B8,5F,4C,0A,EB,73,E3,7E,5A,67,27,DE,F1,E9,02,56,99,82,4E,DD,EA,EF,2C,D0,DC,F2,61,6B,1E,C7,C2,70,0E,20,D8,5F,47,C2,0C,01,B5,DD,2A,66,83,74,9C,EB,A7,5F,0B,4F,6A,91,67,88,5F,31,A6,CF,FB,49,D8,0C,B2,77,67,37,86,E9,8B,79,F5,C8,DB,0E,DA,23,33,66,67,ED,C2,70,72,BC,4A,A9,C4,4D,C0,A1,C7,1D,AD,51,16,1F,37,F1,FD,AC,99,E6,7A,72,E2,2B,BB,AB,A3,9A,9E,A6,19,94,FE,84,3A,37,13,E4,AE,80,39,02,F2,B8,5C,EF,0A,7B,EF,87,FC,A9,F1,F3,9A,8B,82,0D,61,3F,F6,7D,8E,30,B1,24,69,F5,04,47,B3,77,30,9D,5D,A5,6A,EB,D6,57,E6,7F,14,FF,5A,24,67,FD,FC,CF,E6,BF,A0,3F,4F,A3,CE,3C,79,39,47,67,23,03,B1,05,0D,82,82,3E,B7,24,4D,8D,CE,7B,31,30,12,83,D4,86,9C,DE,45,3D,06,7C,F9,FA,F8,BA,CF,02,5C,9C,6C,E0,2D,CC,6B,18,E8,F2,49,16,37,35,E7,36,5C,7A,D8,7A,32,0C,69,A3,84,9A,30,59,54,1B,64,C8,8A,C6,01,00,33,A2,5D,E7,D8,C4,85,34,CE,17,D6,07,E1,A2,7A,34,EE,58,92,38,95,31,A8,44,E6,BC,F3,C1,7C,22,E8,95,36,96,42,15,6B,59,0F,9F,78,8C,4B,63,9F,20,A5,9F,57,05,FD,64,0F,4F,1F,3C,93,F9,A7,45,0F,2A,5E,C3,15,66,FC,D4,F7,5B,59,AB,43,06,C7,0B,EF,46,36,D8,23,AD,71,CA,A3,D3,AE,39,1F,42,45,5C,BD,E2,FC,29,99,B4,FA,95,60,40,21,21,22,54,9A,56,BB,E7,8D,7A,70,51,E6,0C,34,45,0D,E9,38,5F,6C,E5,0F,10,9B,C5,99,AA,74,2C,A9,66,B6,DF,82,3F,E5,44,C5,AC,E3,79,79,A3,D9,2C,F8,21,DC,50,68,7D,8D,7C,AB,35,E0,0C,2B,15,18,B0,6F,BA,0C,A2,92,8D,C7,58,5C,D3,AD,DF,DF,5B,64,5D,24,61,BE,4C,C7,73,A2,7F,39,D1,5A,2D,D4,91,38,03,BB,76,81,6D,73,2E,A0,2F,09,8C,04,A4,63,26,B3,D2,AE,72,EB,1D,22,B2,BF,73,BC,E3,15,D6,F0,4F,73,92,4F,B7,F8,BC,D8,BF,84,42,38,FD,93,E7,73,95,46,3F,8F,64,C8,A3,D5,08,A6,E6,14,44,AF,63,E9,13,AE,75,B3,88,38,8D,FE,1E,DC,1D,71,BF,CB,78,41,61,24,BC,CF,CA,4C,58,E0,F8,BE,26,A6,9D,5B,7D,AE,D0,C8,06,41,B5,58,8C,7C,C4,8D,DC,D2,7E,0D,09,A8,E4,32,39,C3,3D,66,9F,43,14,34,09,08,7B,EB,98,F1,62,CB,17,D7,8D,E9,60,FD,2C,4C,5E,ED,99,C1,50,84,B9,CE,80,16,42,5A,56,8F,74,51,3B,EA,39,F8,72,AF,DA,51,ED,22,31,6C,E6,49,49,A6,C4,C9,0B,B9,4D,29,15,C0,E1,68,DD,6B,B9,2C,0E,B1,1D,D6,D0,48,6F,50,53,C2,64,83,EB,02,E8,D0,CE,64,3E,E3,F9,5B,DE,92,B3,78,D5,6D,38,10,E4,42,2A,DA,04,2B,81,7C,6C,A2,DA,87,FA,4C,70,D6,02,A7,06,6A,34,04,2F,83,FC,0C,3E,8D,07,94,59,DF,0D,69,17,9E,6C,49,46,23,71,05,71,95,89,99,DC,57,36,2C,0E,A4,6D,C5,D0,8F,EB,BD,63,71,AD,89,CE,3C,F5,FC,56,64,CE,5D,92,41,85,56,5B,10,D3,C4,B7,A6,A3,3E,76,CA,C1,FA,BA,61,39,EA,AA,26,93,61,47,B9,72,3C,9C,64,9D,67,4F,C9,C5,D3,92,FC,76,04,6D,C8,57,F1,F3,55,DC,77,6F,7E,18,DE,27,A2,BE,78,FB,61,12,F0,D8,B6,B4,4E,D8,09,14,69,4C,8A,04,B8,9F,BF,23,7A,6A,8C,52,8E,99,AA,F0,24,00,1C,68,CC,A4,B1,87,A4,59,BC,85,9C,E6,8E,3C,6F,EA,92,80,3E,21,E8,20,BC,B4,3C,D9,96,96,EF,9B,DC,36,94,2E,97,E5,22,A7,5E,D1,95,85,0A,10,AC,F1,04,A6,1E,23,8D,72,A0,9F,50,45,28,47,96,B0,21,B0,A9,74,1A,34,E2,A2,2E,C1,AC,AE,32,2B,AF,63,0A,8B,65,E3,B7,9A,45,85,E1,B8,0E,EF,D1,D7,35,45,44,49,7F,38,39,B5,70,47,AE,49,17,F3,CB,41,20,6C,F5,F9,36,5C,DB,BD,0B,2F,12,56,EF,2F,4B,FA,28,54,DB,06,21,F7,00,BE,81,34,93,CB,02,6A,78,B1,42,88,44,FE,92,4C,57,5D,EA,3C,EB,06,96,04,F6,5C,09,4C,52,EE,C8,89,C0,FC,F7,E9,35,40,5A,31,C9,C4,7E,F6,17,66,D1,D0,F1,3E,EA,72,4D,98,B7,91,34,7E,D8,2E,AD,E7,C1,01,31,42,D8,BE,A0,DF,CC,ED,63,7C,0A,B8,17,5A,C7,86,3E,FE,C1,35,32,8B,18,A7,40,C6,66,2C,A8,82,F5,8F,AA,C9,C6,22,F5,B5,B5,C8,CA,0B,D0,AA,5A,9B,F0,4B,55,E2,70,9A,E5,E5,80,A8,02,67,4C,A0,18,73,98,B5,D7,03,DD,F9,C3,35,2A,43,35,5A,7C,CD,7C,50,24,E6,C0,28,74,AF,2B,DA,CB,FC,F4,AB,EA,8B,3A,7C,B8,75,7F,65,5F,16,58,CF,1F,DE,5B,DF,FE,65,E5,E3,EE,42,0A,C9,84,69,FC,3C,8A,3B,C0,A8,52,B3,A6,A0,F9,E5,75,37,59,29,49,04,EE,DD,1E,12,60,80,B9,FD,7C,46,BB,F5,79,98,F5,C2,87,54,60,2D,2E,CA,73,92,13,30,16,C0,40,12,A5,47,40,AA,AF,46,55,C5,40,F8,CE,4D,01,B0,E4,B5,EA,6D,27,BE,28,01,66,1A,B1,16,8F,B6,05,12,48,E5,1E,8D,8E,0D,04,EA,AF,86,22,7C,B0,F6,B8,61,FC,95,0E,5F,BE,B5,1A,2F,93,D3,4F,7F,A2,EE,D2,D5,8B,10,48,A5,51,43,E5,7B,0B,84,0E,85,81,B9,25,85,66,CE,97,C9,61,CB,53,B5,4F,3F,14,C1,93,60,74,24,9D,B8,6F,A6,4F,D2,E6,63,A6,74,89,F7,13,43,B8,52,5E,5D,C4,17,95,25,60,C4,55,B5,2F,BE,7D,3D,6C,D8,D1,3D,76,CE,18,EB,5B,E2,4C,58,9B,9B,7A,40,48,8F,E0,F4,9C,1C,82,6A,4A,39,BF,EB,63,E9,E7,E5,ED,0B,B9,75,86,6E,8F,24,A2,D6,C4,7A,70,4D,A4,11,25,27,E7,74,6D,2B,8F,95,4C,8A,1A,DB,A1,E3,3D,BD,0A,C0,05,7A,28,70,AA,AC,2C,65,A4,5D,61,6B,6A,25,46,DD,5C,00,84,11,DC,7A,56,52,30,C2,01,BA,32,E9,D0,D0,F5,3B,A3,D2,B2,0E,22,91,DF,FB,55,B3,28,5D,58,20,76,77,5B,C0,CB,08,A3,0F,A3,EC,B0,E3,60,06,3C,DB,47,E5,05,55,D4,6A,B7,97,CB,3B,79,D7,3A,E0,79,02,36,BF,FE,03,A0,C5,EE,08,B5,83,EF,EB,76,B8,32,58,95,92,62,C2,9B,72,C2,05,67,56,C1,2F,89,62,8E,DB,38,F3,BC,2A,44,9D,33,FD,28,F9,31,1D,03,DA,F7,62,36,AB,AD,AA,ED,6F,91,03,A7,9B,29,A9,6E,32,C2,9B,C5,93,C3,AD,0B,5C,3B,26,F6,77,33,89,9E,D3,E1,F0,F7,64,84,64,7E,7D,98,99,DE,C8,81,6B,A7,45,1E,17,8B,01,EB,17,14,6E,46,2B,F0,E3,A0,D4,F0,F2,06,7A,B3,F0,C1,BD,ED,7A,1D,77,37,C9,09,83,8E,C0,2B,6A,32,55,51,41,B5,68,30,2E,C8,A5,7F,DD,98,AB,1A,31,29,22,F5,65,BF,7C,D6,D3,1F,02,96,05,E0,F5,A8,F2,69,FA,47,7A,0D,1F,9A,64,F4,DA,49,9C,93,7A,5B,1B,EC,D0,82,F5,A9,DB,40,53,A5,F0,37,7B,8C,1B,BD,49,B5,6A,8D,7B,30,BC,F3,81,01,54,3C,E9,A4,70,DA,AF,C4,F9,86,CE,3C,64,9E,7B,62,78,9E,ED,9A,D0,19,6B,F1,4E,E9,58,F3,73,6E,A1,38,4C,BD,EB,12,7E,E8,30,12,DA,69,6F,82,25,32,D7,93,1E,77,E9,8F,13,A7,CC,C2,CE,5B,E8,02,FA,FB,EC,DE,01,F7,27,1A,41,CC,3A,5A,B6,58,A8,D3,05,E6,70,78,0F,92,8C,0C,2E,B6,6E,5F,EF,96,3D,47,1E,C2,C6,66,DA,E7,53,B4,8D,BA,2B,78,F0,EE,74,45,1A,C1,12,5E,E6,81,02,F8,DA,DA,B6,22,4D,6A,E3,3C,BD,B7,A1,FE,5A,2F,E5,08,03,23,8A,1A,DD,D6,1E,97,92,40,B3,E0,21,58,4D,3B,26,1B,F3,A9,5D,AE,6F,83,7E,A3,00,76,0F,43,7E,03,6C,EC,36,DE,45,28,6C,23,87,C6,8E,1C,87,4B,E5,5F,3C,76,18,D0,4B,45,72,24,ED,43,95,A8,F7,15,C8,75,2C,43,E8,2F,FE,0A,39,2F,B7,9E,20,8D,D1,44,29,E1,8B,49,53,F7,FA,C7,08,94,62,C9,5F,E4,B8,65,51,69,0F,93,EF,FB,9F,C8,71,7A,99,53,EE,80,2B,FB,B9,C4,6C,9D,B1,E2,E3,E8,BE,FE,11,07,47,D5,F7,CE,1B,EE,3B,C5,15,1E,FA,3C,A5,DA,8B,9C,E5,ED,46,24,47,70,D0,C4,91,8E,6F,FE,8C,E5,57,BA,D5,15,CB,0F,24,E0,B8,08,8D,9F,07,D5,5D,67,00,EC,1A,D6,EF,29,F8,DD,EE,BB,75,6A,29,E8,8F,5D,E3,8C,CA,C1,26,6C,6A,00,E9,DA,CA,CB,AC,52,46,DA,BE,D7,65,D2,14,FE,1A,E8,C8,FD,3F,50,2D,57,A9,DB,BA,CF,F4,63,39,D2,14,0D,CA,3A,41,31,80,D5,D8,42,9B,8C,50,72,8D,1A,00,35,67,16,8C,4F,D5,3D,33,E6,85,FD,20,A0,D8,81,B9,17,CB,B5,A6,7A,0B,E8,A9,43,0C,82,D9,6D,FC,12,7C,2A,81,CF,99,82,51,17,FB,B3,FD,90,2A,D8,89,3C,A4,CE,6B,84,32,01,2F,F0,82,FD,CA,2A,9D,ED,FB,82,15,2C,1F,7E,19,3F,54,41,A6,40,D3,B1,2B,5A,FA,9F,52,96,7D,CB,D4,17,B5,CF,2E,7B,EB,D3,29,C6,6E,8C,9D,79,69,BB,D9,3B,9E,2C,60,03,0B,0E,D5,96,54,B3,9D,18,F4,5C,DD,47,0C,CA,86,1D,0E,7A,F8,8E,4A,85,CD,6B,13,0B,D7,5E,D3,35,D6,97,C4,8B,1F,81,0C,E4,EC,24,09,E7,79,44,F9,37,14,52,BC,EA,A2,83,5F,ED,87,A3,07,22,0B,7C,7E,C7,E7,BC,AD,C1,5C,48,E7,29,B1,99,15,44,3F,DB,AF,0E,84,E9,78,9B,D7,D1,AB,8C,49,79,76,ED,00,57,1C,71,19,EA,95,69,D3,D8,36,99,3A,3B,8E,F2,B7,01,75,BF,D3,99,2B,D8,B1,82,C7,51,DD,E2,9F,6D,EA,AA,45,68,05,67,48,F8,ED,7C,EA,D5,18,D0,38,BB,46,36,7A,51,35,7A,98,7A,D4,E6,77,4E,9C,C1,0B,89,52,58,1F,8E,BF,CB,25,0C,69,ED,AB,7B,85,9E,83,F1,71,C5,34,F0,71,37,38,33,9C,37,73,FA,9A,B1,39,EF,54,3D,9D,55,BC,44,A8,89,7C,CA,FF,87,C2,46,78,03,E0,5F,4D,BE,1C,31,22,EE,0F,74,C0,54,51,0E,CD,EE,65,64,0E,56,7C,61,1A,AE,FF,6E,12,AD,1F,E4,8F,7E,94,E9,00,4A,77,97,5D,F5,2F,44,73,D0,A3,A3,81,81,08,4F,B8,36,5C,EE,F2,37,D6,E4,1D,85,82,EB,E6,0E,1B,C1,C7,BC,D0,E0,91,55,61,0F,29,93,B1,2D,C4,F6,B8,5E,75,6F,A0,4F,F0,F8,C5,84,51,33,22,7C,79,5E,3F,47,3B,96,87,0C,37,93,F7,CA,70,FC,98,45,7C,11,BC,04,57,93,60,55,51,9C,BF,95,4B,EC,59,3F,1B,93,A0,42,5B,90,FB,7D,A0,0F,0F,52,E6,93,52,82,2A,8A,B8,5F,0A,C3,B9,57,EC,32,E6,89,0F,F9,22,BF,E5,9D,B7,E3,D0,6E,F8,A8,37,1A,6D,33,F9,C8,E3,45,FF,4F,40,A5,90,05,A6,C3,DD,27,AE,4C,EB,EA,30,0B,85,F1,7C,FD,84,E9,14,0F,36,D0,8A,63,7E,A6,3D,80,98,AA,19,7B,22,1C,E6,9C,1F,BB,66,A0,66,31,70,07,55,2E,B4,3C,24,E6,D5,D4,88,63,FB,AB,79,D2,06,BA,D0,EA,55,99,4D,C7,6E,84,7D,24,52,70,22,5D,84,2F,B9,9A,85,7D,16,36,AE,8E,8C,94,68,1B,BE,81,18,70,EE,FD,4C,93,8A,20,2E,09,58,CB,5B,C7,71,A0,9A,5C,5D,C3,6B,11,8E,5E,71,C9,54,9D,2D,A1,77,1E,1F,0A,77,B9,5C,C6,FE,E3,D2,61,EB,01,28,78,E7,CD,F9,88,92,A7,FF,09,6B,64,2E,9C,33,E3,AA,9B,57,63,BC,48,19,7D,F0,80,77,23,2B,68,52,C2,41,C9,D9,47,54,5B,58,5D,17,3C,23,B6,F2,6B,1E,9B,DC,A9,9C,05,95,D5,41,1B,07,2F,5A,84,BE,F9,2C,2B,71,47,06,99,32,FA,83,E8,04,8F,F3,52,F6,20,D0,04,0B,47,F3,23,DE,AE,84,E0,BD,A6,12,08,07,96,71,6C,EC,30,5D,EE,F8,F6,C8,D4,28,13,5B,95,12,6A,E5,62,00,83,20,6A,9F,58,24,89,AA,4C,B2,B0,C7,55,D7,DB,E8,9B,A9,0A,92,0C,9F,09,4A,79,AD,9D,F7,70,A2,BD,2D,B6,2C,14,8E,4B,11,5B,8F,E2,1A,5B,F4,C4,AE,61,51,27,74,8B,21,55,81,59,76,1B,99,D6,F3,B2,1D,72,95,0E,14,CD,F3,79,6C,0F,6B,7D,44,9C,3F,40,08,19,18,69,46,7B,6B,FA,17,AC,D9,A0,57,3C,BC,29,0E,80,7E,EA,C3,D2,C9,CB,8E,50,F7,DD,83,C7,83,E1,8D,87,FC,87,34,CB,4B,F1,8C,22,68,D3,58,CE,05,B2,6D,93,17,47,75,A2,4B,95,D8,D6,59,1B,28,40,E7,26,F9,7D,3D,67,E3,5B,12,04,BB,84,70,95,04,08,78,EC,C8,13,A8,ED,A7,05,4E,17,8D,13,E9,0F,D8,C8,13,A8,92,50,30,10,BD,15,ED,E1,3A,5B,06,7F,D8,04,53,F7,E3,12,D9,3F,81,F4,A1,34,9A,CF,04,19,23,7A,71,89,5B,FE,39,F2,E2,0A,85,98,B8,3A,1D,95,30,31,E5,EE,63,0F,5C,0E,C6,5F,86,B9,F5,C3,67,F1,AD,58,CA,81,CD,AD,D9,0D,3E,36,F1,06,EA,1D,20,C2,E4,3C,CE,3B,C2,FD,82,8E,6E,F3,97,68,BF,44,C7,D1,88,D4,03,44,EF,CE,A3,13,0A,CD,94,BF,9B,8C,46,7D,16,2A,37,17,F9,40,AF,30,96,98,60,D5,7B,90,47,23,6F,12,29,72,39,5A,5B,5C,12,A8,37,B3,4D,84,E3,1F,A9,60,4C,43,08,62,6E,14,9E,C0,AC,45,3D,CE,33,98,E1,36,EC,D3,07,2E,41,3E,30,FC,8E,24,88,76,64,28,B7,8D,C6,4C,CA,27,75,43,28,9F,1E,AF,58,4C,09,3D,9A,2F,96,63,5E,A6,ED,9C,63,45,49,31,DD,1D,7C,B7,D3,8D,B5,8B,35,0D,9A,5A,18,00,FD,F1,E6,FA,A7,C5,0B,BF,5E,D1,16,22,2A,81,61,CC,05,CB,23,18,E9,62,F9,F1,1C,E7,2D,11,3C,7D,35,96,33,07,35,EF,E5,29,24,F5,92,AA,C3,23,E5,93,12,AE,6D,95,85,5F,EF,31,89,37,30,D6,17,50,24,F0,5D,91,AD,AB,97,31,BE,37,E5,BA,04,98,ED,2F,A3,20,3E,2C,5D,D8,8B,77,B6,63,E7,55,63,C5,34,C6,07,11,56,96,80,A5,2A,83,11,7B,70,E8,1C,41,9D,D4,4D,CF,DA,B0,29,02,0B,FB,10,B0,5F,96,8F,2D,C0,B2,24,19,16,3A,96,4E,05,D8,94,93,DF,D0,D3,F9,BC,75,A9,54,C0,82,3F,F7,56,58,11,A3,B2,05,20,02,FE,13,2C,8B,EF,EE,FB,DD,D3,04,32,62,F4,D6,BD,C8,5A,C4,1F,C8,18,A7,FC,2D,2C,B7,03,D5,DC,34,D0,C0,66,F0,B5,13,A7,D5,03,28,4E,16,D2,21,1A,1D,51,09,D5,2C,10,27,21,F3,0B,EE,82,7F,F8,9E,E1,9B,FD,F8,89,8B,6F,03,E8,37,F5,C8,8F,C6,5C,75,39,26,6B,31,8D,55,B0,C4,E7,FB,F1,48,A4,CB,E3,BE,25,0B,C7,AE,67,5F,D4,F0,57,C1,EF,6D,65,48,3C,D2,B1,D5,5A,03,5A,36,E7,40,DA,0D,7F,CF,1D,F9,FC,18,F7,0C,20,55,E8,2F,C3,DA,ED,27,CC,6C,7D,31,41,BD,96,E2,27,1D,8F,31,ED,BF,AB,44,79,1B,8D,7F,FE,BF,CA,08,7F,2F,C3,A8,33,9C,C5,42,4D,69,44,72,7F,41,C7,46,DD,C3,F1,6B,FD,FF,EE,6E,4E,DE,FC,1C,7A,C9,DD,DC,E3,F8,4A,ED,A1,C3,14,43,9E,6A,0D,2D,42,B7,9B,91,08,FB,B9,35,D0,04,4B,D7,E4,70,4F,D1,22,85,EB,32,FB,98,FF,4A,F2,3E,D5,47,88,59,F7,CA,F2,5C,E7,14,D7,6D,FD,9C,5A,17,2F,5F,68,A1,C0,FA,D9,55,16,A1,14,1B,80,3E,3C,DE,80,91,EB,DB,5C,09,6F,71,EF,23,40,BD,D9,47,37,33,51,68,58,F0,F0,78,F3,75,27,A1,6E,4E,32,F1,EB,F8,C6,22,6F,23,0D,45,E7,54,1C,FA,F1,60,11,0A,16,2B,16,B5,E8,21,A0,AF,5F,9F,50,11,73,41,CF,A4,39,00,29,9B,F0,47,A1,07,F0,2B,07,4C,CA,3E,04,73,BB,45,F9,37,15,AC,01,EF,80,55,9C,DF,E0,E7,13,D8,C4,4A,CB,68,62,D4,D2,51,D7,55,01,62,CA,60,DC,67,B4,80,F5,96,93,80,4E,18,19,28,B9,09,9C,FE,DC,49,0C,84,D5,55,72,65,57,F3,16,84,CD,6A,A9,A8,58,57,3A,AE,C3,B1,E8,0A,DF,02,C2,B7,2D,5C,0E,3B,AD,56,1B,44,75,66,CD,DB,F4,FB,91,80,35,D3,68,6F,23,2B,BC,22,39,AA,FE,59,1B,51,2E,6A,71,47,0F,31,A8,36,74,D6,6B,5F,CC,92,16,E9,0D,DA,F4,46,DF,32,87,E3,25,C3,08,86,37,A5,57,98,93,1C,DF,88,AE,2B,4D,21,5C,E1,DC,58,D2,AA,CB,53,40,1C,88,38,E6,B6,D4,8C,3F,67,2F,15,35,53,42,36,05,2E,DD,E5,E7,51,24,09,C5,D9,E3,71,B7,85,95,E2,1D,6D,8B,3B,71,AC,D6,2C,F7,10,4D,B0,FB,A8,6C,08,56,F5,80,D5,FE,3D,EB,30,EC,FE,00,91,E1,C3,5E,C1,DE,4F,50,CE,FB,48,0F,43,7F,EC,B9,39,6D,E9,20,C2,5E,D3,B9,04,CF,B5,2A,4D,73,1B,42,62,31,D3,9D,65,8B,D4,7D,A9,57,6D,51,A1,05,E3,7C,7D,28,3B,96,87,72,98,E9,53,27,37,3C,46,AE,90,4F,DE,D7,31,F7,64,1E,04,F5,74,A7,74,51,29,BC,8A,B0,67,39,D9,7D,83,9D,7A,2B,CF,BE,52,F5,A5,C1,D9,C3,76,CD,A2,4F,09,46,83,33,DF,D6,6B,87,D7,07,D8,FF,57,51,3A,21,8C,CC,DD,B7,89,D6,FF,B1,6B,D9,81,5C,0C,98,E1,FE,0E,96,82,8D,3E,C8,1B,C8,0E,E4,47,2B,9A,8C,9E,05,BF,E5,63,BE,43,53,49,33,4C,2B,8E,18,F0,5F,B5,DA,DD,BE,1A,45,91,28,65,C8,8D,6F,F7,93,8E,4C,56,4E,5B,6A,A4,6D,9F,1E,A8,22,C9,01,26,76,08,61,07,03,C3,C0,8D,00,67,E9,81,13,E4,69,B0,A9,C8,87,AB,45,53,3D,6A,98,BB,31,70,03,EA,85,DF,8F,8C,73,88,0E,89,2D,3C,61,77,2F,66,EF,99,5C,7A,71,50,91,55,85,1B,29,DD,84,BD,CD,17,C2,D0,2E,5D,A6,BE,5D,0B,2A,D2,D9,B6,CB,2F,A7,3D,DA,69,2E,A0,D1,B6,73,51,3C,8B,B6,5C,CB,58,A0,26,79,AD,C7,1B,C8,83,A1,BF,6F,20,BE,A2,F6,1B,60,6D,23,86,9C,42,D4,DF,37,FF,8F,B5,DC,DC,15,10,3B,82,BE,02,3E,05,F1,21,CF,65,B6,FD,E1,8D,EC,AF,CE,57,A6,18,6D,E2,51,F6,63,CB,AA,FC,6C,6E,6B,B7,BF,E8,AB,EA,4E,43,B7,DC,C2,73,B7,41,D1,65,EF,D0,C8,D4,35,07,20,27,A4,9B,4A,6C,FC,35,DE,ED,92,74,87,55,3B,F3,39,A8,42,42,8D,66,D3,A0,02,D9,02,6E,BA,C8,26,1A,96,83,99,87,44,F9,62,14,AE,43,CF,EC,07,99,2D,B4,10,AF,6D,4C,98,F6,83,A2,AF,AB,DB,B6,AA,45,67,67,63,60,FA,3F,5F,19,23,40,FB,40,27,A8,21,D5,2C,07,2F,1A,9E,07,17,D4,39,1F,53,42,5A,86,C9,C0,4D,9E,17,78,74,32,3A,A3,F2,37,FC,D2,E0,1D,13,B3,CE,B7,AD,C9,4B,C7,57,DA,91,34,57,CC,0D,B2,77,8D,28,2F,2E,0D,7A,E2,FA,D5,51,F8,55,15,F0,FE,01,76,D5,90,24,99,6C,17,EF,AB,95,E3,81,97,E4,D9,06,2D,88,9E,01,D7,E2,36,02,56,16,B1,47,A9,73,82,CC,57,B2,38,6E,B4,68,DA,01,56,DD,30,ED,C1,6C,4E,CD,60,7C,98,5E,8A,E2,28,A3,7C,2E,B2,98,22,9B,42,B2,ED,C3,1E,7A,0A,0E,9A,97,D5,F8,77,47,E7,D9,95,FC,4B,D0,3F,7F,B9,B5,8A,20,44,BA,D4,6F,8D,C6,23,58,8A,7D,82,E2,9A,20,AD,68,61,E1,CC,BA,A1,39,01,98,78,FA,3A,11,57,35,85,84,7B,02,39,72,8E,92,3C,7B,19,AC,6D,71,5A,CF,87,57,2F,10,81,4F,01,42,6B,C0,6B,C0,B0,0D,70,68,65,05,6D,2B,33,F9,9E,A9,83,EA,F9,EC,7B,26,3D,83,41,F6,FA,7A,D0,50,20,18,4C,98,0D,0F,72,F6,42,88,7E,C2,6D,7F,1B,D6,38,CB,D8,B1,51,93,B4,CE,02,25,DB,F6,26,0F,0C,EA,10,49,C3,89,98,33,C6,41,F5,92,18,18,B9,67,83,0A,ED,A4,74,8F,81,2C,23,DB,53,C2,59,25,67,56,27,E2,47,07,42,34,A9,ED,EA,D0,B2,01,D4,BD,74,A1,9B,62,EF,EC,24,75,F6,2E,81,17,A1,E4,0C,DC,A7,9F,E5,65,87,C7,DC,56,82,EF,3C,AC,90,48,38,DB,5F,A7,24,AD,26,BD,33,A9,B4,13,41,B8,D7,B2,A3,44,C5,50,56,3A,03,3D,6E,3F,47,4F,D5,CE,FF,1D,1F,4C,F3,54,1A,BC,C5,37,83,72,0C,A4,57,99,B3,D3,2B,31,74,94,27,A4,3D,20,AF,D4,5F,AA,3B,3A,0F,AD,5E,64,D2,BA,3C,ED,38,F0,C2,29,94,4A,B1,FB,92,A9,4D,B4,8C,08,4A,FF,91,0E,8C,9E,D2,14,83,7C,3D,5A,BD,21,F8,D4,B7,A4,C2,41,79,25,7B,D4,4B,82,85,3E,05,04,81,E9,76,11,96,07,A6,97,72,09,4B,17,86,E4,87,DB,72,9A,7F,67,AF,6E,42,6C,FE,12,C5,7D,9C,97,2C,0F,90,07,72,B3,ED,A0,49,61,58,B0,C7,EC,6D,73,E4,C3,23,AD,7F,04,75,86,B7,F0,19,B9,AE,8D,EF,22,9F,66,97,A2,89,87,12,E5,36,29,E3,1A,20,20,6C,C8,2C,8F,BD,01,AD,00,80,4D,B3,0C,3B,58,9F,0C,28,FE,B5,0A,95,2B,4D,62,58,73,8F,AF,D7,28,31,FB,D0,42,B7,F7,B6,FB,A4,5F,49,FF,96,C3,98,25,5B,5D,E8,A2,0B,0A,D8,ED,F7,D3,6D,59,AB,72,99,A8,B8,EC,B5,EF,F6,3B,95,12,65,26,8B,85,A1,6F,34,24,AB,B5,8A,62,BA,06,7C,93,FC,51,4F,A8,0A,06,70,DF,3D,97,BF,0C,2E,72,BB,0D,C6,02,CB,DF,76,F5,D6,00,6A,49,A1,55,B4,18,65,FE,27,12,9F,05,61,5D,9D,EF,A7,29,7F,D7,45,2A,C1,B7,A9,49,26,6C,32,9D,C5,1D,DB,81,5B,CF,5B,32,55,A1,CE,BF,F5,24,49,9D,B6,43,F8,74,D7,59,EA,8F,DD,FA,8C,38,DF,4D,FB,00,D9,62,23,92,D1,C4,9D,2C,95,BF,76,A0,F4,3B,30,82,46,AB,05,C4,EF,4F,8F,2E,71,B3,3F,08,B8,9D,83,AB,0A,71,38,CC,25,F2,24,59,65,0D,BB,4D,6D,69,16,97,EF,CE,CE,28,EF,AF,F6,A1,11,67,77,FF,EF,D8,A6,1C,C9,83,4E,EF,2F,09,D5,FB,4C,E7,16,D4,32,8E,19,A2,D8,9A,B0,8E,92,46,AC,17,42,83,A5,1D,81,7E,18,65,54,8E,73,EB,38,DF,4A,52,D9,82,2C,C9,B6,EF,7F,82,1A,F5,12,1C,93,A7,DC,85,86,0A,14,0F,50,4C,A0,1F,46,33,B1,B2,AC,15,B5,AF,12,77,37,C3,8B,E5,5A,A4,C3,9C,AA,DE,DD,75,1E,22,3C,82,C1,9E,EE,6C,51,64,55,4B,E4,F5,09,67,46,58,5E,30,5F,86,F7,38,BE,07,01,6A,F2,7A,7E,5F,5B,AA,28,C8,5E,DF,F9,66,A6,40,B2,18,35,35,AB,35,3C,96,58,B3,D5,01,4A,44,B1,67,22,4D,82,B8,D1,AB,BD,57,4B,6B,48,29,DC,97,33,A9,3F,E4,BA,72,97,7D,51,3D,AD,6C,70,40,48,2B,34,56,7D,DE,FC,A4,A3,7B,B0,A5,F8,CF,4E,D7,2E,33,15,56,EF,F5,14,D8,BC,B1,3D,C8,2E,FE,26,58,8B,54,B5,36,ED,A5,38,FA,78,AF,17,8F,98,57,4A,39,40,40,D6,00,6D,70,6C,A1,56,98,47,9F,81,7F,62,D6,78,EB,2B,A4,C5,7B,3E,28,BD,D2,D9,65,D5,DE,E0,7A,2B,F7,AE,79,9A,6E,3F,2D,64,C3,DE,39,53,69,6F,E0,5C,59,EC,CC,81,B7,9D,22,22,60,62,95,77,E0,98,97,AC,01,0E,6A,7A,C2,DE,13,4D,19,0E,B4,3E,27,35,3A,F2,6F,20,F1,07,8B,6F,48,B1,52,81,9D,03,4E,96,41,3A,B8,8E,A4,91,BB,78,CA,90,99,B2,A6,52,78,C7,A7,42,A4,8E,CF,91,E1,07,06,A8,9A,E4,4F,D9,E5,4F,C2,61,87,16,DD,4D,7B,83,87,F3,BE,71,72,C7,09,E3,41,AE,86,50,C0,96,47,FB,8D,8F,99,9B,77,AF,0D,3B,2F,D0,EF,C3,DF,CC,66,84,B6,87,77,06,7E,39,8C,2F,5D,3D,65,06,AC,B8,17,76,75,98,0C,7F,38,6F,FA,87,F8,CC,2C,94,E1,71,18,D6,8D,38,EC,84,4F,D7,ED,BD,9C,9A,A6,FA,1A,F5,E7,1F,99,1E,56,CD,3C,20,84,12,57,2F,E2,50,4E,76,9B,BC,B4,9C,E3,C2,2B,1E,AB,9F,D1,9B,52,F2,A6,84,7A,12,0F,35,04,2D,3F,78,79,AF,29,C5,91,5D,49,62,C3,E3,DD,56,72,67,84,92,FC,F2,E5,A9,89,61,C5,B9,A6,77,6D,5F,CD,36,E3,C6,5B,75,77,F1,9C,ED,BF,D4,B6,E6,B9,EA,48,D5,29,DF,B0,18,88,02,27,07,AB,4A,C0,7D,FB,C4,42,3D,93,9C,A7,FE,FF,26,64,44,F6,E6,58,5D,9B,08,CE,2C,18,51,D3,F6,BF,AF,68,80,02,53,19,B1,4A,BF,16,A3,0D,BA,78,D3,0B,EB,B5,F1,40,D7,68,86,A9,AB,5C,42,6B,AF,8D,8F,F3,C8,0F,7A,CB,0E,BC,2F,00,EE,81,91,B2,E3,14,EA,C7,0E,33,71,60,1E,17,C4,B5,67,74,D7,96,69,C4,CE,4D,C5,D2,C6,CD,B5,A4,0C,2C,48,5E,EF,A7,F7,B1,8F,66,BC,C0,3A,5E,81,37,53,43,1C,2F,23,98,F0,7B,FE,B1,7F,47,FF,87,78,EE,22,50,79,CC,07,D2,DF,5A,A4,63,76,5D,10,20,E1,1F,24,61,9F,5F,18,73,6E,79,10,5F,E9,9C,A4,B2,04,67,28,4D,2E,1D,BC,14,26,59,B3,1D,24,85,30,E4,79,D5,67,A8,BF,E3,54,FB,8D,0C,E5,73,26,45,03,42,99,3F,7F,CC,1D,2E,8A,3E,B4,1C,0A,1A,59,84,68,20,31,DF,7B,D7,91,05,77,D5,CF,C7,AB,32,72,FA,EA,A3,33,EC,14,39,1E,73,90,C9,13,EB,91,F1,22,83,07,01,62,D0,FB,E4,29,A7,22,C5,76,41,F5,14,9E,9C,34,C7,EF,B9,84,5A,81,A3,66,A0,00,0C,0B,18,8E,C7,C4,C2,99,05,F8,B8,E5,49,16,04,84,52,15,A8,BF,FD,71,DC,07,A6,5D,4C,31,D3,E9,88,1B,9C,35,3D,14,33,54,39,65,A8,1F,60,98,CB,5B,A7,22,F4,52,F2,AC,16,18,52,9A,B9,56,4D,23,FC,75,ED,88,43,15,2F,D6,E6,1A,C6,C1,C0,08,6D,03,C7,A9,EF,78,D3,17,B5,DA,DC,A7,39,D8,89,54,B1,22,61,0D,EB,A6,BB,B2,38,F2,5F,7C,97,59,5A,02,5F,7A,58,49,06,C1,E0,58,13,6C,31,33,FA,D3,94,5F,06,88,FE,5A,2D,69,22,88,61,65,D0,EB,23,AF,93,F8,D5,F7,23,7C,89,6D,F8,29,58,B9,00,21,0A,11,32,73,D6,BB,8C,C3,E2,BE,1E,5B,7A,1E,A4,2A,4D,86,C9,75,4B,39,91,07,C6,C2,F0,3A,0B,40,6E,D7,D0,4B,80,9E,AE,61,2E,66,41,E4,8E,5C,93,36,B7,AA,86,36,E5,45,BA,1E,E0,34,1C,4C,DA,69,54,30,14,95,74,FE,42,18,72,16,E2,0A,12,3A,EC,59,9F,AB,F7,CA,FA,36,85,DC,5D,BA,04,9F,80,DA,72,6A,DC,D4,64,60,51,21,27,AE,68,28,13,51,4B,4F,02,A3,42,B8,53,16,DE,DC,4C,86,70,D4,82,BC,72,5B,3A,D4,96,0C,F5,88,2A,02,A0,9E,32,95,D7,19,79,90,F2,4C,AD,A5,D0,58,BA,8A,F4,6B,1D,18,6A,0B,F4,C8,B3,65,25,81,03,3F,FE,F1,7A,49,46,C0,10,B7,DF,26,17,86,4E,DB,C9,36,67,1F,68,6D,AA,EA,0E,A4,DF,6C,D0,82,1D,D8,23,9B,CE,83,DC,2D,4D,73,4A,DD,AE,87,72,68,7B,EB,48,70,C5,A7,3D,33,5E,43,B6,34,9E,88,A9,29,A5,3D,B7,38,C8,E9,91,CD,CE,63,53,13,A1,3E,BC,C3,90,23,54,B7,FC,39,88,53,10,62,AD,A7,8A,28,C4,BE,CA,DB,C0,0B,A5,18,F1,38,FB,38,6B,20,B3,C0,80,AA,13,2E,8F,B4,A8,DF,26,5A,7F,8D,C0,95,E3,E8,18,15,09,3D,D1,BB,10,10,9A,10,1E,99,D0,24,31,4D,D8,61,F4,F9,F3,48,99,01,66,4C,04,8E,DB,F9,9C,73,33,94,1A,A5,92,AD,A4,2F,89,88,E1,5B,E8,07,CC,B7,8D,F2,E0,7D,F7,E4,CA,15,16,20,88,75,03,FF,80,F7,E7,F9,43,3D,67,A9,6E,0B,5E,F8,4B,7C,8F,0C,09,B2,71,ED,E5,57,47,36,52,4F,2E,B8,5C,AA,5B,BE,56,A5,37,C7,C2,9D,6C,25,DC,8B,6B,D3,F1,80,9E,A1,9C,6F,05,91,F2,CF,6B,14,11,00,7D,5D,86,3F,08,D5,32,09,52,58,76,E8,29,48,5E,BC,E3,F4,87,D7,6E,F7,1A,3A,52,76,06,BC,54,85,B8,0B,87,25,70,5F,B5,51,F0,CD,03,0E,87,24,FD,29,A3,01,B9,9E,F4,DD,F7,84,69,A7,49,0A,54,E7,63,49,64,60,04,CD,46,A8,28,88,69,83,36,6B,97,06,98,A1,93,9E,DF,23,8B,7C,39,99,66,B3,54,A9,1C,78,7B,E4,54,EB,D4,EA,BE,3D,E8,38,11,84,AB,F3,C2,ED,FB,04,F7,EA,8A,10,76,18,08,12,EB,0E,40,8B,5D,47,F2,56,5C,D5,64,EB,49,12,57,0B,20,D0,76,C6,E0,20,E3,87,1D,BD,0C,F1,82,93,6A,2C,E5,3A,E7,F7,57,0D,E7,86,85,C3,C4,17,A6,A2,F8,8C,03,E3,25,DE,AB,8E,32,F1,67,37,16,65,E7,F5,25,F8,D1,7F,0B,94,00,50,09,F5,2D,EC,3C,0A,20,69,C3,B6,3F,A8,C3,22,F5,AA,69,6A,1B,2C,57,00,92,44,FD,BF,30,26,01,04,33,7D,85,80,CB,33,43,1C,34,54,4A,94,F0,6C,5C,37,18,00,B0,F5,A3,17,0E,BA,EF,73,4A,A0,D9,CD,F6,0A,25,73,4A,C1,CA,64,99,91,04,5C,BB,18,02,23,04,CC,3D,F1,1F,AA,AC,CE,20,33,0E,9F,C7,31,A2,09,8A,D5,04,70,08,40,2D,4D,B5,40,50,68,E3,29,7E,61,E1,1E,D2,4E,95,CC,C9,93,C0,09,67,AB,90,17,DF,7B,11,37,5C,24,C0,29,FA,29,7C,CE,1B,32,B4,0B,99,7F,A6,CE,D9,22,80,BE,04,2D,A4,E3,45,0F,B9,52,80,52,15,64,97,CF,5E,58,AC,47,A3,91,13,0D,F5,AD,0D,13,F9,D4,80,C7,AA,14,EE,95,DB,23,71,95,E0,09,8C,CC,DC,00,BD,21,60,FA,CF,6A,C1,2B,22,78,D6,12,33,41,01,E2,4C,AD,B3,0E,EB,F4,DD,FD,15,A4,8B,E9,35,7F,2E,01,0B,15,13,DE,F7,F1,6C,25,02,AD,F8,18,69,AA,89,BC,76,E8,31,44,A4,DC,10,E8,8B,5F,28,31,48,07,B8,B6,AF,0D,26,62,93,92,7E,DA,C8,0B,47,F1,51,A5,6E,0B,F2,7B,D1,A4,DD,08,42,4F,08,01,A8,FD,6C,89,60,4A,AA,B2,62,8D,5E,5B,FE,CC,30,9C,E4,A3,54,A0,C0,96,CC,14,3E,90,C2,CA,C4,31,BB,A4,71,6E,10,A2,E9,74,B2,0F,60,E7,C8,00,4F,04,B9,2D,7A,CA,FC,5C,38,58,0F,E5,EA,66,0F,68,AB,72,B1,AD,3A,BD,5A,3D,BD,4C,42,90,7D,3C,03,70,11,91,53,EB,75,C0,C7,9A,E8,79,65,A5,59,67,F4,0A,2F,50,22,5C,51,BC,73,10,55,A6,49,BC,87,6C,AF,9E,9C,4A,12,7C,39,E3,94,2C,BB,55,0C,D9,92,BB,D1,50,CF,7C,5E,32,B3,AF,84,2C,28,11,37,62,62,53,80,E8,44,7D,C7,5F,DA,F9,C3,64,4B,42,DC,F1,3D,29,01,3D,9D,2E,F9,34,AA,AD,F0,FE,C0,52,C1,F5,5F,35,4D,3A,63,1F,40,F8,06,42,1C,EE,31,9B,E3,31,76,08,44,1A,C6,27,00,E4,BE,2C,7D,5E,DF,B3,63,08,A8,20,00,06,AC,50,32,F0,CD,86,A8,EA,54,53,3E,FD,FD,B7,20,D7,39,8E,CB,9C,6F,9F,DE,36,F1,4E,37,D9,22,9D,FC,99,4B,32,92,4F,21,F8,7B,63,8B,76,DA,8E,F4,27,FF,D3,F1,63,CA,6D,14,DA,68,CD,A7,A4,AE,40,D5,3C,47,67,6E,37,1B,B4,F9,4E,CF,77,C8,1D,CA,3C,C7,BA,EB,28,6D,76,72,10,9A,BB,41,2E,FA,E5,46,A3,DE,1C,CB,99,72,F5,57,28,C9,66,08,7F,BF,61,A9,79,BD,C2,1D,C0,CA,7D,61,41,A5,A0,5F,D8,A0,20,DE,DA,3F,65,36,79,68,32,F4,3C,6A,3F,49,1C,9D,87,58,C8,8D,EC,08,35,B5,CE,4A,A6,35,4A,74,F1,80,2F,F0,05,B0,A3,F6,6A,1B,ED,47,24,40,6F,AA,6C,79,7F,FF,7D,10,2D,D0,08,97,DE,DC,5E,E7,A1,42,15,69,15,F8,BB,58,F3,95,49,FE,0E,65,FB,B2,53,FA,D7,A1,A0,C9,DC,61,88,66,59,69,11,22,78,58,60,F3,F0,1F,42,D4,2D,F3,47,0C,45,20,74,53,A8,C4,22,32,8B,AC,F3,A3,E6,F9,70,36,B5,93,F6,BC,3E,CC,10,7F,08,30,16,1C,96,29,64,56,73,AD,FF,51,E0,52,D1,8C,30,67,B7,30,4D,D1,C1,80,98,CD,BF,F4,27,CA,DC,15,52,5D,24,05,23,91,C2,B3,B9,85,84,E6,D1,CA,AD,99,0A,F0,52,00,13,92,1B,F6,4D,47,56,EE,3A,3F,6C,2B,65,1D,8B,C4,6E,0B,13,1B,1A,02,34,1D,D1,08,3B,19,A6,07,2D,69,C5,36,2C,42,13,5A,77,58,35,2D,A1,71,77,6D,E2,93,47,40,44,3B,C1,82,31,E1,A6,69,32,FF,BA,22,7B,73,9C,CE,02,FC,A0,70,D4,B5,A0,18,90,36,E3,2D,31,D7,F9,08,7B,33,A1,2A,81,96,CC,3B,84,A8,04,65,4B,38,DA,87,E4,28,52,6D,31,BA,1F,25,40,CF,B5,9B,C3,B3,48,E0,C7,26,09,90,98,FE,FE,D1,AE,E0,F7,3C,7D,09,EE,C9,C6,F8,56,CA,18,4B,69,B6,69,BC,84,ED,A9,3F,72,8A,59,7A,02,82,0D,2E,CB,52,A0,AD,B0,3A,3A,5C,A1,FC,35,6E,5C,7A,AD,6D,C1,4B,AE,03,78,FB,67,65,10,A8,75,F3,6A,7F,13,92,A7,24,0C,D0,2F,E3,C5,7B,D5,61,FA,8A,4F,DC,6C,D2,4E,66,44,2E,8B,34,BC,1E,2F,49,5E,7C,57,DA,56,C3,73,17,6B,E6,E6,F2,FF,37,70,66,8D,D5,C4,C1,33,34,D6,BB,1E,F0,9B,B4,C9,CF,C3,92,D3,66,B9,62,3E,B3,7A,91,A7,D3,BA,92,5F,6C,EC,F8,7A,3B,AC,84,79,E4,C8,D2,76,FC,96,E8,D2,3A,77,CD,AE,7B,9E,D2,3B,75,1B,58,04,01,09,BF,60,C6,D1,E9,92,5E,54,07,74,C3,79,A8,BB,FC,16,E3,43,40,A8,6D,4A,B9,8F,3E,CD,1C,F5,4A,E2,E4,82,28,51,A2,38,F5,C2,2E,56,EC,0F,E9,6D,DD,8C,B0,81,16,11,6D,AD,B5,1F,5B,83,21,5A,89,D6,3B,D4,CF,2D,FE,2C,84,79,E8,3B,DF,B1,24,E4,A1,64,04,1C,13,C9,83,24,4A,4C,D2,3A,C0,B3,05,F7,73,6D,2B,20,AB,43,28,6B,AC,49,9C,22,A5,20,8E,27,21,3C,D0,8A,3A,47,AB,4F,8D,D8,C2,36,F5,98,89,CC,7E,EB,8A,44,1F,36,16,0C,DB,8B,C5,29,97,B2,48,51,C0,6F,D9,6E,3A,7C,D2,AC,60,14,A8,D5,97,3B,3D,D7,BF,6B,73,A6,59,D5,CE,0E,82,88,99,04,C5,AF,FA,5B,A9,98,3D,78,12,0E,09,0C,F0,12,82,A9,90,DD,FB,43,75,2C,7A,41,18,37,3C,29,F5,76,B6,7C,EB,62,46,AA,6F,32,6A,06,50,98,01,BD,A5,E6,5C,4C,CC,FD,F0,9A,FA,57,A5,82,6B,82,C5,45,EB,24,CA,78,DB,F6,6E,CF,18,41,A2,D9,70,83,21,BF,8A,66,C0,CB,9E,09,64,2C,9F,73,8C,F1,05,B7,9C,B1,84,05,9E,0E,A7,C3,05,FD,E4,77,74,EF,E1,92,61,ED,DD,61,0E,75,46,C4,46,C7,1A,62,FA,2F,C2,A8,1F,07,CE,EA,29,38,C6,52,24,32,92,20,12,81,F2,29,C2,AE,59,AF,BE,22,73,91,34,E1,5D,5F,81,E0,4D,73,A5,53,71,57,F9,7D,67,F6,58,43,29,9D,2D,0A,C3,85,D9,BE,85,49,23,DB,75,1B,37,DE,D9,D4,94,7D,C9,36,73,50,7F,67,EB,40,7C,89,5A,C0,4A,F4,10,B5,32,65,F9,B4,97,8B,17,F4,AD,DE,8F,CE,A1,64,AE,50,1E,03,34,10,6A,C7,AE,C6,C0,D4,D7,E4,04,FE,25,A7,92,0C,96,56,9B,6B,D0,85,5A,AE,C9,27,58,84,85,A1,89,54,A9,AF,EE,49,2F,BF,5A,0B,1C,E1,8E,DB,75,A4,BE,34,6B,30,DA,AF,B5,B9,26,E6,2B,D9,D6,95,A9,FB,A8,D2,19,AD,C2,E0,68,05,87,B2,9C,85,DD,18,9D,EF,5A,B4,0F,EE,38,1C,74,DB,CC,61,FB,75,87,F1,32,83,68,95,05,20,0D,A5,92,43,22,A7,A1,B0,FB,9F,A3,9E,2B,3D,B6,EE,9D,44,91,67,FC,E6,61,65,0C,F9,DF,61,1D,FB,B1,C4,A2,50,70,D4,84,F7,FD,24,DE,14,99,33,B2,FA,36,82,05,11,23,E7,B3,57,B3,0E,35,33,90,3C,D7,EB,D9,9E,55,63,CD,05,D2,14,0F,45,93,53,58,02,F6,AE,43,E7,33,B7,D3,70,43,26,ED,30,1A,3A,67,5E,DC,D1,8C,3E,B1,01,BE,72,F4,9E,55,67,09,13,C1,44,E0,C5,BF,ED,F0,12,D7,FE,AC,E4,0E,F0,B7,B7,09,86,7F,27,95,6F,EC,E4,F8,A7,89,3C,DF,D1,8A,A0,64,67,41,F4,E8,79,6B,A8,44,FE,80,C7,13,62,55,F7,D0,CE,4B,34,A7,A4,29,4A,98,CA,5E,0B,B9,F5,31,1A,3D,CB,07,96,34,77,6F,A0,6E,92,42,C4,86,CD,20,95,8F,57,C7,EE,9C,5C,C3,00,2D,B1,08,7C,35,24,57,D8,AD,06,3B,FA,08,C6,C9,DD,C8,28,3E,FF,46,A7,F6,F1,75,AA,BF,CC,59,A6,04,22,35,B0,3A,90,BE,7B,21,4A,B7,14,C1,69,2D,E6,FF,6B,53,6F,D7,92,7A,74,50,7F,ED,15,C9,16,F7,B9,C3,7F,C0,92,39,EF,DE,C8,15,03,32,1D,7F,F1,B8,D2,98,1B,0E,1C,BC,25,1E,B0,71,43,9C,FB,4B,17,F4,4D,3F,58,EA,33,1A,BF,13,41,13,A6,D1,C8,21,5E,0A,23,08,B9,6A,56,BC,4B,4F,B4,A8,45,9B,C0,F5,5D,04,5E,02,71,3A,49,A5,6A,8F,A3,22,B7,76,18,27,84,40,41,88,23,34,3B,F3,1F,1A,05,54,3F,CF,09,96,F5,41,A5,46,E9,94,4C,37,9A,B2,BB,18,41,4C,F2,C6,9D,09,32,9C,00,E0,96,B7,BC,B3,DC,DF,D3,4C,CF,AB,F0,3C,54,C9,CB,DF,C7,0F,08,03,10,3C,04,56,C0,EE,37,B5,18,C7,BE,3F,C8,A1,D8,2E,5D,E3,13,A6,AE,D7,A5,44,EC,85,09,18,2D,D3,8D,62,5C,F2,B8,9B,6A,BA,A5,3C,0D,8F,DD,60,68,74,47,FF,87,14,93,3C,F1,2F,67,A2,9A,93,5F,36,21,BC,7D,C1,5C,DE,55,4F,62,8E,67,BC,F6,2A,9F,FB,97,B0,57,B2,2C,AF,6D,1C,42,8B,A5,2C,94,E8,43,5A,61,5E,B9,11,92,1C,BE,B6,BB,5C,C0,D8,EB,09,78,2F,50,4D,32,68,01,62,6A,56,10,E1,65,90,1C,8D,04,01,C5,3D,F9,15,55,81,36,F1,0B,F0,3F,9B,FD,55,8C,A1,7B,1C,3E,C5,60,CB,CC,1C,07,31,41,65,56,99,ED,64,73,EE,3A,D9,2C,9C,01,57,B3,A5,58,D2,CE,9F,C1,5D,C9,88,47,5E,31,9D,18,05,5A,E5,E4,D1,61,41,AC,A1,02,BD,16,1B,F9,62,11,41,D6,E9,CD,6E,01,1D,0E,9B,A6,84,6D,2F,45,35,60,E8,4C,AD,62,9B,D8,C8,15,78,6F,11,EB,07,F1,EE,1A,0B,34,CA,23,B7,5F,A0,AF,3D,2D,7E,E2,38,2E,90,AC,17,A3,B1,EE,3B,A3,97,4D,0A,28,59,52,A7,6D,9D,E9,53,FB,F9,DD,F4,EC,9B,52,0B,D7,F5,A8,A4,A3,4F,A8,8E,87,18,B0,9B,3B,71,DE,E1,31,24,EE,8F,50,0F,5B,61,77,88,F5,A7,FF,CB,5D,79,48,3C,FF,50,36,41,42,2D,3A,1D,CE,FC,DD,95,54,FB,9C,60,FF,98,A8,02,E1,EC,4E,62,5E,8B,35,08,B0,36,FC,A8,26,B4,7F,BA,6F,48,88,90,02,23,72,FC,25,E2,CB,D0,AF,CF,F4,11,05,51,A9,F9,0D,E7,0E,81,4D,0E,C9,10,26,3E,48,87,66,AA,A7,B2,82,A0,5F,BB,94,25,4C,4F,1F,49,82,81,A9,10,1D,DE,DC,21,70,9C,6B,CD,32,4E,EA,41,5C,71,8A,E6,DD,FC,A6,57,4B,64,D7,20,14,AB,73,9D,B7,64,24,C7,ED,71,37,C0,0A,2E,86,E3,A7,A4,D5,A7,9D,33,A3,25,5F,3E,A3,BD,D2,86,D1,3B,77,65,3B,29,A3,2B,BD,5C,62,ED,27,B9,D2,D2,71,06,FC,BD,EC,3E,47,92,73,67,C4,05,A3,13,34,C1,84,30,FD,56,A4,1F,0B,27,62,57,1A,E5,7F,F4,1E,84,FF,F1,4A,34,C0,93,BF,F8,45,19,F4,51,13,12,25,76,65,87,AB,A4,36,5C,CF,58,6F,D8,7E,32,EB,03,09,CA,DD,B8,B2,69,91,7C,50,8F,21,9B,B6,7E,16,4D,37,4B,32,23,5F,B2,AD,41,F5,C8,00,65,F1,22,A3,08,13,23,40,EB,52,D2,BC,5F,2C,1D,10,EE,A7,46,65,99,57,65,58,BE,D8,57,79,EF,B3,C2,05,6A,FC,DF,16,D2,F8,67,56,F0,8A,E3,39,A1,1A,91,9C,C1,CF,EE,D1,05,E3,D3,8D,FB,7E,05,28,40,FE,00,8C,90,A7,82,FF,E7,76,3D,E5,7F,30,41,3A,F7,A3,15,C9,32,DA,33,A8,B1,45,9D,2D,0A,70,08,24,EC,58,51,B6,31,57,0E,78,A6,90,91,9C,AF,F7,41,54,E4,90,8E,E9,17,C8,A7,C7,51,AA,72,F1,B2,DC,D8,C1,57,A8,57,C5,EC,BF,05,E5,3C,AA,23,47,95,EF,5A,62,52,D3,41,CF,B4,2F,C0,E7,5C,9F,A5,9D,2B,14,DC,56,0E,87,10,DC,79,08,CB,22,14,59,9D,6E,EE,05,BF,A3,54,DF,FB,81,89,E4,F2,19,02,E3,D6,A2,F0,C1,08,74,59,29,01,2C,89,64,04,64,BE,6C,76,2C,14,24,4C,7D,2C,16,17,97,E7,3C,2D,8C,AE,B3,D3,9D,88,DC,C3,B7,0C,5B,0A,80,13,1E,27,CC,12,4D,BE,0A,9B,CA,00,1C,E2,3F,FE,A5,5A,2A,9F,85,E6,48,D5,6D,4E,50,79,CB,AE,B8,BF,BD,6D,88,56,7F,2B,74,AB,E3,2B,12,A0,80,92,06,64,02,9B,D1,22,FD,92,05,BA,72,19,A7,56,D1,1A,8B,F9,5C,26,81,E5,2E,A2,FF,FB,9F,4E,AF,86,33,5E,B7,EF,D8,A1,4A,F1,BC,1A,4C,09,09,9E,27,94,CD,31,D9,2E,62,C6,98,1F,43,26,2D,C5,8C,BE,4D,4F,19,9C,1F,3B,C2,7A,98,34,CE,73,24,8B,6A,EE,F0,A8,48,74,32,B9,BA,A9,D1,FF,E9,B2,BB,47,D5,D6,B4,2E,D0,2D,1E,FB,D8,E7,4C,BD,D7,C2,DD,10,CE,59,70,6B,21,22,28,54,11,5A,DB,46,BA,D8,2A,CB,8D,91,D4,FD,2C,6A,1B,88,8B,69,D7,09,CB,14,F0,8D,53,E4,0D,E7,E9,BA,41,27,00,00,4A,AB,E6,76,7C,DC,70,E7,6E,0A,3F,79,60,3A,18,B7,37,A7,0B,F1,23,C6,D2,1E,CE,40,4A,05,3A,1D,77,67,D2,94,4E,DA,84,58,8E,13,8E,7D,BA,AB,44,57,2B,F3,E9,90,50,B5,7C,E0,E5,50,82,B5,2C,8C,2A,FC,8F,47,89,FC,C4,23,B1,94,FC,58,6A,C3,39,42,1A,55,4C,FF,4B,99,84,81,8E,FF,D6,E6,6A,97,53,69,02,ED,33,B4,FA,D9,BA,AF,ED,1A,0E,E1,08,F4,F7,4B,E0,97,FC,16,B8,AB,03,4A,A9,64,FD,74,42,D2,A1,29,56,C0,AA,94,7C,B2,8F,3E,3C,D6,D3,4C,2D,56,0B,8A,42,61,D8,B7,FF,9F,AF,DA,8E,92,F5,41,99,23,AB,3E,AB,5C,C5,0F,A7,F0,80,EB,B0,24,5C,C5,48,02,6B,BF,6C,38,95,86,02,75,FA,FA,2B,70,4D,6E,B6,98,04,2F,B4,05,12,29,06,3D,88,B8,54,1A,E9,02,D5,4B,C1,50,8F,88,DD,CC,BD,76,69,FD,C9,5C,60,5B,2B,71,84,E5,1B,F7,74,52,E0,14,81,CB,40,68,FA,C7,94,F0,B0,96,DB,41,20,4E,0F,86,84,24,4E,90,8E,3E,45,CA,AF,D4,C3,32,36,82,64,7A,41,E2,BC,7E,73,3A,57,16,A6,DE,33,7B,E5,03,3F,DD,E0,51,FF,69,01,69,63,F8,15,BD,9F,F5,54,6C,D6,6C,CA,DD,98,D0,82,5F,5A,48,81,C1,80,4E,24,BF,28,EF,37,BA,61,FF,A5,F6,73,A0,0A,00,FC,8A,A3,86,92,87,DC,55,9B,34,D1,87,AA,35,EB,A6,32,1C,AC,1E,AE,AC,02,26,FF,D4,7C,1D,29,69,9D,29,A8,AC,34,C3,0E,02,61,F7,E4,D7,C1,0A,6A,B1,DB,0F,2C,94,09,13,29,CC,69,BB,C8,9F,03,82,96,E2,EE,2E,87,A3,F0,0A,CA,6C,B0,1C,70,EC,05,A9,34,20,12,23,BE,D8,EC,1F,46,F6,57,84,F1,AE,91,3D,55,F3,D3,D2,84,0A,B0,50,FA,AA,CC,83,FC,B4,79,7E,77,64,EA,8B,38,DA,D4,F3,DF,25,BC,44,FE,8D,FE,BB,3C,42,4C,65,CA,26,4F,25,31,01,0A,5E,1C,AF,44,F1,3D,00,BA,B0,D1,E1,99,F6,ED,1D,F6,07,0E,80,8D,7D,53,C4,1E,14,88,9A,AC,1C,B2,51,F8,31,54,5E,83,E6,4E,E8,55,E7,0E,BE,70,57,F0,F3,FB,FF,25,1D,72,A2,2C,12,87,F0,C1,15,E8,01,C3,14,84,90,AC,D0,AC,74,92,C4,2B,F0,AF,38,D3,BD,92,5D,8D,13,E7,BD,4C,8A,31,B6,5B,42,07,4F,1A,9E,E2,A4,68,87,5C,DC,02,02,57,41,76,4A,09,21,42,59,0A,17,82,5B,0B,0A,41,B8,49,11,07,2C,04,0A,53,D6,BD,8A,76,44,B1,1B,C4,EB,40,52,FF,9B,81,4E,20,F6,46,7F,00,C0,A7,1C,B7,FB,3D,71,1D,92,98,C9,14,40,F2,12,F8,31,8C,AA,92,5F,96,57,6A,7C,47,AD,4E,EB,72,52,7A,4C,BA,8F,F1,95,EF,CC,F8,18,C7,A0,52,90,84,B9,A1,BE,AB,38,79,20,F1,D4,74,89,54,9C,B4,42,6B,E4,D6,E8,33,BA,E8,51,2B,A5,51,36,20,D3,AC,78,C2,3B,6D,C8,A2,FC,40,92,EE,38,6D,0C,9B,C4,E5,47,63,2B,BE,56,9F,84,6D,91,08,42,0E,D3,D7,B1,2A,90,21,78,2B,2A,A5,79,31,EF,CE,02,BC,90,97,E5,AF,AD,E4,EC,08,DB,8D,1B,D0,32,30,0A,0A,D3,78,39,CA,0C,3D,DE,A8,C4,27,6F,C0,8A,49,70,A1,B5,87,8F,FF,EF,6A,9E,AD,B1,FC,E2,BA,56,58,DB,6B,24,04,A0,7F,33,93,5B,36,D1,7C,C3,F4,2F,23,A2,A2,23,D4,0B,5B,22,9C,10,A2,F4,02,D6,24,93,38,76,65,33,69,9F,5A,61,96,F2,7B,9C,50,A4,44,3C,9A,96,0A,42,9C,E5,1E,2A,2D,63,A6,A9,C1,C0,5F,38,AD,DE,23,2F,2A,DE,3D,F6,5F,95,76,40,43,54,A5,83,C3,82,88,87,02,1F,8C,5A,74,59,08,12,7C,38,03,C0,8D,FF,BF,D2,16,2E,84,03,38,87,C7,94,8E,CE,34,F6,B0,51,2D,BE,26,2D,60,8B,A1,94,8F,E9,49,3A,4B,27,54,D7,22,10,C4,71,B9,FB,83,B4,DB,46,11,03,00,15,88,97,57,A5,C8,6C,3C,C3,20,68,FC,0E,8D,CE,0F,F0,8B,83,E8,3F,F7,09,1E,3F,0F,A0,CD,F3,3C,E3,21,04,B4,09,4F,5A,D0,28,DE,18,11,FD,7C,C6,9C,77,99,5C,34,8F,66,2B,95,B3,01,45,16,8E,3E,3A,06,09,14,F4,A7,9A,D8,B1,6E,32,9D,86,D0,53,EA,16,1A,70,62,F3,CC,2B,6B,0C,1C,29,F5,ED,C0,4E,D5,03,03,A8,67,8D,8A,60,4D,29,E3,63,4A,64,F4,73,E2,AF,48,57,46,AE,3E,13,E0,B6,54,A8,70,B9,45,C2,5B,E7,89,EF,29,8F,A8,26,B9,C4,EF,5C,B3,41,58,66,90,D8,36,63,7F,F3,5C,28,9D,2D,76,1C,FE,67,59,39,1A,B7,9F,C5,F7,53,D0,E1,60,22,B4,11,41,2F,C3,17,59,FE,2B,7F,53,A7,20,23,65,88,C1,55,3F,70,8E,22,31,9E,AE,A7,90,10,51,35,01,43,AD,79,80,D9,57,0B,EC,7D,12,E6,13,49,A2,A3,F5,1B,6C,AF,B0,BE,2A,17,45,B0,8D,D9,63,58,B5,60,25,2E,BD,B4,DC,EA,22,39,AA,C6,51,1F,CF,25,29,50,D4,C4,D4,94,D8,5F,5C,F5,FC,4C,99,EC,2D,CC,B8,07,B8,59,43,9F,B7,A8,D2,18,79,6B,EB,84,76,29,03,ED,F7,A4,DC,05,4C,0C,8A,FF,FB,B4,52,D1,5E,93,8E,5E,F3,63,D7,95,40,CC,C0,E9,2B,47,50,65,D8,C6,7B,1E,8B,96,7B,5F,D8,C3,91,E6,49,C5,21,8C,3B,72,DB,96,9A,AA,32,43,1C,D1,A9,14,32,1B,50,FF,A9,D4,58,AE,50,C9,77,D7,32,45,C0,4D,57,FF,65,97,3A,73,78,BA,7F,67,2A,A6,E2,B3,E5,DF,36,94,A7,BA,7F,23,42,22,CA,12,27,1F,DD,06,9D,E3,5F,7E,17,12,10,10,A2,FC,BA,57,7C,EA,18,60,8B,BF,65,A3,95,F9,74,AD,FF,8A,1A,13,92,8D,7C,2D,56,6D,0F,F0,20,D2,8A,B4,F5,37,A1,93,98,3A,8F,50,1A,9A,7C,9C,A3,11,E3,AF,77,0C,E6,99,78,73,81,08,03,88,99,2E,95,BF,2C,FD,B1,60,2F,2E,68,FB,CE,48,75,0C,14,DD,B4,AC,54,27,6B,E9,E4,85,1B,6E,61,C7,51,89,D1,5F,73,94,8B,64,0E,66,A1,F3,DE,14,99,CB,FB,D1,8A,D7,CF,50,06,77,3B,A7,A4,D2,D5,42,FF,1B,3E,F9,F3,DD,98,3C,8C,7A,90,CB,6C,9A,D0,9A,AF,0D,8E,AA,8F,35,8C,FD,B3,8A,FE,1A,5C,7A,58,9A,B9,D4,57,E8,CE,D2,77,BC,BA,6D,FC,77,0B,61,2A,E3,C0,32,E4,62,E7,C0,83,74,11,0F,AB,7C,38,52,F2,E8,09,D6,3F,F1,96,0F,3B,5F,29,E9,3B,70,8F,B0,B2,E6,58,D2,34,BD,2A,61,EC,75,40,F9,29,60,7F,F2,F5,0F,61,2A,FE,B7,A3,1D,B0,2F,47,20,8F,B1,F2,70,90,21,F8,5B,B1,60,7C,3C,F9,C0,4D,0A,C3,C6,F6,BB,64,E9,C8,11,40,F7,D4,68,51,22,8F,08,E1,8B,EE,A3,DD,57,D9,24,01,75,64,FB,20,C5,0A,07,69,33,F7,81,66,6A,B9,E6,9F,AC,5B,6A,B9,1A,FA,FB,AA,6C,79,1D,71,C3,9A,5D,66,B2,74,15,42,E3,86,5E,F3,A0,06,58,94,D8,AC,19,70,B2,E4,A8,F3,87,65,34,3D,44,FD,EB,86,92,C0,F5,12,BD,BF,E5,05,19,BA,4D,82,01,54,39,D3,FC,34,90,22,8A,CF,70,95,1A,B4,1C,97,1D,BC,C8,7B,84,91,E8,1B,03,ED,03,0D,29,A1,66,C1,53,F2,12,32,B4,16,B9,41,34,C2,26,B2,83,31,DC,0F,BA,B8,34,82,29,5A,D8,8B,B9,44,90,76,33,0C,C3,76,98,F3,0A,A6,CA,91,00,7E,FD,A4,DD,08,69,BE,64,53,BB,49,A4,53,8D,9F,6B,0D,C5,9E,D9,61,4B,80,DA,18,47,DA,8F,22,C0,A4,8F,21,C4,63,8D,E7,FD,FC,BF,F1,28,F5,4A,23,C3,12,26,8D,A3,04,2F,73,43,51,CB,D4,0D,FD,C1,B4,06,C1,A7,FE,C9,04,A6,73,76,AA,D5,B8,AE,4C,CD,9C,F2,8D,A0,B4,E1,2B,40,9D,BD,B1,8B,FF,CD,86,37,C0,B4,D4,AE,74,D8,0F,B2,BA,A6,AA,A5,B9,07,13,60,45,AA,CB,07,46,99,78,BD,9C,FA,26,F8,6E,A8,7F,1D,E8,A9,5A,70,6F,85,7B,42,92,CE,FC,AF,46,FE,C5,68,72,1D,E9,E6,26,55,3E,44,79,66,B9,5C,41,C8,88,6F,DF,B6,B0,04,49,71,D3,05,3E,9B,43,7A,1A,FC,7F,A6,EF,F3,E3,E5,EC,C8,F3,C7,DD,A0,F4,BE,08,F0,AE,9E,6D,82,3C,E2,36,B0,AB,AC,DE,8A,AC,AA,69,45,38,54,13,A4,9F,5A,27,AD,F5,6E,FA,D0,EC,66,94,1A,16,06,F4,87,3F,97,7A,12,A7,8A,C8,CB,6B,C0,40,4E,53,F0,80,89,80,C6,5D,61,4A,EB,3E,F8,8C,2F,83,33,E8,5D,3E,01,62,18,15,B2,CF,C9,EB,8B,1A,50,94,B2,B2,2E,FA,5C,12,65,DF,9E,0B,7B,AB,69,D2,FA,E9,1B,2E,1A,53,3B,FA,76,E8,D8,39,A9,9A,A7,4E,41,BB,BB,E9,78,CE,4A,03,1C,46,CA,18,83,38,28,19,AF,8A,3E,F8,AC,DD,A8,D3,24,51,08,27,8D,A6,49,4A,70,CB,C6,33,AD,8E,C8,66,81,8B,B0,95,81,45,23,38,0D,74,E2,07,94,82,E0,8F,C4,71,CC,81,84,EE,59,B6,C0,DC,D5,79,F3,2E,60,BF,2C,45,62,18,D0,76,7C,9D,56,78,D1,49,3E,1C,03,75,DA,EC,0A,4A,20,4B,F3,9F,78,37,4D,D8,D3,08,40,AA,34,D6,4E,AA,7C,91,E4,BC,83,7C,B8,09,F1,F3,EA,35,5D,3B,7B,D0,6B,1B,F6,BC,94,48,0C,00,44,D5,62,6F,D4,71,FD,6C,BA,CB,7F,40,C9,F8,97,AD,FF,8B,B1,00,2C,CD,4F,6E,E1,09,78,BB,61,14,80,F7,EC,34,90,5A,FA,B5,78,34,17,B9,49,30,D5,05,25,80,1D,AB,F6,D0,4C,29,AA,0F,61,BD,64,95,15,85,00,FA,E1,FF,3D,BF,65,C5,BC,18,B2,FF,E8,7D,31,86,67,55,13,78,8C,9E,D7,3B,C3,97,BA,20,C4,79,47,85,CD,89,5D,E6,30,D5,D1,2D,67,3A,D5,74,D0,05,C7,A8,1A,55,D1,F5,74,FA,EF,97,1C,6B,82,C9,31,3A,E5,BB,C1,13,66,6B,35,A9,E4,D9,15,EE,99,20,A4,C6,DF,F0,0A,D3,62,C9,C9,7F,14,C9,6D,10,48,5D,63,F2,4C,C0,48,EE,24,89,22,E8,1B,43,08,5D,C0,06,97,61,3A,32,F8,55,61,8D,91,52,A6,60,E2,9D,2C,D9,1A,B2,E9,0C,C2,06,E0,FF,65,C7,1D,5D,99,9F,AF,58,BD,1C,A4,4C,37,5D,80,D2,52,B0,48,61,0A,8E,F3,03,0A,81,E4,15,14,B9,77,2B,46,AA,0E,54,5F,74,CC,7A,76,48,6C,5E,DC,92,2E,52,80,2E,16,82,0B,3F,1F,04,2E,1B,62,F1,03,0B,DF,7B,4A,15,DE,1D,CE,8F,BC,87,B5,71,37,31,97,A6,08,06,FA,CF,AD,CC,88,4D,9B,D3,4E,82,EB,D0,45,C1,17,CE,BF,59,EE,FA,0E,F6,7F,78,FD,55,18,D5,46,E1,6E,0C,39,A9,7C,33,46,7B,F2,2E,F9,66,AE,F8,7A,DF,FD,B4,85,22,09,AC,DC,EA,D7,AA,91,EA,1C,39,70,15,22,69,48,3F,69,0D,CC,D1,88,C7,B9,11,E1,B1,6C,2D,07,24,8E,C8,68,58,F9,AC,23,38,0F,0B,AF,A8,8D,20,1F,87,5D,F7,D4,B1,A3,63,A0,EA,09,BF,35,AC,4A,03,AC,54,24,E2,63,28,0A,CB,22,76,3B,43,7D,A0,73,4F,ED,89,2E,A9,1E,D7,65,55,D3,44,23,C1,71,5B,D6,CF,8B,83,00,3F,4E,CA,F8,05,16,EB,CE,A2,2D,4B,A7,92,1F,68,D2,D0,EA,B1,5C,48,D6,BF,D2,BC,85,41,04,85,60,07,F6,CD,A5,F7,6E,6A,A3,93,A8,96,AB,E3,B7,4A,F1,B8,B9,56,70,B6,F7,24,09,4E,A4,CD,E7,C2,B9,7B,DC,8B,44,6D,FD,F0,4E,3A,D8,60,2E,C8,0D,36,8A,B7,B6,EB,B0,D0,65,E8,25,43,3F,DE,11,3C,22,A3,7C,99,8B,3E,DC,8B,D8,78,3A,78,CE,C8,85,3C,D8,A5,F1,22,1E,DF,0C,CF,7B,07,00,BC,65,59,DF,18,65,C9,EE,31,F5,77,DA,9F,47,8C,EA,39,1F,AA,BD,A3,D4,21,4D,90,5A,32,23,12,07,05,7C,B2,FC,DF,05,B8,56,10,16,66,0C,2B,85,08,61,E5,89,4F,B2,04,C1,2F,80,AA,34,AD,9C,DB,A9,B6,EB,C1,3A,AF,24,A5,36,61,3B,E3,22,C1,5A,8B,55,97,F7,52,21,9B,AD,87,1B,2B,76,CF,9B,50,C7,27,4D,E2,EC,9F,FF,75,1B,63,4F,0C,21,EB,B0,1E,6B,CA,5E,48,77,AE,0C,FB,7D,89,A4,B9,F0,CD,11,76,F1,33,93,69,44,68,62,3C,A1,DD,82,9D,75,93,6B,FD,4F,D2,8D,48,52,D4,7E,32,C8,04,0F,85,96,29,E4,D1,5C,E7,D9,82,FE,77,FB,DB,14,77,38,4F,69,06,9B,48,A1,06,C2,99,DD,99,C3,E3,F3,90,0B,35,9A,14,2F,AB,07,A4,DE,DF,72,E3,B5,F8,D9,5A,14,63,86,1B,5D,92,02,C0,53,6B,24,CF,16,F5,44,8A,4A,C9,23,0F,43,79,DF,63,85,BC,6F,04,32,CA,B4,FC,E4,7F,FF,99,71,02,F9,D3,DA,0A,37,40,2A,73,9C,8B,27,56,FB,6C,4A,38,77,9F,D9,60,24,41,A9,A5,E7,C1,B4,6B,34,7A,3F,8F,3B,4A,CC,FE,A4,09,91,BD,0B,8C,EF,14,B0,1F,D6,C0,16,EF,00,FA,C4,4D,0E,DA,7D,DD,05,53,87,AF,8D,5E,2F,33,2D,FD,B1,09,07,A4,E1,7A,2A,99,5E,7F,87,7D,9B,CF,81,27,10,A8,C8,9E,17,4C,80,2A,16,A0,EF,17,B1,98,0F,B4,E1,3F,E4,61,66,DE,ED,0D,B1,2D,D2,CE,6E,CA,D9,32,EA,AB,D1,9D,32,D9,C9,D5,65,80,05,7A,BA,5E,4B,F9,4C,3C,D5,73,BE,58,28,08,46,D0,45,39,DD,2E,EC,6E,CE,05,FB,BB,0D,8C,6C,37,06,DE,DA,FD,C5,F7,D0,31,C8,88,EC,72,F0,B6,9A,87,7E,34,24,14,A1,CD,CC,AB,BC,65,CE,A4,BA,64,B3,45,05,4C,0A,DB,33,D8,B8,E1,92,4D,C1,86,CB,F2,6C,3C,4E,EE,D1,64,80,F4,D3,C2,97,7F,BD,0E,4A,AE,50,B3,39,8C,31,79,2E,2C,D1,26,BD,EC,6E,E7,1F,27,95,0A,82,8F,5E,D5,95,A9,2E,CD,66,12,6A,DA,7E,52,25,59,79,73,D1,83,15,E0,70,4D,C3,4A,3D,01,C7,23,DB,F1,55,FA,62,2E,E9,4D,BC,72,C0,31,18,C7,13,62,E9,7E,80,8A,2D,38,09,DB,0E,C9,81,63,8B,25,82,2D,7F,F9,67,EB,1E,76,A2,36,29,A1,68,9C,AF,AF,CA,04,58,FE,64,E6,8E,18,45,AF,6E,4C,C4,1C,58,4B,0B,1E,E8,6A,1C,8E,0C,26,6B,86,E8,9C,2A,BF,44,31,7A,6C,24,2A,EF,66,CB,45,D5,EC,15,C5,10,40,A3,41,4F,5A,FB,69,F8,F3,5F,A9,EF,1C,24,EE,89,3E,83,F6,E9,D9,83,54,4A,46,06,22,10,E5,12,75,F4,64,58,37,29,C7,9F,46,F6,B8,11,05,67,FB,4E,11,BD,64,AE,5C,B3,E0,36,13,2F,84,5C,72,0A,8B,6F,96,DF,2A,74,54,80,E7,B9,06,D4,2B,52,74,30,D2,2C,38,3B,04,4B,0C,9E,EB,34,B3,8B,BD,D7,C1,E0,93,2A,51,50,16,F7,29,C9,95,E8,8B,F4,17,A9,02,28,96,0F,14,84,87,F2,D9,3B,4C,2D,CC,47,71,89,7F,C6,55,61,73,9A,5D,9B,06,CC,F9,0F,15,9D,40,63,33,AB,C7,88,FF,45,D8,0D,38,1C,DC,D0,72,12,53,F1,3A,BF,1F,D4,3E,B7,5E,D7,74,DC,2C,B0,4D,37,74,CA,5B,4B,00,B1,34,EC,DB,F7,F7,D9,0D,0C,4C,27,47,50,8D,1F,67,46,25,CA,E8,C7,17,54,BF,D2,E3,08,5F,EE,98,7F,52,3F,79,D2,99,D4,BF,78,AE,1E,B8,A9,07,16,94,D9,62,AD,7A,8B,8A,92,9A,10,3E,02,33,1B,01,33,D4,F2,4D,46,56,DD,D2,7C,76,F3,D5,F5,56,DB,2D,C2,A7,C7,56,3E,5F,22,7B,7F,41,11,4C,8A,59,7B,8A,8E,75,A8,CF,10,CF,FA,C6,4F,08,F7,53,FD,DA,71,AD,A1,40,78,34,02,BC,D0,34,CA,EE,00,70,89,56,07,A0,8A,1C,33,9A,67,28,AC,14,23,DF,26,94,2B,A9,00,D7,3A,98,56,70,21,51,B1,D2,22,C4,E5,92,1D,11,CA,B6,DA,3A,79,04,A2,D0,6F,60,B1,03,BF,77,34,F5,DB,A4,E3,06,AD,EB,BE,51,F2,2E,09,6F,9A,BE,68,FF,37,53,D5,95,C6,C4,E7,00,41,EF,E4,F2,1B,9E,6A,2F,2B,27,B7,8B,35,2B,40,73,D3,39,3E,EB,88,57,D2,F4,50,A7,AA,95,8B,04,BB,CA,BA,35,9D,E5,85,38,E6,8E,6B,68,F4,AB,C0,36,4A,B6,F0,F2,BD,A7,31,FB,B8,7C,AA,42,27,8F,05,73,D4,1A,DF,C8,33,6F,3F,27,3B,C0,D1,1A,C6,A7,9D,6C,0D,BB,20,30,2F,00,A5,04,7B,EF,E9,E9,4D,82,5A,1D,15,7B,4D,CD,83,C6,01,03,31,86,19,0F,DA,9A,BA,53,DF,0D,F9,AF,E0,47,9E,34,E1,28,17,98,71,C6,F6,F6,73,D0,A8,08,F6,50,83,17,4D,1A,3B,4B,0B,63,98,CF,2C,08,60,79,73,5D,64,F8,95,47,EC,42,E1,B8,92,F4,3B,42,95,A0,9C,5A,BA,6E,80,50,88,3C,31,05,68,76,4D,6B,81,12,C0,44,FE,4E,6F,F1,1B,9D,24,C0,1D,AF,48,64,EE,D5,0E,10,89,B6,CD,12,59,50,12,2E,D5,CE,94,DC,98,D4,D6,AA,A2,A4,72,5B,D2,0C,E3,37,AB,38,72,42,CC,A5,BB,EC,7D,B1,24,34,17,AF,B8,EC,FB,CE,07,B1,6A,E7,14,63,B1,98,AD,B2,B6,F9,59,94,F5,06,32,18,FD,67,53,F4,BB,24,14,03,C1,3A,58,F8,EC,3D,4F,D0,BC,B0,E4,4B,81,C3,CA,30,F0,21,77,47,EC,8B,DB,65,12,E1,C1,A3,51,07,AB,99,44,86,21,F1,29,5B,26,7B,5D,0B,B6,4D,F4,F8,9B,03,BE,B3,A7,2B,C2,1A,17,1F,40,B1,C4,F2,2E,88,1B,38,CF,FF,A3,55,88,B4,8B,33,7A,55,68,10,0D,07,3A,48,0D,AB,DF,BD,E7,CD,8F,13,71,70,C5,3A,61,70,95,5D,CF,5D,B0,F4,21,F0,02,1D,87,A5,D4,60,8C,F2,6A,18,52,71,3B,97,6C,1E,F3,05,E7,C0,F8,A0,49,5D,F1,B9,8B,E8,95,DD,CA,11,1E,8D,76,66,61,25,D2,88,F8,C6,DE,97,38,6C,2F,AE,24,DA,E1,0A,8A,A1,98,8F,EA,90,B7,1C,3F,04,EF,DA,45,55,89,49,FE,79,7C,FA,A8,C0,62,67,4B,59,2D,0E,EB,5A,87,CA,D4,E6,91,E3,AC,7F,FB,F0,66,11,E0,68,86,E1,FA,FF,4E,CA,C7,1B,6A,15,96,5E,A1,4E,A0,24,A8,93,B4,F8,C0,96,37,A1,B9,3D,75,4D,B1,B4,44,EE,BB,5A,E7,C7,70,70,99,DB,B9,45,1F,22,86,08,F0,42,85,CF,89,04,3A,E7,0A,F8,BD,5A,4C,7D,C1,95,BA,D7,91,73,46,27,75,FE,58,E5,A7,A1,4E,AA,84,41,8D,D1,CB,AE,E5,83,20,8D,FD,AD,C5,CA,D9,83,D9,83,89,05,52,9B,92,AC,DD,2D,C1,01,69,B6,CE,86,E8,F3,DD,A0,53,04,B8,75,3F,65,8A,FA,27,53,67,8E,6D,7D,D6,AF,B1,1E,A4,AC,7D,62,18,34,25,D5,E3,28,21,E6,1B,02,0B,71,73,CA,7C,ED,9A,15,2F,5F,B1,9E,B1,45,14,02,FC,8B,BA,4C,73,8F,9E,00,04,31,3C,39,A7,7D,02,3E,2C,A0,4E,C6,6C,3A,16,8C,89,D7,BC,83,7A,51,46,10,EF,AD,47,38,FE,D1,76,D6,14,8A,85,D1,6D,C1,0C,05,D8,68,DF,3A,28,3F,DF,F7,3D,E4,DD,A2,0B,F4,DF,8E,2F,4F,6F,17,C4,DA,47,6A,FA,85,69,B3,0F,01,5E,3A,D6,2E,B6,3B,20,BD,3D,A8,B9,44,90,C0,8D,D4,9F,BE,EB,86,E5,BE,36,C0,BF,7B,D5,CA,4F,FD,6D,88,9D,E6,B6,4B,2F,B6,11,F1,28,CA,2E,85,A7,03,A7,15,4D,83,9C,CC,6B,8E,42,DC,87,3B,54,8C,EA,E0,3A,6D,3A,53,F6,49,3E,63,BC,97,9E,70,B4,E2,BB,5B,91,5C,10,1F,88,AE,7B,3A,6F,99,92,45,72,84,4A,C0,57,E1,BE,91,55,F3,DD,4F,47,70,F2,1F,0C,13,2F,AB,A9,ED,F3,EC,58,98,DA,6C,67,24,01,AE,B4,C6,E9,F8,EA,6E,A7,0E,51,DC,9C,37,60,5A,0F,E6,F7,B3,3C,0F,AE,CE,10,4C,6D,65,F8,3E,91,AB,61,17,41,01,B3,3B,05,07,07,56,9B,D1,EE,A9,6E,14,F2,A4,18,63,CB,98,85,1F,84,2C,B6,C2,8E,6B,08,7A,24,19,51,C4,94,16,B4,CC,BF,43,B4,A7,90,83,6C,CB,84,33,03,69,2C,FE,8A,71,F5,39,95,4A,01,DA,67,DC,1E,2F,1A,0B,DC,98,1E,1E,D5,9A,44,1E,0F,DB,01,26,31,AB,8D,CF,49,0D,BC,40,E3,B9,6C,DC,8B,D6,6A,5E,4C,71,1A,E2,C0,82,6C,6B,5B,AD,B2,1C,E0,F5,46,F3,22,89,BE,E9,DF,10,84,1D,ED,E1,C9,36,ED,C4,D0,46,BD,AC,5A,34,72,5B,63,E3,EC,29,B1,EB,5B,36,D9,79,E5,34,3A,8C,99,29,8D,67,BE,3B,2A,38,6B,9D,45,59,60,5B,9E,BB,AB,9A,4A,AB,48,50,AC,69,D8,79,86,B6,E6,59,BC,C4,65,9D,20,BB,55,BD,21,03,71,3A,8D,DC,BB,C8,05,AE,2D,6E,C2,AC,79,75,FB,E3,39,4E,FF,61,D5,61,D7,73,C0,22,AC,BA,EE,D0,49,56,8B,22,92,30,8F,EB,33,0D,D4,96,54,DE,DE,63,9B,F5,E3,72,F8,0C,66,08,C6,AD,2A,29,7A,A0,8E,C3,CD,7A,E5,F3,54,A8,04,62,D6,30,41,80,1B,37,DB,10,BF,22,4E,D5,EF,02,85,A9,CB,1F,AD,63,99,1A,49,41,52,F5,1F,C7,A1,BA,AA,E1,F0,3B,93,E4,95,B4,64,98,F6,70,2F,53,96,FC,7F,22,B6,8D,D7,67,5D,53,34,09,F4,D3,93,E9,2F,88,EA,DD,D5,86,AD,5D,E7,50,88,C9,7E,F4,EA,D0,B4,A5,65,48,33,82,A2,B9,96,96,7C,BD,B3,A0,CE,19,93,78,BB,61,F4,CC,A4,26,61,49,B4,3B,3D,CB,B5,2A,E0,C8,2F,AB,82,D9,DA,63,F8,A6,6A,C6,FF,84,ED,3F,A9,C0,42,A3,EC,33,E0,9B,03,B0,8B,A0,5F,5D,A6,0E,D1,9D,18,9A,DD,E6,5A,0B,FE,62,84,E4,ED,3C,94,35,20,D0,E5,FD,C7,C2,0B,5E,BD,19,D0,23,2E,3C,88,2E,28,4C,29,32,04,33,75,9A,58,8D,55,4B,1C,AC,31,58,0A,B5,5A,FA,15,90,10,1E,58,32,D1,90,04,77,6E,25,9D,0E,5E,DB,CC,51,A3,4A,A7,00,26,A6,67,49,80,B8,45,7B,72,E6,8C,EA,9D,24,C2,36,07,9F,E4,63,9B,0D,88,63,33,32,75,0E,6F,C4,58,28,F2,0F,95,AA,F9,38,44,B1,BC,EF,C5,78,DC,CA,B3,31,20,5D,11,0C,23,F6,4B,E4,5A,00,05,8A,7E,F3,B3,AA,CF,D4,2C,7C,49,5D,BF,C2,BD,DF,86,D3,17,E6,41,EB,B4,D0,3A,CA,95,41,E7,AB,83,66,D3,00,73,15,48,33,E3,A7,78,5B,CA,13,BF,11,D6,DE,30,2B,A6,66,5A,5D,AA,06,B8,52,7C,CC,88,25,C8,DA,39,EB,D9,B4,D9,E1,A9,CF,2A,F4,0C,25,44,4D,76,A5,7C,51,43,08,03,65,1E,0F,8F,18,90,25,2B,4F,D9,27,2F,CF,76,A8,4D,C1,DD,82,57,A6,EC,1F,D5,F9,24,86,91,B5,7F,6A,9B,34,07,41,18,BE,EE,EC,86,1F,83,6A,68,9A,F4,4D,6B,25,6B,A5,DF,DF,E2,DB,FC,C5,39,81,69,46,C7,19,0E,EB,D8,6A,55,1E,F4,B5,84,12,36,FB,95,30,44,88,73,BA,86,9D,D9,0B,DC,2A,38,AD,20,D9,2C,9B,08,8F,66,8C,18,17,6B,AA,2C,9B,38,1F,57,A2,84,58,B2,22,05,A4,E0,B5,0F,7B,C8,5E,3C,8C,3B,36,4A,5A,0E,99,C9,76,D9,9A,7C,03,F5,6D,6D,FC,4C,88,11,74,07,26,82,F2,20,E5,3C,CF,68,E9,06,E9,CD,C0,4F,3A,D9,A3,BD,D8,58,0F,E6,BC,77,25,F8,83,DC,AB,A7,D9,14,95,3B,DB,E8,F7,B1,2C,37,C9,94,1D,59,34,B5,D7,92,0E,6C,8F,BB,67,22,43,8D,1D,96,9D,0C,6F,C3,E5,03,29,BC,69,AD,8C,33,41,B6,38,71,0A,7E,63,FA,A8,2E,8A,58,AF,6F,A0,E5,78,7C,28,6F,BC,9F,71,38,F6,E0,4D,2A,A5,23,D9,30,83,31,CF,A4,C0,EB,27,FC,52,99,03,D2,12,AD,82,80,8D,89,A6,B6,10,B1,A5,3D,E0,3C,AC,AE,80,D2,57,F1,2E,7F,86,EA,9D,21,A9,DC,8F,86,57,CF,17,11,CA,65,A5,4F,CA,9E,1D,80,6B,DA,07,E0,88,5D,D3,1E,26,19,B8,EB,69,FD,9E,74,0E,23,5F,1A,FB,1D,38,6E,C7,C0,B2,95,29,9C,03,9B,9D,DA,1B,1B,1F,4D,DD,F3,58,B9,C2,39,4D,73,EA,A3,58,0F,FA,DE,49,19,55,C2,80,38,A3,9D,82,51,72,D3,EC,A7,54,2C,0D,A6,56,EC,26,57,E5,1E,50,7C,E7,E9,80,39,E6,4F,C4,B1,F8,38,98,49,0D,BB,22,AA,4A,96,E3,75,07,9C,8F,93,13,00,AF,43,63,4E,41,DD,8C,A7,A0,A5,0F,57,ED,63,6B,20,9B,6E,DE,A6,60,37,FD,CE,81,AE,DE,DB,83,31,90,89,6F,79,D3,0B,B5,6F,90,21,77,8E,01,F8,AD,CB,FD,18,9E,09,DB,A4,96,84,1E,97,1F,40,D3,BB,A7,C4,98,F6,B8,E6,1D,3F,72,11,6C,EB,01,8A,04,10,01,9E,01,E4,2F,7D,B5,A4,9A,44,86,EC,53,13,9D,7C,F7,44,CA,72,C9,7B,C0,4B,D3,6D,F6,E0,14,E4,F8,B0,5F,57,9B,C7,33,B3,3C,15,65,B6,81,AB,CC,E3,65,C3,EE,78,DB,69,16,69,84,F1,13,4B,C5,6C,54,AE,70,38,EA,77,C7,93,A2,47,78,11,71,7C,83,E4,64,E9,49,B7,44,AE,4C,32,D8,07,02,94,FB,79,67,C1,41,25,3F,17,86,68,6E,EE,1B,D3,94,D3,95,BE,FA,7A,A8,B9,AC,C4,35,10,36,A7,37,37,85,F7,A5,73,1A,A1,44,BC,4C,82,99,F0,BE,4E,30,02,4F,95,61,98,02,AD,2C,C5,1C,90,4D,A8,A3,61,1C,6C,7D,F0,A3,7B,60,48,1C,8E,F8,10,B0,B1,16,F7,85,75,AE,34,C3,52,2E,8E,C7,07,64,82,0C,5C,E9,D1,86,9C,BD,51,ED,45,F9,B6,B1,5F,BB,61,48,04,9E,63,D3,2F,EF,BD,0A,26,55,33,81,91,3F,89,34,3B,CD,6A,48,CD,DF,70,74,23,EF,32,D0,F9,54,40,43,C2,5D,2A,61,9A,3A,F0,63,8D,BF,8E,41,3A,A7,9E,59,AE,13,5B,FC,A3,8B,C0,B8,B6,D4,E4,4E,56,16,93,B9,39,8E,13,FD,CC,38,A8,25,97,2C,28,EB,5A,C7,1C,74,0F,2F,3C,5C,43,43,EC,0D,C3,EB,7C,18,FC,B6,72,11,05,CB,97,C9,CA,7F,00,1D,CE,78,C2,32,12,85,E7,BB,F2,60,D6,75,89,0A,E1,BB,B5,91,32,9A,34,6D,A3,81,C5,70,38,D2,97,46,7E,CF,9C,F1,C6,B4,30,69,9A,E4,2B,22,76,A7,CD,5B,B3,2D,5C,53,33,6E,D5,BB,30,AC,D5,C5,CB,D5,8C,CF,B4,09,3D,42,00,26,FE,79,21,FD,98,87,E2,6C,B1,78,50,4F,4E,9B,16,0E,A7,2E,C7,27,86,88,99,25,7C,36,06,D0,F1,5C,33,56,1A,A2,74,BB,C4,EF,B2,1F,22,EF,1E,4B,1C,75,06,59,10,63,BF,A9,3E,76,06,30,9E,84,A0,E3,53,CB,AF,33,AF,B5,04,07,E0,AC,37,2A,E0,0C,77,1B,95,D7,1C,9C,89,19,04,44,DC,4D,85,1A,C1,4D,B0,05,9A,0E,5E,F1,40,2E,EE,B0,25,C8,D4,8D,DE,5E,95,66,AC,13,9B,CE,61,62,4D,5D,08,5B,2E,46,92,AC,44,25,6B,EB,31,0C,74,D7,34,80,70,DD,41,CD,E3,C5,16,91,18,0C,79,B7,58,F4,F0,89,6C,AE,42,70,55,3E,56,82,E0,FB,2F,6C,DB,45,64,01,3E,3A,86,52,DF,6D,14,83,53,08,C2,70,33,98,DD,46,1C,68,FC,68,57,2E,D9,9A,51,20,B2,D8,10,B0,A2,B1,DB,C7,DE,6C,94,F7,B3,1F,7C,3B,DC,9F,B1,20,A0,4C,15,52,66,A6,B6,C7,B5,9C,4A,38,CD,9B,0B,76,BA,64,47,F9,99,D3,1A,CC,5D,53,5E,64,42,5A,0A,CC,4C,A8,2D,6C,13,5E,43,A4,DE,50,3C,1A,55,FB,90,5A,30,F0,DE,0C,BB,E5,9E,D3,7D,AA,91,10,19,67,C3,9E,2D,BE,EF,59,12,02,ED,65,78,FD,DA,A1,C1,7B,89,75,86,BD,12,45,93,E6,80,F9,12,86,1F,9B,52,E4,35,30,C1,7B,36,9A,F8,0B,5F,58,96,6D,78,77,DA,1D,4B,A0,83,79,F4,90,5A,6C,BE,8F,00,59,0B,DE,CE,F3,ED,98,1B,64,66,1A,E3,BB,24,13,CD,B0,D0,84,EE,12,9F,63,67,32,40,81,45,27,74,AA,4C,1B,0A,7A,DD,E8,50,B1,76,D2,42,97,33,6A,19,46,95,AB,9A,0B,BF,32,30,B3,F9,89,E4,1B,D4,D9,0A,A0,4B,EB,6A,D6,A8,59,9B,20,46,FB,B8,1F,59,19,B6,1D,90,76,42,0B,A3,D4,3A,B3,87,10,1B,7C,E6,AB,23,2B,AD,FF,9C,38,A2,C0,2A,18,DF,52,D5,A3,7C,00,43,0B,A2,64,91,66,F3,04,40,F1,03,DC,4E,21,31,E6,F9,33,11,07,57,44,9A,73,60,E9,88,37,B5,10,BA,4B,72,AA,CE,8A,EB,A8,E6,0A,5D,8E,ED,17,56,69,51,F6,B6,57,AD,36,FD,7F,23,53,E2,39,45,2D,81,D2,28,8F,C0,55,A7,D1,C3,A8,3C,BD,78,AD,6A,AB,6B,2C,BA,E1,AE,3B,C0,DD,2E,AD,AC,05,E7,A5,E4,AA,F6,34,F5,D2,E0,60,24,DC,20,4B,D3,84,BE,9D,8E,C5,5D,60,AF,9E,CD,DE,A3,DB,53,C3,E3,AC,D3,37,1E,C8,8E,34,F6,A7,BE,1E,C3,25,34,3E,63,5D,DC,77,25,A6,1C,2B,D5,41,FE,08,A3,44,58,42,AA,03,F3,F3,7D,B2,97,18,95,9F,B2,C8,18,B3,0C,F2,94,4F,1E,E9,01,6A,1F,12,97,9A,F7,35,F8,7F,B9,30,BC,AF,E9,3B,0E,79,28,F2,25,68,9A,F3,C3,BC,90,5C,0E,66,40,AE,C7,7A,94,2C,BA,75,7A,63,24,4D,68,A5,F5,AA,DD,D8,6F,3D,AE,60,5A,FA,A9,38,9F,54,1E,08,97,1E,62,40,03,21,F8,96,1E,88,4D,47,55,F9,8D,98,18,2F,98,5A,13,B5,30,01,8B,32,3A,07,9E,29,DF,6B,12,03,D8,8A,D7,4D,E9,C5,AA,7D,DB,B0,3E,53,76,A7,20,40,05,D7,C3,03,47,E7,02,DF,47,FA,3C,24,A6,23,5B,AA,D7,D3,08,90,21,D3,59,C5,E9,F7,1B,82,1A,19,5C,26,66,95,A2,05,41,2B,E0,08,61,C1,7B,DB,66,BD,EC,B3,FB,3E,2F,33,84,E1,6E,5A,36,80,91,A4,F2,99,E6,08,93,2C,8F,ED,AC,87,8C,2C,0B,66,FF,8A,66,86,E6,61,F9,2E,20,B1,43,21,81,6D,24,F5,DC,AD,A5,E9,1A,61,C1,7C,65,23,9B,A8,0E,4A,51,1E,26,08,CC,8A,B2,15,81,39,A1,A3,FB,E8,C3,7E,FE,9D,A0,3C,A6,62,9F,01,FD,D0,E2,45,35,7B,23,19,9F,3F,66,D3,21,E9,3E,52,01,D6,3E,DA,E1,FF,9A,CC,8C,96,54,2D,C4,D3,C1,ED,F6,FF,B8,5C,60,81,3D,E1,50,53,85,5B,20,B4,6B,82,63,C1,A1,DF,74,F5,47,E0,A0,EB,D6,83,BD,35,61,8A,37,F4,38,B6,F0,AA,0C,68,2A,53,AE,D6,79,C0,98,D8,23,05,65,11,32,8C,10,3E,8D,C9,D3,52,E2,AB,35,8C,09,08,C0,AE,FE,07,48,42,E1,6B,5A,0A,9D,9C,54,D6,D4,B9,20,C2,61,91,78,6B,E0,E4,4F,21,3A,74,BD,1A,6F,AF,8D,ED,88,A1,C0,3D,34,F7,B9,E6,37,6F,75,9B,91,55,85,40,8E,1B,51,69,6D,83,BA,19,C3,7F,12,1A,0E,B5,E3,8F,83,44,4F,EF,8B,C3,58,25,13,0A,9D,9F,3D,1E,42,57,C6,1D,ED,ED,ED,69,4C,BC,A5,87,47,D6,E0,B7,E7,BD,55,97,6C,D0,48,22,65,5E,03,30,81,AD,FF,60,B6,E0,15,70,29,B4,E2,6A,D6,FC,A1,23,A8,0E,E1,E9,5C,FC,CF,0B,D1,6E,8C,FA,3C,A6,77,59,C0,6F,D2,8B,46,CE,1F,D9,75,54,A5,6C,07,B4,48,9B,F7,84,7A,72,3E,6B,4F,BC,09,24,BB,8A,DE,4A,F8,D4,74,3B,BF,80,5D,37,92,99,4B,A8,A2,A2,16,20,B7,84,BC,4B,57,8B,D8,7F,26,7A,D5,9E,D4,F0,67,BC,61,9D,83,A7,87,58,C8,2D,D9,93,C7,5E,D5,BB,4F,22,2F,C4,F5,72,79,1D,A3,C9,D1,98,DC,27,46,72,80,8B,9F,F9,E6,E9,8D,96,83,50,25,3F,A5,C0,9F,C7,D1,8B,41,00,01,5E,8C,C2,6F,7E,EB,3B,AB,16,3A,5F,3D,7D,4B,12,8A,ED,AE,E7,18,44,87,27,AE,22,96,7F,87,C0,5B,CA,83,8C,75,EA,64,74,0B,19,F5,B2,02,C3,F4,2C,F2,87,89,B3,F3,AE,78,4B,4B,9E,C1,A9,44,F7,25,1C,26,1F,45,54,70,68,CE,0E,BD,A3,6E,F4,57,5C,BC,6A,41,A5,61,AA,D7,2E,2D,0E,AB,9E,87,08,7C,80,64,BB,4E,3F,1B,2B,11,09,57,40,75,67,F7,91,8F,73,7E,5F,84,6A,D7,F1,BF,81,BB,C1,02,19,ED,82,B3,28,11,07,E8,45,1B,41,13,BC,88,C9,83,EE,85,23,2D,0C,C3,6C,B0,25,F2,BD,30,B9,87,A1,81,32,69,D9,B0,C7,D2,77,76,4A,AF,9E,5E,E5,78,79,E7,5A,00,E6,F8,6A,A8,91,69,42,A3,E4,12,52,16,54,21,59,AA,26,3E,7E,5C,3D,91,82,4C,76,21,88,28,A9,8B,40,2C,1A,19,73,29,5E,B9,2A,1E,6A,70,7D,63,84,8C,5A,77,01,B2,80,61,63,88,B1,9D,2E,89,60,5B,F8,9E,45,C1,09,16,67,04,1C,3F,0B,EE,2B,38,45,67,DA,41,1B,07,72,C6,B6,81,67,C5,EC,09,49,C1,A8,A2,EE,87,08,B0,06,D6,46,EC,56,93,8A,DB,EF,0B,BE,DE,0C,DF,38,B5,67,A3,3D,3F,0D,25,74,63,8C,B9,C2,9E,E5,F8,DD,79,A7,95,32,68,62,EC,3E,73,87,BF,66,0F,2A,4C,83,B7,B5,BE,50,3C,FF,BB,A7,C9,6A,6B,BB,BC,2A,26,C4,D5,37,89,CB,F2,CF,83,2A,9C,BB,6B,73,2D,08,9C,71,2C,91,49,2C,79,80,32,1F,67,68,65,5E,A6,A5,BE,67,BD,DD,F1,62,9B,C4,89,05,05,54,08,9E,3E,E0,64,04,A4,7A,FA,B7,9A,96,A9,18,77,14,E6,16,AF,69,49,9E,1C,42,DE,13,54,F3,B2,EA,BC,F3,66,AD,B5,B4,64,09,A0,AF,6A,A3,90,3B,D9,C4,D4,A3,51,07,AF,46,01,BB,64,15,81,51,0A,6E,70,14,F2,F7,6B,69,6F,D5,D3,93,A0,C0,FE,38,48,10,57,D3,48,97,2D,3E,E1,A0,DF,4D,DF,62,12,25,62,A1,70,93,5D,D5,90,3E,31,B7,6E,2B,6D,42,BC,23,F6,CA,7D,AF,F8,8F,6F,4A,35,28,9F,F2,F8,00,51,13,D2,CE,B3,D1,B7,37,0D,67,28,51,35,24,A5,D1,D6,2D,59,74,99,64,5B,12,C3,BF,B1,40,E3,D5,4D,82,18,56,21,8D,0C,CB,C8,48,22,D9,E4,ED,CC,BA,08,C7,CF,53,67,FD,3C,D1,FE,5A,8A,15,FA,B9,8F,CC,1B,70,AA,EA,11,9D,7F,19,EB,45,AE,62,48,85,2D,F0,57,5F,E2,4A,0B,39,7F,55,B0,A0,E5,C3,AE,1F,E1,01,4C,F4,FA,32,AC,B4,56,2E,C1,54,6F,0D,1E,48,CA,6D,76,AE,70,9D,56,75,47,81,D7,DB,8D,DA,78,34,AC,6C,B1,F2,4F,1F,94,C2,88,8C,F4,40,E0,ED,8F,99,F8,39,4C,EF,42,E3,4E,AE,1A,2C,81,F4,C8,F8,A9,8D,A5,E1,D8,A1,17,FA,17,60,16,05,A9,60,DF,9F,63,BC,06,CF,F5,D0,9E,EB,D9,74,B1,29,2C,61,06,57,D7,5C,78,E5,69,D2,70,8B,4E,D9,07,ED,F5,33,89,7C,96,C6,E3,C4,30,93,03,62,3B,E9,8B,19,38,09,01,0A,9B,39,0F,55,6C,96,9D,9F,43,C0,37,7A,35,32,F3,F1,AF,1A,7C,FE,2F,AE,F5,67,58,4E,84,40,15,06,17,8C,55,E6,70,EB,78,3E,32,FD,57,9D,06,49,D0,D3,4D,1D,F2,C8,3F,93,19,D0,33,CD,6A,E7,9B,E8,16,84,54,C3,02,65,2D,3D,3A,CB,E3,5E,04,56,D0,95,2A,9B,AF,BA,7D,E1,4B,93,FE,60,0F,72,08,56,0A,F4,92,91,C0,08,D2,19,9C,C1,9E,DE,C2,0D,88,DF,A5,E4,98,03,6B,48,41,CC,76,23,3B,D2,7C,A5,24,1F,D1,DD,61,08,12,A9,30,3F,30,7F,C9,E7,21,50,98,3F,2F,77,68,6F,33,E6,30,95,E8,81,AE,1E,E1,8C,1B,98,DF,A3,04,6B,FD,82,AC,63,8B,6E,05,13,10,D2,3B,A4,A7,3A,58,D7,7B,A9,18,51,2E,AD,1C,18,B5,EE,F2,8D,F3,5F,75,7C,D7,D7,6B,B9,2A,89,79,8E,D5,6F,8C,FF,34,9E,34,8A,72,9C,12,43,71,DA,5D,67,BE,48,BD,6E,C0,91,EB,8D,07,EA,8B,FB,A2,59,7E,E1,95,A5,DF,D8,91,F2,B7,B9,D3,C8,F4,31,78,E6,E1,4B,A3,79,D9,E8,6F,FB,33,66,E5,60,C3,EA,98,80,4E,85,6A,2E,F3,F5,96,FB,88,CE,57,E8,D9,22,BF,E1,6F,8E,A6,3C,6A,1B,C7,9F,0B,F1,F3,37,D5,23,2D,24,A3,B6,90,FA,9C,45,0F,2C,2D,EB,56,05,5D,13,C4,B8,75,29,6E,F1,C0,47,E9,1B,1F,76,A2,31,61,41,5C,43,DF,E8,37,30,2D,74,B2,41,C0,81,8B,E9,23,0A,0A,5E,0E,2A,5A,E2,C3,45,59,2F,5C,AA,21,1E,44,F2,F9,77,97,11,F0,D7,F3,20,D8,46,9D,17,01,E9,4F,73,F5,01,67,0D,3E,93,0D,75,E2,69,44,2E,A3,FA,A5,E1,57,80,23,3A,4A,54,D3,7A,8F,0D,F2,C8,2E,C1,13,9F,32,9E,87,42,38,3B,FB,47,44,FB,E4,C6,40,75,A4,68,D7,33,7A,50,E8,4F,08,C3,CC,81,DB,48,04,83,D7,E5,F1,41,50,B1,E2,A0,6E,BB,7F,93,0B,1B,83,68,4F,0B,20,53,9E,02,C5,06,E0,AE,A1,6D,AE,D5,8C,0C,E0,A1,76,A1,44,F6,CA,DF,7E,5F,0D,E2,88,CD,22,04,CD,DD,B0,29,84,E9,99,E2,D6,CF,3A,C9,4A,49,78,E6,97,48,C8,33,CA,0E,5D,CE,39,E6,AE,46,CE,4E,86,48,50,54,E8,62,22,74,33,DB,19,3A,33,FC,5E,36,92,89,59,E1,2E,AA,FA,97,7E,DD,97,AB,5C,7A,55,7E,1D,3A,9B,69,4B,7D,6E,BF,40,CD,24,1C,9C,E1,2B,BE,30,28,31,34,BA,EB,7D,F3,6B,65,8C,58,B9,CF,43,9F,DB,6A,15,F0,EA,01,62,55,70,E4,EB,D4,B9,E8,18,DB,0C,E6,82,44,18,05,86,D9,3C,5A,A3,A5,75,2C,08,94,FD,BE,BF,27,0E,0C,33,25,50,FF,C9,94,30,9D,65,00,49,24,3D,79,80,69,01,3B,5F,96,5B,9C,40,BB,6A,A7,2F,FA,72,45,C2,C9,B3,8E,64,AD,B5,02,F1,D2,FA,0A,0C,99,9E,93,8E,66,75,F6,C6,CF,78,EF,DF,50,59,C6,0A,79,A6,29,36,C0,F5,BE,04,D0,1E,BF,C8,07,BB,84,C1,EB,1E,8B,4A,3E,0E,18,41,AA,5A,72,96,30,A5,60,D8,16,67,54,E2,EC,6D,EC,1F,C1,1E,60,F8,C4,30,45,D6,E5,AC,DF,30,9C,96,13,DE,1B,8E,85,4A,AC,2C,BD,D1,13,06,76,FB,AA,E0,FA,F1,80,CA,DD,98,DA,4B,82,E9,ED,0A,34,06,3A,7C,66,F0,55,3A,BD,3C,7A,50,EB,D5,16,B1,AB,67,6C,34,B4,E0,4E,44,E8,A3,9A,9D,FD,DD,B7,32,58,DF,74,0C,77,20,74,A1,59,3B,55,4D,6F,CA,B9,BC,05,3A,C3,50,60,AD,A9,B7,88,D0,47,4E,3D,CC,8D,C5,26,91,06,77,06,C4,3E,2D,B9,5A,9B,39,71,DE,C5,B3,EE,49,0B,D8,07,CE,D6,D1,EE,74,C4,9F,25,24,9D,43,B4,B1,B0,1E,39,66,6A,34,0D,84,6F,4A,1C,34,37,C6,B3,F8,2F,97,DA,04,C7,1D,AE,D0,18,46,DC,7D,B8,7E,C7,D2,CC,B2,7D,0A,9F,D2,D0,B6,1D,8F,11,48,5A,E4,13,79,11,A6,0B,C2,7C,89,21,99,17,BB,72,E6,6A,E2,BD,F2,F2,91,5C,63,83,79,0E,1A,7D,C8,6E,DB,8A,4F,E4,53,EE,FD,0B,5E,79,C3,E2,EF,B0,50,50,E7,83,84,D2,4F,61,F2,73,E6,4A,CF,58,3C,CE,9F,5D,03,80,AE,6D,B0,71,66,AD,3F,52,EE,8D,EC,3C,DC,91,F5,58,AA,A8,EF,A7,4B,2E,02,3F,D3,9C,6B,13,CB,3D,57,F8,76,67,FD,A0,43,70,07,50,02,AF,F2,A1,DF,DF,48,FF,1A,F5,90,82,8A,C4,94,E7,8B,B9,99,D1,5B,15,79,75,2B,50,C2,52,12,33,C2,C6,E2,14,AF,AE,E1,C6,1A,DA,7B,DF,07,75,7A,DC,6B,BF,9A,D3,23,DF,48,FA,83,EB,37,99,DE,11,4D,CF,BE,A0,9C,33,70,1D,9A,A5,7E,40,90,75,93,70,E9,58,30,FD,60,B8,A7,7E,D4,E6,DF,3B,51,FD,64,CC,1B,87,FD,CD,DB,D2,8C,EF,7D,E6,46,1C,65,02,DE,0F,26,C8,92,15,39,9E,7F,80,E6,60,34,23,49,54,4C,F0,41,8C,3C,26,6B,75,78,48,3A,8B,C3,FB,69,06,D9,38,6E,26,2C,14,D7,2A,28,98,CE,95,2D,E1,F7,8B,D1,DD,CF,1A,62,5F,A8,53,7C,93,66,1A,9F,11,21,C9,8E,A5,82,AB,2F,99,40,85,51,02,BD,94,E2,73,55,A0,D4,2C,74,0B,83,CE,71,F3,7D,EA,FF,B5,C3,B6,1E,7A,AE,6D,8E,EB,50,45,FA,6D,7D,4F,BB,0C,0D,66,28,04,81,F2,12,23,E7,90,75,E8,83,BC,2E,4B,01,DB,7B,76,84,18,43,D8,77,B1,2E,B5,56,62,05,68,E8,1B,28,42,1F,E3,79,45,3B,62,BF,6E,71,27,EA,B5,DE,3A,3F,55,A9,74,BF,E7,0E,0F,61,86,E6,96,1F,0A,E8,C9,24,32,6C,47,10,9A,5D,CF,0F,92,AF,CA,9C,E7,12,7C,B8,1A,A8,E6,7A,50,21,A8,62,47,DA,A9,3C,CB,AE,A4,B5,97,36,97,79,82,DB,82,49,72,51,B8,0B,44,EC,01,B2,96,1F,F7,4D,61,87,3A,26,2F,8A,DB,30,4D,C0,B6,88,6F,3F,77,30,E0,43,6E,7C,48,DE,7C,82,5B,AF,58,F0,58,80,A6,60,BC,C6,B9,DE,DF,21,8D,93,A9,C8,DF,33,FB,EF,AB,F1,46,16,D3,93,3F,38,C5,73,FA,0B,4E,F7,02,C7,2C,A0,97,97,53,AA,1B,B2,2D,32,B5,B1,1E,65,E0,DB,18,5B,56,CF,C0,1B,FF,FB,43,6D,DA,3B,52,32,AE,65,DF,5C,1E,D7,C5,E5,8A,8F,CD,1D,81,39,45,58,A0,48,FD,02,E9,23,4B,DB,95,ED,A1,5B,01,56,B7,8E,64,B5,E3,17,0D,C0,93,33,E4,8E,1C,60,5D,62,B3,D2,75,45,D5,E5,9D,45,54,14,1D,C8,89,A9,52,81,5B,FB,A9,32,0F,EE,B2,16,44,CE,28,7C,3A,7A,7D,A5,33,DA,82,6A,5A,6D,EE,9E,76,D4,F4,DD,6A,B4,4C,9C,6B,00,C2,7B,C7,E5,53,C2,FB,8E,49,48,3A,93,22,A0,82,AC,77,74,2F,21,D6,0D,66,7F,C2,72,A8,F3,EC,0B,AC,CF,2C,3F,A4,2F,98,27,23,67,9A,51,4F,35,90,B6,FF,80,56,26,74,21,26,36,F1,2C,99,A9,46,5F,EC,6A,0F,D4,24,B8,49,41,40,C7,6C,18,8A,BB,EC,E7,B9,95,AE,83,6C,75,F4,D4,84,43,10,99,47,6E,7D,A1,C3,13,3E,82,94,22,CB,83,63,B1,33,75,38,D0,DB,0B,94,29,BE,91,1B,9D,E6,EE,9D,5B,18,3E,14,6D,ED,FA,3C,43,5C,5A,74,0B,6F,D1,72,48,B5,B0,97,7F,95,58,B5,33,DF,5A,57,B3,EB,5B,3F,F0,D8,31,43,6F,5F,D4,A4,69,E8,7E,E9,52,AF,E1,F7,F2,7F,0C,D2,AA,5E,23,56,1B,D0,45,7A,CE,8D,A6,2F,C9,29,52,0D,E6,20,D0,98,D9,45,E7,80,82,3B,6D,F4,D3,17,3C,5A,BF,53,20,A3,C7,5E,16,1D,F5,6B,E3,ED,0F,01,B7,B1,8D,BE,4E,AA,31,7B,21,EA,50,7D,98,F9,DD,48,85,FA,A5,0B,A1,C2,92,D9,64,DA,36,A7,8B,F5,4C,6D,59,CD,EC,25,59,F3,DD,EC,F8,79,D9,5A,B5,16,42,CE,61,E6,FE,2C,DD,B3,83,4D,EE,4F,5A,08,FD,CD,05,D4,04,72,3F,2D,18,27,C9,AE,02,31,18,78,26,7A,B9,98,98,31,E5,47,10,AB,96,64,50,96,6E,00,3B,DD,57,33,CB,C3,84,87,7E,4D,AA,8F,70,6A,D6,19,EE,CB,55,FA,42,A0,39,4C,74,D0,A8,6D,3B,DE,9A,FF,9F,1C,27,DB,13,01,49,BA,A4,04,87,2C,CA,FC,0E,48,95,D7,CC,E3,00,CE,41,42,2D,0A,6D,E9,82,7C,EE,66,78,F7,0D,86,88,4B,FC,4C,62,AB,53,FA,64,4B,0B,07,65,07,53,20,21,ED,91,09,30,B5,FA,DA,BB,82,F8,F9,DE,F2,82,EE,2E,49,35,16,15,FC,BA,21,67,C6,E1,A6,16,63,DB,4D,F5,56,74,C6,E1,A0,B8,C9,D7,4E,15,5A,84,F4,3F,C2,1D,61,E5,37,A7,46,23,CC,5E,38,10,40,5B,F2,E8,6E,4D,1E,3E,8C,47,A0,E2,55,DF,ED,03,A9,89,65,44,A2,FD,EE,5C,E9,CC,8C,A9,B3,50,75,87,6D,D4,92,47,38,19,51,96,EB,B6,90,75,B3,B8,85,01,02,DA,70,4B,92,19,25,7F,1A,8D,C5,A8,11,A8,80,11,48,A5,B8,30,71,A4,2E,A1,0D,EB,3E,23,A2,9B,85,63,AC,49,33,B4,34,29,C7,01,62,38,56,44,79,BC,D1,00,ED,94,EC,B3,29,52,D4,AC,3B,72,2E,F9,E6,F1,7B,87,DA,E5,45,A6,7B,40,23,0E,6D,4E,24,37,8C,BC,5A,A3,3B,10,C1,31,5E,6C,DE,6F,0C,F3,77,DD,58,DC,CB,E1,9B,51,4D,FE,35,D0,EE,16,8A,C8,6E,B5,59,1E,50,99,2D,34,B9,7F,78,FC,32,7A,C6,16,3B,97,B8,9D,8E,18,47,8F,75,E3,B2,EA,12,55,FA,BF,4C,F7,74,1E,81,A4,52,30,88,99,DA,FD,19,5C,0E,8A,1C,13,2F,C1,70,98,8D,40,4E,8A,C6,9C,81,62,52,4E,D3,0D,49,62,BD,AA,89,B8,27,FD,3F,AC,51,4E,52,F5,5A,16,95,01,1C,44,7E,C9,0C,B9,C1,14,4A,D5,2B,76,0A,C7,7A,A8,E4,36,75,A1,85,05,2E,7B,62,8A,6F,0E,86,1D,FA,65,D0,DC,B4,81,4A,5F,78,89,4B,7B,2B,A0,92,9A,CF,2B,4D,1C,3B,63,B9,A5,DA,65,E4,5C,7D,75,58,75,B7,18,55,70,DE,31,8A,D3,78,31,26,4B,DD,B2,A3,52,82,3B,62,41,83,55,8F,39,D0,70,77,FD,73,99,E8,6D,26,41,62,6A,28,98,1F,FB,E7,0E,C2,13,A8,52,3E,73,A3,5B,93,0F,E0,46,79,64,3B,E2,D2,09,62,AA,03,9C,03,AE,76,50,7D,05,CA,27,D1,91,97,4C,E1,D3,C9,51,A4,14,21,7E,1E,1C,8C,40,EC,A2,21,68,61,E1,F2,39,31,DA,DE,C5,74,96,2B,7D,3B,B9,A6,B5,04,55,00,39,F7,85,F1,71,E9,5F,AF,16,76,30,3C,59,73,8E,E6,3E,3D,B4,1E,2C,7F,4E,6F,85,FE,50,A5,2D,1E,A9,7B,E1,2D,0B,77,86,0B,41,83,BB,2B,F6,0F,46,F6,C6,FB,8E,73,D9,C0,05,65,A4,73,B8,7D,10,57,0F,37,3D,5E,16,38,FD,6F,F6,81,9D,54,2D,24,1B,72,A3,D6,4D,55,96,46,B7,1B,C9,CA,AA,0D,D7,E2,F5,08,58,C5,80,57,22,40,D7,03,D5,BB,EA,B4,DE,74,E0,28,CB,20,E5,B7,CB,50,96,EC,43,0B,28,DA,C4,0A,AB,08,29,B2,5A,BB,D2,B1,B2,A1,46,A4,F5,9D,74,B4,C8,09,7E,A6,18,BC,AE,DF,31,2A,8E,11,E3,F5,EF,4C,3A,07,2A,11,D4,AF,E1,F9,B3,60,99,7B,CE,94,A8,70,F2,34,A2,FA,90,A5,3D,6B,E9,13,D7,68,27,AB,8A,CC,C0,74,7F,AE,4E,A1,AC,0B,73,97,00,6D,24,C4,7C,CB,BB,A0,E4,03,2F,81,D1,FB,7F,91,E3,BD,91,B1,3E,28,05,B7,57,F0,31,CE,65,52,AD,8F,0E,37,31,A1,00,A2,AF,2F,20,C8,91,11,4B,93,D4,A5,98,84,41,28,9A,BB,F8,66,88,A8,41,F8,7A,E0,2C,25,01,D1,A8,2F,F0,CA,DC,D9,AA,A4,F2,9F,83,08,91,56,62,A6,AC,68,B2,F1,F5,89,DF,82,81,62,0A,6E,C2,77,D5,8A,6A,78,E7,C2,FB,53,06,E4,A6,B4,F5,58,CC,7B,79,B0,64,94,C9,CE,EA,56,00,90,5C,FC,93,A2,4C,07,35,EB,8A,9E,64,ED,AE,9B,39,00,51,FA,80,9B,AD,C6,9F,78,45,D1,EC,67,44,78,77,10,B0,0E,FF,BA,2A,14,97,95,DD,E4,23,C8,CE,1D,F3,26,88,29,69,E5,D5,91,8C,48,65,1C,73,CC,46,08,48,84,94,3F,D4,29,30,56,07,0E,19,2E,DB,B7,B8,A7,1F,15,C5,0F,35,5E,3D,2E,58,D8,C8,53,A2,90,67,CD,34,2A,81,58,E3,F2,C0,BE,DC,AE,25,04,F0,88,A1,51,9F,B8,B7,B4,0E,0B,68,69,39,3D,1D,4F,5D,66,1D,6B,F8,7A,E4,B3,54,39,CC,1D,DB,10,B7,E9,4C,D5,AD,47,26,22,E3,93,4F,BC,61,FB,22,EC,9E,87,36,1E,AE,B8,9A,EC,5F,42,3C,8D,E7,CF,AF,70,05,9D,E5,D5,36,C6,AA,DA,FD,8C,96,05,5E,5C,7E,4A,D1,CD,C4,94,38,E2,46,84,9D,F1,A6,82,BA,F5,DD,7E,8D,CF,FC,78,3D,26,C1,5C,AC,9D,EC,D3,70,3F,23,2E,4E,37,57,79,3A,29,05,30,82,1E,29,19,41,5E,68,48,E0,6C,19,F1,98,0B,65,DC,5B,C9,75,D6,F8,0A,DD,3D,74,F3,6E,71,90,85,AB,39,1A,93,7F,8C,4A,BF,F9,B3,6C,42,64,57,38,FD,8F,91,51,DF,1F,F9,10,E4,9D,B5,03,2B,18,45,26,42,EA,31,E0,1D,45,7C,22,E3,CA,60,95,49,BD,70,EF,B8,28,86,C6,AA,68,BE,91,CC,2A,E6,C0,C2,DB,57,20,3B,5D,44,D0,76,81,D7,7D,9A,AC,28,8F,C3,7F,19,C5,D9,B2,7E,BD,FF,A3,E9,97,D3,9B,C1,EE,8D,84,B8,4B,DF,0E,D3,11,DB,4C,30,78,47,34,36,C3,D2,C9,FF,2B,D3,CA,CA,09,13,20,ED,0B,26,36,08,7C,13,2E,C4,E2,19,01,C6,6A,DB,35,43,61,37,38,34,9A,FF,2C,37,CC,9D,84,34,60,73,E7,59,53,20,EB,AD,F6,AD,74,95,41,FA,DB,43,87,BF,8C,D5,74,5A,90,A7,BB,67,97,AD,3E,EB,2F,B6,4C,2B,D8,B4,7F,18,49,54,68,1A,A8,30,19,9E,D0,5E,D1,33,C7,8D,B5,2D,27,0A,B3,C2,2C,89,7C,3C,3C,F5,56,AB,C9,BC,47,8A,51,03,83,DF,10,5B,FD,15,0C,FF,18,77,9C,76,80,2C,29,22,82,68,6C,FB,6E,1B,D7,40,F7,65,07,F9,6E,EA,72,20,15,85,78,81,DA,80,F6,5B,44,BD,DD,27,93,62,84,AF,8A,C2,77,FF,8E,D4,40,17,0E,0C,B3,E1,09,67,25,26,FE,9D,0F,DA,BE,87,DD,DF,D8,DC,3F,3D,F5,0D,E2,BF,D1,08,07,4F,1F,1B,1E,64,CD,84,FC,0D,B2,78,99,7E,ED,6D,48,C5,1A,DF,25,72,27,E8,7E,C8,9B,34,CA,E2,E9,5F,FE,0B,55,99,6D,F0,FB,9E,63,2F,63,C3,AA,BD,AF,83,E8,12,CB,AC,69,B9,E5,BC,73,7B,8E,9C,C9,79,18,0E,A0,83,6B,F6,24,8D,22,60,E1,5C,39,FF,A9,BA,02,63,6C,35,89,D1,8D,47,95,58,A8,15,46,FE,D9,5F,4B,7D,F1,0A,74,DB,E7,81,B5,1A,95,3D,B8,53,F3,CB,E3,42,ED,62,32,03,7D,87,77,6D,10,76,2C,78,A3,F3,EE,74,75,53,95,AB,98,53,13,13,80,4D,27,D5,6E,14,48,15,83,2C,AD,01,90,42,27,B1,32,D4,DA,4B,7F,FB,63,E1,A2,E6,DE,B7,C5,08,7E,B1,6A,9F,3B,AA,D0,0F,87,8F,F7,95,00,B9,CA,7B,E0,48,29,EA,D0,2E,8C,E5,0C,FC,5B,B7,D8,2B,8F,DD,F0,F4,74,85,66,77,76,4D,6A,2C,FF,0D,92,01,6D,A6,08,45,38,53,18,26,50,38,ED,CE,00,C2,EB,EE,8D,16,25,D0,34,97,E5,3B,4E,BC,BC,16,75,71,39,CD,5C,F6,20,FE,7B,61,FB,36,6D,24,29,F5,8A,2C,42,94,6D,97,95,FE,CD,5A,63,88,0F,C2,89,FF,E0,F5,A6,DE,8E,36,88,0B,BF,75,68,C9,2F,B0,41,D9,34,49,18,98,CC,65,66,59,93,00,DD,F4,0B,EE,26,76,74,37,1C,78,A4,CB,3E,A1,4C,D4,48,71,C2,0D,94,10,B5,F2,5E,C8,FF,D0,54,B7,A6,6E,92,D5,20,40,7E,3E,B2,74,28,78,9C,64,5A,69,B0,FF,DE,FB,C0,BD,10,6F,A5,2B,F8,40,6B,F3,7E,15,4C,12,D6,6A,8A,EF,F0,01,82,2C,2E,D2,94,F5,4E,C6,48,32,42,66,08,B0,31,C2,E9,84,9F,49,10,CF,A5,6E,1B,8A,3D,41,FB,16,0D,3D,DD,66,0D,B7,E5,EE,E3,1E,94,99,8E,BD,59,1D,26,00,68,9D,56,6C,37,73,4B,08,3F,B5,35,84,62,5A,01,D0,99,58,8B,64,46,4F,50,61,0F,92,F7,75,5C,E2,CC,66,6A,1B,C1,72,0F,BA,47,94,25,F9,EA,D0,56,DA,98,7F,E8,1A,94,5B,77,E1,E6,95,E2,B0,BD,2B,94,FF,2B,C8,C4,B5,8E,FE,ED,B6,D1,60,C2,A1,5E,B0,DB,3E,2A,56,52,77,AE,81,29,F6,51,6F,0F,98,FC,8C,02,7C,60,7C,61,FB,05,A8,44,57,3D,A0,46,87,07,78,D5,85,11,27,2C,14,5E,0C,2B,34,9C,50,33,ED,65,5C,C5,C9,2C,82,C8,FF,9A,42,F2,E0,70,C9,E7,88,71,50,68,B3,78,ED,F2,59,82,E1,F7,15,8A,08,28,5C,AB,26,C2,FF,54,00,79,45,AC,89,16,A0,EE,81,08,6B,89,D5,29,2F,13,DC,0F,91,A3,9E,A1,5B,FB,BF,31,57,AB,0F,55,C1,EB,DA,01,0C,BA,7A,A4,77,A1,D0,61,45,03,33,47,1F,AD,08,A0,95,54,90,D0,DF,65,67,D7,8B,B6,8E,09,4A,08,A6,62,C4,6C,94,DE,8C,12,38,8C,19,FA,61,F3,E0,3E,C2,4B,43,8E,A1,B3,F1,14,14,41,71,94,73,10,D2,A9,65,37,2F,5C,A3,22,EF,9C,23,AD,99,69,49,AB,13,27,39,AC,32,06,9E,4B,0A,38,51,8C,B6,19,4C,BE,1E,C4,BE,DB,BF,17,58,A6,6A,BD,AB,1A,1A,DE,24,A9,5A,A6,3D,BA,92,A9,D9,9A,5F,5A,60,DD,00,2C,81,D9,02,97,26,7C,96,15,94,24,49,B1,80,99,8E,D5,C4,36,B8,29,7A,6C,79,32,5E,DF,C3,B1,3F,C9,39,BE,16,4F,15,F5,AE,2B,19,A4,A3,07,07,4B,21,42,EA,2B,F7,8E,B4,0E,0E,86,A5,56,1C,95,6C,18,EB,8E,DE,AB,91,25,8E,55,07,D1,C1,B8,6A,FE,5A,73,C8,49,DA,91,04,CD,2E,A5,EE,06,5C,23,89,D4,E3,FC,3F,CE,A6,A9,A3,D9,04,57,2F,8E,03,E6,2C,4A,AE,52,E2,E5,E9,E5,51,F7,B4,06,59,30,31,30,52,E3,43,2C,6D,8A,97,C3,FC,A0,5E,88,B5,76,DF,E8,EE,96,CE,18,11,DA,26,A2,29,2F,F4,96,78,9D,4F,84,DB,F7,33,98,4F,F4,45,1A,E2,CD,81,79,9B,4D,15,17,8A,01,21,A2,54,A3,7C,4F,1F,C2,CB,63,90,98,D9,FB,32,FA,A2,40,7E,B8,F9,B2,D7,29,30,74,9F,B7,23,C5,00,6E,68,61,9E,93,C7,85,3C,27,02,7A,BB,AC,FA,C2,2C,26,85,8E,4F,37,45,E8,D5,DE,DE,7C,72,F5,EF,51,2B,12,05,9E,DA,04,9F,D1,7C,1F,44,89,51,72,BD,82,74,CB,22,11,14,26,48,F2,29,49,C7,73,57,FC,2A,34,A1,90,48,B5,F4,4D,E0,05,47,72,34,17,AB,1B,15,10,7D,D8,B1,2B,CA,01,2B,8E,75,6C,ED,5F,58,98,31,68,3C,EB,1F,BA,F6,BF,26,23,C2,44,7E,89,5A,6A,3E,AF,12,BE,C5,D0,71,6C,85,FC,27,59,D1,C8,B6,6B,00,21,BF,67,99,CB,D4,D0,23,3D,29,5A,A7,43,CE,8C,6D,E9,66,62,D8,D5,FB,33,BB,5F,34,E5,50,F4,49,5F,0F,00,6A,DC,EC,24,27,E9,30,04,25,BB,5D,E6,D0,EE,15,1D,74,EB,6A,5A,DE,25,BD,DB,B9,39,70,22,A5,34,4A,6D,37,AB,34,97,E7,19,7E,D4,58,46,FB,5E,DF,B2,40,9B,2A,98,81,79,04,A6,24,4B,AD,E2,31,55,32,74,BA,25,BE,8C,CD,07,64,D1,86,7B,C8,2F,EE,C4,F9,71,7D,09,0B,C7,10,DD,C3,7A,31,9D,95,41,1D,01,BC,19,A4,CE,DD,95,37,47,86,79,13,2E,0F,61,79,8E,45,D9,5E,9E,49,12,6C,3E,9E,DD,A1,A4,69,D6,07,F8,D6,D0,69,6A,29,90,D9,93,1D,BA,44,72,4C,F7,7F,2A,97,10,03,E7,4D,D4,47,27,8A,D9,D4,89,B1,AF,EA,A2,0D,3B,02,6B,2C,2D,AA,1B,4F,F5,A7,BD,1E,47,87,41,09,02,E1,EB,9D,F8,BF,3C,7E,76,80,5E,5E,0A,E8,EC,DA,95,F4,F9,E2,AF,85,37,A9,5D,56,5C,E9,5B,E1,C0,75,7B,DA,BE,EE,AB,11,BF,AA,C1,3F,60,D2,24,13,7C,7E,E2,92,76,6B,95,73,6B,A3,2E,A3,1B,B1,13,B5,1C,64,D6,F2,FB,6E,D4,0D,CF,9B,4B,DA,0E,CC,C5,88,CE,43,52,96,D5,B3,FB,1B,4C,1D,5F,C0,F6,2C,A2,9F,7C,84,8B,13,13,10,F0,02,F0,EB,0D,B9,37,75,23,20,3C,42,00,72,4E,3F,47,C8,1D,55,C0,F6,B0,18,8C,A8,78,55,55,13,B3,8A,F4,1C,26,40,1B,D9,2C,BF,A9,06,0B,38,EE,5D,DB,FE,BB,64,51,CC,3A,BA,C2,6D,41,E8,C6,00,DC,DD,82,15,84,12,34,44,E1,B4,78,12,62,72,58,7D,93,FC,83,1F,67,FA,35,3D,13,8E,23,C4,0B,56,57,55,1C,BF,0D,7C,F6,68,B3,4B,40,A7,4A,CE,58,F8,68,E9,4F,7D,AF,93,14,3F,5D,DE,FF,B5,81,D0,CA,B5,C7,F7,7B,CB,EC,29,9D,96,8E,F4,85,76,C8,2E,D3,DD,CF,46,78,0D,EC,23,C5,04,51,3F,C4,15,49,DA,45,5B,66,BA,66,46,BC,40,75,A0,7D,3C,EF,86,20,0F,7F,15,B3,6D,15,A4,2E,49,D2,A7,FC,D9,21,0B,D3,8A,4B,C7,39,9B,26,7E,54,AF,03,AB,02,1A,EC,07,A9,16,42,39,BD,D9,F0,11,71,37,F6,A1,FF,E7,BC,CC,8E,25,C6,34,A6,D2,33,35,47,94,9A,A2,8C,75,6F,D9,B6,10,F1,4B,8A,76,D2,CC,22,1D,80,55,60,B9,23,64,CE,03,E5,E5,B8,C7,99,68,5D,A9,35,2C,C0,A0,B0,88,1F,4A,67,66,34,BE,4C,F0,59,1D,E1,78,E4,D5,A1,31,D2,CB,48,FB,9F,D3,D1,02,36,E6,69,58,12,58,6D,23,68,BD,DE,1B,78,1A,D4,3D,4F,2C,93,25,9C,7A,25,BD,BA,D8,09,06,7A,4B,42,95,34,AB,86,4D,95,9E,EC,55,FA,F4,1A,73,C6,98,79,61,90,F5,31,B0,0E,DF,1F,55,65,D3,FC,D7,6C,A1,51,84,BE,24,CB,47,01,A0,35,68,AA,F4,64,49,9D,30,74,4B,1B,83,F9,51,DE,1B,6F,54,DE,11,54,12,37,7A,35,27,DB,13,B3,99,56,5F,75,8D,62,ED,E9,00,7D,BB,DF,FC,6C,78,7C,A8,22,AB,B2,7D,A5,C7,01,DC,E0,D8,59,21,39,C0,8A,7A,95,34,AD,A1,96,A9,50,EE,41,3B,39,01,D2,39,86,BD,5B,A8,83,97,79,42,15,BF,DE,93,A3,0D,9E,3C,28,51,2A,BD,FB,96,83,20,0E,8E,95,59,53,8B,5D,F0,8A,11,AC,D1,27,3F,B4,16,FB,5A,D3,BD,82,27,77,37,00,A0,D2,A2,E1,55,45,EA,4D,58,ED,E2,D3,03,A6,92,5B,23,D7,CF,21,56,3A,CF,53,9E,42,B0,01,4B,19,FB,2C,39,37,5E,36,ED,AF,64,00,36,67,B6,F1,24,CF,00,C2,65,8E,6E,8C,5E,D0,73,2B,66,D8,A8,9E,98,E2,89,0B,A8,80,0A,BB,54,CF,91,1F,22,7F,D8,CA,3A,C3,E3,FC,E1,52,E5,07,E1,6A,BC,4D,6A,97,AA,50,E2,1C,EE,04,0B,21,51,85,10,EF,8F,F7,C3,7D,E0,6E,B2,18,40,0D,B1,E6,A6,30,D1,83,57,C5,52,00,E8,33,47,C3,50,F1,EA,31,E8,93,57,23,C6,42,C2,DC,A6,45,B2,1A,9D,47,F1,F7,54,50,FB,8A,C2,40,E1,F9,85,AD,E2,C8,32,ED,AB,24,1B,28,A9,5A,FA,D1,3C,4F,1A,F6,68,C0,15,5A,17,DB,D2,7B,D9,63,7A,A0,FF,55,6D,4C,66,FF,27,D8,C0,81,2F,CA,9E,B6,61,15,25,A3,6A,3B,65,98,83,3F,B6,18,A7,11,2E,B1,36,0D,C3,9C,12,25,DD,05,B3,2C,8A,28,8F,4F,4B,2E,60,CB,AE,A7,12,9C,A8,B7,77,82,5E,53,30,A3,4C,1B,EC,8F,C4,97,4E,C2,DC,85,BF,F9,F9,7B,45,32,A6,29,B8,22,DF,FA,25,E2,61,AF,FB,28,82,86,06,9D,15,02,AD,40,E3,72,70,B2,B6,E3,C3,0D,5C,13,AD,E8,19,B2,65,06,52,64,1E,C1,E8,E0,37,F8,F9,8D,5E,CE,08,9B,6B,73,15,56,4C,9E,21,36,87,1B,A4,89,BE,D2,31,E8,C6,92,2A,09,A1,D1,70,B7,84,A2,62,08,67,F1,E1,EE,9E,26,82,C5,F6,B9,39,21,6A,A6,06,8C,A7,C9,39,78,FD,5A,73,6C,96,6A,C2,47,B8,0B,59,0D,BE,7A,3F,E7,E5,D8,00,BD,33,81,A3,7D,62,48,3B,12,7F,EB,47,E0,54,56,24,EB,CE,AE,0D,9F,27,B5,25,3F,C7,78,B5,E3,83,21,F3,8D,4D,8F,91,91,7A,FF,BC,9D,07,0E,41,E0,05,8F,0A,F1,76,A3,2F,87,B8,99,FC,A1,72,4C,F0,C3,2C,36,EC,75,A4,43,19,34,B5,D4,E5,24,8D,26,36,B5,27,1C,F5,DA,5E,99,6B,01,E0,89,A3,90,4C,C9,90,4D,CB,45,71,51,E5,6E,4B,EC,FC,04,EF,11,72,B6,80,40,DE,24,0A,BA,02,54,B9,E5,98,ED,70,F7,52,D2,00,AF,14,AC,B1,F1,0F,BF,A6,A2,85,4A,8C,10,C8,F7,24,F9,66,DF,D4,A0,67,E9,01,8E,32,73,7A,9E,79,72,56,AB,27,5F,93,73,9C,E4,03,8A,16,F9,B9,9F,5C,C0,BB,15,C9,CE,D4,F9,37,22,B9,4B,91,A8,5B,BB,0D,5E,36,39,AF,80,25,78,4E,5C,F5,25,1E,F5,C0,38,77,BA,E8,A3,57,FE,5B,2A,89,59,B8,CE,80,9C,7B,7B,9F,44,C3,67,8E,7A,BB,E8,D7,52,0D,D0,18,CA,9B,04,3A,99,3A,5B,A9,64,FB,7B,7B,67,8E,1D,80,13,A0,25,2D,A7,81,1E,A6,C9,08,BD,D2,34,D7,BF,FB,90,0D,E8,46,32,AB,4E,5C,78,F0,4C,08,DD,1D,93,B9,82,EC,FD,25,91,88,CC,F8,46,58,00,6C,8B,98,C1,D5,6A,6D,AA,C2,B4,A8,CA,A3,5E,8B,45,3C,D2,D1,29,C9,FF,5C,A7,E4,62,4A,6B,70,A0,FC,88,40,A4,B4,53,E0,BE,B0,C7,F2,37,C1,B5,EE,73,01,E4,76,02,57,A7,BA,1B,44,DD,EF,11,A2,46,D8,46,7B,58,1A,18,71,7A,5D,00,B4,89,CB,3C,61,EC,D7,38,2B,DF,C7,68,DA,7A,47,A7,40,83,BB,67,71,DE,95,5D,AD,39,7A,20,44,86,F4,78,DF,1B,E1,0B,7A,28,8E,FA,93,DC,69,21,63,B6,2D,DC,5A,FA,33,58,25,C6,0D,2E,87,F5,7F,94,39,A3,93,DE,6D,60,4B,37,21,9E,09,F8,A6,F2,82,51,51,CF,F8,10,08,A6,B9,1B,6C,3F,BA,E4,28,6F,9D,2E,99,08,53,97,B8,A9,A8,50,01,47,8D,91,1A,3F,26,20,A1,C2,2F,E1,5B,96,00,1B,63,1D,6D,14,C7,C2,E8,43,C0,39,54,F5,66,CB,46,81,AB,30,72,00,5B,D1,67,63,9F,B4,EE,AC,7B,18,20,12,EF,6F,47,C2,D4,CC,8B,F3,19,70,14,6D,31,5E,BA,2D,13,29,82,69,2D,AA,84,2D,CD,EF,74,4A,23,8C,97,EB,12,0A,93,6A,5A,8F,83,5F,66,CF,3B,60,C0,B7,F3,3D,8A,73,5B,D7,88,DD,C7,4F,85,C1,9B,77,0E,A9,29,8F,C8,E1,DD,30,C2,CF,D6,D8,72,42,3F,EB,16,83,1A,36,AC,AB,EF,E5,9D,3F,31,BF,20,53,7F,2D,0E,28,EC,98,E0,D7,16,74,B9,59,B7,CC,BB,29,A1,2E,DF,87,60,75,49,29,7B,3D,E9,F5,DF,05,23,0F,3C,A3,32,B6,0E,28,3F,63,38,BA,AA,CE,6F,E1,A4,C8,80,6E,1C,06,42,A4,00,6B,38,12,DC,27,B2,4C,ED,09,95,75,FF,5A,32,42,BA,81,B8,F6,32,DF,04,C7,F7,2E,0A,00,B9,AC,48,FB,5E,3F,50,08,EC,DF,6A,B8,FF,95,8C,38,04,02,87,A4,6B,32,BE,13,16,1A,08,5D,5A,4F,88,C9,84,5F,8B,35,1B,EA,67,1F,16,56,22,2D,DC,01,A0,94,23,53,B2,56,DA,77,33,01,9F,B1,CA,CD,F6,7A,D4,62,95,B1,05,63,A6,9C,15,C7,BB,FF,83,9C,C1,59,01,40,05,AF,C3,96,6B,CD,B6,CA,1C,AB,6D,8F,6F,CD,D4,74,25,6F,A9,1F,86,86,ED,CC,EE,23,D6,52,FB,B8,46,4D,82,17,F3,B8,F2,7F,6A,C7,FA,E7,F6,40,3C,DC,76,9B,48,30,13,75,67,20,91,67,FB,CC,F7,20,22,A6,4B,08,93,AB,93,3A,28,23,9D,E6,18,B4,0A,F4,E6,B9,61,A8,0E,8C,B3,69,D7,39,8B,77,23,C8,A0,1E,3B,8D,2F,D2,5D,9C,4F,3D,35,58,B9,A5,31,F0,13,E0,5F,91,B0,17,C3,5E,E2,F2,F8,00,8D,2F,05,E4,4A,14,10,EF,30,B8,6E,BC,BE,89,07,68,3E,F8,42,5C,85,09,22,8F,A5,DF,80,4A,74,58,C0,43,E6,4D,33,BB,94,03,5B,F9,DB,47,01,88,78,43,D4,C0,2F,A7,68,23,D6,5D,C4,EA,5B,A4,47,86,15,ED,9A,01,F5,F6,41,58,A7,F0,B6,83,C9,43,B0,5C,EC,76,F9,79,4A,63,49,E7,4D,45,6E,44,78,9C,78,49,95,7B,8D,3A,F9,B4,89,E6,20,50,5C,69,B8,35,42,A6,0D,1E,03,C4,77,7F,C1,A3,A7,5F,30,25,63,CE,80,8C,5D,DF,AD,9F,A1,A2,49,1A,56,60,40,96,08,D2,11,3C,2A,D5,45,9F,2C,A0,4B,9C,82,AA,B8,13,35,28,E5,6D,E7,84,D0,96,8E,A4,5E,14,8D,CC,19,BC,55,79,F6,2F,11,A3,F7,D6,BE,72,42,98,DE,3C,46,A0,20,40,00,7D,B2,12,64,06,87,4F,25,BF,80,D0,6F,65,AA,E9,D3,A9,B3,1F,34,62,D9,AC,FD,E4,2D,B3,0A,48,56,C4,3F,95,BA,8B,F0,FA,5F,E8,D6,C2,CC,69,9C,AE,A3,ED,90,92,AF,C5,4D,CA,53,B9,B8,BC,69,4F,12,B4,4B,DE,7C,E0,9D,60,A8,69,57,54,3F,B7,F7,6E,95,BA,C9,CB,A1,BF,04,4B,70,EB,CA,CC,C5,F9,DE,0C,7E,90,BA,A8,34,C9,F5,7E,6C,F3,BA,01,B3,A2,4C,31,5B,5F,E3,60,B4,57,5F,0E,A0,30,8B,59,C7,23,94,51,80,13,1C,AF,18,1F,46,48,7A,98,01,86,8D,E6,00,7A,02,B5,EE,0E,10,3A,B3,B2,18,30,CD,33,1A,F6,07,FF,3C,E1,6C,CD,60,67,5D,29,A5,B6,68,2A,A6,74,7B,5B,84,62,EB,FD,6C,BE,F6,4E,CA,8F,04,B8,AA,67,2D,DB,04,30,3C,6C,4B,FE,0B,68,FB,FF,EF,8E,96,85,42,9B,4A,09,B5,E6,93,A2,11,6D,CB,2B,ED,47,5C,8C,BA,E2,7F,89,B0,83,5B,3B,52,80,C0,40,D6,A9,BE,4A,C9,D3,41,1B,9F,5C,C8,A3,F1,9E,98,ED,A7,36,8A,13,80,6C,CD,A3,2D,5F,88,17,A2,26,3D,07,53,7E,BD,5B,00,62,13,33,35,E8,DB,B2,38,00,70,B1,5F,25,E5,78,6B,E5,3D,4F,98,3A,B4,F2,D5,10,5A,18,4C,91,7B,F4,D6,26,E7,B6,84,65,07,0D,62,CD,53,3E,76,73,8F,D0,89,69,0B,70,78,6F,F2,4D,79,9D,9A,72,B0,18,67,A5,82,88,31,AD,A6,29,03,4B,D2,3A,95,7C,EF,EA,CC,AD,BE,FE,C6,D6,7B,3C,C9,43,90,68,28,D8,6E,56,93,68,6D,14,47,40,D6,6B,9F,94,80,89,29,07,22,B0,71,98,3C,D4,F6,3B,96,8A,3C,FF,AE,D8,00,C8,58,8A,46,F4,D7,FD,2D,58,C3,3E,D8,CC,B8,4F,B9,E3,31,25,2D,5E,9D,6C,60,40,21,CF,D6,EC,C4,6C,62,BB,CD,F7,98,D0,82,40,D7,AD,D7,7A,86,CC,37,EF,5C,FD,00,CF,CD,81,74,D7,79,45,1A,67,4A,8A,C6,A0,AA,5F,AF,E4,98,16,FE,77,8E,0B,F2,CA,7F,70,50,EC,36,59,16,85,92,3F,40,BC,D8,75,7A,90,97,D6,5C,B4,72,88,11,D2,9E,94,36,19,07,20,BD,BE,52,15,0F,05,DB,9D,CE,2B,22,D8,FB,E7,F9,F9,C3,45,45,9C,9C,B7,76,7D,8F,FD,73,F2,89,8D,CD,78,F7,CE,3A,8A,76,0D,8A,DD,DA,1E,2A,34,3F,D2,A5,D5,05,E9,D3,A7,E2,3A,3B,86,28,C0,C8,F6,32,B4,C9,A7,F2,F0,F3,28,7A,9E,2C,CE,24,8E,71,F7,A0,9A,E8,00,6F,38,B4,1F,C0,DA,33,9F,3C,6E,77,EB,98,9C,A2,C3,A4,9A,F4,7C,73,D0,A8,1E,CE,A1,ED,8C,71,81,CC,2A,36,50,F1,B3,62,A6,30,E5,4B,42,BC,64,CF,2C,EC,9B,13,1A,F5,79,06,33,37,33,0B,8E,37,05,05,7D,F5,5A,F3,F8,04,CA,DD,67,4F,EB,14,D3,00,8F,07,71,62,97,B8,22,B1,E5,39,BE,58,2B,99,9E,91,DF,E2,DB,17,91,02,FA,C4,54,07,39,D5,6C,4D,A9,9F,DF,C5,D8,B6,03,A8,80,03,AF,2A,7F,D9,14,71,15,70,40,D6,8D,B1,C4,65,F9,C4,A0,DD,47,5C,BE,37,FF,23,BC,35,A0,DB,72,1E,AD,C4,46,0C,26,2B,F7,8E,8E,5D,DE,1E,38,A6,3E,A8,C4,43,99,1E,3B,1F,A4,49,7E,A1,DC,F0,2E,B3,C9,35,A0,51,36,C1,2A,26,B4,84,C9,21,24,30,68,8B,53,49,5C,7B,87,09,0E,E7,F5,20,90,85,36,23,6F,90,D0,CC,A0,00,DC,5A,3D,E5,7E,CA,BE,4A,21,17,65,7E,70,C9,8A,98,76,3D,0B,F8,3E,E0,9A,01,D6,08,79,EB,E4,60,CC,44,9A,B3,7E,34,38,92,4F,8F,0C,2A,F5,11,A4,5E,6E,A3,77,60,16,B5,0C,B3,D6,0B,6C,98,18,55,E4,AF,83,95,7C,CB,01,8A,A9,26,49,73,9F,4F,B5,A0,CB,2B,D5,7A,5F,74,01,03,C7,BE,5F,D3,AD,E3,CE,CE,A5,D4,CC,8E,10,D7,5B,4C,2F,6F,A3,DB,E8,5D,96,19,D1,64,B2,02,31,C2,52,50,E3,DD,58,2A,E0,D7,69,CF,92,49,B7,04,16,1D,11,47,C5,1A,BA,F1,92,C8,5F,10,AC,BF,91,BC,1F,A3,63,B9,BB,55,71,E6,32,AC,DA,1E,FD,67,62,65,58,69,38,9C,14,55,5B,9D,1B,34,0B,67,B2,A0,78,24,5D,87,5A,87,3C,F4,DE,49,E3,18,DF,5C,89,54,0B,69,BA,18,B9,54,55,D9,BD,09,E6,DB,D2,C9,66,D6,1A,AA,22,DC,B6,F6,AA,D7,CB,82,55,F6,57,63,4B,DD,4A,AE,0C,DB,86,BF,66,64,EC,AE,90,6F,D9,B0,D5,74,12,DA,EA,F3,D5,28,B6,1F,D4,68,DA,A7,3F,66,0C,A3,8D,B0,F1,4B,1B,DB,7A,11,B6,52,AA,6C,D5,6C,6B,E0,4D,28,66,DB,38,C0,43,A8,CE,7A,A8,BB,43,B2,9D,59,B9,8C,D6,76,BA,A9,CB,6E,9F,29,2E,BC,34,D9,7B,C9,CD,56,73,03,CB,9B,D1,5B,9F,E0,36,E9,17,E3,94,C6,E2,1F,B3,A7,55,90,14,86,18,01,25,B1,21,9F,BC,20,FE,72,32,C6,8E,E9,69,AF,1C,59,F2,96,E4,7F,D6,31,12,C9,40,7F,49,1D,83,80,FB,23,2A,68,27,A0,D2,AE,53,E8,1A,E0,8D,57,96,A1,28,87,90,A0,9C,0E,53,42,DE,3B,32,68,ED,DA,CC,F3,25,1B,FF,D4,12,67,17,23,ED,05,6F,BF,B9,FB,06,D9,89,E1,76,67,39,86,A3,62,9C,09,BB,C5,BA,1A,C0,BB,83,AD,E5,A9,4F,75,F5,78,B1,7B,01,06,B2,5D,AA,93,02,D9,0C,4E,84,39,A0,2E,DF,C6,B4,B6,0A,7C,8A,CF,15,7E,89,09,53,76,7B,B9,7C,AD,0A,83,DC,B3,A8,76,1B,F4,2A,B5,7E,DB,BC,5D,E0,7D,86,0C,38,DC,22,A0,6C,D3,9E,A7,5A,90,B2,2C,A2,A9,FD,87,0D,C3,1F,CE,3B,9E,5C,61,BB,B4,A6,98,DA,CA,6D,64,EB,3A,FB,B5,C1,1F,9C,6F,8F,2E,90,50,8D,09,FE,97,26,63,4F,66,9A,93,D3,04,99,31,AE,58,27,4A,99,A5,C9,93,5D,46,DF,23,DA,AF,97,D8,0A,3B,32,C5,F7,26,B2,53,B6,3B,02,EF,51,54,0B,0E,C0,4C,CB,82,CA,21,10,59,A6,94,0E,6D,DC,B7,68,72,DE,A2,BB,D1,94,7F,E9,B9,35,53,33,95,8F,DD,0D,AD,87,65,AD,FE,62,7D,F4,F8,9E,9E,AA,4F,AA,D8,72,9B,5D,59,4D,1A,5C,FB,42,73,1D,D7,01,D3,FC,C0,1F,FE,D8,B0,BB,66,80,8C,7E,E6,BF,83,64,F6,F2,FD,81,9F,59,D2,78,2F,F4,63,EA,00,BA,BB,66,9D,B6,83,7E,CF,4A,7F,4F,C0,8B,22,E5,EA,07,32,86,41,6D,69,D0,30,95,D5,2F,36,52,BA,0D,24,42,64,5B,18,DC,5A,D7,34,A1,8C,36,6C,19,81,BC,F5,71,56,0B,0A,25,83,AB,10,40,08,5A,75,3B,13,A8,B9,0A,17,F1,88,39,EC,EE,5D,17,9B,F4,AD,83,FD,B4,5F,40,0E,0D,8E,AE,7C,D3,48,B6,C6,93,14,47,6C,05,FC,6D,77,F2,82,DA,0D,F4,72,14,5A,DB,C4,E8,FB,B3,25,3E,F0,84,D6,02,8B,2C,27,FB,F0,7F,33,2A,50,39,59,04,B0,E0,E6,B3,6C,B9,62,3F,AD,DF,03,23,C9,12,A2,76,8B,47,EE,A9,13,92,DE,79,63,4C,B7,54,ED,79,F7,5B,3D,C3,9A,D9,39,97,23,D5,A4,D1,6B,76,2F,59,58,6D,64,2A,49,76,86,62,57,5C,9E,35,EA,71,DD,5F,7B,F5,03,A6,4E,9D,62,B0,F4,70,9F,E9,DB,7B,DA,78,22,29,F6,29,6B,A7,06,28,0D,FB,FB,E6,F5,42,94,98,02,F6,6C,C4,28,26,C7,41,69,35,28,60,E3,B5,C1,10,7B,E3,E9,20,F3,A8,70,67,E5,1E,BD,AA,EC,93,08,F2,30,FA,44,94,E2,E1,8B,CB,E5,FF,B2,F2,75,87,14,1E,76,DB,FF,C4,38,8F,DB,19,E3,4D,29,F3,4F,81,9E,22,0D,D3,C9,B4,70,95,52,62,F6,83,49,CA,E6,37,B6,AB,EE,C2,43,1F,23,03,39,02,52,CD,03,F6,D3,0B,A1,F4,9A,40,CD,67,00,73,64,50,A0,33,47,D8,F4,05,E1,23,12,B0,F7,3E,DE,59,42,7B,B8,F8,BB,DF,02,6D,85,73,C5,F6,F4,B9,09,F4,44,E5,1B,6F,32,23,76,B1,36,6F,D9,1C,D2,AA,3A,F3,5C,25,08,67,77,16,B3,B9,13,4C,92,EF,18,04,9D,C7,86,A7,4E,4F,F9,A5,E1,DC,D9,00,3C,F4,FC,A8,25,CE,0F,00,56,BE,B6,A0,FB,0D,1A,03,6C,9E,4F,0D,0E,62,4F,CA,BB,23,72,E7,5C,D9,BD,75,4D,5F,A7,58,D4,31,E0,E2,2F,99,14,73,F3,58,89,51,76,D7,C8,8A,C4,65,35,FC,AE,4B,C7,78,3C,B8,24,4F,AF,97,6F,A0,DB,87,98,83,BA,73,E3,76,A3,AE,08,86,7E,79,B4,F7,E7,B1,E9,FA,0E,8F,72,F1,4A,F1,13,BB,82,BE,F6,D8,E6,3F,16,1A,0D,BD,59,7F,14,29,28,9B,C8,41,EB,73,DA,8A,86,9E,E1,28,60,49,00,ED,AE,D9,33,25,8C,44,29,24,D8,BB,A3,1A,C4,B1,DE,2B,9F,C5,BA,92,6B,82,DE,BF,4F,A2,8F,1D,2C,E5,8F,D8,4E,19,A7,C3,76,93,9D,58,33,25,20,70,E1,80,17,54,F6,1F,B5,39,7C,02,72,B2,E9,2C,6B,CF,A7,FA,A3,1B,73,7B,60,E7,9B,12,9A,3A,84,48,38,4A,FE,CD,99,91,A0,A1,A2,26,F6,1B,AD,5F,B2,75,56,61,B9,DF,F7,0B,D1,42,3E,DC,06,6D,DA,5D,51,D6,65,A2,4D,7D,C8,76,0D,5E,19,E8,37,5E,C8,DF,B1,B5,56,D0,15,73,BA,9D,5D,E7,58,47,19,9E,F7,38,D8,1F,BC,3A,FB,9F,D7,B3,8A,6D,46,AD,0B,F3,01,15,CE,FC,78,88,F8,97,6E,82,C8,8C,C2,E0,5F,BD,B4,6D,2F,A6,9F,FB,69,8C,4A,FB,DF,9D,9B,14,CE,10,02,73,50,75,41,CF,A5,61,BB,D2,77,DF,48,00,CA,13,92,C7,40,23,FF,95,F3,3D,55,A6,52,6E,4C,54,04,6B,0B,DC,B3,EB,AF,4E,47,11,E4,01,6D,3C,26,91,A5,10,05,3E,BA,E5,91,9F,0F,6E,C0,56,70,1C,80,A2,F1,A8,F7,DD,EB,B7,F6,FA,B5,7C,A1,EC,7B,3E,3E,E8,F9,52,14,75,EC,8D,18,A1,3E,42,C7,76,AD,12,B1,B4,3A,00,B7,64,65,4C,3A,D3,13,43,B4,B1,7D,FE,85,BD,B0,14,FA,A3,01,52,7C,26,01,E3,6E,EB,52,B5,F1,3E,AE,2F,3F,AE,24,49,46,66,20,D2,FE,45,99,8F,D0,62,CC,8B,AA,38,30,39,1D,6D,34,7A,0B,E1,D6,D5,E0,57,09,68,67,19,E4,3A,4C,72,5C,9D,68,36,06,2E,1D,51,CF,07,18,61,EF,F0,C6,77,53,7A,8D,81,00,D7,D9,8A,12,B2,B3,91,22,1E,AD,85,68,2A,35,CE,A6,FF,43,FA,30,89,DE,B9,5A,4D,B6,32,8C,19,AD,3A,B1,16,2A,F1,67,5D,AB,5F,12,E0,45,33,F2,24,3D,AD,E9,1A,C2,02,10,58,F2,3B,AE,38,3D,E8,65,ED,E4,ED,7A,2D,51,B6,2A,CA,AD,08,F9,59,F5,DA,01,66,09,46,A5,66,F0,B4,F5,45,4D,C5,27,93,DD,9C,BB,CD,2C,ED,AB,E2,31,6D,68,AF,11,F0,BC,35,61,C0,D7,51,8D,64,16,E2,D5,64,22,4E,33,7B,AB,BD,B7,96,93,A1,06,27,0C,28,A3,DD,04,CC,B7,28,3E,6D,A5,9E,E0,A2,71,25,36,23,F3,98,96,C9,4F,05,ED,9F,92,85,E9,65,1A,7E,2F,95,A7,7B,AD,1C,14,B3,45,B4,9A,10,2D,9C,63,97,DC,B1,C9,79,5E,2A,4F,49,F5,B0,09,38,20,A0,52,5B,71,14,7B,EB,37,D4,FC,35,C0,D7,1C,5A,30,D7,37,4E,D5,C5,84,ED,40,69,E6,14,BD,FF,51,1E,D0,AB,1A,02,7E,D2,E4,22,DD,16,28,52,AC,4F,AC,02,67,01,A9,EE,00,2B,C2,0E,75,18,76,25,35,B7,FD,72,7B,08,9D,EB,82,7C,39,30,D4,6E,3E,B6,CC,CA,58,11,1F,64,B5,9D,F6,8B,C8,B6,5B,31,0F,80,54,32,BA,37,6D,8D,8F,90,1D,F5,37,B8,7B,65,70,CC,F5,EE,70,F8,AD,60,50,B8,89,3D,A1,75,75,CA,9C,61,C5,FB,1A,BD,46,46,59,5D,A3,45,62,39,93,B8,07,50,AD,B0,55,6B,3D,15,B2,05,AE,FF,1E,E1,57,02,A2,FF,55,C4,A5,0B,02,2A,B9,2B,7B,AC,DF,A3,76,83,B3,B5,2C,8F,CA,35,7F,74,D0,8E,0B,7A,14,49,DB,DE,12,DD,F9,C2,7D,69,EB,D6,FF,CF,00,B3,25,D8,54,19,46,02,B5,FD,BE,AE,D5,73,E1,44,D5,43,FB,07,23,0F,D8,4C,D1,A2,19,A6,CF,4C,BB,0E,EF,91,9E,2B,B0,18,E6,57,F5,F8,64,A4,F4,A5,8B,06,48,EF,4C,39,85,84,AD,02,C2,EF,6C,02,CF,36,F2,1E,C6,6D,3A,4D,ED,B7,41,3A,6B,90,70,B6,9E,EA,F9,A7,83,74,45,E6,CA,50,B3,48,7A,C4,D7,12,90,D7,54,25,8D,D7,E3,3B,D7,98,18,8C,82,D9,6D,8C,16,76,ED,41,BF,F2,71,7D,64,E4,14,74,C3,62,D6,B8,E9,72,6E,6C,2A,00,6B,A4,6A,ED,2C,95,42,C1,9B,CE,D8,57,70,3E,DC,66,23,56,3B,45,25,E9,4F,01,D4,B3,BC,12,8B,70,6A,D1,58,6C,A9,A1,DA,77,F2,8E,BF,8E,77,74,74,D8,B2,7A,11,75,3A,93,A0,27,5A,2D,23,2B,25,0F,B6,35,BE,A2,A8,8C,45,F1,35,23,B0,26,CD,51,B4,D3,E7,A7,91,05,51,8D,CC,BD,AE,32,D4,55,8D,6C,7F,C2,B7,80,E0,20,21,20,20,4A,F8,7A,F3,8E,69,94,C2,71,7F,1E,62,3A,5E,A5,43,CA,68,DB,7E,A9,19,20,47,0B,D9,00,D5,7C,79,98,C8,BD,9F,CD,D9,BA,F8,FF,77,5E,3D,51,CC,88,C9,9F,6C,5E,A1,0C,86,51,09,F0,B0,C2,B6,64,6A,5C,54,41,F3,F4,32,ED,B9,FF,8D,44,6A,6A,B1,18,07,A8,80,6C,99,F3,5D,47,DE,A5,80,94,EE,78,E2,42,A4,74,BE,2D,2C,FD,68,6C,FE,B1,A3,BC,ED,EB,7A,DB,03,2B,53,F3,97,33,6A,1F,B8,A3,25,FE,2E,B8,1F,87,51,6F,05,A4,CB,C1,B4,94,02,C8,14,14,3F,49,39,CE,D9,BF,2A,41,04,72,6D,5A,03,3B,50,DB,6F,F3,45,B8,0A,74,BF,75,D6,01,31,D6,87,2C,1E,2A,B5,A9,6F,5D,4D,65,1A,4C,A7,0F,30,83,29,C8,C6,2E,1E,48,33,8E,70,AF,22,61,60,EE,00,70,90,03,BD,DF,9D,F9,E0,06,E9,CB,9A,C6,91,25,68,FE,32,41,17,2E,C8,3E,7D,6C,34,E6,5D,FD,24,89,50,95,8F,10,EF,C7,17,7B,64,A9,13,F8,93,30,44,2F,5A,92,B2,6A,29,CA,D8,20,7A,DB,8D,87,A0,DA,F8,3D,C4,15,6F,30,47,48,46,18,15,58,1D,7F,AE,33,46,A3,71,FA,66,21,63,FC,95,7C,DB,E7,F3,70,DE,7A,0D,BC,EC,71,BA,DB,0A,42,E1,3D,95,3C,32,9F,94,95,9F,57,11,60,46,1D,39,AD,50,79,67,53,36,6A,9B,87,88,32,04,A8,0F,BE,AB,26,48,8D,44,B4,52,C7,55,C2,02,00,B6,6F,B7,E8,FB,30,7C,16,96,28,06,00,56,6A,A3,F5,98,E3,74,85,69,1E,4E,7D,C3,CC,7D,92,8C,84,C4,54,67,84,65,ED,AA,91,BF,AE,C2,31,22,F6,BA,88,FB,A6,9C,7E,56,34,AA,2C,C0,0F,1E,66,71,72,BF,F6,29,7E,A3,91,A2,F0,F1,15,C4,B5,3C,6D,69,B4,A9,07,E1,D3,94,0A,CE,A9,B7,64,5D,51,9B,61,01,04,98,C4,EE,73,50,08,65,A0,92,AE,1F,74,8A,F8,9D,DE,74,B8,70,47,41,D6,D9,AF,72,E4,4A,6D,84,DB,BC,B1,81,FA,08,09,FB,74,E4,C2,E4,0F,CC,C9,DE,B5,48,4A,56,B8,77,CB,76,4B,82,E1,35,CC,7E,0D,FF,94,53,5F,4F,C3,28,2F,86,7C,63,C3,CA,CB,8E,3F,8D,91,54,76,C2,4F,76,A1,89,E3,C7,19,8C,24,BC,AC,80,7B,BD,F6,BA,18,A3,C4,91,98,92,CE,F5,75,A8,C4,CB,5B,E5,BB,62,F6,87,16,32,06,F4,57,E8,E4,B6,AA,25,2F,28,27,69,10,9B,AF,B4,79,0A,8F,24,BF,E1,51,AB,72,AD,99,6B,0A,EA,16,8E,4A,4E,7F,09,2F,E1,34,6E,B4,19,9F,FF,82,BB,26,2A,96,88,8A,39,07,A3,87,C7,22,80,29,87,DE,C0,40,EE,75,EC,0E,97,1E,E9,AF,7A,9D,29,0C,63,F1,2D,E4,E6,43,A6,59,3C,82,65,50,EF,9B,A9,E6,D2,0C,D2,4B,26,A7,22,D1,F3,86,13,15,EA,C3,9C,71,DF,08,57,B5,48,F9,47,62,A0,38,CB,16,E4,7B,0D,1A,15,D8,44,97,4C,25,5B,F2,8A,00,F6,11,26,5E,D2,78,19,28,B2,22,10,01,93,8F,E0,C9,56,21,DB,73,68,EF,37,55,F0,94,00,15,67,5A,82,6B,09,0D,45,2F,30,BC,11,FB,73,AC,2F,CD,42,B3,C2,8D,C1,BB,55,BE,A0,8D,CA,0D,BD,8A,3E,E7,46,51,AE,C4,CF,16,B6,DD,AC,AA,2C,E3,76,38,26,6C,96,55,DC,98,B4,E7,71,84,79,37,F3,25,9A,34,36,24,26,18,1D,B5,28,DF,36,4B,F2,A5,0B,4E,A2,6D,10,5F,3C,4D,89,8F,5D,FE,DE,32,84,B3,55,0B,19,E1,75,17,6B,13,20,7C,29,E9,20,B6,43,12,69,E2,72,BF,B3,95,E7,5D,E9,4C,85,A7,86,CE,71,86,61,52,14,58,3F,0F,80,3C,38,44,2A,16,25,8E,0B,AE,C9,A2,94,AD,AC,00,9E,B1,E8,E3,15,2D,C0,94,4F,63,A0,8B,23,1A,7F,5A,0D,54,54,77,00,DC,43,85,0F,CE,C7,96,8A,D9,FF,0C,F4,7B,A3,32,0C,13,9D,98,87,25,35,4D,B3,D9,EB,39,D2,A4,C1,C6,11,1E,31,6D,D9,E3,8C,13,E4,98,6D,0E,1D,D7,C1,AF,AE,B2,58,B4,2B,55,46,9B,1F,14,F1,39,14,EE,F2,E6,77,AE,E7,69,E5,E1,8E,AE,F8,1D,15,2C,D2,83,9A,67,37,C7,B2,2B,25,57,92,E3,4A,81,36,6F,6C,F0,BB,D0,2D,DE,66,10,D6,1F,D0,C6,CB,37,A2,B1,78,5E,6D,F6,12,8F,03,78,8F,59,D1,BD,A6,FF,77,75,D7,28,7B,35,F7,E6,AC,8C,88,07,DE,CF,DC,76,0A,65,39,53,79,EB,5C,DA,21,0B,EF,2F,20,2A,E5,C9,DC,A8,8F,6E,D3,1E,2D,B3,9E,67,C2,03,17,24,DD,36,F0,99,BC,15,62,12,54,E9,10,00,D9,AD,0E,94,03,55,02,87,A0,EE,BB,0E,6C,99,09,46,2B,9F,DB,94,81,69,02,26,01,F7,AB,5C,43,C9,8A,61,F2,0D,A4,72,48,31,47,0F,1F,F3,A6,EE,6B,16,C3,E6,43,BE,99,EC,8D,95,1F,2E,1E,1D,16,19,30,1B,96,D0,B7,F4,FE,32,E4,6E,FC,3B,E5,91,E8,E9,61,8F,B7,A6,64,49,5D,73,89,6C,EE,03,35,EB,5A,E8,54,DA,32,C6,EA,11,FA,F7,F0,B0,74,DB,F2,80,44,45,28,8E,2F,92,C4,29,CC,F4,75,6A,BB,5F,92,8A,F9,A6,1A,6C,04,D4,87,6B,57,F2,C7,AB,DE,BA,93,CF,3B,7D,54,18,0C,BD,23,68,64,FF,A9,54,B8,DE,52,3B,4C,31,69,62,8F,D4,47,F5,2B,AD,2E,08,14,E8,57,56,0F,4C,07,52,44,E0,BA,F2,64,36,2A,85,F2,AC,6C,24,AA,FE,41,A6,6D,37,95,53,51,63,51,65,10,AC,16,97,60,C2,BD,1D,E8,7B,8C,1A,75,D2,18,2E,F0,DB,DD,C5,C9,44,41,3C,06,B9,27,CC,E1,8B,39,0C,0D,15,FF,D2,E6,1C,E6,62,01,2A,19,2E,7B,B6,5F,73,3A,4E,98,23,50,C8,E1,C3,AF,5E,E9,F1,E1,F9,E8,C5,0C,D3,79,F8,F4,4B,05,71,6F,28,3D,5A,20,B4,1F,FB,E1,39,32,BF,15,FD,8B,80,49,00,B1,B3,AF,67,4A,0C,EF,CD,81,7B,04,F8,A2,EE,03,DA,C6,C9,F4,DC,07,10,FE,79,D2,2E,F4,E2,8E,CE,80,16,C9,23,23,E1,A1,7E,14,7C,CB,35,9E,78,97,D6,35,0F,71,F5,BB,77,95,BC,D1,EF,93,7B,C3,C3,D7,42,50,BA,C5,BA,36,11,42,AB,D0,6F,5B,BA,A4,2D,5B,9C,59,E4,17,F2,F6,1C,B0,27,3F,03,24,96,D7,B0,38,17,E2,41,DA,68,1F,C1,13,5C,D2,3F,E9,5B,E6,0F,F2,13,99,14,31,90,E5,AA,62,D9,F8,B4,CA,59,18,43,A5,FB,95,CE,E9,52,2B,91,5A,AD,50,A4,76,2C,89,D8,64,80,FA,DA,5B,CC,F7,0C,E9,31,9E,95,39,A7,A7,20,ED,52,63,1D,A3,4C,A6,E3,CE,A6,34,F3,C1,52,75,44,8C,43,6D,D9,E9,49,9C,CD,5B,52,F1,C8,BC,86,57,A7,6B,B4,ED,F4,5B,37,D5,BE,49,BE,6B,E7,7E,6E,65,26,7F,61,B7,15,FE,50,F0,3C,DB,43,24,2E,F5,06,C7,D9,8F,E3,A5,61,E2,1E,0C,25,0D,4D,95,A9,46,0F,77,26,74,42,B4,F9,EC,F5,D1,5F,3F,F5,92,3A,EC,C6,10,96,9E,5A,3A,4F,1F,68,34,E8,DE,68,E3,60,A5,34,4F,F4,A3,63,35,05,48,48,56,83,A2,3C,EF,09,46,04,B0,36,12,BC,03,BE,09,4C,8A,70,7B,75,95,0A,95,15,92,B9,68,17,BE,13,24,3F,37,C5,28,62,4A,3A,BC,97,A0,F0,C9,F4,FF,AD,3E,C6,EC,D1,42,DF,81,67,D4,2F,D5,50,88,EB,DD,9C,42,A1,F6,A4,C5,3B,D5,5A,DC,AB,9A,C7,DF,3C,8D,FB,90,30,A8,FA,C8,DC,5A,BE,93,28,9A,84,A4,29,BE,1D,1E,BD,18,28,F4,54,2C,8A,6C,A6,B5,9B,0B,BC,B4,AB,78,61,2C,42,A5,DF,B4,B3,DD,B0,27,3F,DE,71,37,4A,0B,FA,87,B4,BB,59,99,19,C8,5D,1B,A9,CA,02,8E,C0,22,CB,A6,68,6E,03,FC,09,CF,49,92,FC,F3,DD,96,C8,50,E2,17,E7,1C,DF,F1,7A,A0,E3,E2,13,9F,95,47,ED,E3,1C,EF,91,D2,B1,0B,53,05,8B,CB,8F,A2,CC,68,E5,DF,E4,3B,B7,7E,66,BD,3C,6F,DC,87,32,C4,91,72,FD,2F,35,B3,35,0D,4B,26,57,FF,91,D1,82,BF,87,7C,74,A9,51,B7,B8,2D,3A,77,FE,5B,B1,5B,1C,7E,FC,9E,0C,32,92,00,D9,CA,1D,6D,53,92,B4,72,54,5C,B2,7D,41,1B,EF,46,86,3C,4A,AA,1A,82,83,75,E7,2B,D7,04,0A,86,0D,DE,45,97,3A,F5,05,9B,B0,77,2C,16,AD,4D,16,63,36,3D,DE,83,D8,34,D1,F0,D6,9B,94,99,74,3D,97,E8,5A,40,59,27,21,B9,C3,22,F7,A8,C4,20,20,4F,D9,A2,74,36,14,28,35,0B,9C,82,4A,43,1D,FF,7E,A1,86,73,B2,4D,E1,77,48,91,CB,D8,80,75,F8,62,08,6B,B6,A6,1A,54,1C,BC,3C,F4,26,73,27,DF,59,DA,F9,FA,B5,F4,1C,6C,79,36,66,71,52,0D,89,2C,38,B8,EE,79,E8,47,5A,94,59,C2,5D,84,81,E7,90,75,31,7C,40,8F,20,57,10,03,70,26,92,04,60,81,CC,81,85,9D,E7,58,D5,D8,FB,17,EF,77,5B,86,82,BC,1E,F6,8B,B2,D6,BC,69,59,AF,2F,ED,23,43,18,88,04,A8,A0,B4,B0,87,1F,B2,DA,86,47,DE,DD,53,6A,9F,C8,57,DB,65,13,28,58,17,E0,B0,6B,24,43,2B,ED,E9,4F,FD,81,6E,F0,17,64,4C,C4,E9,43,85,AD,A2,33,1A,DA,7E,2A,7D,03,29,F3,1E,87,26,DD,9A,18,7C,A7,F0,D0,78,24,FF,48,F1,74,A4,E1,CC,8E,02,58,5C,67,2B,F6,DB,AD,11,0A,7A,63,3B,6F,33,DC,69,87,07,24,10,9C,08,5F,37,81,96,0E,EF,8D,B2,15,01,50,89,90,85,FC,BE,3C,1A,23,D4,8E,83,25,13,19,65,EC,B3,62,9B,DF,CA,A8,92,E6,7F,C4,D5,94,CF,7A,75,EE,99,19,C9,4A,BE,FD,43,66,70,F1,5E,BB,34,C3,2F,7E,12,1A,CA,27,A8,FE,1B,5B,CD,18,33,B5,D4,95,46,84,6F,FF,A3,FD,71,95,64,79,89,97,ED,34,73,97,00,3E,66,28,4F,B6,7A,63,E0,EA,F6,CC,7B,35,C9,9C,4D,F3,67,CD,6B,8C,DE,02,2A,B4,28,2A,68,47,ED,81,E6,DD,2B,CF,AC,7A,54,A9,8D,19,36,CB,38,9F,8B,89,B4,EA,86,D2,87,58,21,F3,97,9D,67,7E,79,C0,48,4A,6A,81,13,EE,D1,10,17,18,CC,A9,5B,E6,8D,B5,25,9F,D0,75,08,8D,C9,6E,16,6E,85,AB,0E,1C,38,41,5B,57,46,D8,BC,4E,9F,AE,ED,F1,06,AF,C1,F0,EC,1F,4D,B7,78,C6,9C,A9,67,D4,A6,D4,5E,DD,E5,E0,69,8A,9B,B2,18,4D,0B,CC,4D,75,2A,2B,BB,77,42,2E,1E,E4,52,84,D8,F1,B0,76,77,B1,83,3C,89,9B,CA,72,AC,74,75,F7,B1,0F,31,09,75,20,61,B1,6A,41,A7,2B,72,1E,81,70,F9,0A,9B,31,A2,2B,9A,F0,D1,0E,82,3B,6D,84,2F,54,10,13,F8,74,1E,E9,22,88,79,BB,EB,01,87,88,C9,C7,26,09,B5,F1,53,B9,A3,20,06,7B,77,31,33,5E,5F,D0,FC,3D,96,17,43,DF,78,89,CE,A1,11,D8,75,3C,EF,66,2A,75,63,90,C2,6A,E4,DA,43,32,57,BB,2F,4A,C4,4C,AC,31,62,6B,8C,39,4E,E2,8A,B5,BC,CE,4C,62,4A,ED,E2,0C,C1,5B,3D,E9,9B,07,5C,5E,4C,05,88,9D,61,D7,52,97,CB,A5,30,AD,9A,80,68,2E,99,7C,48,37,7D,4A,82,EE,08,07,A7,F1,CF,BD,92,43,18,5B,D1,94,85,B1,94,2C,09,3D,F7,F6,7D,16,67,F4,5E,C4,6D,59,D8,47,A2,EB,E3,46,C9,51,ED,3F,14,E0,5C,2C,BA,FA,07,24,11,E3,F2,0E,50,3F,24,46,39,FB,0A,74,73,A1,A3,78,67,6A,DE,DE,CF,7E,7A,2C,98,DB,49,EC,FE,26,27,BD,2D,3D,6D,AC,1B,40,C1,75,E1,43,90,F6,6E,CD,9F,E5,A8,DC,89,83,40,26,3A,32,40,36,80,57,2F,DA,4C,BB,C2,66,B5,52,71,B7,27,F8,7E,AA,94,EA,3F,BC,7C,F3,8A,40,CB,BA,1B,2C,4A,39,13,FC,1D,C0,24,D4,A4,55,70,72,94,0E,D7,B0,62,0E,73,CD,79,7E,83,97,B9,53,A2,48,F5,FE,14,62,F7,51,D1,F4,AF,27,CE,52,35,10,E9,3D,F3,93,18,D9,79,E4,0C,2D,59,C0,BA,77,24,52,00,7C,A4,9B,88,A4,C0,E1,FC,54,FE,45,87,2B,C1,E6,2B,95,AA,45,B8,8C,7E,CA,28,5C,1C,6C,F8,FC,CD,73,23,7B,60,CD,62,34,E9,E4,06,FF,85,67,C0,94,BF,0E,80,53,41,0E,EA,11,13,51,62,06,50,B0,65,47,E3,58,D3,7F,57,A8,35,B7,7F,8E,93,A9,01,78,24,F2,56,90,A1,B8,23,F1,4F,23,CE,E3,71,3B,A3,09,6C,6C,05,E5,34,9D,09,90,0E,4B,99,07,03,6F,D9,93,A0,19,25,B3,FC,5C,52,BE,CB,45,67,EA,00,80,EF,3E,3A,70,89,C7,8C,9E,C2,EF,27,8A,DA,7A,11,63,32,C0,92,9F,55,38,B8,7F,CA,CD,7D,C7,A2,28,2F,A3,3B,6F,55,0B,18,A4,FF,33,C9,02,8A,A6,29,A9,F0,D2,45,72,71,2C,66,17,D9,32,AA,B3,F4,C9,F0,73,17,00,69,93,85,C0,26,DA,DE,44,27,23,F2,A0,EA,0E,8E,DE,38,AA,0F,5E,CC,7A,7A,A5,04,B0,03,57,2F,DD,DD,00,D6,BF,D4,BA,0B,28,08,96,5D,FB,3A,7E,94,23,FD,52,D1,C9,A7,C9,8B,65,6C,FB,C7,59,66,AF,9E,DA,7C,FC,AA,A7,5D,8A,9A,31,88,EE,86,98,C3,1B,22,73,55,F0,C3,FC,38,88,DC,AA,C0,8D,E8,BA,AB,22,51,0B,A7,71,90,BB,48,26,85,A3,1C,1D,98,91,D8,B2,92,FE,7F,E7,B6,20,17,F1,D8,12,3D,19,23,AA,F4,EC,6F,34,AC,96,C6,DE,C6,EC,B6,B9,27,3A,0E,DE,5D,30,D5,9F,F5,F2,29,DC,18,0F,B1,87,A3,42,D8,53,6A,D0,5F,BF,6D,BF,8E,AD,76,FA,30,BE,16,36,61,B2,D1,49,43,C1,11,9E,AF,A2,C5,63,D0,29,62,D8,38,CC,71,A4,DB,2B,4E,9A,97,28,DC,E7,04,27,44,07,30,78,EE,50,DD,01,3A,FF,51,1F,F1,A7,B5,C7,31,42,63,89,28,71,B0,AF,B2,D2,2B,5E,B5,F2,F3,E5,F2,DE,02,43,CA,46,EA,05,65,49,F3,76,CD,FB,7F,BD,66,C2,37,6E,75,57,9F,07,1E,3A,F7,80,8C,3B,BF,FC,31,00,6D,53,1C,B1,A4,F9,73,6C,8D,03,F6,DE,96,91,09,A1,3E,13,79,19,0E,54,0B,85,23,18,0B,7A,61,87,46,44,C5,14,BA,64,85,8A,57,01,FE,23,DE,9F,E3,49,9D,28,6B,13,A4,8C,57,4E,B6,C8,B8,EF,10,51,7B,B6,19,C0,24,22,FB,67,E9,94,7C,C7,E9,D6,D5,D0,8A,62,02,B2,9E,32,74,DA,A0,73,B0,8C,0C,30,15,7C,38,52,93,25,D7,31,EF,8F,55,BB,E7,5E,06,1B,2C,02,87,A1,6A,04,6B,1A,66,6B,16,84,F5,99,CF,CD,4F,62,BB,36,96,3F,27,43,C1,EA,28,74,C7,DB,B9,83,1B,C2,D6,EF,14,A3,83,A6,8C,00,61,B5,6E,69,F7,CD,BC,41,A8,17,6D,E6,19,DE,71,0D,81,E5,C9,3E,45,A3,25,4B,6F,24,9F,40,82,79,97,4F,62,91,AA,7E,06,D8,3C,36,68,C5,95,93,8D,1C,69,51,25,BD,15,C8,A0,D8,04,93,90,66,17,FE,E0,6E,34,64,8A,74,30,CF,EB,49,E9,EA,44,4B,61,84,DB,1D,37,26,D3,90,77,09,18,3B,E8,13,D6,AB,EE,D9,98,4A,BF,67,AC,C5,13,7C,9A,F8,E3,DA,28,90,39,ED,D5,14,23,DE,BC,69,15,8F,D2,EB,EC,13,0F,46,42,66,91,BC,CB,C2,FF,70,34,69,A9,EA,3F,EF,DA,B0,10,92,45,B4,B3,C3,3F,E5,E2,A1,CA,1F,EE,4E,2C,D9,87,48,2E,D8,9B,FA,F8,BE,CD,CD,FC,A1,52,77,35,0F,99,20,B7,89,F1,C9,B0,C8,48,25,7A,1D,FC,6B,C3,9F,A0,A5,E2,1E,C2,94,C5,3F,09,F6,88,EB,4C,EB,8E,1C,AA,0B,A5,64,36,A8,6C,EB,80,7D,57,2A,97,74,A6,BB,B0,4C,1D,15,DE,6E,C2,AF,D9,6E,CA,3E,32,69,72,6B,88,C2,BD,38,7F,E3,63,5E,85,44,E9,5C,D7,26,A1,C1,75,C1,A6,9A,FC,BE,7A,52,4D,EC,D4,A0,27,E3,FA,1B,16,C4,51,9A,BC,A2,62,E6,44,45,F9,6F,E1,EE,D0,78,15,7F,B1,74,E7,C6,6E,DC,AE,7D,B2,E6,A3,47,8C,EA,D0,D4,18,2A,ED,D0,24,8B,B3,5E,55,41,FD,6F,B6,8C,D2,80,EB,06,3B,1A,AD,F9,60,B3,90,39,16,77,A5,75,2D,D4,F1,8A,81,7C,48,41,5C,BF,07,65,F9,DC,18,08,A2,D1,27,81,CD,74,F7,63,D8,FF,1A,7E,3A,AF,BF,DD,A1,B0,82,85,C5,84,86,18,3D,F0,22,BA,CD,1F,4E,57,6A,36,C5,D0,C4,D6,40,F4,B3,E4,8E,95,10,59,A4,58,61,DA,EF,A5,50,0A,78,BE,67,24,12,5E,D4,A1,3D,57,1D,57,93,9B,4C,41,C5,79,D0,F8,10,54,98,F4,51,86,44,0B,02,81,43,BA,5A,C1,28,9B,B4,AD,40,8D,7B,8C,DF,D3,9D,64,BE,C0,7D,38,AF,BA,D5,B7,20,90,53,8D,6B,D5,7E,C1,84,E0,DD,A0,18,86,CE,61,DA,A4,12,0A,05,8D,C6,DB,B9,69,5A,6D,F6,F6,52,CC,22,11,EF,19,93,78,E2,E8,EF,0A,69,B6,91,60,9F,DC,7B,77,33,CF,C2,CD,75,F9,5C,62,04,17,67,05,41,65,43,95,CC,A0,7B,96,F4,DE,57,87,D9,AB,F3,3B,C7,EB,2F,E9,32,7C,18,B7,16,46,79,3D,B0,24,7B,59,E4,C6,79,21,F8,EB,C2,18,1C,19,F8,EB,66,A8,51,7E,F3,9E,8D,93,02,78,88,B2,2B,EF,52,2A,14,77,5B,B6,3B,AC,4E,55,FE,B2,97,A0,07,4A,93,09,9F,FA,81,1C,8D,88,5C,A4,21,C3,BD,C4,8B,96,F2,EB,16,5C,C8,46,AF,AB,06,93,7A,B8,19,37,A8,2C,03,15,14,CC,D6,A5,07,B0,21,B3,3B,21,0C,A4,9E,D9,CD,8B,34,3B,B7,73,92,EE,E3,87,61,77,21,FC,15,F1,C2,B2,1A,C7,A0,57,5C,21,79,87,B5,64,F9,80,B3,56,7D,11,A1,A5,EF,2A,73,C1,B6,C2,74,8F,3A,D8,D0,AE,52,06,06,3E,F0,B9,5D,83,4B,81,32,27,75,EE,DC,AE,CF,C9,32,65,44,68,F2,E7,3D,21,0A,76,EE,BA,B7,2B,36,DC,FA,87,35,E1,F9,75,92,93,D0,3E,1F,BE,5E,09,6B,19,F8,D9,D0,D9,21,53,0E,9C,8B,FD,F5,A5,04,9F,6F,58,84,1D,E1,F5,21,7D,E1,DA,44,EB,5C,00,51,D9,6F,47,63,58,6D,EA,F5,67,76,A1,EF,43,E8,E3,B0,A9,64,67,CD,D2,62,1D,13,6C,4C,62,DD,7F,91,83,8A,FA,FD,52,12,62,6D,86,34,07,ED,D5,42,6A,BB,BE,9D,2A,0B,39,88,A5,A7,F9,52,82,20,1B,36,7E,71,5E,64,05,75,83,52,DC,A9,E9,9C,BA,56,D4,E9,7B,4C,6A,09,83,97,34,6F,11,EE,54,7D,22,A3,01,1E,08,B1,6B,8E,0B,D9,49,4C,88,D7,13,79,47,1E,9B,0E,D1,B7,A3,EC,56,6C,C1,8E,A7,B5,DA,26,1D,EF,77,DF,BC,FF,4F,5B,46,37,62,77,E7,7A,BA,D2,E6,A9,47,F0,95,84,91,0B,9B,28,5B,51,5E,C5,EF,7F,C0,D5,D4,1E,D9,33,2C,25,1E,6F,F2,03,63,1F,C5,6B,23,B6,F2,25,6B,A2,B0,A1,AC,4E,35,A0,C1,09,35,DC,9E,66,4D,14,D1,62,6E,57,76,77,74,F1,02,10,C5,A9,DF,C3,51,73,3E,23,F8,2C,A6,22,C1,CA,5E,E5,AD,24,D7,D8,6A,50,79,D4,83,CE,41,50,10,CC,22,DE,C6,D6,F5,95,56,4E,80,A4,34,BF,51,B2,DB,38,36,BE,F4,79,EE,D7,F5,3F,E4,92,13,A9,3E,4C,27,42,61,51,0F,65,29,71,D0,8E,3A,33,7B,C1,FE,A5,AF,DB,B0,AB,37,EA,E9,7A,70,2B,03,B2,F7,7F,85,F1,64,24,D8,C0,D4,76,6D,B9,6E,95,6D,8E,01,11,B3,58,C2,20,07,01,DF,F9,D7,A7,79,6B,18,2F,D5,45,94,37,1C,6F,D9,06,E1,28,66,1F,95,64,D7,58,98,E8,CC,B1,DA,3D,FF,4F,70,0B,90,0A,FA,22,FA,F6,D4,75,E0,BF,FA,23,EB,3C,F0,5F,D2,C1,86,AE,2F,5A,05,EE,B0,B8,52,D4,E4,0D,07,CE,74,62,24,DC,07,4C,A2,B1,9E,74,21,C5,D3,27,59,99,F4,17,E5,A2,CF,CC,16,BF,D1,BE,E4,A1,6A,80,36,C1,2C,B0,AC,98,CB,84,1B,6F,D7,6E,3F,90,DA,99,C6,69,F9,2D,40,1E,B3,B7,7D,0A,14,E9,01,7A,5C,71,63,31,11,07,7D,81,1E,47,FF,5F,5A,D4,66,D4,CF,1D,F6,82,75,1F,00,C6,7B,B3,A2,11,DC,EA,93,0D,B6,61,FD,D3,7C,66,01,AA,DD,1F,50,76,3D,46,A1,78,59,EE,73,9C,BF,50,3F,DB,80,6F,05,58,5C,69,58,7B,6C,00,3D,7D,E6,64,9B,31,2D,36,A4,77,47,3F,4A,6E,B3,CF,0F,F7,07,2B,E3,B3,74,E0,BA,41,9B,83,3B,66,A2,73,94,6C,E3,A6,C9,A3,D9,A9,FD,D5,B2,66,EB,D1,4A,98,0A,4C,D9,11,E5,05,AC,DF,8B,C5,7E,D7,09,98,92,E3,D8,56,CC,DA,A9,9C,FE,D7,A9,E5,AD,B5,82,09,EC,47,A1,53,9D,CA,CF,1E,54,F5,5C,A4,02,03,EC,3F,72,FB,4E,8A,A4,58,CB,A8,17,AE,B4,58,AE,1E,B0,B5,99,B6,66,83,3A,03,F8,FD,21,F1,6E,96,CE,F2,77,13,F3,3A,81,AA,23,FC,C4,4F,47,1E,13,96,2E,0E,35,CE,CA,8F,77,CF,49,F3,A6,0C,AD,B2,26,37,82,70,D9,8E,45,5F,66,8E,AE,FB,71,78,67,5F,45,22,21,6F,83,8B,ED,A2,C5,F9,8F,13,BF,1F,6B,BF,9A,54,C8,35,74,08,66,68,33,31,A1,B9,39,7E,E4,56,48,C8,08,19,1B,79,41,E2,BE,69,2C,80,A4,AB,F8,99,AC,CF,B8,ED,CB,8E,6B,98,D5,A3,B1,71,3F,C3,B6,3F,1F,24,9B,4E,1E,9A,A8,73,01,FE,10,5E,F9,1F,E7,5B,EC,19,30,56,78,0C,DD,B8,40,41,98,F3,62,20,48,C9,74,F5,4C,D0,6F,98,7F,C0,6F,9B,7C,8F,A4,6D,FF,2D,70,64,12,14,5A,19,26,60,03,A6,73,FC,BC,C0,6D,4B,A5,8F,95,97,BF,9E,DE,6B,B0,2D,0B,6F,1F,7F,DB,24,37,CF,76,26,B3,45,E7,1B,A6,51,A2,C1,9E,67,46,BE,15,E9,36,37,5B,7C,BE,A7,AA,4A,03,EC,D4,84,99,0F,43,2E,D3,25,E9,07,6D,75,85,EE,09,A5,45,35,EA,87,DB,C4,74,FD,01,80,AF,FB,21,7D,A4,33,51,18,BC,F3,D7,77,84,AD,81,67,D2,AF,28,FF,30,13,0F,18,01,94,D7,3D,4F,94,CC,1B,9C,A3,1A,A0,4C,22,3D,6E,7D,98,FB,90,D6,A6,A5,C2,73,BC,12,D2,96,6C,0C,E1,E6,39,48,EA,0A,A6,80,69,21,26,79,3F,B5,F4,1F,D6,73,98,BB,4D,6C,7A,75,C7,3D,80,22,DD,55,B5,2F,F7,95,B6,34,40,7A,9E,A6,AB,67,89,E5,45,32,35,07,A5,09,0F,AD,08,90,4E,1B,FF,39,96,C1,B5,1F,F1,62,FE,F8,2A,A5,C1,BB,F7,F3,BA,A8,66,1B,BA,D6,97,A1,93,0B,58,9A,97,57,C4,25,FE,F5,96,9A,C1,2B,5B,29,86,31,AF,F3,03,CC,8F,47,7F,EF,4D,6B,72,78,00,9D,F5,E0,1F,02,CF,33,D7,53,01,44,03,33,CB,0A,DA,90,16,00,B4,E1,C1,4D,C3,4A,0F,32,41,46,EF,08,48,92,4D,A4,B9,8E,18,C8,43,92,14,DB,EE,66,06,F2,F9,73,D2,48,B7,77,A3,F2,6C,CB,96,EF,54,E8,97,A8,B3,2E,60,43,53,4D,46,E7,72,25,D2,9D,8F,CA,01,66,F6,C2,D5,AF,F2,A5,B2,63,AD,D7,69,78,4E,F6,84,5C,B2,5D,E4,FF,3D,B4,16,C1,CC,BE,E4,73,92,7E,84,10,29,86,C2,1D,3C,AE,89,CF,5C,92,DD,43,55,C6,B5,F8,E1,17,EF,07,1E,09,BC,7D,93,3B,AD,63,DE,7E,9D,1D,98,BB,20,65,81,94,5B,A5,C0,CE,00,25,16,78,C0,AB,A7,00,64,B8,D0,98,BB,07,9E,D0,51,D2,00,D1,C8,4D,51,92,39,2D,8A,15,29,28,D8,98,87,26,F4,86,B8,D6,8E,45,41,45,0A,EF,68,3F,69,0A,90,5D,BD,F7,C4,3B,4D,9B,99,11,0E,15,1C,05,6C,51,6A,7B,19,D0,5D,F3,15,57,D5,5B,BB,93,A1,EE,EF,7B,28,4F,A7,D1,CE,B9,48,BE,BB,2B,2D,9E,F1,EF,F8,6C,74,F0,BD,84,53,71,56,65,E5,5E,74,7C,48,A7,8A,F3,3D,2B,59,B4,A3,11,45,3E,B4,FA,74,E3,21,52,07,40,BE,A8,8F,7C,08,52,B9,56,4C,07,8B,67,3A,FC,F0,E5,DB,C8,67,44,E9,76,68,B6,F0,1D,04,EC,86,FE,3A,DB,B1,D1,0C,F1,0A,16,85,91,DD,62,7C,0E,16,99,0A,BC,BD,8E,81,71,1B,FC,A4,47,17,65,9C,2A,64,22,78,B3,85,DF,76,90,02,2E,00,D3,CF,AA,FD,CC,44,08,47,E7,EE,7F,A4,10,8F,77,19,5D,29,18,4E,3E,3A,A1,A0,0A,0A,37,3F,50,5B,BF,2A,65,57,AE,FD,68,59,B4,3A,33,86,8C,64,C9,65,34,7E,60,18,C6,99,65,1F,B5,A4,08,06,F7,4B,03,98,BF,C4,8A,4D,21,B6,F2,12,59,A5,F9,B4,2B,0C,F8,42,BE,D8,54,47,14,A5,9B,D6,62,64,75,86,20,5E,82,92,42,00,05,2A,C9,33,CF,D0,33,CF,83,D8,44,7A,07,9C,6A,98,62,F8,9D,20,F4,0F,59,2D,EF,5F,1F,86,DE,22,23,87,B7,5B,96,76,3B,19,7A,8B,24,EC,A8,C0,93,82,14,18,5A,25,6E,9C,BF,35,C7,B6,30,E4,D8,4E,67,8F,86,F6,76,B9,70,B1,A8,33,9E,0A,1F,9E,E3,5C,64,10,6B,69,23,2C,A6,67,53,B5,BF,33,F4,60,A8,B0,A9,3E,C2,E3,FB,24,E5,74,C6,F8,C8,38,8D,5E,79,F1,88,72,AC,A7,26,45,BF,01,DF,04,56,C1,DB,9A,C3,75,E2,81,90,00,6D,6B,9E,31,DE,7B,31,9B,DB,52,F5,E1,8E,CD,4A,6D,E4,6B,BD,3C,95,A7,04,FE,B2,DA,C4,96,EE,BB,1D,EF,18,88,A3,41,59,A3,9F,34,04,97,7C,58,50,2B,AA,D8,E9,D2,90,C6,A4,54,7B,0C,BD,2B,B9,7A,6B,7B,D3,7E,09,2C,FC,E0,FD,11,C5,3A,00,7B,82,BA,33,5B,6D,4D,52,4C,06,EB,4C,58,41,9F,85,A0,84,E3,DA,42,0A,8C,16,6A,00,DF,67,13,4D,AA,2B,19,76,85,04,0F,5B,A0,DA,D6,98,64,A6,F9,C8,30,72,E7,BB,4D,F8,1E,06,D1,60,46,79,84,65,5A,D3,20,D2,15,A5,DF,1E,01,2D,76,4D,C8,2F,03,35,7B,68,BB,2E,E8,E5,F3,DC,4E,94,66,1C,81,63,5D,79,C2,15,4B,64,51,F3,E5,42,7D,05,24,BC,A0,77,7F,BB,24,5B,40,FE,BE,17,4B,A4,4B,24,B9,31,EB,9A,D6,6E,E2,C6,85,48,E0,AA,A4,68,EC,EE,88,8F,00,2E,74,82,94,36,4F,9A,08,03,D1,14,7F,D2,18,43,B1,29,0A,F3,5F,F5,E0,41,FF,45,AD,3F,FC,03,F2,C5,30,CF,CB,44,FD,F9,16,4D,DD,E4,03,9D,AA,3B,6D,8F,04,8F,53,93,F4,48,E0,73,17,25,E8,30,F9,B2,8E,E8,12,5A,0A,11,45,C2,11,47,E1,18,A8,43,4C,32,7C,E4,FF,47,07,48,1C,73,4F,54,59,16,9F,E2,FF,19,5B,BD,94,EF,CC,C0,01,82,52,62,58,A6,92,68,A7,64,D9,65,B9,51,68,45,BB,4C,E3,A0,F4,6F,94,00,C1,82,FB,9E,3C,0E,1C,67,87,11,B7,F9,68,59,F9,22,A9,ED,B3,86,31,CF,64,1D,AE,93,DF,9D,3E,24,2A,90,C9,D5,72,36,46,46,8B,26,E9,75,1C,B1,90,FF,FA,37,B7,11,58,75,13,0F,C2,4A,4B,56,50,A5,D3,92,FC,C0,52,6C,62,49,28,26,07,0F,24,FF,E7,BC,14,6C,88,AD,3F,90,4C,28,6F,0C,97,60,76,37,E8,08,0E,F1,E9,57,39,2A,C8,61,FD,58,45,5F,64,CA,38,6B,1A,2D,F0,74,00,85,F6,C3,5C,79,D0,8A,44,4C,DF,D3,15,BE,94,0B,69,84,BC,79,26,56,B2,E9,0A,FA,31,69,7C,A1,E5,02,C5,FF,D7,60,C1,F7,FC,55,6B,63,1F,68,6F,D2,41,D4,0D,77,93,6B,FF,31,C3,AE,3F,1F,A1,D8,0F,66,1E,92,4E,6F,4B,F8,20,D7,3F,72,35,C3,71,D8,63,7C,81,12,9E,99,2A,D3,42,89,76,BC,E9,4F,DF,D9,B1,1D,97,B0,1D,BC,AF,D7,8D,0A,9E,A2,5A,73,7A,CB,DC,11,17,87,36,32,17,7B,E0,17,2C,46,99,C6,61,7A,9E,29,32,FB,DF,9A,8A,C7,F6,91,AB,F4,F6,F8,E3,C9,95,66,1F,AC,38,20,37,3C,E8,CC,4A,DC,89,40,95,6B,19,FF,7B,1F,16,A3,7F,DA,83,70,30,A8,AB,44,FD,5C,10,9B,04,FC,13,4F,30,8B,2F,72,A3,33,AF,46,7E,0D,54,B7,E4,26,28,09,BC,FC,36,9F,52,D2,50,B2,FC,2D,ED,6D,AF,5A,B2,F8,4A,A5,8E,97,8E,D3,B8,6D,57,33,49,EE,10,6E,69,3D,A1,86,F3,09,F9,EF,22,C4,57,5C,C3,0A,63,3E,BC,D7,E6,0A,84,85,EC,4F,5F,09,E1,DD,10,8E,FA,34,9A,3B,A9,8B,13,67,DF,B7,8D,7A,C1,82,E6,4D,E0,97,95,ED,52,68,4F,C5,BD,13,40,85,DE,96,76,34,65,17,69,36,77,6B,66,D4,64,AD,9B,AB,87,64,37,36,04,BA,5D,D4,62,2C,5B,FC,D2,9D,30,BE,27,73,43,20,7F,DA,11,90,3E,13,A9,1E,0F,97,FC,A0,9F,AE,03,A7,5D,34,B4,7E,F2,64,63,3B,04,11,18,22,A2,92,15,8F,BC,B6,E8,2A,53,9D,31,46,64,4B,11,BA,06,D1,E4,0F,17,E7,7F,8A,DC,96,24,A0,64,56,E2,58,00,63,F4,1B,D2,EA,4B,84,68,1A,D0,C6,49,E6,C8,70,EE,20,BC,CB,9C,7C,B0,30,51,78,7F,43,62,01,1B,3B,8C,41,2B,21,7E,58,99,EA,2C,3B,6A,8C,27,83,2A,4E,45,B1,88,A0,47,84,4B,FB,CC,A8,76,D0,0A,BE,55,42,57,68,73,13,93,2A,19,A1,47,C5,F2,45,EE,83,C5,40,E1,D6,05,BD,03,2C,6C,AE,A1,E3,C7,24,31,2B,53,58,C5,A1,42,84,F4,D1,6C,54,33,9C,9E,DC,43,F5,1C,C1,A4,85,B9,41,39,A7,92,CD,3D,EE,DF,0D,EB,36,AA,F0,A7,60,A6,CB,A5,37,3F,05,AC,2A,FA,6E,0E,99,09,EE,B2,CA,D4,1E,E6,3F,50,EF,C9,61,64,B7,49,4B,4A,D0,C6,10,E0,C5,1D,B3,F0,37,43,D0,06,E4,A1,E8,16,B1,25,4C,07,41,EB,67,3E,F1,4D,5A,6A,5E,35,4D,91,C6,7C,EE,95,24,36,9B,45,EE,41,CE,EC,8C,48,33,2D,96,36,E0,F5,23,65,BD,7D,15,67,7F,6D,FD,7A,98,38,53,1C,9A,BC,DF,7C,E3,60,1C,C2,E6,74,57,34,5A,8B,68,E3,07,A4,98,69,8A,8D,18,D8,CF,F1,26,B1,74,C0,91,8A,8C,0D,7D,F6,0A,42,BB,E9,7B,03,C2,CD,FC,31,A8,5C,F4,05,14,7F,B6,72,0E,F4,48,9D,2B,B7,C6,06,13,51,B4,1D,13,91,DA,03,A8,D1,13,01,FE,6A,C7,D7,D1,FC,54,37,13,81,37,56,3A,5A,9A,0D,CF,F8,9C,59,57,68,F3,7F,55,06,A6,85,F1,9A,4A,BF,BB,13,F6,89,AD,C9,77,5E,CD,1B,6A,47,FD,CF,4C,BA,9B,4F,72,43,9A,D0,71,FC,FE,29,AE,EB,4A,0C,A3,5E,D2,B3,F4,D9,26,E4,C9,05,12,9A,6E,29,B3,C6,40,BC,51,FF,BF,E3,56,28,59,5F,77,B5,70,2D,D9,C6,5C,7F,27,69,28,33,D1,06,9F,69,10,EE,93,85,ED,18,43,FE,09,A4,B6,4F,2A,FB,7A,31,0F,95,53,ED,43,BA,37,AB,C9,6F,FB,25,CD,C4,01,80,CC,EC,F6,D7,11,AD,52,CA,57,98,AB,5D,00,9C,78,25,CE,55,F2,3B,B7,37,62,55,DA,DE,BE,E3,C2,4C,22,17,93,65,16,1E,DC,D1,15,9F,54,42,D4,82,3B,01,1E,E1,83,AF,76,87,52,FE,A5,D2,92,07,5F,99,EF,C6,58,6C,62,0E,83,42,79,35,67,8F,01,9A,21,87,56,F2,8E,D8,B9,8E,08,89,4B,A5,15,4B,74,DB,F1,4C,30,E7,5B,D3,6F,0A,1F,7D,EC,0E,C4,C8,7A,C6,54,B2,ED,D5,3C,24,38,2D,D7,5A,18,33,2E,3F,CC,9F,28,21,34,56,93,D5,39,4D,62,19,7A,14,BC,DD,F5,28,09,C7,7F,B4,0D,43,52,68,3F,D3,8E,47,8E,3C,17,87,49,62,49,D2,60,2A,CD,1E,5D,59,4E,AE,17,B5,5F,68,E1,29,C4,BE,8B,0A,AB,D4,C3,CA,A6,E1,B9,67,CE,4E,55,26,9E,89,CA,EA,40,46,97,24,4C,F4,11,FC,FD,34,92,96,42,34,AC,27,DD,3C,2B,E5,E8,CF,DE,0D,D8,3F,EA,70,D2,0F,A2,DC,C2,90,AE,1C,DD,23,64,2B,B0,43,A6,F9,36,CF,F7,D0,5D,A8,76,2B,FA,1D,A9,19,EF,EA,F2,FE,20,12,DB,D1,4E,D0,B5,51,14,97,36,84,67,F9,75,CE,FD,A0,94,AE,95,09,65,E1,6A,79,EA,7D,26,69,1B,57,71,E6,46,EB,84,5D,EF,5C,C5,67,C4,FE,59,A7,1D,B3,63,9A,47,DD,6C,6D,0D,AC,C6,A7,C6,82,91,13,91,50,92,B3,67,86,06,EF,2B,77,4B,0F,B0,A9,43,20,BD,22,43,AA,C4,31,CB,13,D9,0E,E5,25,BC,24,52,A6,FD,57,CC,CE,AC,EC,83,68,5F,A8,AE,89,94,D5,50,7A,C4,95,82,76,CA,60,B5,15,AC,28,AD,0B,9F,99,6F,68,8C,37,29,E9,81,E5,3F,E5,AE,B4,8E,C9,E5,22,0A,FB,6E,6D,D4,57,09,0A,B0,BC,81,45,41,A2,FE,EB,EF,82,8B,F3,A9,60,8D,F0,9F,9B,89,07,F8,F6,58,8F,4C,2E,88,27,E9,72,99,27,18,D3,05,29,C7,23,BD,7D,EC,78,4F,8D,BA,0B,93,7C,57,18,01,E9,CC,59,AF,E2,25,8F,95,D1,49,60,0D,15,EC,CF,37,5B,FB,18,6F,A1,7C,D9,8E,43,F7,AC,AE,18,EB,83,AF,3A,B0,D9,75,66,CA,C5,A3,68,E6,AC,31,7B,56,77,A0,26,A4,FF,CC,51,16,19,E9,38,CF,A6,BE,1B,65,E9,14,76,B1,26,0C,63,33,E1,8D,03,67,BF,CE,FB,C7,85,4F,AE,13,DE,00,AC,82,D6,62,E7,36,62,56,2A,9F,10,90,97,C7,40,12,BC,3F,4E,16,7D,24,EE,15,23,BA,8D,85,BD,B7,25,70,8A,5B,A4,FE,89,E1,66,9C,CE,41,CD,F6,A6,3B,2F,26,9A,EA,3E,97,EF,E9,E1,40,E5,76,CD,E8,9C,84,7F,4E,F6,23,77,1B,F8,28,44,FD,7C,EF,C6,CA,28,B6,5A,CC,B5,09,81,07,8C,68,40,C6,2F,64,B7,0F,F0,76,54,97,CD,AA,F9,6A,57,37,75,7D,D1,34,D2,35,87,60,33,73,03,9D,9A,D5,74,BF,DC,FC,A2,0B,02,D9,2B,E6,0B,CC,26,16,F6,2E,7F,D7,BE,5C,75,B3,26,A2,68,9A,53,93,5A,AD,2E,6F,7A,E1,ED,C7,A9,38,2A,B7,FB,A8,97,F8,8E,30,5C,F7,BE,69,F0,C3,72,1B,90,75,E8,40,C6,EF,9C,7C,32,DA,D1,7A,38,04,DD,DF,36,43,40,AA,03,0F,29,77,91,89,9F,E3,51,F6,6B,A8,27,43,65,22,59,0A,06,0E,01,14,6F,47,9B,39,5B,11,2F,E3,19,6B,05,30,DD,CA,B5,E8,BF,79,4B,BF,86,7E,FA,87,F2,EE,04,65,C8,60,7B,F1,4A,30,FC,AA,8D,73,EC,21,2A,38,4A,FB,AF,1D,9B,5D,72,05,62,2A,53,AD,16,B8,0A,43,CD,42,4A,90,FD,B7,E7,80,CB,A1,29,BD,72,63,A5,FD,72,1A,70,21,A1,03,DB,C7,AD,63,C4,9F,2D,99,4E,4C,19,FA,1F,2F,62,44,E6,D6,AA,61,86,7F,FA,F2,D5,7F,54,9C,B1,28,FC,50,8B,13,59,1B,7F,8F,F2,46,4E,79,44,33,D0,B5,16,17,23,AE,67,8F,42,4E,50,0C,B2,E4,61,B9,3E,B0,84,21,41,39,39,AA,AE,CA,24,88,C0,DA,65,FA,89,97,DD,94,F0,FE,F6,9F,1B,08,79,D7,D3,C3,70,AD,C8,E5,39,96,11,B3,7E,AC,09,2E,FB,74,4C,B4,EC,99,E8,68,A7,83,EE,F2,DE,B4,E2,A8,86,D1,AD,33,9B,B0,CC,B4,27,05,D4,7A,7A,FC,45,11,D8,01,D7,99,75,FD,E2,54,81,90,9E,5A,CF,C9,E5,FF,5E,34,D1,9D,B6,A1,E6,B7,14,03,CE,17,81,F1,09,0F,FF,69,99,27,49,BA,B5,25,07,10,C1,E3,3E,8C,1E,25,49,A6,5F,C7,9B,35,1A,C0,57,75,C3,07,41,59,66,E8,CD,C9,F8,F8,1D,4B,C1,44,09,93,54,E9,46,6C,21,83,88,87,D7,49,BC,35,44,E9,AC,45,87,E7,71,C5,47,61,EE,E1,63,BA,5E,50,13,39,85,EA,78,2C,8F,13,0A,69,BF,26,5B,A0,75,B7,2E,3C,72,D7,7B,01,3D,F7,EF,85,59,03,6F,43,08,D9,56,5F,33,A8,D0,6C,F3,C7,CE,FA,23,19,49,85,75,19,C1,CA,2E,FA,2E,62,EF,1A,06,A0,86,AF,B4,44,C5,5A,AD,BB,5B,67,FF,B5,AC,FC,40,9B,EA,96,61,68,E1,92,DE,55,23,F7,65,29,11,D9,9F,07,95,3C,D8,46,75,ED,79,05,3E,D5,13,5C,F5,DC,1F,66,16,1F,3D,CC,5E,EC,7C,ED,E4,4F,6D,8F,DF,FD,14,98,05,5C,01,C5,AE,F3,13,44,0B,BE,33,4E,4C,63,E5,30,76,32,60,7B,CB,C8,D5,82,8A,CD,FA,C4,E5,CF,0A,E3,65,CA,96,FF,1C,FD,3F,B6,04,38,C4,5B,77,14,8B,04,FA,B9,0D,EE,F8,F4,F9,24,88,7C,9C,32,09,94,B3,FC,85,BD,A8,2A,15,2B,F8,41,A6,28,A8,1A,CF,8E,DE,66,C9,F0,05,DA,59,2C,D4,29,30,1E,04,63,06,D0,FB,98,09,F6,FD,59,95,45,88,5F,F2,CE,01,B3,EE,0B,DC,4A,87,68,D8,7C,2C,6E,54,6D,68,8D,4A,82,41,4C,5B,DE,AD,B7,67,C4,80,6D,E7,31,4D,E6,91,58,7B,57,62,AF,C8,0C,F4,D6,41,DB,74,E0,67,1D,5B,23,70,2E,A7,9E,5B,91,1B,E3,10,F7,2A,E7,06,F5,7B,79,F0,F0,6C,56,64,AF,95,08,ED,01,50,3F,2B,EC,5F,F7,E3,74,7D,20,9A,EB,0A,27,55,E9,8E,74,5E,1C,EF,0B,8F,5B,CE,9C,F8,14,BE,B6,AA,1E,55,10,A5,B2,05,6A,2A,47,71,64,3E,7E,79,F8,97,65,BF,EB,2E,A6,F9,4D,68,44,48,2B,22,D9,BB,AD,D0,7B,04,AB,C0,32,0F,E3,B2,EC,08,F1,30,72,A7,C6,27,CC,8C,65,6E,F6,42,A5,61,99,7A,7D,D2,01,06,99,29,BC,CF,3E,70,A8,0C,78,1E,4B,90,51,EE,1D,13,B2,AF,E6,C2,D4,BE,26,D9,1F,87,CC,49,42,DF,9C,E5,A4,99,EF,63,A5,7D,92,3E,44,0C,D6,E1,E1,12,20,DB,67,8C,97,16,D7,CA,BB,FB,07,08,BB,63,D4,AE,2C,CF,B3,59,56,32,FA,08,EE,CE,3B,A5,32,37,53,D2,45,F2,7E,98,D8,6E,E0,E0,7B,A2,C6,CE,49,00,21,7B,5D,39,B6,BC,2C,6F,16,8C,99,EA,E7,42,A0,2F,35,9B,D0,41,61,05,FC,44,01,BD,B7,E0,04,19,C4,40,59,F8,BA,B7,36,3B,F8,10,AC,28,A6,C9,62,50,37,13,54,3B,67,F9,77,C1,97,CA,AC,5C,32,0E,16,79,46,B0,79,4B,46,D1,3F,8B,9C,2E,B8,53,59,13,B2,C6,AB,48,B7,CF,75,69,42,67,42,A0,39,14,D9,DD,71,D4,2B,A5,B5,6A,58,FE,91,2D,97,A3,13,00,A7,35,1F,CF,CA,06,5B,C9,79,14,CD,D2,5E,48,0B,8E,47,94,D9,3A,A7,88,8F,4B,F8,2E,66,F4,3C,E5,E9,1F,6C,D1,C3,74,53,54,E6,3F,70,FE,0F,78,68,B8,13,0A,E6,B2,22,DA,FB,2F,07,B3,2D,36,CF,FF,91,50,66,38,4C,71,A0,C8,4F,73,B2,AA,C4,2C,19,BF,76,69,1B,38,6E,F9,53,5A,DB,7A,4C,85,16,43,67,64,3D,11,ED,69,35,BC,FE,EB,81,BC,4A,F9,C0,CC,DF,CE,AC,A3,33,28,A1,92,D7,0D,E0,0D,77,F6,73,75,23,BD,77,16,AC,6E,BA,23,89,D1,D8,A3,BE,E0,58,3D,0F,AC,F6,7C,16,FA,B3,0F,12,0A,2B,03,E8,39,C2,F2,DC,BE,62,42,82,8B,E6,68,99,D9,DA,BF,26,48,10,5A,3F,4E,0F,5A,51,74,B1,8B,97,E5,71,2A,E2,BA,42,51,5B,DD,6E,C0,8B,CC,21,3C,31,6E,A5,8E,74,CC,AB,90,0F,4F,FF,EC,CA,63,D3,CD,31,06,F1,82,EE,43,EA,3C,AC,0B,C1,11,90,4B,E9,91,D5,66,3A,A7,28,3A,8F,8B,F4,C3,CC,80,1E,89,D4,95,AF,E1,30,D2,36,29,23,B6,7A,25,2D,3E,01,4B,C0,5A,A6,47,45,79,52,BF,DB,C8,3D,38,BE,09,62,68,34,BC,77,4D,A0,6E,81,5A,E7,C2,9A,5A,87,56,89,C3,EF,4B,72,34,A4,14,DB,2F,00,E1,4A,AF,7A,F8,A5,A5,DB,23,97,F9,62,DA,84,D5,B6,B0,07,A9,1C,28,75,A5,60,5B,16,CE,9F,EE,C9,0D,F1,51,34,D3,D6,20,A3,4D,08,6C,5A,B1,66,47,72,76,21,01,BD,E4,75,9F,78,F1,E5,9F,DB,56,79,CE,4B,79,64,FC,F1,5A,A6,BF,9A,32,58,91,78,F0,26,C3,39,C3,15,12,77,05,29,3F,29,C8,4B,C0,48,60,0F,F0,36,B2,27,70,40,CA,C9,19,23,95,B2,F9,DA,8C,2B,7F,06,34,DA,12,4D,C6,5B,0C,AD,BF,4E,F2,0F,43,F7,C1,FE,F3,D5,54,7C,FD,AC,9C,BA,1D,96,64,4D,E0,91,F8,8F,40,24,23,18,ED,B5,34,A6,09,CB,6B,28,D2,94,B9,36,11,8C,64,A6,C4,C1,1D,C5,32,99,4E,45,2E,0D,74,70,CE,70,A7,41,14,5E,18,A9,1F,0C,37,80,A6,37,D4,CA,8C,F6,D9,77,6D,4B,0F,98,21,94,F1,2C,E6,88,2C,E8,87,CA,53,7A,53,F4,F5,86,68,D1,04,A5,8F,C7,EC,89,12,20,4A,1A,FF,00,1B,C5,72,C0,3A,02,0B,AA,17,92,7E,6F,1C,E4,73,34,E1,62,B9,E3,D9,6E,26,E6,3A,A9,CA,9E,99,0A,C4,79,0D,13,ED,56,46,7A,26,18,F4,42,CD,57,98,CC,81,7B,3D,E4,1C,6D,36,97,11,4B,95,CF,B0,22,90,98,24,7B,AA,5C,46,A0,17,5D,8A,1B,2D,11,21,A5,D8,65,10,44,67,CE,C2,5F,35,E3,E2,6D,32,21,31,BD,AE,1B,EC,23,39,06,2B,0F,B7,86,3E,2A,42,B8,53,BF,8A,5B,87,8B,B3,E7,2D,FE,93,AD,27,5A,2D,BD,45,67,9F,66,CA,BE,B5,5E,86,95,BE,C2,D3,98,E0,F6,D5,DA,B2,8B,75,2F,46,D0,DF,00,10,68,91,06,9B,6D,41,90,79,AF,25,02,D9,CB,D6,01,97,4D,48,20,74,01,FD,64,DB,26,29,69,37,E6,BA,48,98,1F,FE,EE,BB,99,45,B7,A0,3D,91,D4,5E,09,C1,B9,16,25,46,82,B7,27,4D,B4,F1,1B,CE,26,F1,AC,73,67,67,AF,94,A5,84,63,6B,5A,DA,BB,F5,C2,7D,30,DD,22,AA,34,10,ED,5A,9F,39,0F,AB,AB,82,5D,94,C3,62,ED,E3,97,5D,A4,80,0C,69,36,A8,73,2B,F0,77,5E,48,2C,E7,38,E6,71,BC,E9,88,5B,92,6B,C8,39,71,34,AE,E0,AE,63,F6,9C,D3,8C,A6,37,86,57,9F,E2,58,7E,71,99,6B,F3,FA,BD,59,68,78,36,3F,DF,4F,64,CD,4D,6A,D8,8A,31,48,1B,DC,56,06,27,C6,A8,9A,5A,34,19,4C,BD,DB,14,C9,45,A5,DE,0E,C9,11,F2,CF,1E,88,6C,82,65,57,B4,CA,D0,E5,52,E0,C0,2D,1B,27,02,A9,28,9B,5A,F9,81,93,EE,FB,0F,AB,31,8F,15,AB,4A,A2,85,55,41,F5,5E,B1,24,C8,4D,F9,EA,41,28,C2,00,70,46,62,15,E7,ED,D3,92,96,C9,8E,C1,5C,C5,2D,85,D4,BE,BE,C6,F2,AB,B4,F9,11,45,15,3C,68,99,0A,AC,0F,82,B9,C2,5F,78,27,81,92,EC,BE,A9,AA,87,A9,5D,C3,84,4D,B3,D2,EF,1A,A9,29,3D,BF,88,A5,A5,BF,39,6A,DB,F2,83,4E,85,F1,37,D0,EA,67,7E,E7,9F,46,CD,57,25,1D,C2,7F,22,91,DB,75,5C,14,97,E4,F1,07,DC,92,2E,33,C0,FF,24,43,EE,E2,84,F6,A1,A0,1E,2F,D9,37,BE,D5,D5,B8,D0,12,32,EA,E8,6C,CD,17,D7,0B,E6,85,0F,F4,63,E8,EB,8D,E4,3D,46,B2,33,96,36,D8,56,A8,DF,06,BE,2E,B7,60,C7,0A,FE,38,23,E4,E4,D3,E3,59,95,75,90,42,A1,A0,AE,D8,92,9C,E0,67,AA,7A,B1,5D,10,75,79,90,C1,AD,65,BC,ED,53,4B,71,F2,90,9F,29,34,65,BA,B3,4A,3F,D7,01,57,89,71,18,BE,5D,74,CB,88,0B,15,E7,CA,9F,BC,83,5B,9D,31,A8,05,E9,A1,95,B7,DF,33,86,E1,5E,CB,30,CD,EF,B0,91,2C,7B,7B,CD,C2,03,34,26,48,11,0D,3A,C3,BA,4D,8D,49,97,1C,68,7A,6A,55,07,8C,C5,30,0D,4B,4C,6A,1C,2F,29,79,09,11,A0,26,EF,3F,84,E7,FE,14,1E,B3,D7,8F,80,4B,09,E2,AF,C4,19,E4,7B,5F,46,A1,8F,F4,B1,0C,5E,BC,49,28,41,10,56,A6,30,B4,95,42,06,88,81,35,BE,6A,5A,40,B7,13,41,8F,9F,75,32,8E,1F,48,05,12,60,CF,C5,FC,E4,FF,A2,14,B0,EF,D4,0A,C2,ED,80,22,B6,E8,C7,97,83,B1,C2,14,A4,17,5A,4E,3D,CC,6E,EA,DC,54,FA,6A,6F,A3,13,E6,64,E3,0F,13,C3,26,B0,4B,14,36,D3,A6,DA,C7,24,58,C2,83,AC,BB,A4,4B,CB,DB,9C,5E,AC,2F,F2,FA,FA,FE,0A,76,D6,A9,5A,FA,AA,B8,42,04,E6,80,D1,67,31,FB,5B,D6,68,38,0F,BC,1C,E5,17,7F,AE,77,CF,09,2D,6F,84,97,F0,BF,D0,DE,A6,E5,61,AB,60,FC,EF,A0,61,FD,80,04,4C,BA,C2,5A,C9,38,79,90,10,54,D1,4E,0E,E8,93,3F,A9,19,E6,2C,CA,17,85,89,70,99,06,B1,62,64,BE,F7,97,7D,BF,3C,CF,ED,58,D2,94,CB,D9,4C,3A,24,A0,48,97,5B,69,16,51,87,26,72,2D,7C,E4,56,5A,01,C8,B5,01,9A,F4,F8,0F,B4,5C,E0,6D,51,95,A3,0F,15,E3,AB,0E,AB,A1,C5,55,D7,AC,0C,18,28,C5,52,F2,DE,7A,A9,A0,E8,93,D4,73,71,DF,11,66,F9,01,80,93,8E,88,76,B9,29,18,8E,F2,B8,AB,C2,C1,CB,5B,91,1E,7A,D5,40,AC,28,1F,A0,55,40,D4,F5,55,00,FD,AD,00,84,17,29,C3,EB,F3,56,B2,6E,AB,FB,D4,36,C3,37,01,F8,BD,91,CF,6A,85,A4,B5,56,4A,FD,B0,53,41,67,BD,2D,AD,D7,10,F2,66,75,F0,DC,BA,BE,99,01,91,11,F1,FD,7D,CC,9A,E0,D2,97,52,A5,E0,72,62,01,59,CF,73,36,30,F7,D9,8C,89,BA,29,39,AC,4D,5B,58,FD,1D,AD,EF,8D,3F,59,68,B1,36,78,3F,4B,4E,7D,51,21,EF,C9,9D,11,3E,E0,D2,60,AC,8C,E5,01,43,03,FC,0E,6D,98,65,90,BF,B5,BB,9C,31,42,16,AD,B8,0E,2C,86,A6,CB,74,A5,B1,D7,6F,DE,D6,06,37,EE,E8,B8,84,9C,43,1F,18,CE,F9,0A,2D,60,20,B2,B6,2E,76,E3,69,6B,EA,5E,A4,CA,2C,A4,0A,91,37,A7,C8,77,28,A4,C6,F5,00,34,77,09,DA,9A,4E,BB,1E,F0,B3,E0,F0,CF,F1,75,CB,4B,19,34,1B,62,DD,2B,7F,82,9E,CF,5A,35,74,6C,AE,70,C3,84,7D,E8,AA,7F,78,79,13,5C,CD,29,65,3A,9D,C8,AD,9C,2D,19,82,66,04,EC,1E,9F,86,85,31,82,CA,A2,66,7C,63,4E,3E,90,05,07,90,7C,19,DB,F3,1E,DA,C5,DE,08,BA,89,F1,95,95,E8,F8,25,1A,62,8A,20,50,09,43,6A,B4,C9,18,18,77,30,CE,F7,E5,D3,8B,97,71,C2,4C,5F,17,27,29,46,2B,22,C1,66,A6,F1,B6,99,BE,5B,D1,F3,EB,E3,73,DC,7F,CE,75,83,D6,B7,C4,E1,EE,73,5C,BB,42,6B,92,71,86,5B,B8,1E,20,07,6E,55,24,52,3C,F7,80,1B,C9,DB,7A,4E,D3,52,8D,5E,B5,9A,8C,6D,DF,55,EC,6D,5A,93,0E,C8,43,56,03,00,BB,4F,4B,14,63,AF,F3,DD,14,71,88,07,BD,62,29,86,91,72,B0,80,82,51,06,52,18,10,33,15,AA,E8,C9,27,D0,7C,1B,15,82,3F,8A,AC,1F,DF,1C,5A,E8,12,11,87,6B,E8,E2,C9,65,39,7F,BC,19,E3,AC,EC,E9,7E,9A,1C,A7,E8,74,FF,8B,32,69,41,6A,61,33,50,50,2C,F2,42,0E,28,D2,F6,AA,50,94,9B,D3,FD,2C,0B,46,81,7A,71,11,69,19,F8,9D,C8,FB,5A,88,B8,94,2E,18,04,FD,72,1D,AC,C5,67,83,C8,E4,F5,37,56,29,A3,EB,22,77,A2,CC,C5,FA,BD,82,97,34,30,4E,4B,96,6E,F9,AD,87,66,06,38,2D,F8,7B,F1,72,B2,73,48,40,2D,7E,E0,4C,A4,2C,E4,2C,4D,26,2F,80,F4,03,2D,74,9F,83,6E,74,18,90,98,6E,03,2C,E7,76,9E,DD,E6,B8,21,6F,E6,35,A1,FA,E0,87,87,8F,21,47,37,3E,C7,74,4F,ED,1E,46,E0,03,EA,A2,B2,0E,74,6C,C2,3D,1B,B7,C2,76,4F,27,09,E9,63,DD,C5,50,E4,7C,D7,7E,31,E0,A4,52,31,65,FC,E8,3A,C3,CA,B5,C6,C1,4B,DB,DE,70,03,FA,48,D7,A3,5C,F5,8A,99,DC,EC,F3,5C,75,3F,27,29,CC,DB,7C,02,AF,82,E0,80,81,79,87,ED,A5,D0,6F,38,01,39,6F,17,C4,9D,D2,9D,32,E6,FF,02,05,37,5A,E9,CE,5B,A6,2C,A5,30,D8,73,C6,8B,CC,E2,05,7D,53,55,49,1F,A3,D8,B6,83,82,8C,26,F5,54,74,22,77,09,F7,0A,C0,9E,D3,C1,FC,B6,3D,D6,FC,7E,AE,6D,A5,12,F2,CA,27,C1,88,1B,32,61,22,70,39,88,41,F6,74,78,07,53,79,2C,7D,CA,13,69,50,73,6C,27,76,49,98,3F,59,34,F1,F8,64,7B,55,17,48,D9,60,BA,86,B6,4C,27,63,33,0D,41,E1,E9,66,81,BC,58,6F,14,BC,8E,A5,5A,C6,25,01,0C,71,32,B5,02,CA,5D,98,7F,71,74,A8,20,A2,98,46,DC,C2,B1,DD,0F,89,78,B7,1B,45,63,DE,60,79,B7,07,65,89,B2,19,B3,F7,CE,94,5C,D7,C5,71,67,B4,86,79,21,9C,C8,03,FD,AD,54,09,BE,B6,66,10,65,B1,D0,CE,07,F6,48,B5,83,36,22,D8,6E,9D,27,C4,C3,72,AB,3E,74,45,05,02,BC,71,5A,16,DE,77,EB,6A,87,45,8A,AA,7F,A8,0B,85,69,36,F8,3E,AC,2C,DC,55,62,BF,77,72,0D,F5,FA,48,A4,6A,B4,AF,83,E7,02,4E,3A,1C,6A,9F,CA,39,46,F7,22,FD,5B,0C,11,98,E3,71,75,38,AD,6F,E8,64,D9,06,65,B9,77,2E,39,B6,29,B1,CC,D6,38,FC,78,1A,33,3B,F6,26,ED,F8,1B,AB,CC,F4,45,DE,4A,E6,8F,E5,CA,B9,31,7D,F1,AF,AC,A0,3D,0E,58,E2,F4,DD,C1,E5,ED,76,34,11,EE,6D,BA,F1,FA,32,63,B6,D2,03,96,C7,38,B4,B6,A0,D6,A7,86,D1,8F,FE,59,ED,DE,F5,24,F5,5B,56,77,29,39,73,6C,21,FE,8E,C2,0F,30,FE,06,31,60,34,1C,D2,85,8A,2E,12,83,A1,60,E1,40,BD,82,15,3E,2D,48,A0,87,E7,D3,4E,D5,FC,0B,2D,ED,79,02,0A,2F,0C,82,03,E4,D4,28,3B,66,EE,86,3B,7A,B9,C0,ED,6A,E3,9C,CD,03,67,85,26,90,D2,61,FB,E0,14,6E,C1,6C,22,43,49,DD,C6,0F,90,F7,4A,51,AB,A6,0F,CE,18,EA,8B,2C,67,E5,06,2B,E2,8C,A1,9B,C5,EB,B9,74,81,97,E3,A6,84,7E,41,28,17,17,96,31,CF,4E,8D,0B,66,25,FB,B9,CD,2A,A4,BD,EA,B5,07,B2,EE,AF,73,DE,9F,96,FB,B6,54,05,28,CC,91,45,AF,90,CA,78,6F,D0,73,71,8F,6C,90,0D,83,CD,B0,02,0D,18,B0,F3,72,68,68,96,A1,55,93,32,13,45,0F,BA,AB,95,D8,FB,AD,FF,A9,18,57,47,EF,1C,CE,25,5B,41,0C,88,CE,0A,BA,9E,8F,96,B6,F2,46,95,3C,22,C3,7A,5C,97,B8,CC,23,6D,A7,B7,D9,59,A5,48,0E,25,97,B2,7E,BC,19,C8,F5,15,7E,7F,E1,20,EF,B9,2F,9F,7C,6B,04,D5,6F,51,28,D0,E9,0D,B9,B5,AB,0D,A4,0A,B8,E4,59,5A,E5,40,18,A6,C3,0D,E8,CB,4D,CF,51,2C,60,16,71,8F,58,1F,2D,F1,45,94,FB,C3,80,7D,99,24,E4,6D,2B,23,19,5C,5F,C1,61,1D,F3,C4,E3,41,58,BB,21,37,7C,C0,9B,25,18,CF,74,1B,34,D7,81,C0,62,B1,C4,F1,B1,A8,24,47,91,AF,A3,B6,60,89,EA,AE,37,F8,45,8E,68,70,1D,DF,B2,E6,D2,B1,4E,B4,68,9D,26,BD,C2,D6,6B,2B,0A,61,27,84,DB,FC,8C,FA,78,DD,C0,24,B2,BA,A2,44,C3,EB,47,5A,2A,3E,19,28,81,32,D5,C8,56,21,D8,F7,EF,71,E1,4E,BD,F0,E0,B5,FF,42,4A,7C,81,B2,22,AF,A8,6A,27,AC,0F,7E,73,8E,DE,2A,E4,05,A5,99,81,E8,1B,0E,1D,A7,7F,6C,CC,B9,CB,DB,7C,8E,14,04,F0,8D,D1,AB,16,02,A2,20,32,29,ED,3C,0C,B4,54,61,8B,E9,2A,CF,5B,9A,A0,A8,E4,DE,13,79,75,1C,5A,24,59,3D,5B,2C,49,C4,71,79,03,3A,40,47,0B,3D,10,C3,8C,78,02,C2,A0,D8,01,8B,17,0F,0C,52,DC,D3,54,80,62,D6,50,0D,9A,A5,CE,A6,87,88,C5,57,82,2C,7C,65,6F,70,66,69,76,BA,BE,77,D7,78,EE,01,2E,5D,94,8C,0F,E2,51,10,FF,63,4D,91,1D,AC,98,80,3C,13,C7,3B,53,4D,97,9B,E7,98,74,84,13,72,EE,DF,43,3B,69,DF,45,31,BC,D6,9B,93,19,85,3F,1F,63,4A,71,ED,C3,67,B6,4D,E8,49,10,CC,AD,06,F6,3C,AF,FC,63,4F,41,31,72,A8,59,A9,0D,4F,05,29,8A,83,EC,37,1E,3E,12,8F,EC,12,30,8E,FA,66,67,2E,11,08,6E,17,A8,B5,5B,36,DA,DA,49,3C,5C,58,35,7F,B5,B1,CF,96,4F,39,C1,6C,25,DC,9E,1E,47,7E,40,85,FA,DA,EE,45,81,63,C7,F9,63,38,F6,DB,64,F3,63,05,03,CE,C4,CB,21,8F,F9,48,5A,92,37,33,F5,F5,76,BF,69,8E,9D,77,18,21,A1,EE,6E,8B,4E,4B,60,07,C9,B6,12,4C,A8,0E,9C,FD,74,A5,10,42,48,55,55,4A,2A,07,F2,EB,6C,D2,32,E1,4F,45,25,68,F0,0E,2E,DD,48,3A,27,AB,0E,25,E4,B7,9A,61,52,F4,C0,1C,B5,F8,68,C3,7C,1A,2D,8B,36,32,F9,09,A5,9E,AF,A0,30,F0,DD,11,78,1C,8D,34,3F,33,C5,B0,00,B0,B5,E6,20,94,A8,47,D0,93,F0,C0,50,E4,A6,2A,E2,65,9F,A4,7F,A0,3B,3F,FE,32,F4,E7,69,B3,E0,23,7F,98,17,69,41,D1,73,85,91,80,82,A6,DE,95,DA,C3,1D,43,F4,1F,49,25,78,32,07,65,05,B4,D4,D8,54,54,21,19,75,13,7A,9E,2B,F5,B1,81,F1,3E,CB,EE,4E,F7,92,7C,EF,8E,A2,4B,25,B2,EE,54,BD,15,94,86,06,25,07,40,44,05,C0,22,CF,51,8C,B3,CA,08,CF,15,CD,C9,E1,18,0D,A8,E1,50,D1,F1,59,91,C2,3D,7D,2D,FC,70,1F,0E,9B,83,F1,CC,F3,A1,31,31,CD,9B,D5,11,05,0E,0B,09,EC,C1,18,FA,D5,22,75,C6,0D,1B,DE,35,F9,7B,EC,CB,11,60,6C,F4,61,C9,21,E4,58,99,90,58,29,CA,9C,3B,6E,A7,E7,F3,A7,7B,2D,50,69,3A,C6,7B,DD,F7,2F,74,CA,97,18,24,07,D4,7E,63,29,BC,52,A8,47,2B,90,F0,1A,BC,80,0B,A4,49,F7,57,55,A5,59,9A,60,ED,BD,9B,8F,AF,9F,49,A2,D8,CC,46,91,DD,91,1F,7E,72,0F,77,63,B2,FC,5C,FF,78,27,A8,DC,EF,55,7F,F2,BA,2A,0B,8B,BC,43,CF,C6,A2,06,CA,AE,99,95,CE,36,47,87,72,79,F8,A3,40,DE,F7,7A,8C,80,65,EA,4D,1C,28,F8,94,CB,56,6A,8C,7D,67,38,49,3C,CF,04,6D,42,A3,AF,67,24,9E,22,EA,A6,8B,6D,BA,98,5C,FB,24,7A,D1,16,07,65,5E,A9,95,D1,37,A1,D0,C6,19,D0,63,EE,44,ED,96,16,56,23,B9,7E,ED,96,39,89,D6,54,31,DA,90,4D,F9,09,A7,08,B0,D3,DD,B7,6B,D7,80,39,D9,F8,4A,A0,1F,98,9B,5C,24,A7,1F,E3,77,EB,11,4E,DA,23,4A,DD,7C,7D,E1,4F,13,92,B0,D8,67,0D,31,D9,66,FB,85,B7,AC,27,DB,09,5C,1D,03,7F,DE,83,B1,37,05,6C,6C,94,F3,B8,1B,56,9B,61,72,46,F4,75,4C,13,78,63,0C,66,2B,F4,22,7F,B9,A2,92,00,46,63,DF,1D,8D,1E,43,6E,FC,59,36,C3,87,F9,4F,10,9C,51,2D,43,85,5C,E4,DD,67,C3,1F,03,6F,9F,A8,D2,1C,CF,29,29,7C,3C,96,2B,33,A8,AB,02,39,54,8A,A7,37,F5,C5,FE,84,81,D0,2D,50,25,E4,44,D5,4E,37,34,7E,D2,20,F2,8E,D9,A6,07,0F,0C,E4,89,4D,BF,59,0A,35,3D,90,41,F5,98,77,B7,7C,55,2B,4B,AA,45,8D,A7,FA,B7,3B,CE,1E,8F,40,CB,84,81,41,65,C4,0C,E2,65,9E,B0,5B,62,05,AC,88,49,9D,97,2D,B9,C6,B3,24,34,C5,57,A6,6C,0A,25,78,7D,89,AA,25,9C,55,29,E0,9B,33,27,34,31,1E,5E,F1,92,67,81,20,CF,11,C3,84,0A,BC,00,FC,39,23,5B,99,CC,09,53,DF,B1,AC,89,FC,72,33,F6,97,1A,27,8F,FD,E0,B8,FC,9F,33,D5,EF,C8,B8,7E,B3,AF,D1,F6,60,C9,BE,10,92,B6,58,07,46,18,55,F1,CE,A7,41,32,62,BF,49,BB,77,1C,9F,6B,6D,BD,B9,BD,68,37,19,37,28,FD,D6,4C,7D,1A,DC,7B,AE,C2,1A,EF,D4,A6,4A,05,7C,3B,C6,12,4C,42,DA,21,A2,A9,CE,54,8D,1F,03,30,52,76,44,4D,6C,77,AF,6E,D8,0F,43,6E,5B,48,E0,5A,B7,DA,0A,FD,3B,72,7F,FA,44,A9,25,C1,D8,B8,68,E0,22,25,08,58,51,89,EF,C9,D1,D9,8B,F2,B1,F6,8B,2E,42,A6,0E,49,58,DE,97,4B,72,7C,7B,40,12,60,9F,4A,E8,A0,83,C9,85,4C,62,56,40,95,D7,FE,D7,BC,CE,46,69,1D,7B,98,71,7D,DF,20,19,56,DF,5F,7C,BB,69,99,0C,3F,97,6D,88,34,11,45,F0,18,36,B2,7F,09,30,8A,15,5E,3C,44,C5,11,7C,4A,E9,6A,15,49,72,C7,A4,0B,2D,22,65,17,C6,26,0D,C0,DE,44,11,0A,03,D5,21,A5,A9,F7,BB,B1,AF,57,29,5D,23,58,DB,4E,6F,C9,CC,DF,40,B1,90,80,7D,98,FF,B6,06,13,CA,9F,7F,DE,37,35,2F,EE,DD,85,59,55,5A,3F,19,45,6A,26,A1,51,21,E8,71,E4,A7,04,4B,1B,CF,AF,A6,FA,CE,55,A3,23,0C,EF,C1,DF,4A,2E,5B,E2,71,80,71,9A,DF,97,FF,CF,EE,87,A5,E8,DA,EA,1D,53,18,E2,96,FA,A2,F2,A9,2B,4C,28,DB,59,57,2B,7B,B6,FE,0A,AE,9B,6B,2B,77,BD,84,2A,E5,14,4A,AB,6C,F1,AB,5F,54,03,A4,57,42,EC,30,6C,DF,38,49,DE,FC,45,56,56,E7,5B,AF,F0,2B,6D,84,DB,C7,0E,89,28,1A,E9,DE,CA,D1,C3,B9,2E,10,49,D8,6A,BE,29,A9,FD,BA,31,B3,39,9E,D9,7A,8A,A8,F3,BE,D6,14,EE,EA,67,49,0F,B6,C8,6F,B2,60,C3,A3,5D,9B,D6,AA,C0,EC,84,CC,65,DF,45,B3,50,E2,0C,73,DB,34,A2,9E,86,42,A6,EB,97,EC,59,43,0B,DA,7A,9E,16,0B,3B,50,F2,41,41,D4,43,F6,D3,4D,5E,BE,F4,95,2E,D1,23,A6,B1,7F,91,3C,9F,4D,1D,07,2A,3F,60,1C,7A,BD,A0,B0,D3,C3,05,E9,F4,11,9D,0F,1B,16,69,61,86,02,FD,B4,3A,32,71,F2,3B,1D,24,AC,7C,D9,87,FD,B6,DE,01,3F,88,8D,91,6B,F1,24,86,4C,AB,BA,14,5C,62,C9,92,C2,CE,1D,B0,12,63,06,0F,A3,0F,1F,EE,B3,12,A8,31,DB,5E,0E,67,AD,AF,80,B2,C9,D7,81,F8,E5,42,68,12,84,A0,ED,E1,C7,44,FB,1C,CD,A5,57,A4,0B,93,29,87,8A,03,D4,FB,B6,CA,55,80,9D,B3,34,DC,13,7F,AB,7B,DD,F7,E1,30,BF,95,9A,C4,F0,4F,12,36,65,EA,89,CB,E7,D1,23,96,AF,13,8A,F3,94,A0,96,EA,D3,37,BF,48,97,DF,78,8B,F8,67,35,5C,06,9F,69,36,E6,87,46,2B,BB,05,2B,C0,E2,B1,31,D0,B2,17,21,6A,AC,29,81,2B,58,E0,05,34,FF,B5,0F,80,13,4E,D2,72,E5,D6,60,D9,C0,9B,2D,A1,51,DC,02,6C,7C,6C,F1,AE,0B,A5,45,EE,2A,CE,C2,F2,FC,D9,4B,A7,3B,8C,76,77,99,36,1F,9E,A2,E1,DB,C2,DE,B3,D4,92,03,FB,06,98,B7,5E,26,6E,C7,A2,84,EA,33,D7,BF,6F,B0,95,9C,1C,E6,B8,7D,07,B5,05,AF,DC,A5,6A,B6,BD,79,4A,0B,A9,7A,6D,A3,2F,3C,1E,DD,2C,D8,A0,C0,40,B9,2D,AB,C8,43,93,47,DD,99,5B,1C,20,BA,3B,8D,C8,2D,72,3E,4A,70,DD,0A,E7,82,7B,C4,4A,C1,D8,E9,EF,F6,6D,8D,E2,76,52,AC,F9,2C,D4,06,67,03,A6,43,2E,EB,27,7F,AE,45,DB,69,1E,21,3E,E6,20,A4,F3,1B,8B,E8,08,73,21,53,90,DD,F4,1A,1A,AA,97,51,C2,FD,22,4B,E6,6F,DC,48,E9,29,D6,A0,93,DB,3B,D2,84,F3,B6,AF,5C,28,4E,99,7B,43,5A,53,78,07,0B,BA,21,D8,9C,41,ED,DD,E7,27,80,68,F8,4B,04,E0,DC,5F,FB,97,A9,88,40,14,A7,EC,44,0B,B2,71,35,89,D3,21,03,43,AB,47,42,59,72,37,AA,9C,B8,CE,D8,D1,A1,EB,75,78,CF,AC,00,1B,AE,37,E5,03,0C,E6,23,C2,28,94,83,F6,A8,B5,F6,55,A0,F6,DE,77,A1,1A,18,75,5D,3B,6F,B7,9A,8B,AF,06,D0,8F,18,5B,CB,98,2C,4D,B5,FE,82,AB,B2,36,B4,38,E8,6F,C6,D5,9F,ED,58,9C,5D,15,36,77,BE,78,D0,1E,0A,83,23,3B,EA,66,2F,0C,E2,C4,AF,86,F9,7C,6A,13,EA,BD,56,D1,D2,B1,77,ED,C8,E3,55,AF,7A,9B,04,0B,F9,1B,0B,C9,BE,18,94,92,70,26,46,94,B9,32,78,F8,7D,9C,86,BD,BF,FD,90,7E,75,D4,04,6C,16,B8,0C,53,78,E9,95,62,42,C9,F6,9C,F3,FB,3A,60,FD,63,E1,9B,A4,F6,EF,B4,F6,02,F9,99,7F,BC,E2,2C,61,4F,61,CC,C7,6D,04,4A,AD,AB,24,60,0F,14,96,1F,EF,2A,F6,8C,A7,8B,54,3F,3D,84,20,B8,94,35,47,36,1F,98,EF,F5,8C,1E,37,A9,D3,3B,6D,C5,14,BF,DD,3B,A6,9A,D5,0B,1B,0A,81,7F,EA,7F,39,07,BB,41,62,C5,75,AE,BC,73,2B,70,6F,02,E8,D6,9E,55,51,2C,3F,07,20,D2,5E,E9,C1,CA,7A,4A,E7,F4,FA,DA,1A,8F,C2,72,92,9B,79,5D,9B,FF,65,43,4D,AD,11,C1,C4,8F,72,DE,FD,42,31,7D,98,DD,63,24,95,8B,AB,C8,4C,53,68,B2,C4,FB,25,71,49,BF,22,F5,41,64,32,B1,D2,C9,BE,F7,6A,E0,74,7F,77,51,F6,28,69,9D,DF,50,15,06,57,52,C6,9F,B3,B6,DF,31,19,20,6C,7E,87,4D,6E,32,79,9E,76,CE,99,93,C2,7F,26,FE,99,7D,AB,61,46,E9,53,E4,1D,68,02,66,52,50,76,07,3E,46,2D,5A,96,2E,5F,4C,AD,05,D8,4F,D8,7B,02,FC,12,A2,96,6B,63,EB,7B,63,33,43,66,80,A6,1C,43,1E,C8,88,0D,5F,2B,EB,47,0E,1D,E6,1A,4F,8B,7E,E6,E3,A6,50,DB,07,D7,92,CA,76,23,40,15,59,11,EC,E0,90,56,8F,62,E3,7C,9F,F1,55,5E,F9,5A,0A,2F,42,DE,E8,78,1D,0E,A9,C8,71,6C,E4,14,91,7E,62,94,67,F8,1E,5B,EE,8F,BA,BD,14,43,A8,65,5B,5A,5C,5D,38,1B,57,3F,95,31,FB,FA,4C,EF,7E,D4,FA,66,66,25,CE,ED,F3,96,FF,2A,75,1D,29,8A,F3,8F,81,9C,3B,A8,AB,81,DB,FD,16,BA,D9,35,8B,6C,C0,9C,E7,40,21,78,D1,4F,52,BF,39,C1,48,C1,49,7B,E6,A7,91,D0,B0,77,CF,5C,A0,C3,F4,5F,D4,7E,59,26,CE,E0,79,E7,D0,EE,74,F9,03,2B,52,D1,71,0C,9F,99,94,63,BB,29,13,FA,33,ED,09,6D,1C,A3,D1,D0,71,10,C1,2E,A5,46,73,ED,62,60,84,C5,26,69,64,11,01,F8,16,07,44,6C,01,90,27,BE,89,4D,62,A5,2D,BA,5F,64,B1,85,3D,18,0F,FD,01,5B,9B,83,75,91,6B,19,59,56,43,5A,BB,6C,FE,39,26,31,D6,AA,76,3B,02,9A,37,20,22,09,12,0B,9C,42,93,81,7D,2F,F9,B7,12,F6,35,70,82,6A,26,80,CE,B5,BF,F5,76,14,00,23,7A,1A,6B,6C,D9,42,76,69,37,C0,61,9C,61,7F,17,05,74,1D,21,75,88,99,CB,AC,53,7B,E5,5E,92,1B,1B,D0,3F,65,17,F4,67,DE,4F,30,E7,26,D6,65,2E,5F,39,C7,5A,23,5E,4C,D6,CB,4C,40,44,F7,35,3F,64,B4,C1,3A,03,33,F0,05,4A,EB,0B,C1,47,C7,A0,96,C3,AC,EF,03,FB,C6,2A,DD,37,A6,6F,6F,AA,B8,9B,0F,E4,DB,0F,54,18,87,CD,C3,DE,89,BC,35,63,39,25,D5,63,3C,D6,23,3F,41,69,6A,16,30,30,3D,42,B0,E6,41,86,F4,CB,6E,2D,30,70,E1,A0,63,90,E6,89,B7,F5,57,9B,F4,D7,5C,A0,00,F7,4A,A4,4B,3A,E5,06,E9,66,32,3F,C9,79,D6,D6,59,66,AB,E5,0C,CC,70,06,29,1C,7E,B2,3E,DE,DE,17,64,08,CF,44,38,3D,CC,0C,00,A0,8C,9D,ED,A5,A5,10,41,2B,08,EC,E5,85,8B,25,90,44,11,80,4A,25,A7,90,F3,E9,CC,FE,BD,E1,50,54,57,7F,83,D1,FF,EF,59,92,22,2D,34,3A,80,47,BB,2C,6A,B3,CF,40,32,B2,55,F2,1D,ED,DA,4E,D9,86,F0,F3,5E,23,A3,2D,E6,8F,E5,66,DA,7A,E7,E5,2A,A4,CE,36,8C,9E,8E,8E,6D,9A,5A,9B,67,8D,3B,C6,70,A9,3D,85,A7,59,59,31,38,31,B3,6A,F5,D1,51,0F,12,C0,E7,49,45,B2,D0,82,0F,8A,99,6A,98,3E,CE,12,BE,44,3C,CA,06,8F,7C,C5,C2,11,F5,7F,5F,68,14,C8,E2,A9,E2,C9,D3,C1,D8,CC,CC,E5,7F,9A,E6,BA,B6,67,EC,2B,5E,9E,0E,58,93,42,E7,AE,58,CE,B5,96,AE,4E,23,99,8D,22,BC,DB,D9,FC,83,9F,C0,4E,D7,FD,DB,37,7F,94,A6,86,B9,B9,71,1A,B8,FA,04,49,AB,5B,37,9C,4A,C0,00,5B,E2,B8,43,D4,ED,7D,B8,6C,8C,93,79,0E,D6,88,BF,13,C1,95,34,88,3D,75,AD,8C,4E,91,48,02,A1,74,67,43,4E,D4,A3,39,1D,89,70,1C,72,AC,54,3C,2B,E0,AF,6B,D9,24,DE,BC,85,5C,9C,FE,DD,68,BB,31,A3,00,52,0D,52,E5,43,8F,A7,DB,B4,B6,20,51,09,C7,83,95,8C,A9,32,DA,EB,7F,05,27,EF,B3,0C,B1,6F,30,1D,07,2B,51,68,32,6F,5F,30,BF,AC,F5,00,9D,82,AC,0C,1A,34,F9,FD,B8,30,8D,D2,9F,DA,1C,DB,14,A2,F7,65,F0,6E,DC,5F,C4,F5,52,5B,5C,1E,EF,FD,ED,95,DA,68,15,17,C8,BF,92,4A,88,06,FE,1C,28,34,3C,14,C9,21,93,36,1F,4D,59,60,8B,61,4A,C1,5A,88,F9,D0,3F,20,FF,88,0D,A6,BF,82,20,E7,44,FC,34,AD,01,92,7D,92,54,76,07,51,E0,D2,BB,77,9E,19,6E,D1,18,03,BD,03,94,2C,71,0E,94,FF,F1,0C,40,B5,76,7E,7D,18,D0,AE,B8,A8,9F,C8,38,F4,87,60,5C,AF,92,42,5E,0A,1C,B9,02,DC,30,12,54,60,42,52,D9,29,37,9E,81,B1,2E,D5,E6,FF,2A,6E,DD,F0,7C,6A,13,AC,20,E6,C4,AF,73,92,63,AC,DD,3C,E6,C8,BB,03,E7,C9,C1,6F,7A,EF,F4,F8,57,7E,1B,4E,F8,53,AA,80,3C,B6,FD,8D,08,7C,A5,15,26,A5,BF,60,48,4C,E2,AB,2F,4C,66,EC,EE,08,F5,BD,17,D6,ED,17,90,40,DD,7F,7E,56,48,EB,AD,BD,99,B6,E1,6E,91,5C,BB,FB,32,D0,5A,9D,29,7B,61,1F,6F,2C,05,70,05,86,91,B6,7F,30,16,41,D5,99,F7,A7,8D,93,C7,BA,F9,59,76,23,19,E6,C8,69,12,87,B3,16,6C,3B,CA,80,68,08,7D,86,5B,85,57,E6,46,29,93,E7,CB,FB,6F,1A,4A,A5,C8,7D,0D,0D,62,BD,BB,D6,E8,6B,B7,A2,98,59,55,93,7A,55,10,AE,25,F7,9D,39,15,68,A4,BA,A5,8A,78,A4,3E,30,6E,88,0F,75,FE,C5,E2,F9,01,A1,4D,39,C0,6F,81,06,E4,55,00,1D,1C,6D,BD,0B,FA,91,C1,51,CA,37,2B,2D,42,5C,3A,40,F2,1E,41,48,39,C7,92,B7,83,BF,B9,D4,7D,42,E8,09,A7,0C,BD,96,AA,D5,71,3B,11,E2,FD,96,2F,CF,63,85,70,FD,AD,D8,19,94,A0,67,A5,AB,A2,0F,19,80,FB,9D,E9,0A,B9,CA,F0,EB,A7,FC,93,E8,C9,2A,0B,FF,71,3F,61,CD,6B,23,03,F7,C2,E1,90,E5,06,A7,61,FC,A5,8F,AD,AB,96,73,1E,91,94,51,69,22,CC,AA,C4,E2,01,85,68,B9,CC,F8,38,9A,E1,F5,BE,20,EB,BA,86,7D,AB,E3,37,12,F1,76,5C,E1,AD,F7,93,11,C7,88,59,A1,76,2B,0F,AF,BB,0B,C0,F7,5E,7A,A0,0F,4E,B0,B8,F8,B1,F2,10,BA,A5,37,60,47,AA,DA,1F,E9,10,B0,97,B6,43,57,91,15,60,8F,CA,73,64,F7,4A,1D,C7,2C,56,DD,B8,91,F2,2D,C0,9A,5D,FF,F5,E9,58,3A,FF,BB,19,A2,47,86,50,5D,73,B3,9E,68,98,78,8D,6D,EC,A3,10,15,C8,91,14,4B,31,1D,F6,95,A9,C4,0E,E3,56,30,43,E2,D8,FE,96,D8,D1,81,65,4E,DF,9F,56,74,8A,8F,51,E7,AB,AB,FD,B1,AD,D3,B4,53,30,7D,B5,17,65,99,F1,DA,43,0A,D3,2A,FC,DA,6C,58,58,5A,20,AB,EF,CE,0D,0A,D0,C6,46,4E,B7,1D,BE,0D,CB,87,D0,D5,D2,CD,1D,AA,C8,84,83,37,AE,FB,60,D1,41,C6,58,22,A6,6A,F6,79,B7,FF,A4,07,37,F2,FC,C3,D6,3D,65,44,B8,68,4A,5E,2E,C0,AB,73,9C,FD,9C,CF,31,1B,7E,98,39,8A,85,60,EB,43,0A,62,61,20,DE,82,50,1A,47,59,49,32,5A,8B,63,6A,FF,8A,D3,BE,C2,EF,38,32,56,57,BC,28,BF,3D,AA,4C,DC,2D,0B,FD,A1,5D,2D,F8,AE,E5,61,BB,F4,E8,FD,34,A9,FC,47,34,C5,50,D4,B2,4B,05,DD,E9,E5,32,7C,B9,82,13,8F,E7,09,A7,85,C5,29,49,15,31,E3,C4,BE,4C,8C,A3,27,15,8B,DC,5A,5C,7D,8B,AE,09,92,88,55,AA,CC,EF,5A,CE,2D,3D,C1,57,70,DC,2D,B9,0D,1C,06,75,B3,C3,F7,48,58,8C,C8,2F,5D,A7,AC,E3,28,48,5F,27,3D,6D,2F,CC,58,09,14,A9,F0,7E,A9,84,BB,A8,E7,13,7C,94,0A,E3,0A,63,A0,32,5A,7B,1C,18,64,65,A5,34,FE,BE,AB,29,27,4C,95,1A,FC,98,A7,3F,8B,47,00,FB,A6,2D,35,07,C8,3E,03,5D,72,87,42,E5,7C,D9,91,7F,7A,A0,15,40,69,78,73,85,40,DE,B7,DD,78,ED,CD,3E,BF,29,DC,C7,37,6A,BE,C8,01,E5,B8,7E,C4,D0,25,02,1B,BE,4E,E9,D2,EE,E4,59,95,DC,27,46,64,43,46,3E,8A,41,24,77,A6,11,67,2F,1C,45,51,31,F1,94,7F,F5,4D,9C,65,B8,9F,0D,FF,66,CB,30,2E,08,5D,B1,05,16,D0,A3,1F,EE,7D,19,FB,B2,4A,51,8A,0E,70,CF,6F,77,E0,D3,9B,0A,9C,D2,60,FA,C5,82,F0,F5,5F,F8,E8,DC,3E,B9,E5,F9,9D,6E,05,47,2A,BC,53,D7,4E,0C,5F,4D,03,19,8A,69,D4,BF,E8,FA,1D,84,61,EF,6D,92,7B,26,9E,7C,F2,5B,1E,C4,8C,8D,CA,9D,C4,AC,DD,65,66,AF,33,86,91,D3,9D,BD,8A,42,13,A8,0B,6E,A5,7A,EF,07,1D,0D,63,CD,8C,40,70,FA,C8,C3,FC,BA,04,BF,71,DC,1A,BF,59,BF,57,BB,0A,09,FC,76,21,62,97,23,0E,5B,AF,21,58,96,05,93,46,E7,46,5A,FA,CB,14,00,03,AE,51,8D,53,BD,40,A5,20,F0,77,E1,4F,44,53,82,72,50,A6,5B,C9,C4,5E,CE,D4,01,B3,40,15,09,5E,21,8A,CE,06,EE,E9,F1,48,B1,23,98,D5,4B,30,FD,30,15,79,FB,AE,61,7A,4B,C7,A5,97,E4,29,9D,0E,BE,41,A5,4B,91,6B,63,35,75,23,45,E3,07,F9,1C,3E,18,04,5C,AD,F8,AB,73,68,60,A4,A7,C9,BA,99,77,BA,A1,BD,AB,DD,25,BD,AB,DC,0D,0A,3A,6C,AE,E5,08,6F,73,56,B4,97,45,20,9E,C7,39,7A,64,51,B4,B3,36,F7,12,D9,56,F3,29,7A,43,6C,48,BF,9A,6B,20,44,4E,C0,90,91,C1,7F,DF,71,A4,F1,8B,F7,FC,A2,36,67,93,FF,B9,AF,48,2D,4A,63,AD,D1,7F,91,30,16,F1,2B,83,5E,D8,B2,E8,AE,E1,95,23,4D,EE,C1,1D,7E,75,9B,B4,3A,27,56,01,77,CB,9B,E2,BA,E0,ED,21,55,1F,BE,BC,71,FE,9A,88,A2,EC,1D,C8,CE,0B,5B,15,69,44,DD,05,50,40,10,BD,4E,8E,37,56,23,38,36,57,62,86,CC,9F,FE,8F,8A,C7,D7,6A,BC,5E,45,8A,74,08,5C,58,9F,95,AA,2A,92,A9,D7,CA,08,22,F8,32,D8,B6,D9,1F,EE,76,9D,A9,55,08,90,0A,80,1E,25,38,F9,1E,52,15,44,62,7A,A6,81,D8,0D,09,D7,B3,21,A9,C0,1D,9F,25,62,76,C5,3D,79,50,5C,94,B6,B5,C2,96,AF,FC,64,BC,4C,3C,10,72,E2,F0,86,04,B2,74,38,16,F3,1A,1D,34,C2,AD,BC,E6,86,2E,FF,AE,52,68,1B,63,B1,FB,FA,9A,F9,2C,7E,4F,3B,78,14,AB,40,B9,B6,00,78,98,45,2F,80,D0,2D,B9,1B,3A,24,46,2A,AD,20,70,DB,8B,D3,26,6B,93,5B,43,40,6A,B6,27,DB,E3,A4,40,6F,FA,7C,0D,78,E9,DE,98,68,76,1F,14,DD,6E,40,96,C8,69,E3,B0,82,AD,F7,E7,1E,C5,26,AA,DB,6A,26,D3,2B,BF,C2,16,A7,BD,2D,A2,B6,35,0A,34,2D,9F,AC,84,F3,D1,AA,30,4F,CB,30,86,AD,45,5F,92,02,A3,AA,25,7B,BD,80,76,A9,FB,65,4E,49,F2,3D,1B,3B,3B,82,72,91,F2,76,B0,94,01,AD,D3,32,DB,FA,F4,8C,B6,FD,4A,5D,A4,45,59,FA,2C,AF,8B,43,02,84,E2,65,45,2C,5E,FF,5F,40,25,D6,14,BD,67,A5,47,36,1B,FF,5F,C9,63,26,87,7E,F5,18,B0,7B,D4,7D,7D,9E,FA,03,42,A4,AD,4E,C5,EF,8A,BA,2B,64,08,D4,1D,03,6D,80,32,7F,C7,46,F1,24,33,15,5C,23,7A,2D,93,54,D8,71,B6,8A,6D,49,4E,78,AC,43,2E,DF,E2,7A,B6,F0,33,47,AD,AF,68,0B,FD,96,4D,84,18,CD,98,87,6D,E9,80,91,45,20,FF,6E,DE,2F,EC,29,B0,29,BD,BB,17,C2,4E,58,AA,DA,A3,B8,FA,20,16,20,6D,76,0D,DB,EB,78,5A,74,4C,69,74,08,F7,8B,DF,2C,F6,79,1C,29,C2,F4,E7,53,E0,7B,98,C7,A9,42,B1,28,75,3E,7F,9D,C6,70,70,27,93,3F,1F,0A,39,37,F1,0E,5D,CD,67,4F,81,A1,20,96,C7,D6,09,C9,4D,2F,98,EE,79,7D,43,E9,9B,AD,A1,15,FD,5D,A5,66,FF,E7,FD,82,9C,50,F7,7D,F8,CA,06,2E,CD,DF,24,B9,68,F2,7B,C1,C4,30,76,EE,5F,87,6F,63,68,87,22,E1,75,71,E0,43,A1,6A,CA,D2,B3,77,A5,DB,06,47,29,05,A9,E9,60,1C,FF,73,DE,84,8A,8D,82,C7,FC,C8,0E,4A,F6,DC,0D,41,5B,69,9B,27,7E,05,13,3D,69,BF,95,90,CB,6D,6B,63,52,56,4B,05,49,91,3A,C4,5F,DB,AD,DD,BE,71,82,BA,DD,73,44,BC,E6,0D,12,13,B5,10,FE,E1,00,F1,D0,12,E1,D3,42,99,CC,EB,9A,C0,B6,4C,2B,F7,A2,81,F2,2F,05,41,52,22,C9,BF,3E,7B,5B,F9,FE,7C,FE,17,CB,89,D1,EE,2D,41,09,24,4C,10,BE,D6,FE,DA,39,1D,27,92,02,F4,85,A8,79,0F,A7,B8,5A,9F,70,81,D2,99,C6,0B,45,69,98,FA,73,1F,A0,F7,2D,E1,C0,51,9A,51,99,A0,4D,23,EF,F4,5C,F4,C7,E5,79,69,D3,FE,19,1D,28,F3,97,98,68,1B,2C,A1,DA,C5,EB,E6,2D,8F,05,E1,6D,E9,F1,B1,1B,E6,41,D6,2A,63,85,9E,15,28,60,B2,8C,C1,A8,91,22,DD,00,2D,31,02,CC,69,B7,10,57,20,37,25,9E,9D,75,63,4A,C4,42,29,13,5E,D6,AE,4E,95,18,DD,1B,85,B3,C7,2C,92,A6,77,F1,2D,16,29,DD,A0,A9,65,A9,EE,C5,96,29,D6,0D,0E,EA,E6,6B,F5,45,6D,E8,C5,12,77,59,5E,B7,D1,A7,0A,D3,C0,F5,77,D2,1A,EF,5D,B0,06,E5,43,A4,CF,8D,70,26,B6,85,EB,1A,5F,70,64,43,26,85,4C,D7,A7,E0,6C,FD,53,2C,E7,4B,BE,44,EF,20,D7,1D,9A,BD,32,15,97,4A,B4,19,3E,06,E4,3F,D4,62,F5,FA,A7,AF,76,CC,79,44,B2,D3,BC,C6,33,35,F6,60,F7,E0,AD,87,51,11,8C,9E,E4,EE,02,E4,B2,6D,2E,D1,DB,B5,8E,62,A4,97,45,32,D0,5F,D0,85,A7,2C,CA,CF,96,59,36,B7,54,1D,BE,AB,92,CA,57,90,89,87,5A,30,4C,91,1A,E5,34,5E,2D,4E,77,8E,28,C2,7C,3A,F8,FB,99,83,9D,57,CF,75,81,8A,FF,50,9F,15,C4,A6,5D,61,75,7C,09,2D,64,9B,0D,E1,92,97,B3,97,77,FA,A6,94,38,20,56,36,B3,C1,AC,9B,3B,43,82,E4,68,CF,E4,0A,16,DA,E5,DE,D7,F0,E9,C6,BA,C4,A2,1D,6E,C8,25,A9,41,0D,10,46,AB,78,E8,8F,51,BA,9D,C2,58,0B,21,14,36,D4,C9,16,03,FB,01,67,06,F0,29,82,D1,C3,57,12,80,68,2C,E4,85,B3,18,A6,1E,86,EC,D6,F1,68,80,17,AC,2D,2E,21,39,E6,C7,D6,44,AD,85,25,76,3A,D1,1D,EF,D1,1C,E6,08,7E,02,9E,94,8F,AC,B9,5F,3A,A0,AA,D9,56,6A,F9,44,7D,E2,B8,D7,20,22,2E,64,77,D8,2B,3B,75,FA,20,2D,08,21,2B,A2,9E,92,3F,8F,30,06,6B,37,8E,3E,0A,A6,22,6C,62,6A,5D,D1,F5,59,ED,29,EF,17,9F,48,35,2B,40,B4,8A,94,50,A6,8C,FD,52,A9,EB,9B,EB,DC,4B,FD,C5,74,97,01,65,C4,29,84,E1,E1,9B,F7,4A,23,33,E2,48,30,90,8E,F7,47,6C,EB,E4,4B,B8,70,C7,62,1B,10,D5,46,E3,B3,79,3E,CE,13,77,61,57,BF,07,C5,9A,40,90,4E,75,90,42,F6,53,0D,9E,23,E2,52,E6,F0,A6,5F,FC,A7,18,94,DB,A2,6B,59,27,3D,C2,F0,23,FD,4C,45,B3,25,B0,6C,DF,DC,63,5E,F5,CC,39,DC,61,B2,9D,9A,97,FD,99,C4,15,A6,DF,6A,97,07,52,F0,DA,46,96,58,B1,EF,43,4C,C4,94,88,BC,5E,60,04,95,32,73,88,28,50,5E,4B,BB,5D,D2,A4,32,BB,1A,68,A1,1C,2E,B8,45,AF,24,4F,98,58,E5,DA,1A,C4,A2,31,23,4E,C2,DE,54,04,F7,09,17,E6,FD,30,66,73,16,B6,FC,6C,55,52,04,19,8E,80,E1,EE,64,A7,E1,48,B8,FE,EE,86,77,61,48,5F,64,B6,3A,5B,5F,3A,5E,A4,A4,4D,6A,0E,7C,A1,84,65,16,D1,B6,5F,60,15,25,C0,23,CD,4E,2D,3E,AF,DE,28,D3,DD,51,59,6E,1D,B1,7E,6F,15,3B,92,D5,0B,E6,D3,2E,10,15,95,B5,82,00,BC,CC,B7,2A,B5,68,83,A6,76,69,A9,FF,77,AB,30,04,F4,73,3B,30,ED,C9,F8,7B,B0,F8,9B,E3,7B,CD,E5,D7,BC,62,4F,99,45,B2,8A,A3,2F,96,D4,98,D9,DC,89,EF,A4,83,45,3B,C8,87,FD,63,1E,47,0D,F0,12,09,6C,07,2E,1E,63,DE,D9,01,16,6A,1D,1A,17,EB,30,0D,B0,4D,ED,65,43,09,B2,98,00,0E,F7,A3,9A,6F,F4,0A,34,A1,A4,49,DD,79,88,E6,86,DB,BF,5A,F7,5D,6C,5D,1E,6E,00,79,B7,2A,C9,F8,34,9C,2B,26,38,40,77,AB,9C,1E,9B,17,76,A9,79,CE,F5,0F,E9,2A,F7,16,05,AB,E4,02,50,2D,37,52,D9,62,09,F5,30,56,F9,2B,E1,4A,8F,91,3A,CB,06,08,96,F8,F7,EB,18,67,C0,CE,9D,5C,A2,2D,CB,54,EA,C8,7A,03,8C,AF,3F,89,CD,0D,5C,C5,9A,4A,C3,83,05,5D,FB,E6,C3,ED,61,AB,CD,55,B7,99,6D,83,2A,9F,D9,0F,4F,C8,B2,B9,A6,57,D0,09,EC,B1,AD,9B,50,57,41,29,23,B7,05,20,F0,D9,5E,BA,62,63,29,AA,2B,0D,90,7A,E4,70,3E,64,FF,D7,EA,8D,73,69,8E,2D,4A,0B,CB,17,1D,91,52,A1,DB,A4,99,B1,77,36,BF,C8,4D,64,A4,1D,87,E0,A9,90,C7,E5,71,30,15,07,AC,3F,02,A1,5F,C9,57,95,D1,62,95,AA,EA,B3,6D,39,8F,7E,47,AF,DD,E1,0D,FA,51,CF,40,53,86,1C,E8,D0,DF,21,50,D8,68,17,61,84,A8,50,B5,35,44,60,1A,31,78,C6,FC,6D,A7,31,E4,DF,F0,74,DD,03,5B,E7,14,2F,A6,AB,90,72,F2,07,1C,D7,4E,57,02,C4,BD,C2,15,0F,3B,08,39,BF,EA,53,F8,0C,82,AA,72,07,60,2D,C5,FB,6D,7C,C1,D8,B8,AB,BA,18,EC,F4,CE,81,C3,99,A6,04,5C,D9,F1,1A,99,58,6E,36,99,62,67,42,8B,A5,8B,C8,EA,45,C6,84,B7,DE,14,D0,B9,85,E6,43,E4,90,97,8C,4A,9D,FC,D6,6A,93,26,2F,C5,25,C8,2C,00,78,DA,0F,85,84,A4,8B,EE,7A,9F,75,0C,DB,1B,AA,7D,E6,DE,16,1E,7E,38,D6,1E,F3,B0,B7,36,EB,A7,07,9D,2A,49,C3,32,44,64,4A,E4,A7,A1,D5,67,46,C8,BC,3F,23,54,E4,46,06,88,EA,3A,F2,6C,43,0F,84,AA,1B,31,82,29,0C,21,73,25,02,46,83,4A,E3,E1,31,0B,BF,7E,6B,F9,72,FE,1C,11,BB,18,44,F6,24,B3,14,A7,8E,CA,47,2D,28,08,56,D8,B4,D9,29,03,BD,B3,51,3D,74,55,23,E4,6B,FC,87,36,D5,8D,F4,04,18,3E,E5,55,63,6C,93,7A,B1,12,B7,A2,D7,79,E7,2D,B9,BE,AA,EC,2D,D7,22,3D,32,27,C5,E3,EC,BB,CB,2A,41,00,83,B6,44,72,D1,46,92,F9,29,50,20,72,57,38,F1,55,A5,17,5A,86,69,BE,A9,81,AF,11,11,F9,37,44,16,4C,2C,F6,68,41,19,3B,30,F4,F6,7E,4A,42,F6,38,59,86,E6,D2,71,4E,E8,26,A3,6A,21,F2,4F,EB,2F,27,E9,22,DE,D6,94,95,B3,EF,1E,63,3C,C0,51,BE,E4,31,56,4D,EB,71,92,AE,FF,D8,AB,F5,0D,85,5D,03,FE,15,38,CE,0D,31,E4,5D,79,77,D6,0F,5B,7D,D4,B0,C7,12,76,B5,E6,57,1B,24,FE,70,37,9E,1A,32,2C,27,F5,38,23,89,E4,28,42,4F,6C,24,59,CA,CD,E4,96,68,04,B7,8D,AA,42,E2,ED,31,E1,91,CE,2C,A4,DF,E2,72,90,59,5C,69,6B,10,62,BE,9B,03,FF,ED,A1,B4,E9,71,5A,04,0E,5E,D5,ED,2A,1F,DA,B9,D5,06,90,03,21,A7,56,12,64,9D,9C,2B,28,CD,64,02,7B,99,46,DA,A6,F0,26,4F,F7,CA,C4,B3,1F,27,7F,29,AB,78,55,B4,87,E7,92,35,46,21,2D,CD,77,2A,66,54,A8,CC,73,E8,74,B3,91,9F,62,69,7E,18,B9,28,DD,C2,EC,06,23,0C,F8,B8,DB,78,FE,BA,61,A8,43,E4,9A,DF,1A,80,20,A8,37,3B,B5,1A,22,46,A9,62,4A,DA,FF,B9,B7,E9,83,83,C0,B6,4A,A0,B0,C3,5F,BC,D9,50,A5,10,23,51,2F,8B,93,08,06,AE,75,D0,DC,74,55,6A,E6,B8,5A,3F,5D,D2,6A,EA,DE,61,7D,31,4B,F1,30,06,98,1C,EC,D1,7E,E4,83,BF,42,91,9C,32,A3,07,53,6F,92,D8,A6,78,F1,2D,8D,3F,2A,17,A8,9A,43,5D,E1,31,81,57,76,24,EA,7B,FD,D7,E8,84,62,B1,C8,91,ED,A8,EE,DE,40,FC,23,60,05,D3,1C,43,47,5F,CB,E3,61,5C,D0,42,A2,18,F6,A8,A3,05,5B,2F,D9,D2,D6,4D,8F,3C,B2,24,77,4C,1F,0D,9A,DD,29,65,11,D3,7A,E8,F7,CB,CB,70,72,00,EF,BB,28,76,D9,C7,58,79,56,B0,EB,32,91,78,31,6C,9B,A1,05,A2,0B,C6,D6,67,3C,37,F0,62,C6,C2,FF,51,37,4F,89,1B,2B,2C,0A,62,6B,BE,D3,7F,7B,FC,A6,B3,D9,C7,A7,9D,63,50,5A,D5,3C,A7,FE,3C,ED,D3,5F,98,CB,87,24,22,54,44,9E,5D,F9,4B,62,D1,75,0E,3D,DD,85,B5,C7,AF,87,59,22,46,05,7F,00,E5,01,BC,4D,BD,31,3D,0B,73,C6,3A,01,DB,DD,0C,B5,94,75,3B,97,8C,B8,5E,0B,F9,BA,79,9F,2B,A9,1C,31,4C,ED,98,DD,91,1D,11,42,57,E5,08,06,02,39,7E,98,15,A6,91,E5,73,DB,05,C8,E7,73,BC,89,7B,93,E5,BA,75,C1,15,60,77,45,4E,91,69,9A,55,DE,00,7A,33,07,A6,34,5E,42,0A,7F,94,30,CA,AB,70,DA,6C,C4,5B,DE,A2,32,62,FB,AD,AF,87,2C,F5,6F,44,25,E8,D1,99,59,CC,58,16,A7,BE,8E,69,1E,EE,6C,FE,67,B7,BE,98,6F,AA,F9,A6,AA,56,52,17,7C,43,B0,F2,E4,F2,3F,5E,5E,4D,15,D9,5A,85,D3,89,55,27,3B,FB,5D,1B,53,40,7B,84,57,FA,EE,8D,7B,83,A1,38,CC,08,D7,E9,D9,DF,29,83,DB,61,C3,6A,A5,DC,67,4D,D4,73,40,BD,26,53,C2,93,FA,0A,E3,16,CF,1A,74,90,F2,97,05,3B,9A,C7,4A,05,1F,BA,B5,80,B9,7C,E4,C3,2A,62,AC,97,DF,08,7B,A4,9E,EE,7C,68,7D,ED,1B,96,C7,9E,29,0E,D2,52,E4,CB,35,7B,D4,C4,32,A6,4E,BC,90,1C,B2,2C,94,96,12,6E,DA,3A,C7,7C,B9,27,CA,F3,71,7C,D2,43,A3,47,8C,E4,C0,14,C4,17,0A,9C,B6,39,9F,2E,D6,56,27,A8,2C,B4,09,7C,75,48,71,2B,DF,D1,81,DF,AC,35,B3,46,5E,DC,1A,07,66,CF,D3,08,56,14,E2,B5,D1,41,77,A6,17,7A,26,CF,F3,7C,79,BC,51,C7,CF,ED,18,F6,6E,B9,D7,36,56,17,25,C1,A0,A3,D2,7B,ED,AC,A7,16,9C,D6,AF,9C,7D,5B,FD,ED,46,88,18,9E,1C,12,A1,11,48,06,2C,94,7F,7E,03,EE,7B,05,62,E2,AD,3C,11,8F,41,45,5A,0F,3D,6A,2C,A0,3F,1F,23,A2,2F,16,C2,81,BC,DA,E4,2D,C4,D9,57,10,CF,C7,7A,1C,09,DE,D9,8D,C1,D2,E9,A5,08,D2,FC,D9,D0,92,D6,AB,D2,73,B2,86,C0,CB,F1,B6,8F,61,D5,AC,CA,3E,45,DB,27,51,AD,A3,DA,A5,08,3E,A6,19,4E,28,BE,ED,C7,A0,36,E2,C5,C7,80,88,2C,22,9E,47,CD,CA,5E,D4,68,67,5C,F8,87,45,1B,D3,8E,C4,09,FA,02,0E,68,BA,B6,1F,9E,A3,27,54,06,DE,8C,F6,BD,D0,65,11,10,1E,D6,40,C3,6F,6B,56,81,8C,4F,98,5F,1C,B0,BB,EA,62,47,7A,EF,9E,CA,C7,BB,0C,48,52,80,5E,83,54,4D,61,0C,30,00,33,E0,4A,22,5A,E8,F2,AD,97,C0,4D,B1,C8,77,C0,AE,F5,95,AE,08,35,3C,D0,AA,0A,99,28,B8,F8,E9,CB,9A,07,E1,0F,92,16,27,52,55,D9,CB,FB,86,18,3F,77,3D,2B,4B,78,78,1D,24,1E,89,FB,E9,FE,CC,94,B2,D9,CE,91,45,61,BC,35,0C,EF,E4,B4,20,55,0E,A4,A9,18,F4,BF,9C,2E,54,F4,83,10,12,BC,E3,A4,18,E9,3B,09,0E,DA,5C,59,54,68,D2,1A,98,E9,6D,05,5E,AD,86,05,1D,3F,22,54,BD,C3,23,5E,7D,FD,E2,8E,64,1D,21,C0,8E,FB,05,20,E6,0D,94,54,25,5F,8A,41,41,CB,3C,DE,2D,C4,EF,5D,A5,4E,50,AB,7A,C2,32,D3,3B,0C,E0,F2,48,EF,02,BF,6C,48,6C,DF,F6,F6,C4,1F,C3,00,D2,0F,AB,F5,09,EB,6B,F7,6E,1C,AA,AA,37,36,84,C8,8A,B3,25,18,C4,30,5E,2A,6A,00,AA,36,65,1A,7B,42,40,DE,69,15,03,A6,85,02,60,52,99,77,A1,8F,8A,54,88,A2,D1,71,37,82,47,E8,54,BF,5E,6E,BE,4E,CE,B2,9D,5A,85,51,74,32,4B,D4,F5,6B,9A,15,CD,14,6E,07,F5,09,C3,1D,A0,7B,E0,10,D8,33,FA,16,26,2E,82,7B,93,A0,2C,FA,81,68,96,CF,6C,4A,68,D0,C7,7D,E2,5B,9C,32,7B,8E,4A,49,36,09,38,12,51,7D,95,46,32,4F,D2,E6,4B,32,2B,10,1E,BF,C1,C9,93,37,AD,FF,0A,48,BC,25,58,A8,3D,D9,24,03,77,65,E2,97,48,4E,CF,B5,BF,15,44,6D,A9,7D,FE,78,41,9E,32,97,F3,6C,7B,22,30,23,C8,33,E3,C2,9A,90,9A,59,C3,B6,AC,F3,58,34,9A,C5,7D,DB,6E,4C,BE,C7,19,76,7E,00,AA,6C,2F,20,21,CC,8E,A0,65,01,46,9F,D5,83,DF,5D,8D,74,F5,90,C4,9E,AF,17,A0,12,53,7D,41,1A,F8,F1,02,5D,96,1B,DC,6C,B9,4A,5F,34,72,E4,C6,CC,6A,7C,68,D7,26,DA,27,AB,40,F3,FE,82,44,09,DE,39,DC,73,19,4D,A1,90,48,13,62,9C,6B,97,26,58,2B,3A,9E,97,1E,B1,DE,2C,ED,CF,1F,77,F9,DA,3C,75,EF,C0,17,0C,1F,23,8C,AB,4A,28,0D,43,05,D2,FE,A3,60,EA,1C,E2,B4,49,F4,EA,94,11,09,F2,77,12,30,9C,52,B7,CB,0E,AE,0E,11,D5,53,21,3B,C2,C8,B3,E5,AE,1F,B4,62,70,02,E6,8F,78,79,08,34,C6,12,65,02,C1,75,75,6A,81,76,12,DC,9B,7F,5D,FD,A5,0D,FB,49,FB,ED,E5,AA,99,94,12,17,26,6C,17,01,11,1C,BB,F3,12,C2,04,94,36,3E,5C,AC,C4,BB,C5,58,4A,2C,9D,7A,26,96,38,A7,61,8B,56,85,73,9C,B5,E9,06,3C,A4,60,1E,5D,AD,7E,9C,71,C6,EF,2E,B7,15,27,24,8A,94,87,C0,29,05,AF,D1,A8,79,93,1C,E7,57,81,BE,0A,71,34,51,D0,10,BD,27,26,1D,D8,9F,A7,C5,2F,18,01,1B,5A,C0,95,B7,C1,86,50,27,83,95,17,0D,E5,B7,4B,50,5D,30,BA,0C,E4,5F,46,37,7E,1B,EB,92,B2,28,01,05,9A,94,34,24,CB,1B,32,AB,B8,18,93,8F,18,D0,8D,15,6A,5D,E3,69,68,B0,97,F1,44,4B,45,9D,0C,52,C8,04,7E,91,13,F9,C5,DF,69,72,DF,9A,51,3E,15,B9,59,90,25,24,3D,8A,C9,3F,1A,E4,7A,81,B8,89,09,1D,8B,CB,57,5D,0B,C1,6E,05,A2,4A,DF,03,B3,B2,B2,F7,D0,94,64,E8,34,40,52,38,A0,31,7E,F2,7E,B4,7D,BF,90,08,2D,0C,97,22,6C,DA,90,DD,9E,9F,1C,21,9A,03,EF,D0,2F,16,CD,82,9A,1E,F5,D3,C4,56,9C,37,10,9F,02,0F,BB,23,8B,5A,38,4F,B2,E5,B0,88,F7,A2,15,6C,8B,CB,14,E6,41,52,FE,D6,07,DF,DA,F5,4B,24,C5,DB,2A,0A,8D,7D,57,15,C6,83,42,C6,E6,24,40,54,09,C2,5F,4B,0B,98,B4,E1,9F,3A,94,93,3D,30,D0,90,5C,75,04,61,40,E1,7A,45,43,49,CC,09,AB,A4,92,22,7A,F2,67,52,72,DC,4B,C0,C2,7B,92,9B,29,57,5A,EC,C6,23,ED,17,B8,ED,DC,F5,4D,31,51,9E,15,EE,28,CB,E0,8A,92,03,8E,43,B1,8A,68,7B,4E,D1,F7,67,5B,F4,98,73,FC,C6,19,A5,67,0A,31,00,C3,ED,DE,73,28,B0,3C,C3,02,70,F8,6F,DA,0D,7D,98,54,A7,38,62,98,7A,E9,22,FE,61,B4,4F,66,B6,24,D7,3A,9E,99,9A,24,47,47,50,52,4D,DA,5B,FD,79,F6,8D,53,82,6A,7A,B1,57,D3,FB,A4,16,D7,1F,0D,BC,3B,FF,DA,52,47,8A,CF,82,C7,D7,ED,56,F8,66,51,86,BB,9B,80,92,CD,8B,B9,3A,B8,3A,96,01,0D,C9,D6,DD,4D,46,31,C5,99,A6,95,46,85,10,59,F6,AD,D6,22,23,FD,DB,25,AF,42,B3,05,A8,DD,33,26,00,65,F6,A1,D7,93,42,8F,CA,36,1C,48,9E,75,23,15,6F,F6,EA,13,62,00,BB,56,90,AE,0B,47,D8,E8,74,0A,F6,B3,8E,C2,1E,29,EE,63,58,D5,6D,E0,1B,F0,57,30,6A,52,AE,43,18,5C,61,F6,E5,09,A0,8E,D9,2F,5F,FB,7C,CF,BD,2E,1A,C2,AF,01,80,2D,E0,0A,B7,D6,C3,39,C3,CB,27,FF,3D,A6,CC,2D,C7,4C,FC,A0,B4,09,27,44,40,77,FA,57,A9,4A,72,D1,45,00,A8,E2,BD,BF,DF,E7,8E,7A,72,72,CC,D8,79,48,59,F0,97,A1,98,59,92,C9,D6,97,07,47,88,5C,39,3A,25,DD,3B,71,79,70,A0,EA,61,E1,79,43,FA,B6,D6,CE,EE,99,88,C4,D7,D3,82,3D,C0,23,13,7B,08,7C,31,43,BE,B2,87,68,BE,29,C8,D8,B5,D0,9B,BC,78,60,47,0B,0F,B8,2C,81,A4,88,EE,AB,D7,77,59,E7,30,92,57,66,6E,71,EB,EE,82,DD,78,BB,94,A6,A3,C6,7B,DD,A0,25,AB,F4,C7,51,C4,F4,D1,15,DF,88,6C,B1,F6,19,6B,79,E8,92,C9,8D,05,9E,81,12,7F,AB,DD,03,05,F0,A3,80,A7,6C,57,D2,60,EC,CD,09,9C,AE,5F,7D,35,28,B1,A8,3C,49,AC,C5,D7,56,41,D0,13,73,D2,43,9A,6A,43,01,84,57,91,A4,48,0E,CA,B1,1A,AB,D4,46,7B,78,07,DF,E6,BD,AB,FA,D6,AC,90,51,33,17,22,F9,E1,73,CD,30,B1,C0,D8,FF,CE,EE,F6,9D,19,67,D6,0A,C6,36,41,4E,72,B4,E1,1A,24,0B,EE,76,08,15,77,A5,D0,25,4F,ED,FA,1F,66,92,4F,AF,BD,CD,56,F5,B8,43,BC,4E,6A,B8,BC,33,00,DE,F2,D4,14,57,FA,37,A8,9A,4A,0F,B0,39,3A,AD,AF,FD,E5,94,93,AD,95,38,3B,AE,D3,A6,17,19,AD,15,BE,BD,E7,A6,D7,C4,8A,F6,A5,57,B7,A7,AA,5A,8E,A2,0E,17,39,0E,F7,D8,32,62,50,A2,75,31,E5,B5,AB,74,3B,D3,E8,93,85,A1,AE,9C,4C,E7,A6,AD,A4,C6,06,41,1A,09,8B,48,A5,54,71,AE,57,7F,35,D8,65,48,32,B7,98,30,87,6B,D6,01,AF,87,87,0D,09,47,AA,E6,2E,EA,0A,B0,41,EE,4F,F4,B1,E6,B5,A6,EA,3C,96,53,C1,46,24,63,E6,21,46,5B,86,15,3F,74,BA,C6,4F,D2,1A,DF,68,80,D5,AE,C1,1B,2A,58,F2,81,35,3D,C0,B5,68,03,AC,71,B7,09,73,FC,5F,FB,1B,D0,66,57,FA,9C,D5,B4,3C,46,13,E8,8D,E8,4F,02,63,79,0E,CD,3B,35,38,96,DB,A2,E6,6E,39,08,47,73,04,A2,B0,25,67,A8,E5,9F,DC,B9,C0,C9,6F,30,E8,F4,74,D1,40,8F,18,0D,E0,A1,9B,30,C6,2D,B8,A8,A4,FD,B8,91,05,50,F4,FB,27,BF,D5,72,45,C3,C0,F7,24,70,4D,F7,7E,71,2B,4A,A2,17,A0,7B,E7,07,D2,24,87,81,89,65,D6,B4,A5,7A,F9,8F,14,B5,73,0D,D6,09,F5,43,18,89,C9,0A,99,5B,CA,06,D4,31,CA,7F,AD,EA,DB,78,16,50,AB,88,3F,20,62,50,59,2D,4F,62,19,9F,27,FE,06,EE,35,E9,8F,2B,7F,A9,15,AC,94,B5,22,3E,0D,5E,91,97,CC,3D,00,19,84,5E,14,1F,CB,78,6D,07,4F,AE,12,00,4D,EE,77,2F,3C,F9,85,26,FB,8F,DD,F8,F3,A7,1D,09,8F,F0,1A,A1,9C,DB,E9,1A,A8,58,A4,39,E6,EF,FF,3E,76,4C,32,A3,10,9E,51,C5,30,F9,73,10,F5,F8,98,50,19,F5,43,D1,F9,CA,94,51,79,D5,F5,C9,61,05,CB,F9,20,4C,C0,02,31,F5,7C,F2,83,32,9B,A6,A8,8D,8C,22,CC,AA,0C,D1,C2,93,88,13,79,B4,0F,E0,74,E0,C2,15,8E,92,71,BD,1F,CE,89,49,8B,39,35,9C,08,A6,6C,C7,33,91,B7,C7,CE,43,DF,9A,CB,CF,B0,4E,16,9A,D6,2E,6E,76,07,68,90,0D,34,1E,5F,AF,05,6A,2D,D5,78,75,B8,BF,C7,06,DC,B4,B0,3C,5E,9B,C1,DB,32,1C,E4,AC,4F,04,A4,EE,0A,9E,62,0A,77,8C,4E,2D,21,77,FC,73,8F,12,37,BA,73,8C,61,09,09,75,0A,DA,D2,1E,56,E4,FD,D6,83,40,EB,63,46,4B,41,62,18,03,90,68,90,68,58,AF,88,E6,22,71,4F,B3,3B,68,C9,8C,8A,A5,8B,72,98,C0,75,50,1F,D3,7B,C6,95,6C,4F,28,1E,D3,02,87,FC,95,FC,99,45,84,07,A4,C7,AB,E5,C5,A7,D7,64,B2,B5,64,8A,65,53,F4,D2,CB,11,D1,6D,9B,D3,BE,79,F3,53,8F,2D,F6,81,93,50,94,7E,BB,CE,FB,33,01,A6,71,D6,D6,17,91,9C,BF,9C,9E,42,0A,4E,BA,02,39,36,43,AA,79,F5,5E,A3,1D,D4,FF,2A,2D,E4,6A,FB,0B,AC,EE,B5,6E,F9,52,9D,DC,53,E2,09,45,FC,C6,A6,75,BA,34,2B,8A,67,2B,5F,18,09,63,24,54,DB,9F,FB,29,34,E7,50,3B,32,22,2F,E2,2D,81,F0,CC,86,81,A7,DB,B4,9C,FF,67,1A,D7,E2,E7,04,62,E2,04,6E,10,B6,ED,01,9C,76,C5,16,5E,41,29,BA,3E,2C,5D,58,ED,DD,6C,6D,82,02,96,6C,67,3B,D9,A5,88,57,DA,5D,90,45,E0,84,05,EA,06,43,7E,F6,D3,97,7C,E1,3E,25,26,C8,12,42,CD,1E,46,D9,56,0C,2F,3E,E9,50,A5,FE,66,D5,44,AC,5D,38,3E,97,60,6E,E4,29,CE,D5,88,E4,80,EC,FD,EC,02,BF,86,0A,1C,B2,25,5E,FA,F0,27,B0,A0,9D,FF,E4,35,9E,8D,E4,3E,D0,7C,AF,01,F7,6E,5C,4C,81,60,BB,0E,D2,08,8F,10,26,CB,0E,71,D9,11,0F,DC,15,77,D6,EF,36,18,6E,DF,F4,2D,93,46,34,9D,93,A0,94,BE,09,1A,B7,E7,B3,56,E4,5B,4B,08,A6,2F,09,58,1E,1C,7A,17,A1,51,E8,D2,0A,8E,57,3E,07,35,C6,55,23,FE,5C,FB,2C,1C,77,A3,F8,57,B7,14,FB,B0,C3,2B,B6,56,6F,10,1A,40,8C,5A,D5,C7,65,DA,70,2C,CB,4C,4B,9C,F5,8D,C0,52,DE,20,59,A9,41,CE,A2,06,29,D8,80,3F,33,BA,67,EF,F8,EE,E5,7D,70,A7,8F,96,17,BF,A8,F3,7D,22,ED,AD,BF,50,24,39,2E,47,AA,10,36,FF,18,F8,75,63,54,87,CD,63,3C,30,68,CF,59,FF,EE,2D,28,9E,8D,FE,86,B0,39,70,35,54,CA,F1,1E,B8,F6,0D,B4,CD,6D,DC,FE,B3,5E,45,B9,06,19,67,36,5D,B6,2C,B0,2F,BE,0C,60,D9,88,B0,AE,23,19,77,44,F3,1B,A9,E3,20,2C,98,DA,39,D6,FF,78,6C,87,BE,63,9E,AB,15,95,77,91,7D,0C,02,43,DB,63,A0,47,F4,59,30,81,98,B7,AD,26,3D,5E,17,2E,46,13,12,88,D6,70,9B,E4,AD,68,FA,DB,5E,D4,C4,BB,65,E5,96,D9,83,C6,D8,8D,03,F3,F2,6A,80,FD,98,AF,6D,2D,EE,FB,B2,DA,54,72,E9,5F,C4,2A,72,2A,EE,5E,E6,8F,02,29,C2,88,A5,BA,74,54,E8,63,96,A8,27,55,86,A9,1C,B6,29,90,B7,1B,E7,38,A5,85,80,C9,66,E1,3D,D8,4A,6F,25,F9,C9,AA,BF,6A,F6,B0,26,6D,FC,55,E4,FB,57,4F,06,73,89,7C,26,44,77,F5,24,33,CE,FD,16,31,40,ED,D9,99,E7,7B,CE,F3,94,0C,AF,15,48,28,20,06,C6,C6,32,D2,BB,8F,EB,15,69,A5,1E,E5,31,68,85,4E,35,D6,23,01,2E,92,5F,5C,90,E2,57,8A,9D,7F,70,05,AA,27,CC,07,05,7F,94,AF,B7,3B,0B,62,EA,D9,2D,26,57,C1,B5,51,CC,3B,3B,DF,63,13,E8,1C,CF,0B,E7,4F,89,57,1D,3D,7E,80,FB,02,8A,B0,8F,2C,09,FA,31,F1,AA,5A,2E,A2,A7,8A,7A,E0,1B,25,6E,C1,D6,3E,86,E2,E3,97,92,BD,EF,90,CE,E8,F5,8E,97,B8,82,B9,30,89,E3,60,B6,B5,73,F9,19,AE,F7,85,84,D0,FB,08,5E,D2,DF,86,C8,26,2C,F1,5C,C7,DD,51,A1,0B,0A,C3,D5,B3,99,30,A7,E2,FE,2B,DC,7D,0B,A1,29,2A,D9,A9,2D,54,2A,5F,70,3D,A0,29,C9,73,78,76,1E,77,92,1E,1B,C4,1F,F5,57,D1,AD,D3,11,A3,C7,07,F9,36,ED,FC,3D,24,6C,00,FC,3E,F8,93,61,F6,72,3D,12,DD,83,D5,74,40,14,9B,DF,C2,2C,F9,DA,79,4E,3A,38,5B,74,29,82,88,F7,9F,B8,A7,D0,C2,E0,F0,C1,B8,CC,19,99,5F,22,EB,0F,A5,3D,CD,32,73,19,4F,B1,CB,B8,E8,6E,A9,75,89,8F,E7,99,56,77,53,E5,33,15,6C,38,A6,02,3B,E4,12,76,94,65,EC,DA,27,EF,91,B3,02,56,79,A8,AC,8C,FD,AE,AE,1A,5B,73,90,46,2F,AC,34,D7,2B,AD,65,EF,19,47,48,7C,54,32,91,95,EA,BF,6C,FE,EB,C9,36,C3,7E,0F,0A,34,3B,54,6F,5F,37,4E,63,D1,87,6D,25,C0,82,8E,D6,C6,C3,EE,35,FA,E8,79,39,C0,CE,95,3A,6F,3E,6E,28,6C,E0,E9,3F,8A,A9,CE,D2,8B,FB,F2,49,E9,AD,ED,C8,4E,D8,B8,EF,C1,55,5A,7E,4F,E4,E1,F5,C8,1D,EC,FE,21,62,A3,93,B0,75,0E,C0,F4,01,3C,AE,E8,6C,D4,6D,02,C3,E3,71,18,06,97,C1,F4,3A,DA,FE,ED,BB,17,6B,48,2F,78,A6,92,BF,F1,AC,51,DC,F9,91,1A,BE,03,27,42,3F,FA,4C,57,0B,E2,9E,90,D5,CF,36,80,87,D0,2F,FA,CB,89,CF,DC,93,65,A1,22,67,73,46,BD,75,83,26,25,B4,28,A7,71,19,BB,28,24,67,89,5F,80,A8,25,F4,4D,5E,E8,16,5E,71,7C,70,F2,C7,31,77,C0,CA,8D,A1,0F,31,CA,49,26,CC,2B,42,6D,78,B0,3B,61,07,54,69,8A,3C,DE,5C,28,EE,00,05,F5,F5,02,43,7A,93,BF,DF,9D,CB,60,EF,EE,84,3A,22,69,44,AC,8A,23,49,58,11,10,19,21,C0,93,45,8D,9D,57,B2,19,A5,F8,F3,7C,3E,4C,1D,C8,87,FE,09,79,67,92,36,75,84,77,4A,C7,CD,B3,E2,7D,9A,E7,B3,15,DA,9B,49,F6,33,B4,E8,25,A6,55,45,C1,3D,39,3C,6D,B5,65,E5,AE,08,2C,2B,A4,CF,BA,E7,09,C8,22,3B,CE,03,91,9D,36,E7,4A,A6,B3,71,4A,54,9D,90,0E,9A,C5,98,30,CE,24,21,81,30,03,AA,B1,75,E4,86,10,59,A4,10,F2,E4,9B,B5,39,27,74,1B,D7,92,E6,19,D8,F6,AC,63,63,31,40,0C,8E,04,7B,BF,62,94,67,D0,B4,FC,40,34,75,0F,71,B6,44,E0,BD,49,02,BB,81,F6,BF,79,41,2E,E1,88,D4,EB,A9,D6,6F,CC,8E,57,0A,18,8B,14,72,B3,93,64,5C,9D,3D,87,25,AE,0D,6A,66,BA,B0,3F,2D,8A,45,B5,B2,F2,43,E7,7B,56,EE,7F,68,81,2C,91,50,D7,B0,C8,B5,5C,6C,8A,BF,4E,0E,AA,1A,54,94,1A,91,C8,4B,7B,AC,2A,18,22,D3,B0,E9,2F,38,31,24,A4,3E,03,9F,BB,39,56,77,1E,82,E7,C1,20,64,62,97,0F,50,CB,06,81,10,AA,95,80,39,6E,70,9B,8A,48,6E,9B,39,4B,52,7F,41,EA,2F,42,7D,18,17,3C,8A,76,A8,2C,42,5B,05,02,26,AD,3A,56,AC,ED,FA,3A,97,34,2E,7E,B4,E9,E4,ED,D1,32,3B,E7,A4,37,FF,D2,26,C9,9A,D8,D4,38,17,21,7D,B5,05,C7,58,0B,00,AB,D5,D0,A6,8E,20,64,1E,FF,99,BB,5F,89,D3,96,9A,50,C7,63,23,DA,FC,A2,16,08,83,1D,1D,75,F8,BE,D7,89,56,F4,5D,B4,16,42,2F,27,9D,72,31,61,76,8D,2B,1C,F4,84,52,27,3F,75,CB,5B,B2,04,F4,40,C2,6A,C9,55,D3,41,D0,96,96,55,8F,12,71,0C,A8,93,F8,61,9C,FC,1B,83,25,AF,CA,D2,50,80,60,38,09,A1,2C,EA,96,C6,CB,A2,E1,9A,55,95,85,1C,5D,C5,01,CA,97,F0,80,AD,51,C9,DA,4B,F4,26,6F,99,76,1A,46,63,EC,02,C9,F5,4D,AD,4A,F7,50,96,F7,7E,1A,65,19,08,AE,A8,FD,B5,B7,3C,86,D6,ED,5B,7A,B2,F3,86,E5,41,B4,7A,C7,90,AB,F6,18,8B,56,16,CF,CD,AE,77,63,AA,D5,74,76,D7,AA,16,17,DD,6B,33,8B,72,07,C3,FB,AA,8F,05,3D,EF,80,1D,DB,08,0F,3A,CF,5B,41,7A,BB,D7,FB,63,31,B1,35,E6,D8,F8,AB,56,8C,3E,2C,D1,8A,90,C0,33,75,E7,46,9C,29,F2,CB,6B,BC,59,E8,48,B6,59,54,9E,08,CA,9B,BD,3C,12,0D,33,78,E2,86,29,9C,F2,65,87,AE,AE,A6,9F,36,EF,C4,42,2D,4E,0D,95,7E,43,78,07,98,93,55,26,D8,F3,8D,97,01,85,C9,5D,D0,C3,D0,9A,9D,F9,72,04,47,4E,1F,53,EF,25,44,07,CC,14,7A,0F,C4,3B,0C,8F,E4,7E,37,11,8A,D4,C6,3A,68,01,55,49,E2,40,6A,34,27,CB,42,FC,D4,F4,C6,9D,B1,02,8E,C1,57,31,73,D0,B0,A1,A3,18,07,34,F1,AF,C7,01,A3,EB,09,EF,A3,8A,FE,7F,A9,DB,2B,E6,11,52,61,8E,ED,9D,86,63,14,7B,FC,DB,4D,06,46,4E,5F,93,CB,DD,6D,CD,3D,10,DE,CD,DF,F9,8F,CD,93,10,BD,26,76,99,89,C6,E5,90,92,94,F9,89,4C,32,89,19,63,1D,C4,42,55,E4,CB,22,4F,D3,CE,5C,CE,F7,CC,CC,F0,14,C3,86,F5,B8,14,8F,16,AC,D9,7E,15,97,9E,39,3E,7F,39,73,DB,79,00,FE,C7,53,3F,4E,4E,84,69,3E,1F,03,73,17,49,96,A2,85,A2,D8,49,80,B3,3B,59,17,43,8C,57,CE,F5,DB,C6,1E,6D,37,6B,A1,D1,52,4F,B3,97,12,32,23,F9,F6,49,3A,EC,D4,4D,2A,7C,35,80,A3,B5,4A,43,9C,7A,80,75,FE,E0,DD,EB,9A,4B,0A,27,DE,A0,76,23,FB,FA,AE,BB,57,97,CF,0D,D0,6F,A6,48,88,15,3E,17,AF,0B,4B,5F,46,0E,39,4F,B3,97,14,BD,75,71,5F,46,EA,84,58,31,A4,E2,31,90,09,59,3A,A7,28,BF,FC,87,75,DF,46,8D,33,10,DC,97,AB,01,70,BB,28,0E,BA,91,44,19,CD,8F,BA,0E,74,3A,AD,A3,AB,31,ED,68,C8,78,89,E2,5C,F6,59,98,1A,23,91,10,1B,A9,FD,47,46,DE,44,22,C0,B1,4F,75,6F,D2,38,A1,B8,43,71,7C,EE,07,8C,E2,C7,ED,16,5F,E2,45,FC,D9,6F,34,D8,CE,D3,8E,63,50,71,39,DA,64,85,88,18,7B,8A,3E,D8,FB,1A,09,F4,DA,B0,13,46,D9,95,AE,AC,68,6F,0D,FF,5B,47,8D,00,93,28,A9,FD,B2,19,B6,C6,3F,28,E4,3B,95,1D,33,7A,A3,4E,F6,32,B3,B3,41,F1,89,41,33,78,2D,51,18,29,64,16,42,89,6D,C5,8B,16,DE,64,A6,6E,C2,30,74,97,29,82,89,8E,42,18,A0,9E,09,AD,B7,BE,DE,02,B4,5D,EE,5C,F8,36,76,94,6F,81,C9,38,7B,39,95,33,AC,42,CD,0B,45,57,B7,E6,49,9A,AF,AF,C1,16,0E,12,81,B2,0F,15,6C,AD,31,14,E7,31,04,98,BF,56,45,B8,D8,46,91,3F,AF,50,EF,41,87,CB,C4,B6,0A,AC,F4,E6,B7,A5,52,DA,DF,82,61,0F,59,89,CB,89,D8,7F,68,3A,34,49,48,BB,5C,6E,EE,6D,01,1C,0D,79,CF,72,61,9B,1E,8F,BC,FB,0A,63,93,59,8E,70,C6,49,7B,AC,57,C9,CB,5F,65,A7,F5,6E,1A,25,B3,A9,F7,C7,C9,81,CC,94,F9,F3,85,26,49,D1,AC,37,CE,D7,BE,CD,C0,DC,3B,23,69,91,7C,08,4C,B5,DC,AE,35,A3,E4,FA,87,EB,3A,85,B4,5E,F6,C6,8D,6B,D3,CF,61,5E,04,D1,C7,81,E5,2F,F9,86,02,AD,6B,6A,29,54,B8,25,E0,AB,79,C6,14,2B,2A,C7,76,8B,0B,CB,43,60,BD,5A,13,30,3D,30,61,42,B8,E8,AA,8C,41,29,90,5E,DF,68,45,CD,8B,1D,DC,9E,CC,16,19,6C,9E,C0,84,F9,C2,3C,A4,09,B3,3B,64,02,13,5A,B4,C5,24,BB,25,A5,5A,91,27,B9,50,3B,3B,0E,02,D1,AB,02,CA,FE,D5,71,36,56,20,39,3E,5C,11,95,31,6D,6B,C4,1E,7D,06,6C,93,90,BF,BE,1B,9C,AD,AE,1F,37,23,3D,DE,CF,95,DA,1E,F5,25,5D,1A,37,C1,A9,15,14,0B,9D,3A,CE,AA,C6,D5,A7,DA,B5,A9,9E,64,6E,AC,9E,64,7A,38,6E,86,85,0D,9F,45,64,E5,2A,33,3B,F5,25,2F,66,97,2F,55,90,00,11,5B,DC,BC,3B,6D,15,12,E5,D6,25,A2,AC,9A,56,38,22,7E,65,F1,E7,E9,FB,42,CB,22,C3,44,99,01,B1,7F,0E,45,B3,1F,A5,F4,BD,9A,81,BE,51,50,49,FE,A4,2F,A3,C6,90,E7,B0,75,21,73,81,9F,88,2F,49,FC,3A,BC,9C,EE,65,80,CF,FE,49,A0,86,4A,BA,8F,F5,95,4D,63,DA,CE,23,0D,AD,E7,B6,A8,FE,5C,D1,A3,81,3F,61,A5,35,41,8D,AC,38,8E,6B,09,CB,0C,CA,DC,B8,A3,2B,9C,03,0F,D3,F7,4D,49,4E,73,2B,BA,54,59,0C,C8,2A,18,F1,CD,21,BB,F4,43,F0,08,12,65,5C,47,CE,F2,29,01,42,AE,5B,4C,A1,B0,66,F2,D6,6E,F1,C5,22,8A,60,AE,4B,20,BF,ED,4B,8E,6A,FF,A2,EF,1D,57,11,12,56,59,78,82,84,20,13,A2,16,FE,4A,54,FE,B5,B1,B3,0D,23,D8,5D,58,F4,D5,85,0F,35,19,6D,5F,B9,A2,5C,59,F1,32,F9,87,0F,25,88,EC,14,CF,FA,3D,8E,CD,C3,39,24,0A,AD,EA,2E,61,99,92,AD,CD,3B,2E,B6,BA,DB,D5,1A,A2,1E,77,7A,7E,DC,BF,42,A8,52,4D,67,44,5C,F7,CC,DA,CA,48,23,8E,24,91,31,F1,A8,28,26,C7,0D,A0,11,38,4E,BF,78,26,90,2A,1E,14,0A,23,E5,5F,F7,66,21,5E,B8,2A,FA,2D,AD,B5,9D,81,DF,15,21,BA,8D,53,E4,54,2F,08,B5,19,23,E7,8E,BF,18,8E,7E,56,3F,6D,C2,34,D7,04,5C,59,16,C9,30,B8,CA,6F,13,34,5E,95,1E,C7,49,D4,CE,50,19,19,7F,56,A8,29,BC,A6,2D,91,25,37,E6,FD,53,AF,CC,21,1F,25,32,F3,C9,24,E3,86,C8,F2,B5,D8,D9,60,34,6A,8E,FE,1B,49,5C,46,15,FE,DF,0E,84,48,36,17,0F,A8,46,18,03,91,9D,6B,04,85,B3,D6,30,AF,23,2C,3A,D7,64,A2,00,EF,BC,AD,D3,01,4A,42,BE,B0,B3,B1,37,8C,26,50,8D,F3,ED,00,A1,9F,D4,19,05,E5,38,21,AD,4A,C3,66,1D,8A,2F,22,EB,9C,A9,31,B1,8F,4A,6B,0A,33,4C,15,B9,60,4F,2F,C9,A3,64,0D,83,C4,60,5B,9E,F8,58,EC,27,F7,C4,5F,C2,59,22,6F,2D,D5,4B,B3,A4,82,B6,90,72,D3,D9,DD,5C,51,D0,FD,A5,FA,48,34,39,7F,F6,50,1C,AF,2F,53,05,4B,33,CD,0C,27,81,B2,38,79,5C,81,04,46,4E,05,14,72,9E,62,EF,9C,9A,AA,6E,CD,80,A1,E6,67,8E,B2,5F,8B,A5,53,90,F0,C5,5B,78,3B,8E,BF,36,F4,3E,A1,63,04,5B,7C,11,12,D8,FE,FE,DB,62,92,84,81,16,5D,B5,6B,66,E9,96,C5,DB,1B,90,D5,F5,C0,12,85,31,FC,60,7E,CD,9F,AE,42,AB,4C,B2,8C,95,30,AA,AC,45,96,F2,A4,B1,19,1F,B4,67,AD,BE,77,F0,45,16,C4,50,BE,06,38,4E,7A,8C,8A,E1,25,B0,B7,4F,30,3E,99,62,6F,21,FC,70,F3,22,2A,24,E1,B5,70,CE,A6,62,41,E0,B1,9D,8F,0A,98,27,7E,48,0E,86,94,2F,31,CD,6D,83,0D,35,8A,7D,61,14,DF,34,93,EF,CB,89,5F,51,6C,34,A0,8F,47,75,8D,87,EA,69,4D,8A,3C,9A,5F,69,7C,14,C7,47,03,31,9C,E2,24,5A,61,54,4B,63,6F,60,6A,85,62,C0,C7,BF,19,0A,86,8F,55,AF,E4,64,0C,EB,12,6A,0A,57,13,16,C8,7D,2C,CA,FB,4E,1D,D1,E6,C7,CB,73,ED,AB,B3,E5,FA,F3,98,BF,2E,67,8E,E9,1D,BA,25,27,AE,5D,89,E7,F8,4B,78,C4,AA,9B,0B,BD,2A,F2,B5,23,E7,9C,12,33,67,3C,AB,3B,22,F8,5E,D5,22,A0,D7,7F,48,91,76,FC,CF,D2,45,CE,F2,AF,F8,45,C2,A0,F4,51,DF,8E,15,7A,63,27,7B,7C,95,F2,35,E0,B5,D2,38,E2,3A,41,5A,A7,88,B7,BE,7F,C6,19,02,4F,30,FC,F1,69,F5,63,7A,04,28,DF,F3,E3,3B,0E,D6,5D,15,DF,E6,63,48,E8,C2,37,9B,B8,B1,FA,F3,38,AB,95,F5,49,EC,42,92,62,07,24,F5,C6,89,6E,B7,07,95,C5,AE,F1,41,EB,AB,47,76,FB,89,00,1E,D1,70,F6,C0,8B,27,AD,8C,E4,80,DE,65,38,7C,90,F0,7E,A1,76,9A,3A,3C,34,30,82,1B,26,F3,24,C1,CF,89,44,9E,48,61,23,05,C4,CC,CF,25,DB,52,98,8E,A1,53,3E,89,BD,1C,A6,5D,36,DE,0A,67,DA,25,20,BD,50,73,A5,FD,7D,23,E7,8E,55,DF,D6,DC,EC,C8,35,08,88,13,82,81,AA,B3,D6,86,59,7D,5F,E2,34,69,D8,A6,C8,51,A2,C0,4C,DC,BC,1F,98,E3,75,97,ED,C6,CD,B1,C2,FE,B6,1E,54,78,76,B7,CD,E1,E4,30,76,9C,8B,2D,FF,DD,66,FE,C8,F7,B7,56,51,90,84,D8,69,F4,7C,10,B0,8C,C2,7F,FF,EB,25,67,10,14,D5,C0,A7,E0,66,A2,B7,9C,40,F1,F5,EA,53,D6,71,4E,CD,7B,01,B9,C3,C5,C9,34,B6,4D,78,20,D7,4D,A6,57,65,24,E9,5B,3F,AB,08,01,7E,B3,91,63,7D,A3,FC,FD,93,63,97,05,B4,1E,D7,2F,8F,64,21,95,E2,10,98,BB,C6,8A,53,88,C3,6B,EE,40,2F,11,90,5B,23,AF,68,B7,79,75,02,3E,35,D2,F7,AB,87,7B,22,F3,83,79,6D,1C,8B,EF,F3,86,77,C3,C3,CD,AA,58,14,67,81,F7,60,DE,43,AA,47,2F,20,F1,4D,70,A3,80,58,B5,B9,B4,F1,2E,AC,C2,F1,64,17,37,30,AC,0E,FC,EA,8C,A4,DF,0C,25,DD,26,1B,A2,98,28,5F,10,7E,DA,5C,81,DD,BD,88,98,72,82,B0,20,C0,06,12,CB,B6,E7,AC,B0,E2,C6,7F,BA,A6,8F,00,CD,55,D4,6D,4E,54,27,36,09,9D,2F,F2,24,94,67,4B,C8,52,46,50,34,F3,5E,F0,E4,E1,94,B8,24,E9,0C,0D,89,C6,AE,CD,D8,6D,A0,8D,DA,B9,60,F4,45,8D,B7,C1,9B,38,2B,4A,7C,55,A8,B0,62,AE,03,67,64,A1,26,E4,7C,08,C8,9F,E5,9C,6B,55,28,4F,D2,35,53,7E,BC,B4,E3,31,CA,BC,7B,FE,7D,D4,BB,DD,3E,35,85,29,6F,8D,69,BD,B3,B0,99,E0,3E,6C,FD,BA,E4,F2,5E,3F,39,F8,7E,DF,D2,31,9D,C1,9D,7E,EF,7A,FC,97,51,FD,9F,08,29,68,B4,36,3C,D8,5D,24,18,8E,43,4B,73,12,38,26,3D,47,F9,23,6F,8D,9D,5D,31,02,2A,64,47,AE,62,DE,54,F9,A5,81,1F,75,1C,19,7D,38,C8,D3,87,6D,B6,F1,DB,89,10,B0,1C,13,96,B2,05,3E,6E,9E,C4,6B,BE,CB,BF,F3,F9,21,1B,FA,C5,62,09,55,DC,19,17,01,19,BD,19,49,97,A5,8C,8C,69,1B,C9,81,1C,6B,DF,06,BF,B6,C6,1E,F5,DD,81,4D,85,E0,E0,92,40,7F,63,8F,49,1D,A1,40,F2,D2,81,57,0A,0F,17,A0,48,2B,80,34,77,DB,84,35,97,F0,63,31,33,55,70,0B,FC,C2,4D,F3,01,8F,0C,9E,A0,C9,F3,28,6C,B8,AD,63,21,D6,C1,C4,92,B2,D2,18,70,AB,DA,48,D9,28,C8,B7,0F,E6,4D,45,DB,00,21,2D,5B,DA,4E,E1,6D,CE,46,FA,34,53,82,E5,34,17,B8,17,E0,DF,27,36,26,F8,41,8A,23,7C,0C,FA,59,21,10,9C,19,28,B6,99,68,6A,3D,09,31,BC,41,BD,07,D9,C1,92,D8,5B,0E,F3,E0,2C,8C,2B,3E,7F,45,56,56,FD,F9,A8,AE,53,D9,47,F5,33,85,8A,1D,9E,ED,38,F6,B5,7D,4C,57,A6,6D,F2,11,38,CA,32,FD,90,46,D0,A5,93,23,C1,14,BD,E6,97,92,B0,CF,90,F6,7F,D7,6D,3F,C8,C2,88,3E,DB,25,49,5B,8F,B4,E0,8A,CA,07,A4,51,24,57,A5,F3,10,43,8E,A7,E4,46,DD,0D,54,E5,D9,8B,9A,33,04,F3,03,18,54,0E,F1,2F,24,20,19,BA,FC,AC,9E,C1,0D,A2,88,BE,5A,F4,DD,4C,82,91,E8,71,D0,32,2C,D3,96,87,1C,13,4F,0B,89,C6,26,A5,92,64,DC,7D,92,41,4F,19,F2,A7,5C,5E,4C,E1,D2,68,0D,B4,53,AE,C3,85,DE,70,61,9F,52,B5,29,C7,46,06,69,F0,6F,44,AB,DC,6A,0F,BC,E0,00,18,63,45,E1,C9,7A,1C,AC,DA,98,3F,BA,8C,A2,C3,5C,09,3E,DD,F3,8D,B8,02,76,63,79,CF,6D,73,CB,C5,32,CA,03,EA,44,6C,5A,74,4A,84,71,AB,48,1E,23,34,E8,43,BE,FE,EF,EC,EF,48,5C,56,1A,C0,21,52,16,47,CB,5C,4E,9C,26,B9,85,0B,B2,09,AF,85,12,BE,0C,C4,FA,31,9C,BF,A9,32,E1,55,87,9F,D0,C0,07,4A,16,39,AB,67,23,F2,89,EB,16,87,79,46,AD,8D,6D,AE,20,58,21,04,7E,66,C0,F3,1A,4A,EB,89,95,22,C7,56,17,03,CB,DD,2C,06,D8,68,6F,D3,54,8B,4E,4E,7F,7C,54,D7,5A,B2,B8,71,55,15,A5,F0,D0,8D,89,ED,4A,A8,55,90,43,30,B9,9F,E5,7C,D3,57,A6,0A,1C,BA,61,EE,E6,68,F2,0D,E2,5A,44,EE,7E,0D,16,8B,D1,F5,38,0B,01,45,CE,C3,E7,CC,BE,C2,69,DA,F0,47,F5,21,30,59,0F,F6,0A,B9,23,F1,9E,C6,83,FD,9D,1E,AB,49,DB,68,2B,BF,FF,86,E0,28,32,F5,49,81,3E,6F,92,05,92,EE,A6,DD,93,E5,1A,8F,12,4C,FA,B1,40,AF,F9,36,F5,65,E2,39,B2,FD,B0,E3,8B,5F,E5,81,7B,CC,F1,BF,CD,75,0B,0A,8B,1E,84,9F,64,CB,D1,19,B4,FF,DC,B5,C3,BA,E5,FB,DF,C2,0B,0B,E8,4F,E5,EA,CA,69,80,E4,1E,34,21,5E,B1,C9,F6,D9,E9,D0,9C,A6,53,3A,D3,8B,9A,FB,AA,F3,0C,0F,A4,F9,66,96,2A,56,37,D0,AB,AB,D2,4E,DB,EE,36,8D,1E,32,25,0E,43,8A,63,D7,02,F4,5A,49,4D,04,7C,59,65,6E,A5,5D,79,2D,99,45,82,B4,F4,2E,39,60,08,B2,61,8E,66,F3,D0,5C,B5,45,0C,ED,9D,73,E6,2D,AA,A9,F9,C0,CC,9C,1A,CA,31,A8,F1,C0,3A,5A,7B,9B,22,54,D8,93,8F,B5,27,96,49,3F,78,06,DC,D6,16,73,87,13,68,A6,2D,6F,A4,2F,04,1B,E6,EC,C8,B9,BF,4A,8A,A6,18,53,D3,6B,35,24,29,9F,9E,5B,4F,4C,DC,C9,89,88,D1,FD,C4,73,05,4C,98,EF,E7,A9,98,A0,CD,65,9E,7E,72,D0,F2,76,86,1D,E2,7F,0F,07,70,87,F9,46,64,17,86,91,58,C9,20,C8,7D,AE,D0,A2,ED,34,C7,EB,AA,45,43,2D,4A,9F,13,65,76,4C,29,9D,F5,48,AC,21,36,A5,EC,48,6E,AE,DA,85,F9,A4,B1,26,C7,82,10,9D,43,49,85,5B,51,33,65,30,FD,3B,5F,B6,CB,54,BB,DD,87,B8,49,89,41,15,DA,A2,14,A7,32,1C,E1,CE,45,B3,1D,0F,20,DC,9F,B0,CF,FF,0C,93,B9,14,6B,1E,44,BE,F7,0D,67,FE,AB,4B,E0,09,F1,FB,5C,DD,15,56,A8,4B,E3,03,56,4E,D0,70,8C,0A,8B,41,52,40,43,FC,6C,39,A3,2A,8C,BB,F7,EF,42,25,8E,AE,0E,41,91,10,A1,F3,16,DC,B5,2A,C1,28,EE,BE,01,A5,90,AC,8A,4A,12,0E,DB,5E,B9,55,AD,77,8D,D6,88,A6,D8,30,20,F9,69,92,80,D8,0E,81,E4,BA,BF,77,D0,92,93,C3,96,A2,08,26,2F,88,42,3F,AE,5A,19,7D,CB,7A,3F,13,F9,3C,DD,6C,AA,AD,CE,36,27,EC,ED,61,BA,11,7B,98,7F,77,21,D6,F7,95,94,CC,1F,A6,96,F6,A5,0F,C6,BA,C1,14,1B,B4,00,57,D4,52,FA,03,BC,C5,1A,5F,F9,8B,EC,5A,9F,E9,06,9E,4E,02,FC,4C,89,8E,C6,0F,8C,95,3B,26,07,4C,FD,D3,76,93,FE,80,EB,95,3D,C1,65,9E,58,DB,DA,A0,CB,96,AA,E3,58,CB,26,65,11,73,5D,84,44,C4,D9,A3,94,8E,EC,F8,CF,60,62,D9,12,AC,52,7D,B9,A1,FD,39,46,16,4B,69,07,AA,14,40,E5,C6,61,80,17,A0,44,DB,A4,C5,0F,D5,46,91,91,48,EA,46,1C,CF,CB,1D,FF,8B,9A,92,EA,84,AB,D4,59,66,5D,02,C6,69,34,78,7F,DA,08,64,62,0F,9C,12,28,35,B1,5B,49,08,20,E6,FD,8A,B6,DC,85,3F,31,7D,47,C4,88,33,09,93,F5,B3,F8,3A,8F,A1,78,B1,56,CD,3A,AC,00,D4,5A,62,C1,8C,3C,B7,96,BE,4F,C8,0F,9F,CC,C8,42,93,C0,0A,9E,1B,BE,CD,9A,66,E7,F4,67,EC,B5,9E,80,3B,3C,F8,D5,A2,CB,FE,DD,B0,C8,AB,39,85,57,B1,77,BB,B7,AC,1B,29,18,FF,CD,49,D8,04,1E,0C,75,28,0D,79,8B,53,20,2D,C7,72,22,5A,D6,F3,CA,F9,80,E3,B9,56,25,19,02,23,65,EC,E7,95,E8,8B,F4,24,29,91,5B,ED,AE,75,DE,67,05,A8,E5,E3,27,4F,0A,AC,B5,24,78,C9,1B,A2,4D,57,EC,D2,94,FF,D4,0A,A6,EB,73,2D,BD,03,CE,75,8E,05,8D,9C,8D,5D,77,FC,D4,DD,3E,73,A9,25,16,D6,84,88,D6,05,20,4F,56,19,AB,22,6C,A1,68,F0,75,DD,0B,23,F2,62,89,EC,C5,D4,FA,AA,34,81,D3,F1,75,F6,DE,02,CE,78,BD,EB,84,02,03,0E,D6,3B,CB,F8,8C,F5,1D,FE,AD,B3,BC,C6,6B,C2,91,E6,E7,54,06,9E,73,70,7C,D1,E1,A9,E0,3C,98,8F,F3,0A,D0,BE,76,88,DF,57,D7,FB,DF,96,FD,6B,40,61,6E,2A,97,2E,47,E7,E3,E4,44,34,87,E3,68,CA,AF,CC,E3,94,52,3F,DF,85,5D,44,5C,14,EE,43,73,8C,6B,A0,3F,CE,8A,42,17,9E,AA,D7,98,77,15,6F,4F,20,68,5C,5D,BD,3B,01,70,8A,96,ED,A9,1E,1E,7E,F9,B6,2E,05,E1,D7,F1,42,9C,65,39,4B,F2,07,A8,ED,9D,8C,30,15,67,E1,05,98,00,DA,FB,77,14,DA,28,D1,27,DA,E9,A7,60,3D,C3,3A,E4,AC,F3,BF,DD,CF,D4,C9,46,97,B1,83,F5,1D,AD,D0,21,1F,2A,D4,A5,3F,33,2A,EA,29,CD,19,58,4C,E9,1E,EF,64,D3,C2,2D,8A,12,17,23,35,D8,AD,1F,D8,E5,E9,22,51,9F,B7,B5,DE,B2,85,9A,53,4C,EC,D2,41,F0,3C,E2,EE,3A,74,CA,AD,81,0E,EA,17,C2,61,56,EC,CE,2C,63,9D,1E,FE,A5,24,83,F4,9D,EA,04,EA,97,0B,83,1C,85,00,11,3B,7B,07,20,3A,11,90,39,63,99,97,33,AF,A2,B7,6F,DC,45,32,F4,EA,6C,DB,5D,13,43,73,1B,07,82,D2,36,78,E3,9A,B5,6F,1B,DA,C2,76,F7,48,9A,1F,89,38,F1,FF,82,D5,41,1F,7B,15,9C,DC,4C,95,1E,9D,8F,3E,36,1C,6F,A2,F7,EB,2D,6A,31,38,BB,3D,73,C4,1A,12,C2,DA,48,4B,57,06,DB,03,3B,EF,F8,76,B8,B8,3A,BD,07,DE,A2,B6,9F,C6,E3,31,F5,D7,CC,64,C2,B0,02,27,B5,73,F8,39,F4,32,ED,9B,8E,CC,5B,D6,88,E1,55,89,0C,3B,63,5B,81,5B,62,BE,D9,78,8F,C6,FB,B6,62,96,1E,41,C0,1B,5C,CA,EB,04,22,97,06,CF,F1,F6,28,B8,DA,E9,26,0F,18,62,0E,9F,B3,0F,B5,24,59,62,29,9A,25,8B,7D,DB,26,A2,78,E4,97,8A,51,98,12,67,90,0B,F7,28,60,EE,66,B7,47,BD,B7,E1,F0,78,42,46,37,5E,95,CF,DA,B9,D9,21,8F,03,71,3B,FA,11,8C,AD,42,59,79,2B,01,B8,C0,04,ED,3C,2B,F0,12,74,6E,76,90,4B,A5,5E,39,96,BF,6C,A5,1F,3E,AC,17,BE,69,AE,C0,05,63,AB,92,B3,F4,C2,03,2D,37,1C,21,C6,C8,A4,EA,E2,FC,A1,62,93,6A,B6,70,AB,7D,B5,3B,6D,6D,73,3D,F3,3A,6F,A2,73,9B,A8,BE,89,D3,85,CA,02,B0,C0,30,86,3E,BC,2C,93,31,A0,60,FC,D2,42,38,D1,7A,C5,E5,B6,6A,1A,1A,27,71,F9,A5,BF,A5,18,46,0D,E8,1A,4E,76,14,14,CE,2E,BF,6A,84,48,59,AE,A4,11,65,49,F7,54,A5,39,31,28,74,B4,CF,F0,6D,23,DA,85,45,15,12,60,2E,70,06,F2,05,0D,87,71,41,AF,18,80,C6,6A,96,F2,F8,C6,F6,20,6D,59,04,6C,89,D0,09,D0,EC,E9,5C,7C,6C,5F,4E,D5,96,9C,D7,F3,27,93,2F,92,05,8D,67,8E,21,1D,F5,3E,26,2D,B4,26,42,54,2A,25,5C,ED,D2,6C,5A,76,70,2B,4D,90,76,C2,CF,A8,30,65,E0,F9,01,16,EA,B1,B2,28,5C,08,61,DA,52,6D,F7,55,EC,EE,20,38,CB,CF,3C,4F,87,B8,2C,86,CE,81,13,2B,7C,BC,06,D1,7F,78,77,59,CC,03,F9,FA,96,D9,3F,C4,17,7D,4C,78,17,04,6F,97,40,65,E8,AF,46,3C,AC,33,01,F0,F5,ED,F5,13,06,F4,F3,3D,45,19,91,48,AA,AE,37,12,06,3F,BE,FE,8B,ED,EF,82,02,70,A3,30,87,17,BC,37,AF,B8,16,AC,4D,0E,F4,4F,8C,7F,86,67,A4,CF,71,3F,7F,17,E9,A9,6B,37,28,1E,FC,F3,B5,C1,FC,DE,F6,D2,36,91,4D,35,B7,0F,C8,EE,86,85,76,87,00,EC,7E,5E,2A,F3,64,A4,02,13,A3,67,C8,4A,89,AB,A2,02,0C,87,7E,51,14,F0,00,B8,45,9E,1D,61,31,23,00,98,43,79,CD,88,0F,E0,0D,66,2B,42,F8,CF,1F,94,5F,D8,DA,0B,27,5E,29,F5,81,D5,B5,5D,3F,A8,DF,9F,36,39,E6,F6,99,0B,98,CB,75,CD,CB,BC,9F,12,34,12,F2,78,CB,15,A6,EF,BC,45,3B,D1,47,9F,2D,2C,CF,21,FA,BB,B7,F2,70,34,41,90,24,4D,C4,07,48,33,47,36,01,24,29,C9,D6,30,91,C8,39,13,D7,B9,27,67,5F,3F,B5,92,7B,FF,05,81,EE,25,33,CD,57,76,A4,8F,BF,FC,DB,EC,77,BC,67,C2,81,D7,E8,62,87,C5,D7,3D,94,2F,67,00,E5,4F,12,ED,FD,97,DD,1E,51,53,41,62,5E,AD,29,54,43,84,9C,EE,7D,AE,D0,B4,2F,B8,BA,83,50,E4,9B,2D,EC,E9,35,5E,6C,7A,7F,9E,AE,DA,8A,D4,DD,1C,BF,83,F4,BE,0C,61,55,B3,DB,71,17,2B,AA,AA,E4,11,CA,D3,43,05,F5,4E,1C,2D,CC,CA,01,7C,01,12,EA,AC,F0,73,B0,A9,5E,A9,5E,F7,0B,F8,30,D0,F3,6E,E7,1A,6D,E6,6B,EB,26,D5,47,3A,18,A4,96,41,29,28,63,59,5E,54,2C,F1,80,AF,D7,88,60,84,7A,DA,47,A3,C1,20,12,74,A0,94,C5,4A,03,D1,EB,F7,EE,5B,A2,D5,35,9A,B7,CD,BD,C5,9E,73,26,FA,CC,E0,C5,E4,80,07,63,F7,CB,48,42,31,91,2F,D9,04,02,F4,7A,20,04,F1,5D,C7,6D,47,FB,F5,ED,E8,E2,1F,17,7D,9F,AB,87,F2,AB,ED,6A,9C,F3,B9,1C,BB,C1,7F,71,D4,15,F5,C6,70,DF,71,76,D8,42,CA,D1,70,DB,71,57,22,8E,32,85,A2,03,CC,B2,63,5A,10,FE,EB,79,1A,8B,2C,B8,D2,C3,A3,5C,E6,98,04,05,8A,96,F4,00,99,81,33,7E,52,CF,F0,B7,F5,04,3E,13,19,10,15,1E,B0,4D,0D,03,91,71,1E,E3,39,DF,75,24,C4,C6,4C,5C,91,EC,0F,2B,A2,BE,4E,BD,A8,16,31,E9,33,30,02,80,AE,0F,7B,FB,73,EC,10,51,02,3A,B8,CB,FB,53,37,0F,D5,F0,46,FC,93,C1,61,48,84,A9,6C,A5,99,AC,92,B5,12,21,C8,3B,66,92,29,E4,43,22,02,3C,BA,EB,33,D5,17,A0,FF,0C,BC,4C,94,C5,C1,76,B1,A1,55,05,A3,74,E7,10,FF,98,90,0E,00,59,D6,89,7C,6B,96,59,79,BB,18,A8,9C,D7,72,8E,11,56,19,2B,44,73,7D,B6,34,1C,E1,9F,3A,3B,5C,16,43,50,0D,F3,95,0D,63,E9,74,6E,B8,93,ED,A5,A8,FE,BB,30,0D,70,26,FA,D4,2B,D3,C7,C0,04,D3,A3,EC,7A,49,59,9A,B0,0F,95,7F,27,CB,2A,AB,6B,AC,B3,1C,19,70,37,11,DD,C5,58,04,FD,12,B6,DB,26,A3,BD,C2,91,2A,6E,C7,2A,42,BA,2E,33,C3,DE,F8,95,A5,B4,F1,9D,30,B3,53,78,8A,2B,00,41,1C,97,10,3E,8F,AE,A8,A1,66,32,96,85,13,1C,7A,AE,54,84,70,9C,9C,31,B5,C2,34,8C,DD,F7,F2,81,52,80,8E,8C,09,5C,CE,82,C8,01,C6,42,D6,10,46,8D,23,86,FF,38,5B,0B,29,0F,BE,55,AC,8F,87,44,66,98,77,DE,60,11,8D,96,5A,27,84,BC,42,1F,49,F4,27,06,05,43,1A,53,28,36,55,64,16,17,1E,DB,67,40,2C,83,34,63,B0,FC,17,BA,9A,6E,14,78,6F,81,C6,07,AA,CC,BB,6B,66,4F,C3,A8,FD,47,DB,29,B9,27,56,7F,2C,BB,A5,8F,2D,38,A5,8B,B1,58,0F,8C,E6,96,0C,1E,5E,FA,C1,6A,C9,3F,AB,82,CA,3F,D6,74,6A,5F,35,2B,60,4E,8E,EC,88,D2,A3,B7,21,2F,CF,11,E5,82,F0,8E,74,05,4B,38,0D,C0,7A,68,9D,9B,0F,74,BA,E4,EB,D3,CE,F8,B9,5E,3B,22,95,46,A2,D2,3A,85,5F,C6,F5,EA,8E,24,23,49,F0,BC,92,86,96,27,E0,F0,5F,83,AB,C2,A2,CD,F9,3A,01,7C,0B,58,F1,AD,80,5D,4B,07,27,3E,0A,CF,30,7B,B6,52,1F,DE,F9,D5,9C,3E,EC,3E,5E,1B,65,8B,00,A7,2D,7C,13,79,1E,D4,4F,CF,52,6D,EC,A2,1E,27,43,96,4D,CD,6C,C8,31,BA,67,B3,18,0B,61,EE,D4,1B,90,8B,61,90,E7,94,DF,A6,A5,4E,25,A6,7F,84,CF,68,A2,8A,A1,E6,06,09,96,CC,92,B4,0B,EF,1F,51,F4,91,13,CD,90,2D,75,48,00,6A,DC,01,38,D2,18,4D,51,B3,A1,E1,80,C4,3D,26,47,A1,01,13,AA,1C,CB,CF,01,F4,62,2B,EB,6A,A6,B5,6B,1E,A3,45,DD,06,A5,0A,9C,15,DB,F1,EE,8E,2D,1B,BD,F5,8C,3F,31,A9,88,BD,94,72,5A,C5,CA,88,96,A4,13,FE,22,7B,FB,F6,B5,6F,B7,BC,3A,5E,77,5B,82,1D,21,E6,F9,B6,BD,77,09,F9,D5,A7,A2,3E,63,BF,78,AF,41,27,13,C0,DD,12,03,F9,58,85,41,CC,BB,BD,42,76,FB,8F,1B,A5,44,7F,56,AF,E2,C7,44,6B,D2,B2,F4,94,B9,FE,67,2A,D3,BC,56,27,85,AE,2F,20,B5,BA,AC,AA,C3,D5,7F,72,63,AB,5E,97,62,6D,AB,4B,DA,E9,01,96,8D,D5,FC,9F,4E,D7,57,F4,D2,9E,E7,D6,4F,BA,CF,E2,18,84,7A,99,7C,42,02,62,2B,1E,70,04,05,C9,F1,E6,D2,18,6A,43,D2,D1,43,C2,3E,94,80,4C,D9,A0,6E,A4,D3,41,D1,D4,F7,E7,51,6E,68,96,70,8B,B2,AC,ED,EF,27,FB,A6,F9,D9,AB,C1,B3,9E,AC,BA,66,98,1B,0E,ED,77,8C,CD,96,71,BE,F7,1B,52,A6,DD,11,4A,E1,FC,06,22,73,64,17,F2,85,9B,62,5F,93,A6,6D,EF,25,FC,BB,78,B5,12,70,73,3C,E5,8F,8B,22,63,83,8D,F4,ED,9D,07,76,25,A9,8B,85,BC,50,5A,F5,90,DE,4D,0C,2D,83,FE,B0,28,31,C5,6E,65,83,E2,E1,11,22,53,84,FA,35,27,0E,10,DF,5C,44,E9,CE,99,C4,4F,2F,C5,64,DB,99,E7,1E,75,F8,8F,D5,2E,AC,A7,B5,A6,8B,98,7E,ED,AC,DB,24,E3,20,65,18,1B,70,54,52,60,75,96,72,00,84,07,76,47,F7,51,A1,89,84,B4,B0,8B,03,BB,90,72,BE,16,71,84,C7,33,19,6A,9C,06,C7,81,34,B2,DD,04,66,1C,B5,D0,72,4B,04,5A,94,03,3A,B5,ED,C6,A9,50,4B,76,96,D0,A6,AE,E7,EA,3B,F4,15,2A,04,05,C6,50,5D,B8,A5,F9,69,1D,35,C9,39,1D,02,E3,64,B3,BE,C2,50,EA,12,0E,08,7F,FC,9B,17,FF,A6,E8,23,98,BC,04,59,F9,D6,E9,37,E0,F9,D8,30,4F,DF,EA,15,DC,5D,79,5F,9E,0B,4C,6D,52,10,82,4F,DD,3C,21,D1,07,ED,7D,D4,25,9B,56,1A,B1,7F,03,6E,33,BF,C3,50,62,3D,2A,64,8F,26,1E,5B,4D,4F,D7,11,7A,68,0E,7F,8C,C5,01,7C,EB,8F,67,54,B1,A0,73,9F,F1,16,AC,95,37,F8,7B,7A,09,A0,DB,1C,C1,B0,5D,F1,D5,86,12,CD,C0,0B,B9,7B,71,75,01,CE,3C,51,55,A1,B7,E1,47,CD,57,5B,95,9E,7A,DA,A3,40,C2,36,A0,94,2D,24,CD,F9,71,32,7A,16,5F,C8,C3,09,19,61,4E,97,FD,A1,AE,A1,D8,69,15,13,E8,3A,11,A8,64,EC,62,0A,34,1F,CF,D7,DA,7A,07,7F,EF,0C,9B,37,89,2D,1B,B9,E2,B3,97,55,30,67,86,41,3E,93,0B,FD,B6,68,32,A1,53,12,CE,D3,D3,5F,CA,83,6B,02,39,39,8D,AB,49,9C,56,AF,5A,03,5C,2A,BE,14,E9,E8,15,36,C1,10,8A,C4,F0,88,EF,62,B4,78,7F,61,8E,CB,37,B5,A0,37,58,11,55,67,CE,EC,24,B3,D5,43,F5,0C,79,02,CF,4E,33,D1,17,3C,DA,E5,10,C3,01,7D,3D,96,15,83,AA,1B,5C,12,04,2F,D4,52,7F,7F,5A,FD,65,33,C1,65,D5,51,2A,2B,C6,39,89,43,DE,E8,F9,77,3B,B7,B8,D9,3A,58,21,D8,25,92,15,ED,D5,0D,1D,C4,A2,33,2E,AB,A0,23,AE,DF,8D,C0,87,59,B5,BE,DD,6E,56,95,54,21,88,94,A1,70,E1,51,43,6D,2B,64,BF,25,82,88,BD,71,42,AE,61,11,B2,83,D8,3F,DC,F6,05,96,96,B5,E6,D3,3F,1E,1C,F5,A3,9C,A5,92,8E,26,A3,F1,00,2F,70,98,08,1F,27,98,9A,32,7E,80,3B,AB,7C,5C,77,DB,D6,8C,86,74,AA,E9,5E,E5,08,76,DE,CC,12,14,EF,85,3E,72,98,30,C1,9B,65,DE,BF,C5,C5,E9,5A,90,8A,C0,2F,57,BA,53,1F,12,B6,60,2A,01,83,3A,00,04,1B,EF,72,0C,CB,8E,57,FF,85,A4,3E,EA,45,01,17,1E,6D,1E,54,A0,6F,38,95,4B,99,DF,F3,64,B7,BE,A0,6A,67,15,F8,C4,7F,1E,7D,11,48,92,28,FC,85,2C,D5,E6,47,D2,D4,22,70,A1,AA,D6,C2,1F,1F,86,90,59,2A,34,27,C2,B1,D2,03,FB,EE,75,1D,62,5A,C6,9F,75,FD,0A,B5,CB,D6,AB,3D,18,2D,04,32,2F,8D,02,C3,88,85,F2,91,7E,40,62,62,11,90,1B,24,9C,84,29,C4,73,2C,F8,30,85,61,B9,09,7E,32,D9,85,42,70,1F,E6,2D,87,88,40,32,AC,5E,1A,20,E2,24,5A,36,FE,52,C5,5F,29,2F,4F,A2,C8,BD,BB,3E,40,C2,A5,A5,D3,2A,A0,6A,DD,54,8F,03,E8,26,A5,7B,68,F0,C7,7B,34,54,58,B1,07,31,B6,E3,8D,78,6F,17,F7,35,7C,CD,8A,87,26,DE,6E,16,3E,3D,3C,5E,38,3E,EA,DC,89,24,DE,1D,1C,D4,47,3C,47,BC,CB,FE,BA,E0,47,F5,02,03,0E,31,25,92,93,B5,3C,4A,9B,F8,59,08,1C,F9,B8,E7,F0,CC,45,56,4C,08,20,67,A8,1D,C3,49,F2,F9,13,B0,F7,4F,D0,5E,E5,B0,F2,9A,BB,90,E8,AE,48,99,A9,EE,A4,D3,96,54,D9,FC,98,9A,03,C5,ED,5C,1D,E2,A3,48,C9,90,FD,10,3D,25,AC,61,CA,F0,FB,3F,B8,C1,4F,CA,1F,51,A8,73,D7,E0,82,20,23,30,A3,F8,25,D9,51,21,78,9D,22,F2,DD,8C,7B,ED,9B,E9,A1,60,88,EB,80,E4,71,26,A5,A8,98,5F,E2,E6,EC,A2,DF,99,2D,EC,34,D3,42,E2,16,5F,B3,B6,62,37,F4,EF,2E,38,1B,65,67,75,1D,5B,ED,14,F0,50,F6,FF,2F,00,F1,9C,56,AD,D7,60,EA,36,7F,DE,9C,AE,AB,C5,A7,5C,A2,3F,24,E5,2E,24,E2,23,AB,C8,07,38,19,02,33,9D,6D,33,5E,07,B3,BC,5D,C6,59,47,0B,5B,31,A6,62,E1,82,53,A5,BC,58,5E,5C,50,E7,3C,67,61,C4,F3,D5,90,25,D3,24,BE,EF,DB,59,AF,4F,1B,7C,EB,DB,C9,FC,E4,EB,8D,0A,3B,0D,A9,8C,53,4A,56,03,FA,A9,B9,84,30,1C,15,ED,EB,60,42,D7,BA,11,71,C4,A1,BF,A0,8F,89,19,E0,FE,44,4A,2C,A4,DF,C7,EF,6B,F9,E0,0D,20,D9,F7,2C,95,E3,0B,3E,B7,A1,0E,8D,8F,4F,ED,CB,42,D3,57,1B,9E,36,8E,E8,C4,AF,E5,D5,C5,36,DF,96,DA,EC,58,88,CF,92,49,B1,04,46,88,B2,DE,07,D1,7B,C5,70,21,44,83,37,B2,E3,A8,17,92,AE,4F,90,6A,5F,9C,74,F2,B8,FB,5C,BF,C0,85,83,85,36,01,57,47,8C,1B,5D,74,27,C2,96,8E,1A,C5,AA,57,8E,B1,7B,F4,A3,7A,1C,B5,53,31,28,68,57,7B,90,C2,E7,A9,DB,17,A2,5E,83,F2,72,DF,A8,EE,30,F8,D8,19,CF,07,10,F6,67,33,88,BE,B8,7F,99,83,F0,99,A1,48,B3,E2,C9,D0,61,B0,33,21,41,8D,B7,2D,2D,32,AA,9A,D6,B4,21,5F,D6,F9,C2,30,51,6A,E6,0E,8C,58,8B,6C,F9,AB,47,9C,15,09,31,3E,25,67,C1,FB,2A,22,20,F5,14,92,E4,56,01,CA,AF,CE,4E,E0,2D,13,65,C7,BC,B9,D3,CD,32,E8,C4,17,15,CE,4A,0E,20,2A,37,E7,86,79,0F,FC,95,CF,BE,1A,9E,08,E9,65,EF,51,37,61,E1,9F,D3,84,BF,64,78,1F,4E,2C,06,B8,53,79,79,0D,31,A4,18,E6,54,C8,F4,BB,03,6C,5D,28,4A,78,B0,8C,89,C5,B7,F8,D1,EF,DD,5F,2E,81,8A,2E,82,08,51,3A,CC,B1,07,4F,E6,A5,41,A7,1A,C9,4F,6F,7A,45,97,B1,2F,FE,CB,31,6D,B9,75,0B,95,5E,32,76,51,89,0A,37,19,31,73,7C,46,70,28,C6,69,F8,3E,E8,B2,16,9F,8C,87,88,7C,7D,26,F2,E2,81,1F,3B,40,98,96,5B,E0,E5,87,E9,FD,8C,66,C9,99,FC,07,88,14,C5,D1,73,CF,65,40,A9,E7,EC,48,00,F4,35,A2,7A,5A,A7,4E,98,B9,FA,58,D5,43,C3,AF,D6,26,A9,97,4D,8D,AC,2D,42,B3,08,90,10,1A,D8,B7,F8,AB,20,79,B2,08,80,C4,6D,1F,13,6A,4D,D3,ED,CF,87,21,25,F6,47,E3,89,B9,8A,4F,DC,CB,9C,1D,E2,5A,C6,73,0B,FC,F5,7E,AF,AB,5D,26,B0,53,C5,C3,8A,1D,BF,F5,35,90,20,52,9B,EB,87,4F,86,87,66,B7,78,85,CC,E7,7A,26,2C,9E,A7,0F,E6,27,27,ED,54,59,39,06,54,E8,CE,57,BF,D6,E7,B5,EE,59,71,0B,8D,92,A0,84,E5,D3,3D,92,56,EA,60,6E,99,7A,79,05,6B,18,F0,3A,4A,8E,2F,33,0B,4B,2F,6C,63,90,60,48,B0,BE,3F,AB,A5,BC,85,52,9C,E3,37,38,31,4B,1A,EF,84,D1,0E,1C,EE,1D,DE,E9,1B,64,EE,96,8E,36,14,13,72,2D,BB,73,BB,10,AB,AC,40,3C,CB,DF,5E,30,9C,9E,7A,28,24,05,74,67,06,D2,A3,C5,A6,AA,97,E4,A9,A5,79,92,AF,F8,63,A1,F8,20,4F,B0,F1,81,07,73,6C,58,2C,2C,B1,EB,EB,9B,DB,AD,C7,D6,E5,6B,26,1F,E1,5D,70,AD,2C,A8,14,81,40,C6,C7,98,7B,D8,8D,81,40,DD,9F,11,35,3D,83,EC,E7,3B,DF,BF,BA,04,AA,6D,19,56,8B,4B,58,75,1F,A5,78,34,CF,2D,FF,61,9C,19,E3,FC,7E,39,76,FF,EC,46,06,B8,A2,D2,76,BA,C4,27,76,39,A7,EB,89,94,DA,47,8F,A6,A5,1F,93,0F,A1,0D,8C,09,6A,30,F9,55,CA,26,84,97,80,F5,E8,08,1B,20,12,28,57,58,2A,A1,0F,02,5B,CD,06,E7,FD,16,AA,CB,7D,E1,3D,55,19,19,C0,1F,25,88,18,61,C6,BD,84,19,1F,F3,FD,DC,CE,E3,DD,19,EF,16,57,19,2E,3D,DE,AA,E2,07,D2,0C,A1,B0,3E,03,4E,3F,99,95,7A,0C,25,8E,0B,32,77,1E,B4,80,60,5B,3C,35,BB,8A,26,98,D1,93,03,C5,C2,5A,D6,79,B2,0D,E6,C9,DF,9E,98,E5,43,5F,E0,9F,48,13,FE,16,52,2D,CF,5B,05,53,EC,93,F1,D8,3D,78,50,55,FC,82,13,D2,D0,B8,4D,EA,82,A6,C6,B6,09,D3,71,63,5D,11,F5,62,A9,6F,65,0D,D6,63,ED,8D,7A,0A,F7,8C,1A,EA,B4,C5,5A,19,F9,C7,8E,3B,51,0B,3C,87,63,6B,46,CA,82,1E,64,8A,A7,C1,A4,BE,4C,A2,C7,36,4F,02,49,20,BE,84,56,76,59,72,C6,44,44,F5,79,1E,6F,D9,4C,FF,26,EB,A9,19,C5,3F,CA,A5,0A,5F,5F,2D,F0,F6,77,E2,16,AC,C8,98,66,59,5F,86,43,AB,9E,48,BB,E3,C8,BE,AC,C6,3E,6C,01,7A,58,EF,6D,58,69,5E,07,84,07,7D,1F,1E,DE,65,67,5F,2D,27,5F,90,5B,93,9D,5D,7D,2D,35,21,A6,CD,FE,50,75,97,F2,16,24,F1,AF,74,14,67,27,FD,82,04,C0,BF,75,6D,08,9F,27,02,3A,48,E0,C8,AC,82,F6,DE,3B,2D,54,AE,50,F6,46,7E,BB,69,B7,1F,56,85,01,2D,9C,22,F1,DA,27,79,A7,9F,2B,60,05,E3,F9,B8,03,97,D3,FD,75,F4,34,99,CA,9B,1E,9D,87,63,47,2E,30,1B,DE,C0,01,C0,07,5B,B5,6B,15,AC,BC,40,4E,70,FE,27,B0,40,7D,EF,09,7E,09,D1,64,6C,0D,67,90,6E,26,F3,D2,83,BE,85,50,74,69,1A,82,77,EB,5E,76,D2,EE,B4,11,88,F1,FB,95,13,95,F3,3B,D1,3A,BA,2F,F4,EF,BE,81,40,9D,FF,89,AB,09,08,05,15,DE,72,75,1A,EF,6B,F7,AC,0B,0F,EC,25,7D,B5,A2,F0,5E,13,EA,2A,1F,F4,6D,F6,11,5C,BD,1D,C0,F8,4E,DC,50,A6,B9,50,8A,54,51,AB,EE,0A,3E,01,A9,96,6A,61,84,5C,63,57,96,4A,D5,C5,75,C8,70,2B,E3,81,CF,30,AE,4D,24,6E,0F,79,A3,FA,E6,64,F6,0F,DB,33,A2,F8,86,23,67,B9,72,D1,C2,2B,2A,3B,E5,B3,6A,06,A5,2A,7F,19,5A,F5,47,FE,08,C2,D7,49,6F,28,55,81,92,7F,87,90,1F,88,46,50,DF,59,41,6E,72,8B,78,21,49,AF,DB,74,71,55,0B,63,61,5C,32,B0,52,69,B7,61,71,2A,52,34,41,4B,88,9C,51,65,56,CD,DB,B4,F7,3C,84,AB,F7,CB,46,26,28,18,B7,7A,5C,DE,6F,28,1E,DE,15,D3,A8,6C,E3,42,2D,17,43,8A,A5,D9,15,58,38,74,74,0F,6F,EE,24,23,5C,99,1E,DC,4B,61,3E,95,A0,E5,BD,C8,40,E0,E7,DA,83,96,14,A5,0D,FA,D1,5D,8A,0F,B5,17,4D,79,12,39,B9,59,21,2D,1A,67,36,2A,45,34,77,71,86,A7,57,B8,73,53,BC,DA,0D,67,B5,BA,23,B1,E6,47,DB,28,C2,87,5B,FD,14,14,53,58,53,E8,B2,FD,E9,AB,34,57,3E,98,C5,32,1F,24,47,1F,FA,73,BF,16,9E,C6,3C,4E,4E,AC,7D,63,0B,EA,78,36,A4,F5,C5,42,BB,50,3E,3F,A3,BD,8B,C5,D9,A9,F3,22,A7,57,28,D5,24,8D,94,05,98,3D,1E,47,6C,9B,34,4B,1F,FB,EA,D3,0C,0C,5F,3F,2A,E5,7E,46,89,69,76,8D,C3,EE,FB,39,26,34,28,E7,8C,06,96,9A,C3,43,C7,34,62,1D,EF,B1,5D,A7,29,9B,7B,68,D2,A9,EF,A0,80,21,0D,BB,66,4D,58,86,BC,E0,65,7C,62,71,82,ED,31,D3,E7,5D,0D,3A,6D,97,9A,0C,AE,7C,AA,E6,D2,15,D3,2E,1B,23,E6,32,03,FF,3F,AE,8D,57,27,6F,73,7C,FE,10,79,16,F5,16,8A,B7,BF,43,29,CC,CC,28,9A,F2,2F,0C,3B,C1,ED,66,29,21,75,C2,51,A8,1C,06,3E,D2,CD,FB,ED,A2,81,D3,CD,13,6F,E5,EA,95,61,CC,81,9E,77,49,18,88,CC,2F,25,34,2F,C5,65,4E,6C,8A,C4,F9,15,3C,FD,6E,BA,3A,57,F8,6F,1F,B7,D9,5C,69,6D,AB,74,5C,0D,F0,34,DF,AA,58,E3,49,B4,70,45,03,63,73,79,2D,1A,3D,61,2D,1A,C7,88,50,A3,A9,A4,B4,EC,FE,41,71,5E,2C,22,85,95,BF,BF,6C,F6,8B,D1,86,4D,EE,34,70,66,2A,E3,07,FB,1E,89,24,47,4B,99,DE,D6,C1,28,B3,25,37,67,89,AF,B1,00,80,5B,F9,93,F1,FD,10,95,F2,39,7D,E2,C0,84,99,A0,D1,03,38,C7,18,AC,31,4E,5C,1B,95,2A,22,DC,F1,1E,A1,DE,65,91,60,55,E1,A3,0E,0B,3C,38,F2,24,0A,49,A8,AA,DF,BE,13,06,83,D5,55,36,76,56,ED,78,82,30,3D,08,BD,5C,C5,57,23,78,A1,C3,33,8D,AD,BF,56,C3,B0,15,D4,C1,36,2E,38,D0,B5,89,FC,EE,D9,13,4C,C8,2A,1B,B5,5A,EC,5F,79,9F,A6,33,D7,7D,8E,9C,10,0B,BD,65,7C,B6,45,8A,7E,A2,A8,E3,4B,30,54,61,01,BB,FB,AD,AD,9C,42,E5,9A,E1,C0,93,D1,15,3E,E2,1A,21,C8,2C,4F,AE,D3,A0,F4,03,52,9A,C3,B0,55,E7,CB,FE,49,A0,27,DC,CA,59,4B,72,AA,BF,EF,D6,1C,A2,0B,85,91,BE,BA,B8,8C,7B,8D,9B,12,67,E0,C0,35,87,87,C2,D0,DF,D0,48,68,25,D5,FE,E1,0E,92,64,91,C3,E4,A2,00,AB,20,F3,49,1F,5A,57,3E,9D,28,C3,55,A2,B6,0A,D6,F7,FE,22,02,AF,98,E1,3A,A4,5B,DA,40,CB,9C,6F,CD,C6,2D,A2,C7,D8,0D,44,94,11,0A,0C,EB,92,68,E5,4F,AD,33,36,28,11,FE,DD,7E,11,42,EE,F3,D6,17,CE,79,F6,A5,51,26,A7,66,22,3C,16,47,7C,A7,9A,5D,A8,AC,83,EC,2F,9C,59,E2,5C,3B,E3,24,A9,FC,04,C4,40,99,14,D5,48,90,1F,17,80,F9,26,3A,97,56,4D,96,16,0C,05,C0,79,75,E3,67,A8,72,A4,A9,6A,38,DC,B4,21,97,F4,70,B6,60,2B,20,76,B4,80,A0,1C,5A,EA,BB,B0,40,F1,C4,95,7E,F9,01,F5,F7,7E,69,9F,F8,0F,4F,08,7E,9E,E8,92,55,69,63,D8,6A,F4,1C,6B,2B,E7,BB,42,AB,85,03,5D,17,D4,C0,F6,75,CC,2F,87,34,B2,A6,23,E7,8B,CA,18,9F,38,F0,C0,3B,1B,D8,69,C0,5E,D8,AE,E2,76,70,3D,8C,5C,8E,84,EB,E5,95,A9,DD,7A,EA,21,B3,66,4C,A3,08,B9,2D,4A,FF,C9,C3,89,AB,31,74,E0,B1,06,B7,F3,7A,54,80,B7,04,15,50,6C,B7,9C,88,88,3B,06,0B,3E,B3,34,E8,F2,D1,93,F4,3D,83,C3,A0,6E,33,20,43,73,F3,D9,CE,23,3F,A7,E3,C1,DC,07,94,66,7B,91,4D,6A,B1,F0,7C,A6,EC,98,1D,01,55,05,0A,C7,C3,6D,BD,5D,2E,CE,BA,00,B1,82,1F,F0,13,81,CD,11,B2,3A,C4,CF,13,DF,DC,B0,44,C9,05,30,CB,94,82,2E,E1,62,E5,6B,A8,81,DF,67,E8,64,0A,F2,00,02,29,A2,D0,68,3F,76,63,C1,8E,7A,4F,BF,21,0E,FD,B5,02,68,5F,1D,3E,7B,6D,98,34,BC,DE,88,05,68,13,05,0A,24,B7,B0,B3,94,76,4F,03,11,31,E8,B6,F4,AB,E7,27,9C,29,6C,96,7F,CD,B0,60,EA,CF,BE,7B,8F,4D,0C,60,B5,18,DF,FF,74,FC,40,89,FC,C4,68,E3,98,6A,92,F3,11,09,B0,CD,3F,68,24,7F,7C,1E,D9,1D,51,25,69,8C,93,E2,26,81,98,3D,A5,52,94,45,B3,D1,6D,39,69,89,47,CC,FC,43,95,0F,94,56,5D,A2,49,A2,8A,6B,E0,E7,07,19,AA,FA,B3,B3,9D,DB,79,AB,F1,19,C4,45,6D,6A,DD,15,24,AA,55,1D,1C,60,30,CF,E7,E3,D9,69,DC,82,F8,41,0E,3A,64,9E,FA,ED,CF,93,CB,EE,42,B6,16,3E,F0,28,72,75,50,1A,77,FD,0C,17,C8,5B,26,3F,5B,34,61,4E,C2,53,1E,45,E0,EB,5F,EE,94,25,D4,AB,82,D7,CD,AF,17,78,6C,22,C2,C7,62,CA,07,D1,13,F1,00,64,07,18,69,01,E5,CD,DF,CC,03,C1,8A,73,FF,71,7E,EE,7C,73,0D,DE,48,26,16,D2,B1,9C,3E,F6,0D,F5,DB,D8,67,6C,2F,77,00,39,5D,86,C7,30,74,43,38,E7,B4,CF,2D,0A,F6,2F,32,D7,E6,E0,EB,E5,48,29,76,A8,DF,7B,B7,E7,92,23,0F,DA,1C,E2,3B,A5,EB,A7,81,42,B8,9A,FE,87,0C,E7,AD,57,C8,26,28,70,E9,92,20,E5,2E,76,32,55,FC,BA,E2,A3,89,F4,BC,B3,FA,2F,C7,4B,CF,1C,4B,C1,45,91,71,4E,B3,AD,09,38,B2,1B,3B,9B,A4,1A,A2,23,22,66,5E,8F,77,39,FA,D7,0E,86,0B,0F,F3,1E,4E,3A,A6,FC,3D,26,4A,E7,68,83,AC,C5,48,65,0B,CC,35,E6,6A,8A,82,65,5F,BA,19,76,44,23,3F,A2,21,A6,B9,CD,B8,C6,13,B5,39,D1,D4,43,A2,A8,5B,2B,CF,0A,5C,E7,91,65,8D,3A,D4,4E,4A,29,E4,D1,A2,21,FF,17,BB,2C,FE,2E,E6,63,E8,79,B9,D6,BF,09,3C,CA,26,56,61,E1,A4,D7,CA,35,95,01,05,58,DA,76,E1,1C,4D,FA,8F,AB,6C,E1,C4,4D,60,78,2E,CD,E7,6A,EB,E8,04,37,A7,D7,27,75,79,9F,07,E3,1B,51,CB,BF,8C,9A,BF,91,48,C1,F5,30,E3,FA,05,31,C4,06,D2,2A,EF,21,E2,48,D0,70,F3,29,BF,67,06,67,46,AA,89,B5,FA,83,E0,A6,19,BB,78,78,47,43,1B,90,94,05,05,8C,BE,60,EA,89,A6,8D,EE,68,A3,EC,C2,D2,9B,13,BA,32,4D,21,F5,0A,A1,8C,87,A0,E8,2E,6D,C9,5C,43,FE,90,B5,21,AC,7F,2E,FA,28,6D,5A,0B,CD,2A,A1,7B,EA,1A,34,B5,FE,88,84,4B,90,1A,E9,28,F8,02,39,BD,3D,ED,B7,27,21,35,3B,8B,D6,E8,28,1D,A4,F1,A5,5A,A8,78,3F,0A,E9,CB,94,D6,72,78,1C,C0,12,D1,96,30,D3,83,B7,0B,2F,E8,40,61,4E,4A,2F,0E,08,C7,AD,4C,B8,C6,60,CF,5E,D8,88,29,23,D6,91,D4,08,35,4D,14,F7,7A,A0,8B,8F,A8,18,65,C6,1D,67,A7,80,94,C5,F7,27,8C,C5,49,1E,AC,12,D1,E4,10,62,B2,3C,8E,A7,A6,9E,8A,E2,07,B5,94,EA,04,ED,5A,C9,9C,0B,76,21,8F,7C,7A,8B,73,E1,30,75,69,DC,23,D7,DC,5B,4C,9A,6D,67,17,7B,E7,99,11,23,B9,5F,66,E7,EE,BF,D1,70,AD,C5,1E,AE,A3,42,BD,6F,0A,08,8B,E7,9B,5B,FF,58,F8,5D,41,DB,2F,CD,85,76,39,38,D3,B3,80,AE,3C,89,B7,EE,1F,3D,35,3F,B7,66,2C,A4,5C,86,86,E8,EB,29,6F,FB,64,7C,39,7B,B8,2B,95,03,9E,B0,6C,03,1D,62,98,B5,21,28,BB,A1,1C,67,E2,B9,B0,AA,69,F3,22,D0,76,D7,35,FA,27,CC,02,C1,23,92,7F,AF,12,64,E0,AE,EF,02,0D,E9,8A,7C,90,41,2A,CE,FC,13,40,F8,7A,45,72,CB,0E,C6,54,42,89,39,A6,D9,68,2D,19,26,4B,7B,3D,D9,5E,D9,FC,B7,0B,A3,DA,68,E0,D8,42,21,D4,5C,EE,0E,C7,06,AD,36,A5,98,31,10,FC,FD,29,BF,43,D5,06,B7,8C,EE,52,04,4E,9F,E1,1E,94,CD,84,74,17,46,33,99,22,5C,A0,A7,31,0C,67,11,74,C5,3B,1C,1D,2D,DA,8E,C3,64,FC,43,B5,3A,9D,44,D2,56,05,A0,15,64,8C,C6,F5,10,AE,80,D0,6F,95,E4,2E,80,D9,27,E9,82,88,ED,ED,4F,6F,7E,38,DA,66,E9,94,95,17,54,B3,89,1A,AD,9D,6F,8B,60,F1,B9,BF,8B,B0,85,C4,6F,67,DF,01,59,AE,24,81,9E,E0,D6,DB,01,13,5F,C4,0F,6D,54,75,6C,BA,43,7E,58,94,26,EC,0C,C2,96,52,F1,2A,FC,C4,AC,B9,32,65,EB,EA,8E,A3,22,16,D3,59,DA,6C,C8,A2,84,E8,EE,40,B3,3C,27,07,20,7F,B7,38,92,69,92,E9,F3,E4,B9,C4,C3,75,A4,61,F0,19,D0,69,16,E1,BE,A8,DC,4F,C6,7C,7C,26,09,CD,23,3F,BC,D9,E9,1F,7E,96,AC,EF,A8,A8,AE,F7,C1,75,59,72,CC,36,A7,7B,58,45,E8,BF,E4,77,1F,9C,10,E4,E5,C0,82,B3,15,0A,F7,08,33,E5,95,54,8F,30,0B,2E,9D,FD,7F,81,B0,3E,1F,A0,1E,8E,75,43,2D,15,1D,2C,3E,6E,8E,3F,D7,7F,65,BD,9A,A8,B6,E9,50,2E,9D,1C,99,BC,98,47,C6,16,80,F6,65,CB,1F,B0,14,5F,0C,85,B5,E8,BF,08,62,D2,6D,B5,67,6A,5B,25,89,70,4F,5E,08,A1,C2,45,78,02,FB,C8,4E,1B,9C,2F,37,1C,BF,5E,96,4F,B4,D1,84,91,97,4C,7A,1E,2F,F4,1B,F1,80,35,5F,0F,AE,6C,B5,42,AB,29,0B,A9,54,54,FC,49,D9,A0,B8,6F,5B,E5,66,F9,C7,4C,5B,80,1F,68,D9,49,99,88,59,78,DA,9A,9E,96,0E,39,00,FA,57,E2,98,CC,3D,11,ED,E5,33,F5,2F,51,6E,53,2E,E5,F7,76,DD,29,DD,B6,BA,0C,88,6A,9C,BC,F1,EF,FC,DF,B3,19,6D,F2,15,E8,98,65,F8,6D,79,EA,18,11,71,3E,E6,F3,89,43,51,B0,F7,AC,86,D8,CF,14,3C,13,79,1E,E4,42,85,B9,E6,F7,8A,01,33,7F,7E,2E,27,39,F7,47,48,6C,08,B6,4C,E9,25,31,E4,C5,2E,F8,3A,5E,C1,79,A2,45,A9,BC,0B,6C,7B,45,02,1F,F8,D4,D8,A5,68,3B,38,32,A4,C8,84,40,FA,46,8A,10,95,78,47,8D,4B,99,B9,83,32,D0,69,4C,CF,05,BA,71,9F,6D,07,6C,C9,50,1D,D7,AE,44,F0,D5,94,A5,63,50,B8,5A,8D,DD,01,E6,60,6E,B6,9A,D3,D2,3F,DA,3B,DC,00,D2,2A,48,45,E2,AF,8C,64,29,07,4A,21,F5,B6,24,37,C6,94,33,01,AC,4D,2D,64,C2,54,3D,F7,5C,AD,4F,DD,E7,AF,4F,9E,FC,D0,F9,C7,E4,4B,CB,24,16,27,3B,CE,5F,A4,00,1B,32,4F,D6,3F,23,2A,DF,50,9B,2C,58,A5,50,EB,71,1D,2D,6D,6D,42,79,A9,3E,1E,F6,A3,2A,9E,E3,AD,37,6C,E2,60,12,0C,56,63,70,55,69,AF,EA,D6,30,F1,FB,83,5E,F8,9B,C8,1B,E4,06,0E,2B,E5,24,CB,91,70,D8,40,F0,95,78,C1,DE,D4,DE,D8,04,95,F6,9C,05,30,15,41,06,B3,7C,D5,E9,F3,FE,0C,52,08,5C,C0,58,19,B3,5E,24,96,02,3F,39,58,9C,F0,14,80,65,63,54,CE,46,55,6C,B7,AC,9C,0C,8E,29,F4,9F,29,67,4A,04,0C,8C,DF,D5,5F,D1,88,A8,E3,A1,69,97,5A,75,18,00,7A,73,1C,77,69,4F,70,BA,89,DD,1A,78,18,40,BB,11,FA,D8,EB,8B,EE,70,F7,D2,B3,B1,F9,4C,A4,A4,A4,0D,C6,10,BC,89,DD,EC,B9,6B,7C,ED,31,DB,E4,72,36,0E,95,75,9B,32,2D,03,51,40,F4,2F,93,77,AB,C0,69,9E,7A,D8,D9,BB,B5,2C,1C,FB,70,9F,72,D3,E8,A0,5C,FB,84,99,FC,47,54,3C,DE,52,A7,85,DA,01,A5,4C,40,D5,4C,12,F0,11,E6,98,CA,19,2A,14,B9,CB,29,0C,67,7B,3E,43,4C,5F,E7,1D,9C,05,F4,79,A0,F4,E4,18,E3,96,A2,90,F6,4D,78,06,74,70,7C,5D,46,F5,43,8C,5C,AF,C0,AF,AF,51,DE,86,5F,CA,82,7B,F8,2D,2E,12,57,43,D9,F2,FA,24,19,3C,21,D8,C6,CF,7C,EF,72,FB,4B,25,5D,38,D8,65,D2,12,54,EE,00,86,67,7C,DC,C4,5C,A1,4F,D0,BD,7D,BB,CB,5E,C8,53,8B,35,03,90,E2,68,FA,3C,76,07,70,14,AA,F4,91,15,DE,2B,75,B7,40,45,47,4F,B8,38,6B,FF,82,DA,62,89,34,93,D2,70,C3,CB,E8,66,22,28,0E,19,87,8F,5D,F8,5A,92,51,41,E5,6C,00,9C,F0,D2,64,6B,26,00,AF,62,CF,85,45,8E,6C,DA,0F,6C,1B,F8,95,89,FC,DE,62,CE,C2,81,F2,34,28,1E,67,BB,10,94,D0,23,CC,35,EB,9B,4F,B8,48,22,E7,FA,FD,CB,BD,B0,4F,24,C1,1E,AB,93,04,20,4A,EA,C8,C7,04,80,46,4E,A7,07,51,20,CE,FA,1F,2C,3C,0C,BD,CF,CC,AD,E9,B7,A5,2C,A6,DB,B8,45,03,1D,63,1D,28,8A,C7,56,EA,6D,59,1E,8E,29,6E,3D,60,AB,FE,DE,56,0F,03,21,91,58,46,ED,B7,C2,B6,E8,58,A3,4F,A0,C0,F6,E7,74,2F,E0,D4,FA,F9,A7,57,44,1A,95,29,4D,1B,53,5F,A0,E1,60,B1,E3,1D,8D,2D,92,0E,FB,C7,9B,C0,57,B3,25,A2,C4,CC,09,A1,D3,E4,AC,DF,BA,28,2C,AD,C6,EB,6A,BA,99,B8,88,D7,A0,13,B9,84,E9,56,9F,30,F3,7B,F7,EE,6E,EC,76,C5,3E,7C,05,53,BA,BA,E6,8C,7B,CA,52,54,23,D8,98,F8,4B,EC,DD,E6,E2,2F,F5,2D,ED,69,84,0F,ED,BF,C7,55,1C,14,B7,4C,5B,DF,32,CA,BD,D2,DC,F1,B0,9B,7B,14,F0,2A,8B,D1,BB,84,55,8C,A2,F7,9F,AD,17,5D,FA,4C,6F,CA,2F,00,A4,EF,10,37,9D,65,75,1A,DC,4E,D3,6B,D8,4A,E0,4C,17,00,E6,40,3C,85,E1,FA,8A,10,62,C5,28,D3,C1,46,75,3F,D7,F5,95,17,F0,97,20,F7,98,0D,3C,93,5A,AD,F7,AA,2E,C2,9B,E1,3B,4F,72,49,4B,A2,73,FC,35,9B,6C,A6,BC,D5,CF,7C,E6,B6,BC,61,DD,14,F9,C8,CA,A8,16,B6,4B,D6,C2,46,5B,1E,A3,5E,71,F7,90,98,8C,A1,15,30,F7,88,D6,21,23,66,0F,D8,59,CD,0D,BD,58,AC,DF,65,2D,2A,E0,E3,81,5A,00,8F,93,EC,C6,A1,7F,B9,E8,10,FB,29,C7,A1,EB,67,E3,65,16,4E,AC,22,09,9F,5A,DB,E5,0B,94,CB,27,34,BC,DE,14,6A,8B,3E,B0,13,BC,EA,52,D9,BA,D1,59,89,EE,B8,56,7E,E4,D2,38,10,0E,F4,0C,48,1D,CC,09,89,08,7F,28,B9,A1,F4,94,DB,71,46,A9,12,2E,F6,4A,ED,41,25,7C,CC,81,9D,D3,FC,88,22,8F,D2,A3,1A,5E,86,AF,FB,02,E8,2D,1C,EF,2C,9D,D4,A6,EB,DF,B3,4C,9A,39,BA,42,E4,55,09,90,88,EB,AB,F4,23,61,7F,EF,2B,61,74,2F,C2,1D,43,86,14,63,C6,DE,2C,E9,68,B3,88,E6,8B,C0,B2,A0,AA,76,C6,B5,83,D7,55,6C,9A,79,47,07,E6,0C,6B,45,17,18,77,FC,BC,D9,5D,68,7E,F3,FF,D3,94,2D,36,17,62,29,3E,EE,4B,05,93,FF,0E,6E,EC,19,96,65,24,EF,F5,2D,94,42,F5,FA,34,52,EC,CA,E4,DE,92,4B,DB,D8,1E,CE,81,56,F8,98,C7,0A,99,62,D3,BC,28,9A,68,9C,30,8D,86,30,6C,E2,77,97,B6,CF,3F,47,6A,90,44,60,6D,6D,99,99,83,D0,2A,BE,EC,35,C5,F2,9B,20,A7,AF,9C,E9,9B,EA,9D,9F,76,B6,75,3D,5B,F8,3D,21,15,26,37,C4,D3,A3,F0,56,9D,78,5E,EF,D0,60,81,D4,2E,C5,84,E8,B2,82,D8,3E,62,EF,7F,4D,67,8D,2F,57,D1,07,FC,B2,D2,5D,BC,92,56,4F,04,D6,4C,6A,DB,D1,67,25,25,5C,C0,0D,82,F0,33,9F,99,71,1A,FC,EB,DD,F3,83,85,B8,6B,62,E8,5C,8D,72,55,53,7C,99,48,62,65,4F,77,E7,2F,B6,51,41,98,E0,5D,F6,BD,82,86,8C,C6,61,5E,B3,AF,E1,A5,39,38,CA,DB,4A,62,D6,F9,3E,76,1B,8D,30,EC,F3,09,DC,B5,3D,CB,41,92,2F,94,CA,F2,64,38,19,A7,D0,DF,59,D3,26,48,A9,D9,CB,22,81,F4,36,7D,C3,79,3E,55,50,DC,30,A8,21,34,18,CB,3C,B0,47,84,66,21,46,CA,A1,83,8D,AC,10,8D,23,79,A1,71,47,F9,E9,B9,C3,05,52,28,18,76,C9,03,1A,37,59,9D,E2,44,5F,2E,0D,95,15,EA,6E,7A,CE,0B,72,7F,0A,0F,E2,84,78,41,08,19,C6,A7,4A,66,B4,F2,F2,AD,DA,55,C7,FF,EA,F8,C6,BB,9F,87,CA,0F,B3,AF,E7,72,0B,2E,F8,78,13,AA,AF,AA,02,C3,1F,55,54,92,7D,6E,35,D3,60,9C,2F,92,C3,EA,E0,E4,34,AB,C4,82,70,11,B7,03,30,02,A9,A6,2A,99,6C,0D,65,DD,9A,F1,F7,26,1E,9A,F6,ED,76,1D,55,28,9E,87,1F,87,F3,65,6F,22,9C,02,A6,52,AA,59,4A,2D,F2,B1,6D,07,B5,A8,AC,B8,01,FF,0E,57,DA,E3,0E,64,7D,33,32,D2,86,04,27,01,E9,75,98,20,44,90,6A,63,58,31,38,B7,69,DC,FD,40,81,C0,27,F7,4D,59,D8,AB,1C,79,BD,D7,1F,33,45,EA,0D,6E,A9,1A,2C,55,1D,E5,26,66,D5,B3,F0,C2,66,44,E8,09,2F,E4,AF,3F,52,AF,36,9F,CA,03,F0,00,62,F8,A4,5B,F6,2F,71,F7,25,2D,61,7B,0A,3B,4C,A0,5D,E2,6B,5D,47,E3,D6,78,33,89,64,9B,90,85,B6,16,60,4E,33,1D,31,2E,C2,79,85,E1,B7,42,36,3C,04,0A,02,84,AC,CA,C5,98,C1,4C,52,38,3E,6D,73,FB,42,34,B2,6D,3D,F1,1C,D9,E3,D0,05,1E,C4,B4,B1,2C,EF,D0,AA,29,0C,45,C4,AD,07,1D,79,05,45,C3,C6,BF,6A,19,4A,EC,22,6D,69,1D,0F,F4,C5,1A,47,85,0D,07,FE,E3,6C,E2,05,68,FD,E5,95,6A,C0,44,20,77,5F,F4,D7,BE,03,3A,1E,2A,38,5D,5C,D3,4B,AD,82,6C,EE,CA,71,6D,22,0B,09,47,B4,7B,86,B9,70,65,61,56,BA,5C,4B,07,CA,19,8A,A7,FB,C5,84,81,C6,8D,F4,B7,87,14,A6,3B,C7,49,5D,43,EF,AC,67,6B,D3,DB,FD,89,DD,29,2C,A1,DB,63,E2,0C,37,7D,70,66,F8,41,E1,A2,DA,7A,2B,1E,C3,56,F4,CB,48,C2,4A,A1,1A,C9,39,AB,C9,91,14,B8,A7,94,2D,7C,69,62,B3,FF,64,DC,CB,39,66,10,E5,7B,EF,50,70,26,1E,38,F4,AB,18,57,BD,F8,8A,6C,0C,A1,F7,5D,62,B8,6D,AD,36,FC,53,CB,8F,78,95,D1,B8,BB,50,05,14,BE,D9,87,B8,F5,0C,21,B8,77,46,A2,25,AE,98,BC,57,A5,1E,7C,96,3B,02,9D,AC,54,F0,5E,54,1F,94,95,45,FF,6C,CD,80,DC,44,F7,7B,EE,7B,25,A3,1D,B5,96,30,B7,06,35,6F,28,1D,D0,68,56,01,D5,00,6B,84,16,B1,BB,AE,74,5E,A3,09,61,62,61,38,71,5F,70,BC,FB,A8,7E,17,F9,88,C4,BE,F8,67,B5,04,9D,CF,E3,02,09,51,94,54,4B,22,A4,BA,7A,BF,7B,EF,F3,14,74,C0,04,1F,35,6D,11,5E,02,E9,00,77,FD,1B,08,F3,DB,A2,38,88,EB,B2,01,9F,E9,3E,99,DB,A6,01,7C,37,32,76,20,AA,3D,80,B9,95,52,28,44,E8,13,87,69,B1,70,A3,9D,40,B0,15,66,93,0A,8C,9F,2F,B7,B1,47,50,02,B8,B9,41,8E,A7,AD,B6,D4,DF,B8,FE,A5,17,AA,FC,0E,D7,23,FB,1A,C2,AD,48,6E,32,7E,9B,9B,0E,A4,BC,78,DC,D8,2E,71,06,F2,6A,33,5F,B7,A7,FA,E5,98,8E,86,8C,0F,18,06,FE,CA,BF,1F,61,7F,0A,6A,D4,22,D5,06,D0,67,60,C2,86,0B,71,1A,E2,B6,F8,09,8D,E2,4C,AD,B5,20,14,D4,3F,1C,40,01,45,FF,F5,CA,FD,4E,6B,60,66,86,24,80,ED,ED,FC,A4,64,A8,5C,D9,86,40,7E,91,6B,8F,9D,25,4F,0C,98,11,03,90,9F,B0,32,01,8B,9E,49,4C,44,18,E7,4B,3F,4B,49,97,5C,9F,23,F6,F8,81,8C,70,D6,B4,AE,40,19,1B,AE,9B,A3,D5,19,28,2B,B7,73,8C,40,DD,DF,5D,A4,80,D5,41,42,6D,60,82,2A,D9,DA,9C,A1,36,BA,79,BE,A3,D6,22,09,0F,56,A1,1C,F5,DB,0E,5E,07,FC,2F,4D,9B,B9,0C,CC,1B,44,AF,2F,D2,4A,76,47,A8,A4,56,28,2A,B8,E3,32,8D,F8,85,C7,89,76,11,40,1C,9A,2C,2E,0C,C1,69,7D,A7,3B,F8,EE,5F,98,9E,C9,22,EB,3C,E2,6D,EE,06,33,A7,C7,19,64,83,71,32,1B,CF,38,D7,A8,21,B8,27,54,C9,C0,C7,4F,CF,20,2E,13,A9,6B,0A,F3,15,0A,53,CB,EF,20,D1,BE,1E,42,8F,9B,60,17,85,6E,64,AD,40,BA,50,29,5C,AE,6C,89,CF,4E,08,96,77,48,27,08,66,95,05,FA,F7,C9,0C,BA,EE,4A,9A,FB,9B,BC,98,A9,D5,9F,9C,6C,20,D9,B7,EC,D5,B1,4D,44,2B,25,B8,FF,1B,10,C4,CE,44,DB,B8,0E,9E,9E,67,37,CC,FE,56,78,06,C3,0F,3A,97,12,BD,08,C6,94,64,0A,BD,38,A7,5A,B4,F8,21,6A,7A,CD,42,CD,F7,12,B5,67,ED,B0,BD,61,CD,71,C5,1F,05,9E,3D,13,7B,08,9C,FE,45,E2,1F,79,E2,50,6E,1C,C4,58,D4,5D,48,CD,2A,7F,94,F9,CA,CA,E0,64,EB,D0,B5,BF,A9,C1,12,66,DC,78,EC,54,16,B8,DD,41,56,D3,2D,3E,4B,90,4B,4F,28,55,91,5F,25,0C,8D,EE,7C,27,1A,6C,C4,3C,6F,DF,32,7A,36,BB,80,44,7A,D2,A7,6B,53,67,07,71,03,43,9A,76,2C,5F,9E,5E,A4,DE,2E,43,B8,E5,FE,AC,79,47,01,10,0C,9C,1C,D3,B4,A1,82,3E,DE,D8,72,3C,8B,67,37,F7,CF,76,65,7A,F0,21,A1,C5,F7,D2,9F,05,E7,14,70,85,A5,0D,6B,17,BB,93,E6,DA,84,37,3F,36,AC,BD,B1,A1,08,03,63,BA,0D,24,21,9F,F0,0E,DA,68,38,6E,59,90,13,FD,05,13,13,6A,D5,37,9B,BD,CF,94,CD,85,CF,77,59,74,B4,9C,50,3F,68,E3,EB,55,95,55,50,B4,91,F0,87,97,C9,F1,7F,C8,D7,3C,55,FB,F0,B2,37,E4,59,A5,84,BC,CD,63,7A,72,01,18,B0,13,03,4F,AC,75,84,62,62,21,A0,03,E9,2E,2F,5E,CE,87,07,A5,78,1D,0D,EC,DD,6A,35,54,73,B9,65,C6,21,2E,39,96,0A,95,49,97,9E,86,D7,89,52,31,D7,54,79,71,76,EA,B7,E4,17,2E,58,16,BE,57,0C,5F,F7,3B,3C,19,38,C6,C2,98,5A,D9,43,10,F6,B6,BB,75,11,46,6A,38,3C,6C,20,41,47,B0,AA,D5,CA,D9,BB,7B,87,C5,9F,0E,B7,99,0D,1C,28,09,F9,5D,8C,3D,92,F1,DA,0A,AA,C3,0E,2E,12,E7,84,30,A8,37,59,00,29,DE,AF,6C,F5,43,F7,48,91,61,21,3F,D9,6C,DF,E4,37,23,24,23,E5,EC,F9,D1,B1,C8,7C,5C,69,8A,95,27,D7,D2,5E,EF,49,EE,A7,9A,A3,18,32,3D,83,7E,02,B5,FE,98,E0,80,1E,89,EF,09,A3,01,51,3E,52,C3,35,AA,6F,FB,93,6E,22,09,46,61,33,2B,20,31,D0,FB,9F,D6,79,71,FD,A1,6C,5D,1B,8E,9D,65,E6,3C,7E,FC,12,FB,91,06,33,E1,27,80,24,5E,71,6F,47,20,E8,6A,64,3F,4F,42,16,5B,1A,E3,2E,88,A2,99,00,B2,BC,53,35,C5,90,E4,8F,F1,51,70,D7,19,F1,76,BE,9E,3C,78,D3,26,14,6D,04,D7,19,8D,1A,B4,53,C9,FC,B3,01,41,3C,54,8F,01,E5,F0,A4,28,1E,65,37,D3,5E,4C,A0,15,5F,A1,F4,D9,45,7C,31,72,4F,8A,8E,88,7C,1D,51,0E,A2,ED,0E,D7,0D,60,45,C1,B4,B2,99,5A,BA,60,A7,0D,86,2C,6B,07,EF,9E,73,63,94,71,D3,87,9E,E6,DE,59,56,7F,EF,DC,F1,5F,17,E7,D3,B8,46,7D,B3,32,30,FE,4D,0B,A6,BD,65,26,9F,48,2E,B9,43,ED,BD,27,9E,8B,AF,90,08,49,66,C5,DC,CE,EA,76,CA,F9,B6,3A,8A,00,C0,D6,19,AA,66,C3,91,D0,22,A7,87,BC,E2,B8,24,A8,B4,EF,F0,60,AD,1F,A0,FB,EF,48,DE,E5,57,F1,12,91,35,B9,4D,0F,6F,C4,65,C9,2E,5B,9B,AB,E3,F6,5E,29,FF,69,D0,25,6C,74,75,0D,C6,7D,17,42,C0,74,66,8E,FD,72,78,E4,7B,1B,57,9E,F3,C6,F0,67,0F,0E,20,9B,07,5E,AA,14,CC,BD,E5,56,42,18,BE,C9,E5,10,34,B4,B1,10,7F,F8,D1,2E,A5,7C,4D,77,25,12,FE,DE,23,FD,70,DB,13,D4,08,DB,DF,F5,82,E6,3E,C9,CD,8D,58,03,61,21,12,26,86,14,52,9A,F8,07,3C,76,92,3C,69,C0,34,7D,E4,68,DE,27,A8,A8,17,B9,04,F5,2C,F6,AA,57,6E,9B,E1,8F,16,A4,29,47,C2,32,65,D9,E5,B4,EC,E3,A7,6D,91,0D,2E,AF,FA,3C,42,26,40,CA,0E,F4,66,A4,8B,B1,E3,BB,F2,76,04,BC,AB,AF,77,9A,06,8D,75,3D,A8,08,5A,93,3E,37,E3,E3,04,BA,AF,9F,B2,70,0F,10,A3,61,69,EE,6A,72,EA,B5,61,CF,1D,1D,9E,D5,DD,41,4E,CB,37,55,E5,7E,7B,6E,0F,4A,5E,CE,8E,12,82,9F,3A,DC,51,18,E9,01,63,09,89,9B,99,B3,18,42,59,C5,2A,90,E4,DE,C2,9B,AE,A1,A8,E7,1C,99,B1,99,56,1D,8D,EE,62,CF,B8,37,67,CA,3C,A0,23,68,82,35,D3,C7,F6,95,91,DA,7A,30,61,75,5A,56,E8,33,F0,A3,AC,1A,24,E4,67,41,A4,63,E9,8A,B9,0A,A5,90,6C,DF,70,2F,75,A3,CB,29,DB,C4,DD,F1,A3,DE,29,9A,61,84,35,C5,B8,D2,56,8F,17,AF,83,78,AB,11,D1,70,27,F1,AA,80,C2,EE,EB,33,92,9A,FD,86,B0,DE,BD,63,55,78,30,E5,CA,A4,BA,09,43,92,98,71,FE,8E,53,5C,6B,72,B6,BF,33,C3,F8,12,46,19,B2,B3,3B,28,01,D7,38,EF,B7,F9,E6,50,15,A8,4D,6D,2A,2E,F3,5F,2C,59,39,03,BC,1B,05,F7,D8,A4,EB,1F,47,9B,24,79,DE,5A,8B,C6,98,48,1E,01,1B,76,40,94,04,B8,04,C7,8F,A5,FF,5D,81,3D,2D,0F,35,DD,FF,10,27,EA,2C,CA,71,A7,13,2B,D4,59,4D,85,6C,00,26,D1,1F,48,05,9D,AE,44,FB,24,07,AC,3A,BC,53,0F,9D,E2,81,8D,3F,6C,63,09,2E,6A,3B,56,C0,83,04,E9,26,B0,AE,DB,FF,B1,CC,E5,D1,4D,3C,4E,21,31,7F,97,D7,6D,0E,CB,AE,91,D9,AA,6A,92,B5,4E,8A,67,02,CC,86,42,43,8B,6F,D2,E3,21,60,DB,DE,C9,B6,19,8F,EB,F4,D6,50,9B,8D,7A,4B,48,9D,EF,AC,6C,E0,FE,F1,36,43,C3,96,0C,47,FA,EA,FA,4F,39,56,92,C1,E8,5B,D0,05,CD,8F,55,55,3E,9C,EE,9E,75,80,6B,4D,60,67,D9,94,FD,1A,D5,F6,E4,F4,D7,03,AF,5E,B4,8C,26,89,46,B4,90,DE,F7,2F,F6,84,AC,45,A7,1F,65,A3,FA,67,0A,F8,82,70,D4,39,7D,A8,90,EB,77,EC,A4,C3,8C,40,1D,62,E3,3C,8A,A1,2A,26,D1,DD,E2,52,AF,8F,DA,09,AA,D0,A1,D1,22,A5,A0,97,7D,D1,3D,E6,D4,D6,7F,D4,8F,8F,D8,60,DD,7A,37,61,27,6D,BC,8B,E5,B4,69,A7,7A,0F,BB,22,DA,F6,ED,C0,0B,ED,33,9E,36,7E,E9,3D,7F,EA,AD,03,23,6F,65,F0,01,F3,40,2E,D7,BD,F7,0A,01,5D,45,AB,5E,4E,F5,A4,4D,E9,ED,88,F1,54,31,C3,A5,27,B9,CA,34,8D,E5,98,36,B2,C9,5A,26,3B,51,A9,05,B1,9A,B6,A7,76,1F,4C,77,30,D0,69,EF,3E,EC,0D,4D,78,52,86,11,FD,43,8B,FB,59,FA,2F,5C,89,93,10,72,A2,8F,7A,72,ED,88,12,99,A7,FA,E4,2E,81,30,96,1D,FF,56,87,8E,AE,D9,6C,ED,EB,F8,CF,9A,E6,71,E8,C7,1B,31,24,E7,92,EB,04,BA,D0,BB,E8,E6,CE,50,66,65,B8,8D,62,BF,5B,4C,8A,A0,68,96,BA,80,F6,82,F4,B4,9F,78,AE,E6,54,85,B5,48,8A,5E,D4,BE,72,1E,8A,1B,0E,65,DE,4D,5B,B3,98,8D,F1,B2,6D,6C,2B,A7,A4,88,4A,79,6A,2C,58,8D,C5,E8,4C,17,97,9F,44,9D,6D,3A,68,28,47,E1,D2,2D,26,51,68,18,A4,63,B4,0E,3F,83,95,35,67,C2,89,B3,9B,CA,EF,6A,CB,56,AE,46,C6,CC,C3,B6,06,4C,61,96,D5,99,54,FF,44,8B,B0,A6,A1,AB,B7,BA,9C,74,17,7D,41,F2,98,F1,69,83,C9,40,4C,AA,D2,49,D3,68,E4,DC,E1,39,25,E9,7D,4D,AE,CE,0B,8C,3D,8D,C4,27,EE,10,F8,21,49,71,79,53,A1,2A,B4,32,6B,AE,F0,E1,22,C7,8D,7C,8D,38,46,58,19,DB,98,69,3D,77,A2,05,FE,A3,86,C6,E9,C4,98,63,E0,A3,CC,FD,6E,E9,09,ED,9A,E8,B2,29,E9,2E,E2,97,1E,05,48,DB,4E,5F,BC,E1,50,30,AB,BA,80,DA,27,90,D4,AB,33,62,C3,F9,F9,09,C2,00,D1,0B,66,F5,51,29,08,C9,F6,5A,84,4A,32,D2,3C,E4,F2,AC,7D,F1,2F,55,50,C1,FD,13,5C,0E,A3,87,41,0B,75,1A,74,EE,CC,88,02,58,CA,95,49,08,10,42,2D,61,6C,19,D8,F1,6D,6E,B1,0E,77,21,43,9C,84,A5,A4,14,69,99,6B,D9,E2,EE,33,25,6E,55,08,79,41,54,1A,CE,15,87,B7,3C,BF,29,D4,DC,C9,0B,E2,9F,7D,DB,6A,BD,43,37,26,6C,0B,72,AD,56,41,88,65,79,C8,85,19,4E,4C,D9,E7,75,55,B5,67,C1,87,2C,63,7B,F9,82,46,55,BF,27,15,02,20,B6,DB,D2,87,21,A3,25,6C,25,C0,23,48,20,A0,9A,03,B0,1C,81,F6,03,74,40,09,11,84,DB,2E,9E,3C,A3,72,B6,13,3A,AC,76,09,7F,A2,A9,F0,0D,CE,D6,26,89,7D,24,C2,F2,2C,A1,30,DD,88,55,A8,EA,5C,0A,6F,D3,2A,9B,76,9E,3E,B6,B3,4B,02,19,7E,45,9F,44,F5,2E,F9,79,0B,E2,85,A4,83,D5,8C,26,76,4F,16,AA,A1,46,E5,24,63,EE,77,97,38,FA,32,FF,04,FF,9F,86,4E,06,AC,EC,35,C8,24,43,A0,86,48,52,AF,3C,2A,B5,93,8A,ED,CE,5B,4F,0E,80,B8,04,E0,1C,24,50,70,7D,15,58,C9,F5,DD,67,27,60,92,B1,46,51,21,5E,C4,50,62,99,8C,BC,A6,CB,CC,31,07,1C,39,B9,CA,28,7A,A7,FA,2C,E7,E1,BB,C0,DF,69,E6,AD,38,D9,87,8B,25,41,C7,20,E0,30,E6,75,72,4F,1E,24,E2,BD,BA,A2,A7,DA,B0,A2,7F,2E,33,D2,8A,AB,01,B3,71,0A,1B,DA,B1,60,95,30,F9,93,A8,E0,6D,04,A9,71,34,3B,AD,AD,83,99,74,C0,1F,9B,35,55,9B,FA,E1,1A,96,FD,4F,0A,E3,63,CD,B8,2E,AA,32,0D,52,37,A8,CB,DC,36,6D,55,7A,1C,25,7C,07,8F,4C,F5,5D,81,CB,E9,92,5F,F6,44,A0,BA,1D,4B,C4,C4,2F,3E,9D,12,73,9E,5C,19,73,26,BE,6B,44,98,50,52,18,D9,5E,F5,76,CC,93,3D,01,F4,AA,9A,86,0D,EA,A8,C5,CF,25,B1,F1,2A,DD,0E,AE,BE,5A,E8,5C,F4,86,1F,E0,A4,DC,2F,12,EE,27,44,68,2D,BF,52,FE,C5,B7,A3,89,87,19,92,2B,DB,D7,88,29,3D,D3,E7,38,BE,93,94,90,25,41,17,29,74,10,BF,E7,4D,61,89,67,2F,10,17,51,A8,55,AC,1D,12,F0,80,60,6C,00,F9,C1,94,B9,9D,FE,09,C2,82,56,60,EB,2C,25,F1,34,4F,57,CE,0E,74,15,94,6D,20,D7,19,18,09,B8,72,20,76,3B,C9,59,2A,B9,69,55,F0,46,1C,DF,E9,95,E1,A9,80,0F,7C,0C,4C,F4,4D,25,72,0B,7A,F1,2E,51,D3,36,7D,83,63,DA,AB,7F,B6,CB,DF,D2,E1,6C,66,3F,FA,F4,BF,10,39,B8,98,DF,E5,E4,A1,02,BE,54,6B,B8,A8,61,FD,AA,56,00,8F,BC,6A,D3,96,FD,12,F5,8B,35,23,26,3D,BD,EC,1F,AE,95,85,6F,B1,19,E6,CF,5A,4B,21,A5,CA,D9,42,C2,E0,B7,1C,1A,E2,C4,92,10,1E,93,B4,97,DB,5D,57,32,7B,76,EE,D8,42,3E,A4,DA,4E,77,F6,64,8F,99,B0,61,2B,1E,75,61,CE,E9,4E,24,DB,7E,10,81,AF,B4,85,11,3E,A0,9A,B6,23,6A,0A,0F,98,3F,4A,1F,96,B6,D6,AE,00,F8,8A,D7,92,21,36,22,43,AE,6C,2A,96,10,1B,E4,2D,7F,6C,EF,19,89,63,DD,21,B1,1B,30,BA,31,67,F4,DD,F5,25,7D,41,2D,7F,DF,BC,85,73,6D,5C,59,1D,90,06,73,BE,AE,65,B3,86,D9,04,2C,67,58,0B,24,5F,9C,FF,E1,B1,CE,35,11,8D,F5,06,1A,D6,59,AA,1E,03,EE,C4,70,A5,3D,E1,11,95,E0,DE,74,25,42,B6,89,5C,BC,EF,1E,81,B3,48,C3,6D,46,08,FC,99,9F,BD,25,04,15,FB,EB,D1,67,CF,0E,C6,48,49,BB,DC,BD,3D,5E,6C,9C,06,38,F2,71,3A,14,83,6F,20,05,D1,60,0F,84,3B,DE,D0,50,DD,A4,21,48,8B,8F,80,CD,61,0A,2B,F6,16,3C,88,BA,D8,4F,89,A1,4A,74,CD,D1,F8,B1,F6,A9,BA,64,30,BF,D6,74,7E,68,00,05,8F,CA,77,29,73,BE,EB,06,9A,4A,EE,99,C5,20,7F,26,E3,F2,D2,D2,00,4E,0C,D8,97,AE,F0,DB,29,1A,E9,80,43,58,6F,E5,EF,D3,39,1F,A5,3A,F2,42,31,1C,8E,F9,C3,40,2A,A4,60,C9,21,5D,71,DB,2C,7D,00,5E,BF,54,F7,FF,F4,EE,3B,B2,0D,6E,CB,26,FF,D7,F9,76,2B,93,34,3C,A3,F7,9E,D3,B7,C1,CF,2F,5F,39,16,67,AF,EF,5A,9C,19,52,9A,58,60,AC,66,E9,96,16,6F,D7,31,CE,89,30,4E,75,66,63,85,34,BF,A4,A7,A9,77,AE,C3,62,49,5D,7D,E7,E5,7B,56,8F,11,14,C3,8F,40,93,0F,CC,EC,D3,85,0F,92,23,9D,84,F2,72,88,8A,D4,06,3A,B3,01,74,88,2A,8E,C7,8C,7C,0B,5F,EB,20,EA,8C,6C,B1,DC,AF,5D,F7,8C,75,4B,D2,F1,64,15,BE,D7,39,06,7B,15,DF,75,58,C8,B4,36,AF,37,F2,E3,8C,16,A2,D3,C2,FE,F2,C1,0C,CE,74,3D,45,92,D9,39,41,F8,5C,E2,51,16,E6,18,CF,45,63,3C,1F,6A,74,2C,E5,77,C3,BB,05,3C,A0,58,3B,50,AE,18,FD,D0,EF,B8,C7,32,D1,A2,C9,F7,C3,4F,8F,31,AA,F6,9D,DB,96,FA,0F,2C,91,C7,ED,88,1E,7D,5A,D7,44,67,F9,B7,40,0D,99,F3,7F,0A,8E,73,CD,D6,8B,C0,D6,B9,D0,8A,67,3B,F0,1F,C9,F9,D4,91,E1,B9,2F,12,10,9F,ED,94,17,BD,FA,99,04,67,38,27,D0,88,A8,36,1E,34,E9,D2,C2,16,F4,E5,40,04,A9,5D,12,B8,77,D3,12,87,61,67,2E,80,C9,4D,20,42,0E,5E,B1,0E,9E,BA,A4,2A,07,05,04,69,BE,AA,11,40,4E,97,1E,C1,8B,E5,DA,DF,41,70,FC,ED,C0,56,62,88,EC,DF,ED,E6,E3,C3,FF,72,00,C2,EE,CC,D8,F8,48,AB,DD,1B,09,C6,8A,E4,14,69,0C,56,B3,F2,1F,22,CD,C4,01,0C,3C,0A,C6,DF,39,26,7E,A4,03,00,1C,07,E9,C7,98,8F,A3,87,B2,A6,B3,92,84,FC,1F,FC,8A,7C,61,1B,F5,F7,32,A3,BC,22,BF,83,A2,4D,CA,18,21,B1,14,10,19,B4,C3,02,7E,16,00,9D,8D,DA,7B,20,DB,12,36,49,90,84,3D,FC,2C,90,06,7F,C6,8E,75,AE,35,3C,70,C7,85,AA,8E,60,D0,FB,09,13,46,AC,94,DE,1D,0E,E3,F5,AB,4D,7A,4A,29,E8,6E,75,6D,C5,AF,32,A0,70,1E,8C,00,91,1D,A3,80,B5,49,F2,A5,09,13,FC,BE,A1,99,4C,75,CD,83,CA,6D,76,01,65,45,B6,3D,6D,28,2F,48,C6,4A,89,62,56,58,62,68,7D,FA,A7,B4,B8,17,05,27,4E,36,E2,EB,D6,5C,FF,45,B6,F0,A4,B7,7E,C0,EE,34,D4,47,5C,10,0E,28,1D,36,20,33,4D,7B,C1,EF,C0,8A,AA,DA,9F,06,75,20,7F,92,04,31,76,06,C7,93,60,57,37,5F,49,47,9C,BD,8B,58,BF,CB,0D,5E,FD,56,F8,25,E8,18,17,7A,DA,A8,8A,6F,AD,81,4D,99,42,0F,E8,FC,41,41,84,36,C5,FF,9C,48,18,DC,30,45,C2,D1,98,87,83,EE,5D,D1,3B,34,F0,67,01,F1,42,43,26,7C,89,59,07,73,49,2A,51,93,0E,8B,E6,F3,C3,05,86,34,0C,46,58,E6,2E,D1,BD,D6,27,4D,E7,DA,98,AE,B4,F5,66,45,74,6F,32,69,8E,E9,82,AD,44,E5,07,8A,1E,1E,AD,3B,D7,3E,1E,FB,1F,09,87,DE,0B,D1,92,AA,60,49,C2,E5,45,E3,22,4E,25,F5,C6,25,F5,76,A4,61,3F,30,B5,F2,42,93,00,2D,E1,7C,62,21,14,4F,32,EE,E8,87,16,47,F1,A3,FD,E5,90,B3,38,BB,2C,D6,89,4D,DB,B5,3E,E6,35,47,C8,02,E4,07,CC,29,FF,5B,27,6D,8D,D1,E8,B1,3A,BB,01,A8,08,F9,2C,B3,B2,EB,D9,94,A6,13,80,D8,7A,34,84,0E,BA,A5,DF,05,DC,BC,58,03,00,41,72,12,03,99,58,D6,70,57,17,8B,49,6A,70,BB,0C,1C,1F,4D,98,AD,09,E3,A9,98,CB,D8,45,D9,C2,C1,0F,D4,D1,65,2B,E0,A0,44,15,4E,E2,EA,5C,A8,FC,87,C6,33,46,64,42,81,C7,13,0C,91,E9,AF,FC,4D,62,D0,2B,96,1B,28,A6,47,37,A5,D4,D0,5F,E2,D2,F3,B9,C2,86,BD,9B,12,17,0E,97,54,44,2F,1B,74,CE,B3,E5,7E,6C,20,09,56,F5,0C,14,21,1A,B4,68,7B,EB,4B,A9,5F,A5,C1,85,02,81,28,60,9B,ED,FF,9A,A2,08,49,7D,42,43,66,0B,A0,8B,B5,87,BE,2C,E3,09,C9,C0,2D,1C,BE,B4,05,89,83,42,D7,FA,6E,8E,BA,E6,D0,59,52,5E,4E,65,C8,86,44,94,35,9F,F7,F4,A5,0F,1A,6A,18,8E,2F,F2,0B,6A,18,91,9F,2C,E2,57,86,35,65,C7,A7,7B,B7,4C,AD,ED,E1,4B,E8,8A,61,E3,6E,76,1D,63,44,63,B1,E5,8F,61,B0,24,42,DA,F0,41,3B,82,A7,3A,3C,8D,2C,F7,96,D3,60,28,5E,AB,E3,8C,40,7C,6C,05,B2,5F,20,61,FE,82,68,0A,71,AC,29,C4,71,5E,A3,FB,4F,49,46,7D,70,6A,9C,80,3C,AC,6E,55,46,6D,02,06,A5,16,07,C2,F3,13,E6,4F,11,BA,25,75,92,83,45,A9,A2,D1,0D,78,49,3E,A6,11,9F,6F,D5,F3,6C,98,D0,09,22,BF,3C,60,56,35,38,0D,8B,16,B9,00,71,A3,B2,A3,81,89,49,2E,6C,AC,E9,5D,C6,D5,1E,5E,9C,02,68,BE,56,D1,86,5E,F6,97,CA,65,01,BB,0E,43,E6,0F,85,0B,0B,21,A2,9F,C3,36,6D,9C,22,88,F7,C8,2A,11,7C,06,E1,7D,3D,4E,A3,0A,B7,82,40,32,08,2A,01,31,2C,94,E6,19,8B,BE,77,DC,87,6C,B1,EC,20,2B,11,ED,B2,04,C1,AE,1E,DD,B7,0A,31,08,48,61,0C,2C,24,5B,2B,0E,F0,93,BC,70,6B,15,A4,23,BF,58,42,DE,97,CA,AE,6B,8F,1D,FC,62,9B,96,A7,91,AD,0D,52,A0,D9,05,8A,48,A4,22,7F,F7,3A,04,7C,BA,CA,B4,E1,AC,A9,82,A2,26,D2,75,A3,33,A2,F2,33,07,08,73,B2,F3,41,CF,DE,B5,57,B9,5D,AA,FF,C0,EC,8B,4A,02,2C,23,2D,72,C7,A3,7A,18,2E,C8,FF,C1,D6,5D,FB,55,66,31,BA,20,56,D2,A9,59,DA,6C,E3,29,6E,C9,A5,F3,CB,8E,82,AA,5C,34,98,9D,4F,3C,B3,58,FA,F9,BD,AF,53,8B,74,0C,B8,16,8D,5C,62,5C,36,98,CD,E1,50,D4,2A,C7,24,FD,D2,E5,E6,DC,B3,80,FC,40,F1,B6,E3,4F,C1,D8,11,D7,79,B7,EC,02,6D,2C,DB,4B,95,60,3D,26,23,11,DD,9D,AB,8C,88,A7,F1,4C,6D,64,6E,E9,8B,D6,DE,AB,70,F8,0A,7E,08,78,23,1E,51,C6,71,5C,55,AD,01,2B,00,39,1E,B4,B7,E8,0C,FD,0E,D6,C6,AF,47,D3,75,5D,9C,8C,87,FD,74,EB,52,FA,AD,93,30,FC,BD,B7,C0,C6,D0,B1,A3,D3,9F,7B,D1,06,E8,98,6E,49,74,D7,95,8E,09,A3,32,54,2C,82,4E,84,4B,8F,15,30,D3,55,00,2F,6F,DD,A1,2A,F8,20,86,CD,78,26,0B,7C,E6,E9,71,7B,C6,25,84,AF,5D,53,14,0C,3D,18,8B,68,20,5C,37,06,B4,C8,E3,E8,97,57,38,18,D2,F0,D6,22,73,32,AE,9D,24,74,8A,C6,94,74,4C,0C,85,B7,1C,BF,28,75,86,12,82,B5,A9,CA,4F,EB,13,93,E7,58,17,93,2A,D5,9C,63,F1,7E,CA,81,C1,49,DD,AF,C4,A9,82,C9,98,09,3A,1E,9E,E8,15,07,7B,18,13,B1,E0,68,02,61,4B,1E,BF,44,CF,9C,61,59,4E,29,1E,9F,C5,EB,A1,F9,6C,4C,A8,8B,2D,A9,19,E8,F4,9C,89,D0,E2,96,B0,A5,35,F7,F9,A7,45,B6,F8,63,A0,77,9A,36,5A,43,8C,BB,08,A7,C8,B8,03,DA,E1,CE,34,03,49,AA,2F,9C,62,81,9C,9C,00,D3,BB,FA,78,CA,8E,11,F8,94,BF,94,D5,89,93,B0,C2,F5,4C,28,5F,F2,BC,31,82,78,D1,BA,AF,46,AF,17,6B,A7,E9,A5,B7,24,65,93,9D,4D,69,1F,CD,42,1F,48,5A,2A,83,14,28,D3,81,CD,DF,3D,48,1B,F1,0E,CF,42,F8,50,44,F4,14,C8,D6,1B,EE,CB,D0,23,DF,5A,60,FC,35,77,C7,8A,B5,A3,A7,75,51,56,CC,FD,C6,87,20,32,1E,31,8A,BF,79,F4,5B,8F,73,B1,5C,02,77,C8,4C,27,61,E2,5D,D4,23,B9,AB,AB,E3,E5,8D,4A,DC,A4,9B,F9,9C,EA,4C,B5,2F,DF,89,9A,A5,AA,87,96,E2,9A,7D,06,A3,25,B1,5B,29,AB,7A,DB,55,C7,4E,35,DC,09,3A,1A,43,B8,82,04,27,7F,5D,6D,04,BF,15,88,A8,4A,B7,89,93,01,17,7B,70,C9,F8,32,E3,36,E6,0D,C6,C7,A3,8D,D6,06,56,95,47,5B,76,CD,C6,4E,EE,F1,E4,FF,F2,33,99,A7,B6,3D,46,6C,D7,3D,B0,3E,A3,CF,2D,8B,F6,E9,70,33,01,D5,1A,86,B0,BC,B5,CB,FF,1A,12,AA,00,21,36,05,67,26,52,DC,6E,79,E5,8E,9A,85,AA,BE,49,F5,70,A5,F7,F4,12,F9,44,AA,FE,65,1B,01,95,AE,44,43,C2,7D,31,BA,4D,21,58,03,41,25,B7,F4,C0,0B,69,C8,0D,1F,0C,53,C7,2B,7E,E7,93,26,22,59,DE,82,9D,58,88,54,9D,B5,C9,16,58,FC,E5,7E,87,E9,42,F2,F0,77,6F,F2,48,D3,85,C0,D4,B1,D4,B6,48,42,54,86,C9,02,79,EB,19,DC,A9,CF,E6,FC,49,70,77,30,25,D6,11,A6,F2,CA,71,BD,F2,5A,E3,16,AB,63,A5,C0,81,5A,21,1F,FE,7B,99,7C,17,EC,5D,BA,89,A3,34,0F,13,45,8B,60,D7,94,55,EC,FE,07,CC,6C,F0,9F,D9,88,8E,5B,20,41,1D,31,0C,07,85,EB,D3,75,53,CF,38,1C,65,E2,2F,41,28,81,97,40,47,F4,1D,1B,7D,F2,EE,ED,55,DA,E6,C5,C7,6D,28,A7,A0,D6,57,14,9B,DD,D6,E6,24,D0,F3,B7,9E,0C,3B,8D,3E,6B,72,A4,E2,EE,D5,8D,89,36,60,F2,CC,0D,05,28,F3,27,74,71,32,21,55,F4,F5,04,F4,ED,7A,16,01,8F,D4,24,81,27,98,5C,59,02,4A,53,B2,9D,2A,AD,2E,C7,B8,8B,8B,F9,63,C1,4F,E7,A7,31,04,8F,05,8F,D5,7B,FA,A8,B9,F4,D5,81,0F,D7,42,1B,9A,8F,85,04,5C,0E,A7,EF,3D,4C,65,CA,B4,4F,42,0D,88,4D,47,AD,8B,18,C2,4A,BB,6B,FD,22,CC,76,96,86,CD,4A,BB,C2,E1,79,0B,94,AA,73,2F,B0,79,06,EC,A0,95,9B,E7,57,E9,23,9A,51,8D,E4,49,8C,A1,5C,6D,30,0D,28,A2,7C,60,5B,15,52,E5,6B,60,DB,7A,43,C9,95,32,80,02,47,A9,08,02,EA,0E,FA,07,AE,A2,D3,2B,E4,ED,5D,8D,D2,66,66,D3,D6,AC,E6,A9,F2,18,4D,3D,D4,65,E0,75,B5,CD,11,A4,82,CD,6A,D1,90,1D,6F,11,24,A2,C8,7C,E8,4C,BF,AE,A9,57,CB,71,AD,98,1E,5E,3B,75,BA,F9,5D,31,3E,F7,AA,46,01,2E,0C,89,3D,00,3B,93,44,F6,6E,BA,5D,C8,E7,FB,3F,47,82,88,C5,E1,8A,B3,CA,4B,BB,12,A9,A3,57,A3,B2,95,64,C6,34,F4,C6,29,26,E3,07,F7,B7,42,68,67,C9,C1,5B,60,5F,D5,DB,13,B4,C6,5C,E2,30,E3,A9,AA,D7,98,AF,76,E3,87,6E,44,D6,51,EB,ED,95,B9,C5,25,8C,19,6B,4E,64,B7,81,39,30,79,0E,AB,B2,92,1D,11,EF,C1,66,FD,51,45,96,FD,06,18,49,88,1B,73,BD,4C,6D,FE,F1,42,97,ED,64,F6,BF,A4,58,D7,03,05,E5,03,91,20,64,1E,37,07,6B,84,20,DE,12,5F,6E,F3,88,C4,6F,CE,2B,67,87,0B,43,6F,E2,CF,16,C4,EB,AA,2B,E8,58,CA,40,D1,3D,95,9F,3D,5D,E6,F7,68,23,A2,98,6B,87,5C,91,6F,0C,8D,62,5A,77,CA,56,6B,E7,D9,8B,2C,E8,B4,7D,29,3C,00,AC,EE,03,46,AE,73,EA,83,EB,A8,30,2F,AC,00,E5,9C,40,B9,E7,A0,00,74,2A,0F,4D,B3,0B,69,4D,C5,A0,3F,3C,5F,11,25,60,74,B3,85,4E,3B,8E,4B,36,3E,B1,09,8D,E6,B3,D5,B3,AC,F4,47,B0,2F,85,6C,98,14,C2,1A,A9,20,55,0C,E4,CB,EE,1F,70,EE,75,EE,B8,34,56,A3,59,1D,80,C0,93,3E,5E,11,E2,50,54,F1,E0,8C,94,06,14,0A,76,2D,3B,C1,50,50,EE,97,75,BF,94,F5,7E,9B,7E,3C,0B,48,40,EC,16,EA,53,EF,02,4A,96,7C,94,80,1E,9F,D6,1E,7A,F7,B8,14,1F,F4,CB,2F,C0,1E,57,2E,3B,5E,C7,29,45,B8,2E,6B,62,C4,E3,43,36,F9,0F,FC,3F,E1,FF,DA,D4,51,F9,C0,AA,17,00,38,3E,95,A9,12,7A,E3,9B,7C,5C,33,B1,B4,6F,30,C8,63,45,3B,4E,23,F2,E5,CD,BC,39,AE,B8,BC,AE,42,82,BB,1A,40,4B,AA,9A,B6,6F,D9,78,DE,E0,2F,0F,3D,CC,08,F1,7D,27,00,30,A3,B0,14,A2,EF,DF,88,57,87,1A,86,13,21,5D,F6,85,29,FB,A5,88,D0,11,34,44,F5,F3,6E,B7,EE,33,BB,3F,59,89,DC,4A,DC,40,92,91,BB,0C,14,0F,E3,95,6D,13,18,D0,4A,5D,C1,EB,5A,BC,6F,D0,0C,D7,F4,A9,7D,16,CB,F9,7D,C1,35,BA,86,05,44,3D,5E,CF,CF,2C,EB,CD,41,66,70,C5,09,FD,BA,59,EF,7E,8F,EB,A6,C8,2A,08,A3,D8,E8,7D,12,B6,F6,91,E4,C7,DF,E1,CC,6F,6B,BE,BE,D3,D9,0A,97,01,D5,75,39,62,CA,3A,20,1A,6B,68,51,87,DA,D3,93,D0,A7,DB,74,FB,A6,B1,F5,29,FA,43,4C,7A,7D,FE,26,A6,BE,1D,B3,3D,9E,B8,B7,1D,C3,6F,80,CC,E8,56,DE,C4,03,6E,F1,69,25,23,76,2C,E6,24,90,43,A4,1D,F9,33,71,74,C4,0F,62,4D,5D,DC,61,6E,9A,C7,3D,7B,57,1C,4A,EE,C7,24,09,09,93,65,C5,0B,82,89,DB,90,6A,5D,69,4A,06,C5,73,5C,83,EC,E4,5A,71,D4,C7,9C,60,19,2A,90,F0,82,4A,5B,BB,20,EF,BB,64,A4,BB,2D,38,1E,A5,5C,1A,99,0C,78,BC,FD,0E,FC,F4,A1,DA,3B,BE,71,1F,79,9B,50,0D,58,7E,2D,C6,DB,21,58,E3,4D,FC,49,E2,24,6C,48,97,43,E0,FC,17,A0,11,3C,B4,17,F1,70,7D,25,D3,62,55,67,68,89,F7,C6,74,29,4C,7F,50,42,84,1E,E7,DF,EF,8E,05,25,25,78,04,59,69,D0,9A,E9,39,7C,54,2F,5F,93,57,2C,0F,1D,BA,66,F5,91,BE,EE,C0,5D,3A,70,60,08,07,DE,0D,E9,8D,EF,D6,93,D7,E0,6B,7F,AB,FB,44,01,37,F7,47,84,1E,6D,D8,13,62,DC,23,B6,92,81,D9,F6,62,FC,6A,89,9D,42,8D,AD,AD,44,02,31,18,C4,0B,42,68,10,0C,6F,2A,BF,A8,FF,80,CC,18,E5,D2,21,9B,2B,39,80,00,C8,EF,14,8B,89,36,6D,11,95,32,0E,22,F1,67,20,D3,61,F0,24,1A,3B,F1,02,2C,48,03,3B,4D,0A,45,84,AF,13,A4,CA,C4,8E,41,6C,DD,7E,59,73,41,A7,8F,09,74,41,29,57,98,AF,B6,8E,4E,37,25,74,37,24,C0,72,05,B3,C7,5B,6B,94,CF,38,B7,E7,AC,BE,91,03,6A,70,77,B5,C1,BB,14,EE,2E,0F,1A,A6,71,43,64,5C,8F,C8,00,54,09,79,4C,E0,1F,83,45,98,64,D6,35,47,11,DA,6A,91,EC,5E,B6,48,87,02,EA,AC,53,3E,E2,B2,84,50,B8,ED,D0,B5,D1,1C,C7,24,7F,84,7E,45,7F,42,71,86,6A,A2,9D,48,D1,49,4F,FD,5D,84,48,4F,2F,67,5E,23,1F,CA,2E,65,D7,14,18,F0,10,09,37,20,66,7D,A9,72,04,4F,02,8A,5A,D1,31,E5,D1,17,A7,C0,ED,18,13,89,75,26,11,1E,AA,7C,17,F3,38,E7,D4,13,C7,0B,A1,19,49,80,D5,E5,BE,EF,4B,E2,7E,D6,CF,7A,1A,4C,9C,3B,70,51,8F,E1,DB,BB,FF,33,C1,E2,EA,1D,35,18,27,AD,C1,1D,8F,84,76,0B,03,FD,57,C8,B0,0D,C7,AB,19,F0,D1,9D,8D,9D,11,FF,E6,55,98,23,99,43,C1,53,6F,A3,7F,EA,29,F1,44,87,B3,B4,6C,EC,73,BB,2F,D0,7C,A8,BA,73,99,8B,A1,56,08,E2,FE,20,B1,91,A9,FE,07,97,9A,51,FF,D1,9D,BD,8B,A4,7B,99,5E,E2,4A,9C,73,83,2E,2E,8A,77,E2,BA,8A,CC,39,BA,27,FC,70,7E,19,14,44,C7,F7,80,A0,F1,AD,2D,54,3A,15,DF,53,F2,C2,27,57,14,9C,D7,5D,14,BA,92,9C,2B,23,E1,C5,23,F3,5F,4D,93,C2,E5,B6,FB,6E,AE,2F,7F,28,6A,05,3D,F1,32,35,E1,44,B9,79,1B,42,76,29,F5,20,87,68,D3,E3,6A,7B,EF,16,68,AB,02,64,D3,93,86,D8,F6,EC,E9,98,72,FA,45,D4,6F,05,8A,03,5F,2D,98,C6,30,A4,0D,B3,3A,2B,4E,07,19,85,36,67,3D,C0,C7,A0,D6,C0,06,B2,67,94,39,15,DA,66,2D,B3,28,DD,BE,D7,0C,1E,F4,D0,9A,5B,B8,4B,2A,C2,88,A5,EC,59,0A,89,47,B1,98,05,3C,16,D8,9D,20,27,00,99,47,C0,BB,C8,81,4B,AC,46,AE,F5,4E,BE,ED,2E,B0,95,4B,03,56,B1,E1,37,84,65,49,30,56,07,16,0E,C7,37,2A,17,24,59,C8,AA,6B,07,E2,CB,7C,50,8D,88,D3,03,D5,03,6B,D8,FC,05,9C,AE,65,55,FD,60,13,28,F6,EC,B5,39,33,91,5D,C2,F7,1D,36,61,65,25,85,F4,68,AB,A8,A9,2C,A6,73,C9,DE,28,17,F2,AC,AD,F9,E4,56,0D,AC,CF,1C,EB,00,95,CF,AD,EF,4F,CF,DA,F0,68,0C,34,5C,07,65,FC,F4,E9,E9,B0,B9,A5,EB,E2,F6,98,8F,91,0F,04,9E,19,E3,07,55,40,7F,A7,F0,05,87,B0,6D,44,A1,93,B7,E0,A7,46,15,DE,6E,8B,0E,06,C6,79,D5,4E,F2,E1,C8,77,9B,C1,72,46,B9,8C,70,6F,EA,03,17,35,40,C3,AA,B2,EB,58,41,6B,4B,70,5A,83,A0,C8,F2,90,37,9D,3C,72,13,07,1B,96,24,9F,6D,86,3E,48,FE,3D,CF,DC,CB,A5,C7,C5,60,A3,27,22,6B,23,0D,26,C1,60,97,93,50,71,26,F4,17,D7,CE,10,DA,31,A7,86,BC,E9,8C,F5,DB,D0,89,91,A1,A8,9F,9B,1D,4D,EE,E1,62,6A,33,52,DC,48,FE,E6,34,C1,00,65,94,E6,73,30,19,EF,5A,7B,D0,EE,7A,25,6D,C0,4C,61,07,B6,CF,F3,78,70,79,F3,5F,3A,45,59,A2,CB,7A,C7,6E,13,C1,4F,84,5A,7E,3A,8D,DC,3C,08,BD,D7,96,FD,39,5D,99,54,D1,95,C8,7B,AA,BA,CF,84,C0,C3,2A,04,F4,8D,1D,5A,7B,49,30,E6,08,FA,DA,BB,1B,F9,D5,E4,3A,E2,4E,10,D2,25,3A,DE,17,B2,C5,6A,5C,91,B0,08,3D,0E,8B,6E,BE,E1,BB,CE,B6,83,50,7F,DD,5B,D2,CD,AE,86,9D,44,7A,38,2C,91,C2,11,9D,2B,08,EB,6E,88,6B,F4,87,49,16,09,B9,64,97,85,64,84,21,1A,57,8E,84,E0,F3,3A,A6,D8,D2,DE,B9,EC,E3,CC,05,07,77,C5,6B,84,73,93,CA,4B,4C,72,5D,5F,AC,D6,DE,F2,94,C4,B3,AC,DB,B2,BB,54,82,52,D7,74,09,F2,5A,08,11,36,97,C6,2D,3D,94,23,6B,34,E0,1E,05,26,EA,CE,F6,74,A8,5E,40,3F,22,C1,7B,1A,5B,6B,10,ED,38,0E,8D,4B,C2,F6,0D,2D,A9,E9,BB,8A,0C,A5,C7,0D,AD,3B,99,AC,D6,72,48,C2,4E,4C,C6,2F,C1,DF,44,BD,9C,C3,8D,0E,FF,DD,1E,8E,96,72,40,B5,72,A9,A7,8E,44,96,61,18,02,18,DE,95,3B,5D,E5,B1,69,7B,F9,2A,E9,29,19,8D,5F,C1,72,FB,A8,A0,97,DB,1D,BE,76,A1,B7,93,9F,D9,46,56,EC,43,46,BA,12,C1,84,2B,C1,8A,18,E9,9E,AA,17,7C,F3,40,23,33,14,21,71,1E,D8,72,37,41,2D,09,A0,79,4B,71,27,74,1B,BA,0B,46,5A,82,9B,2D,CA,E0,C2,1D,4B,E8,EF,05,4F,D2,A6,BB,4B,DF,2D,3C,CB,1A,6C,05,90,C0,A8,55,13,FF,39,E8,69,1D,54,86,50,EF,B7,CA,14,56,8E,4C,F1,92,65,0E,06,A2,94,D2,D6,16,1E,84,26,9C,C9,CC,83,80,75,8B,B7,FA,B3,D2,47,D5,68,85,77,AD,98,A5,17,93,E2,FA,6C,64,AC,8B,8D,6E,FF,07,C1,99,09,F3,C5,58,53,1A,4A,64,01,A4,AC,08,FA,B2,4F,14,05,AB,E4,33,D3,8E,85,09,5D,57,E8,D7,CA,1C,F0,D9,E6,AA,4F,D7,FE,8A,30,EF,DB,56,12,7E,19,5F,88,54,E6,8D,F2,C7,32,8D,5B,86,87,80,C0,58,D5,D2,16,00,CC,EA,62,DC,15,82,D0,19,80,54,42,10,A3,02,A6,B1,05,CE,8D,9B,C3,6C,26,BF,75,22,E1,3E,F5,94,31,EF,98,99,8C,A2,54,F7,E7,D5,51,27,1C,AA,DB,13,22,32,AA,DC,C7,2D,E6,A8,E7,0D,6C,23,77,8E,70,BF,76,9B,12,41,77,B1,01,F5,26,61,B4,6C,41,48,19,E0,19,73,55,57,6A,67,BE,CC,48,32,D0,80,F3,D6,31,E0,28,F6,53,FE,85,0A,1A,CC,E7,DF,24,B3,74,EC,70,DC,D8,3B,C7,F0,E9,12,97,92,19,02,A3,1A,C0,D5,FD,F1,A7,46,B7,B5,E0,0D,13,3E,67,F2,EC,B4,DA,6D,DA,76,14,EA,63,D4,13,11,2F,7C,B8,63,89,0C,C2,E2,6D,1E,42,D1,F2,75,AC,66,3B,30,D9,93,F5,E2,78,A6,60,1B,7A,98,85,C9,05,39,0F,74,4E,41,5A,99,F2,46,15,C2,03,11,81,1B,E4,98,E5,26,D3,2F,E8,E6,C2,9C,0B,9F,D3,89,2E,D4,95,2B,D2,E5,52,9F,57,68,0F,0E,1D,FA,EE,5F,50,CE,24,85,B7,A3,9B,81,9A,10,BE,42,3D,08,D6,8B,A0,61,B6,4B,49,5C,6C,3B,28,78,20,1F,D4,EF,AC,74,60,E4,5B,48,1A,A1,EA,0F,6B,E4,DA,6A,27,07,73,4E,84,6F,9B,63,0D,4E,4B,47,52,75,3B,8D,D6,DB,26,B1,58,77,3A,1B,70,5B,B6,90,5F,25,4B,C3,9A,C1,B1,98,05,AA,E0,A7,BD,B3,7A,7A,70,A8,55,7F,24,9A,E2,58,E5,BA,06,A7,EF,E8,BB,CB,FA,A2,A2,8E,2B,7D,23,43,D3,DF,17,E9,32,1C,C8,A7,A6,F0,39,EE,FE,97,83,2B,26,77,8D,91,F2,2B,42,2B,31,82,FB,24,71,3F,7C,7F,36,40,57,10,A4,06,E1,94,46,48,B9,25,0C,45,81,E6,23,98,B9,FA,05,BD,BA,D1,BB,65,E6,34,02,FC,A0,81,EB,05,9B,A3,2B,68,B7,75,5C,21,CC,03,80,F4,D1,3A,0F,BA,97,E8,16,D0,FC,FD,D1,75,94,4C,B9,FE,5F,33,51,CC,CD,A4,1B,6D,87,94,FE,16,60,32,46,5F,8F,16,32,90,FF,B3,08,5F,FC,A0,BD,CA,0C,FF,31,3D,BF,72,A9,99,64,CD,B2,05,85,9F,D8,6F,88,2C,48,08,0A,9D,43,78,37,A1,65,C1,25,DC,78,E0,B1,5B,07,8A,17,08,86,3C,BF,0A,AA,A5,6A,AD,3B,3F,F6,4F,CF,72,72,83,D4,0A,FA,3C,E1,3E,A8,17,69,C7,4C,4C,50,73,A9,B3,C6,68,17,CB,19,95,72,93,25,90,EF,48,2C,48,7E,14,EF,9B,81,3B,97,77,09,B8,80,67,33,84,FB,B1,39,F4,7D,42,66,55,6A,D3,97,D0,AF,5C,EF,99,41,C1,DB,3F,15,5D,15,80,FF,69,35,B7,A4,3A,0C,1E,ED,7F,BB,70,0B,44,88,39,84,BA,37,87,B5,5F,6D,9F,65,BE,70,FF,AB,37,E0,E2,D2,46,C7,A2,CF,20,65,FC,CE,D4,C1,3C,63,0A,CA,18,9C,DC,48,A4,4A,7C,13,67,BC,4F,43,D1,D8,0C,FA,A1,27,59,EF,D1,67,54,7A,1E,71,99,6F,E5,3C,15,D6,3E,48,BC,6B,31,A6,BB,25,6F,67,49,97,63,31,FD,67,A0,CE,22,3C,89,C1,60,C6,7C,A7,85,64,44,66,73,5F,33,B5,D4,04,B6,B4,AD,81,97,A3,26,DC,CC,70,2B,22,80,BE,B3,9B,61,AE,4A,4B,29,48,28,C6,15,B6,63,FF,A1,50,4E,01,0C,68,1E,DB,E0,BE,C6,B2,D2,2D,0A,19,A5,D5,DD,41,14,5B,B8,A7,36,E0,39,7A,77,70,3F,56,BC,97,7A,9F,7F,09,57,48,13,8F,3A,CD,A6,98,C2,AD,E5,05,C5,05,1C,85,D8,95,83,6E,5B,F9,57,AF,65,C2,00,E4,B9,7C,B9,A7,6E,6D,D7,04,18,52,3F,F9,07,3D,4B,54,A1,4C,3A,DF,47,CE,1A,1C,AD,B6,7C,4C,87,C9,98,77,DC,C8,B1,1F,E7,7E,65,04,4E,34,04,02,48,E6,40,A8,CF,18,0C,C1,99,7B,F7,44,33,68,16,66,88,11,58,EC,5C,41,9E,0C,98,54,B0,73,EB,9C,07,3B,BB,8B,4E,AA,91,01,39,67,A8,53,DA,08,12,30,61,95,5C,DE,89,FD,64,07,22,00,08,DB,90,75,D8,9D,9D,A1,31,07,64,21,60,CB,EF,6F,A7,A7,E7,E3,FB,57,97,B7,EC,30,7B,F9,27,D4,CC,09,B5,C1,F8,3A,60,85,D7,B3,90,DA,F2,4D,EF,B3,BE,BF,9A,71,FD,02,07,98,8B,04,0B,30,BE,D3,B6,2C,F8,32,91,91,E7,2F,1A,6B,E0,35,30,AF,1C,6B,89,42,3E,63,75,98,71,1F,6C,B8,C1,58,0D,54,B4,C8,AA,C1,2D,8E,87,E5,2C,EC,24,A0,93,88,10,BE,3E,F1,E5,06,A1,FE,C7,84,5C,31,90,8E,6B,95,28,1B,1C,E2,64,D1,21,0B,04,82,B3,E2,A2,0D,5E,E5,DB,78,F8,6A,0D,7D,96,70,93,F4,15,A5,50,AA,DB,61,B2,4C,60,0C,9E,CD,2D,4A,14,74,6F,75,1F,3A,A5,D8,4F,9B,06,7F,E6,39,9B,B2,95,70,3F,75,ED,EB,20,BD,BD,57,40,60,07,97,9F,6A,69,70,74,2E,52,3F,84,68,09,7D,B4,9C,41,4A,EC,3A,27,65,F0,81,66,C9,6E,7A,71,EB,97,06,62,E8,DA,63,AF,55,84,38,F6,CE,C5,A9,5C,92,2D,76,13,C2,C0,DF,1E,98,A1,6A,B3,B9,21,A6,54,98,88,63,00,F6,F1,16,F8,8E,F0,77,E7,B7,B3,65,ED,2A,CA,26,01,A1,28,85,8B,45,9C,93,FA,0E,F0,ED,55,01,8D,0F,74,3D,CB,F6,E1,A8,E9,78,EE,3B,9E,BD,CA,05,E9,85,3C,DE,A0,74,73,0E,2C,57,61,01,9A,4E,E0,10,AE,10,3A,B4,9B,3D,C2,A3,15,2B,B6,63,21,4D,7E,18,1D,2D,81,FF,32,29,BC,F5,73,2C,71,78,24,6F,04,35,DB,48,C6,7E,F9,0D,B6,33,10,C3,E9,15,55,30,1A,A2,0C,89,84,5D,E0,AD,24,6A,A1,6E,00,98,BF,B5,FF,AE,EE,94,A5,12,EC,DE,BC,2E,2C,65,E8,1B,22,00,80,8F,10,04,82,4E,A3,F6,69,53,85,64,79,7A,39,B7,15,16,C7,9C,2F,55,C5,84,9F,9B,E6,56,3E,C7,D1,13,24,EC,54,AC,83,66,FF,C8,54,DB,36,A9,87,E1,D1,22,FB,FB,E5,B7,A0,A3,0D,F8,66,0B,01,CF,2D,9E,E9,0A,A3,DE,64,CB,F3,6B,69,5C,E4,77,2F,45,7C,32,69,F3,E3,BC,5F,0E,00,16,BB,0B,2F,CE,A1,6A,A2,16,97,1F,7A,F8,22,61,F3,29,F6,4E,D7,31,96,9E,99,32,CF,1E,A5,7F,6B,09,2E,52,B1,FF,C3,5A,0E,65,2F,C8,DC,5E,97,E6,DC,E6,E7,57,43,A4,F1,DF,9B,75,54,33,22,8E,12,F6,B8,BE,26,74,6F,53,BC,4D,23,85,68,1B,80,3A,8F,12,0E,85,DD,71,5A,D6,1E,33,55,C6,4B,F3,BD,F1,79,C9,A2,92,84,A6,2B,89,EF,2C,40,69,18,C3,2E,12,A9,46,88,54,E0,35,7C,F9,97,E4,FC,24,26,19,35,BD,78,3C,A8,FF,2F,92,55,24,8E,DB,3D,E4,5C,94,79,E5,7E,06,5C,3C,44,94,CC,DA,EF,43,F8,17,33,EE,40,B1,02,1E,86,DE,5E,02,7D,DB,49,EA,67,D9,0F,34,2A,EF,CB,8F,BE,2E,82,D7,34,A4,7B,6F,EE,C4,31,6C,A8,BA,B5,90,8F,40,59,97,EB,0F,BA,1C,27,96,E1,4C,31,CC,68,D5,65,20,0B,10,EB,3B,6C,E6,9F,F2,7E,07,A3,B3,D4,F6,85,14,90,86,17,6F,49,DF,A7,EC,25,AA,21,3E,6C,64,5B,47,C4,B8,19,69,E7,FB,8D,A6,EA,5F,86,52,22,29,2D,97,4C,A4,E2,EE,F8,FD,B3,77,0D,BC,E8,DD,C0,FB,3E,FE,0A,6E,6D,32,BD,65,80,25,F6,76,E0,F0,3D,04,28,56,67,93,AA,5C,4C,51,83,66,6D,DB,5E,BC,DB,CA,3C,70,D8,8F,C3,6E,4D,B3,9A,B4,31,54,72,A5,F0,B1,92,AA,6C,61,41,58,E4,D7,AA,AB,5D,9C,54,04,E5,C6,42,F0,A1,94,21,72,14,F5,AD,57,84,22,39,A9,23,8D,91,BB,C0,D5,6F,7D,F9,EA,F9,39,C7,A6,A6,A1,64,25,9C,E3,5E,8C,49,5D,81,83,10,A0,E0,69,EF,39,11,65,16,A4,EC,B1,51,55,45,6F,64,4B,70,5E,46,15,16,4E,CD,E8,E7,73,2E,8B,D0,7E,F6,C3,CC,0F,80,9A,A3,D8,B7,3B,98,CA,FA,39,1C,D8,72,3F,5E,9D,BE,C6,1A,B1,04,20,EC,62,F5,82,BA,B0,65,A8,7A,60,30,B7,75,3D,65,EA,F8,90,1A,4E,21,F2,B9,14,D6,96,9C,D0,E8,C8,32,ED,4C,4F,B2,C4,C1,C9,65,39,A7,A0,D0,2A,F5,4E,71,37,54,EF,13,A2,73,BB,DE,DC,C0,7B,E8,E6,D6,95,B1,22,B8,8A,0B,D0,90,15,39,A6,CF,CB,C7,73,19,38,CF,AD,9A,5E,11,E1,6C,24,FC,CE,83,35,3A,43,AC,28,BC,D3,69,95,B0,03,69,BF,9C,6C,9D,90,9C,27,5F,F8,C1,A1,B9,64,88,14,20,ED,B7,28,BF,BB,1A,80,AF,52,26,5E,A8,05,7E,01,90,25,89,70,2F,C0,EA,78,84,78,E1,CF,BB,46,76,36,E6,36,9F,C1,A9,16,64,52,F2,5D,47,30,F2,75,C0,5B,0E,0F,DA,06,4D,0F,C1,F3,A7,9A,CE,27,29,17,C2,DB,A8,7A,A6,DD,05,48,3D,14,AF,FF,56,AE,DE,4B,78,36,16,F2,EF,57,4C,52,10,61,9A,79,AA,36,8B,61,DE,B8,49,D7,B4,9F,F0,A0,DD,41,ED,8D,AB,9D,CA,C4,91,65,66,74,F3,33,CE,5B,0B,32,B1,9D,63,92,D3,FA,45,BE,F2,BB,66,54,B3,87,8F,97,06,05,3B,DF,A3,4B,22,FE,76,A5,56,E3,98,B0,CE,FC,F4,BA,1F,E6,9D,84,E1,65,B8,31,FD,E5,C2,92,30,99,E5,3C,9F,EE,BF,FA,75,B3,1A,64,F3,60,A3,51,6F,D3,E6,FE,F4,81,C9,1F,CA,3D,0F,02,2B,E8,70,F1,15,54,8C,82,AC,8A,DA,F8,46,73,19,0E,44,AA,68,91,A8,C0,F5,3D,BA,21,CD,BD,CA,9A,CD,F3,40,81,AA,36,E1,7B,65,1D,02,78,D4,6C,AC,64,FB,86,25,DE,28,B7,A2,8F,7C,2B,C8,B5,B2,43,EE,27,65,BB,B2,44,EF,80,8F,E7,F6,20,D5,62,44,05,10,6E,52,F9,10,B2,5C,11,AA,34,BE,CD,8B,CF,69,EC,40,FF,4E,47,6D,A6,C1,92,D6,87,79,B1,6C,6B,23,8A,64,C7,4A,20,6A,C7,B9,2E,90,77,1E,59,27,FF,DC,CA,BC,32,C6,69,BA,75,1B,85,BA,5E,D2,A7,74,0C,8E,3B,5E,D1,E1,A4,90,55,92,B6,06,D7,3A,23,50,E3,2E,1B,7E,8F,41,DE,6F,06,3B,0E,8B,9F,51,8D,2C,62,C3,A4,F5,36,5E,7A,17,D3,4E,91,12,61,C7,04,3A,93,4E,E4,11,EE,C8,B8,D9,A6,DA,9B,AF,C1,00,A1,CF,1E,33,B4,23,F2,56,5C,90,D8,39,DD,C4,7C,21,EC,4C,68,2A,C4,C3,76,93,88,8A,AE,6D,CA,2A,55,B3,94,C7,9C,39,DB,C4,E8,96,57,9B,13,CA,0A,FF,9A,80,60,2E,BA,7D,26,93,8E,7A,B4,17,29,C8,86,36,C2,A9,65,FD,BE,99,B2,C6,55,EE,9F,EA,15,DD,34,45,38,71,3A,FA,01,14,E5,87,F5,D1,E5,02,E2,36,23,69,40,DA,97,40,09,5E,7C,D5,2C,1C,B3,FB,AE,8C,49,7D,98,0D,B9,EA,55,F7,6D,A9,94,77,83,7B,DE,DB,EF,0B,11,50,17,90,47,2B,31,3A,42,CC,62,D1,81,F0,08,DB,D5,78,26,EE,B4,C8,23,06,78,93,A7,DA,20,3D,32,01,2C,89,88,36,6D,1F,85,B5,E4,37,D4,A6,0B,D7,C4,28,AD,FC,36,07,A0,D2,58,52,34,3F,07,F4,FB,F7,DC,03,D9,32,8C,7A,E5,34,AC,DB,B3,98,32,32,1C,2D,C5,44,12,AD,BB,C8,A9,56,0D,45,9B,C9,EA,3E,D3,F1,AD,A6,36,47,03,6B,15,0C,00,6A,9A,A1,FF,5B,94,E2,BD,CE,B2,B0,63,C7,C8,97,52,A8,67,3E,8D,C4,3A,29,0F,B4,54,7A,96,51,48,E7,E4,67,B8,70,BA,82,F3,CA,8D,52,69,60,AB,E6,A0,97,35,95,87,27,5D,7D,C0,EB,12,FB,FD,C2,0F,60,82,42,95,BB,61,A3,ED,23,DA,15,41,16,E1,A3,12,65,2E,50,D9,50,F6,9A,AF,55,E7,29,AF,C9,6F,C7,BF,1F,77,3B,05,70,B6,70,DD,64,BD,E7,D4,29,4C,9E,BC,F7,57,1F,2E,0E,47,A6,8D,4F,28,69,75,A2,81,F5,B8,54,58,E9,3D,10,31,D6,EC,09,98,5D,0C,E8,FE,79,3D,73,14,3A,7E,42,10,94,7E,F7,76,C5,6D,96,76,F4,24,09,10,57,31,3D,ED,D1,94,B8,0E,3B,7F,F0,67,C9,C5,7D,50,DB,BF,96,EC,65,D4,36,AF,98,38,1A,30,EF,DC,6F,E9,92,73,3A,76,13,32,47,34,D2,26,6B,E4,1B,80,81,53,1C,DA,C0,86,2A,C8,63,7B,71,56,94,0A,24,AB,72,36,31,B6,A3,64,8B,EE,EE,63,C8,73,8B,0B,26,8B,85,64,EC,23,43,88,B2,33,19,67,B1,FC,BA,12,69,92,B6,F3,51,F9,14,3A,05,DE,EC,C3,AB,7B,1B,5A,A7,28,5C,AB,2D,90,25,1F,81,BE,63,96,5C,67,B5,60,C2,B2,EB,3A,EF,AB,34,E5,21,CC,D7,4A,C8,40,0E,AA,3E,B4,03,2E,B3,FE,D9,FE,EE,21,65,66,23,37,20,D0,F7,D3,8A,96,C8,96,16,3F,97,52,EE,90,2E,5F,5A,E4,B1,CD,D6,48,20,15,32,B7,8E,46,64,C8,5A,1D,50,38,4F,EA,4A,FD,B8,0C,65,8E,5A,CE,9B,EB,AE,89,64,16,43,E8,C3,EA,6F,C9,64,EA,82,7E,7A,7F,0A,E5,55,59,27,97,19,87,24,81,29,F7,4C,02,A1,7A,60,94,A9,55,C5,29,5F,BB,C5,2C,45,D5,F5,AD,BB,F2,16,FD,7F,E2,33,12,0C,A3,A3,C5,2E,F8,D7,51,F6,8F,0E,06,AD,FE,04,43,09,1D,17,4C,0E,AF,69,04,53,DC,55,A4,90,B6,34,F8,65,96,59,5F,C4,01,84,94,62,16,80,36,82,F4,0D,49,73,A9,2C,A5,79,11,2F,F5,AA,C8,34,90,27,9C,DD,F7,38,F2,62,25,7B,1B,83,79,1F,C3,F3,89,E5,D1,42,82,E7,A4,5F,2C,1A,21,EC,E2,31,8A,FD,2B,0C,6C,6C,BC,CB,5F,C1,C8,88,8D,59,53,A4,0A,28,03,DA,87,40,2B,F7,82,E5,58,F4,90,8F,39,86,F3,69,10,56,A0,C3,5A,32,FA,42,0A,41,6A,05,62,77,A4,A3,7C,C0,EE,4A,93,CD,E6,A1,81,56,13,CF,79,EE,C8,A0,85,06,33,8D,10,B6,B0,68,71,54,C1,A5,BA,4A,F7,90,33,F8,E1,32,FA,36,82,A3,D9,A0,8F,99,E4,5F,BF,C5,75,E7,87,4A,55,97,86,BD,9A,D4,1E,D6,23,16,5A,12,2D,E1,FF,BF,87,59,25,9F,4E,64,4D,22,F1,40,00,65,23,C2,D1,58,C6,A5,17,4E,C4,93,F2,C0,5D,FD,EC,56,0C,EC,9C,79,4A,0F,24,79,35,E9,56,FC,DD,7A,7C,6A,54,F4,91,89,A7,0A,8C,87,FB,2C,9F,15,8D,20,F3,1D,1D,4F,DD,12,19,5D,13,73,BD,AE,E8,74,CB,78,EA,C8,53,D7,7C,ED,31,54,7E,16,EA,53,8B,C0,2D,C4,64,77,9D,78,D5,76,33,B3,8B,7F,C0,16,F0,0A,F3,95,1B,3E,A6,FA,7A,E2,14,97,BF,28,64,35,1F,38,11,B7,96,57,06,AB,F0,55,61,DC,AB,E4,7E,BD,10,79,34,32,DE,53,9E,66,EA,33,A7,97,86,FE,DC,73,AB,C6,50,83,59,D0,CD,24,57,87,6C,AD,D2,14,BB,72,3B,CC,07,5E,EC,90,F1,92,7E,76,AB,42,3D,EC,1F,F5,F2,80,78,0F,BF,B9,C2,23,66,DC,0A,4E,54,A5,30,2B,66,09,5E,FF,42,E0,C8,44,CB,E4,00,29,91,BA,DD,CC,7D,35,DD,68,DD,50,17,83,0C,6C,7F,61,DE,C3,C0,B6,69,26,99,76,83,C4,77,E9,43,38,FF,23,B5,E1,08,52,6E,BA,E9,43,C5,BB,4B,DC,98,85,7E,68,E4,2D,ED,82,5C,CF,D6,5B,0A,11,74,BE,11,22,7C,BD,65,71,4A,74,19,E0,9E,2E,69,FF,CA,1E,A1,45,5A,65,EF,EA,3C,B8,1C,71,AC,B0,21,46,5E,7B,D9,F5,94,33,24,45,35,49,6D,7E,D6,37,54,82,6B,EA,D4,BC,1B,3B,BA,C3,85,14,F1,B9,41,9E,3A,4D,42,B3,D2,2F,40,DA,4E,1E,37,0C,A9,81,77,36,51,31,70,94,40,E9,F1,28,75,62,CC,68,62,1E,85,60,8B,B4,BB,E8,7A,95,59,AE,00,8D,88,AF,B3,B3,C2,F5,77,A9,2B,87,97,25,B6,F4,9E,7B,56,3F,90,9B,77,F5,C6,16,18,C4,B8,75,86,7B,33,3E,1A,F8,9F,F5,49,0D,A9,AF,5D,D1,A2,03,98,1D,22,9B,46,9B,0F,BE,7E,BD,DF,A9,5F,53,35,64,9F,B3,C0,1E,EB,06,0D,DB,98,1E,67,38,1F,27,DC,BB,A2,F4,B5,CB,76,A6,AA,B6,03,0B,7E,E2,C5,C3,95,63,8C,3D,DC,10,83,2A,AE,E7,29,B1,C7,77,C9,84,78,64,17,3A,82,93,05,FF,E1,CD,57,1F,E2,9F,FD,0E,88,2B,B0,7A,90,2E,26,CB,40,70,AB,3A,95,D8,4F,AD,2B,6D,8D,BF,BA,80,3F,33,F9,09,65,50,28,B0,63,99,DA,01,15,0A,67,62,CD,44,6E,4F,C2,7B,77,39,1D,CA,95,D4,37,8E,E6,0B,2B,EA,5D,2B,A5,31,4B,3B,8C,54,E9,EC,E6,51,B4,F1,8F,F8,50,ED,27,0F,47,B4,23,8C,F8,69,3E,02,32,AE,1E,F1,82,BB,F5,31,38,B1,03,98,AB,98,23,75,84,99,45,0B,76,1C,4E,D5,81,52,35,1E,C0,2D,68,BC,94,BB,98,43,48,2F,3B,03,62,0F,FC,35,39,B1,47,CE,E5,B4,0B,68,43,25,49,59,10,62,75,45,8B,FB,BD,6B,7B,70,FD,2D,A7,3B,CF,0E,63,54,E0,AE,9B,B5,EF,86,3A,F0,6D,FA,5C,02,98,5D,60,0D,77,DC,44,69,66,91,BC,8D,F6,B9,47,27,48,78,83,E3,A6,26,69,F5,3C,32,B2,38,01,CD,4D,20,5E,E5,F3,7A,48,A7,49,81,C6,F1,11,8F,69,A5,EE,FD,5F,50,70,24,57,63,66,45,90,2D,C2,45,FC,D0,F6,FD,3C,F3,F0,99,2C,D9,30,2A,59,55,EB,7E,80,11,B8,7C,53,C1,14,73,BA,CF,1D,DD,0E,6A,1C,DE,DC,9C,AD,FB,F4,F0,2B,1E,CE,0C,D7,3E,6E,2D,93,88,07,80,15,AF,C5,CF,6A,78,E2,8F,9C,FA,1D,44,A5,6E,69,DF,CC,2C,8A,56,40,87,26,DD,27,E7,27,53,DB,51,41,4E,C6,D7,E6,D1,D1,36,C3,36,AA,35,AE,94,8D,A4,55,C7,9E,D7,58,3A,BC,36,80,E9,12,7F,8D,FD,50,87,0A,CD,D7,AD,56,31,FD,8E,67,41,D6,A4,1C,32,38,66,3B,AC,51,20,2F,D8,3E,13,5B,7D,80,EB,2F,E4,8C,06,F1,C8,EF,3D,F7,4C,D4,E3,11,4E,FD,B7,6C,50,FE,F0,7D,82,DA,61,12,66,26,DA,42,F0,5A,0C,B4,55,F9,6B,67,4F,CB,21,D0,B0,89,9D,79,DE,6F,2B,70,22,41,D2,F7,FE,24,30,76,4D,9B,5B,ED,F7,79,3D,74,49,1E,82,D2,AB,62,B2,74,B3,B6,2C,9A,97,B7,A0,A9,74,2E,8C,A2,F6,99,DE,83,F6,D8,56,18,72,26,10,20,A4,39,CF,22,29,E5,BB,A0,F8,4D,CC,B9,83,EC,A1,B4,52,7D,6B,52,C2,3D,F0,B4,8D,BC,FE,BD,73,AA,5F,07,90,1E,21,08,57,1E,2B,FE,37,F4,0E,A0,A3,08,99,A7,57,2F,05,5D,9C,FB,51,5C,F3,94,B4,2A,BB,B0,41,4C,18,89,F3,43,3E,BE,F3,FE,0A,88,C8,90,E5,95,31,C5,A0,76,78,E8,AA,D4,61,E0,60,31,8E,96,AC,20,8B,54,35,8B,43,C7,36,69,99,89,D5,83,4E,D3,B7,40,61,5D,7F,46,FB,84,B2,83,C5,79,89,E2,9A,70,3C,B8,3B,7D,F4,51,6B,FD,BC,71,D3,95,FD,7B,50,7D,D7,16,AC,29,B4,33,0C,82,6B,56,51,0F,4A,4E,98,2E,32,04,DD,BC,0F,94,AA,32,26,30,E8,08,C8,BE,4A,C4,69,F3,9F,B7,CC,13,B1,DC,B4,E3,E2,39,BA,92,85,9B,60,1D,EE,C8,8A,3B,E1,86,20,7D,86,3D,D8,E8,5F,EC,0B,00,AF,E7,9C,5E,A4,CB,7F,8A,46,3D,05,E0,0C,73,61,06,73,19,78,A3,96,EA,6A,7E,C8,6A,91,66,F2,32,79,FE,08,10,AF,A9,35,3D,2A,FE,BA,A9,59,82,6F,2F,0D,CB,17,B6,37,EC,E6,10,4D,4C,E1,C0,95,7D,F6,6E,E3,C2,F5,04,87,B0,F9,3F,CE,7A,7D,CE,56,15,B7,89,10,77,5C,89,F2,66,48,09,E0,AC,39,2E,75,2A,93,67,15,8A,A6,89,BA,61,BB,8F,64,DF,00,6B,30,6E,54,99,71,32,DB,E7,05,63,D2,5F,FF,9C,0D,C6,CF,D4,B1,92,5A,4F,D5,FA,2B,9E,88,2B,1D,14,ED,F1,40,42,BF,A5,95,BB,CF,02,13,97,09,4B,FA,68,C8,B1,01,CE,73,84,0D,95,57,E2,24,09,36,02,0C,53,E3,96,8C,D7,F7,AA,FF,EE,AA,24,C5,63,AF,2F,5F,89,89,F0,BE,E6,68,D2,77,ED,57,4B,FE,E6,1E,45,C6,E4,AC,6E,16,1D,40,95,FC,3C,26,33,0D,92,DD,FE,1D,A2,C2,15,B4,62,FC,F2,00,75,C0,94,C9,59,F2,B5,95,B0,31,6D,D8,82,91,A9,33,31,7C,8B,75,5C,1D,C9,4D,43,B9,6D,C7,52,82,01,B9,13,89,81,EA,89,50,37,DF,97,6E,B9,4A,9C,4B,10,94,58,F5,94,78,6E,5F,F9,51,BF,D8,19,27,FF,3E,6C,A7,96,6F,BD,D0,4C,AD,21,A4,D8,A1,7A,B1,AC,D4,04,3A,66,B2,9D,93,A5,9D,05,7F,C0,A8,37,43,E9,EE,A2,89,47,C5,AB,58,26,F1,0F,7B,F5,0A,5A,86,15,B2,DA,22,DE,E7,DB,44,DE,AE,94,3C,CE,F7,F3,9F,01,DF,9C,F1,F4,0C,EB,6B,E8,CB,A1,4D,E3,A7,D9,94,AB,B6,C9,E7,92,3D,6A,12,83,97,78,D4,17,79,02,A4,9C,79,75,CC,7C,86,DC,EA,7B,4B,A6,AF,8D,A1,B3,76,90,BB,57,03,64,FA,EF,9A,0A,D5,3D,F2,0A,A4,F3,97,4B,CA,AF,8E,94,72,9C,56,EF,1B,7E,68,48,B9,18,FC,74,AE,09,66,A6,EC,CC,65,A1,AE,E9,36,AE,D8,49,D0,ED,FE,3C,5C,7A,2A,23,EA,A6,BA,B1,8A,96,9A,83,AC,BA,08,FA,AF,65,A3,3C,E3,91,6B,88,95,1E,3B,F0,BA,60,B0,98,A7,F5,14,75,15,EA,3D,4F,0F,74,B8,B2,C4,D1,26,7D,CB,BB,F7,7B,63,B9,B6,B0,F2,CD,2E,DD,53,BA,29,68,AF,81,EF,73,AF,AA,4D,1A,A2,AB,68,DB,12,F3,ED,C7,DA,2E,F1,13,A6,A6,CA,63,B5,96,6F,08,E7,7A,66,61,6F,1C,1C,A8,4A,9A,6D,3C,63,65,26,DA,D5,A2,3C,88,37,AC,84,58,51,C2,FA,D0,F5,41,09,B8,17,11,0C,BA,D1,DA,CA,BD,35,B7,8E,57,26,41,00,0F,C3,C7,A5,2D,1A,4B,50,95,9F,B1,E3,27,44,5A,AB,62,05,A9,36,85,2D,93,6F,11,EF,E1,84,E0,B7,BA,37,20,2A,D9,A3,9C,5E,C9,14,D9,05,EC,FE,5F,E8,7F,89,73,DC,90,6D,8D,7C,D5,BF,EB,A0,87,4D,28,E9,D4,62,30,D0,FD,BB,47,3E,8F,A9,B2,51,D3,B2,48,D5,7E,C7,DA,49,54,BD,80,13,9A,1F,E2,38,64,51,EC,BC,02,81,69,71,DF,1B,EE,54,79,F3,4D,C1,73,E1,ED,90,3E,5E,CC,12,B9,7B,63,DF,0B,57,9B,7B,31,E5,D2,D3,C6,67,B3,AF,1F,9F,A1,6D,D7,9C,66,72,9E,04,CB,9C,89,3C,54,E1,AE,F1,2E,F6,54,6E,BD,67,1A,C2,00,E4,79,90,AF,40,70,B0,AB,5B,48,AA,33,B1,A2,E4,11,15,E5,AF,FD,90,AA,84,EF,A5,F1,21,E4,6A,C9,F4,70,73,5B,37,19,BB,8C,B5,7B,4E,41,C6,8E,0E,50,4B,2E,34,CC,CC,05,CF,3C,A0,CC,80,AA,81,52,FD,DD,2C,EE,B8,C4,55,FC,AE,02,DA,F6,6E,CF,10,A2,30,47,42,55,7D,D1,76,DF,13,EA,4F,B6,00,7F,89,08,4A,BA,BE,DB,85,5B,37,80,F1,ED,82,35,E5,22,07,2F,9B,5B,E2,BE,83,94,0F,C3,41,C8,66,6E,6A,EF,D6,A1,C3,D0,57,E5,3B,F0,AA,16,6A,CE,D9,23,85,8D,0D,35,B9,95,BF,12,66,CC,F2,01,9D,2A,DB,48,58,1B,2E,E5,EB,0A,94,46,12,42,44,B3,A4,A9,7D,57,AA,FF,B0,7A,55,63,F0,F4,DC,8B,A8,50,D2,F3,01,EF,3B,4B,F0,6F,52,33,B8,52,40,89,E9,FB,5C,4E,3F,78,2D,E4,75,B9,4A,9B,D1,41,71,83,5B,FB,8A,ED,36,2A,DA,93,11,6D,32,04,5B,8C,C2,D0,7B,16,E7,AF,7A,31,13,CE,EA,BB,2B,6B,7B,AE,91,AA,CF,A3,F0,F6,FF,4C,95,BF,F8,FC,85,D3,32,45,17,6B,53,56,28,99,EC,FD,5D,91,E1,63,32,2E,D4,1C,1E,D8,85,AF,A7,FB,E1,E8,09,C2,7E,F8,0A,7F,27,86,43,77,CC,77,8F,F4,7C,B2,3B,9D,E3,3E,DF,29,6E,18,6E,49,EF,3A,F1,51,03,A0,AA,D1,E9,2E,E2,01,81,0B,8F,16,0A,7C,CA,25,BC,8D,39,80,8F,A9,B3,0E,9F,58,DF,C0,E7,7A,D9,14,E6,F5,C2,F0,BC,B8,4A,E6,32,BF,80,A8,6E,D9,59,7C,2E,5A,FC,02,B8,D0,FF,8D,AF,4D,42,C6,80,8A,B1,A5,9D,9D,E5,59,D2,4C,26,EB,1E,3D,A0,BC,7A,5D,C1,6D,8E,B8,0D,10,2F,CD,62,20,D2,04,03,CB,7F,F3,C7,95,91,C1,53,F3,57,48,A0,DE,47,39,3A,6E,CD,33,98,74,EA,72,C3,5B,5B,18,EB,33,5A,34,FE,58,F1,B1,CC,8C,9B,E5,B5,0B,16,5A,B2,D4,3B,F2,DC,56,0E,26,61,4F,05,7D,25,17,26,93,49,F2,72,1C,7F,C8,1D,B0,BB,EF,0F,FB,0D,79,F9,6E,00,97,08,1C,56,71,F1,9F,64,A3,F3,95,DD,47,11,06,17,21,86,6C,D0,3E,DA,22,45,60,E5,15,14,E0,30,8C,B1,48,50,E7,24,B2,61,B9,85,85,15,53,9F,78,9E,54,22,94,79,1A,75,0F,4A,AC,71,8C,C3,D9,56,22,17,D9,70,AD,40,1F,CD,EC,C4,54,1A,33,F1,C8,72,7F,3A,BE,2D,69,EB,A4,F3,66,6B,D6,17,DF,54,29,22,2B,AC,B9,4D,97,FA,56,5B,07,A3,0A,E4,4A,D8,98,55,CD,94,1E,C9,14,AA,F3,6A,14,51,D5,02,15,16,8A,06,C4,ED,7A,FA,2B,6A,E6,34,46,B8,FA,34,0E,40,2B,24,40,73,59,A3,49,98,89,B2,81,4F,90,AB,CA,95,EE,A8,26,15,94,1C,8F,BE,6C,D6,07,0C,50,80,49,E9,4F,2F,A3,D8,E2,B8,C0,62,3D,81,61,A3,3E,D1,12,4C,1B,3F,F8,A0,0C,62,B4,87,3A,33,6A,CB,68,18,74,04,38,09,8C,62,84,EB,D0,44,83,55,6B,8F,6B,80,BE,5C,10,F4,97,F4,EF,68,F4,AF,3C,D3,26,AD,76,FF,B9,06,CC,85,E7,FB,0C,D7,9D,A5,A2,7B,49,E0,5D,4B,F4,D7,B9,3F,F6,98,2A,03,C2,2A,EF,56,24,7B,30,F7,F3,9E,FB,8C,F3,4E,35,61,09,BF,DF,E5,A7,53,47,02,CB,B4,E6,3A,06,7A,4C,B6,40,A3,87,35,74,26,F4,98,6A,8E,42,E9,0A,47,B8,57,6B,C7,C1,9C,36,A5,17,D2,5B,05,25,2F,4E,98,B6,22,62,DB,81,87,B9,4A,76,A5,CB,6B,79,F2,3B,C2,C8,A5,21,DE,3A,14,FC,2C,9B,BB,F5,B5,A4,F6,A5,07,06,8C,75,67,09,3F,7E,C3,00,ED,7E,4C,89,35,9F,EB,C3,6B,21,68,7C,4A,15,7D,53,A2,D2,8C,C4,B4,3C,1D,22,BA,CB,02,05,56,3F,6A,CC,C3,F0,AB,2A,C2,8B,27,41,49,70,60,B4,5F,54,71,48,4F,3D,70,CF,F7,6E,CA,F2,DC,4E,D5,DD,08,E7,1D,72,E2,BA,E3,92,4D,B2,7C,FD,4D,6D,30,74,76,5E,98,80,15,0B,2E,0A,7F,70,8E,61,31,8C,40,21,DD,6C,DF,2B,A4,24,63,E0,2D,DC,48,2A,2F,8C,10,6C,6B,FB,FF,86,B4,85,26,BC,9A,38,9F,86,31,DE,CE,D7,46,5C,FE,2C,1A,C3,36,38,68,69,2A,E4,DD,51,0A,BD,AC,45,90,8C,40,08,48,65,ED,17,9D,1C,87,F7,26,0B,8D,D9,52,44,C9,20,23,10,DE,72,8B,B3,02,A1,50,20,F6,B3,44,B1,D1,F5,DC,8E,25,45,36,7C,59,5F,27,A6,40,FC,F0,45,14,37,98,5D,49,3B,AB,A0,60,15,B4,9B,EF,AA,15,5A,7E,1A,5B,D9,86,4B,48,A6,4E,3A,66,58,29,B3,2C,E5,7D,7D,32,3D,DD,92,7D,5E,0B,B9,28,F0,97,7C,88,61,5D,4F,85,00,7C,CE,6E,D8,EE,14,F0,5E,04,55,5F,44,19,B7,F2,6F,CC,DC,2C,F5,DF,CF,91,CA,0B,3A,40,8C,6E,2A,C5,23,E9,53,F2,1A,AA,D1,30,EA,51,E0,AD,E6,7B,7D,83,87,38,BE,2F,70,04,D5,96,3C,9E,D4,C9,B3,FF,9C,A1,44,28,63,A2,B0,22,F6,66,36,32,05,5C,35,53,37,A6,9E,9C,A3,BB,E6,C0,D9,9B,73,78,A4,9A,74,78,C3,9E,20,2E,F3,3D,93,E7,A1,BB,63,87,2B,0C,DB,79,A7,46,4C,5B,F6,40,C5,01,4A,87,63,6A,EF,92,ED,D8,B6,AF,60,ED,53,8B,2B,0B,B7,94,B5,91,1F,B0,A5,37,3A,BD,FA,5D,98,57,E1,8E,A0,42,54,BF,64,1A,8C,54,C3,A2,56,00,F5,B6,CB,CD,4D,28,60,3D,CA,3C,B7,A0,42,E7,0F,4D,6B,54,DC,79,59,69,75,69,DB,68,52,28,FC,5F,98,F8,62,97,3E,88,AA,06,4C,51,E9,1C,08,82,C6,5C,2D,39,81,B9,E6,F4,7D,85,75,D0,93,1D,69,C6,3F,B8,48,1F,28,62,D0,37,0E,E5,D6,AB,67,74,F2,4E,05,4C,53,4A,3E,62,05,71,3A,AD,BD,B3,17,5A,18,C0,C0,41,AE,43,F1,38,D8,5A,A1,6F,0E,08,04,19,44,B3,E1,AC,54,AE,AD,31,B3,9B,DF,B6,6F,8F,EC,16,B8,36,85,25,5F,49,CA,BE,87,7B,43,92,25,C7,62,D4,69,2C,A8,9F,4F,01,BB,20,9E,2E,A2,59,1B,1A,B2,DE,F8,D3,30,90,EE,6D,17,71,54,8E,7A,5B,5E,D9,FF,80,43,E6,89,06,A7,FA,22,29,58,A0,B7,BE,71,F3,E3,21,00,E5,99,86,63,88,CA,A8,67,6F,BC,D9,5F,BF,A1,1B,33,14,56,69,84,5E,E4,02,52,40,A8,33,29,DF,A2,07,2E,36,EA,51,C3,25,7C,BB,F4,3E,96,2E,88,10,84,3B,EC,B9,05,FB,F3,B7,26,D5,49,93,BD,CA,EC,7D,DC,7D,EA,6D,2C,AD,B7,86,7A,6D,8A,E6,0F,16,B4,22,20,D1,EC,13,F6,C4,27,47,6D,5A,0C,AA,07,D8,D8,FB,0D,E2,D1,BA,76,59,7B,07,C7,E8,2F,B9,6B,BA,7E,7A,E5,C9,6E,A7,0C,FC,D2,F5,1A,31,65,0C,C6,47,01,60,29,F1,0A,6E,63,7C,78,AA,E5,F8,88,CC,20,6E,5D,1D,D0,B0,3F,C5,9A,22,DF,C1,DD,F5,86,0D,54,A8,08,62,4E,2E,1A,35,FF,F8,18,95,3E,4F,29,49,14,71,F5,58,A2,C0,32,6E,CA,9F,60,56,52,4A,45,D6,A5,33,B2,39,4C,64,6A,D1,54,30,C8,40,DA,BF,91,5E,51,A1,B8,F2,8C,6B,BC,0C,32,F9,57,05,AD,0C,B8,AF,9F,13,E4,F6,C8,F1,05,47,AF,72,1A,82,64,2D,B7,68,6A,64,B7,66,13,EA,09,CF,CB,D3,8C,11,E3,3E,0A,EA,D4,D7,47,1B,1E,08,87,78,7D,19,21,E8,1A,B1,EB,A7,3E,61,7E,D0,98,D8,B6,7F,37,D3,00,E3,45,B6,DB,94,89,97,0D,3D,A4,03,A4,93,90,0B,06,16,2D,5A,34,B5,B9,E5,B7,58,D8,48,4B,54,64,76,FD,93,F0,1F,42,43,96,15,B8,72,4E,99,C1,31,8E,F1,9B,94,93,24,C2,7A,32,61,05,4C,2D,35,7D,24,2E,23,5A,BE,F5,43,1E,59,9E,A2,E6,B2,9A,9B,80,12,9C,DA,CA,A6,3A,EF,D9,C9,E0,D8,12,EA,E6,61,4D,C7,31,E7,4B,A5,D5,29,08,7A,4A,D7,E9,95,A0,0C,23,6F,26,84,79,A7,C1,65,39,93,B3,83,3A,C1,4E,CD,DF,46,44,85,FD,5D,C6,F7,48,2B,63,5A,23,FA,81,1E,42,E4,EE,40,E8,8E,BB,B2,46,1C,6A,97,B1,4A,F2,2A,99,DE,97,47,53,8D,71,7B,9F,56,B7,63,3F,CE,A0,B4,17,E1,AE,48,E2,89,D7,23,98,0B,B8,17,BC,DD,F9,C5,ED,C4,8F,56,83,29,EB,07,65,0B,6E,BD,57,58,43,A7,E0,B7,F0,86,7E,6B,75,F7,3D,48,58,46,77,CC,45,BA,FB,D3,5D,62,9F,3D,B7,9F,5F,D9,7E,F1,1E,B6,E8,FA,7A,0D,E9,92,2A,07,F4,33,07,0E,93,57,6D,DD,08,8A,70,F6,A7,1B,B8,DE,EE,08,96,C0,72,D8,68,47,3D,56,6C,B8,2E,B0,93,B4,A0,9B,BF,3F,18,6E,51,A4,ED,52,B4,36,5D,7B,A3,3D,9E,DF,A1,26,E1,6A,1A,95,66,25,6B,99,81,02,D9,F9,30,E1,4B,42,D2,EC,5B,BC,54,38,23,0C,3D,6C,57,7A,70,9C,67,2C,0B,D4,35,42,D3,33,B1,45,D1,EE,B7,6F,0E,5A,8C,C0,7B,ED,1C,8F,67,A5,32,B0,B9,D0,AD,1A,23,80,C3,FA,82,13,21,CC,54,F8,23,B6,01,21,4B,2E,22,74,CE,37,EF,4A,9F,0E,CC,71,DC,24,7A,F3,05,DB,A6,72,A9,58,E6,41,B7,20,63,6B,42,35,FF,51,D2,A1,2C,01,B4,66,6E,93,13,9F,99,FC,1D,60,74,7B,2F,B6,BD,2B,1C,9D,BE,29,AF,51,65,83,CF,14,0E,FC,AA,1B,CE,95,1B,C4,BD,1C,69,A7,F3,DD,11,9D,85,FF,B1,5D,C2,E6,99,B4,99,25,91,1A,47,ED,A2,08,41,F9,0F,2D,C7,EA,F3,DD,7C,81,B5,56,87,62,FA,23,27,4A,7C,CB,4A,A3,32,0F,2B,67,ED,A3,AE,7E,F9,70,3D,AC,A3,CE,80,48,A1,2B,DC,1E,38,B8,01,94,7E,6D,4D,14,A7,D3,64,D3,38,57,26,6E,1B,B7,13,4D,2D,4F,2C,E7,06,B9,56,8E,0F,BE,1B,03,6F,51,B0,37,F8,69,89,8C,80,17,BD,46,CE,7A,20,41,5C,AF,91,49,B5,84,F0,66,36,5E,8C,39,82,13,5A,4C,1E,8A,13,02,BD,B1,ED,78,94,8D,31,E5,C4,0B,3C,11,8B,9C,B4,6C,C5,42,F2,66,D8,C4,10,23,BF,55,26,3F,AC,A6,E4,C5,48,4D,E0,1A,16,E8,1E,92,D7,0B,DE,26,07,55,56,0D,BF,C8,AE,A0,CA,15,01,84,C2,C4,AD,B1,1F,0E,E7,8C,37,AD,DA,1D,42,7C,67,83,6B,4B,2F,18,26,FB,5A,38,8D,8D,FD,D6,36,31,D9,4B,AD,EE,52,29,45,AA,EF,9B,2C,30,32,9E,FC,84,C9,27,0B,2A,D8,0C,10,CB,03,78,AD,2A,16,F0,44,E2,34,7B,EA,83,12,AE,19,65,CC,9A,A7,B8,0E,14,73,70,9C,D4,65,AC,A8,F4,1F,59,0A,8B,1E,66,AE,79,80,23,17,26,21,07,E3,7D,41,37,E9,CF,92,06,EA,91,CF,09,A7,FF,7D,11,88,25,22,B6,89,5A,51,1A,62,1C,76,A5,80,69,0F,A2,44,56,F3,7B,40,A5,11,88,F0,37,DB,DE,6F,29,EE,2D,E1,F3,B5,26,25,BC,8F,DB,CE,E1,2D,8B,93,9A,7A,82,58,BB,93,3A,18,6E,98,E7,C1,DE,84,2F,06,1D,A9,FF,C8,25,2F,03,CE,7A,6F,FC,73,4B,2A,F0,41,B4,7B,66,83,40,CD,BB,25,15,DD,CC,2B,D5,75,A8,42,30,F9,45,B4,70,4C,DE,93,AA,AC,CB,3B,17,EF,5C,A7,E2,13,5F,08,42,83,BB,98,79,85,67,81,46,54,D4,88,1D,1F,DB,EF,3B,30,34,67,57,E0,D2,BF,10,7C,34,7A,F4,74,D3,B0,50,64,4D,75,96,E9,BC,84,D2,B7,CC,6F,5F,09,0D,FF,44,CE,68,42,EF,A1,32,6B,10,69,BA,A0,E2,E3,FC,83,40,E6,13,F0,EE,11,5E,BA,D0,3B,00,FF,E1,4A,D2,0F,E8,79,A1,4D,A5,E5,82,8B,D8,CE,C3,6C,65,12,49,F6,53,FE,CC,47,C4,1C,65,85,0D,95,B5,4B,A6,A5,A0,38,72,8D,FA,4B,7D,04,76,D6,95,63,96,79,CD,33,A3,9E,6F,69,02,01,9C,E9,11,2E,A4,50,1B,53,ED,4F,70,DB,FE,02,A1,4F,E9,4F,3D,FF,6C,96,F4,41,A9,09,B8,9A,BD,CF,EA,8E,39,FC,BD,A8,27,73,CF,AF,57,DB,47,D3,B7,A6,EE,A6,90,56,FA,4F,4B,45,00,53,D1,97,00,00,DC,27,54,B7,A6,41,6B,7D,F0,D4,25,78,C9,58,2C,77,0A,35,80,15,29,DD,0E,82,15,6F,65,63,D0,A4,5E,5D,FA,26,37,C4,8A,4B,F7,2E,F0,B7,A7,1D,D1,AD,E9,58,3B,6C,BB,8C,58,6C,6A,99,F5,E4,62,7B,8D,FC,CA,BD,51,0C,28,15,70,FB,F7,CD,94,D6,BC,6E,75,58,00,60,1B,6B,73,3A,CD,E3,8F,86,71,A6,D7,C2,18,95,67,68,08,77,80,B4,A0,84,37,66,FB,09,CA,A0,50,9F,C1,E9,E9,36,A9,04,0B,8B,17,7F,CB,22,24,79,0D,DE,8D,27,C2,6D,A3,3A,E0,5F,2E,80,D7,39,E9,76,1C,D5,74,50,7E,83,F5,37,4A,AC,84,14,3B,CE,FC,EC,D8,28,8F,72,30,C5,9F,DC,0E,CF,51,A9,B6,5F,F3,8E,3B,71,F9,D4,E0,CD,27,E1,7C,0D,5C,02,29,56,CC,E3,05,F5,6B,2D,B7,92,A6,2B,55,17,67,1A,BE,F2,E9,E4,60,53,D9,10,B6,1B,2E,94,53,D5,80,9B,C3,8B,CE,90,4B,D1,1E,7D,29,8F,38,DA,5F,69,1B,A3,72,24,23,3F,82,2A,A9,8E,4E,18,FE,8A,28,9B,1E,E8,51,51,37,45,68,C9,06,F0,2E,45,63,7D,3E,32,2D,C9,75,CA,9C,C0,4B,18,F1,7F,25,33,2D,27,0A,23,19,49,8D,08,B9,10,B2,70,40,FE,EE,0B,4C,57,05,19,9C,09,33,D3,94,8C,5D,FF,ED,87,73,27,C2,52,2B,75,11,8A,41,A1,0E,19,9F,31,54,1D,D4,03,5B,62,90,B6,C7,4F,5B,B2,94,68,7E,FF,4E,82,ED,0E,1B,3B,42,89,36,A1,B8,95,F0,60,87,8C,D5,69,CB,F6,8A,DB,6E,EF,D7,47,DB,25,AF,CD,D3,7E,CC,F8,09,AA,0B,AD,BD,A2,8B,42,BF,27,4B,DC,F6,31,4B,52,13,86,3F,40,38,75,DB,82,38,0D,C8,20,AF,9A,D9,D7,67,FC,16,A4,DC,0C,21,12,C1,00,4C,3E,5C,4B,0A,AC,A1,D0,6D,3D,94,A9,B8,6C,DD,7E,DB,52,1D,CF,86,22,78,51,E8,4F,5B,4C,73,25,B9,B5,25,00,16,36,EE,FA,7F,59,66,41,08,72,15,F7,3D,B9,9A,13,07,2F,02,D9,C7,2A,6A,35,8E,75,84,C0,E0,F2,7F,9A,02,AB,B3,2E,8B,B8,DF,57,DA,D6,CE,44,AF,F8,70,7E,23,EB,86,DC,E3,6C,90,3D,67,C5,E4,A0,E8,6A,BA,EE,D1,AC,0E,7C,BE,D9,EC,2F,F5,BD,53,A0,6E,D2,8F,D9,CD,D9,D7,D8,A8,D8,72,38,CB,B1,70,9E,C7,DB,6D,47,57,76,50,64,88,9A,84,05,13,3C,DD,3F,C7,3F,9A,1F,B0,D4,01,E0,48,7C,C5,88,9A,B0,14,AA,B5,7B,EF,0C,63,FF,40,65,DF,D6,24,25,9D,11,83,94,4C,1C,D1,F3,FD,85,E3,8D,8A,9D,75,E6,ED,87,90,1C,D8,41,7F,E8,41,C5,E1,4B,B3,C8,B4,0B,D9,4E,79,66,E2,47,70,09,BF,2C,A9,B4,53,00,61,2D,57,D8,30,33,9C,BC,48,73,EA,25,1C,6C,93,B2,AA,D5,0D,30,EA,E2,EA,CC,18,63,4F,F1,B3,3A,77,F9,E0,38,E4,A2,57,9A,3A,EA,F8,A2,3B,F8,C1,0F,ED,35,3E,B4,31,3C,F6,EE,0C,59,BC,4B,C9,B7,F7,D8,1C,E8,71,A2,30,C5,61,0A,56,03,63,5B,43,19,10,8D,16,10,20,46,AA,92,E2,A3,ED,AC,F1,38,88,88,40,12,43,D9,76,DB,65,54,86,3C,BD,43,42,2A,9D,94,D5,49,BB,2B,11,83,F0,70,1E,D3,9D,59,DE,89,A2,01,B5,A2,B3,41,00,75,3F,AE,18,FD,9E,2E,19,A4,A3,AB,F7,3C,CD,5F,59,F4,1C,5C,54,32,55,CD,64,4F,93,13,9C,C3,18,99,C1,95,A5,C3,D8,8E,2C,5D,C0,99,81,8A,00,29,43,95,D5,D9,C5,2D,31,B3,DA,6B,E2,8E,DF,36,DB,CA,F1,AA,31,0A,D2,35,52,3F,46,C8,7D,03,EA,C0,E1,CA,B4,E0,31,F8,DA,48,A9,E3,E2,8D,3C,59,37,4A,5D,15,EE,2B,69,54,2F,44,E0,5E,69,B7,45,C5,B5,12,EF,C8,1E,A5,AF,3A,A8,8F,F6,AA,4B,4F,C3,94,D8,B3,12,0A,9E,3A,05,CF,81,D8,A6,22,0E,64,55,1E,74,15,02,02,86,D3,CA,31,CF,1B,23,C6,41,73,66,6B,3C,17,08,7D,A4,2B,CF,57,48,B2,3C,59,A2,1D,C5,0C,27,4B,4B,7D,D8,5A,CA,29,23,3F,82,9B,22,4A,73,52,86,3F,18,DA,13,7E,F5,26,10,AE,7F,6F,74,3A,33,A8,8C,6B,D5,4A,D3,31,29,1A,C4,A2,B5,BD,89,42,33,D8,2F,0D,D3,95,63,3A,E9,09,35,D2,B5,1B,61,37,43,08,20,6F,4A,7F,7A,0A,A6,7E,1F,73,A8,C6,42,98,34,8B,6E,94,AC,75,01,B8,28,4F,B4,FB,B0,2C,F2,32,77,2F,98,10,3B,5F,D8,F5,0B,AA,C9,2F,59,7C,BB,7E,CB,80,07,20,7D,7B,33,AA,38,AE,31,67,6B,56,D5,12,C0,D6,B3,51,66,54,68,AD,C8,F9,24,E1,1F,A7,F5,91,D3,05,35,B1,5B,20,00,9A,47,F3,A3,AF,0D,C2,13,11,43,BF,A6,97,E2,81,11,3C,2B,12,D2,74,EB,02,C5,CF,C4,D6,AC,CE,E0,B9,D7,0B,9E,64,84,9C,BB,25,E3,94,23,4F,14,82,E6,07,92,99,D7,FE,4F,D3,E9,44,7B,12,EB,48,AD,E4,89,97,A8,75,C8,B1,31,F7,FE,88,8B,7F,6B,E5,6E,0E,4D,3B,B4,F7,CF,2A,0B,F0,B7,B5,BB,51,41,45,36,A4,4F,A2,B7,64,A8,AD,09,58,75,B5,1A,5A,E7,F0,F6,61,69,91,A4,55,52,59,57,1A,2B,B7,1B,A2,96,67,E1,43,AA,D5,07,09,01,FE,C7,A5,1F,F4,A3,C0,41,88,C0,83,34,57,41,12,5F,AB,BC,1C,D4,EB,AC,AA,84,AE,DD,48,19,ED,53,EE,0F,94,E7,EF,CB,2F,01,89,C3,99,7D,D5,3A,17,FE,AC,08,54,0A,A6,EA,21,B5,4B,82,C7,AC,CF,75,50,75,94,F3,6A,4F,D4,48,BF,12,1D,44,6F,69,6E,55,3E,6C,C1,90,7E,9B,B3,53,2D,BC,D6,64,3B,F1,EB,55,A1,7B,40,F3,4B,8F,47,4A,56,5A,67,E6,B4,AB,AE,E7,97,4E,F6,58,1D,3B,8E,10,C7,4F,2D,00,18,82,0D,EE,E4,86,C8,EA,1D,BB,76,A3,33,44,5B,5B,4F,2D,3B,44,4C,F2,8B,21,78,37,AF,D2,39,0C,93,55,CD,CC,6F,B2,B2,9E,84,E0,FE,6B,32,4C,AF,2D,2A,E5,0B,15,87,40,E1,A6,83,98,C2,4E,29,61,B3,75,74,26,61,8D,79,0F,55,80,3E,AF,5F,A0,36,B7,E2,A1,86,53,A7,1C,D5,8F,22,06,70,C2,4D,32,05,60,85,D5,89,DD,15,3A,1D,55,57,67,61,A4,15,CC,1C,72,97,36,50,76,1A,93,85,F8,90,A7,69,A6,E4,ED,50,B0,0B,0D,98,70,03,A7,85,EE,37,8D,9F,EB,56,09,C1,62,A8,C6,37,E3,70,EF,E5,67,1D,EA,C0,3D,09,40,65,AE,76,81,65,A4,29,65,18,D0,D6,54,1A,8E,0B,1F,79,24,B5,3E,5F,8B,41,77,55,AE,74,49,1D,6C,AD,D9,75,3A,04,25,31,2C,91,EC,9F,97,0D,09,0D,FF,16,7D,99,65,85,FC,D0,1C,9D,36,59,37,B7,28,DA,79,3B,A1,C2,62,1E,6E,EA,6B,BA,03,95,56,53,8F,C1,B0,82,1D,37,99,2C,FF,11,D6,2F,CE,86,2B,F7,D9,FE,F9,7B,5D,46,8B,9F,0F,84,5A,D6,19,6C,7E,D9,52,FB,F9,09,30,EB,71,E2,F3,E4,BF,B3,F5,D4,57,61,9C,18,5B,1E,C6,B7,7D,85,5C,54,3C,96,C0,3B,EE,1B,F6,C1,CC,0B,08,E1,8D,86,54,03,BB,9B,54,FD,A2,58,D4,6D,C1,C1,6B,A8,53,79,23,28,4F,78,D1,FE,42,C9,C0,8E,ED,F1,52,3A,18,35,95,D0,AE,05,E8,DF,5F,9C,DC,BE,95,E5,9E,30,CD,85,73,F6,22,EA,D9,91,F2,D1,A6,65,45,18,AE,0E,CC,3C,0D,FC,22,BA,A7,81,B5,1D,21,65,AD,5D,6D,A7,93,62,C5,D2,CD,AE,CD,BB,40,45,69,55,4E,DC,DC,72,72,BA,AE,77,84,2A,8D,02,31,A2,2C,1B,3C,24,D1,12,9B,BA,DB,FF,CE,C8,91,BA,A1,34,00,8C,8F,59,F0,88,29,B6,4B,9A,D8,B1,59,A2,B4,3A,43,5A,EC,80,D8,E1,D7,3C,EC,FB,6A,E6,AC,D6,58,00,5D,72,2F,91,8A,54,93,73,52,C8,22,24,BC,B1,0E,D8,3C,C4,B8,2C,A5,B2,F6,A5,71,70,16,3E,8F,81,AB,9F,DA,31,52,88,84,BD,6B,7C,BE,B4,E7,45,80,CF,EC,D0,4A,F5,17,2C,C2,92,06,EE,30,BA,B6,A3,CD,A5,83,09,4A,1C,33,64,4F,22,60,ED,AD,3F,76,6F,62,61,E1,7F,96,B8,9A,E2,DB,BB,20,3D,CD,E7,E7,27,9F,7E,62,FA,F5,00,0B,FD,4D,E7,74,E0,5F,A5,20,32,68,14,68,EB,15,4F,9A,7B,CD,12,87,7E,92,3A,0C,03,FB,F1,95,D6,00,17,A6,13,96,33,A2,21,01,FF,D4,72,AD,97,BC,33,66,09,CC,DE,97,47,7D,47,C3,9C,B5,1F,8F,05,59,D4,08,29,BF,90,46,74,55,5E,A4,D4,7B,C5,05,E3,22,3E,07,C6,BB,E6,37,2A,36,DB,84,F1,1F,CD,67,48,D0,5C,C7,7A,6E,18,BB,8A,F1,9E,87,8E,9B,C7,07,52,87,42,AA,58,DE,EC,C2,57,19,33,56,B6,64,4A,5A,B2,5A,24,75,AC,59,DD,14,3E,33,55,86,38,7C,0D,8F,A0,E2,CE,F1,22,E0,9E,30,11,90,65,98,2E,3F,F5,F8,F3,7F,CE,23,3E,28,36,26,AD,04,2D,B9,82,C1,7A,E1,97,07,A9,EF,78,FF,6F,98,F0,4E,B6,E6,BA,0A,B4,5E,C9,82,31,F1,81,E9,AA,F4,78,B1,8B,98,97,57,C4,AC,DD,32,B5,B4,62,C6,2A,4F,18,44,24,8A,FB,CE,BD,82,75,43,03,EB,9F,00,8A,07,CB,B2,4C,4C,99,DB,06,23,5F,40,32,20,A5,E9,2D,10,5E,D6,DB,EA,80,3B,DC,5F,CE,F8,07,17,E1,9F,57,F4,5B,D1,D8,2A,C3,8F,D1,5A,41,40,21,AC,15,9F,A4,D3,96,4E,6B,EC,D7,FE,DD,BF,56,D5,CF,C6,13,BC,B3,2C,AC,77,46,78,67,37,D4,83,6A,7A,7A,69,D8,17,F3,40,FE,3C,BC,37,70,73,B0,0D,34,EC,05,CE,73,C8,0A,04,E2,E6,39,43,C1,70,78,38,03,B8,C3,B3,18,44,BF,87,6A,42,F7,8E,3E,A7,C6,96,93,EF,2B,8C,A2,32,CC,E9,78,60,2B,E1,F4,EF,EA,31,C0,43,45,EF,35,50,FD,6E,A5,AA,81,E8,9C,13,F8,14,BB,E0,78,C6,42,FB,73,BD,0F,45,8F,58,19,83,DD,A6,AF,9F,7C,8B,D2,D0,EC,20,BE,B6,F5,78,F9,61,4C,A3,69,1C,68,58,AB,16,CD,8B,63,01,E0,E2,6F,5F,D2,61,B0,07,13,16,D8,A4,62,E9,0D,BC,9E,F6,C1,98,13,7A,86,9F,7D,79,D3,86,02,C7,FC,CF,AC,EC,EF,2D,30,CB,73,CD,F3,DD,95,CB,67,78,24,10,06,E3,41,88,BF,37,2E,8E,A9,C5,18,F4,7B,C2,9A,FC,B7,68,95,C0,F0,13,BA,0D,0E,A9,0B,D8,CC,E2,60,EA,60,BE,C2,5E,7E,4F,4F,DB,1E,E7,51,1E,35,62,52,C2,32,B3,C5,8B,85,89,DD,B9,3F,A1,33,72,2A,B6,E4,02,BB,5B,D0,78,2D,DE,7E,D9,CE,38,4E,A9,46,CB,A7,25,25,43,34,D9,19,11,9C,46,AA,C3,83,34,82,4B,40,8A,EE,2E,50,A1,9D,A2,41,48,A1,EC,4B,5C,E5,06,40,D9,A0,D6,A5,F5,E6,18,E0,A1,22,D9,57,A6,23,A7,3F,F4,EE,D0,2B,64,0B,6F,91,38,D7,B5,0E,BE,48,DD,0A,AD,2D,D8,71,5E,EB,18,DD,E9,5A,24,91,A7,EE,A2,F9,D7,EE,4C,83,9E,1A,0A,20,2A,12,3B,0A,6F,CB,32,81,2E,33,AA,52,27,6E,A3,DE,45,6C,E4,38,D2,F2,32,8E,85,92,35,ED,B0,67,0C,E0,1E,07,4A,73,BA,64,B4,65,6D,22,E2,66,29,47,4D,BB,69,AD,6B,6C,11,97,2C,95,62,EA,C0,3A,30,63,22,81,E5,97,4F,67,32,97,EB,1C,1A,BD,22,7B,1E,36,AA,21,5B,40,7A,06,B8,E1,B9,2A,D9,3E,A4,85,21,AA,82,99,B7,D8,CF,19,95,2D,9B,0D,AA,7F,DC,72,17,8E,79,A9,2C,CA,1F,DD,D4,15,CC,29,EB,C5,3C,9C,6D,16,51,84,95,A3,DF,EC,50,B7,B9,9A,99,68,4F,F1,61,D6,D7,CA,52,C3,1F,06,43,10,0D,23,3F,E1,BD,87,F6,C5,BB,7F,BF,8E,5A,5F,86,83,7C,21,B4,6E,61,DF,09,6C,C1,B1,AF,54,62,AA,4D,BD,38,04,1F,36,00,C9,21,8A,10,E3,02,52,AE,31,55,6E,3E,B8,19,AD,B4,E3,E2,F7,57,F1,D5,44,51,27,1D,AE,C2,73,26,F5,4B,E5,0A,E7,44,A9,EC,6C,D5,65,E3,DD,3C,F6,57,49,D4,3B,3C,1D,02,CB,4E,5F,4E,A8,55,A9,C2,74,D6,CD,06,6E,4B,7E,2D,C9,7B,B6,B4,E8,59,A7,F2,C1,91,3E,C6,66,99,7E,FC,D1,48,35,04,55,F8,3C,98,7C,BD,50,89,22,91,4E,74,95,92,91,B0,32,A6,02,33,64,D1,7A,33,3B,4B,8E,91,59,30,6A,B4,9D,BC,00,AF,FA,16,EF,C6,A0,B0,3C,45,2A,44,E4,62,33,48,E4,B4,C5,4C,DB,52,96,96,6B,95,CA,75,50,85,1A,76,8B,18,35,60,6D,5A,6E,D0,5E,12,01,87,E3,D1,B1,1A,BD,56,81,54,42,24,21,81,41,32,39,43,C6,24,4D,EE,DD,C0,21,CD,39,C3,11,73,BF,8B,AD,C5,F8,88,94,16,0F,AD,04,C3,5F,7A,61,4F,8F,8F,84,74,A3,50,33,C5,7C,BC,E9,3F,7E,70,D1,7B,32,A9,1C,CF,23,C2,F5,87,CD,7B,F1,3A,5D,17,5E,8D,8C,AD,10,ED,45,65,9C,49,DB,7F,67,70,AA,56,55,AE,B8,23,5D,26,93,6D,4F,38,1F,90,3E,0D,92,50,50,8B,84,64,EB,46,FC,B7,9F,10,74,A1,E9,61,0A,6E,B8,B5,C9,7A,A1,C2,65,63,97,06,4B,E4,A8,9C,F9,02,08,F7,DA,F6,5B,A8,D2,8A,CC,5A,8F,18,F9,7B,B9,B6,6D,5D,A3,9C,D2,09,E8,A7,4E,C5,04,A5,9F,51,07,2A,4B,09,40,63,D7,0B,4F,16,2A,53,82,11,B1,C6,64,BD,5E,AD,D7,C6,5E,60,75,61,C8,66,59,9B,9E,E5,67,6E,B6,9A,38,92,75,71,43,FB,5A,29,05,ED,A5,C4,1A,E4,4A,4F,38,BE,F8,0F,D6,4B,5D,2F,94,BB,52,6D,37,7E,CA,D1,C3,AC,EB,CE,56,DB,01,39,C7,86,49,81,98,C6,65,53,08,95,13,61,F4,EF,19,63,F3,0C,84,1E,11,7B,7C,A5,62,C6,25,DB,E6,3C,06,07,BD,DF,1C,3C,B1,D5,FD,BD,B7,68,31,84,B1,E7,2D,1B,ED,04,58,98,F2,52,1F,11,B5,F6,B9,F2,A3,93,3B,6D,AE,32,F5,10,16,E8,61,CB,D8,17,F1,9E,94,EE,DA,B5,80,C6,A5,73,B2,85,8A,A2,8A,17,3A,B9,11,66,47,FE,B2,35,A5,25,1A,80,21,11,19,EF,B7,8C,EE,04,13,63,85,BB,CD,F4,F4,38,84,D8,65,E9,3D,0E,0B,A6,AB,01,63,BF,2D,4A,18,B6,8A,D2,9C,BA,77,B0,9A,6C,2F,10,D6,E4,B0,AF,B9,94,D9,89,13,04,85,3B,9D,2E,6A,2D,63,D5,8E,56,7C,3A,AB,42,E5,71,C9,71,3F,48,C6,EB,8F,2D,C1,BE,0E,5B,4D,B6,A9,2A,8C,3D,5F,F0,C8,C5,81,9F,4F,EF,A8,59,F1,34,F2,63,B8,5E,02,DB,3E,8D,F3,F4,45,F7,AA,73,A9,17,83,AE,FB,95,DD,F6,AF,F2,09,06,77,20,46,D3,10,8C,59,03,46,C2,58,B2,2C,BF,45,DD,5C,4E,85,3C,69,29,4C,F6,DA,4E,88,8E,53,A3,04,51,BB,6E,A2,DA,E5,4E,A3,2D,A6,16,6F,47,F4,E9,6E,4B,50,C6,93,6B,E1,FC,31,2A,F1,E3,3F,A9,C9,C0,12,70,84,3A,D3,D4,E0,2B,87,D1,78,73,E0,76,07,D1,2E,A6,09,FA,38,21,42,E5,75,9B,58,52,73,00,51,19,B1,00,64,89,BD,C7,37,62,79,61,54,13,D2,D4,0A,37,EF,B1,7B,DA,BF,99,70,DD,CE,E7,FD,AA,F6,ED,5E,07,60,6B,92,23,2E,42,8D,02,DE,9E,0F,AA,9F,BF,31,73,AE,33,6C,BB,74,13,F7,16,4F,AD,70,56,AF,F9,9C,21,2D,79,C3,34,F0,B5,2F,55,F6,A9,73,FB,D0,D8,B2,44,1B,8F,4C,88,63,19,88,28,21,B6,3F,EB,22,DB,E7,76,1E,96,55,F5,FE,B2,85,1F,D0,48,47,EC,50,95,5C,E7,3D,E6,31,A7,0D,DE,7F,ED,A1,B0,60,8D,96,88,C7,A2,DA,58,38,64,F1,88,2E,54,FE,9A,FC,04,F5,DE,78,B9,E6,0D,D9,60,02,C4,54,2E,79,69,62,14,2B,9B,02,23,97,76,BC,B9,F6,95,32,70,8A,06,2D,D4,46,CA,6C,CF,00,86,C0,E7,BF,30,7D,E4,DD,55,13,A1,C3,06,FD,26,E6,07,75,51,52,6B,3E,1F,BA,9C,07,D2,C7,41,C2,AC,C0,E6,67,40,9B,E8,5F,E4,0C,CB,B3,D8,0B,75,E5,EE,E0,E6,70,E6,DD,F6,EC,B9,2D,EC,13,D2,A6,E7,FB,94,E6,AD,94,30,C3,25,CB,57,16,5F,B2,8E,7F,46,8D,AE,B4,BB,2E,01,4A,C5,AB,7F,72,41,9E,C0,FF,1C,43,CA,3C,AD,48,F5,A9,13,81,73,47,92,2E,24,DE,5A,03,76,44,44,63,51,37,36,32,04,ED,BC,A3,AE,32,E1,8E,30,67,CF,DD,51,D5,A8,A1,F9,96,02,B9,BC,F2,DE,9E,3F,4A,B7,B6,C5,BB,CC,49,2C,6F,1A,E1,F7,BF,1B,52,D5,EC,30,56,F5,15,B8,83,E7,5F,B7,C4,94,44,49,1C,F4,E4,46,70,B8,44,83,E1,80,93,97,BC,D9,B2,77,1E,D2,98,76,47,90,0C,7A,F4,CD,D6,C6,27,B8,20,14,BF,D1,A3,A1,44,C7,A6,77,F3,87,A0,A0,C9,57,35,40,95,BF,91,05,11,66,61,B1,2E,43,46,C4,B8,0A,3D,A4,91,88,B5,4C,B1,A1,71,06,F5,8B,86,6E,96,E1,04,51,06,E5,75,4A,A0,00,F3,8E,72,62,DA,76,18,E5,8C,81,BD,8F,9D,76,CA,BB,50,8D,74,C0,7C,F0,18,E6,EB,B7,B5,BD,FE,85,F4,6D,03,51,3E,10,74,F3,56,6D,36,37,4F,6A,FD,8F,B2,33,81,74,34,CA,2B,19,CD,6F,2C,4F,73,87,88,5C,A3,ED,D5,FD,03,9B,9E,90,76,30,A4,7A,E6,92,6B,D4,29,58,27,69,EA,2E,0A,D2,83,7E,04,0D,0F,79,5D,D4,1E,56,A5,8C,4A,8F,F0,CA,51,DD,DF,83,C5,D4,11,FE,F5,D1,BD,A9,0F,7E,88,D8,19,AC,30,16,D9,2E,74,1F,B9,38,12,18,13,E1,35,DE,56,73,DB,57,E6,10,82,7C,8E,EB,2F,92,60,01,B1,1F,0D,01,D8,2F,1A,C8,BD,FA,C0,F9,6D,4D,8D,2C,97,95,FC,50,CF,93,54,4A,46,F7,10,61,C6,C2,4B,EA,01,B6,C1,92,9C,0F,FC,83,DE,4B,7F,B6,BA,3B,31,24,12,DF,EC,22,CB,45,5B,E2,AE,77,96,C3,65,D8,E8,EA,46,18,E2,04,E4,9E,FC,CD,05,38,E1,CA,8B,3A,51,DE,14,18,CA,D5,43,3E,E9,50,FA,4E,2E,13,EA,E7,06,C1,EC,DE,E5,43,42,E4,B1,47,CB,BC,2C,A9,97,49,CC,73,97,0C,50,29,2B,75,E9,31,14,C0,C2,7C,BD,4E,68,5B,9E,4D,EC,EC,3F,43,E7,A0,9A,4E,55,26,E0,A1,69,EC,F3,93,C1,EC,B9,39,10,30,8B,AE,83,9E,4F,A1,18,B2,BF,FE,D3,0A,55,4C,B1,33,92,72,7C,19,28,58,62,70,84,9C,DA,BC,DA,6F,4F,BF,1B,38,91,E4,22,F3,76,77,DD,74,D2,DD,A0,5F,64,7B,59,EE,63,24,D9,CA,83,8D,E6,1C,5A,4A,83,94,3F,3E,C9,3C,2B,F0,4E,98,89,28,48,6C,B7,95,F9,61,0B,66,20,2F,9A,E1,F8,04,42,B6,BD,79,33,D3,3C,19,06,1C,5B,FD,A3,CC,DB,4D,49,61,3D,18,AB,AA,9A,B7,9A,3B,01,95,78,87,96,CB,50,02,31,E9,3E,04,5E,D6,E7,08,60,9A,8F,01,A9,14,8E,3B,93,83,5B,ED,60,A4,E3,63,54,44,63,B8,FE,01,6D,CE,F8,A5,A3,12,86,4B,25,5F,81,15,1D,B2,70,39,07,7F,0D,21,7F,07,EF,16,F4,8D,4D,D3,B3,FB,72,26,7F,C1,74,60,96,EC,0F,8A,B2,40,F2,0F,38,12,E2,DB,5E,B9,E1,41,64,06,2F,F0,0C,D5,E1,A4,DD,B7,CA,AF,51,53,3C,95,22,C9,4B,4B,90,50,3D,91,F9,FC,E0,00,22,06,C0,CE,C5,47,81,D5,81,27,FE,CB,0D,D9,F1,FC,85,53,44,31,B6,77,F1,40,57,59,35,5F,E3,D5,19,D9,DC,F9,5A,D5,C6,65,C3,71,0D,12,26,E9,16,20,54,09,25,97,41,3E,48,8B,99,86,DB,F8,31,EE,46,C1,14,9B,09,24,4F,AC,06,A1,FE,2A,67,B7,58,C0,A4,D1,AD,77,CC,EA,F8,3B,19,31,67,FC,80,B3,FE,03,FF,20,52,5B,D9,FE,31,0C,8A,C5,FE,9E,CE,78,4B,A2,2D,81,15,48,4F,03,70,05,CD,CA,5B,C9,C3,F7,7D,58,12,88,89,BE,9D,FF,1F,68,07,1D,D2,6D,7D,2B,FA,44,01,A8,D0,1B,A7,DD,28,D1,26,81,33,64,4C,65,C5,6A,D0,19,E8,29,4B,EE,83,BA,4B,BE,F9,03,F4,8B,D0,73,29,4D,35,07,63,BB,E0,E1,E9,EF,A7,29,C5,56,BE,2E,E0,3B,DD,7D,F8,36,FB,C4,EE,82,81,87,87,B8,4D,8A,E2,87,4D,BF,48,08,EA,2F,24,52,87,D1,5A,14,34,E7,17,13,AB,D4,D0,2F,FC,19,D9,0A,8D,E8,3B,88,19,B2,A3,B5,DF,F3,22,63,1F,40,30,C9,6D,28,11,5E,83,C2,3B,C9,B3,56,BB,C4,46,DE,50,09,E3,6E,4A,D6,2C,F5,EC,5D,CC,3C,CE,01,40,EC,6C,D7,0A,36,E2,69,B6,3D,CB,22,50,E4,D1,5E,4B,0C,23,5F,3C,86,6B,13,D9,46,48,BA,6F,89,E8,53,06,9B,3B,5E,15,DE,F4,5B,8E,A2,7D,0D,7A,72,94,8F,82,46,F6,FF,05,68,F4,FC,A8,F2,5B,DC,55,FF,B8,5D,F4,73,3F,EA,88,E4,5B,40,73,D0,E0,3D,E6,1E,DE,78,42,A0,B7,87,AC,F6,0E,9D,2E,05,F1,88,F8,AB,58,8C,70,0E,85,EE,7D,3F,11,BA,07,DA,4C,6B,DD,61,94,5D,6D,2F,D9,91,8B,71,3A,C8,3B,BD,E8,34,CA,E2,42,5A,6D,87,42,8B,18,4A,DD,40,62,E6,24,45,51,3A,F3,F2,0F,37,9E,8B,2F,38,FF,27,B5,F4,FA,D7,11,45,15,22,F9,14,81,E5,C3,7B,7F,17,E0,11,76,A1,73,6A,39,2E,33,C9,B8,BE,64,AA,C6,3E,59,5B,3A,68,AC,CD,30,26,0D,6C,65,9E,6B,9E,A5,E4,43,76,7D,0E,CF,1A,25,A3,54,92,ED,99,75,49,0B,B8,86,60,C2,95,38,BE,50,75,C5,1D,C4,4F,AA,7B,2F,46,05,73,AC,0C,0D,4F,7C,AC,2E,F8,10,67,C7,B1,1F,0B,BB,98,F9,C1,39,BB,3B,00,7D,F1,A0,13,9D,88,1A,F8,A2,0E,82,A2,B6,B5,2A,49,A2,3C,1C,8F,D9,A3,FB,8E,48,99,37,06,39,43,D2,77,FB,A6,C5,FC,80,46,7E,4B,F1,14,7E,3E,24,DB,C6,53,9D,2C,C8,79,69,82,CC,8F,BA,C1,BB,6E,36,28,84,32,08,BB,0E,1A,A1,CA,9F,E2,07,51,E4,13,2E,9F,0E,90,F1,43,11,29,69,C0,93,A9,7E,1C,58,E7,55,C1,E8,29,FB,99,2E,A9,A8,56,44,2B,37,8E,88,81,32,41,D4,DD,93,F8,EB,72,67,DE,E0,7D,8F,27,1A,AA,C9,EE,6B,03,1B,41,EC,3F,1F,59,81,B4,22,68,42,19,8C,A2,42,79,79,1D,1A,80,D6,77,B1,B7,59,DE,F1,9E,76,83,23,E8,64,C4,F0,33,E6,54,25,82,0B,1B,FF,A2,04,5B,B2,BF,74,0B,98,66,53,0F,F5,5B,68,C1,93,E4,22,26,04,A8,85,8C,78,B2,15,85,D8,45,D8,E3,C1,35,D6,75,1F,2D,EB,CE,6D,1F,2A,AB,12,46,61,D8,43,20,80,F2,EB,2D,CE,25,52,60,F2,30,FF,E6,22,6D,38,E2,7D,46,76,FB,FF,34,45,8C,67,35,A3,FA,39,55,26,D9,B4,DB,17,FB,1E,3D,3A,12,2B,C9,65,D5,61,4B,70,B5,8E,E6,4C,3A,83,87,69,82,0C,AC,A8,4A,2F,3E,D7,2D,3A,0B,EF,97,D6,5E,D5,B9,63,4F,F7,E3,90,93,9B,CD,C8,C6,73,39,B3,06,57,E7,E5,15,D3,2A,4C,97,BC,69,D1,DF,72,0B,3D,09,84,29,FF,99,E8,90,48,92,DA,85,24,0E,91,04,CB,D4,03,9F,69,CB,7A,8D,00,D6,48,32,19,79,C4,C4,83,DA,BB,0C,39,04,10,6C,C8,15,0E,59,EA,B4,8D,07,73,98,91,4C,75,F9,D0,4C,90,72,E4,D4,CE,B1,7A,F6,57,1D,2B,47,40,33,1F,C9,70,9C,0B,C2,23,55,D4,DA,21,7A,85,B3,55,A3,86,D5,FD,A4,8A,81,A6,92,12,28,CF,A1,98,65,7E,9C,6B,23,7F,6B,6C,04,4F,6F,23,03,03,A7,6D,0F,45,89,12,77,06,ED,BA,63,E1,E6,C5,D9,C5,1A,40,88,95,3B,EF,3E,F4,E3,7E,65,6D,D3,AB,CD,85,8D,9C,9F,67,EF,D5,99,3A,A8,59,22,02,05,AD,8A,91,06,C4,C1,92,03,74,9B,B2,F0,FC,58,05,E4,64,6C,BB,B8,7F,32,01,26,8F,B4,FE,E5,84,BE,17,D0,8F,0A,AC,7A,D2,AB,DA,F2,3C,95,09,3F,35,DB,C8,83,CD,DA,03,E5,33,BF,AD,EC,A8,20,92,F0,E7,22,B0,5D,D6,2C,17,80,9F,9F,B3,DF,56,D3,A2,24,32,C2,58,89,88,43,F3,0D,FC,4F,95,07,F2,35,34,FA,A8,4F,A1,F9,2E,5F,BC,89,91,1E,ED,D2,7B,75,1A,20,28,75,DA,B8,B9,70,BE,62,CC,0C,19,D9,15,E9,47,19,12,BB,66,DB,C4,42,91,81,6E,F9,7F,0C,92,56,DC,7B,97,D1,F1,F0,43,D5,18,C4,98,14,9F,B3,B4,F3,00,E1,06,88,EE,CE,7C,26,09,44,40,B3,F9,07,23,E6,82,CF,9A,00,46,B0,05,94,0C,AC,A4,F7,BE,E4,4A,EB,B1,72,FB,86,D8,9F,67,EB,10,BE,D5,E5,D7,8C,9F,DD,0E,D0,B0,AA,D6,2A,3F,D1,B9,9C,E1,BB,FF,AA,F3,22,46,D6,B7,89,C7,5D,BB,30,C4,51,06,54,F2,25,6A,3D,03,A9,81,FD,8E,66,5D,59,5E,C9,F0,3B,7F,2D,AE,1F,BA,58,D2,BE,B4,C8,B4,15,23,45,A9,00,CB,1D,C2,E7,11,F3,90,AC,A3,B0,AF,11,E6,31,45,53,3B,59,45,E9,AB,08,AC,B3,0C,4E,0B,50,A6,D0,79,8B,9B,0E,58,4C,8D,EB,4C,38,55,F9,51,4C,D9,59,D5,71,B2,1F,C7,75,80,46,A1,D6,28,0C,E5,A4,F8,21,0B,63,70,60,C8,98,BB,C0,CA,A6,52,EF,72,0B,81,43,DF,5C,C9,F3,57,6F,48,BA,65,7D,39,D5,82,F2,AC,3D,3A,A8,0A,11,EC,CA,4A,BC,0A,BB,72,1F,19,DE,63,A9,62,00,DC,09,85,FA,ED,BF,23,6C,EC,4A,75,B2,E9,91,66,45,18,9F,20,C5,D3,A6,D8,0B,CD,24,67,3D,C6,DB,C1,09,3F,4E,EC,E1,89,40,70,1D,CD,00,CD,6B,C6,99,0C,01,6D,25,FC,C2,09,3B,6F,55,67,3A,0D,FA,EA,D9,95,CA,F1,14,3F,60,74,D6,8B,8B,E5,CE,DB,7B,09,6D,20,EF,68,B2,86,2C,C1,9B,16,D4,88,40,62,D0,21,05,92,89,A3,DB,E4,C0,1E,95,19,83,7F,FA,C0,CD,DF,0A,9A,17,14,C4,59,5A,5A,77,D8,4C,6D,0D,4E,EE,4B,47,92,C8,4D,2E,3E,D3,7C,C4,63,20,B0,DF,49,C0,9D,1D,E5,E2,3D,26,33,64,0E,8C,97,FD,09,82,96,8C,36,7C,45,76,67,BB,F7,36,9C,3C,D8,22,FD,61,14,92,CE,9F,89,B6,EA,A3,CF,AD,EA,4A,00,40,E5,CB,83,59,15,51,54,64,51,0A,5C,83,4B,5D,05,80,38,D5,65,83,F8,52,C8,4D,91,DE,0D,E6,2A,FC,68,34,EB,65,57,44,6B,42,79,AB,C5,52,06,14,63,7E,2B,37,71,98,04,2B,A0,E9,A7,7A,D1,80,66,54,FA,D2,0D,1E,B4,63,24,F8,CD,C9,67,53,68,57,38,3E,4A,5F,06,52,87,7F,30,AC,97,70,92,67,FD,AC,8C,01,F9,46,30,85,38,F8,ED,10,6D,15,82,72,B0,BD,52,E3,15,33,05,16,4E,CA,17,62,A5,31,F8,0F,2B,8A,6D,09,17,AC,7D,02,B8,11,41,0E,B2,D6,74,6B,06,FE,B7,92,74,36,D1,D8,17,5D,D5,95,E5,E8,B4,C0,82,6E,4D,A2,81,D5,5E,60,98,0A,6B,8D,A3,F3,56,D2,8F,8D,CD,0E,DF,57,81,FD,48,A9,5B,44,96,47,7D,66,4A,7F,76,72,35,60,AB,15,27,E1,4D,17,E6,28,F9,36,FF,AE,DD,37,F9,8E,52,AD,9B,37,37,B9,32,C0,D6,BF,6A,C6,C6,C5,60,E9,83,4B,01,E4,D0,A5,B7,91,2B,58,D4,73,A2,CF,B9,83,B2,64,7C,A2,E2,C6,6B,3A,9F,F4,87,5F,53,10,E9,02,0C,CC,9F,8F,76,EC,60,A9,28,95,0D,0A,47,75,00,E4,04,77,4E,DA,82,9A,86,00,C1,A4,37,EA,82,C1,F6,26,70,46,9D,2E,3B,C4,0E,7F,FF,AF,3E,46,7F,A7,48,EE,8B,1A,22,F8,AC,A1,FF,61,B4,26,97,B9,08,BB,2A,7F,8B,3D,7D,2B,82,AE,5C,13,FA,48,7D,5C,14,CE,C9,4C,50,B1,14,F6,06,01,CE,FC,40,E4,5B,92,79,09,DA,57,5A,95,70,5D,A0,08,F8,B2,2A,30,C9,F2,CD,62,46,86,86,26,70,93,D0,DA,0D,A9,CE,53,B1,92,99,DC,B9,F6,27,C9,45,F1,8C,B2,22,79,29,A9,D6,9F,39,4F,44,82,E7,0B,6F,0B,B6,94,F1,AF,39,25,4C,95,00,E7,43,86,84,2F,CF,C4,2E,95,04,66,61,D7,52,CD,B1,40,1E,2A,EF,3F,37,C3,CB,5A,6A,0E,46,94,8B,38,85,2B,05,38,FC,85,F9,CA,25,CA,C9,32,04,E0,D8,FF,D6,A3,45,CB,41,25,B3,51,02,E0,09,68,FB,64,5B,1D,74,FE,97,B9,DB,19,2A,CA,71,6F,18,E2,AF,1D,20,EB,91,0B,78,B5,99,A2,0A,3A,09,5B,04,07,EC,77,CD,8B,E0,E2,9E,8E,33,1A,6F,0D,BF,D8,83,CA,90,5F,55,20,95,3C,12,DE,69,E7,7A,5B,1F,14,FA,AB,C9,EE,94,A4,B0,37,40,F5,E1,DE,AE,FA,E0,21,92,0F,7C,C9,A1,C0,94,D0,B2,00,63,42,D5,68,C1,14,DC,60,CD,D6,D1,51,63,B1,22,D9,97,0F,7B,D1,2D,BB,DE,A8,47,F1,EC,B6,9B,4F,5C,8F,3C,53,67,79,82,5C,6C,09,B9,E5,00,C0,48,18,84,C0,84,D6,75,6B,69,E3,D7,69,AD,47,31,60,9D,E2,52,E2,6E,02,19,B8,49,CB,FA,ED,22,DC,58,53,5D,31,A9,4B,47,1B,E8,4B,AC,8E,64,90,EA,59,DE,A8,5F,82,7D,42,F7,1B,10,1D,BC,C4,B3,90,C3,20,57,B1,3D,62,77,12,86,87,40,58,59,B7,D2,59,6B,0E,EC,CC,C7,DE,2D,12,C8,86,5F,84,E8,DB,86,76,5B,1D,6C,05,5D,91,58,2A,B8,E7,B5,3B,12,E9,B7,CB,B0,63,1F,E8,1F,7F,A3,55,11,76,65,52,D5,0D,0D,24,B6,53,8E,6C,F5,A5,BA,0E,79,62,F3,D2,AA,13,74,2D,72,7B,72,37,32,31,BE,2B,EF,36,CB,6F,1F,04,4C,4C,2B,B7,F3,1E,DF,3E,93,08,8E,D2,FE,BA,3B,66,72,79,32,9C,E1,8F,3F,C2,22,C9,96,DB,A4,19,65,C0,1E,0B,F7,05,A4,19,D8,4A,EB,4A,A8,00,E8,6B,CE,B5,BC,A7,D8,AD,BD,45,55,CE,A9,54,3A,50,93,40,7E,DF,F9,09,09,F4,49,CC,08,2E,89,52,26,42,0B,13,EA,42,DA,25,88,78,4E,D3,05,A9,6E,DE,3A,F7,BD,4E,19,92,74,BC,34,73,62,21,BD,1C,C2,45,BD,05,40,36,BF,03,E7,9B,51,CC,AB,E1,8E,CA,36,BF,F7,D7,86,CC,DB,CB,DE,D7,32,3B,88,4E,A6,E0,1E,1A,95,CD,B7,52,1E,A1,D0,28,EB,30,E5,08,7A,C0,F1,17,6C,EF,6F,43,D8,A6,AC,DD,24,EC,FE,E1,5E,BA,D0,B4,AD,F5,85,3C,D8,75,33,E7,9D,45,C5,9B,62,9C,3F,3D,0B,D8,7D,72,28,FB,7B,CD,EA,B5,73,E8,62,C3,AF,EF,31,B7,B2,A9,26,EA,80,7D,83,63,BD,B5,5D,DC,B6,FC,5A,6F,38,4B,11,C2,3D,3D,A1,D3,40,B8,D1,37,7E,11,0C,65,56,81,D9,DD,58,7A,6A,59,0E,90,00,CF,08,E6,93,C1,E9,91,0A,05,B5,95,CD,7F,6F,B9,6A,A8,0B,8B,42,29,A5,9E,86,F3,C6,2F,C9,EC,F3,91,02,00,75,38,98,12,22,59,6B,47,34,1E,CB,C1,16,D1,9D,2F,A7,64,02,4D,58,6E,85,FD,6A,70,F0,87,2D,7D,A4,04,1C,BA,87,93,AC,5A,3B,32,14,12,4A,21,6C,B4,35,66,FE,E3,3A,52,5F,79,D2,FE,6D,C0,61,E2,7C,7D,CA,DD,4B,3C,48,1B,61,55,B0,BA,EB,05,C6,AC,31,A1,00,DE,B5,3E,6E,6D,C2,89,C0,05,8F,EA,53,7B,27,22,44,2A,96,2D,E5,DB,39,86,9C,1E,CF,A4,82,69,1D,9D,5F,86,AD,D5,97,D1,E4,2C,04,46,BD,C6,E3,C2,89,FD,94,5A,8A,A3,7B,F1,29,A2,10,9B,39,EA,CC,98,84,FD,0F,0E,5F,5E,72,2F,00,28,6D,74,D3,B0,86,CA,AA,6A,C3,32,5F,FF,A5,1D,FD,7E,3C,81,C7,C7,51,E8,76,5F,2D,08,26,59,75,AE,08,6E,18,09,F2,0D,BB,2C,A4,A6,E7,CE,48,3A,58,39,CD,43,F1,24,2E,56,31,89,33,6D,C9,7E,19,6E,C0,41,CF,EA,1C,96,6D,2C,4D,33,E5,FB,26,2F,8C,E7,8A,D0,C3,A0,2B,6C,DD,91,DF,69,A1,98,C9,6A,79,07,94,17,2F,0D,1A,57,90,62,7C,C9,5A,61,BE,82,40,68,94,BE,58,4F,75,89,FB,DD,B0,E9,F0,7A,C4,57,4B,2B,68,9C,0E,DA,E8,CA,D1,D9,6A,18,11,8C,D8,0E,24,C8,2F,FD,63,62,2E,19,06,BF,F9,C0,7A,8B,29,63,18,81,B9,7F,6F,BA,17,E5,50,55,60,D8,6B,9F,88,C8,2F,91,42,F4,44,C6,BF,FC,E0,C2,50,B4,FD,F9,58,0D,96,63,20,D2,37,98,93,28,6E,42,06,62,F9,58,8E,9D,8A,1A,03,3F,A6,69,AE,D8,A1,EA,65,9E,90,C3,DB,DC,F6,BD,B5,93,2C,01,78,AF,10,D8,98,2D,EE,0C,C0,A9,7C,3E,C9,81,A3,45,A2,26,CC,B6,92,08,6F,2A,82,B1,D4,81,09,93,25,16,AF,AC,40,41,55,B4,46,0E,FB,D2,FF,15,51,48,B0,96,70,76,EA,B9,00,6C,8C,A6,D2,65,0C,46,2E,E8,40,34,40,D2,06,33,C8,0E,82,F2,0C,6D,12,2A,E4,91,56,10,3C,3C,B4,46,1E,CC,97,2F,0D,B0,4B,32,84,3E,A2,B0,A2,34,16,5D,CA,B7,BA,9C,8B,1C,3D,C3,FD,1E,73,31,C6,29,F5,E3,D3,C9,6F,38,7E,6D,FC,01,0F,2E,01,C2,A3,8A,AD,D7,75,A0,22,53,C9,DD,02,E7,A0,50,28,72,7A,A8,6D,1D,86,A2,1A,F1,41,8B,75,9A,CF,45,64,63,5F,44,2F,69,99,6E,5C,26,40,B2,7F,D2,BA,26,A9,FB,59,9E,CE,E8,0D,6F,0B,B9,5A,4C,7F,C1,25,77,24,68,09,12,37,7F,9B,8F,20,BE,FE,19,2E,7C,BE,0E,17,58,B2,AC,7B,B8,5D,7C,E0,AF,D6,1C,ED,B5,AE,9E,D3,F5,1A,A6,FA,52,E9,2F,F4,FC,2B,4B,4D,C8,A8,F1,F2,A6,D8,BB,47,2D,32,0C,26,43,AF,BB,A7,0E,F0,5E,92,E4,4E,37,58,33,9E,36,BD,E0,99,BA,32,9C,ED,A7,B5,58,9E,6C,F5,86,7F,77,80,DC,ED,CB,05,78,1F,3D,C1,70,75,F9,32,5D,30,F1,09,26,2B,C5,EE,27,15,D4,AC,EB,CF,22,A7,D0,BD,35,9F,E9,D2,1D,38,D2,BF,49,F9,44,88,56,2B,3C,D4,26,8B,AD,96,B6,23,7A,75,1E,79,BC,0C,F7,00,E1,E0,CC,56,A5,38,F8,D8,A6,93,C8,4A,0C,1E,D5,58,2C,16,C5,71,45,C0,98,CF,7D,37,0D,3B,14,DF,28,E1,8D,68,3F,46,1B,D5,87,FD,9B,CE,56,1F,A8,6F,58,F3,6B,BE,96,8F,2C,CE,25,15,82,BB,EB,75,0F,3A,AE,53,D4,4F,D1,A1,2A,D0,3B,19,D3,D4,F9,8C,F8,B3,A9,DE,C2,14,15,C1,D9,01,CF,9D,07,AA,86,22,23,82,1D,C3,6B,C2,F1,8D,13,89,29,3B,B6,BE,7A,5C,C3,AF,81,E6,35,1F,71,B6,AB,A8,34,9E,08,DB,5C,AF,D5,CD,B9,67,38,16,A8,BF,BE,03,D5,8B,F6,DD,55,69,E4,FE,03,99,BB,C0,50,D1,39,B7,CF,2C,92,35,5E,43,98,C3,DB,96,C0,7F,21,D8,C6,04,B4,D0,D2,55,10,97,6F,1A,17,EB,0A,47,DE,60,A3,52,5D,83,72,DC,B5,82,26,6E,3C,F5,10,0E,21,4D,7D,40,22,91,1C,EB,D3,0A,CA,ED,BE,D9,D2,47,4C,C6,1E,40,55,34,FB,C2,33,01,7A,5D,3A,07,C7,9A,C5,CF,89,91,67,0B,EE,A2,D0,D6,B3,7C,81,BB,9A,70,33,CE,7F,1F,B8,21,62,5C,20,79,43,37,2F,F1,5F,81,08,3F,36,6C,BD,AF,52,B3,4D,F9,61,B2,89,94,CA,3A,90,DD,0D,3C,7D,DF,D6,7F,92,C9,31,CC,81,6C,F9,BE,7D,B9,54,B6,D3,D2,D7,C1,54,07,C1,AE,B8,D0,56,4B,70,55,A4,7E,72,8D,37,A6,F2,F2,B2,3F,19,3D,97,BA,E9,79,B9,60,93,F0,69,DA,6C,85,87,49,AF,CC,F7,C8,59,F2,FC,66,3A,2B,AA,22,BF,01,00,D8,C7,8D,0C,D9,7F,31,62,76,BC,C9,25,F7,00,ED,D7,6E,39,73,06,E6,3A,D5,A0,51,84,D4,D3,7C,6E,F9,9D,DF,8D,84,74,5B,B1,B1,F8,34,C0,1F,91,FD,77,E5,2E,8D,F8,97,38,D4,3A,51,47,22,63,98,7E,6E,DD,E7,8A,C3,C7,7A,81,91,DB,B5,0F,93,48,E2,58,38,C3,9E,4A,11,0B,6A,37,9E,D9,79,EA,D9,D4,62,AC,88,97,3E,CB,3A,CB,75,02,14,4E,48,7B,D5,F2,F5,1D,E1,C7,33,6B,86,C8,E8,DF,00,F9,F4,42,39,A0,6D,DF,A0,70,8F,38,1F,86,7D,FA,79,7B,2F,6D,B3,5C,83,6A,91,2D,75,8E,61,49,02,D2,D3,27,4A,DA,F2,B9,72,0A,CF,EC,A4,BC,AC,85,FE,B5,41,8A,83,AE,D8,88,A2,C7,1D,E1,FF,29,B7,A2,9D,DA,DF,81,84,6C,6E,CB,26,DD,DE,AD,B9,7B,1B,68,68,90,1B,BA,EE,18,96,7F,C8,99,C6,6F,D2,74,62,96,14,07,19,E3,DC,78,74,73,44,6A,06,32,4F,33,A4,28,8B,C1,55,53,6A,0A,30,75,21,29,9F,3E,3B,70,11,14,45,0C,5D,DE,DE,45,B4,07,FA,63,79,11,4F,E1,B7,FB,33,F5,8E,A5,75,10,C3,2C,0B,8B,44,1C,92,C3,8D,64,DB,66,FD,F9,4F,77,EE,62,20,06,B7,42,22,B4,2A,66,22,2D,99,8C,8A,51,D2,2C,04,62,37,05,5C,73,B6,94,D6,FD,4D,8C,74,51,EE,B2,63,79,BD,BD,BE,40,F7,7A,33,04,5F,85,11,F5,9E,E9,D5,1E,25,F9,82,17,AC,2F,40,3A,EF,54,D2,82,B0,85,CE,73,B5,B2,8B,4E,B8,D6,F0,5C,83,2C,F2,48,84,09,54,DC,C7,84,3D,40,90,A5,65,19,1B,79,F0,09,7C,ED,EA,60,C3,13,3B,AD,20,2E,B7,8D,EE,AB,93,4E,EF,28,52,75,7C,AC,A9,5D,59,1E,E0,92,33,BE,23,17,36,53,67,23,E5,9A,51,04,6D,B3,37,60,48,D9,E3,71,38,75,11,03,6B,2A,7F,1B,B6,87,38,93,EE,C4,53,B1,89,D6,EC,09,09,A9,3F,50,21,7D,85,5D,5F,83,BB,06,99,3D,75,D5,1A,06,84,3F,62,4F,B6,1B,52,69,62,B6,EC,F6,A6,0D,9D,4D,0F,B6,D7,26,09,EE,E2,47,03,28,0A,EA,9D,6B,F1,36,C8,D2,C0,A4,8C,1F,A0,62,9C,78,EA,F9,8D,53,C5,C8,C6,20,35,A5,FD,FB,28,E0,E3,BA,F3,00,12,33,07,D3,30,71,E1,FD,D9,D5,3A,F0,41,60,8E,90,90,80,D4,CA,BA,52,2C,EB,F2,BC,6E,CD,A0,19,8F,BB,88,5A,BB,80,E4,CA,FC,63,61,32,2D,3F,D2,48,E0,22,24,45,63,E9,6D,D5,01,AB,71,0C,08,36,30,5F,C1,B7,7C,D2,37,84,61,59,24,73,7E,6E,5F,1A,83,45,4F,F5,AC,58,08,B0,D6,FA,8B,A5,2C,8A,C9,0D,0A,78,CE,12,01,62,9C,20,8A,22,73,3E,39,29,EF,28,F2,77,2B,E2,FE,ED,F1,CE,69,2A,A5,43,0B,70,0E,3C,F7,B0,62,E4,26,AE,4D,EA,97,41,D9,F7,23,F1,87,17,43,A5,F7,B1,7C,17,79,46,87,FF,79,A6,B6,66,A9,4B,D5,C1,3A,D5,01,25,19,B7,20,8E,6F,FE,0E,3F,F7,8F,53,B6,F6,1B,AB,08,E0,29,17,C0,7F,A5,F8,34,98,C7,3C,EF,69,41,C9,1C,B5,C6,2A,27,BE,96,79,92,1A,BD,CB,0A,8E,69,76,BB,82,A8,92,BB,A9,3B,CA,78,05,11,EA,A4,50,3F,97,ED,E1,88,30,BA,C5,70,03,86,C5,18,CC,EB,4E,41,78,E7,6D,0C,EA,29,B7,28,6C,10,69,85,BD,76,89,B4,14,C3,37,5B,24,6F,7B,01,85,29,35,F6,99,DB,19,22,5C,8A,43,A2,D2,68,01,6C,A4,C5,3D,32,01,02,25,3F,50,97,58,0E,E0,AE,0F,39,A7,BC,BB,B6,29,FE,D6,EF,C5,81,AA,01,70,9B,3B,02,DF,C3,96,F1,50,39,D3,89,F4,38,45,F8,C5,8E,81,58,E8,81,C1,EE,C8,29,86,1C,B1,AB,DF,61,20,84,6C,D6,8A,A8,61,18,94,32,60,5E,E8,2A,A7,53,E9,C9,14,49,30,60,1C,21,B8,48,E6,59,3B,91,15,92,3A,C0,90,02,42,E7,7C,B6,0D,99,FF,E7,C3,95,6D,D4,50,9A,80,AD,2D,94,DA,7E,5F,53,FB,7B,C5,3A,A3,25,C1,99,BA,F3,1E,7A,0B,41,D9,78,F6,D6,1E,23,A1,EA,28,CF,91,B6,8A,1E,9F,5C,19,0A,A6,D4,07,CB,13,3F,DA,F1,B2,3B,8F,60,84,AA,AB,B8,C8,5A,C4,96,B3,A5,7C,7F,DF,E7,5C,75,D6,61,A6,74,02,38,5C,64,7D,28,55,05,90,05,70,EC,23,FB,F2,7C,DC,44,EE,19,14,6A,C6,C2,61,95,AD,21,12,FC,F7,DB,D4,F6,D2,6E,D5,04,3F,74,5E,FC,42,97,20,A6,BA,DE,2F,FB,2C,92,75,CD,31,2D,95,F9,13,EA,C2,FE,44,1C,A5,C5,54,57,17,21,8B,25,C4,33,F7,61,15,F0,C9,BE,72,EA,43,95,44,D7,CE,3C,BF,CF,30,E4,DF,37,35,CF,65,9C,1B,DF,41,91,7F,16,1F,5B,3C,F6,7F,71,AD,12,C3,75,26,15,F8,55,7C,99,60,36,8B,EE,67,CD,27,0C,23,F0,AE,62,C6,19,95,27,20,A2,E6,A5,35,C3,14,99,D9,89,9B,75,B4,69,CE,75,1A,BD,A9,5B,E6,5F,75,DC,B4,74,72,3D,D4,FC,9D,5C,BD,2E,41,FE,9C,B8,BF,12,83,10,F2,98,87,FA,C6,73,D4,22,4B,CB,86,FF,22,FA,77,FA,A0,97,3D,F1,8A,FD,1A,0D,9A,67,77,49,75,94,E2,F1,6C,B1,E6,85,C1,CF,56,05,F2,C9,02,6E,78,99,04,E7,F9,DB,08,19,90,A9,EB,8E,02,B2,47,B3,E0,15,46,6D,16,B8,FE,FC,21,44,32,97,4E,57,B2,9D,69,C0,AD,53,8C,66,A5,89,ED,BC,DA,9E,DC,0F,56,AF,D1,B2,45,B4,FA,DC,8D,F1,61,1A,D4,2E,FF,AA,8C,C6,D4,85,32,95,D1,4E,DF,D1,09,13,60,C4,04,6C,90,02,A1,A2,74,F2,78,8E,19,59,80,1B,83,D5,F3,4B,5E,83,5D,ED,18,22,45,D7,7C,13,FC,00,E0,F3,6E,85,1B,E5,FA,88,19,19,58,EC,88,4B,B1,50,C2,79,42,1C,B3,6C,A6,20,DF,A6,5D,77,2D,9F,B9,F0,DD,A9,D8,57,22,C0,C6,82,5A,C9,3B,49,BD,71,CC,0F,B2,05,1B,3B,C7,DD,31,3F,3A,49,5A,27,72,A1,D9,E7,D5,E9,11,D7,45,DC,B4,01,FE,DC,EB,02,8C,12,09,C8,CE,F8,1E,44,1C,7B,5B,C7,A4,A4,40,B5,AF,FB,DF,A0,60,F1,19,B6,3C,9D,0E,CF,88,95,37,D3,D3,BC,28,7C,35,E5,77,6F,41,4E,30,15,0B,D9,A9,86,58,A8,A1,B3,66,8D,9B,16,10,91,F8,E2,00,34,56,16,89,CD,0E,0A,7C,56,34,E7,D4,AE,09,75,D0,A1,83,06,83,AF,3F,05,88,14,A0,E5,4D,B3,1A,81,38,62,EC,98,0A,E4,D0,22,0E,44,23,2A,49,4B,7F,70,4A,C3,CA,1C,BB,7B,90,67,A2,C4,30,75,02,34,40,6F,3C,77,32,AF,6F,B1,6D,B1,B4,BD,9C,6C,11,91,56,A0,60,27,F3,1E,F8,7C,2E,08,74,6B,55,D5,E8,8A,46,D4,D6,43,36,DE,01,0A,71,3D,F0,4C,CB,19,37,73,DC,AE,04,45,3B,63,08,0C,11,70,D6,97,5A,75,C0,C4,65,DE,0D,FD,B3,5A,29,CB,B7,33,84,DA,60,3A,20,DE,75,A7,23,36,3F,5A,0E,65,11,8C,9B,FA,FA,E4,92,D6,D2,A5,5F,51,AF,52,30,2F,85,3C,B5,4F,D4,7D,70,C2,A0,5F,82,BE,BE,47,50,BD,6E,4B,5C,EA,08,B9,BD,92,C1,D4,1A,FD,4F,13,3C,BD,9F,DA,34,A5,93,CF,8A,31,09,C8,BC,AA,0B,83,79,91,F2,E7,19,A5,C3,96,F8,9A,EB,9D,25,41,0C,D9,07,97,B4,CB,FB,88,B9,55,97,D3,84,94,5E,FA,01,32,5B,4D,24,61,0B,46,73,48,84,B0,BA,97,56,90,4C,91,81,AB,F7,4D,C4,A9,85,A1,9D,EE,05,41,0A,2E,BF,E4,E5,BF,F6,26,97,C3,3A,49,EB,F3,5A,8D,A8,89,98,0E,3B,7E,DC,44,08,A7,ED,1E,88,68,12,E3,AB,3D,CE,3C,A6,6B,B8,6A,12,23,D4,0C,04,DC,55,5A,DA,C5,E7,6E,19,C5,0C,FC,EC,7E,6C,EE,20,F3,BC,36,2B,F5,C8,EA,71,85,60,F5,BE,64,CE,E4,EC,91,B4,32,A9,DF,38,4A,D7,8C,31,CB,F8,79,9A,A9,B1,6E,73,E8,01,16,F6,EB,59,08,86,61,C4,93,39,2F,AD,6C,48,EC,4E,97,5E,2B,7B,E2,7D,30,35,4C,3C,AB,15,91,DE,12,5B,86,A9,B0,48,12,7E,68,2E,F3,6A,DF,07,1A,DD,31,C2,39,08,7A,08,DE,7D,2C,5D,01,45,35,34,8D,C2,5D,AD,BE,AF,48,8F,C2,91,7F,37,4F,CD,A2,18,98,A9,B6,94,CF,DA,C0,CF,76,53,08,96,B3,CB,03,A0,5F,B1,D6,DB,14,92,A0,48,E0,A7,34,5B,74,4D,74,A2,13,3A,51,29,88,4B,05,17,6E,53,8E,07,2F,1E,2A,7D,00,FF,48,FB,61,AA,30,B9,6C,68,AA,B3,92,14,6A,97,1D,AE,64,A2,CD,40,B2,DF,38,B6,D5,A6,46,F2,54,E3,EE,F9,37,00,A4,E2,43,A6,EA,23,1A,A5,17,FB,A1,C2,F1,FC,B2,34,1E,FC,E5,B3,A1,0B,A4,06,FE,D0,22,6E,EE,A9,ED,C3,F2,B9,3A,11,3C,05,E4,7E,4D,81,E8,73,45,99,2A,60,35,09,2D,94,91,EC,77,3A,A1,4F,C7,E1,26,FE,6C,27,24,3C,35,6F,C4,16,90,E6,99,8F,E5,29,06,02,9D,FE,8C,E2,A1,2B,EA,16,05,98,52,B6,F7,90,F3,7E,EF,EE,FB,10,29,86,15,F8,1B,CF,C2,D1,11,12,F5,81,86,26,E7,B8,76,CF,6E,0C,53,2C,9D,FE,F3,67,95,D0,FC,4F,4D,D2,E3,57,47,6B,5A,F5,54,D9,C9,60,1E,D8,41,E6,50,FE,DB,96,B9,80,08,C6,91,C0,90,F7,CD,8B,46,FF,49,13,34,DF,99,BD,7E,43,07,B6,1D,08,1B,3C,07,0E,A3,29,EC,9A,D2,CC,28,38,19,04,79,A8,CC,7E,E3,C7,CB,8A,E6,9E,69,C4,44,A7,F2,57,DA,2E,03,9E,42,34,A6,84,AF,DE,D4,43,BD,72,91,30,83,A0,A4,9B,08,1C,94,16,25,08,7F,62,92,96,2F,C1,B6,21,28,8E,ED,49,3F,AC,A6,A5,9C,61,CD,CD,E7,59,4F,C0,D6,FA,1E,6A,6A,23,29,D9,32,B2,B8,91,86,19,C2,F2,9C,48,61,F5,67,49,15,D9,EB,93,1D,DB,15,34,2E,26,38,FF,16,CA,16,FC,6D,D1,96,0E,A9,2A,6D,45,B3,9E,6E,8E,86,00,D9,C5,E7,56,C5,8D,FA,1F,EF,A6,8F,0F,9E,9B,2A,9E,14,A1,91,D3,15,A6,70,FB,2A,03,B1,B7,38,EC,05,B9,BC,AB,15,26,D4,EB,E6,14,29,24,D6,9A,58,8F,E2,20,2F,1F,77,B7,69,93,36,C6,21,0C,7B,6E,1D,64,0D,64,B2,94,F6,E0,35,CB,49,59,20,28,7D,1E,89,AC,2C,1A,FD,81,D7,5F,E2,1E,EF,74,8C,50,19,48,70,5D,25,B6,3B,76,43,D5,7B,C5,23,CF,86,FC,AD,83,0C,13,CE,74,34,0E,5B,4E,30,AE,AE,0E,89,69,A8,A5,C6,0B,AA,FA,86,F6,AC,3E,22,CC,20,86,11,45,37,57,0A,54,D9,70,A6,2E,F1,C4,CD,0B,EE,E1,82,3A,B4,2B,AD,5B,37,8D,08,97,DC,55,96,F6,3B,C3,99,C2,DB,3B,4E,FB,80,56,67,F4,F0,C6,1A,2C,D5,AD,90,25,20,E9,07,31,D8,2D,04,37,99,97,79,74,57,B1,42,DE,1D,89,F0,E4,AC,08,A7,11,EB,7C,6E,BC,3C,0C,DD,09,46,E9,A4,87,07,98,AF,84,23,C9,ED,A7,C0,1A,15,8C,6E,69,A6,AB,94,3C,75,F4,56,73,9E,31,F0,D3,CA,54,D8,56,0B,CB,DA,DF,C6,9F,6C,7F,45,AD,85,CA,9D,73,E2,24,63,58,6F,54,01,59,E3,58,8D,EC,73,18,81,42,9D,02,51,F5,8A,2C,8D,31,F8,7F,63,22,5F,5A,DC,F2,BD,53,84,74,D7,32,1B,5F,98,EB,DB,77,53,1F,88,46,10,DF,D5,67,94,59,44,CB,1C,F5,BA,26,F2,6A,8D,02,54,89,76,AC,65,D2,33,FF,21,4A,B6,37,F5,E2,3D,E4,D4,69,DD,5D,B9,3C,E2,E9,C6,16,73,77,31,DC,B8,53,89,D5,2A,F6,91,5D,29,DF,59,E8,BE,E6,EA,3C,C9,52,E0,7E,58,A6,77,7E,8C,CE,9C,13,55,5F,CD,07,36,05,F1,EF,8E,AE,25,D0,11,C5,20,81,0D,7B,BE,7B,55,E6,9C,CD,F1,7B,75,39,40,9A,31,51,95,C9,3A,4B,79,57,78,C3,B1,BF,90,2E,21,DC,03,EE,C2,D8,3D,0A,34,71,7A,5C,3D,5F,8B,F4,56,FD,88,62,E3,03,46,A1,27,04,5C,E5,21,2F,C4,BD,10,94,CA,13,01,F7,99,B6,DB,84,C3,0D,3E,AE,7E,26,F3,EA,C3,E9,69,66,BD,EC,18,92,90,5D,8E,8D,50,2B,DE,F9,7F,81,FA,D9,8A,E2,73,A4,58,69,A0,74,A1,6F,BA,D0,71,C7,20,84,F0,43,1C,C8,4D,09,87,E9,E4,93,E8,7F,9F,89,EB,D4,A3,FC,C6,57,88,A8,99,C3,33,D3,2D,DD,3E,44,A1,69,DD,BD,6B,2D,C2,44,24,AD,3C,8B,74,41,4E,36,C0,04,A5,3A,76,E1,94,12,68,86,A0,2D,DF,96,8E,90,79,D6,09,D8,43,EF,9B,94,50,1A,EA,19,CB,EB,9F,88,AD,DC,2A,33,26,B5,92,94,E1,3F,43,91,7B,FD,DC,3E,19,D9,6D,93,BA,04,A9,FF,D1,BC,6F,BE,E0,34,FF,34,6B,2A,CA,37,9D,82,CF,B3,98,50,C4,33,19,67,51,2E,07,2C,CA,6B,80,08,D2,04,DC,3B,B7,AD,50,33,BA,8B,19,33,FA,80,26,53,AB,0A,10,AF,C9,82,E2,F7,30,26,31,4A,59,EA,D5,BA,31,0A,A5,26,15,E5,FC,D3,23,D8,13,E8,EA,33,DB,FC,29,15,79,ED,3E,A7,EE,12,53,CF,CB,96,CB,F7,3D,51,11,17,03,24,44,F5,63,74,94,1B,2A,19,A3,EE,BA,1A,70,75,57,26,6B,D6,84,66,7F,21,F3,0B,38,53,9B,3F,25,EF,93,C7,A0,C7,C7,70,E5,2B,B4,DB,7B,8E,50,74,4E,7A,C8,BE,1C,AB,6C,F8,89,D2,35,FC,CB,7D,EE,9E,8E,B7,E0,3B,28,30,A3,E9,CC,43,E2,F5,EF,A7,F9,D4,0D,64,41,AB,2A,3F,70,DA,DF,D9,A4,3F,F5,60,90,1D,62,2F,E0,3D,9F,20,EA,0F,C2,21,10,FB,FF,11,AC,A6,34,AA,5E,76,F5,BA,37,A0,0F,7A,06,8F,69,A2,05,75,B1,46,02,6A,AB,D3,9F,CB,FD,5D,0D,DD,E7,70,7F,A0,F9,73,66,A4,3D,D0,F4,CE,4D,F8,9A,E7,7F,CC,63,9C,8E,73,62,48,0C,9C,36,AD,13,CD,BE,83,0E,46,DC,FC,3A,FA,3B,20,D4,CA,EF,09,71,D4,36,B6,3D,17,FD,F9,F1,E7,61,0E,F5,B5,30,EB,35,10,24,36,42,AF,4F,D5,B7,D9,A4,E5,28,18,66,78,55,D8,6D,13,09,B5,16,39,62,18,58,14,D4,3B,92,D3,F3,EB,E9,D9,D7,95,72,51,44,59,B3,19,D2,C1,EC,50,25,5A,50,FA,71,68,CC,08,09,8E,15,7D,21,E9,99,BC,4E,99,AB,2E,27,F5,D6,DA,B2,18,78,C4,B1,B1,BB,6E,29,47,FE,03,28,DE,54,F2,D6,34,62,9D,58,FD,3E,A5,CC,CE,C6,F9,E2,22,37,FA,02,E5,E8,4D,21,FE,17,B8,3D,15,81,D5,5F,1F,79,2A,E9,18,24,68,5E,31,3E,1B,46,A6,21,14,0D,F4,01,4B,4C,7F,B3,C6,28,C4,3E,9D,A7,B9,E0,43,B1,34,97,2F,22,0C,DE,DC,13,56,88,ED,87,41,16,66,7F,8E,72,38,08,97,FC,EF,A9,C8,49,C1,96,24,13,98,3A,B0,8E,FB,70,58,B1,FB,47,73,17,B6,9A,46,86,A4,C9,31,DA,74,DE,64,AD,09,6F,78,89,A7,A4,E1,79,D0,86,34,81,D5,4F,76,CB,AE,89,15,B6,3E,11,0E,CB,29,39,DD,7A,2D,48,A1,BB,A1,A4,6D,E0,48,68,50,F6,1E,27,1F,E2,B2,73,32,A8,F6,B6,D1,3E,33,7B,02,28,07,48,F4,7B,59,1D,60,51,AA,89,B7,5B,B5,E1,31,70,7E,A1,11,87,F1,56,89,59,EA,D2,49,3D,0B,41,4B,24,65,67,AF,60,6D,72,A5,12,F8,91,8A,1C,7D,BF,F8,15,3A,CA,C3,FB,E1,99,2A,D1,B7,F6,70,64,B7,88,B4,DD,CF,84,1A,A6,A3,2B,B0,1A,84,F4,8B,B7,2F,78,82,1D,71,12,07,7E,3E,07,DE,21,71,DA,B3,AD,A6,25,B8,BA,B8,07,3C,42,D3,BE,3A,A6,6D,47,FF,4C,FA,85,7E,47,DC,FB,A3,78,CC,6E,8C,18,20,61,86,F6,E0,AE,AD,FE,92,55,CB,33,2A,CB,E4,7C,B1,26,AD,3A,57,F5,92,34,5A,C9,53,A7,48,3E,25,77,1C,9D,82,A3,E5,34,A1,97,9D,33,8A,3D,A3,CB,0C,1A,6D,39,62,5F,96,D5,B9,40,4E,94,80,8D,84,1C,D9,EC,E5,5E,9E,A5,15,13,3F,5E,54,78,DD,AF,90,14,43,A0,76,22,23,F9,4D,90,98,9A,80,E4,5F,D9,8B,D5,BF,CE,4E,EF,48,9B,38,09,BF,14,E0,DD,C8,72,0E,BB,23,C8,DF,97,7A,2A,07,6F,EC,52,19,6D,FF,DD,DC,EC,B6,A1,98,1E,D3,4E,29,6A,CA,44,D7,23,B9,CD,16,DE,D6,EC,4F,87,31,6D,F0,40,05,13,9A,B4,82,7D,E9,A9,B5,3F,85,F4,57,E5,DB,BF,E3,E8,5C,5B,AE,DA,9E,7E,02,6A,E0,2D,CB,F2,86,B1,0E,84,67,EE,FF,05,1F,C7,5B,69,31,DB,9C,EE,AF,A8,47,DF,30,BC,DB,C3,9E,E9,E1,80,83,74,9F,CD,FC,BF,FA,E9,F9,3F,E2,8E,87,F0,A2,C6,67,0A,7C,AF,CE,FC,26,13,95,22,44,E1,0C,25,A7,5A,DB,36,46,44,0E,B3,1D,3F,2D,3E,30,7A,4D,26,C2,0D,48,3D,58,C7,F4,37,B0,6C,6D,84,C6,49,D9,C8,F6,DE,03,84,C2,B3,B4,45,22,9C,C6,ED,29,A1,74,7D,67,8C,25,A1,D9,46,0D,EC,56,17,02,31,38,C5,29,2C,63,98,DE,11,7A,65,32,FB,33,C9,78,D2,46,1C,32,54,38,75,BF,2C,62,53,96,5B,01,94,4A,B7,FD,7F,F7,B2,A0,DF,81,91,8C,F9,69,EF,2D,1A,48,7D,9E,5F,AA,E6,F4,E3,98,49,52,4D,43,39,EE,F3,1C,D4,0E,D1,1F,80,88,39,D0,3A,B9,79,8A,54,4E,23,28,91,20,3F,CC,24,23,3F,B5,21,E6,1D,0F,85,4F,9C,A5,A6,05,0A,6D,99,DA,A5,81,3D,2B,2C,64,AE,68,35,7F,90,0F,D6,41,F3,65,9D,8D,A0,57,CE,E0,8E,B2,80,3D,B9,37,DB,1E,C2,50,EA,B6,D9,D1,0C,67,46,F7,F9,1A,6A,C6,34,06,39,92,6D,6D,77,FA,64,7F,0D,5E,CB,83,85,71,9E,B0,1F,3B,B7,D9,0C,7A,54,68,45,25,C6,CA,A6,8B,A1,9A,52,F8,36,65,D2,74,84,CE,7E,6D,A5,94,97,12,E2,A5,3B,E0,41,C6,DC,10,39,13,99,4C,66,35,5C,25,B0,F5,FF,DD,02,DD,A6,D3,AA,DA,D1,A2,2B,4E,8B,20,FB,E1,4F,1D,F9,FD,A0,1E,94,B6,91,8A,D7,B4,24,1D,04,BF,D7,F1,EA,9F,30,BB,5D,4F,BD,3B,93,03,73,AD,87,2F,F3,83,DC,A9,39,66,82,56,86,3E,9B,D9,3B,C3,45,F7,BE,E4,E3,DB,A5,22,D0,7C,21,F3,6A,6D,89,6D,9A,58,6F,E8,E2,F6,53,35,02,25,72,EC,77,AD,01,B3,49,CF,FA,9F,E4,15,FC,FF,E7,84,1E,AE,76,C7,38,8E,9E,85,E1,08,78,E9,C5,EF,D6,B6,17,FF,C9,81,98,24,1F,9E,FC,F2,02,B3,03,F5,23,8E,84,80,55,19,DA,42,83,72,66,E8,4C,27,C5,C0,D4,42,7D,41,0A,E3,5E,00,6A,24,DF,CD,1E,C8,F8,93,26,6B,F0,A8,A0,41,69,E6,65,5D,DD,F3,DA,B8,03,01,7E,E7,44,DE,88,88,91,16,C9,73,4D,04,51,C0,79,27,2D,17,A5,D6,79,4E,0B,9B,5E,A8,A7,B3,AA,20,31,E4,60,51,7B,7D,F4,88,35,85,AA,81,D9,D2,DF,82,BC,AB,0A,7A,00,AA,13,48,50,6B,CC,2B,E3,3B,61,FF,82,F0,E7,D8,AB,8B,F4,4C,AC,BB,D8,A2,22,4D,FD,E1,52,D8,29,FB,C8,79,C6,E4,AC,1B,95,BB,A0,74,B1,10,48,D8,D8,48,30,3D,2D,E6,15,8E,B2,93,8E,74,F9,66,56,91,CA,97,4C,EF,C9,F0,07,C0,65,7D,22,B4,94,02,08,F6,E2,FB,C4,52,62,5E,17,E4,33,B4,61,8B,C5,35,35,37,E2,FC,03,3B,F0,B7,21,44,9D,0F,59,6B,64,41,18,B1,CE,8F,1B,FF,70,BA,FC,7A,FA,B2,06,C1,BF,7C,25,66,DF,6E,ED,AA,4A,47,D3,68,6C,2D,9B,6E,80,15,44,A4,60,B3,B6,B6,BC,B6,23,2D,AE,1A,99,3A,AE,02,AF,05,E6,A0,F1,E3,74,A7,D2,40,79,FA,D1,66,2C,BF,12,BD,12,AF,50,5A,5C,BB,DE,E6,CF,1F,4D,A5,0B,A4,B5,4D,DE,16,4F,07,56,E3,58,F4,30,9D,74,5B,CD,82,03,EB,90,25,AF,F4,D2,B2,6E,1D,7E,CC,25,8B,BD,31,5C,40,EB,62,02,49,B8,41,55,0B,07,31,39,A8,CE,FE,7E,A3,BF,8D,22,72,B3,0B,CA,34,C6,7D,82,91,6A,B6,19,EC,07,B0,39,9F,93,9D,02,BD,F0,E3,C2,AA,FE,71,09,27,3F,22,32,C6,B6,19,6C,B3,BC,18,CC,6D,E4,A6,63,C0,64,13,B7,92,C1,2F,61,3C,6A,B5,88,09,B9,1C,01,57,94,64,41,17,09,59,39,47,06,32,84,A4,D4,2B,E9,62,4F,66,FF,BE,48,9B,6A,A3,FD,55,43,53,9D,31,90,D1,C7,AC,B5,49,E5,A5,44,77,58,50,B4,62,6A,E1,1F,B6,C4,29,D0,E9,65,8D,C0,FA,0A,5E,FD,03,68,18,18,B1,69,4C,40,AB,96,18,58,38,99,70,E0,C8,30,FD,33,C5,6C,A8,51,64,EB,DE,24,71,34,DE,D9,35,3E,00,65,4F,10,31,23,AC,EF,9A,94,9D,AE,B0,D7,7D,E8,E2,F6,8E,01,C1,29,33,0D,EB,CF,F6,1F,9E,C4,43,6D,B1,92,63,A9,BA,52,03,38,53,3C,EB,BC,5C,07,75,4E,0A,8B,0B,66,04,69,02,A5,30,FA,9B,53,37,2C,DB,FB,65,A2,27,BD,21,F6,2D,39,73,61,88,99,18,CF,C9,C5,87,DA,8A,56,7B,6C,5A,DB,E6,F3,18,3B,F7,26,98,8F,24,DB,87,9E,41,AD,64,E2,33,06,97,38,8C,5A,8F,5F,2C,B8,94,A1,E6,88,0A,CD,0F,F2,42,FF,37,0D,1D,3E,BE,85,B3,36,78,2E,AC,B1,0A,50,5C,D0,65,18,AE,52,8E,C9,64,EA,61,2F,45,9D,95,5A,42,06,C2,DD,78,5C,18,52,2F,A6,DF,01,BA,E0,93,84,9F,18,5F,98,42,BF,0A,CA,8D,97,1E,8E,3C,47,18,23,A2,BF,95,AB,50,77,00,E0,C1,6A,5A,2E,B5,DC,8D,CF,08,E7,2F,EF,C0,BD,6F,9F,D3,01,4B,18,42,B1,58,C5,A1,66,FC,79,1A,37,42,82,0D,E1,ED,CB,10,3E,7F,62,5A,0D,FA,82,BA,B6,E3,B1,F2,F0,4D,58,F8,D4,4E,09,F4,FD,F6,93,58,4D,D5,9D,9A,D0,58,8C,05,85,2E,68,03,B8,94,94,07,3B,56,6F,78,E9,75,15,DF,13,18,72,BC,89,29,A9,98,3B,38,86,5F,6E,3C,17,16,AD,FA,8F,44,A9,F4,5D,2A,B9,7C,70,CF,06,97,22,52,7A,B6,28,23,5A,FB,F3,5A,FB,1C,FE,E9,27,FB,C9,1C,83,A8,D9,A4,7E,CD,D1,01,51,11,0B,94,A4,48,E9,0A,55,8B,53,2A,C9,F9,D9,B8,BA,84,37,F5,A6,CA,4F,57,EC,98,D7,8C,D1,E5,FB,13,DA,40,A7,BB,A6,D9,2C,DA,80,3D,9B,EC,86,9B,37,1C,4A,15,00,98,29,8F,49,88,5C,42,BF,73,87,C9,58,DD,D9,D2,54,A6,5C,3F,A1,52,1E,DD,E0,5B,76,32,09,11,09,D7,20,F4,2D,F4,A6,5F,C5,18,A8,5D,38,D4,72,02,4E,CF,39,22,2E,67,D3,55,C3,F6,51,A4,AF,03,46,7C,F6,C3,CB,B4,FC,32,9D,90,22,EA,8A,60,F0,5B,B7,C4,9A,CB,01,EB,E0,0F,8E,12,2B,D1,C5,49,9F,96,39,5A,C2,78,25,D1,6D,8F,30,7A,58,6C,17,F2,FC,76,47,88,DD,EF,A3,45,18,BD,BD,E7,AC,49,C2,18,53,DF,99,C0,7D,F8,36,9C,96,04,6E,25,E8,DD,9F,40,B9,6F,71,4A,D0,BE,7B,D6,74,AB,27,F2,BB,C4,77,09,82,3C,3A,5D,71,2E,A9,0D,90,5A,4A,A4,F9,67,09,E2,C9,4C,17,3A,1C,C7,A2,FA,A1,3E,6F,DB,81,FE,31,BE,8E,0A,62,97,08,61,88,15,2B,7A,DD,DC,F8,C8,DE,B6,83,C8,13,1D,40,15,D8,C9,C9,C7,6B,81,2D,39,55,58,FE,F8,E6,8F,00,B4,44,25,21,EE,77,B9,BD,55,FF,D8,D0,E3,B3,F3,E9,F5,C7,73,C1,74,13,2D,89,25,AD,AF,63,00,1D,43,50,04,4E,91,52,0E,56,E3,6E,89,01,EB,3D,E1,5B,FA,45,23,BD,F6,94,56,EC,BE,57,E4,20,F1,3C,A9,70,C1,A8,A2,00,DF,75,06,BA,CA,05,D3,3A,DD,40,71,04,96,25,1B,1C,92,B0,1F,A6,92,EB,16,E9,E1,48,3B,13,78,7F,B9,A9,97,94,CD,70,B0,6E,94,17,29,B7,11,FC,A7,9B,E8,11,3B,3C,0C,E5,74,7C,A4,7C,40,42,B0,E1,32,D5,F8,41,B0,94,B7,C3,99,90,2E,08,7B,98,90,46,9F,23,3D,70,EA,4A,59,DC,61,84,95,C9,6F,DD,7E,2C,D4,E4,A7,89,63,59,6A,47,AA,29,A1,C3,14,A1,B2,1C,EC,30,4D,09,7D,39,CD,5F,28,C9,4E,11,A2,51,F3,C4,5B,4B,C2,12,7C,D5,E1,A9,08,70,2F,D0,6E,B9,43,20,9A,31,FC,45,81,39,43,74,0B,1E,09,F2,27,93,2F,D6,5A,D9,85,2E,4A,FD,AA,8A,15,F4,1B,D5,6A,A1,53,AF,44,6D,2C,E3,A9,2A,28,B4,E2,4D,D0,E6,7A,D0,5F,B2,B9,CC,41,0D,4F,22,F6,AA,2B,53,8B,D5,BC,40,74,CB,1C,BE,92,8F,43,66,39,08,D1,EF,8E,72,81,5D,2C,74,2A,D6,97,2B,EB,8D,64,8F,1E,BF,CA,FF,74,E1,76,CC,4C,C3,E7,CC,5C,08,1D,E2,AF,A0,04,AB,C9,E3,76,AF,F5,59,9E,02,0D,04,0E,81,CE,59,74,F4,5B,BF,59,BE,28,BC,E0,AA,28,FA,22,E1,B7,C6,43,28,7F,44,3C,95,80,D7,67,05,0E,21,54,0B,D0,C0,16,99,1B,27,06,63,60,86,98,B2,E8,13,16,1D,0D,33,EF,D5,22,03,AE,6D,DD,F1,5B,6A,AA,42,E1,CE,2B,A0,52,41,18,71,76,DD,F2,EF,5F,38,80,D5,4B,D4,D9,2C,C3,63,C1,B5,E5,99,46,28,6A,FA,81,5D,56,95,9B,BA,8B,B6,A9,E4,E0,26,9F,2C,E5,60,93,8B,5C,01,6B,11,A2,81,06,AF,56,DD,38,92,CD,05,C1,32,BE,EA,F7,C0,6C,BE,0C,C2,4D,0C,2A,26,90,04,F6,72,5D,02,9D,9B,3E,92,3B,5D,72,79,5D,5B,AC,70,84,39,D8,36,39,62,83,34,07,7D,A4,AF,79,E2,03,5F,6D,87,9A,C7,44,E5,3F,BA,38,90,1E,59,84,5A,BA,2E,B8,C2,5E,C7,8E,A6,25,B8,26,25,81,0A,DE,1D,83,4B,39,A2,0E,8E,EA,2C,A7,01,4D,43,A1,D5,CA,FA,40,BD,D0,44,DA,2D,37,FE,1E,5E,31,8F,8E,A1,12,FD,FF,33,D7,81,79,FA,EF,64,EF,8A,7A,BF,F3,A5,C7,AE,3B,09,CC,BB,89,89,5D,25,25,44,10,1C,14,46,43,31,DD,1D,5B,6B,9A,36,28,C5,0D,A8,B4,AA,5D,12,4B,36,51,67,9C,78,BD,FF,04,AF,85,6E,AA,74,B9,D0,D9,1D,2C,38,C8,B4,E2,B0,C9,BD,E6,9C,11,72,7D,FA,DE,49,3B,0B,35,8E,68,89,7B,BD,53,DF,2A,07,FD,9C,6B,A6,5E,CF,CC,4B,85,2E,AC,FF,1E,0E,F5,46,DF,E7,3E,70,8F,E3,53,38,82,BA,33,41,7A,DF,CD,19,33,F9,BD,07,07,84,40,A0,AF,6C,E4,20,A3,DE,29,A1,C8,62,77,E1,1B,8F,4E,9D,96,CC,11,40,72,11,88,E4,03,41,73,A1,68,35,4C,E6,3C,90,6E,7E,9B,66,86,C5,3E,AD,99,90,3E,F4,7E,4D,64,5A,87,DB,FB,0C,56,E0,EC,87,A6,71,04,CB,76,4E,A7,FE,F9,E9,A1,2D,6A,97,58,8C,48,66,6B,56,A7,FF,D0,F0,78,95,B3,E6,55,80,6D,29,DF,B2,2D,1C,57,DB,13,79,B4,EC,06,1A,06,E9,09,AE,AC,07,59,79,64,A2,74,88,66,E4,32,64,43,45,87,76,AC,DC,FA,04,05,5A,0B,B4,85,5C,2E,56,EB,DE,62,E3,68,CA,07,DC,51,60,49,8B,FF,25,96,B2,E9,3B,06,7B,0C,E0,90,C0,61,B0,13,4F,C3,90,19,7F,D2,89,87,44,94,3E,C7,25,66,C8,27,74,2B,B7,07,87,7E,83,0B,98,FA,AF,28,08,7D,86,AE,0E,92,8C,5F,27,D2,D3,5A,F9,1E,FE,16,69,B1,C4,FF,15,57,05,26,9D,AB,48,2B,3C,35,FB,F6,8E,73,72,72,11,AA,EA,18,85,1D,61,23,28,5A,AF,D7,01,C5,E4,83,70,75,9A,E9,C3,9E,8C,75,1E,D3,F9,4B,BC,2D,91,B8,16,D7,24,8A,FE,3C,4C,D7,41,5A,E9,AE,B0,01,38,C5,6F,C4,F8,E5,4D,D5,A5,87,EA,29,84,B3,70,A2,90,D7,81,05,5B,E6,88,6D,57,E3,31,F5,8D,23,AF,68,FE,F4,F5,1F,63,13,87,E6,6F,92,4D,9D,8D,DE,5D,F4,3F,FC,11,91,76,35,C6,CD,11,63,D0,CB,A6,27,35,62,49,94,75,E6,0D,27,82,C1,B1,40,84,A3,34,79,FB,29,C9,34,FA,65,BC,B2,65,9D,5A,D4,98,8B,BA,72,4F,F2,63,4C,0F,52,D4,E7,C7,2C,DA,EB,67,44,FF,D1,63,86,5E,B1,4C,A5,A6,C2,E5,77,2F,FE,96,AD,D9,A9,DF,30,9A,2B,4C,8D,C3,8A,16,EF,25,FF,EC,89,C5,29,3A,9D,6E,6D,01,F1,9E,AC,6C,5B,5A,34,0E,67,2E,CD,42,9E,F0,F0,B6,57,DE,7D,32,C5,3B,F4,2A,A6,15,BD,BF,9D,CC,FD,B0,13,6E,1C,D3,0D,3A,79,81,26,05,01,29,E6,0D,6C,25,66,5D,AB,0B,50,4C,79,AD,D0,21,16,22,58,93,BB,52,76,EE,48,E3,08,AE,21,4F,30,61,EA,33,12,0E,D4,6A,C0,90,3C,78,D0,BB,69,8E,00,94,FF,30,0A,14,59,FD,9B,DA,82,14,13,2F,B8,54,BD,96,CC,9C,F9,91,14,7A,87,78,6B,D1,51,D9,2F,32,F2,83,CB,E2,73,96,63,F0,25,00,86,D6,5D,A6,20,6F,B9,BD,8E,B2,E2,3B,AA,38,34,96,D0,6B,36,08,D7,DF,99,02,C9,BC,99,66,8A,48,BF,9D,F1,D7,8E,55,72,B8,FC,45,04,A7,C8,B6,64,87,B2,57,40,65,FD,33,89,A6,C3,07,8A,A1,E8,53,F8,FE,33,ED,82,05,3E,5F,26,61,09,48,F2,F2,E3,A6,AF,23,6D,77,52,FC,9A,02,37,54,6A,76,D7,1C,38,45,7B,C0,57,6D,B6,E1,04,FE,B9,B5,87,3C,7B,75,1A,45,4D,2F,97,B1,97,EA,F1,02,31,25,A1,BE,7D,D3,C4,B4,AF,28,05,F5,82,31,C3,AC,A9,6B,DD,E8,FC,D9,A7,C9,C3,32,CC,23,17,74,96,EF,81,0B,33,41,CE,FE,EB,BF,FA,E1,68,3D,26,22,71,AD,AB,D5,0E,AB,70,62,A3,DB,A3,85,78,E9,8A,C7,21,A5,A2,02,46,D1,1C,01,73,5A,88,90,2E,0F,89,78,95,3D,5E,DD,DE,FD,D9,D4,7B,D6,52,07,6B,98,E8,F1,1D,14,6D,E0,BF,4D,C2,98,B8,E9,D0,28,ED,AC,7E,20,A6,F3,DD,5F,E7,40,84,DB,5E,C0,4B,67,56,6C,5F,F8,BE,53,4E,7C,8E,2D,B0,7B,7B,E0,6F,C1,13,BD,B5,96,5F,E8,B4,78,C7,70,FE,DD,60,EB,E3,22,B0,D3,F2,5B,D4,AE,AA,39,32,29,4E,90,F1,7B,71,7A,A1,17,21,C9,3E,B3,BE,50,C9,B7,30,78,03,B2,97,B7,41,91,54,7E,F8,7A,36,32,1C,68,CD,09,68,D5,BE,00,B2,2C,9A,FD,FA,8D,9A,8D,1F,7F,05,FD,75,87,6E,EA,47,70,57,30,B7,54,E9,F7,C7,5E,A1,36,7B,68,67,91,15,B9,A5,BE,06,7D,84,09,52,0C,4E,44,4B,D6,A3,75,33,3F,7B,24,CB,DF,9F,64,A3,78,79,9D,4E,C3,84,46,37,0E,45,09,56,78,BD,65,0F,CF,49,01,A7,A7,A3,02,8B,9F,B5,B6,B6,34,37,F5,69,77,6B,D8,3C,16,DE,C8,6E,3B,45,49,49,31,09,4F,95,F6,31,2D,13,F4,56,1D,CE,55,62,92,C4,89,32,83,CE,B6,45,16,35,55,F9,E1,3F,6F,2A,BE,02,05,5B,3D,06,FC,8D,54,94,33,00,0D,00,E0,EA,4C,6E,2E,45,8C,49,0D,BC,B8,2D,EA,50,F3,65,BC,A5,C4,A0,1D,93,1F,C6,56,BC,D2,B5,D5,4C,FC,7B,A8,2B,1A,73,44,36,AD,40,9E,A7,B6,8F,4E,DF,4A,CA,3E,6F,8E,85,09,7B,38,56,6E,A6,B1,84,BD,5A,B6,DA,E8,05,C2,EB,8D,7E,D1,DD,C3,85,BE,EA,06,73,46,3D,D5,44,8A,62,80,65,2A,40,5B,57,C2,84,30,C6,7E,4C,D8,89,BF,91,60,AD,1E,6E,C0,BA,1F,9F,4A,B7,A7,55,68,9C,4A,70,8E,5D,CF,57,02,B1,5B,D0,C5,B6,3F,F8,1B,95,77,4B,93,52,A1,A3,9D,59,09,95,13,AA,C8,09,4E,8B,33,35,FB,AC,48,33,EE,BF,5B,91,94,50,5B,03,83,3C,C3,49,33,8F,6D,E9,AE,85,06,7F,C6,8A,F7,CD,6B,27,E1,9F,06,C0,73,EE,3A,68,E7,BD,3F,AA,D7,51,B4,E9,ED,91,AC,17,2F,8B,D6,FE,47,C1,9B,32,DB,25,FE,00,24,81,E7,CD,FE,D3,2D,D9,8A,B0,C4,FC,FF,17,C6,6C,6D,B9,6F,C3,91,6F,0C,52,59,E6,11,F8,79,B3,64,31,7C,20,F8,77,AF,16,22,CB,36,57,1A,EA,65,A5,E7,9B,87,42,AA,96,41,B5,8B,0F,34,55,DB,07,63,CB,BA,4C,02,3F,79,92,A5,66,0F,F2,50,54,90,79,8D,BA,A9,55,31,8E,34,CF,02,DE,6D,08,72,11,3C,18,44,4D,7E,91,4D,10,38,24,0F,C1,B8,B0,E4,B1,88,86,4F,C5,2E,50,B3,C6,B9,89,63,20,7A,47,D9,08,12,8D,5E,10,54,C1,F0,C4,C4,ED,80,5C,CF,49,B6,2D,06,05,A9,69,E0,8B,33,E5,EB,65,18,30,3E,8C,4B,28,97,E5,9B,48,C3,45,B4,03,47,78,BE,2D,C4,8E,70,D6,12,40,4D,75,75,31,95,0B,17,3E,1E,C3,33,C9,49,13,8E,BD,6F,68,24,07,8A,5D,00,C7,E1,AF,02,7C,A1,5F,80,E6,7D,50,39,48,A4,1B,EC,3A,3A,CD,15,F8,F1,89,FF,95,E3,5B,93,FF,B4,45,FF,8E,2C,7A,BC,96,AA,32,14,A3,F1,A8,C7,69,C9,1A,DD,4C,0D,25,4B,74,47,13,95,13,C0,32,80,BA,6C,34,40,48,8F,CC,A8,2D,01,93,3C,A0,9F,C9,F5,BF,D9,55,F2,7B,68,08,80,0B,92,FD,CC,6A,5B,9C,0A,D9,09,46,ED,5C,42,E8,FD,6E,8D,1C,61,5B,D5,CB,B6,32,A5,CD,A7,46,0F,1E,C4,DB,7A,0A,C4,F4,FA,1B,9A,8E,E4,C0,C4,A5,9B,79,F0,5F,29,FC,B9,47,25,93,CA,D6,56,0E,83,84,D6,57,CD,03,A8,CD,89,2E,68,04,82,82,FF,3F,C3,A0,67,70,A8,69,18,BE,1C,B1,D2,E5,E7,CC,94,B7,2C,ED,C2,3A,8B,42,BD,D8,5D,B5,3A,FC,45,E9,F1,18,BE,BA,C0,7A,53,53,8F,2C,28,28,3F,38,63,A0,C3,56,B4,5E,75,93,F7,0D,7C,45,C3,70,8D,1E,AC,AF,22,03,00,51,FB,68,B9,22,A6,AA,10,69,A7,6A,2A,B3,74,86,79,BC,6E,5D,65,78,EB,BA,9E,5A,C6,25,41,A3,C2,BE,53,95,D5,71,3F,B5,30,E7,EB,D2,D8,A2,A8,07,1F,14,F8,3D,DB,04,75,98,25,BA,C2,98,28,C8,AC,69,96,22,6E,43,FE,70,BE,84,6C,98,07,B6,53,1B,A7,C0,BB,40,1C,11,D5,17,17,54,46,E0,C3,6E,C0,4B,22,04,D3,3C,5B,E9,EE,08,4D,C5,B9,8F,63,84,71,62,F2,C3,DC,5C,86,96,E3,05,C5,33,BB,96,D2,D6,E6,94,01,0D,43,56,DC,7F,0A,86,A5,EB,43,05,6E,DC,0D,E3,D1,6E,5E,42,6B,F0,26,8F,F7,E7,19,B3,36,8E,B1,BE,79,5B,30,11,E0,26,71,9C,95,E8,71,F6,0D,C1,65,70,88,F1,29,9D,20,BC,F7,D6,D9,4F,3E,CA,8E,E8,98,30,13,CA,A1,B5,F9,76,BD,71,66,1B,D7,DD,72,B4,D8,A2,F7,DF,DC,A4,78,94,A1,89,32,FC,7C,61,13,3C,08,06,CE,83,0F,47,51,98,53,4E,30,B7,3B,09,5D,CC,29,63,57,70,EC,DD,00,71,42,29,57,68,91,CA,FE,99,BC,F2,D5,4D,85,02,57,FD,EF,F9,28,64,8B,89,CF,CA,12,33,B1,83,55,BD,C3,84,26,0A,0E,A9,E8,A1,89,49,D6,42,D4,58,71,D6,D3,79,FE,85,9A,A3,0A,93,68,6B,5B,2C,97,FE,79,9C,91,AF,DD,0E,01,27,EB,17,9A,93,27,80,02,93,38,FF,C8,EA,A1,33,BA,84,99,B9,4D,C4,50,2A,FB,6F,83,7C,72,E1,23,D0,96,7A,F7,E3,8A,F8,BB,E4,50,12,E2,01,36,CB,BA,21,2D,8C,2E,57,57,7B,32,48,12,34,23,73,18,7E,A1,79,DA,9D,C2,37,81,8B,83,88,56,F5,9A,FF,D7,BD,07,CF,4F,E5,0D,4D,BB,A5,B1,24,78,39,4D,C8,38,D9,94,D2,9F,2F,42,18,05,E2,B0,58,97,A1,4A,97,65,5B,68,96,57,C8,E8,FF,61,4B,3E,63,D6,82,2C,2D,9A,34,87,76,2A,11,E0,FD,9E,B0,73,13,A8,14,FC,12,8A,02,A8,63,7B,DA,C4,D8,34,0F,BB,0C,09,24,B9,37,1A,78,33,AB,72,42,30,54,5E,E6,3F,63,EE,1C,F2,3C,ED,AC,2C,EA,DB,6B,0D,C3,95,1A,96,BA,2F,50,16,79,94,8B,5C,3D,4E,89,27,DB,53,03,F0,4B,BC,9E,EF,02,55,C5,D9,5A,56,2D,59,12,9D,ED,2F,2A,0B,84,06,B0,F2,CD,41,E2,0D,46,69,28,EC,A1,F2,E0,CC,D9,A4,5D,F7,CA,17,DD,E6,72,5A,DD,3C,CA,18,A8,92,28,87,15,B2,A5,A5,50,E2,20,A7,BB,FA,B8,9A,53,92,FC,9C,4F,6A,E5,44,75,60,75,73,97,5D,14,15,B7,DB,82,8C,DD,C6,6A,E8,47,54,78,62,CC,50,9F,41,AF,09,9D,00,F9,CE,BC,6D,CB,04,AE,88,5C,3D,3B,1F,4E,28,E0,DA,AC,36,A5,AB,AB,DD,19,12,A1,35,50,7C,DF,29,BB,D1,1E,8B,6B,30,72,0E,D8,02,9C,42,5F,9C,F1,CA,39,CC,F8,EF,78,2C,AC,88,BA,38,D3,19,59,96,65,FA,66,6F,FA,E0,46,10,C3,B0,09,E0,2B,CC,99,32,61,80,F0,F1,1D,5E,02,92,D3,9D,A0,A2,72,88,2A,91,E4,FC,71,2D,28,67,BF,4F,D6,5F,F0,E1,75,D3,56,DE,3C,B7,FD,E1,AB,20,06,F3,05,45,CB,35,DF,FC,35,F1,5A,92,BD,20,C0,6E,A0,39,A6,34,0B,61,CE,98,0E,AB,CD,A1,97,96,91,59,2D,34,61,4D,BE,87,0C,CB,88,43,C5,88,C8,BB,E9,E1,10,6B,0B,48,99,61,4B,B3,DA,2D,91,09,75,2E,16,55,4C,62,D0,30,7C,C5,02,0C,FF,A5,A0,51,4E,4E,C7,CF,8F,03,8E,BB,9B,62,E0,3A,E5,C1,FD,DC,2F,A3,16,42,2C,DA,AF,C3,C4,FF,65,C9,6C,DA,C8,34,B2,2E,ED,A9,EF,45,9B,A6,35,0D,02,BA,1C,2E,8F,E4,03,F5,2D,A3,C2,CB,30,B0,A6,E1,4D,27,A5,DD,56,59,E8,AA,00,17,7A,5E,D1,05,3C,51,9C,87,83,F3,F3,03,21,5F,47,68,D5,E5,3B,70,1E,98,5B,2F,AA,09,C7,6C,49,6A,A6,1E,70,98,75,64,ED,98,06,2C,39,41,C3,B5,8C,AF,D7,B6,FC,69,00,DF,48,8A,80,26,92,C8,92,90,72,1A,57,5B,34,AF,0C,A7,5F,15,31,87,70,E7,A2,03,DB,D9,F1,8B,7F,8E,23,10,56,EE,FD,7C,7D,24,6D,C8,03,3A,F7,59,50,A5,49,68,DB,C3,03,86,3D,91,24,54,4C,10,23,E1,AE,D6,15,1A,47,A0,0D,21,83,06,10,44,83,10,51,BE,9D,8F,54,C8,82,8C,78,0F,CD,CD,D2,39,65,66,05,A2,05,FE,86,75,3B,4A,76,56,D3,07,4B,DA,66,BC,55,02,16,44,F1,CF,BF,81,61,6A,42,C9,22,C1,8D,A5,7B,68,C5,63,05,FE,CA,91,9C,49,84,4F,27,DB,C5,03,2D,25,B5,FA,4C,91,C2,62,3E,63,82,B0,CD,21,52,35,8F,29,CC,16,EB,9F,67,49,5B,ED,37,5A,8E,FB,87,17,F3,ED,4B,1B,F0,AC,70,E1,00,B3,C7,F2,47,C2,B8,55,12,01,14,01,56,11,7B,07,47,F3,DF,A4,5F,A1,99,DF,5E,3C,3D,3A,89,5C,3D,9D,41,83,19,78,5C,3D,9E,0D,E7,A3,5E,7D,D4,8D,4C,73,74,DC,9F,C8,0F,1A,61,2F,97,3D,DE,66,69,AC,2C,03,BF,A7,3B,7A,9F,C9,D8,39,40,C1,97,D4,BC,CF,AD,D1,73,E7,86,99,46,64,1D,69,A4,2D,B7,90,EE,BC,6F,54,D2,1D,66,F5,81,93,3E,21,D7,70,63,3D,15,B2,70,FC,76,8F,6E,97,9B,2D,11,57,88,BB,F6,25,49,33,A2,6D,82,33,E2,DD,C3,67,BF,A3,9D,44,D4,59,ED,67,D7,24,8C,13,DE,79,68,F0,B5,30,55,36,DC,FE,D0,8D,69,47,94,E8,D3,4A,A9,EF,F5,9F,F1,E5,DD,DC,EC,D0,FA,18,63,B8,D5,E6,A4,F4,05,90,1F,8D,3B,02,8D,7F,5E,4F,F8,A6,06,DF,28,B8,47,30,50,1A,EB,40,27,6D,57,A4,7D,B3,AF,C8,24,AC,80,A1,C7,62,C6,28,59,36,75,EB,88,5C,6A,D9,8C,C5,FE,C3,7A,B9,A2,30,C4,ED,BB,55,65,1D,50,73,C2,7A,BE,DD,84,0D,9E,3E,57,49,47,4D,61,BC,6A,64,8A,5F,7A,AC,9B,39,7A,57,F2,50,3C,D5,9F,4C,63,1B,59,E0,DD,D3,19,CA,3E,0C,53,C9,D2,3A,A4,E4,DB,55,D3,43,F2,D9,53,11,CE,10,C3,15,57,45,F7,64,6F,6F,D0,B3,A1,F1,0B,40,9A,89,F7,E9,70,E6,C5,FC,C2,CD,B4,61,B6,E0,C1,B9,30,F1,91,4D,E5,AC,78,59,76,F4,4F,C8,BA,59,9B,37,07,0E,8B,F6,CD,B7,93,0D,13,C0,75,16,5E,FE,8F,53,A0,0E,B8,8E,5D,0C,D6,58,B6,2E,20,23,42,22,2D,F6,93,D1,6E,A3,68,E2,4B,12,00,E0,61,94,3C,FC,FD,D9,D7,37,D1,0A,41,55,AC,85,F5,4B,48,53,37,24,2B,55,67,A2,1E,FF,19,7E,06,9F,59,1A,BA,91,7C,15,9B,F5,EE,53,37,82,F8,E6,E0,1A,02,2E,CA,69,8C,81,FA,9D,72,5F,BA,09,54,3E,1D,75,3A,4C,FA,0F,D0,05,D5,B7,1C,06,31,31,FD,ED,CB,F3,18,72,06,63,E6,53,09,7B,59,19,F5,FD,C2,AD,7E,77,50,27,4B,05,96,9E,8F,52,D9,67,2D,7C,1D,22,08,CF,2E,0D,DA,F1,FA,BF,E8,24,DF,81,A0,14,81,A8,46,5C,6D,2A,48,AA,41,F2,95,B3,2F,AB,3B,96,6F,52,9E,46,1E,50,70,CB,77,8B,DF,62,CD,11,4E,F1,27,43,B1,34,24,AE,0E,D5,06,68,2E,4C,FB,3E,B9,50,03,E5,47,5C,8B,9F,C0,D5,8A,AC,3E,73,3B,1B,85,30,46,46,1C,E4,44,60,DD,BF,24,7E,07,29,B0,5A,A6,A5,0F,E5,53,C9,D0,23,6B,71,EE,DF,45,EA,57,67,DA,86,C8,9F,C9,6C,87,97,C6,8A,9B,13,FA,7E,7B,68,C1,45,B3,AD,4E,CF,3D,97,0C,AB,D6,A1,05,35,E7,5C,24,B1,9E,34,A0,B7,A1,F3,E5,C1,B0,4E,07,B0,17,BE,B3,42,03,B6,BF,A4,0A,8C,13,4D,54,E8,E6,45,BD,7F,01,2A,D6,F8,F6,AF,B5,A3,14,32,7A,C1,EF,42,EB,EF,38,B4,B6,51,22,62,87,A7,84,B7,A4,44,A1,83,23,72,FD,08,6A,70,55,5B,33,7C,9F,62,24,4D,A4,7B,D7,9B,9B,76,03,DD,FA,66,38,0D,C1,8F,69,36,82,FB,52,10,D5,1D,B4,9A,8A,50,54,9F,D2,95,07,94,76,25,59,C6,21,C0,5C,C2,E4,F4,4D,CA,0E,5E,AE,FC,1C,38,1A,6A,C3,BB,0A,B3,E9,C8,1F,B9,AF,87,01,45,20,21,FB,29,72,CA,57,23,3D,33,96,05,0A,85,96,86,38,64,21,16,29,3B,99,60,84,F6,44,C4,DD,1D,2B,F9,74,84,E5,37,AB,9E,3B,99,81,E5,2A,92,5C,4C,3F,96,80,BA,39,88,FD,6C,FB,53,A6,9A,54,77,1B,D2,D8,5F,2F,55,83,6B,22,1E,05,53,EB,1C,F3,D3,7C,35,5A,52,A2,CA,90,21,A8,C4,C1,72,47,1C,0D,B1,45,D0,F4,07,8C,98,FB,E2,4B,FE,73,C9,4E,2A,03,71,78,40,3E,0C,82,29,58,D9,A0,4B,67,B1,7E,D0,7D,05,D3,BA,92,8E,0E,09,0B,63,2F,BA,30,BA,B2,E9,DB,C0,0B,E9,39,94,FF,E7,44,F8,D0,2D,9C,BA,D2,26,35,27,8A,76,CC,A6,90,B2,56,9A,26,2A,D2,5F,F1,BC,CB,08,48,9D,36,D4,2D,5C,F6,E3,69,2E,45,C9,4F,F8,45,90,1B,5E,73,ED,41,0F,6C,0A,D8,82,16,6F,37,0F,76,B5,D1,09,FF,C5,93,75,80,97,C2,AF,87,EF,B0,D3,D5,A5,2D,FF,EA,21,06,6E,9B,EE,19,56,28,B5,4E,AD,D3,19,AA,6B,1B,E1,03,BC,F1,48,A4,3E,29,A9,12,F9,CD,70,47,7F,E7,E9,F0,15,7C,2B,BE,FE,08,D2,75,89,67,1E,BD,F9,05,F7,79,6A,64,82,B3,DF,1E,FF,DD,56,14,8E,F7,3C,A9,1C,60,06,B8,0F,55,E6,5A,10,40,21,92,AD,25,9F,C2,37,ED,7D,42,23,5C,94,81,73,59,C0,3E,71,AC,F9,C3,EE,79,25,4E,40,D1,C3,F7,70,83,FF,BE,F6,75,52,86,03,F6,E7,02,07,8A,E3,01,4B,73,0E,B0,FB,98,09,0E,93,77,96,8E,79,DF,F0,4A,28,E0,53,92,06,39,7A,CD,74,FF,27,D4,12,95,C7,7A,93,27,6A,5E,5B,97,A3,64,62,9D,B5,E6,2F,4E,24,9D,AC,37,91,E3,BD,07,6E,3B,7B,B8,16,04,BD,C3,79,2D,76,5B,3B,3E,76,2B,4F,83,4B,BC,1A,BE,2C,8F,0B,EF,DD,D2,9D,70,E1,B6,7E,B5,77,8C,41,DC,3E,A0,08,CF,C5,01,EF,CE,47,C7,D2,F5,13,43,F8,68,AB,95,DD,C8,E5,0C,86,57,3E,50,42,A4,B1,C1,EC,CF,A9,4E,C8,1D,CE,0D,BE,F0,C0,81,B4,F6,50,74,D6,85,99,F9,1D,4C,6E,B2,04,C6,F4,C8,9A,01,6E,F0,04,7E,09,82,69,13,41,09,DE,FC,EF,E5,FA,1A,33,A9,11,4E,88,3B,42,77,FC,53,1F,96,D9,E5,EC,BF,FB,01,C0,C6,89,91,E1,0E,00,BC,47,B0,E4,3A,96,13,FA,B0,5C,C8,75,6D,45,A1,AF,64,52,8F,05,E7,55,37,87,DD,9B,80,98,17,E8,02,0C,5E,D4,C3,32,F0,B5,21,A8,E4,AE,5E,D5,05,D4,80,8D,B7,00,3B,21,3D,69,AF,11,2D,A2,71,D2,8A,F0,E0,E3,52,A6,C4,D4,95,E5,4D,FE,65,8E,22,D9,50,2F,DE,6E,9F,1B,27,FC,25,D4,91,48,CA,CB,13,D7,91,69,A6,68,48,14,FB,A0,D8,1D,93,9A,1D,D4,70,1E,25,68,3C,B5,DB,23,9B,EB,A1,98,EF,98,5D,E0,13,2C,43,CA,18,A2,5E,28,02,0D,94,A4,D3,7C,6D,4A,B4,1F,06,CF,C1,29,AA,E3,C2,39,7A,5C,C1,16,B6,9C,B5,FC,54,7B,1B,E4,F3,FF,74,24,B2,6B,E3,2E,F3,0E,A5,8D,A2,74,DA,0F,88,58,D6,F4,74,48,E1,6A,54,18,53,8F,F8,B9,D1,E0,77,6C,3C,01,04,34,3F,1B,D0,51,81,CD,55,03,2F,E6,B6,C4,14,5A,D8,66,90,21,B7,DB,82,47,8D,6A,E9,85,56,BB,42,3F,57,7F,72,99,66,7D,CC,19,60,B5,3D,35,C8,D0,30,B6,08,3D,48,1D,6B,BB,CE,00,FC,B6,94,BA,DC,FC,F4,BB,98,24,06,B4,F8,8F,73,FE,98,08,96,C1,DF,4B,5F,38,8E,1A,21,A0,2C,B0,CC,73,8D,4F,64,6E,25,B5,AF,13,C6,95,4B,50,80,DC,77,1A,29,D0,4A,0F,C8,4C,94,10,38,BD,13,76,46,95,89,64,E5,FA,B2,FE,BC,EE,E9,09,E9,C2,88,41,51,AD,62,1F,C2,84,15,26,E1,19,8F,6D,F8,46,E8,AE,5D,43,A7,21,22,43,E0,F5,72,B9,55,D1,38,B3,1A,AD,63,C3,26,7C,96,EA,E6,B1,B0,72,C8,37,F3,7C,E4,93,BB,63,B2,48,4A,39,35,B4,02,B1,DC,56,62,AD,6B,32,75,5D,5D,3C,05,37,E1,CA,2C,C7,A4,B7,60,BC,4C,23,CB,5E,44,4C,5A,1D,67,9A,82,10,22,76,84,F4,1E,A6,80,AC,C4,7F,31,DF,AA,16,93,B2,7F,52,67,55,1E,0D,26,F3,74,B4,D5,18,9C,8C,8A,0A,92,80,1C,85,8F,F3,84,A7,74,B2,E8,42,76,AE,BF,EE,1C,E8,9E,A2,C6,81,C2,11,B8,78,9A,9D,2E,D0,12,F2,9E,7A,50,C0,1C,2E,76,70,1E,33,57,56,32,3B,5C,A5,76,58,82,1E,76,1A,8F,60,93,DD,98,2F,20,D1,F7,24,B4,D8,65,ED,1B,5E,09,59,68,49,10,97,D2,64,47,5E,95,1D,A7,21,02,F2,FF,F3,E1,5A,BF,40,D2,0D,D4,5F,C1,DA,3B,DF,C3,88,06,75,9D,2B,72,00,0B,5E,48,43,60,50,2E,FF,6B,B0,F8,9A,94,94,9C,7F,B8,B3,9C,49,8A,B4,D1,84,9C,F1,2A,5C,0D,04,CE,F6,22,DD,2F,3E,ED,B8,DE,14,BB,9D,AC,01,88,18,CB,1A,1C,C9,39,17,08,E3,BD,8E,ED,D8,A8,F7,6F,8D,C3,B8,A7,98,39,8C,94,81,44,41,96,BF,60,4E,C9,9F,20,19,B8,F6,CD,F3,29,EC,7E,98,FA,8F,6C,5D,F9,B6,5A,EA,15,23,BE,B1,DB,E5,71,E9,DF,44,19,D1,E5,D3,B2,75,A7,3D,E7,94,EE,91,B6,7B,EA,37,54,29,69,16,31,31,D9,6A,AD,BA,E9,ED,44,47,04,4B,4D,7E,54,6D,30,EE,9F,12,48,59,6E,71,F7,23,3E,ED,55,3C,3C,B7,95,AF,7E,89,AA,B3,97,E4,83,0F,60,55,E9,02,53,F9,8E,33,B7,37,B3,F1,E1,BA,00,0B,88,F6,18,8D,C8,CE,99,0B,72,13,33,DC,21,31,4D,67,F8,6B,1E,0F,66,1A,C5,3C,C3,E6,AD,02,EF,22,DD,67,27,02,61,61,FE,29,41,ED,5D,22,91,7A,7A,D5,B3,66,8B,3F,DA,30,8D,00,50,26,D0,47,BE,2C,C9,4D,87,6A,8B,A7,A5,27,68,8C,DA,ED,2C,E2,C2,A2,3C,78,E9,77,BD,C3,9D,E7,10,0B,15,DF,BF,AD,22,EF,4A,FE,26,6A,95,B2,21,5F,B0,37,82,97,8A,5B,03,3B,99,87,5F,79,6E,20,84,AC,46,A0,00,A6,8E,1D,9A,3F,93,A6,9C,F7,5A,DA,0C,64,16,FA,BB,33,2F,4E,FF,64,79,90,F6,F1,B8,98,03,EA,91,F0,7B,D2,82,27,51,1B,E9,43,20,95,B4,C0,30,5B,92,BD,8C,CC,A9,32,B3,63,F8,F3,F7,D1,E1,B4,02,EC,BF,97,64,B3,51,DB,68,E6,13,40,5D,E0,41,56,09,8F,B2,02,9F,84,3C,C7,C0,DD,7C,DA,80,3D,E5,AF,A3,86,1B,85,A2,8B,52,C1,A6,68,1B,DD,CE,1B,3C,A6,08,62,02,C3,F6,D7,F9,3A,C5,CC,5B,26,3E,3B,2D,CF,D0,2F,D1,7D,48,C3,56,3C,62,95,29,91,A7,38,EE,14,34,51,2D,A9,3A,65,FB,84,AA,0E,D7,FB,97,33,FC,66,D6,79,9C,2A,5F,2A,1B,20,93,0C,E7,4C,32,78,2F,3E,86,20,E4,E8,59,CA,C1,F8,A2,17,E8,F2,DF,6C,64,B7,F4,2E,36,24,F5,CC,58,F6,35,0D,93,65,13,69,23,96,FF,68,C6,EB,9F,0A,45,73,7B,A0,A4,92,B2,87,63,F1,89,39,E2,BF,62,18,F1,E8,2F,76,AF,76,A7,03,60,93,D4,A1,A1,B0,73,4B,04,52,73,39,11,2C,33,19,61,72,D8,63,F7,18,51,B6,6B,8A,51,8C,DA,CE,31,C7,DE,1E,7F,AE,71,47,0C,80,9D,3D,FF,29,B9,DA,36,5B,49,11,0B,FA,60,53,DF,9C,0B,00,B0,1B,EC,40,CE,79,89,18,4A,73,3A,52,86,8D,22,B7,03,DD,74,27,54,01,15,5E,6F,B6,8A,63,96,A7,1F,34,BB,D9,6C,2D,48,26,BD,6D,8B,EE,EC,12,D5,A9,3A,F1,C2,17,96,50,43,F4,9F,05,01,50,4E,B3,10,C7,EB,3B,0F,23,0F,FA,54,22,81,7F,E7,98,88,6A,C2,88,FA,91,75,BC,74,B6,51,DF,3E,29,AE,DC,12,BC,B3,1C,A9,C0,B9,3B,C3,DC,B5,09,8F,CC,17,5F,1B,0A,C0,F0,31,BA,31,80,AC,D2,C5,94,45,7B,7E,6C,20,7D,CE,94,20,B6,41,CE,FD,57,E8,B6,D8,AD,EF,55,AC,70,EE,9D,6D,24,C2,F0,85,A7,01,DB,76,BD,58,37,7A,1C,7D,6B,A7,70,51,49,D9,DB,D5,97,04,71,AE,9D,0F,C7,A4,66,57,05,FC,A5,A7,98,38,BB,1A,0A,53,8D,34,36,96,03,90,0D,50,73,98,3B,13,35,15,99,7E,A4,DF,9B,46,A3,CB,19,B0,3B,AB,D5,D2,C3,54,B4,47,F4,49,77,82,78,2F,D0,C7,25,DB,F9,28,37,85,88,22,5A,96,AF,F9,7A,65,43,A6,5E,47,B0,87,4B,80,5C,A9,DE,45,C3,53,67,6B,F1,54,39,85,51,03,1B,66,9E,0E,5F,ED,64,D8,DF,C6,99,D6,74,2C,4A,5B,18,8B,61,C6,36,E9,D7,54,15,08,AA,51,BF,C0,BD,F2,78,77,D0,A3,E2,95,35,64,13,F4,A4,71,7D,3A,C4,FE,9B,A5,E0,A2,3D,E5,6D,18,BD,E7,57,C8,6E,64,03,C7,66,65,ED,EB,32,60,18,03,1F,E7,16,C5,43,AD,70,1D,67,85,5F,24,31,73,39,4F,02,04,2D,6A,67,E7,92,A9,0C,A4,85,BD,96,79,A1,93,C9,A6,4B,06,9F,3E,AB,A9,92,0E,10,CA,CB,26,08,B8,38,F1,EF,C4,9B,99,C8,02,3B,A6,64,3F,D3,AA,81,76,6A,15,41,45,38,63,D3,1B,CD,11,77,74,01,62,82,06,95,DE,E8,9E,4B,E2,B0,6A,2B,E4,CA,D0,D2,88,8F,B9,B5,D1,78,60,0C,F2,B4,E6,1A,04,7B,45,5E,73,B9,59,45,F9,38,49,09,8D,4A,4A,62,E0,0F,7F,BC,62,1E,6F,24,2A,A5,33,F8,35,B5,C5,0F,26,CC,F0,54,B9,19,7D,F9,97,B9,6B,42,91,3C,37,C3,62,6E,E4,E9,19,0B,68,A6,3D,1C,DF,73,5B,52,A7,14,30,8D,A3,53,5E,92,15,70,01,6A,50,EC,BD,90,4F,0E,BE,E9,B2,72,A5,69,73,07,B5,97,60,12,C1,71,D5,F9,D6,61,85,07,2B,44,77,C4,85,95,F5,7B,68,36,86,0E,F1,82,1F,69,21,D0,5B,D5,46,C9,0D,18,DA,E5,EB,7B,6B,FA,66,0B,A6,62,2F,EA,30,FE,5F,2B,47,A0,C7,88,3C,8F,9A,3F,1F,7F,41,8B,A7,93,72,D1,08,0B,3D,40,C2,1B,D6,08,F4,90,05,FC,40,5C,53,84,04,40,91,B4,32,31,93,8E,EF,99,45,89,74,5F,3B,49,51,FF,D2,B0,D4,4A,93,98,60,1E,6C,EA,62,28,A7,3B,D7,79,AE,07,94,07,8D,3C,D5,DB,29,EC,95,13,BC,D9,04,BC,55,B3,A7,B6,3B,83,DC,34,DE,6B,58,96,61,72,1E,88,2C,71,F4,A4,E9,B3,BD,59,E5,AC,3C,83,D3,6E,9D,A3,FA,51,4C,96,EE,E4,E3,1D,DC,69,95,EE,7B,3E,99,D9,5E,C7,27,DB,32,0E,96,FC,9F,28,2F,EC,CB,51,50,B4,A3,CD,85,D7,A5,D9,30,B5,83,74,C6,D4,3B,2A,15,45,73,16,49,A6,F3,E2,BA,97,30,D7,34,F4,7B,42,A7,EA,EE,0D,8A,4B,01,EE,5D,08,25,EC,02,C8,E9,9C,44,9C,76,DC,B3,FB,21,BA,3C,16,14,9B,73,39,93,A5,AB,12,31,81,9C,7E,15,82,66,52,97,0D,22,94,1D,A3,CD,0E,E7,C6,53,A6,4F,F5,AF,ED,9A,17,C0,65,27,BA,68,9B,AE,7A,B0,35,4F,35,D9,DF,C4,84,5C,A2,AB,7E,5D,73,E8,21,DC,D0,EE,F7,B3,C9,90,93,2D,0D,22,D2,D2,24,74,3F,8F,F0,5C,13,ED,02,D0,17,A8,78,8D,2C,1E,74,06,D8,BD,5E,77,BC,1A,61,A1,B4,2A,81,3E,D7,E8,0B,2C,AD,C8,7F,5E,71,88,F7,D9,32,66,B0,3C,68,F6,2D,97,0A,06,A4,A0,C6,53,EB,2D,73,EE,7B,4B,B8,54,64,DB,F5,6D,62,15,91,0C,B2,CF,F6,D8,9A,86,8F,33,47,2E,6A,F3,E8,56,6C,1F,B7,B9,31,42,42,1A,4F,22,BF,99,5C,2B,33,96,BC,B6,DA,8F,D2,E4,3C,19,66,34,67,44,45,42,63,85,90,02,B6,0A,1C,E8,CB,D8,B8,3F,82,CF,5B,54,8A,F1,A3,46,ED,0E,6E,F0,78,71,F9,A4,AB,41,0C,CC,58,61,F8,7C,7A,E1,83,E8,43,3B,6C,0F,33,FB,DC,24,49,30,7E,7B,85,D6,9B,69,2F,3A,DB,81,AB,15,4F,4B,64,28,18,A1,7C,13,40,FC,B6,08,C9,88,AE,2E,6B,4F,63,60,74,14,2F,E8,5F,9B,29,5F,9A,50,05,F8,A9,27,61,EE,1E,AA,22,DC,D7,F5,46,E2,74,3D,DA,65,01,14,E6,04,77,0F,08,A1,33,10,CB,F2,FD,39,32,4E,3C,74,2D,E2,CB,3C,0F,4C,60,D3,98,85,44,F0,54,DF,67,F3,A4,33,4A,9F,39,2B,C2,37,44,1B,10,08,1E,D7,2F,C2,19,55,9A,C6,8C,D2,5E,5C,29,67,69,AA,E2,5B,96,C4,0C,87,40,0F,48,F2,D8,1E,DA,37,C6,60,93,A6,DE,B7,AB,2E,44,B5,1F,99,92,3C,D5,9C,E5,2C,BB,DB,48,96,B3,22,55,75,85,71,C4,B5,64,8A,4B,19,81,3A,D7,A4,C4,2A,38,FA,95,41,E3,6D,35,E0,3E,B3,2C,BA,1C,7C,28,D2,B1,CE,5A,08,4D,20,0F,86,7D,8C,F6,3C,8A,B7,56,40,C7,A4,50,64,3A,F2,52,24,1E,01,D9,E8,12,F8,91,00,81,F0,23,DC,8C,8E,72,B4,E4,E7,6E,09,2C,04,00,46,F5,10,86,02,E7,BF,3D,39,59,5C,91,5B,C9,B0,4B,06,E1,86,3A,C3,08,2D,39,09,63,7C,91,BB,DE,85,20,A4,50,B2,D8,9C,1A,F4,D4,09,55,02,3F,FC,A3,D9,41,2E,D5,EE,75,B7,3B,E6,B6,A2,BC,BC,3B,33,C8,C4,F3,8D,21,FA,26,87,EB,44,6F,DE,8F,28,5B,E2,92,5B,60,A4,EB,D8,48,C7,9E,1B,F0,F9,C8,6D,F1,C8,77,75,97,EE,0F,0A,C9,1E,E2,80,A1,2F,99,66,39,09,60,DD,AA,E7,86,95,5F,DB,EC,3E,F6,CE,82,BC,C3,06,76,25,22,28,71,FB,AC,E5,D4,77,71,B2,16,DB,2C,1B,8B,B3,1C,73,24,BA,F8,8D,F1,7C,CB,67,F1,A8,92,53,BC,29,E5,DF,D4,F8,5F,10,38,79,38,FF,4C,8A,F6,61,14,58,38,F9,38,72,DB,9F,AB,42,AF,09,AE,08,84,8C,AC,7D,3E,9F,D7,36,38,20,8A,27,49,D7,5E,7B,51,19,5A,29,5A,AF,93,CD,C4,4C,FD,6C,5E,52,C7,4F,06,DA,7E,DD,CB,23,EE,C2,08,B1,A2,6C,18,C1,80,48,C9,7A,48,09,65,76,11,82,D8,21,F2,39,AA,87,10,46,8A,CC,5B,2D,56,D3,0D,05,B7,B4,78,4D,6F,D3,D9,07,9D,F0,41,27,6B,E2,9C,6B,14,84,5B,4B,D3,BF,9C,C0,C5,40,62,ED,E5,EC,98,72,2F,25,22,F8,FF,51,81,54,1E,10,F2,BA,48,81,12,D8,D4,BA,72,7B,7D,54,C7,F1,63,A5,97,E5,1A,65,8B,07,19,FA,09,2C,39,9E,20,2E,EC,DB,50,FC,2A,76,40,C2,06,87,76,45,7C,3F,C4,16,45,E9,F9,DA,6A,0A,90,7E,D4,77,A7,0A,CA,74,9E,91,4A,B5,B5,BB,2F,8D,68,87,4E,6F,D6,E6,23,99,88,D1,ED,93,C7,89,78,DA,5A,F9,6A,FD,62,F9,64,E4,49,6F,30,D4,1B,47,45,1C,A0,3A,AA,24,41,9C,1D,B6,92,B7,D2,7A,42,4C,86,75,5B,29,05,26,A2,8F,1B,C7,6A,3F,87,B0,C8,DA,79,2C,97,3B,1C,B3,BA,2D,93,90,DE,91,A8,9B,AA,35,AA,47,FD,37,35,63,91,C6,8E,22,5A,04,57,AF,21,8D,E1,64,CB,FF,DA,92,47,31,1B,2A,87,73,CD,BE,43,58,EF,09,F5,4E,12,5B,3C,B9,AB,50,CF,14,FF,C4,FD,7D,EE,94,26,58,F9,5A,C7,94,36,2A,62,86,D3,BD,23,E5,89,77,CB,24,5D,EF,BB,9A,E9,7A,C7,2A,C7,AD,89,5E,62,33,91,C4,13,52,C5,1C,02,70,FF,F4,E0,EB,1D,67,6A,8A,AF,D6,68,1B,EE,5C,6F,F7,71,FC,C1,D8,BE,36,1B,06,C5,04,23,EE,3D,B6,17,A2,80,F0,37,01,61,89,63,46,1E,21,16,03,BB,63,9F,96,C2,66,34,1B,A6,8B,46,06,4A,06,DC,AA,F7,84,FC,41,F1,F6,E8,71,3E,F1,F0,2F,6D,D7,E8,B5,9B,72,09,71,35,90,C0,05,8A,CA,86,89,45,78,80,DB,10,DF,40,A1,74,9F,75,5D,CA,08,39,93,8D,A4,EA,36,43,85,31,A8,D3,86,44,F5,36,89,CC,9D,DD,68,D5,0A,BC,EB,A0,44,FA,F8,BB,78,26,40,66,65,21,2D,6F,C0,97,2E,76,16,4F,C2,93,43,E2,83,55,B5,F0,66,02,C3,2D,CF,92,35,3E,21,7E,7B,58,76,85,E7,83,44,80,5D,64,91,EC,DA,4D,61,B7,02,07,93,FE,2D,D6,D9,BF,46,2A,EE,72,06,E1,CF,DD,E7,2A,A9,6E,D2,E9,D7,DE,E1,39,92,C3,0C,62,94,FC,A7,1A,84,61,E7,B7,85,2B,9B,A9,98,F3,5D,C2,A5,9A,B2,68,21,92,50,2D,76,F1,2D,26,88,D8,33,CE,B9,5B,B5,42,1F,BC,B7,6C,96,46,B4,0A,DE,B0,0D,96,07,04,64,D2,BD,BA,21,D9,06,71,6E,F6,FD,97,4E,C3,A4,E1,CB,F9,87,5A,F0,D6,9C,D1,E1,BC,8E,51,28,17,7A,F5,FF,DF,E0,4F,96,8A,FC,EB,3F,9E,E9,8D,07,2D,81,73,AB,2E,E8,A6,DD,DA,38,22,A9,DE,03,41,06,0F,14,C7,C3,90,F2,92,EA,8F,08,5C,19,4B,A0,36,D8,85,CB,F0,1B,F4,C9,9E,21,92,E6,6B,D1,3F,8F,7D,8C,D7,06,46,39,DE,06,6B,B6,96,D6,73,A9,FB,00,38,B4,B3,4E,B8,88,94,E2,D1,EC,67,F2,20,1C,1E,7B,9B,5B,D6,54,78,08,8A,3C,1E,5D,8D,F5,93,A4,66,07,C8,D2,CB,39,81,C9,F9,60,BC,6D,7E,9F,F2,FD,2C,2D,09,26,42,00,19,D3,1D,8C,5B,43,98,75,FC,01,ED,2C,22,EB,EF,11,D4,A6,E6,D7,E3,FC,78,7B,B0,93,61,18,92,91,40,39,6E,46,E1,5C,D2,3F,01,77,29,89,3A,A2,FD,DA,F0,43,BF,96,3D,0F,E4,46,C8,BF,20,FC,6F,0F,DB,4A,2E,8F,BD,80,43,C9,57,DD,C3,12,BB,EE,3C,D1,91,55,1E,A2,42,5C,31,47,9F,E6,65,E7,A9,9F,99,4D,4A,2D,94,AE,37,70,36,E9,D5,02,47,60,B0,55,E6,72,EE,E2,3C,EF,5B,74,E0,00,6A,5A,11,D4,DD,31,B7,D3,65,5A,AD,56,DF,D9,D5,0B,94,99,1E,D7,31,A7,1C,0E,31,10,B1,43,0A,C5,90,EA,AD,03,3A,1B,3B,78,EA,C3,35,B2,D7,B6,2C,A5,3D,19,4A,6C,94,A3,DA,A4,65,FB,E7,DD,93,7B,69,5C,5D,F3,26,0B,32,CC,3D,26,1A,63,2B,A1,EE,11,DB,C0,0D,A2,DF,01,CE,1A,58,09,A4,06,B3,7B,C2,0F,17,D7,37,ED,00,A0,73,29,23,BF,07,BD,62,E9,D3,45,85,F2,1D,AB,C7,66,E4,8D,A4,F6,C4,81,5A,09,E6,BF,50,48,4F,8B,24,0D,47,CE,E3,33,D2,B0,36,5C,BF,DC,11,4F,4C,BA,FF,0F,6F,13,4E,61,9F,E1,40,B3,9D,15,71,9C,43,8B,73,7A,20,A7,15,8A,CB,7F,18,06,D5,8D,AB,AC,FC,C5,0C,C1,A7,D4,EB,6A,77,E1,1D,5D,19,1A,17,0F,A9,D7,33,17,82,ED,AF,3F,E1,39,A5,9A,36,4A,82,96,9D,5C,81,03,9D,21,C2,B8,60,74,4B,55,51,C6,92,B3,8E,CC,23,E7,BC,1E,A5,3E,BF,AB,88,09,4C,24,E2,36,9B,03,38,EE,E8,89,0A,44,B7,98,BA,96,29,4B,66,64,3B,63,B1,19,4C,39,26,D8,C1,7D,DA,DC,7A,DD,A9,73,B1,3F,97,9F,2D,41,70,87,97,18,DE,90,21,AC,28,CD,EB,0A,D1,CD,DE,49,14,AB,C5,69,4D,37,21,04,E4,0C,D6,9E,CE,41,37,2F,4B,40,7E,95,98,EB,22,8D,2B,ED,5E,CA,61,CA,B5,22,61,B6,78,C8,4E,7D,6B,12,A7,29,3A,59,A9,A8,D2,E5,EA,22,00,11,63,FC,2B,9D,B0,B9,AD,54,21,89,46,C1,A0,4B,15,90,3E,05,EC,C9,DA,D1,DF,48,58,BB,36,12,C4,E7,CC,9F,E3,F5,5B,06,B3,7D,15,99,49,01,73,2F,51,A4,D6,3A,98,87,3E,B1,6E,2B,EF,26,B6,84,83,71,93,2A,96,D6,C3,54,3D,5C,C6,48,FC,28,B9,63,E7,D1,E3,C8,57,ED,E3,6C,79,B4,F0,FC,5D,6D,7E,36,DC,47,AE,25,58,FF,7B,37,F4,08,C6,4C,70,2A,67,E7,52,B5,65,2C,D1,2D,BF,36,73,86,4B,86,4F,D4,E9,22,BF,FE,C8,47,24,AA,21,A4,82,0B,99,C7,AB,30,36,E1,CA,F6,4A,67,C1,4E,2B,35,CA,26,A1,99,8C,6C,32,9D,5C,52,CF,7C,EC,E1,3E,C9,7E,7E,A5,2A,39,A6,32,09,E5,2C,1A,D7,83,F2,E5,91,6C,F3,6F,C1,27,9C,15,0A,7E,4E,B0,3E,F5,E7,1D,36,89,10,E1,A7,0D,11,E4,D7,56,2A,44,1D,27,D7,46,9D,D2,73,3F,8C,8B,64,95,4F,67,B8,8C,49,FE,1E,BB,03,B2,0E,08,54,97,6B,2B,5C,56,1F,7C,29,1A,94,87,0B,27,DF,C9,75,38,AF,FC,2A,34,8D,5D,33,C2,D6,48,75,89,63,1A,B2,2B,84,17,BA,EC,16,81,AB,5D,2A,3C,3A,29,60,35,44,7D,0F,71,75,7B,C0,0E,FB,F6,5C,97,AD,22,4C,D3,7F,22,D3,CC,80,87,1B,12,7C,04,96,D7,75,E4,CD,E2,45,CB,51,3D,5F,13,55,05,49,E6,58,1D,64,3E,F7,ED,00,87,94,FE,3B,D0,F4,ED,B3,81,FD,9D,B5,11,B6,91,B6,D5,99,CA,72,E6,66,CD,32,65,26,5F,FF,BB,B5,AD,72,4C,14,A7,4D,28,A0,BE,13,E9,AA,40,5D,82,0A,8E,70,DE,1A,84,71,F3,60,CF,84,B1,8F,CD,99,13,0D,E8,64,F7,03,AB,C0,3C,33,26,4D,5F,4D,6D,13,A0,E3,FE,C0,82,6E,AA,E5,5B,27,BA,F3,8D,19,76,8C,2B,D3,BB,9C,F0,24,1A,3C,73,86,7B,49,47,8F,6B,58,4E,49,D5,46,EB,FE,41,E1,37,48,4B,82,AC,2D,A4,31,EA,FE,F8,23,FF,ED,35,D8,13,C1,CD,9B,3E,A5,B8,75,24,16,2A,C7,EB,7E,D1,62,86,00,2A,7F,2C,6D,A2,9A,C4,F7,74,FA,53,BD,D7,11,EC,68,DD,9E,DF,34,3E,D5,94,D1,CF,D5,AE,66,D8,8D,D5,DB,0D,E5,6E,73,C8,EF,A5,7A,BE,70,DF,27,C9,FE,B8,8B,23,C6,07,0F,78,9B,81,98,E7,A5,97,3D,93,AC,62,CA,23,75,88,CB,D4,BF,B3,32,76,40,06,BD,E5,9F,07,D1,A7,B5,9D,B5,82,FD,DB,B4,B7,48,74,91,E5,3C,71,C6,C6,EB,43,BB,BF,83,67,8A,09,14,73,CC,05,E5,83,A5,92,41,BF,99,48,34,DA,88,35,11,6B,2C,76,C7,54,AC,D0,50,FC,B8,3E,C1,C8,40,C1,C6,03,C8,C2,D1,BF,D4,F6,B2,65,5F,E6,78,01,38,3A,06,B2,B4,AA,18,5A,8B,CB,BD,15,CF,61,53,96,7D,A1,51,1D,03,A4,60,81,14,3B,4D,B3,0A,1F,30,37,A8,C0,BA,3F,BB,CD,9E,A7,CF,60,90,7C,7B,D4,9A,C0,A1,43,0E,8E,B7,74,06,A9,85,31,86,68,24,81,5A,6E,D8,B4,57,60,3A,4A,75,CB,7F,79,EA,11,A9,6A,E3,B9,AC,5C,36,E7,13,8F,D5,60,9A,BB,81,7D,C7,61,6B,7C,DA,8D,5D,8C,3C,4F,35,41,1D,BE,0D,75,AF,8B,A2,5F,37,7C,A1,E5,50,B4,6D,03,72,58,07,00,95,9E,90,BE,4D,79,04,A0,F3,9B,C8,1F,90,0E,66,5E,51,CC,17,E2,7C,44,33,6A,FE,56,17,17,B6,D4,CF,90,00,03,CD,94,65,3D,4C,1E,7D,7B,E2,7E,C7,43,2E,3C,7A,CD,8C,0F,44,4C,17,0D,0B,1C,92,B5,B5,A5,19,87,93,10,CD,B6,FB,32,28,AD,65,39,54,75,A9,A9,A3,AD,16,70,A0,79,87,B7,2A,64,3D,A5,0E,C7,6A,65,34,AD,9C,43,3A,13,E1,44,DE,12,D1,03,6F,A5,1B,9C,72,BF,02,E2,7F,0A,5B,8E,43,54,2B,06,F5,DD,ED,C3,D4,89,21,0B,78,4E,45,2C,BA,8F,F4,97,81,B5,2D,C3,FA,79,63,2B,03,04,46,E3,B6,4E,5D,AB,0A,EE,B9,AE,CF,81,5F,15,E4,9F,1F,4B,B1,69,29,04,41,4C,C1,D6,F1,8C,94,10,DA,B9,2C,E0,35,2C,ED,56,F3,60,2D,B7,3C,BD,76,4F,1A,C3,00,2A,85,32,96,73,37,3F,A9,0A,D5,D6,36,98,43,2C,1D,62,A0,66,82,04,B6,1D,10,88,1D,4F,84,65,49,D9,A7,20,E3,7B,C9,5E,9D,4D,81,7A,61,6F,34,B1,80,ED,14,66,98,A9,2B,05,72,6F,E6,53,FB,D0,6E,C6,8B,F8,F5,B9,A3,C0,70,F0,FC,A6,1A,C5,EF,EF,B7,70,5D,06,B7,D6,A0,6C,02,3F,C3,A3,EF,D0,D7,4D,98,92,69,FF,C2,F3,95,55,FD,3E,13,A1,AE,A6,FF,CB,F7,DE,69,08,AC,5C,2E,8F,D5,29,D7,B1,F0,C5,4F,8D,71,ED,B6,5C,06,0A,BE,E3,AF,35,ED,62,1A,47,7D,D2,26,BA,67,AE,CC,B4,2F,CC,8A,6A,84,E2,E8,DF,8C,77,8F,C3,7C,0C,FE,B1,A6,EB,5E,03,15,E4,1A,FC,3A,C7,80,E6,39,E3,55,D2,F3,6C,BE,EB,BC,6A,9B,5B,ED,97,90,AA,3C,14,C1,CF,B1,D6,AC,05,2D,9D,C0,46,C6,71,97,5C,A4,FE,EE,E7,33,BB,5A,A7,82,33,68,8A,33,68,18,E9,AD,6C,D6,66,B8,40,EB,23,CE,C6,91,D2,07,D4,44,8A,04,5C,7D,36,24,05,0F,6E,7F,27,74,EC,1A,03,88,5A,8A,B4,97,6E,39,16,D0,D1,69,CC,67,F6,12,88,A8,6E,07,2D,AD,77,AC,FF,AA,12,D0,A4,1E,59,38,78,39,FE,4F,E1,C5,7B,CD,11,E1,E2,8B,E6,94,8A,36,E9,9E,6D,71,BC,C3,AC,37,49,BE,09,A3,91,08,B4,57,AA,26,32,E8,C2,34,BB,19,FC,26,D3,B4,3C,CF,9B,56,60,83,6C,15,01,F9,AE,95,40,DB,0E,D5,9C,BD,50,B3,57,6E,4E,D9,48,59,92,1D,13,CC,7D,A8,66,30,EA,78,BD,DE,64,F6,4D,9B,EA,01,59,59,D4,7F,C4,24,31,BC,14,1F,63,51,35,FC,AE,C6,83,C5,17,F9,F1,8A,8E,9A,D2,BE,68,A4,4F,16,E8,DA,40,D1,78,90,3C,26,17,34,17,B6,CD,63,16,73,AC,94,9B,02,CB,BF,04,E9,9E,31,91,2B,B5,96,54,CE,DF,52,D1,C9,63,3A,AC,EB,45,F7,FF,B4,0D,ED,04,93,8C,42,2A,AC,A9,30,AE,8B,0A,A9,4F,14,F8,BA,A5,45,47,1F,43,F3,E1,79,A7,7F,9B,5D,FB,C1,EA,43,00,8D,DA,E6,C3,C9,AD,3C,1A,AF,88,F7,97,8D,B9,37,2D,C2,43,32,6B,69,CF,89,B2,D9,FC,C3,50,13,F3,3E,C2,8D,2E,6A,78,7C,0C,12,F5,89,97,3D,94,C3,5A,5F,B0,3C,CF,C2,F2,32,38,33,C5,3E,97,A7,13,14,12,8C,C6,42,DC,FA,06,05,02,4A,45,A2,09,00,4D,74,9C,5C,B4,1A,B4,EF,F8,64,8C,5E,35,FD,6D,04,30,FC,E5,D6,7F,03,CC,AD,92,64,F0,D6,77,4D,DB,7D,97,5E,14,DC,E6,8A,A4,86,BB,7B,C6,13,89,2F,60,3E,B1,79,58,15,7F,BF,CA,E9,0B,2C,CE,44,CE,75,3F,C6,F9,63,D9,6C,90,C1,44,2D,4C,23,0B,A9,BF,CF,D8,77,D3,94,23,A8,B5,40,AC,E3,1B,CE,48,9A,7A,50,BE,21,C3,BE,8D,12,DB,BE,13,E6,81,21,D2,3B,25,F5,3A,D1,DF,2B,28,8E,59,C8,69,33,9B,A9,CA,D6,36,9B,7F,44,96,F6,81,7F,F2,F1,78,27,69,70,4B,1C,8B,61,40,50,4E,25,EF,99,AF,49,77,9A,05,54,48,5D,D6,34,04,33,19,4C,75,86,02,00,B5,63,5F,B5,ED,12,CB,C1,14,BC,2E,64,4B,93,3C,3D,7D,E0,B2,8F,95,B0,30,98,1D,5F,5B,E6,D0,AD,81,2C,76,59,B5,3E,A4,BF,05,08,51,9D,74,4F,17,79,A6,B7,40,AC,9E,C8,6E,6B,83,0F,55,82,16,A9,6E,9E,3B,63,4F,74,9F,74,D0,94,F9,4E,AE,DC,69,D0,BE,D1,1F,20,52,07,4C,0C,93,0D,29,BA,A0,F3,F6,14,7D,44,E0,42,23,8B,0F,A4,99,67,CD,D4,13,3C,F0,21,20,70,76,EC,33,7F,B0,E2,B3,59,93,3B,07,F4,93,E3,7E,3F,6E,49,C6,D9,46,70,DB,79,97,F2,6B,D2,93,67,5C,91,B9,5C,BD,16,F2,49,AC,E3,13,D5,36,EC,7F,68,3D,14,13,52,C8,5E,62,51,1D,C5,22,77,E4,A3,61,09,E3,82,E4,A9,CA,91,31,F3,3D,B6,2C,BC,AF,AE,4E,E5,BC,F1,43,E6,2B,CE,FD,18,C0,1C,9E,FA,84,9E,8F,06,5C,D0,24,79,A2,88,E3,B3,6F,5D,D2,6D,7F,71,1A,A0,8E,4C,19,8F,D4,F0,C7,54,72,53,B2,A3,E6,36,F8,9F,1F,80,0B,95,28,FC,D5,AA,2F,97,D5,7E,83,8B,6E,98,12,C5,24,AC,F3,9D,4C,AE,D2,2B,50,03,58,95,85,02,CA,AC,F0,0E,1D,E9,7C,57,28,B7,48,37,10,80,A8,17,0B,21,7D,2B,BF,6C,FF,5E,A7,91,6C,AF,C0,74,E3,85,85,36,F2,3C,6D,1C,1D,66,93,B3,63,1E,B9,1A,A1,96,D1,DA,76,64,16,66,94,0B,94,E4,29,C6,9E,C9,85,53,5C,B2,D8,68,8F,43,4A,F1,19,F2,C8,28,18,3C,12,8E,38,BE,9F,F6,41,FF,0B,06,F2,B9,18,DF,7D,41,C5,1C,54,17,62,16,8A,00,92,32,18,D7,FC,5F,05,83,CF,4F,C8,13,0C,DF,55,7F,96,21,B2,54,22,CE,2E,01,28,B6,79,56,23,9E,21,9A,38,99,3F,88,2A,43,6B,79,B9,4E,63,92,9F,AE,C1,F0,AF,D0,21,71,5B,85,17,09,A6,6C,02,92,96,89,64,EF,1A,E5,F9,10,2E,CC,46,27,53,A0,A3,A9,15,C6,53,74,2E,FA,4C,38,2D,6F,A6,5D,C9,26,77,08,9F,15,90,FA,9E,61,0C,8D,B0,95,E8,40,2D,98,13,2C,6B,AD,C1,FC,C6,40,4E,FA,5C,9C,64,6F,15,A8,79,7A,9F,D8,77,FB,9B,19,11,B6,AA,8E,31,3B,6B,B5,0A,F9,87,52,70,43,EC,07,06,0F,DC,B8,A0,24,7B,99,F0,18,30,D3,B5,FC,BB,4E,C9,7A,88,A8,FB,5A,83,F8,F3,3A,D4,3E,16,84,F8,5D,63,F8,6D,B2,A1,F3,1E,67,F2,A1,55,59,1B,10,10,49,8B,E1,6A,67,4D,BF,FD,46,B9,24,0F,B1,71,81,AD,D1,2C,D0,DE,7E,38,CF,99,94,4E,7B,2A,8E,E9,9A,F5,D2,F0,D5,D8,44,88,AB,AA,13,F8,7F,50,57,82,AF,9E,6C,24,29,D7,4B,B6,B4,FC,CD,6C,D3,03,FA,46,56,56,6D,2C,70,40,2F,2F,2A,02,EB,69,35,10,7D,D9,A9,93,92,C6,CA,8C,C2,CE,F5,1A,77,16,53,37,9C,46,BB,63,28,31,20,B9,5C,97,F4,53,87,6E,71,A5,CB,59,27,F9,AF,5B,54,AF,75,E1,79,85,07,6B,2A,E0,B7,FC,7E,B6,EA,D4,94,42,39,BE,9E,CD,AA,78,66,FB,22,9E,3B,8E,88,A2,84,B5,5F,62,E4,51,28,A4,93,1C,C2,A3,5D,2E,34,F2,E8,E8,9A,61,94,0E,B7,C1,46,00,FE,E0,CF,05,30,81,BB,7B,3D,49,A6,D0,BC,72,29,9F,D9,22,D1,CF,31,D9,7C,A6,1F,D4,9A,2D,51,A9,DB,8B,E2,65,16,3B,FF,0A,AA,81,DD,9A,FD,ED,33,CD,D6,83,E9,C5,FD,C8,1F,3E,ED,00,02,F8,5F,7C,7F,34,3C,6C,1E,13,AF,E3,56,9D,7B,9B,5B,72,1F,8F,28,8F,56,0E,CF,53,07,5B,31,6B,0E,32,F2,5B,1E,7D,C8,D0,22,BA,7E,1E,4E,4F,4F,F7,BC,41,85,05,C0,11,F9,ED,7E,9B,53,48,F9,93,3C,A9,00,2C,8A,6F,39,59,9F,FB,C6,20,03,4D,98,11,DA,4C,E0,B7,60,F9,6C,BB,DB,B2,46,6B,5D,B8,9F,8B,B7,80,4D,6D,5B,65,7D,EC,00,96,1F,CA,58,81,65,4A,44,3E,E0,57,91,1E,F1,E0,9F,B5,FC,37,18,15,BB,51,C6,2D,2B,54,4D,C8,E8,09,61,42,6F,DF,61,90,BE,C4,83,1C,51,E5,B1,1D,EA,D7,42,E3,9C,15,01,D0,57,86,2B,50,C8,D9,81,33,A6,AD,D7,5F,55,80,E9,49,BC,D2,49,F3,65,8D,FA,50,33,02,E7,A0,7A,76,94,69,17,F6,0D,52,B0,CE,08,81,0A,1B,23,04,C1,07,BD,36,A8,66,8F,EF,D8,AB,6F,F1,9E,B5,90,38,3D,65,12,FF,05,04,0F,8F,F0,28,3C,FE,54,6C,32,C2,B4,14,64,17,22,CA,11,41,46,C6,27,ED,DE,4E,18,55,BF,97,90,E1,81,EE,D2,3B,DF,AE,01,D4,C9,F5,E0,72,52,23,20,1C,F7,FB,2F,71,FE,6B,52,AB,BB,A1,F1,87,46,74,CF,6D,00,C4,C9,28,AE,5A,FF,61,35,40,BC,89,2A,51,12,52,8A,69,4A,EF,8F,20,19,72,D8,E1,C7,53,3D,D1,96,29,6B,6F,ED,F9,69,CF,F2,AC,5B,00,ED,00,0B,0F,7B,E6,FE,5D,95,78,79,AE,4B,D0,11,8A,FA,44,15,34,AD,E6,E9,C3,5D,6F,7F,81,E0,9C,56,FB,A8,0E,46,96,9B,50,8E,57,55,CB,DE,F0,BE,6F,5E,F8,8C,C6,77,9D,53,83,3A,46,7E,83,24,9C,F9,9C,10,B3,46,BE,72,B2,CD,6C,0B,8F,73,4D,75,F3,8A,84,40,94,5A,F7,46,21,2F,2D,DA,C2,67,42,A4,63,27,AA,73,77,54,93,A7,7F,51,A0,08,E1,C0,4E,B3,5F,9C,57,C4,A3,CE,25,5E,25,BD,CB,2A,D0,BC,F4,A3,48,4A,5D,56,46,F4,DC,C7,D1,F1,E0,B0,75,56,F1,14,31,6B,35,BD,58,76,21,0C,26,77,25,19,28,7D,C1,AB,B0,EF,24,AE,AE,AA,7F,5D,48,23,F2,D5,89,70,6B,D4,F3,7A,A5,66,67,33,D1,06,C0,E4,B0,FB,05,0D,67,CE,7A,A6,C7,BF,0F,62,10,7F,F9,55,81,0A,32,F7,CC,12,60,E7,CE,C3,1A,3F,32,8E,19,36,FB,EB,45,E0,FE,53,45,97,35,87,D6,BE,D5,07,FA,B0,5A,E5,16,38,91,6C,71,B5,B4,31,13,62,E6,8A,75,3F,08,A6,C0,42,F5,23,A0,E9,93,D9,39,B8,64,B5,EA,DC,FC,AF,16,10,0D,40,85,90,24,E5,95,A6,F8,E7,B9,E5,BA,F2,3F,D4,93,A4,6F,4A,E6,CD,67,74,49,74,46,83,4D,3B,4F,6B,76,F9,55,AD,50,DD,E8,48,13,D4,6E,96,1C,71,B6,AB,DC,B7,97,E5,67,07,DE,12,4C,94,BF,B0,96,DD,CA,BE,9F,4D,83,B4,01,06,A0,9B,9C,E7,45,29,D7,35,BE,DF,A9,95,01,1C,1B,58,8D,33,0B,3B,B5,6D,EE,34,FC,89,BD,AB,F7,30,70,69,27,D8,14,A2,32,52,3D,EE,11,0F,62,D9,F0,72,2C,2D,EC,DB,94,55,03,F6,E6,2E,38,6F,66,15,95,E6,DE,B2,82,8A,9E,96,88,39,32,E1,EA,0F,07,1B,78,F2,5A,C6,A6,2A,B2,E5,A2,56,29,C2,B9,E3,F0,88,96,E4,57,E6,D2,75,83,81,36,5F,3C,CC,B6,E6,61,D1,96,10,A4,82,BF,81,B6,47,4D,B8,55,7C,F6,00,C7,0C,35,FD,60,D3,36,F8,80,AD,EE,00,68,7D,A5,19,AE,DE,00,F2,B6,76,C3,DB,F4,7A,D8,D0,FD,EC,08,16,EC,02,06,76,A0,45,D3,72,05,B5,8F,62,E2,45,98,C0,C1,09,C9,AE,E6,C0,33,55,A2,4A,1E,20,BC,EC,01,9D,7A,FA,E1,52,7B,9E,EC,14,2C,AF,41,FF,92,BA,27,70,2A,57,4D,66,5E,1C,02,5D,83,16,08,6C,6C,69,A5,07,CA,CC,28,04,3C,D0,74,41,63,2C,97,B4,E0,2D,CA,80,FD,4D,50,D8,91,5A,81,0D,85,86,52,64,90,5C,50,C9,34,FA,F4,EB,36,7E,D9,F2,7F,6C,DB,1B,AD,06,30,D3,C6,D3,09,70,71,C5,1D,55,D5,04,05,9B,E8,EF,97,9E,62,44,76,6F,82,D6,71,C1,BC,D9,3F,AA,89,83,1A,A5,14,40,CE,EE,AA,35,28,B5,00,A7,27,F6,ED,35,4A,2E,58,60,81,9D,EF,0E,78,BD,2D,50,38,D3,20,8E,80,4D,36,BA,CD,50,59,FA,0F,FC,CC,40,D2,88,69,70,63,FC,4B,D1,11,22,CE,63,2A,BE,B5,23,54,F5,CE,22,C1,8A,AD,87,75,14,6A,C5,61,25,BD,6F,C1,A2,85,06,26,A9,1B,86,77,83,4F,9C,54,C5,32,FE,05,2B,9C,AB,C0,02,AA,2D,84,BE,4B,C0,06,3A,98,FE,47,A2,1D,32,11,CC,45,B0,99,A9,B1,33,67,18,A2,0C,39,FE,B9,32,96,4E,EE,24,54,6F,F7,00,DB,18,53,2A,EB,B7,B3,B0,D8,5D,FE,3E,7E,F3,69,DF,57,58,18,C1,75,A8,52,3E,29,5A,B3,E2,8A,A9,1D,E5,2F,B1,9E,01,3C,76,D8,3E,25,35,1A,17,F0,10,66,B9,CA,84,99,ED,D9,75,9D,1E,44,B3,19,15,E6,FB,88,43,96,AE,74,90,54,8C,7D,C0,D7,C1,10,03,CF,93,C4,F5,BF,13,06,81,D0,79,5C,75,67,FB,CB,D2,29,CC,4E,2F,11,8C,E8,FC,FE,80,7F,3F,BE,67,CF,75,8F,EC,8A,AB,26,38,B8,A1,E1,AD,B3,F1,BA,46,F1,F5,DD,63,A9,49,C8,91,DA,9D,CD,02,74,F7,AA,08,9F,60,39,A2,EF,94,30,D0,60,EA,D7,19,22,AE,CC,88,F2,BA,CC,40,1E,AB,CE,F0,2B,53,A4,9A,BC,C2,18,0D,4E,36,81,D4,90,CB,54,76,FD,74,46,6C,A8,DD,C6,18,05,A7,C3,19,FC,A8,46,D0,1F,D0,6A,42,CE,58,55,03,8C,FF,4A,7C,01,31,20,7D,1F,80,CE,0E,06,29,4F,E7,6F,84,91,AF,AE,57,DC,DE,9E,C6,02,FF,7B,53,4B,C9,32,8C,55,84,B9,BB,31,8E,DF,72,E5,2C,05,ED,AA,2B,E6,D3,0E,53,34,14,07,6F,9C,81,4B,28,38,4B,F1,CA,4E,6F,D8,2A,1B,D0,AA,FA,CA,0A,6B,7C,EC,EC,C7,AD,D1,F4,2F,9A,9C,2A,85,6C,AD,B4,9D,F6,28,CE,B8,7F,31,3B,F7,A4,98,3C,BC,2F,0D,B6,84,71,6E,D7,D5,25,9D,58,17,B1,A4,09,82,B2,4F,F5,86,EB,77,18,3D,9A,11,DC,D4,46,09,AA,A7,D7,C7,61,2D,6F,FC,4A,E0,3D,47,6E,82,03,D6,FE,07,A9,29,4C,06,58,B6,20,7D,5E,25,D7,D0,7E,8C,52,3E,11,5A,3A,6E,10,85,CD,06,1D,22,29,69,21,5D,FF,4D,DF,71,68,9B,B5,6D,F5,A0,B8,D6,8A,80,26,2B,1A,26,F5,DA,90,19,95,FB,03,43,0E,18,E7,76,B8,83,69,CD,B3,F6,01,2E,EB,15,CA,23,31,E5,2D,27,A2,C5,79,BA,06,73,20,03,C6,15,4E,05,A7,DF,52,CB,E6,02,62,3E,DD,DB,74,14,D0,6F,B4,C2,0E,6C,EA,5F,4A,1A,1C,42,36,00,10,8F,9C,72,11,B2,E6,3F,3C,83,CC,7D,FF,F5,81,00,CF,D1,B2,E9,6E,7C,52,F6,37,AB,A9,E8,91,B3,22,D4,10,B1,1C,94,09,4F,A5,DC,07,34,E1,A9,36,0B,8B,97,B5,FE,97,04,EF,CA,2B,7B,89,37,EA,CF,87,CC,CC,01,2F,84,3C,7C,BB,25,2A,40,07,F6,69,84,9A,DC,43,7B,B1,FD,18,2D,24,EA,49,A1,4A,11,6B,58,16,2B,1C,FA,7A,66,9D,63,DC,AD,5E,88,C4,88,41,88,B9,B5,3D,7F,F1,A2,43,E5,44,2F,C1,A1,86,E8,BE,A3,D9,17,00,E2,2E,6C,73,4B,9E,B1,4E,57,B9,69,22,A9,E1,66,79,76,83,33,35,49,DB,7C,73,DC,CE,93,87,E2,9A,EF,7D,E0,22,A7,02,35,F0,BB,C5,4A,C6,37,5E,F4,A0,EE,B6,6F,46,B2,07,0A,FF,28,37,16,9C,DD,B1,F4,29,A0,2B,86,5A,9E,9B,E5,F3,C9,46,53,C9,0F,BB,44,70,39,08,CB,86,72,81,6C,AB,43,7E,7C,CC,5F,46,8F,97,08,C6,2D,E9,E1,CC,FA,FE,5C,E7,EF,74,7F,CB,74,7C,23,A6,4D,B1,A2,0E,E6,6B,82,78,20,33,37,FE,DA,45,CE,06,AC,79,C0,72,2C,7B,32,38,BF,61,C3,02,F6,B8,0E,7B,AC,05,A4,2D,A5,98,CD,02,CA,D1,30,C4,96,97,8C,00,8C,85,5B,40,29,55,E3,F4,B8,0E,9D,4C,4F,0E,5D,38,11,56,81,BB,0C,7C,26,A6,02,E2,61,DB,21,46,15,C7,4B,97,8A,FE,04,FA,52,97,57,09,1E,1A,1A,25,EA,96,42,6E,B7,36,8F,F6,3D,EA,22,FA,85,30,F9,79,26,EB,5F,7F,3E,5F,17,B0,41,4A,89,B9,15,96,DD,E7,17,DE,39,14,94,A6,DA,3A,D4,82,10,5F,18,52,FC,61,01,74,02,DA,EB,C2,EE,3E,0E,AA,71,E9,5F,CB,B7,DE,47,D3,EA,C8,8E,3D,93,CF,4B,70,9D,86,4B,70,5E,5B,3A,C6,4E,E2,74,5C,C9,98,68,5D,8F,2C,B3,F0,87,C2,EF,E5,45,E5,EA,24,FA,DA,43,89,C0,F9,49,8F,1F,C1,3A,B3,1A,40,0B,3B,C1,3F,75,31,50,06,49,93,C2,ED,EC,C6,9B,05,60,A0,9F,8C,3F,59,90,F9,6C,64,B3,55,22,94,1B,00,E9,68,9F,59,5B,89,28,E1,A5,88,98,1B,5F,92,22,5D,14,66,57,E5,28,79,83,6F,02,1C,37,EA,F5,0A,CC,C5,A6,8B,70,57,56,1B,64,BD,FC,EA,BF,06,3E,FA,22,67,D7,40,2E,AC,21,D2,8D,87,E7,BE,BD,8D,22,C2,19,F5,60,6A,03,69,A5,A9,7E,89,D5,91,10,80,C7,0A,6B,D6,95,2A,50,88,9C,5F,F4,49,9B,6C,C4,1B,97,45,77,A3,BD,55,A6,B1,A1,25,12,B7,7A,0C,8C,AD,BC,FB,42,50,5E,45,36,51,95,77,F7,41,85,2F,D6,A9,81,43,2E,76,AF,05,22,E2,26,56,F7,E3,F4,94,24,E5,50,1A,38,E1,FA,47,A6,F5,2E,2B,5D,2F,F6,DF,A4,FF,74,9B,89,39,F0,B1,B9,04,67,5F,86,77,39,C7,ED,99,F3,BA,7D,66,20,63,83,61,17,46,A6,0B,B2,8F,95,46,EF,D8,98,B3,67,0A,26,99,34,2D,AA,29,82,96,C4,03,65,7F,DD,19,CC,7E,4F,7B,88,D0,BE,C7,65,67,9C,7F,77,62,F1,87,1C,FA,BE,B4,7F,F7,DC,34,24,88,28,F9,14,78,DE,AE,52,99,DE,3E,31,05,39,A4,E0,7F,76,E7,16,7C,0F,EE,06,7D,6B,B2,AE,C4,C3,65,F4,12,C8,B2,25,E7,32,56,80,C1,EB,43,DC,E9,34,16,FB,1B,A6,B0,61,AE,9D,A0,2D,90,6F,C2,39,30,02,91,F8,C7,D8,A7,17,9D,62,8D,E6,66,D3,41,2F,DF,F0,56,8D,D4,F8,3B,7D,27,B2,E6,34,63,C0,66,DA,BA,92,E4,7A,17,98,EF,A8,83,3D,18,12,34,79,AC,59,5D,C4,45,C6,24,D8,61,32,F0,31,60,1F,FB,96,7C,B8,FD,7F,4F,78,EB,E0,2C,32,99,F0,24,B9,E6,5F,17,AF,8A,60,AC,F5,6F,D0,CD,27,2D,2A,CC,87,15,31,12,E8,0C,68,C7,D8,80,CF,AF,B9,5A,4E,EE,2D,09,7B,9C,9C,1F,91,4A,80,19,28,9F,99,07,21,92,79,CA,B3,D6,49,B4,DA,FD,CB,3D,AC,72,1A,99,BF,CE,CD,0B,94,6E,2F,53,15,A5,B7,55,27,15,14,C9,D9,E0,D6,A6,BF,3D,39,EB,45,E0,65,E3,CE,47,05,F3,8C,F3,62,62,14,18,CC,3A,EC,03,5E,70,DF,52,2C,F0,D6,AC,49,46,41,BE,D2,E0,C1,43,CD,F3,E4,50,50,B0,A6,60,B1,D4,56,49,0E,19,61,5F,95,5B,CF,48,CF,99,86,A1,B9,2B,DD,73,B1,5A,DB,75,AA,51,81,01,14,29,DA,49,10,DD,F3,C8,B7,E8,C2,F2,91,29,72,04,EE,53,AA,4A,15,8E,8C,5A,F6,71,5F,DE,D4,ED,A2,2C,0C,22,02,70,A1,EF,D7,DC,F7,83,C9,C3,DB,18,CB,3F,F6,8A,AB,9A,A9,92,B5,70,94,C1,43,57,71,CE,D0,9C,30,54,7C,78,B0,01,CC,91,07,CE,E5,CD,35,0E,68,AB,BD,36,57,9B,B0,F2,16,58,56,40,EE,87,B1,E2,CD,F9,AB,05,18,F4,F5,CE,42,8E,25,98,F5,62,C6,74,BC,47,EB,1E,26,80,41,A7,38,4C,6A,3C,D7,32,9A,DD,9D,E2,73,04,6F,9C,B0,EF,09,28,D4,E5,79,DE,BB,38,7A,37,14,9F,7E,92,EF,C3,3B,BA,00,F9,3C,0F,27,5E,3A,7E,01,72,4A,2D,77,01,60,AF,80,30,10,3E,75,DB,18,08,E7,6E,32,65,1B,6E,99,52,52,14,54,C9,12,5A,92,8B,53,06,AD,1E,B6,D0,B2,F8,0A,B7,2B,EB,74,DF,27,6B,5B,A5,51,91,BE,AA,BB,84,F8,04,22,6D,4E,39,8C,E5,AB,C1,77,BF,56,75,DB,0C,ED,96,56,65,0D,44,04,45,19,16,F9,A5,F9,6D,2D,2D,FE,6C,69,DD,F3,4E,AF,FF,03,EF,FC,D3,00,6C,D3,62,03,F1,D3,BB,53,3B,75,09,77,B0,D8,0B,C1,EB,DE,81,80,65,34,E1,25,8E,B1,69,BB,0C,1C,B9,36,B6,FA,58,94,05,6D,9F,2C,FE,F2,A0,06,57,67,5B,A8,ED,F9,B4,FD,38,2A,D4,1C,E6,00,5B,47,8C,FF,EC,8B,D7,2A,AA,C7,DC,E8,1F,B8,EA,0A,B1,5A,A2,6C,4B,9F,59,E2,1C,89,1A,7E,15,84,70,0D,30,58,CD,D8,8C,71,13,9F,F2,F5,E7,8C,4E,E1,19,C4,D6,97,00,62,78,E0,E3,58,0D,61,91,2E,BC,AA,03,D6,5A,D4,15,F3,B8,B6,97,62,62,9C,45,80,C0,70,6F,73,68,50,71,9A,89,48,53,66,73,4D,77,90,34,3E,DB,74,23,36,AD,C4,AB,C1,64,25,7B,26,EE,4B,63,B3,72,6F,CE,4C,30,8C,21,AE,D5,A4,BE,0B,85,E9,B4,98,D4,46,33,2C,31,14,CA,FA,A9,56,34,9B,33,FB,C1,5F,BB,8B,39,28,00,65,D9,BE,C7,22,91,7E,42,43,A5,25,C9,26,BD,88,E3,76,17,33,74,4D,0F,32,A2,C5,64,56,78,4B,D2,7F,87,A2,9A,7C,14,AF,DC,B4,78,5D,58,FF,B0,C9,74,30,E6,81,31,7B,64,1A,5E,A1,B5,87,49,82,08,FC,C0,9E,0B,FC,88,52,F0,FB,BA,0E,B9,2A,FA,AF,4A,82,AB,B7,E3,9C,E8,5F,87,C3,00,1A,62,78,DA,E1,F8,22,0B,E5,F1,E7,A6,FC,FE,29,BA,44,01,EA,D8,C8,4A,5F,6D,6D,4D,68,B7,43,95,84,35,67,8C,53,12,40,7A,5B,F6,C7,66,A8,02,8D,52,CC,43,7D,57,7B,CA,F8,08,E5,61,40,88,27,CB,11,B2,FF,DB,B0,1F,9A,C5,A3,44,B2,EC,3B,B9,B5,DA,A0,AD,37,4D,84,E1,03,AD,4F,F0,D5,CA,CD,3C,81,5C,F4,0C,4C,4C,6E,01,4F,C3,95,BC,82,45,AC,F4,F6,84,4B,FD,73,F8,54,D5,B2,4B,CC,B2,A7,0C,FE,EE,D0,D9,E6,DC,D0,8F,29,CD,C9,B7,FC,6D,0F,33,6E,B5,A9,AE,FE,48,86,37,98,AA,97,B1,C9,16,85,BC,71,94,CA,52,14,7A,28,DE,7D,B1,FE,FA,A0,12,6A,D1,83,6B,5F,E8,9E,B4,A7,89,85,20,71,B2,51,AC,3D,18,CA,6C,83,0B,68,E7,6F,F6,96,29,01,43,7C,AE,E1,42,DE,A1,41,D5,59,50,C2,0F,0B,5F,0B,8F,B3,AD,12,A5,85,EF,D8,91,B6,C7,24,3C,9C,1A,71,6A,1B,26,2F,48,26,D4,29,84,C0,7D,B0,51,33,43,B5,EA,83,C5,8B,CC,7F,99,AC,90,50,4D,77,D5,69,D4,F5,3C,D3,8A,A1,26,00,E0,AD,F3,42,85,D9,F1,06,6E,A3,18,BE,56,74,5E,FD,35,38,57,A1,F6,C4,AE,CC,D7,4C,2D,99,61,F9,89,7B,C7,F9,D7,64,6C,16,1B,96,C5,2F,D8,86,AE,FE,34,07,E9,E2,32,15,2B,D0,CB,77,AF,1E,7E,98,16,0D,B5,20,68,5A,BF,D1,E2,0B,37,8E,AC,B5,0F,A0,CF,63,15,DC,81,F3,AF,F7,A7,18,2B,E8,7E,C4,33,36,2B,B0,B6,63,A6,A0,60,1D,11,32,13,94,D9,D7,26,AD,9B,FC,89,6D,4D,FB,0D,9D,44,E7,E8,61,99,16,24,26,FD,64,0F,51,D2,41,0B,BC,9C,7E,89,4F,68,0B,72,D4,DC,72,97,29,E7,E1,2E,4F,CA,B2,6A,8C,34,E8,2A,BB,52,42,CA,69,A9,C1,2E,AB,E7,45,3E,00,DF,40,97,7E,F6,5B,1D,92,5B,2E,E8,21,E5,70,5A,54,8C,2D,A2,AB,27,EA,1F,8A,8C,4E,E6,56,57,89,B6,26,0D,57,6C,FA,9A,AD,67,45,F7,D4,C4,46,10,9A,B6,47,4F,CC,8A,97,7E,73,88,E1,EF,CB,64,43,94,CD,80,00,0B,5A,56,1B,E1,92,73,10,5F,13,24,B0,B3,53,72,DA,E0,D6,41,81,22,9C,8B,C0,70,F1,70,08,D0,DE,3F,2E,61,5A,4C,42,76,EB,0C,FB,67,27,1E,B3,8D,06,35,E6,EA,7D,5D,98,4A,97,FE,42,13,DC,E3,48,85,90,FC,1B,89,71,F0,19,4C,3B,D9,03,31,7F,A0,32,39,5D,42,2A,BC,40,3B,B2,A8,2C,C5,58,CF,31,54,4B,85,AD,51,E0,84,02,B9,98,53,32,92,4B,78,3F,14,54,2C,25,CC,C0,71,88,39,19,7E,EF,E6,50,0F,E2,B8,74,96,E0,47,BA,10,1B,09,D2,E4,E4,50,F9,6C,D2,B4,9C,85,30,15,04,79,34,C7,24,56,8C,F5,B4,C5,DC,23,22,3F,60,2A,E0,BF,84,9C,85,34,88,A6,51,CE,D8,60,20,FF,BB,A3,8E,8C,C7,6E,DE,4A,D6,0C,4B,09,37,52,F2,74,E1,6D,D0,DA,88,3F,49,8E,B8,9D,9D,BD,73,10,E2,D3,E1,47,28,72,6B,64,0A,73,CC,A2,AA,A3,17,57,24,04,91,87,B6,F9,FD,08,94,D7,7E,7E,1D,5B,2A,A9,15,68,FB,79,C9,25,4A,B3,75,71,BF,11,B3,2F,F7,9F,CD,5C,CB,77,A3,D0,48,4B,F8,52,24,A3,C9,2F,34,4F,FF,55,A9,89,A0,8D,F7,9D,BA,AA,E6,CC,37,B9,98,A0,34,64,19,A3,15,BB,EE,43,AC,AA,E6,71,A9,4D,B8,B1,91,C7,BF,27,FA,D1,05,D0,65,B7,EB,2D,60,50,E7,D0,07,3C,71,33,40,83,22,21,2F,C5,92,9B,B5,BF,07,33,5E,20,07,04,26,8C,32,E9,73,73,D2,90,F2,D5,06,55,50,AF,7D,C6,49,99,F5,C0,80,BA,E6,8D,B9,77,59,5D,0A,5C,6D,CD,CC,03,65,CE,EC,9A,A6,D2,AE,B5,8C,75,A5,DA,76,1C,34,75,ED,3C,49,45,4B,BE,75,CE,E3,65,3C,78,48,26,36,C8,F1,7C,70,09,57,F2,22,2B,EF,DB,DB,6E,97,AE,7F,04,7C,4E,36,71,1F,0C,DF,E2,D6,F4,C4,8C,72,13,3F,CA,34,A6,01,5B,8C,5A,AA,EC,85,86,20,70,80,D9,C1,27,1A,4A,A5,16,6D,F3,16,6F,76,8B,A4,02,2A,BE,D6,FE,31,F8,46,B4,29,E4,55,8E,AF,90,85,3D,0A,90,E6,3F,D2,2D,7B,37,97,86,13,A6,83,CA,A4,A3,3A,87,5E,1F,C7,C9,D5,A0,4B,67,23,C5,53,63,9B,C6,26,3B,82,E3,70,F0,F2,1B,50,7C,BC,39,C3,BC,2B,D5,45,99,7E,3C,19,C8,5C,CE,FC,84,51,8D,97,D2,60,76,E5,E9,39,99,ED,1F,5D,7C,47,9F,E5,44,F8,29,94,7F,C8,D6,FA,B5,60,F8,F7,2E,A7,12,A5,95,A3,56,32,ED,7E,E1,E3,50,9A,30,A7,C9,AB,74,9A,C9,BB,86,54,C6,A9,DF,52,B1,7F,A6,92,DA,F6,30,F7,4B,AC,52,E6,C7,EB,96,F3,F1,01,B0,D1,76,E8,28,2B,02,41,87,66,0C,4A,98,82,F8,97,68,B6,31,BF,92,F9,74,67,7A,66,D2,2A,5D,45,44,C4,D6,50,4B,8E,C5,BB,F6,3C,E2,27,DE,74,27,B3,8B,C7,1C,48,FD,8A,D9,BF,57,45,F6,2F,DF,A5,7A,7E,9C,97,48,32,C2,9E,4C,19,79,B7,3B,4A,D3,1C,A1,7C,F6,1B,B0,D8,8D,91,A8,E6,1F,FC,38,44,C9,B9,B4,D6,D0,13,34,74,7C,C2,A3,5E,90,D5,A5,D9,C3,0B,FB,02,C3,76,FE,62,51,CA,E7,B5,71,87,4B,63,7D,A9,24,F9,6E,F9,4F,21,08,09,7C,3E,0A,7D,28,0C,A9,C0,66,78,49,96,B2,B7,6E,7C,05,3B,77,70,3A,03,F0,A6,62,93,C6,45,1F,50,F3,38,DB,98,47,58,A2,DF,37,5A,14,12,35,34,3D,F3,F9,F6,8B,03,FE,9A,C4,31,0C,DB,09,8B,8F,A5,25,54,C7,41,64,2E,58,D9,53,43,37,DD,74,A7,C5,00,68,B6,89,8F,45,29,3D,C4,10,A2,35,E9,2B,0F,71,9B,48,7D,58,95,C5,56,1F,51,BA,33,EE,93,D3,63,C8,14,9C,F6,96,90,65,5E,35,16,A6,AE,71,20,4E,10,65,9A,D9,F9,5A,AA,F4,06,96,B6,96,CA,47,CD,4C,DB,DA,10,DC,6E,08,D9,D0,64,88,32,8E,EE,DD,F1,F6,88,1C,2A,39,80,8D,C4,E9,1F,D3,C9,FA,61,78,57,98,3A,6C,2B,31,86,DF,C3,56,21,89,90,8C,5C,6B,94,69,DF,B7,96,00,8E,7B,08,5A,F4,4B,AC,5E,6D,6A,EF,11,45,E8,7C,87,2B,48,D9,2A,C6,78,58,72,AE,2D,10,39,98,6B,10,90,D1,2B,2E,D1,A1,4B,F1,B5,44,DD,66,6A,C2,55,CF,56,52,78,8C,54,71,8B,AB,7A,76,BE,12,AC,F0,58,23,76,08,F1,BE,93,46,42,08,8E,FB,03,6A,63,5F,1E,23,CF,03,E1,78,3B,8C,27,47,AA,9C,9C,B4,62,FF,A1,D9,D5,EB,57,41,0F,78,11,10,BD,1A,AD,72,C3,AB,9B,94,54,3D,90,03,3E,EF,8D,65,6E,F1,F2,B7,3E,91,59,2C,50,29,CB,3B,4D,2A,21,CD,65,AF,00,0E,7E,73,69,2C,4A,B5,10,27,80,9F,34,48,E8,70,1B,C2,BC,82,98,B1,44,A6,4F,3E,1D,5F,0B,E0,74,82,52,5C,48,91,9F,E6,68,FF,1D,1F,06,F8,B5,0D,2F,84,9E,48,36,CF,B5,A7,F1,B7,D2,8E,5A,20,A4,D4,DF,92,62,C9,56,B7,6F,CC,5F,4E,D5,06,85,A8,87,0A,BD,C9,A0,19,3D,45,F7,67,0B,89,21,36,C4,FE,6C,D7,47,89,F4,20,7F,FF,55,D6,57,41,7B,5A,9F,9B,90,CB,27,A9,F0,33,6F,14,A9,93,90,3D,C8,21,03,B7,10,84,E4,A5,D3,BD,4A,C1,15,A2,91,57,CF,8E,BC,76,2C,2E,C7,67,77,F8,1E,81,DA,62,45,60,49,31,EC,88,A2,7D,85,DA,60,B3,B8,55,AD,1C,E8,32,0A,CA,73,F2,13,72,D4,CB,98,BA,4F,A4,EA,12,47,69,6C,84,40,A8,C1,66,F1,A4,C3,A5,FE,4A,9D,99,3F,82,91,02,1C,14,06,EB,72,9C,69,EB,AC,D6,30,65,78,FB,5A,F8,8C,34,E3,7C,F3,AE,DD,30,68,E7,C4,39,6F,29,B4,58,BC,44,84,10,E8,B1,C5,73,2C,9A,68,08,A3,90,0F,25,7B,D6,9F,A0,3E,9B,42,B9,36,A8,7E,80,4C,65,B3,30,65,D4,BD,04,9D,E4,5B,5B,BE,98,5D,61,66,88,C0,71,76,00,B2,D1,55,D7,E2,AE,35,5B,AF,43,E3,0F,C6,63,1B,47,12,0A,9F,56,12,BA,45,FF,B9,4A,E6,D4,D1,F8,1A,43,94,C2,09,24,F3,39,73,5E,8D,C2,82,59,8D,18,6A,56,A8,75,6C,6B,E0,4B,62,FC,01,52,4F,6A,C6,E3,F7,52,F6,E2,C4,B3,8C,4A,96,1F,4B,04,D0,5A,3F,E7,67,7E,EC,E7,E6,1D,80,06,1F,20,48,D2,9E,2C,C4,22,AD,73,F3,41,1B,14,18,3C,D6,E4,35,58,1D,55,FF,85,A2,B7,CD,29,FF,A0,88,2C,0C,D9,92,B6,E1,C0,E5,76,05,09,63,76,0C,0F,FD,DD,25,86,7B,0F,0E,D7,96,D8,17,89,AF,24,12,93,78,6D,A0,24,65,DC,28,34,67,E2,58,12,CC,FD,21,6A,E5,07,84,BB,37,BD,19,7B,2B,68,CC,9F,9F,2E,A6,C3,40,CD,4C,EE,66,9A,51,D7,E0,06,22,EE,88,DB,E2,84,9F,01,02,48,CF,06,02,A3,D6,35,04,4A,67,E9,A2,29,BA,FE,20,BF,4A,6A,24,C6,E8,3B,3C,8A,8F,5B,BB,AF,74,38,8F,B2,AD,21,78,B5,24,A7,28,79,EB,3F,BC,A1,E9,92,57,AE,F6,D2,F0,D4,C7,F7,06,5E,73,D0,4E,65,BD,29,61,34,EC,81,C2,E0,76,2D,CE,7A,D2,81,E5,A1,F1,D8,FD,95,AA,15,EE,AD,B5,EB,18,4C,A6,6A,7F,51,CD,15,3B,97,55,CD,72,8B,EF,15,70,F8,C3,E9,BD,65,34,20,67,A5,DF,6F,1F,99,DE,34,9E,0C,57,2D,4E,75,95,F0,EE,DE,DB,76,7A,EB,0C,2B,95,B1,29,FB,34,E8,81,76,21,46,F7,63,B2,EC,1B,C5,55,A3,A1,3C,2F,F5,D7,36,53,F7,67,7F,B9,92,BA,DE,32,F5,E4,4E,FD,F6,53,10,18,7B,09,B8,6A,14,CE,9B,B7,EE,00,76,D3,53,C7,D8,F4,EB,AB,EB,99,FF,85,A5,B5,99,FC,DC,A4,9D,1C,A6,08,8E,61,A1,E3,D2,27,F5,AC,95,05,B5,5D,45,80,78,FD,4F,80,0A,55,5D,5B,3E,AA,DD,E2,CE,1A,C0,CA,4A,5B,21,04,FD,9C,6D,C1,A9,06,E1,3E,42,85,A4,B5,C3,B5,18,4B,56,5F,D2,00,4E,79,A5,87,44,ED,FE,56,B0,E8,F4,DF,FB,C9,F7,10,C1,9E,C0,D6,8B,E4,12,AE,30,63,01,A6,0E,23,A3,44,A5,E9,BE,5E,84,2D,7A,A0,3E,26,78,9D,8C,7B,DC,A5,EB,A9,C5,05,D0,33,36,01,99,B4,7C,53,CD,C9,03,42,5C,65,58,84,C5,4C,B7,16,6B,EA,33,ED,1C,9E,0C,8E,31,11,F9,F6,D1,EE,09,28,85,69,E4,7F,1C,4C,6E,B1,9D,E8,AA,14,4F,19,2A,E5,2A,26,35,07,15,F3,BA,1C,B7,97,6B,07,EF,00,59,94,5E,11,93,B3,20,22,CF,80,7E,2B,F0,47,4A,A9,F8,1E,A3,7D,D0,76,F3,E6,4C,6F,7B,67,CF,12,B5,F1,28,CB,61,AF,19,9D,86,08,79,A4,75,A0,0C,DB,6A,54,53,10,E6,FF,27,24,7A,EF,52,E9,53,09,8C,37,85,D8,0A,19,35,F9,04,1D,88,7E,96,19,3E,08,0E,B8,AA,CC,6E,25,20,18,23,65,4E,F1,F0,C5,99,FB,E0,95,C4,3F,2C,C5,8E,47,7A,9A,83,AF,7D,52,42,DD,9F,62,A7,79,14,42,AF,15,2B,0A,4E,F6,30,EE,E7,70,D4,09,13,AD,D0,6E,96,CB,AF,5D,93,BD,10,68,D1,09,80,91,82,03,1A,2A,F5,04,40,97,D6,C4,3D,C1,EF,44,FB,11,CC,4B,0E,B1,D2,57,DB,6D,68,DF,C1,B5,56,DE,88,EF,57,31,A8,A7,2D,83,04,F6,6D,86,84,F3,11,76,6F,AF,7B,FC,49,1A,FF,4C,1A,39,B2,9C,27,1B,FE,78,A3,C5,54,D8,2A,A6,95,5E,6C,A4,4B,8F,EB,B2,B8,D9,44,12,A4,7B,C4,1F,D2,AB,18,A1,F6,E2,8E,73,A1,7C,FC,77,7B,48,98,52,F5,62,88,4D,EB,03,B4,3C,00,A8,BB,EE,EF,C9,15,05,B1,A0,4D,AF,2F,D5,1E,EF,D3,4D,EC,B1,40,C8,53,08,F0,98,0A,F5,C7,90,E8,E5,89,B1,7E,3A,4F,17,CB,01,94,17,21,07,6C,FA,C2,C6,47,DF,60,2C,9C,D4,C1,47,37,12,AF,C1,6A,51,4D,07,1F,EC,DF,FE,08,9A,31,17,6F,5D,AC,49,7F,09,1B,42,75,84,57,F3,96,0F,82,7A,41,59,84,29,3B,5F,66,E4,F6,05,38,A0,3B,05,C6,F0,58,8C,63,69,04,2A,D5,D7,80,35,A1,D9,5B,23,C9,82,10,C6,3E,FD,14,ED,F2,F2,92,F4,E6,A6,4B,41,DD,4B,23,07,3E,58,03,57,33,B4,69,3F,05,8E,50,F2,C4,A9,2C,F7,31,06,AA,F6,26,B1,30,BE,48,B7,04,E3,8E,E8,90,32,E4,88,66,30,70,58,D2,05,3A,9C,55,DF,BE,59,1E,E2,72,F7,8C,D2,DC,38,74,8B,07,48,56,1B,33,6E,0C,6A,6A,CF,B9,26,0F,89,AE,F4,34,3C,CC,E9,C8,F8,F6,FC,F1,3F,9E,EB,57,C7,62,28,C7,13,F3,F7,23,E0,71,24,08,01,5D,A7,9D,3A,5F,C2,41,44,7B,00,E8,A5,CB,1B,48,03,91,00,0C,77,FD,48,DD,03,9D,AF,72,83,D1,BD,F5,42,5D,F2,AD,8E,D9,B7,33,54,5D,79,40,44,FE,21,27,B1,05,7B,4F,CA,98,F2,F3,93,3D,77,2C,28,C9,FB,C4,F8,8A,84,75,79,93,FB,94,40,82,1D,B4,D0,E4,56,D1,A0,B4,E3,C6,5B,05,AF,D2,AF,00,09,AB,38,E3,14,D3,A4,63,72,3B,7E,18,6A,81,70,F5,44,42,5E,B5,71,CC,FE,B7,DB,1F,A1,B5,0B,64,68,66,12,83,91,24,C3,76,E0,2F,13,8A,38,24,A2,27,66,09,99,54,DF,A4,FB,1F,CA,66,BD,A5,89,11,E3,E5,8D,49,D0,68,DE,58,0E,B5,0A,D1,A7,73,61,CD,93,92,94,FB,17,BD,C1,59,07,E1,CB,9D,65,40,E4,DE,D7,15,24,56,0B,02,CD,06,93,62,58,47,86,93,8D,19,8B,A5,55,73,C6,E0,FF,CB,81,B2,28,D0,80,1B,12,43,45,BC,A3,14,0A,1D,F8,0D,1F,F0,B4,85,DE,2A,78,84,1B,A8,C4,E0,95,DE,1D,F0,67,44,FB,74,BA,FC,23,BA,B9,75,C3,72,12,A6,47,1C,D2,7B,30,20,4D,36,B5,5C,FD,19,BC,C0,E1,F1,57,61,67,5F,E0,CA,F0,A9,5D,D4,0C,73,5D,3D,BA,64,E0,D9,19,C0,36,E0,9A,50,B6,0C,0D,47,7D,E7,4E,D2,B2,7F,BE,4D,41,96,B7,40,51,29,99,C8,81,B4,3E,BA,91,81,D3,BF,1F,F9,A6,29,9C,A1,7D,58,A7,68,D0,CA,3C,6A,56,B2,A8,AE,24,20,FC,DE,0C,1F,8E,94,3B,FF,6B,DA,61,CE,0D,2D,61,FD,CB,8A,BE,09,1F,03,9A,86,DB,FC,E0,66,80,62,07,16,68,7B,5E,A8,7D,B1,B1,47,31,96,15,31,D5,C9,20,62,B4,32,72,E8,06,F7,F3,AC,29,31,3D,86,24,34,88,D0,12,2D,67,95,79,5F,2B,8F,E6,AA,28,85,B4,5C,45,A7,24,5B,77,33,AB,93,57,EC,BE,4A,34,A5,6D,3C,93,FA,6B,17,26,14,E2,51,5E,95,47,35,0C,27,5B,A9,01,40,D8,A4,B3,C3,54,BF,4E,C2,45,20,5E,BA,6A,DA,AA,B7,E9,F2,01,6A,0F,1F,9F,53,3D,3A,28,8B,BD,77,3D,1F,07,00,BB,D4,B3,97,A5,E5,9B,C7,BA,6E,20,3B,94,E7,90,35,8E,34,BB,FB,94,AD,53,B6,A3,6F,F3,66,FA,38,05,50,2D,9D,8A,CC,41,24,7E,EA,E3,A3,54,E7,C9,BD,CE,32,78,54,51,33,DD,C7,AE,05,CD,9C,E5,F0,3A,DD,45,97,56,C8,2B,85,A9,34,83,55,2C,46,02,D8,E5,91,98,03,42,EC,D4,99,AA,32,1D,9A,4F,C1,D6,73,21,32,AC,00,C7,BC,3A,03,16,95,85,C3,7B,80,3C,34,F0,03,1F,47,93,27,D1,58,E1,6B,08,26,C6,07,C2,3E,A3,0C,76,39,D2,C6,A7,44,A3,50,13,74,7A,61,A2,04,B0,DD,37,9E,FD,ED,79,E9,F5,A3,3B,05,07,4C,AF,4B,60,8D,18,CB,31,80,3E,46,B6,E2,C1,5D,D1,FD,4C,46,50,93,D7,32,AC,C6,1D,F8,A4,19,5C,5C,98,75,E1,F0,7B,5C,3D,8E,16,50,95,96,D3,C4,00,FD,0B,75,67,2D,43,88,8E,52,00,D7,50,29,7D,A5,D0,11,F6,4A,D7,AC,A6,3D,63,BB,AF,09,52,70,EF,39,9A,07,50,1F,A1,F8,BA,F5,14,E6,2F,B3,F2,14,C3,47,C1,A4,D7,B9,CB,9D,57,81,7C,0B,B6,65,A0,2E,07,D5,CE,C1,DF,75,9B,BF,BE,03,63,B4,31,22,45,44,7B,6C,DE,E7,8D,0D,71,D5,7C,DB,CE,6A,80,A4,ED,5A,10,F7,84,8B,3D,D5,24,BD,72,7E,64,6E,40,B9,3E,10,D2,F8,ED,DE,93,A2,87,D0,FA,71,3E,F0,20,2E,E4,DA,9B,18,A9,CD,85,32,1F,0D,B5,2D,43,C6,67,1A,CD,4C,82,DE,8E,18,39,23,BB,A3,74,F0,23,6D,0F,5D,8C,C1,96,D9,82,DF,E6,43,E7,41,16,3E,B4,5D,76,AE,BA,AC,63,4A,6B,71,EC,69,F9,E2,1D,A9,C4,1C,EB,FD,27,31,AD,CB,88,9F,6D,75,1B,B8,0C,9B,40,A0,78,B6,DA,D8,26,11,63,ED,DF,4E,F4,26,6E,3E,97,59,9A,2D,03,1F,0C,65,67,3E,6B,14,A5,06,7E,44,F8,BF,A5,D7,1A,CE,50,97,C4,06,04,88,BC,1D,17,41,CA,91,6F,B6,C6,5F,27,A1,60,32,A8,06,5A,72,63,FB,43,77,B1,01,C5,F3,0E,C8,05,29,12,A8,B6,90,7C,84,25,38,87,6D,C5,EF,DC,D4,FC,FD,43,43,31,FD,EC,CF,13,C5,CE,CC,E6,3E,B7,6C,6C,85,8B,6A,53,88,0A,DA,FE,F1,47,26,57,92,58,B1,67,79,DE,EE,35,31,88,C2,FF,91,59,FD,98,6B,A7,DB,84,A2,F4,0F,F2,C5,13,D8,87,33,DC,BA,F9,82,7E,0E,F1,1E,4D,C8,AC,03,9E,0E,E3,FF,B5,51,A3,BD,FB,20,81,76,69,84,71,50,47,AC,63,82,97,94,F9,DE,91,02,F1,FD,8D,69,AB,E3,5B,54,20,3A,FE,DD,7C,5E,BD,5D,75,84,BE,54,21,07,E4,68,B6,86,81,75,FE,00,D9,9B,15,F1,F7,BD,B7,07,9A,F0,4B,78,47,80,28,DC,82,22,0F,D8,AB,BD,A0,3B,0E,E1,16,E3,53,86,A6,5D,42,2A,C3,25,53,75,AF,71,AC,C2,6E,3D,C1,C8,B6,66,AC,46,93,1E,E5,D3,18,2E,10,8C,FA,02,87,87,50,40,18,B2,0B,96,FE,F7,BC,43,40,59,3D,F4,B5,E2,6D,37,AF,9A,61,0C,8A,99,47,3D,0C,BD,B1,EE,6E,8A,94,CD,44,04,5A,07,F9,55,3E,97,76,4F,1B,3E,3D,4E,D1,CD,29,4C,BE,A4,16,4E,C3,53,4B,91,9C,26,35,6F,8F,41,22,EC,4B,87,DE,72,21,11,C7,6D,32,EE,06,56,22,78,B9,F3,C0,FD,76,77,B6,8B,B1,8F,50,54,D3,62,CD,BF,A8,AA,6F,E6,8A,6C,9C,E0,A8,08,48,B8,68,C3,C3,6E,AF,3B,D4,7F,27,DA,01,62,F3,DB,F5,4D,96,46,FB,7C,3E,FC,50,78,0B,7B,BA,74,8F,71,A5,42,A3,3B,92,FA,BB,8A,9B,23,92,6E,99,A3,60,D3,3A,14,06,92,C5,01,F8,5E,17,74,39,E4,C0,76,6B,FE,13,FD,7E,FD,28,97,C3,DE,D9,1C,50,30,6F,D7,72,34,0C,C5,79,1E,C9,C1,7A,05,63,71,03,41,7D,9E,75,48,35,E0,E7,73,35,D5,E6,E8,0F,9B,0F,31,0B,5A,78,AF,23,7D,FF,85,6D,35,C6,6E,00,74,B7,A7,1E,99,9E,A9,C5,E1,2E,C1,9D,5A,EF,9C,4E,8A,DA,7B,68,93,2E,E4,96,F5,6D,65,36,ED,96,01,3D,49,AC,83,CD,12,44,8A,FD,14,14,EB,BA,A5,23,7D,FE,C9,5C,39,50,C4,3B,D6,71,BB,D3,47,3D,C0,7C,09,2E,54,C9,13,6A,20,AD,39,4F,87,90,0B,2B,94,96,D6,80,7B,9B,E2,D9,3A,EB,82,D3,EA,04,E3,29,E3,62,07,98,72,A8,A7,B7,F1,1E,3A,79,69,91,82,E0,4C,EE,4B,7F,0A,80,F9,25,C6,F8,06,37,C9,85,74,C1,DC,79,8C,52,18,A8,AD,4E,AC,8D,EE,FC,ED,D8,AA,63,9F,8F,C6,27,A1,29,10,96,1C,EE,2A,E3,C5,F0,85,FD,3F,72,72,87,DC,C0,46,F9,75,9B,3C,17,E8,AD,05,C8,F8,F1,E7,E0,3A,C0,98,4B,0E,01,DA,4F,45,93,63,DE,EE,36,97,16,53,E3,C1,9D,26,84,90,1B,48,6F,E9,73,4A,E5,5A,01,25,77,54,E2,C2,8A,72,F5,25,AF,BC,6E,60,92,81,12,8B,45,E7,0E,BD,24,49,35,BF,61,76,49,12,75,C0,92,63,6D,F8,58,DC,60,54,08,69,2C,64,9D,0D,40,92,FE,53,C5,9B,86,15,22,4A,B4,35,96,9A,30,E8,B8,34,86,42,EA,17,06,E2,C3,A5,50,44,8E,6D,4F,0E,C3,5B,4F,AE,48,87,EE,99,4E,94,E7,45,DE,12,AA,0C,3C,AF,A2,EA,6C,44,36,56,47,16,FB,EF,8B,62,2A,39,D0,C4,87,AF,B6,94,7F,60,DE,12,6F,2C,43,A4,B5,4E,24,40,CB,6B,AE,6E,54,4B,59,A7,08,89,E4,F6,BA,85,EF,79,02,03,F0,83,CA,79,FD,17,2A,8F,2C,4D,57,F0,C2,2C,85,61,DE,F2,15,F5,8C,6B,41,92,67,30,38,D4,A7,38,37,8B,33,E5,F8,93,CF,4A,57,13,E6,C6,70,81,5B,D5,2E,6F,F1,00,33,D9,58,F2,FC,3C,90,69,DC,CD,91,80,8E,6C,F8,AB,4B,CF,63,A3,03,9A,22,78,20,8C,DD,C4,C3,3A,0B,9B,AB,5B,A2,B3,07,DA,70,51,10,5C,A5,D6,C2,F8,B9,D9,00,61,F8,26,73,79,AA,EE,38,69,6C,7D,C8,4F,3E,82,95,96,A0,C2,B4,64,5D,B3,01,4A,F8,40,43,0F,59,B6,F0,DA,86,19,EF,A3,80,8D,9F,CA,17,48,6A,5C,1C,5B,E9,49,CD,31,E5,00,EA,69,FC,22,BE,8C,D2,EB,86,C5,57,09,16,8B,6E,4A,4B,3C,39,33,41,D4,EC,53,69,C6,53,D4,F8,50,52,FE,86,3F,A1,A9,8F,1E,12,04,E9,A5,C7,D2,4E,E9,6A,3F,5D,9A,D4,EA,6E,67,0C,DB,97,FE,2A,78,5D,6A,C0,2D,31,1B,EB,75,61,14,7E,CB,5D,63,88,E2,0D,A4,D6,BC,2E,4C,AA,E4,DB,7E,52,04,A1,5A,86,3F,CD,C5,3D,4B,35,77,A2,9B,4B,4F,2E,5A,42,AC,B2,95,B0,95,E5,3F,CE,BC,5D,5F,1E,CF,26,F3,4E,EF,BA,CF,BC,BE,E8,3F,95,60,A5,72,4A,55,2E,5B,9B,22,D9,47,27,66,61,1D,AF,D5,70,02,B3,17,BD,40,2C,22,88,D2,52,B5,7C,B6,C0,40,8D,58,A4,55,37,38,3B,9A,EE,D7,1B,14,C2,6C,C8,89,0E,46,B6,A4,B3,C9,E3,FB,76,14,AC,35,6B,1D,E8,2D,F8,61,24,98,62,02,38,66,90,45,7D,6F,E7,FF,1A,8B,1A,1C,17,2C,01,A8,DC,CB,42,F8,EB,04,CA,BC,68,66,65,31,1B,E9,1F,A6,87,24,F2,BF,80,E9,0A,39,6C,88,05,6F,5E,20,B3,08,C4,AD,C2,70,FA,76,FF,2F,A5,9F,C6,EB,AD,9E,41,CF,E3,FF,FC,CB,B7,EB,2D,82,AD,F3,26,BA,DC,AE,71,03,02,99,BE,CC,71,5C,47,D6,92,26,87,F0,48,DC,0D,7E,87,38,EF,29,D8,C1,43,15,14,81,B5,B6,48,B4,51,17,24,6D,62,CA,92,DD,27,69,C8,3B,F9,00,59,70,0A,43,AC,6A,F0,53,E7,15,EA,10,65,5E,53,A3,21,C5,EE,9C,81,A2,E4,02,5A,B2,72,48,41,42,5C,2E,28,DC,05,D7,7A,B4,33,66,F8,31,6C,E1,F6,56,D8,91,40,18,66,4C,01,37,6E,2A,C5,3B,BE,65,8F,0D,4E,68,1E,C7,B2,CC,E4,A0,05,57,7A,2B,C1,AB,13,48,80,33,43,1B,41,C4,19,18,7F,56,41,A6,30,37,04,41,49,3C,D3,2B,18,DC,73,E8,AF,B0,F2,20,06,6D,CE,AB,46,4C,58,53,95,1E,25,58,B8,A2,DB,1E,CE,F7,3B,FB,43,AC,87,0B,DD,D2,71,22,BE,7C,F5,39,C5,27,CF,4B,5E,B1,C4,D9,19,59,8B,23,F9,A5,A9,9A,5F,BD,74,5B,B1,65,74,20,38,68,02,92,93,B4,0E,C7,DD,25,59,7B,4B,10,69,D8,59,44,B6,3A,EB,09,B5,71,F7,E9,06,37,8F,F6,2D,93,CA,77,51,5D,52,54,C3,5B,9F,0D,E5,CD,84,FA,28,BF,EF,C3,77,D6,B3,B6,49,91,87,B2,EE,20,62,E9,A9,E9,EB,BD,AB,9C,B0,07,83,72,09,AA,3D,41,32,CA,55,FF,4C,DB,F8,A4,00,24,97,44,F6,F4,08,4D,0C,46,2C,0C,5A,5A,35,0F,26,E0,C0,2E,D6,5D,F0,94,10,8A,DC,8C,C7,EB,0D,AB,08,E3,25,6F,46,12,24,5E,F2,E0,43,F4,46,5D,77,B7,EF,42,BD,AE,1B,CE,B6,A7,A4,84,27,C3,80,95,23,0D,03,01,47,AF,49,54,9B,08,C6,E7,13,2B,B6,A3,52,5C,23,2B,36,F5,24,61,E0,DD,5A,67,71,E8,DE,66,4C,F7,88,D1,ED,13,48,BC,48,E2,19,B1,89,4E,32,4D,FA,48,99,8F,11,85,40,4E,99,CD,20,F4,16,CF,1D,7D,A1,9E,96,D9,7B,7D,5F,A3,B7,31,EC,E4,DC,28,35,07,4C,00,24,B7,AF,7E,39,70,BA,D0,21,B5,7F,DD,14,20,F2,AB,F1,00,AB,96,82,24,5E,31,05,DF,2C,22,F6,E5,96,2E,17,91,52,C3,31,32,62,2F,2A,B4,8D,FA,31,61,D4,BD,72,DA,3A,66,C1,00,8F,50,55,B3,83,26,CB,63,B7,3F,6F,03,DA,9D,B6,AC,4A,00,F6,CA,AD,27,D7,9E,5E,EA,07,44,89,A6,37,CB,CC,B4,FF,A4,05,04,CD,8D,CA,64,7E,46,8E,35,D3,0D,BC,65,4B,4F,88,ED,19,E3,64,D3,D0,17,EA,D5,20,D3,F5,E4,7F,C2,E3,BA,7E,47,EC,D2,74,44,17,5C,8D,6F,35,D4,38,0B,94,1B,6E,E2,F5,4E,A0,6A,2D,A1,4C,D8,4A,8D,73,20,6B,0D,D9,F4,BB,98,57,A0,FB,AB,DF,5B,17,73,BF,71,4A,A3,56,9C,DC,C7,8A,48,3B,33,17,19,A0,72,D9,78,32,68,3C,6F,0A,A2,FF,0E,38,F2,56,E4,55,7B,77,38,20,0A,27,F4,6D,3A,0C,A2,CC,F3,42,82,05,5D,CB,78,2B,F0,66,73,2F,01,8E,DC,96,15,E9,F0,64,84,89,B1,A1,E1,37,EE,3C,0A,E5,36,EF,B1,F8,66,09,58,32,8E,0D,73,1F,55,2F,62,07,02,D2,3D,0F,E2,7D,CB,D5,83,AF,F8,31,E6,4F,48,6C,5A,F8,09,F3,FE,C4,E6,D2,07,3B,EB,3D,36,FA,6B,93,AD,12,48,A4,AA,6C,29,51,F7,F7,E0,A2,97,E5,06,52,BC,82,98,A1,CF,A5,AD,41,CC,CD,BE,DF,E4,13,42,25,3B,93,4F,B0,9F,D4,00,9F,26,62,33,47,9C,B3,10,93,5D,3F,9D,25,70,94,A6,8A,4A,DF,0E,2C,4B,C6,9C,12,9B,FA,70,AD,C4,11,10,0C,F4,80,94,78,9D,31,1D,84,94,CD,6A,AA,9F,D8,93,2C,63,E2,FC,9E,BB,F3,2B,11,98,53,AB,A1,6C,87,DE,97,0D,5B,38,DF,1A,20,56,B4,54,B9,BA,EF,7B,39,7B,1D,57,BD,DA,2A,8B,03,5E,10,AD,A4,FB,10,9E,C8,7A,B0,21,56,51,72,89,39,52,1D,77,BC,DD,04,A9,EF,E0,EF,94,3E,4E,65,B4,A7,3E,A3,2D,0C,C9,A7,6C,7E,1D,33,F8,8E,43,64,00,D3,81,08,15,72,07,B9,30,C0,47,25,47,0C,66,05,6D,E9,51,6A,A9,1A,4B,10,CF,03,82,16,B0,6E,62,68,6B,CB,E3,86,5A,FE,81,34,29,6E,16,05,C1,E9,52,B2,57,B3,E2,09,66,55,7B,41,3B,BE,C6,BA,28,15,50,D8,B6,F5,E7,C2,E2,AA,A2,61,8F,33,D6,3C,B5,2A,4E,33,35,7D,68,11,BB,EB,77,C9,FA,8B,C1,42,A3,63,FF,09,95,F9,7A,7D,FB,30,8D,5B,B3,1C,2D,E8,B2,44,A7,B2,0D,20,90,FE,0E,E6,78,7A,DB,EC,70,2E,DA,DD,A8,81,5B,E6,4D,BF,F7,BF,DE,1B,F7,DC,EF,03,36,FA,A6,3C,49,72,DC,4C,2E,C5,81,9D,52,8C,40,17,CE,D8,3A,58,3D,EE,73,29,EA,56,44,09,2D,9A,46,F7,F6,92,50,2A,3D,54,45,9C,72,ED,26,18,E8,5B,5F,A4,47,C0,0F,FE,56,82,B6,DA,04,94,1E,B9,94,54,E1,7E,FE,07,10,22,77,2C,B6,2E,A0,86,60,4B,6C,4C,93,34,56,1E,11,7E,CE,DF,BB,79,76,B5,D0,59,59,E9,CF,AB,9A,D5,2D,88,84,6A,58,46,D4,80,B5,59,EB,85,C9,5E,A8,BC,52,C6,CA,E8,D0,01,25,D6,43,80,76,39,12,5E,CD,93,B2,5C,72,56,5B,25,3C,06,0C,C2,E0,6A,1A,C1,A7,0C,AC,5B,79,F1,F1,79,66,EB,07,53,0E,94,EC,07,08,13,12,ED,19,6C,AF,12,43,DB,5E,7A,E4,DC,3C,3E,7B,38,67,BB,A9,9B,14,F3,B5,C0,26,D9,B2,56,F2,4F,1E,47,D7,3A,AA,AA,BB,69,5E,62,5A,3B,02,79,B2,B7,F5,7E,E6,44,1C,3A,D4,D3,15,8B,AE,B7,B9,CC,12,7B,86,8D,55,D1,2B,CB,95,C7,A6,B4,DD,3D,5B,4E,3F,76,2D,41,B0,B5,57,1C,90,0A,8A,00,13,01,47,FE,F7,AF,BB,65,89,16,EB,5F,14,E4,8D,F3,90,26,C1,91,F0,A2,5F,1B,86,64,68,49,F5,AF,5C,A9,43,77,3C,D3,F5,F6,F5,1A,6C,EE,DA,FD,07,F7,3A,50,D1,3A,23,84,7D,4D,17,DD,9A,E0,67,90,BC,CF,53,73,D1,EA,E5,5D,86,B8,35,72,64,13,6E,BA,00,F2,9B,F7,5A,F7,E9,61,58,4F,42,F2,6A,ED,0E,BD,AE,E9,07,43,F5,96,60,1A,71,52,8C,BA,84,8A,FF,5F,A6,6F,BF,8C,71,99,C5,FC,5E,8D,9B,E2,4D,B3,58,B5,56,26,F4,13,D1,2F,35,FD,9F,42,09,B9,E7,24,8C,CA,58,39,DF,96,A5,5C,A0,55,03,64,FC,B3,4C,15,B0,9A,7C,B2,91,3C,04,6C,AC,50,39,63,40,0F,34,44,22,06,D2,4D,8F,77,F3,D7,2C,A6,4B,DE,BD,8B,04,0D,D1,3A,03,4B,93,5C,00,05,09,3D,B6,AD,36,1F,28,3E,5B,96,2B,D1,A8,54,8A,A4,5E,91,44,C9,E7,E0,1F,92,91,68,10,B4,73,62,2D,E5,F5,50,7E,5A,1B,56,CA,3B,7E,84,4B,75,78,CC,F3,D3,CD,61,47,A6,E6,A0,D8,C3,C9,A6,3E,C7,50,F7,13,5F,82,7F,44,36,8E,25,E5,26,42,C4,2D,97,F4,74,67,34,B4,DB,41,DE,C0,84,F3,1B,1E,22,E4,92,8C,A5,12,74,0D,E3,2F,29,2A,7A,32,08,97,EC,78,E4,9D,F6,29,76,70,56,68,90,21,94,25,8F,0C,F1,76,00,D2,E4,99,EA,84,B1,AB,96,5E,77,90,73,8A,F1,0A,13,5D,0B,7D,86,56,8D,56,17,47,73,EB,A5,AF,C7,A2,48,58,8E,ED,F8,E4,78,74,2A,56,F7,B6,7A,B5,B2,9C,D4,B8,94,3A,69,79,01,C3,79,A8,DA,56,7E,0F,64,35,14,BD,C8,3E,C4,8E,27,25,10,39,CF,4D,A5,E7,5B,69,CA,EB,91,5C,A2,30,AB,39,A2,D6,B7,A1,06,8C,0B,C3,60,F7,48,6F,AA,6E,8D,FA,DB,B3,5D,BF,89,DE,77,2C,72,0B,FE,B4,A3,34,60,8D,7F,1D,3F,4D,FC,B9,69,17,07,0E,7A,3B,7C,CF,91,06,60,34,3F,05,F2,7F,B1,69,30,BB,50,47,83,A9,CD,BF,63,5B,B3,08,A8,39,C0,4F,E5,B0,10,01,DC,86,92,F5,9C,87,58,83,FD,63,5D,D0,69,AA,D8,76,9B,B6,98,33,44,1C,2E,E0,12,6E,B6,90,0B,9B,0B,FF,89,F8,55,4C,DC,29,03,5E,20,4D,AB,48,16,F2,EA,1E,0B,1B,1A,E4,A4,DE,72,33,89,9A,67,5B,72,21,3B,E0,43,05,5E,E9,A7,86,67,3E,7B,54,68,5B,B5,35,EC,AE,1A,D5,2D,23,01,B6,73,06,45,46,7B,A9,5F,0B,98,E5,F5,1F,DF,49,D0,21,37,0B,F9,D1,A7,52,90,AE,1C,E9,0E,0A,29,E5,9C,75,BB,C8,14,60,33,8C,AC,C9,95,92,BB,27,C2,5C,01,A6,C2,7A,FB,CC,41,82,9B,F4,29,C0,C8,C1,1F,58,A5,5B,82,AF,FE,AC,4E,FC,93,82,CB,2F,33,F4,35,77,73,A4,C8,DD,0C,B5,BE,26,0B,60,C6,7B,56,DA,17,A3,47,FD,D6,2A,F8,B6,31,AC,E8,9D,71,38,0F,B2,BC,B2,22,CE,B8,C8,77,44,60,D4,C0,BC,84,53,65,BB,02,8B,FB,BF,85,ED,83,8D,EF,63,10,87,1F,CC,5C,CD,6C,29,7F,23,86,5F,78,79,50,1E,6E,38,52,84,9E,F5,41,13,BD,8A,84,1F,26,06,E3,B5,59,E4,C7,A0,50,8B,D4,C0,4A,AD,D1,D1,76,A1,E2,45,9E,80,57,E9,BC,EE,05,9F,02,21,F5,AA,39,51,33,49,5E,63,E9,65,28,63,2E,3D,EA,25,05,96,77,AF,EC,E4,FC,07,4E,BE,B0,D2,AE,C1,68,73,70,4E,21,91,34,7C,E7,BD,55,C3,D5,A4,D4,51,94,D3,34,2F,E3,72,C2,20,AC,55,A5,FF,B9,BD,AE,BB,F7,E0,04,96,D2,AB,39,EA,A0,82,D1,5C,4C,A0,B0,28,0A,B2,09,E6,F0,6B,64,6D,75,D7,4C,D0,3B,12,07,AA,11,BB,DA,CA,E3,B9,6F,A0,4C,2A,DA,A8,4B,E5,9C,F3,A6,81,35,16,87,DC,70,C8,AE,60,E6,6C,28,9B,5C,8C,9B,C3,96,98,24,19,85,DE,54,52,F3,34,3A,8A,11,8D,97,19,E8,CD,21,77,AD,A1,93,AE,DC,C0,E2,B4,4B,89,86,28,98,CB,D4,B4,2C,7B,3A,02,CA,44,ED,3B,5D,44,69,D3,88,B4,EF,0F,24,A5,05,4A,F0,31,73,94,3E,3F,DD,D6,AA,CA,A9,83,1F,9C,1A,16,7D,28,28,CA,50,B1,BB,78,F8,B5,7B,66,6B,19,F3,88,41,41,32,F3,90,B3,F3,10,30,CB,9B,6A,B2,F9,17,B3,A1,74,56,1D,CF,45,63,03,9E,80,18,B3,46,5F,EA,E4,F4,DC,EB,E7,9E,19,7F,F4,A1,F5,CE,BC,D8,20,6E,94,82,E2,20,99,BD,65,AA,F8,13,5F,45,F0,67,50,B3,9E,C3,1C,F7,75,6A,C0,AD,7B,E4,2B,B3,77,3C,13,BE,F1,A5,A9,13,2B,FC,A9,CD,E2,CA,64,04,29,A0,E5,EF,DD,9B,75,DE,7C,B7,9B,29,44,83,A4,14,FB,0C,35,DF,3B,AB,C3,8F,96,CE,93,05,64,0D,BE,4F,76,DF,D2,73,E6,94,1A,8E,FB,8E,1D,CF,9C,A7,F1,8B,9A,AD,3A,85,86,05,3C,06,E5,AC,B6,4B,8D,17,1B,80,4F,DA,5E,AA,F1,D3,5D,DC,54,D9,89,50,39,91,23,31,D0,F6,C4,7C,1E,52,4A,8F,AA,AC,0A,D1,16,AF,7C,CC,9F,6F,39,6C,A5,F9,54,41,55,EC,A0,13,EA,FE,FD,2B,98,BF,1E,7E,B6,8F,0B,91,AF,05,94,90,DD,B1,B9,3E,D2,37,3E,C3,16,2C,D8,A3,20,E3,CB,88,15,98,88,AA,B8,7E,56,4C,B9,68,9B,7C,EB,5C,39,54,9E,03,62,17,F6,F1,AD,30,80,B0,F9,07,E3,A1,7B,4A,D1,10,CF,E6,BD,2F,2D,A3,0B,34,35,F8,F0,83,09,39,20,A4,D8,0A,DE,73,D8,BB,9E,1A,FE,30,D1,9C,A3,DC,8C,D5,2F,A4,55,54,40,B6,FD,E6,80,82,14,4A,E6,5C,9B,2B,F0,89,93,44,BC,9A,36,4B,0E,25,E5,53,2F,93,DE,42,53,86,34,6C,AF,A6,32,87,1B,9A,45,26,8F,A6,ED,C0,7D,C8,DD,ED,A5,6C,4E,13,DD,27,17,8C,7A,64,5D,54,9B,C4,8D,54,7F,FB,0C,37,05,63,11,5B,7F,1F,48,75,85,82,05,6A,DA,1E,7D,2C,76,A7,C1,EB,1F,E0,24,CB,9D,26,24,71,EB,58,C0,C2,4B,DB,D1,9D,B1,AA,C4,35,6A,6D,07,92,00,46,23,27,E2,60,D8,4D,B6,79,16,74,82,6B,2F,13,7A,8D,30,E2,F5,72,EF,8C,BA,04,A1,D3,D3,F1,E6,4F,2E,11,E9,CB,AE,A8,76,A3,31,BB,73,4C,EE,28,F7,08,D1,D3,00,8E,4E,6C,50,B4,84,01,44,17,45,A5,4C,68,5C,29,F6,A4,BC,A9,2E,78,FF,76,40,C3,A2,AC,DF,E6,CD,ED,A7,30,5B,04,7E,B8,46,DA,B9,48,9D,7E,9B,3F,2F,F2,E1,8A,D0,10,CB,A9,D8,D5,82,EA,B5,CF,0D,29,40,26,FA,9C,5A,12,F1,B9,04,DE,50,2E,2B,9D,80,16,2E,94,98,DB,42,99,C1,94,4E,03,8B,1E,81,1E,11,78,F9,AA,B4,11,D2,A2,B0,B0,BE,69,3B,55,1F,CE,98,A0,3D,86,AF,3C,0C,10,5F,75,3D,16,57,10,46,D2,98,0E,0A,2E,8C,6F,D4,18,A9,49,B9,3C,67,5F,6C,02,A8,D8,6B,D7,9E,F4,43,9F,F4,2F,1B,EF,D4,8F,32,42,24,2A,C2,36,36,18,6C,E5,1B,99,8F,F8,27,97,4D,3E,CB,88,CC,92,2B,AE,9D,94,92,29,63,43,75,BA,33,84,D5,2C,C3,6E,6F,2D,9F,A9,F9,72,15,02,94,9E,90,4A,0C,37,A6,AE,C3,F0,72,57,10,1B,7A,C8,E7,7F,29,0A,12,BC,01,C8,BC,D8,10,EA,D8,31,9F,CA,A4,01,6F,11,B6,40,EF,A1,4F,79,28,83,AD,7E,65,A5,BF,2A,33,3E,89,CD,3A,09,02,B0,42,BE,76,E3,05,DC,1B,F8,65,0F,5F,04,E1,55,4E,38,1D,29,73,56,DD,FE,DB,D2,6F,65,16,FB,C9,A4,93,0C,C3,0D,B4,C4,02,01,2B,BC,03,0B,62,9D,14,14,18,CE,84,D3,46,5F,CF,3E,8A,91,35,EB,72,29,FF,73,0D,20,A2,73,21,B7,6C,23,F7,F8,1F,47,1F,89,9B,69,1B,BE,1E,F2,85,D3,85,D1,57,D0,E7,E6,55,20,2E,A9,EE,E0,A1,51,F5,01,C4,70,0C,20,F6,B9,1A,44,E2,81,C7,89,F2,EA,4F,F2,D9,03,27,56,0C,E0,E5,18,56,AE,92,75,08,E0,51,98,EC,E5,10,C6,7C,E1,44,85,46,0F,9B,63,E5,18,EC,9D,84,CC,80,6F,16,00,23,E3,4F,DE,AF,48,2B,E2,EF,CD,64,E7,34,88,19,49,B6,91,E9,8F,02,7E,E3,9D,73,A0,EB,BB,63,7A,FF,B9,AA,73,5A,89,53,16,E7,62,97,64,BC,17,BA,A3,60,9A,C4,7C,18,0E,7B,09,18,EA,35,3A,FF,9F,86,C4,7C,68,69,22,09,71,77,AB,A8,FB,93,9F,AF,78,3B,7C,B1,61,73,D1,A2,B9,18,9A,15,7D,33,7B,42,9F,32,C6,93,27,1B,38,F6,B8,D4,97,64,8E,67,0F,6F,CC,2D,31,13,AD,46,E6,68,31,11,2D,88,48,70,D5,05,33,84,DD,37,E1,67,CB,23,B9,04,D9,22,66,E1,69,22,87,FA,E5,08,29,B0,1F,4A,AD,A9,35,E5,E2,B5,21,1D,E1,5E,45,95,08,B1,D4,99,4B,11,10,16,7A,AC,35,0C,C7,5C,2F,25,2D,37,8B,AD,A1,C2,AB,DF,69,40,DB,FB,A5,2D,EA,6E,93,14,E0,B9,A3,C9,68,08,78,9C,E2,0B,C6,AD,76,2C,17,83,C3,49,6B,76,55,9B,82,D7,E2,0D,E5,56,ED,17,4F,4B,A5,E7,77,88,8A,CF,39,BF,29,23,EF,B2,70,D7,4A,7E,24,06,AE,E8,6F,59,3E,5C,B0,24,0B,74,9B,80,1D,B1,D8,D5,EC,39,EC,8F,C9,E6,28,E2,CD,76,E4,A7,98,8E,0C,A9,30,7A,26,F0,22,36,A7,E9,1E,9D,A9,25,7D,B3,10,FB,E9,6C,7C,84,91,24,AA,9B,AC,B9,3B,5A,5A,30,D5,F9,1F,89,3C,80,86,AD,15,27,AC,21,A1,57,9E,D7,BC,9B,F3,4A,4A,A0,EB,FE,FA,E8,73,20,4A,8B,20,E0,70,1F,66,0C,71,56,15,C4,2B,EC,6A,F3,B7,B1,CE,3A,A6,A5,60,80,06,4B,B0,E5,FE,69,2F,80,98,80,96,52,34,E6,0B,1F,01,EB,69,5B,04,44,7B,AB,B1,FA,72,1C,64,0D,CF,D1,92,DA,79,84,FB,8C,18,C9,30,88,3A,EC,DA,BC,31,D2,5E,B0,57,B1,1B,9C,58,59,08,03,80,9B,1E,3A,ED,E7,98,5B,C9,F9,3B,35,03,83,7A,52,DB,CC,22,7C,CF,C2,26,6C,FF,BF,EE,47,8B,F6,51,08,43,95,5D,5B,EE,D8,8D,D3,21,D6,E9,F1,2F,F2,CD,9E,75,B1,53,C7,FE,3B,2E,E7,52,23,F9,D1,39,F9,AF,D7,99,F2,19,53,85,C9,49,79,58,B9,4D,0C,0F,17,C7,87,26,4E,1E,06,FA,82,24,1A,B5,AB,8C,8C,69,C0,89,99,DB,A8,9E,58,D4,80,E8,80,64,63,B3,96,5D,27,FC,C3,A7,00,8C,44,B8,D7,64,D7,2B,D7,96,D7,75,FE,0C,71,15,A1,48,0D,E6,C9,BC,F6,56,DA,6F,62,3E,7C,9E,74,DC,C2,95,07,7F,70,BC,D2,76,50,03,FB,DB,51,B1,7F,C8,B2,E4,C2,48,16,70,F3,D8,E7,05,46,E2,E8,C7,AD,56,92,0A,D7,98,FD,9C,F1,F5,39,70,B4,CF,A2,E1,DC,57,03,F8,5C,53,47,D5,7E,0E,20,A7,9A,52,7A,8C,B8,DA,3A,1B,9A,40,FE,5A,2A,6F,5A,80,23,8E,61,7F,7C,F6,20,1B,94,A4,CE,06,F6,F8,C7,2A,26,65,76,58,18,08,01,54,AC,05,31,E8,E9,2A,5B,CD,C0,FB,8F,DF,17,C5,24,6F,88,FF,C4,46,9C,D5,4F,C5,70,C0,74,F3,B7,00,C5,55,DD,A1,21,AB,D7,6F,E9,EF,2E,6B,AD,D4,1F,8F,6B,A3,16,B1,22,E3,07,7A,45,BD,89,DA,31,7E,15,73,C8,6A,F6,E9,B6,DE,46,58,64,A8,FE,96,81,9E,2B,FF,56,C4,30,C4,5E,F2,63,62,70,AE,D9,87,09,C8,50,E5,FD,C9,CC,60,EA,40,FE,78,41,B3,3A,F9,1A,35,C9,5C,18,A4,A5,12,FD,17,95,54,F3,65,BB,A5,B9,62,EA,76,76,FE,E5,22,35,91,51,BB,7D,9F,D5,CD,C8,62,26,FE,7B,4A,BC,0D,14,A6,86,69,AA,D7,FD,22,10,29,8D,7F,11,E0,1F,58,F6,0F,9B,E5,21,B9,BE,7B,BB,AD,AA,FD,B1,A1,13,4E,01,5D,EA,90,2C,34,69,BB,F6,26,D1,25,92,65,BC,A9,7B,FE,B9,40,CC,B3,EE,BF,B0,D2,6A,D7,F4,C6,BB,1F,78,99,D8,1D,58,81,F3,B7,BD,DB,84,6F,6A,87,A3,69,56,CF,5F,AB,99,DB,A2,D5,10,8B,EF,C9,33,B9,00,36,DC,B9,DD,B4,28,9D,B7,01,E9,77,6D,47,6B,B6,B0,A1,E6,24,5F,9A,EE,4E,36,AD,09,7C,6F,6D,9C,D5,70,45,D9,23,91,67,9F,38,D3,B5,34,70,F5,55,20,92,2C,3D,93,84,1D,CE,39,3C,E4,FA,53,9B,2E,81,E1,0E,67,88,46,DC,3A,7B,32,7E,A6,62,91,2A,2E,0D,32,8B,47,17,6F,5E,BD,89,14,71,20,6A,F5,81,C9,8C,61,88,11,BF,23,B6,2D,A4,1D,EC,BE,76,63,E2,D8,14,4C,1E,4F,7F,74,38,BF,EE,31,AD,79,92,EA,62,21,C6,C5,26,ED,74,CA,2A,11,98,DE,9C,7E,25,2C,32,6F,B2,03,C2,BC,26,0A,62,98,DF,96,5E,5A,B6,A5,2E,5A,10,95,F9,9F,C2,16,86,E7,B7,1E,5C,6F,46,C5,23,AB,81,84,22,17,CA,D0,6E,E1,2A,99,CD,60,4E,40,96,9F,B8,3D,36,44,23,1A,40,DC,66,C5,5C,38,92,9D,6B,36,B2,24,77,EC,29,18,A3,9C,9E,D6,4B,11,74,7E,91,FD,90,72,19,01,C0,45,C1,8F,1F,24,6F,BA,03,98,4E,39,A1,C3,FA,69,37,1A,2F,6D,D8,D4,43,18,7C,BF,F7,01,77,3B,31,63,64,6F,24,9B,1F,86,48,1A,28,FB,28,96,0A,4E,45,3B,E2,02,82,27,A8,C1,92,CE,BA,97,B4,0D,A5,EB,91,97,0A,F9,AD,6E,8E,FB,53,BE,72,E6,D8,15,E7,6A,45,E6,65,FD,57,F5,85,F5,43,87,6F,C8,14,AC,80,45,5A,4B,DF,9F,28,8C,C6,82,4B,2D,17,11,D5,18,9B,A4,7C,A6,14,ED,11,9B,DB,8D,0E,0C,D9,D3,8D,6D,08,46,2D,99,24,77,7E,85,00,7D,5A,A6,8C,56,45,72,62,55,DE,7B,88,47,5C,6D,1B,C8,4A,98,DC,1F,C8,FA,88,05,13,D8,DB,A1,14,73,05,98,A5,07,09,5A,56,CD,E2,97,38,2F,6C,37,C1,2C,60,81,EC,41,5E,63,8B,7E,BA,6C,9F,7F,50,A2,A0,F2,03,1E,F8,11,71,9F,7C,D7,27,2D,EA,67,8B,44,A1,19,21,C4,CC,F5,4B,56,5D,DB,A6,64,B8,D1,74,03,08,2F,56,E3,6A,6F,68,E2,8A,98,C3,A1,AF,65,B7,09,85,E6,9D,8A,65,E0,7D,F2,86,7E,DC,C5,61,B3,93,E2,2D,E3,5A,09,28,5B,A4,68,2E,2A,96,4F,02,88,FE,21,7D,A5,56,6D,44,88,C2,5F,6A,85,04,75,83,F1,06,D0,1A,82,FB,AB,5B,C1,77,2F,75,5C,BC,D7,82,51,4C,21,F5,99,60,E7,33,75,B2,0A,91,EF,0D,31,33,04,55,ED,D1,62,B0,1A,AE,6B,A4,D2,40,29,0A,2D,B2,2F,09,D7,E5,45,FB,A0,66,41,D0,51,7F,FA,71,E6,CD,A3,44,84,27,0A,F8,89,43,BB,12,B6,EB,50,F7,A4,4B,12,89,73,25,E8,D4,1B,42,3F,FB,1B,CC,5A,AE,00,4E,7B,61,C9,DA,C1,C6,CF,0A,F2,54,3F,12,BF,23,BA,17,2F,65,64,FA,7D,4F,E8,04,EE,DA,3F,82,53,6F,5E,00,AE,EC,AC,63,E0,94,FE,7E,91,94,FB,76,74,45,3F,C2,D4,2E,32,CF,19,9D,A4,96,CB,CC,55,ED,12,79,58,B1,5D,2E,A7,33,AA,F5,29,2F,AF,13,95,D8,53,E2,BC,5B,4A,BC,B5,57,11,6B,D7,70,8D,0D,1D,97,C2,B4,D9,C4,F7,C3,B2,12,18,76,E5,70,8B,0C,6D,2E,AE,9B,94,9A,9D,6D,C8,7A,B7,40,90,83,12,FA,EF,DE,C6,AC,5C,80,A6,5C,65,8A,4D,CD,C4,75,A0,46,E7,6F,0C,AA,00,69,86,BC,FA,A8,FA,46,66,69,EC,A9,87,C3,5C,72,75,A8,14,5E,3D,0B,7E,13,8A,B2,DF,7D,94,2F,8D,F5,58,65,5A,24,EC,03,CE,3E,57,90,13,F9,0A,34,C0,25,80,E2,F9,82,8E,10,81,0D,02,6A,58,6A,20,73,79,64,15,7B,28,53,84,F7,C2,D4,08,A5,2B,1A,0B,15,A0,66,AD,37,BD,7D,E6,3B,26,F5,76,ED,53,1A,0F,65,5A,4F,3A,BE,4E,F0,53,DC,A5,A9,C7,D1,F6,78,D8,97,F1,89,BA,73,86,35,25,87,1B,A0,0C,26,B0,95,6A,F8,98,A0,58,8A,1B,27,5C,44,1F,8B,53,03,33,81,8F,A7,F5,E7,1E,41,E8,05,93,14,7F,9D,5B,AC,FD,3B,CD,5F,59,8D,81,39,28,09,97,8D,1D,92,64,55,00,A0,21,77,B7,6D,31,16,1B,55,79,DA,1E,12,7C,95,F8,47,23,6B,DE,CA,5C,07,09,FF,96,F5,04,55,90,3B,03,27,54,1A,36,42,CB,E7,C9,C3,F0,0F,A2,CE,38,3B,D6,64,9C,6D,A0,01,9A,05,E9,5F,42,E3,44,B0,0C,5B,62,D7,4E,F9,4D,2B,F9,57,3C,0A,D9,55,35,E2,BE,19,4B,C2,BF,FC,D1,B6,90,E0,A1,8A,6C,0D,93,5D,29,90,52,AE,46,48,69,6B,CE,2D,C0,BD,9D,31,F8,49,8B,4D,8F,C1,96,A6,3E,01,27,9C,73,E4,22,47,76,AD,E7,70,20,A7,43,EF,A4,5E,39,E7,06,3A,A9,C4,2D,7C,BE,1B,E6,76,EF,BA,9D,1F,2F,83,8F,AD,11,A9,A6,B6,F0,A8,32,C4,F2,E5,A3,1F,6B,C5,FF,61,6B,E8,FD,8C,3D,33,C5,06,19,66,64,C7,80,17,66,CC,1B,6B,80,B0,2C,43,5B,D5,9F,E2,07,88,87,74,1C,CF,81,41,B0,81,17,EB,1D,57,C7,6A,87,6A,27,F3,F5,8E,64,74,1B,98,6A,32,F3,2E,C1,F8,E9,D6,08,59,F7,0B,77,76,23,BC,47,E9,B2,35,66,C2,49,45,84,A0,B5,D7,F4,E8,7F,52,C7,D2,30,23,19,1D,A0,86,7B,03,62,9B,B7,81,14,F9,6D,B3,1F,F3,87,DF,89,02,9C,8D,EE,8F,F3,5E,D6,17,4B,F3,E7,49,97,9D,DE,62,8E,1C,1F,D0,F7,0A,56,3D,3F,EF,1D,0D,7E,1F,C2,FC,42,C9,C1,FC,B2,40,C7,FD,66,C6,B6,16,EA,C7,67,44,28,80,A0,78,A1,57,DD,B7,95,DA,0A,40,C5,31,62,91,5B,54,F8,08,7C,F2,65,8C,6E,1A,F7,4C,F3,18,E6,66,96,92,F2,52,43,08,02,A6,BB,DB,19,AF,7D,D4,06,E7,E5,28,4C,70,58,BD,A1,32,68,C4,A2,B1,4E,00,4C,69,05,C2,55,50,5C,C9,62,97,AA,4F,F9,00,D8,61,6A,A9,9A,81,E7,D6,36,84,0C,CA,5F,80,0F,51,B5,2D,28,B0,1D,D3,44,0C,84,47,62,F2,FD,74,0F,8D,57,2F,29,F9,4A,B0,03,BC,43,C6,77,6F,F7,9B,17,B1,7C,F6,9B,37,85,C5,5F,34,A7,B9,6F,50,DA,AF,DE,05,0E,DB,17,C7,E9,94,73,37,78,3E,13,87,57,91,CC,67,BB,B6,71,C5,8D,06,0E,2D,83,2F,60,61,7C,28,2E,2F,79,78,F1,2C,DC,23,AA,6C,41,2B,13,73,9E,70,90,DA,CA,15,CB,20,72,15,1F,00,48,00,24,C1,57,CC,D4,C9,BE,C8,88,F3,27,86,28,A8,6C,6F,D8,4C,59,89,3B,11,BC,90,6D,1F,10,BD,E4,B8,5D,27,37,13,3D,23,68,7F,7B,E1,0D,47,BB,51,52,14,8B,2D,77,CC,03,A1,61,F8,9F,C4,CF,71,A1,6A,75,25,04,7B,71,F9,1E,2E,5B,6B,84,0F,12,B1,49,B0,99,C0,BE,2C,F1,3B,CD,31,AF,3D,FC,C0,53,74,28,03,B7,A2,C3,73,BD,B7,B6,58,FF,23,30,FF,FA,79,78,30,17,F8,14,03,98,8B,37,A6,B2,74,5B,8A,6C,CE,38,DD,06,5F,45,63,37,D4,21,1A,23,23,B9,87,D8,68,7B,66,B0,BB,5C,00,C9,8E,F2,BC,61,ED,33,45,7E,3C,75,C5,A5,43,5B,4B,D2,AC,BB,0A,07,03,BF,82,4B,F6,8C,48,51,25,5A,0A,0A,BA,DA,10,BD,8A,CA,3A,78,5F,3F,5C,D3,4F,22,7D,FC,51,6D,8A,D0,69,A5,43,CB,1D,8C,CB,E1,9D,97,31,EE,12,8F,0F,4D,D2,62,F3,E9,B5,FD,F3,FE,9F,0E,C7,F9,4B,47,F3,B4,A4,E0,FC,D1,34,E4,D6,62,44,90,A4,A0,24,3E,21,9C,02,BB,EB,FC,09,4E,57,3B,DE,62,B2,E2,91,24,2C,E1,A9,45,7B,0E,0A,B0,FB,D1,8C,68,E9,7B,FB,89,2C,85,E4,1E,46,7D,30,47,41,EC,AE,57,5D,84,25,AD,8C,90,3C,16,4F,9F,52,BB,95,44,D3,1B,D3,94,9F,7C,A9,90,09,3B,7F,FE,04,3D,3B,95,4A,6F,25,8E,0E,2C,BA,CD,6D,F7,67,04,10,2F,02,15,31,59,01,B0,4D,4C,CB,E7,DD,9D,0C,57,B1,AA,8A,EF,EF,BA,FD,03,85,C8,CF,C5,0B,CB,CD,AE,C1,97,E6,CF,E0,5D,EB,FB,0A,F6,01,25,9F,0E,68,88,71,63,BC,20,A2,88,4C,D1,15,F0,6B,59,33,5A,41,F1,1D,7D,C9,95,14,62,8F,F4,0D,F7,4D,EE,2F,B9,5F,00,70,22,26,67,86,FE,6B,1C,AE,E8,26,CC,84,39,88,69,2B,C0,B9,21,06,3B,F9,11,07,B0,E1,B8,74,0F,83,12,F1,C8,A2,7E,C9,4F,C7,99,AD,A8,35,F6,5C,DC,51,D4,EA,CD,C6,89,32,59,A2,44,F2,0B,F0,BB,13,99,7E,96,3B,8C,FA,0C,E7,29,BA,D9,5A,8E,6A,DE,31,6E,F0,2C,5B,FF,ED,87,03,11,10,03,50,5A,57,95,58,EA,0F,C6,22,FB,2D,2E,37,48,DE,D3,57,6B,FF,D8,49,58,F7,52,EA,D2,DF,1D,A8,CA,DE,97,7C,16,CA,9A,CF,3D,AA,5B,A8,67,CD,1A,3A,49,74,A2,A9,04,70,71,03,C2,D6,B1,7B,F2,93,0E,EF,21,39,06,85,40,C2,99,4E,78,D6,2B,2A,B3,7F,31,7D,83,12,35,11,D5,B1,5C,DE,3D,51,A5,39,13,C7,17,B6,9E,AC,17,74,D0,98,14,C6,36,BC,77,7E,D3,FE,64,D3,87,E6,B1,C6,39,D1,7A,D5,DA,ED,89,A6,86,18,FA,AC,D2,08,5E,B3,CC,E3,09,7F,94,DE,9D,E4,D7,D3,A5,CF,EF,2D,6D,01,01,42,6A,45,5E,CB,67,A8,04,0E,5E,1C,9F,06,68,B7,B5,DF,48,67,BE,BB,05,EB,1A,A2,C1,D9,23,58,1A,7E,40,7D,6E,65,48,CC,1D,70,F3,E5,90,A3,E4,E9,E5,C8,50,EB,D6,9B,C3,3D,45,5A,93,DB,1C,CB,1E,E2,63,39,BE,08,27,83,0C,74,26,7F,A7,30,ED,AF,F8,30,97,BA,74,B5,D7,0E,5A,ED,C9,6D,82,8E,E2,3C,B8,EB,68,D3,80,6A,1C,20,7E,21,8C,AC,EE,AC,B6,DD,28,19,CF,0C,52,BF,C9,DB,63,67,FB,A8,E9,FE,1A,89,9E,11,07,E3,49,14,09,93,B8,64,E5,8A,3B,ED,B7,50,B6,AB,D8,DD,C7,D4,34,55,C3,21,9D,DA,24,6C,83,55,B6,46,1E,4A,98,2C,E6,94,18,E7,D6,EA,AB,76,8E,73,54,8A,CA,78,CB,FF,6E,6D,48,9D,1F,85,87,9F,01,35,E2,E2,3F,82,73,2C,A4,B6,BC,5E,31,7A,97,9E,7E,00,E1,65,1E,F9,3A,42,48,30,52,08,47,38,25,E8,D5,B9,73,85,20,04,45,D3,EA,EF,6E,84,A3,89,3B,E7,D3,1F,2B,1F,25,A9,67,F0,09,82,17,48,B9,A2,BD,35,38,E0,B7,05,D2,EF,76,AC,16,D6,F0,22,F8,1A,63,09,3F,64,A3,B1,A3,07,75,64,93,50,0B,78,8F,0E,D6,9A,F0,A3,EB,D7,4B,7C,4E,9F,D6,57,F2,EE,A6,32,EB,C6,C4,46,49,B2,C7,D6,A7,34,DB,88,3A,8B,42,C1,50,6C,70,D8,D5,05,DC,86,6E,8F,8E,7F,7C,7F,37,94,91,99,70,5F,E4,B1,E3,93,C4,D4,E5,D8,00,3D,3A,75,72,4F,BA,C9,D7,1B,E9,BC,3D,B7,E0,F8,C4,43,0D,E9,C3,A6,06,02,DD,57,4F,4D,66,87,85,1E,9F,23,BA,4D,39,7C,72,D8,2D,44,81,28,20,9A,68,99,C8,62,A3,05,16,CD,88,80,9E,C1,42,15,F9,D4,F6,34,09,0A,B6,9B,7E,41,CB,29,7E,F7,16,EC,67,6D,ED,65,80,FE,BD,2D,D1,77,7A,E0,4F,A1,65,71,9D,76,92,17,0D,F3,83,19,63,E8,C6,8D,FB,57,EC,DA,DD,E7,C7,D7,7C,F9,C5,37,38,AD,53,1A,D6,0F,B5,2C,ED,17,DC,45,42,0A,5F,49,94,F7,5C,90,EA,3E,21,D3,41,E9,D8,24,9C,AD,57,3F,95,B1,19,14,AF,59,E4,60,E8,56,44,2E,6E,17,23,30,2A,90,4D,3F,28,D4,0D,63,4C,96,04,C6,45,BB,A6,F3,B7,A1,B2,87,72,F1,0F,24,5A,51,1B,3B,51,DE,04,5C,65,78,01,F3,F1,A1,22,7D,2F,1F,67,8B,CC,8C,30,58,40,64,25,2B,5E,07,F3,85,BF,73,B2,3E,11,22,DF,60,ED,19,97,7D,5E,0D,19,7D,A4,F5,DD,04,A5,05,D0,25,3A,2C,5E,21,94,C1,B9,87,7A,CA,F5,4D,A9,5B,AD,52,BD,5D,0F,1F,70,4A,BD,06,89,9D,87,D1,4F,90,E1,30,6B,25,05,74,40,72,0C,70,B6,2A,36,6F,81,BD,14,F0,5C,EE,7D,35,5D,1C,25,61,E8,6C,8D,52,3C,06,32,09,DB,BD,17,60,C9,42,E6,33,EE,AB,0A,BE,E4,63,15,26,84,0A,48,F9,CD,B1,17,78,94,C7,27,9D,5D,B8,E8,DF,7F,A0,C9,DE,BD,30,A4,C9,5D,30,27,92,AA,34,39,B7,0B,3B,8A,27,C5,4A,62,90,1C,46,B5,81,FF,83,D0,2A,CA,58,BB,66,4C,4C,E6,9F,21,9D,C6,80,95,94,93,61,12,61,AF,38,9F,A4,CD,D8,F2,8A,2B,A1,39,5B,8F,20,E3,BA,4E,C6,86,70,CD,97,81,89,FF,D4,D0,99,02,3B,EB,76,90,D4,76,BB,7A,A4,A5,D5,15,36,90,C7,F8,24,7F,A9,38,0A,BC,9E,43,BF,54,1B,D4,F7,D0,0A,F2,26,5A,C1,DB,76,61,77,5D,51,4E,5C,25,4A,41,A0,14,AE,EF,6D,D0,7E,F2,DC,6D,E6,25,DF,F7,F6,C3,66,22,F7,21,D7,AF,D2,76,9C,E3,A2,74,52,07,AC,7F,41,E8,D7,8B,8F,23,99,4D,E6,8C,34,8A,0F,8B,7E,F4,48,E2,F7,CE,E9,AD,64,94,F9,68,D9,1B,0F,85,8E,F2,41,DA,24,B1,E0,E3,4A,80,86,08,18,71,95,79,E1,ED,22,50,0F,27,50,E0,6E,B5,04,78,F8,D7,90,4D,8D,5D,23,90,5D,77,B4,EA,A1,89,61,80,B1,97,1A,AC,67,46,97,83,F9,F8,56,01,25,F2,6C,94,C6,5E,BB,A8,94,D2,DA,E6,4A,C4,B6,4E,0B,4D,2D,8D,03,A6,DE,A3,A8,A9,05,EE,A9,17,36,47,72,D6,66,1A,94,C0,71,60,1F,7D,83,F4,45,04,B1,A5,A8,AB,9F,CE,43,F4,F0,38,F0,12,E1,4E,09,A7,6F,5D,8F,32,1D,70,22,03,E7,6C,78,6D,9A,60,C2,1C,34,A7,57,5E,8A,8E,E5,8E,57,FA,54,0D,32,55,87,07,EA,C0,77,C5,D7,DF,4F,DB,B3,4F,71,35,0D,20,43,78,66,10,9F,0C,E3,D8,8D,4F,F3,52,53,31,1C,B8,C8,D8,97,C9,D9,66,C2,AE,A4,97,E7,F8,64,73,90,F2,49,C3,11,5A,64,AB,75,49,BC,30,09,EE,4A,83,53,DC,79,83,B6,41,22,8C,4D,B7,6F,21,FA,7D,FA,70,FA,55,6D,4B,63,9C,6D,10,14,2B,AD,AB,BC,6B,64,E4,F1,F4,C0,27,D3,3E,77,A0,2C,F3,B3,28,62,8F,99,BD,F6,C7,55,57,11,43,61,C5,91,ED,EF,AB,C4,97,F4,2D,A4,1B,23,C1,62,46,44,CA,CF,AA,BE,E5,2C,E1,9A,64,6D,C7,A3,89,10,97,3C,4B,78,AA,2A,1C,E6,5B,B3,E8,B5,E9,A1,F1,04,BD,11,ED,A1,C0,8E,DA,44,3C,B0,6C,F2,1C,0A,57,F9,D4,80,A0,60,53,46,EA,3B,DD,A6,60,BE,E0,6C,2E,51,F5,D2,7C,A1,99,45,C2,80,41,F9,AC,54,2D,13,D0,39,32,7D,6D,72,DD,72,0D,3A,CB,C2,7D,A2,4F,43,6D,FC,54,DC,E1,36,F5,CF,82,9D,EB,30,97,77,F8,5D,E8,80,F0,09,EC,44,A8,66,B4,BA,8B,E6,A7,66,3B,2A,2F,9D,EC,55,D4,05,DF,8C,39,D1,5E,EC,FD,BD,56,64,05,D6,62,2C,DB,A8,0C,B1,17,9F,28,1D,0E,87,BB,24,DF,F0,2E,D0,2C,6C,80,32,1C,98,95,55,A1,9A,14,79,E9,4D,2E,DF,95,A4,17,68,2C,01,30,52,4A,5C,5A,65,A5,95,7D,37,0A,BE,1A,E0,B5,BC,77,A2,FB,F4,8C,BC,12,30,A9,02,D3,56,74,42,42,C3,B6,EC,9B,87,1C,F0,51,6F,D9,A0,55,D8,EF,B0,48,2F,DD,70,21,CE,88,63,73,EE,6F,37,19,C6,03,BB,37,3E,AD,C7,71,0E,E8,5B,86,22,B2,DC,A8,19,5C,A9,9A,87,18,E2,B0,ED,DC,AA,5E,97,D9,E8,27,57,A5,8C,C7,9B,9B,C9,A6,93,42,75,7B,2C,FB,0F,34,24,2C,5C,24,49,A7,9C,DB,30,03,DD,A7,23,82,F6,54,00,3F,88,99,BA,5D,63,78,2F,C2,D2,C8,89,71,EC,03,F1,8D,2A,47,9A,E3,E2,0E,F7,DC,CA,C0,C7,F3,26,19,4D,23,73,2D,32,49,CD,D4,2B,8E,EF,DE,7D,B0,C1,56,D0,CF,99,25,E4,B3,13,1C,E2,CB,13,65,85,E3,BC,A9,B6,62,DD,93,FB,B2,22,40,BD,38,36,05,F0,4E,E7,2B,E3,6B,4D,88,C4,38,D3,BB,27,7C,10,A5,46,66,4B,F6,D6,61,23,4F,C5,6F,60,4B,7A,48,4D,48,1C,50,52,33,42,C8,77,E6,F4,0D,91,5A,96,2D,44,9C,E4,09,F7,41,99,AB,96,40,99,F5,F1,00,0B,F3,47,B0,CB,80,D9,30,0C,64,BC,66,C2,B0,CA,AA,BA,16,85,49,3B,31,F0,D2,49,C6,A1,B7,C3,02,8C,72,9A,85,2C,92,F5,4A,25,B6,94,4F,29,E3,38,06,86,5D,3C,8C,3E,39,20,ED,5B,49,80,35,51,8B,39,A2,07,E6,40,E7,F6,2C,E7,4C,62,62,61,8C,CF,D1,0D,EF,01,7A,E0,40,E9,53,A2,C0,42,94,AD,95,C6,16,F6,74,ED,0D,99,69,BF,A2,3A,88,18,84,23,19,31,B9,D3,D4,5B,B0,D5,9F,22,31,6F,26,CF,93,08,FC,34,9C,6B,69,84,41,CC,5D,83,04,39,21,97,F5,6B,EA,5A,3A,E8,56,5D,51,61,1F,B1,B2,B6,F1,6A,3D,7F,E2,0F,CE,F7,89,A0,2E,D8,69,F1,D3,13,8C,07,67,D1,00,34,A7,D7,BC,F5,70,1F,DC,F9,94,7C,DC,2D,6D,9F,D8,64,CB,6D,71,67,68,4E,E4,CD,D6,D5,1D,1F,4C,48,69,A7,28,80,09,DE,24,B6,9E,58,CD,1E,81,74,89,C9,DE,54,5C,3C,F7,D7,F7,EF,FD,37,8D,39,FD,26,F8,35,50,BD,BE,8B,86,DA,EC,83,B0,79,90,13,69,4E,02,70,D4,E1,99,4B,CF,AD,8A,2C,B5,C7,B1,39,3F,9D,30,34,39,A1,EE,75,33,AD,0D,86,75,F4,C2,64,20,CF,B7,F0,84,69,C5,48,A0,6E,47,A6,20,8C,58,97,61,F2,8C,81,F8,B9,96,66,85,A9,87,E1,24,1F,91,3E,32,06,18,8D,6A,F8,A2,56,E7,61,BF,80,50,62,70,12,45,7C,03,03,08,B2,08,78,83,95,47,1B,03,00,42,D0,EF,95,F7,45,7F,E2,BE,94,2C,2B,A0,C5,77,63,EE,76,BA,DC,51,D0,6D,3B,DF,53,3D,AD,8D,7A,8A,C3,0E,AA,C9,53,73,03,9B,8F,8C,1C,3C,5A,68,1A,07,CF,C3,B2,3F,92,9F,9C,42,EE,B0,5F,3B,36,2F,1F,CC,D5,FC,6C,08,EB,4D,F4,05,6A,0D,0D,14,61,41,FB,C3,5F,EC,71,23,BF,6B,00,CC,6B,7D,95,A4,F9,B0,28,14,5E,59,E0,7D,A1,92,BF,59,EB,DA,D5,88,A5,BF,DB,6F,3C,39,06,41,FF,5B,D8,3D,E4,42,94,11,0D,72,D1,52,57,76,7B,27,95,53,02,4D,CD,7B,D8,9C,6D,B7,23,B4,B7,ED,3A,15,CE,49,D4,F2,6D,CE,A8,75,6C,E1,94,18,2E,23,26,E5,58,2C,FA,38,5C,27,FA,94,28,18,87,B0,70,99,A3,A6,E1,4B,3C,0F,E7,18,20,53,AE,0D,41,84,FA,73,11,EA,37,91,C7,69,BC,86,6C,44,A4,AB,C9,2B,E3,76,A3,6A,51,85,89,59,57,EE,28,93,62,3F,E4,A5,8F,38,A1,07,BA,09,47,B9,A3,08,E0,68,34,D5,10,27,D5,46,7E,09,9F,33,D6,3C,02,3B,43,61,4F,03,DD,52,1A,CE,EC,63,99,45,38,A5,3C,91,38,D7,69,6C,65,99,3C,CF,D4,F5,56,ED,B8,A2,08,C1,47,26,16,42,A3,83,A9,31,1C,1A,2D,FA,6A,84,50,D2,7D,09,2A,7D,F2,50,0B,3B,0A,C0,E1,8C,27,A1,3B,62,AC,CB,D7,08,A9,2F,C0,82,C7,B6,67,48,6D,7D,41,C8,50,E0,AC,C1,2C,BE,4F,CC,36,4D,A5,60,12,FB,6F,39,C1,97,B4,46,67,E5,9E,1F,13,C3,06,15,E2,01,3E,5E,13,5C,60,38,CB,47,DD,EB,78,C7,1D,59,1F,EA,27,1E,17,7C,BC,A3,43,9A,6B,02,7C,7B,CB,7D,81,CF,A8,D4,09,7C,0F,C5,11,7B,6E,B5,50,43,1A,2B,B2,60,C3,5E,E7,FE,BF,67,2C,B2,98,8C,B6,06,50,5E,22,85,7E,1A,6B,20,38,2F,D1,D2,93,46,5E,B9,F0,84,DE,25,54,E6,B5,33,C4,D1,F7,CC,12,A4,A4,1D,A2,96,74,B7,33,33,2D,EA,79,47,D9,8B,CA,64,13,83,BE,FB,6A,1B,D5,4B,EB,5C,4C,80,16,A4,4A,5E,F5,63,14,A8,34,55,13,29,F9,AA,E0,8D,CE,E7,BF,A6,95,30,CC,C8,F0,55,88,67,E4,81,73,59,BE,72,AC,85,D8,AA,52,73,0B,D8,14,8B,61,44,5C,21,78,2E,85,7B,3A,CD,65,A2,9D,8A,A5,15,F3,EE,AF,D9,4C,02,B9,CA,F4,2A,34,59,59,D6,A2,B7,28,CB,D9,B0,ED,6F,38,F7,9D,DE,03,26,50,98,E9,1C,96,49,51,4A,6B,C9,20,6E,27,78,BF,82,40,B8,BE,5C,51,03,A0,BA,FB,22,E4,1D,F6,C8,E1,D2,2A,B6,20,C1,9D,EF,F6,FA,80,72,70,53,65,19,9B,5F,3F,07,A8,41,44,82,11,29,0D,2C,89,F5,09,45,8C,FD,5B,9E,31,22,B1,31,5F,FB,C3,F4,F7,E2,30,3D,09,5B,71,F4,2E,85,BB,A6,9A,4F,2C,FB,B1,7F,CB,39,CD,86,16,3B,1D,00,0C,C2,93,BC,AA,2A,DB,DB,19,5B,78,93,62,AC,58,E1,B6,21,CD,66,94,BA,86,2A,53,BD,C0,07,2B,5D,8F,2F,D3,CF,C6,78,2E,9B,09,86,C0,11,C4,C2,25,87,3A,F1,B8,D9,E6,FC,9B,79,DA,B3,23,C4,89,84,35,F7,C9,6D,EE,2A,FE,54,9D,E5,34,41,6D,00,FA,A3,59,1A,87,37,13,FF,D1,E2,EE,C0,E0,4F,EB,2A,A9,B2,88,3D,4A,EF,1F,1E,40,AA,04,B6,EB,C7,7A,A7,B6,A1,68,77,6A,C0,70,8A,96,06,CC,FA,2E,6E,59,6A,25,64,20,45,FE,F4,D5,07,B8,57,EC,DC,2B,43,9C,FE,07,87,00,42,E0,FC,4F,25,CF,94,61,16,44,F6,D6,C1,89,33,51,69,3D,01,FB,C2,1A,33,64,AE,3D,20,70,0E,F1,89,CD,40,FC,89,38,2F,C1,FF,8C,07,3B,2B,47,E5,A6,A0,13,F5,D6,FE,6D,CB,D3,CF,25,12,98,9A,9F,2E,6A,41,C3,CA,36,4C,DA,C1,17,E1,81,DF,6E,67,BF,6E,9F,ED,8B,85,2B,3A,58,9F,77,41,FB,42,4A,1C,E5,4C,5F,4B,4E,7C,40,DC,07,A4,EE,6E,8D,7B,9B,59,9C,7C,DE,E0,C2,D5,D1,43,71,CB,F0,D6,37,4E,7C,E6,19,1D,8A,C5,42,D4,09,F8,C4,D4,F8,14,45,45,64,57,C8,C5,7E,AF,A4,AE,E1,05,43,83,21,BE,77,8A,E1,44,E4,55,0C,EC,42,0D,39,F6,5C,65,49,BC,62,7A,5C,FD,7A,5B,52,BB,11,C7,A4,CD,1A,E6,ED,A7,DC,EE,D9,12,48,09,AD,1C,F0,79,B2,4E,F5,15,B6,64,B5,FE,6D,D5,79,86,63,7B,04,1B,5E,83,5A,2D,12,92,E7,17,47,65,1A,A5,91,25,EB,22,DA,60,EE,7D,A3,E9,F4,BF,EB,B9,33,23,02,39,A9,33,4D,F4,93,48,BE,34,E5,8F,BD,FD,8A,8E,F0,E5,A0,8A,71,51,46,12,6F,4D,44,7C,08,35,BF,D5,C0,DB,5E,AF,66,F6,5F,8A,18,63,A4,F5,00,CF,EA,F7,08,AD,36,09,36,8C,EB,4B,47,08,1F,6C,A7,BC,D8,B7,B5,C1,11,FC,7C,35,10,EB,80,16,15,65,87,8D,FF,0A,3C,01,95,C5,C2,4A,06,6D,3E,02,FF,FB,01,74,C0,AB,AB,A0,D1,DB,D0,88,A9,4B,4E,E0,6D,37,E2,4F,E4,23,11,6D,4C,EE,52,75,3A,74,A1,54,F0,FD,5B,8D,67,BB,96,FB,DF,5C,EF,45,71,05,D5,2F,D0,2B,FE,73,A2,01,B7,11,68,A2,56,3E,7A,21,53,AB,C0,D4,17,C7,23,42,AD,E8,B4,9F,70,BB,8E,8A,D9,E4,F6,63,68,81,3A,70,BB,2B,57,4F,94,11,46,15,5D,A2,A8,64,F8,EA,9C,41,68,68,81,AC,7A,6E,8C,90,D8,DE,5A,BF,AB,61,C3,57,BA,A8,3C,CF,D7,C8,A6,D1,88,F2,4A,70,5F,09,54,CA,90,5B,92,95,5C,5F,EE,59,65,B3,07,3E,CD,5E,3D,B8,7C,08,80,F5,62,F7,85,B5,6C,D4,76,B3,5D,27,57,3B,C4,E6,CF,A3,BF,5C,5A,6E,2F,E5,B5,79,49,B1,38,E8,C3,F8,F8,D8,2E,19,73,C5,5D,74,62,82,0D,7A,FE,0A,DF,38,F0,0A,51,18,DB,A4,0D,FA,D2,C3,C0,18,14,C1,8D,EC,C9,8A,BC,53,43,CA,5B,D5,09,6D,8E,C8,22,FF,D7,72,34,0C,F2,E1,9D,FA,CA,8D,D3,52,1E,E1,90,31,12,64,D9,41,B9,74,1F,EA,C1,8F,7D,29,7E,7F,EA,38,41,9A,C6,F1,C8,1C,0A,FE,6C,F1,A7,12,9C,AD,72,B8,67,70,54,BB,EE,FC,E4,EC,51,34,5B,F8,C9,84,F6,77,77,33,27,DC,F4,1E,E6,A9,7B,1B,F2,27,BB,BF,14,0E,96,24,D0,8E,31,4A,81,6E,4C,94,8A,F1,FC,F0,D5,6D,41,76,52,99,12,B4,C9,56,1D,61,DF,67,26,5B,CC,23,14,D8,4E,FC,B4,DE,0E,6E,20,61,53,E2,0A,87,4E,DE,E4,3D,F0,DA,C4,C2,10,CF,28,ED,DA,0A,9A,DE,B5,E9,FE,5E,1E,65,7E,94,DA,91,0B,49,77,88,E6,29,B3,B5,A6,89,6F,23,6F,92,12,69,67,46,47,3D,02,CB,EF,DD,17,A7,E1,D9,30,C6,5E,D3,31,C6,5B,5D,29,E5,E5,6A,32,08,94,F2,34,92,EA,60,33,8B,D9,FE,AE,DB,A7,BF,6A,F4,8F,1B,0C,90,27,2F,69,E8,C0,8D,19,1D,5C,7B,30,B9,D6,AF,42,50,21,6E,0B,24,A8,93,26,51,AF,D2,29,F0,AA,CB,4D,C6,DC,70,11,FB,F9,0B,E6,90,1F,21,49,77,1F,2B,F7,15,D7,CB,7C,62,58,82,8B,09,02,FC,5F,A3,49,1C,0C,D3,01,09,E8,A5,45,F2,E4,77,FB,8E,85,B0,25,36,22,8E,E9,D8,EB,25,22,81,FC,14,6E,20,C9,87,09,88,32,0A,4B,68,0F,F2,4F,B4,9B,01,E5,5C,69,0F,47,66,AB,08,30,29,31,EC,F1,70,70,8A,AD,86,AE,5D,5A,1B,1A,C4,E9,43,CA,9A,32,80,77,F1,27,DC,95,1B,8D,9A,28,77,AF,A0,C8,47,F4,41,74,77,59,E3,C5,8E,7E,5F,0D,B0,7F,F4,AD,2D,70,40,9C,50,F5,C7,32,26,4B,1B,3D,D2,08,62,8B,CB,D7,F4,C0,1E,4E,4D,75,E4,0C,7D,16,E2,FA,AA,31,EA,C7,23,0F,EA,95,1F,35,BC,BE,C9,7F,3C,EC,57,6A,C9,6E,0E,48,91,FF,C0,3A,EA,C5,A6,8D,6F,F8,77,BF,A0,26,92,29,9A,C8,9F,06,43,3E,EC,FD,4B,A6,C0,49,47,65,71,06,CE,3E,C4,04,FB,7D,A5,E5,EC,FD,F9,17,A1,68,AD,91,C8,06,39,4D,B5,9C,8B,A2,C6,90,F4,83,55,CD,29,60,B2,B2,C2,40,FA,4A,86,7E,74,F6,67,26,2A,22,10,63,44,61,83,FA,FB,8E,13,62,98,AD,4C,D9,E1,64,75,5C,E0,81,3E,44,84,16,44,4C,08,2C,BE,2F,77,9D,A8,A1,45,2E,5C,08,A7,60,64,EF,3C,9A,6B,5C,34,D7,B3,34,13,8A,B7,B3,35,9C,4E,C1,36,C1,59,AE,61,0D,1A,5D,72,75,BF,EB,BF,9C,83,D4,55,A7,E4,1F,16,C8,B1,AF,89,51,5D,5D,DB,27,E6,7D,44,B2,A2,A3,BA,32,42,51,31,CE,C7,12,89,E1,7C,1A,C7,90,A4,F7,4A,B1,BF,32,2F,20,BC,81,FD,87,E6,CB,77,41,2C,F2,14,B9,28,64,64,C7,52,90,D0,86,9D,0A,37,E4,C5,1B,ED,00,BF,16,33,41,99,67,35,39,20,DD,F7,E0,DD,1D,29,89,BC,AD,FE,6F,34,5A,D3,A5,CD,17,7C,B1,93,16,A2,E3,42,78,2D,20,68,41,06,11,40,87,2F,C5,21,0D,A9,90,6E,28,FE,F8,F5,70,E3,D8,03,86,68,ED,3C,EF,4F,CA,A4,B4,C5,03,11,32,3A,27,A3,B9,AA,0C,38,8C,FF,6B,66,50,CF,5B,90,19,AB,21,E7,B5,57,B9,9B,8E,5D,58,28,6B,00,F4,B4,19,30,F4,38,12,D9,FA,18,A3,DA,AE,4E,26,01,85,29,AD,CF,E8,5F,A5,DA,2D,C0,2A,A5,35,E7,8B,F9,70,43,FC,D9,B5,FB,6D,1B,5C,43,B0,57,1A,B8,19,B0,D4,9D,00,32,37,CE,66,6D,9C,59,B8,74,2E,77,AD,6E,2B,A2,30,D8,7C,89,96,FA,C5,17,B5,25,26,73,04,7A,AA,B5,FF,27,9C,23,02,D2,0E,12,09,5C,D9,AA,76,06,01,24,4F,14,18,83,F5,F4,A4,8F,80,84,9B,E1,8D,CF,46,9A,3D,60,4A,D6,04,B3,23,9B,75,0B,1E,29,68,DA,59,02,0C,0D,A6,9D,47,FC,A4,A3,77,C8,DB,FF,FD,8E,B0,02,9A,4C,CC,C7,92,8B,FC,C0,47,7D,71,D5,6D,6F,71,6C,66,A1,EF,C8,D1,14,38,D3,B7,5E,15,CC,7E,61,A0,62,ED,1B,BD,8C,AF,6A,82,23,2E,93,2F,9A,1F,8C,CB,6C,80,BB,F6,73,FE,3D,8E,BF,59,5A,6A,E7,96,53,55,1C,6E,A4,15,60,38,FE,4D,49,4A,8B,80,C2,A2,7F,AE,33,92,62,6E,12,47,75,F9,93,98,76,08,20,CF,F1,C7,6D,E2,10,D0,77,24,38,04,4D,1C,5B,7D,58,68,5F,8D,1A,BC,1F,EB,72,A9,02,E1,6E,CA,F2,F7,58,80,9C,F0,C2,2A,6C,EB,9A,73,8A,31,D3,00,B8,B0,6F,26,F1,6C,BF,73,0B,BE,A3,7E,EC,D3,3E,47,2D,5B,C3,86,0D,87,EA,02,12,B3,A3,A9,CE,68,42,77,31,B6,6A,31,48,DF,B8,C0,F2,C9,B9,12,8A,D0,06,C3,25,DB,3B,06,36,B2,AB,C5,03,18,AE,61,67,F0,04,C4,A0,A7,8B,E7,1E,16,9A,51,2C,31,36,85,F5,29,C2,2E,09,B0,38,C5,13,00,F8,4B,88,23,EA,36,34,37,AE,47,EA,87,3C,3B,27,36,FC,88,D3,EC,46,B5,3C,0D,92,16,E1,D6,C7,FA,7C,61,9E,D0,8C,BD,54,EE,0E,99,FC,B8,2E,32,2C,5B,54,7C,C9,40,0C,77,58,86,3D,2C,56,CA,2B,B5,33,92,CC,E2,6B,66,39,BA,93,FC,BE,2F,63,E5,D4,1B,FD,2D,CE,93,73,25,5D,09,1D,B5,49,2D,D1,D5,0A,B7,5B,F5,D3,E1,84,8F,02,CD,C2,71,5C,AD,A1,AE,8F,62,2F,F2,B8,70,DC,24,FB,7F,70,BD,74,83,1B,ED,7D,B6,40,D5,A2,CA,7A,39,84,01,52,30,86,FD,C6,C1,10,1D,D0,F1,0A,25,CA,2B,01,FE,70,75,80,C9,07,1E,DE,21,B7,81,17,A2,7B,CB,A6,8C,AE,43,08,16,38,36,7B,95,AF,2D,9C,0C,A8,97,25,22,A7,26,4A,92,02,BF,DB,7B,E2,1B,7F,EE,D3,DA,86,DC,23,25,D0,AB,EC,88,D9,5D,87,2A,63,31,C6,82,3D,76,B7,B4,0A,30,99,85,F2,AC,3E,FA,57,0B,72,89,78,AF,A5,E3,80,95,1C,57,40,19,54,68,96,2B,BB,C6,32,4B,34,B6,10,80,3C,F1,26,C3,74,80,F6,4E,5D,30,A5,4A,B7,EB,4C,89,E9,51,18,FA,88,74,BD,0E,E5,9A,AB,26,4A,87,B9,B1,C0,13,8F,53,E2,F6,AF,22,2C,85,04,C7,B7,8F,14,57,77,AE,35,9E,87,12,58,CB,A6,78,23,C7,D3,A2,5B,2D,DE,78,C0,6A,64,BD,EB,E9,15,84,95,C2,33,53,4B,B1,C7,43,EB,58,9A,62,B6,3A,95,3B,7F,AF,7F,99,F6,15,A7,2C,B2,15,A2,6A,AE,A2,A9,ED,6D,D5,55,AA,70,AB,58,9F,3F,40,7B,86,DF,BB,EE,3C,6D,6D,69,1C,77,74,90,15,B4,7C,18,D3,66,9C,6A,31,FE,7A,C1,62,DC,63,43,66,20,AA,7D,94,15,65,14,80,74,E7,AE,D6,BA,A8,86,FC,F7,6E,1A,EF,77,61,A1,A0,0A,B2,16,E5,9F,7F,BB,13,4B,4B,1A,48,EC,1B,CD,54,01,94,24,34,C4,95,F8,82,A5,37,49,EB,61,96,37,28,40,16,11,CA,C8,00,0B,86,F9,8E,70,A4,B1,16,14,BD,F1,ED,95,89,4B,D6,9E,81,BD,C7,97,F4,5D,D5,03,D5,90,F1,13,41,7B,DC,7F,C0,BA,61,15,BC,4F,EE,0E,97,84,95,0E,79,B2,68,E5,14,8A,58,10,4F,2C,57,71,A5,38,A0,E7,CE,AD,CC,F7,B1,5A,55,77,12,E2,06,14,EC,8D,F3,B1,A7,4C,92,30,44,F2,A3,5B,49,BA,D5,A3,EE,C6,6A,95,10,F2,51,97,A9,D2,00,D4,5C,EE,56,71,A0,26,3F,EB,E8,61,55,51,AC,AE,CA,AF,D8,15,3D,DA,B9,09,C0,C3,D7,F6,67,18,73,99,99,49,5C,85,E2,08,4F,7D,D3,58,5B,89,72,C8,29,F2,7D,95,A3,8C,CA,EC,13,2A,4E,8C,7F,22,81,2D,DD,8F,05,1F,E5,97,45,8A,12,2B,00,05,EF,B7,01,FB,A7,E8,0D,13,BB,9F,B1,BB,CA,B4,64,73,04,18,34,AA,12,80,FE,ED,B5,9A,6C,84,5E,2A,AC,25,45,95,E4,41,E6,2D,75,38,EC,2D,06,13,C8,74,8E,0E,92,E4,85,A8,DE,09,00,2B,E8,60,7D,6F,95,EB,43,5C,E5,98,B3,48,DF,C1,16,BE,27,F1,D8,25,BA,B1,86,13,1D,2E,79,EC,AB,D1,44,3B,82,10,13,1A,C1,55,D8,07,9A,49,F6,5D,B8,C9,2F,2E,53,B5,09,73,4D,EA,35,69,84,F0,92,59,6F,9C,1E,4F,92,C5,9B,4A,12,1A,7B,81,8C,D0,51,F4,46,7A,C9,6F,10,D6,F8,6A,F4,C7,85,07,DD,36,BD,68,1A,3B,94,81,DC,BD,BF,6C,E0,52,86,36,C5,48,C7,7F,42,30,FC,E8,5A,4F,10,D5,C4,F6,46,4B,00,26,9C,C5,37,30,89,F7,67,6D,7D,16,FF,78,6B,4F,97,AF,7F,BC,C1,27,48,FC,C5,FB,61,9E,7E,A4,16,DF,B8,33,1D,FD,F7,E9,25,07,DC,E2,C1,E6,92,7C,39,6F,64,11,DC,6F,A7,99,FE,F1,7D,45,D5,C3,E8,5B,29,1D,44,DF,5B,BD,E9,8C,AA,B6,D8,25,44,0C,F6,7C,A3,B3,31,B3,29,7B,EB,94,00,BA,B9,74,7C,47,D9,3B,12,B2,50,D3,A1,3C,B0,4C,3B,5C,99,BE,76,1E,C4,AA,13,1C,64,31,3F,6A,93,24,6E,39,A5,58,B0,9B,AD,DF,9F,06,CB,64,E0,2D,1F,86,C6,8A,F0,BD,6A,84,D4,F6,51,C9,FF,DE,0B,7C,17,D4,25,72,42,3B,B7,E5,43,64,01,3C,13,91,D1,38,62,4D,04,53,79,F3,A8,35,8C,95,71,F1,35,60,F0,9D,94,48,D6,57,00,2D,D2,06,A7,B6,37,D8,78,9C,6A,28,50,A7,6B,4D,4D,FF,93,DC,D8,30,04,1E,A9,EF,C6,CE,0A,1F,DC,38,13,B0,74,6B,8B,18,53,39,8F,95,4A,8E,FA,4E,6A,D9,68,15,E9,23,72,50,5C,0A,25,D2,0E,90,72,D7,FC,88,0B,A0,E4,9C,CC,0F,0B,E0,95,66,71,4C,72,D5,71,01,20,5B,1F,12,92,F2,21,1B,BF,65,78,6D,9B,1C,57,4D,5D,44,73,93,0E,2D,42,FE,28,08,98,98,30,D6,91,19,F9,8E,4C,BF,AE,14,30,4A,51,37,ED,0E,19,F6,C9,C3,7A,C2,85,1E,67,D4,11,6E,36,FD,04,20,CC,C5,30,7C,18,8E,5D,7E,AB,C2,8F,96,C6,AB,8C,77,A6,D3,AF,10,2A,0D,5D,F7,DC,B9,5B,02,3D,4A,E9,88,99,37,86,C6,53,90,A7,0E,B3,89,56,5D,0A,EF,A8,A4,B1,07,71,2B,C9,DE,7C,51,92,7A,90,D4,08,78,47,B6,4B,80,2F,78,CA,8E,DB,3F,F8,11,11,AE,69,D5,65,8F,0E,D2,CC,EC,55,3D,8C,20,72,A3,81,B2,90,F4,A6,18,A2,99,88,51,22,3B,57,4A,0D,96,40,DF,44,B2,41,E4,8C,D3,5D,8E,20,FC,E1,F5,5B,B1,DA,7A,5A,15,F3,F9,B2,4E,D9,00,2C,5C,D3,DF,08,B1,B8,D1,09,5F,36,7B,47,1C,CE,D3,39,F3,AE,57,0F,14,AD,19,19,AD,7E,63,AB,CE,10,C3,A6,34,E0,00,E0,9E,06,1E,1B,2F,96,9F,A8,5E,60,07,95,45,45,B3,F0,A5,80,A2,00,12,74,4C,58,78,D1,C7,C3,3C,95,52,56,D1,72,15,8E,C7,04,E2,4F,23,36,7E,07,96,D7,34,B4,D9,9E,01,3F,70,E8,59,95,17,BE,E1,10,EC,B1,10,C7,77,BB,6F,89,32,80,F6,AA,3D,1A,CD,C7,CE,8F,BB,A4,BC,04,CC,CE,AB,4E,18,DF,65,10,16,97,8D,4B,9D,0F,A6,B0,5F,14,34,44,BA,74,F9,7E,DE,F6,D1,E4,C8,2D,17,5C,40,D2,58,AD,49,9B,03,1F,A8,4A,F6,E5,78,3D,94,24,CF,A9,12,D8,14,1A,AA,A5,2B,69,11,5C,0E,AA,90,8C,D2,4E,55,94,76,40,11,E4,5F,41,DB,74,E9,F7,39,7C,F1,AD,D3,6F,DD,A3,31,0C,3C,33,B9,7C,51,CB,26,78,58,05,80,60,B8,33,43,20,C3,88,3C,6A,88,DD,58,E7,9B,29,06,8C,7D,18,61,0D,68,3F,D8,0C,47,8A,07,EF,5B,E9,A9,3A,4A,77,4D,E2,A0,F0,84,DB,B5,4D,1C,C5,8F,E2,D3,B3,93,87,D9,C7,5B,CD,89,FB,D8,29,E6,75,26,D1,73,6B,B1,E0,29,9D,E2,AC,A1,27,2D,53,D4,36,DA,7E,88,C6,D8,92,C2,1A,3D,B5,2E,4A,56,A3,3E,82,74,1B,02,28,55,7E,51,8B,FB,BA,3A,AD,EE,F5,5A,68,4B,3A,30,DB,D3,90,6D,FB,15,DD,89,E1,B6,87,D1,22,A5,08,32,A6,A8,B2,BE,81,25,C7,E9,2F,2F,C1,D3,B9,8D,87,D2,DF,20,1E,BF,A9,3B,59,19,97,EE,2B,6D,FC,EA,35,7B,35,69,42,0F,E6,5F,7E,A2,AD,77,01,3F,17,6D,B4,70,0A,26,90,CE,46,8D,C3,A1,FB,90,39,11,4D,7F,BE,30,34,91,42,58,88,85,3F,5F,C1,C8,57,F9,66,B9,98,E6,39,6C,00,F7,76,86,EA,92,53,F2,E3,5C,D9,FA,77,84,EF,FF,AF,38,DE,5D,B0,0A,03,1D,46,0F,0A,F0,70,3D,34,A3,58,17,A2,A4,65,42,71,AB,30,03,D5,3B,B6,8F,41,EB,2A,C2,CA,59,62,CD,A4,1D,1F,A0,4A,D1,72,BE,FA,A8,A3,30,5B,FF,49,43,D4,77,E0,9C,A7,37,DC,BF,55,C7,89,6C,AC,C1,B2,19,1C,0A,CA,23,BC,F3,76,8B,F6,94,67,D1,1D,01,92,8F,CB,C9,13,59,EC,B8,E9,EA,97,9E,D7,50,DC,C7,09,91,5A,CB,0D,9C,9C,3E,6D,53,15,36,7F,66,2E,61,67,79,F6,0F,DE,7A,6A,D2,6F,41,78,56,F3,9C,66,FB,61,C4,D5,94,50,6C,9E,03,C0,87,63,0E,D4,85,BE,12,ED,37,70,01,E3,79,DB,5C,45,5F,95,4F,F7,3D,B2,C4,4B,CB,CC,CE,60,A7,B6,BE,DF,8F,E5,A7,D8,0A,9D,57,F6,EF,BA,B9,06,ED,16,64,A8,B7,46,54,8E,0D,78,38,D0,BD,F6,F5,A1,B1,11,AD,76,DE,E7,70,0B,F9,D2,4E,17,01,FC,D8,63,D4,36,39,4D,F3,E7,7E,68,8F,9D,5A,15,7F,E3,28,9D,91,B8,89,62,90,0E,93,79,A9,ED,A9,C7,51,1E,9B,47,A3,24,B8,E2,DC,D9,84,67,F0,64,80,39,E6,C9,BA,F1,F5,80,89,C1,00,AC,42,60,77,5A,39,ED,E4,0B,E9,9D,A3,A3,9B,38,9E,7D,29,A0,DA,E0,55,EF,DE,8D,F3,1D,6F,DE,FC,34,E4,9C,8E,CB,86,72,66,75,FA,6B,C5,61,04,AF,60,48,6E,8D,2F,B4,E0,50,32,6A,CC,89,C9,B6,48,10,A6,8E,AF,CF,A8,55,E1,43,12,8B,87,10,7E,C1,B4,63,A6,E4,8F,45,37,6E,15,E5,82,4C,95,A2,48,86,F8,0E,77,D5,42,B9,62,0B,F2,38,55,D8,F0,F9,5B,D4,21,8A,18,95,72,EB,C7,E9,ED,0B,23,A3,0E,28,9D,54,97,33,F5,D4,A0,46,6F,45,C4,0D,BF,AD,E9,50,BC,8B,E7,D2,EA,B4,0A,BD,BB,F9,C4,1B,1F,6C,9D,F2,14,A2,B8,1E,43,4B,AF,40,45,06,A8,8C,EA,5E,B2,BE,CA,63,C7,B7,FD,89,7B,7A,58,39,5B,2F,0D,9F,E3,F1,DC,8D,A3,E9,2F,CF,BF,F8,ED,B7,3D,97,E4,1E,40,01,B0,06,F8,9B,E9,77,99,F9,BC,51,85,41,6A,CF,90,82,CB,D4,98,5D,AF,03,0D,AD,66,CB,34,C5,0A,23,35,C5,66,95,3B,EB,F2,39,CE,82,22,05,B2,5A,6C,37,3D,85,F2,7A,C2,1D,15,5D,7D,E7,38,6E,4D,E9,AF,3B,C5,43,8C,2D,C1,31,7C,06,40,51,26,39,EB,14,F9,C0,61,5F,CE,7A,38,41,97,72,46,9D,98,6B,E7,D9,DD,09,25,33,5D,B5,93,15,DE,52,93,E8,89,DD,D3,2F,6B,B5,4E,F1,CF,25,8E,91,73,0A,D6,A3,48,DF,97,D2,37,46,FE,C0,5D,99,EE,80,58,50,C6,44,98,D9,AD,FB,38,E6,7B,92,CC,7E,D8,ED,4E,57,0B,60,F3,BF,74,15,D4,44,FB,39,7E,1D,0B,DB,FE,29,E5,93,12,D6,FC,5E,E7,90,B0,EE,7C,6E,82,D5,9E,62,4E,04,F9,0C,EA,21,2B,00,A5,06,88,32,96,EF,70,F5,92,80,46,6A,C8,75,00,1F,26,48,53,11,64,45,B3,7C,DC,67,8A,52,C8,A2,E3,95,51,A3,23,81,F8,96,AC,5E,7D,9B,1A,1A,A7,3A,6E,2E,99,E6,69,96,DD,46,6E,29,6D,81,DD,00,AA,E2,01,57,CC,14,86,09,48,18,A0,0A,45,F6,EC,D2,8C,D9,DE,A6,4E,5D,85,91,6F,D0,5A,97,88,C1,40,FC,59,20,A9,7C,31,02,A5,1E,C6,4A,84,D8,01,5D,B4,05,60,A7,A9,21,E5,A2,8A,4F,17,F6,23,2D,5A,66,6F,22,BA,A4,27,EF,42,90,CD,8B,54,B3,3A,97,8B,20,5A,20,08,F6,7B,30,E3,3E,C7,8D,B9,33,C2,9D,09,45,81,BD,A2,10,81,57,FA,1B,A9,67,8C,18,FB,33,4E,0F,D6,28,27,2D,37,EB,D8,20,5D,69,11,BE,DB,B8,4C,8A,F1,C6,E5,80,4D,76,61,70,AC,B6,F4,54,DA,F6,93,2C,B8,B8,08,8D,DF,9C,08,17,E6,57,07,DA,12,78,CC,AC,92,17,0E,C5,64,CD,E2,DC,0F,3F,1A,21,5E,55,61,8F,61,F2,26,88,80,E0,1D,8E,40,A4,FA,E1,53,AD,27,3F,14,57,45,CF,B8,EF,1F,C3,88,79,EF,1D,FD,96,D6,F7,A3,F9,0A,A7,90,C1,2E,99,51,71,1B,34,EB,43,FB,DD,9A,40,7D,30,97,8C,D6,14,F0,A2,10,D4,7B,92,3D,12,1A,25,C5,4D,62,7A,5D,6C,19,B5,DD,AD,2C,9F,BD,8E,4C,35,A1,D8,9D,3D,C4,92,D9,AD,01,11,47,2D,F0,6A,50,59,4F,1E,17,B0,AE,53,80,16,7D,3F,6B,7D,CD,30,49,B5,D9,40,17,20,64,DC,8E,C5,93,BD,E6,16,86,9D,48,AF,66,D6,1B,35,89,D1,1C,BC,01,5F,8C,3A,B1,0E,4F,62,46,E0,5B,80,30,8C,D5,A9,36,CC,58,23,6F,50,05,9D,3E,21,83,35,63,C1,33,DE,AB,90,8B,1A,7A,36,1B,76,65,66,19,18,6E,83,07,E4,53,1F,9F,09,45,60,F4,30,2E,DB,CA,28,79,FA,4D,39,D4,F8,C0,92,29,00,0D,84,DE,8E,8F,A6,E8,14,D3,6B,87,20,C5,9D,B0,B3,39,CC,F5,73,56,3C,64,EB,09,F8,D2,70,D3,F7,70,44,82,C9,CB,6C,F3,1C,2B,B5,CC,D5,58,6F,98,89,D3,35,14,83,E0,E6,0B,B6,D1,03,57,04,45,B9,96,29,9A,8D,79,E2,0D,8E,30,FB,6E,6D,94,2E,F7,D8,FD,AB,FA,5D,3C,70,0E,AE,00,D5,8F,09,30,CF,F2,6C,8D,88,02,C9,41,6F,F0,5B,25,00,4B,E6,AD,C2,16,EA,FA,0F,43,0C,88,AB,29,4D,7E,37,5F,E4,7B,24,9B,89,A7,D6,EF,C4,2A,CC,F5,CD,02,09,1E,E6,E1,34,50,F6,59,21,71,40,EE,5F,BA,A7,CC,AA,F7,F9,FA,BF,2C,26,07,62,E5,09,5F,A1,AF,84,6D,58,4B,7A,86,79,14,9F,59,B1,F3,A4,3B,5B,2E,1A,E3,45,5F,77,DC,4F,06,C5,4D,45,D4,8E,6F,7E,4E,BA,0E,EB,27,A4,92,C0,CE,90,07,AD,57,09,6E,A2,1C,36,F5,82,76,1A,92,7D,0C,DC,E7,A0,C5,84,A5,2D,72,2E,74,08,E0,46,5F,3E,76,79,CE,7D,72,01,1E,83,D8,98,E7,46,AF,2C,50,9B,44,CB,0F,79,63,C1,F0,E6,36,0B,43,5D,ED,C5,63,50,D3,91,29,DF,69,14,63,A7,98,5F,FF,A8,63,F7,55,75,A2,97,CD,4D,91,90,03,BA,E3,6B,5F,58,9B,F3,25,F7,1C,3A,8F,E2,0D,6B,6D,0E,47,6F,9D,58,46,3A,4F,02,00,06,DA,4A,37,D1,BD,F0,01,4B,B7,93,68,25,5B,32,71,B2,38,65,34,1B,C4,28,14,41,48,D9,91,FD,38,13,E8,0B,64,77,A6,83,AE,33,45,06,5B,3B,F5,37,90,37,31,AC,91,65,F9,F0,24,EF,D3,06,44,EE,25,37,FB,01,F2,6F,9B,97,9B,91,76,DC,AB,38,72,9A,1E,05,E1,DE,63,0B,D2,9F,D8,9C,33,52,FD,44,F4,F7,47,6A,DA,22,8E,64,38,62,EA,C8,E9,EF,5A,F5,CA,2E,D6,D8,2A,8A,B4,1A,B1,66,C0,F9,9C,07,22,49,86,E5,30,B4,F5,FE,B5,F0,7F,6C,60,17,C5,01,56,2B,C8,7E,70,4B,68,F9,C2,C8,66,F5,04,EB,66,6E,D6,81,7B,7E,D1,E0,D3,95,43,D9,F9,2B,80,6D,34,14,47,CE,B0,1E,FB,6B,7B,FE,AC,85,16,2E,7A,C6,DD,4A,F3,B8,D0,AF,08,71,26,2A,1C,96,DF,37,F1,54,43,33,6C,D3,26,B4,2E,D2,8D,16,14,78,5D,7E,9B,D7,A1,8A,83,F2,2C,F6,64,C0,C9,96,6D,AA,70,4D,90,D5,12,3F,56,A1,CE,66,C3,B0,03,0D,E6,92,95,8D,72,B7,94,D7,E4,D4,C3,D0,38,C0,94,8C,71,5A,D7,D2,F4,78,B5,C8,A1,CD,19,E1,BD,D9,B5,33,B3,A4,25,B1,79,62,E4,FF,C1,60,02,58,5E,BA,79,2F,FA,D6,82,0C,1C,23,F8,1D,8C,FA,F2,71,AF,49,86,29,11,66,4A,58,D1,20,DA,E8,65,5E,9D,01,2C,33,80,DA,A0,ED,38,82,AE,A9,5F,A4,93,7F,36,76,80,0B,15,8E,EF,C0,02,AD,58,34,CD,01,D0,E0,D6,6A,CE,D0,49,95,11,50,75,AA,EA,2A,2D,4D,7B,09,62,0A,1D,61,71,B6,D8,28,CA,3F,4D,6B,6B,9A,9D,9E,0B,99,68,65,2B,61,DF,95,BC,E4,BC,22,8F,67,EF,97,B5,77,B1,63,31,74,89,65,E5,9F,E2,03,70,5D,B0,21,13,61,6D,E0,E6,E5,55,60,27,46,AA,59,CF,DC,28,DE,15,6D,22,C5,36,2D,56,79,BE,F4,F7,03,68,7A,1E,85,F1,85,87,60,B3,02,AC,88,76,74,73,D2,EF,C9,0C,AC,64,3F,81,2E,7E,28,C4,25,CD,46,BB,C1,D5,95,88,1B,0B,54,0D,FD,63,6F,10,EC,C1,96,50,C9,12,6B,B3,50,93,9F,8D,85,AF,AE,9E,18,E7,33,C1,28,8B,33,94,0E,A5,05,E4,00,86,8D,D9,81,F9,17,66,49,B6,5E,B6,D5,CC,A1,BE,0E,51,63,3B,A1,30,AF,F8,5A,94,8C,35,1F,0D,16,64,0F,2E,F7,FD,DE,4F,A1,D8,1A,2F,79,28,1C,A4,D3,C1,1D,A2,30,86,F7,3F,31,AC,98,33,AE,B1,4E,79,FA,4C,51,E5,EF,18,5C,85,F0,41,DB,AC,D1,6D,D0,6D,40,FA,55,59,A4,F9,32,60,EA,1E,E8,6A,CD,C4,75,D7,14,12,21,EF,02,16,86,E9,28,53,3B,70,E1,56,EB,F8,FB,89,11,56,0D,44,52,0D,18,C4,9A,FD,C3,62,2D,67,24,1D,B4,FB,54,AA,FE,49,F4,A8,B5,6C,90,0A,A6,52,D5,0F,60,65,69,75,33,C5,FB,9D,C4,6F,53,FD,29,E1,75,81,BE,5A,43,90,B8,30,F1,CA,CD,A7,93,DE,48,EF,92,F2,25,E0,C6,1F,BF,58,3E,81,30,0D,0F,32,D3,BA,E0,46,9B,D9,4C,B1,67,DB,23,0D,47,E8,F1,7E,99,46,95,54,00,31,CC,69,9C,FF,86,D8,8A,75,F8,00,E5,F6,96,FF,C8,27,04,7F,EC,2D,46,D4,06,1D,E2,5E,EB,DF,C3,C7,AD,CE,F6,5C,39,E6,4A,15,99,BF,B6,02,68,31,3E,4D,5E,FA,3D,AC,EC,91,0B,4E,2F,B7,7C,2E,B8,52,68,7B,2A,A5,CF,9C,00,2E,79,A4,26,91,DE,FE,88,00,0C,75,B6,F6,3D,45,AF,0C,0C,21,85,51,E9,6F,B8,7D,5B,71,3C,A3,77,AD,67,F6,16,73,D2,BB,BC,73,4D,53,B2,8D,A6,98,2E,4A,33,66,19,1A,17,8B,36,31,E0,79,C7,86,62,ED,4F,AC,87,9F,8C,BB,25,75,17,13,BE,85,69,3B,49,C7,86,90,BB,01,04,66,73,4D,88,08,AA,C0,6A,25,88,4B,FD,9A,49,B1,F1,CF,D4,3A,54,7F,58,79,3A,7A,8C,6D,D2,2F,1C,6A,90,7D,E4,C0,A2,DF,F2,5D,55,CD,E3,87,8B,A7,23,36,FF,F5,88,1A,33,08,A3,04,88,4B,0F,98,1D,F7,43,30,63,4E,3F,B2,D7,FC,EB,E3,FD,B9,74,A9,73,F5,11,A8,FE,9C,32,97,01,AE,C0,8B,21,63,0A,18,92,5C,65,F8,7E,D3,9E,9C,3A,F2,C5,9C,A2,16,3D,0A,92,87,CD,F1,B9,52,94,F0,E6,DD,34,A8,37,96,C4,F8,1B,FE,53,5D,09,05,37,EB,20,30,22,EB,7C,11,8D,20,B4,48,10,6B,B5,A4,6C,EA,CE,0A,F7,E9,6D,28,90,48,CC,BC,21,37,31,C8,AE,8A,1C,EC,81,E8,10,1E,01,B8,8D,E5,2B,B2,BD,4D,0F,8C,F3,56,03,1D,A9,66,A5,7D,AF,88,E0,69,6D,37,DB,83,AD,C6,52,1F,9C,23,C9,EA,84,A3,0B,C4,B3,84,3D,05,70,77,6F,AC,F9,C1,B9,5C,DF,38,2D,9F,F5,1A,A0,6B,E1,53,54,C9,00,5F,B7,6A,BA,63,43,21,36,6D,75,06,08,82,0B,66,E7,1F,DD,00,D4,D1,02,E2,69,C1,EA,BE,4D,11,6A,8F,FC,76,D0,90,D4,B1,9F,1B,2A,EC,B1,FA,F8,28,25,8C,65,95,69,D2,F5,70,C6,AB,BE,AB,3A,43,E2,E1,B3,17,33,43,FE,3A,17,CB,6F,17,E2,05,B4,49,69,72,06,AE,D6,58,62,20,E1,2A,90,A8,AD,8D,98,F5,24,EB,2E,11,F8,85,B2,B2,C5,A0,97,24,82,BD,42,D1,05,1E,0A,22,48,0E,F9,6D,F6,AE,59,8E,C1,47,12,26,ED,89,0B,04,4F,52,D1,2E,AF,AF,FC,85,5F,84,C2,2D,A9,77,46,EF,D5,47,33,36,26,BD,0A,46,34,71,B3,85,93,7F,BE,38,6D,18,39,53,64,13,7B,65,11,AC,65,FE,F7,F5,D0,3B,7C,6D,45,17,DD,58,93,A6,16,80,45,48,FD,4C,7A,2B,F0,E9,78,92,27,11,06,BD,62,89,7F,21,2B,D6,7D,BA,B1,B1,EA,EC,8F,9E,79,9C,B2,4B,6A,AD,FB,8B,0E,28,69,7E,4A,08,5C,72,BF,59,FD,A1,E5,46,2F,96,2D,57,6F,3B,FB,4D,53,9E,D4,B0,75,FC,F5,73,01,10,E8,4F,79,A8,D9,14,3F,3D,61,C4,D5,B0,AE,96,EF,48,BE,A4,7B,AE,6D,0A,D5,B1,40,C3,90,08,28,B4,4C,4C,A6,3B,54,FD,3A,27,14,CA,00,2D,9B,3F,44,CD,FA,3F,52,0B,BF,E0,02,3F,EF,70,41,74,31,C5,06,34,E6,15,53,00,1A,05,7A,6B,43,7B,EF,41,C2,ED,81,EF,0A,47,60,55,28,D6,FD,29,F5,56,68,16,E8,98,8D,F9,FE,D8,5D,15,70,75,33,07,42,B3,3E,1E,C0,B9,31,0C,BD,17,52,2D,3D,34,D2,AB,F0,7A,C8,A5,63,15,61,14,61,34,53,53,C9,B1,BC,98,C6,3C,22,14,40,E0,B9,94,4D,F2,D2,0A,66,A3,44,10,94,EF,22,E0,2C,6F,DC,99,15,54,C6,BA,C8,1A,55,A2,11,8F,A0,76,46,AC,5C,3C,17,C0,3E,BD,A9,BF,40,7F,84,1C,79,6D,56,1D,9C,AE,00,F3,07,3F,78,3D,57,3F,36,27,DC,70,4F,F3,41,DA,CF,10,79,D4,8B,13,92,C2,ED,84,15,42,6D,C7,33,11,C3,4E,FF,42,D2,1A,01,32,B3,26,27,99,5C,8F,90,0E,4B,5A,4D,97,1B,91,3C,7E,29,C7,10,F1,B0,5E,38,04,72,EB,D3,10,70,71,B4,66,72,F6,D2,A3,9C,D7,0D,FA,7F,F7,B1,3F,B0,65,B8,B4,B2,16,97,80,70,BB,70,7C,2D,E5,8C,A3,66,3E,96,BA,7F,AB,56,BE,D2,36,E7,77,88,EA,7B,B6,3D,71,29,6D,2A,EC,0F,FF,E5,8B,BF,60,47,C0,5E,F1,37,D9,94,BB,6E,BA,F3,2E,F9,15,3E,A2,8B,87,1C,7F,92,B3,E7,BD,E6,05,87,E8,5D,D7,53,40,4D,2C,EC,B4,92,AE,D2,72,8A,91,48,3B,8D,2B,89,B6,B6,D0,EC,37,69,AB,E1,60,2D,D8,FA,77,B2,8C,21,6B,28,83,95,64,C0,7A,0A,D1,49,C7,05,90,14,AF,D6,B9,64,E7,EA,2F,63,E5,85,4D,9B,18,86,E8,4A,1A,B6,23,1A,AF,A0,0F,99,1F,37,AC,87,9C,6F,93,33,2E,C3,AB,89,45,37,87,0E,0F,03,35,67,56,37,7B,CD,5A,68,3A,E3,5B,D8,42,1E,F0,06,7B,8D,41,28,2C,AB,FD,58,03,CB,BD,F1,52,71,3D,A9,B3,33,47,E7,AD,98,34,E2,0E,F1,AF,7A,33,43,57,56,19,84,59,F6,FD,8A,27,91,39,25,CF,57,F8,E8,52,35,03,B6,60,CB,CB,EE,EA,A2,C7,25,EA,C1,BC,B9,D4,D4,4F,32,04,15,D9,37,DB,96,3F,79,23,2F,78,5F,A7,53,08,BC,67,1C,6D,8F,8E,DD,EC,C2,56,F7,85,1E,6D,B4,5D,FB,D8,D4,AA,B3,5A,45,6B,32,FA,FC,4F,FC,08,C6,A0,D1,42,87,1C,53,D4,B2,A4,B9,2C,B6,39,BB,D1,64,64,7B,0B,ED,4C,76,37,3D,34,67,C7,E2,CA,B1,A4,E0,40,83,58,49,34,4E,85,0A,6F,A0,CD,EB,D4,78,E8,98,AD,01,FF,03,03,1B,B3,33,3E,E5,12,EE,39,1B,AD,70,DE,DA,F9,79,15,45,35,C5,31,02,32,52,7F,4D,89,1E,45,E5,AF,0E,39,DA,9C,7A,C1,FF,35,1E,79,98,0C,4A,D2,00,92,59,4C,91,B6,6F,15,CF,A9,E0,3B,30,88,01,C5,F6,E2,9A,21,00,AA,1F,82,C2,C0,8D,0D,64,41,FD,CF,E8,BD,42,11,86,A2,84,41,BF,3D,64,29,00,D6,77,AB,4B,1D,CF,10,4F,A2,58,46,53,29,79,D4,7A,5C,00,5F,0C,58,0C,EE,47,5B,16,BF,AF,16,95,8C,A5,3A,5C,13,33,F4,E5,D5,3F,BB,76,FD,4C,52,04,53,6C,17,E7,8F,B5,F0,BB,DB,6F,39,6A,A8,ED,7E,7D,D8,E5,9D,0A,1C,A9,1B,41,66,78,6F,00,54,F2,0D,D1,4B,EC,27,FD,48,8F,1E,64,D7,C8,E6,B1,ED,0F,46,F5,53,31,0D,B0,87,01,CC,E2,50,78,EF,9E,6B,BB,D0,52,95,13,56,54,7A,04,5B,EE,9D,3B,70,E4,2A,53,08,4C,99,0D,4E,0D,3F,58,93,47,EA,07,F6,7E,FD,36,23,E9,93,32,C7,0E,55,48,60,02,AB,CE,DE,6E,4F,DE,26,12,F1,B0,C9,57,44,38,84,86,65,79,06,34,94,8F,64,A9,5C,AC,43,C9,04,22,7B,80,8A,BD,21,2B,B4,1C,7A,2B,99,AD,B7,1C,2E,34,EB,74,EA,D4,15,D7,EA,9F,E2,0C,7B,FD,8E,21,EF,1C,B7,85,C4,FC,A8,2B,5D,16,4E,8A,1B,BB,8D,F6,8D,1F,87,8B,89,2F,91,1F,CB,08,6A,B9,F2,B5,65,9C,3E,88,88,2E,32,8C,9D,9B,B2,7B,96,D6,73,38,97,27,1B,86,8C,F9,5A,F9,91,EE,80,2D,70,0C,0A,46,1B,74,D4,CF,AD,AA,CB,63,F5,9F,87,40,66,77,7B,35,CE,9C,F6,F4,41,F1,81,56,A3,B0,50,8A,87,BF,EE,DC,AC,DD,AC,02,12,2E,8B,40,38,85,92,94,A6,34,89,66,B0,D4,FC,D6,0C,66,FD,92,42,3C,5A,9B,E5,E7,15,09,AE,6E,D7,F5,D3,49,6C,46,FD,3C,A5,CA,F5,96,D6,E3,23,43,A6,55,42,7A,8F,25,FC,4E,28,6A,E7,2F,F1,D2,30,56,BB,21,D7,A1,FB,ED,1A,CA,25,51,1C,FF,B3,2F,A6,F3,DE,8C,4C,D1,B9,84,FD,EB,C7,5B,D9,8C,B6,59,5C,04,D2,3C,FF,0E,89,7F,62,79,69,6A,3A,C1,B7,F0,E4,F2,C5,63,1D,DA,6F,E2,EF,B6,5D,DE,3D,5E,11,2F,C0,F1,96,CB,EE,7B,97,B2,70,A8,40,78,CB,48,BD,EF,7A,82,A6,92,F2,73,A3,FF,76,53,30,67,DA,99,C3,EA,36,99,EF,7D,38,55,CB,AE,2C,F3,4B,E9,BA,B5,EB,14,F2,D2,EC,59,F7,2D,A9,8B,E5,71,CE,34,47,8A,71,7E,1F,F2,35,69,34,23,8A,66,15,F0,50,29,2C,D2,35,2A,7C,A0,8D,43,0D,74,A1,A2,5B,E5,B8,A1,A3,69,16,3F,91,3D,29,DE,42,56,B2,CA,F7,23,CF,55,D9,32,2C,2F,57,A8,F5,00,8F,07,B6,18,C2,4B,7E,C4,62,68,4D,EF,31,32,DB,8D,96,88,B0,57,6B,6C,A3,0F,46,D5,9A,CC,17,FA,58,23,4A,58,43,88,B7,FC,DA,7D,B3,6C,FA,2A,50,CE,C9,15,EA,07,33,EA,AD,51,4E,95,FB,57,1B,11,40,FE,BF,0C,85,E6,54,85,45,78,DD,5B,8E,36,6C,E6,DA,7A,70,89,D9,05,52,3E,08,15,27,03,B1,E2,16,D2,D0,DF,38,61,F4,9E,50,BA,B2,47,7B,8E,0F,AA,9A,3D,11,AC,08,E6,90,E6,2C,81,41,34,59,9C,47,A3,42,F6,5B,A5,47,06,07,B7,D7,60,45,E2,03,65,54,10,55,8F,D3,9E,D5,B0,86,1F,A7,B8,1D,A5,B9,F1,40,67,DC,74,2E,A7,55,6F,BC,D0,F6,5E,85,F6,C7,BF,34,FE,70,E4,0F,48,55,2C,2F,4A,E3,E9,23,DF,6B,38,67,97,63,50,8F,E3,AF,C0,B3,6A,75,EA,66,DF,FB,2F,08,BA,A4,5D,04,DB,3E,4F,39,4B,22,E2,CD,A9,CA,97,8F,A1,D5,37,4C,13,5B,B0,AE,29,A0,CF,BA,39,F9,A8,94,FA,6E,77,E5,48,75,32,F8,4E,E7,A2,C4,A4,AB,90,69,82,AB,1B,69,DA,56,6D,77,7D,E7,0E,AE,24,92,46,39,39,F8,F5,24,59,BB,71,DB,F5,1F,C4,66,45,5B,1F,8E,A3,03,8D,6C,CA,C4,C2,AA,40,6B,26,33,E2,D0,42,DB,28,4D,BA,FA,90,EC,57,4D,12,74,11,B6,03,36,CB,72,EA,0D,46,78,B8,29,85,FB,F5,99,40,90,21,00,4B,53,8E,82,BE,CE,CF,01,37,0A,6C,AD,30,1D,4A,54,F1,CD,7A,8B,B6,77,AA,9A,27,E9,5C,B0,16,B1,65,33,CC,86,9F,72,1B,F0,68,67,82,34,F5,B7,B7,99,60,8E,B0,FB,30,1A,57,51,66,04,2D,46,5F,A3,61,99,48,8F,40,34,FF,7A,31,0E,5C,AB,8D,58,BA,DB,BE,64,55,00,A3,9C,76,0A,8C,A4,53,55,41,C7,29,73,68,A1,16,49,C4,44,BF,83,9A,F9,0D,59,1A,B8,02,35,6B,27,12,7A,3C,78,6D,86,F7,9B,33,32,FC,27,DB,D7,3B,12,58,F4,73,03,EA,C6,47,01,20,A5,89,EA,B1,D5,1E,FC,8B,16,2D,D0,A0,D9,DF,35,43,60,47,BE,6E,4E,30,DB,D1,35,8B,A1,F8,50,5F,F2,C4,DA,CA,15,56,5A,AD,B5,40,2C,A4,A7,58,4B,DC,40,55,C8,1B,22,6A,E8,E2,68,52,5D,0D,E2,12,A1,67,18,17,EA,04,FF,CF,57,DC,A5,3F,D4,CA,4C,8A,CC,7F,B8,1E,42,4B,87,41,48,AF,E0,2F,11,20,28,A6,9F,D3,05,D8,20,C3,7A,22,1C,0D,3F,CF,3D,C2,05,03,9F,D4,3F,93,01,7B,CC,31,F5,EC,03,BE,5D,EB,1F,46,D1,B4,17,C4,37,23,62,50,7E,16,08,B9,CC,99,95,41,2A,84,0B,D9,7C,4B,35,30,6A,FE,D3,23,24,3F,EC,F5,32,AA,95,8D,8B,97,4E,C3,B6,0F,A3,44,C8,51,F4,97,AE,C8,71,F0,01,CC,99,F9,6A,97,A6,B0,B7,2B,BF,8D,1F,81,3A,7B,E0,00,39,58,F4,8F,15,69,31,EE,F5,2E,B5,2E,D5,5C,AD,80,BE,87,1E,4D,D3,1D,C2,AD,1A,FB,52,07,94,F1,76,11,4F,BE,00,86,15,DD,5A,2B,F0,1B,D9,F7,84,56,CB,08,24,96,CC,BF,86,F4,46,A1,49,DD,D7,8D,D8,B9,53,AF,EA,74,66,9E,08,8B,64,FE,B5,62,C2,DC,31,BD,0B,B5,CF,2E,BF,E0,BB,06,71,89,53,78,4F,DB,AE,BB,3E,B0,27,B1,55,2B,1A,93,8B,89,0F,17,66,56,F7,1D,BF,D9,95,17,17,D0,9F,8F,84,95,4D,8D,56,F7,B7,DA,A9,04,51,64,CE,94,A3,49,EA,C1,5E,9D,12,BD,9E,C5,A7,56,49,5C,74,61,03,8D,1A,CF,FA,96,D8,B0,DB,3E,D9,98,64,6E,54,5E,AC,D9,15,FD,99,15,7C,84,AC,E6,2C,96,8B,0B,8D,3D,11,4D,24,30,66,0F,A9,5A,3A,71,C6,09,A0,2F,22,0E,44,86,31,D9,19,DB,8B,0F,2E,B4,1B,58,BD,D1,25,56,7B,A1,C1,F3,D2,08,53,3E,B0,47,A9,44,3A,06,80,5F,2D,46,B8,0A,5A,03,47,09,2F,E7,81,2B,43,1B,F5,B6,FB,6B,9B,B2,FE,1D,F6,A9,65,7C,63,79,17,AB,5E,A6,AB,C5,D4,8F,F2,36,E4,F7,2F,F8,E1,3B,9F,A0,06,C7,C2,4E,3F,28,08,FC,5A,72,E6,8F,CF,E4,EC,39,09,A8,B7,11,61,8B,79,32,BF,D4,0E,48,79,AB,EE,EE,C0,53,19,4F,01,5D,E6,23,DE,C9,1C,3B,DA,E8,31,BC,61,0C,F3,55,84,14,DC,61,41,F8,EB,1C,B7,0D,B0,B8,43,D4,02,02,E6,91,53,CB,A2,76,5F,57,9B,1F,4F,E2,A7,02,C8,2B,B2,B5,29,D1,F4,90,32,66,9A,59,A2,24,3C,B5,F7,55,5A,56,AB,67,8B,74,F3,EF,74,E6,53,22,7F,1C,04,F8,29,44,FA,78,35,FC,E9,DE,4B,5C,F1,9C,D1,90,F5,DC,89,74,8B,2B,63,E8,29,A3,11,FA,1A,D0,0F,8B,33,D2,9A,07,79,83,01,82,94,85,4F,B2,66,A5,9F,8F,0F,4F,51,1F,FB,D2,27,8D,7A,77,22,0F,B1,D1,A4,72,2D,53,78,B5,6E,31,CF,2F,7B,A9,BE,59,ED,98,BB,B1,91,AA,53,B6,85,FE,4C,AC,1A,7B,AF,D1,EF,3B,3E,1E,03,DC,FC,47,C1,BD,62,E4,D4,F3,08,2C,4E,9C,AD,09,14,B6,9B,98,BF,8E,B0,D4,8E,F5,1F,BA,F2,98,DF,05,C3,4E,F4,40,E2,E6,92,72,BD,73,0E,24,59,E1,BD,C8,C2,04,D6,80,95,6D,94,F5,56,AA,74,74,6B,EA,7F,C4,B7,75,90,4F,0E,22,08,E9,13,EF,A8,60,41,E6,66,07,D0,20,83,F0,89,78,B8,B9,7F,D7,95,BC,50,D2,D3,8A,A2,43,0D,C5,41,33,5A,79,22,08,16,F2,47,83,C0,AE,92,07,05,C0,A1,21,E5,C0,10,A3,F0,8C,EA,7E,EF,CB,BD,F2,71,F3,FB,99,E0,DD,B1,42,58,50,BC,DD,F5,F0,80,B2,EE,9F,D5,E3,82,35,BE,EC,76,A2,4E,CB,79,CD,35,AE,CC,48,46,AF,07,21,60,50,F7,D2,48,3A,81,F7,A9,5C,A8,41,7D,C2,57,A4,4B,15,C2,57,9F,CB,54,5C,E1,1A,64,34,C9,70,09,AA,9F,20,9C,31,47,D0,48,7F,3B,D8,6E,0A,6E,4B,C1,0D,1B,4A,F2,51,A4,A0,BB,7C,21,D0,8D,C4,B1,50,EF,7E,52,91,01,1A,60,E5,D1,8C,7C,5F,19,E1,76,67,55,95,33,8A,63,8D,3B,13,42,32,9A,C4,E6,84,6D,D8,9C,CB,DA,6D,4D,CB,5B,67,C9,76,6A,8D,4D,1D,D5,D5,B3,2E,C5,4B,DF,17,3F,5E,2E,3C,9E,7F,63,EA,B0,58,FB,91,EF,74,F8,BE,CE,12,CF,C6,C4,38,E2,F6,9F,55,16,25,AA,D8,C9,23,54,F6,DE,FF,F5,46,C0,DC,40,BE,F8,F9,77,98,6E,16,30,1E,AC,4F,AC,E4,6F,05,BE,4D,81,D6,18,A3,7F,3A,FF,15,6D,78,D4,EA,01,58,CA,0C,27,EA,DE,82,76,C6,38,F5,87,70,4C,81,3E,38,91,D0,ED,5A,F1,27,69,41,A1,7F,A7,35,29,1C,6B,DC,8E,A6,89,D8,1B,26,51,12,F5,1B,C4,B1,BA,6B,2C,A7,88,E7,3C,C1,FD,25,53,B0,BD,7B,CD,90,41,E6,6D,08,28,F4,DE,0B,D2,41,BB,E2,80,79,29,00,05,47,7F,B0,36,E3,9C,3F,85,05,1E,2F,61,11,73,DF,2D,22,17,CC,98,FA,75,68,85,13,09,D9,B1,1C,6F,17,69,47,3E,0D,B4,E6,C5,02,CA,4C,62,C2,94,81,71,EA,61,8D,3D,7F,35,E7,72,6E,C2,54,48,0A,EC,D4,0F,1D,CC,BD,FA,20,F5,16,C3,63,D3,04,CC,0F,44,8D,6D,C6,B2,9C,DE,5A,5B,91,F0,38,54,80,33,E3,B9,55,B3,94,90,82,01,23,76,B2,52,6B,80,F3,98,A0,13,94,60,50,27,67,77,F1,83,90,0C,B5,FC,1A,BC,5F,74,E5,A3,D5,80,D3,6D,F8,FF,B7,41,74,91,2E,59,96,A4,45,61,59,DF,42,36,E4,23,D5,B2,2C,92,2F,52,00,87,B3,32,F2,7B,15,D3,4D,C8,A3,13,F1,9C,15,99,62,9A,06,F9,9F,21,76,68,B3,72,ED,C4,65,E6,9E,01,09,E9,75,C9,65,CB,DB,FB,B2,F2,94,3C,4A,CA,11,29,D7,65,B6,CB,D4,46,C4,4C,C2,7B,30,6F,01,58,71,F2,84,CA,05,D6,48,F7,9D,BF,43,BD,29,B7,37,12,B9,4B,65,88,C7,84,11,07,1F,50,8A,26,9E,53,95,0D,88,8C,19,6A,9A,5F,D1,C3,72,C2,B6,24,A5,A3,46,8F,8A,29,60,36,7B,E0,71,7B,B7,88,1B,3F,4E,B0,EF,89,55,FB,EF,2E,3E,BC,97,9A,12,C0,CB,86,7B,1B,7F,29,87,15,B6,EE,CE,8E,F9,22,FD,9E,0F,AE,57,8F,A1,7F,07,6E,22,F6,52,68,FB,20,28,21,27,D5,F8,D6,5F,57,DE,21,FE,D4,A7,B3,EB,FA,38,5D,30,D8,B4,62,3D,30,4B,E7,BC,34,49,5D,AD,94,82,83,4A,3F,2B,3D,C3,76,12,F7,EB,53,64,1E,98,70,1E,0C,50,A6,FB,07,17,19,8D,E9,5A,AB,38,97,52,57,95,76,6F,39,99,F4,39,59,BD,43,EB,05,B1,6E,7C,3B,17,77,45,8A,6C,AC,62,C4,3C,40,C8,C3,90,71,B6,CA,81,50,97,CD,3F,0E,03,82,FC,62,DD,72,37,62,00,71,6F,44,39,D9,3D,19,BF,D1,DC,B7,31,77,E7,37,2A,66,A0,A1,54,39,CC,B1,5D,D1,05,E3,0F,B6,40,56,B3,FB,9E,C1,7B,65,B3,DE,C2,8D,80,AC,CE,46,0F,BA,C2,16,B7,91,8A,2B,25,78,17,EA,F7,7D,C1,54,5F,52,7F,14,B7,75,55,49,7C,CB,BB,A2,63,5F,2F,53,5B,61,FC,1D,54,B2,A6,8D,32,45,31,6D,F6,F8,49,C1,78,23,8B,92,7E,AC,8A,AA,E7,27,8F,F4,9D,5D,E0,1B,9B,FB,1E,20,7F,4B,DA,78,8E,A4,E0,FE,8E,37,6C,E1,A6,4D,86,43,EC,29,78,96,12,B5,FC,C4,24,FD,33,E4,7B,90,F9,19,3B,7B,E4,B3,6F,46,7C,BF,65,73,E4,F4,24,96,8F,9B,07,7D,62,6D,E4,79,D9,BA,E5,9F,89,A6,54,44,19,7C,7E,DA,EF,C1,E2,F5,87,47,E3,10,C5,2E,F7,17,15,1A,E1,12,C9,28,70,EE,F2,12,F8,53,35,5B,5A,D2,E0,38,9F,4A,BB,2F,A3,B2,AE,AA,02,86,51,73,50,25,FC,05,6E,A2,0D,6B,62,B0,A4,99,46,85,71,B3,87,D1,9A,99,0B,05,82,95,27,2C,70,4E,83,52,1E,0F,5D,DF,B4,A5,65,49,E7,AD,9A,F0,77,A8,B9,CC,2B,8E,BE,3E,D9,E6,57,66,94,64,E0,9E,77,70,F5,90,C0,E6,39,3D,AD,F3,CE,99,5A,F6,9C,5E,5C,F6,31,2E,50,CD,43,E3,EB,E5,5D,6D,5D,80,1E,13,9D,74,AE,4E,BB,6A,2A,DB,2A,1D,4E,EB,BC,03,8F,75,BF,F1,EA,9C,68,F7,76,28,CB,D4,56,E7,FD,6D,BA,9D,72,50,5A,40,B0,93,43,F7,51,CD,73,73,9C,D7,48,5D,AE,6F,1E,9E,68,50,44,6F,29,EB,26,EC,99,4F,C3,BF,39,02,DE,0F,37,45,FC,25,C0,C1,A8,C3,FF,15,77,C5,48,CE,0F,7D,A5,F8,79,3F,66,DC,B8,07,B4,AC,3D,60,04,D4,FC,DF,AE,BC,45,90,0F,64,89,DB,13,5A,BB,76,33,BC,29,08,14,64,CC,4D,B1,50,7D,0C,89,1D,27,CF,6B,8A,AE,AD,20,21,4B,72,59,03,04,DC,97,71,14,92,62,37,54,FD,84,04,3E,76,52,74,F2,63,E9,17,33,2D,1F,82,0A,B8,51,A4,53,41,22,DE,86,64,79,8C,FE,55,7F,32,FC,BC,40,8A,6A,FA,7F,1A,B1,05,7F,3C,FE,24,DE,C1,3E,42,81,9A,5D,A5,AA,6E,4D,54,BA,83,D0,7A,26,4D,36,45,3E,06,22,3A,72,9A,8B,06,ED,D0,27,F5,38,9D,3E,E7,EC,8B,38,CB,64,3E,7B,A6,81,8A,0D,EF,D1,94,0A,E4,CF,63,7E,9D,07,9D,23,88,3D,42,E1,EC,02,F3,09,79,CD,1C,98,78,47,66,A3,9D,9A,2A,66,22,88,1F,BC,4F,B8,23,91,65,86,45,5B,4C,39,97,C5,B1,4F,19,A1,A5,03,D6,77,B4,75,75,20,10,67,70,4E,8D,D7,7E,54,8A,DB,9D,19,1F,31,D5,14,70,DF,ED,5E,3B,1B,48,AD,4D,4C,B2,96,27,E9,41,E6,DE,8A,A5,4F,B0,7A,D1,A9,F7,32,03,C9,D3,89,6F,C3,60,90,43,37,9B,79,35,CE,9A,A0,01,B9,E5,E1,55,7A,F4,B7,24,54,9E,BA,46,D1,AE,F5,0E,0A,A8,6C,6E,D7,B2,FE,85,57,47,97,D4,99,76,17,85,B9,89,13,3D,37,EC,91,22,B5,CA,ED,5B,8E,27,E6,D6,0A,B0,D5,72,99,A6,A4,E8,5C,39,1D,4F,2E,E1,6B,D3,97,C7,03,56,5C,BE,F5,4F,BB,46,93,B8,FB,1E,48,BA,8D,E3,CA,B9,41,CA,E3,D3,EF,E4,A1,D4,DE,2A,14,A3,A0,84,5D,EA,4D,60,12,E6,A9,25,07,C5,46,11,95,D2,E8,0C,96,40,D8,4A,65,80,CF,CC,4C,19,8F,5D,64,4C,6B,39,FF,9D,6D,CB,8C,F5,E2,D7,C8,3B,18,FB,AF,33,C4,1F,C4,FB,AD,7F,A7,06,68,F6,B5,32,1F,D5,43,C1,36,13,F9,50,CB,3F,D0,7D,0D,8F,D2,B1,B5,44,A2,5D,09,AE,B8,E2,39,DE,75,15,A1,A3,CD,47,72,20,99,FC,FD,22,7D,8E,A6,CD,88,CE,C6,A2,13,10,8F,25,BF,DF,47,1E,0D,B0,7C,E6,FA,50,F2,CF,FD,3B,45,76,81,E7,CD,65,14,76,0C,5F,66,54,AC,ED,54,35,EA,2C,1C,25,6D,D9,9E,D3,5C,74,42,CC,BA,55,40,7D,92,4A,3C,2F,8E,AD,48,1A,FB,90,2F,6A,16,0C,D0,91,7A,83,A8,6F,64,35,A6,55,7B,BA,D6,6C,66,7F,7A,55,E1,96,AE,D4,73,95,34,BA,60,68,E9,E5,38,28,5D,64,0A,69,2E,E9,F5,2B,97,FC,9E,D7,88,FE,8F,01,85,91,B2,D7,83,C1,9E,39,0A,AD,B4,6D,B2,17,9A,92,A5,D7,3A,24,6B,06,B3,69,E8,B0,EF,FE,C6,1B,57,4A,F0,04,93,A2,DF,45,71,8F,DB,08,E5,62,20,38,FC,BA,3A,1E,CA,B2,8E,54,D5,6F,AE,5B,FA,99,15,A0,5A,0A,20,0E,98,79,BA,43,22,B4,F2,03,61,35,C6,8E,13,89,F7,FB,0D,24,B0,B7,87,F8,9F,C7,AC,56,EC,5D,C9,6C,E9,5B,31,FC,7C,60,83,8E,6A,C3,72,53,07,6F,D8,60,A0,66,E7,E0,2A,74,4E,65,0D,EF,B3,61,04,3D,79,95,3F,D3,12,FD,B4,DE,80,9F,ED,A0,C8,28,F4,35,FE,92,24,63,AD,CC,AC,6C,68,D4,AC,36,2B,F8,6B,8E,22,DB,9B,12,2B,48,87,BC,68,E3,B3,18,4D,C4,ED,75,EF,95,32,EA,F8,EA,94,CE,36,5F,E1,63,41,25,9C,30,45,66,6D,44,DF,34,2F,AD,E0,95,17,12,D9,0E,4C,B6,48,A6,C4,FE,C4,A0,10,5C,6D,3F,39,9B,74,36,02,2D,3F,9F,6D,F3,A3,3F,8C,72,A4,6C,F7,B3,5B,BF,1E,DF,44,46,88,07,FC,B1,98,E8,4A,96,27,33,00,B1,9E,D1,AE,61,B6,13,86,83,3C,74,28,2F,2E,DF,CF,AC,0F,39,D5,A9,AC,24,45,64,19,8A,70,70,A4,96,2C,FC,E3,4E,32,37,32,96,3E,C5,E6,15,84,75,DF,11,C1,9A,B2,17,0C,C5,0E,33,65,3F,8D,2A,09,69,41,25,AD,B1,67,7F,61,B9,2A,49,43,D3,D9,41,FA,66,9D,36,C6,88,71,48,C3,F8,48,C7,02,58,46,14,CB,BB,A3,EB,5E,75,83,42,04,66,96,B7,1A,06,C4,3D,71,19,E8,77,3F,80,BC,F7,0D,C2,7E,F5,99,3A,18,AB,5A,61,A4,48,5D,FF,B4,A6,33,6B,D1,7D,2E,43,AB,FD,70,B4,82,BC,58,76,E8,16,10,08,58,C1,B0,C8,F1,4B,44,06,43,62,65,27,B9,CA,0A,29,7A,1B,5D,4C,A8,34,DD,64,C0,60,DE,9A,CE,B1,F9,9A,E5,CF,21,75,90,49,92,FF,B5,7A,D5,46,88,2B,34,B4,F4,0E,76,61,1D,1D,62,70,C3,F3,62,F2,EB,77,4E,31,85,83,A3,75,C0,78,9E,01,F7,4B,C6,A1,7D,8F,85,A7,77,7C,03,24,09,AA,46,EE,DC,38,B5,89,87,40,32,89,26,C6,81,D5,5D,C1,87,E5,F5,3B,9C,BF,FA,A3,56,A7,D7,68,66,4C,83,27,08,1F,9B,EE,14,48,2E,02,BD,C9,7C,E0,F1,4E,6E,D7,A7,4B,9A,F7,E6,98,AA,27,C8,B4,80,04,66,FD,9E,7F,69,4A,86,F0,7D,DF,C9,BE,CD,08,0B,3B,C1,39,DA,71,85,D4,9B,15,E5,E6,B7,4D,92,3C,91,27,88,B2,79,C8,9B,B9,BE,13,83,F8,71,1B,FB,4E,50,D2,60,AA,44,86,5C,B7,C2,B0,A9,07,07,90,3A,70,40,07,5D,80,3D,EE,88,50,88,E4,2E,5B,31,F4,FF,DB,74,29,C1,E2,C6,38,2D,E9,1F,EB,77,89,5D,71,89,9B,23,43,B2,53,E3,71,2A,05,87,1B,BF,05,D2,EF,CF,86,F2,85,05,CC,7D,5C,E3,55,29,E0,0D,2E,3A,07,51,0B,8A,2E,3C,95,E1,D3,28,89,A0,F8,CB,A7,20,D9,32,07,19,7D,06,F1,50,33,18,8F,BD,32,AB,E2,1B,B7,B0,92,14,F6,8C,99,5C,46,3F,B2,74,DD,42,15,C1,D6,79,EF,39,12,5F,82,16,9B,54,45,15,D9,C2,B2,BF,94,9F,99,CA,B2,81,EF,57,FE,61,E3,FF,E1,B6,03,8A,45,21,C4,18,C8,2C,52,ED,4E,00,73,C5,8F,66,D6,71,2A,7E,BB,EB,58,12,5B,66,A3,EE,A1,A5,07,A7,02,10,8C,F1,56,18,A7,78,7F,A2,7A,ED,05,E5,8A,3A,D9,E2,97,E8,6F,93,9D,4C,C8,7F,92,95,2D,3D,A2,E7,22,7C,D8,08,3B,46,8A,B7,39,DF,45,50,68,D5,59,B3,B1,2E,A4,72,37,0D,1E,76,48,8F,9B,CB,36,C0,3F,F1,54,41,BA,FE,94,A5,CF,20,DB,9C,D8,84,99,EB,0A,4A,5C,9B,16,5E,75,B6,7F,57,00,87,2B,A7,6E,8B,04,A7,29,A6,F4,EA,0B,49,CE,E7,8E,E4,14,4C,84,8A,8A,04,EE,B5,44,D8,E2,82,5D,7D,D6,B2,C4,7F,15,A1,10,1F,1E,24,8A,9F,DB,E2,9F,A3,06,A8,36,DB,34,9A,F6,51,4A,D3,4A,CE,D4,65,36,E1,85,37,06,FF,A0,AE,9F,F7,ED,E6,43,1A,5F,35,C9,B5,77,85,29,0D,01,50,34,F3,C2,52,63,30,9E,EE,F2,78,A9,CA,EA,60,7F,35,D3,40,0F,75,55,1A,79,12,31,89,6D,73,C7,32,0A,55,DC,65,59,CB,F3,9C,20,7A,8D,8C,B3,C2,4F,DF,1A,8F,A1,B8,57,C6,6D,27,70,71,9C,43,6F,16,44,5B,80,26,C6,AE,E3,F3,84,53,C1,04,BF,BC,AF,F8,2C,A5,0C,B0,6A,20,EE,B2,3E,0E,55,FD,3B,13,76,94,93,A4,9A,09,6E,9C,77,30,53,12,C0,CE,C2,77,C2,DB,FA,CB,38,02,38,CA,1E,37,95,77,1E,D8,D8,EE,24,D3,78,04,FF,4C,74,AA,FC,31,B6,03,C5,A9,69,D2,20,09,C7,42,D0,B6,F9,6A,12,B2,CB,4E,0E,AA,43,CB,01,CC,58,35,8E,0B,A2,2A,6C,6F,00,51,28,AD,F4,49,36,1C,A9,1A,69,CC,82,09,C1,BB,AE,4C,51,22,AC,DA,91,B5,72,C2,34,6B,57,40,A1,25,58,5E,A7,6A,F2,E5,B7,60,F9,C1,97,42,5C,00,06,5C,F6,53,1A,BE,B8,8A,8A,6A,A4,E0,EE,D8,EB,FE,47,AB,31,1B,FE,95,5F,E3,85,1D,DF,9B,88,F9,0F,DA,6D,C7,54,AD,5A,2A,A6,5E,9A,C1,A2,DF,28,2C,0E,4B,EF,9B,93,10,B2,29,F9,D9,08,53,1A,42,86,AE,E4,03,AF,05,70,DD,CE,2B,24,2D,2E,CF,2B,13,0B,7B,0A,89,5F,5D,55,ED,0C,C2,AB,09,34,3B,22,D9,20,4A,6C,52,29,6A,F2,AF,71,43,50,B4,81,10,8E,04,A7,65,60,DD,1A,F8,D6,98,82,76,74,CB,F1,31,A3,69,FE,24,04,F3,78,FD,2B,92,4D,A5,D7,3E,B3,71,AE,41,0E,16,54,3D,E9,53,FD,60,67,74,56,F1,83,40,36,E4,C3,9D,F9,3D,EB,4A,64,F2,E2,C7,3C,ED,C7,31,C4,08,A4,48,0D,64,60,9E,A8,25,83,3C,3B,CB,72,B5,A6,5D,38,E3,11,81,09,5F,31,7A,FD,B0,4D,E4,19,32,52,03,66,46,6F,21,50,1D,87,1D,98,A5,DC,D6,F8,DB,B8,6F,C5,87,DD,25,7B,BB,9A,AB,68,93,1F,94,CF,5D,4F,42,EA,DD,03,F6,82,5A,0A,8B,9B,46,80,B2,AD,D0,8A,1A,3D,58,81,0F,9F,97,04,3E,9B,64,47,F8,67,4E,97,83,31,82,50,A5,73,A3,DC,3F,DC,D5,61,93,E1,58,40,69,EF,11,EE,77,F8,62,36,1B,53,62,54,49,90,E6,F7,D2,4E,19,01,23,4D,4E,5A,A8,E6,01,39,3F,5F,67,F1,6B,CF,05,B8,7C,BF,D0,5B,FF,DA,B1,B7,5F,5F,15,AF,49,5D,D0,E0,9B,F8,38,6D,26,48,0E,9D,51,CD,EC,93,01,55,B3,75,6E,ED,A1,DB,C6,D9,1F,B6,34,6C,C6,92,66,0B,15,3B,82,C4,80,61,76,12,94,E1,AC,47,EC,C2,F9,5A,05,06,94,BD,9F,4A,E0,85,9B,E1,F6,B0,37,3E,13,4B,95,86,5E,1B,26,97,EB,49,54,1E,BC,BC,0B,C7,FF,8D,DC,C8,B1,02,C7,34,D2,9B,BA,49,AD,D2,E9,C8,30,36,B9,D0,FC,30,13,A5,62,72,B6,DF,E7,96,E2,79,3A,6D,D6,8F,71,5C,EE,99,C0,63,4A,24,F5,9C,7B,95,E4,91,D6,A4,06,65,A5,99,20,52,2B,AD,2B,92,C3,93,50,5D,38,1B,E6,09,7A,8F,CD,42,F9,9F,4F,8C,CE,F3,52,51,01,5F,3E,45,AC,8A,65,CA,E1,FC,FD,53,E5,4E,73,4A,BF,EF,4A,C9,CD,D1,27,FB,52,4F,5C,1D,EA,D3,3D,D6,A9,C5,28,88,5E,AE,CF,26,30,90,0C,43,59,2D,7A,46,7F,AD,5E,B2,67,43,51,23,F2,D2,95,A1,BC,52,DF,18,A6,BB,27,CF,AF,69,65,25,23,60,FA,D0,CA,3C,EA,99,7E,A3,17,11,A7,8A,64,2C,7E,C1,02,BC,D6,E4,07,44,41,10,D9,B6,DF,79,F0,C9,1D,6B,A3,94,AA,D1,11,A3,A3,1D,33,11,01,58,3A,A3,A5,DF,DF,74,CD,DA,CE,E2,98,C9,95,FD,5F,5B,0C,5F,D0,83,85,22,30,8A,A2,07,5A,C3,3F,83,5C,56,84,25,3B,FA,08,73,8D,CF,CC,D2,00,61,C6,46,1E,FE,25,2C,4C,31,68,2B,72,7F,35,F8,F9,0E,59,FE,86,9D,AB,E5,9F,BE,1D,C3,B1,7F,09,7F,50,AE,DA,CC,90,52,80,05,6B,A8,CF,E2,EE,44,C0,1B,EC,C4,77,00,19,48,07,4B,AA,96,16,90,51,8E,FB,0A,22,A6,0D,63,C0,3A,46,0C,82,C4,B0,18,E5,00,F2,C6,50,9C,2C,F0,DF,F8,3E,57,EE,5E,00,F8,C0,67,48,68,6C,30,A1,68,D6,85,03,7F,44,19,44,74,E9,E9,AD,61,8B,62,08,10,A6,78,75,87,91,79,EC,D4,FA,A2,36,5C,40,B5,9B,D1,C3,80,98,B1,4F,0A,4A,A6,76,10,CF,35,F3,1D,B3,48,68,88,4B,35,AC,CE,42,E3,1A,14,46,77,75,3D,E0,11,02,0E,7D,E3,F9,3E,BF,C5,B5,AC,BF,DA,52,80,05,76,41,B6,5A,CA,17,ED,54,A8,79,C6,35,2E,83,12,89,56,CA,A6,33,02,96,3C,4E,A8,08,BC,3D,DF,BF,DA,55,CB,41,3E,6E,2B,16,86,6A,9F,C7,2B,DD,83,DE,78,74,6B,FC,A5,59,99,31,0C,1E,83,7C,7B,EA,89,25,32,7B,47,35,13,22,DF,53,31,60,75,A1,42,5F,42,DC,81,99,A4,7B,E3,49,C9,1C,81,B1,DC,BA,E9,52,95,B5,88,55,01,BF,1A,02,8B,05,9D,55,14,E8,7E,15,CC,9A,0F,C2,09,59,69,0A,C7,8E,DE,8A,26,10,A0,8E,28,59,40,3F,22,6E,0E,82,DD,33,75,3D,CB,3E,EF,BC,FA,C3,5A,19,D2,7B,9C,BA,5E,97,46,92,B5,83,88,0B,CE,D8,A7,3E,C8,6A,92,4E,74,0A,66,93,BC,69,D0,DA,03,0B,6E,03,8D,5F,40,E4,0E,2E,42,9D,48,D7,C3,A5,55,7B,A8,FF,98,3B,A6,2F,17,8D,9D,04,DA,4D,63,2E,F5,B8,94,E1,03,65,F4,CB,9D,7A,67,C2,6D,86,76,D2,0B,76,72,27,CE,B2,23,2B,46,6C,C3,0F,EF,F0,BD,EB,12,56,EB,AB,7C,E7,23,82,47,FD,60,27,4B,9B,B8,71,82,8B,E7,4C,EA,EC,DF,0D,88,5E,82,35,1F,7D,52,07,25,52,17,D8,20,2F,4E,8E,C4,4A,F6,B1,7B,7E,0F,02,1A,CA,59,59,E6,C4,A9,94,E0,DD,83,93,79,6C,20,66,EF,96,9B,E1,E4,72,CA,1B,5F,CA,42,6D,69,DD,CF,70,52,00,86,D7,8E,E0,D6,F7,72,94,73,78,1C,57,B3,A4,FA,E5,60,2D,91,83,68,1B,07,79,A7,5B,40,CB,23,24,9C,1A,AE,F7,29,FF,F2,74,7F,2B,EB,F5,1C,E0,CE,BE,B0,81,66,9A,A0,A5,02,98,91,21,7D,1F,AA,BB,E8,71,D2,30,1F,54,DD,E1,75,96,04,A0,6C,65,67,4F,26,33,D3,FA,CC,7F,B9,5C,03,45,30,1D,1C,FC,9D,6F,1D,16,95,8D,8F,15,AD,62,C3,5F,68,27,82,51,C2,D1,87,BB,30,41,55,63,AE,11,12,EF,86,20,41,E9,78,67,51,13,AC,F5,B2,9D,42,6A,FF,88,8F,0A,49,EE,02,60,0C,31,C7,60,B4,3A,02,16,EE,37,D4,2D,88,06,08,D4,17,9B,39,53,35,C2,D7,14,67,A6,B0,DC,6B,0C,95,9A,30,A7,84,72,CD,9E,64,C4,19,8B,77,B5,11,04,D7,45,6E,20,6F,E4,8E,19,27,6D,51,76,23,DF,88,0F,71,D8,89,18,EA,B6,A0,68,C0,6C,0A,47,E1,07,5C,7A,5E,6C,B3,3E,E4,8C,6B,BC,EC,54,A2,E8,D8,7C,3B,2B,D1,3B,B9,47,44,95,EB,DF,20,F9,80,44,05,FD,46,8B,73,95,CB,97,C5,71,3C,1B,10,C3,98,AC,C8,E9,4E,28,D7,80,B3,DC,16,A6,B2,9D,44,E4,DF,9A,8B,9E,07,68,90,A5,68,11,89,F9,F9,35,B9,78,36,3C,A2,A6,78,49,5F,D3,35,C3,9D,99,2A,33,CE,16,70,AE,0F,6A,92,BF,89,2A,26,D1,58,64,DF,1A,FE,90,A4,7A,EB,48,9E,4A,FE,BE,AC,93,C6,73,74,F0,D8,EB,BD,B7,F2,1F,15,75,99,2F,FD,F0,2C,F9,B6,CF,E1,07,26,A9,B1,3F,49,0A,55,5C,8C,2F,D7,A7,8A,F8,7E,CB,57,4E,0B,87,09,C1,44,67,9B,B2,15,87,3D,1E,1B,76,B0,04,00,BC,12,23,B9,26,63,C9,03,25,B8,F4,89,82,A9,4C,D0,09,7F,66,7C,AD,27,D7,87,AD,A5,E9,5C,EF,83,53,F7,4A,27,EC,22,FA,BB,4A,2B,28,FD,7E,47,8D,3B,F1,79,B8,1A,1E,21,5E,6F,93,78,66,AE,25,81,0C,3A,76,1B,8B,17,D0,30,D0,DC,89,25,EE,26,BD,E0,3D,48,C6,53,FE,5E,90,3E,64,46,5C,A2,F8,58,80,5A,58,DB,7C,4D,F0,21,33,5A,6C,46,71,C0,D9,9A,82,5F,C7,2E,59,31,65,92,81,CC,4A,B6,BD,E4,46,01,EB,29,70,6D,BA,3C,3F,C3,15,CF,21,65,AE,A9,68,A2,8B,7B,16,28,13,A4,C1,42,A7,56,85,21,E3,CC,E7,D8,BA,67,31,07,AB,0A,F1,B6,C2,DB,75,AE,3F,CE,BC,9D,FB,EE,2C,67,45,C1,9A,F8,4F,91,31,EA,64,72,20,1C,01,D6,23,C3,5A,90,C4,61,75,93,44,28,4D,51,5B,65,B1,2F,DC,8E,FE,FA,EA,B4,49,C4,76,FB,65,55,DE,C5,A5,1B,59,F1,32,CA,34,97,27,07,B0,D7,61,C7,26,62,74,20,09,D9,73,C7,59,87,7E,10,A8,5B,9E,84,49,A4,F5,3E,DA,C5,E8,98,3D,0F,7F,EF,C6,AA,FC,E5,FB,D5,72,9C,89,44,99,88,3B,F4,AC,3B,0A,65,C9,9E,D3,CA,2A,B7,3F,7D,20,FA,10,1C,03,18,67,F5,C7,C1,6C,00,C9,B7,ED,94,43,22,78,AD,C1,5E,AC,D9,5A,D6,F3,AF,90,3D,37,53,C5,4A,63,75,29,9D,BF,7E,30,BD,0A,3B,A7,E1,54,85,36,D9,3A,BA,21,79,65,43,47,D2,9B,0B,01,B6,D1,27,DD,E0,72,68,06,47,2A,28,51,C4,57,E7,AC,11,B0,92,7A,68,75,E7,E8,98,52,84,E1,92,6D,D2,FA,62,BC,07,47,0C,69,38,D0,91,77,BF,86,77,06,4D,65,CB,A2,EB,13,2F,F8,33,A4,35,23,24,87,F4,7B,CB,2A,5C,A0,B1,7F,C8,28,11,69,DB,0A,FF,82,C6,AB,B4,E3,84,05,6F,98,34,8A,A7,A5,B8,63,DD,08,B5,89,88,C1,BD,85,EA,BE,78,4C,F8,2F,07,67,7D,30,BE,63,AA,DD,52,81,D9,6C,17,E2,47,E2,CE,71,90,73,B6,0C,0D,96,31,AD,CF,EB,F7,FC,41,DA,8E,77,1C,BB,E9,86,43,F9,78,2E,2D,AD,35,8F,F2,58,62,99,FB,3D,CA,05,CA,B2,DC,C4,BF,40,12,3A,C4,7A,57,1E,AA,6F,E0,02,82,AE,A2,E7,BF,90,88,39,12,1D,DF,FE,30,40,9C,70,55,0B,83,3E,2C,8C,98,6C,E4,16,C6,F1,66,FB,84,32,AE,82,A2,E3,F0,F8,32,92,59,0E,B3,F1,90,8A,58,E9,74,F6,59,05,E7,78,92,AD,81,BB,C9,55,B6,8E,B5,F9,DD,A7,87,74,38,5E,BC,8A,22,D8,83,C5,FE,B2,F6,C7,C0,1B,8C,CE,F3,E4,C8,86,B4,4D,07,9B,68 -roundConstants = B8,59,E5,70,97,15,10,99,3B,1E,FE,DE,9F,52,AE,C6,31,7F,22,E9,7E,CE,6A,70,1B,9A,A0,3B,39,1F,C5,B3,6A,7D,E9,20,E6,78,3F,77,FB,00,26,73,26,D0,E5,4B,29,0A,74,77,B0,6B,D0,94,BC,40,E7,52,40,FE,97,68,97,17,E9,4D,18,EB,0D,1E,BA,E9,0C,64,60,94,CD,82,94,5B,82,7D,AB,91,34,A0,93,D3,78,FC,90,00,BA,6A,E5,E6,31,CF,32,C4,5A,11,AB,61,CD,A6,64,F1,01,BE,E2,DF,02,43,AB,1A,52,E9,66,2B,62,F6,83,4E,19,02,D7,27,71,B8,7C,CA,F4,BD,D3,25,36,4F,EF,81,5A,CC,98,78,AD,BB,D8,E0,66,20,A0,8B,A6,E8,4C,50,E2,0C,BE,EB,19,9C,02,35,D3,59,9D,7C,D9,AB,D9,1B,A5,69,F4,C1,39,71,A4,E5,E4,D1,CE,12,BC,46,D2,15,1B,0E,78,D8,DD,11,17,61,5D,56,BB,21,FB,D6,0B,4E,C6,82,19,BC,3D,81,79,31,89,03,DB,6A,ED,B4,D3,44,67,75,17,51,84,8B,1D,2C,FE,23,5C,34,31,5F,C3,B1,BF,9D,DF,BD,72,49,4B,18,58,60,72,69,7C,5C,CB,EE,10,61,02,7B,C3,35,1A,8B,CC,D1,BE,92,74,10,53,F0,0B,15,D0,2B,40,E5,52,25,E7,AF,2E,F0,45,8B,00,28,84,E2,9E,DA,84,BA,EF,C7,FD,AD,60,9D,A6,5A,E8,FA,D5,78,A8,E0,C9,6B,87,64,B7,F4,B4,D8,29,59,9E,B9,A5,50,DA,B9,E0,22,A1,78,01,69,80,52,9F,B7,8F,E2,23,0B,C8,DD,53,90,F1,A4,F9,81,1B,C0,26,8D,EE,F2,AF,0E,FE,2A,AF,41,14,B0,D8,80,F9,37,37,96,F7,D7,BC,0B,3C,AF,A6,3E,CD,44,20,F9,9F,4E,F5,C2,48,6E,13,E8,E9,9E,5C,A8,8A,7E,AE,4E,D4,52,02,64,A0,80,4B,42,99,81,33,3D,2D,CC,FD,8F,C0,15,FC,0C,3F,AE,F1,4E,14,A0,C9,80,B3,AC,E1,67,CC,E4,23,48,3F,FD,BF,9D,8C,28,E2,C6,9B,19,19,98,53,66,DA,5C,82,02,77,C8,87,7C,0B,CC,7F,03,30,E3,E8,54,BA,67,C9,F0,EE,01,7B,DF,32,DB,15,96,35,69,FE,57,09,C4,06,17,3A,D4,84,97,E4,77,CB,04,7D,4B,FA,66,68,22,2B,1B,EF,74,30,E2,50,94,47,7E,E6,78,0A,30,4A,9A,0D,2C,93,A9,BD,BB,9E,EC,31,0A,7C,63,D2,0B,E6,26,82,9C,87,4C,B4,68,91,0E,8B,D4,83,26,CA,C4,E0,2B,81,9D,17,8D,D3,3D,BA,8F,DE,F9,52,B1,B9,11,42,CF,39,EB,55,0D,2C,9F,7D,A0,1D,25,3C,53,E2,49,DD,5E,95,02,89,43,E4,87,BF,8D,C3,88,DF,6F,00,55,31,DF,78,0A,2E,4A,77,C1,74,4A,11,EE,B6,BA,E6,8F,9E,E0,B1,52,EB,92,C0,79,BF,39,5D,C7,DD,16,22,DF,F9,06,7A,DE,2D,1A,E5,3C,D2,43,79,E4,6E,FB,63,4E,FF,22,6D,94,D7,63,9E,1C,DE,55,03,0D,D8,41,09,FF,77,AB,33,63,0A,E3,A9,0B,0D,7C,8E,06,99,5C,5E,AA,0F,B1,14,6E,C3,81,28,DD,1A,2D,F6,47,24,70,5A,BA,0F,79,EA,0E,20,11,C8,12,C7,20,FC,63,63,ED,CC,96,DA,78,EA,FC,91,CF,01,0D,CE,8F,F7,35,D7,22,FC,00,3D,64,CC,6F,47,47,26,6E,BB,7A,F2,DB,E7,C9,42,A6,98,A9,BE,1E,6C,94,68,F9,FB,09,2A,B3,94,94,03,ED,7E,E9,CC,26,E4,FC,DD,D1,1E,FD,1A,96,3F,73,BF,08,8F,B1,77,3D,D3,EB,1A,3A,E0,97,A9,03,67,DF,04,4E,10,CA,97,30,7D,E6,D0,7D,B0,AF,64,76,DB,DE,5E,D8,4A,2C,DA,A9,75,0C,11,E0,EB,E1,F9,B4,65,6B,A4,DF,76,77,9E,17,6A,26,BA,85,86,E8,E8,D4,90,23,12,D0,F0,07,62,32,31,5E,46,BA,E1,23,EF,BD,A2,68,F7,3F,4C,24,9C,26,CD,87,0A,EF,4D,B1,ED,A1,CA,19,D0,F9,4F,CE,DB,C6,E7,E0,39,D8,5B,AC,BA,7D,C1,DB,C0,F0,9D,1B,02,F5,8C,2B,51,5A,7A,01,66,24,14,71,E8,3E,E4,98,67,BA,50,98,05,35,CA,BF,B3,FF,28,CA,5D,E8,35,62,9C,A1,58,4F,56,89,EB,6E,11,A8,16,31,37,14,30,CA,F5,4F,0E,A6,EF,6B,A8,8A,C9,C0,27,8D,B9,BC,10,C8,24,E9,74,D0,75,0C,1C,D2,3F,FB,DE,16,EF,0F,62,E0,83,31,1C,2E,F5,EE,86,13,CF,30,B1,14,F6,1B,ED,73,33,7B,75,75,80,26,6C,49,61,81,02,54,32,BA,36,B1,50,29,B8,3D,C5,06,00,46,43,DF,BA,FF,15,82,07,E2,1B,56,B8,E7,22,54,32,D8,DC,0B,B8,46,87,E4,FD,1C,2A,FD,CE,0D,1F,FB,05,17,B6,9D,F1,BA,E5,64,5A,E4,6C,21,39,07,9C,E5,96,6D,20,89,CD,32,00,D5,B4,7B,24,9E,E6,41,70,73,39,76,35,CA,74,E5,12,47,C9,F9,05,FD,31,D0,66,46,1A,1E,A3,EA,1E,23,A3,89,EF,4E,7A,A1,55,50,09,02,C6,55,90,DE,7E,1B,A9,50,55,3F,E6,D7,C6,4B,E2,0E,9E,47,97,29,AD,0D,AE,CD,AE,71,08,8D,9D,C7,B0,7E,42,32,B1,39,FE,0D,4B,EA,42,48,9B,37,88,E3,40,F6,EF,BF,C6,90,3B,A4,4F,D6,13,50,25,58,2C,42,1A,E2,0F,DA,24,FF,F2,51,CD,2D,44,DB,36,83,C8,A5,65,93,38,E7,46,51,E2,E4,DE,00,3A,05,C7,AC,15,80,97,0D,A1,E6,F4,21,AD,87,A1,0F,96,36,F4,2D,47,E1,28,F8,41,64,C8,01,59,F5,48,31,3C,A7,E2,FE,39,2E -keyMatrices = 7B,20,EE,4A,11,2B,90,10,D2,F2,7F,19,89,85,27,76,B5,73,2A,D7,46,7D,84,90,73,F4,E6,E9,22,B3,67,31,40,2E,C4,5D,D9,0F,BA,34,6D,46,FA,5C,39,F4,DD,81,9C,05,DB,69,97,19,E2,31,33,2B,D4,60,7A,AE,2E,8F,BC,37,0D,91,56,07,AC,C8,AE,95,FA,3E,B9,C0,0A,18,96,B0,4E,93,4B,96,F2,CC,36,B6,72,9B,C5,58,6B,C5,16,59,EE,27,4A,98,04,F1,B7,EF,F7,50,BD,8C,7E,BE,33,15,A3,F9,BC,D6,97,19,5D,B1,16,D6,98,7F,B1,20,E3,04,23,D5,46,28,BA,CA,33,A2,21,84,32,E3,25,47,57,F3,E3,16,EE,4E,2B,D1,62,AF,69,6E,AD,AA,24,93,D9,C1,2F,04,C6,9C,0E,4A,38,F6,4C,D1,55,A9,46,A1,67,3E,6F,0A,6F,4A,30,19,0C,8A,93,30,40,E9,AD,0F,BE,EB,8C,3E,C4,EB,66,E3,59,B0,90,C8,34,BA,04,05,BE,2F,F0,E1,3B,B6,2D,98,9C,E5,13,B9,F0,33,E0,07,B3,91,D4,27,E0,E3,B2,CD,9D,47,E0,99,5F,88,75,76,44,19,42,88,49,0D,AD,09,A2,FD,35,31,62,9D,E2,DC,51,D8,C0,14,A4,FE,CF,76,A3,F6,1E,DF,61,30,00,E5,5F,19,68,6D,2E,0C,60,40,6D,E9,10,36,AF,40,C2,A4,45,D6,1C,76,2B,90,69,02,2C,AF,77,F7,72,22,10,AD,08,63,F4,A7,75,7D,28,27,DA,06,6C,3E,F6,DD,04,B7,EA,8E,94,FE,55,A8,37,E3,3A,6A,48,BB,E8,75,EB,00,91,C0,1E,06,58,97,6B,29,01,F5,25,A2,81,01,EB,AA,F3,E1,B2,69,12,95,57,75,17,6C,54,F2,B8,8D,00,2D,01,C7,1D,1D,48,DF,40,A8,C8,C6,EC,34,F2,B8,38,13,00,68,84,7A,D4,E9,91,60,2D,44,19,C5,53,99,09,86,71,C9,7A,DB,AD,79,D4,4C,29,28,B4,EA,92,EF,F2,BC,21,21,CB,6A,13,2C,89,B3,4F,26,F6,CF,0E,9D,4D,E0,5D,A4,18,5A,CB,DF,55,E5,5C,F0,B7,C0,2E,A3,EA,16,C1,8F,08,17,82,E2,DD,58,DB,4D,70,F7,BF,A0,6A,81,5E,7E,B1,A7,3A,85,F2,58,AD,88,4E,15,F3,3F,C1,CE,C7,D0,41,CE,78,FD,6F,90,28,47,59,0D,DC,F3,43,9B,E0,5D,CF,03,0B,32,27,A2,37,5C,2E,12,DA,69,8E,09,F3,00,C8,F7,D0,97,AB,16,32,50,E4,AE,A5,5B,C3,DA,6F,3A,1A,D7,EA,03,15,34,21,00,00,72,8C,07,15,39,21,8E,E9,BD,65,CA,84,C5,23,D6,A0,54,3A,2F,B0,BF,A7,FA,A1,51,CD,07,A3,0C,6B,27,FE,EC,28,93,72,BF,C2,4F,8A,97,3F,DE,4E,12,5A,C3,34,AD,A6,8F,CE,7F,F3,C2,AE,62,1D,CF,36,C9,E8,94,28,EA,F4,F5,F5,F4,75,17,25,C0,0D,E6,51,76,46,2C,2A,DA,99,64,91,49,D1,7A,C4,ED,69,44,B7,F0,83,37,6E,83,49,A4,B0,2D,61,CC,38,AA,1B,C9,76,9B,71,5B,E4,2A,28,69,EE,A4,1F,63,3A,94,DD,A7,43,ED,75,A0,78,7E,38,8F,19,03,FC,30,0B,3A,DE,38,20,6C,2E,1D,89,C3,54,86,E7,75,04,A7,90,2F,6D,0E,F1,A2,71,2A,1A,39,3C,86,C7,9A,60,8C,31,EE,9B,DF,DB,69,19,69,97,EE,83,DE,96,87,18,93,10,58,78,70,D8,33,8A,AE,7C,A9,95,76,2C,01,46,7F,35,0E,B7,C6,07,1E,1B,9A,4B,43,0D,5A,45,02,7B,E9,62,6B,0C,4D,26,FF,11,7C,CB,48,10,1F,B5,22,46,C2,AF,86,46,67,0D,4A,AE,A1,17,2C,25,06,BA,B0,53,9C,A8,44,FF,A0,D6,94,A1,D2,75,C4,E3,2D,B6,53,3A,63,A6,31,CA,5F,6C,2A,6D,68,2A,9D,56,B7,02,0F,9B,68,A0,00,80,80,30,35,3A,CB,39,06,33,B1,1C,A8,9F,23,8F,E6,26,39,7A,49,D2,9B,A7,E7,AF,74,05,2D,DE,05,D1,C4,1D,D2,16,90,53,E2,64,1F,FC,26,11,34,E8,2E,9E,A8,69,DC,5B,16,F0,9B,D7,8D,32,CD,D7,AF,FB,AB,D8,E4,48,C0,04,55,46,A3,07,C9,65,0D,E3,01,28,B5,FD,EA,F4,EB,32,1B,06,65,2B,6A,F6,CD,AB,75,F5,EA,7A,DF,45,2D,BE,0A,65,99,9F,A4,96,3E,DA,4A,2C,DF,29,2A,2C,A1,6F,A5,01,C1,21,20,C4,C7,D1,1C,33,7E,62,76,81,98,0A,65,AD,53,F7,EB,07,EB,A3,F1,FB,7C,11,EF,5B,92,35,EB,E6,E9,44,F9,05,63,D6,6A,CE,E2,97,75,92,4E,4E,08,8F,72,AE,31,A4,55,53,7A,F1,B2,8A,04,8F,FE,7A,C2,31,EA,51,58,FD,FC,E2,B5,92,C0,33,0D,64,E6,E2,B3,E5,5E,64,6E,03,F8,7F,B9,08,7B,15,13,B6,E9,11,62,E7,71,DD,AA,4E,7B,C8,90,95,DF,89,92,6D,D2,A9,FD,F0,4D,BF,74,A6,7D,B9,B9,83,8C,CC,2D,E1,19,DD,F9,FA,67,A8,2B,7E,1B,68,1F,F3,7A,7E,47,E2,7F,4B,19,7A,83,7A,D5,10,3B,6F,37,79,E3,37,24,CC,A0,7B,4A,46,3C,96,25,A2,4A,F9,0B,FC,84,BF,EB,18,1E,5E,6E,1C,53,0B,33,67,76,5F,D5,8E,81,02,3A,B3,1A,BE,3A,C4,58,54,1E,D0,FF,D6,2A,A9,49,E1,D8,8F,22,3D,9B,27,C4,EA,B4,5F,BC,28,85,29,EF,1A,E5,EA,D1,21,84,C9,A6,42,AF,59,2B,F9,8B,ED,9D,43,79,8B,7A,C6,1B,AB,33,5A,C1,05,5B,B7,37,A0,2C,99,B9,B1,25,7E,A6,E3,BB,44,9B,56,EA,76,61,0C,6A,2F,4B,AA,94,15,C8,74,97,BC,BC,E8,41,7F,63,FC,97,8A,C4,E8,AD,07,0A,0B,D8,BE,E0,65,2C,53,60,48,73,FF,68,8E,14,12,52,97,07,97,2C,90,DD,D5,93,66,68,64,74,FD,1E,89,0C,91,96,C1,27,66,1E,B3,91,4F,3E,C8,9A,F3,A4,49,A3,22,11,68,2A,34,A8,AC,FD,ED,97,2C,0A,C3,15,86,DF,1D,FC,27,6A,97,CE,6E,62,DE,90,C1,B2,8C,85,CE,09,BD,BA,9B,C4,48,9B,E5,8D,60,9F,7E,F1,5E,FB,A3,A9,86,91,E3,CE,75,69,A7,8F,3A,93,FF,BC,7E,5D,2B,65,31,DD,6A,D4,BC,80,C2,67,76,29,E4,F6,F4,FF,38,F6,D0,51,71,19,EB,61,C5,34,FB,FE,37,19,90,26,BF,83,53,56,47,80,4A,D7,39,B4,CB,7C,EF,FE,9D,79,45,8E,77,5C,D7,55,CA,6E,83,62,D0,56,3E,BC,32,E9,37,F3,1B,BB,F7,51,61,70,CB,E5,CA,DE,08,D4,05,95,97,1C,30,90,A7,CC,DE,05,95,37,D8,B6,80,AD,48,71,CA,2D,17,3D,ED,F8,BE,BB,EC,AE,63,BC,6B,A1,56,38,F3,19,6A,14,7F,60,13,49,FC,D6,4D,09,36,B5,87,41,FA,CB,E9,23,5F,35,C9,96,3E,0C,75,19,D9,74,E3,92,59,42,E0,5F,8A,20,24,9D,79,BA,C4,C9,73,54,F6,65,0B,41,9A,20,41,8F,F7,1E,55,CC,56,D8,E8,1B,05,3D,61,FF,83,BD,37,97,A3,01,36,18,A8,69,F2,2A,A6,7E,1A,00,5C,0E,2F,65,2D,B4,D3,04,84,F6,70,8B,BC,1D,58,F3,3D,DD,E7,AF,1C,F9,AD,1F,9F,E8,44,8F,76,E2,A7,A0,17,B1,62,45,40,13,16,5E,2B,AA,C2,89,FC,96,A3,DF,E4,6A,45,CF,74,26,13,EF,42,02,7B,75,AC,AE,2B,B9,E1,F3,BA,C6,26,FA,4E,92,C6,81,DA,5A,5E,BE,B5,1B,6B,E6,3E,E0,7C,EA,14,3B,45,F1,81,6D,4A,A5,9D,66,0C,1A,79,C7,E2,1D,46,19,FD,C5,07,14,70,C7,BD,FF,62,AB,61,68,EE,00,46,37,62,BA,BC,57,2E,B0,AF,09,DA,98,81,EE,EF,C6,6A,91,DB,73,0E,68,41,6E,AF,CC,90,9F,16,90,50,77,CB,C5,47,BA,DF,E3,F3,2F,12,84,B1,19,19,54,CA,98,54,88,E7,4C,8C,83,48,86,B2,7E,99,20,A3,73,5A,F9,EB,87,A9,22,F9,EF,8E,9F,B6,17,C7,2A,E0,1D,EF,02,8C,79,02,2B,B6,3F,F0,32,21,7D,81,07,6C,29,CE,14,66,D7,A0,9F,85,0B,63,DD,69,B6,26,E2,49,F0,40,66,ED,76,A1,E9,4B,2B,17,69,36,5E,16,CC,14,7B,05,4C,38,48,CD,E5,2C,D6,9E,83,16,19,36,6F,ED,9B,7C,3E,FC,5B,16,8A,C1,92,E9,C1,E0,68,BC,18,2B,6E,44,94,00,2F,A5,20,D7,AD,3A,FC,61,5D,4A,C9,BC,E2,F4,F1,3C,10,B0,6C,4B,64,A6,10,DD,33,47,29,B4,4B,5B,AC,C2,42,17,38,3B,56,EF,2B,C8,E0,73,20,4D,93,8A,8A,C0,4F,F1,20,E4,A7,BE,CB,99,3D,98,D1,20,F9,62,61,DF,FC,9C,B0,E3,ED,F5,95,58,FD,94,EB,E4,9B,43,E7,A7,A7,33,9F,EA,F2,B3,2F,1E,EF,D9,1D,49,AE,C6,85,00,A6,13,B4,2C,98,57,01,C4,8F,F8,26,94,4A,58,FB,8F,03,F6,E8,91,7F,33,BB,01,8D,CF,B5,F2,AB,87,A1,2E,72,8B,B0,E0,38,CA,42,A7,FF,C2,2E,EE,F5,A0,7C,64,DF,D4,72,49,54,2F,EA,91,8F,CF,40,5A,B8,1E,C1,67,1B,72,E9,07,C6,CD,D5,6D,3C,53,D4,49,64,43,51,F5,42,1C,9E,A1,F7,49,01,69,6C,C2,95,F1,F2,D0,3C,E9,5D,5C,29,C1,2E,8E,FB,A1,E5,64,2A,A9,99,D2,6C,90,C7,31,B8,07,24,FD,4B,AD,03,8F,11,AD,24,5A,1A,C0,4F,32,74,95,AA,60,CC,E5,3A,C0,B5,C8,E6,4D,A3,76,3C,5B,01,DD,FC,0E,B9,72,A5,7E,EB,A5,7B,DC,26,14,A3,5F,0C,25,D5,63,26,AB,19,BD,A5,91,C4,7C,93,36,BE,DE,3D,C2,A0,60,8F,82,20,45,AB,91,58,82,33,C2,E1,5A,AB,67,63,0C,CF,66,49,0B,EF,F7,86,ED,B2,00,34,88,39,97,18,CA,6C,12,C4,DD,A7,55,C6,7A,FB,D4,CC,9D,6F,98,9F,E4,B1,5C,36,05,4E,C0,61,27,1B,5E,AC,86,7D,7B,FE,39,C5,DF,F7,43,BA,6F,95,8C,79,4D,A6,B5,E8,C3,3C,E0,84,31,EB,C6,62,74,D2,92,3A,57,63,2E,DE,67,82,8F,16,B8,D1,48,07,70,55,70,F2,92,FE,0C,87,06,CD,9C,49,DE,81,FB,DA,CB,4B,64,34,87,73,AF,B7,12,62,79,74,CB,7E,5D,D4,4F,24,FB,A3,65,22,FF,5E,B9,9F,09,E1,0C,0F,B4,22,B5,B6,12,5B,92,36,C6,84,75,7F,3B,19,01,7C,F5,D7,DE,E4,A2,CD,0A,81,37,68,AE,63,84,C7,3C,83,EE,08,95,B0,71,A1,33,A1,30,E6,62,F4,ED,4A,AB,A8,77,A7,5C,85,BD,81,B8,8F,68,28,A0,1D,44,20,DA,E9,D9,2D,CB,C2,0A,CF,1B,CC,18,E3,E3,8A,0F,30,72,94,28,64,31,A8,87,82,C2,0F,6F,0F,89,86,80,E7,A5,36,15,29,1A,DE,B4,24,A8,7C,36,61,8F,D3,33,3E,2F,D8,FD,B8,67,90,14,2E,1A,C4,B2,E0,8C,3F,CC,82,91,F0,12,C5,C0,60,13,12,B4,CF,3F,7C,48,B7,E3,62,AB,77,46,7D,D2,9C,1A,34,32,9D,C2,E0,47,D3,6F,43,E8,A1,1A,E0,C0,99,05,89,68,60,37,A1,89,78,3B,30,82,CB,1A,38,4B,A4,25,A1,FE,49,FD,63,D1,4A,D1,DC,88,49,4A,2B,C2,34,DF,64,A3,4C,31,2D,04,1C,A7,AC,0C,C9,7D,7F,0D,F5,4F,B9,B1,9E,32,CB,AD,0E,98,7F,10,FA,80,CF,CA,9D,6C,86,E0,DD,BB,6E,87,02,76,B5,5B,F4,2E,73,72,C7,5F,28,7F,2B,B7,B8,2A,3B,F9,58,86,10,28,A9,60,D5,91,09,83,AE,4E,BA,FF,C3,A1,E4,79,AC,69,35,E4,17,01,35,C4,D9,C9,CD,7D,D9,01,7C,30,0A,58,A9,CC,6A,C9,C7,3D,B3,D4,0A,18,C2,8C,4C,83,5C,15,BD,B5,D4,BD,49,DA,01,95,BE,78,98,5D,C6,88,EE,0A,44,DE,53,63,AA,DD,C2,6A,57,E4,D4,C2,CF,7F,22,EB,30,C3,A9,AF,E3,83,AB,5F,49,A8,31,08,69,85,ED,4A,D8,A7,DA,C7,97,F7,96,DB,8D,5C,9F,C2,70,02,91,04,25,06,78,A4,59,F4,6E,C7,AE,E7,D3,91,B9,A5,57,93,53,C9,44,76,EF,A2,03,31,0F,38,85,80,A5,55,26,A5,B1,99,95,3E,08,9B,F1,19,13,81,D4,11,A2,E1,31,EA,E2,5D,A8,FA,90,5F,72,4A,FE,65,2C,62,A9,3A,54,A4,6C,25,58,E3,B4,95,F8,6D,01,79,D9,45,D4,AD,3E,46,32,46,4E,2D,5B,4B,7B,AB,F5,BE,7E,67,F0,DD,61,B7,92,11,CF,39,9C,1D,71,C6,EE,67,05,AF,8D,E0,89,EE,1F,93,07,79,F8,C2,87,DC,16,C9,64,7F,AF,13,71,44,C2,7C,40,EA,BE,77,E9,22,EC,7D,FD,ED,BD,77,C3,2A,AF,F7,C1,F4,2C,A8,EF,B5,3A,7F,D8,C0,81,3E,CE,6D,11,19,28,9D,60,09,D1,AA,A4,71,1C,6F,C3,88,8C,1A,3A,33,88,C8,E3,A7,AF,8B,C4,A0,79,63,75,07,3B,90,52,FA,1E,03,D8,50,5E,6C,A5,07,61,DC,31,6B,AF,55,09,63,96,60,11,6E,8C,83,E8,48,08,C1,06,61,E0,A3,C2,38,9A,8D,13,87,E5,66,C1,B4,D2,3C,6F,22,33,3B,86,CE,26,36,59,B4,06,A0,31,64,51,A7,3C,D4,59,5F,CA,73,38,72,9A,A4,56,D6,38,75,0A,D9,63,6B,6C,07,01,B1,88,C3,62,63,BB,88,80,B0,4B,09,F0,C0,AE,09,43,0D,54,FD,6E,AD,39,E1,05,2B,8B,B3,18,9A,12,F3,E4,36,51,9F,5C,24,8B,25,41,27,AA,EF,17,27,05,1C,E1,0E,FF,BB,04,FA,7E,8C,9A,86,EE,93,38,FA,B8,6B,CF,15,6C,6F,1A,0A,31,5C,C4,84,9C,F3,72,31,10,77,A0,27,96,4E,60,A1,C9,68,89,06,35,E9,17,55,09,4F,36,A3,B3,11,DD,20,B0,15,6B,B0,AC,E4,0F,27,35,78,F4,BE,C5,B1,97,FA,A2,83,F2,B8,B5,11,5B,3C,F4,3A,D2,51,91,B7,1B,42,5F,28,1E,27,72,9F,57,BD,EB,59,75,C8,AB,15,50,CA,48,28,05,0E,6C,6C,0F,FE,67,D6,27,48,C4,0B,B3,6B,1D,D9,E8,B9,5D,F3,B8,1A,0D,99,BF,0D,35,BE,44,C2,2C,33,D0,5D,F7,DA,5E,80,1F,1E,16,6F,7B,E8,19,F6,CF,2B,E0,EF,31,B5,65,47,20,4C,D8,1A,31,A6,AC,2D,5B,7E,6D,33,E8,71,37,8E,38,2E,8E,CC,86,C8,28,5E,24,AB,3A,57,90,CF,96,73,53,13,FD,31,09,00,2F,5B,42,B8,7C,7D,A0,5D,37,1F,1C,65,69,E8,5E,98,17,97,E2,EA,17,37,FA,83,4D,7B,69,CD,28,73,D2,16,A4,79,33,77,A3,22,F0,06,C1,86,E3,15,D6,05,CB,7F,67,88,F0,17,57,D3,E3,5A,49,67,FC,9A,9E,14,2F,F3,7D,11,8A,76,AF,58,28,5F,EA,05,B8,A3,86,D2,92,5B,71,04,34,31,45,FE,04,04,68,10,25,71,23,9B,7C,E5,DB,DC,60,DE,24,DA,35,54,F5,40,39,43,05,0A,C6,C3,28,1B,0C,E4,EE,E9,2A,69,34,84,94,14,5E,A4,1A,3A,FC,4C,81,4D,3D,E3,7F,D9,93,45,E7,3E,22,6D,70,E0,6F,F4,43,2A,03,82,93,31,98,5D,E6,5C,DE,4E,B2,7A,DD,94,BD,9B,74,B4,74,55,B3,72,F7,C7,DF,15,98,74,16,1A,11,3E,61,27,FD,B0,2F,2A,BB,18,95,73,A0,09,CE,1E,E9,09,9F,29,AF,79,79,10,6B,81,D7,22,08,E8,31,02,E7,7C,40,28,C6,C6,C3,6F,95,1A,18,E6,72,E2,4D,D7,8F,9A,94,2A,67,58,91,07,1A,B3,7F,7A,0F,C1,C8,BB,89,96,DA,68,EF,C6,DB,E5,18,6F,8D,2C,38,5B,10,F8,2B,80,3B,C5,E8,4D,97,3E,A6,B8,D9,87,57,DF,DD,8C,01,C1,99,83,8A,D2,72,D6,C3,14,9B,6F,6F,F0,4C,B4,AC,00,19,32,22,5C,8B,9E,28,00,69,63,D9,09,E4,FF,55,DC,83,D5,A2,68,4E,35,B3,52,6E,FA,E1,A0,25,6A,49,60,59,C6,6C,4D,21,1C,28,0C,D9,68,3C,FD,E1,E5,2F,9D,DF,BC,24,8F,EB,C4,63,7C,8A,08,29,F8,F4,83,1A,A3,8D,BE,82,77,28,C4,B4,EE,7D,20,CD,58,38,F4,F9,3F,CD,25,DE,FD,B4,61,DA,F4,7A,69,5D,F2,A7,1C,77,C6,60,0C,99,E5,F1,CF,5E,3F,F1,D7,0A,77,28,1D,2A,6D,E4,00,AE,1F,3E,89,8B,F2,8E,23,36,69,BD,2C,E9,9B,48,45,5D,47,1E,95,9D,E6,7D,BB,E0,F0,2D,F7,FD,A8,B9,6C,62,CB,AC,29,7D,70,4F,23,3E,F7,63,0B,82,AD,64,64,4A,3D,32,02,8E,30,33,60,80,39,A1,E4,75,73,9C,13,98,7D,E4,5D,5D,24,1B,72,E9,56,5F,D7,1F,65,9E,D5,1F,F1,25,5F,7A,E1,81,FA,A7,89,DE,49,FF,44,8E,5A,2F,C8,89,E5,67,A7,BE,22,2A,64,CE,11,3D,B0,F6,DD,66,CE,79,E2,B9,EB,19,91,EB,A4,5D,88,66,08,28,D8,BF,72,77,F8,2C,E5,73,44,32,2B,72,4E,B9,30,AB,6A,86,60,D6,C2,A2,0C,B5,1D,C7,1F,3A,FF,96,8F,68,06,CE,38,5C,86,6F,64,54,05,75,1D,3D,F8,0F,5F,B3,61,B2,06,9A,A9,7C,58,26,B6,BF,68,6E,15,74,5D,D0,87,C2,04,6F,2A,9E,52,11,03,83,17,61,0B,60,09,15,7C,7A,04,A7,07,A7,F6,AF,B6,27,7F,87,C0,DF,A5,FE,D7,32,FB,AD,EF,65,49,86,78,AF,67,E2,AA,E5,DB,1F,82,26,0E,7A,8F,90,35,F4,5B,0A,F7,CE,3F,F5,98,9D,37,6E,62,5B,92,E9,51,20,41,09,CB,99,98,6A,9E,0F,3E,F0,1A,9C,51,82,71,91,CA,95,B9,C8,B0,D3,6A,51,02,54,FB,D4,EC,17,8C,A1,36,B5,0A,1F,5D,A9,23,26,79,FA,00,3D,B8,F0,61,5A,4E,8C,3C,B5,A7,A9,44,0C,70,72,E3,A1,8A,7F,0A,F3,5B,EC,40,09,D5,18,D7,E4,D4,BD,77,3C,BE,A3,6B,41,03,7B,3C,17,1F,8D,CB,65,7A,E2,D2,26,00,8B,2C,36,B2,2D,23,1C,D4,01,FC,2D,8E,65,A6,3E,22,E3,D1,EE,F1,B0,6F,14,F4,66,E5,38,1D,E7,F0,54,14,18,B5,90,E7,83,69,51,A6,19,7D,D0,4B,9F,03,3A,B6,B7,B1,46,9B,4E,64,A2,EB,C5,AA,8E,FC,E1,2C,C8,98,8B,4A,1E,6C,97,57,7D,83,DE,23,BF,73,2B,B8,3B,77,77,BE,1D,DB,5E,FC,E3,6A,F9,6B,2B,02,47,9B,7B,7F,97,5E,B4,51,F9,7B,C0,B3,F4,F5,77,3E,35,AD,16,61,0A,7D,67,24,58,AC,26,B8,E9,D6,6B,A0,79,56,68,0E,E0,2C,E1,10,90,0D,FB,19,B3,0F,60,11,EC,C1,CA,FC,AC,CD,6B,EA,FF,43,C3,8B,EF,4E,FD,47,FE,2A,88,CB,8C,47,B6,9E,E1,5A,CD,1E,F8,CF,CD,9F,A0,69,2E,C6,91,06,66,92,FA,89,6C,64,95,DC,EE,79,28,03,A3,7A,F5,99,7F,CC,B9,84,D8,65,D4,9B,F8,4C,4B,BF,4A,09,2C,C8,F9,9A,36,91,E8,57,6E,4C,BD,04,E7,C8,CD,01,0A,C2,16,3B,51,77,C6,93,B1,C7,C1,65,42,76,BB,F9,5F,24,42,54,FE,BB,38,1F,73,0A,C1,80,4F,4D,D2,5D,3C,51,EA,30,5B,56,52,C5,0E,F2,E6,41,68,08,FE,7E,05,F3,6E,D7,1A,6D,59,27,D9,D5,38,1A,A1,94,2A,35,2C,28,B9,02,7F,1A,38,B1,3A,BB,80,FB,37,8C,81,E4,BB,A8,6C,1F,E1,90,C9,E0,57,C1,07,A9,3B,50,62,71,4F,05,3A,F8,81,C5,7B,36,7E,06,24,B2,FA,2E,56,C1,46,60,AD,E9,B0,E0,BE,86,A3,16,30,E4,5A,DB,55,4D,45,95,8C,91,60,C8,2B,AB,6C,2F,32,28,73,7D,40,89,73,EA,87,92,C0,9E,E2,1E,E8,AE,87,FE,50,55,67,A0,7B,EB,E6,B0,46,14,AD,CE,F3,66,60,7D,4E,1F,23,BF,87,71,62,B5,B8,17,A8,69,CF,C2,C9,21,5D,8D,C4,34,04,49,95,26,68,55,C2,9C,8E,E7,AB,85,91,16,87,11,53,C6,4D,E2,A8,18,98,43,45,00,C1,4B,5D,F1,CB,86,5B,0B,2C,DA,18,4A,0B,08,6E,CC,7D,51,FE,51,06,29,2B,57,42,D4,2E,57,DE,1B,38,F2,5F,C7,A5,F1,2E,83,DE,4A,CA,7F,BD,25,3C,4B,39,8B,A4,7C,26,3A,EC,7F,9A,2F,64,91,B6,D5,60,A2,AD,D2,DC,7E,D9,15,C2,94,FE,4B,78,94,D3,B9,79,65,54,5C,2A,98,BC,92,25,83,A5,62,E8,09,CE,77,62,1C,3C,8E,6C,C7,FA,2F,B9,6A,07,F0,59,0C,37,43,1E,96,F3,87,B0,1C,3F,0B,4C,A0,52,CE,89,34,2A,12,BF,67,67,46,3C,7B,63,C8,36,82,A9,0F,EA,C7,CE,D6,2D,CB,71,C7,41,BA,11,6B,9B,50,47,68,A2,91,C7,11,F2,99,74,05,FA,07,48,B4,18,47,1E,46,7D,43,01,59,E8,9E,D8,0D,95,25,75,5A,A2,3A,6D,2D,A0,1D,D0,11,7E,EC,81,E2,00,F9,94,CB,71,A4,E5,BA,18,B6,D4,B9,AD,3A,B1,47,B0,4D,51,D7,6D,0A,34,70,E4,A2,25,E6,B0,85,4F,D3,1D,65,08,7B,41,45,6E,AD,37,51,E1,CE,1D,67,C0,CF,14,83,55,9D,FC,9F,E9,85,58,D3,FC,F8,27,4A,6B,4F,B4,0E,B3,E7,D6,70,32,5A,9B,9B,91,D6,25,97,16,EA,F2,53,0B,32,F5,78,86,87,67,E4,F2,25,40,1B,BA,C3,48,63,E3,F9,5A,AB,78,35,24,95,7E,1E,97,D9,84,E8,6C,CB,CD,6A,0C,D5,08,79,56,C3,CD,DB,FC,95,81,19,B4,B9,59,9B,FE,90,21,31,4F,30,40,47,15,16,29,37,E0,CC,54,36,BB,9E,5C,DB,3C,8A,3F,77,10,CB,7A,71,D4,79,29,13,09,08,14,FB,8A,01,EA,6F,6D,C6,6A,B2,22,A9,21,B3,90,47,E4,AB,D2,4E,CC,00,58,A0,D0,20,61,F5,F3,77,EF,6B,A8,7F,AD,6C,28,75,39,9C,0E,17,B4,C8,F6,3C,E1,41,B5,C2,C8,AA,CB,BC,9F,8A,87,FE,D2,11,13,E6,80,34,6E,35,1D,6A,A9,A3,61,16,E5,D7,22,4A,82,71,89,01,15,5C,1B,4F,EA,01,06,E9,5D,C7,E8,70,3A,13,3B,78,0C,31,4F,12,9A,6C,CD,90,76,5A,A0,D6,53,E1,63,39,AC,3B,30,14,CE,5B,58,BE,30,C6,F4,65,23,05,58,B4,29,E9,5B,9D,4E,85,14,65,D6,6A,D8,BD,E6,39,24,F9,13,72,F1,FB,F0,5D,9D,87,AA,12,0F,E2,40,9B,60,E8,A6,E8,08,96,3A,AE,6B,62,EC,F0,55,5D,9D,C2,59,2B,3C,11,FC,89,4F,27,C8,22,89,11,CA,21,B0,35,4C,0D,E9,15,6D,82,58,D0,11,98,EF,29,6C,A9,09,28,97,38,A4,F8,B1,86,52,C4,B4,50,67,28,1E,7C,66,3E,F9,17,D5,66,38,44,90,C7,66,07,A6,49,73,2F,85,6F,17,EE,E8,65,6E,72,9D,A9,70,25,66,38,1C,C0,A2,9F,54,A9,10,0C,6E,FF,2A,96,DB,20,B9,9A,AF,E8,D8,EB,38,E7,9E,E7,E7,10,47,C2,EA,E2,E6,04,74,A8,14,A3,D0,88,F1,C6,3F,C1,D5,80,43,D6,A1,30,47,A6,D9,3D,A4,0D,0A,8E,4A,0C,7F,80,03,AC,25,04,CE,1D,A5,98,1B,EF,E6,AA,DD,FA,79,B4,0F,B0,60,08,A8,8C,90,8C,31,65,80,C3,03,D3,37,19,41,42,1B,94,3B,93,3B,23,22,15,02,C4,CB,F0,B0,06,5A,0B,34,55,1E,CA,36,77,F8,FE,C2,34,87,9E,A7,6F,72,B3,29,11,9A,FC,1F,16,D3,40,3E,A4,0F,17,00,3E,B7,F1,6B,99,04,FE,B1,C8,81,30,3E,78,9D,D1,59,25,17,C1,4B,2A,4F,04,7B,26,B9,71,95,FE,CC,50,4B,44,56,45,0C,8C,A8,2E,E6,A1,59,58,7B,FD,44,26,09,A2,5B,CF,46,F9,8E,D0,02,CF,EB,6A,E6,70,42,0F,06,AE,63,6B,7F,9C,30,FF,5F,E7,AE,B1,2E,53,FF,38,94,76,8B,D0,31,3C,D5,A9,70,DB,2C,7D,7D,B7,65,4F,63,67,F2,DF,15,CD,EF,EF,C2,7B,C7,79,AE,B1,F2,6B,BD,82,0F,0C,C5,96,E1,19,9B,39,9B,0E,BD,60,98,8F,79,99,FF,CA,2B,38,B2,35,FE,D9,79,E6,D6,C7,25,9E,CA,13,E9,93,E1,57,C0,73,11,13,0E,1A,88,7F,B5,E6,0C,8E,DD,C1,AB,D6,74,FD,DE,63,41,22,91,63,73,8B,3C,81,8F,9E,A4,8E,6F,E7,6B,22,2A,35,51,09,B3,9A,42,3A,B4,B8,D0,28,95,6E,3C,6A,F7,8C,D9,20,9A,69,6C,6E,5C,75,78,C1,F8,50,4B,CC,6E,79,AE,9C,38,F0,56,76,33,29,AD,04,96,A9,35,1C,A0,7A,C0,85,42,01,D3,1B,1E,21,34,26,DC,D1,81,21,8A,D6,6B,71,D6,CE,5B,2D,58,D6,8B,2E,74,6C,4E,69,DF,50,23,97,D9,FE,D9,FD,A8,8E,80,C2,24,50,AE,F4,E9,07,2E,55,75,D3,F2,31,84,4D,C4,C0,AF,A5,3B,64,C1,55,BC,2F,8A,42,90,1D,91,AA,72,82,12,9D,20,61,6F,2D,69,D2,D0,15,C9,03,8A,48,22,E4,94,21,E6,26,FB,EF,3B,1F,FE,8A,D5,F6,E5,DA,D0,26,64,9A,76,E8,E5,C8,7D,6C,BE,B1,D8,8F,AD,9D,C2,0D,89,34,00,25,B1,B2,8F,91,B4,A0,E3,7A,17,51,B6,10,42,0A,AE,F5,65,3E,81,3E,4F,50,F9,6D,B6,C9,A1,64,19,BC,EE,6D,A8,BC,21,EF,9E,38,BF,91,A2,0A,94,31,35,49,40,67,F2,C7,DF,9C,BF,0B,5E,08,37,BC,12,06,F9,2D,9A,C5,CA,FC,D5,EF,EA,96,2C,C5,87,23,8C,EF,95,E6,51,87,E7,D1,B1,5D,83,57,52,D9,24,FA,94,55,BD,F5,B7,80,DD,F8,82,DD,E3,88,1D,D7,4F,97,12,FA,16,65,CD,57,A4,90,3C,AF,B1,43,41,3E,64,99,44,8C,03,08,85,45,5A,2F,17,CC,C5,86,2B,0F,EB,8A,2E,2E,00,BB,2B,B1,5F,B5,DC,0C,14,CD,AE,82,31,9F,69,88,BB,B0,38,89,23,02,52,C6,74,B0,6A,E8,66,4A,BE,EE,6C,0D,FD,5A,DE,80,37,30,0B,FE,C2,0E,3B,A8,AA,B1,00,69,5F,F7,48,96,0A,E8,87,19,23,81,43,5F,C0,92,26,F9,5A,C1,2F,6B,DC,61,31,8A,0D,28,FC,CA,2B,DE,33,6D,E8,FF,B0,62,F5,84,EC,8F,FE,57,1C,E6,57,3C,09,5F,74,41,7E,14,A2,9E,E6,11,31,94,BE,E4,E6,20,FD,FB,68,09,BE,E7,A3,00,88,0A,41,3E,88,C4,E2,A8,98,30,55,24,14,6E,F0,12,4E,9B,2C,72,5F,41,9D,FC,8A,B7,9C,09,B4,66,27,C5,64,A3,F2,B5,56,AA,E3,9C,3D,61,68,E5,ED,D0,E1,10,07,7B,DD,AE,32,C2,63,6B,68,3B,FA,24,F9,2D,85,B7,3D,2E,C5,94,19,4B,47,A2,42,B4,3A,51,29,1E,2D,C3,93,81,CE,2C,BC,1C,98,9C,C0,0F,42,49,68,0C,60,8B,FD,10,78,31,29,2D,3B,7A,D7,17,A1,24,9D,F4,09,98,FC,02,53,26,C4,88,05,BF,AE,10,6E,15,A0,7D,F2,9C,5B,BA,CE,9B,EC,90,72,1F,64,6F,67,8D,96,11,50,33,B3,25,A0,C7,49,85,58,60,7D,39,E1,BB,9D,3D,74,87,6F,B4,5B,0B,AA,83,85,B7,63,59,B5,90,70,A0,E8,F8,6F,69,80,6F,C9,C7,66,BC,48,8C,0E,AB,D1,25,9D,43,C9,C7,5F,BA,DE,45,BC,0E,DC,CF,43,CB,02,9B,4A,47,5B,EA,94,15,1D,0A,43,33,75,EA,5B,82,DE,E7,2B,47,FA,8A,1A,BA,38,14,9F,CD,5A,9D,C5,6C,E6,5F,09,09,83,F8,EE,0C,FA,A0,60,BB,57,CC,EF,55,34,3D,0B,54,7C,8D,34,DC,75,68,BE,91,D6,25,D9,15,A6,B5,70,08,3F,2C,CF,21,20,DC,44,0F,20,8D,E8,6E,78,7F,5C,91,C5,76,61,19,79,70,F9,18,DD,F0,36,EC,7F,24,E9,10,EB,6C,EF,0D,90,79,C0,41,91,54,DB,6C,5B,8D,26,E2,7A,C1,8F,38,6A,08,27,32,11,E8,EC,74,E9,57,A9,B3,74,A6,76,86,1C,33,DA,63,9F,C4,5A,04,F9,7E,F0,1E,83,A9,7D,9D,EC,E6,30,EA,67,B5,D3,95,47,C0,8B,9A,20,19,6C,FE,7E,5F,AC,8D,63,60,00,79,4B,00,43,C7,6B,62,B1,47,6A,ED,6E,EA,4E,50,61,29,1C,09,68,B1,CD,C5,86,92,CA,71,10,9F,BA,99,01,B4,38,F5,7C,0B,0A,50,C3,00,28,87,56,CC,3A,31,66,6D,DB,8F,09,46,13,02,21,A3,82,0C,AF,AD,5D,2C,4C,90,53,41,3E,69,1D,15,39,12,C9,62,DB,21,64,6C,8B,C3,4F,95,8A,9D,4C,6C,2E,43,E0,37,07,AC,80,80,FD,EF,5F,19,A8,2A,38,56,F4,78,80,68,02,61,F6,0D,40,52,54,31,F4,8A,B4,85,4E,C0,66,BF,8A,1F,EB,10,A9,95,CE,3F,76,5B,6C,15,57,5E,76,71,02,40,A5,C3,2B,29,25,F8,06,35,13,7F,07,16,DE,D0,4A,92,7B,33,93,B2,CA,3E,42,BF,63,1C,6A,1B,7D,75,F7,3C,CA,A4,3B,F4,CD,BE,BB,E6,05,50,C4,7B,26,66,F9,C8,68,5E,04,37,B0,DF,B7,8F,96,40,0E,53,62,D6,7C,41,03,6A,A9,AC,F6,3C,FE,AC,F6,64,4C,1B,EA,E4,87,AA,AC,02,18,4B,3F,03,3C,46,79,74,8C,FD,F8,97,9D,7B,DC,5D,1B,32,31,66,73,16,05,BA,C0,56,DA,E7,5A,F0,41,BB,69,58,F3,D5,44,81,8D,57,06,65,16,92,57,00,8A,E5,BB,9F,73,C3,65,72,F1,D8,C5,F7,99,BA,15,F9,7D,A6,4C,88,99,73,52,AF,22,66,7E,36,87,6E,FB,EC,3C,FB,E5,4C,68,F5,20,31,3C,9A,7A,76,3D,7E,2A,99,C9,AA,10,6A,B7,24,3A,B6,A9,67,AE,79,84,D2,DE,76,6D,3F,AC,F6,C5,4B,52,4F,73,46,99,04,43,8B,1D,B9,9B,D9,D4,1D,B1,83,C9,FC,DA,59,56,77,DD,95,37,B6,81,ED,6C,BE,89,A6,EA,81,59,93,AB,68,D3,8A,F8,73,F4,23,40,6D,21,4D,90,16,9F,3B,9A,03,98,86,DF,1A,50,DB,80,26,E6,87,B3,D8,1A,02,C6,F4,32,94,E0,9A,6A,AE,94,6E,AF,EE,24,84,EF,AA,11,C5,8E,2E,B6,7F,89,9D,00,7D,5E,18,04,81,4B,BB,5A,96,F0,9C,CB,23,B3,FD,B6,CF,9F,C9,E8,DE,1A,02,86,FE,5D,78,C6,8E,3B,91,17,E4,7E,EE,6B,94,63,5F,BC,74,14,1F,4C,A8,F2,4C,DB,0A,85,23,8D,05,AD,18,E5,F5,D0,E5,1F,29,64,B2,0D,B0,A8,53,9D,C1,CD,15,0E,CB,68,86,33,39,CA,91,17,7A,F0,99,C8,B9,E5,50,7E,74,71,DD,7E,49,B9,BB,62,CD,10,78,13,6D,66,9F,A4,83,C1,36,DD,A8,DE,D2,7A,20,59,74,F2,73,43,DD,66,60,9D,1E,37,4F,8B,98,D0,F5,B9,4D,44,8A,6E,C2,69,E4,E4,56,B1,1D,C6,3A,D9,CB,F1,BC,78,B1,52,BE,53,FF,EF,F9,2B,01,DE,21,4D,1C,6E,E5,BC,40,94,B4,36,22,D3,86,D5,4B,4E,68,FE,9B,09,94,41,72,F9,95,AC,D2,EE,2A,43,07,7D,14,7E,F8,60,0E,33,20,B9,D7,C8,4A,0D,D7,3C,59,A8,6F,FE,27,75,DA,0A,9E,34,66,10,64,ED,B7,39,C2,F3,1B,1E,8F,A0,F3,2F,7C,C6,0C,45,08,65,20,D1,B9,02,87,19,83,C2,57,DF,7D,6C,AA,70,C9,2E,78,E8,BE,3B,78,78,58,3E,F9,C9,28,B1,61,02,63,22,90,C5,22,67,10,50,C5,16,0C,22,A3,8D,DC,A9,98,91,D8,50,44,F3,E1,EE,CC,BF,C9,4B,64,41,99,64,8F,96,0E,65,83,01,BE,6A,7E,63,68,F2,14,3A,03,3E,6D,CD,BC,D1,25,70,45,67,36,B1,9A,BF,86,8E,3B,E5,FC,55,39,F7,58,73,3C,A3,F8,33,94,14,D2,56,33,5F,F5,72,91,0C,CE,F7,83,29,A4,A4,08,C2,6C,EF,F2,76,6E,21,22,7B,A9,94,41,3E,FB,56,F4,FE,71,FB,E0,6D,60,4E,94,1A,41,7F,E2,EF,DB,4C,8B,7A,DB,4B,55,0D,16,8E,4F,87,5E,99,34,4E,9A,3D,5A,50,B6,C9,8F,51,D1,BB,57,AB,55,DE,46,9A,6B,47,EA,C9,AD,5E,E3,0B,03,98,73,C5,5F,35,BF,C1,F3,56,EB,24,5B,C6,BF,F7,CD,62,7D,C4,C2,A8,D0,61,6E,6F,90,C7,88,D6,A9,06,70,0A,22,32,A6,A8,3F,FB,23,E7,26,EA,0D,8A,A9,D3,28,30,92,71,CE,AF,1E,F1,E8,C3,4E,E3,8F,D5,A0,00,27,F1,81,24,E9,F0,01,58,04,52,68,39,24,FE,10,9F,4A,DF,03,83,FB,08,26,28,52,F7,A0,58,87,55,9E,D6,3D,6F,5E,DC,45,82,05,49,B7,EB,47,D0,57,19,20,E6,04,C6,DB,27,52,BA,55,29,47,E4,67,91,84,0F,8B,56,86,18,2D,71,55,BC,5B,D5,32,8C,55,24,4D,B7,E0,14,0A,F1,3A,2B,0A,7B,92,67,2D,26,33,1F,39,62,93,38,62,2F,17,C6,2F,6C,C2,5A,B0,90,D6,96,36,B3,91,57,53,46,1C,71,28,8A,AF,EE,51,59,6B,E6,04,CD,B7,77,DA,0C,F1,14,EB,1F,6C,14,76,20,65,05,F4,13,55,A3,77,C8,9E,1F,F5,74,08,AB,9C,9E,F5,2C,52,D0,62,B2,61,0A,59,4D,AA,5C,7C,1A,BA,22,D4,6A,98,9E,40,CA,01,FA,9F,7E,DB,9D,CA,12,80,03,70,1E,DA,A7,E3,43,41,0B,13,B0,4B,B8,A2,90,23,B1,42,E3,40,10,F2,36,3A,4E,07,46,03,A5,F0,78,A8,72,9A,8F,4A,26,AA,A8,14,CF,98,09,1F,C5,F0,4F,10,AD,17,2B,49,D8,B0,58,C1,25,07,5C,47,AC,2A,8E,59,A2,2B,FB,AD,91,8D,0A,92,5C,C7,00,4C,8E,A5,83,80,E3,55,B0,66,BF,31,EA,C5,D4,4B,B8,DE,7E,CC,69,CF,F5,B8,50,95,85,25,0C,08,C9,0D,43,9A,A7,23,95,1A,8A,BF,4E,A7,86,C4,12,B4,AA,20,A2,64,A8,10,7B,19,1F,2F,4E,D7,93,41,9A,3A,4A,6F,B9,01,7F,0D,49,68,CE,07,94,04,F9,24,71,2A,18,DE,2C,7B,08,EA,D4,B5,F4,7B,0B,76,F7,8A,C9,54,E5,77,BA,D9,50,0F,B8,E7,60,2E,0B,E4,04,3E,1E,D2,EA,AE,A8,3A,A4,F0,14,CB,BF,AD,50,B9,DC,88,AA,97,A5,FF,58,98,95,8C,09,19,8E,4B,3B,F8,29,6A,11,CD,37,66,CA,24,76,46,78,84,5B,6A,C0,E7,57,51,7C,32,58,14,62,E9,46,05,1B,5E,9E,B1,10,25,5E,9A,02,88,7A,3E,2D,95,D3,2A,F1,03,66,C2,D7,BA,D6,8A,0A,3A,F5,B9,58,D4,7D,34,78,DD,85,31,9D,E3,1C,DA,4D,8B,65,66,78,55,3F,25,21,0A,9A,14,77,A5,9F,A3,F1,0F,1D,92,00,E7,FE,4A,78,3A,A3,AC,C9,B7,37,0D,10,1A,4B,78,E6,8F,EC,38,6B,4C,2E,A6,19,F3,AB,72,36,24,78,E6,1C,BB,2C,B3,1B,6E,ED,D9,C6,D0,0B,3F,F3,45,34,89,CA,A3,53,D5,12,9B,8A,84,36,B8,9C,F3,A0,BC,A4,35,3C,EB,FF,11,35,C6,C0,1F,E5,74,3C,D6,0E,DC,7E,2E,88,09,38,3C,19,DA,67,6C,2F,A5,4A,25,48,09,07,BD,E2,F2,96,40,37,4E,1E,70,40,F9,3E,27,A3,AC,C7,AB,A5,C7,FA,4F,47,85,CB,07,A2,EC,52,88,C0,1A,CA,EC,69,79,25,B6,3D,27,AD,38,91,24,B8,A7,05,4B,E8,FB,51,82,DF,2E,62,38,F0,55,66,79,80,CF,9F,6F,F5,39,98,31,06,DC,3F,3B,04,62,8B,E5,0B,96,39,19,16,94,41,43,79,7F,F4,31,78,B8,E3,4C,DD,A1,74,AA,88,85,95,DC,47,F0,EB,5C,4A,CE,4A,4B,D3,C7,D7,95,7A,F9,91,B9,95,59,14,FF,6F,BD,9D,F5,75,DD,74,31,9B,3C,E6,9D,52,36,5F,59,2B,F4,F3,18,50,A2,34,2B,A6,56,58,94,0B,8D,CD,D8,4C,51,52,F5,61,10,01,72,11,54,4A,C6,18,04,D8,0F,EA,1B,C2,81,BE,3A,5C,A6,FD,5C,4A,98,AC,CF,FB,92,37,D1,EC,EC,C9,C7,1F,8A,38,C7,05,7A,B5,8A,87,82,A0,AB,2F,6D,F6,14,4E,7A,14,EF,D1,0D,41,21,F9,25,07,30,8A,E6,7B,0B,92,16,06,51,AA,95,0C,0D,38,B4,9F,34,98,EA,8D,3C,67,A4,10,D1,2A,E4,58,08,49,B3,3D,F7,24,AD,BC,C9,DA,F1,05,66,A2,DB,85,3E,D6,E1,B5,BD,75,A7,D8,F6,12,43,E9,AF,21,90,BC,59,03,0D,F9,E9,9F,74,9C,E7,B5,93,D1,D2,E6,A3,11,7F,8F,5E,EF,38,A0,A8,1D,E7,2A,E0,0B,3C,DC,AA,D1,55,16,96,4D,E3,FF,28,1E,43,2B,9C,B2,D6,75,BD,A2,DA,43,C3,6F,E4,C7,79,28,52,FC,CC,3A,BB,30,C6,2D,17,C3,0F,84,7C,DB,25,52,08,D8,82,9F,F9,E7,B5,7A,AA,B9,16,28,46,5D,07,42,9E,96,E1,DE,FC,EC,D6,9E,17,71,53,A1,DE,D8,77,42,63,E3,A1,05,5E,BF,1D,03,7E,87,63,41,C5,24,B5,A0,88,ED,92,FA,E4,DD,29,65,17,78,79,F4,1D,5B,53,6C,F8,DE,87,AD,31,13,7D,E1,33,73,51,89,F2,D4,DB,B0,B7,2C,42,C6,15,97,4A,E7,A1,3C,CA,28,46,A1,41,78,A0,99,C6,42,99,58,01,F2,96,0D,D1,D8,BC,80,0F,33,E1,64,31,D5,72,D5,9F,AA,3E,3E,CA,04,4B,52,01,B0,B1,0E,AE,D9,F1,77,68,01,E9,45,58,93,C0,51,3B,35,40,B3,FD,31,2E,73,54,57,48,F6,59,15,68,49,26,45,79,75,97,0E,BE,D2,C6,E0,E5,08,39,33,1E,45,D7,FE,36,CB,A0,B8,FE,56,9E,9A,29,B4,7E,9F,59,77,40,2B,9C,DA,36,DB,22,EC,1A,E7,EB,9C,F4,56,0A,4C,01,AB,C3,92,40,67,11,8F,8C,3F,08,A4,EB,72,61,31,71,08,38,23,D7,5F,C6,FD,DB,5E,63,A5,A2,68,DA,7A,9E,2E,7F,63,6B,BD,1E,57,B9,20,CE,4B,CA,2A,0E,EA,BE,88,C4,EE,93,B4,41,24,56,5B,A2,F3,76,5A,3A,F1,6A,CA,A1,44,69,EE,55,18,0B,84,6B,7C,DF,DC,9F,B0,B0,7F,3F,7F,5F,35,10,CC,99,8B,5A,DF,B1,0F,E9,F0,DC,CC,D3,69,57,FE,F2,8B,DC,D7,5C,4C,D4,98,71,68,9D,98,BA,C0,B1,C6,91,0A,40,59,5F,9F,88,F1,D9,1C,52,60,C4,69,A8,7B,05,09,16,0A,BD,AE,0C,19,A2,5E,C0,C2,85,0F,54,44,9B,25,9D,97,47,59,6B,8A,83,88,F5,9A,0C,06,50,5C,4F,5C,33,F5,B0,96,72,20,D0,03,3B,4D,8D,F6,D4,EF,53,37,B6,28,1B,D4,71,D0,85,26,41,F1,3E,BC,AF,8E,CC,C3,AE,EE,54,51,ED,AF,4C,E0,A1,A6,27,F5,0F,14,EC,1B,D5,A5,B3,FC,6B,44,76,75,C8,8F,E8,8D,BE,A1,55,CA,D9,E6,62,8D,1A,5A,5D,D4,2D,24,06,C5,EA,2B,67,3C,49,E5,35,43,C0,AC,55,AA,D5,3F,2E,07,1E,13,3E,AE,F8,C6,EB,D6,D5,7E,D2,5F,6D,B3,8E,FC,78,18,DC,47,4F,96,62,E3,C4,A0,F0,EA,52,B7,CA,2C,2E,DD,C3,A0,FB,1B,85,62,87,46,65,32,7E,C5,17,D0,AB,C4,44,38,40,C7,09,2B,F8,1D,83,C7,95,7D,B3,30,9B,12,C5,1F,94,B2,66,5E,70,77,55,A8,F9,61,32,01,9E,FC,1C,EB,46,E1,16,F6,21,C7,8E,49,63,2E,0D,46,36,D9,5A,B8,BB,A7,52,A8,0F,D1,F2,7E,00,60,03,63,2E,79,D1,18,28,35,64,71,9C,E4,3C,26,C6,39,89,A2,FD,37,64,97,32,F6,E3,7F,98,4A,CF,D0,16,4D,51,22,13,E0,34,4D,86,B7,2A,04,47,0F,77,02,53,9A,FC,BC,F3,09,BF,86,21,8A,78,59,F4,96,B3,0B,EB,6A,98,C0,21,EA,D9,D4,87,E3,88,79,09,03,3D,F9,6F,DE,D3,6D,E8,00,1D,1E,9D,C8,80,99,AF,6B,1E,3C,01,9C,26,AF,00,4A,26,C4,7F,61,A6,A0,E7,6E,AE,82,DE,21,95,25,37,6E,12,6A,A0,08,3F,74,21,3B,4E,E6,00,6A,55,87,24,62,ED,38,78,3D,4F,B2,13,81,F5,AB,A6,4B,37,16,89,43,CF,E7,0B,98,0D,B4,71,18,4B,DC,7B,95,B0,31,4A,E4,85,DC,F2,19,31,D2,2F,60,B0,C3,2B,9F,B9,69,88,98,E8,E0,18,BC,4A,5D,AB,C6,78,AE,1A,75,2F,DC,DB,46,22,E7,37,7C,14,A1,FF,79,71,A3,3D,09,35,D6,68,97,55,98,CD,45,26,8D,44,8C,94,7B,D3,A0,9D,04,47,A1,86,C8,36,33,55,DB,F2,D7,11,30,CE,59,AA,BA,ED,0F,75,A9,E2,7D,A5,D4,B1,06,E1,44,FA,A5,B5,BD,99,49,7C,A7,11,F4,59,40,1A,32,22,37,9B,47,E2,9C,F1,27,5C,69,9A,D2,C2,E2,29,08,91,BC,F0,00,28,0B,43,CF,E9,5E,EB,AA,0E,D1,F6,BA,CE,4D,D5,BB,14,AC,50,BD,A8,8B,2F,2C,65,FE,8E,6F,08,B2,89,3D,44,B9,15,22,AB,15,5A,F0,90,BC,18,7F,A5,32,29,1E,4D,22,9C,D2,19,4D,17,96,90,2E,53,D8,01,AB,41,32,AC,43,A8,50,9D,D9,7C,8C,87,0E,42,6F,73,3B,A4,27,C6,3B,C3,88,60,6D,82,E5,53,E1,34,FB,D3,99,26,64,41,91,04,C2,47,21,0D,72,30,DB,27,B3,2E,E8,33,99,47,DF,79,6F,A9,35,48,FF,98,65,05,BD,DD,33,93,C8,0A,C2,7F,EA,F7,14,E2,F9,F5,AE,AC,79,5D,5F,C5,7D,10,E7,62,B3,DA,26,2B,6C,D4,DD,09,39,EF,7D,66,4C,7F,DE,81,7D,0E,56,B8,2F,8E,20,ED,C5,1E,BB,1D,D8,03,C7,C4,69,DE,28,39,98,42,89,39,EE,A4,76,6F,5F,0C,7C,DB,12,03,5D,E8,88,C7,E7,D3,2C,9A,2A,BB,09,C2,58,FD,87,F2,DD,0F,C8,F5,33,19,2A,12,33,E2,42,4F,CA,0E,DF,2A,31,26,E6,BD,06,09,78,81,C7,E5,42,E3,FE,9A,51,CB,71,4D,98,5D,0A,C8,80,48,6E,C4,07,D7,7B,09,41,F0,33,A1,F6,E3,4B,84,9D,CA,61,CE,CF,C1,EA,26,A2,4F,60,3F,D3,33,D8,AA,50,89,5B,01,7E,1D,40,28,FF,69,5D,35,BA,A4,2E,B3,78,08,2E,7E,58,DD,CE,08,CB,81,EA,B6,06,08,70,28,08,09,92,89,BD,F1,20,4D,04,60,0C,E8,37,7D,FF,F4,A7,07,F5,45,53,CD,0C,2B,18,65,54,04,BE,F5,C8,B2,F7,E2,A5,A5,89,88,35,D3,73,4B,05,12,54,8B,72,19,25,6D,57,5D,AD,6F,CD,78,6A,B1,8B,0D,CB,61,43,C4,6B,26,8F,D4,EC,2F,C3,69,44,92,C3,E2,93,B7,4D,D2,EC,EE,A2,B3,32,99,7F,F7,69,1F,91,F3,0C,7D,AC,0A,19,52,4C,07,4C,DE,33,1D,6F,25,20,EC,29,E2,6D,54,86,3E,D0,85,87,41,40,C7,39,72,D9,A2,54,90,86,28,8E,14,D6,CC,E5,03,CC,9F,A0,96,66,5B,05,09,AD,E5,13,9A,57,AB,7D,8B,93,8C,23,71,10,2E,15,65,08,EB,ED,7D,9B,F2,63,7F,AD,0C,E3,AE,53,E6,D8,30,DC,FA,F6,91,FD,CD,11,28,C7,9F,26,AF,AB,AD,E4,B4,7E,ED,60,45,21,79,FB,6F,AA,82,F4,6A,C8,0E,7C,21,F6,06,1D,5D,06,EE,D8,05,23,E4,08,FD,AD,3D,97,0A,4F,AB,C1,82,87,CF,95,30,B3,54,8A,1F,C5,BA,5A,03,C3,65,D8,B9,0B,63,56,72,05,59,AE,9E,90,26,0B,5D,59,AE,34,05,35,D9,FD,6E,EA,F2,B6,F7,03,03,39,8F,75,46,B5,43,E9,E7,8E,2A,D5,6D,18,3A,CC,42,F0,24,75,1F,AF,96,D0,BF,1B,8E,31,AA,E7,C3,A3,69,40,B5,87,52,58,82,42,BE,D7,B3,DC,B7,F8,00,5E,52,4E,BE,36,F4,88,B5,A3,52,EE,2F,A9,89,D3,B5,A9,79,47,82,55,B1,CB,C0,8A,6B,3E,1A,74,2F,11,A3,EE,AC,E2,8E,4C,83,07,BC,5B,4B,32,83,91,C0,7C,E1,6C,20,6B,94,67,22,5B,1F,A5,FE,69,A1,16,1D,D5,B4,0A,C0,25,62,B0,7A,89,DC,E5,29,88,56,EB,69,5B,8D,3B,2D,CD,8A,00,06,C2,13,2E,32,8C,87,57,E1,B8,FE,DE,6C,24,43,96,CF,20,B6,3F,57,D6,45,B6,E3,B5,19,65,26,61,62,90,A7,F2,EE,BF,63,5A,AA,73,41,EA,D9,B5,BD,C7,68,EA,B7,43,90,9A,8D,49,B5,A6,84,48,2E,82,4A,B0,0E,87,F0,F9,85,48,AA,57,0F,89,25,7E,42,CB,E7,79,98,13,0D,7A,BE,DC,39,2D,FD,47,1A,C5,65,D5,E6,EB,09,67,F7,81,20,06,2B,B1,89,BB,0B,39,4E,40,FE,17,9B,E2,E3,87,8C,4C,94,53,F9,E0,B1,CB,71,6C,87,7C,B3,35,E7,73,31,8A,D4,64,B8,69,4F,CE,33,17,B0,D8,0B,15,37,1C,AE,1F,D6,F1,EA,2D,53,ED,F0,A8,31,14,B1,E3,9C,1B,28,24,F6,3A,29,10,FB,FE,79,78,CA,1E,81,2A,1C,D1,05,B0,A7,5B,01,BF,89,DB,42,87,D5,27,AF,B4,7D,62,84,C4,43,6A,7B,37,3D,91,D6,D8,F3,3B,89,43,FD,32,62,80,A7,08,F4,E7,75,59,AC,68,76,23,5F,71,A3,F0,A5,1D,1F,DC,52,86,DB,F5,29,D6,8B,65,36,2D,38,A9,4A,17,8E,1A,17,2C,33,7B,27,3D,EE,45,70,18,30,0D,90,BB,DC,56,CE,86,0D,A3,DB,4D,27,3F,32,C6,C9,C2,79,2D,5C,7B,D3,DE,16,FF,1B,63,BA,AE,B1,8A,0B,96,EA,43,2B,7D,E4,9C,5A,32,BB,95,C0,2D,EA,6A,87,E8,D3,04,EC,46,85,A3,B9,C2,B0,C7,6A,EB,6C,AB,38,51,AC,D4,DE,D7,CA,55,2F,33,E1,34,A0,83,8A,D0,8F,33,76,B3,59,07,E8,BB,37,36,60,94,B2,0F,B0,A4,E3,93,3E,11,5D,30,F0,2A,E2,BC,2D,F8,BA,76,55,A0,ED,DA,1D,59,30,56,2A,3E,5B,30,CC,FE,66,6E,51,5F,AF,2F,E9,98,F0,54,CF,EB,E0,26,2C,37,05,76,84,12,5E,EB,09,E5,90,AA,6A,61,2F,6C,E2,16,F4,4A,9C,3E,9E,91,1D,BF,00,42,BE,ED,29,6F,4D,E9,B4,5C,CF,0B,DA,76,F3,24,9E,60,88,65,6A,57,DB,2E,C0,E3,7E,92,D5,56,B7,12,68,25,C1,92,B0,42,02,0D,5F,A6,04,23,AA,B0,14,7F,C3,10,41,45,83,76,F4,18,A8,D1,15,AA,4D,01,3C,CC,D6,5C,81,A3,51,47,9F,B2,25,4D,14,2A,10,67,CB,F9,6E,D0,0B,E4,8D,DB,7D,27,76,4D,68,DF,9B,A8,46,FB,21,C6,F2,0D,84,4F,29,FF,4C,BF,D9,6B,10,B8,8D,CE,BF,24,89,2F,46,91,C4,9F,9E,89,36,8B,D5,7E,6E,A1,33,39,8C,DE,D1,13,02,BA,99,F3,C1,75,BD,A3,E4,62,3B,7A,F8,BC,5A,36,43,E3,4E,12,23,C2,7D,10,DE,A0,67,07,EC,C6,46,E2,0E,78,6D,D5,11,71,06,4E,38,8D,FA,3E,D7,A1,A3,CD,04,99,23,D1,F0,8F,3E,7F,E1,D5,72,EC,D5,97,69,03,10,0D,65,3C,F3,19,06,F3,FD,C5,82,C7,5B,F8,A4,BF,31,0D,C1,30,22,21,4D,23,68,23,F1,80,94,9F,67,35,3B,FB,AE,CE,1B,31,16,E9,4C,2B,A7,5D,9A,F9,82,95,C4,4C,97,74,30,10,00,6D,59,16,C2,38,44,8E,56,E2,D6,B5,4E,7E,C4,4D,83,DD,F7,EB,CD,0F,EC,95,A7,B4,25,1B,6B,4C,B1,25,45,04,B9,56,01,26,8E,D6,F6,39,0A,F7,38,68,6B,B0,1D,B0,58,BC,7E,04,8D,E4,30,42,96,16,D3,CD,39,71,D0,8B,35,16,17,60,2F,AA,AB,4A,4B,2B,2C,CD,87,E1,FE,67,44,98,D8,5F,D3,01,C1,18,0A,2A,64,D9,77,87,A1,E6,CA,E9,90,B7,DA,F4,1D,39,FF,F5,7F,7B,7A,87,C3,18,C2,4E,64,02,CE,4C,53,FF,94,FB,B0,51,CB,BB,96,36,34,48,1E,BE,25,04,6E,6B,E5,8C,24,EA,26,BF,44,63,CA,75,0F,AF,EB,78,F7,CE,15,1E,01,C1,16,39,A5,76,6E,2A,82,2C,09,7C,96,EB,28,41,95,38,AD,4E,BE,F2,2C,9C,18,AC,50,23,8C,56,1D,4C,66,B3,6F,5E,24,3B,A4,FA,47,15,E0,5A,DB,E0,8A,CE,9E,49,D8,38,AF,61,62,0E,CE,F5,49,71,D3,CE,1B,EC,B0,2E,02,0A,A7,75,CF,A1,EE,1A,E5,7A,00,75,B5,3D,E8,B7,DA,80,A0,75,15,E9,4B,17,1F,D5,02,F9,F5,17,B0,68,31,51,FA,D3,9B,63,EE,7A,48,1D,E1,D6,B5,E8,F0,2E,54,AC,92,89,01,F2,64,39,12,F4,78,F0,1E,61,60,FD,A3,C5,A0,2B,86,72,DA,F6,41,8B,FA,E5,EF,F2,DD,FB,EE,42,F2,DD,EF,A8,20,92,F6,8D,17,55,F7,82,AE,32,D1,4C,7A,A0,64,78,AA,8D,32,CF,58,5F,04,85,12,4C,7A,6A,CE,40,0F,77,16,99,07,F6,57,D8,89,D7,5D,D6,CF,C1,E0,07,5D,98,A9,88,F5,43,D7,A8,91,EF,FB,7E,86,E2,B4,7A,76,DA,9D,80,71,89,23,15,4B,B3,DC,D6,26,B3,38,37,67,B9,B9,C7,24,F7,CE,34,32,85,DF,63,5B,05,D4,0F,FF,A5,BC,F4,D8,2F,37,DD,32,26,5D,22,22,7D,73,C7,EB,8E,4D,FA,30,91,3B,21,CF,7A,7B,D2,A1,62,C5,75,8E,A8,82,25,5D,96,3C,E0,39,E6,EE,FC,20,91,E1,43,9C,2C,FC,66,BB,A5,E9,FE,8F,75,60,C3,39,67,7F,46,89,40,CC,10,4C,B7,E1,E7,34,FC,05,53,79,5A,C3,C9,BB,68,0E,CE,27,9A,F6,60,B6,0B,EC,F8,61,52,00,48,D5,C1,7A,EC,7E,10,8D,A9,ED,58,43,94,4E,E5,9B,60,CF,EA,1E,B0,C2,B2,51,F0,17,70,2D,B9,4E,1C,37,D8,93,2E,9C,FD,FE,ED,9C,AB,9A,1E,4A,E9,9D,DC,36,AC,2A,4B,9E,27,1C,A3,91,41,D5,7B,C7,17,33,20,32,A3,68,59,B1,71,5D,56,A3,9F,18,1B,4D,3D,80,9A,A4,A7,43,6C,FE,5B,A4,4C,16,9C,08,A1,40,36,D2,95,E0,D1,E6,CB,65,93,56,80,81,91,39,EA,FE,30,5D,A4,CC,34,99,B9,DC,86,D7,39,D1,11,BD,3E,3D,85,32,40,B0,FF,6D,C8,85,4F,FC,CE,CE,9C,25,DB,93,5F,94,35,74,07,40,91,BB,5B,97,8D,07,60,D9,D9,AD,D1,86,4C,FA,C4,F2,8F,3B,B9,E8,4C,A3,3F,F9,FE,D8,B0,7C,CD,B2,AB,45,79,94,6E,3A,2C,F8,5C,CA,9E,C6,BF,5E,0B,BF,43,8A,42,38,16,56,70,E6,74,B1,69,5D,C9,3E,5A,0C,F2,5D,B9,D0,B6,E1,75,AD,1D,FF,3D,E4,3D,A6,14,81,4A,6A,7F,CE,9F,AA,1C,56,11,3B,22,38,F9,81,87,78,9B,5C,44,E8,C7,01,CA,FB,6C,C7,D2,F6,E4,D7,5E,3A,B3,64,0F,8C,8A,B7,63,4A,FF,7D,F2,74,2E,E9,1E,BB,35,1C,9C,55,63,88,69,8D,DB,BA,E4,85,63,69,93,7D,D9,16,C2,06,64,72,04,F2,8A,85,C6,44,88,4E,47,7A,2D,38,EB,47,12,10,71,06,C1,7A,49,E0,A2,6B,D4,78,96,66,05,3F,FC,2F,65,7D,F5,FA,5D,19,36,55,99,CB,63,7C,76,47,D0,07,F1,CD,76,22,73,2C,60,FC,59,CD,A5,3D,86,E1,77,6A,A5,4D,FC,15,A1,29,FE,0D,E1,D8,4B,ED,F2,B1,96,C2,2D,54,32,39,18,17,0F,DC,1E,A4,B9,D5,C4,5A,56,B0,32,57,49,E3,D5,FC,7A,BA,D9,B0,DD,B0,87,A3,C2,23,BB,33,8F,FB,95,01,E9,B1,83,D6,DB,B6,02,5A,AF,40,A2,BB,E1,9B,3D,5F,7D,8E,BF,0B,92,CD,59,AD,7F,82,D5,96,0E,BC,6A,18,2F,97,8E,F1,4A,AA,4E,2E,E9,2F,60,DE,38,F1,D0,1E,F7,84,9C,DA,E8,8E,95,9C,25,18,2B,BD,5C,FD,30,5F,31,04,CF,A0,EA,DC,1A,81,FE,FF,F2,45,A3,13,70,5A,E9,0E,74,30,4F,DA,82,AA,8F,FE,55,F9,6D,F2,C6,A9,51,4D,71,AD,10,A4,31,A2,8D,E8,4D,E2,12,39,3D,D1,31,AC,86,47,5B,FF,D5,2D,E9,CF,20,37,6E,87,A8,0A,AF,15,37,52,95,84,BF,A8,4A,79,C4,1B,69,30,FD,C9,0B,7E,7F,2C,50,65,54,F0,F1,66,0D,80,8C,BD,FD,FA,0E,77,84,43,12,7C,9E,C5,45,E6,BD,8E,B7,26,CE,12,11,DB,19,A4,3E,4D,EE,FB,79,6D,E4,E3,07,D9,68,96,36,FB,E3,43,FE,53,81,81,F1,04,39,23,CC,BF,65,D0,04,45,44,97,1D,27,B0,8C,A6,0F,D2,44,C8,94,38,75,D4,0A,B2,21,A1,0E,32,A6,E2,9E,13,D7,CD,41,E5,CF,4D,0E,78,32,B7,47,97,D3,AB,BC,3F,72,09,49,7F,3C,83,82,82,D3,B3,D8,15,04,7A,DF,AB,B5,34,48,CA,C2,99,91,2F,5F,9F,38,D1,49,D3,AC,D4,8B,8B,29,3B,C7,32,98,E6,55,9A,40,15,D6,56,E6,6C,5D,57,32,45,D8,52,E4,79,9C,53,52,84,97,04,84,9D,4F,1A,ED,67,64,00,55,AB,7C,AC,F1,91,BF,C0,2A,76,16,2B,55,C7,42,6E,D6,14,24,D7,41,93,20,0F,86,7E,4F,99,4A,1C,93,05,6B,0B,57,14,92,19,02,D6,9D,61,5D,9E,5A,40,63,F0,98,AD,30,DD,07,72,18,55,F4,CE,1F,35,6D,C2,5C,FB,42,2E,B7,74,CF,58,B1,84,C8,DD,4E,01,37,3A,D7,D1,2C,1A,9D,B9,63,F6,33,F2,D9,E1,F0,B5,51,57,12,20,DA,B0,5B,AC,E4,95,0A,38,23,D9,FD,D0,0C,9E,8F,90,57,59,E0,57,58,20,3D,F7,41,B1,D4,C0,A2,BF,D5,63,DB,1F,9B,38,10,8E,EA,49,DC,53,73,48,B9,C0,B5,57,69,E5,2E,DF,57,67,9F,A5,B4,3E,C4,93,D1,BD,DE,D3,F4,F7,3A,11,A6,89,80,A3,75,62,8F,94,66,64,A5,9A,F6,05,B3,DC,29,29,53,09,BD,33,22,3C,C1,C7,9A,3A,95,FC,1B,9D,69,BA,4A,2B,DB,F2,38,85,E3,36,A6,ED,0E,20,2D,92,45,F8,BF,35,99,45,14,F9,4B,DC,94,3E,BE,4A,46,1B,58,44,4B,F8,F7,E0,78,02,01,BD,93,81,03,26,3F,B4,44,47,75,34,9C,B1,A3,4D,52,77,FE,B0,C1,D9,2D,AB,89,67,BA,30,EF,08,EA,89,62,DE,2F,9B,7A,8B,47,AE,C1,54,96,B0,9A,5A,36,48,C0,BD,22,00,69,D0,C6,45,83,D5,8C,00,C5,9A,70,7B,30,FD,1D,EC,ED,72,1E,35,6A,44,3E,24,F0,42,44,9F,C7,7B,37,C2,E2,68,25,BE,58,E9,85,CE,90,5A,82,99,37,C1,F9,1E,C7,6A,6F,8B,45,BA,22,8E,D1,B7,11,F9,C8,81,76,68,C9,17,C3,7D,CD,A3,64,0F,54,A5,47,80,84,2C,F4,9C,70,37,46,37,69,3D,C8,E5,F7,7D,F7,17,D1,71,73,E1,22,D9,86,8A,66,BD,1C,11,98,2F,04,E8,B3,B5,AD,92,BE,65,A0,99,8F,B9,4A,74,25,5B,59,8D,BC,F1,71,DF,1B,BB,BE,39,1E,36,15,81,70,10,6F,E5,1C,D8,83,9E,BC,F0,FB,CB,38,7B,C9,F1,85,3B,70,A3,A4,6F,60,4E,00,8E,38,47,22,40,B7,70,9B,D5,AA,B1,0C,EC,36,09,0C,AB,43,0C,77,7B,36,4B,59,74,F3,EC,61,02,E2,EC,00,F5,F2,49,9B,E6,F1,4C,E4,C4,E7,76,26,0D,E3,CE,27,C9,B8,1C,76,B0,A9,04,DC,22,93,5F,6B,30,5B,83,3A,F3,6C,C6,BE,B0,28,DF,27,61,DC,99,50,CA,85,6E,5D,F7,F5,9E,FA,ED,80,B2,D5,4A,9E,A4,75,FC,4F,B5,F4,E1,C2,5E,B4,91,9F,74,5C,D5,B8,EB,09,8F,05,4F,B2,29,C0,DF,FC,32,41,ED,C4,0A,86,DE,DF,7B,4E,0D,A3,FA,15,6A,5B,65,AE,0D,96,C4,F8,16,0C,BE,45,55,83,18,1A,71,9B,34,F7,85,6D,6F,29,6F,7A,E3,F5,D4,B4,18,2A,61,64,4D,45,E3,22,D6,7A,70,3E,C2,1D,A7,BE,DB,B1,F9,29,E4,66,9A,B5,69,85,4C,8C,C2,69,4A,BB,18,2C,E6,88,80,16,C3,C4,9E,66,E3,63,43,A2,9E,2F,E8,C1,26,8B,FD,37,44,33,39,94,32,DA,65,4C,67,A8,EC,3F,50,AD,95,54,AF,1A,0E,B6,74,14,6F,42,B8,24,C6,48,0E,47,F6,38,9C,20,7A,09,86,BB,13,08,88,9E,AC,B6,C3,77,B7,E8,3E,88,3F,49,CD,F2,78,7C,82,9D,92,56,28,2D,67,0F,18,DF,ED,17,85,1A,B4,9E,39,F4,D1,D9,D9,7F,58,7C,7C,F9,2F,59,47,85,87,D0,AE,BF,0C,64,C0,9F,2F,66,C2,08,32,45,B5,E7,47,BD,A7,E6,B2,BA,18,64,74,CA,01,08,57,C0,ED,7A,29,1C,A8,14,C4,79,95,A5,3B,DA,4E,7F,8B,EE,55,9C,18,D2,77,03,6E,F1,B7,B3,E8,0F,F9,01,16,73,AC,DD,F6,F0,AC,C5,92,B4,2D,2A,F6,6D,33,C3,E6,2F,8C,E3,27,05,87,38,8A,E0,98,FA,37,BC,D1,D0,6B,87,6C,19,11,8C,23,1C,92,10,2E,D5,BA,0D,C0,FE,1E,B9,97,D1,AD,33,88,12,E3,4E,25,CD,4E,87,7C,0E,55,D4,A1,BB,32,DC,5E,6C,F3,E3,32,CA,17,9C,27,B9,7A,E6,71,F3,AF,16,B2,02,E5,33,E4,BD,34,E2,5B,5D,00,70,3D,F2,F1,ED,56,1C,66,DF,E4,F1,E5,94,8D,95,21,8B,C6,79,6F,13,28,FF,F6,3E,A4,74,AA,24,76,74,BF,E1,99,13,43,8B,1E,5B,46,D4,EA,88,73,67,3B,54,20,31,C3,E5,45,F0,4D,F3,13,96,60,7C,36,4C,3C,19,25,BB,9C,C8,82,0D,CC,AF,03,49,41,10,9D,68,B1,77,BC,A6,C2,DF,F9,62,44,CD,27,76,39,1C,71,76,D9,41,DC,BA,C7,F7,2E,B3,8E,50,B8,A2,2C,F2,5C,81,23,03,4E,B9,90,C0,41,FD,7E,F1,EA,28,31,EC,7E,AA,77,44,72,FB,56,6A,CF,D3,F9,3E,33,1E,F7,5F,93,85,27,29,11,AB,5B,AF,40,62,41,BF,D3,25,41,85,7E,3B,6C,2C,59,3F,62,91,64,E6,B8,4D,69,A6,01,C0,58,26,80,96,8C,7E,AE,70,A2,00,82,77,C4,4B,E3,F4,50,C0,43,34,C6,66,C3,B9,9C,3B,CF,64,DC,5F,C0,30,5C,45,2F,73,8A,9E,AF,D1,7F,F5,D4,61,52,5B,A1,57,7E,4C,81,D6,D5,BC,90,B6,5F,9C,86,64,48,99,64,73,BB,CC,A8,6A,F4,6F,F7,64,F8,09,A4,9F,67,D2,85,19,BE,62,FE,FB,A2,4B,19,D5,06,64,39,EC,03,06,18,2D,32,62,77,AE,BC,A6,86,44,D1,29,96,8B,CD,FD,FA,A0,BA,39,8F,86,C7,3E,4F,2B,47,D2,96,C2,1D,D3,2E,F5,BE,FE,FE,2B,AC,3C,86,0B,00,89,E5,56,12,59,DB,BE,08,B3,5C,FE,0D,CB,E5,0B,85,BB,55,67,1A,F1,1D,8C,3C,ED,70,43,D5,4D,AE,42,39,75,8F,A6,5A,BD,3B,35,F7,C2,71,61,60,64,9E,E0,9A,43,F6,F7,4A,B3,02,FF,9D,8A,98,57,1B,1D,BD,9F,BA,5A,C7,4F,55,27,5B,24,AA,4E,85,4B,4C,15,C2,5A,0F,87,2D,86,A1,2A,20,38,C7,0D,A5,DA,78,AC,A7,A1,48,96,B8,9D,9A,3C,AB,9A,47,EF,2D,7E,0C,41,7F,53,DC,B7,AF,42,D9,AC,16,0B,C2,72,B2,80,E4,BF,90,8D,1C,08,39,F0,4E,14,57,47,82,69,6D,84,6B,E4,61,20,9E,70,63,D2,84,F9,03,45,77,A0,A1,D7,C1,7A,7A,A3,7B,2B,C4,41,D3,5C,6D,B7,34,6D,1E,80,52,05,14,D1,42,DA,13,32,EB,78,6F,D6,61,C0,19,CB,1A,22,3A,E8,84,C2,97,DA,CB,CE,14,11,B6,B7,81,10,BF,6B,91,2E,15,2E,48,73,F5,9B,94,BA,25,AB,BA,E4,6B,F6,9D,69,D3,7A,EF,03,14,C7,74,1E,1F,92,AF,01,90,5F,FA,A2,DB,6B,06,7B,D6,CC,78,31,87,CD,BE,73,04,D9,3E,36,46,4B,8C,FA,74,FE,E5,31,15,17,3F,60,4C,E8,73,D8,F3,42,E6,FF,E7,69,43,B9,53,BE,A5,2C,25,5E,57,1A,7E,12,45,9A,0A,77,96,AC,BB,11,27,F9,A6,7C,90,C2,94,A4,D7,20,E8,CC,0B,72,47,9F,61,57,7C,9F,08,CA,90,74,FC,20,C7,0C,00,3F,BA,57,03,2C,A3,6C,0D,82,38,D3,4A,F3,64,76,45,D7,B2,10,63,CE,B8,BA,EC,C3,ED,C1,A8,A2,2B,C9,DC,B5,18,09,FE,77,BD,EC,D9,D9,95,80,D5,17,9D,55,CB,B2,7E,5A,76,8E,61,55,DD,66,8E,08,75,0A,F2,2C,95,E4,CA,AE,5E,31,87,1B,38,A6,ED,0C,DD,74,BC,D3,11,F2,A8,45,2B,D0,FE,8B,61,D7,6D,F2,45,1E,80,16,B2,3D,B4,74,F0,E1,F1,0D,CA,E9,F0,00,35,8A,0E,E2,49,2E,6D,DE,D5,00,5E,DD,01,28,04,89,2F,AE,FB,DB,0D,87,9B,8B,9A,E9,D2,60,E8,AB,05,53,E8,FA,3E,ED,F5,8F,25,56,3D,1F,C7,DA,77,68,78,29,9A,B1,9D,F4,30,D1,5D,F1,28,B7,EF,C2,B3,23,6C,8E,14,1D,6C,D1,12,BE,EE,5A,93,CD,6A,66,D6,D7,7F,4F,93,35,90,7D,23,5E,E0,12,63,8E,43,21,24,3F,78,C7,83,E6,7E,EC,84,A4,73,18,D7,60,25,41,48,5E,3B,BF,DE,45,C2,A5,AF,26,2C,85,06,0C,CF,07,8A,18,33,CC,5A,F7,DB,92,B3,FC,56,E4,15,1C,64,64,A4,9C,14,D5,50,23,8D,79,8A,6C,BA,86,B7,EA,56,1F,50,1E,08,DC,11,4D,3C,6F,18,78,A9,DD,B5,EB,56,80,BC,57,41,05,65,F7,AA,19,AA,F1,8D,A0,D8,50,31,81,D6,B1,C1,73,51,FF,97,39,2B,3F,84,DD,87,A3,CB,B1,0A,30,0D,4D,48,40,FC,5A,6B,0A,89,EC,6D,FB,7F,70,69,52,96,CF,DA,FE,6C,87,E8,80,FE,8C,99,F1,21,8C,AC,3C,3A,13,75,22,F6,E3,7F,F8,64,ED,2B,C5,B2,3D,77,72,D1,E5,74,51,DD,8A,73,BA,DA,E7,9D,92,C9,FF,08,1D,7E,CD,38,29,25,52,E4,47,70,3E,0E,C0,67,14,C8,29,6A,C9,64,D8,28,29,8E,3F,31,A7,E4,DD,D1,5A,4E,EA,12,B7,1B,4C,88,91,E8,8C,78,3F,9A,A8,F4,C2,90,99,9F,5D,2C,CE,E8,7C,D0,F1,E7,5C,FF,A9,B8,27,2D,9E,BF,70,C3,FF,E7,2C,44,8F,81,80,A4,C1,E1,FD,CA,98,A8,0D,98,CF,92,A1,0C,05,D0,66,76,34,C4,1A,0F,8B,FF,80,DF,51,81,33,48,51,2B,99,34,FD,06,ED,06,91,C6,A1,43,32,D5,34,87,10,66,2B,85,E5,07,3A,8C,E2,5D,6E,98,34,65,6F,F1,C1,8D,C2,2A,B5,DE,2F,29,B2,1C,59,FD,4F,01,F1,0B,9B,95,C9,31,D3,DF,38,38,05,7D,32,F5,67,2A,AB,C0,66,C9,C6,B2,99,DF,80,49,B0,60,29,0E,AF,86,8B,A6,DE,BA,5C,FE,75,5D,60,C4,37,DE,62,CB,DA,6A,CB,D9,96,84,13,57,98,57,80,35,C5,65,7D,E3,A2,C4,64,32,FD,08,D1,75,02,FF,0F,70,C9,EF,25,3F,56,7B,F8,8C,50,A0,F9,36,AE,7F,83,65,3B,B0,51,A7,9D,1A,89,DC,F0,E0,03,33,5A,63,33,B3,96,35,29,69,93,91,D9,FA,70,B9,6F,73,29,7D,44,C2,ED,D0,BA,28,8D,7B,F8,27,5D,93,C3,28,34,C2,6E,27,B4,00,D7,46,99,CA,7B,09,70,D9,9E,6E,B9,7B,64,B7,04,B4,13,CC,18,8E,12,9C,36,03,DF,D6,83,E3,A4,A4,66,75,6E,12,A7,FC,63,8D,A0,2A,53,19,3F,AF,ED,66,4D,58,97,4B,AA,12,AD,2D,BB,72,25,48,FF,0F,36,44,F7,74,82,3C,6E,93,56,A1,84,DF,0C,87,20,4F,1D,94,46,85,F0,BB,ED,2F,84,3E,3A,29,1B,EF,84,0D,E7,03,EB,CD,FC,2E,92,E1,B9,B0,4F,11,B7,CB,43,1D,EC,3D,60,65,48,07,BC,10,12,C3,EE,19,03,EE,00,83,2A,25,B7,36,63,60,BB,D3,9A,F0,39,E9,CE,3F,20,75,7F,99,24,C0,35,F3,23,D3,C1,9A,EB,BE,C8,4E,72,6F,47,D9,87,E9,56,45,E9,C5,29,94,B0,CF,E2,7B,17,B0,97,F4,47,35,F6,37,ED,90,7F,B4,93,26,75,C8,6E,83,9B,C4,99,87,29,93,73,96,3F,2F,E7,B8,91,5E,57,09,80,67,47,11,80,97,74,8B,2D,00,05,6E,B5,E7,51,1E,FC,00,94,D0,77,5B,30,97,6C,5B,FA,81,24,0D,2F,48,C6,08,B2,B3,16,FC,5F,9A,74,5A,BB,50,D5,46,85,4A,C9,1B,63,CA,00,E2,26,56,D0,D0,E2,3D,92,CD,55,56,DF,90,83,F1,83,3D,1A,9A,D3,8B,F6,7F,FB,C5,49,81,FD,92,D4,E0,6F,FC,3C,27,21,8A,2D,CE,96,B6,4A,A5,A6,80,76,26,4C,67,CE,9A,27,45,E2,14,9F,38,FE,A0,9B,12,9F,24,D0,4E,27,98,A8,AE,04,14,DD,33,7C,9D,9C,71,D8,6F,DE,AE,7E,6E,36,C1,37,BA,0F,64,9A,03,11,59,F4,A3,45,9C,F9,95,7F,D0,C8,89,0D,30,9F,D0,44,6B,E2,AE,6F,69,A5,A7,2B,F8,85,9E,5B,D9,AE,C1,DC,50,14,9C,63,E1,40,F3,D7,46,39,F8,16,A0,AC,46,AB,50,D3,6A,90,5D,40,72,56,7C,87,53,77,5E,AC,C2,B1,27,35,B9,B3,12,20,45,B6,09,DE,70,7E,1D,B3,06,27,FD,F0,94,98,0F,44,C9,61,BD,AC,98,5D,CA,EA,0C,6E,5A,97,09,64,68,1A,AD,B0,F5,B0,BA,40,71,8C,34,94,94,EB,8A,A5,C9,30,34,94,5B,85,A5,05,FF,B3,9B,8D,B4,86,40,7A,C9,B5,3B,AD,A8,7B,66,7B,DE,86,78,39,E6,02,1F,7E,EF,68,F2,1C,B8,83,ED,55,7D,81,E0,E0,38,BE,A3,81,F5,BB,B5,24,9A,1E,96,92,9C,EF,2D,A6,B4,E4,88,E4,91,E7,37,54,2B,FC,8B,AE,9C,0F,47,38,C3,6D,9A,D5,42,D3,45,4D,6C,A7,8C,63,14,CF,3C,F4,21,7A,D4,90,1C,9E,13,CB,5E,69,7E,D5,C4,73,AB,2B,CE,AA,4F,AD,58,6D,92,99,C6,6D,8B,E1,FC,16,35,53,E0,A3,DC,78,34,E8,D4,78,D6,D2,81,65,1A,AC,9A,69,5A,AF,BF,0A,5B,C4,D8,68,B1,6F,70,6C,80,7B,13,6F,09,B2,FB,CF,93,FE,F1,CF,74,C7,82,58,EC,80,B5,0F,B6,9C,4A,56,61,77,2D,CA,E4,60,5D,E6,DB,85,99,47,73,85,84,FB,54,F6,D7,0E,BE,47,E4,61,EB,43,9E,09,40,62,61,BA,49,E0,3D,A5,FD,CD,49,F8,AB,11,B6,5D,6D,AC,4C,20,DB,39,99,2C,C2,34,5B,22,41,59,0F,D8,93,91,91,D3,C8,25,9F,CD,F2,26,A7,76,27,25,FD,CC,C2,38,78,DD,95,48,2A,DF,02,11,E8,94,C6,AC,B3,F3,B2,22,99,2A,54,A4,83,CA,A8,74,51,96,1F,FF,42,63,96,72,CE,43,05,7F,F3,DA,D0,62,35,D8,BC,60,85,B6,7F,9F,DF,82,65,0B,A1,BE,24,C0,DF,24,B8,AB,89,34,0A,BC,E2,6B,D1,54,09,3E,6C,6D,49,40,F2,8F,91,D3,3B,8A,32,D6,B9,0F,54,6B,D6,1A,BC,0F,C1,94,26,23,35,73,B2,1A,87,F2,14,67,02,98,FC,8C,87,39,FC,A3,06,77,B9,57,94,9F,FC,8D,5C,35,7D,2F,A2,10,B6,E3,39,2F,5A,D1,92,44,38,07,03,06,B8,D7,F1,C7,2C,59,1F,31,EC,D2,0B,C7,81,44,E6,1D,AB,47,F9,C5,63,E5,C1,7E,41,36,95,B8,34,F9,4E,4C,03,C2,2E,B1,EF,73,E4,CC,C9,6B,7C,85,BE,1B,1E,92,9B,E3,A5,0D,5A,E0,73,CA,C1,84,1B,5A,6B,40,BF,DE,F0,29,76,D4,FA,51,3C,E0,E3,23,29,06,E9,9C,51,63,8F,47,8B,8C,63,6A,E1,72,45,14,EF,B2,21,4D,96,00,BE,28,29,FD,8F,3B,BE,70,DA,67,95,32,91,E6,B4,F3,01,FF,14,12,1D,7F,1C,25,11,F4,6F,82,AD,12,73,63,99,4E,4E,B3,16,D6,1E,48,6B,BB,E1,93,7A,A9,00,20,27,6B,F4,A8,A7,52,A8,60,FB,72,D3,B2,3E,56,E6,D9,CE,91,BF,60,7E,07,8A,71,BB,D1,F2,49,A7,3E,5C,85,E9,E0,CB,C9,B1,6B,15,AE,43,AC,09,4B,11,08,1A,2D,B9,BC,DE,A7,D3,2F,82,14,DF,FB,7B,06,6B,78,63,21,D5,75,EC,59,4F,1D,62,1D,30,AD,DE,6B,DC,1A,A1,3E,71,C0,0D,C0,E5,9B,B6,28,E1,A9,33,F1,86,CA,F3,27,C2,7F,62,5E,96,BE,37,AE,D9,E3,E6,C2,E6,1D,39,EF,E0,EC,3E,18,22,76,5A,63,BA,4C,BA,BF,8C,03,A4,70,C6,98,68,19,91,41,D4,90,E1,15,D2,FD,E1,A3,F3,98,5F,D1,84,3F,52,66,AC,9C,57,B9,30,1B,8C,4C,C5,39,86,97,65,6F,CA,8F,06,1C,A6,DE,8A,65,BF,B4,60,14,7D,F0,6C,6D,03,77,AA,B3,10,0C,E6,C8,59,BA,00,AC,6D,75,70,A5,37,51,71,66,30,A0,DA,7D,7C,60,8F,5B,B9,97,04,3C,9D,CE,52,95,4F,88,51,2A,00,C1,F4,60,29,ED,B1,C0,E8,38,16,55,72,7D,69,03,D4,39,9D,2F,CA,34,C6,5A,B7,C8,16,BE,C2,00,CF,D3,0F,EF,C8,38,8C,0A,F7,D2,C3,9A,E7,DC,1F,CC,64,A1,E0,C0,2C,F9,75,ED,39,F3,A8,B2,06,44,0D,55,AD,5B,3B,E5,E4,7E,AA,7B,41,39,D0,22,07,FB,61,5F,A1,B3,11,0A,9C,9D,67,C9,26,8A,85,37,D0,35,46,F1,FF,A0,F9,55,04,DC,E2,D7,1C,35,44,BB,38,35,D6,D8,10,6C,32,44,31,A9,CB,45,BA,D8,33,60,F6,BC,74,D9,FC,B7,60,C9,D3,13,39,94,A2,56,B2,83,6E,3B,74,FE,28,E8,AB,4B,AF,49,D5,A6,15,76,BD,52,87,F3,65,99,2A,5B,8A,8F,E4,9E,FB,77,0E,D6,BB,C7,B0,F8,E2,E9,0C,AC,98,D6,0B,ED,58,E4,AF,90,32,3B,FB,7B,E2,5A,10,7C,8C,5B,E2,AE,0C,9E,74,5B,3B,E7,6C,0D,E6,96,C0,9E,E0,FF,69,0A,D7,E4,37,D3,3C,3D,F1,D7,39,FB,F9,BA,E4,FA,3E,76,A0,F0,9A,CF,4C,49,A4,4C,CA,28,91,24,1B,8D,F2,3E,4D,04,ED,FD,83,2F,63,02,0F,B3,65,07,4B,BC,1C,E5,75,FB,1E,FD,CB,CC,54,11,47,2A,F3,35,87,67,74,B0,42,0A,87,93,5A,85,32,D4,36,9A,A0,DE,AC,2C,25,F6,57,2D,7A,EF,CC,03,66,CF,87,29,09,6F,7A,4F,24,7B,22,12,03,5F,C6,D8,F5,47,45,3C,3B,9A,D3,43,B4,3B,6A,7D,EC,10,21,88,13,DC,6F,0F,E0,5C,63,FC,50,37,55,40,A5,D4,53,29,7D,D4,AE,1B,88,56,11,3F,CF,FA,CE,2C,CE,4B,63,5F,87,F3,E8,2F,4D,E9,E8,03,6E,AC,FD,57,1D,F3,76,A9,B2,FC,90,94,6F,3B,2E,FA,E8,54,E3,D7,50,F5,01,0E,94,62,44,9C,13,00,77,B5,46,91,D9,78,22,3E,D2,D6,2D,4A,B7,09,34,1E,C1,E3,1F,20,74,04,4D,0D,C6,7C,27,C6,F8,B5,4F,EF,E9,25,07,6B,F7,F2,B4,ED,B8,76,C5,3B,C3,0F,A9,F5,B8,13,36,BF,00,29,34,AC,03,D9,83,6A,71,73,E2,DA,21,31,FA,CD,27,F6,1D,D1,AB,18,94,08,33,DC,3E,33,7E,93,80,BA,41,C9,FD,AA,62,F3,00,60,DC,A0,CE,31,53,79,57,8E,B4,03,C2,4F,A1,9A,45,A9,B5,02,06,24,33,64,1A,1D,72,EC,07,EB,10,05,0B,DF,0A,2D,55,B7,67,7D,8E,A6,26,82,BD,54,7D,F1,EF,C8,1B,04,4A,F7,0F,B6,CF,35,49,55,BB,6B,32,C1,F7,A7,78,47,A1,29,C4,80,9F,E7,07,28,E9,A3,91,30,51,5E,83,15,FE,DD,AD,86,AA,28,17,52,EA,55,4D,24,7B,7A,A3,5E,FA,81,BC,72,C7,22,D9,6B,EE,26,5C,D2,40,A9,40,C1,43,D1,11,72,8C,AB,09,4F,A8,EE,A2,61,DF,7D,1C,1B,E6,16,C8,E6,25,B4,57,16,FF,94,81,B5,EA,FA,A2,6E,E2,CD,73,DD,57,21,B2,32,5D,E4,AE,3A,13,69,35,CA,C0,30,9D,26,00,02,A5,FE,3F,1E,09,77,36,F1,F2,45,7E,6E,0F,41,48,DD,23,9C,AE,B1,E3,E6,4F,E0,9A,F0,E9,FA,47,6E,7F,2C,CF,AE,2E,41,0C,52,FF,BF,C5,B6,73,F2,FD,D6,66,41,43,23,9B,DD,B1,4F,1A,33,84,EA,90,77,52,C5,A2,C4,6E,EE,29,90,9C,ED,44,2C,CA,55,E3,A1,FF,4D,03,45,45,2A,B7,60,4A,2E,BB,64,0E,C8,E2,D1,E3,08,1A,70,CE,B7,BC,D0,AD,98,85,69,E4,77,FB,B3,5F,5B,B9,11,0C,28,20,30,B2,79,D7,A0,1B,43,EB,EE,51,C8,0E,B6,9B,06,95,43,94,15,10,74,1B,CF,02,43,08,CA,C5,4D,B2,8F,BA,F8,EC,CF,59,8E,09,73,F1,37,8D,22,0C,8A,03,66,CE,09,47,84,0D,3F,1B,E0,82,13,09,0E,22,B0,2C,78,25,AC,DE,20,34,BD,6A,7F,21,A1,7D,BF,58,87,87,C9,BF,F1,F8,1D,14,E2,15,00,EA,6C,DE,8E,59,96,76,D0,88,19,D9,B3,55,DA,36,D4,05,22,B7,D7,AD,A5,1A,1A,BE,8F,08,1F,77,59,1B,A1,23,AC,3A,76,81,68,FB,AA,5A,49,23,4B,65,8D,4C,28,54,FC,CA,C2,E6,94,D1,C1,4E,C9,65,17,E3,AD,17,F0,F6,2F,36,E6,1E,3F,1A,6D,5C,3E,B6,D3,96,E6,ED,4B,E5,93,45,65,5A,FA,19,67,40,8F,69,14,47,5A,4A,19,32,A4,C9,2B,9E,D3,7D,6B,10,3F,1F,7B,A6,1B,BF,7C,B5,09,D4,35,30,35,9E,7C,7C,BC,9B,F2,F1,12,A0,49,FD,46,C0,2E,C6,62,E1,23,F6,E7,73,B6,14,C9,75,B5,F3,41,A0,48,08,60,55,57,A9,59,DD,32,32,BE,B1,1E,EE,E8,AE,F2,75,B2,2C,D8,E6,BA,43,46,72,BB,52,BF,7F,D5,0E,9E,23,FC,23,57,71,E4,7D,FB,04,24,EB,5C,5A,5A,D8,84,83,44,CC,9B,71,C0,37,65,A9,E5,15,3A,E6,68,86,FD,EA,6F,17,DD,E4,1A,BF,17,E2,B5,C0,42,D0,7C,68,9D,96,27,7B,3E,0B,4C,00,82,A6,CE,5D,8E,FD,49,5A,9F,76,7E,49,7D,03,E5,83,F0,91,8A,42,DE,B8,B7,2B,56,A9,2A,13,6E,1D,3F,7F,BF,6F,32,EE,8F,5E,70,41,6B,1B,0F,B0,14,E6,B2,AE,55,80,79,6B,60,04,0A,98,50,C5,AF,96,0A,EE,70,E3,4A,FE,73,EA,C6,DB,87,D1,B3,FD,9D,AA,87,AE,DD,D3,87,7A,5A,B5,4A,53,85,DA,C6,22,0C,BD,98,94,C1,AE,A3,EC,B6,D2,FA,4C,C5,5C,8E,B4,77,7F,D4,BF,A1,55,47,BF,93,F0,E5,7B,08,D4,3C,0A,06,20,2C,96,C9,E1,B5,06,44,9D,FA,AF,49,0C,64,83,55,4B,BA,E1,09,AC,F8,5A,51,2E,4F,1B,63,AA,F5,E4,07,12,95,73,3B,55,02,3C,1F,D9,9D,D0,55,CF,37,9A,87,31,52,6E,AA,A5,44,53,8D,FA,A3,98,9D,11,E2,D3,F6,87,38,67,5E,24,91,7B,1B,65,2F,9D,C5,91,57,17,CD,2E,CF,C4,4C,2A,64,55,97,B5,76,00,DA,7A,A9,82,9F,0B,4B,96,04,23,59,9C,88,3A,CB,76,77,81,83,CC,D5,72,B4,65,71,BB,53,7E,A8,5B,83,DB,95,BB,7D,C2,FD,A1,A2,B2,89,30,80,CB,A0,AC,3C,BD,E2,7D,B6,D9,00,7D,30,8D,2A,62,E7,C3,AC,F8,96,D2,2E,EF,D5,17,52,59,CB,E0,D0,14,DC,D5,B6,06,16,2A,AB,32,A4,3E,C2,8E,3F,B2,64,31,7C,37,00,5F,26,AF,D8,2E,9C,56,91,61,DD,98,A3,AB,75,20,E2,4D,B0,B8,65,E6,CF,BA,0C,A0,3C,27,2E,5F,86,4B,9B,E1,DB,A7,29,F4,16,ED,EE,2E,4A,7D,93,9F,FE,96,EE,78,D5,93,CC,87,62,09,1B,00,15,F1,9E,98,90,6E,4A,F5,06,A7,1F,8E,D8,B0,3C,9A,F8,0C,F7,28,86,BF,42,31,9D,7D,31,D1,F9,95,32,AA,D0,20,E5,18,2B,02,46,98,86,89,38,81,84,FA,86,D6,B7,F6,2E,3A,F6,94,42,89,24,19,6E,5B,A2,66,60,D9,45,B0,E1,73,98,DE,C7,7B,BD,A3,49,07,95,E3,4D,DD,17,2E,3D,2A,3B,31,DF,5B,A0,F1,76,A7,8C,36,32,AE,3F,9E,BB,04,EB,D7,F1,00,DE,CF,DC,4D,04,5E,A3,5A,2B,7A,17,2E,49,09,25,4E,29,84,91,A1,22,58,A8,C3,0B,53,0A,79,8E,81,3D,77,7A,22,BB,C2,91,88,A3,0C,78,A3,5A,0B,2C,70,24,19,45,4D,81,E3,97,82,67,CE,7B,4F,0C,12,98,F4,06,D1,C7,B2,53,68,E1,66,FB,DF,FC,8E,E3,BA,8C,FA,01,4F,5B,4E,62,C9,83,74,8C,48,61,80,1D,56,19,B8,8F,77,83,94,CB,C7,18,96,62,C2,B0,4A,0E,16,C0,97,80,A9,E3,8A,C7,2D,9E,26,CD,FA,30,AB,6A,04,AE,D4,BF,C6,F2,57,BE,47,F9,CD,99,E0,2C,26,2A,CF,84,82,78,45,E8,9D,53,BC,64,5F,1B,E2,23,25,A0,0C,08,91,45,5A,D3,EF,1A,35,61,5E,EA,A4,3D,DF,D1,A1,49,74,E5,1E,7E,AD,E0,6D,75,D1,90,DC,16,99,23,91,7D,66,E7,F4,C9,12,57,B0,9F,72,ED,20,CA,36,1E,76,B8,16,D7,B6,42,CD,79,79,14,4B,B0,BB,E0,28,78,8D,BB,A1,E6,12,4E,DC,EB,48,1E,51,63,8F,71,32,2D,D9,63,C3,60,D9,67,FF,AA,6F,8C,2D,18,53,B1,2B,B6,17,D0,00,1F,FC,4F,1A,4E,64,F2,23,30,58,C6,E6,78,DF,1D,5B,A7,6A,85,E3,EF,8C,79,98,07,88,E8,06,BA,A4,7D,6D,BA,AB,79,B8,18,DF,9E,FB,44,1D,F0,F5,3A,81,C7,16,9B,47,75,C0,25,CC,B9,86,90,D3,8A,31,B0,8A,16,C6,36,96,CA,7F,AD,19,A3,FD,3D,50,B1,D8,96,7F,1A,84,EB,01,4F,D4,AB,39,C2,BE,76,1E,47,9A,39,60,FF,D4,B4,01,F0,16,14,C5,93,39,FB,64,6A,52,34,DA,EC,91,BF,4B,BC,52,1A,12,D8,7C,B3,E4,A8,DE,9A,B6,78,A2,97,B7,C6,CC,0D,7E,4C,D1,6F,D0,DE,5C,87,66,04,39,E7,DC,52,0D,E8,3E,6B,6A,B4,4A,2B,CD,08,2A,48,E7,71,FA,E1,A0,27,78,86,9A,B7,5C,27,FE,56,01,C1,F8,71,09,F5,6A,16,F3,94,44,CE,69,FB,5D,AA,C1,B0,D8,36,6B,1C,8E,36,6A,D8,80,86,87,BF,93,BE,4B,CB,06,B6,CC,2E,F8,17,65,D9,DA,A4,82,A5,CE,76,FA,D9,F0,AA,23,18,ED,48,6F,74,57,7A,4C,B2,8F,A0,AA,B6,AB,8E,60,34,7A,3B,80,1C,65,FB,77,2A,09,21,5F,4D,8A,00,19,92,5B,A2,69,A2,4A,D4,8A,88,5D,A4,91,EF,7C,EF,B7,65,CC,E2,21,A7,13,A0,95,56,79,85,35,2E,84,0D,68,A7,49,52,65,45,D9,B5,07,B0,22,52,71,DE,FE,4D,71,1A,C7,5E,06,D2,A0,12,CC,D7,88,D7,59,ED,E5,0B,93,1B,23,8B,35,DC,4E,A4,E6,6D,C1,28,7A,DE,66,B3,8E,96,37,87,2C,8F,0A,85,9F,6A,FC,9F,3B,CA,AB,49,B4,A6,6C,73,44,12,96,CC,54,40,E3,49,A5,A6,6A,60,2F,4E,CF,49,1D,76,A1,35,12,40,7A,A9,0A,4B,C9,7A,7A,8B,71,B5,F7,48,F2,D7,60,F7,A9,9A,58,E2,BB,DC,9B,12,F5,06,91,76,38,3A,27,A0,93,64,FA,08,5E,FB,42,2A,44,36,B0,D3,48,58,B4,95,15,F8,CA,1C,3B,F0,4A,6E,43,75,45,2E,8F,48,F1,04,26,55,70,02,8F,B2,C0,AB,84,8A,C5,84,CB,4C,76,C2,3B,2E,1F,2C,71,DE,4B,69,AD,29,B3,B4,5E,31,10,F4,94,6E,A3,49,C6,08,A0,14,62,ED,D3,87,69,A8,5A,46,1C,34,57,9A,BC,46,80,A0,0D,C4,28,02,90,41,35,AA,95,33,33,68,A4,3A,10,5F,33,BC,3C,99,5C,21,8B,DB,BA,27,E3,6C,B9,D2,5C,89,1B,04,63,6F,BE,02,9D,E9,76,70,BE,EA,88,BD,05,D4,EF,0C,90,1D,87,56,8A,03,50,68,E2,DE,24,36,52,B1,DB,51,AE,1E,9D,10,1E,3D,C2,0F,7B,3F,81,9D,BB,AB,2E,F6,A8,92,A3,AD,FC,01,2E,57,DD,5C,F8,34,70,3C,B9,AA,31,26,17,58,F9,40,00,5E,D9,77,E3,BC,DC,59,4D,97,BE,83,67,FE,1A,78,13,AA,23,A6,8E,F5,83,DB,E4,76,22,15,F0,85,E3,65,EC,43,60,DB,CE,46,61,02,2C,FB,F7,3D,86,FE,F8,3C,9F,2E,F9,C7,D4,ED,61,F6,25,1D,23,B1,71,97,C2,D7,19,7B,65,73,68,D1,7C,EF,48,E9,86,2C,E4,90,68,17,AA,8C,57,F2,47,BB,AA,E4,AD,65,4B,72,37,A2,5F,64,CE,FF,72,07,3D,D0,27,31,4C,5A,F9,25,90,48,43,21,FC,40,89,3F,4B,47,C5,DD,F6,53,49,D2,E2,FD,DB,4D,9E,82,F7,BB,8D,02,41,7C,D6,5D,A9,5C,6A,BA,1A,BA,0C,53,06,0B,36,A5,76,8A,DC,33,B2,9C,0D,AB,DB,DE,49,20,01,94,7A,22,90,95,37,7D,90,A5,1A,2A,1D,CF,AE,90,EC,DC,4C,85,2B,FD,FA,39,1A,07,CD,6B,51,5F,C7,9C,79,79,C3,15,89,39,5F,EE,FF,5E,F1,FA,DB,DE,7E,BE,B6,B8,4A,BB,ED,4E,18,8A,5C,28,75,40,9D,A0,19,9D,1E,8D,31,BD,4F,EB,F5,D3,B7,F7,4F,AF,BF,71,E9,34,98,B0,B6,0A,03,88,CD,8C,B0,7F,E3,E7,D8,35,73,22,53,F5,8F,2B,2C,29,C4,52,07,2A,20,7E,55,3A,1B,8D,FC,7C,19,4C,2C,7D,A8,04,0A,D6,91,27,0B,93,59,C6,0A,1E,26,1D,75,43,F0,A4,3B,95,0F,7E,4D,CB,28,9C,37,98,15,7B,35,9A,0C,A3,5F,C0,41,58,AB,15,1A,B9,58,B5,F3,99,67,96,67,69,DD,B4,DE,12,F5,8A,AB,C5,52,E7,38,85,FE,16,44,2C,30,23,DA,B9,B6,58,FA,AB,0A,E0,4F,A1,6D,2F,6C,3E,8C,9F,7E,31,3F,41,5D,79,4B,E8,63,EF,61,3E,8A,B2,83,B6,96,76,73,E3,24,CB,FD,38,1C,2D,CF,01,C6,06,D2,D0,F2,11,83,03,9C,86,FE,68,B3,06,BE,2E,1C,F0,57,FC,BE,FA,DE,5C,AD,82,21,F9,EE,D0,67,2E,3C,31,54,9E,0B,8B,E8,82,A4,71,F3,8D,F0,28,14,B7,AE,32,E1,58,DE,BB,09,42,D3,8D,93,D6,AB,D5,79,DF,7D,F7,F2,00,35,EC,19,32,8F,65,5E,EA,51,5E,57,37,CA,89,12,D4,23,E2,C1,04,CD,76,64,1C,2A,03,25,3E,D7,BB,F4,B6,73,8E,C5,82,3F,10,3E,C4,5E,55,C7,B6,20,C4,0D,0B,F1,10,27,81,21,B0,76,F9,EB,35,7D,A6,20,EA,67,DC,79,83,12,5D,6A,83,09,53,E0,B1,8F,45,D8,17,53,9E,AF,C9,9A,F4,2A,F4,B4,F0,D5,42,55,EB,A2,1D,F3,D1,E8,E8,9C,2E,49,70,BE,C1,D5,50,C1,04,4C,AE,C4,A2,5B,CA,54,54,94,33,27,76,DA,24,63,32,F0,05,B7,1F,F2,4B,C9,46,F1,2B,03,C0,D1,67,4C,6E,96,F9,2D,4B,30,7A,EB,30,7D,53,FC,51,C3,4E,7B,09,EA,1F,C7,25,3B,73,F5,2D,5B,8B,DB,92,C1,B7,84,91,DE,1C,70,DE,B7,20,BC,3A,35,93,DA,A0,10,E2,F9,03,DD,7B,8F,C3,E0,AA,1C,0D,48,D2,CA,67,58,F7,22,FF,90,37,D7,59,A6,59,5F,80,4D,53,6F,24,22,22,2D,73,A6,97,A6,99,D1,13,99,88,18,8F,80,44,1B,12,81,C9,2D,1F,0E,B6,B9,4B,B0,AB,1D,ED,B4,BE,D3,30,00,B5,60,60,48,A6,F6,4F,07,36,6C,E8,C0,9A,96,44,16,57,AE,3B,1F,CE,04,D0,8F,37,F6,69,C7,21,A6,9C,2F,9E,0B,0B,C0,02,80,A3,8A,82,FE,4B,E4,40,97,CB,62,3A,B4,75,D8,18,BC,15,A1,22,E6,46,13,51,55,75,3D,C3,78,D4,19,4E,17,3F,BF,7D,1E,2B,65,A4,84,3C,DD,9E,80,5B,69,E4,CA,C2,09,43,BD,B0,BB,90,E0,AF,BB,E2,61,F2,9C,41,21,25,CF,5B,82,A7,13,09,17,91,82,A7,38,F0,A5,52,B5,58,57,DF,FA,E2,58,2A,91,8A,FC,8C,73,26,77,BF,0C,FF,BA,28,4F,FE,09,2E,D2,0B,7D,68,01,C8,DD,DD,20,CC,2B,FB,6A,B7,97,AE,EA,EC,62,5C,A5,75,93,6A,76,F6,FD,B7,F6,F2,14,C1,87,CF,48,0D,D9,0D,38,86,FF,D2,C8,09,3F,C4,BE,CF,AA,C3,D2,F1,91,47,87,89,93,0A,1D,58,70,EC,6B,6A,45,5E,50,EB,BE,19,D2,B2,8A,B2,16,80,6C,CC,2C,57,9D,3A,11,77,D2,C2,1F,19,EA,9E,F1,80,7B,CA,35,7D,58,28,CA,3A,78,FC,82,0B,C8,22,64,A2,B5,3F,AF,FD,BA,11,00,CD,95,C2,5A,60,28,AD,97,41,7C,F5,A3,69,4E,75,B5,1F,3D,EA,AA,6C,50,08,B4,3D,CA,D1,97,2E,C7,CA,B9,D6,64,8B,50,68,72,B8,50,56,E0,D9,24,F4,82,F1,90,95,C8,50,A1,A3,E5,BB,D3,C5,AD,EF,E2,A1,C8,58,64,5D,DB,00,1C,BE,E6,A0,FB,AD,7E,63,FD,6D,5F,AF,EF,B9,87,CC,E7,F7,C9,B2,45,DC,BA,78,16,6F,15,E1,B5,AF,72,CD,B3,20,B2,A9,FE,6A,47,41,78,2C,D7,57,1F,21,D3,84,CE,66,80,CA,99,24,BB,A4,27,A7,38,AF,6E,D3,50,85,A7,5C,9E,FF,4D,F6,A4,04,B5,C3,39,85,DB,48,6C,64,30,26,B4,37,6C,20,15,26,F3,3F,1A,0B,BF,64,AD,29,BE,36,1E,CA,8E,57,08,19,3E,97,5F,CC,F6,DF,C0,23,0D,2E,C2,45,46,0D,6B,9A,66,10,86,C0,87,1B,50,91,35,47,84,04,1C,2F,29,7A,07,7D,34,6C,3B,0B,E8,A3,21,10,78,6F,35,E7,3B,73,C2,32,FB,14,3F,9D,31,C2,AB,7C,E7,C6,23,B9,DA,CE,26,A8,DB,37,19,B5,5A,9D,7A,6B,B2,EB,6B,EA,E9,D6,7D,15,F4,41,F3,46,B2,C8,1A,6C,68,F6,06,02,C4,1A,E9,A2,9B,A7,3D,C9,2D,CE,E2,0E,67,10,38,1C,BD,17,2D,09,C6,BA,D6,66,DF,54,66,E0,8E,5D,13,60,77,FB,1A,73,98,F6,D6,C4,67,9A,D4,F2,2B,90,D4,23,F5,5D,28,30,21,7D,03,40,64,07,66,D9,C6,1E,14,45,88,96,6E,B7,22,F9,7F,94,99,C5,C3,70,AA,74,0E,CE,0B,D3,5E,68,F6,C6,13,5D,97,8B,2A,8D,95,09,6E,75,BD,2D,3D,DD,74,0C,90,95,15,DB,BA,E6,8E,D3,72,A4,16,DA,67,0E,22,38,5E,F2,39,F1,84,8D,56,20,9A,98,A4,2B,95,61,FD,8C,3A,6D,78,EF,B8,73,63,44,86,17,81,A1,63,F6,BE,D7,7E,A3,82,44,7B,C9,F5,30,49,AA,30,BA,0A,6F,B5,CB,C0,86,A7,DB,19,57,72,09,D9,7C,9A,0A,48,98,FB,86,EC,AF,57,4D,63,58,A5,89,3E,43,1C,86,F7,2B,BA,F5,8F,73,05,63,0F,CE,90,08,99,84,59,05,BC,E7,A7,2A,A2,80,0B,84,B7,93,FF,ED,C6,E1,9F,72,0F,B2,C2,93,22,12,5E,11,55,39,88,3F,56,B8,A9,1F,9E,1F,B5,0B,02,4D,31,A9,1F,C0,25,03,6D,3C,3D,D4,6B,C6,F3,6C,33,58,DF,F4,8E,B2,C0,57,A8,3F,A4,C1,A8,E2,D3,FA,58,43,93,4B,DC,E3,16,38,0B,B2,57,BF,D1,DF,D0,A0,34,5C,85,26,6C,62,9D,18,63,0C,C8,9E,67,31,CA,13,4B,AA,59,39,DF,3A,26,4E,F1,45,43,C1,F2,C2,49,C9,C8,CB,3B,6F,BE,71,3F,E4,DB,46,95,8A,A5,32,D8,46,01,93,47,35,8C,9F,53,DA,A6,BF,B7,EC,FC,6B,C9,6A,FF,D4,00,8C,FE,94,8B,07,13,80,19,F6,15,11,57,D7,C2,9C,2A,4A,EF,60,5A,24,DD,66,95,2D,98,AF,F1,E4,75,DD,45,19,9F,FA,3F,54,CF,A8,93,18,90,F5,A7,A0,BC,BE,21,8A,67,A1,7D,B5,F1,A0,9E,FB,DF,F5,A6,D6,06,FD,36,40,9F,44,DC,56,62,AD,9B,2C,94,65,D7,D8,D9,6B,68,3F,88,95,8F,1A,49,E1,07,04,D1,F9,88,33,2D,17,0E,BB,1D,E6,52,E3,AC,F0,7E,D6,49,7A,C1,47,B7,08,DD,08,5B,44,30,2A,48,BF,1E,E9,49,75,F9,C8,A3,95,DA,8D,19,EC,E7,B4,05,9E,4F,BC,8D,44,D5,77,B5,66,4E,1E,8B,C3,28,20,F0,3A,92,3A,BA,5C,44,5E,CD,E0,1C,11,61,A4,F2,02,10,2D,4D,5C,E8,B3,76,C6,23,F2,01,97,00,E8,AE,A7,35,38,D8,AC,48,7E,39,DC,AB,23,63,22,B1,03,4E,6D,E7,A5,AF,68,63,28,2C,0B,AF,DA,BD,21,A7,23,23,B3,DD,43,FD,D7,01,23,F5,1A,56,25,CD,E5,D1,97,D7,91,98,E0,C0,88,10,B3,EC,C3,B4,80,4A,D5,1C,C3,0A,37,68,E2,0F,8A,CF,06,12,B2,2D,5D,A4,F1,E6,BC,FB,CB,FE,85,E6,86,6E,16,14,95,E2,15,72,C2,C3,67,91,8E,0E,0B,11,2F,03,A7,9D,3E,4A,C1,8C,24,C8,1E,86,41,B4,53,47,48,7D,4F,32,BD,3E,CC,9E,79,21,A6,B5,7F,B1,51,5B,58,F5,98,0F,E3,38,D6,F7,FD,21,CF,7A,95,DC,50,8A,F5,7A,19,EB,CF,F3,59,2F,7B,FF,22,E8,9D,23,83,DA,20,E8,E6,C3,76,5E,35,F9,A7,66,7D,32,CD,3B,23,D2,FA,2B,C7,1D,C3,C8,E4,61,EC,2B,96,07,CD,30,EC,DF,90,D5,50,E5,6F,2E,4C,DA,74,53,6E,9D,85,99,E5,CA,AA,C7,B9,74,F4,D7,A4,66,1F,6B,96,BB,94,D8,4B,E0,7A,07,39,1B,FB,85,73,1D,46,29,56,B1,16,E9,AA,A3,6C,4F,94,A0,79,D1,CE,88,BA,2D,9F,6A,F4,35,ED,25,B3,FB,15,87,37,93,D4,3A,30,18,7F,23,49,14,E1,E9,0A,B4,76,F6,44,B6,8B,94,FE,05,15,AD,C0,34,22,DF,04,C3,08,DD,4C,C7,57,8E,75,F7,6E,A2,D6,B7,82,0B,41,0D,86,E1,6B,51,26,31,11,9E,57,65,7F,4A,B0,9C,D3,45,9B,FA,71,14,45,EE,D9,56,A1,20,76,66,1B,6E,25,89,26,08,88,83,73,B8,71,A6,6C,FA,26,19,85,CC,9D,B7,E0,75,D2,59,FC,A4,4C,65,F8,5A,A1,DF,9D,3D,AB,F4,29,8E,AB,95,44,EA,19,23,86,D9,7D,DF,3B,10,A7,17,3D,A4,29,35,FA,3B,13,B2,5D,E0,61,C4,B4,7D,86,4B,08,F1,48,3F,56,B7,08,5F,27,45,C1,46,32,A2,76,D2,40,4D,10,FC,91,F2,E3,08,3E,C6,A8,56,83,D3,1B,45,D7,93,82,3A,CE,D6,48,B5,69,29,62,A5,2B,64,76,DB,C4,86,0C,64,44,A8,7B,C5,02,42,40,BC,5A,FB,DE,60,52,2F,C9,19,CD,76,C6,8E,21,4E,DC,6F,05,2A,59,C7,F4,DE,3E,A1,44,3E,23,C5,46,48,52,00,45,AB,9B,15,89,A9,4F,1D,1B,40,B5,AE,D8,33,1D,D5,97,C7,EC,95,DD,38,19,F5,3B,6E,CE,B2,96,4F,62,F3,6F,DD,D2,01,5A,59,F4,BE,E3,70,07,71,1E,55,52,60,EC,9B,76,F4,8A,4E,B8,E2,F8,75,1E,D2,0D,19,22,69,F6,20,7D,02,1E,05,11,73,20,8D,3F,C1,9A,4D,8C,88,41,A3,D9,39,D9,E0,4E,C4,01,A1,D0,75,AC,2E,82,8F,12,B7,5F,16,99,41,AA,A0,5B,2A,2F,89,BC,F8,C5,49,23,36,35,F6,4F,28,FA,8D,EF,45,E9,EB,BD,E5,F8,96,2B,35,2F,B9,7C,43,AD,12,3F,34,49,62,5E,49,A6,D8,35,D9,97,E5,DA,2C,B3,5C,15,41,88,D9,33,83,F5,E5,97,97,13,B4,DD,38,A8,96,55,AB,71,4D,0E,B0,33,CA,23,94,E2,7B,CF,AB,5B,DD,92,0C,EA,B2,AC,E9,3C,43,3C,43,51,8F,BE,23,F4,99,29,E4,6E,5D,FB,32,21,31,5A,74,C0,CA,C5,F9,6D,9C,B3,ED,EC,F1,6D,2A,3D,56,A5,22,BC,73,2F,0C,5E,40,46,1C,F9,7B,D6,9A,C8,42,D2,E3,29,D3,73,BD,9A,92,6E,68,BA,3F,16,21,E0,9C,3C,FA,ED,B7,16,A8,4A,60,B7,EF,70,C5,2A,CD,1F,79,CE,74,C1,3D,7F,6D,5D,41,FC,9F,93,78,E5,F8,5E,48,68,5A,92,6D,4B,F3,12,D6,E4,7E,A8,92,0E,19,FC,58,80,C2,8C,97,B6,AA,45,F1,E0,10,0C,93,40,16,03,CC,51,B1,32,A2,52,D4,FA,D8,D1,CE,0F,DE,40,30,EF,73,14,FD,5B,47,C4,AF,65,EF,32,D3,0D,01,5D,D9,9C,F8,A6,55,4E,01,3F,35,B6,02,D0,16,27,8A,79,EB,F2,04,C5,9A,28,C4,E7,5D,A8,8E,E7,98,0D,96,7B,EB,2D,30,98,96,3D,05,F9,95,24,BF,80,90,8E,B6,B6,16,B9,1A,DD,D1,B7,40,63,9E,AB,DB,5C,02,92,36,60,E6,7D,EB,C8,83,1E,19,35,29,24,FF,21,F6,30,3D,CE,D7,B0,9C,40,E4,11,04,DD,5D,04,9A,5B,FE,AF,73,D5,C1,A7,6B,D5,D5,07,13,5B,57,41,1B,C5,5F,07,F0,06,5C,D6,76,21,37,86,62,32,15,16,FB,3E,56,53,37,85,C0,D4,88,F4,E4,6E,8D,C0,CC,60,D3,2C,9B,3D,1F,3F,FA,3E,E1,AB,5F,06,31,C3,72,CA,83,A3,2E,86,93,8B,22,96,2E,F9,F0,18,80,38,CE,87,02,9D,A7,18,F0,EB,33,AD,B9,7A,F4,D4,9A,23,D0,82,19,42,9A,C5,D1,81,AD,6F,E2,C0,B3,5A,FE,14,73,D3,91,C0,4E,27,38,25,40,FB,10,C8,B5,31,37,16,4C,3C,18,7B,74,BA,92,7A,31,AA,2B,69,C1,46,6B,5C,07,12,94,94,55,BF,FF,F0,0B,BF,9E,02,7F,9B,AE,2F,EC,67,A2,4D,C6,FD,00,C7,75,D4,61,99,0C,35,15,91,D4,16,DC,BC,35,A5,16,81,FE,0F,BC,52,07,CC,21,62,B8,86,16,0D,66,06,B3,CD,00,C3,0A,DD,DE,4D,A6,C3,BA,6F,5D,9A,56,65,B0,39,E9,6B,67,2D,D9,52,C9,02,49,EC,0D,F3,BE,EC,93,60,E2,F3,8A,85,68,EF,11,DE,BD,E7,09,C4,4B,A8,85,2A,9B,3F,EE,C9,4F,AE,66,2C,69,AE,78,43,C1,E4,F5,C5,FE,33,DA,C3,4A,58,2F,F4,40,71,22,3E,B5,FE,D6,59,32,DF,0D,72,10,3E,03,B8,B3,F5,B2,E9,0D,6F,39,A6,B8,9C,6E,BC,81,64,B7,1B,B0,4D,34,2F,F3,C0,16,0C,1B,53,7A,F2,97,03,7D,6A,33,D2,6D,7E,2A,1A,87,92,C8,D3,6D,52,5A,58,14,B5,31,71,68,21,EF,67,36,D3,4A,B5,B7,B3,21,32,DE,F5,30,E5,E7,19,A6,E8,B5,68,D1,D4,E7,57,CF,94,54,7D,4E,45,06,C7,67,E9,DC,B1,D0,67,BE,AF,7C,46,11,5D,38,97,88,83,87,E9,F3,E0,C2,47,AA,51,0D,1E,07,A4,45,DF,9D,3F,CF,F9,37,72,8F,F5,53,C0,24,C8,F2,4C,6F,62,32,C3,28,21,BE,A4,BA,94,91,CF,57,A6,76,53,3F,FD,F7,51,62,70,0A,B0,5C,E4,1B,56,3D,ED,39,C1,9C,6B,C3,9A,4E,64,FE,CC,6A,6E,BC,0A,47,BD,CA,99,5B,6A,15,07,8A,E7,D6,D8,C9,73,96,A5,20,67,37,67,82,28,41,05,F4,C5,A4,A0,0C,08,78,47,01,2E,B3,EF,13,ED,82,7D,62,77,36,CD,82,4B,49,E5,14,F5,18,63,73,A2,52,A6,0E,49,2B,9F,69,66,C8,E6,70,29,AB,3D,CC,8B,B8,78,69,65,B4,CF,C3,58,79,C1,B3,C9,42,B1,7B,D1,6C,1D,B0,8B,2F,27,88,1D,DC,96,5F,42,79,A3,C2,66,84,3F,DD,EB,8A,C9,E6,98,72,12,70,A5,39,8C,EA,D5,E3,EC,7E,63,02,51,F7,97,83,79,80,8B,FE,D5,78,94,0F,CC,AB,F7,68,86,24,15,C4,33,41,FE,29,F6,EF,79,D4,D4,48,D2,11,4C,FA,ED,D7,DE,42,38,B7,1B,0A,36,B1,4A,AA,1A,67,EF,D0,6E,86,27,BA,3B,95,57,83,4C,1F,9E,BE,3E,A1,53,F8,A0,8F,E4,20,65,CD,42,F7,D2,2C,46,53,03,7A,DC,EB,A9,B6,86,FF,22,04,40,06,A4,60,0D,E6,56,BC,AB,23,72,B4,97,B1,86,3F,5B,E8,BF,98,9F,F2,3B,83,83,BD,EE,BA,3C,57,1F,F9,A7,88,74,9A,BA,23,0F,5D,28,B7,52,75,D7,85,B3,A0,B4,08,86,17,A5,36,2B,01,99,E2,0C,56,87,2B,57,B1,58,ED,66,EB,A4,D4,7F,BC,44,40,56,92,E1,42,33,EE,78,58,69,21,C4,8A,AE,4D,FB,1E,8D,2C,CA,76,1E,A8,EA,3E,07,06,02,4B,30,DE,C5,4E,A2,DC,4F,3A,56,37,BF,D2,EC,92,AE,C2,F9,D4,8A,26,C9,5C,F8,F5,55,60,37,6D,4A,FA,5E,9F,5B,03,D5,4F,A1,8C,0C,EC,BB,5F,42,DC,F4,3C,5C,22,F8,9F,20,20,95,9D,ED,E2,80,07,4D,CD,38,9F,66,BB,70,C2,45,91,91,37,03,F8,B0,7C,4C,9E,38,D2,B2,D3,F6,C4,22,FB,C5,19,A3,EE,44,C9,7F,C2,95,2A,11,6C,A9,89,BA,65,6A,E1,2C,6D,2C,0E,04,0D,5F,02,6B,34,F5,1A,55,E5,27,DF,95,F4,26,66,AD,06,12,D6,C3,97,6C,F1,27,55,AB,B1,7F,2A,EF,27,D1,31,00,A6,2C,EF,B9,60,46,13,74,57,8E,60,3A,21,47,B5,4C,6D,93,FB,32,A0,F1,8C,12,D7,6C,C1,0D,73,23,96,88,2C,9F,46,C3,D8,6F,6E,12,41,89,55,99,6D,9A,A9,1D,7C,1C,D2,2A,82,69,DD,19,EE,4F,50,48,85,21,54,7E,F8,AB,94,D4,B4,1A,E4,5B,96,A4,2D,A2,12,04,E8,A6,6F,6C,11,85,98,00,45,61,55,4F,EB,91,1B,35,59,1D,7F,8E,64,CE,EA,E3,F1,F2,38,CB,BF,6E,4B,86,1E,AF,56,73,1D,ED,03,A3,7D,F7,B5,19,85,C6,4D,D1,88,DF,77,36,AE,98,71,42,BC,27,77,14,DD,8B,5D,FF,BE,25,66,C9,40,0D,68,E1,FB,E6,F5,07,43,E2,50,C8,E0,5A,C2,1B,D9,0C,9F,90,E4,6E,38,C2,8A,7E,73,F1,71,0E,C0,CE,C4,B3,84,BA,B3,F0,05,CA,8B,26,D6,E3,90,C3,EE,1E,93,8B,C0,9C,12,35,F6,D7,5C,85,19,DE,D8,6C,12,AD,99,A8,F3,AE,B2,B6,3C,9B,C1,96,50,5E,E2,8A,C8,61,97,8B,9A,29,E9,89,ED,56,5D,F8,BD,D8,FA,F4,AC,57,27,CC,E6,DB,FB,C9,F3,17,03,95,B2,9D,EE,BE,28,E3,25,F1,8A,E3,C9,E8,75,DE,D0,68,66,BB,9E,D6,DB,B6,A8,03,CD,1E,1F,42,67,88,49,1C,75,82,A3,A2,B6,FE,35,7C,63,EB,8E,BA,CB,75,59,3B,39,77,7A,85,35,6C,8D,E4,C1,D9,69,3D,F6,48,5C,02,F1,49,5F,EB,C0,0E,52,08,B9,E6,8F,7F,A7,19,AA,5C,DD,76,5D,CD,B4,4A,6C,54,91,7F,33,B0,36,D4,AA,42,CD,A1,24,BA,15,86,5D,27,BB,07,BA,65,4B,43,0F,C1,0B,13,ED,96,24,60,05,17,83,44,94,03,9F,8F,84,51,CE,BD,3C,EA,32,7C,83,52,62,2C,FF,D2,6E,15,EA,35,FB,69,D0,53,EE,99,05,43,08,49,D6,F8,3A,90,D8,FE,E6,62,B9,80,34,68,2F,2F,38,4C,63,D4,D0,8F,6F,65,EF,45,C8,55,CC,9C,45,EA,54,CB,13,CF,98,50,91,7C,8F,BD,BE,6A,50,2D,F6,05,ED,CD,39,17,1E,0F,63,C2,8F,04,C5,85,9B,58,17,4B,B5,FD,1E,E4,4E,DE,6A,EB,27,B4,FA,72,69,EA,42,8F,B0,A5,70,B2,CB,51,B7,1C,FB,2E,62,A6,58,BF,13,6A,83,C4,9B,FF,F5,20,A5,E5,20,61,50,EF,9E,CF,AF,1C,DE,20,80,41,1B,17,8E,9F,25,9A,17,01,BA,8A,52,C5,BF,B9,53,5B,D4,0A,C8,F0,53,A4,86,AC,25,31,C8,47,1D,DC,E3,C6,80,D3,8C,8F,56,B2,A6,B1,CB,DD,0D,A7,CE,BD,5F,17,30,64,5B,B9,92,D4,2C,EC,FD,C0,40,7D,A5,8B,42,CC,9E,A2,3D,5D,A4,5E,93,F6,BD,43,0E,FF,A2,D6,E2,0E,0C,77,85,F8,2A,A9,55,C9,B1,7B,05,AB,98,50,64,7C,4C,F6,76,64,BE,2C,C0,5B,C3,C6,E3,80,8F,54,41,3E,D1,64,80,2C,DC,9D,6F,08,35,83,F5,EC,25,D6,41,18,66,E1,AE,38,EC,76,16,C7,DD,91,CF,D3,AC,DB,ED,65,75,96,4C,C5,57,21,1A,AD,4D,72,6F,04,50,23,E9,E7,36,FB,D9,EF,30,FB,89,DD,B8,9D,D8,C0,07,7B,33,50,5C,E6,B0,BF,17,51,6C,57,32,08,FA,8C,AF,BC,85,AB,A5,C4,52,21,7A,D4,88,F0,BF,16,6F,2D,FF,11,6A,A5,A0,65,C4,DE,E3,A4,CC,B9,43,9C,76,13,81,86,3B,BF,8A,91,1C,B3,EC,16,DD,B1,9D,93,94,51,79,2F,3C,7C,F6,20,0C,3E,49,2A,8D,A4,15,ED,E0,D6,B6,39,4D,61,E1,3E,CD,FB,79,12,51,C5,B3,55,C1,9D,C5,A6,67,BE,C2,C1,3B,63,7F,7F,AB,5C,68,EA,5D,22,EC,E2,5F,DA,4E,66,4E,17,29,7B,70,15,9B,CD,17,82,AD,E8,ED,A2,F2,52,31,0E,83,66,52,E0,36,12,2C,3D,51,24,76,60,D9,B3,2D,14,9A,B4,76,30,78,27,C7,73,A1,3B,79,4A,5B,EB,BE,D9,1C,4A,25,F3,73,25,03,ED,60,68,79,7E,18,41,D3,FA,BE,92,3E,EE,7F,47,C3,95,9F,4D,45,95,EA,84,80,E8,14,36,18,E9,54,78,5F,D5,A2,A5,E6,84,09,7F,63,75,F1,04,B7,72,58,01,8B,CE,B8,23,9F,A0,0F,19,B5,29,90,BC,61,71,05,38,8A,6C,E1,05,C7,52,1E,1E,F5,A8,C3,37,47,15,F8,C2,B6,6B,E5,5E,64,30,E5,A6,C1,40,C4,95,E7,B0,3B,8C,D3,63,5A,55,E5,16,31,D7,B1,B9,30,E0,C3,54,07,8B,87,94,F3,B2,9C,9A,4A,92,33,18,88,DC,8A,35,3E,07,83,FA,59,EF,E7,33,9A,86,17,42,E2,19,EC,88,B1,D2,D0,F2,57,18,FE,61,F1,26,3C,49,08,67,D0,20,CA,B9,7A,E5,13,4E,5A,54,B6,27,67,2A,C8,0A,07,3A,36,B9,54,05,D5,5B,0F,06,78,25,7E,EF,BF,4D,1D,2D,5C,FC,4B,29,54,A4,41,4F,73,96,0B,24,06,2B,8C,15,FE,4C,2E,61,21,49,2F,06,D7,FC,95,E3,50,67,C2,50,B5,CF,64,D1,CA,EA,49,03,8F,BF,81,84,13,0B,30,76,A1,84,68,8D,1A,D2,B6,0B,7A,49,73,06,82,67,FF,B8,53,8A,09,11,87,1B,76,3C,03,D7,74,10,74,AE,1D,1D,BF,B1,CF,B2,4D,7F,95,DD,E4,37,B3,1D,48,27,4A,CD,43,A2,65,47,28,E5,D4,0F,03,CB,44,87,FA,9E,1A,AD,D5,DD,27,1D,EB,9A,FF,0E,C0,90,1A,60,67,29,39,D4,22,AE,41,27,D4,2D,85,B5,E5,E0,7D,5B,A6,6F,18,40,FF,3F,86,BF,B0,10,F8,53,09,30,16,1F,FB,31,FC,09,78,D7,92,BB,D2,37,1F,DE,7A,9E,D1,31,C6,DB,FD,2F,C0,6B,59,43,83,BF,4F,3A,65,88,11,58,4D,10,7F,7E,14,65,8E,A7,42,12,C0,FF,A4,D9,96,CD,15,50,10,61,66,87,E8,EC,50,23,90,EE,76,F8,C4,21,C5,0D,D4,F3,A5,DB,B3,EB,DD,31,DE,D9,15,49,C5,1D,78,9B,28,B4,E4,85,07,C8,4B,1C,33,70,E9,B9,A5,47,A1,0C,4F,EA,30,25,0F,26,1D,97,EC,63,E6,45,87,79,94,53,52,16,29,BB,F4,45,B2,98,94,F7,72,7D,70,E7,23,09,ED,FC,9A,49,68,E4,47,F2,F2,D9,AA,47,1F,B8,A8,DC,2D,F9,EE,F6,3B,1A,82,8D,CE,28,7D,AB,16,2E,59,4F,90,42,19,28,16,AD,56,38,7C,31,C7,F5,CD,CB,F1,2A,06,FA,91,78,D5,EC,68,F3,19,37,6A,05,E7,2C,72,1C,8B,7A,D4,FC,E3,28,A5,E4,8C,56,23,64,62,3B,76,0D,2A,95,CE,33,AC,8D,A2,A9,DE,B9,9C,69,FC,C8,0E,95,64,6C,F6,D8,C9,21,8A,A9,62,6F,13,E3,1B,73,15,5B,FE,41,12,D7,9C,D7,10,D0,E2,E3,2F,E3,4E,8B,90,90,6B,1F,10,A0,2B,ED,B8,6D,0C,6A,76,A7,18,8A,42,A3,25,4C,4E,7D,88,4F,C7,F6,BA,A9,42,0E,2D,2E,21,B6,C6,D1,4F,E3,32,3D,20,DC,4B,3F,EC,3C,CB,13,C2,74,DE,35,77,04,E0,CA,1E,A4,60,AF,5C,08,C8,F7,AA,47,55,A5,98,DC,59,3A,70,89,24,9A,0D,0A,EE,3E,8C,80,B4,F2,1A,B1,84,FC,39,E3,0C,03,A8,45,3E,72,E7,CA,4E,1E,35,C8,6F,0B,F4,A0,A6,00,13,AB,D3,63,6D,53,C4,99,77,DA,17,AB,69,75,9C,EB,A4,06,32,A1,66,77,77,63,0F,C4,91,02,19,2B,6A,70,84,95,88,0F,87,65,27,5B,24,60,B5,98,37,EA,3B,76,A1,03,06,99,FC,17,40,02,04,7C,1A,6E,54,7C,0B,72,61,66,81,07,EC,FE,19,21,55,E6,A7,1B,76,6E,B4,B8,F0,EB,82,93,6C,75,EC,89,B1,DE,1F,B8,9D,59,03,4C,6D,65,99,54,50,C1,C6,8C,7A,7E,E3,31,2F,E1,3C,1E,DF,EE,80,72,3A,BC,6D,EC,AC,79,0F,0A,DA,E8,62,25,8C,2B,15,C8,7F,D5,7B,E2,88,BC,C5,E9,26,C4,C7,88,A1,AB,72,35,75,44,F9,9B,4A,86,7A,93,84,66,79,77,D0,12,A2,F7,7B,27,19,A6,CB,D0,2C,EF,18,44,3A,52,1D,1C,63,E4,BA,8B,90,1F,AA,02,E5,3F,3B,BF,3A,A0,96,29,F4,5C,E2,89,D0,6F,50,C3,B9,EA,9B,E2,6A,F0,01,8B,58,1E,46,B9,09,D2,42,50,28,4D,18,19,FD,CD,8A,F8,F9,02,13,57,5E,43,4F,9C,96,25,EF,11,C3,5F,5F,D2,56,21,1F,C7,1F,49,56,15,25,D4,BD,69,DC,0B,6E,76,D2,46,7D,98,90,00,69,46,24,14,91,E8,50,8C,6A,A3,16,02,F6,7F,53,21,8C,F0,E2,23,14,72,54,75,43,5F,19,36,42,73,90,37,35,40,84,4F,DE,B4,BA,D7,FD,22,64,3B,8E,12,1C,16,09,18,E9,93,C7,D8,90,93,F2,98,46,5C,9E,73,30,6B,F4,F6,DA,BC,85,DE,07,9E,A6,92,53,57,C1,FF,DA,30,0B,A1,EB,19,34,96,74,20,DF,A1,5D,15,A7,A5,99,04,3D,A2,B5,36,AE,A4,84,F0,BA,00,2C,92,BA,2D,35,88,65,23,A7,9E,7F,71,2F,87,FC,90,45,4F,6E,6D,56,65,E7,17,EF,2D,67,32,7D,F3,7E,BE,24,93,05,07,2A,A9,45,80,EE,FF,5D,2C,47,F5,31,DB,CD,C6,C7,9D,25,83,7C,26,50,A6,42,6C,4D,79,06,5E,CB,1A,44,20,CA,AD,AC,BB,34,F0,70,52,DD,76,53,EE,CA,10,9A,0C,EA,FE,C7,59,67,E0,23,55,71,86,9C,75,98,40,4A,00,31,20,78,16,62,28,FC,6E,06,3F,C1,51,AE,71,F6,1A,A6,81,5C,31,7F,C1,3A,B1,EF,62,B4,F2,4B,55,C8,B6,BE,EA,D1,15,B1,BE,8C,D6,8E,4F,BA,4B,8A,01,97,A0,1B,74,5B,63,07,FB,39,70,5B,69,4F,64,F7,04,FE,22,C1,87,01,0C,A1,AF,97,9D,07,EF,58,AD,27,EC,87,52,4C,B1,E9,8E,C9,C3,4D,CF,A9,EE,15,B2,0C,B3,FB,51,61,5F,34,90,5F,B0,5A,25,6A,E1,97,B4,E9,E3,82,17,9E,A3,BD,18,88,81,3D,64,B4,AC,A9,90,60,74,02,CF,68,85,39,49,E7,4E,D3,43,09,1C,70,31,3B,5E,A9,13,8F,2B,45,F6,B5,DE,E6,3B,E0,33,10,3D,58,A5,01,37,3C,B6,D9,04,8E,E1,6A,48,3F,78,5C,BD,12,B3,2C,D1,C8,80,BC,88,A2,4C,22,3F,08,27,F3,F1,6A,C7,E9,38,E4,85,E6,D7,87,DD,42,50,56,6B,BC,A2,29,ED,F8,F9,D1,71,97,43,0E,94,20,0C,40,31,4F,08,94,44,F2,51,7D,23,80,9A,5D,44,DF,7E,2C,E8,58,2E,31,70,3D,08,AE,31,48,CA,8E,07,72,68,22,69,A7,11,84,F1,AB,5A,B3,99,79,69,9C,D4,3B,8D,A3,30,10,EB,D3,11,F3,3A,B9,51,2E,57,6C,7F,0B,96,23,B0,67,3D,75,7F,97,60,47,39,89,9B,2B,97,75,7C,C5,72,82,0C,73,A1,7F,DB,C8,48,93,43,86,04,ED,E5,72,07,D3,74,7B,EA,FE,F3,30,7A,D4,22,F4,E7,74,C1,E4,54,53,1A,AF,5F,F5,63,C0,F4,C8,B0,58,B9,90,44,30,F5,68,F8,F5,D5,13,21,65,F2,7A,13,E6,C5,4D,0B,3C,C5,5E,60,BE,0E,8E,0D,33,3C,1E,54,42,3E,2D,EB,4E,AE,5B,36,6B,D7,28,67,25,6F,11,99,BB,F8,E2,CA,FE,11,51,22,90,CF,58,41,82,AA,47,BA,B5,86,7D,17,9C,9A,9B,6A,D8,0F,BC,75,35,28,79,A7,8E,5A,65,F1,58,75,BF,37,B3,52,F6,5C,00,50,43,A1,AF,FB,E6,95,D2,AD,44,C4,4D,3E,A2,91,A0,F2,C1,C6,E9,14,A0,86,6A,39,B0,44,0E,91,3F,F3,F1,FE,BA,E4,DD,E2,74,C1,C1,C9,8A,E2,15,27,55,BD,F0,A5,D8,35,B9,5B,6C,57,B4,61,83,24,C9,62,C0,6A,42,E3,FE,D3,99,CD,ED,9C,DE,E2,7E,22,7B,FC,F6,20,68,B4,39,6B,14,37,3F,68,05,E5,65,D8,11,10,83,C3,44,37,67,05,49,BE,AF,AD,35,A2,B2,A3,C4,7B,60,BF,7E,5B,37,95,D1,F6,AE,97,42,21,29,3C,89,B9,E1,2C,C6,EA,F3,C3,D1,50,54,5A,83,95,22,AA,47,03,32,D8,00,F7,76,46,D4,C4,16,BD,80,14,1F,0B,8A,DA,D7,65,86,36,2D,F7,F1,1C,83,B0,FD,04,92,56,DA,F2,B9,62,E3,47,34,BD,52,24,D2,2B,2D,B9,F7,08,5E,60,3F,71,C2,CB,F8,35,C3,DE,DD,CF,9C,8A,4C,BD,43,DF,0B,46,87,F1,84,CC,F0,3A,B0,89,D5,D9,2C,E0,9E,FA,F5,EA,50,53,D6,26,12,B2,6A,D9,9A,87,47,A3,CA,24,7F,5D,AD,8B,42,F2,03,97,75,26,E6,EF,F2,9E,DF,6E,7A,B3,FA,74,D9,53,1C,40,8C,0F,6A,29,59,BC,ED,39,23,70,E2,19,5C,F0,39,0E,2C,4C,3B,06,4F,DA,BF,B3,F0,F2,64,48,E1,F3,ED,27,05,BC,CF,B3,6F,8A,0E,27,3F,DE,5C,13,F3,FF,A4,9B,89,3D,AA,FE,20,BA,AE,B0,78,79,A6,71,39,84,5E,00,6D,96,26,D6,26,8E,AD,D0,4B,30,97,2B,D8,79,4B,78,51,61,60,D2,60,5F,E0,DD,E7,21,8D,0F,F4,FF,D2,6C,DC,3E,B7,55,76,2E,61,B6,29,9B,96,BA,27,F4,7F,3E,2D,9E,65,1C,BD,66,DD,CE,42,28,B6,BE,E2,20,93,A3,74,C1,28,F6,C7,67,05,5F,2A,34,67,15,F1,F0,17,AC,66,AC,73,50,3C,B7,72,63,6D,A8,F7,B0,EB,B6,7E,7B,92,CA,33,C8,31,8C,A9,78,06,04,54,E4,99,BF,62,63,6D,5B,66,6A,F0,28,6F,94,A6,6B,BC,BB,3A,24,24,C0,32,80,A4,2A,DB,39,06,50,28,28,59,EB,7E,CD,8F,2C,58,D9,51,37,C8,F5,38,5B,3D,A3,D2,3E,BA,AE,E7,5B,F5,53,07,D3,F8,F6,8F,17,42,37,BC,3A,4A,7F,E7,5F,AF,CA,59,2B,E4,60,81,4B,8E,6D,60,14,9C,8E,4A,34,40,85,F3,50,C0,5A,62,4C,08,D8,27,D2,DA,8A,8D,44,B6,C6,95,6D,79,37,3C,EF,BF,3D,2A,FC,CA,77,29,4B,1F,26,0F,B7,C7,9E,3A,92,FB,EF,4B,6B,5E,0E,F1,5D,6E,13,8E,4C,0B,EB,DC,5A,CF,B5,A3,99,FB,87,39,05,75,08,4F,23,AE,EE,8C,37,3F,F0,8E,A8,2E,A3,FE,52,17,73,93,1F,D1,B2,11,55,A8,17,0E,57,C9,47,D1,AD,88,19,C7,64,F7,B8,7C,26,D6,DF,AC,DF,C3,B6,9D,1F,22,51,A0,4B,2D,83,DB,D0,C7,04,2C,CC,D6,F3,69,8F,6D,7A,08,2D,08,4E,F3,CC,25,52,10,D6,6C,0E,82,B5,83,B9,B1,71,02,E5,34,B2,FC,4A,65,2F,0B,78,28,F9,8C,98,DB,6B,0D,9F,F5,E1,EE,7A,24,C5,0A,C6,1B,E8,ED,2F,8C,10,45,E6,D1,9E,78,AF,BA,DA,FF,2C,06,02,77,05,60,45,E1,8D,8A,14,92,06,A1,65,A9,2A,B7,3E,F2,C5,DD,D1,A2,39,8C,85,27,05,7C,E9,5A,FA,BC,9E,F7,5C,20,B0,C6,2C,40,28,36,59,88,E5,00,1E,94,1C,BE,84,74,C9,33,7A,EA,E4,72,E0,BE,4E,34,29,BB,F5,D4,83,B4,04,E7,D2,2E,89,A0,1E,2B,5C,C9,9E,E1,E2,5D,FF,91,3D,7A,9F,BC,5F,0E,C9,5A,6A,DD,FD,C0,09,7E,5D,B4,D3,B3,63,4B,BE,ED,4D,C0,1E,DB,D9,DB,4A,EF,D7,58,2E,47,1B,F0,17,B6,D7,EB,DB,4C,E6,E3,20,28,39,42,32,1B,AE,81,1D,8E,E5,BA,21,71,A1,C6,8A,5F,73,78,50,F8,F4,63,E5,A7,BC,33,4A,87,BA,E4,43,18,55,D3,1C,35,CF,57,9A,53,B1,4E,64,72,8C,B8,AD,E5,EC,BE,49,F4,BA,69,66,D1,79,26,05,2D,F1,74,0F,51,4E,14,62,A3,69,07,7C,A5,61,70,8A,73,C0,AA,96,3B,A1,1E,D9,35,EF,62,CE,42,5F,5F,B2,FB,D4,F3,25,D7,D7,8E,D1,61,B5,3A,8B,E5,D5,17,51,42,7E,41,3C,A8,ED,6D,F4,69,01,7F,F5,F9,BF,2C,D4,44,91,98,15,6C,6C,43,89,AA,D6,B4,B6,0B,55,75,D5,8E,42,FC,88,AF,17,D7,0A,55,C7,19,16,F5,BD,9F,74,86,92,2A,F4,5F,F6,6D,A6,32,9E,81,50,0D,46,8D,66,D3,1C,54,37,94,91,30,5A,44,42,5B,34,52,89,97,2A,AA,56,1C,F2,42,15,9B,04,45,48,84,CE,7C,36,17,55,C7,CE,31,5E,1F,F1,88,A9,28,98,68,C0,15,82,F4,5C,8B,6E,96,B9,F3,2D,CF,77,DB,82,0E,AA,34,DA,11,BD,10,E7,67,ED,A9,B7,34,B4,EC,18,01,09,AE,18,DA,22,8E,05,5E,83,02,DB,0F,F4,6A,6C,E0,EF,52,67,48,02,BA,01,02,C5,0E,68,0F,66,DA,0C,A1,4A,7C,76,EB,EE,E3,65,E0,80,E9,A8,B9,CD,73,28,DE,05,C7,4E,BA,CA,3A,6B,C4,EE,F3,75,65,23,CE,12,2B,72,C0,8B,BF,D6,4E,6F,78,EA,8F,39,08,CF,C7,78,2C,D9,B7,49,C2,44,32,7A,32,F5,64,69,61,74,5F,59,DB,3B,78,1C,D8,FD,2A,07,22,DB,0B,D5,02,EA,8A,A6,7E,B9,5B,C6,0C,2D,A9,7B,F5,CE,EA,41,E0,4B,0D,21,29,A2,65,AA,12,DB,5E,33,91,A1,04,34,E5,C3,B5,3F,95,B8,09,7E,4A,94,C3,87,1A,E5,A6,06,C5,2A,F9,ED,73,0A,A5,BB,BF,AA,A9,C6,B1,F6,A3,10,46,35,0B,00,E1,7C,66,D3,36,F8,AE,17,C2,AD,FB,E6,14,B0,2F,69,9D,39,D5,8C,6A,46,F8,02,AC,7D,71,80,F4,C8,95,4D,66,B7,65,43,9A,BA,80,AF,74,3C,C0,CF,78,C7,6A,94,94,75,EF,A8,D3,E9,65,F6,4C,EC,70,EC,B5,22,67,31,D7,93,BC,9F,34,07,44,94,55,E1,6E,3F,55,DC,2C,79,60,D9,0E,98,15,A2,CE,AA,8A,13,D6,9E,7F,66,DE,01,60,A7,F5,D7,45,EB,58,E6,60,CB,C5,B5,53,5E,37,48,AB,8A,4A,BB,C5,78,C7,02,36,D1,A8,10,91,9E,D9,8D,1B,77,A6,CF,11,31,2E,C5,1E,60,64,30,1E,64,44,41,37,7B,9C,FD,E1,E1,09,19,B9,AF,EC,33,AF,24,41,D9,E4,B0,D3,97,21,5F,04,0D,E5,B5,12,B7,FF,BC,D1,2E,80,91,35,D4,D1,58,FA,51,44,60,E8,FB,9E,66,36,48,ED,0C,85,F0,0A,43,2D,CF,B7,5C,F1,B1,C3,94,45,25,25,B7,52,C0,A2,9E,B9,60,EB,80,0E,EB,AC,64,E0,E8,E1,11,E0,4C,A8,26,2E,E8,7C,CC,12,F9,3A,5B,59,23,98,35,2F,21,18,F7,9F,07,3D,73,88,6C,86,6C,E9,98,D0,E5,73,EF,0C,66,37,7B,CD,C9,F2,A3,06,45,B3,E2,B6,19,E3,71,71,C5,B7,E8,09,9C,54,1A,67,20,D2,E1,91,1B,2C,6B,4C,B3,49,6B,FF,EF,FC,3D,C1,2B,96,0E,27,75,C5,8A,87,3C,0B,95,82,18,E8,06,AC,76,08,57,C2,7F,86,F5,15,90,C9,C1,F6,BF,B0,04,9D,08,8A,5C,DC,DB,DD,2A,98,1A,99,7A,23,87,1C,9E,7C,4B,7D,31,80,0F,A7,EF,3C,A5,69,D4,D3,C7,B2,EF,10,C9,CF,14,C5,41,0C,A0,0F,CC,C1,6B,45,25,52,91,B1,90,0B,86,51,7A,A1,E5,CD,66,43,8B,89,18,76,02,1B,2C,A1,5B,93,08,B2,17,09,5D,91,78,1E,30,F2,48,55,75,AE,FB,CF,B1,68,FE,83,98,98,26,51,DC,8A,0B,86,FF,E2,80,A3,D6,E5,D5,F7,C6,25,12,5D,9F,2B,08,E8,A2,67,F6,D0,D6,FF,ED,69,04,39,6E,58,A0,9F,34,A5,43,1F,44,B5,61,00,66,A8,8E,55,EC,70,6D,0E,0D,76,DA,72,AB,76,6E,0E,46,89,65,7A,43,99,F1,9D,10,F3,EE,45,62,B4,5C,71,87,51,EE,A0,38,FC,69,CD,45,B8,9A,3C,05,B5,E0,7A,8B,B5,61,BC,04,92,EE,60,8B,E1,30,43,A6,F8,22,B2,05,39,F7,BA,3D,A4,A6,39,38,1A,7D,59,45,7A,88,5F,EC,16,C6,FB,3A,34,8E,22,D8,AC,45,0F,E0,A1,85,C7,24,3F,E1,70,E6,AC,74,B8,D5,6F,77,FF,27,1B,4F,5A,CC,6D,79,C5,40,6C,7A,B4,DB,FB,8E,3A,2A,28,21,9D,3E,1F,2D,38,B6,93,65,AA,7B,07,1F,78,8C,6C,3E,C0,28,EE,CC,94,A1,A5,5B,7D,15,5C,4F,84,59,08,3D,54,12,D0,2F,8A,F8,4E,9E,9F,E9,5F,32,9B,B7,40,26,A0,F8,1B,C9,F5,D2,39,0D,97,63,6B,DB,BB,58,94,AF,57,E6,D0,D8,74,A3,DE,84,F0,2D,EC,50,54,95,E4,99,19,0A,89,32,4E,55,96,D2,40,8D,3C,55,DE,CD,B9,FB,28,D1,2F,F2,26,D4,F0,B4,86,B3,5F,D8,F6,6A,F6,0C,64,AB,65,AF,7C,05,EF,AE,9A,09,2F,07,0B,27,20,AD,B3,06,7E,A3,6F,F3,22,D4,25,29,F6,0A,CE,B9,1E,8D,85,88,6C,A9,4B,0D,EB,39,98,E6,CF,6F,DA,8D,DB,44,48,6A,52,6E,50,7E,85,6F,F5,E3,31,24,74,A8,00,5C,34,4D,7B,00,77,D2,18,81,AF,81,A2,6D,20,A1,61,B9,94,69,C7,0D,F2,7A,60,9B,77,97,F9,95,0E,FE,AF,8E,BD,61,3E,E7,AD,57,45,74,72,C6,6F,B9,3B,5B,70,51,80,50,0A,4C,25,E3,CF,0A,67,3E,11,26,14,AB,D9,19,52,A8,F9,81,31,26,38,B8,6C,77,58,6D,D5,03,AB,BA,05,34,96,E8,57,0F,A6,AB,BB,8E,0D,6B,86,F6,4E,F6,29,81,EA,6B,F6,D9,89,0D,A2,0E,F3,93,EC,95,0C,87,61,69,C1,B7,E4,C5,01,DC,5A,09,8C,E0,64,41,2C,4D,48,E1,9F,39,9D,6C,C8,1A,5A,96,88,19,87,D9,A8,EE,67,08,83,2B,44,D3,C4,4D,D0,20,8B,0F,7C,40,B2,2B,7C,9D,A0,B7,93,CF,39,FA,33,CB,88,BA,7B,04,72,0F,DE,5C,2D,B7,A9,19,C3,D7,56,83,55,A0,10,22,45,ED,20,D4,74,B9,DD,6E,03,B5,EB,AD,45,DC,FA,B8,C9,98,50,25,5A,E6,39,3F,E2,FA,33,88,D2,F3,A5,4C,22,B6,58,4C,E6,B8,5E,D7,13,C2,4D,FE,69,0C,FA,9C,22,04,BD,8C,16,AE,0E,DE,00,21,1D,7B,9E,1B,A3,74,E9,C0,0F,17,BC,3F,F4,FA,9C,8F,F3,20,68,D4,11,47,CE,34,15,E2,7C,C6,68,AB,21,03,97,E0,0C,C0,25,6B,E0,FE,38,F3,40,34,DA,C4,92,B6,FF,6A,1E,B8,1C,74,98,DB,04,FE,29,31,01,BE,92,9C,FC,11,E1,3B,B5,2A,90,B7,7B,B7,42,F9,B8,9D,96,C5,80,11,48,B3,0E,E3,38,5F,55,6C,8A,68,76,58,54,04,66,97,45,77,64,0F,7E,3A,E9,D5,EE,3D,D0,AB,55,89,65,EA,CD,A4,B7,C7,AD,57,87,95,A5,5F,A4,E3,71,D3,33,2E,E7,8B,67,AD,91,FE,60,78,ED,5F,E1,0B,09,66,C6,BF,3A,95,F3,B0,52,B6,AF,52,D7,48,AC,5F,A2,5E,17,7D,14,E3,BC,09,98,C2,BE,27,26,30,13,49,31,78,83,9C,E6,8B,AF,2B,6E,9C,0F,78,FC,4C,F9,C0,EE,50,18,02,5C,33,56,18,63,A1,F9,8C,6E,26,00,73,CF,A7,B1,4C,6C,BC,10,99,86,B6,DD,E0,D9,E2,01,53,92,B6,18,98,2E,8E,65,66,8D,B2,92,50,00,A5,BB,78,55,5F,40,09,93,B0,92,8C,7B,65,FA,0D,B2,74,22,7F,79,42,9E,4B,C9,99,AB,0C,29,44,D9,AD,DC,24,D8,7C,B0,99,B2,47,27,FA,63,BE,C9,2B,67,55,98,C2,3B,26,01,D6,7A,70,AD,28,DF,4E,BC,20,49,D9,A1,58,3C,C1,FF,91,32,B1,F7,48,0C,BF,7D,39,97,BF,5F,B9,1F,8F,C8,2A,2F,BE,AA,E7,29,5C,02,C8,D0,60,29,AC,96,52,12,1D,E6,47,CB,70,68,5D,D9,86,D8,F8,5E,74,7E,5F,74,97,F0,B1,BC,DB,84,D3,04,D7,88,8D,51,67,2C,F9,C5,24,60,B5,D4,F0,3B,03,51,17,8E,A7,28,B9,41,79,9C,98,C5,B0,CA,39,58,2F,08,FD,0A,51,87,EE,D1,B3,8E,68,E8,F3,31,06,4D,B1,53,0A,6B,FC,29,F4,E0,5F,0A,85,1B,2B,76,77,B2,42,33,D7,5B,23,0D,9E,9A,DE,0C,D0,CC,CE,D1,CF,EF,0F,F2,3D,F3,DC,FB,1F,EF,4F,19,3C,21,48,98,16,07,B7,C9,A2,7A,47,EF,9D,95,E5,A8,63,D0,6A,58,97,74,1B,B9,68,CD,B9,F9,AF,D7,4D,AC,41,40,06,9E,CE,DB,50,8D,2F,FF,34,70,B2,D3,03,FE,76,86,F4,D4,D4,5E,D2,91,EF,42,D4,93,CA,F6,69,A0,A8,36,0F,FC,37,91,22,C5,97,F6,D4,59,C2,89,EF,C7,34,7F,4B,A9,88,80,06,EB,68,95,5F,A5,7B,52,43,0B,79,D0,3E,2B,1C,D3,A7,9D,19,D9,F4,EF,43,3F,CD,6A,63,27,4F,74,24,43,C7,6F,3C,44,49,21,76,31,03,D1,FB,8A,86,36,67,49,C5,6E,4C,11,42,33,B4,54,84,B2,8F,1A,63,76,32,07,47,25,C9,7C,07,CA,C7,9E,3D,E6,4B,9E,3F,2F,7D,52,E5,AE,AB,03,A6,05,6B,F4,12,1F,1A,08,C0,3F,05,E5,7D,03,32,EE,C6,39,2A,C1,DC,21,94,A0,87,81,67,99,69,EF,C6,BF,48,8C,8E,CE,BB,36,66,EC,A4,F2,E3,C0,8B,55,CD,1F,A4,A5,87,EE,CF,BF,9F,EA,0F,7D,F6,93,0E,0B,C7,59,74,54,29,36,BE,54,DE,97,58,14,E0,53,D8,C3,2C,BF,1F,90,0F,DB,BB,CD,94,27,2E,85,4B,3A,4E,0F,8E,AE,9D,A0,83,C9,A0,BA,98,BB,08,5C,89,62,0B,51,20,E6,D7,F6,64,D7,E1,DF,97,36,03,37,48,D6,04,31,CC,97,ED,DB,0F,1F,F0,F6,D7,8E,CC,A9,63,A7,BD,50,54,09,BF,CD,DC,B6,96,A7,2C,E2,A5,D4,1E,C7,4F,1B,AB,A6,32,E3,E4,C6,5C,D8,AB,E2,04,BE,52,3A,B6,45,6C,39,73,0F,C0,9E,70,91,F0,D8,8E,D4,AA,38,75,2E,40,77,B5,C8,37,73,EC,47,B8,9A,24,D6,AF,F1,B7,14,20,2F,FA,38,2B,8B,DB,5E,E5,C9,57,93,90,AF,89,D1,C1,9E,89,98,7F,3D,3C,6E,0B,FB,D1,20,E9,AF,46,DC,75,37,27,BC,E6,48,5E,EB,2E,57,AA,2B,7B,80,7B,0D,78,F9,95,F6,54,26,82,BA,B7,F2,AC,0B,BB,58,31,2C,2A,81,AD,A7,23,E7,3A,46,FE,BA,4E,2E,17,61,DC,74,26,41,0F,C3,DB,4C,FF,FC,61,4A,A6,06,90,C6,5A,AA,E3,FC,1A,D4,E3,7C,18,E1,80,A2,B0,07,DB,5A,C5,C0,54,64,FA,8D,07,C8,AC,2F,36,5A,F5,85,DD,20,C4,BA,F8,26,A8,52,0A,87,83,AD,AE,07,EE,26,E1,97,EE,4F,18,A6,4B,B8,32,1C,46,C3,1E,99,61,74,AB,0D,97,8C,12,FD,0A,42,62,F4,25,56,BE,B7,BE,EE,6A,8E,AA,28,A5,E3,8B,E3,A2,0F,C6,D5,A2,3A,81,6B,AF,46,57,32,2A,0C,49,BE,73,71,C7,A7,F1,DF,B8,6B,69,CD,51,65,B8,B9,24,62,71,C6,8B,09,30,2B,CE,F9,70,B8,EF,EA,3F,6A,A6,2E,9A,7C,36,E4,CC,1D,02,B3,BF,F6,6E,5C,40,A0,39,7E,D4,32,15,F6,BE,93,30,54,42,ED,A5,B9,44,E1,00,3D,14,54,9F,BD,1F,EE,DE,7B,9C,03,85,49,EF,B6,26,96,E9,2E,68,7B,A9,F4,A0,11,B7,81,C9,FC,96,3C,D1,CD,E6,D4,68,84,EF,EF,3A,29,01,C3,53,5E,99,53,82,7F,14,95,F9,88,F0,79,99,35,6E,A1,AA,07,E9,46,B9,49,AA,9D,9B,10,9B,92,8D,E0,9C,9D,80,A9,97,17,F6,B7,C7,F4,5C,D8,BC,44,75,9D,37,FB,7A,D4,15,66,30,8D,86,AD,38,E9,30,DC,78,84,E3,3F,D5,A2,99,5A,35,29,9F,E7,EC,25,05,36,30,FB,E3,9A,A2,C3,67,98,D7,6A,A5,92,0A,AB,9A,0B,A9,72,D8,DD,89,4B,63,D2,FC,74,B6,29,74,7C,BB,69,41,CD,71,E0,43,CF,6C,E2,C3,17,27,F5,DC,E1,B4,D6,48,12,01,AC,C6,28,71,FB,80,DB,64,CC,7A,3B,E1,07,AE,DF,C5,61,D5,D3,A4,39,7B,C3,98,DB,C5,4C,E3,50,71,48,11,B2,7E,08,D7,7F,32,A0,87,4A,17,AC,80,8B,AA,AC,68,12,BC,D2,37,ED,1C,90,02,E6,C2,EF,DF,50,BA,1B,B4,CE,46,7B,60,C0,73,2F,31,7C,D0,40,92,D4,AB,E0,22,7E,BE,50,5F,A3,64,E0,7F,D5,E9,C6,06,E9,45,B7,EB,36,4C,2B,64,B7,56,FC,ED,D8,72,58,5B,3B,BE,EA,87,36,CD,A6,CD,B4,E4,9F,34,9F,5F,24,CA,64,06,3E,75,69,F7,13,E3,F3,2A,09,DD,0B,0D,DE,42,F5,0F,1F,3D,8B,A1,7F,09,77,4B,E5,90,1E,7B,84,17,9B,C8,E3,5F,06,BB,87,33,0C,84,C5,E7,51,CE,A4,AA,4D,B6,61,5E,B0,DE,AC,36,D4,62,B8,8E,8B,67,7C,8A,4E,EF,39,C1,33,C6,3D,C6,5B,A3,87,C3,F1,43,52,41,8D,64,ED,9B,A0,4E,AD,02,81,E4,9E,32,C3,C9,B0,0A,C8,68,06,CD,44,C0,27,D6,26,9C,13,D2,76,61,FC,0E,C6,E5,84,48,C9,28,FA,4D,BA,9D,EA,FE,7A,DC,D9,07,1D,14,3B,C2,8D,68,F9,20,06,4A,79,89,E8,78,B3,B1,57,71,FB,59,9A,83,5C,F2,85,E9,10,DA,E3,96,0D,31,D7,B3,A6,F5,7C,4C,7E,A0,03,51,4F,D1,93,A8,A9,5A,70,67,48,CE,9A,6D,D3,B8,22,14,E7,40,83,16,8D,6B,21,53,E8,BC,71,DE,34,BF,D5,0D,96,FF,72,73,78,69,87,81,A0,9F,1C,38,93,E7,11,16,66,44,2C,85,5D,2D,79,DD,B7,69,26,DE,85,7C,09,5E,F2,C1,15,87,35,26,52,18,16,8D,03,80,F9,32,A1,AB,58,E5,A0,DD,54,C6,9F,35,8C,B2,3A,CF,68,3E,C3,1B,3D,65,01,5D,7C,D3,66,7A,4A,1D,A8,E3,EB,5F,70,E7,64,75,55,2B,39,BA,CE,91,22,09,0F,1F,BB,A3,2D,EE,22,C3,B2,9A,FC,1E,D8,14,8F,F3,8C,B7,85,92,7A,6A,E3,74,17,D9,CE,D8,5C,E9,04,C1,D1,D8,F8,B6,E3,D4,DF,3E,74,2A,73,24,78,1D,B4,CE,24,B3,4F,C5,BC,24,A9,26,2F,4E,E0,07,45,DB,8B,0D,CA,1F,CC,09,CD,5C,15,D2,FA,93,96,3C,4E,6B,0C,91,0E,3F,8B,6A,D3,EE,E7,31,6B,19,E1,80,E7,68,CC,E7,45,E3,FC,38,68,71,9D,67,B8,A6,BC,61,67,D2,EC,DB,B4,E2,27,F7,DC,06,71,71,F8,64,37,71,AE,B5,1C,9E,2C,F3,16,AE,5A,82,A2,DA,94,B4,1D,A2,A7,0B,14,32,69,12,1C,6B,2E,46,1E,A1,7B,D1,19,85,98,EF,F3,E8,7B,67,DE,56,EA,78,B5,C1,A7,4D,A8,63,47,55,36,F2,24,18,B0,7F,4D,F9,B5,9B,37,C5,6F,D8,56,40,E5,69,AD,AC,E6,BE,14,19,42,0B,FC,54,6E,BA,3E,91,83,60,9A,59,41,5D,9C,08,F7,25,F4,B7,45,C1,FF,83,6B,C8,09,6C,FD,D5,73,DF,1E,02,C7,74,4F,CD,DF,C8,48,0D,34,08,37,E4,46,C4,E0,2C,9F,BC,CC,E0,11,23,E7,37,F3,AF,E8,AE,2B,12,F3,8D,25,80,04,D6,F1,CF,83,D6,9D,DC,B2,68,05,28,CE,6E,CD,49,63,03,61,DA,A1,AB,73,15,4D,F4,06,04,B3,E9,84,21,9F,72,34,30,57,0F,58,D9,B6,C9,1E,5F,EE,40,4C,3E,AA,DC,EE,82,88,5F,8B,CE,7A,21,59,BE,A7,55,B9,FD,BA,4F,33,F7,5B,16,0D,50,FB,13,BB,68,BD,26,E6,09,15,CB,9F,BF,69,FC,E0,2F,40,FF,B8,B5,B2,B6,15,BA,32,E6,CD,84,F9,81,CE,ED,71,31,96,73,FD,8D,53,CB,6E,29,91,31,8A,BB,E2,30,75,D9,98,4C,6F,B6,78,D7,AD,BE,0B,CA,AB,6C,C3,CB,C5,17,9D,E3,05,92,1B,AC,4F,CD,1B,7F,6A,DC,45,BE,0A,78,CB,DA,02,ED,51,55,9C,15,F2,72,BF,C1,1D,B8,59,C8,1E,D9,7B,63,A0,35,54,56,35,96,AA,FA,8D,99,77,D5,D0,4A,D6,D1,4E,96,60,E4,13,A4,05,91,1A,CF,11,56,83,40,39,65,33,20,E3,F9,2D,8A,A9,83,4D,08,CB,A3,93,54,40,81,3B,AA,9D,B6,88,CF,F6,92,09,FF,AC,DF,90,0F,3B,54,3C,B7,2A,E9,42,34,53,E3,3B,0C,74,D6,BE,4F,73,33,4D,54,9B,0B,BC,EB,E6,F4,1F,8D,F5,0B,E5,9F,B6,57,4A,10,A3,A2,4D,09,70,D6,95,AC,4D,5E,B7,00,19,A1,91,8B,56,44,1F,DB,E7,23,86,80,73,04,9F,B2,53,BA,9F,CC,8F,A4,17,76,C3,D1,E6,C5,4E,F9,E5,6D,13,3C,09,C0,F3,07,CF,E3,48,96,55,28,75,53,9B,1C,A1,2E,13,2D,54,AB,D1,59,DB,25,48,C4,F6,C8,2B,C9,90,FA,3B,87,94,FE,E7,19,81,C2,6E,B8,39,E0,9A,5E,20,EA,F4,84,27,91,F6,34,73,95,FE,55,CC,36,D6,32,B1,A7,59,3A,9D,A1,B5,CA,2D,1A,6B,4D,9B,DE,D0,FC,CD,01,5B,C3,C5,9C,9F,65,F0,C5,1F,D4,80,5B,63,C0,CA,80,D0,98,C9,A8,AD,17,AC,FD,5F,3B,A4,59,B0,F5,86,2D,42,27,02,92,7D,82,07,00,DF,2C,BF,57,01,B0,22,76,2E,44,3C,E5,17,72,B6,01,E2,1E,B7,32,70,29,0C,FF,91,5C,6A,BB,D5,88,1F,72,65,AC,81,A5,97,D5,7B,9D,F7,90,40,55,33,07,39,28,1F,90,86,73,FD,E4,DF,A2,62,46,93,DF,81,49,CF,25,97,0D,91,7D,9F,AC,33,C6,1D,4F,40,33,AE,94,DA,4F,0E,90,65,43,54,DA,45,0A,41,8D,7B,F3,B4,70,B9,DD,F5,1A,B4,1E,53,28,25,10,2C,E4,F7,98,41,EE,FF,2C,50,4B,FE,08,A1,47,42,CA,A8,36,AF,B7,A2,2D,6C,07,2F,05,AD,4E,E6,FE,58,FC,5D,6E,53,41,90,4C,B6,D8,BA,E2,80,FB,E1,F4,B4,B4,8E,68,91,B0,B5,AE,4F,3C,59,2D,AA,FA,AF,3E,C5,13,8E,2E,C4,42,D2,D7,6C,1D,78,7E,F8,C0,36,46,72,9F,1F,04,36,41,59,E5,E7,62,8F,72,CD,5A,F4,6B,37,99,E2,E8,D6,05,18,23,41,3A,B3,D9,38,8C,D0,AB,62,C2,4E,48,BA,54,25,8F,51,B8,16,68,C7,C3,F1,B5,AB,EE,2E,2C,52,3B,0C,45,10,76,92,AB,CD,5C,2C,9F,78,06,51,78,DA,3F,AF,E8,D0,E1,B0,7E,8B,8A,91,FC,1A,90,20,E0,47,A5,E0,E3,4E,44,63,F3,59,82,80,CB,6E,86,A0,A6,08,C9,D4,84,22,FE,F4,79,23,48,B1,D0,6A,0D,49,98,4D,FF,9E,98,AB,0F,FF,9E,E6,CB,16,F1,15,2D,BC,17,5D,50,77,8F,A3,62,82,13,B4,3C,16,D2,1C,E6,40,82,8B,EF,A6,FC,54,6F,8A,6C,4A,3B,0A,CC,17,F8,F7,F6,81,23,AC,A5,23,25,80,A9,DB,02,5D,FF,4E,45,C7,27,E7,B9,E5,09,19,1D,5F,BC,2B,47,62,36,63,D2,66,40,E5,92,8A,0D,E0,AB,7B,CD,29,6A,C5,E4,18,9A,B9,C1,56,A2,89,42,51,C1,B7,1F,68,30,9C,53,93,AD,41,98,B3,76,E3,01,3B,6F,89,75,A2,9C,A8,61,26,6A,27,57,B1,C1,42,4F,E0,08,80,13,60,17,D7,50,2B,67,DF,CA,CE,E1,E9,DB,A7,F5,C9,08,79,CA,31,46,E4,9E,A3,E1,E6,CF,7A,88,40,6B,8B,48,F3,1A,72,21,7A,BC,A9,74,6B,3E,FA,9B,14,2E,2D,A2,09,50,C9,19,E7,77,32,BE,3D,62,57,B1,39,1F,98,24,9E,D3,89,FE,52,76,E7,11,82,66,1B,D2,71,91,1B,89,8C,8E,FE,92,62,56,F5,54,49,4A,1D,62,B5,65,C4,32,2D,59,5C,BE,C5,94,B6,5C,1C,98,EF,1A,DF,69,63,5C,E8,30,EB,41,DC,0D,BC,2A,B1,17,D4,4A,1D,42,36,FD,62,C2,CD,31,BD,A5,FE,1D,23,52,E2,3D,53,9B,3B,7C,A2,26,20,CA,B6,E2,5E,F8,E7,F5,07,62,BC,5F,FD,1A,E7,55,89,71,1F,43,BE,8A,E1,AC,48,74,61,83,5A,9A,14,31,63,25,17,65,F6,2A,07,DE,14,41,CC,50,16,EB,65,BE,D1,28,94,41,8C,52,63,19,75,57,E9,9C,67,97,0F,FA,82,AD,E1,3B,F3,94,23,18,07,5E,28,3B,A8,58,A2,BB,C3,56,A6,FB,85,35,43,47,40,B0,25,9A,88,3D,C0,FB,7F,39,A8,67,3C,14,AE,85,7A,89,41,8F,21,80,E2,44,05,E4,48,83,3F,E2,68,3C,FD,6A,AC,3D,7D,AC,0B,FA,44,C4,3C,85,1F,55,C9,F0,62,31,B7,9B,43,C3,D5,91,F6,BE,D3,4C,EA,A1,05,70,85,1C,49,59,20,6B,3A,42,1A,20,C6,CD,BB,03,08,17,66,F7,C7,24,28,93,8D,4F,3E,BA,6C,95,CF,DE,40,84,68,3E,53,14,F9,E6,E1,A5,71,66,DA,F2,F2,3D,AF,CA,63,9C,2B,B4,10,FA,84,75,AA,B2,FF,EE,0A,77,97,0C,D9,EE,37,76,F7,66,44,B8,7E,32,D0,5D,F9,0C,91,93,97,7D,F9,72,D6,D9,6F,21,9E,A3,21,A0,94,FA,22,D2,DC,1D,8B,EC,6F,F1,4C,14,C2,3C,03,94,BD,37,2E,48,AA,C1,EB,73,83,47,7C,ED,37,33,48,4B,55,2D,03,ED,75,4D,DF,44,45,FA,D1,BA,41,9B,69,A2,CC,AF,B9,A1,75,07,CC,57,BF,1E,BD,AD,45,6E,1D,B5,B8,46,7D,67,F5,3D,D4,C6,BE,D4,9F,C8,BD,51,5B,F8,7E,9C,24,48,55,53,93,A2,12,76,3C,B5,F4,2B,85,C4,6C,47,20,04,B0,83,E8,21,2C,F6,4D,74,29,19,93,99,56,16,40,36,BC,36,47,A6,87,69,EF,14,23,3E,1B,F9,C9,F8,ED,20,E6,10,17,96,2B,67,05,85,CD,51,30,07,CD,C5,4D,3D,A1,C4,FF,71,68,D0,BF,49,BF,B8,51,4F,FF,84,23,5F,85,E2,0A,24,41,C8,31,5D,68,C7,E8,F5,AC,2E,11,4F,E4,B9,7E,CF,F9,4B,D9,47,D6,56,C4,77,66,FF,4B,29,6F,73,3B,81,0F,F2,3E,4D,17,22,DE,FE,5C,20,F5,4B,30,31,1A,F2,44,B1,76,DB,58,FB,24,6F,D8,BB,C2,BB,9D,B7,0E,43,C4,C7,F2,4C,E1,2D,A9,04,17,24,BD,D7,F1,63,91,BF,77,22,CA,1C,1D,FE,B2,14,A5,FA,DC,D5,99,EB,9C,4C,7D,95,87,C0,13,52,E0,32,97,77,5E,72,BE,0F,5C,DF,FF,B6,0F,A7,88,E9,68,95,DB,A3,04,02,A4,5C,FC,35,E5,2E,BC,A3,30,C1,18,FC,20,DC,C8,28,61,BE,09,E2,3E,F4,5A,DE,E1,E6,7A,72,77,E5,FC,B2,92,D7,0D,04,A7,31,C7,A6,F0,D8,F6,03,51,88,3C,4D,F0,9B,5F,1C,E2,E0,44,A8,D0,5D,5E,93,39,D4,A6,20,76,D4,BB,16,8D,21,CE,66,9B,2E,12,E0,A7,52,30,DE,CA,71,12,D8,2D,B3,D5,24,B8,A5,1C,3D,41,49,7D,6B,D3,43,AC,6D,5D,AD,F4,CD,81,19,3C,D8,35,13,EC,D3,6C,CE,31,F2,C3,C1,54,A9,E8,E3,A8,7C,36,CF,2D,2C,99,BC,23,69,CD,8C,CB,3E,0F,AF,E1,F1,CF,90,10,06,8F,11,7E,04,E0,51,16,86,B9,ED,FD,3E,B8,B6,91,51,CF,EE,4F,A2,ED,33,EF,2A,32,CC,95,90,FF,D1,9E,7F,1A,2F,47,E2,47,CB,F2,12,2E,30,1A,44,8A,0B,8B,A4,DF,DF,22,9E,C2,98,D5,9A,A5,B9,FC,A2,E4,CE,B2,3F,A6,43,45,3D,58,21,58,89,58,CB,5B,7B,D1,BB,C7,80,A7,81,2D,48,D1,12,E7,51,83,54,D2,2E,87,ED,4D,8C,4E,EA,49,95,7C,07,46,CF,8F,B1,E9,C3,6D,55,6D,A6,5B,CA,7E,D6,68,B6,16,2D,DC,65,1C,0E,60,75,E2,76,B9,03,38,FA,94,F8,E9,91,BC,9C,90,1E,AE,FE,91,83,1C,48,EA,42,F8,E5,A7,A2,36,90,72,38,8A,A9,28,64,D5,CA,B0,61,1B,D0,CF,10,BA,2D,C7,2D,69,50,36,F1,87,DC,89,EB,C0,75,AE,E6,89,04,D7,16,59,7A,74,75,F1,E2,8E,77,D0,34,E3,5D,57,3C,3A,FE,F7,EA,00,39,C5,1F,09,E3,1B,3A,78,D9,51,ED,87,7D,87,DD,F4,94,1E,38,AC,06,9A,F6,63,9E,D2,50,9D,2E,76,7C,E0,32,B2,60,6C,44,6F,A0,62,FE,24,8F,C6,CD,04,52,64,34,84,C2,62,99,BE,E8,D8,2F,82,DF,B0,02,0E,35,25,18,DE,91,05,0A,8B,CB,56,04,D9,CD,C0,51,B5,26,80,73,C3,D8,B2,6E,43,89,CF,9B,82,7A,2B,D8,87,21,7F,95,32,F2,64,B8,CE,20,E3,E4,B0,F1,A9,0F,B2,7D,45,CB,85,78,B1,A7,F5,89,80,22,40,DB,CA,D2,59,E9,32,87,BF,9E,26,A5,7E,41,DD,0F,3D,D8,99,5B,BD,EC,E3,D5,AE,7D,48,BA,C0,84,DB,81,10,0E,F1,FE,F3,6D,0B,79,28,38,1C,E8,0C,2A,AE,01,91,53,50,AC,98,F9,3E,41,C6,19,90,53,81,4E,E4,A9,2A,82,BE,27,C2,0F,41,3A,53,C0,D5,2C,91,5B,72,8E,2E,85,23,16,CF,04,84,8F,AB,8F,73,1C,83,F6,EA,B0,3B,CD,A0,F7,2E,92,C8,57,E0,CF,9E,31,86,F6,CD,67,46,BB,E8,06,70,1D,E3,94,1F,AE,E5,27,42,DC,F5,41,6D,75,92,31,33,A6,0C,33,33,CB,48,10,62,3B,A8,2A,F8,9E,9D,5F,04,19,16,63,94,08,67,CD,AB,01,B9,46,3E,4F,EC,03,07,54,EC,4E,E7,56,7E,01,C1,51,3E,4F,E9,73,46,5B,BA,09,F8,F0,51,D2,CB,C0,36,A5,0F,E7,82,6A,EC,3F,04,2F,16,7C,FB,CD,7F,2F,7E,2F,E3,64,AF,98,CB,0C,33,0A,05,B3,BD,2D,DF,4B,5B,B2,DB,43,5B,14,47,CB,57,AC,6A,E0,A0,A9,29,CE,31,71,73,44,D0,E2,BC,62,1D,14,52,E1,F5,F0,04,E3,00,12,57,8A,61,7F,0C,4B,91,43,43,33,13,54,3C,45,0E,4E,10,0C,1E,EA,FA,72,FC,31,C6,F7,73,7B,6A,B5,E8,90,EE,D7,94,DE,69,2D,5C,64,55,8D,EE,9B,44,E3,BF,59,BE,F0,E4,D8,A5,14,E9,18,0F,05,13,D0,48,02,ED,7D,E2,43,CE,C2,D1,CB,A2,58,E1,B8,96,80,3D,DB,DF,27,61,40,CC,41,A3,B2,4F,CB,B6,D2,07,5D,87,11,D9,B1,19,9B,66,62,7C,18,CB,40,DF,43,49,A4,90,0C,CA,ED,40,3D,A2,A3,2D,B6,4B,20,29,12,24,18,B0,6B,14,CE,E6,67,B6,E8,4E,67,56,3D,1D,06,BA,73,0C,87,94,10,DB,A9,81,62,97,00,C4,8E,3B,6F,55,75,B2,3D,FC,37,EA,AC,92,18,C1,E0,AB,97,F0,F2,9D,74,59,7F,6A,99,42,9C,B0,89,35,E5,33,1E,09,0A,E4,1D,27,FC,CB,56,CB,D1,47,3B,C1,D8,59,1C,13,4E,2C,E3,B5,69,81,6D,8E,67,0C,83,CB,FD,25,4D,B3,52,EC,6F,37,83,DE,20,0C,03,DF,B4,37,90,24,94,D2,02,DA,EB,C3,FD,30,2F,73,CB,17,84,C1,F8,D7,0D,45,ED,94,16,41,7B,2E,16,0D,48,94,AC,88,50,D2,3F,B4,17,F3,76,16,22,D6,C0,EE,17,B9,16,21,BC,F3,17,C2,B7,61,6A,49,3B,9E,8C,70,4E,75,B9,0F,EC,54,CC,F4,AD,46,96,F8,E3,D0,66,09,15,04,75,A5,84,EE,77,4E,D4,62,4A,2D,0D,D1,0E,82,79,DE,E1,01,06,C7,2B,A8,6F,17,39,54,E5,28,C3,4E,B5,93,19,78,15,95,3B,3D,84,8D,AB,E3,52,11,E2,25,18,2A,ED,C4,C1,01,34,0D,7C,D1,6B,A8,19,18,AD,BA,45,03,39,B8,F4,56,2F,F8,23,9D,F1,5D,94,3D,C6,D9,DC,F1,8F,21,39,28,FE,B8,99,BD,C6,B1,B1,2A,E6,89,2E,7A,AD,93,61,F5,7C,17,97,77,6E,98,0B,62,D5,28,FF,DA,1A,20,3F,98,32,FE,B7,D6,22,E4,92,4D,D1,5E,C1,00,B1,A2,75,03,A6,CC,C7,6C,20,9D,AF,F2,F0,22,81,0C,E9,FE,BD,08,70,30,B9,BC,76,53,E6,F1,7E,2F,5D,1A,96,41,93,91,9B,8F,B5,9F,79,43,83,05,7E,97,2B,A9,A5,08,D3,57,78,58,EF,86,72,AE,AD,EF,85,39,14,C9,36,27,96,1D,CD,F9,20,7B,1F,6B,A8,25,2D,D1,EB,91,91,D1,44,8B,AD,42,AF,F6,C2,51,79,04,05,69,B4,6C,DB,E2,07,50,88,16,E8,10,74,CE,36,09,93,4E,AB,9C,BF,F7,ED,AF,CA,1F,FA,F0,D5,2B,94,75,B8,95,6E,12,A6,7E,F7,E7,A7,E6,92,18,F5,79,28,A0,E8,4C,8E,CC,AC,E9,37,4B,0B,AD,F0,57,C5,A4,F7,B3,E1,C0,E6,15,5A,D7,F1,2E,4E,D9,46,16,B7,6B,34,82,23,5E,43,68,45,C3,2E,93,EC,6C,7D,DF,DF,8C,D5,04,2F,F9,A9,A7,C1,32,F9,09,2B,FB,60,F8,BE,A5,E7,F9,D9,AB,26,F3,1A,60,2E,DB,FA,4B,80,CD,23,FC,C8,5B,F7,EF,AC,7A,39,B5,8C,D7,FF,A2,B2,28,B2,29,0B,CB,50,CD,47,55,9C,C1,7D,FE,72,F6,F6,BC,E9,B3,13,1A,5A,3B,45,A0,4A,39,87,BB,85,48,E9,16,CA,FF,B8,C8,E9,DD,0D,E9,09,B6,CB,67,03,0B,DB,A2,C3,FE,47,4D,46,95,BD,3B,72,58,F1,D8,BE,C1,41,93,CB,0A,01,3B,E3,1D,53,A6,78,09,30,37,27,AE,DF,95,BC,18,3B,53,A9,F8,92,23,A1,95,37,A8,C6,0B,88,4F,93,B8,73,F4,E9,D1,9D,0D,CC,01,87,A2,88,2F,D3,8F,59,BB,A8,5F,7C,1C,99,E3,4C,A7,69,CE,E3,E2,07,E6,F4,02,16,58,01,E7,6D,99,91,54,ED,52,72,FC,7D,E2,1B,1E,D5,C2,55,62,13,76,A7,26,76,3B,4A,53,00,A3,5E,8F,62,DA,33,82,4C,CC,4F,D7,A0,89,30,90,93,C9,89,E4,0A,E7,E4,2B,12,25,AC,82,0E,E4,FB,5B,0F,6D,F3,D9,FF,39,CE,EF,02,9C,1D,09,91,F3,08,FA,AA,62,55,61,49,F9,0F,E5,0D,0E,28,DE,E4,69,33,5E,D5,7B,6D,53,85,F6,DF,E9,7E,B5,71,6B,3F,CE,B7,B3,8B,03,70,23,94,CF,5E,82,99,B6,FF,ED,41,1E,20,37,F9,AD,0B,0C,CE,DB,A9,E3,44,09,2B,86,64,E1,07,F5,6E,38,B3,55,81,6C,49,8B,06,32,66,5C,FE,9F,AD,27,3B,2B,AC,38,CF,59,96,45,C9,3B,53,68,89,03,5A,D8,8E,83,BD,B1,6A,78,63,35,DD,6C,69,A3,1C,0E,0C,03,E6,FF,46,9B,8C,53,35,57,00,47,9C,6C,CA,4F,C4,C2,AB,5E,C8,92,05,22,F3,1F,91,3F,64,37,49,05,C8,FF,A5,7C,97,B5,EB,B0,1A,8C,49,9B,C5,DF,96,B1,41,EF,D2,1A,8A,79,6A,D9,60,DF,57,93,C1,E1,BC,B8,FC,BC,8B,75,0A,04,98,DB,FE,E5,DC,02,5B,7C,EA,27,99,53,AB,41,FC,0A,64,44,8A,A2,3A,E1,F5,DB,C2,90,64,4E,1F,6D,30,E1,71,C2,1C,5B,52,54,2A,16,B9,7C,40,B5,91,C7,4E,84,00,77,77,D8,B6,AE,4E,B5,E9,83,0F,15,30,D8,B1,5D,16,A9,B6,09,C7,E7,96,00,33,5E,8F,56,7F,CD,F8,49,06,BE,F3,BA,D1,47,E5,FC,4A,91,6A,0A,C4,45,76,9A,06,70,D1,5B,C2,1F,3F,C2,4E,19,E7,2E,D8,B8,83,E7,3D,4B,B8,1A,7B,8F,1A,8F,97,BB,CB,F7,2D,4D,AC,97,7A,C7,EE,AD,31,72,94,48,98,EB,27,4D,A8,00,68,02,44,B1,1E,F2,25,3A,53,70,BC,FD,F6,63,92,EA,31,2F,C5,6A,35,39,33,6F,4F,8C,29,CF,61,4F,05,DF,1B,44,91,3C,D1,0F,D7,B6,9F,15,0C,9F,62,0C,EF,D7,F8,F8,D6,EE,A7,A2,78,EE,DB,B9,1D,6E,9C,B3,46,5A,DB,43,6E,1F,FC,7B,98,0C,51,99,D4,BF,3C,96,C8,F0,40,D1,CF,29,88,88,F2,4E,6F,FD,3F,53,C6,58,79,E9,7E,80,20,87,96,A6,CC,C0,CB,08,BF,87,E8,77,5D,A0,6F,61,A2,46,67,76,87,8C,BA,DB,14,52,2A,6D,7B,68,DF,98,E5,E9,3F,46,B6,0E,85,FF,76,95,75,D3,51,14,8B,7B,F3,C7,99,C0,F7,DB,91,C3,1E,58,1E,7F,78,88,43,E4,CC,B0,57,8C,A2,76,55,B2,D5,23,AB,03,1A,DA,29,59,E9,99,92,A9,0E,61,C9,E9,23,81,2C,6D,67,16,3E,F4,B3,EE,CB,6D,E7,01,36,35,65,3A,AD,E4,BF,0D,AE,53,08,13,74,EB,C1,5C,02,59,07,57,4C,2D,1D,35,AC,09,73,00,35,A0,F6,FE,A4,BC,D2,F1,2B,52,23,49,E6,36,29,7C,A4,C9,49,09,46,27,86,90,A4,79,10,BF,66,50,C3,5B,2A,5A,1A,D8,44,FC,D7,05,58,1A,09,8D,D6,34,62,49,28,CF,91,5C,0F,8E,DC,EA,BB,BA,1D,FD,3F,11,9A,CA,8C,50,A6,CF,5B,BD,26,E5,16,E3,4B,78,81,CF,A3,F5,5A,17,15,1D,36,90,7C,EB,8A,EF,59,4B,E0,CE,83,7D,54,F1,C8,BF,16,BC,2D,1F,85,A3,AF,77,D9,11,72,AE,D3,01,72,52,64,DD,07,F5,29,2D,39,50,8D,A2,EA,3B,EB,3A,E7,B3,9E,49,00,93,F4,7B,BA,07,EC,F1,6F,65,22,DE,47,26,35,7B,DC,DE,0A,B4,FB,F5,0C,81,DE,6F,7E,54,6A,BA,D7,FB,CA,89,14,01,D1,11,12,E2,7B,1F,00,DB,DE,1C,CD,2E,5B,89,CE,F7,E1,75,CE,A2,24,D7,B2,0A,B0,18,71,44,21,5C,1E,09,E1,5F,68,30,E1,94,1D,E6,78,0D,30,18,9F,20,08,FF,62,E4,EE,87,A4,1F,95,FF,72,0F,91,5E,DE,25,41,3D,44,8B,A4,AE,4C,C2,BF,F1,EF,8D,C3,01,F6,26,CB,EC,54,D7,C6,5A,BF,67,4E,09,BE,53,11,E9,58,8A,74,BC,EF,A2,6C,17,21,31,83,87,CC,6A,82,AD,ED,C6,3E,F9,B4,B8,F7,92,C5,56,11,CF,EE,20,8B,B8,F7,6B,46,C3,A4,61,45,EC,84,EA,E0,76,48,91,13,9E,3A,45,2F,C5,3A,C5,E5,88,74,E9,29,C3,9A,CB,30,61,5A,4E,79,BA,60,91,C6,D8,97,47,A7,35,10,08,69,49,29,82,0F,4B,95,3D,78,3B,98,2D,F3,0A,05,7B,D1,CD,BA,4C,9A,FF,1C,C9,79,04,36,D4,EA,C0,6E,96,87,2A,98,D4,0F,FE,34,F3,45,6B,51,E5,E1,F9,D1,24,DC,43,F5,13,CC,F4,10,1A,96,B1,4C,C7,F4,B7,10,15,D1,E8,6A,A4,D2,5E,42,C2,F0,09,47,02,7D,26,B7,A4,77,90,D4,52,D4,2F,78,26,02,9E,97,3E,1A,89,1B,2B,87,EE,F0,41,28,2E,F7,0D,D7,2C,B7,B1,9C,D2,37,FE,00,57,B2,90,DF,C8,96,C3,39,E7,47,3E,C5,3A,25,3F,A9,83,CA,24,1B,66,F2,42,3A,43,D3,80,95,3A,62,2D,F0,2E,AA,50,25,A6,A7,77,4A,BF,2A,78,FA,CC,BA,7E,A7,A8,C8,31,7D,CA,86,18,50,1B,45,A0,3A,D3,EC,E6,8F,32,80,67,77,67,0F,E4,05,0D,F1,03,74,07,B6,8B,6E,96,AD,43,5D,7C,61,36,FD,8F,7D,1C,BD,A5,6A,E7,06,AA,57,6B,BF,8C,60,E9,73,10,5A,A2,DE,8D,C1,80,10,57,83,41,3C,E0,9C,70,A9,B2,DB,43,7E,91,A1,CD,62,C4,6C,69,41,70,30,9A,B8,19,94,EF,DD,0A,AD,3D,99,51,88,40,EA,02,43,B4,3B,17,0A,8A,8B,CB,2E,FB,37,34,D6,95,E6,37,4A,69,3E,BB,0D,ED,2F,CC,C1,CD,22,3B,1B,DE,0F,51,47,34,DE,AD,A8,03,BC,B1,D0,C4,61,71,A0,4C,B5,9F,C0,AD,E7,09,5B,AD,A0,F5,E0,EA,43,B9,54,2B,27,3C,5B,03,B9,AE,D3,DA,40,64,6C,BC,A9,DA,6D,FD,12,23,D4,5C,B6,5E,F1,63,1F,DC,17,0B,66,B8,21,01,86,19,86,D0,1C,55,96,70,9D,97,42,05,73,B2,65,AF,AA,BD,8A,97,58,0B,E7,26,0A,3E,BF,17,6C,57,98,91,9C,2D,BA,E4,24,85,73,AF,94,0E,A2,F3,9E,11,72,9C,F6,97,04,6E,55,D1,7C,F8,58,FE,A8,E2,5F,9D,B9,0E,B4,E6,76,1D,4A,55,0D,24,DC,5F,E4,1E,3D,6F,27,5F,2C,8F,56,46,BA,1D,63,54,01,3B,88,2A,2B,BC,97,2B,6A,F0,FB,3D,08,E0,6F,77,D6,1F,A9,0A,68,D2,8B,85,6C,82,85,75,BB,81,DC,05,4C,01,FE,F1,4C,74,F7,E3,93,5F,30,3B,75,F0,BA,6B,BD,6B,32,D3,8B,51,2D,44,93,32,1A,A1,2B,20,93,CD,AC,23,0E,35,5B,1B,0C,6B,E0,2F,C7,84,B6,EC,5C,89,CC,50,D1,D0,96,34,D4,11,57,BB,63,23,B6,08,F9,A2,35,01,D2,C8,D2,A0,15,0D,F0,04,E4,37,46,DF,E1,49,43,58,95,C1,F3,C3,77,C5,C8,05,5E,77,81,9B,55,80,59,80,AA,1E,F5,BA,F4,99,AC,17,B8,6D,E2,D4,5F,C4,AB,0D,59,6B,4B,3C,67,23,15,3A,30,BA,D3,1F,4B,43,DE,04,3B,1D,C0,C6,0C,F0,40,4F,65,4C,DE,17,83,BD,8F,AE,19,33,8E,7D,9F,9E,13,90,AD,20,5E,6D,6D,AD,00,0F,FD,B6,80,FC,DF,C1,49,9F,BF,29,58,8D,CE,E3,3A,94,93,5E,35,3E,B2,63,41,BA,7C,77,F8,97,AD,E9,E6,9D,EF,82,7B,FA,A4,62,69,3F,D3,46,83,80,D5,C1,1C,0C,E2,48,0C,2B,E8,DB,E1,F3,1F,B7,60,BE,3D,2E,FD,68,28,32,94,D2,2F,FC,0F,9E,CA,6F,F6,C1,15,89,A0,FB,D1,74,9D,73,EB,BB,2D,A6,ED,4E,DB,73,28,C6,5B,4D,59,81,A2,39,FD,20,D2,B6,DB,AA,F6,F7,61,B6,7D,1E,8B,ED,52,59,CB,7D,28,70,94,CF,64,99,F2,C1,F1,D0,56,4E,E4,05,FF,16,08,81,EE,94,63,22,7A,3E,7B,8A,96,82,B2,7E,0C,FA,48,BC,CD,53,B9,35,2B,C4,CE,D2,AB,E2,2B,20,53,67,96,3D,42,51,B0,54,14,97,9B,1A,6B,49,62,2B,CA,D9,89,DC,E2,47,85,F6,CE,84,B3,E4,5C,23,9A,A8,17,E1,00,FD,A2,4C,71,9D,A3,CB,52,68,74,C3,B0,11,AF,67,38,83,68,08,A7,C5,35,0F,74,7E,27,11,6E,BE,6F,84,28,82,9C,95,6B,97,BF,BA,79,F0,26,F9,8A,92,C8,62,07,E3,DD,08,B6,31,57,65,5B,58,85,FC,05,60,78,2B,29,7F,0F,31,E5,EB,BF,6E,85,79,E9,5A,EC,09,22,70,CC,37,89,C5,21,3B,E0,3A,E2,E6,F6,60,93,76,75,B8,B8,1E,DD,F6,A4,E9,25,20,50,88,F4,42,79,19,BC,7C,74,07,FD,3D,95,99,AA,DE,17,8D,A4,90,93,D2,85,61,A2,70,6A,8C,C2,24,05,F0,D0,52,09,95,DC,E3,2E,07,76,71,6C,89,EA,6A,88,DD,93,B4,CA,2D,43,65,B5,1F,E8,2C,94,1B,5D,5C,E5,05,8A,E4,4C,E5,F4,8F,6E,B7,C0,8B,9D,B5,4E,0B,36,27,6C,34,EB,F4,9A,0F,8F,87,6E,D6,FE,87,4D,41,9E,89,29,48,66,DD,D7,49,FB,AF,51,79,00,60,B3,E8,0C,0A,D9,9E,2A,21,E9,EF,70,0D,03,99,A9,F5,7A,92,BD,E9,D4,3B,A8,E5,79,B3,05,7F,3F,BC,7E,88,18,A4,DF,98,99,78,B4,FE,26,C4,B4,D0,AF,7D,7A,58,9D,FC,7D,40,FB,A4,12,48,1D,6A,36,0D,11,D4,41,2D,52,9F,21,E9,E7,62,BC,96,0D,0F,0D,52,24,65,80,0E,9F,49,7F,47,31,94,2A,A3,DF,65,8B,B5,96,E0,D0,94,BD,C4,18,87,C0,33,B9,98,6E,9B,5D,58,93,BA,CF,52,5D,44,7C,E5,47,FC,1A,FC,4C,87,E6,D3,83,E5,83,F3,89,FD,D9,A7,6A,B6,E8,BB,5B,FE,AD,18,BD,5C,16,90,BB,27,E5,EB,0D,01,EA,2B,9E,93,6C,06,91,1D,AF,89,FC,D2,F5,DF,6B,C9,23,32,17,75,EE,1F,F1,B6,0F,15,A1,DF,8E,4D,4D,78,1E,2D,A2,13,44,D3,48,BC,F9,A3,1E,70,AF,A0,B6,CC,29,76,61,3C,8E,28,09,8F,B2,F4,18,47,F0,3F,6B,3A,2D,98,12,CE,2C,E3,E3,8D,91,AA,97,E9,4D,A5,4B,8B,96,16,85,72,BD,A3,EA,D4,44,2B,89,D0,4F,FF,1C,6D,5D,CC,35,AE,9D,62,EE,17,E6,A6,98,C8,5A,AE,99,9E,C4,EF,1E,78,DC,7D,58,B1,64,04,9E,A8,D5,D4,75,29,F4,92,92,FA,17,48,ED,47,E0,A2,8C,8E,CE,A4,C7,29,54,C7,3B,78,E7,EA,BA,36,43,83,39,48,A7,0F,7D,79,D5,B6,28,12,EC,4B,70,83,9D,91,25,53,EA,96,C1,A8,84,30,58,5A,11,B1,78,BA,CE,BF,A0,8E,27,29,6E,CD,14,23,32,7F,B2,53,3E,21,10,75,C6,D1,7D,B9,F0,B2,0F,9E,D1,31,58,B6,01,58,2F,1F,A1,A6,3F,0C,E6,12,B4,96,E3,83,B1,66,7B,99,FE,18,20,15,5D,1B,5F,5F,0C,E9,1D,E0,40,D1,66,87,07,23,E9,D2,1B,93,98,0C,04,2D,42,1B,46,EF,6C,3D,E1,41,1F,49,30,ED,D7,71,C8,75,69,61,B0,F8,2B,BB,C6,4D,7D,E7,61,25,AF,F6,B1,F3,9F,E7,EB,54,B6,DA,0F,1F,54,EA,7E,65,0D,D2,D6,BA,C1,77,8B,13,10,E2,56,02,6F,93,0C,8A,E5,39,0E,69,64,48,E8,92,66,3D,7B,A4,A1,18,84,7C,9E,1F,93,58,78,A7,E6,C3,F0,CD,07,7C,64,CC,98,B7,1F,D6,B8,FD,73,1D,F9,74,87,E0,3B,F1,01,7C,06,2C,8E,0A,99,9B,5C,4B,DC,18,9E,5D,7A,BC,C4,5F,F1,3F,3C,65,95,2E,5F,BB,97,11,0F,8B,45,4D,0D,0A,BD,81,5A,D2,B2,0D,4A,39,5E,95,6C,AA,7A,1E,83,97,02,68,8B,09,2D,B1,92,B6,BD,58,A1,04,28,EE,07,3A,7D,6F,6E,7A,66,BB,92,35,FB,36,9A,2A,49,2F,A4,3E,69,8C,96,15,05,34,35,07,B5,B8,78,F3,E6,79,2F,24,3C,CD,05,02,CD,21,78,CF,87,28,C7,06,35,E7,7B,D9,73,C9,45,5C,6A,BD,BA,1D,BD,43,D9,79,79,3D,8D,66,F7,6C,E4,D5,99,51,BD,26,EA,56,C4,08,9D,90,FE,8B,98,CC,6B,F4,ED,D6,57,C1,69,2F,75,71,9B,70,19,A9,BA,1C,0B,12,CE,71,19,D1,B8,50,EA,28,B2,33,9F,7E,73,7F,AA,7A,82,B4,9E,2C,D5,2C,1E,2B,2E,15,46,0F,23,E3,5C,D8,E8,FB,1D,98,66,57,90,E9,EF,76,EE,59,0D,BC,EF,8C,3D,F3,01,13,63,C5,C3,34,DB,39,C6,0E,8E,07,8B,C0,FC,26,C9,51,1A,36,50,85,E4,E3,2A,36,A7,E0,A2,A3,B3,A8,05,49,F2,A0,F6,52,C1,77,EC,E2,30,EF,4A,59,85,D8,E4,50,52,1C,F8,D9,94,03,04,F0,16,8A,3B,C4,20,A4,B3,E6,47,CA,72,ED,6D,09,19,F8,70,6B,CE,64,34,13,A6,F6,D6,A8,DB,35,54,EC,88,58,CC,72,3A,61,C3,2E,12,3B,54,A2,E6,CE,3C,7B,E0,A5,71,68,E9,7C,5D,4E,1D,5B,D6,0E,99,20,FD,47,00,29,2B,BE,60,C4,43,48,E3,A9,DD,DD,10,39,68,E5,51,84,8A,88,18,5B,80,7F,7E,2D,86,6A,AD,CD,55,C2,3E,D8,AA,E1,02,B1,30,B9,3E,FA,3F,E3,C0,C6,20,AD,63,5C,0D,5C,0C,65,EB,F1,DD,40,68,37,82,1B,8D,FB,99,54,3A,02,A2,9D,3D,23,40,54,E4,B1,C0,17,83,42,EB,18,26,88,65,37,AF,F3,CD,D8,FA,06,34,10,CE,7A,84,AD,E2,40,65,CB,47,D4,40,B7,C2,2E,27,E4,DC,5B,13,DD,D6,D3,25,79,AD,72,99,AA,28,7E,AC,58,C5,E0,04,11,AA,1B,8C,8B,28,CF,2D,B9,DC,FE,80,F7,7B,AD,BF,23,39,AE,91,3E,CA,B3,0B,C8,8A,BC,00,8F,CC,DE,16,BB,94,C1,B6,4A,65,8A,D4,63,11,F3,5D,8A,DA,8B,1B,82,AB,EE,65,3E,90,81,45,73,25,CE,89,37,3E,75,02,F5,16,E3,67,06,3C,E6,B2,08,E5,65,EE,5B,B3,4E,AA,CA,81,65,83,D5,E1,CD,1A,04,41,66,58,77,54,95,7B,DB,98,B9,90,EE,84,F0,A5,03,52,1E,B3,27,23,EA,23,C3,3A,60,65,E1,43,59,4E,93,95,42,3D,A3,C2,A3,86,BF,1D,6C,27,DE,9B,3E,45,C6,FE,9B,07,6D,6F,F9,B4,D7,4B,EE,90,CA,77,29,BA,41,BB,70,F7,00,59,A2,7C,50,BD,25,0E,4F,2B,DA,A4,BB,85,34,33,AF,24,59,99,D4,75,90,85,CF,0D,C8,D3,BD,AB,7C,41,C6,C4,12,E7,60,03,8F,7A,5D,67,AB,7F,3E,A0,0D,A6,DF,C0,34,FC,48,1D,32,B7,0E,6A,50,64,24,01,86,5F,2F,02,E3,93,9D,09,BB,B0,23,78,68,A4,C9,4A,14,1B,D2,DF,0B,08,AC,C5,7B,26,11,FF,0A,EE,DD,23,FB,D1,5B,75,6E,91,16,57,0C,4C,21,A5,D9,65,D9,B0,5E,5A,7A,EE,49,88,C9,66,39,D7,BB,8D,77,7F,75,EB,D0,99,AF,DB,B5,74,58,6F,9F,44,08,46,FC,2F,22,3D,02,13,8B,0B,C5,F2,7F,F9,C8,EB,C8,01,65,D2,C0,E9,36,B7,4B,D2,32,12,A6,5E,C5,0F,4B,24,89,C7,99,31,6A,C1,1D,06,BB,B1,15,CB,5E,5C,33,66,5D,88,9B,6C,2B,D9,96,96,58,CC,B1,D5,42,50,4C,D0,43,5A,07,6C,F9,E6,F7,C2,D1,32,7B,E1,F6,09,DE,FB,AB,3C,D6,36,06,63,0C,2D,61,2D,65,93,15,1D,5D,23,6B,62,57,37,3F,0F,6E,35,C7,F5,2C,95,54,94,F4,40,70,57,03,A6,A3,A8,DD,18,FB,B0,04,61,4D,92,DB,75,32,BC,CD,95,E9,D4,4A,1D,4C,9D,C9,8B,E0,2B,A4,64,8D,78,B2,49,0A,DD,18,61,1D,52,A9,8B,20,04,8F,EA,98,90,7A,9F,FD,87,F4,FE,13,0A,B0,E3,6C,FA,18,E7,97,9B,CF,63,1A,BC,FC,F2,A1,0E,03,54,F2,0A,B0,DF,0A,6F,9A,D9,0F,88,46,64,FF,64,75,67,2C,42,41,98,6C,27,92,3C,93,3F,E5,93,52,74,D7,DA,A0,AA,2C,7C,6C,FD,B6,3A,AA,CB,BA,4F,53,01,6A,E5,BA,D4,94,76,08,E5,A1,25,01,D7,D1,43,8E,49,79,18,A2,52,A3,44,DC,57,12,54,24,08,89,18,3B,58,7F,C0,00,41,15,9C,29,3E,C8,3A,4E,AA,77,08,14,09,06,80,B0,3E,1F,9A,5B,99,B7,A2,A4,FE,02,6D,AA,BE,CC,88,28,25,94,99,7A,E5,7A,42,9E,C8,F9,DE,48,7E,8A,E2,39,A6,BC,C8,F8,1F,CF,1B,BE,9C,DD,83,A8,C7,73,80,2F,FF,E0,4C,93,88,20,7F,04,AA,71,17,AE,0A,EE,2C,56,22,EA,B5,E4,1D,3E,3E,6F,AD,9D,EB,B4,33,DB,BB,D0,66,E2,24,FE,69,15,E2,AD,FE,86,68,89,60,B6,B9,EE,E5,61,0B,2F,3D,15,6C,15,C8,86,FD,9B,8F,D9,7C,F2,2C,E6,C5,C3,27,7F,92,F1,EF,2A,29,A3,96,01,1C,7F,9B,8D,D7,D0,51,1F,49,FF,9B,66,1A,B7,AF,C4,BF,14,74,5D,A8,E7,C9,D3,9A,CB,9C,C6,FF,60,A2,42,1D,12,1E,1C,E0,BE,9D,AB,AD,40,ED,E2,AA,C4,AA,D1,6B,E5,E7,C8,EF,2A,6D,D4,C3,2A,61,4F,7C,B9,3B,A6,FF,29,44,7A,EB,3E,58,46,AB,E5,0C,D3,55,EC,0E,5A,3E,35,F5,04,03,5A,7B,61,91,79,D0,83,C3,E1,E8,77,E0,13,D5,66,D9,AA,00,1A,04,AD,C2,B2,30,E9,EF,EB,7F,D5,87,23,87,62,0D,41,B8,BE,6C,14,07,FF,5F,28,31,DA,34,78,B2,B9,93,39,36,7F,A9,FC,AB,C0,43,F5,20,76,36,D0,24,4D,1A,71,D2,F9,69,57,90,66,02,E7,BA,13,6C,C6,1C,E0,57,53,EB,47,B8,B3,0F,83,7D,0E,FD,5F,35,06,D4,78,85,4B,EF,1C,23,CE,C9,69,1F,12,C3,9D,7E,2B,B9,B9,E9,2B,B1,42,58,5B,53,5C,8D,6C,F5,81,5C,1D,38,B5,A9,39,9D,D8,F3,FD,78,57,C0,CD,74,7C,8C,D2,73,44,9B,A0,E4,8D,7D,AB,A0,17,E4,89,D9,FF,68,8F,73,40,33,AE,EA,57,8A,27,05,A2,84,10,2F,F4,1F,6A,5E,E5,F6,11,BD,69,55,49,98,42,F8,58,23,2D,60,87,F5,F3,28,38,AC,1D,49,21,AE,DC,E7,2B,17,39,47,5E,59,18,55,BE,F5,29,94,F1,B5,26,B1,93,48,1C,65,8C,0D,34,F6,60,B4,36,32,D1,9B,CB,27,8B,59,10,A9,97,A1,D1,7F,E1,28,CA,C6,8A,94,A0,F0,55,71,8D,1C,F9,41,FD,07,FC,FC,97,1E,4F,25,AD,EB,4A,39,E3,63,B2,45,E7,D6,35,9E,73,4E,0F,19,0E,D2,66,39,C3,50,7F,68,E7,89,76,D0,41,BC,D2,05,BF,8F,51,03,72,C6,65,B0,E3,5A,82,D6,BA,E8,C3,32,5E,D5,CC,58,D7,C8,DD,94,23,55,8E,09,BB,5F,DB,73,E2,C8,28,81,C7,67,C1,5B,A6,49,1C,C5,CA,98,9D,C6,FF,DF,78,E0,0B,E0,A0,B7,FD,22,1D,CD,0F,BE,2F,76,6C,2C,1B,3C,0D,C5,8A,22,8D,FB,3A,4E,3A,60,13,D3,13,35,75,EC,38,10,B3,13,E1,7D,1A,E4,30,51,9B,B1,84,1F,F4,BB,02,0E,10,C6,41,00,32,3F,16,5E,A1,3E,6B,E3,E7,4C,34,17,83,09,7C,B0,97,B9,40,69,EB,97,B0,44,6B,2B,FA,7D,29,47,7E,14,5C,A6,02,10,74,89,5D,0B,CC,6C,7E,55,97,61,6E,A7,EE,49,78,10,D2,52,B5,24,B2,F4,FA,E6,88,A0,B8,B3,F1,13,F7,7A,50,B4,DA,64,E9,95,71,74,86,CC,AA,66,74,5D,EA,C1,D0,56,0B,3C,98,19,DC,66,71,23,51,EC,D0,8C,13,9A,74,3E,35,ED,ED,E1,8B,47,4E,F8,EE,C7,BD,05,F5,C4,FB,B3,4E,3A,49,64,5D,B9,5B,4B,F5,D6,89,EC,15,46,8E,11,B4,02,73,FC,FA,DD,0D,D6,2D,F6,5D,61,3F,24,FF,FB,3C,51,22,BD,28,B0,ED,33,24,16,23,60,07,A0,77,66,B0,64,EA,D2,CE,37,FE,E9,33,90,1C,3D,92,EB,E9,8E,23,55,DA,81,2E,76,3E,65,85,0B,B5,BA,0A,50,33,A3,78,B6,F2,ED,7E,DC,D3,78,F6,1C,F5,57,D2,00,A7,9A,2B,24,AD,7B,A9,77,40,DC,6F,30,A6,DB,1D,8C,51,D6,96,91,1C,D0,E2,F4,BC,68,16,36,90,4A,7B,20,C7,33,38,AC,9F,8E,9A,47,F6,91,3D,2D,07,0B,96,40,5C,1D,94,21,2C,F8,71,85,A4,C4,CE,69,F3,F6,A8,23,A5,49,5D,45,81,EC,60,55,8B,67,2B,36,A3,17,F0,3A,52,AC,B5,B4,BB,BF,10,8B,9F,2C,B0,62,3E,ED,57,8B,F9,1C,17,9B,A8,1A,A2,F2,AC,6C,D5,2E,D5,16,B1,BB,22,32,A5,D0,D8,4B,0A,BE,21,4A,A1,C6,70,BF,88,C2,6E,8F,70,98,D3,F1,94,40,09,07,51,35,45,E7,49,2D,A3,7A,A5,DE,9C,FC,D2,5D,94,A3,29,0D,C8,1F,9A,AD,51,1C,EC,2B,0B,74,2C,E9,8E,7C,E0,CE,15,7F,5E,E9,30,5C,1C,63,3B,F6,7E,00,67,95,36,22,E2,FB,92,20,A0,4C,88,CA,20,04,06,19,9F,81,B7,03,9D,85,08,13,1C,B4,04,7E,63,FD,5C,EB,3F,BC,36,FD,5B,45,6F,72,DC,8D,72,FB,33,5E,E2,7E,04,05,6E,52,C3,16,5B,38,15,8E,5C,07,DA,09,F7,42,62,CC,B8,60,45,BC,C0,9D,62,D3,75,C7,87,4A,F1,13,A2,31,17,F1,4E,C1,70,06,A3,4E,19,7A,A5,36,68,F5,57,9B,AB,DE,56,6B,12,51,DE,9F,09,9F,C2,E5,FC,03,D4,82,59,00,5F,DB,69,CF,6A,93,DE,F9,64,CA,C0,FC,97,40,BA,6C,EF,16,15,92,F9,88,B4,0F,D3,BF,E5,DE,AA,C0,68,0E,C7,72,D4,FE,1F,E6,C5,0B,50,87,2B,21,EC,27,F3,E1,A0,24,96,69,8B,5E,5C,3E,EC,DB,89,FB,EC,C3,E3,AD,57,64,6C,E4,D9,53,4C,B5,37,49,F0,BB,30,D7,5C,68,44,3A,ED,FA,D5,8E,33,76,0F,6B,AF,D7,20,E3,25,17,58,52,36,10,77,83,63,E3,BA,DE,E6,49,17,7A,D5,3B,A5,0C,96,8F,D4,34,85,06,27,81,6C,E4,F4,98,6F,AA,E8,4A,89,B7,B9,7B,7E,2E,0C,AB,26,24,B4,13,F9,2D,30,14,2A,7E,21,27,E1,01,19,65,65,3B,6C,E7,25,29,18,A2,31,2E,2F,63,E1,42,24,A8,78,C0,53,8C,0C,17,9A,D0,2B,C9,66,6B,92,E1,2A,EF,11,EA,4F,01,84,3C,D8,6A,2F,4A,08,D7,92,F7,C5,AA,D9,7D,DD,C9,97,70,C2,5A,6D,97,D9,87,63,3A,BF,C5,83,B4,02,16,7D,D0,84,5E,47,B2,76,05,A0,F4,FE,6C,A9,74,05,25,AB,B6,9A,13,AB,DB,BD,FC,29,22,F6,B5,8F,45,32,BA,5D,BB,79,7B,2A,C6,8C,49,4A,53,06,E5,7B,6F,04,95,A8,EA,54,9F,A3,44,71,FE,E4,1F,FF,0C,99,C0,F6,AC,9F,50,0A,2E,B6,F8,B1,E9,42,59,FA,8E,E0,FD,68,0C,1F,C9,44,09,26,58,B1,4D,E4,5A,FC,7B,50,AB,0E,45,75,33,DB,E9,F7,5F,01,A8,45,F8,A1,74,DB,44,1D,C0,50,0B,03,DB,5C,D3,2A,B1,3C,E0,9A,74,61,8B,C0,6D,C2,C8,9B,07,6A,C3,CA,41,B1,71,AF,E0,39,9E,8F,41,26,CA,25,2C,F6,78,CA,AE,C5,70,7A,47,F2,9C,AE,7C,F1,C1,2B,61,8C,23,1B,B4,DF,82,0D,45,C8,B0,9F,5C,B9,DF,5E,A6,06,EE,ED,AF,37,01,25,FA,86,8A,10,0B,6D,DC,61,6F,1F,EC,0E,2E,0C,19,E9,31,50,38,4C,60,8C,D2,EE,9E,20,7D,29,08,EA,E8,80,CC,22,40,A7,B8,B8,2F,E1,0A,BB,9C,E7,AB,1C,E3,37,AC,C5,7A,E9,3D,46,E8,77,92,72,CD,87,00,ED,82,94,EE,57,0B,9E,33,03,B7,93,81,96,29,45,DB,19,87,C4,D4,C2,F8,4B,1D,CC,E0,E3,79,1C,2D,02,7B,67,F3,BE,14,CB,8F,8E,DF,F9,8D,4F,A7,D6,F2,D9,73,1B,3C,20,B2,4B,CA,C1,36,64,AF,99,37,4B,E8,1E,37,45,ED,F3,A8,3E,F9,09,21,3C,9D,C6,6C,A5,2B,A7,34,D2,1E,F6,AB,7E,50,5E,F8,9C,4B,85,FB,33,08,21,FD,77,17,02,EC,00,0B,36,20,83,9C,86,4A,57,B5,E7,B0,23,9D,37,55,77,27,65,EE,FA,3D,B5,3F,B1,F0,AE,A2,7B,A6,D9,38,3B,AF,36,5F,8A,E6,07,E7,A2,81,77,9E,E2,BA,4E,7D,D7,09,EE,34,64,FE,07,0A,30,F8,8C,AC,0E,5E,7C,F4,A4,04,FD,83,74,6E,AF,FB,02,CC,FD,55,B9,09,F7,EF,52,69,27,6E,3C,2A,0B,90,5C,6A,23,75,2C,B4,15,CC,FE,B5,81,2C,54,3C,AE,54,33,63,03,24,AC,3F,94,A6,0B,A1,26,E7,9B,42,42,0B,5F,7B,81,82,9C,07,A6,5C,FD,B2,82,96,13,2E,FE,20,BB,73,88,AE,66,31,B1,8E,17,AB,AF,3A,C8,F8,9F,10,B6,80,FE,FE,8E,C5,5E,F6,90,8F,B3,E5,13,03,B5,9F,68,0D,7E,47,7F,A9,0D,7A,FA,40,4A,68,88,15,51,F3,B8,5D,57,FB,FE,91,6E,46,B3,79,80,21,63,02,AB,AF,CD,94,2A,53,44,E6,3D,70,FF,1C,16,A9,B4,9F,D3,BB,BC,A0,F8,00,06,5F,1D,E6,E3,80,2D,F1,31,A1,BA,90,10,D5,7D,98,B3,43,AE,6E,C1,3D,37,20,70,C9,6E,A8,33,6B,9B,23,AD,CB,80,DC,62,F5,5D,88,E0,DC,4D,3E,E5,BA,2C,46,53,6F,EE,AC,B9,3A,EE,63,FD,2F,20,24,06,87,D9,23,38,3B,04,B1,F2,06,3F,C6,18,90,C2,43,8D,CF,49,79,9C,CA,EA,93,AC,02,3D,B0,CE,B8,C4,E4,B2,74,F3,85,BC,DC,21,AD,F5,4A,9F,89,1B,68,97,8D,B4,D8,8A,C3,25,3D,8D,9D,D6,C5,3B,62,2B,4C,76,28,BB,C0,FA,21,71,9B,5E,69,81,F9,7F,B9,10,A9,09,94,14,C2,55,D8,7C,23,AF,D1,9D,9D,39,63,D5,48,BA,36,CF,7C,2A,89,DD,4B,9F,54,9F,0B,AF,72,5C,5A,72,5E,14,56,F0,47,3B,63,04,FE,B4,1D,38,21,F0,1C,5E,AE,0F,00,EB,66,E2,4E,17,62,68,3C,12,DA,85,23,90,5D,09,91,AA,EC,B0,EC,DD,DF,26,EA,74,98,04,02,7C,13,B9,A4,9B,5D,3D,85,1C,7F,E9,D3,99,F2,D4,C4,44,B7,78,A3,19,23,B0,7D,CE,AE,D7,FD,6D,27,F2,99,6C,D0,7E,75,3E,4C,7F,09,51,70,18,44,AD,46,05,98,7C,E8,0B,60,FB,BF,31,64,82,63,42,8A,8A,D2,F0,91,A8,B3,09,5C,81,DB,5D,B0,64,66,A4,A2,94,97,84,34,F2,B7,D9,C7,67,F7,32,E5,82,55,6C,91,04,E5,77,5D,7F,5A,FE,03,18,A0,03,2B,06,19,5C,CB,00,E1,7D,25,D4,DA,4E,E6,D0,FC,14,18,FD,E5,06,3D,C4,A3,E6,C4,45,75,87,93,06,12,F0,F5,90,0B,44,74,16,AC,05,4B,08,3F,3C,AD,D7,9B,65,36,7E,4C,F7,9B,E9,0B,B2,76,2F,2B,F4,8D,49,FE,6B,49,DF,EF,FC,48,E8,2C,AE,5B,51,C1,91,93,96,20,CF,BF,32,A1,7E,0D,08,84,E1,C8,BD,06,F5,DE,C9,D5,7B,10,EC,F4,F7,06,B6,AC,2B,0C,1E,82,F9,9F,8B,E8,85,E3,94,F4,43,A9,1A,81,65,EB,F8,51,51,5A,25,9D,C4,FD,54,FC,4F,A5,E8,53,3F,2F,7E,47,E8,2C,48,80,DF,91,9A,9F,62,1B,B9,13,34,7C,2C,6F,CD,EC,2B,0F,50,DF,E1,DF,5D,E5,0A,13,39,91,29,D1,AD,3C,0E,7F,BB,84,10,E4,61,CB,11,EA,E3,9F,FF,5A,5B,E7,E4,5E,34,BC,ED,B0,ED,38,7B,F2,8A,0C,C6,08,3B,08,F1,29,08,80,12,4E,8C,42,4D,44,5F,54,B2,F9,FC,55,66,F3,92,33,76,73,25,80,B5,06,6D,ED,3B,56,F4,5B,7C,C2,60,5F,33,C9,97,69,85,4F,1D,7E,CE,8C,14,30,21,16,73,B4,27,89,ED,48,22,35,33,5C,7C,CC,24,35,A0,83,48,81,79,FD,70,B2,8C,DB,38,A9,01,71,23,B5,BE,D1,F8,D7,96,67,77,46,E1,02,1E,10,BF,66,40,F2,D4,6E,A4,22,03,5B,AA,B5,42,4F,A7,5C,B5,6C,15,4A,03,C9,5F,2A,58,93,DC,7D,BF,36,A5,CD,0F,0B,C0,0A,BB,43,39,47,06,B7,91,80,23,DA,B9,C0,98,7B,1A,31,C2,26,1A,DF,75,53,2D,B2,EB,E0,C4,A2,F0,56,1A,22,17,96,AC,8D,28,5F,3C,65,84,7E,E6,9B,21,FD,5E,0F,C5,44,5E,B5,F7,7B,23,34,11,0C,5D,65,45,FC,63,9F,58,3D,41,D1,A4,50,E2,9C,EC,E3,71,7F,F7,E2,A3,55,E1,82,21,D8,EA,41,A2,46,3D,A0,8C,A5,F1,02,01,4F,35,75,1E,36,3E,99,31,68,38,73,6F,A2,7F,9F,C8,09,35,41,E5,23,C1,FC,2D,7C,31,28,45,97,EB,CA,21,9F,B6,CD,C7,51,27,3C,BF,D2,E6,85,8E,38,99,69,43,D8,76,AA,0B,4A,A5,4A,D6,EC,3A,C1,BD,D4,50,9A,92,F1,6E,19,ED,B7,A4,11,66,FB,23,10,06,F4,FD,B3,69,0D,E0,83,85,05,D5,CE,7B,A8,D7,4B,F1,BE,0A,F4,D7,3C,99,B4,96,8C,0E,A2,7C,A7,71,F1,00,C0,D9,66,71,66,5E,2E,05,37,C7,F5,79,D9,3D,D6,1F,69,FC,36,21,36,86,0D,94,8D,8A,F0,AE,89,4E,B8,F6,E0,4C,66,DB,C9,7F,0D,58,85,6A,DA,F4,33,66,77,12,47,BA,9F,1D,A4,64,6B,53,8B,D5,24,BF,7D,6C,49,2E,4D,8A,0B,93,FE,B2,E2,64,32,B1,76,77,49,BC,B1,E5,10,AC,13,0E,2D,10,FA,41,9F,68,4B,58,64,85,CC,17,37,EC,9B,D2,EF,2A,DF,7A,69,03,BF,72,E6,0E,EC,72,6E,D6,15,35,03,7D,47,0E,30,F9,0C,E2,6F,70,8F,D9,7B,EB,99,F0,F9,9F,5B,78,6F,3B,13,BD,29,93,F5,4A,B5,4D,E2,1C,BD,1F,F2,0F,70,EA,A4,B4,CB,3E,11,82,A7,1B,BA,B7,40,19,EF,6A,1F,93,23,AA,0A,AD,ED,BA,AF,8C,F1,D4,BF,D8,D8,A9,71,FD,37,A5,58,20,B9,71,41,1F,C7,AF,BE,AC,33,64,69,51,8D,7A,1A,08,69,0C,5E,89,03,09,28,04,F4,D4,50,37,E2,6F,49,34,7E,73,D3,40,E4,14,85,BC,B5,3D,2E,C6,54,FC,79,B2,8B,F1,05,FB,CB,D7,D8,F9,2B,FA,07,EA,DE,54,51,DB,93,D5,DC,32,98,95,82,77,FA,AA,41,3C,84,0B,36,E8,ED,AC,0D,D5,91,A7,C8,C3,36,ED,13,A8,F2,3E,BC,2E,9A,2A,BB,32,E8,86,25,1A,B6,49,53,49,2C,03,06,DE,75,FF,01,72,D6,0F,F3,49,CF,E3,94,ED,42,E3,44,48,84,FB,CE,C5,3C,FA,93,E6,51,C9,44,3A,A7,69,7F,BB,E0,ED,27,F0,7A,67,EA,54,C5,8E,06,B2,7B,86,CE,57,2D,EA,0B,BF,D4,F1,22,EA,5F,68,26,34,7F,32,1B,FB,06,B9,63,5D,EA,4E,B6,E8,3A,17,C5,0D,EC,71,7E,44,54,15,25,3C,A1,BF,EE,95,F1,AE,DA,7B,0E,A8,82,F6,D0,94,F5,7F,0C,41,88,E6,4D,4A,6A,EF,06,7C,A1,74,76,DF,EA,DB,5F,3A,03,E4,EE,86,EA,2D,2C,81,DB,F2,F7,E1,7C,DA,F7,1C,FA,8E,EA,A7,30,61,FC,BE,C1,A4,02,3E,A3,CA,EA,9C,0F,E1,AC,75,22,07,2A,80,99,04,BF,0A,86,7E,B4,86,44,C5,70,D2,5B,73,94,65,6C,E9,95,BC,55,6B,FA,44,A7,26,3B,64,97,C8,C0,E6,05,53,20,4F,93,D2,E7,B1,83,DE,A2,5C,1F,D9,8A,99,20,28,C8,7E,E4,A6,3D,AC,0F,37,57,85,1E,6B,66,EF,5E,02,FC,2D,2B,F4,09,8C,9B,9C,A7,C8,BD,53,31,0D,F4,87,E9,E1,72,D9,28,74,D9,81,D2,E6,AA,D9,3B,2C,6C,8C,4D,32,2E,AC,32,B4,F0,8A,13,42,36,EF,36,C0,E9,49,51,1A,6C,D8,ED,CF,05,3E,03,60,89,31,86,99,D5,42,DD,66,7A,29,26,60,06,0E,70,A4,32,1A,0B,EE,A7,D3,84,25,77,07,D2,99,53,79,E6,76,08,28,74,C3,89,ED,B2,38,CE,5B,59,35,D0,96,4F,9E,D4,0D,48,7E,64,A3,E8,8B,14,AA,4A,31,C9,D1,7C,30,FD,F2,85,F7,E0,E5,96,DB,D8,14,78,B4,2E,A9,0F,72,8C,F8,06,9A,B3,D1,18,13,C4,3B,58,5C,73,6D,C0,E3,62,7A,BD,7D,3A,2E,89,23,76,27,8C,83,7B,E6,E6,34,C9,ED,46,E2,94,20,B4,A2,DC,58,60,DC,3B,72,B9,25,B1,F9,0B,7F,DF,11,68,FD,8C,71,21,C3,6E,C2,62,71,F3,13,03,8A,1A,5F,8E,02,7E,73,20,6D,18,F9,FD,68,26,31,9D,C4,7A,7E,9D,26,3E,F4,DF,27,C5,D4,67,E4,4C,BF,7C,88,FF,20,DE,58,1B,87,CD,AC,2C,62,72,DA,7B,92,F4,B1,0A,9F,96,E1,19,A6,A6,3E,BD,52,AD,06,73,B8,25,86,22,76,8E,E8,6C,5E,9E,5D,F7,CC,1F,6F,D5,F0,07,2D,42,82,3C,93,74,D2,04,8D,35,96,00,B2,4D,B3,83,C4,9A,5B,09,A7,44,A5,36,81,E1,02,E7,9E,1D,6E,BD,E2,4D,43,20,8B,BF,EF,92,53,B4,73,DF,69,CD,54,B9,E5,D1,AD,D0,EF,47,FF,08,4C,7E,5F,12,CD,90,51,45,2B,16,01,76,B0,C5,07,F1,1E,BC,D6,0E,BC,88,37,8B,92,59,4C,C0,1C,B6,86,45,A5,FC,CA,50,D8,B1,CA,17,98,F8,4B,E3,88,37,5F,92,4F,21,AA,B2,57,62,03,05,1E,F2,AD,40,FC,F3,B7,C5,07,E9,63,FD,9B,81,A4,06,29,EF,BF,91,1F,D3,D7,1B,CE,CC,00,9B,87,2D,B6,F1,8F,00,07,A4,55,3A,67,C3,B2,6B,89,39,7D,E1,11,D0,F7,F7,39,86,A9,14,34,70,14,64,89,71,C1,BE,1A,49,1E,12,D8,83,5B,45,11,89,75,53,C1,02,E1,89,45,F8,66,84,1D,83,C7,18,D7,B6,E3,32,80,20,7B,7B,09,23,C9,7E,8F,07,BA,45,7A,A6,85,CD,DD,45,F3,7B,F0,14,EA,48,35,2E,B3,3B,D0,6F,07,01,3C,C2,8B,69,20,03,FA,B1,61,C6,A0,D7,24,6A,3C,2A,A1,97,2C,50,F3,1C,8F,22,A3,A2,71,02,D2,8A,19,8A,44,F9,43,6C,DA,52,12,A6,29,24,76,7A,C8,38,11,75,38,50,5E,11,E5,80,85,32,F8,F5,B4,1E,3E,D0,94,69,19,75,40,6A,7D,23,67,41,3A,78,06,CD,0E,82,58,97,AF,E9,55,63,6E,60,9A,B3,5B,EB,E7,20,F7,77,8E,FA,F7,A8,59,C6,A4,C4,38,F9,DE,7F,3A,A5,79,A5,D3,72,72,98,27,01,9C,7E,65,A0,C4,EB,F0,52,A1,0A,33,63,12,4C,70,6B,FC,52,27,44,C0,32,5A,75,19,A9,7B,11,10,A5,5D,D6,5B,FE,88,15,8D,17,35,E4,17,AD,F8,2D,4B,64,33,B4,11,22,DE,9B,C7,72,23,CA,32,F8,C7,76,0E,60,8E,A6,F6,EB,7A,FA,F7,D0,82,67,95,73,D7,A1,26,56,C5,61,17,80,87,7E,E4,F7,47,7E,44,F4,6F,1A,1D,06,8E,16,B9,6D,62,8F,5A,46,BE,FC,7C,E2,0E,73,DE,DC,22,8C,4F,BA,06,60,DE,2B,1A,64,F3,35,C4,75,B5,58,A6,1F,33,39,E6,A3,D7,D8,76,3B,98,55,01,BE,25,D3,6C,F4,65,3E,1B,6A,C4,AA,2E,BA,3A,D0,B9,25,4F,BE,C9,0E,11,26,E1,F3,28,AD,12,52,EF,91,72,75,90,CE,68,4E,38,40,2B,36,28,93,57,CF,11,EB,8A,81,2E,3F,DA,AC,E0,50,7B,53,13,D3,F8,4C,73,9F,9E,B9,C6,4A,A8,1A,3F,03,CF,92,57,23,F4,0D,E7,2B,9E,2E,3D,93,D8,4C,5A,AF,6C,D6,2F,D4,3A,E7,7B,C4,99,3B,AA,F8,80,5D,FF,C6,13,D0,AC,82,94,15,C6,4F,67,62,C9,B2,4C,61,D9,F9,25,22,8B,DD,2E,6C,C6,94,41,EA,A5,0F,84,CF,C2,8F,51,FB,F8,A1,47,68,19,46,DD,F0,DF,28,E9,74,A9,1E,CF,BD,26,98,B8,B7,AA,38,4F,CA,0E,54,34,BB,67,93,63,84,14,E5,43,4B,85,67,A8,E2,9B,4B,3D,66,05,50,B6,A9,16,61,E2,32,FB,39,B5,C1,83,39,70,C5,F4,BF,7F,B9,26,92,FE,CC,47,F1,83,84,55,EA,BD,E7,4F,37,EA,EE,7C,DA,A0,3D,C0,78,A2,BB,F9,64,C0,8C,CE,7C,DC,24,99,2F,B3,62,8F,BB,CE,57,10,7B,F4,EB,C4,04,C9,8E,AB,BB,0E,05,37,FA,98,44,B8,97,22,1F,88,87,EB,B2,71,09,6E,A5,7F,9D,AB,97,A5,E2,52,9B,D0,75,0E,FF,8E,C8,32,49,76,1C,70,90,6B,F7,2D,99,54,27,9F,16,3B,81,A8,54,22,FB,F0,6A,AE,DB,72,C5,FB,CA,FD,E2,CB,FC,A6,A9,16,AE,10,D6,44,3A,F4,02,0A,23,DF,7C,D4,2F,05,9D,EC,7E,7C,6F,96,70,53,D3,95,82,5E,9C,A3,AB,D5,78,1E,DB,68,73,10,AE,26,1F,A9,BB,FB,62,83,2F,44,60,E0,F8,CB,6B,15,E5,19,0B,C4,4A,A2,BA,5A,0B,BD,B8,C4,19,94,E9,84,40,1C,02,50,1C,33,E5,32,0A,2E,BA,5F,45,16,3F,A8,04,80,04,D2,20,8A,8D,73,0A,CE,65,EB,DF,2F,50,12,DC,E1,25,D2,5A,E8,69,A7,88,28,D6,F2,FF,69,BA,35,5C,1B,8D,20,75,17,F7,29,B7,38,3B,AB,08,4C,21,D4,01,92,41,8D,5C,92,44,D9,37,94,C2,94,A0,38,DE,B9,42,FD,7F,78,30,87,36,48,74,CB,87,59,EF,4E,58,52,77,67,22,9A,20,FB,3B,2E,FB,33,1B,DE,C9,AE,41,21,79,33,97,10,20,2D,A5,F7,9A,97,90,51,53,6A,C6,F4,50,42,C8,53,3D,A8,CF,2E,6F,4B,BF,45,A1,D8,CA,49,19,8D,9F,45,F4,50,83,41,4E,85,83,61,E4,62,24,AF,11,EB,EA,EE,69,49,9B,21,01,1B,9E,D0,86,AA,A1,F7,AE,49,20,57,41,B2,04,78,6B,4A,07,6B,70,3E,52,F8,09,A4,CC,20,62,22,A3,7C,07,62,82,C6,23,6E,74,23,05,E6,FD,2B,7E,21,8D,7A,DF,99,14,40,0A,7E,F3,78,C1,36,9A,2A,6C,AB,49,0C,06,10,80,82,F8,A7,A5,0C,06,D3,CA,27,80,2A,C6,2E,83,68,D8,0D,BC,A2,55,58,2A,CC,D2,3A,1F,96,06,14,B7,81,33,A9,45,14,2C,15,43,19,90,5C,51,84,13,59,3F,AE,99,28,39,B1,B4,94,46,46,C6,E4,BF,BD,18,61,0E,D1,C3,73,E2,C1,75,8D,24,38,C1,04,1A,E2,4A,DD,29,06,EB,03,BC,B9,E9,8A,6A,C4,28,CD,DE,B4,B9,47,14,AD,0F,42,FE,B5,D8,42,F2,DF,C5,AF,D4,F0,A1,55,C6,C8,FE,EE,03,F4,0F,42,C9,D9,70,12,8A,42,5F,59,A1,13,7B,90,70,93,E8,EB,1A,F5,EA,16,AA,55,62,AB,B1,2D,98,65,4F,AC,34,7C,34,45,0F,B6,5D,81,E3,DB,26,05,97,0D,14,EF,B9,BC,5D,55,77,A9,0C,B9,31,E4,3E,12,A5,D9,C7,8C,6C,5F,DC,C4,3A,A9,46,2C,23,FC,CE,B7,8E,DF,EA,96,96,36,03,B1,BF,CC,84,56,B5,DF,89,35,0A,12,A2,23,F7,A4,60,E1,5D,06,54,54,8A,5A,E5,89,56,92,E5,82,23,AF,B4,E7,8C,D9,5E,8F,33,37,07,70,9E,F3,75,2A,11,43,72,4F,7F,D0,B7,E5,7E,F4,67,4E,7C,58,A5,CF,F7,CF,6E,99,C4,A1,7A,FB,AE,34,D3,50,BF,EB,A9,06,78,1C,60,0E,8A,FC,A4,AF,5F,82,74,35,B4,9A,F7,9B,40,25,C8,F1,60,27,5B,9F,41,D8,8C,08,2C,20,3E,47,70,AA,C0,CC,02,8F,8F,E2,7F,24,05,F3,3B,A9,2A,20,14,C4,34,D8,FC,0B,E7,7A,02,7E,41,F4,E6,DD,1F,F3,0A,C6,83,A2,6B,F1,01,AB,3E,EF,F6,D3,D7,31,D0,A2,1F,09,32,EF,3F,27,DD,4D,67,03,91,32,47,B4,EC,DD,5F,36,29,0E,14,3E,04,7E,4D,81,76,F2,B4,8E,87,F3,21,C0,CF,5A,92,71,2A,70,D3,4D,F8,9D,C9,47,35,9E,5F,1B,38,FB,EE,FC,A1,C3,E6,77,57,D3,23,53,4C,BC,6C,04,2B,54,CF,FA,92,C8,BC,32,61,BB,00,42,04,C5,D4,FE,F7,0F,AD,B5,73,CE,EC,65,B5,FC,71,E2,54,1C,C9,4F,17,CF,F7,6D,96,B6,17,28,55,E5,2D,83,E6,87,41,C7,F4,F3,03,75,A9,56,FF,A9,31,01,53,16,9F,3E,0E,E7,0B,37,B0,23,79,AE,1A,E2,99,56,8F,34,DC,66,33,01,30,62,89,DA,15,D5,50,D8,A3,66,CF,CF,A2,C9,68,87,D6,A7,61,61,AE,85,19,CC,1D,47,7D,82,2E,D3,4F,27,7C,16,14,C3,32,F8,0E,D4,83,75,FB,04,06,25,0B,D0,DB,6A,E6,E9,74,C3,6C,D5,ED,96,44,75,0D,33,C2,54,9F,FD,46,BF,88,6F,81,2C,8B,60,12,0F,A6,36,BB,D2,E8,B0,20,0F,56,2B,66,83,43,3B,27,C9,37,83,16,74,C8,1C,CF,D4,A4,55,26,30,37,7A,38,5A,7C,87,74,D3,3A,04,8B,34,6B,F0,24,69,42,44,AB,B6,57,CF,43,26,2D,F9,85,B5,71,45,59,F0,0B,F9,69,F6,F8,71,62,FE,04,A8,89,92,11,6E,AB,C3,F9,BC,CC,2E,4D,05,CE,4B,A0,10,A9,64,21,7E,BE,2C,92,BD,6A,90,8D,01,23,8C,95,7B,79,7E,CD,38,44,EB,85,14,07,C2,F2,E4,F2,24,B0,94,FE,A6,6D,20,86,AF,6A,36,B4,F5,ED,DE,AA,F5,5E,FC,7D,9C,C1,40,89,DA,D4,90,51,B5,3B,AB,91,B5,B1,CA,3B,10,CB,D3,6A,6E,CA,45,99,F6,FB,B4,81,5F,A2,BF,C5,3E,AE,B9,72,5A,FE,30,07,24,58,0A,9C,3E,6A,9F,CC,F9,36,00,82,25,F6,40,98,69,B0,35,41,39,94,6C,55,B7,02,F4,3C,1C,D8,76,B5,60,F0,17,12,A5,E4,44,FC,E5,80,96,35,C1,AE,CD,D5,AB,BC,70,E3,94,1A,E0,D6,7D,37,3D,84,31,1C,98,4E,20,36,CC,65,FF,7A,DD,CF,54,10,26,7E,C2,55,E3,52,70,E4,5E,7E,62,E6,0B,41,5D,50,23,51,B9,ED,DC,00,2F,B4,54,83,09,D6,74,53,12,EB,20,23,A4,44,1D,11,DE,F1,21,BB,E3,8F,89,38,70,DB,0A,9A,88,6E,9F,1D,75,42,5B,F5,75,E2,7C,FB,85,13,6B,EF,3F,C6,5B,18,9A,45,63,65,D0,8C,A4,92,0C,01,CE,8D,DD,45,96,E9,DA,ED,D8,08,3B,10,24,7B,46,F2,59,94,39,BE,6D,39,7C,2E,0D,8C,46,EA,78,26,6C,73,5F,AD,D6,4E,E0,4D,EE,B7,5D,05,49,72,B0,60,E0,3B,BC,1A,2C,30,B1,23,54,DE,28,B2,FC,3E,52,5B,BF,8A,A4,1A,8C,75,BC,C3,25,61,4E,4C,2C,F4,16,BF,F1,06,E7,6C,4F,9D,8D,D5,69,57,32,BA,26,0C,8D,6B,FF,BD,50,F4,01,74,F5,E6,67,D9,FF,5F,DC,2D,FF,22,B3,1F,F9,D3,D0,34,F1,DA,A7,9F,C9,5C,FB,63,0B,D3,17,B6,F7,B4,BE,C3,13,BD,5B,5E,91,EE,86,5F,8B,C5,DD,69,A8,00,78,C6,BE,18,DC,ED,52,92,AD,9E,14,43,D8,AB,7A,AE,B1,45,28,E2,9A,47,C4,E9,23,8F,5C,6F,FB,6A,74,2C,50,15,49,B9,90,4B,5B,CD,B9,2E,F5,C4,BD,69,FD,CF,28,83,8F,51,15,19,A9,08,52,2A,FD,81,65,82,A8,6D,E5,55,E6,19,B8,C9,14,C4,83,BB,D1,95,61,2B,20,48,6D,4A,E2,7A,0B,B8,4B,64,58,49,5A,D2,95,2B,87,05,AC,DB,75,75,CA,AB,82,B6,D8,D8,B0,10,7C,7B,72,9E,DF,92,31,8F,A5,3B,F4,41,01,9B,18,5E,CE,73,4C,CA,2D,AA,45,00,70,56,C7,31,35,63,1B,A3,B3,3F,F7,61,E4,37,08,45,A0,A6,27,3D,2E,33,49,84,7A,B5,CA,A6,A1,10,38,14,5F,5F,44,55,27,EC,93,A4,3E,0F,E7,E9,62,D8,3A,59,83,9B,88,A3,99,A3,78,30,98,F5,A4,1C,C9,D0,F2,43,D1,1D,F5,A3,2C,4A,1A,3B,54,96,AF,22,88,EA,AB,14,9C,50,88,71,99,75,A1,C0,BF,29,87,C9,7D,AB,FA,DF,3A,59,AB,79,B3,4C,ED,A5,9A,A6,64,01,E4,01,6E,4E,3E,6B,D1,61,CD,58,05,50,FF,88,1C,2C,CF,A2,8A,8C,56,CD,46,BA,AD,F1,33,B5,E9,86,03,E0,1F,FB,32,D7,67,39,4D,0E,02,9D,6F,EF,CF,50,7D,3F,B7,5F,C4,DD,23,3A,B5,92,88,02,F6,D2,40,CE,65,3E,85,FB,84,EE,14,AA,93,A6,52,0A,CC,B5,B0,A9,18,4A,76,15,42,99,19,0A,B4,85,2C,58,DE,62,97,5B,0B,68,A1,5A,0A,57,0D,46,05,5C,EA,D0,7E,CC,2B,4F,BA,72,02,FA,17,71,9E,EA,8B,D4,67,47,09,5A,E5,6E,E2,BF,C7,6E,0F,2D,CB,03,64,FD,F2,70,C9,AD,67,DF,2B,C5,A2,92,6D,AA,C0,DC,1C,82,F9,1E,99,C4,64,B3,DA,61,03,E8,9E,D9,23,BC,1A,1C,D2,F2,45,DC,4A,8A,04,40,D4,49,43,CD,D3,39,3E,43,A3,43,60,40,9B,5A,03,08,70,93,A8,A2,A1,FA,D7,A4,13,D6,21,FA,18,53,FB,BE,42,12,41,A8,BE,B0,25,E3,6D,05,6D,54,52,19,93,83,09,83,1E,1F,A4,AC,3D,ED,04,14,D4,02,A0,E9,85,0F,CE,34,2E,04,D2,43,24,9F,4D,C5,C1,63,BE,27,86,C9,07,42,D5,A4,F9,70,94,74,70,53,8B,E5,9C,4F,B9,5C,29,67,3B,7F,1C,C3,C8,87,66,4D,54,77,83,12,F4,45,F0,E4,95,BB,19,A8,E3,A3,41,64,91,30,D2,88,DC,18,0A,78,3C,5B,7C,21,C2,D9,E7,E9,2C,9C,E5,F2,1D,AE,55,BB,4F,29,03,2A,B1,11,69,CC,7B,DA,CB,F9,E6,A6,9E,93,6E,C5,92,E5,20,89,82,CC,D4,5D,56,57,90,84,B5,3B,38,30,86,90,32,DD,27,98,58,44,91,05,0D,29,EE,B7,B3,71,54,CD,7B,50,7E,54,E6,61,A4,DC,21,C3,4F,8B,61,91,4A,C9,EE,41,F1,21,0B,2B,AC,9F,54,71,B5,96,F7,3D,05,4D,A7,B6,62,6D,C7,C4,CF,EB,74,C2,49,91,8F,D4,D1,CD,67,B7,18,17,50,D8,53,A1,BA,F9,B1,FE,C8,95,EB,DF,7B,54,11,24,96,60,58,B9,29,90,F3,41,5A,0C,F9,8A,D7,D7,F2,A1,D8,34,10,2D,DC,F0,7A,A7,E8,81,56,B0,A8,87,42,EE,CA,06,32,40,15,AC,C7,0B,EF,B4,96,BD,C8,44,63,A5,F1,D9,38,05,DC,1D,D7,CC,74,4F,13,0F,DF,F8,E3,64,AB,72,F2,85,F8,B2,26,78,67,1C,8A,90,FC,66,97,A6,10,22,08,86,B3,66,5C,D6,4D,8B,DE,E8,54,42,E1,74,6B,FC,2B,41,7C,E2,29,8C,E9,97,25,9A,58,49,DF,D3,B0,50,C5,E7,D0,B3,65,67,18,C9,8E,A0,E6,17,F5,A0,4F,24,FB,EF,10,62,62,B8,1B,63,D6,AA,B9,6E,6E,DA,91,24,68,47,26,E8,49,2D,90,80,7B,EB,21,6F,2D,50,38,FB,CA,CD,2E,10,02,B6,CB,5D,99,63,D0,68,FB,3D,EB,0A,63,AB,FD,FD,1F,B3,47,E3,8C,F4,22,DD,5A,A9,EC,9B,3B,0A,43,8C,38,AF,C5,FC,BE,38,A2,B0,51,53,F9,D9,1C,6A,8E,83,F0,8D,98,A3,4F,BA,E3,AB,80,BC,90,A6,A1,BA,EA,F6,B6,69,E5,69,04,10,4B,E8,31,39,FB,EE,F5,69,6C,CC,AD,2A,8B,7E,0C,70,B3,1B,F9,97,48,98,E6,8C,54,B0,66,C7,CC,95,C0,1F,38,6D,42,28,E2,61,59,D0,EF,EF,F1,37,3D,FD,37,69,9C,79,03,91,C7,96,A9,BA,4E,CD,A5,15,50,D4,96,2F,BE,1C,FC,8F,42,36,02,65,CE,37,12,F8,4C,52,FB,48,7E,E1,26,43,53,FA,99,E3,9B,08,C7,BA,F2,0B,EA,72,AB,56,62,C1,A4,F9,18,C7,78,5E,02,DB,4C,69,8E,BE,41,37,77,07,63,84,82,77,11,9D,FF,E1,56,67,39,9D,0F,ED,E6,6E,FB,C0,92,8E,D8,EB,B4,35,18,DF,76,33,B5,F2,68,0B,29,D1,B1,86,C3,60,2D,95,F7,77,A6,E0,19,C4,E8,71,4D,8B,B7,BD,AB,E2,79,A1,65,8C,D4,70,73,B2,6B,FE,2C,3D,3B,5B,B8,12,88,9A,B5,51,AC,95,79,BC,A6,83,F6,0C,E7,30,62,FF,7C,5A,5D,70,EE,50,2B,73,9A,24,57,CE,A4,B7,C8,28,81,28,65,48,2C,E9,64,48,74,5E,60,91,DA,47,A5,CF,18,A4,B5,4C,59,D6,FF,EC,E6,CC,75,FA,40,86,D1,6B,17,19,D2,94,0F,DA,67,7E,25,C0,AC,CD,01,36,4B,2F,9C,34,F2,82,25,40,12,D6,23,FB,E0,F3,B6,F5,19,CE,08,DE,00,C2,5F,2B,68,80,E6,75,6D,48,D6,C2,2E,18,3C,46,2B,8C,59,32,26,7D,32,29,DE,D0,43,35,9F,DE,96,D6,B0,D0,4E,0B,ED,CD,D9,B2,B5,3D,84,69,B8,0D,F1,13,78,7D,9B,93,C8,CB,11,19,2E,86,0B,47,64,14,AD,2F,AC,1C,1B,B5,F7,D3,44,82,2F,EC,71,C1,9F,A1,8D,64,5E,2A,93,34,D6,37,9B,76,66,33,97,2E,E4,14,1F,1A,ED,D3,B1,B2,F4,5B,9F,F3,A6,B8,13,9A,02,08,43,60,6B,B3,41,47,E3,5E,14,75,63,9F,B7,83,13,09,6C,20,33,23,01,D9,69,8D,A3,00,DC,C3,0E,37,36,6B,21,EF,AB,19,49,77,B1,E0,40,A3,1B,8F,B1,09,1E,23,B0,4B,F0,69,89,9B,2B,53,CA,B1,1D,A7,64,80,D7,E7,F3,69,AF,41,27,FC,A9,EC,2E,13,1F,58,72,99,B5,F2,5C,1A,CB,2E,8E,05,EA,BC,08,B7,B0,BD,31,33,C8,8E,C6,02,50,5C,9B,E5,B5,1E,68,4A,E7,A7,73,87,82,F9,CD,67,CF,11,4B,B4,1C,F5,79,C5,1C,BA,A2,0A,26,74,4C,AC,67,F5,BC,E9,93,08,FA,ED,79,53,DB,82,4B,26,83,E4,2F,19,BB,F3,68,5D,B1,14,AC,0D,9E,D7,43,AB,2A,38,53,A8,70,3E,2E,CF,5F,89,4F,11,05,F0,DC,6E,CD,D7,DB,6E,CA,FA,D7,02,C9,A6,AE,C2,19,B3,03,61,FE,51,BD,92,1B,EC,B1,F0,33,B9,20,5C,2E,98,70,E0,C1,42,D5,69,4D,A2,03,6A,DE,DE,A3,11,3D,AE,74,67,1C,4C,FF,D0,5B,9A,4B,CF,76,AA,BE,B2,84,D9,6B,8A,79,09,81,1E,2B,EC,B8,4B,D4,19,35,88,CC,84,21,5E,FB,B4,8F,9C,C4,F2,FA,00,9A,5B,7E,8E,B7,01,9C,F5,8C,64,2A,B7,AD,31,F0,CF,B7,27,71,E3,07,07,EA,3E,E1,45,03,BE,22,AA,DF,01,F8,8F,B3,E6,C1,C1,6D,8A,47,65,3B,88,BC,70,6D,A2,A3,7C,4C,E4,85,6A,F6,71,BE,B5,16,3C,AB,C6,B8,2E,98,F9,54,C8,6F,F4,8E,89,71,53,F6,EC,2B,22,7E,8D,9E,D4,8E,83,62,33,AE,C3,85,F3,6A,CA,FE,72,3A,A9,5F,80,F0,4B,5F,DD,34,8A,32,C3,F4,91,4B,77,12,40,52,20,8F,6B,C8,62,E0,A2,2A,40,23,A5,7F,B5,B2,F2,2E,97,B2,DA,BA,EE,32,A5,76,DC,26,9D,47,22,25,4F,CA,F4,C8,4F,40,26,9E,CD,4B,2C,6A,83,2F,FC,6D,16,41,24,63,CC,25,EB,CA,7D,11,E9,F4,8C,9A,EB,0A,CB,B4,34,26,14,17,DC,7E,51,C2,F7,9A,E0,3B,3A,5C,53,5C,BA,C7,A0,22,4F,CB,C4,B5,1C,27,ED,97,FB,08,3E,37,11,D3,95,01,44,F0,FF,F4,82,CA,B4,58,F8,CB,97,CC,9B,83,CD,A3,6C,33,98,7D,10,F9,0A,92,60,19,94,BC,BF,8E,13,FE,BB,DC,68,56,B8,6B,AF,4F,D4,41,2E,94,E4,D5,F8,CD,04,55,A5,70,EB,C3,A3,81,B9,5A,D1,DD,2A,0D,88,41,AF,6B,1F,0A,B4,FD,B6,5F,58,9B,24,CC,4A,0D,9F,FF,42,FE,09,20,D6,53,69,91,E7,93,C7,38,C8,A0,55,60,83,75,AA,5A,EC,EF,2E,89,7E,96,83,04,16,21,EC,4F,C6,AF,3D,87,5B,6B,2C,F8,72,B5,D3,BA,D0,A6,00,41,58,1D,87,4C,96,D9,3A,C0,F2,BC,7E,04,02,32,4B,EC,62,6D,A4,57,43,FA,F1,4E,AA,33,D5,47,C1,72,83,53,6E,A8,23,FC,C7,13,CB,3E,1F,60,1F,68,FF,D6,14,05,C5,3C,AC,91,0A,22,F3,97,15,B7,26,A2,10,05,42,2E,ED,BC,F3,25,0E,9C,81,D3,25,77,FE,94,31,79,88,5F,18,F4,18,E1,C9,52,7B,A5,13,28,45,7E,EE,EB,06,EE,4A,D9,92,DF,39,B1,74,EA,8A,97,A0,83,14,11,4C,09,FF,61,7D,4A,00,88,29,2B,13,87,79,6E,0F,9F,D8,26,E2,F1,D9,B7,70,13,7E,AF,84,31,F4,05,14,0E,46,3F,FF,13,38,CF,39,68,54,C6,7F,69,FF,FF,B4,B9,E5,1D,DB,E4,5E,E6,0B,E7,72,AA,C2,41,C8,42,02,77,56,CB,E5,19,E3,37,4A,CE,02,78,6F,68,34,0B,E9,EB,3D,AB,37,56,CF,00,61,1F,05,DE,BA,01,E5,F1,7A,72,7D,67,60,D3,7B,DC,AA,B7,BE,C9,6D,95,71,E5,46,CC,A1,49,E1,14,72,47,C1,9E,E4,00,8B,04,23,DA,05,8D,13,08,7D,4A,FF,61,46,DF,22,AE,1D,11,E2,7D,BF,F6,1B,87,A5,58,87,0D,29,02,D1,ED,A1,D1,33,15,C0,AD,9C,A0,CC,00,49,3D,74,D0,8C,C4,FE,55,81,51,8C,1F,DA,44,77,8F,BB,21,78,C0,26,C4,0B,A7,7A,9E,13,B7,55,93,94,B7,D4,CB,65,5E,3E,85,14,D8,39,5A,C6,DB,3D,7B,0F,31,FE,58,28,4C,13,75,70,B6,2A,D2,07,4B,8E,55,F3,07,68,23,0E,AF,2A,9E,5D,41,E2,A6,F8,0C,C1,90,50,0D,3F,44,FB,66,34,3E,B8,61,03,A2,26,BF,57,D5,07,DE,2E,3C,69,10,F6,CF,43,8F,0D,80,F8,AF,D4,EC,20,CB,22,81,57,24,8C,12,3D,5D,68,42,86,0E,E9,1D,84,80,B0,C2,26,63,51,17,20,67,B2,AA,7E,DC,1A,72,D3,33,A6,2D,FF,86,73,AC,81,10,09,77,D8,BF,C3,8E,05,17,2F,68,CA,F7,D3,65,DC,E3,B1,10,6D,97,48,0C,FA,0D,20,2A,7B,91,8A,42,F1,31,67,BD,7F,17,E0,4B,84,AC,BD,4A,C3,55,92,81,16,DC,B0,06,C5,CA,83,2E,73,84,81,B1,62,C7,76,A7,F6,9A,14,29,64,91,AE,1D,0E,FD,FA,29,E4,3D,5F,9C,F4,23,B8,D4,81,82,0E,99,92,89,AF,0E,37,BF,0A,47,91,17,34,87,8D,3D,65,4F,01,99,AB,81,27,73,E9,B6,47,80,3D,77,A5,D2,97,DC,EF,DE,E4,49,CF,1D,46,5B,48,5B,75,52,45,5A,96,6C,6E,75,92,7C,D5,FF,95,57,D1,9C,55,AA,50,A6,91,66,6C,71,35,8C,2F,8B,34,93,7C,C5,23,55,C4,BE,9B,0B,42,A8,B4,E2,82,28,BE,20,06,06,79,64,6F,9E,EB,9A,43,38,EC,5A,13,45,61,EC,30,C3,8B,46,82,2F,B2,74,83,46,07,38,19,93,55,CF,5C,D3,C6,08,3B,5C,C3,72,17,2B,1D,7C,D3,E7,A3,1B,C4,81,72,D8,6E,E8,86,F5,FE,F1,F5,E0,26,FD,2F,05,F3,EB,AD,41,20,13,56,AF,60,8A,B0,47,47,17,8A,19,98,00,13,E5,E1,0C,30,69,15,4A,4A,CF,73,62,40,9E,ED,D9,92,84,95,61,A7,6D,F2,ED,7C,53,C3,DB,BA,78,81,FD,CE,7E,14,9A,13,49,6D,15,E8,1F,5F,AC,34,47,93,03,FE,83,46,F4,18,B7,D9,11,34,7E,9D,1C,3C,30,07,A0,66,78,7A,C7,B1,A1,6F,31,20,46,01,94,54,08,5D,B9,0B,4B,D5,2D,92,CE,FC,B4,C8,25,96,17,F9,FB,15,E3,4A,EB,2B,5A,40,AB,48,5A,EA,0A,41,B3,B2,0D,61,34,6D,A3,43,57,06,D6,26,58,1C,49,26,0F,F7,B6,72,66,17,8D,56,F1,98,84,BE,7D,DA,5B,26,D5,BA,41,E0,20,88,0C,4E,B1,E6,6B,84,2F,DA,D7,85,A8,EA,9C,AE,F7,AC,97,B7,CF,A7,D9,8D,70,90,9A,FE,98,46,FC,F0,CA,62,B1,F6,F8,F3,17,73,CA,1E,10,7F,BF,07,1B,AE,42,7C,0E,A6,D5,BD,86,F5,AE,5B,E4,75,5D,1C,F2,D5,79,62,F2,2E,66,75,3D,62,E5,C4,0F,62,F8,AF,99,59,EE,CD,09,8D,DC,3F,5B,9E,61,F3,4D,1D,A0,B8,06,55,57,69,FC,20,6B,88,12,8D,D2,DA,CF,DC,90,B3,D2,ED,D3,E8,E1,96,DA,EE,32,BE,21,EB,C6,22,CC,CB,78,98,BC,5A,68,30,3C,0A,69,26,3E,5E,0C,EF,64,2A,E9,D2,87,68,73,CC,9A,54,69,91,E6,AC,2D,4E,88,B9,06,8E,D9,A4,07,D6,17,D7,F5,98,8D,E9,66,99,2D,7F,11,5C,10,B1,C0,99,87,BC,93,B8,8B,C1,5F,57,87,DB,B5,F5,BA,2E,53,C9,05,1D,22,7E,3B,E8,BB,C0,74,FC,E1,1F,85,FA,7A,12,65,A4,DD,AE,89,8D,BE,84,80,A3,B9,92,2E,AE,E9,C2,E6,46,4A,1F,75,AB,00,F6,D3,55,12,1A,F5,29,7B,90,F7,79,07,7D,36,24,60,46,A2,A6,D8,99,48,5D,20,F3,CB,C7,D1,E4,3D,7C,8E,22,0F,95,15,BA,BF,CA,EF,08,A2,94,99,32,38,93,11,7D,B5,35,E3,AC,A7,F9,DC,ED,26,D3,24,4F,82,57,B1,1C,08,95,4F,AF,A0,F4,88,4D,8B,FC,47,19,96,74,C4,27,7B,03,C0,B2,58,7C,58,2C,F9,CE,67,01,3A,29,07,D9,44,8D,A9,F2,B7,87,D3,46,05,3B,86,0B,77,96,F1,38,14,D2,69,66,DC,03,AB,C3,D6,25,12,28,9F,E4,A3,DC,93,0F,C9,9B,49,E1,9B,9A,57,52,FB,4A,3D,4E,D4,9C,2D,24,E4,80,A1,85,EB,1C,11,C6,B8,79,AC,05,56,9F,82,8C,1E,B9,7E,0E,10,34,B0,39,F0,AE,0F,69,EB,4B,5E,20,E8,77,65,5F,22,2C,3F,49,58,AD,B4,75,42,63,E7,D0,3E,D9,F3,74,0A,31,1B,E7,EC,C6,59,AF,14,5E,5B,39,48,C3,22,DF,95,B1,6B,77,77,9F,BC,28,C4,D0,00,96,E3,99,3E,99,86,BB,79,8C,8E,38,26,25,6A,5E,17,9F,17,DD,20,88,87,09,E6,ED,03,63,A8,0D,57,CF,3A,36,B5,D0,C3,4E,69,DD,5B,D3,AF,B8,59,D1,75,B2,0C,D4,41,F5,92,90,E5,4E,F3,B4,BA,CE,98,37,58,B3,DD,6A,C3,39,0E,35,33,8B,7C,67,E3,95,2D,21,62,EA,15,52,B1,72,CD,8A,E7,98,7C,86,D3,84,69,07,A6,B2,20,80,37,2A,0C,35,57,79,55,A3,BD,87,A6,8B,E9,EE,68,66,B6,39,F5,F2,48,08,A5,41,28,A6,6E,CE,79,7F,EE,53,42,33,1E,2F,F1,2D,3D,7D,42,AF,59,4A,8C,43,67,68,26,FE,F1,6B,B2,CB,F5,6F,C2,3B,A0,24,A4,1C,2D,CC,75,C5,31,00,48,9A,AD,22,E2,08,F2,CA,B1,55,7F,E3,63,2F,C3,BB,30,A0,D9,73,2C,17,E5,19,24,F9,44,23,EC,10,D4,BD,FE,96,86,5D,7F,38,3F,C8,29,02,A3,85,7E,C5,6F,6B,65,59,8B,02,75,B4,E7,77,DC,7A,24,EE,A4,1C,80,06,B1,77,C8,15,F6,80,43,5F,8F,9D,AC,3F,FB,8B,DF,32,0B,39,80,93,F2,ED,D3,C2,DA,59,94,0D,E4,7C,01,82,70,2E,7A,15,8C,05,0B,DE,F8,D6,63,43,D2,C8,89,A2,77,56,22,D8,C4,31,1F,94,B5,F1,30,B7,BD,5D,6B,53,A7,14,E0,C9,B6,86,FB,5D,AA,26,B9,54,C2,0A,A2,6A,4E,91,F1,87,07,64,54,20,30,34,B6,CB,B4,A4,0E,34,B0,3B,35,E7,15,09,8F,8D,0A,61,1F,E2,50,45,73,FE,F0,3C,F6,F0,8A,BB,02,EA,4D,4F,DF,A1,80,5B,79,8C,35,AC,1C,A8,F1,93,08,58,E7,B2,7B,AD,D4,F3,E7,1B,99,5F,13,81,51,0F,94,6B,2D,B5,56,E1,14,2A,57,D7,DC,25,06,C7,9D,EB,9B,8A,C1,75,4E,0A,E9,49,E3,33,BB,3D,DE,0D,92,E4,8B,57,10,E1,F8,59,35,39,E7,DB,C6,32,2F,0E,EB,69,89,02,8A,D4,00,9F,B1,28,88,E2,B5,F7,E6,52,55,BB,66,7C,9B,3E,2E,89,7F,25,86,7E,B6,D4,12,65,4A,0C,16,D7,2B,B4,99,B4,1E,BE,2E,2B,12,74,8E,BE,02,77,21,78,E0,07,7B,FB,4C,D0,63,9A,FD,35,FA,5E,E8,D7,11,93,11,34,61,AA,CF,F0,3E,10,BB,B5,E4,22,C2,1A,D1,2F,34,C8,A1,32,BD,BB,87,1B,6E,16,F9,99,F4,74,D1,6D,2D,FD,7A,60,9C,E0,FD,C3,F2,12,39,36,29,C0,19,E8,4B,53,E1,CB,7D,A9,8A,0E,87,4A,E1,ED,FD,34,3C,2E,B0,57,85,35,CE,62,BA,08,11,7A,2D,45,FD,8E,20,CE,4C,32,9B,A2,A7,DB,2C,45,86,09,30,F7,56,C7,3B,69,D4,38,F9,F4,69,82,E9,BA,88,B3,71,3D,B6,06,55,72,CD,A6,63,24,C0,AC,0C,58,00,4F,6E,09,B4,20,0D,19,D5,63,0F,CB,96,DC,44,B6,78,11,0C,FB,D0,9F,BD,75,91,D0,3C,0F,1B,22,0C,AF,69,7A,1A,34,93,F8,D2,4F,3F,6E,81,80,8E,F0,AF,23,8D,5B,B9,55,95,40,B1,B8,7C,BF,1B,DA,84,AC,3E,D5,87,F3,08,50,7B,64,2D,8E,48,3B,BB,2E,86,41,D6,11,5D,56,ED,A7,8D,75,E2,67,44,20,16,C5,51,21,CF,11,E5,A5,37,BE,74,22,58,E5,BA,DC,CF,37,4C,84,5E,18,7C,10,A4,9C,15,59,30,3A,78,CA,75,72,A4,84,D7,5D,EA,35,D2,1B,B6,5A,04,5A,8A,D5,C3,FE,91,CB,0C,3C,97,8E,61,32,B2,E2,DC,27,50,45,D2,24,53,F7,5C,01,D8,7C,3E,C5,C3,E3,73,6C,8F,62,30,D8,AB,84,6F,FD,EF,99,00,97,F6,EA,81,8C,AB,66,22,B3,02,89,B2,EC,64,76,83,29,63,BD,3B,F5,AE,0E,7F,4A,EC,5C,4C,1E,6D,8C,BF,A5,BC,28,FE,2A,09,A1,A8,F9,F4,B2,C5,EB,9E,9F,0D,2E,C8,D5,A7,C2,C8,21,29,AE,03,B7,1B,76,93,48,36,95,EE,89,00,0D,0E,38,5E,59,DD,22,49,8E,FA,DD,7A,5E,8A,53,CA,32,78,3A,65,2D,7E,B1,DF,F5,AF,6B,F5,47,CA,84,7E,A7,95,79,96,40,1D,1A,BD,F6,0F,E6,48,4D,56,20,DF,5D,5D,1D,F5,73,42,91,E5,5F,52,25,15,20,7E,10,1A,E3,7F,D9,35,B8,39,9F,32,DB,FA,7C,72,7A,FE,43,66,4A,C7,28,53,7B,70,1D,8B,EB,46,F1,BA,8E,73,88,BE,39,91,15,BB,DC,08,9B,6F,05,67,0B,B5,31,23,2E,35,06,C2,F2,8B,A9,15,07,B4,0F,14,C7,FF,7E,68,E5,C4,B2,AF,93,8B,6D,CF,DC,CD,43,BB,20,B4,6F,32,24,8F,96,03,FA,81,FB,2D,E3,2C,61,A0,FF,CF,B8,3E,48,09,1D,27,36,47,CC,A4,F3,A4,2D,7D,3D,E0,33,40,C1,7F,4F,9E,23,5D,51,18,7E,0D,8B,D3,BF,D3,1D,97,A2,46,13,F3,FF,94,19,DC,D4,C5,BE,67,71,D2,DE,B3,C1,60,3B,F2,10,23,81,2F,87,7F,F4,2F,D4,18,EC,B2,B0,79,92,5B,66,A7,74,82,04,83,02,3B,F2,16,50,E6,B7,F6,0C,CF,68,FE,42,BF,D6,B7,B5,29,E4,C0,B9,8A,72,68,D4,A2,DC,1F,CA,63,D3,92,7D,0A,18,2F,05,0B,B3,35,C3,72,3E,A7,58,84,91,F9,A0,8A,3E,71,C9,44,A6,42,61,06,FE,B0,8E,FE,D1,F7,16,8E,06,C3,DC,1A,27,EB,84,64,DE,CB,33,6D,45,07,DE,F9,93,E2,E2,13,71,17,CF,09,B1,32,AE,4F,08,FE,F2,98,B6,12,58,8F,19,08,1A,C0,4E,8C,E4,89,A3,02,DF,15,81,00,C6,B3,40,51,A8,BE,25,DD,ED,C2,2B,86,A3,F1,A4,DA,9A,EB,8A,03,53,90,F3,B8,F1,BA,91,56,DA,47,5C,AB,C2,93,11,01,34,96,9B,CC,E0,2B,F9,E9,07,20,23,37,D5,B1,80,A9,AD,30,1A,4F,9F,23,CE,A6,34,50,D4,A9,BC,C7,BB,58,2F,99,72,9B,1C,D3,09,D1,BA,02,42,D8,21,96,64,FB,32,3E,70,67,22,6F,73,32,47,28,17,F8,3D,ED,17,21,4C,30,C1,79,B9,0C,E3,32,DB,A1,CA,CD,E7,AD,66,BA,5B,C8,0E,C4,C2,E5,90,96,06,3F,87,D5,04,67,AB,D5,97,9A,49,E0,1A,89,D7,03,35,16,18,09,8E,DF,9F,91,E1,C0,DA,3A,7D,16,4B,13,33,03,D7,BD,3C,83,25,E6,6D,A5,B4,C8,8A,B6,8C,8F,41,0D,6F,74,FC,6A,92,74,FC,75,34,55,49,40,91,8C,C2,A4,ED,80,84,1F,78,80,36,83,57,AE,B7,8E,3D,5F,89,3F,FB,11,F6,21,8E,C9,26,A6,48,02,B1,81,1D,B6,A2,EA,8E,E8,71,90,08,BD,0E,2F,14,5D,3F,7D,2B,18,75,AE,55,60,27,07,63,D9,AA,75,A2,1D,62,4E,05,AA,16,6C,6F,95,38,67,B8,72,74,37,2F,0D,F6,26,5A,36,ED,43,60,2F,5F,E0,08,BF,27,36,77,FE,32,04,30,96,4E,6F,06,1E,4D,10,27,B4,F9,C5,67,5A,09,39,71,02,78,8D,F8,E2,4E,91,36,0E,72,97,5D,00,1E,4C,F1,F8,04,D4,6C,D8,D9,42,9E,DA,30,70,9F,1C,F1,C2,12,A2,0A,CA,0D,71,72,9E,6A,68,FF,CD,4B,B1,08,BE,E2,BB,ED,0B,E0,49,91,94,59,60,90,ED,EE,67,6E,C1,00,E8,23,0B,AA,A6,11,AC,77,FD,D9,19,A2,9C,AA,55,C7,E8,EB,A9,F3,12,B5,F3,C4,7C,CA,1B,BF,C2,17,63,C2,8E,6E,18,98,46,F3,98,93,7B,39,6D,E1,12,81,CC,E5,8F,86,B3,91,A8,A1,64,AA,97,A9,2D,DA,7A,5E,24,62,35,D6,85,08,5E,9E,81,00,93,49,1B,2B,FB,60,7E,13,5B,28,06,EC,9F,E0,77,20,CE,6B,05,B8,07,4C,F1,F3,18,64,4F,17,94,71,CB,72,EA,88,DE,89,EF,61,31,D7,B7,48,52,FC,D1,21,69,5A,32,24,7D,D1,F7,49,30,B9,ED,FC,54,9A,A9,E0,E0,BB,1D,B7,8E,0F,B8,E8,27,4D,B7,3F,15,40,88,DC,DF,31,23,59,B7,36,A3,AD,F6,43,E4,1D,AB,C7,BA,81,44,A8,E1,A7,C6,F0,6C,24,28,08,B1,63,58,CE,CD,93,30,05,0C,72,EB,B6,6B,5C,F4,27,75,25,30,52,15,FA,69,41,76,B9,02,F6,1C,58,B9,0B,59,DB,BE,AB,CA,38,51,9E,A5,80,5F,B8,97,58,41,50,2E,B0,E8,74,1E,6F,EA,7D,EB,71,98,48,A8,A0,BC,8B,D6,9F,62,A5,A8,DB,05,BE,91,19,AE,69,71,7A,0B,38,3A,63,89,00,F8,47,3C,9D,35,B1,8C,92,13,03,B7,28,A8,2A,8D,D7,FE,A1,0F,54,A0,18,F7,D8,2A,8F,BC,C0,81,FB,B7,1C,F8,0F,08,C3,33,CA,AA,EF,A7,C4,73,E6,03,D0,C3,90,65,AC,A2,AB,BD,0F,42,DC,13,1C,82,42,0C,D5,3C,F8,0F,92,2C,95,6F,12,25,88,89,B8,47,4F,27,37,11,45,3C,CD,74,75,DF,2B,EC,33,63,8A,53,76,4F,C6,D9,83,E5,E9,EE,E9,C5,0F,84,01,80,CD,2C,AC,11,A8,7A,77,08,AA,4D,BC,5C,6F,54,96,C5,58,3C,F5,F8,3B,13,F1,DC,4D,30,C1,B9,16,03,A4,FC,08,04,2B,00,DE,C5,EE,88,E5,60,F6,D5,AF,60,72,0C,3B,45,D1,B6,B4,EE,70,7C,F5,34,2C,1F,61,10,B0,40,CB,50,66,87,7E,3B,6E,19,B0,D9,61,8B,53,8C,CD,9B,34,BC,2A,69,AC,78,C2,1D,65,C0,57,60,C4,AE,18,BD,D9,66,14,85,41,01,8F,A2,66,BD,0B,05,DA,EB,14,53,7F,B7,1A,5C,D3,94,56,C3,A0,50,4F,8C,C9,1E,BA,DF,B2,A7,1C,30,BB,7D,D9,D7,52,3D,71,A6,D2,5B,5C,59,D6,B8,A8,51,09,EC,95,A1,B1,D4,A1,87,41,B4,C9,CE,9A,52,77,FC,EC,56,CC,A0,27,76,07,4B,09,A5,B4,37,5E,DC,85,E8,90,07,5C,A9,02,F4,E6,D7,70,36,17,74,E7,5A,AC,3E,26,F1,41,60,3E,CC,42,80,62,E6,6C,68,A9,32,AA,60,00,6F,A2,5F,3E,36,C1,E6,A0,73,6C,CE,A4,B3,74,F9,24,2D,FE,75,3B,B9,AF,EA,76,4A,3B,45,F0,FF,F6,9E,38,7F,6E,1F,4A,21,DB,C6,E2,74,E5,6F,2A,CD,DE,D1,AF,7A,38,2A,BA,11,79,92,A4,70,94,56,13,9D,A0,17,B5,A0,C0,66,9F,87,3C,CE,25,21,60,24,0A,F0,D5,0F,96,E2,F8,C6,08,07,8A,1D,FD,D2,C4,14,7A,B4,97,1A,FE,77,AA,C5,78,E2,AA,E4,C1,D3,70,D1,87,85,B3,97,05,33,F4,C7,83,CF,97,BA,94,6F,63,46,89,A4,8B,CE,29,CE,75,AD,A6,14,21,52,39,45,84,0E,9C,C6,60,47,46,0F,16,01,A3,D0,D0,5A,8E,A8,B5,51,E8,4E,CE,F5,31,FB,69,EB,7B,36,7E,DC,15,8A,79,B8,6C,CC,B0,27,67,D0,B3,A4,9D,9B,C0,FD,3B,B4,4C,C3,2C,88,53,EC,61,9E,E7,13,F0,21,56,74,97,7D,BF,56,25,7F,18,50,7B,7D,B2,53,59,C0,3E,23,D3,9E,B3,E4,D5,7B,AB,6E,34,82,66,2E,D7,80,3F,EE,DD,57,A5,3B,B6,9E,9F,17,96,74,0B,11,6B,F5,1B,45,F3,0E,6A,4C,F3,B1,50,41,0B,D1,EE,3C,52,30,89,51,F0,EE,24,E1,5A,12,FD,77,30,7E,EB,0A,D2,92,08,01,FE,40,CD,5B,B2,C7,F8,15,D2,06,50,1E,5E,22,00,E7,17,62,BE,DA,1C,6D,21,70,61,81,D3,7A,54,97,19,1D,C7,CB,B9,64,FB,C0,24,DC,3B,E6,00,12,D3,82,22,C8,E0,E0,84,FC,74,C5,21,CD,FD,75,4F,21,C9,6B,AB,71,F6,BB,C6,A5,72,8D,26,A1,81,92,FB,C7,BF,F4,A2,E9,85,B4,8E,00,BE,E3,FE,2D,FA,8D,5A,6B,AA,32,46,2E,E4,7A,C5,A0,22,C3,E3,21,BD,2D,50,63,82,73,75,E0,F5,93,D1,B9,A9,27,FE,BD,FA,67,5D,F7,5A,53,71,F1,22,4F,B8,A9,1E,BE,A0,7C,7B,DB,39,98,95,46,5F,BD,E5,93,FD,81,56,7D,AD,39,E4,CC,62,B2,15,62,F2,B0,7E,DE,A6,EB,69,30,64,8E,A8,D5,F8,52,31,D4,81,51,08,D3,4D,B3,E5,D7,10,A6,AA,A1,D8,6F,3A,3A,FA,62,C8,6A,A3,A0,22,3A,16,A9,72,C7,A9,A3,E6,2F,01,D6,28,6C,89,03,21,62,13,69,AA,CD,4C,49,62,BF,87,5F,72,B2,2D,1A,94,C5,62,0D,2F,3D,D0,10,C7,39,4D,DE,A5,D8,BB,85,98,0B,47,06,5C,8A,3D,E4,14,F4,48,BD,E2,3D,C4,3B,4B,FA,B8,01,35,6E,28,38,30,88,A4,2A,69,80,4F,FF,7A,E5,17,D7,30,1D,94,1D,1C,02,FF,C8,E1,03,98,4D,D7,30,DC,6C,9B,AB,EB,A7,89,22,30,48,06,A1,FB,FF,CB,DD,40,EB,E8,9E,2B,2B,A1,B3,57,AE,5D,57,EE,8B,56,EA,16,54,54,23,90,7E,94,FC,14,3F,0A,51,68,6A,FF,BC,49,D4,FF,15,7D,9F,84,EC,58,A4,4E,58,85,3E,07,1D,67,3F,D3,54,D8,63,D3,59,FC,D7,22,BD,B8,6F,1A,56,E4,AF,36,54,8A,7B,62,4D,6A,A8,12,A5,21,DD,1F,B7,E6,76,D6,A0,1C,8F,86,CF,8D,09,63,EE,83,94,5B,85,0B,CF,EC,DB,D5,A4,64,68,78,63,09,DD,6B,39,F0,0A,05,DE,B1,E2,43,56,FB,34,0E,74,4B,2B,60,87,76,4A,9B,69,BE,F5,DD,69,FB,E7,23,34,75,F7,39,AA,92,80,E1,7D,7A,00,B2,2E,91,ED,CD,CC,D5,1D,EE,D7,DA,AC,BA,4F,3B,77,09,67,7E,D2,DE,55,F8,2C,FD,A2,8E,1A,7E,4D,24,FA,BF,AB,01,19,13,2E,E2,10,C4,37,FB,C1,D4,9D,4A,D8,84,EF,EF,0A,39,FB,2B,37,F7,BD,48,07,A8,3E,4C,62,1A,24,16,B0,35,F3,E6,96,52,C4,62,DD,50,8F,2F,45,49,F9,F0,77,9A,25,00,7A,A2,43,AB,3F,FC,18,FC,D3,E6,89,12,F3,1C,A7,EA,FD,15,D3,EF,8C,01,36,B8,60,83,8A,2A,94,91,2A,7E,CE,91,90,FD,CB,91,33,D9,B7,CF,D9,43,7C,65,5D,32,23,A8,4E,25,AF,02,97,D6,D3,24,EB,9E,B8,D8,F5,EE,62,21,99,D7,19,D7,95,0D,F5,33,BA,8B,99,EA,82,D5,CE,07,9C,B8,73,FF,C6,08,AF,AE,A5,93,6B,E2,E0,F7,61,7B,E8,6E,63,56,80,F3,99,C6,4A,20,BB,08,5D,FD,7D,74,61,36,F0,20,DD,74,79,87,ED,8E,8E,7D,27,2C,F3,1B,36,8F,D3,2C,0C,DF,34,83,D3,81,DF,9E,9D,1D,9D,C0,DE,19,BB,72,65,02,D3,B5,F4,1A,66,1F,D1,3E,10,B5,04,88,D2,74,40,00,74,64,78,2A,FB,DB,E8,98,DA,16,B7,D2,BE,CF,B0,78,C6,87,B1,7F,99,75,53,F0,D0,15,B1,4E,0D,2D,E6,C1,6E,5C,44,CB,7B,60,16,4F,3F,0A,E9,8F,D3,F0,C2,3E,4D,80,75,DA,6F,61,B0,6C,7B,09,96,23,0B,09,E7,08,89,BB,D3,E5,FE,B6,F7,A7,72,E0,BA,88,8C,0D,1D,C7,83,2C,02,86,02,00,C8,BB,41,39,86,73,CF,67,A2,AE,C2,5D,D9,1C,6C,45,E7,1C,D5,21,0E,E4,31,85,84,3A,EE,5C,D1,F2,2E,CA,44,FB,07,AC,F8,EA,74,F3,23,14,C5,70,AE,8D,38,EB,D7,76,97,30,11,AF,0B,5F,4A,07,A4,EE,8D,B7,3A,EA,6C,8A,C2,BC,59,C4,80,26,9A,0D,FA,7E,46,A9,A1,8D,7B,70,DE,16,FD,2E,E3,DB,3C,D4,79,4B,C1,64,A7,4E,EA,F3,0D,9B,EC,C5,C3,4A,5B,57,38,20,22,A6,A7,47,DF,26,6F,AA,42,A9,4F,84,2E,1A,6A,FF,7B,C2,E9,25,47,DA,81,DF,9B,0E,8E,B9,4E,84,8A,B6,18,E0,1E,B9,11,3E,35,1D,6A,61,00,35,B1,23,E2,C9,03,D7,60,DD,B5,CC,CB,87,46,FC,FA,04,96,49,62,4E,6E,F3,62,B2,C7,8E,9C,17,8A,A6,61,B8,D5,B5,9A,39,74,33,60,A2,2B,8F,1F,51,3D,8B,06,C2,C3,72,96,B2,D7,5A,A9,FA,FB,68,33,9C,0A,DD,18,C7,E2,BF,3B,8F,57,BD,19,28,84,86,DA,13,DA,73,FB,0A,41,FE,B5,D2,AD,DC,06,89,9D,ED,18,FD,ED,07,69,7B,E8,5A,86,5D,7B,FC,52,68,27,C8,AE,90,69,A5,ED,36,D6,A3,04,3F,0D,15,DD,C0,CB,B5,A9,7D,36,3B,08,25,5E,E6,4D,58,01,F8,81,CC,01,55,C0,0C,F0,25,19,B5,68,48,D2,56,9D,5F,BF,86,E0,C0,E3,43,61,05,46,28,FF,45,E1,B2,C8,9B,B5,ED,F4,9A,B5,BF,FE,DA,AB,35,C7,13,9C,2A,77,8F,9F,01,D3,84,5A,DD,89,86,93,8B,B2,35,33,1C,BE,27,2C,96,63,D8,F1,33,8F,8E,47,DA,8A,0E,9D,17,ED,C0,94,57,8A,2B,EB,99,14,48,75,FE,44,2E,1F,7F,D0,90,12,0A,CE,72,D2,71,D3,EC,51,77,45,A5,5A,1D,92,C7,40,52,03,A3,AA,91,0A,9A,01,6E,3A,7A,E6,F6,95,7A,F9,02,AB,96,54,83,6E,CA,E9,E7,EA,6F,E4,1F,54,54,C6,38,F3,8D,CB,16,83,44,80,D2,5A,F2,99,8B,0D,A1,4B,0C,EB,3A,7D,88,2F,0B,DE,F2,F1,F5,94,5E,7E,9F,59,FC,24,FA,CC,51,DB,16,12,40,0E,88,9E,C2,59,74,1F,D4,B6,E0,18,70,62,9B,83,86,24,91,95,18,8B,1A,C5,02,ED,32,1E,E4,F7,74,36,5E,C4,0C,BC,D8,13,88,A9,8D,99,41,1E,DA,0B,1C,AF,7E,66,A9,FE,A1,F9,32,3F,8B,B4,B8,5D,5E,87,8E,85,57,64,93,1D,73,BB,41,F4,E8,09,D9,FC,7A,99,2D,81,6F,AA,07,25,36,C2,C7,56,EB,75,F8,5D,D5,50,12,63,C2,AD,D8,30,92,20,6F,75,6A,99,CF,10,85,61,CC,D8,EA,20,34,1F,E0,D4,C7,AD,FE,D3,BC,61,9A,32,1F,D3,D2,7D,DB,BC,B3,D9,E7,19,95,BF,F1,FE,05,45,03,65,A6,AC,55,03,0D,6F,FB,BB,4E,37,3C,B4,B0,D7,04,CC,D5,53,79,84,D6,53,41,6F,C1,94,AF,6B,1F,BD,13,92,48,BE,B3,1A,5D,0C,46,45,B9,9C,E7,02,92,FE,82,FB,5A,15,52,E1,77,B9,6C,33,91,66,AC,C9,1D,FC,D3,40,D2,41,96,46,25,25,43,10,93,8C,F2,95,B0,F0,B0,B8,C4,A3,11,E9,E7,F7,EB,E6,35,1C,1A,F3,53,9B,C2,A8,93,BE,00,B3,DB,16,C9,5F,0D,7A,F8,EA,FD,F4,FD,92,7B,35,77,82,C4,70,74,64,C6,92,8C,9F,9C,BE,B4,10,3A,FA,22,1B,A2,2A,D8,3D,F4,F7,DF,75,A3,34,B4,8C,47,1D,45,53,2B,C7,23,C3,39,D1,54,01,E7,D4,DE,63,02,A3,53,0E,42,1F,9A,8C,50,F6,3C,7E,99,93,4F,96,69,0B,CA,D1,99,B7,E8,2A,B7,2D,A2,06,31,08,5B,17,46,DB,75,79,E5,50,0F,BE,49,3B,E3,98,DD,87,61,AB,61,98,85,D0,80,A5,64,5B,86,C4,21,1E,1C,3E,91,1A,6D,21,32,55,8D,AE,5A,52,06,36,34,A6,23,56,58,2A,88,14,59,A3,6C,C7,D7,75,66,92,29,ED,E3,BD,02,35,A3,BA,01,4B,90,48,97,79,4E,57,6D,9A,22,FE,D8,FF,1F,39,B9,03,85,4C,4B,B2,3A,DC,4F,AC,EC,08,4F,4F,B8,4B,73,38,A3,BF,71,5D,50,E5,FD,3F,12,C6,35,8C,4E,26,E1,2F,6E,D8,95,E7,A2,B7,34,77,3F,6E,D1,61,D0,AD,C2,EB,72,2B,3D,4B,A7,85,BC,6A,F4,5B,9B,B5,7E,E7,5B,CD,63,8C,3D,66,D6,E1,CD,48,DC,4F,C7,89,71,3C,25,96,D5,AC,70,88,D2,2E,DC,B8,44,FA,F2,C8,DC,D1,6F,27,78,67,1E,44,17,41,B4,E9,4E,EF,68,20,35,53,58,06,24,2B,07,67,12,ED,1A,54,53,A1,B6,DE,9A,01,F2,EF,75,BB,3E,A9,D1,45,05,15,0D,04,F5,CE,7F,C4,B9,CF,5B,9A,4C,2F,E8,41,92,2F,58,90,B1,E5,93,9A,F0,D5,8D,CF,41,FD,D3,87,DF,27,E4,CF,C9,FE,89,CE,B6,F7,D0,92,FF,97,A4,8B,BE,E9,C2,61,B9,7E,69,A8,64,37,F1,C1,A1,B1,E0,EE,44,36,E8,ED,ED,2E,1B,AF,A9,44,A8,6A,3F,0E,7C,D0,E4,A5,54,01,EE,19,35,B6,E0,8A,E8,1D,2A,4A,66,8F,07,32,F4,E1,71,38,51,1F,55,7F,D1,01,CD,CA,27,27,89,54,60,6D,44,C5,82,EF,5F,68,47,ED,6B,45,6F,47,70,A1,B8,37,A5,DF,A4,0B,45,3E,D2,A4,A8,C6,69,6A,44,87,C0,D2,83,8F,57,D6,D0,4F,97,55,A3,00,5D,08,2A,DD,0C,A2,F0,34,21,D7,AB,85,20,9E,05,27,51,F7,54,61,6E,40,BD,15,EC,10,9F,26,6D,90,BE,37,3B,6C,38,F1,5C,CE,54,1F,31,E5,C0,00,74,85,A4,AC,D4,83,84,C1,78,09,53,0D,86,E1,9C,32,CE,F3,F6,53,55,67,6C,41,8F,99,A0,47,23,E1,4E,27,E1,11,6F,86,AB,7F,AC,72,22,2E,E2,3C,4B,91,B3,80,24,21,82,BA,1F,7E,75,F2,49,7D,97,A0,83,46,FA,47,66,38,1E,42,0E,E6,5D,C9,A0,70,BD,5C,6E,D2,B8,A7,2B,50,85,9F,B4,BB,68,C0,7C,CF,FE,7E,DE,AC,5E,C1,D2,73,64,4E,9D,56,4D,8F,BE,9B,2E,DC,87,78,63,B2,50,9F,9C,DF,8F,90,16,C4,14,53,FE,56,12,B6,24,52,2A,0C,50,89,32,7B,B9,88,04,2E,17,66,AB,97,24,53,15,A1,E9,86,79,68,46,7A,38,0C,B8,FD,3B,55,30,D8,82,FC,18,5A,07,A4,D6,68,08,F7,E2,07,29,E9,C8,77,D6,83,EE,55,00,66,28,09,A4,06,98,7B,60,F4,11,02,B2,F1,D6,D2,EA,46,83,AC,DE,03,F7,0C,F0,EA,9C,85,A4,76,E3,DF,30,48,82,30,0C,B4,10,21,FD,CF,CB,F2,68,E7,A5,F3,5D,F8,25,38,FD,94,D9,A3,49,7D,99,9C,B6,49,B5,98,9F,89,F8,54,5E,22,9D,93,64,3F,3B,87,BD,62,4E,02,D0,29,32,C1,E6,8B,77,AD,5A,BF,2E,E9,2B,41,81,89,09,88,E7,92,06,CD,F1,1B,37,01,EF,9C,40,A1,20,AA,C1,3C,9A,65,14,1B,5B,1E,2E,94,FB,AB,BA,C6,61,F5,40,89,37,9F,96,0B,DB,F2,2E,C4,C5,DE,C6,8E,70,86,9C,7C,BD,C3,A2,83,90,6D,20,23,98,B7,D5,23,47,08,61,D8,AC,61,E7,EA,9A,CD,39,5D,44,7D,A5,10,52,2C,2D,6A,25,34,00,44,00,81,5E,E9,1A,82,8A,0E,A7,70,C7,6E,FE,D4,FF,BD,73,35,20,56,0D,54,2B,DC,36,1E,48,42,49,CC,05,14,31,5D,1B,19,FA,97,84,FD,66,8F,79,53,E0,E0,E9,33,AB,7F,12,5A,48,E8,38,4E,62,27,73,64,8F,7E,63,03,96,FD,CE,0A,9F,E0,94,0B,7A,8C,89,EC,E0,73,12,DD,D4,88,44,3E,D2,13,CC,FD,26,A1,EE,CA,F9,8C,26,5A,58,F5,FC,2F,48,07,E3,5E,E7,03,11,A1,55,9C,BB,49,C4,EF,63,17,46,A4,CE,1A,7F,F4,03,7C,A4,D5,54,4B,9B,29,99,9D,C6,9A,A3,8C,C1,4D,34,39,57,DC,E5,11,80,0F,DD,36,DF,90,3F,2A,5F,0D,77,AE,37,04,EF,DF,80,63,77,66,B4,55,86,13,53,8D,07,D8,34,C1,F4,71,6C,1D,24,5E,9C,77,88,20,D0,67,67,B5,20,FB,F4,58,D4,E9,22,94,E4,EE,4D,97,85,7E,E2,FC,F1,B9,EA,C0,8C,86,6A,85,4E,FA,D7,21,44,C0,70,33,0F,07,37,D6,12,68,99,8A,FB,02,52,93,B5,05,4E,1D,42,48,73,98,4D,CF,97,2D,5C,FF,B2,58,1D,AC,CC,5E,2E,F4,A7,A6,EF,03,8D,1E,E3,43,DB,6A,9A,4E,C2,30,6C,DC,19,6E,AF,E0,D4,E9,89,2D,56,DB,29,F2,89,00,C4,1D,41,8D,46,6B,36,78,FA,05,9B,0C,22,39,05,0C,01,CC,92,7A,8F,97,6C,B9,57,97,8B,52,37,8E,2A,E3,E3,61,8C,EA,85,DE,84,94,55,4C,2B,CB,57,E1,82,12,04,B8,C3,88,EA,0C,B0,98,2E,4D,75,F4,61,F3,FE,18,26,5E,B3,FD,42,B2,FC,8E,94,9A,84,56,35,18,4E,F6,50,06,A4,86,61,D7,33,DE,E3,3C,7C,12,38,51,CD,A2,6F,F3,2A,D6,71,37,2A,69,AB,6A,B9,18,6A,37,DD,58,9A,93,D6,4B,07,A0,B0,EC,D9,0E,B6,D4,5B,F0,BF,D7,37,ED,58,93,F7,21,6E,24,B1,A8,3C,35,CB,41,CD,5F,26,0E,52,58,07,CC,E5,B2,C3,98,5F,CE,31,29,5C,01,B1,DF,FF,B4,EE,0D,A4,4F,E0,CD,74,62,D7,DF,11,A0,EA,B8,98,62,89,72,15,51,3D,DE,FB,F3,31,4E,F6,CF,29,C3,12,32,45,B4,BE,FE,32,0C,8D,F1,11,75,64,D0,C8,FB,52,20,29,73,64,EB,BA,EE,8B,7C,C3,19,8C,C5,AE,07,AF,32,07,9A,8D,D4,19,8C,2B,D0,7B,E0,E7,39,8E,AA,60,79,D6,52,A6,43,AC,9A,3F,25,60,2F,1B,4F,C2,ED,80,9E,B2,C8,6F,DE,7A,9F,B4,26,93,B7,22,13,14,41,CE,2D,F7,B5,42,C9,AF,54,E9,63,8E,88,33,9C,D6,91,96,96,6C,5E,3D,0C,7D,E2,07,74,2A,EA,7B,18,CB,0B,09,FE,D0,58,7B,A9,DA,1D,BD,68,72,53,C3,60,06,A6,71,96,B8,D4,06,3D,C2,77,B3,65,61,6E,D1,FC,C2,23,EB,1F,C9,9C,12,10,0C,A7,0F,00,96,32,31,BB,82,B8,35,83,D3,92,28,5D,27,BF,DF,15,DB,B6,D4,9D,C3,BC,B1,8A,B6,34,C3,61,AD,43,60,54,94,E9,21,7A,D7,E5,3D,5F,F6,A7,42,8A,7D,E3,F3,56,B8,22,A0,FA,87,6E,81,DC,5F,DD,53,77,99,B1,A7,E2,63,AF,5A,99,BC,D3,6B,8A,38,04,E4,28,90,A7,F4,F0,77,3B,33,9F,E0,9B,12,D3,A5,9F,EB,8C,44,9A,93,C2,ED,FC,EA,E3,E8,6F,23,80,5D,E4,B1,B1,05,12,12,87,41,C7,E4,43,44,52,C1,A7,A2,ED,BB,8C,17,23,6D,5B,71,A1,1A,09,3A,4B,5C,47,79,16,16,B1,2F,AF,41,4F,95,3F,11,1D,CE,F3,C6,96,D2,3B,8C,84,43,E6,67,5E,60,29,50,00,FD,6B,D7,59,D0,FA,D4,F9,01,33,F1,8E,29,C7,35,62,3C,7C,85,44,24,B9,36,8B,BE,22,81,02,5C,06,58,6A,61,72,82,15,2F,E0,21,09,CE,03,D8,77,85,C0,5C,99,CE,F5,D3,E7,2B,49,17,2E,CD,39,97,EB,A2,86,1F,B8,F3,1B,C9,0E,32,5B,44,EC,13,AE,4C,01,D2,87,32,27,0A,5D,21,4A,57,58,C0,E4,15,19,7F,C5,6C,E4,96,63,3D,5B,45,56,81,83,CD,09,2C,4A,CD,FA,79,60,0E,C9,F1,85,0E,9A,1A,A0,34,C6,75,8E,93,10,CA,14,46,FB,9D,75,79,96,A4,A2,3D,A8,3C,EC,00,5F,6E,37,8C,3D,F6,13,06,ED,26,AF,40,47,82,79,F3,15,FA,2B,5D,37,88,F0,DC,33,FA,30,C6,27,13,5F,10,DC,59,AA,9D,57,E7,CF,37,86,8A,F4,FA,89,2D,18,A9,81,C0,31,DF,62,1C,2B,09,61,B6,42,8C,83,8B,9D,2D,25,D9,1E,2B,4E,58,46,10,AF,A0,08,E4,DC,77,89,84,7A,7D,D0,E3,58,52,78,66,97,12,14,3C,B5,48,1A,1B,11,56,6E,0F,6E,1A,3F,CD,87,55,A3,B4,2C,20,21,7B,34,4D,CD,92,5E,52,23,13,65,11,F3,E0,44,60,83,F4,1B,AC,D3,44,12,61,25,DB,18,FD,1F,3A,6F,3A,C5,A5,3E,03,07,99,79,5D,0B,4C,07,3D,D7,F6,E3,A4,44,77,B5,0F,EA,3F,81,F5,E4,C9,14,99,64,2C,F1,E4,1A,0D,D6,D0,97,77,9D,A3,70,EA,D3,12,06,C8,3D,9B,3D,14,45,1B,7F,0F,1E,C5,4C,BE,85,2E,4E,BF,92,94,48,ED,CC,2D,42,A3,43,E7,FF,A1,95,80,E4,BB,A1,81,C0,AF,1F,7F,B6,83,AC,D3,C2,A3,D2,3C,EC,98,B4,26,DB,C7,62,69,B6,BE,EA,E3,DB,FB,61,1B,69,10,AF,BF,A9,7D,C4,1F,E8,B9,B9,94,59,30,E7,DA,1B,BD,55,1C,AC,2E,11,E3,CA,33,AF,13,9D,29,C0,ED,12,62,ED,0A,41,D1,4E,AB,7B,79,CB,C6,B1,0A,25,03,8E,31,07,25,45,A5,D5,44,CD,0D,DC,89,58,BA,13,50,F4,D9,8C,E5,56,48,0D,0E,CC,75,66,9B,FB,2C,0F,B2,9C,0B,6C,C0,A0,55,73,E5,80,7B,8B,F4,C9,5F,21,1B,DC,E7,8E,F9,3B,18,94,DC,C7,63,A9,BB,6F,28,95,9B,39,4E,E4,8D,17,F4,A1,95,3F,68,D4,A3,8F,52,FB,8D,D2,30,ED,1A,DA,B9,66,33,73,B9,98,A2,03,35,7D,35,3F,15,89,2E,99,30,54,2C,53,CF,83,EC,41,29,DD,34,B9,64,0B,38,5A,0E,73,DF,52,67,6D,EA,91,D7,73,95,47,4E,F0,86,A1,E7,E3,EA,48,7B,49,76,06,A5,83,C3,EC,C3,E1,45,D4,60,31,62,9B,3A,E6,96,A5,54,A2,9A,5E,E2,1C,1A,86,3B,6A,D9,FE,D9,47,BB,E8,D9,84,69,3F,2A,86,A2,87,73,17,9E,43,0B,FD,85,A5,F6,F1,60,32,C6,33,62,28,AC,88,A8,04,15,D2,CF,6B,43,13,D6,58,62,DB,16,8A,31,9F,ED,2E,95,A3,C6,EA,CB,A7,67,92,DE,F1,00,BB,51,17,81,85,BB,EE,A6,30,D9,E1,AD,8C,39,90,B0,E9,D6,4D,61,16,AE,AE,B0,CC,C4,9E,00,1F,28,C5,14,FA,1C,89,BD,1E,05,A3,C5,57,23,8C,50,D6,63,69,0F,E1,DE,DE,CD,81,6B,D8,FF,3A,76,D9,BB,12,D8,5C,CC,F1,D8,97,D2,79,5B,70,23,E3,1F,5E,DB,67,1A,FC,F0,1A,63,7C,D5,C8,5D,81,24,F5,48,E6,14,86,40,D3,19,5C,06,69,35,4D,16,D3,54,CD,23,93,0B,7A,E9,0E,B1,82,FD,23,02,4F,10,51,2A,99,DF,48,99,50,4E,30,C9,EF,BB,11,49,E3,F6,1B,9C,9A,7C,4F,73,3C,79,7B,F6,6F,CA,67,A9,AB,CE,D3,33,58,BC,FD,C1,B3,B5,66,B5,1B,EA,A2,79,D8,4F,08,DC,85,D4,68,E3,15,0E,AB,E8,AA,06,1C,BD,A8,EC,E4,F4,52,28,00,20,F8,C5,80,A0,DB,4F,BD,A0,15,9E,FB,2E,1A,ED,55,1A,36,E7,59,E2,30,D2,B3,7C,E3,29,D7,DE,37,4D,5B,D4,12,3F,1D,46,7E,12,E1,9B,F1,88,9E,24,D1,8E,0C,68,D8,88,F4,2C,DD,40,2C,35,7A,C8,E1,22,B0,BB,B3,AC,B6,3A,9D,55,1E,85,BB,9D,AD,42,B0,CA,79,E4,FE,67,16,47,D5,F6,9A,61,B3,F4,C9,9F,FA,B2,BE,24,B0,2A,DB,7D,D4,CA,98,2F,C0,2E,43,A8,22,CD,E2,34,BF,98,DE,16,36,05,54,7B,D4,0C,5C,57,7A,F6,71,60,D2,7F,29,9A,5F,A4,38,2B,15,83,28,5D,EE,BC,EB,27,C5,9E,C6,73,F9,C6,24,58,43,6A,70,7E,55,DA,29,B0,65,C4,03,1F,CF,96,B8,78,33,41,33,6D,58,C4,24,19,83,D6,DB,00,7A,0F,12,D0,6A,0E,50,EC,34,66,E4,01,90,D4,3B,35,0C,61,68,14,0B,4F,82,CC,A7,2C,98,B0,E9,5E,65,10,8C,C7,F5,1C,38,3E,0D,74,99,08,1F,A6,9C,CB,D0,FC,16,C7,C4,26,84,19,48,EC,51,9A,61,84,ED,4C,84,50,57,5E,50,0A,25,F1,9B,64,9B,DE,AE,4F,1D,02,61,30,77,FC,49,B3,4B,9B,E8,96,14,E4,28,79,8D,68,F6,64,12,E9,BE,68,58,CA,AC,5D,90,31,89,A6,DB,B2,1D,AD,0E,10,49,06,2F,5A,85,4E,B7,7C,87,AC,95,44,09,B0,88,AC,AE,E5,79,2E,2F,20,56,A6,94,85,74,2A,1D,CC,8E,3C,95,FA,33,45,22,8C,7D,D1,2D,01,9D,1D,35,DD,96,4C,CE,F3,14,6B,9C,9B,9A,9E,F8,5E,E7,C2,68,E0,9D,4B,32,FC,87,1A,4E,C4,1F,E0,ED,05,C5,C1,72,61,F2,8C,47,7E,7E,20,9F,5E,83,BC,68,60,F0,8C,59,CC,09,6D,1C,BF,D5,69,42,15,2B,55,50,B7,7A,62,E4,29,A7,88,5E,13,73,98,35,AE,E9,B4,9F,B6,98,CF,9C,EB,D4,47,5D,49,7D,A2,2D,23,89,54,74,EE,9C,8F,E0,DE,5B,AD,49,E6,57,BC,35,32,83,1F,9C,31,8B,5E,C1,26,65,21,3F,7D,C7,F9,0C,B5,0A,91,CC,1B,86,60,9B,F0,08,62,88,31,46,74,5A,D3,18,B1,7C,38,3D,F6,17,97,1C,7F,33,7D,00,B9,14,CC,EE,20,8E,02,3E,3F,F7,63,8A,C9,CB,4E,C9,3E,7E,16,5A,73,F3,A0,83,CC,85,2E,23,EA,1D,3F,B9,3D,1F,19,F1,3D,3C,3B,81,2A,68,C5,24,F9,33,86,3D,6E,F5,7F,62,42,11,FC,F9,02,59,FA,C2,AA,03,65,91,54,74,E6,BA,EF,CA,92,85,61,64,4D,CE,08,52,2D,F3,61,EE,76,57,2A,9C,44,B8,D9,51,77,4E,19,CF,87,D5,5D,22,35,9E,87,98,FC,2C,FE,02,8E,E3,2C,DA,95,4B,72,8D,46,11,C1,49,F1,42,68,1C,36,36,1C,86,9F,D5,15,0A,37,9E,A2,E1,C3,55,64,5F,C2,CF,56,0C,8F,8E,D2,E1,F3,99,77,F2,69,FA,43,39,27,A9,B9,55,56,A9,F1,39,2E,05,CD,1D,C1,67,25,AD,78,A4,94,BA,55,66,4F,D8,7E,97,B6,DF,41,06,B8,79,31,DE,4B,EA,85,8E,1C,EF,4A,82,4D,9A,0F,A2,0C,C2,46,5F,B4,2A,F8,01,DB,C4,54,52,34,6C,9D,99,7C,4C,22,E4,DC,B5,B5,CD,9A,20,9D,5E,00,C8,18,0E,CD,88,0A,F2,6F,0B,28,4E,FB,16,13,1C,CD,05,10,3F,16,7C,19,72,30,A8,15,FF,86,89,FB,F1,3A,4A,B9,BD,63,08,0C,03,18,FE,BD,75,3F,12,2C,46,C5,35,A3,F3,76,9D,66,BA,41,28,4E,97,47,D9,B8,C3,8A,E2,21,9D,7D,74,18,88,D3,8B,B6,9E,1B,6A,C1,CC,DC,52,1D,DB,B3,C0,7C,B1,34,90,48,7D,12,47,3B,19,3B,B2,43,0F,5E,43,5C,2C,1A,09,DA,D8,67,39,5C,70,17,3A,26,A9,CE,A4,B0,AC,72,25,E4,2D,5E,83,8A,08,81,B8,21,B3,54,6E,09,32,2C,8D,92,ED,80,E6,DB,23,A3,CC,C8,34,8B,06,65,03,54,DB,98,04,41,54,63,41,BE,63,54,21,06,4B,0E,3D,EC,2B,17,0F,00,97,9D,5E,41,FF,B9,4C,C1,2B,4D,56,B3,75,36,2B,7F,AC,3F,A8,5A,AC,7D,09,9A,83,B0,17,C4,74,8E,11,CC,7C,3F,78,A1,54,AB,B5,40,B7,7F,87,4F,F6,37,0D,45,FB,EA,4C,50,3D,E9,9C,DF,E7,55,4C,A8,28,37,EB,C5,26,B1,57,39,34,A0,42,10,90,9F,5C,80,A4,9C,D2,EA,99,38,76,CD,16,F0,A2,95,8F,E4,A0,97,D2,6D,61,71,2A,8B,36,A7,EC,A3,D3,59,55,0A,30,99,AA,E0,C8,83,AB,96,2A,B4,2A,D1,4D,48,C3,5A,CA,80,8C,E8,62,62,C8,B2,41,D4,73,E0,E2,0A,38,12,37,A9,88,27,8D,96,F9,A1,28,00,A4,BA,68,C7,32,2C,80,B8,78,34,C2,1A,16,60,5F,DB,29,17,73,35,08,82,6D,15,B1,DE,B4,43,FE,75,CF,97,FE,C5,15,9F,88,3D,8C,9C,57,67,59,6C,53,EA,2D,A8,22,ED,CA,26,F6,F6,3C,07,16,A0,1E,26,8E,47,CD,3B,7B,CA,CF,AA,CF,AA,29,ED,23,53,CB,80,95,77,90,D6,C3,F9,5B,75,F4,5B,65,29,BD,B9,40,51,8D,66,A3,46,77,9C,A9,8C,B9,7E,3F,F1,31,DF,E4,57,FE,54,60,D2,F1,0C,D8,F4,5C,B2,8C,38,5B,00,EC,C0,07,F4,59,24,7C,C4,63,2D,2F,6A,89,84,A6,88,A5,1A,F9,DD,09,01,F5,DE,6A,B4,7E,5C,7E,50,03,0F,6B,3D,CD,A1,46,2A,51,7C,36,59,85,6E,76,6D,DE,26,CF,D5,2F,38,29,3A,5F,66,AD,57,89,1A,97,CA,BC,AE,8D,85,4E,E9,A4,AE,10,AE,B7,CF,45,13,0F,1A,96,78,74,E0,12,73,97,00,0F,25,B8,82,DB,65,36,A9,2B,8B,35,87,BF,EC,C0,F5,2C,38,99,29,AF,E3,46,D8,F8,1D,34,DB,9D,C0,E0,5A,11,62,70,2E,C4,34,8B,EA,4E,9C,55,25,11,08,21,10,67,0D,2A,13,08,1B,E7,EB,C9,DF,5A,FB,46,21,E0,3B,ED,F0,71,63,D7,A4,04,27,38,9A,27,D2,A4,DC,48,AF,AE,2F,A1,E3,DB,45,2C,CB,1C,94,3F,DF,1A,C5,C1,87,C7,CF,2D,92,8D,36,C0,A4,22,86,59,66,D0,2C,1F,93,C8,82,09,40,4F,1A,14,75,D4,2A,14,7C,D2,98,FA,5E,80,42,86,4E,CC,8B,28,FC,CA,58,03,4B,A4,85,C5,AF,37,22,1D,71,9B,38,54,AF,4A,AA,84,F3,97,B5,7A,FF,38,BE,F6,7C,6B,E7,B9,F0,1F,CA,78,2F,93,4E,DF,65,91,86,F8,6C,28,B2,2A,CD,AD,5D,6F,E8,CC,C5,20,65,C5,89,2F,C1,A7,52,7A,25,30,A6,E3,FB,6A,CE,84,A6,2D,D6,22,F2,10,30,E2,8E,C9,8D,B9,DF,27,E8,A5,51,05,9E,3E,7E,FB,4D,23,06,53,CA,5A,E2,FC,38,E0,D7,1D,A1,54,49,4D,14,1E,2D,78,06,9E,87,96,74,5A,7B,79,44,98,F5,89,56,80,72,4B,C1,3F,82,8B,61,A2,A8,EC,80,84,BA,EE,55,64,CF,6E,E7,FF,CD,B7,DC,E8,1B,44,F3,F4,EA,2D,BF,2E,3A,37,78,BC,67,EF,EE,AE,51,BD,D6,C0,41,0F,39,9F,1D,7B,AA,7E,4C,40,EC,0D,1B,A1,6B,AD,40,38,90,C5,59,CA,38,6D,62,22,4A,B4,A4,F0,17,73,8E,0D,B1,6D,D7,8E,10,1F,BE,A8,3E,4B,AD,C4,07,DA,03,C1,04,40,93,EA,D2,EB,3D,12,B9,83,47,EA,6F,AE,5F,F8,CD,A5,3F,26,25,4B,9C,20,D0,46,46,82,6F,16,98,6A,BB,B2,D1,E1,0F,30,FE,49,75,86,16,59,6E,81,36,BE,33,EB,D5,69,55,07,D8,C9,3B,1A,21,45,AE,DD,15,ED,41,98,4D,5D,36,AB,25,D4,42,ED,AE,C3,E3,0E,D5,5D,E1,AF,B6,A2,74,7D,B3,99,09,B1,C6,4B,F9,F2,63,5F,8C,13,2F,3B,48,CA,1F,8C,0E,1B,0B,32,C7,B5,06,B9,15,76,2B,BB,39,6D,BD,C1,54,D7,0F,EA,BC,A6,DA,B1,35,7C,BB,E8,C4,80,B5,21,F9,4E,6D,DB,44,50,7F,99,4C,A9,3E,CF,40,6A,7C,C4,8E,AD,15,25,6E,06,9A,89,7D,90,6A,8A,BB,B6,93,3D,94,A8,AF,0A,9D,3E,C7,34,96,CA,C8,59,20,02,2B,F2,06,CF,0B,50,A7,37,C8,7D,6D,F7,3B,61,51,4E,A2,43,4C,E3,5F,73,FA,0F,8B,93,11,6D,FB,BF,C8,E7,5A,F7,FA,F2,87,8E,0F,24,6C,C3,F5,73,D3,C8,5D,45,F9,76,24,AF,EC,E6,A4,7F,F5,30,65,7E,72,1F,3C,9E,24,B8,21,7E,B4,8A,C5,81,49,6C,84,63,11,C9,C6,E4,45,89,47,B1,58,E8,DA,4C,E1,AB,CD,E6,3F,8C,6F,C1,E5,A0,C3,82,19,0D,CB,35,CE,73,41,D8,15,36,5B,57,D5,6F,CB,55,8C,AC,ED,40,23,DD,D7,9D,BD,9E,93,4F,4F,91,E9,C8,AE,FA,6C,7E,1E,CB,45,41,89,D6,A5,97,5C,4C,A8,24,5A,DE,AA,CF,A2,41,55,FC,BC,9B,58,E1,E1,91,AE,5D,5D,C0,63,96,1C,63,54,A0,EF,CB,0F,EB,12,A3,00,05,E9,8A,F4,8D,68,E3,C4,54,E8,CA,A9,A5,65,A8,58,CF,C2,76,4C,B4,23,EC,00,FA,66,94,A6,8A,57,D8,4A,24,EC,95,5E,1E,45,AB,11,3D,5D,01,0E,DA,A4,AE,2A,D6,E2,ED,C3,F7,B3,A8,31,2C,7A,A6,40,4A,60,B0,20,57,A3,68,27,5A,2E,21,F1,22,6A,E5,5D,37,EA,B7,C2,23,52,46,0D,13,5C,F9,54,FA,2C,6F,22,04,0F,E1,93,DD,10,9A,D3,81,76,42,52,36,7F,6F,DB,BD,9F,1C,5C,FC,4E,73,63,17,91,BA,31,79,BE,5D,0F,A6,65,3B,D5,69,C3,DC,E6,9D,77,9C,54,E5,A0,EF,91,5F,FE,9A,E5,BC,3B,AE,F6,9C,5F,61,CC,46,59,FC,4E,69,C5,F8,F8,42,B8,FA,61,41,C4,5C,ED,B1,4E,DD,CA,32,B4,1C,19,8C,68,D3,1A,97,8B,9C,08,C1,75,BD,20,2A,17,8C,64,C0,55,12,A4,D3,63,8D,85,36,DB,A2,D9,CA,99,91,AA,80,79,6D,13,C5,16,AC,DF,7B,55,50,9A,47,38,83,E1,F8,FC,C1,0D,6B,DD,D9,F3,4F,AB,68,04,B3,3E,70,0E,FE,2E,D2,92,66,BF,3D,B6,7A,B9,F7,45,9E,04,F1,72,03,DD,F8,11,15,AA,EF,73,3B,B6,2F,37,DB,91,59,A5,C8,56,85,C1,4B,88,40,EB,8A,31,E2,60,4D,25,62,AC,12,7E,4C,F1,EA,DF,14,B1,32,E8,DA,7B,01,17,CD,5C,2A,A8,BD,E0,48,69,23,2D,48,0A,F7,31,A8,E6,48,AB,20,2A,E6,E3,5E,3A,E4,FC,A7,B7,2E,52,9A,1F,70,33,CB,12,83,30,74,15,E4,5F,21,6E,1C,18,BA,37,D8,3F,BE,C5,FF,53,20,27,BE,2A,9B,36,79,CA,B5,75,68,BD,BB,AA,3A,29,2E,70,61,FB,4A,7F,74,9B,EB,96,35,08,AF,30,8A,81,64,F4,31,80,49,CA,51,68,C7,BF,DD,42,81,6A,1A,8C,21,5B,BF,E4,D2,B7,75,C7,55,90,0D,C4,3A,87,83,A0,99,99,C7,DC,9F,73,43,D6,97,02,57,60,C4,4D,F1,95,52,84,A3,FC,F1,FA,B3,DA,7D,36,E6,52,4E,AA,67,3E,CE,24,47,D7,86,1A,09,04,4F,04,9E,51,06,8E,66,61,B6,C4,E7,77,87,13,8F,5D,18,ED,0E,A8,2A,BA,62,F8,70,B8,09,1B,F8,24,F8,4A,49,75,40,F5,1F,E2,0B,53,21,B3,59,DB,3A,75,01,54,70,3B,DD,DC,75,7A,29,52,27,79,24,5C,0B,43,10,61,74,D7,9A,8A,1F,08,2F,09,31,0F,B8,36,4F,89,51,2A,83,64,1B,A7,EE,FC,B6,C3,98,80,57,CC,A1,03,EF,43,11,61,E0,54,3E,3D,72,DF,DD,BA,7C,EC,51,ED,A2,47,C4,92,BE,59,57,FE,C7,83,5A,92,3C,46,97,68,4C,FD,BE,15,46,4C,F5,43,55,C8,8F,8D,C4,25,77,E3,D8,D9,97,B9,79,64,06,5C,AA,83,6D,78,F5,B5,BE,D7,02,81,B0,25,A6,B5,D0,AD,20,D9,06,4F,9B,60,F8,86,F8,7D,A8,C9,CF,F1,BD,5B,73,C4,BF,7E,0C,B3,EC,AE,1E,39,B4,ED,80,DC,E8,F9,48,3B,74,BA,2F,99,F2,84,21,92,9D,A3,63,05,11,51,BE,E1,1B,19,B0,75,57,0F,DE,48,19,87,00,2F,B3,57,C6,74,0E,BE,B9,C9,3E,9C,5B,21,73,35,CB,FA,F1,8F,81,AB,5B,3C,61,2D,92,EE,B5,B8,CD,04,79,49,86,A6,D2,E6,80,93,E2,F2,98,12,F6,C7,70,1C,D1,20,2F,A9,53,CF,FD,28,9F,E4,84,34,A3,94,37,2A,47,2C,DF,E3,A9,E2,EC,38,39,D6,18,61,3A,4C,EF,EA,DA,94,A8,49,EC,43,65,43,DF,BC,C2,87,4B,2A,77,ED,0E,12,3E,46,F7,F1,EE,B0,39,C6,E5,0B,E5,0D,2E,31,A4,14,BB,26,21,B2,7C,BA,87,27,02,BB,F3,1C,AB,FA,27,30,D0,3C,1A,B4,57,39,0A,F4,A9,3E,AE,24,D8,1D,73,F2,1E,E3,78,68,AC,77,CB,A4,60,4D,2F,1D,51,88,E9,D3,BD,CD,6C,55,8F,21,DF,EC,9F,D8,6E,1F,1C,F3,38,B3,7F,9D,17,AA,D3,25,57,6E,4A,E0,CF,DB,17,54,5A,17,43,BF,A1,9A,54,07,B5,67,CD,23,C6,16,8A,9C,AE,84,81,6A,06,6A,B8,28,CD,B7,9C,C8,AD,9E,67,DA,02,40,96,6C,B3,A4,C7,0C,B2,F9,42,63,62,69,C9,24,D8,2E,91,FF,C9,B9,8F,68,B9,2A,4B,73,02,B3,C0,01,29,4E,46,D3,6B,7C,48,E8,23,6F,D3,F8,75,EA,C2,BA,41,2F,15,26,67,FD,E7,EA,BB,C2,F4,9A,F9,93,21,48,97,58,10,39,06,3F,93,FA,1D,5D,5E,40,29,40,52,44,C4,F9,7C,D2,CD,C4,83,40,69,38,05,CF,52,F4,5E,0D,88,71,F8,41,0A,23,C8,FF,58,C2,8A,F5,AE,3E,55,CB,C8,CE,F8,82,7F,1F,86,32,4D,97,3F,99,A4,19,43,D5,E9,FC,71,1A,A4,02,9B,65,17,DC,72,7E,95,4F,32,D5,D7,37,B3,BF,DE,83,A1,27,F7,6B,02,1B,75,25,F7,F8,93,71,8F,0F,8C,DD,11,F4,E8,00,11,84,80,72,AD,27,41,CB,9A,88,FB,24,8E,05,E1,84,96,A5,6B,C5,81,2A,C4,FE,24,7E,02,08,CC,8B,DD,29,A1,6A,8B,90,76,0E,20,08,D6,58,03,84,8D,58,3D,F5,29,3F,02,EB,F0,46,24,E5,05,03,66,6D,B5,9B,DE,37,20,65,45,64,37,F8,66,FE,46,37,09,1F,F4,79,FE,92,50,6B,BA,11,9E,64,2A,90,23,E6,FF,62,39,F1,A2,64,9F,F7,A6,D9,5B,9E,23,67,DF,33,71,99,40,96,2F,A9,8A,02,F6,77,BD,8D,B3,B3,39,13,E0,99,E9,35,EA,2B,B9,B7,7C,3C,CA,CD,50,07,6D,60,6B,E7,19,AC,53,E6,9F,52,B8,1E,1E,C3,2E,6B,45,75,F9,01,16,BC,02,00,5B,0F,33,C0,B5,5E,6C,08,C8,E9,F8,7A,E6,65,FF,3B,50,01,3C,CC,4D,21,46,82,A1,59,C3,3E,96,EB,7F,77,40,C7,7C,15,8E,A6,08,27,72,EF,11,58,75,1D,DE,B0,1F,7E,C6,3D,D8,D3,FA,E7,2D,40,8B,FA,EB,11,BC,18,29,F9,84,FF,02,D4,43,19,C3,FF,22,DE,22,40,99,3B,B5,20,66,D0,9D,22,C2,B5,AA,C7,EA,29,60,E6,63,1A,D7,41,58,CF,40,8A,C6,FB,70,91,CC,2C,F9,FE,9D,74,01,5F,75,90,D9,CA,A0,45,20,A4,16,A4,EE,A5,5C,54,20,A5,57,D9,69,29,A8,AF,22,8E,93,01,4E,85,3F,0C,D8,1B,A8,49,8A,12,C7,88,16,F8,58,9F,2D,3D,CC,72,A3,18,20,31,5B,F6,EA,94,22,91,0C,D8,73,AE,D1,2E,D5,C0,47,28,5C,36,D5,1E,9F,D3,89,BA,22,B9,26,EA,DE,37,C6,A7,1D,C3,71,7F,00,DE,39,94,C6,BB,91,DA,E1,A7,5A,B5,0F,F2,25,BD,19,77,49,5C,0E,58,54,B6,BD,9D,90,23,52,9F,60,61,B7,F0,63,95,6F,B9,94,59,FF,44,5B,1D,53,53,AA,E1,0C,F5,65,29,90,55,6C,18,2C,B2,B4,93,BA,B8,24,D4,13,ED,AA,32,1D,D3,28,69,2D,BD,31,C4,28,DB,13,B6,3C,31,74,9C,FA,2B,5D,46,45,FE,91,20,1C,4D,28,33,C0,10,51,66,0C,EB,89,B1,58,F0,B0,69,3A,D8,19,6F,73,44,CD,DE,26,BD,A3,C1,EC,65,81,C7,BE,B0,00,EB,77,4F,E8,84,B5,EB,02,C8,EE,09,7F,56,18,EF,05,8F,F5,92,E5,BD,7B,34,42,5E,26,EA,C0,FE,83,72,A1,0F,EA,D0,FE,60,D9,7D,7B,6E,3F,2F,65,55,B8,63,DF,14,B7,68,C0,AB,55,A5,4F,A5,81,72,F4,A1,41,85,5A,DB,8F,64,14,9C,9F,D8,0C,D8,9F,3B,4F,24,92,09,81,DF,DC,E1,BC,5F,64,DB,1F,10,66,13,5E,75,40,EB,B3,6B,31,A3,8E,41,A5,4E,5B,45,0B,48,C1,1F,4C,47,E3,24,9A,6E,F7,68,51,5C,35,F9,91,89,3E,63,7B,60,B6,95,AF,BF,8C,01,1F,7D,FB,7A,1A,99,F4,94,F2,6B,5D,74,6C,F3,1B,D9,D0,4F,45,47,42,F9,6E,EB,52,2C,E5,37,CA,A3,2F,B0,D3,D0,B3,9D,8D,1C,11,3C,AC,78,35,5C,26,1A,D5,26,71,7B,0D,07,4C,5D,FB,B3,E0,1A,A8,27,BD,0E,FA,6B,91,2E,E4,97,17,3C,17,5F,0A,42,58,7C,9E,7A,B3,41,0E,58,6A,36,A0,15,A4,4D,F3,7D,2C,B0,74,D2,7A,B4,0C,74,DB,FC,16,79,2B,68,8A,F4,B1,33,8D,E3,8B,2C,AD,90,4C,64,D3,78,0B,A5,26,5D,A4,68,E1,8C,3E,F0,95,96,AF,9D,C8,D3,8B,3A,F3,19,D5,72,57,F3,05,24,26,24,83,BB,66,7F,53,7C,62,99,B8,B7,78,9E,1C,17,61,1E,BC,EF,74,50,E0,8C,4B,33,DD,45,F5,86,7B,EB,23,58,5D,A5,8B,EC,92,9D,30,A3,BE,38,C5,24,9F,0C,E3,68,EA,2D,D7,A3,01,55,AA,37,44,4E,15,F2,9D,6B,7C,01,B7,1E,05,8B,E9,A8,BC,E1,86,9A,9A,8E,CC,44,75,FB,B7,A6,42,15,03,9E,36,69,5F,C1,D1,59,23,81,39,6B,52,38,CE,8A,08,7A,C4,BD,5F,A2,65,B5,1C,33,EA,34,02,B8,1A,60,42,34,68,2F,3F,56,0C,C2,3A,05,40,1D,5B,AB,25,ED,D4,C1,1F,6C,C2,3C,A3,B3,CB,E0,FD,1D,F5,05,DA,F5,E0,56,5B,E1,77,32,EF,89,EA,58,A2,3F,BE,A3,D9,4E,7C,16,69,5E,AF,CB,00,28,B0,47,D2,7B,E6,09,B9,C8,58,6B,30,F6,6C,E4,E8,60,E2,14,1E,7B,79,27,BD,16,7C,65,DF,5A,65,B4,7F,46,DA,22,15,88,A8,E5,92,49,C8,EF,71,E8,1F,F6,69,A3,FC,78,42,A8,18,BA,30,EA,A8,A0,CB,ED,8F,E3,4D,15,6D,7E,DC,9D,88,22,EE,EA,EC,0E,F9,53,7D,F7,43,A9,7C,24,5D,4D,55,4B,3C,8F,DB,67,51,AC,38,0E,C5,F2,11,28,D8,F7,43,06,FA,91,D6,D5,C5,48,E3,E2,97,58,1A,8A,73,AD,20,84,A5,2C,C3,42,82,59,FB,4A,59,94,48,98,B8,24,2A,4A,87,E8,EC,3A,F4,CE,72,45,41,07,3E,A2,65,F9,06,C8,6C,07,6D,A9,94,16,EB,2A,54,9C,A6,85,A5,12,E4,80,17,72,BD,6F,00,DB,1D,90,58,7B,F0,C3,C2,BF,25,B5,16,2D,D2,7B,B7,00,F6,5D,23,56,B1,44,7D,D0,92,C1,FC,61,F0,00,F1,28,B4,BC,C8,BB,15,CE,92,34,B2,90,75,26,6B,D5,37,BD,25,2E,00,70,21,D1,4C,E1,7B,91,88,9C,E5,09,B9,DE,E7,FF,E9,72,11,EA,DF,AD,46,81,E6,3B,72,80,59,8B,6E,99,2D,41,B8,B1,02,72,0E,08,8F,15,68,98,20,44,D4,5D,E5,E8,70,4C,9E,A6,91,3B,BA,CC,AB,87,BF,52,0D,FE,03,28,03,99,7B,3D,3A,08,26,CA,D6,0D,5D,C9,26,C8,F0,9C,5D,B0,C3,22,A3,D9,C1,D2,42,4C,48,35,BB,D4,AD,C5,00,88,92,BA,36,92,F3,02,D8,4E,B4,23,7D,63,88,DA,62,E8,B4,5E,0B,2A,45,63,F9,1D,6E,05,1B,C7,54,CB,58,BC,78,8F,2A,B0,B2,7B,3C,EB,AB,8A,DB,38,F4,0A,31,2C,01,CA,8F,4F,F4,94,FD,C0,29,56,62,BD,AA,D8,84,BC,BE,0F,76,94,AC,74,73,CD,22,F0,01,89,41,D4,A7,21,F5,29,87,97,47,75,3C,9A,05,0E,93,3E,E2,8E,27,0E,22,BC,53,C4,37,41,D7,B9,01,7D,72,F1,74,67,57,AB,71,02,27,E8,3C,CE,D0,57,F9,5D,7A,E7,29,61,79,02,D4,36,BE,C7,07,B2,D6,1E,81,2A,DB,4C,6A,C5,7F,9C,7C,E0,95,54,1E,CF,5A,8B,9F,27,13,40,D8,BA,A1,5E,51,E7,86,29,3C,88,3B,AC,2A,1D,F8,23,77,D8,3D,16,09,A4,C9,54,9C,40,F3,B4,B8,1C,B8,90,65,D0,F9,E7,41,E9,8F,7E,FB,2A,44,46,71,83,04,19,00,C4,97,F0,1C,35,CA,93,35,76,78,5B,26,EF,0C,32,A3,6E,79,3B,36,F4,0A,B2,41,31,9C,2C,19,AC,A6,12,F8,41,2C,0E,19,3C,C8,73,83,84,9B,F0,A7,51,BC,50,2E,F8,E8,D5,7C,2B,1B,3D,26,BF,04,70,1A,F8,33,58,5D,D8,AD,73,0E,7F,BE,AB,AE,F9,D6,5B,6C,94,E5,EF,86,51,3F,1F,07,DC,2C,4E,84,5E,8B,BF,EE,D9,F4,BD,C5,BD,94,98,A9,12,D2,86,DE,5B,6C,25,49,7E,4F,89,D2,B2,28,6A,0C,64,AD,F8,03,4E,1A,DC,F6,B2,81,C9,91,8F,F3,2D,D7,FA,FF,EA,52,45,46,68,2D,A4,92,31,C3,C2,4E,95,06,DD,4F,03,63,07,20,77,B4,F1,9F,81,4E,B9,27,F1,D3,84,42,D8,85,38,DD,4B,60,D6,91,5D,71,CC,EF,B0,15,D3,5F,36,2F,BF,99,7C,2E,C2,5D,42,27,54,41,0A,D8,55,19,AC,E2,2B,D0,9D,D7,3A,8A,B5,98,D5,91,1B,55,E3,A5,5D,D0,21,08,99,60,D6,DD,2F,C4,88,0B,3B,32,FB,5B,27,50,97,2B,B9,96,32,9B,38,25,ED,1B,E8,C6,E3,8F,ED,FD,EE,89,38,87,AE,0D,38,69,8E,91,EB,DC,E0,0E,5E,5A,98,83,1B,B3,E7,53,0B,2A,6C,E8,61,6B,FC,2A,79,BB,FC,C9,FD,12,E2,B8,29,B3,B2,F8,12,44,B0,CA,B9,84,80,18,69,FE,7F,FA,40,D9,A3,92,FB,86,2B,4A,2F,72,16,77,D5,56,71,68,C0,21,AC,31,13,07,2F,00,9C,65,1B,87,FA,49,8E,0E,45,30,F6,80,14,99,E7,22,62,3E,F1,DF,D4,F1,E5,0D,2B,E3,B2,09,29,25,12,4F,CE,7D,5B,BA,0A,AD,0D,83,5B,AE,51,50,FC,26,60,BF,DD,25,BC,1F,5A,12,36,31,F8,29,D5,3A,10,35,5E,17,4F,0A,91,90,8B,96,75,13,4A,45,20,31,4E,7C,A4,60,47,A8,EC,B9,19,BD,17,AC,DF,70,EA,C7,51,6D,63,DF,33,AC,5E,12,55,C5,4E,9E,BD,6E,D8,D1,C9,4E,16,1D,5A,13,47,FE,9C,AC,FB,AB,C3,68,C9,E6,79,F0,D0,1D,D3,1C,2D,11,6E,63,56,04,11,01,F5,63,24,BF,CA,3A,4C,63,1C,07,70,03,9B,DF,98,7F,A1,7F,82,9E,BC,DC,F9,D1,F7,5C,15,81,91,3E,C9,B7,F3,E5,27,DC,B6,50,99,C0,19,44,0D,9B,0A,AD,0D,E0,C5,BA,33,07,0A,CD,D6,59,A3,98,35,20,1C,C2,E3,7A,F6,07,22,A0,4D,13,5C,CF,1D,F4,53,83,9F,77,3D,9C,7C,FF,B5,AA,2F,DB,2F,4E,80,ED,39,41,B5,96,66,1A,70,8A,4E,0E,5A,D8,1A,F3,99,92,F5,DA,07,7D,9A,AD,63,25,35,1C,19,3F,E0,8F,6F,AC,F6,DA,C4,46,C7,74,E4,32,BA,F7,5F,BC,BE,48,C2,13,C1,F3,C3,DA,EB,0A,D0,35,5C,71,8E,74,80,5B,87,2D,08,D9,88,A9,87,0D,BA,A4,6C,D9,AC,E9,7D,ED,C8,39,A4,26,27,B4,0C,12,4C,4E,76,F0,06,26,2C,35,25,CE,B2,93,21,60,39,22,DA,58,35,55,7F,61,46,F1,E3,FD,9C,B4,DA,0E,FC,20,43,AA,D1,17,E3,66,03,80,C2,42,2A,70,78,ED,78,35,74,87,8C,70,09,5A,6D,DD,B3,B2,77,CC,E4,AE,EB,68,94,59,B4,4D,7B,C9,CE,AA,3A,8D,52,97,D4,A5,A3,80,18,6D,3A,71,24,14,6E,A7,D9,B9,B4,5E,BC,AB,F7,6F,0C,8A,C3,8E,B0,58,A5,F0,79,D1,1D,A6,10,74,8D,49,1C,BC,75,3E,F1,BD,29,7A,80,5F,62,49,47,69,66,F8,FC,EF,B1,CF,03,09,A8,D0,E5,2B,B8,21,C9,99,56,15,E2,2B,6D,C7,DB,8E,8C,23,C5,A7,D8,3F,0D,5B,E6,74,35,AB,2E,76,6C,84,B2,FE,75,EA,95,05,23,41,DD,6F,1B,09,FE,3A,A9,B2,B1,51,96,A7,C0,47,25,D9,C1,42,85,D2,50,1A,09,0B,F8,60,96,51,4E,84,56,1F,1C,DB,96,5F,71,B6,28,EF,87,ED,86,EE,A3,72,39,FC,C4,5B,19,5C,1D,54,26,4E,2C,77,C9,BF,19,0B,55,90,ED,E6,C7,0E,39,AF,CE,C2,4C,DB,A5,C4,CD,93,19,D5,25,3D,7F,A1,B5,B2,65,49,11,63,59,4A,FD,34,9F,2E,BD,24,5E,A1,3C,A0,6A,7F,3E,CC,13,BF,BB,EE,22,01,5A,F2,73,AD,70,42,B2,5B,46,8A,36,0A,46,2C,1F,FF,3B,77,1B,17,39,10,10,86,2D,49,72,B3,D2,59,1D,5A,AF,26,F7,47,10,4E,04,35,81,EA,D4,00,65,73,62,FB,9C,E4,B0,89,45,B9,EE,E9,62,4E,A2,79,58,FD,91,41,6C,8B,0E,13,AE,26,AC,DF,C9,DD,19,E9,F4,A5,FD,6F,B3,04,C0,8E,C7,35,65,F8,E2,96,8D,7B,E0,67,74,8F,F6,97,DD,32,7F,46,E0,82,6B,71,01,0F,F8,2E,B7,2B,79,59,46,CE,DF,2A,F8,89,CF,ED,59,D9,52,3C,3A,79,76,39,9B,A1,E9,3E,AE,8B,AB,06,E8,F1,D9,80,F5,E8,75,E6,E8,41,06,06,56,54,CD,12,1C,EE,F6,FE,1E,3F,47,AF,DC,F8,4D,2E,29,F6,60,ED,41,67,A8,DA,E2,53,ED,3B,1F,EE,85,3F,9D,E9,F7,A7,59,2A,54,69,79,E2,35,11,B2,90,61,C0,3C,C1,46,17,8B,A0,0B,3F,49,28,CD,84,75,53,23,F2,40,DF,41,64,76,AB,E1,D7,38,0D,3D,96,45,FF,F4,BC,BA,76,1D,A9,00,68,EA,88,4A,2F,BB,15,6D,F5,F8,29,5D,9D,64,00,71,AA,CF,2D,07,85,93,2B,4E,4D,61,E4,93,2D,FA,72,C2,41,A2,CB,64,23,26,C0,60,C5,A1,39,DA,B3,17,2F,A1,BB,EC,63,36,C0,03,84,63,9F,D6,04,6C,B3,9B,0D,AF,6C,68,4A,03,6F,80,E0,D0,D0,A6,A5,73,40,F5,D8,EF,66,E9,FF,BD,AC,2B,21,1E,9D,F3,50,B2,CE,9C,DF,5B,26,4C,9C,55,22,C0,9A,02,0C,C6,33,66,AC,F7,38,7B,39,EC,67,36,90,0E,DB,7B,BC,BA,CA,FF,0E,0B,56,68,89,2E,A6,98,3B,A3,E9,C7,41,96,FB,46,13,FA,46,E3,9D,8C,57,24,08,2E,16,5E,E0,B9,64,D6,96,22,2C,CE,64,30,44,C7,6E,62,BA,2E,14,49,43,D3,43,1A,57,3A,47,40,A9,BF,56,08,3E,39,03,CA,B6,B3,66,A6,49,17,61,DF,D4,19,66,E3,0A,7B,78,08,20,75,82,A3,57,F0,AF,7D,2E,28,1C,29,DD,EB,07,52,82,B9,1B,43,E1,59,CB,6F,6D,75,FF,85,E2,2C,AE,2F,19,BE,FE,14,A8,61,6D,05,5C,CF,AA,EA,0D,8C,FD,D5,30,8F,31,E8,AF,64,AF,5D,5E,19,7E,E7,EF,DA,D6,2B,E5,27,A7,DC,EA,AD,22,0A,80,65,38,73,81,5D,F9,28,C3,5E,EE,0F,1B,88,9A,16,B8,C8,48,0E,5A,B7,CD,8A,53,F8,8B,9E,48,7D,2F,57,79,1C,A9,01,D4,03,D7,1B,A0,C4,96,2C,B3,8A,3A,5E,C1,4D,CF,09,FE,3F,6D,D0,BF,92,F1,BC,51,D5,21,36,BF,DD,CF,1A,4D,AE,31,6D,9D,D5,9B,0B,03,80,C7,3F,F6,A3,EF,DF,4B,80,4D,33,A8,FE,E9,E0,2A,1C,1C,8F,20,7F,14,E9,0C,AD,F9,EE,02,C4,D2,B9,F6,02,FA,5C,91,FD,BA,85,A0,36,86,7A,41,D2,23,AC,E5,AB,7A,BD,29,07,21,BB,A0,4E,4C,79,D4,3D,0C,D8,92,3C,7F,96,7C,B9,C7,D2,EA,47,9E,18,DB,31,7C,19,F3,F7,A8,10,D2,E5,89,72,F3,CE,2F,4A,3C,A2,BE,65,8C,40,29,DC,32,55,14,BC,69,4F,6A,4A,E8,12,F5,67,D3,51,66,B5,90,06,67,7F,3F,67,76,7B,C4,C3,D3,F9,C6,F3,04,1B,63,3F,54,AD,93,DB,BE,19,5B,19,7A,2A,1A,20,20,B7,13,AE,F6,59,1A,59,85,05,0A,BE,D6,F1,94,CE,F1,F5,C3,07,02,60,11,F2,F0,B2,D1,86,A6,E6,F4,31,0E,88,F2,5C,A1,E8,D7,AE,44,8E,EF,E7,56,3A,C4,2E,A4,30,F7,0F,D9,F3,05,13,4A,6E,AD,FA,93,69,29,35,36,DD,97,75,DB,A4,62,D9,BF,6C,EE,64,40,DA,93,8E,5B,E4,EB,0A,7C,23,CD,65,13,97,3E,7B,99,B6,B9,D6,BC,15,EB,A4,D7,FE,A9,83,AC,F0,93,63,5F,76,9F,D9,79,AF,CC,A2,9C,34,E6,5C,03,87,C7,AE,A4,AC,DE,D5,96,98,A7,2B,42,5C,9D,4E,93,B0,36,11,28,E4,A5,02,9C,63,CE,B0,93,76,50,C7,6E,B3,8E,8C,1A,5B,B4,3F,5D,94,10,E8,10,06,13,2A,AA,E6,A8,0D,05,D8,0C,A7,9C,E5,74,A6,B5,52,9A,C6,0E,3C,36,30,78,37,97,54,49,79,92,50,DA,48,41,99,DA,73,AF,08,65,3B,04,A4,8C,00,46,12,86,C6,9B,BA,53,07,CC,4A,7B,93,EB,9A,C2,10,62,A9,10,5D,7A,2F,B8,7E,6A,4D,58,73,C7,27,9A,FC,14,27,C3,19,ED,CE,24,3B,9F,29,F0,9C,6B,AD,96,CC,47,4D,6D,5A,43,A9,49,30,BE,91,09,39,08,1D,2A,EB,0A,79,08,67,46,94,DC,95,69,97,36,46,0E,65,58,0E,FC,21,82,FF,C0,0E,1B,D2,E2,6C,B4,1C,D2,D4,73,B5,A7,16,5E,49,E9,66,9F,50,0D,D3,37,D7,E3,88,7B,55,F4,6F,97,48,E7,23,E9,D0,F7,F4,E5,F5,36,10,2C,91,9C,15,F5,3D,06,29,A7,05,0A,2C,5B,A8,0A,18,57,66,35,C9,4B,B3,E0,3B,58,62,BA,4F,C6,7E,66,D5,6B,1B,03,D5,5B,64,85,70,7D,2C,82,DB,B6,CC,22,1B,97,BB,60,8D,AC,B7,0E,FD,69,8A,38,96,11,03,91,62,09,A7,7A,7C,C3,16,62,99,40,13,3A,82,60,6A,A9,FF,D6,2D,D0,0B,7E,51,66,0B,6F,1A,F6,A3,19,95,CF,7A,2F,24,08,AB,93,A0,99,2A,2E,0A,2E,07,43,E3,5B,CE,1D,96,70,8D,39,E2,77,24,18,8D,DE,B0,74,70,0C,34,4E,84,CC,5D,0D,EF,85,6B,DE,6D,B5,8F,8E,24,78,BB,32,9F,9B,B5,83,88,B7,A4,6E,08,96,C8,07,99,D2,AB,2D,DA,5D,EE,84,7E,FD,56,61,A4,12,81,67,49,0B,95,8A,0C,09,1F,B9,4A,C5,27,80,7B,0C,DE,68,BB,A7,28,3B,52,A6,14,1B,83,72,48,2D,23,61,B0,4A,2F,55,8B,3C,24,8A,AA,46,ED,BE,47,A4,26,35,89,53,E2,C8,7C,9F,5E,74,A8,23,3E,F9,BC,C9,3C,F0,A8,75,B8,15,68,66,76,FE,15,FA,9C,73,95,FB,C4,CC,D4,36,2B,19,A8,D1,BE,AD,B4,BC,CC,8C,58,35,CE,DE,8B,87,EC,00,92,4F,31,A3,91,CA,3B,9A,E9,8B,CF,72,6A,73,AB,A3,C4,00,EE,C3,35,F6,59,AC,9C,6B,51,03,79,63,4D,4A,C9,68,51,AD,4B,B5,1D,C1,47,2B,A6,A7,06,52,FA,99,DE,2C,D3,1F,29,D0,92,F3,52,6C,40,DB,07,78,9C,F8,D0,E6,3F,AF,9C,D9,0D,38,C7,16,25,7E,52,5C,8D,5F,82,72,7B,F7,61,88,D7,37,7A,AC,98,48,F0,03,89,22,97,53,1D,3C,C5,2D,ED,C3,BA,13,9C,C8,75,75,38,F3,F8,3D,EC,21,55,71,7D,2E,60,AA,C4,DF,50,8A,F5,CB,7E,F1,C4,E2,8F,48,7A,64,9C,A5,70,BD,82,C8,FC,ED,AB,51,F2,E6,83,93,83,B0,06,0F,0E,02,77,ED,63,3F,CB,53,E4,AD,32,FF,BB,5C,34,55,E2,60,E0,65,73,AE,50,8C,41,14,3E,56,B4,42,A4,98,91,54,78,06,C8,4D,24,32,28,B6,89,AC,3F,9D,3D,33,A1,08,A8,5F,EE,AE,28,92,97,E2,68,C6,00,98,FB,A3,92,E2,2B,B5,61,B1,2B,F5,41,5E,CD,12,9B,DA,1E,A8,74,0C,78,2D,CA,2A,9F,84,1D,10,8D,68,B2,F8,35,7B,F2,38,93,39,AA,FD,BC,57,D2,5D,40,C2,84,C2,EB,0A,25,62,C4,85,02,4A,43,A8,40,27,4A,47,16,43,63,68,FF,3D,DA,2C,B8,EB,D6,C9,BF,4D,74,B2,B9,3C,64,29,58,3F,03,16,25,FD,09,CA,2C,F8,65,93,29,9D,81,11,A0,E6,25,E7,D6,52,A0,41,07,E3,AF,13,8B,38,2C,E4,0F,FC,C9,F9,70,A6,64,77,C7,5A,C3,5B,DB,26,C5,74,80,CF,3D,AB,25,28,25,65,49,A2,9C,D5,89,A5,EE,F5,93,C8,F6,BE,3B,3A,54,A3,2F,64,34,F8,BA,B0,5E,09,FA,23,F4,39,F5,3E,4F,01,3D,EA,A9,CE,46,8A,84,18,8A,05,94,27,69,1C,7B,01,56,56,BE,A1,B5,AC,FD,39,F0,29,6A,E5,AA,5B,91,5F,C3,FB,13,2B,8C,CA,31,42,0E,E5,84,51,B1,5D,E6,9A,1A,AB,E4,D4,82,89,75,B8,7B,49,B6,EE,13,A2,09,8D,3A,7A,B0,96,5B,83,B8,E5,48,5A,65,73,5D,28,7B,EB,C7,75,3D,2C,E6,7A,BF,AD,73,3B,D1,D7,DF,99,9F,4B,17,D3,77,B2,B5,04,43,F1,6F,05,CC,78,E6,28,2D,01,1B,CA,38,DC,4C,F7,36,4E,67,BE,37,E8,6D,18,A3,B4,23,F1,2A,32,67,44,FA,F6,E7,BF,D3,7D,18,8F,23,A9,2E,65,A8,9F,C3,24,DB,62,D5,45,E7,53,03,42,8D,39,CC,CE,D1,38,A6,06,25,59,B7,D2,F4,58,E9,FB,69,7C,DD,BA,6B,3E,DC,F6,3E,EF,F9,FC,79,37,3C,58,5D,63,F1,DF,5E,15,A8,A6,CF,9E,01,F4,34,DF,75,22,70,C3,52,D8,E1,D8,43,C7,BB,4A,F6,D2,25,E6,6D,8C,4D,A2,68,2B,62,DE,2F,60,6E,62,86,8E,49,E4,53,2A,D4,DF,FF,40,9E,10,6D,0A,36,A1,76,47,02,F7,26,34,01,B7,AA,A9,85,5C,DC,7D,E3,33,C0,05,E6,83,11,05,E6,F6,51,AB,5D,4A,86,58,7D,FD,84,68,FD,0F,E9,83,AB,AF,0D,62,32,6F,B6,06,98,13,C2,AD,16,85,E0,6F,B8,9E,69,D1,E4,EC,FF,BC,B6,29,FD,7C,D4,E1,2A,6C,72,95,8C,95,0F,9B,68,9D,78,FE,77,F0,66,DA,4F,ED,7B,D3,EB,DE,54,0D,AA,B4,8E,6E,42,50,16,42,60,60,69,56,C6,54,F1,CB,25,61,E6,0D,A3,4C,45,22,D5,90,9A,6F,6B,4B,A0,B1,90,3B,CF,15,A7,F6,53,FC,58,CF,60,9F,AA,E2,E7,65,44,84,82,81,F2,BA,51,F6,46,48,24,5E,EF,93,79,E2,55,8B,FB,B9,71,B7,FD,A2,0B,80,46,EB,E6,23,38,F6,8C,07,7E,98,55,CF,A5,AF,03,BB,B7,3E,B9,93,BE,64,AF,2B,33,2E,54,5F,E0,B0,75,B8,C1,40,4E,55,42,48,3A,6D,06,6B,A3,C9,6D,DA,F6,0F,50,16,2A,95,5B,C7,4D,41,4D,61,B6,7F,A7,E3,A4,E8,47,CA,2C,FE,A0,E7,24,9D,93,89,33,AF,D0,D6,94,21,EE,27,4B,19,AC,F8,7C,66,9D,54,F2,0D,4E,2F,20,A4,8C,53,F5,93,C9,AA,BB,0D,C5,A8,30,B6,73,B8,F9,E3,A8,41,96,A5,21,A5,E8,EE,7E,82,BA,4F,0B,AC,B5,12,9A,E8,0A,58,02,EF,93,F1,B6,88,28,4D,A6,5D,93,88,54,43,3C,26,00,1E,5E,08,F2,7E,9D,51,81,94,63,82,F3,8F,00,B6,38,4E,A7,E2,EE,CD,13,80,E2,14,7A,D4,95,FE,6E,8C,74,7D,6F,19,8E,DD,48,7B,6B,D5,15,02,7D,79,F8,0D,97,91,D4,25,F8,0E,85,75,45,F3,7A,7A,78,82,98,BC,24,27,D3,3D,01,B9,D7,9D,01,12,ED,6E,77,F1,89,FE,EC,68,46,3D,A4,AB,A8,B5,89,78,9B,CE,A3,37,78,C1,FB,3A,80,80,1E,38,EF,1A,2D,E8,81,4B,1A,63,53,A9,E3,BD,04,81,AF,AD,D8,C2,5F,E5,52,01,49,61,0B,87,37,DA,C9,81,B3,D9,8D,3D,62,2C,CE,3B,71,4F,69,1A,5C,41,93,B5,B2,E3,F6,E1,C0,96,72,D4,7A,D7,A9,8D,7D,A5,7F,1E,94,4C,88,9C,C1,52,1E,87,E9,48,51,71,85,7E,11,C7,44,55,47,8B,C1,9A,F8,02,28,5C,E9,08,63,C7,17,69,0C,08,F5,45,E0,AB,D2,90,2F,09,04,DC,FA,76,46,C6,E8,EA,91,1F,06,53,B6,7D,42,3B,6E,45,F6,20,4E,78,5B,AA,82,D8,5D,50,8E,8C,43,16,A4,0B,DA,DB,39,E3,2E,52,D1,45,07,0F,E3,FD,FC,A9,5F,66,7E,E0,CD,2E,3C,0C,2C,A3,51,74,EA,1E,4E,D7,AE,DB,03,94,4C,AC,1E,F2,07,81,11,FB,C8,DF,58,DF,61,45,D0,35,31,03,98,DD,56,94,E0,FB,EF,78,B2,5B,9C,0E,77,55,9D,CD,43,A7,DB,B1,F5,60,0B,B8,FA,0E,67,B2,E4,CE,AC,2B,BA,97,2E,C9,FB,AE,BA,58,40,73,BE,19,BB,85,52,87,3E,F8,40,1E,4A,BF,B3,B5,FA,7A,CB,A6,8E,35,68,77,04,B6,86,65,70,F7,E3,61,7A,CB,69,02,DB,8B,DF,74,06,01,DC,0B,37,86,44,6B,C5,DB,86,0C,C3,7B,89,1C,F4,D0,59,D4,E2,05,47,6A,B1,E6,5C,A7,8E,F2,A9,9E,88,2C,28,68,60,27,02,3E,BA,1A,31,22,74,FE,7D,D2,EE,B0,5C,A5,70,2F,57,2F,54,16,27,7E,A8,DB,85,A7,90,AD,77,8F,E7,52,68,28,9E,5D,7A,A7,F0,AF,07,FB,F2,C7,D1,59,A9,3D,3D,8C,73,66,12,F2,0C,B7,FC,8F,CE,0A,35,AE,8E,71,4A,55,B0,B7,82,DE,79,D3,12,4F,4A,84,3F,EF,21,60,8E,A5,93,59,C6,8E,50,8B,8A,B3,5A,A0,A8,52,18,F1,28,4B,E2,94,2A,A2,B0,6B,8F,A8,AF,7B,DE,F2,09,81,E8,18,6C,70,CD,17,EF,D1,D7,F6,85,02,C4,9D,B3,E4,52,70,4E,40,95,91,A9,4A,FF,76,03,C3,F4,EB,37,8A,A2,C5,AB,A4,46,61,20,FB,92,F8,5D,76,B0,A5,F9,2B,14,AC,A1,6A,5D,D4,28,D4,CB,5F,25,A7,C1,98,63,64,1F,71,C7,D1,E1,C3,BE,AD,96,19,F2,B5,40,37,6C,B9,2C,7C,97,73,CD,82,0C,77,EA,C4,13,0D,27,AE,3F,E3,2C,23,AF,6F,A3,FB,34,67,BF,0D,22,DF,5C,FD,90,82,CA,CC,86,83,2E,A4,68,5A,3A,BF,23,8D,34,18,5E,DC,9E,BA,DA,9D,ED,AF,A8,35,AE,D8,23,CB,79,49,84,32,B2,40,66,C0,7A,EA,30,4F,59,20,53,11,A9,4F,12,A3,07,66,C7,6D,6F,08,D3,01,F2,ED,0E,3C,EC,92,9A,B0,6A,AB,45,58,68,8B,38,2B,15,63,1B,45,53,27,61,67,5D,01,C3,63,EC,0A,DF,A9,72,8F,89,0F,05,25,BD,17,4E,32,1E,19,75,4A,8E,96,17,8B,FA,25,99,26,9C,15,14,7E,9D,5B,E0,B6,A9,D1,26,BA,8E,6B,11,6A,54,C1,0B,6D,E9,CA,83,29,F5,DA,E0,7B,47,F7,41,95,98,C9,55,D4,6C,CC,A3,23,86,33,7F,5E,08,0A,F4,C6,0B,78,BB,01,A6,CE,66,A7,8D,E3,A8,D8,3C,1A,B4,35,17,E1,FB,DD,F3,22,71,81,B1,91,6A,85,B9,ED,FD,3F,69,BA,61,3D,F1,FE,DB,C2,D1,F5,77,FF,C7,AC,8A,DD,E6,BA,70,2B,F0,66,0C,24,8E,37,75,98,B7,02,AA,2F,3E,A2,24,67,17,7B,D2,B5,4F,96,07,69,80,89,50,D4,78,B1,9F,F3,1C,22,66,F4,37,D1,00,D8,DE,24,D4,05,DC,60,95,D0,7C,B2,78,19,11,B2,F4,23,C0,0F,93,70,6F,AC,E6,29,8C,5F,16,D6,E7,93,56,0B,08,B8,DC,72,46,09,FD,1F,E4,F7,40,32,FF,CF,DF,18,F7,50,4B,FB,94,A9,C5,BA,37,D1,4B,6E,11,7B,90,25,56,28,1B,E4,D1,CA,78,CF,2E,41,56,9D,71,2E,AD,9A,0F,38,DB,DF,95,13,55,6A,FB,81,47,93,BF,43,D8,73,24,8E,84,27,A1,C2,2A,C0,15,50,60,55,16,47,FF,C2,28,2A,53,C8,9D,87,99,B5,E6,4E,63,44,91,9E,02,52,FA,65,AF,B3,94,8E,A7,91,01,C8,0D,20,78,02,73,0D,70,A6,22,3C,77,22,43,84,D4,3D,FB,CA,5C,27,6B,BC,69,43,72,C9,9A,82,8D,31,2A,73,59,BA,B0,B2,DD,2B,6E,15,A9,74,6A,93,9C,78,D2,5E,02,53,D7,46,DB,23,5C,8E,20,29,C7,44,E3,F4,03,ED,E8,DB,A4,67,07,60,16,38,F3,24,A0,C0,2F,63,14,B4,AA,76,A9,38,7E,48,45,A3,FA,3D,AF,E2,31,65,AE,BA,DE,FF,72,C9,85,00,29,D2,51,4C,78,5E,77,17,08,78,B1,C0,A1,A9,FA,A5,F1,34,02,F6,FB,15,64,03,80,29,58,5B,25,B8,8F,FE,3D,87,01,0D,E4,34,D4,16,77,D3,47,4C,08,A9,6A,FE,F7,A9,BA,46,C4,95,95,8F,E6,8E,88,B4,90,EF,ED,7D,71,D1,55,87,A8,C3,46,6D,1A,92,8A,15,63,7C,58,2F,AB,91,09,B7,58,F1,FF,6F,F4,BA,89,E9,B0,70,6F,85,66,40,FE,E7,79,B1,BF,67,80,B2,DC,B5,0A,91,2D,C3,44,22,DD,06,BD,0E,8A,D7,8A,D4,31,1B,BF,D1,82,64,02,82,54,50,3B,F6,01,A3,2C,10,37,A5,A6,15,BE,A7,35,23,1B,EB,95,3A,31,48,3E,A7,3C,4D,1A,CB,01,6C,E9,14,7C,FF,0C,74,5D,22,05,F2,95,05,EB,26,E1,1E,89,29,AA,73,54,A4,D2,BC,76,9F,13,47,9A,0D,1E,EB,0E,BC,C3,1F,F0,DB,C7,8A,74,98,D9,71,1A,B3,FB,B0,BE,D4,80,6E,23,D9,20,39,4C,A2,78,37,C3,B3,89,C3,90,36,36,3F,5D,8C,D1,21,28,3A,7F,E4,D9,FC,FE,A0,D2,B3,88,57,83,1A,3E,50,5D,97,9D,C2,3C,9A,9E,72,23,D0,0E,87,02,3C,71,30,EF,12,15,6A,C5,EA,8F,0E,92,45,C9,4E,54,50,D8,90,73,90,F4,32,55,78,3D,14,AD,5D,8D,FB,11,58,41,45,6E,33,17,DA,42,D7,6F,BC,16,FC,60,AA,FB,52,8D,9F,3B,72,67,62,9B,89,C7,89,1F,FF,BA,F7,E0,86,35,6F,AD,03,B6,B1,7F,CE,EE,3A,9C,8A,04,A2,97,A2,76,7E,4D,1B,0F,4D,08,C0,18,E6,C0,65,15,DA,BB,8B,57,8D,44,D8,DB,01,A2,91,9C,01,98,FE,A4,B3,23,9E,E9,76,2C,C2,E2,F4,2A,29,1C,B0,4C,E5,0D,DA,4C,00,33,63,07,7B,32,E4,26,D2,1F,4C,59,20,B9,4F,55,A6,01,C0,F7,69,A4,30,C0,70,A2,9C,83,F1,5E,2E,76,79,5D,72,20,2A,55,92,35,B2,FA,1D,45,C9,49,92,63,70,7E,53,89,C0,29,B5,76,DF,96,0F,DE,72,E0,64,A4,B8,22,B6,B7,4F,6A,CF,7A,50,BA,38,38,F4,3F,F9,D3,10,97,DD,03,ED,3D,9E,5D,EE,0E,36,0F,7F,14,C7,8E,93,CA,BB,1F,FE,CB,4E,C1,BB,E0,BD,07,63,23,C6,96,5A,8B,8D,1A,6F,79,0C,49,C3,3C,19,92,A2,01,C1,1B,D0,EB,7D,F1,3A,0B,3D,82,EE,49,43,C6,21,5D,68,21,98,C7,97,67,D7,53,A8,8D,83,02,79,A2,11,53,47,DD,6D,C2,1F,C6,3F,D7,9A,F1,26,00,A3,31,71,6E,42,6B,0A,4B,58,DC,D0,B2,6D,6E,55,DF,73,13,41,C0,E5,E8,20,3E,8D,8C,EF,3E,65,AA,99,10,5A,F4,65,E5,C9,BC,88,C0,12,A6,7B,97,30,7A,C0,6A,AC,34,1C,4E,C7,EA,41,04,63,55,6D,EB,68,FA,B0,BB,A8,81,44,73,BB,EB,5F,38,3B,22,C1,BA,A8,81,E8,2E,40,E3,CE,C8,F9,D3,08,D6,D8,9F,C2,38,14,68,E8,68,78,A8,F6,12,81,75,CC,C2,4D,F4,74,4C,14,CA,B0,81,C7,65,06,8D,E9,F8,6F,42,4C,43,04,6F,77,5B,92,2C,1B,8C,05,5E,B8,13,66,34,F5,F0,45,A4,74,3C,A7,66,77,DE,F5,53,BE,A5,23,93,07,CA,4A,40,F2,55,1E,A6,7C,51,A4,44,BD,30,D3,4B,41,57,C0,0F,5F,2C,9C,0F,E1,D9,4D,17,D9,53,5F,EE,9C,16,D1,29,14,0B,04,4F,3F,B1,7A,D9,30,D0,EC,FD,F5,99,86,44,EE,FD,E2,BE,5E,3E,00,36,20,1E,B9,2D,25,55,C6,3B,1E,F7,C2,82,7A,F1,80,C5,FF,28,3A,45,D6,1C,53,65,6C,3C,40,39,94,E6,1E,AE,65,D6,73,5C,07,A2,4D,EB,E5,55,6A,27,81,3B,D5,24,C2,1D,15,48,D3,F9,9A,42,6A,D6,7B,E1,40,4F,DF,68,39,D2,7D,83,F9,38,DD,7D,8D,E3,75,BB,23,60,BD,6C,50,9C,35,24,A4,E3,D0,36,31,36,24,C1,30,59,C2,92,6C,74,BA,FB,01,10,06,DA,8A,25,89,91,C2,F9,C0,CD,5E,A7,AD,B3,11,76,97,39,A8,8E,3E,38,E9,B7,EA,E0,25,3D,06,9A,0F,D3,FF,E1,C0,AB,AB,06,76,88,6F,AF,D9,18,AC,7F,8E,DD,E0,5E,2B,6C,CF,D5,28,B0,88,D3,8F,B5,E4,AF,1A,5F,B8,EF,5D,D8,85,6A,D0,50,FD,BB,CD,E7,ED,E1,52,09,AF,A8,F2,82,54,EC,B1,08,32,17,9F,48,F3,B5,AD,33,F6,67,57,48,DA,02,1C,25,30,52,69,29,A7,0B,D5,BB,45,05,85,C0,31,9E,7B,85,C8,29,1B,06,5C,DE,F4,D1,C4,B9,61,29,55,CC,89,22,FB,81,B9,15,6D,F5,A7,B0,24,14,88,B5,80,89,67,ED,0B,0B,4A,71,D4,CB,39,C3,CD,8A,30,E7,CB,5F,48,E8,74,8F,E7,2C,3D,52,2A,22,DC,A2,C4,5A,BB,F3,40,C7,28,4F,09,14,3C,F0,49,20,22,08,A9,18,36,5A,38,8D,29,40,E0,2C,C1,FE,6E,FF,C3,2F,CF,95,90,BD,AE,83,40,5F,1D,70,D6,FE,D7,40,79,1A,28,90,BA,3C,AF,A0,64,4F,63,13,9E,81,25,69,2D,5F,41,66,94,16,10,67,E6,BD,87,77,58,32,1C,72,75,FF,CD,10,55,05,02,9F,8A,AD,40,C8,D3,DA,EB,E4,59,D2,FE,B0,21,15,B4,A5,D9,58,F4,B2,9C,51,42,9A,E1,04,E8,A6,4C,69,F7,37,7C,07,9D,E9,77,4A,9E,2D,96,DA,EB,FB,9E,91,B1,B6,F1,31,CA,55,42,FB,16,BD,26,FF,80,3B,19,4D,FE,74,10,FD,E2,47,8B,42,07,FC,4E,7A,1D,96,6F,1D,8E,F6,D3,02,DC,40,A4,6E,56,93,CE,C4,37,95,54,01,E3,0C,B4,09,A5,1E,FA,37,31,4B,E4,52,F4,8B,A2,34,DB,A3,9D,AD,F9,B1,99,16,D5,64,AA,FE,B8,99,88,CA,65,E5,0B,9B,09,88,78,7D,6E,C2,D5,13,7F,4D,34,D1,25,35,C4,B6,A8,DF,FD,91,89,D9,A2,5C,DE,56,5C,05,82,13,8E,F2,C3,99,8D,99,CD,7C,BD,79,C2,4A,5F,27,9D,F2,F5,B8,AB,AA,C0,C7,81,DB,28,BF,41,16,55,44,22,E5,07,BA,7F,B7,10,F4,12,DA,2B,0E,4A,46,0C,84,76,5E,AA,79,7E,FC,C8,B2,0D,CC,47,10,16,FC,38,D3,97,86,94,87,10,38,BE,5A,C9,55,80,1F,A9,4F,53,5E,CE,FD,65,81,1F,E0,82,E4,5E,19,4D,9F,18,FA,84,62,A1,EF,EF,A6,AD,98,5A,A5,AE,41,EE,B3,52,7B,C2,90,7C,DE,80,87,F8,1A,A1,3C,FD,AD,F7,1A,95,31,03,3C,A4,6D,39,47,6D,0D,38,79,77,67,6F,1D,B5,CD,E2,1C,67,61,69,68,99,BB,3E,13,32,3A,06,D3,21,19,67,BB,A1,66,A9,D7,6C,1A,D3,AA,AC,1D,56,9C,CB,4A,B0,F3,E1,F2,C9,6A,F0,06,EF,3B,28,23,81,1E,59,0B,73,0A,C0,04,0F,A8,76,66,B9,A7,9D,CC,74,5E,97,75,3E,F0,D3,4F,49,3D,11,9E,56,D4,C5,32,F6,2F,F0,83,5F,FC,40,F1,DF,8C,3D,E8,71,DA,E7,75,CB,80,3B,47,BC,57,8A,C7,0C,04,91,4A,C3,19,4B,05,78,CD,89,0E,3E,7E,3E,BF,39,27,D1,95,B5,DD,B0,1D,4B,46,C0,8A,97,BF,EC,D8,AF,A7,DA,40,D1,D1,E5,66,99,72,E4,8C,66,99,75,0F,CE,84,E7,D5,3E,10,05,0B,BD,5F,CF,5A,C3,07,A7,34,E6,54,92,54,13,67,72,14,44,F5,DB,1D,77,AE,F1,40,C9,C3,31,43,D3,3A,18,A3,00,2E,35,54,1F,14,92,FA,BA,C9,6E,56,56,89,53,05,B8,4E,13,56,24,95,D7,06,5D,F5,CB,37,DF,F5,86,6E,03,07,CD,DD,A5,53,C6,4E,5B,87,FE,9D,9C,90,29,93,2A,92,50,2F,3F,8B,61,D9,9E,F5,5E,C7,B8,BB,7A,51,3E,19,F4,0D,A9,2A,30,84,DC,3E,F3,FF,BC,0A,F8,CB,39,D9,D6,A4,E6,CC,7D,EB,53,DD,D1,E0,B1,EC,DA,99,E9,B8,88,87,E7,32,2E,60,25,95,6D,82,95,ED,8E,44,80,A5,16,FB,6D,06,FE,77,00,F3,2A,4F,26,0A,10,BB,11,7A,28,3E,37,1B,3E,74,84,2D,86,8E,6A,B5,0F,3D,37,B3,29,4A,72,0C,95,77,58,D8,F0,D0,49,B2,31,78,64,14,A2,14,69,22,44,96,A1,3D,19,66,35,53,02,53,8C,3C,7E,78,76,4B,A4,21,A1,72,4F,95,68,7A,5A,F5,3B,41,8B,81,FE,56,FD,3C,23,BB,8E,C7,D9,F4,8B,23,FF,75,19,98,65,FB,15,7D,AE,AA,32,7F,51,0A,20,DB,00,CB,C2,4F,4F,A2,2A,53,19,28,F6,83,13,35,C8,B1,9E,D7,49,1E,53,1A,28,AF,6C,1A,0F,C5,75,72,62,F0,39,60,C0,A8,E8,E3,F6,48,F8,79,F7,B6,83,5D,A4,D1,56,54,E8,33,F0,63,2B,13,00,83,04,DC,4B,94,A2,C9,31,64,FE,35,07,33,C8,4E,1A,E3,69,F8,5B,69,8A,44,F3,42,D2,76,C3,4B,D8,DC,72,14,FD,D4,3A,0F,72,0C,8F,36,0C,EC,9A,CF,7B,79,8A,88,01,DB,D8,40,9A,07,28,8B,4C,D0,B2,C6,A5,30,9E,AA,76,32,3B,5B,05,5F,F3,69,47,6A,CD,F7,0A,25,1B,FC,2C,AE,A4,53,EA,B0,61,56,C8,01,15,FA,3F,EE,0C,38,F1,B2,BE,CB,3C,DA,1E,FD,1E,9B,2F,64,56,21,54,AD,0A,C4,7A,48,2C,A6,87,A9,BE,3C,AB,24,71,AC,37,7E,6D,F3,3A,E0,32,32,CE,0D,68,78,F9,A1,0C,98,30,7E,99,FF,7F,13,42,9D,3B,36,E8,71,98,83,B0,BD,D8,85,D6,7C,F2,8D,9C,7F,9B,B5,4F,74,58,18,0D,BD,F0,50,AD,88,99,B4,D0,75,B6,52,DB,D4,A3,AB,4C,03,11,A0,C4,90,DD,F8,15,70,7F,F6,3B,D9,BE,1E,4A,CB,B1,51,64,51,10,FA,9D,39,DC,C5,BD,9D,48,B9,4C,B8,FE,96,94,44,91,B1,53,79,E5,62,95,D3,1F,EE,8E,09,D9,89,74,7C,29,2A,77,12,E5,01,60,20,6D,B1,26,9D,CC,62,25,99,D2,D1,00,05,A5,D6,07,BE,35,B6,24,E1,9D,88,D3,6D,F3,3C,C8,F9,74,C8,F4,28,DC,30,AF,26,9E,16,E5,C4,2E,3B,DA,89,EE,13,69,D0,F1,86,28,4D,AC,4F,72,A7,B8,79,C4,A4,2F,A2,E1,2F,84,E7,D0,F8,BE,8F,18,77,97,BB,3B,13,82,08,FD,91,A0,97,CD,80,5A,A2,3F,2D,2A,EF,92,4D,EA,EA,46,79,3A,C7,FA,D3,44,7A,22,AD,24,F8,12,C4,EC,58,ED,87,85,91,A3,62,A9,DA,1E,EB,59,C2,93,FD,E6,EC,47,63,61,00,BD,CE,B8,F2,8F,C8,05,3A,9D,B7,AA,A9,C9,DA,57,56,CB,4F,A3,56,A3,AA,A4,FB,39,54,B7,6B,85,B0,84,AD,38,0C,43,01,4C,56,36,0A,6F,32,AD,A0,13,13,AA,64,CD,B8,A7,BA,0D,3D,23,A9,A7,FB,43,10,E0,EE,BE,82,A4,E9,39,29,D3,3C,B5,4F,3B,73,A5,39,3D,69,1F,F8,23,F0,A7,B4,6A,0E,88,81,59,CE,89,49,D6,90,A4,E3,37,37,59,57,64,98,99,E4,D6,B6,68,D7,CA,68,78,1D,D2,B6,F9,4B,EE,7F,5B,BF,70,70,09,C8,3C,A7,07,41,D0,F4,D8,46,CD,8F,13,CE,E0,8E,3C,B3,83,AD,1F,27,FB,8E,3B,B5,5D,97,BB,45,72,5C,47,C9,26,99,BB,4A,B9,62,04,C2,CC,A3,D5,DB,33,C8,E0,C5,A4,87,E0,F8,7D,BD,F3,83,A1,FD,8A,86,ED,30,D1,8A,E2,E3,DC,CC,FE,FE,A2,FF,6E,C6,F5,9C,A4,6A,EE,13,A4,CA,16,65,4D,0C,E5,64,5D,DE,1D,CB,A0,93,67,A4,33,E1,F3,D8,26,A1,FA,A8,DF,45,92,EE,2F,45,F6,6E,74,00,B3,9F,71,2A,92,19,12,3C,01,DF,56,CD,34,07,CE,E3,73,08,AE,77,0E,70,46,32,6F,1D,4C,13,C9,A6,AC,69,04,01,8A,3E,B0,68,26,BB,F1,6D,7C,67,98,A5,5E,BF,B4,15,E3,1F,E7,78,F2,D7,03,F3,5F,7F,D5,9D,F1,3D,89,70,00,B8,A0,8A,B7,D5,55,E1,5D,58,11,CD,C6,35,CD,B0,AC,95,5D,D6,A1,1D,45,45,6D,79,C0,22,3D,34,20,62,24,D3,32,8B,74,F4,45,A1,A4,86,88,73,3C,76,20,06,0B,B5,CF,36,B8,1E,04,DE,B6,10,C5,B8,4B,CB,84,21,F2,29,12,28,65,A1,FE,57,F6,15,A6,20,3C,83,14,7C,42,05,48,8B,AA,CE,CB,91,57,4C,46,03,6E,7C,11,F5,27,F8,03,32,AE,15,80,1E,28,9F,8F,84,89,15,28,B9,53,91,D0,13,32,C4,48,51,DE,F0,07,99,B1,82,DF,FC,A5,0F,8C,69,BF,0F,CA,D7,56,32,3B,5D,DA,26,2C,52,40,74,ED,1A,D9,11,F1,B0,C4,66,A2,A4,B5,E6,5B,76,9D,FD,D3,54,EA,47,4D,7A,98,E4,B0,CB,91,05,F2,69,E0,70,96,4B,CE,0A,3E,59,33,13,CD,76,D2,9E,63,14,76,A3,C4,30,DA,2E,A4,55,6D,F4,D7,8D,9C,41,99,0F,37,B3,99,52,90,A0,B2,42,2A,FB,9F,CF,B3,BA,7C,BE,BE,D5,E1,50,AE,15,7C,DB,AC,EF,78,C2,AE,1D,B8,56,70,1E,4A,8A,FE,21,98,00,15,36,21,50,D4,2E,52,84,5B,47,E4,AF,85,B5,C8,9F,88,10,F1,59,92,CE,39,15,AD,66,0E,40,67,07,B7,1F,F1,3D,95,79,1D,F3,04,1A,66,59,4A,35,43,84,AF,EE,7F,5A,48,D2,F4,C7,4D,F7,3D,F5,4A,BC,20,9E,FC,BC,52,DF,DB,D5,C9,EB,62,23,68,0A,66,A6,5E,CB,F4,6A,15,14,E0,3D,B6,EE,FD,5D,D7,9D,6A,D3,A1,23,B9,C9,C3,6D,1E,B4,F9,7B,53,6C,77,45,49,FF,3B,D1,47,0F,1B,BE,1E,96,26,16,20,BD,60,99,75,DB,8E,B8,8A,D7,69,90,65,CA,AB,93,11,6D,21,1C,D3,D1,D9,6D,92,05,FC,44,9E,DA,77,CB,F0,FD,24,BF,08,A6,4B,B9,F9,2C,2D,73,D7,00,7E,AB,99,4F,EE,82,06,B6,F3,E3,14,EF,02,D4,A7,68,51,39,27,33,81,E5,81,98,B5,9E,70,D0,A4,E7,B2,4E,DB,73,7F,CB,69,92,F5,B6,BF,37,C1,61,08,4C,95,0B,1B,A0,3E,F1,A1,FF,1A,81,95,47,10,76,72,EA,1B,06,46,9E,47,B0,8E,E5,C7,A0,18,6D,69,FD,C7,C1,41,5B,13,3C,2B,80,72,39,DB,8B,91,91,A2,C4,1D,47,9D,C0,DA,26,11,5D,35,7D,DE,51,E2,51,27,9F,72,25,CF,6E,44,60,06,37,01,64,DF,38,42,7F,0F,CF,A8,AB,FF,88,9F,46,61,C2,EB,41,4A,DE,F4,5D,7A,88,FA,4C,BB,6B,9A,F2,18,05,25,37,63,5F,7C,9A,E1,91,C0,48,FC,F8,15,7F,0D,2E,D5,5A,41,89,11,CA,00,C8,23,11,6E,6F,16,F1,F2,A6,BA,F4,24,AA,77,05,DD,40,16,60,E2,13,B1,60,5A,EE,CD,EA,1C,A5,41,5C,53,B0,B3,CB,59,54,E1,20,A9,F8,0E,C5,E6,EA,59,25,0A,6C,82,A7,B8,04,BD,36,3C,3E,A6,8E,72,A5,62,05,1C,51,C2,0F,44,F6,54,28,57,CE,B9,0B,F2,E9,E2,9B,E8,CF,B1,BB,45,0D,9A,DD,DF,86,0E,2A,AD,59,DA,80,29,FD,42,04,FA,CD,27,0C,53,29,56,1A,17,6E,6C,90,97,67,A5,19,3F,57,58,B6,68,6A,EE,99,56,46,DA,8D,79,58,04,7A,98,F1,D9,21,D4,81,0E,BE,A6,B6,2C,51,6C,C8,CB,26,CD,91,7F,9F,58,06,53,D9,94,79,35,68,45,1D,2E,AD,44,F0,A7,49,AD,AA,4D,F2,DD,53,E0,A3,9E,DE,45,EE,D4,97,3B,CC,34,D6,8A,0F,9E,3B,14,03,90,F7,CA,60,1E,8E,66,6C,1D,C0,79,56,B8,56,6B,63,E5,A0,2A,9F,51,AD,34,73,91,8E,E6,21,8B,8B,51,B4,27,89,93,3E,51,9C,F8,71,87,7A,61,C9,C1,0B,1C,30,34,D1,C7,62,9B,96,42,CC,24,66,32,92,AE,DA,2C,E4,BA,CB,6E,E9,6D,EE,5D,4A,4A,B7,96,B5,7D,86,D3,4A,B5,51,ED,E7,F3,20,9E,BA,B1,A0,51,77,9F,24,60,D4,9B,73,E4,9D,9B,F5,74,81,5B,B7,1F,25,B1,7F,80,BA,32,88,B7,1E,68,FE,27,0B,8A,9D,15,3B,8A,6A,68,83,F1,1B,03,EE,C3,CD,F1,46,92,E6,74,C7,EA,AD,4C,2B,29,C6,23,07,6E,E3,4C,49,B4,54,34,7D,34,A0,EF,CE,F0,B3,A1,DE,DB,2A,45,2D,16,A8,5B,A1,2B,F9,A0,58,A7,6D,26,15,A1,37,15,B2,C3,7E,52,94,B5,1C,F1,37,44,07,77,63,F4,0B,18,74,BB,31,8B,E2,52,8D,AC,8D,18,EE,69,55,CC,E3,CE,EC,82,80,EA,4E,6E,B1,C5,CE,CB,E4,82,6D,88,09,96,CA,D0,FF,3E,DA,19,0F,8A,4E,40,8D,66,F9,75,8C,C5,C4,21,A9,00,11,F7,1E,CC,C4,56,74,31,65,F8,89,3A,27,87,7A,2B,14,4A,F1,EF,10,22,53,94,28,70,B0,BC,34,94,8D,2F,BA,9C,46,ED,60,95,E3,A6,64,0E,9B,72,81,9A,FA,6D,BE,E6,59,0F,90,22,B0,23,11,3C,C3,C1,AC,02,BD,5E,2D,E1,38,67,E7,33,F6,0D,C0,B2,C6,BF,AC,19,90,BD,AF,50,3E,D4,FA,5A,90,F2,45,53,00,BF,DF,A8,5B,FE,D7,D0,0D,87,C1,EE,B8,58,10,DB,59,FD,0E,19,A0,29,2F,95,56,E7,EA,9E,E6,A0,A1,C8,9E,B4,C6,C2,74,C1,E1,89,F4,75,AE,35,D9,FA,7C,5A,6B,4A,D5,9A,75,66,25,04,45,6E,63,63,FD,1D,0D,B5,29,32,69,40,7A,EB,73,8D,6A,00,50,E9,82,78,10,1A,DC,11,8F,64,F7,2B,1C,10,2F,15,1A,4A,5A,61,9C,2B,B6,F6,9E,E3,E1,17,73,D6,37,55,7B,68,04,AB,14,A9,09,68,07,D6,CA,39,C1,9E,CA,58,44,32,9F,81,3E,02,B2,50,C2,2F,01,17,E1,DB,C9,BD,95,15,AE,59,00,97,AA,34,A9,3F,38,C1,AA,5F,53,53,92,2B,53,FF,46,CB,6A,2A,C3,25,FD,D8,CC,F7,CA,23,7C,59,5A,4A,45,DD,CA,48,36,4F,5A,2E,78,1A,AC,28,A5,16,B1,C2,0E,8E,E6,DA,A0,D8,75,5F,5F,DB,63,C1,3A,AA,74,45,6A,4B,0A,4B,1A,35,85,71,7B,F4,98,19,D0,C5,20,BA,07,69,56,27,D8,C9,77,DF,41,4B,3A,51,8F,DF,8C,AC,13,0E,4D,52,5B,1B,83,A6,E9,A2,1B,56,99,40,F0,CD,B9,88,4A,14,F1,72,3E,69,ED,6D,C3,F7,63,A8,D0,E4,55,C6,59,CD,15,64,1B,D1,28,C7,B8,7A,B2,02,E5,04,39,81,EB,A8,B6,C2,35,20,5C,7B,21,77,6D,F0,0E,2F,35,57,83,CE,85,B9,E9,81,0C,8A,5A,7B,FE,35,7E,F3,C9,1E,09,59,E7,0A,66,24,D3,07,C1,00,E6,AE,35,F0,1B,4A,61,50,B6,0E,9A,B8,8D,60,02,30,91,28,78,7F,92,69,68,5A,E3,38,F5,F2,6F,83,B2,32,B4,A4,F2,A5,87,E8,BB,DF,7D,48,40,76,88,C5,2A,81,7A,32,5A,B0,6A,EA,F0,A2,97,46,AF,41,9E,F0,86,74,20,F6,5D,74,86,DC,39,44,22,F6,CA,45,13,FE,85,29,4B,7D,B5,F0,54,44,5A,C2,08,D0,65,CE,A8,6B,32,36,05,86,C0,5C,2E,AD,54,36,5F,74,A3,A3,D9,83,63,21,B7,7D,42,C3,34,D1,AD,71,20,E4,1E,E3,BD,0B,5E,10,B4,E5,78,08,08,D9,86,4B,53,F9,D1,9A,05,E9,77,19,95,F7,EE,DB,2E,DF,C6,C4,9E,97,93,A9,5B,4B,1B,04,BC,70,72,24,A7,14,39,60,BF,EA,9A,5F,EA,A1,45,0F,E3,6B,48,47,FD,DB,7B,EA,0B,DE,3D,2A,C0,54,1F,1F,5D,33,B1,D5,6D,9A,D0,41,16,E6,EF,60,9E,D8,4E,4D,98,F2,D9,0E,E7,17,9B,6A,C3,14,A8,48,34,AE,DC,E0,19,DB,77,C0,A3,CF,BF,5B,0B,B7,99,26,3A,F8,90,5D,53,61,14,8A,88,D7,FE,4E,FA,88,66,2F,DD,69,9F,7C,0F,30,13,E5,E0,53,2B,3E,6E,F7,E0,5E,B9,D4,0D,AA,53,F0,4B,B7,52,82,8E,35,8F,7F,2F,DB,85,74,A2,CB,4B,A6,7E,F2,D1,40,C6,67,41,2C,28,41,55,51,3D,9B,26,25,A9,AF,7D,76,6B,4F,61,27,2A,9C,65,B9,37,8A,6F,51,DB,A3,8F,10,02,C3,0C,83,D7,5F,56,88,C1,9C,CC,87,1B,5B,F6,11,5F,52,B5,15,0E,1F,E7,96,65,EF,7A,B7,6D,F0,92,EB,C6,59,CB,94,31,5B,3E,02,BC,81,2D,47,79,86,F9,1B,BE,EE,4C,35,BD,EA,3D,42,38,0F,E4,C0,27,11,4F,C7,76,5D,8B,D6,03,C7,E8,3A,F5,23,A1,B2,3E,F6,A8,D0,9E,50,BA,C2,0A,81,D6,46,9B,A5,3A,D7,3D,E1,7C,45,C1,A5,D3,EC,07,FD,E4,5B,99,0D,FC,89,66,DB,D0,D8,0B,2C,3A,7C,E9,13,77,1E,F7,52,C5,2A,D7,F2,06,51,1B,71,A8,A8,A1,71,A4,0A,27,BC,C9,E1,CE,A2,B8,11,99,BD,50,D1,4A,BA,91,61,21,CD,0E,2A,58,64,F1,03,1C,F5,85,F0,C9,58,75,7F,14,2E,48,48,E8,01,70,00,A2,FC,45,77,05,C0,D9,CF,57,33,B3,E3,E8,7A,41,99,2C,5C,AA,6F,AF,44,66,CC,AA,2E,21,AA,56,32,A2,52,D1,FF,2D,A8,32,DE,27,C4,9B,D4,2C,C5,C0,8B,87,31,CB,95,DF,35,59,8D,91,C6,F3,41,CC,91,77,4A,43,0F,C3,3C,86,BF,75,9A,CD,81,DA,A4,AD,31,CA,76,A8,7C,36,CE,1B,B6,7B,14,81,D0,D3,6E,67,1D,48,6D,A4,6C,D1,9F,74,8F,4E,E8,1E,78,07,46,D6,63,EC,A6,CC,ED,4D,49,4D,6F,4D,7C,84,10,6A,FF,DB,6A,F4,A2,33,0C,87,3D,85,B9,31,B3,26,7D,18,5E,94,C2,A5,20,0F,FC,45,00,B7,A8,2D,3B,AB,74,21,D3,CB,3F,D3,AE,A8,2A,B8,96,77,76,8F,1E,70,6C,3D,AF,EF,04,88,AE,AC,12,D2,CD,B9,B0,32,AD,11,62,47,46,63,D5,DC,3D,16,62,78,F5,1D,CE,46,F1,9D,A8,3D,D3,0B,2C,AB,85,D8,90,D2,65,32,D2,C1,32,2B,C7,53,C1,8E,BA,B5,C5,0F,C3,5C,B5,2E,D1,A9,AB,CE,50,47,5C,CD,87,59,05,5A,05,34,86,6B,B1,D1,F5,73,C0,19,D5,5D,00,52,2D,A2,C6,7A,08,41,B5,BC,7A,D2,1B,F5,DC,CD,C8,E4,6E,82,24,3C,00,CF,83,B9,6B,5E,98,9C,69,25,9D,60,EC,80,1A,0D,6C,B5,86,F2,F6,08,9F,23,FA,86,7E,4A,48,8A,4D,BB,AE,DF,B7,64,A7,94,03,08,B8,67,58,C0,78,AD,7E,7C,BA,79,A2,95,14,85,F1,42,5A,FE,B2,B9,F0,A7,91,84,8F,4D,5C,DD,A3,2C,9C,12,A4,AB,B3,B3,31,82,44,BB,A2,99,82,86,ED,38,D8,3A,DF,EA,90,96,50,7E,DB,09,7F,70,E8,22,17,8E,B1,7F,FA,4A,2B,1E,C1,37,66,5C,19,FF,1A,77,40,5F,1C,40,F3,EF,4B,DE,F0,29,06,87,29,D4,75,66,8B,FB,7D,9C,CC,72,13,C2,99,22,59,C1,40,69,CE,12,75,A3,E6,EF,61,57,DD,0D,B3,C4,24,39,99,9F,9A,96,A1,97,2F,30,39,21,45,1B,64,D9,BE,7F,07,A0,46,DF,A7,BC,28,AD,89,AB,25,E2,EA,BE,3F,4B,59,96,06,01,13,4C,7A,54,E5,CE,DE,2A,9B,E2,4A,8B,7B,C2,83,26,70,86,6F,57,05,A5,DB,B2,1D,AA,60,A4,2C,A6,99,29,8F,D7,75,B2,F7,0E,A3,B2,DC,3A,52,C7,44,57,1B,9F,FE,FA,CA,88,5A,FA,78,98,94,8E,1C,C6,2F,29,01,C7,72,B0,44,4D,F3,30,3B,85,9D,AC,3E,40,1F,8B,11,54,AB,E2,FE,C1,10,A6,2F,E6,32,D7,16,9B,AC,C8,F5,59,98,29,18,18,B5,94,EC,67,A2,2A,79,25,32,08,88,C0,2E,EB,F2,E1,91,70,25,86,48,D3,5E,15,E5,42,A0,D0,C0,03,85,76,27,2D,75,D8,20,9F,B4,8F,93,C3,EC,C2,96,5A,CF,4C,62,2E,5C,34,B2,CF,2C,EA,97,3A,5E,37,8F,B5,A4,37,F5,AE,63,87,5D,20,52,5B,69,C7,39,CD,E7,49,81,AB,21,36,D7,BA,19,EF,34,59,95,26,0B,86,19,EE,5E,12,40,F9,8B,06,B8,6C,99,F2,EE,42,3C,47,F8,77,9E,D6,CE,C3,D6,DD,FE,EC,0D,28,EB,60,72,59,E4,16,B6,AD,76,21,01,5B,5D,D7,91,4F,C6,D1,D3,4E,8A,4F,CF,76,CF,BC,46,CB,A9,99,06,E0,97,8D,86,A8,BC,69,35,60,B7,AF,7A,92,CD,C4,7E,6C,FC,07,38,75,E9,E2,9B,AD,78,4F,E1,45,B4,EC,E2,0F,CF,BA,77,53,CC,D7,F2,B6,97,4C,FB,15,84,C9,D2,FA,63,91,05,E3,CF,E5,5D,E2,FD,49,B5,96,3D,11,05,0B,BC,0E,D1,A4,75,A9,32,0E,8E,F2,21,A9,C0,94,05,16,D5,86,4E,34,17,85,C6,54,61,64,8E,BE,0E,BA,7E,C5,DE,57,60,5C,59,5D,29,FC,79,2E,38,B1,6A,37,51,7D,F9,8D,DB,94,ED,0B,EA,A5,C3,B7,F1,91,8E,FD,C4,42,32,39,4B,61,CB,7B,D1,7F,38,13,F2,A2,06,AA,D0,BE,5A,F1,51,4B,1B,99,52,51,07,9C,31,64,AA,BC,3E,D8,97,E2,10,44,B0,19,26,05,E8,B5,F0,D5,51,38,3F,A4,7C,FB,6E,95,D7,78,77,E8,90,AB,E0,80,E5,B0,BF,0F,E2,97,FB,B8,5E,46,FB,70,1F,B9,F4,02,B5,D6,37,0C,6D,AB,DD,52,F5,7A,05,3D,4C,6D,0A,F2,52,4A,77,A4,28,7D,D3,9F,DC,96,C6,1A,10,03,4A,F4,DE,AE,31,44,19,00,89,D9,F3,24,AC,44,0C,57,5F,34,F0,51,5B,9F,52,D3,F5,08,FF,32,35,85,69,FD,EE,88,79,4B,1A,D2,FF,36,B0,F0,DF,B1,D8,4A,C7,7B,71,23,55,7C,12,4A,7F,7C,9F,2E,9F,11,AF,EA,33,30,DD,09,73,A4,1B,91,99,3E,18,61,56,0F,D0,F0,3E,E5,BA,50,0E,46,59,53,EC,60,F6,21,39,DF,D1,E3,A0,34,2B,40,2A,C3,3C,49,34,B3,F4,19,F2,9D,93,3C,F5,52,02,54,C6,E2,8D,13,71,A5,F7,45,C2,77,B6,28,9F,2C,A4,3E,77,13,B5,96,4B,92,12,FF,F6,16,A3,70,2E,F6,66,21,90,E7,77,31,5A,C0,0C,CF,DE,8E,38,0A,E7,64,79,5A,B1,22,4B,55,42,5D,B7,BD,88,E3,B9,BF,68,76,71,4E,CC,09,74,9B,71,AC,12,48,67,C5,BF,BF,19,7C,B1,67,63,00,48,C6,05,40,7A,07,01,76,FC,E4,5E,67,1E,B6,E1,CE,F2,03,4B,60,B8,AD,9B,FA,28,A9,DF,23,4C,2C,45,0C,48,45,0D,BA,FC,C8,E1,7F,D6,73,55,AD,3E,74,66,EA,31,34,8B,1D,AE,1F,50,46,D7,1B,0E,9F,B2,CA,61,3A,56,1C,AA,81,AA,9D,A2,44,58,63,6B,81,3B,E1,C9,5E,EB,34,6E,EC,BE,43,8B,06,52,12,C6,17,9D,94,9A,89,3A,20,F2,7B,83,56,B1,5A,30,EB,09,CE,AB,AC,8A,0A,97,8F,16,7A,77,15,31,42,D3,66,E2,2D,1C,C0,1B,E3,E0,10,E4,5E,82,4D,32,91,42,7B,2F,3F,DE,90,D1,F1,CA,27,0D,9E,84,6D,AF,1E,A8,88,2B,BA,FC,B0,C1,29,29,8B,46,FB,71,A8,25,C5,E0,BA,31,60,99,03,B1,99,18,E2,2E,3B,53,34,9D,7F,AA,3B,CF,A6,94,E1,AD,26,44,44,B5,C6,2C,94,4F,FB,FA,27,C2,1F,4A,20,72,64,A3,A5,27,14,E0,28,B5,3A,94,AB,BF,31,88,19,3F,A6,64,74,6C,E9,FF,27,BF,29,78,D4,76,F4,E6,91,6E,29,BA,4B,E7,0B,4B,6B,A4,61,19,D6,1A,0B,CD,D7,CE,D0,14,19,F5,F0,B0,E4,88,A0,0E,B1,9C,22,84,86,F8,06,B0,EE,AB,27,39,F6,8B,28,7F,34,D7,83,83,FE,32,81,8F,2D,D8,EA,89,8E,5D,00,43,01,DB,51,5C,F6,8A,17,79,6B,47,99,18,0F,E1,AF,91,B0,4F,68,89,92,13,C6,21,79,F6,75,78,43,C4,93,A9,52,94,91,C9,AD,E1,14,D9,EB,42,7E,EC,E6,75,21,75,29,99,E6,54,29,36,41,D8,FC,CC,FE,27,B7,E1,39,DE,0F,95,6E,57,6D,60,71,15,13,A1,18,91,00,4F,6C,F1,8F,B0,34,93,AA,DB,EF,43,88,6A,ED,AC,57,13,37,42,E9,D5,67,F6,00,D8,25,D8,01,04,BF,AB,2A,BB,0F,A7,7E,E8,87,48,E4,7B,5E,C6,F5,40,B6,60,23,90,9B,C6,CC,09,0A,8F,50,8E,4C,27,29,6D,D4,45,5D,64,9F,F4,15,A9,53,EB,95,09,27,CC,D9,58,11,FC,FE,2E,27,FB,E9,2A,77,8C,57,2C,D9,AE,0E,9C,03,CA,DD,39,D4,15,59,B8,61,51,A5,C4,C6,03,36,9D,1E,B3,A0,9F,CE,20,C0,5F,40,75,60,12,EC,9F,5B,E4,45,20,6D,DC,DB,63,52,58,2A,ED,5D,C7,2D,53,50,D1,A9,EB,82,A1,BF,B4,29,9E,57,70,E6,B8,41,5D,A1,70,45,FB,19,28,C1,C1,C1,7F,DE,9C,D6,2B,6F,A0,C7,E2,4C,ED,06,0B,12,8F,92,28,2C,22,40,4A,19,E9,C8,E4,5A,F2,B4,52,AD,1B,88,A3,2E,8F,5C,85,4D,7E,B3,A0,5C,E8,D0,32,8A,1C,BB,B8,32,E6,A0,6D,E1,E7,5C,B9,DE,14,EB,AE,79,C6,A9,68,5E,B0,F8,C8,A4,6D,1D,1B,0C,13,B8,AC,43,A4,B8,DD,A9,FC,8D,A0,43,A3,7C,BF,F8,01,D2,C1,6E,CA,C5,E9,B5,BA,8A,38,F1,2B,A6,90,E5,88,5E,C6,AB,53,70,B2,11,7F,04,0C,FE,90,03,4D,2D,36,47,BD,DA,53,AC,27,B6,6F,4D,5C,5B,19,FA,E4,3F,E6,57,A4,80,79,9B,FF,A0,E4,A9,E7,B7,A3,BA,BD,41,5E,B3,FB,22,48,FB,67,64,B8,22,27,AA,23,1E,ED,28,E7,78,85,6B,A4,DB,12,75,75,39,F9,17,FE,B7,2C,D4,C1,E6,92,8A,CE,E0,58,F9,99,65,FD,14,3F,78,E5,76,2A,D3,8C,64,29,39,6B,7B,80,D3,F5,B3,A8,BA,20,91,55,4B,66,F5,AA,D6,31,65,AC,59,C8,16,87,31,41,4A,36,EC,34,B8,AF,9B,94,A0,9C,3F,65,3A,B7,C2,6A,E3,2A,08,9E,42,43,18,49,07,BC,C8,59,3B,6F,BA,97,98,A0,34,A9,83,42,C2,51,FB,28,50,6E,AA,3D,0B,B8,A6,37,AF,64,00,D7,AC,15,5F,AC,9A,F9,D8,10,68,17,04,0D,62,FF,93,01,58,FD,C0,0A,21,A6,B9,43,8A,C3,1C,77,1C,21,E5,30,72,B2,71,A5,0C,21,58,B6,55,71,F0,5A,01,2F,F1,38,A0,61,4D,85,7A,2A,A5,46,A0,1C,B3,38,F0,D2,29,3C,1E,B2,54,15,7A,DA,39,1B,25,43,49,EA,7E,2C,4F,03,A2,95,96,ED,A4,E1,B7,2F,AC,96,A1,F7,1C,D8,B3,63,AE,9F,D4,B6,D9,FB,2F,CE,49,74,EE,40,12,B9,C9,F3,F5,E7,BB,E1,8D,1E,CF,26,52,D9,C4,CF,95,4B,E2,A7,10,B9,6E,11,25,E1,8E,D7,68,F2,8C,70,84,ED,63,BC,9F,95,11,8C,BA,40,65,43,31,5A,B7,68,48,AB,45,53,C0,D2,DF,07,C3,DE,0C,DF,81,1B,5E,7C,A3,6B,CA,78,12,08,7E,97,2D,AB,EA,BE,30,6B,62,08,4A,B8,B4,5D,B0,7F,F0,A2,C9,9D,0E,B5,EC,83,C4,44,9F,A0,B9,DD,01,0F,EB,E4,15,DB,D3,0D,CD,FF,DF,60,72,3B,36,CF,18,4A,1D,C9,E2,7A,9D,04,C2,0A,BA,02,F0,62,AE,C5,37,FB,C1,49,87,52,1F,79,3E,26,04,88,C9,06,20,56,E4,2A,A4,94,7F,A4,86,71,F7,CF,60,76,2E,1B,5E,BF,0B,DA,79,D5,47,B6,22,E7,49,D7,65,51,AB,B2,67,19,CB,87,94,B2,1D,27,C6,A8,26,14,69,93,12,89,EE,79,B9,8C,59,05,95,16,63,B0,38,A0,3F,2D,01,43,05,FC,A6,F2,58,08,2D,E2,89,50,28,3C,68,DF,5E,1A,F6,09,E3,AE,BD,8D,83,4E,F6,EA,77,32,F6,A9,54,B7,96,DB,AF,2A,4B,29,6A,25,FA,3F,EA,69,D7,DA,8F,FF,02,77,C7,5B,04,63,C1,39,22,E4,AE,06,EB,36,CB,05,C6,7F,A0,9E,8E,0F,5E,20,78,33,A6,EB,59,7C,E1,77,C0,D7,16,5C,4A,B8,34,1E,5A,32,BE,8F,57,3F,54,B6,7E,FD,22,DB,9D,50,A8,A0,2E,DF,76,B5,26,D2,8A,A6,4E,9B,DA,26,66,A8,C3,31,D0,82,CC,D3,89,80,00,A3,F2,B4,2D,A4,C3,81,5E,80,74,4E,C9,A6,10,5E,56,27,70,16,B6,90,17,24,92,2E,6F,B0,06,4A,EA,41,28,32,B3,2E,08,4E,D3,73,70,EB,B3,26,63,14,51,4F,83,DB,6A,ED,73,EB,D0,C2,5B,0E,A6,09,A3,9B,9E,68,78,95,F8,40,2C,0F,30,32,68,22,50,7F,28,14,15,F6,AA,3E,4F,48,9C,B1,E3,DB,1B,AC,3D,3A,D0,BA,03,70,96,15,B3,B1,A4,F1,1A,78,BE,97,52,C6,8F,B9,F7,DE,91,8F,66,EC,B7,0C,36,41,24,01,FD,E7,4D,52,06,32,14,89,EC,17,F1,39,3C,A3,DF,6B,9B,62,C0,8E,53,A0,D1,45,2C,91,B2,46,E3,0E,05,C9,E3,61,42,24,5C,01,12,A3,8F,30,57,0A,AC,8B,E4,89,39,C0,39,4B,25,A1,46,64,BA,87,DB,7B,61,0B,1F,3A,15,74,21,74,97,3E,12,54,A1,78,73,70,DE,2D,3C,E7,99,F0,77,EC,D7,B4,D0,02,20,E4,11,D3,D1,2E,D5,B3,91,EF,21,AD,AA,1F,C8,32,1E,B0,3B,D4,17,4D,6B,8D,74,AF,4A,5D,83,B1,FD,26,81,F2,F4,FE,39,B0,80,9B,26,A4,26,7F,0E,5D,C9,54,7C,AC,0C,5E,23,21,CD,7E,EA,5C,C7,02,67,3D,77,42,F9,6C,5D,BF,E7,39,57,93,29,C9,C4,2A,BA,4B,A0,D4,0A,72,DA,4B,C6,AB,1F,3D,92,BC,87,FA,4E,CD,86,C7,35,94,0C,22,AA,EF,73,98,24,67,E1,99,EC,0C,28,DE,09,B7,2F,CA,43,48,2E,C9,A8,D7,F8,F0,A6,DE,17,40,5F,70,71,3F,0A,4C,71,8C,88,80,C9,E5,8E,50,6E,71,B1,D7,49,7B,63,D3,C5,C1,58,BE,4C,58,13,D2,27,95,45,42,67,49,40,F5,FD,CB,12,96,DF,FE,31,54,95,E7,85,78,38,1C,1C,7D,88,1A,2A,8A,28,30,2B,44,CB,14,AE,7A,4F,EF,E9,EE,CE,4B,34,15,D1,87,17,CE,82,CB,AB,D7,C8,10,69,D7,FD,64,63,55,61,34,83,25,55,E1,EC,67,90,82,34,CC,D9,58,72,93,45,B7,1E,80,B4,9A,C6,E4,D5,97,67,E3,9E,1B,38,72,F5,64,70,1F,B5,00,AA,C9,EC,14,DC,9C,D0,92,6C,32,FE,38,60,73,6A,5E,CC,50,41,07,54,F7,B4,E0,25,BC,BD,A2,19,F7,A9,C3,A4,3B,6D,7A,2C,6A,26,75,0F,48,AC,D5,9C,21,A2,1F,0E,F5,84,47,52,A4,C6,71,23,44,B5,8D,FD,40,87,47,56,F8,C1,E4,C5,77,15,73,EF,F1,F0,E0,E0,C6,38,FF,70,D3,77,66,1B,19,A3,8A,E1,DE,5A,7A,24,CE,AC,E7,33,41,43,FF,FE,83,DF,FE,43,9F,08,C1,F9,98,B9,4F,E4,AC,2A,F1,0E,2A,BB,0D,23,59,5E,BA,61,61,BC,3C,62,CE,FA,60,63,7A,38,D8,CF,25,06,F7,20,E3,85,44,FB,A2,DD,C6,71,5D,17,EB,4B,8A,40,FF,30,1E,00,D9,3A,09,26,A3,CF,69,06,4D,D2,13,09,ED,D7,5D,3F,ED,68,26,25,F9,42,DF,62,43,CD,D8,5C,CA,DC,96,33,B0,18,05,16,23,16,D2,A8,2D,D0,3F,79,9A,45,FE,EE,41,FA,26,C7,EF,CD,15,B2,4C,CF,93,48,32,FA,8C,A5,7C,60,19,24,69,F7,4A,BF,85,B7,6F,41,9C,17,F1,3E,5E,94,33,BD,DB,B1,F9,D9,E2,FD,ED,44,B4,7E,E1,08,ED,A4,F0,68,64,5E,98,1F,2A,37,ED,01,68,50,A6,E8,6F,D7,3B,7A,27,C4,D3,EF,00,60,AB,B3,A5,4B,75,30,D4,18,8A,25,6C,12,9B,0F,60,3F,63,6B,5F,8E,CA,B9,83,24,D2,D6,03,35,FA,36,A9,84,75,5B,99,47,89,03,34,5E,8E,C9,4E,6E,1D,C5,77,51,9C,C5,46,28,F3,B3,B3,97,4A,4C,B9,D0,DB,F2,F1,0E,AC,B7,AD,29,12,D5,FC,86,B1,A9,9A,FE,79,08,B1,0C,33,49,22,E3,6C,26,15,E6,52,66,8D,BB,FD,66,40,2F,C2,63,FE,30,02,57,73,38,8A,82,64,CB,95,7A,F5,10,7B,88,D3,C5,EA,05,D1,A7,78,2C,2C,F8,71,3D,B9,B4,1E,38,E6,0B,61,C2,D1,87,CA,15,F4,E8,9C,13,4B,B6,6D,7D,25,4F,CF,F9,21,BC,8E,5E,54,36,C8,2E,D8,D2,CD,DD,0A,83,83,4C,CE,C6,37,52,90,87,58,8A,6F,00,E4,98,9A,F4,AB,18,0B,50,5F,E9,2F,7B,1A,F0,20,47,A3,D4,AE,03,99,F7,6F,74,44,75,7A,91,12,3C,C2,58,BB,71,3C,37,6D,95,5C,0F,A7,55,B1,90,14,7D,6B,C0,BC,3C,21,B3,DD,E2,DC,F5,D8,A7,24,C0,43,8C,F0,DE,1F,AA,14,0D,3A,97,E0,B5,6B,9A,57,13,9A,76,4E,3D,35,DF,68,75,17,F9,72,FA,20,D8,6E,93,5B,18,C5,4F,52,1D,06,F0,20,72,DF,4C,39,00,AE,30,DF,34,63,95,08,2D,2B,37,F0,80,C1,8B,B1,D3,8F,27,BF,58,13,01,E3,D1,7A,08,20,AD,63,AC,2D,EE,78,C3,03,B0,68,AB,57,19,AB,DD,6E,8A,4B,D8,F7,03,53,FB,59,80,77,31,FE,99,54,46,D0,99,BF,38,2B,B5,AC,18,5F,61,4D,B3,2B,D8,A4,4F,7C,9C,1D,2F,CD,46,CE,59,9A,E9,7E,94,A6,C6,C4,31,76,E8,37,F6,F8,10,80,54,78,A9,57,DA,C1,CA,AD,33,08,AC,22,5A,22,8C,E0,F6,A1,DF,33,C2,43,E4,99,B3,31,2F,AC,00,B7,8A,F4,B6,72,75,0C,06,0E,B6,86,11,90,1A,54,47,CC,48,F4,02,97,70,0B,CC,06,B3,0F,2F,D1,D8,08,C7,74,A9,0A,D9,E8,00,AF,B5,35,21,46,64,61,3B,94,CD,73,2D,C1,E3,09,51,A3,38,E4,0D,58,C4,BE,72,42,25,B2,23,96,06,4C,B4,29,64,A8,06,3C,11,42,C8,1A,72,01,34,AD,A3,35,3B,85,61,4E,9B,DC,38,9F,6B,7F,B1,E0,86,CB,7C,8E,6F,DB,81,3E,AB,7E,3D,A3,AD,71,30,14,F2,1B,2F,D1,50,39,DD,4F,12,33,7D,99,94,48,96,CB,76,80,F5,95,80,F0,09,57,F3,6C,B0,1B,C1,CF,EA,BE,ED,98,01,BA,A1,E2,99,D3,E6,8B,8D,A6,39,4E,98,E7,5D,34,40,CD,CD,1C,B5,F9,F7,6D,20,8A,84,F7,D7,B2,73,1D,D4,84,27,A8,FC,2A,61,D8,9D,63,76,68,CD,0B,D0,0E,D3,F1,DE,BA,DA,5D,B9,99,30,DA,A3,D3,F7,8B,87,B8,0F,34,99,23,D7,4E,C4,57,CB,0F,30,03,61,83,E6,41,56,EE,00,B3,04,25,AA,DB,CD,13,A0,21,B7,EC,5C,3C,A0,28,12,37,B5,26,1B,D4,07,80,C5,EE,B2,AD,DD,54,A2,A3,29,E0,D0,F4,62,7F,61,85,81,D2,75,4D,B1,DC,38,36,0C,74,D5,1C,A2,A5,B8,8E,07,09,0F,FF,D4,4F,A2,A0,7C,73,91,ED,B8,4D,ED,B0,D8,EA,31,9E,F6,DF,E2,9F,07,31,A0,34,66,06,56,CF,0D,79,91,01,23,E0,52,A2,95,5D,38,4F,DB,75,4F,B8,01,C1,01,BD,2C,14,19,11,A1,60,7D,8E,2E,D0,31,86,F7,09,E4,11,06,4B,4A,29,49,E6,3C,10,E5,5D,BD,93,39,1D,92,D5,79,F7,FB,C8,87,17,C9,D9,35,7D,B5,CD,95,E1,20,F0,6B,36,7B,54,26,81,22,8D,7A,EB,2B,E4,A4,3B,C4,52,3E,5D,E4,E3,48,B0,E1,79,64,82,3A,94,1C,6D,35,55,7C,11,DD,B6,9E,83,4D,06,67,72,BB,DE,0B,2B,0A,31,55,16,62,25,04,BA,96,CA,53,C5,B6,28,BE,B8,90,8A,C8,9E,31,1A,56,D2,2F,44,10,08,ED,01,87,A9,DE,19,F5,A1,FE,A3,CA,34,D5,51,F3,6A,1C,16,5C,CE,3F,37,69,FD,63,E9,6B,A4,FD,1F,21,D3,DD,1B,FF,0A,6B,92,63,CD,23,AA,37,43,C1,89,54,83,EF,99,4A,6C,29,8C,C3,0A,19,3F,59,BA,A8,11,84,83,97,0E,50,B7,79,35,FD,C8,CA,6F,D7,7E,DF,5D,F1,DC,C0,69,4A,99,FC,F6,3A,01,FB,66,88,03,6A,83,45,0D,F6,C7,F3,4B,7C,D1,7B,DA,74,CB,42,6B,58,C8,E2,16,09,EF,B7,2A,78,72,2D,F8,65,C1,5B,58,BB,73,BB,DC,1E,B0,2C,20,1F,EF,A9,E5,2F,2D,50,BC,F5,EE,75,1F,97,6D,F5,D4,EA,09,45,28,0B,32,F6,EF,F0,9E,72,DF,C0,6B,7D,B3,CB,2E,E8,FD,A2,DD,48,A7,34,82,7F,2D,A0,82,18,A5,9D,58,06,85,10,49,8F,83,2B,64,E5,36,41,E9,56,D2,A4,22,F9,A0,75,35,2B,9A,2B,C7,E0,F9,1F,61,1F,97,01,EF,34,6E,ED,E5,FE,49,E7,B1,5B,5A,6A,37,5C,6F,A1,E7,C3,74,C5,1E,AD,AD,5A,0A,27,C1,BA,B6,4D,8D,52,3A,38,74,79,DB,3C,25,44,00,DD,05,5E,2D,A1,D8,A2,7C,01,16,0D,8F,F6,A7,70,C6,E8,5E,33,E7,96,2F,F0,DE,DD,ED,73,05,D5,19,5C,63,8D,C8,88,83,0C,A3,70,B2,CA,C0,1E,65,65,83,91,EF,AB,39,47,84,FD,EA,08,85,F7,1F,CC,03,A8,19,48,C3,5B,EA,AB,F8,D2,C9,04,D5,9C,A5,50,1D,3C,4A,7D,99,E4,EF,54,46,94,98,36,11,14,95,B4,E8,59,F9,3F,74,EA,0B,50,2D,3E,DB,14,DF,7E,BB,66,5A,38,1B,D5,94,32,44,5B,33,1C,E3,99,7D,D7,78,E9,2F,84,97,08,AA,21,4D,E6,BE,42,31,BC,0B,68,6F,C6,02,0A,7E,41,43,FB,5D,79,54,5F,D4,23,F3,25,CC,22,63,A0,CD,75,15,D6,B6,47,5C,C2,B8,90,C6,63,5C,62,14,1B,97,F0,63,F1,B9,45,DA,C6,51,E0,29,03,08,AA,F6,78,78,20,FD,21,91,E8,14,F0,DB,CA,79,EB,01,6D,CD,07,3E,76,03,6A,97,A0,78,3E,3F,BA,51,76,0E,B3,00,F6,9D,7B,CC,CB,D8,26,44,BA,F7,78,E7,4D,56,8F,8E,9F,33,42,58,0E,2B,EB,A6,F7,0B,59,3E,A4,36,7C,1B,39,C5,2B,7B,5A,26,DA,9E,74,10,F9,8A,5E,F9,17,E5,42,6C,3C,AA,4B,06,DC,C1,D1,83,98,C8,D5,6E,09,CE,CB,23,68,34,94,01,7C,67,3F,A3,E6,2B,AD,C8,3F,EF,2E,C0,E8,CF,A5,69,5D,C0,EA,32,E8,91,AF,9F,8F,D4,F3,06,4E,82,C4,CF,C0,5B,18,7E,EF,EF,EE,76,5D,5E,D0,C5,9C,A8,F4,C3,19,6F,36,E0,8D,45,47,5F,6E,22,B7,39,46,1D,89,02,EA,D9,46,3D,B1,CA,0F,21,F0,7B,1F,E7,1E,C4,E6,8F,E7,26,D1,D9,77,E1,A5,2F,CC,49,32,4B,5C,F9,1B,06,B1,65,0A,E0,F9,6F,79,5D,AC,04,A2,E6,C2,85,0A,7F,6A,0E,28,CB,FD,2D,15,62,09,D9,A7,05,C1,2E,08,B5,DC,E0,B2,B4,04,D8,4D,14,98,0E,10,A0,2F,C6,61,32,78,29,8A,FC,4A,F6,ED,4B,9B,82,D4,E2,18,80,4F,A3,8C,4D,32,04,3C,BC,D7,EB,E1,8F,EB,BC,69,61,72,C8,12,BD,0C,18,5C,56,4A,C2,FE,B6,4B,C6,11,42,92,BD,A9,76,BD,96,C5,F1,C3,8F,21,CD,85,69,BB,01,E1,11,D2,D6,5E,20,95,90,6C,CC,05,DD,B1,AE,4A,F4,91,0D,98,F5,9D,D5,B0,76,26,B7,56,FE,F6,8E,67,7C,3E,F7,4E,74,BD,5E,E6,36,EB,02,D8,AD,C2,C3,0D,1A,62,FC,1C,3E,DB,FD,3B,30,E2,6E,8F,C7,D7,02,6F,72,D1,B7,42,0E,B6,EE,2F,A3,8F,96,C0,DE,7A,EC,0D,B8,B3,85,1F,86,F3,A5,5C,79,B0,CC,F7,77,D5,2B,DE,62,B5,F4,1E,3D,9A,87,13,70,31,8E,B9,3D,8D,E1,84,AB,61,E9,63,38,C3,7C,6B,48,48,15,7C,BA,DE,60,E3,D3,56,77,17,7C,54,9E,51,85,6A,0E,7D,94,A3,62,22,92,A4,0A,F4,57,56,5A,C9,4C,BA,F0,27,69,7B,A8,4F,13,FF,1A,6F,B3,2B,D3,A8,A2,2E,67,ED,00,D6,9C,2E,99,BD,4D,7E,AA,F0,38,2A,02,25,CE,5F,A7,EB,F4,19,06,CB,53,5B,4D,5F,93,41,03,15,7E,2C,88,99,99,D4,42,EC,24,31,AE,D6,95,CE,EF,FC,AD,EC,4F,E0,9B,2A,C4,C4,A8,0A,AD,C8,C3,58,CF,C3,7A,0F,C8,12,C9,AD,BC,05,EA,FD,B8,E3,69,37,4B,BD,88,56,14,6B,90,30,CC,7B,1D,5F,61,DD,19,E3,1B,DD,48,CB,F1,4E,C3,E6,FE,FD,AE,F3,E4,55,C1,C3,9B,B8,A4,03,27,A9,32,83,B0,AC,78,87,C0,2B,FE,D8,28,CA,F9,80,D8,AF,1B,47,3E,72,19,20,7F,6E,DF,78,D5,A0,FE,85,91,7C,A2,5C,EA,E7,25,45,43,45,77,97,84,3B,CB,67,13,A5,E3,04,AA,22,75,E5,7C,D4,CD,E2,BC,65,82,4A,89,C5,9A,FC,0B,EC,89,EE,1A,CB,E8,A9,26,23,20,41,73,DC,7D,41,AF,A3,A4,FA,5A,EA,E1,25,53,74,97,B3,C6,C7,C6,41,20,7D,5A,89,17,5A,C5,CA,54,20,88,3A,F4,DA,1E,D8,53,7F,0F,DB,11,2C,24,EF,30,AC,54,82,3E,B8,0A,9A,97,40,40,21,DF,62,CF,0B,A9,5F,1B,BA,E3,6F,79,6B,2D,6D,08,08,D3,50,04,53,A6,CA,7C,65,C0,91,F3,B6,A5,B3,2E,F4,D4,19,4E,0D,98,39,8D,CD,38,59,F6,46,17,08,C5,59,89,A4,98,B6,6D,15,98,5E,B9,17,9C,27,6E,27,90,F7,29,8E,A9,79,63,7E,3C,F4,E0,05,1F,FF,B5,7E,6C,DE,66,00,6A,4A,C7,9D,7C,83,C2,02,BE,AC,AB,6E,15,DF,CD,8E,9C,66,95,18,E4,8C,9A,47,50,04,D4,A5,32,66,61,9C,F1,03,AB,0F,43,C7,B8,43,E3,2C,B9,3A,AB,C8,98,ED,8C,CA,87,87,B4,1D,65,B7,9E,13,CE,93,06,7C,58,A1,4F,7A,21,20,83,66,E8,A8,FB,8B,32,09,0B,0E,C7,5B,36,42,21,A2,81,9C,81,C5,CA,70,97,A5,CE,4C,B3,93,65,D0,27,0D,E9,CA,37,E3,E2,2C,8E,58,8D,93,D0,71,37,D6,2E,01,7B,48,C2,C0,6E,83,4E,97,0F,81,FA,37,DC,75,2E,54,30,09,87,E6,44,84,4B,90,5B,11,B2,91,AF,AD,6D,99,EC,D5,6F,22,B4,07,F8,C2,57,D5,B5,04,A1,7C,5D,CF,AA,D7,1A,12,CA,18,A9,0B,4C,5D,DB,D2,24,27,5E,CA,E9,9A,C9,2D,72,96,B0,6B,23,40,97,FD,8F,1D,83,71,D4,DD,97,F1,94,03,E0,00,BF,A3,84,E3,90,DA,DC,9D,46,21,EF,88,65,4D,CB,03,88,8E,C9,27,2A,3D,0D,F5,97,93,1F,9D,54,06,1B,CA,D7,08,69,E8,5E,FE,EB,49,66,21,DA,9F,B3,17,4F,96,19,88,92,E3,37,F0,EE,01,7A,28,54,B4,84,3A,44,FC,0B,C9,43,01,82,25,1C,7B,18,74,EA,CA,6F,87,8F,2B,1A,26,A6,27,7C,5F,0E,6D,92,E2,04,0C,88,B5,BE,CD,6D,65,B5,C6,7E,D3,3F,7F,B1,CA,54,A6,74,7D,B9,20,D3,5E,C3,A3,2B,7A,FC,41,07,46,6A,52,3D,DD,E3,CF,B5,53,9B,8C,8F,57,75,C0,AD,DD,13,60,6B,BA,C4,53,DA,7A,2E,2D,ED,16,55,0F,05,E2,00,F7,27,42,CD,04,EC,6A,28,9C,B5,F9,BA,51,9A,12,E9,80,92,40,D5,B1,99,A6,42,29,75,B7,A5,43,A0,2B,6B,C4,09,FA,9F,E6,CD,7C,75,CC,C1,56,FF,B2,11,39,21,91,C7,59,8D,95,F0,31,81,3D,61,89,EA,5F,C0,1B,07,B6,10,C2,13,FA,AB,17,D6,CE,10,FD,D5,2E,75,3E,CE,B8,C2,15,EB,43,A3,A4,26,E3,74,0D,2B,BA,CC,D3,FE,9A,79,76,F4,60,9D,7F,57,F1,D4,BF,82,1B,FA,A9,DF,1E,55,08,91,7C,EA,80,E4,FE,21,4F,F8,29,E6,D6,9B,48,63,90,33,37,A1,3B,BB,3E,26,FD,77,0C,F7,C4,1D,8E,64,7E,D4,12,31,FE,E2,FC,A9,69,02,61,3E,97,D6,1F,81,C3,B2,B6,C3,7B,48,8D,42,54,05,EB,54,55,11,FC,12,E1,47,B7,EA,60,E8,60,9B,B0,25,92,58,18,0D,AC,5B,C7,71,E9,26,3F,05,6D,E1,7A,CC,92,9B,EE,1E,A5,83,2F,2B,D2,0E,AA,B8,52,08,B3,2C,31,99,49,6C,76,00,C4,6B,A0,46,73,CB,68,9D,62,53,66,23,07,42,23,EF,57,71,C9,75,F1,C1,72,F2,F3,1B,9B,BD,FB,8B,8E,7E,B4,A4,50,CF,0C,3A,EF,37,4C,81,67,F0,02,3A,9D,6D,1E,60,3B,B9,9E,27,8F,51,8B,AF,03,68,24,01,9B,16,28,A0,89,31,BC,8F,3B,C2,70,38,4B,50,2D,C1,E8,EC,A6,EE,2C,FC,0F,2F,14,B1,7B,F7,25,08,17,24,EE,EF,0E,5E,D0,AA,29,EC,EE,FB,3A,DB,29,9C,6C,27,85,87,E6,FC,7D,40,22,35,07,AA,25,AB,61,D0,21,7E,9E,6C,4F,0A,EB,F3,74,07,47,DC,2F,32,F5,36,86,79,BD,C8,BF,48,5B,3F,A5,26,2D,05,E9,2D,B2,10,E4,E3,41,D7,8A,04,96,4D,01,17,7D,62,85,C2,19,B6,75,DF,B2,2C,A4,BC,D4,75,98,60,3F,A0,E5,F7,47,F4,8E,E7,1B,A6,71,07,A6,DC,5C,F7,62,59,20,08,83,DE,9F,89,6B,16,EE,85,2E,53,FA,33,5C,37,DB,CC,6E,3E,62,15,EC,C5,B7,31,AA,0A,D9,55,7F,70,94,BC,07,1D,6E,A6,0E,AB,6D,BD,43,54,C5,B2,70,FD,25,9A,BD,FD,CD,08,C2,FB,92,71,52,03,73,10,E1,67,76,80,94,FF,65,27,60,41,66,2E,8C,67,D9,FA,E2,2F,CF,FA,4F,75,C1,A6,CF,CF,32,B2,10,57,AD,97,46,DC,AD,93,58,8A,2B,F8,E7,D4,E6,8E,65,58,A6,42,E6,82,95,D9,40,38,E5,E9,7C,B8,AD,65,ED,D4,E5,37,D2,93,8B,3F,B0,01,EC,DD,95,16,79,37,FD,2A,C1,D1,07,16,8B,BC,D2,FC,3D,23,CB,49,3E,31,47,0F,41,FB,EA,03,22,12,BB,8B,EF,37,AA,F5,CC,05,64,97,86,77,B9,0E,00,0C,5E,9D,86,A7,7D,EF,C5,06,8F,5C,1F,7F,FA,4D,A2,47,D2,A6,76,87,AC,34,3F,EE,38,37,05,C7,11,66,1F,A3,F7,B5,EA,73,24,7A,49,7D,EB,E4,C8,AD,53,9A,E7,76,74,08,BE,E3,36,F0,23,77,7C,E2,C6,6A,C5,AC,34,5A,B0,32,2D,15,D7,C1,C7,47,8D,E7,F8,A6,64,0F,5E,D0,C7,C7,81,59,F5,58,36,00,45,3B,A7,2B,A3,AF,F0,8C,B3,8F,C8,38,BA,FA,09,38,21,5A,3B,6E,78,AF,BE,C6,D6,E6,EC,D0,A4,0A,AB,A6,8E,A1,1A,DF,51,26,C6,17,E4,A4,25,DF,E4,56,C5,06,28,23,C0,BE,16,5F,35,BF,11,6A,C5,E6,7B,5B,EA,56,86,E7,06,62,9A,DA,B1,81,15,17,E3,E4,11,7C,28,9F,79,13,69,82,80,BD,B6,4D,EA,A9,AB,88,FC,F4,25,EA,AD,27,C8,37,74,66,00,1E,E7,FC,2E,99,FE,78,C6,E3,3F,0C,A1,82,F9,15,45,59,16,86,AD,B8,1D,1A,A3,0B,15,BA,17,1A,93,B7,10,95,1A,57,B2,8E,52,27,0B,36,F9,4F,99,CE,3C,D3,C5,5E,99,0B,30,68,92,5E,F7,D8,0F,F1,A2,0C,54,5F,29,60,61,74,F4,C1,BE,AD,2E,DE,95,FC,5C,FB,62,60,80,36,E3,CE,A0,5F,9F,35,10,CE,2B,33,68,0F,54,80,4B,87,6A,BB,6B,91,39,95,F8,67,23,AC,0D,CA,1A,60,04,81,64,2E,70,79,1A,FA,49,2E,6D,EE,09,C0,72,37,56,52,29,0D,DB,3F,05,9D,62,C2,55,87,FF,46,97,4B,82,F3,04,25,F5,F7,14,D2,67,49,73,D7,89,23,9C,27,EA,36,65,A3,A9,B2,93,15,3D,FD,3C,FB,D2,26,E8,54,AB,53,3D,3F,D6,E9,A3,87,DA,9E,F7,C5,47,EF,9E,3D,CA,4E,4B,A2,8F,3F,3C,25,47,F0,39,F0,49,0E,4E,6B,7E,DD,E5,04,E5,BD,86,6D,D5,F3,D4,55,A0,A4,A0,0B,D1,4F,AA,0C,8A,57,41,8A,3B,90,1F,03,88,0A,37,73,25,36,97,17,4A,EC,40,B1,09,8A,96,5F,00,14,55,4D,42,2A,D0,9E,24,AF,D8,B1,19,5E,D6,7F,2F,E5,8E,2C,F5,7F,99,21,D4,98,51,09,C8,74,E1,08,E8,D6,B8,06,41,D9,80,7A,A7,4D,15,38,80,22,2E,70,E3,2A,A0,2D,B4,50,54,C0,72,F8,ED,E9,F3,8F,0B,7A,88,5F,55,2E,A0,61,0C,26,AD,1D,B0,E9,26,0E,58,56,3A,72,4C,2A,0B,FD,23,03,4C,6C,3D,42,3D,A0,14,0C,68,ED,E7,C5,81,BC,D7,65,6D,EF,34,F8,03,90,0D,E9,3B,9B,CB,A9,06,42,F5,73,F6,FE,EC,02,9A,30,01,D8,7B,2C,F5,A4,AC,A8,59,2F,C5,F1,E9,05,C4,F6,59,3D,0B,53,BE,37,79,00,17,75,ED,B3,2B,B8,05,D3,3E,16,E9,AA,D2,72,FF,12,C0,EA,9E,A9,9B,E5,DC,EA,8C,D4,60,A4,E4,DF,FA,E4,AB,32,56,E0,B8,99,D2,14,65,10,2F,D5,A8,68,94,D8,7E,87,BC,01,5E,80,A1,77,A6,A6,54,0B,0F,6E,B3,21,57,E7,F4,6A,B4,65,67,AC,D6,F8,13,69,54,38,75,42,47,81,EF,96,47,B7,D1,0B,39,05,52,78,82,65,26,78,0D,AA,90,97,E0,28,BA,8F,11,CF,2B,78,8A,32,77,04,B9,F3,00,4D,96,44,EE,A6,2E,07,59,B1,36,05,9A,D4,B3,9A,19,C0,B1,36,C8,34,C3,EF,19,E0,FA,2E,A9,9D,D6,91,98,AE,DE,AA,32,F6,1C,5E,CF,70,95,15,0E,5A,E6,8B,72,DA,2A,A7,F4,03,A1,AC,59,A4,54,3F,B2,41,45,93,47,5B,51,E5,E5,01,21,B5,9D,DA,F4,49,A6,C7,E6,CB,7F,F0,5B,13,72,98,7C,41,AA,A2,A6,AB,5F,FA,F4,B0,98,30,B0,60,F9,FD,02,C6,CA,4E,46,06,F5,BD,05,5E,FB,DE,E5,B5,E1,1F,EF,B5,E8,8D,E6,C5,4E,56,1A,81,AB,B4,CC,AF,FE,7D,4D,2D,69,F9,62,A8,49,38,FF,62,2C,9E,DB,2C,D1,7E,5F,A0,5D,5A,AE,08,D9,8A,22,D9,5A,51,D9,3F,47,B1,9A,04,C1,B6,3C,6B,31,0A,2C,B0,9E,A3,49,82,C3,CC,A5,59,F7,C2,F1,D9,83,C6,F4,C2,E0,CE,68,13,AA,AF,83,1D,CD,B5,93,6C,2F,2E,F4,84,58,AC,49,47,B3,61,39,C0,9E,4A,80,29,2C,89,93,B5,94,B1,4B,85,EE,63,29,DE,A4,CF,E8,9A,88,D6,E9,29,FD,79,0B,93,FB,DB,39,88,C7,F6,37,47,C8,73,CF,65,80,2A,6C,9B,12,3B,1B,F0,18,03,0A,55,40,07,C6,01,EE,E3,EF,18,EC,7E,62,65,06,A2,BC,63,49,BC,34,61,E8,4D,4C,04,A7,5C,CC,6F,45,E5,5B,9C,E2,1C,87,B2,A2,F6,43,19,59,50,F9,4E,2C,4A,55,6D,E0,FB,98,7A,C6,F3,88,43,4C,4A,3D,3B,6E,FF,5A,2B,AB,79,75,2A,BC,EF,12,74,3B,64,7E,E4,11,EE,C9,23,3F,91,45,B1,08,69,51,D9,1F,03,39,99,F6,8B,07,73,5D,E7,91,90,68,55,85,73,29,50,61,49,DE,BE,EC,E7,12,3E,FC,4E,D0,0C,99,F3,0E,C9,D8,39,61,A0,35,5F,32,B2,6B,0E,18,95,4A,95,F0,19,ED,05,4D,89,88,39,A8,37,9E,D5,7A,14,E8,70,36,FD,B1,EF,31,EA,20,05,B2,DA,D2,F1,BF,83,11,5C,77,35,BC,7C,CF,38,3F,14,23,81,4C,16,3E,E7,49,76,DC,B9,9D,72,F2,65,45,56,20,13,37,EC,B9,D1,3C,24,C8,E8,04,01,5F,4B,D7,BA,EE,A3,09,12,82,88,16,CA,06,3C,FF,03,39,E8,7D,C4,52,3F,83,59,97,39,F7,07,75,7C,AF,EA,DB,01,A5,4F,F8,77,5C,AF,7A,10,9C,5F,78,99,17,BE,8F,17,D8,A1,F9,89,DE,EE,5D,0F,25,5E,38,85,B3,87,41,41,C7,E6,B5,15,ED,E5,81,C0,2A,70,66,1D,A1,45,CA,16,4E,FE,07,14,36,92,5A,95,7A,4B,B5,35,90,B9,02,01,D2,79,71,24,FB,63,F3,D1,C0,E0,40,1F,01,B2,41,D2,5C,88,4A,F2,11,A4,48,94,81,91,C7,2F,67,1E,26,37,63,25,F7,C6,4C,1C,5D,70,84,7A,99,34,D9,79,71,62,75,E7,53,5E,0A,3C,0F,8F,26,41,A6,A1,EB,40,70,C3,A4,71,08,2D,E6,65,D8,5E,B0,98,79,08,DD,6B,5A,9C,54,45,F6,9A,CB,E8,CF,0D,FD,61,49,B2,18,63,4D,92,82,CE,FC,DF,64,B5,5B,67,D8,73,DE,8C,4E,0B,CD,87,39,E5,81,31,CA,DC,54,85,FA,FD,10,80,9B,78,04,2D,CF,40,0F,4F,F8,E6,B1,D5,97,A4,3B,E1,57,B6,79,14,A8,8E,78,D4,E2,AA,80,28,00,D2,1B,62,60,6B,62,71,45,2B,2B,E9,9A,55,4E,08,E3,6E,CA,FB,F9,62,6A,7D,4B,26,82,FE,E4,99,8B,80,32,DF,28,6B,D1,45,B1,85,10,F7,6B,6E,50,3B,BB,D6,C7,DA,43,3E,09,85,A9,00,A0,2C,49,54,86,7B,AB,20,E3,94,10,D0,9A,13,87,0F,42,06,39,48,50,F3,0D,44,88,A8,74,A4,25,FD,46,F9,30,34,01,11,00,93,16,B2,68,0A,3D,84,F5,69,34,E8,50,FF,4E,C5,55,43,9E,D6,1E,92,C1,60,00,9E,37,57,18,4D,15,6D,B2,90,9D,37,1C,77,EC,EB,DE,2B,39,8D,D7,1D,8C,A2,6B,40,ED,EB,9B,83,EA,5F,A9,AA,CA,A8,50,A7,8A,1A,15,B4,C2,ED,28,6C,27,C2,24,C4,CE,A7,1D,0B,6C,82,36,79,15,DA,2F,C4,4B,96,57,B3,6B,78,D0,57,E4,C9,FE,CA,94,FB,6A,33,33,A0,10,00,AF,DD,14,31,89,A1,2F,6F,5D,BA,2E,5D,43,12,53,23,C3,18,BD,F3,08,6F,1C,C5,5C,AF,4E,33,6B,CA,FC,D5,BD,FA,3F,CE,80,8B,A8,D1,A1,17,D0,09,07,1E,86,35,B8,A6,AE,0C,79,07,13,2C,DD,C7,E6,01,0E,25,48,D8,FB,3F,04,92,85,73,01,22,6A,20,63,23,0D,70,2E,7F,A9,40,31,36,12,BA,FA,C8,B1,9C,06,B7,DE,98,7C,5A,80,90,AD,CD,28,34,AF,04,D9,C8,02,3B,D5,7B,57,21,50,1B,2A,5F,D1,62,2D,45,A9,98,43,19,9E,D0,89,C7,8E,6C,26,ED,48,F5,CA,D2,17,55,BC,48,28,1C,B9,0A,29,F6,46,4F,1D,D4,CC,0F,E3,0E,F9,B2,51,99,32,2F,CD,22,69,25,23,06,B8,82,23,B0,D8,DF,63,28,68,9C,1E,46,80,0C,E7,8E,64,2B,E6,8E,3D,EC,EF,D1,B0,89,1C,54,3E,0E,03,0E,A9,E1,5E,9E,83,08,CD,E9,63,0D,DF,D8,73,70,49,62,34,E8,ED,B3,F6,E1,B3,F2,33,71,46,70,62,93,AE,67,D7,76,CF,BB,11,10,C9,04,04,E0,FF,53,46,AD,F5,09,2D,24,1F,7E,C9,C2,C3,49,AC,D7,86,50,65,06,FE,B1,0B,9E,AD,D8,7C,A0,3B,57,B4,6E,C8,86,E8,1C,7B,26,20,39,52,CA,5A,6A,58,8E,46,8D,20,EF,4D,3D,56,A8,DA,19,57,97,FB,13,34,C7,D2,67,99,5A,91,BF,AA,A2,59,A4,E1,87,2F,87,F7,39,1F,7B,C3,EE,A2,8A,77,32,96,67,7E,73,0B,DC,9C,CB,3B,0E,3E,B0,98,DB,72,50,44,8F,00,05,1B,8D,F2,3A,05,CC,DF,A8,FA,42,9B,35,80,EA,FE,A2,BF,60,16,75,B0,4F,DE,F8,CB,09,75,C6,B6,8B,EF,B6,B2,39,34,F0,0B,9D,01,B8,1D,11,1A,39,68,32,4F,14,F7,15,DE,B5,24,28,C6,2F,55,C2,31,DC,E2,80,22,8E,D6,0C,7E,3F,C6,87,E7,44,5C,3A,07,70,70,62,68,09,3F,B0,6B,F7,20,41,E2,2C,BF,87,65,1E,2D,8E,97,23,16,9B,86,BB,52,C4,68,8D,F0,B6,E7,D0,57,EC,7C,47,88,C5,EC,F3,CE,AF,95,4C,DF,29,E8,54,60,71,8B,0B,97,F1,76,63,5C,D2,2B,3A,4A,BC,18,C8,C9,82,DF,44,E6,51,E2,A9,AA,26,EF,1B,D7,97,6C,32,5B,DC,A9,C4,B4,09,98,4F,BB,45,01,AE,E1,9E,FA,0A,02,0B,48,BF,34,09,D8,5E,A7,AA,C8,A9,E4,FB,E4,12,DB,3D,12,49,3B,23,25,7F,68,85,E0,27,8E,FA,80,17,1C,A4,16,98,72,BC,08,85,1F,2E,CA,A6,9E,61,38,5D,9C,3D,F4,26,AD,FD,DC,94,75,7E,DD,26,88,E1,74,04,F3,92,5E,A9,13,58,CC,FC,18,B5,6D,51,F2,7D,C6,2C,90,5A,8F,A1,B9,DB,8A,DE,84,A1,3A,92,4E,B4,1F,3F,54,8E,6B,F7,96,86,A5,C5,1B,16,BF,56,70,CB,7C,A6,D5,FD,E7,95,27,AE,B6,0F,08,3F,A9,0A,54,A4,04,45,AD,F2,45,22,02,99,1F,BD,04,DE,64,19,74,1C,68,67,2F,AB,CF,C6,33,8C,90,B4,4D,AB,22,6F,A9,0C,08,83,CF,68,15,24,FD,1F,85,6B,89,21,BF,7A,CB,E5,51,69,CB,1B,34,B0,2E,54,E3,F3,4C,E3,8B,5D,1D,FF,74,1F,F8,7C,C0,69,69,37,26,12,95,62,7E,B0,62,05,0E,57,3D,BD,CA,2A,14,A2,08,77,78,51,3B,23,90,D6,96,28,DB,58,D9,08,15,F7,3C,74,26,B0,4C,BF,70,B9,70,40,F6,D2,B3,3C,D2,51,67,ED,41,77,35,49,83,4E,48,A5,E1,A3,A2,31,51,55,82,60,A2,57,6C,E2,BF,DC,18,92,D0,98,6D,D4,43,80,E3,20,92,3C,6B,82,0B,B4,0C,73,A4,2E,1D,53,A4,4D,E8,C6,2B,4D,F1,22,A1,FC,52,30,9E,20,55,33,08,2B,71,B7,9B,59,CD,F0,31,DC,53,94,DF,AD,F4,68,0B,67,11,FB,7C,67,75,63,BA,BA,29,39,59,58,2B,CC,55,71,85,E6,4B,AE,D9,39,F4,6A,18,4A,77,E3,57,F2,87,03,3A,60,37,51,C5,48,AF,C0,8A,47,04,8F,20,7E,83,CB,2F,19,B0,2E,44,79,52,AF,33,14,4E,9B,CB,A8,E7,EF,F4,87,3E,73,B0,65,49,42,2E,51,80,25,B6,69,5E,8C,64,69,3C,84,11,8E,A4,84,10,2C,D5,D3,B4,D4,E0,58,2D,87,50,49,83,C7,50,51,B2,07,D5,BB,01,62,0C,7A,26,47,FB,44,3D,15,8B,CD,66,40,65,CD,DF,B7,89,06,CB,97,84,00,9B,BA,D9,52,27,FC,46,94,52,AA,A3,26,CA,0E,A0,13,5E,AA,9E,2A,56,F2,53,D2,B9,22,85,16,C4,40,D9,37,45,5B,E7,D9,79,EB,53,A4,AC,B0,CD,0E,36,1C,AC,43,F8,7D,58,31,C6,DA,FC,39,0C,6B,EA,74,EF,12,4F,31,9D,C2,E3,66,33,DC,59,36,AC,D9,BB,F5,C9,6D,F2,55,39,03,B0,C2,07,05,7E,B7,71,39,7F,38,C3,EA,B7,55,F6,E7,89,55,82,3E,15,23,0D,C7,D3,70,54,09,A2,EF,52,30,B7,F8,3E,24,49,97,0B,13,50,72,7F,DA,0A,2E,FC,04,44,7D,E8,4C,EE,13,E8,18,2E,A8,9C,07,2C,AD,F7,D7,91,C5,4B,41,44,9B,80,30,58,AC,89,9F,B0,91,1B,E3,E0,BD,58,ED,30,F3,A2,FB,C9,E1,7F,DB,76,43,34,57,4E,21,AB,4F,02,10,28,91,88,B3,25,1B,C8,D1,BC,FE,95,EF,7A,DE,12,DE,38,D1,8B,AA,6D,8E,53,11,8A,F1,E2,0B,28,E7,A3,4C,FB,FB,22,AE,43,85,F9,36,C5,23,05,2E,6E,69,37,52,AF,2B,BA,5C,BD,A2,EF,10,05,D7,55,64,26,E3,08,9A,73,DE,0E,64,24,DE,32,15,86,A4,60,4F,9B,66,36,1A,AF,4A,1A,9E,B0,83,2D,EF,EC,F8,64,45,9D,93,A7,BD,AC,B7,D9,01,28,29,82,4F,99,DF,48,C2,6A,DA,71,E0,95,78,43,50,C5,33,C3,12,91,B7,B9,F8,08,53,80,F9,87,8D,5F,C0,5D,8B,3C,40,F3,B0,8A,CA,19,FB,9D,7B,6F,F9,00,04,1A,5A,6F,51,32,B2,DC,FB,35,D0,54,01,75,50,65,95,88,78,9E,F5,42,BD,B5,AC,19,D5,13,D0,6A,92,F0,ED,71,8B,65,36,C2,7A,46,4E,0D,B2,2D,79,47,D9,04,4B,49,A1,5D,88,B4,51,6D,45,33,7D,CE,A9,5B,3F,0A,44,D5,FC,D0,2B,D5,CF,BF,35,C1,24,CF,B4,F9,47,13,6E,A5,26,71,7D,CF,A6,33,B6,E6,A7,17,7C,60,2B,F1,D7,49,FA,D7,D9,80,7E,44,F3,5D,6E,0C,62,4F,3F,DD,92,EA,EB,DA,C8,9B,57,C0,9E,C4,6E,82,E0,71,78,31,02,BF,13,02,83,D0,0C,3C,23,2B,A0,56,1F,69,E6,15,3F,4B,66,5D,5F,07,B4,84,35,F1,89,F2,CC,13,BB,36,A6,19,B1,68,6B,47,AB,69,CC,33,4A,A1,09,ED,BC,77,B6,1D,DF,E2,C6,DA,0A,19,5D,7F,1B,FF,DA,5C,54,81,B2,A6,99,10,81,73,1A,E3,17,8B,BB,DC,71,4D,21,6E,20,56,0B,66,FB,D0,F3,0A,B8,3F,E0,6F,A9,A4,1E,43,D7,46,9A,42,2C,08,91,DB,AA,0E,AF,05,05,DA,AF,5D,2D,48,18,6D,D0,E2,14,AE,55,EC,FA,E1,87,DD,56,4B,79,E7,A1,C1,10,10,78,1B,97,7B,FE,59,63,D8,5C,13,4B,84,3C,26,DF,E3,44,AE,39,40,CB,37,BC,B1,70,0E,43,96,CE,9A,24,3C,9E,25,76,55,8D,7E,0E,FA,4E,13,39,FC,D2,C4,AB,8C,4C,AB,0F,8E,53,4E,A9,D3,FE,2A,6A,60,41,98,C2,0E,44,6A,0A,B5,31,BF,20,B6,46,91,92,7C,07,26,5D,C9,3A,76,64,2C,0F,DE,52,2E,78,A7,F5,DA,A8,9E,2B,E3,61,EC,C7,68,17,89,E2,5E,0D,01,09,12,B1,AB,E3,73,23,FA,CB,FD,EE,C5,61,12,BF,D1,68,6D,7C,89,F7,A7,8D,0F,D8,2C,74,73,3D,F6,A5,02,4F,45,FE,DF,DA,AD,82,A8,CF,81,C8,7D,11,18,CB,0C,D0,E0,58,BF,AE,64,53,40,1D,0F,FC,2D,5C,6B,C0,74,00,CC,9A,43,E5,06,F0,A9,87,60,B5,40,4D,53,57,F5,34,87,2B,B5,30,BD,71,96,8B,8B,73,57,8B,39,CA,60,4C,9A,2D,C9,71,71,0B,30,FB,FA,F0,D6,E9,E0,E3,9D,D2,E6,EF,C2,DF,9C,27,3C,A6,80,22,DF,FB,FD,84,69,C4,B2,C8,06,54,5F,4A,04,D9,E4,DE,CE,68,C7,C1,01,E3,F9,2A,C6,1C,7D,D6,78,E3,49,8B,8F,BD,4B,D6,62,2C,4C,F6,73,67,4A,BB,C2,AA,AF,B8,6A,6B,12,26,56,2E,A8,EF,03,42,7D,B8,A1,AD,40,07,7F,81,37,5C,6D,A8,CC,71,2A,70,9B,33,F1,AE,A1,6D,48,39,F1,C5,22,1D,8A,6C,36,50,83,C8,3F,A2,3A,64,55,CD,67,4B,16,3A,C4,BE,57,A1,2C,F7,B7,10,FC,D0,9F,8A,A8,CD,68,01,74,FF,95,92,99,2D,B1,AA,C0,76,21,D8,FF,10,9C,6D,FE,42,D2,55,7D,C9,21,F1,F3,08,22,C5,FB,CB,F1,29,56,8E,74,5D,61,F3,BA,72,D1,50,63,6E,16,D3,FA,2A,75,11,9D,FB,BD,9F,48,FB,66,36,72,AA,4B,45,FA,CB,BA,85,B8,B0,2A,C5,1F,F3,86,E2,B1,D8,CD,19,D7,9C,CB,12,37,F8,DD,12,1A,26,81,5E,56,7D,9D,15,9F,89,8D,68,DD,8F,80,81,EA,27,16,0B,D7,1A,CA,8A,AA,4C,6B,2B,3D,71,3B,B8,A5,BD,94,96,67,57,CF,94,51,85,8C,F9,DB,1B,61,B8,45,F2,83,80,7D,E2,E6,69,23,54,4A,0F,20,52,1B,92,AD,1A,9E,F8,7D,0E,CD,03,A5,F3,5A,EB,EA,08,D0,50,52,7A,6E,8E,ED,21,2F,C8,97,20,EC,97,DC,6D,A0,96,F8,4B,9D,A5,4A,C2,67,D7,09,F3,BD,C5,7A,2F,5C,03,9B,A1,7C,A8,55,8B,3A,43,56,CD,4B,19,4A,32,5B,AD,5C,AD,0B,0A,E0,AA,78,B6,B4,6F,9E,97,F5,AD,66,C6,A4,E4,A7,CE,1F,0C,9D,1A,C4,45,97,8B,A5,87,E8,DE,01,32,8F,ED,D8,66,E6,20,FA,62,1F,E2,88,89,2B,C5,7C,AB,E9,62,FF,DE,94,CB,F3,F7,E9,91,7B,AA,9C,95,38,A6,2A,2A,D7,3F,03,97,98,48,F6,1E,21,AF,11,55,0C,77,C8,B1,95,AE,C7,52,3C,5C,5B,F9,FF,6C,5A,43,9D,C4,97,3E,3B,D6,30,8A,1E,E6,0A,98,7C,61,DE,95,76,E7,72,C9,9A,46,96,99,80,8E,DC,AD,2F,5A,82,B3,B3,52,A4,EC,40,AA,F7,FC,B7,08,73,29,0A,C2,D8,BB,74,B3,75,6A,2C,F4,F8,6E,27,F0,7D,A3,B3,BA,1A,43,0C,13,75,C6,A5,EF,D0,0B,8F,AB,52,93,0B,90,75,EE,1D,B4,2D,23,F2,9C,2B,CC,0A,D5,79,78,65,01,3D,EA,DD,D7,94,C4,A4,32,8C,E4,B7,91,B0,4E,F7,53,28,56,6D,59,E5,6A,A9,1C,06,D3,49,80,2C,9F,FF,91,2A,34,B4,35,08,39,F3,69,CB,F1,BA,A8,93,9F,15,BD,C5,A5,C1,DC,2B,05,DB,8C,EA,36,C8,FE,32,4D,1F,91,B4,E3,3D,1B,80,C9,EB,B0,9F,23,51,97,39,7B,38,F9,0D,2C,74,C1,9B,DB,95,9A,1E,24,19,33,3F,D9,EE,9E,97,3C,52,5F,83,75,69,17,41,86,CD,4D,3B,0C,EE,C2,F8,EC,DE,AC,EA,16,EC,E7,24,7F,B9,E2,9F,C2,3E,B3,21,C7,FD,EA,8A,A8,7F,27,BD,9B,59,AA,71,56,63,D8,FC,01,51,F4,06,99,05,AA,34,8C,AE,48,60,56,92,6F,81,75,AC,90,DE,11,92,26,0C,32,45,7F,18,8C,A7,0F,3D,54,3F,80,64,70,4D,0C,26,6A,01,A1,FE,93,7B,AB,96,F3,AB,33,CF,13,60,6A,06,B9,FD,99,DE,45,86,1B,48,4B,F1,28,3F,A1,5B,A6,7A,9D,E5,D9,F7,28,CC,2C,D1,01,03,B3,F7,7D,2B,F9,E6,F8,32,89,2D,A0,B5,A4,73,33,50,E4,AC,12,D9,34,80,7A,14,0B,15,66,6B,57,4C,0F,3C,6D,FD,A2,30,85,C9,A5,48,C7,6E,43,88,85,BC,E2,0C,BA,43,F1,F9,12,DE,21,77,30,8B,24,79,30,80,F1,CE,2E,F9,7D,F5,12,78,1C,CF,55,4D,00,4F,54,9B,A8,63,97,00,B6,56,84,4C,8C,27,7D,D5,CC,FE,39,00,05,30,CC,BC,DC,FF,8A,24,10,26,6B,EC,27,30,F9,D4,0C,4B,9A,8E,8E,F5,F5,74,02,3E,0C,A9,08,D4,3A,69,FA,94,55,B4,A3,AB,42,27,B0,BF,19,F3,84,22,59,85,3D,35,EC,7E,2B,EB,05,02,9B,CE,62,5E,DD,95,F6,DF,AD,9B,E5,DB,F3,33,2E,42,D8,3B,C4,39,3F,CC,A4,0C,95,EF,31,4C,58,BE,65,DF,68,E0,4E,DE,D9,9C,04,43,FE,CE,DC,00,0D,9E,EB,EC,1D,A3,73,AA,7E,E7,D1,EC,94,8B,99,CA,35,4F,7A,B8,75,1C,86,2A,B3,36,0A,D0,1C,9E,F4,CF,33,B4,A8,D9,58,91,E3,5C,71,C6,F2,0D,A0,7C,93,3E,36,09,9E,24,54,B9,40,04,54,3A,66,3E,3B,4B,49,9F,DB,9A,35,94,EF,31,E5,BD,3A,DF,31,92,8F,CD,F9,A6,B6,30,90,7D,C0,1A,00,71,0C,D3,9D,B3,55,60,14,C2,4E,ED,A2,47,5B,47,2C,AB,35,F7,B3,DE,42,DA,B5,DB,B4,A4,62,0D,72,EF,3A,08,0E,F5,C2,85,93,83,6B,A1,7B,84,D7,E9,FE,4C,CE,A4,E8,F2,E3,FB,41,B9,3F,21,D8,6D,9C,DB,3B,51,FF,B0,0B,B8,67,37,1D,AC,59,7F,D1,37,42,AE,48,EA,BE,33,7F,4B,50,06,88,AF,53,25,C9,41,EF,D9,07,A6,03,F1,5F,72,7B,3A,5F,F1,0C,73,AB,4E,71,6C,DE,0E,A7,93,6B,C0,86,C5,33,CA,5A,60,D6,40,2E,6B,7B,90,14,89,22,14,4E,2B,CA,99,57,B1,E6,D4,67,79,8A,32,16,7C,9A,EA,B9,46,2B,2C,04,E5,E2,67,41,02,76,E2,37,7F,18,8D,E4,50,2B,EB,EF,C8,10,30,1D,B6,F6,C9,5A,ED,60,18,D2,2C,5F,C8,B0,58,7E,6E,B7,DA,B4,39,9C,B6,29,88,0A,FF,73,48,6A,7E,82,B5,40,C1,61,79,C8,D5,49,B4,27,03,4C,F3,2F,59,D9,53,11,3F,AA,0F,EA,08,91,AC,72,DA,33,FE,BC,EF,E3,71,CC,4A,D1,70,BF,FF,8B,C8,80,68,01,21,02,8D,51,B9,42,04,E3,D0,2B,DC,6C,2A,8D,6A,0E,E7,48,A0,70,63,3D,0E,7F,92,52,F8,F8,D6,F1,DE,4A,FC,62,B8,85,78,7D,6F,C7,D8,01,DD,88,F3,95,2F,58,2B,F9,73,D6,E6,D2,22,5C,25,80,97,A5,13,65,4B,F8,68,3F,B7,01,F5,F2,21,55,98,8E,A8,B4,33,22,B5,64,76,CA,58,E8,6B,0C,5F,50,5D,8B,F9,D9,00,49,54,F1,DF,EC,54,B9,A7,86,F3,F0,FD,49,B5,8F,59,5E,D2,86,C2,74,E2,74,E6,D6,2B,E5,AC,39,60,E1,F7,7C,A6,89,E1,AE,61,9C,E0,7A,8E,BA,40,3E,AD,C2,53,AF,20,41,9F,C4,0E,2C,E5,53,14,72,04,77,21,85,07,A1,60,2C,CF,20,E5,E2,F4,3A,F4,43,88,F2,79,6B,16,90,CD,78,34,27,95,30,42,81,52,A8,03,D5,38,BA,EF,CC,F8,13,46,E5,CD,79,0C,C0,8D,1F,67,2B,B4,13,8A,AE,E3,95,35,64,C2,52,54,56,03,8D,3C,CE,DE,30,CD,7D,08,5F,92,28,26,60,E2,33,95,51,71,D0,02,06,97,B8,59,94,EE,00,C7,9C,36,D3,6B,BD,77,B5,3D,31,68,B7,F2,87,F8,61,98,BD,CF,E5,EA,8A,F8,8D,0C,43,E7,7D,E7,CE,21,34,04,A0,C9,3F,56,9E,65,D2,F7,6C,5A,D3,69,AD,97,41,87,82,B3,E0,A8,9B,4E,CC,5E,18,90,7D,EC,E6,C3,14,6C,A3,BD,35,8C,B6,73,CE,E6,5F,42,75,EB,E8,AA,56,E5,1B,BD,C3,F9,12,DF,55,0E,C6,54,3B,60,87,0C,E0,04,13,9F,04,65,27,F7,B0,C4,32,23,31,C3,D7,20,74,47,21,84,97,AA,CC,A7,13,09,A4,FD,5F,3E,DA,68,05,FB,D0,CF,DA,8D,E4,B8,15,4F,95,31,B6,5F,8A,CC,3C,8A,55,02,B0,D7,56,75,F6,E1,DD,39,DE,10,AD,08,D9,9B,27,8D,CF,8F,71,36,DC,F1,54,10,A1,18,52,DD,CB,D4,70,F4,4C,A6,18,D7,FF,AA,53,EB,CC,00,86,B8,E1,A1,88,DA,95,92,22,42,B2,C6,95,46,63,B0,2B,60,7D,25,E0,A9,04,89,F5,6D,E8,D3,70,F0,27,3B,7F,B0,F7,F9,16,5F,05,7F,2C,77,45,75,4D,88,2A,82,9D,C4,1A,98,B2,26,20,51,17,B3,2A,DE,B2,2B,F9,56,2A,25,76,51,CC,3F,48,22,FA,26,2C,60,64,16,56,88,59,2D,D0,C7,C7,2D,CC,6A,7C,86,97,52,5F,AC,E7,8B,45,85,72,EB,12,3F,85,C1,9F,57,30,32,8B,E5,82,EB,9A,E4,08,73,9D,F2,0F,BF,F3,E0,A4,90,A1,4A,22,4F,B0,40,13,5A,D8,40,7A,8C,82,D3,67,F0,5D,D2,2D,04,F2,4A,9C,27,CE,E4,F3,3D,46,2C,D7,1A,E0,2E,41,9F,AD,88,A9,4C,BB,BA,8E,6A,1C,76,2C,53,1B,FA,51,AB,76,DA,89,FF,70,F7,42,46,0F,4B,EE,47,98,B5,A2,79,60,55,47,A6,33,23,3E,2B,92,07,19,33,2D,79,BD,56,35,D6,B2,4F,6B,B9,46,B9,55,4B,E8,87,CB,6A,B5,E6,19,ED,9C,43,29,79,7E,90,BC,7F,1E,98,DB,5F,8C,1E,29,3F,DF,5A,12,A1,C6,72,69,93,F5,52,F7,19,9B,14,DD,DC,A4,D8,40,13,23,FB,6B,40,F4,04,53,B2,8A,FF,2C,8C,F1,3F,C6,21,A5,3F,AD,9E,73,36,AB,45,67,0A,EB,F5,61,E1,EF,EB,AA,0C,C6,C1,38,F7,17,96,B0,21,48,EF,BA,35,05,12,48,5B,03,C0,08,93,97,E5,D3,A8,1B,24,8C,39,45,46,8F,6C,46,68,90,FE,57,70,7E,21,ED,33,4A,D5,FE,A5,8F,E3,79,32,33,36,66,DD,33,68,3D,11,D1,61,70,F7,B3,D6,36,E2,94,78,92,C5,6E,FD,F8,E5,B9,7E,CA,4B,0B,E0,D9,BA,8D,E2,9B,4F,6B,25,9A,DA,A6,81,C0,E0,19,1A,5F,83,52,5A,96,87,BB,C8,D6,4B,48,60,9B,41,2D,B2,50,62,AF,05,47,3D,0D,6C,AC,E2,8C,D0,44,A5,0E,F9,7D,80,32,36,60,24,A9,70,A0,68,BB,15,08,1F,81,76,AC,EC,0F,4A,B8,0E,B6,46,B7,BD,BD,54,FA,53,14,E0,10,87,09,27,B2,1D,A4,07,92,7A,4A,92,4D,26,63,EB,1E,78,23,F8,5A,F5,1E,99,A3,5A,FC,76,80,DD,EE,B7,38,F8,3E,C6,C3,6D,1E,D8,90,3B,50,B4,A2,41,36,AA,13,72,57,D1,E0,C1,63,50,A6,EF,5D,CF,54,BE,80,EA,1E,D0,FA,5F,F8,65,0D,77,56,FB,91,4A,DE,08,C0,ED,DC,D3,4C,ED,5D,AA,C3,C8,15,51,83,79,94,1F,7D,76,53,94,5C,3E,7F,72,5C,00,2B,68,E0,CC,7B,09,6B,12,A4,D0,49,A4,D2,EB,4A,3A,F4,0E,3B,4A,09,F8,FE,EE,5F,19,71,6A,E3,5B,73,DD,7E,97,6B,94,4A,D2,87,D7,00,0C,08,37,AE,9C,FA,12,30,07,2B,1E,EA,92,B7,A3,D6,C4,F2,99,78,38,34,1B,7E,6F,C1,E7,43,B7,A9,E8,7E,BA,79,B7,2B,0A,06,C0,BB,F1,DC,EF,79,20,79,20,9F,47,4D,E6,74,01,58,53,9B,A2,C8,29,B4,DE,F8,92,A9,93,E3,B9,AE,54,D9,83,4A,A7,DF,9E,0A,C0,58,38,48,25,5C,8E,B6,6A,73,C3,C9,2F,EA,97,62,2C,B3,27,53,F0,54,9E,F8,2E,2A,96,75,8B,5A,70,BD,3D,BD,73,F1,6D,47,46,99,6C,70,C3,50,8C,A4,BE,95,38,54,AE,01,05,24,1E,2D,A3,24,98,79,C2,FD,4B,BA,6F,5E,B9,56,F8,45,DA,2E,C2,96,8A,C4,86,FD,5B,E8,B2,DF,A9,BB,93,87,33,65,3A,DB,15,EE,20,6A,3A,78,2A,E7,1A,AA,5D,F0,2B,B3,1E,A2,B4,31,F7,C4,77,C7,09,A8,79,3B,A6,FD,42,14,FB,21,EC,FB,C5,6E,F1,A1,B5,0B,22,25,14,B4,4F,7D,69,92,BE,6F,08,A2,84,15,5C,0E,6C,33,96,26,27,0A,EB,34,B9,6D,42,A5,BC,8C,DD,01,7D,18,9B,C3,9B,6F,D5,D7,7F,5D,8C,2D,E4,B5,D4,6D,65,C6,E6,83,BD,08,1E,90,1F,25,45,BB,09,04,60,70,C6,B2,D2,11,D2,58,F9,48,ED,7F,A2,24,95,CE,71,E1,AD,7D,28,58,98,88,EF,DD,DE,9E,CC,EA,8E,47,E7,44,83,FC,50,DB,BD,6D,82,39,5C,B9,5E,FA,70,FB,A3,68,2A,6D,56,B6,90,A2,25,09,7C,84,6B,0D,A0,62,01,72,74,F6,FB,20,12,71,38,9C,7C,EB,6D,B0,E2,70,50,34,E9,A1,2C,55,25,25,85,0E,C4,3C,A5,30,48,62,82,A8,3E,D7,B0,89,5F,E0,C3,1D,85,8E,CB,7A,5A,E4,7C,44,71,FE,5B,DB,9B,3C,8A,88,7C,1E,46,F2,B2,D3,5B,E3,3A,DB,9E,3D,EA,04,5C,A9,53,5F,F0,61,3D,78,D6,31,0F,A5,98,61,26,50,54,42,67,47,EA,BA,BA,95,F3,B3,BF,87,30,63,86,64,9A,48,48,B7,54,02,A7,38,3D,81,DB,45,3D,6D,87,84,CD,0D,34,2A,37,20,E4,0C,50,9E,F0,80,38,5D,9D,A0,F9,81,FD,C3,F7,08,6B,31,E1,FD,1A,64,E8,17,CB,08,CC,3C,25,BE,04,33,0E,6B,FC,47,8E,1F,BD,5D,31,90,70,97,23,CD,DE,9D,D5,D7,C0,EB,2C,F3,9E,82,2A,F4,A9,12,3B,9D,67,81,BA,81,8B,30,BE,E0,4E,1D,09,03,84,2E,CD,0D,39,4F,44,CA,38,7F,67,2E,A0,7D,18,9F,EE,5F,A3,04,D3,B2,E2,9A,5D,47,ED,CC,F7,95,F0,1E,B5,21,0D,31,3E,2A,55,23,1E,A5,08,13,35,B3,01,CD,60,2D,1A,CC,10,D8,9B,6B,3E,4E,CA,D3,12,D0,A1,04,21,8D,A3,9C,A0,12,1E,92,43,C0,3E,E4,FF,7E,EB,E6,59,90,E7,97,58,0C,63,3C,EF,72,E4,D2,D3,F4,48,0E,6F,7F,72,DE,AA,91,E7,C2,46,FE,9C,7A,B0,8A,2D,E1,7F,C2,CB,20,9A,E1,6F,44,B4,46,A8,EB,70,3E,C5,DA,A2,92,10,5A,D4,C5,AB,B4,C6,F2,26,72,BD,2C,49,4A,71,FE,46,D1,18,CF,CA,D1,1A,F3,39,C4,27,16,FB,44,D7,F8,EF,1C,5D,E1,E4,95,1C,C3,1C,31,77,93,A7,FC,CB,6E,76,77,83,A9,02,21,E1,92,94,5D,5C,87,A4,B9,89,E8,7B,52,F3,75,C3,61,1D,58,B1,D5,3D,37,9E,3A,BA,47,3D,99,8B,ED,26,FF,A1,FF,8E,56,BE,A2,4F,A2,E6,6D,1E,2D,B1,AA,B6,35,78,BB,38,D1,8A,23,C5,8F,8F,57,D1,77,4F,C8,70,39,03,67,85,C5,CA,DD,D7,58,31,CC,77,6A,F9,41,4F,7B,52,57,E5,35,AB,DB,BC,D3,A6,CD,8B,2B,10,8C,43,94,A7,5A,95,67,7A,6C,70,95,94,4F,1D,BE,EB,29,18,F4,42,B3,97,89,59,F6,0B,5B,B8,D7,88,1F,05,30,54,DD,CE,10,45,8F,93,8B,74,E2,80,C5,29,18,F2,7E,5D,6C,DE,AD,3E,BC,27,99,DD,59,30,C8,ED,57,1D,18,4F,03,DD,63,EF,99,93,55,87,21,C3,3B,34,F4,6B,31,1E,CB,68,50,66,AF,DB,94,E5,14,E4,A6,1C,31,DA,74,2E,E0,AD,39,68,1E,A5,CF,DD,82,FB,61,B3,09,7F,0E,28,FB,0A,5A,1F,DA,65,F8,19,A4,18,31,5F,D3,98,85,72,CD,CC,40,8B,76,FA,63,8A,0C,63,15,B1,CE,DC,DB,6C,7C,15,FC,00,AF,4D,63,CE,D3,67,48,AB,7A,A8,45,EC,82,3D,AD,6E,60,78,47,D2,BF,84,6E,95,FD,D0,12,F8,16,19,BE,7D,02,D9,BF,F1,1F,7F,30,4A,51,5C,F4,41,3E,98,C6,65,6D,39,8E,9A,1C,56,B4,EE,ED,60,E2,2F,E3,F7,83,EF,87,FA,86,2C,DE,8F,7E,D8,07,18,62,75,F4,E7,73,C2,C4,E6,07,10,05,81,31,62,56,74,A4,F4,BE,3D,34,5A,4F,E8,EC,46,89,A2,89,E7,D0,69,E5,60,7B,2A,7E,DD,F7,D8,A1,53,1C,A0,FE,6B,39,65,15,1E,00,FD,57,66,E5,32,D2,A3,23,3B,FB,30,CA,09,5E,1F,0B,5A,30,07,E3,56,D2,5D,FE,A6,5D,29,F0,A7,7B,10,19,20,CD,1C,BD,B1,8C,D7,E2,F7,FD,6C,EE,66,74,26,E9,C5,DE,C0,E3,75,C0,01,02,AD,0D,D0,98,DE,00,C8,3B,DC,22,0F,D7,22,BB,AC,6A,3A,13,0C,10,7B,31,81,5F,0E,E9,08,EE,39,B8,B0,9F,AE,D7,03,73,2D,AA,DA,27,DB,FB,8E,8A,75,FC,E3,D4,F9,71,03,7D,A3,16,54,AC,47,53,BE,68,8F,07,81,EA,5C,82,67,45,26,2F,68,38,48,25,C7,D6,40,99,E2,AA,94,55,3A,6A,B4,D1,60,A2,8E,BA,A5,07,D4,EF,D2,B8,EF,63,DC,C9,05,30,2E,1E,B7,D6,0B,97,E0,9B,CC,84,2C,02,C8,5A,D2,2D,E9,63,91,31,47,29,8A,5B,D4,FD,A2,FB,6C,44,F2,95,20,73,23,45,36,15,1D,73,68,1E,14,EB,A1,ED,81,DF,B6,56,BB,62,67,B4,E0,4A,7C,8F,B4,97,44,94,56,B7,94,CA,DB,9D,B2,16,F3,96,45,C9,11,89,4E,A4,FF,1A,9E,36,FC,17,16,90,BE,41,BA,48,FD,28,B6,BD,43,2C,FD,BD,1C,D7,3A,A3,F2,9F,72,F8,59,D7,A4,0D,85,42,29,54,EF,04,91,37,60,69,CB,77,57,33,38,19,B7,18,D3,7B,7B,0C,64,D2,1F,BA,C0,43,01,24,14,9A,EE,9F,5C,D2,F5,1B,A6,B9,D4,EB,96,C6,BE,A6,15,10,75,E9,71,A3,DA,F3,E7,22,C1,41,8F,54,38,D4,12,10,78,49,3A,FF,39,A0,C0,B1,57,6A,36,62,08,95,8B,5D,EF,C1,15,DF,83,67,C0,4F,EB,7C,68,06,91,26,59,F1,D9,A7,5C,9E,6A,2A,F6,A1,D6,16,53,BF,18,60,66,06,AB,C2,A8,49,DE,4E,99,87,53,0F,D2,3F,06,68,85,FD,7A,1E,46,49,4F,EA,52,5E,4C,5C,10,C5,B7,A0,0C,B9,F1,47,6E,8F,EE,34,2F,F6,06,FD,3F,AA,74,DE,BC,C0,76,03,56,9F,2F,9A,ED,E1,BF,EC,DB,AD,AE,C0,37,C0,70,A0,E1,ED,7B,6F,1F,FE,DC,DE,28,23,9D,12,E6,1B,A2,86,38,4A,0C,89,0F,60,72,6C,A9,6F,1A,51,72,4E,ED,C6,0F,ED,AA,CA,4C,1D,2E,03,6C,A0,1D,FE,F5,F6,30,5B,DC,25,2D,3F,AA,67,29,F7,36,FC,D2,04,D9,8A,FC,27,3F,36,9F,06,AD,E4,BA,76,A0,5E,F2,45,B9,9B,24,D6,F9,34,6E,27,C1,D3,C2,9A,BA,84,DD,8F,4E,C4,A1,D1,A4,B1,B6,56,6E,93,A6,20,59,4E,87,4B,27,C5,FD,B4,91,FB,6E,A5,FC,E4,83,CD,EF,CE,A6,D9,B2,B4,2C,EC,8E,69,91,DD,D3,76,D9,FC,EA,B4,40,DA,9D,5C,12,D8,0A,F5,7F,26,2E,A9,EF,C3,2F,3E,06,13,C6,54,28,16,27,98,04,74,2B,F2,3B,E4,03,C1,80,A8,2A,D1,8C,00,0B,A3,BF,2A,88,A7,66,0F,A1,BD,F1,13,6B,B3,C8,B9,C5,6E,C8,2F,D4,8A,EF,96,B5,06,3D,A6,A9,EB,E6,0E,77,D3,31,A1,FD,B4,17,0A,10,F1,B4,75,ED,64,70,16,29,BE,0E,52,8F,0E,FD,09,1A,8F,65,9F,8E,D2,D8,2D,6C,5E,0C,C0,75,D3,89,87,1B,A0,69,2F,9B,A8,3E,16,69,C9,7D,98,45,86,88,B5,D6,AE,D0,58,4C,57,9F,D0,13,79,45,AC,C1,28,4F,8D,ED,CF,0C,30,76,75,B4,8B,63,33,89,B5,14,B8,BC,55,B9,91,7A,7C,42,76,A7,67,3F,80,5C,BF,D2,3E,E9,4F,1D,39,2C,D8,8B,89,6D,96,22,54,D4,70,87,05,8A,F9,3F,46,89,B3,91,57,F3,6D,85,8A,95,F7,17,32,97,06,01,F5,56,7C,7D,38,0A,4B,8F,B5,C3,12,AC,F6,21,D5,42,2A,1A,AA,01,A0,3C,8A,FC,C3,23,BC,84,58,01,EC,7F,3F,AD,1E,50,F6,2F,51,65,0A,7D,C0,E4,63,1A,15,03,2E,8E,42,D1,5E,FA,DC,D2,BC,86,FF,B7,52,9B,63,45,64,9B,01,F7,7B,A4,10,5E,83,02,81,76,26,FF,19,04,2E,DD,06,8B,D7,1A,CB,E4,C6,C7,74,BD,D6,1C,C2,97,FA,73,6C,77,F6,9B,04,17,76,3E,7A,3D,EC,73,88,61,24,9D,17,46,D7,52,14,9E,82,2E,FB,EE,55,94,BC,6D,37,65,FB,E0,EA,E0,BE,D4,CC,C5,BC,4A,07,4A,BB,9A,11,1D,33,6A,77,64,BB,C7,AD,EE,10,E2,C3,A6,3C,0A,1C,79,44,19,83,64,31,B3,0D,4F,2C,63,55,7B,DC,89,CA,59,18,E6,63,9F,CD,5D,F4,11,71,87,A7,3E,B5,13,AA,88,3B,27,FC,EF,C3,0B,4B,03,0D,D1,4D,5D,47,F0,E1,C1,DE,F2,14,DD,6D,2C,38,F3,35,34,89,DA,30,08,EF,9D,65,82,47,06,1C,18,7C,E6,AF,DC,C6,29,87,B2,16,B7,43,DF,32,F4,B4,C7,D5,A7,4F,99,A3,2A,54,FA,70,15,9A,43,34,66,EA,5A,CA,88,D2,5F,5F,12,38,35,94,00,D0,F3,C9,EE,7A,C9,A0,E4,C7,92,52,70,05,EE,3C,92,D8,ED,44,BB,BF,F5,AA,31,93,C4,5C,DB,75,AF,0E,D8,E8,A8,DA,8A,8A,03,8D,7A,1D,B3,AB,B9,40,EE,E9,CB,7A,36,4E,22,B4,81,07,E4,1F,19,5E,ED,1C,B5,FC,68,35,E8,AD,85,CD,39,47,F3,B1,88,E3,99,E0,F8,AF,30,0C,27,52,2C,FB,7B,44,44,82,C8,0F,F5,08,E0,18,6F,FD,C8,97,E9,55,3F,97,7B,96,DE,C0,98,16,D4,CF,49,0B,2B,FA,77,94,E1,27,4A,0B,14,C2,FF,AF,E1,42,0F,B3,BF,B1,CC,FD,B5,96,F1,FC,99,A1,E8,C0,B6,C6,C4,CB,53,9F,98,77,02,BF,77,9C,69,53,75,68,C1,A1,AA,27,09,15,ED,6A,9A,3A,AC,B5,2C,70,31,86,F3,19,D5,66,3A,0F,FF,56,4D,C9,7B,16,D3,A1,D1,40,DE,80,03,10,A3,65,75,7A,38,CC,7C,BA,D1,CC,68,0D,C5,6D,F2,9E,E0,C5,25,28,B9,D9,B2,38,99,BE,28,B3,49,02,96,9D,31,FB,8D,4C,43,D0,B3,9F,19,BA,8F,B7,A9,09,86,B5,2D,2B,31,B8,63,FC,2D,F2,28,8E,D7,C9,7E,EA,5A,68,19,FA,9A,4E,34,F6,53,68,62,0D,B6,35,28,E4,4E,6F,96,86,12,1E,E3,DF,47,24,17,03,53,4B,89,AD,F1,EA,8E,BF,66,46,C6,98,29,88,12,B6,98,33,19,54,6D,3F,3D,A3,91,9C,FD,44,E7,4A,61,80,90,82,60,8B,58,8F,9E,21,EA,A7,C7,CF,CB,54,D4,12,29,7B,91,FC,20,DA,F4,DA,B3,FE,1C,45,DE,DE,D6,AD,1C,DA,28,B0,A4,3D,A1,7C,CD,A9,9D,E0,52,86,8F,A1,6B,0F,E2,F5,65,51,DB,4B,EB,AF,A2,A4,56,BF,FF,58,89,EC,B8,8F,65,97,24,4F,04,0D,00,86,19,84,20,95,5B,F7,98,A3,42,40,CE,2A,F9,8E,E7,9E,20,30,DA,A9,D4,38,1E,CF,AD,20,21,AC,C7,B1,68,22,87,B5,20,6C,82,41,88,32,C8,4B,70,14,AA,F1,1C,DE,5A,58,4B,65,23,58,08,BF,CD,9F,84,D0,3F,ED,D2,8B,D1,91,88,FB,F3,E3,9B,BE,D9,ED,C7,CB,09,55,F4,7D,4B,0F,05,B3,35,24,DD,3C,24,38,2A,76,C8,BA,3B,4A,90,E5,43,C7,C7,40,0B,1E,52,0F,41,18,A1,2C,AD,5F,75,61,96,21,C6,EC,4A,2E,AC,73,05,B8,2B,41,97,50,21,1E,F1,47,30,10,46,CA,E6,81,EA,DF,BC,F1,4A,B3,74,C7,26,CF,4F,EC,6E,CB,70,8C,0D,F2,14,6E,DB,4F,31,E7,64,E0,54,7A,16,B1,BD,35,50,3E,DB,EA,29,4D,CA,13,66,85,BB,08,CD,7A,6C,AD,92,A9,2E,C6,28,BE,36,51,0B,96,08,03,40,F9,D3,B8,C4,01,0E,BA,19,1F,50,5F,70,6F,12,6D,09,A4,49,45,F1,96,0C,61,9D,3F,C7,CF,87,46,4F,B8,D1,D1,ED,3E,0E,F3,32,D9,B5,31,DB,AF,DC,B9,5F,1B,83,F8,F0,CA,FA,A4,BE,59,A6,04,8E,C9,59,F4,42,FE,CF,C2,93,8E,A5,73,11,EC,5F,CF,25,39,64,76,74,82,81,36,FA,52,72,33,AC,8D,0B,0D,82,8A,65,67,A7,18,0E,E5,5A,DC,98,D9,BD,10,EE,FD,9E,84,82,08,53,B6,34,A0,3A,87,B9,35,DB,E0,07,19,EF,47,01,9B,F1,A9,B5,F4,1D,35,28,C3,30,6A,94,91,22,D7,DC,1A,EE,F0,92,9B,90,F4,A9,CB,7F,B4,3D,59,CB,DD,76,7E,B2,90,43,7B,3A,00,1D,FB,33,B5,4F,6A,66,02,F4,DB,F8,76,EA,80,7A,8D,B5,58,B3,45,9E,D4,71,F7,D1,B0,9B,1A,FC,6D,2D,75,71,FF,AD,DB,0A,47,FE,9B,B1,3F,F8,51,98,33,78,B8,47,C5,67,F9,DE,A0,2A,2C,4D,E7,B1,92,B2,6F,74,1D,E6,CE,80,76,8D,63,AD,6C,A7,8C,6C,77,48,85,DB,D5,23,96,2B,33,D3,55,EF,D8,8F,59,EC,C1,84,44,02,4D,86,62,AE,BD,8C,53,33,8C,63,B9,49,6C,1A,87,3E,FE,DD,C7,C2,60,43,62,A9,5A,20,DA,13,E5,7A,E0,57,65,35,F4,2D,6D,09,1B,88,AF,B8,6F,8E,F8,3C,8B,5C,ED,9D,C9,6B,0E,61,41,EA,90,5B,91,22,AB,C7,D1,8A,94,45,34,5F,29,6C,D4,A2,03,6D,E9,55,54,DB,31,48,D3,A3,1D,75,3E,9E,93,39,27,A9,D1,1B,C7,9D,CD,2F,25,03,93,82,E5,17,7A,12,C1,91,45,8B,50,18,D8,48,E1,69,84,CD,C8,E9,2E,DF,6C,7B,59,BA,82,6B,69,B0,20,60,99,86,AD,CE,51,20,CA,46,49,87,6D,2E,04,69,AA,AD,23,92,D5,B0,4B,4E,E2,D7,77,71,DA,D6,05,42,3F,9C,4F,5A,72,78,8A,F4,8A,09,F0,56,F4,5F,FB,EB,65,E4,58,CB,B9,DF,52,49,57,33,88,5F,1B,F4,28,9B,01,CB,75,E4,97,E4,E0,A9,D0,3F,C7,89,9B,C8,A9,D3,85,83,91,13,24,FE,90,63,20,D4,E3,F2,33,21,C1,4B,ED,CD,52,4A,D5,E3,A9,11,88,71,C3,79,06,89,94,24,E7,D5,5E,A9,D2,4F,6E,16,82,73,5A,62,5A,BE,3A,D6,12,D2,0D,8B,A1,94,7A,24,04,CF,48,69,6E,96,D8,99,3B,FC,D5,63,1D,5B,9B,C1,A3,BE,12,02,EF,52,E5,AA,E4,9D,4D,C2,09,85,14,2B,5F,18,5F,9E,97,B1,1B,03,78,4B,46,BB,D3,D0,6C,25,20,AC,D3,6F,E1,3F,77,BF,9C,C4,A7,D6,F0,8A,C7,FE,34,18,98,F2,5A,B6,63,97,AB,84,A6,CB,38,BC,38,A6,33,91,9A,84,9F,94,EA,F6,E7,60,05,AC,11,73,D8,CD,02,B4,8D,2A,EB,D1,C0,E0,9E,DC,65,49,C5,09,B6,08,AD,1E,44,D7,2C,8F,77,AF,38,18,52,4F,05,F3,6D,E8,E1,18,25,DB,A1,9C,F8,EC,70,23,F8,84,1D,D7,67,B5,19,C5,1C,D2,E8,D0,17,38,C8,26,EB,8E,AE,F7,9B,3F,16,AB,61,1C,DC,09,E8,B2,E8,E1,14,4B,FC,DE,90,15,73,B0,CA,AF,E1,C5,CA,A8,A7,B4,6C,E6,1D,12,DD,B2,A5,83,21,AA,8A,DE,37,59,D1,F4,8D,E8,2A,92,4F,AD,71,D8,FB,4A,DF,DB,90,85,DB,4B,79,E4,67,EF,72,7B,F7,7D,81,A1,5C,C0,6E,D4,23,EE,E8,F9,69,22,91,C1,1C,89,9E,A5,D3,7E,98,25,02,2A,11,1C,59,59,D4,10,77,D4,C3,2B,DB,53,CE,09,10,71,41,4F,CF,19,DD,F9,9C,0A,00,36,40,47,B9,84,6F,00,44,48,99,DF,7B,57,4B,BB,FA,13,AB,91,77,97,78,B3,6F,6A,D6,93,5B,EB,C4,87,28,22,A2,39,54,8F,51,8D,95,6C,7E,5C,06,82,1F,C3,56,28,A6,42,24,46,C2,25,55,A3,70,EE,AD,84,9B,07,CE,7E,D0,4D,9A,A5,2E,D2,DD,A3,D7,D4,EE,0B,C0,B2,0B,56,B9,00,2A,12,78,D2,91,6E,77,10,4B,21,31,67,1A,20,5A,F9,F5,B2,83,EB,4F,DE,2D,27,97,99,05,FD,E0,48,75,8F,5E,BD,01,DB,BB,3A,EF,60,E8,AD,69,56,1A,C6,1B,CC,5C,C3,EE,F4,FF,52,FB,54,81,AE,E1,34,6A,52,44,05,12,D8,60,8C,62,C5,93,D1,A7,A2,1F,DC,7C,D6,3F,7A,FB,2D,07,23,13,BD,7E,B7,73,B3,AA,50,10,F3,E0,AD,AA,B3,82,C3,F8,71,DA,BC,CE,A3,F7,06,B8,06,94,7E,2C,F4,D1,0E,29,3B,14,1C,BD,7B,48,39,D5,30,80,16,B2,86,FC,8B,1F,99,BA,09,34,50,9B,87,49,B1,D5,00,F9,68,70,94,D3,C9,60,CE,BE,56,3E,93,B6,9A,25,A2,83,44,A2,9E,63,62,7F,D1,A3,8B,27,69,4A,71,15,58,06,07,95,72,47,93,FA,A3,65,86,56,5D,F6,18,CC,8E,D3,A8,AA,0A,FC,12,14,49,98,E4,10,67,99,2F,D0,D6,12,D0,26,50,B2,45,25,16,38,1A,AC,38,10,D8,D3,AC,53,30,94,C9,BE,B5,3D,30,7B,57,4A,97,0F,06,C2,93,5F,6D,12,8C,13,9C,6F,5E,84,41,BA,DF,36,F2,FF,B7,05,3C,AD,81,02,21,67,D1,6A,F2,66,B6,4D,8A,3D,8A,D3,60,79,9C,E2,D9,8C,51,5D,A9,F5,CC,25,B9,C0,F6,23,F1,72,A3,0C,42,3F,52,9E,FB,5B,14,69,A7,4F,88,90,34,89,77,3F,8A,17,EA,A3,F5,18,61,63,E5,9C,16,C3,32,EE,27,C2,69,B7,97,C7,15,5E,4E,14,4E,9A,C0,0F,93,13,4D,DF,05,24,E3,A2,BE,4F,73,68,CB,BE,56,BB,48,2A,7E,33,63,0A,24,08,DA,54,1A,85,CA,02,EC,B0,08,A7,FE,3A,7A,28,02,78,42,3C,AB,E9,21,28,91,6C,F1,9A,EF,59,14,06,6C,AD,1D,7D,D7,E5,EF,E6,0B,E0,8A,CC,0A,CF,17,6F,C4,34,F5,6E,8D,02,DA,B0,CD,5F,9B,B9,8B,97,3F,D2,23,39,5F,6B,79,DD,1A,63,67,E5,66,B9,1E,48,C2,9E,ED,E2,99,69,06,63,DD,B9,48,F4,AA,9F,89,45,2F,8E,22,2B,28,A3,9C,4C,07,38,2F,B6,3D,FD,B5,FE,18,71,39,EE,8A,D7,C0,61,92,26,BF,71,7E,49,03,07,B4,0C,52,74,D8,A5,04,4A,9B,DB,6A,CC,5D,8E,9A,08,3C,9E,5B,2F,85,12,FC,D6,DC,65,61,E3,E2,76,F5,2F,BB,CD,67,B5,EB,D3,01,C2,F3,08,7A,1D,32,AE,31,A1,BB,9D,80,93,9E,89,1D,D2,F7,16,79,BE,63,CE,FD,98,2B,FA,B7,D5,34,B1,32,7C,C5,87,96,89,29,7D,11,BB,14,CB,62,FC,8F,81,7C,6D,33,EC,F7,6E,14,75,4F,EB,57,95,48,54,DE,F6,2C,82,82,F7,9C,03,70,6C,26,00,E3,8F,8D,1A,0B,EC,E0,86,63,7F,EE,AD,60,46,6D,BC,FB,EE,81,26,A0,B9,4D,84,13,07,66,C2,CD,59,84,B9,42,A8,F5,18,14,1F,EA,DF,7C,3C,0E,46,EF,E6,69,EB,CD,81,C1,A6,9F,89,8B,21,1A,19,1D,8A,94,03,C4,17,91,F3,07,C3,EB,CC,B5,4C,B6,F3,74,05,69,EC,DE,3B,B1,FF,F8,99,24,A8,F1,A5,F0,E2,C5,85,A3,4F,96,17,65,93,4F,AD,D8,4A,FC,72,2C,33,12,66,28,14,D0,35,F4,4F,C5,BC,95,D2,17,20,2B,64,BA,B8,08,1D,8F,46,70,C9,5E,30,4A,A6,E9,52,E9,48,34,70,9A,8B,3F,D7,01,7E,77,04,DE,FE,43,99,F3,6A,3A,59,29,44,9E,6B,95,68,3A,93,33,74,A3,4C,29,8F,0F,07,86,03,F1,60,D5,67,89,98,C3,90,E3,01,CC,6A,8B,78,86,E9,E9,D5,53,78,59,C2,4F,72,C7,63,3A,2B,DB,3C,D4,37,DF,42,AC,51,BC,6F,3D,6A,C7,A1,DA,A4,F1,F8,7A,37,E6,E0,F3,8E,5F,8B,7C,28,01,44,F2,15,D4,66,59,96,3F,53,66,37,3B,AC,FC,3A,65,0D,10,D5,98,52,86,3F,33,D7,55,C3,1D,9D,B9,FA,DC,6B,15,7A,E6,90,C2,3C,05,F1,0C,3F,1B,FB,5E,2B,FA,BB,4B,36,ED,7F,26,A4,A4,22,A5,18,29,E0,6D,1E,99,81,16,4B,60,C8,C8,C2,9F,6B,B7,A1,CB,90,39,91,D9,B7,1B,9E,D6,94,EF,55,9F,94,C1,30,A9,6B,28,00,F7,2F,1E,24,B8,3A,52,58,3F,97,2F,30,8B,AF,6B,AF,55,DB,C5,EA,FF,D3,35,16,2C,56,8B,EF,84,C4,8B,FB,9B,72,95,46,F0,10,C0,69,59,ED,46,6D,B6,D5,29,11,9E,BC,2D,DB,E9,FE,FB,B7,10,6C,87,0B,74,E3,57,35,21,0B,9F,35,8B,EB,D2,25,69,4D,0A,51,04,E7,6B,A8,9B,CC,AA,DF,A8,A7,56,92,73,D9,C7,1F,26,90,C1,78,94,F5,41,D9,E4,8D,BE,F5,FC,A7,D5,C3,CC,2B,7E,2A,8B,78,F5,01,0B,1F,6D,52,EF,E5,2C,BB,99,A1,64,70,21,03,DE,0F,A4,5F,9D,8E,24,D7,83,4A,DC,54,17,15,EF,D5,33,66,90,03,DC,3E,0B,78,E8,F4,1D,F6,6C,78,63,AF,5F,B7,89,B6,1D,7E,D1,97,2F,3E,FD,E9,66,D6,58,27,05,F3,70,78,76,2F,90,56,6A,B7,1B,7C,7A,5F,9A,48,DF,65,67,CA,EA,C4,83,DA,3D,40,CF,52,0E,D2,7E,7E,7D,A1,F3,BD,BF,77,2A,5F,AE,7B,3B,79,07,F0,C7,0D,EB,36,7F,19,2B,3D,70,54,B4,E0,ED,45,2C,37,7A,4B,0E,76,C3,A1,D9,BE,6F,72,32,AB,14,C0,58,03,5F,55,DD,5D,4D,44,80,B4,1C,99,44,A7,07,C0,7A,B5,B0,68,9E,FE,77,EA,5E,F9,CE,91,B0,E6,8F,3C,DD,68,A8,17,EB,B5,CA,23,C7,5B,01,EF,4A,8A,07,E6,05,09,5E,8F,9D,F7,C0,04,38,D7,46,72,9A,1E,51,07,E1,C9,99,14,40,63,F8,8F,2B,E4,A9,8E,62,11,D4,CE,C8,19,14,0E,1C,88,3A,1A,45,39,0F,52,97,C2,E8,92,CF,78,94,BC,41,A3,33,A0,24,40,10,2D,AE,25,CB,4F,BD,1B,D2,D6,33,D1,FC,3E,EF,F1,F3,01,B8,7E,26,FE,3B,3E,FA,2C,CE,8A,8E,A1,05,B1,96,14,08,F0,E9,B1,AF,18,D2,7A,88,63,48,5C,D1,B9,54,45,76,FE,2C,31,86,13,E5,41,06,83,49,DE,30,7F,EA,D1,78,31,B3,24,CC,26,04,FB,7E,B2,A0,10,D3,D7,CB,D5,C0,37,65,E6,CA,C4,31,82,7B,C1,6A,AC,2A,33,4E,88,04,A9,21,79,4D,85,74,35,76,75,3A,15,74,BA,D1,A6,5C,AF,12,6A,B0,B6,A4,3E,24,16,DC,7C,2D,49,0C,08,44,A8,F1,A1,4E,0A,F2,BA,38,EB,24,9D,22,61,BB,75,73,6A,B8,40,80,14,F1,A5,42,E6,6C,D9,ED,3B,B2,0C,9B,AF,F6,BB,70,7B,CC,0A,90,C2,AB,FD,7E,22,81,B0,F4,87,2A,BB,7C,85,51,A5,50,8D,00,6E,1E,DB,AF,55,59,D2,EA,A7,A5,57,89,82,A2,69,22,8B,56,85,D9,04,9C,25,CA,DD,3C,4A,FA,F6,00,22,29,EC,FE,69,40,47,CF,D7,1F,D6,85,9F,04,03,B8,01,4F,38,E9,F5,3A,61,5D,64,C9,CB,B2,3C,EE,C7,22,06,55,92,4A,8C,82,ED,81,7B,52,0F,0B,0A,8F,87,DC,70,54,BC,A5,F8,DD,D2,6C,1F,0D,BF,D6,3F,00,45,7E,F0,18,80,85,10,B2,26,CC,84,88,C8,CD,B1,57,05,3A,B0,F6,4A,44,8E,E5,9E,91,3A,E1,A8,14,DB,53,2C,31,C5,4B,C6,EF,0B,75,54,AB,E5,88,5F,BE,D5,87,11,7E,CC,29,73,58,D8,26,84,1C,58,09,DC,96,B1,D1,15,27,3C,2B,78,B0,9E,DF,44,8B,3C,84,91,BC,07,B9,E2,BA,64,68,52,6B,C9,52,D6,20,D9,A3,F9,E4,A4,05,DC,90,2C,7B,DD,46,56,6F,46,A0,1E,B7,82,DC,B9,4D,94,A5,8C,82,FE,0E,CE,8B,C9,5B,D1,83,B0,FC,A6,E7,B3,4C,78,15,7A,10,D4,FA,CB,1B,9C,27,B7,7D,63,F0,3B,79,51,43,97,80,03,13,B2,CF,75,5F,08,0B,9E,87,A2,9C,1D,0E,68,C9,AD,F0,A8,39,B4,62,4F,A9,AF,FC,77,E7,FA,7C,81,2B,DD,8D,52,87,DD,20,D7,04,1E,33,BC,36,9D,49,B4,EE,A1,DF,44,F8,9C,5E,D8,9B,1B,9D,30,44,ED,6F,82,76,98,AC,4B,51,EE,58,7D,A1,D1,C7,21,2D,6B,37,40,E3,FF,B3,5B,82,C4,A9,43,20,E1,FA,EB,74,9B,0F,8E,8A,8A,33,95,38,70,96,B7,C7,B1,DB,AE,BC,DF,A8,99,1B,6A,75,B9,DB,7C,80,7D,62,28,5F,A5,2E,E4,9C,9E,E1,DB,B6,1F,92,CB,14,C4,D8,5F,DC,6F,5E,A0,AC,D1,94,7A,6C,29,56,99,17,39,C2,EA,81,0E,A8,FC,7B,92,11,9A,15,BC,23,D8,64,5D,AB,5C,B5,82,6C,35,1B,5D,CB,D6,D4,D9,7F,17,1D,33,A8,B2,2E,68,37,AD,0F,3B,E2,7A,50,77,58,ED,9E,EC,C9,F2,42,4C,1E,30,F5,98,7E,9D,91,CF,0C,C6,8B,E4,5D,3E,1C,E5,64,A1,DF,28,D5,B6,22,D8,E0,83,BC,17,4E,20,53,F6,57,CD,83,10,62,D7,37,67,36,31,74,E7,CA,05,AB,56,21,E6,FB,18,62,B9,44,16,94,A5,B1,C8,93,2C,AF,D0,6B,5E,82,87,B8,84,CE,26,8A,40,33,63,11,39,1B,E7,E9,45,1F,6D,E4,72,CD,5A,58,86,DC,05,38,AB,3E,10,99,79,A6,2A,E3,5D,B1,F8,3D,D4,A2,19,FE,9A,1F,A6,72,8E,AC,06,EA,0D,1A,7C,47,6B,2A,CF,DA,70,BD,21,76,58,71,1B,22,84,E9,84,73,8C,38,C0,81,59,3B,E0,D3,84,7A,29,5D,85,BC,17,68,26,0C,80,5F,47,F6,D8,BE,44,6E,E4,51,9A,1B,76,06,4F,09,B8,90,DB,AF,52,41,51,4E,61,10,14,0A,6C,21,E3,74,99,6C,CF,5C,A6,7A,31,60,5C,65,48,1D,73,02,A0,E0,54,F0,90,23,BE,9B,7F,6E,0D,B0,11,6A,89,E9,8C,38,15,5F,C8,D6,80,DA,8D,05,5F,0F,C4,7D,DC,CF,F0,7E,B3,1A,E9,54,29,4B,7B,F9,A5,21,74,20,11,B0,34,22,42,9A,EB,E3,93,36,68,1E,68,34,8A,54,93,CF,5D,72,CF,56,A8,D9,14,BE,68,E4,75,A7,A5,82,14,6E,A6,8D,CD,16,6C,56,3B,25,D8,04,57,6D,A5,3E,2C,BF,AF,07,B9,E0,5B,43,92,0E,CB,BA,0D,6F,96,DD,C1,1F,CB,69,56,0A,60,CA,49,6F,76,B0,10,55,4F,CB,42,65,76,12,53,14,18,E2,CF,F8,32,E0,94,CD,85,E4,54,2B,7F,5A,89,35,66,C3,13,B3,BF,F1,D7,38,ED,02,95,E2,9F,5F,68,CB,A8,B8,17,2B,DB,CC,CA,01,DA,C2,49,D7,DB,8B,35,25,89,60,53,DE,B9,D4,56,4E,C7,CF,B9,6A,47,12,EC,D0,49,E2,AD,B0,8C,FC,32,B3,6F,DC,C5,5B,2F,A5,B8,26,9E,3F,F8,AB,8A,BA,52,70,CB,20,C2,94,71,4D,CA,4D,3F,EC,51,E1,85,07,75,D9,22,CB,68,09,6F,B4,C3,55,2B,DD,3A,49,C1,80,C2,41,B4,66,CB,F0,89,BA,67,C4,15,3C,CB,A4,06,F5,3C,B9,F8,57,1F,53,7D,85,08,10,63,2E,10,AA,05,2A,C6,55,9D,DF,25,EA,25,C7,BF,66,EC,F8,E0,68,69,6C,4C,F5,1A,40,62,B1,A3,58,2C,C8,91,7B,86,AF,5E,11,B3,0C,B7,BA,69,27,7E,29,B5,C4,24,05,13,D1,66,1D,A0,B5,69,4D,00,C1,EC,C2,1A,FD,50,1C,79,B5,B1,6B,7E,15,6A,06,29,8E,5C,EF,C1,B3,68,B4,00,FA,16,F7,C7,68,9B,4A,0F,E4,BB,F5,9B,6B,A6,B7,CA,D1,FD,49,02,1F,AD,C8,93,DB,7C,55,26,49,CF,A9,0E,DF,3D,32,35,E8,45,2F,71,60,65,89,01,06,B6,D1,55,74,86,EF,36,8A,37,24,89,BE,CA,5A,47,24,BC,02,36,66,39,BF,85,F2,AF,A9,C2,F1,02,96,76,39,D7,A4,1A,0C,0A,37,3F,8C,22,66,6C,22,F5,03,B9,3B,D1,86,B2,D7,42,04,6D,02,94,C0,B0,3F,9A,AF,47,4F,F9,B3,04,50,1F,1A,5B,51,62,C5,8C,0C,E0,F0,F5,06,7E,32,67,CF,CB,E4,6F,9B,81,DE,07,16,87,C6,97,4A,39,89,E8,F2,1E,CE,37,0F,11,9B,C0,EC,0D,0A,4B,57,5D,EB,D3,30,88,C1,6B,AE,18,BD,65,ED,E7,4E,A1,B8,DF,CC,CB,5F,77,C7,7A,23,E7,7A,78,B1,53,4E,44,8B,EA,05,AA,65,D2,46,62,CA,66,C7,25,A8,2C,52,1B,DF,2C,80,C0,D0,B9,05,12,FA,68,9A,C1,11,14,D1,65,9D,79,38,BE,E3,BC,8F,5C,66,4B,DD,15,6E,2B,F0,E3,25,3E,35,E2,C7,15,51,70,FC,B8,7A,23,47,27,CC,D7,15,A3,DF,03,D2,50,09,55,7F,A2,28,CD,34,28,93,CE,E8,E0,0B,76,7C,40,40,72,79,84,2F,D1,42,83,C4,6C,E7,72,54,F8,0D,37,E6,AC,2E,D6,0D,B8,B7,78,EF,58,D9,76,38,73,67,23,66,91,BE,27,2A,15,DD,A4,69,AC,46,E5,32,CC,74,94,CC,E8,72,6D,4B,7B,2F,E3,43,77,0B,BE,14,1D,E9,E8,9D,9B,43,4A,40,42,67,6D,E3,0E,33,D0,28,31,46,CE,AD,05,AA,2E,C4,34,B1,F1,B1,0E,DB,63,25,03,CB,BE,DD,A6,0B,3C,B2,8B,82,96,F2,29,34,86,A4,C2,FD,11,11,FF,AB,07,5A,EF,C9,08,BC,D5,0D,B4,33,37,A7,DD,57,BB,BD,3D,4C,7A,81,FB,91,19,EE,33,9E,58,50,44,01,49,A2,86,91,92,60,21,80,12,2D,90,CF,A8,CF,24,E6,26,67,45,35,E6,A7,32,45,24,FE,73,AC,13,0D,3B,6C,EC,84,86,AC,24,01,C6,D2,9D,A7,81,E6,12,9F,DE,AD,4D,1E,F6,8C,CC,C6,D0,7D,B7,5F,F9,37,29,B6,14,D0,19,5A,A4,2C,D4,56,D5,DD,B1,DF,98,42,65,DE,B1,DB,65,C0,16,33,F4,FE,18,91,E8,35,AD,54,55,37,E9,B6,4F,86,6D,7A,C8,C2,96,6B,86,89,8C,EF,1A,81,48,71,B4,9F,C0,E2,A1,73,A8,F6,0B,B1,83,AD,97,98,55,4F,8D,9E,5C,31,8B,21,3E,58,CF,99,F8,7C,52,ED,7A,A1,64,A0,B2,8C,B1,41,89,72,36,6A,56,42,22,F6,4C,0B,19,D3,11,34,A0,97,27,28,E0,93,04,49,10,AA,2B,A5,B3,AB,A1,60,1E,EB,81,29,38,70,30,DA,4A,6B,87,11,8E,D7,BA,B7,FD,61,2B,5E,B5,71,57,CB,E2,F4,74,AD,0B,B8,EC,F8,D0,8E,C6,1E,F7,60,AD,CA,54,45,31,20,7B,9A,AF,DC,23,12,AC,73,4D,AB,4D,6E,8B,BD,BD,D4,6D,AA,BD,CF,90,AB,89,7E,EA,48,FD,9F,50,5E,C9,77,D6,D5,DF,E7,73,84,D7,03,D5,DF,FD,05,9F,B1,65,B3,4B,C5,B1,37,BE,4C,06,47,AD,3E,1D,05,8A,BA,62,9C,9B,E1,BC,58,75,69,B4,F0,8A,BF,99,F2,1C,4C,ED,C7,3D,36,36,5A,1D,DB,93,6A,D5,1B,44,BB,34,E1,52,B5,1C,E7,D4,8A,01,87,A8,2D,05,84,03,96,10,D7,A3,35,C4,57,FA,42,C4,E4,CC,EF,F2,58,23,4F,96,AA,67,E8,54,CA,28,F2,1B,93,91,4F,57,9C,84,79,FA,4F,EE,C4,DF,AD,68,15,D8,5C,A9,E4,8C,C2,71,0F,97,27,68,D1,14,A0,2F,A3,1D,07,86,EA,36,BB,D9,30,FF,89,D9,F3,C5,77,DA,AF,9A,7F,0B,1A,25,0D,6C,41,F5,03,3E,92,73,28,1C,D6,35,70,52,74,2E,2E,81,B4,CA,95,77,94,07,C8,61,09,6D,84,3A,9F,41,80,AD,58,9E,20,F6,15,26,8A,A7,FE,CE,E0,A5,E7,C4,60,8E,6E,B9,D6,42,5D,82,D7,3E,9E,1D,AC,F4,63,23,36,21,C8,9B,68,04,3D,C0,F7,DC,EE,AC,5E,09,88,B6,83,24,23,F0,EC,73,6A,ED,65,41,45,AA,80,13,06,56,59,25,62,26,08,B0,83,28,48,47,DF,B1,1F,DD,41,5A,15,DA,10,BB,3C,0B,20,3C,1F,79,32,40,59,22,43,36,89,D8,D8,75,17,7C,E1,9C,80,95,4F,A6,EC,A7,DC,10,92,2A,44,B2,B4,8B,38,FE,E7,61,C5,34,47,18,DE,EA,35,BE,74,92,3D,85,D2,C4,2B,E3,42,BF,2A,08,5C,B0,0B,F5,D2,06,98,7A,67,37,A5,EE,5A,40,7B,08,7C,67,56,EA,8F,B8,1A,00,86,BB,AA,CB,14,0A,F5,E6,6F,7E,A5,82,47,FD,A3,AD,71,17,6A,F9,0A,26,BD,AB,5E,FE,F9,25,76,38,DE,BF,BD,76,CB,08,25,74,F0,58,51,07,47,87,B7,95,62,AB,EA,27,5E,D9,00,8D,F4,49,4B,E6,4A,CB,75,11,F2,F3,ED,8C,84,A0,DC,99,FA,D8,9F,95,87,72,BA,49,D5,99,2D,4F,6D,5D,DF,80,4F,4F,5C,38,EC,D2,D7,72,61,18,0A,3C,DF,43,20,F5,44,1B,4B,B4,24,3A,5F,4C,5C,3B,DA,A4,8F,DD,18,0A,C3,E3,82,ED,47,19,4C,0C,F7,74,69,DE,DA,1A,0A,01,AE,91,19,20,D0,03,91,F5,9B,4E,AD,48,90,B1,FD,AA,E3,31,48,7B,E4,96,4E,3A,54,6B,A6,50,F1,47,19,0E,85,A4,7E,17,12,92,EB,85,CD,A0,00,DE,67,2D,AF,EA,47,84,E4,4F,41,92,0A,8E,A7,98,AB,DD,5B,96,6B,4C,59,46,F8,12,21,5F,7F,F3,FB,DF,00,13,BF,61,7F,B9,E3,45,E6,D9,F0,CC,B2,13,BC,07,18,E3,12,3B,F8,F2,45,A9,C5,E3,4C,47,C2,59,DA,70,83,20,7B,17,11,3F,97,43,EA,58,46,8E,27,DE,54,1D,E4,98,AD,E0,C3,E3,44,68,4F,5E,BA,33,E0,55,61,FD,D8,BA,B6,40,58,35,D7,A8,96,9F,32,AE,F5,52,D8,9D,3A,2D,CD,9B,FA,6E,F7,53,95,FB,DF,E2,7D,54,23,2D,70,84,1A,FD,28,70,AD,BE,48,62,F6,86,0B,06,EB,2D,C5,E8,C7,D6,4A,0A,22,3D,61,77,FA,BE,AC,00,5A,1B,4A,C1,AD,B9,9B,93,56,FC,29,DC,6E,CD,D4,31,4C,BE,FD,61,0B,92,E7,4C,AD,AE,4A,D1,8B,E6,E4,0B,FA,B0,5A,7D,0D,49,8C,CD,A2,CB,6A,0D,78,39,99,08,D1,63,87,96,BD,3E,A4,8B,BD,E3,9A,C9,87,79,39,46,22,D8,D0,2C,0F,36,BC,5C,1B,B0,B2,E7,C4,17,5D,B4,62,B1,19,84,5F,EC,6D,4E,55,E0,4A,4C,E8,EC,5A,AB,9B,C4,77,19,35,1F,4B,A0,3E,16,14,11,C1,B2,78,C9,FE,60,DD,97,4A,D5,90,4B,D6,C6,1F,58,8B,27,5F,03,B6,0C,3F,38,A5,CE,33,EE,2C,9A,0D,73,45,74,CC,70,A6,9E,DD,6A,4C,91,19,25,00,76,3A,4E,3F,E6,F6,E1,DD,88,7F,74,21,EB,E3,2F,41,0A,DA,62,4E,A3,75,30,B8,88,A1,D3,BB,79,1C,45,4F,A2,13,59,ED,31,98,28,98,50,30,6D,D8,C3,33,26,A7,6A,FD,CF,28,BD,FF,03,7C,20,42,92,D2,CF,94,6F,20,29,17,22,0B,06,D3,2A,CE,3D,0B,1C,70,31,F0,B3,CD,F3,7F,D2,7E,D8,1E,82,53,D1,27,6C,1B,59,58,2C,60,05,46,4F,C1,E2,0C,98,8F,D4,2B,4A,D6,8E,EB,89,E1,41,B9,1B,B5,B8,68,65,87,09,4F,7F,A5,4A,2F,93,48,24,35,54,3F,E7,85,C2,4F,88,85,A5,C8,96,91,95,3D,5A,67,EB,FD,67,E7,A0,74,72,DB,AA,9C,68,76,65,64,4B,06,1F,CE,58,3A,78,38,A1,47,61,D9,12,2E,44,85,E0,90,1A,9D,9E,B6,A8,D5,E4,D8,95,7A,8F,B6,A3,05,5A,70,7F,A5,43,3A,D0,1A,59,BF,A2,CE,56,35,18,00,CE,C6,D2,3C,58,8E,AB,25,71,6B,67,40,BF,35,D8,02,91,BC,39,74,42,A6,32,39,64,0A,2F,2D,05,A5,57,C0,8C,00,1A,82,00,09,9B,82,91,59,45,F5,5E,12,55,15,F7,50,62,34,14,E5,9B,E4,25,D9,4C,37,AB,5D,86,89,2D,FE,D8,70,E7,4B,68,28,41,63,0C,E2,C7,D2,E3,DB,A5,BB,F4,61,4A,31,25,61,5A,33,E7,F6,0E,47,4F,01,AE,1A,37,88,D8,D7,AA,E8,95,02,42,DB,61,33,83,9D,22,2B,91,26,52,01,61,76,CA,AE,42,A4,86,26,7A,B9,1E,2E,5E,35,4E,E9,0A,D5,3C,66,C2,83,B3,18,82,87,8F,DC,BD,B0,E0,B5,11,B0,E2,EE,83,F3,C9,08,0F,AA,81,C1,97,D3,07,DA,1F,C5,71,4B,C7,BC,CF,39,53,F9,01,CC,07,D1,4C,92,17,D4,3D,45,AD,4E,C0,88,CA,BB,FE,3B,23,91,B1,5A,69,1D,90,F5,46,F9,FC,DA,F8,89,21,42,76,CE,2B,D1,5A,39,AE,22,D6,73,CA,4C,54,57,E1,0C,86,6A,FB,80,B3,02,51,03,49,43,D0,10,50,10,97,7E,DB,68,AA,26,EA,A1,2B,EC,B5,6B,2D,B2,8F,60,7D,EB,A4,C8,40,FB,40,21,5D,44,53,6D,9A,7F,F1,08,73,AD,46,7A,27,1A,C4,4D,95,69,D5,A5,87,A0,99,0F,AF,CA,FC,6C,83,60,3D,CC,99,BB,0B,6F,EF,2D,4C,F0,54,10,BD,36,23,A5,56,EF,20,D6,73,7A,60,BB,2A,75,F5,55,6F,A8,04,DA,22,D8,2F,19,1E,D1,82,F7,B8,3F,53,12,64,1E,08,8A,7D,32,72,BE,5E,43,C2,09,8A,70,AA,2B,1B,E9,3C,BC,6A,93,2D,DB,E9,02,D9,20,D2,FD,DD,8E,AC,63,EA,E9,19,2D,56,85,C0,9C,E7,05,3F,76,C5,0F,E3,28,D3,7B,0A,E2,7F,17,58,32,43,49,8A,39,1A,FA,08,55,5F,F1,44,D5,CF,4D,A4,58,DE,99,0D,87,11,81,BA,1A,E5,DD,A7,F7,77,CC,3D,4C,8C,7E,74,09,34,58,11,35,6B,39,06,59,FE,52,0E,32,85,B3,D4,CD,A7,A4,57,40,03,1B,EF,3D,44,43,C0,E3,13,1F,59,2A,31,24,18,D5,9D,C0,F4,AA,A9,50,6B,49,77,73,D1,85,54,9B,02,F5,1E,1B,6E,33,4B,DD,0F,74,82,A9,E6,D2,F3,46,43,4B,C7,46,9F,DD,25,FC,4A,9A,E6,A4,B6,E0,26,26,65,63,C6,29,C4,E0,AF,DE,1A,2C,88,89,A5,D4,94,F2,8E,B4,4C,8C,E4,7E,F7,25,E0,18,67,97,8C,59,87,22,81,10,86,4E,02,96,B4,E9,D9,24,C4,63,58,6B,60,66,98,17,1D,72,78,79,F8,1D,FF,D5,E9,17,08,B1,24,FC,EB,CD,3F,18,2B,A6,32,30,50,5D,D9,D3,36,35,DF,6D,9B,4C,68,85,AB,D8,45,90,6D,7B,99,A7,EB,8F,08,E1,DC,13,59,B9,10,85,03,28,42,3E,B6,95,19,2A,96,7B,FF,26,C4,FB,B4,DD,41,AF,FC,0D,8A,50,00,A2,1A,DF,35,09,52,FD,FD,57,C4,AC,D4,A9,75,0D,B1,C6,40,D3,2E,0D,C1,FD,F3,F5,8D,AC,C0,F1,A0,7A,44,69,E6,51,D5,61,C6,FE,E7,E7,76,B0,EB,45,2F,62,EE,F8,D6,90,B0,E6,B3,7D,EF,7D,36,96,C9,B6,AA,B7,1D,43,60,A1,22,F6,68,28,F5,66,59,76,94,0F,96,3B,A1,1A,89,59,0A,FB,D9,77,DD,82,7C,0A,94,4A,2C,21,3E,C7,C4,15,DF,56,25,06,AB,3C,EE,02,1E,9A,EE,F4,D8,D6,C5,89,A8,9F,24,60,32,3E,CC,92,7E,F5,A9,38,F3,09,61,23,0E,61,37,36,3C,AE,89,75,FB,35,17,1E,8F,E5,0C,62,A2,D7,F3,14,EC,8C,D1,33,14,BA,CD,2C,A8,D1,27,F8,98,A6,FB,99,DA,45,21,1D,FB,45,59,5F,AE,E2,58,A4,CE,22,69,29,B2,23,86,3B,B8,94,6B,36,5F,97,48,5F,9A,C5,9A,1A,69,55,0D,81,FF,02,CB,AF,7F,45,53,95,97,18,0C,75,A4,DA,A9,3E,8F,EF,CA,6D,67,6B,2A,34,CB,FB,A9,05,1B,76,79,52,70,48,0A,AB,31,47,87,1A,6C,2F,6B,AF,F9,E2,89,18,AE,F4,33,16,4C,E3,BD,EF,0D,E3,4E,57,ED,B5,24,9E,2A,88,7F,0A,7F,B8,00,DB,E6,18,4D,DE,BA,CE,A7,55,E8,B3,2F,CF,A0,BC,EA,D8,4D,AE,B6,3F,AA,0E,FE,7E,C7,A2,43,AB,31,4A,4D,25,A2,07,CF,5D,CA,F8,75,0C,E5,19,68,88,2F,32,E0,3A,72,2A,08,1A,1C,2E,5E,B0,7D,37,6D,88,57,CB,6E,26,AF,9A,47,C6,48,30,94,B9,B4,09,F4,0D,20,D9,D0,9D,4C,C8,61,13,FF,93,3F,FC,05,D2,2B,87,D0,6F,03,AE,E8,7A,42,E4,0E,48,3C,1B,87,65,DA,3E,B2,71,89,08,5A,A4,8B,1E,BA,22,A8,7B,24,A5,CC,2A,09,32,66,77,36,AC,CE,3B,93,00,3D,7B,98,67,0A,55,2D,09,42,A0,2F,1C,7A,C6,B1,C2,22,66,05,D3,AD,D8,BA,DD,53,69,9D,2E,EA,8D,70,7B,40,9C,3C,4C,E2,F2,2F,D9,0B,8C,5C,D2,52,01,2C,0C,61,72,96,8D,78,E4,CA,68,09,3D,B3,5C,9B,16,60,7E,F7,E5,21,52,E1,78,88,7D,7A,16,6F,9E,A5,9A,8A,02,6F,29,40,00,C8,07,C6,61,58,EC,F6,4A,04,D6,87,D1,20,0B,AE,0D,B0,F0,90,D0,8E,49,22,B7,AE,EE,FD,06,84,E4,21,C8,DB,3E,F8,DC,B7,D8,5C,31,C3,41,E9,FA,47,19,CA,17,9F,1F,96,22,94,E7,5C,1D,DA,D8,C0,E1,CE,B4,6A,5A,4F,F4,02,8F,C7,5B,4F,BE,15,DF,71,8B,56,D0,3B,1E,5F,C6,C0,2C,5A,F2,BE,3C,99,23,97,C1,36,5D,83,D7,9D,08,EA,BF,C6,F5,21,40,A6,CF,35,8C,9F,1C,0D,9D,66,08,7F,68,3B,6D,D2,72,03,8D,99,C0,47,44,7F,EB,0C,C7,F8,2E,97,B7,5B,22,9A,11,6A,FF,54,B5,7D,7C,9D,D3,D5,C5,95,DE,D3,0E,21,E8,DC,9A,40,63,3B,2C,D7,E1,D4,0C,8C,8A,C2,E0,AF,80,E3,63,E8,8A,13,9A,BD,01,5E,16,E3,CE,2D,17,19,F7,AE,3C,86,2A,DB,C0,D8,55,77,B6,23,56,3D,7E,C3,E1,23,52,22,CF,65,1F,85,5B,6A,7C,9F,72,B7,00,C9,E5,C5,9E,26,0B,C2,E2,55,8F,75,41,79,5F,92,3B,E5,13,9C,9D,CA,D6,2E,41,DB,3D,54,06,8E,B1,19,BD,A1,CD,57,B0,23,AA,B0,0B,F5,E1,B0,BD,7C,67,35,34,A2,FD,07,62,BE,91,CD,D8,FB,D1,2B,FC,4D,5B,86,BB,6A,04,0F,47,80,E7,E2,E7,C0,90,AE,55,57,85,69,F8,DF,01,F4,BE,52,71,A6,9F,D3,D3,09,D4,96,6A,E0,33,8D,BF,DE,92,C0,06,59,18,E5,EF,43,DB,A3,16,6D,C6,9E,67,B6,97,A4,67,86,7F,DC,23,37,A0,99,54,55,D2,65,99,EB,4D,C5,8D,1E,FB,F3,AD,04,E9,A8,77,58,06,B5,D6,AE,8C,53,EA,33,59,D2,C1,B5,DB,D8,CF,5F,59,B9,49,B1,F8,F3,3B,4B,48,2F,8E,93,A0,71,4A,5B,8C,CA,8A,2D,91,79,57,DC,64,B1,94,05,02,B4,20,2E,FA,83,4B,4B,65,CE,0F,F5,8C,7C,2D,C7,80,03,C7,4F,75,CC,DA,FC,8D,F2,BB,85,54,85,4A,F0,F1,90,08,48,5F,EF,6B,3D,71,FF,79,7F,44,83,C7,EB,F3,0F,66,D4,42,0D,14,E2,5A,A9,2B,87,0D,47,EC,C8,F6,3E,6E,B6,D3,BF,3D,E1,55,13,BF,E3,11,F9,EB,BE,B2,6A,D7,B8,7E,25,64,4C,92,1D,69,45,D7,EA,1D,DC,7A,C6,23,B5,F1,62,3E,D7,31,43,89,03,B0,60,E2,A8,AC,0C,07,2D,93,08,77,91,FB,51,65,53,B6,D5,03,50,40,00,45,1C,56,E1,2D,F0,B0,E9,5D,69,00,02,CA,54,91,47,A5,2F,56,DC,A0,DB,7A,5A,0A,5C,25,BD,99,A1,CF,C0,63,BA,87,FA,3D,95,A4,14,93,BC,66,8E,2C,B9,7C,28,CD,86,81,D5,91,F9,C9,C1,6B,EF,FF,C9,1A,41,84,0A,D3,2B,17,CF,83,EF,92,8D,1F,30,AF,EF,0B,EB,72,9C,62,9E,9D,46,6B,FA,D3,BB,CF,A1,3C,26,7B,9F,75,2F,0C,21,06,D9,1F,BA,9B,68,D9,28,36,58,F9,D7,46,4B,39,36,7B,33,5B,EE,B9,EA,22,03,FC,BF,57,67,4D,F8,AC,52,62,57,E8,80,16,D2,6C,5D,01,93,B4,1C,0D,2E,1A,30,93,DF,7D,AE,D1,A0,8B,1F,0E,DD,4E,9A,C0,68,C1,7C,B5,4B,A7,FE,CC,00,95,0F,78,FC,36,8B,02,85,32,E8,DB,C9,AF,7F,0C,04,DD,FD,3A,9E,1B,7C,07,AA,A4,59,3A,E0,85,A7,A4,BB,4E,A4,C9,88,90,D5,51,40,B7,92,F0,1E,AC,82,D7,38,6F,E8,05,C6,31,1E,1A,34,96,D4,5E,8B,6F,B6,C4,34,8F,86,7B,8A,96,B0,13,30,86,3A,D7,02,31,A0,63,45,F2,FF,8A,B0,83,2A,29,9A,F9,B6,BB,81,57,AE,C5,F1,B8,56,09,2F,BC,0D,98,20,F4,79,0A,98,40,DD,57,1C,8D,4C,B1,05,51,1D,82,8A,14,94,EE,4C,CF,0B,0A,81,8C,7C,8E,F2,F4,44,4A,46,C6,71,93,64,65,01,05,94,18,D7,3B,F3,53,0C,CF,F8,0C,B1,35,C2,F3,BA,2D,CC,39,CD,0D,75,00,6B,CE,7F,E4,22,9F,CC,0F,8B,89,19,B6,16,BD,4F,2B,87,D8,EC,1A,14,E3,01,9E,56,B4,1E,BA,44,2E,29,8F,3B,48,60,20,E3,86,03,ED,81,A0,F8,7C,A0,B1,AB,CD,DC,63,F3,DE,25,14,3E,D6,D8,37,DC,EC,7E,5A,19,51,6C,4D,BC,36,D4,26,08,58,1A,47,71,AF,B3,1F,90,79,45,1D,22,64,66,A5,92,CD,C1,4B,73,00,C1,A6,1B,AD,A5,96,7E,50,74,7B,67,83,9D,E9,0B,3C,D6,04,0E,A8,2D,2A,67,50,03,5F,66,C9,93,E7,3B,F8,17,23,AA,47,10,55,1C,D7,F4,4B,0B,01,D8,02,68,20,72,B6,7A,86,B3,8E,FE,F0,67,24,0F,95,CD,1A,A8,9E,39,15,C6,BE,40,3D,F1,2C,37,1C,A5,54,4C,BE,B3,2B,B7,80,4D,E3,23,D4,40,D4,55,6C,5A,D1,09,20,DA,A9,75,84,A9,92,E9,DA,88,C1,17,02,7D,E9,9F,75,28,71,83,4C,B8,80,61,D0,1D,23,3C,AB,9B,C1,40,33,1A,BA,C0,1D,62,97,CE,E4,21,14,C5,9D,24,BF,EE,D7,3E,20,12,42,6C,D0,C9,C3,01,38,6D,3A,E6,C0,A2,FE,DD,CA,0A,E8,FA,01,66,3E,42,88,F8,AC,4D,8D,88,D9,08,57,65,A2,95,CE,3B,51,B3,E4,3E,64,7F,DF,B8,BF,B9,24,3A,5F,8F,77,90,C0,C7,10,C3,59,06,A2,0C,8A,B3,1A,08,79,E0,6C,BC,00,4C,6F,DE,CE,A1,A1,7C,0D,07,B2,A6,D0,CB,31,09,97,DE,B2,B2,C2,03,5D,58,AD,B3,0B,AF,30,DC,38,58,E2,96,1B,63,02,46,91,C6,A8,BF,6C,0E,6B,46,84,03,C4,ED,F4,4B,7D,27,AC,77,2D,79,1A,33,A0,E1,E8,BC,22,F4,7C,FF,FF,1D,46,3E,0A,79,41,C4,39,37,17,33,07,C8,70,BB,15,40,E0,92,F8,2D,B0,13,3B,BA,DE,6C,82,AB,87,30,A4,91,8B,F2,F8,E6,FB,8C,34,1A,E1,DE,0F,65,FF,79,6F,CF,F4,D8,89,36,0B,59,2F,89,C6,B8,0E,2A,15,21,68,CF,04,EA,BB,9F,F6,5A,01,82,89,2F,CC,95,B4,2F,F1,76,46,A4,05,F6,F6,F4,10,71,42,FC,57,3C,E3,D3,CB,43,73,A1,68,A3,95,78,00,11,53,B4,4A,CF,02,EC,71,09,71,EB,5C,5D,8C,C4,B6,1D,EA,87,8F,6F,58,80,44,37,C9,1E,94,31,0C,2F,90,8A,2E,AF,73,09,4A,85,E4,79,39,60,36,7E,E0,D9,5D,97,98,00,06,1E,B0,9F,2D,51,1E,4D,45,BB,2B,AF,A4,EE,73,91,6C,2D,B9,C6,1D,5D,7A,86,F3,30,ED,E5,6B,9E,E2,78,A0,BE,D9,3C,DB,A4,B4,F0,04,3D,EB,A5,9C,79,5F,7D,60,56,C4,A5,8C,9B,7C,C6,9E,94,13,05,2C,B6,90,80,ED,A8,FF,2A,74,6E,62,D0,A2,15,51,E1,56,02,28,8A,F2,D2,C2,71,8B,6A,E6,A6,6B,C5,DF,B3,11,88,3A,41,80,60,93,F7,E5,33,01,82,19,12,E4,A2,38,1E,F8,5F,05,52,46,E2,D3,8F,1F,27,5F,0D,05,EF,12,4C,89,8E,92,8C,FA,B5,B0,E0,EC,F6,7B,C8,AC,C6,6F,CE,9D,14,79,50,90,EB,12,89,31,34,CC,B3,13,7F,75,42,27,DA,7D,24,BB,F7,D8,C0,B4,DA,4B,D9,F6,A9,85,BD,C1,CF,60,55,CC,84,8A,62,34,9E,68,6B,A0,7D,4E,C1,12,DD,B5,49,67,6E,AD,A0,4C,FB,33,85,17,7E,26,B8,0D,6D,22,AD,45,8A,BE,EB,9D,E6,37,A8,D6,54,4D,F4,57,06,5A,D7,0A,89,6A,8D,B4,A8,15,55,F7,1A,D6,5B,CB,C6,BD,C4,A5,0B,D4,DA,9B,CD,BE,40,A7,EA,87,11,13,7B,65,AD,9D,68,11,38,70,D4,31,17,05,4C,30,CA,7C,A3,47,17,0E,42,CC,3A,8A,24,4B,77,A2,0F,6F,48,AE,D7,5E,71,34,5F,C8,00,6F,56,68,55,D3,FA,C5,6A,A8,F7,F9,65,A1,50,97,E7,45,6A,C2,6B,BE,CD,E9,EB,D3,9C,B7,55,49,0B,6B,C5,0B,DD,FD,08,29,21,EF,CB,56,E7,65,18,0D,2E,47,4F,38,EF,0A,6A,13,4A,97,28,6D,84,06,A8,6B,5C,A6,C6,F2,84,C1,98,AE,3F,CF,29,E8,28,FD,51,C0,87,94,7A,8D,19,41,94,5C,B7,A8,25,3F,A2,D3,39,7C,E5,62,D6,66,A1,A6,C3,79,2A,60,E4,DE,46,08,86,F6,F8,6D,AB,33,A0,D2,5D,A4,46,C4,0F,BB,A7,47,D1,F1,9B,13,D1,8A,6B,BE,9E,A1,A7,42,EF,4F,C7,53,63,21,FE,32,04,E0,61,49,5A,E6,BE,01,01,FB,AA,7D,58,1D,2D,3B,72,DF,BE,E6,90,4E,95,84,77,C5,3F,FF,D0,04,46,66,49,D4,3A,8A,37,B4,67,A6,13,81,EA,46,65,C6,3A,08,56,D5,25,49,1B,0F,CD,74,38,9B,0A,05,EF,74,95,35,A3,17,6F,A6,32,43,FE,C3,8F,B8,A9,CB,23,DA,29,90,BB,01,15,68,74,AE,E5,C3,0D,54,6C,07,47,58,2B,BF,2A,1E,05,E2,1B,CB,6B,B1,C0,09,A5,54,34,DA,06,CE,8E,34,8B,A5,9C,B6,0C,AB,4A,D3,85,12,56,B8,D1,D2,3E,BF,68,F0,C4,25,7E,FA,B7,A8,6D,65,56,75,F5,12,85,7C,E2,51,B0,01,F0,34,56,E7,0A,B5,D5,F8,A1,FB,7E,1B,CE,DC,0D,05,92,6E,EB,96,EE,CB,EF,14,F4,C2,DE,6F,90,19,62,E4,09,2F,6D,6E,8A,FA,86,63,14,EC,B7,90,BD,F3,23,24,90,88,FF,BF,A1,0A,1A,B4,EE,0C,94,21,75,38,CA,5F,7C,5C,10,67,A0,5F,50,73,9A,E3,7C,24,7E,FE,0C,05,77,BC,29,34,65,0D,80,A4,01,A4,3B,9B,B4,17,04,A1,E7,28,6D,9A,12,D8,86,AA,43,A0,E6,0C,2C,0D,41,D1,A2,9F,CD,3B,19,31,D8,B8,60,D3,49,24,91,5E,D2,93,DE,65,57,DD,11,AA,B8,43,0E,54,21,96,F0,E0,32,10,34,17,5C,B9,B4,41,19,1C,66,FD,6B,45,AF,EB,97,4D,AE,CA,DA,D7,7A,EA,60,BE,A3,8E,40,A7,B9,57,8C,F3,F3,F6,56,E0,02,AE,93,B8,8E,C6,3E,22,63,76,E7,61,E4,33,CE,6A,78,F9,D2,B2,06,8F,C2,D2,43,28,7C,91,66,24,26,FE,94,0C,E7,DB,88,72,22,D7,A8,75,0D,8C,1C,06,C2,34,5B,8C,5A,E8,77,36,D4,41,B5,99,A7,DD,EF,72,EB,E5,51,C8,B7,39,C1,57,73,C9,1E,9B,22,FE,CE,53,33,12,43,54,6F,C6,2B,43,24,E2,F4,11,14,C1,FA,8D,8D,A2,63,72,E2,AD,69,4A,97,1C,52,FE,4C,F0,DF,A4,3A,3E,9A,C2,4D,AA,1B,72,9F,96,15,9C,32,FB,D9,FE,BA,3C,8B,24,0F,7E,76,C7,92,42,A9,EB,31,AC,30,C4,58,EF,11,93,D0,58,30,37,19,3E,0C,28,67,1D,F7,A3,1A,0F,2B,71,69,F4,6F,9F,57,95,C2,24,D7,FE,0A,03,86,AE,31,BB,62,52,EF,29,8E,C0,83,A4,D8,A1,C4,BF,4B,D9,02,8A,EC,C8,A4,65,A3,B1,A3,F1,4D,E7,8A,5E,7A,0F,10,BD,23,78,FD,0D,D8,F6,E2,DE,66,4E,37,4A,43,56,7D,49,1F,CA,B1,D2,A1,CA,DF,58,9A,C7,EA,48,7C,43,12,11,8E,78,4C,FE,99,CA,BF,EB,75,A3,87,3B,7D,73,6D,FD,95,B3,25,F5,FB,A0,99,5B,F6,68,31,16,E0,9B,B5,AE,32,9B,54,6B,58,CE,7D,94,CA,FC,3A,39,1A,F2,0E,C8,88,FA,D3,1D,42,23,5F,D6,46,30,97,9D,E6,A3,90,CC,E3,BA,1C,2E,0A,31,AE,BB,2C,E9,CD,43,EC,45,49,2A,55,26,0B,95,3E,0B,07,31,E8,CE,18,70,AA,4E,2D,BF,BA,98,55,22,96,0B,C7,56,D0,1D,E5,58,17,C0,4F,25,6C,CC,90,8D,19,2B,CE,4A,6D,D5,78,B3,55,24,4B,B6,E1,3D,78,80,3A,F0,6C,B4,74,97,C3,78,B0,81,25,55,B5,0E,7D,C4,48,DC,2F,0F,05,5E,40,F0,9E,4B,8F,B6,3B,17,52,CA,72,06,CF,27,44,C2,B5,4F,A5,32,9E,24,0E,CF,3E,95,B5,98,44,B1,6E,AC,56,EC,67,5B,3A,39,A0,8F,E0,B7,82,D8,39,F2,00,C8,76,3E,D1,73,B6,47,41,9D,E9,CA,BA,CE,C6,44,FD,8C,FC,EF,65,D5,C0,25,13,1F,67,F3,73,44,65,3F,38,73,38,F2,99,04,8D,A1,67,AC,88,8C,C0,D5,F0,14,DB,5B,B6,B4,C8,EF,AB,97,68,BA,22,31,13,FA,CD,0D,F6,5D,2A,E6,4A,95,1F,CF,2E,B6,BC,BF,8B,D8,95,ED,8B,95,83,E6,DF,84,17,2C,D3,A5,6E,40,70,B8,EC,A7,86,B4,01,F6,B4,6B,BD,A2,2F,A0,E8,BC,3C,AA,01,85,8C,AE,65,CB,82,B5,67,C0,CF,12,B8,0B,C5,B0,88,E6,D1,A9,3D,7A,05,CD,01,B9,B4,BA,11,13,84,CF,B9,7B,E1,BC,30,FE,A9,36,B2,40,8C,14,53,36,A8,31,AF,00,3B,7D,9D,C3,D5,D9,07,1E,14,7D,03,87,2E,03,0E,B6,C0,9D,71,96,EB,37,E4,97,D9,AC,E0,A1,66,7E,AB,E2,C4,30,A0,A8,CD,6B,77,EA,3E,EA,B7,55,BC,A7,3D,D6,E1,30,93,6B,15,D5,8A,F8,D7,73,94,EF,B2,46,95,C6,FF,BC,94,15,4A,B5,9E,09,28,FF,C0,5D,43,B6,21,F7,10,FA,77,0B,9E,7B,78,59,57,98,94,3D,68,5A,16,40,5F,3D,9F,0F,E4,BC,AD,F3,0E,6B,FB,DC,DD,98,02,06,4A,DD,5A,61,09,E2,23,4F,8F,33,AD,B1,50,84,F2,70,7E,17,CE,28,D8,20,C6,71,0D,8E,B5,18,D5,50,79,65,A7,37,10,D8,65,E9,1C,D7,C0,51,C9,E9,9E,87,6B,6E,2C,2F,87,93,98,3A,98,01,DB,70,43,24,F6,96,B7,1E,60,CF,C8,8B,71,DE,9D,AA,CF,B2,86,9D,08,C3,75,E0,C0,55,A6,CD,15,92,6E,3F,F8,02,60,30,01,79,F2,D3,13,B4,AF,BD,AA,48,81,DF,32,EE,73,27,39,D6,F1,C7,B7,AF,39,2A,A2,5B,A3,D5,D9,D7,85,F5,38,7C,68,B5,75,AC,F8,AD,13,9C,B2,7D,D1,70,9A,1A,01,18,2D,71,BB,10,B5,D5,17,D5,84,BD,17,CA,5F,0F,BD,77,BD,37,1A,46,5E,C6,94,FC,28,3E,63,30,AA,FD,DF,F6,DC,98,CC,CC,86,69,ED,EA,40,A5,C3,08,D9,EE,25,02,B6,6B,26,2B,68,7F,DD,D6,AA,AA,DA,8C,57,9B,01,CB,B2,80,E4,1B,F6,AD,DC,09,4F,A7,00,F6,C7,4A,DC,8A,F3,DA,23,A4,A5,A6,A2,0C,A7,6A,E1,CA,46,05,4F,7A,8E,AE,9E,63,95,71,DD,90,E8,97,0A,96,AA,8C,41,D5,70,0B,52,5E,BB,FF,47,C7,61,E0,8B,5D,12,A4,BF,E0,37,6E,57,97,06,FB,28,80,CD,30,CD,92,BA,80,E9,41,7D,57,9B,AC,32,C2,EF,16,D1,E2,23,27,9D,28,4A,50,E6,1F,55,6F,FA,6F,8A,A3,D1,19,F6,8B,63,DD,6D,15,00,C7,86,9D,2B,10,60,23,D7,B8,38,B7,8F,D3,EE,55,6C,40,07,AF,40,02,5F,5A,71,B3,5F,83,D7,0E,8A,BF,1F,C2,A9,9C,F4,BA,99,44,FB,33,E9,26,56,77,67,1E,F2,EC,F8,A8,C0,32,9D,EB,B7,61,EE,45,16,14,69,4F,36,86,7C,F1,1E,23,5E,D4,A3,3E,9E,37,3C,93,73,32,FF,ED,BD,7F,EC,4A,33,E9,1A,DC,AA,EF,40,8E,23,26,44,16,EE,34,8D,50,F3,C7,D3,70,FB,AA,A9,B1,FF,F7,EC,52,A5,38,22,1E,22,C1,F5,B6,59,66,38,A8,44,1B,35,BE,30,A4,D1,74,80,39,59,9E,7B,EE,FC,FD,8E,74,80,6B,8B,F5,7F,3F,B2,2B,8D,8C,F7,73,03,84,66,8E,4D,4A,64,50,79,7D,C0,87,1E,C6,DC,FA,27,6A,8D,A0,DB,8E,7F,26,A4,6C,00,1B,16,B4,22,21,3E,EC,FF,63,B7,C2,36,17,40,6D,C5,84,CA,94,10,F9,C0,60,79,3E,33,63,99,C0,87,C0,A1,BD,7B,62,F9,40,F8,35,36,82,A3,0E,EA,09,65,32,5D,55,97,9C,76,08,68,2F,62,DF,24,14,B6,1F,29,4F,DF,B2,7D,1A,96,AC,E7,68,BB,24,F0,61,23,98,E0,07,A0,5D,4F,F0,F4,99,04,36,54,2E,30,7A,6B,DF,E0,8A,A4,F2,41,1E,B2,02,04,F0,D9,99,DE,B8,06,60,9F,A6,E2,66,31,C7,E5,33,21,4D,FE,0E,DA,A8,C1,5E,9A,45,BB,2B,58,89,B3,DD,0D,33,0D,9B,39,2A,E8,DB,50,97,FF,43,DD,EC,63,02,9C,F2,9B,74,C8,9C,8F,17,AF,E6,07,A7,50,1B,C5,DF,EC,D0,5F,99,75,05,4C,BA,6E,41,B9,F7,EA,D1,86,E7,14,48,9F,F9,5B,F2,36,CB,65,E9,D4,7B,F8,67,F0,1F,7B,1C,7F,4C,A5,4C,8E,00,06,96,58,D0,2C,89,32,5B,0C,B8,00,40,89,95,F9,23,F1,C1,81,DC,52,1E,2D,7F,95,BB,7E,7D,A4,04,A7,CD,89,7F,D6,76,E1,AE,CF,FA,AC,04,29,FC,CC,AB,91,BB,E8,E5,77,31,E9,D7,C6,C2,4E,95,2A,CB,79,A3,18,04,B7,65,0B,1B,34,66,91,27,C0,CD,11,D1,2E,34,67,DE,8B,2E,2B,63,21,0D,76,02,76,46,E5,9A,76,FE,BF,30,00,0E,C3,3E,CE,19,17,6B,AA,BE,14,5E,80,1D,35,AF,8C,BD,52,AB,14,52,39,86,1C,5D,57,3D,5D,9F,59,9D,E5,8D,C1,4E,8F,4B,50,15,27,B2,EF,4D,98,7B,03,E2,4F,EC,80,94,8F,8E,3B,03,13,B9,D3,5E,B1,BE,49,BC,F4,17,D0,D9,BB,4C,C5,50,1E,07,B6,72,B8,FB,A9,01,3D,66,68,EB,A4,86,E6,52,09,D4,60,90,B6,A7,7F,C8,70,A2,89,F6,3F,9D,FD,19,A9,F8,88,4C,80,51,47,AB,D3,FF,3D,EC,45,15,B1,52,0D,F6,41,A5,CD,90,08,71,4E,60,F1,84,4C,4C,2C,77,38,1A,19,B6,04,52,2B,B9,4F,F4,53,A4,4C,CF,B1,1A,F6,A4,41,3E,C1,DB,07,5C,63,4B,E4,05,FB,18,4C,9B,46,B4,9C,FE,67,AD,92,D7,54,CE,3A,F0,E5,78,E6,57,5C,2F,1E,76,94,99,F0,A2,0E,2F,EB,9C,79,5A,1A,E8,60,40,45,64,DF,26,25,62,5F,BB,30,41,13,30,D0,70,1F,CC,04,AC,72,EC,74,F4,FF,C4,A9,56,8D,4C,B5,24,E5,58,A6,A3,54,0B,0A,47,94,2C,A3,9E,45,DD,51,35,DF,D7,91,0D,5B,8B,F3,98,BB,3F,21,F9,51,B8,2F,4C,6E,E6,49,38,16,A9,11,FF,25,45,25,37,FD,32,C2,59,10,8E,BE,BB,60,39,F1,5F,24,4B,A3,49,62,ED,B2,A0,01,BB,25,05,F7,81,0F,10,79,C1,97,67,A8,67,B7,D1,3D,AE,4B,71,C2,B5,03,73,88,14,8D,AB,1D,5C,82,05,F7,01,B4,3D,C1,66,F1,1D,54,19,C6,58,1C,59,AC,98,F0,33,9F,A1,FE,15,61,8B,17,6C,93,60,70,F3,81,87,E1,C3,A1,41,83,BC,5E,92,4D,7A,07,DA,83,AB,92,28,44,0C,AC,5E,68,F8,6F,7D,6D,16,34,38,4D,2A,D7,2F,C7,EA,4C,57,20,A5,6F,F5,96,69,CB,DA,FC,28,6B,B6,38,29,A9,DE,D6,C7,08,F7,90,59,C4,2C,08,9A,81,F1,18,89,2E,F0,C9,97,C5,D3,5E,D4,2B,AC,BB,1D,BA,38,27,4B,EC,25,2C,65,41,23,71,93,93,0D,58,A6,FE,63,FD,1C,73,00,9F,9B,2C,9D,47,2B,FD,14,1D,58,E9,C5,51,22,09,1B,26,FE,6E,A8,D1,6F,61,6C,58,F0,E0,9F,83,E2,CA,4F,00,95,B1,4D,0A,B2,0D,7F,BD,FE,BF,FE,43,5E,05,D9,6D,36,4F,8B,DF,88,D4,FF,6B,B2,C3,AB,C8,07,20,19,07,9F,04,92,37,72,85,DD,00,74,0E,A7,AC,93,A0,72,A3,3C,83,1F,14,CF,B9,9C,3A,84,EB,2D,E8,3D,EA,AB,B7,32,CF,40,89,FF,A8,D5,5A,C8,0F,6C,03,0C,BD,B3,E9,D0,36,6F,1A,31,F8,52,78,4F,A6,88,88,D3,50,8A,EC,C9,9F,D2,46,F6,57,2A,A1,B0,5A,AC,33,39,63,D8,3E,17,89,82,08,49,9E,F4,F8,36,37,5C,38,B7,50,E6,5B,C3,48,9B,83,AD,71,7B,F5,1B,C5,E4,BC,D5,C3,A4,B6,64,05,C7,B5,44,4F,C2,D9,5C,64,09,67,A8,21,5B,CC,B8,D7,6A,AB,20,33,F5,92,4B,AB,C1,5A,B5,4F,11,EF,5B,D8,3C,F3,74,D7,EA,98,AB,B7,CA,02,CE,1B,F5,91,90,39,E8,89,43,50,85,5B,D9,08,F7,4F,3B,4A,8E,61,30,09,F5,27,E8,27,6D,61,65,54,0E,31,CC,B4,34,44,2F,E1,DB,8E,B6,25,F4,6E,E5,BA,30,0C,F3,B0,2F,1C,65,12,A3,2D,3D,2D,EC,91,98,96,A1,1A,F7,9F,31,4B,60,10,43,CF,3A,B2,88,13,6A,23,38,BF,CE,53,FE,7F,AA,AF,FB,DD,32,C0,99,53,88,59,DD,6E,E9,E4,F3,42,78,94,B1,7A,9E,67,0E,4F,DC,75,3B,07,B3,E7,8F,7F,B1,B9,AB,5D,48,89,ED,10,15,EB,75,35,68,33,A4,76,57,91,91,2E,A6,A8,4F,0D,FF,6A,84,F5,BC,0B,D5,93,DF,60,2D,77,80,37,EF,71,2C,4D,0D,38,91,28,22,70,A2,81,95,2B,9A,4E,AE,F3,FA,E9,81,44,72,09,B4,DA,63,12,50,BA,B9,6B,48,2C,AC,49,0A,89,A5,CB,FE,DF,6F,01,4F,C6,F3,C4,30,5B,80,CA,F8,E9,AF,71,B6,A9,6A,3B,89,D9,35,BF,F4,BD,21,D5,4E,DE,C6,6F,40,00,15,B5,41,79,5B,58,80,E9,F0,70,05,99,26,61,54,3A,69,0B,3C,75,17,26,0A,F2,13,7C,7F,9B,CC,75,40,67,01,7E,45,D0,17,DF,B1,27,3C,65,8B,F1,DE,10,5D,47,25,EC,C0,5E,65,42,E2,4A,35,59,0B,25,75,00,F5,3F,54,50,68,59,E0,4E,AF,53,4F,47,E5,47,53,C8,18,74,DF,8A,15,29,DB,61,0A,82,A7,E9,D1,BA,E8,9B,57,F9,BF,BC,65,90,59,89,7F,00,EB,25,F3,97,8B,C4,F0,96,0C,0C,72,78,42,4C,67,24,4E,30,BA,39,57,7A,6B,EC,F5,0E,2C,8F,4A,52,E3,BD,BE,B0,E8,A0,48,1C,05,85,60,0D,BC,82,FF,C2,FB,AA,90,48,21,90,B7,02,35,94,8A,6F,E8,F7,F5,08,8C,0F,3C,8B,77,02,C5,8F,10,64,87,E8,9B,D8,CD,D3,83,58,84,30,09,A6,C1,79,79,17,B9,76,10,F6,22,4A,10,49,47,FF,E8,8C,87,0F,C0,10,FA,8D,E1,22,F0,DA,EE,FD,B4,7B,89,F3,03,C0,6A,D3,38,77,2A,E5,74,C0,CA,00,74,58,6C,AE,24,B0,77,47,FE,EC,FB,90,04,CA,54,BE,78,FA,64,07,1F,62,50,85,56,59,DB,D2,CF,E9,23,42,68,86,7B,28,01,70,0D,CE,2C,13,70,AD,96,CC,42,3B,D5,E3,33,A6,A5,83,D4,B5,EB,30,58,18,91,1C,2A,EC,74,73,BA,00,35,1C,69,41,61,F4,39,7C,95,46,30,D0,EC,25,9E,DE,D8,D3,2B,8E,6D,8F,A0,A0,CE,8A,1C,63,01,E1,44,03,8D,A6,46,F0,D0,90,C2,AB,16,C8,B8,7F,33,F9,C0,E8,BC,46,35,F6,32,0B,EB,72,DD,84,E4,D2,C1,0D,B3,0F,84,C3,8A,D3,E9,CB,B7,07,58,93,4C,B7,DA,B6,B7,A2,6F,05,EB,DE,94,0E,1B,B9,59,F4,A0,27,BE,90,CA,31,D7,76,6D,1B,3C,18,1A,7C,40,CB,34,45,9C,E9,54,51,63,AC,59,AC,54,81,71,E6,19,16,12,8A,86,C8,25,7A,7A,A6,B5,17,86,A5,35,B5,52,63,2B,16,8F,54,4F,17,5A,9F,E2,85,5D,86,38,A1,DC,C6,AE,D8,10,1B,6F,CF,4D,6C,85,BC,61,22,85,80,4F,72,DE,10,0A,50,7E,ED,9C,A5,42,C0,2A,FA,4C,EF,7F,C1,E0,2E,86,9C,D1,7D,3C,B4,13,94,76,50,A6,B7,8D,CD,0A,96,79,96,14,EB,B6,9D,37,31,98,16,66,9A,B5,FA,02,9A,1A,BE,B8,66,42,59,37,82,63,7D,06,44,3B,8C,9C,87,0F,06,C7,85,D2,9E,9B,56,D7,65,2F,D7,D1,8B,7F,29,05,5C,C7,0E,DA,B3,DF,AB,49,D3,66,DA,26,FF,EC,F0,E0,CA,33,42,5F,78,24,0B,6C,A8,64,7F,7F,0E,5A,2B,4A,AC,DA,9D,75,C2,73,0E,B1,7F,34,DC,45,D0,00,76,94,C1,CB,CA,47,38,C1,CC,A0,4E,08,9A,EC,4F,4F,14,F8,19,34,99,48,18,DC,21,E7,9B,67,8C,B1,24,63,78,2A,17,F6,8D,D7,8B,26,6E,B4,82,54,72,69,CC,D7,BC,2E,60,59,EA,69,11,DA,FB,09,79,43,45,C5,84,42,63,78,0B,B2,81,58,D1,80,82,E4,DE,30,97,B1,FB,D6,5D,8D,EA,5A,09,C4,B9,DE,16,BA,45,9B,CB,2C,64,C5,8C,E3,75,9B,C9,88,2A,6F,BE,BE,2A,53,1A,69,1B,D5,F2,3C,70,9B,48,35,4C,E1,F4,8D,E8,7D,BB,EB,C6,E2,CB,27,C8,CD,A2,35,42,9A,B2,DC,0A,ED,68,97,65,35,53,03,32,6D,E9,6F,A6,20,4E,C4,96,FD,A0,CF,B0,83,E5,1A,2A,5A,E8,43,B0,41,64,29,76,9C,6C,09,A2,76,E7,91,2B,5D,35,15,7B,37,0D,50,86,A2,DB,D7,98,1A,5D,CA,D7,DD,62,23,6B,FF,0F,A4,D2,82,62,5B,F7,87,6D,EA,77,DB,AF,3C,71,08,28,16,04,02,AC,68,11,95,B9,EE,D4,C4,71,C6,7C,4A,F1,68,F5,2D,DB,68,2F,AD,EA,51,67,95,B6,58,82,E5,D0,7E,DD,F6,83,C5,47,6E,39,47,05,01,CB,40,26,D4,CC,52,09,D2,5A,27,C8,58,DB,3A,B1,E9,B9,3C,F8,95,83,9A,D5,86,EB,D6,FA,5B,5B,F8,8A,D6,30,F6,0D,41,22,9C,59,C6,EC,6C,D1,AE,EA,F6,B4,72,67,6C,A1,11,1F,44,55,65,1C,89,40,81,FF,52,0D,4B,DC,7C,A3,EF,9F,F1,7C,85,3D,8C,8D,9D,08,06,8F,53,7D,0B,41,3C,68,86,9C,00,F3,1E,A2,4B,47,A1,A3,2C,12,95,D9,4C,33,4E,AF,20,08,A2,99,11,C4,61,7D,DF,02,E7,67,07,1D,5D,C9,F1,94,93,1A,DA,54,FF,30,BE,6A,BA,5F,D9,D6,2E,DD,54,AD,EB,D2,7B,75,6C,00,B7,D1,9E,E3,E5,51,40,BF,E5,A0,6D,94,2D,8B,9D,2F,46,02,5A,6E,4B,45,21,86,80,E5,3B,67,CA,9C,C5,AE,C7,61,EE,A2,C5,88,10,49,3A,1E,FB,12,4B,6C,A4,CC,EC,7B,51,EB,1E,18,50,52,57,64,0F,6D,E3,56,69,56,47,3D,03,7C,F2,86,70,75,77,A5,C8,D2,8C,06,9A,18,56,36,B4,57,33,B1,21,F0,19,AC,72,F0,84,95,A2,BA,0D,37,BF,20,5A,AB,26,97,4D,F6,A3,3A,EB,89,BE,4B,70,90,41,1E,B3,FC,CA,67,37,18,7E,9F,02,7D,DA,65,A1,14,13,50,30,50,FC,FC,73,04,7F,EC,0F,3B,DC,7D,9F,D3,39,D8,57,E3,A5,73,64,B8,BE,37,51,28,BD,B2,28,02,65,F7,C7,52,01,EE,CB,B5,82,7E,83,1D,99,2F,2B,72,98,B1,D7,35,7E,34,5C,22,B5,78,AF,57,88,0E,7B,4D,50,EE,1C,B9,C4,B7,9A,D1,2F,FF,5C,09,27,92,7A,F7,C4,9C,6F,A1,14,4D,4A,AE,F5,9B,D2,2C,3C,B8,29,FB,F6,41,9C,E2,B5,0A,FA,39,F4,E8,33,A6,8D,8A,4A,3C,9A,73,34,35,51,B8,02,6A,03,D7,2F,ED,A1,F5,AE,BE,5F,82,F2,A6,C4,76,1F,2E,9E,16,14,04,6E,23,85,B7,69,94,CE,9C,33,CF,0E,2C,2B,C6,EF,AF,27,82,C4,92,A8,31,CB,18,87,14,6A,D1,D5,17,D5,37,F6,8D,C2,F1,C6,54,1F,A4,7A,CF,26,87,03,00,52,78,2A,80,49,3C,91,FF,27,10,2D,6F,25,0C,37,16,0A,24,60,70,90,C4,1A,CB,05,BB,C3,96,BD,29,53,B4,4D,B5,F1,D3,51,9B,A8,00,4B,BE,86,9F,3C,F8,0A,F9,8D,76,E8,FB,62,92,26,D4,05,B8,F8,FE,F3,78,FA,4A,8D,C4,3D,A6,21,85,F1,E9,C5,BE,68,C9,0E,28,6B,73,26,39,C5,16,7D,56,BC,19,FA,4D,EC,78,90,9D,C8,5E,C0,30,C5,EF,32,15,13,DA,C8,C7,B4,4F,49,81,1E,61,B3,65,60,DC,6D,5D,B3,B0,33,05,A4,A7,DB,9B,F0,05,17,2D,9A,3B,0D,55,64,D4,71,A1,CE,35,73,1C,46,BF,85,18,35,64,F2,E2,03,36,64,DE,6C,DB,2B,14,A9,BA,2C,9F,D1,21,C9,2A,55,86,20,43,D7,58,90,53,5D,17,FF,80,80,FC,A2,40,77,47,57,B4,71,12,62,2C,90,C8,BE,EF,87,AA,FF,E5,0D,09,4A,98,8D,D2,FE,03,ED,94,EE,37,B2,43,84,46,6A,49,2E,D3,C8,81,95,56,31,36,45,7E,A9,84,80,19,92,94,8F,73,02,87,82,09,16,82,86,19,AD,0F,15,66,0F,1F,F9,3C,11,38,5C,F9,AA,6B,1D,96,1E,1B,4A,D3,79,16,49,41,69,5E,19,0A,C3,6C,13,C1,50,04,32,95,33,86,F2,A7,D6,49,45,66,D3,AA,81,91,97,2F,D5,EE,6E,CB,0A,56,AF,91,D3,48,D4,4D,0D,3E,9A,94,B6,61,3E,60,4C,E5,8E,07,46,59,F6,C8,3F,73,56,C4,C2,93,86,97,A9,24,2B,F1,B2,DA,28,03,78,A0,0D,F2,EE,8B,5C,A0,08,B5,85,8E,66,3B,8D,40,0A,D3,5F,9C,2E,47,7D,4D,9A,8C,49,24,89,18,85,A0,40,D7,BD,BD,DF,D9,D2,54,18,BD,D2,A7,14,C4,A0,B4,40,87,E2,38,72,A0,CB,BE,69,4B,2A,93,A5,3B,3A,6E,DE,96,2B,EE,BF,C0,CB,2F,37,AB,07,46,5F,11,25,6D,9D,5E,D3,6E,71,2B,01,20,3C,29,6E,5F,36,C7,59,49,36,24,1F,CC,96,2A,56,D1,F5,20,FC,10,F1,14,AB,80,6E,DF,92,E4,E2,CF,05,F8,D8,59,15,B8,A5,AA,42,3E,DB,B3,E3,79,DC,A2,7C,7F,2E,5F,18,60,43,3E,A4,95,8C,7D,DD,4A,0E,77,EA,FB,D3,83,B1,2E,F4,25,FF,5B,76,D6,6B,82,AF,80,71,DF,2F,9E,22,5C,04,1B,19,BE,FC,C1,C2,CE,22,B9,0C,4A,43,8E,48,C5,CA,7B,B7,05,8D,0B,85,78,FF,83,CF,29,E2,77,34,B1,E2,F3,14,29,1A,E0,F8,D7,5E,FF,0C,38,45,85,CD,CF,02,91,8A,4D,A4,B5,56,7C,78,97,4D,A9,BE,A5,B5,AD,D4,6A,5C,F0,4B,21,A0,5A,01,53,25,04,7B,14,39,61,03,82,F7,DD,EB,EC,8C,63,88,2F,B9,ED,65,F0,95,6E,E2,D3,61,E1,FC,19,E7,DB,13,0C,99,8A,8D,EF,6A,D7,D1,F5,3D,C6,06,5E,7E,E4,27,C0,C6,3B,61,F8,9B,CC,27,0F,1D,E5,D4,1D,0B,35,FF,A9,16,65,6B,14,59,97,C8,29,67,EF,E2,18,A8,9D,41,BC,1C,C8,F9,46,DA,DC,BF,93,3C,0E,E7,4B,12,A9,78,88,D6,2B,35,68,5A,BB,D0,57,00,16,19,C6,9E,F3,FB,86,EE,52,72,09,01,03,77,D7,87,46,48,8C,8E,0B,E4,70,50,BE,48,D1,D3,F0,19,83,65,1C,59,29,11,CB,D9,89,5A,DF,8B,76,9F,A0,FA,8B,0A,FC,0D,73,35,52,06,44,EE,07,11,B6,6C,E5,B5,6B,FA,2B,23,8A,DB,46,3A,0C,9B,81,A7,F7,D4,F3,5F,CD,04,72,3F,74,8B,0D,23,56,39,3E,4C,3D,1F,18,06,01,65,BC,69,B1,DC,88,A4,E4,88,E2,A0,5A,6B,31,D2,DB,7F,40,6B,61,7F,CC,00,BE,FC,92,9C,83,DD,6F,1E,B3,B3,C8,1B,9E,53,3A,70,AA,5A,55,C2,61,F8,88,F6,DF,14,36,37,22,EE,3A,2D,19,74,D4,78,0B,14,0A,DF,3A,D4,B7,82,D8,9A,C3,9D,2F,81,E0,DA,CF,6A,DF,4E,05,3A,E3,D1,B4,3E,14,C8,E8,F1,8E,29,71,21,C2,40,FE,0B,63,09,98,C9,2C,8D,65,BA,04,F0,D0,58,64,5B,CF,27,4F,88,F5,32,CA,EF,30,71,DD,C4,3B,33,6A,19,75,41,B1,32,96,6D,70,5D,02,63,00,86,D6,D9,48,10,1A,FB,D0,73,B2,F7,FC,D9,D6,26,24,83,80,0A,A7,7C,CA,3F,5E,85,44,F6,B1,A4,71,EC,22,49,84,7D,3A,BB,71,AF,D4,FD,28,58,00,5C,70,36,AF,76,7A,25,B4,E1,90,D8,95,DA,FE,CE,C7,16,3A,18,B7,A7,08,E6,BD,73,3C,A1,F5,55,37,BC,14,48,7A,CC,72,A9,67,9C,25,5C,50,88,C1,34,74,5A,E0,7C,DD,2E,48,57,B3,17,BB,B1,DB,0B,FC,61,D1,47,39,EE,05,D7,75,49,28,6D,91,3A,03,D4,DE,92,CF,E7,18,B6,DD,03,44,21,8D,C7,AF,EE,AB,8E,A8,9A,B7,D4,90,34,77,94,16,27,D7,7E,EA,EE,2C,A3,C7,0F,AD,80,4B,D6,33,DA,13,12,1C,A8,18,10,70,7B,90,0D,86,95,9C,47,05,D1,A7,17,96,39,FE,03,B3,C2,81,98,10,DA,94,71,2D,78,57,38,E9,C1,B5,7A,5E,BF,8D,EA,AF,6A,5F,0A,CD,E3,74,15,74,64,7A,63,DF,40,1F,14,79,6A,80,73,68,D7,99,EB,DF,7F,33,86,E4,DF,EE,BC,1C,32,6D,9E,46,98,9A,46,BE,B0,63,6E,3C,62,F9,54,FA,E6,C9,DD,93,D1,83,49,04,E1,9C,B0,55,1A,A1,40,65,A5,4D,8E,BE,73,62,B1,E4,72,34,68,C7,7F,A9,53,B0,9D,7E,8C,F3,2A,28,B7,4D,D1,7C,40,36,A9,F1,CB,96,35,6A,EC,E8,A5,F3,9D,6D,90,1F,F6,F9,AE,3E,B6,C8,C7,BB,4B,02,F0,06,1D,DF,FE,60,AD,C3,63,19,F9,B7,41,D5,75,3B,AE,60,ED,0E,0D,41,F3,C2,C2,8D,43,46,B3,5A,C3,8E,67,33,D6,C1,74,82,FD,27,40,19,47,C2,04,75,84,C8,8A,ED,77,A1,9D,06,2D,FF,D0,99,AD,31,D9,54,24,49,8C,8C,81,9D,CA,CE,BF,17,53,E3,1D,42,AB,71,97,44,9B,01,75,64,77,E1,EA,C4,1C,E3,00,2B,96,AD,6E,34,C5,2D,99,9B,D4,AA,C7,7F,E4,B3,79,0A,B6,7B,EA,D0,64,11,B0,78,6D,81,F6,C0,A4,A8,78,A8,F0,1A,2B,EE,EA,53,8B,AB,04,41,34,39,03,92,94,E5,68,2F,44,2B,D9,E0,EF,10,89,29,79,B8,58,0E,DB,F0,49,2B,E0,DF,45,AF,DF,83,B5,54,2B,D6,AC,79,1F,4E,FD,A2,2D,4B,B5,98,F2,C1,33,62,CC,E6,63,93,87,3B,48,38,89,64,34,A8,60,FB,E8,57,03,2B,E7,63,27,90,CE,19,9F,BF,9D,5A,33,39,2C,EA,83,3F,33,DE,63,1B,3A,12,97,94,7D,3D,23,8E,60,B5,9C,01,2A,21,50,0E,F3,FE,5B,2D,53,49,97,6E,75,96,91,67,51,E5,09,A7,02,A4,FF,21,B8,BC,75,47,90,3A,48,BA,11,66,08,8E,F1,BD,21,9E,38,15,56,64,01,F5,84,90,27,0C,20,9E,32,B7,8C,9A,E3,E5,F1,42,9A,0E,04,9B,A0,2E,B9,5C,29,17,39,5A,43,B4,E8,A6,E8,BE,A9,34,8B,E2,0D,23,50,F0,84,EB,1E,98,06,88,71,D4,37,B8,35,0D,89,75,FB,41,17,32,BC,67,30,05,56,95,AB,44,5C,EB,E3,3B,40,34,4F,73,1E,C3,79,0E,17,BD,F4,C8,44,CE,A0,20,F4,FD,BC,8A,F2,6C,D6,52,D3,DC,69,98,0D,05,1D,3B,C9,55,B1,4B,8C,83,A4,67,1F,05,EA,3C,42,FE,A2,1E,EE,BC,76,CF,82,A4,4D,39,F2,5E,40,21,8F,19,1F,AA,BB,38,BF,92,11,8B,CA,1C,24,7C,63,E3,2C,D4,EC,C9,6E,55,C6,70,CA,0E,F9,EF,36,E2,CB,37,AE,CA,A9,0A,95,26,C4,5E,DB,4B,BB,F2,A4,29,5B,E9,47,9F,3C,88,21,28,E8,A4,56,61,29,02,EE,14,DB,A3,67,FA,52,47,06,12,F2,AF,82,56,98,A2,0A,60,C2,82,21,45,45,31,0F,E9,F2,C2,84,AE,BA,E3,7F,7C,1C,D6,BE,EA,72,EF,EF,21,39,6A,28,56,5A,FD,DB,0B,A4,D6,F5,21,92,D8,E4,74,12,71,D7,69,80,6A,E7,BF,AF,7C,A2,96,F5,8A,4C,17,03,21,89,A1,06,A7,DD,B2,8F,6B,F9,01,9B,51,FE,70,C3,94,72,AD,42,33,DA,CA,60,84,65,2E,C4,D8,8D,77,F6,B0,0A,B6,90,03,10,E9,AE,49,54,AA,9A,67,86,55,E4,CD,85,7C,74,DC,70,64,15,13,01,DB,3B,A7,25,AE,BC,68,64,35,16,5E,E0,F3,0B,63,36,24,C9,5F,CF,79,66,C4,4E,87,C6,59,C6,19,2B,52,B4,B9,99,B1,EC,01,14,09,06,5F,54,ED,4F,24,8F,AC,45,3A,94,58,77,C1,B3,47,AA,16,71,B3,24,1E,25,E8,73,7C,F0,92,BC,C7,DD,15,77,D3,FD,B8,B2,A9,5D,D6,E8,BB,3A,DE,17,46,0D,DB,F6,3A,0A,0A,45,9B,8E,61,1D,26,63,C1,9B,66,9A,B6,B9,15,A4,16,74,AC,67,A0,DF,14,89,30,FB,FC,77,B8,94,70,0F,9D,9F,B4,E1,60,C5,EE,30,C6,1B,AC,D1,76,6D,5C,F4,40,FD,8E,B5,42,33,F0,F5,6B,8F,10,9B,22,22,EF,BA,90,8B,B9,1D,E5,B5,88,03,BC,18,69,44,20,82,7C,54,5A,67,DA,19,02,77,7A,D3,9E,81,73,9C,CC,03,AA,72,A6,94,EA,1A,72,17,08,88,75,5B,45,30,68,C8,76,84,98,A7,06,27,DB,6E,CB,E8,EB,1E,F4,DB,DA,4F,98,5D,9C,85,6C,54,3A,96,96,03,EF,B2,EA,D8,87,B8,7F,53,4A,A5,53,9B,08,33,9C,E7,DF,2A,0A,BF,E9,4D,91,1F,48,10,87,B0,3D,AC,A2,2C,1C,1F,86,C5,3D,B9,76,05,BE,0E,8D,1C,98,5E,42,8F,88,CB,5E,48,C9,DA,F8,9B,D3,AA,C7,11,74,CE,DA,E6,3D,C6,35,E6,FB,03,C6,FF,17,4A,41,15,E2,6A,24,AE,D5,4A,A7,84,0F,61,45,D2,A3,37,DB,ED,D2,82,F7,FC,4A,6E,BF,09,90,B4,6A,6D,65,A6,C7,3E,78,4B,40,89,B9,CB,FF,23,27,E9,E4,1F,17,4C,73,0B,63,63,C1,A6,4A,A1,F1,CD,8E,17,0A,44,23,69,46,23,25,44,58,21,D5,AF,89,C1,AD,19,DB,7F,F5,D4,83,48,A0,41,F4,34,11,A7,D7,18,98,AD,D7,AE,5B,84,FC,D2,E2,1F,F1,F7,CD,1F,EB,D4,11,F6,8D,48,B3,B9,EF,61,F9,5D,2E,C8,07,40,44,D8,9E,41,0E,87,8F,22,74,D2,C4,41,AB,FB,BD,57,4A,0B,61,8B,C7,16,FF,E0,CA,7E,3E,6E,8D,67,10,3E,B1,03,82,96,CD,B3,30,9D,E4,88,DD,F7,94,31,48,3E,81,E5,C9,AD,10,AD,26,2B,AD,19,17,B2,4B,61,2E,C5,43,9C,48,6F,03,16,E8,57,E4,EC,4E,1E,23,1F,CB,A3,12,89,67,95,AA,F4,E3,83,84,41,55,F2,B6,0B,13,83,58,C4,53,24,F6,EE,16,D6,7F,08,4C,7E,11,A9,EA,77,FE,81,73,21,B7,89,E0,F1,66,21,2C,51,0E,4C,9B,2C,7B,94,21,B8,81,8C,F1,A2,8B,74,AF,66,F5,45,C1,C5,3D,90,5C,D8,B6,43,0A,E7,5C,C2,E1,07,55,27,10,C5,6A,E4,95,52,DA,BA,DD,9F,2C,1C,82,8F,0E,C0,24,B2,32,D8,5E,54,B7,8A,1A,FB,1C,21,4D,44,90,70,36,22,B8,61,96,19,4E,C1,92,57,E3,5B,C1,09,9F,23,31,B6,EA,2F,77,63,FA,B1,4F,FC,A1,F1,DF,E1,A1,A5,2C,DA,C3,E5,8B,CF,B9,DA,E4,4E,D5,D5,10,98,C1,7C,87,81,9B,38,DC,73,90,29,CF,B7,A9,85,C8,99,A0,9F,1D,35,98,07,73,70,41,1A,C7,6F,D2,F4,C5,5B,74,0E,A7,71,E8,B0,76,0D,B4,85,A7,36,3E,F0,30,15,DA,40,FD,65,E1,DA,91,1A,3B,59,92,A8,61,6F,6B,AE,A8,86,18,82,23,3F,11,67,24,A8,08,52,8B,5C,04,7A,19,44,55,25,B6,79,36,31,5F,F7,FD,FC,82,7F,FE,CC,70,30,67,DE,D3,44,32,09,D9,F9,0D,F4,F9,2D,BA,A3,77,57,BD,31,AD,F3,77,9C,16,E3,55,79,15,6D,F4,B3,7E,C3,20,BF,11,19,59,72,41,24,0F,B9,09,09,27,A7,B1,FA,FE,3A,23,67,D4,F8,CA,FC,56,84,75,4D,AB,56,7D,55,AF,A0,D4,BC,3C,37,8A,FD,D4,03,4E,7C,36,38,8E,82,47,85,10,71,5F,25,EF,E5,30,A5,92,85,A9,1B,F6,35,EC,C3,94,16,FB,24,07,E2,AF,79,F2,B7,CE,48,47,82,D1,E7,4C,91,0E,CA,9F,21,5B,C8,D2,23,7A,44,B4,EF,46,5B,79,24,C1,66,2E,75,E0,8A,56,B2,02,79,BB,A3,32,1F,83,C0,F0,34,CC,D6,FF,F4,EC,AE,CC,0F,DC,EB,B2,9C,2F,9A,21,7F,09,97,C0,37,A4,83,6E,DE,EE,BE,01,52,58,76,18,78,07,37,D3,C5,CC,36,B9,DA,56,99,0E,7D,EC,95,AD,79,45,A7,E2,42,4B,59,E1,82,0A,1D,28,92,DE,FD,10,03,44,42,06,77,39,62,94,69,EE,02,BA,7C,81,6F,8A,59,D7,9B,17,95,2D,EE,DF,5A,03,C3,B9,77,28,45,B5,AD,83,B2,DF,65,03,68,8C,5A,AD,AE,3C,24,9E,18,DC,74,06,2B,78,4A,BF,64,45,81,48,0B,05,00,23,A6,4A,BC,F0,6C,90,63,0D,26,90,29,79,62,29,05,0E,03,C2,80,B6,A0,BE,62,DF,C9,DF,4F,B3,2F,E7,7C,26,B0,9A,3E,09,EF,7D,56,2F,51,FC,23,C8,A3,51,9F,F7,2D,36,4B,BC,1C,58,41,5C,46,3A,FB,F6,02,BC,69,4F,E9,6D,AF,2C,EB,9A,14,52,76,40,87,9B,D7,0A,07,99,B7,3D,5F,E3,BF,CE,3A,FC,30,B4,83,EC,DC,FB,80,E3,E0,96,49,6D,7A,73,DE,03,9A,83,DA,6F,C2,40,5E,31,98,29,1B,E9,E4,27,66,39,F8,04,A8,E0,62,22,49,4A,95,2D,4D,E0,95,BF,79,2E,C1,28,27,AF,69,1E,78,8E,6E,57,A3,C6,F4,BD,A0,90,AA,B6,3F,23,A0,FB,73,78,FD,2E,85,B0,A1,E1,65,7E,4E,DA,1E,7D,FF,DC,55,4A,DF,7B,D9,0F,29,B6,2B,5F,7B,AC,3C,15,4D,67,ED,6A,26,97,0E,E2,C9,89,8F,98,C2,F8,94,39,25,62,8F,9E,39,F6,B1,00,C9,D4,13,FE,4E,C5,00,C5,A7,A2,8B,B0,CA,A0,09,64,FF,A3,4B,FC,52,3B,B4,CB,F3,DC,CE,CB,06,96,2A,37,74,98,53,CD,60,99,6D,78,D1,C2,84,81,B0,A9,26,14,F9,8B,B7,8C,E5,C6,40,BD,BE,95,62,67,28,32,BE,CC,93,C9,59,CF,AA,78,12,6E,47,7D,BC,0C,17,A6,D0,6F,16,61,E1,AB,D1,9F,FF,D8,02,8F,10,82,7A,E7,E0,97,28,F1,4C,CD,DD,50,8D,89,7F,33,A1,1B,DD,90,93,72,F1,A6,D8,D3,0D,20,7E,DD,E8,A4,BF,3E,88,D7,4A,65,2D,F7,AC,8E,D8,52,3D,67,CE,A4,25,57,7A,7D,09,68,DB,B6,B7,35,44,B9,19,00,8E,A8,1E,DA,EA,D7,9E,25,02,6E,DF,67,9C,C1,97,00,EA,31,4D,A1,58,F9,A4,0E,86,32,54,93,84,87,9B,74,2B,59,91,85,93,B3,1C,68,E0,1D,87,9D,4C,1C,F2,3F,D0,6B,F0,D3,8F,4C,52,39,73,76,F2,D8,0D,6E,7E,11,C5,78,1F,88,87,16,7B,47,35,E3,25,5F,86,BF,00,35,3C,F7,4C,31,17,93,B7,54,4D,9D,97,6E,5E,96,FB,58,C2,CB,D0,AE,7A,D6,E7,D3,43,FF,9C,EB,F8,1E,F1,80,FA,E8,30,7F,D9,F5,64,E1,33,85,68,34,2A,89,FF,DB,88,7D,0F,26,30,03,CB,EC,6D,20,AD,AC,DA,D2,0D,64,95,EE,55,6A,63,89,42,8D,B8,28,A8,42,AC,31,81,F9,53,23,20,76,A7,DA,AB,6B,89,9B,7F,83,A1,43,20,E0,35,93,ED,79,EE,CD,E2,F9,28,D1,C5,93,26,AE,66,E2,A6,04,0F,49,12,91,8B,1E,EF,43,32,EB,83,12,50,16,CD,DC,0F,FE,9B,7C,96,FD,DE,06,C3,B5,CD,B0,5C,A2,D5,10,4C,DA,FD,AE,65,2F,FA,06,86,E0,30,19,15,6B,DC,89,0B,03,49,37,A8,C3,ED,56,36,09,60,B9,65,69,0E,81,BA,01,22,C9,21,52,0F,27,86,AC,77,CF,01,C5,75,B2,4F,E9,21,8D,A5,BA,BE,B4,C1,93,31,12,01,CF,42,08,7C,2F,DB,38,C1,7C,E4,77,6E,FB,F2,11,47,00,4B,F6,16,A1,F4,18,74,12,67,5A,CF,B8,A6,6D,E2,E8,60,E1,0F,0F,0B,C5,4F,A0,9B,5E,56,89,5D,14,5B,EF,00,5C,A3,C6,BB,BB,F4,DB,3F,0A,A2,A4,34,4C,1A,EA,5F,1A,ED,06,DA,87,A0,E5,F0,D1,E5,D5,F3,F2,EF,EC,C3,AB,9A,B1,23,85,A0,77,ED,81,C4,91,A2,FD,05,E5,A1,D8,11,93,00,EB,F9,BA,3D,33,50,95,7A,44,64,93,A5,58,BC,0D,8B,31,C4,BD,1A,59,2B,39,BE,F9,9A,C9,C4,DE,89,58,D3,DA,28,2D,E6,70,B2,08,26,1E,F4,E9,40,4B,83,FD,2C,97,B4,56,6F,01,72,9F,A0,16,D6,28,A4,C9,99,44,FD,0F,E4,FA,96,6A,15,B6,EE,82,D1,77,7D,6C,A6,3A,D7,B8,EE,7C,23,B1,2F,55,12,A0,DC,8C,35,6D,2A,2D,FF,00,44,47,01,84,F2,F4,F1,6C,92,71,BA,6C,04,02,C7,70,6C,7B,9D,7B,F9,45,A2,21,F0,9A,F0,A5,A2,1B,A3,9F,41,EA,AD,AC,23,3A,BF,D0,CB,14,76,19,6F,AF,4C,35,95,9A,2D,6E,7E,EF,1E,5C,D0,A7,06,C8,CA,D1,21,A4,ED,F5,A0,52,E3,7E,19,2B,D0,BC,4B,FC,50,3C,D0,2B,16,02,EB,72,59,7D,E5,F4,C8,D5,B4,81,79,81,19,52,6A,C1,B1,50,19,51,DA,A6,3B,7C,71,32,5E,64,EA,FE,AD,BD,D0,3D,1D,CB,6C,ED,93,A5,AE,DB,A4,26,79,8A,77,76,8F,BE,34,7B,A7,15,7C,9F,15,39,61,4A,6D,12,F6,DC,0D,9F,06,74,D0,5D,7F,41,42,58,59,C5,E7,D1,BE,47,C3,D0,B9,90,F7,21,5E,4F,A6,83,1C,C1,62,EF,1E,10,EE,45,72,05,FF,CE,CA,BC,F1,21,78,E6,AB,DC,22,F0,80,06,FB,61,05,21,46,37,5E,5F,2F,CE,32,65,99,B1,6E,3A,2F,2C,76,68,75,20,4E,72,05,68,93,8F,5A,CB,77,6F,E0,3D,04,63,E8,94,3D,E4,0E,51,09,84,ED,AF,AF,AA,57,20,43,39,95,A9,A7,12,C5,1E,78,9A,99,A2,73,C8,8F,B1,E9,32,A6,0B,B5,E2,8F,80,6F,65,49,23,10,F2,34,DD,64,A9,75,8A,BA,7D,2F,6E,B1,39,01,0A,1C,08,14,1C,48,F4,72,8D,BC,50,EF,D2,5E,5C,C5,A9,52,42,13,4F,85,35,DF,86,32,AA,4B,CE,D1,6D,20,15,13,07,FF,8B,60,D8,F4,D2,84,C2,5D,4C,D4,02,A4,86,F6,D7,9D,81,02,91,3B,6F,72,EB,50,D8,8A,32,0D,30,97,82,E4,CF,0D,EA,7B,05,43,19,29,71,CB,C7,37,E6,1C,CD,38,CF,CE,46,4A,A4,74,EE,26,D9,0C,D1,2D,D9,93,61,3F,6E,FA,24,43,66,1A,08,08,D6,B0,A5,CC,63,63,24,9B,EB,3D,A6,BE,2C,F1,4D,79,3B,7B,51,C2,24,60,AB,EB,04,04,BA,B5,AE,40,F7,3F,F1,22,3F,7E,B9,CB,95,9B,48,D0,33,7D,8B,61,36,B0,3E,5C,1E,DE,EB,7F,31,BF,64,19,DB,E5,83,6C,54,30,FB,EB,C8,E9,51,82,5B,91,BE,91,9F,2C,0F,8B,8C,82,0E,EC,62,29,84,79,19,29,51,37,BF,B9,E8,BB,9E,21,66,32,16,02,E2,35,95,0E,00,6F,7E,FA,CC,DE,96,96,2F,55,DC,4F,93,64,22,57,ED,47,19,53,B3,17,E8,C2,BB,80,B5,51,26,74,56,50,8C,2E,2B,04,AB,95,B4,A0,74,93,4B,A5,ED,0E,5D,1C,8F,40,DE,D6,2B,25,8D,CD,58,D3,AD,3F,53,14,18,39,FB,6C,ED,CA,C4,02,54,D4,8B,70,12,D6,24,47,BE,59,CE,87,7E,F7,15,FC,6F,BA,2F,DB,A5,8C,9C,A7,59,FB,0D,7D,F2,64,35,7E,32,3A,26,EA,85,1F,81,E2,B0,44,5F,F7,56,07,9E,92,7B,90,4A,40,7B,34,11,1E,9F,81,CA,7D,5C,06,CE,AB,1F,02,BA,5B,CA,9A,C3,27,AF,14,BC,3A,F6,66,7F,97,90,DD,C4,8B,5B,44,0E,D7,17,48,1E,2C,BF,F3,DB,27,5F,66,07,EF,5E,8B,28,CF,FA,75,0F,FF,A7,FA,16,2A,28,6C,FB,B6,4C,AB,63,ED,88,B5,82,2B,30,E5,AE,FA,49,16,20,D5,5E,EB,49,20,AC,E4,9E,46,FC,06,EF,DC,91,79,6D,24,C7,FD,A0,90,68,66,33,EA,2F,42,91,24,E3,10,7B,11,1E,18,77,EB,5C,A1,04,5C,1A,06,FC,21,DC,E5,55,54,01,A7,A9,82,35,F6,26,03,A4,2B,52,76,86,CA,9F,6B,11,D3,68,5E,C6,BA,D5,F6,E5,EA,D9,52,9A,0F,95,76,37,69,02,8C,71,49,46,B6,05,14,70,45,36,C4,7E,67,D3,A1,A2,D3,10,B3,18,66,88,76,54,69,C8,52,93,79,3D,E6,12,02,E1,7B,5E,95,9F,FA,23,97,A3,FF,59,EE,0C,57,AE,62,12,C1,21,BA,DE,79,37,0A,CD,B1,BF,6A,C9,AF,DA,59,97,F3,41,F4,6B,3D,A0,14,52,AB,80,42,2D,01,DF,1E,73,CA,45,4F,B5,11,C4,A8,0C,A8,79,53,AE,96,61,83,5F,A7,93,BF,57,DA,61,13,4E,66,21,5E,F3,19,7F,56,6A,BB,C0,90,BD,28,FF,58,EA,9E,DF,C4,A2,B3,0B,C3,C1,58,81,4F,20,EA,2D,EC,57,12,24,0E,2B,54,63,28,9A,2E,50,D2,4A,62,90,67,48,A5,95,C1,1F,D4,D6,DE,E2,98,10,3B,55,D5,5F,B1,65,8F,4F,4F,3A,9F,2D,A5,CC,ED,23,4F,17,0E,67,C6,E9,F2,BF,AD,83,86,2A,2B,93,6A,CA,2C,C0,EA,B7,62,AF,DE,9A,38,CB,94,17,58,7B,1A,60,DC,A4,62,43,E5,35,F6,3E,FC,97,34,4F,D8,3B,D4,12,E2,72,7A,06,46,DD,48,E8,02,A1,18,C0,0E,AE,5C,25,70,D9,2D,07,6D,6C,C5,DB,7E,80,EA,7A,C4,BF,04,27,4D,43,08,86,A4,C3,5A,39,20,B2,2D,78,EE,CA,66,44,73,50,59,5A,47,71,7B,5D,50,10,0D,B8,CF,26,0E,85,10,6B,6C,41,02,8D,45,A1,79,B5,66,29,B9,A1,CD,FF,74,CE,A5,22,9D,60,E4,E6,2A,57,80,CD,53,92,30,EE,F7,9B,D5,F2,6A,FC,6D,4C,B1,98,9F,A6,D6,47,0B,D2,5C,D4,BA,15,01,FA,FC,DE,F5,88,35,90,03,FE,21,25,AE,2B,01,A1,43,83,C0,E5,30,0E,C0,9E,7D,FF,2D,5F,9D,D3,7A,7E,12,F3,E4,30,58,1B,87,9F,A3,15,9D,FA,08,21,50,7F,E7,E3,A4,39,EC,61,42,78,E8,FA,18,E2,B0,5B,F2,5F,9C,CE,95,79,96,D3,AD,AD,B6,A5,DF,B1,58,8C,91,0F,49,D6,85,4E,BF,B4,68,17,8D,A7,FD,3E,30,B1,ED,5E,79,08,F7,E2,E5,E2,4B,33,62,27,C6,0B,2B,92,B9,F5,22,50,7B,51,CB,AC,05,41,0E,87,59,30,F5,AA,41,9E,DC,5F,A6,CC,41,42,2C,62,1B,32,96,B7,E8,30,18,92,CE,92,29,7A,97,B9,E5,6F,84,25,E7,93,D2,E8,EC,DD,84,57,64,22,A4,E8,55,6F,E3,46,C8,F3,7D,E4,9D,A4,6B,71,B6,66,E9,A7,47,E0,72,09,A5,75,0C,A9,86,D3,1D,40,CB,0A,74,3B,7A,28,8F,99,B5,EE,11,0E,C2,B1,86,90,F8,E3,2A,89,50,FD,7A,86,94,04,6A,C4,2C,CB,D0,7E,FE,44,45,B9,40,AE,D6,10,06,CF,25,61,0C,59,2A,54,6A,7E,D0,95,4E,7C,19,A5,96,9B,A8,65,27,B3,26,F7,A3,02,AF,63,44,45,3E,F5,2A,1B,F2,66,8A,3E,B4,81,82,93,10,20,9D,F3,7A,C3,AF,1F,8A,53,82,C7,19,41,49,AE,B0,EC,B8,29,5C,47,81,B0,87,2C,4D,4F,CB,26,73,35,49,FE,6D,69,E5,50,39,83,75,E0,9F,DA,42,0E,35,A1,C7,1B,36,9B,3D,50,D8,8C,37,F0,69,C9,FD,9C,D5,0D,EA,45,D5,B2,5C,35,DD,E7,C6,9E,EE,EA,6F,E0,66,7F,EC,6C,C6,CA,0F,D6,90,A8,06,E7,65,87,2A,4D,05,C8,42,9C,11,7E,37,D2,8E,89,89,C8,FC,3A,D9,EF,9B,28,A4,A4,D0,7D,D3,69,34,1A,A3,F5,91,FA,B2,2B,C7,F2,C1,FC,5A,9A,43,B2,F8,7D,44,DB,A4,C4,FC,64,6D,C1,D6,47,0D,11,6F,52,87,B9,8D,9C,16,D8,B2,B2,B3,8E,DC,D8,59,BD,34,66,86,3D,85,B8,77,75,BA,CA,B4,FB,54,24,57,93,55,A2,52,A7,89,C1,41,01,A4,BA,E2,73,12,C7,0B,06,E3,59,2A,17,6B,CF,4A,2D,62,BE,2D,94,81,E2,58,2F,3B,37,70,2F,42,7A,E8,45,8E,91,B8,9B,8B,C1,8A,DD,82,D4,02,34,A3,A4,44,BD,72,36,90,EF,44,E7,2B,57,18,BC,78,07,D0,B2,3B,C0,5F,2D,34,D1,9E,A0,10,B3,E5,96,FE,6E,06,A2,08,1B,8A,FA,75,E0,13,90,A2,D9,1B,95,E6,D1,B1,0B,D6,CE,11,64,2D,E8,CC,F4,E2,B8,16,DD,C4,8A,97,1E,AF,67,1C,DA,1E,B8,CD,AF,7F,04,FB,B7,4B,1D,6E,72,24,31,54,53,93,12,07,F0,7D,19,FC,09,DF,F5,14,6B,CB,E6,EF,32,D1,BA,E0,5F,10,AA,FF,3A,1F,BB,14,56,92,DB,C2,F5,AD,DF,52,C6,A2,2D,18,95,21,16,92,4A,F2,5C,CF,D6,51,E1,56,05,26,5E,59,52,07,ED,17,E3,19,E6,E8,A2,F6,F2,67,60,9D,BE,43,CB,59,25,DB,C5,5A,7B,6A,F2,90,47,31,74,B7,C4,34,09,16,FA,66,D3,14,E3,3D,F3,A8,6E,C7,61,2D,2E,36,AF,B5,B9,27,C6,63,F8,49,64,A5,B1,7F,FC,36,69,3D,19,EB,EA,36,8A,EE,8C,28,6E,89,E4,69,94,D4,85,40,5C,1E,3D,48,5C,1F,7E,1D,CC,20,B7,75,F2,99,1C,EB,DD,F4,8C,4E,D4,2E,11,C0,0E,E1,DD,EC,6B,AA,E1,1F,2A,4A,B4,C6,C4,86,9B,64,73,AC,15,93,BE,09,C0,CE,E4,28,33,79,C2,E2,85,D4,8F,5C,8D,0E,FC,F8,A8,9F,DB,55,CD,67,F6,B1,AF,0D,99,66,B0,F6,A2,59,D7,11,D1,3B,F7,4B,8F,E7,26,9C,06,94,06,FB,4C,5C,AB,69,29,27,2E,F1,4A,7C,97,29,27,37,B3,3C,E5,49,3B,E9,DB,BB,F6,B6,43,26,CD,AB,7A,02,62,F2,47,56,BD,E2,FE,9D,0F,61,D2,65,06,17,F3,99,66,27,75,E8,7D,4E,AD,6F,6C,F4,93,C0,E8,88,61,4B,65,A4,A5,98,FD,2C,B8,AD,31,F0,41,CF,2C,5F,15,F0,A2,A8,26,C4,7C,1F,40,47,01,F4,39,3B,98,2D,49,FE,D7,8F,1B,0A,FA,41,95,1D,CA,74,C4,12,41,EA,61,79,4B,DA,CC,7A,D2,96,89,FB,C6,8B,76,E6,D4,7A,E7,98,B6,CE,A1,8E,96,2B,24,69,3A,B5,FA,2B,6F,01,A3,BC,5E,76,5D,73,F1,4F,1C,1C,C3,46,8F,21,45,9A,87,25,91,6E,EF,A8,19,38,37,57,49,9A,CD,D4,B9,23,CA,5D,C2,31,84,29,23,8C,D7,85,25,21,23,42,34,BD,77,39,C5,3B,68,E6,CB,1B,81,7E,FE,44,BC,0C,D9,1F,FD,D3,6D,48,4F,69,47,6C,BB,AA,DA,44,D1,12,39,9A,06,FC,29,3B,1F,E1,BB,7B,D9,9C,AE,74,5A,02,06,F7,EF,EF,18,07,7E,46,BA,3E,79,44,E3,FF,23,E0,4E,23,55,34,93,A9,AA,B0,AF,FF,C8,09,C8,B7,E7,C7,0F,4C,5F,2F,DD,43,DA,C3,AA,06,15,AA,ED,9A,76,6E,53,1B,46,EB,60,72,5E,C4,69,B3,0B,5B,85,6B,92,2D,D5,29,34,EA,EF,03,A4,59,5E,FF,6F,4E,CE,9B,21,79,5D,DB,4A,07,6B,00,99,03,8B,FD,72,66,66,C3,B2,02,6E,7F,88,6F,3E,EF,73,E3,57,3E,1D,80,A8,90,78,85,0F,B6,D6,63,72,7E,EC,B7,78,D4,4A,71,81,B1,A0,D6,C8,53,B7,67,64,B4,09,30,FF,7E,37,B4,79,07,BC,EC,A1,64,BB,4E,03,98,B6,A2,58,75,5F,8F,BB,E4,11,52,55,57,BF,AE,53,E4,41,21,F0,A6,DF,0D,1B,56,E8,8F,C6,92,6A,72,2A,7D,9C,D2,A3,E1,3A,A7,88,A0,40,91,97,AB,42,FB,86,01,58,0F,5B,45,A8,B3,D2,43,28,E8,21,63,BB,FF,84,61,A0,B9,1F,BC,F0,0D,15,7F,75,C0,80,B1,29,8A,B4,0A,22,48,D6,CE,E0,16,CE,30,B9,E8,29,BA,86,0B,C6,59,8D,64,C0,F7,98,11,73,D5,29,E6,F4,E7,FB,7E,E5,F4,B7,BE,C5,BB,9B,77,01,F5,6C,1B,06,05,D1,93,CA,33,B3,45,A8,B7,D0,D2,34,8C,4E,27,AB,E8,11,31,82,4F,23,FF,4A,77,C5,C5,76,8E,46,7A,E2,2F,DE,1F,F1,98,91,8A,DF,D9,D5,43,53,70,1E,B3,80,EE,73,64,39,24,4F,F6,67,0F,A8,7A,AD,21,B2,AB,9A,29,69,CA,1E,FB,5B,2E,FA,E3,7C,E8,12,7F,B2,3C,BB,30,B2,88,35,2D,F4,9B,2B,29,8C,35,A6,1A,58,9E,9F,FA,6E,28,27,AF,A3,17,0D,78,2B,69,B6,18,02,BE,B7,73,80,33,4B,CE,F4,50,CE,39,E1,C9,95,ED,39,15,DD,4C,03,0F,10,FB,04,0B,E5,42,98,90,49,77,A1,3A,B0,64,D6,A3,98,8D,92,3B,3F,1A,11,47,BD,03,FB,3E,62,99,C5,83,4C,3A,FC,89,61,F4,B1,34,BB,6E,2E,BE,AB,5A,0A,65,2F,F8,8B,A8,72,E9,7C,A4,9A,0E,C4,1F,E8,6B,DF,08,01,05,E9,25,10,69,54,54,03,B0,86,6E,48,63,6F,61,2B,0E,D5,DE,55,8C,F9,7B,07,36,CC,BD,33,5D,AD,6B,4C,58,FE,C5,C7,EF,D4,AC,47,FB,CF,F5,8D,D2,79,3C,78,69,BC,A8,E3,37,B2,AB,FD,2B,34,27,15,E0,EB,02,17,83,E4,17,DC,3B,9A,11,64,CA,51,F0,04,96,F5,69,E8,45,95,4F,6B,28,31,29,18,0E,03,7A,DB,EA,A8,57,D9,13,B9,6D,F0,67,13,08,33,A6,BC,10,CE,07,B2,22,C9,D4,2E,6F,AD,71,51,97,42,C1,4F,49,68,C2,74,34,1F,81,98,09,B5,73,69,98,5C,2F,72,4A,2B,3A,A9,65,E1,D4,8C,12,A9,43,05,22,2E,58,BD,ED,15,00,08,FD,A6,32,55,8F,D9,31,DD,7D,29,71,71,6C,84,93,4B,63,02,49,F2,46,3C,DF,75,E5,77,57,FC,AD,43,43,64,E3,37,C7,89,6D,DB,13,01,69,42,FA,7F,EB,9B,F9,63,52,39,17,F3,E0,7B,08,D7,AC,90,9D,75,49,4C,73,B7,A7,B6,F8,A7,0D,4A,C0,19,BD,A2,0B,5B,8E,49,2F,64,5A,05,F6,52,B0,31,8D,47,06,8D,02,1D,B3,15,A1,8F,4E,C4,84,17,CD,9C,FF,9F,E5,34,A8,9F,FB,3C,BA,7E,83,D4,FE,13,F4,9B,55,81,95,7E,CC,17,F5,5A,54,33,55,3F,73,51,93,A5,C9,A7,E1,28,FE,54,8F,F2,3D,DB,F5,BE,CE,15,C4,97,06,4C,D9,65,60,45,81,74,2D,87,35,FB,77,25,37,1C,C9,ED,82,AE,53,BA,0B,EB,17,01,F8,97,12,12,33,C5,DE,BC,7A,4B,DE,09,A4,29,67,46,62,7B,C4,DC,33,42,6D,37,F0,B8,C4,77,61,FE,7C,DB,E5,3A,B3,2A,89,AD,26,22,B4,38,C9,BC,B0,12,89,8B,1D,ED,D5,4E,97,8B,1D,89,0D,32,C1,5B,1B,DB,A2,92,92,75,02,AD,79,93,B8,2B,55,87,7F,34,10,02,7C,E6,F1,FC,E9,BE,19,11,19,FA,9B,F9,06,A6,84,3E,81,C1,A1,94,17,47,89,BB,B5,25,C6,B2,5F,A4,8A,65,BD,8D,28,CC,D8,B4,01,6A,6A,9C,78,01,30,9C,29,CB,7F,E6,CC,0E,B9,94,20,2C,46,91,42,28,44,E5,4A,E9,17,4A,98,E6,D4,A9,47,AF,9E,0A,B8,A6,81,5B,2E,75,8A,5B,61,47,CD,E8,C6,F2,44,71,32,31,35,52,66,16,99,D9,86,4D,0D,59,49,09,3C,6B,67,6F,CE,AD,51,1A,A0,B4,C7,68,1E,6F,BE,8B,62,45,38,BA,F1,CC,37,A9,2E,94,EC,52,6A,05,FB,13,A7,CC,EA,20,A8,95,FE,7E,B9,0B,E2,53,83,52,E4,5A,5D,E4,A1,97,08,CB,44,B3,64,39,55,B5,D3,D6,70,1B,EF,9A,FF,9A,72,C9,76,01,B8,22,4B,87,5E,B0,75,C2,CF,ED,55,D8,81,3C,E2,33,26,21,D3,E4,A2,17,43,D0,C7,00,70,7E,11,67,AA,F0,D4,D8,17,CD,C9,0A,3A,E8,C9,02,73,3D,04,77,B0,8F,26,56,DC,43,46,88,B9,72,87,48,ED,93,E4,6B,B8,D3,AE,F9,7E,EE,6B,F7,50,94,61,15,00,9E,D5,82,96,85,53,86,B4,2E,BF,AB,75,65,D0,B3,BD,93,78,94,6F,CA,AD,72,1E,28,12,71,1B,CF,0B,3B,55,20,36,2B,18,37,01,3B,D7,E3,A2,BC,B9,F2,32,EB,DF,2E,31,5A,AD,21,E6,D5,BD,34,A5,70,72,41,CC,AB,AB,2F,B7,53,BB,D1,09,D7,64,9B,3A,E7,F7,BC,31,13,58,DD,2C,A9,55,4A,72,B4,BB,3E,F1,F2,6E,ED,2A,7D,E0,36,D6,56,FB,F5,4F,CC,27,49,EF,98,2C,5E,31,DE,E8,0D,5B,A6,F4,12,38,B6,42,BA,57,71,58,99,86,FF,42,AD,A2,7A,83,6F,53,FF,F8,5E,44,76,DF,43,A9,E7,77,F7,8D,B8,8F,E4,12,DB,94,D5,0A,3E,73,83,7B,72,AC,9D,1C,8C,15,F7,42,86,08,91,4C,16,CF,ED,F3,7D,77,43,E8,25,EE,9B,86,E3,9A,E2,72,3A,90,EF,AF,DF,5D,17,FD,D1,36,A5,1C,F3,26,21,40,C4,68,41,D9,E7,53,2C,87,78,70,52,2B,C1,72,B9,33,33,7F,65,85,C4,5B,BA,BE,94,3E,F5,16,C9,50,9D,76,4B,D4,DA,3C,FB,02,E4,53,65,65,ED,80,20,4D,97,DD,02,7D,FE,B5,F4,C7,B8,EB,4C,CA,13,67,EC,05,26,58,A7,64,40,62,F9,5D,62,2E,55,5F,B1,EE,0A,7F,30,2C,2A,69,73,53,49,F2,DE,84,EB,51,18,74,47,FF,64,99,C6,59,2E,3A,4F,53,56,1E,A2,FD,22,F2,CB,F0,F5,31,A6,E1,45,58,D4,E6,35,D3,29,71,9A,59,40,35,AA,59,0F,2E,FC,FE,9C,3F,20,EC,72,B7,CE,CF,ED,E0,9A,52,D7,30,7F,F9,D3,D2,87,C1,8D,16,23,67,D4,01,F4,B3,35,3B,8D,B4,82,5E,F1,06,BA,8A,26,E1,76,DC,AE,D6,2F,22,E5,39,DF,65,FC,1F,EC,1F,9F,6B,73,4B,3E,26,A6,7C,44,3C,04,63,35,20,AD,1B,AD,17,DE,BF,A8,DD,F1,8C,5A,33,1E,DA,DF,F9,C4,87,E8,5E,0A,CF,39,42,E1,0C,1B,84,FB,E8,98,CF,A5,D9,28,6A,12,D0,73,43,F4,A7,E1,B2,03,56,E2,14,B6,75,A7,0B,2C,32,7B,D5,C4,CD,D5,D8,E3,CD,30,6A,E0,77,87,0F,CE,A4,E8,50,2C,87,DF,1C,32,07,34,09,95,D4,AF,83,43,21,37,32,7B,20,3C,85,A1,75,05,67,75,B9,53,59,A0,A1,11,7D,8E,A6,AC,96,AA,06,E2,C2,4E,83,F3,92,DC,C8,8F,28,B2,56,25,09,70,3A,A4,FD,0B,B3,AF,57,50,CF,CF,E8,EB,AE,B6,0F,A9,EB,8C,D2,61,23,8F,99,A1,30,27,88,43,EF,4D,0B,03,B4,AE,3B,EF,FA,E1,D7,23,0A,06,0E,6B,E0,33,D5,4C,93,77,80,97,8B,67,28,17,91,A5,EE,99,80,DC,42,20,D2,F0,79,91,DB,6D,A6,E4,F0,E6,64,6E,62,BF,88,2D,24,21,DB,4B,5E,59,A3,FE,AC,EF,A3,23,A1,75,1C,27,EB,4D,08,9A,58,65,D0,22,FD,F6,3C,8B,1E,9F,03,7A,AC,F2,B4,A5,77,52,96,60,AD,EC,F0,8F,0A,4E,A3,08,C8,8C,F2,48,A3,E6,B9,53,21,17,EF,35,8F,8D,FD,DF,70,CA,D9,37,ED,B1,7E,44,57,F8,50,26,91,15,AA,93,44,D1,CB,A3,31,EB,03,ED,82,F8,FD,03,C5,F4,38,3B,F4,14,62,FF,01,E9,2F,2D,BF,58,7E,F3,76,2E,DB,6A,F9,D1,E7,C6,0E,65,32,58,FA,42,27,54,E3,94,E4,C2,A3,4C,F9,3F,01,39,E6,03,80,D8,88,12,A3,6A,0E,B7,62,B9,2D,D1,B5,D2,34,C9,20,11,C6,2B,0E,7D,02,05,96,9A,7D,C1,EF,CE,2E,7D,07,CD,C1,CF,DE,51,1E,B5,63,8C,BA,53,FA,9C,72,F2,8E,60,58,88,30,AA,8A,66,C3,13,E9,F6,7A,A9,25,BA,60,19,8C,F5,F9,DC,41,E1,E7,0B,D6,A1,01,C3,AC,65,A6,5E,77,FC,D7,BC,08,28,1E,A1,53,FB,3C,B9,2F,98,72,A2,F2,25,D9,FD,24,A4,14,1C,22,4A,B7,C6,FA,70,46,FA,8A,79,5A,0B,CA,4E,F9,49,E7,08,B4,C0,97,DB,F9,6B,F6,52,C7,B0,73,30,C1,09,FF,4A,81,24,F6,42,84,A3,1A,8C,3E,18,CB,D7,4A,CC,FE,58,12,55,47,A8,E4,09,FE,9E,FC,38,ED,D1,1A,EE,ED,D3,36,3D,12,43,C3,1C,05,C5,DB,33,A4,63,0C,63,4E,BF,D2,48,01,57,4F,5D,F7,CA,34,A0,54,E3,44,40,EA,8A,20,60,8A,1F,81,FB,19,B5,A2,0D,EB,E5,E4,0D,E2,80,6F,53,B3,66,29,2F,F8,7B,1D,FA,15,E4,2F,C3,D6,EC,0D,38,7C,94,BF,3C,57,58,5B,4D,59,EC,EE,52,6B,B3,36,FF,F1,73,E3,EF,97,D7,D8,BF,78,78,5D,E2,D7,C6,AB,FB,8C,2A,6B,D1,A3,0A,0E,6D,37,8B,EB,78,F8,90,55,29,B7,CA,0A,52,17,54,EF,99,93,1B,B2,23,A6,8D,25,12,A1,3B,86,B4,AF,A1,AD,FF,48,A4,28,E9,F2,29,35,D0,F0,9A,2C,FD,64,54,61,A1,EE,98,86,D6,55,54,AE,14,07,7E,51,12,1D,7B,F5,AD,C0,AB,F2,1B,12,4B,F2,9D,48,4F,23,87,8B,73,B4,FD,9A,CD,F5,9E,C9,99,24,78,E5,08,49,9A,7B,32,5E,B0,E1,17,64,A3,4C,6F,F9,03,8E,AB,8C,15,FF,9E,5F,F5,F3,3C,81,57,DA,FA,0F,05,32,43,BB,89,D0,F9,51,A9,7C,AB,FA,2D,79,9E,7C,A9,02,74,44,91,A1,34,49,AC,F4,8F,00,86,45,14,09,32,F7,4F,70,CD,CA,54,7E,6E,91,2E,82,7B,E5,87,5C,45,10,F6,E6,49,13,63,49,2A,6C,C9,C6,36,35,66,1B,07,61,8A,E8,28,FC,A9,2A,DD,53,FB,08,13,C0,9B,89,A4,D4,79,07,A9,FB,61,72,CD,F1,6A,03,03,4B,16,58,11,A0,12,51,D5,2C,2E,68,88,A3,54,C8,8E,0E,6C,4F,06,81,46,B6,29,93,51,F9,3E,7D,D0,03,89,4E,79,C6,19,B5,97,AB,F4,08,F1,C3,A8,9E,AC,06,00,0F,AC,29,4B,91,92,79,F3,B0,E2,99,EE,64,D5,9F,A8,44,26,D8,6F,2E,93,DC,A7,EC,71,C3,DF,A1,71,CE,28,F2,80,1A,A3,81,0C,D9,35,B3,45,E2,BA,11,78,70,6C,25,63,8F,C0,21,DE,5D,42,29,D8,C3,7B,A8,B9,0E,AF,F7,AA,30,C0,28,42,F9,17,7D,96,70,C0,DE,46,2D,21,FC,43,B8,66,9C,FB,A0,FE,5B,4B,25,BB,15,A1,6F,E8,7F,91,F5,1C,DD,76,02,FE,56,4F,21,DB,85,12,38,79,E5,97,6E,1E,E9,7D,8A,9A,18,EA,08,3D,B3,D6,F4,76,E2,9C,4A,79,A9,80,DA,E3,E1,C0,B5,90,EB,9F,94,3B,E1,5E,86,35,52,29,87,63,48,05,59,E6,4A,F7,D0,23,0A,DA,D6,FE,51,81,1A,8B,8C,6B,42,02,5C,F2,92,F8,3B,DF,4A,25,E7,D8,F2,B8,25,93,63,32,F4,D0,91,BF,80,9E,43,61,F3,3D,4C,81,77,33,7B,D7,81,CE,CD,21,B7,E3,8F,83,1A,A9,3A,01,33,2A,B8,1A,FA,5F,28,72,B1,80,66,40,2A,4A,B6,F8,51,FE,97,87,EF,83,1E,62,A5,20,55,E4,02,E6,0D,E8,25,2B,08,03,4F,CF,35,FB,15,3C,F4,09,EA,7E,D1,79,A0,54,08,FC,35,F5,31,17,5D,76,D0,81,ED,EA,40,C2,99,BE,07,8C,83,48,C2,3F,69,9D,58,7A,A2,DC,F3,0D,1B,5B,DA,FB,F4,F7,61,1D,B7,B9,F6,57,C4,B3,F6,82,6D,FB,0C,49,2E,68,9F,33,62,53,32,2A,C5,60,4E,94,44,4A,07,DA,D5,F1,B1,12,D1,B5,F1,10,5E,B5,54,CE,73,83,43,A0,CF,59,E7,DB,F9,04,A4,94,0C,96,AB,44,4C,8A,AB,91,BD,1F,B5,28,A4,8E,43,7C,02,3B,38,D8,5D,53,23,A4,62,F3,C2,77,B1,78,59,FA,B6,15,83,CF,1B,38,75,51,82,68,DB,76,DA,BD,6C,DB,BA,E6,FB,48,9F,44,07,23,92,75,9A,37,83,E0,66,09,E4,D6,A0,34,42,1C,7D,1E,73,BE,85,87,57,D9,07,8B,AE,38,7D,1A,07,EE,C2,17,83,61,CD,E5,5A,8E,0C,E4,37,42,05,5B,B2,77,9E,CC,9D,CB,33,5E,23,D4,83,D7,3E,FC,4E,C2,4A,02,A5,5A,A3,52,9A,F2,45,3A,BA,BE,84,33,F8,2C,CF,34,50,83,3E,C0,E7,DF,C1,44,5C,DF,3C,32,2E,EE,C6,E5,41,CA,FE,6D,C3,F0,DD,04,B6,8B,AB,5B,F7,C4,E3,38,FD,38,49,3E,1B,ED,82,54,8D,88,B8,E8,08,A5,D9,38,2A,55,58,A6,57,8A,C9,78,E4,F2,D9,B9,E2,21,A9,B3,43,F0,13,AF,E8,E0,DB,28,CB,9B,45,B1,86,71,F2,73,6A,7D,EC,C8,39,F9,2C,C0,5C,24,E7,A1,A0,47,1C,C0,58,97,C4,F3,14,28,D4,62,24,88,FA,2A,C4,F3,AF,20,63,C6,DD,C7,99,20,28,D0,05,07,2F,80,46,19,57,48,98,86,26,20,F8,28,05,62,4A,E5,C0,78,0F,97,BB,FD,2B,3F,54,45,1E,D3,40,2F,5B,5B,A5,60,D2,A6,C7,D3,A0,99,6B,77,B6,34,83,96,05,D1,A1,95,45,20,A0,69,4E,85,A8,9B,DA,BD,31,4E,B6,75,23,1C,72,F6,8B,A4,7E,21,7B,E4,81,28,50,E4,8E,2D,8A,A4,01,29,14,80,5B,45,11,4A,39,C5,17,4A,40,22,19,C0,C2,28,22,35,82,3A,B0,2B,4A,E4,E6,40,15,CB,60,DA,A8,DA,AA,BF,0D,A3,FD,FB,3E,A4,99,41,C6,BC,91,26,20,3A,7B,32,E3,77,DD,6C,6D,18,B6,4E,44,5C,DD,F3,7B,8F,58,62,08,3C,2B,BC,05,25,17,6A,01,A6,CA,AA,66,9A,DC,5D,ED,3B,43,68,83,CA,6F,AE,0E,E8,FE,B5,97,64,D4,12,5F,0A,58,9A,E0,ED,AE,A6,81,82,BF,E5,B8,A5,3B,D0,1A,33,18,13,3D,10,01,FD,CA,79,44,49,D6,8D,D7,78,2E,0A,A0,89,36,D4,54,0A,A1,D1,81,F1,87,97,D2,FA,0D,EE,43,AB,94,61,48,A5,73,6C,9E,D2,17,A5,9C,2B,90,FB,3F,26,B8,47,C3,72,64,0C,F8,CB,8D,D1,3F,59,79,3E,F4,26,32,D8,1C,5A,51,EE,7F,76,7F,81,F7,E2,C0,0B,2B,4E,DC,53,58,AD,FD,2E,72,6F,60,2C,87,2D,75,6D,46,29,5B,93,F6,08,0C,08,58,50,51,E2,3D,CC,8C,08,46,62,55,62,76,C3,D9,8F,95,72,6A,C0,6E,A7,E3,95,70,76,5D,3B,B8,2C,4B,23,02,3F,F9,0A,25,6B,A0,3D,3B,B4,1E,4A,38,12,F8,05,93,1A,DC,48,0F,68,24,AB,C4,F2,08,83,87,E8,47,67,5E,09,ED,B1,7C,81,F6,AD,BE,09,A0,38,53,48,6B,E1,48,6E,1B,23,D2,45,54,E0,AE,10,62,BC,51,35,4A,B5,50,F7,8B,C7,CC,9E,6B,9E,2A,0F,E1,FD,12,60,27,FA,D9,AB,6D,2E,1C,0B,57,E3,49,0E,63,42,30,30,76,61,AD,F8,E9,7C,C6,91,85,00,C3,DA,F3,37,F4,5C,AC,4F,24,00,FD,C6,D1,1D,D2,E2,DD,6B,79,CE,89,7F,BB,A0,68,66,60,AB,76,AF,5E,C2,40,BD,CC,13,22,DE,05,31,86,09,8E,EF,EB,17,02,C9,64,8F,6F,CD,C2,3C,7E,91,48,DD,67,C1,A5,94,2B,C6,D2,46,96,A4,1B,5D,EE,43,D4,F4,1B,C6,4D,EC,F2,98,DB,51,52,CE,0E,10,5B,F0,3F,62,F4,85,49,C0,0F,6D,F8,86,17,4A,93,4B,4A,50,5E,13,FA,78,2C,4C,E8,9D,BB,5C,FD,D7,CD,E9,8B,08,C6,D9,ED,58,3A,8C,83,8C,B8,52,5F,80,74,5A,61,1D,99,48,2E,EA,59,BC,AD,0F,1A,D3,52,2F,13,0A,AC,9E,CC,B2,5C,17,C6,2B,34,C8,F7,62,B4,42,40,FD,4E,A6,F1,B1,80,03,FD,FD,B5,52,48,69,33,31,E0,0D,7F,67,A4,F2,C3,4A,7A,DA,2A,30,1E,84,D6,E1,6E,1D,DD,D5,10,7D,92,20,A4,86,4A,32,B7,D2,E1,EB,76,3A,37,BA,C7,2C,77,9B,3C,C0,AE,C6,ED,9B,F0,9E,1C,64,0A,BC,F6,50,52,B8,2B,AE,40,9C,4A,CA,5A,49,0D,5F,9E,8B,F1,89,47,E3,CE,DD,0C,85,39,4F,8D,D8,97,CC,5F,B7,88,0F,EB,0E,BD,9D,5E,2C,7C,82,B9,15,91,BD,B3,1D,0E,D9,78,E7,66,88,C6,98,4C,D7,64,4F,23,1D,B2,0E,1D,33,13,EA,06,37,B3,97,23,12,AD,5F,8D,D1,59,BF,DA,47,E3,26,59,5B,B0,BD,C8,A7,2F,2C,06,87,35,4A,BC,67,0F,B9,97,89,3A,25,31,DD,32,7C,E6,49,93,F6,8C,55,09,5B,38,D7,3A,4F,12,BA,11,C8,5E,E0,93,51,6A,A8,20,B4,72,11,48,BF,6E,EE,8D,A0,7F,42,0B,59,5F,77,F8,0B,0D,A0,42,46,73,2F,AA,D6,69,C6,92,39,77,BC,76,3F,13,7E,52,4E,13,8E,20,1F,27,57,03,0A,96,EE,6B,51,8C,39,FC,C1,22,CF,59,FA,B9,1E,88,F3,2D,A7,0A,1C,35,EA,64,10,40,6D,4D,83,8E,91,26,C4,2A,3C,36,17,D3,CB,44,2B,39,7A,D8,4A,1A,EF,33,D8,5C,0C,80,05,A4,9B,3F,22,F3,F9,03,37,A6,DC,5C,C8,9F,5A,78,08,61,5E,7A,79,C6,E7,C9,BB,08,AD,7A,A8,DC,D6,CD,3C,DD,5B,F0,03,C4,FC,2F,B0,9F,A5,30,A0,C7,93,40,CE,4B,88,C7,3A,88,B1,40,00,49,DA,2C,B9,5F,26,08,2C,45,A5,EB,D5,B4,43,1A,38,9E,63,7A,20,78,7C,1D,D8,5E,74,F5,43,53,48,D4,2E,3B,A9,D0,2D,AF,E6,79,56,F6,7B,C4,E2,AC,A7,D1,BB,50,F7,83,0F,79,A1,3A,CA,A4,04,78,9E,E2,1E,8E,5C,C0,00,70,78,AF,A7,A4,F8,4E,F6,A3,7B,CD,3B,39,3D,59,BB,F0,64,5F,0A,A0,86,62,A5,93,D2,97,94,6F,E0,2E,EF,27,F3,92,D9,4D,D0,79,17,F2,D4,9D,75,44,32,64,17,3B,F3,A4,49,B1,F6,FE,78,BB,B3,B3,CC,86,64,13,4A,F3,F2,D5,1E,11,2F,E7,A4,01,B5,AD,5C,71,26,D4,3E,AA,D8,F6,94,9D,6E,E8,A2,00,9A,CD,C7,07,20,25,CE,97,70,97,CD,30,91,A7,E1,97,27,6B,06,5F,05,A5,EE,3B,4B,C6,C7,58,3E,B4,A3,21,79,32,9C,02,1A,02,82,7C,B0,D6,EE,D3,21,96,71,0A,ED,FE,27,CF,86,DD,73,03,53,AB,21,2D,2F,39,9C,4C,F2,31,18,A7,19,BB,36,40,4B,4C,70,86,48,24,19,B8,86,8E,F9,54,B8,FB,3C,A6,D1,F1,00,AE,44,05,DF,BB,4D,4C,E5,F5,B0,D1,6B,43,6F,E6,31,70,1C,4F,1B,A0,2E,1C,74,CD,07,CF,00,04,E2,C2,D0,6D,D7,E6,5A,8F,09,BD,76,08,E0,7B,3C,74,E0,D8,47,BF,CD,4A,99,F2,BA,B4,5A,14,F1,85,28,38,F1,A9,27,6B,9C,55,0C,CC,0E,12,61,20,13,71,D8,F2,53,A1,60,D6,EC,7B,BD,3F,1D,13,94,2B,73,BD,74,4C,20,16,70,33,CF,0C,C8,68,34,3A,D8,37,CF,07,BF,9F,36,75,94,4A,67,99,EF,E2,04,25,1D,0C,34,C0,CD,49,C4,59,FA,28,62,1F,72,06,36,A5,E0,10,19,F6,F4,3D,C7,0B,63,ED,82,72,A1,AA,DA,70,0A,BB,6F,BF,FA,90,F6,A9,3E,FB,84,C2,8C,F5,C1,64,79,FB,AF,B7,D7,B4,0A,A2,60,A7,E4,6D,DF,EF,1B,22,D1,88,7B,84,DE,58,4F,AC,7F,0A,39,0A,38,1D,7A,27,F5,6B,D4,AE,28,3F,33,0C,F1,2A,47,EF,C8,11,99,93,99,52,BC,45,02,D0,3F,7F,07,CD,24,EC,31,4E,8C,48,A2,96,8A,FB,2B,2F,25,98,68,93,C1,71,B0,33,B7,8D,C6,44,5F,B1,9A,CB,24,A9,98,50,81,1D,48,E1,41,5F,BB,89,CF,B4,8B,9A,D6,79,95,29,E6,9F,D9,AD,3A,3F,5F,4C,DC,F8,02,DC,3B,AB,12,A2,FF,EF,62,20,22,B4,B0,D4,C8,45,97,FF,2D,9F,25,B7,CE,13,6C,F3,5B,8D,E7,CC,A7,13,86,F0,0B,DE,1B,DA,B2,B7,8A,94,F2,CF,5B,E5,1A,C9,6E,80,A2,E0,27,DE,DF,86,F3,FC,1A,C3,15,73,A8,5A,3D,EA,15,86,9B,77,AD,67,07,EA,22,7A,44,B0,27,D0,58,BB,94,74,3C,9E,DA,42,35,E5,01,61,C7,44,77,F4,39,A4,28,08,3B,F9,6E,B5,BD,78,3E,C2,EE,45,0E,9F,A6,C8,52,B4,B0,A6,2E,94,24,4D,D2,3E,64,AB,F5,61,51,8C,70,F8,BB,16,CA,E0,1B,FB,96,1D,33,A7,20,3C,DA,BA,6A,A1,EF,A1,3E,33,27,F9,B0,55,82,E3,13,88,6C,17,98,39,90,CF,78,82,03,F2,F5,93,A0,52,DF,87,29,27,E2,EB,C4,EF,F7,FA,22,60,BC,6C,0B,BF,05,B4,AF,82,A8,87,0C,95,65,66,F5,F8,5A,3E,2A,D8,06,9A,A7,B4,64,DC,0D,47,65,B5,99,E8,53,AD,49,43,24,A0,9D,C3,1F,B5,FE,00,CC,7E,7C,22,6C,23,FC,2B,A3,A8,5F,BD,C6,05,D1,D4,27,7F,12,3D,94,4C,B0,9A,E9,FE,89,60,A6,30,C7,A2,34,20,13,E9,95,92,9A,B6,33,14,36,AE,D7,27,FA,2F,73,27,87,AC,87,12,35,7E,FE,CF,5E,AD,5C,D4,D1,DB,A8,42,09,35,25,28,2F,DC,AE,BA,F6,D9,6C,DF,40,D7,D1,3B,53,7C,F5,97,C0,22,0D,F3,0B,BA,AF,50,14,7C,EB,9E,99,AA,F3,23,5D,86,79,41,A8,71,1C,E4,ED,26,73,7A,D6,F9,62,B2,4F,87,25,9B,83,EC,6A,55,E6,62,AE,76,6C,0A,DA,5B,31,8F,38,0E,D0,45,22,97,78,FD,27,96,AA,56,4E,CF,2F,5E,3E,09,81,5C,2A,F3,82,5E,06,8F,8E,7B,6E,3B,4F,F6,95,9F,C3,6E,02,FB,95,3D,DB,EE,0F,A9,2C,37,0A,8A,91,EF,86,20,CF,FB,37,A1,8E,61,7D,22,9A,4C,B6,F2,84,53,FF,71,26,C3,7D,32,D9,2E,E0,C5,71,9E,25,2A,1C,DC,72,DA,B1,0B,47,11,23,07,65,EF,2E,0E,FF,AE,8B,19,8A,B8,EE,C8,E0,75,9A,59,F7,7E,D5,45,B6,73,5E,95,97,AD,D2,A2,41,CA,AB,A9,C4,F1,1B,E6,27,85,F0,64,4A,F5,DA,9A,79,ED,24,89,90,78,29,D2,C5,4A,7A,9A,DA,43,89,44,23,7C,3B,2D,65,5E,B3,42,BE,CA,BE,96,75,B1,7A,3D,C7,B4,15,92,55,B1,90,43,49,F3,E5,BB,10,0E,11,66,C4,FA,9C,A4,F0,78,BF,D6,B3,43,06,A9,FB,C4,83,D4,E3,C9,0B,38,B0,30,80,0D,29,1A,85,CD,90,FA,E8,3C,30,7E,46,4A,56,9F,28,F0,5A,3E,9A,15,BB,14,A4,D5,35,8B,C9,7D,24,DD,84,CD,3E,25,B4,0E,E4,62,B4,B6,4C,E4,E2,BE,56,AE,97,0A,06,26,A9,C5,95,37,77,81,E0,F7,05,8A,CE,71,C1,19,DF,11,E6,96,D7,B4,08,00,B4,86,64,0D,45,2D,02,2B,AB,C1,D6,4E,E9,BC,2F,56,99,B1,48,2B,C9,F2,59,1C,B7,2B,F4,01,98,C5,C4,2B,81,BA,1B,F0,06,9F,44,46,22,04,6A,BB,C3,95,AC,8B,48,C7,D0,D0,B9,1A,A5,68,9F,44,E2,ED,66,29,A3,AF,C2,08,9B,E8,ED,3F,6F,7C,79,0C,3B,FB,F3,5F,CD,81,78,78,39,7E,32,46,55,3C,67,9E,4F,EA,8C,69,C6,0F,7E,25,82,67,0A,08,FE,8F,32,08,16,E0,BB,3E,AC,4D,FD,0B,A0,75,2A,2B,DC,C4,6A,C4,28,F7,4E,50,E1,E1,1A,36,16,4D,01,71,25,E1,AC,A1,E5,30,72,69,6C,39,67,CA,70,0A,D0,D3,F2,1F,5A,C0,FC,B4,3F,42,A1,39,C1,57,BA,EE,7D,4A,10,A6,AA,16,DC,BE,CA,FD,69,B8,70,E2,7F,C8,9A,2A,BC,92,2D,2D,E8,16,B6,B5,2C,5D,6D,3E,CD,36,8D,E6,4F,63,79,1A,D3,3F,46,BE,BB,ED,A5,6F,78,AF,D5,2F,10,AC,76,73,E6,B8,C1,F1,4C,6C,97,7C,2E,03,DE,AA,D1,F7,99,FA,D2,2B,A4,C0,83,DD,49,B5,43,5C,D4,19,F7,90,EE,6E,3E,80,A9,E1,B8,C7,52,18,D9,CC,41,3E,03,1B,E8,E1,81,A1,21,53,F5,F4,65,9E,5F,BB,04,F5,B3,8E,9C,E1,55,46,0E,AD,F0,EB,F7,83,F3,96,7C,0D,2F,E7,90,08,89,02,B4,E4,87,EB,1A,0D,77,D2,66,98,5E,4A,08,A6,8E,F5,AE,31,91,54,E4,E6,BC,9C,33,D4,1C,E3,7F,06,2E,E5,A9,CE,5D,AA,78,BD,38,7E,67,71,19,A1,5C,23,CE,00,D3,38,9B,92,97,52,BF,14,B8,9D,B1,DE,85,2C,49,E9,21,10,27,28,66,98,FC,39,7E,12,20,31,4F,DC,9C,87,55,BA,85,B2,D6,7C,6C,5C,33,58,AD,22,70,D1,18,EA,F8,6C,96,05,6C,0B,AD,42,60,3C,B5,32,B7,16,59,A8,8D,FB,F7,61,42,C8,B7,2F,60,B0,50,1C,A7,7D,B9,19,B8,CD,28,DA,54,88,78,F9,EB,A6,FF,58,5E,43,93,E2,1C,FF,23,8D,E5,0C,2A,80,CB,EE,FC,03,53,5C,DF,64,4D,DC,CE,91,E4,16,CA,5D,7D,59,B9,6A,A2,E4,83,38,26,AC,47,E5,8F,39,AD,73,D0,F6,EA,BC,87,96,36,E4,F8,8E,78,C7,FF,C6,61,9B,12,CC,38,EF,16,2C,C8,96,28,06,79,E3,48,C5,94,97,9E,9E,80,A7,73,E8,05,65,B7,8C,D8,10,EE,B2,31,7D,AB,1B,A5,0E,42,25,D1,98,DB,A1,89,AD,B0,78,8B,81,FB,42,6A,03,62,D7,FA,47,B3,D3,7D,4A,07,92,1A,46,0E,74,A9,65,DF,51,07,42,4B,30,81,0E,C9,D7,1A,86,A0,C1,4C,20,EB,CE,DD,76,7E,0F,3B,90,48,42,AD,56,A5,82,63,27,A6,28,3B,8D,D7,33,7E,10,07,28,D4,47,9A,E0,EE,40,21,83,7A,FD,2C,40,39,4F,8B,17,0A,39,5D,3E,78,8B,94,F4,08,5D,6E,3E,55,D2,FC,DD,61,DD,EF,91,67,F8,4F,23,A5,DB,D2,B1,33,BD,52,6B,B8,62,65,8D,F7,ED,DA,C5,3F,F2,BC,52,49,97,D6,A1,17,19,5D,E3,CA,57,4A,0B,14,3A,F6,34,CD,89,BB,B5,7A,29,BA,CC,CD,E4,06,E8,95,CE,1F,CF,77,B9,7A,42,4C,6A,10,37,F9,B3,01,4B,7D,37,17,F3,3E,EE,9C,41,57,DB,F6,DE,78,F6,2E,A5,3F,40,8B,C4,E9,2C,0D,57,72,DA,41,D4,A2,B3,51,FD,CF,2C,4D,B6,A7,7B,21,EA,97,F4,10,67,FC,FC,7B,A5,28,69,DA,C2,2D,D2,1C,28,0C,85,D8,7B,33,5D,D2,6F,37,E7,23,28,CD,2F,92,64,DE,62,EA,CD,0C,95,0C,7F,60,C9,16,CF,25,1C,2E,D0,63,ED,AA,86,BC,E6,54,88,47,22,30,A5,23,B0,84,D7,0A,28,00,F8,E3,B1,9F,83,72,29,C7,F5,A1,46,21,1F,31,02,09,28,E4,5F,10,24,76,DE,1F,F3,96,CA,DF,6A,66,23,86,CB,D7,76,36,8D,81,39,E4,F6,16,70,39,1C,83,A2,A4,4D,34,10,E1,D6,5C,F2,E7,B0,3E,09,B1,45,F3,35,A2,05,09,B6,4B,EB,60,E5,79,AC,7D,87,BE,35,F4,F3,F9,33,13,05,BC,3C,CE,48,FE,CC,F1,3E,3A,BF,BE,44,B9,C3,67,32,37,48,9B,11,75,E4,0E,0E,89,EE,BF,8B,B6,39,49,45,82,C3,92,F4,00,44,51,5A,2B,08,AD,50,D5,23,67,46,B1,53,5C,01,28,7A,A7,8A,EC,76,8C,25,55,38,C1,7E,A6,A1,01,A5,C6,04,FF,33,17,E6,B2,B5,5B,E8,E5,23,99,04,8D,9F,75,77,49,1B,BF,A8,00,E9,C0,DC,3E,CB,34,2D,67,2F,26,0B,58,31,EC,22,6B,9E,0E,D0,AC,6D,79,08,26,09,6A,1B,C1,77,B0,24,0A,86,3A,B8,C1,66,69,58,D2,49,04,B9,A9,81,F0,C4,2F,86,3B,46,BE,D7,40,54,B1,5C,96,64,07,0D,19,FA,D7,B7,B9,EA,14,BF,1B,D3,F3,5D,FA,E1,4A,45,3C,5C,C4,E0,70,46,1F,A1,3C,86,CD,D8,9B,80,21,62,18,73,8B,4E,7F,9A,46,05,A0,24,41,B3,6D,B2,38,C7,DC,DF,BC,E4,53,D8,1B,C3,02,99,27,28,DF,89,EC,A5,C7,52,9D,07,16,7A,DC,FF,F7,03,0A,82,6E,C9,3C,09,DD,6B,0F,CC,9D,EC,FE,71,FA,C2,55,5C,F7,C8,66,AF,7B,61,E1,3B,65,1F,49,3A,D9,24,D4,3B,AC,59,6B,B1,3D,ED,3B,A3,2B,E4,6B,76,46,FF,D5,CA,AD,6E,25,5C,E1,04,14,83,E9,1F,2F,4A,75,85,0B,07,D7,7F,CB,08,5A,C7,84,47,83,17,B5,FD,00,C9,EE,31,24,EE,26,E0,95,93,15,CA,8A,4A,78,85,B6,81,0B,50,70,C5,38,21,92,D4,AC,B1,75,CA,B5,1D,25,76,DC,35,3A,31,7F,50,FA,BC,96,A1,0F,2D,E9,69,CA,71,A6,4F,E7,93,2D,70,53,07,B3,F8,9C,2F,17,CA,74,AF,76,70,B7,92,46,E8,06,2F,17,1B,7B,10,AD,83,42,EF,72,05,81,1D,1A,3C,AD,F0,F7,BA,57,A4,DB,98,91,06,FA,01,E7,50,5A,FA,12,2F,0C,40,F1,8D,1F,92,A8,75,1F,22,DE,97,75,10,1C,8D,60,AD,14,C0,8F,23,E8,E6,60,26,F3,43,82,2F,13,99,CD,74,10,1C,0C,51,2E,3F,73,CA,2A,76,60,28,29,C0,A1,16,1F,4F,E8,B9,E2,DF,AE,7B,A3,64,64,AA,98,6A,07,CC,8E,B7,C1,6E,9D,D5,88,43,4E,EC,05,CE,39,9B,C2,63,46,29,3D,FD,5B,11,24,77,DE,BB,88,E8,ED,22,C8,92,A9,98,25,60,7C,C4,85,73,54,C7,F7,70,7E,26,5B,DD,63,CD,F1,73,BB,7D,C3,75,C5,49,CD,30,A6,88,87,DA,9B,45,77,2E,53,AC,9F,7A,69,E5,EB,0C,4B,93,0F,DA,22,A4,57,66,CD,AB,8F,86,53,88,4A,73,A9,67,09,06,FC,D5,4C,A5,3B,2B,98,F8,CD,0F,43,70,BC,49,1F,CC,52,C4,74,3D,29,D0,8F,C7,76,D2,2C,45,78,D8,37,F2,7B,7D,A5,D6,BB,D3,1D,5F,FC,52,A2,9A,52,23,1F,1C,2B,A3,FB,7B,E1,90,3C,E6,3D,26,AB,E6,43,94,B6,1A,4B,BB,AF,96,0F,68,D7,42,48,81,C5,5A,D7,C3,40,A0,BA,1C,A2,49,AE,8B,14,02,5D,60,6C,C8,A1,BD,03,22,4F,7A,72,05,7B,5A,A9,A3,6C,10,E4,02,C9,BB,BF,07,11,E4,4E,BE,82,ED,E9,BE,24,FA,4A,DD,3F,9D,03,3E,96,54,F3,E5,69,63,E4,28,D3,FD,D6,C1,1B,C3,EC,8F,82,DE,0A,EF,34,6D,7B,AF,F2,67,EF,4A,63,C7,E2,55,8D,59,39,CE,7A,23,B9,75,10,53,6C,02,7D,44,F7,80,05,01,FA,94,E1,8E,D0,1D,A1,3D,6C,90,16,96,03,D2,FF,D8,F1,A9,D6,3C,D7,3B,1B,BB,8F,97,4A,AE,85,CE,6C,4F,26,1D,95,B1,4E,30,98,C7,2A,47,AE,AF,1E,15,F4,35,73,F5,37,06,B9,78,67,69,A4,FB,03,E3,62,3D,E7,96,2B,1D,2B,18,AB,22,37,46,19,D4,02,6B,91,0B,74,88,6C,8B,0D,19,1A,59,3A,79,CB,59,85,61,EB,52,BE,F1,05,5A,6C,43,0B,DE,26,92,D1,D2,1E,97,91,E0,F4,88,2E,9D,AF,83,22,03,69,51,A4,D3,FE,34,2D,C6,A7,49,60,69,2D,95,F2,40,C5,6F,17,5F,BF,63,D1,6D,EF,31,E1,42,F7,BA,FA,9B,5E,FA,69,E7,D6,6A,B6,DC,83,C3,6E,78,E6,6A,03,E4,63,C2,29,63,D9,94,93,A4,CC,B8,49,7E,11,4E,82,9F,3E,8A,C1,78,62,A6,34,0A,A3,DE,5D,E7,F0,EC,A0,3F,64,AA,FD,1E,4D,7F,3F,F7,F3,4A,35,E4,E9,77,A5,19,97,10,E2,2F,FD,DF,08,C7,26,E9,71,1A,77,8B,C8,BD,B4,23,AA,27,91,FA,E4,A7,10,54,D4,CC,1F,37,07,C4,61,5B,D4,29,47,2B,A4,6D,19,06,C2,ED,A8,BC,A3,27,4F,98,31,5E,5D,47,26,55,BF,59,03,7D,27,F9,59,BA,8D,5A,F0,9A,4C,33,DC,68,A5,5F,36,E6,C6,97,B8,79,3D,09,2E,5C,0C,C8,58,9E,0E,58,12,C3,A8,00,35,4F,8D,18,35,9C,C3,91,0E,B2,E9,BC,2F,D2,B9,DC,48,B3,F9,E0,70,A6,9A,38,F4,AB,72,72,78,3C,7B,28,7E,BA,15,AD,11,C4,E3,E0,EA,78,B1,DA,B0,B4,83,E7,60,4E,47,36,A7,36,D7,37,75,71,FA,8D,4D,B6,EE,02,21,80,9A,20,ED,A1,91,D4,0F,74,96,E5,65,79,A5,AC,41,1E,EA,9B,0C,40,06,5E,61,A5,19,3F,E0,D9,11,C9,E5,80,E9,C6,16,AD,5F,6D,08,78,BB,75,D6,91,A0,CA,E2,B9,D1,52,43,CB,17,E1,73,B8,F7,71,53,DE,46,E9,7F,2F,60,FE,06,53,92,9C,A8,A5,97,82,B0,AB,4D,72,D3,83,E8,D9,AA,78,CC,3D,8A,9E,62,7A,59,F5,0B,06,53,47,C5,54,D0,5F,26,D8,91,13,5F,E2,ED,19,89,6B,11,A3,85,40,8E,72,44,02,82,17,F6,7B,01,D6,02,0C,AA,E3,6E,47,6E,82,AA,AF,E6,08,E8,08,B7,24,8F,D0,A9,F4,1E,66,42,8B,BE,7E,A7,B6,A6,EC,FC,69,66,0D,50,AF,1D,50,EA,28,E2,9B,62,C5,CD,8D,0C,37,AE,1F,CD,E4,36,B5,56,07,B4,95,0E,DE,D0,BB,B0,EF,D0,0A,08,02,0A,FA,2E,89,DC,F7,7E,98,DD,45,7E,DF,41,1C,13,37,12,1B,B0,66,DD,E2,9F,9C,D4,AE,57,3A,59,DF,A6,2C,2A,E6,84,2E,7F,C2,4F,B8,00,DB,32,66,83,62,A0,26,62,49,A2,D9,69,F7,EB,5E,B1,D6,79,CD,F9,3E,85,A9,99,73,B6,4E,C2,37,FF,87,90,43,75,F3,D1,0A,52,BA,21,D6,46,3E,5C,9D,4B,ED,5F,13,98,19,8F,B0,78,FD,99,3B,CF,33,DF,05,54,87,4D,37,71,26,35,41,EC,A4,88,27,07,3E,F9,12,A0,DC,91,62,E8,9F,BB,00,D7,3F,68,77,9D,A2,10,46,5F,6E,F1,A5,6F,79,0A,5A,39,51,A7,96,BE,4F,6D,89,1F,63,77,0F,E3,A6,B9,55,D0,47,82,57,3F,6C,E6,3C,34,FD,6E,FD,06,25,A1,DE,0F,F5,C9,A3,C2,45,B8,BC,AE,EA,C1,D8,F1,9F,58,31,B7,3A,DC,36,AB,92,0A,67,20,60,58,22,9B,3A,4E,61,6D,7E,83,DC,28,52,18,0E,94,F6,51,5F,86,E9,8D,3B,8A,49,A2,61,D8,77,FE,71,D5,EE,28,FD,AF,FA,AB,F2,D5,25,83,D7,CC,22,1B,7B,30,D4,5A,3F,85,24,C1,3C,D3,D3,CD,57,10,19,67,7B,CA,69,FC,8A,F1,DE,6F,6D,65,8F,A3,99,97,46,70,E2,78,E2,FB,44,8C,E4,6E,E3,32,4B,B9,A7,4C,6D,4D,B4,A2,43,74,E1,51,EC,B8,D3,E2,4E,AB,34,19,C4,C3,45,66,B8,9F,05,22,A5,C1,7C,C0,35,64,F6,D5,E7,DB,15,E8,0F,C8,E1,99,21,7C,9B,05,E4,10,11,E0,64,50,41,DB,62,8C,B8,0C,1E,8E,F7,A2,4E,8B,8F,46,66,D3,CC,12,B6,36,F9,68,99,38,51,74,57,6B,AF,97,76,2C,23,AD,17,5E,31,3D,3A,A4,8E,D5,5B,71,D4,28,60,3E,B8,88,9F,79,AA,3C,5D,1D,7D,73,C7,0A,08,C5,F2,3E,44,5A,4E,FB,6C,70,D7,FE,AA,C6,91,01,63,23,FB,62,3C,AB,00,AE,21,62,88,C6,5E,23,9D,04,64,F1,AE,06,EB,15,AC,6F,5C,0C,23,C5,DC,B3,CF,D4,FE,10,98,56,E1,04,D2,08,AC,F5,28,05,14,DF,5F,B4,77,CB,B8,24,B4,F9,A1,58,E3,CE,41,65,FD,4A,BE,94,A5,4E,18,A7,E7,4F,C7,5F,08,ED,3F,86,8F,0B,00,4D,23,89,6D,36,7B,7F,14,53,DB,94,A2,F6,CA,BD,83,65,43,38,C7,D4,5E,A9,50,31,57,51,4A,2F,19,5A,3A,A2,E1,5F,F5,B4,A4,2E,3B,45,9A,CD,7B,55,9D,D4,55,12,CC,A9,E7,AC,4D,8E,53,01,CD,99,C2,60,79,B0,D3,5D,9A,C3,7F,B7,E4,9E,6B,EB,43,36,B3,68,FB,A1,19,D9,EE,69,E5,75,1F,23,A2,BF,E7,20,7D,B1,96,1C,13,5F,AB,F6,B7,6C,9F,E4,4D,86,C0,EC,9F,3C,4E,55,39,9A,52,1E,BE,36,DD,F2,C9,3C,D0,03,DB,F1,73,04,F7,D2,97,02,3B,71,9C,30,7E,88,61,8E,B0,BA,7E,2E,C8,5B,FD,4E,E6,27,4E,D4,68,B2,B4,29,E6,20,65,2C,03,73,83,7A,9C,F1,E9,FF,B1,F2,40,B0,CF,98,FF,E7,FA,6A,C8,5A,6E,CC,D7,C8,FE,A0,C6,3D,85,12,C6,4F,FE,0C,E7,CB,C5,18,C5,F6,4B,49,D9,E8,A2,69,19,2A,1E,2D,FB,5F,3D,24,6C,CF,8D,40,6B,99,C2,FD,DB,49,5F,70,B8,15,F5,3A,68,E0,71,3F,EE,CC,64,98,6A,BC,C5,EC,77,7B,0C,4F,81,B9,68,48,4E,45,91,44,15,60,D5,C9,03,3F,AE,82,84,AA,D8,54,D9,27,91,9E,D4,53,AB,61,DB,3E,5F,C3,5E,AB,C4,4B,68,95,A4,83,32,4A,72,6E,C0,EE,03,2E,87,5D,63,98,D4,3B,C4,F2,B1,C8,B7,4C,75,63,76,AD,F9,89,71,5E,D7,1B,27,54,6E,25,9D,1E,80,BF,80,C4,EA,71,27,C5,2E,38,A4,D2,B7,05,9A,57,3E,7F,7F,2F,E3,91,A4,A7,69,50,9C,9B,C6,F3,46,60,E4,ED,43,4D,E8,1A,5B,A9,D3,30,C2,44,A3,98,00,05,68,F1,50,1F,CD,3B,E9,C3,46,22,93,B9,FE,BC,1A,81,B2,CA,8F,0B,4D,6A,D3,84,77,82,52,98,13,D6,DA,44,41,63,B8,A9,AC,31,2C,66,C9,0D,8B,8F,99,A3,1A,7B,A7,C8,D7,1B,D3,9A,68,3F,04,E8,A9,D3,38,0F,18,9A,31,34,36,AB,F3,37,3B,CF,75,F8,A3,0D,A1,3B,96,57,0E,43,45,D9,BC,75,27,1E,92,65,CD,46,E3,54,F0,C3,34,79,25,C8,A7,47,85,D1,A8,E1,13,54,96,9A,BD,EB,67,1F,43,57,B6,B6,13,0B,78,12,E5,69,54,76,A4,04,8D,2E,1B,4A,67,E8,44,22,E3,7A,A2,A7,AE,C8,5F,2E,CE,15,46,A0,45,3D,44,95,DB,64,53,98,08,0C,3C,FD,2D,E4,78,D1,D1,50,E4,2A,9C,7A,A4,EA,97,50,B7,81,FD,58,96,D2,0D,B8,69,CD,8A,8B,51,73,1A,55,FE,6F,7C,CB,C0,8C,03,EC,51,AC,D2,89,06,BC,75,AF,FC,56,D1,2B,A7,51,26,3B,06,C1,43,02,4F,2A,8C,9F,6F,1F,33,45,0D,0D,88,99,77,35,4D,2B,C2,4C,C6,BE,BB,CE,64,82,9E,F9,8A,00,63,F4,D0,6F,D7,F8,00,98,F7,8D,9E,30,77,D2,FC,5C,CB,24,F0,11,34,2C,E5,0B,05,A0,A1,7F,A2,74,37,4C,85,F8,E7,61,5E,9F,46,55,76,E8,A6,23,F7,4A,27,61,CE,13,77,0E,7F,5D,93,7A,75,C1,FB,E6,6F,4A,F9,30,01,0D,83,1E,56,18,93,AA,91,3A,8A,89,5D,17,A1,81,85,1F,A0,FF,2B,AB,BB,7E,31,B8,39,1B,7C,E7,1E,58,3A,3D,31,25,71,22,8C,15,45,06,80,22,D6,18,88,C8,74,98,CA,EB,52,99,CE,94,44,EE,FE,57,95,F2,BE,28,B6,B0,7D,86,49,72,71,C3,B0,14,25,2A,37,DA,1F,22,E2,46,D0,3F,C8,E4,60,CD,AF,A3,6A,2B,54,65,6D,E2,88,7B,33,22,B9,46,8A,BE,55,F8,A7,A1,FD,A1,CA,51,36,2F,22,25,B8,D9,49,F8,BD,AF,C1,71,3F,F3,C7,F6,97,95,38,B4,A7,6B,C2,5C,C7,9E,4B,10,56,AA,13,C2,9B,B7,77,92,83,D4,04,4B,22,02,2F,22,42,A5,4B,97,1B,7D,E5,99,F4,BF,AB,53,FD,97,D4,43,8E,0E,CF,64,F0,50,66,DB,0C,1C,67,17,BD,39,C0,12,77,26,EE,4B,DF,48,89,9F,E0,08,61,2E,4D,42,D6,1D,6C,8D,13,F5,3C,30,12,9E,67,09,00,C0,5B,64,07,BE,81,7C,48,55,A6,41,FD,5E,70,77,2B,E3,41,68,DC,C0,B6,3E,A8,F5,BB,97,2F,22,D4,28,B2,64,69,2B,CB,C0,4A,91,48,42,58,36,21,1A,14,C9,79,EB,41,A9,FD,1C,29,96,D6,D6,64,0B,E7,70,42,02,31,5E,2E,10,45,E3,2D,6C,8D,A3,C0,9A,6D,32,54,CA,83,16,BB,E6,02,F6,1C,40,CA,30,E3,BB,E4,1C,23,9C,BD,D9,0B,6B,CC,E6,3B,C4,27,36,86,F4,D6,02,61,B6,F1,3B,EA,6D,13,56,59,10,B8,DA,77,4A,DE,CE,DC,AA,F4,A0,6C,6A,21,85,17,34,61,ED,77,79,F9,8E,00,5F,89,A0,FD,38,4E,D4,B9,0E,1D,F7,59,DA,0A,97,44,7D,EC,AE,CF,2D,44,49,9A,88,A2,FA,91,4B,3A,0F,19,A8,70,54,B2,47,84,03,6D,08,E6,09,D8,56,35,C0,3A,7D,E9,68,72,05,F5,95,9C,4B,75,EE,0F,13,5C,FC,56,3D,E4,BA,67,48,07,F7,D0,EC,4C,FC,4A,E1,D0,D9,72,5E,41,1F,9A,11,81,F6,FE,90,71,12,F8,77,FD,8F,4B,15,C5,83,51,F9,7C,74,44,85,D5,E4,F0,41,24,9F,7E,14,39,32,4A,F7,A7,78,5F,CB,23,F0,3D,14,57,6F,55,18,9B,96,33,E2,2E,CA,54,BA,8D,86,33,88,AF,D2,73,85,48,FD,7B,78,08,7A,DD,75,7E,82,7A,9D,80,46,C3,62,95,B0,0E,5A,28,8A,D5,AD,5B,D5,3C,F1,68,60,67,9F,47,26,23,48,B6,B7,F9,E2,EB,B3,DB,54,35,2D,A9,34,A2,79,1A,90,91,8C,D5,67,E9,41,0D,F7,10,F3,EF,2B,BA,AD,DE,3F,EB,66,D5,C9,EA,59,1A,60,7E,F5,7C,95,E0,A2,4D,45,99,26,28,DE,66,C0,0F,51,14,83,10,3E,02,82,B0,A8,E0,96,55,DE,D8,D3,3C,8E,64,47,9D,AB,E1,95,B3,73,39,F3,B8,0C,E7,20,41,F3,B9,72,1D,4B,41,68,93,03,30,96,A7,D8,00,DE,FC,3F,26,D5,3F,50,3B,08,DC,4E,B3,7B,50,FC,DC,29,EF,47,B0,0E,ED,A6,32,CE,A9,D3,54,68,29,D3,50,8A,DD,E2,8E,18,51,31,36,00,D3,2B,BD,15,3A,8E,96,2F,73,13,C6,5A,6C,F8,AC,C2,99,BF,03,7A,31,62,C7,E4,28,EB,9F,EB,FC,C6,3C,E5,9D,16,81,09,82,A2,A3,61,F0,16,0E,4D,DB,66,B7,D7,5B,35,C3,49,30,67,18,D8,42,D8,AA,61,36,41,EA,E1,57,72,DB,8F,71,FD,DA,A3,C1,19,54,9D,56,EA,07,1D,A7,9D,91,44,69,3D,82,68,60,80,C7,53,0C,C8,5B,95,F4,30,B0,48,83,33,5F,AC,A9,64,CF,65,00,EF,1A,B4,D6,A1,1D,3B,59,C8,ED,59,93,B9,77,89,56,02,F5,6A,65,DB,58,05,88,9A,25,14,68,B9,7A,3D,A2,40,32,64,D8,B8,1D,CF,F9,E5,EA,0B,88,CB,12,20,A2,C6,88,57,A4,A7,4C,55,FE,34,37,E3,C4,96,B7,E6,31,D9,F2,0F,3E,FF,89,DE,ED,C5,F3,6D,EF,52,00,E2,F9,D7,0C,35,BE,0B,A1,E8,1E,93,0D,0A,31,86,C9,AB,A4,F3,51,6E,6B,D3,BE,82,FB,B5,FC,30,99,AD,CF,CE,EC,7E,CC,DF,6E,06,5B,72,B1,06,7D,55,5B,87,7B,DD,80,99,D4,75,DD,03,AA,C6,CF,EC,46,00,D6,64,4A,49,4D,85,CF,BE,B2,8B,A1,85,EC,77,14,CF,D0,1D,6F,38,AA,7A,2C,C9,C3,26,9D,76,22,A3,50,1E,02,A1,AE,4F,ED,FF,B9,B2,D7,ED,4D,36,57,82,A4,FD,18,F6,7C,94,DD,46,0D,89,BA,8A,D1,06,C6,33,FD,CA,28,D7,A7,E5,33,45,15,59,30,7F,FF,1D,2A,C9,D3,F7,25,D4,18,F3,1E,22,BF,CC,FA,E9,B1,B5,7E,AC,B7,32,4A,1B,F5,93,69,AC,98,91,34,52,49,90,D7,3A,E0,50,5C,B1,B5,A6,4A,B8,60,F2,76,64,3A,80,1F,CD,D9,EF,7B,9E,EC,1B,1C,CA,0D,A6,CF,4E,77,D6,A8,21,CB,3A,BF,A4,A2,56,CF,FF,53,71,E1,C2,29,80,CE,B4,A4,03,79,12,89,92,C3,93,43,59,9A,FA,EA,92,5F,18,70,0D,AC,54,82,A3,D1,62,A2,36,DD,2D,C8,AC,A0,0E,03,C9,9C,F6,49,83,DB,E6,96,23,7E,34,A2,CF,61,05,4A,19,C4,CF,48,68,8D,2A,04,B5,2F,DA,80,F3,7B,01,4E,00,6D,D5,80,55,F4,74,F8,DA,FC,1D,60,E8,6A,2A,CD,F7,1D,17,BB,6C,3C,07,10,38,7C,64,32,FF,E7,12,7E,AD,7F,27,AB,0C,30,C4,BF,42,0E,93,9A,CF,4E,62,BB,E9,76,72,92,EC,2C,17,6C,C5,A1,0E,C7,83,0E,A8,A6,66,7D,F5,C9,19,7A,55,7F,61,D4,0C,8A,6B,72,D1,93,66,D8,91,D3,46,B5,41,F4,D1,07,63,E4,66,08,D1,6A,A8,5B,06,86,77,FA,83,04,BC,7A,ED,30,D8,2A,25,E1,1D,C1,46,1D,99,A6,6A,8C,FE,AB,13,3C,8D,90,82,AC,31,3A,4D,32,0D,60,D7,3D,50,D7,2B,CA,53,49,82,49,7F,2D,0F,B6,20,C1,83,93,75,40,FB,53,FB,7A,30,89,A1,1C,ED,EC,C8,94,E7,2F,39,91,C4,B2,B7,F6,2B,F1,70,52,78,C0,D9,1E,EF,22,FB,02,D7,DA,7A,4F,AB,E4,E3,79,4E,8E,D6,CA,59,61,35,8E,B6,CA,83,5C,B5,82,6B,46,9C,35,5F,30,50,27,91,EC,1C,CA,74,20,8E,8C,20,5F,62,A3,DD,B8,18,1F,79,45,D4,7B,1E,5D,48,9D,95,CF,B6,89,E7,FE,3C,03,8F,5E,A9,91,E9,31,5E,85,69,80,50,F2,91,AB,D4,EC,E3,A8,00,1B,8F,3D,77,D8,E7,0A,E5,A8,7D,D8,EA,3F,62,75,8A,1B,94,1C,2E,19,67,6D,43,3B,7F,3C,A5,64,46,CC,F4,22,18,5D,58,A4,38,0E,E0,76,09,2E,3B,B7,94,CE,43,3D,47,70,D5,17,22,19,DB,03,94,E5,F4,A0,1B,A8,AF,7F,83,B1,04,6D,EB,B8,F6,BF,71,0D,2B,EA,70,CA,F9,07,FA,F4,6F,19,AB,C8,98,46,F2,32,2C,F1,7A,3D,38,33,5B,AB,EF,9E,15,78,CD,13,C8,5E,25,BC,40,30,96,15,31,73,1B,71,C5,46,48,5C,C3,E8,FE,22,F9,D9,BE,1F,92,EF,18,88,D9,D1,DD,6C,16,7C,8A,19,39,73,E1,45,8E,7C,67,09,7E,F8,EA,D9,CA,42,24,41,86,EC,1B,16,1A,C8,61,5D,D9,FA,E9,C7,67,D2,F6,46,AA,ED,19,DC,39,9F,5C,19,0F,79,A1,68,46,20,C5,3E,A5,79,24,E9,C4,5B,7C,4D,E3,54,59,13,E0,7A,11,C1,43,7C,6A,CB,48,73,0C,E7,EF,60,CB,DA,05,60,35,E5,09,B7,FE,5A,0C,C3,CA,F5,86,AD,5E,9A,C1,F1,B9,6D,98,EF,3E,C0,AB,89,55,8A,71,60,A2,C6,73,11,23,28,E7,49,68,C1,3F,A0,F4,2F,93,6D,80,47,22,CD,1B,E3,4C,F6,89,B4,43,9D,EE,E9,F7,86,A3,01,47,68,0F,C2,1B,02,21,94,5C,FD,06,EE,1F,65,DF,47,E1,6D,73,64,75,4A,F4,76,8A,82,91,F0,B9,1A,A5,10,49,45,1D,8A,60,11,45,B6,5E,86,B1,10,C5,36,1F,B7,49,10,AD,D4,01,58,73,BF,DF,11,5D,74,E1,5E,B5,4B,CA,6E,F1,FA,F1,00,3E,67,EE,E5,B5,EB,F9,28,D8,96,4E,F9,5E,A4,BD,E1,80,FD,5E,9E,F9,4B,38,34,AD,33,7D,0B,9C,B3,68,13,28,E0,82,56,20,ED,80,3F,62,66,56,5D,36,1D,2E,36,CC,AB,E2,CC,C9,F9,5F,9F,E9,67,C8,FF,F3,E3,7C,97,FD,79,8A,21,50,78,4C,2F,3F,80,39,8D,29,3D,77,FF,27,48,44,F2,85,74,32,0B,BF,E7,C1,D2,48,E4,5D,06,F6,78,D1,CA,8C,64,34,E4,B0,ED,6F,5A,F9,22,12,CC,BA,06,47,F3,F1,64,22,70,7D,B0,07,65,66,E5,DE,B5,A2,8D,43,88,88,AF,B3,B9,10,10,5A,99,54,45,9D,E4,F0,2F,E0,B8,89,62,68,52,2D,D1,1E,69,EB,3A,D0,5A,DD,C2,68,83,76,14,AF,BA,52,73,40,BE,1B,FD,5D,37,0E,76,55,09,68,AE,E1,DF,58,58,39,F3,24,A3,9D,61,FA,76,11,D5,1E,B0,63,BE,99,F6,CC,30,E9,DE,0B,F5,21,83,0C,D4,97,3A,75,A2,D9,D7,D9,C3,A1,BF,D4,92,F1,F4,2C,01,A6,F9,4E,FC,99,80,32,ED,17,37,18,50,48,2C,4B,AA,47,6B,BC,DC,59,C5,AD,63,4E,2E,40,F0,E4,A6,E6,EA,CC,F2,C2,DF,63,F5,FD,1A,94,BD,24,9E,42,69,25,92,DE,AC,0E,76,6D,F5,5E,B6,AD,4B,25,38,9B,61,50,9C,B7,5D,48,34,6E,7F,3A,D0,C3,43,67,B1,A0,35,4E,BA,2D,81,99,D4,2C,1D,F4,47,15,4A,C4,F9,1C,11,AB,C7,46,BF,49,5D,B6,E7,B1,9C,AB,6D,1A,40,60,94,37,9E,3F,70,A3,B1,35,58,2C,5D,77,8E,F3,1C,14,6C,B4,36,67,3D,AF,29,42,2A,50,3F,78,C8,97,7E,7A,BE,14,5C,88,72,0A,B1,B0,67,36,AF,03,75,46,D2,91,2F,E0,4D,34,F0,01,D2,53,15,81,6C,39,72,70,30,D8,15,E2,E0,50,CB,62,30,75,01,27,64,22,8B,8E,01,BA,F7,DB,94,05,B7,C5,02,86,2A,C8,49,45,91,E2,2C,D1,38,92,A7,50,50,31,F4,6C,84,3A,98,B4,58,E6,6C,A8,67,8B,51,C3,61,08,0E,78,16,07,D0,BA,6C,89,F1,2B,FB,54,3A,DF,AF,60,78,21,5C,3D,5A,24,E2,DE,99,D6,9C,FD,A3,89,7D,15,4D,9D,7F,61,3F,78,60,0B,C7,87,03,52,23,31,D8,6E,9F,CB,E7,F0,6C,F2,88,3F,2E,1D,75,72,D6,C6,E6,0D,E4,7A,09,2F,AC,08,F9,8D,AA,81,DC,01,FA,70,71,2C,EA,F3,4F,92,27,87,0D,3B,70,7B,39,F0,06,44,ED,34,05,15,F5,B6,75,21,F6,8E,FC,E8,B7,3A,6D,E3,0A,6D,3A,0E,79,30,3D,21,B0,2C,52,86,E5,6E,49,A3,C2,40,F7,80,EA,EE,C7,A1,F5,8E,D1,F1,8C,6B,9A,A3,2C,00,05,53,1B,BC,B0,BD,37,A1,95,BC,B7,5C,87,EA,51,22,CE,44,30,B5,30,D9,F4,1D,10,0E,77,C0,42,32,7D,37,70,CF,1B,59,B3,21,D8,CC,59,3A,42,7F,4C,5C,91,4D,8E,61,00,03,BD,DD,86,FC,93,0C,A2,6D,2E,9D,22,ED,5B,51,5F,2D,03,25,56,DC,04,90,CF,BF,FA,57,19,E5,76,00,01,DB,F8,32,90,C4,66,B3,0D,1E,95,FF,07,05,22,FA,32,C4,4D,AF,2E,77,A6,0E,4A,96,50,83,C4,53,66,5D,F1,0C,BD,D3,10,EC,A8,CE,DC,8F,0D,05,18,CC,B9,AA,C6,FD,8C,70,82,10,52,45,CA,95,B9,2D,8D,CB,35,DE,45,E2,21,A8,EE,76,60,A2,1E,C3,39,2D,78,3C,DC,85,D4,87,23,7E,D2,78,05,21,38,AE,CE,BC,44,AD,57,AC,73,84,99,81,8D,2D,14,B2,70,6A,33,CD,79,DA,CE,9E,D1,0F,28,C2,EF,19,B9,6E,78,0D,0D,AE,E6,A3,F2,6B,D3,A4,1B,0E,A8,8D,28,FA,0E,7D,F4,96,E9,39,E1,D5,16,68,AE,1D,A7,BA,D2,1A,E0,25,BB,E4,44,1C,1F,71,7B,C4,9A,EA,F8,75,38,C3,16,14,8C,83,00,48,04,5A,D0,F2,3B,09,1E,5F,AD,CA,FF,AE,42,94,D9,3A,57,13,C8,27,66,92,B7,8D,98,29,46,E6,2B,28,B3,C2,57,21,09,9A,AD,51,39,D0,17,87,39,D0,A5,3E,C4,7E,80,B5,33,E4,76,29,0D,91,91,78,05,57,62,AD,D5,E6,B9,2B,49,AB,AD,94,8A,BC,EE,53,28,F5,9C,6F,F7,3F,47,27,E3,33,4A,D3,69,D9,B8,DC,88,EB,08,26,EA,AB,D0,05,8B,E9,25,8D,0F,E7,69,53,56,A5,70,FE,F6,67,9C,AD,63,BA,07,DD,53,C8,74,A5,0B,77,F1,31,06,F2,61,FF,9B,4E,BC,48,B2,79,2C,63,65,77,74,E0,61,FA,00,32,D6,CD,20,DB,DA,C9,D5,AA,38,F2,94,B7,86,A6,B4,F2,97,76,FE,48,45,83,83,6F,87,9D,CD,77,B2,BB,F3,11,D4,52,61,F9,BB,99,8E,B4,6F,48,25,75,01,2E,54,CF,55,83,8B,85,03,7A,F5,3B,1F,94,A0,B7,DB,52,DB,67,13,21,C9,94,4D,6A,57,60,C6,6C,9F,02,6C,CC,2E,87,19,3E,48,A4,36,E4,01,93,80,48,CF,78,05,2E,60,2E,86,D1,68,77,E8,7B,D4,63,E1,7E,17,86,EF,4F,C9,79,D8,4F,B9,4A,E8,40,05,7E,47,9E,D5,48,88,21,04,84,BF,91,4A,FC,87,E2,EE,61,5E,19,2A,17,C3,7D,1E,E4,8D,72,1E,AB,8E,ED,E0,5B,43,80,96,88,EC,83,33,84,7A,68,09,FF,56,08,60,98,9C,1C,FB,19,D4,90,B3,6B,46,59,C3,55,CF,91,CE,D2,F6,F1,8F,F3,D4,B9,B6,69,52,09,64,79,90,22,07,61,83,CB,C6,77,02,E9,40,E3,7F,15,C5,A8,BA,21,5D,FD,64,67,2A,43,54,66,CB,84,44,F6,05,1C,8D,0A,FF,56,DE,01,CD,AF,13,7E,DE,EF,35,14,1B,D8,37,9D,9E,FC,D0,D6,4E,FD,44,50,4C,2E,43,C5,6C,47,EB,EB,3B,73,D1,43,F3,B5,4A,9C,42,91,AF,A5,6D,D0,72,34,DC,59,28,4A,DC,DF,0F,11,00,61,58,59,FB,B5,8C,8A,48,85,9B,36,96,16,C3,96,91,E5,C9,1C,1C,13,49,71,4D,91,D8,B9,95,F7,B7,4D,72,06,8D,C9,52,D7,EA,6D,48,10,61,66,E4,7B,0C,35,90,5C,64,84,A2,BF,E8,13,EC,D3,1F,77,25,75,63,8A,5C,65,9B,F8,B0,63,63,AF,02,BB,D0,B0,4A,25,DB,82,A4,00,67,5D,FC,97,A7,3D,0B,F9,64,E9,16,21,EA,29,9D,57,F4,ED,F7,DC,7E,2D,C7,61,CF,7C,BA,AB,BC,FC,67,F1,A3,0B,47,06,09,38,7B,C1,D2,E2,AF,62,65,45,6F,F2,B6,09,00,29,CE,6A,7E,3A,78,8A,64,35,73,BC,D1,B6,29,A7,41,AB,F8,21,B5,9A,64,19,4E,FC,5B,A0,76,A4,BE,74,91,07,EF,81,A5,97,7D,47,F9,C5,5E,C9,0C,5D,B2,CF,6E,9E,B0,B8,5D,8B,D8,43,14,F2,59,BE,DB,7A,3D,6F,27,AF,43,53,78,C8,C0,0D,AA,C6,29,27,99,3C,4C,05,67,6D,E5,B6,CD,03,A3,99,AB,F4,92,FF,89,22,18,9A,C1,E0,4F,5A,E5,09,3F,B2,C0,84,E7,F5,F9,87,F7,2C,7F,F9,07,B3,50,C1,8E,24,E5,04,64,B8,BF,E1,2B,AE,55,49,CF,90,2A,AE,59,25,AC,62,72,DB,55,68,66,DD,99,F6,20,FA,44,8B,FF,D3,B0,48,AD,FC,66,CB,C6,0D,04,05,47,34,E5,D7,B6,7E,D1,4B,58,12,76,9B,0D,6A,24,69,F6,E5,0B,4E,7A,A4,E5,1F,AD,AE,23,A4,D8,FD,50,D2,0B,44,A2,C4,68,BB,DC,30,F9,B4,DC,D0,1B,A9,4A,94,90,D9,F4,2F,55,56,A9,96,26,8F,72,2C,14,9A,AD,F5,D8,57,FB,A7,0A,FF,0E,E7,C5,33,C8,FB,61,CB,E3,03,D8,A0,D3,54,3D,8D,E6,84,1A,70,4E,DF,95,87,A5,33,C4,91,5B,08,3F,8E,0B,96,83,5C,4E,2F,49,ED,98,55,1D,02,18,B2,08,A0,22,7C,11,3D,C0,C4,9D,C0,06,BC,AD,8D,CA,56,23,78,01,EF,01,32,0A,2D,85,B4,9B,6A,04,08,C1,74,A4,96,B9,18,41,9A,A9,53,15,7C,CA,7A,F8,51,D3,B5,D9,21,EF,64,99,45,11,95,CE,46,4F,3A,4A,1B,32,B9,A2,53,B3,FB,31,4C,43,94,0E,00,F9,84,BB,CD,04,40,87,24,70,87,10,BC,98,04,01,60,35,E1,53,F2,23,EE,93,F1,84,76,0E,93,8A,84,B2,0B,73,8F,68,FA,DF,EB,F4,F1,AF,4A,27,5B,8E,A7,CB,76,CC,A8,89,C7,33,50,1F,47,A8,93,53,72,C9,C6,D4,49,8F,0F,57,F1,25,5B,F0,13,78,A9,4E,2A,BD,31,DD,4F,BF,89,08,BD,12,53,B5,9F,E2,C2,15,E6,09,2D,AC,36,25,EB,DA,4C,B2,28,59,21,EE,5F,63,79,B0,BD,C5,7B,DB,E0,DD,26,EF,A9,9D,83,F3,04,5E,08,E2,D0,F4,8B,68,0F,C8,7F,84,0D,CE,A9,B2,2A,F7,4D,6D,1A,B8,0D,5A,E4,60,D3,04,BD,38,1F,72,23,46,D7,F8,66,A2,20,B1,7A,B6,94,42,A4,04,85,14,CF,CA,AE,8D,D0,12,13,AD,A8,60,F6,F2,54,A5,DF,BD,CD,65,33,5A,FD,65,16,11,6B,25,10,7E,94,98,8A,34,2D,7A,1A,D2,8B,B1,D5,EF,B6,7D,F1,62,A2,61,1B,85,55,7A,CE,32,A7,FA,AF,A9,E4,4B,09,C3,27,3C,32,BC,B1,9C,A2,07,FE,33,B0,85,0E,DD,B4,D2,7C,F5,00,A5,70,69,59,EB,D0,62,DD,37,27,F8,24,68,34,91,43,78,02,B2,F5,FB,C4,E4,F1,14,5B,AE,A5,1F,DE,A4,2C,D2,02,75,8B,99,7C,58,DB,F8,7B,A0,3C,4E,E1,7E,12,A5,82,9D,BB,A2,8F,B7,96,56,5E,FE,34,C2,DE,72,14,51,6D,CA,E0,F7,AC,E3,C2,1A,4C,6C,E7,DA,08,6D,04,1A,C1,63,63,79,D9,0A,19,85,43,C1,FB,10,DA,44,CB,AE,B0,60,DC,3F,0E,9F,ED,60,B1,97,C6,0B,4F,F3,69,9E,9D,FA,95,EC,06,CD,D3,CE,D4,D0,5B,0E,EA,E4,CF,9F,26,49,FA,02,42,5D,1C,B9,71,A0,93,CD,12,38,61,FD,9C,E2,8A,4C,27,FC,66,C0,74,02,E5,8A,05,1F,94,56,5B,B7,5B,B8,53,EA,DB,75,BD,CA,24,04,F9,35,B4,FE,B8,B9,EF,28,C8,83,B5,F8,41,F0,2C,54,03,E7,A6,E0,94,1A,D3,91,D9,1A,25,F5,58,F0,10,1A,70,9D,90,32,56,04,94,12,F4,01,B8,DA,E0,C5,44,D9,99,F3,A5,45,FD,AF,88,E3,E4,04,97,C2,71,47,4A,A9,5D,FB,C9,BA,9F,E4,EB,A8,2B,83,15,D4,36,F3,44,EE,7D,81,39,22,D3,B5,95,49,84,73,AC,75,12,15,33,A3,54,DB,4F,CE,37,E0,E2,19,5D,B0,E2,D8,CF,57,22,87,96,BA,13,FE,94,03,9E,11,0A,03,C6,95,13,B9,47,7D,BB,57,D6,E0,ED,81,A7,E6,8D,09,62,EB,B7,DC,85,61,DE,E8,51,26,70,B2,EE,1A,8B,6C,EA,32,6A,80,1A,05,A8,CF,03,B7,C6,89,2E,6E,29,3F,F6,1A,E4,06,1E,3B,55,C0,12,D5,E8,4B,36,DA,28,90,EE,6F,C6,37,6F,B0,43,A2,8F,57,81,6B,AB,38,33,74,76,EF,B8,3D,82,78,8B,30,1E,3F,83,E5,52,37,F1,0B,91,C6,7F,BC,CA,F8,EC,13,9E,2D,C5,65,74,87,DF,74,70,8F,6C,83,1F,9F,31,51,E1,87,75,BB,C4,B1,0E,06,45,89,28,01,BC,EF,E7,37,D3,F7,D3,E0,25,79,FC,41,85,36,8B,46,F5,C0,DD,52,CE,5B,DD,54,84,F5,C6,1A,F5,36,24,D7,67,83,FD,F3,CF,09,04,BE,B0,D4,9D,28,58,F7,10,9B,84,50,1A,9F,BF,5D,D0,27,9B,4E,36,FB,A1,DD,10,A3,1A,99,A7,35,60,2C,EC,58,7E,25,4E,5F,AA,78,A3,6B,80,39,95,6F,27,48,C4,7B,2E,4E,48,46,3B,49,FA,71,A2,D7,39,26,62,30,21,B6,20,C3,78,65,42,C5,13,CB,74,DC,FF,CD,5C,0B,EB,BF,83,FA,38,AF,12,22,B9,B6,CE,3A,96,09,D4,80,8D,EE,36,34,65,78,C6,A0,B4,1B,65,BD,3E,F4,8F,4F,4A,D2,41,E9,83,21,67,51,DB,24,9A,13,7A,F9,EE,89,63,72,F3,08,1B,CD,28,A4,58,B6,8C,C0,22,1C,0F,E6,31,E8,55,A1,8E,A4,1B,C8,27,64,0E,51,B4,D7,3A,5E,7C,B0,3C,0B,AD,8F,57,72,90,88,B6,B0,6A,B4,5F,0A,EF,21,FF,3F,43,B6,31,F7,0A,37,38,22,3A,7D,C6,3C,AB,D6,59,4D,F3,39,53,83,FB,88,96,9B,2C,C1,00,D6,CD,72,38,3B,04,BF,36,0A,24,39,5E,3A,35,DE,81,33,12,F8,F5,D8,B7,8B,87,9B,44,44,13,AA,EB,25,F5,DD,81,3A,84,E7,22,BB,EF,7A,8C,75,65,CE,BC,D1,D5,DF,67,9B,09,C3,E2,9E,58,9F,38,21,69,98,20,AB,7B,CC,EB,A6,83,D1,60,9F,9A,B4,14,63,98,04,FF,04,BC,51,AC,2D,2E,13,F6,D9,60,CD,75,C9,6C,F7,35,CA,DC,A0,F4,8B,93,A9,D4,3D,F7,43,FB,4D,13,C0,9C,10,D6,98,17,DB,2F,91,72,D1,3B,FD,C1,EB,AD,E5,D8,F2,D2,BF,FF,69,CC,10,A3,56,BC,C7,12,CD,33,F0,95,B7,B0,1B,49,47,3D,6B,8C,80,78,F8,AB,D2,5C,11,5F,0D,32,82,37,EB,D0,88,46,FA,8B,4F,2E,DD,CB,E9,78,F4,EC,25,0C,0E,EF,3D,78,26,B9,91,54,A3,95,E2,5A,6C,0B,1F,5F,42,BD,F4,79,6F,2D,95,61,E2,1C,92,EF,1A,24,15,22,41,2F,78,58,41,51,71,32,04,C4,60,BF,6F,3A,25,F1,BB,5F,CA,FD,AE,F3,64,DA,16,0A,F3,0F,B6,31,5D,06,F0,D9,F3,B8,C1,EA,3A,D3,B0,9E,01,EB,29,D7,72,5B,AF,22,50,59,5F,83,E8,6F,0F,87,F1,90,F3,B5,ED,9E,F3,70,47,77,BE,35,FC,31,6A,A9,FF,26,A2,38,9D,4D,79,A4,AA,F6,50,F7,8C,C4,59,6B,16,18,2D,4F,F8,00,AD,9A,8B,C8,24,DC,57,CC,80,0F,D0,6A,9E,A0,13,DA,27,61,3D,2B,1E,35,9A,2C,0A,38,9C,B7,41,4D,FC,D1,0A,AB,85,BC,F9,AC,26,0A,11,9C,07,FD,B5,8B,C2,09,21,07,D9,7B,D9,1D,99,8A,E8,C4,8E,7D,02,B7,A1,64,70,6A,40,F6,17,03,98,E4,AA,47,0B,BD,63,EE,1B,47,75,04,BF,1F,22,E9,C6,D1,64,E6,3A,0B,4F,C6,8F,12,A4,10,99,20,60,9B,B7,D8,F3,02,86,9C,7B,BE,26,D9,F6,4C,BB,35,0B,F5,A4,CB,45,F5,BB,C4,43,7D,39,1A,16,A7,F5,FB,24,27,0B,A0,4B,8D,2F,45,98,1F,42,71,D6,73,15,5B,F1,71,E3,4E,2C,B7,4A,A1,6D,0F,99,38,71,4D,1E,5D,C8,F4,03,BF,B6,20,C6,27,D9,25,EF,A8,02,FF,56,FA,14,48,B3,C9,AE,05,23,87,68,D3,F1,00,78,6A,6A,3D,22,FE,6F,1A,38,71,51,96,11,76,4C,53,BD,16,56,58,FB,42,3D,33,0D,DE,D1,37,D5,D9,9F,C2,32,73,55,FE,D2,26,CB,37,6C,F4,21,8D,20,91,25,AA,A7,55,61,57,C0,34,F3,45,55,DA,53,F8,67,36,2C,07,AC,7B,A8,A0,B9,28,1D,5B,90,53,C8,90,4D,E3,88,44,E4,0D,9A,95,BD,4A,38,85,86,6A,FA,87,6B,5F,F5,A8,38,B1,64,E1,B8,39,96,95,1A,FA,6F,FD,7C,13,DA,61,EA,93,A1,E9,27,14,30,B1,2A,30,31,DC,F4,97,12,56,CF,12,09,7C,F8,B1,65,96,9E,11,3B,18,64,32,CC,6F,A9,41,73,31,E2,23,96,0E,DD,EB,6D,05,CF,6A,16,DD,18,26,1E,57,05,D0,8F,F9,EF,8C,93,F1,87,DC,36,8A,EB,D1,63,9C,45,31,1B,0E,A3,BC,EE,EC,59,48,C8,32,22,B8,13,93,33,A5,22,19,EC,03,D8,6A,00,68,59,3E,83,5C,9D,45,35,9C,D1,06,4D,1F,A8,1F,70,F7,D0,45,46,AE,45,08,17,FD,28,1B,D1,65,E8,B8,C6,0C,E8,8A,B6,B7,39,E0,95,7C,30,D9,65,9D,BB,C4,89,3E,8B,CE,0E,5F,9D,75,D9,A1,D4,67,4D,D5,78,10,EE,02,31,F9,D9,31,CC,DC,FE,C6,4D,D7,BC,42,8F,2A,5E,D7,CE,24,91,D5,F5,2E,4D,19,D6,F8,08,88,DE,C8,8B,4C,A4,03,C5,D0,2F,84,87,4A,38,57,B9,9C,68,F3,CD,1C,2E,FC,04,27,83,7A,32,EB,42,3C,89,E7,92,FA,91,6A,8E,42,A4,3F,16,6A,67,41,9B,28,72,B3,1F,B1,39,69,F3,E8,D1,C1,89,94,6A,C6,53,E9,00,18,4B,2A,CB,15,19,45,CC,F4,0C,1C,16,32,E4,F3,A9,38,35,27,93,DA,D5,93,2B,CC,98,6C,88,E2,AA,D6,8C,25,8B,6B,A5,51,48,B0,08,CD,E7,3C,4F,08,27,A6,01,FD,E9,0E,CF,5E,5F,D9,11,0D,9D,B3,0F,BB,8F,56,C8,3F,94,E2,83,9F,13,D5,CE,62,B1,D6,B6,44,8D,3C,44,3A,83,D8,36,72,A3,44,41,E1,33,7F,EC,3C,60,54,FC,AB,03,31,2E,3C,C8,25,C9,1E,95,46,97,C2,2C,38,B8,BB,09,48,7A,4F,F4,9C,A4,3B,A8,D1,AC,E5,A1,53,32,E2,9E,66,0C,83,AC,E0,C1,F6,03,00,B1,4C,98,5F,9F,B9,9E,78,04,97,54,BB,7B,C9,C0,AE,BA,54,C8,EA,A3,8B,6E,AB,FF,09,B8,29,4B,8E,31,FD,51,6E,50,A8,3D,50,C8,00,27,A9,30,B1,3B,BC,21,F1,49,50,A2,1D,E6,B5,76,E2,D2,85,14,FD,D0,56,96,7A,F3,F3,DF,AD,C8,84,56,61,C3,C1,DB,ED,8A,74,8F,E5,18,61,9B,38,37,4D,80,07,A9,F6,50,B0,3E,51,8D,21,EF,AC,70,2D,FD,CA,84,6F,38,63,5C,27,16,A0,85,12,3D,DC,45,C0,F6,6D,D7,D4,2B,98,D7,40,64,4D,6E,CD,5B,79,1D,ED,A1,4F,D8,9C,98,E0,85,2B,35,55,A0,CE,D4,B5,D0,64,2A,D0,E6,FB,D8,E7,B7,A4,A8,2A,1C,4C,DE,E6,D1,4F,A0,0C,D3,BB,C7,D2,B2,0E,48,0E,13,37,90,44,11,F7,7A,8A,EC,90,75,B4,AF,B6,EB,96,C3,A6,BB,FC,2D,AB,82,46,3F,55,D4,2D,B4,BE,28,62,73,19,2F,A5,9F,39,13,2E,86,CF,D3,C8,D9,37,09,EF,2E,C5,3C,43,63,B0,61,7D,7E,84,C6,79,8B,40,53,38,65,74,64,36,BB,26,58,28,5C,86,76,FD,36,89,3D,F0,E7,EE,E5,6F,CB,98,8C,72,CA,8C,8A,73,33,EC,6C,EE,13,48,F8,B1,B9,EE,64,30,04,85,62,46,8C,99,D0,99,C9,AD,2D,01,6C,DB,39,92,BB,17,12,F4,79,A7,A0,E5,7E,D8,E2,0B,BD,43,88,84,2C,AC,E4,6B,51,8E,FA,A6,B6,BD,41,0D,4E,E3,2B,3F,44,A9,C5,0F,40,DA,DF,58,64,1A,79,69,A4,B9,2E,1F,FE,CA,11,14,32,41,27,2E,68,00,B3,A1,1A,6A,EE,39,DA,8F,1D,4F,A6,BD,23,25,E5,D6,D3,BD,79,E5,21,A4,18,5C,C2,49,61,8A,75,67,C6,10,49,CF,ED,8D,8E,CA,16,44,4C,30,95,C6,69,18,81,6C,99,1F,8A,69,3C,9F,94,8A,FF,52,1A,D9,2B,0A,32,84,4F,4A,B6,31,C2,C3,1D,4A,93,69,23,0B,69,8B,46,6F,04,B8,C1,1B,3C,CC,E6,B2,EF,16,60,FE,58,96,C8,35,E0,86,53,49,3C,9A,A2,C1,2A,14,8D,64,A1,3B,14,37,2C,90,1E,F0,85,6D,C8,B3,EA,B7,BF,DA,34,9F,11,98,C4,76,A6,A7,69,54,1E,B0,13,CD,BD,85,52,B9,EB,4B,98,27,EA,A3,CD,B9,58,9A,21,04,AB,44,E3,15,03,DA,5F,F4,0D,DB,31,00,9D,F7,7D,B2,74,25,3C,AB,D0,91,15,F6,70,D7,33,B1,6A,2F,E9,57,9E,D6,63,16,F7,54,CD,A5,63,BE,66,83,43,B8,BA,51,0E,DF,86,CF,35,F8,DC,89,E0,D1,A6,7C,2D,42,A9,07,96,70,35,76,18,F6,C0,8D,6D,B8,F8,E6,67,AC,63,CA,13,0B,C8,5D,78,CB,5D,92,C3,98,4D,B9,F3,F6,A8,9B,FA,40,CE,A3,71,5F,E1,B7,B3,3F,5F,32,1D,F5,E2,6F,F9,54,91,5F,15,5A,3E,A6,10,4E,51,C1,7A,95,21,54,4B,DA,78,48,E2,0D,6B,82,C0,9C,F3,B2,E0,77,8D,5C,21,70,EB,D2,F2,19,BC,D2,64,0B,0A,A3,00,69,84,B3,5F,6E,DA,8A,E2,78,86,FB,84,79,9D,9B,18,6F,B1,71,B1,83,9C,73,F0,03,52,A1,98,D5,EE,88,F5,5F,A7,F4,41,62,4C,47,EE,95,89,7F,83,A7,F3,31,B8,45,56,49,0F,4C,5D,CB,A0,84,FA,FA,21,93,B5,44,27,A5,E0,18,20,2C,F3,11,4F,AB,5C,51,10,E1,1D,5C,79,94,E3,4B,ED,11,70,CE,A9,D8,A9,9C,AE,98,F2,2D,37,68,91,BA,4E,C5,0D,FB,03,0B,E2,28,66,4C,24,18,51,8D,BF,A8,5D,4D,D1,F4,FA,0F,2F,B1,85,D2,F3,2F,07,7E,F0,91,00,2B,07,CB,70,F7,EE,E5,2D,DD,5A,16,02,20,95,94,90,FE,BC,D7,1F,3F,EE,65,D1,52,F3,AE,B9,5D,AF,59,18,9E,A9,66,10,1D,7D,73,AE,8E,2A,02,1C,60,4E,30,7A,82,27,70,51,F0,CF,1B,7A,45,58,D1,F6,41,66,91,AA,7F,9C,1C,90,3F,E8,2C,F3,CA,9D,E0,95,C4,F2,CD,AD,AA,11,CB,B4,52,E9,5B,1F,75,3B,52,D2,8D,56,86,15,DE,19,B3,7D,5E,5D,00,0D,D8,73,8F,EE,07,3F,FC,DC,D0,3D,00,D7,20,95,39,F4,AF,2F,1D,43,CD,65,E5,2B,D9,78,2E,11,7C,AC,69,F1,34,D9,FD,2E,17,C9,39,74,70,31,DD,5C,2C,6A,92,53,22,F4,21,E7,1C,85,BA,F6,51,B4,6C,93,27,FD,80,1B,2D,F6,28,DF,D0,5A,75,93,C4,D7,37,E3,B2,27,A2,4B,8E,16,76,FF,9D,6A,0D,50,B5,2D,06,02,A9,79,1B,77,A1,93,B2,13,84,BB,7C,72,C6,B2,E4,6D,A8,07,11,5F,FB,0D,07,FD,23,1C,E5,1C,9D,9D,D8,D5,48,48,CA,B1,09,5E,6F,04,ED,25,70,D4,C9,FE,C5,B5,39,70,24,64,4B,81,51,2A,23,27,20,3D,04,62,C1,DF,46,7E,FA,EF,85,05,8E,3B,A5,71,96,8E,02,7E,29,C5,B7,5A,74,B5,78,05,55,C1,B9,5B,35,F9,4E,37,D3,5D,C4,8A,64,D1,F1,FF,3E,A7,98,0C,F7,6B,26,7C,68,D3,F5,63,EB,71,83,22,D8,0B,9D,2E,AA,17,41,CB,21,AC,73,B3,7D,5B,95,AB,E7,22,FC,15,05,17,34,5B,7B,4E,DD,9C,2C,8E,EA,65,8A,43,EB,E0,4F,A1,D8,5E,2F,66,F7,2F,AC,90,F1,62,92,C6,80,FD,A1,45,23,8F,05,2F,72,91,D7,B2,57,54,A4,95,CC,80,DD,D3,A6,9E,2B,EE,EF,E6,88,67,6D,1C,02,C4,2C,B5,35,52,5C,46,CF,D5,07,AD,87,6A,AF,86,78,EF,CD,93,54,4B,33,BB,D9,62,5D,D4,0D,49,FF,B3,BB,67,BA,AE,1A,FC,88,32,0B,B0,6E,82,F6,1E,69,84,48,C1,1A,CA,0F,FB,52,15,5C,AA,83,E8,53,A5,D0,33,DB,E3,F3,49,6D,CD,F4,6F,71,54,CD,A7,02,EB,8C,67,9C,19,29,3F,8D,06,5D,EA,A3,CD,32,C3,D8,C2,BF,79,95,87,28,77,BC,21,EC,A8,34,0A,AA,F1,7B,50,81,A1,0C,25,25,CD,B8,3D,F6,4C,DC,85,D4,43,52,69,E7,97,05,6A,6C,F8,53,C2,38,81,0D,B5,F2,C5,92,1A,B4,E0,8C,7D,ED,5A,CB,AD,B4,B1,5B,48,F4,EA,59,59,BE,1C,13,67,BD,80,2B,42,CD,27,DB,B3,C8,48,9D,EC,4A,A5,A3,CE,49,80,3C,CA,3F,26,00,B9,F0,6C,61,4C,00,9F,41,EB,D7,9C,FE,AB,07,25,DF,E6,BD,43,DA,37,18,26,8F,D6,98,7C,19,49,D0,B6,A1,23,B4,8A,D9,B9,87,E8,E6,4F,19,F9,FF,0D,E1,F2,48,F7,27,60,E3,81,9E,7B,21,85,E6,E7,D6,A3,10,99,CE,85,9E,3C,AD,18,A7,83,98,92,00,11,B8,88,4A,34,0F,D8,3D,6D,CA,A1,2F,97,8F,F6,F2,EB,35,0B,48,78,70,56,BF,80,86,65,B8,91,8E,E8,F6,0E,9C,E5,B7,09,B2,A6,74,6D,FF,2F,46,87,03,C6,15,D1,D7,EA,A8,99,F3,0F,21,98,17,1C,EE,04,D9,25,48,76,A6,32,E9,2B,43,B1,FA,17,C2,42,3D,AF,0B,EC,0D,67,5A,A8,35,E6,E1,5A,46,67,30,1F,BD,C1,CD,FD,E0,2F,17,B7,D9,84,D8,F4,BB,19,97,7B,63,32,C7,84,B9,CF,64,11,DA,F6,90,A6,69,79,17,12,18,AA,4F,18,52,9D,64,ED,99,11,6E,5D,8D,78,92,40,CF,00,01,35,1A,7F,54,FA,5D,0B,14,41,FC,01,B2,F0,87,69,0F,F1,97,3A,6A,AE,41,D7,9C,D4,37,54,8F,54,BC,2B,18,55,C5,6D,53,C5,D0,CA,59,75,5E,3E,D9,55,25,19,1F,F3,ED,D2,6E,C1,04,14,14,79,4A,D1,D2,51,39,7B,A9,B8,74,ED,7D,F4,81,F9,4A,55,81,E5,5C,1A,FD,30,AD,63,15,77,A4,4F,D6,B3,7A,0F,14,B4,69,A0,DF,E0,0D,FE,D3,25,68,83,CD,06,8E,A7,95,E4,CE,AF,1E,6B,85,31,EC,98,53,F6,99,D5,74,8A,D5,80,CA,42,B5,97,CC,FC,B9,57,0D,89,C7,33,8F,1E,A5,77,99,A8,5C,E2,82,28,8E,96,E8,58,BB,28,9D,02,23,53,93,5F,E7,2C,B6,81,1C,76,18,3B,0C,0E,E9,E2,9E,A4,A1,65,58,B4,97,3E,74,D7,2E,18,A4,98,04,96,7B,05,5B,BE,A3,32,37,01,B0,BB,4A,C2,DB,97,E3,84,7B,90,A3,BE,87,C7,F1,70,F8,20,FE,89,35,87,A1,DC,49,35,6D,53,08,FE,A9,1A,62,69,2D,52,8B,5C,D7,88,07,A9,D4,F4,AE,32,49,40,8E,C6,DB,D9,FA,09,9A,F4,06,DB,F1,D5,D5,46,DC,51,75,F8,A7,B2,FA,23,D9,B1,2B,C3,22,58,F1,A1,61,97,AF,08,A6,9E,76,C7,14,D0,75,38,28,C2,2A,6B,07,94,18,19,C8,F1,50,FA,BA,9B,44,C3,39,89,D7,48,58,18,30,5B,15,35,8D,AC,97,C7,4D,5C,2F,4B,1F,FA,EC,AD,BF,2F,A5,5A,28,49,E1,78,06,8C,5A,FD,78,58,DE,CC,49,A5,10,63,91,9B,53,FB,EC,DD,AC,74,8C,12,8B,83,0F,CA,5E,18,81,19,A9,5F,D7,EF,D8,C5,2E,DA,09,59,F5,B4,4F,E6,C6,C1,B1,3E,1B,C2,58,62,BE,43,98,63,FA,89,D2,7B,5D,DF,51,13,B4,C5,B5,FF,0D,50,8B,99,4B,F9,F6,30,5D,FB,E0,DF,7A,C6,33,43,13,D9,0F,C0,F0,C5,D1,E4,9B,FB,16,45,38,EF,79,4E,2E,79,EE,E4,F0,C9,B9,7F,B1,39,26,4E,06,B9,CA,53,D9,44,0D,2B,DD,73,CE,EB,6E,B9,91,61,86,20,4E,96,77,A1,65,1B,5A,E8,D8,09,3E,C4,4B,5C,89,7D,C6,29,73,86,56,30,64,8E,71,06,8E,75,BE,62,7D,76,80,C7,DE,F2,2A,39,87,EC,5F,D9,2C,E7,2A,8B,32,6F,28,FD,00,86,BB,85,85,1C,0E,FB,12,3C,0C,86,93,A8,92,28,89,FB,2B,F5,6A,76,9C,40,35,FE,0E,A1,57,BB,FC,DA,43,9C,41,93,7A,BA,D8,CB,96,22,6D,15,CE,14,ED,4F,D1,D6,2A,77,F0,B6,B7,62,E1,1D,D4,D8,C2,36,3B,84,F9,4D,D8,D2,8B,3C,09,7E,E7,CD,1C,01,C9,98,33,40,21,A6,00,2D,BC,8C,BC,4C,8B,F9,10,E3,07,BE,C5,3C,2D,38,7A,06,32,B5,35,00,21,97,86,2F,8E,BC,26,FF,CE,E0,9E,12,6F,79,58,C2,EF,96,DF,9D,E5,09,AA,A0,86,87,0F,7F,6D,9A,19,8B,5A,41,44,D7,F4,71,DB,30,08,5A,0E,07,64,C9,6C,21,1D,4C,17,CA,C4,E2,2A,F9,96,F5,6D,48,54,7D,50,73,C2,04,10,88,C2,FE,97,B2,15,4A,19,8E,8B,29,1C,A7,DC,A0,87,F6,41,AA,36,FD,B2,01,57,C6,1C,87,32,2A,CC,13,3C,54,12,4C,53,99,F8,27,18,CF,CA,00,1A,CD,53,AD,45,19,22,26,20,B4,B4,36,EE,BD,70,AD,79,7D,AD,69,0E,2A,5C,1B,91,33,1A,A7,0D,20,7F,3A,6C,31,2B,B0,06,F2,1F,D2,3D,27,01,16,66,2D,E2,0F,2D,61,06,A9,76,7F,8E,7F,9B,83,16,EA,76,30,3E,B6,AE,77,7E,85,F6,51,48,B9,5D,96,74,74,7D,6B,72,AA,C1,5C,FA,70,5A,33,43,03,5E,95,D4,DF,8A,17,2A,FC,46,08,1B,22,E9,7E,E3,C3,D6,A6,1C,AB,FC,6E,32,CD,B9,90,13,EC,FB,02,61,73,00,30,F3,D9,D4,70,EE,7F,DD,0A,99,3B,83,E6,AD,5D,93,B9,29,5C,2C,2B,29,CA,07,67,64,6E,4E,FE,03,66,0D,0A,9A,0F,34,64,58,3C,BF,6A,D2,F0,86,7C,32,97,8A,4E,6B,93,0C,D8,14,50,DC,67,CB,10,79,59,28,CA,5D,12,53,F2,64,41,14,AA,10,9F,34,1B,35,72,CD,CA,A4,66,C9,84,EB,20,6F,00,62,28,0E,57,D7,72,32,ED,02,2C,B4,A3,B4,20,36,39,D1,17,72,F0,D4,80,5F,DA,51,02,AA,1E,A0,12,68,7D,69,4E,D0,2F,C1,16,7A,13,0D,0F,AC,64,A3,CF,52,37,EE,4A,28,40,96,3F,57,F0,0C,0E,AF,4C,CC,94,AD,30,E6,24,0A,01,7D,D6,FE,7B,65,D1,73,C9,7F,61,61,D1,C5,39,1B,B5,0F,94,4C,C8,18,66,99,67,CA,C2,E7,62,3D,24,1C,EC,1C,E7,53,6A,DB,C3,6B,C7,D4,93,B3,0C,96,44,93,CA,BC,B0,4A,43,A4,7F,A7,FD,2C,B1,CC,01,6E,0C,D2,E0,F6,B7,55,B7,F7,35,FB,82,60,56,A8,CC,3E,E8,F7,51,D5,9C,A0,3D,D3,EE,E1,89,47,9D,20,DC,3E,DE,6F,E4,37,83,9B,CD,1A,C2,5D,90,4C,5D,53,91,37,B3,14,F7,35,76,B9,AD,06,DE,B5,A2,F4,14,49,77,4B,DC,7E,98,F5,18,0A,BA,4B,CF,A7,16,D0,C5,3B,4E,9A,8B,8E,3A,A4,08,F8,B7,79,F4,CB,02,DB,55,37,CB,E6,98,46,4D,7E,DF,13,72,B9,6F,C6,1B,07,9C,15,A2,96,B7,61,AB,0A,DF,61,05,EB,26,66,5A,F7,91,C2,61,90,41,C4,98,7F,36,D9,B5,73,FE,CA,5A,3F,73,08,37,2B,5A,5E,81,B5,EE,22,BC,7B,22,8C,03,29,44,BC,BE,4F,DE,8C,89,C6,6D,60,BB,4A,12,AE,01,37,EE,9F,A7,26,F4,E4,29,12,A3,94,CF,26,78,7B,16,B4,03,F0,9A,94,BE,58,F0,5C,90,17,26,2F,29,23,75,2B,26,5D,00,51,23,EB,68,9B,55,F7,98,24,00,E9,FD,10,55,0E,C4,D8,32,C6,9B,50,79,BC,2B,31,A2,BC,C1,0F,92,3E,2E,1A,BB,CD,88,67,E7,6E,3A,A3,8C,C9,BF,24,D6,06,D1,6D,F7,93,B9,8F,71,86,94,23,9B,23,73,4D,AA,19,43,13,FA,7C,BB,C8,40,D3,84,A2,AD,E3,86,C7,F5,58,8B,13,95,1F,40,6C,C5,65,06,5C,23,83,8E,0B,AD,56,37,43,9D,B5,7B,77,32,92,8E,D3,DD,C7,64,4A,E2,52,81,67,CE,D5,CD,9E,C4,C7,31,B6,B6,44,DF,F0,40,C6,5E,FB,AF,E0,03,C3,4F,DC,48,F8,E3,41,13,89,BC,A5,DD,DA,CE,1D,36,58,0E,D0,73,C9,12,95,BE,82,02,47,CE,C5,89,86,C0,D0,EC,B8,EA,07,4D,70,06,F7,AF,B8,11,0F,4E,F6,44,D9,AF,A6,92,35,E8,40,BC,3E,E8,5B,96,5A,69,B9,47,39,32,C0,46,17,AF,9F,44,28,BC,EB,6A,30,F3,AD,E1,16,49,86,08,3F,AB,6F,84,ED,17,14,01,D5,13,6B,CC,87,D9,B4,7D,45,8F,2B,B5,3E,FC,FF,77,35,19,A2,BA,95,7F,92,3E,B0,4C,DE,FB,86,A8,67,04,9F,7B,4E,98,6E,E1,2C,58,73,33,60,2B,90,C4,E9,FA,06,FE,43,C4,77,F9,A7,C0,40,FA,05,4A,9A,EB,A4,DA,67,97,F9,91,FA,D1,CA,55,F0,D5,D5,28,3C,68,FE,4D,F2,D5,63,04,63,18,B4,04,EA,67,B1,66,A4,F4,F8,19,D9,52,35,FE,27,C1,5A,9A,32,D5,F5,CF,5B,11,1E,FF,21,A1,00,55,F1,7B,4C,88,FA,54,F8,82,08,4F,14,A6,71,CF,A3,95,FE,06,CC,B0,91,2E,02,76,9D,1F,1F,52,4F,F3,F1,9B,31,FF,EE,4C,5C,8A,99,84,5F,00,F6,DC,FC,00,0A,71,5F,DE,B3,DD,D2,9C,E7,F4,53,8F,47,BD,05,1B,6D,46,95,33,F3,20,BA,30,9C,97,BE,61,9A,38,44,30,B4,F6,96,15,D5,95,0D,38,25,95,D6,F1,75,A1,6B,8E,E7,1D,F2,14,18,97,69,EC,02,9E,36,0C,A3,E2,0C,F7,97,59,53,52,A5,C8,5B,E2,26,5F,54,11,42,63,21,D4,87,E9,F4,C1,28,4D,9C,9F,FE,8E,B2,72,0C,A2,D2,BE,FF,68,2E,4E,81,56,AD,4B,30,6F,BE,7A,C1,F0,C6,ED,60,30,C9,54,64,81,E9,8E,CF,76,59,59,F4,6F,1F,52,87,3F,BD,CF,4C,6D,B5,1A,12,59,F5,92,73,0D,9C,71,08,8F,23,98,26,84,9D,37,42,2C,2C,9A,06,AA,69,5C,A9,2B,91,3E,86,7B,38,13,EB,8C,10,BC,31,45,38,C4,32,6C,55,EB,5E,E6,3D,1B,8F,26,BB,83,54,51,91,9D,D6,49,E8,81,C0,36,26,62,2C,9A,BD,46,32,B1,6E,1B,11,8D,FF,F3,1F,CD,2C,25,90,7B,89,A6,A6,04,10,A7,78,83,89,E8,FD,0B,D3,B0,A2,69,A4,12,B8,BA,54,D2,8E,4B,11,B5,BB,C3,AA,4F,37,C8,7D,14,9F,F8,7D,D6,BE,A8,1B,FD,A2,AE,9D,6E,15,D8,31,61,81,EC,B2,ED,C5,11,F5,CE,C5,89,10,4C,74,66,8C,B6,63,23,D1,A5,F7,CD,EA,1C,25,72,43,8E,56,6C,C9,26,92,7B,18,8E,23,C1,63,EC,E1,39,1E,33,3D,62,64,60,3D,C6,EF,90,64,A3,8F,45,2E,83,AB,A3,3C,E4,69,28,E6,C6,4D,F9,63,C2,FF,CF,60,D3,63,A1,DA,7C,B8,24,34,D0,8F,C0,DC,0A,85,9F,CB,F8,D9,52,09,9B,C5,6E,A5,2F,41,40,9B,0E,35,B7,D5,2B,31,0B,05,99,D7,AA,36,73,AC,7D,00,81,A3,A8,E8,57,C7,71,D6,66,B1,AD,29,18,85,32,60,CC,C8,8E,C7,65,57,AB,08,1F,D8,EA,DA,C9,8E,0A,AA,A5,A7,4D,5D,E3,D5,43,7D,3D,C9,42,E5,0F,D8,0A,F7,8F,DF,43,9B,55,82,6D,5C,47,85,A7,91,3D,55,A8,70,C6,EC,B2,D7,FF,B8,C5,6A,52,C5,BF,D9,D6,A0,13,D7,EE,9B,6F,F6,58,04,F5,ED,F9,3C,06,F7,C2,7A,CA,B5,FB,57,E3,E6,03,46,87,EB,09,8F,82,A3,22,CE,7F,F5,8A,09,F5,D4,C6,4B,EB,78,95,56,36,C3,AA,A2,74,61,DF,76,3D,1A,22,E6,B5,38,50,71,D7,92,D1,55,5A,82,7C,5E,49,EE,CF,76,66,20,CB,49,55,BA,59,B4,BC,63,5D,77,52,7F,AF,88,7C,27,DE,18,A2,B4,44,4E,10,AA,87,7D,CB,7C,99,A2,04,A1,34,01,0F,56,C7,F0,51,51,35,99,EC,CB,DE,9A,16,BD,37,40,E5,C9,8D,1A,D4,38,F9,06,3F,23,FD,F6,50,26,E0,87,88,98,4E,2B,FE,0B,E2,FD,07,66,B5,28,57,38,36,1E,19,4A,82,26,28,1B,76,CD,2D,8E,2E,99,A7,5B,53,EA,70,47,57,42,D0,A5,84,90,49,F0,28,BC,A5,B0,DB,B1,33,86,CB,9A,71,62,36,46,34,6D,D9,9E,EC,3A,F4,00,FA,F4,8C,95,25,75,86,C2,27,D5,0C,B0,6D,52,46,E1,68,55,E1,58,C7,37,84,00,C6,6F,79,C7,8F,28,1A,CA,0A,77,5C,E9,7B,7B,FD,4C,7A,A9,9B,38,36,15,55,8C,36,36,F2,49,50,CC,E0,7D,DB,38,28,BE,6F,AC,98,AF,5C,9A,00,6B,DF,93,FD,7F,B2,50,03,EB,22,0D,A3,98,49,9A,F0,28,1E,87,CF,AD,FD,2C,B3,0D,96,0F,D6,ED,34,62,8C,94,6D,54,41,A9,94,39,CA,C3,CF,45,79,66,65,6E,7F,7C,E8,4C,83,09,51,7E,84,8A,08,E8,50,C5,18,37,BD,02,5D,37,86,A5,A0,AD,DE,9F,76,E8,84,C3,90,6F,2D,9A,CC,8D,72,CD,1C,0A,5B,FE,EC,14,93,C5,61,D7,83,61,49,7B,E6,6E,5D,5E,19,37,6A,E0,93,BF,13,64,C0,AE,8A,1D,09,51,B1,19,D5,68,32,6A,FD,92,1D,1D,34,62,C7,FB,94,E5,C0,C8,09,E7,BD,0A,2E,03,6A,C3,FD,E6,40,AF,02,B9,3C,8B,55,CA,00,D7,04,F6,DF,D3,E3,44,21,B9,F4,7B,D5,D8,9B,2D,33,1D,44,90,A2,AC,A9,D6,C8,E1,0D,DF,26,6A,A6,C1,60,0E,DF,C9,0D,64,BC,59,54,DE,19,82,01,6B,A4,69,A2,1E,D1,2B,D0,A6,72,F0,BC,D8,BB,81,EF,F9,DC,47,2E,8B,30,FD,8F,B0,0B,11,5C,D7,2E,8D,86,93,06,DD,87,D3,42,31,77,A6,A5,82,09,6E,AD,94,D2,76,E6,0A,F7,7F,43,2F,DB,E6,24,36,12,D1,6C,B0,F6,C7,39,47,FA,2B,A3,49,49,99,BE,3F,F2,35,C6,40,31,A7,12,10,2C,C9,AB,FD,E2,F8,EC,A2,D1,E2,23,15,D3,FE,EF,6F,91,F3,83,FC,A0,D1,51,42,B8,52,37,B8,D8,11,1A,23,BB,AA,9E,23,20,82,59,02,37,B8,98,53,0D,34,7A,EA,47,B4,9B,D5,10,F2,8A,F3,04,06,8D,54,92,9A,A2,F6,8F,6D,74,6F,03,EA,D8,EB,25,94,71,C2,1D,66,5A,15,D1,FD,55,4C,D7,36,90,D9,6A,BC,B4,DC,3F,0E,19,62,B9,A4,F4,D3,3E,23,87,C8,BA,83,91,39,B4,4A,79,AE,EB,E1,96,B3,D2,B4,35,FE,07,65,5A,06,77,5D,FE,D7,26,C5,94,FD,CB,2A,2E,B7,3F,7B,29,69,AC,30,D6,62,B1,C0,F0,E5,CE,8E,B5,58,51,13,4B,57,35,32,CA,C9,80,8E,DF,83,BF,9A,D2,3F,67,E4,29,33,60,FA,05,28,F5,07,68,00,68,23,F4,FB,03,21,3E,50,9C,49,08,CE,81,35,E7,1E,41,F3,90,16,98,30,0E,D4,5E,55,A8,AE,BB,89,02,A5,B7,3E,06,31,B4,68,70,DA,09,BB,B8,20,9B,C2,E2,82,A6,F7,85,E9,0D,93,B6,A0,EE,A2,4F,AA,AF,2D,0B,F1,50,F8,FD,5B,2D,FC,F2,22,AC,0A,FD,54,7E,87,85,B3,40,8A,13,E8,2E,4E,1E,61,4E,E8,12,5D,69,1A,E2,03,A7,71,E6,AE,FC,D3,68,F7,E0,BD,DF,60,89,3E,B9,22,1A,DF,74,B4,51,3C,46,32,09,69,4A,FE,65,54,F0,12,5C,75,C2,D0,E7,3F,70,12,EC,7B,4F,F9,69,7E,52,CA,13,E8,27,BE,92,98,54,1A,6F,15,0B,0B,01,A9,5D,9C,E6,60,19,CC,50,71,8B,A4,A5,01,9C,8E,27,C6,75,7F,12,6F,26,BA,12,0C,2C,64,93,27,FA,C1,AB,3D,C2,68,1A,B0,CC,AD,AB,C6,3C,98,7F,76,6A,C2,C1,AF,A8,08,A6,24,89,7D,A7,47,AF,95,82,90,90,C2,49,CE,8D,B5,DA,A0,B8,C7,9E,9E,07,0C,63,64,8A,08,67,41,12,86,81,6B,9F,F6,E2,64,C5,B7,E0,14,0E,EF,C7,17,04,BB,2D,45,8F,62,EE,33,0F,91,3A,DD,A8,65,A4,AF,64,91,C2,C4,89,6B,63,E3,28,9A,13,C9,64,70,49,FD,8D,7C,A5,8D,16,37,F1,54,F3,6D,59,BC,D9,FE,71,71,EA,2C,5F,6C,DF,87,2A,C8,D3,D9,BB,72,3C,B9,6C,0A,BB,A3,32,F4,B7,45,5F,DF,39,04,43,B2,C9,D3,60,D7,A6,9B,33,69,A1,C6,B0,4A,8B,DD,8B,49,8B,D8,EB,5B,2D,51,5C,C4,EE,61,FC,D7,7E,D2,3C,12,F1,AE,49,7F,A0,D6,DF,66,D7,4E,45,B7,9C,23,27,DD,A4,02,16,AD,5E,52,97,B8,1E,01,2B,35,1F,C5,EE,AF,C6,66,13,36,A6,17,7F,E7,E2,7D,D8,E4,C6,45,3A,8E,1A,09,1A,5D,24,5F,09,DA,05,7F,29,21,44,C8,C1,81,7A,D1,F8,37,F2,36,2F,05,64,A8,B8,7D,7B,AD,6F,47,74,50,10,6E,95,22,B1,1C,1F,34,90,C0,74,F5,37,A5,2B,55,A0,8C,FA,FE,04,A7,E9,7A,A9,41,6E,C9,F8,E3,A9,0B,57,01,A0,1A,CE,00,11,8F,72,BD,70,4A,AB,94,A1,91,05,C8,46,A5,3D,AE,CC,47,E9,91,CD,45,34,64,09,0C,B5,00,2D,3A,02,2B,F2,9E,72,1C,FC,7F,0A,FC,54,A0,D3,91,AB,68,22,3A,EB,2E,0D,23,2B,02,5B,22,78,74,E6,09,38,55,06,7B,B7,41,04,2F,7C,3C,3A,43,20,78,81,EF,86,47,A7,AF,CB,8F,D1,6E,1D,4E,4F,28,46,B6,BC,54,74,CE,E8,FB,61,BF,59,1A,62,39,5A,BB,29,F7,79,AE,26,A2,B6,C1,01,21,E4,B2,15,3C,AF,31,67,E0,18,07,D3,6E,CA,2C,C9,E7,81,61,B3,A6,50,64,AC,7B,38,AF,59,42,54,AD,E3,1F,A3,A6,7C,84,F6,8C,8E,40,B3,D6,4B,86,E7,7E,B0,37,C5,26,52,97,F5,CB,F6,0D,A1,39,0F,22,FB,65,D2,10,29,EA,04,7B,08,45,12,60,8D,7C,29,15,78,87,1F,C0,CC,AC,FC,A0,AB,B2,61,42,E8,2A,63,7D,08,E9,3B,46,91,8F,92,C0,B7,B3,8A,3A,1D,4D,23,7C,DB,CC,A4,D5,DF,28,5C,26,F3,BF,FD,CF,8E,5B,80,A4,D1,D1,08,23,93,AD,1D,D0,C3,9B,9D,E8,E9,8F,C3,4B,52,4F,59,FA,43,EC,42,46,36,6C,36,7E,6A,42,C0,A9,D0,2A,AD,63,B6,1E,84,47,32,85,75,C7,CE,3D,5D,D6,11,FC,5F,A3,22,7B,22,47,24,BE,41,1C,53,96,35,82,D2,9F,3F,A5,7C,D1,43,2A,44,0F,40,30,2A,94,09,83,B7,01,38,C0,D6,C6,01,6A,CE,9D,0A,ED,12,6C,8A,02,3A,CB,E3,4D,DF,F6,F5,9C,66,81,79,36,FC,C5,8D,4E,A6,F6,AF,66,C7,3B,94,13,D9,42,BD,7C,93,74,4B,65,E6,29,14,A0,A1,61,71,14,12,81,1A,F5,3E,77,D4,39,E1,DA,E1,52,14,D9,D0,E7,0A,E8,2F,16,6A,5F,B0,14,D8,2F,EA,A2,2A,88,53,2F,BC,7E,E6,1B,8B,C0,2B,43,52,D5,02,98,4E,D9,C7,71,87,E5,EB,E6,42,17,31,87,27,14,0D,1B,57,EF,89,35,A6,26,08,56,26,D9,BB,EF,2D,DE,67,D3,56,1A,37,1B,C9,8D,EF,1A,77,B5,F4,94,51,B7,D7,72,A8,0C,40,52,4A,6C,B1,45,A3,20,2E,52,09,D3,53,E9,68,16,11,42,D7,5B,41,B3,9B,A2,70,92,BF,26,2A,0A,A4,F2,87,4F,99,8A,C4,FF,B0,72,D6,63,6E,17,23,5C,60,D9,57,9A,81,18,F3,A5,D4,C5,F5,BB,D5,B0,29,73,46,9C,E2,FA,E9,A7,BA,AF,92,68,AA,9D,59,D5,BA,5F,05,05,AE,74,84,21,DA,5E,8A,63,CE,49,22,6E,93,62,CA,FD,05,61,E1,AD,A7,69,A9,41,46,85,E3,5D,CF,02,03,70,9A,5C,6A,E9,82,B9,80,DE,80,0D,22,B1,3B,C1,E7,0E,FB,DC,C3,3F,AA,40,2A,CC,A7,29,DF,E7,36,6B,22,12,80,2F,99,EE,93,C5,F0,47,88,F1,17,68,32,ED,F2,1F,35,DB,0A,F6,A7,B4,1C,18,90,07,2D,0C,77,94,07,FD,EC,79,A4,CB,1E,4C,E3,DF,3B,0B,E9,00,04,DB,66,4D,C7,23,B4,BA,43,76,C1,0E,0E,F3,E5,5F,F9,7C,07,90,BD,D3,A9,FE,AF,E7,14,5C,54,DD,F3,B8,77,67,13,EF,07,FD,D7,65,D5,2A,1D,84,3F,4C,6D,72,B1,AB,6D,C6,EE,8F,28,90,40,CD,59,DD,4E,92,4A,1D,3C,EF,75,31,82,6D,03,14,04,EE,B6,89,3D,5B,DF,04,32,64,9D,D4,EB,48,96,3C,BE,7A,2F,B6,20,87,5A,C2,5B,19,35,77,36,B2,54,C4,5A,9B,8B,43,F1,51,CC,6A,3A,92,45,E9,60,64,E4,EA,55,43,FD,23,F8,1E,A1,FA,6F,A9,7D,E0,F2,70,6C,41,9C,AF,88,F0,C5,C6,74,99,65,61,B3,AA,FB,EA,41,E0,A9,2F,AB,AE,F1,DE,35,F3,07,94,9B,CB,E4,A3,5B,41,BA,A3,DD,BA,D5,D2,1C,DF,9E,29,3B,A8,BB,8C,AD,9D,8F,8C,AC,AC,90,53,15,7D,BF,E1,F5,D9,62,C8,7A,42,B7,F8,3F,39,CA,86,FE,CB,40,FD,5E,01,A2,FC,F5,20,32,2D,E9,AC,E1,53,AB,D6,DF,93,F0,32,3D,0C,A3,88,CF,92,A7,EC,75,A0,1D,76,6B,33,DC,5B,95,31,51,29,AD,3D,DF,C0,3B,C5,FF,0E,05,5B,36,A8,0A,0B,66,57,1D,02,E8,63,19,DA,34,87,68,26,61,1B,F6,DB,F9,FF,B6,F8,76,3F,EA,B8,43,45,BC,47,A6,8E,60,6F,93,E5,DF,14,3B,63,6B,7A,AF,7A,D1,7F,ED,EE,66,FE,71,1C,B0,A1,01,F0,66,A6,09,FD,57,EE,AF,C7,45,C9,A8,BF,20,C1,02,27,62,61,6B,12,D7,D4,AA,07,ED,70,EB,FF,DC,FF,45,97,20,05,0A,7B,7A,D8,F5,1B,7E,A4,41,6B,AD,90,70,E3,E1,E3,AF,9E,86,1E,31,53,66,20,86,1D,4A,9B,8A,D2,2F,52,7B,BD,3E,5A,CA,59,B9,31,C4,42,C6,97,6E,5B,FD,2E,01,2B,78,F8,00,23,A1,6D,31,21,EA,A2,AF,45,BF,9E,F0,7D,1F,95,9F,9F,C9,10,E4,47,CF,F5,20,3B,82,0A,63,07,F7,20,E4,5D,02,4D,17,FB,71,2C,87,2D,A9,83,C7,8B,B6,7A,6A,0E,05,60,02,B8,95,8C,35,5B,AB,EC,24,F8,A1,12,1C,55,AE,83,A0,98,B4,DD,AD,D8,92,43,DF,30,5D,8D,14,8F,E4,52,3A,4A,9E,B8,2E,4E,84,41,D1,C8,7B,9F,27,70,F0,4C,24,5E,A3,11,77,15,5E,F2,EA,75,D1,18,B6,9B,76,A2,AE,64,44,B5,32,5B,74,B3,A1,71,80,BF,B5,54,85,7B,B0,D5,E6,DB,74,A7,B1,03,8D,AC,76,16,B5,F7,AA,BA,B5,4C,63,F8,63,04,78,EC,97,6B,50,A4,C9,BE,60,50,7B,45,EB,3B,92,7B,36,F6,F3,74,4F,D1,C2,56,59,3E,FA,0B,2A,E1,B2,7B,02,E2,57,C5,3F,78,F6,8D,D3,14,D3,32,9F,07,ED,7E,C2,5D,D5,F3,78,59,FE,55,AF,B7,85,0D,7E,72,10,AD,57,F9,AC,B9,A9,91,F7,7B,7B,14,A7,60,70,0D,75,FB,D1,26,8B,4F,95,18,AB,43,D6,45,B6,27,BF,6D,9E,03,14,D9,5B,07,B4,CC,83,FD,66,C1,BE,52,A7,D6,24,6E,2E,B2,86,C8,8C,EE,E1,4D,65,38,12,FA,9B,F4,24,70,D5,7A,46,BD,E2,E8,CD,62,F9,BD,57,20,AF,72,DF,4F,B0,0E,7E,22,99,A3,3F,79,93,C5,03,15,07,EF,CC,89,E4,F9,71,AC,B9,92,39,82,59,13,C3,B5,AC,F3,43,C0,C2,D3,35,EF,FE,E7,F7,15,6D,25,EE,E9,C0,13,B9,9E,04,76,09,60,DF,16,C8,FD,08,74,B2,0F,F8,93,0B,4C,73,D2,11,3F,D5,71,B6,42,13,8E,CB,BA,23,EA,7E,FF,60,E2,84,64,B6,10,10,D8,75,E9,20,78,4E,76,3C,2A,85,E9,8E,27,72,3D,C7,B3,32,63,FE,FA,C9,31,45,8C,6B,3D,1D,59,29,ED,F6,E6,54,25,D7,55,32,3C,AC,31,45,8B,A2,DC,9C,44,36,7B,87,70,0F,68,A5,A6,F9,F7,99,03,32,90,3C,08,AE,C2,C3,12,29,44,03,B7,FE,E9,46,51,B6,26,05,40,AC,75,C8,AE,C5,78,C3,59,4E,E5,90,6D,88,1B,53,57,97,73,46,BA,20,7F,25,3A,EA,12,83,6D,33,10,36,C5,6C,34,F8,AA,2E,F5,01,F7,BB,C0,0C,CD,DD,91,D1,4E,65,2A,FD,04,EB,50,A1,48,8D,85,65,73,FA,F5,8B,DD,29,51,EE,E9,BF,40,E0,52,33,7B,6C,1D,6E,14,B4,C9,C0,C4,B7,A4,95,2B,A0,67,F1,AE,A9,8C,20,D1,5F,9E,0C,C8,5B,41,03,B9,1B,4A,EA,8A,40,8B,5A,BE,B4,17,32,CD,D9,07,3F,9E,7E,9F,39,02,82,94,F4,1E,DD,D7,6A,45,32,79,B0,9B,C6,47,A7,19,B9,A5,A0,14,E2,11,87,34,2D,9F,18,6C,D9,1B,41,BD,4E,D6,8B,3D,0E,B1,E9,33,59,7E,F2,4F,87,D6,3A,85,C8,A8,35,82,D4,64,46,68,CE,7D,3E,CA,51,1D,A4,24,FA,5E,DB,D0,03,6C,B4,F7,C2,F1,02,19,74,F6,0C,1E,99,22,AB,73,01,61,A3,15,F6,C8,76,BD,19,DA,7F,C1,80,5B,8F,DA,CC,99,C1,9C,04,2D,B9,FE,81,09,F8,25,9C,87,E2,BD,C6,4D,34,22,01,24,72,D7,EF,62,37,99,B4,45,74,74,4E,ED,F4,3A,2B,37,C2,10,DB,72,E7,B4,5E,82,19,A2,56,AA,40,75,E6,2C,E3,4D,59,11,FE,AD,A4,93,32,5E,FB,B5,E7,81,5C,3C,4A,08,A2,D5,45,4C,D4,43,3C,9A,71,22,FB,1E,15,97,44,2A,A3,CB,E7,9B,96,B4,1A,DC,23,FE,BC,01,C5,7D,51,BD,A7,37,C8,0C,40,C1,60,76,61,1E,5B,8C,F4,65,D0,B7,27,4F,6E,48,90,22,ED,C8,2B,1F,37,AC,84,CE,33,66,5E,62,BE,74,B7,AD,9A,B1,1D,72,80,C5,72,81,EC,B4,D8,54,43,F1,E3,77,7B,09,8D,7D,BE,D9,A0,52,88,91,7F,0C,E0,38,16,0B,28,25,52,A2,A5,2A,DB,14,7A,E3,4F,DC,D7,C6,84,C1,49,C6,37,BD,67,64,5C,21,6A,E7,85,05,3F,B9,1A,0C,2F,DE,99,9D,AD,A5,EC,0B,58,B8,9B,7C,84,B7,65,89,74,D9,F8,A8,9B,1B,64,2C,95,B1,02,EE,7B,73,35,48,FC,BC,47,A7,22,16,7F,80,CE,A7,C8,96,FD,96,FA,AC,8A,74,12,1B,30,34,EF,5D,25,7B,A4,5C,8B,7D,2F,1C,9F,F9,D0,6E,E0,49,45,02,37,03,3E,61,C5,99,7E,7C,14,E3,EC,34,B6,9F,E1,73,CF,03,15,85,8D,66,7E,37,3D,66,36,E0,40,88,A7,8E,4D,77,3C,56,E9,A3,B6,94,4C,FD,8A,B5,73,6F,CD,6B,C7,D7,97,17,25,F7,4E,8F,96,DF,21,94,58,A3,15,18,32,58,81,13,36,AC,06,FC,DB,CD,6A,5A,BD,FB,B0,B8,85,4A,18,A0,04,97,4E,B7,86,CC,3C,84,FA,4C,27,40,0A,60,C0,34,5C,78,72,5C,C7,13,4E,45,54,11,DE,8C,76,94,44,41,5D,8A,4C,6A,F0,C7,6C,EC,8A,31,03,31,05,52,29,75,77,48,E4,78,D4,E8,94,F2,EE,71,D4,CD,0C,0E,65,84,50,1A,D2,87,F4,F0,DE,DF,A5,9C,86,81,52,E0,31,B5,FB,5C,4D,86,50,05,C5,7E,87,64,6F,02,A2,51,71,0A,C6,0E,58,03,FD,89,61,56,A6,20,15,6B,E4,72,13,39,0F,06,3B,A3,58,0D,73,A1,E6,86,69,EE,17,5F,13,B0,29,9E,21,27,99,07,BF,98,B2,56,79,48,35,1A,B9,BB,3C,14,E3,8B,6F,6F,5B,D7,AB,87,14,54,B1,3D,0A,2C,E0,7F,B0,F1,40,29,84,EE,50,B4,61,D7,30,C2,93,06,04,12,51,D6,17,C7,A4,F1,55,67,70,F9,C7,7F,5C,CB,BB,1B,C7,FF,A2,D0,57,EB,6B,70,D2,81,65,F0,82,70,C0,57,79,A7,97,0F,F2,14,C4,71,52,32,88,C8,C6,E9,F4,B0,C6,2D,1C,33,CA,36,FD,E0,11,26,4C,30,6C,05,3F,D6,6A,E2,93,08,BA,44,2B,95,BE,CB,01,FD,31,B0,33,76,C9,9C,D8,6B,0E,8C,01,9A,CD,E9,32,45,90,B2,50,50,FE,ED,DE,38,7A,21,C9,29,EF,FC,F4,F9,19,07,C6,97,FA,66,83,1A,08,40,A7,36,15,AC,D0,6E,2A,CB,37,C8,A4,B6,50,C9,9B,40,37,B4,04,79,26,E5,76,38,0C,A1,0B,77,19,6F,9F,21,73,24,91,A5,E7,96,0A,B2,9D,49,C5,C6,A0,59,2A,72,C7,87,9A,1E,6A,4F,2A,68,E8,0C,03,15,4D,9F,71,5E,4A,FB,17,63,F5,38,67,56,5D,4A,63,F3,27,42,7F,B7,77,68,24,AD,CD,36,D6,6B,55,83,FC,AE,D4,69,31,26,7E,00,D6,3D,BF,D9,77,37,F8,96,7C,DB,2F,A4,0E,C9,23,B4,B1,77,0D,0A,C9,E0,CC,94,F8,A1,F1,E4,01,A4,2C,7A,44,9D,F5,4A,EF,C1,0C,F8,FB,78,01,42,FD,A6,F3,55,45,A6,EE,11,9D,30,C3,A3,B8,C2,C8,5F,46,51,49,59,29,E2,79,83,D7,E5,25,7C,50,B9,7F,A2,EB,D0,39,2D,02,50,9C,E3,77,04,77,61,48,41,68,64,DB,A9,95,2D,21,CA,69,E8,84,EA,DF,76,EA,41,B6,78,97,39,42,7F,DF,08,42,06,95,70,E6,4C,A1,F0,C5,5B,12,31,49,D1,44,45,88,1C,2F,00,73,F1,49,39,D8,D7,B3,39,98,42,3E,D5,D0,66,A2,A3,41,66,18,77,F1,14,1E,B9,64,CF,3E,F6,C6,CB,96,F2,53,6A,4F,61,4F,8C,4C,0E,F8,38,2F,60,DA,B4,DD,BF,AF,3D,5C,72,68,02,0F,8E,69,0A,19,1B,7A,0D,21,54,23,54,A1,C8,35,FF,3D,A1,C0,6E,7E,87,3A,26,79,97,32,1B,AD,A0,61,3D,57,E4,9C,83,17,BD,55,E8,0A,72,FA,D3,BF,F0,EA,5F,5C,9F,CD,F9,CD,BE,01,46,65,80,28,6E,99,A1,18,96,CA,4B,98,E2,CB,4B,0F,AB,ED,CD,FA,3D,19,9C,9D,AB,4F,42,42,42,E6,E1,81,CE,C4,9F,8B,74,DC,92,15,3D,B0,09,0C,6B,95,AC,20,4B,61,4B,CE,19,1D,21,DC,E0,4D,9C,D8,6D,A5,73,F3,5F,C6,0E,63,8E,46,DF,D2,07,C8,D1,55,D0,56,39,FA,9B,F0,45,FE,22,46,91,8B,F6,1A,8A,9B,0F,4B,71,1B,BA,70,75,CE,F1,A9,80,D4,FB,05,D5,A2,BE,7B,5E,41,45,F4,61,58,47,6A,E4,94,8F,F6,27,41,3F,FE,AE,81,13,10,66,E5,6D,AF,7F,CF,0C,CA,50,0F,80,34,FC,D6,64,09,4F,17,19,76,04,9B,F1,C6,8A,EB,9E,CE,7B,4A,41,FC,98,6C,56,AE,9F,F8,0C,23,A6,1D,5D,D2,FB,9F,FA,CD,7A,70,D5,62,83,B4,5F,58,64,A0,0A,3A,2C,6A,11,DF,E0,30,96,E5,24,99,07,AE,EB,EF,93,B6,B5,8F,E5,F1,0B,1E,0F,AD,E0,AA,9F,7F,A1,AA,C4,4D,D6,B0,65,A5,FD,A9,54,44,83,D8,6D,6A,99,BC,B7,1B,3B,E8,27,7C,45,9F,E1,2D,EA,44,F0,CB,68,2D,26,5A,AE,18,D5,BB,22,9E,0B,29,6A,96,FA,D3,6C,FF,7F,9F,B4,D9,F5,A9,07,B0,87,11,CC,C1,05,AF,24,95,5F,19,57,A3,74,CB,C7,8D,BE,B6,83,12,96,1A,FD,76,16,F6,3E,64,C1,EB,F4,03,00,A1,6D,AD,08,FA,C7,69,DB,68,EC,41,2C,63,4B,A7,5E,0C,EF,E2,5F,06,98,B4,7A,63,0E,ED,2C,AC,D3,87,91,76,98,DE,BC,6E,43,FB,33,CB,AC,3B,B6,99,56,81,D3,0F,4F,AB,6E,6B,59,45,E1,34,40,E8,80,64,D8,A5,44,B3,ED,7E,6B,A0,5E,48,41,E4,6D,3E,FA,32,50,90,98,F3,3D,E1,2A,48,53,AA,D4,08,18,E1,A9,A2,A7,5B,D2,20,1D,F9,B0,DB,1F,39,E7,90,A5,5C,52,CF,91,B9,22,27,60,B2,EC,05,68,64,6B,9D,AA,79,36,0D,8F,BA,1E,C8,EE,B9,5F,0D,FB,01,38,E7,21,B5,61,6E,56,0C,DF,F8,C5,01,FD,92,6B,63,63,0D,FC,AF,8C,AB,53,69,FA,ED,65,E7,8A,DD,50,55,60,BD,63,DA,6E,9C,E0,0C,70,5D,0C,0D,17,2A,EF,B1,12,F7,0D,63,63,70,35,48,1A,C2,24,2E,30,C1,59,ED,A6,DA,12,F9,8D,34,04,3D,15,F6,1C,9B,27,3A,40,2B,BB,23,38,97,8C,C8,BB,8E,96,6C,45,75,BB,6A,C9,0D,D3,A8,A9,A6,1C,2E,73,AC,A3,FB,90,6C,E1,9F,BD,04,04,BE,12,B1,AF,41,18,F4,D2,12,DD,24,34,1A,35,CD,7A,6B,DD,53,CE,17,8F,77,43,91,B4,D0,6A,75,16,F6,8D,D3,87,5E,84,3A,34,C6,89,9C,E0,9B,56,7C,66,70,6B,45,52,44,FE,7D,80,20,84,83,02,08,06,BF,97,DC,EC,A6,A9,96,77,7B,71,D1,26,3A,C0,B7,02,98,7A,69,3A,E1,0D,58,06,EA,9D,1D,05,F0,23,D0,B8,3A,AD,69,7F,43,5D,BD,21,11,14,C4,8C,08,0C,A1,58,3D,91,AF,78,4F,D5,8B,5F,D6,C6,ED,64,99,F0,6C,83,E1,D7,7A,DF,05,88,0A,0E,E1,23,4B,AA,62,F6,D5,A2,38,23,92,0B,E8,3B,A3,2F,2E,CC,23,5F,18,F8,68,29,05,F1,5D,85,42,8A,47,77,65,EB,E4,9B,C6,27,B1,AB,CA,51,2C,4C,AF,61,F9,87,6B,22,81,A3,DE,78,AA,CA,1B,05,EE,79,83,D9,69,05,8A,AE,2D,1A,A0,59,5B,2B,84,99,8F,B7,E5,D9,A6,53,D3,CB,79,81,23,40,22,73,E8,CC,14,90,B1,34,C0,E3,38,1D,C8,CD,3C,8D,EA,F2,B3,CC,20,7D,25,1B,0F,01,7F,45,E4,E6,96,6A,63,62,A8,F4,C9,46,A6,0D,40,0F,94,52,E2,B9,A2,D0,4A,26,67,03,82,33,C1,6C,AA,F4,D6,02,96,2A,A7,2B,FD,89,C8,65,2D,44,C0,AF,FF,FF,4B,1C,37,48,DC,83,D2,5F,EA,F7,CE,76,EC,8C,06,CC,3A,48,31,85,88,44,D2,05,4B,08,A8,F7,02,73,80,E2,6B,4D,62,DE,46,F6,B3,30,72,16,5F,B5,01,31,51,1B,24,4D,C3,4E,99,7F,34,50,49,01,A6,EA,01,F8,52,0C,09,40,57,87,46,39,C8,FD,9F,4C,B3,29,51,8A,60,97,E9,8E,E5,00,C5,AF,98,02,94,6C,9A,98,B7,3F,75,C2,C8,DE,C5,6E,E9,CD,E9,D1,E6,0F,21,00,20,EB,DC,B6,1E,92,A3,54,A0,D2,50,40,AE,DC,C3,A3,AB,C0,5A,6C,97,41,5C,A0,AA,62,2D,B4,A3,4E,2B,A3,B6,8D,C5,40,AD,FD,B8,BC,88,B4,20,1D,99,40,D1,B5,1B,7A,0B,EC,05,A8,15,15,50,40,B5,F7,9D,75,A4,4C,7A,9F,37,C2,71,4B,C3,D1,BF,41,7E,F4,CD,B3,45,20,C6,9C,29,4A,28,5D,61,16,D8,72,C1,62,6C,6A,1B,2B,90,D3,DA,A1,01,50,A0,6B,68,A4,23,3F,42,4F,22,C9,6C,15,37,E3,DA,F6,79,9A,F2,1C,14,3F,DA,62,ED,FD,C1,B2,49,0D,C4,9C,4F,69,47,25,2C,60,93,63,D1,86,E1,DC,A0,83,9F,92,6E,C1,9A,36,BA,DA,21,B2,C6,1D,4A,78,C4,0A,99,58,33,6E,CA,FC,6A,96,91,6B,03,91,EA,E2,16,2D,76,7D,97,13,5D,B8,88,C2,E3,7D,BD,67,03,15,A0,B0,23,B8,C3,AB,72,83,FC,66,D3,CD,87,6E,07,33,0F,43,D0,0F,22,38,55,5E,B9,27,03,EF,8B,E9,8A,D0,A6,C3,FD,15,34,E6,C0,B1,8F,19,69,7A,D4,44,D6,C8,E3,48,91,69,FD,8B,02,0B,69,DB,34,3E,AA,7F,EA,5E,0F,75,06,66,D8,0B,11,50,E3,29,6B,BC,48,E5,FE,00,E6,9B,F6,44,42,65,B6,B2,6A,B1,0E,04,A9,5A,1E,A2,D5,D2,02,3B,8F,77,20,08,DE,E1,7C,BD,B5,91,2A,7F,DA,8A,DD,98,89,99,E7,21,52,B0,F7,DB,5E,FD,C6,00,8A,FE,C8,02,76,25,BC,79,57,4D,D9,2B,CD,E6,55,70,7E,CF,EC,78,67,BD,A6,19,BA,C2,5D,21,03,47,5F,C4,49,E3,89,DB,BC,60,F0,FF,13,30,D2,79,61,DD,43,EC,40,0A,C9,2D,8C,65,8A,A9,3E,CA,72,71,67,C9,C5,B2,0E,50,E3,E6,30,2B,9B,88,65,E7,1F,44,B3,71,4C,AC,70,F5,B5,A3,90,89,C5,F0,A2,9B,A1,AC,E3,3A,04,0E,67,78,CC,85,36,3A,02,1B,9A,13,02,13,4A,5D,20,23,CE,A1,CE,51,A1,7D,16,49,F3,B4,CC,06,8B,61,51,20,FD,DA,DC,0A,12,57,4C,05,A1,41,75,11,60,F2,36,E1,E6,56,E7,D8,8B,49,FA,81,FD,2F,54,F6,72,02,B3,AB,FA,78,B5,B6,A1,02,90,E4,6A,57,15,54,62,61,69,86,E6,57,77,E7,54,50,AD,52,C9,70,88,E5,9F,5B,68,D8,81,56,01,7A,DE,C4,5C,AF,D5,72,90,DB,1B,7B,B4,DD,D7,54,FD,88,54,43,E7,40,47,03,85,60,AC,37,87,49,E9,7B,77,28,57,B4,42,CC,9A,FB,50,01,63,27,4D,C7,0B,3E,9D,A9,1D,5B,EE,6B,E3,B6,C6,53,A7,A6,B3,86,32,BC,6D,C4,3C,0A,54,3A,11,70,A6,A7,32,6C,1F,9F,20,C7,17,B4,1B,83,00,E2,5B,E4,71,95,70,59,1C,F0,01,90,A3,26,31,7A,A4,2D,CC,29,8D,B7,25,54,FD,9E,0E,2E,33,73,9A,6D,66,46,7F,7E,E6,7D,3A,EC,03,35,81,CC,43,A6,C6,8B,AE,15,EA,32,4B,A2,4C,C1,82,06,30,34,03,BB,0D,6F,BF,C9,5B,61,7D,F8,FB,81,6C,7B,3D,E0,CC,7D,0A,0A,27,31,4C,F4,2F,13,14,93,5D,E3,DF,37,94,BA,D1,06,B7,2B,9C,87,E5,70,F2,3F,7F,C0,7E,BF,E5,74,C9,CC,36,E6,2B,11,70,A6,3A,1B,87,89,B2,57,CC,F4,EC,85,3F,4A,83,5C,99,1D,9B,FB,DB,55,D7,74,30,51,1C,BD,94,81,32,58,51,C8,45,EF,03,EE,5C,E0,6E,B7,03,07,6B,43,C4,42,3C,89,70,56,84,B7,60,D4,EB,CB,4B,A1,42,2E,DB,5C,73,B4,1A,FF,D8,C4,69,A4,4A,96,B6,A6,BE,75,1F,B2,6B,46,D4,FF,8B,45,19,7B,01,8A,F8,9B,41,B2,4F,78,02,F4,50,68,A1,1A,3D,06,36,14,A8,5F,B9,A1,89,20,F1,04,78,F3,B1,41,2E,5C,6D,E9,38,91,5B,F5,13,BC,D6,8E,32,A2,63,56,48,85,E4,0B,E4,99,31,C5,6F,92,CF,CC,EA,82,70,88,55,8D,41,B2,F7,E1,47,F7,42,66,67,79,16,51,6F,DC,E0,EF,04,25,4E,00,09,0B,33,49,28,85,53,EA,02,FF,BE,5A,02,77,18,3F,66,E6,15,05,75,5D,18,6F,34,E8,BC,D6,6D,77,70,FB,74,5E,3A,8A,82,7D,F2,D5,03,AF,8F,45,EB,61,7A,08,C7,10,55,8B,E9,4B,40,FD,83,84,2F,6E,01,12,08,36,37,FD,97,DA,C1,2B,EA,7B,C5,A9,9E,86,5D,CA,A6,87,20,44,77,D9,B5,6A,DA,9F,C5,5D,75,B2,4E,FF,45,69,35,94,6C,EA,98,64,27,E0,8B,2F,F0,1D,10,F9,92,C8,2D,9E,AD,FD,A1,A4,B9,00,0D,29,51,C6,72,85,1C,74,0A,9F,68,14,78,6D,52,6F,DB,C8,FF,F2,12,B5,40,0B,DB,4F,94,98,D5,64,AE,7E,2B,AF,72,48,E8,A7,A7,91,B1,B2,AF,39,5F,E0,A1,E7,31,C5,0B,1E,CF,92,EF,85,6B,05,71,43,78,63,CC,ED,A7,B4,1B,91,EC,F7,26,52,F1,96,4A,45,12,EB,53,D9,18,7D,51,4E,D1,B4,B6,FB,5A,11,38,29,69,A4,08,53,89,9A,9B,80,31,4E,E2,9C,69,09,8D,89,B6,81,4B,71,14,4F,16,7A,B1,45,CF,2B,13,EB,B5,BF,54,92,42,FB,5E,FA,3E,B3,85,FC,BA,D6,6E,65,AB,45,3E,FE,D6,22,8C,9E,6C,0F,F1,87,E0,8D,DF,1F,82,38,A4,7A,61,18,D4,D9,6C,1D,43,FF,6D,95,27,58,91,AD,D8,BC,BD,AA,2F,C4,B0,69,22,2D,84,00,FB,EB,C2,AD,0C,E4,8C,69,3C,77,7E,96,34,8B,14,54,55,FD,DB,32,82,97,F7,A1,67,9F,F5,4E,26,DA,B3,90,E3,27,12,C7,74,6D,CC,21,A4,F3,58,3F,77,4D,E6,E7,9C,F9,28,B6,70,0F,04,FA,71,EF,ED,A3,78,41,D0,3F,89,B3,DB,0D,C5,55,66,D3,7D,FA,0C,89,6E,B2,E2,5B,61,EF,2A,2C,97,6A,09,6E,26,9A,6B,58,4A,FF,DE,14,8C,96,21,2D,DD,5B,5F,E2,1A,2F,5B,46,D0,4C,A6,99,43,33,42,88,D8,F6,AF,D5,FB,71,1F,A0,CC,1B,F1,29,86,AA,14,4F,3D,AA,04,CB,45,BC,DD,E3,4D,51,4A,E1,D8,3E,4E,A3,03,C6,5C,EF,0A,DB,62,81,BF,90,AA,82,05,3B,F9,AB,C6,63,9D,4A,E8,48,E2,E7,F3,26,FC,73,8F,22,8A,3E,F1,5C,64,A4,09,39,AF,41,8D,6C,87,46,EE,93,1E,85,EC,56,3C,C8,8B,98,CF,63,F8,E3,E7,A8,67,FF,58,DD,6B,5E,94,40,62,76,EA,F1,EC,B2,02,DF,27,F0,5D,C4,FE,62,1D,B2,E8,41,D3,AC,72,38,B1,83,72,E2,CA,A9,DB,95,19,4F,FF,52,25,DE,D7,14,09,8B,5C,24,1E,EC,94,6F,C0,59,7D,A9,75,19,FF,DD,25,EA,68,06,C6,B6,92,BC,58,56,96,8C,2F,43,34,02,CB,6F,6C,25,F9,8B,EA,47,9B,F8,E7,E0,7B,91,FC,2E,69,B5,3E,D4,E0,42,2D,66,D7,1B,4C,F5,C8,9E,1B,BA,13,5B,76,C7,D6,D7,8C,6B,90,51,AE,71,7F,12,DB,46,98,FC,33,CF,7D,DB,8A,1F,72,2E,5E,1B,9E,4E,C2,9A,CB,FE,47,DD,43,B4,FF,1D,40,A6,73,E1,EE,F1,FE,EE,4F,28,F9,88,C2,CC,BB,6D,84,BD,EE,55,B3,FB,55,C7,48,A9,A4,6E,46,52,E2,37,F9,14,2B,54,39,AE,EF,A4,BC,2A,76,9B,1A,2B,CF,BF,72,7A,11,31,30,0A,B4,24,7F,FA,83,3D,A7,1D,64,97,9B,73,5C,04,36,AE,8B,79,4E,61,D3,EC,B9,C3,78,1F,FE,5E,F0,32,B8,23,61,B7,F0,0D,4C,A3,76,C8,95,8E,EF,39,BB,1A,BC,BF,44,A6,B2,26,BF,18,4E,9A,D0,F1,49,7B,C0,3A,CB,3B,18,80,75,71,61,51,3A,33,A8,38,E0,25,E8,8D,E1,C6,84,C9,33,9A,27,9A,E9,10,E2,D6,42,B8,C1,24,D2,DB,86,4A,26,48,71,29,E0,EA,EB,AE,0F,25,5B,D2,05,BC,49,41,78,00,65,4B,C2,96,AC,80,47,47,0D,84,E4,A2,EF,4C,C2,11,5C,1C,D3,51,EC,73,57,02,2A,C5,B5,91,17,B3,27,09,8A,AB,52,97,A8,1F,4A,1F,32,6C,1E,AA,BE,AC,BA,13,70,4F,BB,91,89,8F,37,4B,6E,1A,C1,5F,14,FE,64,F7,37,A3,33,13,B4,F5,1E,0D,1D,41,40,EE,D2,61,C8,DE,EF,B0,E3,99,85,36,35,51,C0,09,B7,AD,FA,B4,48,59,66,82,3B,6B,B2,61,E8,17,10,D8,48,DD,78,85,5F,5E,39,E0,EA,55,C9,31,D6,6D,A9,61,AA,A2,48,D5,5B,D3,B3,D1,4F,4E,85,07,B1,A3,B2,E5,35,B7,0B,FE,B9,9E,C0,CD,DB,29,CF,81,4E,3D,37,D1,BC,C8,77,66,55,44,4B,DD,63,6F,64,10,71,05,A2,8B,EE,93,A7,C6,AA,1F,1C,8D,9D,1C,6B,71,14,3E,0B,99,18,E3,07,2D,51,99,AF,31,52,E3,3D,C7,6C,A4,9B,2E,8E,12,1A,9C,E8,A6,5A,83,70,80,58,A0,3D,1A,0E,92,05,44,2A,CD,42,62,62,DE,AD,EA,59,92,C8,62,AE,B0,61,FC,11,91,0F,05,9D,01,1B,59,E6,E3,54,9E,26,B0,05,B8,49,F3,9E,D8,6A,5C,F6,C4,F6,5B,C5,B7,FB,56,52,37,84,35,D1,02,D7,D5,CC,F4,1C,28,E9,94,EF,59,63,52,46,58,4D,67,89,C0,44,FF,FC,74,11,C1,EB,8D,40,1D,F8,67,F5,8A,B0,67,E2,91,43,FA,C1,44,4A,77,39,D3,C1,73,F3,F8,9C,30,32,FE,13,37,3F,C5,F2,39,88,A3,3A,2E,E5,D9,DC,73,5D,59,56,89,76,39,CE,B3,8B,F6,D7,07,7E,D9,10,1A,3C,19,ED,A9,3D,2B,14,58,0D,17,94,36,D6,D5,64,E9,92,69,A0,70,B4,02,0A,5D,41,02,FE,9B,EC,A6,94,01,1E,78,85,B8,81,D7,E3,3B,FF,17,C7,56,67,0A,E3,F1,E7,9F,CB,F0,F1,33,3D,1F,92,7C,5B,03,A8,49,CA,5B,36,81,77,78,1B,0D,98,33,E0,01,DF,2A,8D,74,61,E8,B5,BA,80,50,B0,5D,5D,D3,57,9D,D5,31,06,9D,70,F5,69,C5,6E,6C,29,FC,1F,BE,7A,A7,C4,B4,0C,61,B6,D7,49,C6,34,FE,F5,4D,9D,98,7E,80,A9,1E,0F,D3,56,92,C5,9B,91,ED,7D,99,18,C5,F3,DD,81,9B,95,13,A1,05,3F,9E,08,21,D5,C1,6F,0E,93,39,C9,FC,C9,ED,03,75,9F,55,10,75,BE,61,F9,C7,4D,02,AB,96,90,BF,47,05,19,64,D0,D3,8B,3F,E8,78,A0,95,57,C8,F9,66,44,FF,32,F3,B3,72,FE,52,12,46,BA,35,F7,1A,7A,69,FC,2A,A9,5A,C6,29,00,94,D0,EF,4C,11,64,71,92,61,ED,3C,31,7C,34,C4,49,D4,AE,FC,3B,43,A8,A3,71,51,52,9D,ED,B2,0E,79,A5,CD,13,24,00,C3,B7,46,D1,B7,B2,F6,1A,EE,AE,4E,3D,D5,BF,EA,F5,DC,0C,49,47,33,19,F0,A1,51,E4,95,48,CA,4C,54,BD,D9,AD,A4,86,DE,BD,46,FB,F3,AE,AD,F0,C5,5E,24,E1,4D,02,81,99,FD,F1,D2,9A,C2,EB,62,4F,2B,9F,78,A1,C2,E7,CE,08,30,55,A7,32,9E,F3,B1,2D,F9,26,7A,B3,42,24,64,ED,1D,60,02,71,7A,64,AC,52,A3,8E,76,E5,3B,25,51,E3,C9,4E,FD,19,C9,9C,64,93,1C,74,78,89,CB,39,12,55,0C,7A,20,8F,EB,39,6A,B6,3C,71,47,A6,56,A7,F5,50,BB,D2,4E,24,97,80,1A,75,26,CF,50,32,3E,66,A4,13,13,8A,5B,7F,A5,73,EE,66,84,0B,20,47,F8,6E,7F,00,BE,B0,C8,57,E1,C1,F5,A0,EF,83,0A,3D,44,85,A0,BE,DC,18,BF,08,6D,B9,7B,45,E4,DD,D4,55,AF,32,A7,20,AB,FC,58,DA,BD,58,7D,F1,A8,BE,0F,C4,A0,F4,CA,70,7B,4E,C2,02,1B,37,1F,9A,0F,58,76,0D,CE,40,FD,49,33,70,2D,E0,82,B5,9F,8D,87,5F,73,20,C3,1B,CB,5B,C9,83,36,CD,81,8B,80,4A,28,7C,67,57,40,BE,7E,BD,30,FE,9B,73,1B,85,13,1F,0C,70,B0,56,4C,DC,B6,E3,CF,6A,C3,1C,FA,11,6E,6D,47,8E,61,81,9B,B8,BB,96,C7,17,81,43,4B,77,E0,AC,93,1C,3E,78,3F,CA,28,6A,15,BC,2B,2F,BE,0E,FB,2D,67,6F,1B,96,4F,D5,FF,3F,04,10,60,D7,14,51,87,31,91,2B,AC,90,A7,12,C4,7D,7E,80,B6,CD,B6,C5,B5,5D,C4,FE,4A,2F,C8,B0,D7,3B,D8,BD,65,9A,DD,C6,D1,AD,3A,54,3C,F6,B3,38,38,64,DB,D8,EC,42,EB,A9,E9,B2,DA,AF,EC,93,3B,7B,9A,53,B7,85,31,46,17,D0,18,A7,8A,A7,FA,7F,19,76,04,1B,39,64,B9,3A,25,D3,C9,EC,C3,40,A7,25,6F,82,06,CA,28,97,88,27,82,0E,E1,1D,31,9C,09,A8,2B,6F,B7,B9,63,F4,01,79,CF,58,53,35,D9,58,48,DB,0B,C3,9F,11,5C,1E,4F,6C,4F,DC,25,42,8C,71,90,1C,E8,25,AA,16,9A,78,7D,F2,71,88,E3,49,99,31,19,3A,EF,93,AA,69,45,38,B4,12,78,4C,2E,9F,1A,AC,4C,AF,3D,BF,53,FE,7B,59,41,58,39,F4,EF,D7,2E,58,A7,66,52,09,89,0B,8D,01,F9,21,DA,C6,93,1F,FF,1F,4E,75,39,9F,F2,A5,AC,C1,5B,0A,90,B7,06,9C,F0,72,FB,3A,BD,F6,36,9A,2E,4F,D6,3A,5D,99,CF,D1,7A,20,24,A8,1C,4C,F6,15,61,5E,E5,A4,B6,87,06,13,E4,E3,9C,A4,90,7F,1D,8F,90,96,19,24,C8,D4,61,05,8D,74,93,4D,31,46,EB,7E,A8,AA,E8,A2,A2,50,56,EF,5B,6A,AC,6A,2A,23,61,5C,93,A4,01,C1,9C,D4,20,18,8F,BC,11,80,53,AE,0E,97,AE,E3,D8,F4,99,50,58,FC,AE,A5,A1,3A,11,20,CE,C4,C8,B9,55,22,3B,38,D9,0D,B7,94,4C,27,0D,71,E5,AE,A1,53,AB,6D,F4,94,68,EA,72,55,A4,B5,24,51,A9,05,60,42,AB,05,9D,2B,62,BF,8D,10,96,30,5E,9B,49,8D,29,C7,FF,09,12,53,37,1A,23,67,4C,0E,13,15,00,86,48,EE,62,D8,08,DB,D2,A7,87,E6,B2,C1,2D,41,56,F2,F2,E5,78,47,70,B3,EB,05,0D,7B,FC,27,37,0D,58,3A,1A,B6,F4,9A,0D,13,CA,AC,C5,E2,78,9C,D7,B8,D0,72,24,7C,62,6E,4B,AF,4F,68,46,B0,09,A2,9E,A0,A6,63,F3,E2,97,17,96,15,C4,BF,58,B9,23,85,7C,A9,1B,70,24,7D,F7,29,58,E6,11,60,A4,7A,4E,18,AF,70,AB,C9,21,62,20,D0,1C,8A,1D,C7,44,45,33,6B,63,39,0B,40,38,E9,2D,B7,8B,7E,70,73,3F,4D,F9,41,90,3C,8D,C3,8B,FB,58,80,41,49,C0,3E,C3,31,BA,4D,AD,B4,11,6E,42,D2,7F,1E,B7,D3,4F,1A,C1,17,94,85,BA,06,60,F8,26,4C,74,DD,FA,24,5E,8F,17,40,09,98,EB,EF,A6,41,1F,CB,F0,38,CF,EF,1D,44,0B,32,0C,4E,17,7C,19,58,84,29,6D,63,97,0A,AA,26,56,C4,41,A1,53,7E,DF,41,39,51,34,4D,32,5C,95,CB,92,76,90,CF,82,24,11,BA,E7,01,85,BD,6F,90,BF,91,20,D3,E2,33,80,A5,51,64,1F,06,1B,BC,24,EB,28,F2,FD,F8,91,8A,2A,09,D0,0C,B2,C9,3B,C3,68,3F,66,58,2A,93,2B,0C,11,0D,0D,81,9F,EA,07,72,0B,01,7B,38,64,44,65,A3,93,14,BD,7C,B2,82,F9,BF,B2,74,B1,4B,74,30,6A,2F,B0,18,39,D5,F1,F3,AD,22,58,8A,29,4B,5D,4A,B7,94,FC,FF,61,A3,CD,83,30,FA,E4,DA,6B,A1,16,17,35,4C,C5,A3,9D,40,87,AA,5F,75,30,09,14,AD,E2,63,55,8E,6F,C7,6A,3A,62,DC,8C,D3,C8,E7,1E,65,93,C2,6C,1A,D3,56,55,C4,08,24,6A,37,8A,41,4C,39,A2,5B,96,34,71,CD,55,F7,DB,60,A2,6D,85,E5,1D,AA,D6,11,F2,C4,22,11,39,6D,62,3E,07,5D,6A,82,74,A6,8D,A7,AD,D0,12,58,FF,C4,31,9F,D5,FA,7D,2D,F4,A9,8C,0F,8D,A8,1B,8A,81,69,97,ED,A8,1A,3E,8F,76,A5,86,FF,12,33,D7,12,64,84,27,0A,FA,3D,27,B0,C1,C6,D6,6E,DF,12,65,71,A4,A2,85,BF,41,EC,1F,D7,D4,9F,54,79,BB,13,C0,57,CE,0C,5C,5F,01,34,F8,C6,74,DE,95,7E,75,81,D6,6F,3D,D4,37,2C,DE,59,E3,2F,F2,A5,AB,D9,AC,C6,94,FD,38,9E,92,61,96,17,03,4F,02,AA,FF,88,67,14,10,D6,87,3B,CE,2F,EA,B4,07,D9,2E,81,39,D2,8D,05,A4,59,B9,B5,E7,2D,19,73,48,A2,60,B4,57,38,1F,B5,72,1C,1A,3F,5B,8F,42,AE,D0,37,27,99,1F,90,AD,4D,D6,BD,7E,C2,CF,85,5A,4A,0E,10,39,2B,FB,09,63,4B,94,74,8F,A2,9B,77,5C,71,AE,C6,AA,5D,9A,7F,16,AE,28,C5,AA,B7,5A,43,8B,79,DB,59,F4,18,8B,B0,7E,D1,C5,AE,E8,68,F2,3C,7F,17,B4,3F,B2,7A,10,D6,45,F4,CE,91,07,F0,C8,45,B9,59,33,F0,90,8C,DF,E0,FB,63,15,94,61,72,CC,FE,2A,FB,5A,2E,94,E6,0F,9A,C4,DC,01,7B,59,8D,B2,C0,DA,87,DC,A6,B3,B0,D5,E8,13,1E,0F,EB,A1,52,26,6F,6C,87,A2,82,E6,DC,A9,9F,42,BF,C6,97,C1,40,D6,E3,F1,D8,09,5A,E6,2F,47,BE,C7,E5,21,C7,E4,39,93,CC,4F,58,06,05,8B,FA,9B,4B,95,55,43,A4,8A,AB,2A,44,B2,2D,F2,31,3C,21,8A,3E,9D,A8,D7,69,5C,6F,1B,F3,A5,48,68,FE,80,41,2C,2F,36,8F,4B,88,E9,DD,D9,CE,9F,72,A8,E9,A3,84,EB,83,0E,3E,8F,68,E7,FC,95,79,2E,29,55,80,41,39,F8,8D,74,41,2A,C8,11,7D,BF,42,39,28,A0,0C,95,49,0B,9A,49,93,F7,2C,05,AC,AB,02,29,F7,29,B9,DE,D1,C7,CF,41,AF,A3,C7,3C,8D,77,E7,6A,A8,F1,CA,52,BF,8E,5D,40,EC,E9,37,0F,10,83,6B,A3,AA,63,2A,D1,AB,02,B2,0D,D2,3A,25,34,8F,98,5F,33,BF,6D,45,9D,12,11,38,8C,E4,BF,B1,60,58,D2,E2,46,0F,EC,7E,D4,92,ED,E0,E5,53,91,34,2D,A4,01,A7,6A,FB,9E,F5,ED,C4,B1,52,2C,C2,BB,8A,E6,4D,0E,7C,93,91,98,93,6B,99,BD,37,66,DE,51,53,6D,CE,7C,9E,2A,80,83,CC,7B,02,7F,AA,12,ED,2A,41,96,F3,82,78,4F,B2,CF,87,AF,9E,58,42,0D,A1,F2,F5,38,B1,D3,E2,C4,7B,D8,41,41,8D,51,C0,BD,5F,EE,B8,A9,48,56,1E,C3,AC,C3,6D,C5,37,97,89,B5,88,DA,9E,CA,63,20,06,94,DD,31,72,6E,FB,BA,00,4C,B1,D5,1E,AE,1F,4E,7C,50,7D,28,F0,2A,05,17,8C,2B,A5,97,5D,E7,D7,E5,B2,41,6C,25,CB,E1,EA,E7,38,66,E9,ED,DD,8D,79,E3,9A,21,66,31,B4,4D,71,85,DD,30,E7,04,ED,56,51,A0,44,BC,2D,A0,FB,A3,E6,AD,48,DC,34,89,C5,80,01,A9,19,9E,4C,4A,F5,79,08,F5,0B,91,1F,8D,00,B1,4E,B8,D7,36,B0,4F,93,CA,D1,C0,EA,01,67,7E,38,15,2E,B4,16,87,D5,A2,BD,B0,70,6D,78,34,6E,C9,75,1F,29,54,E1,1B,47,02,18,FD,9A,BE,47,F6,4C,1A,7A,93,98,C8,10,D9,42,4F,86,EF,A4,C6,36,B3,18,3D,D7,C2,79,D7,AC,62,77,8C,20,94,B6,F2,AA,EE,68,BB,C7,E1,D3,E6,48,DF,BD,A2,89,7D,DF,84,94,4D,9F,9E,E7,30,10,CC,00,44,17,3D,2B,0D,F2,4D,E4,69,C1,D3,40,96,6A,BF,17,6F,5D,C5,42,55,05,74,37,EA,B7,5A,62,92,A9,02,DC,9C,78,ED,E4,67,6A,B2,38,9F,AE,23,41,B3,B5,E1,62,91,87,EA,25,2C,83,90,30,59,7E,FD,34,1D,0E,26,F4,76,1E,22,92,A6,3C,EF,42,C4,F9,EA,EB,90,89,0B,83,EF,B9,0B,0D,EE,3F,B4,4F,D6,01,28,25,F7,08,81,11,ED,A8,BE,FA,09,E3,3A,75,43,DD,70,02,70,BE,D9,06,BA,5B,DB,41,C6,41,18,94,34,C7,29,AC,4B,34,95,9C,6C,21,6F,F4,AB,F5,65,BB,9E,35,62,B5,80,96,60,4F,7E,6F,C3,8F,9B,2D,A9,E0,30,78,66,16,92,FC,9B,7F,02,E4,20,47,D6,DA,A8,E6,E8,F4,F5,58,15,EB,D0,6C,C1,BF,71,84,7B,2A,77,2E,BE,49,28,D0,D5,DF,B0,41,01,84,60,D1,43,71,05,1F,6D,26,E4,01,A8,5A,50,A0,6C,97,78,1F,AF,5E,AF,4A,DF,94,C9,8D,C7,DF,01,88,86,F6,22,36,0D,E6,91,94,97,81,68,0A,E0,7D,03,F0,CF,F9,81,A8,ED,D7,36,98,56,91,89,D8,AB,00,09,3A,0A,1C,1E,64,AD,69,EE,47,39,F8,85,2B,BB,2D,10,C5,43,0D,8D,26,B2,0B,14,D4,64,AE,91,9C,06,D5,28,95,47,3E,4B,DB,65,FB,D4,A1,25,74,F7,9A,C7,8B,E5,6E,37,46,0E,6A,35,D3,BD,2D,8A,F5,A4,94,58,BA,F1,92,6C,77,29,2C,78,BB,95,C1,87,14,1D,8B,19,E5,6B,83,C7,45,98,FA,52,E0,F3,AB,C3,0E,0D,2C,99,B1,A3,1A,96,4F,B2,76,D6,E6,7C,D0,28,B0,51,A7,49,84,28,DC,46,D3,7B,20,F8,9B,00,6F,00,48,5D,D1,F3,1F,5E,2E,1D,CD,04,36,1F,8F,E3,1C,93,8B,F1,F2,5F,68,15,EF,50,27,2F,34,B5,A3,9D,B6,4D,54,9A,FA,66,67,34,A4,CD,5C,E1,22,C5,FD,95,39,F6,DE,40,C4,E5,59,18,E5,82,1B,95,F8,AA,32,E0,12,30,F5,F7,60,9C,90,FC,3C,89,78,5C,BB,31,5F,CE,90,D9,90,2E,61,A3,94,1E,1D,07,67,FB,0F,E6,A6,5E,7E,99,AB,DD,54,5E,58,66,EA,D7,E8,CE,97,53,98,84,46,69,30,06,37,03,24,35,82,FB,29,B8,00,31,F4,C7,C8,F7,EA,53,56,82,D7,1D,53,E3,05,C8,B5,E1,FC,6B,20,0B,9F,0F,40,00,D4,F4,1D,4E,12,7E,C6,37,4D,F8,D7,7A,8C,69,35,C8,C8,AC,60,99,E7,03,B3,4D,BC,C0,C6,FF,74,76,15,CB,92,97,16,95,ED,55,FA,D5,4E,C6,F2,3F,22,11,71,E6,3E,50,61,02,D9,35,D9,32,DF,4B,30,0B,FC,56,55,BB,1F,44,47,C3,A0,38,B8,D5,1B,75,3C,DF,F6,C6,04,46,45,5E,65,FA,24,38,96,A4,57,A7,A1,6F,E8,85,E9,17,24,2B,CF,38,D2,85,CA,80,AA,F3,BB,DC,C5,57,DC,31,35,29,DE,9C,0B,C4,33,9F,E8,29,E1,78,E6,1D,B4,1F,CF,76,79,8D,D0,47,E2,46,91,8D,A6,C9,BC,50,20,D6,A7,EB,EA,B8,EF,A5,EE,5E,0C,46,13,E9,B3,A9,7F,86,8E,BD,F8,63,00,4C,19,8F,0F,68,01,B6,BC,22,19,54,EF,F3,9F,14,81,6B,B4,85,5C,DE,73,29,8C,1A,2C,F2,7F,D4,44,4A,7E,A6,BD,E3,D7,EF,84,E6,88,39,07,93,F1,75,D1,8B,79,FB,F7,80,9A,4F,4A,D3,3C,4C,B1,E3,CB,C1,45,56,7C,C3,A3,95,63,E0,36,48,6F,84,F5,CF,EA,B8,CE,0D,18,CD,B7,57,E8,E1,D1,76,D3,DD,BE,3D,5B,EA,59,D5,3E,80,C8,7C,37,2E,A6,39,34,9D,F6,AD,0D,97,3A,C0,D6,A7,D0,12,EC,08,CA,C5,08,15,49,23,44,36,3B,65,BE,80,F6,A0,2E,57,1F,E4,01,A5,BA,B8,9D,F3,26,DE,C5,2D,87,C6,B0,24,A1,60,FE,22,34,20,F3,E0,B6,65,37,4A,90,6A,04,71,E9,9C,89,F9,FA,3F,73,2E,56,80,69,01,B9,2E,55,2F,31,4A,53,47,43,D4,BA,E4,44,6E,BA,72,F2,CC,E1,E7,0E,B0,37,AC,B5,B5,4D,1B,1C,90,FE,89,D8,2F,C0,AA,0C,B5,23,34,8D,2F,F2,CF,C2,EB,A8,3D,0F,DC,B1,63,3A,4C,58,09,3A,A2,71,4A,CC,40,F1,10,FD,FF,E6,A2,64,14,9A,66,1A,10,0A,47,8E,A5,C0,B8,F8,AE,32,4D,27,A2,5E,32,63,2D,89,AA,42,BE,54,CE,BA,8C,38,25,01,B4,55,03,57,31,9D,E8,5D,28,5A,6E,1D,51,7A,2A,D8,2B,ED,49,F1,CB,A4,57,07,AE,CB,3D,21,3B,FE,F1,BB,4D,A8,E0,5C,05,B5,67,F8,22,E7,42,16,25,A4,75,E5,E0,45,2C,EA,0F,B1,B4,62,F5,6C,CA,F5,2E,F6,89,F3,BA,09,29,FB,0E,BD,4D,30,36,16,27,17,A1,2C,52,20,E1,58,EB,EA,45,B0,B7,02,F6,39,A3,19,4B,EE,E0,D4,B4,F7,13,57,D7,34,78,B6,8D,19,B4,BC,91,9C,86,F0,DD,84,37,FD,0E,C1,FE,64,BB,41,EE,EB,44,BE,C5,F9,5A,B4,13,16,F1,5D,17,33,D3,10,6D,5F,97,E5,DA,8E,7F,82,1B,52,90,27,6E,40,F0,4F,67,AC,88,F9,1A,B9,76,FA,90,84,24,09,F0,D1,02,57,FA,95,5F,7C,36,02,3F,5E,B5,93,1F,F2,6D,13,3F,1E,40,B2,34,77,4E,A2,29,C1,45,63,3B,F4,93,C4,B5,9C,48,7F,E9,67,30,9B,BA,D6,AA,1B,BD,C9,58,A6,1E,BC,95,FF,9E,54,BA,3C,6C,B6,E8,60,54,44,7D,B1,31,68,32,AF,95,DF,3A,72,98,C2,DA,DC,A6,DE,6C,20,87,85,AF,CC,95,EB,1C,AC,8B,50,CB,9F,76,FE,74,AD,1F,18,82,8F,8B,84,EB,8E,1D,60,AC,0C,01,58,5D,1A,11,09,F8,C1,95,FC,C1,14,A9,1C,B8,3C,DB,B2,46,D0,85,2C,1D,D8,FB,7C,85,F3,35,D5,B7,62,DE,6B,E3,4B,CB,95,71,55,EE,AB,FF,70,24,3A,64,68,63,36,CA,F4,F1,D2,21,37,2B,E5,42,5D,66,7D,E3,8F,B3,04,86,F3,B5,61,47,48,EB,71,52,13,53,78,65,FD,B1,FF,DF,15,37,8A,DD,C0,32,22,31,1B,81,6F,D7,6D,E5,1A,F7,9D,CA,E4,A7,C7,AF,53,94,4C,BA,7E,92,F7,CF,45,DF,48,68,C4,51,30,F7,80,39,28,AE,AD,EE,B5,3F,72,E2,BF,93,76,02,E9,50,6F,A5,4A,FF,AD,91,8E,4D,8E,BE,57,D7,DD,D4,05,AB,C8,7A,9C,59,CA,D2,43,EC,38,D0,42,CB,26,F8,23,BB,BC,4F,5A,F5,D6,B6,6D,A1,8B,9A,F3,EE,D2,8A,80,53,D8,40,4C,22,B2,A3,C4,55,2B,5C,CE,90,BD,F5,16,63,AF,38,28,DE,78,74,E0,B4,B7,05,4C,A5,22,CB,26,CA,EE,5F,4F,39,2B,D8,9D,54,4F,D9,B4,5D,00,5B,A5,D4,71,F7,1E,A9,DE,57,4A,97,D4,40,9F,1B,DD,28,97,4A,A3,A1,60,F7,05,06,39,B7,00,73,89,B9,0A,06,CA,57,13,DF,0E,00,F6,DA,7F,45,F9,32,44,42,36,4C,A2,B9,83,99,D2,63,AC,88,7D,58,B2,EB,8F,02,29,93,C5,55,F9,A8,5E,08,03,43,D8,73,1E,45,10,6E,FE,84,D4,6E,EE,C2,FD,29,41,4E,AB,FD,38,7A,F9,8E,DD,3A,F7,71,DA,C2,68,00,28,9C,50,04,B7,ED,71,37,9D,CC,65,04,A7,14,5A,A6,92,C1,63,69,9C,68,10,66,AE,7B,6E,F8,34,4B,FC,B5,86,E6,FF,74,93,3E,68,32,BC,B9,0E,E7,7B,35,D2,A1,E0,84,66,B0,C7,F4,1D,61,09,50,8C,AF,66,73,C3,DB,8C,7F,F7,6C,65,B9,C3,B6,7F,AE,FF,F6,93,84,4A,6C,91,0A,19,33,33,DC,19,CB,A4,AB,93,7B,E6,64,D9,16,A2,28,EB,D5,B9,FB,43,93,0B,B9,5B,C7,FD,16,51,E2,D7,98,E1,FE,A5,AE,20,B6,29,A4,93,54,0D,9D,EA,77,A7,39,CA,E7,D0,84,29,6A,F3,86,3E,41,8B,DC,0A,AC,D8,C3,6C,80,E7,D4,75,27,ED,09,0F,B2,D0,08,40,0D,A9,08,85,BF,3A,91,2C,29,89,75,CB,3C,7D,10,86,83,96,74,A3,90,16,0A,B7,B0,6B,4F,72,39,DC,64,A7,BA,9A,E0,03,89,B2,17,52,7A,AF,33,7C,A7,B3,5D,7B,64,7B,F7,13,15,47,70,9C,6A,23,67,81,72,F8,48,A9,86,41,7D,88,A9,AA,3D,B3,7B,F1,BA,D3,F2,F5,0C,C4,0F,23,AE,E7,90,3C,F2,B5,C4,F5,94,15,1A,3A,4C,9F,11,CA,C0,6F,E2,6A,BF,7F,EE,7C,7E,B3,2F,8A,3B,D0,63,0F,F3,39,98,98,0B,B4,8D,4B,E7,F6,A2,F4,58,AA,B5,94,6D,DA,C7,24,55,76,E0,34,51,CB,DC,B5,9C,95,87,DD,A6,A7,7F,63,C5,B1,95,FC,37,31,7A,2A,38,8F,DC,41,AE,8A,C1,1D,18,14,EB,6B,20,98,60,A9,E0,41,0D,15,0F,0F,46,02,7E,88,88,67,69,93,72,C9,7A,B3,59,A4,23,DA,37,3F,35,C8,46,37,BC,4B,C4,53,EE,C9,4C,50,9D,38,20,DD,BB,8E,BA,56,02,74,E9,C7,39,41,E0,CE,0A,56,A8,79,FD,41,97,35,F4,45,AC,AF,E5,55,EB,08,7C,1F,1F,E7,4B,A1,A3,A1,35,4E,06,EA,58,60,4F,01,AD,E6,E6,1B,A0,29,9C,46,EC,7C,B9,07,43,8A,35,47,71,EF,53,BD,B6,ED,E5,7C,BA,E0,AE,B1,2E,A4,35,3D,54,DB,A8,5A,22,60,D9,7E,43,DD,4E,6A,6D,D1,80,D8,74,93,65,73,63,19,73,E2,84,A1,9E,6C,CD,AD,BA,94,29,F1,77,89,E7,34,54,9F,E1,BC,25,2B,AC,E3,1B,E6,01,75,38,11,D3,22,1E,80,74,DE,97,B8,2F,CC,B1,1B,03,E8,49,6B,F8,D4,4C,26,2F,79,B9,2A,BB,0C,B6,B0,22,CE,07,64,D9,EA,B6,AF,6D,06,61,35,AA,D0,B4,AE,BC,1A,1E,3A,5F,FC,38,95,1C,BD,A1,97,BE,CE,64,21,05,C7,89,BE,21,6B,BC,EC,5C,0A,4E,50,12,90,CD,D9,64,B9,E7,C7,90,A6,3C,02,64,9B,A8,AF,D1,48,D7,27,51,A5,A9,3F,CC,01,59,47,03,6B,B5,3C,84,74,94,BB,84,0C,6E,60,0A,FF,43,86,E0,71,8F,A6,69,43,05,A6,B1,29,24,21,AE,C2,AE,B8,49,3C,75,81,D6,EC,03,7B,15,4E,E1,6A,69,90,32,0A,10,66,09,09,CA,61,D2,BE,37,20,A1,62,CD,20,DF,A6,5B,2A,63,F3,89,D4,15,03,65,A7,4C,C7,A0,7E,B3,E6,7F,DC,0D,80,85,82,71,6B,6E,68,9A,65,54,3A,DC,14,11,16,80,03,01,65,16,F8,A5,32,02,2B,BE,54,D6,4F,9F,CD,22,DE,F2,FE,21,72,88,D1,52,99,B8,8F,20,D7,AE,FB,FB,00,BA,74,4F,FD,8A,D4,2A,88,C6,9F,04,2F,30,0D,D7,CE,FC,F9,6E,47,56,A3,17,98,BA,5F,88,9C,B2,F3,A8,B8,38,B7,12,78,7A,5E,B5,64,BD,B8,71,3D,9F,EB,27,A8,CF,CB,29,EF,0B,24,14,48,74,BA,C7,34,6E,71,AA,42,93,6D,7D,9F,C3,8F,10,C4,6C,DA,7A,64,4F,6B,6A,00,20,A3,A2,EA,7E,77,60,3B,13,45,61,0D,99,AC,03,AF,17,A2,69,DB,6E,A9,BD,73,DE,58,93,08,45,C8,B9,0F,24,4F,A9,68,0A,C7,DB,53,78,72,EB,37,4C,D3,13,DE,27,6D,2C,75,AF,C5,D4,20,AE,E2,AB,AF,37,49,37,05,77,D9,AA,74,0C,18,26,CB,B5,FB,A7,A9,77,8D,CA,D1,5E,CF,6E,48,04,66,BB,94,60,65,39,FD,48,65,F7,59,9D,79,C5,B5,C1,7B,E9,B2,A7,CE,49,F1,72,D5,BB,64,C3,B3,D3,A1,2B,05,E1,CD,0B,BF,28,29,99,8A,E2,B8,EC,2F,80,8D,E6,24,FB,E9,A7,12,BD,0A,8C,39,51,57,0A,A0,4D,F6,9E,A5,1A,C9,51,2C,1D,D1,F9,00,96,B7,75,CE,E4,F4,08,58,CB,FA,C3,B2,9E,EE,91,80,E3,CB,43,4A,AC,54,F0,B1,9A,AF,5E,D4,53,27,1F,C6,39,3D,D8,A2,9B,41,71,AB,B2,C1,C7,ED,6E,6B,AC,29,F5,70,78,06,86,C3,71,F9,87,A2,DD,42,45,67,EC,DC,CE,08,7A,45,4D,EC,70,72,82,58,9C,E8,EA,9A,C8,89,62,7E,52,01,3A,C2,A3,4D,A5,09,4A,2C,02,CA,F0,DE,AB,94,F8,AC,47,2B,3A,32,4D,88,46,72,25,04,EC,A7,33,BB,40,83,F8,99,8C,D0,DE,B9,4F,C0,25,96,4C,90,A2,D7,6C,D4,C5,38,0D,F3,81,38,C6,44,80,53,6F,94,16,13,5B,7C,AC,2F,A7,DD,9D,67,58,B7,D5,FC,DF,6E,D4,35,A5,DC,5E,74,E1,BE,84,B4,84,52,44,CD,92,C2,27,FD,E0,36,9B,F3,89,F4,D3,FB,87,AD,7B,C0,0E,79,A4,AF,2E,82,5C,A1,F7,72,C9,A1,34,3D,35,5E,AB,AD,0A,28,D4,60,4E,9A,88,65,BD,D7,C5,12,07,64,9D,56,02,84,72,6E,07,04,70,A7,F4,4D,F3,5F,83,6F,FE,EE,06,2D,F5,E9,D9,64,E6,BE,D5,EA,E6,E0,D4,7D,FD,99,F3,B8,D8,43,E4,4A,0D,22,CF,29,6A,A9,E6,E1,29,FE,D2,4D,26,FC,9F,21,6B,81,67,C5,52,B0,A8,EC,AF,AE,F7,B3,39,81,93,3F,A5,6B,96,65,9D,C1,5D,C3,52,16,6E,D9,62,84,CA,91,0A,93,4A,9F,F3,64,EF,48,A1,B4,61,78,6E,3F,4C,E7,E5,97,9F,36,BD,4A,4D,13,69,2C,6E,68,56,24,F2,3E,54,70,EE,78,6E,8E,25,CA,93,80,EC,F3,2F,00,B5,A6,2B,18,AD,38,C4,3B,74,7D,1F,81,8E,E9,01,18,2A,E5,5A,2C,99,CF,28,65,83,11,E2,BA,6B,D7,D2,8D,CA,A8,43,C7,46,DE,59,97,2E,BF,93,2A,A0,40,1C,69,CC,20,83,6B,D8,DF,4A,56,42,89,DE,3F,17,EB,5C,08,7F,C7,EB,E8,88,9A,0F,13,48,28,3A,8E,E9,C1,C8,5A,2A,C5,DB,6F,D1,7C,E5,55,EE,1F,7A,14,5A,EE,5B,90,61,9B,69,A6,B3,27,81,3C,20,2E,31,E0,2C,DA,CD,B5,D5,AD,2B,04,56,0B,2C,7B,C6,69,02,73,38,8E,8B,0D,B1,88,83,2D,6C,90,A7,F7,F5,F2,6B,A4,9E,78,EC,ED,18,6D,8B,44,AF,65,9B,FD,1C,75,A1,AC,FE,03,9B,42,68,3B,74,3B,C8,70,1A,89,BD,A4,7E,23,FD,2F,11,C0,E5,44,DD,52,E8,76,01,13,9D,F8,B1,AA,E0,A2,5C,57,E9,52,8C,E2,1D,AE,6E,32,77,FB,FB,2A,B9,77,A9,DF,39,36,4E,99,7D,95,73,BD,11,83,B8,ED,32,CD,69,2C,A7,51,6F,C5,E7,4D,70,5E,BF,19,D1,EE,E3,0C,01,46,91,9A,DE,C8,A2,01,F9,B7,B9,CA,9C,19,69,DF,C4,11,AA,B3,77,0A,5C,12,1B,E7,9A,88,28,DD,F5,48,A5,1C,32,2C,AC,FB,5C,5F,24,0D,9F,46,57,AA,3B,17,27,B4,E6,5F,CA,4F,8B,C3,F1,CC,08,C5,B7,90,FF,77,26,8A,C6,DA,65,AE,8F,D8,16,AD,CD,E8,CA,FB,D8,1D,4C,7C,F0,7E,27,DB,F9,93,37,42,DF,D8,C2,96,D3,BE,D8,D7,40,96,88,F4,A1,27,DC,9B,58,6C,55,49,C7,04,BB,7D,F7,2A,06,8C,06,18,00,FC,00,C9,E0,20,71,1B,2B,AE,78,35,ED,02,07,EF,F0,44,9C,80,BD,C7,06,D0,40,5F,79,B7,30,91,30,D4,EA,1A,5B,FD,60,FB,6E,52,77,91,C8,D6,F8,6B,27,71,F0,E4,F2,79,DC,92,23,BB,DF,E8,81,F7,04,3C,E4,54,8C,DC,30,99,1E,07,D3,FD,60,41,B6,C6,C4,82,5C,18,E8,1D,FB,72,B2,E3,FC,3B,0B,A8,6B,24,CA,82,A1,F3,D9,50,5E,B9,DC,A2,5C,3F,B2,D2,0D,94,FB,E3,55,CB,17,F2,55,6D,90,D3,40,B6,25,07,AD,12,D8,05,42,0F,5C,EA,0E,F2,22,BD,3D,85,46,C8,75,34,0D,E4,B1,2B,60,C7,8F,76,2D,98,E5,D3,29,65,13,EA,E0,7A,DE,BC,D5,DE,CB,5E,74,0C,18,C3,1D,9B,27,FF,18,63,EE,A4,1F,9B,36,76,E2,7D,D3,FD,B5,3E,A3,9B,E6,0F,47,F5,4A,AF,EC,47,16,FD,5F,E5,F2,F1,2A,80,B2,8D,82,12,98,AB,41,B2,9C,38,6C,48,67,F5,E4,C6,E4,2A,FC,72,BF,69,F3,09,64,69,21,3D,A5,02,2E,C1,BA,5B,AA,16,0C,3A,87,93,58,C8,FE,03,E8,A4,FE,CA,FA,87,F1,7A,24,EC,12,F3,EE,BD,37,1A,59,8E,77,F7,A4,5F,CB,78,48,9A,05,18,A7,26,B8,3F,EC,F9,74,26,F8,FF,EC,A2,8F,B9,6A,0E,56,41,AD,C9,49,73,82,65,B7,49,3D,BE,DC,00,FA,EE,31,B4,5B,E4,53,CD,AA,00,62,DF,42,E9,13,04,DE,FF,30,51,C4,26,22,23,89,2A,A2,6E,2B,9A,3D,69,4A,E3,00,4B,F6,3F,51,31,1A,27,97,FB,74,82,15,A8,6E,02,10,55,50,77,D1,8D,5B,D2,71,00,A0,EA,30,E0,FD,49,6B,8E,E2,10,4E,7D,78,59,72,93,39,42,35,C4,FD,72,D1,6A,F6,F6,C7,EF,2F,D7,5E,C2,77,66,5D,DE,3D,A4,02,44,96,F9,FF,4D,C6,EA,5C,E0,CB,56,1D,CD,4E,53,52,1F,78,9B,92,29,0A,1C,CC,62,B1,29,58,FD,3B,9F,A4,A9,62,5C,18,1E,F0,C0,A6,9E,1A,7E,BB,D6,8E,0F,BD,E9,1F,CE,BB,4B,3D,1E,A1,B3,8D,70,28,4D,AF,D0,87,59,BC,B4,D5,E8,0A,DE,E8,9E,75,D0,31,9C,FE,4E,2D,90,07,8B,DC,82,80,D3,9C,69,7E,29,ED,40,AE,FB,A7,B6,40,1B,74,D1,D6,39,D6,68,EA,48,72,D8,6E,25,60,89,52,65,CE,1B,8C,C0,95,FC,1D,E9,DE,C6,C1,15,01,1B,6C,56,DC,08,B0,FE,1A,1C,3A,92,0C,D8,E1,E2,18,8C,66,D1,A1,36,AA,53,15,5F,3D,B7,5F,3D,29,D3,6C,39,51,95,33,CC,63,82,81,82,55,09,92,9A,90,FF,54,10,BC,02,D8,3E,0F,9C,EF,C4,A1,5D,EB,C8,26,B7,5D,11,55,63,5F,13,20,81,18,C5,A3,4E,B8,43,E6,F9,16,11,C7,D6,EE,C6,5B,B8,BA,32,65,61,8F,68,D8,08,FB,CE,8F,79,16,7C,C5,4E,EC,02,ED,85,D0,58,E1,DD,D7,74,1C,B8,CA,F0,DA,45,BE,F0,17,15,D0,DB,0A,6E,A5,B3,0D,38,A2,72,57,41,62,D2,31,FD,C5,A1,D0,3D,06,21,29,0B,CA,6B,9A,4D,8D,D5,96,CE,E4,A3,B2,7F,1E,E7,CB,F9,C6,0E,86,F5,1C,C2,1A,A3,64,0E,BF,B6,A8,54,B5,CA,45,3E,CF,83,60,5D,1B,A0,CB,C6,BC,F7,F2,BD,84,0D,E2,07,58,B6,4B,1A,AF,0A,12,87,F5,0F,58,BA,36,A8,85,9E,5B,B9,28,52,B3,BF,4D,A8,C9,10,43,DE,11,5A,09,0C,F8,18,8A,AE,5D,F9,36,9C,CE,14,41,EA,76,CA,59,82,18,D7,65,4E,3C,F2,08,B9,02,6B,D9,98,5A,A7,A4,88,01,60,02,29,25,3A,05,FB,C8,98,7C,B4,9D,45,97,7C,92,BA,5C,7D,B6,01,4E,5E,CE,A3,2C,3B,8A,EA,D8,28,DC,36,09,E6,1C,80,9E,2C,D2,AC,70,14,27,4C,0C,90,30,C2,A5,EA,61,05,50,6E,B2,A0,E1,BA,67,F6,AF,D8,0B,5A,7D,09,CC,51,AC,DF,11,74,B6,1F,29,C3,7B,05,95,5C,C4,29,12,3B,11,09,01,5D,58,B0,BE,3B,15,66,CA,4E,4C,BF,12,3F,0F,4F,3E,4A,4E,0B,FB,A8,C3,95,3F,8D,E1,EC,22,D9,7C,EF,40,C3,C1,23,6B,48,23,4D,DE,3D,A4,76,B3,DF,91,56,9C,27,52,8C,BC,B6,B8,61,99,99,EF,35,05,45,37,20,FF,CE,5D,B0,90,8F,CB,EC,22,9B,64,0C,8A,00,3D,3D,0C,54,5B,0C,77,29,C0,46,CA,FF,C4,4D,F2,05,59,10,F4,DF,13,43,F6,FA,25,20,41,10,62,CB,26,0E,97,96,60,A8,99,4B,4F,D8,10,19,A1,E5,68,FB,04,35,C6,36,F4,FB,9A,F4,EF,C8,B9,2E,01,7D,C8,A2,47,E7,6C,D3,84,2E,0F,E3,9B,BE,36,C3,4F,08,55,A5,04,AF,36,B2,C8,4F,60,69,FC,42,93,80,E5,80,62,D8,DA,A9,49,CD,05,16,D9,32,09,98,B7,2C,6B,19,68,09,9B,B0,56,9B,06,F4,54,FC,86,66,B7,DE,CB,C3,42,91,F0,C9,F0,30,00,CC,67,70,B7,F8,29,79,83,80,B8,0A,21,FE,D0,13,84,1C,9E,BD,96,F6,35,43,F4,E3,0C,37,AB,F8,DD,05,4A,31,52,BA,4D,61,30,0F,30,4A,22,D8,92,FA,7F,A0,90,ED,80,0F,73,F7,D1,12,37,3C,FA,59,F2,5B,E4,01,FA,8D,70,F6,89,34,F1,6A,00,84,04,79,79,31,14,F7,7B,04,BB,89,5D,81,50,4E,49,71,64,96,F0,DA,3D,67,7B,A8,69,5B,1B,9D,A9,17,90,FB,9C,FD,BD,80,34,07,AF,43,84,2E,0B,23,CD,08,0A,20,D1,43,77,C3,08,59,8A,95,1F,F2,19,08,37,3B,06,4D,6C,8F,A7,42,E6,0E,EF,15,39,62,C1,4A,19,B3,50,F7,4B,73,B6,7F,38,65,AF,3E,0F,A2,C2,68,E4,CD,86,AC,EF,7B,5B,21,31,CD,40,4B,28,8A,40,E6,CA,E5,4D,F2,9E,63,A3,F2,73,E0,D5,B3,B9,6C,93,F8,96,06,EC,E0,93,A1,70,7D,86,B2,A4,FE,EC,53,E8,30,B3,51,66,72,EF,03,F1,35,D0,D3,6D,B2,C7,09,D3,F0,1C,A8,30,0A,6F,F2,24,21,C4,43,4B,64,F9,9F,65,86,76,C0,00,28,2D,23,34,E7,81,0F,AD,2D,DD,AA,20,49,2C,7B,84,CD,66,38,DA,23,74,8A,F6,72,B1,73,BA,90,63,33,30,07,10,CA,4E,AF,BE,80,07,18,B1,F6,DD,66,38,A9,F7,E0,0C,6F,F4,5C,D9,B5,DA,BF,CE,47,9C,12,50,97,1D,A6,6E,0B,AE,42,65,B6,CA,1F,6B,B9,B1,4B,3C,6F,ED,F0,E5,84,9A,6E,C1,E9,DE,70,F3,B8,1A,32,6A,84,35,CF,CD,82,D9,A5,61,02,EB,DB,9B,5E,9A,47,9D,F8,9C,68,5E,C0,FA,23,14,BE,53,02,B5,07,3C,FB,3A,96,7A,A6,30,B2,B6,6A,C9,9C,11,AD,F4,63,79,06,DE,2A,28,2D,05,C1,26,96,70,E6,EE,58,11,68,B0,79,AD,CB,91,40,62,84,B9,ED,63,35,79,3C,0D,9C,FD,82,16,FB,B9,C0,DB,50,2C,4F,CA,E0,7B,E7,57,27,BC,23,7E,FB,0F,3F,D7,BF,52,66,83,82,79,FE,2F,15,8B,A1,E6,FC,5E,C0,E7,55,24,8C,16,20,0E,4D,0D,C9,2B,01,4D,FD,0C,06,D6,32,4A,2B,A5,00,9C,0B,51,09,22,48,5A,7A,B9,A1,C9,44,B0,7B,94,56,59,72,7B,20,5C,6F,57,21,7D,D9,E7,16,88,D1,A3,A2,3B,B5,C3,E1,77,FB,12,E3,94,60,8D,6A,9F,7C,F8,28,B6,41,B0,D8,82,59,D1,26,C0,9C,8A,99,1B,6A,FF,DA,5F,05,0B,D0,58,44,8C,D9,CB,AA,C5,81,92,BF,55,E0,D4,C1,BB,C6,2C,18,F3,00,BF,2B,E5,CB,5B,61,20,AE,5B,E1,61,20,E9,E9,6F,AF,96,F6,2A,C5,A7,D6,7B,84,D2,F6,45,2B,E3,7D,49,16,CD,86,34,6C,85,23,F6,66,44,77,46,C9,18,99,22,DF,12,77,03,06,77,75,87,E9,5D,D1,9A,4F,2C,F9,7F,99,76,AB,34,DE,CE,88,BE,D2,8A,B3,5D,2A,60,51,8B,E6,FD,4B,46,F7,CF,E9,C0,3F,D9,22,F1,A8,EF,F1,EC,2F,E2,E4,11,47,AC,05,F1,03,D8,73,F6,19,10,AB,84,0F,4D,9C,DA,F6,12,2F,4F,75,94,61,D7,D4,7D,2C,43,30,D0,25,67,5E,A3,93,12,58,5F,42,9B,91,32,EF,9B,2D,E8,FD,11,BB,6F,A9,F7,3B,7D,3F,CF,2B,CA,EE,E3,02,EE,0A,66,48,ED,BF,1F,57,09,F4,8B,85,2C,BE,E1,A7,67,B6,95,A6,A4,11,99,AB,1B,79,C2,2B,E8,2F,59,7C,2C,54,44,E4,43,22,75,C1,44,D8,CB,BC,6C,C5,DD,63,15,8A,E3,FB,7E,DD,66,83,48,B9,E7,8D,41,F3,09,5B,83,43,B9,BC,66,93,33,15,B4,FC,B2,88,7F,51,F0,DE,55,5C,75,C8,83,82,07,88,57,6A,0B,08,01,5C,7F,5B,4D,98,66,63,D8,4E,C0,6E,F0,D3,13,A9,C9,EC,64,45,CD,78,98,58,53,D4,86,32,94,9C,53,DB,4B,E3,FB,06,4A,84,A0,4D,C8,C8,29,80,09,B6,79,9D,CF,C4,DC,78,36,64,93,19,5A,45,94,8E,F7,46,C8,68,76,B8,F4,1C,AB,30,10,30,95,43,FF,4C,81,72,4D,1C,F8,23,02,2C,D5,C7,6B,32,3F,38,7F,B5,D8,F5,52,19,F8,76,31,65,A7,CD,0A,37,91,45,49,9D,42,70,CE,4D,90,88,E2,E6,C9,34,86,63,8B,B0,47,5A,85,0B,41,DD,D4,26,9E,CD,C0,9D,7C,B8,32,FA,4D,BA,F6,89,2A,D8,F3,3D,97,F1,4A,15,59,0B,67,71,F3,00,CA,92,B9,2E,77,8A,B2,AC,92,1C,66,72,6B,A1,8F,D1,9B,A2,11,73,4D,30,3A,30,3B,07,20,59,E4,00,FD,22,18,98,8C,B8,AD,FD,17,A4,CA,CF,2A,A1,A0,C0,33,01,2B,66,C6,47,EF,43,1A,13,EC,4A,7B,AC,12,53,4E,17,3C,14,27,A2,A3,38,3E,40,48,5B,99,83,D3,CA,17,E0,9F,DC,99,F5,52,AA,FE,24,FF,6A,37,B6,A8,2B,35,A6,5D,88,62,E1,15,E9,8B,D7,CF,AE,D0,18,8C,A4,43,E5,45,5E,31,6C,54,F5,19,59,61,FB,FE,1C,80,04,AF,C9,CF,16,C5,A7,9F,3A,7E,AD,17,5A,DF,3E,17,59,19,75,B4,B0,83,6C,D1,70,9C,37,E7,C7,52,AE,48,1B,D5,BD,1E,79,73,BA,FB,5B,A2,DC,39,DD,F6,5E,32,F9,61,C5,FA,00,B4,12,C7,8D,B2,83,79,00,51,59,51,AD,E6,55,62,FF,41,63,7F,3F,EA,50,6E,64,21,EB,81,74,23,4C,59,ED,9D,57,B5,03,01,CB,ED,3E,AB,65,96,E9,BE,02,5D,76,85,AC,33,FA,E8,12,6A,43,49,88,D4,D5,D0,1D,82,52,3E,DD,E9,C3,1C,01,EF,AC,8C,4D,D1,4D,58,9E,C2,B3,40,B5,FD,AA,C5,B6,FD,F3,87,5A,96,D4,79,8B,C2,77,92,7C,8B,B1,48,24,9B,74,31,19,0D,C2,45,38,29,76,9E,C7,33,95,C4,86,83,A2,F9,7C,D1,B2,2B,31,01,FC,CB,A1,FE,1D,2A,9E,99,32,5B,D8,69,B3,68,FB,E9,6F,7D,19,41,FD,28,E5,3F,11,B5,B8,97,05,21,D1,28,15,91,00,02,4E,B3,6C,3E,8D,CB,E3,1C,58,4C,F0,5A,08,5E,A7,3B,6F,88,99,25,21,BE,64,23,A0,B9,91,96,55,07,E8,D6,8B,B0,33,28,81,8A,BE,FD,D3,B8,8F,BD,01,D5,E0,44,EA,8E,1C,59,59,91,CA,D7,E2,61,6A,F2,91,FB,DB,D2,B2,46,43,9C,92,6D,5F,99,39,F0,EF,7B,A7,E1,AD,F0,E6,20,3C,8B,91,8D,99,C1,4A,F5,E1,4B,32,04,ED,8A,7A,D9,26,24,10,52,BC,BB,9B,6F,4E,6B,9D,24,55,A1,58,32,B0,F9,8B,05,43,1B,68,EB,5E,F9,46,AC,51,09,2D,7E,CD,81,12,B8,F0,CA,7A,5C,57,94,8A,6F,41,40,A5,B7,18,A9,71,B4,8C,04,2B,C2,F1,C7,66,A2,BC,D1,84,C8,5A,CD,D6,40,A0,B3,9D,2B,96,D7,D6,1C,52,24,1D,CC,09,24,06,5E,94,FD,A0,7F,48,8D,BC,48,FD,42,EC,F2,17,4A,2F,75,07,C5,9D,31,00,96,42,0C,48,5B,A8,1A,17,DD,9D,EE,28,0F,AC,6F,C5,E7,F4,88,13,AB,81,94,C0,76,CC,08,E1,36,86,CA,E6,E3,53,DD,E7,92,2C,F5,E6,A2,46,25,22,37,5E,9A,04,5C,E6,4E,02,84,F0,5F,2A,34,DD,DB,4E,4E,2C,BE,31,C3,CF,F6,C8,E8,EB,ED,1D,28,44,ED,B8,42,8E,F6,CC,5F,A8,FC,51,A2,5E,C9,A5,FF,0A,DC,C7,74,DA,96,89,A5,38,5D,5E,01,5E,86,A5,5B,C8,E8,DF,B2,1E,0D,86,1C,B0,32,82,19,0E,88,20,84,FE,BB,01,EB,EC,65,54,F6,2A,33,A0,E1,F4,71,A4,FE,F7,13,D2,CE,51,9A,B1,6E,52,8C,4E,A0,9E,AF,8B,66,93,75,D8,24,66,20,96,ED,2F,A6,5C,91,98,A4,F9,DE,EF,0A,99,A1,06,95,4E,6D,E5,B5,EF,9F,3A,D8,5A,A5,CD,92,D5,B1,C6,DF,74,6E,AD,9E,5A,21,D9,37,27,A2,40,F7,F0,97,89,D2,3B,BE,1F,FA,AA,93,0F,6F,51,5B,B4,1C,07,B8,2E,5B,0A,78,47,A1,D7,2F,37,AB,57,91,46,EA,6B,8D,7D,81,B5,A2,F3,B9,84,E0,89,E7,D8,C5,7B,56,0F,EE,44,9A,78,A1,5C,1F,0A,5B,8A,2E,AE,E5,DE,44,1D,6C,87,EF,64,F2,5F,0B,26,7C,7E,A1,C8,3A,89,05,5A,24,88,5E,8B,89,B2,77,A2,FE,6A,54,0F,E9,E0,C4,85,AA,6A,71,16,70,38,41,78,A0,69,E8,50,95,3D,7C,18,FD,23,C9,B4,79,4C,5F,82,90,95,40,9D,0C,6B,07,28,BC,FD,26,BB,69,42,90,83,3D,17,17,76,25,FC,E0,07,DA,DF,40,4B,57,0D,E3,1C,9C,90,13,3F,E0,8C,AF,23,0C,D1,DF,18,06,CB,2F,B3,BA,75,E1,59,8F,05,F8,BC,1B,C9,86,7A,9E,F8,36,C0,7D,82,D3,4B,E3,AE,E9,8F,F0,76,47,8F,52,89,96,F8,55,9F,5E,85,2B,EC,6D,85,7D,F2,83,4C,B2,04,EB,99,17,2E,6E,21,28,C3,7E,53,04,AB,F5,91,A8,B6,77,D5,89,B7,9D,BD,98,1A,A4,B3,A6,44,BE,09,35,7A,0C,08,2D,25,0A,4F,71,9E,5B,84,62,E6,8D,00,24,4C,C4,A4,1C,A0,90,C4,96,BB,9F,A7,9F,E9,9A,E0,6F,B1,21,E3,81,AB,08,F9,33,A3,27,03,90,1A,82,A3,87,3E,69,37,B5,26,0A,FD,E3,07,D0,E2,2B,E8,A6,87,DF,0A,A4,FA,AD,87,E6,D5,63,AB,60,0B,E0,A4,86,81,62,AB,DB,17,71,CF,B1,6C,36,D2,BB,2D,0B,5D,72,AD,AB,0B,6C,3C,95,8E,4D,B8,01,30,E8,E9,5A,A9,8E,C9,32,D5,82,F8,37,7D,19,DC,95,D5,0A,AE,9D,9C,24,1F,72,73,A3,22,AB,79,E1,49,58,BE,87,DD,04,92,CC,64,A2,59,FE,3F,BB,50,96,10,4F,74,57,AF,47,69,B0,71,9A,28,4C,11,09,83,26,B8,07,B2,B3,B5,35,D2,EC,5C,F4,8B,14,04,DE,6E,CA,FA,08,0D,A4,27,98,3C,69,37,8B,48,49,E4,E4,DC,B0,96,A4,BD,EF,1D,5B,63,21,9E,16,C1,DE,BF,5F,C8,28,C3,5A,BE,4A,09,06,8C,91,8C,CA,5F,42,76,BF,C9,6E,41,26,0D,02,F0,09,FA,58,C8,AD,EF,09,C9,91,A7,64,9E,3A,B9,D5,F0,DD,9E,B7,28,4B,25,D1,EC,69,49,1C,C3,5C,A4,25,CB,F2,33,EA,0F,21,7D,18,FF,B2,D9,ED,E3,C9,57,EB,90,7B,8F,FB,07,8B,41,3F,E9,E6,54,A6,CF,1E,C0,52,52,24,22,82,7B,3E,4E,B2,DF,2D,20,46,28,6C,98,7B,7E,97,83,CE,BF,AF,7F,E4,2F,D7,E2,FC,24,FE,4A,BD,94,59,2B,82,DF,74,FF,B4,AD,BA,44,98,7C,17,22,F6,B4,58,2E,93,A8,B9,7D,CA,C7,E5,22,EA,3C,F1,ED,55,F5,D6,9B,80,E5,87,36,CB,E4,BA,D9,46,36,67,77,4A,04,C7,A6,CC,51,85,5C,39,F3,24,BD,58,C8,F3,58,0C,0B,E1,54,1E,73,57,50,FD,9E,81,04,E6,0D,AD,78,56,F0,29,55,56,63,80,41,EC,48,C7,04,4D,46,67,5D,68,90,35,36,2F,E2,98,0F,80,30,EE,00,F5,FD,80,28,A6,A3,81,16,1C,1F,C9,7B,3B,F2,C9,26,96,05,84,9B,09,C2,8B,8D,A8,20,93,E1,37,93,3C,BF,38,EE,51,DE,C7,C8,3C,AB,42,66,85,B6,30,2A,98,B3,4D,D1,EF,0B,AE,90,C0,77,82,04,35,54,A7,CC,F0,27,71,D2,AB,80,3E,8C,33,D8,82,33,03,A7,E9,A5,71,81,6D,AA,CE,8E,1F,05,16,F1,18,11,0B,12,2D,23,97,28,04,5C,F1,FB,E5,7F,5D,D6,2D,D6,D5,E2,A5,E9,C5,7D,46,3D,F1,27,59,0F,09,69,19,09,44,75,69,B5,EA,D9,7B,16,01,94,6F,CD,20,C5,15,9E,45,65,B0,3D,76,32,CF,52,0B,A9,E6,6E,60,D6,C3,A1,88,CC,A5,5C,2D,80,37,12,B1,AF,F8,FD,85,C9,0D,2B,DF,36,9C,99,BA,06,56,4E,5E,3D,DD,64,4B,76,F0,B5,BA,98,8B,8F,A9,41,B4,EB,40,A7,7A,18,63,3D,12,88,71,82,69,BE,04,37,DD,16,31,78,40,23,24,3D,88,C1,FE,C5,38,13,5A,66,50,F6,03,46,60,09,ED,44,67,3A,67,97,D9,94,7E,6C,6A,F0,FB,5F,EC,37,41,FB,35,95,76,36,8D,F6,7E,2B,0C,CE,AA,2F,7B,56,A5,2F,59,D2,7A,16,8D,E3,51,95,DD,BD,84,8D,C0,3F,BF,37,1C,0E,A5,17,46,CA,8F,E0,6C,61,12,FA,AB,7B,D6,A4,1E,BE,4F,5C,5D,9C,88,45,17,0A,BA,A1,77,69,9B,AA,93,7F,87,1E,9D,E2,A4,3F,4E,4E,1A,69,0D,3A,1F,EA,C6,77,D3,56,A7,1F,80,13,99,42,C1,35,73,46,DA,64,66,C0,4C,E3,07,43,2C,B7,E9,62,D0,CF,D8,E7,90,E6,92,64,68,3A,00,FF,00,F7,F5,34,CB,2C,03,B6,8A,06,87,69,C3,EA,0F,F3,A2,42,51,1D,79,A2,33,DD,0B,B2,29,46,91,C6,4F,7C,92,47,9D,B3,4F,75,8A,A9,3C,DA,19,28,7D,CD,62,A8,9C,DB,62,FC,73,58,B2,AE,37,6C,8C,B0,75,61,1A,73,CE,60,74,0C,7B,DC,B2,BD,D9,8E,B7,FE,39,97,96,30,94,8A,6A,27,F7,A4,88,4F,03,28,3A,48,E1,21,32,65,B9,4B,0D,34,5F,BB,A5,EB,59,57,65,32,4A,B0,23,78,24,31,D7,B5,B1,7B,5F,C4,CC,80,3F,C1,05,0E,F0,1F,D3,7A,34,2B,FE,63,34,C2,E7,55,81,22,D7,D1,1E,5F,74,77,13,E8,65,C9,CE,15,86,11,3F,6D,63,71,86,FC,2A,09,AC,CA,52,41,28,82,CE,D2,AE,C9,C8,84,A6,33,AD,9E,3F,D0,4F,33,93,D0,79,C2,0A,4B,52,6C,7B,55,D4,FE,EB,C4,A0,D7,23,D7,67,4A,8D,FF,D0,B8,28,43,93,DB,2F,C1,7E,5A,26,1C,3B,7E,75,4D,83,15,DB,D4,0E,78,AC,4D,1F,32,D9,96,21,32,69,49,8E,A4,E2,25,E8,F3,98,5B,CA,25,95,01,25,6C,47,C4,39,3F,54,9F,23,60,CD,A5,92,C6,8C,7B,16,D3,8B,35,5E,3B,BF,15,7F,D8,24,C6,E8,D4,C9,7D,B8,ED,4B,57,6B,C6,88,C0,7B,4D,FE,7C,41,60,1F,4D,0C,80,A2,90,71,8A,C0,BA,93,81,9A,4B,C0,8C,6C,17,B7,E8,2A,17,FE,9E,FD,4D,5A,45,5A,E8,4D,51,5C,EE,F9,3D,A1,C0,5D,27,F6,6E,59,46,CD,2F,FA,AF,F8,8F,52,8A,0D,A4,27,F7,1E,43,70,54,E4,3A,60,CA,39,92,8A,DA,19,1B,14,E9,B3,AE,76,58,F2,92,4E,8E,86,6B,FA,53,7C,BE,F4,D7,5D,E8,E5,40,8A,78,34,9E,30,E1,42,07,E9,04,6B,AF,5C,98,D4,12,5B,AC,BF,ED,87,AF,C4,3A,B2,72,12,DA,02,32,AC,FC,AD,3D,0A,36,36,2C,4B,53,BF,78,92,AD,3D,03,09,37,3B,F1,7D,DF,0F,05,BE,F1,01,93,C3,79,A3,2F,E0,48,D5,5F,1D,8F,EB,A6,0C,50,5D,8D,29,14,FD,9F,C1,52,0C,90,02,51,FB,6D,B4,6C,A4,96,A1,73,40,E0,CE,98,38,24,39,1F,B1,17,D7,6B,2D,AE,5C,6A,2E,F9,EC,EB,C6,50,57,50,BA,41,A1,B1,6D,0B,24,74,C8,A9,7C,C5,70,A9,92,F0,6F,64,CB,2C,CB,D7,E8,39,30,F2,A0,D0,AE,7A,72,F4,89,A0,82,18,3B,72,4A,3B,C1,94,56,73,E1,4B,94,41,0C,F1,33,45,B8,3F,E4,55,C2,75,1A,DA,36,40,2A,B1,2D,A1,53,96,EA,38,6E,38,21,FE,63,7D,0C,C1,6F,9E,2F,5D,0C,00,8E,14,BF,01,7C,B4,75,84,B8,62,94,64,8F,4D,97,63,79,C2,55,E9,8C,9C,B3,D1,89,D8,9D,D9,FC,76,C0,9A,E4,50,CC,F3,3B,F0,0D,F5,61,8D,7D,EA,CE,88,9F,76,08,00,25,C2,81,DA,FE,9C,5F,BB,4F,BB,CE,D6,39,1D,39,2A,DC,2F,A6,79,F0,7F,CF,20,32,12,D1,15,39,DA,7A,EC,77,AD,C7,DD,D6,10,25,A0,31,D7,F6,32,03,5A,82,0C,A8,C1,36,AE,EE,5C,6E,E8,23,03,43,DF,00,80,C0,CA,82,22,50,97,4E,A3,D9,72,BB,15,1F,24,87,08,4B,CA,21,26,30,58,3C,91,15,7D,CE,29,CE,B6,3C,24,79,E2,35,B5,C8,1C,1C,CE,E3,7A,34,FB,38,D1,8D,85,C7,70,6F,02,C9,D3,1F,5A,9F,1F,7E,CF,23,6E,D6,D3,B8,5A,99,1C,07,42,2D,A6,64,EC,FD,8D,38,5F,C0,36,64,A1,2B,F0,C8,5E,D9,A9,68,C7,B2,48,D9,8F,CC,CA,BA,7D,D7,A5,C9,4C,24,AA,0E,91,06,CA,82,78,6E,1B,E2,F7,EF,01,27,A5,37,D9,95,7C,B7,B8,85,33,65,9D,87,07,70,14,63,47,33,03,C9,7F,2C,45,9F,BC,0D,12,02,E8,A4,17,15,94,0C,36,EE,AB,B1,21,BF,1F,BE,79,0B,84,B3,97,58,70,0D,41,7C,51,A2,44,B6,7E,32,20,D6,00,2B,F0,8C,EB,5F,E8,9C,FC,14,2B,B5,09,1F,2E,79,94,12,2B,AD,82,3D,79,AC,DD,F7,0D,AB,8E,C3,21,82,21,A3,75,12,B4,BC,EF,F1,9F,E8,30,47,DD,D7,94,C9,7C,D2,AE,36,7C,C5,6A,AA,73,21,57,E8,D2,15,42,6D,E5,4B,86,E4,BF,6E,86,69,EE,38,0F,E1,01,01,65,03,A1,0E,4E,73,E1,20,5A,80,73,5A,59,65,A2,A7,A3,81,5C,31,4D,36,85,11,06,C4,E0,01,1A,75,D7,53,DA,4F,CF,4E,7D,B0,14,BF,3C,9C,B0,6C,5B,45,4A,CC,70,B0,46,2C,C0,E9,92,EC,F9,D5,42,B6,DD,80,96,72,B9,97,D0,8F,A0,86,F3,67,A7,4E,43,AA,E2,D4,87,86,FB,AE,63,06,1C,CA,29,98,8E,2F,1D,22,EC,D6,90,13,86,F4,EB,0B,6B,32,34,4D,B5,2F,FF,71,EF,29,82,02,1E,4D,3D,25,3A,B3,56,92,68,E9,A2,57,A5,3F,3B,BD,27,C9,32,95,35,F4,A0,71,A3,37,E3,B4,6B,E3,8D,A7,F0,4A,B3,BB,12,27,85,4A,49,78,42,69,31,66,AE,06,1F,A3,7D,77,C8,27,52,8B,C5,14,5A,76,E4,E3,31,30,2C,6C,9A,E3,D3,12,E2,8D,10,32,7C,ED,D1,D6,A4,05,4A,12,2F,25,E8,20,6D,DC,EA,A4,08,01,A1,EF,7F,CA,B9,73,94,7C,E7,C3,94,6A,B6,A3,42,CA,84,AC,58,D9,10,63,1D,48,8A,25,50,77,0A,BD,C7,C7,65,42,DF,14,D9,38,70,82,9B,47,38,CA,23,8A,CE,D5,8F,3D,80,20,06,DE,65,BD,4A,40,E4,33,13,4D,7B,19,A6,6E,CA,6D,EA,43,A1,3E,BD,75,AA,1A,29,EF,04,70,A4,79,49,57,CD,36,B4,0E,CA,84,FD,AC,18,14,11,73,FC,E4,C1,AB,71,65,11,FB,3E,1B,62,91,9E,2D,65,77,42,75,E0,0E,C4,C8,DB,4A,96,F3,99,D5,72,58,C6,70,40,1C,B7,78,FE,B7,FF,10,25,3C,6A,B8,12,06,67,91,05,AC,60,A3,7F,EF,B0,11,51,14,5A,4A,BC,9B,60,3A,8B,EE,39,6E,B6,39,86,CB,B8,29,33,62,2C,23,20,32,F2,45,28,FE,0F,3D,23,A2,7B,E0,A6,EB,57,25,03,C9,04,63,69,2E,9A,4E,7A,8D,BB,2C,B4,93,9C,50,26,1C,83,7E,6D,E5,3A,8B,BE,D5,D5,FD,35,72,4E,BC,51,A4,BA,A2,24,10,3B,57,9D,4E,07,F2,03,5D,BB,C1,14,F4,07,C7,63,2D,46,FB,50,E5,F4,08,CA,73,72,20,8C,CB,B9,32,89,21,B5,E6,4D,09,31,E9,CC,7F,E3,B1,BB,A8,F9,E3,7F,C0,5D,C9,5C,40,20,F2,A2,FD,2A,8F,87,2A,44,7B,99,78,D1,91,BA,A4,BC,C5,DE,90,08,AA,99,37,14,05,99,DA,BB,41,C6,24,AA,BD,A4,3C,E0,97,DB,FF,07,FE,0F,BC,60,17,91,D5,37,9D,20,7F,34,A5,46,3E,41,D7,C6,F7,3E,D3,13,A9,AA,11,5B,15,0D,6A,78,F7,89,FD,75,9F,AD,4B,59,DF,84,39,BB,C5,7F,13,E6,A8,37,70,95,65,D4,2B,2F,19,FD,D2,CD,42,81,9C,6F,3E,3C,E6,22,E7,96,39,94,84,D2,A9,F7,0F,7C,B6,E5,98,63,7A,DC,40,80,37,32,F4,9C,A9,32,21,D5,8A,9F,F6,04,EB,35,07,40,16,31,71,AC,84,4D,AA,B8,51,71,56,2B,CA,13,9F,DC,93,70,54,67,12,37,02,6E,16,9C,A2,03,49,B2,43,1A,75,06,77,46,40,C5,33,A6,FE,E1,0E,35,6E,23,8B,05,B3,D7,76,11,FE,D1,7F,9A,E8,F6,6C,0B,32,FF,9D,BD,C6,2A,A7,65,E5,F6,EC,F9,27,D8,35,42,0B,E7,2D,E9,33,2B,48,57,29,8E,BA,EE,0D,DF,3D,04,39,CD,8B,F4,93,82,B7,25,00,B5,79,99,58,AF,29,77,38,34,3F,9C,89,93,A1,E0,A0,20,55,88,95,41,F8,68,FA,3C,C7,EB,AD,77,C4,A6,CC,A1,7C,4F,2E,3E,AE,2B,CD,6E,90,C9,C4,18,FB,5C,AB,4F,DF,9B,13,D9,F1,66,1D,6C,19,CD,7E,03,EB,20,E6,29,88,11,EA,1C,75,E7,64,62,E4,9E,42,3C,42,AA,51,4F,10,3C,F9,B2,4B,E5,D0,F8,F6,A7,B5,58,0E,72,63,A9,CE,7E,17,39,20,81,B8,A5,D6,64,DB,A0,07,DC,DC,7A,09,31,B0,6F,DB,55,8A,CB,19,85,9B,48,E1,8D,8A,6B,8C,72,3F,8F,81,E5,C6,6A,12,49,38,D6,8F,DE,70,AF,6E,08,83,FA,4F,C0,03,E9,50,57,BF,8F,4D,08,C6,83,BB,42,E6,66,E2,3B,D5,0F,B6,5D,42,7B,CA,2D,86,77,CC,B6,D6,3F,E7,EE,9A,88,08,33,D1,0C,10,3E,F5,8D,09,FB,D6,B5,B7,B4,54,20,83,DC,ED,86,16,2D,AA,23,7F,0F,97,C2,1C,EA,A2,46,51,2E,17,AD,B5,BA,94,BC,6B,DF,6E,02,4D,35,CE,15,DC,31,0F,FE,C4,94,54,1A,0A,11,63,A6,F6,78,E4,36,A1,4F,F4,A6,D9,0C,06,BE,15,A6,27,9F,FD,20,CE,E6,06,E2,BB,89,B0,32,60,10,EA,2F,8D,75,0F,3A,E8,89,70,95,34,19,06,09,C1,B9,17,F9,1E,3E,54,28,F3,DF,C5,1A,10,F3,2A,3C,82,4A,4C,B5,D5,B0,16,32,1B,67,EA,69,87,54,B3,55,21,F6,94,4A,10,F8,8B,96,5D,9E,91,2D,ED,8C,B0,3C,3A,B3,2C,2F,74,62,F3,19,41,B2,3D,15,1C,C6,CF,C0,95,8E,FF,B2,E1,99,E6,B1,C5,9C,F2,B9,7C,D8,78,3D,71,0F,4B,7F,F7,6B,55,81,FE,28,79,52,41,C0,35,45,0E,CA,68,EE,FB,1A,AE,55,AE,E8,94,2A,C7,CC,FD,1F,79,D1,B8,1F,EE,98,A3,4E,31,E3,EB,79,F5,69,EF,CC,4E,AA,88,3E,09,E2,E7,0F,4A,6F,10,96,41,C7,6D,DE,56,96,A7,A2,96,E9,1F,29,88,30,6F,E1,BA,EA,94,05,95,B7,3C,BB,FA,AF,9E,C9,92,2E,C6,68,98,2A,51,04,7B,F1,70,62,59,A1,0C,43,54,D8,61,9C,E7,C6,F5,0E,42,DB,EA,23,DE,E1,65,21,C6,29,CB,F5,5E,7D,DC,6A,67,BB,40,0B,C5,ED,3B,10,77,36,18,8D,A5,D9,0A,B2,67,91,98,8E,52,65,2D,40,5A,EA,FC,A0,68,F4,9E,9F,6E,6C,2B,C3,3E,E6,AE,6E,79,5B,15,7E,9B,61,42,7E,44,9A,C2,D3,35,5B,AE,49,88,D0,E8,6C,FC,75,36,D9,EC,51,0E,E1,62,6E,63,F7,FA,9E,BB,A8,2E,09,E7,4C,53,A2,D2,DA,D3,AE,F4,CD,F3,24,FD,2A,98,9E,74,BF,51,C7,DE,A0,EC,1F,4A,ED,86,5B,51,A6,8A,1B,F0,2F,BF,62,83,B0,45,98,90,E0,9E,28,99,9B,C1,13,BB,1B,64,01,EC,D8,B2,A1,2F,6F,70,34,81,CD,5F,1A,A0,F6,20,61,53,C5,30,E0,B1,F0,47,96,72,80,27,8C,A1,47,86,14,70,A3,38,E9,F2,40,8B,E2,D7,C6,C4,E2,27,46,FF,FC,38,9E,EF,53,40,73,78,06,16,F3,9F,84,03,76,8B,51,2E,EC,A6,EC,0E,9E,11,FD,7A,8B,6D,29,E2,A2,90,2B,E8,C2,3A,5C,D7,39,E8,1E,D2,4F,A1,C3,6D,E3,61,A1,8C,C3,37,C5,BB,E7,17,E6,8F,40,45,68,E2,95,8C,16,31,34,69,2B,CF,1A,D6,58,08,8B,D7,98,9B,84,AC,67,E1,EB,80,6F,5D,ED,44,43,54,AF,ED,F3,8E,AD,00,20,F5,17,D1,44,27,FC,B3,5C,83,5F,09,74,90,BB,54,E1,F7,78,72,34,53,CA,D2,00,B3,16,9A,C6,6E,90,3A,77,64,53,C0,EA,8F,40,DD,3C,76,22,0C,71,CA,AF,7B,2D,10,7D,D6,2F,8A,5A,AA,D2,1D,C2,96,2A,D6,D9,28,A2,DE,AE,BD,B0,04,3F,AE,85,6F,42,2F,47,DF,0D,8A,06,27,C2,A6,FA,43,24,7F,06,FD,0C,D1,26,C4,DF,A5,5C,67,6B,D1,74,A4,9E,58,79,37,27,AF,34,3D,84,24,68,22,7E,DE,4D,37,9D,DA,0F,FF,7A,37,7D,0F,E1,B4,A7,57,78,7A,B0,24,F6,22,22,E2,3E,F4,00,68,28,71,3D,B8,6F,70,EC,94,34,A2,C1,84,7B,18,56,6F,06,97,2B,B1,AC,AA,DE,3D,77,A8,C1,51,BC,68,5D,5A,A0,5F,87,D9,CA,94,F3,D4,81,B3,F8,DF,AE,D8,1C,3E,2E,25,E0,A3,EC,6D,6E,F9,2C,E7,BF,25,34,72,F9,5F,1E,DF,B7,82,5F,38,13,07,FD,D6,D5,60,6C,C9,BC,FE,21,A4,6B,50,41,3A,83,B4,3E,B8,B1,96,0C,77,0A,EE,72,18,A1,0A,57,8C,AF,F4,78,2B,9B,32,AC,D9,C4,29,B6,92,5E,68,74,F2,B5,43,9A,08,D9,AA,C9,6E,FE,10,FE,19,20,4D,F2,16,65,03,5C,B2,4F,38,D5,8F,CC,60,C3,3F,FA,6B,CD,51,CF,F6,D9,84,BD,E1,D4,78,5F,36,9D,BD,B3,15,5C,66,12,7B,C7,A2,DF,B9,61,A0,0F,3E,F1,CC,7F,64,1D,90,DA,ED,9F,37,E5,49,03,0B,1E,2B,21,9A,E6,79,5A,B1,26,E3,25,E8,6F,45,05,EA,F2,7D,CB,5B,28,42,B3,D7,88,92,A6,7D,60,90,34,9F,7A,2F,FC,5C,5D,7E,E3,E1,96,55,40,85,FC,DD,F9,BE,86,89,5C,6D,91,1F,CA,3E,41,E7,7A,71,38,16,11,CD,D9,1B,FE,9F,F4,9D,8C,3C,AD,35,E5,C5,FF,24,38,2D,5C,82,67,B9,E0,42,2B,8E,60,73,EE,90,A2,88,38,56,FE,52,E2,EC,5A,94,D0,A7,5E,F5,FA,4D,45,28,F1,C2,CA,BD,7D,98,99,9C,B9,FC,01,74,91,E1,67,B5,B7,B8,9D,0B,F2,87,3A,64,7A,11,59,F7,22,C8,2B,0E,03,01,8D,45,4D,AE,65,90,31,C3,B7,D2,A8,BB,35,2D,AD,4C,71,81,3A,AE,ED,BE,FD,0A,2B,2A,6E,A8,58,9A,C7,10,2E,9E,9C,B9,72,A1,11,1B,96,63,4F,00,48,2A,AD,E1,AA,FD,70,4E,0C,3F,69,C9,6E,70,4B,33,44,8D,4D,EF,82,11,0A,99,03,9C,18,56,5D,F4,4C,6D,80,3D,00,76,BC,7F,44,18,2D,42,5D,77,5B,FC,AF,8C,3D,C8,64,47,D0,B4,43,E5,39,5B,BB,CD,82,A6,16,A8,86,9E,51,81,C5,CC,A8,93,DD,64,FD,70,53,70,64,79,77,80,8B,AA,2F,5D,EA,3F,51,7E,FA,7E,C3,7E,49,32,E3,E4,65,44,48,26,C1,51,86,9C,33,F1,1A,92,EE,9E,94,E4,9F,77,19,64,FC,0F,40,28,75,BF,3A,E2,F7,59,F9,B1,69,63,06,03,12,5E,67,B5,82,9D,43,8F,2A,3C,A8,72,F9,B7,5E,E3,A6,58,1E,08,0E,BE,9F,75,27,D8,0C,27,23,0C,26,46,86,17,33,F7,22,D5,46,0D,2E,FA,70,29,34,D3,AF,0C,29,F6,7C,5B,E3,10,DA,E2,95,8B,28,A1,04,B4,16,85,BD,9F,C0,49,A2,16,32,D8,08,55,AA,F1,1E,88,C5,22,22,C2,B3,62,6C,87,4C,D6,D9,85,90,ED,C8,E9,0B,EB,CD,3E,C3,82,3E,06,6E,F0,03,76,0B,17,35,EA,AC,C6,FB,BA,67,B0,54,D8,CB,31,08,08,4B,4D,9B,A5,5A,50,AB,FC,9F,4F,FC,AC,51,F4,88,CA,AC,8F,D5,9A,D3,C6,81,21,28,35,6B,B2,FA,9D,E3,14,91,D0,DC,B9,AB,A3,6B,48,A1,BC,E4,70,2A,69,63,6E,B9,47,30,8B,F4,5C,2D,E6,91,41,E4,F8,85,D9,0A,60,EB,F8,12,2D,C1,4D,EF,5F,84,F7,38,C4,C8,F0,F0,FB,04,FB,BA,FE,AF,68,64,61,7F,07,9B,79,A7,B8,81,DA,67,A4,40,8F,63,47,5D,7F,AF,A7,86,54,EF,61,5E,87,51,49,45,1C,5D,FC,F2,2E,D1,0D,4D,C6,A9,38,C1,46,E7,FB,11,35,98,B6,03,3B,1D,01,19,D2,35,89,F3,2F,6C,B1,60,44,92,E2,CE,CC,AD,0E,B1,CC,94,8A,26,8F,8B,AF,C9,5D,EB,E4,C2,A6,42,82,88,DB,2E,2C,76,EA,6A,B6,9E,8B,6D,35,FE,FA,97,E7,06,53,77,3E,D9,CC,C9,97,F2,B4,B3,03,7B,36,A4,01,74,1B,FE,92,8D,0B,EE,28,24,C2,69,18,C9,48,4D,B9,EB,E8,63,88,50,DA,39,40,34,75,29,05,60,B4,01,10,CF,F8,36,EF,78,AE,EA,7F,D7,F7,98,F1,22,90,A8,8A,EC,AA,AE,70,9B,E2,08,DF,58,A5,13,CF,4D,50,83,D9,C0,D2,A8,E3,96,96,66,29,DE,34,40,5D,06,43,C9,FD,AE,90,EB,8A,35,A2,EA,55,66,D6,D7,2E,8C,49,1A,D4,DC,68,94,7A,F6,C6,F0,F6,AD,E9,39,A5,52,5B,B5,09,D1,A2,5C,C6,A3,DA,0B,B0,89,6F,13,18,47,62,09,67,27,9B,8D,A6,67,7E,22,06,8D,0F,87,2A,54,43,C2,0C,27,47,1F,75,CA,51,A0,76,6B,86,64,14,AB,E3,AB,24,E4,C4,15,CC,AB,1D,6F,D3,8F,D6,D8,6A,A2,16,83,9E,4C,09,7F,A7,EB,EC,D7,D1,1A,13,9F,AA,2D,FC,39,C0,C5,17,CE,95,4D,0E,D3,5D,79,8D,F2,8C,18,F1,13,76,9A,78,26,42,92,55,0F,8B,22,21,2F,1D,46,03,35,24,66,71,12,40,F7,55,F4,6B,95,4F,D3,17,AF,41,36,3B,55,5C,C5,A2,E3,67,20,C9,F6,D7,0A,78,C8,67,DF,5B,E2,74,97,28,ED,23,DD,C5,86,57,63,C1,17,92,16,2F,FE,F4,8B,67,9B,90,20,79,5C,B3,9D,43,C1,6B,75,53,9E,97,FC,57,7F,5B,44,37,B2,02,77,74,C4,7F,DD,E7,BF,A4,AC,C4,FD,FB,0E,F1,86,D6,EA,3F,BB,77,E5,85,65,31,AC,C9,DC,E0,E8,7A,3E,27,6B,9F,46,C2,6A,D9,49,1B,0E,FA,72,32,45,0C,70,70,09,7A,2D,AF,3B,FD,40,06,C6,10,9E,15,3D,3D,20,30,EA,B1,0A,C0,36,2A,CD,8A,1B,8C,C9,29,3B,54,88,B8,D0,00,75,D3,F1,12,B6,83,1D,47,4D,D7,3C,3A,69,6E,E5,F8,57,63,34,00,3A,2D,5A,9F,26,0F,46,5C,03,29,77,DE,96,4B,A4,81,AC,81,8D,D7,E1,C8,1F,70,B9,12,06,09,E9,EA,B9,D0,19,BB,BB,E6,EF,11,53,8C,28,56,89,76,FF,70,DD,22,6E,49,22,31,FA,47,D5,0B,6A,DC,B0,90,69,2E,2F,91,CA,A0,44,EA,2A,7D,E8,32,54,B0,6B,6A,BB,E9,CB,22,7D,AA,FC,9F,78,31,8D,8F,53,C9,FB,68,64,6B,36,A5,E2,B8,F2,88,64,55,53,31,A0,A6,DD,24,B9,A7,A9,BA,F6,95,7A,82,7F,43,89,16,CA,E5,27,54,D2,77,C1,8A,F3,D6,85,9C,E9,37,06,87,08,3D,8C,71,5E,F7,E3,1E,67,5A,5B,17,AE,97,70,3F,37,F1,4F,0A,23,C9,06,C4,57,24,BC,D6,A1,7D,2F,69,ED,54,36,3F,78,B0,BB,FB,18,C1,51,EC,15,C1,D4,EE,11,30,E0,CA,A9,3A,22,46,FE,A2,ED,DF,86,30,17,F8,5F,55,95,3C,BD,B4,23,D9,9E,7B,91,5E,0F,91,B5,7A,16,73,E6,F1,9C,44,DB,27,19,86,45,1C,BF,ED,D6,F7,ED,5D,1A,46,9F,C9,73,DA,3D,1D,27,DE,EC,0E,CE,85,66,24,B6,D6,98,0A,8D,A8,2C,0E,9F,EC,FE,F2,E5,F3,AE,17,E6,4B,F2,C7,6D,97,00,AD,68,86,7D,BF,72,4C,78,D1,93,46,EC,3C,8F,83,B0,28,C0,A1,A2,FF,13,EE,37,61,E7,AE,44,3F,54,0B,34,61,13,22,D8,EF,7E,B1,88,84,AC,D9,E0,23,62,3B,F1,F1,3F,98,A2,4B,79,85,31,21,15,1A,D5,80,9C,DA,FF,DA,17,40,F2,16,F1,19,D4,8C,E8,07,0C,9F,64,C1,A5,FF,16,B3,59,15,2A,A6,51,F3,B9,C8,76,FC,D2,6A,11,6F,9A,4E,9E,C4,77,07,A0,80,A3,6C,46,14,00,AD,76,4D,4E,34,E4,86,B6,17,F3,FE,6D,B2,4F,4D,BB,64,DF,39,C8,9E,4B,3D,4C,03,08,14,A6,61,E2,40,DC,8E,15,BA,40,55,6F,EB,C3,E5,1C,42,41,37,C7,A1,6E,AB,81,0F,E2,D1,85,11,10,E6,53,EC,3E,6A,F0,E3,A8,50,2B,C9,AC,23,7C,BC,11,52,9A,F4,CA,01,06,00,AE,05,41,69,12,E4,47,04,F4,86,D1,4E,4C,98,65,58,A5,25,3A,B1,2F,ED,C5,36,A4,81,45,CA,A9,14,E3,0B,FE,08,05,82,CD,5F,A1,F4,BB,4F,A3,A3,78,28,00,E1,0A,70,B9,95,DA,0F,9A,94,7D,5F,A4,78,BE,B2,9C,14,91,FD,48,C2,D3,12,27,31,9F,A6,90,71,2D,73,01,D1,93,83,90,2F,53,68,C6,9E,83,11,90,56,8C,67,F9,93,6E,D9,17,66,5D,38,CD,C2,32,C4,47,EE,16,48,0A,40,F5,BC,8C,37,BC,4D,20,A7,66,D3,7A,A4,22,C1,79,FC,6C,1D,2E,43,6B,96,AA,F6,84,0C,76,CE,AF,58,50,1C,78,A8,D5,65,AD,47,83,E7,EC,B6,B4,B2,0F,35,48,4F,D3,CF,D6,F2,AB,FE,D8,BB,DE,55,8D,78,BC,14,22,66,35,8C,EC,34,57,44,28,3E,94,58,A6,7C,F5,92,73,89,C3,EE,BC,2D,FB,40,D1,48,E0,45,B2,A7,61,17,96,9A,79,6D,29,9F,97,37,ED,A1,70,98,F6,06,37,4D,D6,F8,D4,A7,BC,2D,EA,04,35,25,E5,FC,3B,69,08,60,68,4C,EC,B5,BD,0B,8F,79,44,77,94,0E,87,7F,70,10,D2,5E,D3,3B,8C,6A,29,8D,D5,49,61,0A,37,65,B0,04,39,1F,90,4D,86,35,DF,BE,2E,6A,4E,76,BE,DB,C2,B7,99,CF,0D,39,D5,34,F6,D6,28,69,57,9D,3F,AC,0E,46,C9,6F,B9,E1,3D,9D,53,E3,B1,71,15,0E,E3,2E,6C,C6,66,D0,DE,D7,4A,3C,8F,85,2E,D0,72,C7,CE,D3,34,9A,2A,40,F2,87,10,E7,9F,EF,1D,7C,D9,A3,85,B4,B8,E0,1B,FC,18,F1,EC,1F,E8,12,FA,D5,E1,44,67,CA,F2,73,7B,F8,45,20,28,D3,8F,30,22,93,D5,18,42,D7,15,F9,EB,02,5D,F9,42,E8,84,0A,6C,77,42,23,FF,F2,1B,61,26,1C,DB,0E,1E,61,A6,53,61,36,7D,70,F7,80,B5,D8,88,56,68,51,0B,D0,B9,80,38,E7,BC,92,CA,FB,CE,01,CD,80,CB,CA,99,12,E2,7B,EC,56,C7,A6,4E,E4,9C,E1,42,1E,4C,D5,F5,93,4E,BF,EA,CA,82,C3,2E,AF,E7,0D,C3,96,40,C9,14,9C,A3,27,FA,9A,D3,F8,CB,B1,B7,A6,26,E8,F4,19,D4,3A,6B,A2,EF,1F,99,BC,0E,9E,F4,0F,D6,8D,3D,F1,E1,08,DC,1D,F0,F8,6D,D7,EC,2A,57,34,55,D1,77,A1,2C,07,FB,2F,C9,51,92,E8,9A,3D,27,BF,AB,24,06,34,94,F4,61,D6,3B,7B,C1,38,20,2C,E6,D2,C7,63,D4,A0,23,C9,D3,90,4D,95,0E,61,29,A1,51,28,48,5E,F5,BE,9F,CE,FF,97,25,2D,0E,17,00,D3,4F,B4,8F,BA,AB,6B,57,98,F9,E7,12,70,BD,BF,17,17,8A,99,D1,F0,14,BE,43,22,5B,A6,08,3D,E1,B1,D8,69,94,C7,BF,ED,FE,5F,03,FA,A8,87,C2,46,38,D4,9F,D5,D5,A5,18,27,C4,3E,92,B7,49,0D,30,80,AE,71,C4,52,D0,E3,1C,C0,A3,CB,24,F3,83,BF,50,D9,00,F9,74,90,93,C7,01,90,0F,EB,36,FD,64,BF,1F,EA,FD,A0,E6,5C,2F,67,4C,15,22,93,F2,A0,52,BF,C9,64,B4,85,DA,8C,44,77,46,A7,62,7B,16,33,DF,A8,FA,83,FB,CA,E5,59,3D,77,2E,D9,0C,18,20,10,CE,78,D1,29,EC,AC,80,7F,BE,AB,E5,87,A0,34,14,06,45,4A,27,AB,3B,9D,DA,5C,90,83,5A,8F,20,D5,21,04,4D,51,B7,C5,5C,FB,49,60,50,A3,6E,EC,16,4B,19,16,C8,82,7D,B9,65,F9,EA,7F,F4,C1,0E,99,C5,90,6E,0F,E2,A9,E1,F2,1C,39,DE,FF,86,A0,33,4E,6D,AF,D4,9F,EB,02,FD,99,B4,7E,A2,0A,AA,02,D3,42,6D,09,97,52,73,B4,DE,FB,E9,39,DF,7C,AF,05,68,CF,FE,FF,2D,1C,41,B0,5D,50,11,D5,54,0D,8B,27,4C,AC,AC,19,7A,F4,F2,4E,A9,8B,34,44,D8,4E,97,B0,28,1C,6D,3E,98,5C,4D,32,C9,F0,F1,B5,BF,84,1A,85,F0,1D,0B,61,1F,5E,64,16,CC,E7,D6,8C,18,F0,0B,D2,AA,6E,A0,88,45,1F,AD,B4,48,3D,AC,A3,FB,F5,66,85,64,29,88,F7,76,0C,46,66,37,77,2F,16,8A,C4,70,EC,18,27,EA,B9,CC,DD,95,6C,8A,DB,5A,90,D2,87,AE,A4,1E,47,0C,64,01,38,8C,DA,60,91,78,82,6A,6B,AA,EE,D4,32,7C,A1,5E,42,43,84,50,BD,28,93,BD,09,84,0F,A7,9C,26,84,C0,B7,B3,80,82,E1,5C,E5,98,52,0E,90,FB,E2,D3,ED,27,06,55,4E,9B,5D,E1,3C,7C,B0,19,8A,9A,02,1C,18,E1,D4,EB,62,47,86,16,65,CC,6B,C4,88,B4,23,65,50,05,33,21,EF,32,61,F9,87,DD,AD,84,06,A1,77,F6,2C,F0,54,A8,9F,67,46,A0,12,08,BE,57,D8,43,59,FC,FA,FA,81,55,AB,DE,C0,EE,85,44,F3,91,45,00,32,6B,96,4E,E9,14,15,A1,8D,FD,21,38,AA,FF,38,9D,C2,08,AC,FA,91,BA,32,57,61,33,22,AC,66,3F,41,F2,BE,D8,51,EE,F1,CE,CB,64,72,F0,91,2D,67,FE,85,D3,4A,36,E1,29,82,75,CF,1A,47,E3,1A,89,A8,87,04,D8,6F,9B,CC,C1,C4,13,E2,61,03,FD,5B,E5,07,F4,48,F3,C0,82,4C,2F,FE,C2,02,60,D7,F0,80,3F,7C,42,5B,9C,BF,3B,67,B1,63,AE,88,B0,AA,F7,62,A4,6D,7C,B1,DE,59,85,32,E7,8E,7A,45,2E,B4,E2,05,5A,E2,8C,3D,40,03,18,2A,C6,46,D1,8B,E5,42,24,DC,91,CD,82,87,0D,9D,DC,C2,57,69,9C,FF,68,5E,6E,92,E7,08,F1,96,79,43,E7,83,FE,51,51,B5,37,11,E4,56,67,84,06,EB,F8,80,FA,13,A5,EE,04,19,33,BC,DC,72,16,0C,43,A5,AF,D4,74,8F,D9,C0,E4,D9,CC,B0,C9,FA,A0,8B,0D,29,8D,8E,02,EC,0B,B7,1F,69,8A,B2,7A,41,12,AA,C9,15,51,63,BC,70,A1,B9,53,AC,5B,CF,3A,C5,CB,90,7D,2B,50,2A,57,4F,22,0A,7F,38,3A,C5,04,AA,C5,D1,5D,CD,B1,9B,CD,48,53,F2,46,D5,8F,C0,F8,8C,72,E8,76,7F,DD,BC,C6,06,38,00,B6,56,64,28,7F,F5,93,8D,84,C6,72,7C,8B,FA,11,43,2F,1B,3F,E1,0F,9C,0F,39,D0,6A,D6,DF,53,AA,C7,E0,5D,DC,8B,6F,6C,B2,75,07,93,B6,FD,E3,7E,7C,70,8E,35,32,0E,47,E8,10,AD,E8,0E,B8,52,F2,9B,78,B7,B5,A2,AD,48,95,14,06,6B,CC,73,28,BD,D3,08,17,8F,BF,AA,09,58,D5,32,C1,C7,41,BB,8D,CB,8E,F5,A5,19,95,DD,58,B4,98,FE,AB,3B,05,B7,AC,CC,A4,6E,7E,62,8C,57,D1,70,41,A0,8C,41,43,80,63,15,D1,C4,5B,4A,4F,42,36,3C,DC,2E,3B,B2,55,22,1D,33,5E,0A,87,61,9A,DA,22,9B,4A,65,45,F1,1B,AD,00,02,F2,D3,58,74,D1,5D,9A,E2,6E,C9,8D,26,BB,70,AB,DA,0F,0C,53,85,25,32,04,30,79,F0,4B,B7,A2,7E,CC,E4,5E,73,C2,76,B6,EE,C7,7A,D5,73,41,3B,6F,A4,85,A6,7A,4F,92,0E,43,9F,45,A4,5D,2E,67,C9,F8,2A,21,C9,49,9F,68,82,27,3C,73,BE,6A,FB,91,F6,49,23,AE,9D,D2,20,CB,9F,2C,43,94,82,D4,1E,33,B5,75,E1,1F,A9,24,FE,6D,43,5F,CD,3D,E8,26,78,B8,BA,FC,5F,2C,36,7F,59,1F,5D,63,E3,9F,A8,1A,8C,6B,00,28,2B,0C,29,12,78,77,A4,63,C3,E8,87,2A,96,9F,A1,63,5F,AF,D7,C1,A2,F0,09,3D,9A,0A,99,39,D4,B3,D0,E7,42,D4,1D,C3,A5,FD,C9,1A,A1,41,AF,7E,AF,CE,F9,C4,F0,C2,B2,2A,ED,2C,1A,5B,14,B4,BB,3D,DF,CB,14,6A,16,43,46,54,3F,F7,6A,06,37,22,5F,E7,94,73,65,21,EE,3E,57,03,23,0C,EF,1A,81,BE,F4,57,45,59,0D,AB,8F,E8,68,E3,96,04,45,A8,EB,BF,D2,10,B5,CF,1A,BB,3A,BB,E8,B0,16,CD,95,36,AB,17,93,75,A7,CB,7E,B3,2D,46,5B,E6,FB,1A,0C,55,67,E7,93,CF,3B,92,D6,0E,AD,21,68,85,67,E1,55,FD,5F,76,F8,83,2B,73,E6,FE,AC,13,46,E0,A0,C1,7D,64,8F,2C,5B,24,67,6A,2C,04,73,97,17,C8,BE,64,36,44,FB,E2,50,38,45,10,BC,2A,4B,E0,64,A6,97,55,4C,54,F7,C1,2D,87,25,B1,F8,15,6E,2F,24,7C,7A,E7,B8,19,FF,D0,2E,8B,58,63,8C,48,DB,1B,31,EE,35,20,3E,FB,49,65,9A,7D,C9,6E,0C,41,39,63,B6,71,30,4E,78,DC,BB,3A,9F,BC,37,26,F7,96,3D,DB,6B,FB,EE,8F,AB,B6,11,51,17,48,AF,93,92,C2,64,8E,56,BC,59,28,00,61,20,CD,09,32,2D,BE,24,CE,CB,CB,5C,EE,5C,57,77,57,81,41,81,0B,95,6B,A2,B3,02,CD,39,D5,21,E4,EC,AB,C0,7E,42,79,B8,95,8E,5A,AB,5F,7A,45,92,23,95,D3,1B,0A,29,04,3F,9C,10,AB,E3,40,B8,63,0D,23,39,3C,46,23,A5,AE,DA,13,96,1E,A4,47,8A,DB,E6,7E,62,DC,AD,24,7B,AD,1E,E4,E4,B7,09,35,9E,0B,F8,24,7D,17,74,03,9D,D5,D2,98,80,05,67,AA,D0,B9,CC,0F,97,A4,0B,49,11,25,15,5E,B0,39,23,6C,6A,20,1D,53,0E,2A,B0,76,0A,27,46,0B,85,60,89,11,06,2C,F4,2C,01,9A,2F,D9,06,2D,F1,F8,CF,D5,D8,DF,9B,20,21,AD,FB,EA,9B,EE,6D,2B,01,18,B9,3B,14,27,E0,CB,36,92,6A,02,AF,3B,73,8F,87,49,05,59,9E,4E,53,04,49,EB,C6,00,8C,BD,67,BD,71,EB,E2,FB,39,36,ED,97,23,F4,AB,EA,0B,D2,DF,6F,F7,59,C5,44,4B,D0,B1,FC,87,40,52,1A,59,81,11,9B,E2,E1,7A,24,CC,54,A5,E6,C6,61,9E,06,12,7E,5D,93,74,46,E5,91,CE,10,F3,CA,4F,5E,CF,B9,A6,C9,77,88,35,00,10,A9,7B,B9,2C,1F,D8,73,F1,87,AB,D4,06,0D,33,67,EE,B1,3A,0A,2D,B5,A4,2C,65,9F,DE,E2,A1,84,F1,F4,63,43,FA,AF,56,0D,7F,A9,68,85,86,48,AB,0F,C2,BD,A6,CF,E3,59,3C,65,C1,2E,06,6E,F9,7B,92,2E,AF,77,F1,2B,64,B5,E5,37,92,10,8C,2A,05,18,88,90,8F,D2,4A,1B,24,9E,14,1B,2E,FA,C3,82,9C,9A,B7,13,40,FB,31,38,3F,55,59,1A,4C,06,96,AE,DB,E0,B8,73,06,E0,C5,C4,70,8D,21,54,B5,21,F5,AA,A6,74,9B,77,9B,37,C6,A9,5B,FC,5A,F1,82,5A,A5,B4,9D,2A,69,49,14,51,87,11,F9,ED,EB,E6,5B,B4,81,E3,FD,CD,FC,8A,1F,B7,B0,5B,86,45,C8,06,1D,11,37,50,1B,87,3E,29,56,17,34,96,B9,AE,61,D8,75,D4,F7,B4,11,B8,7A,C1,72,CE,AC,52,34,D3,DF,9A,68,62,74,1E,21,48,42,F5,12,90,53,3F,7E,E9,11,02,81,50,1B,AC,B8,43,BC,E2,9F,A2,AD,F9,8B,14,47,55,25,6C,B9,D7,D9,3D,32,0D,66,DE,B3,03,FB,34,D8,5D,27,D1,F3,4E,4F,D4,4B,45,44,E4,8D,1B,6A,05,82,FF,6A,13,45,D7,3B,D3,51,F7,EA,F1,B6,F0,5B,32,F0,95,6F,AC,E3,0D,92,74,26,63,26,2E,E3,32,FD,60,3C,B6,45,04,B3,D1,F9,DC,EC,DD,BE,37,49,F7,B3,1D,7C,E2,47,B1,AC,4E,9B,10,17,0E,6D,B4,F0,F7,10,E7,67,5A,43,93,C9,B6,0A,EE,BB,19,56,81,DD,BE,AA,CA,D7,45,F1,A9,A3,EA,E9,7E,9F,59,3D,9A,4B,78,60,40,D7,A8,8C,F8,98,AF,29,0A,63,B3,D4,3B,07,72,E2,50,B4,EC,D8,96,CB,9D,64,85,74,42,AB,4B,7D,63,78,56,FC,DC,7A,86,4D,97,BD,54,A1,25,C8,27,69,88,30,80,36,55,63,CF,E2,66,72,71,C2,48,DC,52,CD,84,7B,E7,59,04,60,0E,DB,EB,5B,DA,A6,9B,07,EA,F9,63,3E,64,AC,60,B4,E6,A1,69,92,B0,04,3B,69,80,B1,D1,47,02,6B,93,8C,29,F4,B5,85,90,2A,84,C4,A8,EE,B8,C7,80,03,66,2D,17,DA,95,76,D9,DE,D4,51,E3,17,A9,BD,89,0B,41,11,73,D7,65,15,7E,5B,17,A8,70,8D,68,74,DF,66,8D,C6,04,29,A4,36,A8,51,FD,FC,44,53,4E,7A,E2,02,C3,32,59,AF,F3,4E,BB,EB,E8,70,23,CA,B0,1A,A1,EC,C2,1C,5A,CA,DF,00,6D,A1,BE,21,BA,B4,DC,44,98,44,8D,D6,E8,10,42,13,18,B0,18,89,92,46,4A,E0,B3,32,5E,4D,D4,96,1E,98,A8,61,27,FA,D4,BA,FF,DA,01,1D,25,D6,C3,3F,72,27,E4,11,A3,18,B5,6E,02,AF,34,02,13,D7,F4,64,42,A1,2A,64,8E,17,FE,5C,B0,C3,1E,1C,2D,82,85,FA,6D,78,89,FF,C9,B7,B8,C1,18,C3,1E,01,38,57,20,88,15,80,AC,D7,3F,1E,DF,FC,7F,5E,3C,39,E4,1C,D0,65,D8,42,BD,BC,FB,2D,37,A1,E0,70,BD,1A,F8,D0,5C,83,2C,49,1F,EC,B3,9B,B5,D2,A0,80,30,AC,FF,15,09,D4,92,D5,90,65,F9,7C,36,FD,E3,35,1F,D6,FC,82,A3,F5,FC,72,A7,8E,E9,2F,85,A7,62,2E,27,1C,E1,AB,A7,DC,26,96,ED,8C,F2,CC,AE,75,9E,A7,A5,1E,A5,AE,75,AC,31,BB,4A,E2,B4,50,06,25,06,59,BC,31,07,06,17,BD,F2,99,2B,B2,15,84,51,BF,E0,E1,B9,11,63,B2,6E,91,73,4F,A0,20,E4,99,02,B8,9F,B8,2E,98,29,BC,4F,DC,3C,F0,F0,49,09,37,B2,D3,2D,B7,29,F7,F0,84,3C,AB,19,44,69,8D,EB,DD,11,32,EB,DA,2A,79,09,B9,5C,6A,44,55,A6,AD,0B,64,E9,B5,53,42,F3,63,CB,62,66,0E,37,C5,C4,68,12,5D,EE,E2,6A,3C,B3,E3,54,F6,E4,F0,5B,0D,0E,8D,C0,93,8E,11,9C,E7,EB,B5,9E,BD,C2,0E,9D,FC,96,92,3B,EE,56,39,C4,A7,BE,08,E6,1A,A8,D9,B9,C0,C4,28,10,16,6C,18,CD,76,AE,F2,45,F2,74,C8,7E,27,F0,99,EF,87,24,D3,7A,94,B8,FD,1D,F6,DE,B3,01,BC,8D,90,FC,15,F7,69,73,7C,2D,84,7D,F5,03,72,D7,05,14,C2,6F,FA,64,EF,44,A8,05,F1,83,18,AB,07,F2,D1,1D,0F,7A,6F,DD,66,84,8D,17,2C,19,81,63,6F,1D,AD,F3,FD,63,B0,F5,C3,FA,68,95,CA,29,DA,75,4C,23,34,93,50,98,AF,00,91,C0,4D,EB,E4,74,60,A7,44,D4,F9,FF,02,C5,0F,DC,62,49,20,84,DE,69,C7,44,20,FF,3B,34,4E,54,49,EF,79,B6,3C,12,DF,20,C1,E4,42,BB,30,1D,7F,B7,88,49,D5,79,D2,CA,B4,AB,F2,60,61,3C,28,BD,42,87,0D,47,B1,B8,A1,FF,2B,E2,ED,5D,D3,83,46,1C,02,45,15,FC,3E,1B,66,DF,73,C2,BE,E9,AE,E8,75,78,15,C4,9E,E0,C2,A0,B2,DC,F9,69,3E,59,CD,1C,39,65,E2,C3,45,EF,60,08,BE,B5,42,68,BF,FB,9C,D1,61,63,08,C0,DB,73,0E,F0,DE,C5,F3,B6,E4,96,0B,2E,2D,58,0F,14,D4,CD,D9,A1,7E,5A,9E,80,96,62,E5,8B,38,38,BF,38,1B,BA,EC,47,AD,30,5D,2C,9F,42,5E,D3,5D,9D,17,5D,C9,98,14,60,BF,5B,46,19,5C,5B,47,80,EC,3E,77,83,D7,17,DB,94,05,00,9F,EC,62,A9,AC,41,75,D7,C4,D2,BB,ED,02,7B,D9,33,4A,84,C3,5F,4C,6B,E0,94,40,D3,6B,E3,70,7C,24,33,8B,56,5B,52,9E,A3,0D,C8,EC,D9,B0,9B,37,0E,C8,5D,80,29,36,2A,3B,2C,69,9C,5F,F1,6D,46,03,40,73,0E,5A,C6,16,25,DE,59,06,F2,B1,FC,97,5E,8A,06,7B,6A,A8,0F,4B,50,74,8B,65,06,61,50,CC,1C,82,34,D9,78,7B,6E,F2,61,7E,D6,11,13,02,4D,1D,BE,0C,D0,48,90,9E,C9,FA,EB,7C,21,EB,D4,08,6D,60,32,1D,70,AD,45,8F,C6,96,1D,48,C2,5E,A4,3B,A4,5F,A6,DF,10,22,28,79,DA,4C,7D,BC,8D,88,82,F1,F4,8B,9D,BA,C6,31,C7,A9,E6,7F,42,0F,4B,25,C8,74,C6,00,E8,56,B1,A4,D7,DC,65,CB,F0,FF,B6,96,2D,F6,2C,87,D7,7A,C2,33,D6,3B,51,95,E3,D1,E0,54,6A,DA,88,87,34,1A,8B,9F,CD,EF,8A,F1,6A,0D,E7,E8,54,A0,40,AB,D7,B4,0F,F8,6E,CC,6B,90,1C,C2,0B,67,40,EB,4F,3A,79,3F,08,64,8A,70,5D,40,BE,4E,EA,58,70,35,A4,A7,BF,9F,18,C1,C6,F0,B6,39,32,B2,82,1C,9B,1E,41,AA,9E,D9,19,D8,55,DA,06,A7,83,F2,ED,1B,CD,81,F0,34,72,06,FE,3A,F0,21,C8,98,44,DA,5D,84,5E,BA,C1,F5,E2,CF,1D,02,4F,70,81,72,98,72,55,BB,D0,F8,FA,10,79,C8,62,CB,D2,B1,BD,84,EA,AF,54,DF,8A,E2,72,E0,DD,C8,27,30,82,4E,5B,D7,09,34,5C,67,91,C9,4B,2E,4C,04,3F,F5,7F,8D,C9,1B,C8,41,9B,E8,EB,9C,B9,11,3E,FF,1C,BB,03,FB,77,C5,8E,0C,C5,92,BD,28,53,B7,49,62,67,86,71,47,3B,2B,DB,2F,B1,08,DB,B8,DA,3D,C6,7D,87,6B,CB,57,11,21,D9,43,63,F5,71,41,13,7D,97,96,81,AC,C7,7B,BE,14,0D,13,51,84,51,BA,99,A3,CC,9B,5E,39,70,DB,DE,FB,C6,15,46,E4,82,8D,D7,ED,87,14,D8,E8,CA,3D,28,6D,7A,C6,02,07,1E,D9,87,BE,4F,E1,05,17,0E,D9,9D,AB,E1,FA,BE,79,2F,A8,83,34,E9,F3,60,DF,43,3A,5F,5E,62,0F,CC,FF,6D,29,A6,A0,0A,EA,A8,2D,2A,05,B6,C1,9C,03,D9,46,F4,13,C8,8E,E1,28,9E,F9,7D,32,83,E5,12,28,31,32,FE,F0,10,75,0A,B1,30,33,40,7A,98,BC,F3,68,DB,B6,22,AF,8A,6E,BB,DF,92,86,52,B5,1F,C1,BF,D2,03,A0,4A,E7,F7,84,AD,45,1D,75,10,FE,E6,5F,3E,6F,54,A3,2D,95,17,E5,33,D0,7A,25,9C,83,0E,D8,7F,4B,5F,2B,8A,6E,C3,B3,37,2A,56,66,C3,18,44,F6,D4,D9,1F,5E,0C,A7,B1,87,67,90,23,DB,16,08,D9,AE,67,90,80,ED,2F,CA,79,05,65,FF,F1,D0,B2,41,04,1C,C7,C1,42,76,D0,58,C9,D0,FF,87,28,6D,B5,0D,A3,4F,64,1F,4A,30,FD,9A,8D,4D,5F,1F,26,FF,05,0E,26,A0,92,BF,7F,2D,2B,CE,29,3C,84,C3,4B,11,7F,91,43,86,64,1F,B9,E0,8C,51,15,7F,F4,49,3E,1A,76,E3,73,60,10,7C,DB,BC,BA,B4,BB,DF,4B,16,29,00,B7,D8,FA,D4,3B,0F,50,AC,12,03,B2,93,1E,AC,C2,89,0D,A1,F9,2C,C1,AF,89,21,C9,6F,74,C3,8B,97,C5,AB,E1,94,93,00,18,33,2D,C6,D7,72,E6,52,BC,D8,80,21,87,15,90,5B,C9,BD,20,65,8F,72,4A,E6,10,8C,32,F2,2C,3B,BA,90,C8,AB,7A,14,10,18,B0,77,36,DB,0F,06,35,5C,13,FF,28,AC,D3,5A,62,33,6C,9A,11,21,C6,E2,D0,69,40,4A,98,E8,1B,D2,AA,95,AF,27,AA,71,E7,AC,D5,0D,C8,DC,3B,90,B3,DE,4F,5A,1C,EF,B4,D7,29,37,21,EC,94,AF,FD,FF,78,F9,A4,72,7A,5A,56,5D,4C,BB,DE,79,28,3C,68,C2,2A,29,B3,15,04,4E,BB,3D,14,E6,43,2E,6C,FB,15,73,18,B1,9B,8C,14,66,42,55,3A,51,51,34,64,06,1F,40,6E,F8,85,DA,6C,E7,15,F3,D2,AA,81,46,8A,CB,44,58,2B,50,9F,AF,2E,BD,79,D7,92,29,A8,67,8C,2A,2E,12,73,14,B5,64,C7,89,2B,E2,0D,5E,B9,60,96,95,0A,F6,C4,A2,FF,9A,5D,B9,F6,29,B3,0F,75,CC,6C,A2,05,B2,B4,82,2E,1C,2F,7F,C8,3D,AD,46,F8,F6,5C,1F,23,39,58,CB,4D,C2,BA,BD,CD,11,BE,AF,A4,DD,89,C8,C3,AE,D6,64,63,6D,69,6B,19,9F,B5,75,C6,0B,19,FC,0C,C2,8C,C3,59,08,D0,1B,10,DD,18,02,F3,6E,F3,64,81,F4,38,57,00,59,1C,FF,AF,A7,FF,64,26,5E,94,E9,45,19,4B,AC,E8,4C,BB,EF,F3,D4,07,04,7F,FD,0F,04,A4,8F,DF,7C,AD,75,B0,FC,CA,1A,37,0C,4D,4D,3B,8A,93,4B,B2,9F,6E,AD,11,30,AC,4B,16,E7,E3,0E,F2,A4,EF,97,6D,05,2C,72,69,EF,9D,B9,F8,18,A4,E9,EA,EA,6D,9F,3F,88,CE,C3,96,93,80,75,22,B9,E8,6D,07,A9,3E,6D,27,AD,9B,B2,34,FC,60,96,B3,6D,A2,A8,A9,52,ED,3E,18,36,E1,BB,7E,50,5E,82,AE,63,9E,EC,A8,79,CC,77,64,F4,89,8B,EF,73,63,2E,01,15,84,A6,31,FD,C3,82,8E,E2,D9,E7,F1,A7,86,C9,AB,AE,AF,BF,38,FB,0C,FD,50,DA,AB,E7,EC,C0,CD,07,D9,F1,42,69,DB,CD,18,97,6C,68,F6,23,B7,49,61,D2,E4,89,18,77,C2,4A,DA,08,BC,42,C6,3D,E2,45,58,A6,3C,F5,22,28,09,42,24,63,0E,8C,2B,59,7D,48,78,59,7A,A0,77,FD,CA,5B,A2,BF,60,FC,FC,67,D7,9B,3F,38,8A,16,51,0F,9F,94,B4,A1,D4,68,F1,3B,7C,A0,C0,F1,0B,02,CC,54,C9,CA,C7,EC,7F,05,50,0F,B3,0D,DA,8C,5F,85,EA,A5,0A,A3,4C,52,26,28,70,C8,4B,D4,CB,AB,C8,A3,D9,3A,DD,3E,42,32,36,1F,28,06,1A,11,93,FC,F1,BC,B2,F8,C4,3D,E8,AC,34,0A,33,79,C5,D9,80,37,DC,34,DC,38,E1,D7,38,66,72,8C,7D,0E,6E,70,90,FD,9C,1C,9F,E1,15,19,3A,17,48,CC,31,D6,24,94,7D,4D,0F,90,8A,2A,34,8D,2A,9A,53,11,91,CC,8C,76,AB,83,F2,B2,04,34,9A,7E,30,54,A9,02,9E,F7,07,5C,6E,1F,84,5F,F1,8D,F8,6E,2F,11,95,72,3A,16,A8,18,FA,BF,6F,57,CF,42,9D,C2,6F,8F,EE,01,25,1C,E6,CB,F3,7B,B4,2C,6A,66,01,EB,E1,8F,0C,A5,E5,E2,1B,21,0A,89,99,A4,6A,8F,95,0E,2B,E5,BF,60,C4,31,70,F8,D7,95,E0,DA,A2,82,86,EF,6A,3A,26,08,09,6A,E0,9E,1E,CD,0A,23,15,0F,70,90,B5,33,63,29,B7,AB,D5,21,D6,89,E8,6E,86,92,8F,14,5D,AD,5E,8B,F3,AD,D9,F4,9E,77,30,2D,C8,9A,26,23,36,A4,46,F0,DB,34,B0,F6,1E,64,1F,46,28,16,91,5C,01,3D,B3,53,84,3B,FE,14,02,8C,62,08,E7,0D,F0,CE,D1,B1,0C,9B,2B,7D,7C,8D,AF,78,D5,F6,26,5F,22,7D,D7,83,C4,17,7F,B9,0E,A2,4A,53,F2,72,CD,42,26,4F,C6,2A,3A,FB,34,6F,A6,49,7A,67,EB,8B,73,12,53,E0,C5,8B,BB,76,BF,BA,AF,E6,DF,09,E8,EF,2E,75,C5,6C,67,55,56,CF,B8,C6,CF,03,83,98,4D,FC,64,80,CC,85,71,07,4A,11,74,D4,92,0A,73,B3,42,2D,59,ED,F4,B4,3C,4B,01,96,6B,FE,F6,D5,18,F7,4A,F7,49,09,C2,4F,EA,85,6F,13,C9,14,38,16,87,96,EC,DE,55,7B,91,33,75,EE,79,E8,91,89,FB,F0,7F,A0,26,40,7E,FC,B2,DC,D8,E8,E8,DB,BF,FC,ED,7E,25,83,1F,F5,2A,3B,CE,B1,FC,01,FA,26,45,42,46,45,5E,B5,88,9A,2E,7F,64,25,B7,17,A9,6B,06,A0,BE,49,CB,1F,8F,AD,03,68,35,09,DA,AF,FB,23,67,2B,0C,56,F8,FC,1A,7C,B7,D9,E6,36,AF,79,47,F4,E8,57,AC,41,0A,9A,60,52,50,BD,B2,5C,4E,B6,61,A8,09,E8,B7,13,5B,10,D5,C5,CF,87,F4,36,1F,A4,BF,0F,AB,AF,E5,FA,0F,DF,9E,80,F0,3D,E1,23,B7,00,62,0E,D6,8A,F3,11,29,85,1D,AF,79,52,D9,F6,C8,FC,F1,E0,38,C3,95,D4,29,40,D0,34,94,AD,0E,9C,81,D8,8D,7C,27,68,3E,AC,59,50,88,12,CC,E0,A4,3D,C8,2D,3A,17,02,46,F1,4A,CA,0F,80,F9,E8,C5,60,86,EE,6B,69,BE,3D,82,07,99,7A,4E,6A,CA,10,DB,C6,73,95,A8,F3,A2,43,FA,3B,F5,58,5B,06,3B,33,63,00,09,DF,62,16,02,47,A0,E2,5B,7D,88,FD,CB,5C,56,5E,F6,3D,AE,B2,66,D1,3A,E4,08,69,F4,10,D3,95,C8,15,5C,51,D4,9A,D7,24,1A,6E,14,9C,EA,C7,C6,A8,76,7D,B3,31,2F,BA,90,9A,0E,4F,C3,D4,BA,7A,1A,13,4D,08,40,C8,BD,D4,D1,59,75,7A,5C,0E,04,FC,0C,AC,6E,CE,08,5C,2B,89,E0,8C,14,14,11,69,32,84,0B,F9,8B,DF,01,4C,8E,F5,F8,B5,38,C4,3E,7A,97,C7,6E,FD,6B,0C,DC,A5,E9,81,5A,C1,A2,97,F6,5E,06,99,C2,F5,E9,AD,EB,00,64,E8,49,C6,CE,13,EC,C4,4A,10,89,51,C1,86,3E,A3,9B,92,51,F0,EA,F0,28,93,5D,0D,6A,63,84,E9,EF,58,B1,C5,F5,FC,63,93,B9,92,DD,F3,35,6C,17,74,1D,5E,40,A2,C3,79,DC,7A,55,38,50,ED,D5,EF,CD,48,E8,57,8A,33,CD,3E,E8,25,FE,F5,D8,FE,B4,F8,6A,95,A3,EE,91,E4,13,EC,A6,B6,CB,F5,9C,DE,24,FA,B3,E6,F6,FF,C1,49,FB,1B,D8,39,6D,A7,EE,15,24,17,B8,6F,43,D8,7D,2C,65,55,21,3D,28,31,F4,86,1D,16,8B,65,D7,D2,F9,31,AF,6A,DA,23,CA,8C,52,AA,6D,6A,53,8B,CD,C0,78,8E,94,96,1B,9B,51,FC,E5,1D,CD,09,18,81,D2,82,5D,1D,E2,B5,92,39,09,2E,03,7D,A4,DD,60,86,A9,E3,ED,64,44,90,3C,96,C3,D6,2E,15,07,A9,CF,76,7C,40,4D,B4,F8,FB,DF,5B,2A,4F,0F,C2,F8,44,B1,11,CE,77,BF,20,35,89,10,F1,7A,7E,86,9B,BA,96,3E,83,CA,30,EA,FB,7C,83,4B,CD,B1,21,69,DD,F8,BE,34,95,EC,91,3D,CA,D4,98,C0,D9,E9,80,6F,80,43,D0,9D,56,46,66,71,55,41,4D,52,D0,C6,B7,AA,D4,84,BA,9D,E3,85,7F,65,EF,42,AB,F1,A4,45,3B,C4,74,9D,62,0E,E8,A2,23,4C,1E,D8,14,29,61,AC,32,84,F0,40,0B,E8,A9,F6,F3,D8,E5,2E,1E,01,03,13,A4,2B,85,8B,00,84,04,64,8C,FE,61,27,95,EF,4F,C8,5F,BA,1B,D1,16,8D,A0,88,C4,3C,4E,00,69,57,76,AD,66,A7,A0,2E,47,88,25,25,BC,A5,CA,90,65,61,35,CB,7F,DB,7A,E9,6F,DA,10,A8,D4,28,A3,4E,B7,3C,D4,12,7B,29,06,3F,75,05,3E,A8,69,02,C0,FA,E4,E2,9F,FE,A1,7C,4D,CE,9B,DB,A6,44,0D,DA,CE,2D,2B,9E,92,09,F4,E4,08,82,9C,53,31,14,22,EE,A7,AC,9A,C5,EA,44,1F,77,74,0F,5D,DE,B7,86,EB,17,92,00,DE,67,D3,3D,7F,09,DC,6C,F3,CC,FD,F8,34,A4,EA,4A,DF,77,BE,3D,B4,95,0D,21,12,64,9C,23,A0,87,38,15,F4,86,00,DD,CC,01,6C,33,FA,C0,51,6E,18,89,52,6E,5E,59,D1,D8,F4,83,D5,6A,A7,7E,A1,96,9E,67,1B,EF,77,D1,E6,D6,1D,D2,CB,5B,E5,6F,04,AD,DA,D3,A7,4C,3D,67,B3,FA,35,CA,2C,41,95,0D,72,03,1C,0E,1F,96,4E,00,54,A9,85,BA,A0,84,19,EF,8F,2C,34,B5,13,B2,9F,08,E2,2C,20,5E,B4,23,A1,4F,FA,61,DA,5F,F3,CD,C8,82,21,89,23,0D,96,E3,F9,9F,74,80,16,AE,9F,31,5D,33,36,9B,34,82,83,E4,5B,01,58,25,03,63,4A,45,DD,7D,50,E5,03,12,91,80,F6,B9,7D,40,C7,D4,3A,C0,E8,63,49,49,41,73,B2,17,8F,4E,77,6A,14,D4,2B,26,DC,8A,0E,F1,C7,96,22,92,C2,DD,F7,BD,50,F7,0D,D1,66,59,2B,14,E0,DF,6A,64,17,35,DA,D9,FF,1D,0C,84,57,76,87,27,E3,5E,60,C0,DD,58,08,EC,65,97,79,DC,71,D7,1A,5A,AB,BC,40,30,94,50,54,43,AC,7A,42,7A,5A,7B,46,E7,67,12,F8,EC,5C,A3,DD,38,1F,E5,F4,EF,F6,9A,E1,C0,C9,27,7E,78,28,6C,66,3D,C7,1E,35,3B,5E,05,0E,B7,B9,82,F3,84,64,D5,7B,99,48,47,A7,A8,12,79,1A,D8,84,4D,F5,89,43,12,3D,3E,BA,59,08,BD,42,20,C7,4A,F0,F0,EA,00,5E,31,A7,26,B4,26,4A,B4,F4,88,91,0A,59,D2,D6,22,5C,3A,09,63,62,8D,F3,10,EC,4A,E7,50,82,A0,A4,2C,BA,C3,BC,BA,AA,87,1B,85,00,21,4B,29,4D,B7,36,18,2F,10,3C,DB,48,F8,A8,F4,97,37,5F,B8,7B,72,38,72,91,87,C4,0C,01,B9,23,53,A5,5C,2A,B3,6B,FF,30,92,E3,33,73,39,F0,5E,1E,E5,BD,2E,A9,05,D6,F7,08,60,8B,75,41,44,4D,4E,D4,EB,70,07,13,7E,1E,1A,27,4C,25,A5,40,96,67,19,4F,C2,74,9C,1A,F8,AC,4A,54,5A,85,9D,AD,98,79,CB,2B,A7,B0,DA,27,81,53,8B,59,55,39,64,66,DC,9F,8E,D9,77,66,07,18,4E,96,E5,F1,B7,FD,DB,2C,F1,BA,29,93,8B,81,74,7D,61,35,C0,D8,18,11,20,7C,52,B2,D3,0C,28,96,7F,90,95,E7,F8,D5,75,14,E3,FB,6C,32,BC,E0,C0,DF,7D,24,E8,6A,9F,E5,47,40,14,1A,0F,CC,A3,BB,7D,5A,57,E4,57,23,10,F5,A5,9E,8D,45,C6,34,A2,AA,30,9A,23,0A,5B,AD,95,AD,71,82,75,53,DB,DA,16,50,2E,07,39,B0,67,1F,2C,6A,E3,A9,9C,22,62,31,0B,BC,48,46,2B,B8,F5,93,56,85,29,F6,FA,99,7E,B4,B4,78,4F,0A,C3,28,CD,18,0B,6B,FB,5C,DE,70,AA,12,6D,CA,05,B7,3C,90,A0,EC,A8,96,EF,FE,4D,69,CF,5B,24,18,5D,3C,B5,95,95,D4,85,52,F3,7B,68,DA,EC,3B,55,22,C7,04,09,83,69,C5,D6,27,3E,2D,A7,57,39,B7,74,5E,CD,E7,BC,3C,B1,EC,5B,12,96,6F,82,00,40,6A,32,AA,BC,BE,08,27,6B,6A,58,46,50,98,BC,F1,40,5C,24,EC,78,28,54,41,6D,F2,68,06,83,C7,D4,74,FB,DE,19,CB,73,E0,D9,DE,EA,BE,C8,1C,AE,05,C1,8E,13,CF,F5,9E,EA,F0,3A,6E,9F,B4,ED,09,D6,6D,45,30,78,BF,A5,93,1D,59,63,5A,01,2F,1F,31,59,93,EF,A6,F0,45,FF,00,D6,B1,16,36,4F,3C,A2,1A,73,5A,8F,40,2C,96,C9,93,3E,D6,4C,85,74,59,0E,4F,9D,16,BC,2F,00,DD,76,25,BA,86,2F,5E,BF,D1,0B,9F,77,8D,B0,62,34,CF,59,80,D3,C4,23,C4,FC,AE,51,CC,2C,5F,3F,38,1C,AB,CF,8C,81,EA,9D,07,D0,71,E0,BB,14,01,75,6F,5A,56,C2,12,71,5B,40,01,4E,2E,F5,BA,C1,41,57,1F,FD,F6,5B,8C,1A,4A,62,4E,51,E9,28,A4,B7,DE,D8,0E,B9,24,CD,42,9E,96,4E,5E,22,A4,C3,DB,78,0D,BA,98,EE,7A,7A,60,6D,B0,A2,C6,A4,4A,A4,8B,FA,FF,83,A6,2A,B5,7B,54,CB,F0,98,30,19,31,E6,27,3B,7B,D5,40,DA,E1,E1,8A,99,35,5A,96,2B,89,B8,A4,4B,8B,E7,0E,84,B2,19,B6,36,B6,53,64,7E,AB,81,64,DE,3B,67,14,CF,AA,9F,9F,57,F9,2D,FD,8E,36,A8,56,30,17,16,24,6B,94,4B,C9,B1,8B,AF,D7,EB,72,12,4F,AC,79,D2,01,06,01,6A,B9,30,05,C3,12,FB,CE,E6,FE,52,CD,EB,28,0D,F0,0B,5B,BD,03,F5,AC,D6,65,33,CA,23,79,CE,D3,C7,76,48,C1,3B,30,96,30,D0,BE,60,09,EB,5F,B3,6C,1E,1A,89,D4,D9,A7,14,B1,42,FE,28,07,62,D0,B2,94,5C,19,BB,01,6F,85,2C,89,A6,D4,3C,72,FC,BB,36,15,E0,7A,71,A1,C1,91,79,AF,46,08,7B,E3,A4,84,66,37,1B,A1,D1,C2,51,29,9C,76,52,C9,EF,CC,D1,72,56,D1,FB,93,6A,3A,D5,41,76,9E,6C,E0,31,5E,1B,D5,F7,07,A6,89,68,AC,BA,DD,88,7B,41,AD,ED,4E,4D,39,F8,45,9D,AD,6D,6F,43,60,B3,5C,E1,15,03,C4,3D,8F,11,3D,3E,6C,95,E9,AA,D6,11,0E,02,66,DA,4B,94,26,C6,D0,F6,2A,58,30,F3,20,7A,69,E6,3B,BA,F1,58,8D,AF,AE,2C,53,D7,2B,62,31,19,C1,19,19,D0,E1,6D,56,57,89,A9,3D,A4,A3,F9,15,A4,45,84,82,93,A9,75,F8,54,20,C3,61,C9,91,E2,09,69,85,7D,EB,7E,66,81,42,40,E1,44,5E,D8,11,C9,6B,35,A4,82,E3,13,3E,D9,1F,AA,11,55,7D,B4,41,B5,6E,93,82,FD,3D,5A,21,B2,84,94,08,67,DD,95,92,CC,56,D3,98,0B,86,9A,9E,6D,FA,CC,76,F8,B9,CC,53,07,13,84,DB,DB,F1,B6,8C,F8,46,65,29,4C,5A,DE,C5,09,34,01,C7,08,49,4D,D9,AF,2B,2D,E9,BA,75,86,F4,70,7F,52,74,3F,15,D9,15,BE,EF,3D,6B,8A,5E,CA,B2,78,6D,4E,9A,67,73,44,48,0F,B2,F8,04,7A,1D,17,14,D3,AE,F8,E4,2A,F1,F4,C1,AE,FA,EF,BF,92,FE,C8,FE,B9,77,CA,7C,4D,71,FB,1A,38,26,D7,E0,3E,CD,A3,E6,73,EA,BA,B7,11,99,4B,F5,0C,F9,23,B7,B3,F8,49,62,83,69,7C,26,76,38,62,E6,45,FF,39,39,87,E2,A6,71,65,8D,44,9D,D9,E1,AC,7B,CD,53,28,71,C7,0C,5B,6B,0C,E7,9E,2A,93,72,38,D3,60,04,1F,BE,11,7A,3F,E8,D7,00,92,B2,50,55,99,D5,E2,2D,DA,33,C3,EE,28,A1,5E,4B,1C,CC,90,73,AA,30,97,06,AB,B1,1B,7B,94,33,BD,DD,EF,C2,FA,A5,EC,E7,31,25,BC,F9,10,5B,A0,F3,F6,96,AC,B0,FE,18,B6,F2,63,B7,C1,BD,53,A6,C2,98,E3,30,67,C4,98,BF,09,F9,E8,7A,79,64,71,6E,7A,F4,19,42,81,AF,9C,3F,29,1E,A9,D7,20,5C,CD,BF,61,06,96,FF,4F,CB,47,92,1B,FF,C2,13,25,B3,87,C4,4A,A5,1F,9C,FA,87,30,3A,17,D6,65,41,26,64,2E,38,08,84,C6,79,A2,1A,EC,89,BC,EA,8E,D2,05,E1,53,6B,A7,80,6D,34,D0,E5,22,8A,4F,53,35,90,3A,89,44,DB,4A,F6,47,FA,0B,34,67,2F,6E,CD,21,35,74,E2,05,45,39,52,A8,48,D1,89,9B,31,A9,87,3A,F1,10,F4,63,A4,7A,8B,CC,4F,08,DD,2F,82,2E,CA,04,4F,5C,FB,CA,21,96,74,B6,3C,E3,DF,15,B1,5C,4B,1A,34,A3,B7,F5,1D,B0,DA,7B,24,59,4C,B5,79,49,6E,12,D3,3A,51,54,29,F6,74,0E,64,13,F0,3E,97,44,2F,B9,22,F7,B9,81,AA,58,44,22,98,18,DD,9B,45,8E,7C,31,98,55,82,ED,B0,6D,4A,1F,23,F9,A1,8E,86,81,2D,08,6B,BA,2F,53,DA,A2,D2,E3,04,E7,9C,0F,1B,C4,4D,0E,B2,90,95,AB,E1,A0,EB,15,B1,6F,2B,84,E7,42,39,F3,7C,B2,EA,DD,98,1E,C3,80,66,50,CB,F1,EE,7A,C7,BB,A3,B8,8A,75,50,09,C2,EE,BC,52,BC,C0,C6,FD,67,B5,FA,32,39,42,FD,9F,BA,28,A1,66,C4,D1,48,9A,09,EA,D1,AE,09,EB,DC,66,D2,5A,D5,7B,C9,7F,40,65,35,2A,55,80,B0,2D,6B,54,E5,DD,72,0D,8B,B2,AD,50,89,BE,6C,E6,2A,B5,C2,5F,71,E4,D0,7D,59,B8,5D,D0,D3,A1,C7,63,93,D7,80,8D,45,C7,25,AC,93,99,7A,4B,C2,05,58,6C,C8,1E,9D,68,63,74,7D,54,E1,DB,C4,C6,D8,E0,D7,26,1E,68,7C,74,AD,36,CC,E8,15,89,04,BC,53,57,6D,93,10,BA,78,23,1F,4B,E0,FB,6B,F1,29,F0,45,D5,9E,C3,93,31,B5,04,17,F1,20,A7,E7,F8,CF,23,21,9D,83,7E,1C,1D,AE,32,06,EC,4D,E9,42,D8,EC,32,69,12,88,5D,39,45,9C,4B,1D,C2,51,09,DC,19,AC,D8,58,50,05,AF,34,FD,63,2F,E7,57,E5,32,54,09,2D,BC,7A,06,26,05,D1,27,FF,EF,D1,14,C0,45,95,C7,95,23,58,B4,E3,A8,CE,3E,F2,06,0A,DC,38,33,23,30,E1,C7,92,B3,03,42,D3,20,29,21,66,04,40,FD,0A,64,AB,F8,5E,5A,FD,BF,77,55,78,2C,44,46,0D,F5,53,FD,D0,2D,D5,28,1A,8E,0B,82,71,14,57,FA,5C,91,D8,45,40,4B,59,59,72,CB,0E,AE,2E,8E,D7,5B,DF,89,57,7B,77,CA,02,2B,CD,12,CD,41,A4,A7,98,4B,36,4D,22,FC,C7,73,FA,9E,E5,0B,46,ED,E4,5B,89,07,B5,26,D5,39,17,A9,CC,37,CD,73,15,07,2D,EA,97,BF,51,58,FF,58,7D,4D,85,EA,BA,41,39,65,7F,B9,DA,5C,A3,19,3F,D3,31,7F,3F,D7,F7,A4,82,56,D7,2F,D4,F7,EA,8B,C7,FB,18,09,B8,50,AF,7B,FB,EC,0C,E0,42,06,5A,11,09,08,8D,E8,6B,38,D3,9D,15,21,97,26,56,52,F5,39,31,6A,B7,7C,BF,40,00,20,E2,4D,C5,21,09,A6,1B,22,3E,5B,4F,66,E9,49,60,BD,2D,9C,E1,39,0C,48,CE,60,C3,73,2C,57,64,C1,1E,26,87,71,72,40,0C,DA,19,0B,78,B1,02,23,30,8E,1D,6B,23,D6,5F,3E,16,B2,BE,86,0F,AD,21,B1,B2,A9,17,F7,66,6F,F7,E7,22,06,C0,9D,6F,B6,F0,B0,18,16,1F,18,73,84,94,70,9A,67,59,50,14,AD,0A,56,0C,D7,71,3D,74,67,CD,28,26,52,51,A9,8A,FD,64,25,35,76,E6,3A,C5,42,1F,54,8F,37,EC,97,BB,A4,8F,DF,B0,75,2D,E4,1C,A8,D1,39,C8,49,B9,B6,E6,57,FF,7A,E8,FB,6F,4E,DB,B8,83,C9,DF,E6,40,0B,79,B6,99,11,82,3D,9E,F6,BE,95,97,A0,CE,84,C3,E9,37,9A,DD,FD,D4,C4,54,E4,F8,9A,DC,C4,40,56,D1,9A,78,61,18,2A,53,ED,1A,CB,51,34,D5,13,62,91,FC,19,9E,2D,3D,B3,6A,B4,A7,38,CC,38,15,EA,FE,22,EA,08,53,9B,BE,C3,1C,EB,21,7E,8F,74,E3,11,B2,1E,6C,6D,E0,DF,53,B3,ED,EF,A5,6B,F3,1B,AB,F6,F0,84,7F,E2,23,C4,ED,4D,9D,71,51,9D,0F,FD,3D,7F,58,EA,A7,81,1B,D9,82,D4,2C,40,A2,62,DB,15,27,F8,7D,90,76,E5,9C,B9,D0,00,C0,75,09,69,B4,9D,CE,C4,8E,30,BA,4C,E7,AD,28,0F,67,65,4F,4C,19,62,81,DC,DA,C7,23,B6,10,D2,AF,C6,62,E6,F7,EE,57,E2,08,A6,F8,8E,7A,A7,AA,FA,43,5F,D1,DF,0F,AF,55,2A,91,F9,0E,C2,8C,09,33,8B,FF,F2,DF,01,05,50,86,B5,AD,D4,9D,81,A6,41,47,51,C5,5A,4C,31,DF,59,5E,0B,A2,51,E7,20,ED,5B,A1,2A,72,C2,98,E6,41,2B,A2,15,A7,6E,5E,40,2E,79,68,E7,9B,97,BB,EE,09,BB,70,EF,66,FA,F7,12,A2,A4,F2,3C,C4,24,86,3C,1D,DD,21,FB,5D,36,4A,A8,1A,FC,4C,18,F0,32,11,EF,48,00,46,65,25,18,19,D6,54,DF,4E,11,84,65,B6,B2,C4,14,5B,A4,11,E3,F8,66,7D,18,1F,52,23,01,F6,50,5A,D1,62,FC,C6,BC,91,1A,1E,6A,2D,CA,EA,B8,89,0F,C1,87,76,B4,51,A2,75,7A,BB,02,30,02,5B,22,CE,32,C8,DD,DC,E6,D1,48,76,E7,39,05,C7,79,AC,D2,CE,DC,94,BA,41,A2,B1,94,2F,2B,04,9D,37,7A,D6,84,C9,11,BB,5F,DA,BF,4E,B3,02,A8,85,6E,1B,9A,D1,CF,83,C2,FE,96,7A,D1,35,8A,08,E7,BD,94,72,BC,FA,77,1A,5E,D0,3A,80,01,09,0B,A1,B5,3B,E7,F3,4B,1C,D0,B3,73,AF,47,3C,9A,C5,4F,CC,DB,F7,BE,E1,1A,74,82,89,09,EE,07,89,72,7A,77,3E,32,A4,8E,33,A3,32,43,31,20,B1,DC,21,F9,DC,3F,69,B8,08,6C,7E,45,A3,04,5B,CB,E4,EE,E1,6E,6A,E3,17,D5,A4,47,88,76,BD,7E,8C,E7,3C,09,D1,6C,90,4C,AF,40,1F,DF,4B,B1,CD,D7,FB,FF,EC,54,D1,A7,EF,C9,80,1C,E1,37,D5,C7,B8,C7,BD,0C,67,28,AC,BB,FA,9E,94,BA,53,3D,5D,8F,57,3A,E3,57,CC,45,FF,05,40,EF,FB,82,DE,E2,0C,A6,5E,90,06,00,FB,60,E1,11,B7,6E,78,96,EF,A6,7C,19,9B,3A,BF,F4,DA,C5,DF,0B,F2,BC,6B,3D,3A,CC,0D,23,B9,12,DF,65,7A,03,EE,BD,00,D6,4C,EB,9A,E2,4E,79,C6,08,06,E5,56,04,62,DA,8F,A9,94,EF,71,1A,B1,2C,5D,F6,75,9E,A9,13,E3,E3,B2,0B,C0,F2,90,C8,80,16,C3,8B,72,2C,D9,40,3F,B4,B0,9F,35,F6,E7,83,B0,FD,4E,7E,BA,3E,9D,39,2C,EC,DF,19,34,44,DB,10,99,B4,93,A1,AC,32,97,DC,92,9D,2C,67,C5,D3,21,9D,1E,BB,BE,6A,7E,98,5F,A1,89,03,09,D1,3A,31,0A,55,1D,12,8C,7D,AB,B3,38,ED,2F,2F,98,1E,B2,47,89,A2,E6,C7,9D,81,5F,E6,8A,D2,DB,3E,F0,7D,BB,08,FE,01,CC,C4,74,8D,DB,26,DD,F6,3C,9C,83,6F,FC,A9,0F,59,69,88,DF,63,38,CD,4E,66,CA,25,E3,10,B2,DA,97,98,88,A1,D7,81,3C,F4,D0,3E,07,18,74,0A,7D,EF,AD,B5,A3,92,29,1F,0E,1F,3D,6C,EE,0E,22,E2,73,0D,FB,D6,C1,C1,0F,15,01,22,2C,7A,AF,D0,D9,40,5C,00,A5,F7,BA,7D,01,3A,7C,B8,DF,59,EC,4E,FE,37,0E,E6,B5,58,09,61,BF,AD,3F,72,A4,C5,74,DC,D6,C5,41,4A,EF,22,0D,75,BC,62,9F,E7,CE,4F,E1,62,65,C0,01,B3,36,F3,3F,A4,81,20,0C,4F,21,67,B1,B5,83,A8,C3,AB,82,89,82,70,9C,14,E2,42,96,1E,5C,4D,82,C5,45,30,0F,01,FD,4A,C0,01,3F,38,F2,1E,23,14,D6,FE,78,B2,CB,5B,39,70,C1,AE,34,39,38,87,0F,FE,80,B4,8F,6E,F7,9F,C8,3B,37,04,E8,33,7A,48,CD,04,64,38,25,48,E9,0D,60,5D,8D,5F,78,BE,84,6B,44,07,76,24,50,11,85,E5,FF,0D,82,5A,BC,11,9B,6C,F6,6C,33,88,57,0C,7D,EF,21,33,4A,E2,F0,AA,50,24,B7,E3,37,5A,F8,3F,BB,36,2E,CB,9A,EF,1F,EE,41,32,0A,46,43,17,C5,D8,BF,05,6E,64,26,99,51,4F,3A,C2,8B,08,2F,4C,EC,A5,4A,80,C8,2A,C2,3C,66,A9,EC,AC,43,D1,D8,C7,60,83,D9,53,E7,2F,24,CB,E8,67,B8,8B,28,D0,B3,7A,F3,16,1C,F7,EF,30,5F,B9,C8,25,89,C0,C6,09,DA,C4,5B,48,9E,64,12,5F,4A,98,4F,09,23,6F,CE,D0,AB,8E,F0,67,54,C2,5B,32,26,AC,11,B7,DE,21,25,55,25,22,0C,0D,04,77,16,AA,75,A9,7D,43,44,3C,EF,CC,11,22,4B,56,34,7D,9E,7A,D3,4C,7F,67,E8,5C,18,AB,10,69,8C,E5,DF,43,1F,89,8A,AE,9A,7B,7C,6B,68,A8,F0,45,F1,6A,B4,2C,3A,6D,9A,32,EC,3D,7F,D3,83,13,CF,3D,A9,E7,8B,58,38,1B,2D,13,DB,24,BC,89,76,B9,ED,AE,C5,C4,88,4C,31,3F,FD,3A,6C,8F,91,88,03,EB,BF,29,15,E8,9F,09,1C,73,98,36,39,50,7A,BB,B8,E4,F5,6A,F9,85,5E,DB,6D,D0,90,C6,07,4D,CF,88,93,CA,C4,D6,DA,ED,19,1B,0B,02,98,4B,12,D5,1E,3F,44,8C,4A,CB,A1,8D,AC,A1,E0,3D,69,1D,22,4B,23,C2,C2,D4,01,2F,9F,C1,F4,A4,F6,9E,0C,64,84,61,67,03,0D,64,0C,96,1E,FA,21,75,66,D9,3A,81,3B,3B,26,9F,71,6D,46,34,66,B5,81,10,F0,C3,40,72,53,79,51,5B,8F,89,85,A3,E9,DC,5C,59,A8,0A,DF,53,8C,A7,94,E8,95,5F,09,D8,1A,D6,F5,6F,CE,8B,C1,E7,94,33,FC,F0,68,2D,4F,00,85,84,8C,36,36,BD,FD,E2,32,39,E1,1B,B6,E5,04,88,AC,FA,67,F9,AA,F0,B6,49,B6,90,08,93,C4,77,5C,B0,8E,B3,38,03,03,E7,F8,AB,31,66,81,E8,15,20,A1,8B,8C,35,97,90,81,1A,00,69,1F,30,34,AF,F7,17,BC,64,9B,4A,F4,3A,34,D5,23,1E,85,A2,48,72,AA,53,90,AF,92,7F,96,17,84,00,A4,CB,81,CC,EA,5E,35,24,07,4C,20,18,68,8C,06,E5,67,24,92,45,86,C1,34,61,B2,01,9C,C4,BA,04,0A,69,DB,60,16,5F,AA,34,3D,91,C2,B9,7C,B8,F3,B3,A6,8B,0D,0D,BA,04,FF,9D,2F,38,D9,47,B1,28,43,74,5A,81,B5,5E,06,46,6C,2C,5F,38,6E,44,C3,1F,D7,B4,A3,F3,80,F5,0B,46,CF,38,64,62,38,58,5C,42,1F,F0,E3,57,51,D3,9C,26,52,E6,C6,E3,7D,A7,92,A7,30,23,C3,D6,BF,D9,4B,28,32,95,0E,91,3C,71,84,67,03,AC,78,22,E0,CF,D8,23,3E,CC,3F,A1,CC,23,D4,01,EE,ED,DA,B5,F9,81,27,5D,D4,94,57,BD,A3,1B,50,2A,D5,BC,1C,75,D8,37,99,3A,F9,EF,3E,5F,8B,B0,F5,FD,18,B8,09,C0,1A,95,53,F2,32,2E,F0,4B,5C,A5,15,45,42,16,B1,F8,F2,62,D9,E7,DE,73,F8,70,EE,44,06,EA,77,2C,6D,12,1C,21,D7,8D,79,03,56,D8,EC,30,1C,85,97,43,C3,38,14,47,36,EF,15,56,C3,53,46,0C,18,3F,23,8D,75,53,C4,BF,13,58,E3,29,E4,D5,7F,C3,64,CB,08,4C,77,00,9B,B4,AE,16,5F,CD,CB,73,A5,7B,85,B8,52,90,C7,CB,2C,E4,0D,D4,C4,84,C4,28,D4,8B,D8,CA,F9,A5,A7,4F,A2,F7,0F,B2,C2,C6,F8,1D,04,6C,04,49,3A,EB,64,77,67,72,64,61,96,48,EE,19,4E,1A,FE,60,96,43,DB,5E,AE,16,66,28,CA,E3,5D,7F,14,3B,A9,68,F8,61,DD,8B,9E,55,EE,CC,46,3F,BA,D2,D5,35,63,C3,9E,B0,86,54,23,E7,99,D1,6D,E0,2B,C2,97,36,DD,03,58,10,48,8D,93,EC,49,50,98,6B,C3,0A,CE,8F,DD,D2,09,CB,74,CB,54,96,46,78,6D,D0,9B,17,FD,66,2A,35,4A,C7,52,67,93,C0,7C,B2,9B,68,D7,F1,D2,87,20,A2,8D,03,13,AA,A0,EE,CF,ED,4C,96,CB,A7,CC,91,63,09,E5,6A,F2,BA,2E,24,7B,AD,FC,0B,0B,DE,77,01,4F,30,F7,48,96,FC,5A,4B,7A,C2,10,EE,B3,6C,EB,7A,28,59,6E,61,00,99,1B,BC,C1,C4,E1,8C,E3,CE,90,4D,82,10,F7,C3,4C,48,0C,5F,91,CE,D3,7D,1C,3F,0A,0C,24,A2,50,30,7C,19,94,54,74,A0,51,AA,24,FB,30,87,25,5A,43,A1,42,EF,D3,07,E1,DF,4F,20,EB,B4,F4,B3,7E,17,B1,DB,55,4A,52,5C,52,9A,7A,C8,1C,E3,B1,60,E6,9B,FA,BF,B6,D7,B7,C9,62,27,FF,AA,6B,1C,83,9B,08,35,AB,37,9B,27,0D,F5,78,21,4F,70,2E,E7,AC,71,B9,2B,F9,D5,50,2F,05,54,E4,5B,C5,A5,84,86,10,79,02,7B,82,DB,55,19,28,2A,AD,B1,AD,77,51,1A,A5,0E,EA,FE,6D,C1,E2,44,19,12,C6,79,85,8F,63,AD,CE,C9,44,B8,19,56,AC,19,E0,58,4A,A3,70,5E,65,37,0E,99,33,51,D1,79,BB,75,E4,22,B7,36,45,C9,49,B0,DA,E3,66,A6,F8,58,AB,24,6B,21,1F,04,BB,0D,E6,D8,97,06,3D,A1,E5,7E,97,39,80,86,BF,1D,FB,20,09,ED,8C,AD,0B,05,6B,99,47,1E,0C,1E,87,05,2B,29,1B,51,98,B3,D0,38,90,4C,37,74,9E,79,DA,45,25,BA,61,F3,95,37,16,22,94,0A,66,CB,28,5B,96,C6,A4,1B,47,7D,FF,EB,85,20,C0,7F,DB,04,85,94,2D,2A,B2,B3,6F,F1,75,6A,E0,E3,D9,92,72,65,DE,C3,09,98,DE,2E,1B,53,AE,C1,7F,22,7A,7D,1C,D1,1E,E9,BF,0E,A1,39,6F,3C,BD,8C,AC,45,05,01,CD,62,6B,D2,03,88,91,E7,2D,43,31,78,5D,A9,32,3C,B0,E7,22,AA,01,F9,5A,85,67,67,CD,93,2E,A1,C4,7D,9F,E4,D9,33,0D,24,5B,15,44,C1,E4,DF,C0,18,EB,12,DC,6D,A6,6B,FD,13,84,AF,1A,B7,74,32,F8,18,9A,3C,29,B6,3C,04,4D,B2,8C,4D,28,E6,A4,3C,45,C4,E8,1C,46,EE,2A,BC,BF,2C,CF,3B,56,D8,99,89,2B,82,F5,F6,4A,75,E7,F9,CE,99,74,4A,F0,02,78,2C,85,79,4B,8D,74,0D,71,0C,46,F1,E8,4B,75,31,21,5C,E7,73,13,20,CA,3F,76,99,02,41,21,37,F5,1A,5F,90,69,5A,CB,C1,A0,A2,D9,9B,34,40,8F,CB,46,A9,C7,DE,F1,4B,07,0F,6B,88,00,89,ED,1A,17,6D,D6,BF,CC,70,A2,44,5D,2A,C6,43,CF,AA,BC,71,7E,EA,6F,45,C1,DE,7B,9B,1D,6F,DC,4C,EF,F5,15,61,76,DA,F7,CB,3E,74,CD,10,39,7D,EC,71,AF,81,EC,58,62,15,07,60,5E,AB,9D,7B,49,A0,04,EC,25,BA,84,F1,90,6A,06,82,0B,03,04,F6,84,9B,9B,A7,78,07,B5,C0,E5,82,C9,D7,B9,7A,2F,00,A5,19,36,40,E1,EE,96,8C,69,F2,42,5C,7E,C3,AB,B3,43,90,A8,67,33,66,ED,03,15,89,82,63,EC,36,30,D1,D4,5B,7B,C7,4B,37,59,CA,56,6A,44,CE,D8,99,6F,09,61,D2,DB,61,42,5B,36,EF,83,7D,01,71,1C,6D,21,95,1C,F6,C6,D1,5E,C5,55,EA,EA,B5,3B,F3,3C,5A,83,3B,50,61,5F,7A,C3,AF,C3,19,34,7F,97,4F,90,64,42,0A,E7,15,8D,75,71,58,AB,D7,6C,5A,68,C8,78,F6,F8,1D,97,C0,6E,AC,8A,B6,99,09,87,FE,92,29,64,09,9C,D8,F5,C1,86,ED,AA,54,4D,59,BF,92,F6,E9,1F,CD,54,69,4C,4D,81,34,A3,8A,3F,34,F4,2B,C8,39,B9,CE,90,BB,C5,46,DA,84,53,0F,97,4C,76,41,3C,DA,C2,44,CF,62,C3,03,1F,9C,4F,F8,57,3E,C0,BD,DB,8C,9C,DA,2C,80,AB,D8,B5,69,1C,0C,E5,C4,B5,56,97,8B,95,AC,AD,80,16,A8,24,A2,28,0E,6F,32,86,DC,4D,6A,79,E9,03,7D,63,ED,B1,9E,4B,9D,BA,D7,B5,13,E0,25,9E,FF,29,B4,17,6E,DE,DB,2B,3C,54,0A,CB,4C,89,20,8E,BC,67,65,25,B4,EC,19,18,DE,A6,FA,A7,E8,9D,D9,E0,34,B3,45,A7,3C,FA,CD,2E,CA,D7,76,98,63,9E,5E,C5,69,FA,71,59,0B,B3,E4,07,FA,F5,89,B6,AC,26,1F,9E,E2,3B,A8,19,79,0F,CB,1D,AC,C0,13,B6,29,7E,F6,E8,EC,A3,1E,B2,15,97,91,56,A9,79,EC,F4,3C,82,5B,12,B1,CB,31,FA,B7,AE,DC,19,5A,24,91,E0,2F,63,86,C6,DE,B0,DA,42,BB,75,AF,81,AA,38,D4,2F,E5,B4,05,F6,E5,96,B3,85,85,49,9D,71,64,56,5A,A8,AA,D6,46,F4,21,21,6C,0A,19,AF,E3,78,85,BD,1F,3F,17,85,B0,F9,8D,C4,2F,91,BD,C7,D1,C5,8E,D6,74,E1,1E,69,F2,01,D9,DD,B7,9F,62,DE,9B,A3,E1,87,0B,73,6D,96,5A,95,AB,F5,52,9F,18,B9,B1,71,3D,38,9E,9E,48,97,F8,DF,54,C8,2B,F9,FE,05,50,55,B9,87,6E,0F,54,99,6C,F4,8D,9D,3D,0E,99,4F,A0,3C,CD,0E,5D,0C,C5,85,CA,31,1C,74,3F,22,2B,38,33,2C,F9,1D,8A,9F,DA,31,5A,BC,36,85,0A,65,EB,73,50,EE,27,0E,4D,FA,FF,D0,37,FE,C4,70,9A,AF,29,9E,2B,19,B1,61,CF,A5,31,AC,3D,70,87,2A,EE,F3,99,4C,6F,F8,17,A8,0E,0F,B5,75,01,6F,99,38,5E,87,EE,89,E1,7E,04,70,87,8F,C7,B6,67,A0,C4,D7,F9,66,D3,2F,B8,63,23,F9,C7,89,4B,B6,0B,A0,69,97,2C,5D,5D,EA,6F,06,24,27,47,4A,29,E8,CD,19,76,76,44,D8,F6,1C,93,68,5B,B3,D6,99,4B,A5,FC,9C,B1,9E,59,1D,D5,9B,07,B8,58,ED,0E,AB,41,0B,15,E1,01,87,35,2C,7C,2A,DE,E1,9D,D4,59,28,30,1F,19,5B,7B,1E,E5,39,97,E4,3C,19,E3,EC,FE,A6,0F,CA,A3,43,CB,A1,1D,D4,CC,08,DA,A9,57,61,B1,F1,E2,71,85,37,AD,9C,4E,D4,42,D3,7C,8E,45,37,85,70,B0,36,DF,C2,BE,35,87,1F,A8,FB,CD,85,A6,3C,9E,DE,08,1A,6E,42,C4,7F,C3,66,80,9A,36,99,1D,E0,24,0B,BF,69,67,61,4A,85,20,C3,B9,A6,81,6B,54,54,44,29,3F,67,A5,E1,6D,98,3E,68,4B,FF,0A,AD,FD,A5,41,B4,19,F9,23,B5,28,3F,59,B3,43,85,1A,7D,A0,B6,B9,1C,78,7F,1A,62,47,96,08,BD,DA,72,5A,41,B1,12,85,7C,C8,96,2C,E7,15,4B,F6,AC,1B,4B,3D,F8,18,EB,66,FB,8A,63,4A,EF,CE,1C,B5,DA,D7,E1,CE,47,F3,E6,B6,4C,A0,EA,88,4D,32,86,9E,F8,0A,C0,A9,6D,C6,BB,E8,3D,60,99,20,A7,A0,E1,06,80,39,0E,D2,9B,8C,1D,07,30,44,6B,88,DB,2F,9A,1D,0B,44,9E,AB,9D,27,A5,9B,40,FB,90,01,63,0B,09,0E,EC,2E,55,95,63,EE,BA,FD,54,CE,BA,78,BD,60,73,A3,23,65,6C,9D,13,3C,FE,93,EF,58,44,E5,45,12,69,7B,22,92,E9,24,3A,4E,61,EF,96,09,7C,26,40,AA,21,D8,01,73,99,A9,2F,D6,7A,95,49,59,75,94,85,3C,BA,9E,05,50,98,73,DF,01,4A,95,A9,0C,18,83,34,4B,36,2C,AE,6E,CA,59,18,9C,EF,0B,D3,7C,21,C6,CB,13,35,58,78,DF,26,74,A4,76,65,4A,10,D0,ED,34,B7,72,1C,07,77,E3,F4,AE,98,8C,AB,DF,78,07,23,CB,3C,A0,60,B5,60,F8,2E,4F,56,0D,42,A9,5C,AC,69,AF,BC,A0,5D,9D,E5,EB,12,C9,9A,44,34,D2,05,72,CD,DF,CD,E0,64,C1,45,DB,98,31,7B,BB,41,DC,35,45,76,2D,2A,BC,0F,27,13,1F,27,5A,A8,34,83,B5,B1,E9,86,2F,B1,D5,72,61,C0,3F,51,63,F2,D3,9C,19,87,CD,97,8D,9C,C4,38,8E,A5,41,2B,30,A3,12,81,4D,7E,26,45,D4,41,5D,67,03,FC,14,86,46,AC,13,A0,5D,E8,1D,34,7F,EA,B1,AF,35,3C,F1,B1,BD,FD,39,7C,8D,21,99,DE,88,28,AB,2E,18,90,C1,D3,5C,2F,7A,D4,81,19,8C,82,BB,A8,58,55,7F,B8,FF,99,D4,5E,DE,E1,DD,F1,D8,E4,7C,2A,5D,72,DF,4B,0C,F7,DA,BE,B6,D0,C8,4F,66,C0,CE,60,FF,41,1B,F3,72,22,CE,2E,08,04,8B,BF,64,36,AC,3E,E9,A3,F8,32,3D,E1,31,07,EF,AA,4F,F7,BA,3E,DF,46,05,F0,3E,35,02,89,6E,A7,52,30,E2,9F,2D,E5,8C,3C,01,B7,0F,CD,CE,F2,1C,EA,ED,A9,D5,CC,F8,F6,8A,84,B2,FA,C2,F6,04,16,6D,E4,D9,71,DA,E3,C3,43,45,FD,64,F5,E4,CE,4F,07,4A,9E,95,C0,97,B5,C0,32,A5,C0,63,25,5B,B7,B8,68,D5,6C,7D,DF,70,B7,13,F3,AD,9D,73,12,6A,C5,D8,7E,FA,E5,B0,F5,9F,93,D9,8B,A8,61,4D,AD,D4,E6,43,B0,97,1F,1D,95,9D,29,2F,02,6F,9D,EF,75,57,BF,B2,2D,79,69,BD,55,31,21,44,1A,2E,C0,E8,70,72,A0,DE,B8,72,A8,AE,BA,AC,38,30,31,0F,DC,7F,B8,66,40,42,2E,72,8B,D0,E2,28,C3,D8,B3,53,87,2A,6E,D7,71,5B,10,44,50,8A,8F,2A,FB,85,5E,5E,27,7D,A0,AF,01,7C,E8,5D,A6,20,25,C3,7D,16,AD,9A,42,6A,66,65,01,25,F5,3C,26,94,F7,45,A7,60,9D,59,93,BF,A8,5E,64,34,A3,A0,B9,F9,2C,13,A3,54,D3,CF,E5,28,5E,BF,D0,DE,F7,14,14,61,C3,7A,0B,99,90,E7,EE,E9,46,A1,E9,6B,32,FC,91,2F,DF,01,64,0F,B8,1B,7C,62,92,79,57,7D,96,64,8F,30,A3,0B,91,41,65,AA,73,2F,03,7C,C1,44,EE,A4,DD,6F,DC,03,A2,B0,87,DD,72,37,E7,D1,BE,DA,62,48,1C,8F,20,C6,68,FB,1F,40,28,6C,8A,8F,38,A0,F4,40,47,0A,04,1A,8B,B0,6D,F7,34,6F,6A,43,49,DD,C9,D7,FE,20,CA,55,A5,B7,CB,D4,AB,20,0F,E2,4D,85,F5,0F,11,FE,01,AD,D3,57,E7,95,D6,9F,B3,38,D7,C5,34,14,8E,B3,21,BB,1B,84,7C,03,B0,42,8F,40,4D,84,D3,AB,62,1E,4E,0C,50,B3,8C,E7,91,44,74,67,AB,CF,4B,C8,D5,1B,EE,84,C7,45,3C,60,A3,03,C8,7D,F2,A9,04,52,6D,20,F7,D7,A2,ED,7A,3E,F1,A8,FC,77,E7,8E,D9,E2,64,54,22,00,DC,20,FF,03,9C,87,65,5F,F1,85,03,B5,FC,79,96,9F,65,4C,C3,98,7C,71,73,DD,1A,7E,E5,01,7D,1B,A8,08,81,2B,24,49,E1,D7,33,D1,50,A3,62,B7,B8,C0,E7,8E,50,33,B6,FC,D6,47,63,FB,2D,06,9C,A0,BF,2B,1B,16,9C,7A,E3,F0,2A,00,54,76,49,F8,11,3C,B0,F6,CF,C3,00,7F,7F,24,65,F7,8C,0A,87,CA,67,AA,17,94,DC,4E,37,8D,C8,2D,BF,28,D6,CF,EB,84,DB,5C,46,A1,8B,20,5C,1B,97,9C,D2,F8,A2,8D,61,95,E6,4B,24,39,3F,5E,35,5B,A4,86,35,E2,B2,61,79,68,21,9D,AD,10,7E,12,86,A1,8C,56,D6,9A,35,55,46,EA,39,6E,CA,82,CC,D4,D5,36,34,CB,9C,AB,BF,45,3E,C5,C9,EB,BE,92,83,52,8A,66,76,A6,C1,85,F3,65,18,A0,2D,C9,6F,99,35,14,C6,EB,B4,FD,C8,84,73,AE,C7,6C,1C,D4,F2,E6,A4,0C,0D,F9,1F,06,E5,56,E6,0D,8B,80,10,E0,11,2C,00,A3,EE,75,4F,6E,15,0D,A7,A7,B6,B0,92,B9,E0,68,1C,81,2B,4D,C6,8B,E7,AE,D2,B0,2C,54,3D,C5,66,0B,12,04,29,C4,DC,43,DA,2A,1F,AF,41,56,A7,18,C2,3C,7A,F3,8E,B6,02,71,4F,79,DC,83,41,46,AC,7D,E6,6C,8F,B0,0B,50,33,F0,5E,17,1E,86,0B,41,C9,E7,FD,78,E2,88,D4,71,27,B8,61,2E,09,DF,BA,F9,CE,22,5D,E5,C4,78,41,9C,28,16,72,9A,E3,91,11,11,15,0D,9C,00,E2,43,CB,C4,8C,0A,6E,D1,8F,B9,78,66,74,49,8B,17,85,61,3F,CA,D0,DB,57,32,94,1A,1C,AD,3C,31,0F,28,FF,E6,1A,90,C1,8F,79,87,42,60,7D,8F,84,C7,34,85,5C,B7,60,94,B9,03,F7,DD,42,82,37,46,26,3B,37,1E,D8,01,AA,E0,BD,FE,E0,3E,2E,F6,62,8A,BB,8A,F0,74,D8,99,CD,2F,C8,74,6C,36,7D,C7,E1,56,12,BC,21,2A,0B,66,4A,AF,53,B1,93,99,16,77,9B,5C,42,EE,57,71,BB,A8,D1,F9,66,77,56,3D,30,FF,3F,9C,13,1F,33,24,D8,37,BB,EF,58,22,22,F3,9A,4D,D7,BB,FB,94,9D,D9,C1,DA,54,70,1C,A8,0A,1F,A1,78,88,C0,5F,E0,57,C1,B4,57,92,4B,D6,18,DF,0A,15,BA,B4,31,87,05,60,63,D4,50,46,DA,2C,EE,7E,3C,54,64,D4,79,D0,A9,A8,83,77,C6,91,36,16,23,CC,2F,C4,31,B4,60,AD,1B,19,4B,D6,4C,45,60,91,76,D1,F3,9C,15,A7,BC,4D,54,74,8A,00,F2,0D,3A,2D,23,86,B7,2D,8E,8C,48,64,DA,F3,73,63,46,7D,07,3C,E4,FD,10,A7,66,E1,D1,14,C3,7D,B2,C9,D0,35,4A,9F,06,A0,71,A0,22,6A,D8,6A,EE,3C,A0,E0,C9,D7,1B,20,76,E6,86,46,56,DD,5B,3E,60,A7,9C,47,CF,47,42,8D,2C,67,95,B6,4C,F5,D5,9C,A6,73,1C,34,97,B5,E4,61,12,83,A5,72,0F,92,9C,9B,70,A7,18,7E,B0,39,E6,D8,54,27,3E,89,40,E3,A3,EF,64,CA,50,87,4E,58,6B,17,A6,C2,11,90,36,D8,42,6B,2D,EF,3F,F7,B7,20,48,5D,D2,65,CB,D5,BC,6F,65,3D,EA,AE,39,47,13,3D,04,EA,E8,69,E1,4A,0C,38,82,A8,9B,9A,9D,F7,33,02,70,EC,84,24,28,B0,DA,AC,A8,18,20,C9,C8,90,0C,06,AD,03,C7,42,1D,AC,0A,24,88,79,6D,B2,F2,D2,5E,4B,80,BE,1E,A4,89,25,AC,77,7A,B4,4C,BF,FD,EC,5B,77,10,A6,09,A3,52,E5,3E,67,5D,CA,D6,6E,44,5C,CE,83,AD,24,4F,F9,D2,69,65,AE,DC,26,6F,D6,19,C7,16,82,01,8D,37,4B,1A,96,3F,0C,2F,F2,4C,9E,40,D2,7D,83,64,8D,22,FF,97,EC,6B,A3,62,97,E5,B6,65,51,54,B0,FB,C3,7B,DD,23,86,7B,87,93,6A,A4,17,74,AB,BA,5D,FD,F1,5F,29,E9,F6,26,6F,60,5C,3B,B2,D1,28,EC,87,D6,11,7C,CE,3E,BF,B9,23,D9,E6,F3,CE,7F,A4,02,A9,A5,24,AF,C8,D5,79,1F,D7,1E,23,DD,E6,81,3D,A1,30,73,FF,4C,2B,BE,6C,F9,85,AC,38,96,74,35,45,09,48,25,A5,E9,1E,35,21,DC,9C,10,62,CD,77,98,56,3C,D7,8B,40,9C,EA,6A,DB,04,63,D4,E4,39,51,D3,D6,53,02,44,9C,2A,50,9F,DA,39,96,1D,FB,8D,1E,3B,B8,E8,68,E7,A5,73,2B,27,2F,B1,77,F8,6D,31,CC,2A,DC,31,54,9B,75,5B,4F,2C,C9,BE,F8,6D,C7,70,7D,1D,51,DF,C0,CB,95,6F,7D,8E,86,3A,28,0B,86,F6,45,3D,FA,10,04,4D,EE,05,BA,EB,E5,94,95,00,BE,A5,CB,B5,85,F9,A4,D1,1F,75,9D,1A,24,60,83,1A,10,F0,56,B7,FE,DA,88,D8,CA,B2,86,54,D2,52,49,AC,5B,79,A9,28,F0,54,6B,8A,23,A9,7C,F1,8A,A1,76,27,EE,B5,4F,56,0E,73,76,9D,2A,1C,0F,E2,55,9E,27,D9,EA,95,5F,4E,F2,5A,DA,F4,F6,FC,62,25,47,CB,21,EA,D8,E8,D5,1B,E2,BB,F0,87,F8,57,95,9A,AD,F5,BC,65,23,99,F4,B4,E4,16,5E,AF,19,97,20,AE,47,BB,91,0C,DA,72,8E,F3,0C,F3,84,26,31,89,41,11,A6,A0,EB,86,FC,52,58,B9,DD,1C,29,54,FB,B6,99,13,24,25,1F,B5,E0,B5,7C,7E,53,A0,0C,9A,30,E5,4C,73,C0,26,7B,47,3E,89,5A,0E,4B,48,58,74,2B,F0,ED,D6,47,37,28,FF,31,36,FF,FF,7C,14,2A,F7,C4,FD,CA,5D,9D,88,9A,E3,A0,2F,E5,22,36,30,0E,41,9B,35,34,58,56,44,D7,8B,06,34,89,31,70,80,0A,E7,26,B0,7D,06,2B,B8,80,34,24,C6,8B,31,5E,09,C5,5B,F0,58,CE,8F,68,DB,5E,21,2A,E0,65,DF,F0,51,C6,B4,83,CA,7C,AA,DA,F5,79,0C,10,77,B5,4E,0C,3D,26,63,53,67,32,3D,96,7B,14,8F,55,AC,19,FF,E2,64,49,CC,EA,50,38,9D,AD,D3,FD,4C,9A,C9,42,57,03,29,B1,3F,5A,32,8C,B2,26,F0,A7,F7,19,CE,79,01,CC,81,9E,58,0C,54,1D,9A,48,70,86,A5,80,BA,F5,91,E2,9B,FE,D7,DC,0C,F7,B9,85,A4,80,86,C6,FF,D2,2F,F9,F5,02,6C,40,1E,5E,20,FD,95,DF,F5,6D,24,E7,1D,A1,01,C8,41,CA,1E,94,C9,AC,E1,8E,B5,4B,42,56,0B,7C,DE,7F,AB,05,C9,6C,EA,45,36,3F,35,3C,60,6C,DE,38,37,7C,36,C0,D4,0F,5C,BB,9B,0F,0C,7C,E6,ED,FB,46,88,2B,19,F8,5D,3E,7F,9B,CC,9B,29,32,59,9B,FC,14,C4,89,B2,9E,7B,9B,C5,59,37,9B,96,41,26,1B,B9,DD,8F,37,F9,D2,61,B1,D4,69,09,45,BF,A5,FA,7C,4A,B8,9E,A8,3B,54,95,B6,FB,00,3D,75,D1,9E,E4,2B,EB,22,8B,1A,96,8D,00,26,B2,E0,93,5D,EE,D8,EF,86,0D,08,D5,00,74,6F,24,CC,AB,01,19,7B,EC,72,F7,F4,73,5C,E1,E5,0F,D8,1B,DA,EF,C7,19,60,62,AB,12,D2,81,EF,5A,6B,F3,98,01,F8,FD,4D,F0,E4,99,A5,25,EF,58,7E,45,03,47,82,CE,DF,53,C6,80,AB,D4,DB,9C,F1,CC,DD,46,81,58,73,F8,E7,19,88,7A,27,46,49,59,05,EA,0C,E8,73,83,6F,1B,9B,67,D4,DD,0C,2B,8E,53,24,00,C0,BF,FC,F4,AE,80,F0,D1,79,07,CD,DA,3D,4B,D9,C6,AF,D6,ED,85,F3,8A,FF,7C,B8,F2,3C,33,66,4B,50,2B,CC,81,D2,09,E4,E6,1D,C7,65,02,D2,F3,4E,A3,46,10,72,AC,5E,A0,A5,7B,84,16,9D,14,DC,E7,55,14,13,23,37,24,E3,C9,8E,E5,F5,AF,0A,25,99,02,C7,02,03,ED,7E,F4,70,39,15,28,10,69,CE,E1,4C,DF,34,DA,E3,4C,E2,1B,5D,3E,19,C2,9B,49,7B,62,4E,D8,AF,06,DF,EB,3A,AF,D2,35,1B,9B,80,86,42,49,AE,41,C3,67,00,19,BE,41,C6,8D,09,8A,D3,BC,F4,18,53,2D,8B,5E,39,1F,2E,18,33,CB,E7,6B,44,CC,D2,96,A6,59,1E,E7,83,AE,E1,90,0F,03,81,B9,BD,42,34,32,D1,59,9D,42,5A,A1,20,7B,8A,E6,48,A6,D4,49,D2,E9,CE,80,E4,62,3D,84,53,8E,25,52,98,48,6E,D2,AF,F6,BA,3C,FD,05,DA,7C,54,FA,AA,1A,75,24,33,0F,74,3F,06,05,8B,93,8D,3D,66,A2,E7,33,39,C0,EA,4E,9B,50,DE,D5,74,17,4A,3A,22,7B,44,5F,DD,48,E5,C4,4E,9C,CA,42,44,C5,9F,3E,B3,84,3D,25,27,65,91,AF,66,D6,D8,81,FA,93,80,2E,46,AC,27,08,94,10,D8,53,ED,67,04,2B,A6,F1,89,93,8A,C2,DE,16,8D,B4,F0,C2,81,50,F2,28,C3,73,2C,26,D7,21,89,86,AC,14,44,1F,C4,1F,26,58,C3,CE,0B,5D,85,0D,FF,82,9F,0A,80,1C,4F,6E,86,DA,6E,DC,C1,3F,F2,E3,67,07,FD,78,44,62,FD,03,73,CD,19,16,A0,B6,D6,0D,0C,DF,9A,C2,9F,9C,C8,75,DF,56,DA,E3,53,F3,22,D7,16,02,70,64,0E,F5,8D,7D,D9,2E,62,CD,F6,86,70,FA,21,D5,07,CB,DC,B8,92,EB,B7,60,B6,A8,B8,4F,F5,4A,52,FB,B4,1B,74,17,76,DE,D4,54,B8,3E,49,6C,40,15,3A,6F,44,FE,C8,BC,DF,87,0F,8D,E5,72,69,64,8A,3C,EF,AA,16,9D,07,D1,41,2C,C7,E7,3E,7F,F3,2A,E8,6E,C7,BF,10,1C,A5,49,89,36,CB,81,06,6B,93,15,66,F8,A4,D4,0B,7E,AC,D0,92,32,12,C0,E3,82,81,C0,EC,5A,45,5A,51,C4,3B,93,CD,D4,9C,A6,30,59,74,86,54,0B,2D,EC,E7,47,0D,48,4D,5F,3F,D7,E8,29,E9,1C,F3,0F,2A,C5,91,0E,CF,78,12,2C,5A,9D,7E,A7,A2,9C,1A,4A,70,CE,E4,7A,05,AC,60,E4,E3,3C,DC,ED,82,C0,35,48,E6,F4,02,11,50,0C,0E,59,5F,25,9C,95,CB,E9,52,AF,6A,BC,D1,48,7C,A1,48,63,8C,AD,5C,A6,16,41,E7,62,BA,47,3A,88,38,75,D5,2E,00,5F,A5,A5,38,DF,F6,9B,1D,45,55,1D,B3,8B,89,D3,0C,D3,AA,8A,CE,5F,8D,D7,CE,0D,77,57,F1,CB,59,10,DB,EC,9E,39,2F,95,DF,43,29,20,E5,70,F5,9E,F4,1B,3D,AA,23,D9,F8,4F,BF,EC,09,F9,B0,0C,F8,74,CB,6D,DB,A2,42,C3,88,15,CF,8D,89,C5,D2,F4,76,F9,4F,81,AD,1B,D0,E7,68,E5,BF,42,A9,35,51,97,E3,3F,04,96,A4,51,59,38,07,D5,60,06,4D,6E,CD,1D,23,4C,EE,C2,D9,B2,97,E6,21,C6,36,F2,5E,F6,0C,09,A2,01,B2,30,B8,7D,70,80,D1,8F,0F,EF,1C,5E,26,72,9F,13,C1,6D,48,3E,6F,56,9E,28,36,34,F5,12,24,75,CD,17,CB,85,BA,01,AE,AD,37,AA,F8,21,39,B5,E9,52,F1,27,B9,00,FB,67,A5,0B,C3,64,0A,5E,C7,04,9D,99,78,F4,A6,0D,B0,8A,1C,5F,B9,4F,83,14,B0,F3,C2,F8,6D,11,F6,F7,65,3E,95,C1,F2,B6,55,13,3D,B6,2E,0C,8E,1E,7E,7C,BB,07,CC,D1,9E,6A,EC,D8,1B,F4,7E,0A,4E,A2,A0,18,33,57,2C,80,60,F8,AB,D1,72,0B,C9,4A,FC,9E,69,E7,C5,F9,87,92,9F,39,E2,2E,03,51,A0,61,AC,BD,08,A2,E7,FB,97,FF,8D,D2,70,35,B2,F6,2B,53,41,76,9F,5B,C5,C1,10,E3,61,25,F8,EC,83,D8,BF,7F,16,E6,B4,EB,9F,C1,EB,DB,8D,80,5B,08,66,41,7D,4A,23,B6,C2,E0,8B,62,EE,3B,F3,E0,99,80,99,90,CC,42,32,4C,31,0B,8C,1F,F3,A3,E6,67,A0,A4,55,CA,C6,C5,5C,26,E8,A0,86,36,28,C0,9A,22,CB,D8,2D,B9,CF,44,67,7F,F5,E9,1A,D0,6D,69,2D,92,70,51,0A,58,2D,F7,4C,F1,15,CB,99,E8,B4,46,57,FE,FE,AB,AD,1A,5F,3D,59,E1,A5,DF,0D,E2,31,F6,96,4A,4A,8F,DD,B6,FC,33,29,63,65,90,BA,7A,14,85,8E,17,3A,6D,72,BA,98,07,A5,3A,4A,6E,E8,DD,54,19,D3,CF,81,41,4E,79,30,A2,F2,CA,9E,FF,21,20,50,A1,0C,88,08,AD,71,D8,19,A7,7B,4B,70,49,20,55,AD,7E,FD,5A,C8,1F,03,D2,EE,7E,EF,D0,DC,4A,28,EA,BA,8C,1E,B6,5A,B9,05,8E,71,BB,3A,06,AC,21,51,36,C2,6D,2D,96,B9,96,F4,53,61,58,E9,46,4C,23,C4,4C,3E,A5,4C,07,80,A7,CF,F4,24,F4,14,4F,20,50,90,73,86,59,D8,67,95,72,CE,6D,76,42,BA,B4,8C,2E,CD,F1,3F,1C,8F,1D,A7,DB,8B,80,22,C8,EA,31,E0,BB,65,08,72,2F,DD,57,F4,93,23,16,D3,7A,FC,A1,FD,8B,FB,8D,3E,1A,86,43,DB,9A,95,00,E8,6D,12,92,ED,E2,D3,D1,61,11,7D,80,09,5D,A9,A0,A2,3B,3B,48,03,5F,CC,5E,F6,4A,7E,35,38,B8,2A,45,53,65,7C,A2,04,1B,C8,6F,87,F3,16,65,31,09,73,18,12,11,F5,1C,74,BB,1A,4C,A2,E8,25,36,18,C1,0F,07,A4,AE,1F,78,98,75,7E,88,9D,5B,D6,52,5B,A4,9B,4C,6E,1E,EF,AC,B5,69,64,FB,CD,B3,BF,6A,1D,77,DB,0E,1F,A6,55,24,66,D6,BF,9C,F2,C0,45,E0,25,B5,78,3A,3A,BF,0B,BA,88,58,9E,1A,8F,5D,CB,23,5E,5F,5D,A3,1E,01,E1,1B,66,3F,04,6E,8C,7B,8F,20,DE,4D,BA,A8,77,9C,4E,FA,CC,63,E2,C6,68,E1,E2,98,85,D9,54,F0,16,DF,26,30,7F,11,D9,9A,CC,09,A9,ED,85,01,33,21,18,02,D7,5B,9A,2D,C6,38,48,8E,05,7E,8C,AB,60,4C,2F,76,82,AC,0E,DE,24,5E,E0,11,8B,73,8A,75,F3,CC,6B,B0,B9,51,C3,75,9F,23,A6,6C,0C,DC,7A,40,97,DE,F2,8D,B5,07,07,E2,F2,02,60,40,7D,74,56,2D,72,5D,C9,7C,64,8E,F9,65,5F,C6,F2,A3,D0,4F,7D,3B,AC,21,F8,7B,E6,8E,5D,E4,5F,A9,1E,B8,F1,53,94,C8,3E,EA,4A,25,D9,12,77,B1,4F,36,CB,80,0F,AE,09,D3,32,04,93,27,E9,E1,76,BC,4F,80,0E,1C,17,47,F3,8E,87,18,24,AA,60,29,86,10,EC,F5,48,F0,44,94,06,CD,46,F8,5C,76,1B,0C,B6,D5,FE,0E,8D,79,66,DA,1C,95,2A,46,A6,EB,B2,14,0A,DD,8B,AB,A5,63,46,01,22,B9,68,E5,EC,8F,33,34,3B,31,D0,B1,B5,48,9F,07,9D,02,E3,15,B7,EB,C6,2F,53,75,46,D9,B2,C2,09,DB,2D,D0,BC,F5,CB,F8,5B,5D,E2,E5,0F,A3,D3,63,76,28,9D,99,BF,E8,5A,CB,7F,76,40,19,05,9E,11,90,0B,3B,E8,23,84,B6,09,2D,BC,9A,A2,11,B6,5B,36,0B,8C,59,DB,FB,6A,C8,A9,A6,65,8A,D4,B8,DA,9E,B3,50,1C,B9,AE,B5,9C,0E,D8,7D,45,A9,EF,B5,B4,26,A3,63,B9,DD,BB,75,F8,75,94,49,4A,2D,E9,64,9B,B0,18,58,C4,5E,4D,A0,61,2A,16,CE,87,E3,B6,B0,EF,7E,00,64,34,30,C1,3C,AA,E2,C8,1F,AE,9D,62,99,63,B3,EB,16,24,FE,15,E1,4A,E0,49,E5,3F,9B,89,FC,40,25,1C,84,24,FF,65,5B,48,C6,C0,CA,2E,73,79,CC,D1,89,E3,33,CD,AE,FF,91,84,4B,18,2D,85,D4,4A,7D,53,06,C3,CB,E8,E5,EC,5E,F5,AC,D9,41,75,6F,DA,65,D8,5C,0E,CE,88,9A,A7,28,B2,E2,9C,F5,AD,BE,57,E9,E1,8A,24,30,08,29,AC,62,09,8E,A6,E1,3C,EC,F6,4B,38,5D,18,FB,2B,76,8F,4F,B6,ED,24,34,4A,52,8A,3A,51,9B,12,5E,0A,FA,87,33,CE,87,90,A1,46,11,BB,62,70,79,3D,90,5E,08,D6,AC,C9,76,AD,59,41,25,E2,27,A5,6E,03,EA,8A,EE,0C,36,23,7C,5A,14,2B,56,4C,FD,B0,D7,96,D7,19,DE,49,7A,61,19,10,3A,0E,1A,FA,43,3E,0A,93,18,4C,3E,6C,C5,C6,76,78,7C,85,7B,68,83,95,5F,98,CF,4C,42,32,89,44,82,C5,49,DC,1E,0D,E5,4E,D7,DE,0A,82,2C,81,B9,4F,FB,02,D7,CC,72,5D,44,7B,F0,04,A3,6E,CF,DD,5D,76,B2,06,A2,C2,31,03,E4,46,33,08,4D,6B,B4,C7,E1,EF,F7,83,E9,09,0A,D1,36,CB,BC,55,3C,B3,CF,F3,CE,95,53,56,61,C5,2E,AB,17,C4,85,5D,7D,33,A5,EA,97,A3,B2,89,C3,D8,79,C0,AE,C8,0C,6A,D7,6B,51,EE,07,C1,F4,05,7B,9B,7B,91,26,50,AD,AE,82,74,14,8D,43,EE,11,34,AD,AE,AD,A1,1F,9E,AB,83,AC,8F,83,DF,D6,DF,6A,50,31,54,70,30,7C,D0,16,BF,14,0E,F7,15,80,F7,C2,C1,C4,D8,88,E7,AB,62,6A,26,D1,CB,1C,73,B6,18,2A,4C,05,CE,3E,F6,24,A0,15,B0,6C,12,26,75,0D,A0,64,00,3D,84,3A,B4,5A,53,1E,02,F4,2B,D0,F2,5B,2B,C0,43,E4,99,BC,D2,AB,B8,AA,F3,A9,3A,F5,73,A7,66,2C,72,CE,E5,7C,EA,04,3D,B2,64,65,93,FD,6F,07,A8,F7,35,51,28,9F,0A,A0,2C,2C,02,A6,81,CC,6D,D6,57,D2,F3,7F,E6,90,81,68,63,6F,2A,76,15,4D,9B,A1,D2,B2,80,0F,FD,75,D6,F7,8B,E5,16,53,FD,30,2E,97,54,81,B2,95,BC,E0,EF,0B,A2,E9,61,44,CC,BA,9F,25,44,6D,3D,C0,9C,FE,D4,F6,00,9A,D2,32,01,78,F1,51,F3,D4,7F,5E,5A,C7,93,91,B8,E8,0B,F7,0C,87,1D,30,4B,29,F1,65,BD,58,10,1E,DE,E2,7F,2F,87,06,B3,40,43,A8,21,C2,52,85,72,C1,3C,64,9B,F2,5A,0E,32,AD,A3,02,5E,21,96,62,A2,E9,68,24,7B,1E,4A,68,74,C2,5A,EA,3A,51,49,C4,56,CA,B8,62,34,E3,0A,C0,A8,E5,1F,DB,C5,0F,D3,62,64,E2,B0,72,75,C7,88,2B,02,53,CF,88,BB,E6,C6,08,46,8F,6C,B3,86,DD,D5,69,57,49,9B,2C,A0,C9,E7,39,37,EA,7E,18,A1,BF,0C,87,11,C6,D2,06,64,E8,A8,AE,92,89,57,A6,13,3B,20,31,7F,27,16,65,12,FD,43,D2,F1,EF,4B,10,EF,31,8D,F2,C4,81,4F,E8,29,EB,FD,87,CC,89,09,B5,B6,17,71,6A,47,4E,7F,5D,30,82,3A,49,D0,36,00,3E,A1,35,CB,5D,9F,2E,18,AC,85,73,22,E6,6A,72,80,84,18,28,3B,4D,24,DF,18,B1,00,72,0D,2D,FF,F8,BD,14,AD,D3,54,D5,40,0F,24,D5,DA,0F,F9,41,3F,8F,84,DB,A0,70,CC,D5,2D,4A,A2,F4,22,A2,D7,33,44,63,1A,96,2C,E3,25,B5,37,3D,52,C2,DA,C9,77,53,5C,B3,19,1E,AF,BE,FD,F0,E3,55,CC,5F,76,5B,D9,8C,AF,06,AE,2C,E7,FE,20,D0,7D,65,30,74,02,78,27,76,FB,0B,75,37,3E,58,88,5D,FB,3C,3F,9E,13,93,AC,53,8F,A3,40,42,F4,29,D4,E7,7A,03,D6,88,DA,C3,7A,D5,22,10,D2,3C,B3,8B,11,46,23,29,AE,52,01,87,82,32,51,EF,A9,94,55,CF,16,ED,1C,7F,32,8F,03,1F,CB,14,1A,9B,56,F4,71,CF,29,58,F5,65,82,C9,08,9E,20,31,FF,BA,C1,DC,8A,B7,1B,90,0C,02,A0,11,22,39,88,57,B2,EF,1E,3D,15,14,71,27,83,07,96,82,D2,E6,CF,F3,73,9E,DB,57,DC,35,76,E9,33,32,C7,2C,80,90,02,69,42,92,73,D8,9F,AC,19,74,69,EF,75,73,4F,C8,7A,CB,79,F0,E5,D0,D9,E8,42,1D,2A,38,52,6B,63,A5,91,F9,52,56,7B,9B,1B,58,90,81,BE,52,28,A2,C2,04,B1,92,9C,40,07,A2,C6,0A,42,95,D4,A4,7E,5E,2C,1C,AC,1F,A9,99,9A,47,27,D9,BE,34,1E,77,D0,03,C9,E7,06,CC,F2,A3,E6,0E,F7,3B,59,8C,5E,C5,FF,34,CB,AE,8A,3F,22,51,13,FE,9F,D5,D4,CA,B9,1F,12,AF,71,08,B0,9D,54,D3,E4,0D,22,7E,CA,2C,88,4F,4A,AC,13,59,F8,E2,EA,23,2E,54,74,45,48,E0,A7,09,B1,39,1D,7A,54,E2,28,12,E8,5F,6E,D2,30,F6,A0,A4,2C,34,B8,42,90,E5,92,F8,DD,8D,8A,06,18,1D,96,99,24,15,01,8E,96,0D,7A,F8,14,93,EC,05,2D,C2,93,A6,2A,86,98,E5,BA,82,49,20,44,DC,75,15,5D,1B,6B,21,59,6C,BC,BF,BC,05,82,4A,36,A0,FE,BA,3B,85,92,0A,EC,DF,C0,4B,F3,82,D3,96,80,81,44,96,2F,E5,4B,13,AE,CF,04,81,0F,B4,41,D5,73,A0,1F,2E,44,C2,6B,71,F3,AC,BA,60,57,E2,E8,3B,8A,D2,45,F0,8B,12,6D,AB,A6,ED,E1,52,F5,9C,CD,74,45,DA,A7,64,3D,50,36,BB,9C,EB,B4,15,72,DF,3A,C7,09,FC,72,45,C1,3C,C4,BE,77,C6,79,7E,69,ED,A1,34,CE,31,FC,FF,03,BB,CE,8A,99,DE,AF,7D,03,02,63,DC,D5,23,A0,ED,C6,D8,C8,64,7C,59,1E,12,18,97,26,5D,E5,87,83,E0,18,28,B3,A8,78,C0,08,3D,28,27,3E,5A,9C,F0,EF,27,EB,0A,8D,D6,22,0D,5B,2E,B0,25,70,5C,8A,EA,80,6C,AA,8F,16,9B,BC,06,2D,05,BD,83,FC,43,D7,F1,00,DC,07,B0,88,80,88,6B,07,CC,C0,B9,40,26,60,AA,46,AF,F6,5A,20,CA,EA,0C,54,E2,EF,44,DA,CF,5A,21,AF,65,D3,79,51,C1,E3,41,3A,01,26,DF,96,C3,35,7D,F9,F4,B1,2A,81,F7,28,91,36,7F,8D,4E,ED,2D,76,A7,28,EA,39,A4,B1,89,DA,24,68,AB,DD,44,CF,78,77,28,08,11,6D,0B,23,84,E0,A7,36,94,92,DE,27,83,5C,14,EA,03,F0,47,26,93,E6,90,6F,26,1B,8B,23,2A,1D,8D,C6,2A,DC,E1,45,CA,21,0E,B7,88,CF,33,73,24,B2,F7,DA,D8,7A,AB,74,6F,61,CD,FB,7F,92,1A,4D,36,50,C2,79,8E,C0,D1,25,32,F6,A6,58,6B,8D,D9,AC,3C,5A,3D,1C,72,0C,33,7D,5C,9E,9D,F1,FD,14,2E,BB,A2,3A,82,7E,1B,37,09,CA,0B,5B,CB,33,EB,E3,28,45,CB,30,98,2F,95,DB,DC,C0,02,92,F6,82,F9,0A,92,89,F7,CD,26,17,47,70,0C,22,6F,D6,3E,0A,26,50,ED,FF,39,89,92,7A,F6,E5,C4,C6,35,E2,5A,D3,E5,AC,DB,28,7A,E3,D4,0C,97,45,10,A0,94,20,68,7D,7F,A8,34,95,AC,7D,EC,95,05,6F,F9,EC,75,01,AB,C8,1A,A3,F5,CD,57,22,1B,8D,D4,18,CA,C1,92,D9,72,3E,58,6C,F1,D8,BA,5F,A3,6E,DF,D6,8F,9A,2E,9A,0D,5E,CB,A4,52,D4,A8,1F,17,D3,74,7D,B1,52,6C,88,29,73,9A,B6,BD,B5,53,99,B6,D7,93,2E,FF,3D,F8,8F,B3,36,F3,11,C4,FB,C2,A3,CC,70,77,9C,E2,CD,31,77,EF,F2,DA,3D,C9,B2,4B,76,9C,84,73,83,C9,01,2D,AB,50,F9,83,6C,B2,59,E6,79,7E,33,B1,95,47,25,17,10,FA,9C,E4,29,FF,94,52,A1,26,E9,16,B0,7A,7B,44,DD,61,48,D9,12,B2,A9,2A,64,09,CB,69,B9,02,AE,C5,43,55,A4,67,86,5B,21,9D,5F,89,D2,D3,5E,54,BE,08,41,DE,C0,3A,D2,2F,4B,CF,3D,73,E3,D3,A2,38,08,01,72,0C,AF,7E,C5,17,76,CD,3C,42,52,38,84,A9,01,37,76,25,DC,9E,D3,DD,F0,C2,B3,71,08,38,EB,E2,6B,A7,D3,3E,51,B1,C9,6D,FC,C1,C8,8F,79,82,A9,AB,93,CE,9D,BF,C0,97,02,8D,CD,34,2E,85,65,26,68,21,C1,9F,68,E8,27,43,FE,C8,0E,2E,1F,BD,A5,07,64,4B,8D,DC,30,9D,A2,F3,AE,E5,A6,BA,31,12,C9,07,6F,54,3F,FF,7F,CC,F6,3D,62,1B,3B,F9,10,B0,84,84,46,EF,89,84,5F,91,CC,82,16,49,D0,16,14,20,DA,3F,60,D7,3E,86,13,8B,87,2E,F2,43,2D,AE,65,F7,3D,54,A6,04,DE,7D,2A,0B,F3,A8,91,46,82,9E,3C,46,7A,39,D0,12,D6,BE,1D,18,E0,AE,AD,82,17,6F,B6,8F,15,19,2A,34,4F,58,BA,06,1D,ED,55,71,15,9B,BE,68,E7,97,28,0E,58,85,EA,94,12,7C,0D,4A,BB,C6,F1,71,06,AA,F6,6A,99,FD,05,68,1D,0B,75,B5,AF,2F,0D,DC,EF,90,86,61,54,02,8E,E9,6E,0A,CA,1E,B5,D2,97,F9,4D,70,C4,D5,5C,36,8E,92,02,9C,BB,47,50,D8,05,0E,C8,D1,0A,F9,DE,3F,99,6E,24,55,18,8B,92,27,49,11,E8,A0,5B,44,51,9B,9D,89,B1,98,F5,D7,D1,92,96,84,B6,19,6A,74,03,22,B9,6A,4A,E5,55,13,F0,F1,2E,6D,5F,A5,DB,BA,70,49,55,E3,6E,91,71,54,1F,65,A0,A2,04,0C,BF,9F,B7,EC,38,AA,A7,4C,B9,7E,B5,2C,01,20,BB,89,C3,2C,88,F7,C4,B1,E8,FF,8E,6A,2F,9B,6A,67,80,29,19,07,58,2F,53,59,DE,02,E1,CE,B4,1F,AE,4A,BE,DE,25,00,6B,EE,14,C8,9C,C5,64,B2,47,8A,0A,1D,B4,EC,4B,19,A3,42,6B,44,C8,54,CD,9A,EC,0A,5A,3B,90,F8,8D,65,AA,19,A6,EB,76,82,75,5C,CC,E6,7E,89,6E,8E,46,BF,19,F4,6A,0C,0F,F4,58,1F,06,CB,72,9E,52,07,3D,0C,E2,DF,22,C5,13,A1,17,6F,66,EB,54,AD,FA,4E,BD,26,8C,90,9D,1F,6F,AD,5E,9E,7D,7A,3A,17,A1,BE,93,69,8A,60,57,44,12,0A,68,96,3F,AF,50,B6,5B,F2,E5,B9,11,34,4A,6C,97,C1,95,28,CC,E3,BE,4A,68,FD,60,C8,7A,55,46,63,17,94,07,1E,B4,4D,2D,CE,B0,F0,FC,DC,E2,61,91,76,72,6B,99,6D,A6,4B,13,19,64,1E,4A,1D,19,59,AE,DA,11,3F,BE,C5,63,EA,38,85,8A,49,99,CB,D3,F2,2D,F3,44,62,F3,19,54,4C,54,1D,D8,F2,6D,F9,82,CE,7E,1C,FE,62,62,60,90,0E,48,C5,7E,1B,4A,5D,71,A4,CF,58,D1,5D,CA,9E,32,9B,F8,E1,DC,27,81,F5,95,91,28,3D,57,16,DE,4F,61,1F,2A,95,62,6C,0E,5F,62,E4,EC,57,FB,84,3E,77,83,C8,9E,4B,04,B0,4D,2D,49,14,63,67,15,1E,7D,EE,D0,BE,9F,81,7D,A3,B6,E6,A6,69,F0,1A,A8,0C,79,A2,5D,F3,F3,1B,A8,FF,3D,68,05,F4,97,30,C0,49,D9,98,60,38,A6,01,75,E3,28,A9,65,03,BF,44,EF,B8,F5,56,74,9C,C5,A3,3A,57,1A,4D,DA,F4,AD,6C,75,06,8F,C9,3D,F1,CE,90,6C,E2,A2,CE,45,EA,25,F2,73,0A,F1,AE,F5,41,3F,73,80,69,0D,0D,C0,02,15,71,8E,F6,48,EC,1F,22,87,F8,D7,9C,2C,F1,DC,9E,B9,4D,55,84,E2,DD,18,F6,66,2D,88,66,3F,5A,49,D2,97,AB,F8,63,E2,83,24,D1,6A,98,66,81,F3,B8,52,63,3C,AF,C6,F9,43,26,51,90,3E,0F,2C,92,B5,76,21,A9,EF,50,14,2D,33,85,CE,F7,94,62,EB,74,1C,F9,FB,47,04,0A,C5,79,55,BA,9D,BC,CA,C9,B6,AF,30,5D,D6,06,B9,D7,DC,26,C6,C4,5B,71,BA,37,60,29,04,E6,C0,2C,41,6C,2A,E1,B3,CC,3C,B1,60,11,B6,9D,9E,94,AE,0A,F0,E5,BE,DF,28,BC,12,DA,96,7E,E7,7C,88,AB,5C,C0,8E,6C,6A,40,3D,CB,9F,B5,D9,6F,08,80,69,3D,2E,40,C4,97,DA,CE,C3,06,A2,76,A5,6A,5C,D2,7E,FB,C1,FA,B6,AF,74,09,56,6E,B1,40,27,4C,02,14,19,36,34,45,A7,A3,17,55,28,0A,E5,47,9C,20,A1,CD,2E,34,6B,E6,58,33,56,E7,50,0B,DF,F4,30,23,2B,EE,2A,D4,84,FA,2D,66,FF,55,3E,33,AC,DB,74,BA,EC,0A,FE,8E,6D,8E,BE,BC,0F,4D,5F,7D,8D,B4,3A,6A,EA,7F,B5,15,FD,FF,BF,BC,BB,D5,EE,9F,01,8F,E0,F4,15,23,E1,F2,8E,D4,C1,C6,23,58,6F,38,C7,A0,EC,6A,97,BF,A9,33,DC,58,E7,82,0B,C5,FE,BB,F7,4C,34,88,91,A9,FD,51,8A,E6,58,12,13,8D,D5,E5,BB,79,5A,B9,72,EE,92,19,51,09,61,62,C6,43,94,62,7A,69,85,F4,4B,72,0C,41,EA,13,17,45,AC,30,BE,7C,D2,AB,EA,6D,D0,7F,2F,96,61,DD,B0,42,F4,68,3C,49,64,3D,97,AD,21,19,C2,34,07,4F,F4,68,59,3C,54,7F,4C,38,3D,2A,9D,95,24,58,05,BD,DA,BE,C1,24,C5,E8,7E,C2,00,80,F8,55,70,89,C7,36,21,6E,E8,CC,AB,3E,FE,EA,D3,E5,CD,AB,16,03,C0,67,30,DD,15,57,D2,96,6D,57,3E,4B,C5,BB,DB,67,3E,3B,DE,8C,ED,EA,F5,B9,6F,75,05,EB,97,BC,CD,86,A4,B1,8F,7E,BD,70,74,97,E9,55,85,37,A8,D1,4A,22,BC,35,BD,C5,1F,6F,95,94,E5,12,C4,34,EA,B6,3B,43,00,DF,8E,A6,DC,4C,BE,17,D8,35,15,CC,51,90,C8,93,59,4B,7A,23,B8,59,B3,1F,33,07,54,3E,10,02,F3,99,C7,B2,2C,A8,20,E3,A3,95,45,39,CA,7E,B8,C1,A3,9E,B6,D2,B8,A1,85,E3,FA,9F,B1,C3,72,28,67,D5,FC,F1,75,5B,DD,B8,CD,CD,7F,C0,A8,D3,8C,45,9C,98,3C,40,22,93,8B,7E,D9,FE,D9,DB,2D,1E,0A,A8,1B,25,62,30,AF,E1,DF,88,EE,C8,7D,4C,D7,78,B8,22,7F,99,FB,4A,22,68,FF,29,6D,FC,C4,4E,25,55,18,D3,BE,44,93,B5,53,EE,AD,88,D2,23,E7,F8,AC,C7,1C,43,8F,F1,D5,27,4B,F5,B7,7B,9C,DD,56,EE,A5,F1,09,55,26,43,D3,DB,8E,4D,83,D6,76,2E,9E,35,1D,F6,6A,EA,10,6A,DA,68,C5,00,C0,A4,ED,23,C0,64,0E,19,E5,F5,14,C5,30,6C,CC,84,5D,C5,92,97,82,28,E0,76,E7,57,26,B9,9D,1E,2D,CD,34,AD,F2,B5,3F,1C,37,C2,E8,97,71,32,E7,6C,DB,53,20,1A,1B,49,12,51,C1,33,89,CC,94,F6,01,D9,8C,CA,5D,E6,C9,60,36,71,A8,EB,D4,C4,B4,7E,88,E7,5A,8A,58,86,AE,AA,E5,12,78,DF,18,04,9E,0F,79,98,05,FC,B7,18,2A,3C,16,CB,A6,63,C6,4C,5B,31,46,F2,26,F0,F3,85,68,FD,93,65,C6,36,33,98,E0,E8,62,CE,AF,FF,B9,04,47,81,89,EF,B5,3D,EF,2D,AE,4D,CC,9B,7B,5E,D9,27,C7,A2,9B,09,4D,23,20,6C,90,B2,D1,D2,A0,9A,D2,08,6E,38,66,CC,99,67,3F,1A,8C,37,2C,77,60,28,42,48,2B,A0,60,CA,0D,A4,54,AE,FB,78,D1,B6,D2,10,8A,F0,5B,B6,95,0C,26,0D,EE,00,20,E7,22,69,7B,23,FA,5E,F2,23,A6,28,DE,74,5C,40,0A,87,2B,E2,7F,AA,91,D3,C1,6F,3D,0A,53,1F,17,2A,3F,52,B4,9B,70,9E,43,0E,77,BA,3B,E2,EA,51,9D,45,50,1E,8D,19,6B,D4,43,F3,38,00,BE,C4,45,5B,2C,A4,BA,DF,4E,90,1D,AB,96,62,23,51,B0,B8,11,71,15,BD,B3,FC,87,35,75,A9,10,02,55,58,E3,2E,18,78,3B,C6,5A,4D,9C,27,81,BD,99,14,DF,37,C3,83,C0,1B,8E,01,E2,FF,6F,CC,AE,8F,72,C4,43,63,7C,3C,83,40,81,39,AE,CE,E5,61,3B,2D,55,F5,7B,44,7B,99,0E,BA,09,4C,79,70,66,F2,64,97,54,F3,82,4B,33,61,B8,FF,9F,4A,D3,5B,0F,78,95,B6,E6,C3,20,A9,E5,DF,6B,4E,EC,7C,D9,66,23,CD,03,00,2C,25,8C,58,F1,04,D5,79,3C,07,03,05,CB,0E,A6,99,DD,71,55,96,7D,57,4F,42,47,07,CF,BA,6D,8C,A7,E6,EC,E1,F6,AB,52,4B,30,F4,CE,A0,80,CC,83,9D,C0,F0,E3,F8,D6,38,CD,E9,0B,C9,20,D7,D3,14,5E,DF,27,C0,73,A3,8E,69,0B,2F,2D,77,B1,E6,D7,6D,A5,09,EA,C8,80,9F,39,10,F5,89,5E,75,08,E3,B4,B6,2D,C9,2B,5A,27,DD,09,A3,CF,E8,83,FD,59,50,2B,C3,AC,A2,8F,FA,AD,62,5C,28,64,1D,E2,5E,41,CC,4B,4C,85,1B,B4,25,14,E0,EA,71,D8,43,90,3E,EE,33,8A,17,66,A3,25,EF,45,B5,3B,39,6D,F2,11,30,8A,CC,29,CF,2F,46,62,D2,0A,A1,32,D7,B9,8A,BB,93,29,11,9D,0F,B2,20,8A,15,2D,0E,1F,EB,EB,FB,1F,40,D2,21,5E,F9,C5,9D,CF,12,42,C4,B8,BB,A6,43,E4,FA,67,80,77,E3,3C,C8,F2,DE,02,9A,B3,92,93,15,E4,D0,D8,0C,A3,3E,86,8C,58,11,67,0E,77,72,16,99,32,81,62,8C,BD,27,B0,43,22,C9,7C,91,C5,7C,FD,8D,5C,09,5F,51,E6,04,D6,0B,47,B1,91,C2,9F,DC,DB,3F,68,E4,54,5C,F9,80,6D,F5,1A,67,DA,7A,2C,96,C1,CA,92,28,78,24,A5,07,2B,3C,E6,28,EE,EA,55,58,56,6D,3E,29,CF,3C,E3,9E,A0,9E,82,D7,6D,41,DC,C1,D0,17,02,FF,D8,E4,E5,72,47,EB,5F,E6,FB,7B,34,17,B2,51,E6,62,CD,60,5A,B8,39,86,FC,D0,1F,AD,43,01,82,FB,7B,1F,39,88,18,6E,79,08,88,09,36,FE,FE,2D,1E,0C,D9,01,74,CE,21,BA,15,4A,1A,8E,85,65,0E,AA,4E,39,8B,D1,AA,5C,69,B1,73,06,21,4B,96,1A,2A,04,F6,15,F7,8C,F3,20,9C,5F,A4,AF,A6,65,E5,63,9F,61,8B,4E,C9,EC,11,AA,B2,31,B9,1A,A4,49,9C,D4,35,7E,A1,A6,A0,4B,A1,E4,92,0A,9C,D3,D1,BC,50,72,01,23,A8,E4,B0,58,48,AB,C2,2C,79,7C,2F,CF,5A,83,6D,E1,9B,B4,96,72,D9,84,0B,61,E9,0B,68,B9,CE,8D,DC,A9,BC,ED,36,5C,5E,94,BE,6C,A0,C5,C2,E2,0A,BE,5F,E0,6C,EE,1E,27,B6,90,51,10,FF,AD,C6,67,9C,4E,36,13,72,3A,55,B7,A4,CC,D8,AF,18,2B,2B,31,22,E0,04,B6,0F,89,AB,3B,27,DC,BC,B3,F0,BB,82,5B,1D,9E,4C,A0,36,51,4E,41,DA,EC,59,D0,FA,3D,27,C0,E0,68,46,92,73,F4,23,12,FE,98,78,91,40,F6,A4,E5,B4,EB,A9,C9,F6,76,21,E6,7B,B4,E7,33,82,AE,F1,42,EB,5C,AA,9A,11,76,AB,CD,15,BE,78,DB,34,F1,1C,7F,3D,79,12,74,5D,36,29,6E,A6,DC,30,26,B4,6B,1F,08,05,0A,4C,94,FC,1F,86,CA,77,9A,03,4F,C5,FB,FB,E5,D5,37,86,8B,CF,33,26,B0,86,11,64,66,A3,7D,E4,01,8B,03,81,BE,45,87,1A,72,47,8E,34,A5,10,62,29,01,60,A9,19,15,FB,B7,08,32,C9,BA,8B,14,86,1C,6E,69,6F,50,73,DD,A6,71,91,A1,29,54,52,27,5B,EC,E9,CA,5C,CF,4B,35,02,1A,EC,B3,81,E8,F4,1D,72,01,CF,5B,47,F5,59,42,6B,30,D0,79,7A,93,7F,BF,DF,5C,2B,56,0B,AA,F0,EA,09,99,40,B6,CF,0A,D6,53,D0,49,A8,FB,8D,78,04,83,3C,FB,04,7C,4D,07,4E,CA,8A,FE,47,4E,E6,2C,35,ED,E3,B0,9F,59,C6,2C,A2,59,EF,C2,F3,80,20,89,7D,06,F8,B4,3C,3A,B6,1C,C7,39,38,BB,EA,68,7C,11,A3,36,92,BB,4E,0F,D0,C8,FA,AB,3D,47,A1,D1,86,FE,AB,0E,D2,DC,96,B9,BA,11,B1,83,12,DF,7A,3A,E1,A2,14,30,DA,C7,D8,39,77,37,8E,DF,CE,E2,9B,79,44,C2,CC,95,30,70,1D,26,66,4C,5B,4A,11,18,D9,0A,A8,FD,53,41,86,80,08,51,F6,90,38,7E,42,46,7C,36,D0,B1,67,C8,C1,29,78,29,8E,A2,F2,71,16,A2,51,0B,DE,01,CD,69,50,E6,E4,1E,36,DA,16,CA,12,64,4E,45,04,12,27,EC,9B,2E,0C,35,43,02,95,1B,16,5A,E4,01,AC,44,28,16,F2,AD,46,0B,99,7F,81,71,65,D9,8A,F7,1B,6D,30,CE,4B,DF,55,7B,76,3B,90,3B,05,2A,C9,E0,A0,73,CF,54,74,DA,E4,3D,55,80,EB,C3,0C,0C,B6,A6,BA,D9,A6,2B,CB,7B,CB,5F,91,C7,1B,33,31,B6,AD,36,51,B1,BF,5F,58,E1,98,52,30,2E,D9,5A,3B,D2,33,A6,B2,02,C5,64,52,A5,06,C3,04,67,AF,C2,B7,D2,4A,56,AC,A9,B8,FB,4A,01,26,9C,3B,1F,DE,9C,92,82,82,25,07,F5,46,00,4A,59,00,51,EF,DC,AA,56,43,D1,39,73,ED,D5,98,E3,2C,3C,67,1F,F5,75,CE,2A,FB,25,27,02,0D,6A,DD,A1,B6,98,A3,AD,18,97,78,AA,AC,43,C6,F0,E9,84,4E,C4,A9,16,CB,7F,46,3D,50,54,2C,5C,C3,D2,F1,B0,4E,03,0B,A7,FA,14,77,A5,15,7D,82,95,93,16,C4,87,FA,8E,BD,4B,F5,72,4A,CA,6E,49,45,87,82,0B,0C,5B,F2,C7,05,F0,44,4B,65,26,B8,A6,9A,EB,2A,7F,E4,3B,C9,83,D5,5C,A1,3E,ED,A2,29,1A,8E,28,6D,37,90,36,19,0C,C9,8B,F3,08,B3,D6,4C,E9,05,7F,9C,E3,48,21,A9,59,2A,30,CD,0B,6F,0D,1A,40,00,3A,7D,70,C7,39,B6,01,4B,76,75,DA,5A,62,5A,E7,3E,19,9F,9B,3B,38,F0,7C,8B,A0,92,F7,7F,A9,96,A6,09,A5,E4,E2,86,BB,4B,36,84,34,64,31,59,E8,42,10,89,63,45,94,94,9A,86,97,07,84,90,96,19,B9,29,8E,84,2F,16,8C,6B,6F,67,B2,42,96,53,9D,E3,4D,B3,01,24,BB,14,D4,71,D1,73,31,41,EB,DE,34,D8,58,A4,71,FB,5D,25,CB,48,B9,DE,2C,03,7A,D5,18,BC,F6,BA,0B,76,92,65,E4,72,0E,57,00,16,4B,C4,65,72,4E,19,6E,DF,AF,EF,64,B8,0C,0F,2B,43,46,BF,F0,4E,4F,A8,E1,4C,C9,09,3D,20,12,41,E4,0F,3A,AA,1B,FF,17,F9,35,5E,B3,89,09,4C,EC,46,38,AF,96,12,1A,C6,1B,92,49,0E,F0,F9,F0,CD,20,5C,1D,98,C0,F0,70,D0,C5,E5,0E,86,49,F8,14,F5,72,8B,A5,A9,25,80,52,37,F2,1D,F8,80,44,8E,18,89,B1,8B,73,2A,16,98,9E,C1,8B,09,F3,00,24,24,DD,30,3A,2B,7D,D0,9E,D0,F9,47,CF,2E,B6,DB,B9,6C,A9,52,60,18,F7,39,4F,FE,04,D4,F5,25,56,16,D8,32,F4,60,C9,FB,9A,55,EE,A0,13,6A,20,48,84,AF,D6,C4,59,52,2C,97,E9,0C,D1,72,84,8B,FF,DC,04,06,75,3E,43,83,01,7A,E5,D2,2B,3A,9D,C7,38,4F,F5,79,70,23,5B,41,DD,B7,76,3B,B3,08,5E,55,16,37,49,6E,4B,D4,C2,DA,53,24,0D,1D,E4,F1,74,E2,14,04,95,44,D8,91,F0,D5,D2,37,E0,EA,CD,F0,66,9F,22,3E,CE,D5,48,B3,41,C4,F8,31,2A,FF,E5,BD,6C,3C,AB,1E,CD,F7,1A,81,81,B8,DB,E4,35,0D,8C,44,00,6A,87,3C,6A,2A,1D,26,38,9A,10,E2,42,E1,06,6C,22,56,57,24,5D,51,90,1F,D6,7F,C1,A5,A5,03,35,1E,4A,8F,51,B7,11,BE,59,6F,CD,F3,1B,B4,66,42,0C,08,D6,54,B2,20,BA,0C,16,6A,FC,05,A0,4D,BE,FC,F8,58,84,36,62,01,38,1B,B7,19,91,E9,C2,AD,2D,66,1F,88,00,2D,41,41,0A,66,7E,31,01,2C,13,9B,B4,3D,53,82,E4,53,7A,0C,A1,9E,28,2A,89,9C,DF,1B,14,EC,83,56,2A,03,5C,98,C3,47,7C,5D,29,69,DC,53,E1,D4,70,70,58,65,69,3F,8E,1E,7A,67,16,A4,83,5A,E4,19,5A,58,BF,D8,73,81,7D,31,C2,DF,ED,64,EF,71,F8,67,A9,C9,88,B7,84,F0,DC,B5,EA,5D,B0,1E,B1,8B,54,90,B9,95,4B,70,7B,70,25,D0,E3,33,66,08,B3,88,97,2B,20,E2,A3,0E,88,EB,14,9A,2D,97,C5,70,87,74,8C,EB,EA,62,6E,80,27,A8,DB,97,3C,78,0D,E7,74,84,C3,45,50,65,51,B3,69,8D,1E,34,70,DF,B5,AC,E1,C1,A8,31,C4,84,6E,3D,88,DC,99,F1,88,C2,F7,CB,FA,CD,07,D9,04,0C,41,9C,A0,C9,98,A2,90,37,BE,C7,28,0A,22,CB,5B,3F,08,34,C5,C8,42,F5,60,19,8E,2A,3C,1A,B6,25,B7,47,61,42,A3,AF,D0,70,03,40,DB,1E,7D,36,A5,C1,25,8C,C2,2D,2B,D3,D8,28,B2,9B,72,20,86,31,F3,EF,7E,AB,72,A9,1C,90,B0,D4,AF,F7,B3,EA,0A,19,24,27,3C,AD,BC,C9,EC,B2,2A,77,DC,41,4C,5D,0B,61,B7,4C,BF,A5,8F,4D,00,4A,14,CD,89,04,E6,48,91,5E,85,DF,2E,D2,1B,3D,5B,01,87,44,2B,B2,15,F1,C5,5A,21,9A,AB,D2,9B,D0,18,A2,10,4F,DA,FC,AE,4B,4D,FB,EC,BE,64,C6,7D,F2,F2,18,6D,D9,CE,14,4C,6D,9C,D8,7A,AB,FE,F2,21,52,B6,33,A9,C3,51,31,DB,91,91,B3,C5,17,07,5B,15,F0,91,64,BC,A8,5A,C7,30,C7,45,CD,4E,22,1B,C4,27,18,BA,12,B6,3C,17,87,54,C4,11,F3,4B,1B,59,55,11,90,AF,20,85,B6,C7,F0,4B,30,E6,B1,42,D3,44,24,18,99,21,43,4C,07,D1,1B,0A,18,7B,45,D6,38,48,98,A9,1E,BA,1A,E0,91,69,73,4A,ED,D0,01,D6,AB,F0,D3,82,F6,C7,6C,A8,47,44,BB,F1,37,BA,FE,69,86,78,F6,DB,F7,0C,E3,62,E8,C2,40,30,0A,1B,49,60,6C,1C,B2,3D,D7,B4,A4,F7,E3,AD,BF,B3,25,CD,5C,70,15,93,EE,00,89,B6,62,39,BA,E5,24,0E,C3,8A,18,CD,DA,E9,34,00,DB,9D,27,DA,D5,F5,58,49,BC,BA,3E,F1,0D,A3,9A,E1,19,DF,FF,7D,B2,C0,5F,F5,9C,6D,37,A7,41,A3,CF,FB,F3,46,13,D3,B7,7C,D5,30,72,F4,21,2A,A9,E9,47,02,93,83,4D,52,60,47,1E,96,75,4D,AE,70,DD,0A,E7,15,2B,77,0A,40,03,0F,87,F6,A6,6B,42,46,8C,AA,E1,F4,FF,FC,B9,03,5E,2F,FC,32,57,9D,A2,AD,02,F9,04,5B,2F,32,EB,46,39,A4,F5,33,A7,54,41,DE,98,65,42,BD,1D,DF,29,E8,09,AC,6F,5E,4A,24,23,18,9D,56,AF,0C,E7,74,A0,00,89,8C,F4,8F,93,B6,5A,ED,CF,5E,7A,BF,48,F5,DA,8C,4C,01,0A,7B,59,94,62,45,FD,48,DF,C3,25,1A,8A,91,3E,83,B3,9E,C8,4C,3A,D8,7F,D8,EB,41,E2,B6,8C,3A,9F,12,1B,08,8A,52,24,D1,DB,28,C3,BD,4F,A6,19,5E,DC,71,76,2D,FF,9C,8B,C8,99,A4,51,3C,75,3E,EF,E1,3A,FC,57,55,04,AF,70,FF,7C,2A,51,35,A5,D3,7C,55,B3,68,17,0A,ED,DD,8C,32,24,29,53,58,94,17,29,06,FC,52,08,9F,4B,0C,25,AA,CB,CB,AD,F9,77,79,A2,6A,93,CC,1E,87,A6,1E,62,76,CA,41,DD,56,1D,1C,53,2D,FA,86,42,22,AA,07,09,90,0A,67,57,F1,1C,62,F6,24,12,F7,69,75,0A,5C,34,93,73,29,5C,20,62,02,E0,3B,F3,4C,7B,56,0C,3C,89,BC,AE,F2,1B,76,10,94,20,D7,2E,D2,AD,E1,F1,52,50,71,F4,65,BA,F6,7D,EF,E7,D2,4B,54,5E,42,BA,E8,56,D2,3C,36,90,6E,B2,8C,E5,5E,70,03,F3,17,6A,39,23,E4,46,0C,50,DC,66,C9,A4,1E,99,87,2D,8C,A5,72,4A,2E,8F,98,6E,DE,A6,7B,4D,6D,E6,8F,31,42,10,0F,D3,0A,BA,34,93,BC,86,1D,FF,09,62,49,00,4A,29,6C,E2,28,85,EE,48,C0,B9,FB,DA,9D,B6,97,D4,EB,DE,7B,6F,64,0D,63,EB,1D,41,DC,B0,CA,05,30,EE,B6,3D,8C,EA,21,CB,2B,A6,37,7D,DB,CB,86,98,B6,60,B0,49,08,67,C4,1E,56,78,70,75,53,86,F5,66,18,F1,80,A6,CC,A3,6D,58,A0,06,0D,48,95,A1,1E,F5,91,8F,9C,78,3D,3C,DA,95,90,CF,FA,9A,FB,2C,9B,51,B3,B2,1C,B7,0B,B2,60,A2,B7,5D,09,31,6B,08,06,60,34,02,86,12,39,0A,6C,9F,A3,2D,22,B2,B1,BE,56,BB,A6,57,A3,C8,2A,02,80,B5,E2,4C,72,E3,EF,EC,B7,9D,7E,C4,3B,7F,AF,2B,AC,CC,F6,0C,0E,CD,F1,0E,1E,93,6D,7D,B3,09,96,FF,5B,DE,19,52,EA,71,5C,76,63,F1,21,96,27,8E,94,10,4E,83,7F,CF,A9,B3,BB,11,BD,AD,33,00,91,6F,07,E3,6F,71,CD,3B,91,04,74,F5,88,2F,23,0C,3E,40,F2,4A,4B,D7,F3,51,F9,B8,8B,AB,DC,4F,1E,31,B4,2B,B5,3D,73,9C,A1,5A,73,E2,A7,48,F5,4B,1B,3B,F4,BF,82,E0,02,6D,45,F8,A7,9D,F5,1A,F5,8B,FB,2D,74,4A,6D,9B,AB,DD,D8,94,09,48,4E,56,BB,0E,86,22,B5,46,51,21,FE,FB,82,1B,26,14,57,28,8C,D8,86,8C,5C,11,7B,76,70,6E,3F,24,A0,95,24,F1,CC,92,92,BB,69,15,5E,A0,12,8D,AE,1C,DC,B6,50,38,52,3A,49,7E,69,63,6C,9C,6A,51,91,E8,2A,5D,10,34,B8,D9,C2,FD,EB,DE,29,10,12,51,98,4E,82,A2,2A,E6,FD,EB,47,D7,C4,F7,E1,F5,8F,AB,7C,5E,7E,BC,5C,DC,7C,95,78,E8,FD,0F,1F,2C,C2,63,AA,64,CF,48,F1,9C,5F,3E,61,4B,39,49,CF,B5,89,8B,2B,63,6E,23,FC,0C,55,51,FB,EF,45,95,7C,AA,81,18,A7,75,43,4D,8D,AB,56,E0,CF,F0,C4,F5,63,71,D8,8F,92,E8,CB,EB,27,4E,B3,AE,6C,36,C9,19,9C,BA,19,16,C1,44,19,A2,77,D0,B6,00,75,A7,9D,CA,EF,EA,A0,24,38,6F,26,EC,E7,C0,65,AF,50,E5,9D,AF,A4,21,F5,90,01,F4,97,2E,09,0C,F4,95,82,F3,66,5B,82,7B,7B,B6,17,5B,5A,04,FA,A2,DE,BB,91,03,6C,81,4F,93,D1,0A,05,AD,88,57,2C,AC,4F,BC,9F,45,BB,CF,63,6D,7C,3B,CE,45,D2,80,56,E8,1E,CC,55,64,11,49,96,F0,6A,D4,C9,4F,78,ED,D5,19,17,AC,E0,28,05,72,CB,01,55,08,88,B2,50,45,C3,85,53,4E,D0,8F,E7,3A,5B,EA,B0,80,1A,ED,84,68,66,15,63,0F,04,AD,1F,23,9F,63,B1,0F,FF,F1,B1,E9,77,B8,05,69,BE,56,0E,BF,8B,39,F2,AD,F6,EE,35,33,69,C0,19,38,26,CF,B8,73,84,A7,E5,99,6B,8C,65,A6,4A,C2,0A,62,97,68,DB,F5,25,BA,58,66,67,A1,CA,AD,E8,A7,6F,AE,08,D0,41,D0,68,53,3B,0E,2E,51,3F,14,4F,15,7E,9C,56,FB,0A,3B,D1,C3,DD,45,D9,52,BD,19,02,A7,60,CB,22,FF,DD,10,9B,BA,46,1F,B9,FA,A8,62,29,1E,EB,BA,BA,83,E2,1A,FC,EF,B9,33,71,C2,48,11,B4,56,24,48,06,D7,4B,20,03,FA,1F,A9,C9,AA,A4,C3,3B,0F,6B,06,B1,C9,E7,A5,61,D6,6C,CF,68,A0,5A,68,2F,91,1D,5C,22,A6,7F,D4,EF,BD,0A,B9,97,A3,A4,FC,9B,82,AE,51,F1,17,2F,9C,AD,94,58,AD,E0,48,82,FC,47,A3,6F,66,AD,C3,26,F9,3D,A8,15,1C,4A,B4,27,78,C8,FE,CD,1A,DC,EA,24,3E,9D,4B,D8,0E,2D,45,7E,4C,5E,C2,BA,F4,71,55,3F,38,3C,C1,D6,9A,21,68,D3,CB,60,78,B0,C5,AC,46,1A,2C,B2,77,D4,76,27,6B,FE,D6,F2,FA,4D,78,25,C2,19,61,8E,C8,B2,CC,E5,34,B4,13,E5,A5,C4,B9,71,AF,6E,6E,B0,12,49,87,10,8A,EB,82,30,F3,75,83,E6,25,E3,CD,7D,85,01,DE,94,4A,25,2F,C2,DD,11,DA,36,C5,DE,40,14,8B,0B,29,18,C2,6C,4D,F1,90,60,D3,9F,D5,E8,21,2A,D4,DB,4C,83,D4,F8,D2,E0,10,BA,73,78,EB,78,6F,69,08,A3,D2,B8,FE,25,B9,70,B1,5B,29,D4,FA,62,52,17,7E,8F,CC,25,9C,ED,34,3D,21,50,98,3C,65,DE,C6,31,AC,92,21,A0,8B,FA,47,90,E7,29,53,7F,B9,02,FD,5F,7D,09,DB,F2,01,64,1A,68,E5,47,71,DE,85,DC,85,AB,E4,C9,77,B4,1D,A9,B2,0C,41,9B,78,DB,B4,9E,53,EF,43,1E,1C,17,45,A0,D0,AD,F2,13,6C,63,C5,BD,C4,9F,EF,59,3C,1E,FF,FC,23,64,3E,43,B5,24,FD,D7,94,87,12,80,7A,11,00,89,2C,D4,2D,95,E6,03,F0,FC,AE,BB,9A,6D,23,06,9E,4C,B9,61,C7,C1,67,A1,4D,88,E8,91,E6,B4,AE,5E,93,74,49,CA,5F,C5,A4,D8,5C,C4,15,FF,30,8A,99,AC,76,D9,58,7E,7E,4C,B7,3B,ED,3D,13,32,13,71,50,7E,B3,9A,26,B1,2A,9B,CF,AD,FD,22,31,5D,16,BD,78,A9,7C,98,35,73,6D,B1,44,7A,28,0D,63,CC,55,C3,9D,74,0D,6B,CE,65,C1,B2,B9,1D,35,64,3A,DC,96,97,16,73,34,F3,1A,2A,68,9B,3A,88,6C,44,E8,34,4F,A1,38,C5,F8,3D,37,C1,9F,B8,4C,E1,4F,E5,F0,5E,95,12,9D,52,6F,02,DB,80,B6,D0,D1,3C,8B,5A,5D,CE,F9,76,1D,74,95,4A,0A,7F,2C,93,84,FC,0C,CE,99,42,C0,DD,97,2A,F8,D8,FA,2F,F1,9F,97,74,03,A3,A5,FE,C9,CA,C2,8E,9A,FF,1B,72,0D,0D,07,93,CC,E8,E1,64,72,80,B2,E6,DC,60,31,0E,AB,3C,41,53,DD,EA,AB,DF,97,D4,36,E4,DA,6F,24,0C,D2,D1,33,30,B4,DC,62,3F,4D,24,1C,51,83,6E,57,E7,83,41,C2,47,45,91,7C,C1,19,78,F3,47,DE,FE,3A,69,71,63,3C,B6,30,A9,B4,AE,5B,F2,4C,30,6C,8D,34,74,67,B1,05,9E,4C,3E,E3,4B,9D,FD,84,50,9D,8E,63,DC,C8,C2,32,98,C0,7C,0D,67,BF,8E,BA,8E,94,55,C9,7E,4E,63,C2,2F,C3,84,FD,A9,AC,07,64,93,B9,CB,6A,2F,96,67,AD,FC,7F,40,B5,33,A0,58,B6,2D,2C,A1,30,F2,BC,BA,3E,48,DD,BF,CE,E5,5F,C3,BF,40,10,E2,60,90,48,A6,B8,20,60,14,54,BF,84,FF,83,D9,2D,91,D1,EB,1B,81,14,B9,CC,FE,C7,A3,63,BC,94,BA,AF,15,7B,4E,8A,B9,24,DC,0C,9E,3F,F0,55,D3,F6,20,14,5C,2E,68,30,F1,DF,32,E1,48,A0,62,BD,BE,77,03,24,A5,2B,46,F3,74,9B,E0,D2,3D,B3,CE,F3,CF,E8,07,9D,74,20,66,5C,AD,78,8A,7A,BC,D0,14,7E,45,AD,49,F7,EB,42,9C,EA,95,B6,16,E5,A8,25,58,A3,CF,73,83,DE,CA,7A,3C,E4,6A,AE,A0,36,59,EE,BA,12,F4,93,24,F9,A8,24,5D,7D,D3,42,A0,B8,76,E8,84,14,C5,7F,F7,5B,B3,14,6E,FF,46,93,AF,BF,4F,D7,69,15,9D,6F,4F,DD,DF,62,F2,93,DA,BA,E3,C5,D3,F5,DD,D5,99,44,54,90,F7,50,73,3F,9B,06,59,9B,56,DA,78,82,17,57,7D,33,C9,E6,0F,E3,2C,A1,A4,93,9C,63,52,AE,4D,E5,57,DA,B0,2D,4E,2C,32,C4,67,88,18,91,69,9E,E9,46,D1,34,9E,44,7C,5D,01,ED,54,C4,27,4A,E4,24,A2,0C,DE,D4,93,FD,A6,9A,DF,6B,04,1A,09,7B,5C,C4,63,5A,FE,BB,2B,92,E9,6A,84,80,88,9A,A9,C7,44,CD,E3,07,FD,C3,3D,9C,90,B3,CA,2C,B4,B9,F3,E9,36,64,14,AF,27,CB,F4,E4,C5,BA,D0,9E,22,28,67,AE,D7,54,C6,24,BB,D5,02,70,29,0C,C1,9C,49,0F,51,86,E5,55,AD,5C,43,06,00,A0,F3,AA,C9,0C,2A,EE,33,D6,19,37,A8,9A,B4,62,78,7E,DD,E5,F1,DF,65,5F,56,34,74,33,82,49,7F,8C,8A,43,D1,4F,B8,EC,14,6F,2C,71,1E,89,22,28,67,D0,DA,CD,07,E7,DE,78,D5,F1,38,A9,F8,FB,E4,49,79,E0,00,B5,DE,FA,1B,B9,1F,88,C0,A0,3E,21,B4,D0,B8,58,3A,85,13,89,6E,8C,42,5E,A7,73,69,09,C2,E7,E7,10,FD,27,00,BD,DC,FD,6A,D2,ED,24,1A,AC,53,8F,E8,AE,9F,73,70,C3,87,37,97,CB,86,DE,CB,27,0E,FD,DE,2E,E9,4B,1C,D8,EB,A8,52,AB,4B,23,54,5F,21,1D,9F,8A,42,7D,3C,F8,74,67,90,63,A4,B4,05,53,0B,BD,9C,4E,0A,3F,9F,28,BD,D8,80,1B,20,79,BC,94,C7,02,F2,E8,C4,FF,6D,D6,96,B7,D5,4B,21,28,0B,6F,78,2B,EF,E1,A7,78,A1,9B,B0,AE,BC,BE,83,77,20,61,A0,85,45,1F,7E,D1,53,D3,05,47,28,24,E5,D3,6C,79,D8,CF,2D,21,FC,2B,D5,8C,DE,59,1C,1C,2E,02,26,9E,91,D8,B2,FF,3A,C1,64,F1,74,46,57,F0,1D,D3,04,6E,55,B0,98,AF,9A,C3,A9,23,50,36,37,2F,07,CD,5C,F1,78,EC,0A,00,8C,BB,C1,B5,31,54,37,9E,7F,DD,1E,08,9E,B3,8D,EB,02,EB,56,42,CF,42,9B,00,1C,E5,CC,A0,D4,99,36,69,EF,1A,6B,2C,D1,51,6F,02,21,12,0F,4B,81,85,17,E2,01,52,3E,B4,4A,03,37,E2,63,3A,74,1F,26,AD,0A,EA,3F,A4,D3,83,00,F0,F9,A4,60,7B,92,DB,39,E5,86,63,77,2B,29,45,8D,70,EF,E8,05,31,D3,51,32,51,C7,9A,F0,98,5A,BC,97,29,FD,A7,37,42,B0,5E,10,22,20,51,51,0F,AB,26,0A,B1,BA,7A,78,04,15,42,38,67,AE,39,77,1A,64,16,B0,90,73,24,8F,17,CC,55,CB,52,62,10,AE,87,80,3A,74,20,F8,9C,EF,79,E2,05,0D,B2,E2,E5,9C,CD,A0,6E,24,E9,42,5E,52,DA,75,12,06,A8,8B,3A,E8,DA,5A,25,69,5B,32,38,08,9E,26,BE,9B,0E,DF,70,6C,15,25,0A,E1,67,CE,38,4B,5A,FF,5A,B9,54,EE,4D,02,F5,22,58,AF,E3,75,C5,2F,24,5E,5E,CA,5C,E1,F2,FD,A2,AF,99,EA,35,24,1F,04,30,A7,AF,ED,60,F7,6D,F4,F4,9C,A9,AA,48,9F,35,78,F6,BB,9C,A7,B5,77,92,8E,DC,F5,20,F5,93,EA,C9,A8,BB,14,C2,32,81,BC,BB,D8,3A,F9,EE,BC,26,DF,3E,21,43,29,CF,A4,5E,64,8E,8F,A9,AD,12,6B,E3,0B,86,97,78,4F,C1,D8,95,11,6C,C0,94,86,1D,6B,70,25,5F,A1,35,DB,6C,0D,D1,4C,B4,70,3E,66,70,72,6E,89,61,2E,BA,CB,FC,10,AC,85,F9,46,B1,4F,0A,5C,AA,66,88,FA,48,B0,26,61,E7,86,99,22,27,01,31,E1,9E,85,62,13,2E,4B,F0,0D,14,F3,C9,77,D5,22,07,1A,27,75,2B,93,3E,0A,84,EB,7A,35,98,6D,56,7F,8D,CD,0A,9E,83,76,D9,62,54,E3,EA,E6,66,6A,2F,63,FF,79,09,F2,6E,8F,60,7F,1D,4E,25,39,2D,DE,C2,F9,76,7A,2F,14,10,B7,66,7E,82,FA,00,80,BB,12,5E,5A,9C,32,EF,4F,07,02,4C,FB,C1,C1,4A,01,96,46,00,38,72,7D,18,4C,CA,AE,86,4C,C7,2B,19,F1,31,F7,3A,B2,C9,EB,02,2C,58,9B,A3,9A,F1,32,C5,0F,69,83,36,C4,59,95,05,CC,9D,2D,60,AF,C7,10,1C,07,86,3D,EB,A4,2A,DF,B0,06,3C,96,54,3B,35,03,E2,1C,D9,6E,9C,0B,F0,FC,F2,B1,4F,61,85,76,38,63,DE,C1,C9,AE,35,40,81,42,8A,CA,03,5B,87,88,38,EB,D1,EA,11,2A,34,A8,9F,4F,17,D4,6E,FE,82,DD,B2,5D,32,57,6E,07,06,77,B3,72,71,E2,E7,BB,3B,89,F4,C9,7D,9F,9B,5E,C3,54,B2,A8,A4,4C,8F,EA,AF,24,AB,DE,D3,02,99,36,3C,AF,2C,3E,A1,8E,62,29,BD,91,F3,B1,CB,3D,4B,67,04,67,AC,08,00,32,BE,F6,F1,BD,0B,A6,17,98,89,3F,75,1C,65,38,43,D2,35,43,62,0E,8A,3A,AC,97,5A,99,EA,8C,F8,9D,0D,22,9D,79,AB,9E,D8,B5,66,D8,F9,7F,7E,1A,77,BC,52,17,C6,6E,25,C8,97,4B,A6,D7,41,0C,8D,33,6F,CC,C3,61,72,02,F2,11,8C,B6,2A,C6,13,14,BB,10,0D,EC,D5,B6,08,B9,63,D0,67,93,70,18,F4,FF,BF,A6,7C,2F,A3,53,96,74,7D,AB,52,36,CD,D7,E1,21,C3,4D,0E,6B,34,5D,68,68,7A,4A,F2,B6,52,71,1D,9F,60,DB,52,4D,D4,04,38,72,EE,52,AF,B2,2E,7C,63,34,96,D8,FB,7E,1C,AE,81,A3,53,16,84,3F,CE,6A,8B,42,24,30,BC,52,65,C4,F8,75,EA,92,D6,4B,F6,C5,6C,39,40,86,2F,A4,A5,8C,04,4E,59,D0,A2,8F,02,B7,BF,0C,B3,1E,38,10,46,F8,69,C2,4A,27,A7,15,E2,8E,CE,50,11,89,A7,77,DB,BD,25,87,E7,B4,25,1D,32,B0,45,57,C0,85,DB,C0,32,BE,92,6D,88,C0,A2,6A,D3,E0,84,34,60,50,3B,CC,AD,86,B1,6B,EF,C8,C3,E6,2F,27,86,E5,A0,BC,A0,7D,52,42,8B,E3,61,04,16,CA,B0,85,B4,4F,2F,0B,14,6B,04,44,A1,62,C2,0E,86,39,64,19,51,AE,59,40,EF,BD,19,D7,D8,FC,B2,0C,DA,EC,67,AC,09,FB,EC,62,56,E7,C9,A5,7D,0E,BD,3C,CD,7E,FE,AE,89,31,07,0B,65,A1,62,C5,29,8E,02,5B,12,F1,E0,8F,74,C1,A0,D1,FD,F6,BC,8C,13,12,35,52,26,D3,DF,84,64,24,10,79,BD,72,91,FE,BB,7A,AA,6A,4D,B9,D9,1D,95,14,D1,EF,68,F6,88,EB,35,19,AC,55,57,75,B4,9E,B6,D0,7D,E2,7A,99,1B,F0,75,0E,A8,DE,25,0A,18,02,6B,6B,C2,10,8A,C0,20,2E,FF,7F,A5,78,13,FB,BB,D2,7A,3D,D9,51,4B,1B,61,8D,75,70,DA,DD,51,DA,B3,B2,E2,3E,D3,35,C3,99,33,02,EC,5D,BA,2B,64,84,64,FD,94,04,41,FA,BF,F5,92,46,5A,C9,44,B7,33,A3,21,64,90,A2,81,A2,77,8D,5A,F1,19,5E,91,80,CF,DE,24,B5,64,2C,DB,B5,EB,23,FF,6F,21,DB,B0,10,11,5F,CB,24,26,CB,B7,91,F7,09,66,AF,FF,0D,4E,53,12,EF,3B,7D,6E,00,5F,C2,23,72,54,2D,13,4E,3E,F0,14,5D,2F,81,CD,38,19,A4,A8,A3,1E,CA,E4,B9,00,C3,5A,BC,3A,01,05,22,56,69,2E,3A,97,E5,08,55,77,3D,30,A5,19,B8,66,04,F0,7B,71,AE,D8,F2,2A,82,16,70,A4,88,3C,DF,8B,28,D7,BE,CE,FF,C9,C8,73,E5,8F,20,3C,A8,57,ED,7C,16,BD,2C,CC,92,B2,9E,A2,4A,C2,9F,1A,E2,F7,26,AF,30,FA,08,9F,96,3D,D5,02,FB,99,0F,09,A0,FD,4D,38,46,5D,37,40,06,A5,A8,0B,78,DB,55,0C,B4,2F,8C,7D,1B,43,F0,03,D8,78,38,28,6F,E3,EF,04,21,DB,23,95,8F,E2,F3,44,87,99,4E,AC,9E,C2,4E,9C,74,F2,B0,66,95,44,21,C9,77,3F,B9,65,F3,C1,65,C0,DD,3D,C9,4A,D4,4B,59,3A,11,5D,80,0A,8E,35,39,68,D0,15,7E,A7,EF,DD,AC,BF,B0,9D,E2,4B,6C,2B,E8,FE,CE,EC,AE,27,0E,4A,D5,C3,DC,D0,97,8A,88,F4,36,26,7E,80,FC,78,E3,9D,3C,8C,52,0B,40,1A,68,3B,7C,A8,30,4F,6B,4A,73,75,A0,73,F5,81,15,C4,C3,A4,09,CC,64,D1,EE,61,6C,DF,38,04,DB,67,0F,DC,01,66,A3,B5,E7,B9,6E,A1,71,CD,8C,3F,B0,96,6C,D2,01,DF,6D,75,A5,48,2C,39,CD,5A,70,CB,57,F1,BC,A2,32,D4,B2,8B,81,42,97,99,B4,34,8E,3C,51,1D,41,F7,06,6B,D9,9B,CB,07,D9,80,EC,55,B0,62,8D,1D,40,1E,B1,AC,14,E6,29,73,E1,AC,E5,0F,91,19,6D,BB,6B,0D,5E,DB,00,1E,E5,B3,48,42,21,31,83,BF,75,01,DA,51,7F,27,A6,1B,34,8B,15,95,10,6C,E2,0B,C9,50,40,0D,20,95,3A,FF,82,D8,E4,07,4B,86,7C,3C,ED,1F,D2,8D,B0,DC,68,5E,9B,BD,40,96,AA,BF,6C,4B,A6,0F,D4,39,DD,D4,52,13,57,F7,36,CD,B7,98,A9,93,C0,95,F7,1E,ED,63,4C,1E,BB,DD,32,3E,CC,B1,79,8A,9A,78,71,7A,D6,30,E5,FB,90,E0,9C,C7,C7,1D,74,CB,6A,3A,94,A2,DE,FA,D0,21,C6,F7,E8,A4,E6,CD,05,DB,E3,89,8B,02,68,7D,13,10,B9,9B,09,55,02,09,B6,2F,B0,94,49,A0,3C,EF,E6,31,1D,22,54,8E,E9,57,89,B6,6E,93,37,AE,21,A1,CC,94,AA,AD,FC,7B,B2,5E,46,73,48,DF,A1,1F,A0,DE,F0,1D,7C,D5,F1,42,10,47,09,BF,12,A9,4D,ED,58,4A,BE,CF,04,4A,F1,03,93,BA,30,A0,3B,F8,68,F0,4E,67,88,C4,78,77,06,10,D4,08,73,9D,88,8F,77,43,D4,D6,DA,35,6B,E8,BB,92,8A,CF,BD,6D,40,2B,E6,6F,DF,97,E4,60,A0,E3,43,6E,DD,4E,77,13,2F,7A,C3,70,78,5D,73,EF,B4,D8,8C,4C,21,5E,A6,FC,FD,E4,F6,2A,93,07,4A,A9,B0,6E,49,03,77,91,B3,43,1F,68,B7,BE,EA,3D,C3,E0,16,E6,31,76,AC,00,EA,DA,3B,61,91,E1,11,E0,96,CB,6F,A6,81,DB,7F,A5,B4,D5,2B,C8,F8,C6,3F,98,0D,B1,C6,C4,44,0C,44,2C,C9,96,99,D5,BF,0A,47,98,AB,C2,AD,76,C4,2A,05,E4,76,C9,0B,D4,BE,2E,7A,3C,F4,89,F2,03,F9,E4,15,3F,01,BA,CE,5E,70,D5,93,5D,98,9D,99,B4,08,85,54,23,8D,A8,6B,73,64,51,A8,43,5C,9E,F1,C7,2C,6F,5D,39,75,54,3A,DB,BD,34,7E,F0,90,55,9B,C0,F2,DA,FA,A5,D8,5D,2D,A2,38,03,66,47,B5,28,A8,85,71,02,B1,7B,B4,CE,29,25,06,4D,C3,2E,85,1D,C3,60,67,0D,E5,BA,14,66,4C,6A,D2,63,2C,EA,A3,62,2B,E3,79,41,0B,75,89,12,C3,02,B0,C9,E7,5E,9B,DF,84,3E,D7,C0,A0,F7,93,14,E4,EA,A4,80,16,04,EB,F2,4D,39,44,67,20,C3,B7,34,89,D4,D3,EF,8A,38,6F,AA,00,14,7F,6E,72,0B,0E,B5,EC,06,FB,A7,13,4E,2B,C7,E1,8A,0B,31,F8,6D,BC,B2,62,85,15,78,B2,50,6C,71,5B,B9,F0,7A,D1,FC,EA,B8,84,86,F0,4B,F2,9C,27,C7,22,A8,9A,44,C7,33,4A,B0,79,81,59,0D,0B,F4,92,EF,9E,2D,F0,72,0E,BF,A7,90,73,5E,68,C7,FC,73,A2,AA,FE,67,95,C0,FB,A5,00,E7,F5,DA,DA,75,6E,14,EC,96,13,71,78,CB,45,21,1E,B6,59,0A,CC,AD,7A,63,5C,2C,3F,15,5E,F4,9C,D9,D2,F8,38,5E,95,67,36,E5,9F,73,90,79,F4,CF,BA,4A,B0,A9,62,9D,BA,05,B6,65,B0,A9,14,69,0A,03,BB,14,75,3F,47,92,73,11,27,06,49,26,5D,D4,8E,3B,BF,E2,D8,51,34,F4,EA,06,A6,BB,40,90,48,9A,19,C6,E9,63,79,49,33,F1,7E,D6,4B,C1,A3,D4,FC,21,96,FF,70,AC,3B,FA,74,E4,80,99,D3,39,DC,5D,D5,57,BA,0B,D9,2B,8C,39,1E,5A,F8,1D,43,7F,FD,C7,6E,B8,3C,85,52,42,27,13,69,94,F7,76,B3,85,7B,E4,99,34,CC,5F,D4,5B,0E,53,EC,6A,95,13,75,F8,9B,9C,DC,79,FC,0F,12,16,E5,F5,94,F1,2A,E2,8D,3B,46,67,01,AE,25,C1,49,25,37,2F,B1,83,DA,67,06,AE,54,4D,6D,75,1F,B1,E8,0C,D3,4E,04,D2,5F,EA,DC,8A,24,79,DA,F7,45,EA,AF,51,78,64,B7,50,94,6D,61,4C,6A,E4,EA,AB,82,F4,A5,A0,34,A2,D9,7C,2B,24,26,60,C2,D4,D1,CB,63,34,08,2E,4F,E5,CD,D2,C0,EF,04,FB,0C,7D,DD,CA,74,E4,85,15,31,77,E1,96,58,87,E4,86,4F,4B,13,69,00,8B,10,C0,E8,DC,13,9D,DB,DB,61,59,B8,63,AC,FC,24,C4,99,5D,1C,9A,BE,C9,2D,F4,E8,A3,96,9C,9C,CC,F5,CB,02,7D,A0,0E,EC,78,78,A6,A5,DC,62,6E,28,BE,C8,42,1A,BF,07,B5,90,6C,16,8F,8F,F0,1E,4C,66,C1,EC,17,98,B5,83,84,61,65,F5,F0,8A,EE,43,8B,CD,DE,A6,9F,53,62,C6,01,8D,A4,59,51,9F,C4,21,23,67,9C,45,2F,E8,F1,E6,76,C0,46,6E,C3,1D,BB,B7,6F,20,A0,69,43,BD,6A,B9,EA,66,40,4A,13,DA,D7,BD,B2,F8,90,E0,85,CC,45,0D,8B,5E,BD,34,6C,C6,1E,48,FF,C7,D9,16,D3,0D,3D,27,5E,EE,AF,87,39,86,29,9A,FD,03,7D,D3,76,BA,CD,69,27,25,7B,7A,10,B0,A4,0C,B8,B3,81,8D,AA,C0,01,B2,E9,82,3F,55,CA,35,54,4F,61,CD,E8,FE,D8,AA,71,F4,BD,CC,68,65,1E,1B,1F,96,C9,F9,17,6A,E7,34,DB,19,D1,AF,FA,46,E3,87,0F,96,4D,9F,4C,D2,3F,42,2E,03,8C,7C,76,1B,7E,F7,99,77,92,C2,A8,B9,10,3C,9E,AF,67,18,A5,B3,F0,F8,7F,F9,D5,91,B3,6F,69,EE,50,40,75,EF,47,73,E8,03,76,B9,C4,7D,C6,81,5D,E8,22,4C,88,8B,5C,D0,93,77,08,F2,6E,7A,84,0B,2C,3A,3D,6D,BE,EC,6D,80,4C,16,85,E6,B8,0F,4B,26,20,09,9E,7A,F1,EA,F0,48,DB,9D,74,74,16,BE,6F,51,4F,33,97,EE,ED,B5,53,C0,BD,52,8D,ED,4A,77,3E,C2,C6,6C,40,35,DD,27,59,E6,1A,1A,18,AB,9D,7D,EB,55,D8,4A,63,7F,10,FF,32,B3,D7,EE,87,8A,63,28,B6,66,71,60,D5,D4,38,D4,84,38,AF,AA,66,7F,0B,E6,83,82,F6,74,E8,E4,7A,D2,E5,0F,07,33,68,FC,B0,72,16,3B,10,EA,31,AD,17,93,D6,C2,50,0A,0E,D0,28,8A,E5,66,DD,3B,C9,0F,AF,95,F5,73,5C,C7,38,97,0E,89,61,1F,3B,9D,5C,C3,42,56,4E,8E,63,76,38,FE,72,B2,0A,BC,20,2E,AE,15,BA,D2,4C,63,58,CF,3D,E4,B8,52,4D,24,60,31,B9,DA,F3,16,8B,CB,52,CE,EC,49,B9,FA,87,C8,16,16,9E,57,49,DE,FD,56,74,2E,9D,48,2A,EE,BF,C3,C0,AA,32,EF,51,3A,8A,44,1D,A4,98,1C,29,0D,CC,F1,0A,87,14,10,BE,A8,01,BB,86,61,86,09,4A,0F,56,EC,BD,FB,73,78,C7,FB,A0,67,91,BC,67,23,BF,D9,52,48,05,53,44,DF,EC,B9,A0,5D,E4,96,3C,AB,83,48,18,8B,53,C1,32,15,C3,D5,2F,A9,36,79,2B,C0,FF,D1,26,8F,96,6E,48,8B,7F,A3,19,96,3C,41,B7,CF,86,AD,60,B1,C3,E0,9F,0E,FE,13,B3,9D,FB,2C,62,FF,53,B5,9F,72,43,BE,59,E9,C0,D3,05,14,35,05,F2,72,44,69,83,92,E4,8E,B2,7A,55,39,21,AA,96,F5,92,03,D9,DE,50,54,16,1C,9E,9D,9C,00,30,0C,A7,D6,5A,40,59,38,80,E9,40,E6,CE,72,65,5A,BF,49,3D,0B,5C,78,C9,76,DC,02,2E,AA,96,D5,F5,B3,25,F8,50,6B,D6,61,D4,18,4A,96,66,A3,12,EA,49,4C,62,39,7A,52,1F,00,C3,E1,4E,14,D6,B5,07,74,44,16,69,2B,CB,8F,0F,1B,DF,F8,ED,50,D2,7B,DC,A7,96,8F,21,24,4A,F7,87,1F,22,19,E3,86,2A,E9,B9,64,C4,FA,52,A6,A6,46,0F,7B,7A,B7,DA,B3,A2,8D,17,2B,FD,8D,2E,6B,03,4D,49,38,46,79,18,72,DC,90,3C,7F,14,E9,B3,FD,E7,D9,A3,A4,36,11,CC,0D,A6,3D,F6,6A,58,5F,F0,43,58,09,64,EE,46,A6,8F,8D,8C,50,58,90,09,4A,B9,FE,BF,EB,84,E3,55,BB,BB,7A,10,58,4E,F2,80,5C,FA,9C,1A,54,5E,DD,01,BB,98,86,49,7F,4F,6B,65,24,29,6C,3C,AC,31,9B,A2,28,95,D3,FB,E5,2E,F6,E1,38,70,F9,20,86,45,9E,66,88,49,74,5C,A3,3B,FD,FF,2E,5C,B2,44,75,7D,A7,5A,1A,22,4C,92,A5,3C,51,A7,16,39,C2,AC,1B,16,0B,D9,47,54,79,52,58,6D,40,FF,EA,0E,D4,BD,99,EF,93,5B,CB,0B,28,D9,EA,02,C8,B4,71,4A,85,73,E3,4D,C1,3F,92,E6,B5,66,F7,A0,A0,B7,B9,E1,E1,6B,80,7D,CE,59,DD,D4,E0,4F,B5,75,BA,AD,BB,EE,49,F4,19,70,1E,AC,26,C3,8B,86,C2,FB,96,BD,57,58,94,30,22,8E,51,55,28,A0,33,86,E2,2E,EB,32,BA,5D,38,90,21,1C,B9,97,11,6E,1A,66,3A,89,DE,B7,5B,82,BA,14,40,7E,5C,B7,A3,B6,F9,D3,2D,1E,DE,91,59,12,E3,50,DA,4F,93,38,D6,78,7A,C2,A1,13,FD,65,31,3E,FA,02,6F,95,98,57,69,0C,CB,1D,70,38,59,96,92,0B,15,45,C6,90,11,35,7F,77,D1,E2,22,3D,2A,71,94,FD,AB,38,60,B2,66,7E,62,B1,BC,39,5F,50,57,F4,44,01,5D,44,00,F5,54,B0,7A,7D,8D,EB,A9,31,EC,21,CB,3E,84,01,B0,D1,DA,4F,FC,A4,F2,66,7C,1F,5D,2D,E8,B9,CD,EE,E0,8C,16,47,36,D7,B0,F1,4F,47,78,94,FC,C0,8B,D5,0D,22,AF,14,D8,86,85,B1,DF,62,3D,29,C1,D5,E9,CC,A7,F2,03,B8,1F,BA,74,94,77,71,5F,4F,74,FC,19,82,AA,50,E6,01,54,BC,B7,69,B8,06,71,36,6C,DB,A5,F3,B7,AB,B8,C9,3C,89,BD,C2,C8,8B,8A,E9,06,8C,51,85,F0,FF,69,00,20,C8,01,74,D8,F7,2D,42,98,1C,8D,25,51,87,D2,63,92,CA,D3,3E,E2,A9,D6,8D,BB,95,B8,50,97,F1,C3,FB,E3,AE,09,46,26,64,A5,E6,A7,7A,3F,2F,4D,EB,A5,29,23,B1,F9,7A,39,8C,17,CD,2F,A1,41,80,C8,EA,5A,BC,5C,BA,2C,E4,1A,E8,F1,8A,66,48,15,C1,66,BA,D6,34,88,75,8A,4A,79,96,3B,66,A6,78,DE,42,A9,06,97,1D,E4,78,E3,AA,FD,EF,FC,58,EB,82,F6,24,CB,C4,64,2D,71,CA,C2,20,EF,C4,5F,AF,45,59,03,CE,32,92,03,CC,D6,15,60,A1,41,2B,DD,55,0E,18,46,FF,0E,2E,CD,CB,F0,26,96,A6,2F,43,CA,0D,A2,36,E0,4E,A6,C7,3E,48,08,8F,67,08,08,02,07,92,1D,85,C4,60,CF,6A,04,77,A8,CF,04,F6,31,E8,F3,87,BB,69,3B,2F,77,2A,08,6E,B3,AC,78,5B,03,6A,81,7A,A9,39,28,E5,5C,FF,36,62,25,50,F4,87,52,51,7F,00,5A,DF,9C,B7,7D,CE,6F,AF,7C,E1,B7,E8,CB,E0,6C,E3,2A,A0,A8,31,16,E8,F3,12,4D,23,8B,5D,D8,BB,F5,96,C7,8F,2A,45,31,3A,23,D4,68,A3,F1,F6,09,24,A8,F9,42,26,92,E9,84,8E,6E,2F,77,3C,E5,77,2E,D1,FA,5F,9B,C9,9E,F3,C8,82,40,40,38,FA,D3,29,B2,EC,69,91,EA,9F,FB,E6,2C,CD,2D,17,74,D1,99,D0,47,E0,28,A5,05,9C,D6,1C,1A,ED,00,70,A4,4C,2C,C4,E3,FB,75,85,02,4D,5C,91,FF,E5,27,CA,23,0F,95,E0,26,E0,83,6D,BB,44,AE,8D,74,6C,23,5F,6A,CD,D8,4E,2E,F0,27,5D,CD,EE,91,45,30,9E,16,D7,D9,D8,52,EA,54,4C,7E,C3,69,A1,49,F2,94,D3,02,1F,05,1E,6A,18,72,D3,0E,43,1A,79,74,28,13,CB,FA,DB,1E,92,CD,6E,A8,87,D5,49,FE,90,B5,46,AA,C7,0A,15,43,88,0B,50,26,82,3E,E0,4A,8D,7C,9E,E5,F5,47,64,FC,24,21,0A,90,0F,B2,64,AA,66,BC,E7,71,2D,72,44,0A,95,1C,B1,51,D4,08,2C,10,7F,54,57,AA,D9,AB,AE,5C,1E,46,9A,A4,C2,72,CF,E8,9E,DE,5B,8F,12,E3,2E,DF,DA,95,BD,5A,12,F2,4E,73,FB,8E,C4,AA,B2,21,5D,CB,46,B1,7A,61,33,26,EB,9F,52,F9,E9,18,54,09,FB,F8,E2,5F,DC,5B,22,C5,32,A1,0A,C8,70,50,3F,13,90,BC,8F,C4,32,94,A8,EA,3F,C7,3B,E0,E1,73,A2,FE,85,4B,6E,6D,DE,F7,94,43,73,16,D6,30,6C,3F,8E,11,6F,57,09,64,D6,02,B7,E1,DE,7D,9E,72,2C,56,65,36,D5,CB,D0,0C,A2,25,C4,2D,47,72,73,E4,E6,DB,11,F3,63,4D,26,A0,2F,0A,36,3A,7C,7B,75,75,96,7F,6C,C9,97,D1,F5,72,90,45,CB,6F,DF,C4,74,EF,20,49,B1,D8,B2,43,BE,CA,1B,82,EA,7A,83,99,1B,5A,ED,6C,7C,A3,BF,E3,D1,53,9B,A5,7D,10,F0,E1,50,C9,53,B0,29,03,1B,9E,F8,0F,CD,CC,54,3F,45,64,1E,AE,AE,87,02,DA,78,4F,05,58,F0,4E,F9,F9,A2,E7,8C,90,54,9C,E0,40,73,31,5E,F8,B5,0E,3C,4D,80,A8,41,B1,E9,FD,F5,FC,31,28,13,0E,A3,B7,51,B5,56,36,D9,88,73,FD,DA,EE,2B,F5,C2,F1,CF,20,46,BE,5A,87,C4,DB,7E,88,72,B7,23,77,F0,CD,80,E9,AE,07,D6,EC,65,C6,19,11,BD,5D,D9,F9,09,F8,4E,D5,86,DF,24,DD,1F,C7,0D,04,13,95,69,61,91,A3,2C,51,51,21,58,AB,45,89,F1,C4,67,73,A8,E0,59,F8,B4,51,36,29,26,11,76,7F,97,F2,18,2A,26,0E,7A,71,25,71,35,30,A2,62,42,B8,68,DA,B6,4B,D9,A3,F4,CD,EB,B6,77,91,A5,68,4F,C1,19,5B,86,37,75,65,78,7C,39,D4,B0,8F,BB,14,14,05,5D,05,6F,94,A8,19,6C,02,C0,A7,DA,7D,4C,46,C1,2C,76,30,23,2B,48,EA,2F,9C,68,86,8C,08,A4,E8,68,3A,12,CF,BF,F6,8E,CA,B0,64,50,9C,C0,4A,79,E3,07,49,B1,BE,1F,D2,73,52,8F,A7,2F,6C,0D,61,7B,5A,C3,80,B2,0E,49,20,47,07,70,45,18,20,88,7B,BB,00,4E,2B,A0,97,B2,71,2D,C5,33,54,FB,A5,D7,B4,1C,85,43,CC,E0,B7,F7,0C,5E,57,34,C6,EC,FC,16,B1,DE,47,F3,15,78,67,EF,EC,34,A4,1E,ED,CE,10,CF,5F,B1,2F,39,F7,39,BC,94,2C,1D,FA,65,65,3D,47,59,EA,23,8D,91,70,A0,58,90,9D,77,E8,EF,A1,67,F1,E7,13,49,57,15,D9,D0,8A,91,17,80,80,69,1E,CF,90,40,9E,FB,8A,68,CE,96,F4,1A,1C,44,3D,15,4F,68,D9,82,1C,0E,AD,89,79,40,9C,96,C3,96,7C,05,E9,55,31,04,F5,B1,7D,31,B0,CA,E3,F2,3A,13,21,02,06,8E,3F,62,AA,8B,AA,AD,94,48,78,BF,10,DC,0F,61,EE,86,2A,59,C4,3C,23,34,83,C3,D7,BB,0E,B9,5F,D7,7C,B4,1F,A1,AA,9B,BB,39,9A,34,53,4E,BF,C6,CB,DD,01,3D,6B,3C,90,45,FA,D1,03,15,1A,8C,D8,8B,C4,4E,FC,E2,80,77,60,FD,B5,AF,FE,51,F6,42,C9,79,A5,5B,81,B4,FF,51,3B,1E,F8,2F,C3,7D,1A,D4,30,40,5B,47,19,48,5E,B8,1A,65,D0,77,DE,BF,4D,71,58,4C,E0,3B,CB,87,5B,8B,9E,06,A0,7F,1A,40,5A,8C,4C,6F,CA,5B,8A,EE,02,A8,5C,7D,5C,65,46,C2,28,4B,96,F9,31,AC,BF,0C,BF,7E,36,6A,A8,49,59,44,4F,00,85,DD,6E,9C,43,5D,E9,CB,16,AC,CA,9E,6E,35,D0,A9,AA,7F,AE,A9,C0,63,89,68,BB,6E,D4,15,A4,AA,07,48,66,D9,A8,97,23,76,01,D8,F6,FC,EE,A5,94,B7,91,69,FD,85,40,FA,36,81,BD,77,30,64,F9,0A,D2,E4,44,2E,24,22,87,73,BB,D1,00,9C,FA,9E,D8,67,92,89,FA,86,A0,C0,71,36,4E,A5,CF,F7,07,AB,80,5D,E8,B2,48,49,6E,E5,49,0C,00,4B,69,16,74,95,EC,72,30,86,FD,2E,78,88,B2,0C,B8,19,26,16,B7,79,FF,10,05,31,A3,0A,F5,C5,52,18,4C,E3,06,27,A7,AC,48,00,E4,7D,0A,31,82,9E,FC,9D,88,14,E4,CC,28,53,BD,91,0A,A7,3D,75,F0,40,F4,AF,E7,C6,00,C6,F3,2E,FA,B0,42,AB,AC,92,AD,3F,C4,D6,9C,27,10,90,0A,BF,2F,AB,62,0E,0E,99,8D,3B,A7,58,C1,AD,DF,3D,F0,2B,7F,D1,57,B6,DB,5B,6A,4D,D0,8E,21,D6,12,CC,49,C4,4B,D3,AC,F3,CE,68,30,0F,A6,E2,3E,8D,4C,F6,5E,CD,DB,8D,1F,E2,ED,33,0A,31,9A,D5,63,17,E0,81,B2,5F,6B,E1,16,CE,C3,EF,9F,E1,C3,5C,05,A9,D1,00,95,3F,6D,97,EF,A9,82,22,79,27,FA,53,3A,63,DD,DD,B2,29,04,E0,48,13,9D,55,00,19,64,C7,52,F5,A4,3F,A9,91,64,77,DE,38,89,4C,E1,B1,BA,BF,C3,63,F1,4E,93,EC,4D,77,8D,13,28,AC,CE,19,5B,8E,C1,3C,F0,F5,D5,3A,3A,22,0C,13,3D,74,4B,7D,D0,4B,CD,AE,80,42,0E,9A,64,13,34,FC,DB,46,B8,AD,CB,96,FC,C7,70,CF,3B,2C,18,43,AB,4B,96,15,E1,6C,1C,05,A8,44,E6,CE,C4,05,71,7E,54,F4,91,46,89,B4,4B,42,EE,30,4B,66,58,69,4C,90,C4,9B,A9,D8,25,B6,A5,3C,C8,27,38,80,27,02,EA,F4,E4,FD,00,A8,95,A9,9F,1A,D0,31,EB,E3,3D,06,84,D1,B2,BC,7C,AB,2A,B7,07,7E,67,D9,5F,FD,91,7A,46,9E,69,AC,48,7A,69,22,5D,5A,0C,24,CB,79,77,4E,98,B7,71,31,78,1C,31,89,C8,D1,50,74,4E,40,79,10,15,0D,2C,1E,52,70,F6,14,09,24,28,83,C5,B7,B7,B1,54,EF,12,43,C6,8F,DC,C7,CC,3F,AA,AB,05,E6,E7,BA,67,91,85,49,40,F8,8C,3E,3D,68,9C,24,E4,21,97,D6,3A,56,B0,DE,0B,28,92,60,31,C7,8C,00,5B,E4,0D,33,90,E7,AD,80,A8,1E,4B,AB,4C,1B,81,5E,F3,DB,53,C1,2D,41,13,AA,D8,3E,9F,47,51,30,2F,5A,FA,B3,2C,9B,8A,76,D4,BB,17,56,95,55,02,68,64,A2,47,48,F2,32,8B,8C,1A,1E,B5,CC,D3,03,B7,3D,71,F4,45,D9,E4,C1,06,B3,9E,A1,A2,70,44,46,FA,19,8E,28,6C,48,58,79,B0,E1,E5,80,D1,BA,B8,F5,32,30,24,19,24,34,1B,A1,D7,99,FA,B8,0D,DC,4E,52,8E,7D,47,3A,14,59,EA,A7,B2,63,00,18,58,BB,D2,29,FF,65,BC,FC,1B,40,38,4A,5B,FA,FE,AA,A5,78,70,5C,9E,BD,8B,76,A5,BC,95,B3,00,6E,69,2D,5E,72,FD,10,A5,3B,1F,56,9D,F2,5D,31,A9,D3,83,03,D9,AE,C5,3C,60,3C,C6,64,80,84,B7,73,34,E2,0A,F6,BD,59,6D,FD,1F,05,64,5D,65,EB,65,1D,FA,A5,52,18,EB,BD,A7,C5,89,ED,56,1A,74,36,6A,27,41,61,D4,D8,FD,62,46,4C,AD,E4,7E,1E,83,1D,77,B3,F0,50,C1,EB,CB,49,F8,FA,9E,3A,5E,09,F3,79,09,F8,95,5A,99,D7,38,F5,7B,26,77,78,2C,12,DE,6B,1D,6D,1C,E5,4A,A2,ED,6B,DB,1E,0E,81,4B,8A,4A,40,C9,30,02,4F,D9,7E,F5,68,EF,B2,E8,BD,FF,7D,18,4F,10,E7,E4,B1,51,08,08,7F,95,D7,9A,30,CB,49,8F,9E,AB,FA,0E,B2,F8,98,5E,E6,B8,10,DF,11,A0,4E,4A,46,73,84,20,B3,5A,BC,0A,FE,7F,15,22,1B,F0,DA,CF,40,D1,D6,57,37,27,80,8C,92,F5,E6,0F,CC,5B,4D,D5,79,7C,EC,85,8E,1F,53,4A,B1,C5,E9,9C,78,6D,BA,0C,1A,6D,41,D1,6C,F3,3A,7B,BA,A2,8F,B6,3B,C5,04,A7,7E,F9,81,DA,5A,C3,BE,45,EE,45,E7,BF,B1,AE,AF,8F,93,DD,93,4B,B1,4A,EE,B1,39,F2,DA,6B,9E,4F,17,D0,F0,09,E7,E6,0A,66,E1,46,DE,40,CC,92,B6,82,3E,E5,3F,0F,8F,AF,E2,6C,DA,E1,4F,4E,D4,BC,4C,B4,5C,4E,7A,CC,4D,DB,C4,FD,2D,8D,B9,CB,CA,C8,19,76,46,08,67,45,56,2F,C6,B8,15,E3,C9,1D,1E,1D,C3,F6,81,DE,99,C4,3B,5E,9D,B5,20,3F,8F,D5,C6,EA,BE,A3,6E,18,25,FF,93,4A,2B,15,E4,D5,09,88,4C,69,A1,F4,0A,BA,E9,FB,CC,8C,D0,3D,1A,D6,C2,86,4E,99,23,17,38,2F,F1,89,95,74,CF,B3,24,CF,DE,82,50,EB,36,D2,90,4D,17,16,F2,36,5D,18,A3,BA,88,2A,91,A1,5F,20,6F,8E,34,02,6E,5C,6A,03,89,AF,2D,9F,AC,BA,BC,6F,EB,45,2B,7F,8B,26,B2,8E,74,C4,C5,3B,3F,4D,75,26,21,F8,1C,9C,2F,3B,A0,18,D3,0F,FC,36,08,EC,6A,52,2B,FF,83,0A,A5,AF,52,FC,F9,34,CE,A0,AA,DD,A7,4A,36,AA,63,75,8D,A6,06,FB,E3,C0,B5,72,1A,64,B0,23,92,4B,53,05,D8,F1,F3,71,D6,BE,8A,9A,FD,65,A5,F5,1C,6A,90,81,60,43,A5,47,47,57,A6,B7,89,BC,A8,D3,F3,AD,49,68,7A,F0,2E,B4,70,45,C8,CB,D0,73,5C,73,1F,89,36,AF,A8,C7,DA,D0,3A,AB,2F,01,81,9E,6E,2E,9E,B5,AD,7F,21,23,86,2D,7B,A7,51,85,5F,DE,38,4E,D2,C4,AD,65,D2,C9,9E,E5,69,F5,F3,79,FF,83,89,53,02,C3,D7,02,E2,C9,91,0E,3C,AE,D9,6E,C8,59,5F,E2,F9,6E,A4,78,F7,1F,51,AB,B5,29,BC,61,8E,DF,52,65,6B,63,FB,CD,97,25,5A,D1,BD,6C,CB,3A,E5,BE,6F,76,2E,C1,F7,DD,BA,0B,4F,79,8F,FE,78,B4,71,77,1F,30,24,FA,55,61,B9,4C,05,B8,7B,7C,18,D3,C6,0D,59,E6,EF,84,8E,9B,AD,86,BA,1D,B8,B4,6B,A6,DE,C9,26,37,F1,FE,9B,9A,88,D5,DB,FD,BD,79,3D,A8,DB,DA,9B,1B,3C,CC,F5,F6,EC,6F,0C,31,21,1F,F2,1E,C7,0C,69,12,27,E1,E9,40,36,6F,F1,3C,88,70,80,87,4D,2F,13,FA,E5,50,6B,D5,FB,E1,5C,DF,9B,F3,48,7B,0B,20,08,D0,30,50,D4,F5,54,DC,92,CA,5A,E6,6D,4B,92,D9,21,44,E2,BD,C8,A3,2A,A4,7C,1D,8A,65,30,1D,A9,34,CB,B0,EE,96,2A,AA,83,69,BE,B0,BD,8B,33,65,96,9F,CA,87,5C,84,01,FC,3D,0D,4C,52,76,99,4C,9A,D6,4F,ED,C6,55,4B,62,39,56,3F,4C,D2,A2,6B,90,BE,5B,6B,BF,CE,14,1E,77,4D,BD,44,71,12,CB,EE,F7,F7,71,D0,B7,7B,6C,94,A7,0F,8C,A9,6A,E0,1A,8A,89,14,D2,57,7A,E6,D7,4A,99,2D,6F,1B,6C,65,A9,9E,9A,51,0F,CB,C3,3A,C3,DD,A4,44,A5,9D,C5,FA,A7,92,50,49,A9,E3,57,7B,3B,C1,A5,65,C3,7E,34,83,D6,57,56,A7,71,59,1D,A3,B8,85,55,CA,E9,0C,4D,A9,9C,15,51,02,32,E3,BA,C0,89,9E,49,0C,1C,BF,DE,1A,64,4E,4C,3E,76,EC,0C,5A,A0,4F,E4,B4,14,76,03,87,44,DC,12,7E,8E,DD,12,4D,75,BB,D0,1E,D9,68,D4,A7,E2,ED,1F,D6,8C,57,EB,D7,B9,BD,99,D7,FC,B4,E6,E3,F9,8D,50,C6,A3,13,DE,74,E2,6C,3B,9A,10,6E,2E,F9,88,6E,BA,EF,0F,A6,4F,AB,14,F0,5D,96,B9,E5,18,7A,A4,2E,41,DD,EF,15,FE,1D,A6,CE,F0,5A,37,B3,B6,5D,F2,86,A3,1A,74,74,00,0C,3D,59,BF,9E,51,C7,C8,63,11,71,4F,D0,DF,2A,09,BC,52,14,C8,9D,2A,68,88,31,89,92,D7,A6,16,CB,44,A2,DA,9C,9E,C7,FA,D9,9D,D4,29,75,DF,99,95,32,AB,81,0B,D8,13,97,66,F1,4D,C6,FD,A6,C4,FA,E2,1F,6D,D9,4C,C3,7C,19,6F,B3,F2,97,C5,19,57,23,F2,55,5C,B3,DD,42,9C,6E,82,67,5B,8B,FA,62,CE,7F,73,87,F7,21,E0,F9,56,20,98,BE,E2,5F,21,C6,4F,D8,83,82,B5,37,C3,FA,4C,D9,5B,FB,79,F2,27,FD,84,9E,A3,2E,00,BC,72,2A,AE,15,1C,F5,B5,69,F6,0E,4D,55,E3,74,75,2F,43,26,46,EB,CB,A7,CE,6E,5A,38,3A,D3,1B,1B,42,1A,3B,8A,AC,1E,7B,2A,FE,0A,5B,B8,69,E7,B6,E5,77,CE,97,FA,95,CC,6A,7C,31,D4,B8,3F,40,0F,0E,63,36,0F,67,7C,91,93,B9,0F,92,04,C8,BD,C4,5E,ED,7E,E3,D2,D1,BF,58,11,87,80,34,55,44,D5,CE,FB,8F,80,F3,11,D0,7B,81,97,00,40,8E,9D,E3,0D,7E,43,5A,11,72,47,DA,5B,D6,7B,17,DB,23,06,63,1D,83,59,A8,BF,E3,5A,6C,FF,5C,BB,31,3C,96,F8,D5,4D,F5,40,5A,88,89,03,16,F3,CD,84,3E,21,D5,D5,F7,37,9B,86,67,A9,83,C3,D2,C4,DB,B1,1C,3E,57,B5,43,58,7D,8B,2D,91,CD,7F,D4,AD,A3,8B,6C,2D,A2,BF,6B,78,FA,96,47,54,57,1B,A6,3B,71,60,8F,36,68,EF,C3,26,0D,8E,A3,80,58,4E,40,3B,87,6A,A4,1A,48,1E,96,E8,80,FA,28,AD,79,3F,EC,0E,2A,79,0A,2D,73,EE,41,4F,6A,4C,6E,B6,C7,04,E3,4B,3D,17,CA,66,23,5C,2E,26,81,F5,DE,76,71,A1,7D,52,FB,23,82,A0,8C,31,8F,3A,27,CC,5B,36,34,CD,D4,9B,16,E5,2C,5E,3B,A2,96,26,63,52,30,B2,DD,7E,BE,57,4F,1C,50,34,9E,D5,BB,09,22,1B,1E,21,2B,74,08,FE,FF,1F,13,06,48,40,5D,40,7F,A8,48,34,F3,EA,1C,D7,89,DC,B3,C0,C0,59,53,06,BE,0B,82,2B,9B,A5,B8,35,B1,52,C2,42,48,D4,50,4E,E4,12,8C,02,83,E3,86,EB,A7,CE,42,4D,18,EB,6C,BA,E6,39,4C,E8,5B,89,76,C0,84,19,BA,79,A9,E2,95,0E,0F,59,F8,B8,A4,E2,0D,F5,7E,80,A0,47,3C,F6,25,0A,85,4C,1A,08,10,C3,FB,F9,77,BE,86,34,94,99,77,34,91,FC,88,99,F5,08,D8,11,6E,A1,6B,3E,FF,2A,51,89,02,F0,43,CE,25,1C,F8,43,F1,6F,52,61,5A,EC,5C,F6,9F,39,7E,A9,DF,89,B0,6F,4C,EB,A5,6F,DC,1D,B1,28,42,11,29,F9,C4,D9,99,A1,A9,3F,1E,10,70,08,CD,6E,85,15,24,7F,66,53,42,AD,C5,F1,60,AF,B6,04,82,31,C0,BE,39,2B,B5,09,1F,54,54,06,92,3E,55,86,70,A0,BD,C1,70,8B,37,59,77,29,07,F0,F1,F5,7E,5B,B9,1A,F7,4D,AA,75,FD,8E,A4,9C,06,BA,14,0F,DC,F3,CF,82,BF,0A,3C,23,FE,72,E5,CE,A1,F8,2F,BA,B0,01,B7,DE,3F,93,3B,03,50,56,C0,47,E8,6F,09,77,C1,33,82,6C,9B,C7,71,C0,0B,FF,2B,EC,C6,2A,E5,46,26,DC,B2,60,D8,27,6A,DE,47,C8,B2,9D,F0,AF,1E,2A,BE,9C,1C,BE,C1,08,EC,02,D1,93,E6,5C,59,A2,1E,51,72,90,1C,F7,64,20,F0,39,F0,D6,C3,9A,70,6A,78,72,32,3A,1A,6E,73,6E,BA,6E,22,29,BD,5C,2C,64,FA,D6,90,D4,43,17,11,1F,2C,5F,C1,16,A0,30,07,68,68,6F,5E,D8,90,B8,D4,67,F5,D3,53,60,50,7B,DD,0C,43,40,16,2E,15,7D,BB,FE,A3,87,48,B9,BE,3C,0B,EF,F2,1A,AB,56,3E,11,BD,33,46,CC,73,B9,60,22,5C,90,0D,26,AF,1A,44,A6,75,63,99,60,2F,A6,CA,7B,1E,B0,68,5C,EA,DB,88,50,61,23,C8,41,90,21,B8,FF,0E,BF,9B,82,F1,F5,34,1D,2A,F1,B3,2D,42,B0,4E,73,83,D3,ED,72,E9,6C,AE,74,00,F6,28,17,D2,3A,59,85,43,AB,B4,D3,C8,4E,8C,F3,68,3A,02,DA,39,B9,0E,44,B9,E9,7A,62,91,B4,C7,C5,05,89,56,B4,36,56,34,FD,70,73,98,C3,71,FF,D6,74,75,71,2C,4F,63,26,53,B7,F7,26,E7,CA,86,BC,6F,36,EB,1C,BA,59,86,51,D0,F9,B9,C0,B1,17,C7,65,A2,B2,96,C2,92,B2,66,E7,F4,0E,49,4B,2B,DC,F9,66,B9,5C,01,B1,2E,25,45,04,D5,6C,BB,BD,6C,32,0B,17,2A,7F,9F,BE,A4,24,D1,75,3C,C8,33,5E,20,34,7B,2A,93,FC,44,98,B6,D0,0B,FA,05,6C,13,67,67,6C,61,51,6D,95,8E,21,35,FD,B4,18,A2,54,32,F5,F0,62,75,D1,87,E9,19,4A,48,6D,80,F2,7F,68,CE,F9,09,20,2F,2C,29,4D,AA,D1,44,39,F9,E3,51,76,3B,99,4A,95,E4,0C,89,E8,4B,D5,6C,EC,11,FE,82,00,DD,38,56,DD,5A,34,8D,15,43,1A,FC,00,73,BE,B0,0C,EC,1E,14,6D,18,BA,1B,34,CD,49,CE,87,5B,AF,85,4C,9E,64,A7,26,6F,47,3F,5F,B4,AD,AE,3F,C1,05,F6,9B,FD,49,ED,86,65,8C,A7,06,27,9D,28,92,9B,E1,A6,41,72,95,46,E0,40,25,A0,85,FB,B3,DF,8D,C5,4F,64,FB,57,B3,08,41,85,FB,24,89,D6,C6,F0,F4,95,3D,BE,79,19,68,F0,21,E1,EB,1C,B3,84,EA,06,E1,CB,C7,A9,77,C8,5F,A7,56,04,B6,B5,51,98,8C,B3,FE,2D,83,99,68,5C,2E,DD,A9,6F,74,AC,4C,E4,21,E5,1A,81,41,76,3F,B9,2C,E9,62,2B,13,B3,20,7A,17,EA,F5,40,7F,67,83,DE,AE,85,D0,27,AD,88,1A,F6,17,AA,5C,4B,C9,F5,2B,D8,FE,50,12,C3,7F,A6,10,2E,E5,E8,C1,AE,1D,31,05,D4,36,22,CD,AE,27,22,AF,8F,27,86,1C,D6,A9,5D,9D,F2,84,B5,4F,45,09,8F,B5,FB,36,E6,D1,C9,DB,DE,7C,87,F9,C6,E0,86,80,F3,B8,64,A9,3D,E8,14,30,6D,E1,57,97,AB,83,FA,91,E0,26,0B,06,24,E9,36,8C,00,88,E4,22,C1,34,63,D7,CE,0A,63,AA,86,B3,E8,A8,9D,6E,C8,AD,2C,17,77,17,69,DB,4C,3E,71,FA,F1,3B,64,0B,D1,CD,37,A3,EA,C5,A0,7A,CE,8D,7C,1E,71,E3,14,C9,0C,83,2E,9B,F4,98,04,63,53,12,C2,90,05,5C,2B,65,8F,AB,F6,89,E5,A6,0A,E5,47,5E,02,B7,45,F5,20,36,09,93,B3,C6,4C,72,50,42,11,FF,28,1B,2E,8E,8E,A2,CF,73,F2,3B,A9,F9,0A,EE,7E,52,E0,ED,62,BD,9E,9F,36,CA,76,AC,5F,0F,A1,1A,72,9E,36,57,CD,74,91,E0,9E,4A,56,42,27,AF,BE,DA,EB,FF,A8,E5,BD,1B,35,C7,02,CE,E0,26,E3,7A,98,91,0B,6F,4E,76,5A,F8,FC,F7,C3,B0,52,F2,88,A4,74,13,B5,83,53,87,D5,21,C2,B8,06,21,11,54,42,24,FD,C9,3E,5C,2D,F3,F9,B8,5D,80,59,08,3A,E3,48,0E,30,AA,9E,5C,B3,6D,BF,7D,20,68,9A,DA,4D,AC,CF,D4,DD,8D,D0,CC,2B,FC,5E,D4,32,5E,1D,45,21,A5,F8,2F,D6,93,9E,74,4D,79,C7,F8,47,04,37,E2,55,24,55,E2,70,A0,C0,49,13,99,FD,7F,EB,32,FC,C2,D6,CF,F1,B3,62,90,B8,46,E4,84,92,A0,A4,92,1D,68,79,99,91,9A,32,52,AE,A0,E0,2A,00,C6,6B,4B,CE,F8,A5,AC,E6,3F,0C,1B,05,8E,18,3B,CA,40,C1,5E,F7,3F,61,13,1F,A7,59,5A,05,1A,73,F0,A3,F2,E6,DE,0C,E8,72,ED,4C,21,9E,06,85,00,2F,C9,4E,BA,93,3F,C7,73,E4,4E,1B,98,D5,4B,0F,3F,81,59,1F,9B,26,9C,DD,63,36,88,0B,AB,56,7F,27,81,CC,4E,40,60,20,6A,ED,33,E9,EB,E6,2D,05,37,DE,69,93,B1,11,9B,18,80,B8,24,CC,1C,F3,FA,4F,66,5B,D3,06,86,54,FE,F6,A9,8C,0A,68,B1,6A,5A,15,C5,22,88,C7,FA,CC,63,57,D7,FA,C4,DD,90,90,55,0F,4B,11,13,89,58,3B,79,10,E6,0F,AF,E5,8C,0D,F1,29,CD,20,48,B0,28,CB,75,1D,34,0F,0C,A1,07,74,57,19,68,D5,D2,02,AE,61,75,85,95,ED,8D,E0,E2,7C,1C,92,73,BF,28,CC,3D,98,BD,2D,86,E8,15,A3,90,25,A3,9C,4E,CA,C7,18,BD,1F,0A,AF,22,01,38,F5,07,36,17,1A,D3,25,76,DB,55,11,F4,E9,85,13,A4,CA,C3,45,39,72,ED,E8,18,50,FF,FB,54,FF,9C,C4,DB,76,FB,96,D3,2F,ED,92,7A,F4,BA,82,A2,8D,EB,4B,EF,2C,6B,0A,56,B9,C7,1B,E5,C4,F4,F6,9A,16,14,78,16,C1,F5,1F,4B,25,78,45,87,57,1A,AE,B8,E9,C5,48,DD,0A,8E,C5,FD,B6,DC,0A,51,58,27,8E,28,59,46,80,63,A4,93,19,7D,22,B4,08,47,68,79,66,54,52,E7,60,A0,A2,A6,65,5A,45,C9,15,C2,7B,DF,74,AB,1C,D4,6F,75,34,70,A3,9B,96,6D,D2,6F,4A,14,F1,28,6A,7D,DD,D4,86,54,E3,39,26,B5,45,B6,55,E5,39,D5,A5,88,86,BD,BC,AF,11,87,EB,71,B3,5F,A4,31,E1,C7,4C,08,51,F3,E4,4D,1D,4E,A0,02,28,9A,56,DE,F0,82,E4,66,1E,20,A0,ED,E9,B4,49,72,BF,27,4A,0C,6D,09,E7,BE,43,81,1C,16,50,1B,77,D2,37,0C,AA,DA,49,9D,81,59,60,10,53,E4,0B,1D,E1,44,BE,D5,A4,97,4C,02,7E,80,C4,6C,3A,F4,28,00,75,0E,B8,46,53,45,18,50,86,B0,C6,96,A7,D3,3D,F9,18,97,C7,F2,A1,AB,EB,CD,8F,12,14,59,BD,7F,9F,32,B1,02,70,C8,F8,60,09,DE,88,BC,7D,C0,7C,DD,58,56,69,33,28,99,1F,4F,BB,6C,50,5D,94,6A,41,55,D3,C3,74,3D,5D,62,0A,1E,43,59,AF,76,4D,94,EF,9C,C7,9E,38,F2,27,9F,60,9D,07,C1,B5,82,FF,56,E2,5D,F9,20,BB,06,1B,31,57,98,F5,A1,E2,95,50,FB,BB,02,8F,F9,ED,8A,69,84,43,73,FF,5E,32,21,A6,96,D4,05,AB,FB,E6,AE,17,AF,9C,D3,06,CB,33,97,BD,09,D3,7F,7C,2A,16,E0,C8,D5,F6,67,88,BE,7A,56,70,28,C9,BF,A1,87,B7,5D,5C,67,6C,E2,0B,B3,BB,D1,B7,CB,76,A7,29,16,AA,8A,92,C4,BD,47,E2,4A,B9,F1,2B,6A,93,5C,CB,01,98,8E,CB,29,BE,70,64,D5,D4,DB,9F,E7,91,8E,B4,1C,F4,CB,62,50,71,7B,D9,85,67,CB,FA,0E,73,A7,75,56,17,3D,35,D8,E9,63,D8,15,20,FA,DE,BF,15,95,FD,C9,F3,27,18,A0,C6,17,13,24,32,01,AF,21,77,C0,E9,45,13,F5,49,75,F7,59,EF,71,1F,2C,8A,13,A0,19,75,9D,E4,3B,CB,A4,3C,54,FE,76,F6,93,E0,0C,48,C1,8C,91,98,C7,1D,80,89,1B,C5,06,A9,A8,75,75,E2,80,60,0F,97,AB,9A,F9,0D,99,06,7F,5B,F8,90,52,35,CB,A0,F6,C6,63,35,16,AB,88,3D,9F,2B,49,1D,9A,7D,A3,A8,2E,C1,16,DB,4D,79,6C,55,3C,5A,6F,92,B1,E0,56,A5,74,C5,4C,63,C6,45,41,8C,7F,7D,64,9B,C5,09,60,54,B8,4C,41,43,AC,BC,01,D8,6F,B0,F4,23,DB,F1,C3,F8,55,B2,5C,27,8D,64,F6,C0,B7,79,50,E0,30,FC,A8,1B,9C,60,EF,CD,2C,E7,E3,FE,81,AF,D5,B2,00,B6,78,FB,82,29,68,91,6B,2F,CD,86,54,7F,11,6B,CC,87,2B,AF,CF,34,D9,D5,A1,23,B5,74,0C,92,5E,EB,EE,2C,9D,76,1D,FF,92,15,87,7C,64,FE,21,96,2E,E2,FD,A7,E3,94,E3,A5,C5,3D,77,5D,A2,82,4B,36,A9,F1,4D,22,99,56,A3,EB,08,DD,F7,A9,4A,FE,AA,D4,04,5E,54,64,FA,57,C0,56,0D,10,E8,0B,BD,2A,7F,16,79,D3,FB,45,7E,DA,BD,B6,1E,9F,33,A1,B2,E6,71,A2,F1,4E,D1,0F,C4,50,3D,32,2A,BC,1A,EE,BE,7B,1F,F8,E6,4C,EE,FC,DC,5E,FA,D8,C3,A4,AB,BD,5B,23,70,F0,99,AF,F1,CA,C5,47,58,B7,49,F2,47,DC,C6,D8,3D,5E,E9,8D,4B,7F,57,28,06,22,A8,80,55,57,5D,55,FD,9D,1F,ED,2E,7E,CF,D5,B9,37,F2,87,D8,F4,50,04,E4,45,E8,9B,C8,B5,4D,EC,0E,5B,DB,FC,6C,7A,16,E1,DB,22,77,4B,D4,17,36,54,D3,A3,16,F8,1D,37,D7,7C,D9,83,DA,40,5B,72,C4,32,6F,EB,BD,11,52,47,6C,83,F1,60,6E,F1,CC,E8,21,93,D5,8A,3C,F0,00,5A,7D,51,A0,04,04,B9,6F,E3,60,40,2F,50,65,DC,6D,56,42,5D,FD,23,7D,2C,D0,90,9D,8E,B1,68,6B,B1,60,67,E8,31,E0,DD,7E,52,1B,59,BA,6D,8F,DF,AE,CE,2A,1A,68,5B,2A,1E,D9,36,4F,1C,1A,7A,E3,73,47,37,62,62,8F,64,EC,01,6B,DC,7D,DB,F3,D9,68,25,DF,06,0A,E0,26,62,6E,F3,2C,39,0C,54,93,B8,37,32,4B,EC,D8,EB,C9,40,F5,96,F1,B2,EE,C4,A2,1D,8B,1D,98,D0,3E,73,5D,A8,AD,C1,76,77,03,0F,77,4C,E2,29,1A,9C,A9,A6,B9,ED,20,4A,62,E9,9F,CC,9A,77,1E,F0,C1,A1,85,53,90,37,12,B2,9F,D3,8E,2B,6E,E7,A0,FB,11,23,CE,1A,15,A3,08,10,35,83,D7,A1,EC,9C,B4,FC,71,B3,7E,4A,0F,D6,13,5C,2D,7D,D4,5F,35,EF,06,01,8B,FB,BF,42,BB,5A,8A,71,7E,1C,B0,02,4F,5B,FC,00,37,68,DE,4C,57,72,DC,DF,ED,81,17,38,8B,85,D8,C3,A7,6C,BC,8D,00,00,9C,E9,8B,0D,6B,B8,D0,E6,70,3F,92,F9,FB,E6,80,68,D1,C7,CF,8E,B3,EC,49,B4,6A,07,80,DF,3C,9A,DF,0A,1A,66,14,5D,7E,7E,B0,70,11,30,F8,48,34,42,95,3C,C0,A5,A4,E2,06,92,5D,55,7B,A5,E8,95,B2,8C,EE,2F,1C,D2,4B,C5,BA,78,31,56,85,CC,17,58,C8,E0,A1,A0,1E,9A,2D,5B,16,63,9F,7C,9B,E8,3C,17,31,1C,33,8D,5E,61,F0,89,40,84,77,96,99,BF,A9,01,0B,86,C3,8D,38,4A,F1,4E,BE,05,7D,29,81,67,23,C0,75,4B,E4,B4,83,08,F1,84,25,9F,4D,B5,96,BB,F8,7C,80,F4,5B,D7,13,52,A5,DB,D2,F9,BD,7D,E4,4D,98,3C,2C,0E,42,E2,7B,42,7A,9D,D8,26,3E,B9,16,22,65,49,0B,DC,82,4E,0C,5D,38,A9,97,01,BD,30,4B,E2,61,50,19,77,AF,19,DF,DE,86,DA,3D,16,17,D2,AC,46,10,0E,3B,51,A8,5B,EE,C2,C2,EF,4E,62,24,3A,4F,BF,A3,16,51,9C,87,3C,22,74,77,E1,3F,F9,E6,A4,34,39,C6,2B,E7,62,C9,6F,CF,D2,DB,14,41,A1,63,65,C4,1F,30,6B,F6,8F,A7,C8,30,2C,15,3F,4E,41,74,BB,17,5B,07,BD,02,B1,A1,D9,DE,EC,D4,61,95,17,9C,5D,DD,F0,42,A5,56,CA,CE,86,0A,42,A3,06,D9,56,7A,50,DE,B4,22,EE,2A,1D,54,C6,E5,20,42,89,A3,60,3F,E5,76,5F,E5,DE,C7,E8,4D,E3,3F,8F,A4,99,79,B1,DA,D8,2F,B0,DC,84,C0,AD,EC,DD,0A,17,87,6E,AF,FE,CA,D1,98,8C,49,09,B1,70,77,03,F9,DC,4D,D6,B2,96,92,E0,B1,B5,5A,35,09,14,9E,BB,FA,92,DD,CF,1F,14,13,72,BA,BE,C9,CE,27,90,B0,AE,1C,9F,F5,F2,12,87,6D,64,01,01,38,A2,42,1D,B4,76,0B,6C,A1,6E,51,05,A7,19,4E,10,67,5E,8D,0F,5E,A6,C3,03,D2,7C,FB,B0,0E,98,AA,65,6F,A0,33,95,1E,14,25,6E,76,D8,17,23,13,FD,B4,DD,C6,34,C7,0A,3F,FC,95,E5,71,10,60,47,66,A3,2D,D1,38,82,1C,2E,3C,35,96,30,C9,75,A9,7A,7C,97,27,E7,7B,0D,E7,21,94,C6,58,76,93,43,E9,E7,CD,DB,F8,E6,DE,8A,95,73,FF,1F,C6,9A,D9,3C,F0,3C,89,82,9B,AD,57,CC,98,6F,5A,AF,CB,17,94,87,C5,D0,79,C1,3C,AF,72,A4,C4,03,31,85,C0,8E,70,7C,C2,B9,4B,A7,29,05,0F,D0,19,D2,1E,59,73,3E,19,84,63,D5,77,0E,59,CF,8C,5E,17,36,DD,92,98,E8,39,00,CD,CF,DC,B8,C9,A4,8D,B0,BE,5B,B3,CC,E5,F1,CF,04,80,D6,30,B3,ED,C1,B0,B4,57,B9,0D,AD,7F,20,A0,71,BE,15,A7,08,75,6C,A5,A2,60,E1,44,59,29,CB,6F,6D,13,02,CA,4B,D0,20,AE,E7,05,65,69,B1,F5,9A,51,15,34,7F,3C,57,40,BC,70,D4,94,0F,92,92,39,41,A4,2E,3D,B9,9E,B5,65,A0,DB,DC,E3,78,51,02,02,81,DB,91,EA,3F,5A,00,2F,CF,11,7E,D3,B9,13,FC,54,25,22,6D,74,CA,E7,A5,F6,F7,55,02,98,07,17,6A,95,43,CF,BF,5B,38,80,A5,D3,D1,E1,DF,28,42,F1,63,DB,08,9C,FB,A4,8F,ED,3B,10,E5,8E,7F,CD,B2,BF,E8,B1,19,CB,6A,52,B4,87,2C,F3,A0,3D,73,56,6A,E6,E5,D2,61,78,D9,E9,F8,5D,6C,43,68,B6,9D,2A,40,E1,C4,19,3D,F3,08,08,5C,74,CF,F8,E0,78,8C,50,88,70,29,89,11,C4,9E,24,4D,F7,2F,42,9E,57,6A,68,E5,28,82,9C,BC,87,15,F0,C5,3C,F7,C1,FC,5C,AE,36,DC,CE,DD,A0,9C,40,79,B6,94,06,34,98,27,3A,9F,D0,06,C2,D9,1B,1F,3F,60,8D,AE,8F,D3,83,4D,BE,34,65,1C,FC,BE,79,6A,47,BF,E9,2B,67,3D,3E,6E,48,0D,07,7A,BC,76,10,71,2C,7E,E6,C3,4F,FA,09,4F,52,1B,D6,FC,D8,94,2F,47,62,5E,B9,F2,5F,67,16,2C,5A,E5,4D,8F,1C,0B,D9,13,54,AA,A2,92,B5,89,80,47,53,B0,E7,2A,14,86,C4,2F,15,6F,ED,91,80,A2,23,C2,77,52,6F,2E,93,2F,90,33,B0,19,2C,42,F2,5D,7E,9E,4A,C8,3D,A0,6E,D1,50,14,3C,78,BF,F1,21,6D,8E,A5,02,D3,E4,92,0C,90,6C,B6,35,A4,FE,2C,F0,9C,8F,29,9C,04,31,09,F3,14,E4,13,5D,92,7A,B8,C2,CF,98,B4,88,75,DE,1E,A5,35,F4,89,BD,F4,29,51,09,17,58,8B,4B,FB,F5,04,5E,64,B7,24,B0,D1,4C,52,A7,7E,1E,71,3A,1D,52,24,34,C3,3C,CA,68,E1,12,0B,76,2A,EA,F6,99,AA,BB,CA,0B,2E,94,5A,31,93,FF,41,48,DB,C3,FF,09,2A,1D,3B,2A,5E,16,91,B2,67,AB,48,0C,B2,E1,D2,69,F2,1C,F5,DB,5F,DD,FE,C8,0F,58,37,4B,89,91,9B,07,D1,0E,42,A8,D4,D9,DD,8A,01,A4,BF,5E,89,3E,13,E1,F2,CC,A2,DB,BC,B0,29,EF,54,35,35,8A,0D,9B,5D,88,D9,14,20,E4,57,A6,BF,18,65,8C,AD,6F,9D,27,FF,86,13,65,AB,99,F9,55,4A,4C,EE,A4,B9,A4,43,AE,8F,66,BA,EC,B3,FE,76,DE,B1,D6,08,E1,5E,B3,22,C1,DC,05,03,84,90,5D,3A,A5,C4,93,18,A9,71,54,85,D8,A8,B9,A9,05,E1,66,EB,64,89,76,33,91,E7,1F,BD,8A,CF,21,C6,30,95,C1,A9,4C,8E,F3,F3,8C,6F,2D,F7,8C,7A,C2,43,CA,5C,E3,AB,C4,04,0A,15,74,14,61,DF,F7,77,9F,45,F2,F6,82,ED,3D,5F,2F,F2,00,FB,B7,00,B8,FA,9E,13,40,10,9A,F3,1C,54,FD,11,03,31,26,06,9C,A7,7B,F0,AF,2B,3C,5C,70,62,C3,C5,9E,93,A0,B8,0B,59,2F,CE,98,25,AC,D6,E0,6D,8E,5B,BB,2D,26,B3,7D,E4,52,D9,3F,9C,9D,72,DF,76,8F,CB,98,64,C3,97,98,F1,EE,88,AF,81,E4,18,FA,84,DF,9C,56,AF,2C,09,4F,C6,78,DA,D1,04,15,B8,78,24,34,BB,58,66,5C,BC,1E,75,1A,07,CA,95,32,CC,06,6C,B5,D8,4E,47,D6,1E,A9,57,8C,3A,26,E1,38,66,EA,87,66,62,2B,39,BD,12,46,3B,CC,D0,4B,64,64,AB,BF,27,88,09,17,15,31,09,79,BE,CC,33,52,3F,46,6F,B2,58,DF,64,BD,19,6D,FF,9F,6D,32,43,40,DE,89,AB,BB,FF,C4,81,24,C3,15,5A,22,97,65,65,B6,05,FD,19,49,73,E8,25,6F,54,22,9A,A6,1A,F6,13,5B,71,30,D8,EB,6D,9A,67,E0,9E,7E,E3,4C,59,76,21,13,3C,60,20,3E,8F,92,85,D7,72,92,96,D9,E2,2D,E6,66,57,7C,E1,E4,63,A9,AF,11,4F,B8,FC,A5,8C,E0,CB,EC,CD,BA,B6,11,54,5D,85,BF,CF,40,A3,29,80,8A,62,1A,F8,F8,0A,CD,A7,DB,B7,F5,1C,81,9C,EA,63,F7,A2,04,0C,A2,FC,1F,F8,A6,09,6F,7F,CE,43,05,6D,C0,62,D2,4D,E7,41,4E,08,F8,01,E1,02,D1,C2,28,79,5F,E6,69,16,A1,7D,DE,2B,3F,1C,47,55,88,58,73,62,F6,7A,20,E1,88,B5,0D,71,F7,B8,A5,14,D5,9D,67,12,E4,19,56,EA,CF,4C,0C,D1,E0,DB,C1,6C,7C,A3,88,FA,35,EA,29,AE,F0,8F,99,29,C0,03,06,06,A9,7C,39,8A,46,4E,F3,FA,E1,8B,B4,F4,FF,CA,F1,80,28,62,5E,CA,AB,C9,02,55,AD,FE,FA,7A,0D,AB,D6,7B,51,CB,F8,A2,84,C4,6A,12,75,8A,C8,2A,64,7D,28,C0,3D,BE,0B,BB,09,C7,40,58,9F,36,5E,EF,42,E0,EF,0B,51,45,66,9A,E6,2E,87,86,BE,3D,BC,05,03,66,D4,5E,49,38,5A,D5,11,E2,80,A8,0B,14,CF,55,88,23,0E,EC,BE,1A,A5,C0,F5,68,05,79,72,10,2A,0C,CE,94,BC,17,9B,B2,43,47,1B,9B,37,31,33,35,06,18,48,41,91,AF,33,6A,CC,FB,C4,68,3E,23,AE,26,B2,C4,92,E1,C3,A9,3B,CA,F1,98,96,60,1A,85,A7,29,7E,80,EC,6E,70,BD,71,4D,47,84,7A,0F,2F,10,93,B4,04,3D,6A,99,6A,73,DF,6F,6D,79,E3,01,82,A5,3A,49,E8,AC,99,05,20,50,A7,04,83,C7,8E,A2,EF,45,48,E8,AF,CC,F3,42,C0,DA,43,B2,41,3E,4D,11,0F,6C,E8,57,FA,E9,81,24,29,78,CF,F4,B1,72,96,3E,F3,69,84,6B,4E,81,BB,24,76,B1,BA,0C,D7,DA,1C,C8,9E,C4,A1,03,9D,9D,55,B5,4A,AD,A2,B9,92,F3,BE,8C,5E,05,B7,1D,E2,33,28,1E,25,DB,4F,12,5A,52,14,82,80,F8,94,F4,54,0F,35,44,5B,44,17,09,14,C7,DA,2C,4A,2F,91,BD,43,D0,B6,5E,C1,3A,5C,7B,A4,49,12,7E,ED,54,05,81,88,93,3A,F2,1F,C7,C3,4F,68,2B,F5,EC,BE,17,F8,13,BB,1D,10,71,93,AD,32,48,2E,47,B3,4C,B8,88,D6,C8,CB,DD,9F,0F,3D,5F,F3,59,87,C6,9F,05,F1,84,15,19,E1,5D,4F,A1,49,D8,30,F9,96,2C,CD,37,E2,72,D9,24,7F,D1,6A,CC,38,DC,D8,9A,4C,CE,2D,34,63,85,D5,CA,32,9D,AB,B4,7D,96,72,66,77,5E,D4,BF,08,7E,44,EE,B8,01,9F,8E,C8,40,D6,02,3F,49,86,9C,AA,8D,4B,AD,EB,41,24,CB,48,55,82,34,F3,4A,AD,ED,C8,67,1A,2C,17,D8,69,2F,18,C8,6C,77,F8,7D,B5,B3,B1,A1,37,E2,9D,FC,93,CD,8C,B4,A2,53,F8,54,DD,C0,71,B4,EC,89,A2,17,C8,60,30,7E,8F,A5,15,B0,DE,06,24,BB,21,5A,1A,78,7B,DC,88,25,06,02,05,C1,1A,97,67,EB,B7,6B,8E,06,62,AF,73,9B,F9,82,AE,AD,95,EC,39,4A,03,A8,58,C3,16,F2,28,36,CF,2C,B4,58,3D,10,82,F5,41,2D,53,30,33,F0,5E,47,BF,75,A9,E1,9F,48,5C,D4,0E,60,F6,61,16,F6,8A,45,AA,6B,1D,40,05,0F,7C,94,1F,9A,99,5E,71,79,5D,8A,4E,A7,91,06,B8,3F,5C,48,4F,7C,C5,40,57,02,CE,6D,57,2C,79,D2,7C,2F,50,39,C1,6B,68,07,36,04,92,71,26,2E,36,4A,F9,20,2B,37,31,78,92,26,04,60,35,5F,FF,30,25,A8,3F,0D,FD,78,49,B5,9C,54,30,2D,FF,20,37,14,19,25,2D,78,A4,DC,EF,B3,A5,8C,30,0A,6A,88,30,F2,E7,7A,9C,86,79,65,4A,11,9A,62,FB,0A,8A,33,EE,52,68,46,E9,E0,38,5B,DD,29,DC,12,9C,CD,A9,99,2D,33,E8,81,FD,A4,CA,15,6A,AF,93,7C,6E,65,6F,9D,77,FE,F1,C5,38,30,0E,81,B5,57,B3,80,66,D6,A4,5D,B9,2B,67,91,53,55,F1,EE,ED,FE,7D,5B,7D,91,63,7B,26,58,7B,A5,2A,5D,45,35,05,07,C4,F6,77,31,93,75,D8,A9,63,F0,89,D8,06,D2,C8,67,0F,84,32,D2,E5,1F,71,C2,1D,FE,4B,06,A6,B9,B5,0B,88,7E,88,62,F3,CC,C5,0E,6C,EB,CE,F8,B1,21,B1,93,52,30,F3,93,B5,CA,BA,5F,26,5E,AB,9A,7E,B7,2A,2C,48,EB,22,98,E2,8C,31,F8,4E,4C,FD,C5,35,98,A2,EC,D8,07,C1,32,B3,AE,AB,35,73,A0,CA,56,0C,DA,2E,AA,DC,F3,E8,E6,7E,50,2D,91,B8,A9,24,C3,3C,72,09,A0,72,C8,9E,04,10,DC,AA,9B,A1,68,EE,FD,6F,C8,EF,31,23,22,4D,B9,3E,FF,3D,56,57,13,9D,AF,9E,21,BF,69,00,67,AF,92,2F,D2,88,4F,31,08,73,C1,D3,22,E2,75,3D,95,EC,2F,0F,B1,B8,89,C6,EC,43,2F,62,53,6E,0C,5B,A5,DF,42,52,53,26,80,0A,22,F6,02,09,04,FE,83,F2,26,A3,1E,42,2B,2C,21,64,11,85,56,87,D6,99,16,F7,9E,13,AC,08,27,ED,84,6F,C9,A9,BE,E9,06,EB,CB,61,3A,95,99,DD,5D,D2,60,EE,46,A5,60,A9,7F,1E,F9,69,A8,F3,91,94,D3,4C,7E,12,51,DE,E4,90,E1,91,9F,23,76,FA,A1,A3,0A,00,61,8F,FD,1B,B3,A1,8A,19,DE,B1,53,0B,47,A7,F4,B6,37,91,5B,6D,7B,55,A0,7D,12,9A,04,27,0B,DA,80,D9,A8,FD,1A,F8,25,0C,BC,BA,E0,4F,1C,6C,CB,DE,A5,77,F1,F6,61,16,E1,3A,4C,C8,54,1F,CB,AB,C8,31,6D,BA,4B,04,1F,36,98,D7,6B,0C,E5,D3,92,12,D9,E1,14,F9,EA,D0,68,21,56,63,E3,E6,91,62,53,8C,1A,95,C4,54,66,E7,13,B5,3F,47,FB,21,D1,FE,A6,6E,66,AB,1D,55,F4,5C,5E,E5,6C,D8,9F,29,0A,8C,44,8E,B2,D8,01,67,66,7E,86,BE,A0,B2,4F,55,CC,F8,12,52,BB,26,8C,BC,AC,78,9A,34,73,CD,C0,F9,DE,24,2B,1A,B2,5C,0B,84,28,C3,70,C9,ED,C3,AE,A0,9F,43,5A,A5,7B,7B,CF,A3,0A,93,57,16,2D,F7,75,FA,11,E8,D2,91,03,BD,3F,B1,3A,9A,48,FF,E7,A8,0F,F9,D8,97,5C,2E,09,2A,8D,CE,AF,37,E2,41,20,95,04,66,CF,BF,44,74,21,A5,69,8C,9D,17,CE,5B,13,DC,4E,00,F5,1F,22,A5,80,15,DA,61,0E,1A,46,E6,DE,32,C9,94,6E,A0,12,60,13,2C,27,B7,55,7B,8E,FD,26,95,5C,69,29,F2,88,EE,9A,F6,BF,B4,05,3E,83,0A,07,0D,C4,31,D9,67,D8,B2,99,7B,A1,0F,80,5C,9B,D3,43,15,31,39,BA,76,42,F2,03,49,E1,D8,CF,1F,E3,1D,07,5C,12,1A,E0,BF,A9,71,FB,31,86,87,96,62,DC,C4,A3,FC,0E,C7,94,F1,91,D2,BA,8F,B4,46,15,B5,98,8F,34,FD,2F,59,DA,D0,1D,B9,BA,5A,D0,D6,F3,C4,2E,A2,8B,40,1E,0B,C3,A3,9A,19,31,96,67,8F,01,B7,DF,04,C8,B6,30,B6,04,C4,D7,F2,5E,F5,67,B0,12,7A,A6,F7,CB,45,D3,21,B6,CE,73,D3,86,4F,15,1A,74,1F,35,50,73,78,B9,2E,CE,22,AD,F7,98,5A,4F,A6,B8,AF,D2,84,94,25,E5,02,03,D5,3E,1A,EB,D3,51,09,92,D5,06,32,F1,F6,79,E4,99,9E,2D,C5,7C,FB,91,C9,99,A5,FC,24,A4,B1,44,07,35,A2,FA,56,42,F4,C9,4D,72,F5,9E,E2,7A,FC,F1,38,58,A8,94,14,C6,E7,A3,FD,EC,22,50,34,E1,35,A5,F0,CF,03,67,C2,BD,A6,F3,45,BB,15,F1,D8,BF,68,47,DE,F3,1D,27,1B,56,12,65,32,03,F1,60,4A,3A,0A,0A,8A,0B,96,C2,33,E4,6F,81,3B,E6,31,22,0E,9E,83,89,C9,40,7C,B9,C1,69,E3,20,58,72,D1,A0,E4,D4,AD,9C,FE,6F,50,AF,FF,BB,02,DD,25,66,A0,EA,2A,BE,31,B7,EE,53,4F,1E,94,40,8F,FC,8B,3D,BD,1B,5F,6A,C0,B4,DF,14,04,F2,9A,5C,26,27,94,0A,8C,BE,C4,04,1B,40,0C,32,6D,AA,0E,B5,20,19,A1,EF,ED,21,09,59,A5,F1,C6,D1,7A,B5,96,DC,EF,E0,F3,A6,1F,B1,BF,88,D1,5C,96,9D,66,F6,0C,B6,73,24,9D,A5,3E,22,61,80,9C,19,CC,E1,B0,D0,EC,64,4A,83,F9,01,5A,9E,DB,7C,27,F8,6F,21,E0,A8,20,BC,22,C8,F3,A7,94,2C,77,98,77,DC,6E,B4,59,EB,9A,05,90,CF,63,06,B3,10,33,69,69,8C,11,EC,3A,CE,22,46,57,CA,7C,19,EA,DE,52,D1,0F,18,1E,EE,F6,5D,7F,A9,B2,DC,4A,83,D3,DB,50,84,D6,8F,97,B1,43,6A,93,BB,8F,3A,F0,2F,AD,5B,83,CC,5E,26,8E,97,F8,49,B9,51,52,7D,CF,36,C9,80,C5,25,41,A5,AA,B3,FF,66,25,5A,83,92,97,9C,08,EC,4A,33,C6,5C,FD,4E,52,91,D2,03,6B,4B,CE,45,8E,FC,72,36,47,6B,61,EB,40,D6,4D,D5,2B,87,98,B6,29,DF,53,41,7B,19,02,FF,4C,23,9A,0E,C0,CC,16,A1,5D,01,3D,AC,AA,8E,C4,47,74,91,21,1C,D0,B8,41,FF,98,E9,62,BA,A2,11,AC,1B,B6,51,70,EF,E8,81,D3,B5,4D,2A,29,62,C3,98,86,F4,A2,29,FA,84,7F,57,40,7E,4E,12,42,A6,45,56,82,3D,9D,15,3D,33,04,73,4C,D4,71,04,F1,E9,2A,5B,CE,94,13,54,50,30,91,4E,8E,70,1E,58,BE,80,7E,22,5F,16,7C,CE,C8,A3,A5,2F,C7,E6,52,16,09,62,9D,DA,E3,49,0B,E5,08,03,30,3D,99,E5,43,EC,EF,7C,AF,F1,56,9A,65,DE,34,12,58,31,64,65,3F,A4,D8,C9,F7,C7,20,ED,93,C3,B6,3F,1D,EC,CB,D6,F2,20,2D,5E,1D,45,FD,A0,73,16,EB,FC,23,AE,57,A8,11,6E,32,95,9D,5F,3B,38,5B,7B,27,41,6C,29,89,C6,77,42,47,BF,42,E9,3D,95,3E,1A,14,DF,74,52,58,DA,25,19,FB,91,67,93,27,12,53,47,7B,2F,3B,84,28,DD,C7,3B,E1,51,E5,B5,C3,7F,45,A1,4E,7C,8C,72,A4,8B,00,59,31,D6,2E,3E,14,33,6D,B7,AF,ED,9B,47,22,A1,52,13,CD,BE,1A,78,22,D2,CC,33,27,C7,C4,B2,56,00,36,91,73,21,6B,14,F6,0D,84,A2,E2,CB,57,16,B2,37,31,4F,12,DF,49,DA,22,B3,87,32,3F,C3,D4,16,2B,FD,90,D0,DD,6F,52,D7,B6,D8,2F,21,79,BC,CF,E2,A4,E5,20,DF,AB,30,82,87,DE,DF,22,69,EC,FC,62,6E,68,D3,CD,FD,14,20,81,CB,79,11,6F,56,F6,54,D1,5C,DE,CE,A5,24,48,87,26,96,41,27,1D,EF,E4,9A,9F,EF,30,1C,DE,73,5C,A1,D3,19,06,5A,04,8F,A3,F3,17,35,F3,4B,93,A9,FF,3E,01,B2,C3,42,1E,68,67,AF,34,43,BF,07,EA,09,D3,1B,42,F0,3A,6D,1B,B6,C5,05,8F,F3,5C,61,30,04,C3,62,4C,A1,2E,5A,21,BC,77,79,D9,72,B3,4A,76,D0,7A,86,13,1C,30,BB,A2,5A,76,57,21,9B,5B,15,FD,DC,F2,39,17,6D,3F,A0,45,CC,CC,19,6A,41,89,3C,7E,8B,57,DC,FA,2A,19,E4,AF,A1,A1,38,2F,B4,C1,39,A7,29,B4,28,3B,C5,7F,AE,5D,6B,F2,92,7F,EF,48,ED,43,2E,1C,4B,A6,D2,F0,BA,1F,20,40,D9,49,0D,B9,20,AB,9B,3C,1F,5F,05,3B,5C,3B,B5,83,76,3E,A7,1B,FF,5D,B7,81,41,B3,2E,97,E9,AE,77,36,37,60,03,CA,2E,51,3F,50,F1,53,E1,63,58,44,41,E9,05,4A,A5,CD,0B,CD,E9,18,6A,80,60,0E,90,26,2C,8D,59,F5,37,B7,94,EB,C8,72,A1,C1,DD,8A,5A,79,E3,20,D6,C6,AF,AF,29,D1,B4,55,57,11,3D,25,F4,25,56,CE,2F,C4,A1,08,24,7C,1A,99,F5,8D,01,B6,5D,3C,F3,6B,1D,37,FF,8C,5D,3D,F6,F1,05,93,5F,AD,78,0C,1E,EA,64,4B,9D,B7,6E,C6,DC,D2,A2,2C,F2,92,DB,F4,5C,1E,5A,7C,4E,9E,6F,CE,03,F2,89,E6,10,5D,2F,38,DA,B0,23,EC,B5,4E,51,8F,CB,FE,E0,D4,3D,1E,48,D6,B2,B4,EC,09,E1,6C,A2,BC,E3,31,97,CE,02,5F,C4,79,AF,71,5C,8D,ED,DC,AD,94,47,06,07,FE,EF,B2,E7,CF,AD,82,E9,B3,96,FD,3F,53,9C,3D,0E,98,18,74,52,2C,85,E7,25,5B,FC,94,88,2E,F4,F2,9A,08,D3,0C,65,A9,CC,57,6B,87,56,5A,12,E3,05,9B,02,30,EC,D0,2E,93,C4,0A,9A,CD,9A,88,D5,43,B4,72,35,E3,79,52,DF,C0,29,0F,A0,36,BC,30,60,6F,B3,1A,C2,AC,D8,56,ED,CE,E1,1A,DD,F1,11,A2,67,89,66,9B,5B,5A,81,57,76,BA,96,1E,67,B8,9E,77,E5,0E,88,A3,65,4A,90,FA,4D,31,A0,0B,35,D8,DA,85,36,AB,95,D6,D4,E7,98,25,50,7C,ED,F9,B5,27,96,C5,0B,8B,34,A8,7C,D0,51,89,B0,AC,D2,85,78,2E,BD,0F,0D,52,61,C1,B6,25,5D,B7,6F,4B,4C,86,71,B1,98,FA,F3,A2,E4,8F,51,FA,31,4A,F1,76,D9,8F,2F,DA,E0,11,4D,DC,5A,10,A1,10,AF,2F,78,AC,84,D7,30,E2,F9,2B,16,22,38,E5,84,2C,D0,03,F1,EE,BD,BE,9A,CA,FA,65,A1,4E,EF,A3,A0,E7,9D,95,C6,6D,6D,9E,70,16,01,A3,1E,0E,98,44,F4,E8,5C,A3,B1,95,65,4A,68,5F,94,DA,E4,42,92,C6,BE,AF,1A,6A,D7,6B,46,67,53,68,F3,86,93,B2,F2,84,A1,A6,91,2D,04,36,2F,8E,8F,82,1A,A2,21,59,46,B3,FF,77,D8,C6,6F,F7,3E,C1,A4,64,4D,2E,67,07,06,18,D1,CE,45,63,02,D8,37,82,7C,4B,CA,89,41,44,91,98,0D,1D,B3,40,8C,B9,D7,25,54,8E,F1,10,AF,EB,41,23,94,56,57,AE,53,8C,64,8D,A0,C5,DE,0F,78,98,83,ED,65,5E,C5,06,B9,65,28,0E,82,C3,8A,34,37,B8,21,CC,E6,13,21,09,F6,9A,48,2C,70,EC,2D,34,3D,7D,A3,98,BF,46,41,4A,B3,BB,7C,44,93,8C,D7,EA,8C,99,8B,4B,C0,57,AA,CB,3E,8B,EC,2B,2D,C1,92,73,54,FD,AA,9C,4D,D4,D8,C2,C6,88,2B,1F,27,01,F1,AF,B8,E7,F4,D2,DB,41,42,B1,89,2A,7C,DC,8B,B8,4A,E8,50,75,B2,72,B4,22,11,B5,76,FC,02,F7,68,68,0B,05,BE,96,B4,F3,80,44,46,E3,5C,9C,DF,D7,D2,E3,6E,BB,A2,C5,61,BF,5E,B1,06,6A,FA,DD,88,F1,51,47,CA,19,4A,AE,8F,D9,B7,80,8D,32,2A,A7,14,50,E5,9E,B1,DC,0D,D0,B7,55,D6,86,D6,67,C9,DD,87,A4,0A,31,77,A2,C7,5E,49,54,04,07,32,61,DE,40,64,20,E6,C6,E9,1C,2E,2E,EE,BE,A8,E6,4E,33,58,01,12,E9,34,7B,3D,20,C4,33,CB,02,04,A6,3A,15,75,75,3A,D8,D7,2C,41,B5,8B,7C,BE,08,9C,83,96,BD,34,59,F9,CE,A6,9B,01,AB,B7,AF,52,34,44,68,AF,D9,16,75,35,E3,0E,B1,95,23,96,3D,90,62,B2,0D,05,5B,54,28,CD,BC,3D,B5,CC,24,23,B0,58,82,54,A5,01,3A,74,08,67,1E,3D,27,BD,0F,27,63,E2,3A,FB,BD,77,15,56,1C,45,1D,B9,06,C7,2E,5A,1E,EB,62,E2,DF,29,30,77,B7,44,42,FE,E8,13,15,E6,B4,EB,8C,23,5E,2B,73,86,F8,87,E1,00,E5,63,FD,65,28,C5,0C,5A,29,DE,AF,7D,5E,98,8B,FF,CF,E8,82,E5,1E,F7,BF,43,EC,91,2C,7A,4F,14,B2,AF,74,A3,43,D5,C3,B1,56,9D,BB,C8,2F,49,81,48,86,96,B6,9C,C6,A0,99,F3,6C,56,71,14,78,78,7E,5F,41,55,7B,58,68,6E,D2,BD,01,7E,8F,15,81,1F,86,68,0D,9B,5E,16,D5,5B,C9,89,E8,1E,70,94,AA,D9,79,7B,12,A0,7C,A4,F7,FD,91,2D,2A,7E,66,81,63,32,9A,00,94,49,F2,7D,3C,81,A9,18,39,9D,EA,41,9C,F7,A8,A8,5E,E6,D8,70,C9,7F,0B,0A,EA,04,15,AF,F5,1F,54,07,F8,B8,49,82,A2,56,26,22,2E,FF,86,BC,E4,BA,68,86,C6,CA,38,8C,1F,60,41,2F,F4,CC,A8,CA,C0,91,92,45,81,09,C5,63,64,C4,D6,82,00,00,6B,03,5C,43,7C,9B,93,53,BD,EE,AB,BD,2C,DD,C8,6A,26,06,A1,8C,A2,AE,EE,09,67,F5,C8,87,5F,2C,BA,2D,EB,F2,43,91,A0,97,12,97,0F,61,7D,84,A2,A6,23,4A,E8,20,F1,20,39,06,95,7C,33,E8,8D,55,00,52,9C,1D,2B,DE,79,B4,82,35,99,CB,B4,02,91,1A,94,EE,40,C9,86,4B,95,70,46,A6,63,64,F4,B4,C7,24,B7,FF,95,DC,04,B8,F1,36,70,06,18,B6,D3,49,95,5D,F9,60,7F,4B,46,82,CB,CA,FD,2F,21,98,DC,F8,CA,03,9D,9D,7F,B0,C1,4C,3B,3E,2D,70,7F,33,39,83,AF,D2,21,C4,F7,67,22,5A,62,5C,05,4F,63,BA,6F,6E,4A,47,B5,5F,01,0F,E4,AF,3E,19,C9,5F,3B,AF,2B,8F,69,1F,9A,38,3B,BC,27,DE,EB,64,93,C9,90,B9,9E,72,5B,25,EE,1D,1F,62,CB,9E,07,1E,CD,F7,59,A0,59,4F,15,D8,AF,ED,CE,DB,03,7E,71,2B,A7,80,17,3B,74,25,C2,24,33,0E,61,F9,66,B9,0C,E8,60,54,DA,22,C7,BC,5B,30,AE,41,5F,9F,06,8C,1F,4C,BC,16,8B,E3,EA,01,37,C0,30,21,D6,B4,74,F9,8A,5E,7F,D5,87,36,FF,1E,50,B9,52,1A,0D,69,AB,41,29,F1,0D,CA,B1,5B,D1,E1,CF,CE,1B,1D,AE,A0,82,FE,DA,D4,D0,CE,20,B0,3A,54,56,33,95,5A,65,9D,A2,28,B3,41,0D,6B,B6,EB,E2,8C,1D,1C,09,29,E6,AB,75,1D,0C,BF,99,8C,C4,72,83,44,40,F9,F9,4F,15,B9,EC,59,05,02,0E,32,DB,3A,D9,D1,0B,59,7B,EF,D3,0F,C3,90,8C,E0,E0,9F,A2,53,D2,C4,E4,7D,75,F4,88,FC,59,CD,88,4A,8E,3A,BA,F2,19,5B,60,C8,FA,21,CD,3F,99,3F,6E,96,BE,4D,0F,F5,DF,4B,AE,FF,03,A6,AC,1B,0D,E4,3C,90,8A,CC,9D,4A,3D,C8,08,B0,85,50,F8,30,EC,BB,5E,9E,16,3B,B1,20,B7,33,18,8B,62,DF,B3,74,86,DC,16,3E,93,CF,B5,FF,22,CA,68,1C,06,1C,D2,AE,88,E3,31,1F,0C,B1,C5,DF,79,EC,78,AA,ED,DC,BE,0F,2E,1F,FC,32,E2,B7,CC,86,4A,42,04,6D,3D,D0,D0,8F,72,B7,4C,17,5C,C0,5D,42,AF,AA,E5,A8,D2,A2,F6,9D,E0,01,2B,41,F1,0D,9B,1E,88,0F,6F,DA,18,E4,F3,D3,1D,CD,3A,F6,44,18,9B,4A,2E,9E,5B,A6,15,48,0F,B0,C3,9F,ED,BC,FF,3A,C3,53,28,D2,1A,D8,C4,11,5D,8B,ED,91,13,D3,BC,1A,4F,91,E9,12,9E,ED,04,A3,19,F7,08,24,2B,54,89,E7,F9,80,3F,DC,4C,BB,B2,90,76,82,07,5C,E8,16,62,08,F5,59,43,C4,FD,2D,98,54,74,3D,E8,FC,C2,DF,63,4E,86,9B,38,2A,2A,47,10,C8,C4,B2,91,66,14,62,CC,7B,40,B3,B3,09,60,D6,BD,07,C3,46,B9,CA,9D,48,CB,F0,C8,97,11,53,89,9C,58,96,98,95,04,C5,FD,07,B3,0E,F0,AD,E3,7F,45,B8,1E,5F,17,AD,2D,05,06,FB,6B,FB,2A,43,4A,40,4F,F8,79,36,C7,7A,4D,66,7A,57,07,C5,04,1E,A2,64,A9,84,D8,02,51,25,07,3A,79,E0,2C,BF,C2,6F,D4,6E,10,02,BD,0A,B0,DF,F3,C7,78,AB,9B,75,4F,C0,AE,30,51,3B,58,41,D6,6B,D1,57,4E,96,D0,D3,DE,CA,E2,AB,34,AE,38,B6,DB,5B,65,8D,0B,49,03,12,95,A0,49,9D,57,00,2C,A8,33,A7,23,66,52,BE,D8,01,9B,AE,85,AB,69,C6,8D,BD,E0,93,EA,9E,B4,F7,07,11,B2,9E,96,CB,68,25,33,FE,29,23,49,34,06,60,ED,9D,18,E7,24,93,46,8E,B3,D6,6A,CD,89,2E,AD,D0,60,AA,D6,50,D5,B5,E3,D0,73,EA,57,34,9C,04,DC,A1,36,D1,C8,28,9B,6F,C1,6B,C3,27,00,CE,BB,70,26,6E,A1,6C,27,53,0C,5C,4A,0B,26,61,D7,34,F8,9A,0A,23,13,32,E7,3F,8E,AC,B6,A8,2A,D9,7F,DB,EE,02,E2,AD,44,6F,96,E8,B2,A0,4C,97,65,0C,35,C4,E0,EC,04,BA,AB,AC,72,61,4F,18,C5,49,43,D8,34,8D,77,F9,D2,72,24,1E,E8,B0,7B,11,15,5A,F1,CE,FF,C7,2C,3B,49,10,2C,AE,69,61,10,91,62,A8,62,AB,F2,6E,18,89,28,0E,2C,F3,98,86,67,DE,36,C3,2C,79,1A,A5,D2,18,F1,1E,6F,26,6A,70,24,C3,76,86,A6,DE,BB,87,C6,0A,CB,56,CA,9C,01,E6,79,1C,7A,4C,EA,3B,5C,81,8D,13,48,9C,88,29,CA,97,8E,B9,FB,4D,4C,F1,CF,94,D3,A5,72,E2,11,C3,38,55,E6,61,B8,E8,39,DF,AF,25,1E,04,37,81,D4,A5,01,CC,5E,A4,2C,FE,0D,CE,F7,84,A1,AC,70,95,AE,58,81,3D,56,F4,4A,D3,76,6F,AF,F5,12,A6,0D,BC,B3,11,FC,3F,19,00,70,3F,FE,A3,6A,64,B5,7E,70,E9,0A,8A,03,75,5D,8D,DF,5D,8E,44,7A,6A,32,23,4C,BC,57,3A,0B,A9,3A,B7,1C,1A,AF,43,B5,CB,90,57,4A,5C,31,4E,47,B6,DC,06,2D,DC,FB,8D,FA,13,25,5D,B5,2D,E7,E7,E6,4A,1D,97,FF,EA,E7,D2,06,2E,25,05,74,D9,42,13,D9,D5,85,E0,A9,9A,59,2A,B2,4B,DA,82,A4,30,AB,B2,CC,F7,B3,23,AE,E1,1A,10,FA,04,3A,84,3E,89,4B,20,0A,CE,62,F8,74,18,D3,DF,D7,AF,26,B1,89,B3,D2,CB,99,2B,5C,6F,1B,18,30,4E,A0,7F,44,18,44,2B,36,CF,54,C2,A4,8F,03,71,08,CC,3A,71,D6,42,EA,AD,1B,F6,BD,CA,52,34,1D,8A,AE,5B,9F,41,E8,4B,AA,55,E4,4B,BE,70,1B,E3,53,2F,65,F1,41,2B,E2,47,40,40,79,D2,B6,23,9F,D5,30,5C,EF,E8,FA,8E,31,E6,1A,45,96,ED,91,6D,D6,CF,1D,9F,D3,59,C7,B5,45,06,D1,3C,77,D8,E8,BA,EE,B6,6B,D3,A4,60,09,E3,6C,71,D1,93,CC,63,BA,B3,93,2B,38,A6,F6,27,8F,0A,55,16,44,31,5F,82,FE,73,0A,6D,1B,19,3A,79,1D,04,C9,B1,D6,5A,01,3C,80,71,7E,1E,96,E2,12,07,92,30,BB,E4,64,DB,CB,78,BA,79,AD,6E,3D,B6,DD,F4,C9,4B,2B,6A,6F,A7,05,5A,2C,4C,DA,30,4B,28,87,A7,1C,91,CD,FB,30,C5,95,F6,E6,5C,7D,66,D9,F7,5A,B3,4B,A7,CE,82,CD,4D,AD,A1,58,94,52,52,48,A3,D5,D0,E0,33,56,C6,E0,A8,02,81,32,45,4B,C8,A2,FF,38,07,36,50,7F,82,7E,9B,D9,2A,36,46,CE,8E,9F,98,4C,97,65,87,18,C1,2F,BF,4D,46,C3,0C,47,E7,14,B7,B0,53,78,83,DC,3E,7A,A3,7A,F6,E0,AD,26,A3,84,0B,8F,8B,16,BC,14,0F,19,6C,35,B9,82,E1,D9,04,0C,68,E5,0F,88,CF,D2,68,3C,63,EB,FF,EC,3A,70,F0,73,BE,F1,47,1B,39,A5,B6,E6,10,A6,74,74,1E,68,6C,74,7B,B4,D4,73,71,D9,3E,40,F3,52,DB,D2,28,1C,32,3D,BD,0B,C2,2B,BD,1A,60,EC,3B,D8,2C,96,57,01,18,38,33,C5,9C,6B,9D,63,F2,69,0F,31,4A,FF,88,1A,51,BF,36,CF,91,3F,52,01,81,A7,1B,78,99,D5,D5,D6,20,2C,E5,CC,7F,D7,7A,2C,EE,25,BF,15,91,20,99,70,FF,41,84,4C,16,6B,16,75,47,3B,EE,DA,36,2D,53,D3,C1,13,09,29,34,6A,0B,0D,F0,EB,49,23,86,7E,3F,90,E3,B7,DB,DE,D3,5B,40,33,C7,F7,36,12,1C,CC,15,29,84,B3,E0,D3,DC,26,B4,93,37,3C,3C,41,05,03,8C,E5,86,38,F7,90,3E,1A,DC,9A,DD,CE,82,62,5D,2F,75,55,CF,AE,4B,24,10,5E,0F,E3,73,A3,69,CC,82,E4,0D,C7,C1,F8,25,A3,BB,FC,27,FD,64,DB,92,AD,ED,B9,DE,8A,1A,E8,DE,41,18,9F,3D,6D,C7,A0,0C,FC,57,3F,8C,77,D2,77,E5,4D,10,3B,32,E9,78,C5,8A,B0,E4,8B,1F,78,38,87,77,C1,0E,27,18,AB,32,C8,6A,6F,56,92,28,66,0B,7D,79,34,2E,5A,50,C4,CF,67,27,12,8B,9A,6F,49,3D,10,2A,94,28,C6,90,A7,1C,68,49,BD,47,79,79,1B,0B,BD,DD,12,57,88,0A,EB,32,40,12,E4,9D,5B,E6,91,34,4E,3F,7F,7E,40,F5,62,2D,A8,3E,2E,A4,7B,B0,F9,D5,A5,AF,F7,BC,F2,1D,51,77,B9,68,92,C0,15,6B,EB,8F,8C,7C,3C,D4,42,7E,6E,70,FF,9A,D7,1F,C4,97,91,F1,C6,F0,AA,ED,DE,18,2E,1D,E7,7B,9C,15,03,23,AE,66,BE,82,96,25,34,76,54,1B,28,68,D0,48,14,BF,97,23,2E,92,66,BC,8E,BF,F7,23,55,34,B3,AB,C7,ED,CB,01,D3,15,CF,6F,5E,8D,A5,D0,CA,4D,4B,AD,2B,43,7A,76,97,C0,E9,30,4A,D7,BB,E9,36,67,BF,54,32,F3,8B,B0,3B,A2,61,FA,6D,33,F0,84,85,30,5F,35,88,E7,F9,06,FF,8C,4E,B9,98,0E,BC,67,A1,4A,42,BE,36,56,BC,0A,5D,D9,69,09,2F,AA,38,9F,82,11,86,FB,0B,42,37,1B,EE,CD,54,3A,0B,87,7E,10,2B,3E,66,F5,08,58,0D,9F,20,DD,A2,A5,83,83,AD,8A,15,06,9C,DF,43,2E,E3,54,7A,39,4B,38,39,0E,DE,00,59,2A,17,48,67,10,FF,1A,E7,1E,A3,A1,E3,30,8A,BC,E2,17,71,E8,75,70,6C,69,11,1B,F5,97,E1,C0,E2,41,27,5B,41,B8,39,7F,44,67,38,B6,B7,7D,92,65,10,E8,C6,44,6B,44,4C,D4,77,29,84,04,FE,24,42,19,0D,4B,BF,FA,16,90,BD,48,8E,9E,98,B3,48,F0,58,ED,6B,AD,E0,46,EB,0C,81,E1,CA,5A,6F,DB,B3,8A,D8,F3,FE,91,66,0C,23,84,68,2D,10,08,F7,6C,9D,A9,FC,16,86,AD,47,6A,78,74,3B,E7,18,C6,EB,21,67,66,71,EC,50,FC,B0,CD,16,06,5D,05,21,94,D4,D1,9A,92,EE,9D,A2,AF,4B,4F,2D,5A,61,82,3D,F2,BF,33,3A,6A,97,4A,FC,AC,35,5D,F8,48,0E,5B,6D,F8,26,9A,3C,8A,D9,7E,1E,9A,D7,05,AB,74,D3,A2,55,72,45,D3,84,36,97,1B,CC,1A,6F,C2,19,94,9B,63,B9,D1,93,A9,4C,5B,EF,7F,89,3E,60,22,1E,C9,76,CF,F5,DE,BD,B9,8A,BA,90,8A,9F,4C,93,D1,96,F9,5A,A6,3F,C3,D4,38,7E,64,BF,08,3C,8A,14,C9,02,43,27,3A,00,F6,31,D1,1A,A3,8B,F4,75,8B,16,E0,05,F1,2D,0C,95,82,25,93,95,4C,05,66,16,0A,AA,1F,48,6B,7F,7E,BC,B9,C3,37,F7,D3,CE,96,C8,F2,A4,2C,DF,FC,48,E6,41,69,28,27,1D,1C,1E,FA,7E,04,1B,F9,23,67,EC,63,80,E1,1B,87,55,1C,73,56,AD,8D,E1,08,4C,61,90,E2,E2,06,42,91,A3,C2,A7,4F,88,BD,54,D0,F6,7A,DE,23,45,F3,28,2B,65,06,5C,CF,C4,8F,70,64,E5,FA,BB,D4,4A,F5,2E,46,6C,D9,A4,32,B2,04,FF,1E,AD,43,C5,7E,03,73,59,1D,38,46,61,5E,D2,ED,61,C9,28,55,EB,20,00,33,EC,EA,E2,1A,8E,8C,AC,33,A3,57,18,63,15,76,8C,FE,CE,B8,14,15,68,96,F7,36,EA,98,7F,BE,06,81,D1,E8,80,B3,8E,87,2A,40,34,7F,6B,BC,8D,B0,0B,10,10,6E,1A,6C,4C,9C,FE,E4,16,57,69,82,B3,30,26,9D,E7,60,62,22,C2,F5,CE,D7,B8,53,8A,76,AC,7B,95,A2,5D,D3,3A,1C,97,61,64,04,8F,EA,05,1E,0C,E9,66,70,F0,98,B8,81,BB,A0,11,2C,AF,0F,5B,94,BD,C2,E1,3C,70,A2,99,9C,66,35,E6,3A,8B,C6,51,52,6D,BE,C1,94,F9,AD,30,1E,0A,31,63,34,0C,8B,3E,98,62,E7,85,6B,74,A2,C8,E6,BE,67,55,E6,23,6A,0D,C8,65,EF,A6,AD,5A,DA,88,A6,77,FD,01,F8,1A,9C,38,10,6D,F2,1C,A1,4F,08,DA,95,C1,6E,BB,47,18,79,AA,85,4D,29,EA,99,7A,52,F1,90,D0,29,A9,E9,14,3E,90,6B,5B,CF,9B,74,3D,33,F1,03,0E,CB,86,69,EC,E2,61,01,95,87,41,59,9D,CB,92,8E,BB,19,1F,45,1B,62,60,A7,3F,69,82,04,6F,E4,55,46,EF,60,61,2C,92,E4,F6,F6,D1,E0,1C,2E,D1,F1,5D,31,DD,21,60,93,BD,67,4F,83,84,36,5B,D4,70,B5,A1,63,06,83,4A,BB,64,B4,90,C3,36,37,69,9C,9E,22,E5,E1,6D,27,99,0F,88,87,48,4E,B7,E2,C7,00,BF,1C,54,F4,D4,71,04,60,7C,CA,4F,7F,35,20,C1,3D,E6,D3,F4,EA,9D,61,34,88,EF,E4,ED,7E,AC,0D,97,DF,74,46,66,89,EF,0B,34,BD,63,11,96,5D,17,2B,F1,C3,13,F1,C4,54,89,E2,E2,A2,13,29,CC,C9,5C,A0,64,DA,C6,63,B5,7B,31,A5,47,BD,81,D4,2A,54,77,29,52,D1,52,D6,27,04,EC,A5,85,99,DF,CD,1E,D3,F5,C9,8D,80,B6,09,EB,62,55,EE,27,3F,B6,D4,D9,3F,C6,29,D1,2C,1D,4F,80,74,7B,4E,6D,4B,8D,23,D1,00,3A,D5,96,9C,75,38,9D,37,D6,3A,5B,A2,1B,2A,44,77,AA,4C,D8,4B,5E,FF,73,BE,8F,A9,14,94,13,D8,EF,BC,7D,C7,AF,C1,CB,54,68,52,61,BA,7B,2E,A4,9F,DC,69,37,3E,BD,C4,52,60,22,96,A5,A6,B8,B9,44,F3,BF,97,41,D8,0B,83,A3,2A,3A,59,17,BC,65,DA,12,B8,5D,64,A0,FD,44,B1,B3,7A,11,47,53,B2,4F,5A,55,B3,B1,7C,E5,FE,86,AD,42,F8,72,03,71,51,2A,74,9C,03,EF,70,12,AC,05,94,CC,43,10,23,88,46,30,94,FC,35,B6,48,7A,DF,13,A7,9A,47,27,42,7E,6C,92,9F,27,DE,6E,B4,34,0F,84,DA,48,3C,EC,E9,11,19,69,4C,5D,EC,CF,A3,EF,11,C7,A9,68,93,63,A2,70,BF,E6,E8,F2,E4,43,77,C4,CF,A4,56,3F,0F,A9,B9,E9,9A,FC,6C,1E,5F,0D,C9,95,97,E1,10,5E,D0,EB,82,B9,E9,B1,0E,A5,4B,EB,7D,D2,7C,49,FC,20,F9,77,5C,19,13,A6,1B,62,B3,45,D3,FD,12,33,E3,75,D4,02,79,64,88,1E,EF,75,93,D9,E3,EF,39,C8,4B,BA,55,A4,45,38,52,1D,D9,F8,78,0A,BB,4B,DF,07,F4,D3,21,10,29,04,2D,24,AF,AD,D6,03,68,47,99,91,9B,09,F4,EC,B6,4C,D1,B6,A8,F0,D7,7A,E6,C1,46,74,37,51,59,B4,D8,49,C2,C6,A0,6A,1E,E6,EA,33,2D,61,33,EF,F3,F2,88,A3,43,7C,1A,17,43,54,68,7E,09,A9,52,CF,7D,E8,EB,58,7B,F2,80,EA,FA,EB,5A,B3,E5,9C,3E,F8,21,1B,F5,0B,1F,3E,94,94,83,1A,8C,2B,F3,12,E4,4A,23,6D,A2,46,E2,1E,65,1B,D8,AE,00,CE,8F,C9,0C,A9,16,DB,B7,EF,C4,FC,10,BF,C0,91,44,7E,34,14,96,DA,C5,B1,C5,8D,68,C1,66,87,B4,D6,FE,CB,9D,36,33,30,39,48,46,C6,4E,2B,AD,89,CC,48,59,D6,23,CB,E3,DD,F3,E0,CF,DE,4C,8A,11,DD,C6,52,43,97,01,CB,8F,B9,8B,0D,CE,EF,CD,E2,C7,C5,6D,40,E6,E5,A8,88,DB,6F,56,56,FA,1C,0C,3F,5D,29,1C,5B,0F,65,A7,AF,DC,2A,7A,06,86,55,D2,C2,48,B4,7A,09,81,1C,57,F5,D0,4A,4C,1D,28,83,52,5D,93,80,ED,B0,83,4F,4E,EF,FC,7F,98,17,57,58,79,C4,B7,D9,AE,8B,FB,F7,68,C1,0B,34,39,D7,E8,16,ED,1C,7D,F4,66,7B,C1,33,BE,77,E8,A0,66,90,39,C9,EC,D7,A6,32,3A,E3,1F,36,2E,0E,15,44,D7,7D,31,D1,31,0E,BA,2B,DC,D2,2F,15,DD,76,9E,FE,B7,D1,FB,B7,CE,CF,FB,FD,C1,0D,CC,58,01,03,96,B4,CA,34,EA,E0,66,02,3F,0A,5F,81,88,75,1B,40,7A,3B,69,3A,F6,E3,D2,CF,9E,2F,DC,B8,AD,A1,BD,7F,D0,86,84,99,D7,E5,15,F3,D8,99,19,53,6E,3F,D6,38,C4,FF,61,03,D4,68,94,05,3A,E4,A2,F2,5D,06,09,4F,DF,26,92,DF,27,24,03,4A,ED,6B,0A,E0,39,A2,EE,B9,D8,EF,CA,AD,46,33,11,4C,95,3C,CB,DE,D2,2C,10,97,C7,24,6C,48,B9,EB,65,CB,90,E8,AB,2A,E6,5F,12,0F,F7,D5,45,C9,7C,5E,E1,EA,1C,B0,8E,A0,EC,F5,83,57,C2,20,4F,57,92,4C,8B,C7,17,03,AB,47,47,CC,F4,A2,3D,D8,98,CB,73,83,31,BE,67,41,23,3C,0B,CE,CB,6D,FA,70,84,99,95,A0,49,40,2E,7B,CD,0C,DD,08,0E,9E,57,E4,FE,9D,3E,67,84,23,EC,36,A3,89,6B,CF,F6,57,38,BC,2D,55,06,BB,09,16,3E,FE,6A,88,8D,5F,1C,5D,FC,D7,EB,11,CA,02,E6,DC,DE,6B,44,67,D1,DA,10,EA,13,85,50,0D,B0,A3,B6,01,0D,0E,D1,0C,46,64,61,EB,00,6F,CB,AC,8C,FC,CC,5A,22,56,8B,D0,BA,67,0F,FD,2D,AB,40,B6,72,14,3C,32,7B,95,98,7F,A9,5F,24,47,90,03,F0,87,E5,57,21,8B,09,1A,4A,09,07,83,5D,FF,05,4E,1B,DE,1E,6B,23,8F,31,BD,13,3C,D2,09,E8,1A,D7,FA,47,FD,40,FD,A9,ED,C8,F1,C5,0C,95,34,BB,62,3C,48,EB,4D,DA,64,76,E1,37,48,7F,DF,8E,F0,05,A4,4C,63,9B,E3,C9,A4,1E,5D,5D,CD,6C,99,06,6D,AB,12,9C,52,C9,30,47,97,0B,C0,7A,CB,CB,53,43,98,96,75,E5,77,C8,65,D4,42,ED,63,E1,E4,32,7A,3A,B6,CE,29,D1,02,32,73,BF,FE,35,BF,38,DC,53,B1,68,A5,38,62,22,1C,EB,33,BE,1C,F0,FA,4B,49,03,29,32,08,89,79,EE,38,1A,78,04,5E,9C,B8,83,46,37,13,6F,D7,9C,85,06,B4,80,64,42,30,45,25,60,B1,D0,2B,BF,FA,D0,49,08,69,AA,B8,89,A7,96,77,28,7C,0A,51,A1,A0,6E,58,FD,D2,39,53,CA,1B,AD,34,2E,2E,14,3B,6E,E5,70,31,BB,2E,13,7B,98,C7,00,77,6B,7F,E3,3D,66,CB,73,99,83,9F,17,FC,BA,D7,E0,50,A6,15,2E,D1,C6,67,8C,23,D1,71,0D,2A,8C,BF,79,4C,F5,EF,B8,3E,43,88,16,3C,0F,9D,04,63,0B,68,E4,03,E4,A7,12,64,6A,CF,B0,CF,48,58,19,FD,AC,7B,BF,B7,5B,F5,85,3C,CB,93,FC,F2,03,8F,B9,B7,D6,A7,77,9B,52,9A,AE,B0,96,23,2A,53,37,FC,D4,42,1B,5A,6A,3C,EB,FE,DD,56,A2,0B,A4,33,FC,EF,A1,B5,43,14,D8,27,B6,5C,23,88,65,07,66,55,1F,3A,C8,12,B0,31,C9,8B,B9,68,A1,06,3D,05,A2,33,C6,2F,39,2D,B6,2D,7A,18,78,09,60,8C,D6,80,C5,71,77,B2,72,A7,07,E3,BD,E2,07,D5,5B,C8,10,AD,B5,A1,4A,18,A6,B3,2E,C3,9E,97,B4,32,06,9A,E9,FE,B4,75,FD,BB,7A,F1,83,C5,44,E9,37,1C,E9,79,E2,A9,BB,8A,3C,20,9F,8A,DE,5A,B0,7B,E4,45,90,97,08,B9,B4,7A,06,5B,FE,49,B1,A5,86,0A,F4,C8,C7,8E,BA,8F,30,98,7F,25,06,8E,8F,D1,8F,6B,B9,17,32,0D,AD,6D,AA,0B,B3,F6,4B,E6,CB,9F,07,E8,1C,55,E2,AA,8D,09,3C,3D,DB,88,BC,FA,A2,7B,0B,2C,01,EC,6A,35,44,80,40,E0,C6,CA,52,A0,84,BF,65,C9,E8,73,2D,07,B9,34,E2,8F,B9,F9,D1,8E,AD,05,55,9E,BA,51,05,C8,F2,CB,CB,21,54,40,22,8A,A9,AF,86,B4,A7,3E,D3,33,CC,06,66,C6,42,AC,99,4B,A6,C0,A8,2B,3C,7E,AD,C4,D5,A1,61,33,62,FC,EE,91,78,80,F7,08,D5,49,B2,62,09,3F,0A,9B,3C,37,E5,5A,DC,A5,B6,CD,65,EB,3D,01,76,A7,D7,54,0B,32,2A,2D,B4,E5,68,07,E6,98,B3,29,24,A7,E2,F3,42,76,3A,5E,FB,CB,83,EF,E1,3A,4C,33,2C,59,CA,96,15,DB,25,F0,D8,65,FE,6E,6C,4F,E7,44,91,7C,71,F6,CB,EE,36,67,15,95,C9,21,05,A8,38,F5,4A,8D,60,A3,FD,0D,BA,D3,65,3A,90,00,4F,C0,03,AA,FE,44,DE,7A,A2,96,20,09,74,C8,34,0B,82,4F,50,04,4D,21,D4,CA,54,EA,F9,33,14,B9,6F,EA,C6,B9,D0,2E,BE,BD,53,6C,AF,C1,3E,57,98,46,0B,1A,D6,31,4B,18,59,8F,68,3D,D1,15,79,2B,FB,52,7C,38,D4,A6,04,4D,46,61,14,72,03,59,CA,0E,CD,4A,7B,08,60,FB,57,4D,FD,03,B9,21,A0,22,4A,C8,33,70,E8,7D,F5,26,5A,B3,A9,6E,B8,CF,9F,67,FE,49,7B,05,39,81,B9,33,67,64,15,46,3F,C6,7B,A0,9C,DC,36,3A,EA,98,A5,A0,46,5D,8D,65,F2,01,3D,8B,7D,E2,EB,F9,D6,2D,C9,F2,D5,6D,6C,C9,B1,99,75,36,AE,69,D0,C6,7C,DE,86,30,EC,BC,32,3A,F8,09,6B,82,3E,58,07,25,9C,B6,66,83,80,F0,60,6E,E7,D8,C5,9E,8E,CC,D2,67,AD,74,82,88,97,F7,CB,8B,65,66,20,E7,4A,6F,E3,EF,28,25,C2,0A,69,04,6C,5C,77,16,AE,44,55,F9,A7,82,61,80,8F,C4,DF,5B,AA,9E,46,DB,39,DB,07,41,1D,95,5A,3C,63,40,B8,4E,13,0A,60,E3,B0,24,CC,17,35,F2,8A,E0,10,2A,6C,8F,70,D9,AB,8D,BF,BC,C9,D2,AF,B4,6A,BD,51,04,DB,F4,BE,F0,CF,29,91,1E,51,3F,15,DD,1F,A5,F3,C5,28,8B,52,B9,97,4E,1C,28,58,62,BF,81,02,93,CE,22,37,B1,BA,65,16,35,B8,FA,02,29,BB,C5,3B,DB,DE,70,E9,BA,E2,1E,74,1C,15,1C,2E,5A,D5,EA,42,72,F4,2C,7E,24,7B,26,20,70,08,48,26,32,34,2C,37,77,B9,6C,56,55,5A,FA,80,2C,E2,CE,AF,62,39,0A,5E,3B,76,03,55,F3,4B,BD,62,2A,86,05,9D,B9,60,4B,6F,D6,E9,11,C3,CD,AE,10,81,6E,33,A8,41,58,98,BC,35,DB,02,9F,4A,AB,A5,1F,67,95,12,79,65,FF,B1,15,7D,06,9C,2A,05,27,3C,C9,52,F7,6D,18,69,14,37,20,68,CE,FC,4B,AF,5C,C5,06,2A,FE,BD,19,50,A2,A5,17,31,12,C6,7B,60,04,60,84,58,24,00,49,40,F0,DD,F9,31,33,BA,74,01,25,4B,F1,35,19,E5,1E,C7,AA,9E,B0,78,F5,FA,63,04,F0,08,BC,73,39,5F,55,98,B5,12,DB,BA,21,C1,CA,F6,86,95,5C,D2,64,46,BB,9F,54,A7,64,61,0B,82,D8,55,0C,FF,95,E8,68,F5,CF,8D,17,FC,88,F6,0B,B7,C0,88,61,F3,13,7C,6C,34,A4,CA,2F,AB,9F,6C,8B,92,43,36,46,9F,A6,A3,64,C5,24,93,A6,11,DC,D5,AB,81,6B,B2,09,B3,1D,BC,8C,E1,FB,18,3D,6D,F3,E6,A8,C6,AF,CF,DF,A2,3C,1F,3F,0F,C1,83,4A,68,45,09,90,CD,B1,A8,AC,13,2D,4A,88,B0,DA,4A,00,30,77,18,28,BD,C6,7D,50,5B,25,C6,EE,C6,47,F9,EA,45,28,81,1E,70,98,E8,36,CF,41,6F,CD,A9,4C,02,89,C7,EA,69,FF,FD,FE,2D,08,83,E0,87,5F,FA,03,01,BB,B2,45,89,FD,0D,CA,7B,D4,C5,D5,D3,87,2E,24,9F,AD,5D,28,66,25,46,9E,0F,8C,38,1C,51,FF,11,8E,A6,E6,3A,62,17,4A,55,28,B1,4C,34,4F,A4,CA,8D,D0,8A,46,6A,6A,43,57,EA,12,15,58,6E,A4,CD,3F,A1,4B,F4,AB,13,84,DC,20,9F,C9,52,DC,1E,52,F3,1F,C5,9B,9A,1B,C4,2F,31,BF,D6,3A,E5,CB,4E,4B,BC,4E,D6,A8,B8,F8,E2,21,9E,2A,6A,49,64,30,11,24,7D,9D,9F,77,52,E9,95,16,D6,2E,1E,D9,9E,4D,87,82,A9,A1,72,DF,32,D5,EF,C1,A2,54,E3,ED,22,93,BA,4E,6D,35,52,30,09,D3,33,4A,7A,FA,B6,4D,A3,BE,22,62,EB,6A,E5,AE,A8,32,0D,9B,B6,4F,FE,61,3D,C3,B2,26,0C,84,25,26,66,91,30,72,DA,C9,65,14,28,7B,B3,91,D8,C1,B1,F1,E4,A8,18,0E,18,63,DF,68,44,26,9C,04,F1,3B,F8,CF,27,37,FF,61,3C,35,51,27,21,0D,EB,19,8A,43,F5,A9,37,9F,F6,0B,5F,AE,86,A8,69,B5,31,E8,99,0C,A0,BB,8F,81,B6,D7,90,91,A6,C7,F3,B1,A6,1F,14,BB,8C,8A,2B,04,8C,CD,82,07,D2,D5,D0,2D,19,DF,B8,57,65,6E,AD,1B,1B,AE,2E,9F,20,CA,95,7D,CE,A4,A9,5D,37,32,A9,39,08,A6,21,3D,9F,89,F0,BB,43,76,B8,05,D7,BF,CB,EA,F7,6A,E5,0E,61,D5,51,49,F6,36,C6,2D,F7,6A,FD,11,A0,43,4E,17,FE,93,3A,93,94,37,51,87,3E,B2,76,E4,25,12,AA,3C,8F,16,76,D8,51,87,8B,A7,83,B5,7E,10,BD,4A,49,3C,2F,C0,7D,4A,64,34,BA,F4,67,67,22,33,6E,5A,DB,91,E3,1A,61,65,C8,84,62,EE,C2,A5,11,63,9D,15,53,44,5C,10,49,1D,64,55,33,2A,26,B1,3E,E6,A5,A6,E1,60,33,F2,F8,86,55,C2,B8,43,43,E9,DC,53,AD,9A,1A,9D,C1,B7,76,11,62,36,A8,E0,56,67,0F,0F,06,B0,54,FE,AD,60,9A,D4,4E,A9,F3,12,B1,E1,4A,D5,49,A9,AB,09,56,9D,02,73,92,14,2C,AD,04,76,84,A8,03,A3,AC,58,F4,69,25,FD,6B,D2,FA,89,69,71,57,16,92,C4,2B,98,AE,96,00,98,86,0C,F9,E1,F2,56,E7,6B,67,85,AD,C2,4B,B5,1F,02,67,EF,6A,75,E5,0D,19,BF,CE,7E,28,42,BB,AB,8C,8C,DB,AA,EC,39,93,FA,FF,C9,21,C7,CA,8A,E9,EE,76,04,F6,D2,5C,09,EF,77,BD,41,A6,53,4B,D9,38,B8,CC,A8,2F,B1,ED,B3,27,81,A6,1D,D4,21,00,7D,4E,E8,0C,92,34,88,D4,49,89,21,53,28,52,FB,2D,87,51,E9,CD,C6,E9,AE,B4,64,59,37,B4,A3,A3,33,E2,48,39,13,B1,59,BC,11,DA,77,0C,C7,A2,B0,C4,52,82,E3,C8,B1,AB,0C,60,14,0E,75,EC,6C,CB,2D,F2,73,2C,B1,A2,DD,1A,2B,95,49,61,E9,C1,C2,A7,1E,C0,67,17,96,FA,27,32,F3,A7,5F,E5,97,CD,4F,F5,64,D7,EB,20,EF,7C,F6,29,4E,34,88,C1,38,FD,8A,52,4A,E7,B1,35,CA,29,50,EA,18,46,CE,FA,46,B9,F0,C7,A4,AD,58,9C,B3,D4,3F,E6,BC,44,78,0E,28,E3,F9,FE,F5,8D,55,A9,54,96,22,08,BB,5E,3D,73,79,95,FF,7E,E8,09,4A,3F,A0,59,C8,52,43,D9,3D,D0,D5,0B,8A,7D,98,A7,34,7B,B0,42,85,64,4A,06,06,4C,2A,18,70,12,3A,D6,E5,B7,9A,ED,85,45,C7,FC,EF,46,AD,24,47,5D,69,B8,E4,C9,B4,A5,97,63,F2,CF,3E,0B,23,90,78,99,22,1C,3E,28,69,05,EC,26,D0,54,B7,59,1A,F4,93,09,90,72,E3,8D,4E,A1,1A,DB,7B,D4,32,BA,97,6F,79,B5,5B,FF,D5,74,64,AD,5B,51,6A,2B,86,DE,95,DA,B7,A0,8F,D9,56,C0,06,35,80,11,D8,EE,D8,17,04,0E,C2,99,21,3B,BE,13,69,DE,28,D5,4A,2D,BF,D6,61,B7,DB,10,17,A9,95,C0,72,6F,CA,D1,1F,75,16,8D,7C,81,A0,4D,A1,39,36,DB,7A,D8,F1,DE,F2,0E,34,7A,27,27,75,C5,70,A0,6A,F0,DA,6D,61,6A,CD,59,FD,AF,28,9C,C5,3C,22,C7,41,F8,3B,CD,6D,37,AB,8C,A0,21,4B,C8,C8,68,81,6F,22,F2,8D,8A,4E,33,46,F0,28,02,09,DA,F6,81,D1,39,82,8D,41,E9,F4,F8,A4,AC,A2,F0,55,FB,E3,C3,39,17,ED,F3,A7,7D,3C,E5,CC,B6,DB,D2,FA,FE,FB,8C,62,54,3E,9E,18,E1,76,90,79,31,48,3B,78,4D,44,B3,CD,F3,B9,AD,C5,D8,54,A9,7D,1F,7F,51,C2,76,03,1F,6F,9B,25,46,83,D0,F1,5B,BF,79,0C,1A,05,DC,17,71,4C,2D,8A,32,C3,24,B6,1D,30,68,28,A2,65,4D,D3,D9,CD,C1,BD,9C,F5,2D,0E,2E,21,1E,54,98,2D,9B,70,21,BE,DA,45,0A,DE,B1,86,A8,07,40,BA,30,3C,D2,CA,86,89,3E,C1,AE,E2,20,3E,35,82,09,A0,85,AF,01,BD,55,1F,8C,D1,E8,AC,85,48,F9,3D,1B,D7,86,DA,43,E1,4D,77,0B,7B,CA,8C,34,7D,D7,2C,74,E5,79,52,D7,54,C7,6A,EE,38,F0,AA,79,08,EF,8C,28,7E,1B,11,52,B9,C5,19,42,E8,78,3F,E8,E4,51,88,79,D8,3D,EB,1E,69,4A,BB,F5,79,BF,7B,CD,E6,9F,09,58,AA,99,5A,E1,ED,0A,25,77,DD,DF,85,F5,89,B4,C1,17,B7,78,3F,93,D6,2C,71,9F,FA,09,3A,6D,4E,00,87,A2,A8,6E,17,D6,D8,2B,DB,BA,C3,55,4B,0A,4D,03,6F,C0,95,89,32,CC,9A,12,64,C8,DD,CE,74,3E,F8,EF,A1,1E,F5,CF,5F,35,3E,B0,E0,CD,6B,42,55,67,86,A6,21,E7,7A,37,07,30,84,4E,C1,95,77,3E,B5,CE,41,45,00,88,29,F7,B3,D6,FC,73,0F,66,75,70,3E,6A,82,9A,0C,88,8A,B3,0B,CE,A1,38,C9,0C,F6,E3,98,64,3D,AC,18,F7,8B,3C,20,3D,CA,C8,DA,09,F4,6A,24,ED,83,5A,A2,DB,BF,6A,A0,05,82,EF,55,40,93,B2,80,47,59,90,1E,83,23,6C,89,9F,CB,86,DE,37,C3,BD,B4,AC,76,D5,F5,4A,06,CE,FF,71,6C,4D,2D,97,AF,96,88,49,76,C6,DF,F9,95,98,94,3A,B6,9C,2C,C0,92,52,D4,F4,E8,75,29,DE,7D,A3,0F,C1,0F,CA,77,AB,8F,01,2F,08,CD,75,73,7B,CF,75,18,0E,4A,5D,67,BB,2A,FF,83,1B,DF,C9,97,86,77,A0,00,38,CD,71,D9,74,B1,56,7F,12,25,15,06,8A,DB,76,AB,AC,07,0A,D6,20,66,B4,07,D0,1D,6D,8C,CD,D6,F7,43,FB,6C,D8,2B,27,86,BC,47,04,7E,36,33,11,6F,E0,6A,B0,6B,A6,86,30,5A,55,74,B7,0B,0E,F8,87,A0,1D,57,B6,C9,D3,E9,33,9D,2C,85,80,06,BB,BF,2B,13,73,9E,77,6E,2D,55,23,0E,95,36,8C,1F,A9,82,29,A0,96,7D,C6,31,17,37,AE,03,AF,A1,D0,8B,40,E8,4B,44,9A,55,ED,84,86,FB,53,65,7C,8F,A0,2B,CA,6D,9D,74,30,72,45,E1,45,11,02,65,B8,3C,D6,60,1A,08,F7,73,D3,1B,AF,5A,81,20,47,84,E3,BA,E2,AB,0D,58,12,C7,7A,31,63,CE,72,CC,7B,7D,22,68,2D,AE,BE,DE,D9,93,E5,4D,56,D3,37,D2,FE,86,FC,75,E2,2D,29,02,C9,18,C0,14,E5,6B,B1,00,08,A5,2B,E7,F5,1F,8E,89,C0,D5,F3,FC,56,F0,E0,1E,AF,6B,C0,8A,4B,5B,CA,1F,4F,8A,8B,4E,6E,0A,D1,88,9D,62,48,94,5C,8E,D9,B9,0A,8F,36,EE,72,27,83,F3,45,72,CF,05,67,B8,C1,99,AC,6B,46,3B,C2,E0,74,DF,94,EF,17,A0,86,E4,5B,28,57,50,51,D4,A4,DD,38,01,09,1A,D8,FF,E3,F2,81,CA,6E,46,81,0E,EF,E6,7E,50,1B,E7,39,6B,1F,38,00,B5,53,0F,3A,0A,54,73,C6,70,84,DC,C0,85,55,72,E1,8E,B6,E8,CE,8E,10,97,25,0B,AC,A5,5D,67,66,0C,EC,5F,E8,2C,AF,93,28,6A,42,48,91,16,B4,18,1A,8F,4A,E1,52,F6,80,1B,D7,17,D0,32,9A,70,6A,0B,BE,CE,31,69,CD,CA,2E,0F,71,7F,B7,56,49,41,A3,3C,08,90,2D,A3,17,D4,4F,5E,4C,57,BE,52,DC,46,EC,D0,2F,AA,1D,D6,0B,93,29,F8,53,37,6B,2E,F9,17,BD,68,3B,CF,F3,2B,8A,65,9D,48,A0,5F,EF,D8,F9,90,B3,80,22,27,AA,3B,CF,94,AE,98,82,42,29,FF,DD,13,34,82,97,DE,78,CD,65,F1,9E,DC,04,B3,97,1B,D4,A0,B3,21,13,FC,7C,A2,3E,1E,AF,2C,5D,83,26,A9,4C,E6,89,AA,1C,D0,BF,EC,8C,0D,31,4A,3F,85,2E,CE,30,E2,2D,B5,F8,18,58,37,1D,EA,C3,F0,B5,65,41,E2,E9,9B,30,9E,59,03,F5,3A,9E,88,98,AE,FC,84,EA,B9,B4,2F,03,F4,FB,98,1A,6C,C3,42,9C,5E,E2,2C,53,C4,6A,6E,E0,9B,B7,25,E7,61,0A,CB,D1,7A,5D,8B,9F,2B,20,26,CF,6C,76,19,A4,1C,5F,33,0E,0A,69,AF,7B,5B,4A,AF,73,D1,4A,45,A6,79,E4,9F,81,CC,DA,08,82,DA,1E,C6,29,19,02,17,03,3B,FE,FC,94,F2,D9,D8,35,F7,ED,9F,B9,5C,87,FA,E3,34,8B,2E,6E,7A,7A,1E,65,A3,92,C4,CD,DB,97,08,B1,AE,4E,7A,91,B9,3A,BA,78,03,F6,0D,D9,EF,16,5C,B3,EF,AA,3D,00,24,1D,DB,BF,FD,86,03,11,28,9A,91,27,61,C7,31,B7,41,D3,70,A1,61,1B,71,CD,01,CE,7A,56,29,27,92,52,93,F8,39,0A,E8,41,50,50,D1,99,10,0A,85,D9,E5,54,DD,73,27,A2,AA,94,F6,28,71,C0,F1,6F,E6,E6,50,E1,F2,07,9D,DA,D2,A4,1D,06,30,9B,33,B4,9F,97,D0,F4,41,53,6E,1D,09,51,C9,D8,10,72,FA,97,1C,9D,10,3B,2D,16,D5,E4,B7,9D,ED,EB,FC,85,EC,E3,F7,BA,12,4D,4A,69,91,8F,84,08,C2,CA,82,97,D7,11,AD,DF,30,97,1A,31,0B,AB,7E,4A,78,2B,62,7C,4E,E8,49,F2,82,EB,21,BF,04,AB,88,BA,71,E8,FC,2B,93,2E,71,19,00,84,C1,42,24,46,BE,E9,75,D3,FE,BB,71,E3,B6,D3,A9,14,F2,13,49,FB,B9,F9,D6,02,76,1C,BB,6D,CD,C9,6D,0C,FA,54,76,C2,BD,F8,BC,2F,CA,AE,A3,95,B6,C4,0B,C4,5E,75,45,6C,11,FB,70,C8,01,0A,D1,E6,F5,67,EE,1B,26,50,2B,00,E1,12,BA,65,57,EF,F4,89,FF,D0,AD,55,BC,04,81,7A,57,B6,61,98,70,C5,12,25,A1,CB,D4,E7,FB,51,25,80,78,6D,6C,F9,97,85,D5,8A,30,98,07,71,01,3E,BC,E9,DD,41,5B,C5,D1,05,AF,D8,8E,D0,26,FB,43,1E,7E,74,AB,FA,5B,39,A2,13,1E,98,63,C1,7D,6B,EB,48,FE,34,2C,E1,6A,61,3B,D6,CF,AB,14,73,04,2B,FD,21,FD,15,AD,76,D3,0E,AB,94,30,6B,FE,BC,0B,7E,43,90,C8,A4,CF,7E,6D,4E,C4,29,38,CD,40,F7,F4,E9,83,55,1E,CF,7F,28,8F,45,55,23,E2,AF,14,CA,7B,2C,0B,47,46,FF,62,19,6C,CD,38,93,08,A7,AA,1C,BD,6F,2B,58,0F,74,31,8B,FE,C8,AD,7F,B6,04,8B,06,72,CD,E5,10,B8,D7,DA,DB,00,5F,A5,04,D2,22,0B,15,D6,7C,1A,90,52,87,49,0D,56,83,43,58,00,36,34,ED,2A,1D,98,94,2F,F4,97,E7,0D,6F,C3,54,CC,B6,CD,21,23,3C,97,C2,06,A9,4E,39,0B,6A,CA,F6,FC,87,56,5F,49,56,33,FA,07,87,66,26,29,3E,F3,A8,25,F7,31,C0,47,5B,CC,D8,03,FD,13,E1,90,7C,8E,AA,9B,E7,A2,41,2D,30,2A,F3,BE,41,BD,C0,FC,C7,C5,CC,B2,12,49,07,86,2D,FA,9B,9F,9A,ED,80,9D,E9,78,18,CF,FE,71,26,B0,BC,32,EF,FC,3F,70,1B,13,53,8F,AC,9C,0C,13,96,60,AC,A0,89,E9,88,10,3E,EF,E3,A3,9F,C1,A6,E8,D9,6B,32,DD,B0,98,DE,E7,4C,BC,F5,B3,C3,6F,5A,C6,B3,74,45,F1,56,64,AD,C6,D5,60,F1,30,53,FC,BD,00,42,70,7B,8D,F6,ED,E9,61,EE,1B,34,C4,6D,9A,5A,95,56,09,69,50,74,C3,2E,98,23,97,FE,D3,F9,48,13,73,64,B8,96,9B,AE,AB,D5,0C,98,25,EC,A4,FA,A5,84,03,E4,9C,8A,72,E6,4A,73,B0,9D,AD,C8,B3,A9,09,10,AE,AD,49,5D,DD,9C,76,9C,4D,56,73,C8,B9,3C,1C,9D,B0,28,E2,89,29,1B,6B,FA,11,AD,E3,51,1E,91,5A,80,66,FC,9C,1B,43,61,86,19,28,A3,71,35,35,CE,B0,F4,F5,C9,31,CF,26,1A,82,0B,E1,94,1B,34,3F,15,61,7B,5B,3F,64,AC,15,8C,1B,55,8B,20,4D,3B,BC,F8,19,9E,E8,63,CE,37,14,68,6E,35,E2,F0,C8,C8,A0,5C,B9,F5,BF,B6,8A,E7,F4,CC,6D,63,B6,44,5C,62,7C,77,39,4B,24,7B,FA,C5,6F,C4,0B,47,9C,38,C8,3F,9B,99,13,E2,CB,15,20,0F,AB,E8,BC,69,2B,9A,99,3D,DE,A5,98,59,31,3A,AB,D7,8C,87,07,93,3D,92,12,48,09,6E,D7,46,EE,86,26,FF,16,AD,BD,07,62,A3,0F,77,2B,58,78,A7,D9,D9,C8,13,CE,8A,20,3D,4A,69,5E,AB,75,4A,32,0E,31,F7,F1,2F,3F,8E,C2,D3,9E,05,C8,3E,B2,D1,4E,01,6E,F7,0B,B9,C3,6F,7F,3C,2A,C6,48,B8,BF,D4,B3,3F,D2,29,D9,4A,FA,0F,B4,36,E2,B3,29,DA,57,C8,2D,61,45,D3,63,51,34,9C,2B,8C,A7,08,4A,6D,56,CE,50,B4,F9,68,BD,0D,F3,30,9F,9B,AC,65,89,1F,03,AB,15,ED,F9,AB,05,19,49,86,A3,BC,8B,0D,88,0C,73,6F,F6,C0,39,32,4A,E9,25,3F,DA,7A,E5,AF,6A,FE,6C,82,9D,78,11,75,55,ED,B0,D0,BE,50,86,F6,EA,31,5D,E9,E5,C3,D1,4C,D1,76,D1,01,B0,E9,DC,03,19,83,B8,56,35,2F,B8,C0,51,66,A9,40,DA,93,1F,F1,03,0F,77,AC,8E,85,DB,A8,4F,69,12,A6,BF,F2,E0,B5,3A,42,F8,FB,CA,58,7D,50,6A,7F,39,B7,45,1F,65,0C,0D,FC,83,B7,FC,13,B1,E3,80,9E,62,F2,0D,5E,30,98,2D,43,F4,7F,21,9A,3E,AE,14,53,39,46,5B,DE,3C,EE,0F,C3,52,1E,01,06,D0,54,64,7A,FC,F3,21,0A,29,E2,50,7C,7D,A8,2F,A9,E0,B0,23,11,01,20,44,08,A2,CD,6C,FC,A8,F0,C2,BB,B9,AF,BE,EA,96,6A,58,97,CF,23,61,E3,06,4E,92,3C,C4,03,81,28,AE,32,89,C2,D5,FC,5D,B2,72,C0,93,B1,DE,1C,DF,37,E0,EB,97,F7,50,ED,59,4F,2C,ED,00,91,47,55,72,17,72,39,3C,70,58,AE,6C,0C,C1,7D,52,4B,A6,FA,72,3F,6B,55,CA,A0,F7,28,ED,E7,40,15,EB,94,E3,41,75,CF,C1,E9,24,4C,71,8F,85,00,32,0F,F8,86,FE,21,DC,F2,DC,DD,3A,B2,1E,B7,65,B2,88,A6,D9,10,03,64,70,C1,F2,0A,52,5F,CE,6B,60,BC,52,CB,3C,9B,03,E3,A0,12,67,BC,5B,E2,CC,E2,BA,EB,36,FF,9C,59,23,FC,14,CA,4E,0A,8A,B0,F3,C2,7A,4F,B0,80,F7,1F,27,3F,DD,94,6A,4F,8E,49,11,0D,7C,18,5D,BA,14,65,BF,A4,A2,FB,04,4E,AC,C0,0B,3B,D8,00,4A,71,AE,DB,98,9E,C7,D3,14,07,2D,67,B9,1F,84,99,F4,42,8D,D1,3B,2E,30,67,40,A7,2F,8C,AA,DC,C3,8B,98,0F,EA,A0,16,39,5C,E2,9D,5A,56,17,40,6D,22,DE,64,D6,F5,C9,FF,55,94,65,B5,71,32,3C,DC,40,B2,F2,53,66,E5,E3,CE,51,28,2A,E9,66,29,9E,36,A3,DE,75,56,45,3F,94,AE,40,AF,B3,31,B9,8D,26,87,0A,A4,5B,FE,CC,72,40,68,7C,1D,28,63,B5,86,21,07,13,5E,A2,45,4F,48,88,1F,18,4E,FF,79,EC,BC,45,67,01,D0,E7,91,AC,F3,80,08,33,93,26,0E,46,D5,85,82,9D,4F,34,77,A3,FA,09,96,B7,33,30,94,EA,65,9E,C1,40,F4,27,89,44,67,25,98,84,CF,95,80,C6,EF,0C,CB,EF,F6,D2,C9,F8,88,65,23,21,2D,59,96,2A,B1,9B,32,38,B8,F1,3E,40,5E,AC,67,46,29,32,46,59,5D,E4,0F,1B,B8,A1,3B,FD,AD,A7,12,C1,3A,07,26,C1,4E,43,7C,3F,36,9C,BF,56,C2,3A,E9,96,F2,09,40,D2,F7,E8,0E,D4,16,94,6B,2C,19,F6,2F,B1,30,D8,89,37,19,28,C8,F8,A4,0D,35,A5,15,FC,C1,3D,C9,80,0F,A7,C6,48,C4,F6,D0,64,5E,89,BB,A0,5C,A0,6B,49,AA,F5,B1,DF,31,66,E2,64,1F,7D,C9,93,C9,AF,E3,1F,7E,D3,53,0C,09,1B,43,AF,F3,4B,EA,51,1C,12,6C,48,58,97,5F,C2,C3,35,F4,23,0B,2D,E6,13,63,9A,A4,5C,E0,3E,FB,3E,3F,A0,B9,4E,53,16,2B,3D,A4,67,90,3D,9E,5B,53,CB,FD,8A,2C,E8,F4,23,2F,96,E0,AD,2E,B3,D8,17,93,14,AF,D6,3C,74,A9,B7,29,34,74,93,42,47,D2,22,66,47,7C,06,F3,5B,86,FF,F5,30,B3,CC,DF,12,9B,8C,6D,18,FD,8E,E9,25,3B,D7,F7,54,3F,BB,43,30,4D,0F,8B,76,42,0A,6C,2C,F1,73,EF,F1,9A,66,11,B3,1C,2C,A3,09,73,F8,C2,7C,52,D4,2F,6F,88,DF,88,83,59,B2,CE,A7,D2,77,F6,90,0C,6D,C1,0B,41,E9,99,11,B2,76,8C,EE,63,8E,C7,00,90,12,7B,B0,96,63,DE,AE,0E,E9,B9,30,16,7D,71,A8,6E,DA,21,AB,8D,29,68,18,58,45,9F,C9,96,24,85,23,09,84,F3,BB,60,7B,EA,7D,B8,B8,42,70,19,0B,A5,8A,DB,AC,76,B4,98,F8,5C,1A,02,C1,EC,02,16,EC,45,5B,82,0F,8D,D1,0F,B9,7F,03,DA,9B,52,A8,70,D7,B6,79,4D,90,7A,62,7A,2A,37,25,2B,C7,AD,9A,3D,3C,AF,6F,CD,B7,2D,80,5D,37,4E,D7,CE,E5,68,5E,19,5D,9E,44,1D,FD,99,A7,E5,20,3D,33,E4,F3,8A,94,83,29,36,53,C0,47,AD,84,5C,16,F3,3B,8C,85,76,E6,2B,A3,4D,B1,0F,6A,56,53,F3,A5,D9,97,18,ED,D4,38,0E,E2,C6,FD,3B,52,21,11,90,EA,29,AD,19,BC,F5,FC,86,24,1E,10,BD,0A,A2,D1,84,3C,E9,30,F7,89,8E,B7,6B,2D,C2,FF,EF,99,89,A5,E4,BD,25,CE,24,79,51,B3,3E,D7,0A,42,BE,A3,89,75,5D,44,EF,31,8C,20,41,F1,61,66,B5,94,73,A2,69,62,42,55,97,6E,0C,04,95,2A,59,18,80,91,75,08,11,AD,53,2E,F5,10,4E,51,DE,B5,C5,1A,72,B4,E4,83,70,A3,3C,BF,BA,B8,D7,6F,8A,A1,FB,56,30,5E,70,6A,30,7D,A8,29,C1,F5,AF,53,2B,23,58,5F,27,39,1B,F2,53,DD,FE,E8,85,26,A4,1C,0F,AC,EF,8F,07,0D,F6,35,7A,43,BF,22,7C,00,F2,D1,3D,6F,3B,41,BE,59,5E,41,8B,D9,22,22,7D,1B,CA,3A,AB,B3,FF,9C,64,4D,58,76,62,F9,38,8B,F6,AE,E7,30,81,13,A2,2B,7B,EA,51,96,F1,BE,D6,1E,FD,9C,3A,A5,6C,6B,D6,72,03,8A,36,FB,FF,F9,63,74,7D,9F,5F,8C,45,89,AD,45,66,E7,ED,F6,F3,56,87,F6,E2,21,8F,66,96,9D,9B,13,2E,DE,BD,DF,B2,A1,45,48,3D,21,85,AA,80,8D,2B,D4,BF,88,8D,77,FE,38,71,78,6F,78,75,2D,EE,39,24,45,AA,99,3F,97,2A,26,71,7F,8D,FD,01,82,76,7A,AE,93,B0,EA,62,8E,A6,33,69,97,61,6C,BD,69,29,60,C4,BD,74,2D,BA,B1,2F,7D,79,DC,92,B8,F6,A5,3C,78,C8,AC,0C,D3,94,1F,8A,87,65,D6,AD,41,B2,8E,E8,ED,80,44,87,FC,01,02,FA,B1,A9,AE,8C,DA,D9,C4,C2,47,58,2B,18,93,8D,7C,1C,A3,08,D6,F7,59,B1,F7,18,0D,9E,76,A4,0E,A5,2D,F0,42,2E,17,EE,92,94,14,55,E4,B7,F2,02,75,8E,4F,E1,70,15,5B,5F,7B,99,CD,86,61,D5,32,06,A2,C0,92,2F,F1,74,60,46,65,96,E6,E6,96,39,B6,60,29,5D,CC,C2,8D,AC,32,75,EF,41,E0,17,47,F9,B3,F6,B6,61,54,3E,94,E7,E8,49,4F,01,00,C9,69,AB,F3,93,2E,5F,5D,E0,63,35,FC,CB,9B,DE,BE,54,0E,4E,A8,17,0C,FD,63,EB,0E,F9,C2,40,FC,3D,95,03,BF,AB,16,E2,5C,C4,6F,63,F9,5E,CC,87,68,10,F3,0A,85,ED,61,F8,BF,A1,7E,65,8F,35,E0,E3,E3,6C,E8,51,39,77,78,A7,E9,E8,C7,16,B9,B4,82,6B,9E,76,3C,31,5F,EB,F2,F3,F7,0B,A3,67,04,D3,33,A9,0F,28,72,A8,4D,32,4C,A1,90,2F,30,4C,87,AD,99,45,B6,C3,46,72,67,B1,F8,F8,E5,1A,F3,02,7C,AF,0B,9B,CA,23,CE,98,A8,63,7F,82,56,A0,DC,38,77,43,41,CE,AB,84,08,7F,F7,0B,39,22,37,31,F2,AA,4C,42,AA,CB,4B,6D,A5,B6,85,7D,B7,03,7E,59,E5,10,1F,23,CE,04,F2,F4,AE,B3,11,ED,12,16,A3,71,72,F2,84,46,2E,1E,4E,20,8C,4E,82,E0,F6,FF,0F,CA,F3,52,7E,19,7F,D8,01,B7,08,C9,41,F6,C5,C1,B7,E2,C2,22,71,8C,B6,DD,DB,25,CF,60,DD,8E,3B,A8,00,30,20,C1,BA,2D,3D,A2,23,10,60,89,F5,B8,2D,57,49,47,2C,97,64,FF,27,66,E7,A8,54,15,05,E8,09,39,4D,CD,88,CD,40,DD,83,A2,EC,BE,12,59,85,84,B5,20,2D,02,2C,CE,88,1B,5C,89,3B,28,BB,98,D0,BC,84,91,3D,B8,25,9F,67,33,CD,43,80,B0,D2,BC,12,90,5E,17,99,33,1E,3F,3E,BE,38,D0,F3,97,EB,1F,B9,15,BF,2F,CB,D3,F0,28,C9,39,5A,0C,6D,09,A1,11,B2,57,E5,38,01,6A,13,07,38,04,EC,E1,6F,FC,65,E0,D7,3C,8D,EB,47,72,B2,A4,35,BD,71,02,A8,5B,BA,B1,A5,A7,8C,04,AF,95,74,1D,34,70,E5,4F,0C,87,5A,53,16,9F,AE,FB,F1,AF,F2,56,6E,8F,B1,08,9E,10,91,AC,8E,09,E0,64,54,6B,57,77,04,98,AD,0D,47,E1,40,D1,63,6F,75,A7,8F,AA,56,8F,DD,B8,B0,94,D1,CD,6A,6A,FF,35,21,D6,7A,D7,FA,92,E2,72,F8,64,54,64,2C,A9,52,7F,0D,7E,C8,3D,D2,83,FC,F5,4B,6C,FC,13,FB,59,95,23,ED,CB,FC,92,C9,5C,F3,56,0E,AB,F2,F3,02,39,2C,DE,69,41,72,AB,FC,EE,A0,5E,7C,4E,80,FB,4E,32,0C,1A,B6,61,8D,A1,A8,65,8D,86,37,8D,CA,EA,05,F7,F3,74,66,6A,4A,0B,E0,94,26,63,57,7E,B6,5A,3D,A4,7A,1C,7F,56,F7,D6,2B,8D,CC,53,6B,0E,39,6A,07,E4,CF,9E,B5,ED,63,27,33,0F,5F,8D,4D,C4,1E,17,1F,86,F0,9F,90,70,38,C5,0F,E9,50,F7,82,B9,5E,88,41,0C,40,CC,31,7C,FD,80,05,45,07,F4,B0,05,05,E1,66,9A,2A,06,4F,DF,6E,2D,E0,03,4E,CA,E3,2C,50,57,76,9F,39,17,D3,85,94,D8,F1,2E,0F,47,44,A7,E6,E4,88,95,DA,33,4B,70,3A,8D,86,35,E3,BF,FB,F8,C9,BB,67,B6,57,55,3C,07,92,98,DF,32,59,1A,E0,76,7A,CE,18,DA,D4,B9,2A,64,F9,71,37,0C,C8,E3,37,38,16,05,60,0A,AC,E3,72,20,9F,AD,93,2F,5B,5F,6D,4B,4F,BF,E6,7A,C3,D5,2F,A4,CA,31,13,AC,59,49,9C,0F,03,37,10,E5,31,D4,81,98,6B,10,25,34,7B,52,DC,F3,9D,77,01,7E,85,3E,48,47,D7,8B,84,94,18,FB,6B,FA,D7,C5,9B,79,63,A2,AA,0F,A7,9F,CD,1E,B1,3E,AA,D3,FE,08,89,8D,3C,0A,49,51,DC,B3,66,BF,54,1E,5B,9F,D0,66,50,38,C4,E5,5C,D2,C1,31,CD,FE,3A,8E,D9,B9,40,EF,57,17,23,81,B1,55,C7,F0,FE,38,92,02,DB,72,4E,EB,0F,3A,6C,94,A5,AD,75,93,DF,54,21,7F,92,AD,31,12,EC,32,DA,B1,F4,A8,E4,BF,43,F6,1E,8F,9D,40,4E,B0,68,FE,97,DD,0D,D2,33,FF,4A,90,CA,35,30,A3,A8,A7,8B,49,25,99,8D,2E,85,CC,FF,10,95,04,5F,68,89,E8,93,C7,C2,BC,07,25,F9,54,22,36,B5,5A,A9,78,04,57,25,A1,93,22,50,CD,A8,D0,A5,F1,C0,9B,66,24,9C,14,8F,8B,A7,6C,AB,A5,DD,5A,25,75,FF,71,30,8C,63,25,A5,5D,F2,F5,3C,EF,91,88,02,68,F6,B8,03,59,6E,B2,62,2C,E3,A0,85,AE,34,88,45,29,88,9B,E3,13,82,82,72,D9,E7,C7,36,64,15,6D,4E,3F,94,DB,F0,6C,1E,6E,D1,A7,86,AE,D3,20,86,EF,AE,96,27,75,B5,33,3D,54,CB,8A,C3,7D,46,67,6A,A9,7F,28,51,56,BD,8F,88,9B,B9,CB,74,2E,CE,C8,D6,62,5C,56,C3,56,F6,07,35,01,4F,84,5A,19,B5,84,C0,98,AE,F3,5C,C0,73,2D,8B,05,15,74,11,11,28,06,C2,6F,1C,ED,FD,F8,43,E4,72,CD,1E,9E,3E,7B,02,21,86,3A,DC,E6,C9,61,D2,29,9A,05,43,AE,D2,43,B1,49,72,AE,9D,F5,20,4E,10,4C,05,36,8A,D4,09,DA,AC,60,C9,72,A8,14,61,EB,FF,96,BA,91,45,7D,19,F4,7E,B0,89,F5,DA,11,61,DB,53,2A,CD,9E,F5,33,8C,24,18,2D,6A,67,A3,3D,DE,03,59,0B,6F,A0,91,D0,89,0D,62,FA,6E,CA,1F,16,C2,2E,04,A7,D6,A6,2E,A1,F5,28,BC,AD,1A,95,13,1F,04,C9,FF,8C,56,AE,4A,06,F8,4F,3D,E7,3D,3B,72,39,BD,36,74,E4,7B,97,CE,FF,2C,D5,59,80,41,CB,EA,5C,8C,B8,C6,00,FC,F9,62,12,11,82,4B,EB,25,02,E1,AE,D4,2B,A5,67,BE,1B,08,91,30,83,CB,35,24,6B,C9,FC,65,09,18,B1,4C,86,BB,F9,9A,ED,21,B5,55,B2,E8,D7,17,78,40,72,93,CA,EE,48,AB,B1,82,62,9E,93,84,56,C2,22,AC,E9,C6,00,36,19,28,3A,B0,07,15,F6,F1,3A,3B,70,81,F8,46,7A,E5,1A,84,D7,D5,33,15,53,3A,D5,6D,98,10,B9,C6,DE,CE,F3,06,C8,BE,9B,EE,16,35,31,7A,BD,4E,E8,A3,05,29,61,8D,61,29,FD,C9,02,DE,0D,64,85,73,70,F4,32,57,AD,21,DF,8E,18,1E,7F,34,6E,EB,78,E4,40,BD,3A,2B,1E,0E,FD,F6,D8,FA,C5,63,E9,DD,D5,7D,87,CC,D3,84,93,28,46,C7,EA,5B,E8,41,C2,60,EA,58,32,1D,18,97,A5,96,9B,9F,FA,58,92,0E,19,C5,75,B7,5E,8F,8A,BC,ED,69,71,A7,DF,4D,73,44,8A,68,89,EC,FC,6B,80,AA,8F,3D,C4,8E,77,2E,2E,07,13,1A,E7,6E,86,46,A4,37,4B,AB,66,E4,0C,48,A5,00,32,89,70,6C,86,F0,58,81,40,72,75,15,36,BD,55,D1,FD,93,2F,87,31,03,A5,E0,D3,A4,58,90,DE,B3,4D,58,32,F7,8D,43,03,49,9F,04,D0,B0,1A,BF,C3,D2,F0,85,7B,F2,EA,C6,AB,9A,B7,40,B4,22,86,77,12,58,80,5F,25,2A,42,DE,7D,CE,F9,85,B2,16,E6,20,09,A7,53,FC,46,21,24,F1,26,61,D0,E9,C3,40,5F,99,46,7C,B5,7A,9B,1C,70,9D,C9,0D,C0,22,1F,D0,7D,00,80,72,CB,7B,CC,03,34,3A,9C,6B,AD,91,61,D2,DA,92,B0,B8,87,CC,D7,96,15,9D,6C,E1,64,5D,77,A7,81,61,5C,AC,6D,B9,24,26,84,02,C9,10,96,BB,28,AE,94,5A,AD,29,71,53,CF,DF,22,CE,AC,26,8C,CA,85,04,67,C2,42,05,8A,D8,12,0B,88,B1,8F,6D,40,7E,4E,40,7A,D0,B5,DA,84,B0,1B,20,90,D8,6B,6E,6C,94,37,EB,3B,A5,95,C2,28,60,BB,4F,BF,1C,98,E7,74,F0,E8,76,A9,61,FE,09,29,06,DE,17,17,47,7F,DB,47,24,25,3B,8A,19,3F,77,B0,8B,C1,9E,AE,C6,76,E7,21,7D,8B,21,66,B5,AB,57,6D,33,0F,4F,73,C4,7B,00,A4,38,B9,12,0A,BD,0A,99,BE,7C,C5,B8,C3,7D,15,EA,AF,56,00,C1,83,74,E5,9D,75,B0,89,77,03,2C,63,2B,F4,FE,17,71,F8,FF,F7,D3,B4,F1,8C,58,D1,1D,6D,0C,52,6E,1A,BC,13,FF,71,B6,73,40,4B,37,47,70,91,F2,04,C6,2A,E7,18,9B,33,27,D0,36,46,08,FB,2F,4A,39,94,43,62,CD,D7,56,BA,50,57,B8,67,24,6E,4A,38,B3,6B,F9,71,41,0D,E7,9D,EF,49,A5,55,E7,F9,F6,30,B8,6D,A6,99,52,5B,8A,4D,A7,8A,A7,19,AD,C2,C9,63,90,9B,6A,D4,37,47,73,A9,9D,16,81,2A,06,03,03,AA,40,13,DB,73,09,08,4F,D6,EA,06,4B,87,E1,1A,2D,BA,8C,A6,8D,12,2F,19,F3,DB,12,AD,6E,21,F4,D5,BE,D5,32,F8,35,5F,56,55,0F,71,D2,9E,6F,AE,A4,BD,B9,69,E0,DF,9E,08,54,E2,3B,36,1E,64,B5,95,F5,30,D2,25,06,9C,4A,B9,82,19,33,E2,A2,DD,8A,DD,CA,B5,2C,98,67,79,3A,D8,DB,99,AA,2B,F0,17,14,85,DE,70,FE,30,E9,0B,2F,97,F6,03,D8,5A,E3,35,08,5E,D0,7E,40,CD,B8,0B,7C,0B,54,50,A6,2E,43,22,5C,80,9F,1A,47,C8,B9,BB,82,DA,D7,7C,9E,65,13,37,BC,D9,CA,71,5C,D4,13,94,18,5D,81,7A,72,37,CE,92,4C,AE,EC,99,91,E3,DD,7F,17,AB,2F,47,87,A6,4B,FA,EF,96,5E,22,99,F4,2D,63,DD,B7,6F,30,6A,3B,14,B4,3F,C3,48,B1,74,A9,5E,45,5D,0A,74,21,3C,03,49,5E,52,48,1C,5D,9A,BF,0B,43,43,99,7D,39,3D,01,D6,20,25,15,C8,B2,77,8C,D4,7E,62,EB,FB,BB,61,94,DC,D0,4E,86,D1,10,FF,D0,9C,3A,F1,BB,75,E0,35,7D,FB,06,90,2C,72,3A,7A,75,11,00,B5,4F,1C,7F,E6,57,BE,69,C7,B6,B1,FF,63,1F,9C,6A,EC,3E,F3,D5,5F,45,20,33,A6,61,F2,99,86,24,22,8D,83,09,69,E9,90,36,97,16,EB,77,0D,DC,51,D0,01,F2,D3,0F,82,98,98,4A,FB,53,0B,91,A1,9A,DB,7A,4D,11,C0,71,38,B0,97,71,8B,BB,44,E3,05,DD,20,9C,14,90,43,C9,FC,15,3B,C0,00,BB,B9,70,DE,81,DC,D1,90,60,B9,12,CB,A4,EA,53,A0,5D,30,8D,9D,48,20,52,3C,1E,FA,77,52,9A,4C,DE,6E,76,A3,FE,8A,92,3C,D5,7C,D8,FF,B7,E4,AF,76,08,14,A7,FA,15,08,AB,CE,10,65,E8,5F,48,AD,9E,7A,CE,54,2B,E4,3D,29,6F,AA,CB,F0,C9,71,72,57,39,F1,10,5C,46,45,93,DC,1E,EA,C2,AC,53,22,B7,AA,1A,9E,E0,F5,44,B3,A1,B5,14,86,97,B5,C7,98,F4,D2,C1,1C,B6,94,C6,DE,F8,24,CF,75,0B,6B,B2,13,A5,C7,6D,24,17,CB,BC,9F,B4,12,3F,1C,43,D7,8B,40,AB,F2,20,E8,47,AC,5E,F3,2A,CF,8D,2F,41,3D,05,08,B4,59,13,36,E6,78,B8,36,5B,23,D5,B6,BE,15,04,10,6F,68,EA,4E,E4,BE,66,C5,F2,B3,55,66,0D,D2,05,61,FD,36,A3,83,68,DE,01,59,6E,38,48,34,97,14,27,AF,9D,FE,22,B1,3F,ED,4A,C7,0F,E6,49,66,84,98,9C,87,64,FB,8C,B8,D0,5A,D9,3A,6F,28,FF,73,5B,5E,2C,9B,CA,66,F5,FC,EF,D3,1E,87,AC,AA,D1,68,47,3A,E5,AF,63,16,E7,3E,04,11,55,55,93,C0,25,17,30,00,C2,CF,69,F4,0C,B4,91,96,0D,85,1F,4E,01,8D,55,45,9B,5A,4C,BB,EA,74,48,E5,AB,CA,9C,7F,79,3F,48,11,D5,AE,F8,36,55,88,5C,2C,E6,8D,B8,38,56,9B,01,FC,E5,7D,FD,E7,E8,BB,0D,33,89,68,94,77,3D,65,61,8D,77,E0,1C,23,1F,72,F9,D1,69,E8,07,B6,98,41,3D,AA,65,21,CA,A6,64,E4,CB,48,26,5F,8E,94,33,EC,1C,67,CA,92,DD,7D,B0,D7,5A,B6,B9,50,67,FA,4B,60,F6,3B,BA,C1,CD,F2,9A,ED,8D,EF,75,0B,D3,E2,9B,87,DC,63,B5,B8,00,34,1F,49,11,02,D5,FE,2C,DB,3D,B6,54,FE,F5,9C,A4,5E,EA,1F,70,64,85,88,FB,B9,17,C2,7C,8A,44,A3,9B,0A,18,D4,12,56,2A,9D,5C,E7,93,6E,7A,60,78,1C,C8,60,C9,EC,C2,81,1D,D0,D2,C2,76,73,5D,35,7D,AB,D2,BC,21,2E,8A,56,85,B1,5E,33,2B,D7,5E,85,6F,01,71,BB,98,66,9B,BD,92,46,B5,FF,39,16,BC,A8,4B,75,DF,AE,08,45,D9,92,4E,2A,63,8A,8A,1A,7A,02,5B,D2,62,91,22,B1,93,05,AC,3E,28,AE,DE,19,66,D6,6B,89,53,72,7E,B4,CC,34,77,E5,36,3D,C5,56,C1,7B,A7,19,39,CF,D2,42,6F,AB,39,6D,75,FC,FD,7F,13,33,D2,9E,8C,C9,3E,87,D9,C5,40,85,93,B2,82,57,A3,4B,11,49,64,59,0B,87,57,B9,BE,56,36,EB,B0,96,8C,CB,44,99,FD,B3,A7,3A,E5,33,D9,DD,2C,78,AE,D2,8F,4E,7F,C0,C3,AC,C6,4F,D2,5F,E0,45,2B,77,79,24,23,AC,BD,CA,8B,18,AA,FE,11,C4,BA,B8,20,2E,CD,BE,E9,50,CA,5E,E5,5F,CB,E6,35,FE,C0,EB,EA,5B,63,ED,FE,2B,90,69,F7,ED,14,34,53,5B,82,62,4E,A7,F6,0A,29,BF,DF,CF,D4,27,55,E9,E7,6A,E6,28,5E,55,A9,2F,E1,79,B3,F0,0B,E2,8C,55,B9,36,C2,79,24,09,A0,DD,44,E8,37,BF,C0,B9,AD,4F,E6,E5,85,54,3A,0F,90,EF,2C,6A,01,8D,E5,F7,2D,F3,97,39,AB,3C,1B,5E,EA,66,E9,1D,C2,A0,F4,AD,17,AB,B7,B3,9D,60,A6,54,C3,48,C0,6F,13,0D,BF,CD,AA,E8,61,9E,1D,4F,5F,CE,62,92,F4,A1,07,AB,54,34,E7,87,D8,4C,95,61,3F,66,6A,C8,D8,F5,88,C9,F0,6C,93,9D,C2,A9,6C,37,8D,45,A4,F7,9F,4F,56,7A,0F,92,D7,7B,0B,0E,36,E2,97,8A,D6,C7,53,D3,C0,1F,E8,68,72,9E,0F,B4,C6,F6,7A,E6,AB,F6,7C,18,3C,58,76,27,20,D1,79,A6,57,3C,D6,8D,30,8B,C6,36,B8,54,B1,60,31,AD,21,A1,8A,C2,3F,CC,98,6E,C8,FB,BE,74,59,E4,4E,92,C8,FB,5A,F4,02,33,D3,AB,1F,DD,FF,8A,07,29,34,EA,C6,DD,CA,B0,A0,1A,82,CC,8B,AD,D2,B0,D3,55,DD,2B,AE,7E,0C,39,8D,81,17,C2,20,0A,F0,0B,1F,69,2F,F7,9E,B7,E5,79,AF,5C,C6,CD,2C,B7,07,45,12,13,27,AB,3E,3A,31,DD,87,EB,B8,4C,D8,BD,D5,A0,A0,09,3E,A9,75,25,86,D2,ED,4A,1C,66,B0,B8,97,FC,F7,3C,3D,38,28,A8,45,B2,B0,67,DC,45,DB,19,7D,BE,45,62,72,BE,F6,D4,FD,B1,1A,CD,D0,52,60,1A,51,C0,5B,D8,29,94,40,81,B6,9D,3E,45,23,29,D9,67,C4,E2,8E,67,70,F1,31,EF,BB,D6,57,33,3F,35,31,93,D3,1A,79,D9,C6,54,6D,18,6C,B1,3B,A4,44,BF,95,02,70,42,B2,38,C4,4C,E6,F9,02,F2,81,D6,C1,F6,3D,28,29,0C,2E,80,27,8F,6C,10,01,6B,CD,4E,E2,AF,76,76,AA,0A,02,3F,75,96,88,E3,EC,10,D5,E2,F9,E3,21,A3,53,E9,73,65,5F,2F,1D,36,15,DA,27,89,D2,73,E2,26,C4,99,1E,91,9E,A6,02,3A,D6,15,5D,7E,DB,24,19,27,4E,85,2C,51,63,E4,93,C4,37,E1,ED,D1,5A,37,A5,74,AF,5A,CA,DF,7A,F6,80,AB,DD,14,8B,3F,8F,F4,B0,8C,BB,BF,17,8F,75,E8,45,2A,75,42,EF,CC,6D,D7,B0,90,AF,E8,3E,1C,9C,63,4E,D8,45,D7,4B,4A,CA,CD,94,C7,EB,63,C8,E1,76,74,B6,2D,B0,AD,8B,D2,85,73,85,3D,0E,76,B1,E6,D2,5B,0A,B2,D5,E9,22,82,47,BD,A6,46,A5,53,7A,59,7D,1D,78,2A,F6,5C,7B,13,59,A6,0B,E6,6C,8E,5D,6C,F0,33,E2,75,4E,A3,A9,ED,53,CA,9E,B9,C4,F2,B0,30,A2,D4,BA,1F,24,06,23,89,64,55,99,F7,00,20,AC,EC,F2,50,81,BB,50,55,AF,86,79,8A,F2,43,83,28,A9,F7,BC,66,BC,2D,42,87,73,81,64,19,43,D1,22,94,CD,55,B2,E0,D9,2D,F9,2B,B5,AF,A2,24,28,4A,85,CB,F0,9B,14,2D,56,CF,81,A7,31,56,FC,6F,BA,43,59,B8,48,CF,61,70,3F,B7,3F,99,AB,C2,28,06,F1,F3,A8,F7,D4,91,E7,40,C9,EF,35,22,11,56,E8,F0,38,C8,73,3D,8B,34,AF,B3,13,67,4A,D6,47,55,3E,61,C1,81,75,2D,BC,31,C1,04,3A,7F,F1,2A,1C,8C,1A,5B,C8,36,C9,C0,12,35,C2,41,C0,77,E3,3A,EE,09,6E,EF,E0,7B,24,92,78,28,99,9D,29,4D,B7,06,1F,CE,A8,CB,00,A1,8C,3E,13,15,AB,44,AD,16,1F,19,9E,1D,35,01,11,55,2F,00,C4,57,54,C0,01,15,0E,96,C5,87,2D,DC,A9,76,DB,7F,59,1A,EF,EF,43,3F,D0,CE,9D,04,EE,DC,38,91,03,8B,83,00,C6,AF,6B,EF,D4,2A,09,46,A9,54,06,64,37,09,0D,16,D5,7C,9D,35,72,18,D2,E6,5B,F1,63,BD,81,71,09,BB,D7,9D,47,03,B7,15,C1,94,37,8D,0B,E2,9B,10,34,4B,62,69,C7,F1,00,4B,67,D4,F3,A6,7B,A2,11,9B,D1,5D,58,3A,A1,15,88,4A,0A,04,A4,1A,92,8B,31,0A,00,38,F1,76,46,AB,17,38,4E,08,D4,97,C5,72,59,97,1A,D0,7E,D0,E0,16,5E,0B,04,0C,B5,10,7E,0D,19,0F,7C,AE,03,94,49,1D,68,BE,BB,DC,21,4A,FF,FA,92,9F,09,74,68,29,2D,CB,23,D7,37,D3,C0,AF,88,7C,6D,D1,C7,7E,A1,D4,3E,2D,59,63,6C,D7,95,D4,6B,9F,C2,8A,8B,EA,AF,1C,E5,66,1E,89,67,28,88,50,D7,5D,FF,0A,F5,53,AA,AA,EE,93,B4,50,8D,AA,A7,52,78,36,05,AF,5A,92,3E,0F,09,CA,B5,1B,7C,A3,3F,D6,26,43,18,9C,3E,DF,5E,DD,B8,AE,D5,04,06,71,DD,8F,7B,B8,53,76,73,84,1F,35,DE,F9,38,33,ED,09,60,F4,46,F2,A6,ED,7C,A7,2C,B1,98,78,F6,A2,03,C3,08,FF,4E,84,EF,D2,94,61,8F,41,75,5E,1D,82,CC,BF,E4,F6,1C,23,05,2F,B5,A5,1E,79,83,FC,14,92,23,75,87,03,76,5C,72,A7,9D,74,3C,8E,2C,B1,3B,9C,7C,32,AC,02,36,DC,B0,46,C2,0D,64,70,B9,F8,7A,AE,94,DA,03,D5,A9,D0,DD,3E,8C,2C,CE,F4,F2,F0,A8,DA,FF,6E,3B,68,D8,01,70,85,5C,82,19,C8,8F,E4,A6,59,13,4C,59,5C,9D,35,81,5C,B6,CE,32,A5,4D,86,A5,E9,02,DD,09,73,9E,2C,4F,F6,CA,00,34,F6,50,AB,7B,90,F1,E8,E1,72,43,1D,9C,0B,88,3E,9C,97,91,7D,AE,6E,DD,33,7B,2B,7E,AB,40,CD,40,34,C0,C3,E9,EC,5D,C6,C8,EB,15,68,B8,B5,5E,F5,B3,88,02,E4,01,1C,D3,90,43,91,5A,6C,32,D3,F8,12,C9,ED,47,2B,4D,63,18,EA,F0,73,E8,F5,70,A5,48,BE,B2,0A,44,C9,B9,5A,BE,6C,11,B8,59,8F,8A,1A,84,89,83,31,FC,63,95,EA,5B,50,14,45,9B,9B,E5,A1,13,7E,02,D1,AC,ED,7C,35,71,75,24,2A,4A,04,5C,F8,1E,AD,A4,B5,DD,EA,FF,2F,33,D0,62,2E,19,CB,4A,70,34,74,F1,1D,36,78,A7,50,E6,41,70,3A,16,0D,40,4D,5A,80,B1,AD,A9,E7,A0,AE,5F,5C,C6,50,51,17,72,19,54,7C,39,A3,05,3A,AE,3C,E2,72,02,32,78,A5,58,DB,BA,F7,21,CD,79,32,E6,77,37,61,EC,0A,4B,3D,16,49,DD,36,6C,73,20,75,A3,86,91,AE,68,AC,46,60,2E,14,32,87,49,69,BF,10,7D,3F,3E,9E,62,83,CA,93,84,C4,96,97,E6,69,EF,6D,6C,2B,90,F5,EF,35,B1,C4,B5,ED,FA,31,9C,49,7C,15,71,7B,6F,14,A0,A8,6B,95,9E,0B,4E,07,32,0C,4C,FC,61,82,4E,5E,D6,57,4A,DE,97,EF,FE,0E,03,E9,20,64,DC,F9,11,25,61,E8,CB,45,3C,71,26,EC,96,FE,A5,5A,0A,DF,16,1D,99,9D,35,79,50,42,E7,8B,AC,B1,3C,80,DE,62,33,01,32,94,1E,BD,B4,5C,9A,2F,77,94,5D,2C,15,9E,01,62,59,83,D0,FA,9D,B2,45,B2,07,0D,FF,38,55,53,22,A7,68,A7,8E,53,4E,5F,9F,A0,E3,9A,51,DA,68,06,15,2F,4A,7C,C0,EE,D6,03,D5,69,3C,7A,15,C9,ED,18,CF,F0,92,C8,FF,93,CF,32,2E,FA,D7,14,D8,13,9E,FC,DB,BD,4F,45,E5,FD,C9,C0,03,BD,6D,CA,40,BB,47,2F,14,A9,7C,6D,82,A3,EF,44,76,2C,18,88,F2,D3,C7,9E,AE,A0,E1,DD,26,E5,E1,EA,8A,22,73,E5,06,A2,93,13,19,77,54,41,0A,5C,E9,31,B9,90,08,86,34,8E,F9,D3,36,55,B8,08,70,6E,75,E2,D7,1B,84,6D,6F,C1,FE,44,69,31,7F,29,C1,9F,67,D2,03,0D,90,CF,10,41,29,39,EA,78,4C,8E,36,91,71,F1,44,38,68,93,C9,01,F2,C2,E9,D8,FC,47,A5,57,53,52,59,F6,60,0E,54,86,DC,E0,51,91,3F,41,7C,6A,7D,10,66,2E,39,95,EE,B2,F0,5A,75,9A,A4,5E,04,CE,64,C4,A7,AF,45,99,DA,FE,D6,F4,75,53,A9,40,1C,3E,A8,2D,DD,3A,E9,63,86,F3,C5,A3,9A,F6,05,CF,1B,D9,FB,8C,68,3D,2D,B4,E5,14,E2,AF,77,C7,15,22,4A,0C,FD,EF,58,A5,40,EC,3B,00,8D,7A,88,AE,C2,88,D1,3D,0D,57,0F,A8,05,94,97,1F,34,5F,C3,28,6F,2D,D4,A5,CB,03,FE,AB,FA,36,D0,DD,51,73,F8,93,66,F7,B7,3B,1B,AF,14,D6,9E,F3,5F,10,36,12,90,1C,FF,78,27,EB,51,96,F2,60,E3,10,1E,6C,0F,09,FC,37,1C,03,D4,C8,AD,0C,3C,83,F3,3F,6D,59,BD,57,CC,DC,98,70,55,C4,25,72,26,42,50,77,F9,06,09,F6,F7,51,09,9B,F2,75,0D,E0,22,A7,3E,D0,16,E0,6F,94,B9,92,EA,ED,0A,D8,CA,AF,7D,9B,26,A7,1E,BA,B1,50,F0,12,B3,22,45,8A,4E,DD,73,F6,F3,B8,31,55,E0,36,48,11,90,94,69,E0,B9,F7,20,18,46,E9,9E,2D,C6,14,AC,8A,37,35,2B,B8,6F,30,D7,DA,9F,5B,88,DA,ED,03,2F,00,93,B6,B2,28,BE,A1,C7,C1,31,10,B8,83,C0,38,87,BA,0D,3C,A1,35,A0,0C,15,10,E2,4A,65,6D,2F,88,8F,3D,03,74,93,3D,47,5C,72,E0,D9,4C,92,AD,E3,F2,A5,D5,26,7F,6B,2D,1B,97,15,9C,F6,09,42,9B,7B,A0,B6,66,3B,4E,1E,34,FB,AF,DB,CE,E0,74,63,12,B7,00,3E,D8,14,E2,B8,EE,E1,F9,2C,95,1F,7F,95,CA,6C,54,37,D0,72,CC,C2,9B,E3,9F,CC,A4,59,C8,EB,68,FF,5D,6B,7B,47,CC,99,6D,0A,D4,BB,95,FE,99,69,A8,06,57,18,91,AF,CB,3C,51,4A,05,C2,C8,EC,47,6D,7E,C8,EA,D6,5E,20,14,95,5F,1E,E2,82,43,0B,42,D8,E8,89,DC,9E,32,62,E8,33,2F,40,7D,D8,4F,42,FF,07,23,56,3F,82,F9,E7,55,69,BD,BE,F6,98,6B,8D,A6,C2,80,D7,ED,84,10,87,6F,90,7D,36,DC,01,92,AE,EA,8B,78,2B,E3,1F,D3,FE,CB,3C,D4,FE,AB,95,09,70,5F,9C,FD,CA,94,70,A2,5B,79,41,EC,05,8A,8F,A2,49,8D,8F,82,EB,ED,B5,D1,58,76,5C,97,39,F6,1C,16,11,2A,04,B6,41,2D,E5,ED,B7,A7,04,CA,E9,CC,FD,20,FF,C3,11,65,9D,DB,A6,B9,2A,8E,86,F1,C9,83,4C,40,54,82,61,77,07,68,0C,0A,1B,4D,55,50,A8,30,E8,1F,44,22,A3,76,4A,5E,D1,74,53,EC,BD,51,F2,A4,F2,E2,6E,28,02,4E,70,EA,7C,47,E1,A9,10,FD,B2,45,D7,6A,58,D3,F7,2D,BC,39,A9,FE,E2,F3,E1,F7,6A,E5,8E,CC,E7,CA,D8,06,02,F9,15,51,A8,C8,73,6F,5A,57,8B,85,2D,C9,A8,46,2A,41,B1,6E,8B,3B,92,8E,87,9F,00,BF,1B,AF,CE,BA,57,AB,DF,D8,8C,47,BC,EF,9F,FD,82,96,E9,87,97,A8,13,82,36,77,E6,24,F3,00,1F,B8,FF,97,18,36,23,B4,5A,05,D6,33,B4,03,9F,AF,F3,32,58,75,0E,B7,C2,8D,FA,69,85,73,3D,C4,14,1D,2A,7F,CC,C7,A2,B9,61,1E,90,5E,55,BA,E8,E7,03,86,98,40,30,C7,7F,25,0E,BC,B6,FB,3B,F8,C9,BC,8D,AC,F1,90,7D,51,75,59,83,29,19,E5,B8,93,02,73,74,17,7C,C3,85,5C,85,7B,57,A8,90,82,A7,87,31,FC,39,E4,9F,A0,57,7C,03,3B,AA,07,71,22,55,44,2A,9B,49,73,16,90,87,BA,D9,C0,A7,7F,D1,C4,49,B5,3F,6A,91,86,5F,2E,C4,57,B3,78,8B,2E,CE,37,84,11,AB,E7,A9,B4,B8,C2,E7,12,74,FF,89,43,47,45,4E,B7,65,6F,59,7B,3B,76,AC,93,F7,89,E6,D8,B1,56,46,9E,41,EE,0E,6A,2F,78,DB,49,25,76,11,FB,79,0C,F5,DB,F8,14,82,BA,63,6C,13,4E,6D,89,D9,07,B7,D5,7D,69,3E,E1,81,34,35,A3,63,E5,BE,46,C0,55,83,F9,A7,9B,E8,AB,2F,10,4D,1B,E5,F0,0A,81,DD,58,65,72,8C,E2,9A,BB,E7,2A,0B,18,8A,57,98,78,6F,B9,7B,08,8C,7E,1A,0C,69,9C,88,AF,61,9D,C6,B7,D0,26,AF,38,A8,3B,37,23,DB,59,88,DD,2D,FD,D3,4F,80,F0,E5,6C,17,E2,16,2F,71,00,E2,C9,CB,77,B4,59,AA,E7,92,F2,FC,40,02,08,07,21,83,F9,F8,B5,4A,FC,BF,53,6B,D2,E9,68,20,82,69,03,25,3D,2F,1A,11,AC,0A,B8,2A,43,C1,BD,10,3B,D3,FF,36,7D,26,08,CC,30,45,B4,24,B0,88,7F,20,79,22,02,4D,75,A5,C2,D6,55,B1,7B,CD,66,5E,58,44,98,D1,EA,52,4D,B4,58,AD,A9,22,DE,04,11,DD,2C,EE,D4,5F,1A,69,E5,14,57,78,3F,7B,52,C0,51,43,1B,C1,A5,F4,E1,4A,14,CF,86,A8,32,72,D3,F7,E6,3D,44,31,74,38,FD,1E,E4,A3,C2,0C,2E,75,B3,DA,70,AB,C7,25,72,4A,21,48,63,42,61,C5,58,7A,0E,2B,A8,95,CC,0B,E5,F9,A3,15,94,8B,17,BF,F8,43,DB,C9,75,A9,25,50,C5,16,20,BE,7B,CB,D6,40,49,4B,61,54,F7,3C,3B,C7,DB,D1,A7,FE,A3,FF,EE,29,D6,AD,56,7A,19,B3,E0,AD,E3,87,5A,9A,0A,6B,FC,98,72,E4,27,EB,D6,BF,B6,20,EC,17,2E,B9,83,75,10,E1,21,49,50,44,ED,40,01,E6,EB,88,EC,3C,E3,C1,61,0B,71,79,64,BA,B8,F0,DC,C9,19,49,EC,49,91,F4,26,B4,F2,76,16,C1,7D,BE,E3,95,BE,07,8B,63,4F,83,84,20,33,71,17,BA,98,C3,6F,17,41,0F,FF,98,04,0F,CD,71,F7,F5,38,ED,D3,8A,5D,70,6E,B9,C1,EA,9C,C2,6C,85,EE,01,62,DE,61,66,56,32,9C,92,AF,C1,FC,65,93,17,09,6A,81,F2,B4,5C,0E,6F,0B,CD,66,B6,92,40,97,D3,71,08,12,21,21,63,C5,74,79,9C,66,B0,33,0B,F7,42,20,48,53,51,5B,C5,68,ED,72,72,42,FF,6A,86,DC,6A,C7,15,E8,B0,4F,30,BE,CA,76,5E,E3,0B,2F,F0,51,E1,77,BA,B8,A8,4B,3B,C3,AA,57,D7,A9,38,79,92,E1,FE,DB,67,FB,64,A2,57,4E,AA,88,C4,30,22,B3,AF,51,C4,72,C6,E5,F9,80,E5,0D,07,23,D1,0A,D6,7E,70,F8,BD,F4,57,24,B2,3B,EE,6A,29,C9,E7,CD,66,4D,5D,29,06,17,42,21,3C,B8,E9,B1,02,A1,81,60,90,A4,58,B4,F4,1F,29,6C,D9,7C,BF,AD,4A,8B,92,ED,BA,A1,B8,27,AA,75,6D,64,DF,EC,43,21,72,68,0C,BD,69,21,0C,2B,CE,BC,5F,FF,45,12,8E,89,B5,5F,E9,73,F8,9B,63,0D,B1,8E,F0,F3,C8,1A,4B,77,22,49,1C,71,5D,E5,2A,6D,70,89,4E,F2,86,E8,84,A1,C6,BD,A5,64,07,FC,3B,FC,7D,B8,C6,0E,81,05,03,9C,92,FA,1C,22,65,89,16,9D,15,B4,09,3D,DD,2D,54,DD,3C,D4,83,B6,FF,B2,E8,66,79,94,FD,C4,CC,2E,1B,20,44,BD,4A,16,BB,C5,CE,5D,42,B3,A6,FA,1D,91,42,1A,EA,46,4A,DC,40,76,E6,3F,C9,5C,2B,D0,B8,DA,BB,0A,9E,1A,2B,4D,4E,E1,85,95,B7,14,55,D3,D8,37,35,12,09,0A,E4,46,92,2C,E3,FF,7E,19,3A,63,F9,F6,C0,01,0B,F5,66,67,63,8D,DD,56,BC,3C,DF,FE,26,28,8A,68,B4,F4,31,28,7A,A8,9E,B3,E8,24,7E,47,FC,66,68,5A,F8,E6,28,94,B5,D4,3A,23,E4,CC,F2,4F,38,DD,6B,44,3D,47,53,14,49,3D,35,03,68,0F,5D,F4,BB,FD,C4,6F,F9,35,DB,D0,B4,CF,25,4A,AB,7A,2A,B0,5A,29,AF,6C,93,A5,67,B3,33,C8,2A,DB,D9,75,74,DF,11,B1,B8,38,73,BC,01,63,75,5A,E1,40,F3,2B,67,D0,0D,55,6A,71,84,63,B7,30,4B,82,F1,69,C4,7D,5C,FF,85,02,47,40,76,FA,19,B3,04,A0,B1,46,07,7B,87,13,D1,90,D0,D8,35,D5,F5,1C,7E,9E,13,B8,AC,37,BF,4E,C1,EF,11,64,D3,F9,CB,1E,A8,E2,ED,CC,0E,DE,24,68,CC,14,62,22,63,81,46,0E,EB,DF,55,3D,B6,F8,1C,BF,3B,8B,FE,1B,91,08,32,8F,9F,69,D4,8E,01,47,8E,0F,9A,7C,06,B7,FF,D7,62,B0,9E,6A,F9,A9,89,2C,0F,34,44,EF,36,07,04,EB,11,EF,B6,F4,28,15,EE,E9,D6,12,04,04,13,C0,93,99,48,93,13,EF,2C,96,32,7D,CE,0E,51,E8,6A,8E,FB,27,70,09,5F,74,23,98,80,5B,01,C8,C3,4F,C5,1E,6E,64,D1,DC,9A,35,7F,F8,25,14,74,40,D8,3A,C9,B2,86,F8,2B,2C,7B,65,29,57,06,AF,69,14,3C,C1,B7,89,80,C4,82,DC,CC,12,64,EC,DD,2D,1D,F8,1F,CE,77,B8,A5,38,64,57,8D,FB,D5,FF,E7,DC,38,E0,F5,F1,A5,19,85,2A,8A,16,8F,E3,E6,52,EA,CC,CE,90,6C,EF,1F,2C,3C,E4,18,87,19,E5,E7,58,8A,37,7F,73,E5,BF,63,25,00,A9,7F,1B,17,28,BE,CF,09,FF,F6,D1,6A,D0,6F,30,9B,EB,9B,C9,47,9C,52,3A,5B,83,92,DD,88,E0,2A,3F,B1,3C,C0,0C,0D,6A,82,F8,A6,E6,27,34,21,F1,0A,16,7D,24,37,31,D4,9F,38,FC,3E,17,D5,6E,A9,20,E8,F8,99,DD,AF,0F,58,E9,15,F0,86,18,D9,73,28,84,FF,E9,7C,D4,44,4D,72,70,AD,06,B7,67,F6,89,07,D9,15,3F,85,5C,2A,4B,38,73,14,35,C1,21,AE,32,91,3E,61,6B,F6,02,1D,6C,A9,98,29,C9,11,BF,6C,2E,74,A5,D5,BD,CE,2D,79,0E,A5,BF,78,0D,78,96,62,41,C5,8A,6F,75,95,3E,21,79,11,E1,29,6F,5D,66,FD,83,11,41,3E,95,94,4E,50,AE,55,73,F4,E1,95,D9,26,83,8C,14,93,75,4A,8B,EF,F5,F5,F9,2B,BF,81,01,8A,8A,42,4B,18,CE,B3,C8,6C,D6,00,3C,D6,1A,97,E4,48,5E,FF,93,7E,B0,7A,A3,EE,F2,75,79,9F,E4,42,5C,E8,73,FA,EF,A8,E9,0F,9F,36,BB,69,D3,78,28,47,E3,5D,4E,4C,C6,A6,4F,65,D2,31,5C,F0,FF,85,A1,32,EA,85,70,BD,14,09,0F,14,3E,88,C5,CE,97,43,81,57,33,64,B1,BF,A6,B4,AE,D2,BF,69,16,05,BB,6C,01,59,45,0B,42,05,F6,BB,D9,CD,22,5C,88,55,AD,1F,2E,B2,7C,BC,53,6C,D2,08,C9,BD,A6,6C,A5,4F,93,56,3F,DE,80,EB,4A,E3,B3,7B,F2,06,F7,1C,03,DB,A7,A7,AE,B2,4D,4C,AE,5A,32,BF,A0,0F,EA,6B,1C,73,AC,C0,3B,9A,F7,79,E2,A2,C2,2B,26,9D,E6,D2,A8,B7,EB,4F,41,9E,C5,4E,E7,73,D7,49,CC,71,2F,1F,5E,80,C6,0F,8D,BF,74,D0,5E,48,4A,C5,CB,7C,07,37,BD,F7,57,91,D9,84,19,6A,C5,AD,D0,2F,88,39,20,23,D4,34,8F,C0,4D,16,E4,FA,43,F5,9F,3C,66,5B,B2,DC,25,2F,DE,A3,43,7A,86,2B,32,AF,47,33,7F,CA,89,57,4D,0C,08,64,F1,70,F2,A1,FF,01,1C,C9,CF,D6,B4,46,24,45,76,0C,C8,25,49,54,47,81,1D,27,76,1D,21,9D,2A,73,5D,05,26,2E,8C,59,FF,F1,67,A5,42,80,12,2F,AD,AD,3A,96,76,3D,CD,3D,F7,2B,D1,B3,5F,1E,C4,32,FD,C6,C4,A1,9C,D2,90,EF,92,E0,32,57,4C,EF,C3,10,28,82,84,C3,E8,34,26,32,00,9D,81,50,86,AB,FF,66,BB,B4,AD,8A,A6,17,53,B3,0D,A1,9F,52,66,ED,9B,B6,60,6B,6A,F3,50,E8,50,92,15,C4,F1,14,1F,9D,5A,93,81,3B,FC,A1,D1,A0,1A,A7,84,DE,65,BE,31,5D,85,2C,44,31,8A,BD,66,C7,5F,93,78,36,62,86,E7,9D,B6,52,FF,2D,45,61,6B,BF,2E,6C,4C,AE,14,FF,24,9E,3A,D5,2E,0C,FB,AF,3F,D2,44,66,D4,A2,3A,E9,8A,3F,09,88,21,12,25,30,B7,FD,CA,96,1A,6E,85,AB,4E,A7,81,90,90,99,C3,BC,16,E3,9D,29,49,4D,B6,74,07,07,B8,29,80,F7,9C,8B,C0,CB,5D,D3,A2,BD,4A,EF,51,4E,8F,AF,C5,38,9C,30,CC,3B,45,4C,30,EC,24,AA,C2,03,D4,0D,18,C2,18,28,88,1A,51,9C,95,47,71,38,09,12,F4,E2,B5,A3,CA,C9,E9,B7,5F,76,0C,6A,8F,2E,16,AC,BA,0B,A4,82,CD,FC,8C,1D,8D,BF,E2,7A,D5,22,47,95,9F,10,A2,54,FB,28,56,F7,A2,63,9F,0A,6C,80,A0,F3,6C,86,4F,22,A2,28,B8,ED,D4,EF,37,41,AC,22,0B,14,9B,DF,8B,3D,EE,74,94,70,CB,9B,BD,CF,71,95,84,32,23,E1,00,1A,65,45,0D,E4,2F,2B,73,45,C1,CF,D9,7B,85,24,39,8D,D0,6D,30,EE,0F,73,97,03,E6,DE,B9,F1,01,FD,7F,A9,DE,07,9D,C8,60,67,5D,77,70,6C,20,91,42,7B,94,6E,74,73,57,6E,1C,69,E6,05,45,89,44,40,0A,F5,B5,C5,E1,0C,49,C3,91,7D,DD,D6,02,BE,C7,A7,83,04,46,62,28,6B,BD,77,8F,EF,60,81,AC,86,E9,F3,DB,E6,66,11,3D,E1,62,8B,2A,4B,8A,05,E4,08,9A,F1,E7,53,93,6B,1B,A7,6B,1D,0E,ED,47,25,63,2F,6E,09,D6,DB,D6,41,9F,BD,07,AF,D7,D6,D9,C0,BA,10,E3,5A,22,A4,4A,FD,5B,4C,B6,B3,6D,FA,0C,1A,91,B3,3B,FD,04,3A,CE,11,4C,51,E0,FF,06,B2,34,03,1A,8C,24,F8,CA,7B,FC,0D,9A,82,AD,79,5E,7E,FB,C7,0B,5B,EB,FA,82,E1,2D,EE,3A,06,5E,C5,BD,49,4B,A1,9B,49,68,20,46,4E,CF,04,42,1B,9B,04,85,78,EB,C1,8A,21,9A,5C,E7,7A,D5,21,34,16,61,C0,CD,63,3E,FB,6E,D3,B6,3A,39,79,BE,C9,8B,F7,BD,91,9F,59,B2,3B,95,B5,57,AB,8C,EB,D2,52,13,34,AD,6C,25,26,29,A5,49,1C,51,F3,EC,39,15,EB,B7,8E,49,C9,A5,FF,25,4F,51,BD,3A,54,72,AD,41,94,70,F1,0A,F8,6C,51,39,D0,6A,30,B5,E1,B0,2E,FA,E5,D2,DA,C7,2F,F4,A7,07,63,46,6B,F1,3E,B6,64,74,5A,50,A8,65,43,97,C8,2D,A4,D5,FE,34,7E,14,72,56,F6,F7,A0,73,D0,F4,1D,6D,4B,95,6A,D8,C7,08,C7,C7,85,AE,D3,32,59,E9,80,88,D5,DC,83,64,DA,B7,AC,79,EA,9E,45,B3,93,6C,29,8F,EF,AC,69,A7,CF,04,4B,58,76,F5,E3,B7,83,4A,94,96,0E,F2,32,4F,B6,DE,43,5B,86,CF,8E,0D,2B,2F,CB,1E,87,7A,1B,B1,0C,8A,C6,3B,1D,87,00,E4,B4,D6,E2,C4,50,A7,E1,5D,C6,25,26,12,A8,DE,5E,2F,76,80,DE,81,AF,65,3B,D5,54,A2,16,35,9C,F5,26,54,D1,63,BE,31,18,E7,3B,87,00,D7,F2,48,77,62,EB,B4,A8,12,37,94,8C,22,AD,01,84,55,E0,21,1F,CA,41,C8,6C,37,8D,F9,91,56,E5,CD,67,35,89,F0,8E,C4,D1,06,FB,C9,0C,32,CA,F4,F0,EF,A1,63,83,2F,BE,0A,57,A1,A8,B5,61,DF,2E,BB,79,E4,C1,4D,5E,BA,9F,B3,BE,C5,F3,D5,90,98,7E,A0,6C,64,6C,03,D0,EF,EC,21,F3,9B,8A,51,FA,C9,C5,D1,50,C0,02,AE,E3,B6,BE,FF,9C,3A,85,43,55,9A,A1,55,C4,CB,86,13,EA,85,0E,C8,89,CA,4A,39,CC,54,2F,0A,D5,EC,6E,E2,36,65,FC,1C,48,2D,F8,53,0F,5B,D1,EA,DF,FB,03,32,22,B8,B9,1B,0A,8C,9A,1B,96,44,2E,97,5C,D1,B4,3A,C4,4E,CA,3A,2F,B1,94,6A,B9,6C,DC,8A,A1,EF,97,57,6F,45,55,82,82,47,75,F1,E4,B3,6C,E7,DD,C1,4C,2F,EA,B4,10,5D,35,3E,5F,55,B9,71,E6,2F,32,85,C9,9A,95,85,63,E6,EE,03,E1,7E,D8,48,E7,C6,AE,2D,7D,71,7F,C4,DC,D2,E7,4C,90,C8,69,70,47,C1,CF,4D,12,A0,71,FB,14,87,B2,6F,1D,2D,08,73,16,BE,35,2F,E4,EE,0D,85,50,21,E0,48,5D,E4,AB,51,85,27,91,1E,67,E1,B3,B6,B8,B2,77,D8,5B,BB,61,F6,27,42,E5,79,B0,BF,88,47,B6,5F,C5,00,9B,66,56,28,57,25,97,91,DA,45,16,86,65,C9,2F,67,F9,65,B7,33,34,C6,A1,F3,09,0A,CA,63,32,DC,93,95,EF,DE,80,3E,AA,3E,04,09,C1,78,BA,B9,5E,49,B3,05,81,F8,7D,01,09,77,CD,E4,23,AF,44,8F,D0,C5,C8,3B,D9,67,DF,7E,4E,98,1F,58,D5,8C,85,F3,3A,40,C7,D4,1B,C6,9D,57,61,C2,20,B6,9D,6C,1A,C9,98,A6,15,6B,7A,A5,DC,2D,C5,CD,E8,AA,34,E6,1B,A9,49,0C,F9,83,5F,5B,43,28,C8,45,C1,60,D1,78,CA,64,C2,72,8D,11,CB,9F,70,81,8A,77,B2,89,43,1D,A4,B0,CE,00,06,1C,38,08,4D,5A,D6,D4,7E,94,22,BD,30,9F,EF,FC,A1,1F,45,03,0F,DB,83,93,BF,ED,39,9C,32,D0,A2,96,9E,AA,01,76,27,0D,DA,24,58,85,A4,46,8F,89,A2,6A,F8,1C,69,4A,04,33,00,06,7C,AE,82,BB,2E,27,CC,85,E9,2F,A8,04,86,AE,4C,BB,B5,96,FD,DE,3C,05,79,C9,F4,E0,38,F1,4D,2C,D2,8F,7F,0F,62,EA,23,32,E9,C5,AD,F0,BC,C0,7B,3E,DC,DC,23,1F,6E,83,67,18,85,97,98,0A,F7,F7,BC,12,3B,E8,D0,44,35,46,E1,F6,93,07,32,04,39,9B,20,DC,E3,D1,63,CC,87,9E,C1,DB,DD,4F,24,B2,EB,24,5E,50,2F,A6,46,7D,74,DD,D0,37,90,78,70,98,26,FC,27,1F,4B,1D,18,7D,E3,FC,64,71,EF,92,89,54,82,15,C3,8C,38,54,5D,CF,60,BB,C7,FC,8F,8A,D1,DC,E7,47,29,F6,D3,31,B7,78,C0,6C,21,E1,69,13,34,64,3C,A0,9A,31,EB,30,07,DD,ED,E5,73,E7,A3,08,F3,86,1F,E4,F0,DA,4C,CE,5B,BD,4D,28,E8,01,21,CF,BC,C7,A4,9B,E4,E5,47,00,3E,35,74,1C,04,88,BE,3F,CF,30,69,39,07,A7,48,0A,03,13,2A,60,9F,E1,AB,5E,CB,11,1E,52,40,F4,3D,19,44,9E,D5,6C,FC,0D,36,27,59,FB,7E,DA,17,D1,53,BF,B8,28,FE,13,D9,BA,88,0B,F2,AD,F1,50,57,78,7B,83,B0,7C,11,49,94,22,35,8A,C6,5B,A3,7D,CE,25,D4,30,B2,25,A4,49,B7,F7,8A,96,F6,D1,E9,66,56,F6,8B,EE,8D,34,64,F1,9A,98,7A,14,AC,20,73,E7,AA,46,87,E2,C4,1E,FB,EA,75,4A,EC,9E,48,92,C1,88,76,2F,15,16,65,BF,A7,91,EF,7F,9E,66,02,21,DC,BA,85,24,D8,06,77,F3,FE,F6,2C,56,74,B5,1E,67,E3,F4,A1,F1,DC,40,6C,B4,27,EA,CF,50,97,92,9C,23,A6,60,87,E3,2F,40,A1,A7,1C,4F,18,44,A3,F9,21,E1,35,E1,23,E8,1D,A8,54,B4,6C,88,7D,5C,7E,28,5D,80,ED,65,EC,35,2E,3A,0D,A4,88,EC,87,B2,7A,00,F1,8E,34,C9,4A,04,86,53,66,2D,C4,A3,24,23,F2,41,A3,D0,EB,61,05,01,D2,68,40,7C,86,D5,53,E4,4D,5A,28,4A,5C,38,7F,3F,D4,6D,DA,4F,29,D1,DA,AE,8B,A7,18,04,8B,09,FA,54,E5,E9,84,D8,FE,57,8B,E7,C5,02,63,82,CA,54,42,7B,4F,B1,BF,C4,D6,18,FB,9C,42,70,54,53,F2,42,DF,58,43,52,1F,A0,C7,AF,68,EB,D1,25,CA,3B,E0,0A,C8,96,2A,93,DA,8E,D2,21,95,A6,5B,79,03,B4,FB,9B,97,3E,15,6A,CF,EE,BF,CD,52,7B,E2,EE,77,02,99,2A,D9,55,A1,E7,55,F0,DF,65,41,F8,A6,B8,F2,CE,79,44,6E,E7,99,E2,94,E3,71,06,92,75,C4,77,C2,91,E4,CE,E5,A9,C4,A5,D4,78,E6,FF,7E,28,48,8F,F1,41,26,6C,FC,99,9F,AB,F4,88,76,4A,E2,17,3D,EE,6A,E0,19,8A,84,2D,74,07,08,8D,E3,BB,07,06,95,CD,FD,28,BF,05,8C,49,6F,65,65,ED,4F,4B,6B,97,D1,44,9F,FD,E5,23,16,E2,B8,DA,A6,58,D6,1F,37,2F,17,F7,AE,3D,E4,50,2F,DE,86,FF,AD,50,CB,41,F3,C8,7E,6B,D0,09,EB,4C,EE,30,D6,D7,B8,3C,79,07,34,81,E5,66,57,F2,F0,EE,29,EE,EF,56,2F,18,D5,51,04,41,B7,66,F7,A4,26,E3,F1,F7,80,7B,67,7D,91,84,2E,11,05,23,67,7E,84,78,FD,49,A7,86,E5,3C,89,66,99,74,81,02,94,A0,D8,9E,37,90,98,6B,A2,A5,39,AF,83,98,31,45,A9,33,8E,9C,A0,B8,26,FA,9D,74,03,68,5A,6E,DC,F5,70,C9,42,BE,84,A2,EB,A4,33,E7,34,82,38,71,BA,A0,22,FC,73,B4,95,96,78,7D,BC,EB,A4,23,D8,E5,37,77,94,28,30,44,AF,19,A3,5A,E6,08,5D,32,8E,77,F4,96,AE,FA,20,E7,01,19,C1,0A,D2,31,68,D7,54,87,ED,A7,01,E0,89,99,61,98,42,3C,60,1D,51,36,3B,3A,F1,A0,7A,BD,46,AB,4B,43,F7,74,18,48,35,6E,EF,A0,7D,1C,BC,65,9E,D9,E5,09,8D,5D,D0,A6,72,B1,54,98,70,83,D2,A8,8E,50,7B,8A,25,2D,1A,AA,66,29,09,A7,FC,0A,59,7C,6F,E9,6D,76,85,3E,31,0C,1C,BB,BF,A0,D6,3A,54,52,B5,77,B9,9F,B0,35,9C,28,C7,73,04,62,40,57,7C,E8,3F,4F,00,25,0E,79,C2,6F,22,71,6A,CE,E6,8B,30,EB,2C,C8,43,A5,A9,C5,97,D2,89,9C,E1,D3,47,91,A0,19,5D,69,78,30,1C,E1,DF,A6,C9,0F,57,5A,C0,86,C5,9B,13,C7,4A,CD,07,12,F2,AA,27,68,96,C7,BA,D0,F1,F7,05,A3,F8,B3,D2,DB,4B,56,FE,89,2D,16,DA,1E,2D,E9,F9,9F,20,15,B4,86,D2,C3,CA,7A,C7,AB,03,E4,0C,4B,78,40,97,D0,2F,D0,80,3E,E9,49,83,4B,E5,1A,14,CA,9E,DD,66,E5,A1,15,6C,83,78,89,81,BE,98,AE,19,53,92,BC,C1,3C,A5,2B,60,BE,C1,C4,DC,61,86,A0,1E,08,09,CB,7E,90,40,C1,D8,19,A2,A6,42,24,6C,B6,20,1E,35,81,D7,BA,DC,53,AF,DA,F1,F5,74,18,70,75,B4,09,5C,0F,25,2E,28,D7,A4,23,18,F3,A2,BD,D2,30,D4,4C,9F,2F,3D,1F,F1,8D,31,FA,E8,48,E8,45,FA,F1,EE,36,07,4C,00,06,71,5C,0C,6E,97,BB,5C,2F,56,5C,66,AF,30,A7,20,FC,88,BE,D6,08,13,9A,25,D2,1B,E8,C3,FC,9B,BA,22,5B,3F,B7,8F,A6,A2,3D,1B,A1,B0,5E,4B,54,48,84,82,CD,04,1D,6C,1C,94,4F,98,E4,C4,6A,6E,E8,E9,A9,2E,02,88,C3,D6,A0,28,70,D5,1C,0F,56,D4,54,68,91,B7,1A,E3,D5,59,7D,D0,A5,81,64,88,E6,0F,1B,87,4A,04,A9,4D,6A,F1,0C,0C,51,1C,CA,84,FC,AE,BF,3A,5E,0D,7E,3F,4B,92,39,37,0D,8E,09,0C,D0,5C,07,44,BA,50,5B,1E,8B,EC,FB,7C,D2,AA,8C,05,43,AC,E5,32,49,27,BB,0D,79,28,04,18,FD,AD,B4,C0,FA,0D,A6,63,E2,CC,D2,09,2E,4D,42,88,2D,5D,6E,90,F2,49,4A,14,E1,E3,45,AE,BE,34,12,32,78,DE,90,13,79,B6,5E,BC,AB,FD,AC,71,3C,60,C2,93,EC,4B,B2,BA,19,B6,4C,2E,8B,66,D1,9D,9B,4A,FA,C7,57,8C,B8,0B,65,A8,CD,EF,D2,AB,5C,66,A1,D1,E5,51,E8,FF,C7,07,F5,45,4F,36,62,4F,8E,7C,9B,A0,3F,43,B4,D4,4D,59,60,9D,B1,8E,F6,93,88,3E,89,B4,54,35,34,28,F5,FF,94,02,21,1C,9C,D3,27,91,74,84,7F,A0,96,16,0A,EF,CA,46,2E,00,9B,B5,56,94,B9,3C,03,A5,23,97,33,50,28,01,DC,16,2B,B6,B3,0D,C8,4E,F8,19,62,A7,04,69,F6,E1,FD,49,4F,71,08,97,AF,A0,88,E3,77,2A,B2,FF,DB,50,C0,77,5C,08,12,40,FC,B7,28,6D,14,31,75,01,87,DB,95,9E,2B,09,39,54,98,5F,BF,AF,3F,30,19,3C,9E,F4,F0,89,1D,11,1A,FB,93,ED,CE,D7,D9,BE,C8,35,BA,20,EB,DE,79,D7,15,CA,DE,0C,9E,19,DE,C2,6F,29,4E,39,AE,99,86,E3,4F,EC,BB,67,F5,C9,28,DE,10,8D,47,6A,6F,03,88,93,95,BA,74,11,9A,4C,1E,84,A0,61,99,DA,56,6F,C9,D5,0B,7C,F7,C2,A7,69,02,18,D1,87,29,39,59,E8,E9,E6,35,DE,5A,FE,E6,9C,CA,2D,49,A1,7E,C4,38,CB,96,13,B3,21,F6,33,10,90,EC,CA,CD,B1,52,D7,E3,D5,3F,CF,DC,2D,CC,3A,0D,63,99,2B,70,89,5D,EC,1B,25,26,4C,C1,67,08,DD,AF,0D,84,28,87,31,67,62,0E,FB,2E,CA,9B,76,73,7B,F2,D0,6D,4B,D5,FB,04,07,0D,66,FB,9C,18,D9,92,5F,16,BB,BC,D9,89,30,CD,0A,3C,A8,CD,8A,3F,03,E7,1B,B5,3B,91,99,90,3B,EC,DA,9B,E5,9A,13,CB,17,3D,C2,E1,17,0E,64,B6,33,B2,51,49,2C,9D,85,49,F9,A0,28,CA,2A,3C,2A,40,0E,36,F2,78,E4,5B,DF,A7,2F,F7,83,DE,45,8B,53,05,4F,46,FD,8A,02,07,AF,C5,D8,D0,83,D8,FF,D2,C9,52,02,82,7B,59,1F,06,9B,BC,05,CF,A9,92,D5,0A,DD,4D,5A,D0,89,57,DB,5B,37,24,6B,63,8C,A3,4F,39,1A,D4,49,3B,7B,A5,2A,EF,5D,DA,7F,06,44,14,ED,E9,11,76,8A,5A,CB,F1,6C,63,BC,FD,63,26,80,5E,CB,9A,41,DD,E2,4A,16,F0,5B,17,B3,A2,1B,57,3C,FE,F4,EB,46,25,79,26,C2,7B,5A,D1,B8,B8,00,B0,40,D6,AC,AD,0D,23,D1,5B,9A,2D,9D,08,D8,15,78,1D,76,15,A7,1A,CB,EE,60,67,39,F5,ED,60,F4,DE,12,B3,60,8F,44,DC,0D,04,6F,43,7F,85,EA,38,A9,E9,0F,37,84,E5,58,8C,46,08,7C,E0,E3,D4,C4,A7,31,E5,6F,05,09,CD,2C,2B,BC,29,2D,23,22,8D,DD,0E,60,37,2A,FF,C9,14,B2,F4,0B,20,A3,C8,6C,F9,38,CD,2D,37,88,A8,05,ED,B6,F8,77,5B,B8,FC,63,63,80,3D,1D,C1,A8,3F,03,05,EF,5A,15,88,9A,13,4B,2A,A5,17,FD,AB,7B,6A,7B,7D,23,DA,F4,14,0A,D6,ED,9D,21,D6,AD,B2,7B,15,8E,B5,29,EB,79,69,F4,35,BF,6B,7D,31,BF,09,3C,97,14,CF,7D,71,95,42,30,AD,2C,7E,66,87,A6,3C,7B,80,92,A0,22,77,22,64,61,09,63,C7,8D,47,61,46,D6,69,8C,5B,F7,C2,E8,11,D2,AB,C0,CF,3C,F4,84,A6,F8,9B,3B,AF,C5,A4,5D,D7,C4,A3,6E,D8,8C,00,4A,0C,D6,4A,2C,D9,BE,D4,37,73,BA,1D,73,76,F2,3A,E4,51,57,7B,AE,48,60,49,58,9A,7A,55,93,ED,DA,48,B2,9D,3C,14,DB,69,A0,E1,10,51,DD,B6,8C,6F,EA,1A,17,81,85,61,A9,A1,6A,3B,FB,49,C3,30,64,98,ED,D0,73,5A,03,D2,9A,7F,D2,C0,91,02,9A,D5,50,8C,CC,88,22,35,8F,9A,31,02,4A,7A,4A,17,47,A1,EA,36,2E,EA,E5,F6,56,F1,BC,58,E4,9C,64,F0,CC,82,5B,16,02,6D,8D,31,81,F8,64,5F,6F,99,3C,2F,82,F1,C6,72,73,E2,DD,05,1A,D6,03,F0,F6,93,26,C0,3C,B7,DB,88,26,C9,C5,56,4E,6F,8F,FA,76,3E,8D,70,31,F3,6C,1C,B9,FE,D5,22,C0,DF,45,6E,5E,AB,F6,17,99,D3,C2,35,02,2E,94,E6,13,B9,5E,E1,90,05,3E,93,2A,A0,D1,4A,2E,F6,FE,C9,88,21,A2,DA,AD,41,8B,A0,82,96,39,FC,3E,CB,79,C9,B2,60,D1,D1,0E,EA,96,68,4B,3E,A5,F3,93,66,1D,01,1B,4A,D8,3C,C4,FA,4D,28,CE,52,CF,11,CE,3A,1B,67,8D,3A,44,06,C4,C9,5A,E4,3A,A2,6D,E9,34,CD,12,98,85,8A,24,B2,C0,C2,84,FA,91,A3,42,7B,C6,99,B1,50,D8,BF,26,A3,82,DD,C2,E0,B7,CF,1A,A3,14,4F,D2,B0,6E,58,CA,89,FD,D1,73,B7,D6,5F,04,4A,AC,D3,31,83,4F,E0,39,F7,C5,14,9B,18,84,92,3C,6F,B4,E9,1A,FB,D8,B4,12,D9,82,EE,39,7B,66,7D,F6,74,87,07,9F,17,FB,1F,63,2D,A1,BD,BB,1C,A5,33,30,DB,44,2E,0F,4D,70,BA,7C,A5,AF,81,BD,97,2C,2D,7B,8C,80,23,B3,68,FF,75,FD,64,9D,E8,4E,10,17,5F,6B,08,62,E3,66,2D,12,6D,D3,35,61,9D,E7,98,FF,38,29,65,D8,8D,64,E9,64,81,DC,F3,B6,10,A9,F9,8A,F3,98,64,DF,CB,5B,A0,1C,7B,79,CA,D7,A4,3F,03,0E,24,52,30,0D,9B,91,AE,F8,C9,69,08,2E,99,64,CA,5E,71,41,B4,A3,F4,21,EB,D9,11,B4,C0,82,04,37,DA,08,0A,89,8B,B7,70,DA,86,49,44,1A,5C,DE,D8,78,DB,AF,5B,F6,7F,43,4D,4A,5A,EC,FB,BF,28,EA,2C,E2,33,0C,57,E5,87,09,4F,32,2C,4F,A7,FA,A3,02,B1,E8,79,93,F0,04,C3,E4,8D,22,71,6D,71,CA,F4,AD,F6,8B,9F,1D,75,56,07,72,56,2D,69,02,73,8D,CF,64,B3,7D,90,6E,42,D1,E5,BA,76,E0,3B,B5,A7,F6,3C,8F,6A,85,4E,0C,19,2A,39,DE,0D,33,56,7B,53,1E,41,DE,D3,EB,9E,71,1A,25,51,8E,50,2C,E7,6E,1F,58,06,27,F1,1B,AE,09,FB,AA,E8,03,C7,56,A2,73,6E,30,BA,C6,8A,E3,DE,35,2A,BF,9B,B9,B0,7F,FE,C7,BE,7E,F2,F7,F6,D5,4C,F3,FC,E9,DE,63,0B,6E,1E,7A,95,09,DC,C8,DB,DC,46,00,24,D0,BD,43,88,B9,65,E2,81,9D,9D,A5,8A,EA,3E,67,71,E3,AF,2B,46,4F,31,32,BD,16,5E,74,8E,43,8C,10,88,A4,EA,52,46,BA,E0,9A,10,7F,C2,1E,1B,92,E0,8A,88,4F,6A,EF,87,B0,DE,18,8C,37,79,DF,11,C5,83,08,1D,E6,76,96,F2,80,EB,0D,21,68,72,AD,87,5F,16,EC,B9,4C,0F,E1,07,A8,C6,2A,65,C0,A7,CA,F6,52,E6,88,21,B4,A1,13,B1,57,30,04,7E,30,55,E7,29,49,92,18,83,80,78,7B,0A,78,EA,BB,08,10,7B,FE,67,FE,33,FE,72,58,DD,75,9E,0B,9B,E3,52,AB,7D,EE,A2,A9,72,54,95,99,03,3E,96,48,2A,D0,66,9D,81,D5,95,AE,7D,CA,90,0D,25,AC,E2,59,5A,01,16,85,92,6E,F3,E9,CA,F3,D8,FF,44,50,05,00,A7,72,37,8A,3D,19,F9,31,55,FD,B2,D2,F6,F6,4C,16,77,9E,D5,74,E1,8B,77,68,60,28,71,A8,A7,2B,93,AF,8E,96,FD,F4,3D,6C,12,F2,80,83,5A,BC,40,BB,48,F5,3D,F4,09,47,0B,1B,C3,C9,6C,C6,D7,FF,99,9E,A3,AD,30,84,94,DB,78,74,C0,D5,0A,55,FE,B2,85,F8,FC,40,78,9C,2B,2E,F3,5B,B3,0A,76,EF,BC,83,E5,50,72,29,06,D1,6B,55,DB,03,9A,AC,F6,F9,A2,ED,06,54,29,46,19,00,24,F7,3A,C3,49,D7,B8,D1,B5,A2,8E,8B,9B,07,CF,EF,AB,06,1A,68,A1,90,D8,DF,3F,21,72,98,DA,35,EF,EB,A0,65,DA,A1,42,21,23,B3,6C,C0,65,78,2D,33,E3,45,80,3B,41,F7,36,62,84,2A,4F,2C,E2,30,4B,A2,A2,F6,E5,D9,E3,46,21,70,72,BD,14,2B,27,42,78,86,83,0D,96,56,C4,CE,2D,12,9A,79,FB,D4,FA,74,E3,E2,3F,50,D2,25,CE,A6,53,D4,13,FE,75,E3,74,0A,22,65,EE,F4,48,FF,EF,16,FC,13,55,67,ED,0A,61,77,19,7B,BD,AF,EF,51,A1,6E,D1,0E,4C,9C,C7,99,8E,EA,CE,FF,B5,F9,7A,40,C7,67,A9,F2,6E,C3,7A,A9,D4,F8,C8,26,31,4A,7C,2C,82,00,BB,C8,C3,D8,8F,B5,33,97,40,53,96,D4,2C,10,E8,EE,4E,F5,57,CF,44,75,97,A0,00,8D,39,28,A3,85,02,F3,F6,75,74,04,13,77,F6,DB,04,1C,43,A0,34,50,9E,95,68,3C,71,37,6C,F1,FD,40,19,3F,93,B5,B3,89,F7,21,6E,51,D0,02,A3,6F,35,11,29,6B,8F,24,5B,26,F1,56,A1,08,CB,28,E5,D8,C8,E7,9F,CD,85,32,F6,D3,FF,B9,2E,3D,89,AE,D7,51,F1,07,B5,B6,9E,8F,EA,AE,76,94,A0,E5,5F,19,B9,33,A8,50,B2,7A,0C,79,3D,C4,D3,E2,AE,A0,D1,6C,54,D9,58,E1,45,89,7F,95,61,07,7F,47,0E,F2,12,A9,18,53,CB,1D,58,09,D5,08,60,4C,08,3C,B2,4F,8C,AD,FB,6B,E0,60,07,4E,EC,D1,62,5D,F6,D2,89,6F,3C,91,AE,19,7D,45,43,FE,31,66,73,BF,C1,99,D5,41,ED,E5,AA,94,9E,44,EA,9D,C6,6D,38,D2,55,3C,75,13,2D,C2,8C,15,7C,75,10,D8,24,EE,93,BA,A1,DE,E6,62,C6,12,5D,0B,97,CF,89,A5,1B,86,EB,72,42,6C,35,BE,56,19,4C,5A,06,2E,5E,5B,73,E9,9F,1A,59,C9,C6,0B,0E,5E,B4,BB,70,32,0C,15,3D,BF,AC,49,11,14,9B,29,B4,BF,2F,3F,FE,BA,75,64,5A,09,C2,13,79,25,9A,B7,02,5B,1A,FA,D2,67,66,7B,48,7B,80,1A,09,1A,87,A7,90,1F,9E,EF,60,3E,31,2E,D0,AF,14,1F,7D,0B,5B,51,FF,59,EB,8D,D7,ED,32,B0,E0,ED,1E,FC,51,B1,09,09,AA,33,DA,F4,02,02,A6,98,A7,CE,DF,6A,33,76,B6,31,FC,C6,34,2E,77,20,DA,59,43,23,FC,90,1B,8C,22,D1,EC,E4,22,9C,61,05,66,36,61,89,AF,7C,E2,24,BE,C9,70,6A,BB,AD,7E,75,59,9E,A2,AD,58,7B,AC,93,EF,F0,D2,6E,EE,6C,D2,A5,D3,BC,17,E9,63,C8,08,3D,AA,7B,A2,51,01,7D,74,AC,52,09,DE,A5,83,C3,0A,55,A1,0D,B1,7B,55,4B,63,90,07,6B,E0,25,DF,CE,8E,D7,9B,43,6F,4A,21,6E,A7,0A,FE,0C,B9,49,CB,E5,51,FD,5C,62,00,B9,EF,97,0F,AF,E8,3A,5A,B6,05,FE,71,4D,96,1A,F8,DB,60,FF,F5,C6,46,8E,AC,BD,D5,A8,71,46,76,27,A0,39,17,78,0E,28,13,D3,92,B0,DF,AE,01,06,E6,07,AE,3E,34,96,EB,EA,AC,26,66,6F,66,6C,CE,53,40,EC,11,DE,D2,E9,D1,BB,B3,C8,22,D0,A4,44,0F,28,EE,39,ED,38,39,72,61,40,05,F5,FA,2F,AD,7B,D1,84,3C,F1,7B,CB,F4,01,10,7D,29,44,2D,B3,55,9A,CD,8C,16,53,85,27,A8,C4,34,17,BE,7A,4E,35,3E,4C,2A,7B,C6,66,48,92,A2,2E,B6,F3,02,7B,64,AA,FF,4A,E2,55,26,7C,CE,27,00,14,9A,52,3F,0B,A7,29,DF,EE,2B,23,97,6F,2A,77,E7,36,7F,CE,05,DB,BD,1A,58,77,2A,E9,58,71,6C,E8,67,1B,C1,E4,FC,8B,44,6D,BB,CB,E7,C6,8F,7E,91,B5,76,19,C6,6E,DB,8E,12,99,D0,DE,78,FD,FE,DA,95,8A,99,39,67,90,B2,03,B7,04,DD,35,0D,06,1B,30,D0,68,7F,1B,4F,F8,62,5D,58,92,AF,A6,34,E7,DA,01,3D,66,EE,D1,1C,2C,AD,F6,18,F7,EB,FD,2A,D7,C0,4F,FC,49,2D,82,87,C6,11,F0,F8,BA,4C,E7,B0,D9,73,4D,AB,BF,4C,03,D8,80,EF,53,4E,A5,A0,1A,AF,1D,61,1F,0C,25,01,B7,D7,99,F2,C8,5B,7E,5E,0C,31,F3,D8,69,29,B0,53,F0,35,0F,B3,33,66,C8,CB,AE,62,D2,A3,1F,32,CE,F6,17,C3,28,31,38,EC,C0,23,16,74,6F,92,A0,26,A3,DE,B9,0D,FC,BD,75,A5,0A,AA,2F,6E,01,35,A3,45,48,28,43,18,98,AA,3A,EE,33,BB,3E,DD,00,D8,29,26,60,2F,08,45,9E,F7,14,39,3B,97,9B,C8,3C,DD,31,B5,60,5A,54,76,75,EF,DB,E4,23,72,55,AE,AB,1D,CD,CA,F9,FE,B7,74,7E,7B,53,09,2E,BF,1F,27,F3,0B,7A,45,9D,30,AD,6B,82,2A,46,FF,F4,F3,8D,57,53,D2,2B,60,CA,6B,E4,78,F3,CD,62,2E,F7,4C,95,7A,D9,B6,FB,8D,50,1C,C1,23,F3,0B,19,E6,5C,5A,FD,00,40,D4,36,8C,9D,4F,A8,5B,CD,6C,FD,EB,9C,28,6B,9F,5E,5B,DA,5B,76,91,68,DE,2C,58,4A,B9,AB,B3,FD,BE,D1,5C,9C,0B,C7,B3,10,AE,41,6C,AA,BB,02,58,AE,31,42,46,19,00,90,6D,14,5A,73,FC,8E,83,87,DD,FD,01,59,A2,37,F1,00,9B,98,D9,56,11,7A,44,30,6D,39,59,49,CA,C0,AD,D0,52,CC,DD,DF,61,9E,D8,BA,39,B1,F3,F6,67,FE,EF,73,DB,9C,90,6D,16,17,E7,CB,17,AF,91,F5,4F,EE,BC,DF,C2,E6,76,41,16,72,54,BE,D6,58,28,6C,1B,3C,F1,1F,FA,0D,A0,1A,0D,4A,29,6A,5D,C6,E6,87,69,B4,E2,5D,FC,AF,B0,F0,0A,0D,E9,48,93,AC,1F,5B,4A,5C,35,53,05,E3,C6,F0,C8,EC,16,D2,92,FB,D5,B9,BF,C3,93,56,83,8F,CF,63,55,AB,91,39,76,F4,B1,A9,29,B3,F8,5C,EA,21,CC,9C,E2,8E,A0,3B,B3,57,85,4C,D5,57,A7,A2,4C,7B,17,06,29,0C,E1,F2,8C,52,E6,45,53,C7,F3,56,EF,5D,19,B9,B2,11,A1,74,BF,33,BD,F4,E9,F1,5D,41,9F,2C,CB,2F,3C,E5,79,60,CB,8A,2C,B4,46,3A,B6,FF,8C,92,50,CE,AA,CA,4B,37,48,51,D6,B5,BE,6F,2C,47,F1,C2,69,27,87,F6,C0,6A,BD,88,46,42,E0,C3,6C,B8,02,ED,C7,C2,6A,04,12,E3,0E,A5,C5,4F,5F,95,00,17,02,40,46,FC,41,11,C3,90,3C,4B,B3,62,83,C4,E9,17,11,78,BF,91,04,B5,77,AE,CD,2E,B4,EF,93,EC,46,94,B1,13,7A,AC,13,AC,8B,93,CE,33,FD,D0,4A,CA,F8,42,6A,A5,07,90,DC,85,49,DF,EB,BD,05,41,BF,58,FC,92,D6,8A,46,0F,32,66,93,9D,5C,E6,7C,E2,F7,BF,ED,1B,C4,2A,1E,16,7D,69,67,A9,81,F9,42,BF,E7,38,F7,EB,55,A3,0D,30,60,E1,9C,81,2F,51,A3,23,39,29,F3,61,C1,BC,25,1F,67,7C,CF,93,AB,EB,1D,D5,8D,B8,1A,8F,3D,3A,64,42,7B,E7,69,7E,F9,B1,60,1D,B0,51,A7,3D,4E,5A,0B,B3,B2,CF,CF,A9,1B,73,CB,05,4C,EA,3D,49,73,A2,0F,7B,6E,01,9F,4F,E5,02,C9,73,44,F4,16,6E,BD,22,89,38,F1,3F,7D,63,9C,C1,A8,68,39,E2,56,52,BB,99,B9,AC,38,8E,64,91,95,12,46,1B,B6,A2,78,EC,46,2E,B3,E9,37,A8,E8,D7,D1,33,F1,C2,19,7C,45,21,E4,EE,5F,63,25,8D,3B,5A,4C,B2,BB,30,04,C5,20,F1,CA,53,93,81,13,CD,D7,37,B1,74,B7,C2,08,E6,5C,F2,71,DA,47,E4,E7,FA,B4,65,5E,05,37,20,7D,C5,9D,96,76,62,E2,09,5D,4C,40,31,85,9A,78,86,8C,6E,02,84,EA,DD,D5,AA,47,B9,96,8A,6B,6B,EB,F6,CC,ED,25,16,4D,36,49,2B,B5,F4,0C,95,4E,CE,F4,66,26,36,0C,D2,E6,E7,AE,88,8E,71,C0,47,79,31,10,04,1F,EE,A1,29,0A,63,16,32,B1,3C,85,6E,A3,D2,35,1C,73,52,82,5C,4E,80,D3,C7,44,89,F1,FA,7D,02,62,2A,97,23,D3,28,70,8B,9F,04,5F,AB,55,E5,13,92,DB,01,93,3B,9F,2B,CD,23,C4,5C,84,E0,FA,2F,79,CF,96,7B,8A,4C,54,F3,B6,92,E7,28,A3,9A,78,75,D0,8B,86,36,AD,82,9B,85,24,C3,7C,6C,8A,40,83,C2,0E,0E,36,D9,8D,D6,12,A4,F8,0B,89,A5,8B,D9,4C,05,2C,F2,84,7E,AF,7B,AB,CD,76,6A,CA,85,3A,69,84,BD,DA,A1,8D,E4,5D,7A,24,B9,8A,13,44,64,06,55,2E,CF,65,F3,9A,C1,7C,4E,46,3E,42,C5,B5,09,9E,4F,DA,AE,81,3F,F7,A0,37,09,46,40,55,4A,7F,1A,0F,71,81,09,F6,27,DD,AA,B1,A5,4D,78,EB,81,10,6C,38,03,9F,D3,7E,33,D4,09,8F,2F,4E,30,F0,8C,62,48,38,66,E2,6D,61,22,2D,5E,1E,AE,6B,E9,C6,DF,E7,D1,3A,D6,8F,1E,EF,2D,F4,5E,47,1B,94,4B,C0,E2,96,20,A5,FD,A7,D2,E9,6E,1B,F1,EA,37,97,FD,28,54,CA,17,B5,85,2C,E8,26,D3,15,37,32,9F,6D,C8,4A,93,E2,1A,74,C2,39,F2,86,12,A7,59,76,A2,AC,AE,6B,F1,8C,E6,AD,B6,CD,C8,8E,20,48,85,3F,D5,8E,30,A6,07,90,49,C6,63,CA,7C,67,FB,B4,16,58,CF,B4,A4,DB,37,2E,8A,82,AD,1F,5E,4B,4E,B6,88,9A,48,5F,1B,D2,EE,C9,51,CC,7F,8D,AE,1A,FE,31,73,DD,FF,6B,F8,21,DA,38,96,27,DA,C7,58,B2,59,F9,C5,2E,B1,7D,BD,A2,D3,69,E2,D7,7D,5B,3D,FF,E5,BF,1A,C7,8D,4A,F8,1B,0E,5F,F8,F6,81,52,4A,3D,5E,96,39,64,E2,17,22,DE,C2,21,71,A4,2E,B1,04,0A,0E,F6,BA,51,22,1E,D4,8D,A7,D9,94,26,F2,A1,5D,50,0D,6C,19,74,8D,40,FA,FD,BC,73,03,D0,11,FF,7F,F9,39,DA,21,A8,2D,46,D7,F5,0B,98,3D,E3,C9,8C,1F,5B,04,C2,77,5F,C3,1B,72,66,E5,52,B5,BB,C3,3D,BE,41,B9,B5,81,84,6A,CE,C3,7A,E0,D5,42,41,8D,14,C9,67,0C,BF,6E,3E,BD,9D,7A,B7,55,81,B0,B5,A3,84,AB,4D,27,0A,13,85,40,15,AF,45,22,15,B0,0F,EB,E1,54,4B,65,43,77,5B,C9,B3,15,42,D5,18,21,8F,E9,8D,CD,B9,4F,D0,A2,CB,C3,46,42,4E,69,93,63,5B,75,FD,C7,4B,04,58,FD,0D,B8,90,56,5C,33,9E,4B,DA,F5,52,3A,D6,09,5F,5A,B1,4C,61,85,ED,99,28,67,80,70,4E,79,B0,76,90,BA,8C,9F,10,89,7A,04,EA,3E,B4,9F,C2,7B,BD,42,BA,07,6B,1F,A2,3B,0F,56,2D,88,26,A9,55,74,AA,C7,DD,EE,EA,62,91,87,26,93,AD,8A,4D,CB,9D,FE,96,D1,0D,FE,4C,C0,04,44,60,48,34,1A,E3,06,FA,78,61,31,78,DA,FB,15,D3,FD,CD,D2,19,26,F7,A7,E0,64,DB,BF,44,74,53,8C,A8,3B,E9,2A,92,10,4D,85,7E,86,0F,86,AC,82,DA,B6,26,61,E7,64,AE,6C,D1,43,C1,25,86,1F,B3,32,74,D6,44,1D,9C,56,D7,61,1D,19,98,65,A3,25,CA,51,A1,5E,EB,9A,7C,46,F4,AF,67,0F,5A,80,B5,4E,4D,6E,82,14,73,33,7F,BE,4E,E5,13,CF,9F,39,99,FE,8D,A8,F5,7A,3D,EB,2B,76,37,D5,1F,1B,30,8D,69,33,B3,37,AB,3E,7C,8F,AB,FC,2F,D2,F1,47,43,4C,B0,CA,6E,66,49,DD,52,E0,FA,3D,50,F0,AB,C8,F4,B7,D7,2E,56,41,83,BF,AB,52,5C,D7,44,F1,8E,2E,F3,18,DC,A1,73,EB,9D,28,68,57,3C,38,B0,47,0C,96,48,63,88,5D,37,58,08,3E,DD,F2,01,52,FF,1A,C4,06,2E,FF,36,EF,00,E6,FC,90,44,9C,D8,5B,CF,A9,E0,1B,97,0C,56,3C,FB,D6,98,C2,4A,4F,2F,38,97,5D,CC,E1,C2,01,25,38,73,7D,4A,AB,E1,91,98,C6,53,6E,77,05,7D,D8,31,8A,DB,30,09,14,30,43,25,B7,C3,EB,6A,69,1A,C1,18,C8,35,C9,C6,58,83,99,86,63,1B,C3,37,16,88,A7,83,E5,32,0E,6E,18,64,2C,E7,DF,66,29,0C,59,4C,A1,C6,56,20,34,60,33,DC,9C,99,D3,93,A9,26,64,CF,85,24,E4,07,97,2C,34,0D,58,1A,90,A8,B7,50,E1,58,89,B8,6E,98,F6,4E,DE,CD,EC,1E,C3,34,4D,56,2A,A9,C0,0A,65,CD,C0,08,34,A0,21,A7,43,88,FB,37,FC,84,8A,47,76,49,E3,FE,F5,56,82,9E,4A,87,B9,DB,43,73,E2,EE,38,0F,E8,A1,81,91,DF,58,24,AD,B7,2B,56,CC,62,BB,B3,55,19,5D,0B,D8,9A,E5,34,C3,AD,22,B3,7E,D8,BB,D4,C9,B6,91,23,3F,52,C7,79,0F,10,29,1E,29,36,DD,C3,C9,7F,7F,8D,BC,67,27,AB,23,F9,EA,B4,2D,84,17,AA,4A,8F,0F,17,55,A0,B0,69,D6,1E,C6,CA,37,37,07,1A,83,94,45,70,61,83,70,9B,64,37,7F,74,62,0F,77,46,B5,C0,FE,53,79,BD,84,42,E9,7D,C4,79,07,61,77,7E,E6,6B,A5,94,9E,D1,8B,9E,46,A2,EF,B4,F8,2D,78,31,26,BD,9D,E0,90,F6,52,36,6F,4F,7B,B1,55,5B,BA,F7,54,9B,A8,95,CA,7F,03,6D,74,29,C7,AE,85,D9,12,00,AE,20,C8,BE,F4,D9,A9,A7,00,D0,15,F0,EB,3A,A9,5B,37,C3,30,98,12,70,49,2E,E1,3D,E3,4F,AB,28,12,E6,4B,6B,C9,53,35,05,0B,82,01,29,C1,6C,00,F0,EE,94,BB,B2,F7,50,5F,58,47,E6,D9,62,68,C4,44,7E,91,44,B0,E7,41,57,BE,F4,CB,1F,03,57,F9,49,5B,45,2E,B8,AB,14,46,B8,8C,E9,51,93,09,0F,5A,D1,3B,02,18,73,5E,22,B1,34,A7,1E,C6,07,FE,32,A0,A2,85,27,CF,06,5F,2F,B4,C9,BC,51,EB,5A,FB,A3,4C,70,F0,6C,61,2D,8E,14,05,81,EE,66,1C,97,1F,E5,AB,1D,10,29,FC,F2,19,BA,69,02,3E,F2,46,DD,AA,69,17,B5,34,24,50,36,61,EC,AF,DD,D3,A0,11,74,BC,2E,45,C6,B3,04,01,8D,FB,A8,E9,C7,41,A7,ED,1B,65,BD,AF,D8,2A,33,23,02,C9,53,C5,89,67,71,3D,08,B9,24,47,75,46,41,EF,54,36,E3,31,B4,C2,47,42,86,15,27,33,14,F0,D4,91,02,4D,57,FD,1C,B4,29,D6,0D,70,DC,59,A6,65,42,2C,10,50,8D,16,9C,56,E4,D3,78,76,F1,7D,19,08,B8,C6,B6,3B,0D,20,A8,C8,D5,FD,C7,C6,71,D7,56,E8,05,10,36,79,00,F3,F3,FE,16,C4,B6,99,22,05,A1,A7,25,64,36,26,1A,6F,61,8B,57,B5,86,A0,B5,A0,FE,22,F3,99,5D,8F,B2,8D,79,81,5A,E1,65,57,84,AB,E7,76,16,D0,E1,92,79,02,86,7A,F4,0B,5A,E1,2C,5C,46,9C,B9,4F,06,55,CA,99,29,7B,04,82,07,C0,5C,E5,6D,D7,C3,57,B0,33,CC,31,1C,A4,23,64,07,7A,50,36,A1,B5,2B,67,00,23,3A,3E,D3,AB,D8,C1,2E,7E,94,47,55,C6,CF,D4,5D,90,9E,01,5B,04,0E,69,5E,CC,37,81,B6,3F,2F,A7,AD,E3,3D,52,0E,A2,7F,48,CA,66,58,07,2A,60,43,58,3E,C4,FC,3B,71,6E,B6,53,E2,BE,F5,22,B5,70,18,F6,C4,D3,AE,7A,86,0A,71,D3,5A,72,44,95,8C,A1,A5,02,6F,2D,D7,D7,1C,AE,4E,66,D2,D0,D5,C0,1F,FC,19,75,C3,59,5E,C3,55,ED,C6,F5,35,A4,31,D7,73,E9,45,B9,00,2B,EE,0D,06,8C,EF,C5,31,55,8B,88,F1,FB,C5,F0,04,FE,2A,78,F4,6D,D3,0D,89,1D,DA,D1,36,89,AF,06,B0,55,F8,8A,6B,5E,B2,56,5B,EC,8B,45,DC,73,FC,BE,D6,B6,09,17,3F,DB,28,30,17,E7,B1,2C,8D,34,66,A2,6A,40,C8,E0,1C,AA,FA,32,F5,19,00,11,A9,3A,C8,93,F0,97,B4,85,78,0A,95,F4,91,C5,F8,02,36,EE,95,4E,83,7C,CA,95,24,7F,AF,1B,F5,93,8D,AB,24,F9,1F,63,A6,24,5E,B8,84,CA,55,52,66,62,7D,EB,C1,D0,D9,27,F7,A9,BF,F9,6C,FB,C7,77,50,BB,A3,97,A2,CD,AA,87,DD,EC,CA,25,C4,F2,F1,CD,41,6E,37,52,3B,08,3B,AF,97,9D,2A,B4,1F,03,F1,8E,7D,F9,EA,BE,07,FF,A7,93,FF,DE,4C,91,39,F0,16,1F,CF,96,E3,71,E7,70,FE,C6,43,05,30,01,CA,C0,33,DA,FD,6E,CC,E9,AE,12,04,D4,DE,A5,F9,A2,E2,08,7C,63,A4,15,FE,0A,FB,F0,66,E0,D8,B3,EF,65,4D,89,67,C5,6E,BB,F1,73,54,1E,31,2A,88,5A,3B,92,D5,FA,D5,7A,3B,9E,77,97,B6,66,3B,49,4F,BE,75,D9,72,98,2E,DC,C6,30,3A,F8,4F,18,5B,17,37,76,20,60,E5,D5,22,ED,1B,82,92,44,D4,C1,0D,8B,94,D3,3C,2F,A2,A5,72,CC,D2,A6,D9,63,BF,90,C2,35,09,C3,B9,7E,9D,94,07,E6,79,9C,CE,6B,BC,FA,C1,FF,EA,1E,01,28,2A,2A,78,31,DD,AA,F6,0C,53,98,2F,F0,D6,CB,45,84,C0,D2,21,EE,C7,D0,E3,11,42,3F,2E,5B,99,68,D1,26,F8,82,ED,DA,4C,8F,69,81,6A,32,A1,59,17,3C,41,0E,9E,9A,2B,4F,D1,F1,9C,4B,4A,8A,F3,6C,A9,0C,09,BA,13,AE,7C,08,C2,F6,C5,65,A8,D0,AB,9C,1B,A2,84,74,9C,B3,60,E8,64,21,1A,84,01,7C,7E,96,0F,6C,52,D3,E5,C5,73,C6,03,84,76,DA,8C,5C,BA,44,C1,BC,77,22,71,35,09,85,7C,7E,34,0A,DC,6D,4B,F8,6C,A7,73,E3,C0,66,EE,42,65,17,0C,9A,45,03,AC,A6,A8,63,FA,A1,3D,2F,DD,BE,49,A6,32,9C,8C,B9,CC,F2,33,A7,DA,16,5D,89,F0,26,6E,50,0F,E0,FB,57,98,31,E0,FE,A2,33,6B,28,F3,23,CE,33,B3,B1,49,41,1D,60,6D,21,77,5C,D4,8C,45,BA,8C,C5,6F,BB,C6,EB,A9,75,36,B7,89,89,49,16,1E,F2,E2,9D,C1,9F,17,84,6E,18,66,6E,87,EC,AB,E3,B5,78,B3,2D,D4,3A,BE,D1,F2,CA,D5,8E,D3,B2,8E,7A,BC,B2,D0,0C,B6,8A,B1,41,66,7E,98,EE,B6,21,B3,CF,3B,3B,C2,36,06,45,EB,8C,B8,6F,AE,4E,2D,67,5A,C8,C1,8A,E0,71,4A,3D,37,CC,E1,D1,AF,93,36,3C,BE,4D,E0,3B,FA,5E,94,E3,BF,7F,73,7E,07,47,1C,F6,0E,CE,44,94,2D,55,88,C9,30,48,93,F1,26,CF,A3,F3,D6,5A,9F,11,E1,B3,93,1C,CA,A0,C0,CF,FC,EE,CE,5C,ED,6C,01,40,C0,32,E1,00,B6,28,4A,1F,60,B9,FE,30,4C,D4,F8,63,F1,F7,68,9B,7E,E9,6E,31,39,E7,1D,A3,5D,76,ED,DD,27,6A,A9,A5,D8,24,B8,55,50,C3,26,B3,3B,7F,44,9D,4C,C6,65,EE,A7,F6,73,04,1C,45,85,21,0B,F0,5B,BB,A5,8F,6C,B1,29,D5,75,18,85,05,5B,36,81,54,90,81,8B,A4,FC,CE,9A,A1,6A,89,36,72,6C,B8,53,2A,E8,C5,0A,88,D7,A3,8F,39,21,E6,45,64,8D,CA,B8,C0,08,1B,17,7E,EF,0D,DC,6C,A0,8D,FB,75,6C,9C,D4,74,6A,A9,32,DD,17,8F,08,ED,0A,51,6C,90,C3,C6,E3,AE,17,07,56,E9,8B,E1,17,D8,BD,68,8C,D8,A6,5F,B0,BA,95,FB,CC,C6,56,43,32,F3,BD,21,98,C4,DE,75,08,A3,5D,6C,4F,28,1E,95,40,37,A2,AC,09,6A,3A,99,41,16,EB,EA,FA,8C,E5,61,EF,65,FD,45,75,9F,BF,CB,95,BF,41,EF,70,15,B6,7F,F1,09,90,82,0A,44,57,93,C7,4F,D6,7C,99,EA,B4,04,C7,54,9F,62,07,59,D5,07,85,18,D5,F2,BF,DF,F5,9D,44,91,BA,18,30,A5,4C,A4,E2,E7,59,2F,4A,FD,DB,D2,61,79,40,B4,C1,9E,C7,A3,61,95,D0,A9,47,E0,8F,02,62,59,C2,42,BC,66,26,59,5D,93,B5,E9,49,22,B7,A6,C7,82,97,BA,B6,41,3D,D5,78,7F,EF,06,9E,3C,7A,0C,5C,30,08,8E,7F,EF,7A,29,82,8C,73,EF,D6,6B,C0,63,C8,26,2B,B7,E7,F6,5F,8C,A7,11,B0,D9,BF,F1,1E,A5,C1,03,34,31,53,E9,BC,A8,E7,4E,0D,B0,27,F7,F9,E7,6A,F8,6D,96,84,EC,A8,4A,19,4A,04,43,A7,7D,3F,A8,6A,F6,93,41,FE,AB,3C,AD,9B,47,60,B6,6D,61,51,2A,0B,B1,D6,39,3B,11,FD,D8,A2,C9,EB,44,41,23,1F,FC,D7,0F,49,75,78,97,17,C0,78,75,89,47,9A,4E,EA,EB,DF,4E,DD,0F,DA,2F,13,B3,CE,7C,FB,44,86,57,4E,32,E5,4D,F4,A9,9B,90,65,6A,3F,E6,B5,B0,50,FF,3F,69,A1,E0,95,DC,93,08,D3,36,47,9A,36,83,58,94,62,92,F1,CC,BA,55,68,25,05,1A,00,75,44,18,7A,30,1E,E3,DD,90,4D,D7,A3,4D,F2,0D,6E,81,20,C0,7A,54,06,D6,08,1F,30,FE,CB,85,33,FC,75,C7,BF,2D,C4,A6,11,AE,E3,EF,A0,64,BF,25,88,E2,2D,5C,25,0E,A5,86,98,E9,16,A2,85,1A,DE,54,FB,F5,C9,92,00,AF,17,33,0D,77,28,F5,84,10,03,0E,54,E6,45,FB,00,E6,95,C5,52,AD,04,26,83,AD,8D,59,FE,AF,01,BD,11,9A,B4,74,A2,A6,E6,BD,AA,B6,DB,C2,5B,47,BD,4B,FA,5F,21,2A,62,CD,65,A6,F1,BD,59,A7,F2,B4,83,35,F5,66,0D,44,BC,93,74,2B,F8,50,F3,88,58,03,1A,C9,0E,70,EB,C5,EE,BE,9B,DE,25,EF,B9,68,E7,FB,4A,86,28,C7,61,62,5E,27,3E,B9,50,21,B1,43,89,0E,DC,B4,46,60,DC,79,76,87,DE,60,8D,29,F1,75,DA,55,F6,39,69,EA,B5,C8,99,4C,C4,C7,3F,F6,DC,2F,66,D1,4D,D5,6B,47,D4,C4,EA,F3,92,FD,3E,EA,96,FD,F4,49,50,ED,B0,5B,94,1B,DF,27,82,D3,F2,46,30,41,68,D0,9C,F9,B8,31,9B,57,50,A5,A5,C9,52,CD,73,42,8A,3E,2A,D8,1B,A4,B6,E6,A2,84,E9,2C,FC,A5,4C,E7,7E,DA,B2,72,2E,AC,12,E6,D4,43,06,F5,51,83,5A,B8,48,AF,86,C7,C9,6C,1D,B1,01,C6,FA,B0,D2,13,CB,E7,E4,81,F9,37,BD,61,61,95,46,70,EB,D7,51,BA,2E,82,ED,45,1D,42,CA,9B,54,07,64,AC,24,DA,3B,4B,84,40,B8,02,3F,9A,20,84,86,19,4D,C4,0D,70,3D,40,06,EF,F6,7D,CC,B9,AF,F2,B5,D4,9F,32,37,AD,F9,BE,CF,3C,50,F2,09,F6,F8,FC,1F,2F,77,B0,C2,9E,A1,C3,F1,41,EF,98,42,15,AF,CB,D3,7A,81,07,F9,BE,08,1F,62,F4,13,96,E2,74,FC,06,B8,28,B9,6D,85,41,C2,F0,2F,DE,FC,C8,9D,4C,D1,8D,AD,B5,12,94,44,96,1E,2E,5A,1A,22,97,E2,0E,B2,27,20,A0,64,80,C6,B2,A2,1D,F0,CC,9A,78,C9,EF,4E,E2,F8,AD,0D,6A,5B,2E,BA,4F,79,65,C1,30,B6,E6,1D,21,E2,A4,60,F1,68,29,24,95,2E,AE,54,4B,1C,25,1B,18,D9,27,9D,87,0C,8E,E3,29,0E,38,E5,89,8C,1F,FA,7A,44,B3,BD,B7,F9,2D,E0,18,65,4C,09,AD,7E,6C,38,2D,A4,A3,69,87,BC,B4,6D,76,49,23,64,B9,2A,D8,FF,3F,A2,C6,C0,F2,71,76,33,8E,6F,B3,B0,3F,07,76,CC,B5,6A,0D,2E,09,DC,2C,D6,CB,17,0C,68,F7,7C,0C,1D,45,80,29,5A,24,25,0D,9E,02,0A,AC,EB,DC,16,E3,37,F4,7F,28,31,C5,BF,46,00,10,9F,70,32,A7,8D,CE,58,89,30,EA,D3,42,8B,28,4A,E5,98,48,F4,A3,F4,9D,7F,9C,2E,5A,68,6A,74,89,28,40,A4,21,69,6A,E8,59,A3,B5,7F,F8,2E,67,26,B4,6C,04,E1,44,C4,C0,3F,62,C7,45,0F,BA,BC,FE,82,78,AA,EA,61,9F,4A,A9,B1,57,30,9F,67,BF,31,3C,7C,AB,27,27,C5,E2,09,E6,D3,74,7D,BF,CA,D1,6D,13,4E,2C,26,BA,5D,32,F8,76,24,9B,18,29,64,13,B8,F8,DC,8A,9C,1E,78,D2,56,0E,9B,E0,78,9D,96,AD,58,B1,C9,98,1E,11,1B,9A,DC,32,5B,1A,D0,F6,B2,5A,D4,34,55,61,D2,32,81,26,56,A4,C0,86,78,99,C2,BA,6E,49,08,F2,AD,59,30,D2,13,ED,D9,A8,6A,BC,6E,47,3E,5C,BA,7A,23,82,5E,1D,B4,D0,54,AF,B0,68,6F,9F,45,06,FC,3C,A9,35,D2,CE,A1,B6,12,B2,9E,0B,DE,C8,79,6E,42,AE,DA,0E,F4,D2,23,F9,BE,CD,BC,2F,FE,ED,19,68,F6,EF,AB,55,3E,2E,D4,56,04,3A,F9,2C,B2,78,D0,76,F6,6D,2C,D7,6A,5B,99,E1,AD,92,F8,5C,4B,7B,0B,B9,BD,A7,D3,8D,CD,FA,9E,23,CE,50,62,9E,67,3D,0B,29,01,5D,72,74,DE,A6,D8,94,E4,F6,14,F1,89,0A,81,91,69,B7,50,CE,CE,19,7B,AA,B3,0F,AF,FA,E7,4D,C1,3A,A4,BF,AA,F5,34,5F,BD,B0,13,BA,2D,B0,4D,E7,AF,3E,B9,57,FF,EE,22,B2,6D,8E,07,61,D1,B1,8A,2F,CC,42,F3,55,26,30,2C,1A,DC,3E,3B,62,1F,B9,66,FF,7C,30,62,BD,A5,58,ED,42,18,F5,E6,9B,16,E4,28,E2,9C,FB,1F,A0,4C,B1,35,9D,ED,9E,01,D1,72,83,8B,75,AA,CE,62,0C,1D,B1,51,FE,4C,9C,7D,08,45,35,8D,B2,CC,21,A1,5F,7A,B5,7E,94,25,85,5B,6B,61,18,92,17,2C,F6,EB,15,7D,CF,F2,DE,5D,12,B5,0E,1A,36,D5,8F,B0,D1,80,3A,17,BC,B7,28,CF,45,47,CC,21,31,F2,B6,39,DC,E7,8D,44,39,B1,67,3D,EE,D9,99,6D,A4,A5,BE,0D,B1,C4,84,14,73,A3,18,E1,25,60,6B,02,84,89,35,0B,C1,8F,12,FE,7F,3B,82,D9,9F,3E,AE,7B,15,29,E8,7E,CA,02,37,6E,B8,42,57,CF,6A,25,25,9E,63,A0,23,5A,8A,91,F7,2B,2D,97,83,FF,E6,91,19,12,60,ED,7A,4F,D0,70,CF,E3,62,3C,FA,6C,9E,3F,E0,3A,A1,82,B6,96,8C,99,EE,66,86,9A,D5,B5,0D,6B,84,1F,3A,64,33,BA,C2,45,B5,0A,C4,89,16,13,3C,E6,9A,62,F5,8E,86,FE,92,26,34,BE,ED,B2,1F,FC,BA,BC,B9,7D,E1,5D,A1,E5,0A,03,5A,B0,95,F4,81,34,1F,78,E9,55,31,67,23,ED,D6,1C,E8,C8,69,E2,B0,E1,F9,2D,0E,BA,EE,CD,A8,0E,0C,54,52,F6,75,A7,54,49,57,32,BF,D5,3D,73,1D,84,17,64,7F,94,A5,AA,67,EE,4F,33,A5,D5,9D,91,1B,5A,62,98,A7,F4,63,32,79,3B,29,4F,05,60,12,D4,04,CB,D3,96,AF,C2,9F,C9,77,96,6E,76,9D,81,50,2B,17,82,74,6D,0F,B6,FB,78,6D,D7,24,9F,4F,F9,D5,14,9A,20,5F,C6,BC,1D,95,30,42,E0,B2,3F,A7,E0,5F,EA,84,CB,14,99,11,33,F0,7A,F3,78,B9,1E,FB,0A,8C,ED,A5,D9,ED,47,50,5F,C0,42,59,3D,07,F8,CD,44,3B,14,09,19,4E,F6,DF,02,94,C2,61,73,70,5A,B1,83,A1,44,42,8C,2A,49,3C,7C,18,CB,47,BE,6D,4D,EF,4D,C9,58,D7,E0,55,09,17,8F,B8,DD,7D,00,0C,25,E6,45,F8,75,5D,7A,F6,F2,BF,C2,F4,11,8B,94,6F,9A,94,66,B8,F4,1D,A2,86,01,36,4E,E1,47,2E,AD,BF,B2,27,2B,A1,5B,B0,A8,FA,B0,63,5C,94,60,5F,EC,B0,44,2B,57,39,AA,14,D2,F6,3C,A8,C2,13,72,99,DA,50,A6,CB,34,C8,A2,CF,C5,FC,7D,05,55,09,FA,44,7D,78,4E,D7,42,6C,7F,62,02,48,F6,EA,12,DD,C9,32,02,94,31,1C,90,E9,1B,E7,9D,4C,42,D1,64,72,2C,78,94,02,25,55,FE,10,0D,0D,64,61,07,00,77,57,0D,FE,DD,10,DB,1A,05,8D,86,17,4B,B0,FF,85,E0,48,86,4C,89,3D,73,E8,9A,41,82,95,86,5A,89,12,08,99,CF,88,C7,FA,B4,5F,28,B1,2C,9F,F1,3D,84,F3,3E,7F,2F,E4,17,5A,E1,E4,A5,7A,3F,C6,A1,E5,F1,50,75,EF,30,44,13,E0,DB,E9,2A,2E,64,3C,12,1C,95,6F,CC,92,3C,32,00,26,A8,60,25,19,B6,97,07,FB,4A,AA,00,3F,1E,CD,44,FC,DE,F5,5A,4E,80,8C,4C,5D,9A,D0,AB,B8,B2,8A,37,AD,6C,26,36,9E,19,D2,13,EE,4C,71,4D,8B,71,D6,E1,CA,54,05,9A,BC,B7,0D,DC,79,E2,17,5B,7E,A1,FD,27,23,E1,FF,87,BC,5C,78,CE,AF,21,AD,42,3C,88,A1,12,AA,28,74,99,57,B3,8E,01,63,AF,F2,52,69,4B,8F,79,F0,5C,4B,5E,E6,46,51,D1,0A,6E,17,F8,37,C5,30,70,F3,1F,07,58,94,31,66,7F,13,77,45,E4,E9,89,2F,16,68,65,F0,4A,3C,AE,C6,8C,F0,6A,79,85,BF,30,4B,2A,16,1C,D1,56,75,F6,79,75,7F,BE,35,08,99,B3,C9,D9,69,DE,01,AF,17,2B,8C,F8,4E,5D,19,EE,BA,E6,1D,B8,09,10,AE,69,6E,EB,33,47,81,DE,63,77,2B,E2,AE,1F,FC,4C,19,BC,7A,E5,CD,B5,7C,4E,A9,95,0D,3B,97,E3,ED,50,A6,65,4C,A5,FF,30,5A,74,36,1E,6E,06,2A,C4,3A,6C,5E,88,E0,22,79,C1,5C,7D,49,2D,C0,10,B7,7A,E3,D5,CB,19,EF,AF,5E,7A,E0,6B,29,87,BF,E3,7F,88,60,5F,25,A3,B6,F5,4F,99,A1,82,5F,EE,A1,FD,67,22,61,F5,B3,27,15,6B,FA,96,24,18,36,01,EB,81,88,11,47,69,E4,A7,70,9C,68,6F,BF,EB,AB,63,89,14,1F,B2,6C,28,C0,1A,E4,DC,31,BB,40,AE,87,C7,0E,2D,B2,C4,5A,8B,C7,0B,AE,CD,11,98,62,D5,F4,F9,62,C7,D1,B0,3D,E2,45,4D,B9,F0,3C,57,EA,FE,A0,EE,DA,B0,80,79,DE,00,C4,B8,99,7C,55,1A,45,55,B4,B7,00,C9,6D,4F,BE,2E,96,1A,7E,28,BD,F6,30,A1,E4,F8,8D,EC,87,31,D4,DB,FE,30,4C,A3,8C,12,61,08,F0,48,3E,91,B5,3E,F4,E4,85,D7,B1,76,70,50,0B,40,D9,68,1F,B8,1D,7C,C4,12,53,32,84,EB,17,25,BB,71,BD,1C,36,F6,9A,6B,80,AC,98,88,9E,7C,46,0B,9D,78,13,08,21,A7,F1,03,81,6A,63,91,59,E9,A4,79,0B,8D,C6,5A,C0,44,3F,82,7E,DD,17,0C,EB,06,BC,2F,8F,36,68,C8,55,15,39,F2,0E,4E,58,39,DC,F0,D8,25,1E,F3,B6,2E,67,DC,DC,22,2C,F2,C9,74,3C,F7,B8,80,B7,93,DE,44,63,33,DF,42,ED,20,0B,69,5C,B5,13,7C,B7,DC,22,61,97,19,93,FA,6C,15,8C,DD,AE,6A,54,BF,28,CF,D0,86,C2,F0,22,9F,68,83,B3,3A,18,95,26,CF,F0,08,CD,07,0E,80,CA,5E,2E,EC,D7,AF,91,C5,34,37,33,14,1C,E5,A1,F2,E9,A2,6D,DA,1B,B0,A1,7C,31,76,A8,CD,13,DF,C0,43,63,23,E5,04,B4,94,D5,AC,B5,1F,F9,1A,64,2F,DA,D2,72,9A,00,0F,16,02,3D,35,CA,83,80,19,80,39,95,95,AA,80,1E,F6,C9,8A,49,3D,B6,91,A3,13,19,07,22,DE,AE,D4,0C,8D,8C,C4,61,69,44,A2,F1,E3,28,EF,95,CD,41,C2,DA,CC,BC,B9,32,B2,7A,F2,5F,15,1D,15,8C,83,47,D9,71,E5,AE,C9,74,F4,8D,33,AF,04,01,D3,B0,2C,95,AF,40,0D,F4,59,27,49,B1,7B,EF,4D,A5,B3,82,10,AF,C6,99,9E,E6,9D,C3,DC,64,D1,5A,A0,09,33,1F,8F,AC,2D,67,E7,8D,65,AB,96,FB,93,EA,C5,56,ED,36,13,0D,7B,29,3C,5A,38,13,D9,F9,71,24,3D,66,2D,1B,FD,B8,F0,FE,9D,25,E3,21,82,55,27,2E,89,08,99,6F,2F,DC,25,A7,8E,27,61,72,D5,3F,0B,5B,D6,3D,21,1C,0A,CA,06,11,64,C5,66,94,B8,EA,B1,FA,59,23,8E,3B,C7,01,5D,EE,3F,BE,86,B6,25,F1,90,8C,98,5D,F7,E7,33,64,E2,F8,16,56,B5,10,E9,D3,FA,28,93,09,6F,D0,CB,E8,0F,64,CC,E4,E0,09,11,91,2E,60,DC,06,CA,82,A7,E7,E5,57,E5,F4,AE,EB,17,2C,43,9C,6F,F5,F1,A6,AE,49,31,44,1A,08,18,0B,C8,C3,76,48,00,62,2C,75,CF,C1,20,96,59,72,5A,65,AF,01,18,C8,5D,F9,0D,4E,71,3D,C0,21,A9,68,3D,F0,10,9B,2F,93,E4,E8,4C,8D,6C,B1,61,AA,15,5F,72,62,C7,FF,48,33,83,41,3A,1B,09,52,2A,52,32,B5,A4,9B,36,2B,83,8D,3A,03,3F,E0,97,F9,42,D6,88,DF,35,17,D3,D4,14,C9,FF,D5,40,05,C3,86,B1,43,99,F3,B0,DF,B1,74,EB,B2,F1,77,57,F3,8F,4D,82,A0,8A,2F,99,88,62,56,B4,D6,E9,94,FD,21,BB,A9,C4,D6,EE,84,3C,43,13,F9,D7,9E,54,6B,AD,BD,92,A8,8F,D6,C4,AF,68,FF,23,0D,C3,91,CE,97,66,17,0A,C0,F9,E7,B9,7A,26,A3,69,F3,E3,CE,3D,F7,F9,3B,30,8D,49,52,EF,DC,30,D7,2A,96,16,9B,10,55,7C,26,8F,12,AA,07,5E,7B,3E,AF,FC,57,20,13,0A,A4,D6,43,D2,0E,50,5F,D7,BD,14,94,82,E0,3F,6A,70,1A,D2,C7,1C,D9,E4,74,16,49,6D,B1,AB,E1,9D,6D,D1,60,C2,C8,67,F2,3B,A8,4B,A5,31,13,C9,2B,78,17,9C,54,5B,D0,18,D8,82,FD,C6,90,22,96,A4,8C,0A,B3,54,4E,E4,4E,70,4A,B2,CF,3D,6F,78,E9,43,C2,B5,DA,4E,7A,91,21,29,F5,E6,F8,01,1C,C2,B3,E6,80,8D,D0,E2,63,61,1C,0F,34,F6,D1,FD,E3,1A,9F,40,89,06,60,12,D3,A1,D5,6E,C7,7A,2C,DE,C2,39,3D,D1,9E,68,A6,AB,A7,08,55,24,14,73,79,9E,9A,15,5B,77,E8,83,E6,02,D3,CB,17,38,15,CD,B1,F8,1D,AE,8E,3F,F2,C6,32,68,23,F6,EB,37,43,8C,10,1C,71,44,5A,06,C4,69,04,D2,D7,56,6B,73,27,B8,59,6E,39,04,D5,62,A5,9A,89,25,D1,7F,2B,4A,C9,74,E2,1A,46,0A,4F,FE,B6,A3,47,9A,67,A0,E0,C8,D3,5E,07,A1,6E,7E,08,16,7F,7B,9A,3F,E6,65,C0,F3,B7,D4,14,AE,2B,DC,4C,17,B4,1A,81,0C,71,DD,66,B6,58,6E,72,80,9F,AF,37,F5,A0,86,DE,18,6A,6E,39,38,AA,25,15,B5,56,36,B3,3B,3F,21,13,73,00,68,8B,74,CC,10,25,C0,EE,9C,F8,5F,F6,C5,B9,9F,F6,1C,8B,61,6F,61,D0,37,24,07,27,02,64,19,15,D3,DE,E7,32,7B,9A,F6,B7,A0,1F,ED,69,9C,66,F6,3B,CC,FD,B8,6D,5B,68,AB,75,98,C7,CB,E1,79,00,48,53,97,77,91,48,5E,87,0E,02,EA,31,4F,D0,2D,60,EA,56,EE,FA,F1,4F,D4,C4,24,52,DB,5F,6E,FF,15,0E,C7,E5,7F,D8,CE,C1,81,BC,8C,36,9B,FF,D6,96,D7,02,39,E9,AA,61,03,66,2E,DE,0F,11,31,40,FD,8F,A0,A7,84,FB,EB,97,EC,BE,11,34,34,D6,7A,FD,B6,A0,24,A4,84,F6,52,12,78,7F,2D,35,5C,FA,64,7C,B1,99,08,47,15,FD,32,0C,DF,86,8C,48,28,C5,9F,CA,71,70,8E,36,C4,25,50,AD,1E,C5,66,2E,7F,E4,74,7B,91,1B,ED,CA,2A,B1,DF,97,AC,4E,AE,CC,04,FA,C1,0D,11,1D,4C,79,7C,96,70,A9,D7,60,B2,68,E5,98,14,EF,B0,89,6C,C3,09,F3,05,AB,47,E2,6C,8C,B5,07,00,58,BF,F7,C9,68,0F,BE,88,D7,AE,77,2B,C3,72,EE,E9,44,8C,D3,1B,F9,14,7A,D3,BD,02,40,8D,29,27,08,34,E9,83,09,93,F0,ED,19,87,4F,26,6A,64,07,38,C2,87,57,8E,6A,A1,E2,E8,78,55,B4,91,5A,B5,BD,35,14,B8,45,F2,53,02,FC,31,30,4F,17,00,FB,5A,BB,09,03,BA,FB,46,85,38,75,81,8C,DE,0B,84,D2,38,32,D1,26,53,C5,2A,BB,9E,13,0F,4C,E7,8F,6A,6E,7A,6C,5B,36,63,12,B3,31,41,68,CF,FA,CC,A3,6A,72,A5,93,DE,F3,56,47,18,B5,97,A7,98,20,AB,96,31,77,7D,EC,28,DE,D6,49,52,19,E9,20,BE,28,25,6C,3D,E1,48,59,6B,91,77,67,9B,72,F4,04,3F,BD,19,73,3A,AE,57,8A,7E,61,55,9C,39,FF,71,7E,ED,CD,EF,0B,A8,9D,5C,19,99,B8,E4,D8,76,FB,5D,84,EF,B2,AB,42,81,44,B6,B1,38,79,B1,F5,A1,77,14,A3,A3,3A,DD,D4,32,2E,28,7D,45,D4,4E,62,F8,3B,75,EE,24,71,F7,7D,91,5F,D9,A7,A0,0A,90,67,63,63,BA,6D,48,8C,56,41,B0,D6,98,64,69,07,41,1A,11,8A,DB,31,99,E2,DC,78,74,AD,73,FE,F6,79,AF,96,2F,CE,14,0F,3F,4A,1F,EE,FC,CB,46,6C,F2,AE,F0,1A,0D,9A,EA,02,BF,51,A7,AC,B4,B2,D6,1A,29,0C,85,51,E8,9F,FE,33,AF,0D,0B,E1,BC,D6,93,9B,26,44,3F,B9,4D,2B,54,CA,73,9A,6C,7B,40,B5,42,80,DB,45,85,AB,A9,41,37,EF,8E,58,22,20,D9,E6,B2,77,54,9B,0F,40,1E,CA,9F,C8,D9,97,9D,78,9D,11,BD,C6,4A,D1,67,ED,22,B0,4B,B5,B8,85,58,85,90,56,B8,13,18,1F,C2,94,59,B6,AD,90,00,70,B2,12,7B,98,E5,8F,CE,5F,16,A5,A8,CE,B6,C7,B6,DF,FF,50,20,92,1A,F9,00,95,47,91,79,58,F9,63,F6,C6,E0,AC,D2,14,21,27,F6,6D,07,07,AD,34,8E,73,4A,B3,22,0D,5F,FF,76,5D,ED,75,B5,D2,88,1A,F5,58,A2,B3,52,8C,7B,B2,A7,98,77,5F,FF,81,7B,28,07,BE,E9,CF,2D,CE,5A,B8,66,5F,34,8B,F2,F1,28,D6,AE,17,7E,17,D3,12,47,E6,B9,A1,DB,D8,18,07,5C,84,68,CE,90,8B,A5,00,8C,E6,C9,B8,51,70,CE,F5,1F,88,22,71,FB,F1,62,22,F8,BD,18,0F,45,92,3C,87,62,CD,B7,C5,92,6B,ED,F0,F0,45,4C,A8,51,D9,E4,9A,3E,1E,D2,D9,D1,16,62,E0,34,A7,D8,43,50,13,3C,C8,5F,B4,04,DE,57,B6,17,9C,D2,54,FD,35,29,77,E9,BC,B5,76,55,6B,FD,D8,FE,BA,DE,2C,20,4A,D5,BE,0A,47,C1,8E,98,E4,3B,70,59,B9,2C,D4,63,1B,11,3F,14,E6,2B,87,2F,4F,57,9E,35,04,01,82,55,0F,C0,09,31,94,20,FC,A1,28,63,7A,8F,01,61,44,76,60,25,D9,3C,B5,A3,6E,D2,3D,89,E2,57,FF,F6,87,AB,C7,05,DA,94,BC,3B,3F,82,68,1D,2A,E6,19,9A,89,25,FB,EE,43,FF,47,DD,FE,65,71,D3,86,20,B4,83,88,4A,1F,12,4A,D2,D2,A8,B6,06,36,E9,B1,24,78,D0,AF,AE,EA,F3,A6,8D,43,60,CE,48,0A,87,0E,BA,BD,1D,70,C9,97,0D,40,88,38,8B,7C,3C,A9,A6,4D,47,B6,43,97,BF,E8,EA,40,99,61,5E,DF,EA,3A,5C,16,00,12,70,58,56,64,0D,11,8E,30,11,50,DF,10,25,79,31,34,4A,14,D4,44,61,38,1D,4D,6D,8E,83,24,F3,4E,A8,5C,58,F5,69,4A,45,D6,B5,F5,E6,40,F1,04,E3,55,32,75,D2,CB,D2,5A,EA,DB,12,B0,06,A8,6A,7C,9C,53,CF,C9,F0,47,B0,AB,4C,68,BD,A4,A6,9A,A3,2C,D6,80,D4,3F,14,7E,79,1C,D0,3D,AD,4A,B3,68,E6,7E,21,09,3A,0E,79,92,27,21,34,B8,BE,1F,C6,9A,3E,7A,BD,72,ED,3B,46,C6,9B,87,CA,5F,8B,E2,5E,22,D3,19,A7,80,9F,D2,93,A2,3F,C4,94,15,3A,F8,57,75,46,F4,22,CB,4E,A1,0D,0D,6E,C9,C0,61,5C,A1,29,F6,77,77,85,9D,B2,62,8C,CD,18,F0,E4,E6,F9,54,39,EB,55,85,BD,A5,E1,99,48,C1,E6,01,2D,2A,4F,9C,27,84,0B,DC,AE,B2,CC,02,D2,B9,07,94,7D,99,EA,78,C8,54,64,97,09,46,61,EE,D0,1F,E5,24,7F,CD,74,2A,65,06,E6,29,2D,00,5A,3E,C5,34,AD,87,77,41,66,60,3D,1F,C0,B6,28,9D,E7,CA,0A,5C,5A,5C,73,59,D5,F9,A7,1A,C9,D4,99,AF,13,96,E3,F0,45,8F,D4,80,46,AE,87,87,8C,E6,64,E2,A5,AA,0D,3F,99,94,AF,69,FF,92,63,48,1C,5B,D5,61,7F,25,39,A5,49,40,EF,B0,1D,21,D6,39,47,4F,8E,37,17,68,5D,FD,A7,BB,1E,88,30,CB,02,EB,BD,5E,CE,EB,60,0A,B8,55,AA,45,C7,19,A9,68,BB,B5,08,A0,76,5D,39,FC,3F,00,EB,0C,CB,14,92,4D,BE,41,B2,26,39,F8,4B,65,72,AD,D1,54,DD,B0,D9,C7,AD,2E,D1,22,59,FF,E2,BA,05,A4,1C,67,D5,D1,4B,35,C8,01,DA,12,33,58,E5,B7,41,AB,48,C5,21,62,2E,E3,EC,37,C1,F6,2C,18,16,7C,09,F0,46,0D,3C,81,45,4B,59,62,47,97,A8,E3,E1,09,C9,04,08,68,29,CC,DC,9E,1B,02,92,17,46,83,7D,C3,E5,DF,54,86,39,9F,A8,A1,83,30,41,09,95,84,44,42,39,E4,34,55,19,7E,66,4F,EA,7F,FD,EF,25,F0,C3,69,F7,E2,D0,9A,A7,1D,5B,F5,BC,24,8F,0F,E5,41,02,9F,4E,2C,93,4C,C0,C9,E7,AF,A0,CE,04,EF,C6,FC,E3,B6,2A,FD,00,93,91,D9,77,CF,79,B8,94,0F,29,45,9B,12,E9,A7,84,A6,10,D7,3D,10,39,4E,84,C7,54,3E,A1,ED,34,6A,80,62,9F,6E,3A,BB,F7,EE,AA,F9,75,DA,84,F9,D9,27,38,20,CB,E7,09,94,DA,EF,B6,E3,1D,79,E6,EF,C6,B4,27,DD,04,21,BE,7F,E0,A9,A7,1E,02,41,ED,F6,05,E6,5C,3D,DE,54,5E,0E,A5,CF,A5,40,17,AC,C8,96,4A,A5,74,44,3F,6E,E1,AF,BA,3D,BC,63,DD,4E,BC,E6,6C,67,D7,1F,A5,98,C8,77,23,85,0B,C9,5B,28,85,D2,73,42,F6,CC,F3,5B,E4,2A,75,A7,91,12,90,FF,A8,7D,C8,0E,13,47,32,67,A8,6D,D5,69,2A,21,D3,52,FA,8A,8A,44,B3,9A,D7,14,41,AD,88,16,DB,16,99,21,3D,BE,25,01,FD,45,1C,CD,0C,A0,BE,EC,D5,07,52,4E,13,2A,18,24,1E,2B,E6,44,94,05,7A,E4,74,7F,A3,18,AC,A7,1A,60,25,E0,EB,B1,77,2B,82,40,08,9C,9F,B1,5C,28,87,8D,E5,40,06,B0,D1,C6,79,A8,54,C0,23,C6,85,75,C8,1B,78,A4,14,D1,43,54,08,79,33,BC,04,14,0D,C3,BE,53,48,08,BC,00,B5,79,B8,D2,4D,73,32,6A,93,A9,7C,12,8D,BE,3F,E7,E5,D5,F2,55,90,79,5D,AD,68,67,79,03,BB,82,34,B5,5B,43,A8,24,93,49,32,88,1F,BD,FF,40,1C,49,1F,1A,A7,B5,40,5C,92,6C,02,30,43,40,B0,1B,BC,1F,0B,24,52,CB,8E,48,10,A1,FB,6B,F1,4C,9C,D0,4D,98,D8,4A,90,AE,D1,19,64,78,07,66,61,77,56,80,27,97,19,AC,C7,78,F0,D4,AA,82,E9,94,1F,2C,EF,A0,4B,AA,5B,C2,CF,59,8C,8D,7C,E5,B0,60,20,46,39,76,7A,21,19,66,CF,F5,21,F6,AE,83,5C,B9,1D,39,36,3D,16,D3,CC,1B,59,A3,5F,AA,CD,FF,8D,E2,C1,C6,B9,AB,26,F1,F7,11,C6,8F,39,04,35,47,63,D7,F6,AF,6E,5D,95,8F,9B,A3,AC,80,26,9B,F9,8E,57,6F,D7,23,EC,30,64,81,6D,C4,2E,56,29,F4,62,9E,AF,F8,BF,89,B9,2B,86,DE,86,C4,B9,5C,C4,DF,36,0D,15,94,58,13,77,5E,B9,5C,4D,46,D6,BD,73,F4,37,90,BB,69,60,21,7C,9D,C5,48,A1,36,D4,68,1E,8A,1D,5D,37,CE,0A,EB,50,C7,89,96,AD,33,9E,99,B9,C2,F2,5A,8D,EB,39,79,AB,03,98,B9,24,AA,4B,6D,A1,46,5A,04,38,D6,AA,F2,92,21,86,FD,78,50,42,DD,80,53,2E,B7,DF,67,72,50,EA,83,E1,D0,7D,2E,60,43,AC,7C,3B,69,47,4E,9E,A9,5C,F0,9C,AD,0C,E9,66,09,92,22,E0,B0,A9,3F,DC,96,DB,BA,7C,3C,FF,F8,5A,2B,5C,5A,1A,25,62,7B,EB,0E,B4,D4,92,78,86,E0,F4,6E,7A,81,75,7A,DD,2F,D1,21,3D,EA,0D,3A,F0,DA,ED,99,B1,73,33,48,88,48,B2,03,42,4D,4E,17,71,BF,2B,20,8F,A9,A8,7E,6B,E4,DF,3F,41,3D,7E,EB,14,9E,9E,E5,6E,FD,3F,17,FE,BE,35,85,E8,DF,5E,12,FF,6A,3C,DF,63,17,5F,89,D6,76,8F,3B,A2,E0,63,A2,48,E8,1D,69,CC,0C,49,E8,C0,BD,CD,DB,E6,6B,56,94,5C,AA,20,4F,D0,9C,D7,F7,4D,B3,87,5D,F2,4D,A8,8B,C6,22,AA,EE,2B,CB,0B,C6,BD,CD,F2,77,E0,F2,4B,7C,D1,8E,BC,85,7E,F1,9A,07,12,7D,AF,12,7E,48,1C,90,24,CC,F4,E0,59,E4,A6,80,5C,3D,54,E1,D6,6B,25,68,41,F2,73,6D,E0,21,C3,6E,65,14,2D,9B,09,9B,DF,3E,30,83,66,34,99,9D,72,AC,83,98,F8,BA,6E,B9,CF,3D,1E,8A,74,FD,AB,30,19,DC,56,E1,C5,AE,45,D9,86,16,45,54,FA,B5,D0,C8,C6,82,BC,37,31,9A,46,0B,2E,16,69,E2,0A,D9,2A,FB,C9,88,21,5E,00,51,CA,89,78,79,E7,56,96,18,99,F7,B6,15,8D,D8,06,1F,77,00,B4,3D,B0,53,CC,67,E5,BA,42,01,85,69,B1,58,C3,1B,DB,83,79,46,35,10,EA,0A,5D,A0,A3,9B,BC,AA,A1,84,DB,5F,A8,80,35,CA,E5,FD,05,3D,7D,A6,8F,D6,81,EF,1F,88,22,97,E6,DD,EE,32,A7,E7,F0,6E,60,0C,CA,B2,19,39,BB,54,B5,A5,D7,4A,AD,82,33,44,AF,0A,2E,1E,88,A4,4E,6A,20,63,DA,78,15,E2,20,D6,0F,62,11,39,13,63,56,02,D1,43,90,F4,0D,7E,99,2D,36,8D,E3,3B,E5,16,9D,69,17,95,4A,C4,F5,61,E7,90,8B,EF,5E,52,01,1D,1A,35,76,82,1E,F6,BE,5C,17,A0,35,E2,91,2B,63,9C,DA,77,A1,36,56,0B,66,FC,07,4B,49,79,6F,8C,2A,52,F7,54,CF,8E,26,F2,58,F2,00,59,72,9F,E0,C8,D9,AB,F5,1A,64,FE,DB,8C,0F,C0,D4,27,BF,0D,04,A5,6B,D4,03,6E,56,A0,35,87,55,E4,EF,DF,A0,76,E8,14,24,98,26,97,CE,E8,DB,52,F8,67,74,90,5A,43,3D,26,73,39,2A,E1,D9,B4,E8,72,68,C9,48,9D,4A,5E,8D,A9,5E,80,8D,07,82,D8,A6,04,F9,2D,78,BC,20,E8,16,45,6F,0C,B6,BD,09,2C,0E,4A,15,EE,DC,5F,86,7E,80,DB,15,25,F7,71,29,9A,3B,92,7D,5A,2E,EE,87,14,83,85,81,9A,9D,FE,BF,02,CD,CF,6E,00,1F,00,D0,D9,FA,6E,97,04,6C,F6,52,F7,81,45,06,1F,68,2D,22,7F,93,52,C0,37,EF,13,20,89,E4,CB,73,18,D2,BF,E7,DE,0F,49,61,88,CB,E4,E9,85,EC,A0,99,A7,D5,8D,EA,8E,85,6D,81,19,CB,47,40,6B,12,13,BE,79,22,BF,9C,9A,28,13,BC,85,37,0F,62,79,B6,FF,41,BF,92,0C,6C,6F,4F,D2,5B,F5,FB,BC,96,C3,8D,80,59,58,02,94,EE,0B,C0,C0,66,A3,1B,6F,34,A8,FA,16,90,F9,18,C2,98,A7,80,E5,9E,5D,00,91,AB,D3,B2,E7,9A,15,81,D8,59,AA,87,1D,2C,E1,1F,60,BE,90,65,85,4F,BF,F7,50,0D,B7,FC,E7,0B,C6,EB,26,49,27,95,78,77,B4,39,E4,B0,24,D2,84,63,FC,D6,8C,87,89,A3,34,09,10,0D,83,DD,01,33,7F,B6,28,65,97,43,47,EB,D5,92,51,EC,8E,D7,30,F0,4E,90,0D,2C,8A,80,46,4B,72,08,EF,F5,FC,F0,4D,8C,7E,82,71,CC,F3,79,D3,A0,75,A4,74,BF,E0,00,A9,57,00,E2,A1,73,FF,29,E0,F4,D9,DD,3B,82,DD,55,FF,AD,F5,DF,FF,F9,CA,BA,61,5E,89,B9,71,3A,BA,33,03,71,AD,FD,6E,E5,75,ED,38,D5,CA,A3,C8,34,D0,FB,A9,2E,11,20,B4,59,5F,39,D8,A4,13,27,3F,02,A6,1B,3F,28,26,EF,7C,AF,F0,CF,0F,D9,96,CC,1B,A4,96,94,77,B8,6A,02,0C,1A,EA,C7,0D,E4,EA,16,2E,34,C5,7C,45,71,BD,45,5A,19,7D,44,04,E3,72,EC,92,5B,93,77,2A,10,E3,19,7F,1F,FE,C8,88,21,5C,31,D9,55,5D,37,45,E9,AB,A7,79,49,9F,7B,87,78,C6,92,50,18,14,00,AE,BA,19,88,99,6D,43,26,D5,A6,89,12,B8,27,E1,F5,32,83,EE,1A,13,1A,83,33,3A,F5,B6,20,F3,D3,04,94,59,74,E0,49,6E,C6,E7,C1,F1,0E,55,84,0B,70,3C,F8,9C,25,D7,6A,EF,11,02,A4,8A,20,CE,7F,9A,FA,15,45,00,5E,88,41,91,0E,C9,F1,3A,77,B2,C2,9A,4A,0A,0A,5C,1B,50,92,14,B9,39,68,9B,47,B4,B1,66,D2,D2,3D,88,3E,0C,C2,2A,2B,88,45,D7,44,86,2B,86,49,80,06,8F,41,39,1F,B5,FE,23,FF,5C,17,F0,10,45,A4,EF,F9,DE,03,CC,52,3D,C7,27,5D,10,5E,7F,2D,99,15,07,FF,56,4D,AD,0A,DA,DC,56,AD,8E,B6,FC,04,E5,5F,12,43,B8,E4,9A,1E,2F,EA,BA,AB,D0,A1,E2,AD,85,08,8C,1A,9B,F9,CB,8E,FA,6F,00,F1,DB,B6,A0,6F,99,B7,F2,25,11,BD,15,57,3F,6C,0A,C1,5A,89,3D,33,B1,C0,6F,62,C0,D5,EC,FB,35,70,9D,BE,63,D1,7C,7C,F2,A0,43,DD,6D,D0,0D,AC,95,D8,BF,3E,54,44,C3,68,7E,7E,C6,FB,0C,CF,10,4A,4F,A1,D2,C0,55,1C,50,CF,46,B2,E1,F2,7B,7E,19,4D,87,18,CD,F5,7B,49,7F,BF,2C,3B,40,71,7B,42,14,86,6D,2F,7B,94,84,F7,67,09,66,15,23,D0,7E,AA,94,80,0B,9F,29,80,FB,B4,D1,ED,BF,1B,B5,15,C8,A6,1C,41,62,48,9B,C0,AF,06,AE,68,3D,0C,08,7C,B1,88,CE,07,BA,98,BE,4D,C5,1E,34,A1,42,D1,E1,C8,9B,AA,1B,10,2C,41,D8,A3,A4,AB,33,82,64,B6,FA,A7,E6,3C,E5,CF,BA,8F,D7,AB,AE,E4,31,7B,84,EA,9B,4E,D7,38,52,AF,26,DE,11,9F,99,06,A3,A4,DD,CE,A3,54,29,2F,43,89,EC,59,B2,A5,E5,7A,E4,70,65,41,98,C8,36,0C,D6,CB,4C,FF,E5,2B,C6,91,FA,AA,E5,CF,C9,9E,94,93,2D,B8,7E,C9,C0,D4,AE,38,99,23,39,3A,89,E1,D2,F7,58,6F,D4,FE,C9,62,65,CC,59,CF,0B,54,DB,4B,43,94,E4,A5,F8,D0,10,5B,17,5D,53,F7,60,D4,00,EF,5C,83,19,8E,C0,AE,E2,82,C8,5D,7B,DC,AF,6B,9D,3E,A0,EB,0F,82,99,7C,1A,F4,C1,15,A0,C2,ED,7E,AC,8C,44,18,89,B2,FB,1C,5B,77,9F,C0,0F,6F,AD,9F,1D,C4,2B,09,C1,26,73,45,A6,40,E7,23,F4,FB,D4,E3,D6,E5,AF,D5,5C,3B,8C,1A,1B,B0,F3,2C,95,DC,05,58,39,23,39,61,1F,AD,7D,47,99,E1,7E,5B,FD,8B,E2,5D,CD,F1,47,9D,55,50,B9,8D,09,9D,71,31,BD,8F,3B,D5,B3,54,BD,DE,92,35,7D,0C,71,78,14,94,6B,76,13,DB,93,2D,10,B6,FC,F4,7C,F5,CD,9E,86,EA,C1,BD,32,EF,66,5B,94,3F,26,34,11,23,F0,3A,1A,25,98,5A,DB,D5,BF,67,6E,43,61,10,E0,81,65,80,EC,08,9B,6B,EC,71,A6,6B,23,48,3F,88,F5,CF,42,88,79,F2,32,D0,EB,70,FB,E2,90,5A,E6,30,66,49,D5,1E,1B,E2,0B,BC,66,B0,77,70,1A,75,38,08,FF,7A,7A,22,69,6E,D0,0C,49,D5,5D,75,62,B2,01,B7,AD,B4,2B,69,7F,51,DE,AA,41,17,5A,BF,FC,44,85,22,46,F2,A7,C1,39,1A,34,6D,00,BE,F0,7D,DC,2A,1E,B9,4D,D0,CD,3D,B9,D9,9A,B8,45,C7,69,3A,88,B2,17,91,36,27,3B,D1,40,AB,B4,C4,00,C7,F9,E9,0F,2B,FD,AE,E9,2A,E0,E0,B7,C0,1A,9E,3A,15,E5,56,7D,CF,8F,1E,D2,98,F5,55,CD,D1,7F,EF,16,1F,B2,2B,5A,5B,8D,FF,1A,80,C4,A4,22,A5,F0,06,4B,00,E6,CF,52,76,34,79,5D,21,89,71,CB,FD,FF,C3,A4,44,00,AF,76,DC,31,48,54,7F,21,6F,2D,11,AA,34,C9,DF,4D,C5,AC,D0,CF,BD,3C,2A,B7,D1,20,77,7D,EB,93,A8,ED,4D,28,07,38,74,92,30,F4,90,7F,C5,73,0B,F6,8E,D7,5D,77,73,00,3A,DC,C5,1B,03,29,27,38,07,32,71,D9,43,CB,5E,14,6A,8E,65,C9,33,7D,63,5B,34,01,68,2F,A0,1E,8A,D3,7F,70,8D,7B,6C,D9,5E,6E,0C,81,C3,61,E0,D7,43,12,C3,18,CA,C0,29,F1,DD,5D,0D,31,50,65,64,22,CB,B4,86,C4,5A,DA,67,58,87,CA,EB,0B,ED,21,E1,A3,04,4B,8A,A1,B7,BF,A4,B7,3B,4C,D5,7E,5F,0D,EE,DC,77,D1,7C,B3,72,95,89,41,99,A8,C6,16,C9,63,8D,89,21,A1,5E,C9,08,6B,B0,F7,22,17,5D,95,3F,C5,B4,8A,B2,29,C1,C4,8F,E6,EB,0E,A0,DC,2F,A9,73,E8,80,EC,0A,AF,BE,29,84,21,7B,E9,4C,AC,E3,E7,AC,71,D5,7D,FE,2E,FB,44,42,06,DD,74,DD,40,05,AA,97,5B,54,CC,AF,3D,B8,96,10,0A,1B,44,E1,07,8C,86,AB,31,FC,35,2A,94,C1,C2,19,1A,88,86,AF,5E,A1,E3,23,AD,86,5A,D3,62,2F,90,39,9D,66,2A,20,CA,26,0C,EF,93,C9,C0,0E,88,14,FE,40,73,71,67,99,05,88,CB,7C,75,DC,5F,02,4E,F8,D5,0C,30,89,C6,BB,BF,11,3C,34,6A,3F,8F,AB,0A,8F,EE,41,9C,3F,FF,D5,06,4E,77,51,BA,A1,5E,91,BD,51,F6,61,BE,9F,7E,74,41,4A,22,05,3D,C2,BC,E5,D8,94,90,1A,59,C5,E5,41,A8,D3,3A,81,32,41,6C,7A,E3,A2,99,DE,D1,9C,5F,50,38,71,30,1F,03,F4,7E,45,97,6B,DA,6C,BD,1B,95,93,C8,42,AC,A2,A0,3D,E6,3C,6D,8F,76,76,96,78,5A,B5,72,FC,3C,7C,4D,22,54,51,F2,EC,85,E3,C9,39,6D,39,E0,81,58,7A,2F,D3,0A,72,8A,17,2F,FA,7E,F7,21,77,12,01,D1,32,93,89,0B,F7,D5,27,15,34,26,82,E9,AE,52,D3,63,5C,D8,27,6C,C3,BF,75,B9,31,A1,82,60,04,85,47,93,09,61,2D,30,26,28,00,2F,8C,E2,CA,8D,D5,22,AF,C8,8D,4F,43,27,6E,E6,EB,11,60,01,5E,93,37,84,12,66,1E,8F,75,1C,D7,FF,D4,B5,91,CF,4E,49,FD,5C,44,7F,17,9B,4E,F5,B9,08,B2,7B,91,C1,13,9C,00,42,6D,1A,F8,20,BD,90,58,49,05,D8,67,BB,02,51,8A,B0,C5,58,1B,23,5F,71,A7,20,92,53,D0,CC,E8,A6,C9,99,B3,A2,29,FC,66,40,59,98,C3,95,6F,C3,B9,37,24,7C,6B,38,11,8E,7A,4D,BC,1B,26,0D,FD,A9,42,5D,0A,E9,24,1A,34,E1,00,8C,BA,63,7B,7B,44,F4,CC,9F,B1,14,91,87,66,F6,75,98,A4,C3,F8,BE,31,B2,9B,96,03,45,4E,0A,B8,F6,7E,A7,3D,75,8D,43,21,9C,53,E6,09,88,6D,0A,3D,CD,BD,4C,35,6A,41,50,E6,EE,C3,70,32,A3,15,AF,EC,72,B4,F9,72,3E,B9,88,B7,77,F1,FA,AA,1B,15,6B,10,70,81,45,0D,97,40,79,D4,59,2A,C7,16,A0,98,86,4C,AC,0A,67,A4,6D,FD,3C,6A,4E,37,2F,2B,11,F7,7B,95,6A,F0,09,6D,B6,77,76,5F,EB,D0,6D,36,63,54,2A,E0,39,58,D2,46,36,71,05,0F,1B,47,51,8F,65,D4,86,97,E2,E1,4C,CD,F5,31,75,4B,DB,93,A4,A1,49,D7,FB,6A,A5,A7,B2,3C,0C,5E,78,35,DD,69,92,93,F9,AC,7A,41,16,5D,AF,10,C8,5C,64,94,A1,E9,C0,F4,5E,3A,0D,E2,57,EF,D3,2C,6E,F8,67,FF,09,61,59,4B,B3,D6,49,1B,1D,DB,6C,0C,6F,B7,B3,36,0A,F7,F4,8E,04,1F,B1,01,68,89,F7,97,45,59,7A,05,DE,37,05,46,99,10,F0,8E,92,23,AB,FE,14,27,6C,03,DC,78,BA,2F,EC,E0,DC,55,18,97,B8,45,02,3D,9B,27,32,A5,69,D1,27,4F,6F,F8,E5,6B,E1,D8,CF,F9,64,59,02,42,88,BA,9A,7A,51,82,43,1F,9C,67,CA,CB,BF,2F,F2,AA,5E,7D,19,09,FC,BD,91,25,FA,4C,6A,56,AB,EA,37,D4,F2,4E,C3,3B,A8,E5,E9,C0,C3,85,C0,FE,63,A3,F3,96,32,EF,10,0C,42,B7,42,34,22,B9,67,E2,A5,AB,F9,9D,36,1B,BF,8F,CD,56,74,F9,83,F7,82,B8,FC,AF,F0,6E,7B,C8,D0,B2,4B,90,5D,79,79,E1,27,A3,14,81,A0,E1,CC,BE,AD,6E,6E,82,D5,32,BC,F2,95,AD,B9,A8,5E,03,87,B9,A9,D0,04,CA,49,20,AC,00,A9,C6,CE,78,32,21,80,25,5B,5C,29,6C,C6,EA,2F,39,3B,69,C7,81,FF,2B,11,0B,BF,48,68,0E,3B,1A,1C,84,FB,D4,D5,5B,DA,71,F9,28,B9,F7,3E,88,0B,2D,8F,3C,00,11,DA,1E,C9,AA,B6,17,BC,19,89,AC,E5,4A,15,CB,20,A0,ED,58,4F,5F,55,71,86,B2,D1,15,B6,DC,04,A5,DB,DC,69,AB,AF,6F,6A,F4,59,5A,17,08,CB,A3,D3,03,77,46,D8,5E,E1,F2,D6,79,99,74,E5,A5,EE,E9,FB,B9,6F,69,8C,73,ED,6F,F0,EB,74,AA,15,70,7C,EA,77,E9,FA,5A,27,43,C7,22,63,D4,52,23,6F,41,CA,12,0A,69,37,9D,65,E2,57,C7,BA,4A,D1,4F,9D,19,4B,18,BF,50,D7,21,E0,2A,F6,14,42,B2,6C,74,D9,9F,75,EB,8C,16,2A,32,EC,CC,E2,4F,8E,1F,C9,B5,9C,7D,F1,81,16,8D,03,1D,0A,86,48,1C,C8,C6,04,11,B0,8B,39,96,F1,07,60,7E,4A,33,44,13,48,5E,4D,F2,65,E5,7D,72,E8,B1,0A,06,A3,20,A1,7A,F3,E1,67,B5,A4,17,C5,57,DD,94,36,3E,71,9E,8D,2B,40,C6,E6,2C,5F,E7,4F,63,26,04,DE,8E,34,56,4E,6D,F7,AF,6D,5B,69,42,88,A6,AF,1C,42,6E,34,A8,A0,89,BA,66,09,50,7E,AD,AA,EE,08,FE,02,83,6B,06,A3,BC,DA,68,0C,C3,F1,75,B7,DE,C2,02,36,C6,CE,18,AC,AA,E8,54,49,E8,F8,77,B8,18,F8,3E,36,65,2E,3B,F4,1A,44,39,DC,A4,50,CD,84,FF,BF,E4,75,4C,FC,DC,B2,1B,B5,9B,8E,0E,8A,6A,EB,08,46,A1,F5,25,37,4E,8B,6D,AB,A8,6C,D3,7E,0F,17,05,21,15,81,C6,3F,A6,D6,84,5C,3F,40,AD,FA,C6,75,C4,92,A0,C1,45,72,64,72,F4,FD,94,B9,90,9D,58,5F,0D,A3,47,6E,46,26,56,C9,29,05,81,41,14,E5,9E,F7,98,EC,8C,1B,DE,EF,18,BF,AA,46,0A,79,37,A0,FD,4A,9F,B8,A1,7C,76,EA,3E,AA,48,BC,BD,48,BD,D6,71,4F,33,DD,43,34,C9,10,AA,44,92,7A,83,5B,16,CB,72,42,D0,CC,11,66,CF,0A,ED,77,96,33,E8,8F,46,8E,6A,C7,CC,8D,53,16,05,84,CD,3D,BF,60,64,38,6D,24,52,E4,6E,1F,EE,27,56,A7,55,85,A4,65,0B,8D,BE,8F,2A,03,E0,B7,F8,DC,42,2E,8F,87,75,D8,7A,08,5F,12,36,CD,A6,AB,73,78,A2,EC,10,01,58,A3,2B,74,9C,AB,4A,FA,A0,BE,2B,BA,93,AB,B7,EB,11,9A,8F,CC,0C,3B,F8,65,FF,5A,63,FD,93,A7,7A,B9,3F,34,10,FA,D8,66,8B,8A,D5,6D,8D,AF,41,C3,0F,DF,76,28,8C,09,B7,A7,7C,C0,8C,1F,0B,1B,B6,85,BE,2F,95,CE,89,CF,53,F2,68,AE,F5,9C,3E,40,F8,BA,0E,B8,7F,9F,00,8D,E1,81,5E,7E,FF,8E,0A,92,EA,6E,9D,B1,80,2B,72,A2,92,62,00,80,9A,CD,9D,81,4E,90,C6,45,CB,B7,A0,B5,BD,8A,D1,80,A1,4A,9A,8D,D5,3E,A6,30,61,35,2C,83,1B,22,B6,37,91,A1,64,4C,17,F9,4B,01,46,14,8D,AF,A7,6C,8D,EF,B9,CF,E5,BE,F2,10,F1,DD,A9,8D,63,DB,6E,45,86,66,46,38,93,9A,B7,20,36,AA,8A,B1,34,20,0A,7C,47,42,E9,79,AF,FF,52,92,13,4E,60,98,9F,42,37,E5,97,DA,F7,CB,81,A1,6E,7A,91,D4,78,12,CB,89,C7,F6,74,4F,E2,10,8D,97,15,03,49,0A,0B,78,42,4B,3D,C4,7F,09,1F,D3,5B,8C,57,C9,E1,AD,BE,EE,57,09,1F,08,79,74,F9,55,CB,FA,AA,F1,4F,CE,A6,59,DA,C3,D7,66,57,AE,ED,50,5E,15,D3,C6,EE,B1,49,B3,EA,28,DB,4D,47,54,1C,C5,D6,8E,5C,D6,D1,BC,54,87,23,2C,A6,D9,C0,F1,57,8D,78,E3,1E,1C,2A,74,82,61,DA,B1,64,39,BA,FF,85,50,4F,78,DA,DC,4A,32,B4,60,D2,DD,0A,9A,2B,1E,27,D8,1E,4B,5B,A5,34,41,9C,DA,94,99,CE,FB,7C,83,80,D4,EA,8B,0F,04,76,C8,70,65,04,7C,D2,C5,67,8B,6C,30,C3,56,4F,45,3C,5F,08,96,E6,C2,CD,1F,F8,C2,FA,A7,48,F5,0B,44,5F,AE,3A,7F,CA,DC,1A,D9,A6,B4,7E,12,06,2F,28,7C,FE,FA,C0,6C,0E,2C,48,A0,71,B2,1A,F6,24,AF,10,8B,37,ED,26,9B,76,FB,52,7B,33,C2,82,DC,29,07,69,D9,86,B9,7F,B8,1C,1B,33,F9,7F,3D,24,88,AC,9E,E0,B2,13,3A,5E,BF,E9,8C,FB,50,41,5C,A3,94,EE,85,7D,21,63,BF,28,04,31,82,DE,7E,93,A6,4A,70,23,EF,EB,D4,5E,72,8C,28,EA,27,8C,4A,C7,6E,25,1E,78,98,FA,12,9C,C0,53,45,0E,EA,3E,F5,67,58,5F,80,27,FA,BE,D5,2A,B6,19,BD,D3,C6,7D,2C,F1,E8,C7,E3,F7,1A,C0,8E,88,30,F5,52,80,06,A5,BF,1C,DB,F6,9B,69,33,6E,5C,02,8D,11,75,12,5E,E7,41,29,7F,95,5E,C1,51,DB,7B,1D,F8,B6,BC,AE,85,EE,68,D1,AA,17,32,9D,C6,79,FE,E3,BF,41,A1,B0,26,A8,B6,84,BA,C2,57,3B,72,CB,87,E2,7F,60,46,88,9F,4F,0B,E5,41,74,D5,E5,37,9D,24,74,CB,C7,9D,A7,9E,1E,D3,0F,2A,8E,43,84,8E,FA,CE,83,A0,7E,28,7A,C4,C9,01,25,4C,6B,AF,31,0D,0E,74,F6,7D,C5,0C,4D,A6,B5,C2,21,26,2D,9A,DD,13,B7,39,EE,6C,80,45,CC,1B,02,60,C6,77,9C,2C,EC,12,81,A8,6B,A5,3C,95,22,DB,2F,F8,E8,DB,5C,9B,52,40,A2,14,5A,E4,D8,71,14,C9,7B,F8,6C,5A,73,16,04,32,06,A9,6D,55,54,69,6F,0C,D3,E5,F2,91,5A,50,FC,ED,13,72,95,9C,C7,0C,8D,DD,9F,60,56,D7,A2,1D,1A,B5,06,36,A8,91,C5,C4,50,99,35,CC,D4,32,4B,13,76,12,0B,E2,A5,77,D0,C8,41,78,52,E2,34,8E,77,EA,4C,73,21,73,0E,07,70,43,13,03,2D,BD,E6,F4,22,5B,64,FA,6F,4D,53,11,C8,17,05,B3,5E,FB,4A,5E,7C,E0,BE,42,CF,1E,8B,1B,D8,97,A6,63,AE,97,1C,97,6F,43,03,C4,48,DD,14,08,36,3F,B6,4F,11,78,CE,1E,1E,4E,ED,3E,6F,6C,9F,AF,35,97,86,54,20,A5,C7,75,1E,22,6A,80,EE,6A,73,B3,D6,2E,90,7E,BF,E2,0A,36,91,34,14,C1,37,67,AF,8F,3B,9B,01,F7,E5,FE,4B,B3,BA,70,63,93,ED,02,95,39,78,53,25,95,4C,5F,BE,BF,5C,B2,AF,36,85,BF,6E,76,13,5A,8A,C7,E0,8F,86,58,E8,5A,18,73,2D,44,1C,46,0E,E4,5E,B9,2D,77,F1,AB,00,B6,2B,13,53,B5,40,7A,46,9E,1B,EB,77,C1,55,31,3D,B3,9C,D4,9B,1C,5A,4C,05,54,D2,53,89,7C,60,F0,2E,4B,57,8A,E2,F4,E9,09,E7,2D,E1,1F,3B,04,49,86,A5,40,81,1C,22,03,88,9B,BD,45,D3,68,E7,DA,F8,8B,94,F4,08,AC,39,9D,D0,BA,48,2D,BB,6D,F2,FA,C9,1A,39,C0,00,77,60,2C,91,74,B0,F7,66,EB,B9,BC,16,D8,37,BE,4F,64,74,A3,B0,01,F9,B8,EF,8B,48,36,C0,68,61,20,02,9E,58,10,C3,82,64,5E,BA,EE,0E,F5,0E,74,E6,70,C3,5F,B1,D0,06,95,4D,D1,3A,0B,0D,32,D7,56,5F,58,C5,9A,8E,F6,B7,76,2A,3F,DE,9D,61,C0,2B,A5,60,58,B8,5D,2F,2D,13,FE,A8,A0,E8,5A,90,7D,A6,97,A7,DA,F5,A6,40,73,69,89,D6,D0,C1,BE,6A,2D,32,93,2A,2E,4F,4F,A3,EF,AC,38,93,8C,05,4F,B6,DE,AD,DD,DD,9B,6B,4C,FE,CE,88,FD,DD,AA,98,68,22,D3,8B,34,41,90,BC,88,10,4D,FF,13,31,E5,E5,0D,7A,E4,01,D1,6E,8E,E5,64,1D,E0,D1,48,8C,20,40,CE,0B,3B,6C,F6,D4,17,59,C5,47,73,76,B7,5A,DA,A6,2E,93,A3,02,DD,D5,7A,BA,43,FF,C7,6B,46,5A,FC,B0,31,67,08,C6,AB,F4,9F,49,4E,D6,57,03,C1,3D,90,77,97,D4,2C,07,B1,6E,D8,B7,BA,5F,0F,1F,5E,B3,61,31,B4,88,8C,6C,EC,13,B0,CA,10,C6,13,37,23,8C,CF,30,CE,C2,C1,E3,CC,E6,87,83,CB,8B,22,1B,10,38,18,A8,33,A9,1C,F9,FD,79,76,8A,41,EF,36,DE,6E,71,5E,AA,A7,CD,0C,EF,77,CF,16,07,A5,10,1F,5D,0F,A9,44,BB,5D,B9,BA,E5,CA,80,53,D3,60,2A,F1,60,29,AE,EE,FE,4F,E5,A4,57,AD,3C,B1,86,BA,8C,7D,F9,9B,C3,F5,5B,A8,AC,BE,82,88,92,F7,EA,57,C2,26,C4,23,F5,6B,B8,2E,9A,24,24,1A,C9,ED,30,EE,AB,8B,6C,F9,89,FD,6F,D8,1A,64,8F,DD,4F,AC,DA,36,F5,46,2D,1B,2E,AE,DA,B1,EB,DF,87,B9,FE,BD,C9,D3,F2,3C,F6,C4,07,1C,75,22,D7,78,EB,61,6B,95,7B,E3,A6,5E,D7,49,28,D0,2D,48,CD,17,A4,FB,4B,2B,3F,95,3A,0E,39,DD,B8,61,2F,4F,A3,D3,44,69,8C,3F,59,AB,7E,E4,DA,BE,62,9C,2E,83,3C,D2,5E,31,26,1F,0A,83,04,15,C1,7C,09,9A,8C,1C,96,AF,72,21,B8,D5,9B,9B,60,89,3D,F4,16,57,27,B6,AD,18,43,0E,F2,DA,35,99,93,72,1F,2C,11,55,44,98,62,E8,F9,85,4B,80,8D,BE,89,23,23,39,53,31,24,40,AB,16,E5,82,6F,2B,9D,89,43,C2,4A,74,D0,B1,D3,CD,48,BF,51,94,17,72,D1,4D,60,67,1A,3F,EE,AA,E9,8F,69,7D,00,03,F4,90,8F,9C,86,00,EA,EA,8C,75,0D,F8,D7,CE,96,71,F4,77,EE,22,73,4D,86,66,6A,83,EB,F0,B6,62,45,52,40,E4,4C,83,03,5E,2F,F0,F9,F5,EE,39,1D,6C,C7,68,CC,1F,F5,06,5B,F4,49,BF,1D,76,58,AE,FF,CA,55,BE,4D,E8,A5,B7,93,CF,F2,E6,F1,90,35,5D,C8,79,D9,86,E5,81,A5,94,CF,77,4D,E6,AF,B5,B8,8E,9C,7D,D5,15,DA,BE,5A,85,72,60,7D,1F,6D,78,60,A8,C3,D8,F1,00,ED,14,4E,97,D9,6C,44,EB,45,3C,32,12,A8,DC,62,F9,80,F9,7F,A4,5F,34,5A,0C,C4,6C,47,97,7A,22,76,FA,8E,74,45,5F,1B,48,74,9A,03,12,E8,02,D4,28,B6,59,32,31,34,BD,A9,C3,97,94,2F,F1,77,C5,4B,2B,63,84,B2,4E,79,78,7D,F6,4D,B3,C6,BE,7B,D7,D9,F8,F5,E8,53,70,4D,FE,56,32,2C,39,E3,0B,58,C0,0E,EE,06,AD,AB,FC,16,1B,BA,43,70,BC,92,57,56,38,E9,9F,0B,6D,92,88,3B,63,6A,09,21,BC,00,D9,5A,9E,29,09,BD,F3,2D,D3,60,33,0F,77,47,D5,AB,10,1E,DD,9A,19,0A,05,B1,6A,19,5C,41,B9,EE,09,AA,53,9E,D9,2F,55,33,42,10,EB,93,E7,EF,C7,CF,92,08,E4,47,70,94,BE,F2,F9,DE,FB,01,01,90,68,C6,B1,9C,7F,BA,8D,8F,8A,22,67,81,72,FD,01,BD,95,AE,8D,B8,A2,C6,06,75,1C,E2,DF,53,61,1F,51,24,54,A3,EE,7F,77,B0,67,06,26,3B,BF,CA,40,E9,35,63,46,07,F9,4B,1E,96,D9,A4,FC,C2,F3,8C,B6,74,18,81,40,66,B8,D4,1F,27,87,26,FA,ED,E7,EB,3F,DC,33,C2,0E,92,3F,CB,5B,1D,AD,16,A5,7F,05,FC,DF,EC,C5,A4,97,9C,83,17,C9,13,4F,3B,34,48,86,39,6C,15,73,DD,20,DD,A7,36,6B,95,99,12,B7,57,72,FA,BB,96,BA,E0,7B,27,08,47,5A,1F,87,FA,C2,5A,FE,0C,8C,05,5E,8E,9E,7D,5C,BD,01,A2,1C,23,BB,D2,7E,3C,E9,8A,B7,1E,49,BA,96,E5,84,0C,12,99,22,56,DC,61,DA,25,DD,30,69,0F,B8,31,2E,32,F5,5E,B5,EB,D7,FF,9B,C9,DC,2E,D1,1E,D4,BD,26,F6,D3,09,D4,C6,E9,47,7F,B8,39,90,16,82,90,F7,27,40,CC,85,15,94,03,E8,CD,45,05,2D,87,60,DC,51,21,99,23,E6,F6,5A,92,1E,21,E6,A9,DB,1D,01,06,19,12,E6,74,EA,FB,7E,BA,79,C0,71,3B,83,2A,51,D6,5D,E6,E7,8D,8E,12,99,DD,C9,56,57,C6,18,46,E8,46,B5,F2,FC,33,60,D4,B5,F3,B4,F8,E5,EC,8B,0F,E5,6A,2B,DE,56,67,82,2F,9A,45,51,2A,19,D2,14,0E,E3,23,0F,3B,3F,AB,29,C8,BB,A4,16,98,28,BA,32,37,37,D1,58,C3,10,55,C4,49,52,27,0F,08,B0,1F,B8,D6,A4,13,D1,E2,78,A3,3E,11,F0,FD,FD,87,C2,7C,6E,67,96,FA,0F,EC,A6,DE,C9,01,45,1B,68,29,D5,2A,53,C4,BA,D2,97,02,F1,79,BC,50,70,24,8C,07,64,47,A0,46,C1,45,81,CD,45,95,B3,B3,83,6C,C2,71,9D,D4,A3,83,EB,9C,02,5A,3B,0F,1A,92,B1,54,24,A5,00,D3,E2,55,61,6C,F2,E8,3B,9C,4F,06,64,C8,BA,68,18,FB,1C,70,2F,81,1B,BC,A3,31,3F,FE,32,C8,7B,39,78,28,EB,6C,71,F0,56,68,DB,C2,C9,AF,27,44,53,67,FC,A6,62,15,72,44,50,FA,D7,24,BA,FD,8E,7E,0B,D5,8B,D3,FB,C9,E1,8B,68,9E,20,6A,C2,45,FB,1F,74,12,D6,D0,94,C5,D6,87,3D,AA,B1,2E,50,F1,0C,7D,76,68,B5,46,12,AA,98,43,0A,F1,6E,B7,47,8F,C5,67,BE,C8,99,52,C4,6F,E2,4B,30,03,DE,D1,A6,1B,A8,5C,E1,45,72,5A,09,86,3C,4A,90,CC,7E,49,C4,E3,8D,DB,05,BD,07,04,96,BF,F1,54,24,AC,9E,BA,F4,FD,51,3F,9A,22,F2,21,A1,FA,CA,1E,AE,2B,D6,E5,2D,70,A1,5C,7D,67,07,FB,D4,CB,43,61,61,D8,3E,13,B3,64,10,11,71,58,1B,A5,C4,3F,9C,9E,F8,33,45,7A,62,8F,67,FB,C1,17,51,F2,F9,F8,01,0F,AA,11,A3,F7,7A,72,39,93,AE,B8,10,CC,2C,16,D9,50,BA,0F,DA,95,E6,EA,A9,8B,30,2F,D4,CF,07,FA,16,5C,B6,46,9F,F0,4D,14,93,17,A7,89,9B,03,BC,B4,E4,62,B9,75,B9,8D,B4,E6,12,9C,B7,83,2A,8D,90,BB,15,BD,2C,D4,27,8A,5B,FC,2A,2E,D9,2C,8C,5C,74,0D,B0,1B,13,6A,F7,F2,23,DD,A8,EF,18,8E,D1,2D,98,C0,A4,50,13,60,DF,FD,21,48,6A,7B,45,AE,5B,F9,18,90,E9,C1,CE,2C,18,1B,FB,F8,C0,D8,0C,6C,7D,48,7B,17,B3,52,EA,04,4E,4C,C9,CB,4F,2C,B5,E2,7E,8F,78,92,09,51,56,81,96,1A,5B,94,F2,E0,64,32,A6,95,01,8D,DD,88,7A,EE,C3,59,23,D6,95,51,D8,AD,29,71,08,EE,A3,D1,EF,A0,45,0C,7A,0D,81,90,93,AB,AE,86,F3,DF,B7,BC,1A,F4,57,A0,E4,93,EF,28,26,CE,E1,D8,46,EA,10,7A,30,BE,58,19,4E,BD,2D,40,78,E3,EE,1F,44,8C,C3,B1,ED,9F,B9,73,11,D7,61,9B,EE,61,59,51,55,20,02,22,B3,75,6C,C5,2D,DA,99,BF,41,8E,12,E0,8A,E8,D7,E1,AF,78,D3,95,83,FA,E8,DA,11,92,BF,26,E2,E4,37,3D,9D,BF,5E,61,38,38,EC,DB,55,CF,95,8A,F0,90,50,92,C3,51,FE,B5,3F,52,22,D2,53,85,7D,72,12,89,BD,F4,7F,D6,8A,D0,C2,FF,D6,44,7B,50,47,94,92,EC,D7,05,7D,B2,CF,2F,53,93,9B,BF,0F,C2,EA,B9,90,95,8F,7A,2D,E2,40,20,21,1B,43,D9,27,55,C9,3C,F3,C6,52,F5,5A,96,CE,13,DF,93,17,0E,D8,06,44,E0,8E,3E,7B,EE,E8,60,E4,C3,70,72,B4,75,C5,25,64,37,B2,9F,54,6D,82,F9,20,01,2B,BB,42,85,03,F9,0C,07,F1,71,8D,82,E3,55,FC,5C,9B,A5,7B,D7,BA,88,F2,86,11,56,2E,A9,11,27,F0,1B,D4,EC,B7,59,D5,B5,2C,34,04,25,6E,E5,71,19,3F,6D,DE,62,19,8D,93,A8,B3,17,C9,C9,B1,27,53,72,44,88,BD,53,70,75,EA,28,4D,D9,32,E2,9C,E9,C4,68,7A,FF,16,F3,C8,2D,49,3B,85,AA,1C,9C,99,69,33,59,2A,19,AD,FC,72,41,7A,20,D5,A8,C5,05,A1,CE,19,BD,31,2A,F2,64,D1,FF,1F,71,24,EB,F1,E5,C3,8F,74,19,60,EF,7C,EF,21,2D,5B,44,52,7F,F4,0E,07,77,85,99,64,0A,DA,F5,A2,F3,84,63,8A,3D,CE,05,1F,07,18,AE,AB,9A,B1,F4,4A,1A,86,FC,3A,C7,AA,30,07,EA,1F,3A,FC,65,C2,9C,28,A3,D0,CE,8F,E1,9F,2E,1F,5A,F6,AD,9E,44,C8,CC,49,FA,A4,16,A3,F2,36,3F,2E,9B,64,08,05,8D,6C,E4,F7,F7,FF,EA,45,20,EC,F4,F2,D9,5A,61,42,5D,3E,56,F9,AD,ED,43,93,1A,02,FF,C3,BC,64,2A,F5,F2,3D,F0,E9,CE,15,50,AF,74,03,E2,AA,89,68,F2,F9,00,EB,D0,5E,DD,BE,14,3C,50,11,00,74,5C,3B,5A,B1,3A,EF,77,73,74,CA,E0,51,1F,9D,FB,56,B4,51,34,CB,91,0F,BF,42,2E,28,48,A7,5A,BB,8F,43,37,31,F3,1A,5E,5A,C6,FE,00,28,1A,EC,78,D8,FC,90,AD,4F,3E,FE,C9,3D,CA,68,06,65,31,74,31,A0,14,4E,17,EC,D9,BD,40,49,97,AE,26,0D,DB,2A,3E,84,F3,32,92,FD,F7,1F,C6,ED,38,F1,6A,BB,BB,98,89,2D,66,70,EA,69,D7,12,E2,47,41,CE,77,3E,CB,06,71,44,19,E6,84,6C,CF,A8,51,5E,56,F8,99,8A,7B,FE,AA,03,F5,36,DF,DC,B8,62,B8,73,B7,B5,E8,11,21,BF,12,76,E3,C9,81,B3,3C,72,3C,5E,F3,3A,B4,F1,30,71,7E,8C,17,43,67,9B,6D,43,07,49,E3,EA,CB,BD,D3,91,2F,6F,EC,5E,FE,4E,AA,01,6D,06,E1,8C,79,82,0F,2B,75,54,60,31,B2,9D,3A,E8,A3,62,03,EF,BF,76,53,6B,97,32,B2,DD,16,42,1E,9C,EC,FF,C8,FC,8D,F7,4D,DA,71,E1,9F,D2,82,F6,D2,33,48,14,67,B9,D9,B0,65,E6,CD,76,C3,5F,01,05,08,27,14,41,E2,5C,84,02,8C,37,D1,58,62,79,DD,E9,91,D5,10,B4,0A,5B,F4,CB,72,E0,41,DA,3E,19,A2,3E,8F,B7,06,15,8A,9D,71,18,01,5E,13,D4,0B,07,D4,7E,A3,91,B2,4B,30,8D,EE,95,B5,B0,D3,C4,49,46,E6,36,B9,D8,88,71,4A,2E,16,91,87,1B,7C,43,54,F6,26,1B,F4,71,DF,89,A6,C9,12,F4,96,D8,48,F2,5F,62,09,42,F8,C0,D6,23,20,60,FC,D4,09,E3,EA,D7,E8,B3,73,4A,65,30,2E,F3,7D,79,69,74,96,12,96,35,6D,D3,1C,2C,0B,16,E2,E2,27,70,82,F9,32,78,5F,DF,94,06,15,3A,F4,A3,B3,39,DD,6A,9D,E2,F3,FB,A8,8A,22,7D,B3,D8,C1,14,44,E4,17,3C,18,95,3C,60,5A,A7,9A,D0,DC,0F,15,C7,CF,2F,C9,BE,7C,00,AE,88,5A,98,DA,CC,AC,03,CA,5E,FC,D5,89,D1,4C,0A,41,B6,02,65,7E,98,80,3C,FC,18,8A,F2,0E,41,15,68,08,79,5E,CC,65,47,DD,7D,83,10,F6,1D,34,C8,45,8F,A4,38,77,22,B7,EE,01,3B,1C,C2,FD,E6,90,C9,11,CB,7B,0D,C9,E0,CC,A8,06,BA,AD,6C,7F,FE,C5,AD,F5,2A,66,A2,5C,EA,FB,C6,91,98,9C,45,43,46,79,F5,09,1C,A1,25,13,4C,42,F6,68,8C,CD,A3,74,5D,D7,13,D2,D6,52,2A,85,90,C9,94,BA,35,EE,26,29,CB,32,81,F7,98,BF,EA,E2,11,EF,BD,E9,C1,B0,A2,13,42,0E,C7,14,89,CD,FE,C4,DD,10,BA,83,5D,DF,3B,B7,C2,AC,3C,C4,D3,74,E0,99,5E,CB,EA,C0,1B,0F,65,50,1A,EB,F9,19,57,68,5A,A1,8B,88,82,A7,1D,0E,7D,85,63,95,D7,05,55,69,C1,2E,E8,25,00,5E,67,26,CC,C1,AD,E2,8E,D9,F1,4A,A9,18,A0,BE,BA,4C,12,B9,08,61,96,9F,3C,7A,A2,CC,C9,43,67,E3,E3,7A,CA,1E,84,8D,C6,36,DD,AC,04,83,C2,FD,8D,E3,31,FF,38,F1,B5,D5,BA,58,11,F4,11,18,F4,83,08,F1,5F,CA,2F,6C,D7,AA,FE,26,F4,6F,C3,4B,CE,ED,72,35,B7,65,C3,21,9B,1F,F6,B5,78,59,1D,C0,E2,53,E5,88,C7,FF,F4,4D,45,88,98,FC,4B,2B,CB,53,09,33,65,A6,7F,B8,FE,AE,A6,26,CD,D7,6F,AB,15,83,61,B5,8F,71,77,83,16,35,A5,09,83,2F,CD,CD,43,1C,CA,E4,D4,BA,1A,53,53,C2,CA,F9,ED,3C,08,66,8F,3B,2A,2A,B1,E3,A1,30,6D,0A,A5,51,78,25,17,FD,67,0F,A9,3D,A3,66,1C,11,AD,6F,82,69,A3,A3,B3,A1,FD,4B,F9,9F,63,81,E6,B9,AC,73,E9,88,76,3A,2E,C8,B1,DF,DB,9F,B7,5A,DF,F3,47,66,42,6A,A7,40,9E,FE,8D,65,58,B6,1A,AC,66,0A,E2,62,4D,8E,20,B3,7E,B1,87,59,D8,F9,96,94,D1,5E,0B,90,9C,C6,F9,DC,18,E2,0B,E2,95,FA,BC,00,E0,C7,54,3F,A2,D1,56,E4,0C,51,B3,A9,32,9C,35,CA,52,A2,58,C8,49,9E,C8,A0,C1,B5,F4,8C,FF,9F,20,C6,89,A3,61,7A,DB,49,23,86,CC,C4,71,1C,BA,27,8E,48,A5,06,31,ED,61,0E,22,2D,23,3F,7F,2F,9F,E5,E6,EC,BB,46,47,5F,BB,DB,45,C3,43,0B,86,80,82,AF,89,CB,26,43,2B,D2,8F,06,CA,35,55,95,D1,3C,E3,96,B4,35,6E,AA,28,E1,59,F4,6F,FF,F8,63,FF,C6,0C,8F,52,08,32,30,E0,B3,35,06,8A,66,A4,9C,D1,61,20,6D,30,6A,BF,13,B2,1C,DE,6E,3B,73,DA,84,9E,A7,0B,E3,C7,3A,60,6B,15,6B,90,13,92,36,F0,07,FE,9D,FB,BD,10,46,4B,76,AE,C8,AE,62,2C,9D,BF,79,8F,53,03,F1,86,1F,07,AB,26,A5,C8,33,44,DB,35,03,37,29,E4,68,17,7C,C8,F4,25,8A,E2,90,79,5C,B9,59,AB,A2,9F,32,53,09,1E,F2,AB,4D,0C,3A,4F,13,12,10,13,C3,E5,84,7B,4B,72,68,46,75,B3,A4,46,C2,C3,4C,2F,EB,EE,23,5A,9B,F4,A5,67,8D,C8,06,FA,CE,A5,30,2C,25,75,FD,4A,EE,5E,81,B3,31,28,AD,A4,F0,3D,44,23,1A,0E,DD,C7,65,30,A8,5A,A7,D8,15,25,D8,24,59,A5,31,D8,EA,91,8B,82,94,1A,B7,51,01,65,73,89,71,5E,6B,C5,AD,4B,0A,51,EC,DE,0D,CA,06,E8,F0,A8,3C,2F,12,B8,07,F8,63,FE,1B,72,3F,1D,59,CB,CA,B1,33,01,72,C1,9E,F0,1E,44,85,12,8F,E4,11,CA,AE,79,9A,F7,5D,AD,C2,56,AA,77,8B,D5,91,6A,F4,36,99,82,6B,55,17,03,72,F3,44,D7,CC,0C,8E,99,3C,63,FA,AE,68,B5,51,1E,15,90,9A,3D,9C,21,D4,F0,59,BB,62,F5,5C,29,F0,D8,05,54,BA,C9,EA,6A,75,DD,60,C2,A1,5C,60,4C,BE,9A,3E,27,81,14,F7,0D,4F,9B,70,B2,4D,FA,D5,47,70,51,6F,80,0B,20,E4,82,92,9C,72,6C,28,0B,EF,88,48,C6,0F,2B,2D,D4,F5,8E,B0,15,52,7D,12,4B,AF,BF,F0,DA,01,A2,B9,8E,09,5B,6B,CE,5F,27,58,3D,19,CA,41,90,B8,9B,1F,85,D0,0A,06,71,19,53,3F,73,86,B4,72,EA,F1,A8,54,2B,8F,A7,76,5B,9B,91,50,87,8C,12,56,8A,D9,07,FE,A9,3F,35,75,68,8A,CE,22,29,42,CF,73,C4,ED,8D,F6,C6,6E,07,83,2B,D9,05,F3,6A,44,1F,B3,D6,80,62,BD,50,6D,CF,FD,09,9E,B0,E0,F1,88,1E,70,B4,04,C7,39,D4,49,AE,67,F9,54,2E,77,62,1D,4D,7F,CB,E2,16,D2,73,6C,60,C1,BA,6F,98,03,93,96,39,8D,B8,1D,5D,BD,27,B9,E0,13,A9,38,93,F0,C1,B5,5C,31,BE,4B,B0,38,01,78,5E,45,46,C6,74,42,80,F0,FC,F2,8F,89,00,CD,54,20,0E,44,4F,B3,53,2F,C8,E1,B8,B4,67,F6,64,65,86,7B,E9,A8,77,27,AA,4D,00,04,C7,55,9E,AF,6A,04,B3,F8,60,A5,38,28,E1,29,40,D6,9F,BE,60,0E,49,90,D3,C0,FB,AA,91,48,E3,64,CB,4E,81,AE,D2,63,EB,95,D3,1C,3A,7B,67,43,03,32,84,A1,F4,EE,A0,F3,34,63,80,BD,41,94,49,F3,93,0A,0B,E5,31,4F,05,D1,46,92,C3,A3,7C,83,F9,D0,E2,56,6D,0A,B8,10,A9,90,7E,E2,E4,CC,78,BA,B1,61,2B,ED,FA,FA,FC,8B,53,90,F5,BE,9E,54,43,8F,D3,DC,CA,16,47,B8,EB,28,AD,1A,17,DF,9E,DE,AE,D3,25,62,26,33,45,26,14,B5,68,08,58,65,4F,D9,D2,76,CB,7D,33,93,A6,BA,AD,B6,26,94,B7,F3,09,51,9E,6E,C9,EE,BA,30,86,88,2D,89,33,F6,F1,9A,C9,44,DA,84,A2,28,48,86,90,2A,6B,26,91,05,C7,C9,33,0B,6A,EF,CF,B3,6B,EF,22,11,74,1B,91,6A,8B,B7,28,A3,3E,A2,90,E2,B1,F1,D9,CB,52,01,40,92,46,1A,66,F7,FA,DA,D1,FD,61,62,50,A6,71,D5,39,EF,BB,DD,11,E3,6F,FC,30,F8,17,5E,50,35,A1,79,0C,8A,9E,FF,0A,AA,18,B5,EF,5F,AE,45,86,D6,74,28,22,3D,7E,C2,91,C3,C3,9C,3D,08,68,64,29,79,0D,B3,79,B1,A9,AD,D4,65,EF,3C,F8,50,33,3C,80,84,2A,A1,5D,3B,D3,64,7D,86,B4,55,20,60,64,C7,73,3F,02,C4,DF,89,59,D0,DE,F6,D5,A3,F7,21,84,06,56,4A,F3,86,49,E2,D6,7E,3C,15,97,D6,19,CA,B3,DA,31,55,37,80,CD,D3,FA,E0,44,CC,B2,9F,49,8A,DE,04,7D,D0,34,36,FF,02,D8,01,40,08,16,77,87,BB,70,28,6C,A8,90,43,F3,57,76,DF,9A,B3,C4,57,D8,DF,5E,6B,61,A3,CD,97,F0,51,B6,F6,E8,5E,99,BB,84,85,EB,78,59,90,BD,08,B6,1D,23,07,89,AD,D9,66,A6,B3,97,53,23,F8,35,F8,D1,2C,EF,EA,DB,F8,ED,C2,64,61,3B,C8,F4,B7,33,BF,23,36,03,E0,6F,6C,51,2F,10,A2,43,73,8A,55,11,69,E9,7F,61,66,19,F3,9B,AF,7B,BD,A9,45,05,2E,09,A3,0B,6C,F1,28,97,03,C6,97,6F,9B,A4,2B,02,49,8C,77,33,96,F2,AE,7C,FE,EF,A1,8C,FF,B9,84,E2,E3,E1,A0,38,63,73,FC,4C,BF,40,BB,61,D3,17,24,6F,64,9D,F3,4F,E2,DD,DA,4C,30,56,B3,61,18,7D,9A,15,23,B5,94,76,DE,59,C3,AE,6A,0A,AD,EF,04,C6,98,C4,26,09,E6,1F,4D,D0,D3,BF,0E,8D,AE,3C,1A,3D,5B,35,22,9C,D5,AC,1A,5B,DA,8E,4A,37,CA,CC,BF,D7,7F,EA,5E,2B,24,2E,00,C2,4E,51,2E,39,30,46,66,17,D2,DF,74,C6,DE,92,14,75,41,9B,7A,EF,52,BD,39,66,97,99,09,F3,0C,5A,81,8D,92,0F,46,20,C4,65,96,47,9B,53,CD,25,66,87,14,59,C5,CB,A1,1D,81,17,80,25,43,A9,5A,BA,34,CF,AE,34,CA,87,9B,4A,94,88,17,50,84,2C,48,7B,24,62,56,88,5D,4B,04,74,0B,B7,B7,A9,03,A0,46,AC,24,E7,3D,6A,F7,7E,7F,97,A3,15,DF,C1,0E,AF,F9,5E,72,38,0C,13,F5,65,EE,55,5E,A7,F0,01,02,9B,C8,56,04,BD,0C,CF,48,7D,12,BD,B9,AB,58,28,C2,3B,89,22,DA,C8,11,DC,41,51,BB,4B,13,C8,CB,33,D6,68,60,24,EF,2B,2C,B3,4D,58,D8,A6,76,29,65,20,AB,14,BF,C6,C8,BD,0C,41,44,39,CC,49,9D,0A,14,7C,71,F4,99,B5,EF,00,D0,62,A4,91,0A,F0,3F,3C,E5,3B,1C,06,17,79,FC,E0,8B,7E,2E,B3,A4,EB,B0,9E,50,7C,5E,E6,F0,F4,AA,CD,91,3F,27,55,49,68,E1,24,C1,08,3C,26,99,3C,91,F8,0C,84,45,31,4F,41,80,60,18,EA,C2,8F,F4,8B,0F,1C,FF,D8,DC,15,FE,96,C1,6A,19,D3,86,D7,1A,D5,E6,0C,0B,B7,03,DE,60,0B,E0,42,7D,74,22,A9,60,E8,53,84,1E,87,6B,87,BA,4E,63,E9,07,99,98,8D,64,A0,83,D1,7F,8D,54,4F,36,24,86,CB,FC,9C,96,3A,FF,29,24,D4,5E,58,B1,07,C9,DF,9D,2E,6C,40,31,42,66,C0,0F,F5,51,E3,57,E8,A2,0F,73,B2,DF,F3,A4,0B,76,A6,84,81,47,F5,69,CC,7B,EB,D5,6D,2A,D8,0D,D4,1A,7B,E0,56,C6,68,27,E1,05,EE,6B,77,90,C2,8B,5C,D5,10,C5,6E,70,D4,21,96,08,DD,08,D2,6C,89,B8,BC,75,D0,BC,78,7F,9C,66,59,34,16,90,6A,A6,59,21,97,F2,89,F0,58,8C,E1,9C,4D,73,60,95,70,1F,A9,52,B5,1E,53,4E,3F,03,BA,9B,E9,84,09,D3,9F,45,7B,D9,86,25,3E,25,CC,F0,C2,B6,C1,E5,19,2F,9A,DF,A7,71,EE,24,F8,36,07,FD,67,30,55,14,8D,D3,11,3D,75,B2,50,69,EE,44,6F,D9,C7,BE,7D,4B,27,AC,D2,A1,97,DB,17,4C,5F,E1,91,B8,3E,A7,BE,67,CA,0D,33,2E,10,85,30,6C,9D,83,D6,4E,77,35,AC,BD,77,18,D1,1E,2C,49,73,FF,DD,79,C7,CF,27,00,3C,11,45,13,16,22,FD,49,EA,DD,3C,FB,24,3F,74,44,94,A6,2A,5C,7C,0F,E0,0F,C7,D4,A0,45,0E,33,3B,6C,A0,7F,C6,7D,7B,2A,F7,58,C3,70,80,85,39,A4,E1,DE,52,94,D3,FF,7A,F1,A8,24,76,DF,90,C0,D4,F1,13,F9,95,B8,59,9E,C6,C6,98,EA,F2,AE,C4,F4,BE,F6,9C,FE,C6,71,FB,74,2B,D9,59,0E,A7,B0,A8,BF,0E,42,7B,72,B8,2D,AE,EE,38,70,24,5F,8D,C4,68,CA,14,4B,65,0B,41,69,44,16,B1,86,FA,D9,F5,BB,83,01,12,1B,22,A2,E5,5E,12,42,63,FB,06,98,64,76,97,B0,58,4F,E4,58,03,FB,FB,9F,3A,93,DB,4F,02,69,58,17,70,C4,CF,18,9E,15,E7,18,2E,E1,1E,8B,4A,1F,06,E5,DD,B1,CB,0C,DB,62,6D,6A,47,1D,C6,3E,58,50,C9,DE,82,A9,D9,40,39,F3,90,74,3B,41,FF,DD,42,99,48,9E,8B,F0,42,15,7F,89,D3,86,5A,25,DE,6B,60,71,24,B6,BA,64,18,B3,B9,53,D5,90,BA,94,93,5B,DF,BA,35,09,79,D7,0C,49,0E,80,BD,ED,70,4E,F3,C5,12,0F,12,CC,90,4C,F4,70,19,9D,19,19,B6,D9,6D,EA,9E,BE,63,3C,16,2F,9B,CE,87,07,8B,56,47,BC,F8,00,66,E4,BA,7F,A8,7A,D5,A0,2C,AD,BA,A1,C5,47,87,38,20,AC,B8,B3,05,BF,2E,19,C5,B2,C1,84,A2,4A,1C,8A,0F,C2,7C,B5,83,0C,22,CD,93,92,B4,A9,0F,22,EE,33,7C,78,54,BE,CB,43,8F,1F,86,90,27,3F,81,E0,B2,B8,08,BD,DD,BF,31,78,8F,D5,B5,34,AE,63,0F,56,93,83,A4,60,AB,2B,42,C0,13,2D,F4,81,75,72,22,25,BA,DF,00,4E,F5,9E,A2,FA,D7,2F,53,8E,0F,FB,9A,00,83,F8,24,0A,A7,62,D6,AE,14,28,47,FA,EE,32,26,94,78,4B,54,BE,DF,D8,D7,78,C1,57,F8,C2,D8,1A,38,61,1D,9C,4D,FD,E1,17,43,12,56,F0,E9,B3,05,80,87,75,6A,E2,48,8A,11,39,7B,1B,71,C5,59,23,E1,9F,4A,57,B4,18,D7,B7,88,37,9E,23,E7,3D,43,8E,6F,79,80,3E,FE,D8,DE,F9,22,70,B2,AD,2F,4C,08,33,B8,3D,74,EA,DF,2D,CC,68,A9,AC,E1,92,18,B5,A1,76,DC,58,61,A2,50,51,AC,D3,CB,3D,0E,FB,60,C6,D3,65,63,C7,7E,DD,52,11,BB,70,C8,BB,56,B8,DF,78,6E,DC,DC,EF,E8,68,29,BF,41,73,11,46,E4,76,8A,53,0B,04,73,27,EA,40,72,ED,29,3A,16,1B,99,84,A4,2E,14,EA,C6,B9,B7,9F,88,EE,0E,AF,47,6D,F8,A3,BC,81,1B,FA,39,59,EC,A1,2E,E1,9A,B4,BC,4A,B7,3B,3F,0C,C2,FF,F7,D6,FD,53,96,97,1C,24,73,21,22,23,9D,10,42,A9,5D,49,96,73,DE,78,3A,8A,4A,9B,C0,67,62,DF,97,D1,D7,9B,4E,CF,83,EB,A5,A1,45,CF,FD,5F,B8,33,D1,83,DC,12,94,93,42,1B,92,05,4A,A6,8A,E4,FA,40,2E,A1,F6,8C,09,0B,F8,E1,87,58,DC,FA,C4,9D,1A,B1,F8,9A,3F,9C,CF,5E,36,B4,97,CC,FF,46,A4,60,F7,21,BD,03,03,7C,09,9A,BC,C6,C1,39,57,F5,02,6F,9F,10,6C,DA,38,C4,F9,3F,7A,5C,E0,42,29,1E,22,46,ED,65,A6,D4,BC,1A,D9,46,37,E5,D7,23,AE,7A,09,02,AD,DA,D2,E8,16,BE,57,4E,AB,08,EC,D1,20,B4,D8,7D,0A,57,67,8B,34,1D,54,DF,BA,0E,BE,41,BD,AF,8F,78,C6,C1,D6,31,5F,DB,A8,B1,A1,67,99,97,50,0A,E1,4C,13,EA,44,B2,59,70,BF,E3,ED,44,0F,02,08,7F,5D,40,BD,02,97,DA,5D,46,FF,E4,87,6A,49,DF,BD,7C,11,C5,E3,C6,62,07,B2,C4,CB,89,2E,90,E9,F2,EC,EE,70,35,75,5F,12,6C,55,47,62,4D,9A,06,CF,47,79,CB,07,27,B5,46,FE,EF,7E,50,40,83,F3,76,B3,8D,3F,6C,AD,87,9A,A5,56,0B,BD,46,C5,90,70,24,C1,38,C0,BC,0B,4A,5F,4E,F8,DE,0B,0F,EA,01,38,CF,32,0A,CD,4A,52,78,59,D4,C4,21,E0,6E,45,F8,35,2B,4E,FD,EA,47,73,CE,44,0D,5D,7E,98,B0,02,44,52,68,CB,41,D1,A4,F4,CC,61,44,26,FB,33,4B,95,58,11,47,18,98,06,34,72,97,2E,65,A5,78,D3,68,7D,11,B9,F3,F7,A5,D5,D9,40,68,92,92,DA,B8,2B,D3,09,E6,72,79,BA,74,8D,D0,FE,98,62,F0,BB,A5,F5,95,2E,92,26,AD,DC,A0,FD,58,FA,5C,B0,9F,FE,C4,9E,1F,C7,88,89,30,FF,52,35,DA,8C,95,22,6B,48,54,64,2C,9E,D7,66,AA,55,D4,80,CB,33,89,F1,5A,CF,A7,83,7C,E7,5E,16,73,21,C6,BE,47,6D,BA,A5,04,99,D3,77,20,C6,DA,C5,7C,A4,2E,40,BB,66,9E,D9,B4,9F,1D,80,44,0F,C3,E6,EF,F6,28,E3,C5,E7,73,C7,25,69,DE,94,49,BE,37,C7,29,13,0C,8E,9D,AA,1B,A2,90,6C,D8,AE,90,32,8A,46,AD,6A,85,78,F1,A8,48,90,7D,CA,FB,6A,26,0A,5F,4C,E9,C8,DF,6B,69,4D,59,30,91,83,E6,51,C3,10,6C,48,5E,4E,76,16,53,17,12,8A,0B,66,D2,49,BC,DD,BF,8A,64,EC,F8,74,C0,62,F4,8E,BC,4B,D2,58,5C,9E,53,7F,05,AC,3E,A1,F4,12,3D,0A,3E,62,67,A8,15,AF,B0,BF,D7,D0,DE,A8,B5,C3,80,F8,32,3F,DA,BA,6D,8D,AF,A9,70,DB,75,62,F9,24,B2,71,0F,3D,C2,44,28,34,3F,E3,C5,7C,C6,40,FB,47,C6,89,03,35,1B,D5,A1,0D,77,AC,02,1A,2A,14,67,07,5C,E6,44,97,58,5B,5C,19,98,59,B2,16,6D,50,54,61,54,4D,AE,62,F1,9F,84,65,1A,77,D7,4D,B4,C4,3F,EC,F4,56,A3,CB,30,2D,AC,76,2D,21,7E,0C,31,85,DE,45,CF,84,86,A8,02,DC,F4,FC,66,21,45,73,B4,B1,B0,9B,66,1F,64,6D,F0,24,FA,69,EE,CD,A0,CC,C3,5C,92,1D,CA,7A,B5,F2,80,DE,7F,25,F9,8B,86,14,AD,E8,47,6C,F4,2A,07,4C,CA,1E,91,D2,6B,D1,14,F5,CD,E1,A8,E1,8E,E3,8A,66,1D,FA,65,EA,A0,EF,D6,E9,16,DE,36,8B,03,2C,CF,B1,BA,8C,05,53,67,07,C2,8E,C2,25,1A,14,65,4E,CE,9D,3A,0D,7A,86,56,6B,33,E9,03,F6,F4,E5,B1,62,74,3C,86,6C,AF,46,CB,E7,99,4C,17,FE,7C,C8,FE,F2,03,60,8E,FC,8D,F6,66,2E,94,16,90,74,A3,C9,DF,EB,8A,21,B3,1B,A4,23,93,EE,DC,7B,C0,23,18,5E,9C,CC,B7,55,62,C2,49,27,35,7F,36,7F,6A,CE,33,35,40,B6,97,D6,51,A5,2D,7D,F0,4B,20,13,B1,B1,94,7C,0F,4E,A9,54,A2,1E,E5,D7,72,D5,FD,6B,22,CC,2D,3B,7F,4A,93,CF,09,F0,B5,74,41,47,07,02,11,5F,38,BF,98,18,FF,EA,56,8B,AF,0C,9A,9E,4E,F9,A1,AC,8E,20,C8,81,47,FF,E6,B7,E6,D1,B9,C3,45,29,74,CD,AD,9F,C6,40,0F,D1,25,96,10,9C,73,B4,96,F3,1D,34,12,5E,39,7C,C2,52,84,44,57,99,7C,1A,F6,65,7D,F5,21,B5,46,67,E3,DC,6A,DF,25,B0,11,6F,D9,4F,0C,E6,F8,C9,1D,D8,54,E0,F1,16,38,AA,17,DF,F8,B9,65,97,39,64,A6,A2,83,97,49,41,24,8A,1A,53,F8,70,E5,4F,02,3B,34,66,92,29,78,71,B0,C1,D6,5C,AA,17,1F,77,FB,B8,03,D6,81,13,95,CD,94,D6,56,29,95,5C,7C,EF,79,35,3F,1F,78,0E,66,7D,D4,83,8C,C0,EB,06,50,9E,64,3C,AF,33,AE,1C,DF,B6,F7,05,E4,3C,EB,CF,99,23,5E,08,4F,D6,8D,99,A8,C7,B6,49,E0,1F,48,1F,99,33,6D,B7,2D,D8,FA,4B,2F,E5,DB,8B,CB,63,DC,CD,DA,2E,70,9D,31,D1,5F,3F,BC,27,5C,ED,D6,B8,D8,38,DA,80,D0,53,7F,13,48,BA,97,91,A9,AE,F0,41,B0,B1,2F,DD,8C,F9,B0,13,ED,3B,01,DF,2C,34,34,2B,51,30,2B,41,40,1D,F6,F9,2C,86,C9,CE,E5,CF,5C,28,BB,C9,BC,6F,0A,82,60,E2,FA,09,94,30,BE,3F,60,11,91,3A,94,B7,ED,67,45,68,D2,71,86,C8,16,3D,20,C9,3D,E6,0A,18,C5,BC,7F,FE,96,D9,72,B5,C2,A7,57,21,0C,44,F8,67,13,0D,57,D1,F7,02,65,6A,3C,E2,2D,AC,30,F2,9E,A8,9C,7D,43,AA,A3,CE,2D,21,AC,E1,F3,8A,E5,1E,C2,59,89,4A,BF,47,62,A0,AC,AF,E3,86,75,C7,E1,02,CB,D4,7C,95,00,F8,3A,35,7C,99,19,98,EF,BF,C2,E7,B8,FE,8F,3F,46,80,2D,FD,1F,C6,D8,E8,DD,7B,E2,55,7C,75,5B,53,A0,5F,F9,FF,C9,4D,D3,67,CA,48,B0,EE,39,87,29,37,8F,85,D6,8B,6B,D2,36,EE,95,6B,1E,5C,F4,78,8B,8E,44,F7,E2,6F,B2,D3,C7,1D,DF,83,B6,2D,B4,1C,C3,1C,5B,C5,5A,42,F6,25,9D,3D,D3,A6,54,44,0B,28,DA,35,D5,77,52,61,05,18,EC,35,FB,73,68,FC,FF,0E,C6,C7,5F,94,69,A1,BC,B3,CE,5E,FE,29,E9,AA,91,5A,82,AB,00,48,F3,31,90,16,1D,40,81,AF,43,9E,D5,C1,05,CD,9B,82,17,31,20,45,99,91,11,78,6A,04,1C,71,43,C4,93,59,6A,D2,E8,42,14,F2,66,C5,E1,FA,B1,A1,F7,9D,8B,4D,28,C3,02,70,9B,8E,4D,23,DB,96,CF,A4,6D,5A,93,BB,55,35,58,D4,C2,81,14,11,5C,53,C3,E8,81,01,DF,8F,B1,DE,9A,4F,A4,59,19,0A,58,9E,84,EB,3B,AB,43,C0,E7,CA,D8,3A,6F,B3,56,41,8D,52,6C,83,15,E3,93,B9,92,19,80,CE,FA,64,EE,D0,CD,85,1B,12,23,49,29,11,6F,57,5F,04,57,EA,B7,9F,3B,99,84,8C,2C,65,A6,F1,58,7C,8E,33,C6,3F,90,38,51,75,37,00,19,A2,F9,88,31,82,98,5C,56,2E,05,3B,CA,B4,3C,16,33,60,E8,34,E7,D8,94,42,7B,80,12,FC,EA,21,65,4A,A3,E6,17,66,78,81,D8,19,4C,DC,69,26,2B,F7,73,CA,6C,57,CC,07,EC,4E,71,14,0F,F7,A1,68,CC,EB,EB,DC,DC,78,D4,81,E7,42,FA,A2,8F,FD,46,B1,B9,E1,6A,22,F5,8F,4B,B5,AD,F7,FF,EA,16,AB,C2,0C,BF,EC,3A,51,22,70,13,C8,1F,36,73,EE,99,39,29,06,67,02,AE,90,50,6A,28,B6,18,4C,0A,9E,2C,14,2C,9E,B5,67,AA,37,FC,A9,1E,16,B3,6E,B4,E9,48,18,EA,67,9F,39,B2,42,D0,73,82,F9,75,C0,7A,85,9B,C0,E5,EB,BD,7D,BF,45,9C,CD,3E,77,4B,4A,5F,C9,0D,9C,7F,99,DD,8D,43,A4,3A,6B,8F,7B,DC,73,20,88,1E,B9,F0,CF,F9,E0,30,8A,3E,5F,1C,AC,9C,04,D6,13,7B,04,25,BB,15,29,08,FE,1B,48,77,3A,46,0E,D7,BD,42,31,AB,20,4F,A4,DF,07,C7,B4,63,80,66,F5,63,44,EB,E7,AA,E3,C3,B8,C3,F5,5F,B5,3C,C9,71,85,96,36,3C,03,CC,FE,76,29,66,56,8D,6C,D7,79,2E,C0,C3,49,DD,A0,6C,EC,B1,8A,F2,D1,C6,2E,7D,3D,47,85,5E,6E,19,AB,86,5B,75,3C,48,4F,D3,A4,37,6C,C1,38,F0,AC,16,BE,4E,25,0A,FB,ED,D7,AE,35,C5,DC,65,F0,42,51,E1,FD,97,7B,AA,8C,DE,FE,6B,7C,8E,09,23,49,B0,8E,00,B7,75,05,82,44,6F,C4,51,91,21,14,22,68,A2,29,29,72,DF,89,DB,6F,19,CD,69,88,37,E5,58,49,AB,0F,87,9D,CF,0F,D2,EE,5B,7E,FD,85,D7,33,E9,3C,CC,2D,20,76,76,CF,A9,4F,56,16,74,1F,9A,48,00,FC,83,B4,09,5B,CB,37,69,88,01,CB,F8,49,E1,36,F3,78,7F,22,06,29,DA,2C,35,CB,B0,1C,18,33,43,BF,D1,E9,88,D7,9A,C5,90,FD,B2,37,45,48,35,7D,6F,89,49,90,C2,2E,79,19,06,53,A9,CB,B3,19,BE,F5,7E,FB,D1,00,96,42,0B,29,9D,D9,4B,46,B7,61,01,BF,BC,86,26,D8,AC,09,B0,13,24,0E,19,52,58,E1,C0,A7,5C,37,0B,B7,FD,87,38,E6,37,23,87,12,66,DA,65,49,FB,AA,B7,E4,8F,8B,B9,AB,3E,E5,E4,4D,A4,14,2F,22,08,E1,F4,EA,00,A2,2F,9A,1D,FD,2C,7C,8F,FE,F3,BD,E9,DD,3F,02,EE,48,41,C6,39,EF,43,09,9F,17,6D,DC,9D,D9,C7,3E,48,4D,3E,02,3A,4A,79,17,75,88,77,6E,3B,8E,92,80,9C,A3,CC,CC,7D,EC,BE,39,92,3E,CD,B5,C6,A5,D3,D6,E0,0E,44,E2,62,57,3E,5A,B4,02,75,EF,99,90,AA,DD,82,38,3B,02,DC,CE,F7,1D,57,6D,30,F2,C1,1B,9D,FD,A4,33,11,42,1D,01,DF,6B,05,9B,D3,B9,B9,DC,F0,17,47,0F,E7,1C,DC,5F,9B,B9,B9,95,BB,E4,0D,20,27,EB,0A,59,6E,F3,7E,12,02,3C,B4,F5,24,4F,19,F7,03,84,68,0B,55,63,DF,56,87,D8,C3,4E,00,C1,34,60,A9,1C,83,A9,6D,03,CA,C2,16,8E,D4,34,07,DB,DD,17,C5,4F,80,92,2D,86,AC,06,E4,78,50,BD,5E,A8,A4,5B,88,06,92,F2,A4,89,9F,ED,4C,BB,62,02,2B,C8,8F,8E,DF,82,CC,B0,1A,DD,DD,A8,58,81,C9,52,8F,B6,86,C9,BF,E5,06,F4,26,27,6D,1A,C6,32,CD,23,92,F8,5B,0C,51,15,C7,50,5B,C0,5E,9E,65,16,FB,77,B6,8F,F3,E9,50,0F,6A,CD,D4,11,0A,FB,A3,09,54,D3,85,2F,7F,C1,05,F2,9D,13,97,93,8A,36,C6,85,26,4D,39,0C,04,68,E5,F3,A9,80,FD,5E,7B,6C,50,61,9B,3A,67,02,57,8D,B8,19,36,B0,DA,60,37,A4,05,90,00,5E,35,FC,1C,05,95,58,A2,F2,E7,5A,97,F5,CB,4E,81,0D,A2,06,CA,D3,A5,92,23,8F,4B,6F,AA,45,B2,02,E9,7C,83,38,5A,5D,99,72,20,DB,A8,AE,2A,24,0E,4F,02,3E,8B,D0,58,D9,CE,13,74,25,04,34,F1,4B,6D,E1,49,5F,2B,CB,DD,57,87,71,E3,C9,5B,20,A2,BD,EF,92,7A,93,E7,7D,F5,2E,D5,CC,AB,21,D0,86,14,FA,1C,0F,26,91,0E,88,38,58,1C,79,88,21,76,ED,DC,D1,81,37,43,59,1F,68,56,F6,4E,97,65,3D,32,D9,A8,DD,63,48,77,CC,13,02,05,4A,DC,1E,DC,6E,88,53,E0,C4,5F,92,85,23,DB,1C,92,EA,AA,4E,D7,50,F7,DE,F9,37,5A,30,57,61,24,47,D8,94,31,E5,B6,1B,B3,C7,ED,D9,ED,42,AB,8F,1B,12,17,74,4B,2D,14,53,CF,3C,94,4B,CE,07,32,C7,AE,6E,BD,42,D5,4F,3F,59,97,46,E1,D1,A3,E2,2C,A1,0B,A7,04,F2,CB,BF,99,94,B6,A4,4C,B7,BD,4F,E6,01,82,AF,70,B3,02,35,E8,97,A2,F8,50,2A,5A,CC,87,E3,A3,92,D3,06,F2,75,56,F9,F2,CD,95,C4,F2,6C,0D,0A,D0,4C,68,67,DE,EE,DB,BC,E0,BF,26,E6,0B,B8,EB,99,61,55,2B,E3,0D,EF,53,4F,E5,74,65,C2,C7,95,B8,01,D2,58,B9,F5,03,2B,62,CF,52,9F,81,85,8C,72,A9,A6,FF,CF,A7,9F,20,2B,17,31,A7,07,99,6B,DA,E1,77,94,05,67,FF,28,0D,CD,32,07,E0,BF,E9,68,86,6A,E7,0F,FE,E1,A3,C8,C4,5A,B2,3D,D1,23,6B,B5,42,3D,B9,88,F4,59,FC,2A,26,CE,43,71,0E,72,89,27,1A,25,AC,1A,5E,F8,D0,F3,23,E1,5C,E8,FE,C7,A4,0C,BA,01,A0,C6,37,AE,81,28,48,04,41,8F,D7,CB,C2,C3,E7,E9,1D,3A,A4,23,5B,5D,65,6E,C2,99,6B,EF,C9,2F,38,C0,6B,D3,BF,D9,A9,6F,64,A0,AB,FE,38,60,24,20,DE,9B,BF,1D,30,17,9C,06,73,95,CE,A4,02,22,A9,98,1A,A9,F5,09,F0,99,E4,65,7E,02,48,B4,72,60,D7,7A,EC,72,8A,A9,4C,8B,62,DD,B6,4A,F7,E1,F7,72,98,98,D5,5B,B4,80,45,FE,9C,AA,42,BF,4D,3D,E5,1C,9E,43,EB,22,74,93,B1,49,59,AE,B3,FA,33,DC,D0,F6,EA,DF,08,00,A1,42,F5,D0,D0,90,2E,8E,DC,E3,BA,8A,0C,54,BD,28,1C,9A,07,19,79,27,80,F0,B1,BC,10,02,D7,8E,78,7D,73,A0,3C,91,5F,72,DC,C0,82,5C,0A,7F,B7,73,5F,A4,EA,FA,91,F2,24,6F,09,E4,3F,E5,5A,F3,8C,78,58,4D,E6,01,5D,85,49,ED,E3,A1,36,02,DD,7E,BA,3A,9A,4A,19,DD,65,06,50,24,13,6C,3A,91,5D,B3,87,C6,31,CA,E9,48,D7,36,8A,30,6E,19,AD,80,C1,B7,21,66,B1,FC,BF,10,C8,29,4D,7C,2A,ED,6B,AC,8A,4E,9B,54,45,DF,D0,1E,2D,E1,B6,6F,5E,54,93,BA,89,C8,4B,6D,6C,A6,43,1A,CE,1C,77,EC,BF,99,1E,FB,24,85,0C,4C,E1,D9,5B,35,76,C4,19,19,BA,57,B7,55,FF,9E,19,60,D6,66,A7,B0,27,F8,EE,E3,3A,90,4C,80,17,AF,AF,18,CF,70,C9,92,EC,EB,78,5E,93,63,10,21,F8,4A,96,0C,A1,48,7F,27,07,3F,A3,9A,1A,9A,57,41,4C,5F,8F,83,F9,ED,08,3D,63,49,A7,4F,C3,54,61,45,D3,CA,FC,2D,B7,54,BB,66,64,81,97,B6,C9,61,B7,80,B1,9C,95,E7,E0,9C,22,AB,BE,7A,93,48,B9,4D,F1,DD,A0,75,BC,52,DA,8C,25,2E,24,C1,DB,F2,EC,A1,31,6D,17,5B,B1,FC,1E,E9,1C,0D,C1,54,53,0E,CE,BE,5C,1F,E5,F5,8C,07,FF,1E,06,FA,E2,4B,6A,61,C8,BB,EC,C6,40,E6,78,F9,9E,87,BE,F8,9D,00,49,B6,7D,C2,FB,C6,32,B9,79,6A,53,AF,AB,55,31,44,0D,E8,5B,7F,A6,29,F6,2F,F2,5F,1B,21,7C,74,E6,52,61,08,1F,B6,F0,18,75,D2,AA,E9,4C,85,D8,57,67,99,78,14,4B,9F,3D,2E,BB,6D,2A,1F,E7,73,F1,36,15,14,7F,F3,CB,1B,A8,46,A5,5C,5D,AA,66,57,82,A9,59,81,F6,E0,31,82,9C,47,1B,B4,15,55,C6,9A,07,65,50,BB,E4,A9,E7,2E,A5,9B,A1,F2,99,E6,94,84,52,82,02,25,56,4F,03,43,BE,6D,B3,D3,CC,A7,34,BA,0F,AE,A4,58,7D,9A,F8,5E,92,AB,15,FC,FB,4B,4E,F2,79,B4,C2,10,3C,4E,25,EF,51,21,F7,69,3B,96,0B,FB,A7,92,EC,AD,46,6F,43,23,E2,DC,AD,83,8C,FF,F8,8A,20,D2,E7,F2,3F,C4,82,A0,90,1C,E8,4C,40,97,CB,DF,C7,70,BC,73,2E,65,87,F0,5B,54,CC,A7,01,14,B9,65,BD,78,59,01,59,96,47,35,61,0D,89,B8,D2,04,AA,DA,7A,E2,85,76,79,86,E9,FB,83,36,FB,6C,F2,AF,AA,98,74,AC,94,68,5F,F5,AA,EE,D5,0F,66,9D,CC,24,E5,FB,FF,75,08,E5,C9,CF,C1,AA,32,2A,44,B4,86,22,86,A4,78,69,99,7A,80,29,C3,59,0A,DD,61,72,43,F6,0C,19,D9,D4,73,94,3D,18,DE,4F,A7,8C,68,1F,99,1D,9A,14,A8,23,2F,C3,1F,BC,63,AF,07,95,C5,E5,67,CB,29,DB,6C,55,4F,DD,B7,7B,98,67,ED,28,4C,07,27,C0,43,14,64,8F,7E,08,76,02,51,D8,8B,00,72,EA,26,22,FE,F8,B5,C9,EB,41,71,54,94,64,04,3E,9E,65,C9,86,7E,35,64,A7,61,DF,32,75,63,8E,61,DA,4C,F0,99,B2,54,29,44,4E,94,01,B5,E2,65,13,4C,70,A2,C8,DF,2E,72,18,28,A6,1D,17,F2,B6,E6,EE,0E,B7,BD,A2,C4,86,DD,F2,D4,75,F8,D0,30,97,32,30,E7,38,F1,EE,D3,3A,08,D1,15,3D,C6,49,B4,34,4B,F0,90,6F,D5,86,A4,80,49,8C,7F,DB,01,1F,86,50,13,D8,E6,3F,D1,A9,C0,19,0F,0B,1C,B1,CC,DD,41,4C,A9,D0,0C,A3,0F,74,72,52,5A,D1,22,4B,1A,A7,30,39,0D,C7,C2,43,63,03,03,BC,35,6B,10,BB,73,CC,CB,29,6A,57,86,DF,87,13,E6,82,F2,3E,14,79,17,A5,91,35,81,F5,7B,63,15,97,83,3C,9D,F4,81,C7,42,7F,06,7A,B3,B4,D4,23,74,09,D7,0A,35,23,D4,1F,F3,65,34,F1,8D,78,9C,CB,A9,28,7A,6B,09,FD,8C,0E,AB,21,D0,DF,74,34,88,E7,8D,2E,9A,C0,06,1C,92,7C,8E,CC,24,C3,D2,FD,67,C4,17,C6,DE,C5,97,33,87,00,15,F0,BD,72,DB,9F,D5,79,8F,01,95,D3,7B,79,B6,14,E3,75,7F,88,BA,5F,E5,A6,83,BB,30,3D,31,DA,49,AE,07,7D,E3,2D,30,C9,E0,2B,B3,8A,B8,E2,F0,73,DD,56,B5,F5,2C,91,4B,74,1E,EF,96,44,9B,4A,0A,17,2A,76,52,5A,3C,55,69,4E,25,71,45,4A,2E,AA,A0,7B,29,D2,65,4D,8C,F0,7E,E0,04,6A,8E,9A,33,38,96,41,E4,EC,B5,B4,ED,4D,4B,FA,82,0C,39,15,0B,4B,09,8A,E0,69,D6,86,F8,BC,0D,9B,54,83,E0,D3,CD,9C,4C,5A,F7,49,20,DE,A2,35,71,76,3F,20,53,70,2E,52,98,08,C2,1F,F4,B2,25,1C,97,46,FD,65,6F,89,C2,D9,64,DF,D6,DA,EA,38,7F,74,63,8E,12,65,57,9D,5A,F4,6B,B6,AB,83,09,69,DD,35,F1,F4,CD,F1,2B,B3,79,63,0B,3F,C2,5F,C6,B7,2B,63,D9,46,93,15,A7,33,B3,E8,FC,2A,DE,76,A9,63,8F,6A,0A,ED,A2,79,07,8C,03,61,B0,A4,C9,D6,57,7F,BF,FE,60,97,28,30,7B,F3,EE,BF,08,EF,4E,89,44,80,FC,C9,5F,E1,83,66,03,02,5E,EC,63,6D,8A,B0,AC,68,4C,C0,3E,A5,25,A2,92,56,5E,C1,B5,BE,F0,3A,6D,77,40,2F,83,B1,06,E4,26,51,9D,2D,93,D5,2D,D4,0A,0D,1D,4C,94,51,5A,76,9A,A7,CE,D7,0D,4A,E5,FA,D8,A5,41,51,F9,10,8A,2D,B2,88,BF,EA,07,68,5F,54,CC,35,B3,0A,8A,3D,BD,CC,38,65,30,71,E2,3A,FE,3B,BA,A0,86,A1,02,07,95,70,54,0B,87,D7,51,5C,7D,0E,09,45,F8,13,44,1B,25,BF,18,88,49,95,D3,30,18,89,2B,C5,5C,E5,D8,B6,BF,2C,40,81,EC,55,F1,7E,99,CB,86,19,EA,9B,C0,82,4C,33,F7,98,BE,5C,52,52,7D,EA,6D,16,9E,ED,22,2D,02,E0,D7,EE,D6,A0,A6,59,9C,87,BA,1A,4D,AE,8C,A0,7D,31,D3,73,57,E3,13,F4,48,96,A0,46,39,09,A4,FF,74,F0,F4,1B,0F,10,23,5F,BB,47,65,E7,77,CC,78,99,92,13,45,81,9B,C6,40,96,53,54,9D,A7,65,FC,88,C2,A4,F5,16,30,AF,53,8A,52,77,AB,1A,BF,9C,76,5A,9B,B7,6D,6B,E2,33,79,20,C1,BE,4C,D5,E5,F0,14,A0,B0,EC,5D,14,1B,14,56,39,E6,29,24,2E,AD,7B,E8,A8,95,D1,12,A8,89,91,DF,1A,B2,AF,D8,E4,DB,F5,81,86,F0,33,DF,C3,E0,56,08,FE,AC,93,32,1F,9C,57,98,F2,09,16,12,A7,27,40,04,4A,C2,58,3A,38,AB,17,F1,B7,67,08,AF,23,95,17,9C,C0,CF,26,20,4F,23,32,B8,A8,72,DB,A9,18,69,4A,6A,14,06,BE,31,08,73,9D,65,D2,2E,65,38,24,0A,12,F2,6C,D0,82,C2,EC,E7,45,77,73,54,1E,76,C7,71,79,36,45,69,64,70,03,51,95,9C,DF,A1,0D,21,09,45,B3,55,85,33,0D,3F,A3,BF,8D,EF,1B,AF,65,41,16,59,A5,F0,2D,E0,29,4E,A8,34,1E,1F,79,E6,78,8E,9B,B5,92,DD,68,D2,C3,F0,C9,5F,3D,E3,DE,FC,61,8C,F6,CF,79,08,35,09,1F,37,22,EC,AD,73,6C,90,B9,40,41,AC,E0,68,A0,F9,89,04,8E,A9,46,E7,9A,B7,F2,56,D8,59,BF,1A,FC,9F,E7,1E,90,78,1E,71,FF,EB,C4,80,F6,6C,3B,61,2E,EA,49,7E,C7,61,62,8A,A2,64,7F,98,E7,67,74,81,7C,0D,EA,FC,2D,33,B8,70,9D,6E,B2,12,6E,DD,C0,65,C8,1E,07,81,4B,B5,3A,52,B7,0D,70,54,D9,22,BE,3A,4B,C2,3A,8C,4C,DB,A8,11,67,55,E8,39,62,FF,B2,F3,77,92,D6,FF,60,FA,78,7B,F2,1F,06,74,18,4E,37,4A,9E,41,47,4C,DC,F9,94,54,EB,C0,24,C9,ED,F1,A8,39,A0,0D,8F,91,B0,0F,06,89,BF,62,CD,29,91,4A,5C,7A,69,A7,AB,30,41,40,D7,CA,F9,BB,49,9E,08,BC,83,7C,44,A0,2D,67,82,63,2A,0F,E5,66,A1,29,BB,3D,43,03,56,B4,3C,CF,26,C2,1C,16,39,5A,18,56,0D,13,58,41,AD,EF,F4,34,DC,19,A7,40,56,27,0C,61,30,81,A1,6A,E5,E3,87,6C,B1,EB,A6,87,4D,5D,EC,4D,EB,7D,75,AD,0A,B7,22,A9,53,72,8D,92,05,4C,3B,49,38,B5,57,CB,98,6B,2A,8F,AC,2F,3D,B5,8C,35,5E,45,CB,5A,77,11,D3,01,CD,71,54,1F,3F,44,3F,CF,75,07,79,1B,BE,36,86,30,4F,73,19,5B,0A,89,DE,A1,80,6E,36,DE,7F,4C,B3,C1,F1,64,BD,27,1F,35,84,55,4B,3C,2C,91,4C,1D,11,C1,D3,F1,D0,E2,6D,FA,10,07,52,9E,2F,2F,FD,AB,75,C5,F6,DF,12,ED,D2,E7,D3,E7,77,DE,C8,8E,C7,1E,39,A3,D3,7E,53,34,69,95,88,79,B2,2D,74,63,74,A7,D3,E3,07,13,D9,69,0B,1E,E3,C2,C9,78,52,A2,0D,8F,9E,37,41,F5,47,30,D9,5E,9E,38,45,F6,4B,90,48,63,02,80,2F,AC,D0,D1,40,C5,BF,DC,68,51,C7,C1,1E,2A,E6,09,C7,9B,17,FC,79,C7,9C,23,56,40,30,F6,1B,C6,30,F9,C7,CC,F4,FA,7F,15,D2,F1,12,1B,F3,6D,0E,83,D1,DA,E8,5A,1F,02,C7,33,2A,6D,CC,FE,55,B5,40,9C,C0,C4,F2,B8,A0,5A,63,0E,A4,BB,7A,23,98,CA,1A,83,C9,49,F7,36,45,13,58,E2,B7,B9,77,E8,1B,97,7A,21,0C,E6,CF,CD,95,5E,81,9A,D6,FE,60,CF,F8,39,B9,7C,54,3F,16,23,20,06,65,65,CD,36,4F,42,3D,CE,BD,9A,F6,56,44,E1,5B,A4,55,F3,91,6D,B7,8F,C2,50,70,EF,36,22,2F,8D,55,8A,4F,88,72,42,A6,9D,07,57,57,BF,55,78,DD,81,1D,57,8E,53,E1,44,9D,DE,A8,16,A7,BC,39,29,07,4A,46,42,8E,8F,49,06,67,64,0D,11,92,55,8A,27,98,10,00,EE,A2,66,05,F4,60,3F,FA,C3,6E,F2,76,A1,35,D6,65,23,AC,5C,82,55,E3,E0,C6,5D,7A,69,FB,30,E6,14,33,A4,C6,A6,1B,60,F0,EA,A9,70,FF,9D,40,20,F5,4E,26,80,55,C7,8A,DA,7D,F5,18,EE,A6,E4,B2,30,EB,4E,7A,98,CF,C1,F2,6C,18,3E,39,D3,2C,BE,C5,61,E7,30,2A,A6,9B,F4,4F,8F,93,A5,A9,E9,38,13,1E,BA,18,93,E6,50,82,82,4D,1F,82,5D,56,E6,A3,74,3D,32,9B,8D,A8,74,84,5D,6A,8C,05,97,BB,D2,83,CD,A9,A8,89,E2,3E,31,FA,84,62,10,CF,7E,39,52,F3,78,DE,73,DD,72,E3,1F,34,A0,06,D4,98,EF,7D,A4,5B,68,8C,AD,DD,EA,C1,34,DA,5D,BE,B7,52,1E,A0,F3,61,09,2D,24,33,05,4F,4B,ED,B4,FE,86,21,61,D8,D1,27,C4,0D,CA,94,5B,4F,CC,D7,AF,F8,F6,39,EC,11,BF,43,D4,BF,D4,66,6E,67,3C,AC,3D,07,60,00,4B,14,11,D0,2F,E9,9B,C8,EF,12,35,F1,2A,E8,0C,B0,32,3D,56,AE,8F,1A,48,8D,72,89,45,67,2E,FF,8D,51,00,3A,22,A9,A2,E1,24,18,26,CE,8D,5F,55,F4,B4,E7,30,33,A2,1E,F0,E3,BF,76,C7,F3,77,14,5B,80,92,85,1E,AD,55,C9,61,AB,D6,98,E8,09,9D,88,BD,B3,15,E6,87,BE,BA,16,F2,13,4A,F5,3E,58,54,36,91,0C,F9,33,69,E9,04,4B,D8,78,41,CB,0A,86,71,E5,F8,1E,9D,62,01,E7,CB,0C,C1,ED,C8,DE,E1,D0,F5,AD,55,E1,F0,F3,7B,D8,2A,AB,0D,0F,50,E8,B5,E6,69,BA,04,4E,96,43,6A,6D,92,09,6D,F7,10,01,4B,9C,98,5A,1B,EB,2C,A1,B7,08,26,D4,4D,DF,6A,45,59,B9,C5,78,41,B9,9A,EE,06,8E,DE,FE,60,88,BB,B6,5B,8A,06,E2,4D,ED,62,21,5C,B4,23,5B,75,F1,C8,5E,51,B3,0A,FA,70,96,3F,A6,D4,2B,45,BF,0C,79,B5,14,E1,9E,9A,7F,D4,E0,37,F5,AA,6B,6D,3C,5A,31,79,25,4E,27,06,F6,C4,C0,0D,BD,BC,F4,4B,C3,E9,DC,F3,4F,CE,DB,D5,C0,02,96,2D,33,47,E1,38,C7,9F,25,8F,B5,58,37,D0,E4,AF,1A,B2,9F,09,3D,F5,6E,6B,DD,AF,49,BB,AE,A4,30,16,83,1E,25,A9,A8,48,2A,E5,41,E4,77,A2,40,B1,50,89,74,E8,96,EF,A9,5F,A7,E2,0A,3B,8E,16,3E,37,A1,F7,D8,F9,FC,3B,E9,04,1A,1A,4C,50,DC,C3,A0,D0,65,69,8D,12,C9,4B,D2,10,2D,7A,A7,F1,44,A5,F1,EF,52,95,0E,B2,D9,0C,F7,7E,37,31,41,8A,CA,E1,0B,D6,54,29,54,F4,0D,BC,41,07,24,36,12,D6,C0,E3,D8,D4,4D,5C,4A,1B,E5,98,70,C4,20,FF,B5,3B,D7,05,DB,F2,69,91,35,46,38,64,15,9C,52,16,66,BF,7E,CE,BB,9C,57,40,03,8B,A4,80,D8,57,E2,5D,A4,88,8F,01,51,AB,B1,7F,46,30,20,FC,DA,F8,21,1B,74,A1,C0,C9,04,D2,27,5B,CA,19,96,18,FF,D2,44,A7,C0,D5,E3,B0,09,8A,54,96,7C,63,2C,D1,6F,C7,F6,3F,D7,DA,C0,3C,5A,6E,83,E8,3C,63,05,03,FF,38,59,7F,09,33,DF,A6,3B,6F,49,C6,D5,8D,D3,F9,13,E9,5B,BF,19,05,E3,57,25,BF,7B,CC,A1,A9,F1,38,22,E8,B2,21,DB,D6,60,9A,1B,2A,A6,0B,3B,4C,5A,75,3C,ED,A2,06,77,71,D6,84,A6,FC,07,CD,9B,67,CD,0F,44,5C,A2,05,C0,21,12,3A,34,0D,B3,49,B0,72,BF,34,39,23,F9,FF,E5,4B,5B,F3,15,1B,1B,B0,BE,8C,5A,BF,96,E0,12,98,3B,7C,34,F5,E9,9F,C1,14,FB,96,C8,B0,4D,93,EC,61,F3,2A,78,40,BF,1C,6B,49,0D,0A,0E,50,F4,2B,30,88,13,E4,CA,E7,3A,99,77,07,CE,15,4D,2C,54,0E,0A,F2,7B,AC,59,53,B8,9E,0C,80,76,E0,F1,C3,B1,EC,52,47,6C,C0,6B,0C,26,C5,AC,F9,C0,D4,A2,41,26,F9,0C,05,59,EF,94,71,2E,4F,CA,33,B1,7F,88,FB,DE,73,79,DA,71,1A,F6,75,53,B9,6D,0F,BA,4E,9B,B8,87,E6,4E,80,40,D8,C2,EA,0E,A6,44,DA,62,97,94,DF,B4,0A,8C,78,0E,3B,9A,2B,CA,7E,E8,0D,61,E0,A2,CC,52,8F,E1,35,63,F4,51,67,52,3C,89,7C,9E,14,15,27,39,D3,29,A1,72,96,1C,1B,E0,AF,C9,CE,D8,36,0B,E8,7A,FB,53,C0,C3,A7,FC,D9,21,8A,60,B3,D5,44,2A,0C,95,F2,CC,1F,E0,58,D8,B1,08,AC,3F,8C,87,05,65,BC,BD,52,61,81,14,49,65,4D,52,7B,DE,93,7E,2A,4A,0B,4B,6B,E3,5B,CD,CB,A6,8D,8F,5C,69,E9,03,D5,ED,E1,C5,DE,D8,51,5C,FD,88,77,CC,69,3A,32,DB,BB,AE,1B,B5,A7,D0,54,51,CD,E9,0C,B7,39,09,54,D8,21,70,30,D2,3B,E1,AA,E4,08,2C,CA,F8,AE,18,43,F4,85,8A,F8,19,A2,71,9E,68,BE,80,D8,A0,E1,44,EB,92,E3,8C,E6,61,3B,90,A9,68,BC,D8,AB,97,9E,83,70,2B,E6,A0,F0,B6,7D,A0,B9,E6,E5,D3,90,64,C8,FC,95,93,B8,88,66,6C,13,AC,79,B0,65,E6,EC,14,D8,F8,6A,94,5E,42,87,62,ED,5D,C1,38,E5,5D,CD,E0,23,D4,A9,AB,BD,9E,CC,1D,D8,84,ED,F7,0B,FD,96,D6,03,8B,27,9C,64,D9,0A,0D,F1,EA,0F,16,51,9D,29,59,97,3C,C3,BF,80,09,FF,57,37,50,6A,DD,B9,91,26,69,35,D1,72,FB,15,79,9E,20,CC,2A,DA,84,D6,CF,37,1C,36,A6,35,6E,C9,E4,B4,56,9A,A7,EE,7F,2F,E0,6B,E4,F8,7A,00,F5,46,40,65,BE,CB,45,47,EE,DB,B1,CB,FB,17,25,98,36,9A,31,84,B0,BE,D8,D6,01,24,56,05,9F,0A,0E,4B,9D,34,30,B4,D6,0D,A9,0A,93,F2,CE,49,01,85,A2,8D,17,34,86,50,A2,C4,84,F3,C0,55,30,7D,15,E9,72,77,51,64,85,F7,23,A3,83,2D,D4,CD,BD,F9,02,5A,82,29,4B,A4,10,0D,AB,4F,D3,5C,B8,3A,2C,EC,C0,D9,9A,4A,8E,7D,2C,90,3C,C9,88,AD,B6,9C,F9,90,50,71,E3,C5,34,E3,29,37,DD,D0,FB,CD,CE,A5,4D,70,25,F6,B4,48,1C,E4,A9,2E,87,69,74,67,34,04,02,DD,52,FD,DC,45,D3,DF,13,AD,4E,8A,29,4B,E0,65,95,30,BD,96,87,48,54,96,ED,72,4C,2E,6E,C9,5A,2E,17,86,D2,41,86,AC,0F,C7,35,0A,12,10,5F,BA,D4,51,9C,BE,2E,42,07,FF,1B,1A,39,02,FE,03,65,F0,2D,55,F7,13,09,B6,21,DC,BF,C5,4F,E0,23,09,D8,E5,26,2B,56,56,99,D6,A7,38,EF,7F,CC,54,F0,C8,99,5B,49,C3,2F,06,0E,CD,B7,28,48,B1,2F,C0,1C,B0,8B,2C,16,43,51,0B,9C,98,9D,6E,93,5C,4B,A4,33,BD,27,A6,12,EE,BE,B2,EE,BA,58,ED,AE,8D,C7,17,0B,CD,BA,E7,79,28,AA,7E,5D,FE,28,36,58,16,0B,4A,C6,AB,18,06,CD,AD,91,25,13,AD,E9,35,24,30,A4,0B,C9,D3,27,6E,F4,72,03,15,13,34,6C,69,63,34,82,DD,AE,D4,40,CF,62,01,29,00,BA,DD,14,22,8B,64,1F,98,D7,E7,9C,21,45,1F,18,50,D4,A5,B5,5F,B1,0A,B6,39,AF,E4,A4,D1,4E,C9,BF,2E,D6,54,57,BC,B5,55,46,AC,62,E0,9C,E7,0C,8A,C4,68,73,B1,EE,92,1D,56,DE,6F,84,76,24,C6,38,B3,EB,4D,6C,77,0C,74,B3,DC,0E,53,2E,E1,88,09,99,2F,34,35,20,AE,8F,7B,2A,E9,63,4E,73,56,22,DB,F3,5E,DD,4D,CA,85,37,8F,25,22,48,39,25,7D,04,AF,57,07,A6,4E,2E,1E,8E,49,F0,CC,BF,69,10,A1,E1,EB,80,79,E3,13,EA,62,CC,F9,ED,48,C9,C7,00,4B,11,44,65,36,D9,7D,B2,52,7E,B8,13,E3,D9,70,4A,52,25,F8,00,5C,D1,8C,90,0D,24,E4,79,9E,A6,72,C5,2F,79,D7,68,F5,D2,49,CF,92,07,6D,12,DE,4A,9E,75,8F,4A,07,35,E9,BF,55,24,B5,F9,3F,1F,DC,D2,00,BD,9A,19,16,0B,99,1C,B1,50,F6,63,32,1C,68,9E,02,DF,39,39,54,0E,EB,6B,37,46,00,CC,34,33,3D,60,8C,21,DF,28,04,05,26,F6,63,41,3C,61,58,01,68,5A,53,09,CD,37,46,78,F5,6B,9B,B2,D7,FD,DB,1C,32,58,DB,5D,2A,EA,96,38,05,95,4F,15,6B,F6,63,C4,A1,62,16,96,E1,56,98,0E,E7,77,9E,0E,62,31,B2,E8,0A,7F,EF,C5,83,AD,0E,F3,1B,C5,9E,0A,0A,36,3A,4D,CF,95,4D,43,09,88,19,D0,51,96,DB,14,4C,B6,53,8A,F1,4F,F1,11,84,68,28,33,D1,E9,15,79,CB,92,BD,A6,9F,81,3C,45,D8,0E,77,07,44,40,93,51,F7,BC,13,F3,47,04,9B,46,1E,2D,D9,D7,C3,6B,81,6B,3D,F0,1E,B2,9A,D7,63,4A,F0,BA,46,FC,AA,4F,F1,35,23,1E,7E,1A,26,B4,C9,C9,D1,BB,A3,6B,13,CD,3E,D4,C8,AF,31,81,DD,A8,09,3B,4E,B2,3F,41,0B,34,C8,B8,F3,28,4B,B3,BF,ED,0A,5A,0C,09,2D,7D,D2,4F,55,BE,EB,28,73,31,85,07,A5,D5,40,15,B7,21,3B,D8,C6,C2,0A,1A,9A,97,3D,27,A3,4D,CB,ED,61,83,B3,DD,FF,19,56,A5,8B,26,41,77,1A,0E,E0,A0,1E,ED,4F,18,CF,2B,01,C1,00,06,7E,32,4A,1E,E9,52,E5,C2,F0,5C,71,8C,18,F8,02,C8,BA,6B,6E,0B,59,0F,1B,1F,29,76,70,DA,62,20,10,F7,A0,FD,1D,90,69,1A,8D,1A,C4,E7,44,E4,3C,B3,5F,D7,BE,C7,FB,72,DC,71,E5,39,0B,CD,E9,C0,7E,44,CE,66,D3,72,C9,E7,C2,60,31,69,7B,FA,F2,85,6A,3D,27,F3,59,C3,0A,37,D6,1C,B9,BF,56,E0,57,F2,6B,F1,75,D7,CE,01,E5,6B,43,15,38,AE,30,99,AA,72,AB,FE,06,FE,18,EF,92,69,4C,81,20,79,CC,E4,8A,F6,23,50,8D,B4,9A,37,54,8B,CC,55,BF,03,ED,CE,6E,B2,1C,91,5B,64,47,CF,DF,81,15,31,72,F9,22,4B,42,F5,59,04,0F,EC,07,66,79,FF,66,3F,2F,69,FE,1E,00,17,EA,CE,B6,6E,59,4D,B4,18,7A,EA,FD,23,DB,7A,1E,8B,69,31,C6,4D,96,98,61,7B,0D,67,AF,F1,2F,18,7F,1B,FA,00,E9,0E,67,5A,37,93,95,5D,78,1D,AA,2D,A0,BB,DB,9A,A1,2D,77,E6,06,77,9C,78,8B,29,00,86,1E,57,31,46,35,19,82,3F,D5,9A,07,D6,5A,D7,6C,9D,87,61,48,55,39,6E,22,AC,1A,FA,6D,70,2C,70,24,59,B0,93,B2,D4,A3,DB,79,65,86,F1,8E,9A,42,38,9E,7B,BA,FA,21,41,92,DC,D1,49,F7,1A,0B,62,F5,29,3B,8A,C3,65,C0,DA,9F,CE,DD,70,CB,CF,67,2D,7C,7B,8D,A0,2B,74,EF,7E,16,1D,19,EF,9D,59,6C,7A,24,D4,A5,D5,72,EC,FA,AD,2F,FD,E6,A1,C7,5C,BA,2C,B9,39,BE,FB,C0,D2,AA,34,E6,C4,9F,6F,4C,43,01,D2,DF,2C,A2,06,FD,73,AF,B1,46,D0,70,D9,36,A9,E5,9C,47,57,65,3D,99,B7,55,16,25,B7,CB,27,7F,05,70,62,8D,5D,A6,23,40,64,5C,0C,14,DA,FE,B1,31,55,DF,47,EF,A1,63,9D,09,43,FB,A8,4C,E5,1F,6F,09,2C,62,98,FB,EE,6F,52,40,D6,AA,CD,EC,30,F9,D3,8E,FF,65,59,CF,C3,E0,2E,2A,2B,EB,37,D0,1C,7B,2A,93,B2,DC,C9,B1,88,74,6E,E8,0F,6A,49,55,DD,24,CE,8A,9D,74,66,7C,B6,47,F0,8A,AF,2E,E9,51,82,43,FA,31,38,7E,86,BB,34,E7,F1,FB,A1,54,8E,DC,71,AF,E1,04,F5,4C,2A,26,5C,DB,C4,DD,DA,65,E1,4A,3E,FB,FA,C6,83,BD,DB,B6,0E,9C,43,D3,62,A7,2B,A1,0C,2E,91,9D,D5,86,35,E8,91,63,18,F9,FA,D7,56,5D,8B,F3,EB,96,57,52,5B,1F,16,BA,D0,35,C3,A5,83,B9,47,84,8C,62,CA,7F,57,3B,3B,B5,78,E1,BA,C7,C9,F6,7E,7D,47,7D,3C,D0,86,20,CC,BB,92,2D,D9,2E,3B,A0,AC,E8,95,B3,2D,5E,F5,E9,C8,B4,68,C5,DE,05,9C,9C,A1,F1,F3,32,54,8E,DA,14,39,0F,A7,28,03,04,F7,96,EF,50,A9,04,4E,DC,BC,C3,88,8B,7B,C6,39,DA,11,9E,D5,FB,90,5A,44,AC,43,A9,51,30,96,5E,BA,E2,56,CE,5F,26,28,5D,A6,2B,18,FC,28,DB,05,25,94,83,7B,C1,14,F0,A5,8F,AC,12,1D,FE,48,2A,5F,99,33,1F,DA,79,6E,4D,57,30,AA,BB,6A,A5,82,60,25,23,79,B6,9E,75,1C,88,EA,6B,25,65,D7,2A,C3,D4,67,6D,AB,E2,62,56,F5,FE,AE,8C,A1,7B,2E,4C,2D,AF,C5,5F,89,A0,D5,18,88,29,E8,E4,07,4F,C0,E7,E6,82,DF,27,CC,4F,34,20,40,5A,17,80,57,19,46,C0,DF,C5,C0,2E,56,77,5D,5B,F8,93,3B,1B,11,8B,89,24,7D,B1,C5,9E,31,F1,BF,4A,DA,3C,E6,C9,0E,B6,C2,22,26,1B,6E,0D,DC,BE,E7,72,10,7C,56,90,A5,CB,5B,76,40,F0,12,10,92,22,26,4D,E2,65,09,14,CF,E7,25,E2,2C,B6,EB,76,9E,C6,53,CE,67,43,92,BC,25,75,DE,40,8F,EC,C8,B9,1B,BE,04,50,37,D1,B9,7B,5B,79,D1,36,1F,B0,D2,3B,6B,DC,AB,64,C0,D8,AC,FB,08,D9,EE,E4,26,B1,E3,60,4D,BA,19,EE,BE,3A,D1,52,B2,F4,2E,50,8B,D4,F8,56,07,31,51,31,30,AE,60,11,BD,FA,92,CC,D8,95,3E,A5,A7,A8,A0,EA,97,08,66,F7,4A,09,BA,F7,31,5F,51,E3,00,16,62,DA,F5,AB,D3,9A,9D,9E,7F,B9,9A,76,CF,14,3E,1D,A4,72,7F,A5,95,18,6A,81,9E,F6,CF,B7,EB,D0,90,8C,AF,92,0F,79,F8,7B,AC,98,5E,4F,68,F4,59,5F,F6,F9,C0,0F,9E,92,9A,44,B7,DE,7F,73,08,12,71,AA,6C,F3,37,03,48,4C,B7,5E,16,55,1D,7D,18,6D,39,D4,9E,BB,E6,33,9C,1D,E9,79,2D,C5,F5,88,35,55,64,F7,38,29,1E,36,1C,DE,52,52,B8,8F,AA,27,D5,9A,7C,AA,6C,17,92,B4,4E,B3,47,A7,43,7C,D2,9C,5B,D9,1C,E9,E7,4E,85,69,7D,9F,35,E5,8C,22,F2,5C,0B,D6,C1,16,AB,F5,A2,4E,43,37,18,C8,5A,48,89,82,DF,FE,BF,1F,CC,8A,F0,FC,BF,E7,2E,FB,5C,80,E4,29,AE,EC,8D,96,7C,B1,89,79,EF,3C,77,F3,17,FE,56,6D,63,33,5B,CE,D1,20,36,CC,EB,27,DC,D7,8F,30,65,C8,25,F9,27,8A,0E,6A,2D,B5,04,7C,3A,A5,D8,56,44,98,2C,21,36,2A,A4,A1,82,6C,1F,62,20,A6,2B,38,5F,FA,43,13,DE,7B,01,6B,1B,37,0F,06,B3,6C,18,1B,70,5D,2B,9A,C3,6C,70,FF,99,EE,A6,05,B9,48,E8,30,B5,49,41,EA,10,AF,91,84,CC,28,61,CA,4C,F7,64,10,B8,AD,DE,0F,F6,E1,03,7F,09,E7,75,99,D9,79,E8,82,B7,DD,2E,65,A7,96,E4,40,E3,0E,BB,75,3A,74,DC,7D,5C,F1,C9,9E,C4,78,76,B2,3F,6A,3D,E7,DC,27,9A,0C,F7,CF,21,CB,3F,70,2E,0D,44,BE,DE,59,21,90,47,D1,D2,E5,71,CD,8A,EF,58,B7,14,86,41,2F,8A,26,D4,3C,A3,5A,C9,B6,DB,78,FD,0D,33,DD,FE,87,64,B2,BB,0E,26,A8,82,23,86,0C,E1,E8,79,BE,B0,44,14,28,0F,DE,E4,03,0F,9D,39,57,C0,7B,81,34,44,2C,EC,B9,8E,0F,E2,9B,40,23,C7,D8,3B,CD,7F,5B,75,22,52,38,86,8D,5A,0D,05,3A,41,36,D5,16,31,AF,1A,CD,69,63,72,9E,D0,6E,8B,C4,CA,83,22,A2,53,2C,85,39,0E,C3,6B,EE,E7,D3,0A,7C,54,55,FC,F4,DB,C8,E6,37,9B,30,A6,EA,4C,52,6F,57,5D,71,6A,99,0B,06,C0,46,8F,5D,F9,07,EB,43,07,37,C5,D8,75,5F,D7,BA,78,38,33,34,5C,7A,39,20,EA,DA,26,83,FC,B2,05,C9,DC,5D,32,C3,49,2F,07,35,87,6C,64,B3,5E,CB,44,0D,78,8E,97,1D,58,57,4F,6A,D9,8C,CB,CE,8C,88,26,FB,9A,F7,9E,36,75,EE,16,A5,64,73,93,37,4D,B8,CA,CE,FB,99,E7,84,B2,78,68,7F,31,D1,CF,C8,90,C0,C1,2B,5C,AF,74,AB,64,26,6D,85,F1,A3,3C,BB,79,FE,52,B3,1B,45,F4,BC,2A,E5,ED,EF,CD,3C,CD,C5,5E,63,47,6F,50,0A,AC,C5,D0,D2,47,03,E9,B5,AE,B7,13,2C,A7,46,17,E9,5E,8F,F2,78,AA,E1,51,DD,3E,2E,7B,B8,98,0B,62,1B,58,67,64,3A,FE,B2,A5,51,35,38,82,C2,A7,92,B3,6A,74,EE,89,E4,D9,74,3F,C9,1C,25,0E,D4,63,49,38,A0,12,BA,24,90,52,CE,C8,F0,8E,0F,E7,42,DE,14,B7,CF,14,C5,12,8C,89,69,C4,E3,83,8B,7A,60,04,06,30,9A,75,7B,C3,FF,4A,9D,30,50,73,62,2D,E3,5F,10,C6,43,2E,57,B3,44,99,86,E0,DC,AD,33,09,4E,8D,F1,76,6E,97,38,15,D0,88,51,41,D7,20,08,A8,18,57,7F,EC,FE,78,B0,FE,75,74,25,E9,6D,82,F8,79,02,A0,59,28,58,CD,C3,81,14,CA,73,3C,C6,09,53,6C,86,50,BA,D7,53,3E,98,98,4A,96,8E,4F,B4,79,9A,7C,87,B3,E4,EE,61,CF,86,F7,15,0E,9C,1B,52,4F,A7,75,F8,35,EC,1B,49,D0,96,10,DE,5B,67,1E,BD,A9,33,05,25,DF,15,9A,49,E4,B6,44,41,A6,DC,F3,B6,B9,66,C9,30,A7,9E,14,52,D3,00,8E,A4,C9,E3,04,92,34,45,D0,3A,33,DF,C2,F3,16,F0,C4,59,0A,46,66,61,75,92,66,BE,6C,84,BD,5F,97,F4,29,3B,FF,71,80,60,1E,7A,0D,7E,B8,65,0C,9C,F6,24,D1,82,AC,64,49,54,9B,12,6B,CE,95,58,0F,6B,07,D2,64,6E,D6,B1,53,ED,5D,3A,16,0D,52,04,19,04,92,B9,B8,91,E9,4C,2B,67,3D,49,FD,97,76,70,D2,6A,7A,33,F0,72,42,52,35,5D,A5,70,BF,8C,EA,BC,E5,81,27,A7,32,A2,4B,6B,C1,44,F5,4B,57,64,78,EF,5C,9B,4E,83,59,D4,D1,CB,47,55,7D,4C,01,A4,0C,3D,98,F1,B0,25,F7,9C,8B,37,C9,5C,5A,9D,6F,AC,C4,19,4C,EA,1C,46,45,BD,CD,72,6B,F7,3D,57,C3,CE,F5,B4,9F,AA,1F,FE,EE,B9,F2,72,A2,AC,DC,71,23,E1,2C,A7,D2,8D,0A,AE,23,A5,43,3D,2D,9F,DF,8F,AE,4D,EC,08,81,9E,BB,CB,86,6A,D8,D8,A4,EC,1E,1B,10,74,D9,71,92,8A,1F,FD,7F,5E,18,9F,82,F5,33,CF,31,5B,F3,AD,54,6F,1E,A9,3B,93,C5,1A,C5,FE,8F,E2,AB,AD,B4,7D,9B,31,36,1C,57,60,3D,DD,B4,5A,97,C3,EF,D6,BB,3E,1C,9B,36,29,97,60,C4,F4,75,F1,20,95,F4,60,41,2F,73,D3,8F,51,6F,B3,7A,55,8A,EF,B5,8C,C2,7C,C1,7F,8F,8E,00,CE,5C,32,CB,66,31,35,42,A0,13,EB,69,D0,CC,F5,65,C8,CF,F4,FF,1F,9A,58,7F,93,3B,3F,BB,41,56,81,3B,65,BC,32,62,69,31,8E,9B,27,23,45,C8,A7,60,62,80,C2,79,E2,A6,57,30,3C,C4,09,6B,5F,B4,AC,15,48,66,52,33,91,2F,0F,E9,36,5A,6C,1E,45,74,0E,24,DE,AD,F1,48,BC,B4,D0,A7,27,64,5B,CD,FB,F5,35,C3,09,4F,B6,A9,B8,2B,86,6A,FD,EF,44,2C,AB,E8,A3,9A,F7,50,3D,79,BC,2C,F4,C7,19,B5,A4,59,F8,DC,24,EB,F4,2A,3E,60,8B,69,A2,59,DA,F5,D5,6C,09,A6,0F,19,67,EC,43,E9,C2,FC,09,AC,B8,39,F9,08,E9,9E,18,4D,CB,FD,C4,7C,9C,36,97,73,D6,B0,8D,B9,87,D5,AF,09,9A,3C,CB,F6,64,CD,09,E9,E4,EB,EB,E4,36,4D,44,0A,05,AB,77,E5,04,76,3A,83,E7,79,4D,0D,23,45,98,21,AC,6A,1A,99,A3,13,00,E6,AE,29,64,D7,9D,84,86,48,11,84,9F,5F,EA,7A,73,02,E5,BE,6F,AA,1D,35,1F,6B,BD,15,F3,98,44,9F,76,4B,64,F1,34,B7,43,16,5D,22,3A,28,02,84,A7,10,71,C7,7F,07,B2,A2,1A,AC,03,16,A2,41,EA,B2,24,E8,F8,E2,F8,76,49,56,81,1D,56,B1,41,05,41,39,99,1F,E0,9B,E0,74,E8,A3,FD,2F,FD,0A,1E,5C,85,11,F0,00,06,E0,96,71,55,F7,99,15,B7,57,B4,D4,B0,82,55,EE,7E,E2,1D,A7,12,48,7F,2A,4B,28,5F,C3,43,E4,9F,86,01,4D,EB,EC,CF,96,B4,8C,05,F6,2A,EC,09,30,36,1C,62,F3,E2,BA,24,35,DC,D4,2D,27,2B,62,5A,87,EC,62,1B,48,BC,52,E2,89,DC,6C,87,00,5F,1D,7E,12,D9,84,1C,6E,46,84,A8,BC,46,BF,F7,7F,89,F0,37,0A,94,D8,0B,9E,E8,B0,5C,2B,F6,06,EC,D8,9B,7B,61,5E,D6,DF,0C,10,8F,D4,FE,01,0C,E8,B4,C7,13,C9,17,FE,3E,A9,AF,43,89,4B,93,41,81,CB,E8,DE,43,88,03,8F,C9,3F,5F,D1,14,EC,EE,1B,A0,F7,3F,1C,F4,7A,74,78,FD,63,4B,E5,B8,76,03,F4,24,36,69,B6,0A,1A,D0,A4,D6,62,B8,71,06,A6,BA,D9,7F,F0,B5,89,63,D4,B7,0F,98,6F,5F,BF,E6,8B,E6,F9,C0,A9,E6,22,C0,C2,C6,87,F0,59,05,71,B6,FC,E8,D7,E6,01,27,6E,0F,AC,85,42,CF,9A,72,46,93,00,98,39,5F,2F,40,91,5A,C4,B8,54,3E,C2,99,A6,14,AC,7B,4D,87,B0,69,D7,61,3D,7E,BB,03,A0,92,68,00,24,79,8F,E9,D3,94,DF,28,09,96,45,6B,BA,6C,A0,32,D9,91,6B,24,48,61,57,8D,32,DD,89,16,29,20,CC,8F,6D,21,1A,53,CC,EC,78,D0,FD,FD,3C,D4,A0,4A,26,53,B7,E6,37,87,B5,51,6C,8D,73,7F,0C,D2,AA,2A,BE,C6,6E,11,14,06,BF,87,F9,77,20,34,2E,07,7C,29,B2,BD,82,88,0E,07,50,4A,18,40,9F,2D,67,6D,A5,91,79,C7,48,D7,B2,54,65,11,81,07,CA,D0,B5,04,5E,34,F5,BE,FC,B4,9F,57,4B,1F,49,67,52,02,0F,91,17,1D,74,90,A9,65,6F,56,CA,95,F4,8C,E4,37,69,0B,8A,5C,D3,7A,F4,03,11,D7,9A,54,60,6B,B8,1B,1B,42,04,8E,1E,5C,98,F7,58,AF,3D,5C,00,0E,91,92,61,E5,74,76,82,CE,4D,E0,9A,7A,D6,26,36,F2,53,05,8D,AD,99,F8,B5,9B,D8,B7,12,29,3B,91,45,5A,A4,17,F4,C0,7F,A2,F3,4D,2E,E0,71,14,14,FC,75,13,03,B8,7C,78,23,CD,8B,74,6E,50,E3,72,83,41,C0,0A,7D,4B,1A,45,03,AA,A4,BB,D2,5C,7A,70,F2,97,BB,4C,A7,DC,9C,E9,0B,4A,DA,46,A0,B0,70,8B,72,77,A6,0D,FD,79,45,0E,46,35,1B,96,6B,9F,DF,03,0F,1B,8C,72,37,E7,73,5A,3F,4C,44,9C,AD,A4,8A,B1,35,EC,94,5B,4F,9A,7A,5F,06,51,C7,B5,14,12,01,4D,04,44,37,B7,0B,F8,E9,D1,CE,34,BF,D7,3D,04,AB,93,44,E6,04,1F,AA,D8,A7,B8,FD,FD,44,C7,A9,25,4C,DD,86,A9,BD,30,F7,F3,98,6A,34,7A,83,BA,6F,E8,3F,86,32,C5,B2,72,19,FE,F6,7B,2D,1E,89,08,80,13,5F,5F,3D,B2,6B,22,40,5C,7B,CF,96,48,56,13,AD,64,85,F2,AE,33,FB,54,27,F6,E7,5B,F8,03,F3,B1,0E,56,28,5B,D6,8F,69,C3,2F,3C,A8,41,56,D1,A1,61,3D,4C,0D,B2,10,4A,10,E2,53,AF,BE,9B,28,52,27,2F,D8,C5,E7,0C,A0,04,95,8B,40,60,5A,BF,E9,BC,F0,77,98,80,99,60,4C,CC,E6,25,EB,52,09,37,4B,FE,9B,5E,41,81,63,00,48,01,CB,D3,1B,77,5E,25,B2,7B,A5,68,1B,62,91,FD,B6,72,B1,D4,89,AB,9D,9C,00,44,AE,9E,67,FB,84,EC,C7,A4,F8,FA,C5,18,75,25,FD,55,8D,14,FD,15,27,B7,98,65,77,4E,B9,21,AB,A5,03,70,7C,0C,2C,D3,6C,4A,07,E1,E5,8C,83,45,59,EC,6C,E6,F6,A8,9C,F2,73,46,21,7B,51,23,72,7D,06,E1,B2,05,D1,E8,02,04,53,D0,2E,19,A0,88,B2,61,6F,2A,6D,68,11,12,B9,FE,32,AC,D9,D5,77,FE,51,AC,79,FD,ED,DF,50,CF,D5,61,88,16,03,59,5C,6B,A8,50,4C,F3,06,41,86,57,B7,17,77,8E,DB,00,21,3D,E8,D3,21,CD,B7,03,5A,C5,91,7F,D3,18,09,97,B6,E8,3D,7F,D6,53,BE,37,46,D4,8A,42,79,90,B1,1F,0E,63,81,2C,BC,B4,35,04,75,5B,34,56,D2,C4,AA,57,3A,57,B3,F7,59,15,B9,E8,BE,8B,2F,CE,AB,37,70,14,72,47,E3,79,FB,CF,83,D5,58,CF,74,CD,1A,E9,94,47,69,36,47,EE,FC,C3,88,C4,99,A2,93,85,28,02,A0,E4,03,04,F2,37,E9,3D,E3,CC,CF,41,05,26,41,69,F7,3C,3F,32,F6,80,7D,6A,E1,B1,F8,93,C4,27,7E,3A,AF,79,10,59,FC,24,81,45,B5,A8,8D,B0,55,D8,69,33,33,A7,96,03,9F,2D,65,EB,07,96,91,0A,BC,B9,98,D1,FE,72,FA,F9,25,D7,95,EB,56,73,A3,4E,42,83,48,61,A8,96,44,8A,B7,09,54,FA,20,AD,0C,1E,3D,49,35,38,6C,5D,B2,1F,F9,31,A5,B7,C6,D4,D9,CE,BB,22,4F,08,A9,C4,C4,12,24,17,F8,9A,BC,48,FA,D5,42,03,78,44,46,1E,50,02,6B,8E,FF,C4,7E,11,E2,B5,18,AB,E6,A9,3C,EF,37,58,71,4D,54,8E,D4,80,6C,B3,F7,25,C0,12,A5,05,43,40,F7,CA,BA,39,7F,DE,1C,C4,89,CD,32,87,E2,EA,E9,AF,BF,26,F6,BE,34,92,4D,86,E4,B2,EF,E3,68,DA,82,95,C4,6E,B2,26,6C,26,A6,51,C3,79,FA,A6,11,0F,64,4F,05,C9,BF,7F,71,03,E3,A9,4E,FA,A5,09,91,9D,CC,0A,7E,E6,34,1C,2F,DE,F4,57,15,00,F2,2B,AA,58,7E,E7,9B,4B,88,46,EA,95,AB,96,3C,FD,8E,44,BE,63,70,99,12,9C,11,E1,04,CF,8D,29,FF,0C,1B,77,0A,F2,FF,39,81,9D,A4,D3,B8,2A,E2,37,FB,5A,82,E5,1F,F7,AC,C9,66,A0,73,C1,26,7F,6C,10,1E,40,74,BA,EF,84,62,11,E0,FE,24,66,85,AC,E0,8E,30,AC,A5,D3,D7,FD,90,EF,14,5D,73,E3,16,88,AD,9A,57,38,F2,BB,64,38,38,C4,F3,B9,C1,51,47,DD,72,17,4A,CD,B3,48,00,19,22,BF,1F,51,E7,2F,EF,4B,14,80,7D,F1,6D,46,7B,7C,AB,6C,C9,23,9F,B0,84,F1,62,12,4D,CC,5B,07,A1,4F,F6,B1,B0,76,FE,69,28,B1,8B,96,C6,60,11,49,D8,37,71,8F,15,8F,65,58,75,BA,EC,E5,2B,B5,1E,50,24,81,E9,06,70,65,A4,AC,CE,4E,49,88,0F,83,82,BC,35,CD,6B,81,C1,A2,06,CE,DC,89,52,30,96,AF,5F,A2,71,89,CB,EE,1D,22,A2,DE,05,56,7B,32,CA,C3,FE,76,9C,A4,1A,6E,C2,AD,56,F7,46,86,4C,72,98,DA,F6,60,43,9A,24,DB,39,34,92,9F,87,AB,1C,29,4F,9A,ED,A3,DD,FC,75,CF,D0,BE,29,B6,EC,C8,A2,F9,FE,0A,B1,6E,81,F5,DA,52,0B,54,F7,8C,1C,DE,3A,67,1F,4D,73,FB,05,AF,12,F5,B2,9A,98,12,71,64,0A,6B,97,D3,FC,D4,91,1F,EF,5E,65,C7,0F,2B,5B,B8,39,C5,58,1D,C0,00,34,FD,59,09,CE,4E,E7,13,29,3A,3E,C5,DD,32,F5,97,A5,EB,13,7A,7D,72,9D,B8,6D,65,28,00,E9,E8,CF,66,00,5C,76,E3,56,BC,BF,A4,15,30,50,36,0D,59,90,4D,5C,3D,BD,83,9F,15,BF,00,9A,CD,A5,27,AE,BB,2C,91,1F,F6,BA,7B,69,10,07,30,47,77,5C,AB,92,F8,44,31,E9,63,CD,19,7C,7D,F2,2B,21,54,9A,B7,DE,67,B3,AC,40,0A,A4,82,0B,9F,3A,A0,97,21,2D,7F,0D,D9,61,5F,E7,52,0B,35,2C,5F,F3,F5,C7,CD,84,8E,71,CD,95,96,2B,02,20,60,80,D3,FD,6D,61,0E,48,31,DF,37,3A,95,EB,0B,E5,AC,3B,06,71,6C,8F,B5,CB,F8,91,59,C4,85,B8,32,91,58,CC,82,35,07,59,55,A8,4C,6C,7F,E6,5C,32,91,CB,3D,18,F9,92,B2,12,DC,4A,BF,59,D2,D4,BC,6A,89,6D,4B,55,5F,06,D3,39,4C,56,F8,73,44,40,6F,D9,62,08,1D,78,EB,40,C4,BA,37,88,63,98,87,25,86,BE,C9,C6,D0,30,6D,40,23,53,E8,47,83,B9,CA,BC,FF,3E,AF,B1,F7,2A,C1,9B,40,3E,7B,F7,20,42,7E,06,CD,CA,9D,EC,57,F7,48,E0,50,87,07,53,15,83,B3,21,D9,F0,D1,6D,48,E9,CE,39,12,A9,63,50,FA,B6,CF,31,E7,E7,8F,72,3A,3D,91,A2,C4,A2,B0,AB,87,05,9A,D4,6E,03,1E,BC,2A,AD,7B,72,0F,13,8F,C7,76,46,4E,4C,AB,6A,B3,F8,00,F1,EF,75,1F,55,EF,E7,52,82,05,4D,E4,20,E6,15,34,C5,76,DF,50,64,A5,D5,E4,7C,B8,77,2E,31,CC,C6,D0,D5,7B,B9,59,75,93,BE,15,FE,1F,D5,CE,01,25,AF,68,0C,52,33,AA,B9,A6,BD,8F,4D,5A,22,06,8F,CB,5B,9F,80,D0,7F,9E,B0,61,7C,83,25,6D,A3,74,4F,0C,7B,9D,D4,EB,B7,7C,DD,97,0B,BE,AB,CD,2C,41,AF,13,4B,81,44,55,F7,59,86,88,00,7F,A3,DB,11,C7,5B,81,A0,9C,5B,DD,1E,55,22,9F,88,A2,62,4F,AF,ED,83,21,0F,2A,5A,B3,03,70,75,A7,47,16,4A,14,F8,AA,EF,58,FE,E9,07,9E,10,B0,87,42,FB,EC,36,57,D6,5C,12,48,35,E9,61,89,E5,5C,37,C0,8B,03,FA,FE,3E,20,A9,05,49,94,C9,B4,AF,CF,04,42,2E,FE,BA,E0,8E,C0,D2,61,56,1F,4C,F1,74,9E,53,46,5D,1A,72,35,4F,F3,B4,18,87,16,8A,3A,F4,A8,01,92,49,4C,BF,48,C9,5F,30,A5,E5,51,A6,47,AB,C1,EC,B2,DA,AE,47,45,0C,EE,5C,C4,35,1C,4B,CE,F0,5D,A1,54,BF,81,70,19,25,A1,73,5F,7E,19,56,EC,8A,3C,17,AC,42,26,26,89,BB,26,4E,1A,79,DE,CC,D5,19,C4,D2,FF,B4,00,BE,2A,3C,1D,B8,05,1B,A0,19,F9,8F,8D,1D,B0,70,02,00,B8,FE,2D,F7,26,A1,B3,65,E7,BB,EC,AE,AA,BE,99,86,AE,F1,B5,95,F7,D8,95,C7,67,E7,C1,53,0B,11,78,B3,67,F2,DA,97,51,0A,5C,C5,F7,8E,E6,29,FB,9E,22,8B,D6,A4,CE,C5,FA,F1,24,9C,B9,C8,17,2F,31,90,5A,06,6F,CA,1B,3E,FB,1D,DC,96,01,D6,C9,04,4C,30,82,67,CC,DA,82,B0,C0,7C,5C,CF,13,C2,2D,B6,BB,4F,AC,3C,7C,C8,1B,A2,E2,6C,5E,2A,A8,C5,4E,AE,07,5A,CD,FF,63,69,33,FD,F6,3A,1E,D2,40,AD,64,DD,19,13,B0,36,A3,6E,53,C3,F1,B5,B9,85,E3,B8,D9,89,89,CB,F9,58,36,C6,EE,7D,18,03,DC,81,BC,54,8C,16,D6,16,AF,27,CC,90,18,E2,2F,D0,5A,89,46,A3,95,91,23,02,FB,76,92,61,08,D3,7B,B6,CA,80,A8,C1,7E,21,59,26,47,A8,57,89,F2,B7,D5,2D,B5,27,1D,DE,96,F5,F5,B9,0E,BE,EA,50,CA,01,4E,6E,A4,19,79,9B,F6,F7,6E,C8,B2,74,0F,E3,0D,54,FD,D4,2F,F5,7D,73,38,9B,1F,97,ED,2D,FB,10,BD,EE,97,E9,A4,A4,79,23,BF,B5,BC,94,DE,B6,30,B7,49,6E,A0,05,82,CC,5E,A0,D7,55,75,D4,9C,5D,71,05,07,7C,48,93,EC,8D,4B,9D,46,A5,75,DE,FA,56,50,3B,67,49,F6,A1,DC,D1,DB,AB,DF,98,E4,4A,CB,C9,11,DD,FB,2D,79,D8,E5,6F,09,CE,66,5B,FB,E3,ED,3B,55,29,A0,80,28,6E,02,A9,E5,DC,54,1B,05,A3,56,27,23,40,32,EB,22,88,0F,36,BA,7D,DD,11,FD,A7,C7,86,24,5D,AC,25,6D,FF,E4,FC,F1,63,39,7E,82,C3,D6,62,A3,E7,31,8D,0B,B1,F2,05,18,A4,50,A9,A5,87,06,04,7D,88,8A,CA,11,40,06,FD,32,E5,2C,58,0C,A8,D0,88,47,82,30,8A,BE,43,DB,D7,44,91,E7,61,E6,EE,23,78,DD,56,97,15,BA,D6,81,8E,74,CC,13,A2,FD,5B,BA,68,D4,F8,96,78,66,EB,77,DE,C9,A5,67,CA,DE,EF,B6,60,3D,7C,E8,42,89,E0,62,2B,DB,ED,2E,9A,8B,5A,10,AC,95,7C,4C,F5,14,52,95,C7,04,50,05,41,E7,EC,03,8F,52,40,EF,D4,3E,FB,C7,ED,14,B4,CF,9F,B9,98,3F,45,A6,8C,83,3B,E1,80,7F,B8,BC,92,57,24,C0,D5,6D,73,7F,C4,85,15,43,88,8F,2E,A2,6D,AB,D9,BF,C9,0D,5B,93,9E,0D,44,CA,97,2F,B7,86,0D,FD,39,98,CD,4E,5F,51,49,F6,84,D1,E0,DB,B8,54,6D,E4,10,59,9E,17,1C,55,6E,38,05,86,B9,2C,24,79,97,F6,DF,15,39,98,A5,B6,09,65,B0,89,1D,11,0D,43,6B,FF,FE,D3,EE,C7,FC,CB,B5,65,19,84,43,FC,0F,8F,C1,78,B5,F8,75,AB,15,2C,D5,44,FF,7D,65,C2,F8,5A,98,5F,6B,1E,E2,A0,25,F7,47,C3,45,7B,D9,64,7D,D4,75,22,77,30,B9,4E,67,FA,A0,72,0A,C3,CD,10,1A,79,F2,B5,4D,4E,86,FC,6F,EE,83,71,50,3A,F3,1A,20,04,80,F0,CF,70,B1,F6,F8,91,C7,8C,2C,0F,85,8E,06,CA,54,2B,96,38,0E,8B,3B,84,0A,3B,1A,4A,51,D3,C2,23,87,54,D5,2E,A2,3E,67,6B,6B,0F,7F,F1,30,D5,38,3B,7C,E6,66,24,76,A0,BF,22,97,4C,7A,53,BF,0D,6D,C5,00,9B,FD,A8,D5,90,BF,9B,BE,E4,69,84,6F,08,46,97,3A,B0,8F,AA,93,DB,FE,15,AC,2A,0D,23,F4,5C,88,70,1B,03,DB,9B,B5,21,83,0F,15,8D,B9,48,B8,79,6E,E0,4A,D6,51,1A,CC,9D,65,49,95,01,8D,3A,48,EA,5B,28,E9,8F,E1,0A,9A,01,23,75,D8,C8,3F,9E,DD,8B,49,D3,F8,A5,3A,80,C7,09,1A,EC,8E,74,AD,3F,6D,4D,77,18,D9,CB,48,13,D3,60,F7,65,BA,33,BE,F4,8F,FD,24,43,35,B2,62,C0,BA,7E,AF,3B,B9,E5,73,9F,09,8C,60,71,92,0C,42,A1,47,22,D1,50,63,88,97,F1,5C,C1,C6,23,21,EE,BD,E9,6C,EA,C1,C0,67,16,30,A3,D4,D5,1C,9D,F3,FE,00,5D,97,84,67,7A,68,6C,9B,BD,E0,96,07,1F,7E,EF,07,17,3E,F2,5E,4C,65,C3,8D,FB,EF,F9,00,4E,B3,E3,14,7B,EB,9E,5F,09,FB,34,71,C3,D0,CA,0F,72,A8,9F,0D,14,2E,45,73,3F,91,A5,1A,81,81,FE,12,86,2F,5D,78,A4,F7,56,D3,C5,3A,9F,11,5C,8D,B3,61,0D,4E,50,6B,46,44,99,35,C6,45,D4,CC,26,D5,A7,D8,1E,6D,F3,09,06,F9,4E,64,D9,FB,6A,A5,9F,CB,AE,F4,FA,06,6E,34,D7,AF,9E,13,8D,33,C4,C3,FC,D4,1D,7C,F8,91,A3,22,77,55,51,F1,40,A2,23,28,3A,93,B9,C1,77,BA,DB,57,85,14,DE,3B,E1,C1,B8,2C,EB,D4,2E,76,8E,F6,61,AA,BD,B7,69,B3,69,EA,BD,2D,AB,9F,40,43,FE,77,D8,5C,28,F8,98,35,2C,75,52,E4,C1,21,5C,AF,5A,C9,BF,A8,91,48,F2,9F,4E,AE,F4,D8,24,C9,21,D4,E1,CC,D9,6D,2E,A0,B1,B9,EC,AD,5F,F7,2B,ED,94,9F,6C,50,30,55,6F,3B,0C,15,27,BF,DE,9E,C8,2C,66,C6,C9,6B,A1,50,58,CB,7B,CB,AC,97,2B,39,7D,6E,38,E0,58,F2,F9,0C,64,CF,20,A6,C2,27,20,5B,1D,6A,56,77,FC,EE,BD,B5,A7,EA,D3,07,F4,4F,13,ED,81,73,99,39,B9,77,BB,72,0C,2D,25,82,9B,D7,8F,C9,7F,1B,0B,80,C3,2B,49,62,2F,7C,79,13,4B,AB,C0,A0,93,76,09,A7,5F,82,CD,33,8D,42,0A,00,EE,FA,6F,63,4D,94,F0,EB,EA,75,62,AC,56,B5,2C,D9,03,4E,AF,E4,0F,32,BA,9F,96,39,F6,D7,61,C2,A7,C0,97,1D,EC,2D,B2,67,96,F7,22,22,11,E7,3F,30,00,02,2C,93,B4,86,1E,52,3B,78,42,E3,95,C9,5D,00,67,00,2E,F7,69,BC,C4,87,79,F4,06,10,85,23,08,12,AB,08,32,EF,55,D8,40,A6,EE,DF,0A,5D,5F,D3,9B,F9,F4,3B,A2,2C,FF,F1,15,AB,F1,99,7A,90,13,23,2B,6B,A4,58,AB,12,CE,7F,E3,23,6F,0B,58,D5,20,91,CF,5C,D6,A3,B7,BB,33,01,DD,A4,83,C1,CC,CF,71,77,2D,7A,E9,F9,73,9A,9B,FE,2D,17,4C,58,35,48,95,14,EA,72,73,B3,73,2B,84,DC,6D,EF,D2,CF,08,72,F0,7B,66,C6,70,3F,C1,88,94,41,30,A5,2F,BC,E5,68,FD,D0,97,BB,A1,DE,68,7F,56,0F,BE,DE,FD,A2,85,26,AC,FC,D3,19,07,4C,21,EB,1A,C5,31,BC,62,5C,E5,48,D5,8F,AC,10,96,4E,FE,BE,85,28,6E,5D,5B,7A,04,5D,E8,46,DE,F0,00,A6,3B,6F,8D,01,74,74,69,BC,35,6E,BB,87,83,20,8D,1B,B7,BE,1E,CD,A0,7B,BF,1D,91,A0,DE,59,CA,7B,65,AC,72,E1,50,82,F6,3F,E3,5D,FA,6E,22,F9,F2,F5,F9,79,57,96,7B,9C,87,0F,5C,D6,93,51,32,4B,15,02,4A,76,6D,BC,06,95,75,60,39,BA,8D,E5,D8,DE,C7,8D,F3,78,93,77,AF,3E,41,1D,4D,C1,23,16,D7,6B,7B,08,B4,D5,0F,0C,7B,68,BD,AE,E1,15,8D,3B,DE,88,A1,8F,6D,58,27,D2,9C,E0,3E,57,41,7E,48,BE,69,C1,E9,8D,C0,8F,97,EE,0E,98,B1,02,19,B8,88,3D,89,17,58,90,AD,0B,44,10,42,5D,E3,EF,51,AD,CB,6A,B1,37,3F,55,55,CA,35,20,B4,6A,7C,F4,84,68,D4,27,C5,8C,39,D4,96,9B,79,3C,40,A7,A0,13,62,92,72,2E,81,89,43,E0,35,92,05,12,2C,66,1B,1C,8B,92,8D,BE,72,08,2B,3C,D6,9C,E3,98,1B,99,8F,14,56,0E,6A,36,0F,AC,49,37,1C,27,36,AE,5C,2C,28,B1,14,29,39,DC,3E,64,D8,E9,3F,A7,ED,FF,BF,E0,3A,97,C3,48,07,72,5C,50,41,85,25,55,88,1D,FD,57,63,4E,37,04,F0,7D,DA,BC,AD,14,2C,90,F4,D3,9F,BF,00,92,D1,90,9E,70,10,09,FE,AA,14,BC,AC,34,D1,37,BC,93,DF,9A,39,27,4D,2A,EC,1C,1C,4A,F2,BA,18,53,5A,D5,09,A6,C3,8C,3C,27,F9,A0,3A,D7,63,B8,6F,7E,E2,91,35,2B,40,16,68,6D,1A,9F,83,22,72,76,CF,8C,65,4E,30,FE,98,72,72,5D,E3,E4,CB,F9,44,76,20,05,6C,EB,2F,26,FD,B6,26,B6,2C,B8,AF,07,05,32,80,E0,D3,EA,3D,7A,8C,68,A6,29,A8,ED,B5,FF,03,04,AE,BD,C4,45,BE,F3,22,D1,DB,8A,CB,67,CF,1A,C2,33,A5,2C,1F,B0,7D,7D,DA,E7,BC,47,02,5D,82,C7,45,5F,B1,4E,AD,A5,8C,3F,3F,AC,25,6C,4D,7C,2A,5E,93,35,CE,7F,BA,AA,B8,20,55,DF,53,36,FD,89,F9,90,A5,EE,9F,E2,98,0F,86,74,BE,1B,42,7A,AA,A0,4A,70,D9,ED,48,81,60,1E,22,63,CD,84,C7,25,CF,32,94,CB,DC,2A,A3,22,D2,D2,28,12,32,A7,F8,60,C5,3B,92,DF,11,2B,1B,82,71,74,0C,DB,AF,8C,85,28,B2,2F,39,44,85,FB,70,13,11,1B,FE,13,39,DB,4F,62,B6,97,DC,B8,7D,0F,1F,8A,85,14,BC,D3,5F,F6,08,05,CA,7A,6C,A4,3C,50,D0,31,D6,F4,61,29,94,96,F4,C9,35,32,C1,F6,21,DA,A6,94,9C,20,62,11,0D,40,A8,53,D9,E0,6B,D1,5D,93,2A,31,91,F6,89,FB,3A,6E,21,A3,41,3D,5A,B6,D3,63,05,CF,E6,5A,B0,80,95,31,7D,6E,6E,B0,81,2B,52,23,1A,CD,07,54,CC,90,3E,6F,A4,AC,04,B7,CB,4A,D7,1C,8F,C1,13,C7,C9,F8,38,31,1D,F0,0D,71,48,19,42,21,A4,55,DB,8B,F2,23,9F,93,B7,EF,3C,74,77,A1,4A,5C,42,E7,9E,FC,F7,D2,FD,05,F0,8C,82,1E,24,72,AA,7E,BA,64,69,83,CD,74,E7,32,0E,EF,4F,A4,50,18,F0,73,3F,49,39,F3,03,C7,35,F0,FC,71,3D,07,08,25,FF,67,5A,D6,D6,A0,7D,11,32,EC,D9,98,95,17,FF,C7,50,2D,58,66,FC,BE,4E,C4,6A,CE,62,FE,9E,E7,58,C1,D1,99,1E,59,3B,D0,A9,DF,66,78,9A,24,8E,48,FB,31,03,F5,1A,9A,C3,BA,D4,7B,29,C2,25,46,D2,85,E1,DF,3B,61,97,A8,D2,46,E2,CB,2A,BC,49,3E,3E,E6,67,FC,9E,DE,99,A7,98,73,65,88,CB,DB,35,26,F8,77,50,D4,DB,4B,3D,98,58,30,84,5F,C8,21,9F,CE,59,62,86,9E,1C,D7,88,A9,45,76,72,80,5A,AA,82,C2,3A,93,EA,71,63,6E,34,F2,D3,BC,BB,F4,DD,D8,AA,B2,56,BE,28,2B,BC,8B,FB,80,93,61,46,DC,55,15,BC,BA,21,07,D4,46,29,34,79,F3,B1,40,58,E9,98,2B,01,9B,1F,FC,42,FB,0F,42,1E,D0,DC,9D,61,66,C0,68,74,31,5E,5F,5C,4C,1E,14,CF,09,B9,3F,E1,FF,39,16,49,8F,E0,F8,14,24,D3,6B,93,B5,A4,EB,0C,7B,1F,79,7D,A6,62,53,F5,19,FD,CD,91,24,5C,32,10,F7,A1,DF,6E,41,ED,CF,2F,95,BE,97,8A,5A,6B,A0,A8,47,39,EF,96,25,B8,94,B8,41,3E,18,BC,6F,73,41,AF,F0,DD,EB,8B,42,BA,18,B5,C0,5F,04,8E,3C,DF,09,92,52,C3,EA,D9,C1,E0,AA,C0,AF,D0,99,28,AC,2D,FA,3B,1C,27,6F,BD,D4,5B,42,69,C5,1B,AF,85,05,CC,EA,AD,3B,22,0D,05,5B,42,53,A6,09,BC,7E,A4,C6,93,4D,13,B1,D6,B6,83,C5,1F,5F,85,08,37,11,28,40,A8,A2,14,C6,3F,12,A8,DC,A2,4A,94,1B,28,12,29,43,AE,13,8C,08,70,F8,6E,00,07,E4,D2,BB,2B,70,17,92,0E,E5,42,AB,50,EE,36,27,18,25,4A,76,D5,69,A2,2B,B9,C4,A6,16,D5,43,2D,BA,8A,F9,AF,53,AC,98,AB,FA,3C,4B,3B,03,7B,A2,3E,24,EF,B1,AF,C7,7C,5B,5F,F3,25,F4,7B,90,61,2F,EA,1F,A9,B2,36,AD,9F,FB,DC,14,6B,CB,F3,5D,0D,F0,CA,3E,CB,77,1F,50,5F,75,24,99,D1,9E,D0,83,7C,5F,AB,66,FC,94,AD,75,1C,6E,03,0D,F8,F0,30,F6,B7,FC,0C,CD,F7,92,45,CC,BB,8F,84,81,F3,45,BD,0A,38,F5,98,FC,29,92,66,11,7E,3A,3A,F5,E5,B6,3A,83,17,F4,E5,69,F9,43,2D,34,6D,32,E7,95,6E,BD,B5,F2,DB,CF,0C,6D,65,EF,10,C1,DB,8D,7E,13,6E,65,2B,32,FE,47,A5,03,A4,42,02,37,2A,49,72,7B,54,5A,FC,F0,22,6B,0F,34,96,6B,8E,96,DD,74,86,A1,43,52,10,10,60,47,5A,E6,2D,66,1A,0D,24,94,2C,5F,C4,13,CD,31,9A,6A,F7,5A,B1,2A,FE,95,90,1C,33,63,C0,AF,BE,3D,74,B5,E2,35,37,34,06,B4,03,64,50,EB,A3,74,70,AF,A2,67,C1,56,BA,91,93,69,75,06,28,EE,C7,42,A4,23,1B,41,21,90,42,A5,F2,33,05,0E,0C,F4,70,4B,06,3D,6D,BF,13,6D,29,1E,57,8B,73,E3,45,F4,2A,E7,64,1F,8C,9F,17,AD,0C,A4,1C,31,E0,58,02,A6,6C,3B,90,1F,23,CF,D3,03,62,EA,31,8F,A9,91,A9,CD,69,1A,8D,8A,24,D7,91,27,B1,5A,20,E8,D8,55,17,19,4C,60,B5,E7,40,B9,D8,42,E9,B6,65,7E,5F,D2,B0,33,D5,35,63,AE,B0,3D,9A,7C,8B,9F,89,BF,B0,D0,0D,C7,87,C6,33,46,E7,F9,4F,4B,67,D2,67,57,CB,8E,7C,1C,FF,C0,CF,5B,62,D1,10,12,C7,8A,78,69,B8,AE,BD,12,25,36,5C,9A,7B,59,18,E0,55,4B,3F,6C,67,43,90,F1,A1,E3,DE,28,49,D8,09,FB,37,90,50,98,C7,5C,2B,5C,18,D8,58,B9,4C,07,83,6C,CF,19,A6,24,20,3B,4D,C1,96,C3,1C,35,79,CC,F3,BA,BA,28,45,77,F7,76,1B,6F,4D,9B,B0,08,47,D8,38,3C,52,50,AA,83,B3,46,8F,F3,BB,89,31,2F,B8,ED,1A,F5,52,D6,F2,EA,1D,ED,43,30,17,66,76,33,35,C9,7D,FD,91,7C,52,5F,91,CD,B2,75,C5,7D,4F,E2,A9,CD,67,6A,07,D9,17,67,98,0D,26,AA,F5,28,A9,70,D4,D3,0F,4C,A4,C3,22,30,89,57,1C,83,8E,C0,67,F4,4F,44,23,CE,26,17,83,9D,60,0B,EA,E3,68,8F,90,CD,F3,97,B4,B1,E6,CE,1A,51,31,C8,79,CA,B4,08,A5,17,ED,97,8E,B1,14,30,3A,A3,B3,0D,18,C6,58,4C,0A,29,75,A7,5A,9F,A3,03,6A,31,3F,CA,6E,D3,8D,9B,50,5E,1A,4F,45,A1,19,E6,82,49,87,89,D1,D9,B5,F2,00,94,E4,6C,1D,FF,5A,0E,62,95,80,08,0E,BE,08,36,03,25,A2,F1,57,60,6E,5D,5F,15,D8,BE,F2,EF,DA,0B,E4,1C,4A,25,52,E2,AD,D0,E3,CA,A9,8D,39,21,13,9B,3E,65,A1,35,DA,79,80,19,E4,B0,9C,DF,3B,42,BB,19,D7,75,D2,AE,52,F6,E0,61,E4,D0,91,CA,86,7E,07,0B,A8,CD,D4,2A,19,CD,8F,72,21,9A,0B,C6,55,48,FB,4B,4E,01,FE,98,1A,72,CC,64,6C,88,CD,A9,4A,76,B1,D9,74,9E,3A,4C,5C,92,04,92,D8,B6,B7,2A,6E,B1,69,17,CF,DA,9D,C3,23,11,58,D1,76,B9,EC,91,AD,D3,74,C5,77,19,D0,64,BB,BB,51,8B,2F,3E,FD,AF,2D,75,C6,B2,E1,99,7C,23,26,0B,0D,4E,B7,76,5E,06,E4,E7,1C,27,B1,F1,95,5F,2C,17,EF,28,74,AF,66,4E,1C,54,4F,E7,E3,65,44,E5,BB,67,76,C8,C0,8D,A3,AE,3E,9F,1C,E7,09,46,F8,71,8E,08,31,A7,AF,DF,F5,4D,49,B3,39,8C,67,BF,3C,0C,7D,6A,D0,98,76,56,B0,32,90,DF,65,30,BF,8B,88,EB,C1,06,27,13,A9,1D,EC,6C,9B,72,0F,E3,17,B6,99,68,81,83,03,4A,7D,5D,8A,17,8B,AD,CD,3A,A3,68,FC,3A,89,45,94,01,43,5D,06,75,E2,2D,1E,C4,B8,CD,15,02,49,B1,61,D6,70,D5,B4,3A,09,CD,58,4A,A4,06,8D,E3,F1,39,6A,6C,AB,E5,DE,B3,63,55,24,43,DA,88,C2,CD,D0,C2,63,16,E1,51,55,35,4E,1D,10,B1,52,48,4B,74,90,62,8C,8A,FD,D1,A3,83,3A,5D,3B,CE,FF,3D,BE,A0,04,DF,70,0D,6D,71,27,6E,0B,8F,4B,68,D3,6B,52,41,FE,87,3C,51,CF,C5,89,01,8A,BD,8E,9B,4B,D9,EF,F2,1D,B7,9F,53,1D,5D,E0,EB,A8,29,90,A6,A4,EE,E3,A9,3C,6C,E5,F2,CC,4E,DE,FD,DB,1C,9C,64,7E,8A,D9,FF,C8,ED,E4,63,76,55,77,D1,1E,5C,F1,20,6D,A9,81,C5,D6,DE,A9,68,26,08,E8,2D,D0,7E,B5,2F,2E,35,7C,E8,B5,88,D7,78,9A,55,B8,9B,C6,D3,AE,E5,9C,92,E5,71,39,77,CF,60,D5,EE,D8,F2,55,6E,45,83,D2,B9,81,6E,C8,E7,26,EA,2D,B1,8A,1D,35,2E,39,2F,04,C7,25,C6,C9,CB,BC,BB,0B,45,20,A3,06,9A,4C,D1,67,4D,71,9B,6B,72,8A,7A,4D,2A,43,14,17,DF,39,6C,72,BC,C1,82,6B,98,7F,BE,39,87,73,88,EB,DD,B1,9F,D0,D8,A1,A1,10,6D,18,90,02,12,D6,60,8C,D6,3D,EA,1C,FE,45,92,78,3E,8D,59,27,0D,2A,CD,6D,44,D5,E0,8A,BE,52,8F,90,83,FC,92,7F,45,7A,45,F1,02,B1,40,ED,C7,38,F7,65,02,64,77,B4,7E,9B,A6,96,70,29,E2,E3,6F,80,9D,57,BE,74,7A,56,B1,71,A9,42,CF,59,3D,59,1E,D0,87,5D,D7,C1,42,63,B5,39,58,17,80,E3,5F,46,BF,B0,5C,2D,08,4C,B0,F5,00,6B,59,2E,8E,91,4B,D1,CB,97,9D,69,5C,90,F6,0D,D7,42,81,96,C6,6D,03,D6,3C,17,5E,E6,71,18,6C,60,86,BD,43,44,E2,F5,57,9B,AE,DE,42,CF,8C,7E,3F,11,71,9A,8C,89,E7,62,AD,A1,93,F6,AC,BA,70,30,0F,90,AD,68,97,D5,35,73,58,D9,9D,0D,22,90,06,0B,39,3F,30,5D,AE,F3,3F,15,B2,BD,40,CE,AE,E4,5B,FE,5D,35,E5,18,39,44,52,EF,B5,36,BD,1E,ED,EC,B4,CD,99,B0,86,96,18,3A,70,C9,D6,B4,F5,AE,16,6A,46,92,A9,4B,CB,DE,9E,D6,31,49,B4,61,5A,25,02,C1,E6,C3,B8,55,F3,AD,69,E3,6B,AE,C4,4A,2E,8B,47,C5,BB,2A,80,5B,3D,76,E8,37,00,3A,36,4A,A5,B3,93,CC,0B,D9,45,39,A7,87,DE,DD,6B,F3,5D,46,3B,91,7B,36,AC,E5,07,98,92,1F,15,01,6F,C1,74,8C,69,33,7E,4C,2C,1E,B1,FD,0F,3C,FB,F0,16,CC,78,6C,FE,7C,1E,32,C1,7D,A1,CF,4F,55,1D,B5,6F,62,03,F0,7E,BE,C0,7E,C9,66,80,B7,3F,31,E6,C2,AE,64,67,B0,7A,EA,64,1F,6E,06,52,F8,0F,83,D0,8F,00,71,89,CD,B2,43,4B,E0,A6,2B,E3,4A,4D,3E,61,BC,C3,7B,06,3D,B9,99,78,E0,8A,AE,EF,8D,DD,AF,BB,C0,10,19,B2,E5,BA,90,5B,08,C0,F5,D5,6B,D8,4D,B4,86,5A,36,DC,56,DC,67,8C,F0,93,E2,94,78,F7,0C,60,ED,01,F3,10,25,F3,96,24,19,55,42,F0,65,50,FA,35,39,F5,B5,E3,DB,E7,69,35,96,D7,6B,91,66,8C,D0,17,34,9E,31,5E,70,7C,BF,88,82,DA,3C,D0,37,01,7E,B1,CF,51,B4,7A,FD,15,29,10,55,5B,68,AE,B6,B4,1E,98,6D,A5,A4,B2,CF,0F,9E,04,5D,4F,12,AE,12,12,28,AA,01,24,0B,E4,8C,FA,F3,38,2A,4E,30,AD,2D,59,58,D4,64,4D,23,7C,37,5C,37,44,DD,3E,80,C3,20,84,D8,68,02,F7,8D,31,98,DF,F1,D4,C9,4E,FD,9F,A8,E6,66,8B,1A,14,EE,51,95,BF,D3,76,86,BF,E0,81,31,08,76,85,27,7C,60,BB,FE,9F,EA,7E,CD,D3,4C,0F,5B,2C,68,BB,5D,C2,5B,04,7E,C0,6B,73,4E,A6,34,69,2F,FF,26,94,84,5B,A4,1A,CA,48,25,C0,C0,C5,29,4C,EF,25,E8,D9,29,E9,59,74,37,29,26,6A,95,1A,D2,A9,6F,54,81,F7,06,7E,B4,F5,B5,AF,97,E1,36,7A,B1,2D,1E,D9,F2,66,22,FD,DD,3F,3E,A0,64,F0,00,F1,02,79,4A,E7,36,F3,62,C1,28,F9,B2,40,C3,9D,B9,84,EF,60,74,E7,B6,07,CC,9F,4B,DA,C0,19,68,65,6D,F5,6D,47,E1,0A,8F,63,78,A8,A6,19,8C,9E,80,20,EE,37,6E,B7,90,5A,E0,3C,0B,28,98,F2,31,DC,0C,65,77,D6,4E,3D,15,80,35,32,F6,5B,1E,79,9F,46,14,B2,14,B8,BA,62,04,98,26,84,6C,04,A8,70,1A,31,16,D2,92,38,86,D5,29,5D,91,5B,EF,35,26,01,A6,15,6C,93,E5,61,EF,B6,88,E6,B2,A0,7E,1B,79,5B,E9,BA,50,7B,43,77,23,4D,44,CE,86,7E,1A,D4,F8,4D,76,B2,0A,94,5D,4B,89,65,E2,B7,0A,5B,D7,C4,F4,F2,82,C2,38,5C,F4,81,45,D9,2A,4A,B5,82,8B,18,FA,36,F4,E1,85,D0,D5,0B,2A,75,36,29,26,21,A5,6D,79,25,FC,7F,66,96,51,9A,F9,9F,25,DB,7C,EF,B9,62,B2,58,42,BF,1C,1B,01,68,7D,45,C4,AE,C3,16,C0,AB,1E,35,4A,92,5F,78,A6,32,CE,4F,A3,3F,54,F1,70,2D,9C,DC,F2,6B,FA,11,B8,E2,22,29,C7,F1,05,2F,81,95,1C,FE,39,31,B9,55,2A,D7,F6,99,0A,D4,0D,0F,4C,8B,15,7B,83,54,02,5D,03,6F,4C,BF,95,01,5B,18,31,F7,0D,82,5B,C0,E9,42,73,08,ED,A7,31,C4,0D,D6,D5,12,83,0E,22,DA,57,3D,E1,D7,89,B1,06,E7,51,B3,03,17,B5,F9,6C,59,E1,45,68,5B,80,65,8D,E7,F2,78,19,BC,FF,C4,31,C7,50,F3,23,2A,C5,13,1B,C9,B7,BB,F9,54,73,AC,C7,DE,76,D7,8B,88,8E,E2,44,05,AE,F5,44,CE,C6,75,EC,A0,72,D5,91,4E,8B,2C,AE,5F,CB,11,2E,7B,93,B8,4A,36,69,C8,1E,1A,F6,A4,5A,D6,EF,CA,7E,4A,0A,B0,20,57,A1,FB,B9,D1,7F,BB,6E,40,78,37,86,6C,72,69,FB,DE,BC,0A,F3,05,FF,37,88,8E,FC,39,45,3F,B4,B9,65,E4,1F,08,A8,A4,EC,BC,70,75,94,F9,DE,82,82,1F,EE,C8,D7,D7,54,A2,51,8D,16,6C,8C,C7,BB,49,35,AA,B8,26,DD,C6,45,90,3B,D9,9A,A1,CB,E8,50,B2,C0,07,8E,CF,C5,86,30,4E,99,6C,C6,17,97,06,CA,FD,C2,30,F3,8F,9B,19,43,E3,B9,3F,C3,68,B5,83,26,91,A1,86,4F,79,F4,D3,65,98,C3,5C,92,28,CB,0B,08,1E,2B,99,CA,7B,6E,00,43,A1,1D,16,4C,FC,07,B3,49,1E,CB,3F,EA,21,21,25,A3,32,E1,96,DE,21,4B,5D,2D,0E,FA,F6,FC,19,75,66,97,7A,50,7B,70,C1,44,73,BD,B9,58,56,90,6B,0C,8D,58,62,16,19,E9,A7,A2,68,E0,54,4B,EF,16,B7,5A,9E,9B,4C,3F,2E,51,0C,C3,25,4D,17,3F,82,60,C0,83,E4,57,C9,0B,BE,87,3F,BD,14,37,B6,BD,FE,D3,26,D0,B4,DB,14,A1,F5,5E,10,E6,ED,C1,59,21,8C,F8,5D,7D,69,54,C8,C7,F6,63,45,8C,32,08,C5,2D,BB,6E,3F,DF,96,97,94,40,C5,ED,CA,29,25,D4,17,A6,35,9B,FF,61,78,9A,35,D6,24,83,CA,37,FF,3C,61,F4,39,2C,FD,D1,D3,0E,BE,06,70,13,0B,D9,C4,90,FC,A6,1E,9F,BB,76,25,11,28,19,C9,B3,07,D2,28,2B,02,C2,B0,13,D2,47,AF,F7,07,90,CC,50,DD,82,B0,F7,17,DD,D2,3F,B0,CF,B3,AC,07,4E,EB,E2,E7,A6,82,03,4F,4E,98,F3,E8,51,C8,4D,5E,06,6F,CC,BD,E4,88,81,F3,26,3B,69,62,96,A6,F8,8F,63,5B,DD,13,40,02,D4,F0,D4,AA,26,64,E4,B7,38,4A,B8,D4,DF,C2,70,CD,80,3A,89,B2,7D,4D,B0,8C,62,B9,7B,1B,45,DC,D5,A2,C4,B4,E9,7E,F3,B5,82,A2,A2,EA,70,3E,6D,B9,47,96,9F,66,A6,B2,AF,71,4A,42,F9,DE,F6,CD,17,40,55,F8,E3,4F,90,74,2E,75,9B,D9,B4,E0,F8,38,42,ED,34,F0,1C,3A,2D,56,AD,54,C2,9B,96,3A,5A,3C,F4,1A,F2,19,F4,05,68,28,38,70,42,25,F4,E7,6C,37,AF,AB,02,B9,F6,14,A5,86,B3,EA,DB,C4,81,41,67,62,F2,5C,1E,EB,B9,1E,5E,FC,55,0A,AA,C4,F5,7B,BF,2F,B4,E6,8B,F1,E7,D3,BE,27,F5,70,DD,B4,32,43,4E,E6,D9,B0,D9,39,77,A6,C7,C9,F6,98,E6,A4,EE,BA,1C,A0,4D,37,79,AE,3B,ED,CA,1F,C2,77,C6,14,57,99,12,D2,5E,C5,C3,71,96,C0,74,D4,D7,A2,F4,8E,30,DD,40,7D,9E,0D,8F,C8,3C,7A,22,26,F6,1B,2E,62,4D,50,2E,4A,06,2E,BC,0F,50,0C,52,4D,DF,4A,9F,8D,6B,77,08,26,62,56,DF,AB,7E,09,AA,EE,F4,6B,A5,62,58,E5,50,9F,F8,00,8F,A0,CC,58,5F,0F,27,EC,50,49,B1,97,BD,3E,40,1E,FD,CB,DF,3E,84,29,2B,A0,46,8B,D6,7C,79,0C,3B,66,59,FE,A1,10,8E,37,5D,D6,1B,69,EF,89,3E,65,1D,F3,9E,AE,F5,92,80,51,65,EC,EC,2C,E1,16,52,E0,2C,45,AB,71,AF,23,74,0C,8A,A6,E3,EB,EA,3F,1B,51,91,9C,01,A1,46,89,65,1F,F7,09,27,86,C5,B7,C9,F6,A9,9A,F9,02,5C,C1,F4,D6,22,03,55,D7,D7,E9,30,4B,C5,3D,53,6E,74,3E,D9,A9,32,B1,D3,66,F4,39,FB,E6,5B,15,81,6F,40,7B,34,68,EA,5A,C1,02,05,4F,C1,A0,72,0A,09,B3,CF,81,AD,87,AF,3B,19,59,07,41,EF,B7,62,97,01,3D,BA,4D,64,27,1E,B0,F4,B8,E4,14,F5,CC,26,ED,A3,E9,AD,D3,8F,8A,82,23,60,3D,D8,64,B1,08,15,AE,0C,8A,EA,8F,34,9B,1D,BB,4F,E2,7E,A2,85,B6,A8,A7,84,60,6A,A0,05,51,FB,44,E2,3D,21,9D,41,05,30,53,0F,B9,DA,A0,02,7C,27,56,39,22,03,56,A3,6B,5D,16,9E,75,DB,F8,79,4A,45,ED,E2,6C,9B,C7,46,BA,9D,A1,A5,AD,AD,01,01,FF,75,E0,CD,C3,E5,9C,62,01,4D,B4,84,B3,24,C6,67,F7,F1,88,AB,4B,B7,F4,87,A4,38,E6,33,AE,F1,2B,0E,C4,6F,61,AC,C6,37,4E,D3,0F,86,AD,D7,68,AD,ED,E7,28,71,7B,58,63,D2,99,68,08,48,F1,80,91,39,FB,0C,50,2B,CA,65,70,E5,8C,EE,AC,F1,79,28,6E,20,89,F8,3D,92,55,EB,1E,2C,F4,BE,92,7B,B3,D1,F6,8F,CD,FC,62,14,2A,9D,24,B0,62,1C,D6,C6,4E,32,4C,EA,E6,F4,5D,DD,26,3E,B5,DE,F6,38,CD,B0,59,02,9E,F6,F1,61,42,9E,72,F4,C7,A0,EC,3D,45,EA,7F,4A,2F,77,4B,98,06,7B,48,4B,2C,5D,50,95,F7,20,21,51,E2,1A,1C,E7,4A,FB,FD,7C,1C,70,21,7E,86,6E,F1,2A,C1,25,EE,43,21,E3,28,A1,B4,65,7C,FF,99,95,A0,85,01,66,B1,52,2F,65,94,6B,92,2C,15,17,EC,BC,B7,87,9B,F6,B7,D2,2F,1A,C8,58,61,20,BC,93,F1,28,23,8F,76,B3,44,D9,95,17,82,6D,99,02,07,ED,74,B9,74,D0,27,78,16,F7,8E,EA,1C,10,5F,B2,9B,E1,DD,2B,EB,DB,C3,6C,3E,A1,8D,36,77,92,B3,99,9C,B8,C0,7D,4A,BB,F5,03,EB,A7,67,40,E1,B6,B4,C0,D7,86,BE,38,36,7D,AF,E8,C6,06,64,AD,B4,8D,11,40,DE,88,48,4B,53,DF,46,CB,B2,67,97,D6,70,0F,F8,0C,E7,B7,BD,EC,90,52,18,3F,1D,00,E2,B3,2A,38,A9,27,CD,CB,2F,EC,4C,19,C3,85,70,35,14,CF,58,21,E7,60,24,6F,D5,2B,49,E9,93,30,7A,09,59,2E,A7,2E,C3,70,15,CB,F0,5D,26,3C,6D,69,D2,34,DA,EF,0B,D4,00,AC,21,34,86,6A,CC,4F,05,0C,51,89,4F,03,B7,AB,F3,29,3D,E0,D3,19,27,B1,5D,59,C3,A6,00,6D,6E,85,A8,CF,09,50,3B,F3,66,79,D8,5D,03,71,4C,F6,FF,A3,F9,E5,71,41,42,58,55,74,FC,0B,B2,D9,AB,7E,40,E9,51,E4,43,8F,2A,B4,E4,AD,DD,85,E9,D9,C2,A2,2B,6C,D9,5F,B8,B6,7F,62,C0,C9,2F,CA,11,53,A9,56,BD,1F,77,88,28,95,40,F5,A6,75,78,0A,D8,A2,9A,CA,EF,45,6A,8D,62,FE,F1,CF,A8,E1,73,28,98,C7,61,56,51,A4,50,DB,B8,EA,8F,60,86,51,F8,5D,08,BE,97,65,60,8B,F7,81,2F,2C,4E,71,E1,1C,89,95,D2,EC,E0,A4,0B,B2,77,ED,21,B8,F4,5E,34,B4,48,C7,5E,77,54,C3,FC,D7,5D,59,90,9F,20,A1,9B,45,92,32,C9,9F,6B,5A,78,A3,97,C5,FE,4E,D3,5E,7B,BB,7A,26,89,E2,3F,D8,C3,B8,70,8C,D1,8B,0B,21,09,BE,2D,40,9D,78,1E,37,63,77,72,B5,D1,DD,BC,F4,FF,03,5E,CF,3A,5C,80,96,98,FA,95,83,A4,DA,3A,4C,90,64,E0,72,43,B9,24,CD,7A,8D,FA,25,EA,03,D1,F3,67,F8,36,0E,03,96,8A,BD,FE,B2,1C,9C,35,B7,B7,E2,8D,43,F5,8A,7F,4A,DB,02,6B,FA,39,EC,89,A5,8A,43,74,BE,0B,1C,9B,B1,E3,5B,AC,B4,1C,08,16,6E,1A,37,8B,D6,F3,14,7D,F7,13,F0,66,73,53,D3,6E,81,55,7E,AD,1F,52,87,93,21,4D,2D,D2,16,4F,55,50,D3,43,31,6B,80,15,CB,5D,D6,95,E1,74,5B,19,0B,5E,70,62,18,02,B7,76,96,8C,85,DF,32,23,FC,20,56,A2,5D,01,3A,A1,12,EC,CE,B3,37,D6,29,12,3F,1E,E6,53,FE,41,9D,CF,40,7E,56,2A,25,0C,3B,12,37,6D,C1,CA,36,1B,76,06,40,42,2C,15,0D,2E,F8,28,11,1D,45,1F,56,30,B5,C8,96,00,EF,1D,75,14,DB,28,F5,CF,A7,80,CE,F9,61,7F,A0,96,9B,47,4A,74,19,68,D9,A8,B2,DB,38,14,2A,B9,A1,69,F7,87,9E,9B,47,AF,77,AD,E7,82,37,27,45,A3,DE,66,41,ED,FA,06,05,D6,2F,69,7E,D7,20,F6,B8,C3,9F,D2,99,D9,BF,80,32,14,75,84,97,66,A7,64,84,2D,79,52,93,EC,16,A9,3E,A2,90,4A,B9,96,FB,38,F0,6F,C4,50,90,99,A2,9C,FA,85,20,F3,C5,45,1C,9E,7A,85,4E,6F,FD,D7,3A,A1,FB,D1,13,34,31,C3,7C,32,87,27,CE,F8,57,0F,37,81,31,FC,C5,81,7E,83,31,57,11,C0,EB,81,96,D5,7A,4B,BC,57,02,50,05,27,04,11,7F,CB,CD,09,9A,2C,D5,53,36,A5,FA,D1,6D,A8,47,AA,AC,85,6A,D2,7F,33,62,0F,6D,F7,BF,94,64,BD,F8,00,DC,6B,D9,5D,DD,34,03,B7,28,49,C8,36,1C,48,17,C5,D2,A2,EA,F5,B2,2D,4C,6F,2C,DD,BF,74,C0,29,58,1D,12,1B,51,EE,A2,A8,BE,CD,60,98,BA,BD,3B,AA,FB,07,64,B7,88,50,E5,D5,4E,AC,D6,F6,C2,77,B1,F9,77,2A,8E,E4,4B,11,7E,C5,08,F6,DD,1C,5C,AE,EE,E1,A3,F6,F2,D1,16,10,46,46,D9,3B,E8,97,22,48,E2,36,84,0A,2D,30,6F,D7,66,D0,3F,E9,5D,C8,0E,4F,E0,F7,60,F9,25,D9,AF,FB,A5,F8,B4,65,79,A9,7E,85,55,2F,8E,AD,EA,07,DB,C4,91,DE,79,83,88,AD,A3,85,A4,0F,93,55,35,78,FA,B1,74,27,E1,4E,8C,FB,89,5E,3C,2E,4C,ED,41,47,29,94,08,80,69,A4,24,78,AA,65,FE,01,F0,9E,DE,19,94,F9,6A,71,55,2B,0C,7A,EB,29,0F,4D,67,88,47,10,73,65,AE,71,BB,7F,2B,A1,6B,77,30,35,C6,CA,1B,FD,23,81,9E,A2,E1,37,0E,88,E8,E7,15,42,ED,C4,19,95,B4,6E,C3,7C,E7,02,35,1B,0F,45,1D,46,2F,F8,70,4D,EC,83,98,50,60,CE,96,0B,2C,01,65,9D,55,30,26,B6,7C,EE,E5,34,5E,22,1A,AB,53,6A,B8,73,79,2C,C1,18,E4,63,FB,D2,06,2D,D7,2B,D3,36,93,08,D5,7D,08,09,35,32,67,44,3D,61,64,DC,F5,31,72,73,81,28,C2,C1,DB,99,FC,3C,36,E2,FE,52,96,72,E9,35,DA,07,3A,02,B9,C9,FB,AB,C7,F9,76,60,E7,F7,0F,6F,35,6B,A0,CA,48,9D,DE,EB,43,82,3E,9E,22,B9,9F,19,B5,87,71,3B,81,D6,71,96,D5,E5,97,24,8A,F0,08,23,AF,C0,AD,25,28,01,97,3C,9E,21,FE,72,81,C1,77,55,8F,B5,1E,A0,F6,9B,B9,80,F7,A5,DE,7C,5F,75,11,DC,F7,2C,29,00,3F,96,B8,D1,BA,5C,AA,EA,85,B9,3C,26,FB,12,FA,9A,9F,4B,AC,54,DD,A6,BF,00,5F,3B,AE,43,1A,61,47,53,08,2D,BA,CF,D4,3D,82,20,D2,22,F1,57,2F,C1,49,05,80,BD,D9,0B,95,FD,FC,84,A8,2C,94,CE,B6,68,D6,5E,DC,72,C7,39,FC,74,0A,82,B2,DD,8B,A8,A3,0C,42,62,92,9F,E3,A6,64,C7,38,D9,5E,29,C8,00,56,54,B3,69,E1,FC,87,28,AD,0A,85,27,38,55,2C,52,D8,D4,09,CF,D8,04,13,33,E2,EE,8C,A4,66,93,82,9F,49,33,B7,8F,62,FE,B8,1B,BD,47,58,CE,86,A1,14,49,3F,DF,D9,2E,A9,AF,B0,C6,97,68,6F,46,35,BC,FB,0D,02,46,BF,8D,67,31,E8,4A,84,4F,DC,D8,58,C0,7A,A7,D2,5C,D3,8F,73,B2,8D,E1,0B,BD,F5,05,C6,27,38,26,BF,3D,F3,AA,38,A7,32,7E,4A,EB,77,92,A2,C6,41,17,1A,B1,A3,70,B9,6C,E8,0A,6B,4D,63,30,48,E5,27,7C,33,52,97,0A,FE,DC,40,18,90,DD,09,ED,30,31,80,5B,57,13,0D,2D,F7,BB,0C,CF,D5,9C,04,3A,06,41,B4,2B,79,A2,1A,20,43,90,F7,61,AC,30,CB,EF,66,FA,F4,D5,F0,EC,97,86,69,8E,88,0C,C0,1B,4B,C3,D2,7C,75,2A,DE,4B,4C,C5,CC,6E,20,88,E5,B6,BB,73,7F,B3,56,D0,CD,32,1B,FD,7B,00,A3,59,E8,0D,34,3C,8B,61,6C,D5,17,7F,36,D1,D8,87,3E,07,5C,0F,8D,A1,D5,50,F6,34,1F,0B,8C,66,46,AA,7A,6B,6C,2C,1B,FC,AC,27,84,DC,DB,4E,5F,66,46,7B,60,6B,F1,43,62,6B,3D,C1,3F,D7,EE,48,D4,C2,74,01,C5,7B,12,73,34,14,8D,8F,50,D2,C3,65,68,AC,B9,37,BA,44,26,AD,27,85,D8,AD,6D,95,C3,08,62,87,5E,AE,5B,05,1D,E6,ED,70,2E,FE,85,DF,85,93,F6,ED,0E,39,CE,65,0F,FA,34,92,AF,23,C1,97,5F,82,85,F6,8F,14,32,AE,8B,7A,B9,31,79,B9,3F,58,1B,E0,79,44,26,91,BD,DD,62,C4,39,22,F4,2B,40,70,19,E1,16,BD,FF,B9,FB,84,E6,C4,BC,9D,B3,14,40,23,D8,DF,08,A5,8C,32,E0,79,B9,59,1C,AE,C6,F6,E6,6E,53,0C,64,45,3C,B2,6B,D0,13,EF,67,69,5D,AF,8A,8D,46,2B,64,F0,03,37,63,75,EB,96,D5,90,67,93,50,5C,A4,EB,4E,2F,AD,4E,47,60,FC,DD,15,DA,39,05,95,B9,53,A6,DD,44,2C,9A,BE,1F,07,46,66,45,A7,B3,F5,D2,16,FC,BB,FD,C3,4B,51,E1,1D,AB,DE,5B,1D,7B,BB,11,45,A4,3C,36,98,46,BF,59,1C,6D,60,A1,D6,90,88,B3,43,68,0E,68,87,08,7A,3F,24,76,EF,0B,EF,A1,56,19,6A,D4,F4,4E,73,92,49,0F,00,45,56,33,17,16,81,32,92,8B,21,30,71,C0,B7,D4,55,A1,B3,12,0E,78,A7,E9,8D,44,C2,EE,EE,83,1E,78,D0,D4,E0,26,E4,72,FB,64,14,7E,96,24,85,7B,CF,8A,FE,B2,61,81,75,18,34,A9,27,AC,62,1A,8C,67,30,7F,1B,D6,63,40,2B,6C,59,5D,9C,0F,09,D4,E8,8F,64,7F,CB,79,D0,EF,E9,16,82,85,97,44,7C,7F,1D,8E,42,C1,1C,3D,BC,EE,E7,A8,93,11,0C,48,36,A7,2F,5F,AA,E1,85,57,EB,34,FF,89,62,C1,9D,BE,F2,2F,14,97,92,BB,46,EE,B1,6E,CC,4E,D7,D3,9D,14,E6,FF,50,60,F3,55,8D,EA,CA,63,B3,CF,75,6B,70,04,1A,26,F5,61,2F,C7,54,05,6B,92,3F,FB,30,70,CA,CC,D8,03,A0,35,1B,D8,34,C7,8F,35,0B,44,CE,09,9E,A5,16,02,75,D1,31,55,F9,D2,CC,F3,6F,C6,00,48,23,1C,39,98,1D,0F,CB,FC,51,8F,B0,44,90,A0,07,23,0E,AD,04,BF,87,F2,C6,55,79,29,4E,7E,0F,89,2A,FE,7E,08,FC,7D,B6,D8,51,D6,F6,55,49,5C,76,0B,CF,F5,41,EB,BD,54,8D,B7,9F,C7,59,03,68,C8,00,B3,4B,37,D1,2F,66,8B,5C,BA,0E,3B,C8,8B,F5,3B,ED,DE,8B,EB,11,78,69,58,4D,8C,98,30,66,CC,31,AE,E9,2A,8C,61,99,56,86,82,4A,76,3A,1E,4A,A2,BA,26,1D,E9,9F,44,68,DC,E2,C8,CC,39,26,D3,BF,A0,EF,5F,F6,CF,E5,74,8C,32,8F,76,3E,A4,84,FD,DF,6C,41,DF,0A,35,5F,7F,E6,EF,C6,86,A9,F7,BE,51,75,8B,3C,74,4E,B5,C2,67,B5,9E,C7,30,E9,B6,DC,F3,A3,AB,D2,E6,2A,D9,16,00,53,53,54,79,D1,3A,E3,9E,1E,92,EC,ED,93,81,F5,A7,89,C4,51,F7,6D,A0,E9,A3,6F,E9,82,9C,54,6D,1E,DF,98,BE,86,1B,61,68,C3,2A,A3,19,64,0B,23,CB,97,70,69,8E,7C,B4,94,1C,26,47,52,25,06,4D,E5,6B,C4,AC,E9,48,7B,48,54,A1,E0,85,33,23,F0,67,6A,DE,B4,22,97,03,00,88,3B,D3,1E,FE,5D,8C,85,94,6C,3A,B9,BC,88,53,68,32,BA,13,1D,52,9C,2B,5B,B2,87,03,6F,C7,C3,4A,09,EB,B2,65,60,8F,BF,76,BC,48,7F,16,6C,CD,46,BF,FB,B7,2E,CD,17,2D,2A,53,C8,CA,DC,26,1E,B7,F5,5D,09,5F,49,B2,55,31,CB,69,08,58,EF,78,0A,89,53,BC,49,25,32,8F,63,57,57,0E,B1,1A,4E,1E,55,9F,3C,40,38,C1,27,C2,82,EA,A9,8E,B2,2F,2B,68,FB,AC,64,D0,A1,01,F1,2C,16,DE,41,9C,C0,DC,07,AC,97,04,E1,16,0B,04,3C,B2,E7,F5,BF,5F,61,21,B0,05,29,45,9B,DC,4F,F9,D6,B0,DD,EE,AF,97,F9,89,3C,83,DD,28,DD,72,3E,19,4C,E0,08,91,60,0C,EC,58,F0,94,5F,60,43,1B,60,4B,F2,75,D7,48,C6,11,C0,45,5A,3B,44,7C,45,33,70,60,D2,D1,D6,1E,E4,26,37,EB,A1,48,8C,B8,7A,8F,92,16,99,28,E4,DD,88,00,17,67,A7,0F,83,82,B8,D3,EC,E7,47,3E,92,A7,2B,57,E4,2D,C3,CA,37,87,D1,16,D7,E6,A5,A5,69,11,DE,81,B5,94,E1,E0,D1,8A,41,99,54,4A,0B,2E,72,54,2C,96,77,DD,79,58,05,B7,5D,DC,57,0B,42,27,23,A0,D0,83,25,3A,E5,E7,E3,8E,AB,C1,F3,60,2D,EC,44,A6,9F,BA,E0,FE,D6,56,45,23,6F,9F,4B,DE,E9,CE,63,3E,E8,03,52,F0,97,A5,C9,21,DC,6F,9B,C1,CF,E4,39,BE,98,1B,D3,A2,C5,ED,9F,A1,C4,68,1E,5D,5B,47,9B,91,64,5C,AF,46,03,9F,3E,86,B8,AF,28,80,F4,A1,D0,35,B1,06,C1,0A,8E,09,47,66,61,A3,D6,55,69,38,DB,4A,68,A1,8F,66,E8,D3,3E,D2,ED,A8,C9,84,9C,6F,21,63,18,A6,57,0E,B2,F6,B4,FC,D6,8F,40,1E,3D,99,1E,C6,9E,C2,9A,A6,00,4F,94,D2,51,57,83,0D,56,D8,86,47,35,C7,78,09,37,A1,55,ED,70,A9,93,C1,5C,3C,15,A2,E7,1F,7F,B4,13,B2,03,E4,77,72,59,E0,01,69,C4,F2,BA,54,C8,A5,30,87,F9,08,68,90,0E,A1,D3,58,A9,F1,93,64,D3,4D,D5,21,47,32,02,38,21,42,57,41,05,15,4C,02,E2,62,CB,FF,18,74,6A,43,6A,53,68,EB,28,AC,69,5D,E3,40,96,D3,CE,82,89,CD,F6,0C,FA,84,CD,26,BA,08,0E,16,A0,7E,DA,AE,7F,30,53,A3,F8,EE,7F,FA,AB,54,00,66,5F,C5,5B,8B,F3,AE,CF,00,AB,F8,B1,5B,10,EB,CB,EF,18,A2,96,49,D4,E2,2C,D1,9C,11,A3,86,75,DA,BA,65,E1,81,6F,10,E5,97,03,00,B0,E8,59,68,0D,CD,ED,E1,1F,74,0F,30,C7,10,98,22,E7,F0,BB,1B,75,79,6A,EE,0F,92,B0,EC,69,C2,44,23,4C,82,64,1C,0C,95,8D,C6,7A,87,B3,6A,B9,6C,E9,61,8B,A7,CC,1F,11,C7,4A,07,01,24,11,0B,43,A4,54,8A,F7,6C,D2,A2,59,04,C4,94,E8,45,DF,E2,CA,49,A0,02,D1,C6,2F,37,49,C0,96,22,E5,3C,78,51,E1,CC,70,DA,E6,8C,B4,47,09,EB,D0,87,9B,0D,4F,9F,4D,55,78,82,1C,1D,9D,95,A1,05,80,07,95,5D,E1,0D,F8,9E,4A,80,92,2F,B9,D0,A8,21,92,70,31,25,8D,97,15,91,D4,26,7D,3F,47,22,00,E6,57,53,26,6B,EF,D2,64,F3,FC,54,0E,36,D5,1D,03,D5,50,00,D7,BC,19,DA,54,DC,AB,77,51,8F,C3,9C,E4,96,9E,52,3C,F5,A2,F6,4A,93,E9,4B,14,79,D6,2C,2B,C6,95,7A,88,62,AA,E8,1C,1C,83,51,87,07,51,AB,8F,13,DF,B7,42,20,8A,3B,3C,67,FC,89,0B,ED,84,08,2D,28,73,07,9D,E0,3D,E5,59,83,9A,06,3F,B9,BF,FD,88,51,DE,38,A4,16,A1,25,3A,B4,58,07,9E,45,B4,26,0E,FA,74,18,EB,D7,EB,B8,BD,83,A1,E3,28,3E,A2,48,56,FB,5A,0C,AB,09,C8,28,7A,16,01,95,99,FB,CE,42,20,C6,B5,E6,BE,6B,9E,93,21,CF,F2,A3,1B,36,6C,BE,60,39,73,C0,92,66,CD,05,75,FF,AF,44,DF,8C,CB,74,72,B2,E7,B2,EF,84,C9,11,30,E8,B9,B2,3A,F5,07,C5,6F,51,1E,3E,53,BE,62,6C,EF,74,23,50,E5,8A,4F,AD,8A,43,98,6A,6B,83,55,3C,1B,4D,D8,FF,76,B0,62,10,D2,8C,54,C1,3F,0C,60,53,D5,1B,01,00,BD,1E,C0,52,24,B3,23,31,17,A0,46,ED,4D,DD,BA,11,28,9B,B8,98,CB,8F,C9,1F,F2,1B,1D,78,C9,A6,E8,A4,87,91,DF,6B,A9,2E,FE,6A,2B,BD,40,C4,6F,B2,3A,90,2B,9B,22,F9,DC,A1,3C,DC,21,B4,F9,9E,35,81,F1,B1,1B,C7,52,23,B8,AB,3E,DB,E3,AC,83,E6,25,69,E7,42,43,FD,F9,88,60,32,8B,B4,81,F8,28,09,66,8D,D6,E4,4F,3F,CE,D1,81,53,25,5D,6F,D0,13,E8,45,BD,9F,A8,E8,FB,C7,CE,C2,80,74,05,81,1D,87,52,5E,5A,91,2D,A1,70,D0,7D,C8,6E,3E,9B,B1,64,13,03,D1,44,44,02,DE,9C,CD,17,66,AB,D7,B4,9E,CC,B4,2F,74,BA,B5,82,66,64,77,CF,8D,A5,CE,10,8F,F2,B5,6F,E6,17,8A,4F,6C,AF,D8,09,00,C8,58,2F,C7,A3,D0,FC,61,CC,4B,26,26,E2,68,30,C3,B9,20,97,CF,60,D6,DA,47,EF,EC,63,C4,35,A1,7E,54,36,51,83,91,50,FD,D3,EB,CD,9C,73,6C,6F,69,25,AD,D5,E1,0D,80,F8,F5,C4,76,B9,4F,19,9E,47,61,24,96,FE,06,32,86,F1,57,AA,D2,28,8B,B8,EA,E4,66,8A,33,44,A2,47,8E,F8,A3,CC,17,E5,18,C9,97,70,5C,09,FF,C8,16,6E,D5,18,FB,CA,60,6A,C4,26,E3,5E,1C,66,A5,4D,8D,73,9D,49,9C,17,FF,71,0F,FD,91,8C,6D,EE,58,94,B6,A8,B9,D3,CC,99,4A,BB,24,91,FF,AE,B4,60,32,4D,B4,14,E3,66,E7,AA,DA,F3,FD,82,44,CA,38,3F,8D,20,6B,83,2E,29,6D,7E,AB,E6,92,A7,DE,97,B8,5A,E8,BE,61,27,3A,88,8E,9E,82,36,76,F1,D3,BE,9B,6C,0F,E5,85,57,69,8A,6D,5D,F4,21,FD,A1,93,09,F5,68,52,C4,BB,CF,30,B6,CB,1F,14,4E,C0,A0,19,77,67,A2,65,81,06,79,2E,C8,3E,34,0F,5C,C8,1E,45,4B,97,60,AC,3D,D1,87,FF,31,64,D6,A7,00,CF,CC,00,90,0B,08,F4,45,6B,66,95,CB,45,51,13,A2,AD,62,81,C8,D8,41,C7,AC,8A,EA,1E,81,10,59,AD,31,AC,87,77,5A,F8,15,D9,43,C8,F9,B9,A2,AC,2E,40,B4,BB,14,A2,61,0F,97,9B,29,A1,0E,90,06,BA,EB,F8,56,47,4D,96,92,13,30,48,6B,BE,4A,3E,1B,7D,C0,13,A1,6D,49,08,97,FB,31,90,9B,CB,CD,0C,CD,4F,F1,96,DB,A6,30,DA,19,80,AE,07,03,D5,52,85,AA,20,0F,5D,DC,D4,C0,8A,07,13,8E,09,E1,FE,3C,E5,37,9F,AD,BE,71,E5,F0,A1,20,B3,27,8D,60,F9,4C,13,ED,0D,31,A3,45,1A,69,BD,8E,14,BB,84,09,60,D7,C8,E5,DA,5D,02,00,FC,31,AB,17,A3,74,44,F4,0D,1E,E6,70,2F,AD,3C,02,30,97,48,12,50,3A,B5,F2,5C,CE,4A,B8,92,D5,30,7B,D7,66,0D,8A,0C,B0,AD,77,44,96,1C,84,86,56,B4,44,08,90,34,26,92,4D,F1,72,8D,BB,95,F8,1C,D0,D6,33,2B,5C,15,53,A5,71,63,9D,DF,09,8C,52,93,AC,96,86,15,C8,F8,CC,D9,63,23,C0,AA,FD,0E,13,0C,F5,98,16,8E,4A,19,A8,E5,70,AB,93,7C,EE,DB,2B,B9,F8,0C,3E,AB,60,F1,52,AE,9B,C9,44,79,42,46,BA,D9,74,96,22,D6,6F,C2,94,60,4D,90,41,71,1A,B5,CF,37,79,20,D1,E7,4D,4C,23,59,91,AD,0D,A5,7D,0D,9A,7A,7B,6F,2E,E0,C7,C8,CC,D7,75,72,E9,38,F7,11,7C,53,D2,DA,20,CB,2A,57,0F,61,83,53,8C,5E,F4,BD,29,84,C5,DE,54,93,12,26,DB,0F,95,F6,94,1A,BD,F4,5F,5B,F4,D0,ED,67,9F,D4,82,A9,15,8A,A6,F9,5A,73,85,21,99,A4,D2,D6,83,43,73,83,52,0C,5A,77,B3,8D,63,D6,7D,20,C7,AD,A9,4F,C8,56,4A,26,A6,C6,2B,CF,2B,D1,7F,27,B3,86,17,DA,32,21,83,E5,B4,12,9F,23,3B,23,38,C4,BE,25,B7,B7,24,C0,E9,D0,DC,59,B5,6D,E6,90,6D,10,7F,40,8E,79,83,42,81,F9,9C,0B,DC,49,CC,02,B0,63,5E,76,84,8C,6C,FF,95,8D,7E,F9,21,2C,D0,68,E1,27,60,AB,F9,D8,99,47,FF,47,A0,3F,D4,BF,78,9B,A8,C4,E6,D9,9B,FF,A4,B3,F8,F3,D5,5A,C7,27,A9,8A,52,D1,86,16,83,B4,8E,59,5A,C8,1A,5F,41,9A,60,CC,02,D1,CA,2A,32,48,61,BA,58,9F,27,B9,25,DA,7F,BA,1C,DF,1E,62,C7,91,CC,E6,FB,09,9E,59,E5,5B,06,27,27,30,65,8D,78,7A,04,48,74,39,4D,6A,F9,59,92,E4,3E,33,CC,2A,50,D3,18,18,B9,CA,89,33,7D,60,C2,70,DA,29,9A,3C,75,4A,3D,B4,FE,D5,EF,6A,11,FF,EF,E6,8C,55,80,99,CE,6A,61,31,AE,FD,5F,25,70,5A,EB,3B,1C,69,5B,3A,36,03,6E,56,3A,BF,08,79,53,4A,7D,C1,A5,FA,50,4E,A4,68,9F,C2,E7,7B,F7,55,AA,47,31,C6,D2,E0,55,17,FD,85,13,E5,36,57,3E,61,00,4A,BC,38,E8,1C,88,18,79,A4,EB,16,20,B5,95,F4,7B,10,44,32,AD,DB,0E,1F,D1,BB,76,FC,39,60,40,6A,3A,51,1C,B3,AC,2D,AE,B8,99,C3,C8,00,5C,62,92,6D,E1,AB,B6,48,A9,4A,65,91,CD,71,97,49,F0,FE,18,E2,F4,2C,92,88,55,63,30,EA,48,6A,B8,E4,E2,D0,94,57,7E,1E,B9,99,DF,4B,4E,BC,98,D6,C6,67,93,05,88,8F,7D,51,A7,95,2F,61,B9,8C,69,DF,8B,1C,1E,17,76,39,F4,75,AA,85,FE,54,FE,63,A1,F1,FD,C3,EB,B2,16,1D,F6,B3,75,B6,AF,1D,DC,E2,84,46,E0,B2,83,D0,CE,78,E1,75,E3,99,36,AF,0D,07,72,77,05,12,55,BD,51,FD,6F,63,3D,FB,41,30,10,D9,A8,69,FA,E4,26,CA,28,B3,19,5A,27,C6,50,B1,52,BD,AC,F7,E7,65,BA,59,FE,DB,78,17,BE,B3,AB,05,2C,75,68,51,0F,19,76,AD,BD,48,3D,DC,1C,69,18,C6,D2,66,3B,AD,A3,D6,55,41,FA,0B,AE,94,8E,6F,9A,27,C5,75,0B,8F,41,70,6A,A3,E7,1E,1C,5F,45,1F,16,E5,D6,34,DE,14,25,BD,01,72,DA,2B,DE,13,B6,02,F9,2C,D0,72,7A,AE,BF,D5,37,DA,1A,01,4E,DC,C2,33,79,B6,CF,F9,88,FD,6A,DD,9C,99,B1,70,FD,A3,26,AB,11,65,8B,31,08,B6,41,00,1B,06,85,48,F3,8B,8B,0D,BE,60,F0,9F,2E,71,54,AE,1F,21,89,8C,63,FC,4B,C6,EB,0F,60,C8,68,09,00,AC,75,15,4D,48,AE,42,BE,F0,81,BA,23,31,E7,5D,D5,E7,4F,D0,57,C4,3F,12,8B,5C,E3,96,0C,EB,5B,01,04,01,44,F9,30,44,96,8E,6D,9E,5D,AA,EE,BC,42,5A,D8,0F,44,D3,41,F5,89,88,43,77,60,6A,A7,79,EF,58,DA,69,32,5A,21,75,1B,FE,D3,C8,E4,3E,59,C6,2E,A7,98,A4,A7,A8,7D,21,B6,FC,0C,01,77,AA,DF,53,5B,1D,13,CF,28,B5,A4,78,66,FC,A9,C2,DC,CB,1E,3F,4C,CC,F6,E9,45,88,66,FB,DE,A3,10,82,FB,D1,75,A3,CD,6F,78,1F,06,81,26,D2,DB,D2,DA,0B,63,B9,69,C8,A1,70,D2,A9,F3,F0,7F,A7,B8,57,AA,7F,7F,2B,2D,C4,C7,10,40,90,2F,57,2A,8F,E7,79,23,E7,A5,98,27,B4,C9,7B,7E,88,BB,11,38,52,85,58,4E,8A,50,A7,2F,F4,13,7F,0F,48,88,11,20,3F,98,93,8D,60,A3,14,78,27,89,AD,3A,C8,14,5F,F5,FB,48,9A,B0,01,A4,B0,42,F0,33,A6,DB,AC,72,21,20,82,9F,DB,90,01,96,06,57,B7,30,DB,E0,C6,0E,95,10,41,B6,75,A8,56,E7,7F,3D,11,BE,60,44,EE,23,02,BF,76,73,53,F1,97,8B,BA,85,E3,E4,F0,12,39,3A,6D,DC,C4,B1,99,BA,41,85,46,F6,0A,F3,22,43,6F,FD,87,E7,0B,02,3D,27,07,8A,CC,CA,DA,30,6B,13,78,72,65,70,0B,57,C4,2E,51,4E,8F,64,6F,8F,3A,A6,09,24,A5,01,83,63,7A,10,C6,A9,A3,E3,DF,DA,B3,97,B5,F4,15,37,98,B7,B2,4D,BB,8B,A1,BC,82,F4,14,2F,44,76,55,78,EA,A1,7D,F4,40,6C,A8,BF,54,24,9A,1B,32,2E,2A,DD,BF,D5,77,5A,9B,4C,33,4B,60,72,C3,C6,8D,7E,E8,AA,87,D5,B5,92,C8,2E,A6,A8,65,F5,80,CA,01,3C,9B,8A,00,30,F2,5B,1A,2A,6E,06,80,F8,88,F7,79,0D,3C,45,2D,B1,23,85,08,86,D3,EB,44,D7,79,80,23,35,55,10,3D,94,C2,FC,26,C2,47,93,16,BD,2F,7A,5C,90,5D,93,12,9D,3D,FA,06,B5,3C,7E,50,91,D1,21,8D,8F,8F,11,5E,44,0F,91,F1,AC,9B,64,F2,E0,1C,F9,67,8B,41,33,37,0C,B1,E7,B6,2C,7E,E7,B1,8A,C5,BA,FC,F7,9C,44,0C,CB,EB,A2,5D,1E,71,FF,E4,10,4B,CF,C5,7D,E1,E7,A9,CE,DC,98,17,55,CF,E6,8E,B0,A7,08,55,6D,A1,E8,06,94,BC,A9,38,D3,77,A9,79,72,BD,DA,75,31,EC,85,3D,C0,6E,25,B8,C0,70,04,05,E9,D5,35,6F,F5,3D,34,3B,56,44,AF,D5,55,B4,67,C2,D3,B7,1B,55,9E,C0,D9,22,46,86,CE,6A,B3,9F,F2,26,58,37,F7,9C,37,3E,B7,A8,84,73,07,26,44,0A,8E,1C,28,86,51,B6,88,DF,0B,F3,30,E9,49,46,B4,CB,9E,74,A8,ED,3A,8A,DE,04,68,D8,CF,E5,08,18,1D,71,6B,78,B4,BA,CC,6B,A2,9E,AD,46,DC,8E,AE,43,58,1E,D1,02,35,C1,A2,69,76,E5,82,62,48,62,C4,3F,45,8F,9C,A0,10,69,87,90,A8,35,00,29,43,3D,46,81,90,B8,2A,CD,2F,AD,60,A7,78,E7,53,66,E0,F7,CA,BF,5A,D0,FC,7A,6C,57,4E,EE,70,85,BC,50,D0,CB,99,3B,C6,E8,AB,21,64,5C,4B,F6,FD,37,39,74,B7,29,80,D5,17,30,C8,23,23,4B,E8,BA,8D,62,18,20,EE,2C,78,49,20,59,B0,24,11,C3,19,22,D9,47,EF,F0,2B,B0,20,A0,06,33,8D,BA,A7,9B,57,58,EA,24,34,0C,E4,57,2E,47,BE,C9,6E,A1,7F,8F,3F,B0,5B,84,4E,DF,E2,84,29,5C,D4,7D,27,DC,D1,A7,49,F2,1F,80,B4,CA,2C,0A,DC,C9,E3,32,0E,42,F1,32,82,E0,E1,F4,0E,11,5A,9F,92,B6,4D,A3,81,2B,CD,E0,99,AE,98,0F,E6,79,5A,8F,D5,10,DB,0A,11,3C,35,70,A1,8F,19,AE,8F,AC,6B,C4,BC,92,75,AB,DA,73,55,86,36,83,03,AF,A8,A0,CE,DC,87,B3,0D,A3,63,D0,35,FD,66,FF,76,57,70,1E,C7,9A,19,EF,D9,45,ED,66,71,EE,01,DD,18,1A,D7,2C,4A,F8,02,2B,A8,79,F8,02,B1,BA,12,5B,2D,48,F6,8A,7C,84,75,8A,B4,51,B8,FE,96,B9,EC,A4,C6,CB,93,E0,EE,A8,77,9E,6D,1D,27,19,DC,3F,F3,14,F1,D3,CF,12,63,D3,1C,85,3E,63,13,2A,50,65,72,19,AB,82,8B,B8,F4,C1,BD,0C,69,C2,BF,61,EC,55,3D,06,7D,24,ED,2C,45,81,C7,95,3B,43,24,30,54,1C,3F,27,9E,EE,09,98,25,7A,F8,74,E7,89,D8,71,5C,16,C8,C9,86,8D,55,89,7C,B0,AF,45,09,03,58,0B,04,E3,02,16,6C,C1,AB,9A,51,42,B8,1A,41,2F,D9,33,CB,A5,4A,D7,25,65,57,75,06,87,8E,98,A1,C9,DE,17,9D,B2,72,5C,F3,D6,E1,A9,CD,F9,19,02,02,E6,DF,D3,2E,63,84,CD,33,D4,7B,F0,DB,62,96,00,FA,1A,36,34,FA,AB,0C,7F,9F,F4,F8,74,5A,2E,03,D2,1B,D2,C4,37,95,2F,AA,DD,D1,F7,07,54,D9,0D,7C,6E,22,D4,D4,1D,41,61,29,9C,13,77,AC,06,55,98,C4,92,71,88,C5,AE,ED,CC,99,C6,E2,45,3D,06,A5,75,4B,51,41,E7,50,76,74,7B,35,18,C2,4D,F4,36,DC,7C,88,77,2C,E9,67,55,DD,32,2D,AC,5F,E3,44,BC,13,7B,AA,90,69,89,E6,8D,D7,F2,10,79,13,CF,11,B3,F0,55,79,D0,4A,37,DB,8E,99,2B,54,41,03,AE,F8,62,51,C7,70,ED,24,BF,C0,5C,B6,33,5A,62,37,8A,01,0A,12,0D,F3,1E,B6,56,A5,75,B9,90,9C,3E,EB,8B,1D,94,B1,E6,DE,62,FE,C7,7F,E8,6C,27,94,92,45,AE,22,F0,CB,7B,65,31,3E,EC,37,18,B5,ED,81,E7,75,B3,2E,38,61,2A,F3,36,F8,FE,01,CF,93,2E,A1,75,DF,AB,78,2F,81,6A,47,C6,A5,D1,DF,F8,25,50,1B,B9,3B,09,B6,C4,DB,86,BF,28,FD,7E,A1,B6,80,71,00,76,12,BD,B4,F9,3C,1E,0C,67,34,66,7A,A6,87,4E,4A,46,71,ED,D8,66,BC,93,3C,ED,8D,09,3E,2B,CE,64,F4,75,43,F6,E0,5C,88,54,BE,30,F4,EF,57,D0,05,8C,86,62,3E,6C,3A,63,2D,B5,9C,64,FF,DD,2A,48,B8,05,10,10,E3,4D,61,47,64,71,5F,25,7F,05,66,8D,9E,0B,3A,66,70,00,B2,72,FF,6A,59,A3,B0,C9,5B,DF,B5,2E,58,AA,B8,50,45,43,03,E9,13,D1,3F,35,63,9A,53,33,E7,52,12,DD,3C,20,6B,4B,E9,CC,E1,34,B6,73,68,06,84,7D,C3,AE,E5,F0,4E,83,3D,AF,84,08,61,98,29,55,98,0A,1F,00,7C,06,FF,CB,8C,69,BD,04,40,C3,49,B1,BC,5D,5C,65,60,96,5F,D1,43,B3,DE,84,AD,C6,35,F9,21,B4,B1,4F,D2,A6,30,7C,4D,3C,F5,6F,99,E6,C1,5F,30,22,EE,35,41,67,A6,4E,29,17,73,40,AD,EE,66,8B,59,FD,2A,35,8C,97,1D,55,0D,97,50,D0,41,66,25,9D,59,1A,24,5F,56,1B,A9,E6,D8,BA,7C,F1,B4,F1,1A,6D,E5,E6,D2,1C,E3,07,6D,5C,8C,18,4E,27,97,79,D3,1B,F7,A4,3B,84,38,E6,27,8F,5E,CD,23,15,71,69,54,9B,4C,9C,37,9C,9E,18,13,14,92,16,83,90,55,66,87,F1,93,08,CD,F4,0D,36,06,DC,15,DC,48,C6,A4,8B,FD,55,29,EE,A6,F0,D0,42,10,FF,BE,ED,C8,CD,E6,B7,BF,E4,01,9A,D2,17,EC,E2,0B,14,94,B5,06,1E,20,69,95,11,72,8F,DE,62,F2,7A,75,54,C5,73,93,4A,23,27,AB,2B,24,62,E9,10,07,3C,1F,F9,2C,49,01,52,2D,C8,D0,02,63,36,1F,56,49,42,6A,9B,0E,98,32,75,6C,A9,7C,FD,0C,FF,B8,98,15,F1,B4,70,57,41,41,0C,93,E8,10,B4,BD,78,F6,12,2C,AF,F3,B4,A6,AA,BC,7A,6F,2A,B5,B7,DE,3B,17,A4,9D,4B,2E,59,B5,44,0E,F7,81,D0,9D,C7,C6,9B,80,DC,05,E7,90,2F,FD,C8,EF,00,3F,A8,88,EC,38,73,E3,49,EF,D0,B6,FE,C0,C9,22,F3,00,CE,2E,EF,DC,99,38,55,D6,AB,6D,81,66,7C,F6,72,C5,DD,DE,0E,73,FE,89,B3,7A,93,86,F1,89,E7,77,C1,5D,B2,73,68,A2,09,47,D2,DB,ED,C3,00,4A,6D,BE,4B,0E,2C,37,DC,50,7B,EB,C3,A7,6A,1C,63,50,FC,3B,1C,8A,0D,0C,1B,E3,C3,3D,06,9B,77,9F,04,6D,78,CE,57,CF,B1,15,77,C7,B6,C1,AF,EE,8A,92,9C,0E,51,E2,97,42,59,50,0E,7A,F2,47,A8,76,81,1C,C3,AF,4E,E0,A5,C8,75,C8,DA,1D,2D,35,67,F2,73,12,8B,4F,80,D0,5B,4A,FC,AF,6E,58,6B,F8,5D,B2,FF,E7,9F,39,5E,3F,CC,82,78,BB,D7,6B,AF,90,AC,B4,F8,94,2D,D7,BD,66,43,F2,69,F6,50,D4,13,4A,51,79,AD,2A,CC,22,FE,15,68,DB,E2,58,C3,58,B4,B9,1A,7E,13,1A,0D,F5,22,8D,03,5F,42,84,93,AD,9E,A5,31,1C,38,89,65,18,3E,E2,35,67,1B,2B,38,1C,4D,81,6A,3A,CC,37,96,94,38,C3,1F,B7,39,A2,DB,9E,A6,AB,B0,C1,8A,AF,84,BB,B4,AF,34,43,BF,05,58,83,12,8E,6D,3E,2B,10,E1,59,0E,B8,7E,17,3E,93,8A,EC,19,2D,FA,BB,C5,FA,D9,90,6F,EF,73,AD,C9,07,90,56,94,7C,5D,2A,74,1F,61,61,D1,DB,FA,A9,E2,D0,D5,F8,75,44,28,0B,A8,5E,CA,4F,BC,7B,7F,2E,8C,90,69,5B,A9,38,3A,AF,6E,C2,64,F8,47,23,14,87,C0,01,71,F7,22,E4,27,C5,20,E9,B3,B8,63,60,C7,25,5C,51,BB,EF,33,C6,07,26,56,97,86,0D,94,0B,50,78,95,14,7C,42,B6,24,A0,AF,0F,03,61,0D,E1,37,4C,45,31,8E,5A,A4,A6,DB,05,5E,EF,89,42,BD,72,7D,84,58,6F,D4,F3,E1,1C,F5,9F,BE,1E,7A,EA,B9,D8,1D,61,63,23,E6,19,5F,E4,73,6C,E2,98,78,DC,61,C1,7E,DD,D8,5B,57,B9,9C,FE,C3,C1,14,17,95,A3,8F,FD,5A,19,A4,82,45,63,B0,C5,99,B1,8E,E3,1F,3A,5F,6A,B3,C6,5D,C4,EF,FF,77,CD,E1,96,2F,95,67,2C,F8,26,35,96,AB,2A,AB,88,29,B5,96,F4,F5,E6,2E,1C,99,74,22,EE,09,0C,8F,55,7C,86,6E,5C,9D,D8,F9,4F,1D,13,DA,F3,E7,DD,83,70,A0,EB,F4,3A,98,F6,BB,03,22,B9,4D,12,0F,C8,D5,4A,B1,1A,7F,F2,04,CC,96,51,08,C9,27,2B,85,79,38,25,5B,46,94,B6,E8,1C,3C,26,E1,9A,2E,43,35,40,8C,94,D9,08,04,8D,8F,57,60,B4,23,73,C3,45,54,BE,1D,8E,32,B6,AF,0E,A5,82,2A,29,19,A2,D6,5F,64,A0,A1,1C,B7,5A,7B,2F,4C,8A,B2,AE,BF,61,25,95,A2,76,41,23,00,E0,EA,04,50,6A,4B,02,8C,D1,54,A7,9A,4F,1B,99,12,DD,16,FB,D3,49,20,3C,78,9C,1B,57,DE,7D,E2,C0,1C,BB,D1,4D,6A,2C,A1,47,76,D2,E6,45,58,BF,BC,A0,1B,FB,AF,00,7C,E8,1B,7F,90,79,A3,1D,CF,E4,89,E6,28,E0,8A,94,B2,73,01,06,6E,83,27,6F,3E,85,8F,9D,A2,1A,62,DE,59,80,DA,D6,1E,50,D3,0D,9F,B4,16,67,2E,24,34,BE,61,D3,7C,11,83,20,36,E8,64,72,DD,92,D9,7A,94,F6,50,69,32,68,39,D7,96,63,FB,B6,C7,53,92,73,2A,A8,BA,ED,BA,CD,BA,8D,AA,C2,2C,86,44,D9,C7,76,10,0B,1B,4B,21,D3,9A,2B,CC,86,43,C9,E2,82,C7,37,69,6A,D6,DD,59,55,A3,71,F4,B6,71,DC,F1,C7,35,DD,7B,04,5E,DD,E7,8D,16,43,AF,A5,05,69,F6,63,38,26,0B,79,42,F8,66,F8,9C,7C,17,CF,CB,32,C0,16,3F,3A,D7,B8,46,CE,3C,A9,F4,4D,7B,B8,3D,64,21,8C,A5,CB,B6,30,EB,5F,4B,84,0E,C9,D0,5F,79,1C,63,1B,5E,DB,24,D0,6E,B8,D4,3C,34,01,57,5A,8F,AB,7D,19,A1,00,6D,30,99,B7,D5,EF,A5,02,C8,16,3C,33,6E,EE,23,25,B3,84,D8,81,C7,A2,F2,08,0F,26,51,AE,F8,B5,B3,F5,5A,DF,38,91,02,D0,6D,6A,1E,35,57,7E,82,B6,C7,9C,A5,1F,5A,71,82,24,48,0B,8D,02,E6,22,D0,3C,0C,D5,DF,F6,2D,2C,5E,32,80,45,8B,E2,6E,DD,6A,8F,23,1B,D5,73,08,94,5C,4E,F7,D3,58,AE,8D,78,B2,EF,4D,F1,04,C1,CB,23,18,69,AA,82,5C,29,6E,06,3A,55,1D,60,3D,9A,CC,6B,EE,69,1F,FA,8F,15,46,57,72,42,BB,5C,B5,B0,E7,F8,69,2D,76,67,6B,8A,81,C8,50,50,AA,89,31,FE,E1,F3,D5,C6,CA,98,76,ED,B8,9A,8B,A2,01,8D,10,BB,F2,80,39,60,E4,54,F2,0D,D1,03,C8,E8,38,8E,BE,0A,07,90,78,12,12,06,62,11,6E,3A,18,BF,BC,18,8C,06,EC,9F,83,5E,8B,AD,89,1A,C4,67,2E,20,3D,EE,8C,EF,64,DE,CA,BA,95,D2,8D,71,FE,6D,62,7E,B9,0E,12,C0,CA,FF,30,00,F9,32,12,FE,14,6E,24,77,F7,32,79,98,ED,A9,94,19,D9,42,B4,5D,55,C7,20,57,04,F4,D9,10,64,00,AA,5A,63,EA,2B,BF,04,98,51,2F,C2,EB,0F,0D,BE,C4,D4,C7,78,CE,E6,FF,B5,7F,AE,99,80,16,A3,D7,F3,5A,95,D2,5B,10,A0,7B,AC,99,CF,FF,47,C5,28,7F,9D,89,25,63,9A,8C,E5,81,42,F2,A0,C5,AA,13,DB,A6,48,D6,96,95,FC,21,D3,78,55,6A,75,E2,ED,62,8A,39,77,57,88,C3,8D,88,DC,C4,82,8E,81,2B,BE,67,AE,CE,46,88,E9,D0,4E,89,8B,CA,C0,9C,46,3F,7E,51,19,BE,FE,5B,67,4B,94,54,EF,6C,BE,6B,9A,B3,2D,81,36,84,32,50,D7,7D,19,A6,1B,D6,9C,19,1A,34,EC,0F,44,03,72,97,80,FB,80,17,8D,EB,2A,2E,E1,78,27,9E,9B,7C,4C,75,18,62,B7,7E,AC,14,FC,09,6B,AA,06,90,F8,6D,9A,9E,15,C8,A1,91,70,FC,5B,04,7A,8B,14,59,C6,42,9D,D9,9A,6F,38,AD,FB,DE,05,9C,D6,3B,FB,83,3C,C7,36,48,0C,C4,33,89,AD,A8,23,88,2E,AD,C9,F3,06,03,C1,49,E1,94,DE,E8,91,82,B6,F8,15,C1,79,67,99,B2,16,AA,70,F6,F9,DD,A8,55,69,9D,13,FB,1C,36,35,D6,0C,4F,BD,25,32,5B,C9,17,46,2F,6B,3C,46,7E,60,D3,DB,1C,7D,BE,85,C9,EF,CD,8B,73,E9,7A,0D,B8,80,BF,52,93,C3,3B,68,75,3C,A0,6C,5C,47,AC,DC,0E,68,34,2F,C4,83,2E,7B,A6,E5,B3,5E,C8,56,98,53,6F,48,9E,FF,C3,BA,53,F0,37,E3,6A,B4,8D,B3,A8,F2,3C,A9,80,02,71,66,D2,E2,5E,65,1F,3F,FC,53,AA,36,06,74,80,2A,A7,21,31,06,FD,98,2E,80,37,B0,6A,12,E5,EA,13,29,05,19,37,D5,FC,C5,10,BD,4C,7B,CF,FA,D2,BB,BB,54,74,2C,CD,C4,D2,1A,C4,CE,F8,DF,C4,0E,07,16,AF,59,60,D2,22,31,8F,38,D4,AE,33,E3,0C,9C,FC,37,89,98,AE,DE,49,DD,E0,98,50,FB,B8,22,24,20,FB,AB,BD,3E,D6,92,C7,AE,82,20,36,FE,CD,08,D6,AF,FA,21,B6,24,BE,8E,0E,FA,6A,68,3F,F5,DE,82,DB,09,A8,71,FF,BC,20,22,A0,4F,18,E6,F5,28,A0,66,A7,8D,EF,36,4D,BC,44,33,7E,CF,44,16,7A,57,49,9A,4D,13,2D,27,69,8E,85,25,70,A4,5A,80,96,06,B4,67,AE,B0,1E,21,EE,ED,36,66,A6,CC,95,79,8C,E2,47,23,17,42,2D,47,F5,97,DA,8C,DE,FC,9A,B3,CB,4A,F0,57,98,BF,73,18,1A,DD,07,3B,E6,B3,3A,09,E6,FD,CE,BB,BE,94,70,2F,28,96,80,14,3E,0C,2A,0E,2E,69,00,A7,F6,C8,64,9B,81,3C,8A,DB,09,1C,C5,4A,49,2A,2D,A3,61,CB,FC,BE,28,92,27,35,59,90,BA,0C,0F,AE,36,9C,1E,11,63,3F,7D,45,07,66,F0,A9,0A,E9,BB,AD,2E,2F,DE,14,BD,1E,5D,AD,C7,B8,F2,2B,B3,16,33,8C,CA,5B,CA,D7,C0,B1,CF,F6,F4,4D,50,18,C6,F3,31,8F,F2,56,E3,58,FB,39,0D,F8,F2,DC,40,8B,41,D5,35,F0,4B,96,6C,F4,75,60,D5,7A,B6,B0,07,AC,1A,A4,65,39,7F,7C,1B,08,39,3B,C6,48,97,B0,93,A4,A5,FB,04,9B,86,56,33,35,15,74,C5,32,A6,54,F4,1B,41,DF,5C,A9,9A,62,72,8D,48,57,87,78,33,D7,B8,94,7C,7A,8B,5A,61,7D,09,EA,F8,CA,BD,DD,1F,D3,47,B2,DF,AA,A4,A4,E0,9F,E6,45,DC,68,74,AF,AF,DA,A6,A1,87,0B,22,2F,47,54,9E,80,AB,F4,FD,B4,AF,6E,8D,8E,16,30,23,90,A9,F2,0C,8B,F2,3B,27,A5,74,AC,BE,95,C8,DD,5F,C6,24,6A,98,B8,03,7B,ED,76,A3,1E,A3,90,4F,1F,70,A1,85,7C,28,41,08,4F,51,D9,A9,85,CC,E5,A8,36,79,C6,46,23,27,21,C4,C1,25,93,31,EB,20,21,74,AA,9D,D7,24,13,5B,AE,6B,0F,CB,4D,C8,75,9E,4E,D1,96,F5,88,58,B3,E6,04,CC,04,10,8E,00,22,5B,BC,DD,62,B0,D5,84,21,83,39,AA,31,11,B7,75,6E,AF,5C,4D,72,93,66,CD,C0,F4,DF,5A,E6,71,3F,01,DD,7A,4A,2C,40,5A,0E,EA,38,4F,10,07,42,9A,C1,DA,14,98,E5,1E,11,AC,A3,03,67,DE,E1,85,27,6F,5E,63,52,74,EA,BF,1C,18,7B,76,4D,52,56,DD,61,34,EE,B1,46,9B,CB,E3,0D,60,74,54,9D,3A,58,D4,6D,C5,9F,8D,1E,53,67,EC,C7,C7,85,3F,EC,48,5C,14,8D,1A,42,C5,4E,8A,11,D6,A3,C2,74,61,93,6D,71,FA,39,15,71,00,6D,62,6B,98,8F,73,F7,20,48,F8,90,9C,61,AA,C2,EE,B8,29,01,FF,10,CE,08,C7,01,9E,E4,DA,90,49,2B,6E,10,C2,10,E9,45,47,DA,D3,35,43,98,BA,52,0A,F0,13,14,CB,83,7A,B2,95,55,BC,15,77,40,7F,7E,FA,C6,D2,E1,59,90,1E,14,82,CD,E4,3D,89,87,8B,69,69,99,81,5D,F0,B0,EB,D1,F8,2E,54,C5,5F,27,F9,6C,54,3D,F9,70,F3,B7,15,DB,37,D8,9F,63,E0,52,FC,30,CD,E1,42,7E,26,AC,16,49,05,64,8F,9D,31,23,8E,E5,C9,58,1D,F3,3A,0D,D3,E6,1D,41,91,45,95,47,9B,B2,0C,A0,4A,20,24,84,86,E1,66,CD,30,30,13,F7,E9,3D,F7,C4,E8,AA,5D,D2,05,73,AC,49,37,04,80,D7,0D,FE,5D,F6,E6,BB,5C,1C,9C,06,46,8A,C6,D0,0F,88,11,D4,4F,0F,83,B7,BE,70,AF,86,9F,9A,0F,52,26,6A,78,2B,A9,04,14,C9,EA,89,7D,B7,48,4A,A6,25,BF,15,59,54,30,57,93,E0,39,46,A9,50,F0,FA,BD,29,95,2E,18,08,C8,B8,49,CD,61,B4,37,E7,4F,CB,C9,FD,4D,FA,46,4E,E7,E7,97,E8,A5,FE,F1,1B,EE,DD,A0,65,FC,0A,1C,E4,7F,77,BC,F0,D4,09,34,F0,46,E5,19,67,C2,B4,67,05,B9,36,0B,5F,9B,81,FD,C5,BC,00,CC,C4,D8,B5,41,AA,6B,07,5F,7F,B9,ED,E0,5E,B3,24,FA,4A,E7,37,37,49,1A,84,1B,26,20,07,75,F5,81,DB,83,FD,17,AB,88,FD,15,34,26,B8,74,57,FE,90,52,23,5E,F6,4D,39,84,3B,95,F1,9A,0B,CA,AA,4A,03,04,46,87,3E,F4,51,6C,06,B0,24,A8,F6,01,E2,E4,FD,76,2D,F8,EF,C8,66,3B,0B,B6,3E,3A,83,CE,66,29,E2,73,70,0A,53,8E,D6,B8,B6,F1,7D,78,B7,E3,F0,77,5D,56,27,12,C0,A7,D2,F7,9C,F5,D2,17,45,F5,C7,B5,92,7D,EE,88,0F,7C,9A,C8,FE,7F,50,7E,6D,01,D1,2F,B6,4E,24,03,EC,A1,99,D7,E5,D5,9D,86,C7,E4,5C,B6,BC,13,DA,D2,4F,26,48,FE,BE,C6,25,16,B1,0D,DB,4B,BB,7C,DD,A0,59,D1,DF,16,CA,67,75,9E,CF,91,B7,B5,86,56,CB,72,EC,8A,15,4C,8E,56,8E,70,07,34,38,7D,A8,14,9D,37,4C,E8,8A,C8,46,42,1F,6F,05,F4,48,EE,88,54,FE,6C,EA,44,24,5D,0D,96,E9,BB,8D,6D,BF,BB,CF,81,AD,02,49,01,B7,F9,09,7F,31,39,AD,ED,AD,AB,8E,03,A6,0B,62,49,1C,EF,38,78,5D,97,BF,98,AE,01,82,EF,A6,5D,04,7A,B1,50,43,DA,E0,F5,F6,78,00,F5,A5,46,56,2C,1D,8C,BD,FB,0F,78,95,9C,CB,57,90,57,D1,E4,C1,9D,67,2F,C6,CE,65,95,F2,2D,40,0C,5A,8B,8C,47,42,B9,7A,5F,0B,69,35,6B,43,AB,0F,33,08,58,FE,FC,C5,CF,5E,E8,9C,3A,8A,A5,FD,40,76,DC,92,74,BD,E9,D7,70,EB,AE,AD,91,D2,51,9E,4B,5A,B6,F7,A3,16,93,37,07,36,E5,4B,40,75,8B,04,CD,58,CE,69,3E,9B,7A,84,18,FD,57,9E,32,34,95,86,8B,0F,DD,23,41,E9,8B,C0,03,1F,9B,D3,8C,64,C5,20,EB,65,B2,E0,9D,08,2F,1D,74,A6,82,A2,08,C5,9C,EB,B1,DA,BB,7C,B5,A1,14,7B,D4,31,57,58,7A,2B,7C,41,F1,A5,31,08,8A,FA,22,32,59,AB,C7,49,87,FE,C6,57,59,04,AE,B3,3E,06,74,9C,5A,47,9C,8D,70,32,A6,50,81,E7,0C,C9,35,9C,D8,90,52,BC,17,90,32,21,BE,38,C3,4A,CA,ED,15,CD,8F,97,A4,2B,97,6B,1D,6E,52,25,E9,6A,52,B4,78,0C,F6,F1,D3,EC,CB,A1,CE,A6,FA,E5,A0,A5,BA,1C,B0,8B,1E,D8,B7,6C,21,9D,8D,96,66,5C,DC,D4,C1,29,1D,90,AB,2D,35,1D,62,86,1D,CF,37,2B,43,7C,9E,AC,24,C1,DE,71,99,15,51,EE,3D,E3,AD,D6,92,2D,AC,B6,E4,EB,29,EE,68,CE,A8,4E,28,3E,C8,65,D8,44,BF,74,E0,3B,16,D6,29,EA,D5,23,D1,49,4B,27,C2,CE,E7,1D,64,DF,20,60,E3,BA,D8,08,7A,98,79,81,17,80,87,93,9E,B8,FC,FD,C6,27,85,3B,85,D4,C1,E5,15,78,D4,F9,FC,1B,9A,C9,41,40,DE,FA,C7,C2,30,A7,53,24,DE,C4,08,2E,B0,7C,69,EC,49,9E,E8,47,D1,69,D7,62,9E,16,3F,77,DE,06,C0,5A,6F,CB,A6,F1,AB,F7,F1,F7,F7,12,87,8D,ED,E9,A9,C0,E0,CC,66,5F,FC,59,D2,4C,36,D5,A3,12,4F,97,6F,07,23,6F,03,2B,A8,9E,96,16,09,F5,EC,72,3F,8D,BD,9D,80,99,FB,C0,06,F9,EA,CE,EC,90,F4,C3,53,EB,95,82,DC,96,B8,CC,44,F5,C6,5A,1A,37,1A,6C,3B,D4,B0,35,10,10,8F,0A,19,D6,E9,04,E6,97,AB,33,93,5C,1E,B0,FE,20,25,93,9D,49,C7,BF,AF,B9,9D,03,C6,1E,39,84,E9,2E,E2,0F,31,46,C7,33,60,48,E4,0D,A8,98,4D,85,14,98,5B,B6,90,1A,73,5F,7A,50,EB,CF,DE,E8,9A,75,DC,F7,06,40,8B,64,F2,EB,57,42,F1,81,54,42,BB,A8,A8,AD,87,98,D0,32,17,4A,CD,9C,ED,D2,23,00,E5,48,5C,06,31,2A,C5,01,C7,10,B3,3C,2A,45,5E,57,92,49,18,A9,C9,65,4B,E3,08,AA,DA,77,EE,2A,55,54,77,D7,F6,45,56,09,F3,6D,0D,B6,DE,E3,6A,14,F6,67,D2,9C,1F,32,B9,A4,F3,78,26,BB,EE,87,99,4E,A7,7B,68,D3,E0,1B,B3,74,E1,68,D3,D4,A1,FD,6F,67,06,FE,45,75,3F,BB,72,FF,B5,51,99,89,A9,F7,8F,C3,70,54,DF,0E,2F,E8,59,F0,3A,22,05,5D,E0,FD,69,D3,DC,5E,AE,3C,7F,F7,D3,C2,32,16,B7,5B,0B,95,B7,19,55,26,39,DD,15,6C,53,97,17,48,01,50,03,B6,9D,09,FC,9A,5F,13,27,2B,7F,1C,1D,F3,61,60,66,5A,3C,73,C7,DF,DF,09,63,CB,7D,13,FB,12,F9,EC,36,FE,66,B8,C2,02,0E,4E,B3,B0,88,38,A0,4B,AF,AA,99,6E,50,45,93,C9,1B,62,1E,5F,0E,F2,78,08,77,58,26,DB,6A,E6,FB,D8,C5,73,BA,03,0B,8F,A0,73,B3,38,DB,87,2C,B1,A1,01,C0,50,FE,B3,2A,D4,53,4A,18,E2,4E,09,F7,67,7E,40,F0,85,40,AE,1C,E2,B1,49,3A,8E,90,D9,8C,D1,A1,92,1F,66,18,9E,EE,2F,FC,18,A9,AD,C1,2B,D6,0A,44,1B,DB,60,12,28,80,03,24,57,99,4B,3D,7F,45,46,AD,25,1F,7F,00,66,06,B9,95,95,32,8E,0E,F3,0D,6F,1E,E3,D3,C3,98,22,94,92,E1,3F,33,EA,C6,0D,D9,3B,F3,EC,FC,8C,FA,8C,65,BE,71,A9,31,D7,42,A5,98,A0,2B,B6,C0,24,92,9E,F2,C3,E6,2A,97,B8,33,D1,BD,2B,A7,0E,93,EE,03,20,6B,BD,33,94,7D,05,BF,28,69,6C,26,43,FD,34,D2,98,EB,11,21,23,C7,F7,3C,1B,AC,E9,E3,EE,E4,69,46,DB,DA,30,01,02,03,55,40,68,8D,C6,D6,8E,53,F1,4D,22,82,7D,2B,75,83,11,DD,42,3F,32,F0,5A,74,E4,F2,23,FD,D7,B9,09,02,1A,D5,1B,02,69,82,41,19,68,AD,FA,E0,82,69,B2,A6,0F,10,52,A6,F4,FE,8C,E9,17,BF,73,50,4D,12,7B,16,F6,D3,17,57,67,DA,D4,E0,5C,F9,BF,76,77,D3,5E,56,00,67,69,A4,AC,76,1B,76,89,76,E8,02,76,B1,DE,87,8C,4D,F7,0B,D5,00,8F,82,3D,0E,6B,E9,5A,41,7E,D7,D5,CF,CE,95,B0,64,A2,70,DA,FB,A9,01,E0,E8,AB,54,21,F4,99,F6,F5,98,A2,31,5A,F5,BC,54,84,42,C7,91,7D,4F,99,63,7D,85,11,64,A4,9D,E0,E9,5C,D0,F0,20,F1,59,C5,63,BC,4F,29,7D,80,9C,4F,B1,BC,92,A0,6F,48,BA,85,6A,16,99,18,E3,11,4C,76,11,E9,1C,D5,EC,75,53,B5,C8,32,D3,9B,7C,CB,03,F5,7A,FD,BE,85,67,1A,D1,98,68,D2,F4,92,7F,D0,CD,F8,BB,DD,80,86,1B,E6,3E,97,13,9A,91,5C,4E,54,86,4B,A2,AB,44,95,E7,4D,DA,79,D7,66,E7,F7,BD,42,AD,FE,D9,88,36,8A,CF,BA,D0,13,AF,3B,3D,55,7C,90,50,B8,B4,9D,ED,0A,DD,EB,E9,20,56,E2,51,94,9B,0E,8A,2F,32,BE,45,55,A3,C4,05,E0,CD,13,1C,66,55,EC,AA,6C,CC,51,F5,63,98,6B,F4,D7,86,FD,DF,62,2C,B4,EC,A5,5E,11,90,02,A7,9F,E5,D5,10,33,54,E2,B3,6E,DF,21,69,FD,AB,D7,F5,F2,1D,E1,62,A6,B5,09,B6,81,42,2E,A8,9B,4B,FF,30,A6,10,5D,FC,FE,89,67,B7,75,0E,D4,A3,D2,FE,BF,E1,9C,06,4E,E7,19,C1,8A,7D,BC,0B,6E,AA,91,80,B5,7C,CE,1E,F2,28,F1,AC,A5,DA,28,F1,D6,03,61,32,7B,50,8B,66,DB,9D,8A,EF,AD,A4,40,AE,0E,23,75,4E,3A,C6,A7,BE,EC,22,51,F6,66,D9,7E,5D,8E,4E,F3,0C,F6,54,BE,36,9F,D9,D6,AA,B3,E7,92,28,CC,98,8F,11,55,1D,11,50,14,E8,2B,62,9F,B3,9F,9C,9F,1F,E2,AB,F7,17,A1,13,5F,E1,75,D6,4A,B1,8A,AF,98,40,04,03,3E,68,33,99,75,68,90,53,64,EA,FD,FE,B7,A5,4F,F1,3C,70,D4,D9,21,56,94,17,4B,DF,1C,46,CD,8E,50,06,97,EC,03,95,DB,CE,B7,6E,B0,7B,71,95,13,C4,C4,BE,34,4E,E3,6F,54,50,FB,1D,2F,DB,46,8E,97,9A,8F,25,54,F4,0D,B2,E6,0C,D2,5F,BC,33,20,25,32,00,80,34,67,59,D1,14,E8,21,D6,2A,E8,4B,E9,0D,6F,FC,E6,AC,74,BB,EA,B1,7B,FA,E6,E0,F6,A8,35,7C,67,E7,A2,BA,E1,7F,F5,6D,17,78,97,50,91,8D,25,F2,7D,A6,58,CC,96,4F,F9,E8,BB,CC,66,0C,4D,F1,F3,3D,FB,7D,14,86,BC,07,21,AD,AD,D5,FB,E1,B3,DC,5C,4F,74,A0,B9,3E,57,99,9C,B7,45,D8,8D,AD,CB,D4,EB,D4,09,62,5F,5D,43,05,73,0B,C7,AB,D7,85,E9,14,67,96,C8,15,AE,AB,94,01,75,9E,6A,6C,67,13,06,1E,75,A2,EE,00,CF,84,1D,17,7F,CA,28,89,4B,8E,88,90,E5,F6,C1,36,13,76,D4,E0,43,12,EE,F5,FB,64,79,19,6A,90,3D,01,54,FD,45,E3,50,9D,91,89,52,57,BF,F9,DD,7D,6B,6D,C5,58,28,C2,43,DB,9B,B1,77,78,2B,F0,26,1B,D2,68,22,04,93,EF,5B,07,AE,29,1B,B4,7E,58,E2,2E,F9,52,74,65,BC,F2,3E,9E,FB,5E,13,F8,CF,CA,CD,10,63,66,B6,82,73,09,9E,84,D9,F1,AC,C7,79,86,8E,AA,46,40,68,B8,99,2C,40,7D,92,26,BB,65,7D,D7,C2,21,83,79,7F,22,39,3D,32,50,2C,B2,29,A1,58,72,E2,74,0F,FA,9F,16,12,FE,F0,05,D4,56,D5,B8,5E,C3,22,87,28,66,E7,19,B4,88,7D,4D,2E,FD,C0,8B,71,DF,1C,EE,A6,56,97,B6,9F,83,11,94,2A,1D,56,7A,99,61,B1,5C,AF,85,7C,FF,58,36,E0,FF,09,CB,F5,B6,EC,1A,A0,2E,F2,A9,22,57,C1,1B,A8,C6,6C,B6,71,B0,97,E1,FC,69,E7,72,E4,61,F3,7A,50,7A,E7,BC,69,DE,A7,6A,C7,C9,9F,24,71,32,08,B3,D4,A1,8A,68,47,11,AA,FE,70,78,8F,1D,9B,5E,8F,66,35,84,7D,32,14,AC,CD,61,7A,6F,6D,03,8E,D1,CD,13,25,9C,C7,3A,F3,6F,6C,A5,C5,9B,50,5F,4E,69,40,2D,F3,A4,FE,4D,3F,6C,45,4E,3D,66,4C,5B,FF,5B,BC,63,C1,93,D6,E4,FD,29,CB,A5,B5,92,BF,65,3A,F8,32,BF,CE,7F,E2,A3,7B,BC,EF,03,63,B5,32,95,D7,70,9D,11,D3,F8,F9,2D,C9,B6,01,E9,4C,21,6E,F0,77,ED,F4,57,AC,21,DA,58,7D,77,98,5A,14,6F,D0,A6,F5,D8,14,98,3C,63,B4,A6,6B,71,0E,EF,7F,C8,25,59,C0,01,D2,2D,D0,D2,7C,20,60,2F,DC,18,24,05,8A,F1,36,18,5E,63,D2,5B,71,3B,B6,69,DF,C8,4D,90,C6,D3,E0,36,B8,36,B6,DD,3D,C3,22,1E,DE,03,12,36,28,01,30,A9,FD,9F,7A,E8,2D,42,EB,95,69,7B,28,45,9C,06,DE,31,28,88,30,AE,93,6F,D8,43,FC,8E,13,27,AA,2E,E7,CF,47,5A,F1,24,EE,67,C3,6A,D8,3D,44,8B,C3,0C,3B,61,0A,31,C4,97,C4,07,99,6C,52,24,00,B4,73,72,44,AC,C3,DF,1B,E4,27,11,69,F0,F9,C2,2D,F9,B9,3E,11,14,AD,A7,07,CE,2C,07,4E,3E,4E,6E,DE,66,F4,23,3E,14,AD,D1,5E,E7,83,ED,44,0B,E0,74,63,D6,B9,66,BF,71,3D,50,4E,CC,60,27,8B,9D,62,A8,3A,4E,8E,1B,48,AD,5D,DC,CD,CE,74,55,E9,69,18,D7,43,DD,BD,63,E0,19,93,1D,A8,60,C2,E7,7B,32,ED,67,4D,A6,A5,28,14,CA,F9,FB,9A,3C,7E,22,E7,63,36,8B,15,F6,CB,B3,97,1E,83,18,6C,1B,68,AD,C4,64,FF,D2,4D,A3,1B,E8,2A,63,2B,54,64,5B,F4,C0,D3,F3,B2,FE,5D,25,A1,D7,93,33,EA,F1,B8,4B,00,24,9B,C8,C3,A7,B8,6B,A7,71,DA,7A,18,25,4B,CD,94,B3,1B,55,03,75,29,BC,89,3B,B3,0B,E1,21,D7,B7,AB,F7,62,10,9E,55,55,93,63,8D,AD,A4,2B,F6,E4,F1,53,9F,D3,5C,F6,DD,56,94,A2,07,6C,06,1F,97,8E,4E,BF,03,89,3A,59,83,86,33,5D,BA,52,1E,1A,E1,E0,C5,CD,1B,A9,9B,44,90,77,BF,ED,58,26,DB,59,3A,EB,13,95,C4,4B,48,97,8D,A1,DE,CC,02,7D,82,BE,0E,F9,7B,9E,6E,2C,E8,CD,D6,5C,40,79,CB,83,DF,4F,44,66,D3,5F,7F,FF,3D,29,0E,92,36,F8,AE,43,D3,4E,D4,D1,CA,77,22,56,26,BC,71,A7,35,EA,02,68,2D,51,D9,5D,E3,4F,CC,75,CE,39,D9,20,15,5F,7A,AC,45,C9,21,18,85,71,85,23,E2,3F,CC,3F,A8,26,E2,F2,32,B2,BC,99,A3,49,ED,B4,87,E8,99,D6,AA,C0,91,01,AD,68,09,8A,F1,E3,9D,A1,CF,11,0D,04,AD,96,D4,A3,01,62,DD,35,C8,23,3A,6F,08,EA,06,EF,A4,4E,F8,6D,19,AA,AD,88,B7,EE,1C,78,D9,EC,28,D6,47,AD,41,9E,43,B1,A8,35,07,56,D4,D8,2F,5B,B9,A5,24,78,21,93,CD,B0,2D,9D,B7,35,48,9F,54,62,9F,AA,EF,AD,FA,0A,3F,07,42,87,1C,DB,0F,76,96,BF,E4,44,5B,FD,97,F3,F0,E0,B4,30,B5,EF,7A,8F,15,3B,27,01,B1,79,F3,01,44,C8,60,83,92,49,2D,42,93,20,47,EA,F8,D1,3C,0B,AF,7E,E7,8B,09,1D,3C,0A,C2,DA,D2,08,8E,A2,DE,7A,4F,45,BC,35,25,88,A9,63,AF,5C,B7,6D,26,FB,E9,7E,20,97,03,D2,5A,0B,D3,7B,C1,02,B3,41,45,37,25,71,82,82,DA,43,86,28,FD,D9,34,5A,7D,48,C5,1A,5F,8B,AA,A5,18,1B,AA,8E,C7,1A,80,93,A9,3A,B2,7A,A1,C2,A3,47,42,E3,F2,28,B6,CB,C6,C7,78,0F,2A,42,91,2C,98,92,96,E8,F4,04,1E,EB,E0,52,35,D3,3F,58,08,8B,71,97,64,27,79,89,07,DE,F3,D1,C5,C2,4C,EA,B1,BC,6F,FB,4A,11,30,76,2C,44,36,48,16,0A,E2,83,5E,13,92,5D,CC,C8,2A,16,DE,55,B5,60,F9,A3,10,FF,73,D8,70,9C,3B,56,97,CA,96,D6,0D,15,FE,95,CD,26,50,8F,FB,16,94,F7,68,1D,71,8A,1A,BC,87,E3,99,8C,44,91,6C,5F,14,CE,4D,F3,54,50,3F,69,01,17,25,9C,21,A0,7C,1E,C9,82,A0,EB,B0,E4,05,98,A7,04,E3,4F,F6,3D,9A,8F,7E,7F,7A,E4,80,B2,F0,E2,12,8A,0E,0D,11,61,67,75,FF,96,F2,BE,4F,24,DF,1C,70,81,DA,5B,2F,CF,0F,00,A5,D5,DF,C4,41,EC,49,B6,E9,25,01,D9,95,17,ED,53,91,8F,E5,28,DA,34,58,A4,DB,68,D5,15,90,8A,A3,BF,74,DF,CC,AB,02,AB,19,4D,EC,1B,6E,5C,B1,81,E6,F8,1A,24,A4,67,C6,4E,57,EB,FD,28,3E,10,3D,DC,41,15,5D,DD,72,85,25,12,E3,9A,46,8F,98,32,31,59,02,38,9D,50,D1,36,CD,3E,36,4C,A7,17,20,D4,F4,CA,5B,DF,0E,68,5D,C4,09,31,FF,78,0B,C7,65,B6,3B,8A,C8,BA,01,30,9B,98,41,05,6F,83,49,DE,7D,CA,49,DF,21,4E,7E,81,FB,BD,CF,A5,2A,CE,BE,D8,BC,14,1E,41,29,1F,0D,FF,D2,F4,5A,1E,86,6D,7E,26,30,EE,56,88,82,EC,93,6D,8D,FE,60,73,50,E8,69,F0,F8,4B,C5,CA,7F,E9,6B,C1,E0,26,7C,5C,90,9A,EA,5F,85,38,60,8A,F8,10,D5,DD,3A,AC,C4,6A,AA,31,FE,20,BB,0D,42,0C,69,E5,97,63,41,D6,94,DB,04,E4,B2,08,ED,83,E4,19,2A,20,EB,98,86,E2,70,C8,1A,08,ED,DA,5F,20,1F,40,01,68,79,5E,97,72,F6,EB,1D,9B,AA,18,AD,8E,FB,29,44,2C,D5,B2,13,FE,4D,0B,0F,48,54,9C,DC,3D,9B,E0,44,15,FB,AD,0F,AB,BD,E8,88,C1,C2,7F,C3,9A,79,02,8B,DC,3A,4F,0F,D8,9A,38,81,B2,31,F3,2A,E2,06,AD,28,8E,5A,EC,3D,64,61,BE,0D,CB,22,81,E6,3A,D4,D5,77,ED,51,8B,BB,65,E8,BB,95,6B,24,9B,A2,06,C7,29,4B,76,A1,50,2D,70,2A,8F,BC,C7,5B,08,64,55,D7,86,77,3A,C8,07,71,18,A9,F0,C5,B3,23,8F,5C,51,57,98,E1,96,D5,4C,B3,52,2E,41,D8,33,B3,1F,18,1B,E6,58,6D,AF,7A,B5,D2,4E,D2,86,76,A0,BA,D2,4D,12,01,07,D0,02,7A,46,82,29,9A,D9,03,98,57,2B,95,31,1E,44,70,34,23,71,DA,7A,2E,4F,C5,F9,99,B6,D6,D7,F5,A3,79,6E,A3,2A,9D,88,7F,0D,AC,5E,05,3E,5D,91,3E,F2,71,80,EB,2C,97,FB,0F,AA,6E,06,73,0E,94,28,86,D8,DB,7A,B0,8C,54,C3,28,00,A5,5E,2C,01,7F,B6,0B,58,6C,E2,A7,94,AA,5E,7A,C5,D8,66,92,85,80,31,96,DD,4D,09,98,B8,41,C9,C1,6B,63,35,08,E6,E1,49,E1,25,AC,FE,9B,9A,85,5D,22,C2,BA,92,0F,F6,B2,08,E1,C3,12,A0,97,F5,03,FF,37,1C,AF,69,4F,54,B3,E4,2B,6A,F9,5B,C5,08,CB,B4,AB,BC,D4,1C,E3,F4,43,F1,21,E5,99,FC,C1,33,6F,F3,0C,50,52,1E,A6,76,2F,62,1B,E6,B3,CF,AC,67,1C,A6,12,F6,8D,C8,05,C5,68,B5,37,36,2A,26,F7,33,B0,53,10,A4,58,34,9A,86,C6,51,31,FD,24,CA,93,EA,D1,BE,56,0F,1C,6C,EE,42,CF,2D,62,5B,F3,22,15,A1,AB,4F,68,57,C8,64,83,A2,02,EF,8E,2C,8D,C4,72,72,67,95,84,E7,3E,AC,1C,F1,99,50,8B,54,A1,4B,7C,BE,02,46,96,A9,D8,44,20,35,AF,34,3F,09,FB,C7,54,A2,48,11,B9,48,7F,F5,B2,F9,7E,39,F6,44,E7,59,9F,FC,56,C5,60,E5,91,D0,B2,E2,A0,9B,87,18,AB,E6,A5,B3,0D,17,BB,3F,86,20,CC,CE,53,27,3F,8F,1C,6A,B5,28,7F,75,CA,D2,8C,F8,82,77,EA,DF,DF,8F,F7,17,EC,49,61,59,EB,9E,78,92,6C,C1,73,F7,37,E0,92,9E,ED,7C,57,39,27,51,1C,7A,45,E6,31,A4,29,3E,20,B9,43,DC,AA,D9,6C,61,15,9B,39,81,B0,6C,A5,FF,7A,2F,C3,34,16,42,E7,86,51,F0,0A,D1,93,40,8C,E9,65,74,7C,15,D9,6E,6E,C6,8E,A4,EA,B4,90,FE,1D,AD,CF,05,33,5E,CF,20,60,2A,9B,D0,42,47,16,26,43,55,A5,0F,75,02,7A,B0,0D,B6,FC,52,4D,51,4F,26,5B,09,B4,22,AB,06,DE,BF,D6,75,D8,12,79,EC,C8,63,B8,61,01,0A,78,BF,4A,B6,70,64,EA,3F,9F,92,DC,3D,97,AA,36,F7,82,42,A8,F2,97,92,76,23,BD,F8,F5,8C,45,C3,2D,BE,49,CA,05,0F,AE,A8,9F,59,03,80,ED,0C,E4,A7,C2,77,90,46,10,6F,D1,AC,DC,45,12,64,33,4E,3C,33,AD,EA,20,F8,92,A4,75,A9,E1,49,D0,DB,D8,EE,A1,98,F4,F5,E6,62,24,32,66,D4,E3,15,CA,80,90,E9,C6,3B,70,E2,11,2D,7A,5E,21,8F,3F,B9,29,16,1A,7C,A4,8E,BD,1C,DC,7D,D8,71,22,0E,06,8E,27,66,67,6B,9C,A6,F1,03,F6,B3,66,61,F1,67,73,D1,15,59,62,C3,D1,31,EA,44,CB,CE,4A,D2,2B,44,D0,4A,81,5F,AF,32,20,20,99,E9,BD,8B,FC,CD,3E,D7,6F,2C,7D,5C,C9,0D,A0,41,43,B0,75,43,70,9E,28,43,A7,8F,4B,5B,91,45,DA,F3,79,36,99,9E,13,FE,84,A8,A9,A2,B6,09,45,70,EE,52,02,AE,A8,9C,F7,E2,8A,0A,33,5B,47,11,0A,EE,7D,62,DE,5C,21,6A,60,E8,E4,42,BF,E0,E9,C3,36,1C,95,37,EE,32,BE,84,66,8B,21,EE,04,33,14,4E,EE,76,87,94,A9,01,B0,1E,22,54,1A,72,2E,85,0C,E0,76,E4,21,EB,7D,3E,F6,C3,DD,CE,6C,95,5D,56,82,01,CB,EF,A1,43,7E,EB,B2,17,57,ED,FF,B6,71,CF,F1,C6,36,1D,E7,6F,E0,09,06,13,AC,56,F3,F1,F8,7E,14,30,5F,BF,3A,85,0E,33,92,F4,E3,95,03,A6,5B,D6,20,37,0C,5C,95,72,B5,83,18,34,4C,CF,C4,34,96,E6,A2,03,A6,36,91,CA,1D,65,B5,A3,0C,20,14,78,D8,20,E0,22,0C,44,13,B9,77,F3,3A,85,75,EB,76,82,48,75,AD,FB,61,D1,69,6C,DA,64,56,64,CF,88,30,59,A0,92,F1,85,B7,6D,0D,1E,0D,58,CB,8C,56,A7,2C,46,5C,F4,0A,55,D7,48,6C,AF,D1,21,EC,4F,84,4F,6B,F1,6E,61,88,4B,7A,F8,D5,7E,7D,F7,89,28,08,12,C4,FE,8E,D5,B1,05,2A,C9,A2,57,8E,3E,99,E5,87,6B,B3,9A,81,7E,9B,2E,3E,2D,3E,DA,D1,01,D3,DA,07,8C,F1,01,94,DA,46,08,A6,15,24,1D,A5,06,BC,E9,C2,DF,40,64,E7,FE,53,67,5F,39,DE,11,63,7F,EE,D3,16,37,1B,3F,0F,53,8B,62,EA,C8,25,73,69,B2,E6,74,08,D4,76,F8,22,9E,D6,18,10,34,85,D5,A4,42,31,68,97,82,13,38,A7,CB,85,45,7C,8C,7F,67,AF,7C,62,FF,F7,8C,F5,74,63,07,D4,1F,C6,C9,45,F9,68,E7,C5,E1,53,5C,73,C6,C1,BB,28,7B,E2,45,0D,C0,6F,73,FE,DB,56,58,68,C8,79,BE,BB,DF,7C,C6,E3,58,A7,5A,74,21,CF,C0,3F,1C,E9,C6,1B,FB,FC,BD,D1,C7,EB,E4,AC,80,48,48,E7,67,E2,4D,4F,F1,B8,9E,62,DA,DE,10,2F,EA,FF,44,8E,DF,C9,AC,BD,53,AC,D9,02,F7,3E,09,72,AB,C2,C2,67,55,8B,49,42,AF,13,6F,24,1B,25,9B,42,BA,8A,C7,70,C8,AB,58,4C,1E,5A,76,6C,91,4B,F1,B9,FC,AA,D9,04,7F,34,BD,7D,95,D6,A7,87,96,D4,FE,48,D1,2D,AA,11,60,4F,32,1A,93,27,FD,F6,A4,28,A6,90,38,42,D6,6B,5F,6D,27,85,07,70,19,CC,E7,F4,B1,87,03,CF,EB,B8,DE,1B,9C,D7,95,86,30,AA,2E,2A,AD,99,87,14,85,3D,09,4E,78,CD,B1,B9,5F,06,72,3C,05,BE,30,3D,05,06,6D,21,38,EA,BA,E0,8B,38,EA,B3,74,98,4C,15,47,91,54,85,4B,92,AC,01,EB,0F,06,04,BA,45,DF,28,2E,ED,62,86,AF,83,16,BB,45,14,C4,2C,55,0A,F5,F8,79,A1,81,D4,CE,01,0D,B6,DD,B5,2B,19,1C,CC,E3,AD,DF,56,9F,C6,0D,99,11,58,5A,13,B0,5D,10,D0,C3,2B,B7,98,84,66,02,21,A8,04,9F,37,9A,F1,34,34,72,80,69,6B,80,60,61,03,52,9E,80,30,1E,CF,A5,D9,1F,AA,AE,96,CB,40,97,1D,AC,39,31,39,8C,FD,AA,F4,72,A6,CD,AC,D7,4F,26,72,63,F2,D3,79,57,DE,7F,53,42,FA,52,64,6A,A6,4A,51,DA,AC,3E,16,4D,C8,CB,D6,EE,3E,E6,F3,BD,65,4D,57,B3,F4,62,62,C8,3B,8B,76,93,5F,79,0B,27,63,65,69,AB,08,3D,E8,04,B0,E7,2D,03,CF,D7,CD,DB,3B,E2,EF,C4,08,DD,2B,23,B1,FA,AA,3F,D7,C7,EA,61,E1,8D,82,B7,E2,8C,B5,3D,DE,4B,2B,77,39,AD,27,AE,FA,E9,D5,2F,5A,45,45,54,A5,AA,A2,49,5F,80,88,93,25,81,51,CC,F8,9D,6D,0A,7E,AD,D1,50,B1,EF,92,BA,A0,DF,66,A2,B0,23,1D,9C,79,06,3F,26,CA,60,BC,A8,F7,51,3E,37,DB,77,6C,56,D9,5D,2C,02,5C,CA,5B,53,C7,04,02,A4,93,67,00,51,5C,FB,5B,5C,12,37,2C,10,EF,55,D5,75,B6,1E,CC,CD,09,88,64,BC,4D,A8,9D,98,07,F3,BE,42,B8,D6,4F,35,08,D9,EF,80,20,8A,86,96,9F,94,A5,43,C2,97,33,53,12,A0,82,42,2F,F7,05,06,2B,00,44,A5,33,35,35,DC,D4,09,72,7A,EE,77,62,90,09,D4,BC,4F,C7,FC,F9,E1,6F,19,3A,5A,3A,58,E0,32,03,CB,AC,06,12,B0,4C,8E,A0,25,E7,8D,A7,2B,2A,71,EC,C7,73,3C,FF,6D,03,1C,55,63,52,33,21,A8,BB,25,82,2B,A0,C7,63,B8,10,3D,0F,25,D0,82,09,FB,C9,83,E2,54,B8,B7,BE,68,02,2B,6B,A6,20,87,BE,85,4C,5C,CA,34,2D,97,78,6E,17,E6,78,51,F1,A2,20,A2,B6,B3,CB,77,AD,7E,D7,BD,3A,45,AF,E0,0E,6B,B1,45,29,60,A0,A9,90,C8,B4,65,63,72,2C,A9,1D,31,46,5F,FE,D2,CB,05,76,64,96,34,9F,A9,BF,A9,A8,3C,72,C3,45,98,C3,2E,EC,28,CD,FA,10,73,E0,0D,DB,57,B2,B9,FB,64,14,D9,A6,F8,9F,73,48,6B,34,FA,69,37,6F,9C,C3,E5,4C,77,E0,91,06,A4,EF,C9,AD,6E,8A,24,F9,BE,2C,1B,15,E1,B1,9E,BE,25,F3,D4,56,99,82,51,16,D4,D5,74,83,83,35,30,1F,86,51,B8,09,53,FB,71,F0,17,2C,80,CF,BF,EF,6C,D9,2F,10,03,68,FF,D6,50,F1,DC,EF,AB,03,4F,87,4A,CF,DE,97,4C,97,25,D1,8C,5F,BA,7C,8E,90,CF,BC,4C,35,13,2C,30,93,F0,A2,2C,53,4A,5B,8F,7A,D3,41,9C,78,CC,2B,0E,23,0F,9A,9C,72,5A,B6,F7,BB,55,F6,A4,6A,A7,E8,B8,A5,07,94,D5,74,EB,1E,FC,59,DD,AB,79,3D,B9,6F,88,43,4C,39,26,45,FC,C5,55,0B,84,1D,25,B2,32,60,AD,65,EE,B3,B9,DE,62,06,4A,09,B8,10,B8,B3,33,6A,4D,14,3C,FA,44,5B,A6,07,48,59,DA,B9,36,59,E5,4B,F8,F9,6E,E4,03,93,65,FE,16,38,DD,96,73,17,73,2B,BD,F1,D6,31,58,6B,56,9F,E5,A6,70,83,7A,6F,05,EF,40,46,B3,78,E8,2F,C8,9D,4A,6E,12,EE,36,7E,EE,3B,1E,B0,F6,DD,89,09,B6,12,2C,2B,33,D9,D5,27,A2,6E,BD,3C,5D,53,03,31,F2,50,11,55,8E,25,9E,DE,5C,45,66,DD,14,F6,A4,2D,C4,FE,4A,96,23,55,B4,F7,01,5E,7E,FF,FB,4E,AC,50,5D,53,E8,8F,61,B0,7C,DB,48,E8,A1,B8,96,6C,17,D7,4A,6E,AF,80,FC,56,3B,4F,F5,6B,11,3B,1E,50,83,16,39,D1,14,2D,60,73,3C,62,20,A9,5A,C3,98,8B,EB,D4,E6,A3,74,01,DA,C0,CF,37,4A,DC,A3,47,9A,46,01,19,86,A6,91,C3,8D,31,B4,93,4A,4C,C4,81,A7,99,ED,E6,A6,0E,40,E1,DF,33,F3,B6,44,33,1D,3B,E7,73,9F,04,B2,E4,F6,8E,45,F9,F9,9E,84,DD,06,56,90,7C,2B,1C,71,C9,76,5B,ED,E5,B4,89,4D,07,EC,A2,6D,E1,4E,DD,40,5A,D8,87,9F,E6,4A,7C,10,4B,7E,8C,69,FD,F6,22,C9,63,FC,AD,AC,EB,19,AC,7F,1F,31,C4,0C,A6,41,36,A4,52,21,F1,C4,6F,29,0B,F2,17,85,B2,02,4F,17,6E,1E,86,C6,2A,7A,F7,76,EE,00,31,D5,EA,17,BB,40,0C,E4,5E,E5,4F,0F,CC,75,10,36,AA,A4,1D,11,E9,7A,FE,A4,15,8E,5F,8F,65,9D,38,68,FE,C2,0D,3E,16,C3,D5,D9,D0,34,EF,9F,39,7B,83,4C,A4,DA,85,59,34,90,48,BA,29,CB,B3,2B,BB,81,19,1A,D6,79,AF,19,0E,39,CC,AB,18,CD,82,4D,76,6F,17,DB,FF,9A,C1,E2,4B,ED,B1,75,F7,B9,0F,D5,0D,51,31,B5,E5,07,B2,D0,DE,43,99,60,0C,EA,23,32,3A,73,08,99,17,DB,01,18,5B,74,51,DD,98,D5,05,E8,F1,2E,CA,77,E7,90,AD,C7,13,C1,43,1D,34,34,93,89,61,82,E6,C6,80,32,56,F2,54,49,3F,63,A2,38,FE,C5,77,53,77,F1,36,8D,14,03,1E,DC,E6,A8,3A,09,FC,B0,12,59,9D,4B,04,3A,17,4B,49,F3,1A,55,95,E2,86,AC,D5,63,E6,88,86,DE,D9,6C,E9,38,02,BF,21,C8,D8,4B,B9,B6,A3,F2,6A,24,62,F2,F8,0D,EF,5B,B3,FD,86,FC,5C,04,BB,55,E0,EB,22,49,1A,FC,64,1F,73,93,BA,FF,17,B3,65,5B,D7,AA,CD,97,F9,85,6A,C0,40,66,DD,EB,C5,08,6A,7A,2D,36,73,21,75,46,32,FA,EE,F5,71,0A,DD,BB,DE,4E,D7,21,B6,B4,47,5F,A8,3E,37,C9,BF,E8,A9,8F,77,85,E6,CB,0F,9D,E5,7A,68,D2,35,6E,9D,9A,CC,B2,A8,55,D7,F4,67,9A,CD,1A,2B,FF,93,16,B3,5F,7C,C3,FD,83,7D,0E,1E,0C,85,C0,41,1B,51,92,F8,8C,5D,0D,60,2C,29,26,F3,31,09,E7,7F,A8,78,1D,33,16,4F,B1,4C,F8,9E,A1,7C,9B,77,A7,57,15,8C,8A,89,6A,0A,7D,DE,C4,CF,F9,27,B2,9B,79,26,BA,4B,40,4A,0B,B1,AA,C4,DE,10,A0,0D,6D,B1,87,F7,20,93,B5,0C,BB,8D,35,9A,4E,1F,DD,0D,87,36,95,3D,17,5A,3F,6E,4E,87,CF,A2,A0,68,A8,A0,37,EB,29,B8,EA,E8,54,CD,27,D4,21,67,3D,D8,E5,E0,97,3C,F2,F0,04,BB,56,B9,53,0D,A8,3B,9D,69,28,5C,28,21,BB,A7,55,0C,16,BB,2E,DD,DD,85,97,1A,64,D3,FD,DE,79,A1,3B,C9,EC,E4,72,CD,A6,1E,9D,E7,20,F2,23,BF,48,12,6C,34,70,B7,33,25,50,1F,81,BD,71,E0,7A,4E,36,E2,B8,B7,A8,92,7C,FE,E7,C7,A6,E8,58,1A,A6,C2,DA,94,FE,25,30,35,84,D7,E1,D4,57,59,0E,C5,56,0C,55,46,F8,AA,C0,87,0B,2E,F5,55,E8,29,69,CA,F5,24,66,5C,CA,B7,FE,7D,B5,B9,60,50,7F,C5,5B,54,83,9B,4E,C2,BD,A7,20,F0,4E,22,D4,9F,4D,A4,E2,93,AE,D5,9D,B5,35,8F,41,D4,66,6E,25,9D,49,A1,BF,8D,30,CB,EA,4C,1F,A6,AC,2A,58,AE,C4,4A,66,51,3D,24,0B,D1,04,A8,F1,78,8D,0A,63,5F,9E,76,D2,FA,45,9F,20,26,84,98,B5,E7,A2,CF,F8,A3,97,1C,E7,70,F9,BB,23,F4,45,71,A7,3E,EA,A6,A9,60,B0,2B,5A,5B,A8,A5,09,26,4E,D1,14,73,50,27,E8,E7,A1,F2,94,71,B5,EA,CF,B1,B6,BA,EA,D7,5E,28,80,C3,65,DE,3F,14,20,B6,BE,15,9E,45,C9,D8,4F,20,19,9F,E1,C0,C1,EF,1B,77,B7,DD,00,AC,AC,55,E9,5F,80,E0,75,DE,10,57,E6,D5,25,D5,93,A1,6D,EF,DE,A9,E3,C2,0B,4A,A8,95,97,D8,81,A4,6F,0F,96,1F,04,E4,11,30,DF,1C,59,B9,4B,3B,83,07,C6,5C,7D,2E,25,35,33,CC,4E,38,0F,F2,BC,7B,F9,AC,C2,4D,55,F5,A1,0B,59,22,D6,83,70,D7,C3,B5,5C,C1,45,FA,98,A5,8D,2F,BA,17,91,3B,10,26,4D,8D,15,F3,8A,78,C3,D8,66,74,D4,F1,E8,29,5F,33,3D,C5,7F,17,30,F8,72,10,15,B7,E1,86,B1,62,2A,D7,30,D9,05,96,EE,04,E8,1C,3B,F4,C7,42,A2,B4,DE,46,4E,AC,DF,13,FC,8D,AF,71,56,B5,1B,72,22,E4,5F,52,F0,24,A4,B1,B3,2E,A3,E0,A1,B4,EB,96,E3,A3,FE,6E,96,EE,FE,9F,BE,03,8F,01,8E,7F,2E,F2,C5,F7,66,E7,7D,62,F3,B5,D8,47,31,58,32,77,96,5E,FA,16,BE,CD,FE,8E,4D,32,4C,4A,ED,1D,D5,83,51,7F,1E,A7,BB,87,2B,97,DE,5D,5A,06,C0,8D,20,F6,D3,30,00,E8,AF,CF,9E,6C,E9,3E,7E,B8,2D,9A,DD,1A,4E,2A,B8,6A,57,C3,85,A0,C1,55,7E,B1,77,86,FB,B1,58,11,BF,33,4E,DC,11,4F,35,1E,EE,95,F3,0D,1F,88,FA,50,68,9B,2D,05,98,41,18,D8,DB,08,D6,E0,77,72,B5,6E,F8,8F,97,DF,89,4C,FA,3E,62,AD,05,2D,EE,C6,F7,54,55,29,8E,76,00,87,9D,90,7E,B0,25,91,50,F4,8B,F1,37,62,64,F0,2B,DE,66,58,BC,92,60,0D,1F,F5,F3,34,C0,21,D2,51,0F,AB,45,C4,E3,78,40,E3,7D,49,16,BD,95,6F,4E,C1,F2,C3,AE,58,36,14,D5,4D,82,D1,41,E4,E4,E3,A9,81,8B,FC,55,C3,14,2E,12,3E,24,4B,74,1D,A0,37,D8,34,8B,7C,4B,75,3D,C9,DE,B8,DA,93,15,DD,99,37,9D,A5,37,08,E8,0C,40,5D,1F,18,B4,27,9B,DD,7E,3C,44,80,32,55,32,A7,7F,6C,97,16,3B,28,E0,F4,54,5D,51,70,D6,73,28,0C,FC,4D,E7,CE,EC,B3,21,D6,E5,63,4D,20,35,95,F3,C0,7B,D2,E8,09,6D,69,F3,DE,8D,50,EE,3D,A7,3A,08,15,05,59,5B,53,89,BB,75,70,08,FF,4F,AB,AD,F7,99,4A,61,CC,B6,BB,94,05,5A,68,FC,E6,35,32,22,12,9D,A0,A0,C6,D7,70,3C,DE,B1,47,34,04,F3,9E,0D,9E,3D,DE,D9,6C,23,6C,C0,C1,D3,6F,9E,29,68,BC,1A,1D,6B,A1,B2,D5,43,97,93,25,6A,59,75,4E,3D,03,33,F9,AD,35,1E,4B,9C,FB,3F,E7,4F,CE,F6,49,59,E9,E9,04,FD,24,4C,F4,D1,33,15,47,3B,DD,E2,E1,91,9C,4D,D3,27,10,AA,EF,D1,58,AD,75,00,05,3C,2A,E7,3D,8B,BD,38,A8,5C,4A,30,B2,BD,DE,58,35,19,4B,A0,D0,0F,47,AB,F1,33,81,E6,AC,FB,4A,B5,C2,8F,28,8D,A9,5F,B7,45,8F,54,A2,3B,9F,E0,B8,21,86,A2,16,3D,F5,8C,D8,B3,A9,7D,40,52,2F,FE,DB,B7,5F,06,11,71,B9,F9,67,FF,31,6C,30,F6,8D,8D,3E,26,E7,3C,11,84,5D,69,1A,99,1A,E2,DB,68,00,4D,53,DC,11,7F,41,AE,C4,1E,56,51,53,C9,16,0B,13,1A,3C,AA,5A,AB,E2,7B,57,EB,A9,E2,E5,12,F2,3C,A5,CC,16,D1,D6,77,BD,ED,BE,6F,30,0D,B6,05,C3,31,17,B8,13,9A,2B,09,6B,BB,59,79,C1,B9,9C,6A,B5,E1,2F,18,FE,31,ED,89,C7,43,61,FA,BB,0F,A0,90,80,FA,15,BF,D1,94,AB,B0,6C,3E,13,28,72,6C,AD,88,E8,0E,49,70,5C,DB,D2,B9,E9,3B,9A,AE,6D,CF,BC,78,BE,11,06,F0,50,46,4B,37,17,FE,67,43,55,42,2C,B6,CD,0E,16,37,1A,22,EA,6E,D5,0F,98,0D,89,83,06,C9,85,90,BC,72,F7,CB,91,D4,1B,35,18,90,A3,B6,33,45,D0,15,61,F1,06,8E,8C,7C,62,CE,C5,73,BC,E4,5E,62,E1,98,D0,7F,3E,A5,CE,8C,B6,C2,8A,37,B1,CF,A3,E1,B5,38,0F,82,57,FE,93,67,2F,8B,8A,3B,DC,CD,7E,87,D2,74,F2,30,BD,49,09,DD,86,97,15,FD,70,36,B7,30,37,A5,7F,9C,74,DB,7A,2D,64,67,20,23,4C,EB,B8,8D,86,88,5C,27,6B,EE,03,3A,0C,C2,B1,94,4C,75,81,11,21,87,11,CC,62,24,BF,2A,F2,BB,22,5B,A3,F3,B3,5E,DD,A3,13,0F,31,7F,20,E6,51,82,D1,79,E6,ED,77,08,7C,6F,F2,99,43,D8,12,03,1E,53,A3,C1,52,CF,12,0F,2F,7D,ED,9C,C7,55,3D,9C,22,D4,27,78,17,52,61,7D,CD,45,57,B3,E2,FF,0E,2A,0A,D3,73,CF,2E,73,E5,3C,8B,B9,0B,12,0C,47,7F,8F,62,82,B1,5C,6D,D3,AD,D3,A1,07,9F,79,38,0E,3C,4B,DE,CD,EB,73,32,AA,16,D6,7A,43,3F,EC,D0,A6,F9,82,AD,1E,76,B7,8B,5C,44,B9,38,AD,FF,4B,C0,F9,13,70,9F,C3,35,24,D6,A7,2F,BD,08,5A,90,8C,99,83,E7,2C,9C,C9,49,2A,2D,0A,D3,D5,51,E9,B8,3B,69,20,8E,F0,BF,44,5A,1A,6B,88,E3,BA,55,3B,80,F3,D2,1F,A3,5B,5E,E7,09,2C,D4,BC,2B,95,FE,59,AC,DB,BC,1F,6C,CD,EC,07,56,5D,17,EF,55,2F,1E,44,EC,EF,E1,7F,42,1E,9D,F4,A0,93,B6,40,18,B7,E3,DF,74,F0,7B,95,D4,E9,5F,91,72,BA,5E,B7,D5,F9,5A,95,A3,00,4C,04,46,EA,A7,2C,62,66,14,C9,E4,37,5D,55,4E,9C,58,09,2C,E3,E1,E5,90,5A,4A,7C,AC,42,40,F9,47,47,0E,7F,09,EA,06,E1,81,FB,7E,9A,49,FA,26,2D,61,08,25,06,57,B4,D1,42,C7,26,33,8B,35,53,1A,85,F5,32,21,DB,E3,D3,9B,A0,E8,AD,F3,A8,C3,84,BC,36,8E,36,18,90,50,E2,70,BC,57,E0,BB,1C,AA,73,12,E7,0A,01,D7,C7,6A,06,49,DF,17,9F,49,EC,6A,72,50,2A,E8,03,CA,BA,98,78,25,0E,01,18,45,35,20,AF,F5,C1,FD,02,E9,CE,D0,92,D6,16,D4,27,F4,99,C8,B8,2D,2A,D7,7E,20,BB,DE,54,5D,5A,47,D7,75,86,EB,F8,75,91,72,5F,FF,C5,5B,5B,86,DA,BE,D5,A5,3C,98,69,14,BD,C3,84,C4,BF,6A,74,A6,22,F8,81,2B,3E,00,A9,2B,41,31,51,5E,52,40,DC,3E,D1,FA,0A,36,C9,FD,A0,85,EA,EF,D0,4D,24,C2,1B,61,4B,E2,C0,96,9B,36,7A,34,9D,52,5B,19,1A,82,EA,9F,AD,FD,DA,D5,89,97,79,69,56,13,42,5A,F2,FD,E0,39,9E,D5,8C,83,84,2A,4E,38,DB,DF,6C,FC,5A,CD,CE,A5,27,72,BC,47,2D,53,B1,A2,E0,14,5B,F5,A1,D8,C3,47,0C,5D,4A,F9,EB,D2,4B,83,87,8F,E4,FA,5E,57,8A,EE,9E,8E,73,14,55,38,C6,90,4C,2A,B9,61,8A,6A,B0,E8,47,C3,88,AF,7F,4C,5D,B8,7F,FE,80,03,08,B9,BF,91,D1,80,6B,A2,9C,0D,E9,B8,D7,27,32,A6,43,9C,3F,0C,AF,CD,EE,CD,5B,06,AD,B4,56,BC,28,74,46,DB,E8,13,1B,1B,08,C8,47,7D,7A,A7,7A,D8,AA,1A,DE,B6,41,5C,B7,5C,3B,1F,90,55,F7,3A,20,B3,50,AC,66,79,48,38,7D,06,12,3C,8C,FA,A1,3F,C1,CA,CA,CE,31,DB,F7,11,E6,FB,81,64,4D,B0,DB,26,66,38,52,94,B2,C1,2B,35,56,FD,01,0C,C1,E6,69,F3,40,83,0C,A4,71,00,87,A5,A0,C2,BC,10,82,80,EC,3E,F3,EA,EC,26,7C,41,E5,04,A8,9D,C7,5B,C8,1D,F8,97,8D,54,AC,F9,B5,35,31,AF,67,CA,E8,B7,E0,01,9F,2E,27,9E,1F,00,D6,47,4A,DC,19,AE,9D,5A,1F,23,83,52,FA,E9,A0,C8,DE,4E,32,06,BF,F4,8D,82,78,1B,98,72,62,5B,37,50,B5,65,A4,1F,AB,38,C6,FC,B4,72,83,49,22,1E,38,29,72,53,1B,ED,69,3E,9F,9F,2F,DB,46,90,16,B1,33,1A,CE,93,DC,DC,80,FC,F7,20,B5,00,E3,81,90,79,C7,36,09,41,16,FA,A5,FF,FB,60,BF,C2,F9,16,16,EC,C8,B0,F0,7D,71,D0,56,42,E0,13,03,A9,DB,A3,ED,64,17,F1,71,62,56,D6,FD,E9,55,C9,44,ED,48,EB,7B,A0,DD,E3,B2,1B,C8,9E,BD,68,43,D5,BB,41,39,E7,0B,58,30,6E,D3,85,8D,1A,DE,29,90,0D,D1,F3,63,28,D8,FB,67,01,EB,5E,CD,B0,F8,85,D4,6C,FE,31,64,36,66,A8,35,F0,B1,BA,7C,D6,77,47,61,9F,31,CF,11,2C,4B,2B,87,41,8F,49,08,1C,31,47,AF,0D,F3,7D,73,A7,76,E4,7B,67,4A,D8,F5,0B,66,8D,8C,23,3F,E9,15,84,88,11,58,8A,40,3D,E8,8F,49,5D,08,8B,73,B4,FE,64,A6,E9,A2,CA,89,8D,B2,78,2E,DD,1E,35,EB,7E,D8,F0,74,C5,96,90,54,4B,1F,6F,B7,EB,0B,89,5E,AA,85,88,86,02,31,98,B7,E0,E8,02,39,88,6A,9F,65,C1,8E,47,40,2E,2F,F9,45,9F,78,2A,28,0A,8D,17,24,60,C7,6B,D9,1C,49,B2,5C,81,95,9B,BB,AE,8B,EA,A0,72,CF,93,E9,19,9C,D6,99,D3,C3,D9,DB,92,93,29,96,2D,8C,A8,27,A8,2F,84,2E,BB,97,B0,B6,D4,AC,AA,72,B3,77,C9,5E,64,CA,5D,6D,1E,37,63,07,C1,C4,66,77,8B,A5,9D,11,2B,C4,B8,9A,64,72,7D,4D,A2,BE,C6,55,72,AF,0C,AF,4C,B8,87,53,02,38,64,D4,0B,74,F2,AD,3D,70,C7,B2,2C,DA,B0,82,6F,7A,D5,A9,D6,5F,76,EF,F6,8F,A6,00,3E,A6,D1,C3,EF,EB,07,4E,5E,EB,12,A0,3C,3D,4A,33,10,01,DF,D4,39,97,B9,8A,34,13,BA,A4,26,07,65,19,DF,70,DD,A3,3E,8C,EF,84,78,D1,7C,D9,B1,29,D0,E5,67,77,EF,11,FC,5B,DE,EB,91,51,63,1D,54,32,99,AA,FC,80,DB,D8,24,E8,A8,39,4B,77,CF,F5,3A,80,62,0F,E5,60,BC,E6,5F,3A,55,22,B9,B3,47,1A,81,89,12,D6,DB,58,B7,B3,60,4C,4E,1E,5B,73,58,2E,93,6E,01,12,B3,A5,62,05,11,58,CB,7F,86,64,ED,95,AC,21,0F,11,50,FE,9C,A0,74,28,4A,59,08,39,3E,76,36,3A,31,8D,76,16,5F,E6,F9,11,6E,0E,0F,88,50,06,D3,A4,20,73,9F,45,A5,03,6A,CE,33,B0,0C,D2,F8,B0,20,BF,42,DC,3C,86,A9,60,23,D5,C7,79,37,C1,BC,CE,A0,56,12,3A,7D,DA,FA,28,9C,08,EF,41,0D,EC,67,1E,20,52,71,B8,44,CE,90,D5,F0,3F,CD,DE,C2,B8,BF,66,B2,F9,9A,12,05,79,7F,2B,84,89,79,FD,8D,EF,F0,F9,46,9C,F6,D4,BC,9D,2C,45,38,9F,B8,EF,73,EF,8E,46,91,38,1F,2E,A9,3B,10,26,07,E9,29,E7,2E,E7,E6,C9,9C,5E,6A,D8,87,43,30,33,B9,14,86,18,40,96,77,A0,A7,FE,36,61,60,3F,DA,43,BB,93,76,F5,E8,68,CA,DB,84,06,FD,C4,E7,5E,57,D4,91,1E,1F,E8,51,34,29,98,95,47,A1,BC,A5,34,FE,48,CA,E2,DC,D3,F6,3B,CD,FF,D3,87,B9,DA,F0,63,16,4B,53,5A,59,87,B7,E8,79,D1,19,59,51,49,39,DA,5E,84,4E,FC,AD,7E,7B,9E,F0,67,14,7E,2B,07,B0,7E,EC,94,C2,18,DD,D4,78,27,EE,1E,6B,05,C4,8F,13,99,BC,3D,ED,5C,C1,13,30,94,3D,B2,78,59,AE,78,94,32,42,5D,DC,28,0A,F3,4F,9C,BF,76,BC,4A,8A,03,A9,2B,39,5D,12,EE,EA,26,84,92,0C,1B,89,9F,93,9C,A2,13,B4,DE,59,98,79,EE,CF,B6,E6,13,4F,00,D5,CD,91,10,A0,9B,F8,BB,C7,CA,40,71,7C,EB,B9,4D,0A,87,EE,60,D5,DE,24,74,25,CE,D2,A1,E5,38,94,27,6F,CE,47,5F,D8,98,1D,E2,CF,FF,EB,97,7F,4A,4E,3F,06,F4,2E,F4,8A,E9,15,B2,B0,9F,35,F5,82,1B,BB,A5,CF,40,FE,6E,9C,0A,2A,E5,13,38,4A,87,BC,A7,72,18,38,EF,39,F9,8E,87,FC,06,71,BB,3D,05,31,67,ED,BA,A5,AD,F4,19,76,15,E9,4D,1B,21,09,C1,DE,84,4F,15,3A,81,89,BE,96,F4,F2,8C,D5,C8,F5,03,21,63,E8,39,9F,74,DD,07,DE,C9,E1,B3,DE,35,3B,04,FF,26,9C,6A,02,67,41,F9,CC,20,02,43,42,2F,22,BF,92,5F,D7,76,18,68,6C,4A,39,66,48,99,74,39,3A,BE,77,19,4B,98,ED,BA,6B,C2,06,D1,70,B7,8D,6D,15,84,0C,ED,BF,4B,F9,F1,0A,4E,B5,5B,E3,45,A5,CF,F6,F1,E2,DA,9E,F1,EF,6F,0C,4A,C0,F6,5B,8C,C7,C6,DC,E0,E8,0C,72,92,D8,C8,F0,A2,ED,21,86,EA,83,E9,4B,EB,53,08,A3,E2,D6,92,16,27,AF,E6,D7,2E,AD,7C,D5,FF,D0,82,21,7E,0A,CB,49,7E,14,F4,4F,CB,8A,6E,32,FA,23,D5,8D,0B,D1,AE,39,63,60,3F,B3,04,38,35,42,62,50,38,61,FB,DA,89,18,87,3F,5D,E1,44,24,DD,21,90,1F,A0,24,31,DB,20,36,6D,92,E1,87,38,ED,4A,62,EF,24,EC,80,07,C6,D4,E9,06,82,0A,AF,0E,BC,24,81,A3,26,5C,50,8B,CF,B3,FF,2C,05,3D,1A,D8,45,D4,16,FD,8F,CB,A8,48,4A,49,74,6E,76,F8,B8,98,34,07,7A,2E,36,AB,C5,58,32,A5,6B,4A,A3,F9,52,AC,31,6D,60,F7,C9,09,7D,6E,33,0F,FF,CE,13,0D,A3,9D,7A,C7,16,24,27,8F,AC,2B,69,0F,DC,65,28,B6,EA,93,E0,32,07,23,75,02,47,F6,40,BE,F1,6C,FA,D7,19,2F,A8,BA,A3,58,CB,ED,5C,EA,32,25,A3,18,2E,28,4C,EE,CE,99,30,59,EA,82,16,8C,7A,3D,E5,D4,33,BA,35,87,2E,61,BD,86,51,DC,AC,51,85,AC,EA,C4,7E,E0,99,85,58,CF,7D,96,8B,97,A2,59,58,72,5E,85,58,5B,93,B1,7A,E6,E1,F9,4E,78,48,13,1A,9A,21,C8,55,79,71,7A,A8,86,FA,C7,74,45,59,EE,12,58,ED,FF,5A,DD,EC,5A,59,39,70,32,46,10,9E,EC,83,AA,64,66,05,61,38,74,C8,C8,7B,CB,46,CC,FD,98,4A,8A,3E,B6,22,1A,FD,E0,FA,B2,03,46,E2,33,AD,0F,0A,2C,EB,D5,AF,2A,57,C0,02,92,63,18,75,8A,A1,AC,C9,D5,12,06,D4,F0,BD,B8,09,63,6C,47,41,79,28,A4,93,59,DC,22,97,22,83,14,F7,D2,51,99,3A,11,8A,35,39,48,08,8D,D1,98,6C,A1,CA,5E,09,1A,17,DF,F2,AE,FB,AD,D2,EC,48,68,06,F1,71,A3,42,B7,A9,B4,A9,6B,39,BA,16,71,CE,78,34,61,EB,45,D5,EF,25,5B,AF,0C,E3,37,04,8E,EE,25,64,28,D0,AB,8F,92,68,13,11,7E,11,F9,7A,FD,B7,3A,86,00,48,82,26,64,CA,3D,70,71,56,F3,47,27,8C,AA,B3,83,8E,B8,B2,8B,5F,FC,C9,AC,D6,01,DE,DC,9B,90,C9,D3,DE,C1,73,74,26,6B,36,60,5A,86,1C,48,A6,FF,D8,7B,D3,63,69,10,C2,7D,B6,8C,C9,68,AF,AF,E7,EB,94,B8,80,8A,BD,FD,3C,09,95,E5,E2,D0,9C,3B,18,6C,9B,4F,1B,14,7B,6A,E9,DA,55,EA,7E,28,3B,1E,1A,50,F4,31,FA,F2,9F,F0,70,5A,8F,EB,EF,DF,42,DB,2A,92,E4,72,91,18,54,AD,22,60,C9,92,F7,0C,B0,6D,36,B8,80,69,EC,88,2B,25,6E,E7,D4,F5,5A,A5,9C,25,F6,7B,E5,A1,4C,09,93,46,3D,CC,61,05,D8,2E,3E,3C,76,81,EE,96,40,56,F3,DF,77,5C,61,E5,06,87,A0,78,DD,D3,E7,CC,76,A1,0D,A5,B3,57,00,A2,6C,1F,3E,60,FA,25,35,C1,C6,10,74,BF,22,3C,23,78,33,FC,BF,99,C8,B9,A7,A5,13,57,BF,BB,79,95,4D,F6,6E,09,F8,33,C1,B9,0D,D2,75,C0,14,8D,FD,D9,53,1D,E6,1E,C1,AE,CB,D1,F4,8A,66,68,3C,DB,AD,E0,A8,5D,3E,91,53,B9,4C,C5,29,18,CF,08,EA,28,A0,31,5C,C7,0E,FC,12,1B,89,47,9A,18,79,7F,5A,DB,B9,6B,DE,F1,B3,80,D5,36,61,54,DA,EB,7C,AA,67,8E,9A,E0,0A,E5,8D,49,B7,D6,12,52,C1,31,2C,BD,C0,CC,A5,44,90,3A,BA,FE,2D,09,B5,AF,CE,2B,02,86,A1,97,CE,3E,40,F2,1D,21,1D,8A,44,71,C9,86,5B,EA,E7,D7,5C,71,0A,05,F6,E2,5C,B3,31,CD,D6,9A,91,F6,0F,6F,48,5A,9D,8F,30,D5,09,42,4D,03,52,A6,DB,68,9B,06,CB,19,9E,06,21,C5,4D,52,0C,DF,E7,BA,F5,75,D6,8C,DC,B4,5B,57,1F,44,16,96,A2,B6,13,8F,BD,D0,59,53,85,FB,63,46,F7,AC,17,C2,30,40,8B,E7,BB,16,AD,83,6E,00,B3,54,57,F7,B1,28,98,B8,5F,EA,39,8C,DD,77,8D,88,08,F8,56,7A,E5,28,BD,94,8F,04,74,1B,98,32,2B,43,30,37,64,8E,DC,D5,3E,C0,5B,E3,CB,9C,3B,12,D2,C6,03,8C,D0,1B,F7,A0,EA,C8,BB,28,01,8E,1D,37,A8,5A,78,A5,A1,E5,50,6F,78,F2,9C,22,DD,C0,D2,7E,3A,17,63,AD,07,2F,31,EA,6E,93,51,75,47,0B,29,EA,52,1D,F3,52,5B,0B,E6,72,A2,99,F9,FD,EC,F9,47,87,40,B3,E8,D3,D3,BA,EA,92,09,CA,38,63,41,83,3D,9F,DC,02,FE,82,F8,49,FF,F5,D1,BA,CF,39,AB,58,60,0A,B0,D5,69,39,08,2F,44,7D,7C,13,38,74,D3,46,46,9C,7C,3B,B7,6D,B7,81,FC,DD,42,BA,AA,E6,CE,BE,B8,F6,58,60,39,D1,D8,6C,47,CD,38,40,CF,EE,C9,3B,5A,11,8F,77,9C,3C,1A,A1,78,B9,8C,26,4B,FE,56,F2,F1,0D,F1,E0,EA,E3,C3,BB,D0,42,C4,A5,4D,4F,0A,94,EE,24,0A,2C,74,F4,16,B6,E1,1E,85,37,A0,4A,A4,54,E6,2A,2A,8D,56,D5,FE,B5,41,81,DF,95,0E,7C,1F,A5,DF,12,5C,7B,57,82,26,D4,0F,85,2E,24,D8,7F,E5,A0,C5,94,01,42,CB,47,B8,BD,15,21,D2,0A,67,26,6F,E8,5B,02,5B,07,27,F4,82,36,9B,07,0A,77,6C,28,EC,14,C6,74,E8,B0,A6,FF,0D,19,67,4C,E1,95,E1,67,D6,D3,0D,28,62,EF,D0,53,C5,B0,A3,B5,25,D7,D2,81,A0,32,09,11,DB,2E,81,23,E9,37,33,B1,99,26,D3,69,1C,A9,8A,67,74,D4,25,77,F5,1E,33,97,60,75,1E,0C,A4,77,54,ED,81,9F,FA,EE,6F,DC,1C,D6,B5,57,E3,1F,E2,A8,81,7A,D6,CB,46,B4,DD,F6,08,C0,D1,15,CC,41,AC,4A,32,54,BA,73,09,9B,7F,15,B6,2E,C6,DE,88,62,56,51,B7,8E,AC,CE,9B,CE,1F,BB,46,9F,DB,5F,AE,42,D7,2E,92,BC,19,E9,CF,B9,84,02,1F,8B,18,36,3F,95,20,2E,24,B4,C4,A5,3E,7D,39,EA,91,55,6C,6F,C3,CD,C2,85,A9,55,74,C6,08,0B,28,BA,EF,F0,6D,B0,5B,B8,81,09,F0,95,DC,44,AA,E7,9C,A8,6A,97,95,77,8A,B6,31,7E,A3,91,A9,5A,09,31,B6,42,09,EB,7F,E6,64,39,E3,9E,BC,0A,F3,8A,48,7A,78,42,58,FF,5F,9D,6D,9E,9A,AD,57,F3,F1,C1,C6,53,E9,A6,8B,2F,80,2F,DC,17,B4,8B,DA,0F,0D,E2,7B,0A,25,ED,FD,0D,21,EF,0F,C4,74,F2,A9,89,CB,60,CE,35,85,2B,11,73,E3,D5,E6,DD,33,9C,C6,A0,76,D9,11,2A,A6,27,32,A7,CE,11,12,EA,60,64,AA,30,87,AB,75,FB,4F,D0,2B,15,23,89,21,4E,85,90,85,F1,C8,D5,96,1F,BA,45,50,1F,1E,B9,FA,5B,2C,1D,79,A6,64,29,C1,D3,A6,29,FC,E0,C2,00,38,A1,2E,C5,EC,9C,2B,B0,BA,6C,EB,24,DA,3B,AC,87,22,09,7B,B4,B3,20,FB,75,00,54,96,F8,AF,D7,16,30,84,59,29,F1,10,CD,17,28,D4,F5,A5,6C,26,84,9D,87,36,B6,47,5D,88,B1,06,CD,97,84,E8,71,F0,7A,72,DD,01,82,50,C8,21,8E,47,F3,79,48,46,E7,D8,CE,07,8B,C5,C4,EA,07,61,12,E8,F2,5B,66,D6,CB,BF,2E,D8,F8,94,5C,48,59,06,CE,78,FB,28,59,E0,C6,E5,3C,BA,11,E3,06,DE,FA,4A,A9,47,2C,55,09,E0,50,0A,D6,E7,67,6E,BA,65,FF,E5,4F,87,65,9C,49,47,19,98,8B,07,B2,11,A8,1E,CC,29,2F,67,0C,9B,C1,80,B6,E4,06,33,B9,FB,98,F2,49,DC,44,0F,9A,3D,F8,D6,A4,08,21,56,E1,FE,94,1B,FF,20,83,2F,48,02,63,19,74,89,60,97,61,0B,95,CA,AA,B9,88,34,AF,88,24,5C,B8,74,6B,B5,76,95,EA,86,C5,53,1E,18,1C,18,A7,C3,F5,9A,02,74,7A,BF,C8,24,1C,C1,EB,88,6A,EE,F2,33,A4,FA,6F,98,13,B2,02,8B,D4,8E,F6,02,F1,F3,18,42,7D,75,6D,D9,41,29,9D,09,C1,8C,4E,F7,7A,36,0F,43,07,9C,72,91,CE,B3,1E,5F,02,B1,1E,DB,F7,F8,9F,58,68,EE,C4,9D,A1,D6,08,F8,FB,69,7D,76,4B,EB,78,47,E4,E7,61,9D,C0,AA,A9,EB,81,9D,B8,EC,B3,DF,77,C0,35,8A,DD,8C,66,59,A3,1D,75,3D,8A,C1,34,2E,B0,98,DD,FA,9C,2E,57,8A,C9,9F,D8,13,75,A7,86,37,75,9C,71,8B,67,25,DE,6A,E5,1D,B2,7F,09,8F,C2,49,B8,1F,52,1F,F7,EE,E6,03,41,BC,0E,C7,B5,DF,15,B6,87,1C,66,20,5A,3B,55,DA,C1,46,59,20,09,F4,CB,25,21,00,25,11,3E,77,DC,4C,E8,D9,BB,01,DE,DD,0A,3F,3F,F0,0A,07,A8,20,23,45,3B,03,3F,95,4D,5A,B2,1A,15,44,A9,3E,D6,E3,11,8B,87,9D,A1,AF,CF,E4,69,BD,01,62,54,A4,D8,23,06,FA,E1,84,43,73,3F,00,70,B4,7C,77,69,23,F1,58,4B,F6,78,D9,B9,45,3B,7D,E8,FB,CA,59,E0,7A,A5,70,A7,2F,4C,B5,5F,57,F0,AC,FA,3E,62,4A,8C,45,2B,52,79,3E,84,9B,74,F6,FF,01,F0,21,BF,94,BA,2B,22,97,ED,AC,D7,B1,83,A9,CA,71,FF,20,D8,F3,57,EB,43,E2,DD,EC,0B,71,AE,F9,D0,9C,B6,48,AD,8C,17,B4,6F,14,BC,37,48,80,03,C3,C9,A6,8C,43,B6,45,A3,13,DD,E3,C3,55,A2,10,0B,67,F1,8C,51,28,00,B8,B1,95,15,A5,A8,91,BB,6C,59,A2,72,BB,71,04,C2,9F,FD,F4,D0,26,64,AB,D9,4C,F8,3D,88,30,19,DF,CE,E5,63,71,C9,79,8A,E3,A3,1C,FC,2F,F6,29,8B,57,3F,2D,3F,2D,14,83,1B,6E,D9,D6,8E,25,9D,1D,37,72,0B,CA,7B,7A,08,0F,A1,DF,1F,23,DE,F5,1F,FD,4C,52,E9,02,F5,5E,13,52,E6,FA,65,9D,21,AA,02,62,51,FA,48,8C,B3,A9,7B,35,5F,44,81,5B,F3,78,00,62,16,A0,0E,2E,23,47,56,0F,6E,5C,79,46,25,41,8B,6A,AD,B5,12,EA,F3,E0,7A,BF,AE,E4,AA,AC,9D,2D,1E,35,2A,58,47,32,3F,45,7D,10,8C,A4,21,B8,E5,6A,77,AE,0D,32,CF,A1,C5,5E,D2,95,79,7D,2B,9F,C2,E8,5D,5B,F5,45,C2,FD,4E,F3,27,15,F1,C1,95,3F,80,A6,64,20,6B,1A,92,85,82,AB,61,CB,7D,55,D3,7E,52,22,DD,03,67,1E,9B,62,C1,7C,F5,9E,91,8C,E6,0D,77,82,D4,6D,CE,36,A1,2E,CB,B4,39,47,71,A8,ED,66,DC,46,47,61,21,8A,2B,F0,35,9D,86,B0,F0,9B,43,AD,EB,73,EB,6E,02,AC,BC,95,F0,91,F0,99,9D,62,1D,E4,1A,B1,7D,B0,8E,73,93,02,DB,F6,61,8F,80,94,06,3C,7A,44,58,62,55,E3,61,9B,34,B4,8C,97,62,CB,B9,BA,7D,83,E1,96,DF,A5,74,79,DB,AC,4E,B5,A5,97,66,44,A0,73,E4,D3,05,A0,33,5F,F2,ED,6E,5A,D6,B3,97,DD,AB,7E,7A,02,4F,B6,C2,BF,04,41,97,35,54,5C,43,22,2B,25,DE,6F,93,96,91,A7,EA,3B,77,4C,97,E3,23,63,6B,C0,6E,E7,32,74,CC,A2,F9,F4,08,51,CE,A7,9E,5D,EF,52,05,E1,C8,4B,6F,38,6C,EA,18,CB,4B,62,66,FD,B6,19,68,C9,BD,3D,92,4B,EF,AB,75,57,0A,12,F3,26,40,D3,2C,83,C1,67,9E,98,86,A4,42,6E,16,E1,64,90,06,FF,C9,6B,D3,C0,F7,96,4F,DB,9C,10,A2,01,61,35,4F,0C,D1,AB,69,04,67,08,E2,80,89,C2,6F,73,C0,16,D4,78,9C,55,44,43,D3,C8,DB,D7,ED,DB,B9,64,7F,6A,89,31,8D,06,45,94,C1,7C,B0,EE,D3,DC,38,70,0D,00,7F,8B,BD,EC,86,3B,09,8F,7D,42,89,F5,21,9E,44,7E,E8,A6,CE,B0,3C,88,92,43,24,56,1C,A2,BE,89,0C,17,6F,19,82,B0,5E,0B,75,AA,29,49,C0,14,D9,CE,3A,0C,D8,DA,76,A8,0C,D2,94,D6,25,33,1A,25,0E,55,B5,3F,ED,38,64,88,1A,82,0E,53,F7,77,FD,8A,A1,E7,E0,37,18,EF,42,32,04,C7,67,A5,BD,E6,15,4E,BB,ED,2D,CA,C3,4F,EF,F7,C5,01,41,14,50,27,BF,BB,88,C7,24,E9,AB,AB,A5,7F,C8,D3,77,21,82,02,D4,8E,CA,13,CF,2C,2F,40,22,38,45,9D,05,1C,14,D1,98,63,8E,1F,B9,33,B1,71,19,67,7A,BB,2F,E7,2B,97,E1,01,27,A4,56,1B,F6,AE,78,7C,41,C6,99,47,90,40,80,73,77,45,AD,8E,10,96,81,BF,DD,2B,D9,9C,6C,AA,CA,5B,DC,72,A1,7D,4C,9B,5C,08,D6,31,99,0F,5D,9B,F7,CC,AC,C8,5F,62,24,4E,92,78,04,FA,D7,89,83,83,96,D6,89,C4,CD,89,36,49,26,49,26,B5,28,4C,28,D2,19,FF,16,E8,22,15,FF,F7,DF,78,FB,59,5B,EC,EE,45,C2,BE,08,91,68,2A,C6,C0,FC,AC,FD,AE,49,02,E5,7A,AA,2A,D7,37,69,34,86,14,0D,B5,78,00,E2,10,D5,F4,8C,3A,7B,41,BF,28,5E,DB,55,68,B8,2D,C6,94,0B,62,0B,39,85,92,BD,78,65,FF,C5,75,D7,D3,8B,FB,AD,B8,C5,12,87,D6,6B,C8,60,8E,70,FB,9C,A5,03,05,F4,E4,C9,D2,94,A9,7C,F3,E2,1B,4B,CA,E3,BA,F5,66,9E,A6,76,15,AA,20,55,19,D0,4B,CE,2E,5C,E8,E7,AF,07,43,60,26,16,EB,9D,80,E7,92,A6,CA,92,85,52,5C,CE,3B,CE,14,57,62,57,EC,73,50,9D,9F,A4,EC,A4,72,75,00,BF,D4,F3,B6,A4,94,3B,0B,27,D1,D4,E2,71,1D,67,DD,CF,7F,51,DD,06,A2,64,F1,B0,EA,8B,7A,1B,EF,96,2D,A9,FD,2A,72,26,4D,D2,C4,B5,32,BA,83,6E,A7,12,B2,10,C3,96,66,D8,81,36,C5,BB,E4,7C,8D,D6,69,31,9B,DA,5B,75,48,50,4E,56,B1,C4,5F,5A,FE,28,11,C7,D1,64,6D,14,EA,0C,32,F8,A7,A7,D5,42,A5,8B,E2,CE,22,54,A9,37,76,09,C8,84,A0,8C,A8,A3,EB,71,14,8F,47,5D,03,4D,FF,5F,8B,9E,96,48,53,14,7F,13,87,E7,92,28,50,D9,CD,DE,55,C9,04,D9,B4,C9,55,01,65,C6,F6,56,CC,38,92,50,6A,3F,82,9F,0E,85,FD,2F,0E,21,C3,42,A6,78,DC,0C,39,C6,57,7D,D6,CD,A2,71,15,FE,B5,07,7D,23,AE,73,DA,62,64,27,A9,C5,65,84,A4,B3,37,B4,B3,89,BF,FF,BD,74,A9,EB,00,F7,61,A9,59,D3,49,45,7E,21,B4,34,2B,E7,5E,61,CB,2F,D2,63,F7,5E,1C,E3,6E,F0,57,F3,91,B7,AE,CC,4D,74,8D,D8,CB,2C,5B,D7,1F,F5,00,59,DB,E8,C4,EE,C1,D4,6C,BD,D8,7B,30,C2,79,96,89,96,66,15,32,F9,26,D6,4F,15,2D,E8,F1,D4,05,52,EC,87,F7,3E,E6,ED,8E,CD,20,48,1E,2D,27,97,5F,D6,73,A7,84,14,4B,27,E6,24,CD,91,40,F7,0B,1F,EC,1E,AC,9F,1E,0E,D2,25,EA,28,C1,7A,42,3F,E2,34,91,8B,16,D8,51,12,18,91,4D,B8,78,41,4B,8C,40,8B,92,CE,99,7A,02,0C,62,E6,0A,21,BD,71,4C,0F,D8,5D,76,30,F2,84,42,4E,08,8C,07,E0,02,33,38,2B,FF,60,51,97,D3,05,1A,E5,4A,E5,84,BA,A0,13,BC,B7,E0,4D,08,EA,99,9C,AB,17,2A,E3,2E,A1,D6,CD,56,C4,29,26,26,FE,0A,2F,2F,A7,C1,58,D9,1E,98,E3,00,75,DB,F5,A5,12,BE,AA,B7,43,AF,D9,4B,F9,ED,3B,CF,00,73,C9,73,55,93,45,5A,F8,33,A5,B2,92,FB,9B,80,AD,3B,B9,52,22,A2,38,7C,4B,F9,5F,87,29,6D,7F,54,F5,3A,83,58,69,10,78,D5,C3,82,93,FF,7C,EE,08,47,90,F0,5C,62,A5,56,D7,38,1F,BB,BC,2D,D1,6F,E4,2A,4D,06,F7,0E,2D,9E,95,95,2B,A5,C9,C3,CB,B8,07,D1,43,0A,B9,81,29,89,06,B7,B8,42,B8,91,E0,54,6B,26,6D,24,A6,07,B6,B6,85,B2,84,68,4F,55,61,78,8D,F3,8E,CC,23,A6,95,AF,8F,C5,99,B3,DD,AD,1A,1D,CE,5E,54,57,EC,2F,F9,DD,98,10,8B,3C,1A,CB,72,73,2F,03,84,39,71,08,38,A9,56,55,56,ED,DD,3A,74,5A,84,F2,45,F6,F3,57,A2,F8,26,8C,3C,73,D1,45,E3,9B,F9,9E,C0,12,BE,EC,FB,24,9F,23,E9,6D,FE,70,7A,A6,90,16,19,E0,A8,5B,CD,B0,3E,C2,27,C2,85,04,95,E3,E0,2F,41,32,E0,4C,F4,08,36,84,0C,DA,53,E9,A3,86,10,65,B1,1A,4A,9E,D9,7B,77,E3,29,1B,9A,45,5E,4D,9D,61,2E,68,E9,93,1A,95,1C,7C,89,EF,6B,52,0F,80,48,9A,12,F4,61,B0,2D,DB,0D,CA,3D,EB,07,7B,EF,4C,25,35,8B,82,D6,BD,8E,CD,27,24,1F,AE,63,88,9A,72,26,27,1E,C0,E6,6C,46,E3,07,20,0C,93,FB,16,13,83,88,77,4D,90,88,68,6F,B6,01,89,CF,0D,2F,EB,7A,E8,2D,FE,25,8B,AC,18,EE,37,0E,8A,BB,53,B8,5F,11,43,7F,D3,C3,F0,1C,90,52,99,09,DB,E7,2F,64,65,98,31,AC,5C,96,2E,97,5E,FD,BF,75,BC,BC,CC,C7,E0,E7,BF,85,47,81,93,48,B2,C5,F9,F6,43,D4,73,60,4C,39,1F,10,B1,05,4C,2C,A1,5F,90,68,00,EC,07,DF,AB,27,83,6F,53,9F,8D,4F,9B,85,40,85,A2,4B,6F,B8,24,E1,EE,BC,46,9C,3A,AA,0E,8C,A3,92,C1,CA,EF,75,2E,7A,DC,68,D4,24,5A,09,3D,BC,B1,1D,EE,9D,2E,45,49,B0,77,77,EC,91,91,00,48,66,43,92,87,EA,58,3E,C9,A8,0A,D3,0F,CD,BC,8A,A4,3C,49,8C,15,00,6A,66,1E,65,97,6A,16,57,F2,33,FA,93,25,CB,1A,E9,41,D8,E4,2C,B7,7B,EF,A0,2D,BE,59,CD,60,B4,88,CF,19,D7,AA,43,44,2E,01,1D,32,62,3A,9E,9E,19,2E,83,FF,54,1D,72,B1,16,39,42,D7,0F,BF,3F,71,D5,56,86,B3,F9,C3,9D,09,8E,8F,24,70,81,CA,CC,A5,2E,C2,D6,C4,72,AF,3F,AA,12,E0,6A,0F,06,CC,CB,7F,A4,6D,4C,A2,7A,45,3C,22,B0,4E,5B,A8,3C,6B,F4,6C,FE,57,8F,EE,36,4C,37,F5,F6,07,F3,F9,1A,F0,4E,C1,C9,3F,15,19,D2,D3,42,FF,C7,C6,95,28,E1,E6,67,05,C6,FB,68,8A,B0,E9,7E,11,5C,94,E2,91,15,74,9E,EC,13,F4,7E,15,F7,67,C9,C7,B8,D8,2E,40,14,98,65,7C,17,E8,30,5A,47,AC,42,2E,34,78,06,C6,35,F1,6D,BA,C1,A1,D8,5E,7E,8A,C8,BA,1D,2D,4C,2B,D7,16,65,2F,52,DA,2F,8E,AF,F1,CE,86,DE,0B,1D,69,28,05,C7,6E,4F,9B,E2,47,5C,B6,5D,C7,02,98,9B,1B,4F,0B,2C,3C,12,25,4F,7C,95,47,89,A3,52,98,03,47,F8,7A,BC,4E,E0,F8,67,DD,BC,D8,77,15,26,CD,63,10,03,B5,E5,7D,70,96,C1,30,81,60,3A,B5,38,2B,F7,85,BE,B3,21,C7,D0,5E,84,38,BA,C8,ED,F0,50,D5,9E,8E,EF,6B,21,B3,72,F0,2F,41,39,33,4A,CA,87,6C,FD,B3,94,DA,F6,8B,76,1E,33,C4,DE,06,61,4B,81,C1,94,5C,8F,4F,B5,BF,07,4C,4D,61,9D,E1,5E,27,0D,33,E2,7F,5B,8F,EA,FB,8C,82,30,4A,60,BD,49,3F,96,82,E0,65,EA,9D,65,F0,47,0A,35,CF,97,9F,73,72,DC,D9,B3,53,82,98,4E,CE,4F,48,17,6D,04,BE,DB,F2,57,B3,22,74,17,2E,65,DE,4B,38,56,42,1A,5D,DF,32,D3,BF,AB,F9,72,99,84,FB,9D,76,FB,78,9D,9B,7A,6B,76,28,91,23,9D,AB,08,46,49,EE,3F,D4,6D,53,A6,60,76,9B,6E,38,BC,E8,CA,AC,A4,FD,12,2F,61,91,AB,62,EC,21,71,4D,55,52,D1,52,4A,FC,44,3B,83,3E,24,04,F8,4F,AA,72,BF,02,ED,C6,20,48,E1,71,47,86,01,7A,36,2E,53,3D,45,32,38,B7,FC,60,11,E8,AF,79,0C,2E,76,38,AA,AB,A9,5E,C2,94,E4,A8,2D,DC,98,AE,3A,E7,ED,8A,4E,AA,86,04,A1,31,5A,88,E5,46,0D,D1,60,8B,9F,1A,2D,13,4A,0E,88,43,B8,7E,38,91,AF,AB,B9,95,EC,17,AB,98,7B,CC,44,61,7D,6F,8B,5E,01,BC,03,DA,17,4F,60,44,A0,B0,19,EA,16,87,CE,F8,96,E9,DB,E5,C1,5D,88,39,F8,D9,22,40,86,C9,F9,AF,9F,F7,7A,46,91,86,92,01,46,97,70,8F,1E,67,92,2E,97,4D,D0,C3,4D,C9,B8,BB,42,3F,F2,9A,79,27,C0,0E,45,4B,E9,EF,94,D6,86,68,3A,E1,AF,B8,69,1C,6A,5D,76,F6,94,4E,64,0D,30,09,31,48,F2,09,C6,66,F8,DC,A9,97,4F,17,7D,CC,21,D4,81,00,3C,A4,58,E6,12,19,88,D8,E0,F3,9A,6A,FF,66,2B,EC,63,BB,10,FF,7D,DF,1F,42,47,E2,14,CC,F4,93,1B,7A,38,2A,46,15,E7,BF,DF,4C,A9,90,2E,3D,0D,2F,21,EA,43,6E,1D,35,DF,C9,A2,88,58,02,2D,16,56,66,D8,3C,8E,EA,F0,3A,7E,7D,0C,58,63,70,B4,63,3A,A7,65,ED,87,AE,1B,F8,F9,07,7D,C0,54,F0,88,67,1B,23,49,FB,71,0E,A1,F4,95,42,B0,1F,1B,A7,F2,FB,F2,E1,95,C8,FB,E4,A8,2E,F1,7C,5D,C7,CF,C7,CC,4B,C3,9E,08,5E,CD,48,18,BD,8F,B9,2B,67,30,1E,F6,A1,39,AE,6E,65,BE,6F,B7,03,A2,2B,70,91,DB,75,28,4F,33,55,C6,64,51,C0,B4,E4,98,3F,08,A5,94,7F,DA,C5,76,9F,36,B5,EE,62,C2,22,82,F1,DE,23,38,5B,3B,BF,5E,EC,A7,15,F2,54,12,48,87,86,BD,09,CB,6B,30,07,B3,C4,66,05,10,4B,C6,A1,B4,15,34,7D,FC,DA,A5,97,8E,18,B8,C7,5C,35,25,42,AD,F7,D8,43,BC,66,2D,B1,23,71,FA,7D,66,09,C7,8E,5D,52,1C,44,5F,C8,11,93,89,F5,0C,8D,1A,DE,87,96,63,9C,C3,52,B8,49,5A,E2,C5,4E,89,0E,E0,1B,6A,A1,78,EE,CA,2E,24,E5,33,BA,71,F5,B5,AD,D0,B2,EA,92,5C,59,61,42,07,47,22,02,61,AF,DD,B7,08,BC,9E,9D,03,56,F4,5F,4F,94,4F,B7,3D,25,DA,EA,FC,67,6E,9C,77,CA,11,F4,8E,29,77,BD,A8,AA,86,76,19,16,33,B7,BF,BB,1C,56,88,95,4D,A8,D8,45,41,13,7C,3A,97,CF,37,B7,50,FE,1F,4C,41,92,C2,5F,12,CF,DF,66,43,4E,E7,81,26,BF,48,A7,CE,EB,D1,3C,BA,C1,27,DF,D0,FC,9C,43,14,62,21,98,EE,BC,28,D7,BF,D4,9E,C8,DF,8A,31,71,06,DF,DB,37,BB,26,A9,90,30,BF,42,89,E3,05,E8,94,A5,3D,75,01,3E,A1,D2,B2,31,D9,D6,63,1A,03,F3,E1,8F,C1,7A,3A,F4,74,A4,CD,50,CF,EE,8B,2D,DF,8E,3A,D1,60,CA,17,06,B9,EA,24,20,19,1C,09,67,88,A7,08,C7,3E,A5,8F,52,46,93,27,3D,85,FF,93,17,F9,E5,58,E5,7B,D2,43,74,13,46,A1,D1,D3,A4,AA,0C,63,79,7D,20,7B,72,42,F7,95,CC,40,CE,E1,33,DB,2E,48,94,E1,6F,E1,D8,2A,36,96,24,90,D7,67,7B,98,EF,23,89,2E,47,E6,F8,EB,02,87,75,CA,21,1C,57,F7,3A,3D,F4,AD,07,D9,0A,30,E1,66,FB,74,8A,0A,68,82,79,33,6E,63,2A,DD,D6,E0,7B,58,B6,EA,BE,EA,76,CE,64,40,8D,18,E5,36,D4,35,CF,F4,A6,6E,AF,F9,0E,6D,88,0E,AE,D9,4C,2B,4D,64,F0,67,4B,6A,11,0F,57,12,A3,9C,C9,E3,52,0F,01,02,D2,1C,0E,FB,AC,24,D2,5E,82,74,96,32,CF,80,14,50,DD,A9,13,BA,91,F6,69,96,D3,DF,0C,2B,C5,55,F6,3F,92,C9,24,E1,FC,66,BF,CA,68,E6,63,5C,56,63,5A,AB,5B,ED,45,91,3C,6D,16,B5,08,F2,D3,B6,72,2B,26,D7,64,2D,5B,FA,22,F9,F4,70,23,88,6C,2B,CC,8B,D4,A6,77,04,F7,8D,28,17,76,C7,1B,55,46,2E,91,1C,23,E0,89,35,9C,21,BE,01,82,97,2B,A6,94,87,F1,D3,28,74,60,40,81,3E,0F,20,45,27,91,3A,FD,BD,5B,0C,43,A8,62,C4,05,A5,11,92,F4,0B,43,50,41,5A,FC,F6,6B,1C,B2,25,23,E9,D1,82,2C,B3,9C,45,9B,EB,B5,1E,97,09,AA,F4,33,39,0F,71,1C,B7,A5,CB,C5,EB,CA,11,A9,C9,7D,F1,83,EC,64,64,09,00,C0,D4,BF,CF,02,B3,C8,D3,03,5C,27,FB,1C,C1,4D,C9,AF,81,D4,24,6E,90,D3,41,17,CF,AC,72,EA,38,DC,A6,0F,9C,33,49,E3,63,14,23,35,C0,1D,B0,8E,C7,35,47,64,D5,C6,7A,3D,61,44,58,36,55,30,76,43,F8,0B,6A,E4,B0,17,00,96,CD,84,13,3F,8E,A1,75,C8,63,A3,C3,88,E6,B7,64,63,92,4B,6C,31,12,67,A3,62,26,AB,A2,02,51,75,DC,3C,23,E4,51,4A,7C,87,28,5F,C5,EA,15,F2,54,A3,91,40,0C,61,A0,81,1E,F6,6E,EF,99,67,96,BF,26,07,FB,89,84,20,40,88,2F,14,77,B7,6F,ED,27,E2,E2,CE,FB,AA,E7,F5,3E,F1,50,52,94,E3,B9,0D,9B,BD,26,39,7D,58,14,99,79,7A,E0,C7,1F,7F,EB,13,83,67,B6,02,39,59,6F,56,3A,B3,57,9D,44,8C,0C,F3,DB,67,E4,EF,9C,C0,CC,73,A8,D8,66,1B,95,70,F2,91,43,4C,44,D7,96,44,D7,64,D1,5F,B0,1B,10,2F,70,BC,1E,D8,80,CF,4F,11,B5,AF,BE,B4,5E,24,78,8F,6C,6D,DE,A5,19,A3,96,20,0B,22,70,BD,D0,C1,87,F8,6F,6A,7C,C3,74,F7,53,C5,0A,69,14,CA,0D,68,B0,AB,3A,4A,EF,E4,86,BE,68,12,E4,08,0B,5A,5F,A9,C1,31,E5,7A,D3,E8,91,58,84,7C,C8,1D,BA,B9,0E,85,A1,C8,57,36,83,89,37,09,8B,8B,99,57,9C,A1,B5,DE,F5,94,79,4B,8B,E4,2B,86,81,66,73,D6,B0,95,73,D3,4D,1E,14,98,21,EB,E0,60,2A,BE,99,01,C1,61,A8,35,25,43,99,42,14,B5,60,EE,0A,C9,C4,C1,81,E0,6B,34,B7,46,01,11,CE,9C,85,88,E7,59,42,6A,35,D7,40,CB,91,12,6F,8D,E2,7A,0B,9E,C8,98,85,5A,94,91,F5,E3,EB,18,89,B7,B3,47,05,66,43,54,D4,C2,56,22,F8,0C,43,6F,A1,86,98,7B,E6,94,2D,1B,E7,F6,DE,44,DD,C5,1D,B5,D1,3B,29,47,01,FE,3D,66,3A,9A,9A,E3,40,66,81,C4,BA,94,9F,44,E6,4F,DC,1A,C9,64,9B,6D,73,C5,1E,CA,BC,35,28,74,2A,7C,01,A7,F8,57,1A,BE,0B,D1,10,0D,EA,6E,03,8C,5E,9F,11,E2,F2,2F,14,1B,69,2D,D3,50,A0,FC,4B,AA,A8,EB,11,D4,5E,85,29,59,92,65,CB,D3,C9,AB,3D,19,93,38,EE,33,57,90,AA,3E,C1,21,62,28,6B,38,67,4D,93,9D,D7,8D,31,51,CD,66,EB,13,4D,FA,FD,8A,9F,18,23,EB,CE,09,CF,DC,FC,FB,A7,69,95,5B,25,F9,61,B9,20,46,52,AE,53,69,3C,74,65,DD,7F,6A,C3,66,F4,3F,43,BB,1B,F2,B1,21,E2,6D,A7,9C,91,02,17,E3,66,91,2C,7D,68,24,A6,44,E5,0F,DF,6A,53,DD,2A,93,1B,EC,9C,8E,AD,9A,9E,49,11,33,F8,E8,1E,0B,18,A7,BF,C2,08,33,FA,07,F5,DE,1D,4B,02,22,A5,2F,30,1B,50,B3,A2,B7,18,DB,8E,F4,04,AC,57,B4,87,41,10,4D,1B,22,61,12,0C,2B,89,F5,48,8F,E1,B9,D8,3A,D5,33,99,B6,C2,58,26,5E,B1,3F,67,FF,78,8D,C1,2C,AA,5C,11,8D,F8,6E,74,09,4C,CF,49,C4,99,6E,88,70,8D,1F,70,FC,55,FD,01,33,12,AF,DA,55,EC,ED,E0,6A,D5,1D,7E,90,3C,2F,4E,B6,96,BF,C7,68,9B,5D,53,65,01,7D,3E,12,29,AE,99,7D,2D,0B,9E,46,E7,3A,94,49,B4,3E,49,0A,B7,BE,28,D8,72,A8,C6,6C,AD,3A,02,A6,82,20,CD,69,21,C4,80,75,10,3E,E8,D0,54,7F,63,5D,A2,51,F1,30,70,9B,DE,D1,D5,C2,F2,BD,4C,52,67,3A,38,D0,2F,70,68,26,5D,83,9E,BA,02,C3,7C,CB,D6,AF,D2,01,5B,B6,E4,FD,CD,6C,78,17,8B,75,D3,57,33,27,0B,28,2C,3F,F0,BE,3C,17,C2,25,B0,4E,F6,A4,F7,BC,AC,5E,26,F2,D6,E5,A3,D4,51,61,5D,85,D6,BF,59,E3,D6,60,4B,FD,16,FB,F2,DE,24,9A,6D,86,39,EA,C9,B2,AA,60,58,BA,92,56,CE,C5,25,3C,57,F1,18,FB,B4,18,11,B3,7D,A2,B0,40,D9,92,B4,A7,6E,F2,C2,60,89,77,9B,F3,0D,6F,04,E4,FF,69,D0,75,36,CA,24,8E,9D,B8,01,70,44,D4,CE,B4,C8,22,30,52,90,1E,69,B1,23,87,D8,E6,DE,80,63,B0,5D,28,6B,73,1B,F6,0F,0F,84,7A,DB,A2,D5,8E,66,A4,85,3C,25,73,33,A7,2C,24,FF,E6,5B,D2,CA,EF,EB,FF,40,6B,82,6D,04,7C,F4,87,0C,5C,F9,FC,43,82,8B,94,38,C5,03,71,F6,26,A0,F7,2C,03,A2,7C,9A,63,D3,16,72,51,CB,E4,35,0A,F1,43,8F,88,D3,49,FC,21,4C,78,B8,2B,AA,84,F5,BD,68,06,61,FC,95,EA,83,53,AF,2D,02,C8,FD,7E,FA,CB,53,B0,0B,3E,77,A7,72,14,47,B0,F5,E0,F9,BF,21,C8,B4,E2,DE,1E,E0,B9,7E,B3,66,DB,B7,42,82,A5,0B,7E,91,89,AC,63,C0,BD,55,74,DC,24,B1,04,A1,7F,60,F3,88,E6,83,D5,69,08,BD,AF,94,64,94,2B,1D,FD,AA,60,CE,B4,AD,39,3F,57,C2,D2,2C,AC,68,9F,7C,03,73,DE,01,A9,0C,BB,1C,FE,C2,50,7C,6E,C5,4F,92,80,9F,A5,FF,66,A0,80,7A,99,2F,45,F3,3D,1D,98,22,8F,CF,7B,B7,B3,39,F6,18,63,6A,FF,EC,B5,32,B9,20,9B,93,DF,74,20,4F,7B,AA,02,8A,60,ED,EB,28,6F,30,48,E2,1B,43,02,E6,62,3D,E4,07,5B,A1,4B,4E,A0,BF,9F,E6,47,F9,AE,C3,74,7D,EC,BB,A7,B6,BD,01,FA,BA,89,F1,1D,6A,6D,26,E0,52,3F,33,73,BF,C5,CD,DA,EE,2B,D4,71,13,A5,E6,48,9A,77,94,24,13,42,85,71,77,7F,5F,54,2E,51,5B,E9,05,A4,AA,C1,F9,F0,78,22,8E,88,3F,BC,51,9F,FC,44,AB,59,18,80,57,D3,D7,BE,57,C7,99,0C,B1,31,53,EE,DC,F7,85,83,B1,8F,0B,A9,3D,65,A0,6F,62,9F,72,3B,21,C6,32,AB,66,74,7A,79,30,47,DD,21,48,F9,13,B7,EF,FD,28,7B,B4,58,91,63,55,BB,CB,47,10,09,A9,A8,C6,A1,17,85,34,76,39,68,A7,8E,5F,B0,88,67,15,7C,20,C9,0C,32,7F,DA,74,34,14,A8,97,47,77,4A,02,74,4C,8D,D9,02,0E,2D,0B,09,2F,EB,9E,BE,69,4A,02,1B,FF,C9,74,77,AE,B4,FB,70,63,65,90,D8,55,27,B8,AF,7F,5C,A6,D9,50,40,28,C6,7D,D7,CD,F2,C3,24,29,1C,BF,2D,10,44,76,4F,DB,5A,8C,85,81,87,3B,DA,89,A8,54,84,6E,5C,FA,9E,E1,48,86,A9,57,FF,EC,82,FF,F4,0C,80,78,9A,FF,6F,35,80,30,BB,34,AB,44,31,06,16,77,48,31,2B,2A,26,BD,81,78,95,15,8E,8C,B4,77,E5,62,AE,A4,49,98,99,97,F6,BC,AD,E2,D1,19,A8,F8,3C,C4,1F,93,85,D2,03,1E,E9,3F,36,C5,C3,6D,09,C9,74,BD,F7,D9,42,12,75,B4,6B,E6,89,09,DF,09,32,8B,0F,98,EC,A1,CA,A8,6F,E8,4F,42,E4,93,DF,6E,41,A2,5A,DE,12,40,62,79,6B,06,DB,22,4E,55,C9,1A,AA,85,A7,B3,9D,28,DD,90,D0,09,7D,4A,9D,A3,49,13,DC,D7,58,FF,1A,64,E3,3D,CC,71,37,7F,33,79,8F,69,3A,22,49,31,CE,B7,8F,BF,F9,1F,4D,A0,AF,60,5F,56,E9,66,7F,AF,98,64,8B,C0,3F,D7,9A,E5,97,16,96,DD,38,0A,2B,26,0A,22,69,69,D5,9D,B5,78,B5,86,15,DF,93,20,3E,BA,68,2F,4F,DD,A7,7C,9E,50,7D,72,EF,5E,7E,10,C1,29,0B,B8,20,D2,E4,8A,08,93,D8,B4,B1,0C,00,2A,97,30,DE,C0,82,40,E7,F5,C9,7B,E0,BF,E5,52,30,D3,95,79,88,B8,4C,61,51,D4,67,43,E4,42,C9,40,52,4C,37,84,E7,E5,C7,B5,5A,2A,EE,B7,4D,CB,FA,DC,F4,FB,A9,B4,5B,17,B3,6D,75,A8,06,0E,5E,93,3E,88,CF,BA,F2,07,81,E1,FB,83,09,13,E6,F1,1B,5A,A3,DA,1F,35,84,93,A9,59,A0,0C,B5,73,CA,30,14,76,13,F1,FD,7F,5E,B7,85,16,E5,4E,4E,58,B5,BE,09,8C,9A,1F,EA,98,5A,74,2B,97,0E,8B,41,E2,57,B3,E6,F1,10,0F,D9,6F,9D,F1,A1,D9,C7,78,FD,43,10,65,B0,9B,EC,30,8C,C5,4F,C2,4C,D5,E4,5F,96,A7,90,5E,24,21,B9,1A,E0,C2,44,6F,92,C7,B4,AB,20,79,BF,57,DB,A3,9B,65,55,70,37,7B,64,AD,8F,7A,43,0E,1D,B0,C0,1E,EB,0D,0C,77,EE,56,E4,FF,2B,CC,E7,2B,41,34,37,9E,0A,3C,2E,69,53,74,B2,2A,21,1D,27,A6,7F,C3,2E,72,75,A7,4C,CD,DE,01,42,45,FC,98,51,5E,D6,3C,B5,A0,B9,0B,7E,A1,1F,C8,58,9E,6B,BC,93,C7,09,94,B7,8B,33,2F,6D,8D,E1,50,94,3D,75,7B,1F,1D,CE,1B,E0,CD,5A,45,13,FC,68,47,8B,28,DE,F9,42,E0,32,0B,43,F8,51,54,3D,D0,9C,DD,83,89,95,EC,22,21,E2,35,41,77,96,E3,DF,CD,66,E3,66,7A,34,D2,89,09,B0,43,02,C9,BA,F4,AC,8C,1E,43,29,9E,CB,97,3F,5C,1C,A2,38,AD,82,F5,01,6F,49,05,98,6E,67,9D,85,77,BF,11,60,CD,99,96,26,40,B6,9C,9C,CA,35,BA,6E,EA,C0,81,4F,C7,93,F6,A1,5C,E0,56,E3,68,00,6B,48,53,AA,9D,49,7C,DF,38,15,75,9A,99,65,62,0D,8E,03,0E,B8,C6,18,05,0A,FB,87,17,6D,CD,76,A9,FC,B4,7F,15,C6,8F,97,97,F4,49,35,4F,24,5D,F4,D4,C1,84,B2,C1,9A,F2,6A,8E,82,B9,08,14,30,69,F6,66,F8,A0,92,E4,CF,94,5E,0B,6D,1A,83,B6,BD,B9,4D,7D,22,D7,9E,D5,6F,26,B9,F4,63,2B,CE,AC,CE,93,8A,ED,51,93,B0,14,9C,BD,08,B2,2E,30,0F,7A,C2,06,40,F8,75,47,D4,DD,AB,8B,4E,D8,40,EB,DD,D8,86,D2,3A,5E,26,11,5F,59,95,C0,13,53,1A,2A,04,D2,E6,85,C1,EA,DC,07,61,66,36,B9,17,FF,C8,3F,E8,42,B4,C2,71,0A,D0,82,88,B7,0A,43,8A,FF,44,B1,04,79,7E,EE,1D,63,D6,64,71,FA,B2,04,7E,10,9D,7E,68,96,62,07,45,78,E9,49,B5,97,27,B9,C9,FD,5C,F2,72,78,5E,96,BB,F6,D2,1B,3D,CC,1A,B0,DA,40,09,16,73,56,96,EE,1A,57,1E,CC,52,49,BC,71,44,D3,18,C2,3B,01,F1,B0,EE,04,2E,7A,5C,35,E3,08,D4,57,35,55,AA,75,F0,5C,0A,28,C8,C2,0B,11,7E,35,85,FE,EB,9F,EC,38,9E,11,1A,68,AF,9C,FB,F6,26,19,21,9D,63,9B,C3,CC,52,0F,AA,CA,50,FF,53,2A,38,BF,A1,A0,AB,E1,78,75,28,99,E7,39,28,0A,C3,B5,19,22,10,E1,25,20,3E,5F,AD,42,9D,E2,10,A8,4D,BB,8A,97,E0,2F,6D,64,D2,E2,7D,52,E3,42,CB,99,7B,D2,3E,CA,BA,FA,D0,55,C6,7C,70,E6,97,67,18,E2,25,0B,BA,85,13,B6,B4,28,89,12,91,30,C8,79,77,0D,00,B5,68,EB,D0,70,B8,E1,6A,E2,13,B0,02,F3,84,69,36,39,F2,DE,DE,B2,9E,10,0E,4B,FA,03,A9,42,FC,2F,CC,70,F7,44,93,05,B7,EF,3A,EB,BA,52,CB,1C,A0,8A,50,B3,60,AF,B0,3E,31,1D,73,61,30,A7,4E,A8,CE,D6,A4,6D,AC,29,C6,DE,61,DB,0C,34,20,A1,76,E6,5C,3B,49,52,6A,52,97,36,41,BD,D1,CA,85,A3,67,8C,4F,5D,15,17,6D,E2,35,01,6E,F8,53,D3,5F,2C,68,C4,2C,1D,F4,8B,96,70,43,D3,94,A8,34,47,E4,86,95,E4,3A,02,7D,2D,D3,A3,56,AA,CD,87,FD,11,41,5B,67,A4,7D,3F,77,F6,61,31,EF,CA,2B,A8,30,D7,17,D0,26,11,BF,94,26,1A,DD,66,C3,C9,10,2D,D7,F2,11,F2,E0,7E,39,84,E0,BA,E2,6A,D4,0F,F7,02,81,B4,53,B8,79,F0,95,AD,E5,DE,88,85,A6,8A,24,67,E8,0F,DD,95,AF,35,66,F7,5D,42,FD,B1,3E,CD,2A,95,5C,8B,A0,C1,4D,30,43,78,53,67,3B,CA,BA,8D,DE,6B,73,88,D7,55,47,71,2D,0E,F0,70,C7,A5,C8,6E,60,ED,EF,39,91,3D,8D,16,69,7C,7C,5D,B2,96,A9,39,84,E5,DD,AB,5D,F6,7C,DC,C5,67,7B,36,44,98,7F,AD,80,80,37,AE,DD,19,D5,C3,0B,91,F8,83,F0,D6,8D,F1,92,2D,07,72,31,42,B6,FD,E3,EC,02,00,12,D5,ED,23,7F,EF,95,AE,95,E3,80,B8,82,63,B8,F7,DB,B5,CE,94,14,B2,8A,19,21,D7,FA,8B,31,2C,60,20,79,AB,37,22,F4,30,9C,78,77,64,3B,76,56,D1,E3,AF,89,7F,C4,FC,4C,70,E4,E8,18,9C,46,91,C7,BA,37,73,EC,8B,6F,32,EB,64,1D,02,30,E9,2E,B3,BE,2E,E8,1B,9E,18,5A,6A,11,06,74,1B,1A,41,77,AC,86,47,54,A7,7E,9E,F9,C4,78,24,49,DD,B1,88,13,65,7D,6A,8D,2E,79,37,61,8C,0D,32,E6,6B,26,DB,BB,24,28,49,82,86,EC,A2,AD,2E,AD,03,95,D2,1E,84,8F,37,16,EE,19,C4,1D,98,C9,73,93,93,19,5E,D6,A3,F6,9C,96,1B,87,F6,5F,F6,CE,F8,77,25,4B,DB,09,74,4B,60,AD,AE,0A,BB,10,CA,A1,4F,8F,EF,D2,B1,76,95,64,21,CC,9D,03,1B,3A,F7,23,DF,C4,F2,2E,94,8B,2C,12,A8,B4,92,01,FB,BC,7F,C1,A9,FC,69,6A,5F,DD,87,0C,33,30,60,44,A8,AD,9F,46,87,B5,9D,3E,F1,7C,A6,5C,3E,C0,7F,AB,7D,CA,FC,56,03,19,AF,85,29,E0,90,D6,C9,ED,57,B2,0C,C6,9D,B4,A7,50,C4,28,71,82,82,1C,A5,9F,0D,54,B5,5D,44,D9,74,2D,87,57,BF,5A,AB,55,1A,74,5C,85,B7,DB,5D,A1,D6,26,90,3C,6A,F9,B9,6B,6C,84,49,06,04,B3,89,66,62,6C,7E,34,3C,0A,21,1C,D1,D7,74,43,15,3C,35,39,07,D5,65,F0,B6,E3,C5,63,60,CB,E3,BF,F4,D5,C1,48,9F,01,90,FB,F0,E6,9C,EA,C5,8C,1A,5E,A9,2E,7F,66,D0,92,7B,8D,75,09,B2,08,E7,EB,CE,EE,1F,57,9E,42,70,91,0D,05,A8,CB,65,54,47,86,DC,1F,2A,1E,2A,F3,B7,FB,42,F6,76,FD,98,1D,D2,CB,01,61,3F,43,F1,0C,68,CC,7E,D0,AE,03,C5,87,0F,02,0E,D4,46,82,35,24,57,17,28,5A,C9,44,D2,F2,47,A3,62,F7,5A,7F,91,AB,03,DF,FA,08,3F,C0,E3,63,CA,2D,40,4A,E5,D3,3C,BA,76,5D,83,0D,08,32,BF,63,59,AB,BC,B8,2B,06,F6,16,96,6A,77,A2,47,65,3C,E8,9D,E2,52,C8,AC,14,2A,AB,BC,1E,1C,F4,2C,BC,39,D4,64,E7,A6,C1,45,0C,76,6B,3C,F9,03,DA,14,2A,4F,FD,FE,3A,C0,A6,6C,42,11,BE,3E,46,0F,9A,C3,EC,2F,7F,17,74,C5,CD,3F,AB,5F,D8,D2,E5,83,7C,C0,F3,02,F8,59,85,33,0A,31,38,5F,72,F4,9A,04,07,B5,7D,F4,55,AF,7F,F0,EE,25,4F,42,4D,CC,A6,C5,93,D4,2A,C6,56,86,84,49,CB,89,E4,CB,33,12,5F,76,9D,CB,29,5F,47,49,23,45,3E,22,C8,F9,9B,85,9E,AE,EA,1E,46,67,AD,DF,CF,59,04,AA,77,12,07,EF,B7,CE,B4,52,39,12,A2,24,59,5B,E9,D9,AA,21,F7,A2,6A,D3,24,46,E1,19,B3,E4,8D,E4,AA,93,2C,6E,68,FC,66,A9,1F,99,70,6F,CE,AF,2E,42,5F,6C,BD,0C,44,09,55,B7,44,01,25,2E,E0,85,83,23,6C,AA,5D,CE,94,A2,25,E4,4C,F4,E3,32,86,72,2E,CB,47,10,4E,E3,27,20,46,13,0E,1A,5E,4D,B1,05,1D,F0,5F,F4,C7,14,9C,48,86,4F,70,86,15,8C,80,5B,13,5C,18,04,B3,60,C1,82,3D,D3,75,2F,06,45,3C,21,13,41,6A,AE,1D,ED,40,FB,B5,0B,E8,0A,25,86,34,FB,1F,36,79,A3,D4,D7,08,98,CB,42,28,AF,CA,A9,55,78,47,92,03,14,E3,70,E6,C3,10,6D,9E,96,BB,C3,BA,30,8D,8B,2C,70,FF,52,B2,57,6F,87,A8,34,AF,B0,18,71,06,57,FA,AA,8B,F0,48,BB,CB,84,FC,1B,16,1C,7A,53,B6,DB,59,A0,93,6F,6B,33,5D,19,C5,FE,F6,42,A7,79,21,F2,DD,E0,75,47,35,44,B7,29,72,D4,9E,EE,A7,BF,70,C2,59,93,66,E0,94,35,95,04,00,0B,C6,3D,53,F0,E5,EC,16,1E,38,20,3D,83,4B,84,DC,C7,84,2D,3D,21,98,13,E2,13,70,CD,56,21,A1,02,75,D0,9D,6C,18,B8,73,57,CB,CF,C3,C4,C2,0A,47,58,42,12,2B,F5,2A,87,B6,4C,62,D2,E0,9A,5D,CD,1A,58,AA,1D,B4,E6,DE,20,93,73,3E,C6,7C,46,2B,89,63,C3,F0,63,8B,36,23,C9,92,F7,8F,A4,8D,AD,AA,58,46,88,6F,F3,B6,78,97,A5,59,EE,79,CD,D9,32,6B,2F,AD,7B,A0,D9,B6,9D,82,B4,61,EF,BC,4D,27,FC,2A,50,E8,DC,06,7F,49,62,DD,FE,B2,C9,BC,22,57,90,3A,F2,00,BF,59,5C,F5,6A,FE,56,BE,F8,D0,21,BA,63,33,F4,52,2E,10,80,81,19,68,3E,AF,BE,C2,18,7E,71,9C,C8,50,3F,C0,DB,CC,69,D2,57,FF,FB,3A,B3,E9,21,2A,F8,F2,0E,32,7B,59,60,F3,09,06,D0,9C,01,CE,C9,35,39,14,25,4A,30,1E,A6,B9,EA,7A,EE,12,6F,2E,4C,82,38,7C,98,35,64,64,67,67,01,B6,EA,9A,AE,BB,C9,B4,F4,2A,92,A3,BA,A5,62,89,6E,1B,23,C7,24,8C,38,FB,DF,3C,01,CB,41,C5,93,AA,37,49,C2,EB,6D,56,3D,64,D3,49,28,BC,FC,53,30,57,FA,32,42,71,0D,AA,D4,1A,D0,46,40,78,65,49,95,B5,85,AD,6B,B4,33,2B,8D,3B,6B,C0,20,EE,BC,96,C2,C1,41,E2,7B,4F,66,33,B5,B9,B4,C9,57,50,62,D9,DF,85,55,97,D1,0A,D6,3F,7F,24,28,C5,C3,1E,05,65,8D,FD,23,F7,90,E6,B2,DB,65,D8,4D,EC,81,45,A7,07,54,BB,39,77,B1,CF,20,F2,C3,40,F6,71,AB,57,8E,1C,FC,A7,03,FC,72,B9,59,85,32,E6,A6,1A,EA,2B,C6,BA,A4,C2,99,62,97,DA,7C,70,A8,D3,13,84,42,CA,7D,5C,FD,8B,EC,EE,AD,21,0E,AB,1E,3E,E7,32,F6,B3,09,C3,2F,D6,53,38,5A,06,DB,AC,84,0F,39,55,CE,FA,C1,92,A0,BD,E0,76,43,96,EB,47,14,AF,30,28,67,9E,2E,AB,14,2C,58,F2,14,38,1A,FD,D6,4C,19,76,7C,DE,3C,B2,68,6D,18,03,39,AB,14,CA,90,90,0A,21,2E,AF,B7,32,41,DE,66,85,F6,32,19,13,25,90,AB,4D,49,C2,AC,28,C2,C3,76,67,D9,09,19,02,1F,ED,CE,56,50,56,7E,52,C3,3C,E0,D0,1A,0B,B8,20,07,0A,B5,1B,EF,BF,95,61,80,F6,02,1C,5C,70,33,0A,3F,4F,94,66,15,2F,5C,47,6A,D5,18,C0,DB,05,E0,7A,10,E5,64,DC,A2,15,4E,28,6F,AA,D2,29,9E,88,7E,C5,B8,C3,BE,73,CD,E0,BD,8B,60,6E,DB,10,75,61,A6,C9,D4,5B,A0,58,8D,4A,A2,CB,C1,C8,44,4C,F6,DB,EF,B5,89,1C,71,8E,EF,33,CB,70,83,80,1A,DE,07,11,C1,20,80,D4,BF,8C,C2,AA,2B,BF,BA,C5,69,09,06,99,7E,5C,32,BB,7E,74,A5,46,90,CB,99,3C,0A,99,BE,F4,DD,A3,97,64,36,17,38,10,96,A2,14,9D,34,52,90,C7,6A,43,66,21,F1,0A,1A,A0,8A,E0,E8,9F,0B,37,39,9C,5D,BF,16,6F,AF,5A,65,AC,A9,C0,66,46,33,E3,BB,71,24,73,EF,9F,4C,9A,B7,3E,E6,87,FC,4C,54,63,9E,C3,00,F7,E5,F1,36,F4,FA,29,E1,26,03,5E,DF,76,2A,17,14,3C,53,3A,57,15,BA,C5,DE,D2,96,9E,31,BD,33,30,18,B7,32,88,D3,C0,74,56,49,54,67,69,4A,9A,37,2C,DB,28,F2,50,3F,FA,9D,74,98,08,5A,2C,90,92,07,70,61,52,EC,15,C3,A2,58,C8,CE,A9,C5,EA,38,0A,6F,73,32,47,9F,B3,C5,11,D7,2A,3F,89,69,E7,47,FE,15,7F,02,BE,AF,15,13,E2,0D,4B,2E,6E,D0,55,73,43,CE,D2,41,21,E5,C4,25,02,C0,1B,0C,7E,54,56,12,91,72,6C,0C,8B,8D,1D,AD,C0,75,2D,31,A5,A9,7F,C7,BA,26,AE,2D,05,B9,60,F7,9B,5C,CF,A5,F2,2B,B5,1E,BF,14,AE,4B,6E,98,47,09,07,AB,D4,71,89,13,0A,49,23,95,B8,E2,C0,9F,D5,9A,97,FA,81,B4,79,B3,CD,F8,8D,8E,58,28,1F,70,56,F2,13,A2,9B,66,DA,B1,56,3A,59,97,9A,13,FF,B5,00,47,6D,FC,78,03,DC,6A,C2,94,F2,0F,B1,88,C9,23,F8,C9,4A,3D,6D,12,CA,3E,BB,11,88,C9,4B,B1,6E,E3,49,A4,E0,4D,CF,79,DC,78,21,B2,78,17,BD,41,F9,2F,C0,F5,E2,19,B6,DA,05,5D,72,22,9D,DF,CE,48,F6,BB,29,EC,95,18,25,06,51,D2,8F,C8,6C,F1,0D,D1,B6,86,58,A1,AB,08,EB,7D,57,99,1E,3B,A0,E1,41,0C,53,7D,DD,0A,9B,F2,02,EC,FE,5E,79,E1,38,72,8F,ED,62,C6,36,63,DF,80,97,3E,17,6F,2B,F2,97,3C,38,FF,A1,5A,95,7D,A4,3B,24,8D,74,C9,B9,83,8F,46,41,69,4A,57,EF,11,DB,39,C7,47,AB,B2,1C,FC,51,0E,F1,AF,22,DA,BE,B1,08,EB,12,15,98,4D,68,FB,D8,6D,4B,C6,55,21,2C,49,70,4D,B9,E2,B6,AC,F8,79,79,F0,1F,2A,7A,5D,E3,FE,E0,B0,C4,19,7D,16,AB,7C,DE,F9,7B,0E,55,41,2C,0E,7D,37,94,E7,A0,5A,02,E7,8A,66,A8,AE,15,E1,4C,A5,59,FD,7A,AB,FE,E8,C2,72,0B,69,5D,CE,8F,83,0B,52,4B,7D,B0,4B,45,8C,0B,57,7A,22,FF,8B,22,D2,11,1A,7F,6D,05,87,73,94,4E,CF,9F,CF,A0,62,2B,E1,27,D1,89,36,AF,FE,83,5D,5F,60,5C,86,39,C9,49,64,CA,DB,64,56,05,7E,A1,E3,3E,77,2E,40,02,4C,86,A9,AC,1E,B0,8F,D1,21,27,A2,46,8C,16,16,27,B0,FA,B0,66,0E,09,DF,D6,6E,42,CC,EA,5E,EB,EA,7B,00,E2,3B,F1,84,C5,07,B9,EE,AD,6A,D8,8E,1E,52,80,00,87,CB,06,B1,49,01,82,F1,72,D0,64,34,1D,A9,50,18,9D,9E,A3,4D,4F,54,C7,9B,4F,75,BE,EA,96,32,1E,AF,F2,05,FC,16,50,A3,3D,72,D0,71,17,7F,51,E5,FA,10,6A,5D,3F,2E,0C,A6,E2,49,A8,74,67,F3,0C,6C,6D,ED,A3,B8,CB,2F,FD,A1,3E,4B,81,30,78,CD,87,43,B9,BD,50,B3,79,52,D9,9F,6A,D6,AA,95,C1,4B,98,E7,66,2C,29,FE,78,0F,1B,54,B0,66,3C,30,67,63,1C,8E,C4,DC,33,EE,A4,AF,D9,FE,8B,55,F1,A2,B0,91,34,E7,FA,4C,D3,5C,82,62,EB,FD,88,F2,5A,F0,7D,2B,68,AA,7D,03,5F,64,9B,E6,36,19,91,26,B0,51,9B,9F,A7,E3,79,70,0C,81,07,8D,81,58,D0,73,C8,0A,0F,24,BA,30,E1,62,AF,63,CD,52,03,AC,9B,39,82,B3,45,AC,76,13,68,BF,71,52,BB,FE,09,0B,C8,34,4B,DB,EF,32,B9,BB,5F,FE,AD,CE,EC,A8,BF,3C,16,E9,5F,B9,D0,1E,E1,7A,8C,97,54,85,32,AF,BA,61,DE,92,FA,F3,EB,21,D9,5B,EA,79,38,87,BA,A7,2F,13,41,09,C0,14,73,B1,74,8D,87,01,1F,AF,D8,D4,6B,C9,5F,E2,D5,4B,A3,8F,68,0B,4A,C0,FE,83,C6,42,A2,D3,24,86,48,97,B9,A3,90,68,BB,AF,D8,AA,34,C8,06,5D,6D,07,8A,4C,32,0E,86,92,57,B8,EE,15,8C,CD,9F,34,88,D6,70,4B,AE,23,20,E9,C9,38,48,25,2F,2C,65,87,9A,57,1C,C2,63,48,85,BC,8B,AD,6A,7A,D0,10,82,A2,50,39,AF,5F,8D,2C,B7,2A,03,B2,13,ED,7F,49,B7,38,49,02,05,41,3D,2F,3A,4C,E1,09,0A,0D,22,61,9A,55,1E,B3,92,B3,1E,FB,8B,44,B9,CE,78,63,1A,4A,85,E6,CB,C4,5B,17,4E,C0,7A,9B,3F,FE,92,81,E7,C7,69,9A,70,8D,96,5C,A6,D6,66,0A,C4,C8,5A,76,99,8A,B7,D2,60,E9,8B,63,F3,D7,0C,B8,94,CD,94,40,F3,8E,6B,43,EF,D0,43,00,8D,30,53,7E,D5,1C,2F,20,4D,70,15,B4,9C,CA,2A,C5,E0,78,15,14,5E,FD,51,D1,EE,35,14,90,30,3C,0B,FE,A0,E8,7C,60,9C,4A,95,85,61,C3,3B,BF,E0,A7,DE,D4,EB,53,5F,A6,9C,27,E7,3D,5C,15,A4,BD,24,21,56,C1,9A,29,F6,DB,D4,5D,89,65,8A,22,B1,00,63,88,14,97,90,77,57,B5,38,7B,8D,5F,AD,2E,62,C7,76,5F,C6,CD,07,75,F7,4B,69,2A,54,20,30,34,B1,37,CB,4E,7C,8B,8F,0C,E5,7D,AB,F0,00,B2,09,E8,C2,F8,16,CB,4F,F9,84,6E,1D,55,3C,A2,4B,E1,AA,08,A8,DC,26,E5,B4,E4,62,3A,92,40,09,AC,95,1F,29,6F,84,90,06,5F,87,75,F8,5B,78,96,68,84,25,01,7F,1C,1D,DF,9E,65,8A,4F,DE,04,59,30,FA,C0,FD,9C,9B,E0,F5,5C,6D,92,02,46,CD,55,70,68,B3,25,4E,42,BF,BB,DD,AB,71,82,FF,F7,AC,FC,DC,1D,78,A2,EF,9E,59,63,30,39,A8,30,C5,0D,86,42,4F,BE,39,30,A9,2E,9D,6A,2C,D7,C0,81,D2,8E,F1,23,94,58,45,1B,51,A7,87,80,BE,EC,23,0C,49,AD,10,21,CF,DF,3C,92,4C,8F,A2,D8,21,E9,96,82,F5,B9,6C,E4,9B,52,52,E0,05,3B,0B,FC,E6,F7,95,3E,25,E7,7C,C4,9B,F4,A8,CD,C3,96,1D,07,E5,7F,19,DA,2D,B2,58,0A,A6,54,A7,B6,05,CD,7B,38,1D,2D,34,62,DF,B2,EE,A5,19,16,11,91,DF,F8,ED,59,B7,48,34,6A,66,FB,11,F9,3E,34,E0,2D,D2,0A,D6,42,D6,5F,6E,C8,35,FB,B2,E9,D0,29,96,D3,4C,39,53,3C,E6,DA,AC,E9,CC,BC,C8,4B,B7,F4,CB,43,C6,6C,7D,B7,6A,17,36,16,86,36,DE,06,22,97,6F,A0,70,26,76,69,D7,B5,60,DB,85,F0,FD,E7,62,81,0F,F5,F1,29,48,4C,67,2E,96,00,71,F3,49,3A,0A,28,90,56,A2,6C,93,DD,93,B2,AC,BF,C5,64,26,05,3B,9D,7C,80,56,62,4A,06,D0,AC,50,AF,B6,07,70,C0,97,6E,AB,CF,BF,88,0E,06,7B,B3,8A,E6,FF,0A,AE,32,37,1C,0D,40,06,DE,B4,51,83,D3,87,88,C2,DC,D3,82,57,1E,C4,AF,E6,54,C0,5C,CE,9D,AD,EB,67,71,50,94,47,18,F4,E1,C3,64,77,12,82,F8,CD,C8,CF,F0,BB,7C,5E,18,1D,4F,0B,29,27,EC,AC,6F,49,F8,E9,69,6F,84,84,17,8F,0C,23,D4,C7,77,21,B3,FF,07,4A,D2,0E,91,F1,AE,C1,3F,8A,9B,08,BB,15,BA,60,F7,1E,63,D2,92,1B,5D,BD,AE,A6,A9,24,B9,66,B5,04,57,D0,5F,0B,B7,1C,2C,B7,95,C7,A8,40,F1,5E,D3,D7,E0,86,88,09,C6,70,CE,6D,DF,03,EF,29,F6,E9,C0,BA,31,8E,24,F3,57,B3,A7,B7,CE,73,CE,2F,C1,8C,EC,97,B3,3A,B1,F3,70,DE,6E,D7,3C,AC,96,09,E8,71,FF,54,A0,7E,7E,EB,83,AE,E4,B5,64,8E,56,32,7B,73,9B,0B,9D,0D,47,42,36,5F,52,B6,2A,0A,4B,38,B6,BC,ED,9F,9A,26,F8,C4,C8,88,0E,51,82,24,F0,42,C5,CC,B1,E9,00,13,A7,BB,94,E5,69,59,61,E3,10,11,A5,46,84,BD,26,48,20,28,47,70,BE,7E,E8,6A,A2,21,04,7A,29,40,BF,25,30,49,D8,5B,4E,D7,95,38,4E,08,19,8D,25,F9,99,E4,DE,14,71,78,12,73,3F,DC,BF,B6,1C,AE,C1,3C,53,21,E3,19,FA,7C,C8,E4,31,ED,86,79,3F,43,2A,65,09,5A,FD,31,F9,E2,9C,31,79,4F,B8,EC,FD,DE,F1,47,3F,A0,A6,95,A5,8E,83,CB,F5,26,18,FE,E3,50,93,AE,42,80,84,FC,E1,E2,29,19,F3,D4,A4,14,EF,E3,C9,0E,02,67,E5,A7,AE,45,B2,9F,C5,90,80,C5,E5,B8,E9,98,5A,36,F3,E7,26,7D,DF,93,02,40,A0,B4,AA,9D,99,AF,57,C0,52,20,64,A6,ED,88,EF,3A,BC,8B,DC,2D,18,83,BE,CC,3D,AB,C4,33,D5,C5,04,4C,94,33,29,13,6F,05,97,03,89,5D,A6,82,D0,53,BD,4D,15,5A,0E,06,65,49,C1,BE,C9,15,78,93,6D,6F,41,69,E3,F9,E8,73,7C,13,90,8A,B9,65,86,02,CE,37,56,34,E3,37,B3,4E,AD,54,29,01,9C,56,42,BA,E4,C3,03,38,9E,79,53,F9,39,8B,63,32,70,23,06,0A,C6,E4,7F,52,8B,6F,48,B9,A9,D8,BA,CE,E6,93,A4,B7,A1,F3,AA,14,32,3B,39,1F,2E,6D,AE,9E,85,59,0F,DC,40,F4,A9,AA,DE,68,28,F7,D6,FA,FB,60,C0,17,59,11,62,01,7E,67,C4,96,44,D6,DB,B2,24,79,6F,EC,C1,17,C8,0A,0F,64,09,ED,8A,88,42,03,30,8D,78,25,CD,9B,A2,9B,5E,2C,28,77,B0,62,2F,6A,03,87,F0,18,61,E8,7F,D5,15,D3,D3,16,47,85,46,41,E5,8E,BE,4B,F0,31,56,2E,C6,67,A5,D6,50,18,64,4E,22,0E,C8,D8,8B,85,35,5A,7D,3A,44,37,FA,99,D7,AD,2C,70,56,A5,94,45,2E,B7,45,8D,EC,35,8F,AA,F5,B4,62,C0,B4,9A,9B,87,FF,6F,FA,E1,88,80,7E,57,E3,90,BB,E7,AF,88,5C,DF,01,16,27,F4,7A,C6,14,BA,C1,BB,44,7F,BC,F8,5E,A1,55,C1,07,0E,27,5C,98,01,4A,67,0D,6A,CD,7F,C2,8A,FA,B5,E3,38,04,13,FF,38,0F,C7,41,98,CF,85,80,E3,47,61,62,33,43,3A,54,DB,61,2D,69,35,24,61,07,5B,3B,FA,8C,4C,28,20,1A,E9,01,2F,08,43,17,20,F9,CF,28,66,2C,12,39,75,E9,EA,4C,25,A5,7F,81,79,5E,02,DE,EC,41,4B,14,BE,8B,EE,5E,CE,5B,70,99,A5,77,87,D3,32,53,C6,2F,CE,63,1E,6B,70,8A,24,C2,B7,CE,3C,0D,7F,FF,CA,35,95,FA,D0,75,1F,D5,03,FC,72,88,7D,AE,3E,BC,AC,B1,6A,8D,33,0C,38,0A,45,3B,DA,75,1F,D9,0F,8E,1F,70,BB,41,D9,29,EB,38,14,AC,3A,EA,5E,77,D6,0B,E0,EE,1B,F7,35,50,A7,D6,E7,68,1E,BC,C9,98,43,95,D5,89,07,AB,B4,28,49,50,27,50,18,7C,3D,15,31,F5,CA,76,12,4B,27,66,DF,14,F8,44,75,3F,C3,F6,5A,A4,F2,76,A6,5B,EF,5C,A9,73,9D,AC,57,D0,69,81,33,5C,30,6B,2D,43,00,E8,32,4F,98,B0,F8,0A,F3,2E,F9,6A,1C,3B,A5,B1,28,06,50,12,23,C2,99,82,6B,F1,88,32,1B,44,08,D1,6D,D6,A1,48,68,CD,1F,54,95,53,19,21,81,F6,86,A2,64,77,25,0D,4B,B9,EA,F5,13,23,09,12,F4,85,5E,94,E1,A0,16,0F,72,36,DF,16,2E,89,01,70,56,44,3E,A1,CB,60,A1,81,DD,D1,3A,96,3D,E7,46,65,5B,77,2E,DD,E2,4E,05,6F,48,E5,27,57,DC,02,4B,FF,2D,F1,F4,D1,3C,25,A0,18,FD,24,B1,1D,28,08,7C,C9,E0,12,DD,7E,95,60,5B,70,A3,52,90,24,A7,38,6E,B2,1E,DF,06,69,7C,E6,72,32,B4,02,02,6D,E8,1B,E8,C3,C8,F7,D0,C6,2D,81,98,1E,A2,80,F3,24,51,F9,D4,0D,92,3E,9A,1E,0F,8D,74,A5,71,93,10,38,DE,B5,55,0A,BF,C7,E7,00,2D,49,73,A6,9B,72,A2,53,CE,F9,D2,79,B7,16,47,09,39,D3,3E,47,C6,A6,B9,23,4B,4C,4C,7C,DE,0D,AF,C7,30,FA,FC,A5,FC,50,C6,36,74,A6,34,C8,08,C6,C8,36,35,F7,96,14,46,B0,2D,F2,9B,84,9A,83,2C,69,06,18,4C,61,60,35,75,4B,1E,8A,97,18,DC,AA,CA,31,81,DE,00,B0,81,C6,51,5A,18,21,2B,2D,4D,8C,13,B4,F1,78,26,B5,E3,3B,2F,0C,25,A9,28,F8,06,13,CF,8D,89,C7,DE,F5,67,8D,13,67,CF,12,85,67,04,80,20,A5,0D,AC,C4,F7,6C,E1,12,77,B1,39,FA,1B,F8,0A,5B,9C,BA,BA,D1,E3,2D,6A,D6,08,EA,E4,C6,D8,0E,2F,F9,16,24,71,4D,4A,9E,FE,80,BB,ED,8B,A8,D9,C1,B9,79,91,08,87,D8,05,4E,C1,CB,6D,16,65,97,7D,F0,F9,4C,6E,49,59,01,F8,2F,A4,85,27,56,54,6C,0C,68,4F,9C,FF,C8,05,3B,72,55,10,BB,DF,54,EA,3D,D4,50,47,FF,A3,22,13,51,C6,9B,AE,FE,65,1F,AE,B9,DB,D9,75,96,82,7F,45,EC,6B,6D,51,FF,4C,3C,AE,6F,14,0F,AA,B5,7B,71,3A,C7,31,73,1C,A6,E4,BF,52,5E,B6,17,E4,EE,13,26,90,61,0F,CA,0F,D4,B1,67,0A,BD,EC,EE,79,68,DD,56,69,32,6E,79,D1,7E,81,C9,85,4B,29,C4,CC,01,4C,56,02,99,5F,BC,33,46,E5,59,B4,E2,5E,3E,8E,FE,FE,51,51,98,CF,11,A2,2B,BE,24,71,23,48,EB,42,35,AA,E5,63,CB,12,C4,56,3D,D4,84,D6,83,92,EA,9D,29,2E,D5,03,62,5D,EB,19,93,C9,BE,9E,8E,D2,DC,B0,E5,56,B4,80,0A,1E,13,BE,9A,2F,AB,25,12,35,C2,8E,40,1E,C8,E3,EB,98,09,2C,25,AF,59,16,22,43,88,E8,A0,0A,84,6C,EE,84,74,05,B3,24,A9,BA,86,18,07,68,72,8F,7A,15,A5,EE,FB,4D,D4,72,86,B0,66,C0,94,AC,9A,9F,90,A8,3C,00,65,A8,25,09,D7,1B,22,41,46,90,0A,99,CC,86,6E,FD,15,55,19,C3,8E,A2,B9,C2,DB,A5,E5,2A,C1,3B,16,D3,93,F6,3B,B8,76,C6,DE,50,2A,26,72,1D,D1,94,9D,09,EC,2B,19,8E,B6,B0,C5,94,96,1B,62,80,24,7E,3B,F5,D3,2C,9C,46,38,28,49,1B,81,0D,98,26,A8,82,87,56,45,A7,F0,CD,8B,6B,FB,04,58,88,1C,96,7B,35,17,DA,15,B0,CF,52,3D,C1,9D,15,A1,FC,00,2E,4D,DB,6A,6F,88,F0,3E,23,45,FF,07,BE,8A,D9,73,EF,1B,9C,D6,06,2B,3A,07,B4,D6,50,B9,04,12,7F,1A,55,91,1B,06,0A,EC,C8,AC,E7,AF,86,24,24,55,29,23,1E,A6,0C,15,8D,66,73,5B,FD,24,ED,4A,F2,F8,36,63,2E,77,18,67,E0,C0,58,5D,A2,F0,B1,70,B3,AC,8E,FB,27,D2,9A,8A,F4,5C,B8,B2,0B,CA,5B,2B,8C,6F,9B,F1,C5,F7,EC,A2,A6,4F,81,DE,D5,43,18,BC,6A,6C,60,61,0D,7F,1F,90,58,4F,B8,43,BA,EE,A2,8E,FF,E4,F7,C0,73,D4,90,59,49,FD,24,AD,61,BE,E4,0D,A7,7D,00,24,F0,0C,C5,7E,0D,7C,5D,04,F3,9A,FB,B5,97,31,FC,99,CF,BE,9B,A3,75,56,A5,98,01,AE,00,80,DB,49,C5,60,D4,B8,C0,C2,D2,E7,65,CA,3C,31,D7,50,C6,21,DC,94,37,F1,04,75,27,CC,5C,9A,2F,5F,31,2C,01,46,F4,6A,3C,51,6B,53,0E,0D,BB,34,CB,81,C8,5F,3A,23,F3,8A,1B,3D,6A,DF,0F,FE,8B,8A,ED,85,85,25,09,BE,40,C9,ED,98,FD,1E,A7,6C,EE,FC,E2,B6,EC,34,42,69,00,15,DF,84,D9,14,45,2B,D7,39,0C,0D,87,E3,8A,D0,2B,26,F5,BB,BD,36,2D,9F,46,4B,63,01,8E,67,01,68,94,E6,06,CA,6A,7B,1D,2E,57,CC,BF,44,B9,40,77,FB,F1,73,95,41,ED,F4,10,22,A0,1D,75,B5,26,78,58,47,F6,45,8A,C2,97,E9,86,F8,5A,FF,C9,77,43,F1,3F,A5,BA,ED,E1,6D,74,C0,2D,B0,F0,E5,28,C7,D2,61,78,09,C6,F1,71,68,46,EE,84,59,FA,83,31,1C,CA,C4,8C,F4,90,58,7E,8C,D4,CA,2D,85,7E,C6,D8,AE,95,7F,39,E4,C2,C1,BF,87,C1,F4,F7,76,D5,09,71,E6,77,C4,3E,F6,01,ED,06,25,3A,2A,43,2B,FB,B1,D1,F4,B6,1B,5E,06,05,02,41,F5,C5,1B,79,2C,DA,BF,BB,05,E0,BE,BB,13,E1,85,6C,B5,D7,52,BD,0C,3E,5E,30,F7,F4,B7,48,F5,A8,61,0B,F1,36,50,C6,14,70,09,66,F1,32,71,F7,A2,7D,19,81,A9,39,17,DB,70,71,F6,C3,08,B1,C8,17,18,AD,4F,77,D1,F8,07,97,A5,05,92,88,FB,FE,F1,5D,16,42,36,22,8C,D7,03,1A,AA,16,2D,45,42,F0,AB,79,60,0D,72,55,D3,E0,32,F3,4A,F0,0A,3D,31,7B,E1,0A,C9,40,7D,F9,AE,2B,F6,83,3A,DA,32,9B,02,65,9A,39,CE,9B,DC,A7,A3,E8,A7,3A,63,5A,99,5E,EA,8A,AA,5D,62,09,7E,8B,3F,95,C9,36,CC,C2,A8,B5,7D,B9,F1,7A,71,A9,E2,A4,E3,A6,84,14,50,2A,AD,4A,6F,05,91,63,BC,69,46,45,09,44,13,02,8B,69,29,44,71,7B,7E,CB,31,84,99,FB,D5,51,C9,21,3E,16,3D,C6,28,FB,07,CB,93,85,0D,8A,AD,D6,C1,09,BA,C3,36,BD,9A,D3,91,2B,4F,D0,38,3C,2F,9D,9D,E2,77,D8,85,B9,52,23,D5,81,E3,19,DC,6D,95,FE,AF,50,B7,20,4A,34,C7,FC,0A,FC,D9,D6,2B,A5,83,37,9A,97,AA,3C,F9,88,19,A2,1E,CB,E1,8C,F8,21,90,A4,22,FC,B7,89,8D,54,AA,2D,BB,16,E0,28,79,46,E6,7F,22,B4,52,48,19,28,D3,8F,AF,B2,71,E5,D9,53,01,C4,F6,34,0C,3C,3A,C2,38,F6,C3,25,EB,70,C6,23,91,CB,B5,F0,11,63,E2,B1,AF,42,21,A2,8B,C2,54,CF,24,09,E8,3A,4E,91,C9,EE,40,90,B8,D8,E3,95,FB,8C,B9,A9,4C,4D,B1,6D,4C,12,62,15,2D,6B,BA,D1,C6,09,E2,89,9F,CD,3F,11,02,5F,1E,DE,14,B0,3E,D1,E8,7A,F2,3B,42,2B,BC,7A,8A,9A,75,E7,5C,4B,F0,F7,F9,EF,A0,EB,A5,F2,7D,92,80,A2,25,EF,AF,AA,E3,C5,16,C5,EE,E0,BD,6B,A8,86,6A,6C,8A,CD,37,53,EE,6A,0D,43,7A,87,42,C3,06,50,12,DB,72,A7,2B,22,AC,6B,90,12,65,C7,E7,C0,08,2B,2E,44,4A,8C,4B,21,43,4E,18,BD,FD,0A,0E,9C,3B,DA,B2,4B,24,A3,A7,10,FF,5F,FA,7E,E3,B2,A7,D7,09,D7,7D,E8,56,E0,D2,DE,C1,F7,17,4B,90,09,2B,75,D9,B5,85,A7,AB,44,01,68,3E,FD,34,36,AD,01,67,CF,EA,FB,47,06,F2,39,30,9A,A5,85,32,A1,EE,60,47,4B,C6,88,9F,B8,38,68,65,89,07,EF,10,DC,9E,DC,29,AE,16,16,F3,47,41,E4,4A,FE,27,7A,C8,E3,6B,EC,9D,8B,10,B2,D1,B0,9A,85,60,C7,4F,35,63,71,1C,6B,E0,C2,85,1A,7A,C0,69,A9,39,00,46,51,E7,61,70,63,0A,2C,3B,B8,2A,FE,70,4D,61,47,8B,FF,33,C8,DA,9B,91,43,9D,4D,2A,E9,A0,B0,2F,2B,DF,07,8D,3C,C9,2D,97,75,EE,24,7E,C3,BD,52,81,77,66,9F,63,E9,47,40,11,C8,D0,79,E2,34,E3,31,B9,A5,AC,8C,98,5B,E7,CB,EA,CB,2B,C0,3B,9B,C4,21,FC,D7,AB,E1,9C,0C,FE,6F,C3,74,8F,63,03,0F,05,FC,2A,60,9B,BE,18,FE,A0,36,B1,77,79,2B,FB,99,7F,EB,51,57,E6,4C,B3,95,C6,DE,FB,E1,7E,D5,3F,B1,83,55,A1,54,86,7E,DB,C9,D8,7C,58,88,BD,3B,F7,9A,CE,36,A5,76,12,78,4A,22,0A,6D,02,39,7A,13,FB,3D,C4,94,AB,AC,8C,23,76,98,82,8E,3D,9D,AE,F0,4D,06,6B,A6,23,8C,2B,70,69,DC,3C,95,8B,14,9D,4B,F9,33,86,F9,52,ED,BF,D9,DA,D8,77,7A,2D,28,8E,2B,0C,E7,39,F3,1D,C8,64,12,C6,98,18,40,CB,83,9C,26,7A,CE,78,CD,22,9E,9E,2F,C1,3C,B6,C1,39,90,BA,C1,C2,93,35,AD,00,B3,97,82,9F,37,3A,AB,2F,CF,C5,11,86,C8,B8,16,04,B0,60,C4,5B,4E,C7,9E,75,1E,04,BB,6F,DA,C9,86,67,55,4C,3E,C4,52,F6,94,5C,1D,C9,A4,32,09,44,AD,36,A0,17,7B,D6,52,D2,BE,32,67,81,EC,F1,81,22,37,63,5C,51,AA,6F,C4,D0,E8,7B,14,3B,B3,B2,33,2E,54,3F,DD,20,12,5F,6D,F1,52,11,DA,7D,EC,9F,66,ED,9F,3C,7B,E2,30,00,8D,9D,C6,AA,6D,29,85,6E,34,FE,AB,88,40,95,84,C4,E6,D9,10,19,42,4B,6A,DC,FB,C6,AD,E9,F3,8B,80,B6,8B,E3,6D,09,2E,44,C4,F6,46,C9,D5,22,6C,6C,5B,74,24,00,FE,CD,A7,63,8B,9B,E1,D2,E7,32,F3,45,F7,C6,A7,22,9F,60,C4,33,B1,57,F2,42,5D,05,57,85,AB,58,15,AC,4A,56,D9,6A,59,F1,12,CE,23,E3,50,17,3F,CA,41,57,04,7E,36,6F,D0,BE,F9,AE,A6,D9,CA,6E,52,84,52,69,A6,2D,C5,53,75,75,81,31,A3,14,7F,2D,06,05,76,8A,CB,8D,21,CA,A9,7B,BC,3A,AB,C3,AB,0E,C9,55,B9,6E,84,50,6F,CA,13,03,F0,35,4E,76,3E,39,8F,DD,96,70,99,47,13,C6,05,13,EA,9A,5D,D0,60,21,51,05,5C,D6,28,59,2F,7E,0D,B5,12,D7,3E,41,E6,F8,23,4F,23,D0,6F,A9,00,97,86,63,1B,AB,C8,21,0C,15,53,E3,D1,77,22,51,6A,07,19,66,21,9C,92,96,5D,14,42,91,EB,FF,F0,32,E7,9A,59,99,AA,C1,D4,9B,D3,B4,91,9A,44,D0,91,94,9C,53,D1,1E,FC,B0,3B,C0,9F,0C,51,2C,6A,B9,1F,13,63,6A,8A,44,68,DA,D8,D4,0E,03,76,B1,00,CE,16,BC,43,7D,89,A6,E7,45,68,2A,AE,C1,73,09,16,81,01,36,AA,CC,A1,EB,57,6D,17,41,00,46,F6,74,63,9A,77,D6,87,EF,62,CE,3D,BE,BC,8A,72,71,62,77,A1,19,64,36,4F,D0,4A,DE,02,B0,86,2E,65,36,98,BC,3E,DC,74,F7,9D,2F,54,22,CD,C6,9A,11,5D,50,F8,14,2C,74,52,9F,D4,FC,D0,29,33,97,EE,DF,8B,67,2B,F7,32,F6,CA,08,F8,C9,CD,6F,5D,58,DC,0E,00,12,02,EC,97,A5,B8,09,D3,D5,6A,14,11,F1,35,12,0A,18,59,0A,6D,48,53,16,A0,73,44,08,19,5B,17,57,8B,37,CB,F5,78,E8,73,55,04,AC,5A,E6,D4,AB,FF,64,43,63,43,E0,4C,FA,15,2C,94,AB,76,C5,2C,9C,CD,86,60,02,02,E3,51,3E,FC,A9,EA,A9,F3,9A,B8,B8,9C,F9,53,CB,38,C3,C4,EB,45,9E,7A,04,60,C0,CE,23,EB,AA,BC,78,A1,C2,56,62,81,6A,DF,07,05,5C,61,1D,19,6D,EE,2C,28,2A,0F,B4,16,14,A3,20,A7,87,E3,83,D7,D9,18,93,E2,3B,ED,89,ED,24,08,05,00,72,6A,89,C8,9C,47,52,49,60,C2,74,E5,5E,96,D6,44,D9,11,68,35,90,EE,53,B6,01,46,97,66,AF,1A,BB,48,58,FA,A8,E7,9B,EC,B8,D4,DC,7B,BC,EF,1E,5F,DD,3B,CE,00,DB,7B,5A,BC,91,6A,25,6A,BD,40,AA,95,69,B0,9C,0E,40,AB,CC,CA,A1,24,1B,AC,30,0E,BF,35,30,C2,C3,13,2D,C1,24,80,03,37,DE,C2,B8,3B,D0,A7,E1,38,72,CD,72,5E,D0,A1,8D,6A,12,7D,3E,25,21,4E,C6,79,D1,AD,D9,8F,06,D7,68,4F,B1,5F,FF,3A,44,08,58,09,6D,F4,9D,D1,6E,97,EB,51,58,48,33,74,67,5A,D5,17,BE,64,1E,A8,A0,81,AC,8E,3F,6D,82,AB,CB,49,FF,A2,2F,BA,A0,05,EC,60,ED,7F,7B,90,4E,6D,D6,DF,73,0F,29,1C,F5,B6,3C,FD,F0,D8,4E,1F,1F,77,14,CE,94,50,5E,47,E6,B5,4C,95,B1,17,9F,63,FD,E4,7D,30,9A,25,9E,E7,08,C4,21,20,85,93,53,C8,37,DA,90,B6,32,54,B8,3F,96,74,14,16,15,D0,4A,0E,58,C6,B0,EF,6D,69,40,38,A7,10,67,4F,1E,19,8A,12,26,02,BF,1A,B5,C7,3A,E8,DE,BE,96,24,67,71,D1,9A,D8,0F,CB,B4,7E,C6,62,E8,B7,7D,AF,1A,38,65,7C,E7,BB,6E,07,40,EF,D5,DA,67,EE,67,DA,06,1B,02,68,A4,76,07,B2,C2,49,5F,94,83,51,F6,77,64,F6,C9,E7,22,AD,A8,79,69,72,BD,94,E0,12,0A,55,7F,B9,08,62,4B,C7,84,0D,07,58,8E,8C,2F,AD,F7,54,C0,37,60,FF,4D,8B,DA,0B,23,3E,CC,AB,44,9D,F0,E3,38,C6,4F,6D,CA,1F,1C,8B,90,59,65,D0,BB,7C,42,16,F6,A0,05,05,67,11,A2,17,B8,A0,2C,6B,BE,3E,33,46,CB,66,2A,A9,44,FF,37,C0,A4,70,3C,80,9B,72,AB,53,2F,D4,2C,16,87,C4,4D,17,98,37,D2,22,E4,56,0D,8E,62,F1,C5,68,A5,A4,AB,B5,6E,EC,EC,D7,CA,0E,79,BB,85,66,DE,D6,49,B7,6A,B9,5F,5C,DF,46,C8,B5,83,8A,B6,D2,B6,5C,61,BD,31,0B,B2,EF,88,F5,5D,41,D6,93,C3,AB,FE,1F,DB,98,28,DF,F8,9B,F5,09,E1,FE,F0,6F,C9,AF,BE,97,08,7B,67,36,FD,A5,9F,7C,77,76,1F,5E,A2,6B,FC,82,88,F5,49,E9,46,82,EE,20,0A,7A,99,34,23,F8,57,A7,8C,7D,AA,EF,77,A7,96,06,AB,57,89,8F,D4,77,05,BA,11,77,5F,16,AD,A6,5D,CE,60,A5,A9,9E,1B,E1,5C,CB,E6,9A,56,8D,6D,66,19,E5,85,C9,6C,3C,47,13,57,86,59,41,5C,60,AF,A0,DD,BD,54,FA,FB,A4,1E,7E,EC,30,6B,C3,50,27,CE,74,56,0F,EA,E5,8F,60,5F,C3,C5,E9,01,28,FE,1F,AD,E8,A7,35,FF,44,75,4D,25,CE,CE,2A,F2,A7,90,85,BA,CC,E0,74,8D,9B,52,32,40,DE,21,08,AA,16,DF,99,BA,B8,5A,B0,7E,94,46,DA,A5,28,47,06,F5,86,A3,8B,6B,62,EC,C6,ED,F5,EF,50,2D,87,8A,0E,F7,48,3A,87,9A,ED,6F,9D,3F,C0,D8,54,94,E9,D0,D6,7A,90,3C,45,3D,3E,00,0B,A6,10,D5,03,00,88,8A,57,34,A1,00,0B,AE,07,09,48,64,D0,FC,07,83,42,CC,8D,DB,97,0E,F6,22,EA,EC,F8,0C,C1,7C,CA,09,AB,CF,C9,78,10,9E,9C,A3,87,83,61,DA,17,FB,72,14,1E,4C,D7,DA,26,5B,17,A7,4D,2B,D2,C3,C3,E6,A7,88,C8,BD,6A,92,7D,1D,FD,B7,66,79,BE,B4,BA,A5,82,63,E7,8F,5C,7B,F8,4D,5A,55,1B,36,9C,A9,51,B3,0A,B2,0B,5D,82,21,BE,B8,A1,08,9D,F9,41,57,33,38,7F,11,1E,AD,6F,95,01,2C,FC,3E,7C,D6,C2,4E,01,77,5D,B7,AF,C0,B2,3F,8E,B7,8A,70,05,87,16,0D,AF,D1,1E,F1,AD,57,B3,FD,C2,DD,44,3A,37,23,FA,35,9B,5F,35,91,2C,49,51,75,6C,D1,A7,5F,63,03,A4,FB,F7,AE,10,9A,99,13,B9,84,3B,FF,95,7C,67,AC,32,88,AB,E7,B4,6E,9B,D4,61,75,24,BD,E4,76,17,3B,57,BF,44,94,E8,B7,3F,FE,58,BC,0D,DC,7C,1B,91,07,03,00,C8,D4,41,3B,41,07,AE,5B,CD,59,FE,5E,C7,1D,A7,55,9F,80,09,F0,AB,19,2A,05,DF,0B,12,39,65,B2,AC,62,19,78,BC,C2,41,F1,55,85,3D,C0,0C,8B,42,70,DE,EE,AC,95,27,2F,73,BD,EA,DE,B4,33,6A,88,D9,78,90,6B,AE,C7,5D,D1,CB,CB,FA,B1,F3,91,D1,62,9A,1A,2F,6D,47,5C,AB,C1,11,AD,F6,AA,93,3D,B9,76,08,D4,27,4E,21,31,01,5E,7A,00,79,85,E7,58,40,B6,E7,29,F3,91,97,BC,A1,B2,77,02,6F,83,F2,47,56,1C,26,20,97,B2,4B,76,33,91,4A,50,C4,66,5E,F7,F5,F2,D2,E1,F4,22,FE,E0,E3,DE,8E,D8,F0,6D,52,84,82,C0,1B,5A,AC,D3,5B,73,A2,73,06,0F,FB,9C,81,12,F8,0B,8A,C0,F8,0B,AA,3B,64,81,55,38,49,62,36,D9,3C,74,F4,1F,77,E2,0E,A0,0F,7D,B6,AC,CF,64,BA,AF,CA,B3,0F,2A,5A,84,66,4E,A9,DD,80,A5,87,7C,91,68,6E,5A,33,93,F4,BC,A9,38,FB,AB,95,F3,2F,76,03,E0,45,24,54,73,A7,BE,5C,C1,01,8B,5B,43,B9,53,92,F2,37,BE,67,BB,F7,2A,D0,79,62,4B,4E,26,9A,83,9B,67,A0,93,14,3E,73,4D,69,44,A6,BF,FA,F4,A2,C1,58,F2,78,2F,B4,4D,D1,5D,83,DF,F6,58,E8,EF,33,20,C9,E3,52,90,C3,25,6D,82,39,53,71,4C,EE,25,F1,97,2E,E7,C3,A4,5E,F9,A1,0E,8D,46,19,6B,59,B3,CD,2D,02,E5,FA,6A,CB,BF,B0,B1,6A,F6,EF,48,1F,1C,FF,8D,D8,48,FB,E8,72,D2,35,00,82,27,D7,88,66,B6,52,67,2D,FE,EC,BD,44,1A,92,EF,15,66,C1,12,5D,D9,EB,37,5E,B1,A5,0F,A9,77,5C,31,9C,1A,53,DF,4C,D0,19,E5,83,24,C6,30,67,0E,10,3A,72,76,42,E3,60,14,B9,E8,01,94,E2,E8,53,5B,82,8B,0A,CA,7F,46,E7,57,00,5E,AE,70,E6,48,A1,2D,D9,8F,9D,A2,11,D5,0A,90,31,B3,80,2B,45,13,99,FF,6A,C0,1F,08,F9,B0,29,02,35,F4,CA,C9,B0,C7,6D,22,A3,DF,7D,83,42,A4,60,C6,AA,22,9D,62,6C,B9,2B,56,33,52,E2,D0,FD,1B,E7,70,C9,F3,2B,D8,BA,4C,55,D6,3F,4F,2A,62,D9,44,CB,09,B8,C7,A1,90,0E,C1,56,E7,7B,AE,97,D0,68,23,EB,1A,01,2F,DB,AF,36,DB,97,41,35,12,BF,45,9E,E1,B2,50,D9,E6,3D,E1,17,F4,A6,CA,AE,56,60,FF,78,7A,61,03,D4,A6,69,2C,57,5E,23,AC,07,67,9F,5D,AB,7B,3D,1C,68,37,C6,AB,FE,A4,7A,EA,87,DD,12,32,45,99,3C,66,7B,DB,65,B2,26,13,26,CB,11,F0,B5,D3,3C,E9,10,8A,8A,BC,12,7D,44,E4,72,83,93,68,B3,9A,DA,65,ED,9A,54,4A,1B,E8,64,83,BE,A3,53,82,A7,36,5C,DC,4C,A2,9D,D6,07,15,5D,94,24,81,6B,97,12,88,1B,55,7D,B4,9E,75,F4,C7,64,96,0D,71,EF,0F,9A,4D,92,62,AB,D7,7A,6D,14,76,F6,6B,00,B0,CE,5E,29,10,95,ED,15,B0,FD,3C,5A,25,4D,13,FF,93,D6,4B,C3,FF,FC,EB,3C,E8,8D,2A,99,76,F9,BD,9D,DA,2C,81,FD,93,4E,B6,BF,6C,F4,D1,BC,1E,CD,BB,86,2A,70,BB,97,1C,ED,F8,2B,17,B3,30,EC,F2,DD,52,DB,93,D2,50,E4,57,E5,CF,BB,9F,7D,6F,F4,6A,61,F4,54,EF,67,6B,57,EE,F6,09,FF,7E,5E,1B,9E,3C,8C,B3,E3,AE,0F,12,96,EB,13,C5,52,0E,77,1A,B8,C0,BB,71,D0,22,E1,6C,06,5F,F2,3D,C0,68,B6,D6,D7,4C,73,FF,76,12,8A,46,89,B0,4E,E5,35,6C,91,CC,DE,CE,06,D1,C3,8C,5E,0D,E2,0E,AE,FF,12,C8,5E,D1,06,74,15,DB,B5,78,3D,B3,32,15,91,D0,47,37,7F,D8,F7,4D,A9,F4,29,B7,4B,60,48,49,06,87,45,F4,5E,C8,FD,C6,70,06,C0,4B,6D,C1,51,AF,3F,07,C4,76,64,07,E2,6B,AA,89,D2,8E,64,2E,FC,79,DB,57,10,AE,1C,CC,EB,CB,95,97,F5,7D,30,FF,15,7F,87,16,A8,69,4E,8E,FF,23,9A,3C,F0,FE,77,49,E9,5B,11,CB,CD,E6,BF,13,49,3D,EB,9F,4A,E7,9B,03,EB,3F,08,45,67,14,61,B6,82,A3,50,D9,E8,4B,FE,25,D3,29,E6,A5,7A,9F,4C,C3,E2,3D,1C,42,7E,C8,4C,41,97,76,4F,0D,30,B4,AD,0F,0F,C7,27,58,DB,D5,38,A2,B6,A3,EE,C1,9E,40,17,DA,03,7F,7D,67,D0,2F,88,26,0E,1D,A9,12,A6,CF,F3,D6,54,2D,CB,13,46,24,A5,58,C2,65,89,A7,46,F4,6C,D8,C9,FE,97,FB,5A,7F,C8,7D,FA,77,06,90,DA,EF,B3,53,2D,E7,8B,6B,50,05,4B,B6,02,1B,46,BC,AD,95,2B,A7,73,7D,81,9A,A8,4E,18,EC,FD,65,86,B9,FE,80,7F,1D,02,B1,B7,F9,54,99,82,FE,C0,33,13,5A,38,93,AC,83,19,5C,7C,62,74,5E,8F,9B,27,BC,CB,44,20,5B,C2,FC,17,F9,36,82,F6,54,3D,8E,D5,68,5F,36,8B,4C,E1,12,5C,92,D0,DC,37,A3,49,09,C3,50,C2,C4,5D,63,CA,6B,10,41,D0,BF,F7,06,D1,66,AF,0D,DC,00,8E,39,4E,86,73,DD,1B,98,CC,06,C1,6F,58,6C,26,CE,F2,AF,63,85,16,D5,75,2A,13,AE,BB,CD,8D,4A,DA,8F,43,F8,C5,C4,C9,D6,01,91,A7,A6,98,76,39,0E,FD,CC,5B,B8,94,08,62,C3,D2,21,37,B0,BF,1B,47,00,4C,50,92,21,D2,0F,46,F1,B5,AA,A9,50,60,36,06,63,9A,2E,92,5D,60,09,1F,5F,9D,B0,8C,BD,6C,4A,6B,E2,7A,38,CE,A2,7C,4C,C7,A9,3F,3D,D3,9C,90,3F,33,BD,2F,8F,9D,93,47,53,93,3C,EE,A2,70,3C,EE,C7,31,55,E2,B5,AA,88,F3,4C,25,1B,17,70,4C,9E,C9,9B,43,77,27,7D,48,93,32,3C,74,6B,93,31,82,CD,8A,92,53,BF,7C,EB,BC,7C,EC,CC,97,98,FF,F2,09,1F,2A,BF,B6,24,23,FC,F3,18,36,4E,47,AC,E0,ED,C8,93,7A,09,25,0E,DC,A0,70,8D,68,B1,25,D1,F5,C6,9A,D2,C5,93,CE,B9,8C,11,89,DD,42,96,42,24,55,D1,C3,14,80,85,DF,A1,39,A8,53,9A,B5,78,50,59,1C,51,E3,8B,86,46,82,06,79,37,DE,25,87,66,8E,91,14,4F,9E,2D,02,90,80,2A,75,66,B9,08,B1,75,BE,8B,4C,04,38,A9,2C,42,D3,C8,B5,89,25,4A,6B,58,E1,70,5A,8E,D2,A7,82,F3,2C,93,81,91,10,EE,F5,C2,F5,15,75,C5,8E,38,C6,B8,8E,F3,35,92,61,40,4D,B7,07,F5,95,1C,2B,A2,4B,BD,8D,76,83,6D,BF,C4,9C,F4,FB,F0,4D,D6,8F,25,63,B9,20,BF,72,50,A0,2A,99,D0,9E,8F,BB,39,C0,74,5A,A5,36,DA,DA,F1,CE,09,1F,06,4E,03,1F,B5,92,49,1D,6E,92,9A,F4,BC,F6,3C,92,1D,70,52,F3,CB,1B,7A,44,CF,68,1C,BE,9B,A2,B8,A9,DB,CC,FC,9F,47,C5,0D,3B,94,19,E9,30,8A,97,3E,C7,19,80,0C,80,54,82,82,AC,B3,F8,AE,1F,DA,94,69,78,15,FB,25,3A,A2,0C,41,09,FF,1F,33,DE,CA,A8,0F,D4,12,23,84,01,88,6B,B7,D7,27,E5,31,02,56,32,5F,8A,FA,36,E6,54,7C,76,5B,AC,5B,49,26,56,02,82,46,2B,8E,36,42,74,27,8F,7B,65,E0,8B,06,09,2F,EE,C3,32,32,51,2B,05,D2,8A,66,BC,6E,D9,8B,2A,0C,D8,18,95,80,49,57,55,DE,6A,63,62,DB,7C,A6,7B,42,F8,DA,0C,09,48,EF,1E,E8,1A,A2,0F,3E,DD,8D,6D,31,C3,D5,94,0E,92,34,A1,D2,1A,C4,A6,8C,D2,83,A7,A5,9E,5C,66,45,5D,5D,C1,90,CA,22,E0,65,0D,16,30,AC,AC,2F,3C,C0,B7,67,F9,55,21,DE,F4,92,5F,DF,1E,5E,49,6B,E0,E3,38,6A,1A,DB,25,21,56,5B,BD,04,DA,EF,CE,60,18,7D,69,A2,D0,D6,70,B2,FF,AF,AE,08,32,61,A3,66,7B,30,BE,3B,8B,6B,37,80,1A,F1,4C,48,0E,F1,48,03,E1,22,A0,1A,DD,B3,27,00,50,1F,02,6F,4F,2D,97,C9,78,1E,9F,48,7D,70,54,64,8B,9E,75,4D,98,EF,D4,23,57,2D,29,51,93,FF,65,32,21,8D,1C,67,B5,4C,3F,41,56,11,59,4C,84,CD,B1,7B,58,50,6C,F5,57,DE,60,97,2D,FC,9B,38,80,3C,26,BB,BA,52,70,86,22,AC,E6,FF,73,16,54,82,56,EA,8B,97,F0,41,28,E5,62,EB,20,80,37,39,02,08,34,68,2C,D5,D6,2B,2E,F7,45,C0,57,75,0E,84,DC,E4,19,C4,6A,62,25,65,54,01,72,B1,8C,C6,7D,2F,29,BB,BC,6A,2C,26,5E,BC,D9,1B,59,69,F3,C5,08,83,AF,D8,55,00,35,DC,98,E3,5A,E7,60,19,07,F9,B0,72,A0,73,28,48,03,62,9F,B1,A2,FF,CA,A5,10,0F,E0,60,D1,9D,A1,F7,8E,60,18,50,2C,2D,05,BB,DA,D1,B1,C6,62,71,40,49,A7,AD,C5,53,90,E1,17,AA,44,A2,F9,04,C4,15,2C,6C,18,25,43,23,01,4A,4A,9A,2D,AE,88,84,60,08,74,88,9C,43,57,05,74,1F,F0,D0,D9,C4,A5,71,77,E3,20,63,8E,32,1C,EF,D2,41,EF,49,BE,0E,A2,74,67,24,8B,42,3A,7F,B5,71,50,F1,84,56,0A,92,E8,63,82,DF,04,AC,0B,73,9F,BB,83,00,5F,A6,E5,3E,44,3C,FA,6E,B4,D9,87,95,C7,30,2D,39,70,C7,7D,B9,8C,26,86,27,6C,42,63,B1,0B,C8,C1,85,A0,69,F1,50,AF,A4,AF,4C,07,B3,84,23,EC,51,A5,4E,B7,7F,A1,CF,2C,0B,7D,45,13,30,12,47,BB,F4,2D,AE,36,03,18,1A,EE,FE,4B,BC,B2,47,EC,82,86,D4,4E,0C,B9,90,40,F5,41,D2,DE,74,62,E4,C7,72,28,0D,50,35,56,51,B2,12,78,C5,BC,59,F4,9A,8A,0D,E8,C5,FF,BE,0D,44,2C,A7,C6,2A,8A,92,9C,F1,D7,5B,F1,9E,EF,51,AF,FF,A5,C5,D7,D8,86,13,9B,EE,D3,0E,4E,ED,C5,1E,A4,52,06,E5,F8,52,A3,F5,B6,AD,CA,64,A9,EB,D7,D8,91,E7,75,09,FC,80,45,0B,A4,42,49,D0,3E,76,93,29,94,1F,78,DD,5E,B2,A5,BC,DA,E2,64,E2,21,ED,F5,F1,08,C5,24,21,34,AF,87,D9,92,93,7B,5F,A6,BB,2E,BF,4C,9B,15,31,A5,9E,E8,53,B5,11,DD,40,C1,0A,2D,67,09,87,03,E1,7F,47,70,9C,67,5B,62,D8,41,B2,CB,70,AA,3D,E0,3D,93,DC,68,5E,5D,B0,91,14,96,19,5A,92,D6,6B,B9,AC,B5,FE,ED,83,8F,44,C1,4D,B4,D7,9B,3D,2C,28,2C,67,24,06,07,B1,46,C1,71,26,B2,21,4C,09,7A,3F,96,0A,CA,25,67,21,6E,DA,3F,8D,5B,9D,69,DC,92,E1,41,7B,36,45,A3,A2,CD,F7,9B,9E,99,92,DF,ED,03,31,CF,1A,06,AB,60,1D,0B,1A,06,30,52,12,2D,BF,14,39,59,AA,28,44,33,56,07,88,2B,9C,7F,0D,F0,86,87,4E,28,21,3A,C1,CE,30,EF,36,F5,67,00,98,BF,07,7F,5E,B7,B6,B8,3A,12,67,77,16,2C,39,32,D7,CA,EC,9B,ED,D3,9C,F5,EE,45,52,74,49,DE,D8,F5,44,A3,11,75,EC,35,A6,D6,17,E0,E9,81,3D,72,51,AA,F9,30,0F,07,06,45,AE,23,3C,F8,E0,E0,1C,A4,75,A9,B1,63,B2,3F,E2,28,FF,FD,47,C5,81,F3,2F,9D,63,5B,F9,F5,43,95,CF,C6,9D,5A,FB,EE,A0,8A,8A,A1,59,FB,1C,35,70,61,8D,97,C7,26,54,E7,1F,CE,68,60,8C,4C,17,8F,E9,D2,46,BD,A6,A0,EA,81,51,91,4C,94,4B,E6,D7,E5,BB,85,00,D8,ED,24,CB,EA,59,FD,F6,C8,4E,E7,3F,19,1C,76,1B,FE,56,A5,AC,FC,E7,00,22,1A,63,B6,8A,5B,47,25,42,0C,49,5E,2D,76,CB,39,03,60,DE,98,B1,A5,AC,0C,7D,3A,50,FA,5D,D3,3E,5D,77,E0,B9,EC,99,C1,E5,7C,D6,D6,D4,3F,7C,09,B0,7A,D7,44,4E,F7,FA,70,3F,D7,ED,9D,A5,D8,3A,33,EB,C2,72,0B,82,7F,F8,B6,46,E7,E2,56,EF,B5,2B,51,75,04,47,A6,C0,91,F7,D3,E1,C1,9A,10,93,B6,CA,A0,B0,38,E0,3F,DE,F1,61,DD,D0,83,55,72,B0,6A,BA,9F,73,81,79,FC,F2,54,7A,A5,85,0D,41,73,F4,FE,DE,71,B4,F6,AB,E3,B4,CF,35,FA,6E,08,0F,88,94,CC,C3,09,C3,D5,E5,25,BD,07,AE,B9,41,60,C9,9F,14,8E,CD,6C,A4,E9,C5,73,DA,4C,C7,E2,37,9F,5D,EE,2C,49,31,9F,44,87,86,C7,5D,60,15,8A,AC,5F,03,A8,78,EB,B4,0C,2D,66,2E,04,50,10,E5,31,DD,51,3C,71,AF,28,F7,9B,5D,26,41,F1,81,78,5A,17,42,23,17,84,82,7C,2B,BD,59,1F,5E,FA,5A,41,E8,B7,EA,E1,42,4D,6F,79,D8,C9,E3,B7,2D,CA,95,AA,56,39,68,D7,04,DD,5D,DE,58,85,99,76,8A,D7,2C,53,2F,69,CE,29,81,F2,FB,4D,DA,0A,45,8B,CE,F5,E8,4A,A2,6A,D5,1D,FE,D9,33,70,6F,DE,A3,13,08,05,76,8B,93,C2,14,CF,F9,2A,B1,DB,03,D9,6D,F5,B7,E2,FB,0D,A1,53,58,68,60,B1,89,2F,B6,52,5B,78,C0,B4,1C,8B,52,FC,A1,6C,6E,E0,A2,F1,A7,32,88,43,1C,D2,72,BF,1C,23,E0,6A,D3,B3,CC,EE,BB,28,D3,25,11,97,03,68,D6,47,00,1B,0A,94,4F,64,ED,A9,F6,64,DE,71,F0,41,81,65,46,2B,0B,BC,70,EB,EF,5D,62,47,F5,33,69,42,BD,96,CE,CA,B4,C9,F9,4C,80,49,1C,90,A0,63,0B,57,D2,74,58,98,ED,B7,1A,B6,27,33,91,29,7F,5F,1B,94,12,6E,01,C4,3B,C5,00,16,61,08,F6,B2,53,6C,D0,D8,07,85,02,C8,01,A7,11,F2,C5,E2,70,D7,2A,AE,18,2F,34,A1,44,16,56,0C,DB,28,85,EA,31,20,08,D0,FD,B8,43,6F,0D,7B,4A,30,97,7C,1F,7C,4B,0B,97,1A,43,F2,EC,35,F0,CA,D2,FA,F5,3F,4C,13,54,EF,B0,88,54,9B,43,8F,73,34,86,97,D5,59,AF,73,6C,30,8E,D5,8B,AC,6B,C6,D2,90,40,A0,CA,E8,53,B6,50,3F,9A,32,54,AA,F6,9A,D5,9E,C1,72,73,96,FD,7E,00,1A,39,2A,4C,38,EA,1F,3E,30,F8,C0,20,D1,1B,71,A4,1B,57,ED,91,CD,1F,72,E3,04,F6,0B,AC,49,01,B6,F6,47,6F,C6,21,2F,9A,DD,29,CB,05,A5,70,3C,B2,9F,3B,CB,60,DD,48,44,EC,C8,58,73,09,2C,F6,FF,3A,D1,E3,0F,5D,38,F5,A2,D2,08,FA,1D,0C,99,51,9B,59,B9,F2,07,C7,FA,44,B4,F4,51,6D,DD,F0,F7,12,41,78,92,DE,7D,9F,60,70,97,0A,B6,BF,A5,3B,A3,F0,40,02,EF,1E,45,34,75,2C,EA,14,D6,13,C7,83,A7,71,F4,44,E3,6D,6A,19,89,87,AA,E6,2A,61,97,20,EA,8D,A0,B7,C9,02,67,87,0A,CD,0D,E0,88,C5,11,DA,3F,A9,21,5A,D5,B8,61,6F,76,5D,B3,9F,1C,DD,BC,2A,00,86,FD,37,3E,AD,2B,76,7E,A9,84,22,81,3D,49,76,37,7D,5A,44,4A,E5,1C,A8,B7,3B,AE,F9,ED,61,C5,F4,F9,9B,45,9C,A7,DC,A2,9A,DB,7F,B8,7A,8C,E2,56,81,67,F8,36,BE,7F,F2,04,73,25,B2,F2,73,26,AF,2A,2B,27,C3,40,6B,A4,3D,AC,3A,4B,02,1E,0D,D6,AF,65,BE,45,3F,A3,26,9A,7D,B6,96,81,D1,CF,FC,02,83,87,F4,9B,B1,8D,E8,50,52,FC,1B,14,D8,EE,C2,B3,0B,A9,EF,35,83,1C,8D,04,7C,8C,F6,F4,3F,1D,E8,9E,35,21,7F,41,DE,AF,B3,7B,CD,D0,8B,74,7E,61,F5,6A,3E,95,33,31,2B,AB,7A,4B,AC,67,D6,E7,03,4B,11,61,08,40,71,B1,C0,AE,2E,82,E7,C7,85,2F,EB,9D,AE,83,F5,AE,70,5F,27,FB,78,1A,69,BE,55,BD,F2,E3,35,F9,54,D7,68,4F,74,98,F0,39,9E,73,0A,74,51,49,65,20,7A,65,E4,25,3C,40,F6,2D,00,FD,88,8B,FC,21,EA,2F,F9,DC,CC,EA,77,C1,1E,BD,1C,0E,46,D0,F1,87,12,69,FC,DD,50,39,4D,FE,F4,E1,F0,81,A6,E4,B6,D4,78,0F,99,4E,84,A0,35,B3,FA,75,46,EC,EC,8C,05,ED,C3,F2,8F,1D,A8,CD,E9,0D,7E,52,61,A9,6A,35,B7,94,8F,CA,01,90,C4,2C,2B,7B,2A,C4,33,18,37,68,9C,D2,D1,8B,46,00,2D,95,23,22,71,E8,C4,9A,71,4D,AA,0A,9F,FE,2D,A5,68,01,99,D6,F1,04,55,A2,C1,7E,ED,2E,68,2A,DD,EF,8C,B9,A9,9C,51,BF,71,6B,50,CA,30,A0,9E,A3,DE,82,BE,C5,7B,E7,81,49,F3,51,5F,D9,11,F5,40,C0,E2,96,66,3B,F3,93,7C,25,E4,1C,34,74,9A,EC,5C,57,99,59,25,B7,C5,73,31,84,D2,80,B0,92,75,28,BB,FD,5D,19,80,0B,C7,7E,CB,66,52,E3,53,9C,A4,54,DE,AD,23,DB,57,21,37,E0,EE,3A,E3,BB,74,07,85,6D,E4,22,78,74,1A,A5,17,3B,8B,6B,E3,70,07,F1,E5,E7,99,4E,EA,8A,2C,6A,76,5E,42,F1,A6,F9,33,AF,44,E7,5A,B8,77,DC,F7,B8,A3,5A,94,13,0C,A6,9B,CE,93,63,DE,84,97,1D,95,40,B9,E6,E0,7A,C3,B7,BB,21,8A,0D,F3,04,4F,5A,3A,E8,05,3D,1F,FB,CF,E1,F5,AA,49,94,13,EE,58,FF,10,35,BB,63,F2,65,5C,C5,69,81,FF,68,4C,16,4C,DD,4D,24,B7,E7,40,0C,37,98,69,DE,BC,2B,66,32,8D,30,D5,F3,19,0C,15,92,CA,0A,59,6E,6E,0C,0A,50,CB,B9,C8,7C,05,D6,CD,78,5B,C0,E1,AC,2F,AE,38,DA,25,6D,F9,1A,F4,AD,64,8A,5E,BC,92,8B,37,15,6E,50,62,E9,6C,AC,A4,84,40,C8,37,83,97,8E,45,31,AD,07,ED,1D,47,1E,4B,C7,D6,CF,60,A2,CA,93,4A,FF,62,2C,51,40,C0,C8,17,FC,6B,3A,23,DE,22,8B,6B,FB,44,4F,1E,7E,BD,FA,4C,D5,ED,E7,16,2E,24,39,67,1E,15,15,AB,81,6D,50,50,1F,6A,BF,49,13,74,AD,9A,0F,CD,9F,89,4C,DE,BF,51,52,BC,E2,98,F2,F4,EC,91,EA,24,1E,59,F9,5D,85,02,6D,5E,2B,25,85,8D,3C,D4,ED,3E,19,DE,99,D8,EB,DB,0B,1B,E1,42,B8,8D,98,F9,85,CA,6A,B2,37,47,BB,5B,6B,E5,7C,3A,EC,98,72,CB,8E,84,98,3C,F4,ED,C6,4D,9F,F4,AD,7B,75,3D,0D,12,98,EF,7E,59,B0,D5,F3,4B,25,FD,D5,BF,E7,B2,4E,95,75,9F,49,BB,4F,AA,51,40,17,CD,DB,6A,34,97,1B,36,CB,5A,EC,A1,1C,D5,66,A4,C3,4D,81,3B,C7,10,67,59,33,9E,86,68,D1,63,36,71,26,3D,11,6A,E3,0E,62,3E,AC,F7,28,6A,44,7D,42,FA,75,EF,74,B9,70,8C,6F,0E,E4,B3,C0,28,59,43,DB,96,E9,88,DE,91,02,02,79,26,31,CD,63,C5,00,3D,02,A2,2C,6F,9B,BF,B2,1E,A3,45,8E,26,85,D9,A8,76,E5,53,7B,67,D4,27,1E,6B,D1,65,3B,A6,5F,CF,EF,BE,3D,64,5A,C8,D0,63,7B,EC,1C,0D,AF,3B,24,C6,2A,9B,46,05,90,9B,15,56,3F,91,4A,95,E1,17,7F,49,C4,C3,B9,B9,0D,C4,9B,CA,66,F3,2D,12,85,15,00,17,EE,AA,20,6B,3C,F2,DE,1D,0C,4C,A8,F9,01,FA,72,BF,D2,78,26,27,3E,A1,BE,75,48,CD,83,F6,4C,4A,AF,BA,B2,50,AA,30,C0,91,19,60,F5,54,74,8F,52,0C,F8,A9,47,F1,8C,EF,7F,4D,D1,8E,C5,90,C2,3F,01,58,AC,9E,E4,FF,99,A4,1F,B6,D8,8C,D1,40,3F,6A,78,EF,9F,E9,83,28,6E,D0,35,FE,3C,60,DB,8C,F4,2C,79,C2,EF,F0,B1,87,EF,1D,63,63,89,4F,34,07,DD,A4,F8,EC,DF,A0,79,DF,C7,78,88,5B,0D,15,F9,1E,61,60,BC,27,1A,74,45,B5,BA,78,29,8C,DD,DA,27,80,3A,57,F7,9E,8A,62,EE,13,05,C6,7D,92,FD,F1,D1,97,3D,F4,D3,80,90,01,C6,F0,1E,0D,49,13,FF,88,97,DC,7C,CA,1C,ED,09,28,E1,3E,76,B7,38,49,5D,26,9E,34,8A,30,30,C9,09,79,4A,AF,88,95,E7,47,F9,72,A8,C9,34,C2,FD,F6,5B,8E,9E,53,43,A3,1B,8E,22,B5,92,EB,B2,8F,AC,BC,86,E8,59,52,0B,9D,A5,52,E0,DC,59,B0,BF,11,1D,92,C9,30,E5,F8,7C,94,75,55,76,63,68,40,B8,F3,70,AA,33,D2,9D,AB,CD,4C,E7,B2,69,26,DD,4D,3A,2A,DE,11,BF,D1,5A,A3,EA,59,3C,EE,7D,62,2F,7F,78,AD,9A,23,45,06,D4,EC,3C,1A,6E,B3,87,76,50,F1,21,01,4A,CE,B5,A3,65,BB,B4,2E,83,F3,3E,59,3E,F5,30,0D,0A,31,65,82,A6,CF,C2,F3,3C,F6,E3,D2,85,53,5F,0F,7E,F2,DB,0D,CF,88,99,72,97,43,21,2C,D8,75,A9,B8,D5,7A,83,07,72,A8,54,04,62,2A,80,15,4C,E8,6E,22,7F,05,03,CD,47,D1,6D,D5,73,6E,FE,E0,6A,AC,8E,16,E0,F6,8C,E8,FF,61,93,0D,84,E9,12,D2,E0,16,E3,B7,B6,DD,9E,50,6D,6D,20,FB,64,CF,7F,91,95,E6,25,07,40,4E,71,F1,C0,B7,82,7D,9A,05,D8,2E,93,A0,3C,4D,41,66,89,C8,C9,C3,BA,56,D8,ED,40,CE,62,AE,EB,CA,C8,41,A8,3D,28,60,11,DC,A0,3F,48,59,FC,0B,56,72,52,3A,29,5A,18,8E,4E,9F,DF,86,C1,1F,BE,0B,9E,41,19,62,FA,39,EB,75,DD,90,31,96,50,EF,EB,35,20,9D,E3,13,26,C7,E5,D9,FD,86,F7,A8,4A,85,AE,75,41,1E,F9,7E,18,1A,5A,D7,3C,57,42,65,C7,2C,85,98,26,D7,53,D2,AB,99,14,2F,F9,B6,32,3A,37,32,6E,C4,11,AB,2E,85,AB,86,11,C0,0D,0D,D0,91,D8,27,54,29,D1,4B,FB,BB,81,45,6C,4F,5B,BD,EB,07,B0,73,F5,7D,EA,F4,52,66,EE,7B,B4,77,57,F1,8D,99,3D,2D,D3,96,70,10,BD,9B,B9,2A,E6,DB,FF,E9,2D,1C,5E,53,50,B3,5C,61,75,12,FF,0C,0B,F7,B4,08,65,42,8E,5B,32,08,CD,F7,E9,A5,BA,B1,89,CE,E0,09,E3,FA,D7,E7,68,CF,91,82,47,8B,5A,20,AA,C8,46,AA,4D,18,99,0A,FE,D6,E8,61,38,DC,0E,3C,70,C9,73,E1,37,92,34,03,F3,3B,4B,24,88,A9,A0,2D,C3,6E,00,C9,F1,FC,A4,0D,B0,E3,93,2C,BB,FB,04,2A,9D,AE,E3,6B,A7,C4,E1,20,B1,81,ED,3D,71,05,D3,ED,2F,FE,F4,DA,79,DD,F2,29,AB,5C,28,0E,20,65,8F,97,2B,DA,BA,26,8C,0E,FB,E3,A0,A9,9B,55,AB,65,57,9B,89,8B,EF,E3,98,73,57,C3,BE,60,47,F2,A1,BF,19,9F,33,75,20,76,78,05,D4,94,9D,DA,BA,CE,60,79,F5,D9,74,1E,0A,F4,D5,19,A5,C1,1D,49,B7,E9,A8,32,BE,7E,71,20,F2,A1,85,E2,59,0B,15,0B,58,5F,C3,E9,BA,C8,54,4C,79,69,77,E9,2F,38,C6,DB,53,CD,10,B6,D5,07,0B,61,8A,57,38,F0,8C,66,1B,30,34,4C,1F,48,18,04,C7,F2,4D,DD,27,90,9F,2F,C4,D7,02,E5,17,BC,4B,F8,8E,B3,27,A4,D5,62,F4,76,4C,E4,B2,F0,D9,17,8F,A2,32,34,C6,1D,47,C9,EF,B7,8E,E6,2F,3F,03,C7,5B,19,11,8A,C2,E4,84,46,C3,AD,DF,3E,04,FA,C9,DF,F4,21,17,E6,1E,80,B6,99,08,6A,60,B0,44,47,C5,E5,B4,C1,0B,D3,CD,D8,14,32,69,E9,79,2A,AE,56,45,1E,15,59,16,83,C8,02,2B,D7,9B,CF,78,38,9A,61,7A,31,E6,C9,64,CE,00,9F,FE,16,EA,42,CC,4B,E4,F2,4F,46,E5,56,89,67,6C,BB,13,2A,F6,14,EE,22,E1,94,ED,A4,0D,F0,9F,A8,5D,2F,60,67,9F,3A,53,11,3C,AC,EC,BE,B2,9C,AE,0F,84,AF,44,29,9D,BD,31,D6,87,73,4B,6A,4E,5C,B6,C5,A1,7A,E7,3D,94,5B,0E,A4,37,4D,0D,FA,15,16,68,F3,3D,4B,A0,65,A1,4D,48,45,DB,6D,DD,51,E0,E9,9F,93,BB,96,FD,89,D9,9D,5F,E6,B0,56,FF,A3,A6,C8,C0,B3,68,3F,A2,A9,07,A4,30,4E,D8,8F,6C,46,26,C1,24,1A,D7,A6,B6,49,10,B4,3F,F4,84,B2,96,6B,47,29,D5,62,40,71,96,83,87,7D,8E,9D,77,C1,0B,44,30,2F,C1,50,C0,E9,9F,8F,AC,2B,4C,5D,DB,76,95,0E,38,7A,C4,26,92,F4,B3,6C,4E,D9,48,6E,A5,BF,85,41,FF,6A,54,6F,93,91,04,08,46,81,46,D1,A2,41,85,94,DE,E0,B0,CF,E6,BE,DE,00,9D,42,38,E7,F7,13,C4,9E,CF,52,1F,1B,73,79,0C,EA,2A,1C,29,AA,13,80,B9,24,55,06,9E,19,EF,AD,B6,C3,2C,56,F1,5F,3E,EE,52,B6,40,39,0E,84,F1,63,9D,92,D0,3A,3E,3C,3D,4C,F5,1F,F5,AB,7C,7C,DE,5F,C3,3B,86,CE,44,91,65,3B,8E,3C,92,C7,21,47,3F,63,9A,70,29,9F,6C,1C,A2,9D,1E,01,32,52,0A,CB,54,0C,E8,D0,CB,AD,94,9B,24,01,4B,42,1B,E2,6D,A8,A0,5F,7D,D0,37,24,76,06,2B,AD,C3,45,D2,80,E4,0E,8A,87,48,08,B5,25,E4,32,1E,F5,06,70,9E,64,13,3D,C1,00,B3,FF,36,EB,F7,B6,AC,EB,05,13,4A,4E,A1,A5,98,D5,AB,5A,85,C6,7A,80,74,36,4F,0A,59,02,22,CB,CC,B0,94,1D,0B,7E,5A,91,68,A1,D3,EA,6D,97,1F,3F,25,62,DB,09,13,92,38,6F,4D,FA,63,FC,2B,30,D4,80,80,B8,CA,2E,32,43,FE,54,F1,B3,CB,A5,06,A0,1C,6D,FB,27,54,B9,00,2D,BE,11,D8,E2,77,89,1A,12,A4,F4,3F,2D,AA,E3,F7,52,1D,A9,3A,E9,16,4F,0F,B2,B7,D4,AD,82,6C,55,3B,03,36,9D,4A,97,D7,F5,CF,43,94,05,40,DF,0C,11,94,AC,9C,F4,A5,8E,9F,E0,D3,3B,59,8B,8A,BE,A4,C1,B7,D4,FA,BF,9E,5B,8B,67,EE,31,4B,1C,F0,56,16,A5,A3,39,DF,86,0A,74,4F,F5,8D,D2,F7,61,82,C9,8A,D1,A0,E0,BD,31,37,79,0F,81,EB,03,77,15,75,62,5D,1F,86,B0,1E,A4,51,34,14,83,1C,AD,9F,F3,42,FF,E2,67,00,CE,1A,48,45,A8,2F,B7,CA,E7,20,81,6C,28,C5,8E,32,80,C0,A9,67,61,6D,A6,92,37,35,F9,50,E7,D3,F4,AC,DD,9A,98,B7,AB,8C,F6,AD,94,8A,82,94,29,6F,8E,2E,26,2B,64,8E,32,92,0E,73,28,87,A7,47,D8,74,F2,FA,30,7D,9B,D5,40,F3,0E,C0,C7,4C,3A,63,CE,14,7D,38,68,15,DC,BD,35,F9,1F,05,F1,2E,E0,4F,4E,1E,6B,47,AB,6E,57,30,62,06,57,6B,D4,E1,5C,4B,A9,C6,F6,8B,23,EB,6B,B9,89,14,7A,0E,EF,63,13,45,66,27,A5,46,A6,18,94,56,A7,1D,52,DC,17,A4,4E,8C,EB,74,C3,10,A8,33,D6,AE,70,94,48,3F,EB,37,11,2F,BA,96,46,F6,7F,27,24,54,B8,0D,32,71,50,E5,3D,2F,11,6A,4A,5F,C6,85,20,AF,50,76,C1,7B,25,F8,54,52,54,01,CF,C2,90,9A,FB,5B,AE,CD,09,A6,25,47,22,70,A7,CD,69,B7,CE,BD,4B,E7,6A,5D,97,66,34,8F,50,59,EC,18,F4,D3,50,0C,81,E5,BF,C8,C5,93,02,21,6E,40,17,8D,13,D7,1B,FF,15,E0,6D,3E,6A,0F,F5,C3,82,68,AC,6C,21,3E,A0,EB,DB,F8,88,47,7C,65,B6,24,56,E3,E5,47,DD,C2,44,93,35,DE,C2,45,9D,CA,CB,36,DE,F6,81,94,E0,AA,9F,95,01,F7,82,FA,51,F0,8D,A9,2E,C6,F6,02,86,C8,32,0F,03,1D,FA,A5,31,12,C2,75,74,75,C9,48,BD,06,6C,9A,0F,66,27,F5,6C,96,22,98,04,1E,8D,89,6F,F3,93,04,A1,27,AE,42,B4,16,FA,AC,8C,A6,2C,4B,CB,A3,6F,86,CF,E3,90,6B,6D,0E,5A,F0,BD,AD,A0,30,C5,C3,A2,D0,E1,06,A3,F7,EE,0D,EF,4D,E8,E3,BC,BE,59,CB,AB,15,91,0F,E5,CD,1D,42,CA,30,C1,48,1F,CE,66,A5,AC,C0,4E,26,85,9C,3C,1D,41,9E,8C,6C,1F,EA,D3,4A,11,02,9F,B1,D1,1F,FD,11,C3,3A,F7,17,CC,62,8C,B8,F4,99,77,78,CB,D8,55,92,4E,E8,30,75,76,C5,8F,16,CF,03,CF,9F,21,40,EB,DD,7F,C8,42,A2,D4,AF,55,FE,E4,6B,5E,AA,F7,B9,C9,EB,96,46,6E,2D,9C,65,A2,06,8D,9D,51,8A,2F,23,BF,F6,E7,5F,D8,03,6F,EF,30,29,4D,36,72,C0,69,89,96,8E,2B,3A,D8,DA,A1,C9,54,B5,0A,34,9E,76,99,F5,E7,C7,67,90,1E,48,77,B6,0F,EB,DE,FE,5F,32,90,90,40,88,89,8A,2C,6B,36,82,0C,3F,53,D1,B1,8F,C6,37,D8,58,C9,D0,C1,C6,8B,BE,C0,20,41,DD,4C,0D,84,51,A1,59,6F,A0,DC,76,1F,47,98,9C,74,3E,D7,E5,DF,87,36,D4,FB,3D,C6,8E,2F,B1,8B,27,09,C3,B8,DB,35,F5,B4,B6,B1,51,8C,5D,75,C8,B1,E7,8D,24,5B,B3,5A,C3,2B,2D,55,E3,A0,A9,BD,F0,63,0B,36,63,A7,C1,7B,EE,E4,CB,A2,59,56,3A,7B,2B,A6,6A,E7,5E,9D,2F,1E,26,18,43,8E,76,57,17,D9,3A,D6,67,CE,04,7E,B7,96,84,CB,9F,8E,5F,8B,3E,12,38,EF,F5,00,8C,95,F1,1F,45,7C,A5,52,9B,58,DA,D6,8A,70,FF,23,B1,43,63,D9,DC,9D,75,88,BE,8F,C3,E6,F7,A7,9C,4B,4A,86,F1,00,61,0F,7D,AC,49,3B,34,6F,9D,CF,C8,19,B4,DE,CA,BF,5F,7F,A6,A6,09,D3,EB,2C,C9,7A,4A,F8,26,FE,BE,DB,74,52,DB,BC,E0,05,17,CA,2B,C6,84,5C,3C,35,EA,79,01,BA,DF,F8,DE,99,8A,7E,DE,21,54,35,79,08,64,A1,30,A9,7E,7B,51,99,51,D6,1A,61,0F,21,86,20,B3,F6,D5,4E,87,4B,93,B8,C4,54,38,16,01,EA,23,A5,42,8F,40,9A,08,D2,5C,58,94,87,CE,0E,C7,0C,FF,35,11,D3,9C,05,19,E0,AB,11,8E,1C,C1,FF,89,47,3E,55,CA,B4,AC,DD,5D,E8,A8,57,BE,13,03,B7,CC,BD,FD,00,75,91,1B,72,AC,4C,B1,74,16,7A,02,31,0E,9C,BE,3F,C1,40,99,94,7A,B1,3F,F7,B3,C1,1A,DE,49,C3,7C,75,69,BA,48,1B,0B,5B,2F,48,92,02,58,75,95,0D,60,BF,24,70,7E,EF,2C,18,E1,0E,4C,FA,24,CC,3B,95,B7,E0,A1,3C,76,BE,15,48,FC,22,A2,7E,92,E4,A3,B5,B7,16,A1,B2,69,8F,86,D1,AC,70,6A,79,EA,E2,CD,95,66,16,C3,AA,05,40,F1,1B,8D,9A,F0,0A,B0,F0,4A,57,20,B2,75,74,6A,79,34,6F,BA,BF,0B,56,B8,40,E3,5F,36,A3,F5,B9,A3,7A,E0,E9,27,4E,4D,71,7B,4E,75,D7,0B,B9,F5,CC,78,A5,55,77,E4,8E,29,5D,56,29,9E,92,23,13,49,93,AA,02,AD,23,00,84,0E,60,42,F3,B9,EE,F6,53,10,91,8B,95,5B,62,9B,4A,34,9C,A2,3E,C2,76,91,6E,DB,2D,CF,9D,98,D1,3C,0C,4A,BD,29,E9,4C,09,68,FE,11,0F,AC,42,CB,E9,87,B3,19,30,4E,E4,63,CC,4E,49,31,AE,E9,24,3D,B7,6F,2B,39,05,95,4F,94,34,6E,ED,48,F9,15,0D,3E,07,D2,1A,62,3C,10,82,FC,42,4F,73,E2,68,CA,E7,60,B0,C8,94,DB,D0,0A,EC,E5,78,A6,4F,7F,11,6F,11,20,00,54,BC,50,8A,12,E2,EC,82,6A,4A,45,FA,80,01,7B,5F,B3,89,24,B0,9B,F0,14,F6,B7,91,11,00,A3,85,18,06,45,24,32,5F,A9,A0,87,A4,6C,CD,80,97,02,D6,60,DA,0B,AD,01,3F,AD,4A,9B,E5,5C,0D,95,18,9B,7C,6E,FC,B1,F6,4B,89,64,B3,33,CF,C4,B8,CD,F7,65,01,7A,A4,E7,35,92,34,4D,C4,C8,89,D7,C3,B3,62,7E,10,38,D4,5C,62,AA,09,0B,4B,A5,3E,E4,DA,CB,98,BA,8C,7A,73,C7,C6,48,10,BD,10,8B,33,37,AC,8D,D8,C3,DB,73,B9,28,49,2F,B3,C4,D5,CE,2F,5E,7A,1E,E3,BC,01,EA,3E,CB,EF,28,33,E8,FC,C5,E4,F3,56,B9,6D,44,99,7A,31,88,44,78,79,7F,40,0F,63,5F,F3,24,EC,77,43,AF,CB,65,80,A1,98,72,ED,FA,05,52,80,AC,E3,47,5D,9C,5D,63,A9,8E,5A,62,B6,68,1E,BB,4D,01,13,8E,38,3D,DD,5B,B1,BC,27,E5,EF,A3,53,EA,F8,30,A9,A6,7B,3D,A1,A6,BA,07,F7,55,C7,F2,89,8B,1A,DF,55,2F,69,A3,25,27,22,1C,6B,E4,C5,0B,E4,5F,96,74,89,4C,86,9F,75,CF,1C,02,02,1A,C4,31,8D,D8,77,C8,CD,1B,D0,F0,3E,E4,28,BB,15,6F,93,D1,61,59,41,ED,66,1E,0B,FC,4D,5D,9A,E4,3E,6D,0C,72,6D,EF,B0,71,B4,3D,8A,72,5C,9E,75,93,8D,75,E0,40,67,3A,42,D0,BA,9C,6A,51,23,50,F6,38,A0,77,AB,A3,77,AF,FC,DC,9E,84,F9,FC,A9,4F,5A,52,9D,FC,D9,69,8A,3F,C3,A3,65,11,29,27,F2,CA,E3,52,DA,12,40,70,CA,B3,21,D3,5E,A1,58,93,D2,FE,66,6B,4F,44,BF,09,CA,78,D9,EF,04,DE,7F,5A,94,1E,F3,48,80,C6,DA,34,88,48,0A,A0,F8,CE,4C,C4,E8,1F,96,E5,0C,24,9C,34,D9,53,B4,1F,FA,EA,39,A9,C1,53,64,39,CE,85,D5,19,D4,4E,C2,03,89,DA,EB,D4,EC,20,A8,4E,03,AB,91,FF,9E,AF,FC,C9,52,71,94,55,06,45,7B,92,0A,5C,22,0B,AE,C9,89,FA,0E,D5,3B,A6,40,C7,43,3C,25,AA,FD,0A,E5,09,20,74,55,C2,27,69,5F,82,C6,62,03,8B,77,23,F9,74,5B,F0,50,FC,37,5A,81,AE,BB,A4,32,C3,2B,EB,4B,88,2D,84,67,38,33,15,99,40,68,11,89,6D,62,0A,7B,84,D4,D6,A6,D1,49,5C,AB,BB,99,3F,6F,4F,A6,5F,46,39,7F,41,43,9E,30,88,91,39,0C,AF,AD,C2,EA,75,2E,93,6B,79,BA,F7,1D,83,9F,C4,40,92,4D,C6,9B,10,4E,F2,4C,2F,06,05,CC,6B,75,D0,37,65,7E,27,3F,C3,B5,B4,27,B5,55,32,1E,E1,A8,C8,E1,3C,6E,BD,EE,36,F2,63,36,17,C0,A6,A2,93,F4,EC,9F,C4,2F,56,FC,75,BF,1A,7D,89,FD,47,73,A4,5B,0D,E5,73,5C,8A,4C,51,63,FB,7D,1D,FB,2D,47,99,E3,2B,44,72,1A,3A,DF,14,36,00,EB,B5,F7,A9,33,95,53,1F,D8,12,CB,97,8A,94,8D,01,CF,4C,B4,45,4F,1B,6F,20,AB,EA,89,6F,48,70,B2,7E,99,02,77,3B,C2,97,4C,E1,74,B9,A9,19,FD,12,E8,84,1D,B8,B1,D6,40,98,E9,50,5D,BF,72,0E,DE,3D,B3,4E,34,C9,CF,22,51,6E,73,5A,1E,93,86,83,EA,9E,0B,60,C3,BF,6D,BE,D8,C0,48,BD,14,2E,12,9E,DE,B7,B2,BD,C2,78,D0,82,28,52,E0,C7,3C,AC,F0,84,80,61,E4,12,6C,A3,F5,7F,3E,38,73,27,59,AA,AE,A7,B2,11,5D,4C,70,A4,35,70,6A,09,80,F5,1A,1D,49,4C,02,67,B8,E4,78,0E,13,BE,27,19,55,64,95,C6,E2,F4,EC,54,53,73,5C,DE,AE,C3,2C,FB,74,6B,80,5E,01,D6,FC,C3,53,DF,31,98,93,7E,F4,9F,B1,FD,69,32,C6,99,66,99,18,EE,8C,A5,E8,A4,9C,DF,47,BD,30,DF,2B,A8,62,03,FC,BF,D1,34,EC,3C,6F,CE,B6,68,9B,E3,B8,7C,38,AB,47,E0,4A,45,B7,4B,6A,AE,9C,65,7B,4C,4E,A2,94,DC,4C,D6,24,8A,22,B6,21,F4,16,0A,8C,E0,0D,89,C7,FB,48,A9,AE,E2,7A,F1,6E,67,54,1C,5F,F4,F7,6C,47,5C,EF,AF,A9,39,B2,EF,C8,D3,AB,1A,B4,A0,7B,2F,BF,39,AD,8D,87,6A,32,F4,09,30,3E,CF,A0,4C,05,BF,EF,05,EC,10,C5,03,95,8D,2D,EF,8A,23,7B,62,92,E3,AC,36,F8,C0,D2,27,10,38,00,5E,26,8E,D7,01,20,34,C4,16,9D,4F,E8,1A,76,F7,BE,26,1F,FD,16,AF,C6,D5,49,06,34,D6,34,0A,3A,B9,94,AB,18,B1,ED,61,10,26,A5,E2,93,84,B7,DB,C2,9E,13,54,02,63,DC,4D,33,64,71,48,FD,48,79,8D,35,88,BB,2E,A1,F3,3D,92,B5,5F,1D,32,B9,B5,07,FB,CB,E6,14,BB,B6,06,7E,01,21,9D,AC,E8,F5,71,A3,45,4B,7E,75,98,C4,7E,13,9A,A1,62,2F,A8,C2,1D,3D,EE,A0,82,EE,73,61,BD,EC,7C,40,B6,AE,46,FD,2B,14,06,C7,B3,B1,28,EE,B9,84,54,74,F7,08,FB,FB,A6,E1,44,41,F9,F4,07,5B,59,43,E4,34,D4,FD,6E,28,8C,ED,F0,23,80,8A,E2,5B,B1,33,92,2C,C8,4A,E6,14,8D,60,8F,7F,B5,E0,E8,FE,75,97,EE,BF,AF,7F,FE,20,9F,A2,E0,80,68,2E,62,59,32,AC,DB,B1,2E,0B,71,4C,B5,A7,4A,9A,32,45,57,70,67,E0,BC,21,0C,4E,08,FC,A7,E5,F3,46,85,7D,95,06,94,81,F4,B3,61,0F,73,FD,C7,71,AD,EC,BF,69,8F,F7,D5,67,34,D1,98,AE,07,7A,48,6F,17,5D,90,EF,BF,F9,7D,4D,16,8B,E2,A4,D8,0F,34,67,34,0B,76,0D,D3,3D,D6,94,E8,2B,B1,89,51,3D,95,64,B7,1B,03,48,FA,DC,1B,D6,6E,C8,94,54,CD,8E,FF,85,6D,71,8A,3E,6B,89,16,0F,99,5E,B0,C7,0B,94,A7,3C,04,29,07,98,A1,59,C9,E5,9A,BC,8C,4F,BB,EC,85,CF,52,F1,F1,07,5A,FB,FC,85,12,AE,BD,F1,6F,38,FA,43,2C,93,68,28,7A,73,C3,D3,95,95,4D,41,9C,B4,94,BA,28,B4,A1,73,1C,25,4A,35,45,15,70,5F,25,5A,97,EF,F4,BD,61,B3,46,BC,24,C5,28,19,5F,F2,1E,4D,C6,C9,4A,7E,A6,B2,CC,C8,AD,C7,07,EF,7E,07,33,84,F8,82,2A,59,08,F6,85,93,68,EE,10,D2,43,18,DF,31,66,82,88,60,6A,5E,C0,8A,86,78,C2,F2,F5,C6,50,91,D1,5C,8E,F8,36,94,83,EA,1C,81,61,18,39,F8,9C,31,91,5E,DC,F3,52,CD,65,48,F5,FB,DC,53,F9,7B,14,D9,B9,16,22,41,15,99,3A,C9,B0,F7,50,3A,10,91,84,07,E2,B3,24,76,54,4D,E1,55,48,23,0C,46,40,81,A6,A9,51,AD,5F,D9,F5,76,1B,8A,12,A8,29,BD,E4,D4,A7,8B,AA,91,D0,DC,0D,CB,E7,D9,52,47,87,3F,EB,D4,7C,00,44,AB,48,B0,89,5B,4A,7D,55,04,5B,20,AF,1E,2C,98,14,C4,CB,D9,AF,C0,81,51,43,18,0D,2A,C9,85,8A,F5,29,8C,41,7A,85,E6,87,22,34,CD,79,F3,E0,4A,EC,3E,01,FC,58,DD,15,13,4B,2E,DD,35,9D,75,53,D9,D4,47,87,C0,A0,4A,C3,24,1E,05,AA,20,1F,1E,75,F8,59,C6,CD,9D,3A,67,88,60,CD,53,60,39,4E,CF,D1,43,A8,87,60,E3,3C,32,F1,A1,E2,C9,2B,1D,34,8E,5C,C2,8D,84,2A,6D,A7,EC,DF,6A,A5,14,A5,88,D0,7B,74,35,2E,17,F3,42,6E,41,E6,E9,73,1F,51,F9,6F,00,E9,67,9F,73,88,2B,41,94,7F,C9,8C,1E,3B,04,4D,DA,01,57,3A,1D,8C,85,9E,77,D9,6F,86,17,C7,20,3D,0B,89,BD,F4,36,44,DC,93,02,00,F6,6D,1A,61,E0,21,A3,84,12,6F,29,EA,4F,0B,88,4A,A2,D1,52,C8,CA,A8,04,02,82,0D,D8,E2,73,37,95,99,76,38,C0,66,86,F2,38,7C,39,A4,8D,7D,59,51,8C,4F,14,97,4A,88,75,85,11,C5,49,D6,D6,1D,47,57,89,BC,D2,7E,A2,E0,7C,39,34,E5,FD,DB,48,62,17,A0,3B,56,3F,CC,80,DE,3E,DB,E0,A7,CE,DB,49,4B,D0,C9,FE,D2,D3,EA,26,E1,DB,10,01,6D,8E,8E,63,A9,34,24,8C,4F,9B,90,FE,18,B4,61,B5,CA,47,AC,44,58,57,18,9F,A2,AE,F4,C2,61,7F,AD,92,FC,2F,F5,9B,5A,68,72,47,4B,C9,2F,8C,0F,E0,22,41,BB,1F,BB,18,5E,C2,13,10,15,B9,FB,D8,58,90,FB,A0,44,AC,80,81,0B,B4,CF,DB,FC,26,57,D2,22,ED,91,51,9D,EA,0A,7F,7A,00,D7,29,1D,D4,58,3E,D4,61,8F,F6,68,E5,99,0A,3E,D9,7B,34,36,72,0B,B7,16,8C,54,63,B9,F3,CB,C6,1C,3D,7A,D7,7C,E2,82,32,B9,E3,0A,52,C8,57,C2,5A,45,E9,2E,F2,26,AE,DA,64,04,47,85,B7,18,86,1A,C6,4F,A1,9C,B8,65,A3,09,63,F3,7E,FE,0F,D4,4A,11,60,03,09,22,A7,94,DE,13,C4,8A,49,88,AC,26,79,FA,7B,35,4B,B6,4E,39,B3,49,57,54,35,62,27,D3,25,D3,8C,71,43,1C,32,F4,5E,32,6E,6A,7B,71,8D,7C,29,8D,72,97,BB,D0,32,9A,E7,47,08,BD,68,FD,05,91,75,5D,46,C0,FC,43,73,C6,B4,75,46,F1,72,08,42,8F,FA,B7,84,D7,92,02,FE,79,C2,C4,14,AF,71,95,E1,1B,F9,5E,C4,8F,B1,D3,F0,7A,CD,04,98,79,4B,9F,AC,24,3E,50,D4,03,2B,BF,32,09,E5,43,9F,5B,EB,00,B2,07,95,FB,C5,22,4C,54,7A,8A,3A,50,35,00,19,0C,87,B6,BF,04,E9,E3,1A,B1,ED,0C,AD,83,66,12,C2,5F,A0,65,B8,F7,F0,3A,E0,9B,0E,F0,70,27,61,04,83,C0,8F,FE,76,1D,2B,80,19,0F,7A,A8,F8,7D,6D,4F,A7,90,00,4C,48,59,39,35,B0,AE,E2,28,8E,14,A0,A5,61,D4,D7,23,EF,BF,50,C8,EB,90,8B,6F,A0,08,79,73,6F,49,FD,D9,87,2A,EE,BF,EE,70,90,7F,80,7E,6C,33,CA,7D,1C,3E,63,70,E6,E0,5B,2F,5B,F1,20,E2,A4,CF,54,00,34,23,9F,B5,C4,F4,9B,42,86,AB,A1,DA,64,2F,EF,11,C6,1D,C6,C4,40,40,8C,45,6C,55,6D,E5,15,CA,97,83,C2,9F,27,ED,10,27,3D,97,3A,BC,E8,09,ED,47,5D,2C,8C,4F,28,A5,4D,3B,1E,A9,4B,6F,A3,77,74,2A,4D,65,D8,1B,79,EB,A0,2E,34,D1,75,45,C8,94,67,D6,F5,6A,C8,92,74,26,63,1B,7A,72,3F,69,C1,AD,CA,4B,F9,11,39,21,49,C5,15,40,B5,D2,5B,20,BE,1A,58,BE,A0,B8,6D,47,D1,8A,81,D6,D5,3F,15,9C,34,18,3C,8B,83,CD,C2,17,9B,2C,A0,AD,50,F4,1F,87,82,2C,BF,37,68,BE,5B,2D,C4,86,9B,72,34,95,58,15,C5,7A,AF,B3,92,9C,F4,A7,A5,F4,7C,6C,C8,43,33,4E,9B,76,CA,89,A1,90,60,B1,65,74,98,02,24,28,25,1F,71,17,8B,58,2A,45,0C,4B,48,04,CA,76,76,32,B0,9F,E3,65,0C,15,58,7F,9B,EA,4C,0D,F6,52,FA,7D,7F,FC,75,43,AB,91,FA,A1,BE,17,BE,1B,5E,15,EA,5E,07,8B,FB,E7,52,8E,B8,64,6C,4B,44,92,79,6A,AB,99,A2,DD,83,75,FA,A4,40,8E,F6,35,37,E4,A0,1B,DE,1C,56,5F,E9,22,42,60,5E,DD,7C,44,D3,C1,DF,79,F0,4C,D3,D0,C3,2D,E0,40,2F,B9,03,89,39,DB,FA,25,33,4A,64,EB,FB,6A,76,75,AF,3B,AD,EB,E9,41,B3,27,48,63,3F,57,8A,B0,37,AF,E7,FF,82,7F,D6,9B,FE,B5,50,90,DF,3D,44,62,D9,AB,3E,E7,2B,83,45,1A,E1,08,FE,93,17,39,49,26,CD,63,ED,F1,40,9B,9A,C4,4D,0D,EA,4A,E5,0A,8A,0F,86,8A,E0,A7,DC,99,99,0A,C0,EF,C8,39,22,D3,0D,9F,7F,50,5C,3D,40,DD,39,F7,50,45,BB,2F,A9,42,0A,74,D7,EF,79,34,79,93,46,A9,ED,D9,01,B1,45,B5,67,8A,36,AC,7D,96,F0,A9,E3,E5,E0,28,13,B2,7D,7D,0E,CA,81,8E,D3,E8,66,F2,2A,68,6F,DF,21,CA,48,81,A0,EB,DB,3E,D1,A1,73,C7,CF,79,3C,3A,F5,5D,01,EA,6C,C3,E3,19,77,0D,86,E1,B4,B8,4C,F5,1B,47,44,37,E5,71,DB,82,B0,6B,C4,26,1D,EE,E9,5C,13,56,8D,50,FF,11,B5,61,67,C2,35,AC,50,56,2F,2D,E8,92,97,BC,B0,9D,A8,CB,43,2D,0E,65,9C,F5,FF,78,B4,68,1D,B7,13,AE,F5,F6,B2,7E,64,BE,A5,82,AE,90,14,4B,98,57,77,0E,25,E6,A3,58,1E,A7,EC,85,4D,87,79,7A,D1,FB,B6,10,FC,8E,23,62,28,94,07,2A,AD,A7,5E,0F,EC,F0,3D,35,65,D5,C1,EA,6E,C4,1B,86,C5,DF,A7,55,EB,7B,E7,D8,CD,F1,9E,05,6D,48,86,D6,8E,D2,58,94,CB,CE,E7,CF,13,EB,50,36,99,75,0E,68,85,49,27,40,1A,71,36,4D,A0,56,A0,6E,2B,61,3C,B2,DD,E7,51,4B,F5,3F,0F,03,B2,40,C7,A1,B4,8F,A2,69,C0,20,37,18,36,F8,3F,DA,EF,4A,66,CD,0F,8E,B0,CC,6B,CF,23,B5,3B,A8,AA,9D,B6,03,10,CC,F2,16,CE,C8,8C,3A,7B,40,FC,26,E5,A7,AE,D4,BE,66,1F,B9,7B,23,86,C1,A8,CD,A0,BD,B3,FB,E1,9C,7F,BF,BA,71,EB,8B,09,D6,2D,41,62,DD,BA,E8,99,37,A3,38,54,B2,1D,2D,47,5A,DA,FB,80,E0,E8,87,19,36,DE,58,77,F8,05,28,62,44,42,1D,0C,03,79,2C,5E,B3,E2,F9,0D,96,C8,0B,00,40,9C,0C,FE,DB,D6,BD,82,58,E8,3B,49,B4,0D,89,B3,AA,20,21,64,8E,72,B8,56,0E,75,CD,6E,DA,A1,3B,2C,30,6F,1C,BF,F5,41,A7,67,ED,B3,5C,65,9C,01,48,B1,A9,7E,12,9A,5A,DD,84,B1,79,5F,82,4A,29,DB,E7,0E,4C,26,3C,BF,EB,4A,C5,F9,BB,C2,F6,EC,30,C5,B2,46,5E,D3,FB,44,EF,A9,52,9F,E5,28,43,9C,F7,90,A1,E1,61,DE,C7,D8,39,08,59,68,90,FE,FC,C6,D0,D2,18,5A,C6,3D,25,5D,65,6D,5F,11,14,C9,47,96,84,A4,F1,41,86,44,26,CC,A2,E7,33,92,0D,3A,DC,42,31,12,84,DD,65,74,67,DD,96,34,F0,1F,CD,81,5C,A4,43,C2,23,9E,1E,57,2F,B2,DC,71,55,D6,A0,4E,4F,03,3E,F3,13,B9,FE,24,A7,D9,C9,AA,61,E4,7D,96,E7,D4,3F,04,93,BC,30,D7,E9,E1,C4,46,08,B7,C3,1A,69,24,83,74,14,7A,41,EB,D6,CA,95,56,F9,6C,E3,A5,CC,DD,84,E0,6C,88,4E,A8,91,9E,21,62,9A,39,D9,B2,AE,42,FF,F9,B1,82,E0,7A,E6,74,2C,D9,6E,5E,2C,5A,D6,8A,E6,6B,54,3E,43,CD,0E,07,88,A0,FA,AC,5C,87,86,8F,3E,3C,A8,2F,61,50,02,93,48,67,35,0F,CA,CC,89,15,1F,1D,C1,98,CE,C5,3A,D3,E2,E3,82,BF,F7,51,FC,8E,8A,73,9B,46,9B,13,D6,00,60,BA,80,59,3E,DA,CF,DF,DA,4D,46,77,4F,EC,9E,6C,34,33,3C,8E,A8,7D,AD,57,F6,19,FB,DA,0C,13,6C,DB,69,C4,35,59,42,CB,AD,7B,37,AA,7B,EC,08,90,EC,4B,B5,4F,2A,F2,26,F0,5E,25,10,18,AA,44,89,E8,0C,08,36,BF,92,B0,7E,85,80,29,7A,56,D3,F1,93,7F,65,08,93,16,51,C2,74,A4,CD,D0,30,DB,3B,15,DF,43,F9,8C,6F,6E,5F,39,42,B7,33,C1,E9,ED,2F,E1,46,32,E0,56,40,10,26,C9,B3,D2,30,55,A9,35,4C,E6,AD,8C,D9,89,91,D0,64,1C,C1,0F,C6,DC,34,26,85,14,4F,E5,3A,39,F1,EF,85,4D,F8,6F,D0,C3,BF,46,60,6B,E1,CB,50,99,D0,67,97,3D,6C,F8,07,46,22,A6,80,59,9E,E2,15,09,17,15,83,10,9B,62,0A,FC,2A,2F,CD,65,EB,5B,B5,32,BE,CB,AF,33,A4,F9,C3,4F,A7,08,81,38,3F,13,5A,F8,93,73,DF,CE,3E,B1,C0,CF,51,32,14,BF,86,A4,55,1B,02,6B,71,4C,96,CD,03,A9,4A,82,DA,3B,C7,82,1A,BA,35,A5,51,B6,05,53,87,5E,FB,32,37,54,73,6B,93,EC,77,F1,D0,1E,74,02,5A,9A,09,3E,44,8D,80,00,F0,7D,9C,AB,00,1F,3F,BD,9B,46,7A,43,4C,DF,F8,1D,FC,B1,4A,25,BF,A4,68,0B,6F,30,08,53,3D,5A,A5,21,EA,00,AC,37,97,3E,7F,4A,BD,21,0C,B2,68,F3,96,50,E4,22,B3,6E,E7,12,F8,59,93,90,FA,6E,46,26,DE,55,82,63,E8,6D,06,1C,13,D7,05,11,C3,CD,24,96,6E,63,78,27,4D,4C,95,A2,EE,AF,5A,3E,6F,2B,A3,01,A4,21,70,68,20,6F,42,A2,81,E4,91,48,42,6D,0C,C9,2B,75,56,3C,5C,8E,B2,7B,AD,D2,71,EC,D0,3E,75,85,5E,ED,45,BA,B6,19,4D,D9,4E,4A,E7,2D,AC,31,5C,09,DF,BC,FF,59,D2,F8,B7,C1,E2,5A,1A,E5,CC,FF,D9,3D,93,A4,44,88,DA,EE,1C,FD,08,79,E7,E2,E0,EC,76,24,CA,3E,78,C6,A1,AB,79,51,4F,87,42,D7,60,0C,9C,D1,23,44,0B,A7,62,65,21,DE,EF,B9,ED,87,43,BD,4B,F7,85,C8,1F,AB,B5,3A,56,D8,D4,5A,0D,E5,4C,A5,58,2C,AE,BB,26,42,CB,64,31,F9,F7,36,A1,86,A1,93,6B,C5,AE,73,EC,42,0B,3A,04,EC,9C,5D,42,3B,46,46,8D,2D,F1,82,4B,B8,0D,E4,69,8B,ED,50,AF,98,F5,33,93,AA,6F,81,38,3E,5C,18,FC,72,A2,3A,76,8C,92,3C,C9,8C,50,39,79,6C,98,C4,AB,FD,1E,3F,D5,08,E8,1D,B1,2B,A7,52,73,B8,EB,47,13,DF,CA,76,A8,8F,BA,38,7F,73,E1,0F,E3,68,0F,97,AC,9F,3A,CE,D9,9B,52,D9,3F,21,54,2D,39,EA,94,B8,98,EC,A6,F5,58,A4,15,98,E1,C5,86,E7,9C,4D,CD,AD,F9,D5,DC,7F,0A,7F,34,C7,36,E8,D4,E3,9F,ED,70,D2,58,2A,00,64,4A,71,6D,E8,3D,92,28,55,5A,9F,2F,E5,D1,5D,C3,BC,31,1E,3A,D8,06,B1,25,88,EA,FF,B4,9C,3F,51,6A,F2,17,B1,C1,80,1F,B6,F9,3C,3A,5B,BB,EE,39,31,94,F4,EC,36,56,28,CD,49,1D,99,A6,8C,E4,9C,70,07,20,10,DF,88,95,31,6E,31,46,FA,EB,A2,68,27,E2,AD,46,9B,D4,86,98,04,8D,54,28,77,ED,AC,B2,BA,0C,FF,01,DE,9A,B6,7B,A1,AB,F2,21,6F,C4,F1,3F,11,08,75,8D,5C,72,6D,3D,4A,52,8B,D3,CA,7A,79,EC,E1,CC,65,E7,B5,AC,50,14,E7,7F,D0,C5,03,94,F9,8B,96,5C,AD,62,E1,29,0B,A5,DA,98,4F,18,0A,72,74,5E,7A,99,D4,68,77,76,64,8A,C7,98,9B,F1,85,BB,65,F3,86,20,84,17,45,13,5A,87,30,4D,A2,CA,E6,20,C2,91,01,44,36,64,01,12,1F,28,B8,97,CF,49,F4,3A,8B,9E,4D,AD,94,66,13,A3,D5,76,DD,1F,D6,D4,31,8C,33,75,2A,C1,10,56,E8,0A,E8,95,22,58,5B,A0,E3,00,D3,1F,25,C0,A9,38,2B,CC,8F,08,84,AD,0C,16,2B,7E,21,CC,F0,E9,4C,37,0A,FE,C2,17,CD,D3,AA,70,ED,9F,16,B1,37,63,BA,B5,B6,6F,D5,3F,0B,F5,F4,EB,4E,2D,25,B2,F9,4A,ED,3A,20,80,F2,80,FD,FB,18,05,93,DE,26,77,DC,30,83,A8,D6,48,A2,46,2F,ED,79,55,79,D5,8B,81,C6,23,A7,75,BD,BA,2B,80,BB,12,8B,40,C8,58,CF,8E,32,43,58,AA,90,6A,59,61,1B,4F,A7,7C,7C,AC,64,6F,DC,3A,F1,48,85,F7,4A,AE,44,1B,7C,63,25,AB,2F,0E,73,4C,59,B9,CF,9B,23,03,40,B1,0B,E5,77,64,C3,A4,9E,11,3F,3A,6F,36,84,91,40,1D,51,BC,76,1D,BB,09,9A,96,5D,34,BB,45,DD,5E,E2,5A,70,62,E8,2C,CF,E3,C9,41,7A,64,D7,9D,7D,6C,03,DB,62,54,0B,DE,72,9C,15,6B,BC,48,49,BA,09,C5,A1,C6,42,6E,17,DF,38,BE,B8,39,95,85,E3,4D,34,A3,BD,18,F7,43,D5,0C,10,39,D0,58,E6,F8,FA,99,F6,E2,20,7F,CD,6F,3E,56,43,D1,BF,74,A0,60,23,E7,C7,D0,57,EC,B1,9E,87,54,66,A9,C6,E8,E4,EE,53,FA,23,18,51,CD,13,A9,02,3E,37,CD,D3,3F,65,8A,9B,C6,F2,F6,F3,6F,A6,19,CC,A7,36,04,A3,39,41,0B,22,93,9D,09,BB,01,27,9A,9B,02,5C,C4,F8,46,17,4F,34,54,E1,B7,30,2E,B9,46,21,F2,B3,BD,41,2A,04,E8,A5,03,DA,27,97,DB,1E,DC,B5,B7,0C,31,B6,AE,F1,82,82,C2,F5,6E,15,9B,8B,8F,B9,82,FE,85,80,19,5F,4A,C2,00,A1,96,16,A7,C8,43,8D,6B,CD,7E,B2,D5,D1,94,09,A3,44,FB,94,80,7B,F7,3F,9B,BB,69,61,21,DD,B3,40,3D,DE,08,08,80,0C,5E,85,CB,7B,46,18,1D,78,1A,36,45,72,39,A6,A8,62,BE,36,F9,1D,25,88,1D,0A,C9,4C,C2,E4,6C,F3,FC,55,B6,08,35,34,B0,C2,BA,BB,A3,FE,B0,0E,E5,81,61,49,9E,71,4A,CB,B9,FB,0C,C8,CB,DC,BA,F8,05,66,19,B3,60,31,CB,7B,2C,7D,64,C1,12,A4,0D,BC,7D,DC,E5,8F,9A,2B,9F,8D,96,E0,F4,26,DF,21,B6,7C,79,FD,BD,A5,85,50,69,A2,CE,82,4C,B1,70,D9,6E,4C,4F,57,B1,E3,29,3F,91,AE,48,49,72,64,E6,11,97,EE,C2,FA,70,FE,8F,FE,C8,04,0B,D2,77,A5,14,2E,68,B2,EC,15,7D,37,30,00,0D,73,44,AD,72,5B,89,50,35,C0,CB,71,CC,6A,00,DC,D0,7A,16,27,87,8E,3C,DA,FC,F7,28,BB,DE,FD,BA,17,D8,1D,AB,C6,28,3A,D7,7F,11,65,FE,F7,37,C2,F3,DD,40,0F,DB,FD,18,FD,7B,7C,3A,90,8B,3A,F5,26,71,DA,2A,1A,75,1D,02,33,86,9C,E0,21,EB,80,D0,AB,61,7E,6D,4A,EE,71,25,4F,6C,DC,11,AA,3E,C5,8B,77,92,06,BE,FE,CB,13,98,D3,05,B6,BC,72,8D,7D,53,59,E3,0A,2A,1A,46,AF,3F,46,45,A5,57,5D,29,8A,98,6E,0F,62,C6,05,71,C9,41,33,42,DB,5B,BC,95,75,0F,9E,9B,51,B0,39,71,D0,68,15,95,2F,74,3B,23,5F,DD,C5,84,77,59,6C,26,CE,B0,F0,3B,D9,4C,11,E5,51,7F,B9,22,20,17,18,13,51,77,5C,78,DF,7B,72,DE,16,C5,40,7B,44,50,B0,49,CA,2F,82,60,6C,52,63,25,6D,F5,65,9D,A3,C0,BF,70,D1,41,F2,77,0F,EC,31,C3,4C,D9,2C,E8,0B,91,C4,56,8F,A3,1D,F4,F3,05,45,8C,7A,7F,D0,0C,CE,BE,7F,FE,CB,18,D3,16,4B,C9,35,CB,B2,18,47,48,11,10,9F,A6,79,BF,2A,6E,AE,83,7E,91,C8,DF,5D,76,63,58,05,09,B7,9A,B4,15,86,88,22,02,58,B3,58,81,C9,17,AE,0E,36,75,7E,DA,93,45,DE,D0,0A,D0,18,A0,57,77,6F,F2,2F,97,B1,CF,CB,28,FF,13,E3,EC,70,FB,CC,B1,D2,A7,EE,D5,CF,25,D8,0F,49,F9,09,96,3F,78,11,9F,13,C1,AD,A7,D8,E3,3A,78,B4,D7,66,D9,25,7A,6E,20,D0,32,2C,23,0D,7F,A9,C2,32,00,A4,DA,DD,23,61,1D,8C,5A,7B,39,35,3A,46,93,2E,29,D1,E7,6D,E2,07,A7,23,5C,2D,07,49,BA,7E,8E,87,BE,A4,DC,DB,63,09,26,AE,1B,C7,D5,E7,9C,F9,32,87,3B,4A,F6,34,0C,BC,C1,0F,2E,25,CB,5A,36,2A,B6,5E,58,67,4A,B5,F5,B7,1D,85,00,82,8D,1F,66,C1,DE,51,1B,66,84,B2,14,8F,17,21,20,90,83,4F,61,78,6B,40,83,EE,BD,40,2E,3A,79,9C,70,AC,C6,28,9C,5A,D7,B6,90,53,CE,C2,07,0F,7E,97,1C,4C,C0,63,4B,20,78,D7,47,D8,A1,9F,7F,7E,4D,62,C7,38,75,7D,45,50,84,3C,3E,01,9E,1B,4C,0F,3D,AB,35,E8,85,BC,80,05,C8,C6,38,6D,12,24,95,53,6E,F6,38,E6,4F,34,29,25,FE,61,63,AE,84,B1,EA,8A,61,D3,32,B9,6C,16,1B,0E,D3,FB,C4,B0,C5,D5,39,BB,23,3B,2F,CF,F6,15,0F,E4,D6,BE,69,0F,92,1D,A8,F2,FF,53,E3,AC,10,24,07,8C,CC,CD,A0,71,97,18,E0,A8,B9,28,AD,07,28,B4,06,B7,C1,CF,4C,CA,77,25,89,CD,7B,07,14,EA,ED,F7,47,0E,DF,D4,B8,85,46,FA,40,1A,C7,66,92,CD,58,86,06,A3,45,D8,94,21,10,89,2C,D6,82,E3,76,7A,C1,9B,5F,06,BB,E5,5B,78,B4,E4,89,78,7A,47,64,4D,45,FB,16,E1,75,CA,F1,52,DA,52,C5,01,EC,FE,CF,4A,4A,6B,0B,D3,D0,7E,10,D6,A5,0C,4D,FC,3D,05,05,85,F0,D2,10,2B,0B,4C,0D,21,39,25,8E,8D,26,DB,8E,07,FF,F9,FA,61,B9,89,99,27,A1,76,65,2F,37,B4,08,42,C7,A1,DA,BA,D6,8D,89,FF,00,5A,AC,48,9C,BA,AC,3C,7F,FD,73,24,90,6E,9E,EF,08,DF,71,C6,54,1A,9D,CA,2C,C5,54,F2,1B,A2,C7,F4,73,C7,BD,DD,3F,E3,74,9C,80,38,C8,E5,2B,1D,91,68,99,BC,4D,C8,2F,EE,1E,5F,39,B5,85,4D,4F,05,ED,03,EF,52,A3,10,1F,79,BC,90,C3,0D,F2,32,B1,6D,C5,71,40,72,5F,B3,6A,BA,A7,54,11,A7,10,07,D3,F1,F8,40,74,0B,2C,45,6F,25,7C,B3,8F,44,F6,AB,92,4F,4C,52,9F,FE,65,5F,B0,55,27,6B,6B,27,15,50,A8,B1,D4,37,4C,90,18,AA,7D,4B,BD,7A,12,2A,59,C6,51,6B,C2,93,48,61,55,24,A5,15,A9,DB,8B,9B,B0,15,7A,9B,49,BA,53,FC,CC,48,95,BE,74,0B,47,3B,F0,FA,CD,BB,EA,B5,AE,E6,87,3B,61,68,B8,C9,26,13,41,5D,F0,75,4E,B6,EE,C0,E2,AD,8C,0E,7B,64,9F,EE,66,B5,57,A3,9E,46,62,F9,B6,E2,E2,4E,A2,E0,4E,CD,48,5C,B7,4D,21,A7,7F,C5,5E,11,FE,72,44,C9,33,D8,83,99,4A,1D,EE,A2,E8,5E,2A,D6,F7,BE,E2,7A,37,B5,3B,D2,5A,15,B8,AF,B2,A8,EB,60,5A,4D,8D,04,F1,9F,F2,A3,E3,97,D6,31,E7,D6,8D,73,2F,0B,17,66,33,2D,D6,57,20,26,46,81,D7,A7,39,B2,DC,2F,4C,48,AE,6A,02,64,AA,CC,84,02,47,E6,2A,58,AB,37,54,39,09,1B,85,82,C2,39,98,04,71,AD,D6,F5,F2,B3,20,A5,DB,01,F3,F2,1B,41,00,1B,33,EE,1C,43,9D,52,81,E5,ED,27,F2,CE,7A,87,47,D5,F3,DA,D3,1C,0F,87,11,48,F7,0F,54,50,1F,E3,97,E5,AD,7D,92,FC,6B,C2,BA,35,3B,3E,CE,3C,18,C1,EF,52,AE,75,FD,94,FB,08,1B,29,CC,FB,D3,02,A3,12,7C,0F,FA,02,E4,B3,9F,5E,99,2F,F8,23,C8,FC,DE,61,7F,AB,90,35,C6,2A,D4,B6,D4,39,E0,AD,7A,6C,AD,F6,7A,5E,BB,8E,FC,34,75,54,6D,58,9F,B5,37,C3,DA,D6,D7,E1,B1,8A,D1,63,E2,04,0F,CD,01,5C,AB,8F,AD,40,91,77,CD,18,9B,E2,87,9E,57,4C,5B,1A,AD,F2,56,23,39,AA,C4,9C,FC,28,5C,65,F6,1F,93,A3,7F,24,5F,AD,53,F4,3F,F0,A5,4B,DC,EF,68,53,4E,1C,B9,06,05,DD,D3,2C,63,97,23,B1,8E,A6,11,AE,9B,3D,F9,E5,E2,06,CB,BD,DB,2E,75,3F,45,02,B6,04,BA,7A,1A,76,EC,E2,58,68,00,79,8C,5D,80,F3,8F,83,7B,A5,7E,5D,7C,F2,F3,8A,38,4C,EF,2E,64,CB,23,5A,5C,1E,07,27,1E,A6,71,EE,D8,EB,8B,05,2F,A4,A5,BC,22,00,47,93,B2,A3,09,A8,02,24,97,29,1D,AB,92,D0,03,DB,88,22,4B,34,97,83,5C,0B,52,DC,92,A5,81,8D,77,8A,62,FC,63,54,31,99,D2,1C,DE,51,68,54,F2,9A,1D,E5,F7,B4,B2,C0,34,02,81,A2,E7,4F,BC,D7,AD,91,48,19,44,F9,D7,EA,96,24,E2,E2,CC,27,B2,B6,28,B8,15,1C,5A,F0,80,6E,FF,75,72,A2,F0,6D,9D,9C,52,B2,01,58,91,C6,E4,26,42,F2,A0,0B,79,78,88,2B,6F,B2,49,C7,71,18,B8,65,69,F8,CE,DA,77,F6,CD,69,8F,88,09,13,5A,F2,50,19,80,3A,C8,A6,48,78,3E,F1,8F,49,03,0A,A0,0F,46,D7,CC,69,88,7D,33,57,51,3B,5B,41,6B,DF,4D,C7,77,39,6B,AB,F9,DB,9B,3A,E0,35,D1,BC,64,9A,73,7B,B5,85,3E,2F,EF,FC,3D,88,2C,43,E3,49,E3,06,CB,12,8C,AB,E4,FE,3D,31,44,89,DF,EB,34,4A,06,0B,EC,71,48,CF,09,D3,9B,DF,11,A4,51,A2,37,03,D1,DE,7E,E8,F7,95,8D,B4,CC,53,2B,C6,FF,41,CE,27,ED,11,A4,E8,70,91,13,A2,20,B5,74,50,62,97,0B,1F,02,20,B8,F6,E6,93,E2,28,CF,C0,A9,7D,B1,E9,E1,24,6B,E1,FA,2C,F5,9A,62,92,FF,C3,39,BE,00,6A,3E,6B,24,49,AD,85,23,2E,6C,74,D0,47,84,C0,87,BA,B5,17,38,98,79,A1,BD,C8,E7,BF,9D,9D,2F,51,D5,9E,AB,44,1C,95,05,36,A7,7D,26,0C,2F,3E,D9,C0,F5,CD,60,02,DA,64,89,0F,62,9F,75,C0,B8,69,5A,9F,C5,CC,7C,88,71,BB,23,F9,99,FB,60,F7,2D,61,1F,A3,16,FC,90,36,3B,66,60,06,4C,EE,F7,37,F3,47,2E,5A,F2,7C,BE,A5,2A,4E,ED,B1,CC,2E,03,41,5E,D0,EA,ED,D5,AA,46,39,0F,2D,A4,CF,D1,A5,02,3A,DF,41,68,D8,C2,6C,35,4A,61,26,E0,C3,53,61,4C,A4,EE,D9,04,5B,A6,AE,EB,1B,A9,12,3D,1B,40,96,A0,3A,77,22,12,71,10,69,C8,66,89,25,71,17,99,03,5C,5D,A9,B3,97,50,16,62,3F,44,F7,04,55,2F,11,DD,FC,88,A2,74,36,22,DF,4A,E9,36,F4,09,00,B2,D8,21,B9,09,5B,6A,14,3C,44,D9,E4,99,3A,2B,58,C8,0E,3C,8F,63,57,FF,A7,12,25,33,30,C1,AA,A9,6C,52,DC,DE,30,18,E9,09,77,38,0F,FD,4D,D6,86,6E,E7,C3,AC,0F,B1,A9,23,D5,93,D3,FB,AE,2E,82,FA,E1,68,23,6A,50,B1,4E,D1,7B,CC,63,73,CA,E0,F6,26,F3,16,DA,4A,43,36,55,28,9D,FE,B6,C8,C4,8C,96,2E,15,7F,F7,6C,52,FD,ED,33,CD,46,0C,26,15,FE,93,FA,04,04,51,B7,60,B6,A2,13,D5,94,35,43,48,FF,BD,F7,00,93,2C,2B,34,AC,14,A1,CC,E1,23,B6,6A,A8,50,ED,04,50,38,72,06,F7,FC,7B,60,C3,E8,EB,5C,A4,54,F6,8D,3B,CB,45,B7,B0,24,89,DE,B8,D7,8A,E9,53,CA,B3,CB,D9,56,50,C8,89,AF,5F,CB,2A,6B,83,21,55,D3,C6,AB,44,F4,33,A6,BC,1C,C3,9F,78,A3,F6,9B,F5,48,C5,A4,D9,49,0A,7F,4E,E8,DB,A0,2D,7B,96,26,69,55,7A,C1,38,13,94,53,EB,14,CB,15,A9,64,13,FD,AA,70,D4,9E,EE,01,C4,7D,C3,B8,60,CB,41,7A,34,7B,8F,8C,C7,62,72,A5,F2,CC,F4,09,6C,71,4B,29,99,D2,64,64,31,3B,F0,A6,0A,6A,71,0D,36,5A,B4,38,B6,BE,72,64,1E,24,19,75,DB,B5,65,8B,96,D5,23,09,55,9C,A1,56,7E,57,74,65,4A,97,86,0C,7F,39,6F,3A,E6,B7,97,BF,6C,B6,73,01,93,6A,5B,81,3B,93,D9,CD,7A,38,38,B2,F5,B6,8E,8A,E1,CB,29,54,5C,2F,2E,96,D2,70,1E,AD,FC,ED,5C,4F,84,B9,3F,1F,CD,FF,1F,9B,8C,42,6C,B2,24,7C,73,7C,FA,5F,03,E2,56,7C,14,E3,6A,17,A3,6C,2B,D1,CA,8B,F8,A4,F8,1D,80,9B,4E,47,0D,DE,03,C8,AC,95,36,BC,C3,C4,E8,C8,D3,28,9F,7F,55,63,E0,B8,E3,8F,E5,5A,85,1A,D3,F0,30,68,8A,F5,45,12,D4,1F,55,6E,E5,A7,D4,B2,6A,D1,D5,03,45,DD,79,D3,FB,4B,EF,E4,02,D0,13,48,EC,AD,41,36,93,B5,97,50,AC,10,D9,CA,7C,7D,BB,31,3C,B3,EA,76,F9,63,2B,A7,D5,7C,EE,0E,8D,0E,A0,27,59,62,01,3C,DD,8A,5D,48,7F,0B,39,43,0E,35,CA,76,59,AC,61,09,FF,18,12,3A,D7,46,4C,9C,22,57,CA,BC,8C,A9,D2,21,BD,3A,4C,2B,20,B9,96,CF,65,6B,F5,54,36,0E,E2,AD,FE,E1,09,27,9D,8E,0B,4C,67,C6,F6,4A,7A,72,EC,95,99,2D,DD,45,0B,F7,B7,93,C4,C8,3C,55,DE,22,94,D7,4C,38,12,EE,D8,B0,05,F4,61,EA,0B,54,02,59,17,2C,8D,59,67,DC,98,F4,5A,0B,F8,D7,4C,57,EF,D2,11,A0,06,E7,6D,1A,CF,C9,48,97,5E,A4,E6,F9,27,D1,7E,7A,20,79,A4,19,05,55,D0,91,D7,10,71,0C,16,87,93,45,CD,88,44,50,4D,3C,23,DE,FD,69,EB,5C,24,17,1F,98,4C,F9,6F,F0,E5,87,CC,E4,A9,47,A4,05,4A,56,2C,60,BF,56,D7,EA,C9,00,07,0C,EE,F2,AF,E4,60,93,A2,8E,7E,9D,EC,5C,D9,B9,AE,55,A0,D9,6A,55,C9,F0,4C,23,06,EB,E0,EC,7A,00,8C,A6,13,ED,3F,47,26,9B,99,0F,CA,AE,A8,9F,F5,CB,F0,4B,68,F5,5C,80,2A,25,D8,D8,82,42,5D,59,B3,83,6C,02,99,EF,EB,1E,00,33,80,8E,1D,11,49,4F,5E,FB,93,F2,35,76,DF,FF,9C,11,87,F9,63,57,74,9D,46,8F,C0,E5,6F,13,A5,6D,18,FC,7C,98,F4,AD,1C,4A,CC,7E,AC,70,36,2B,35,8E,80,68,C0,AA,77,8B,1C,D9,C1,4C,C1,07,D7,31,03,07,16,0A,E0,4D,59,9D,FA,57,56,99,FD,69,C5,8B,9F,42,FF,AD,C8,5D,C9,C7,C9,5B,BF,4D,55,EF,F1,C6,24,DE,79,83,F8,0F,AC,FE,1F,89,48,79,FE,87,76,45,09,E3,D4,5C,64,48,BE,80,01,1E,11,94,09,B2,C9,53,C1,4E,1D,A2,0F,8B,98,68,0D,0F,C8,F1,AD,3A,20,F6,5A,99,6F,B6,C9,A9,C0,F0,26,46,14,7A,F9,B9,87,E2,20,AE,D3,DE,C8,62,EA,D1,8A,51,C0,43,21,7E,AD,4D,C9,6F,FA,54,23,FD,63,DD,2D,66,F9,5D,BD,60,4A,FC,F7,E7,D5,99,E3,5E,2E,AE,64,70,CF,6D,B4,B8,33,16,BE,8A,7F,BC,B0,DA,20,0C,64,20,C3,57,34,B2,BE,99,D4,C4,09,B6,64,7B,C7,69,0F,0F,B2,88,78,91,9F,28,A2,AE,6E,C3,E9,24,DD,80,84,F0,61,EE,84,07,54,25,5B,0E,17,DC,E9,A0,80,77,10,0A,E1,C4,F5,79,AF,24,2F,EF,79,EA,6A,26,85,16,BD,E1,22,21,2E,48,AC,26,3E,29,C2,57,EE,21,B6,90,D0,D4,6E,53,07,4F,1E,93,E1,4D,18,87,65,45,23,24,4D,7D,E5,9B,B5,38,6B,DD,BC,39,8B,B1,BF,05,37,9E,50,36,93,FE,D7,36,50,F1,96,29,6D,01,D7,5B,57,11,F5,9B,85,FE,A7,D0,A3,43,E8,7E,FA,00,A6,96,C3,BC,77,90,0E,2D,7C,3E,34,E9,35,54,74,2F,A9,AB,FB,5B,08,08,27,32,E4,D2,E1,31,F6,ED,4F,5B,F5,4B,8D,0C,C2,F0,BC,ED,CA,01,6F,DC,FA,02,75,05,3E,3C,FF,6C,96,25,F6,96,3C,B0,DD,8D,3C,3B,58,3D,4B,FD,81,59,42,90,4A,0E,D7,98,D8,36,87,61,95,5B,E4,79,7E,12,4B,70,9E,76,B7,F0,A9,15,34,EB,92,C4,0B,73,96,60,D7,B1,A8,63,C4,D0,19,64,A9,A6,4C,73,31,41,5A,5B,A2,81,76,22,59,64,1E,D9,E0,FB,70,9D,2A,78,E3,82,FA,13,D3,8A,40,1B,C1,C3,CB,22,31,3A,57,FB,32,44,10,39,B8,99,31,E8,62,7D,B6,21,6E,41,D4,B3,BC,39,85,D3,62,F7,9B,A4,AD,9C,4C,F2,94,A3,26,E4,37,6F,E7,47,19,17,AD,22,CC,C9,F4,BA,7D,9D,5C,6F,D8,4E,18,39,F7,CE,04,47,5B,25,7A,34,8E,30,0F,0C,65,F7,63,7B,C6,50,E6,61,CD,2F,0F,28,6F,2F,C0,A5,9C,42,B1,71,0A,59,43,3E,AC,50,08,0F,FC,86,ED,C9,B0,45,97,4C,AE,F5,5E,5E,D8,CC,63,BA,AB,F7,39,FA,89,CC,AA,E6,E3,52,7F,1F,6B,5C,47,1C,1A,88,D4,F4,7F,AF,D7,2D,DF,54,16,28,55,50,07,8F,95,75,1D,F2,C0,24,43,CD,3C,E7,64,01,A8,38,49,66,BA,67,CA,C3,82,5F,28,E5,4D,94,E5,9D,A9,60,F5,71,D4,E7,C4,FC,AB,72,44,D5,47,FB,8A,34,B0,9F,1F,EA,25,32,D4,2B,40,55,F9,67,F2,CB,32,D4,C0,BE,B9,B3,B0,BE,39,68,C3,1A,11,9A,B5,4F,3C,35,08,62,55,EF,03,6F,36,D9,77,8E,7B,0C,2F,F7,A1,80,57,73,12,0B,D1,4D,85,12,7E,89,0A,1C,0B,17,55,AC,A4,66,E0,13,80,C9,32,A3,07,8D,A5,DE,7C,22,00,A9,94,CC,9C,56,24,C2,53,2D,68,FD,09,1A,D0,54,F8,C6,2E,E6,01,46,58,E0,6F,81,D4,6F,C9,FD,5C,6E,3F,F0,3C,BC,04,1B,E6,2F,25,54,4E,E3,DD,45,27,32,A9,51,D4,28,A4,47,15,A0,C7,2C,C7,1A,74,00,33,0E,71,BD,A8,96,1D,8B,44,6C,F8,87,C5,FC,4A,FA,A2,10,96,D9,5C,56,E7,26,8F,A3,B5,1D,C6,EB,18,34,9A,E5,5F,13,57,C8,5F,DA,F3,06,EC,BF,98,91,5D,A3,78,D8,92,F7,96,3D,A2,4E,CE,FB,E8,9D,85,98,92,A1,2C,A8,20,33,F8,3B,50,FA,EA,00,C0,33,44,88,DA,4D,0C,0D,16,F9,F7,DD,A2,3E,93,18,CD,6F,31,88,0C,BD,0C,2A,46,C5,08,69,4D,63,B8,EC,D6,9C,2E,6B,78,2E,30,0E,1F,7D,F4,FE,29,21,67,CB,84,46,C5,E5,5B,FD,EE,11,81,6A,87,01,DA,BA,F2,ED,CE,2E,26,E8,53,A3,F6,04,20,76,73,D1,2D,28,62,EB,23,F1,41,B8,AB,BA,FA,97,48,C4,4D,80,09,F2,1D,87,39,6E,0B,71,79,2C,92,B0,2F,E9,F1,C3,95,8D,DE,A4,F9,8D,03,9B,91,68,D3,E5,F7,2E,8E,34,F9,8F,C9,B5,7E,D9,E3,EB,31,53,F8,9F,DF,4E,EF,EC,87,EC,DB,72,BC,75,C8,B7,5D,00,76,BE,4C,11,2A,12,07,22,F0,47,95,47,06,EE,BF,E0,A7,FB,86,C7,73,16,C3,07,50,8C,69,D4,13,99,4A,B9,02,67,F5,89,35,C1,57,58,34,C0,17,B0,04,4E,84,15,7D,1A,99,98,2F,53,D0,EC,AC,50,C2,55,F5,16,DE,1C,FD,B7,C7,42,F8,0D,8F,33,61,15,35,0D,E4,E4,3B,D0,42,DE,04,67,22,9F,8D,B6,C7,74,5E,01,20,77,B5,4E,D6,DC,E3,43,3D,65,D6,B5,D5,67,16,D7,DA,FF,83,B1,B0,98,21,10,51,10,74,E3,86,21,85,73,5A,9B,1A,18,76,61,C6,B0,C7,CD,39,D9,AE,8D,D9,EA,81,F1,36,B9,C9,D2,A9,AB,CD,72,FB,30,96,EA,50,DC,30,1C,E7,13,1C,E8,5E,4E,A0,40,7D,D6,F2,34,BD,E0,60,92,29,B6,EA,38,5C,9B,DC,C0,63,DB,EA,82,D7,92,E6,CB,8C,39,6B,77,2E,E1,40,6E,A5,D1,5F,12,E3,B0,5B,A9,B3,A4,4A,AD,46,DF,C6,A9,B0,EB,53,E8,27,CF,F2,79,56,9B,E0,98,4D,FB,CD,C8,03,57,BA,41,47,21,AB,78,6C,54,30,A1,48,FC,E6,C6,AE,52,9C,9A,E2,0F,D7,C2,57,A9,52,1C,10,0D,FA,9A,03,81,73,50,64,8B,B1,40,67,EF,44,FC,67,0F,6E,C4,D7,CD,25,7B,63,F2,CC,25,7B,11,3E,C1,7F,69,43,CE,77,08,FD,97,7F,87,D5,36,96,F7,5A,3E,A6,4A,BC,12,56,DA,A2,C9,9C,FE,DE,55,B5,C2,42,9E,BF,89,F4,BD,B2,91,64,A9,14,14,40,9B,37,C9,FC,04,52,8B,C4,60,CC,58,39,D6,B2,EE,55,43,D5,4C,F8,9B,C3,07,A9,B4,BB,FC,C8,72,53,02,DA,56,C0,D6,6B,03,0B,B8,1F,33,8A,93,7A,D1,B5,27,19,2F,82,26,71,12,30,C8,FB,33,DF,3D,8B,CA,BE,5D,46,92,C6,44,CE,C5,AC,E3,2E,71,8A,44,2A,FB,5A,F1,2A,B4,7C,B7,B5,9E,36,5B,E0,30,B1,1F,72,BA,60,FA,90,BA,08,1C,70,99,1E,C6,A1,C3,7E,C6,03,6C,F7,ED,7F,D6,5A,FA,F4,90,40,81,D3,2E,95,F3,6F,5E,75,50,B8,51,A1,28,BD,67,13,70,F8,0A,95,0E,3C,52,1B,02,20,B6,62,2D,4C,F0,B7,13,2D,94,72,31,77,46,C8,9E,73,F8,6E,8D,D0,9E,D9,F8,77,75,1C,E4,48,07,D4,C7,EF,09,32,39,E2,F2,72,B5,A3,8C,76,58,2A,27,5F,3A,C0,B6,83,00,94,6B,F1,0B,C4,4E,80,BE,7D,D0,D2,F5,82,A9,E7,61,2D,1F,E0,1E,D6,6B,F2,11,E8,0E,D8,13,9C,7A,66,90,A4,2B,E1,52,EF,5D,81,C8,FE,AF,59,72,BF,02,1A,F5,F0,85,A4,D3,05,C4,81,D0,05,DF,13,30,31,C8,BF,0E,5F,C9,22,9B,31,FA,B8,4B,4E,6F,60,95,42,A6,8A,58,FA,91,09,43,4E,A3,25,A2,5E,40,43,0F,40,EF,42,B0,F0,A8,54,7C,9E,F7,7E,BF,AF,D0,EE,A2,4A,A7,D9,4A,01,6F,E1,EA,00,9A,DC,66,3C,C9,4F,71,BF,70,03,9A,09,08,56,4C,57,73,A4,BD,93,7E,05,78,B4,64,C1,DE,FB,BF,90,A1,5C,18,E9,D5,E7,3B,5D,30,88,C5,77,06,24,A1,C4,28,31,A9,C9,D6,56,9C,05,29,92,13,A2,12,14,34,8C,BF,A6,07,C9,05,F6,82,28,90,2D,8A,82,69,24,F8,F1,B2,12,2E,23,14,A2,9F,4E,BD,12,54,A6,D3,9E,7D,34,9E,F9,DE,5D,8A,54,75,B3,58,4E,B7,D9,B6,32,4D,97,0F,02,DE,C2,23,01,2D,14,BA,FF,DA,6A,27,02,B2,56,9B,71,42,F7,28,67,A0,71,F2,7F,13,B5,E4,2F,D5,F0,3B,9C,CC,ED,19,36,D5,54,51,EC,0F,B1,8A,E6,54,D0,E2,D0,12,8F,AD,C2,25,FF,3B,B6,80,BF,0C,1A,92,DD,7C,34,4D,51,68,58,E0,B9,B5,6F,A9,4C,E7,1B,46,6A,C0,61,11,57,15,D8,83,84,6A,20,40,7D,10,8D,3A,1D,0B,47,DC,24,44,40,22,75,87,E4,A7,20,52,39,E2,7C,B1,50,6C,4C,5E,8B,7C,F1,64,9B,40,22,B4,AA,CF,68,99,85,0F,11,4E,F9,CF,9C,08,B3,DA,90,A3,DB,2A,BA,6F,34,0B,9F,00,E4,72,39,F8,55,C8,4C,B8,34,20,5D,9D,28,2B,4E,8F,A9,4C,25,D1,07,AB,C6,1D,B6,D7,1A,A7,39,EA,34,92,C2,45,59,D9,58,68,88,56,57,AF,82,B8,F8,EA,1A,64,CC,19,4D,95,B7,0B,70,B3,35,C8,CF,B6,34,7A,92,10,90,F1,DA,10,0C,40,F3,6A,C6,9F,6F,F6,6A,1B,F4,47,E0,C7,7F,21,F2,FD,6C,3F,44,B8,AE,BB,B0,F1,57,77,7A,90,5F,8B,18,F5,1C,7E,DE,B9,4A,74,10,3C,5A,D7,A8,C7,66,C7,1C,73,4A,03,4A,CA,A1,27,91,FE,35,6E,EF,C0,6F,6A,E0,56,9D,AC,1F,8E,E4,6E,89,BB,08,4B,CA,4B,C8,A9,28,F1,B4,D1,D0,61,DF,98,FC,EA,FA,4E,77,5B,E2,4B,BC,9D,90,88,CA,85,89,42,AB,53,21,4D,AB,D3,F9,6A,B2,D3,1F,4D,9D,85,F3,48,BC,9A,21,BE,44,E3,C0,FA,02,CD,59,A3,11,72,8C,D7,47,84,E0,22,5F,DC,EC,E1,67,7E,50,94,E2,22,75,E5,72,4E,8D,90,87,EE,3F,A5,A4,00,0B,B5,F0,1A,E5,3C,34,49,FD,25,B3,94,89,4A,3C,E9,FF,89,4F,43,4F,3F,D1,AF,9E,75,6E,25,98,F9,DC,50,2B,8B,08,8A,63,20,1D,3B,76,94,3D,39,A8,D0,0F,77,39,55,4F,32,7A,35,7A,1F,10,D1,1D,1B,3D,B8,61,4A,1D,EB,BD,07,5C,49,96,C3,D9,F6,88,4F,DA,2D,C5,C4,00,0B,F4,1A,63,A1,0B,A9,79,A9,04,7A,C3,01,28,68,CB,C4,FF,14,B3,96,50,62,B1,5C,8C,77,58,6E,AA,E8,F1,E9,BE,98,5E,E8,32,0D,4F,26,B2,D8,BF,CF,CB,43,38,5E,AB,52,F0,5F,45,C3,56,C9,64,7D,69,34,48,F2,E7,55,6C,83,85,1E,87,C3,BC,0E,65,75,6B,FC,2A,11,51,0D,64,5C,D7,DF,A9,AA,40,96,94,79,5F,93,A8,07,4B,7E,E0,ED,30,A7,CF,DA,8C,0B,7A,81,95,A0,0E,6A,EB,79,3A,76,86,22,ED,3A,CE,E2,C0,EE,A5,54,F1,6C,81,59,00,E7,7D,3C,FF,BE,2D,75,2A,E2,05,2F,83,A8,79,7D,04,F4,08,E8,39,DE,FF,AA,E3,4F,B0,05,26,90,A0,53,64,D2,18,14,08,CF,25,DD,83,65,AA,BB,B8,F6,C2,02,BB,14,5A,CA,F0,7E,4F,89,C7,C2,EA,F9,AF,03,13,CD,C8,DD,03,EE,57,0E,06,54,56,A8,BA,D3,B6,B3,48,E0,81,62,8A,09,E2,20,AC,89,B8,8C,D7,6A,95,07,AC,28,62,91,5D,EC,2F,08,A1,90,F0,59,A7,17,CD,5F,0B,DF,B6,EB,96,C0,1B,0F,3F,F7,14,47,84,8A,D3,86,C5,A3,6D,9B,ED,F5,40,90,EC,87,DB,67,E0,16,AD,DF,33,A5,14,29,06,2C,54,A2,0E,DA,34,65,6A,AB,10,DF,EE,85,1B,E7,BA,ED,F2,8C,66,66,2F,79,14,FA,7C,DB,3C,99,4E,2F,E5,7A,D0,AF,66,14,A9,7E,E0,6C,05,58,02,74,68,DE,CA,63,0A,AA,80,84,84,6B,59,8E,FF,EE,0E,45,B0,EB,E2,3E,F2,E8,B1,35,FD,A5,13,6A,AF,2A,43,96,70,D1,AE,BB,2D,B5,0C,9E,5E,F1,B5,58,29,FF,61,0B,91,10,B3,25,41,38,28,3B,5A,D4,D9,3F,BE,D7,85,8D,25,2F,70,E3,2E,6B,D1,72,BF,19,6B,AA,1E,70,40,FD,62,BB,01,D7,9A,DA,7A,BA,22,14,BE,29,1A,26,10,7F,0B,1A,EA,8D,F3,94,85,44,9D,3A,5B,8F,53,D7,18,D9,BB,59,57,A4,F3,4E,4A,75,D1,AB,38,74,EA,AB,7D,C9,DB,71,4D,2C,79,B6,64,DD,7F,54,66,55,38,89,DE,07,E1,4D,B7,80,3A,AD,6E,8F,90,4F,1D,5A,54,43,30,A6,16,1F,F5,C0,89,94,FC,81,93,B6,55,8B,3E,D0,13,21,28,2E,62,F0,7E,EF,A1,0E,D0,D9,86,99,6A,0E,AC,75,91,B9,25,A6,10,99,34,D3,10,63,E7,05,3E,62,03,8E,2C,88,51,CA,A7,12,89,DD,2C,B0,F5,1D,A4,E4,D0,A0,D1,3C,B8,63,42,94,15,BA,BA,6F,D6,81,7F,F4,23,6B,8F,04,D8,36,E7,67,11,31,80,F6,BA,7D,E9,9E,F6,1F,66,12,84,40,DB,B9,4B,D1,1C,32,A4,5D,2B,07,B7,DC,87,0B,66,53,66,1E,A3,B3,41,F5,AF,DB,3E,8A,67,69,93,B6,2A,84,24,25,FB,97,98,3E,3C,71,A1,CB,EE,BD,C0,C3,7A,4F,98,D5,30,C6,51,21,6F,F0,0B,07,72,97,1C,57,BD,E5,1F,E5,C2,09,D3,A1,92,1E,AD,58,7C,78,20,0D,BE,9D,D6,18,94,66,2B,34,95,F7,3F,3F,5B,68,F6,51,10,0E,CF,A4,D7,43,E0,35,69,67,86,93,DF,99,56,B6,16,BC,64,09,0E,3D,A2,12,17,F7,00,AB,C9,53,91,F6,AF,FC,8D,94,93,D8,45,67,76,0B,62,88,B1,5F,6D,CB,8F,99,23,EB,31,AC,BB,EF,FF,28,B3,1E,6D,90,15,81,09,23,C4,5A,44,8E,40,35,9C,E9,1B,8A,AB,A1,E6,F9,9E,52,FA,5B,AB,12,17,B9,C0,62,6F,97,41,45,FF,97,5A,D1,C1,F4,F5,76,63,C0,B9,71,2E,8A,80,D2,EF,F0,99,12,F8,16,DA,EC,E5,11,49,3F,56,5E,25,24,B6,1A,45,03,B8,94,B2,3A,87,50,F7,EE,E1,97,FA,65,11,5D,0B,F5,80,06,FC,7A,83,A7,F4,1E,88,EF,FA,0F,BF,C1,08,8B,CB,76,FE,0B,20,0D,B8,73,36,F3,4A,A4,E3,78,42,D5,53,F1,48,20,5C,31,69,6A,57,6B,60,AE,CB,93,1E,F1,D4,E7,60,D7,69,6B,89,6C,25,E8,75,9C,A3,A3,0D,50,B3,09,31,6A,3F,B8,AB,31,7A,8B,D1,74,F7,34,29,3C,47,BF,1D,09,AB,E6,93,70,DB,41,75,9A,02,83,76,CE,5B,D5,DC,4E,5C,77,21,E2,21,F1,FD,59,89,96,FF,F2,56,7F,F6,4C,15,00,17,98,09,1F,2C,20,EB,9F,6A,A1,D2,57,37,68,1E,B9,77,CD,9F,3C,B0,CC,68,F4,ED,8D,F8,6C,D4,92,B0,3F,BB,B5,AD,3A,7A,67,CD,61,BB,AA,0C,AC,35,B6,DE,D1,E8,3A,D9,1E,33,8D,4C,7B,2D,24,E3,EB,EA,97,6B,67,49,12,F4,CF,41,C1,65,AC,1D,BB,96,58,4E,D7,26,7A,0A,C6,DB,88,C4,C7,17,8B,4F,82,9C,BD,1E,5D,05,79,03,48,A0,4D,EB,68,2D,E0,EC,0A,A2,24,0D,F6,BA,2F,7D,71,C3,2D,21,BC,93,AE,2C,61,3D,63,E7,0A,71,1B,B4,52,A1,D7,CA,58,FB,4E,C5,08,32,B8,D1,F1,DE,3D,A6,63,AC,DE,6E,3E,BB,64,A4,91,95,69,42,72,A2,FF,EC,68,31,35,D0,30,5D,12,51,55,CC,5C,7B,24,DA,E0,54,97,56,3C,7C,A7,AE,2E,8B,E5,2D,CD,13,B2,DD,AD,3D,5B,93,72,57,8E,23,F1,54,80,3B,46,49,0C,54,DD,69,4B,30,AE,E1,4C,ED,7C,AF,4A,B7,6D,74,82,F0,AC,60,FE,24,2C,84,87,2C,6F,2C,29,AE,A2,6D,5F,5D,0F,C8,C5,C2,1D,49,C0,68,E3,77,89,CE,0A,67,C8,94,28,2F,72,A2,28,9C,C0,5A,F7,FC,68,1B,13,7C,90,B3,34,C8,53,2E,E0,DA,12,F2,9A,60,49,7F,09,47,A9,67,B2,D1,8C,35,51,5B,01,5C,B0,6A,2A,4F,7E,AB,61,1A,29,B0,69,CA,1B,D0,BA,D5,AC,DB,2E,22,10,F7,54,27,02,00,D3,9E,E9,DD,28,EC,E5,C3,4C,08,80,4A,B8,15,A5,54,E4,53,9C,71,E6,E4,C9,24,7F,52,7F,EE,62,43,B5,FF,BA,72,B0,21,1F,79,44,A7,98,85,D0,79,EE,0B,68,BC,3B,CC,8F,00,79,AD,A8,8D,84,47,2B,4D,D6,A3,4C,74,02,59,E9,55,36,92,91,0B,AF,25,DB,4B,DA,1A,E0,72,6B,15,50,6D,D3,87,4F,74,E7,FA,F2,BF,46,F0,75,E6,CE,17,4C,1C,6A,6D,08,40,99,FC,5F,81,C7,E7,26,DD,C2,2E,3F,81,35,A0,3B,4A,F1,37,E0,36,93,6E,E6,7E,09,BD,82,4E,1A,27,8F,D4,3E,99,2C,DF,45,DD,EE,66,3D,0E,AB,EA,3D,F3,85,3D,ED,4D,B9,53,59,CA,A3,BA,EB,36,6E,A2,8E,48,3C,04,14,03,EF,60,67,7D,38,25,41,28,49,CD,2B,2D,59,C0,E1,0B,71,17,DA,AE,B2,2D,C4,77,E5,09,8C,7C,74,B2,2A,F8,92,06,B8,E2,CE,52,C0,15,51,8B,2C,73,F6,7B,97,F1,1A,A0,BA,28,7D,EB,6F,7E,E1,C2,99,EB,1D,8F,50,8C,C1,03,63,1F,3A,5C,7E,7F,60,14,DA,58,4B,9C,7A,F7,17,2F,EC,77,59,1D,21,BC,11,60,94,35,DE,BE,4B,8D,4D,C5,FB,49,E3,E0,D5,12,EF,15,4A,8B,FF,70,7F,D8,D9,9F,74,DA,39,A8,49,BB,68,95,A3,E9,9F,C4,66,9E,58,3D,32,B6,5E,F1,A6,85,68,CF,9B,4F,79,53,4C,8F,40,71,89,28,93,81,92,27,DA,34,07,59,2A,71,11,1A,09,CF,DD,AF,07,63,AA,12,77,A1,CE,64,20,62,A0,F0,F2,41,DB,73,2C,CD,22,E8,80,62,5F,73,6A,A2,E8,A2,56,11,7E,95,44,E1,0B,64,12,D9,A5,58,02,57,DD,F7,75,1E,AD,AA,7A,57,98,D4,1E,9D,C7,09,A8,3C,A4,92,B9,FD,65,6C,0F,3B,24,F7,CE,5F,FB,CA,83,D6,97,E7,5C,FB,DD,7B,BC,4D,8A,4F,C4,FB,24,0A,68,05,54,32,38,AB,2B,79,E9,17,A7,CF,11,01,85,05,BC,86,6A,8A,DC,22,62,E2,40,33,47,BC,6E,22,42,BD,E7,8C,1E,86,17,14,59,1E,52,3A,3D,7D,97,53,0D,5E,D9,9C,E1,AA,C5,70,77,FB,8C,17,AE,42,C2,76,5D,6F,D7,67,C7,1E,4C,38,0D,B1,1B,A1,35,43,0C,3E,FA,2A,3D,9A,4C,AC,C7,FC,71,2B,76,9B,D8,F1,21,25,BA,D3,19,51,25,73,15,FB,FF,76,02,4F,1E,C0,57,CA,B8,86,C0,00,F0,70,C5,68,AF,8E,91,56,6E,02,EC,21,77,96,BF,F1,B8,23,2E,25,79,3E,23,65,9F,5D,20,E8,99,B3,BB,B0,C4,AC,8B,FB,EC,08,7E,CB,10,88,F9,B3,2F,04,EB,19,66,2F,50,9A,75,93,8F,E0,D7,29,C0,4E,43,B7,7A,6B,5C,1A,FB,0C,09,30,93,AF,DB,4D,43,85,F4,D9,69,63,75,C6,70,0C,A1,FC,EE,5E,60,41,E7,D9,AD,0C,02,F3,65,65,99,0B,4C,83,8A,1B,34,A7,09,39,4B,4F,E0,F4,49,D2,89,F5,F9,2F,AC,43,98,BB,18,C9,14,3F,05,72,EA,03,76,80,73,BB,E9,6B,61,69,5E,7D,23,04,4E,EC,3A,E6,AF,15,25,F8,70,C6,38,40,B0,C8,63,02,F0,60,9C,9D,7D,FE,C8,3C,80,3A,59,C5,C2,09,80,92,E6,57,05,90,D8,ED,47,77,14,EA,8E,61,BC,81,6B,FA,44,74,CC,27,2B,86,A1,4E,C7,91,4E,DE,20,21,A5,39,1C,75,ED,98,07,21,E2,10,C7,EF,99,30,30,FB,58,BC,A4,2E,F1,0E,D3,47,FC,4D,32,1D,96,4E,C2,3C,E3,65,00,FD,A8,E8,5A,1A,31,C9,E4,5C,A9,E7,F1,3F,BE,FE,90,2F,22,EE,BC,59,C8,BF,0A,D6,25,06,4A,E2,65,0B,F9,D7,50,84,DD,12,E3,55,A3,DF,6E,91,F4,5D,37,80,29,3C,E0,52,7D,B3,F9,AF,6D,CC,44,FD,DD,59,09,CD,7E,08,0B,63,6C,9F,48,E5,72,ED,9D,95,F1,38,FA,F9,71,53,E8,75,52,40,4A,E6,A4,DC,7A,DA,53,A4,35,5E,5F,05,33,F9,C7,18,9B,CF,E1,83,16,A6,14,83,26,90,4F,59,71,D8,1C,6B,26,5A,D1,82,F7,4E,6E,36,8A,8C,E3,53,6A,EF,16,AE,42,FD,3C,AC,F4,99,E3,50,22,CD,70,41,6F,4C,BF,4F,E1,24,8F,86,7A,73,E4,5C,7D,28,21,30,8A,DC,08,FD,B5,45,65,F7,C8,5F,53,57,90,12,8A,7C,6E,F5,F6,5B,CC,C8,86,1C,55,C6,0A,A2,C7,FF,AE,0F,CA,71,84,77,26,77,11,32,E1,E4,24,5E,BB,72,6E,CE,02,B9,2E,38,7C,EB,FC,8F,ED,BE,B8,9A,F3,BB,57,99,59,7F,FE,EC,F2,24,1C,AC,18,A6,CD,74,95,23,BC,E5,2E,2D,AA,0D,D7,87,5E,98,36,C4,16,54,11,41,E2,3C,EB,D9,B3,80,90,05,19,AE,8B,EF,6D,FF,AF,67,03,25,88,10,40,7D,EA,CD,A1,F7,7D,0D,71,C9,6F,FE,13,A8,C3,6E,EB,A4,EE,0D,9B,FB,37,64,2B,9F,31,E4,2C,95,A8,5B,4E,9F,1A,C7,CD,86,25,99,42,1D,3F,02,F3,B5,22,E1,19,2C,B4,4C,03,DF,9C,46,0D,48,2B,16,79,51,70,6D,8E,15,5B,2E,C0,78,90,A2,C3,19,8C,C0,EE,F8,87,AE,F5,FF,53,D7,22,F5,43,84,96,BE,1F,38,9B,B4,5B,82,D6,B1,D2,B8,83,92,D3,BB,09,CA,92,D7,A9,EE,4B,EC,33,89,20,D4,57,97,5A,0D,A2,F6,0E,54,CE,5D,2A,82,45,17,2D,70,9D,46,43,FC,46,5A,D0,12,82,E0,9B,8E,85,1A,41,9A,8B,A2,29,B7,B6,90,B9,5A,94,C9,C6,77,66,C8,D6,30,78,E7,12,44,39,6C,07,6F,A7,87,EA,07,01,7D,F8,1A,C8,8A,6A,D4,0D,12,C2,49,4E,9A,85,97,7F,4E,6C,88,4D,2F,34,0F,7F,26,B5,B1,36,50,1E,C0,26,A9,90,77,CB,2F,E8,E4,64,B3,5D,E4,EE,BB,F2,0A,89,15,C6,FF,65,BB,76,C3,82,E5,FE,2F,68,EC,E8,EA,51,9A,8A,B7,06,58,64,29,D1,61,3C,17,AC,AC,34,30,A5,E0,CB,93,E8,DA,78,E9,54,B7,F3,08,4C,5F,AC,50,45,CD,E6,E8,BD,9B,5A,A4,83,78,C3,4B,5E,C3,0D,4A,C8,38,9E,3F,80,38,18,39,82,3F,26,69,0C,19,66,6D,37,B2,F3,70,68,5D,55,75,70,7E,BE,AB,46,23,7C,55,6F,98,ED,CC,3C,FE,8A,8F,9C,A8,A4,0B,77,A5,0F,90,17,F7,38,06,CE,3D,7A,C8,F9,A9,29,52,B4,DB,61,BA,64,C0,25,51,84,BC,04,07,F0,20,AC,A4,AF,C7,06,9C,49,F4,4A,E9,D4,D9,E4,D9,BD,0E,EA,8F,E9,3F,53,11,D3,20,DC,49,28,53,E3,9F,D6,21,5D,54,F4,15,1E,15,2A,20,DB,B2,80,D3,00,F9,65,C0,42,EB,AB,4F,10,AE,49,B1,EF,73,FF,D1,DA,7F,6E,A4,54,85,08,A6,6E,89,8D,76,9C,14,E2,66,20,C7,C9,A6,CD,5D,AB,B0,16,9F,8B,35,04,04,D0,06,5B,D6,9D,04,FC,C6,D5,ED,3F,82,A9,CE,7C,8E,C3,71,8A,14,90,66,43,25,BB,8F,D5,38,E2,C5,91,26,49,EF,26,90,31,58,E7,70,3A,90,C9,BB,F1,A7,F2,87,4E,FA,F4,41,A9,14,C4,41,73,1F,83,84,CB,98,31,E3,CF,C6,40,98,97,54,F5,7F,1A,63,10,1B,7A,A0,DC,88,70,57,BC,DD,AC,ED,38,BE,CD,FB,92,3E,EE,89,E1,8C,D5,61,05,3B,61,0E,2B,B9,D8,DD,00,49,F8,28,B5,F5,B1,83,E0,D1,88,43,C8,D2,CA,17,68,73,70,11,40,19,28,60,13,60,8A,78,23,96,CF,B7,93,4F,31,C7,CC,1F,01,F4,CC,2C,38,2A,32,46,7A,03,E1,0C,2C,9C,60,AC,5E,BA,B1,44,CB,CE,4C,03,EC,CE,D9,A1,4E,E4,DE,B2,12,A7,27,21,91,AC,E0,68,82,13,3B,04,5E,97,29,1A,96,1F,B6,8B,76,01,9D,61,EA,EA,3F,E8,4F,39,CE,05,A7,02,8A,EE,92,01,BA,2E,B3,29,63,CF,BE,D7,63,5A,3E,AF,BF,BF,92,B3,C5,1A,A0,01,B1,96,B2,F5,3F,1A,37,ED,D1,A8,C7,58,3E,85,4B,4D,F3,E8,C4,D5,3D,2B,D5,BF,A4,0A,70,46,F1,CB,00,AE,FB,5B,A0,6C,36,5D,BB,74,8F,A8,11,28,6B,94,91,0E,0A,53,77,D2,D1,CC,F6,F9,C9,BC,FB,B7,55,CA,F6,5E,C5,5B,E5,4A,07,9E,C4,78,B9,5C,CC,9B,C6,4B,F0,5C,98,A7,31,4E,DE,31,1F,7B,A1,E5,25,A2,5F,54,A5,1B,EB,95,05,A0,DF,B8,92,94,C3,2E,AC,B1,69,56,BB,08,DB,90,FA,85,3E,DF,23,9D,4E,5A,3F,1B,45,D4,6D,FC,1E,D4,F5,0C,52,A8,39,0B,FC,36,74,FF,EA,63,4A,C7,7C,7F,E5,38,ED,18,C2,93,E8,7F,16,13,F2,3B,9F,DD,59,5F,7F,46,51,58,FD,D9,7F,FE,47,3A,FE,50,21,7E,C5,72,09,12,77,F9,10,CC,4A,FF,A1,51,21,FE,32,63,75,6E,37,A4,AE,47,93,D2,77,B4,31,E9,3A,88,43,77,C1,9F,13,A7,C8,71,F7,A6,B6,00,3D,C8,C7,EF,BE,D0,1C,1F,A7,2E,CC,5B,FD,A0,6B,9B,8C,07,E8,16,C0,82,F6,CA,D0,51,3F,8E,76,86,5F,DC,C5,00,11,25,BF,EA,4C,D3,59,EF,21,28,C2,DA,57,01,F8,BF,8A,FC,CF,B8,C5,1E,98,B2,AC,51,2A,0E,2A,D8,22,A9,7E,F4,7E,4D,7E,8B,DC,AD,ED,D4,FA,B5,9F,15,F2,3C,51,19,F5,32,40,44,57,3B,1D,E3,99,F0,F1,A6,CC,C8,17,91,62,84,F4,1F,36,C9,32,D8,BB,27,FF,D9,BA,68,94,A7,5A,A4,77,39,02,D5,F5,F2,1C,67,75,45,93,B7,0E,99,05,F7,AB,27,86,75,0D,90,F3,E0,21,61,87,C4,63,DE,C3,4C,A8,8B,FC,FF,12,BD,75,72,AE,0A,7F,A9,C3,61,BE,75,64,12,3E,11,28,F4,9D,C9,0D,8F,F7,B6,82,1D,64,C5,F9,86,E4,F3,C8,0C,9E,19,03,A0,E7,C7,5F,F1,EE,8D,F0,61,C8,BE,F4,3C,01,18,DD,79,CB,0C,21,9F,1D,65,4B,69,53,3A,75,08,A9,EB,77,2C,64,A0,D3,FD,B2,D0,E5,EC,22,10,81,EF,8A,7E,FD,67,1A,BD,F4,60,7B,A7,55,38,DB,7F,F3,32,79,D3,73,F6,30,4C,2E,65,A8,B4,24,CE,A0,09,46,42,4D,3C,F5,B6,55,99,4D,D5,55,E9,1E,96,78,A8,56,41,7D,EB,93,20,D1,7B,34,F9,1D,68,1E,0E,C6,FD,CC,6F,42,11,FD,80,E9,8D,F0,30,B1,9F,34,D6,15,59,97,9C,88,86,F0,AA,CE,CF,DE,96,95,A3,0A,89,6E,7A,DB,57,F2,E7,21,FD,FC,21,5F,C3,94,9B,62,03,B3,2C,2B,F4,D4,F5,1F,CB,96,B2,83,F4,67,FE,D4,16,FC,98,F1,EC,41,5E,CA,C2,6E,25,10,0E,B4,29,66,36,30,EE,8B,F8,86,11,D8,3B,68,E2,38,92,F7,33,66,8D,70,96,38,37,A6,50,EE,52,36,BE,C0,9D,31,F6,01,80,0A,BA,49,86,47,23,14,5F,0A,3E,06,6F,BC,7F,8C,61,01,0E,C8,B2,71,C7,6E,58,4E,E9,63,8C,39,F8,36,DA,0E,04,53,6F,DD,91,04,AD,BE,29,3F,51,1A,53,43,08,16,BA,85,68,60,2E,94,7E,C3,6F,9F,96,C3,D9,FD,93,42,01,84,14,25,19,D4,77,4B,88,CC,B1,C7,D1,B7,AE,DA,1D,24,FC,E4,56,7F,EE,D4,61,4E,F9,A0,34,12,74,E1,BD,C5,B9,A9,3C,19,A7,CB,B9,AE,EF,01,B2,01,68,66,34,FF,18,CF,6F,41,BF,4E,54,83,AD,31,FF,A3,6A,E5,F3,99,F9,64,FC,D5,75,04,5C,EC,FE,1C,2C,17,8B,5F,42,74,BA,17,BE,93,E8,3B,47,68,42,68,27,11,43,A2,F0,39,65,A3,96,4F,D7,AB,D7,0B,23,53,54,FC,22,F9,56,73,B2,C4,95,8A,A5,C6,FF,01,91,48,EA,C1,42,99,54,75,76,9B,1F,58,93,69,9C,5C,9D,2A,C4,6F,CA,67,76,08,C4,91,08,CD,3F,FB,6C,C4,FE,9A,07,51,5F,AE,73,76,58,FB,6D,CF,9D,CF,EA,BF,40,83,92,42,B1,C5,7E,75,60,DF,E8,DB,E4,0C,0A,A0,95,6C,F3,87,0F,6D,BF,C4,0A,7D,7D,AF,E6,0E,CE,3D,B1,58,35,A4,EE,B3,62,99,12,10,7B,D3,CE,85,DD,6C,C0,05,12,67,7C,AC,7C,43,47,BB,60,01,52,33,52,32,7E,4C,0F,39,AD,ED,0A,4A,62,34,C5,99,34,09,79,51,4D,D4,D8,17,17,55,24,96,B8,79,33,3A,E6,B9,14,2F,E8,75,09,85,49,1E,75,E2,96,B1,90,AF,78,C1,53,93,CB,08,20,8C,BD,B7,3D,78,98,14,ED,66,C3,E6,DE,18,CD,E7,F6,86,66,44,D2,95,EB,93,5A,A5,63,3F,00,40,BD,7D,83,5D,D0,85,41,A6,5D,78,AE,BD,8A,EC,28,24,4C,F9,A8,B2,BB,B9,CF,98,1D,9F,5A,45,C7,8E,E9,E7,21,21,D6,DF,C8,4C,AB,03,A8,90,D5,D6,37,38,56,CB,65,B9,A6,33,44,5F,F8,B6,50,A0,39,7F,02,DB,F7,1C,B5,30,E8,97,21,B7,76,F5,81,D9,A7,B5,EC,D7,9A,47,72,C0,EF,FE,D8,DE,DE,59,C6,75,FD,DB,B2,2E,18,8C,47,C3,6F,79,7C,93,4F,02,D2,FF,16,60,C6,88,D0,27,92,DF,51,2D,CE,D5,DF,01,3E,2E,87,D2,7C,42,BE,5F,0D,EE,A2,D0,1D,20,8B,9F,35,42,C6,FE,CF,53,E4,83,A5,B4,6A,54,C9,E6,57,B6,5D,86,12,86,A7,62,6F,14,D7,1A,03,7C,41,20,1B,56,9F,51,EC,3A,11,10,05,45,EC,52,6E,6A,E1,56,21,2D,11,97,5E,28,7B,9B,74,3B,7F,37,2E,FE,C2,13,AC,E8,54,1E,BC,5B,8E,15,93,8A,F9,1F,EE,C9,21,56,07,B5,DE,81,DB,1A,FA,53,0A,67,61,A5,93,7B,19,B6,04,3E,C4,2C,13,DE,A5,AA,F6,9F,5E,AC,67,24,CD,5F,A5,10,EB,D4,DC,AB,82,65,79,F0,83,E3,ED,8D,9E,A8,F6,0E,16,95,D6,7A,3D,3E,10,EB,C1,F8,B9,BA,84,6E,7B,AD,E9,8A,F6,85,A3,61,56,3E,1B,D1,19,F6,F0,0F,2B,7E,EE,54,93,8F,67,B9,A4,09,1C,0D,97,76,74,F1,76,D8,E7,EF,DC,DA,BD,0A,5D,BD,F4,D4,40,F0,CB,D7,FF,DB,A4,D2,76,B7,21,F0,56,2A,77,72,86,80,3D,EC,06,BB,A7,1F,D9,B8,7C,DF,D6,0E,BA,92,35,8B,09,AA,58,35,B1,63,E8,22,6D,DB,70,8A,9E,36,2F,71,82,CB,13,61,8D,59,56,EA,26,80,26,27,A8,CC,E4,8C,5E,8B,63,B9,DB,31,A7,5B,4B,85,35,45,71,07,51,0C,07,74,14,5F,70,CB,6D,B5,F6,C5,73,83,3B,B3,E9,26,74,84,34,98,92,64,E5,F1,1B,68,8E,01,93,B9,2D,D8,B2,E0,9A,3F,47,9C,CF,FA,CC,30,61,A6,9F,11,3E,23,76,10,37,2B,B6,93,C2,D5,50,AE,CA,89,CF,2E,86,8A,0A,5D,81,59,71,DB,43,DD,62,C4,6B,24,42,BA,94,1D,F5,C0,B8,68,48,C1,CB,53,D6,40,BB,B7,45,DF,9A,D4,50,56,16,B6,38,64,C0,48,DD,02,64,27,D1,43,E1,CA,3E,15,DF,36,C7,EA,4A,94,F2,ED,DB,EE,7D,92,13,60,D0,F8,C3,E3,39,79,93,8E,3E,7D,FB,D7,DE,2A,B8,C2,60,72,40,9D,67,A8,0B,54,0F,1C,48,FA,8E,B0,52,40,B3,4C,4D,CD,09,D6,FB,D7,C7,C3,E3,2F,CB,24,67,AC,31,F8,13,70,DA,93,26,5B,52,57,FB,2E,E2,17,E7,E1,C3,9C,4B,A4,EA,7F,EF,94,B3,15,59,52,61,67,C9,83,10,E2,BB,19,B7,F1,FB,23,04,4C,08,0B,47,56,E3,A5,F6,00,A4,E5,5F,CC,46,46,E6,05,37,A9,FC,8A,80,C0,DC,41,15,A2,70,B3,82,03,99,9E,D8,BE,22,C0,06,E1,DA,69,2E,FB,C0,E9,8C,8E,F6,DA,18,4E,30,64,9D,35,31,48,6F,DF,7F,D3,A2,01,79,D9,C3,AB,64,17,0C,5F,87,AC,6B,BE,E2,B2,EE,FD,E8,CA,6E,25,27,C2,5A,78,B1,8A,63,D3,5B,15,07,8D,99,92,06,74,73,A6,CC,21,6E,69,7E,F9,2C,B7,E1,78,F2,D6,E7,55,06,59,F9,56,71,48,65,EF,C8,8B,F4,D8,FA,E7,A2,C3,FC,01,35,BA,D9,6B,6D,E5,B1,9D,69,40,D9,1A,5E,F2,F2,5E,06,99,04,4B,8C,B4,97,BF,4D,C2,17,CB,B2,CA,C7,A4,EC,6B,71,83,FB,36,70,37,51,FC,33,F2,F0,E2,68,82,E8,D3,E1,35,B7,6C,63,CF,2C,1E,46,B4,AB,F3,6C,A8,56,1C,DF,D8,1D,E0,21,FC,D0,1A,B2,96,22,A2,C8,F6,0F,84,46,6E,4C,56,D3,85,E9,09,22,67,17,9C,08,47,17,78,F4,2F,82,96,5B,87,E7,15,AE,10,B9,D7,1E,B2,50,6D,E8,97,DE,55,5C,2F,2E,A6,C2,2C,E0,B0,61,61,FB,94,1A,29,7F,3F,62,DE,19,F2,60,F7,1A,BB,D6,87,AA,77,F5,E2,A2,0A,5F,8C,78,99,F9,8D,19,BC,CA,28,C7,5F,F9,76,F3,B3,41,AA,D1,44,AA,C6,98,2C,CC,96,E2,44,54,0C,A4,4D,76,41,77,4F,F2,A6,45,56,CE,A5,9A,3B,6D,FA,3E,3A,A9,81,D8,D4,9A,E3,AF,EC,45,44,3E,31,35,56,98,FD,DF,81,F8,E2,E9,98,1C,A0,B8,82,D1,B9,E8,F3,20,72,16,A6,0C,2C,3F,DA,2E,9F,39,C5,DB,85,1E,0F,44,DD,F0,77,DC,E3,DB,C6,64,DD,59,76,5A,E1,AB,EA,B3,1F,AA,0B,74,18,42,E2,AA,D1,4E,AE,EB,F6,9F,12,78,F5,DF,79,1B,C5,C5,D2,11,F2,47,45,57,7F,A9,0A,F9,11,27,80,ED,7C,E0,6D,94,E4,A7,32,EA,9E,18,F6,DA,31,3A,AC,66,96,05,EB,42,50,65,49,4B,75,00,D9,9E,F6,4B,5E,3F,2E,C2,90,E9,9B,68,57,65,DE,09,28,F6,4B,13,CC,52,02,D7,7D,48,10,FC,E0,1E,BB,9B,A3,E4,3C,EC,19,90,71,ED,CB,5A,71,32,34,43,CC,C1,E8,B0,30,61,09,C3,BA,05,79,A2,9C,9A,74,2F,D0,6D,29,47,85,9A,A9,55,B8,B5,FD,39,D4,DE,A5,36,CF,60,9A,39,69,B6,C5,F2,4D,AF,E5,3C,F7,FA,0A,93,AB,3D,D8,9A,54,B6,2B,6E,01,83,23,98,7B,11,9D,97,B2,12,DB,F6,0C,FF,FE,AA,4B,15,64,E2,5D,F4,25,84,38,57,9C,CA,1A,CD,7F,D3,12,A4,25,31,56,FE,BB,EF,F4,37,BA,8D,0E,17,C6,D2,29,14,55,08,DC,BF,61,ED,DB,1A,AF,91,FB,C8,60,99,48,87,21,16,FF,B5,48,79,B8,04,25,E1,55,D4,D0,04,88,D3,A2,3C,16,C1,54,DD,D8,33,F1,6B,BB,1D,8D,6D,A0,8C,26,CC,BD,89,36,9A,BB,1B,83,FE,42,B1,A5,8C,C2,69,45,F4,49,D6,3D,03,62,1A,91,04,AC,96,FE,4B,68,6B,D1,EF,06,A7,82,24,76,BE,22,96,4E,36,C8,CC,D4,4E,B6,6F,9D,47,94,BE,C9,14,80,76,96,FA,1F,40,A0,8E,AD,86,69,93,38,F1,85,54,EC,BF,B9,F6,5D,61,40,22,7B,2B,90,C1,2F,E2,0E,7A,64,3A,24,64,76,46,9C,96,1A,9E,69,C5,E3,35,75,B1,97,5E,45,B8,43,32,22,7F,9D,21,10,3D,9A,39,15,BB,2F,EB,88,5E,C6,38,C0,D1,3F,AA,CF,B7,CD,73,37,12,A0,56,B5,E2,7F,40,75,2B,18,54,D2,F7,4A,D1,15,62,D9,F1,1E,59,12,5E,F6,19,47,AD,73,9C,AB,A8,15,29,ED,DF,96,F1,E9,A2,6D,AB,17,DB,44,1E,78,D6,F7,0E,0E,5D,5B,E6,9B,A7,4F,86,42,9C,5B,93,95,41,9A,CB,C8,13,14,3C,84,F2,34,03,0E,A7,2B,79,81,95,EB,F2,22,3F,AF,92,15,AF,D2,A4,CF,80,27,ED,9E,00,84,A1,05,55,2D,50,43,5C,10,B3,19,8B,6A,8D,91,84,4F,E6,66,8A,CC,83,C6,D1,7F,99,AF,66,16,D1,EB,FB,C0,6B,57,6F,F8,F1,F0,B4,4A,27,EE,0E,01,67,49,65,04,FE,40,48,9A,2B,19,C2,38,7F,A0,9B,6F,74,BB,9E,E4,24,44,63,F4,55,70,DA,1E,7A,0D,04,29,B4,14,34,CC,83,11,C5,C1,50,B1,7E,40,6C,D5,87,25,21,7F,95,F0,F4,F1,0B,EA,DC,48,97,3F,37,73,A5,1C,F0,1E,89,C0,05,3D,F3,28,11,82,51,02,3F,B8,F3,3D,D4,B1,4D,86,B7,48,9B,00,BA,7E,C5,0A,5F,D8,A2,BC,BF,DB,AD,2E,DB,C7,F2,6E,CC,60,AD,23,45,5F,0D,B2,10,91,91,E4,49,7F,47,13,E3,84,9A,CC,A0,19,82,58,8B,A1,87,52,09,44,54,B5,8A,83,C7,9B,D0,21,C2,64,0C,A4,67,C3,DD,E2,36,0E,38,FB,DB,50,FD,0A,DF,49,EE,78,4C,B6,9D,50,C3,9F,78,13,70,18,D1,8D,45,11,45,52,60,94,2C,A9,EC,22,73,65,E1,AF,12,BF,B9,76,42,AA,FF,A4,DC,08,02,4C,5C,7F,02,24,66,CD,D6,D9,3D,79,98,D1,8F,72,E3,3B,91,8E,64,7C,30,5F,D4,E5,F2,53,B6,26,69,D9,FD,D3,7A,5F,E4,2E,7F,6D,8E,6E,7A,F0,56,7D,4F,B3,51,4B,EB,90,6D,06,F5,B6,E4,7F,BD,DB,EA,E5,46,5C,40,71,84,39,A0,A5,D3,81,48,BA,95,48,13,22,1B,D1,7C,13,EC,FA,16,4E,A5,A5,2C,B6,BD,B1,0C,E4,70,18,72,D3,A3,E7,E0,00,48,88,EE,C2,3B,67,ED,A6,7E,43,CE,59,FD,18,1E,F9,2C,A5,9A,1E,61,F3,03,08,9D,0A,C6,98,6F,43,26,D8,94,D1,5B,7D,30,7E,5C,56,06,3D,62,53,3D,06,56,7F,E7,56,80,AB,E6,00,9A,CB,1B,89,39,BC,E5,7F,4D,A4,FC,57,31,BA,99,27,48,19,AF,08,A4,2B,79,AE,34,0B,91,95,19,F2,84,F7,C9,47,BE,00,59,5C,A1,EA,2C,DB,3F,BD,FE,3D,FB,4C,FF,C7,74,A7,EC,42,47,11,95,0E,30,24,6A,61,7F,3C,4A,95,42,3C,52,EA,62,5B,07,A7,6F,BA,77,3D,3C,EA,58,F5,4C,06,EC,74,63,A2,9D,AD,3C,FF,B4,31,91,6C,DF,22,01,0E,68,8E,FF,4F,AB,2D,07,03,7E,9D,81,AA,9B,59,BE,62,C2,B8,49,32,71,68,B8,17,DC,B8,3C,E8,40,D4,D2,94,62,78,0A,01,29,32,BD,AF,3D,3B,96,9C,B2,AB,D3,40,13,F3,FB,3A,1B,42,BA,24,92,7E,E7,00,DC,23,3F,FF,EB,D7,AD,CC,28,60,07,06,5F,E5,9B,8C,94,66,64,6A,CC,46,18,CC,3D,FE,4E,D4,E0,63,99,D5,86,2D,08,3E,5D,CC,4A,71,8A,17,4B,08,97,F2,51,AF,3D,D7,35,CF,DA,DB,0D,08,34,80,2A,D4,B1,E9,93,BB,86,C5,9F,F2,5B,ED,41,E4,00,BA,52,1F,FB,1A,12,13,82,2C,3C,5B,24,54,9B,1F,B9,49,8B,BE,CC,2B,95,DD,8E,91,80,8D,96,BA,D5,F7,E7,AD,8B,D9,30,6E,C4,CE,61,26,A0,90,99,4B,66,53,98,0A,96,F4,83,53,D7,71,28,9F,01,35,0A,3A,B6,6B,69,DC,EE,0A,DD,F6,7D,33,43,89,2D,FB,E8,7C,E5,25,DE,CD,3D,54,FE,66,F9,E5,DE,7A,01,13,94,6C,04,59,8A,94,C8,06,D3,6C,07,0F,7C,4B,5B,CB,F1,0F,D0,66,D0,73,B9,F1,5C,F0,4E,10,24,8B,4F,73,B9,24,8F,D4,57,0B,CD,00,1E,32,25,40,72,0F,55,E4,97,3D,60,63,70,90,FA,42,AB,3A,DD,40,4D,75,2A,13,3E,C9,C5,11,A1,E3,B7,0D,C8,4D,82,7E,24,6E,41,1B,E0,0E,27,E3,79,1D,B9,ED,53,70,6E,5A,DF,C6,22,37,E7,57,9D,FE,AB,88,48,06,38,B0,4B,21,E1,36,77,DA,FD,42,2C,D7,55,9A,EE,BE,B6,5A,D2,DB,F2,EF,AA,12,3A,9E,35,65,7B,EE,9B,A7,83,E6,B4,41,1B,E3,C4,31,8F,8B,C5,79,93,54,29,3F,5E,8B,C3,91,E3,0B,FE,A1,67,32,C8,41,D1,46,57,E8,F7,0F,BD,56,47,B8,72,10,94,FC,5A,0B,12,68,8D,54,EE,5D,57,C3,99,42,1A,9B,64,04,80,CD,17,D8,5D,21,A8,F3,61,79,9E,0C,49,D9,BC,C8,8B,88,43,31,E8,84,F0,CF,01,5A,A9,B4,26,6D,D4,64,B2,04,7D,01,0D,DA,4A,3E,0E,E1,2F,79,2D,BA,9F,DF,85,59,DA,F2,2A,8E,9E,C1,CD,AE,48,E7,C3,31,E0,56,F9,24,B3,F8,3C,0B,AC,DA,12,DE,FF,4F,36,22,F8,6F,5E,65,09,F9,CF,F9,3B,C5,9A,76,62,20,61,14,F7,28,0E,82,AF,7D,10,6B,C6,85,63,14,CE,9B,2E,81,58,E4,26,0A,61,D7,1E,B2,14,04,BF,EE,E8,4F,21,D8,4A,C4,75,35,E9,88,FF,86,94,25,CB,37,47,D6,23,04,F7,E3,5E,C2,6D,EC,E4,F2,8A,03,08,2A,6E,C8,D3,43,BA,E3,DB,2A,B9,CF,0F,1D,D1,F3,56,70,1A,88,4D,DA,0E,B4,70,AF,FA,24,7F,7C,62,A9,5D,8C,E1,22,32,A5,1C,A9,76,31,21,36,33,84,5F,52,37,F0,AC,44,77,73,60,11,29,45,3A,A1,67,0C,13,48,5C,FB,46,22,1D,01,A8,BB,94,D3,A9,30,E0,CB,BC,17,C3,5E,20,B2,A6,FF,5F,F2,9D,AB,CF,6C,A1,57,A5,AE,34,02,CE,6A,46,BC,5F,83,6D,90,A7,E0,A2,5D,12,B7,F9,19,C1,51,96,3C,53,02,68,EA,BC,0A,4C,57,BC,2E,BD,37,DC,3D,D3,5E,55,DD,6A,72,5B,9A,C7,E0,5B,6C,49,80,C8,EF,DA,11,BD,E7,BE,2D,8F,9A,E1,F0,38,1B,02,7A,74,32,CC,98,68,CD,F8,2B,65,CE,C1,F2,9B,73,E1,95,E3,AF,2C,5F,05,E6,52,67,6B,78,AD,D3,0B,9F,4A,88,8B,9B,D9,0A,3C,6A,06,52,99,FD,0F,84,20,37,F8,55,E7,22,13,F2,7A,D3,2F,9D,8B,BA,75,95,92,77,B8,75,89,48,73,F7,2D,B7,EF,69,18,6A,48,C2,60,C3,92,F6,11,EA,53,49,42,BA,07,68,BC,66,32,8C,D3,D7,17,EB,C1,CC,9A,C3,11,E0,31,7F,D0,74,BF,13,3A,02,26,B4,DE,9C,84,8A,07,57,00,72,9E,26,62,57,ED,E7,8A,09,8D,E7,3B,D5,2C,9A,08,2E,C5,ED,A1,28,81,6A,B0,B4,D4,63,BF,FE,28,B7,34,7D,66,71,16,FC,A1,F0,F0,9C,2D,EA,C5,1D,6C,20,13,0C,60,0B,C3,27,2B,21,B5,A5,CF,21,68,00,6F,B9,D8,51,3E,2A,43,DC,96,5A,15,07,43,88,D8,94,A4,AF,EE,9E,BA,3D,19,67,A1,2E,15,0C,71,AC,60,53,35,AB,DA,E1,AF,F9,51,9E,8F,58,50,C2,BD,73,AD,74,EF,6F,F2,9E,11,8F,A2,1B,AA,E6,77,C9,67,F1,6B,70,C0,72,86,FA,70,DD,7B,DC,54,21,30,98,32,8C,09,BD,CE,13,69,30,26,CF,48,D5,E7,19,F6,8B,5B,4D,A9,5B,E3,D3,BC,DF,F2,A9,4E,81,A1,A2,A7,49,3B,E3,9D,24,06,CA,23,E4,25,23,05,7A,AE,62,9C,22,C2,80,77,BA,42,4A,B7,27,CE,22,C1,2E,56,A6,4C,37,F7,32,35,FF,78,07,E2,51,33,18,79,72,23,28,8C,04,9C,DA,24,26,4D,20,0E,7D,1E,F5,C3,C0,3D,BA,FE,00,16,CF,A6,57,96,EE,00,B5,7F,1C,CC,B4,24,16,7C,07,E3,F7,71,FC,F6,08,88,49,50,FA,AE,C5,6D,1A,EF,CB,26,DC,2A,21,72,3E,76,94,7E,B6,41,48,3A,B6,43,88,2E,4D,55,6E,63,DC,E4,80,20,A7,9D,19,B1,83,66,0C,B8,11,38,25,92,99,7E,01,4A,64,4B,96,39,44,E5,3D,78,CB,83,8A,D8,66,8A,D6,A5,C4,58,94,BD,FB,81,70,86,D8,78,66,A7,9B,99,B6,BC,B1,54,3C,9C,79,AE,87,91,8E,F8,EB,C1,58,20,33,24,93,BD,90,FA,95,1F,28,26,48,85,6C,3B,51,57,0B,37,EA,9E,33,B7,75,55,81,06,2F,F4,A3,53,12,1F,4C,A1,46,C4,B8,D0,81,51,D8,01,60,BE,BB,E4,14,03,17,07,D8,BC,41,EA,70,82,31,4C,84,2E,17,0F,61,C6,93,1D,FC,06,50,66,C5,7D,80,32,FB,9F,04,72,4E,41,42,61,2A,16,84,34,EA,15,F8,26,E0,74,A2,B9,3B,D6,38,F1,6B,C8,40,AD,EC,09,F9,04,3C,08,B1,4C,87,AA,1F,95,27,ED,CF,53,86,DA,E9,DA,2E,F4,08,53,87,D8,AE,07,B0,9D,42,C6,9E,B7,2F,FB,EC,5A,4D,3F,F4,39,30,B8,07,40,B3,C7,D8,D7,03,32,81,FD,D5,7B,FC,E5,C9,1C,88,BA,5B,DA,37,47,D7,4B,9D,D5,80,E8,C7,54,90,04,93,BB,56,64,ED,50,07,E4,BC,16,88,22,88,71,44,0F,A9,FF,EC,1C,B9,7D,12,9B,F7,38,5B,A9,D6,D7,56,41,F2,76,AE,6F,61,67,41,AA,B8,23,B4,B0,B2,31,F2,56,55,E1,8F,1B,F2,5E,E8,D5,ED,91,DA,F4,DA,AC,8D,CD,FC,86,C6,B2,FA,8F,5D,86,CC,09,31,1B,BB,59,B4,CA,61,A0,62,08,8D,3A,44,5E,2E,E4,38,67,28,0F,F7,E2,AC,E1,6A,92,97,3F,CE,7C,0F,86,42,4D,F2,78,32,2D,08,22,8B,D0,3B,2D,1F,FD,34,63,81,6A,13,B4,F5,85,70,29,E2,79,E8,68,6C,1D,0A,72,46,1E,10,C6,31,B9,2B,67,58,EC,63,38,84,55,DB,87,16,3F,EC,7F,E2,8E,18,F8,6A,5C,17,2A,08,41,0C,DB,B2,A0,65,BD,8E,31,CD,8D,8F,AD,0E,7A,CF,18,9A,19,BC,1D,62,A0,D0,00,03,CF,C1,48,A5,3B,82,9B,C6,1F,4A,2B,0E,AE,B0,3B,A9,3C,44,72,5B,5A,EA,5D,C9,9E,F3,45,80,A6,85,86,5F,83,85,83,73,62,04,E7,E5,C1,A0,8F,4C,E4,D6,EF,D4,FD,20,49,F5,76,21,F7,1F,8A,CA,82,7F,4C,82,6C,0E,B1,9E,F0,D1,C4,6C,84,C4,CC,86,4E,7A,69,C7,DB,CF,6A,61,73,F4,79,0D,61,EE,59,C1,2F,E9,3A,13,B2,30,1E,26,1D,EE,75,1D,F9,24,AD,81,04,8A,8F,F8,A2,38,B9,4F,E6,6B,D6,7D,9D,50,A8,DE,E1,96,1D,C0,DC,BD,D1,1C,E5,73,B4,4E,E5,89,C1,63,E9,DB,33,EB,D8,27,4F,DC,66,22,55,DA,D9,BC,12,CB,36,61,27,9A,2C,98,89,24,65,DE,FB,7C,7B,6B,EB,A2,35,72,8F,6E,71,AB,2C,79,94,A6,CC,CB,36,FB,69,E8,99,AA,A6,6E,3E,60,75,CD,DF,88,B3,6B,5A,C1,05,06,A2,B3,1E,D6,85,53,3C,16,2C,15,75,83,42,92,E8,2F,81,B6,A9,46,A6,CF,6C,80,F2,7F,FC,C3,35,5A,D4,EC,C0,C9,0E,4C,E0,E7,04,BB,97,EE,01,B7,24,D6,08,24,B3,62,1A,16,D5,73,C6,A6,99,35,64,F9,57,F9,60,FB,29,9F,A2,7E,71,FD,5D,93,34,41,44,42,46,E8,AD,E1,4D,E7,92,86,CC,1B,0F,D4,C4,5D,F0,12,22,2A,05,B2,C9,EF,64,9D,E7,D9,DC,87,B0,B2,EC,F5,60,94,DA,EA,F7,7E,11,A2,55,44,87,A8,83,14,E8,40,16,6D,03,4F,56,68,58,98,59,95,9F,9E,A3,37,5C,28,90,C6,B7,45,E2,E7,F3,15,32,8E,37,D1,AC,5B,56,79,CF,5F,FE,3B,3D,C8,FF,E9,7A,6A,F3,D9,DE,D7,2F,00,80,8C,50,A8,0B,00,68,02,41,AB,9A,58,E5,CD,E3,54,A8,8E,E8,4A,70,36,BB,5D,E5,02,2E,D2,56,FB,46,7A,8F,24,68,97,E4,57,BD,FB,D5,8A,7A,C7,A5,E8,89,3A,45,3E,3E,98,70,44,7F,05,24,AE,1A,2C,D8,49,1C,0D,BE,1A,E0,95,BC,DE,C2,3D,C9,FB,98,C5,A7,13,AB,26,DB,59,7E,AB,D6,D6,27,B2,E5,AD,27,5C,DE,8C,D0,56,FE,95,E3,BF,75,72,A5,27,20,A6,54,6A,54,14,32,69,01,48,6B,8E,C9,BB,1B,DC,AC,96,EE,15,6E,32,DB,04,2C,04,8C,C5,1F,9F,C7,08,CF,63,4D,30,08,ED,4A,A3,55,D9,34,57,2C,0C,D8,F0,58,3B,69,28,37,5B,C9,E6,FC,0E,59,0A,33,EF,06,C5,F8,34,8E,03,59,23,5A,A2,C2,58,F2,5B,FE,D0,79,45,3E,AB,E1,8E,96,10,D1,6E,C8,A1,7E,EF,B7,0F,51,39,8C,94,95,07,B9,94,E1,5A,33,E1,7D,CC,64,0F,67,1D,4E,CC,FF,EE,DC,70,D3,5A,5E,5B,DA,46,BE,8B,51,F6,F4,27,18,90,B1,26,14,EF,3B,F5,EE,57,AF,FF,8F,A4,D6,88,3B,B9,30,43,0E,27,19,A3,C3,4B,DF,C0,1A,BB,88,CD,79,FC,57,38,D4,B7,72,D5,CA,38,D4,05,A8,68,0E,46,36,85,D2,F0,E7,A6,BE,92,A8,FB,FB,1E,E2,3D,4F,98,A0,02,9F,25,17,01,EC,F3,D0,91,3F,76,0D,56,6B,2E,5E,F0,89,86,C8,00,E8,1E,71,80,15,A3,7A,07,E0,03,36,AF,81,EB,77,81,3C,AF,33,26,B0,1E,B9,2C,C9,86,BC,4A,C3,E3,5D,15,AE,62,3C,A4,4B,42,19,92,FC,C2,D4,AE,26,D7,74,47,91,E5,F6,EE,0D,0E,F9,E2,B4,49,0E,83,63,A0,B1,75,98,19,87,E9,04,49,48,79,82,10,DE,70,F0,C6,DB,46,3A,85,4F,C9,38,70,44,D0,58,00,5D,EC,A7,4D,E5,1F,E0,90,E4,E1,6E,4F,FF,2D,90,1E,CF,38,32,55,0E,7E,FE,90,36,C4,68,0B,D8,34,EA,18,B9,7C,79,84,23,A8,46,7D,C7,C9,EC,F9,FC,A7,28,6E,4F,B9,5E,95,53,0E,D9,73,75,C2,3B,0C,D9,08,01,E0,2C,5B,BF,75,E1,01,7C,DB,96,78,95,69,45,15,22,4F,3E,43,E0,71,21,87,3C,B5,5E,02,15,CC,6A,98,09,47,AD,9A,6C,AE,DA,4D,5C,E3,FB,BC,A7,83,B7,F5,92,4D,22,57,67,64,2E,A1,E3,0C,3C,E5,89,5F,69,8A,E0,CC,92,F6,15,5C,0C,CC,1D,0C,D2,2C,6C,DF,F7,F2,7A,D6,14,8E,93,10,5C,56,C5,D2,B7,6A,F0,EE,ED,77,97,A4,E0,D3,B4,D1,53,4E,B0,D7,09,42,FA,51,BC,51,BF,48,D1,27,F3,A4,54,8A,66,7B,9E,90,6A,C9,20,89,CA,5D,38,B7,45,0B,7D,7F,8F,95,70,34,F6,BD,BC,DB,0A,B4,67,0F,61,3D,B2,7C,74,1C,EB,3B,F1,FC,A5,D4,47,3B,5C,CC,72,2E,DD,57,39,74,DF,B4,E7,5D,1D,71,6F,8A,45,26,40,63,E7,DA,12,86,E2,B9,D8,22,EE,CF,E0,43,B9,CF,61,71,ED,10,28,74,A0,D3,54,EA,26,91,40,06,91,89,4B,5A,D3,16,B0,3A,58,59,5B,F9,59,51,60,04,D7,29,F0,5F,07,27,0A,6D,11,56,74,FD,DD,58,89,FC,BB,D0,CE,0C,6F,1E,B6,85,14,63,2A,99,DA,ED,89,B2,0F,20,5F,24,FB,C5,EF,95,9C,26,6F,49,9C,4D,2D,1A,4E,E3,D0,B5,7A,E7,25,23,66,D4,18,48,40,A0,7C,43,0C,DC,D1,8B,C8,02,38,AD,E1,A8,67,EF,F6,6C,4B,EA,50,4F,DF,82,11,A6,F6,2F,12,54,8A,D6,13,6A,96,0C,7F,76,63,23,10,E2,2D,D3,9C,F8,FB,98,1A,7A,54,21,AA,E3,B8,26,68,2A,7B,1B,5A,4A,CE,12,60,7A,D3,70,E9,EA,16,C5,10,0D,97,89,89,2D,08,0F,B8,F0,5B,89,D6,E0,86,B3,1E,E1,A0,12,0C,F8,A9,79,14,71,43,C6,0A,F3,92,61,86,91,49,FB,8F,F2,BC,07,EB,6E,A6,91,24,6C,BC,7C,E1,83,79,78,93,82,1F,1D,9F,BC,40,D5,0C,EA,4B,F5,E5,96,F3,42,7F,15,2B,24,72,D8,08,2B,CD,94,1B,52,DE,54,B1,95,81,8F,E3,34,69,B4,31,B9,CE,9A,F7,8A,A8,49,45,E3,5E,E2,68,ED,DB,8E,E1,94,5B,D3,98,B1,57,74,D8,F7,10,6C,60,6B,79,0C,0E,87,44,2D,60,DE,9F,33,5E,3C,3A,FA,B4,CE,57,C3,D5,88,08,E0,35,57,3A,B2,30,7F,3D,29,3F,43,92,1B,35,BB,3B,B9,84,93,A0,CA,9B,52,C5,C8,8D,C8,22,80,95,3A,9F,33,DC,78,F8,0F,12,1C,A3,52,F5,8D,57,4C,D5,E8,76,83,EC,FB,A4,29,6E,3C,EE,C8,7B,CD,C1,85,CB,D4,AF,A1,AC,78,6C,48,AE,C8,2B,4B,05,7F,DA,28,0D,D5,B6,06,32,8A,C1,8D,6F,F6,E1,96,6D,E3,82,18,93,E3,45,19,D1,98,8B,67,47,CD,FF,A8,BD,00,24,88,F0,75,1D,86,2C,21,9F,89,15,F7,9E,D1,7C,83,3B,72,58,40,7D,E1,36,05,6A,F3,03,C6,6A,05,6E,B4,80,9E,16,01,B3,49,C9,AE,A1,89,A9,5B,64,8A,45,83,04,62,63,94,32,A4,E7,EB,9F,5C,8C,3C,42,77,82,03,AF,E4,63,8F,65,D9,B6,55,3C,2F,C5,B0,32,AE,39,9A,13,F5,43,3D,71,FD,83,AD,47,E7,4F,4E,B5,18,83,AA,2B,A7,31,48,75,61,B4,28,1D,D5,66,4F,56,23,25,AB,AA,B2,2B,0D,0A,26,63,3E,57,1D,A5,4F,38,57,58,BE,51,89,A2,6F,97,09,63,A9,E4,75,D9,E6,18,D8,92,64,3F,9C,01,B5,68,D6,A7,5A,8B,38,06,95,75,29,76,CA,3B,F4,28,8C,46,FA,8E,14,42,05,AF,DB,9C,D0,64,E6,28,D4,0E,30,0C,D9,25,EC,3F,60,CA,59,17,55,82,FE,7B,84,FE,FA,76,E3,62,46,E1,F6,53,F5,B2,46,18,D2,C2,6D,9B,03,01,CA,3E,C9,AC,65,F4,85,C7,15,6E,88,30,F1,D6,BC,15,55,2A,7B,A7,51,38,8F,6A,CC,E9,F5,04,20,3C,1C,51,EE,94,EB,9A,39,B6,AE,FC,E7,66,16,73,66,E7,D4,17,64,15,4A,B7,D2,EA,B4,68,91,D0,7C,F7,14,7F,BA,C4,17,C0,F9,0A,CE,1E,A0,42,39,D7,8B,BC,1B,D5,C8,3C,C5,C6,90,85,3A,35,51,B9,45,EF,CA,69,AC,91,8F,8E,48,50,63,8D,29,58,8F,6F,F6,F9,E2,07,D1,C9,3E,D0,DC,C5,D7,6C,16,8D,64,5B,A8,D6,0E,22,0D,C7,1D,B4,A6,7E,65,EC,D2,15,16,46,9A,CE,AC,18,E9,E2,1F,2E,3C,0D,3A,97,D4,07,D8,89,DE,BF,28,F6,39,29,E8,46,47,F5,F4,D0,18,08,BA,B1,6A,ED,3B,BB,CB,84,60,25,77,50,D6,75,09,91,93,A2,F8,2F,E1,20,8A,D2,BC,13,0E,78,DA,3E,29,38,D8,8E,F0,EE,60,FE,C0,76,2B,8E,D5,83,E1,59,BA,D2,11,90,16,F4,56,DD,39,A9,9B,A5,44,77,6D,FB,2E,6A,E0,ED,1E,37,53,C2,2B,F0,8C,69,46,55,01,F7,78,32,25,05,CF,FE,88,1B,FB,91,90,4B,C9,D3,61,39,C6,42,1A,89,19,B8,0D,66,6A,54,55,2E,0F,35,2D,7F,13,32,7F,0D,77,A6,A7,30,1E,FB,D5,B4,8F,83,72,91,C4,27,AB,42,37,5E,7E,E8,78,60,17,B3,63,B5,78,07,EB,45,C4,31,D6,50,D1,BF,2D,70,52,7F,DD,0C,8E,36,8F,F5,4E,CA,1B,AA,E9,1D,34,72,76,AA,7C,62,3D,CC,08,6C,D5,04,E4,25,D1,5D,C1,5A,83,90,57,44,C7,65,84,68,E4,31,1C,F0,78,5E,D7,E1,96,8E,3A,D6,C9,B8,32,13,CD,1C,BA,C4,6B,21,86,59,63,61,C8,DF,4D,FA,21,23,12,99,BD,F5,C6,50,D9,C5,23,DD,5B,82,66,F3,DE,ED,0C,C6,3A,90,2F,22,98,6F,25,00,BC,F1,83,9E,5B,03,D1,54,30,22,A6,3A,C8,C7,D6,F4,92,43,04,CC,C7,14,61,92,8E,F3,91,03,9B,8F,56,EC,79,AA,79,BC,88,AF,B2,0C,43,AF,8E,A1,75,4E,50,F5,DF,62,12,C7,61,A6,BF,6C,1D,00,3F,BA,E0,56,39,CA,86,F6,E8,A4,5E,92,69,87,D1,ED,6F,C4,6B,76,2D,15,74,13,78,31,53,25,E0,B0,B3,C6,55,BC,E6,FB,55,E9,87,F4,D9,E8,83,5D,20,11,95,CF,D5,DB,28,00,ED,62,D7,BE,14,C1,12,24,F8,2F,47,5A,6D,68,CD,0B,CA,D1,E4,93,A5,D9,92,58,5D,FE,C4,D1,A3,8D,61,A6,C1,26,28,15,87,FC,E3,FB,4E,97,87,E0,55,CC,30,C0,76,81,76,69,EE,62,3A,41,5B,AD,EF,B5,17,D6,33,99,F2,8A,9A,22,9C,D7,FD,3B,EC,9C,33,63,29,2B,7F,3D,00,2E,94,F9,42,08,98,A7,19,5D,80,BF,71,0A,51,4C,A0,52,CD,AC,12,F9,BB,3A,D6,9C,AC,07,7E,0A,92,B4,C0,5A,FD,35,39,40,1B,39,6C,A9,91,5E,E8,6A,A0,84,51,57,24,8B,CA,E6,AE,54,61,0E,F1,84,E6,B9,36,B8,43,4A,8A,A8,CE,C6,96,85,8A,A8,56,FB,4F,4E,FF,CC,F3,41,95,87,CA,02,E8,39,7D,F1,B0,59,E0,07,DF,84,0B,1C,22,60,47,38,7B,2C,65,41,C6,A2,10,B3,0A,A4,29,E2,E4,CA,3E,C3,B5,21,CF,22,FB,2F,4B,57,92,C4,FF,22,FA,3F,2A,52,CD,D6,C9,96,2C,CB,23,1B,AA,EC,C0,19,F2,66,DF,8C,8F,18,45,F3,21,D3,DB,B9,A2,A6,25,EB,69,66,60,14,1A,F6,95,F8,E5,A3,3B,B0,B0,4E,5B,8B,7B,D8,B9,62,FF,40,2D,F6,97,E4,AD,74,50,5B,7C,A0,68,18,4D,B7,A8,A3,0E,F4,4F,80,6A,40,D4,FD,D8,F2,49,7B,67,3C,76,82,CD,55,3E,F9,96,57,C1,7E,B0,F9,B7,AE,7D,CF,83,A6,5A,71,5D,A0,10,2E,0E,84,4A,D0,B6,C0,A2,E0,C2,83,52,EA,CF,0D,77,81,79,64,01,1A,B0,14,21,B2,BA,92,B7,A3,B0,99,EC,A5,A8,05,70,66,D9,E7,F2,50,53,10,8F,55,B0,0B,28,A8,19,D8,D5,1D,81,36,4D,7E,D5,EF,1E,E0,CD,C4,46,23,AB,04,DF,50,99,53,20,91,AD,8F,38,11,CF,A0,56,CA,D2,49,9B,85,FA,6D,9D,3D,FC,2C,02,23,64,91,85,34,3C,34,52,42,87,E3,A4,14,26,4B,D0,A4,BE,53,34,CF,CC,86,13,32,DD,68,A1,4D,91,5D,F4,3B,10,C1,78,21,8E,F2,4D,94,A4,E1,39,92,7F,29,FE,52,B7,A3,E4,96,1F,4E,96,5C,C0,1D,EC,3F,71,DA,AF,56,A7,5B,0D,7E,A0,C5,D5,38,6D,39,BF,11,2D,91,98,74,DC,51,C3,8A,8A,3A,71,F0,1D,21,F4,31,7C,A9,67,73,04,97,13,59,11,08,A9,7D,01,5E,F7,BB,94,AA,0B,6F,2A,7F,5F,1E,3C,11,52,98,63,28,8F,88,A3,D8,06,C9,A2,54,0C,E9,C1,09,35,0B,D0,59,D1,18,1F,A0,F9,3C,02,AA,E7,2F,13,9A,4B,B9,16,22,8B,DF,22,3E,DC,A3,E5,D8,E3,02,2F,B4,D1,5E,8F,47,F2,66,AB,9E,1D,8A,57,84,46,D0,1C,07,A8,BC,0B,AB,76,87,2C,B5,50,77,F8,ED,33,72,72,F6,96,DA,C3,A4,40,6F,5A,9F,4C,03,7A,3D,42,1C,8F,7F,5B,98,C9,D5,A1,34,24,DA,51,64,B2,06,D1,AA,8A,92,D9,0D,6A,9F,BF,70,FC,0C,FA,10,95,17,07,BB,29,B8,65,07,D6,44,7D,01,93,89,AB,6A,61,CB,1F,BD,7C,E3,A0,24,41,12,1D,3D,32,46,43,7B,3E,10,05,1D,19,37,A3,1A,7D,6D,04,4B,8D,08,AB,5E,E1,DC,95,74,C3,39,5D,58,A2,77,2F,53,7D,F4,21,78,9D,3E,BD,C3,1F,02,FA,C7,D0,BD,1B,59,0F,DC,35,35,C7,B4,43,15,48,BA,5B,63,C3,B7,4D,66,4E,48,CF,38,8F,14,DE,45,6E,60,20,0E,FB,B5,43,84,02,22,9F,69,06,FA,85,9A,0F,23,29,22,43,5B,16,32,68,5A,81,8D,E4,0F,7E,86,91,6F,E7,4B,1C,66,3F,6A,59,5F,CE,09,C8,16,F0,32,57,15,F4,BF,2F,5B,3F,07,08,8D,2D,42,7B,4B,22,1F,FD,D6,70,E4,35,7D,AD,48,B1,41,51,04,23,F4,31,5D,EE,49,55,21,3C,C7,A7,C9,0A,BE,0B,EA,EA,5F,9A,D1,36,33,6A,51,6E,61,AF,3E,C7,81,4F,09,50,42,19,97,D4,C3,E6,A6,1E,DA,5C,B0,F3,2D,8D,C3,BA,07,52,14,5C,82,D8,E6,2E,0B,13,79,E1,13,AF,5C,B7,C9,49,E5,A4,E8,F0,34,94,7B,3E,71,57,3D,2B,00,66,06,68,D5,19,8A,54,A6,58,11,47,63,9C,24,F7,0F,37,E6,13,28,A0,61,FE,E6,AE,9A,CD,49,ED,EC,24,1B,7C,F5,F9,0B,BB,52,85,BD,15,D8,EE,14,B5,DA,73,4C,2A,58,36,E5,9A,37,5D,8B,0F,C2,96,1E,94,4C,4F,15,68,FA,D9,A2,72,93,77,59,1B,08,F6,93,0A,64,A2,F8,8E,A0,AB,C4,4E,34,08,D8,87,DF,A7,0D,F2,12,10,72,B3,CB,00,DF,F7,79,0D,0B,AC,43,6D,82,34,4A,C4,46,BA,9C,B7,02,EB,24,52,1A,CC,14,B0,45,64,38,A8,A8,DA,2B,3F,28,3E,2C,71,D6,1F,1F,4D,F1,3A,51,85,61,B3,35,97,F7,08,BB,40,67,D4,20,9F,08,2B,F5,75,AB,6D,6D,C0,6D,CE,7B,08,B8,8E,A6,12,E1,09,CB,28,B1,BE,A2,17,C9,A6,09,FA,B8,51,D3,3D,79,6D,4C,32,82,08,A8,03,99,54,2F,70,DA,92,AB,BE,C3,CB,09,8F,47,A7,8B,8E,7B,1A,BB,E8,22,4B,5E,D8,C9,D0,69,9A,08,26,3E,4D,01,5E,7F,C1,95,E3,69,45,59,10,08,34,A8,DB,DB,99,2C,D5,C2,63,4F,AE,A3,95,A0,8A,3C,03,10,5B,1E,10,6A,5F,1C,9E,2C,45,8C,64,D4,8F,EB,7B,D9,4D,25,EB,5B,25,BE,30,FB,CD,AE,59,AC,B4,97,E5,F3,64,7D,2E,21,5E,50,A2,DA,CE,2D,6C,D2,4A,69,63,4E,F7,B2,97,CC,D5,53,EE,63,4F,1B,B4,A5,2A,83,D4,00,52,00,CD,CE,C7,52,2A,09,D2,C9,2D,74,B6,3C,9C,E5,41,96,D6,5F,9C,01,8E,81,75,40,CE,7D,58,9C,02,03,54,EE,3E,05,1C,DA,EC,39,E7,51,64,43,51,B0,D2,64,D4,19,65,65,F5,00,56,F8,F9,D8,DF,39,59,C2,DB,9F,5A,7B,EA,95,C2,2C,6E,F6,2B,A1,C8,B9,D8,84,66,E6,3E,E2,1A,F1,BD,97,1F,13,09,08,D5,72,D8,EE,80,72,5F,B6,35,19,CA,66,85,C2,22,ED,66,AF,83,66,5F,15,51,8E,C5,6D,97,B3,59,22,F1,32,29,D5,B6,0D,A5,5A,97,DE,D9,96,F2,14,6C,E9,B7,E2,68,21,8D,EE,21,95,62,BA,41,4C,FF,DB,1B,9B,05,D7,1E,1C,E8,ED,90,F9,0D,45,47,1D,0D,60,6D,8C,CD,15,6C,40,E0,AA,F0,1C,AB,1C,F7,23,67,F2,84,39,14,4F,0A,B0,53,0F,04,21,89,07,D4,74,71,CD,6E,A8,EA,D5,DE,3F,D2,7A,74,EF,9F,23,0B,99,57,BB,46,F8,4F,2C,43,6F,76,B1,7B,30,4C,14,FF,FA,A1,3F,97,EB,7E,7F,34,BA,0B,87,E0,32,7D,DD,FE,93,DB,23,A9,A0,8B,A8,23,E5,BD,15,35,F8,87,B2,5F,BB,D6,D8,C6,52,C9,85,49,20,6F,27,EC,AC,80,D4,BF,BC,92,C0,04,3A,F1,77,8B,CF,C2,6C,08,CD,ED,93,F4,63,04,FD,9F,E3,E4,F3,DE,8C,A1,AE,57,6C,71,02,D4,52,4C,8C,09,1D,32,06,31,57,36,14,B8,11,78,FF,33,75,13,A0,03,FC,2C,30,E0,24,A3,41,06,85,DF,BC,1D,E2,DD,1A,FC,45,0A,1D,05,24,07,54,8F,6B,D6,6F,1F,CA,80,D4,64,FB,58,26,3D,1C,A6,E4,96,28,76,1B,84,F9,00,74,9C,4B,27,74,74,D4,2E,11,CE,0E,36,05,1F,DD,05,F7,28,C9,36,2D,83,AD,C3,75,6C,A1,44,D6,04,B4,97,90,81,BB,4D,58,C2,76,91,84,1D,6A,9B,9D,F3,D2,7B,69,C9,6D,A3,DF,C8,2E,0C,21,1D,B8,AB,ED,49,7B,8C,38,0D,D8,DC,CF,CC,AF,EB,B3,F0,12,70,C0,B7,44,15,74,D4,3D,13,C2,22,C9,5E,34,A1,FD,2C,71,2D,8D,CF,1C,BF,59,BF,F5,79,DA,94,BD,11,DB,66,DC,75,43,12,59,BE,15,1E,90,40,1D,13,29,18,6F,58,4C,1B,68,53,F4,1A,F3,88,FE,95,F1,AB,4B,A0,2A,F9,FB,27,DC,CA,1B,50,4B,68,77,2B,28,25,E1,72,F3,A0,83,45,82,9A,99,EC,DB,5F,06,3D,F5,40,45,88,E4,F5,A6,4D,49,D2,49,5E,94,74,D2,70,6E,56,BE,DC,94,73,E1,7F,39,06,30,DE,36,7B,46,B9,E4,05,DD,DB,7C,A0,CF,A0,37,1F,69,2D,C4,E7,A1,A6,CE,24,04,E1,CE,0D,84,BE,23,B1,7E,E6,E5,63,49,1B,FD,94,DB,14,11,FC,40,8A,C2,86,81,C8,02,F7,12,17,D9,A5,E0,AC,A0,77,0A,40,33,3D,D1,BF,C9,3F,FA,53,73,70,CC,27,E4,7C,E0,0B,3C,54,78,4F,9F,37,0E,7D,11,91,09,83,AF,E6,6D,AB,38,68,4A,66,29,9A,7C,EB,5A,A3,53,85,6B,1D,01,43,51,F5,7B,0D,D9,BC,BF,C3,B5,F9,6F,9E,B0,54,40,A5,AD,1A,3A,6B,51,D2,91,9B,AE,88,12,30,DA,A3,09,51,43,86,89,10,6C,33,D7,32,59,12,A9,F6,91,A3,26,E2,4C,98,5B,62,DB,26,0A,D2,E3,34,2F,D1,5F,C7,05,EF,36,19,14,2C,F1,BA,6C,F1,4C,C3,BD,8F,FF,AD,3A,C7,00,66,32,6E,2A,2D,88,81,85,B9,54,29,99,62,23,69,4F,B1,80,E2,77,25,A5,AD,9A,32,89,84,61,CF,32,D9,8F,F7,A1,F2,1D,FD,01,EE,08,0B,7E,FF,C5,88,69,4D,7F,32,0D,A0,8A,52,E8,D3,17,4D,59,56,5B,C3,82,19,CA,70,BC,20,05,E4,EC,00,BE,9E,40,5F,66,F5,1E,5B,6E,48,E8,46,6D,EA,88,6E,16,75,CF,DE,E0,74,C2,05,7B,6C,67,C6,D2,85,B6,AB,D6,B8,26,AD,57,A2,FC,99,F4,2D,8C,A2,93,9A,59,13,E7,AC,3C,DA,EE,2A,2A,79,A7,64,80,60,27,47,FF,CA,17,B4,74,BB,FA,AD,9C,9B,72,27,9E,9D,0C,01,E3,65,A5,0B,42,65,55,90,66,36,FF,6E,3F,B2,7F,BF,63,0D,53,8D,36,E0,F0,39,D8,15,0F,3E,7C,12,87,B9,7D,3C,94,B8,30,AF,B9,4F,46,99,22,3F,C7,00,DF,2F,22,53,8B,58,FD,BF,B4,C8,B6,DD,B7,A5,3D,C4,64,B2,75,44,E5,D9,DC,7C,85,6F,89,3E,B7,CF,9F,D6,3B,59,6C,28,DC,95,1A,0C,7B,19,A8,44,CD,32,2F,F6,E4,D2,73,64,B3,E9,E1,3A,E7,4D,CA,27,FD,30,A9,BC,7E,7C,B8,0F,BF,02,6B,BE,CF,14,C4,B9,01,A4,03,5E,D0,43,7D,6A,27,03,69,89,93,91,12,F3,4A,9A,B6,AA,E9,E8,21,48,2F,31,C8,F0,AE,93,17,A4,9E,FD,F5,06,1D,C0,AE,24,D5,1A,04,7A,86,EA,3D,89,85,91,D8,97,E1,D1,B6,21,AA,8B,30,7E,BB,C6,F7,19,7D,C6,1C,B8,D5,D5,1C,18,B2,D9,03,41,3B,91,DA,50,8B,18,E3,3F,70,37,AC,7A,93,2A,17,0B,7A,00,EF,DB,9F,EE,22,98,71,13,63,35,B9,98,DE,10,1A,31,D8,3C,A8,A3,C5,B7,E7,6D,DF,A1,54,DE,1C,26,DD,C7,C8,0A,3D,34,EF,12,11,3F,2F,3D,84,E0,B5,04,23,D1,17,4C,F0,48,C1,96,CB,A1,DC,88,61,70,89,C0,A1,DF,FA,94,D4,DF,B3,15,AE,C9,3D,83,55,74,8D,BF,82,2A,6B,84,C8,91,C7,05,BE,D2,54,97,74,26,D9,CA,C7,05,7B,CC,0F,04,8A,05,B5,4B,47,13,1A,79,10,83,4F,FE,87,DE,3E,B8,2D,33,F5,40,FA,37,0C,E2,37,F6,85,7E,11,FD,FD,B1,66,6A,1D,19,0B,88,3C,9C,03,48,00,C1,45,A8,3E,66,38,98,44,B4,6D,25,A6,2E,F9,C0,DD,38,AB,20,E3,2D,6E,D1,E1,0A,6D,70,CF,CA,94,77,C0,EE,CB,72,23,44,58,CF,C2,91,8F,7B,00,36,99,14,5C,F2,6D,19,D0,52,28,B7,C3,39,BA,57,9C,9D,6D,32,1A,A1,73,A9,9A,C8,6D,89,84,E2,E8,98,75,52,8B,68,E7,FC,B3,A2,08,CF,D0,60,5E,D0,0C,E2,A4,C9,CD,C5,06,00,B5,12,3C,7A,1D,4B,E0,97,7E,18,15,08,8B,01,8A,3D,0D,9D,A6,9F,2F,2E,13,D5,90,5B,AC,B1,18,3A,ED,2D,24,07,4D,F2,1A,87,91,F0,F6,E0,89,62,B0,69,06,A2,F1,2A,B3,7C,6E,29,57,0B,D6,BB,95,48,7B,EF,15,BE,FC,3F,91,18,2D,E6,3A,ED,F9,BC,B7,AA,D7,3D,38,A8,7D,90,1B,6C,10,71,55,12,A5,8F,D1,16,D0,B3,C5,E0,7D,84,33,AA,48,CE,5A,49,B4,E3,16,5D,50,40,79,8A,CC,0E,9E,B9,16,14,DA,B7,82,BD,A7,B9,D4,ED,15,3F,D6,7D,24,3A,6F,E1,95,CC,AE,85,E5,31,5C,40,CC,3E,38,17,28,1E,24,7D,2C,3F,96,17,47,E4,8C,CB,0B,F6,6E,CD,D7,14,61,22,6E,0C,FA,4C,7B,EA,88,38,3C,69,A5,01,00,86,65,26,B2,C1,E7,0E,4F,D1,66,EB,9F,07,46,87,C9,36,7C,9B,6E,53,D7,A8,D1,CF,DE,1A,05,F4,47,94,9D,AC,44,C7,AB,C4,03,77,05,4E,3A,8C,9D,02,57,84,08,7C,47,D1,99,D1,FE,F4,5E,0A,FE,B1,9D,49,16,A8,E6,29,AE,F9,FC,54,E2,D4,2E,45,ED,8A,0B,D7,E2,25,C6,D0,8F,93,5C,15,5E,8B,C7,28,56,03,66,25,2E,20,2F,A6,9B,C8,34,FF,2B,F5,44,53,B0,8F,A5,40,AF,34,C9,21,2A,59,FC,52,D0,90,B2,B8,DC,9F,0A,30,08,3A,7A,0F,04,70,6E,1B,5E,29,8C,03,43,2F,AA,90,C3,78,0C,E9,2B,F3,11,BD,BB,9E,68,50,B1,A6,27,A0,03,2A,16,8B,F9,55,68,21,2D,EB,78,FF,A1,61,72,C2,B8,B9,BD,0E,40,F0,D1,EB,45,12,E6,4F,62,72,1C,98,5E,EC,BC,2E,B3,26,00,7D,A7,EB,2A,03,A0,1A,33,0B,97,D9,87,C0,A9,89,E8,C4,75,B1,9B,1B,A5,C8,E0,C2,61,F5,EE,C8,42,65,36,D4,0A,A7,73,F4,83,3E,6E,04,08,8E,E9,54,78,47,C1,E4,59,6F,7B,EE,66,15,F1,66,8E,99,22,48,B3,CB,44,09,1B,A0,11,1A,9E,E5,88,F7,73,D3,6B,2B,9E,DD,B5,AD,9F,58,0D,39,0C,CD,AE,01,4B,FB,C7,2C,F3,5D,B7,CB,EF,8F,15,5A,71,36,32,B1,0B,7B,B9,55,D8,52,C0,28,0C,19,C6,06,05,41,6A,3C,F0,C0,B6,CA,4B,E2,01,F8,4D,CB,48,EB,06,EA,52,CC,A9,3F,07,26,D4,4B,9E,18,64,2C,5E,49,5F,B5,5B,68,20,B4,3C,1B,CD,1B,BC,03,35,37,C6,FC,61,7C,D9,8E,20,37,7F,75,6E,FC,3A,6B,E8,E2,5C,C0,08,83,D4,83,04,97,CE,20,58,09,34,F1,ED,06,A1,8C,87,83,1D,3F,32,4F,74,36,82,E9,57,57,53,2E,FA,DF,3F,F4,68,FD,FA,CF,54,ED,31,7E,72,58,6E,1E,77,05,32,36,BE,5F,6C,48,FE,97,20,21,3E,11,04,76,C6,BF,AF,55,3E,F9,2F,A8,17,D3,E2,7D,B9,42,A0,A2,1C,92,80,00,25,81,6F,E7,89,ED,31,C3,13,8A,08,70,CD,99,B0,D8,D8,16,BA,A8,03,D5,4C,DE,F9,32,D8,54,C7,1F,94,4F,75,E6,F4,2F,6F,57,CC,2E,A9,19,20,F7,37,9E,A8,7A,74,67,45,0B,1F,AC,A7,67,70,A9,17,85,A6,1A,9D,23,E8,66,8C,64,0D,98,DF,98,21,33,2E,65,FD,50,06,82,EC,D5,3E,3F,06,22,25,62,86,54,FE,C3,F4,63,C8,E9,D3,D6,BB,D4,2C,62,7D,7C,95,A6,44,71,32,73,3F,38,05,8E,16,D4,25,85,2A,3B,F2,3E,2C,E4,56,1E,64,02,EC,CD,E3,FB,6D,6D,B3,21,CF,35,F0,D3,6F,44,00,D7,FD,97,F1,50,F3,59,3B,CF,1F,D5,BD,E4,53,86,AF,1C,EF,31,D6,02,EC,40,DC,1D,F8,66,4F,B9,67,1A,70,44,EC,35,73,38,C9,68,E1,BF,55,26,63,2E,14,41,47,5D,C2,CE,99,BB,19,6E,2B,5C,37,7E,A4,B4,CE,32,54,0A,98,4B,0A,A9,AE,4B,8E,C7,41,2D,00,F3,F4,4E,61,16,38,ED,6E,C6,EC,CF,DD,B5,61,02,28,B3,83,63,5B,90,49,15,ED,68,2B,27,88,7E,F1,AB,B8,4A,50,2A,85,C0,F1,30,CC,CA,F3,24,45,E3,FD,6C,0A,3F,5B,54,14,52,5E,80,85,D8,32,C4,B3,D4,5E,D4,80,60,BF,8E,93,BB,26,22,B1,54,4F,72,30,56,BD,0B,D8,6A,95,64,59,A3,33,76,06,59,CF,EE,FA,84,3B,62,E7,11,20,E5,BC,69,D9,65,92,2F,47,72,1B,C1,34,28,06,8C,47,10,62,97,C1,9C,87,DE,F8,6C,A2,2D,CE,6B,2C,E7,A4,C3,34,02,46,B8,79,68,3A,B1,F0,97,E7,A9,B4,3F,43,29,E7,83,B3,B6,85,25,0E,82,1E,19,D3,D9,B8,DB,97,FC,5C,3C,58,30,89,1D,CB,A3,44,5F,7B,BE,D6,65,AD,D9,FA,81,6C,6F,F5,33,53,58,66,F2,3D,78,A0,34,2D,16,11,56,9C,B6,7B,9F,79,25,3D,77,80,85,31,FA,1D,A9,ED,7B,92,34,C0,65,10,4B,3A,55,62,37,09,E0,19,7C,C8,F7,AF,AB,23,A7,48,AE,4D,25,F6,C3,07,57,8F,75,B2,79,EB,BF,5B,47,9E,9C,A8,27,28,9C,6D,D7,93,52,62,0E,D2,66,B8,56,58,63,CE,04,20,79,2E,98,0D,2C,0F,7F,63,13,9D,6E,B0,FE,83,4E,80,EC,1F,98,58,4B,7E,36,82,21,2F,DD,EA,5F,9D,52,B4,CC,0A,CD,EA,15,D7,FD,3E,56,AE,BA,3B,9E,83,E0,BB,CE,D5,60,44,84,E2,AC,04,C7,70,8B,B8,FE,31,54,A0,70,95,AB,E5,27,2A,74,06,F0,71,90,10,AA,3E,8A,A2,35,34,16,BA,AC,63,4B,37,F3,25,01,1F,26,DD,AB,05,B6,C7,B9,3A,F6,BF,75,C1,E9,68,B4,4F,96,B2,3A,78,9D,E9,F0,43,F1,A1,EC,45,F9,82,06,63,23,DD,82,F4,39,60,F3,91,93,0B,AE,49,B7,00,CC,10,5D,4B,FC,33,F7,F8,DD,83,DC,6C,0E,B1,D8,2F,CE,DD,46,A5,73,2E,F1,54,84,C6,4A,3B,7D,C3,16,FB,5D,E2,A5,30,DD,73,4E,4E,A8,21,E1,79,72,52,BE,CE,64,AE,93,A2,2E,06,23,28,43,7C,CE,7E,03,D0,53,88,B7,4F,81,C4,29,CB,4D,AC,C7,6F,2A,AB,E8,BE,4E,82,ED,95,DA,10,81,9B,D9,D4,A7,18,83,9D,64,84,9D,F5,7F,E1,A8,E8,72,B0,6D,F4,7A,CC,45,E5,AF,D3,19,BD,E7,52,B5,1C,FC,40,04,66,EC,10,20,8B,0E,3D,E5,05,84,7D,1B,23,48,27,09,60,F6,0B,80,4C,35,E8,8A,91,47,0C,3C,14,D4,74,4B,52,1D,E3,50,59,E6,7B,ED,66,DD,21,D8,DD,22,4E,93,76,4B,24,BB,C6,96,10,43,A3,B5,D9,38,F3,55,1D,1C,20,C3,51,EE,B6,CC,14,DB,7A,62,2B,98,5D,45,EB,6D,6C,B0,78,B9,1A,38,5E,E3,1A,33,7D,28,F7,5F,9C,E7,6C,1B,02,D3,82,2D,04,FB,E8,87,90,98,6C,60,D1,19,4A,7F,02,1C,85,82,69,0B,F0,D5,E4,C2,59,81,69,63,3E,BD,67,9F,B0,66,0F,1D,03,16,A6,2A,C3,61,83,66,40,7B,5C,53,71,9D,D8,9B,E3,3C,A1,2F,D4,DA,6E,44,11,4D,88,16,3E,E8,FF,A3,A3,86,64,9E,C3,03,94,D3,3E,8E,D6,3E,16,F4,91,BA,DA,D3,54,7F,58,E9,DA,07,1E,E8,03,A5,54,CB,72,FD,AA,42,D2,DB,8D,AF,89,49,92,1D,36,46,C8,F4,83,DD,FF,B8,36,14,B1,F2,58,2C,5C,94,23,41,44,9D,D0,6E,6A,61,38,79,E9,B9,46,3F,2A,60,23,6D,E4,80,A5,8C,F7,EE,A7,F5,FE,C0,55,8A,A6,74,44,EA,DA,9E,68,3B,F0,76,6B,F5,53,47,D9,FF,80,18,D1,8A,A8,F5,C5,3C,57,83,6D,B9,A7,A1,25,5A,06,66,AA,F5,34,B3,C8,DE,F9,DC,5C,A8,CD,BD,CC,C9,BC,7E,4E,0F,99,8E,8C,19,ED,BC,BF,51,49,00,4B,57,DD,45,5F,C7,D6,1F,0B,DD,85,BB,A7,CB,FA,BC,F9,49,FC,94,4C,32,0A,38,31,69,EE,64,AC,B8,E4,57,B0,63,6F,81,E0,63,CF,55,37,E2,59,2A,D7,57,21,73,51,DF,4A,D5,26,D9,49,EF,1E,25,B5,27,80,F0,4B,60,A1,9F,E3,F7,CE,10,F1,2F,FD,A0,3A,2D,C3,31,01,00,04,23,28,86,1F,CB,B2,DF,B1,F2,D4,19,3B,A2,0C,ED,B8,65,91,63,02,55,47,3E,D3,EA,39,0D,CB,A3,87,95,BF,E1,B0,CE,DF,1F,96,28,E0,B2,DE,F4,50,D7,02,B4,DF,E3,BB,C4,FA,B1,06,73,BA,D4,49,A8,FD,91,5F,24,5D,1C,EB,6B,3A,DB,29,E0,35,F8,84,98,97,59,7D,18,56,EB,4B,2F,6B,2D,A2,19,32,7C,A1,A7,30,E7,FC,EB,D9,2B,18,36,8E,B1,7C,F1,62,1F,A3,5F,FE,53,2B,6A,37,82,C7,B6,41,CD,9B,2B,2C,24,C5,94,BC,58,D9,93,05,E4,CF,3B,1D,2F,10,21,95,FA,A0,11,09,51,73,0B,E2,5E,F3,25,FF,2B,65,18,D4,EF,E4,80,B1,13,A2,AE,E0,45,10,4E,BB,EF,03,1A,D9,FD,CE,1D,1F,0A,90,50,3E,08,03,6B,78,DD,4A,0E,F7,CA,01,88,76,72,9D,97,48,3E,DB,CE,E5,0B,51,3A,67,4A,86,4A,6D,C6,DE,FE,34,4A,3B,36,5E,6D,DF,30,9C,20,CC,55,E5,5F,F4,33,88,93,00,EF,2E,0A,4C,61,9F,D9,DC,78,3B,45,A7,32,3B,99,0D,6B,DC,9D,CE,D9,56,DC,57,D5,69,FB,FB,2F,C6,C8,9E,F4,5E,70,36,4C,38,3B,00,6C,B7,FD,B6,CA,E3,46,A2,BC,2C,D6,FB,7A,A3,28,F7,B1,9B,8A,03,A2,15,6C,61,25,56,A6,9F,52,4D,0E,31,4D,A7,08,7A,76,F6,83,AA,42,EB,73,F5,C2,7E,54,08,71,25,DD,D0,E9,86,5F,2F,72,2C,AC,B1,38,AD,4C,B2,6B,B6,69,27,EC,87,48,65,A2,BC,0E,95,68,E7,41,14,CC,C1,FE,C1,74,75,07,38,C1,35,1D,CA,99,37,D5,CE,54,2C,17,16,88,CE,43,63,2E,94,F2,62,25,20,9A,F1,14,B8,93,A7,7F,83,28,9D,39,9F,85,9A,11,01,65,DC,AC,BC,18,7E,CB,90,D8,2F,CC,6D,81,BA,D0,B7,F3,C7,CB,16,11,A5,AA,0A,6A,E6,9D,01,43,C3,6E,4C,47,52,CE,7C,76,37,DE,E8,0C,F9,95,40,80,BC,68,63,BC,57,F8,90,FA,49,49,6F,E3,33,80,5B,AF,51,67,5A,D1,6F,D8,86,32,08,05,78,29,5B,9F,53,D2,FA,59,49,F4,1A,66,89,20,12,8A,11,0E,68,54,DC,4C,AA,75,42,0A,A9,8E,7C,74,7D,5B,E8,EA,48,82,CC,B2,89,DF,C8,65,42,22,72,FB,A7,3B,63,99,D8,66,9A,74,38,ED,6A,55,BB,4F,74,C5,93,FC,AE,4D,36,8A,B0,4A,06,1D,DD,71,CA,70,FE,3B,FE,6C,AF,BC,D7,09,97,31,84,D6,53,E5,61,81,C5,51,41,8C,20,FE,E6,B7,D8,CD,28,D2,9C,F7,0A,60,62,41,91,37,8E,CE,1A,E3,57,52,0C,C2,E0,46,40,6F,27,F4,76,9A,FB,99,7F,66,B4,1B,B9,B5,E8,5F,E0,08,5D,13,FB,16,AB,AC,32,BD,09,4B,C6,95,43,E4,1F,08,B0,80,AC,D7,14,EF,4F,E8,34,12,83,89,4E,1E,5B,E7,66,B7,C2,7D,5F,CB,E7,73,C9,5A,8E,47,8A,97,BB,1A,B8,53,89,AA,76,17,2D,6D,F3,53,4C,34,96,EC,6D,F3,E4,7A,4D,45,9F,80,F4,BA,B7,31,38,24,CB,C0,7D,BB,27,3A,3B,EC,3E,CB,8A,92,19,A7,04,84,C9,91,91,06,0A,D2,F0,27,2A,40,AD,C2,D8,90,BC,39,AE,40,16,D6,EE,1D,E9,9B,80,8D,7E,1C,3E,50,F2,7A,85,CE,90,69,B4,0C,1B,F9,F3,3C,57,26,C5,BA,93,DA,A1,04,7D,F4,C6,48,F7,E9,30,EC,7E,92,A2,DA,A9,DA,76,0C,63,C3,03,F2,FF,27,8E,4B,65,CD,2B,C9,B6,17,8B,84,1C,92,DC,04,48,30,2E,F0,37,47,71,10,F1,D6,CE,FE,9C,32,8A,23,4A,53,87,FC,55,27,37,BA,DD,64,DD,D8,55,E5,B9,2D,7D,33,4B,8E,8D,18,F6,C9,DE,AF,1A,24,07,C4,76,D7,CE,3C,4D,A6,56,B4,69,7E,4E,FA,03,CA,79,65,EE,B5,27,C7,1D,B9,34,D6,A5,40,25,5C,B1,2D,75,50,39,FF,35,5C,E5,0B,DE,1E,FF,C5,FA,67,23,05,EA,21,08,04,E4,CA,67,73,E1,CA,A9,6A,07,00,D2,6C,72,84,5B,41,F3,76,CE,6B,90,A8,FB,10,C1,71,A1,30,D6,D9,6B,6F,50,BC,7F,05,99,E1,5D,D8,3D,AD,66,37,DD,1E,5D,D7,50,3A,48,7B,3F,72,E6,CA,4E,53,BC,04,EF,F6,AE,A5,DC,EB,64,80,E4,AE,93,C8,91,94,17,55,CB,3E,A6,42,AF,29,87,A5,DA,88,03,73,7A,BB,76,EA,0C,7A,10,75,DC,57,65,D5,0D,CA,6D,7A,AB,FC,53,79,F3,0E,39,85,66,32,6B,04,01,DC,18,BD,B3,47,98,76,D9,CC,E3,42,F3,76,7C,AC,C9,FB,F4,3F,DD,F9,E5,7D,0F,B7,9A,27,A5,D1,33,04,A7,EF,75,A1,3F,09,D4,75,5E,80,76,1D,CB,94,42,1D,A5,52,B9,A5,54,36,AB,C9,51,76,9C,B7,B8,E4,9E,BF,71,33,75,64,88,9A,F9,7A,60,E8,F2,3B,50,2B,B1,19,F1,D7,95,DB,B8,F8,C5,5B,FE,B3,7D,07,3D,AA,37,79,7F,DC,45,28,53,18,35,AA,ED,5F,3B,8A,76,7D,8E,52,1A,3F,9C,56,B6,3B,29,8C,5B,23,F1,45,F5,A9,09,2D,85,C2,FA,CB,C7,27,D8,FF,34,58,53,94,7E,56,1D,73,0F,49,CA,6E,10,18,27,4B,6C,5D,4F,51,11,C3,02,5B,E0,24,A3,36,85,39,10,E2,88,1E,1B,C5,F4,27,6A,67,A7,FF,02,00,69,E6,4C,08,B7,61,70,21,33,85,1E,B4,14,FD,D9,40,43,E5,4C,C8,C9,D6,55,D7,3A,6B,D3,8F,C2,D1,65,18,02,E2,81,DD,53,B5,2F,66,BB,C1,C0,F7,69,DE,1E,3A,6D,F5,5F,D4,22,53,9C,91,39,F1,51,AE,A3,D8,4C,27,B9,D9,A3,35,AC,F7,A2,02,CC,AB,61,4B,F1,9F,7F,E9,DD,C7,8F,5F,63,5E,AC,2B,9F,84,F7,DF,F1,CC,B2,2D,A4,0B,38,B4,2E,5A,DD,03,3B,02,85,BB,93,E9,F3,10,65,F0,BD,5F,15,84,D7,88,68,A2,26,8D,B2,DB,3A,2A,EA,9B,38,52,4D,DA,AD,F8,D5,38,4A,3E,C3,9A,EB,6D,EC,2E,72,B7,5E,6C,91,2D,E4,77,F4,89,A0,44,7C,F3,E9,53,9F,3A,DB,E3,00,0E,69,62,0E,05,24,81,C7,34,6F,D2,57,8A,5D,38,B2,6B,DE,0D,43,3D,A9,92,FA,43,6F,32,A0,76,62,B4,AF,B9,2E,AE,92,B3,19,47,82,5F,D7,57,F0,7B,08,2D,51,62,66,5C,75,4D,D2,62,79,0E,B7,D9,03,8D,D4,5A,DA,BE,F6,B8,3A,CA,0F,32,F9,60,85,45,23,71,77,41,A1,15,9E,15,D5,28,F5,9F,0B,92,40,63,C1,E5,B6,ED,74,C3,53,8C,C0,4B,87,93,7E,9E,04,D7,56,C6,29,9B,54,07,CD,15,A3,A8,A9,C4,A5,27,38,09,A6,6D,8A,B9,F9,95,90,CF,39,0B,D1,43,ED,64,96,59,E9,E7,CC,44,E6,DA,C4,4C,B9,C8,C9,34,96,F4,59,35,32,D6,48,87,8D,4F,2D,E1,CD,A0,16,7F,E5,C1,B9,EB,FC,76,52,F7,24,3C,35,59,F7,17,44,7B,D5,E2,E9,5F,91,75,06,45,3D,08,E3,54,7D,A5,12,DF,55,59,62,41,6D,EC,98,AD,FD,03,04,54,8E,69,38,98,65,DA,B6,A8,7B,BC,76,1E,7F,08,E4,04,61,18,25,AC,E7,59,CB,29,10,C7,0C,F6,F2,15,3C,FD,96,9B,77,FF,21,76,67,D5,9A,E5,14,D2,21,CA,13,C7,68,27,91,11,75,B8,F5,27,09,AD,13,A5,7E,AC,60,72,50,89,F8,B6,3C,15,5D,92,0B,B6,3A,F4,BD,FA,8B,64,31,D9,EF,EE,71,EA,33,78,F7,28,2A,DE,A1,29,F1,75,68,9E,6C,46,87,D3,7F,6C,D9,34,6B,DB,D7,17,0D,72,E4,B9,A0,A1,DC,D6,F4,D5,57,1C,46,06,98,06,0F,70,D5,63,7D,70,35,F5,5A,AB,DB,D7,32,FA,A5,9D,88,3E,2F,12,83,D5,6D,F6,72,98,31,87,B7,A2,A4,5D,DA,B1,5D,E5,00,A1,E0,55,F0,84,74,AB,A2,90,E5,0A,8D,75,36,65,D4,A1,2D,9E,CB,60,8A,1F,41,02,3A,91,7B,F9,1F,40,4D,B1,11,4B,C5,5C,0D,10,E0,1B,AC,CD,7D,CD,54,C1,44,14,4E,D4,4E,4E,93,92,DB,39,B9,CA,CE,56,31,16,B8,83,B3,F9,D5,81,9E,EA,8A,55,D5,AE,B4,05,85,FD,44,D1,E0,F1,4B,3D,04,7F,06,6D,E3,B7,97,72,F8,BD,F9,A6,2E,4A,BF,B2,D9,58,1D,40,E0,FC,0B,8F,6D,ED,B1,C9,5D,1E,68,67,D7,05,CF,E0,89,3D,79,80,09,FA,72,8B,53,24,C5,A3,79,6E,F2,71,71,89,FE,74,5C,F4,47,08,3B,E4,1E,26,F6,73,4A,38,EB,35,F0,A1,39,BE,8C,E2,7C,E6,97,16,95,4C,A2,8B,60,92,A2,36,3F,87,3E,22,1C,7B,8F,4A,FC,3A,CE,7C,E5,CC,BE,1C,34,9F,51,2E,0B,D3,08,83,5A,23,7F,03,C3,F9,33,72,5B,F5,AB,CB,9A,E2,2E,0A,93,43,EB,03,0F,D7,CB,A7,DE,23,46,47,CC,1F,B4,66,08,AF,D3,56,00,8D,63,8D,D5,61,E2,2B,23,43,EB,3C,C8,FD,4B,E4,77,C5,28,94,BC,B7,5A,86,51,A4,3D,41,DB,67,DC,DC,3A,50,5C,ED,F0,7A,7F,C5,2A,24,69,07,89,B5,BA,35,DF,E2,D5,4A,90,71,78,0A,2B,A7,67,E8,4D,EE,B3,75,03,B9,AF,7A,E7,03,9C,65,7E,C4,FD,C2,B2,67,F7,2C,3B,CB,19,B5,83,8B,40,18,F5,92,9E,DD,3B,1B,72,8F,C7,7D,3E,39,77,25,1A,6D,B5,76,B5,9D,40,B8,7C,03,18,6D,1B,AE,C4,92,2B,D4,84,1A,04,4B,F9,10,17,E5,94,14,A7,36,48,AB,10,F4,DD,4E,36,AA,45,F4,83,03,16,9F,C2,8C,4B,4E,7E,75,C5,6E,C9,C0,3A,44,B5,2F,46,EF,F7,55,DE,84,33,90,D8,8D,D8,0B,D4,F9,1B,B2,6C,50,D3,D9,71,85,70,1A,59,2F,09,15,06,10,2B,AD,E6,D0,43,76,9D,41,50,80,84,26,32,44,87,03,7E,56,60,34,1F,13,95,60,A5,B4,98,26,E6,82,68,7A,86,10,F9,63,10,2C,E5,5C,F3,7A,17,CA,A3,69,E1,A8,50,4C,11,D3,3F,49,F9,84,8C,02,A4,8A,3D,22,D7,3D,D4,EB,7B,22,25,CB,96,C2,C9,77,AC,C4,0A,00,9E,C3,A9,EB,DA,21,5A,24,8F,AE,05,8F,0A,4B,15,66,52,88,86,B5,4B,40,AF,01,BB,4B,7C,58,F2,C2,11,D2,F2,81,61,4E,9F,1F,19,76,0F,5B,E2,D3,0A,AB,B6,4E,51,D7,23,98,16,E1,31,64,4A,58,32,15,09,CC,35,A8,E1,DE,9B,6E,3B,FA,9F,80,93,B4,EB,D5,7D,45,C5,86,89,0B,31,75,61,6A,8D,3E,49,DF,D0,18,91,DB,2F,75,F5,7F,83,57,2E,36,C5,02,89,84,F8,40,FA,BB,CB,E6,FB,98,26,4C,6C,2C,AA,B0,78,1B,0A,A2,7C,78,1F,6B,83,4F,9D,70,80,40,C5,25,8C,C7,B7,8D,53,00,35,B6,96,13,5C,28,A6,E0,21,F7,C4,E5,45,4A,89,4D,80,D4,15,A1,93,0E,6E,99,F7,27,AE,29,B1,34,BA,E4,29,A4,DE,31,84,2A,E8,8E,15,6A,17,9D,F1,AB,ED,93,8B,DD,BC,A9,6E,5B,0B,BB,94,9C,2B,8F,95,D6,C6,FC,70,D7,ED,97,F4,EA,3F,FF,F8,E2,CF,D3,10,10,2C,EE,8F,E2,DB,1C,FE,1B,3B,43,A9,AB,1C,02,BA,EB,BB,26,BA,3A,70,6C,68,FB,5F,89,10,EC,B1,E1,8E,9A,05,39,4D,A8,C7,F2,AB,CD,C5,85,BF,16,51,4E,9F,1F,CC,4C,74,D4,E1,BB,67,30,96,74,EE,60,63,98,99,A5,2A,46,EB,49,80,67,25,C5,BA,51,2B,91,E7,88,BC,72,FF,D3,32,40,54,0D,58,97,9E,D0,B8,62,35,9D,DC,0E,AE,48,07,C0,B1,6B,82,CD,8F,DA,98,04,95,34,16,1C,00,10,80,52,08,01,AB,02,DC,0A,7F,FF,FC,C2,A9,9E,D1,B0,EA,1F,62,E4,44,D1,61,B5,C8,BC,7B,F8,95,9B,B1,C9,22,78,BB,44,9A,2B,9D,9A,6E,D0,21,14,D7,F4,80,71,1C,AF,4D,C6,26,A9,85,B4,6F,57,0C,9C,B3,FF,4F,D1,10,AA,17,60,4C,BD,51,22,E2,6F,06,0C,48,76,D6,9F,38,D1,B6,25,AC,8D,5D,3A,E2,8B,89,2D,D2,56,33,3D,C4,D6,81,5D,36,0F,14,58,88,5F,4E,75,1B,50,61,A1,DE,42,D9,F2,C7,14,49,DD,41,0B,DC,19,B7,A3,73,14,53,DB,65,80,72,89,A8,84,D2,9C,E2,1C,C9,85,F9,3E,E2,91,EF,D4,E7,74,64,B8,24,87,C3,AC,52,8E,C0,24,60,4A,52,4A,1E,0E,81,A5,F8,22,7D,4D,3C,4C,23,17,C0,01,61,B0,30,92,EB,56,4C,11,53,64,63,82,E3,A3,13,82,B2,EC,DC,EC,BD,00,32,62,FA,A3,F2,89,34,91,40,32,BF,B2,AA,CA,E1,26,4E,4B,DB,3B,EB,46,4A,B8,57,AD,2F,BC,A8,B2,08,EF,9C,ED,1A,07,B7,EF,9E,B8,F3,2B,3D,6E,C0,B0,F6,44,C8,D8,3E,4F,1F,86,20,A9,11,EC,13,2E,A4,71,DD,16,DF,B5,0C,E4,0C,1B,13,24,6D,7B,D9,01,3B,EB,6D,FE,AE,20,F4,0B,13,52,38,59,7D,F7,92,C3,DD,E1,CC,F5,67,94,BD,BD,C0,25,29,5E,A8,15,07,BD,99,FF,2A,96,6E,4A,89,2C,87,BB,58,06,61,FA,DE,2A,79,70,B2,56,F8,AD,1A,FC,A3,BA,06,6B,27,1B,D1,35,6D,34,40,D4,B5,AB,28,65,69,C1,09,F6,38,93,A2,CB,A7,A7,CD,A9,BA,B5,E7,B0,4A,C5,90,50,2B,4B,5D,3C,78,12,9B,29,1A,3F,98,3F,A2,C3,67,01,09,2F,85,05,DF,06,98,B3,65,89,1E,79,E6,27,70,F2,5F,54,01,B1,16,2B,B5,46,BB,67,78,52,65,80,ED,C4,0A,03,BC,24,E0,49,7E,74,E8,07,CD,4A,CF,55,59,CE,C8,4C,96,12,3B,AB,38,5B,07,9D,89,CA,7F,F9,06,EF,01,92,77,A6,36,A9,F3,78,EA,DC,C3,1F,21,AD,4D,94,F8,29,1C,54,9E,89,B0,8E,5C,B1,6D,DF,92,28,C2,F5,8C,32,2D,90,B3,95,9A,91,9A,72,06,41,5F,8A,CE,BE,A5,48,7D,52,42,1D,55,F0,D3,E6,1B,DB,91,14,04,B6,C4,1C,DC,62,EA,06,B8,EB,B8,AA,58,6B,AC,11,B2,50,19,22,BF,40,BE,C5,A0,25,2A,5F,52,FC,B5,20,2A,72,AD,59,9D,CF,F2,99,C4,4B,0C,93,30,E9,CE,16,94,C4,51,C4,53,38,70,51,04,D8,7E,54,84,43,C0,0A,5B,D7,AD,E1,62,E1,B2,36,EE,AA,F7,59,F4,5D,4F,E5,0E,82,69,E9,75,3B,2C,B0,8A,C0,21,4F,83,26,57,93,65,EF,17,16,AD,E5,13,25,63,64,2E,EE,9E,63,08,8D,A0,06,F6,E6,22,14,56,78,B1,44,1B,E5,92,71,C9,DF,BA,5A,74,D7,BA,30,8A,F2,76,CF,6D,39,93,2A,E7,84,FB,C0,5B,77,6D,A7,CC,60,A4,6E,FB,6C,68,17,87,66,28,85,76,97,D1,22,62,45,61,48,54,33,31,CE,46,AF,51,6C,D3,3E,CB,6F,B8,09,59,E9,1E,71,F3,97,1D,39,75,4E,27,24,64,B6,2E,5A,86,45,82,33,91,B9,A6,3C,10,CA,4F,7A,84,73,64,D2,2D,59,E6,8C,F9,0C,B1,2D,BF,4B,65,47,9E,5F,BF,30,04,67,83,3D,B6,A2,2C,ED,A6,16,A3,33,BC,EE,42,CD,B9,84,22,5C,27,E3,CC,D0,BC,90,8E,18,CC,C0,EE,5B,5D,E9,1F,BB,2A,C4,AA,D3,95,28,79,07,18,4C,F2,4B,C9,DD,25,C2,DD,FE,35,28,6D,72,F4,B9,8B,33,DA,C6,1B,46,F1,5C,16,56,BD,3A,6B,C2,9C,F9,1E,04,F3,2E,B7,A1,70,0E,17,CA,1B,CC,20,71,98,24,0A,59,31,53,F0,0F,76,11,30,0D,AE,0D,8E,4C,80,A5,BB,DB,FE,B1,EB,EC,D0,0A,0B,0C,22,8B,D6,95,23,6D,FF,DF,40,C3,30,DB,FC,0B,C7,8A,6F,90,5E,8F,35,BA,23,D4,B6,5B,A1,F0,2C,5F,9C,35,04,AF,18,8F,B6,FD,8B,FD,10,A7,61,D2,22,8A,32,68,D8,D4,DB,43,B3,E4,0E,AF,D7,F0,82,D9,13,B0,BC,3A,F1,15,0E,20,F7,CD,AB,0A,57,F5,9D,1A,9F,44,D2,84,26,07,CA,0A,7B,C1,DA,C2,B1,16,3E,32,04,1B,51,83,1F,C0,6C,7F,2D,0C,00,92,A4,9A,6B,1E,51,4B,A9,B3,D4,00,61,21,C6,A0,16,A5,D8,74,20,6B,DD,4B,6F,E4,B9,E1,01,1F,C3,E9,53,AF,17,9C,2A,F9,CB,0D,7C,70,37,3F,ED,9E,B6,CF,EF,0B,5C,D6,4A,F8,F7,29,EC,37,8B,73,9B,64,70,CC,64,5A,05,38,47,9D,88,C4,FF,11,E6,B9,26,4F,0F,9C,4F,FA,BB,DF,BE,60,92,12,23,53,DB,FD,91,61,68,20,43,1A,4D,47,AD,04,DB,08,22,A6,12,75,BB,D6,F6,07,48,21,CF,AE,07,B3,6C,FD,24,91,32,0E,1C,C5,06,91,F5,A9,40,B3,12,67,75,0D,FD,CB,B3,26,C7,EA,D2,9F,EB,3A,C8,56,7B,D2,3B,AA,BA,EC,7A,4C,78,5B,8B,07,9C,8C,13,FF,E8,3A,87,0C,4A,FA,DE,C0,82,18,7C,FB,69,04,9B,3B,A0,CB,86,18,76,C0,11,BB,3C,4B,57,BE,D1,DA,2D,63,F7,27,1A,F7,96,A4,C0,E6,DF,3D,72,BB,CD,80,02,41,50,CF,55,AA,37,FF,A1,A6,AB,D9,DF,C7,F7,24,05,23,8C,27,F2,3E,DE,6F,AA,EF,53,CD,8F,D9,E3,F2,85,F7,BB,14,EB,71,2A,E6,D8,B9,D6,39,5B,D7,5A,3F,83,42,3B,45,AC,51,76,75,2A,1A,26,72,5D,82,CF,83,21,E6,08,B6,04,E0,91,1E,09,C4,97,89,5A,41,1F,E9,CC,1B,44,D3,D0,03,63,E5,A1,9A,92,13,64,14,4B,40,7B,1D,34,5C,0C,77,1C,B4,A7,CF,59,D9,7B,51,48,7A,D3,E1,0B,21,86,E0,A5,91,37,D2,D2,A6,F4,F7,14,1E,C9,D4,8F,31,4B,08,EF,C2,63,05,33,48,C9,24,39,62,8F,D4,3B,3D,1E,56,F4,8E,2A,E1,24,25,B5,19,35,07,D3,1B,18,26,D0,1C,6E,94,C9,26,7F,CA,C5,59,20,B7,B0,1D,6C,4C,29,20,21,BE,1C,9A,09,A5,B0,98,68,33,34,9D,51,EC,A6,70,3F,D4,3A,6E,CC,8F,37,67,7E,42,7C,4F,60,92,1C,75,FD,E9,3E,00,4B,9A,90,EF,A8,9F,52,70,44,85,05,E2,EE,4F,E8,C8,D8,5E,21,22,5C,2C,A6,9C,D6,C6,D9,6D,8A,52,C1,DA,A6,C6,B1,22,19,86,C2,63,44,65,96,B6,FC,1D,C9,4D,D3,1B,6A,92,25,35,55,DB,FE,07,2D,D1,96,9B,E4,E4,46,8E,70,53,2E,8B,2E,26,47,AC,86,C1,0A,08,6F,93,97,F1,91,03,5B,4C,3D,53,0C,AB,B3,3A,BA,06,0A,5F,59,C5,F4,23,75,5C,34,48,B1,61,9D,93,55,3A,92,0F,98,78,F0,B0,4D,BE,8F,D2,06,C6,45,DC,E8,5E,70,E2,C8,AF,06,CC,DE,B3,72,21,48,4C,F3,87,32,47,A9,FD,D7,C1,A7,F2,A6,D1,90,64,40,D8,5D,5F,1C,E4,5F,BE,C5,7D,B0,39,6A,58,B5,0D,70,3E,B2,3D,8C,A4,FA,25,02,80,09,AC,32,39,13,90,FE,E3,0F,D8,2A,D3,89,47,E2,99,41,2D,22,C9,06,84,8E,CC,98,C0,57,45,CB,65,18,DC,3C,FC,0A,66,DE,BA,2E,59,E3,E4,F8,FE,94,C0,E1,09,7F,63,9F,7B,A1,E4,CE,8C,7B,C1,2F,BE,DF,0C,4D,BD,68,4B,05,F8,BF,FB,0A,66,DB,87,C8,14,35,C3,0C,76,05,A9,20,AF,BE,E9,F1,AD,97,77,D1,14,B6,9D,00,61,BF,AC,6E,43,68,F6,E5,7A,4B,EA,D1,5A,9F,BD,A3,BB,E4,2D,80,39,75,E1,82,CA,44,B5,A9,3B,54,44,21,17,35,9C,F9,39,90,71,78,02,96,B8,7F,49,5B,39,8D,06,B7,CE,0C,D8,E3,16,2F,29,4E,78,E4,09,53,E5,F3,BD,F6,64,72,C6,FC,8A,62,60,E4,B5,C8,BE,36,E9,B2,06,C0,71,DC,BE,A8,AA,FD,25,64,D3,DD,40,13,E9,13,D9,D2,EF,C8,7D,85,8C,33,5A,C7,F2,98,A3,32,6A,BF,77,A3,56,07,CD,B1,F3,A4,5E,5C,2C,7B,C7,2C,AB,D2,A7,94,A1,EC,56,71,D6,A3,28,87,6A,06,36,C5,13,CB,E3,48,EC,74,4D,0A,EE,7B,A7,DB,F9,36,BF,54,5A,C0,34,11,44,66,9A,32,F6,62,6C,61,1E,43,0C,26,AC,8C,62,83,4B,F7,7D,8A,E6,EE,DF,55,53,A4,99,24,5D,73,F8,AE,B0,8F,42,51,21,42,80,15,EB,FC,3B,F0,DE,83,22,48,BD,5F,6E,87,2B,15,B3,AC,2C,FA,43,85,5E,D8,FE,55,30,D7,CB,B3,8B,B3,8B,B3,CC,C7,7E,D5,F3,76,2C,63,46,D3,B6,6E,E6,FF,AE,33,6C,93,20,08,06,10,7B,DB,8A,6E,04,F1,EE,B3,5D,A5,61,43,7F,F4,35,E6,59,47,6F,78,E0,FF,7E,53,8D,5D,CD,C5,2D,10,6B,9B,1D,4E,76,DB,8A,87,8A,37,BF,DE,E0,8F,EF,43,D0,0B,E4,DA,C8,B6,DE,78,ED,C8,D3,D1,15,DA,C7,53,50,34,9A,EF,96,72,F3,4B,82,91,EE,B8,61,0E,AB,AB,85,23,87,A3,D9,B6,AB,15,65,CB,61,66,47,6A,67,BA,60,1F,53,3F,23,90,0D,DA,A9,F2,3A,9E,C7,CB,E7,4E,F3,BB,A7,4B,F8,6E,DC,42,93,5E,84,F9,AB,B5,B1,C0,7B,F7,95,F0,40,88,C4,79,35,1A,A9,0B,9D,A7,51,86,D5,11,E2,47,99,1B,CF,A0,AE,F4,C3,D6,E7,1F,A8,17,87,19,45,8A,71,11,0E,29,49,86,CF,18,81,68,B8,43,25,49,F7,C0,0E,C1,C6,74,53,D7,20,B4,80,9D,A4,54,0E,ED,08,4D,A2,8E,12,FE,69,6F,3E,C7,85,B5,E7,7E,3A,DE,C7,B2,5A,19,56,7B,79,00,66,E0,5D,C5,53,0F,70,FB,FE,B4,9F,F3,84,2D,74,6F,28,3C,FF,97,B0,81,24,CF,16,BC,0A,0A,59,F6,97,47,03,6E,25,D8,3A,24,C1,81,64,CB,DA,D2,69,A9,FF,AC,5C,31,61,A0,27,91,91,8F,B8,66,C7,8D,FA,D2,A8,67,CF,DC,79,AE,7A,4D,65,21,8D,6A,88,D4,DF,8B,68,FF,2E,58,98,36,3A,25,7C,66,E0,B6,FC,F2,E5,25,A6,F9,08,62,22,F4,10,87,1F,6E,9C,7F,C6,42,67,D2,85,57,8E,DE,F7,58,B2,F2,20,20,DE,29,F2,1C,C9,5A,A1,AB,65,1B,65,A5,DB,2E,21,D5,57,C1,CA,52,FD,23,68,96,30,BB,19,74,97,29,D5,F9,11,63,07,67,02,45,69,7F,24,9D,AF,32,11,53,C7,62,CF,64,D4,E6,4F,38,07,F5,10,A0,6A,71,8F,C2,8F,11,C2,2B,DE,5C,BC,38,83,E9,29,E4,37,B4,19,2C,5D,79,06,25,93,33,04,1B,23,8C,2C,F3,A1,C3,86,25,EB,2B,65,5C,0C,AC,17,2D,68,61,88,EB,33,11,D5,56,EB,C0,02,D0,E5,BB,7E,16,3F,E1,A5,EB,95,A3,D8,E1,9B,30,5B,32,3B,3A,59,A3,5C,7C,85,87,1A,0E,89,EC,E5,C7,B0,66,F3,EE,1C,54,ED,0D,D2,32,C4,16,41,CF,48,ED,88,63,64,A2,62,09,0B,67,7C,2D,8B,59,AE,91,2B,B1,42,6F,82,45,A5,C9,43,89,FD,91,18,16,8A,A9,80,0B,F6,C8,49,FD,48,19,B1,F8,D0,55,E0,32,4E,6C,04,B0,FB,0B,3D,21,7B,A4,D3,88,59,36,92,8E,64,74,9D,FA,FB,9B,33,BA,E5,A3,3B,E8,6F,CF,5A,8C,ED,F6,57,B8,E5,4D,94,CC,7E,CC,F4,C7,39,08,91,EA,6F,8D,F3,EA,47,F5,8F,D9,64,BF,1B,81,32,71,39,54,95,3B,BD,58,50,AC,77,17,F6,8B,40,5C,F5,24,30,94,A4,E1,34,4D,B4,D2,B8,0A,63,98,0B,CA,76,FC,9C,AA,52,8A,9E,B6,48,8C,7C,56,79,92,D7,77,F5,F4,9A,D2,07,6F,B3,38,49,31,A6,8A,D2,D4,48,8E,62,38,FB,6D,91,69,52,BE,0F,91,E8,DC,73,0C,CB,2D,C0,C2,52,A2,17,54,5F,17,50,ED,85,0C,5E,FE,A2,13,06,DD,FE,AD,5E,52,A6,ED,C7,D1,47,A8,C0,91,FC,69,93,A0,78,B5,9D,1E,2F,4C,26,03,BF,A5,3A,80,47,A6,81,2B,DF,BB,BB,DB,4B,8C,1A,74,AB,C8,91,88,51,4B,08,25,F3,CA,FC,FB,BD,19,E2,80,18,AB,19,00,54,EB,CA,57,67,83,4A,46,06,C9,5E,2B,2D,25,06,56,8F,FD,92,A8,07,E2,AE,86,0F,C2,FC,FD,2F,C3,7E,95,51,42,A4,D9,F5,67,BD,9B,BE,A1,93,16,E5,18,EE,0A,3C,88,99,D7,F6,10,1C,65,B5,F0,7F,8B,AB,41,F5,BD,65,4F,79,E7,39,1A,11,65,C1,C6,E6,15,DA,47,7A,BF,91,B0,AC,51,98,96,8E,60,77,09,09,FC,69,51,CA,46,6E,41,48,A9,2D,19,C2,7E,9F,74,8C,20,A9,99,0D,9C,80,83,CE,88,64,7E,20,C4,E1,4C,69,BD,09,DC,27,BF,9C,C4,CF,3B,1C,3B,6E,F1,8C,A7,A0,7C,88,C5,D9,7A,2B,A5,4A,25,9E,59,51,27,73,68,A9,60,CF,B5,B3,95,29,A0,A6,0C,4D,A6,2D,78,06,61,8B,E5,9A,D5,E2,7D,0A,79,9A,75,9F,95,D2,D9,AA,83,AD,9E,97,CE,2E,9D,A9,EA,CD,D1,3B,06,60,51,77,9C,91,C8,D3,77,A4,B6,B3,57,1B,3F,75,E1,69,45,B4,C3,E9,BC,A2,18,24,93,ED,8C,D1,6C,98,3E,DE,72,E3,DB,73,EC,09,34,2D,5E,31,0F,A3,4C,60,C9,6D,3B,52,84,DB,F4,5C,6F,35,11,8E,10,03,4A,C2,2D,19,EC,A1,3B,D0,1E,10,F4,BF,B9,83,70,88,A8,16,DD,DA,3A,7E,F9,D5,61,DA,6F,65,E9,2D,A6,64,2B,F8,16,4E,13,E2,7E,3F,BE,D3,4A,B2,68,3F,E5,62,D8,15,F7,03,EB,63,20,EC,00,8F,13,A3,83,18,7B,FC,6E,92,D3,DB,D8,AD,42,89,8C,9F,9B,17,40,BC,0A,2A,69,37,B6,0E,7C,B1,48,C4,58,22,43,A5,8F,6C,BC,CF,66,28,5A,6F,B9,94,BD,41,C2,55,9A,A9,D3,5E,24,84,FC,2B,5A,AD,B7,AB,30,3E,00,45,C8,35,CA,15,0E,72,7C,D0,27,68,C2,F2,80,9B,0A,B4,B3,0B,DF,3A,D5,0A,58,BB,C8,B1,77,CD,5B,93,2A,A6,A9,96,94,ED,B4,65,A3,C3,B9,64,CC,6C,C6,6B,51,82,9C,84,6F,C4,25,CC,3D,78,D6,9F,07,F6,AE,A3,EC,D5,8B,95,EE,0B,97,90,2F,3F,1B,D1,A9,9B,4E,64,E8,95,DE,94,33,B1,3E,A8,49,49,4A,D3,36,B8,56,26,8E,EC,34,84,A2,C6,93,30,E9,97,66,20,3E,11,7F,79,44,92,17,B9,B3,71,89,61,1A,50,11,DF,14,BC,C3,E4,62,CB,45,2F,B9,DC,0E,E9,07,97,7F,66,24,12,DD,66,B0,35,CA,05,AB,6E,73,8C,DF,A0,D5,88,BD,12,25,EA,E5,1B,A6,22,4F,8D,1C,50,2F,B2,AD,FF,DF,B4,3A,E3,97,9A,9E,B4,EF,FD,29,88,7E,11,E5,25,B1,E9,92,96,C5,BA,47,30,C8,88,69,71,A6,8B,B9,E8,09,93,B1,A2,7B,8C,73,C8,2F,54,33,FA,15,0F,55,60,48,C8,9F,2F,FB,9C,D4,5F,A2,D1,4A,EE,6C,84,E3,AC,37,D6,48,64,3F,72,E7,AE,EE,A0,F3,05,60,F2,C0,D1,79,F9,69,AD,24,20,11,1F,15,11,9E,B5,E3,AF,F7,75,D2,A1,B2,D0,2F,59,46,65,88,76,FD,C3,93,99,51,22,23,27,B0,EC,C2,D6,23,69,6D,20,79,46,E0,2B,C9,34,A0,B6,30,1C,4A,98,52,96,31,AE,D3,02,90,72,FA,05,FC,2B,2E,A2,E6,6C,DF,5B,A3,5D,41,E9,CB,F2,61,36,4B,1A,DD,F4,26,F1,1F,8C,02,4B,49,DF,19,D5,21,37,A2,3D,69,06,6D,04,47,7F,B1,FB,8F,DC,D9,BA,70,AE,9A,B3,B0,C2,5E,2F,50,E7,33,9F,F6,D8,EC,AA,B2,8D,75,E1,01,A3,EE,BC,75,CD,CE,09,01,3F,09,F9,BB,18,83,BA,24,08,E5,56,43,1B,7C,FD,CC,0F,6E,B9,FD,DB,F5,C2,C7,F1,0D,04,4E,A7,2E,E8,3C,30,C4,F7,B0,28,4F,BC,46,68,22,95,CA,31,59,F7,6E,D3,EF,C9,51,26,5D,2F,17,A6,AC,87,99,C5,0D,0E,F1,D0,87,DD,C5,3E,28,9E,5A,39,82,81,08,1E,B9,18,D7,DE,0E,0E,CD,EA,52,3E,79,65,1C,94,51,54,AF,3C,46,A9,1E,BB,8D,E2,4E,67,B3,21,21,E3,D0,CE,E8,16,87,DF,02,7C,9A,74,E2,C4,41,2B,72,23,BA,B0,47,26,A3,1E,87,3B,AF,D4,B4,7F,DB,E9,52,07,49,99,23,38,39,D2,1E,09,16,0E,CD,77,F6,DF,C3,BC,3D,D6,A8,E8,D6,EC,E7,8E,07,2E,36,80,DF,42,95,D1,76,EB,1B,33,15,91,73,20,8E,B3,F5,B6,59,08,0B,1F,91,0B,99,44,43,24,C2,8F,EA,6F,10,72,7E,52,FA,0C,1D,89,96,68,80,74,91,00,FF,1C,19,BE,D0,A8,B6,F2,47,1D,55,0C,FE,5E,55,82,BA,47,B2,A4,9D,AB,5F,B4,EC,FC,F4,49,DA,AE,A6,8B,25,80,6E,79,21,DB,D9,1F,4A,B6,E3,ED,D1,0A,F0,EC,8C,AE,1D,CE,82,7B,32,72,7B,EF,AB,EA,38,20,C7,E2,7A,10,81,6D,FA,F3,45,9E,7C,2D,BC,01,9C,95,90,49,5A,6F,4C,4E,47,1E,59,C0,BD,7B,49,5F,D5,8F,AD,A1,34,67,A4,6C,2E,A9,66,92,2B,66,08,C9,E8,92,49,CE,6C,3E,4D,B2,DF,D0,84,3D,8B,56,F8,66,19,51,C4,AD,E0,90,D3,CF,3D,21,B8,18,5B,B4,BC,05,72,85,EB,9D,A3,86,D0,F6,C5,3D,BD,67,A5,07,A7,4A,0F,CB,58,BB,2B,CA,F8,85,C2,6E,5F,64,6B,D4,00,2E,7B,D0,54,93,48,87,FC,1A,F1,40,39,39,1C,5E,59,65,E7,81,DC,8B,A9,73,6C,5F,C6,20,F7,F1,5B,B6,A0,AB,1B,36,45,2E,18,C6,7D,95,5A,A2,1D,17,FD,E9,6C,04,47,3F,48,15,58,FF,18,78,63,40,0E,A5,88,81,41,E2,14,D5,EE,00,0F,55,E1,84,6B,2E,44,CB,6D,AE,47,33,F8,FA,5C,9F,9D,D0,2D,08,83,4F,AE,85,C9,BA,BC,AE,06,E6,B2,8B,44,6B,16,D8,8C,14,CA,F0,7C,63,7E,B2,C1,1A,0B,95,DB,FD,B3,45,5C,FA,AA,41,EE,9B,D8,42,A1,DA,21,34,59,A0,43,85,36,C7,C9,03,65,43,B4,A9,89,02,5D,39,17,88,24,34,6A,F2,5B,4A,C7,40,DE,D9,F1,D6,58,40,AE,22,4B,94,B0,6A,99,17,B2,5B,A1,97,D2,86,F4,81,E6,11,9B,C8,52,CB,23,E8,3D,C7,45,10,F8,B3,A3,EB,1F,3B,FC,42,93,75,43,A3,3F,27,B3,A3,7D,27,07,A9,CB,A5,8C,D4,C0,85,24,64,18,26,E1,FF,28,F2,8C,1A,72,11,81,20,44,B3,2E,00,66,EE,D1,1C,FD,66,CD,E6,17,36,6D,41,D2,26,46,8D,8A,F0,9E,41,2F,16,58,C3,7E,10,7F,52,CA,88,EC,9D,38,20,B3,12,8D,E6,05,EA,77,C5,0F,F0,72,36,03,98,6F,E4,73,39,78,C0,17,6F,F9,EE,B3,5E,70,15,F5,B9,7C,11,FA,CF,9A,45,D3,C8,FA,DD,3C,6F,A9,51,A9,A4,6F,81,50,89,53,36,20,CD,BA,CD,7A,3D,37,97,45,F1,7D,66,C3,5A,02,6E,44,61,08,79,6D,2D,52,42,EE,3D,A5,D8,A4,EB,37,08,AD,47,C1,37,00,C7,4A,0D,FD,C4,3D,4D,F1,2E,47,C2,F3,78,0A,73,C2,69,67,E6,EB,EE,B6,60,F2,54,61,9E,DA,43,10,72,AF,CE,E6,A8,9C,73,8F,3F,A1,9C,B5,BA,59,1C,BB,2D,72,3A,27,03,DA,E9,B3,3D,0C,5E,13,10,73,55,54,F1,25,5E,0E,72,0B,DA,DE,EA,A6,CA,F2,87,D4,74,E0,87,73,C1,AD,1D,4F,AE,97,93,82,0A,E4,7E,E5,AD,8D,41,64,86,80,A7,8C,01,89,0C,78,2F,B5,65,30,9F,F9,E7,9F,12,4E,48,E4,2C,2F,15,D0,66,77,03,0F,87,33,F9,3F,E8,CC,8B,E4,67,85,B5,B1,B8,3B,71,96,2C,66,33,C2,B2,D9,9D,14,53,9A,8B,E2,71,DE,EC,00,44,DD,2C,C4,C0,67,B6,B7,C9,93,60,51,0E,DD,5B,7C,AB,EC,E8,20,0B,B9,45,2C,15,45,66,C2,F9,7E,F2,2F,70,A2,AF,0A,B0,CC,D4,AC,D6,A8,00,C0,B0,D1,DA,43,3D,B6,19,1A,2B,03,B7,0D,4A,F5,24,6B,9A,0A,03,84,1F,D5,03,C9,1F,D6,E3,BA,8B,C9,79,49,30,CA,A1,0E,FF,D0,7D,69,F7,74,A9,D6,A1,98,E1,AB,F3,EC,EC,69,15,12,0E,91,1F,A8,1A,27,12,3E,80,0B,DE,8E,43,F0,70,AD,48,D1,1B,B2,C6,41,1A,1D,8E,42,FB,35,E9,58,C6,5D,57,EB,F3,DD,40,EB,DE,49,6A,5A,FA,2E,3C,96,38,09,E9,3F,41,CE,8A,7A,EE,0F,B9,05,C3,3A,55,88,6A,9A,11,FB,43,C9,D4,8F,72,62,FF,AC,4C,8F,9A,62,40,0D,3B,06,F9,AD,D4,DC,23,3C,2E,64,B6,0C,5D,9D,E8,41,0E,BB,06,81,F9,F5,C7,3B,79,1B,46,26,94,DE,C3,E4,9B,83,7F,50,EB,F8,1B,CB,03,D4,29,F2,42,BE,35,C2,A3,8E,03,6F,EA,2A,8C,17,11,04,20,6A,A4,71,63,AD,DD,E3,EF,D1,0E,63,48,D9,EA,32,CB,B9,21,37,42,1D,A9,C1,B8,93,35,71,91,45,9D,F0,D3,F3,8E,94,AE,F5,57,46,E5,79,4C,54,88,55,A9,62,50,C3,4E,8C,01,97,CD,84,24,D8,71,98,77,00,11,8D,36,AD,D7,01,38,05,F2,06,E8,14,F9,BD,30,9B,6C,DF,5D,4F,42,CC,0D,3F,FE,6C,39,5A,52,4A,49,17,E0,48,5E,99,1A,55,46,F5,2D,76,74,32,79,3C,77,E8,9A,34,7B,A4,32,28,60,5A,44,5E,F3,79,34,A2,08,40,2D,7D,7F,1D,B1,01,80,33,EB,20,1D,77,76,E7,87,C9,4E,11,7B,6C,9B,BA,CE,9B,39,D9,22,CF,88,A2,CC,94,50,97,AA,CE,0A,6B,DF,43,D0,97,6D,B5,95,3D,F6,8D,F5,F3,29,26,AA,DC,A1,73,FF,39,F7,3E,93,50,39,9A,98,35,F7,3C,C9,38,8F,22,92,AB,4C,84,E7,F7,EE,2D,47,94,7F,94,3A,6C,86,20,40,00,B3,A2,F5,FF,3C,E7,24,77,4C,51,4C,38,A4,60,BF,FC,AC,DE,82,FB,57,47,06,75,F4,42,EA,B7,EC,C0,CF,FC,11,EB,9F,09,F9,96,D8,42,13,D4,BE,BC,CA,94,C1,0B,37,6C,32,FD,84,F3,68,10,69,39,B4,29,84,29,13,5C,AD,AC,E9,86,52,8F,91,E9,62,2F,4C,AA,81,1F,81,FD,B3,BC,2F,15,DE,65,E8,80,81,A3,4F,22,7E,F2,5A,C0,04,D3,1E,1C,8C,B3,76,BB,93,75,C7,7A,34,F2,34,76,5B,E2,AE,60,C5,8D,9D,E4,D6,60,BB,25,87,F3,76,82,09,D2,C7,A9,56,32,56,DF,A5,FC,EB,6D,6A,C1,82,E3,4F,D3,D2,C9,D6,1F,35,D0,63,29,35,2D,55,B9,F8,18,D0,BE,0D,79,40,D5,05,BC,D7,D9,6F,6D,A9,A5,74,D5,BA,92,EB,45,55,B4,2B,05,8C,2E,8B,6A,D6,BA,CA,3B,D2,67,19,85,69,B5,A6,2E,C4,71,98,1B,A5,B4,9C,4C,2E,2C,A5,62,BF,E4,51,4C,FD,81,AD,5D,75,F6,7C,55,EF,D2,10,48,00,73,54,FD,AD,3C,0B,FC,6A,07,B8,E2,00,A2,2B,19,03,A9,09,58,B6,6D,6D,A1,93,75,58,B2,E8,24,31,00,82,45,C1,5E,29,5E,05,D4,F8,5A,20,CD,55,6B,2D,2D,8F,0A,33,2F,10,A8,EB,2A,56,7D,40,22,53,D5,92,78,61,3F,0E,63,48,04,13,8A,9C,81,A3,D5,23,62,70,63,E9,18,1A,E4,69,38,8D,74,1F,6F,59,66,13,1A,27,D8,E6,90,FC,E9,82,87,32,D0,41,48,EF,EC,9A,C5,92,7A,02,DD,7D,C2,1E,3D,9D,F5,BF,2D,7F,37,D7,83,7A,7F,77,BC,5C,B2,C5,A7,53,D4,CF,E8,F8,61,87,75,C9,A5,8D,60,3A,61,A6,58,CA,7C,31,C7,78,B6,6A,74,DA,29,00,C9,10,87,04,4D,8C,59,6E,54,20,8D,9F,F5,C3,1E,4F,8D,49,C2,39,1A,C1,64,1C,5B,3C,81,5E,B8,8C,0B,18,3A,0D,13,E7,9C,A6,5F,EF,4B,2D,40,13,3A,57,E3,E3,C8,44,5A,00,24,E4,13,75,F1,1E,A7,E1,82,DA,86,F3,DE,2D,C4,C6,99,46,A0,7C,93,58,01,A9,60,15,02,E8,42,EA,70,F7,3E,26,F5,E1,D7,D2,A1,3C,30,48,1E,7C,F4,18,DF,B7,68,8F,80,C8,B2,0D,30,CE,34,87,F0,E7,4D,59,D5,3E,ED,8C,53,CA,9C,A9,31,7D,A2,60,C9,04,F9,87,DD,B0,86,DC,57,82,C3,1C,AD,2F,BE,62,EA,A8,0D,68,89,19,D9,0C,E5,6A,62,55,15,09,96,93,D2,3F,4F,4C,21,F0,74,F5,AD,C8,FF,50,C9,21,22,36,CF,6F,9E,CA,F4,AD,9B,27,C8,B0,2C,7C,15,D5,FE,28,E7,06,FC,5B,87,A5,6C,32,DD,CA,53,08,60,DB,20,BA,0A,5F,21,2F,28,80,C8,DC,16,D0,39,5A,23,56,4C,35,05,24,59,7B,B7,48,F0,E4,D7,14,11,DC,5D,2C,47,1C,57,59,B9,CF,21,3F,AA,B2,3D,EC,CA,62,AE,F4,C7,C2,21,F0,C3,2C,46,AA,F2,B0,7F,42,FC,18,58,9B,11,AF,BC,43,22,64,7C,C6,48,D3,AE,77,3C,FE,D5,98,54,03,7A,5B,FE,F1,74,E6,EF,C0,9C,24,67,41,72,DC,E7,6E,64,0E,6B,C1,38,A2,A0,3A,B5,36,7C,DF,02,F5,A7,C3,E2,D5,84,C4,8A,BC,FD,53,CA,24,47,74,20,A8,FD,B6,61,E7,BB,66,ED,C7,C3,E4,92,9B,18,27,DC,63,90,60,24,A7,2F,29,7B,A8,99,D5,E3,AF,41,89,55,F9,D7,F2,46,CD,A6,5B,43,C8,B8,CD,AB,DA,4C,A8,4B,B2,09,76,74,09,0E,8C,E3,FC,0F,D1,50,47,79,32,07,CA,29,00,65,9A,A2,5D,57,29,42,96,A6,D6,12,CF,9D,BF,35,82,0A,9C,3A,F9,B0,89,ED,2F,29,77,FC,9A,D7,E7,53,CF,C5,D3,2E,9C,61,F9,0C,3A,CD,83,2D,37,E6,C8,98,41,BB,2F,8B,7D,D2,9B,AF,BA,61,5C,AA,9E,C6,D4,97,C6,7E,E0,91,6A,16,FB,D7,7A,A4,23,BB,FA,44,4B,BF,F1,16,C7,7A,6F,E0,42,D7,90,C0,C7,BD,09,57,90,2A,47,2C,C0,48,55,F1,47,B4,AE,7A,27,86,45,89,8E,11,5F,A7,42,C2,C5,C8,61,00,E8,E2,70,01,51,5B,3D,0A,76,74,1D,44,10,02,AE,52,1F,38,8B,1B,F7,1F,5A,AF,E4,7F,01,FF,B8,AF,27,E6,A4,2E,64,B9,BF,B4,FC,E0,DA,05,42,62,8B,2B,68,07,40,F4,55,70,0C,66,33,17,F2,67,B0,D7,52,93,56,4C,F6,71,EA,99,39,54,6A,B5,13,0B,E4,F5,8F,1B,50,E0,DE,BC,CC,BA,A0,1F,C1,AB,A6,C6,84,DF,D3,3F,2B,FE,D0,D9,C6,0F,79,A3,53,A1,6A,62,5E,62,C5,B5,2C,DF,C4,20,D0,3E,10,41,6F,AD,6F,7E,D0,CB,45,24,4F,4B,4F,74,FC,96,C0,51,DE,24,29,E5,6C,6F,86,7F,2D,27,00,76,E9,E9,29,65,B1,19,72,95,AD,99,0C,8E,95,F0,E7,02,98,C6,CD,31,05,42,B4,49,14,04,06,5B,BC,6A,6A,7E,2E,FC,93,1D,89,BC,2B,6B,A7,0E,15,D9,ED,A2,2D,8C,2C,83,5B,E2,A2,78,77,B9,3A,19,1D,26,07,72,3A,7C,0C,80,F8,2A,D7,6A,BC,0E,50,66,63,2F,93,1A,FC,FA,30,28,D9,4B,77,61,91,91,16,2D,2B,7A,1F,33,1F,8D,53,D0,76,1F,C8,C9,EF,AC,7C,CB,FF,50,14,64,7E,A5,BF,B2,49,B3,89,93,DE,F0,58,92,AF,F3,86,FD,E5,CB,87,75,C0,22,2B,19,91,5E,44,A1,DD,D0,D7,30,04,4D,26,9B,47,AB,F2,ED,B3,1F,62,56,A7,DD,4C,20,11,33,50,98,AD,90,68,BC,AB,D3,FE,00,1A,DD,66,CC,BD,60,07,E9,83,05,5B,28,87,ED,A4,95,68,0F,62,26,4E,92,32,D4,5D,3B,46,07,2E,0D,24,A3,D4,34,5B,D7,80,77,C6,77,DC,F6,7B,62,CF,6F,3D,BC,7B,61,D5,0B,22,8B,A0,10,9F,5E,F5,BE,E6,27,28,D6,D5,C7,A4,0D,9D,BE,2D,C8,EB,39,81,7E,7B,0E,AD,02,9A,41,7E,DF,AD,39,85,B6,F3,D7,4E,D2,0B,AB,2A,24,72,2D,9D,3E,3D,04,7E,5E,D6,06,A9,1C,83,F6,8B,92,DA,74,2C,F5,B3,FD,AA,07,5B,03,BF,4D,87,64,F4,29,B5,10,C8,18,C3,A5,25,E9,D5,99,77,63,3F,0F,54,B6,83,61,DB,4B,61,B5,05,1B,4D,53,4F,D5,F3,98,3D,97,56,50,CB,1D,E5,D2,D3,05,33,82,91,20,D8,76,A5,98,87,8A,FE,7A,16,59,1A,BC,2E,10,FE,EC,40,BF,72,47,0D,52,F0,F8,7A,0B,F5,F0,6C,85,CF,65,87,03,B7,EC,C9,5A,CE,C3,AF,9E,C0,71,A3,C9,91,B3,88,43,3B,17,49,34,1E,06,D0,2A,4F,C5,1D,3F,A7,06,3F,9C,9F,15,1F,D7,DB,5C,E8,E4,6C,6D,39,C4,AA,61,8A,3B,E5,8E,B0,75,24,6D,F5,BB,50,39,4B,D6,C9,A6,39,E6,A0,37,3B,37,4E,34,FB,95,CB,00,26,2E,FC,96,81,24,13,AF,F6,70,79,4F,83,CA,1F,DE,DC,E8,0F,96,6B,C7,C3,AC,95,88,FF,D1,55,C4,F2,E6,13,D3,CA,A8,37,6B,F1,FD,CD,31,2F,D9,BD,76,7C,5F,43,9D,FB,6F,EB,D4,86,B1,7E,AF,C0,38,27,BE,D5,2A,CC,DC,C7,A7,C2,4E,D3,4A,CD,7C,17,FC,C4,25,EA,A2,94,C6,2E,88,8E,BE,93,F9,3F,6A,F1,74,DF,51,05,30,3C,64,B5,10,0D,71,AD,8B,A5,38,E8,C0,0C,EA,48,98,44,8F,29,27,5A,71,AB,50,D8,3D,03,E3,C2,59,15,81,FC,7D,A1,92,2E,30,EA,0D,77,B7,A1,C9,A5,45,16,78,13,DF,49,C0,59,F7,49,4E,3C,79,60,F9,90,EF,1D,F6,B0,08,48,C4,C0,EE,8B,84,F5,E3,97,31,43,B7,6C,21,B2,D0,17,55,AE,BA,73,7B,37,23,EA,51,51,DD,02,9A,CD,73,CC,D1,BA,93,34,9E,4C,6D,C3,7E,B0,E5,12,FC,C3,97,99,03,7F,C5,27,EB,CF,06,23,3E,AA,2D,52,CE,7B,AD,65,CB,BC,0D,A6,B5,AB,00,EF,CC,20,B2,7E,6E,4F,7D,75,1D,ED,C4,73,40,EC,8A,10,2B,D9,DF,19,DE,4D,FC,9A,6C,83,B5,36,C6,2B,E8,C2,4D,B4,D4,5C,FC,80,70,93,C9,C8,11,E7,B7,D9,A6,F7,12,61,ED,CD,9E,E2,7F,AE,78,C5,98,20,66,06,40,01,B1,4E,2D,46,81,9E,9F,AB,59,E9,8A,4C,54,50,A4,1A,AB,CF,0B,07,5E,37,EC,CC,90,29,F3,87,14,D4,97,04,A5,42,98,A5,20,3C,9D,1C,94,DC,D4,C3,55,52,61,77,69,07,CF,6F,1F,59,E6,97,12,43,ED,97,AB,8F,B1,50,A9,42,EF,0A,7D,89,B9,FD,3F,4C,33,D7,E3,6F,79,FA,D7,66,E4,59,A9,A9,DC,50,D1,A6,0D,E4,3C,3E,A0,B3,1F,BE,42,F6,90,14,79,1C,F6,FE,82,2A,74,DF,6F,F9,6B,E7,F0,5F,7B,18,ED,F0,E8,CA,72,EE,A9,A2,9D,38,A1,2D,E3,4C,1F,2C,B9,CD,7D,F8,7D,11,C2,E9,72,66,84,4F,FC,18,0A,80,28,26,18,0C,4A,95,1F,A0,34,0E,24,41,5E,97,90,87,3E,76,A4,1E,50,DF,71,F4,21,87,0B,67,A9,EB,2E,82,7B,2A,EA,1A,FB,06,3A,ED,43,E4,D4,92,84,D5,1A,5B,81,C5,56,3D,99,AB,48,7E,F0,F8,D7,2C,3D,AA,15,44,51,1C,05,F1,65,16,ED,B3,6E,B4,3A,96,14,9C,78,2F,E1,11,2D,A0,09,74,91,63,FF,7F,45,91,DF,5D,8E,41,78,DA,1F,06,35,44,91,2C,7C,10,A7,B2,ED,D9,13,F2,E4,40,84,9B,6E,48,A1,64,35,4A,34,9F,0A,FA,24,FC,15,E0,15,77,69,81,1C,09,9D,CB,4B,55,7E,10,41,E7,67,EF,1D,9A,49,FA,EE,0B,22,E9,1C,B7,3C,3B,8A,7C,19,16,A6,51,C4,9D,64,5B,D4,BB,80,B8,DF,59,99,3F,B5,2E,17,47,61,86,CC,D9,1C,35,EF,BF,77,DE,9A,B4,41,C2,7C,95,75,81,DD,3C,B6,0C,0D,76,C8,B8,3C,9E,1A,9E,DE,75,3D,99,0A,EF,49,1D,6C,73,CC,24,70,DE,D1,F2,17,37,69,9E,03,1E,ED,64,51,5D,E3,E6,E1,54,54,94,1F,9F,3B,36,E0,1D,D8,35,CF,79,4D,39,00,3A,49,B2,9E,33,69,BB,A0,81,CD,7C,BC,B5,50,BC,0B,35,A5,A2,7A,CF,66,49,B0,91,DB,7C,2D,99,1C,95,48,6D,55,E6,58,FB,4E,25,40,94,71,48,AB,C5,74,09,B9,EF,AF,25,D2,E8,03,A2,01,24,A5,66,DA,A5,27,B7,1B,89,F6,8A,B3,AB,E1,9A,87,72,B9,27,56,C1,F5,4C,8B,07,BD,68,F7,D5,A9,B9,B3,2C,D5,56,A1,4C,F8,51,32,06,15,42,51,F3,AC,3B,DB,49,46,BC,1F,93,A1,68,0D,8E,AF,7C,00,D4,1D,47,69,AF,D3,79,DA,0D,1B,C1,1C,D5,DF,94,2B,A2,07,B3,FE,D2,5E,2C,3A,94,EC,DC,B6,AD,62,29,C2,D7,5B,27,83,E2,22,F4,47,A1,28,46,E6,E2,EB,84,EF,A6,16,5D,AA,34,25,9F,05,38,E4,B2,37,B3,41,81,37,45,71,46,8B,F6,15,98,9F,9B,71,77,05,1C,FD,5A,D6,07,3D,B0,D3,C9,E2,76,5F,1A,F0,E6,64,2E,26,34,B7,05,27,8B,71,71,61,10,50,D2,28,EF,03,D1,BE,A0,09,45,BA,3C,3E,CA,C8,24,FE,B7,85,72,71,01,55,0C,FD,28,34,EE,45,20,C0,26,E0,70,33,10,40,3A,C5,48,70,4C,B3,29,CA,B1,6A,8F,72,47,EE,94,39,E7,3A,1C,A6,61,6F,77,84,90,82,0B,A1,1D,74,51,FA,E7,3C,C3,06,0F,37,C9,88,53,19,FE,CC,53,8F,1B,AE,DA,4B,7F,E5,73,27,A3,75,9F,56,44,8E,D8,06,37,C4,A5,81,6A,1C,5D,61,64,6B,08,DE,49,37,34,D8,6D,B1,C2,83,F8,10,6A,95,BA,19,5A,BF,E0,EB,D1,A2,93,7D,E5,96,36,73,CB,AD,40,47,71,AF,08,5B,6D,6E,98,B0,1A,6E,0B,CE,03,88,65,FA,1B,71,BD,E7,4E,EF,B8,E3,28,E2,80,05,8B,58,A4,5D,6B,60,BB,B8,7D,C2,2C,7A,66,D8,5A,DE,B6,FE,E8,3B,C7,F4,71,87,17,30,23,FB,16,28,5C,B0,20,4F,14,70,68,74,A4,5A,03,69,44,35,90,C7,E7,30,32,36,51,9C,92,9A,C2,94,5E,18,D7,EB,01,F0,A8,1C,E5,69,31,A4,3E,13,AB,E5,81,90,77,E4,0C,65,5F,F3,0C,90,28,4E,09,78,5D,44,19,D5,05,DA,F0,5A,A2,15,5B,FA,4F,14,00,50,4F,7E,44,8B,A9,F4,27,42,39,92,FD,AA,61,75,A4,B1,02,36,46,69,82,3C,F2,5D,74,31,AB,AB,25,27,0E,C0,BE,F1,6A,81,05,1B,8C,14,52,FC,21,CA,44,C3,00,4C,BB,DF,95,E3,6B,B3,D7,B6,3F,95,A0,23,EB,70,81,1D,1E,83,1D,E2,70,2B,7D,15,6C,EA,74,CE,5D,54,3E,F7,22,10,B1,2D,F4,F0,AA,6C,05,AB,C3,4A,5B,DF,0C,62,EE,B0,88,02,79,80,38,3A,07,0F,1D,91,81,3F,E6,AE,EB,F9,02,90,EA,43,C4,C9,F7,05,21,B5,A3,53,9B,3B,CF,A7,BF,D9,A1,7D,7C,97,E8,00,AF,8A,84,65,3B,6B,B2,0C,E2,9C,21,64,66,AF,32,57,2A,43,E7,DF,4D,2A,66,34,F9,64,A4,79,5A,F9,90,89,89,57,C2,FD,C0,16,AD,11,7C,F9,E6,5C,2E,D5,DD,7F,5D,02,01,7C,B4,0D,39,C0,1D,FB,C8,2D,49,02,60,CC,5B,A1,F8,52,07,4B,97,E2,B4,D5,04,3F,53,56,19,D7,91,C9,97,95,14,21,AE,95,60,2D,EA,29,4D,C4,69,FC,84,44,0B,39,6F,FB,27,A0,75,C0,4A,BD,37,19,4B,4C,F9,26,A6,7E,85,A8,BE,F1,81,C1,03,F2,78,1C,BD,28,89,27,25,9C,64,B5,9F,5A,F5,4B,CA,FE,2F,3B,8B,06,1C,6E,67,71,AC,E4,42,9B,1D,F0,68,29,4C,2E,D2,E7,81,D0,F4,36,AE,A9,4A,7D,14,3D,BC,9C,22,0D,36,00,F6,52,8D,FA,55,84,45,C4,63,14,5E,F3,C1,81,E9,F2,3D,D3,BF,EF,0B,C5,0A,6B,1D,86,B1,FD,AA,D1,FF,97,9F,5A,55,F3,7C,24,65,E0,09,74,FC,F6,F7,B9,E0,AD,AA,19,31,8C,70,FD,9B,1C,D7,6F,EF,E9,6A,94,74,EA,FD,C4,C2,52,64,38,8D,13,66,EA,5E,87,FA,F2,B8,18,B4,A3,D1,07,00,AC,F9,57,93,55,C5,AB,04,85,43,01,04,23,C1,46,36,DA,C3,D7,90,89,F9,CC,40,26,EA,9C,C2,7F,EE,B5,D9,81,CF,DE,CA,93,08,5A,EF,DD,1D,90,FF,F6,68,37,C9,64,90,EA,14,02,02,DD,A9,11,AE,9D,2E,FA,D2,50,F3,CC,D3,20,25,DB,60,86,EB,3E,CE,DB,CE,39,BC,83,E0,1B,F8,31,30,B8,FA,66,BC,71,1B,D1,3C,64,EB,C0,05,33,22,80,43,C2,1F,40,9A,88,DE,64,FE,C7,F3,A4,3A,4C,2D,4D,9E,56,EE,0E,93,34,62,6C,AE,1F,78,59,EE,9B,25,96,86,AE,95,98,07,57,C3,C8,0B,52,A9,4F,1A,81,37,43,90,85,DD,DC,6E,6B,61,84,F8,C8,1D,71,01,AF,FE,64,57,AF,D2,10,8F,50,90,E8,EC,A4,05,09,B1,7C,E8,6F,27,D7,FF,42,27,B6,5F,0B,C9,A7,75,E8,C2,82,67,83,7F,E5,53,7A,47,F7,B7,6B,2C,C3,A1,9A,48,00,AB,85,E5,61,CF,5B,EE,6E,D5,A0,8D,C5,98,7F,00,88,49,FF,6D,45,FC,12,88,AD,7E,A1,0A,6C,38,24,6E,EC,DC,4C,CD,F0,21,E3,C1,BD,26,5C,CE,32,F2,38,0B,17,1E,D9,FE,32,1F,A9,41,FB,15,AE,71,C8,4B,50,B8,B2,26,07,F0,66,6D,D6,2D,13,77,AB,AB,C5,02,C3,09,FD,8A,FB,83,3A,16,FE,1D,0A,97,CF,F2,EE,67,28,C9,69,96,44,FB,B6,7A,89,B5,B5,D1,8E,29,1A,E6,E0,CA,71,61,A6,87,0C,F3,DC,38,C9,72,5E,FC,96,A6,C1,A9,7E,62,15,E0,C5,A0,13,5A,B8,CA,1F,CA,72,F5,3A,7D,A7,83,B1,A1,07,DD,42,A8,0A,85,41,C7,77,7E,95,0D,AE,B8,DD,35,88,7A,D6,30,8F,7D,69,64,DF,3D,5F,C9,5A,A3,FA,5A,55,8A,87,FF,CE,A8,22,67,D4,EA,6D,08,1A,97,DC,2F,F0,52,04,CF,BA,EF,EC,BD,13,BB,4A,79,80,40,63,20,D9,DC,3A,BD,08,4A,03,F5,ED,1A,23,EE,7D,39,F1,DB,1D,EC,27,38,72,2A,86,42,E1,4E,14,2D,89,50,53,D4,CF,B2,9C,EF,0B,26,44,F6,AD,DD,54,63,A0,D3,91,50,01,C9,32,62,89,CA,DB,8A,FA,49,CB,2E,6A,20,9B,03,0F,A0,50,0F,EF,74,56,4D,F3,FD,08,7F,4E,AD,68,3B,CC,41,C6,C3,3A,32,07,F0,8C,7B,44,D3,E8,27,57,F4,E3,FD,E4,DF,C7,08,9B,57,BC,70,D9,1D,64,0B,F7,F1,64,CD,45,83,89,31,58,91,21,3E,70,12,4E,82,08,21,FA,D0,BB,DE,D8,CB,E8,0B,EA,87,98,B9,77,8C,35,B7,7D,FB,4C,AA,2E,48,77,61,16,C2,AD,6F,69,2B,F6,60,4F,13,06,C4,84,FB,69,8E,80,F8,5E,8D,D3,39,48,3B,79,62,E9,EB,B5,D6,2C,AA,B1,AA,5A,66,FE,5F,29,24,A7,B0,5D,A1,66,2D,83,2B,94,8A,A7,4D,4D,4E,5A,E8,4E,71,41,66,07,87,94,B9,8B,D1,EC,31,DF,2C,5A,10,63,BA,24,23,71,3B,F1,08,97,94,AD,34,A2,68,32,5C,A7,C5,99,72,C5,9C,A3,B2,34,41,51,8E,D3,C7,DA,3A,B1,22,66,7C,86,57,25,CC,06,69,0D,80,43,75,FA,2A,D5,74,4A,77,A8,3D,07,E1,49,26,D4,A5,7A,BE,B2,1A,7A,8B,37,93,91,AD,87,9B,5B,F4,0E,A7,72,7E,D8,97,F0,E8,E5,00,BE,FB,D6,2E,8E,34,F8,87,8D,C3,A0,6B,C9,BF,52,EB,B5,F5,E2,88,1A,02,07,46,A3,DD,78,6D,62,EE,88,E4,BF,E4,47,7F,80,7D,A8,33,90,75,2C,81,1A,6F,15,0F,8E,BB,5C,ED,56,AF,46,09,48,BD,1E,2A,C9,94,C1,C2,E8,BC,08,C3,A0,43,60,15,72,A2,32,B6,57,12,33,87,18,AE,9B,91,89,93,5C,5F,06,A8,55,EC,60,17,F0,79,F8,C4,B5,16,85,A9,30,9E,C2,FD,C0,0F,45,C6,B4,6C,50,50,46,DB,99,B2,FD,8B,2D,AD,BC,32,C2,2D,0A,DD,4D,1E,9F,C8,C2,66,29,B8,AC,3D,C8,6B,61,50,70,9F,54,39,4D,D6,2B,6C,DA,EF,5B,37,FE,41,96,15,86,BE,8F,9A,33,4F,6A,0F,F6,E3,DA,FC,5A,E9,2F,33,B4,04,5D,1A,95,02,74,FC,FE,F4,F3,AE,08,AA,74,7F,24,65,95,53,7A,15,FC,6A,97,2A,6F,FF,87,24,EC,E1,DD,8B,A1,C0,99,5A,12,2D,12,28,5F,94,8F,F6,48,79,FF,8A,12,FC,6B,6A,DE,48,7E,54,42,2D,FD,4D,34,D4,6D,39,BE,DC,29,CE,CB,54,04,D5,20,B2,45,96,C2,CA,6D,49,90,94,1A,42,27,E7,18,63,04,95,F7,B5,DA,52,5A,E5,61,14,5A,C8,21,E2,2D,01,F1,7A,FD,DB,12,3F,90,24,D1,8E,9C,0A,66,44,B6,95,9C,83,6D,EB,4D,F8,41,0C,33,88,95,A4,A7,86,F4,50,C4,C5,D8,74,0A,D8,92,6C,B0,06,83,9E,8D,82,B5,FE,DE,C7,54,50,70,0B,EA,BD,C1,9E,6D,D8,1E,72,8B,1A,DE,6B,73,9C,96,C2,DF,9B,A7,F8,E7,3E,3A,CA,18,5D,0B,C9,84,41,A3,F4,7A,7D,62,30,A9,F9,47,8D,41,EA,02,67,EF,38,8B,12,5F,7E,C0,67,2B,7F,7C,C3,47,22,64,90,DF,3C,91,AD,E3,56,31,56,22,96,28,78,42,9E,08,B8,57,A4,4B,97,7F,47,B4,7B,FC,82,E7,CA,23,92,9B,AE,06,23,8D,38,92,48,AC,73,07,B9,19,2B,8F,7A,C5,7D,6D,4D,85,83,5A,E5,86,9B,EE,CA,72,DC,6B,71,F8,A6,A9,23,77,9C,A2,10,EC,C3,FE,91,08,69,F1,CB,58,15,4B,57,C8,8C,0F,16,03,E7,C1,BF,43,86,D9,BB,CE,D5,22,86,19,34,C5,40,FE,9C,44,0A,BE,07,BD,8D,F8,D1,35,E2,BE,F1,60,4B,77,07,4B,46,32,66,DF,E5,D0,7A,B3,39,05,91,34,9B,0B,1A,7A,0A,65,4D,EA,CA,68,33,28,16,47,F9,37,FA,76,AE,25,2C,6B,A4,C6,C3,A6,86,D5,7F,99,92,29,6A,87,4B,1F,AA,A1,D8,73,C1,B8,59,E1,12,96,DC,EE,E7,F9,C4,8E,DB,F5,E2,C5,88,60,D5,72,BA,35,CE,34,26,39,60,7A,08,AA,42,72,47,60,24,21,F8,C0,0D,4E,1F,D4,52,AF,FA,17,B6,3D,BB,BD,F3,32,08,67,F6,12,F1,C3,44,04,99,42,D2,53,42,0A,0D,12,A9,ED,40,3A,E2,F0,2A,EB,1D,C4,DE,18,00,A6,3D,72,C7,85,18,49,4D,9A,85,2E,BB,19,0F,B2,98,DE,68,D3,61,D1,98,37,4B,99,00,49,F0,7B,57,D4,21,D0,C8,B1,0C,E5,BE,38,D3,86,6D,88,AA,EB,B2,4F,E6,CB,00,CF,66,09,3E,C0,0C,55,5F,C8,90,C9,26,94,9A,63,B8,EA,51,EB,E6,C7,3A,7F,F7,45,F8,F6,A4,79,7F,D3,43,99,83,3E,DE,61,58,FB,6F,9F,2A,AC,2C,47,2D,11,6D,C2,DA,B2,CC,DA,81,65,F2,68,B5,10,14,2C,26,06,EF,BE,63,78,35,F3,C5,1B,26,E5,EE,18,4E,FB,39,BB,41,E5,C7,12,64,19,EA,85,69,DD,06,32,83,DF,03,C0,97,CD,5A,62,B8,DF,04,3D,C4,87,96,A1,81,38,66,AC,50,82,2E,F9,23,25,39,AD,46,E1,FF,6C,CD,5B,4D,31,B6,6D,E6,BA,39,F9,B2,86,D7,92,73,D6,2D,E3,1F,8D,87,79,BE,D9,09,16,31,9A,90,6A,F7,22,BE,82,6D,87,AF,BF,6E,37,ED,77,9C,20,D8,96,5E,BD,94,26,91,79,A2,DC,00,31,C2,FC,AD,E5,25,B9,F4,20,5D,ED,27,31,74,9D,27,C9,5F,3E,93,80,DB,4E,22,4E,54,06,2E,4B,D0,29,C0,75,A1,D6,B3,F6,A4,18,DE,5B,97,A7,4F,55,DB,90,3A,31,06,BF,26,09,EA,EF,4E,FB,41,E9,43,D5,CD,D5,6F,F9,FB,F3,23,30,E4,9F,04,66,D8,80,10,99,D1,99,B2,A8,FE,93,11,6A,CA,64,39,A3,0C,C5,02,4E,5C,F4,A8,F3,7C,10,8C,2B,2E,80,14,E8,A1,BF,45,2D,DE,1F,F3,A3,A2,22,FE,88,6E,88,A3,1B,57,6B,A2,D2,84,5D,55,91,8F,C1,0A,4D,C3,D1,A9,06,A7,E8,49,6E,44,07,49,69,1C,C8,CD,B5,89,45,C5,BC,8C,D5,B0,55,15,CD,57,6E,16,A3,02,00,57,48,66,5B,4C,B5,D3,15,34,64,D4,5E,4A,4F,B0,A5,18,75,E4,EC,8E,AA,A6,83,5F,28,1A,F7,90,00,3E,96,33,E0,DE,1A,67,37,5C,DC,9F,04,44,2E,86,32,45,4D,4D,C0,97,53,79,10,BA,22,73,13,AE,40,60,64,29,C3,15,2B,A8,61,30,91,AD,CE,42,34,14,62,C0,EF,B5,2C,71,B4,00,DC,EC,3C,3F,BC,FE,31,2A,F5,00,53,07,34,7C,4A,17,9D,07,E5,26,9D,29,CD,71,9B,2A,0E,0B,13,23,A9,BF,A1,43,2A,B2,77,3C,FF,92,73,2A,C2,DA,29,2F,C9,3A,44,82,E3,C2,A7,7D,3E,C6,27,F8,1F,11,1F,4C,F8,73,A5,99,C1,EA,45,C5,66,60,E3,3D,AF,B9,D1,20,1D,0D,3E,35,06,1C,65,8C,F6,9E,A6,6F,55,60,11,00,2D,0D,5F,4E,F1,14,23,C4,01,BC,03,0B,28,0D,69,6A,A9,FC,5E,3A,A3,D4,BC,B9,CF,9A,09,F1,FF,83,DD,8B,AB,0D,D8,8F,BA,8D,C3,98,06,46,2B,35,98,4D,D8,94,C0,65,1E,46,51,2A,EB,53,85,12,1A,4E,2A,B9,EA,FD,C8,86,06,20,94,83,6B,69,BC,71,CC,C8,B2,A1,32,A0,06,68,06,94,B3,2B,33,B2,23,C4,74,72,09,39,6E,54,1C,A9,78,DE,43,D9,1A,E1,26,8E,7A,6F,25,AF,A4,3C,F6,77,63,55,04,34,F6,E3,E6,8B,55,48,46,D9,7A,B5,DD,3F,B8,D5,13,77,18,C8,D5,1C,AC,9D,51,D2,81,A5,06,8C,EB,11,AB,FB,D6,15,33,0C,11,94,B3,DE,8C,1B,6B,9A,0D,82,99,82,19,9F,AF,AE,67,2D,F2,B8,FC,8B,E8,61,37,FE,CA,01,82,19,0F,2E,D3,65,3E,8A,6B,A4,A9,50,93,E0,F3,29,53,E4,26,5C,06,CA,D0,43,BA,23,74,1E,74,0D,E0,02,E6,75,E6,11,3B,EE,E8,99,FA,CF,26,7C,24,A3,AE,C9,DD,B4,90,54,9D,BB,A8,12,CA,7F,2E,E1,44,B8,89,35,81,AD,21,37,20,49,1F,93,4C,F0,F9,0F,5A,97,19,B1,7B,92,7F,DD,60,82,8E,B3,E2,94,56,A1,F8,F9,E9,6B,2A,53,95,03,F6,0F,32,C3,B8,8C,6D,5A,89,F0,1E,77,23,99,28,D3,12,D0,8D,6E,50,88,C2,61,3A,F9,1C,48,B8,49,4F,8D,8F,1B,12,30,81,C2,F4,EA,6D,19,BC,DF,4E,19,1C,07,D2,2D,CB,A4,C4,23,7A,81,80,BE,45,4A,B6,32,83,85,EF,0F,78,2A,D8,87,61,24,79,94,6E,F6,23,A1,1A,63,44,4A,C8,62,05,90,A3,44,2C,7A,AB,DE,92,F3,11,A5,39,49,9E,30,BB,4E,69,7E,E0,19,F9,D5,E2,41,13,F6,5F,21,D3,6B,33,2A,65,08,4B,AC,42,FB,3B,3E,D7,1B,30,70,87,7F,EE,EF,70,C1,59,0E,56,46,32,39,72,42,61,8B,D8,31,EA,1D,0B,E0,4C,14,E5,F1,66,F1,C1,57,DC,57,20,82,17,2E,46,D3,4E,6F,2A,BE,42,92,59,23,55,B9,99,49,A6,D9,C6,F3,F0,A2,8A,E6,79,B1,8B,90,21,43,EF,1B,EF,F3,99,0F,7E,B1,DE,8F,1C,6C,EA,74,A6,9B,4A,A6,46,E1,DC,1E,AA,AD,81,0B,66,D8,0F,D5,3F,EA,F6,A6,43,65,F6,91,EE,42,DB,C1,C0,52,D7,DE,25,C6,DE,7B,EF,A4,4F,3B,57,8F,0C,CB,E2,D0,38,F7,92,09,6E,99,9C,36,55,E7,C7,40,68,FC,EB,50,20,DD,74,A2,CC,21,4C,F2,D2,19,EC,DD,96,D9,15,0F,A9,F4,DC,86,12,35,1E,59,4B,94,B9,22,72,7C,BC,3B,C3,B4,1C,64,97,AC,BB,A9,E3,72,F1,DB,23,3A,E9,DD,A6,06,56,B1,EF,FB,63,9F,C0,87,D6,FE,BA,7B,00,C4,07,C0,33,52,7B,5C,F3,14,D5,6F,36,51,1B,AA,8F,06,2A,7A,E4,D0,35,67,B7,E6,BF,02,BF,80,6C,1A,D2,EF,E0,7E,78,11,27,68,FB,49,00,D6,8A,11,14,13,FC,13,5A,BD,BE,49,10,3C,C3,33,3C,3B,55,62,35,99,ED,14,10,3A,7D,11,B7,BB,07,97,B2,09,3E,EA,E1,21,DC,FC,82,F4,F7,75,23,F3,8A,AF,53,60,AD,74,F5,11,8A,C4,2A,5D,F2,0A,5C,16,9D,8C,8F,CB,C0,93,CA,71,69,2E,E8,80,C5,66,DB,54,45,FD,B6,72,04,CF,0F,F3,5D,08,64,52,47,E0,91,78,D0,10,2D,9E,37,DB,A7,AF,2F,82,BC,95,A4,C1,D9,9E,74,D3,D1,54,CD,D8,D8,5A,F5,E3,85,9A,D2,05,EB,74,FB,E7,EF,CC,98,84,17,E0,C6,E8,1A,70,17,42,51,2E,66,B6,F7,4E,41,12,36,FD,43,3A,8D,42,63,E8,A2,72,83,0C,8D,FD,AB,C8,53,39,F2,62,12,E1,2F,9D,83,08,23,40,4B,4D,AA,14,DA,CF,D5,57,3C,84,21,66,FE,A0,5B,C7,A7,56,14,4E,B2,8E,88,BA,74,95,C9,4C,BD,8F,BB,A9,8A,A9,2A,C9,9C,0E,8E,E6,50,80,44,55,1A,D5,41,F6,8E,6F,6F,EB,02,70,F8,88,FC,EB,3D,FC,E8,DB,82,3F,B9,95,B1,BC,A4,D6,54,FA,C1,A7,61,AC,62,2D,5B,25,C7,05,BF,87,C0,85,4D,3D,EF,26,C0,AE,4E,99,DC,89,62,56,1B,F4,30,8C,14,B9,4F,01,31,5C,56,FC,74,90,A4,0A,EE,D0,45,B7,44,92,FF,81,A1,98,8B,8D,6F,D2,DB,31,66,42,4D,EF,A5,48,2E,39,41,85,69,ED,AA,6E,AC,3F,DA,E9,58,8A,4C,A4,85,03,13,92,EE,1A,D9,0B,F9,B5,4C,C6,94,2E,2D,10,CB,9C,90,62,9B,35,82,76,E7,35,16,FC,05,DA,31,6F,E8,E1,62,55,AE,B1,4F,11,0E,F3,C0,EC,B7,03,A2,5B,9C,E1,5F,83,8D,7D,71,D5,C2,CC,91,8D,85,59,F4,93,05,14,DB,E2,CC,18,08,29,6C,0B,D6,FB,29,F1,D1,8B,C1,17,E7,02,7F,4B,B4,CF,CA,B7,8A,3E,51,EC,70,BE,7D,57,13,C4,FC,B1,72,76,0F,7E,92,E7,1D,1B,DB,05,53,B5,EE,D9,30,A1,C5,CA,B6,15,BA,7D,EA,7F,B8,52,C8,7A,62,DF,BD,47,A1,B9,12,03,D2,27,7B,A6,B7,93,72,90,0C,A9,19,7A,BD,85,F2,7A,19,BC,4A,FC,70,AD,4B,3E,00,AC,FF,6B,D1,56,F5,AD,F8,F5,73,26,F0,F9,B5,76,6E,45,79,B8,51,C5,7F,C8,EB,09,E5,BB,03,6C,6D,D3,99,4D,F9,4B,5A,4D,25,74,2A,96,7B,52,A7,D6,14,3F,36,DA,C7,18,03,06,7F,1F,74,53,58,EB,F3,CA,B9,CD,4A,9D,E7,32,DA,57,5D,43,11,81,FA,69,B6,62,E5,7A,F4,63,86,98,77,C5,FC,F6,10,19,02,2E,61,17,3C,FD,6C,26,4B,93,E2,3F,60,4B,60,87,23,90,42,BC,85,DD,54,32,8F,68,54,02,78,D9,54,E7,0F,08,D8,9C,05,EE,6F,34,46,5C,92,F1,66,30,31,5D,84,05,6C,2F,D1,47,2C,46,AC,DD,9A,70,7D,EB,FA,01,79,12,AF,88,1A,B0,F1,89,34,CC,CE,B9,99,EF,C6,6A,80,BF,26,C7,C7,07,2A,2D,CF,0F,C8,E4,99,A4,CC,C9,C0,E1,A7,B5,82,83,A4,BE,7B,31,94,DB,68,77,BF,B3,44,23,32,58,F2,01,DE,EA,82,93,BE,66,B6,81,F5,A1,2F,44,F7,97,1F,44,58,F4,96,4C,21,A1,69,4E,22,89,D4,07,1F,D0,5A,91,59,0D,0B,37,08,3E,8D,97,D6,CE,25,70,00,02,10,F3,00,6A,5E,A3,29,02,C9,1D,C0,CC,AD,BD,A7,76,A5,E1,99,8A,23,99,74,9E,E8,6F,2C,30,DE,56,D7,E4,DF,5E,3C,0F,CD,7F,D8,0A,A8,22,A6,DC,B7,E3,A7,CB,EE,21,24,83,6E,38,BC,80,7C,8F,9B,6A,D6,69,F2,27,B0,E1,20,77,18,A0,4E,23,CB,5F,24,48,1E,30,2D,BA,1B,3B,6C,AD,70,E7,BC,F1,80,4F,6B,AB,27,99,E8,5A,D9,C5,62,5A,FC,01,0C,9E,2E,02,C0,E8,5D,89,81,93,18,09,7A,6D,AD,27,E9,B4,AD,9E,56,60,EA,6C,83,D2,76,9B,D4,2C,A6,5B,B6,25,68,5E,09,B3,27,3C,BF,C8,1F,75,E8,61,87,0C,9E,E6,46,09,37,D2,2C,94,24,97,36,EC,BC,31,BA,0E,DA,DA,DF,F7,F0,7E,D5,32,CA,A3,EF,3D,2F,73,83,90,9C,65,25,34,2A,6F,43,00,7B,43,92,27,F0,05,70,59,EA,5D,3B,0A,65,3A,7D,A4,D5,BF,05,29,A5,D3,F3,19,2C,3B,DC,8B,98,CE,3A,D0,05,28,E9,DA,16,0A,E9,43,AF,6B,31,B7,B5,78,D3,B2,AC,08,DF,3F,31,2E,DA,A2,30,1E,80,82,25,67,EF,9E,02,1C,C0,17,0A,0E,1F,42,07,6A,65,6E,CB,BE,C9,5B,93,89,3C,80,AA,03,9D,7D,E7,FC,2B,D1,84,20,87,2A,92,93,07,DF,74,B9,8C,6C,52,B5,F9,B0,46,98,BA,82,AF,4B,73,A0,74,58,5D,67,A8,F8,D9,12,3B,DE,AA,EC,06,91,65,30,CC,27,2A,12,FD,1F,E3,1B,5F,BA,3D,4A,AA,CE,99,03,03,97,6E,EB,BA,7F,F2,27,D8,4B,49,3D,23,C1,ED,E3,64,F6,B8,99,BF,62,01,4B,44,3B,95,8F,5F,D5,97,39,A4,4C,76,25,8A,EC,41,10,4B,DD,CD,C5,ED,F2,AC,1D,A8,10,44,65,3B,DA,97,D3,53,6A,36,F3,B2,62,0B,AF,EF,BD,7C,24,F0,E5,48,04,1D,2E,85,64,7B,CA,0B,1F,FE,BC,C3,AE,75,97,2A,44,D4,F4,1A,BB,A0,AC,3F,D1,A8,E5,90,6C,AA,5C,A8,0F,E9,7F,8A,C4,1F,BE,3A,F6,87,CE,FD,20,57,F0,E7,4B,94,30,E6,4F,4B,EF,9B,29,4C,69,51,74,07,5F,BB,CF,E0,41,5B,0B,2F,87,7F,05,C7,B5,C6,16,AC,A1,91,1D,07,F6,AD,DA,23,73,73,E9,9F,DA,C7,C4,2C,BC,A5,9C,5D,8E,66,E1,52,A1,F3,FE,0A,E6,9F,19,91,E5,5C,69,10,6B,0D,92,FE,8A,F0,33,35,8F,C2,6E,FF,FD,D1,8F,ED,35,B3,29,C9,42,E3,95,BF,BA,71,FC,D2,BF,3A,A7,DB,4A,B4,58,46,91,22,F0,B5,18,95,27,BE,88,7C,40,41,74,FB,15,42,4D,06,67,D6,2A,2A,C6,96,1C,18,8F,3A,65,85,C4,43,5C,F1,0A,92,29,79,50,F4,B3,37,37,B1,D9,FE,6B,8E,28,4D,9A,A2,4A,3D,D0,91,6E,37,77,E0,ED,14,7C,64,7E,4A,15,60,C7,BD,4C,03,52,10,45,3D,D4,C9,FB,4B,91,44,C2,AD,CB,C4,57,5D,A6,EE,30,C9,25,2B,18,77,55,16,48,7E,2F,CA,D7,A8,67,60,93,32,4E,EB,01,91,49,CF,3C,33,72,FE,AD,20,F1,90,B4,C3,9C,5E,C6,10,AB,22,D5,6B,37,16,7E,9C,7C,F2,A4,44,E8,B7,BD,2E,55,DF,E4,5B,B9,FC,3A,AD,26,03,D9,13,65,52,46,CB,07,01,0D,E7,DB,B3,07,7F,A0,B3,21,7F,58,40,37,D9,69,8C,1C,AE,66,F0,39,F6,6D,96,78,49,96,14,49,63,5C,8C,FE,2B,C6,E4,75,45,7E,53,1A,F9,46,BF,93,53,38,D0,FD,4F,13,82,9D,83,A9,E9,19,C6,F3,4B,A6,A1,49,C2,9A,57,1E,26,8C,F4,98,C4,BD,45,DB,43,0C,2B,B2,0A,5F,53,52,E8,F2,1D,1C,4D,51,4B,32,C5,90,52,47,B6,E4,D5,BD,3D,BB,62,A4,29,53,FB,B3,3B,3C,04,39,28,7D,AE,16,59,57,92,87,3A,10,2D,BD,14,C9,D0,FE,D4,59,B8,AF,0B,5B,B3,5D,12,48,ED,42,75,3C,6D,08,53,60,8E,4A,68,C1,E9,DB,D7,FC,48,4B,44,BB,E2,0E,0F,06,0D,1C,1E,91,13,61,5B,AF,6F,CD,0F,0E,4F,D2,6A,D3,60,C5,79,A5,36,03,B3,42,B7,DD,C6,9D,6F,87,3C,DE,DF,32,9C,20,7F,DB,CA,6D,9C,85,D8,ED,D3,4B,AE,4A,0E,97,60,E1,89,F6,81,66,62,43,7C,B9,C6,9E,3B,8D,25,2D,72,B4,13,2E,9B,9B,46,13,DF,BC,B0,3A,AC,DE,C5,01,4B,A0,D6,E3,5D,3B,75,00,68,4E,F4,82,93,9C,17,36,66,32,44,1D,5F,55,67,50,73,F8,55,9E,8E,67,36,5B,E0,F7,7B,88,8E,D3,08,9B,E9,C8,AA,90,F6,D6,30,35,4A,46,F7,63,36,C0,C0,B9,28,C5,B2,C8,F8,E2,A4,7B,24,C9,B9,0D,4D,E3,3E,8E,BE,5A,0B,39,95,B3,48,8C,C5,94,50,0F,AC,65,86,1A,67,0B,3A,62,E9,DE,63,2B,78,72,15,2A,54,28,BB,14,E3,F4,62,04,3A,66,4E,9E,A5,A2,22,8A,A4,71,06,34,E7,55,80,11,B2,0E,C6,2A,6A,ED,5F,92,30,AC,19,89,30,00,6B,0C,A0,C0,82,C1,47,52,E5,0F,93,FD,2C,EB,AC,F9,94,4E,1A,DE,0C,92,24,46,3E,A6,0F,9C,9D,55,F7,78,D2,06,DE,A7,4C,FC,68,3A,1D,98,44,09,28,89,AB,78,96,32,7B,7B,77,4F,76,FE,6D,36,2D,CE,D3,2D,C1,01,5F,74,EB,CC,C7,04,7B,A4,E4,65,AA,40,E0,AA,E8,9B,A9,F5,F7,05,D2,DB,5F,90,0A,93,FD,03,57,FB,11,52,60,2E,61,09,F1,4E,65,1E,B8,08,78,2E,DB,71,1D,BA,92,1D,7E,CA,D2,65,61,B9,A9,75,5C,BD,02,64,79,41,90,7F,F9,DF,74,B5,8C,98,71,01,EF,E5,35,99,20,20,A0,71,DA,D8,3B,5A,28,9A,35,40,73,62,50,B3,04,48,C8,A1,60,84,06,3A,0D,0B,6F,A8,69,3E,89,9E,28,DF,FC,DF,17,B4,EC,F0,E7,D3,FF,E0,74,C0,7D,13,9D,37,B4,11,26,F1,8F,A2,2D,B2,10,C3,88,7F,A2,4B,6B,5B,17,C0,DB,24,2F,A0,8E,3F,72,E6,14,79,B7,79,07,EA,00,02,87,90,C6,2C,AC,C7,8D,EA,66,0E,50,F9,93,0C,D7,75,A8,AB,D2,C6,E0,04,BE,76,61,66,18,4C,9C,62,A6,DF,3A,39,3D,02,8F,56,72,93,C7,AD,4A,E3,2A,64,94,7D,F7,F0,0A,E3,CC,8A,A3,A1,D3,A6,8F,0A,39,3F,53,81,15,49,93,44,AD,7F,36,F3,84,18,8F,99,21,01,55,25,EF,DD,D2,D5,64,02,51,5E,00,76,F2,79,7F,34,A6,75,42,1C,F9,C2,7D,EE,C2,0C,BA,18,DE,DB,B9,78,73,BC,C3,F5,AF,E0,D1,7C,B3,4F,3D,1E,4B,13,26,C5,EA,82,61,EF,77,5D,15,FE,F8,A1,0D,92,A3,13,5A,9B,76,CA,03,74,48,17,CF,0A,46,C7,8E,7D,60,0D,AE,D6,4A,EE,AF,3C,9A,01,8C,8F,23,A1,60,1D,73,0B,C9,5E,28,00,45,83,AE,71,A1,25,BC,72,0A,05,D3,76,1A,F4,DB,83,AF,54,5A,D9,45,34,E1,70,8F,CF,79,88,A6,EB,C5,45,F1,B1,2E,F7,59,4E,11,8C,80,EA,0F,93,DC,48,F8,35,EF,38,2E,D9,CD,ED,CC,96,A5,DD,D1,C9,FF,8D,CF,B1,05,D2,3B,E9,BC,DA,BD,3C,03,7F,09,08,40,CB,A5,5B,47,9E,3F,1E,0E,2D,24,89,68,1D,D8,24,36,1F,5B,1A,1F,1B,D1,8F,FD,70,12,95,CF,FF,F0,59,AB,A4,1A,63,88,66,57,CE,6D,07,AF,A6,A8,9C,F8,6F,76,8E,4E,5D,6E,80,7D,AE,11,D6,EA,48,6E,33,EF,C2,19,8F,54,6A,C2,7E,77,D0,BD,71,66,CD,1E,09,D5,E0,7D,42,06,2C,FD,87,29,20,2C,31,67,2A,66,FD,49,D9,86,7E,AE,90,DA,2F,F1,AA,E1,68,39,DF,D2,35,53,AC,23,C0,A4,F6,21,B9,84,CB,98,8A,D4,A4,B0,F7,36,EA,EF,FF,75,BF,10,D6,E0,7F,EF,0F,BD,7A,3D,65,43,95,E6,A3,66,CB,30,7C,23,A8,FB,E9,20,D9,A3,F9,A2,35,92,66,9D,C3,41,07,95,7C,1B,77,2E,58,FD,16,84,EA,75,2D,C6,D4,85,0C,24,0F,7A,19,14,C3,DA,48,75,22,9D,8C,59,45,10,80,AC,1F,BA,42,35,EF,F0,A2,6F,32,1C,DA,2C,21,FB,96,BF,E6,02,DF,15,F9,82,95,4C,76,F2,86,9D,43,33,A9,EE,49,D7,EC,64,0F,8A,FA,E5,67,F7,66,85,EF,C9,67,AE,08,9B,8C,A2,D9,2F,47,54,AC,8F,EF,C8,18,4A,69,34,B0,EE,54,FF,3F,2B,C0,66,DD,89,1F,B5,AF,24,48,E5,E6,EF,07,01,ED,79,4B,89,8B,E4,76,47,A2,9D,D9,2C,11,F5,D0,CA,E3,7F,8D,56,B2,52,D3,00,20,D2,07,55,22,E6,74,65,F2,1C,40,89,24,05,1A,E6,22,86,28,D2,B8,0A,14,85,91,0C,69,D4,D2,83,63,AB,DC,C4,EA,1E,CC,26,DC,49,D3,C9,1E,D1,4E,6A,45,E0,8A,01,ED,FE,14,50,73,2A,4F,1D,94,1E,07,37,AB,E2,9C,9B,B6,B5,A9,3A,07,11,D5,2B,B3,27,E9,66,F5,05,1C,ED,CE,42,D6,96,5C,06,8C,71,72,13,91,5C,B5,24,6F,1E,D4,D7,E4,F4,9A,14,39,4C,49,42,F8,5B,7B,6C,A2,96,FB,9F,27,64,67,D2,F3,87,5D,69,67,D7,A3,8B,0E,D0,CD,CD,02,57,B3,04,AA,2D,CF,39,32,D5,A1,72,68,16,96,38,EC,40,31,65,04,DA,DD,6E,B5,A3,12,31,39,96,3E,01,DD,2F,30,E9,88,F0,47,44,B9,AE,5B,C3,00,10,34,A9,99,BD,C6,44,A3,D5,7F,1A,AD,47,60,95,A2,1F,20,88,3B,B6,E9,A6,93,EA,B3,12,52,71,3C,4E,09,07,FD,36,FE,70,3A,25,42,FD,4C,F3,63,22,D3,04,CD,9C,99,75,91,9E,C8,4C,F1,D9,48,B7,12,24,C2,89,DF,F6,01,75,BC,50,37,56,93,91,67,E0,CC,07,5D,5E,70,CE,CD,55,82,1C,01,27,A3,CA,7A,61,D5,B2,6B,E9,96,C8,54,98,E1,79,1D,08,7A,FD,47,3C,6E,42,BF,80,02,E6,7F,6A,3B,EB,5A,CF,48,1B,1B,6D,18,43,09,77,9C,38,5F,A5,56,C3,83,AC,20,BA,14,D2,D3,DF,71,ED,3A,CC,38,6E,11,2E,EE,28,56,6A,07,B8,8D,1E,F9,23,1C,C3,6D,1E,79,6A,87,3E,9A,93,66,FC,C4,29,94,02,2A,7C,84,E8,96,17,41,1E,B0,B3,55,C9,34,10,BB,5F,B9,93,66,CD,B0,86,B2,89,F0,28,5C,88,F0,76,41,07,1D,0A,AD,08,09,CB,9A,6D,EB,CD,AD,BD,AE,48,69,80,66,24,A2,A1,6E,9F,8C,CF,90,35,C8,40,52,B3,88,61,3F,D6,8F,A5,64,03,CF,DC,8D,24,D4,EE,47,97,B6,AD,F2,6A,FF,8B,38,29,BF,CC,83,E3,36,27,77,14,E8,96,E4,79,5B,20,4C,3D,A0,38,05,62,76,F0,F4,97,3A,8A,82,F6,BC,5A,B4,16,55,16,E6,BD,A2,B6,E3,56,C4,D1,E8,24,54,5E,79,9E,5F,43,AE,30,70,92,5E,4C,53,00,29,D3,80,45,20,1A,FA,DC,A5,47,D8,D4,4B,43,C2,E1,C3,98,A3,20,F7,46,06,97,8E,5B,C6,C9,A0,38,CD,40,16,E8,0E,04,EB,E0,2E,BF,A7,B9,6A,58,EB,8C,27,71,B7,79,42,0C,60,8A,4C,2C,70,54,27,6C,17,E6,14,FB,1F,25,9C,BE,79,D4,67,1B,11,5C,28,37,FE,C7,09,B4,5E,24,FB,FF,1B,52,8E,95,0F,B8,B2,ED,2A,4C,DF,76,0E,6C,39,1B,FF,3B,CB,54,B2,DB,77,6E,48,D9,53,F0,AF,6D,3D,D8,F0,F1,33,F4,1B,46,B3,22,A8,EF,DE,D7,B7,A5,BC,B2,E9,8A,56,F5,B9,BF,1D,7D,12,D8,56,08,34,C2,B6,01,28,F7,04,28,13,AC,ED,10,25,76,CF,D1,E2,D1,9E,97,DB,49,E7,83,A3,43,4D,21,A1,10,88,D4,40,8E,A7,48,28,B3,49,7F,6F,9D,44,F6,53,F6,52,CA,69,50,4E,56,60,F7,FE,FD,F8,A6,33,82,FF,8A,A5,99,23,BB,FB,FD,A4,BE,54,53,F0,CF,43,8E,29,AD,5C,E6,6D,FE,DD,54,82,07,8B,8E,4A,0E,72,CF,68,C8,55,DB,5B,44,3C,02,5B,EC,7C,12,77,1F,85,13,7A,D7,24,A6,6C,49,F5,D6,61,ED,78,CE,3B,F3,D3,3D,00,FB,F1,80,74,29,AB,4E,B3,68,2A,E2,E3,31,D3,EB,1D,79,FB,15,38,B1,F4,BB,F3,96,12,65,7E,2D,E9,F9,17,67,0A,08,C3,84,01,99,16,C7,AB,DA,D9,C2,5D,05,6C,80,6E,46,45,E7,F0,78,4F,9C,FC,EA,03,6F,B7,8A,14,60,D8,55,52,02,C3,BD,A2,39,0C,34,D4,3A,55,1F,BA,0B,72,45,09,57,B4,F2,9A,D5,A3,21,D2,40,38,A0,FB,84,3F,F4,58,4E,CF,AA,3F,65,D7,BF,8E,C4,B7,4E,36,B1,68,62,D6,7D,77,49,F0,BF,E9,F9,1F,78,67,15,C1,68,59,E3,60,78,DE,3F,59,66,1D,60,A2,5B,6F,61,50,EE,4A,51,12,33,52,1C,77,24,98,1A,C3,5E,44,E8,E0,0B,17,50,4C,3E,D9,38,EE,24,0A,0B,BE,C3,85,77,78,79,D0,81,44,D4,31,CD,3D,53,96,FC,58,E7,60,C5,ED,8F,2E,00,F6,60,73,BC,8C,6B,45,A4,66,5E,E9,FB,16,C3,0C,CF,62,95,74,1F,68,0D,4E,CA,37,E5,CE,F0,E9,C9,CE,5B,9E,87,A8,84,33,91,50,0A,EE,05,A2,E3,7A,1A,A8,6A,9A,C0,88,9D,3B,E7,1D,7F,EE,80,57,39,35,DB,84,2A,29,25,06,2C,80,0D,86,7A,D3,98,FA,06,DC,00,C9,91,C1,68,F0,D5,38,12,E3,90,4D,63,00,CB,FE,67,C9,3A,F8,5A,77,07,15,A7,AE,E4,5D,21,98,17,F9,00,68,D9,6A,B7,EA,CB,11,2D,86,8F,DD,80,B5,F0,45,40,03,E2,23,7A,C3,9F,22,48,7D,85,12,55,82,AB,D2,2E,AF,2A,72,23,A5,1A,30,0C,D0,37,45,AB,B5,32,D2,C9,39,2C,65,57,1F,58,61,EB,E3,D1,67,22,1D,8A,7F,FE,42,01,2F,98,7A,E1,18,5E,99,AF,1B,26,93,1E,BE,42,16,24,EB,1B,94,BF,2C,D3,EB,8A,3A,A0,C5,13,10,A4,53,BF,B1,91,0F,D3,9D,58,B9,57,ED,83,B5,25,E5,85,F3,A0,0A,63,07,EB,D6,A4,BB,81,7F,EF,A0,F4,77,B5,9A,BE,D9,76,E4,94,29,4B,63,76,B9,D5,13,C7,50,E3,02,1B,A3,6D,67,5D,E1,43,A7,51,59,36,6A,BD,DD,43,A3,9E,FC,2D,F1,88,24,FF,56,45,2D,65,6E,F8,89,30,D8,82,04,8A,BE,9B,04,8C,73,92,F1,1C,A5,B3,78,9B,40,F2,68,36,64,5F,6D,E7,A1,42,53,8D,B4,6A,DC,A5,B9,EE,00,77,BB,4D,AC,B9,06,70,A3,8B,D3,C0,24,1E,47,CB,34,2F,F7,BC,BD,2F,6F,30,66,EA,74,55,EE,FD,7B,58,57,81,5C,F3,A0,77,08,1E,83,28,D1,6F,15,AD,39,A7,5B,50,CA,E8,91,79,98,BF,C2,34,2F,83,4E,D5,CA,71,1A,93,4C,AE,42,70,95,B5,92,7F,2F,A0,C7,85,EA,C4,4A,96,2D,67,5F,2C,53,09,DA,37,35,54,C4,1C,5F,36,1E,38,85,4A,2A,53,2F,B7,F6,99,21,F3,C8,1B,AC,B5,B0,F8,1C,7C,C5,78,B0,7A,C3,24,3E,D9,DE,B8,81,21,19,85,60,EC,5F,33,68,0C,3B,A4,28,A3,BA,60,4A,9B,35,13,8E,D4,09,76,4B,07,8B,2E,5E,DD,20,98,20,B2,70,14,34,42,77,50,4F,E1,26,17,D1,63,BE,61,26,1E,6A,BB,9E,32,1D,71,61,BB,8B,BD,15,6C,35,E6,3C,24,CF,4A,3E,62,E4,0C,60,6A,FD,EF,7A,BA,4C,8A,64,B4,44,E7,0E,26,22,C9,CB,24,DF,64,3F,AD,AE,4A,6E,9C,31,3A,C3,22,30,60,A9,CF,CF,24,6D,77,A0,A9,D7,90,8C,35,7E,F8,D6,56,B9,95,79,97,20,4B,06,5C,94,D0,FC,05,6C,E0,9E,4C,2F,19,95,92,39,93,86,B5,EF,1F,93,EB,DD,24,C9,68,0E,1F,E1,27,BC,91,2A,A6,43,96,90,F4,89,55,A2,25,5C,D0,62,1A,23,C1,54,42,4A,A6,05,96,EE,4C,DC,B4,AA,38,DD,E5,06,5E,DF,9B,52,A6,73,B4,00,8A,FF,37,D4,68,5E,77,D3,40,1E,47,E6,9E,8B,98,BB,D0,3F,16,C9,35,84,11,AB,43,1C,4F,AE,16,8A,10,73,1B,C2,51,C0,C0,83,9A,E5,C6,2E,2F,8A,7D,0E,04,3E,E9,43,6A,77,BE,2F,A5,C0,9A,4A,76,54,B8,AB,09,7A,50,CB,77,DF,23,82,BF,08,1F,49,1C,BF,9D,FF,5F,19,0D,FF,D9,E4,C4,37,14,AF,DB,84,70,E4,1B,89,A1,67,87,20,08,7A,7B,ED,28,CA,93,2C,46,2C,5F,B8,55,E2,3A,AD,2A,48,28,60,A8,DB,0D,15,CB,6B,31,FD,CC,8D,5C,7F,46,01,F3,7D,07,AA,30,85,C8,E7,45,9C,E7,22,1A,74,8E,69,1D,6D,C5,EB,F8,D7,89,FA,9E,C0,C4,B7,87,27,07,45,06,3E,5F,2C,7F,1E,62,4F,2B,57,C4,C4,F8,C2,ED,28,82,D6,93,38,DB,E8,21,7C,C8,37,8A,E9,1F,9E,78,6E,E3,0B,C9,A8,FE,4D,CB,93,96,DB,81,54,69,9A,86,C1,30,39,2F,8D,7A,2B,4A,77,42,8E,06,FA,71,41,87,66,EB,D2,F9,9B,51,65,B0,E6,88,5D,4A,ED,2D,11,3D,9A,77,93,5D,80,8F,63,10,6A,F8,62,97,68,50,BA,78,22,92,90,18,72,AE,F6,89,B6,22,98,BC,B6,53,03,B7,BB,C1,60,9A,3F,BE,82,E6,2F,35,EF,3C,BC,B7,F9,53,E7,AC,2A,41,00,10,5E,27,38,8A,39,2D,75,DA,DF,3C,94,4C,03,A0,55,4D,54,07,AE,AA,D5,E8,BB,33,80,E3,3B,D7,D4,1F,59,03,FC,0C,8F,4D,D3,D9,22,92,B8,C2,97,5E,C0,84,81,0A,9F,C2,BB,B2,AF,1E,CD,0D,7E,C2,F6,7B,D0,1E,09,DF,BF,C1,9E,C2,A7,CD,6E,25,D6,6F,D7,DA,3D,48,7E,C5,93,98,36,75,60,21,BF,5F,1B,59,E8,52,FB,FA,B8,CC,7D,57,0F,92,0E,80,F7,08,82,10,7D,26,6C,DC,6A,FB,3D,EE,01,AE,96,05,CF,BC,B0,6C,43,D4,BA,28,6E,55,B4,65,C8,EC,80,DF,05,E7,A6,52,1A,4E,F5,AD,E5,34,3F,B7,02,2D,30,E3,C9,6B,39,1E,91,82,47,09,25,B7,0C,35,45,20,B2,08,B4,2D,D4,DC,87,23,D1,BD,B3,14,AA,01,31,4F,86,FE,B8,65,30,9B,33,2C,90,78,40,B0,7F,01,DD,44,5D,4F,A0,82,F1,71,34,7B,11,4E,3E,78,D2,07,BB,9E,DA,4F,9A,38,F4,CB,F7,12,87,A3,C8,92,74,A3,97,84,22,05,34,A3,65,07,55,05,F0,12,64,0D,DE,4E,6D,DF,0E,F7,7D,36,29,CA,41,DA,76,33,7E,C2,4A,72,B7,C3,87,FA,62,16,1B,E1,D0,09,49,8F,69,DF,A5,2D,CA,2A,DD,9D,BC,10,77,0F,C8,C7,71,A8,D6,C8,DB,A2,4B,7A,1E,26,F2,12,2A,DC,D7,19,5A,7A,79,C0,ED,3E,82,FC,A9,7C,98,BF,AD,C6,32,5A,76,B8,23,F5,63,6C,2F,D8,A1,60,5F,C0,F2,33,E1,1A,EF,2D,1F,FE,1C,21,FE,4A,4F,D7,4B,43,DB,E9,87,DB,26,F4,0A,6B,A3,6D,D7,6E,CE,CE,5C,4E,4C,1F,CB,B0,E6,78,FF,0C,CA,1B,3F,9E,2B,23,D8,63,3A,47,70,75,45,68,8B,01,60,93,D6,BB,B2,B9,E2,57,8A,8A,0B,A0,DC,45,3E,A9,69,B4,03,08,D1,99,39,35,30,A8,ED,15,BE,AE,A1,BA,79,82,02,83,D0,AE,84,B5,E8,44,0F,F7,E6,F2,30,F0,BE,A0,C9,D5,E1,0A,49,FC,21,23,CE,10,EA,50,BA,7D,20,09,05,FC,D6,79,20,56,12,6B,CE,C5,7E,9F,C6,70,85,60,5C,F5,DE,0A,13,6F,20,9C,3E,B0,CF,77,EC,42,0B,6C,61,7F,61,33,2C,38,7E,96,D0,C0,4F,3F,76,6A,59,90,6D,08,14,EA,64,7B,FD,86,F3,5C,D9,BE,3E,E0,84,22,32,DF,C6,C8,B2,BA,AA,43,22,D4,DC,43,ED,98,49,6A,5B,73,F4,A8,1D,B1,FF,BE,D3,76,37,7E,9A,EF,7E,F9,2C,6E,98,B8,7B,E4,F3,0D,32,93,1C,7D,A5,E3,43,20,04,EC,EA,49,A8,F4,AC,BC,2B,A7,EC,AF,0F,B9,80,6B,05,B7,9F,E2,1C,0F,75,23,10,75,F7,2F,12,5A,32,32,E7,21,2F,1A,64,30,89,08,DE,58,78,3B,59,06,4B,3C,C4,18,A7,F9,B0,C7,81,B0,F9,33,DB,C2,18,30,EB,3D,2B,DA,17,E4,BA,E0,7C,AE,1B,6C,A5,1D,79,54,E0,7C,73,C3,3F,11,E2,95,F4,26,4A,72,E7,62,8B,BB,5A,AB,18,C1,74,1D,C8,66,30,62,28,50,A0,C9,C6,5B,F2,FF,41,DC,D5,9E,53,62,43,45,B0,DC,73,F5,86,E8,44,5D,BE,FB,1E,4E,6C,C3,BF,5B,6E,FD,1A,5D,F3,BD,1A,CA,3F,6D,DF,76,F3,09,48,9D,F0,F2,60,45,CC,7D,B7,A2,CE,15,7C,6D,4A,3A,BB,F6,04,EC,29,A8,31,E8,AE,1F,9F,61,72,BC,73,E9,44,DF,94,0B,5F,0F,0B,2A,88,B6,92,A9,15,C4,C2,8E,76,20,CA,88,C5,82,12,EB,63,E5,44,B6,8D,8B,8E,B2,D0,B9,B1,5F,6B,01,D9,2C,D9,C7,7F,94,BE,CB,B6,42,48,3A,1E,99,B0,00,8D,ED,6D,AF,A5,64,F2,A8,F6,4F,B4,78,E5,13,4A,C9,C3,39,18,32,A6,56,AF,5E,9E,FF,72,59,E6,06,EC,B5,45,61,8D,9A,95,AB,99,E2,91,89,61,AD,A3,06,50,0E,5C,CE,38,B2,D8,A6,C4,FC,D0,F8,12,F7,5E,B7,67,6D,15,2C,93,8E,27,36,F2,DD,E4,4B,7D,B6,DF,BC,20,8E,5F,57,B4,D3,6C,9D,A5,9A,0A,CC,EA,B7,EB,39,31,2C,B8,71,D2,2E,B8,38,30,A7,0E,E2,A1,B2,A3,3E,C6,70,DD,C0,9E,3E,AD,7F,83,56,B6,00,9B,99,16,5E,16,0F,2C,52,A7,B7,E3,B3,64,3F,04,37,63,49,16,EC,CD,42,0F,7B,47,0E,E0,90,FF,2F,20,2D,76,04,D5,1D,29,13,E6,09,89,93,E3,6F,09,E6,B9,D5,77,07,96,A4,12,75,22,BD,EA,8F,BD,6F,F8,69,5E,03,A7,6F,E5,28,1B,0E,B5,15,24,17,35,F1,77,64,3D,D5,6A,52,B6,AB,13,6F,85,80,14,AA,C3,7D,AB,F6,52,25,32,86,E4,4A,80,A4,BC,59,B7,54,DC,E0,B3,80,E8,A4,38,BA,B5,D2,F4,B7,57,4A,21,F5,C9,BC,ED,93,2E,11,B4,9D,6F,88,22,13,65,5F,9E,07,5D,F3,49,FE,03,F3,76,D5,CF,DB,61,AF,15,F8,A4,27,90,C0,52,62,98,E9,63,C1,D5,83,4C,DB,0A,C2,C0,41,93,99,23,FE,9D,65,24,61,6C,AE,AB,50,FA,9A,FE,38,FE,C7,1A,41,80,E6,41,5D,97,BA,81,6A,AD,72,9D,60,AE,06,5C,3B,39,4A,5E,CA,24,E5,89,1C,7E,85,AF,38,44,05,F3,CC,B2,18,F9,E4,42,89,C7,51,85,33,6C,A2,87,73,2F,6A,E4,33,A5,E5,FF,EA,09,0A,0E,66,18,ED,47,75,0A,1A,1B,07,F3,89,55,48,70,A8,DF,29,0E,81,5A,F8,D5,57,9E,7E,00,04,F7,74,C3,36,EA,19,04,A6,BC,40,59,A7,BD,FB,C0,29,1F,D7,3A,94,2D,5A,1E,65,3C,CD,E4,83,A7,EA,9D,0E,BF,64,1C,AC,4A,05,65,0E,9D,DE,2A,FE,B2,DF,A2,A4,8E,FF,F3,D3,A3,BF,3B,29,33,89,6A,1F,F0,46,6A,37,CA,07,19,85,3C,3D,F7,2D,AA,B5,B8,04,12,86,77,3D,30,46,AA,1D,49,B7,6D,E7,48,45,C4,5A,B4,E2,00,CB,47,7F,F8,AF,8A,24,63,7E,B6,2A,24,78,10,73,BA,E2,11,A4,40,1C,C3,CF,B0,B0,39,08,DE,AB,DE,6D,F1,C0,BD,9F,47,4E,7C,15,97,8E,72,2A,91,34,8A,BF,E4,6F,51,02,04,98,39,F4,CD,F7,2E,11,7B,0C,32,C1,D5,B5,55,AB,19,82,C8,68,60,D7,6F,35,D4,B8,C2,91,24,CC,35,45,AE,19,5B,5B,3F,7D,19,BA,F5,61,28,16,F0,96,1F,4B,B8,EC,F7,C8,38,F7,7F,E1,A7,C4,86,87,DB,29,9E,E8,16,06,46,08,26,A5,F4,5C,32,34,2A,CE,27,8B,AB,30,77,43,A4,18,CC,B8,61,E7,1F,A9,20,8C,A2,60,56,45,6F,D0,9F,FF,A3,F3,54,B0,3A,0F,5D,1E,7C,94,6D,F1,FA,D7,84,09,A8,EA,70,C5,9B,95,64,72,D7,DD,9D,DD,7C,A2,BC,80,D0,26,74,0A,82,F7,63,83,7E,5A,61,DB,9D,6B,A4,DC,14,22,02,2C,D0,5D,F7,29,3D,97,5C,1C,80,AD,8E,99,D6,D4,87,89,A3,B1,4F,37,EB,A9,08,8B,C6,DE,34,48,F4,57,0E,05,81,2A,F8,45,B9,4E,F6,5C,3F,69,77,F1,4C,16,38,D6,74,D0,3D,12,AF,26,00,19,50,CA,80,24,7D,19,73,A4,12,44,48,A5,28,B1,75,B3,B5,C8,F9,63,45,62,4C,AA,70,9A,2F,CA,CD,07,6E,11,82,A6,38,7A,59,0C,43,20,68,71,F1,48,8D,74,C1,32,38,43,62,02,37,FA,F8,A5,E8,C5,18,01,78,A7,E9,08,37,E6,10,4F,7E,A1,5E,24,34,33,97,12,4A,E7,B7,92,31,14,85,94,72,83,EF,0E,3D,35,C2,A3,BA,F0,0A,26,55,46,6C,1F,24,19,C0,29,8A,4B,37,CE,5B,7E,FB,F9,C5,21,FA,93,CD,E2,68,1A,27,E7,DF,C4,DD,13,47,5F,10,B7,C3,BC,B2,BB,E7,0B,BF,55,90,A7,A3,2E,D0,69,72,1B,30,73,6F,1F,AD,52,23,22,34,92,DB,65,11,6A,83,66,2E,33,B3,67,0E,2B,9A,5F,54,0A,D8,BD,6B,9A,19,1C,2C,30,7A,16,53,57,D7,D4,33,D8,0D,74,D7,2D,E5,FB,6E,18,BA,F8,07,59,B0,6C,93,F3,F9,FF,67,07,DC,FC,7F,9A,77,CD,0F,67,7F,7F,D7,B4,90,37,D8,DE,05,5E,BD,8B,2D,D5,9C,AC,C4,E1,D6,83,5D,B5,7B,23,93,29,95,D5,DA,85,D0,1A,61,79,F1,83,F9,A8,1A,3E,F4,61,30,EF,29,6E,BA,EB,14,37,A1,EE,56,A8,3A,CF,6E,A2,AC,69,14,10,2C,6B,0C,14,49,CE,E1,C0,83,27,69,CE,0A,40,A3,B2,45,B8,AE,47,B3,69,C0,D6,60,46,91,91,D3,2B,85,DB,B5,30,66,68,3D,6C,15,A3,FD,1C,24,98,2B,46,31,E7,34,87,5D,44,76,50,D7,CF,01,7D,5A,5F,9C,0B,2C,DD,D4,77,3E,F2,92,9C,81,35,82,42,80,87,53,DE,E3,4D,40,3D,84,38,FD,25,A4,67,9B,58,CC,85,12,F3,7D,1D,E4,42,21,32,D4,F9,44,B9,5A,DB,26,F3,3B,83,86,9B,46,B2,CB,7F,78,3D,18,4E,C6,23,38,4D,4D,94,C6,8C,07,DD,1C,D6,AB,FD,C8,88,F1,24,75,64,48,4F,11,0F,36,D0,2C,22,A6,BE,A6,62,81,43,62,86,41,DE,CB,91,75,4D,97,BC,D0,94,0D,05,59,73,D4,F0,DC,AF,38,C6,DF,A6,0B,78,6D,41,C9,9F,4B,7A,EB,8C,8B,7D,36,61,78,82,26,65,FB,70,DD,AC,BB,6D,B5,8B,00,9D,3F,FC,8C,74,60,F4,27,42,2F,EA,13,21,AF,3A,22,A9,02,F3,4F,FB,0B,1D,13,D4,38,A9,C7,06,69,E2,83,1A,03,B3,18,61,9F,77,08,B3,50,8B,AE,CE,E5,56,90,D2,39,30,51,A3,D9,F5,B3,DF,9C,5F,08,DA,51,2F,CA,86,B7,CF,FE,05,5E,D0,87,5A,1D,87,23,D2,29,C8,EC,F2,59,25,9C,A4,D5,44,FE,77,A8,A4,CB,1C,38,42,77,EC,A9,DB,9A,CF,8B,91,72,FB,41,12,8E,51,DC,CE,88,B7,9D,26,2E,AC,57,EE,0B,14,47,1F,6D,69,F5,8D,0E,0A,4C,90,A8,D0,43,55,44,2A,6F,3F,3F,77,99,96,AA,A7,04,EC,3C,6F,65,B5,40,E6,50,6F,67,04,5C,A2,CE,A5,52,EA,23,4B,3D,A4,6A,A9,FB,D3,30,9A,FA,62,DE,A2,FD,73,02,5B,01,F4,64,2D,3A,A6,83,24,0D,7E,6B,BD,B4,4C,D1,49,CE,77,0A,2A,DB,04,85,CC,78,60,6C,C4,06,79,32,8B,83,69,9E,B6,9B,15,99,3C,F8,04,AD,13,5E,1A,C8,82,70,3D,39,64,84,27,B1,49,6E,B1,D3,8A,F6,41,10,C7,07,BD,C9,B7,87,E2,48,83,56,82,53,FF,3F,7F,A0,FA,22,94,1C,0A,AF,47,E3,33,18,F7,FF,30,DD,6C,43,35,7A,C3,BB,29,A5,CD,0A,6B,64,C6,A6,A0,35,65,8B,27,EB,75,F7,D3,A3,EE,0E,D4,31,65,A3,40,21,45,96,02,07,09,AB,18,67,60,1F,3F,74,61,6D,5F,EA,DA,C4,AE,7F,79,B8,69,C9,FC,86,6A,0D,41,77,1C,B3,22,12,59,CA,EF,EC,2F,0D,39,D3,78,0F,74,BE,62,03,60,85,29,20,30,4D,0D,9A,A9,B0,05,0C,E1,31,85,DC,D2,8A,BA,E1,51,DF,1B,4A,83,4B,B7,02,80,03,17,08,2F,C0,40,8B,B3,98,EF,F3,AE,0D,24,43,66,3C,18,82,88,02,BD,FC,B7,22,2A,2E,19,F4,E1,60,8C,16,C6,59,68,0B,71,61,3B,FC,67,E3,6A,05,9B,54,95,29,EA,EB,05,4E,8A,EE,00,FE,9C,76,21,52,4A,88,D1,DC,3C,BC,2F,6A,A9,65,5F,C3,05,E4,2A,FF,D5,93,B2,82,7C,F4,E2,E9,CF,31,1C,35,5C,57,2D,20,83,6C,91,16,9D,93,DC,66,18,EC,AD,C4,DB,CC,F3,BF,C6,66,3B,55,CC,58,27,43,89,35,A0,7B,4C,83,B4,43,6C,AF,38,72,7D,43,C1,49,EE,63,67,A8,7D,60,70,EB,8C,3E,CB,1B,2C,32,31,DD,7A,A6,86,E3,59,2A,26,D8,E2,26,DA,5B,D9,A2,B7,44,D8,35,31,DE,75,57,C9,9D,0F,CB,20,11,B2,A6,CB,67,BD,F1,94,3A,C8,4D,5A,CA,5D,C3,A6,47,6C,72,B4,1F,28,A0,17,B8,68,E3,35,8A,4A,4B,DB,E1,DC,7E,16,66,FA,4E,6C,A6,62,0A,0A,90,B8,80,81,39,60,0F,11,B4,BB,28,C0,E4,E3,CF,B1,2D,23,5E,1A,77,16,1C,1F,A1,D1,34,D0,B0,83,89,E0,51,B2,23,21,AE,1E,25,4F,A5,A4,67,3D,EB,53,58,84,D5,07,70,D8,07,B8,01,8C,04,99,80,74,B3,17,B3,97,4A,FB,30,2C,47,3E,B3,B5,E8,C1,3A,9F,8C,C8,10,48,DE,3B,A7,D4,5D,6B,0C,E3,5A,29,45,85,BC,E0,1A,DB,B4,46,10,2F,D0,D1,12,B5,7B,EE,AE,27,3C,26,E8,F1,51,B5,36,50,29,72,24,0F,9F,E7,56,E4,18,B0,13,01,44,FB,33,13,5E,8F,28,D1,0B,74,DD,27,D7,B9,6B,6D,A0,ED,52,95,50,81,49,17,27,F2,EE,17,23,DE,CE,4D,19,9E,7D,7C,F6,CB,E5,AF,67,61,2B,09,C6,32,A4,29,5F,86,FD,63,BD,B0,35,46,B0,EC,9A,E1,34,FE,94,F6,5E,7C,8A,12,7D,9B,75,2D,16,22,FA,C1,C5,DF,3F,15,1F,3D,BC,36,12,63,75,31,D0,AB,71,76,8A,68,BB,F0,61,D6,E8,2A,FA,31,B9,CC,06,53,A0,1F,D6,9D,52,16,9B,1E,0D,26,57,EC,36,61,51,78,FC,06,65,E6,48,C6,10,C9,57,83,D3,BC,16,9D,34,DF,6A,3E,DF,DF,14,AC,FE,92,08,9F,8C,BA,70,4C,C4,E8,99,CA,9C,D0,27,8A,00,C9,03,38,09,80,31,7D,D2,39,C8,B1,4A,58,74,F1,9F,9B,92,C8,9D,6F,86,9C,4D,AA,74,FA,C6,AF,A0,CE,78,6A,2D,B9,35,FB,3D,0E,4B,F8,30,9D,1F,C1,56,45,DE,2E,7F,65,32,5F,2E,70,2C,39,EB,C6,01,5B,6B,6B,56,BD,33,75,C7,BC,6B,CD,A6,D2,97,4A,62,11,E6,70,42,CE,B8,B3,70,92,DB,E8,73,CA,E4,4A,CA,A5,91,C0,A9,C7,86,C9,0A,2B,DD,A1,D4,74,1C,56,6A,89,B1,63,05,A6,A9,9A,3B,B6,3A,11,F6,F1,94,F3,D0,55,57,21,F8,B7,1B,09,25,AA,D3,7D,2E,8B,63,80,52,A7,DE,0B,19,BD,7B,72,CF,7F,2D,81,34,95,1E,5E,B0,BD,06,C1,E0,AF,06,16,B3,02,84,78,71,01,DA,54,97,CE,0A,ED,73,5F,D4,A6,F9,41,D3,51,23,CF,5B,D9,56,B7,3D,1D,1B,F4,11,49,6E,E3,E6,21,B8,40,06,40,5B,F3,D6,8D,FB,41,40,03,E7,5E,96,F7,A5,C3,B5,A7,E8,82,10,D6,C0,6E,5D,93,B0,C8,C3,AB,39,FD,8C,5E,0F,2B,D0,1A,B7,23,CB,14,CE,16,C2,99,B0,6B,E3,B6,C2,78,1A,94,1E,96,99,54,45,73,E6,73,8B,EC,5D,19,0D,EC,13,AD,D0,FB,6F,57,99,D4,E3,19,FC,DD,B3,89,F8,F8,95,7A,6F,6F,6B,B1,E5,49,93,BD,8C,8A,86,4F,F5,C7,2A,C5,D3,40,E7,27,7D,1B,3C,7E,04,E5,2F,15,1F,5B,F5,BD,B5,B6,2F,4F,76,F7,45,51,33,3A,AB,25,03,E8,E4,8A,85,F3,C9,C3,98,48,28,7D,15,36,5C,FD,E5,45,73,C3,21,0B,7C,3D,E3,1A,82,E0,DA,19,F9,F1,F1,6F,78,08,C6,EF,36,47,A8,C3,9C,6B,48,9D,6E,86,B5,55,F9,D7,35,02,09,61,6C,E9,54,FC,1A,56,7B,40,BF,E3,E1,C2,D6,8B,DA,36,CB,4C,FF,A1,17,C6,4F,C0,EF,F0,38,40,88,93,17,86,32,F7,86,6A,BD,6F,E6,F4,7D,40,53,B0,5B,A8,69,BC,F7,BC,76,C2,F0,8A,24,C3,EE,5D,77,9A,60,3D,ED,ED,0F,73,FA,98,9B,11,F2,A4,2E,8F,4D,B6,CD,5F,38,20,D4,D8,DD,D3,D4,FF,7A,65,0B,B8,58,3B,B8,BE,B9,AC,22,48,55,61,6C,59,23,C0,83,FA,D3,0F,F3,B3,5E,1E,A9,9D,9F,77,1C,20,9F,93,7F,99,EB,7F,36,96,7A,FA,09,EE,91,03,7E,28,75,0E,09,06,85,A2,0F,4F,55,9E,4C,D2,63,C3,97,C0,1F,DE,00,9D,DA,3E,A7,35,0A,DB,C6,6A,63,91,BB,11,99,64,6E,7B,2E,4B,01,DF,E8,13,EB,D0,B2,1F,2B,F6,ED,19,9B,24,10,E8,95,F8,94,E4,76,98,49,66,AE,49,B0,74,B4,40,BE,BC,59,46,03,CC,8A,48,C6,DD,92,4A,9E,D7,C6,70,8E,2B,F8,DC,84,8A,35,F7,56,2E,4F,41,31,93,72,B1,5F,13,6F,0A,44,23,7F,8B,EA,2F,F7,58,0C,BE,2C,D9,DD,93,09,47,FE,9C,DF,30,E6,97,EC,3A,C7,44,E4,12,AA,DE,0E,79,0A,3B,06,65,80,B6,37,FA,79,9B,F5,E5,ED,6B,DB,54,1B,1B,F5,86,9E,AF,1A,94,EA,7D,36,A5,84,12,41,4D,EF,37,E0,F6,FB,DB,EE,7C,59,AA,F8,9A,4E,92,9B,0B,20,11,94,0F,5F,CB,96,D0,B9,78,5B,DD,DD,54,2F,F0,4B,EF,03,29,87,1A,13,D3,1F,4A,22,A6,99,8A,B4,D9,B0,29,ED,39,46,9A,E4,0D,E9,7B,90,BD,16,C8,61,BF,FC,00,97,75,39,37,C1,27,7A,91,C5,CD,37,A8,CC,04,EE,96,5C,E6,71,5F,86,E6,55,FF,82,DF,D9,A6,A3,E6,EA,75,5F,B8,79,FF,EA,D2,F9,FF,DC,AC,C3,61,87,3B,D9,CB,51,0A,E2,39,98,73,B0,47,BD,51,13,D7,BE,47,B2,56,71,8B,DC,06,92,38,ED,49,FB,C6,9F,B3,FF,88,98,F6,12,3C,5D,C2,99,3C,C7,5A,EC,97,BF,C6,8F,EB,76,7E,D7,6A,C8,58,0D,28,B0,3A,B5,68,58,B0,A6,D9,8E,D4,57,10,D7,9E,72,66,3E,15,79,E2,5B,9F,DB,B0,F5,93,36,83,4F,7A,D3,A1,9B,B6,A7,94,C8,28,F4,8D,75,CD,04,38,A6,1D,11,29,09,9A,8D,3B,F5,56,70,7B,23,35,A5,AF,21,13,A8,A0,4E,38,34,CD,F4,7B,1B,39,E8,C4,47,58,2D,19,D3,23,F7,22,33,88,73,0B,27,61,73,0C,80,40,5E,4E,46,D6,6A,BA,EC,A0,B2,DC,2B,B3,55,11,08,64,99,72,BE,FD,3C,0C,88,8A,85,97,CB,F8,98,C9,E5,BF,EA,29,B9,45,A1,81,2A,B2,F3,3C,19,7A,3D,3B,35,74,5F,72,5F,DF,08,A7,97,C7,19,E2,C4,C7,14,37,E0,8B,EC,BB,1F,D5,1A,3D,5E,D1,0A,BA,1B,AA,B1,7B,E6,BD,21,F7,00,FE,C7,42,17,CD,74,8B,B0,C6,16,B5,5F,64,7A,28,E8,1F,20,14,57,4E,BD,4C,56,98,EB,9D,6D,82,3A,E1,73,F9,93,1F,EC,7B,56,4C,B9,14,CE,B6,88,E5,FC,F8,7F,AE,20,5E,A4,A8,B7,FF,9B,9C,52,18,64,F8,C0,0E,61,4F,86,9F,78,51,97,12,63,CA,3D,2F,94,E0,F9,23,E4,DD,0C,C1,86,A5,05,EF,1D,7B,0A,C3,5F,50,A9,55,91,27,3E,2C,E9,07,D2,4A,36,A9,6A,FD,79,8F,A2,E5,3B,89,B4,1C,54,89,B9,4A,A5,84,AD,4B,1F,52,E5,DA,F4,28,B1,78,8B,B5,E9,6F,8E,67,4F,63,F1,B2,18,45,A7,77,7C,9A,96,15,03,3E,D2,07,04,37,66,15,DF,0A,E2,32,4C,63,C2,C4,4A,FC,E5,48,88,87,6A,89,D5,B9,AB,F3,C2,3E,6B,7E,0C,C2,42,B4,AA,08,BD,21,A9,07,F1,D6,76,BB,41,1C,B0,E1,9B,8E,32,FC,82,D2,85,3D,00,20,93,D4,19,73,F8,61,59,CC,76,E5,A2,81,AD,B8,88,0E,F9,0D,E4,D4,C3,49,2E,D1,24,26,B0,2C,34,EE,52,B9,75,7C,78,04,DA,3D,6C,4B,D4,33,7F,18,D1,C2,40,44,58,1B,DA,12,5A,6E,E8,8E,A1,77,68,36,AB,48,9C,8E,5B,50,D4,29,95,05,2E,06,1C,7B,89,3E,A9,F6,E4,3C,26,B8,91,52,34,E5,54,71,DC,BD,63,F6,B7,92,B2,0B,85,A0,0B,EC,DD,E9,FE,57,63,A2,C1,E7,F2,85,AA,C4,9A,A4,A7,93,9D,DF,B0,FB,3D,3E,5C,53,50,C9,C6,96,E0,35,73,88,2D,67,E2,80,51,DC,77,3E,16,7F,A4,B7,AA,E0,87,93,85,F3,63,0D,06,80,3D,DC,C3,4E,F0,81,29,08,60,34,FE,7A,85,54,A3,86,34,A5,4C,D8,B2,15,C1,76,11,51,41,1A,35,44,EB,78,04,67,59,6E,6E,7C,37,7F,CE,DA,F3,2D,C9,EF,4D,F7,02,6D,15,59,2D,B4,75,04,2C,F8,A1,35,24,DD,F3,39,37,5E,6B,99,85,FD,4F,ED,65,4C,4C,E2,06,FC,C7,B7,B5,E2,F9,07,A9,3C,EE,59,2B,75,32,9D,62,C4,30,4D,DD,AA,FF,5B,CD,1C,75,8A,76,1C,E7,EA,7C,FB,5E,21,2E,C4,36,AB,27,49,4D,86,C1,BF,38,EB,16,01,03,17,60,9E,F1,5E,93,3B,F3,71,02,F5,05,36,A0,A6,39,6A,04,DF,5E,7C,F3,03,8A,C6,01,AD,71,24,99,D7,37,9E,4E,F5,FB,27,A4,27,B3,66,E0,45,85,5A,50,16,8A,0C,2E,57,81,3E,5F,CD,58,7D,1E,F5,40,8B,35,8E,6C,17,D2,97,28,D7,E7,09,52,B3,1F,D9,FB,D8,DE,0A,7F,90,4F,6E,43,5E,4F,03,3B,13,94,FF,92,D8,DD,D6,99,83,C6,BB,42,7D,7D,4B,44,10,32,9D,A0,45,EF,79,46,91,DC,A2,DC,83,EE,0B,49,B0,2D,55,AE,EA,C4,A9,3B,DB,E9,84,8A,33,D2,CC,E4,30,51,89,80,24,E6,EA,E7,DF,E5,99,B7,5C,77,F5,03,C5,3A,68,E2,FA,45,5C,5F,1C,86,F8,ED,F9,66,69,5B,F9,B9,73,7E,E1,87,99,E9,5B,AD,81,6B,CC,CA,D2,CC,A5,2E,EC,92,56,B9,D0,3E,31,B4,F5,07,9F,3D,EA,72,8A,7A,23,C8,B7,06,F8,58,86,E7,C1,3E,0C,CE,E8,A4,45,AF,22,D6,DF,13,46,1F,01,15,BF,98,CF,9B,23,1D,7A,03,AF,A9,3F,2A,D5,08,DC,33,2C,3B,4D,BA,76,35,BA,17,03,F9,7D,47,8A,1B,F4,0E,15,85,9F,E2,77,F7,68,FE,94,08,96,4C,D2,12,05,E0,D4,0F,5D,0B,24,04,79,88,69,6B,47,DE,FC,C0,1A,22,DA,C2,BF,85,FB,67,8C,A0,EC,1C,AB,FC,CD,58,57,4F,C3,1D,A4,49,03,53,E3,67,78,6F,6E,C9,5B,C7,89,99,96,60,A2,34,F9,6F,13,50,D9,98,0B,7F,7C,E4,D1,EF,98,7F,98,0A,3B,D1,BC,6B,DA,47,14,6F,E0,78,03,86,B0,27,A6,78,2A,54,BF,8C,04,96,D5,FE,2D,F2,03,46,E0,AC,B9,C7,71,47,7B,27,97,FD,68,CB,D5,11,BE,C6,7C,AF,17,7C,03,23,D6,37,AB,B4,1F,4A,8C,E4,4F,D7,F2,1D,4A,39,FE,BC,33,7B,24,A5,7A,D7,E0,88,0D,BE,59,0A,74,43,FC,27,46,37,E6,5E,D3,F1,45,55,E0,30,49,4E,19,0A,B4,F2,FC,78,CA,F8,15,3F,BE,FB,68,43,37,CC,09,59,10,98,E1,65,A8,E0,1A,10,16,2E,03,53,08,3C,A5,98,1E,44,6B,50,B5,CB,A7,44,2C,72,40,6F,F9,8B,3D,81,FB,DD,46,73,10,C1,A3,EE,8A,6A,EE,C4,BE,32,38,E2,A4,06,9E,53,E3,98,3B,60,6A,9D,A7,AE,68,82,B1,E2,73,74,32,45,7A,37,93,28,EE,D3,1C,85,64,8D,14,D0,D1,88,A9,99,7E,DE,4B,5A,2D,7F,BE,A7,FB,94,98,FE,D0,2D,EB,99,20,11,25,2F,3A,65,58,C8,AD,A1,2A,4E,CC,8D,DB,C9,C1,47,A4,41,FC,D6,AD,13,41,1D,B9,AB,3D,17,B1,29,B7,95,54,D1,85,FB,F5,4B,1D,A6,F7,5B,81,82,DF,A2,14,84,80,9E,36,45,33,38,42,E7,66,68,C7,4D,BD,2E,83,3E,2E,47,F8,19,39,EE,75,86,3D,81,A8,C7,C6,72,57,75,69,C1,0C,EB,AD,99,77,07,26,6F,7C,6B,68,86,1A,3A,11,9D,E8,DD,18,5C,23,85,15,B6,65,9D,3E,7D,95,BA,3D,6A,A4,C5,C1,D4,EA,BA,91,E1,1E,25,DF,55,15,68,D7,BE,FC,28,C0,E6,E0,86,A7,20,3E,5A,84,63,C4,1B,33,89,72,51,40,88,5D,FD,6D,73,2C,2F,27,69,1C,05,02,61,3B,09,D8,F7,D9,B9,1B,6B,33,87,8B,D2,42,E4,45,C1,C8,56,6A,12,6B,0E,0E,3F,43,E1,1E,7F,67,56,F5,6F,75,31,C6,83,86,92,4D,26,89,CB,0D,D9,2A,E9,03,24,8C,A3,07,8B,96,22,B1,72,C7,EE,DB,93,C6,C4,CE,2F,BB,E2,2E,FC,FC,C2,A4,F5,7B,3E,C7,BB,70,52,6D,BB,33,03,9A,E5,8C,FA,BE,76,D8,6A,AA,00,5A,D5,1C,62,C0,DF,EC,97,8C,D4,E4,66,09,93,BF,05,B3,83,65,90,D7,64,42,87,1F,E2,DE,A9,A4,B2,58,9D,D7,02,B0,F3,51,C7,CF,57,8B,08,53,EA,0E,EE,E9,AD,76,A4,A7,6E,BD,71,3A,92,23,0A,EB,6B,54,40,AA,F5,50,A9,E1,73,52,78,F9,6D,E8,DD,6D,E6,D6,C4,56,B6,D6,D8,9F,36,D6,29,0A,D9,79,BB,80,57,C5,45,7D,48,14,6D,FB,90,2B,1B,CF,C2,82,32,00,5B,BA,2C,7E,A4,2A,D8,97,30,9C,41,C0,C7,F3,75,BE,EB,5B,DA,AC,22,11,CA,F2,A7,BF,62,B0,3C,E0,39,D0,BA,F1,29,03,0D,7F,17,89,BA,61,1B,82,66,DF,44,B7,F7,6F,3B,33,E7,0C,17,46,ED,21,30,65,97,BC,94,20,79,39,0D,48,0F,B9,54,09,E9,00,84,EA,FA,A0,FB,3B,31,C7,70,15,CA,EC,68,DC,CD,F2,19,5B,C1,37,D4,9D,E2,EE,33,DB,2A,48,20,56,58,1D,29,2F,79,88,F5,72,0B,53,A1,B1,62,F3,FE,73,4D,51,92,53,57,30,FE,CB,6D,29,AF,2F,7C,5E,72,DA,91,4B,E9,AC,7D,29,52,AA,95,3C,1F,80,83,3A,76,70,24,52,55,15,8C,7C,BA,CA,26,C9,B5,3C,54,F3,1F,8F,22,02,1C,0A,11,33,A6,C5,59,82,D6,EF,8E,97,50,54,78,A2,1E,53,36,23,FF,D0,68,26,AE,A0,9F,15,AE,20,C2,2C,D6,89,A8,B5,41,DC,12,DC,CF,93,66,86,FF,46,B3,21,5F,D5,4F,3B,26,E1,1B,EA,1B,C4,27,F5,F0,90,3D,F7,9E,95,31,43,40,92,4C,1D,86,0E,F6,EC,8D,2A,70,D0,88,0C,06,09,13,D1,29,7C,C1,AF,DE,4E,44,38,23,2D,AD,63,9F,BE,6A,FA,36,35,5E,20,DB,DE,E7,75,6C,3E,35,C8,98,26,BB,63,89,06,81,50,29,15,BF,41,6E,0D,4B,AB,A8,73,B6,AB,C4,7B,FF,71,19,EB,4F,41,FD,11,4B,83,51,0F,70,B3,C9,64,5E,58,17,AA,A1,2A,82,27,ED,B5,6F,73,29,4F,BA,71,00,F1,A5,BD,A5,46,6D,0D,5E,ED,14,BE,9F,9B,42,F1,51,8C,8E,F0,5A,B3,CE,09,F3,04,81,96,94,E2,22,86,E5,B0,44,75,45,1D,7F,C8,56,34,25,30,A2,40,96,04,8E,F9,5D,EA,21,AD,60,4E,81,37,A6,EE,38,B7,0B,41,23,B6,C1,DE,1B,46,5C,E7,24,B0,B4,D3,9A,43,F0,10,DE,8E,DB,FC,A7,55,BA,3E,E8,9F,34,F6,AD,64,99,14,7C,20,5B,EA,71,56,FF,52,AC,92,70,C6,D1,75,9A,E3,21,21,44,CF,B9,C6,41,46,8F,0A,2C,5E,65,49,B2,C2,EA,53,C3,0B,DA,81,D0,B1,D2,08,F0,83,1B,A3,D3,99,42,38,8E,73,BF,49,3E,30,A6,1D,A5,80,F5,31,BE,9E,8E,16,7F,A4,96,36,CA,33,65,31,D8,ED,5B,02,9E,9C,F2,70,88,DC,CC,EA,3A,9F,D6,18,43,3B,34,C9,1D,3B,26,BD,CF,81,81,8A,BB,0D,DD,4C,BE,1A,49,80,16,E1,B5,8E,DC,E1,55,C7,11,3A,78,2D,42,8A,C5,6A,93,6C,B6,F1,AE,3B,DD,4D,97,6E,ED,79,D3,B0,75,9B,80,B4,8F,5B,E6,F0,6F,10,04,98,D7,36,16,49,A8,51,CE,10,80,AF,7C,A9,8C,27,92,3C,83,60,C7,95,90,E8,CA,EA,C3,D9,0C,AD,01,2E,01,A0,25,D4,43,A5,D1,FD,93,F2,49,61,30,1C,D7,B5,B8,4E,C6,A4,E8,D9,3D,B9,74,E3,84,1D,B9,53,9E,90,53,F6,86,D0,BA,0C,9A,C1,A5,08,99,4E,CB,4A,36,48,AE,11,7B,80,88,E6,DA,CF,6F,0B,44,A0,4D,0B,DD,C5,D7,D7,5C,2C,20,8E,4E,A4,4A,53,25,73,69,C3,F4,6C,A4,4D,8A,50,DC,D3,AA,BB,4B,1A,5D,73,F9,7B,2B,78,68,C1,B4,44,28,96,74,16,31,7D,71,64,C1,E5,0A,8C,E3,33,09,21,86,73,89,85,E0,6F,E1,09,FA,A5,72,ED,D0,6F,70,7A,15,5D,A0,81,FA,95,24,BE,9A,02,73,22,1B,E7,0E,B3,FB,C7,8C,D3,6A,D1,CA,5D,56,4C,9A,27,F9,A0,87,C1,71,44,4B,7A,7C,AD,36,6B,1B,65,B7,2F,41,69,48,3F,65,32,35,E7,16,B1,B3,A4,AE,F7,69,65,4A,AA,56,51,42,D9,6E,11,66,4A,F9,1F,B9,A1,07,17,6C,70,8D,6B,D8,AB,8A,E2,76,E0,80,9C,A0,4F,6E,60,21,8C,6F,37,DE,08,6C,30,E6,44,16,1A,27,F5,A3,35,AD,57,51,E6,6A,75,FB,FB,46,37,6C,FA,91,4D,DF,A4,E4,3D,20,A9,8B,2E,86,EB,32,60,C6,A3,28,33,94,47,6A,57,29,CA,7D,C2,18,84,57,26,00,78,B5,47,36,2D,E1,B4,8B,2E,02,EE,63,EC,2F,C0,D4,CD,19,6D,43,F5,AD,94,FE,B4,23,28,FF,BC,1C,63,A7,95,FC,67,C5,6D,65,CC,65,D7,98,B2,A6,86,0C,89,80,ED,CD,E0,73,07,9F,0E,F4,06,D9,75,12,F7,7B,0D,CE,A7,51,7F,3A,1F,DD,92,B3,55,D7,10,99,FE,2D,4F,71,79,70,98,97,A2,E8,53,88,7B,11,82,2C,25,4A,EC,3D,4F,72,EC,AB,AA,3A,80,26,22,64,A9,18,0D,A9,E8,3A,0A,D4,D0,BA,99,FB,AD,FB,73,38,70,00,66,56,10,86,6D,46,FC,2E,C5,A9,36,2B,E9,59,D2,4F,CA,E4,EC,D4,AC,A5,A1,E4,F2,D2,A0,D0,55,39,3C,09,2D,85,F3,BB,57,43,D4,C4,5A,CA,0F,BB,AE,06,97,2C,A8,4A,29,A1,52,A5,7E,57,34,28,39,32,4E,84,48,44,12,CB,14,C0,25,94,84,41,E7,5B,07,30,15,04,C1,C2,C0,12,F3,21,9A,3B,C0,84,D7,87,4E,AB,F8,94,33,D6,C7,D9,93,DC,53,9F,F3,26,72,5C,80,48,9B,6B,57,B4,2A,BB,C4,45,86,BF,10,B1,2A,F8,3D,A4,4B,C5,F2,2A,7A,44,58,2B,07,C4,35,72,99,55,57,AE,16,33,9C,FD,0A,1C,B1,A6,BD,D8,AD,7F,66,E4,8F,03,C6,E7,F9,11,8A,48,26,BF,73,AE,79,32,32,4A,09,F3,2E,1A,3A,8B,90,AF,BE,16,44,39,F9,1F,E7,2D,44,6A,25,AA,97,B5,5B,0F,A7,E3,B6,E2,B0,E5,8E,70,10,63,7A,E5,99,90,EF,67,18,91,44,7D,F2,EA,68,E7,C9,64,C2,DB,1C,FB,FD,82,C8,3D,B7,30,B2,C7,59,84,23,E0,30,0A,EC,51,80,44,6B,F0,B9,5D,6B,CB,D5,69,C7,4D,E7,CF,F4,C0,7F,63,44,31,93,2C,BF,25,B7,90,B7,BF,07,04,12,8B,90,50,4F,74,3F,9C,A2,BD,0F,53,94,0C,7E,24,29,13,CA,A4,FB,96,DB,A9,E6,AC,BE,8E,26,01,DC,0F,5D,31,E9,98,AF,B7,7A,00,D7,D5,13,09,BD,13,DD,7A,AF,42,79,2B,3B,28,81,53,5B,7D,BB,BE,F9,2A,68,B1,B9,DB,31,01,80,33,EC,C4,3B,63,DE,C8,69,BB,25,EE,A9,34,01,B3,DC,7A,B6,A0,B9,EC,F9,01,08,B2,F3,BE,41,47,D2,81,D4,D4,8F,CA,58,05,19,CF,0A,D6,E9,B0,3F,BB,01,9A,47,2D,52,52,A8,4A,D9,CF,EC,9A,36,2B,0F,D6,D3,BC,A2,A0,FD,84,74,C5,ED,16,0C,05,C1,80,B2,6D,3F,5D,BA,3C,08,B4,B4,C5,0C,89,A4,69,85,60,FE,5C,4E,78,C6,88,A4,B1,D5,0C,B1,75,45,3C,AE,E1,E1,B8,76,D3,04,85,88,31,19,62,43,44,D8,9C,1C,C9,91,C5,CA,B6,E3,FA,41,2F,3E,26,9A,85,C8,D3,A1,C2,1A,4E,06,32,8A,55,26,24,B4,2E,CC,31,7B,00,D0,A0,F4,76,A1,F9,77,1F,48,53,4B,C2,73,4B,30,8E,D9,41,B0,00,95,AA,C0,84,A3,E3,86,08,E9,EC,22,3B,95,C5,BB,95,8E,FA,F7,D9,B6,D6,BB,64,2B,18,C6,F9,00,DB,AF,C7,09,5A,43,0F,7C,C7,A1,15,2D,89,23,F8,70,5C,10,B8,E9,EB,70,71,6D,BA,44,3E,E1,1C,51,D8,12,54,34,3F,B1,F9,15,47,E7,3B,97,F6,84,D5,2A,97,7B,16,70,BE,B5,B0,40,82,45,37,62,75,52,C7,26,BE,36,7B,19,E6,AF,7D,A4,3A,CD,9F,3E,87,6F,C9,69,D8,8A,96,E5,C3,07,2F,66,84,3B,66,8D,8B,F0,17,27,70,7C,47,12,DA,9A,38,46,A6,96,9A,C5,57,87,B8,B1,2B,84,C9,9F,E4,D1,86,03,B1,B1,FA,32,38,AE,FF,4C,1C,84,1C,28,4D,29,8D,2B,20,AD,C5,3F,F0,C1,72,95,3D,70,8B,4A,51,C1,07,B8,39,D7,DB,84,36,B6,C8,E6,43,8D,F7,8A,9F,47,79,43,08,58,EB,E3,95,14,D8,23,29,39,F2,01,DE,77,3A,E8,16,E7,88,3C,8A,9F,F5,A6,61,BF,8E,7F,09,BD,84,EB,BA,B9,EE,6B,77,7E,CB,65,B9,A0,24,1D,5C,29,23,EB,14,A8,61,3D,E8,FD,55,FB,87,48,00,F8,DF,9C,2E,89,0E,92,C2,F7,AD,14,8B,79,55,BF,55,04,83,BD,AA,24,3E,A7,0B,67,E0,0E,23,B6,A6,57,CB,2B,DE,22,ED,6B,9E,C2,8B,32,33,FD,1B,F8,5B,C2,DE,1B,DC,B3,C5,33,33,CE,40,65,6A,AC,76,6C,9B,27,26,19,35,0E,2B,08,04,7F,22,5E,97,79,9D,F1,99,1D,1F,15,83,12,77,74,F0,80,22,46,A8,13,A2,5C,25,58,E9,23,0C,C4,C6,FD,ED,7F,D1,F4,3B,40,8B,B6,DC,3C,18,58,F0,69,65,86,4D,80,6F,80,60,AB,DB,C8,E8,08,EB,4C,25,D3,90,5A,31,09,C2,DF,9D,6F,E6,D2,CC,96,A6,AE,3F,18,E9,62,21,4D,08,B3,4C,C6,B6,9A,CA,67,99,0F,76,EB,30,BE,D6,3F,04,6A,A8,F5,5B,1E,2A,5F,85,C9,64,BA,D1,FE,42,FD,72,D2,3B,5D,06,97,FC,1C,F4,F0,CC,CB,58,7E,CE,11,F2,C7,6B,69,29,68,C6,98,FD,0E,6D,6D,A8,56,B4,B5,FC,BD,D6,3D,81,10,51,0B,B2,D7,1F,89,07,E5,66,81,2D,1E,E0,14,C8,31,F6,9B,81,63,CF,D8,ED,D5,A5,0E,22,2C,11,81,34,88,75,87,B8,5F,A7,80,DD,EC,1E,A2,03,F1,4F,41,E7,C3,6F,6A,80,C0,30,A7,1B,92,DB,3F,69,E3,61,58,E8,10,0D,B6,EF,54,09,72,65,AA,CD,22,5C,45,47,51,AD,74,E3,66,EA,29,58,FD,B1,67,A1,9E,98,28,8D,00,55,27,09,1B,BC,3E,A4,8F,E7,96,43,7E,3D,61,43,1D,47,20,87,82,D3,96,D4,37,5D,2B,5D,19,9B,53,0F,06,E0,C0,DB,63,59,03,20,64,9D,E9,1E,D6,94,56,17,3C,CB,4A,41,3E,2D,50,62,43,33,74,CE,D1,F6,09,30,62,B4,47,E1,1B,DC,08,8D,88,3B,F4,41,5A,F9,C9,7F,D1,D8,ED,29,55,75,10,E5,7C,37,70,21,AE,8D,3A,49,D1,53,4D,EA,64,BC,A8,EF,28,5D,78,69,64,17,18,B7,6A,CC,EF,25,6D,51,64,CC,67,4D,80,D2,C4,E2,5B,BF,81,E8,EF,3B,C6,08,E4,58,6F,41,D6,C9,8B,05,43,25,B4,A8,1F,72,84,6F,D4,21,4F,9A,DD,78,42,BA,C5,83,5A,B2,AD,AB,BA,4C,14,4C,52,BC,C8,56,63,38,7F,B9,6D,EC,9C,C2,5D,E3,BA,A1,04,3F,74,82,1F,DA,78,47,76,3F,46,30,84,35,7F,81,C1,B1,9B,C3,8D,50,75,07,5E,FB,81,01,15,D0,CB,55,4C,4B,5A,06,55,87,DA,D3,FD,03,42,C5,12,7E,83,5B,83,87,C9,BC,CA,82,11,EF,03,ED,5C,27,AC,86,4D,33,C5,21,84,86,E0,ED,D9,34,2F,E4,18,12,BC,8D,81,65,AA,7D,1A,97,2D,6A,1F,6E,F9,7A,7B,8A,50,8D,F6,55,6E,57,53,B1,03,F0,DA,58,2F,DD,88,C4,A5,FB,5B,62,E1,88,1D,07,A4,B8,D8,9A,AA,54,D6,02,4A,2D,FE,DF,1A,09,D3,EC,A8,6D,82,69,F5,B1,0A,41,39,7E,F7,6C,F6,01,61,0E,76,E1,09,94,7D,64,DB,2B,E4,E0,37,7C,13,93,26,6E,FB,41,D0,E4,4F,D5,A9,94,94,45,EB,D2,32,95,EE,AA,FB,BA,E7,2B,6B,59,F4,EE,28,1E,4B,A9,A6,EF,4B,2F,BC,B8,9E,4F,A9,99,5F,29,D6,B4,7B,D2,B8,D3,E1,99,16,29,53,D5,E4,04,A4,40,2A,DF,FC,02,89,B9,3B,47,4E,7B,D6,03,6F,B5,A2,D8,F0,E3,EB,A4,AD,14,4B,1B,13,89,78,EA,76,A5,A0,F1,CF,DE,75,92,B3,BA,F7,CC,8F,5E,FE,3F,81,CE,BE,66,1B,53,D2,24,21,0C,18,EB,9F,BC,83,D1,A2,B6,5D,45,0A,BD,20,C3,64,9D,6F,86,F1,D5,A7,58,4F,D3,31,74,8C,5C,A5,46,29,AB,AF,AA,C5,E4,3C,0A,47,A1,C4,57,BF,C4,E2,21,14,CA,04,BA,98,BC,D5,6C,3B,B3,62,0C,C7,57,2E,46,50,4C,00,2F,9B,45,0B,08,F9,11,CB,E0,76,EB,91,76,C3,71,DD,EE,DF,3D,A9,F5,47,20,49,B3,39,5E,84,B7,DE,66,66,2F,04,A9,ED,72,B0,9A,DA,7E,FD,09,EF,72,DD,BE,64,C1,1C,61,7A,8C,AE,3A,4E,37,D4,5E,64,BE,BC,97,EC,8C,10,4B,B9,A5,39,67,38,D2,4B,22,48,AB,77,DD,16,94,33,2F,6A,50,12,3A,B1,E3,AF,55,B3,5C,FB,DF,61,92,EA,90,D1,C5,13,75,CC,15,1E,37,8E,E2,D4,CC,9A,E5,9B,F1,FA,0B,7D,B9,1B,C5,1B,67,C4,46,24,75,FE,2F,2A,42,48,45,F8,5D,A3,31,A7,A3,F1,0C,5E,44,25,A7,52,41,F6,E2,8F,27,6A,31,4D,30,A3,30,A3,F4,D0,88,A9,81,66,D9,C5,33,A1,94,5E,D3,B1,B9,81,57,72,3F,1E,E5,5B,4F,70,D2,F5,17,F5,3C,4B,AA,D9,50,E3,C3,DF,41,C7,8F,47,8D,83,71,34,0C,22,61,81,6B,B1,BD,5D,8A,8B,F1,C5,1B,33,0A,F0,02,F8,56,BA,24,11,F0,05,DE,24,35,B9,01,84,C3,79,76,06,B2,52,B5,95,47,B0,20,F9,5F,FB,ED,E4,72,76,08,F9,6B,28,5A,9A,19,4F,49,05,76,EF,DF,A8,4E,A5,08,FA,94,4F,75,3A,69,EA,F5,D1,5A,61,0C,32,97,26,6A,72,0F,67,9E,BC,83,04,00,3B,F5,B3,72,34,41,49,88,ED,54,7E,3D,BD,54,12,62,61,22,B4,0D,72,C7,6C,37,EF,D3,65,A7,41,1B,B5,0C,4B,8C,36,77,9D,C6,A4,29,9A,07,8D,05,A0,37,75,68,10,7C,59,10,4C,B6,BB,CE,0E,BA,37,33,CA,E3,49,92,A9,22,6C,2B,9B,D7,37,20,DF,A5,15,31,A6,E9,AF,A5,0A,3C,41,2F,76,D3,DA,25,81,32,A0,22,A7,2C,43,DC,26,11,DE,BC,60,CA,B8,37,52,33,A6,3B,DA,CC,B5,7B,C3,18,72,E9,BA,D3,1B,FA,15,C8,92,A1,4E,2B,78,C4,0B,17,9E,5F,E1,3A,52,CF,60,99,8F,DD,F7,CD,65,20,8A,19,21,EC,85,99,87,D6,43,A1,BB,34,F6,93,FA,AD,C0,E9,CF,B9,57,55,64,57,A0,23,35,8C,6D,77,55,ED,81,BE,1F,AF,3F,F2,BE,2B,6F,ED,91,54,01,2E,69,4E,2F,21,BD,2F,D1,13,D8,E6,DE,F6,6B,67,0D,7C,D5,C7,07,37,DF,AC,0E,D2,22,6E,F2,C3,B3,19,7F,E4,AF,3F,5D,E0,88,B6,C4,21,9C,A6,A1,74,12,31,98,7E,98,89,ED,94,19,5E,4D,7F,B0,A1,A1,40,D6,D8,32,81,63,26,55,2B,6F,ED,10,8A,5D,F7,B3,4A,65,1D,25,91,F3,0A,67,E5,6B,AA,F3,B9,4B,77,C7,AC,54,C3,EB,DD,33,96,F9,56,FE,08,B6,06,90,C1,A6,6A,C5,C5,AD,AD,33,2D,42,B0,AE,60,89,89,71,D0,26,B2,E6,E7,CA,B2,AA,24,3B,6D,C1,3B,97,84,DC,CF,08,90,55,A2,07,A5,2C,4E,8A,E8,CA,02,C2,5C,58,1D,3D,15,AD,08,37,54,64,30,BB,7E,57,16,22,A9,9D,61,3B,D7,24,78,30,81,C3,65,67 - -linearMatrices_full = 31,C1,12,36,B1,D3,AE,D8,FA,91,7D,27,02,E6,03,2B,C2,06,E3,FF,07,CD,DB,C7,62,DE,60,8C,B8,CC,3B,54,CC,E5,D2,2B,D8,F8,D1,D3,B2,62,29,6B,92,F5,88,78,7D,21,35,51,91,73,5A,6D,28,FC,ED,D1,5D,A0,26,F8,70,78,D2,8D,41,11,21,32,11,78,88,E2,B2,60,51,CF,F7,1C,2E,DF,7C,39,29,DA,2A,3A,9F,3B,3B,1F,C8,EA,A9,C2,C0,55,F0,3E,A0,97,5F,A6,59,6B,38,9C,CA,52,20,55,EC,F5,83,12,FF,E2,18,4A,A0,32,67,AD,92,60,E9,40,5D,DE,1E,25,DE,AD,2A,50,73,36,CF,87,C5,45,F3,CB,37,5A,96,F8,D0,EF,B0,5B,58,60,FD,EE,B7,5A,AB,B6,8B,84,3A,F9,44,F9,6E,19,9C,9D,AC,93,A8,AF,28,88,C7,53,DE,B1,DA,1E,C6,42,A8,95,BB,34,EC,C8,9D,46,2D,A2,7E,D3,9F,E2,09,C0,26,EA,98,5F,D2,DE,B9,72,56,8A,A0,9F,06,72,C5,E4,65,46,1A,EC,DD,66,42,5B,57,F9,20,1C,1F,72,9C,AF,F3,2C,69,DF,35,3B,6D,9E,98,2B,9D,C0,3B,59,EB,93,CC,DF,CD,7B,F5,26,18,94,54,B6,44,8D,E3,41,38,79,24,CC,30,36,7D,EE,55,2B,08,B3,D3,F5,5E,B4,D6,FC,1B,49,0A,A7,F2,D2,2E,40,EB,71,70,A4,9D,B9,A6,28,96,C1,B5,98,40,E3,3F,F4,27,D6,B3,AD,E8,04,1F,83,4B,40,82,B8,4C,D4,20,98,64,CB,C6,BD,03,4B,E7,71,0A,D1,9A,30,8A,D2,6D,7C,CE,42,78,A0,AC,68,91,B3,77,B8,55,F7,E7,14,8A,20,99,DC,59,90,55,2C,F7,89,E7,03,5F,F1,B7,57,07,B1,2B,6A,03,0C,1C,11,A3,A1,99,D6,DC,1A,0D,1A,75,3A,FB,5B,86,ED,E4,A7,4F,2B,4A,A3,02,25,30,B5,5C,7A,31,7F,41,A9,6B,9B,1F,08,A4,13,92,EB,D1,20,90,52,9F,05,92,5A,DF,15,16,52,A1,6F,0E,35,46,A7,01,95,3D,E0,5B,AC,81,0C,99,1B,BC,D3,BA,B4,99,F0,75,0E,C2,4A,19,5E,13,D5,29,48,59,E7,B0,30,5D,90,3F,C3,36,94,2D,74,A0,0A,DF,AA,82,48,3D,B4,55,CE,6A,DA,12,C4,61,1B,E6,CB,1C,32,AF,A8,1F,DC,E3,DB,13,0B,F7,C1,49,C6,EF,B0,36,2A,C4,D6,7B,2E,0B,50,4B,A4,98,BE,D3,35,08,71,BD,68,D4,21,EB,46,49,DE,A6,89,52,FF,BB,BF,7B,14,94,B9,33,81,79,59,F0,3A,AB,1C,72,5F,05,BF,2C,51,76,2C,DB,2A,41,B8,6F,AD,CA,23,AD,E4,6E,C3,CD,E8,4E,5E,34,DB,55,43,63,CE,52,D5,B8,1B,19,76,FC,8E,59,E9,BE,09,A2,15,0E,C9,B9,C7,38,EB,15,91,3E,FA,41,F5,9A,32,3D,FF,DC,04,DE,E5,1C,25,D3,28,03,C1,59,49,AA,94,04,1C,40,7A,CD,35,A6,36,EC,54,1E,E1,E7,CF,CA,FB,28,A3,76,38,36,A7,DB,07,7D,62,3B,26,42,1D,45,43,9D,51,9A,22,4B,16,B2,59,21,E5,0F,8E,81,A9,B6,79,66,9B,C5,FE,05,30,8B,05,3F,98,A3,4A,78,D4,F7,FA,10,5E,1F,39,6B,2B,DE,C5,5D,07,E9,6A,99,B5,2F,5C,50,AE,95,70,8D,F9,98,16,D2,93,57,9F,90,97,AF,BB,F8,7E,B1,0A,3C,80,BD,DC,49,66,3C,1B,59,6F,9C,68,45,D9,AB,C8,58,BC,0A,F2,77,F2,1F,53,0D,F8,18,25,A0,98,B4,E3,56,C4,AF,A1,EC,37,72,83,FA,7C,B9,52,B8,F0,4D,64,84,61,58,93,FB,6B,66,15,F2,8D,57,F0,EF,7A,B7,38,FE,7C,FF,E8,FA,9A,A3,91,31,14,E3,9E,18,47,D1,F8,60,F2,F9,7F,4B,D6,42,FB,3F,BA,DB,78,50,23,84,A7,A0,93,D4,CB,54,23,EB,98,DF,E1,FA,B2,62,A9,63,96,C7,D8,55,98,24,4F,CC,6B,86,78,A7,07,5D,85,03,5B,A5,4B,CC,3F,82,DC,12,2B,D3,57,7B,7D,2F,15,6B,78,BD,D1,DE,68,27,BA,4B,85,1B,4C,5A,F2,D1,D5,95,7B,B3,8E,8B,E3,7B,36,11,3D,95,54,1B,F2,60,A9,EE,B6,72,3A,C4,E2,CE,48,D0,0C,F3,7D,DC,85,B2,DC,0F,7C,A9,E4,95,68,5A,D0,AE,29,9C,12,60,9B,80,F5,DC,60,31,59,F5,A0,5B,A7,1A,7A,B5,AD,AE,88,94,6E,E4,84,04,04,BF,1F,E6,EF,87,47,51,68,0F,D1,0B,25,25,18,70,4F,46,83,F9,36,1A,E2,96,A3,C3,18,F6,64,BC,95,D9,66,DE,91,34,49,46,24,EF,83,15,9A,1B,14,5F,68,45,C3,EA,F2,C9,35,E8,CE,B8,42,C7,AD,9A,5D,B6,40,C5,E0,B0,E9,CC,E2,5F,06,7A,B7,D9,81,96,1B,C9,46,62,07,61,1A,58,0A,97,D9,4A,99,70,8E,22,9D,B7,07,C7,DB,5A,CE,9C,5A,33,5C,DA,10,85,A7,4E,EF,75,F2,B4,7A,73,45,78,C7,23,25,2D,33,63,A0,45,44,95,06,BB,6F,A4,30,FF,99,9D,13,EF,91,87,63,1A,96,33,94,9E,7E,CE,93,78,1A,FC,8B,A7,E2,9B,DF,75,39,F3,1D,1B,70,1C,FD,87,18,CC,59,E1,7B,09,BA,92,7C,42,B4,39,12,38,CD,97,3E,B2,0B,73,D7,67,42,1E,E3,45,32,32,59,4C,7B,A4,E6,0D,42,43,24,A9,E6,82,31,35,92,A8,95,2D,AF,A0,6B,3F,AD,1A,BE,9C,F3,7A,85,9C,15,4F,B4,28,84,44,26,42,0E,7E,6E,A7,3E,03,28,98,F0,C7,3F,5C,97,DC,8C,37,8C,D7,D1,FD,A8,0F,EF,18,BB,B5,A6,26,F4,13,0A,32,46,BF,14,4D,DE,BA,6F,8E,3E,DC,E5,88,3F,1C,AE,9C,44,91,87,EE,5A,F3,BC,B9,C4,05,06,6A,AF,A3,CE,D5,F1,40,79,E9,C3,F9,9E,EA,46,A3,39,D1,2E,13,70,E0,C5,75,59,00,AD,6E,D1,05,72,5C,8B,20,52,E2,20,A5,FF,32,30,A8,25,AA,1C,C3,BC,01,E7,5F,A7,46,25,E8,F0,D8,23,1A,51,0C,88,DC,90,2B,8B,CE,C6,BA,C2,7E,6F,D8,E3,98,14,C4,2A,85,22,AE,33,24,54,1F,B8,B0,30,64,65,5D,B1,A6,06,5E,BE,8B,A6,E7,88,D3,C6,95,2E,EE,8B,BA,D4,74,8B,4F,26,D1,E8,8C,2C,8B,D9,9A,A2,DF,E4,2D,E8,74,B5,09,73,9F,FE,B4,E4,D4,56,C3,CC,DF,A1,D2,C6,BC,E2,57,DE,DF,D8,BB,BC,0C,3B,02,31,D3,DD,EC,AB,86,77,4A,FE,87,EE,98,47,68,A1,B7,66,5C,7C,45,B1,8A,79,57,A6,23,0B,14,9F,2A,1F,76,64,64,65,F7,27,52,A7,E6,A5,E8,BF,2B,8A,1D,2D,58,AD,9E,53,46,52,76,6C,2A,CE,A8,F6,C2,5B,6A,A3,46,30,F4,DE,DA,91,57,95,9A,BD,6A,03,DA,BF,B3,C5,A0,E9,E0,2B,B1,AA,BD,85,C0,66,AC,BB,D7,36,DE,4F,DD,CD,64,94,9F,BB,4D,54,FF,A5,ED,7E,6B,A8,FB,69,47,DB,FA,C4,57,7C,34,35,A6,34,9E,53,EA,10,7F,C4,F1,EF,4E,10,A6,DA,DC,7C,CB,DD,14,5F,33,CD,E3,6A,C9,5B,30,84,39,01,1D,21,F2,34,09,E9,70,47,C6,5E,D5,1E,04,BF,6D,4F,62,C2,D0,3D,45,59,CB,B6,7E,E1,FB,76,51,5C,1C,56,FF,3D,81,66,20,BE,45,2F,5D,A9,1D,AA,A7,75,A2,D9,20,00,59,69,F5,FE,16,BF,E6,B0,66,D2,6D,47,D2,73,62,CD,5D,E0,E7,6E,E8,00,90,8E,AA,D1,A1,33,0C,49,7F,5A,B2,A7,FF,66,F3,20,7F,BD,54,6F,41,40,68,2F,44,05,35,FA,65,CD,D1,BE,F3,8B,26,F8,3C,E5,DF,0D,9C,C6,64,FE,0A,0F,1A,0B,16,69,A4,34,7C,CD,72,A9,5C,37,AD,94,3D,DD,5B,60,B3,BC,1F,8F,19,65,5E,4E,73,CD,E0,8A,CC,EA,F3,13,81,A5,AE,6D,80,3B,2D,E0,15,2D,F2,34,64,3A,4B,96,45,A4,C9,A8,21,13,1C,67,B8,BF,13,C4,2B,55,F0,21,A4,D8,96,1B,A4,76,20,46,3C,E7,15,16,2B,F6,C0,02,A0,68,B9,E0,2E,13,FA,94,D5,23,90,31,40,0B,E3,3F,F9,6C,08,4F,FA,1E,46,89,21,26,34,68,B7,C7,84,E9,E5,E0,48,2F,FF,8F,C2,7A,D4,BA,BC,96,99,B0,96,4B,82,FD,EE,B3,B6,A4,EF,7A,FF,F3,36,AE,DD,E1,D3,30,08,29,44,6B,C8,3B,E4,36,99,44,69,F5,48,C9,11,A3,91,33,DF,9B,D5,29,D1,BC,84,62,20,86,2C,F2,FA,3D,54,5B,E1,3A,4E,C5,F6,C8,2A,97,6B,22,C0,30,B3,97,9E,82,49,FC,5D,8B,56,3C,BB,A1,D3,1E,6A,71,F7,05,F7,7F,46,E7,3E,05,63,07,AE,44,57,10,3E,F5,3B,86,3B,E5,DB,52,8C,B8,A5,CC,6C,BD,2A,D2,66,BD,14,81,9D,48,0D,2A,61,DA,99,FE,B6,A3,41,F1,D4,41,DE,E3,17,4E,B3,CB,FB,46,E4,B3,32,AC,DB,36,AC,06,E3,A8,37,AC,95,1B,B1,6B,BB,D5,89,92,88,88,0A,29,74,7C,50,E8,18,F2,7B,76,D0,8A,D4,83,61,9E,9B,EC,48,B9,19,A2,25,DA,57,3A,8C,D3,09,72,24,31,94,B3,5C,DB,4E,F1,0B,82,10,52,89,D9,34,25,09,C8,10,B8,C4,AF,B4,F1,D7,CE,F3,92,28,36,AC,B9,0F,7E,CF,F3,F3,CA,2D,7A,8D,48,21,CE,86,11,CC,20,C1,9E,E8,8D,AD,F3,7F,FC,20,9C,10,5C,3A,48,41,C0,AC,2E,A9,63,AC,79,01,71,8A,5B,54,DB,DF,F6,31,D7,31,F0,69,AB,04,8C,C8,EF,C7,8E,10,81,AE,61,F6,14,65,68,14,D1,DF,06,9F,54,D1,AF,55,2B,56,BD,72,32,48,0E,CF,40,C3,0F,AB,2B,39,B5,34,FC,FE,E1,9D,63,17,E5,BD,40,E1,4A,A3,F4,C3,10,21,01,F7,B0,16,FE,54,6C,40,D8,3E,F4,91,28,99,00,7A,36,65,66,37,58,09,FE,29,E0,AE,39,31,04,95,5B,F5,E0,42,AC,7A,70,0A,9C,78,52,A1,50,60,26,8C,BF,67,53,BE,6F,65,8F,AC,DD,9D,2C,48,91,D3,1C,BC,76,FF,E6,38,A0,B4,CB,6C,B8,00,CA,0D,AE,62,41,36,5B,2E,6B,99,40,9B,41,20,A5,11,79,57,21,5E,DD,B6,54,73,1D,A8,CC,3E,E4,F0,C4,2F,50,B1,F9,CB,49,C2,7E,EC,3E,92,69,39,0B,0F,A9,3E,17,D7,E3,C4,5A,89,0D,60,BD,52,34,23,B7,9E,7C,8F,6A,B1,CF,1A,83,BE,CD,54,A9,61,78,A5,C1,C1,35,BE,FF,17,52,40,B8,5A,83,49,2E,4F,ED,9B,55,E1,BC,FC,58,A8,32,17,8E,03,E5,44,92,92,A2,9C,EA,E2,E9,30,3B,E5,4C,42,00,BC,F1,F4,53,36,6E,AB,5B,68,32,FE,59,E9,55,45,3B,F8,2A,E3,36,3C,44,7C,BD,08,4B,24,EA,C8,11,EB,20,8A,36,FF,49,D4,8A,66,0B,0F,14,5E,12,CF,84,47,EE,C3,E7,D2,51,FB,94,7F,F9,9E,C4,3F,64,62,16,3F,07,97,F2,5F,AD,43,8C,E9,AD,61,72,B5,9E,4F,50,3B,77,3C,7F,1B,41,A1,4B,82,E5,81,0F,03,86,4E,C5,F5,5D,F6,53,8D,D0,B6,BB,10,00,C0,7A,97,80,61,46,F0,1C,73,EE,CF,01,27,2D,A8,03,92,1E,E4,1D,A9,83,ED,56,4E,E5,71,A6,98,AA,FC,55,9D,34,48,BB,45,8E,5B,25,1D,7F,2F,55,DB,74,8E,E9,F4,CB,E6,F6,43,6E,FF,E3,A9,6A,0F,00,BE,23,18,A1,B1,A6,5C,FF,46,E1,B4,30,E9,B6,AA,A0,68,0A,26,93,0F,B5,3A,FF,41,D2,CC,05,AF,D8,4D,AB,66,50,EE,31,DF,B6,3D,D4,34,DB,68,12,95,2C,3F,E9,FB,AA,4E,F1,E7,FA,E3,D8,03,5D,11,2B,87,34,45,0D,1E,72,67,EE,F3,9C,39,CC,5A,A0,15,72,3E,68,5D,4E,D4,DC,C6,D3,4E,5B,78,8F,9F,A4,FE,DC,93,23,14,3C,01,31,17,D3,78,50,23,A5,E5,91,8C,E7,8C,25,0C,C8,86,EA,0F,E8,53,00,5C,31,E4,F2,61,90,A4,F2,7B,0A,27,1B,0A,1B,A9,B2,76,BE,65,5F,8E,1E,21,61,D5,17,8E,E3,21,6F,0B,3F,21,A4,5E,59,37,71,08,00,88,04,B0,55,E9,5E,EC,0A,6A,7A,7F,37,FD,53,BE,4E,45,34,11,BF,78,E5,CF,F0,58,62,0C,99,E5,B7,66,E6,35,A9,9E,B3,10,2E,7A,02,08,B8,AF,81,89,F6,90,A2,DD,4F,9E,4A,AD,FB,A9,DC,89,AE,51,4B,33,FF,D9,75,A4,39,DF,83,AF,EF,43,4C,62,5F,91,9F,B9,27,30,DB,06,DE,20,16,D5,9B,01,91,28,14,8B,33,33,52,FC,82,28,6B,78,E0,17,8F,CB,D0,E0,D5,B5,A3,9E,FD,F7,3C,22,2D,63,16,0F,73,80,65,C8,F6,6B,4C,C9,13,72,C1,0D,A7,4D,09,01,1C,57,4E,ED,F6,E4,B0,25,FE,2A,EE,7E,8C,AE,57,3B,28,40,11,97,D8,54,0B,5B,40,0C,F3,BA,E2,C5,E4,07,6E,AA,3C,D1,14,FA,5F,7C,0F,FB,85,B2,E9,BF,C3,E7,89,5F,87,80,EF,3C,7A,93,55,97,2F,C4,ED,2B,9F,D0,DE,F5,68,30,70,B9,7B,D8,B4,71,14,FB,E4,64,00,6A,23,72,B5,E9,8D,7D,72,1B,14,4C,2B,9F,68,D4,A9,35,DB,3C,BA,F1,0E,F8,51,08,42,71,9A,FF,33,26,2B,B8,94,9F,2D,38,05,C9,7A,3E,0A,E4,57,5F,60,C4,6C,E1,08,1B,60,0E,BA,82,95,1F,B4,30,63,11,4E,80,82,94,5C,41,73,AA,80,68,E8,DF,B3,2F,27,85,6A,85,8E,F1,93,4D,6C,B4,89,50,A1,86,26,A2,8E,03,7B,C2,A3,44,BA,3A,7E,47,C8,28,51,81,35,9B,02,0B,F5,E5,14,33,E1,CC,26,36,6E,42,76,70,C5,48,89,6B,33,3F,AF,55,8C,48,BF,22,AB,92,61,1D,22,15,03,AD,30,56,58,5E,4B,7B,98,88,20,F9,24,D9,95,53,79,09,2F,99,AF,D0,31,F2,F4,26,3B,6F,48,4D,8C,53,80,90,7A,DE,62,7D,16,5E,E8,B7,3C,ED,46,14,3E,04,DC,CC,36,67,AE,DC,DD,EF,4B,81,ED,5D,E5,50,FC,C1,1F,EB,94,51,9F,54,41,2D,36,57,19,81,FA,76,02,3A,DD,F4,69,DA,B8,4D,53,6D,F9,D9,89,6D,1A,19,69,5D,33,12,9F,6A,4C,4F,61,FA,6C,09,6B,F8,83,10,56,8D,B1,BB,6F,7C,F0,C6,0E,86,7B,88,03,11,F6,94,F0,74,CB,27,69,E0,47,B8,49,71,78,44,69,76,FA,63,AC,F9,4A,15,3C,75,E4,07,66,1B,46,98,E6,B3,1F,5A,5A,DB,3D,D0,B1,E5,D8,54,0D,F0,1E,88,8B,EC,1B,C5,E1,B5,E6,15,5A,DA,6C,93,6F,76,95,C4,DB,6F,B0,61,41,FF,2C,F2,F3,38,8F,00,3C,37,20,68,4A,EF,72,8B,B6,13,B4,C2,A7,67,6F,5E,F7,08,C2,58,9C,53,E3,2A,72,08,18,BD,AD,5E,9C,6D,5E,CE,0A,78,5B,BF,6B,AE,AA,18,35,01,65,EE,34,8F,C2,3D,7C,2A,38,C2,C7,18,EA,E9,5D,22,BC,40,A1,42,34,5A,42,8E,4B,9B,29,05,B2,0C,08,A7,5F,1A,D0,40,55,00,9F,10,8C,32,5D,67,2C,A5,35,BD,91,4B,4B,0E,7D,9B,02,6C,70,7C,DD,CC,AE,F5,DA,B9,27,B4,CF,80,81,3A,08,A2,EF,2C,DF,17,E4,AE,EF,29,8E,40,84,D6,B0,EE,92,16,2E,2A,E6,01,95,03,10,53,3E,39,81,D9,BE,C6,58,A3,1A,5B,85,B9,31,A9,72,60,03,93,E5,2C,72,1D,94,02,BA,8F,4C,1E,99,AC,52,D4,34,84,03,4F,31,CA,83,CC,48,58,98,2D,83,B3,06,F1,B3,4C,27,2E,5E,8D,CE,85,0D,7B,38,EE,0E,5F,87,AA,60,B8,52,0B,2B,5E,97,04,51,A0,8D,C9,C7,2C,65,5F,9F,1C,27,12,31,A0,48,72,9E,37,3A,9A,2D,4B,EC,AC,00,49,DA,3B,8F,D5,68,AD,0D,9A,6F,F0,30,87,4B,C9,93,4C,B6,45,7F,18,38,DD,F2,55,7F,94,2F,DA,4B,A9,CA,AD,AD,B6,3C,7D,70,02,99,26,1F,FF,E1,36,9D,BD,D6,D4,E8,9C,C4,99,36,11,D0,2F,C1,22,08,C5,F3,95,DA,81,5E,3E,87,3F,EE,37,AA,74,47,36,A8,7D,AA,57,5E,49,44,D2,0C,AD,20,9D,9D,0D,E2,A2,94,F9,9E,3E,90,C2,AD,7B,22,FF,82,6F,19,A0,5D,8E,10,D8,89,FC,EA,F3,1F,30,33,A3,B4,8B,85,F1,F5,FA,73,35,5C,7F,28,F2,0B,FD,19,75,31,66,A4,6B,C9,CC,3B,C2,AE,56,E6,48,A5,71,C1,94,1C,71,E4,C1,22,C3,4E,0A,9D,60,C8,BB,94,90,9D,15,E6,26,93,4C,62,EE,AD,A1,F4,1B,45,87,8D,9F,B1,BB,9A,E1,B8,74,F1,DD,E9,06,37,3C,30,7C,DC,18,0B,FA,3A,B6,AF,5A,80,A1,7D,D6,8C,A5,97,01,51,51,CC,80,5C,0E,6A,97,1E,5B,7F,4A,94,6B,37,6E,55,FA,58,2B,76,79,8D,AE,37,71,22,87,DB,0C,41,E0,F7,98,24,1E,84,9D,99,4A,A7,FC,29,D8,28,DA,8C,74,A7,30,18,FC,CE,4F,CB,56,97,5B,5E,5D,C5,49,66,1E,CA,BC,1D,F5,84,2F,42,D1,E7,53,18,C7,D7,A1,67,C1,A2,70,88,80,99,8A,40,BC,57,F7,D2,F4,6C,77,1D,9F,11,99,E3,FD,FE,50,4E,49,DD,8F,7B,3E,E7,C0,32,AA,B5,31,23,AB,3E,D2,E3,5E,EA,E0,DB,84,3F,53,DA,42,3B,37,92,23,64,D8,9A,B3,EC,7B,C7,C0,7B,A6,F9,17,35,80,C1,EC,03,74,E3,4E,30,12,F3,C5,FF,03,E1,96,5C,7C,C1,B7,FE,90,AC,E7,D9,7C,18,F5,90,0E,D8,8F,19,F1,FE,EA,34,8E,DB,52,F6,31,64,07,9D,16,D9,89,F1,A5,C5,94,C4,76,47,8E,13,89,D9,C2,5A,D6,ED,B3,7D,9B,BE,A9,A3,8E,80,DC,75,B7,A7,F3,13,F0,D2,6A,08,12,A5,D2,9A,71,22,18,81,24,C6,AD,23,7C,10,F1,7D,1D,7A,24,95,CD,E4,B9,1D,64,95,44,14,92,DC,E2,CD,D5,23,95,48,51,B7,CD,52,62,7E,B3,7D,C4,CD,B3,C2,42,87,A7,5F,BF,AD,05,92,06,AD,04,28,90,46,13,5B,5C,28,6F,00,2B,A7,0E,39,E2,AB,75,4E,60,5B,71,5B,44,8A,15,34,33,2A,57,E0,4F,AE,F5,04,04,85,0F,01,71,CF,8D,3E,62,BB,6D,E8,35,90,0A,45,63,69,42,A7,9A,83,79,B2,73,C3,0C,AC,2B,5B,8F,E9,5C,DC,EB,4B,E4,D9,10,36,F6,A6,B5,E5,BC,9C,00,92,B7,31,E8,69,D5,3B,46,3E,FE,74,4F,59,6A,8E,DF,36,AA,B3,E3,26,FD,D6,C6,D2,B6,D0,C5,FE,4B,F3,F6,E0,CB,8C,A4,26,09,F0,63,FE,6F,E8,8D,12,6D,10,C3,C0,A7,2C,1E,1E,AE,71,7B,60,7C,37,95,62,92,40,21,6D,31,15,AF,9F,54,92,D6,2D,3E,F9,F2,0C,C1,70,06,21,8F,54,96,DE,7F,92,F9,5A,23,B3,0C,12,31,3A,B6,DF,5C,8E,4D,70,37,6B,86,26,A1,8E,21,9B,14,64,53,AC,CF,C7,4F,2B,AE,AA,A0,BC,12,BD,3E,E0,98,B7,52,6C,15,E9,04,E3,97,06,25,A3,57,19,80,2C,F5,C3,05,3E,78,2A,D3,2F,DD,3A,EF,3C,58,1B,71,A7,CF,8E,E2,17,33,BE,1F,11,5C,8E,CB,73,ED,D5,05,9F,3D,A4,E1,E8,64,04,1E,11,FA,61,D8,CE,F6,62,37,81,AC,B2,24,C5,61,C8,89,F6,1D,61,14,82,F2,79,D4,69,B2,89,BC,E1,D9,49,28,10,8F,78,03,F6,78,7D,F4,09,97,4F,BA,28,18,3C,FF,5F,7B,83,D1,71,C6,D3,78,66,39,D7,B4,B9,82,D4,8B,0D,09,2F,BC,22,32,72,DA,40,8D,B6,F9,54,AF,94,AD,E5,EE,41,79,3E,9E,40,9E,1A,6F,83,59,2E,FE,0A,0E,9B,DE,7A,42,4A,25,78,17,F0,DD,FE,B2,F0,BC,24,AD,77,8D,66,F9,65,58,92,92,9A,AA,92,28,22,5E,D1,C1,9B,5A,3C,59,08,D6,80,1C,61,6F,11,4B,32,88,9F,6E,C8,57,D2,F0,8A,EA,5D,79,68,EC,61,2B,A2,DB,09,0F,7D,7E,1C,C8,26,8A,80,0C,18,36,95,30,26,83,AE,87,BA,2E,D3,08,0F,33,A8,76,0A,BE,2A,57,D6,45,01,D4,37,94,2B,20,4C,8F,50,11,E9,48,50,B9,59,37,AD,B7,13,E7,4E,48,4E,B0,84,2B,2F,82,E9,BF,FA,AE,19,A5,F1,FE,50,B0,4E,8B,C2,3C,80,F7,8D,82,A6,F3,2A,9F,76,B5,3E,3C,A7,B4,AE,50,CA,1E,69,43,D4,0B,A6,9C,56,7E,25,F4,60,C5,97,4A,4A,77,77,BB,B3,D2,3A,04,C1,AA,B7,B1,97,54,B2,EB,76,DC,AA,F2,4D,19,BA,06,57,7E,38,AF,96,A8,C2,A0,5D,EB,02,14,43,A7,E5,3E,A1,96,33,50,E2,6C,B8,7A,10,73,48,47,7D,74,19,0D,15,C4,88,B4,00,06,4E,56,F6,8F,22,B4,B3,D7,75,50,72,F3,C7,63,4E,84,1E,F2,73,E4,FF,9A,FC,CF,13,C5,D3,3C,7B,87,0E,3E,0E,2A,B3,C6,03,B8,20,CE,B8,42,D2,6D,A3,E1,74,14,14,1B,80,0C,CA,3D,40,E9,33,E7,C6,E6,C6,DF,20,12,60,A3,32,F0,60,60,0B,F3,5A,81,2F,B8,2F,C4,74,42,48,D3,6E,01,5E,AE,73,E0,AF,50,80,7D,35,DF,7E,8F,10,32,6F,BF,4A,9C,99,32,81,24,3E,78,A8,42,F2,CD,24,EE,49,78,9D,4F,13,AF,CB,CB,75,F1,0E,56,74,A8,6B,2E,80,92,C4,FE,65,B2,84,6F,B3,B5,14,C6,D6,62,8C,1B,FD,4D,1C,D1,48,FC,9C,99,4B,15,14,B7,F8,A2,2C,5A,3E,1B,06,7B,C7,9A,EA,30,A8,BB,F0,3A,DE,57,6A,F4,4D,7F,65,5D,D9,A6,A7,2B,BD,F1,96,DD,88,33,4B,11,D3,AB,05,31,AD,90,2E,97,C0,C9,F8,0E,D3,C8,78,5C,89,5A,7B,A0,46,17,21,EE,BD,AB,34,1C,9E,95,7D,7A,FA,29,24,99,10,EB,B6,A9,0C,C0,B0,26,4B,29,BE,37,56,4C,76,F7,0B,ED,B8,C2,3A,5C,88,4C,16,BB,0D,9B,70,FD,8B,2E,F9,D2,79,60,2A,1D,09,BC,2A,B4,A0,3B,39,55,8D,C8,71,4B,24,BA,07,B7,96,E8,C8,2F,BB,E6,BD,E4,43,CC,29,7B,A2,81,44,25,21,4C,A5,E7,F5,07,2C,66,49,24,A7,46,83,F9,16,3D,7A,83,DA,52,A9,B4,FC,93,30,42,B9,76,B9,15,16,BE,A6,96,02,23,63,BC,8A,78,0B,95,3D,F3,BE,3C,86,4F,29,69,B0,7F,B9,50,A1,4A,E6,2A,7D,7E,ED,5C,AE,DE,2B,CC,90,A2,1D,F5,DF,52,BE,5F,BA,B7,69,FD,E0,19,7F,5D,2E,59,00,D7,38,DE,4A,EC,2A,19,A5,09,12,BC,B9,D2,A2,E4,0F,E8,8F,E1,03,86,98,05,51,83,0F,99,99,43,44,61,F9,43,19,6B,67,91,39,50,E6,29,D5,03,DA,D5,6A,73,8D,31,BA,B8,A5,45,7F,0A,77,8B,33,0B,F0,ED,FC,CB,1D,19,66,92,45,A5,9D,7E,FE,52,EF,0B,DA,78,0E,DE,05,A5,C6,D8,E8,38,8E,AA,49,72,3B,8A,34,33,B6,C0,F9,DA,3F,F8,BE,41,47,08,9F,F2,F9,7F,67,5B,72,6B,76,92,92,B0,76,9D,D5,B1,A9,10,1B,10,9A,E8,20,93,A6,E5,A7,44,EE,E5,31,A1,6C,07,8D,B8,2F,F6,AA,AE,A9,3C,C9,9D,8B,2B,98,2F,C4,71,8D,B2,FE,59,34,7D,E4,8B,A5,8C,9E,6C,C3,D0,B7,21,C2,F1,54,B2,F4,62,2C,8F,68,29,DB,9B,B1,75,8B,BA,87,DE,8A,29,D0,4C,59,5F,1E,AC,D7,73,6B,CB,69,9C,DC,91,0B,A0,03,EC,FD,7A,AB,89,89,65,93,C5,BB,2E,DF,42,E4,5A,C0,A1,43,A8,16,76,B5,73,0D,2D,7C,41,AA,13,6B,EF,E7,3E,6F,94,B3,33,0B,99,B3,5E,61,62,CD,F7,95,A9,0A,97,C4,19,32,5F,53,E4,5D,31,43,86,75,EE,CF,73,6A,FF,C8,4E,49,B3,A7,E4,DF,E2,23,9A,B6,92,6B,C0,B4,0A,3A,52,2F,F3,75,CA,EF,A8,19,B6,96,EB,DC,88,BC,F4,60,22,4A,FD,1A,BD,9C,DD,DB,EA,58,F6,CC,92,46,6F,FB,C6,93,B9,0E,07,29,0B,EF,4A,5B,CE,A1,BE,39,B3,DD,B3,9F,42,A2,22,BA,55,15,78,AA,B5,6A,AE,56,F4,5D,C1,BB,39,45,8A,25,06,E6,9F,BA,A0,2C,6D,90,C6,29,E2,11,A9,7E,23,E9,2D,AC,74,AB,AD,66,62,4C,45,47,6F,52,53,16,FD,41,31,0E,7C,7E,5C,09,AD,E6,9D,7D,C2,EF,E0,48,F7,EA,6F,E2,A0,AA,EF,13,6D,A0,23,8A,A7,14,12,55,01,96,C0,02,EA,4E,74,C4,49,63,9E,CE,90,DC,C7,0D,3A,27,6E,FF,89,53,F6,1C,03,A8,88,E1,09,85,3F,87,95,63,2D,B5,D3,3C,08,D9,9E,29,E2,88,4B,E5,0E,2A,8B,5E,D5,DA,CA,C2,D3,82,E5,AA,F7,46,89,D2,6C,E4,8C,51,40,47,24,1F,37,F5,45,BB,B3,DA,5F,4A,AF,F7,0E,D9,88,4B,C8,EA,54,CD,21,62,65,BF,EF,20,76,6C,CE,80,49,51,02,06,5F,F3,85,37,C1,0B,AA,C2,FB,74,A9,B9,00,D2,0A,01,67,51,AE,2E,61,33,4C,AF,58,6F,4E,97,61,5E,16,7D,41,10,A2,B0,23,DC,31,21,A8,B8,46,3E,0C,2D,0B,CC,A6,9F,84,3A,EE,D0,66,D0,AD,89,8A,1E,0B,22,AA,4F,61,B4,39,F0,D4,D0,BB,82,AB,0C,CA,01,BF,2D,5D,FC,25,0A,C5,F6,D9,C3,95,C2,BB,83,68,9A,2B,E1,9B,83,15,88,3D,11,21,26,92,8D,72,FD,30,7D,E0,B8,AB,49,ED,0E,17,16,AD,0E,3A,C2,0A,94,D5,37,A9,7F,4A,A1,55,15,E6,7D,97,11,F2,F7,FD,B6,98,8C,B8,3C,C8,77,3E,C2,BA,C2,85,B7,8A,34,56,FF,2C,22,E5,74,DC,5F,59,01,52,B6,EC,E7,C3,D1,E5,6A,46,2A,2F,EE,C8,3D,30,15,4C,DC,E7,1D,EC,49,97,C3,08,23,01,DD,DB,48,FA,B8,21,D9,B5,86,A1,04,DF,2D,A1,D4,D5,4C,29,EE,DC,AD,6C,5A,A1,48,31,F8,8C,38,5C,0D,6E,1E,3C,33,53,8D,D9,56,0A,CA,E0,AA,B8,E5,5A,38,3E,5E,60,ED,88,7F,A9,78,38,FD,22,FD,84,13,FB,1C,AB,45,B9,6F,A8,DE,96,6E,24,BE,C4,E7,33,DF,FC,B5,24,67,1F,4A,1B,A2,31,3C,A3,03,2E,B6,4B,1B,5B,9F,17,B6,4D,32,97,5D,07,81,8B,ED,C2,AC,48,F1,C9,A7,7D,BB,EB,33,61,88,97,5C,8F,AA,6A,85,FC,7F,33,54,6B,8E,57,A0,CF,C1,D0,3E,4D,2F,34,41,90,A9,DA,06,14,F3,81,30,AA,1E,7C,0A,A0,70,75,F8,C8,66,E5,49,FA,81,59,CC,1B,67,21,FF,8A,FC,B3,06,88,95,BB,B1,FD,F3,C3,36,4D,3C,34,50,D0,E1,01,3C,E1,39,0D,9F,AA,33,C5,C3,36,C8,3C,A4,46,5B,24,45,14,EE,5D,DB,8A,B2,47,F4,47,1D,69,AE,0E,A7,1A,34,66,DC,A6,6E,FE,7A,4F,14,82,BD,61,69,51,E9,31,C0,D2,3A,19,AC,8F,9A,0A,B4,A2,52,DE,88,39,9C,20,73,F4,5C,5D,5F,BB,B0,65,CB,C5,01,BB,98,4D,1A,11,4F,43,66,9D,E9,87,6F,8F,34,36,23,75,98,9B,86,10,02,F1,B8,38,37,66,1A,BE,CC,B1,D3,E8,43,AC,C1,C4,A5,53,9E,63,4F,01,30,A9,A2,C8,1E,50,B2,BD,A1,27,15,50,E4,13,96,A5,62,C9,CD,C2,A8,30,4B,DE,D5,5C,BA,DA,03,C3,E8,31,6B,EA,EC,B3,4A,44,BE,05,DF,38,EC,9C,41,E6,4E,62,32,E0,23,0C,C2,44,42,41,7F,1F,86,22,D7,6C,E2,D0,51,E7,5A,FE,74,E0,B2,73,A9,92,8F,89,7D,8B,F1,C6,97,3D,C1,90,C9,63,2C,4B,5C,9C,87,70,A4,84,20,7F,B1,09,CE,3C,A0,E0,D0,18,A1,5B,97,F1,4F,E0,5F,7D,BA,EC,E6,C4,3B,7B,E6,BC,0E,86,E8,6F,72,E5,C9,86,0A,02,8B,35,DD,3B,A8,F5,8D,51,4F,84,41,A1,3F,76,26,AB,CB,C1,FA,13,74,CF,4C,20,D8,86,58,B9,F6,1A,9A,BE,B8,F6,B1,C9,88,7C,AE,C8,BE,5B,3E,14,66,6A,4D,27,D5,A5,21,19,CF,A2,8E,C5,37,B7,2B,1D,AA,A2,44,C9,9E,67,56,F5,E2,72,43,4E,69,D5,30,EB,8E,A4,DD,D1,F4,5D,03,58,F8,87,35,1C,1A,59,54,4E,8F,94,BE,6E,63,82,82,65,C8,BB,39,08,45,40,B6,DB,90,11,BB,2A,92,34,FF,32,AB,6F,24,6E,A8,81,47,66,24,A2,5D,65,A9,28,9B,B0,A0,AC,81,7C,1A,F5,DC,39,CB,A3,40,51,A3,A9,06,8B,36,4E,3A,35,E0,DD,30,78,41,98,83,D5,3B,3C,12,A9,B2,F9,0A,09,EC,F3,B0,EE,0D,7E,1E,34,F0,83,AF,C2,CF,F7,18,F0,EA,72,73,20,3F,81,9F,E3,DE,02,57,62,18,C4,98,FC,7F,FB,19,15,03,96,DD,0F,90,51,BE,76,B8,09,5E,18,71,3C,C4,0F,81,82,0B,80,2D,A3,41,20,EA,D4,09,96,E2,73,E0,39,A0,12,E5,57,7B,28,0F,28,5F,EB,9C,E0,AF,93,85,3F,68,D1,55,24,A1,5F,57,5B,AE,F8,4C,71,4C,DD,A4,E9,55,35,DC,F4,A3,0C,7C,FE,77,A4,5C,38,ED,40,7B,B1,43,F8,70,33,6D,F9,84,F1,48,7E,16,BC,BC,50,F2,3D,65,7D,34,4B,0C,A1,7E,08,25,41,5C,0E,3E,B7,85,21,B1,08,9C,9A,ED,F7,34,C6,A8,05,0A,B2,78,98,50,28,44,69,91,2B,1E,AD,AE,F9,53,98,E6,1A,E0,2C,09,8B,B7,C8,AC,1B,A2,12,A0,21,64,CD,6D,79,FB,D3,5F,03,2E,66,30,B2,93,AE,65,72,92,9C,57,9C,2F,D1,D6,77,B1,12,82,55,C2,7C,C9,7B,60,0D,65,7A,10,A2,36,84,64,1F,98,2A,60,EF,FA,F9,E2,92,10,25,FA,D3,31,C4,C4,78,19,FC,A7,F4,78,DE,88,36,C8,0E,32,5F,EA,94,4F,E0,1C,31,DD,6A,ED,CB,62,15,87,75,BE,11,38,E4,09,E0,40,93,32,28,C8,B8,E4,BF,10,50,4D,18,99,64,FE,CF,70,12,81,F0,C5,30,0C,E9,FA,33,3C,7A,6A,40,3B,70,F7,2E,E9,00,AF,4A,B6,E2,2E,90,08,C1,B1,77,2A,F7,93,DE,C8,EB,69,11,4B,D4,79,0E,99,83,E2,00,95,37,C2,EB,98,C6,18,3B,1E,F0,02,3F,E9,43,72,A4,3A,D6,AC,EB,DF,60,A4,B6,05,24,1B,0B,F1,E4,37,2B,91,BD,0B,33,0E,20,A6,FE,4A,29,5F,53,57,FC,2E,ED,7E,9D,D2,80,EC,DB,DB,70,2D,38,B4,66,8F,AE,39,19,11,27,B3,FB,55,C5,5E,97,30,B9,D2,3E,89,4F,09,08,9B,D0,9F,94,C8,52,E6,9A,6F,BB,F4,6F,7E,65,38,2A,A8,CE,13,FD,89,D8,91,7A,02,13,F1,35,F5,3C,D3,B6,AA,AB,16,43,49,5E,E4,3C,09,1D,BC,2F,48,86,8B,20,E5,CE,19,53,0D,6B,D0,B9,0A,FC,37,8E,BD,98,1F,8A,2B,A9,46,7E,D3,43,48,31,DA,C1,BA,4A,6E,4E,D1,BA,E3,1D,EA,21,F8,9F,C4,12,F8,F7,89,B9,E8,32,3B,8F,C7,1E,0F,00,F0,72,35,9A,19,48,0C,78,79,70,58,F3,F7,F0,74,D9,3E,6B,3B,13,26,5C,1F,69,B5,5A,35,0E,30,FF,F0,14,64,6A,46,76,E1,FF,C2,4E,4A,38,82,61,FA,83,FE,7B,94,1F,28,83,36,47,3F,E7,C6,CC,AD,26,7B,50,1E,4F,EE,9D,79,BA,7F,94,A7,09,BF,6F,CD,53,0C,CF,CC,0E,80,D5,BF,0B,F0,65,25,9C,3D,17,81,E8,37,79,22,B0,EA,5F,71,88,ED,DA,EB,D4,E0,54,D7,4F,7D,33,89,E9,BE,74,30,D2,46,03,CF,6D,1D,6B,3D,D9,F0,CC,0A,8B,B0,EC,13,05,DB,4A,5D,F8,DA,AA,EB,B9,A7,A4,32,3F,FF,98,6D,9D,4E,C4,5B,31,C8,16,F8,D5,1D,42,85,60,83,09,B6,9D,80,BA,E1,6D,E6,54,29,C3,1A,DB,7A,38,E3,3D,F4,56,82,E7,D3,CD,6F,9F,3A,B5,16,E5,18,DA,C7,97,F0,B8,47,28,54,5F,67,AC,56,BB,45,86,B8,56,96,C9,FC,6E,C2,9A,8E,31,A6,57,6D,DC,21,8E,72,4D,4A,E3,91,A8,50,C6,8D,13,2F,9C,F9,7C,B0,27,9C,99,B6,C5,F5,F1,90,56,CD,AE,2C,7C,96,78,E8,24,C6,A9,5D,A8,21,EF,44,12,D2,51,1F,B1,E3,E6,50,A1,96,38,4C,3A,05,59,04,11,E9,AF,BF,EC,41,2A,B8,18,48,35,18,A9,B9,AB,69,E4,6D,AF,C3,7C,E7,E8,82,3A,94,AF,83,56,01,EA,E2,13,32,C8,AD,86,02,03,54,3D,0E,D2,07,24,07,2A,C9,26,CA,4E,BE,84,D5,2C,E0,05,8C,35,D9,7D,37,70,3A,D0,AB,99,9E,61,C9,15,3E,7B,1B,28,F7,08,F8,99,05,9D,6F,4E,AF,D9,AD,C0,AC,AC,A4,0C,64,B8,73,89,2E,EC,5D,70,8A,99,47,47,96,40,AA,E3,11,B8,E3,69,F4,9A,41,92,3C,F0,59,84,D6,08,39,30,49,36,38,01,46,60,75,99,F2,08,55,1F,FB,96,97,26,37,AE,D7,0C,4C,10,4C,97,D4,7F,78,E7,C3,97,67,01,3C,1B,DF,43,10,9E,0D,65,EB,12,D3,C9,15,03,8A,6C,F9,E4,B0,C0,D8,72,73,59,A6,7B,C8,FA,C4,39,A5,6B,F7,BB,F4,D0,CC,F1,9F,36,AC,58,01,0C,26,80,85,4B,64,51,0A,8A,ED,19,36,E4,24,66,EA,00,7D,C3,EB,38,53,E9,A9,3E,D6,84,37,96,CA,78,1C,D9,0B,C0,24,E2,C6,3F,F1,5A,31,CD,E9,FB,A6,E8,15,CF,32,AD,03,95,4F,DD,35,FB,F2,CF,96,ED,A7,A4,F3,4A,E2,96,39,55,D1,F8,4E,76,73,F5,A1,CB,64,E2,59,81,3D,88,4D,50,75,A0,4B,45,CE,35,E8,C1,96,BB,6B,AD,E7,4E,3C,0A,42,22,89,2B,3A,30,C0,AD,B7,DA,E4,1A,49,D5,CE,EF,8C,37,90,3D,B8,CB,E2,4F,5E,46,65,DC,F3,B8,FC,25,CE,AA,5C,11,03,2A,41,0B,30,71,99,1B,74,72,7F,D5,6E,85,4F,2D,CC,1A,02,D2,09,B7,08,D6,6F,E3,66,4C,C9,43,C6,FA,1B,6B,B3,88,FF,8B,92,41,8D,83,43,47,83,B7,81,C3,94,13,DC,30,CA,7A,37,32,BD,4A,26,0D,62,D2,A8,9D,5D,07,62,A0,99,87,BF,1D,3D,B7,31,BC,0C,36,C5,56,38,8D,33,6D,EB,EF,29,AF,8B,4B,0A,6E,8B,96,7F,11,F5,31,5C,B4,A0,00,8B,E0,15,4B,0C,EA,DF,98,8B,14,DE,44,8E,05,28,DA,25,A2,E0,6E,AC,86,A0,03,4F,74,2A,8A,26,88,E0,0D,8A,DC,26,56,16,FD,A9,08,90,13,44,5E,9F,EA,24,98,AD,1B,30,F0,DD,91,C3,69,D5,F4,A9,0B,EC,E5,5D,8F,87,07,3D,09,89,51,42,49,CB,F8,DC,0D,03,18,EE,87,A7,97,F5,53,4B,4D,97,57,B0,7D,BE,3D,8C,04,27,A4,39,6E,F5,4C,07,E2,3B,8B,11,1F,54,7B,7B,A7,03,00,65,3A,B3,7A,7C,46,F4,FE,FA,F4,C5,B9,3A,B9,6E,51,E1,4B,28,6E,05,69,67,32,63,4E,E8,E9,4D,C3,9B,AC,1C,C3,1F,1E,1E,94,42,DD,13,7F,2E,7E,AC,79,91,A5,F3,69,D6,59,2D,2F,E1,AE,72,65,4C,8A,B2,47,D5,43,6D,4A,00,D7,56,D9,8C,25,85,8E,80,04,F4,46,3A,F3,9D,C0,8F,17,8D,0E,8A,04,91,AF,BA,A2,02,E8,D8,7D,95,1F,C6,93,84,B4,97,DD,50,90,82,60,22,7E,BB,77,7E,71,A7,1D,F8,3A,39,3B,61,74,54,71,92,A4,29,52,48,95,36,8D,45,E8,A3,F3,89,8C,35,3B,17,84,77,A4,F1,89,5F,4D,DF,4F,13,D5,8E,F4,3A,1D,41,F7,C2,A9,D9,24,59,73,2F,22,42,37,8A,ED,E4,DF,18,AC,92,EF,D7,90,EF,5F,9E,CE,F4,0B,E2,40,08,07,F6,91,B2,E9,A9,D3,A1,70,DC,8E,7F,13,D9,BB,29,B7,5D,33,BA,8B,D1,07,26,9A,89,71,AD,A2,F6,ED,98,E4,02,6A,F5,B7,86,B2,F5,19,13,F5,92,82,52,F8,8D,F6,F6,69,72,99,2F,FE,C4,AC,FD,F8,D6,F0,1C,F6,26,76,6C,DF,99,FF,8E,B8,5E,EA,3E,6A,F2,2A,27,44,CA,BE,18,13,4F,66,CA,92,BF,30,98,7D,51,C6,4D,D3,AA,8A,F4,4D,5B,8B,99,2C,27,71,6D,00,F0,E6,87,1A,F1,C1,01,A1,0F,63,E2,D0,FC,A8,7E,75,B3,5B,AF,36,CC,8F,22,B6,3A,E5,F4,CE,E2,18,4A,B4,1F,16,3C,88,AD,54,05,76,3B,88,B0,81,C4,8B,D2,1A,A8,AD,D9,AD,34,C4,09,45,CE,45,2A,D0,CE,29,AE,6A,05,63,61,24,35,AF,9C,F9,42,ED,CF,43,EB,7A,19,19,58,62,01,8D,98,D5,DF,DC,1B,AA,8C,F5,5A,E0,5F,8A,57,C5,FA,8E,E2,2A,6B,44,72,C7,B5,08,BF,56,E1,27,EA,78,B8,26,BE,B2,9B,FB,2E,88,4F,F7,6F,56,44,E8,9F,D8,BE,52,AC,90,76,A1,62,56,73,53,03,07,D8,DB,A9,11,12,67,C2,40,52,0B,AC,39,E1,4A,1F,4C,51,B1,FD,3B,0A,C5,FD,F6,3B,43,2C,74,49,21,81,8A,B1,FD,2E,95,4D,6B,70,80,94,43,B0,3B,5F,18,81,B5,76,9B,70,8A,DD,08,99,9A,62,83,75,1B,CE,D6,CD,D1,D4,A7,0A,BC,FA,BE,82,5E,42,37,4A,38,49,15,61,5C,DE,EA,7E,DF,4D,60,6C,4F,3C,A3,7F,68,5F,85,2B,B7,C3,14,87,9C,44,4C,82,55,B4,BB,0F,11,FC,28,24,0B,24,BB,78,CD,79,46,4A,D1,BF,70,74,F0,71,04,E6,91,2A,ED,F8,A1,15,29,16,08,53,6B,17,16,CE,AA,0E,05,67,34,49,9D,D0,87,78,70,36,DF,92,1B,33,5F,5D,5B,1D,29,53,D1,A3,F8,0C,DA,7D,BE,DC,CE,0E,E2,EF,AA,7E,6A,91,15,79,CF,31,F0,70,17,71,0F,BB,95,1B,13,84,BD,6A,92,52,AD,7A,94,0A,19,B5,1F,CC,91,6B,E2,5C,5D,BB,25,FA,C4,65,8E,F6,5E,BB,0F,18,66,BC,B7,42,3D,E0,31,6E,FC,3E,91,51,A9,F3,E4,77,8B,32,36,2E,27,19,AD,91,0F,34,6F,06,E0,E3,6F,DD,FD,FB,E4,AD,33,2F,A1,10,2E,12,C9,52,C2,85,E1,02,D4,6B,78,0C,09,9D,D9,98,B2,52,A3,32,F9,D0,4D,44,B1,A9,38,01,68,85,48,58,60,B2,C6,54,2B,9D,7D,94,78,B1,E1,CC,17,BD,F9,5F,D8,3B,8A,A9,B2,8E,18,68,C4,93,67,EF,F0,DF,D2,65,28,10,CD,AB,CC,B2,D2,7D,93,34,0A,C8,54,17,03,15,AB,1F,B9,A5,7C,6D,8C,E1,67,88,D5,F1,BB,60,13,3A,66,10,6F,70,26,04,DF,72,40,D0,28,1D,37,41,A7,45,77,52,CE,06,59,2A,20,F1,D3,05,96,A1,0A,AF,46,D0,82,2E,6D,BB,97,1E,6E,DA,27,4B,6B,2C,D3,F4,3A,6E,40,25,06,F9,78,30,29,96,E0,A5,3E,45,1B,9B,11,66,84,E0,6E,55,88,0B,3B,8D,AC,B1,22,DE,C9,A4,D2,64,2F,4E,D4,75,95,08,DE,54,1C,10,91,79,D2,13,F3,3D,45,8C,09,34,25,68,84,69,34,E5,DB,C0,5B,4C,7B,0E,F9,D1,F9,D7,4C,8C,BD,6C,44,02,87,38,40,5E,9D,17,7C,68,55,AB,29,90,38,95,73,52,DF,29,FB,DB,67,A3,0D,DC,D1,3E,DF,E2,B4,3B,36,07,95,04,4E,54,3D,DC,B9,80,A2,18,72,DB,69,47,F8,4A,54,2B,C2,1C,18,1F,C6,22,48,DC,E4,88,C0,8A,5E,4B,08,86,0A,54,FA,A3,FA,06,11,F5,3E,08,B7,7C,11,B5,C1,C9,0D,44,B8,78,95,9C,43,DB,B1,F9,4B,D0,DD,3B,B1,59,A7,9D,03,6C,D0,B8,11,83,18,38,48,92,23,46,9A,32,B9,A8,F0,10,DF,65,60,AF,DF,9E,92,96,48,8F,D0,0F,8E,5E,7D,A4,D7,58,2A,5B,EC,B1,6F,87,7E,EF,45,4E,F9,EF,49,B7,E9,7B,34,FE,3D,D0,45,2E,CF,9D,C1,46,80,BA,B7,77,36,64,3E,AD,D7,7B,AD,F1,C9,C3,91,77,E2,6F,1D,90,1B,B0,FA,53,B8,C5,DD,D7,54,AB,CC,7F,47,E0,33,46,1C,70,6E,F8,9E,FA,61,04,F4,A9,71,E3,7C,81,82,B5,4B,DD,62,AC,9B,88,AF,FE,08,84,22,D4,69,8A,2C,9B,15,E0,3C,7D,5F,32,EF,07,5E,EB,7E,74,89,53,6A,BA,F9,3F,F0,4E,05,86,1A,87,88,72,2D,5E,CB,CC,06,BE,D1,EE,70,F8,21,B1,A5,99,5F,44,99,C1,74,F4,53,60,8B,F9,AC,68,DF,5F,78,DD,C3,47,47,F1,75,E6,61,53,FD,5C,55,5C,07,A4,0E,F3,F0,8B,E6,2D,BC,4A,91,11,AC,25,F4,8D,6F,65,18,6D,95,04,66,B7,D5,45,B1,5E,DA,18,71,37,8E,4A,E6,51,9E,7E,62,37,A9,34,D9,E3,FC,56,13,BE,1D,DF,4E,84,13,0F,DB,A1,78,E1,AD,C3,84,3E,34,8F,2C,B6,C9,0F,30,CB,97,7A,3D,8A,D0,08,AC,5E,90,7D,B2,AB,0D,EF,6A,83,B8,C1,BF,BC,F2,2C,04,54,CA,01,C4,C3,52,A2,08,F0,2B,BA,C9,27,2A,54,7E,62,AD,68,3F,8C,D3,84,78,BC,1E,2A,01,B7,6D,24,B9,CC,F3,39,B9,04,6B,ED,62,EE,62,51,95,C0,7E,E5,14,A1,A5,5F,DC,F7,1C,A8,D1,24,E2,53,F6,DC,03,0E,19,44,B6,6E,1A,30,A2,B1,B5,1D,41,53,78,64,8F,5F,E9,57,C4,17,20,B1,37,25,FD,56,8E,78,FE,CC,01,E9,EF,20,B2,DC,DE,45,49,AB,24,17,73,3D,44,F8,51,DB,1D,94,59,D8,11,D8,48,A5,79,0F,D3,6D,FB,13,7C,4D,03,42,D1,F6,73,E1,76,00,8D,A5,B7,57,9A,7C,31,77,B0,7F,E4,72,2B,95,F1,27,48,E4,F5,EA,79,EF,DB,EB,1F,C8,7E,21,81,81,AD,C3,07,CF,50,03,12,4F,6B,90,CA,02,59,C9,40,2D,26,62,F5,85,B7,96,4C,B5,41,2D,54,5C,58,D7,B9,AF,8C,54,81,90,B5,54,05,1D,FF,CA,34,DD,5C,05,55,76,2F,FB,35,6C,1E,F8,6C,49,B3,A5,35,A6,F5,8C,23,FE,39,AD,78,E1,4B,FA,98,18,E7,77,22,0B,DF,A3,32,D5,A4,A2,F2,A9,50,45,72,EF,FD,96,30,06,6F,52,FB,2C,18,8C,00,49,C6,B7,8E,55,78,00,61,7E,72,FA,30,10,E4,AC,D4,43,79,ED,69,A8,E8,6C,A8,F0,0F,ED,7A,D9,B6,4D,F4,6D,4E,04,61,00,98,3A,A5,98,35,9F,82,D6,C0,5E,4F,E6,71,3F,23,BA,7B,4F,E7,8A,96,43,0B,A1,2D,D9,7A,64,A9,85,2A,2E,EA,47,5C,20,D4,41,71,F8,48,1D,BD,C8,E0,E4,F4,49,EC,5B,E8,96,AE,27,DE,BB,9F,22,FC,1F,83,92,DD,45,D9,87,4D,13,39,EF,38,B8,31,7E,17,CA,56,73,2E,A5,25,71,94,AE,17,AA,1C,FE,8E,E8,C3,CB,39,19,65,9B,DE,60,7D,18,A2,87,54,9A,01,36,51,2A,A5,26,01,A8,72,49,A7,AC,DB,52,4B,C1,39,11,BF,1B,92,AD,4E,85,80,B0,DA,0E,24,51,A7,09,D8,3C,46,6D,84,2C,D0,40,88,3E,27,1E,60,6F,55,6B,5E,E0,E2,93,0B,78,38,28,9C,D1,C5,A0,F1,1C,1F,8C,7D,2A,95,A4,66,C3,48,F8,D2,AA,1A,F2,7D,B7,CC,7F,C2,D3,C2,D4,B0,7D,75,05,BD,2A,D2,4C,D3,63,20,F6,31,FD,D1,B1,73,53,C5,41,F4,66,C2,D2,FE,26,63,EC,D9,7C,32,B5,F2,5E,BE,18,63,65,46,68,1E,04,07,18,95,26,3F,AC,F4,2C,4E,72,64,B1,08,00,21,51,23,B9,BC,29,AD,C8,96,62,6E,8D,E2,66,1B,DA,52,91,38,3F,87,65,2B,D1,9C,4E,A6,AE,3E,FD,75,EC,79,CB,42,8E,97,6D,D5,FC,45,CA,1B,80,5B,DF,66,9C,B5,7B,82,1A,09,27,B6,5D,10,9D,C2,BF,56,B5,35,8C,29,D2,C4,FB,F5,31,37,F5,0E,6F,10,01,36,38,DF,A9,9F,AB,4E,83,08,30,1E,29,3B,9B,95,A2,F7,90,BF,BC,F5,F5,69,BD,65,5B,13,39,BD,16,D2,C6,3E,3D,D9,4B,50,A6,8A,D3,CC,AB,7B,14,41,1E,53,DF,E3,28,45,E6,CE,98,42,40,25,6B,DC,D4,75,84,D6,5A,0A,6C,E7,0B,65,18,85,D1,A2,BD,B8,A6,0D,AC,25,8C,4C,FF,0F,9E,EC,8A,0E,98,51,A8,98,E7,17,A4,DE,7A,FF,78,D6,20,67,26,2F,B6,8A,96,0E,34,31,D9,6D,C1,31,75,2E,E6,5C,AF,4D,8A,58,3A,F5,5B,88,0F,47,AB,DB,1B,B8,5E,3E,0B,0F,3C,F8,47,85,EE,48,D9,9C,35,5B,D8,30,E0,86,17,35,DD,79,A3,B2,86,B6,DC,1F,16,CB,9F,47,B3,5A,9F,F3,7A,5A,90,EC,81,45,DA,69,EB,2E,7E,56,50,AB,5F,44,F6,82,91,7C,3F,83,3A,74,A9,8A,75,A6,46,A0,4F,63,88,E3,A0,42,C9,0A,C2,A4,95,CF,FE,04,E6,72,C1,0A,D7,8A,2B,C3,EF,E2,08,CC,99,74,38,B0,CD,A9,04,B9,17,CE,99,D0,C3,62,39,45,51,2E,BC,02,D8,1A,31,8B,71,E3,11,CB,C9,CD,46,CB,5A,A3,A9,74,A3,35,61,D0,70,FA,A2,9B,B9,BF,B0,D0,42,67,B1,B8,CC,2B,CA,63,E4,62,D9,00,78,8F,B7,04,CC,21,36,C6,5C,2A,A1,BA,E0,E7,B4,96,38,E1,E9,A6,26,FA,D8,C6,A2,E2,33,01,43,32,DE,D3,6C,7D,95,8A,0F,27,D6,FA,F5,98,46,D1,A3,C4,81,0C,BC,FC,3D,95,6C,71,A8,EF,76,CC,D7,BA,2F,93,6E,58,B7,89,AA,74,1F,BF,83,EE,A7,43,24,E7,2A,F9,AC,EC,D8,AD,E8,B5,50,48,9C,A8,D8,7B,5A,4F,08,69,5C,3A,68,E5,9D,C9,53,E8,53,94,BF,51,73,EC,E8,62,E3,D7,58,41,94,01,BA,37,8A,AD,C4,30,52,A7,4B,11,09,A7,3B,7C,06,F9,5E,DE,C2,4E,29,4A,82,F0,25,D0,7A,3E,AC,90,12,64,5A,8D,37,67,46,72,76,A6,48,8E,EF,AC,6F,AE,03,C8,6B,71,A5,D5,B1,F6,8D,50,43,DF,90,A8,A1,CD,A8,30,A8,6C,22,4A,4C,82,BE,BC,2C,15,BA,B3,70,E3,8A,03,6B,4F,86,FE,D0,31,A4,B8,70,D4,DB,4A,11,C2,6D,D6,F5,B8,9C,D5,46,88,90,47,68,17,55,5C,93,BB,2C,5F,55,9E,D2,50,EF,88,E5,00,1A,DA,94,BF,BA,46,F9,1B,63,6A,42,AF,76,8E,E5,28,BC,5D,E6,2E,23,5B,D3,F7,F9,12,D7,93,B1,55,5D,3F,7C,A9,2A,7F,52,94,DA,76,6F,E0,96,8E,D0,1D,A0,BE,03,11,D5,46,11,07,49,9C,2F,2A,99,AF,A0,CE,6E,E8,04,05,72,53,47,D4,35,26,84,52,56,44,D8,C9,A0,4B,80,4B,4A,B5,2A,D5,85,8A,7E,20,33,97,A9,E0,92,DB,64,4A,0B,10,13,02,5F,7B,5A,3E,F5,36,C6,D8,6A,E2,32,55,AF,A0,5E,4B,C3,BC,34,D0,22,82,F1,C2,57,20,99,00,F4,59,69,70,94,63,77,57,71,DC,38,B5,24,A6,D6,50,C0,FB,79,CB,51,AB,19,8B,7D,EE,72,31,EA,BF,11,AC,B6,36,A1,B5,75,08,14,8D,83,59,F4,1D,05,D5,4C,A0,7E,8F,A1,B4,B1,25,1E,7A,04,1E,C5,36,EF,B0,E0,FA,97,8E,8D,E8,CD,2F,A9,3A,90,D9,2C,24,9C,3E,AB,A8,5A,A9,77,26,6B,BB,5F,A0,F6,5A,CC,E1,1C,F2,62,9F,13,D0,25,D5,85,A2,E6,C0,17,77,80,04,4F,BF,70,17,AA,9A,B5,A7,80,0E,6A,54,6B,39,4F,C3,88,CC,03,DC,82,5E,0C,FD,7E,7B,54,D9,15,C8,38,7B,EF,DF,5E,1D,8C,48,5D,53,8D,58,95,36,D2,7A,A9,B6,40,33,D6,BC,A1,96,07,C3,21,3F,BA,BC,A6,45,6A,C0,61,1E,D1,4A,5E,41,F4,BB,91,69,BE,84,1F,D6,E8,C1,C3,0B,C8,D4,52,85,A7,DD,AB,F7,E9,0F,DF,CC,AE,57,0E,F8,0E,45,AB,3B,9B,F0,4D,78,27,97,6E,5F,F8,4E,CF,9D,33,BB,BF,3C,C8,87,AF,9B,17,22,16,FD,80,D8,8C,5D,24,4A,6F,1F,9D,16,3B,84,AD,A3,6F,1B,D0,40,EA,14,CE,E8,6C,13,D7,ED,68,EA,16,D8,2C,68,1E,5E,73,69,B5,74,D2,66,D8,80,D1,EF,77,9D,11,68,12,E2,9F,C0,07,30,61,6C,54,EF,90,6D,97,E2,42,4A,D2,E1,6F,9D,0A,E9,E4,14,48,28,51,75,8E,C1,38,9C,CA,5E,18,04,CF,DB,DA,F0,A5,66,9B,EA,81,0A,D3,58,82,91,EE,2D,99,B3,AE,30,D8,8D,1D,73,4B,38,FC,28,17,15,1E,FA,FA,8D,A6,9B,3A,38,5E,F7,64,C2,07,50,AA,76,0E,3E,1C,81,1C,33,DA,51,B8,92,7B,28,75,CD,D7,03,F4,73,46,AC,45,0E,87,16,36,FF,18,0D,A4,E3,42,AD,5D,8A,78,62,8B,25,62,5E,8B,19,74,7F,D1,63,C2,16,F9,37,16,10,E5,62,34,56,6B,19,E4,2C,21,19,E4,E7,B2,B2,19,39,15,60,EC,25,A9,E7,21,2B,B3,66,AC,90,99,A4,59,9C,02,41,5F,AD,92,70,32,4E,02,77,B2,45,18,7C,03,64,C0,BB,06,13,CE,B9,13,56,C7,FB,62,1D,D2,19,F8,9A,DA,27,B9,62,63,A6,7F,61,C3,7F,E2,26,1B,61,93,A6,95,7F,B1,C3,47,BD,6C,13,91,3E,B0,C3,9A,E8,8C,EC,10,92,EE,76,AB,B0,84,32,9E,B2,4E,3B,BD,68,4A,F0,F3,42,C6,2B,75,D2,25,2C,5A,96,0B,9A,4D,34,EE,2D,31,DF,35,1B,EC,F9,4D,31,E3,EC,9C,5C,1B,7F,8E,27,8E,1D,44,86,A0,11,97,26,35,E3,D3,6B,F4,A8,F8,EC,F2,EC,53,DF,02,EC,94,08,98,28,E4,87,4A,49,91,60,C1,E7,41,11,D5,07,53,02,C8,70,C3,E4,6F,5F,AF,C2,5A,D0,0F,CC,25,F3,3D,4C,9E,EA,EE,AD,6A,74,09,DB,71,E1,87,97,DE,82,2D,65,3E,63,B5,D7,FA,39,3C,A8,44,76,8C,35,E8,D4,4D,BC,0E,30,30,93,D9,08,B6,E9,C2,0F,3A,E4,72,43,F5,36,91,F2,82,B4,1A,FA,D0,E2,DC,7F,9D,0F,4F,E8,B8,8C,51,88,4C,B2,72,66,20,B8,50,70,4B,51,B0,CB,29,3C,82,6B,B6,90,68,12,B8,84,C6,59,CC,9A,87,78,06,5A,7C,C1,1E,26,9D,98,70,9A,ED,BF,54,B6,C8,E3,3D,13,A8,CB,B3,4B,63,7D,3E,AC,B5,BE,9F,9F,8B,64,E1,D5,BF,15,58,8F,43,7D,B2,E4,3B,F2,E9,F5,00,84,EC,5A,57,21,CE,17,A8,DC,61,CF,60,E9,B7,D7,B1,8B,37,09,03,47,4A,CE,B9,D0,02,83,17,49,35,A0,37,F9,7A,58,1E,C2,3C,BE,DA,1C,D5,34,06,47,7C,7B,95,39,DD,09,4D,B8,1C,1B,FE,5D,9D,05,64,B6,FA,C4,C9,5B,55,D9,9A,FC,A9,05,A4,38,43,E1,C4,73,22,20,CF,60,11,81,CF,66,AC,84,FC,7A,B0,71,21,91,48,2A,3F,D6,53,EA,E9,FD,56,A1,72,84,61,E8,77,66,FF,A7,EF,A8,A0,7A,23,C4,2E,77,24,6F,76,EF,BC,5F,6E,B6,84,77,F1,76,13,0D,70,90,16,AC,0F,61,E1,93,CE,48,64,B3,EF,7E,6F,4F,34,CD,9D,8E,AA,E2,36,A6,AF,26,4B,8C,28,5D,0A,00,0A,AE,03,DD,6E,77,72,1A,83,C6,FC,E1,B2,FE,51,C0,6A,7A,24,AC,A4,7D,6D,97,EC,0F,44,79,39,4D,50,1C,4C,08,1F,46,0C,3C,83,B5,9E,08,F7,60,A7,43,D9,7E,60,E8,A7,AC,29,F4,C3,A8,A0,C0,58,79,20,19,2D,5E,43,BB,EB,EB,19,08,F5,6D,B2,14,1A,16,41,9E,5E,19,22,4C,D3,8A,13,6B,B4,F9,FD,60,47,C9,C2,66,9B,98,D3,67,1D,72,C3,D6,6D,EE,65,DF,96,C4,CA,4F,D6,2B,E4,81,12,E8,AF,AB,7D,3E,C2,6A,B5,60,83,C1,B7,3D,88,5C,C8,11,5D,CA,41,8C,89,42,9F,3A,94,04,6A,59,BA,F2,95,FA,6C,42,8D,62,8D,EB,56,A1,FE,3C,8F,E4,53,2F,4A,BE,C2,9D,CA,D1,81,A2,FD,86,B5,21,F3,50,70,3E,2F,EE,10,E5,27,C9,59,32,38,06,40,8B,1F,F5,09,FE,58,7A,64,FA,64,17,D2,C0,FB,31,CD,52,73,72,52,C1,8A,B7,C2,26,2E,73,FE,6B,85,E4,5E,EB,13,5B,84,C9,43,51,EB,27,FE,0D,8F,8F,6F,2E,4E,83,22,7A,64,80,72,42,2D,E3,98,FD,CC,5C,40,FA,5F,4E,CC,66,03,9A,DB,49,37,1E,B4,F7,28,81,21,29,DD,45,B4,8C,4E,47,37,D8,C9,EF,65,8E,77,6D,DA,58,AC,31,F1,F9,27,09,F5,F4,D8,11,E9,E7,A7,E5,67,68,42,12,5F,5A,70,A4,D0,E0,85,11,85,D7,DB,00,66,E6,1A,56,BE,0E,FD,A1,65,F8,9B,9A,65,2E,15,E4,60,33,A1,93,11,F6,FC,AA,FB,78,B7,F0,C0,5F,31,2E,2D,B6,13,46,B9,EC,5B,4B,3A,74,F6,74,85,BC,E4,8A,F9,B7,5C,2A,56,5B,70,6B,88,78,DF,0F,91,8D,DD,32,69,F0,45,D3,B2,FF,95,1A,43,85,9A,DB,0B,32,A2,7B,FA,C2,0A,21,4E,8D,A0,29,03,30,C7,5E,A5,BC,07,0D,44,10,2A,5A,7D,1B,56,51,89,05,AA,8C,EF,D2,E9,BF,B7,AC,F6,F7,C8,3E,AE,D6,51,33,0D,48,7C,CB,9F,B1,7B,4D,1B,FC,1E,02,5C,90,A1,AD,BB,33,AC,17,DC,D7,97,4F,09,94,27,7C,70,6B,71,1C,2F,C0,A9,24,3C,67,F6,5D,35,73,62,38,C0,34,D3,33,72,F2,2C,77,6B,C6,27,98,1A,C3,5E,0F,A8,1C,7A,3B,DB,A6,C5,F9,50,54,B0,47,E5,5C,5C,12,92,EA,C7,BB,41,87,5B,CF,6A,72,0A,9A,90,D6,14,41,12,68,36,87,16,E8,7C,D8,9D,B0,83,41,8A,B4,1E,86,7A,C8,55,1B,35,76,DA,F9,69,19,16,8A,57,2A,7F,68,1E,2B,4C,7C,5D,2C,61,66,F3,9D,46,F3,9C,BA,C8,8F,77,C0,E9,EC,D8,B1,A7,FE,3A,50,54,E3,EF,01,A7,FD,4E,2E,2D,82,54,D4,AB,41,A0,19,A6,ED,5F,B4,FD,DA,F3,03,9D,9A,5E,42,75,F0,EF,A6,13,A0,16,B9,81,7C,AC,31,B6,19,46,07,D2,D6,02,98,B7,63,F9,EA,0A,74,07,0A,7F,3F,1D,24,ED,93,12,ED,5C,95,BF,17,6F,A0,78,96,4D,5D,63,AA,80,1D,05,28,CA,96,02,BC,99,9F,EF,A7,91,67,6A,03,12,FE,A0,E4,F1,0E,C1,F6,EC,81,A6,BC,3A,E5,EB,F3,0E,7E,14,0E,1D,59,C5,A6,61,6B,E8,2A,E3,30,94,6E,C4,B3,3E,A1,73,2F,CF,65,67,93,BE,D6,78,8C,05,9B,8E,2D,0B,93,41,38,2B,39,B1,36,34,DB,CD,C3,24,B2,54,F8,1C,03,C4,75,69,E9,1B,80,B4,DB,7C,56,29,D3,9B,4A,C6,61,EB,AB,73,B6,50,32,7A,AF,A7,A9,BC,48,00,34,83,87,07,46,0D,1C,34,63,36,C4,55,17,D1,33,1D,45,DB,84,3C,92,08,54,B4,15,C0,9C,C8,8F,03,4D,64,30,1B,51,58,44,DC,10,53,8B,E8,2F,BF,96,7C,DA,57,6B,8A,FA,EC,14,A8,8E,A5,E7,15,FF,EE,BF,DB,25,7F,DA,95,1E,B2,F4,50,21,58,9F,86,24,5E,0F,54,11,15,9C,F8,B2,06,8E,3C,0C,05,05,97,51,75,61,57,4D,BB,1A,36,98,F0,BB,7B,B6,BE,A3,20,EE,02,20,26,3A,FE,65,E0,8D,11,8F,61,6A,B4,D3,CC,46,47,C0,53,92,11,40,C3,F6,53,6D,C8,D6,E5,C2,88,95,4A,F1,47,AF,BE,43,41,57,E2,FD,E1,71,4E,B8,F9,6B,C8,7D,0B,C1,2F,46,55,6D,A1,C1,84,E6,13,91,E4,E8,01,2D,25,F8,3C,15,B4,53,88,8D,11,ED,F9,A7,A8,9F,7C,80,C5,A3,F3,9C,AD,41,8E,28,26,1E,BB,30,6A,6B,BB,57,C9,58,5C,01,75,E2,26,79,62,70,C2,63,3A,0D,54,8B,78,9E,1E,2B,A5,C7,1B,14,2A,2E,06,EB,EE,C3,AF,AE,2D,25,E8,ED,73,46,25,D3,6C,95,53,B5,A1,03,BD,7D,B0,AA,2F,DA,C4,F7,EB,31,78,0A,44,BB,CC,BC,44,52,B4,6F,A2,A6,D3,2B,CD,02,5E,0D,2B,FD,E6,AF,32,C8,55,81,CE,7C,61,EC,A6,33,5F,0D,0C,7C,C4,7D,A4,4F,D1,DE,A0,14,6F,B5,7A,34,8C,95,15,7C,A8,57,36,7D,24,29,71,5F,4B,74,FB,46,61,E7,E0,20,9E,CE,A4,8B,97,44,45,C3,0F,31,A2,B8,B6,A4,65,9D,E7,DF,D3,B9,D2,9D,25,C5,01,2E,F4,8E,88,5A,42,DA,20,79,A2,A2,CC,53,1A,6B,91,1E,58,2A,9D,2C,57,14,31,B0,2E,D4,4E,5D,74,21,AE,7F,03,62,A1,85,FD,7A,78,0E,2C,2F,4E,CB,9D,B0,C3,12,99,A9,11,C3,52,2E,E9,EC,6A,49,06,6A,EA,51,15,87,EE,A8,FE,75,0D,C9,12,36,0C,79,04,15,17,7A,FC,51,6A,96,08,98,A5,27,CF,59,55,73,12,52,E7,36,6E,B2,38,20,F1,C5,2C,D6,16,E7,66,EF,84,8C,D0,71,AE,6D,91,79,27,3C,66,04,F5,9D,E8,7D,86,A5,98,93,64,E1,DA,28,60,42,E7,D1,84,92,EB,F0,E1,4F,37,05,58,BE,10,F3,AC,39,67,72,DC,F7,5B,9B,AE,05,FA,0F,01,07,69,72,BF,4F,30,3F,9E,0D,AB,FF,3A,D1,BE,E0,D7,57,DD,AB,AD,63,38,22,6A,91,E7,BF,F2,EF,68,79,97,3E,5F,46,9D,ED,25,59,AE,D8,27,17,AA,90,CD,DF,71,F3,80,9F,51,71,74,EE,01,51,4E,B7,B3,A2,99,7D,C4,66,91,7F,70,DC,DA,D3,EC,BE,D0,E6,09,EA,3E,89,26,29,B9,1C,0A,89,B2,31,08,47,6C,39,8A,93,EC,98,62,70,74,49,7E,08,00,85,14,C5,BA,45,88,FD,78,2A,7E,8D,D2,73,6B,D6,61,06,BB,15,D8,C6,AA,0A,69,3A,69,BC,7C,58,75,C8,F5,54,7A,3D,6F,DC,CD,05,F4,AB,E0,9C,0B,C0,F5,09,49,2C,9C,E5,B2,A4,0A,8A,8B,8C,1D,2B,F5,20,44,D9,F5,E0,4E,06,C5,BD,C3,C7,95,BF,BB,85,CA,2B,9E,8D,3E,34,2E,07,4F,3C,AD,84,F6,26,89,F2,BD,FE,91,63,67,2F,0C,C3,65,CC,4F,F5,16,CA,25,39,30,2A,3A,AA,73,00,F8,CD,17,33,91,D8,74,B3,B3,12,D8,A4,7D,24,0F,2C,FA,5A,16,4F,42,B3,97,F3,63,F3,F0,62,12,BF,34,20,C8,FE,C7,9E,67,11,DE,35,5E,FC,B2,BA,01,8E,78,47,04,70,34,09,81,F8,49,6B,35,7C,26,C4,69,0D,CB,8A,7B,37,FD,EE,E8,82,02,9D,6B,D0,03,10,BD,81,51,91,08,8A,73,B3,5B,91,30,13,54,ED,B4,02,DF,8D,23,A4,25,F4,45,BE,4A,74,99,7C,FF,26,2C,93,BE,D8,BA,68,C6,CF,FC,62,B6,04,16,E7,A2,7F,9D,67,2D,EC,D6,F5,87,A3,3B,33,A1,53,3A,21,8C,3F,7D,97,0D,CA,36,A3,86,33,D5,F5,86,CF,87,F8,03,E1,BD,C4,11,DF,51,8D,2C,4E,1C,9E,B9,09,38,A6,77,BB,B8,8F,3A,9A,7A,D6,DA,6D,A1,6F,22,03,8F,2D,5F,8F,BB,2F,E5,43,94,A9,AD,C1,F3,72,07,A4,CB,A6,66,85,5B,A2,2F,42,EA,CD,D2,1A,38,85,E7,74,46,E0,CF,7A,19,1F,A4,9F,04,C5,1F,EA,E7,4B,4D,94,48,D0,29,22,FF,8D,BA,2A,09,92,60,35,F9,8B,4D,36,FB,33,EC,54,29,8C,5B,AD,E1,3F,9E,E4,F0,AC,99,98,67,BB,4F,99,86,60,9B,5A,8A,3D,02,A7,6A,9B,C0,9D,2A,F4,24,7E,AC,7A,49,DD,9D,E4,1B,03,A0,7E,A2,41,59,4C,9A,CE,9D,0C,AA,89,C2,9A,86,40,84,45,EC,D9,D7,B2,20,01,2C,59,21,BA,10,79,6B,BF,34,B7,A1,5F,E7,F1,93,DF,22,7B,A4,B0,16,DD,0A,A5,C3,16,AF,CD,0A,6E,31,2E,9B,D3,2E,0D,5B,E2,F4,13,B2,23,A8,29,9D,E0,A9,20,45,18,5D,93,AC,A4,62,E6,50,1F,B2,F6,37,D8,0F,73,9F,C7,11,E0,73,E0,73,D7,05,51,33,67,08,26,2F,06,42,71,56,16,91,EF,AA,BB,A1,A1,51,25,41,20,87,A6,04,04,38,8C,07,39,2E,CF,52,EE,E0,EA,36,80,DE,2E,D9,F6,AC,CB,44,3D,62,FF,A4,3E,24,6E,0E,92,AC,CF,69,80,CC,76,29,11,CD,FA,FC,34,DE,B5,19,1A,83,C4,A2,8E,00,BE,C1,91,E0,3A,91,8A,00,06,C1,12,9D,77,47,18,92,77,A1,CF,40,FE,A6,36,1D,DB,0E,62,09,D3,32,F0,56,2C,53,F7,24,61,F5,35,2E,34,04,FA,A0,08,C9,E9,30,BB,AE,63,B2,55,BB,3F,4D,E8,E5,32,64,B1,86,FE,A7,76,41,AF,E0,35,D8,60,3A,3B,43,AB,60,0C,3D,D3,1E,B2,35,21,7A,7D,03,D4,AF,18,B4,62,6D,71,58,71,F5,C9,61,28,AA,D8,59,EC,C3,86,58,F6,B6,C2,BE,FD,64,98,76,3D,F4,92,32,84,21,11,21,6A,F2,CE,BD,BC,45,96,F2,DA,FC,CA,49,CC,C3,12,00,DF,3E,A8,F3,FE,7F,78,74,70,C2,DF,F7,37,FA,E7,A4,28,EF,6A,92,C5,B6,41,EC,F0,1A,FA,27,AD,81,B7,F7,28,D5,49,54,DE,97,E7,00,87,EF,39,29,26,F4,23,87,33,74,0E,07,42,DE,13,08,A7,12,AF,B0,30,A3,C8,E4,5A,5D,A4,F2,71,29,31,E9,EF,84,95,83,79,4D,68,1B,EB,65,CE,9B,F2,5B,E9,C9,7E,68,AE,9E,46,F0,D7,74,0E,84,04,A5,9E,78,BC,F2,1B,DE,9B,82,FD,55,D3,40,66,21,F8,00,79,76,7B,58,A7,D2,E4,2F,47,9B,75,59,22,9D,F4,30,F8,C8,30,4A,78,D7,D0,3F,88,7B,22,FF,75,91,8B,F0,E9,84,6E,19,39,B2,0B,58,1D,1D,D1,B6,35,BC,06,1C,54,3F,D5,B0,41,1C,6D,E2,96,72,23,99,1F,C8,B9,05,BE,0F,16,B3,EB,20,A8,7D,A0,F1,BF,62,07,52,BF,5D,87,45,31,5D,83,F0,2B,42,86,86,17,79,D9,75,CB,FB,4D,D3,FC,A7,E0,D8,10,35,D9,69,4B,CE,9A,86,A8,54,E9,53,82,F9,D7,C3,B5,35,0B,AE,C3,79,31,7F,73,54,3A,1B,A7,1E,4E,A6,27,4A,E6,58,A3,50,D0,DE,A4,C7,4C,BA,74,AD,28,AD,77,99,A2,20,4D,48,6B,A9,EA,B8,45,F7,12,B7,33,4E,63,35,E5,F5,7F,7E,11,38,3B,23,E2,1E,DF,CD,CA,16,C6,B2,6A,C8,30,C7,BF,5D,D4,73,39,B8,BE,CE,46,6A,FE,51,F8,76,DF,74,8A,C2,AD,C9,0C,A3,EA,CC,F8,E3,0F,9F,69,7F,EF,6D,A6,56,2D,C8,CA,45,BA,F4,02,0A,8C,C1,13,23,BE,70,CE,98,FC,E3,A9,1F,0A,83,D0,72,97,42,AD,54,2E,84,DB,01,3F,42,E1,87,C9,51,88,D2,28,5C,AB,74,09,20,B1,80,32,A5,F2,12,BC,28,EA,52,F1,B5,48,2B,60,B0,C4,C1,FB,A0,6D,42,77,CE,21,B2,1B,68,3C,08,DE,A0,67,B5,D4,28,6D,4F,8B,88,AF,E3,16,D8,9A,97,E8,23,92,DF,E9,5E,C8,01,80,66,1D,FE,4A,6B,FC,37,FC,56,7D,41,67,54,43,55,9F,E7,35,EB,2A,E3,2B,56,0A,5B,F9,D0,1D,FE,F7,04,59,56,CB,32,A8,12,0C,2E,2C,7A,1F,8F,96,E1,DF,36,67,CE,AD,B3,05,E5,C9,B8,0D,6C,EE,C9,86,70,53,D7,AE,4F,7B,D8,37,0D,71,03,09,58,72,54,FC,FF,6B,D5,C5,0F,B2,1C,8B,90,C1,A6,26,16,F4,1A,2A,A0,6C,DA,F5,55,1D,F2,F3,6B,DB,CA,94,C0,36,E7,70,5C,B6,94,D3,F4,0E,2D,3F,EA,4E,FA,3A,C6,45,A3,80,57,AC,E5,6D,75,86,96,86,05,5A,47,7C,D8,B2,22,E3,04,A5,88,E2,6B,0B,4A,BB,D8,BD,68,DE,75,44,47,FC,42,11,B2,A5,3D,D5,4E,C9,A4,C0,66,BB,9E,93,89,E2,BD,95,5A,FC,1F,02,A2,14,1C,75,FE,92,98,B1,AF,3A,B1,58,22,E9,28,E9,56,73,B3,7B,9C,4E,AA,3E,24,3E,26,6D,1E,4A,2A,AD,4C,4E,19,2C,1D,90,86,37,1C,7F,12,F7,3C,B4,2F,CD,C0,83,5D,D3,8E,C7,14,B1,4C,C0,4C,65,78,59,74,3A,01,45,3B,F2,86,17,2E,13,7C,DC,3D,70,70,E6,FB,3A,9A,25,57,A2,A0,6C,10,22,FE,C1,71,98,0E,DA,AE,8E,C6,B8,E4,6A,9D,A1,9F,F4,A3,B2,31,F9,B5,70,5F,03,4C,BF,EF,E5,7B,1A,A4,8E,3B,DC,6D,D0,25,51,EB,EB,44,D0,43,4D,1D,58,2C,7F,D2,19,35,55,90,71,88,EF,D2,5C,A4,5B,E3,C4,53,B9,09,B5,88,30,C0,02,42,B5,8E,33,8E,B5,23,3A,F1,8A,D7,99,B4,0F,44,6D,3F,9B,66,EC,5C,78,B9,3A,DB,11,9E,91,4A,D4,EA,93,13,E2,AB,C8,55,89,44,DA,B1,38,30,2E,97,33,20,44,4B,6D,34,E3,71,65,EC,D1,0F,33,9C,8E,F0,95,89,5C,63,A1,BF,11,62,D9,59,40,62,EF,86,52,D6,6C,2D,73,34,59,D4,67,45,41,7B,CF,5B,51,54,EE,E3,BF,BF,B7,4D,23,65,43,DC,DA,20,7E,BC,5F,1D,9D,77,DA,BF,74,D7,BF,08,76,EB,71,13,60,E2,BD,D3,32,E4,7F,C5,1C,92,B2,7A,DB,54,C0,A3,6D,52,4C,4C,88,0D,E8,1C,D7,8D,EA,84,82,9D,92,14,E9,03,AC,64,7D,7F,75,78,A3,74,D3,66,7D,F3,C0,63,87,90,AD,65,79,A3,9E,27,69,24,E4,44,44,D5,F2,D8,EF,15,33,EB,A9,A3,30,D2,1A,AD,16,A3,FC,D0,75,92,ED,14,6F,A0,59,ED,E2,2F,5F,B1,63,7C,8F,A9,D6,7B,A8,31,BB,DB,7F,F0,E9,8D,B2,94,7D,CE,96,C9,F0,82,C9,55,90,15,BD,78,0C,86,72,4A,D4,32,60,4B,4F,42,C6,DD,2C,8A,DF,8E,AE,68,6E,02,6A,5B,48,C9,A6,42,AF,4E,15,F8,B1,D8,EE,7C,0F,B7,E6,74,FD,E3,8C,20,16,04,F0,B6,7C,70,41,91,13,1B,47,E2,0A,63,86,27,1E,E7,56,2B,7F,D3,F3,F5,D5,FA,B2,A0,04,6A,A6,47,A9,1F,DD,40,31,A7,10,8C,94,E9,F4,06,18,E2,5F,CB,C4,B8,68,2B,C6,65,C9,9A,46,A2,62,48,F3,4B,CE,49,CB,9A,A8,78,E7,DF,76,FB,E6,D6,FC,65,05,DE,AC,92,EF,85,AA,8D,21,95,D8,CE,10,BA,4B,70,9E,56,34,45,86,EA,59,E6,0F,31,19,7F,38,D1,2E,EA,CB,BC,A2,D0,37,12,3D,B7,9E,61,94,0D,7C,EA,38,06,B6,6C,09,34,66,D1,B8,79,56,FF,A2,AB,6F,57,A5,98,7B,61,27,9F,13,F4,1E,3C,21,80,34,BF,30,09,39,A6,6C,20,B7,B9,53,35,FD,44,9C,69,F9,7E,4A,42,D2,C8,2E,70,BD,09,38,3B,AA,C1,CE,9A,27,73,9B,39,79,E8,0E,60,5E,EB,94,C7,2B,98,A7,A6,F1,D9,98,66,FC,6A,BE,09,BB,53,DF,0E,47,5D,B1,76,32,79,44,BF,4D,7E,4F,50,86,AF,31,E7,D7,E2,39,6B,2D,C9,5F,4A,B2,C5,A4,A0,E2,5A,F5,71,FA,7B,47,2A,F5,60,5B,B6,3F,5C,48,B1,39,58,32,49,A0,24,22,5B,71,59,4E,74,6D,21,2F,EF,C7,89,37,45,F7,F6,3D,C6,B0,FA,C8,F4,D5,AE,64,F1,2B,55,E2,2E,15,8A,5D,23,0E,C6,86,2E,E0,75,6D,1B,90,71,F5,36,31,92,E4,40,5A,EC,B7,BC,34,0C,99,2C,46,84,D6,E5,0A,1C,F7,CC,AF,2A,7D,C2,87,D5,AD,20,7B,CA,CE,6D,B8,EB,1E,B1,BC,FA,7E,38,0D,D4,78,32,E3,FB,77,CB,D6,F3,6C,B9,85,C2,47,67,6C,65,70,FF,42,2D,57,75,72,68,86,87,54,0E,B7,C1,3D,4C,A6,17,7C,FB,A1,91,60,6C,85,C1,51,7E,70,01,EE,04,E7,C5,6B,87,24,6A,11,6F,5B,41,9C,67,11,04,92,B0,76,32,FC,19,53,3B,E8,62,80,BC,FE,FC,1E,AF,79,90,EC,FC,EC,16,A8,F2,6A,C2,44,FB,E9,47,C4,7D,F3,10,10,F3,F4,22,2D,A6,17,70,89,71,70,C9,D5,2A,9D,7C,BB,93,73,70,F6,CE,D8,6A,52,A3,47,D0,8F,90,EE,10,33,EA,AD,93,55,D0,D0,00,19,1A,AA,D7,AD,A3,2B,FE,C3,9E,0A,45,EC,3D,88,96,AA,5F,BF,D2,32,6E,3B,40,88,55,21,C2,AB,DB,36,9E,03,61,C2,5B,A7,AF,DC,09,C6,0F,A5,4D,6A,96,F2,66,09,F6,45,77,43,12,19,08,F4,36,D9,9D,2D,E3,BE,90,96,AB,63,DD,8A,5F,45,64,13,48,78,80,91,0E,83,14,6F,59,43,F8,FA,4E,B3,66,74,AE,E9,48,97,36,FA,DA,1A,D7,75,5E,4F,C7,E6,11,51,9B,3A,18,CE,24,B1,64,E3,11,68,CF,B9,C7,8A,8C,4E,0D,FF,D4,4F,9F,2F,04,41,5F,08,4F,D6,C4,6B,66,0B,BD,00,EC,7A,4D,97,50,BA,30,1C,7B,F7,30,CD,34,C3,E1,80,2C,B2,53,5A,0C,D5,36,E5,03,83,E6,22,1B,9D,CC,68,F8,C1,8B,E5,CC,B3,AA,6B,91,1F,67,6B,3C,1B,E8,62,56,40,2A,F5,C1,16,C2,97,64,A7,8A,61,F5,CC,B9,78,97,7B,77,8F,67,A0,20,C7,17,D3,06,C3,B0,FD,2B,3F,39,4E,07,9A,BD,2A,A0,7C,B3,27,7C,D7,7A,96,2A,DA,45,F6,9F,66,8B,76,0D,EB,39,46,D5,EC,14,AC,AC,F9,B3,44,01,EA,1C,B3,97,E5,4B,8F,B3,37,59,0C,41,53,C8,FA,48,EE,07,5D,53,E0,BF,F0,48,B3,FE,19,95,C1,8B,01,D9,E9,EC,28,F0,50,6E,3A,27,9C,A4,B4,6E,D2,D0,37,8F,C9,9C,EF,4D,3B,D7,C2,96,D8,22,48,52,75,1E,5D,CC,5B,71,C1,38,CA,82,87,7C,7F,5E,AA,0D,4B,91,34,9F,8B,A2,48,7D,B2,4A,BE,08,94,F2,86,A2,29,6D,BC,3F,6D,7E,02,B4,F4,33,53,E5,4B,22,F5,18,A1,3D,89,65,57,B8,DE,B3,B2,D6,21,F9,5C,48,82,83,C3,53,2C,5D,78,FC,EA,8C,C9,EF,6D,25,12,CF,60,6E,CE,8E,62,68,C2,70,0E,56,BC,CB,96,04,48,B0,6F,EC,EC,4D,31,07,3A,FB,BB,30,86,74,65,E8,E6,E5,04,0B,11,6D,CB,F9,86,E7,E6,CB,51,DA,CA,0D,B5,4E,CA,C7,15,1B,88,FD,18,69,3A,CB,11,0C,09,D2,0D,39,BC,6D,72,16,93,61,8B,EE,22,AE,1B,E9,F4,5C,0C,FE,D1,F2,BE,25,A5,A4,9C,24,09,31,A2,B9,40,05,5D,A9,31,29,2E,2D,AF,43,E6,34,17,AF,1D,5C,03,03,46,66,A6,0B,AC,BF,4A,B6,E0,7E,01,0D,CE,EB,03,FF,21,98,DF,43,13,AC,59,4E,7C,58,B7,76,2B,F0,DE,9D,1C,20,17,DA,02,A0,A1,A8,73,A9,46,3E,7D,81,DA,E7,D6,C4,D1,60,85,C4,1B,90,CA,98,E8,36,D2,3A,08,21,DF,96,77,06,A3,C7,B1,E7,36,02,C4,7E,7E,AC,59,F7,46,04,C9,34,31,E9,AF,46,4D,27,C4,0B,02,70,EC,18,1A,2E,04,D1,C9,19,FC,7E,1E,72,4E,40,9F,11,98,8A,9C,E8,ED,25,51,05,02,3F,7D,E4,0B,FE,6D,11,CB,E0,82,12,A7,22,9F,9B,27,CF,39,01,30,DB,04,AB,D2,D1,7C,7C,13,A1,67,FB,2A,AF,5C,02,FF,39,1F,07,44,4A,76,58,A0,86,28,17,98,C6,9E,61,0E,E6,77,85,86,24,B2,37,76,AE,72,F3,17,00,42,D2,E9,08,48,57,B7,46,EF,32,B3,83,5D,EC,2A,4E,7C,62,83,25,3E,13,25,27,45,7A,7B,73,21,6F,56,C0,2B,CC,2D,54,D3,18,30,9E,2A,78,44,8F,E2,3D,AA,65,7C,5F,DC,E2,07,77,8A,D2,09,EB,56,07,A7,39,6E,21,15,E1,80,AA,E4,6C,46,7C,E4,3E,E4,4C,5F,3B,03,26,CF,9F,BD,57,ED,2A,03,56,97,72,1B,7F,D0,6C,C2,99,B8,73,6E,D8,82,4C,0B,36,78,22,52,ED,9B,6D,4A,D1,6F,A8,09,41,B8,82,86,C9,8D,2E,F1,FD,55,AA,CC,CD,44,EC,93,29,7D,C2,3F,9B,33,EC,96,E9,3B,7E,A7,5E,D9,AC,75,E5,60,F6,C8,82,84,70,5F,08,1B,D8,41,F1,C7,88,04,28,32,7B,52,55,E2,0C,26,C5,C9,8E,11,D4,26,41,CB,37,1B,5C,4B,14,75,4F,F7,D0,9D,D1,F2,20,0B,40,7A,E0,D8,7F,B6,DE,04,24,B5,B7,B5,72,80,29,A8,7F,7E,5E,B1,6D,AB,31,C2,22,BD,24,AF,63,41,7F,0D,B8,8E,57,C3,73,92,19,1D,E6,E7,9A,A2,7E,FC,4F,10,69,0F,99,6D,2F,A6,0A,AF,C7,E9,1B,CC,03,52,10,40,19,6E,8A,43,D3,88,D1,BC,48,22,8D,5A,64,92,EE,D6,6B,D6,F9,28,1E,97,B7,9B,4B,59,1C,32,BD,95,31,B2,9A,79,05,BB,DA,DB,0C,C9,B6,15,A8,69,A7,EE,B5,B9,1E,79,21,8A,E3,70,47,E1,8C,65,CF,E8,ED,0D,10,0D,79,A1,EB,8B,D7,1F,B5,99,A4,EC,E7,E5,A9,5C,F5,7B,79,1F,F4,65,35,5D,54,99,69,88,3A,2A,A5,8C,3F,94,FD,37,7E,82,35,4F,9A,F1,DA,36,C2,27,B0,91,CD,8C,7D,1D,9D,3C,4C,5E,40,1D,DC,3C,A2,0F,53,5C,B7,DC,CE,B8,36,98,2F,6A,F6,70,04,37,BD,A1,B6,97,0A,70,5C,AF,37,29,A5,E7,CB,6D,61,12,1E,FE,06,B2,65,B9,9F,C8,95,3F,98,3F,AF,17,C6,66,A2,AB,56,36,B1,9B,F9,EA,73,18,8A,84,08,9C,5F,0C,B4,4D,55,9F,F8,6C,EB,B9,7E,9E,D8,63,A7,5D,08,A5,B0,F5,CA,BD,6E,6E,CB,65,59,31,84,48,BC,54,DB,A5,59,D5,1D,78,B2,20,8F,CF,85,60,97,18,C0,FC,3C,90,AD,95,C5,E2,DC,1B,89,C8,E8,88,86,7B,FC,DF,50,7D,83,BC,31,7A,64,CF,FC,36,DB,A7,72,D1,BC,66,A4,19,F6,80,58,20,5E,0C,12,D1,46,BD,DB,3A,39,4C,48,74,00,B2,75,4C,15,66,5A,80,83,24,49,09,57,04,FE,20,0A,8D,88,51,08,3E,DB,D1,B5,65,21,00,B9,AB,A9,5D,CE,91,34,B8,6F,93,D0,8D,FB,5E,45,E3,41,24,36,A7,07,F3,EC,A8,76,9E,A3,A9,22,A5,A8,34,09,F5,0F,EA,C2,24,9F,7A,B8,F3,AE,89,12,26,7D,09,06,C5,62,EB,00,89,9A,9A,B7,50,AD,40,07,1A,AD,DB,73,0C,37,72,CA,BD,4E,DB,6A,C8,BF,2A,2E,1A,A6,46,BB,45,04,BE,4E,A8,53,2F,63,68,E0,8B,FA,DF,7B,AF,30,A3,31,56,A3,81,04,CE,25,C9,72,E0,19,A3,37,9E,9B,C6,92,91,EF,EC,AF,03,38,B4,B2,B4,FB,B6,33,91,6A,92,28,4D,99,DD,E3,9D,7E,0A,24,40,AE,CB,71,DA,4B,04,5A,9A,DB,D5,3B,56,9D,85,2B,EE,05,E8,38,D2,3C,2B,D1,56,06,30,5C,3C,B9,22,27,3E,FD,E6,A8,56,BA,AE,AC,F8,EA,D2,1D,EC,BE,31,31,43,B0,52,C0,CB,63,79,86,42,98,45,79,71,FC,7B,84,36,FA,12,A8,E0,D1,F0,60,3C,51,D9,C2,75,3D,DE,68,50,44,2F,29,08,4B,72,4A,65,A8,2E,6D,DF,9F,D9,05,4B,51,3D,2A,9E,E3,10,B6,68,47,C2,0D,7C,AE,37,88,59,40,5E,DC,18,AC,B6,9C,09,61,6D,B5,14,77,2E,5A,68,1F,C9,6D,00,65,53,B0,F8,04,FA,48,C7,06,32,43,87,AD,BA,4A,A3,DB,CC,16,B5,B9,A6,C7,66,01,1B,30,68,CE,AC,2A,19,43,6C,12,B1,B2,05,FF,8D,6C,1D,E1,DD,77,3C,A9,34,35,A5,7B,CF,A2,52,E9,B0,F3,B3,2B,54,FC,09,D4,9E,BA,5E,88,E1,53,ED,77,D0,F4,56,10,D4,09,13,18,3B,57,CC,89,54,92,7F,9D,89,09,28,41,8D,31,EF,A0,53,18,9B,0E,C0,21,61,AF,93,21,4F,EF,45,B5,EA,25,BB,44,C9,DB,DE,2A,80,35,E4,7D,50,49,E3,8F,80,C7,DC,C2,35,2A,20,1D,53,6D,A3,CC,06,E3,09,7C,58,D7,5E,43,14,63,9C,C7,FD,52,70,0E,95,34,DD,F4,2C,A6,9E,EA,A9,FE,29,E7,8F,1A,D5,E2,52,49,3C,58,88,4D,C0,3E,6B,83,E7,1C,C5,3C,DF,E7,AC,2F,6F,A2,7E,5E,FC,24,94,92,18,DE,37,D0,E7,DE,52,F4,D4,02,5F,BF,83,61,01,0E,FC,63,A9,FA,CD,C7,6D,34,A2,D6,10,1D,2E,70,F4,B2,C4,C6,E6,61,BE,92,8B,9D,C0,74,F1,BC,17,9D,62,C5,37,4B,5D,47,87,F1,47,29,8C,DB,64,CF,62,3B,C5,86,D9,FF,29,22,4F,74,BB,E1,93,6F,75,B2,23,0C,86,AF,00,DC,A7,D5,69,F0,ED,04,7D,54,B2,F5,18,85,FA,16,9C,16,9B,52,6D,02,1A,99,72,A9,29,1A,9D,6C,7C,B2,FF,54,E8,AF,6E,96,34,1B,BD,46,CC,1F,D5,FB,FF,68,D1,86,0B,76,3F,A0,2E,54,E9,68,2A,3B,A8,EF,5F,5F,98,FE,B1,55,FC,76,08,1C,F3,C7,DF,4B,24,F2,F5,F4,45,31,AE,DA,1B,A7,40,8B,BB,D8,EC,5A,C7,FD,F3,0C,79,A0,1D,6E,79,8F,05,44,90,AA,36,9A,97,9D,DB,2A,62,CA,43,55,6E,2E,ED,1D,9E,46,FF,77,14,73,55,BD,BD,0E,94,3B,90,23,17,48,59,C8,D2,74,86,73,BF,E2,83,6A,03,70,30,FC,FD,61,5A,F5,E2,A2,19,EC,AB,96,39,36,60,0C,94,82,6D,10,42,45,4A,EA,F3,68,5B,54,A1,31,18,69,EC,8D,F3,73,A1,6E,45,ED,A4,DE,83,FF,95,E0,2C,AF,E2,A2,43,1B,F3,81,27,BA,63,F4,00,3A,0E,0F,24,96,C3,01,DC,20,05,57,B4,B8,3D,3D,0C,88,B9,14,70,22,64,43,97,11,2C,1F,68,31,B4,86,78,B8,92,08,4C,1E,4F,58,3E,08,2D,AE,46,29,B0,76,78,A8,6D,51,4D,7D,55,4D,78,26,4A,37,90,AE,64,08,A6,60,FD,28,6E,75,81,DE,34,AA,9A,96,11,FE,13,A4,DC,17,76,DF,B3,24,60,EB,E8,FA,56,CF,A5,37,3F,ED,FD,26,A4,63,F7,19,5E,11,02,50,A2,53,B2,7D,08,19,7D,68,86,18,51,A1,F2,AA,83,37,5A,66,FF,72,FA,5E,C3,66,AB,16,57,77,E2,4E,60,6C,24,77,18,D6,88,96,57,4C,C2,D6,32,91,E8,D1,B3,A4,9A,37,14,8F,16,0D,4C,08,91,42,F2,0D,77,96,5B,E3,AA,C8,16,87,9D,90,FC,70,06,C1,41,C4,26,03,50,79,6C,E3,C0,07,B0,8A,4B,DC,26,4B,DA,67,6C,00,7C,BE,BC,53,09,0F,3C,1D,0E,62,85,08,EF,60,9D,9E,CF,16,83,AE,7E,3C,E6,8D,D1,2C,38,A7,BC,2C,26,A4,0D,C6,2B,69,2F,57,05,7A,3A,9A,31,A1,5B,EB,B1,05,7B,B5,DF,37,86,74,12,B0,DE,1A,92,F1,D5,A3,A7,C5,EC,23,11,29,AC,CA,25,9C,29,9E,AF,7F,45,EF,4E,A1,23,C0,CA,EE,A3,D2,EE,A2,E7,FE,C9,75,77,31,16,0F,6C,7D,B8,C5,60,1F,B2,B1,9A,60,00,9A,86,98,4B,3E,42,DB,FB,6D,DF,6B,B4,CA,28,AC,17,5B,AB,49,21,B6,94,AB,14,03,DB,14,1D,14,B5,5C,50,E3,F9,2D,D6,04,AC,6A,AF,02,58,4B,89,7C,41,66,48,78,7E,0E,A9,DA,2A,FF,A9,C0,22,2C,BC,2D,29,76,10,5D,A6,DA,4C,70,0E,5F,9C,EB,9A,94,A9,6D,3C,40,2D,56,D8,F3,02,4F,FB,D6,63,2B,3A,4A,4C,1C,07,3D,55,B7,A1,1F,71,46,0A,45,9B,05,C6,FA,8D,04,B2,1E,26,47,A0,74,66,4E,0D,6F,22,E3,05,DE,22,A4,E8,79,AD,1E,F7,13,92,F1,EA,AA,F4,DB,26,A6,D0,13,A9,E8,CD,8D,06,CB,D4,D0,BB,2B,5F,AA,D1,8B,A7,C9,2A,D3,01,70,0E,C5,88,37,6C,B2,BE,6A,CC,21,5B,93,C0,90,FD,0E,8A,C8,7A,FD,81,52,07,AE,2D,A2,AF,59,4D,E0,D8,B5,CB,69,1F,9C,A6,BF,15,8E,83,43,F0,72,C5,70,F5,B6,B0,9A,CD,17,1E,E6,33,F6,66,17,3B,37,B6,F2,02,71,97,2E,54,D8,FF,5F,61,7D,2B,A2,A3,10,67,FC,65,06,27,25,5D,11,41,B1,CD,06,C7,49,95,D2,C4,72,B2,8B,2E,93,47,4B,29,1A,CD,93,94,11,9B,57,00,B2,4A,03,07,83,AE,27,CF,7E,6E,28,7B,8D,3D,2D,3E,0E,C5,5D,E3,6C,AC,18,63,F8,C4,DA,09,48,D5,40,48,C8,11,D7,7D,86,48,84,82,D1,DE,31,BD,BA,5D,11,38,D2,DB,10,56,19,C6,45,7E,A2,5C,37,20,67,8E,03,FD,32,2C,72,2A,C4,F6,D2,33,E0,4C,0C,85,C8,69,85,A4,E1,BF,52,76,81,54,12,0B,81,51,01,9D,5C,87,B8,65,1C,2E,7A,0F,34,5C,87,02,26,DC,DC,14,1F,D2,D3,DD,D5,74,44,14,3B,01,29,76,1F,87,8C,2F,A2,09,A9,E2,18,20,A6,84,FF,2E,54,77,07,A2,77,01,2D,75,AB,39,3F,8B,69,BE,DD,EC,FF,0A,B2,94,25,56,D1,FC,BF,FC,14,D5,86,00,D5,35,9F,66,FF,85,C7,B2,A2,01,74,F4,17,52,2A,96,57,84,56,15,AB,ED,E1,5A,3E,C4,77,A4,5A,1D,2C,FD,02,B7,1E,33,0E,73,DC,5C,88,9E,99,17,7C,D1,EB,A2,59,25,C0,D4,FF,B0,C9,D3,6D,AD,02,E0,66,16,B8,80,65,A1,F4,BE,F5,3D,A4,BD,51,5C,6C,55,2E,E1,08,C2,42,04,C9,B8,86,B2,8D,99,C6,12,81,95,1C,54,36,19,B2,F8,E4,C5,D4,15,7A,DB,12,E2,51,49,26,EE,D5,50,E7,95,6C,FB,86,BA,7D,E1,CE,D2,3F,E1,18,D2,75,4B,6A,41,84,AF,FF,CA,E8,F0,BC,0F,F2,99,4E,B2,E3,3A,1A,0F,88,A5,B8,E2,16,E6,7A,F8,96,82,36,B4,3F,62,43,A8,32,98,BA,25,8A,5A,B7,A4,A0,18,D4,22,E2,E3,33,E0,B8,40,61,72,AF,AC,71,F2,B3,73,66,1D,EC,7B,E6,91,7C,5C,E5,0D,CE,79,34,48,25,89,5F,92,97,F7,5B,25,50,5B,14,80,A3,7B,B5,FA,FD,36,0E,0B,EE,2F,54,9A,BC,D1,82,B9,86,FB,B6,D9,CC,EE,96,FC,AC,D3,7E,08,5F,D5,C4,B4,75,EE,35,3D,BB,4A,EA,B3,C7,DB,94,62,29,65,2A,04,0F,C3,EB,A6,62,9A,E3,7C,FB,FF,1D,8A,4D,72,AA,DC,AA,81,19,B2,DA,C2,24,EF,57,44,21,9A,8D,39,30,CD,15,1B,BD,AC,95,F4,4C,3B,58,13,3F,C6,C5,BE,95,D0,AB,70,AD,8B,EF,55,A2,E1,CF,CA,B4,E3,37,7B,EB,23,EE,73,FC,D2,20,44,3C,F5,0C,B6,01,63,87,B5,BC,44,94,FC,96,0C,C9,4C,EA,3E,2F,AE,06,5D,F4,50,6F,5E,7D,99,08,F8,57,FA,8F,62,3D,95,9F,2A,6A,B1,C7,91,42,3D,E9,A4,31,27,0C,3D,04,DC,E0,8F,02,18,E4,6A,F6,43,E4,3D,58,62,E7,B2,7D,7D,0E,81,1B,E4,9D,61,DA,CB,67,16,3C,9E,58,B9,6C,9B,83,E9,C2,F3,BC,17,65,52,2D,7B,EC,BA,60,9B,F0,D6,49,7C,07,6E,B7,0D,09,94,95,90,8B,82,B8,B7,32,1A,32,3D,CC,2E,9A,F7,3E,BD,39,48,31,A5,7B,4B,75,BA,AD,74,34,43,38,A0,1F,5E,CA,EA,72,0B,5C,3A,2D,62,D9,42,6E,31,67,F3,A2,1B,A9,9B,76,D4,3A,4B,2B,63,FC,F7,A3,B8,9C,E1,65,E8,50,F0,10,3E,E4,83,B8,0A,0D,E3,DA,7C,C6,91,4F,06,67,4A,89,E1,D4,B7,CF,08,B6,E4,DE,D5,A0,C8,6E,AD,AF,6D,33,3A,AE,5D,D7,A7,B9,C9,06,57,EC,DC,32,6A,86,6F,19,48,4B,A0,8D,A0,67,CB,E4,2F,F6,24,C0,49,B9,B8,13,27,BC,10,DC,83,5B,3B,B1,81,C9,29,CF,66,62,A7,5C,2A,DC,07,88,F5,8A,45,29,FF,0B,01,43,7A,7A,A3,E5,41,66,28,E1,E5,D5,99,CC,1C,7D,D5,74,11,31,54,D7,51,71,D3,8A,D6,A9,DD,7B,75,7D,4A,8B,98,07,45,04,86,28,6D,F5,2E,5E,8C,D7,35,5C,78,0B,F6,DE,58,09,E3,E9,A9,BD,09,4E,48,B0,7E,77,9B,B3,10,56,35,7B,A3,E4,08,D0,8C,E7,69,9A,C5,77,E9,72,1B,98,FB,E3,68,9A,49,83,0D,CD,7D,A6,CE,16,57,36,77,54,55,8B,57,3A,66,36,21,25,59,55,88,3A,7F,1C,34,44,28,B5,FF,0D,EB,49,BA,11,30,D0,B3,06,30,D6,72,4F,9D,C3,7E,E2,64,FA,34,92,E8,37,3A,EB,09,B8,D9,4A,2A,71,86,F5,4F,7C,57,48,53,67,BD,90,31,F7,60,C8,C2,07,2E,DE,77,3A,0D,07,C3,57,F6,42,8C,0A,FA,98,0B,8B,76,E2,55,0C,ED,D0,BE,01,8E,A2,9D,72,7C,DB,09,D4,4D,F4,9A,07,BE,B4,C3,1B,02,BB,98,19,85,2F,B9,BA,F8,A4,44,E3,04,EF,50,07,0E,F6,F1,D8,E8,28,A8,1B,1E,50,CD,B0,21,A5,79,BE,41,B1,24,70,8D,8B,60,AF,C2,08,07,85,DE,33,D3,51,A4,76,42,56,40,EE,6A,A7,50,8E,03,57,6D,5A,61,AA,AB,8A,D8,20,82,B9,A1,D5,E3,6A,E6,F8,9A,83,7A,74,DB,C5,19,F5,31,D6,40,7A,27,62,8D,85,E4,7C,6A,4E,81,46,C3,DD,7F,EE,37,B8,D9,BC,ED,38,9A,98,D5,20,DF,1C,FA,A6,79,4B,1A,E3,3E,C8,59,07,3A,FB,85,61,47,96,83,87,10,C5,F2,41,BE,ED,26,C3,EE,79,FB,AC,ED,CE,5F,E2,C6,56,9D,66,CE,4E,8B,36,6E,98,6A,B6,1D,10,5F,E2,DF,7A,2D,23,85,23,B6,F6,03,0D,86,D0,BB,9A,5D,58,72,49,D6,4B,41,DE,7E,F0,EA,B5,C8,5A,D3,19,B8,06,CA,26,EB,03,35,A6,AD,C4,B2,27,F0,60,B7,CF,BC,BA,1D,49,BE,10,A2,3E,E5,AB,EE,AE,73,B1,E9,E1,1C,7D,38,F0,6B,56,81,74,08,8F,47,60,F9,E9,01,A6,11,CE,48,E2,82,7F,8C,0C,79,27,95,F5,D5,1C,8B,41,39,F2,87,BC,E1,D5,96,CF,A7,94,B5,69,4C,FB,8A,45,B0,76,F2,03,FD,24,16,A4,62,62,2F,BA,FE,4F,89,D6,72,22,0C,8C,D5,19,1F,FB,46,A3,35,F7,34,0F,D7,B5,67,97,1D,62,4B,20,31,2C,91,6C,90,11,E6,06,AE,A3,88,0D,26,27,0A,32,75,8A,AF,BA,1C,80,9E,8E,71,E6,04,B7,57,A5,AD,1E,17,12,0B,D6,86,7E,46,70,B5,33,0D,67,5A,30,FC,78,4C,E0,B4,DA,8F,70,AD,64,0F,83,F1,3E,CB,DA,2B,1A,E5,A2,5F,BC,15,4C,01,C2,7B,20,E5,BA,AE,5C,2E,C4,86,B4,17,D1,8C,77,17,79,08,93,C7,12,F1,DE,29,2F,88,32,A1,F0,00,49,3B,62,63,F0,C0,75,8D,17,55,8F,A0,46,CB,35,E7,F6,61,B7,82,61,E3,CF,97,12,88,91,DA,10,68,E1,A7,85,20,59,D9,7C,96,BA,D8,CC,72,71,29,84,CA,AF,7D,D6,05,F5,3C,D3,6D,6A,84,24,44,B2,E3,9E,A6,47,00,DF,92,94,3F,E4,2C,FE,DE,5F,48,34,29,8D,93,AD,33,D9,A3,71,05,5B,EB,70,54,CE,D8,7E,1B,B0,35,03,05,7C,3F,B1,1A,E8,80,97,46,18,92,21,2E,FF,23,1F,F9,EA,4A,A0,5B,99,10,0F,11,E0,16,A5,8C,0E,F0,80,A2,6A,74,6C,2A,66,F0,00,29,19,9E,F9,0B,7A,61,62,51,BA,77,AB,09,9B,BD,49,F6,B1,F6,35,11,28,3E,92,27,00,9E,81,E6,05,42,FF,13,33,75,5E,65,06,F5,57,04,BB,96,23,EF,72,C4,8C,9E,B2,8E,83,86,60,68,93,74,A0,D5,AE,6F,4E,8A,FB,D7,AF,2C,25,04,B7,89,CC,42,A0,F7,47,10,B8,D4,DA,51,36,39,E4,08,BE,B0,FE,E6,7E,AD,61,B6,63,9C,AB,D2,28,19,E9,C8,3D,3E,F8,9D,FB,6F,06,A8,B9,ED,70,DF,7A,0E,1B,F6,6A,9D,23,D2,8D,98,1A,5C,52,27,E3,AA,D5,D7,90,98,8F,ED,B1,81,24,5F,66,E9,C4,0E,B8,EC,AC,A1,73,77,1E,49,60,BC,14,5E,EC,0D,A1,BB,21,E0,12,65,3C,D0,59,93,F2,D1,13,78,7D,6A,F0,A8,45,54,75,A3,E2,C6,82,38,DA,E4,3D,B9,F8,3C,12,D6,ED,B0,96,8C,74,40,63,15,BC,2F,A1,27,0B,E0,C7,D2,24,C1,E0,18,26,66,84,B1,6C,A4,1C,F5,09,02,F0,8E,B3,0C,B3,B8,2F,87,A6,00,1C,60,78,2B,F6,76,98,6D,0F,27,BB,67,7C,23,D4,59,BC,22,05,BE,A9,DF,51,F7,59,1F,9B,16,3F,5A,81,B0,EB,0F,43,03,96,8C,59,F7,04,A0,B0,70,02,3E,4E,C3,5D,1F,DB,5F,5C,F1,A3,0F,DB,35,12,1A,16,0F,42,68,41,ED,07,FD,DC,3B,27,95,CA,14,4F,1D,75,40,0C,DE,11,E7,0C,EF,2C,90,CA,59,7B,64,C1,11,54,EA,BB,59,0D,68,E3,0F,09,BA,7E,15,88,B4,C9,4E,F2,0A,2E,30,55,58,B7,C7,57,0A,62,78,8D,0A,C5,71,E0,BD,DA,96,61,1A,C2,72,A9,94,FC,E0,A9,44,50,8E,DB,48,F8,09,82,CA,22,E7,4B,2E,DB,BA,A8,D5,7D,D5,8C,D3,94,B6,3E,3D,70,11,96,B5,85,98,F3,73,5C,55,AE,AF,0C,2F,B0,E5,46,AF,0F,45,92,60,31,0C,A7,86,4C,CD,9D,40,9A,6D,50,71,67,4D,C1,C2,6B,70,CE,5B,64,8F,B2,4A,AC,5D,25,71,DF,FE,57,A8,4A,A8,F1,14,31,DA,09,BA,3E,2C,65,24,F2,7A,D6,88,A0,C4,12,A2,5B,5C,94,91,1B,E4,04,F5,DD,2F,A1,E7,6F,64,61,06,B9,BD,45,2E,82,71,4C,16,29,39,4A,B8,9F,3F,51,E0,A7,6A,D8,AF,B6,53,6E,50,8E,ED,20,7A,FF,9A,71,02,F7,14,36,E7,42,92,7C,3A,E8,C3,FF,42,6D,41,90,BA,A7,DC,64,FE,DB,A3,00,07,A2,6F,9D,9C,FE,42,A1,16,24,38,77,9A,00,57,75,72,06,4B,A7,5E,C9,67,1A,40,B2,DD,C6,C3,2F,31,F7,32,F3,86,70,2A,A9,AC,26,0C,48,2A,5D,AF,69,09,82,3D,BF,1C,AF,18,9C,24,39,08,A4,ED,46,E2,E0,E3,8B,D9,9A,6D,B8,21,9D,AB,CF,E3,96,0E,CE,C3,64,85,3D,23,3C,98,D6,F1,92,BD,77,8D,62,AE,6A,02,49,24,2A,12,AC,34,EE,89,58,F2,61,C9,42,6C,FE,4C,F1,6D,F6,A3,98,2E,AA,9D,16,42,D8,B3,3A,8E,FA,DC,4F,2B,06,EA,A4,E4,B0,4E,3A,2A,1E,A2,00,8C,1C,D0,CD,A6,D0,3E,A1,94,C6,81,D5,B4,8C,4F,CA,1A,54,E4,8E,CF,32,46,B1,98,73,2A,14,7A,42,18,F8,BD,5C,87,F7,4C,FA,81,64,EB,04,1D,52,17,6D,37,56,18,3A,B0,0E,E9,DC,8D,F8,7C,2D,F0,09,91,5F,F4,9E,D6,B3,97,7A,A5,D2,5F,76,7E,E5,45,DA,EF,30,C4,68,D1,42,17,8E,D1,51,69,7F,BA,16,99,62,73,2C,D1,90,90,0A,50,BA,72,6E,BD,32,38,AE,26,A3,A7,7B,2A,BD,92,46,17,4B,FF,78,E2,57,D8,E2,6A,19,2B,54,CF,B2,DD,83,F9,8B,E5,89,B6,A2,8F,AE,21,41,9D,A0,16,0A,E9,86,64,85,76,FE,F8,35,22,FE,72,92,A8,15,71,50,7B,EA,29,2B,A5,9B,CF,74,CC,C9,FB,09,F5,5F,B0,EF,5B,54,AC,A1,31,0E,D4,2B,C1,BC,B4,75,0C,17,9C,8E,19,40,29,E5,88,D0,B2,21,9E,F1,C5,C1,74,E0,08,36,9E,3C,B7,73,CD,7A,D7,80,45,B7,A6,C4,98,CB,53,A0,35,52,4C,A9,B4,B7,4A,8D,3E,41,00,E1,93,E6,E7,4C,3B,FC,84,39,D5,F6,90,9D,39,3D,E1,86,6B,C3,D0,66,ED,A1,9F,27,78,1C,86,10,68,84,77,B7,D4,BE,A8,E7,37,A0,68,5F,FF,41,59,6C,B2,E3,40,26,E9,3E,7F,C9,24,E9,82,48,3E,DA,09,E0,CA,AF,37,43,EF,99,CE,C2,4B,42,50,90,69,B2,E3,38,B8,97,2D,92,FD,A7,4B,79,05,BD,9A,16,54,DA,A0,E5,10,DC,F0,F2,9D,66,37,46,17,5A,4E,F8,72,8E,1A,AD,B3,99,AF,7C,24,AA,BF,DC,E8,E4,92,66,8D,12,D1,F2,D8,C3,4D,BD,FC,8B,6E,89,C5,48,00,56,21,E5,4E,C8,68,ED,37,4F,56,76,F8,55,38,8A,83,A8,3D,33,67,86,B4,47,D0,4A,74,11,2C,78,BB,26,DA,30,49,4D,C6,47,D1,7A,98,8C,25,A7,D9,3E,BC,31,DD,10,08,CA,04,F6,D6,24,97,13,F0,28,2B,11,B2,2A,0E,39,A2,55,2F,35,43,78,42,CE,74,D7,57,87,DB,59,96,F8,B8,AC,BF,0B,B8,C9,6A,DA,9F,4B,4D,FD,17,8C,15,54,12,F0,D0,71,AA,0F,10,1E,69,49,74,B8,03,F0,B6,58,56,D9,A4,5B,3C,73,F3,75,C0,6A,41,15,35,6E,83,31,A0,A7,00,F7,1F,20,6E,FF,F8,29,42,50,B2,E8,BB,52,1B,4E,14,23,87,9F,FD,2F,2C,F2,01,44,93,E8,99,DE,24,81,32,2C,3D,0F,00,57,C2,83,27,27,32,62,BE,CC,0F,87,D3,7A,6F,1E,B4,49,3F,FD,97,9C,70,C4,A7,6B,64,52,50,D6,C3,E0,B4,72,FE,F2,E9,8C,B5,DF,29,83,20,E4,88,A9,62,8E,BF,40,4D,19,FE,D4,F6,92,BE,C3,CD,AF,04,53,45,F1,6F,46,7D,CC,F6,6D,CB,27,DA,9D,94,A6,42,DE,1E,50,DB,13,5C,93,BA,0E,B8,EC,35,3B,90,7F,A3,3E,69,D7,83,CD,C4,C8,F8,6C,8C,42,F0,1D,F9,C8,B9,2B,AC,16,BF,28,09,2F,1E,90,60,40,B7,2B,4B,FC,FF,2A,3B,AC,06,68,87,6C,4C,C3,B3,EC,95,A0,8B,0E,3A,07,43,DC,DA,F5,52,AD,27,B7,9F,B6,16,98,11,57,98,BA,B7,4B,72,E7,39,BD,E8,81,F6,D3,49,96,7E,BE,BF,68,E2,76,5E,F1,1C,CC,C0,E3,65,80,B7,B7,31,76,DE,56,30,91,92,73,76,73,C0,A8,CF,54,B9,D9,70,49,7E,F8,FC,08,5A,49,EB,97,83,9A,FA,3C,DB,47,ED,60,64,52,F5,2D,42,90,0B,4A,22,60,D9,FC,4F,99,18,1D,C2,DB,74,E0,C9,E1,E5,D7,C7,A0,B7,E6,91,6B,CB,1F,28,11,C9,8E,03,F6,00,5A,39,FD,E6,CB,D3,63,FB,2C,37,41,A8,9C,B8,57,C2,F3,F4,54,62,DE,56,F3,61,C4,75,F6,CE,B9,76,4D,95,8F,0F,4A,C1,DE,32,FB,BF,52,E2,F6,31,EA,75,86,54,0C,3C,F9,B8,7A,F8,D9,DA,80,85,BE,E5,1D,1E,B5,7E,C4,45,0F,78,DC,43,24,C1,36,40,1D,42,C9,66,35,63,91,6F,6C,E0,32,34,7A,3E,22,03,E5,F2,C2,D9,A5,22,E4,F2,B2,5C,C7,12,C7,ED,8D,E0,20,B2,31,83,F3,78,9E,B9,F6,71,54,4B,24,D2,1F,64,A4,26,AD,25,EA,2A,4B,40,B1,E0,42,97,18,AD,D2,F6,9A,5C,7D,A4,14,D3,34,6E,7A,48,48,FC,53,4D,15,4F,27,FF,05,50,CF,89,11,31,A6,AF,C5,29,DA,AD,28,BF,0D,D4,14,6C,D5,47,4A,AC,68,FA,F8,C0,D1,CC,07,EF,84,5B,65,1D,42,C8,62,48,57,C0,C9,5B,3B,01,BF,BF,70,8B,AB,F9,40,9E,BA,9D,D0,F2,F0,60,FF,EB,89,60,58,66,65,02,13,79,E7,91,D8,E0,C0,40,3C,90,AA,83,1F,48,49,B5,10,19,15,1C,F3,AD,06,83,85,E7,F0,FA,39,23,3E,F8,19,59,C7,D8,06,13,78,94,DC,0A,CA,9B,B6,BD,68,D2,9E,1B,F6,0F,04,EC,F2,72,83,EE,4A,21,A5,20,67,D0,1D,2A,2C,16,62,9D,41,92,91,76,B7,9F,78,2B,22,F7,02,4D,7A,8F,61,A6,56,E5,C9,50,B9,CF,E3,37,F4,54,09,CB,1C,2D,B1,94,41,62,D3,CA,53,77,76,CD,6D,19,E2,1E,6B,17,6D,96,B6,ED,93,48,1C,FD,83,51,EE,0D,08,21,37,85,B2,62,79,09,ED,50,23,AA,F9,4A,BA,9C,33,D2,34,31,79,E7,1A,DF,BE,76,3F,BA,AD,E1,46,F9,A5,F0,BC,9B,ED,12,08,01,41,A7,24,78,D4,50,7E,C5,66,45,38,51,4A,36,A8,EE,07,83,29,72,80,51,E0,7E,6F,15,18,40,1A,14,6D,E2,57,B9,CF,29,9E,BA,D5,C0,D7,9C,2C,28,19,49,BC,18,E7,50,09,FC,30,8C,B9,BA,CB,54,A0,2F,B3,6B,D0,50,47,42,87,88,ED,49,7C,E0,85,46,DD,BA,A8,DF,D0,59,1B,BD,44,AB,8B,02,B2,18,04,27,60,04,B7,10,D3,1E,ED,5D,B1,BF,B7,31,6F,AD,83,DA,D4,D6,CA,A4,40,1F,35,82,09,7B,AE,F8,62,9D,37,1A,85,4F,48,C8,07,27,31,FA,94,FA,46,83,8C,A0,60,05,72,7C,F6,D7,26,10,C1,3F,0A,69,9A,56,03,B4,B9,34,8F,4A,3B,37,24,4D,7E,36,8F,6F,2A,E2,61,20,B6,87,44,4D,FA,43,10,3B,D6,6E,A1,08,79,F4,5D,0C,46,9B,1C,00,35,26,0F,0B,B7,04,DA,B1,76,45,C4,FF,CE,31,01,CD,7A,A1,E8,E3,D8,96,6A,F7,4C,20,FE,4D,C4,49,D0,C8,0C,85,D5,52,C7,66,9D,6B,5A,1F,9E,73,AE,BA,AD,DF,69,E0,18,0D,95,34,81,8D,D7,95,98,20,47,C4,E7,62,2E,C7,82,8C,64,21,1E,AF,9B,F5,F9,C1,9A,F0,0D,1C,3B,BD,06,B0,4C,36,52,B4,73,32,42,1B,CC,7F,AD,AC,AA,7C,06,1C,85,87,2A,51,70,26,7E,96,5F,59,E1,4F,68,D5,80,0A,35,86,C9,6D,87,B0,79,9C,63,4D,39,B5,00,1D,AE,B8,E9,F7,74,09,3E,3F,94,80,4F,E2,3E,6F,D8,08,BE,6C,48,EF,D6,DC,0C,4D,74,D8,7D,7C,BC,37,65,60,3B,12,6E,A4,56,8A,F4,D7,76,33,F4,5F,CD,39,4F,3A,78,84,EE,A8,6F,62,4B,EE,2E,F2,EB,31,B8,C9,7D,D9,26,9D,BF,B9,2D,2A,DC,9B,11,06,8D,34,BE,A9,E3,3D,08,51,6B,E0,20,40,56,4A,DB,8C,4F,75,9F,21,D7,9F,98,F4,C9,90,4F,D8,38,F1,A2,BA,06,2F,1E,02,D5,C7,8C,E0,25,77,EB,24,E3,E2,FE,A7,59,C4,FC,47,28,1E,E6,56,CB,31,15,68,2F,28,25,62,6F,9F,83,18,3D,CD,54,24,AB,E2,09,02,9C,41,2B,37,28,EB,A7,EE,EC,84,7A,FA,DF,95,0F,20,D0,BE,22,BC,F1,83,FD,99,F1,29,C0,6A,FF,F7,95,93,F3,EF,B8,FB,EB,57,3A,18,88,E0,1B,E5,07,79,1C,7D,1D,72,E0,76,2D,C9,6A,35,DB,25,CC,56,8A,02,9B,D3,6A,E0,A6,10,38,D2,58,1C,BE,4E,1B,46,CF,F6,A9,99,71,A5,CA,CD,E8,E0,F4,C6,D4,2B,B6,EA,8F,28,23,28,C0,07,46,B8,88,B3,28,AA,E1,E2,94,1A,64,5B,39,60,B1,BA,9E,0F,9C,71,2D,02,D9,41,22,90,4D,76,3B,9D,E3,2C,C0,72,4F,FB,00,82,62,BB,7A,8F,06,21,C2,7A,19,59,24,76,95,D9,26,FD,1E,75,28,8D,F6,49,DA,7A,74,9F,13,39,DE,6B,32,CD,91,88,08,FE,51,7A,50,9D,E8,DE,6A,A7,E0,00,D3,F9,B1,EE,2E,27,11,93,DC,CC,A0,9A,5C,F2,B3,F9,F0,E4,B6,80,5A,63,22,F0,41,85,CD,F6,A7,C0,15,93,30,CE,36,3C,20,AF,4D,51,13,77,18,AC,BD,C2,CB,C0,D4,EF,41,0F,EA,4A,F1,C4,BB,CA,2B,B0,8F,08,29,38,2F,D3,44,4A,6C,98,C4,78,34,02,9F,36,29,78,A8,5A,98,AB,B4,E2,0A,B4,2D,64,09,54,B9,46,9F,29,82,9D,29,E0,09,AB,96,33,67,83,59,CB,52,D3,82,4E,2D,AF,04,4B,21,35,65,0E,DF,89,A9,3F,AF,CD,5C,86,12,9F,D7,0F,33,C3,E0,C9,2C,BA,70,FE,F2,83,95,D8,2C,C5,EE,47,26,6B,11,CE,10,8D,29,88,05,04,30,7A,E5,E2,AE,AD,79,2E,BC,D2,F1,10,3B,D2,3C,95,EA,0F,38,94,A0,E0,C0,B6,54,03,3A,69,32,13,2F,2C,52,65,7E,4F,DE,61,1D,30,FA,DB,87,F0,62,0B,67,71,32,DB,86,7E,BA,63,F0,30,B5,82,76,26,63,AA,95,1D,FB,4A,1E,3F,EE,B2,63,7D,E2,AB,22,2C,03,14,FC,EB,23,1C,8D,F1,02,F3,34,4F,DB,80,73,D4,CA,0C,CA,D7,9C,43,C2,27,D2,94,C8,4E,26,35,D8,AE,C5,BE,2C,41,43,95,5C,8C,A0,97,7A,7F,34,E7,74,1D,55,EB,AE,51,93,64,1C,F7,15,4F,A8,88,40,EA,F8,AD,31,96,B9,81,87,A5,36,F0,9C,2D,58,B4,26,C2,B0,6E,3E,9D,90,65,CD,69,5C,AA,83,9F,70,F8,6E,18,A4,85,20,B2,C0,16,38,BE,8B,81,92,1A,D0,A3,A6,01,43,AC,26,0D,4B,C5,93,BB,4C,9B,42,E7,27,49,BE,D5,3F,CE,D2,08,87,9F,D0,33,5A,72,A8,C8,F6,6D,4D,6C,D1,4E,DF,AA,B9,1D,BB,E7,FF,21,E2,9F,99,53,9E,85,F7,C7,85,D1,09,D5,3C,E0,5B,FA,33,74,E3,EC,F2,60,DB,64,08,F1,C5,7B,4B,E6,C4,6C,59,A2,A9,4C,38,36,BD,A7,CA,15,5C,F9,05,55,83,9E,2D,2E,9D,7D,DE,BC,C3,6A,A2,7C,C5,08,73,1F,A9,C8,86,BC,A1,0B,8E,89,0D,97,2F,20,94,B8,BC,EA,01,8D,02,3B,16,8C,EA,4A,BA,62,93,5F,07,89,3B,B6,B2,7A,04,54,3A,B4,14,D8,98,E5,D6,EC,26,93,3C,F9,F6,3E,5F,E1,B4,C5,9C,1C,6C,3A,0A,88,F4,84,3A,1F,0F,F1,0F,7D,5C,E5,C0,68,C6,AE,2A,26,BA,53,27,6E,E1,DD,0E,B2,66,84,2A,70,01,15,0A,10,76,66,51,76,52,16,F6,0E,6A,0B,A8,41,CC,06,C3,8E,70,86,9D,6B,0F,D9,6E,76,4D,01,6C,C6,90,FD,45,D5,D9,66,E9,31,35,D1,EB,DD,EE,5C,82,BC,F6,5F,57,FC,BC,5D,B6,0F,24,E1,8D,5D,E2,F0,C3,56,41,1A,D0,AE,0B,37,42,2D,63,F1,1F,4A,88,35,08,28,E5,43,EC,C4,1C,1D,B2,E6,40,72,E7,C5,F3,55,12,58,F7,4B,F8,D4,2A,AB,4A,BE,B8,AF,19,49,15,A0,FE,3C,AB,EF,37,D4,C8,6C,DC,59,F7,31,EC,C4,70,BE,C1,20,1E,2E,F0,D9,2C,2C,99,39,F1,E3,57,36,41,12,80,B8,49,61,45,4C,A8,5D,65,2B,32,4A,C3,42,51,E6,60,89,EE,0E,3C,C2,35,9B,8E,43,7B,A0,8A,B6,83,2B,0A,03,71,C1,46,EB,FC,8E,96,21,65,F2,37,CC,31,2C,8F,97,1B,F9,48,69,94,56,D6,D5,F4,CC,26,2E,B3,0B,3A,56,CA,1E,91,A7,BC,A7,9D,CD,DF,F4,D7,ED,81,65,26,32,DC,95,9B,3A,29,DB,4A,83,7D,02,B0,6C,A9,FA,5A,C0,6A,FB,8B,19,B1,48,FD,C9,85,AE,1A,72,25,5F,44,12,05,F6,86,77,B1,B2,0B,F0,13,84,AE,83,1E,CD,2C,C4,DA,A9,AE,D9,B8,22,8C,91,5B,A3,87,F5,05,F7,07,2D,BF,B1,FF,83,A6,3A,07,48,56,42,1A,F3,D3,A5,40,24,6B,8D,91,59,D6,42,C5,46,AD,F6,94,C5,FC,28,8D,59,C3,8B,2B,76,C2,21,54,F3,79,02,FE,31,FB,D1,16,8B,AB,8E,71,7E,41,AB,CC,22,7F,59,5F,A7,F3,C3,19,7B,05,2C,A2,0E,6D,61,54,E3,83,4D,FB,40,E3,0B,58,8E,7E,47,BB,54,74,D4,17,89,09,41,82,A4,B7,30,06,0A,B4,0F,4A,34,9E,91,5D,2B,3A,11,A3,E0,38,1E,1A,53,20,34,47,94,C7,01,A6,21,28,27,97,AB,B4,08,FB,C5,35,B4,14,A5,F3,53,59,82,FB,FF,AA,AA,25,3D,06,8A,BB,BC,AC,28,3E,83,F5,53,A6,E9,AC,21,8D,87,61,F1,68,58,43,59,31,DD,05,DD,F2,98,C1,86,1B,51,AC,A0,E9,87,81,09,44,FB,5E,05,EF,64,5E,51,61,F5,AA,7C,E1,A8,D7,D0,53,60,79,B0,74,1D,60,97,AB,1F,30,FC,85,1D,DB,10,39,D9,6C,73,E2,EB,6A,9E,B3,BC,F5,38,83,9C,A1,8D,58,0E,E3,4C,DE,2B,D0,23,26,B1,4C,41,93,E5,06,81,C4,09,B9,24,AC,DC,6A,0E,16,26,C6,DC,E8,06,28,65,0E,75,99,E4,88,55,46,33,44,3F,8E,5B,F7,21,5A,E4,CC,26,B3,37,F4,E0,4C,A8,22,1C,32,C4,2F,F5,E4,61,46,F7,D6,05,4D,5A,00,08,9F,AE,04,67,BA,61,13,1D,EE,3E,0A,B2,0F,BD,B0,AD,F3,B8,2E,34,F8,C1,57,9C,18,50,38,E8,B0,7D,94,44,BE,52,4C,7A,10,6F,01,FB,FA,F5,48,5C,56,61,6B,91,21,0F,9F,B4,E5,2D,FF,52,1F,13,39,68,26,B2,6B,26,DF,11,F6,01,8C,EB,93,89,D5,DC,FC,8B,9D,C9,05,21,A2,C9,2F,BF,72,18,00,E0,5C,43,DB,20,15,B2,E9,3C,C6,DB,EA,12,2C,E4,58,D8,CF,00,44,86,D5,42,4B,A1,0F,C1,49,A5,2A,01,9C,EA,63,CF,61,A1,0B,4C,5C,22,1F,C2,2E,A2,BF,8F,03,59,28,3E,37,D2,73,BD,A7,BE,25,42,1E,AD,9A,E1,CC,6C,86,74,81,07,86,8A,26,E9,97,5C,3E,D3,05,17,D2,55,E2,0D,67,53,CF,BE,DC,CB,18,99,DE,D7,D1,7E,77,AA,0F,BB,BF,91,F6,AB,B5,1F,06,78,AC,23,69,B1,BA,EE,2E,96,76,A7,98,DE,A0,22,22,2B,22,67,24,B2,F3,5D,4C,A2,CC,84,2D,A5,DC,8E,B4,20,6E,5F,B8,50,FD,59,77,69,EA,C2,08,22,62,66,FC,6C,5B,9C,4F,29,18,03,B7,3A,F9,5C,B0,B2,1B,03,2C,F2,5E,03,BA,21,37,B0,5F,17,4E,92,8F,FA,DF,9D,D2,AA,FD,96,94,4A,9F,53,D2,11,81,C0,31,DF,95,23,4E,25,4E,9D,97,93,41,DC,0F,7E,07,94,B8,09,0E,A5,CD,B5,62,B6,4A,59,51,AB,32,99,30,6F,6F,97,3E,BD,EB,61,EA,06,4D,1E,93,9F,76,0A,60,12,90,76,6C,9E,E5,AA,12,2E,08,84,54,13,0B,12,21,4C,76,71,00,2F,DB,D9,B2,B1,78,73,9B,B5,70,AF,0B,2B,D5,BA,2D,87,E8,29,29,27,4D,58,2B,92,5A,FD,A1,F6,79,CB,A3,2B,60,E9,32,7E,55,15,1B,F5,72,DC,92,75,53,BD,B7,32,40,5D,4B,72,1C,85,5D,87,73,2F,18,10,15,7B,6D,6E,1E,07,F6,7B,6A,40,76,AB,82,CE,39,4F,43,FF,19,B3,DB,8D,8E,D0,7B,D3,C3,77,E7,E2,D3,53,38,B5,E0,C9,B3,C2,9A,9B,7A,90,EA,CF,03,46,22,81,35,02,E5,35,D0,41,E1,3E,B5,A6,E6,59,C8,CB,30,17,35,41,E5,4E,95,99,DA,BA,AA,24,93,6F,3C,30,93,B3,AA,FD,FC,36,FD,6F,BE,C2,8C,C6,B9,93,23,F3,0D,5F,A6,69,EF,3A,D6,5C,B2,51,90,20,D9,6C,3D,3F,2F,8E,76,3E,33,F5,27,B6,25,FE,AE,AA,84,49,69,BC,02,A4,58,47,34,F5,E5,50,A8,65,C9,93,2D,51,03,8B,26,62,63,A3,4F,9C,6B,3B,F0,45,06,AC,55,DF,F3,79,D6,93,EE,13,A7,51,56,9F,DC,C3,61,EC,65,F8,C8,42,4C,84,0B,8F,20,A6,44,60,43,D1,75,38,0D,4F,DD,BA,D5,5F,55,3C,53,0D,AE,B7,12,DC,A0,4F,D0,F6,CF,82,2D,61,93,A2,56,7E,03,53,84,CE,A5,A7,F2,80,DC,7B,46,16,8E,45,93,69,5C,86,3A,84,73,EC,C1,8C,F6,29,C4,DE,53,1B,6D,5F,EE,69,A9,67,0C,9D,45,EA,C1,D6,93,D7,90,0C,B2,43,EF,A1,44,18,1D,13,17,F9,8D,D1,83,E1,D2,2E,E8,74,4B,34,7F,52,96,D8,91,D1,98,EF,44,C5,E7,D6,23,08,5A,83,1E,A7,8F,37,4C,62,E1,DD,ED,65,1D,19,8C,DD,B4,E9,EA,27,A1,C7,FC,44,A2,3D,C2,DE,43,B3,11,E2,6E,49,52,0D,68,9C,28,91,9F,CA,60,8A,C2,0E,06,7D,1F,64,9D,89,74,1C,31,A4,CD,04,4A,DE,C3,B4,BE,BC,B3,1B,C8,7A,5C,AE,8C,DE,07,02,DC,57,1A,C7,23,BB,AF,92,83,6D,98,57,F1,98,AC,06,79,14,95,4F,E6,EA,78,9D,AE,6A,1F,21,C7,F4,07,74,BE,B6,F6,72,72,A3,47,01,0F,80,50,64,3E,D5,6E,37,A2,95,33,84,62,28,13,73,62,1F,26,33,6C,F4,88,3B,4F,45,4E,DA,8C,4F,5D,8E,7B,89,0C,20,16,E0,92,A3,72,C8,7F,F5,D9,BE,A5,0C,A8,19,73,E6,C3,70,69,17,5A,1E,64,91,BC,64,45,36,22,C1,5E,3D,35,BB,42,03,D7,2C,26,74,1E,34,C0,6F,D6,DF,BA,6A,9A,9A,77,A3,33,80,23,AF,D4,70,FC,39,B0,B4,D1,BF,A8,46,03,10,AD,D3,5F,93,09,1E,8E,34,F6,4F,08,1C,AD,57,4F,26,56,CE,07,7B,73,75,54,8D,24,A7,7C,FC,87,48,BD,01,A1,9C,44,95,0B,3D,AD,F3,2E,38,09,29,8C,C5,25,DE,86,47,69,7A,4E,74,28,3B,65,BF,F6,DA,C2,F4,FF,DB,B7,FD,93,4F,8B,B8,A9,56,BC,82,C1,2D,9F,D6,F8,82,D6,F2,52,A0,45,98,35,A1,E6,E7,D0,3C,92,ED,E7,79,74,CE,E6,63,5F,3E,FF,D0,6A,48,57,EA,F5,12,F5,F6,48,70,FC,F7,48,5B,C4,8F,C3,5C,54,42,91,66,72,54,5E,22,EF,94,DF,68,0C,9E,B8,76,82,3A,41,14,49,6A,EC,89,48,CE,A5,45,07,19,EB,BA,6C,BD,E4,4E,14,B5,7F,08,C1,AE,34,E8,B3,A5,64,A1,68,12,BD,BB,18,16,6C,CB,D5,8B,DE,AF,31,2B,6A,76,32,CA,94,86,ED,00,5C,DD,B8,72,59,74,39,58,2E,0B,EE,02,23,22,BB,A4,B2,8F,7A,7C,2F,F7,9E,DA,D2,56,7F,BC,83,DA,C4,79,40,9C,1D,04,0B,03,C7,2C,22,31,39,C1,94,AE,55,A3,AC,97,1D,DF,4C,8B,4F,4D,B4,F0,CF,A8,5E,31,24,DA,46,C7,3F,6C,3E,06,0C,0D,1A,98,72,32,43,73,21,8E,1F,79,FF,00,EF,E7,27,86,50,83,7A,53,E7,DC,A2,FF,15,FD,B2,62,B6,72,CA,F4,C2,D0,69,79,A9,0E,4B,1C,02,AB,84,FE,CA,08,C1,22,AE,76,06,45,B7,6F,21,9E,42,CA,21,D4,98,C6,31,00,D0,FA,11,D6,4F,71,21,D1,15,1D,21,CE,EC,F1,57,24,4D,C4,6A,3E,AC,F5,64,14,5E,2D,E6,04,49,47,56,67,10,A4,81,0E,8D,EB,AA,96,4A,FF,85,1B,ED,4C,5A,C7,95,B1,75,93,F7,89,F6,13,9A,DF,1B,5E,45,81,10,52,00,29,A2,A7,0C,5E,1F,66,99,4F,F3,47,F4,13,17,15,6C,45,A2,F0,29,20,9C,CE,FB,18,B5,CC,49,9A,AF,00,8A,3B,08,14,7D,8A,F4,E6,BE,82,44,3E,94,74,C7,A1,50,39,CA,CB,22,67,C8,69,74,A6,93,C9,E2,55,46,DD,42,13,5B,88,32,99,ED,88,FA,28,21,95,3A,26,17,2E,86,8B,6F,1A,04,E0,C1,4B,07,34,70,2D,FE,92,0E,77,98,37,44,49,DF,F6,68,A0,6C,4D,70,3B,08,51,3C,7F,82,B1,2A,D2,D6,69,46,12,4A,D8,01,E7,F8,F3,BB,B6,B0,C1,92,A2,CF,F3,F3,F8,1C,A4,00,15,8C,43,9A,FE,92,EA,25,30,91,D2,0D,A6,D0,A3,D3,F2,B9,45,32,06,E4,0C,4D,8E,56,CF,E8,3B,60,47,C9,16,77,0C,B8,D9,0B,24,3D,2B,04,2A,1C,23,93,09,A1,8E,BF,02,B6,C0,B8,5C,E5,3B,F0,FD,5C,2A,78,EC,ED,98,E5,E4,B3,B8,11,A2,8C,9E,41,4E,E1,9E,F9,3A,B1,EF,E2,41,60,28,B2,2F,12,AC,21,8D,36,00,DA,03,8E,69,AF,B6,F0,A4,4A,7C,56,58,17,51,17,1A,EF,BD,68,A7,5B,32,BB,F2,5A,B9,AA,2C,D2,6D,B8,BC,BC,30,F0,02,2A,8F,31,9F,1F,F6,55,A3,19,6A,0A,ED,2E,75,12,73,29,BA,4E,13,EE,29,00,FF,2A,80,62,98,EB,3D,31,C9,BB,E3,67,EE,AA,A8,BD,81,B7,C6,8C,09,AC,22,20,3F,23,91,C1,5A,9A,8B,47,3E,AC,4B,77,6E,69,8C,CE,F8,D5,AA,C1,23,38,3E,AB,75,54,A7,60,08,7C,E4,B5,FB,F1,36,A1,0E,BC,76,58,BC,76,50,E4,55,BF,90,03,9B,EC,71,F7,7F,F7,D3,B0,86,43,2C,FC,56,7E,F8,C5,DF,85,28,C0,32,18,5A,51,2E,69,84,B7,8F,00,6C,5A,BD,7D,33,AF,CD,47,AF,9C,C0,B3,9E,C8,28,3A,E6,71,DD,74,54,46,51,56,9E,8D,30,52,D1,64,55,24,C9,91,29,2E,3F,D7,6F,50,C3,56,53,FF,8E,75,59,CD,D9,3B,E3,8E,2C,31,5C,F4,B8,06,98,F1,A8,C3,8E,EB,09,35,39,65,1D,57,2D,CB,4E,55,6D,FC,F5,3C,FB,29,F6,59,99,F6,9A,F6,F5,B2,37,1D,0B,81,8B,3B,A3,3F,48,AB,BB,2A,CC,21,46,D6,C5,1C,E9,45,2C,16,61,46,37,39,71,ED,94,F8,87,EE,40,B3,90,8C,ED,6A,47,29,A2,27,4F,FC,2B,74,AC,71,1C,31,8E,DC,1A,E5,51,8F,DA,03,17,D1,62,06,89,42,1B,EC,4E,A6,D3,F2,AA,38,EC,4C,F4,11,E0,AA,42,13,7F,80,D3,59,57,E5,CE,A6,21,29,B2,B8,D9,5B,E7,7A,7D,0F,62,A9,3F,F8,88,6A,87,84,FC,10,B4,7D,6E,29,D5,8F,A3,89,0E,3F,64,C5,02,8F,BD,9E,11,5C,87,2E,8A,3D,02,54,A1,E0,50,7A,4C,60,A4,89,41,DA,D6,4B,C2,CA,5E,F7,6B,4B,2C,5C,60,DF,B0,61,39,FD,37,A6,EA,52,12,E8,3B,03,A0,A5,18,C4,99,C3,36,07,09,D4,BE,8B,FF,6D,3C,CD,6E,FC,3C,01,E0,9F,D9,CB,47,CC,50,40,B9,C0,FE,6F,DD,3D,07,07,C3,7A,9B,79,88,7C,C5,CA,01,71,AA,8A,A8,58,2D,05,4E,83,8C,17,8F,DC,A6,3B,8A,C9,4A,1F,CD,EE,E0,C7,88,8E,E6,AD,B9,5A,E0,26,95,35,F0,45,FA,CD,7F,F5,4B,BB,8F,A4,2B,3A,A6,7B,CB,BE,9F,C8,F2,A7,AD,47,7B,85,EB,33,ED,AB,3D,8E,B1,1A,C2,9F,F5,21,43,EE,9B,99,D7,64,2E,8A,32,CF,E6,97,FE,72,56,24,C9,88,85,88,21,A6,21,EB,FD,2C,59,29,B0,DC,1B,02,F4,E9,35,8F,A4,0A,E2,BC,E3,E5,7F,08,0D,E1,00,C3,89,71,EF,5B,96,B0,83,5C,A9,80,D1,A7,A7,37,7D,47,3F,68,5C,2F,9B,2A,14,42,72,2E,3A,99,21,E1,2B,C9,56,3A,18,F4,A2,28,DE,9D,BA,FF,40,30,EE,FA,FD,8C,CA,82,5D,C8,47,97,A9,86,42,4C,5A,1A,06,06,BB,E7,AA,B5,01,C7,D7,58,CA,DB,9B,18,EA,DA,5F,4C,DC,4D,C3,B5,01,4B,F9,29,0B,A0,5E,60,62,34,CC,C4,3E,D2,AC,32,6C,88,70,EE,71,58,23,F6,8F,7C,99,A9,74,71,7F,2B,58,98,80,FD,34,70,B8,75,80,1D,62,82,B0,AD,0A,29,62,86,50,7A,72,66,83,D1,EB,E2,4A,37,BC,51,5F,A4,93,CB,8E,70,B5,76,1B,B5,01,D0,1D,6C,F9,16,DA,E1,78,79,76,F0,51,4D,0C,93,A8,13,48,42,18,84,8A,5F,9D,99,D1,D5,B7,54,4D,0A,5B,F3,2D,A0,14,DB,4E,24,70,7F,F7,73,BF,9E,09,A1,1A,A5,6A,38,AC,C0,7E,18,A3,96,CF,4C,38,DC,33,58,A1,09,94,3E,34,05,6A,CE,72,98,8D,40,F1,9F,6C,1E,A4,EE,AA,CD,91,C0,65,76,37,83,AA,E8,C3,C8,D2,DA,B3,70,34,AA,BE,29,9E,44,F3,23,96,C2,C5,33,32,7E,D1,01,EE,FA,A0,7B,0A,4C,89,41,45,B0,4A,BA,31,7E,A5,0A,1C,7F,D2,8A,19,06,8B,02,75,16,5A,73,14,03,00,EC,74,42,2A,33,D2,B8,22,21,1D,E2,B9,6C,DD,FF,9D,42,A6,1E,6B,DF,2E,73,07,E7,FC,B1,28,C5,83,B8,9F,F5,2B,79,43,CF,10,3E,0D,31,8C,A3,01,90,8C,B0,0A,79,1C,C6,D4,56,D0,58,FD,9C,92,35,E2,B0,FB,EB,CD,A5,C9,93,A5,97,C2,C0,93,7C,21,DE,04,06,BF,D9,4D,0A,17,68,55,87,31,08,E4,11,C4,0F,7D,A3,CF,DB,2B,2A,CB,54,F1,D4,6F,75,81,66,C1,70,47,AA,26,46,DC,AB,E4,82,AB,F8,CC,66,AD,C9,09,74,AF,02,6C,75,4E,83,33,EC,48,C1,19,DE,C4,47,25,B9,B9,42,F3,5D,AA,12,7C,C3,4F,C9,9A,38,01,82,49,57,94,73,07,40,36,AF,13,D7,09,76,76,A9,E9,EB,29,A0,1C,F6,88,2B,3B,22,A9,43,34,85,76,DA,EA,61,B1,DD,49,C8,84,74,D0,3B,1D,C6,EC,C9,4D,EA,51,B9,FD,2A,57,F4,12,09,0D,DC,46,78,07,8A,57,C0,5A,6A,8C,99,4E,2C,88,EF,81,F2,97,7B,C0,B7,5E,D4,59,C8,ED,27,FB,F8,F4,DC,AF,18,58,DB,3A,BB,A2,BA,17,BB,ED,90,0B,BD,D9,04,4E,29,69,36,E2,30,4C,66,1A,5F,DC,70,E5,56,70,81,2E,64,3B,16,7F,2A,20,64,FB,92,D1,B4,20,2F,D0,14,C0,07,93,36,2B,10,88,D7,29,AD,7F,78,E9,F8,63,70,8A,06,56,1A,1C,3C,A6,16,9C,D7,E0,A3,83,F7,A9,F4,68,83,C7,D7,30,15,83,17,9D,42,41,D2,1D,BC,3F,C9,1B,00,AA,2E,D5,A7,EC,6B,14,F8,4B,BB,0C,8B,59,1B,F4,BE,02,B4,8A,1D,0D,F5,44,46,9B,69,CE,CC,8B,18,1D,21,5E,18,F1,95,64,EE,3B,09,2F,23,3A,0B,6B,BF,E5,5F,E0,E2,51,5E,D6,77,C4,1C,6E,07,71,EC,FB,61,EC,CC,A9,CD,E6,C1,09,D0,FB,0A,BE,78,5B,06,21,0C,E9,88,A8,0A,C3,A9,25,5A,C9,87,5C,1A,D1,28,C8,37,1E,5D,ED,7E,D1,0F,D3,73,71,DF,AB,C5,F5,9D,05,9F,68,67,29,F8,C9,DB,C3,9A,62,1E,9F,5B,BB,66,17,05,B2,DA,7A,57,91,99,B7,62,B6,EA,30,B5,56,0D,0D,AD,0E,40,7A,DE,1C,7A,80,6C,1F,2C,5E,EB,5C,12,A9,43,91,E4,46,24,FA,7C,AB,9E,56,51,52,52,25,76,28,4B,FA,B6,1F,08,D9,EF,BC,02,A7,19,3C,CA,95,B4,1A,38,40,11,1A,14,A0,90,A8,B3,83,8F,FA,56,5B,D5,F6,0D,49,55,9A,86,AA,6E,3B,AA,FC,07,38,FA,FD,B4,D0,B6,CD,87,EE,11,D0,E1,2B,08,9F,AE,8E,37,CE,A4,52,86,23,5F,FD,76,DA,01,D7,0A,A7,88,BE,A4,48,5C,74,EE,5C,1C,65,3D,4D,89,79,9A,80,4C,B6,EA,17,FB,8C,82,7D,1C,4D,DC,1F,4F,BB,D1,BD,1A,B6,65,57,06,71,C2,87,DC,FC,6F,78,64,1B,E2,80,BD,40,60,92,8B,83,FA,3B,89,EF,6D,D3,AD,44,BF,77,89,96,64,23,EE,77,1F,99,67,2D,CE,53,73,DF,82,22,5D,56,02,D1,B0,C0,2F,3C,B4,E1,76,68,BE,F6,F9,4C,7D,FB,8B,7B,24,B5,32,3B,9B,8D,E0,CE,73,C5,99,D8,42,8F,87,26,FA,D5,D9,E4,8E,01,E6,25,AF,B3,0B,66,7F,99,CD,2C,B2,27,B4,EC,C2,6D,8F,23,D0,85,AC,6F,B4,93,8E,BE,FA,97,EF,C2,B8,60,A4,A0,81,1C,BA,56,D7,45,90,D3,84,E1,15,BB,7D,D4,A0,66,BA,B9,F5,37,58,0F,83,4F,CF,6F,DE,79,AE,92,E4,61,C2,A9,F5,3A,45,7A,09,B1,70,CF,4E,13,F3,9B,45,EA,7C,E1,1E,48,66,47,D3,D4,FD,02,BB,24,C2,8D,01,3B,8E,96,DF,A8,8B,80,B1,8C,3E,C4,B9,A3,B5,49,C4,B8,DB,C2,CC,AE,2E,63,25,DE,8A,A3,53,22,9C,E1,FF,44,B1,EC,EB,0A,98,0B,F2,C4,72,FC,BA,BC,F1,BE,FA,9C,1D,28,A8,00,74,48,6E,88,7B,32,4C,52,C9,5C,7C,47,0C,FA,9C,C6,08,7E,33,6F,32,31,9C,41,B9,34,B0,2A,97,8A,1D,32,B1,95,F8,83,70,D6,7D,6B,CF,26,A6,26,FE,9A,66,EA,A9,0C,A9,83,02,19,23,80,A3,4E,8B,6D,C1,31,4A,92,59,65,27,C1,42,63,38,6E,A1,53,83,10,B0,F8,AC,DE,91,18,DB,99,E0,63,6C,7E,E9,88,04,FA,65,6B,23,4A,F4,86,A5,6B,B8,1C,50,B3,C2,8A,AA,29,9A,20,C1,3E,A8,89,41,E9,90,37,60,5F,7D,5D,44,63,C5,CE,BF,31,6C,51,0D,99,4A,F7,E0,6D,AF,82,15,B5,41,F0,BD,C4,34,80,3A,7D,80,39,6F,67,50,0C,04,D9,8B,C1,39,91,F4,A4,EB,DA,90,2E,7C,30,46,68,B5,35,E6,B9,F6,1B,A1,DB,80,C3,46,8D,6D,94,4B,B3,16,79,52,DE,8E,74,19,A3,2A,45,D6,50,6D,0D,E6,E1,1E,4C,3D,42,9D,ED,0B,93,FD,FA,E0,92,69,1A,47,7D,72,7A,1D,7A,FD,06,E4,E9,B1,D1,D5,BB,E3,07,68,A3,63,2E,A5,57,FC,2B,33,BB,CD,C9,28,61,4D,BB,77,6B,29,51,36,E3,1C,FA,77,B4,3C,81,5C,4F,1D,75,BC,9E,1B,3D,F1,09,60,4B,31,4E,BD,BA,1C,51,82,5B,D1,B9,AD,FC,D3,2E,58,91,53,58,52,DF,DF,45,E0,60,AC,B9,8D,52,E1,72,9F,9F,E2,9B,8F,37,3E,91,0C,CA,E9,39,A5,88,87,6F,A1,12,D1,3E,4C,4D,90,7B,C8,67,F7,09,11,D1,D6,3D,20,4E,79,AC,4B,8B,F6,34,2A,3A,31,31,7A,CD,10,42,9B,E0,86,9B,3C,BA,02,94,53,19,DB,40,74,8A,A8,6A,FE,00,2B,B6,9B,E6,66,78,0F,98,BE,19,B4,AC,25,D4,DF,4B,29,D9,A9,CC,4D,28,01,72,75,25,68,4C,3D,A4,5D,5F,65,DB,B1,9C,C0,A9,17,AA,62,B4,0E,33,82,64,01,DD,BC,05,F1,0D,89,37,7B,BA,A3,3A,61,B8,31,36,F7,7C,F9,B5,C6,EB,04,22,3E,B7,2E,F3,88,4F,E1,71,61,52,B4,9E,6E,CC,DF,BA,35,60,33,D7,4B,0F,2F,F7,0D,7D,20,DE,39,43,E4,74,3B,1E,7F,8A,0B,AF,5C,FA,C1,EA,64,AD,4F,70,54,7C,77,A7,3C,81,01,00,CA,D8,A9,3D,92,0F,16,CB,16,67,3F,55,B9,68,68,10,1C,AC,F1,35,0C,D5,93,3D,B1,CA,7F,8E,BA,C7,91,A7,36,42,DA,E3,5F,47,AC,31,16,35,7F,A4,35,A1,9A,AC,72,38,2E,67,7D,17,F9,6A,33,51,B3,47,C1,79,6A,CE,9F,10,98,8A,CB,FF,C2,10,00,36,41,07,28,66,1E,D2,D1,AD,13,74,88,5E,AB,7B,CC,E8,CC,55,6A,5E,CA,97,4B,39,C4,FC,59,91,23,C6,AA,DE,47,88,68,DF,59,0F,92,C0,D0,79,00,A4,22,62,BE,D7,EE,C7,CA,E1,06,AF,A5,28,B1,FE,B9,68,AC,A0,D4,05,B3,8C,B7,09,61,A6,B5,E8,3C,80,C3,BF,A4,17,C5,D0,A5,13,CB,40,30,37,A5,E3,10,BA,BA,24,01,77,66,5F,07,92,17,C1,AD,84,30,7F,21,E7,74,0B,0C,14,00,08,58,E6,60,13,05,A2,34,3C,10,35,9F,CF,0C,40,64,26,47,52,74,F4,A7,B2,B4,A7,D7,07,A4,4F,77,D4,15,99,7E,51,27,06,67,13,04,8C,3A,31,E1,CF,7F,72,4C,7F,1D,FD,C4,DF,E7,DC,A8,32,41,C8,F2,05,D6,03,74,ED,94,B9,DF,44,94,AC,AD,EE,76,68,CA,68,C8,B1,B0,7A,74,EC,6B,AD,BF,30,8C,A1,6C,A4,0B,F3,A4,27,AC,D4,BA,DE,9A,5B,55,C0,01,E6,5F,A7,E5,2A,35,8B,06,D7,67,7B,46,46,6A,CA,DE,6B,50,4F,EB,3D,A1,62,E1,0F,25,A7,D9,FD,45,B6,BD,0F,D8,A3,B8,13,FB,EC,50,6B,BF,6D,A8,B5,63,93,92,49,62,57,23,41,B9,47,EF,54,E1,24,C5,B1,F2,EF,3E,F4,7D,C8,5D,DE,42,28,06,51,89,BB,6E,89,F7,BE,CA,74,C3,35,03,E9,50,ED,37,27,9A,0A,6F,CD,62,49,71,32,F9,FB,60,A9,23,69,72,1A,15,5E,A7,F1,6A,00,46,E0,33,D2,47,30,82,72,F7,96,08,05,5A,B6,4A,AF,18,2B,AA,4C,07,B3,0F,DD,32,9A,A6,2E,20,2D,4F,2E,E9,27,76,1F,96,7D,BD,A2,4D,EA,AF,9E,16,EA,48,1C,6B,D2,16,DC,B6,52,C1,BB,76,FF,82,D5,1E,D7,ED,99,D8,3F,A7,0F,F5,95,85,5D,96,FB,86,73,23,A4,1D,DC,CA,57,3C,93,E7,F2,C1,46,04,03,25,BC,B9,08,21,6E,31,53,EE,6E,55,60,68,E5,CD,75,46,6D,71,BA,E9,D6,9D,14,DC,49,7B,90,A5,F6,F2,29,E0,54,C1,AA,CD,BE,B2,30,E1,7B,CF,6E,CD,5A,3F,D0,CA,A9,99,0A,36,85,7D,F4,97,CA,28,91,A9,AC,36,2E,8C,D3,6C,17,CA,5D,E7,08,F1,8F,AD,9A,40,C2,80,B6,61,A6,9D,ED,61,03,9E,25,C8,19,7C,BF,4F,6E,42,15,2F,62,3C,F0,81,62,31,0A,C7,24,F1,AA,F2,7A,05,D0,1D,A6,B4,78,6C,36,2D,FB,C7,A4,FA,23,0A,A8,D8,51,B5,D1,C7,09,24,15,A2,40,AC,CA,7F,57,04,F1,79,AF,A2,4A,61,25,EA,B6,99,DF,1A,37,7C,37,43,32,4C,AE,C0,9C,5D,71,99,69,95,A1,C2,3F,CB,B6,C3,AC,F6,73,A3,5E,ED,02,2A,DA,71,BA,B2,F3,76,EE,C8,24,16,6F,C0,E1,A8,46,16,69,08,95,D4,2E,BD,A4,88,98,98,5D,2A,FE,D3,69,86,09,02,67,57,BA,C8,0D,7E,70,4A,30,9D,84,D6,84,19,9E,8A,94,56,48,59,52,97,A6,55,16,C9,48,66,3D,4E,50,B8,94,80,F0,54,7F,63,4F,30,E3,65,1E,0E,E7,FF,00,5A,44,7A,8C,59,57,76,B6,AC,70,AF,1E,0E,62,DA,7E,86,B1,19,5D,CF,27,C2,45,AA,21,76,87,B2,6B,31,9E,F3,A6,BC,50,6E,C5,D1,83,5A,4A,E3,7A,68,C1,C0,11,26,7B,DB,4C,02,86,CB,71,78,E5,5D,BC,CF,98,D6,7B,0F,5A,A4,C6,83,A6,02,28,89,A1,72,50,C8,64,F0,15,DF,EF,BF,BB,6F,D4,EB,02,6A,9C,54,99,B0,82,9E,9D,5D,90,2D,0F,5F,90,85,47,A5,A8,61,A0,B7,6C,12,0D,36,49,3C,4F,C5,5C,A4,F0,D0,10,6F,EA,AF,C1,2F,E6,CB,8F,B1,F2,CD,F8,A7,23,9E,37,9C,7F,8A,C1,7B,BF,C7,66,61,00,81,F0,C4,C4,8C,48,C8,7E,25,63,93,D6,2A,2F,62,B4,08,DB,C2,3B,79,CA,1F,D3,54,31,EE,7B,F4,14,12,00,D0,86,A9,25,EA,CD,B4,E1,AC,BB,4A,B8,DA,F6,10,E6,5E,4B,38,01,BF,C0,94,2B,97,7C,B6,DE,79,A3,F1,4B,3E,7F,C2,69,F4,E5,8E,39,F9,05,73,0F,2D,D4,BD,9E,20,39,F1,13,27,91,55,4C,4A,B7,FB,0B,F3,7D,39,57,0B,20,CF,25,66,0B,13,14,6F,61,E9,9E,EE,FC,AD,70,ED,0C,5D,F6,F0,E9,87,EA,4C,52,DD,73,8A,E0,F1,33,BC,A4,3B,DA,4C,C6,EF,31,E3,57,43,40,B6,11,28,C3,13,DE,60,A2,C8,0D,E7,79,54,40,87,8C,E9,9B,FB,24,F5,D7,3A,91,7C,A6,EE,3E,F7,93,F2,E1,09,0B,3B,D4,08,6C,1C,7F,85,D3,9B,82,78,2E,C8,45,E0,5B,E1,7B,F9,86,70,F6,08,20,59,61,9C,9F,55,76,FC,30,C2,4E,58,10,DF,48,9C,07,47,6A,7C,40,D6,FD,88,BA,A4,48,7E,C6,05,43,96,1B,42,94,96,EF,0C,27,22,AF,82,43,B7,1B,41,18,FF,EB,F6,A5,73,74,66,83,60,90,D8,F6,67,CB,80,85,B8,14,53,0E,29,EC,F2,B7,97,56,0A,4C,FA,88,A5,23,F3,F1,DB,B4,EE,12,AE,24,F3,56,69,83,96,F2,C1,3F,2E,DF,13,B0,F6,BD,9D,43,67,6E,9A,43,33,75,A5,22,CC,32,60,AA,DE,5C,92,F4,70,26,32,5B,BD,83,FF,1D,DA,5F,74,A2,7C,1E,B9,C1,94,C9,E3,21,25,D7,56,76,CF,1E,F4,3C,96,54,46,6F,0A,AA,15,D6,13,0F,97,E4,0A,F3,1C,97,CC,A6,81,D6,59,B4,B3,BC,05,38,75,CB,45,CC,70,79,47,35,DD,55,01,C1,65,54,C2,41,5A,5D,20,D3,86,22,4B,F2,95,10,51,F4,D2,B2,63,E7,CB,8F,E8,39,AF,3A,7A,D8,60,33,2D,52,D3,38,8D,62,D1,F4,0C,28,E6,8B,D2,63,D1,2E,3C,14,4F,39,41,4C,61,EA,01,F1,4F,56,56,D6,CC,64,4A,FA,3C,FD,0F,18,0A,D7,B8,59,12,40,87,6E,E2,EB,EB,B3,E3,5C,EC,54,D9,1A,E6,22,A1,59,0B,A8,84,F9,E8,44,08,27,D8,78,C9,0E,DC,5A,F6,A2,3E,08,9E,CA,23,44,21,91,0A,C2,68,AD,E3,29,AF,10,C3,B6,A6,3E,56,8A,4E,D8,76,C7,32,9E,C6,BC,1F,49,BA,7D,D5,CA,58,8B,DE,B5,ED,60,75,89,CC,90,82,EA,18,50,2A,5C,A0,81,5D,06,94,89,FA,06,E6,EF,FF,45,4C,A1,E2,A0,DC,40,1F,08,88,12,CD,1D,23,93,82,58,30,A5,7A,EB,2B,33,61,E9,C6,A6,16,13,1C,7B,25,CE,EB,BB,F4,C9,AC,75,09,66,DD,77,B5,81,A6,0C,D5,6B,A1,FC,17,ED,CB,10,FF,92,58,08,79,48,6C,96,B3,F7,03,71,6D,C8,DC,DF,A4,EC,23,34,D1,A5,1F,F2,B9,E1,C9,B0,F5,44,53,F5,E9,40,49,35,6B,C8,AE,28,49,5B,AB,5B,11,34,20,D1,97,CD,17,38,7F,4D,C4,B4,5E,95,C2,5A,8B,7F,5E,C9,ED,62,0B,88,2E,58,E8,65,F9,12,7F,40,10,56,1F,96,62,25,90,6E,08,53,2B,41,C4,85,B3,DE,4A,A8,77,51,88,9D,10,58,02,FB,64,92,0A,F9,0B,C7,B8,EC,ED,DF,B9,37,1A,22,AB,10,AB,97,5E,3D,3A,F2,6F,8D,65,A2,78,47,16,19,F2,0D,B0,51,F2,8A,B9,09,E5,19,94,A2,99,A6,FF,9D,54,4D,37,3E,7D,33,94,83,7C,2B,92,D0,35,2B,4D,C2,2F,67,D0,74,25,60,17,C5,B0,B7,CA,D1,C3,4F,D9,22,79,26,F8,EE,75,51,B2,22,80,CF,3B,48,82,DB,9E,BF,73,FA,C4,FF,03,E8,32,5E,1F,A7,A9,07,8C,D9,44,F2,1D,9E,0A,12,19,B3,41,36,97,D7,7F,BF,23,23,FF,9E,FB,29,68,2B,4D,11,DF,E3,94,B5,A4,E9,E8,4D,2B,A7,EB,02,47,86,02,5A,E8,78,B7,31,C0,66,EF,35,B7,E6,A8,BA,4C,11,12,87,24,49,D7,BC,AA,7B,57,3A,7D,3D,FB,6B,0E,D8,99,51,17,05,0D,11,BA,10,1A,FC,38,8D,FE,C3,FC,E0,6A,5F,66,C6,4C,48,9E,02,C0,C2,0E,7A,4E,86,7D,85,EC,E8,71,F8,80,61,03,03,30,6B,2A,BC,89,A6,18,1B,2A,C6,D9,1F,81,82,1F,57,C3,FA,95,DE,7D,CF,9F,DC,B2,B6,53,64,B0,61,7E,B7,8B,8D,78,35,66,83,16,C1,F0,9D,E4,D3,D2,8C,81,D1,92,C0,48,C0,26,D7,2E,35,9F,D7,28,AA,54,D7,97,77,0A,24,8A,76,5C,49,84,72,E0,1B,23,52,C9,EA,CA,4F,C6,EE,22,BE,83,AE,8A,40,ED,49,BE,FD,95,4B,B1,B9,52,4B,99,B6,39,DF,18,CB,80,0A,33,91,E0,D7,5C,CE,C5,86,B7,F8,87,00,15,C2,48,F5,3F,0F,6B,2E,2C,07,18,EB,7D,5B,9B,7A,B4,4F,EB,08,8F,C7,43,BE,D9,9F,61,D0,A6,B7,46,27,02,FA,B3,C1,53,6B,1A,3C,67,E5,EE,8B,13,24,90,66,A4,C1,AE,3A,B4,B5,F8,50,44,23,E5,0E,0E,51,C0,24,24,AF,B6,63,86,BD,5E,9B,44,CC,6F,89,A9,CB,E4,D6,46,48,97,25,93,ED,F0,78,5F,53,1A,AD,57,DB,A3,97,3D,4B,7F,C4,70,AF,AC,63,49,6B,A9,BA,22,3E,3C,8E,66,A5,47,22,F8,74,82,17,7F,AC,38,17,E0,96,42,FA,3C,0F,ED,EE,C8,64,34,4B,90,CD,3A,06,9C,2A,D2,A7,DC,0F,F6,19,F9,6B,1D,05,54,9B,5C,8F,80,C8,AC,44,E2,1C,49,82,67,05,36,8D,42,08,BF,90,1B,8C,1D,30,A8,42,F0,85,24,B9,21,7E,33,D1,71,B8,64,E7,31,A7,BD,7B,A3,79,79,A3,20,DC,B8,C0,EB,2E,88,BC,4C,53,1E,CD,FB,B9,27,2F,DE,D3,7A,9D,8D,4C,1A,CB,27,74,B6,31,07,AE,B2,EE,54,B5,F4,1F,E1,7F,73,DB,92,E6,D2,F4,10,5D,11,AE,B8,23,B3,83,51,54,06,75,E7,03,51,3E,C8,45,A4,35,6E,D1,11,80,C7,B6,61,5E,64,F2,42,27,89,87,25,B2,86,25,7F,02,1A,60,6B,36,DD,79,CF,A4,FC,1C,E0,49,D2,62,8C,BE,7F,7D,BA,B6,BD,0A,D2,21,18,79,AD,47,03,A6,A3,A1,FE,0D,6C,E9,91,B7,ED,38,3F,27,A7,AF,70,1B,D5,D1,5E,45,1D,08,49,1F,12,63,65,19,C4,87,52,04,6B,72,F4,B7,E6,82,46,10,E4,83,58,44,3F,6F,92,BF,88,E2,87,01,EE,10,85,DE,4A,77,9D,0F,57,8A,A5,DB,89,DD,3C,F9,A5,AF,23,3B,1D,0E,CE,63,0C,C5,91,F5,2C,18,8A,67,5B,E9,B0,5E,0E,77,9A,FE,A7,07,C6,C4,99,69,A6,61,23,DF,ED,D6,B6,B0,E6,13,4C,CC,5B,37,41,03,6F,BD,98,58,15,A3,76,FA,DF,8C,0D,25,4E,C1,F4,57,DE,46,09,77,7B,38,4F,49,25,CB,D8,76,3C,76,1F,6D,6F,AC,DB,0F,F5,56,DA,82,40,85,7C,12,91,E9,9D,31,C1,96,6A,73,B4,D6,26,0D,4E,73,F4,2E,C2,03,2A,0A,C6,80,0F,A5,59,3D,AA,83,40,0D,70,93,CA,48,32,21,09,2E,A4,F8,14,A5,40,EA,74,BC,92,77,04,1D,E7,2F,BC,F6,03,FD,98,D9,B8,CC,B0,8A,C1,E4,B3,2F,C2,9B,B1,82,66,CF,E1,CD,4D,3A,00,E7,AA,0F,6A,3F,92,07,65,F9,9B,3F,97,B9,5A,67,14,4B,2E,B0,60,41,BE,CC,AB,24,05,28,36,B3,B4,98,C2,74,88,79,AE,5C,23,00,9A,D5,27,1F,5F,24,3C,66,C9,E0,F5,81,DB,68,1A,10,62,77,2E,8C,8C,A9,DB,70,35,DE,B1,0C,CF,F3,CB,8F,06,0B,E3,E7,22,0F,D4,0D,A8,2F,6D,4C,73,F9,5B,4B,BB,F4,86,0E,12,C3,B8,FA,C1,A3,A5,75,C8,62,18,A3,7D,94,D0,8E,EB,45,BA,B1,19,5C,2A,0D,67,36,23,55,3E,66,65,CD,B0,9F,DE,C8,80,98,B2,96,CA,57,93,90,D4,FD,E7,00,61,80,C2,94,8A,BE,5E,1B,83,C8,12,D2,4C,AD,3C,47,EB,A4,05,E9,8D,04,80,B1,C4,6B,0E,42,17,52,F1,27,CD,A6,9C,4B,81,FA,3C,46,C1,32,5D,39,FB,BE,4B,0A,CD,94,18,F8,28,78,68,0E,A4,42,56,C6,80,22,07,F4,4F,55,44,9F,D3,FB,57,14,12,11,C7,3A,F2,14,58,A2,93,ED,FB,49,EB,54,3F,86,B8,96,8B,93,D8,64,BF,9D,DF,E1,24,33,4C,B7,D1,86,99,58,81,AA,7B,F5,C7,9E,17,8F,45,F1,F5,83,DB,D6,72,CE,0B,4C,12,8B,89,CC,7B,ED,20,C3,FD,D1,F2,C1,D4,58,27,64,A8,E3,11,AF,62,D9,20,34,C6,ED,EF,6A,BE,8B,BE,D4,70,13,FD,6A,A5,40,C6,37,07,CB,18,FA,35,8D,D5,6B,51,9A,7A,F5,6D,D4,B4,AF,D1,B9,F4,09,09,14,0A,41,4A,C4,4C,9D,EE,91,46,55,D7,B4,82,C5,D5,CF,38,3B,DC,C9,2F,0D,0A,A7,0E,08,E6,D5,D5,67,2B,1D,2C,C6,D8,E6,8B,FE,F6,BA,0C,1A,77,4E,C4,03,AD,62,A1,60,45,DD,79,DE,3C,05,8C,50,82,02,FD,FB,92,5A,A4,6C,8A,10,8C,14,7D,AB,F8,E2,07,20,7D,4D,4B,E0,05,F8,80,CD,A7,7F,45,FD,BA,81,B1,23,02,7C,4A,70,8A,A9,04,A9,D3,C9,12,54,F6,DE,32,27,91,80,5F,FD,95,53,41,85,91,58,A9,9C,86,0C,E5,A0,16,F3,D8,97,1A,69,6F,B6,8E,5C,78,6E,06,BB,82,D7,C3,1F,5C,85,E9,43,ED,66,75,54,D2,E5,23,D6,D6,8F,0D,AA,D0,47,E2,41,98,AB,1E,AA,54,E7,1A,A9,34,5C,D0,47,B0,6B,1E,CA,72,29,CD,CB,14,AE,78,A9,96,46,70,2E,58,1D,49,D5,F2,0D,DC,97,6D,26,0E,C7,69,2F,BC,4E,B6,D8,78,44,AA,17,35,9B,29,9A,A4,60,D6,F7,96,66,32,0F,9E,6B,FD,FA,F3,9B,8A,CC,AE,64,91,01,72,28,CD,B5,60,53,C0,22,53,C7,7C,55,1F,4F,66,3C,AE,68,1F,6E,EA,C7,D4,A0,27,63,14,2F,8E,2D,92,E0,2D,4B,90,91,89,29,E8,53,3F,87,A7,CB,69,01,22,A0,17,54,5B,81,61,56,8A,E3,A7,F9,43,7A,D6,4F,AE,71,BD,0A,BC,5A,98,99,40,16,34,01,B4,3C,C7,20,3A,B8,E5,38,FA,18,E2,8D,0E,BA,86,C3,19,AB,52,5F,72,F4,4D,AD,F6,4F,1F,6C,AD,67,DC,C0,4E,7B,00,73,36,13,C9,67,BE,9E,6F,45,65,C4,F7,87,47,90,0E,13,31,BE,F8,94,86,B3,60,B2,3F,0C,B6,FC,6D,85,12,9E,00,2A,D4,53,B9,7C,55,01,3A,F8,5B,89,24,B3,66,7E,13,25,97,0A,A1,19,27,C8,50,4C,96,B2,9B,78,AD,60,A4,92,DD,DF,C0,D5,60,4A,C7,A8,FF,0A,30,7C,0C,21,C2,26,1D,77,1B,A4,38,55,ED,0A,64,D8,91,E9,A3,AE,D7,59,8D,6B,8B,03,A1,17,75,B1,9E,F1,17,0E,A8,E0,2A,BE,B5,48,96,79,12,F6,E9,29,41,CC,0E,69,A9,48,9E,32,0F,18,13,E4,3E,ED,A6,36,49,8A,94,E0,86,EE,5F,EF,86,D1,8B,64,D0,D0,09,20,17,9B,A1,35,10,F2,B2,4A,46,2B,94,AB,14,B2,1C,DE,E1,28,03,96,BE,77,7A,01,88,A4,B2,FF,F3,9C,86,77,6B,9B,E3,9C,5A,8D,7E,B6,3B,FD,D3,04,F6,A3,1C,01,26,CD,85,12,86,D2,AF,DD,6E,AD,DF,36,C0,4C,36,25,6A,E5,C8,72,CF,06,E7,11,C2,AA,9F,54,9F,85,FE,BE,A6,A1,9D,21,22,B0,88,B3,43,25,51,B6,32,29,C4,D3,79,33,61,A1,51,42,FD,3C,68,2E,D9,03,8F,8C,3E,15,69,53,A2,D9,50,B6,18,B7,F3,0A,C4,2D,1E,42,A6,EF,18,24,62,AB,F7,0B,A1,47,25,4E,1A,CD,EC,DD,3E,BE,A7,0D,8A,AB,40,93,3F,73,84,18,70,87,CA,2F,B3,26,9B,3E,34,77,C8,D6,8D,FB,5B,89,8D,63,CA,ED,55,3E,25,01,53,53,64,3D,71,F9,3C,EA,06,F5,35,E0,70,E5,B8,D8,96,9E,16,16,09,0D,CF,32,C5,AD,E3,E3,A0,91,E9,51,22,F2,B8,01,C9,A2,0B,52,11,39,A3,98,18,3B,A6,B4,7B,FB,11,F9,81,7A,DC,3E,B4,33,23,50,10,E3,0A,59,EE,CB,EE,71,D0,CA,54,DE,D8,00,F5,0D,04,72,68,24,3E,88,55,36,7E,A0,35,4A,49,E4,E1,CE,E7,41,F9,35,34,1A,A8,C9,46,3E,E2,59,EC,56,47,66,4B,9A,16,00,16,E8,CD,25,33,AA,79,4F,34,1F,27,74,AF,65,1D,B5,D7,EB,40,B5,F9,B6,44,5B,8B,3B,AE,30,C1,3C,4C,C5,5F,41,5A,6B,4D,BF,8B,E7,27,8E,36,EF,F8,F1,4F,7C,F3,78,7E,6F,49,9C,BF,54,B3,DD,D7,D4,B1,86,8B,E2,3A,6B,A9,B5,0F,1A,B6,02,50,3E,20,2E,82,94,BA,49,F6,18,26,53,DF,11,3D,83,C8,7F,73,62,FA,28,A0,3E,3E,E2,72,32,40,0E,B9,88,FB,47,DF,17,D0,8D,7B,A7,B2,0D,50,A3,20,B0,A4,91,D7,0D,23,66,D3,B1,FF,DA,FB,3F,1C,76,4E,E4,8F,BD,6F,41,FC,C8,59,5A,C6,4F,E5,88,A8,C8,AE,DD,D9,19,CA,A5,9C,CB,07,43,40,6B,DE,FB,EB,10,E7,47,A0,2E,B8,C3,C1,62,51,8B,9A,D6,E4,61,EC,D8,22,4E,92,9B,89,B0,6D,A5,EE,83,E4,81,66,9C,47,56,96,B8,2D,B4,F6,31,38,2E,F3,C8,21,D6,A6,FD,CA,25,26,53,9C,4D,38,C6,41,3F,D3,1A,F4,09,D0,C1,18,30,04,16,D2,7E,0F,9D,21,52,DB,28,A6,DC,8E,92,7A,AB,40,7D,D8,F3,E6,CB,76,70,9D,26,6B,5D,76,67,7B,22,39,66,8E,E2,28,2C,1A,F5,13,A0,AD,54,2A,02,B0,ED,C1,E9,58,E3,73,62,9F,4F,B3,BC,0E,A4,47,49,6B,9B,53,C3,CB,68,30,11,34,4C,AF,08,EA,6B,76,F3,A0,51,0A,4F,AE,DD,F5,F3,66,6F,54,07,9A,C4,E8,FB,38,18,B3,26,09,B3,ED,40,18,8B,24,33,3E,95,BD,7B,E8,BA,55,50,93,74,67,9A,C0,8C,81,84,A7,B5,EA,CB,17,6A,55,BC,3D,A0,CB,F7,86,25,9F,89,F4,80,74,42,C4,A6,6A,DF,D5,C0,7E,AA,10,E3,F0,07,79,A7,D0,FF,D7,8E,1C,8D,F2,85,C3,FB,F1,C7,E8,5E,82,AC,AE,B7,DE,19,75,12,2A,DE,89,0B,B7,D5,2E,3B,A5,53,27,37,1F,DD,E3,84,B5,D7,98,4E,21,85,5C,89,07,AF,D9,74,86,34,1C,73,66,4C,ED,1B,3C,EE,CA,A3,12,EF,16,D7,C8,46,5E,64,A7,99,B6,AE,78,AC,DA,D9,4A,07,ED,EA,F4,09,3D,23,0E,9B,35,74,AA,5B,F2,A0,BC,8B,11,F6,9C,56,E0,E0,42,EE,0A,EA,77,A3,59,06,44,A3,07,89,9E,D7,37,95,B2,93,3F,73,CB,63,6C,2C,37,9E,80,B4,45,BB,86,2F,EA,5B,7B,8C,00,83,9A,68,68,44,AB,48,8C,97,3D,1D,4F,84,54,30,2F,8A,98,59,06,9E,D4,0B,C9,DC,E2,9C,8A,55,B1,9A,51,01,EC,8B,B7,6C,21,76,2A,C7,CA,B3,00,A5,25,12,1E,13,4F,5D,1D,9E,AB,3A,5E,4B,3F,E2,63,5F,3D,A5,E3,FB,EF,82,C5,FC,B1,C8,1A,0E,3D,08,44,03,EF,54,AE,E2,05,DA,62,E5,15,3E,93,53,21,23,71,1A,4A,56,DB,19,25,EC,67,7D,84,2F,EE,E7,65,87,75,7A,D6,9A,22,5D,55,22,9A,ED,18,06,E5,6F,65,13,45,50,03,00,30,58,AC,E3,F9,BE,C5,F4,F4,BB,03,05,3C,E2,DE,98,BA,D1,6B,21,E6,E2,FE,C7,52,7D,CB,0D,8D,BF,E8,10,E3,9C,0D,81,6A,25,3F,51,4A,1B,C8,A5,DB,0B,6F,52,0F,85,3C,02,88,EF,6A,3D,EB,8E,30,79,C0,AA,80,2B,8D,73,79,DA,27,FD,46,82,EA,57,7B,D3,A7,C6,CF,BC,54,FC,B6,04,03,16,F5,10,58,88,1F,C0,E5,A7,54,6C,A4,E6,DA,A4,53,B7,36,40,B6,DD,FB,BC,8D,03,4F,96,B1,BA,52,68,C3,97,12,B7,7E,C1,D4,EE,3C,B8,AB,A8,24,8A,13,3A,D7,2F,C4,7C,98,D5,01,8E,06,59,90,CF,02,52,54,B8,BE,D0,DD,57,41,B0,2E,38,29,0D,B0,6E,5D,2E,EE,CE,E8,AA,C1,A4,74,16,6D,ED,82,5D,F0,C9,84,DA,82,AA,10,7A,31,5B,A2,05,1E,69,B7,9D,C7,B8,17,57,E0,F4,D1,1C,7C,BC,0A,06,4D,F3,DA,73,97,65,BC,1E,01,B2,8D,08,A8,9B,91,4E,52,02,B3,FC,FC,76,EB,3E,DB,43,3B,A8,A9,CB,EE,9A,78,2E,D4,5E,F9,F1,74,4A,FD,F9,C4,5A,54,10,C5,78,73,70,5F,1A,27,BE,1D,28,4B,99,70,34,13,C8,00,08,E9,99,35,7F,43,D9,59,C1,1F,72,BC,25,35,51,B4,39,C4,64,9F,B2,CA,03,3C,F7,B4,5F,2A,56,36,3E,2C,BF,BE,36,1D,36,94,57,F0,33,39,FE,74,E2,CA,E9,65,D5,A0,BD,80,DB,72,96,81,EA,A4,8D,F6,06,FF,D1,62,28,EC,EB,0F,DA,5C,5C,B3,53,DF,3F,AE,9D,9E,22,1E,5F,A5,B1,62,60,10,A3,85,B6,EA,C4,B5,B6,80,14,CE,00,63,47,45,23,46,C5,A3,DA,6F,0C,88,51,5F,10,75,F5,E3,CB,17,13,F0,AF,EB,60,00,71,83,9D,CC,DC,28,D3,FD,35,7B,0A,BF,B9,44,2D,36,9F,C1,04,98,BC,23,C6,64,49,FA,4F,FA,94,2A,8B,01,24,4C,7A,76,8C,68,83,20,41,38,AE,BD,58,A9,41,11,DA,EF,B3,DE,62,73,DE,24,6F,5F,B5,9A,1F,6D,72,A3,DE,EC,63,8D,A8,5E,ED,F7,95,23,26,6A,DE,DB,D5,0C,4C,8B,C7,5F,C7,A4,18,13,99,4A,1A,1B,51,75,44,F1,7E,5F,B9,77,1D,FE,3E,A9,70,8D,60,5E,75,4B,C8,21,5B,F0,BA,7D,BF,D1,CA,16,55,1E,BF,E1,FC,D4,9F,FA,E9,2E,DB,B1,E3,8E,09,74,58,51,88,FF,E9,9D,8F,A3,0A,D5,CC,2C,81,72,A4,21,EF,2C,33,8B,5E,FF,EA,DD,B4,B7,96,FE,86,50,F7,DB,C3,4E,30,81,45,93,2C,DB,69,49,37,4E,AC,BC,CD,05,21,8E,0E,DA,CB,CD,2C,7B,90,E3,C8,C2,5B,F2,96,34,DA,40,D7,C6,E0,18,C4,7A,A0,FA,B5,7E,DC,9C,2C,3C,ED,5C,D6,A1,4D,DB,F4,3A,66,61,FC,78,9F,0C,51,BF,62,7B,CE,56,1D,2F,72,2E,AC,3B,6F,54,82,07,9E,62,7E,AD,DB,75,EB,CA,78,C3,31,3F,D3,54,DB,FA,92,45,A6,E4,5C,A1,96,D0,47,DB,76,E9,B3,6D,7F,B4,7A,19,24,32,83,D8,E1,3D,2D,F5,DD,C6,68,CB,E7,2C,85,77,FD,DC,C4,F9,34,05,7A,A4,96,5C,27,94,7F,FC,F1,CB,D3,34,D5,9E,41,9D,DE,04,F7,71,94,21,6D,DE,61,4D,C7,BA,96,1D,F3,92,9A,CE,1D,5F,B9,54,9B,C9,25,A1,96,CE,F4,29,0E,CB,4A,08,2D,20,C7,6D,B3,5E,B3,EE,A9,E6,EB,0F,EA,D4,08,79,C0,1E,71,26,F3,4B,40,B8,F4,F4,C4,CC,44,C1,49,F0,D3,88,CA,59,44,32,57,E2,D0,CC,B6,D9,61,FB,3C,23,C5,36,AD,B6,4B,98,13,E3,65,08,1F,A6,CB,30,0B,CC,7D,8A,20,C9,7B,50,5A,E5,77,BB,E4,6A,B5,7F,95,8D,CD,F9,15,EE,AC,F1,7A,F0,9B,8A,FA,F1,CB,74,CC,FF,8E,C4,E1,50,FE,3E,B9,5B,91,FF,29,B9,90,86,D8,8E,2F,19,EA,CA,38,05,6E,4C,F7,FB,14,93,70,9F,24,C2,8B,06,AD,A5,B2,A8,7C,C8,57,38,88,6A,1D,B7,38,08,30,16,C3,90,4F,6D,44,70,46,CE,90,9E,A9,17,5E,9D,27,66,9D,B6,52,08,2E,63,A1,BF,BB,A4,D1,FE,2E,66,D9,B4,CA,9D,2D,6B,F6,76,C7,EF,0C,97,A4,59,9D,84,E9,CC,06,8F,1D,62,21,F7,3E,62,96,F0,57,37,FE,36,8D,50,4B,9C,D9,74,B4,02,6F,4B,D8,1E,91,86,D5,AF,E4,40,DD,02,73,D0,A9,8E,54,77,26,A3,1D,A1,B4,2A,B7,D5,BB,FA,30,AB,2C,84,F3,04,6E,33,8C,0B,B4,84,BB,98,DF,46,63,60,E8,8C,4B,C3,28,DD,B9,77,B3,BB,D1,B8,D0,33,7D,C9,8B,B1,8A,68,96,19,4D,1A,A9,9C,85,3E,E6,E7,EA,9A,66,79,CB,3A,CB,A4,CA,0F,91,06,15,71,8E,C3,99,25,47,75,6A,D7,D8,F4,EC,28,71,BA,B6,DB,0C,6D,39,D8,95,D9,95,44,03,F4,C9,8B,2D,3B,E3,2C,1E,71,B7,88,0F,D0,B5,05,CA,8E,AB,1B,98,D5,E5,D7,C4,B5,09,E6,BA,96,10,1A,57,EA,D7,97,EF,62,FE,03,31,50,72,4B,17,51,5F,11,C8,A5,12,E7,05,6D,0E,51,0F,48,D2,02,76,BA,D7,6D,C1,3B,B0,83,7F,0B,9E,71,70,C6,14,E0,9F,39,E4,DB,13,B9,B0,07,BE,8B,10,E0,FC,FC,A8,E4,C2,32,02,68,4F,54,CF,7B,77,02,44,EA,C5,91,7E,CB,67,F4,5F,83,B4,6E,9F,1D,AC,73,47,1E,24,49,E2,D2,BF,BB,7C,09,E5,7E,FA,65,4A,E4,3E,4D,E5,05,00,2B,6E,55,82,B9,54,1D,E1,52,A0,05,AF,62,F1,A9,AF,66,3C,97,55,AF,D6,A1,A2,F0,56,10,6E,5E,94,CE,CE,5D,D6,62,15,64,8E,6D,87,93,4D,8E,B3,25,83,E4,CE,D0,3C,84,A0,98,AE,FA,7C,ED,7B,0B,D5,39,57,03,45,CC,CF,9D,24,CE,9B,79,BB,D4,C0,5E,38,07,C7,6E,FF,66,88,CE,AC,F5,77,7A,D9,EC,1F,3B,46,89,45,A0,94,74,E0,79,CB,F5,CA,8F,73,4E,9B,56,F3,30,4D,A6,88,62,8C,5F,38,46,B9,23,0A,D0,8F,12,35,D2,B9,12,EF,38,85,86,F5,FE,89,B9,B7,27,CC,CA,02,9A,05,42,4E,92,FE,28,9B,43,66,A1,2A,68,D2,B3,BF,72,E2,DD,59,85,4C,AF,95,72,B5,33,4F,4D,90,A8,AD,9C,96,32,07,96,B4,6E,35,68,92,23,05,29,7E,7B,9A,07,30,3B,90,09,3F,83,D5,34,6B,A9,48,A4,81,9A,EB,EE,33,FA,0D,B2,82,9F,33,B3,37,9B,4F,F9,FC,82,3B,33,36,CE,C7,9D,6F,1E,1B,AD,01,81,CF,C4,85,B8,DC,05,EE,18,76,F2,AB,B4,3E,47,47,23,E6,88,2B,78,2E,05,6F,56,C0,EA,FF,1D,D8,79,18,58,46,34,39,DA,5B,77,31,4D,76,3A,9D,57,56,48,37,22,33,F1,D0,EF,37,B6,45,E1,5E,7E,1C,E7,9B,F2,83,14,7C,8C,5F,C3,AE,17,2C,45,55,58,FA,1C,1A,7F,82,DC,22,76,2D,02,D7,AA,41,86,48,11,82,D6,32,4A,BE,01,0F,75,6F,B3,DB,1F,30,0A,73,A0,89,B6,E6,2C,91,8E,2D,D1,35,14,B6,CB,A8,4D,49,51,79,DF,39,23,F9,82,45,5A,2E,0F,A8,5E,FA,41,57,84,DB,58,27,52,B5,4B,38,EC,CE,A4,82,90,CF,D1,97,51,02,0D,E6,B0,9C,21,5C,42,A9,29,F9,BB,22,2C,37,D2,54,72,58,83,66,CE,6A,87,FF,49,DF,19,79,5F,36,2F,13,72,71,3E,A5,87,0A,8B,D6,83,32,C3,90,AF,2D,B2,D1,67,EB,B1,9C,EA,AE,9F,67,0D,47,D1,A2,3C,7B,B9,CD,49,97,60,3C,11,70,A8,F8,FF,12,B5,41,F9,24,3C,56,83,3A,C4,9B,B7,0D,0C,FE,61,F1,2B,8B,17,8A,B9,D7,10,8A,3D,3D,90,97,F5,C8,E4,15,28,A3,3B,DF,A8,05,B7,14,A7,0D,96,25,88,F7,F2,91,20,12,56,11,03,6F,A8,83,26,E2,E1,83,13,64,8B,8E,8F,23,6A,DD,2E,82,73,BD,AE,77,5F,38,50,BF,42,D8,BD,6C,51,D5,0E,F5,6B,F0,52,67,5D,74,DC,7A,30,9A,DE,22,1F,31,AE,2B,AC,96,51,B8,F6,3D,79,97,8C,F4,B4,F3,00,2F,32,BE,87,46,9B,EE,6D,1F,65,09,F2,39,D1,5D,88,53,CC,52,6B,F5,49,E0,51,69,8C,23,DD,FB,3C,61,30,B2,01,B5,1C,8D,9F,FA,A3,C1,B7,89,CF,A2,F9,CE,44,37,E2,8C,83,DB,A3,08,6F,31,4A,6E,EA,85,CA,50,F0,F3,AA,40,36,E4,0A,F6,EE,7E,FF,50,8B,4F,50,0D,91,7D,98,DA,0D,DE,DB,C5,70,AA,33,0A,97,2B,E5,58,E9,A4,3B,44,07,BA,46,0A,3E,02,30,27,E9,27,15,90,5D,AD,88,5C,B7,28,F3,17,91,B2,45,1E,DB,37,BE,EC,ED,58,B2,AA,85,6B,A4,1A,8D,AA,B1,8D,7A,10,9B,7C,50,53,98,93,43,D3,A4,2C,8A,E7,4D,D4,C5,3B,F0,D8,16,C7,CC,83,96,4B,7A,BA,20,98,BA,5F,BE,96,16,2C,78,F6,F8,89,EA,C2,C8,B0,D4,CB,A4,44,27,FC,D7,C9,46,89,F2,84,02,03,9C,2B,35,04,BF,E9,08,99,8C,AB,91,E3,42,0B,3A,34,A0,D5,07,53,4E,4E,47,6A,64,A6,82,3E,57,4C,DD,05,FB,AC,5C,B7,A5,40,D3,28,66,3A,77,ED,E2,CF,90,C8,EB,0C,DA,72,FB,12,D6,2E,B9,76,E9,A5,56,95,8C,D5,C9,5E,1B,A8,CB,08,DE,10,9F,AD,A9,DE,9C,AA,D5,7E,71,F1,28,D1,01,FE,57,42,23,7A,63,CD,4E,A1,D6,65,9F,7A,B2,B2,CA,A6,8A,11,3E,C7,4E,FC,8E,01,ED,07,A7,3E,F6,8E,48,7D,BA,4A,7E,99,30,4B,7F,10,7F,4E,EA,AC,8C,59,A5,A6,95,3B,09,F0,11,08,82,A3,4E,98,9C,CE,DA,FC,61,9C,53,23,AD,2B,23,6A,3E,9A,6C,FA,8C,1F,BA,3B,A2,2E,29,51,A4,57,FB,98,66,B8,9E,F5,F4,85,EC,95,8C,01,3C,F3,77,69,01,6A,CA,D3,EE,64,2F,26,AF,10,1F,41,28,C8,03,BC,69,DC,6E,EC,62,AF,48,FF,61,EF,8F,3F,9A,3D,7B,38,2D,AF,2F,5D,D5,A3,AE,E2,D1,5D,AB,DF,07,03,42,B6,6E,BC,A8 -linearMatrices_inv = B5,80,8B,96,63,3E,60,91,5B,87,44,17,A4,C9,5F,9F,20,7C,B3,E9,14,31,69,A2,F5,74,DB,8D,6F,81,DD,F8,D6,81,03,AF,31,65,49,04,A9,1A,48,4A,FB,36,2F,DE,75,BB,C0,80,0E,AB,B6,1A,1D,A0,53,20,FC,D2,6B,F0,26,35,26,FE,43,70,4C,1E,37,20,F2,88,D6,C4,27,94,5B,C5,74,02,83,DA,EF,99,DD,56,3D,2E,62,FA,AF,AC,5C,80,05,15,16,67,45,1D,D2,0C,BE,D5,D5,85,66,E9,C3,D2,76,5A,B5,45,31,73,12,F0,DF,BB,A0,72,29,0E,B6,A8,17,19,A1,8B,DD,EF,29,A4,8E,4E,A2,EA,66,3C,D0,AB,11,F9,D3,FA,36,02,19,75,7D,05,EA,E9,0F,80,9E,78,90,BC,4F,29,A2,67,CF,8D,F8,C3,46,3E,C3,CD,DE,AB,9D,FF,33,A5,D5,E6,12,E1,10,C6,9C,FC,DF,B0,15,18,11,1A,9B,41,7B,1E,78,FE,E3,DC,D2,CE,90,13,56,82,C5,F9,FC,35,73,0F,6D,E1,77,44,B8,E5,95,14,A3,B1,01,47,5C,2F,6C,8A,EF,9A,F0,61,EE,70,FD,1A,9A,54,FB,29,A1,0C,3C,EB,58,D2,FB,CB,A1,5F,C9,62,46,FB,7E,9A,FD,B0,1A,97,0B,E4,04,E5,AC,FF,B5,D6,3D,7B,DE,67,46,11,19,68,EF,B9,47,43,93,05,D7,2C,B6,16,9B,2F,9E,05,12,3C,7A,9D,4E,BE,04,13,A9,B1,A2,D5,DF,03,80,E4,39,41,9E,C1,3E,66,D4,5E,AB,C2,40,6D,45,6E,13,F8,2D,D3,87,70,75,0D,73,DC,55,91,D7,9C,2C,AB,C5,67,7B,CE,92,FD,48,01,0E,A8,A0,10,DF,84,3D,86,10,F0,1D,E7,B3,DB,67,97,69,77,11,54,4E,C1,AD,67,48,A1,7B,67,13,D7,20,E0,2D,8B,80,D8,00,F7,34,4D,2B,15,BA,ED,51,62,C8,14,2A,BE,9F,B0,67,06,A3,9F,4C,76,91,83,29,EF,E2,2E,F0,71,10,8A,8E,D5,20,78,40,E5,FA,DD,05,B7,57,B8,65,4C,C8,35,7E,F9,27,AA,D4,95,44,91,E1,E7,C8,FA,16,90,58,AE,B7,69,57,23,0E,F9,A7,1E,AB,0F,A1,CE,0E,8A,31,6A,FF,2C,44,2C,4F,73,FE,53,3C,92,CE,14,EE,52,A0,60,CD,79,C5,DD,10,65,D4,93,B5,8D,DC,8E,E0,F3,DD,DA,C7,68,B9,25,37,C9,AE,B4,C2,4B,7B,E3,1A,9F,78,46,03,78,E3,CD,BD,BD,37,74,C2,70,C6,28,EA,C8,8A,5E,03,92,38,C0,7D,67,95,98,88,D8,6F,EC,BF,F3,62,34,84,DF,A7,8A,65,AF,71,30,DC,AB,17,E7,FE,C3,BC,26,E6,84,D4,BF,5A,F5,BE,41,3E,66,05,73,24,3A,4A,44,FD,F4,E4,86,0D,9F,36,7E,13,74,51,48,B3,74,C1,BD,FB,CA,61,BC,88,7E,17,50,06,47,96,3C,12,0B,1B,3A,3B,BA,06,BC,2A,3C,E3,09,2A,A0,17,C2,6D,45,4D,8D,13,71,F5,B0,1B,AF,3A,C0,34,40,FF,A2,A9,A3,CE,D8,F0,22,C5,F5,0C,1F,43,0E,A2,A3,CD,F5,93,7B,38,6C,95,9D,EA,F3,B6,0A,C2,FC,18,AA,4E,37,6C,56,B7,C8,88,E8,B9,A5,CE,2D,6A,E8,A9,6F,F2,B4,D2,02,08,42,09,B0,9B,9D,90,91,9A,46,82,F0,A5,76,E3,92,C9,C8,06,0D,36,8C,20,F0,A2,2C,7B,95,29,F8,5A,19,7D,86,3A,D5,A9,9A,94,5F,61,33,A0,F1,6F,C6,B9,BE,14,D4,AA,CE,00,1E,5F,31,66,27,7D,EC,9D,66,4B,BA,82,C6,E4,0E,61,66,96,35,9C,E3,F4,04,DA,88,E7,D1,61,66,CF,4D,DD,72,28,13,03,D6,19,F5,B7,3A,A9,36,9C,37,57,6C,67,EA,C3,7F,A8,E1,6E,14,75,EA,16,B5,77,9A,DB,39,FE,51,71,15,FA,03,AF,97,75,CF,BC,23,9A,F7,AB,D1,DE,37,92,2A,67,4A,CD,84,6E,05,32,C0,21,7C,77,95,1A,33,87,E6,1E,81,1A,84,99,71,C7,47,B6,E0,08,1C,A1,E7,F3,ED,D8,BD,AD,50,CB,2D,96,8C,17,00,42,70,63,9F,E4,C8,59,1A,F2,0C,CC,7C,A6,3A,BA,B4,D8,80,22,18,E1,8E,E2,1F,F7,55,68,5E,72,06,20,60,2E,C3,2B,63,84,3F,3E,AD,05,76,45,89,98,92,D8,52,FC,45,0B,76,C8,6F,C1,D2,6A,53,1F,3B,C4,C1,97,78,21,1B,5F,72,5F,DB,E7,AA,52,DE,E7,3B,F5,21,04,A5,70,0B,07,DE,75,05,9C,A4,D5,AA,8A,44,2E,A7,73,08,8A,E4,CE,B1,93,91,5A,42,BF,36,43,50,9E,F9,BC,47,AE,D4,92,44,10,35,56,91,9B,BE,B5,77,7E,84,86,D0,55,66,DE,07,26,D6,A5,14,47,97,61,AF,BB,F0,57,59,61,4B,CC,B8,80,7F,EF,39,17,3C,44,38,99,DC,2E,18,24,49,0B,96,6A,4D,2B,39,6A,9E,B8,25,60,CC,2C,AA,4C,31,E7,1B,CD,B1,36,E4,86,3E,88,CD,33,A4,C2,92,9B,0D,E7,C0,A1,19,97,D2,34,CB,A4,44,2F,75,31,F9,F3,FA,D5,C3,B2,1C,68,27,E7,52,20,D8,B8,DF,E7,60,D7,76,54,7A,24,A2,39,77,96,6D,CC,61,0D,F4,D5,7F,67,45,BA,65,32,9F,25,DE,88,2A,A3,40,EE,EF,85,86,06,3A,63,ED,3A,6E,1D,A9,C5,7C,67,53,7A,AE,A7,13,3E,8C,F1,BB,2B,ED,51,62,1C,C9,D7,F5,68,5A,0C,84,6B,46,54,CA,A9,D6,D7,F2,16,1D,DD,64,D3,FC,BE,B3,CD,E5,8E,EE,A9,9C,35,CF,B8,96,E0,CF,92,D1,D2,64,AD,60,51,64,75,56,D1,53,BA,24,1B,D5,0D,C1,6C,F6,43,BA,49,3F,EE,7E,B9,4A,F8,4A,F1,4D,18,2D,06,D2,3F,52,18,91,35,55,54,B4,29,51,A8,CF,05,3A,37,A2,3B,36,7E,D6,6F,20,69,75,C7,DA,34,75,CA,E9,E2,80,AA,8D,E4,54,BC,0F,2C,48,6B,C0,00,C1,6F,A7,87,1C,86,5A,FB,74,52,3A,61,8B,2D,AA,33,00,55,5E,BB,A2,9B,57,2D,09,4C,9B,A2,A7,AB,8F,7D,A1,27,9B,1C,F5,4B,FE,5A,4B,23,05,AE,E3,35,FA,80,98,8F,BD,D8,12,80,5B,8C,77,29,5D,B1,6C,93,A0,7A,80,C7,18,2F,1F,EB,F0,C4,3D,7E,0B,4F,F7,11,69,57,87,AB,DC,9F,34,16,37,6A,67,EB,D3,36,D8,51,2A,AE,2D,9C,5E,71,2A,CE,01,78,42,09,18,4E,FD,5A,3D,6A,28,85,00,4C,12,F2,6D,4A,4F,0D,7D,E2,A3,8D,30,FC,AE,57,98,AD,D2,56,4D,53,D9,AB,37,8F,12,CA,AC,92,D2,C5,73,C0,E4,B9,60,CE,73,E8,56,5B,D9,86,8B,97,F5,4D,80,74,DD,B7,0E,BA,9B,A6,27,8B,86,DE,8D,4B,5C,F3,D9,DA,02,2D,F1,C1,C8,69,AA,48,38,A6,C7,7C,B3,BB,4A,E9,B4,DB,56,86,E9,D0,C8,86,99,9A,D3,56,F5,89,F5,13,1A,A7,85,4C,C4,9D,4F,C4,74,C3,0D,E5,51,A3,B3,D2,8B,E8,B5,49,A5,A7,DE,53,57,DF,DD,C0,F1,5D,36,95,9A,AA,EC,28,1B,3B,D8,A6,BD,2E,53,CD,E0,1D,FD,8C,43,9E,83,04,B7,A0,C5,78,A9,F6,49,2A,E5,3A,05,72,9E,E1,42,55,CD,D6,4B,EB,B0,85,B9,5A,E0,F4,AA,1E,AD,A7,5A,A6,97,59,B7,81,2C,DE,7A,33,8F,71,27,03,E0,86,72,B1,60,FC,7E,42,AB,E4,B7,93,47,BF,7E,4B,E7,64,09,AE,9C,8B,29,93,27,09,4C,63,75,EB,B5,80,84,01,D4,C5,01,BE,84,14,54,4C,3A,1C,DA,36,E4,80,E6,AA,BC,6D,B9,32,10,C6,AC,CF,26,F6,C8,88,FB,34,CE,2D,67,9A,69,E2,BF,9F,E4,FE,C9,62,23,0F,53,B3,97,C2,AA,47,EA,D6,87,94,CC,AD,F7,89,9C,B2,5E,4E,8C,8E,6E,96,6B,3E,31,90,C2,28,2E,F1,20,0B,CA,08,A4,88,1C,6C,3C,6C,C6,CD,30,EB,86,2A,46,54,8D,25,78,D9,6B,D6,E0,84,92,C5,F3,87,E6,B5,07,9A,25,2F,10,40,66,3C,E6,96,01,85,6C,4D,68,72,5B,98,3F,A5,54,4C,BE,A0,0C,AD,DC,CE,8A,ED,A6,FF,61,5D,D7,53,62,6A,80,CB,BE,ED,A1,1B,AD,7E,4A,E4,25,B5,FC,D2,30,90,C2,44,00,18,E0,D9,1C,B2,AC,E4,87,EA,F2,AC,AF,F1,7E,2A,7C,2E,1A,22,BD,E4,BE,9F,FB,20,E6,F8,A8,26,35,8C,5D,B7,74,EC,73,D1,8C,3F,78,E3,C6,12,CE,27,15,0A,F2,67,7A,8E,DE,EF,A0,9C,FA,10,77,35,24,DF,20,B9,5E,09,91,49,6F,04,3A,55,34,0E,38,99,28,14,25,12,B5,36,A8,C3,E3,94,27,D8,01,DD,E2,7A,86,18,02,89,4E,2D,87,56,A4,83,3D,F4,C9,16,6F,1C,80,63,F0,48,91,73,66,C1,9D,C2,E9,F6,40,53,36,71,84,1B,1A,CD,EB,64,F0,61,78,DC,4B,36,29,09,C5,D9,AC,8A,8B,E6,A3,FB,1C,CA,E3,AC,D1,EE,04,85,86,C4,74,61,C9,2C,D4,DF,00,0B,CF,B1,91,A4,38,26,12,0F,AA,F3,3B,09,D9,F3,50,BB,D5,88,39,9F,BC,F4,19,DF,D8,EF,87,DD,FE,E6,B4,EF,90,46,2C,0D,CB,1D,AC,A6,AD,86,EB,FB,CA,13,9A,C1,27,CB,71,43,9E,04,3B,7C,4A,85,71,51,74,9D,57,6B,70,C7,4F,91,30,60,77,7A,B6,C1,14,C0,8E,F6,A9,C7,69,9C,C9,A1,61,76,98,B9,84,38,E2,EC,F8,95,91,81,EB,5C,BE,FE,8F,A4,C5,72,EC,F0,D1,33,41,92,A6,B2,1A,05,34,64,C3,2E,7F,2D,38,80,00,B7,2B,C2,4A,3D,1D,E0,B2,52,D0,78,5E,09,BE,FC,B1,31,E2,0B,BC,F8,48,41,E3,58,BE,21,90,FB,FC,91,BD,82,2F,3D,DF,FB,E2,5C,7A,3F,84,DA,90,BA,10,72,B1,10,D7,1F,10,57,FE,38,F4,6D,78,53,00,EF,B2,BF,89,A7,AF,E1,82,EF,68,87,14,FC,14,8B,44,18,73,86,19,B7,86,DD,9C,19,7C,73,91,3C,8E,8A,D1,9C,20,31,3B,2B,1F,6A,75,A1,9B,84,C8,85,5B,03,4A,5F,0F,2E,86,E4,26,CE,71,41,07,77,77,3F,F4,36,8A,F5,1A,1C,F6,42,BB,DB,C5,E6,D8,CB,14,C0,EB,C5,AF,8A,A5,DD,6A,42,2D,2A,FF,35,AF,54,D6,FC,B8,6C,9A,C7,CA,1D,51,6D,07,C9,ED,20,83,4E,C8,EB,7E,9A,E4,F3,F0,13,9C,FA,76,6A,CF,23,1E,6B,55,9D,39,10,28,03,46,53,3D,93,56,C0,19,B4,F9,76,CA,8C,74,02,F7,73,6A,C1,A1,5D,0D,AB,76,99,56,8C,EC,93,64,2A,79,67,F2,14,1E,03,85,3C,21,E9,96,A8,4E,08,A2,89,5E,F1,34,8E,34,45,C4,38,BC,86,39,D6,E4,00,E7,7E,94,5A,20,10,52,96,E0,C1,0A,CB,12,9B,4D,F2,A5,68,BD,36,A9,DB,D7,B5,6A,BF,63,B5,FF,41,EA,D8,05,11,E1,0D,A6,84,58,C7,92,D9,A8,EC,95,AF,56,87,6E,38,CB,B8,0B,5D,B4,25,96,FF,3F,63,D6,5A,BB,51,24,D5,F9,53,2A,45,70,EF,AB,9C,77,F9,BB,C7,85,95,A4,8A,3E,E4,64,AB,E8,1E,EA,AE,A6,CA,98,07,F8,31,7B,42,C8,B5,AA,8C,C2,71,2C,DC,FF,B3,6F,9C,53,AB,9C,8D,74,DF,0D,AF,3B,37,EA,52,C3,99,7D,84,97,C8,B4,26,6C,3B,9C,E9,B9,BD,27,6D,D6,5D,6E,C7,78,93,C3,B6,15,27,56,D8,EC,F4,AA,B9,16,3E,DE,33,AA,B0,25,77,87,FE,16,32,A2,4A,4D,06,28,F1,8F,A8,E3,34,07,DF,DA,D5,8D,67,3E,DE,D1,A8,87,F0,4C,5F,BC,6E,19,92,BB,9F,C0,3E,B8,88,E0,96,C9,4B,0C,0C,32,08,87,A8,C5,DC,44,CF,4C,6A,95,2C,7E,A4,A8,B0,4C,3C,58,39,82,C9,CE,BA,40,A3,28,94,B4,2E,C0,12,25,50,62,74,67,FF,4D,DA,89,C0,A8,52,1F,16,E4,DF,69,72,D2,84,A7,AB,CC,4C,24,A9,55,36,35,87,D3,9F,50,41,3F,42,E7,0D,E0,3A,6B,8C,41,74,3E,E8,7D,41,E5,EF,1C,9E,3F,6E,B2,1D,A3,6B,02,60,B1,09,3E,5A,57,15,DF,10,7D,F3,6F,E9,05,5C,EF,36,91,EA,89,AB,1F,19,44,04,89,07,2A,D1,7E,96,AB,06,BC,BF,0D,22,9A,56,41,79,51,2A,01,8C,C3,D2,F6,32,B6,2C,1F,57,F1,D1,CB,F6,B6,35,32,FD,9D,D8,53,06,45,EF,04,EE,98,26,B7,A3,7D,FC,E1,07,B0,8A,ED,6E,87,5B,76,59,3E,1E,EB,CC,33,A6,DA,C0,6E,E2,CC,FA,76,46,9F,AA,7C,D0,01,DD,F2,31,54,89,32,E9,97,44,9F,09,F0,6F,B6,A9,84,4A,4F,F3,F0,7B,0B,41,61,79,F4,2C,F1,62,A9,2E,C0,71,8A,B4,CE,74,54,B8,6A,E5,C3,5D,32,BC,8E,3F,D3,B4,8C,2B,28,18,19,64,A0,84,18,8E,7E,60,AF,37,28,BF,B5,A3,26,C2,46,FF,97,1D,4E,98,D5,86,F6,FE,C8,B6,B4,3E,88,A3,34,8E,83,A3,F7,77,4F,E3,49,99,6E,AE,E9,26,2C,5D,A9,92,2F,44,E7,40,3F,BE,13,87,04,FC,19,CE,CE,97,47,AD,BD,28,32,17,25,49,C6,42,43,59,B7,A7,A1,CC,91,51,D3,64,6C,17,7A,0B,D6,11,1F,2E,D7,FC,00,3D,A6,EA,FE,3A,1B,03,46,61,2E,28,AF,58,69,31,CB,77,08,C4,A4,52,C7,03,08,6F,26,CF,9B,C5,68,37,BE,95,4C,7D,A1,CD,6C,88,98,71,AD,77,67,E4,CF,4C,BD,B2,C7,40,80,0E,67,62,B6,D6,75,55,F8,C2,F3,AD,00,CE,4C,64,06,16,EA,F6,28,D8,5F,15,0E,E9,A2,D2,9C,51,65,75,18,00,1D,16,C8,14,82,3E,88,75,DC,4E,1E,73,2F,A9,61,CD,5A,B1,E6,AA,20,C2,27,1D,43,37,96,ED,84,37,66,2F,71,AB,4F,BF,64,E9,65,2F,40,F6,DA,99,94,E4,F6,2D,A8,47,DD,B7,C6,CD,F1,D5,02,10,07,35,7D,30,4E,53,99,14,FF,63,58,E9,01,D2,1C,24,2C,2E,CC,EB,D3,42,AD,46,61,BF,5C,B7,B9,19,0B,DE,D4,B3,37,C8,E9,8E,1F,B7,DA,26,33,EB,BE,E6,BD,87,BE,A6,92,33,3F,CB,21,06,73,04,46,0D,45,73,88,43,FB,A3,68,78,18,D6,A2,7E,FE,1E,90,C0,E2,FE,44,00,C0,CA,AF,EE,BF,D0,84,F5,DD,4F,9D,C5,70,22,E6,46,95,0F,95,A5,88,EA,88,8B,78,D3,8E,A7,2D,EA,C5,A3,00,EC,21,69,6B,A7,F4,AE,B3,52,53,B5,EB,86,67,2D,B9,C5,9F,F4,00,49,82,0F,D3,66,51,F6,97,7F,32,F6,5C,56,7C,B4,3C,AC,9C,E9,C4,DA,7A,13,EA,AB,D5,41,20,18,8F,78,CB,D8,A2,18,FC,06,3A,0F,E8,6E,C7,D9,44,DC,E5,9C,5B,88,6B,5D,FB,C6,8D,88,4C,ED,A6,C2,BC,32,5C,AF,FB,4F,1D,24,1B,DE,73,CF,B3,DA,55,6A,8E,76,BE,B3,F1,EA,38,EF,F4,5E,40,BC,DF,F4,DC,5A,81,84,7C,CB,CE,DD,50,3A,62,7B,35,69,80,9B,CC,BD,12,9D,8C,63,94,51,AE,FF,48,A8,B1,39,31,61,94,0A,5B,89,7F,F2,47,A0,F5,BF,CE,BB,3B,59,0D,26,55,7A,AA,4A,D0,D9,62,A7,F8,5C,17,03,E6,FD,EC,2D,30,84,DA,EB,05,21,A2,F9,2E,E6,A4,29,C8,ED,5E,79,3E,1E,40,69,AC,06,1E,83,D7,93,ED,BF,E3,92,91,74,38,9B,42,EA,F7,B2,19,F8,41,DA,F1,0E,FC,8A,74,FF,BF,E1,C0,9C,24,70,88,7C,AF,62,4E,61,E4,AF,9C,05,D3,B3,1E,25,40,B0,8A,21,CD,CC,58,21,F2,3B,64,9A,CD,6B,7C,83,80,77,A5,33,15,F6,E2,A0,97,AF,D5,FE,5C,9F,CA,C7,86,3C,D2,2C,52,1D,9A,4C,F6,D5,9A,BE,F8,2F,88,9C,25,2D,F3,67,75,33,FF,10,DC,E5,C2,FA,97,0A,5D,3F,3E,19,98,FD,86,36,0C,08,0A,C9,3A,0A,BF,30,46,30,04,EE,6B,B9,A6,69,D1,FD,3F,E0,AD,C5,63,F1,1F,6A,19,5B,98,E1,E6,36,AF,36,33,E9,C0,05,B8,AC,E4,94,16,F7,2A,9D,2F,52,26,3E,15,BB,AD,73,F9,80,4B,90,C8,1C,D9,5E,1D,7B,8D,EE,30,ED,54,F0,EE,11,C6,AA,26,99,31,88,18,28,5A,4A,87,10,0E,AC,21,43,47,A3,1B,3E,02,FA,7B,27,86,BE,9D,08,C5,3B,8B,2F,76,FF,F6,F5,DA,B7,05,18,D7,0C,53,EE,66,73,64,9B,1C,3A,BE,7A,FC,77,E4,45,39,34,F8,1B,AC,7C,12,BB,30,A0,D7,83,7B,FE,F1,24,56,DC,77,E3,0F,CD,D1,1A,62,B7,6C,F5,35,AB,37,AD,DD,85,BF,76,47,9D,CF,FB,CE,FD,3B,DB,11,90,68,19,10,8F,CE,29,52,8E,E9,B7,3A,02,5B,18,B2,E3,88,B1,AB,54,32,E5,73,6B,1F,FF,C0,01,44,25,38,B2,36,83,70,DE,7B,7C,40,60,A7,F4,BB,8F,C4,A4,24,59,7E,C9,85,5B,6E,8A,47,B4,78,38,20,D9,34,9F,AF,6D,65,29,60,FF,30,2A,BA,C1,9C,29,DA,C3,91,58,EE,60,59,E9,DE,37,8D,8B,65,FE,FC,75,C8,B3,FE,AF,08,90,2D,0D,DC,FD,EF,ED,27,97,9A,1E,E8,3E,CA,E4,A7,FB,2B,1F,01,58,A2,76,00,3E,F1,D5,56,1A,B5,B2,6C,D0,72,3D,F9,E3,6A,95,D8,7D,70,27,B5,84,67,96,FF,52,F4,1F,CF,0C,AC,ED,1B,4F,95,68,7A,7E,56,81,A0,E7,29,28,4E,31,77,C4,55,97,86,66,B3,51,D9,0E,AB,F9,D0,2F,E0,CD,89,9B,C1,2C,1E,D5,0C,7A,75,D2,A2,E4,68,53,6C,58,49,FB,3F,44,25,CD,AD,42,9B,5B,EC,8D,8B,E8,2F,2B,ED,CC,42,A8,0D,A7,4C,76,33,DE,6E,0C,6B,A1,B5,03,3F,3F,C5,20,E8,0E,5D,DC,73,92,5D,F0,96,44,F5,23,3E,B8,9E,0E,81,2A,22,47,D0,F5,5F,76,EC,33,0E,4E,37,A3,E7,A2,43,9A,1A,F2,33,49,44,19,2B,93,B3,6D,39,F6,62,39,77,FB,DC,32,35,FA,6B,3B,8D,60,2D,C6,68,B2,27,81,DE,78,55,D7,E3,47,2F,8A,2F,88,1D,F4,1A,65,8E,C3,DB,4B,00,63,32,0A,44,0A,8B,64,EB,EA,74,34,9D,E6,8E,04,89,88,B0,90,5E,44,6E,3E,C9,27,E0,13,F7,C9,F9,22,D4,4D,F6,8C,6D,33,C3,83,75,8B,1F,1D,9A,6B,A8,52,42,FE,A1,99,9E,E3,A6,0C,A7,00,A8,14,75,20,DD,87,7C,C4,0A,89,7E,CF,E0,66,AA,3B,4D,0C,56,E4,A9,E8,A1,2D,0D,8B,97,81,AB,BF,7A,9D,8E,C2,1C,4F,5A,99,88,2E,38,2E,4D,40,4A,B9,61,DF,46,C2,E7,74,BB,B6,F8,43,D4,8D,F6,AD,B1,4C,DE,E0,33,F7,11,EC,A7,4F,26,5C,F0,1F,4E,34,3F,AA,6B,26,FF,F6,3F,18,43,9F,F5,A2,DC,68,4A,0E,5B,FB,32,AA,B0,3F,CB,57,6F,48,00,F3,0A,7C,BE,4E,C4,4F,C8,CF,5E,D6,84,E4,66,4D,54,C9,04,BA,F1,A0,65,F1,57,66,82,5F,DE,60,94,C6,DC,26,F2,B7,FC,C0,01,85,CB,12,87,6B,40,5F,F5,1A,4B,01,E6,66,6E,DF,51,D0,5F,FC,8B,D0,5C,34,75,97,C2,47,FA,9A,72,53,67,E0,09,AA,07,67,A1,6E,49,B6,11,6F,B6,20,EB,40,6F,B4,76,EE,55,9E,C0,12,4E,DE,F8,84,26,B9,4B,FE,6C,21,54,D8,7A,84,2F,03,3E,B1,37,38,8A,DD,97,56,36,1B,16,6A,B8,1D,43,5A,76,10,C4,DB,28,94,E0,D3,73,58,E5,DA,B3,00,B2,D1,65,BB,25,CD,94,3D,7F,C9,76,5A,25,03,CA,ED,6C,44,7F,31,C2,12,4A,32,71,FF,BA,2C,86,E0,5F,BB,A6,CD,AE,BF,CB,56,EC,3C,F1,D8,38,A9,9C,3D,C1,EA,A6,95,1F,1C,0E,5E,FB,FF,87,79,E2,D3,0E,14,6F,AF,F7,5E,7A,D5,85,BC,0F,1A,40,B7,6F,5F,03,69,4D,8B,4C,2E,56,50,30,E3,19,54,FE,52,B4,74,60,2D,9D,2F,C2,D7,F8,1D,F0,A7,45,CC,01,8E,F5,18,E6,8A,92,27,C9,7F,92,69,BA,0E,19,0A,6C,26,AD,33,66,FD,97,F1,CB,DA,23,6B,13,AE,D6,2B,42,9D,4A,04,39,27,FA,E2,B7,71,39,96,36,8A,5B,97,6D,E2,B1,F4,EA,06,72,00,B2,F2,AD,5C,80,DC,1C,A1,58,62,32,AF,69,53,4E,5E,08,7E,0B,B9,40,CE,49,1E,CF,8F,1F,E4,67,52,72,37,3A,7C,48,7D,19,1E,4F,8C,90,1D,02,91,BA,F9,CC,80,90,DB,0F,34,04,89,5A,F4,D9,33,75,F7,36,EB,F4,C1,62,93,A5,0B,26,F5,93,53,BD,66,2E,E6,F0,B2,62,B2,85,E4,E3,C8,38,A5,4A,31,CA,72,13,F7,64,86,56,7E,6D,AA,16,C6,AD,8B,B6,4B,31,0B,B6,4B,F7,95,3D,D2,1B,FA,E9,4B,A2,94,4B,2E,37,35,74,77,80,45,B8,05,DE,67,49,06,EF,9B,AF,05,B4,C0,94,D4,F0,8C,BB,1F,8B,A9,38,69,F2,F6,39,96,0C,5F,F0,6C,F6,1B,9C,7E,74,1F,FF,B8,8F,44,BA,38,FB,01,35,6C,18,B0,67,EF,8C,BF,92,33,76,4E,A0,A2,3B,E8,C1,AE,64,29,20,40,70,39,45,0E,B9,76,17,02,BC,40,F9,CB,D8,3B,F9,B3,92,AC,B6,10,D2,D2,23,30,DF,3F,04,73,B0,29,90,7D,A1,AE,B1,86,99,12,54,58,03,9E,95,80,B2,61,BE,B7,35,08,82,0F,BA,1F,97,75,74,0A,5F,1D,C2,CB,D9,F5,D2,01,45,92,CC,C5,45,E0,AC,49,91,EA,65,A8,D3,C2,C1,AD,EB,F3,9A,0D,80,2E,5C,E3,AD,56,29,F5,DB,6F,F4,6B,3A,A1,A2,F8,EF,D1,87,3E,74,B0,FF,D5,39,79,D5,21,F6,3A,00,7B,1F,5E,62,16,B6,88,4D,FB,33,C4,2D,17,4A,C2,37,DE,7F,48,64,A0,E6,91,DB,55,EA,BF,DE,1C,7C,D6,2A,50,E4,E0,D2,ED,F3,1D,15,96,29,CC,73,FC,0D,C3,1F,B6,00,40,6C,F2,82,53,4E,16,74,35,1E,F3,30,D8,F0,A1,75,47,C2,74,5E,9F,E8,48,F4,A6,C8,41,E4,12,DA,88,3E,1C,06,D0,C8,09,BE,AC,B8,B3,B1,0D,8F,88,DA,DA,CB,33,71,14,D2,86,FD,DE,CB,3D,D1,66,E3,FB,18,AE,78,39,4A,4B,7F,49,5C,43,FD,45,C1,0E,F5,32,3A,90,1B,0A,5D,4D,D4,92,C2,F0,8F,30,DF,45,44,46,42,58,BC,26,D7,21,2C,51,B7,BA,7E,6D,E1,2D,78,53,06,39,05,51,66,FF,F2,17,F0,95,A2,AC,3E,69,FF,FE,82,B5,CF,FA,A7,3C,8A,8A,DE,AC,9A,D1,40,28,3D,86,B8,C1,93,EF,CC,61,C7,C4,98,D9,C5,C7,96,7D,E2,36,FF,42,D9,7A,AE,31,60,E5,4A,80,CB,26,F3,52,A3,27,F2,45,7F,34,A8,E3,45,D4,7D,6A,D6,60,68,3A,D7,04,80,E6,5E,DE,B2,F0,52,A8,16,40,14,39,98,D3,8C,62,CA,3C,87,A8,1B,84,73,08,10,2D,AA,92,4C,46,E1,8F,C0,DE,2F,A2,9D,1D,9C,53,E2,88,A9,63,9D,8B,40,0A,9E,40,EE,A3,BE,56,AE,C6,2B,B3,AF,C8,AE,CA,65,75,14,C2,E0,A1,2B,59,B3,79,DB,14,B2,0A,18,3A,4C,B4,B6,1B,47,82,4C,4B,B1,ED,13,D3,CC,03,69,37,D2,CF,E5,42,A9,F7,98,66,99,A7,18,21,06,07,C7,14,F9,86,CA,C5,25,8C,0A,84,81,86,B8,6D,44,89,4D,9F,41,58,2D,F8,5E,AA,8F,26,6E,84,63,76,37,3F,4F,2A,59,04,A4,87,F3,16,8F,C0,E8,A3,86,3E,93,AA,2F,E2,87,40,0A,F8,E0,59,3D,A5,91,F5,6B,81,F3,5A,00,62,A8,48,EE,C5,54,44,6A,A5,4A,F5,D8,91,55,AF,7F,BF,81,FD,59,F6,B2,4F,96,2F,9C,99,FB,1C,31,27,CA,61,2C,7A,94,07,9E,C0,1B,5C,E7,7E,1F,55,8B,53,56,F5,4F,D7,A6,09,7B,66,68,19,1D,1E,44,CF,89,22,52,E2,0A,F1,42,6E,4D,F5,FE,D3,FE,34,E9,C5,69,97,1F,EC,9F,47,D1,A0,2B,91,50,F8,DA,A8,92,26,AF,E3,81,05,7F,99,40,3B,6C,06,6F,AB,A9,C4,51,3A,5B,45,D7,29,1F,9F,30,A6,16,CF,79,EE,75,3B,CF,49,29,D5,9F,B3,46,FC,74,C8,D4,04,F1,6A,BA,D6,F8,E8,A0,9A,64,B9,13,F9,6B,51,7F,8D,52,4C,19,A0,48,CE,92,9E,2C,D1,84,84,20,90,3C,AC,2E,F7,E7,3C,D7,9F,A0,55,C8,BC,03,67,B5,EC,9C,AD,58,74,D9,D9,60,5A,FC,03,B4,57,15,5C,A4,E1,56,20,18,7D,D9,69,12,4F,F7,FF,E4,FE,35,5A,9E,6D,10,AC,8A,D2,AA,C3,60,7A,22,2F,CF,A0,6D,44,24,94,3C,C3,F4,D4,41,37,91,08,E6,F0,58,97,B1,1B,13,7D,D9,C3,61,4C,1B,58,4B,FA,1B,7F,11,58,F6,CB,A8,30,E7,7D,F4,77,88,64,A9,6E,A9,E8,2A,44,84,C9,CE,B8,64,56,38,C5,6A,47,E6,A4,8A,93,D4,35,ED,EE,1E,10,60,7A,40,F1,8F,CE,5B,E7,53,07,3C,8C,9C,8D,6A,E7,0E,45,52,3A,9E,20,35,52,F4,80,60,AD,7D,1A,06,07,15,33,8B,BF,58,DF,39,FC,6F,30,AA,31,62,71,DA,56,23,0D,4C,B3,5E,65,DE,CB,70,CC,E6,82,6C,1C,0C,F2,57,D9,34,CD,5C,0F,6E,09,32,E6,E1,C9,44,51,85,45,87,B9,EC,5D,CB,1D,55,C6,B1,B2,A2,90,8C,43,8C,BC,A2,42,2E,E8,06,8F,A8,1E,94,03,46,CA,98,5F,91,AA,D3,9E,64,5A,C8,08,7D,D6,DB,90,C8,E9,C8,13,76,54,58,F9,BC,05,D3,2B,F1,AA,DC,83,78,A3,2E,E1,6D,BC,09,B4,DB,33,A7,29,53,D9,49,1F,53,F3,C2,18,8E,8F,47,A6,F0,45,FF,4F,8A,2F,6D,BB,A4,6C,6C,41,79,4D,12,E9,42,39,A7,09,83,6A,99,15,49,1E,60,54,48,89,66,FC,8F,0D,3E,A6,60,50,8B,88,12,9B,FF,7E,C4,1D,FC,8F,5B,06,5B,F9,B1,BC,E1,FC,B8,AE,34,51,9C,AC,17,18,5B,12,76,A3,8D,D4,00,E3,74,E8,CC,30,3A,0A,7B,4E,76,44,EE,2D,75,6C,7C,06,94,D4,8E,48,3C,59,15,1E,CF,52,55,22,7B,71,E7,52,17,0A,79,5D,99,46,80,A8,48,E7,2F,37,B8,3A,0C,07,5B,B0,0F,BA,1A,74,F9,82,FA,B2,76,E3,9E,F2,41,09,A4,DF,BD,DB,45,42,C4,02,F6,64,2B,23,17,00,18,BA,AF,90,86,07,C6,A7,11,89,15,58,06,50,95,A7,C2,5C,B4,5F,61,DD,68,1B,8D,9B,35,3A,E3,79,F5,B1,84,AC,42,C7,AE,3E,BA,25,E8,13,7C,D7,A6,08,5B,9B,3F,11,AB,64,79,2D,FF,B4,CA,A6,25,3F,ED,7D,08,DF,FB,CD,25,A9,7D,6C,6A,5A,15,26,9C,A4,A5,8B,8C,89,FD,F6,CD,91,F8,EE,9E,2A,F1,DE,3A,C9,F5,0B,36,31,D5,11,39,0C,BA,B2,62,B4,25,4F,E5,99,3F,45,2C,6C,67,99,A1,05,C0,81,F6,1E,3F,81,F7,C2,0C,85,6A,5C,63,0C,CA,3D,72,B4,1E,DC,1F,B6,44,6E,1A,23,B4,ED,4A,2F,17,63,92,E9,8C,88,A9,2A,F4,63,82,6E,30,FD,31,61,C5,6E,26,94,D4,37,1B,C0,6E,28,F1,A4,2B,BE,D9,9E,08,79,B8,31,C0,07,41,B3,B8,70,DD,F9,E2,B3,9A,D9,73,26,48,97,EA,7E,8E,23,98,AA,D4,0F,10,33,13,F3,A5,56,D8,DE,10,D7,42,D0,B4,D8,97,E5,06,0E,E4,00,0A,D7,66,F1,80,04,59,24,E6,F3,B2,ED,B5,47,8E,4A,92,3F,EA,66,51,FF,8D,A0,FB,8F,93,35,5B,D6,D0,39,6C,87,BA,D5,B8,14,53,64,F9,4C,30,DD,74,08,45,AD,37,80,E1,62,C6,D9,B8,8C,01,DB,B2,2C,79,08,E2,0C,08,93,F7,F7,1E,F6,2F,16,53,87,1E,59,2A,F8,7D,61,ED,66,53,64,69,BE,36,EB,33,35,B9,25,AD,10,84,BA,49,ED,E7,1E,66,3C,6B,7E,D7,1E,0E,EA,53,24,1D,8D,9F,D2,45,7B,B7,56,A2,F0,0D,19,42,76,D4,84,F2,70,D8,38,FB,71,D6,6C,CA,7A,8E,FF,FB,83,C6,C5,1D,47,37,95,5F,E4,B3,54,D2,87,81,2D,C3,39,AA,1D,BE,26,C9,0B,EB,8F,4A,BC,96,BD,A7,D4,AA,D7,A3,74,FD,40,9A,2D,FB,B5,B4,ED,4E,A1,B6,E3,80,F8,49,71,BC,D2,14,17,78,B3,46,FE,3D,60,6D,03,FC,EB,CF,37,99,81,98,79,6C,E3,6A,3B,9A,DA,93,5F,B9,4F,64,85,AC,0C,72,8D,28,13,30,A2,5D,43,E4,43,D6,ED,2B,77,36,C4,BE,E4,D7,5B,36,57,7D,F5,88,7C,A2,9C,25,7D,21,FB,BD,E8,D5,C9,4C,1A,B2,E5,68,D8,F3,FA,A4,43,7D,A2,0E,72,11,19,15,DE,E4,E4,5A,29,E6,69,62,F8,9B,5A,00,66,7E,38,6E,0C,20,37,49,61,8D,60,79,B0,97,64,4E,54,95,8A,4E,47,C3,C8,62,31,73,89,E1,62,A0,A4,A3,DA,00,B2,DC,66,EC,58,CC,C7,DC,F8,B6,07,E9,1C,F3,7C,33,B7,B5,57,53,F5,51,A6,15,BE,45,6B,82,B1,94,97,2E,85,84,CB,A6,7B,96,BF,56,7C,30,5D,7E,2A,BF,4F,EA,10,C2,27,78,6B,60,40,70,5B,B5,CF,6C,31,EF,63,2C,F5,54,9D,BF,CD,74,5E,FF,C8,25,C7,CE,FB,68,49,EF,78,F9,16,8F,50,99,2E,16,8B,66,59,2C,62,93,91,A9,D7,44,3B,83,EF,45,25,83,D6,67,2E,95,BF,72,75,FA,67,BE,04,4D,3F,CF,A8,6B,EF,87,08,26,1E,00,6C,EB,99,84,6F,71,67,26,97,48,2E,F3,46,0A,6D,7E,4F,AC,2A,42,5D,44,41,FB,A5,E9,94,06,25,D3,24,04,02,70,76,08,34,C0,CD,CC,29,A0,0C,B2,EC,50,CA,F8,EF,5E,D8,10,D4,B1,EC,F6,DA,41,10,50,DB,66,72,99,54,03,B6,BC,15,67,CB,15,56,94,F7,0A,44,77,9E,CB,3D,2C,08,2A,E8,24,C4,A5,4B,03,C2,B2,A6,1F,8F,44,72,4D,D5,B4,58,65,62,ED,DE,10,9E,C2,27,E5,42,71,34,F6,04,6C,00,84,A2,6F,2A,CE,F5,39,4B,E4,28,60,F2,51,0E,FA,6D,0C,60,26,9C,D6,1F,43,EE,38,85,A8,77,69,B5,0B,AE,22,7B,0C,28,74,B0,71,F1,CF,A3,94,DE,CB,7C,54,61,B1,68,5A,76,17,55,8E,9E,FA,DF,4D,DE,A1,88,D6,CF,83,8B,41,D5,7A,C7,85,56,E6,4A,FA,61,83,CC,04,21,9C,B4,82,8E,7B,84,DC,5D,95,4B,69,0E,4F,9D,06,5A,FF,50,9E,71,D8,FF,EC,2B,82,AC,D1,9B,8C,41,E2,49,62,06,45,41,73,14,FF,1E,24,63,D1,CF,EF,09,92,75,B6,49,C4,99,24,38,B8,D1,F7,01,B7,00,AB,B7,22,DF,5E,82,8F,20,6F,E8,80,EF,8C,EE,D6,D9,C9,7C,C2,F3,DB,D9,89,1A,14,65,4A,06,03,C9,47,15,54,BE,CC,49,9A,6E,04,A1,4C,DB,27,09,AA,1E,E1,C7,13,0E,F3,A2,F6,3C,E2,63,08,E0,35,8E,44,2F,5F,04,14,A7,6E,BE,F2,F3,C1,4E,0A,61,9A,00,E0,2D,9D,43,5F,7F,94,57,11,41,D0,7E,D9,68,9D,A8,10,EC,FC,7B,87,0A,44,C4,FE,14,BE,2C,0B,78,13,8F,77,81,FB,75,C0,09,72,43,7E,96,61,98,99,CA,31,7E,ED,70,43,4B,F0,6D,5C,4E,CE,8D,6B,7C,2E,C9,0A,26,73,37,D4,3B,26,8F,BF,99,46,B9,D3,F8,8F,82,A8,18,32,B7,4F,F0,A2,F1,AC,32,85,70,FA,FE,FC,8D,0F,48,E5,38,E7,10,94,56,7C,FE,15,96,4D,4E,33,71,80,21,52,B3,8A,9D,1B,B6,32,6D,EA,17,AC,22,C4,C5,60,AA,58,D0,08,A4,98,AE,42,1E,67,DB,C3,C6,C9,D8,4B,70,DA,9A,5C,5A,A8,9B,30,C7,2E,D0,7C,D9,1E,C7,65,4A,F5,60,45,CD,83,08,12,7D,D0,AC,7A,65,A2,98,F3,3A,8B,45,32,23,61,C8,06,7E,27,0F,A7,FE,9E,EA,7C,A7,56,D5,09,08,6F,42,F3,DF,C7,52,F5,87,4D,46,75,FB,4D,9D,E7,E5,D5,BA,DC,01,BA,E8,A7,59,36,9D,59,4D,04,B3,38,32,C8,68,67,57,45,90,7B,B1,78,A1,59,F2,6E,D9,15,2A,24,95,22,7B,2E,70,A3,A8,AD,B8,91,1D,AC,BD,9D,FC,77,02,DC,D7,51,76,21,B0,1D,C8,74,2F,37,A8,17,04,EC,96,74,D1,99,42,64,3E,4B,4F,4A,2C,00,99,9E,0C,A7,65,88,83,B6,AA,3F,0F,BF,34,0F,49,A5,6A,4A,2C,FC,DF,FE,F2,9A,23,35,77,14,46,78,A2,ED,4F,1E,C6,F1,B1,C4,07,CC,28,FF,3C,CC,67,51,AD,75,89,AE,DA,AE,80,8C,27,54,2C,1F,20,60,E3,A8,9F,34,19,A6,AC,E1,ED,A2,DF,D7,96,9E,28,FF,73,6B,55,E5,99,80,27,80,0F,B4,95,20,42,47,61,EC,65,71,0F,4B,D6,27,11,17,B7,D1,64,1D,3C,2F,38,C9,8C,18,D5,25,52,E1,72,8B,55,04,08,94,16,BA,22,C9,3B,D0,7A,31,59,29,9C,53,89,98,BB,AC,EF,CB,06,A4,9E,4A,1F,08,49,69,05,31,B5,96,1D,EE,91,CF,2D,1C,49,9E,B5,02,D6,67,7D,2C,19,39,7E,E7,D2,F6,74,D7,5D,67,41,12,86,57,2B,CC,20,20,01,8D,86,31,11,BC,D1,EC,E5,98,70,C6,61,11,45,36,33,C8,B9,B2,0D,05,F4,37,CE,8C,EF,50,B6,FE,51,40,9C,67,00,B2,AE,EE,CA,9E,96,DA,0A,C4,9C,3E,5B,25,3F,DC,65,8D,3E,5E,A0,4B,D9,A1,D7,F8,56,92,22,DE,6B,AA,AA,AF,B3,EE,8E,D4,4D,CD,DF,76,FA,B4,F0,A4,FD,3F,7F,6D,80,B3,38,19,F1,A1,D0,40,74,45,14,A8,44,34,8A,90,53,AF,7F,35,23,4D,50,FE,4E,B9,05,B0,8F,0F,36,72,28,8D,B5,36,67,D4,4E,51,B8,15,94,CC,46,B8,1C,D7,37,0B,81,DD,A1,10,E7,A7,FA,85,54,B2,F0,C9,79,AD,38,83,65,E3,D6,77,56,A6,4E,D4,D6,46,55,7A,4A,79,11,29,DA,FD,AC,1F,76,75,1D,C4,D9,1B,34,02,08,34,2A,F1,3B,49,28,E4,CF,09,AD,54,3A,02,58,B2,82,F3,48,52,19,65,A8,FE,B7,9F,51,15,56,D2,FD,66,1C,16,CE,9A,7F,2F,AB,DC,4E,D1,A4,EE,3C,00,37,BA,4C,22,84,A4,7D,F9,48,38,85,A6,31,29,69,C1,F2,5E,83,79,AF,BB,15,32,86,D8,C0,83,56,AD,1F,10,64,DB,0D,08,72,0F,C7,90,82,7E,99,47,76,14,69,09,AB,9F,1D,AF,C8,6E,CC,21,3E,90,93,2C,48,54,51,AC,51,A2,BD,54,3D,71,30,51,73,BF,02,9D,5A,27,B3,3E,4A,66,D1,AA,05,4B,53,77,54,D4,7D,9B,95,E7,00,3E,45,77,73,52,3D,40,7F,14,E8,60,E1,61,3D,CB,BB,B2,27,90,D1,4A,ED,2D,3F,B0,F4,BA,9F,A4,FD,66,C1,1C,E5,72,9F,42,82,03,16,E5,B6,98,BF,CE,1D,26,EB,A4,05,7B,28,9D,9A,BC,30,59,3A,79,D4,68,CB,53,AE,90,93,FE,BE,AD,53,35,5A,12,85,E6,D6,1A,3C,38,87,01,89,DA,7A,DF,30,22,AC,23,B0,B4,04,B7,56,02,5C,00,1E,EE,6D,C7,D8,27,34,6C,38,F6,3C,99,34,D5,96,43,47,D3,9A,B6,6A,5D,A5,1E,8E,1B,44,41,CF,8B,12,8E,00,60,B8,BC,7C,F7,69,78,67,AA,CD,13,09,38,1D,0E,71,EB,6B,96,A2,17,FB,5C,E4,C6,D5,82,2C,F3,C1,CC,6B,AA,CB,59,87,11,8D,C1,09,AE,95,43,6E,75,06,BD,A1,94,C2,71,2C,C6,67,CC,F2,5F,8F,67,2B,06,D4,44,27,CC,B0,EF,CD,5A,A6,E5,FD,EE,96,A6,AC,39,F7,0A,89,D4,0D,D9,00,BC,D5,9A,AF,3E,07,F9,E8,79,02,B6,9F,FE,32,CB,33,8D,A5,A6,AD,D0,E0,3C,AC,48,4F,F0,75,4F,18,2F,05,78,F1,37,7B,3E,F3,0B,A6,5E,38,E8,9B,3F,8B,D0,A3,1A,FB,FF,44,40,D0,BD,F6,7F,55,C2,3A,C4,C5,FB,22,1A,38,CE,9B,16,68,CA,F8,59,F7,76,25,0F,F3,12,97,0E,5A,19,1E,FC,E1,A0,BD,AE,97,E3,9D,C9,40,BA,D1,62,05,A7,20,7D,6B,FF,5B,19,C3,DA,F1,8A,A1,8D,D8,DF,22,2A,70,24,F7,DE,19,A0,C1,4B,7C,69,27,27,02,DF,AD,42,CE,51,8D,C1,C1,D2,C6,BC,05,7E,15,D2,B3,09,0F,0C,1A,30,EC,E4,66,7F,73,86,FC,0A,87,6A,BE,7A,20,C9,47,02,DF,6F,A4,83,A1,B4,1D,1A,6F,CE,42,70,95,94,02,53,AC,02,06,36,31,2E,17,FF,E8,94,24,AF,EF,ED,F6,44,AF,E3,6D,2E,E8,1A,EF,A7,09,5D,3B,69,7E,3A,87,B8,FD,CB,D7,CB,2E,5B,D9,0E,42,DB,8F,DC,7D,F2,CA,06,18,C8,E9,63,B0,20,BD,41,D7,F7,13,D5,3D,02,63,32,ED,2E,28,03,73,5F,02,AD,95,36,6E,4E,0F,11,52,E6,68,2B,A8,69,4C,E8,9D,2B,FA,80,11,DB,1D,19,00,91,AC,CA,F5,2F,C7,F9,66,B8,26,18,35,3B,6D,06,CB,42,C1,34,F1,4F,D6,E8,42,B7,1B,48,05,F9,1A,15,25,46,D0,5A,BD,4D,63,42,52,E7,79,05,FB,F1,0A,12,84,98,C8,37,D4,26,04,C8,E7,07,66,ED,E4,D5,88,7D,20,73,61,44,EF,E2,31,73,5C,DE,C5,7A,FF,46,D1,29,0C,92,52,1A,D7,B5,2D,D8,70,3C,72,A6,FE,2E,60,1A,BF,17,FE,1F,11,1E,9A,35,6E,79,90,05,BD,24,46,C1,AC,B3,EE,40,94,F6,CD,84,27,83,55,59,F2,58,28,21,16,EE,61,B8,EB,84,5F,38,B7,19,8E,FE,ED,EF,E3,AA,B8,1D,9D,92,E0,41,25,90,58,E3,E9,FE,92,77,E0,7C,29,45,23,4F,D0,2B,D7,79,1F,71,02,7F,61,E8,C8,F1,37,DA,80,04,F1,1A,5F,0E,14,D8,BC,2D,39,38,A7,E1,8E,57,E9,96,57,56,B7,C2,0C,CC,E2,2A,EB,29,7C,B2,95,D5,08,50,9A,B1,5F,2A,D2,89,32,C3,01,12,7E,B7,6E,64,D8,08,63,01,69,10,66,D7,3B,6D,F0,71,77,15,DF,31,F9,3F,A0,5B,78,F0,82,CD,9F,92,C3,1E,A7,2F,15,0F,3B,41,75,FE,41,DD,69,D3,79,B9,A9,5C,11,E9,D1,EF,92,25,D6,54,0F,B0,B9,20,42,82,4A,EE,A8,5E,95,FF,D3,F7,BD,AF,9E,AD,F6,78,D2,14,E7,A3,97,8F,8A,F5,87,60,8B,09,A4,D6,48,AF,97,A4,B3,C6,42,24,1B,81,B0,5E,FE,EC,BE,BC,32,6F,69,09,54,CC,49,84,41,17,F9,98,F5,9F,67,9C,52,79,80,F2,02,73,5C,4C,9A,82,82,C5,B1,24,66,47,0E,22,32,A8,91,FB,FA,34,E6,4F,F3,5D,4C,AA,5C,E0,E9,2C,16,6A,6A,6C,B6,05,BB,71,BA,27,59,8D,FB,54,24,36,04,5D,C7,57,9B,43,56,94,F8,74,99,D7,A8,CE,B1,98,D8,58,69,7F,68,91,4A,60,A1,0B,C7,A4,C8,CB,FA,E8,5D,07,81,01,84,AD,89,DC,20,98,B3,55,99,DE,A5,95,A1,26,5E,C2,51,55,82,77,99,C7,DD,7D,76,B7,BA,C1,D9,38,85,BF,FC,CC,22,80,E9,78,6D,18,DD,26,5F,E4,95,2A,4F,74,89,CB,27,BB,2B,F7,68,3B,22,C7,41,33,C3,6E,BD,79,C2,9B,E2,AF,42,82,DD,8B,91,86,44,77,21,65,14,8C,06,32,E6,B1,E6,0E,E8,2F,EB,F9,FF,2D,09,97,F3,33,3C,47,BB,93,6E,7A,14,C4,10,D8,6A,21,12,67,1C,E4,90,24,4F,3B,75,18,F1,47,17,6B,26,A6,47,44,4A,AC,7E,5F,BA,75,CC,DD,95,D4,2D,74,20,D3,1D,3E,CC,D1,42,54,27,1F,80,20,5C,EC,A9,2D,7A,D5,CD,29,B1,A1,35,B1,0D,CA,C0,A0,61,1C,18,0C,BC,8C,D9,E9,46,C9,23,00,9C,C4,69,ED,58,D6,D5,FF,D8,90,F9,E2,F6,DD,56,EA,E7,E6,71,BA,0F,27,C8,9E,39,2C,1D,E6,BE,12,5F,6C,EB,DC,10,3A,5E,DA,07,CA,99,A0,53,58,05,92,92,05,38,2B,E0,16,96,97,3F,3E,CE,9C,63,1B,18,DA,9D,18,FE,A6,42,C4,65,E1,56,3E,39,11,81,CF,A3,EC,D5,5C,D5,8F,AF,9B,8D,67,CC,52,9D,30,A7,50,3B,2C,FB,A0,31,FC,E1,59,71,88,30,CA,EE,31,33,23,76,FB,E3,91,14,E0,42,86,5D,03,C4,E4,73,B8,D8,CA,7F,9C,F8,87,6F,53,35,A5,20,00,3C,0A,FA,82,69,BC,09,23,CC,B5,7F,20,A9,07,21,9A,BE,66,96,EA,5A,75,82,C8,97,AD,35,C8,B5,B1,5F,87,C1,7C,86,A8,F5,5D,76,0F,C7,27,ED,E6,AC,CD,82,DB,59,8C,AB,8A,76,EE,7B,74,57,2B,7F,6F,F4,08,0D,A0,00,0F,22,04,79,A0,0D,93,14,27,8E,9B,2C,32,B9,84,33,20,14,C9,71,09,B0,28,6E,F8,74,50,28,B7,72,0D,80,36,D8,D3,00,F0,57,5B,C9,97,E8,02,8C,83,54,7B,2A,60,9E,1B,2A,D1,17,B6,0E,95,49,41,D7,00,78,D6,10,FE,86,2B,64,03,F1,94,8D,22,02,D2,19,AF,5A,23,4F,AC,24,AB,7B,78,43,D1,CF,74,F4,0C,6B,99,5C,99,FA,CD,8A,2A,64,79,FB,5B,98,DD,6C,24,9D,72,5A,50,7D,20,25,12,72,2B,B3,DF,3C,90,EA,3A,A8,DE,D8,54,95,39,29,4E,55,DB,BF,A1,FE,3D,9C,13,30,07,8F,3A,C9,20,66,43,20,24,7B,7A,27,C2,58,C1,45,F8,95,F6,54,EA,F7,CD,BD,F9,06,27,34,82,6B,79,DF,17,31,91,AA,BC,F0,B4,7F,78,0D,C0,CD,CB,56,70,1E,58,B5,E1,DA,47,CB,39,D3,D5,60,21,E8,31,6D,E7,FA,6F,25,CB,4E,8A,D8,B1,F5,94,3E,19,A4,2E,69,B9,1B,12,18,FF,D2,DB,35,ED,2D,7A,B2,44,18,9B,DB,A4,2C,6F,B1,41,A4,3C,CE,57,F7,8E,72,33,6C,34,34,61,E4,D2,FD,B3,BF,68,1F,BD,6F,E5,FD,68,D4,56,49,EE,4E,4B,56,85,EF,48,1F,13,4B,6A,A3,52,7D,CF,ED,33,77,F7,A6,93,60,AF,FF,A0,F8,B6,FA,22,3A,84,CC,D0,62,DB,AE,8F,80,74,75,98,3C,0F,BD,9F,A5,98,60,EE,5F,34,6F,E8,B2,58,EE,3F,F8,59,E7,9C,A0,04,49,ED,40,C8,A6,46,3D,FE,53,BE,5E,80,71,D2,7D,59,3E,0D,E9,22,5C,E5,2B,03,D0,BC,5B,49,99,68,0A,0F,EC,65,0F,A3,72,BB,92,C0,F9,2A,1C,C9,6F,34,1C,8F,7C,07,5D,CE,B5,0A,CB,27,72,7D,4B,A7,8C,EF,E2,42,25,2E,B0,BB,BE,E0,02,8C,1B,C7,5F,C2,CB,BD,22,ED,4F,0F,86,83,E0,47,BF,05,CC,27,6C,EE,8C,80,7A,AB,42,E3,D1,59,97,43,F7,EA,DC,36,3A,CB,AB,FA,BB,D2,FB,94,D0,E6,7A,0B,17,5D,94,E1,E8,0B,1E,7D,CA,0B,10,7B,05,4C,6A,25,F0,48,65,92,BE,4A,B7,23,2E,CE,75,F0,BB,86,F8,45,4D,6F,78,F8,43,12,66,CA,36,D1,C7,CC,C8,65,9C,FA,39,04,23,FF,B5,B8,09,80,95,B0,E6,52,72,53,32,4D,1B,4E,8A,2D,AC,F6,1E,38,07,14,D9,73,03,B2,D9,10,B6,06,A7,60,58,61,0C,E8,52,E1,D8,47,2F,1E,5D,54,2F,18,D5,85,2A,03,91,20,14,CF,AA,3A,A6,D4,0D,73,ED,F4,28,A0,62,3D,BC,B9,88,5E,F5,F4,D7,EA,40,40,23,D9,DB,D9,C5,B8,A8,56,F9,8C,3A,63,DD,89,92,BE,31,6E,51,2C,B6,98,E6,10,51,2B,38,75,73,19,78,AD,51,43,D2,DB,E1,9B,8D,68,D8,EB,87,B3,74,5D,34,F1,09,C8,46,74,60,26,7F,57,D4,3C,5B,11,26,AB,D4,EB,27,2A,72,E4,82,37,D1,9B,56,B9,C7,37,EA,95,99,E8,CE,D8,0C,4E,E3,D4,74,6B,7C,CF,AE,ED,97,62,E5,A0,3F,C3,88,14,49,FC,44,45,74,FD,61,8E,7B,D0,D6,6A,D7,F4,F3,57,A8,4D,7D,BC,91,84,86,47,57,04,96,F6,FB,6B,32,A1,B9,BB,73,6D,F3,64,A2,98,7C,32,E4,79,6F,2C,73,C4,FB,9E,4A,00,79,AB,07,D2,2A,E5,29,2F,9F,6B,30,E7,4B,14,E8,1B,5B,4F,EA,06,EB,A6,79,78,25,5E,7F,54,F8,FD,B8,6A,E6,30,20,99,A3,4F,92,92,63,25,C9,C4,F0,02,C9,68,06,AB,09,53,27,F8,3A,0E,BE,F4,C5,36,44,62,2E,B3,1F,8B,C2,38,61,B1,71,7A,9E,4C,4A,A0,B5,5B,07,2B,44,16,09,C8,80,F4,C3,CB,8E,CE,8B,56,A3,DF,9B,20,25,8B,C1,54,39,14,C9,7C,B8,14,F4,85,E7,2B,5D,9F,FA,25,21,C3,83,06,95,A9,B0,B8,D0,6A,9C,BA,5B,DB,7F,9B,10,65,56,94,08,B2,70,B6,95,65,01,52,A7,60,F6,BA,C0,D5,EE,A5,52,93,FC,0A,97,0F,EE,D7,55,8E,FF,BF,C4,B8,BC,BA,55,E3,33,28,F3,8E,7A,07,F0,0B,46,66,C5,04,67,49,F5,B1,5B,A0,64,E9,D3,B3,79,CE,6B,52,ED,0B,8A,ED,FF,4F,02,74,42,61,C8,D3,29,73,6C,2A,3E,F1,CF,AE,C0,5F,A2,56,4D,53,B1,A4,E9,7E,55,F2,0B,90,55,07,54,49,12,D3,B5,28,41,9D,21,63,DC,D6,E0,F7,4B,A9,EA,37,CD,54,4F,E7,8D,DA,FE,1E,3F,FD,88,8A,64,24,87,99,84,E8,C6,96,C4,37,98,47,F9,A9,A3,CE,C5,E7,C7,8F,0D,A0,04,2F,A1,92,83,94,F7,5B,3E,43,41,8C,C6,07,BD,91,3C,00,FB,24,FC,D0,4E,7A,AA,6D,5D,22,ED,8D,06,9E,35,62,B5,14,1C,17,34,AC,F8,F5,B4,4C,CD,7B,17,0C,DB,61,88,7F,60,7E,2F,FE,D1,7C,87,19,B2,79,E5,12,13,76,98,33,EE,6E,B2,66,22,B3,2E,6F,BD,31,E2,C3,E9,86,BE,86,36,F0,F5,50,DD,42,8B,75,A7,CF,83,4A,76,72,77,94,E9,D0,F1,62,9B,6A,CA,81,AB,31,EE,36,25,8C,DE,26,5B,01,28,00,45,A1,15,86,7F,F6,47,B8,27,E4,DE,71,20,98,CC,7C,97,F9,C6,C7,4C,50,97,15,7B,AF,05,00,65,7F,67,4F,B1,8F,63,7E,5E,36,4A,FA,24,BA,A5,90,CD,AA,59,22,1E,29,01,A6,03,0A,E2,5F,79,C7,D0,AE,D2,8D,DE,B8,EA,75,A7,FE,EC,05,98,5C,4C,E0,31,90,0F,4C,20,76,93,4A,17,02,38,B0,37,D6,EE,27,95,EC,BF,48,63,47,78,29,AC,06,93,5D,FD,0E,EC,FE,E4,4A,45,72,82,CA,E1,B2,01,E4,A4,E9,2E,2D,4E,32,D4,C2,D4,6D,34,DF,3A,A4,36,73,81,1C,B6,F2,F8,F1,84,39,8A,BB,4F,7B,B5,E6,CF,7C,D7,28,4A,5A,9D,53,47,10,62,E0,46,C8,3F,7B,8A,8B,68,4B,F5,04,C6,4C,C3,0C,FA,5D,A5,66,B7,14,44,B9,DC,43,51,B7,15,0F,36,AB,D4,CE,AD,B0,7B,F3,ED,8B,BB,42,35,18,1B,4B,CD,18,0E,C9,44,CD,E2,81,5F,73,48,20,1A,EF,20,49,98,69,A3,B8,29,03,07,54,73,33,74,4C,F5,C2,BE,3C,51,6B,98,28,82,87,6F,5D,EB,55,C4,1E,A0,16,F5,FB,2D,8F,E1,19,65,24,CC,61,D0,B3,D2,2F,4D,50,2F,95,C4,B1,13,A9,37,16,DF,82,66,36,95,20,FD,74,9D,84,D4,09,2B,73,66,86,3E,CB,73,5F,0D,5B,D7,66,58,1D,BE,79,7F,33,52,69,91,9D,42,47,99,EE,8A,1B,53,58,E1,1C,EC,06,5B,0F,34,93,AA,36,47,CA,89,DE,12,11,E2,C1,32,7D,DF,C6,F9,49,26,15,FF,19,3D,98,FA,A4,33,D4,F2,7E,65,51,3B,3A,81,E8,13,A4,E6,BC,77,0B,64,9C,F8,21,CB,17,5A,D4,16,DE,C4,2D,F9,5C,5F,0A,10,12,92,C8,91,8F,9D,A5,8D,19,1F,23,D7,A4,01,B5,6B,06,2D,89,62,13,5C,0A,D3,67,3A,EF,D0,12,E5,22,19,BD,70,47,D3,5D,8B,01,00,FB,32,3B,DC,56,CD,9A,7F,2A,7A,67,D9,8E,A1,E4,F9,CD,D7,59,6E,BD,2A,45,7B,63,8E,88,52,B0,E3,93,57,70,E4,C6,B2,4A,E6,74,E4,12,81,4B,AE,07,08,D6,21,A5,12,70,57,58,97,20,49,19,CC,32,10,C4,03,5F,7F,18,2D,2A,16,9C,1B,A2,18,F2,BE,C0,0C,2C,0B,89,B0,A2,8E,64,73,F9,78,45,E3,A6,32,0D,BB,7F,21,85,A4,E6,7B,5A,EA,F6,23,31,76,A3,B3,F5,68,F9,3B,2C,66,43,F0,CB,19,BE,9E,C3,CB,8F,84,A3,2B,8B,94,8A,47,ED,7A,6A,6D,FE,32,02,9F,D3,2A,9A,DD,D0,58,A1,81,89,B1,CF,74,07,C0,0D,72,66,2E,79,E4,0F,C8,B1,85,64,81,C0,80,FA,CB,98,A6,01,01,75,75,C4,1D,A2,68,25,B8,91,51,0F,3B,EB,C8,83,6A,A3,E6,33,29,B8,16,A9,DD,B4,A7,08,25,32,5E,AC,2F,B7,0A,88,F4,9C,1E,F8,0D,E7,4A,C0,FA,C2,AF,70,7F,4E,62,C2,85,9C,D5,6D,65,56,31,08,FA,4C,27,F6,9C,0D,E6,7A,E8,E4,42,EA,A7,F1,51,78,BA,D2,D5,90,D5,41,33,90,A9,A8,2D,03,5D,F1,AB,9A,9C,F6,3A,60,38,49,7C,6E,F5,F9,69,5D,9D,C5,BE,C7,BE,72,97,64,14,F4,A8,CF,DA,FD,55,FD,41,B4,28,BE,B3,91,70,13,51,06,93,7B,8D,5E,96,B0,BF,1E,A4,1D,F2,32,ED,35,C7,91,C3,5F,B5,FE,B1,F7,DC,AF,6B,AA,DD,F2,43,FE,ED,5E,02,F3,60,52,FC,B9,5C,FC,36,72,08,41,3C,71,E5,3A,E2,3A,29,4A,4D,2D,20,8F,B7,90,93,FA,96,92,AE,B4,30,C6,55,3A,72,84,E4,F9,93,19,4F,7A,61,DD,BC,95,4E,9E,C7,78,BE,85,1E,8A,F2,1E,A8,3B,77,CB,8E,28,0A,D0,32,27,4F,EA,76,04,7E,A1,F9,CF,DC,D5,6D,63,B3,A5,D4,23,E1,B5,A6,FD,6E,08,77,3D,71,63,81,8A,E9,80,12,CE,BA,5D,38,14,07,89,CF,83,47,4A,29,01,D3,CB,EC,BD,4F,8F,33,CB,A9,4E,30,F0,B5,16,FA,58,AC,A3,D8,1A,E4,30,E7,45,EB,99,4A,8F,BB,1B,EF,70,A3,10,01,75,31,C3,2C,6B,D8,44,6D,AE,35,FF,6A,EA,41,C8,44,0F,BE,9D,33,E3,B5,E3,71,F7,B2,95,CC,8E,34,65,6C,AC,22,9F,81,C2,84,10,E0,67,C2,71,0B,02,61,C8,0B,13,AA,BF,C8,2C,EB,F5,42,CC,33,5A,8B,9D,EF,D4,9E,77,48,8D,69,F1,05,6A,99,C4,0E,FF,EE,37,3A,94,95,26,7C,DF,A6,2F,3E,0A,6A,CA,46,30,83,A8,72,31,F5,C7,AE,F3,62,5E,D0,80,4E,F2,AD,2E,FD,3B,47,58,AF,4C,1F,50,43,92,E1,F2,26,94,E1,05,79,2D,1C,53,8A,A9,0B,9D,00,2C,F2,46,66,7D,4C,C5,6D,FF,32,B4,08,63,DA,76,A5,CD,AB,B4,E1,5C,2A,C7,01,23,B2,BA,EF,83,C8,63,D6,17,DB,5C,F5,0C,B3,FF,AF,17,B7,48,57,8E,C0,D3,A1,21,1F,37,4B,42,31,11,E6,10,6F,8A,37,BD,2C,2E,B2,D0,B9,A6,6B,C2,74,DD,F6,59,14,BC,E4,51,5B,D7,C5,1F,51,DD,A3,2A,2A,12,FE,E4,D4,07,F1,9A,B4,43,6E,51,F9,1E,BF,3F,08,7C,BE,7E,AD,53,00,D0,13,B9,A3,B7,EC,62,17,F8,A6,0F,25,AF,0E,43,19,75,2C,B3,6C,71,22,18,C0,BB,C8,57,E7,90,2B,1D,BD,6D,61,99,58,39,10,7E,DE,02,4D,04,2C,00,96,8B,D3,5F,3E,26,82,10,BC,30,95,8B,DD,56,C1,78,60,E6,9B,7E,E9,6A,E0,82,3E,76,1A,34,9A,89,D4,E3,E5,BB,03,0B,63,37,B1,D1,E7,DE,82,F3,05,EB,31,87,CB,13,4F,AD,B8,9F,BC,47,84,54,2B,A8,ED,8A,8E,6C,4C,20,4B,C8,45,FD,D2,39,17,E0,FC,14,1C,B9,8A,48,B4,15,2F,A9,FA,D4,5D,9A,DE,2B,C8,81,78,C5,76,8A,0D,59,A3,BE,60,97,F8,B8,6F,06,41,99,3D,E1,0F,2A,FC,3F,F9,70,2C,CA,80,F4,7C,F8,26,30,0C,20,D5,99,FB,FB,65,30,90,E5,BE,ED,7F,7E,2A,91,1D,6F,8D,C0,DA,8A,13,9B,93,E6,09,7E,4B,3B,DF,FF,A5,53,38,B1,43,35,C9,8A,1C,E6,56,21,73,C0,F1,26,9F,09,F1,50,7A,0E,38,41,6A,DC,6B,91,7D,7C,E5,C3,C4,22,91,8F,3C,81,72,CD,30,0F,38,5F,50,34,63,4C,FF,5E,15,3F,4A,98,68,EB,35,21,17,AD,38,4A,93,29,2B,A4,EA,68,CE,69,74,AD,19,4B,6D,2E,4E,A6,45,62,65,04,CA,5B,C2,43,BD,2E,9E,47,67,F3,FB,B4,78,71,68,59,78,B7,C8,D8,09,C2,6B,77,F4,39,57,52,86,15,0F,BD,A2,58,FD,D2,FA,39,FC,CD,35,5F,39,BC,79,DB,FA,6D,60,A6,AA,6E,6B,33,72,57,A1,C9,CD,32,AA,C6,CA,10,24,3E,9C,B2,6C,95,E1,20,6B,2D,6D,18,3D,E6,5C,EC,12,00,A7,98,39,F9,53,E7,0B,D6,5E,DE,25,90,6F,51,8F,6B,AC,C8,AB,BE,7F,E8,62,C6,99,08,2A,C0,B7,ED,C7,03,64,D2,1F,D6,7F,93,5B,4A,AE,9A,AB,58,D2,F3,FB,6A,43,56,7D,69,79,67,07,96,32,D2,A0,8A,D8,58,44,C4,72,9F,C1,49,E6,3C,63,31,3A,BA,55,DE,10,E5,EA,D5,93,CF,CD,55,13,F2,A0,6B,C7,99,43,CC,99,FD,1B,2F,44,22,3F,95,0C,E7,79,3D,BA,00,4B,A0,FC,D8,C3,FE,2E,32,F8,DD,86,CD,68,DC,70,A4,C2,A2,D5,AA,26,4E,5C,EE,BD,95,08,0F,75,01,08,38,C2,F3,A6,C6,C7,A5,AE,2A,CE,F2,24,5A,1A,A2,1F,4A,A9,82,09,FC,EB,34,A2,34,DB,C1,67,4E,8B,63,88,50,B2,4D,04,B2,63,EF,2B,18,0C,A4,9E,A0,EF,AF,22,D4,5B,5F,B6,1F,6B,01,13,06,4D,43,50,34,6E,97,88,8E,1B,7E,59,FA,E1,BC,34,68,9A,D1,DA,03,38,EB,BD,5D,DD,A8,12,91,57,DB,B0,2F,99,62,C6,DE,65,5B,C2,E2,F1,A8,CE,DE,39,36,84,18,81,7D,60,38,FA,60,72,B5,44,8F,CD,62,C1,49,85,85,1D,E5,9E,EC,04,33,C1,FE,2C,BF,E7,5D,71,59,C2,87,F3,00,C9,9F,07,C0,95,62,A0,82,AB,14,74,0E,49,B3,6C,02,42,7A,6B,76,E3,32,80,26,00,20,BC,B6,EC,F6,BC,38,AB,B0,E4,EB,D7,EE,82,25,5D,D3,5A,BD,9E,DB,3E,0C,64,7E,31,9B,C6,EC,BD,22,C0,5D,AD,2C,0E,DC,6F,B0,41,83,A3,0F,65,E0,3F,AE,82,68,BE,78,36,84,D3,16,14,1E,7F,A3,88,BA,09,77,CF,1D,E7,9E,D0,3E,18,67,AB,FE,E9,8F,DF,41,7D,BA,58,D6,7D,43,DF,28,5D,39,78,4D,54,3F,5A,1C,16,4B,6C,56,45,17,9C,A1,FB,49,C3,8E,29,40,04,0F,9D,48,31,C3,14,85,EE,A4,FB,9A,D4,C7,42,40,30,A4,F5,85,46,26,30,B0,B8,FF,76,5A,3B,5E,CE,D1,29,8F,62,1A,30,95,DB,99,40,6F,AF,EF,B8,74,27,6A,27,24,C6,BE,9D,F8,65,45,6C,5F,D3,BB,9E,75,89,73,B1,53,5D,EB,69,59,C3,21,ED,42,AF,2E,08,31,3F,97,BC,5E,72,C6,1B,1D,AE,A1,CD,D9,37,A6,19,E6,D2,85,24,0E,FF,4E,9C,2C,5A,BE,CD,80,A6,BA,5E,2A,01,67,27,78,C8,E9,73,22,D9,28,2B,C2,F8,BF,B5,BF,90,82,05,B5,21,E9,91,AC,48,3E,0D,5C,05,E1,33,87,41,EC,6E,A6,9C,5B,E5,E9,90,0B,7E,F3,06,C1,A2,DA,2E,32,65,BE,CF,92,95,00,B7,68,31,92,70,7D,3F,24,51,24,A8,24,1F,EE,2E,E8,72,1B,B1,CE,C7,FE,6C,7A,C0,8B,30,01,88,2D,6E,BE,45,B0,68,76,32,07,9A,5B,52,7E,AA,2E,F0,5B,B4,6D,D5,0A,8A,2B,59,DB,26,78,BF,30,C4,80,7E,D3,8E,43,8E,90,D8,06,72,F7,BB,EF,39,74,F6,EC,82,57,40,A7,BD,D8,7F,AA,D4,62,7C,F9,8B,90,6C,C4,50,69,7A,62,DB,A6,F5,63,40,CA,DF,72,EB,58,AA,F0,57,22,82,DC,AE,24,74,A5,5E,40,EB,15,80,C8,8D,B4,E8,81,7A,5B,73,01,35,05,72,E7,AF,BC,EB,20,02,94,7F,C9,42,4F,25,9A,8F,9A,4D,6B,FB,93,F0,D0,D3,8E,4C,40,4B,B1,87,04,85,1C,53,CE,C7,AC,0C,98,CA,C6,CB,65,B6,6A,A0,8B,24,46,20,E7,6A,08,E6,76,A6,67,BB,28,72,A7,26,17,6B,B0,82,19,05,E8,CA,1F,D9,AC,73,6C,76,EE,0B,1A,35,2A,44,68,DB,F1,21,1D,E4,85,98,7D,19,CB,08,A8,B0,A7,D0,16,CD,3B,AD,DC,EE,02,28,E7,AA,B8,3E,72,77,92,BA,66,0D,56,17,5E,B6,A6,9C,23,8C,14,43,9F,2B,1C,3F,7D,1A,84,A3,31,AA,62,D2,85,99,95,93,7A,7D,62,4B,45,92,CE,9A,48,F1,B8,34,BD,87,48,52,0E,9C,13,BB,1A,BD,70,DE,11,8A,A2,69,E5,A3,9F,50,F3,8A,9B,AE,6B,03,AA,A3,0E,E6,52,88,F3,4B,08,1D,10,05,DD,91,24,C0,A3,7A,79,3A,46,E6,4C,13,D8,44,8B,ED,8C,47,31,44,31,4D,FA,38,09,22,FD,3E,27,19,26,69,B4,F5,39,23,DB,D3,C9,04,92,64,1B,00,85,89,00,5C,A3,BB,8D,28,B8,14,DA,B0,49,7D,EB,13,DD,0E,D2,66,48,C5,85,C0,6C,C9,14,DB,74,EA,B7,4E,34,0E,33,E3,89,DE,DA,55,F6,6E,3A,24,7F,5F,C6,0F,0B,F7,D5,61,65,CA,0B,0E,DB,2E,38,5E,FA,23,52,1A,52,6A,00,8C,72,26,00,CD,BE,A0,6C,98,6A,76,72,48,8A,DF,6E,05,54,64,9C,A3,B4,6A,47,9A,6A,A7,17,ED,ED,C6,6D,58,F8,F9,8A,8C,17,85,44,0A,8E,65,9C,04,02,D2,59,3D,31,88,51,0A,F7,D3,86,3C,38,A0,F7,96,43,68,5C,D2,E8,06,01,9C,79,8D,CA,3A,39,3F,4D,CC,A9,70,B1,78,97,C9,01,8A,8C,4A,79,F2,3E,B6,F9,BD,4C,B5,56,C9,09,4D,03,92,85,3A,97,0F,36,14,1B,C8,4E,73,92,29,E7,B0,70,9D,79,A0,BC,BB,C2,CC,50,9B,DE,81,BF,DB,F5,1E,EF,10,74,0A,A0,7F,B4,A0,F2,26,48,5F,55,53,31,4B,2F,E1,B6,56,C7,80,E2,2A,95,30,74,89,15,30,01,57,0D,D7,FD,1B,91,74,95,F7,56,44,A0,3E,08,A1,98,6A,DD,21,FF,DE,AD,57,90,E7,CE,8B,AD,F8,D5,86,87,2E,D6,81,7D,DD,7D,61,EA,55,AB,E8,BC,00,8F,0B,3D,99,71,60,7C,08,4D,2E,D8,E6,ED,0F,27,BF,DB,97,FB,42,5A,90,C7,8C,73,E3,8A,A5,42,23,C2,A0,BB,8A,6E,C5,86,76,B2,79,4B,99,66,AD,14,91,A0,C3,6D,FE,4C,3A,73,46,2D,88,5F,4E,DD,25,65,81,52,14,3C,A3,83,26,8D,3F,10,BD,8C,2F,8E,35,53,47,3C,BA,26,BB,31,6D,7E,76,8E,E0,DA,C1,A5,56,C2,87,7B,C8,61,5E,59,67,7B,F0,5C,09,EE,9C,0A,7E,18,0A,D5,25,57,2F,DC,A6,E4,69,C9,4A,01,EC,34,69,93,CF,1A,E4,4D,6D,1A,DA,CE,7D,44,5A,DF,5C,F4,0E,08,83,7B,86,FD,63,47,95,4B,D8,F2,FE,02,41,E3,A2,50,D4,2C,68,52,CB,09,83,0F,AF,8A,A8,B7,E9,A6,0E,EA,21,47,EE,1D,58,A5,8C,25,26,A1,D8,31,DA,6E,8A,92,23,C8,5B,E7,FF,70,54,F9,4A,92,D7,3A,A0,8E,79,8D,0A,31,94,1E,48,9E,69,6F,BF,A7,5C,9E,9A,19,8C,E8,BC,DC,87,E6,C7,AC,53,92,1C,D1,B9,C6,0E,62,E2,34,04,A4,47,D1,C8,82,83,29,93,34,BF,D1,8D,1F,32,67,BE,6E,4D,15,F2,20,2E,83,EC,26,B1,50,00,22,62,CF,BB,B0,09,F2,22,5D,23,FD,00,97,DC,E9,3B,AB,34,1B,CB,5C,B7,72,2A,2C,F4,40,A9,08,60,E5,BF,74,16,E1,B7,08,D8,4D,5F,2F,E1,CE,43,85,2B,D0,CA,76,D7,3C,83,07,07,50,70,A4,1E,24,37,E7,58,B8,75,A6,1F,67,44,12,B7,74,2A,4B,9B,F1,5F,26,B9,68,FD,66,88,AB,98,68,69,B9,0C,ED,90,6E,20,B4,3D,09,A2,74,3B,4A,70,98,A7,83,C5,AB,35,B9,2E,61,91,3C,8C,AA,D8,45,F1,33,EC,A2,11,1B,3D,6D,66,57,CC,B1,55,9C,55,66,06,66,38,66,55,49,45,3D,EB,9C,32,8C,5D,D5,73,04,AF,D1,2C,CC,E6,F9,9B,10,74,D2,B3,4A,78,A2,31,9D,F3,37,E9,EB,CD,E0,68,F6,9E,F4,91,05,6F,F9,B7,93,76,B7,3E,87,40,BF,8A,41,73,53,9C,E9,BB,CC,7E,03,17,8A,D4,16,7E,E0,5D,13,BC,C3,7F,08,23,A8,C7,9F,55,7B,D3,05,66,9A,A7,3D,66,B0,96,3F,BB,A2,BD,DD,A9,70,83,49,A7,20,49,32,1A,95,90,94,E7,05,F9,CD,B2,16,E1,1D,87,B5,A2,94,4A,5A,09,C0,24,DE,77,54,64,16,87,92,BD,D3,28,B9,2B,6F,CD,7C,39,74,0C,71,F1,10,DD,E7,34,F6,86,69,F3,64,03,D1,47,3C,81,15,E6,A7,DC,B9,9D,B8,D3,BE,B7,29,FC,80,EB,88,A3,6F,D7,76,3C,3C,F3,DF,16,E2,6A,CA,9E,5B,40,F4,97,1A,C6,A6,C6,07,C6,10,50,82,A1,81,43,C9,22,1B,70,A6,06,CF,1E,ED,39,56,5C,F9,17,A6,99,8E,E2,6C,B6,CA,A1,90,4A,96,61,AA,B8,4B,77,4E,67,1E,44,3A,C0,6C,CC,76,4C,5C,1E,7C,B1,82,99,02,D9,2B,D1,F8,68,41,34,59,4D,53,AC,C9,6D,B4,9C,F6,4D,4D,03,73,37,01,D3,2D,3F,CA,BB,0B,9B,24,25,97,71,00,38,F8,06,C5,92,F5,A6,EB,25,52,10,06,AF,9F,82,22,97,9C,CD,3F,BF,65,28,62,7C,F1,F7,47,07,81,20,FF,8C,A4,81,1F,7E,7B,35,15,42,AA,EC,07,9D,AF,08,63,F5,DB,B2,A9,09,C9,C4,36,2F,D2,2C,F3,4A,EC,15,E1,42,52,CD,94,95,FC,D5,5E,5A,A6,4C,95,03,D5,27,EF,60,65,F0,47,E5,35,61,D9,CF,CC,77,CE,8A,42,94,10,77,5C,53,9B,22,5B,9F,E3,BA,35,1A,09,E2,62,01,76,78,FF,9E,F2,39,D0,2F,C8,44,3C,F5,8B,A7,D7,91,FF,FB,66,83,9D,0E,00,AF,C8,CC,F6,B7,83,1E,AF,C5,85,C7,F0,DB,62,1B,79,49,DD,C6,88,2F,03,23,15,F3,20,B3,FA,20,C3,D0,1F,8F,55,B1,96,AE,F0,4C,7A,55,FF,5A,8F,EA,78,94,A7,E8,BB,86,AB,2F,CD,15,BA,C7,69,D0,90,A4,4B,87,68,62,B3,62,6D,D6,71,E6,81,9F,DF,23,2B,A7,7C,1E,97,20,21,E0,20,BB,A7,23,AB,F7,84,0B,0C,31,95,B9,45,AA,13,8F,A9,02,CD,7A,3C,90,BA,CF,A6,25,43,87,5D,AC,64,75,AB,8E,80,88,4B,5D,9F,BF,5A,EF,ED,E8,9E,EA,57,01,3F,FE,0F,91,63,F1,2C,C0,13,5A,2C,97,77,90,B8,BE,95,16,E1,C5,45,46,33,F7,4C,BD,73,04,1A,FA,2F,39,C9,AF,39,44,3E,9C,65,95,DD,65,CB,C3,11,CC,7D,22,F7,6D,CA,BF,76,40,26,DF,56,E7,36,C6,B7,F6,7B,C8,D5,CC,AA,6E,35,D8,75,6F,DC,D8,4B,A4,1A,1C,A9,F2,B7,67,FD,C5,C0,65,F0,3E,70,2F,70,3B,8C,8F,6F,4D,1B,33,AD,E8,C6,DD,4C,2E,6F,EE,1C,FA,40,84,A3,CD,2C,AD,CC,7D,BC,10,C2,54,8E,36,19,94,24,B7,E7,3A,03,BA,B1,05,50,92,82,99,53,32,FC,12,55,86,E0,B8,3D,B2,EC,E4,85,FD,BB,40,E0,E8,63,FF,3E,BC,95,0B,D5,89,B0,8C,C5,77,4A,DF,7A,0F,A1,D7,EA,F0,9E,63,A1,2F,95,9B,B9,78,66,14,E0,4D,0C,7A,69,08,DF,DC,56,DC,6B,01,5A,66,1A,3F,A2,74,BD,E7,96,20,4C,45,13,D8,09,08,BB,0E,65,26,5C,84,9B,33,F3,AA,32,16,BB,CC,DF,15,DD,2E,B1,66,5C,D4,76,24,72,97,01,28,1E,8C,15,86,76,F8,2D,5E,5C,57,8F,F5,DE,CF,63,6F,FF,EB,B2,CD,38,FE,9C,EA,2B,92,25,38,A4,C7,F7,EE,67,AC,E5,4A,79,E6,34,4A,36,84,C5,2A,FC,09,2C,95,E6,E6,10,CC,8D,8E,09,07,D8,F2,EC,39,0B,32,3E,E5,10,61,E9,00,E7,BE,BD,78,00,3C,B8,6F,12,45,F2,86,19,8D,E9,8B,2B,7D,6F,0E,11,DE,94,54,51,97,E8,28,79,5D,37,1C,92,4D,E3,E9,10,DD,CA,6D,49,3F,A3,5A,0E,A3,C6,E7,10,AB,88,28,DE,27,6B,80,3E,6C,C9,E6,7F,AB,45,AF,89,C9,92,C3,EA,9D,40,8B,2B,E2,C0,A9,D8,3C,F1,0D,91,D8,53,6A,DA,8B,C3,C6,1A,D5,A4,2A,7A,D0,6C,FC,3B,EE,AA,37,D2,8B,C8,5D,33,C6,F0,D9,B2,A6,BA,A4,B2,FC,8A,81,97,AA,1A,F1,BD,61,F8,12,D9,DF,50,33,00,9E,C1,53,9C,EF,2E,A4,A7,2E,A9,DC,14,26,FF,FE,77,94,48,0D,A9,41,69,3B,99,16,12,C8,86,AE,16,CA,25,3C,64,E8,20,6A,81,71,24,BC,5D,82,7A,A1,75,2C,63,3C,23,E4,94,37,7F,C4,65,59,12,7B,D3,C1,FD,DF,EA,25,ED,07,40,32,54,B6,9D,B1,6C,D9,C3,0B,1D,F2,56,F8,0C,42,95,CA,EF,38,64,89,D0,72,B6,BA,B0,11,BF,36,4F,86,EE,BB,D4,BB,92,7C,9E,84,AA,0A,FF,C9,7E,48,F2,11,3B,CD,47,C9,8E,A4,30,0D,24,DD,D1,50,CF,A7,7C,49,9C,1A,0C,AD,B3,56,44,0C,43,BE,9B,03,D2,20,87,7E,42,CF,36,59,E4,85,8F,E7,85,63,29,EC,64,CF,65,5D,D8,7A,4A,6B,93,F9,7D,24,B0,78,6A,52,E7,25,3C,A9,A4,41,35,5F,23,15,CE,9D,FA,7C,C4,26,BA,7B,D6,14,84,F9,FF,D3,AF,C7,9B,00,51,AB,30,C7,EB,BA,A0,08,EE,8D,C4,B9,F1,08,B6,8C,76,E4,53,79,FD,99,2A,C4,9C,20,F7,34,7C,4D,79,35,8D,2A,40,E7,8F,57,EB,AC,D4,6E,4C,79,D1,2E,08,66,ED,D7,93,74,14,80,AD,71,9A,50,63,E6,88,08,C0,00,21,F5,1C,F7,32,9A,A2,EB,45,C2,80,A1,4C,AC,18,61,E4,1E,4F,52,E9,EB,E6,1B,70,63,40,5F,00,CD,3C,2C,64,11,D8,3A,3C,2C,89,35,1D,F6,E5,ED,53,C3,46,79,3E,CB,58,A9,B2,2F,FE,21,84,93,0E,40,DF,2C,18,E3,78,8A,A0,7F,ED,DD,96,77,E0,EF,33,33,B1,FD,54,0E,62,AC,6B,DE,56,78,F5,DE,AC,D6,63,60,B7,A2,83,92,BE,D1,63,97,CF,B5,32,CF,32,8D,31,84,62,95,C9,33,EF,CC,5F,2D,18,75,18,7A,DE,30,5E,19,B6,AB,6E,14,8C,E9,9D,60,7C,28,C9,DA,3A,78,C1,23,90,03,95,93,4E,44,3F,02,22,9D,08,31,5A,7E,76,D3,A7,77,20,50,1B,40,97,84,69,A4,FC,A0,CE,D8,72,4E,BF,BD,0A,8E,BB,A2,97,36,89,7B,A9,28,9A,20,C9,45,91,14,99,F3,E4,7A,EB,26,25,0B,50,92,1B,F2,FB,06,8B,37,4F,75,B1,77,EA,86,6B,EB,1F,34,08,75,73,FE,61,9E,7A,E1,D9,E9,AA,11,B9,A6,BC,53,D9,79,D5,85,D9,D7,F2,BA,2C,22,7E,CC,C9,38,99,BA,3C,2C,A0,74,0B,8C,47,90,F5,51,B5,60,6C,D6,7A,B1,4F,3C,00,BE,35,6D,2C,1E,C2,45,EB,11,34,A9,E8,A1,3C,15,B8,CC,FE,CF,5C,D1,78,FA,55,D8,31,1E,0E,C4,54,5E,BF,7F,5B,E0,B8,0C,A8,BE,55,03,08,AF,62,8B,A8,E7,CB,08,8D,9A,F4,FB,EC,80,CF,D9,D3,8F,D3,55,F7,AF,2A,8B,09,22,71,17,84,AD,3E,DB,3A,C1,E7,7B,70,20,23,47,19,B3,13,03,31,F2,44,6C,66,69,DB,E1,5D,28,D1,7C,FB,4E,52,E3,9E,EE,84,17,80,4E,4D,2B,F0,6A,BE,64,55,D2,AA,6F,72,A3,58,65,AB,57,FE,07,C8,AD,7E,98,AD,9A,ED,30,04,6C,EF,79,06,C8,CA,51,BE,0D,FF,B9,D1,6D,AD,68,E0,20,D5,6F,09,53,5F,08,81,D5,4A,EF,69,09,86,88,34,80,A4,EB,74,89,BB,8D,06,77,AB,94,B0,9F,E3,00,57,F2,7B,37,8B,7C,02,32,65,A2,B6,02,52,3D,2E,33,F4,16,37,80,D4,E7,AF,3A,D8,BF,BF,35,79,03,B7,30,11,C6,60,50,87,89,37,8B,C1,BC,C9,EE,D4,0B,D7,55,60,31,68,E0,46,86,59,14,2E,3F,2C,E4,36,79,0B,6C,C3,EF,19,F3,3E,FB,41,5F,D7,BF,D6,80,DD,8C,5B,64,F5,5D,CC,CF,78,27,05,A2,6E,CB,AA,2A,EC,84,1B,15,82,8E,7E,E9,1E,24,3A,99,7A,6E,2A,78,12,77,60,D8,7C,79,22,5B,18,CF,AC,2B,20,1E,23,E7,59,0C,DC,4F,17,F8,D5,53,8A,FF,F3,FF,1E,50,A3,24,45,CB,4C,BB,42,D0,8F,B9,63,C5,44,F5,DC,8D,43,7E,1D,A6,83,7E,F3,B2,6E,45,50,A2,45,A2,7D,4C,14,38,AE,3B,B7,60,EA,A4,0C,B5,5C,DA,89,B1,8E,82,F9,19,87,5D,14,C0,5C,58,28,2F,77,19,AC,03,1B,E1,9D,A6,33,23,AA,CB,F8,1E,84,0F,9B,7D,46,00,AC,08,85,ED,7C,D2,4B,97,C9,CC,C7,8A,A0,9E,82,FA,A9,CE,34,BD,23,B6,BD,CA,CF,4A,E4,36,5E,F3,23,A3,14,28,A7,97,D8,4F,06,B9,97,A4,F0,45,7F,38,9C,BD,0B,14,6B,E5,D4,A0,BA,01,17,CE,CD,32,8A,41,8B,70,BC,94,BF,89,A0,6F,81,82,6C,93,F9,42,F6,CD,4A,76,94,A2,FA,2A,DD,11,11,5E,8C,68,5B,EB,E5,C1,9E,05,5E,A7,B5,13,29,A6,5C,CC,04,10,54,71,85,D9,7C,DB,FD,89,87,60,9E,F9,7F,8B,4D,E0,EF,9B,E1,E5,DD,2C,74,A3,5D,C1,4E,76,5F,08,68,71,18,5D,F5,1A,C6,9C,8F,06,26,F1,A1,0F,2D,6B,76,9E,BD,EA,EE,FE,76,11,70,C9,E6,DB,63,C6,11,41,C0,9F,D8,07,0C,99,33,3A,82,2D,66,38,3A,2E,CD,14,A8,CA,92,B7,8A,A1,5E,E3,F8,B4,23,A1,AB,14,E9,AD,E4,87,40,E6,F6,4D,9D,AB,97,EA,0D,B4,4C,C8,8F,A1,8B,4E,63,FD,75,FA,49,35,CC,BE,98,71,FD,0E,6E,DA,2A,6B,15,7E,D8,54,03,E4,4C,67,F8,9C,BC,BA,83,97,A1,46,9C,7F,A5,2B,1F,9A,1C,41,4C,5F,9A,62,93,7D,9C,2A,49,21,34,71,4C,AF,C8,C5,B4,70,BD,B6,B2,62,86,E8,1B,75,BC,72,5D,8D,44,9A,45,75,A7,84,00,E4,B3,0C,D6,A1,0E,AE,45,04,FC,33,87,4C,FF,F4,C5,56,C6,B8,9E,11,4A,17,C0,23,A8,49,21,08,55,F3,3B,7D,A5,D3,0C,C2,97,A3,10,4A,AD,33,11,91,EE,83,9A,75,86,BF,74,2F,11,B0,80,5E,3C,A1,8E,CA,37,75,57,C0,17,6E,87,E1,C8,73,FD,0B,E7,F7,D2,33,90,E4,A5,95,D2,B4,1F,17,1B,3B,D5,F0,36,93,85,56,D9,A3,14,9E,C6,73,C0,22,A9,98,67,B9,BF,5B,CC,9B,8E,D6,9B,CF,E6,9C,08,EE,E7,80,DA,DE,F4,6A,1F,12,C9,92,F3,64,F1,01,02,EF,C7,D5,BD,46,FF,AE,A7,97,7F,5E,18,3A,20,4E,DC,D4,51,07,EB,97,14,1D,34,A5,3D,0A,38,F9,ED,32,91,8D,C0,E6,26,F1,28,26,35,C9,3B,BD,54,13,89,C4,77,CC,52,41,5C,31,86,25,EA,AE,E4,D2,4A,C9,6C,74,38,AE,12,B5,7B,2E,33,E6,F6,EB,C4,56,2E,1E,99,CF,3E,18,20,2D,42,52,AA,A2,C6,13,EC,60,A2,A0,75,2C,60,BF,84,AB,06,3B,AF,A9,49,C9,14,26,2A,BF,05,AD,A1,61,B0,05,53,59,0E,A0,E9,33,1B,D4,5D,38,08,86,FD,3D,B0,4A,04,51,25,5B,D8,CE,93,AF,3A,47,FA,EE,4C,0D,02,9D,F8,20,64,A4,56,86,FF,21,26,79,32,18,75,99,30,66,56,9D,F8,DB,CB,0C,FC,7C,C8,38,26,91,FF,F9,E8,9B,6C,7D,FA,7A,92,9B,10,E7,19,41,66,ED,60,12,36,28,92,9C,4B,B8,4F,1D,74,4E,30,50,C7,0E,1B,8C,22,7B,0A,DF,D8,31,93,80,A0,BA,C8,13,20,7F,14,BC,A4,15,11,1B,2B,6E,0E,B8,99,BC,72,62,37,A1,CD,CC,AE,F2,EE,DA,84,27,13,CF,8E,ED,73,1C,87,72,E1,DA,4C,A5,26,D4,78,74,42,A8,02,84,40,47,BE,9F,FD,D6,7B,AB,23,14,FE,59,C9,A3,6F,4B,2D,A0,06,CD,B1,AF,39,BD,2C,A5,3E,56,2C,95,04,EC,38,56,3D,FD,0A,C8,FA,F3,BE,03,36,25,EB,4D,7C,70,96,C2,86,4A,93,DF,EE,36,DA,2D,D0,CE,A9,B4,36,96,FF,44,DB,3C,BD,D6,CF,BA,42,49,7E,3E,A0,FA,A9,AD,99,FF,E7,24,A2,D6,2E,04,B8,F5,A6,66,87,51,C1,00,2E,13,36,52,99,A6,DB,05,C3,54,B0,2E,55,A1,2D,5A,78,3D,8C,EC,F3,64,47,DD,F2,84,5C,9B,A4,4C,69,BF,F4,89,80,73,0A,A0,8A,25,C8,4A,7C,02,C0,36,65,75,F3,16,8B,A3,8E,83,E3,4C,7E,9C,67,E8,79,BD,91,9B,D3,BA,09,01,B7,C1,69,EF,B4,BD,A4,72,8C,AE,34,C4,BD,81,1E,EF,80,64,6D,75,11,E0,EF,86,AD,DC,9E,A3,55,29,36,93,B7,96,CA,54,5F,7D,C2,E2,FE,E3,17,A4,50,AF,5E,33,F4,37,F4,8F,5D,5A,C5,B7,EA,87,71,1B,0C,B3,B7,2A,9E,35,28,F0,30,54,68,61,D2,D8,1E,8E,8A,B2,F8,22,ED,A7,D6,30,FF,A6,1E,D7,D2,68,29,90,E4,29,EE,95,45,76,99,EC,AC,5B,76,E3,69,65,AD,D3,B7,D8,FA,60,6D,F1,11,AA,B1,48,C9,D5,A0,3E,2B,65,3F,6A,DF,29,AD,09,CD,F5,EF,00,BA,D0,92,48,46,65,4B,59,78,ED,36,BF,4A,B4,0C,68,25,1B,C4,03,74,0C,09,9E,DA,D7,0D,F2,BC,30,05,59,92,7F,DF,D9,F6,C3,8D,77,DD,61,47,2D,80,60,0C,E1,83,EB,41,26,D4,A6,50,ED,EA,81,BB,B3,A1,5D,F6,9C,B4,DF,BB,E5,67,D3,D5,14,64,27,B4,DC,8B,DD,58,5E,4A,03,7A,1E,11,2A,47,02,F2,54,BD,BC,AC,E5,95,C1,04,EF,D2,EB,FD,8D,B6,F1,7C,05,A8,5E,11,69,A4,16,38,22,F5,BA,FA,2F,D5,8F,FB,5D,BB,D4,4A,C2,44,B7,E2,DE,DD,67,11,96,0B,9B,2E,62,41,43,A0,17,79,93,85,56,19,2B,4E,53,ED,EF,18,82,6C,83,E0,93,47,D4,AA,5A,49,C5,7A,82,AB,CE,02,30,63,44,89,F6,F8,01,35,67,7B,95,83,8E,01,20,DD,19,F9,71,E8,19,F4,4D,08,F6,25,C2,21,64,09,2C,07,70,21,E8,08,E3,D5,4D,42,9F,00,4E,58,FE,06,AC,6C,D9,0C,6A,83,98,60,CF,34,E3,9D,6B,2E,82,B3,D4,66,0C,87,4A,5B,5B,20,FE,E7,02,29,CF,54,4D,2B,00,97,DB,3F,CA,EC,3E,70,84,16,6D,4E,86,02,07,3E,AC,35,7D,26,AA,88,47,56,65,01,D7,71,CC,62,14,6C,67,91,64,48,FE,6A,19,1C,17,02,C1,B4,F5,D5,84,7C,D4,35,C4,9C,BF,9C,46,24,63,AD,21,41,72,68,4E,86,98,9F,1B,6B,B7,4D,7F,81,C8,38,FA,5C,3F,41,6B,1A,71,62,5F,07,F8,C9,BE,B2,BD,01,E1,99,A7,C0,D9,5E,3F,A8,99,60,6D,36,5D,9C,20,0C,F5,E6,88,6F,82,F3,FC,E7,F6,D1,4A,D9,E4,97,A1,41,B6,3B,2C,73,9C,40,D7,BE,60,F9,FA,0D,2C,22,4D,A6,72,1C,48,9B,84,4C,3C,D2,9B,15,C6,8A,FD,00,41,E8,EB,84,EF,24,69,9C,5E,F7,07,37,A9,6E,9E,81,63,F0,FC,38,EC,08,17,83,BB,F7,CF,50,34,BD,78,E0,43,04,A8,A4,74,28,4B,46,1E,6F,02,D1,02,A3,4F,1A,3F,6E,4D,98,93,8E,79,08,E8,D6,84,FF,44,B6,AA,04,72,3E,8A,77,93,3F,94,4A,23,FD,B2,1E,0E,7F,5C,27,40,66,8A,06,30,6E,BC,82,5C,CD,6F,30,6D,79,C2,DA,A1,DC,4D,D2,3F,29,C1,1F,35,7B,DE,55,53,19,EA,0F,A7,F0,E8,4C,51,70,19,18,9B,4B,35,FC,67,64,BC,43,22,24,5A,4D,8F,C2,7A,76,C3,F9,52,8F,0F,3E,F1,14,3B,9E,CD,F3,19,7E,5F,5E,FA,F7,97,4C,D3,36,79,AD,2B,B3,38,74,76,C6,29,E9,9F,F7,FD,E7,33,A6,43,BE,CE,80,AA,BF,59,26,A1,5C,C5,44,44,8E,4F,1D,C1,7A,2F,A4,B3,4B,1A,11,F9,1F,62,8E,C3,80,3F,B0,51,9F,C9,36,42,4B,BF,2D,20,BC,37,71,71,34,15,38,59,A7,D1,F7,03,BE,47,B1,8A,62,52,0F,16,39,F7,9C,71,6B,08,EC,F7,DD,D3,8C,26,5A,EA,15,BD,4B,1A,03,59,E8,B5,0A,37,CD,68,81,18,C2,BA,13,25,A8,66,3F,9A,CF,3A,4C,C4,1E,43,2E,6B,F5,3F,07,3F,82,30,A0,B2,B4,48,C2,93,67,A8,E6,DE,6B,F7,A6,F4,42,B8,28,94,95,54,64,05,FA,BC,9B,3D,1D,64,C1,6E,30,E3,F5,9C,F6,43,F1,A2,A2,B6,74,A6,C7,26,EB,31,35,B0,EA,EF,58,2A,CA,AC,45,34,20,CD,FD,42,5E,4F,84,93,DB,F0,1D,E9,95,7A,B2,5C,92,31,5B,E3,DB,07,36,3D,3D,6E,79,5D,4C,51,25,B1,F0,6E,73,0E,10,3F,9E,2D,F5,B8,81,D5,28,FF,59,AA,47,EA,E6,0C,8D,15,95,A5,F8,F5,73,15,60,53,3B,2B,D3,7D,99,BD,0A,34,CB,88,72,9A,DC,88,B7,B7,93,3D,F8,C5,76,B6,56,18,67,EA,B8,0F,B5,95,22,63,BC,BD,47,1A,2A,E8,B6,F0,11,71,B8,23,0A,0F,6C,2E,4F,B5,12,34,BE,08,9D,57,5F,3A,6B,49,6A,56,94,AC,B5,17,7F,0E,C5,24,8B,FF,A2,E3,2D,56,F5,48,97,41,A7,17,E4,3C,D1,78,50,FE,E6,0F,F7,24,E5,69,60,DF,0B,DA,9F,71,D6,6F,BE,B2,12,9C,B8,DF,23,DE,E9,A1,55,B4,44,CD,97,35,D3,3F,9E,2E,66,F5,A5,6F,A0,32,30,76,9A,BF,4B,94,02,92,D3,BF,54,FC,2F,3B,DA,0F,32,A7,2B,71,26,A4,34,2B,C7,68,65,D8,08,AE,AA,BB,4E,5F,3B,E2,03,A7,89,F4,97,4F,60,15,80,7F,B8,DA,22,9E,A4,85,A8,54,71,ED,88,20,89,70,5C,83,E0,D0,C8,71,82,8F,63,AA,22,C8,27,A5,18,B8,FA,85,35,CA,4B,E7,D9,4E,D1,10,2D,87,BC,1F,1F,50,85,7D,5A,49,1E,FB,A3,1B,D0,45,01,B1,C1,98,F5,C8,61,67,4A,E5,A1,82,79,0D,A9,CF,AA,6C,4E,9E,55,44,C1,4A,18,55,5E,4D,03,0B,9A,B9,BC,B9,54,AE,F1,9E,C7,70,58,66,75,1E,84,8C,2B,B4,25,F2,6B,F1,9B,FE,EF,7F,B2,D7,01,67,8E,D5,13,3A,1B,DC,D7,96,BD,FE,40,09,4C,19,EE,86,CE,DA,F5,1D,75,1D,8A,17,17,AE,7F,D6,76,8E,CE,67,3F,82,F9,C1,BB,7F,7C,72,AC,9B,32,FD,29,37,AC,34,1A,65,4B,E3,AF,F1,2C,3C,EB,B2,94,3B,62,24,73,EF,F6,C2,B1,A4,1B,CC,07,41,5B,63,C8,A1,9B,EB,88,3A,D5,39,5D,10,E0,95,17,AF,2A,80,7D,FE,16,8E,5D,21,C2,9C,41,E8,81,EA,0D,8C,E2,65,29,17,6C,C4,F0,00,DE,5B,99,36,A6,85,DE,09,6B,67,07,54,F6,53,10,AE,7B,14,85,53,1F,A4,B5,C4,04,1D,9D,0A,30,72,F5,C3,A0,FF,D8,EA,17,DA,0D,58,36,11,45,04,E0,B4,BD,A4,08,51,68,DA,DA,07,4D,02,CD,6A,1A,F6,0E,F8,D1,D1,CE,07,73,68,79,66,C5,8D,32,6B,B1,45,A8,9A,6E,4F,DF,21,CD,AD,69,C0,C2,52,8F,5C,42,7C,64,8C,27,FA,14,A6,24,4F,8C,1F,13,CB,1F,0D,64,C9,70,9E,51,31,5A,44,0C,49,09,AF,44,FB,9C,3F,81,2E,20,63,F9,06,09,E6,5F,57,2C,36,D1,59,09,B1,1F,B1,BC,96,C6,B6,04,FA,30,2F,64,5B,74,DF,8C,E6,16,0B,6D,8D,61,11,40,A8,B4,70,A4,C6,67,6E,C3,6A,AD,78,88,09,16,CE,F1,22,AB,27,B4,D9,8B,2A,94,93,44,0A,3A,6D,B0,F9,10,C4,DC,D0,1F,81,20,11,57,A7,EA,87,6C,BB,1A,2F,BD,6A,9F,13,A2,BD,44,D2,13,D4,E7,DE,8C,1C,4E,FB,BD,A8,B0,0D,72,B1,8F,81,6D,18,85,C8,AC,29,A5,CD,32,C8,63,02,70,16,50,8D,F7,56,45,4E,F2,59,9B,49,FC,0D,84,37,19,3B,34,20,34,F0,B3,3E,E2,D7,DD,8B,72,7C,7D,EC,D3,64,F5,5C,4B,64,51,95,99,86,8D,6F,8A,37,1C,27,6B,FF,CF,EF,57,58,3E,83,98,2F,A4,FE,2C,D8,66,41,D8,F9,FC,88,BC,40,FA,BB,CF,DB,B0,D5,8C,A8,53,EE,D8,00,57,7C,6B,8D,C9,2D,DE,53,84,1C,A8,73,5B,06,BB,3C,6D,C2,CB,F2,9D,F4,24,9D,49,F5,44,1E,DD,F0,9A,0D,15,12,D4,CC,D7,42,D8,78,08,D2,12,D5,C9,66,57,EB,67,C2,26,29,EC,86,E4,E8,82,5F,78,6D,E8,8C,DE,A3,89,E6,38,AE,17,5B,CE,FA,E2,95,5D,9A,D2,54,1F,79,BB,41,3F,74,A7,A3,17,DE,C7,08,BA,01,88,22,43,29,0E,41,DF,83,F8,F7,26,17,C0,44,03,BA,CC,21,4D,EB,BF,18,78,C2,BE,7D,06,D1,F1,2B,FB,EC,C0,85,BC,4D,E1,16,78,59,F3,83,66,D8,F5,91,CC,93,80,36,DC,D7,E1,1F,F0,B1,38,75,36,33,16,9A,70,80,D8,A1,9B,FD,93,AD,FE,BD,87,12,44,B6,DB,C5,89,FE,1E,AD,52,D3,DD,4B,6C,2B,12,76,BF,67,F8,B4,B5,A0,74,78,A9,54,D1,17,92,3E,28,E5,5E,AE,FF,11,89,A7,B0,81,9A,9C,19,7D,56,D7,B5,61,8A,20,B5,2F,2E,C3,A7,3A,72,C1,BC,C5,DE,2C,B1,4A,86,47,4F,7A,B7,D8,AD,19,D6,59,C0,9C,47,2F,73,3C,F9,4E,00,1C,80,51,ED,3E,D0,92,1A,37,29,93,8F,84,3C,EA,AC,ED,85,A1,56,E4,81,D1,C1,F0,BE,EA,90,C3,4F,82,A0,F3,BA,C3,BA,9B,93,E3,16,AE,A7,BE,E2,34,CE,B2,19,FB,65,9B,59,07,FD,AB,D5,C8,8B,DD,C5,A0,18,11,D8,11,D9,83,12,8C,95,5C,F5,E9,76,63,82,6B,C6,2C,9D,28,D9,B8,92,07,26,F3,6A,BA,BA,70,03,B4,CF,B2,04,12,83,94,7C,9E,78,11,EF,62,A1,C4,34,29,F0,35,F7,6B,4C,2B,48,11,01,05,27,1C,3D,F1,DE,C8,FA,4B,9E,FD,52,68,C2,C7,E8,18,E9,F4,6E,FD,3D,EB,1E,08,31,C9,50,CE,B3,D5,4A,BB,AE,7D,86,29,30,1C,86,C8,1A,68,5C,84,74,8F,A6,86,3F,AC,CF,FE,AA,16,9C,16,BF,88,9E,D0,C7,E2,1A,25,7F,49,E7,82,30,65,55,09,8F,6B,A1,D2,26,55,0B,CA,FA,FC,BC,9F,15,33,D4,63,48,DC,08,A7,7F,22,7D,AB,0E,9C,8B,26,9A,1B,3F,69,79,D2,72,D4,12,E1,2B,93,CC,33,65,49,E4,79,F0,4B,0B,13,21,3B,C0,5D,AE,EB,0E,0B,C8,1D,CA,8B,A4,34,90,CD,CE,26,3C,13,A2,EB,17,D4,89,49,B7,6E,C8,F6,45,16,E1,B7,AD,18,CB,56,30,BD,2D,D8,58,7F,79,4E,7F,16,EA,21,DB,66,15,75,7B,27,F5,A2,83,AB,C4,0D,9C,E6,1C,76,30,60,23,67,BC,5E,24,DE,C6,CD,EE,26,D2,16,ED,24,7D,64,3E,5A,0D,89,FF,0A,CD,BD,3C,9A,D8,35,79,C2,F0,81,87,57,12,4C,BE,C2,E0,D7,8A,31,32,79,D3,2A,13,7F,06,12,8E,BF,96,31,A0,D5,70,4B,5C,95,F3,1B,59,A1,E9,3C,3A,E8,15,8F,C1,7A,F4,70,48,1D,13,E6,9B,0D,0E,26,93,74,B0,C2,D5,E8,E4,7C,98,E7,F7,23,95,E6,B3,A3,47,6E,D5,CA,8D,C6,81,83,48,BB,58,8C,17,1B,4C,AA,EA,47,27,C8,1D,BD,38,57,73,6E,B5,9D,D0,97,CE,21,56,06,D5,8C,9E,C8,C0,A1,F6,8F,50,EE,BF,30,B6,45,89,98,31,E9,02,10,12,0C,AD,E8,DC,4D,BA,19,67,D0,D1,89,17,30,AB,CD,48,4E,37,97,50,97,1F,9B,47,86,B3,45,95,4F,85,79,4C,CB,31,BF,92,10,D2,B9,AF,2C,32,F8,38,A9,44,BC,33,39,4A,37,9E,73,4D,69,95,87,87,9D,E9,63,40,56,FE,DB,E5,54,A6,B7,FB,78,07,6B,E0,51,3E,E5,E8,8E,34,76,F2,B6,F2,91,22,D7,FA,0C,D3,92,71,39,15,98,28,0A,E8,48,07,7E,93,18,83,05,F0,74,24,BA,FD,37,AC,4F,AF,D9,CB,59,F5,EE,A0,02,15,C0,D0,53,38,FE,28,49,24,62,6A,A7,75,1E,87,46,C1,39,32,70,CB,E3,1C,48,9A,85,B5,C3,48,48,D3,22,C3,EB,8D,E0,7B,08,3E,04,23,88,9B,9E,B3,DD,FC,B9,A0,A3,20,77,EC,41,BC,45,B8,A2,A8,E0,5D,99,09,64,B2,21,92,AE,73,F1,6C,6B,98,35,7F,C7,9A,16,AF,15,07,5B,D4,AB,BA,C5,FD,53,4D,C4,30,BA,95,AB,9F,3C,D1,7B,C3,DD,5B,4E,5E,11,84,4F,F6,88,31,56,73,E5,2F,90,86,A3,C4,B0,2E,56,32,B4,55,D4,8D,81,AD,7F,D9,C8,2C,F1,EE,76,20,9C,BB,31,42,70,95,9E,1D,3D,42,21,0D,8C,CD,F9,16,6D,AB,4A,01,A8,F4,D6,A0,FF,0A,56,55,EE,6E,6A,72,70,04,89,47,EB,04,4F,56,24,F1,48,AA,79,75,5C,B7,6B,EA,C0,B2,F8,A9,ED,E1,53,D6,13,8E,07,00,D5,66,4F,F8,B1,00,B4,AD,86,4F,FE,A2,80,DF,87,AF,90,4F,BE,52,92,FB,F4,54,04,12,F3,DC,05,F5,50,7E,A8,78,DB,88,29,B9,E0,A9,6E,CA,0C,98,1A,CF,8A,FF,9E,E5,24,01,9F,F4,D7,21,26,DE,BB,C2,F2,FF,FF,21,20,2A,50,A9,A8,C6,18,91,A3,9A,A9,0C,29,25,4A,F0,D5,F4,2B,94,2C,76,97,EB,80,51,8C,60,9D,7A,46,32,4C,E0,C9,80,68,56,87,24,4B,C3,6C,11,39,BC,BB,3B,64,52,7E,19,FB,30,58,AE,FE,EB,D5,7A,CB,C8,7A,AE,EB,52,E7,1F,20,8D,9B,99,CB,D4,44,6F,AD,04,24,45,30,37,4D,51,EB,AF,2F,A4,E4,88,E6,98,53,78,7D,27,8B,EE,CD,02,1F,6A,8B,59,B0,6B,96,47,6C,FE,6D,F8,95,C0,6D,D0,FA,C8,B0,24,DB,B6,7F,E2,70,07,17,65,2E,1E,F7,01,BC,48,E7,37,4B,B4,D5,28,20,1B,5F,27,73,AD,DA,8E,AF,70,E8,37,45,FA,0E,76,B3,C7,F4,5A,7E,20,25,B2,E4,2D,C9,8C,50,5F,EC,53,2D,40,84,D9,AC,1B,73,08,D8,F9,5E,D1,9E,02,92,D2,9B,C5,61,CD,A7,E0,F2,A4,0E,6F,F7,CE,4E,FB,51,96,2C,69,F6,97,49,F3,71,C8,66,5A,2E,2D,1C,B6,FA,95,A3,F6,43,DA,04,7A,B2,0E,78,08,67,C0,77,04,9B,28,47,BF,B3,EA,28,23,F0,F6,B5,4C,18,4C,68,4A,A3,AF,A3,35,B2,BC,6D,76,07,A6,53,CA,53,58,B3,17,D7,B8,BC,1C,26,3A,23,F2,76,E4,05,4F,74,B9,D5,E4,98,B8,DB,CA,3D,83,46,48,EE,E5,C0,3A,E9,08,B9,D8,00,E6,11,D2,09,6E,D9,8F,BC,EB,F7,6A,33,AE,18,FD,C9,DB,26,37,45,16,0F,8E,20,C2,E8,6B,02,5C,3B,4C,D2,49,2A,53,4A,17,1E,DD,CA,07,62,51,EE,AC,42,A9,F0,67,A9,5E,5D,E4,AF,CC,53,2A,4B,A9,57,83,34,E2,DB,CA,E3,E9,EA,BA,A9,89,3F,EC,BB,9A,70,C4,95,69,F6,AA,A4,78,37,D7,01,38,34,A6,77,C9,F3,5F,50,B4,E1,9D,94,67,8F,D4,9B,A3,87,50,49,2C,15,2C,06,FF,28,B9,58,19,9B,3B,AA,C6,DB,BA,17,24,C4,79,BC,43,CF,A6,2A,26,DA,63,A8,28,F6,96,9A,68,A6,BF,03,8A,82,01,90,F2,D5,93,AC,0C,B5,05,00,36,65,FD,87,AD,01,60,75,65,BA,D3,3B,00,C6,83,8E,B1,95,B5,4C,8C,41,D4,92,3A,F2,F4,3E,5C,28,04,3A,4C,89,75,2D,A0,ED,0B,76,ED,BD,50,4F,E3,17,50,CE,E1,AB,03,0B,50,72,5E,CD,BF,ED,E7,9C,A2,E1,21,B5,E2,53,ED,A7,C4,85,C6,E1,AD,78,8E,3F,68,F0,67,76,A9,32,2C,AC,AC,20,EF,0E,CC,0A,A6,42,5E,16,31,8C,47,1F,8F,9A,F2,2A,43,62,07,71,EF,0D,45,D1,46,24,10,08,2E,3B,FB,41,C2,92,3A,8D,55,12,36,7E,EA,FC,A3,5B,C1,70,08,76,D1,DA,1B,88,03,5C,7B,EC,FA,D4,64,91,5F,B3,13,53,23,A1,BA,46,4C,57,6E,0C,30,D4,4E,4B,39,33,B4,72,6A,30,A3,87,33,42,C6,5D,EB,28,C4,D6,1E,76,24,E8,4A,2E,C0,EB,CD,09,88,29,3D,3B,89,D8,A6,AE,F9,6B,A1,76,B7,68,77,9E,C4,A6,A4,3E,E4,89,2C,26,D9,59,8D,44,45,D8,E6,67,22,C2,0F,91,D7,2D,FD,B1,22,93,85,A4,94,43,16,67,F7,94,74,57,BB,FB,7B,97,BD,3D,09,11,7A,07,FF,B7,A4,A0,FE,55,37,7F,D4,FB,C5,ED,4E,A0,F2,AF,71,D4,56,C2,16,32,61,12,BE,A1,76,B9,96,7F,2A,8A,16,2A,D8,19,83,38,A2,14,7B,CB,3C,6C,FA,57,93,34,0D,BF,FD,98,FE,7F,5A,1C,48,08,0D,32,0A,B7,F9,B0,0A,F6,C0,2E,67,83,47,C5,E7,76,EB,38,7F,80,D1,FB,AE,10,2D,50,96,D0,D5,90,9B,61,F7,1C,6B,14,EB,7F,24,D7,26,23,D6,77,7D,ED,C5,79,6D,AF,09,57,C0,BA,04,EF,94,34,E9,1B,E8,B6,99,7A,10,C3,0F,36,AC,7C,A9,E2,D2,71,1C,3E,8F,85,2B,1D,AD,91,E1,43,7B,B1,D8,4D,73,F9,BD,D6,BE,20,3E,19,E1,7B,F3,D3,62,84,37,F2,68,C1,D4,2A,11,1F,D8,A6,53,F3,F7,E8,98,3C,D7,E7,2C,9F,FC,36,D7,86,96,5F,6C,DE,2E,3F,A3,0D,CB,FB,6E,BC,58,1A,9E,33,20,2C,D4,21,6F,76,61,A8,D2,9B,A8,0A,B3,DE,C4,46,A6,97,4D,E1,E4,3A,0A,A4,1B,94,34,9B,12,D7,97,08,F8,EE,66,66,11,F4,95,87,0D,6E,12,3D,56,6F,44,59,0F,6C,E0,79,D6,D1,22,AB,E1,56,20,DA,55,20,D1,3D,99,14,6A,AD,84,C0,D9,10,95,D5,CA,2A,57,F9,93,1E,2C,F9,D7,3D,65,FD,AE,D8,8A,7A,7C,D4,CF,EC,EC,25,55,4A,9F,1F,AD,27,05,F6,0D,FF,93,6E,0D,A7,38,CA,01,5D,6A,D4,D1,93,86,4B,82,B3,FC,6A,72,AB,48,DF,EF,DA,BF,F9,E3,91,70,6D,54,3D,C6,E5,E5,07,68,87,64,36,37,E1,33,C9,04,B6,44,36,C8,1F,EF,92,A5,87,B3,F7,29,60,F5,33,85,FA,A6,68,ED,C0,4F,04,80,9D,F3,54,70,DE,E6,BE,6C,8F,A2,9A,CE,6F,C7,A2,22,FB,EF,13,24,DF,7D,3A,9A,C0,39,CF,21,B0,4B,A8,72,F3,92,7D,3B,78,87,E5,91,DB,0C,BB,44,5C,1C,AF,F2,52,AF,BD,8B,1F,35,FA,4E,E5,28,00,16,7C,47,9A,E2,3D,9E,73,D5,33,9F,1C,3B,14,39,7D,6A,E4,4D,7D,6C,05,16,E8,48,2A,A3,81,3C,B8,31,32,52,60,66,60,6C,9B,35,0D,F0,01,2F,11,3D,D2,BF,62,B4,23,2B,5B,90,AD,00,01,3F,3A,23,0D,5F,0C,06,F2,6C,15,5E,24,3F,F0,A0,3E,4D,0F,72,D5,67,E1,E0,6F,40,69,BD,8C,CE,92,DC,12,1F,A5,F0,B8,BE,BA,D9,06,3D,1F,65,E8,F8,5E,C2,CB,48,BE,02,20,05,BD,CC,96,F4,6E,39,C3,90,BE,06,A0,AE,FB,3F,59,DE,64,D8,7F,3D,84,89,F1,54,AF,1A,89,CF,13,36,7E,26,66,9D,F1,38,61,6A,D6,18,EA,98,00,A8,62,3E,88,97,2D,7C,76,A9,03,24,E8,A2,B2,2B,6E,8E,39,F3,8C,58,EF,8F,41,06,FE,6C,F9,41,71,98,01,CE,C1,C3,A0,83,2E,64,C0,B2,28,F5,B9,A2,F2,F7,A0,72,8A,D4,7D,1A,15,02,C0,A4,83,6A,9B,AE,3D,69,93,75,8C,CA,2A,23,05,56,EB,91,7D,73,C4,89,9C,2D,D1,75,FA,D8,FF,BB,5F,D4,58,EA,C3,B5,EC,ED,8F,49,C3,54,C3,99,F0,35,B8,6B,5E,62,D6,4B,99,86,C7,45,12,82,3C,D3,5C,03,97,5A,31,70,DC,7F,76,84,59,E3,79,76,B7,A0,20,D9,CA,46,F5,54,1F,6F,E3,2D,04,7B,85,B3,DA,AD,99,BD,6D,1C,E3,44,84,D9,D7,D5,59,B8,64,0E,E6,C4,FF,47,02,69,BA,8D,F4,53,87,B3,F4,24,2D,FE,7C,C4,B4,86,11,A4,80,60,5D,9B,A5,92,07,0D,4C,90,06,4F,E0,5B,3F,21,B5,AB,F5,FA,63,9F,AA,39,1E,AF,F5,85,38,5F,AD,F4,91,DE,40,46,1C,D2,8E,A1,08,F4,73,94,76,AD,42,0B,45,1F,0E,51,8B,98,31,BA,F4,99,0C,8E,01,07,32,38,55,20,1D,89,DA,2A,32,B2,D5,CF,B6,76,E7,DB,4E,01,85,64,4C,6E,5A,89,1D,1B,74,D7,A1,A7,63,AF,99,9B,45,36,A2,61,46,20,AA,A4,F8,AC,95,61,3F,50,A2,6B,B7,5A,AC,A2,B8,40,0C,72,53,F3,C4,29,4C,3D,F4,66,C2,4E,61,B7,FF,1C,47,A1,82,3A,18,CF,B0,B3,D4,AC,2E,2E,7D,B0,AC,06,3B,FD,0C,B8,F6,F7,13,C1,70,7C,04,4E,16,77,27,48,69,63,CE,43,FB,D2,AD,7E,B4,00,8C,B0,92,06,12,A2,81,7A,E9,32,1A,06,6D,EE,61,39,98,28,E6,77,A3,A8,9A,2C,E6,6D,45,AA,AF,4A,18,09,AE,7A,4B,9A,3D,D1,CF,05,02,5D,67,4E,C9,CD,9C,1B,49,72,CF,89,64,FB,91,EE,5B,9C,CD,E7,F6,8C,67,B5,B0,E4,7F,77,AD,93,BD,DB,BC,05,9F,0C,71,3B,81,16,41,1C,2D,E6,D3,4F,E1,16,32,F0,EE,5F,86,A3,23,3C,D4,2D,28,71,4A,A6,84,B1,13,DE,BC,F3,3E,5A,CC,84,FF,30,76,B3,06,F0,10,A5,B0,82,4C,FE,D7,25,E0,66,58,59,9A,36,68,3F,BD,51,DB,90,E3,C4,8B,65,74,D3,71,64,64,A8,D8,D1,52,61,E8,05,5D,10,A3,AA,CD,37,BD,FA,C7,A3,B8,3B,64,42,E4,64,87,AE,CC,F1,A0,80,E1,56,D3,0D,12,F4,81,3E,BE,3B,35,4D,11,A5,86,BD,E6,B7,62,8A,9D,D0,F6,DE,8E,41,7F,D3,E4,8E,43,89,AD,3A,13,7A,8E,77,F5,DE,AF,C2,53,DA,29,A1,33,92,3C,65,2E,63,A3,38,FF,D7,97,66,C2,B6,1C,FD,F5,4B,2F,F6,92,A2,4D,3C,28,20,A4,FC,E6,3C,44,87,AA,E2,9C,63,97,0C,1B,B3,47,02,2B,4A,E5,53,77,96,C7,C8,AE,E4,AB,D3,35,91,7A,A7,58,B9,48,56,18,99,EB,9B,5C,C1,7E,D0,B2,3F,25,81,7A,F8,EA,09,24,B2,FB,03,15,4C,04,C9,75,EB,91,5F,89,7D,57,7A,F8,2E,FF,D8,05,5D,82,CE,B3,AF,D6,35,51,73,B2,44,4D,58,F5,A7,3E,76,96,7A,8C,A6,4A,B0,75,02,25,36,BB,E8,1E,9D,2D,E0,96,5F,8E,F2,1F,8C,59,72,D8,12,18,2B,EA,4D,4F,B6,28,61,25,EB,40,D0,A5,BE,72,0C,D6,03,9E,0B,50,7F,21,8E,04,18,5C,AD,3A,0B,4E,69,62,BA,CD,AB,5B,12,6A,8D,D1,C6,1E,D4,09,BF,C3,86,52,54,A5,6F,65,7F,32,93,E8,2E,0D,80,44,66,16,79,AE,03,46,C0,1F,42,C0,E3,CC,B5,60,C2,6B,DD,A8,8F,84,74,AA,9F,89,F3,EB,05,6E,ED,61,07,3C,81,29,28,1D,F4,7C,52,37,3A,9D,92,BC,2E,F4,CD,86,76,66,32,4E,3C,46,D7,47,31,A0,8A,59,FA,B3,F7,CF,77,D1,CA,E1,9F,4C,D3,41,80,64,B6,46,68,50,D0,9E,D8,E7,88,E5,AA,52,D4,0B,41,3D,1A,61,D9,46,71,84,A8,A2,D4,C5,B7,6D,D5,2D,8C,94,B1,F3,09,EC,54,23,C3,B3,8F,8A,2F,3C,3F,C3,29,41,A7,5D,F9,DB,1E,48,60,56,60,70,E2,03,27,4D,28,30,54,BD,B7,15,BC,18,2E,FF,4A,20,AA,00,DF,F6,38,93,ED,01,DF,C6,00,52,B2,70,46,2D,EA,19,8C,CA,F4,74,02,76,01,50,87,4B,E8,77,21,3F,17,2D,88,78,FC,DD,A7,52,14,D2,11,DE,0E,81,0E,86,1A,8F,1D,81,46,D9,39,8B,E5,9F,4F,AF,7B,AA,5E,52,C8,32,8C,22,86,BA,CE,77,9D,4A,F6,34,47,4A,F1,08,40,4E,67,D2,72,2F,51,6D,CA,A1,70,83,78,B4,72,1E,40,86,5E,ED,4F,B7,E4,7A,A0,A7,8A,34,24,2E,E6,E0,1A,34,A8,06,B6,F5,CD,76,C5,7F,FE,7A,BB,01,9A,A1,7B,9C,28,C8,BA,D8,4A,4C,FB,6B,C2,B2,99,E6,FC,9C,88,47,2A,C3,92,EA,C6,9A,31,07,37,3B,72,AA,F0,13,DE,1A,AD,47,56,9B,10,05,01,AE,B2,94,24,E7,28,A2,31,B1,7E,BB,5C,E1,03,A4,3C,D9,24,B6,C8,05,F5,54,1C,81,8F,26,8C,5F,DF,04,C2,3F,3C,C8,72,36,86,2B,EE,DE,9D,E1,52,3C,2C,7C,9D,45,7B,4B,C5,C7,8C,C1,D5,F9,BD,5B,32,8C,7E,5A,17,F3,DC,1F,99,72,55,1B,EC,26,72,C4,20,0E,0F,CF,CD,64,F1,D8,6C,80,9F,1A,7C,F4,27,97,9B,72,35,72,41,42,D2,D5,E3,C0,34,B8,C9,3E,E1,C9,64,E8,2B,09,9D,54,CE,C3,BA,20,C6,14,DA,9A,70,90,34,23,77,4B,EC,72,6E,29,E7,4B,11,8A,8F,F0,32,64,5E,8E,B3,B2,0C,DB,66,51,4D,6F,6F,20,B1,61,1A,B4,09,95,5C,32,1C,D3,57,82,65,5D,F5,81,D1,EA,56,24,6A,DC,09,CD,F4,6A,D7,15,15,E7,11,A6,A6,8F,1F,D1,EB,4F,F5,18,D1,10,C5,3E,B0,B8,6E,6F,0C,86,A6,EB,06,CF,A5,B1,18,A9,1D,4C,43,C7,9F,2D,0C,3B,61,31,2E,4C,A6,29,F9,0D,5F,64,DF,13,C1,35,E0,2F,77,36,6A,D6,E8,49,64,40,FD,D9,D5,4E,04,56,AF,CD,B0,9C,95,D3,2F,81,E2,71,1F,24,C2,A1,05,2D,C5,12,06,0E,10,D3,1C,11,39,0D,47,3F,76,35,EB,3A,FF,BA,62,26,B6,BE,87,77,17,F8,C6,E4,52,61,37,48,43,B5,0D,7F,30,E2,FA,8F,0D,A1,03,0C,F6,40,0A,B5,A7,73,80,5F,EE,07,D1,AE,12,BC,D9,91,3F,B6,3B,2C,15,BA,46,9C,66,3D,A3,A9,58,7A,64,17,61,37,E3,4D,22,13,AC,21,C5,7F,92,12,AF,51,93,33,A3,B1,8D,80,30,2C,60,83,88,84,98,54,8D,10,C8,A6,DB,F6,1E,BB,29,02,50,6D,33,81,87,8F,09,EF,A8,72,FD,A5,E0,14,C9,CD,32,C5,D2,17,6C,53,0F,26,FB,85,6D,3D,ED,7E,48,6F,B5,47,4C,86,BE,6E,AB,94,AA,46,2A,27,60,C0,C5,E6,CC,F2,D4,5A,45,71,69,FA,F8,8A,C6,AF,D7,9A,49,E8,EF,11,8E,8F,46,65,1E,F2,0C,B1,41,36,7F,43,4A,78,45,BF,A0,02,63,75,10,FB,26,D6,D6,E3,15,0D,7D,F6,54,77,F9,4A,F2,FB,53,37,7A,09,F5,4A,4B,49,7D,57,85,2A,7E,FE,06,80,70,05,FB,BF,B5,99,35,40,34,7C,AA,11,84,23,6A,48,48,4A,A2,99,69,3A,44,9C,4C,BF,B9,D7,52,B3,B4,ED,AF,2A,E0,2F,F0,BD,65,62,E7,9B,11,93,2E,B5,00,48,C4,2A,92,45,10,F6,A5,9A,62,DA,55,25,EE,EF,D9,85,B4,12,45,6D,92,9D,97,25,65,ED,F1,60,97,F0,33,04,A8,56,B2,ED,11,35,BF,CD,4F,15,8E,CF,4A,E4,AD,2D,84,CB,3A,AE,B3,66,D8,70,F7,BB,7A,17,97,15,56,5E,B4,B6,9C,60,F4,C3,EE,43,A4,33,C9,76,8C,0F,18,E3,86,81,DE,BF,98,7D,D9,CA,F8,B2,B5,5A,60,BD,19,12,79,8E,56,78,CB,43,6E,06,86,BF,42,A3,22,1E,A7,61,9A,D2,D1,55,55,19,5A,01,6B,C4,01,BB,72,D1,C5,62,B8,7C,84,76,1F,6F,F1,A8,FA,40,A6,5D,3C,69,59,85,F1,5C,86,27,3D,B5,06,BE,D6,6C,72,F2,C3,99,95,61,B6,83,C7,03,D6,50,47,9B,A4,B2,B4,37,92,1B,53,BE,11,C3,90,56,78,96,52,46,83,F3,7A,73,9F,95,47,00,2D,46,09,E2,68,DA,85,BA,AB,BD,99,AF,28,EA,EA,0F,3C,F1,FC,0D,3D,5C,02,C9,8C,01,E5,6B,05,59,AF,01,7C,84,BA,78,5B,9A,C7,F5,F2,06,12,F6,48,2A,BE,F8,16,83,00,92,80,C9,A8,D8,5F,3A,D2,08,AC,B6,CB,71,43,52,AF,52,7B,D9,44,7F,7E,9A,F1,76,4A,1B,DC,AE,1E,B9,64,E6,AF,F7,63,11,ED,14,D7,2B,4D,03,31,01,76,C2,B9,B0,11,06,A4,E1,1E,ED,4D,51,6A,C5,95,61,42,4A,13,E0,93,6E,B4,0D,36,7C,A1,3A,61,E6,86,39,16,8F,31,F8,E4,62,6F,2C,0A,59,C2,82,22,0C,34,4C,FD,06,31,4F,E7,E8,33,A1,8A,3B,04,33,C9,50,55,7C,AE,DD,80,FA,B2,B7,56,F5,E1,E7,13,4F,58,3B,9A,81,2E,15,9F,84,3A,9D,54,AD,B5,50,B9,6D,DE,F2,65,9E,D6,4C,52,76,D7,5E,1E,A1,90,D8,1F,FB,DE,9A,CD,AD,0B,34,AA,0B,70,1C,84,69,56,E1,68,2E,50,F3,02,4C,07,DB,F8,2E,65,7A,4B,DC,F2,7B,CC,30,56,9E,F2,76,EB,A1,DB,5F,92,BF,97,E4,A2,6B,C5,96,41,23,B7,4D,6D,14,4A,53,19,D1,FE,6B,DC,C2,3B,04,12,08,D3,18,C6,B8,D0,B0,4F,89,4A,13,D1,C8,95,7C,55,66,63,81,D4,90,01,84,93,88,8C,FD,DC,56,52,96,E0,0A,15,C9,0C,F6,86,0B,F3,51,59,03,DD,D0,7E,21,FA,1D,0F,26,D5,40,18,FE,F4,08,94,19,FD,73,8A,FE,D8,D3,BD,C5,60,8A,2D,9C,1F,D8,16,6B,EC,C9,43,5E,8D,E2,C8,D3,6E,CF,8D,84,31,D6,FF,C7,2D,7F,84,D8,06,CF,B2,DF,BD,EB,38,2A,CF,15,4E,0C,2E,77,0A,4D,A6,14,02,22,2D,4D,DE,CE,FC,57,2F,F8,4A,9F,73,A2,00,B7,25,25,B1,46,96,BD,2A,8C,5D,98,60,53,A9,7B,CF,8E,F9,D4,76,20,64,EA,81,9D,AE,42,DC,0A,C3,DA,50,F2,DC,19,FE,20,7D,00,81,32,8C,10,1B,F0,88,92,2C,B4,B5,4A,13,1B,46,5C,E4,B0,2E,FB,03,B9,02,48,F6,A0,2C,4D,93,99,D9,6A,2E,31,FF,DE,BB,B8,00,C3,5E,37,5F,FF,4C,2E,60,CA,DA,DB,83,85,D9,2B,C5,05,96,AA,4A,99,D4,A3,CF,0B,E6,C1,76,AF,07,9F,08,C5,89,B0,C2,4A,EC,AD,60,32,0F,C5,FE,BA,D7,49,B4,3D,06,2C,FA,60,94,A1,63,6A,7C,83,28,71,84,2B,83,0A,13,D6,46,17,46,BC,34,38,87,C4,D8,5D,1E,D7,B3,72,CA,27,8D,22,67,34,4F,ED,7F,7E,2E,65,5D,EB,14,F2,68,76,C5,72,D6,ED,C2,9D,F6,7F,A0,61,C7,9D,F9,A1,B8,A0,55,EB,D1,3D,15,D0,FA,F0,32,DF,47,C6,07,AB,0F,F0,F3,C7,F4,FC,55,85,4A,17,AF,79,FE,13,BE,E6,46,E9,53,24,2F,06,D0,F1,46,D2,E7,08,A8,8F,70,DC,DB,17,E6,14,78,2D,1B,8F,5C,EA,55,23,78,CA,D7,E6,D4,EB,39,26,9D,70,B1,96,73,81,52,A2,CA,0F,F8,14,7A,B2,71,81,80,F6,96,F3,76,44,DA,7A,25,6D,C9,61,60,94,F3,2B,E9,51,AB,AD,86,DD,0E,AA,EC,CE,75,93,94,90,BF,7C,B7,5B,25,31,80,F2,32,20,90,EB,02,B6,64,61,14,B9,48,A7,A6,DC,08,D5,72,6A,C3,74,0C,FA,C0,CE,C8,FF,31,7B,45,67,28,28,DF,2E,E9,8F,B5,34,16,FA,7A,59,D1,E9,59,A8,DC,53,1F,1A,CF,EE,02,36,D2,01,DB,14,C5,9B,7B,DD,7E,8B,49,BD,84,06,CF,ED,0E,33,80,C3,0B,CB,88,85,69,BA,77,42,D8,D3,34,BB,0D,5D,B5,90,44,E9,97,ED,71,A1,E1,C7,23,24,BF,A1,70,FC,2E,99,86,4F,07,C5,6C,CF,78,56,A7,B5,06,93,A3,F9,A2,8B,A6,46,16,F3,76,01,68,42,2E,2F,0E,F0,2C,94,ED,38,27,5F,5F,DC,58,96,F0,43,DD,21,3F,2B,1C,00,51,C7,FE,A2,3A,CC,1F,D8,F9,CD,36,22,FD,5E,A8,B1,D5,CD,1D,3C,77,DF,15,CF,B7,AA,54,E2,B9,D9,10,A4,3D,B9,CA,C1,05,44,02,53,F7,6F,8F,02,82,64,5E,00,6D,A7,30,7F,56,1E,70,F5,A5,0A,E3,25,C6,9C,0C,FF,FB,44,82,CD,6E,25,73,A9,79,E0,D2,4A,35,AC,1A,51,64,48,52,AA,0E,E8,63,50,4F,23,FF,DB,0A,E3,5D,83,D5,EF,A5,40,58,33,B1,A3,12,7E,27,09,B9,F8,3C,23,CC,5F,2C,E8,DA,FC,BA,FB,CF,27,49,38,4E,7D,60,3C,0B,1B,C5,76,D7,F1,AD,C9,05,A0,B5,23,81,C4,4E,35,C2,AE,AB,11,BD,84,39,18,B4,80,4B,63,E8,55,CF,5F,64,72,0F,23,8A,73,04,4C,DF,37,8F,78,2D,D2,B0,CA,40,43,CF,6D,11,60,B6,D7,AB,C6,07,02,93,19,0E,B8,4E,98,0B,DD,E7,B9,C3,A6,60,75,45,10,C3,6E,D8,B8,6E,B3,3F,4D,C9,0A,C3,70,77,B9,C0,3F,A7,41,3F,F6,9B,48,4B,7D,BD,8B,5E,08,2A,F1,1B,C9,CB,0A,46,C4,AB,32,B2,95,2A,F4,7B,0F,D1,28,9F,1F,E0,87,05,D7,31,2E,CA,90,A6,39,7D,02,4C,B0,A6,86,0C,85,B0,BB,1C,4F,FD,84,7C,4F,F7,48,75,64,3D,29,A8,FB,E5,3E,89,5E,90,6E,F5,59,2A,5B,75,F3,6B,DB,6F,01,E4,1A,60,8E,4D,F3,F9,20,04,8D,9C,EE,D0,58,6E,FB,9E,4C,A7,DB,4C,C8,BE,A4,02,2A,62,7C,17,F2,29,C3,3E,59,C4,5A,9D,FC,37,19,EC,9C,09,E4,1B,53,E7,13,E4,AB,D1,73,7A,51,39,76,BE,DF,54,55,E8,D9,8E,65,F2,12,2B,07,E2,DC,C1,AB,6F,47,18,B4,C2,7A,64,C0,23,8D,69,61,93,5E,D6,0F,98,2E,73,DD,16,20,2E,35,08,02,B9,12,AC,40,62,D3,02,F2,A0,1E,76,C1,34,30,5D,2F,42,66,4B,8D,61,FC,63,BB,49,69,8B,92,46,02,40,46,34,56,E7,4B,39,F4,67,42,25,73,4F,97,61,C8,16,EF,F2,E3,80,2F,A2,15,9B,46,5B,52,09,AF,5F,C4,22,79,96,46,E1,33,13,80,2C,F0,21,74,6A,D3,85,66,43,B5,06,94,21,2B,84,0F,8A,2A,21,4C,E8,5B,3C,97,2C,1E,B4,39,5C,71,07,EE,B6,2A,1F,D6,31,26,58,B9,02,A4,AB,B1,A7,9A,03,DB,B1,F1,8E,9D,8B,64,72,EA,0C,5A,EA,15,F9,E5,15,26,27,40,3F,2F,84,B8,64,94,92,CC,8E,64,39,10,06,EC,06,33,EB,8C,07,00,05,44,86,01,D1,8F,AA,38,DB,34,58,BC,A5,03,D9,8A,17,15,AF,23,2C,6D,58,77,4E,7A,B1,8B,46,A0,C8,A6,A1,4E,AE,10,76,71,37,07,9E,CE,D4,23,12,39,BB,9B,D6,0D,0B,AC,6B,05,12,20,C7,D0,A6,80,F1,54,15,5E,48,AA,8A,26,93,98,AB,49,55,16,BE,49,0C,44,E8,12,27,2B,30,F5,E3,9D,F4,46,D7,1A,2F,77,66,28,DD,A6,C3,2B,70,72,A9,BB,B3,84,B3,15,ED,C7,1B,F7,36,2C,23,D1,B9,13,0C,6B,13,AE,27,54,B1,D1,59,84,AC,B5,AA,4D,C2,21,91,3D,18,21,E5,67,34,41,3B,A3,82,C0,AC,AC,82,8C,7D,08,1E,89,37,42,10,EA,95,2E,C9,D7,ED,D8,74,77,CF,13,5F,51,43,AD,D3,B9,C4,3E,B1,2E,82,8A,82,1C,62,46,1C,7A,B2,4C,D9,92,9C,47,CF,6E,CC,D5,10,85,BE,7E,DB,24,5A,B7,5B,0B,75,65,72,0A,3C,01,BB,CA,00,AF,8F,AF,45,0D,32,18,D4,01,ED,76,CD,E5,68,17,C2,10,93,64,2A,F7,B5,F6,47,3A,28,58,84,D0,F7,9D,5E,BF,E7,A7,55,EE,7C,90,51,C0,12,CA,62,C6,E2,B1,F7,41,B0,78,D2,D2,F5,7C,83,9D,9E,AC,49,98,8C,75,06,18,5C,F0,B3,55,C6,81,E9,FF,ED,02,13,90,30,84,E7,46,88,43,33,80,B5,EA,93,44,FE,91,40,A5,15,F2,11,46,AC,6C,CA,42,13,9F,C7,47,93,08,1A,69,5C,D5,B3,74,88,1A,3C,C3,C1,45,68,D6,3E,D3,5D,BB,1C,77,8B,50,93,6B,92,BA,6A,26,FD,9E,31,8D,78,76,E4,96,B2,3D,C2,C3,23,69,DE,0C,94,02,81,A8,5F,5B,B1,DB,D2,06,02,DC,14,DF,71,78,AA,30,1C,C9,02,E4,02,01,12,EF,61,FD,0A,89,7E,E5,D6,33,14,97,C9,79,07,6E,B3,3F,6F,DD,87,00,2A,6C,CB,4E,38,D5,D5,6D,D6,74,E3,E8,2E,75,E2,BA,8D,F2,CF,61,66,A7,31,AC,D4,D0,9E,1E,AD,7F,4F,BB,3C,E3,10,40,DD,1C,CE,F6,2E,1B,7B,79,B6,42,D2,4D,F1,1B,8E,DD,3C,B4,B3,24,82,71,EF,15,9D,29,CE,5E,CE,22,E3,C0,73,03,84,4D,8C,59,FC,9F,58,85,DD,24,26,95,93,C4,6F,BA,7A,53,73,F0,87,23,59,87,5D,B7,18,CF,4B,28,12,5F,A4,BC,76,85,E8,DC,87,66,97,24,74,4A,5C,98,1A,9A,A3,7E,96,2D,3D,27,78,3A,01,9F,08,00,BF,4A,96,6B,5C,61,B4,7A,5C,B7,BF,3E,06,4E,20,36,53,C3,DC,69,B6,6F,50,48,89,E1,24,6A,6F,0F,1F,FD,B4,5B,4B,CF,77,02,00,34,93,A9,F6,5D,DC,37,AA,E9,1A,8F,24,87,06,48,E7,00,31,E6,9D,E4,33,48,DE,CD,C0,3F,FE,F8,DA,67,8C,18,FB,49,1A,F2,51,0F,F9,8B,2C,DD,BD,81,A7,E5,5F,E3,EF,1D,E8,D6,C4,A7,35,94,D0,DA,A6,77,28,E4,9C,58,B7,91,EC,D6,92,8B,DE,C3,B1,12,0C,C1,3A,19,DD,E5,38,95,24,36,A8,4F,63,6D,A1,DF,98,93,95,C3,B6,BF,93,F3,9D,B9,6E,5A,19,60,8D,23,CC,BD,74,62,57,90,E0,B3,7E,10,07,86,84,FF,9A,40,79,4F,31,7D,62,26,8D,9C,AF,3F,98,8D,2E,8C,2D,B0,2B,3E,C9,C2,8D,DC,40,5F,E8,4A,D9,FF,50,B4,17,32,FB,66,2D,4F,1A,AB,9A,47,D5,95,9C,9F,31,5E,94,8B,78,D0,ED,0D,CD,4F,7A,0C,E4,32,AA,54,69,4E,AD,5C,40,02,EC,2D,86,01,68,05,9E,85,B2,5C,9D,81,0E,A8,2F,FB,87,7A,79,14,4C,1D,77,B4,B5,4E,46,E4,B1,FC,19,B1,75,1A,90,E2,2C,38,57,9C,EE,88,22,D3,2A,6D,3F,B4,8C,D6,72,4A,CF,C0,E3,60,F1,63,13,0D,3E,71,DF,3A,23,F7,D2,18,44,8A,D2,51,FC,2E,5A,62,4B,81,48,1B,33,EB,87,D3,99,35,5F,EF,F4,48,E6,B0,CF,5F,93,6A,E8,1F,E2,C0,FE,87,A9,D5,F3,97,65,FC,E8,AA,97,46,29,90,9D,02,00,B8,8F,89,2E,17,6E,C6,2F,1D,F8,2F,64,43,B8,77,D8,E1,84,B8,F3,82,24,81,F8,D0,0C,9E,04,AC,F7,FC,E9,64,9D,B4,6B,C0,E4,85,BC,9A,FC,7A,06,04,6A,93,EF,7A,F7,36,D7,1F,3E,1E,1F,C6,42,FE,6B,B0,4E,3D,27,F8,F1,AA,A8,52,0A,ED,B0,82,7F,85,56,12,C4,65,1A,31,8F,A8,90,E0,AC,F7,73,E1,FC,55,AC,4E,FB,E5,9A,67,87,69,B9,FC,FB,58,B7,56,C1,81,DB,E1,EC,9C,C7,E8,ED,1D,E9,2A,9D,5B,60,9C,1E,88,EB,76,D9,14,93,13,7E,DF,61,AA,C6,74,A8,92,23,02,5F,98,90,E8,D8,6D,93,60,A8,2E,E4,C2,B8,5C,14,90,08,B8,6E,A4,71,A5,01,03,2F,D3,FA,B0,CF,5C,80,AF,EC,08,82,DD,71,97,80,B8,F1,79,1B,C1,19,F9,90,5D,C3,18,B8,45,78,BE,25,62,8B,1A,D8,2D,CC,B2,F4,E6,A2,25,04,0C,6F,B0,8E,B3,2B,C4,38,7D,1D,CA,6B,A2,F9,E3,C2,5A,A5,0C,CC,FF,F0,CF,63,9A,E3,CB,6F,70,92,45,78,20,E4,56,D5,9C,D1,47,42,4C,F4,A5,B0,5D,75,69,D7,ED,EF,13,5F,82,A8,67,77,B9,54,E7,3B,0A,14,35,72,E2,98,E2,09,2E,BB,50,24,28,3E,42,B7,0D,CC,CC,CF,57,FB,9B,EB,6F,03,B3,0B,2D,C7,4C,A0,F5,03,65,24,21,87,95,88,A0,14,79,5B,FB,46,DF,76,39,FA,48,1A,E7,4A,9A,04,B3,76,5C,6D,9E,82,D0,1E,F4,4C,C8,08,34,B9,86,E7,21,25,2B,DC,FA,FB,45,79,A2,C1,80,7D,57,5B,D8,03,78,9F,E5,BA,94,FB,7A,1A,4B,EF,37,76,F5,B5,C2,BC,D1,41,1D,3D,AC,3F,25,91,A3,D7,9C,A7,68,F7,AE,B9,5B,0B,C8,DB,C1,9F,D3,F5,44,2B,BF,88,AB,C8,98,70,CE,16,FE,94,59,6B,27,3E,05,74,D8,BE,18,62,31,40,AF,5A,92,C4,B9,E2,27,95,86,6D,FE,F8,2A,A9,99,C7,BC,F8,E1,97,D5,7D,00,36,9C,94,53,0A,24,92,0A,7B,33,EE,72,63,B7,A3,8A,77,03,B0,A8,40,56,AD,7E,89,0A,05,A0,93,75,8C,CA,88,94,AC,4F,D6,EF,CC,DF,F6,07,83,0A,50,E2,B6,58,54,54,E5,56,6E,FC,3C,ED,EE,34,EC,CB,C5,CD,A9,6C,F1,7A,D7,FE,53,81,34,5D,CA,D9,F9,D5,E5,D7,AC,41,84,D2,D2,5F,B8,47,14,FC,8B,9B,AB,70,E8,03,78,22,DC,17,A2,A5,7D,50,2C,24,97,4A,EA,2D,9A,05,31,D7,19,BA,15,53,E2,C6,78,B8,E4,34,5E,AC,69,26,1F,32,C2,1D,98,48,29,23,A7,49,BF,87,DF,B3,19,C8,ED,9D,89,6F,89,BB,AE,1B,8A,2B,F9,E8,28,D2,59,B4,C6,DE,00,33,77,81,DA,B2,31,CD,E4,9E,51,70,83,54,54,D6,60,8A,B6,C7,3C,00,B5,68,66,AA,87,58,F2,5D,3C,88,F1,FD,AE,EF,BC,8A,6A,11,0C,3A,66,1E,BF,67,9E,05,8A,25,2D,2F,0A,2B,9D,D2,DF,6F,B9,A6,E8,A7,2F,C6,F6,A5,48,B6,37,81,A8,77,23,32,5A,14,34,9E,B6,6D,BB,9B,CF,71,24,5E,05,4E,A0,F2,E2,91,C6,A3,65,4A,06,1E,6A,BF,23,91,AC,01,05,29,E4,9C,DA,F9,99,D0,2D,E5,EA,C3,30,88,AB,02,FB,A7,F3,31,6C,5F,03,CB,23,B4,84,41,AF,8D,8C,98,88,A4,92,6D,92,E1,FF,51,8E,5A,78,A3,0E,AD,81,E0,02,64,83,58,CB,19,13,EB,28,DB,9F,61,54,FF,3E,25,40,2A,6A,98,1D,52,EE,3B,DF,26,1B,1B,74,C5,3C,66,55,A9,68,1C,77,68,2C,35,49,6B,DD,88,7F,56,E5,AD,4B,08,3D,23,7D,7C,5F,90,1E,BB,03,D4,B6,CE,86,5B,FE,A6,02,4A,68,5A,1A,72,0E,DF,BD,9F,14,87,12,A0,4A,4A,18,01,BE,1E,19,C0,17,17,34,44,2E,78,AA,84,8F,4E,D9,DE,A0,05,6B,B6,34,4E,9B,B6,BF,58,A1,9D,54,DC,42,51,C1,68,9D,6D,5A,C6,D0,C4,60,82,F5,90,2D,8A,69,35,77,21,54,95,47,5D,67,A2,58,45,C9,59,1A,7E,06,4D,A7,88,D6,96,39,BC,7D,79,AE,D6,6B,2D,06,5D,29,9C,62,28,58,11,E5,AB,1B,B4,D0,87,4D,1F,53,36,C1,2E,8A,7F,AE,C8,44,D5,BF,09,CA,B8,68,A9,AF,BC,AB,2F,F8,4F,AC,FD,9A,58,F6,53,02,8E,79,1E,C5,14,33,73,FC,E9,F9,1C,B7,A2,35,2F,10,09,49,2B,7C,5A,4D,42,93,CE,CF,57,5E,32,DF,1F,FA,DC,17,F2,BD,F9,30,3C,5F,50,11,05,C0,16,09,BA,0C,56,F1,94,83,99,37,6E,CA,36,93,9E,F3,9D,68,14,01,4F,72,1C,EA,D6,57,68,C0,0A,E2,3E,5F,B5,08,96,E4,BD,D9,DF,57,77,76,A9,BD,B8,E4,D8,E1,CF,7F,2A,32,98,23,4A,FE,6C,9F,B0,95,8E,BA,47,85,D6,06,4A,B8,FB,B0,1E,D3,19,A5,41,F4,FF,DD,6C,8A,E9,12,29,38,C3,62,B0,38,2C,5C,13,1F,36,97,DE,10,61,08,36,FE,3B,56,84,68,ED,CD,51,BC,B4,B0,E9,C5,FB,2C,58,C1,4A,EC,B9,08,5A,D3,B1,82,7E,74,72,F1,6B,62,35,B8,38,1C,56,BA,02,15,54,74,45,9A,B9,6F,71,42,59,68,4D,66,02,F3,54,38,77,43,17,13,1C,DD,C0,24,C9,46,4A,11,60,AE,4D,9F,DB,50,0D,8E,DE,74,28,67,F4,CD,90,C3,88,B1,57,87,01,76,6E,88,5A,1B,30,75,83,02,B5,5D,10,2C,01,C6,63,EA,DD,D7,6E,E5,90,4F,C0,B2,4A,8B,13,9B,00,3D,48,95,87,CF,1E,6D,F6,F5,F0,E0,2A,70,DA,BD,B2,C0,8D,56,F0,76,4E,1A,26,9C,69,03,14,CD,CE,09,BA,29,E9,26,F9,9C,BA,ED,9B,C2,BD,6A,BB,B9,FB,71,B0,37,B4,6B,D6,9E,B3,AD,8A,BC,1E,2F,FF,15,91,4A,ED,CE,FE,BD,2D,E0,0C,7C,A2,0F,8F,1C,E8,93,8A,8F,65,D7,46,FF,93,E6,B9,15,56,67,C2,98,69,38,72,B6,3E,23,1F,9E,75,A5,7B,88,80,45,0D,A4,25,53,46,13,72,78,90,2B,7B,2D,CE,88,D2,64,73,D8,D3,AE,84,3F,C5,41,21,6B,45,B6,E4,23,35,E7,58,D0,55,DA,2B,35,B4,B0,A6,6C,39,68,63,86,5A,46,A2,07,F1,98,94,89,11,88,8B,6C,8C,31,07,91,54,A1,6C,AA,F9,18,16,38,B5,02,2A,9B,42,1E,29,DD,EF,60,46,6C,02,65,A5,7C,60,AC,30,87,7B,98,C7,40,5B,16,ED,D2,9A,57,0E,C0,DD,D7,FF,EB,70,79,47,EE,19,47,A0,C5,62,C7,9F,BA,69,31,1F,98,A8,38,29,24,00,DA,A5,86,56,18,3C,BB,49,6A,90,3C,75,BD,F5,86,32,39,78,D5,C4,ED,24,47,2F,51,3E,DF,D6,0C,59,58,19,BA,49,3C,78,3D,52,89,97,9E,5F,44,55,98,09,5D,00,2D,3F,2B,89,C7,1D,CF,A2,EF,94,CF,D1,2A,31,13,B3,93,04,C2,07,15,9F,B7,FD,7A,19,BA,20,AB,BA,AE,20,E9,E1,EA,CC,8F,F4,25,F8,93,B9,58,6F,C4,FD,25,0D,7C,A4,22,3F,42,38,03,03,BF,07,9F,DC,AA,4C,5B,A3,58,CF,E5,D1,92,2C,1B,D0,16,27,F6,81,78,A8,0A,71,36,3D,6A,C7,E1,3D,01,D8,E1,A3,F3,95,42,23,39,EA,76,53,82,0E,6C,4E,5C,17,D9,97,F6,79,C2,60,38,81,03,6D,5E,A5,4C,DD,01,40,3B,70,3F,AC,76,0B,82,61,16,9E,D3,A9,12,FB,B2,BD,15,A0,06,FD,57,AC,B9,48,A1,48,48,45,5A,0F,F5,9F,7A,C8,EA,8E,0E,27,DC,93,7E,3E,55,A1,E4,D1,36,E6,B4,B1,10,D9,D9,91,E7,14,13,6A,E4,FE,B0,66,F7,A0,2A,66,2E,2B,18,79,6C,C2,D0,36,22,21,0D,D7,4B,1C,12,5A,47,1B,86,31,C1,5C,4F,FB,D6,BD,92,8C,0A,BF,74,8D,C9,21,0D,FB,23,40,AB,DE,E6,F4,86,B7,C0,07,B4,F7,C9,01,4E,C8,83,F2,CD,05,5E,77,76,E4,05,59,6D,AE,B4,35,F4,16,EE,55,62,30,7B,24,A7,01,04,B6,A8,D9,3E,62,F2,94,95,A5,69,7E,9A,FB,35,BC,27,8D,A9,C7,24,A7,0F,E9,B8,F8,E1,9F,A1,67,42,81,80,62,9E,95,8C,9A,E8,4D,02,53,1D,AB,56,0E,00,B4,00,16,F0,B5,5B,56,D2,C5,F2,9A,11,FB,08,AB,ED,90,33,CA,62,8B,23,64,96,09,79,EA,C1,9E,1E,FD,4D,D3,99,57,DC,9F,70,12,8A,DF,D2,8E,F1,E3,FA,C5,90,AA,65,28,A6,8F,D4,1F,9A,77,D8,0E,39,CB,FC,05,73,12,AE,A8,8C,DB,CE,44,BB,48,02,6E,AB,AF,A4,B1,74,18,27,98,47,D7,4A,33,EF,D7,54,23,3E,AB,2A,33,81,97,81,66,6E,C6,07,22,90,FA,17,A6,CA,61,D6,CC,A5,5B,4B,0A,1F,9B,9C,3A,A6,48,37,C5,40,F8,D0,E8,84,E4,68,B5,D5,5E,AE,84,37,65,EA,A9,A2,71,A2,14,F1,F4,3D,77,A7,EE,3E,F2,91,AC,01,09,D8,CA,C2,EA,95,B1,14,84,A5,CA,63,08,50,43,0E,FB,E7,3A,43,F4,CF,69,41,B3,52,C8,38,91,6E,3C,AB,57,7A,C9,A8,50,E0,A6,6A,30,4D,B8,DB,5B,58,C5,5E,40,4B,4D,D2,42,78,4C,62,0F,D3,0B,31,7C,C2,57,0C,2F,7B,0E,DE,C4,36,75,28,2F,2F,BF,0C,81,8D,26,91,8B,BA,BE,18,17,F8,33,20,37,F0,20,39,80,F0,FE,6E,2E,2D,66,EA,5C,F0,92,3E,E2,9E,6E,63,F1,1A,78,52,40,D0,EA,85,89,03,7B,C2,1E,09,C8,54,29,17,44,58,FB,72,CF,DC,D0,33,A1,20,77,39,3C,FB,45,00,B1,39,A2,58,85,92,C4,85,25,2E,E9,00,13,34,21,39,87,D6,00,48,D8,72,A5,C0,96,5D,18,4A,2A,3C,A4,7E,20,12,66,9D,C7,AF,36,1E,42,35,CE,FB,14,A3,01,AB,9D,BF,D5,69,C9,AE,FA,A2,55,BC,96,43,8D,1C,4A,82,A3,F3,70,B2,50,AF,B1,02,F6,16,C6,18,44,6A,31,6F,5F,A2,D0,5F,B3,52,36,C9,E8,4C,0A,89,C5,85,F6,FC,53,91,7A,7F,30,28,F8,33,E0,A5,C2,D3,3C,18,75,AF,DE,C9,12,F6,EA,92,A6,82,9A,D0,02,BF,1A,19,1E,31,80,E4,32,3F,D4,1D,7C,BC,A5,38,CE,60,6C,BE,B8,66,5A,9C,E7,39,BD,16,FC,39,C5,CA,D0,F5,F2,B6,AE,01,64,9E,BB,71,7B,E1,C9,0A,DE,19,C5,9A,45,A9,E4,F1,10,71,B0,C4,3B,42,B3,1E,FC,DB,17,95,51,C7,4B,B2,7F,A8,F8,4E,09,EE,88,5B,57,B1,66,E0,AD,A5,D9,C3,A5,59,78,A2,0E,5C,9C,AB,9A,6A,03,49,0F,B0,ED,79,A2,B9,7A,FF,3F,FC,66,D1,A3,DB,ED,4D,63,35,FF,37,EE,1B,18,E2,22,F8,ED,54,CC,66,98,20,A5,7B,93,B7,6F,0A,A1,C0,11,FD,E0,74,3F,46,51,31,D1,AC,71,51,F9,29,A2,91,38,44,48,25,2E,C4,3B,4B,E2,77,8C,AD,3D,EB,49,DB,70,A6,88,D9,75,52,82,AB,26,72,37,A6,8D,EC,18,F6,E8,7E,0F,7C,9D,9F,F9,6E,79,74,4B,53,83,B9,97,62,37,A2,3C,99,F8,D4,95,56,60,8F,6F,A1,56,B9,BA,4A,1C,1C,E7,F1,D8,D8,23,65,41,A7,91,13,6F,AC,5B,AB,14,23,D7,6A,85,BB,75,58,2C,EE,3D,8F,5C,EE,55,62,FB,D4,9F,55,BF,23,D1,0E,A2,EB,0E,1C,86,39,BB,BD,E1,DC,DD,C6,06,22,21,23,A1,98,B7,4D,35,FE,F0,F5,17,68,10,99,AD,A0,55,AB,08,DA,A9,F3,3B,A4,A6,1D,47,BF,3D,38,B1,A6,9B,71,41,E2,A4,C4,7D,AD,1E,79,EC,76,21,C2,43,E8,D6,6F,B5,F3,28,1D,88,A1,E0,0E,9B,D7,FD,C2,E2,0D,D3,F6,19,A4,81,49,6E,F0,AF,79,1A,18,BE,0F,1D,55,DB,01,0E,F0,61,B2,D1,16,8E,4B,3A,26,F6,AB,13,8E,96,50,68,20,7D,A5,EC,12,54,86,1F,40,53,15,4E,FD,23,30,00,C5,68,FE,77,F6,A8,25,E8,DF,C4,1B,87,71,C6,FD,E5,C3,18,51,FC,F3,7C,6E,8E,78,18,37,F0,B1,EB,59,33,3D,D2,68,5E,EE,84,13,21,19,06,CD,9C,76,FF,33,D2,0F,BA,CB,E2,73,7B,E3,E7,B4,89,CC,BD,71,68,6C,E1,14,D4,45,70,70,16,EE,5B,75,E0,EF,71,36,9D,C3,D4,5D,86,48,5B,D5,37,FC,53,2C,93,89,45,24,BB,D2,80,4B,EC,67,08,05,23,32,6D,39,A8,50,BA,CD,47,8B,A8,BE,D9,C3,E7,F9,37,AE,88,2E,21,8B,4C,4B,66,AD,8F,A1,DA,AD,26,C5,B9,F8,C0,A2,51,7A,F1,D3,CA,47,EF,54,17,19,4B,28,28,40,E1,18,91,E4,FA,52,B7,DB,C3,00,A3,E1,C5,61,98,85,C5,05,33,C0,59,80,F9,EF,9E,AE,32,6A,9A,E7,1C,9D,6D,B4,33,AC,25,96,69,57,1D,23,22,4E,13,22,28,C2,AD,77,65,0C,9D,6E,4F,57,49,FE,03,A1,99,1E,FC,94,B8,E6,9C,DE,33,09,8C,63,96,19,24,55,E8,F3,C8,12,E0,99,63,7B,A0,9D,8D,E4,79,2D,41,EC,52,1A,21,95,34,00,DA,53,56,3E,2A,37,C0,7B,9A,2A,82,78,9D,4B,CF,C7,85,AB,49,E4,08,25,CB,6E,DF,3F,D6,72,96,92,01,D8,84,EE,1E,3C,B4,BA,BB,1D,0D,E3,F9,23,8D,35,AB,6B,AB,71,62,41,90,B8,6B,7B,7B,17,8F,4A,DC,C1,FB,6E,CA,1B,14,07,A0,E8,37,1D,8C,FF,CD,55,61,16,3D,BA,5A,94,0C,C2,45,25,41,77,9C,9A,5B,89,4D,58,84,0E,CC,D6,BC,7D,E5,99,F4,1A,A1,2D,1E,3E,4B,72,F9,AF,77,B3,39,98,3E,94,E0,29,CC,45,B3,10,B1,74,F9,18,95,CE,1D,C6,46,9F,1D,4B,71,40,A0,38,CB,E6,7B,7E,9B,08,5B,08,77,91,00,EE,F4,8E,49,B1,AF,A5,95,1C,5C,20,11,5A,96,61,CF,77,C3,16,52,71,7D,8D,85,C0,53,F8,63,94,73,3B,95,A0,EB,63,17,5A,CE,A9,D5,90,95,1E,9F,68,2D,CE,4B,34,14,FE,FE,0A,F9,D1,44,8D,FF,4A,FD,44,61,D0,3E,49,E4,FB,68,FE,C3,23,8F,A6,DF,B3,3F,08,02,8F,AB,30,5A,19,93,4C,4A,B6,8A,D0,49,2A,70,84,73,F9,09,62,55,BA,B3,86,E5,7C,53,40,81,4A,55,6C,FC,97,B9,4A,97,CB,12,90,ED,BD,28,63,D9,7D,33,63,06,89,1C,7C,AA,B5,5B,B0,4A,F5,5E,BE,42,E7,2E,8E,5C,BE,A1,4E,20,32,10,AC,D0,91,44,D7,3F,C4,BF,71,29,FA,F5,A4,01,21,9D,6C,AB,8C,23,0A,B5,9A,4B,3F,A7,E8,24,0F,70,71,62,73,D7,66,0A,33,DE,64,AF,57,7E,3E,6E,E3,33,4B,4D,DE,24,32,5A,4C,E1,4C,AB,24,F1,87,EB,B6,7B,0B,E5,3B,C4,D0,65,42,1A,50,46,D9,3F,93,04,37,AE,FF,B9,F9,1D,F0,45,D0,90,33,26,D0,0E,B9,A5,8D,07,2A,56,2B,76,02,FC,7B,71,09,7F,22,B5,7F,5B,A0,6F,3F,2D,A8,34,FE,E1,64,73,C8,4B,AF,A2,1D,9F,F7,BC,78,FA,92,EA,E6,4F,D2,60,8D,3C,29,9C,8D,61,C7,8B,52,A2,65,13,E4,B4,C6,7A,44,C7,CB,A9,7F,FB,08,4B,49,90,67,A4,9F,4C,12,7C,DA,3B,EB,24,98,4F,71,9B,BD,67,D8,89,DF,4C,9A,13,BD,D5,FF,0D,D5,11,7F,15,8C,DE,8D,9B,00,E6,48,72,B9,D2,03,23,32,9F,65,08,70,BA,53,79,A4,71,F0,88,10,29,42,E9,F9,C1,67,97,59,8A,B3,6C,E9,FC,AE,6F,AF,47,1A,93,9D,E7,B8,67,06,E3,C7,E8,C4,99,28,0D,2B,73,EE,3A,73,14,C1,7D,A4,85,5C,BD,6E,9D,9F,80,EF,A9,F9,6B,F0,CA,06,D6,67,BB,E7,45,F5,62,94,48,B3,71,62,9B,0F,73,21,E5,B8,64,63,F0,CC,5C,1D,D7,D8,B2,F3,85,FD,E6,1B,93,2B,27,89,1F,B1,74,74,5C,CF,A5,85,E9,14,F7,2D,3C,3F,11,D0,20,06,AC,A9,4A,A6,7C,35,79,21,B3,8B,06,B8,B6,15,D8,B4,BC,70,19,E0,F0,E3,45,DE,66,CE,83,2A,DF,96,14,9C,21,53,CE,9E,A9,36,75,77,19,AA,CA,D9,56,6B,2D,8B,47,8A,E4,2B,22,E5,BA,DD,31,62,2B,47,82,B6,25,B7,57,E3,A0,64,65,F9,37,1F,4A,59,D2,CB,58,7D,DE,E7,E1,FA,3B,24,3A,FD,8E,D9,38,07,CF,C2,AF,30,EC,C0,FA,B2,22,CD,25,79,A6,E0,43,0A,85,19,85,FB,8E,66,2B,FA,91,83,61,D4,68,19,03,95,57,49,47,70,31,DA,4E,85,48,6E,7D,7E,CD,3B,68,3A,93,F9,AF,4C,6D,A1,11,C8,76,D6,9B,80,E6,A6,71,F3,87,D6,0F,C8,7A,F6,C7,39,05,E2,44,FA,35,57,36,E5,D3,15,70,89,D6,69,AD,C4,4A,60,B1,06,86,EA,0A,96,83,84,7A,A4,35,0B,45,17,FA,2E,FE,4E,61,69,3D,37,B5,D0,4E,7E,B9,98,E2,2C,4B,07,3A,AF,AB,4E,86,99,77,6F,67,CA,75,C2,41,44,A0,2F,42,8F,87,1E,3E,41,90,35,C0,BE,7D,B3,83,D6,DB,31,76,AC,B5,D6,3C,E1,BC,6F,E7,37,13,09,3E,AC,8A,6B,B1,3E,78,F5,83,EC,85,C7,25,AD,8B,76,47,FC,6D,B1,17,A5,BB,01,75,5D,B3,FD,8B,24,0B,59,3E,1F,B0,28,9A,C5,DB,E3,75,97,3A,4C,DB,80,B8,CA,0B,44,F8,26,69,E9,B0,46,61,46,2A,69,29,E7,2A,9F,5A,AF,4B,A0,98,C4,F1,19,DA,30,14,08,C3,DF,95,9C,7D,D6,BA,C1,FF,C7,2E,D4,37,33,E6,40,D5,F5,45,B1,AB,11,FB,80,F0,66,D4,44,E8,81,C2,E1,7C,F3,BD,22,78,B4,39,BC,87,5E,43,C5,B4,83,00,BF,EE,D5,47,C7,FC,BC,B1,AF,29,3E,8C,39,6A,A6,76,95,3B,89,96,44,31,9A,A0,BC,71,97,E9,FD,51,1E,33,9E,E5,60,C0,F0,49,21,2B,A0,A3,3F,E6,6A,32,99,4D,06,E0,F9,6F,B3,DB,7E,68,7E,8B,4B,23,29,18,1D,18,64,CA,BB,76,EC,56,3A,86,AC,B8,D6,4B,07,1C,9D,97,E5,36,50,2E,1B,6D,3A,E0,86,62,43,98,88,29,BF,8D,92,A5,01,F8,2A,5A,49,66,7A,C0,C6,5A,AE,87,D1,4E,63,BB,9A,EE,AE,03,86,E2,9E,A5,EC,5A,BF,C1,28,A0,31,6F,47,35,1B,63,39,3E,0F,2C,68,A7,B1,A1,63,28,C4,7C,CD,7B,05,67,22,30,79,B5,C6,81,BA,D2,A5,8A,BA,87,B7,B3,5D,0F,DA,7A,51,F3,C6,4E,E4,B7,3F,91,3D,83,47,A9,98,20,F6,5E,7F,CF,C2,39,03,87,15,9E,7D,11,14,84,BC,EB,22,0E,9F,DD,5F,79,56,E8,CC,A2,02,86,71,DC,39,70,CE,4F,C9,87,57,16,AC,86,CD,14,96,F7,90,EB,DC,A3,14,F7,6A,41,B1,63,4B,08,E0,F4,27,E2,B4,43,DA,49,0C,0A,1B,70,00,2A,DC,1D,94,E8,74,C5,EF,08,89,B9,38,5D,89,C1,B7,7C,08,EB,DA,AC,42,C9,09,24,B2,7B,D8,A6,AE,74,34,52,E8,C2,88,61,55,01,0B,DA,8A,4E,82,DF,2B,DF,E2,DF,2B,46,17,9B,06,FD,07,45,0E,0C,F4,BA,7C,01,4D,16,DC,38,33,E4,C2,CD,2F,75,9C,51,5D,9F,49,4D,AD,69,19,B8,E6,68,FB,F2,45,94,BF,6B,5E,76,FD,62,A7,24,DE,2E,50,9F,2B,EE,9C,0F,7A,35,47,A6,D3,7D,2F,A9,9D,DC,A3,42,93,52,AA,7D,C1,E4,76,98,AB,73,E2,8E,7D,46,79,5F,54,39,1E,EB,C9,15,53,89,47,96,2D,79,93,B1,FD,50,1C,E4,6B,FA,61,F6,AE,49,CB,5A,46,F3,A5,BB,20,96,DF,96,48,66,0F,6B,7F,F5,5B,62,06,A0,3D,F8,44,66,6A,15,E2,55,E1,93,F4,C7,BF,6C,0B,F7,EB,8A,6D,54,90,B3,9E,93,F7,18,05,10,6E,E7,7D,0A,E6,97,11,E1,20,07,71,CE,93,D9,DE,B8,AF,DE,83,DC,7F,99,FA,1D,E6,21,41,10,B5,1D,F1,23,40,E1,9A,42,B1,5A,61,71,4E,71,01,61,B1,7C,46,31,F8,DC,F9,D7,04,B4,4D,13,94,56,E5,DD,BA,B3,E1,E6,EC,1A,F6,FE,E3,9E,74,8B,F2,7D,EB,3C,82,07,68,64,97,23,F6,D1,94,AC,B2,55,B4,56,67,2C,77,43,09,D5,F4,47,ED,7E,E2,7D,D9,DA,0F,FA,C0,01,2D,CA,CA,FF,3A,34,C9,99,CB,4A,76,06,C7,9A,AA,01,A9,08,16,F3,E9,13,EF,4E,E2,39,04,71,EC,E9,DA,36,BB,A6,3C,39,ED,B3,A4,28,46,ED,64,6F,FF,EB,EC,46,8C,77,0F,04,08,DE,A0,F5,D0,09,C3,5A,5F,1A,D5,D3,2F,CC,E2,F0,F7,95,99,69,8A,06,AE,D0,08,05,7A,E0,75,4D,37,CD,34,5D,1F,DC,1A,66,45,A2,4A,44,7A,FF,6A,F5,9C,95,11,6F,31,71,54,67,BB,D0,83,BE,0E,07,6A,B9,85,3F,46,A4,BD,44,91,B2,59,2D,EB,3B,28,3B,5E,D4,26,89,6E,5A,34,C0,11,FD,E5,5A,6B,2E,B0,0B,D6,E5,89,66,9C,31,8F,32,45,EC,57,AC,01,3A,0A,1D,2F,B0,1C,8A,A9,58,4C,70,61,52,9D,38,09,24,22,EA,1C,94,57,41,42,F0,FB,D3,E7,5D,C1,51,48,04,A4,80,53,B2,D4,5E,F1,CA,65,08,75,61,E1,A6,17,F1,A0,36,B6,72,FE,AA,10,4E,96,43,00,94,F8,F1,41,08,8E,5F,58,F4,48,08,F4,03,8D,17,47,7F,AE,EA,02,24,78,87,9D,D0,5A,80,97,1B,4F,2A,54,40,0F,7A,75,26,0C,7C,BC,B6,1A,8A,56,8F,05,5E,43,A8,62,C4,CA,A9,7D,86,7A,F5,CB,D9,0B,AE,69,A6,2A,21,10,73,A9,36,61,50,0E,ED,70,13,FF,47,12,8E,FE,AC,7E,FE,9A,6C,85,B2,1A,A0,DB,EC,33,1B,2E,48,9D,79,0D,5F,1F,39,51,D3,E7,16,D4,9B,55,65,33,CE,5E,D7,56,07,F2,19,16,5A,AA,EE,00,E2,B1,4F,1F,73,74,03,7A,C8,BC,D8,42,D7,90,ED,AA,08,86,85,6E,E7,39,68,9C,BB,FB,DA,7F,C8,88,2F,B3,90,EE,18,16,55,3C,33,1D,F3,4C,D5,BB,55,55,BD,AA,49,D8,C2,96,35,C1,7F,CA,81,20,64,00,C4,5D,DF,5C,6E,D1,98,5C,90,55,82,CA,64,08,3C,20,94,2A,10,80,27,C3,F7,7F,47,5A,DD,B5,11,E9,87,08,1F,91,97,E9,B2,C9,79,C8,18,CE,CE,54,74,2F,F3,41,49,6C,9F,D8,2C,47,67,E3,98,14,1C,FF,42,70,5E,B8,6B,E2,16,5C,E9,47,F6,E7,57,21,01,4A,C5,42,C1,BF,39,37,DA,6C,0F,4D,D2,D4,1D,E2,5A,AD,82,E0,7C,8D,84,98,1B,4E,4E,BE,BC,1E,7B,7F,49,92,2C,4B,21,98,97,A2,52,BA,B6,32,2C,81,DC,DB,98,47,B9,20,4A,55,10,34,5F,D7,61,54,43,B3,E8,AA,3C,E4,4A,C1,4B,CA,B7,5B,88,A8,FF,01,96,38,62,74,9C,9A,93,88,E7,1F,5A,65,33,8D,A8,22,D9,5F,4D,E9,0B,0D,95,38,E3,17,82,07,12,1C,1C,79,1A,AD,7D,50,7D,CB,E9,FB,DD,5D,93,C0,2D,B1,19,A0,FA,14,25,C0,4F,2B,90,F0,E1,B7,BA,61,CB,52,62,2A,D1,18,DB,63,DA,67,D3,94,8E,78,F9,6E,27,D6,44,82,0F,78,18,14,99,1E,2F,36,FA,53,BE,80,B4,D0,A2,52,E8,8E,64,62,E0,BE,A8,90,DB,0A,82,E4,42,C9,BF,6F,92,FB,3C,1E,1E,E0,56,A5,22,3B,51,8F,3B,22,CF,CA,96,C4,27,2E,74,8B,EC,9A,F1,48,72,C1,AD,80,4F,D0,37,12,58,FE,3A,13,32,FA,FD,45,A5,C3,98,46,89,9B,86,F7,EB,AC,4A,71,62,20,25,D9,B3,88,33,B9,84,CF,A1,6B,5F,60,7C,87,DD,9E,C5,C3,0F,06,1F,76,91,46,A3,45,9A,40,AD,F6,17,81,BF,C6,39,50,D5,0C,11,6A,0C,00,C0,B9,E8,91,A3,C1,2C,B6,A2,78,28,6E,46,C5,9C,7A,21,BB,72,79,43,2A,00,E6,D9,9A,03,BB,B8,10,01,1B,4A,F1,70,4C,5B,1C,24,AA,23,9F,C3,2C,30,FD,B1,E4,4C,56,11,8C,A6,CE,33,F2,29,BD,64,2B,35,D7,D2,32,39,B6,78,4A,C8,B1,A8,EB,E3,33,1C,88,46,08,A8,8A,65,B2,13,72,C4,28,A0,0F,6F,8D,58,9C,E3,F4,66,F6,E1,57,05,1A,AA,DF,DC,39,D8,89,4B,30,D4,08,02,28,03,1C,45,94,2C,26,42,A9,7E,D2,8C,E6,14,7E,EE,A7,3B,61,31,2D,EE,45,1A,05,34,26,5F,B0,61,8A,2C,C6,12,A8,52,56,CE,99,1C,F9,52,A6,E2,7B,03,53,68,DE,7F,8F,51,A7,CB,20,6D,EE,A3,36,7D,BC,BA,26,89,FF,4B,D7,E4,F4,03,91,90,03,60,A9,E4,A3,24,CF,AB,F3,DA,5B,FE,EF,21,91,3A,F1,A8,22,BD,2A,75,8E,7C,1A,99,0C,61,F3,1C,D5,B0,73,B0,C2,C0,C9,A6,0B,7F,78,B0,EE,1E,63,24,99,48,D9,90,67,BB,46,9F,3C,43,22,B1,47,4A,52,44,49,F8,A9,E9,00,75,3D,94,66,B1,AA,5F,F0,F3,C8,CD,E4,E3,0E,44,2D,CA,3C,08,5A,F6,8E,6D,B2,73,25,EB,0A,D3,2B,C4,BD,28,C0,7A,7D,DC,3A,FD,DF,EE,44,94,97,60,AC,2E,94,B8,88,B5,EE,83,31,14,34,10,FD,71,E3,29,D3,7F,32,FF,7E,DD,EE,C7,8D,5F,6E,93,A5,C3,C4,7E,90,84,14,CC,3E,30,41,06,E2,15,C2,6A,1F,71,F0,B4,33,D8,F0,98,79,3E,19,95,B5,6E,F2,FA,74,19,7E,1D,32,7F,FA,83,16,85,9B,8A,0E,B4,F0,89,BF,FA,06,82,2E,DE,F2,C4,4C,03,77,FB,D8,0B,2B,A8,FC,F6,AC,9D,DB,E2,F6,71,C8,2E,F7,F4,B3,E5,A8,7E,97,80,14,AC,84,FD,83,3C,CF,19,D8,D5,92,52,DA,58,41,22,A5,08,04,22,AA,9C,E4,41,5C,2F,29,47,3F,F0,4B,DB,E7,15,A3,52,D5,70,70,DA,C4,AB,05,69,C8,E0,60,B6,36,94,98,D8,23,92,56,28,1A,91,00,43,B2,87,17,C5,34,95,8B,5E,64,C2,14,03,73,2F,24,1D,C3,43,38,7B,27,59,D1,22,2E,B0,1E,3E,33,29,20,05,E2,29,33,3C,71,AB,55,49,4A,19,6C,18,1A,FA,DB,3A,0A,22,A5,5A,61,99,57,14,08,DF,64,AA,9E,FD,25,4C,80,84,15,B9,17,A1,DF,A5,84,44,87,30,11,98,EB,EF,68,9F,DB,AB,70,6D,2A,61,B5,6D,0C,A6,03,34,25,88,E8,C2,73,C9,1D,5C,F0,3A,FD,3E,D0,AB,08,87,F1,93,CD,2A,44,FD,8D,4D,B0,CB,A8,F3,8E,77,CE,E7,CF,37,17,AD,1D,A4,63,C6,9C,D9,5A,17,2A,91,C3,7B,60,07,C0,B7,67,2C,0D,4B,7D,52,EF,B0,C2,9D,27,BF,2C,09,E0,87,3D,60,E5,4B,B9,F8,F8,65,93,7F,AE,45,F2,CB,02,31,BD,93,FF,79,F1,31,2A,68,F4,3B,07,93,C3,6C,8E,84,7C,73,04,79,E2,B5,46,D4,12,D5,59,19,A7,BC,F9,93,D1,AA,93,15,C5,87,9D,98,9A,DC,09,C9,C0,E1,45,B1,22,C6,BD,24,D8,62,22,6F,87,76,7F,90,A2,55,4B,E3,82,B1,C9,A2,55,64,BF,57,3C,5C,73,16,76,6F,D3,36,75,AD,66,A0,41,EF,79,61,D9,62,B2,DC,04,3E,35,12,FC,EF,70,C2,51,89,EF,8F,5A,64,79,9B,BD,19,CE,5F,E3,C9,F1,70,85,E9,B2,97,B8,48,39,14,A7,2C,EC,AB,92,0C,2B,51,4E,90,E2,C2,A6,13,99,7F,12,5E,F2,F5,EF,3B,17,FF,B2,09,7B,ED,02,83,29,D5,79,10,57,F7,84,52,23,FF,D4,08,9C,91,50,19,8B,82,ED,15,1F,C3,2C,77,47,48,C4,CC,0F,94,6C,0D,06,E0,BA,49,86,FC,A3,9E,FD,AF,0C,32,52,C4,76,48,8D,E5,E3,8E,89,07,B2,0A,B7,6D,6F,D7,C3,34,04,86,5C,3F,47,47,1A,8E,20,45,0D,C6,8B,DA,FD,CC,F0,E3,08,3E,D0,32,63,C9,B1,A9,8A,7C,EF,56,88,AF,43,15,3A,66,D6,D1,8D,92,A5,E7,E5,72,F8,C3,D0,95,84,9C,21,0B,BE,FE,61,B6,F8,45,7F,0C,4A,FC,D1,1E,29,FB,DF,01,FE,56,00,56,4D,7E,AD,83,34,FB,67,DD,80,77,A1,65,55,09,11,29,01,51,E5,EB,93,A0,6D,E5,CD,A0,96,BC,6B,3B,8E,7B,2F,5D,62,94,38,03,7D,6A,98,31,2B,1B,4A,FA,C7,E7,6B,D6,E2,A8,FB,5D,87,48,C0,48,2A,18,80,8B,50,12,0E,0D,BF,68,52,DA,A8,9D,98,28,0C,95,83,10,8A,55,A1,E3,4D,BC,77,90,0A,30,17,B0,C9,F6,6C,EF,66,0D,20,85,9E,01,90,9B,60,68,E4,F7,39,A7,56,B4,5B,29,40,C3,4C,6B,B3,96,4A,D3,BE,A0,77,23,C6,73,9E,AE,D6,2F,9D,21,43,A9,3E,32,EA,3A,29,80,AB,50,8D,A0,BB,49,0E,CB,57,8A,BE,C0,F2,51,C8,F4,7C,0A,66,4C,B7,8F,5B,53,D6,E3,54,C2,2E,6C,78,85,89,97,2C,DD,56,B0,A9,FF,33,D7,E7,32,8B,3C,93,8A,94,CF,63,F1,A7,CC,18,FB,87,1D,44,E5,E2,3E,E9,20,4B,19,BB,96,C0,41,8E,20,DE,76,1C,A2,22,AF,A8,2A,7B,CD,F0,43,06,BD,66,62,42,01,99,31,EE,CA,C2,BA,07,23,D1,7F,52,AD,05,1F,F6,63,45,18,D8,EA,B7,45,BE,82,18,D9,BF,2A,74,86,37,AE,9A,13,C8,24,26,D2,7A,1F,92,E1,47,4E,0D,21,11,9E,EA,27,8E,14,D2,37,EF,30,83,55,12,EA,1D,1F,1D,29,60,A0,76,52,4B,85,3C,31,03,95,A5,6E,5A,AB,B4,0C,4A,C0,03,8C,43,EB,93,9B,F9,FC,34,90,5A,38,CF,36,FF,F1,B4,02,AB,7F,9B,47,D7,E9,20,8E,83,33,E2,8D,C6,91,AA,B2,3B,64,46,F7,A2,7F,54,09,82,68,9E,3B,98,51,1A,64,6D,BB,EA,7F,ED,84,42,8C,73,1B,82,8E,C6,0F,E8,A3,59,86,2E,41,B1,F3,E0,5B,00,58,26,2F,FC,B7,38,10,C7,E7,FE,FB,D8,B0,BC,0E,A0,17,6E,88,18,4C,F5,96,94,E3,B0,88,2F,4B,A1,29,8E,8B,B7,15,ED,8E,EC,29,50,C9,5F,CC,6F,B9,E6,9A,08,46,27,83,31,FE,07,A8,D7,60,D0,A9,31,CD,ED,09,62,8E,C0,D1,88,86,AE,45,CF,0C,C6,A7,FD,99,67,13,29,23,8F,90,FE,6A,16,98,F7,28,06,74,77,EE,0C,1F,70,FF,39,0D,17,E1,B4,F8,60,A3,57,41,B3,7B,78,7D,EB,D2,08,23,65,DF,13,BF,33,D5,70,EE,E2,51,05,63,51,8C,9A,E9,E5,DE,A8,CC,4B,BF,89,A2,A8,FE,59,CB,73,A3,BA,E8,16,EE,96,16,06,9B,10,64,C0,89,E4,E9,46,B8,0A,51,70,72,8C,CF,85,1C,F4,60,B0,B5,88,D1,DC,50,F9,74,07,E3,C7,72,6B,B5,33,32,A7,1C,05,62,94,7A,85,7B,F5,38,3A,5E,3C,0F,2A,18,41,71,63,16,56,00,CF,B8,A3,DE,CE,17,FA,9A,93,2B,C9,76,1E,43,0C,DD,AE,4E,9A,CA,2C,DC,26,F2,02,EB,E9,DE,ED,6A,9D,8A,6C,5B,1D,FE,24,67,93,57,5D,19,FB,AA,B9,88,18,09,59,18,96,05,90,06,3F,65,D0,39,59,42,75,66,EE,D0,BD,74,3A,4B,65,9F,E4,EE,99,80,2E,85,0B,EB,AD,C7,69,9A,04,BE,48,D9,9B,1C,64,C2,CD,64,9B,13,5E,CB,D3,80,1D,E6,FE,2E,2A,BA,38,8F,06,EC,47,A9,8B,32,1C,19,13,74,22,A6,95,8F,C1,41,4A,F3,93,B8,F1,8C,4F,4C,FC,B7,18,60,DB,F2,E3,B7,6D,EA,0C,CA,E6,EE,FB,63,7E,87,22,3F,4E,20,AE,B6,18,70,43,AF,92,80,FD,4C,86,4D,3E,12,1F,65,CC,EF,69,DD,B0,D1,60,1D,B0,85,4F,2F,22,8A,24,CA,86,55,55,49,F5,31,18,B4,A1,89,96,9E,08,7C,8A,79,71,17,64,DD,3B,D0,48,DF,3A,9C,52,CB,8C,C5,F3,C3,B9,B8,DD,87,F3,8F,A0,58,AE,16,9C,28,47,FC,66,FD,D7,58,0E,C2,5F,F1,9C,26,C0,9A,4F,34,DA,97,55,3E,38,B2,74,DD,31,DE,A5,18,FF,C2,C5,71,BA,E8,F7,5D,CE,1A,80,92,65,2A,C2,CD,62,B0,42,30,06,88,68,0B,B0,66,B9,E8,AE,C9,96,37,0C,FB,CE,34,62,36,76,C4,26,C1,16,C4,1B,1F,0E,12,08,25,DC,A2,0A,AA,58,C7,0A,09,9E,7D,04,FB,70,70,20,47,7E,E6,D6,01,26,5F,6C,A9,C4,3C,9F,7F,79,83,F0,D2,F6,B1,08,8A,09,FC,03,9E,5A,65,A6,84,7D,F3,A7,8F,B8,A6,63,42,F0,59,45,EC,3D,A0,BA,82,20,35,7A,EE,CB,E4,F2,3B,3B,4F,13,56,68,23,F1,4D,D4,57,C6,D4,FC,44,9C,CB,3E,C5,68,E1,AE,A1,26,DB,F7,C9,85,DC,E8,AC,4A,62,B9,4E,4D,BF,BC,DA,B1,67,72,4C,16,AF,A1,05,96,FC,50,D2,99,3E,93,51,B5,95,A7,28,87,F6,11,70,6C,2C,77,B7,08,3D,60,DC,B3,34,43,42,C3,2E,8C,25,5E,72,56,1D,EA,27,D4,FC,89,1B,D4,59,E7,6F,70,04,86,09,6F,0F,88,44,3C,BB,32,7D,71,A5,2F,1B,B3,BF,62,9E,54,31,EE,1C,D2,D2,59,C7,B8,67,1C,CB,35,EE,BC,4B,C8,E1,E7,AA,F1,E9,5C,85,7A,D8,20,79,9A,D8,A8,16,1C,40,5E,4F,5C,E2,21,81,F3,F8,98,9E,86,90,B2,D9,B6,C6,97,F8,F0,0C,91,4E,F2,9F,4B,B3,BF,B1,FF,DA,71,7A,55,E8,A3,0E,11,97,92,3E,26,0E,31,5D,86,81,B6,D3,46,CB,BD,F6,52,88,1D,D8,45,76,0C,3B,34,0E,A5,AC,49,FD,A4,9F,DA,EB,EA,ED,9A,98,53,B1,1C,77,E5,A1,5C,DF,AC,B2,96,35,92,33,9A,2E,03,3E,9F,DF,BD,A8,31,47,19,A5,E4,B3,FB,02,17,17,D5,61,AC,07,B1,F8,35,81,2E,4B,23,95,77,35,DB,43,71,5C,06,67,E5,DC,7D,63,46,4C,0A,F3,3C,28,50,E2,A0,FB,C8,D7,4C,58,2D,B0,F3,4B,B6,14,B1,FB,CB,B0,4B,FF,54,34,E2,0F,90,C9,33,CF,5A,AE,76,B1,C8,3E,D0,5A,D4,F0,0E,61,12,37,63,27,90,F3,FC,12,F8,86,3B,5A,0E,8C,89,54,57,A4,AE,5D,D0,05,B1,BD,2B,BF,57,1B,80,54,EE,EF,C1,FA,6A,F2,7E,72,23,93,AE,EE,85,E6,AE,1A,25,C0,AD,D8,89,0C,E1,B2,14,BB,E4,64,FC,17,1E,7F,53,66,6E,AD,32,B7,27,16,A4,50,53,BB,06,5F,D7,D7,71,3F,03,45,83,58,8F,55,30,74,A2,9D,F6,C9,FA,31,2F,0A,1A,AD,F3,D1,4C,75,EB,74,67,AB,C2,0E,64,87,24,D6,99,70,58,65,B6,45,FF,52,B4,3F,5A,1B,4A,FD,43,E0,12,BD,D8,05,0C,BC,DD,9B,47,1A,07,14,23,12,57,E8,0E,56,72,8C,1E,31,45,07,B8,37,D4,E2,16,48,A4,28,B5,07,E2,83,79,F2,DD,96,11,85,0F,77,42,1D,C0,8F,90,33,B0,21,CA,A0,08,21,7D,92,51,CA,82,2F,3E,79,07,AD,EE,C9,95,1E,B9,76,3A,98,82,03,94,BA,CA,7B,09,AA,39,47,78,B1,DA,C2,0B,8C,B8,1F,E4,E4,4B,DE,8F,03,86,65,4C,21,AA,4A,0F,62,34,C3,6D,E0,FF,77,87,99,59,45,7E,FD,E6,8F,02,5E,6A,AE,2E,AF,A0,01,CD,08,EF,9E,87,9B,37,67,3B,3E,B3,0F,4A,E0,50,10,F4,EA,23,1F,A9,47,40,4C,AA,E5,55,F9,98,43,0E,1E,5D,CB,CB,22,6B,32,8F,43,ED,6C,85,87,01,59,E0,90,7E,73,C3,36,DD,62,A9,5B,6C,EF,A2,B4,BC,05,C5,5C,82,22,DA,07,A9,35,F0,DF,66,67,4B,C7,F4,EA,14,BA,3D,B8,83,83,19,33,16,44,89,9B,77,19,72,D3,EB,A2,F5,7E,F0,82,AE,56,07,BE,BC,99,0A,11,A2,1D,94,20,8A,EE,39,CB,8C,92,FC,47,8C,45,52,38,B8,42,C6,CD,1B,5F,A9,07,31,3E,FA,D0,D2,2D,28,24,47,30,40,F4,FC,AF,2E,73,0D,0B,C9,4A,46,12,31,07,C6,C3,F6,73,80,0B,EE,99,B4,62,40,80,C8,18,46,55,F9,BC,2B,B0,1A,0F,26,DB,17,45,73,D2,96,77,84,B1,C0,DF,70,4F,8A,A3,B2,B2,8D,72,84,66,CB,80,8C,13,2D,1D,97,BE,FF,77,92,2B,14,60,5F,53,2B,95,05,94,EE,66,8C,EC,75,ED,5D,F8,7D,2A,23,80,B9,71,61,AA,F2,EF,06,F6,0A,64,1D,BB,F2,7A,76,11,7A,66,DD,27,A8,91,70,63,23,4E,7E,F0,B9,7F,4F,92,77,99,D3,E2,1C,F4,65,75,A9,F3,D7,A4,42,C7,9C,15,85,D8,AB,81,84,36,E5,50,B2,F2,C1,2C,B9,D5,50,8A,C7,12,2B,19,33,CB,D5,24,CE,8E,D9,8D,3D,86,13,20,D2,03,E1,B7,DC,47,3C,94,5E,3A,C9,D2,FB,35,1B,E2,01,90,9D,F1,F3,6E,42,F7,FF,CC,CF,49,10,8A,99,AF,DD,88,B7,2C,82,77,19,5B,62,3A,E8,59,24,A5,9A,53,D4,10,0E,D3,D0,18,CC,60,1B,1B,94,F0,A0,72,15,E8,FB,88,9A,D6,F2,D3,BC,9C,64,9A,EE,D1,CB,DA,D3,23,0B,FB,F2,08,0B,B6,A2,E9,32,A0,3A,21,13,08,80,20,17,B2,F1,BF,26,F4,63,F7,A4,90,DC,02,3E,47,94,A8,62,6F,AC,A7,09,B4,F3,08,45,8B,8B,3A,89,68,D4,CE,E6,AD,9E,45,C0,17,46,D0,83,D8,94,29,89,5E,5E,AC,6D,C8,F8,2A,DB,45,99,42,82,54,87,64,2B,83,55,9B,3C,AF,33,C1,9A,BB,D4,6B,62,EF,B3,28,45,FF,6F,C2,26,37,6D,5F,F1,C8,2A,69,2D,39,E6,34,60,C9,B6,CF,63,06,08,CF,0E,CA,37,D4,62,A4,2E,96,33,86,A2,5F,B8,39,15,59,86,F3,68,6F,5A,50,97,62,7F,AB,6C,6A,AC,2C,67,07,04,F4,DB,6C,92,7F,7B,98,FD,C7,00,4B,C4,75,30,0A,20,BB,51,D1,04,6E,5A,F3,AE,35,5F,C8,D9,AD,F2,65,12,E4,62,15,EA,0C,5F,BD,D1,18,C2,73,DA,1C,62,38,45,39,59,59,84,7E,5A,54,61,2E,7C,C4,0D,4A,3C,9D,CE,88,9C,AB,05,37,DE,6B,10,64,98,E5,1B,C9,2E,E7,78,40,9F,FA,5F,97,8C,31,3F,76,BA,99,7C,B8,52,DE,7E,01,24,C4,64,E3,C8,29,FD,CF,F0,46,22,03,49,30,9F,A0,B4,20,3A,CB,4D,3D,48,55,60,32,26,EC,E2,1A,68,B2,4E,F3,AA,44,55,74,E0,C2,E5,81,F7,D6,71,8D,19,39,18,83,A9,64,63,65,D3,1E,E9,E6,20,98,30,8B,CE,04,73,EB,71,EC,95,75,B5,2C,A1,E3,65,0C,F0,39,FE,E8,71,20,18,BB,19,A5,CE,F7,80,3B,D9,78,9E,AA,06,2E,8B,A1,5D,0D,BD,B4,28,54,F7,2A,2F,EE,58,92,5E,0F,B9,CC,1B,B7,83,E0,C5,32,2A,00,F5,41,F0,CF,C2,8D,68,20,E4,5D,2C,8F,5C,57,68,0D,5C,A5,A7,74,62,5D,7F,E9,1B,9A,92,1E,A3,E1,16,4D,08,C3,25,D9,6A,D1,BB,6B,D8,66,FE,5B,D8,41,6D,EE,EA,ED,29,F9,E1,91,7C,D9,9E,12,76,D9,AC,EC,B4,6E,F6,7F,74,79,96,AF,A0,EE,59,B3,31,69,00,8D,CB,56,D8,9C,6D,DA,B7,DE,91,DE,0C,92,A3,71,67,2A,85,0E,B4,7B,2D,76,AC,A6,78,70,33,B6,D7,03,41,B4,73,BE,43,9E,AC,2A,FF,5A,F0,E3,6B,F4,87,5A,BC,52,33,D8,DB,01,2D,F3,40,75,E2,65,63,28,94,9E,FA,1D,8E,8F,B2,F2,C4,05,43,9B,60,07,0B,40,03,8C,5D,DC,6A,CD,54,DA,B1,9E,C4,40,21,8A,F1,D5,FF,70,5D,71,5A,7D,64,8B,77,B3,74,D4,03,05,6E,D1,73,9E,47,E6,90,E9,C8,78,DE,08,E6,42,D0,A4,9A,E3,88,2B,CD,9A,1F,73,AB,9A,FE,5A,20,39,06,B2,EB,4C,9F,9F,E1,D8,BF,85,05,17,E2,9E,1A -roundConstants_full = 23,AF,7E,35,9A,34,A6,BE,48,C0,0D,47,D6,A1,FC,91,71,E6,B0,A2,EB,03,E4,D2,B2,2C,0D,11,22,9A,E7,44,3C,0B,8B,20,9C,2D,87,63,F0,16,94,0E,85,8B,51,E3,47,82,80,C7,6D,0D,4D,CE,04,BE,79,67,ED,14,A0,24,FD,12,8A,3A,28,F5,36,F8,5E,52,A4,1C,5E,6E,64,20,83,AE,59,0E,7A,46,68,BF,61,67,84,79,95,9E,4A,0A,31,39,11,71,5B,71,3F,2A,A0,D6,14,AF,77,48,76,74,8F,38,81,46,58,6F,CE,35,0C,E2,2F,60,25,55,27,52 -keyMatrices_full = 55,7D,8F,D8,AE,9D,F3,56,13,90,35,C9,BB,2A,39,3F,B8,09,76,84,BF,9E,0E,26,A2,14,58,70,CF,1C,C3,14,C9,3C,A5,79,6F,3D,45,B4,7B,06,E2,CA,B7,86,69,3E,D3,F1,9A,DB,20,92,5F,1C,1A,D3,9A,A1,38,82,83,5C,74,66,01,90,91,09,B2,17,DD,27,80,8D,35,65,85,77,49,9E,6C,5B,7C,00,89,BB,87,AF,0B,E2,E7,3D,94,94,E8,CA,08,B1,BF,AE,DB,F9,9B,D2,CD,19,40,B8,31,BF,A6,CF,F6,12,6D,5A,48,BA,E1,B9,40,68,81,66,EE,14,D2,9F,06,4A,9C,47,F2,62,88,9D,78,18,57,EB,6D,CC,8A,FF,A8,39,5F,73,6B,1D,0C,56,11,9E,00,7D,AE,B6,3A,63,3B,05,51,CE,82,9D,81,E3,EC,32,C3,DA,77,75,24,E2,A3,84,72,DB,A3,B8,3E,EA,EA,21,F6,96,92,A4,DF,DC,57,CB,C7,EF,22,C2,A0,D7,74,6D,A0,02,DF,DA,C5,73,55,6C,8A,0A,40,61,BA,FC,89,A0,A9,4D,EE,7E,90,C2,8E,6E,14,D9,37,E9,8B,AD,DE,99,CB,75,57,22,44,35,E8,EE,F0,0C,52,CD,4E,07,02,4A,2B,A9,E1,BE,10,83,E5,A5,67,9F,3A,87,60,3D,85,F7,C6,34,60,D4,B5,E2,03,5A,ED,E1,71,80,6C,94,5F,16,A4,65,1A,40,F8,E4,16,A4,F1,17,4B,02,43,99,D0,B9,0E,8D,E0,30,CF,E0,1F,C6,67,03,A2,79,33,7F,B0,9A,74,DA,2E,A4,0B,C9,33,AE,36,24,8C,DF,79,F9,1F,B9,E1,40,58,3A,52,76,E5,6D,6C,4C,B6,A2,10,9B,8D,DE,8D,8F,A7,72,1C,E5,AC,96,F9,D1,D0,C1,65,3E,95,9F,61,E8,6E,E6,94,8C,BB,66,94,EE,DE,06,DD,20,F1,C8,1A,EC,B2,B4,91,98,F7,25,15,3B,73,CB,B5,6D,81,1C,CE,33,C7,F8,D2,1B,EF,0B,4C,42,34,C1,87,7C,33,F1,89,03,6C,D0,81,B4,CF,11,52,A1,9B,26,C8,0E,81,BF,29,14,F3,CC,C0,CF,60,87,02,7D,80,BB,EB,A5,BC,E6,72,05,59,08,CF,3F,F7,57,AE,19,B6,91,AE,53,25,57,0B,B7,7D,51,C4,3F,13,6E,0D,6D,D9,FE,E6,BF,FA,7F,BB,39,5C,EE,F7,F0,C0,BE,F2,A5,A1,D6,1A,31,C3,B1,C2,DF,8E,00,60,9E,B8,78,78,A7,D6,43,FB,CE,B9,46,D3,50,14,90,1D,EE,D8,4B,D2,7B,11,EA,91,89,B3,B9,E1,CB,C6,00,7A,23,58,EE,0E,23,F2,56,37,AA,B3,1D,27,26,22,64,37,56,C2,4A,4A,E8,66,E0,6E,8B,0E,55,DB,13,0C,DB,5F,BC,69,19,B9,0E,C7,B2,71,C8,D4,1D,E4,F8,39,AE,7E,C5,8A,9B,DF,BF,3D,95,2F,EE,0E,5E,D1,E0,27,82,45,FE,6B,01,68,D7,9B,67,72,17,AD,C3,01,DE,30,EE,95,AE,E0,EB,0F,1E,12,30,E3,68,22,44,2D,DF,74,1C,5A,21,94,5C,6C,EF,98,90,60,0F,25,4D,FE,14,04,14,C7,96,F4,5E,09,27,D9,C8,49,37,34,24,13,35,4A,D1,0A,9A,D4,2E,97,98,1F,D1,61,F1,4E,D5,A2,D5,0A,3A,9C,C0,A0,AC,4E,5B,89,E6,56,7A,FC,91,2A,8F,6F,15,8D,09,B8,B9,D6,61,19,E6,9B,1A,06,3D,7C,34,8D,F4,08,0A,58,DD,0C,1B,37,77,E0,67,96,B5,FE,FC,48,60,68,5D,17,99,54,67,66,32,2E,DE,07,3D,D7,06,21,D6,2C,14,C0,3F,74,CD,E1,EE,26,AC,6D,29,8A,74,4D,56,27,E4,F0,B9,0B,9C,76,41,E1,82,83,EA,35,08,F2,80,13,91,A3,F5,32,B6,DA,2E,7B,83,82,08,B0,5D,AA,7C,D2,FC,24,B6,84,CE,63,A9,DE,32,A5,F8,68,CE,09,56,B7,F0,6C,04,6C,BA,27,11,81,99,F9,49,64,BE,29,23,7B,9B,10,4C,55,F4,FD,5A,63,B8,B4,4C,6F,F4,89,E4,A9,46,65,D6,1A,11,0E,4F,80,62,5E,19,34,44,67,12,89,88,55,47,AF,31,F1,9F,EB,7D,34,5C,82,AF,30,40,13,5D,DC,FB,B8,61,23,28,6D,8F,01,DE,6D,78,FE,1A,65,DE,07,92,A8,B7,5F,B6,F4,69,B7,B7,D4,1B,25,F6,A4,5B,50,76,22,E2,C4,20,AC,82,A7,EB,9F,15,A2,2B,5A,E9,AE,BC,5C,38,E1,92,63,05,01,98,C6,06,8B,14,AC,F6,74,8F,F8,9E,68,32,3F,BD,AF,01,AC,61,EE,18,6C,9B,C0,D9,E4,EE,D5,6E,18,CB,AE,42,96,49,D1,FC,0C,A2,E0,04,6F,65,05,7F,57,EC,00,F5,E2,7B,B5,80,66,5D,40,2E,8B,17,4E,8B,82,6E,D3,44,F6,D2,E6,E6,4D,2F,C0,EF,C9,54,74,CA,8A,BB,AC,8A,8B,F9,30,B4,40,82,8F,A9,06,D8,04,CB,60,81,C1,CD,09,7E,1E,5A,36,AC,CA,CB,BB,7F,26,61,49,6C,E9,24,C7,33,94,89,02,DD,5A,18,C1,2F,E5,AD,88,55,81,D6,F1,F3,CE,2E,BF,0B,98,D3,50,4F,A0,56,A0,43,F1,D7,70,AE,EC,18,45,76,D5,87,98,F0,21,8F,FC,36,B9,32,32,A0,7D,26,EA,53,D1,5B,10,2D,D8,76,C8,5E,79,71,03,B1,E7,F6,13,71,D7,A7,56,3E,AD,7F,10,54,D1,17,71,36,E5,0C,91,5A,80,76,A3,AB,F5,F4,03,83,B1,64,AE,5C,C2,EA,85,88,E1,F2,EB,98,19,D9,F3,2A,60,01,84,8D,FE,10,E8,3B,75,15,C9,E4,12,2F,D2,57,CD,58,DD,75,24,D9,DC,9D,EB,23,74,B3,F0,FA,44,12,70,51,6B,26,E9,9A,DC,7E,BE,A2,E0,52,8F,24,DC,99,EB,30,EB,01,4D,90,64,D0,AA,D3,D4,4A,92,34,00,46,C7,C3,9C,46,12,BC,A9,93,BA,C2,AA,2E,31,9F,5F,41,02,E4,62,E2,F0,53,01,0D,79,B8,58,53,77,49,49,80,47,0C,2A,7C,64,38,20,01,E7,9E,D5,4C,EB,8A,0D,35,CC,B2,92,17,8A,A1,7E,52,D2,E8,B2,36,11,3C,68,70,54,BD,1C,FD,67,FC,E8,AF,D5,A1,85,E1,1D,7C,A6,AD,0D,F4,7F,5F,3E,18,70,EE,1B,E1,C7,73,29,54,FC,30,E8,74,6B,78,D1,54,28,55,C7,22,15,08,57,1D,C6,75,68,F7,AF,BA,47,4D,4D,F2,C7,A5,F6,30,3E,54,DF,EA,CC,3F,1C,1A,EE,0A,55,87,61,A1,22,6C,AB,D7,EC,7A,B8,00,DF,90,34,A2,14,8B,10,0A,EB,AA,AB,94,1D,8E,CC,DE,BD,4F,67,34,8A,C8,07,33,E5,07,F0,EF,3B,4C,FA,93,26,5E,98,B5,D3,3C,3B,4B,4F,3E,B4,99,C0,D4,C9,BB,22,97,1F,D0,CD,DC,C7,62,9C,25,93,4A,99,75,6F,61,59,E5,51,BD,4A,30,CE,66,C1,72,2C,3A,2E,CE,33,3B,36,78,98,A6,06,A0,F0,B2,14,8F,C3,9F,28,A1,53,E5,15,B6,77,EA,1B,3E,40,32,22,42,FF,24,96,0B,C7,39,24,A0,11,DC,FD,51,42,D8,C8,02,21,A3,C1,B6,15,D7,DC,07,11,BB,DB,BF,F2,2A,D7,F0,EB,3A,60,27,D8,01,2C,64,C1,72,71,15,86,F2,85,DB,30,A9,9D,7E,86,5F,0E,F1,47,83,9D,C9,4C,51,B5,5F,50,AA,89,E3,9A,9C,B8,DE,83,64,E2,04,F9,2D,5A,D3,D8,20,9F,41,91,B5,F3,6E,8C,BC,EC,74,89,D4,84,E1,CA,CB,AD,05,22,18,55,A9,19,28,D7,DF,26,2B,0D,58,88,26,42,66,B0,68,12,97,AA,F7,41,25,24,72,A0,FE,D4,EC,E6,72,84,77,4F,2A,C6,76,AD,DB,37,82,87,58,F6,D3,AB,E4,2A,70,C7,26,B8,A6,7C,5E,93,60,B3,D6,94,D1,4F,40,05,6D,40,1B,8B,00,D0,87,B1,9D,DC,D6,19,D5,91,E3,80,D3,49,9B,38,FC,64,2C,03,E5,48,5A,F0,29,FC,A8,61,93,F0,73,00,F4,32,8A,F8,DA,89,70,FA,D5,2A,94,93,8B,58,42,92,3E,25,A6,2E,0A,38,86,3F,8D,66,60,C8,77,90,53,DA,D0,E3,F3,5A,D2,4F,C0,0E,52,7F,C4,F5,FB,1C,50,FF,F0,D4,CB,7A,E1,08,64,75,ED,1D,BE,C6,C5,64,BC,1A,A2,77,84,99,EC,10,6A,C0,F4,AC,E5,A3,E6,C8,6A,CA,C9,B8,E2,C4,DB,9D,55,A7,A4,39,A7,96,F1,CC,94,E0,BE,6A,48,DC,55,08,BD,D1,23,04,FA,8A,32,E2,C2,67,AF,3E,8F,7C,99,94,59,4B,F4,95,A5,C6,D2,FC,16,9C,EA,4F,90,CD,E2,83,3F,19,B9,EF,95,8A,FA,C5,B1,57,01,09,92,01,6F,E6,9F,65,A9,E5,A6,C2,4C,05,1F,6F,9A,BB,36,FC,6F,38,B6,42,2A,3C,4F,F5,20,AA,C7,DA,92,1D,48,E6,1F,C6,38,0B,18,39,2A,26,DD,EE,38,BF,AE,14,FA,C3,B2,A8,92,52,CB,80,F5,3D,F0,2B,DF,93,E6,2F,45,50,81,45,39,9A,47,E4,E6,E3,22,1B,AF,C0,10,A6,5E,49,80,4D,1C,D3,72,CC,FC,5B,19,70,AB,17,D2,6E,51,B0,BD,36,FC,72,0C,55,53,BE,38,DB,82,FF,A0,BC,AF,24,2F,D4,33,7E,C2,62,D5,DA,A6,3C,E5,AD,C2,A9,E8,D5,67,0E,E6,D3,87,C1,BE,29,40,2C,45,41,32,70,85,A1,F9,22,95,62,C1,1A,80,72,E9,9D,80,8A,D2,EE,B1,F4,12,89,4B,42,02,79,B8,4A,95,B4,DC,95,54,67,EC,E6,34,2B,5D,84,B9,08,30,29,EC,5C,AB,6E,8A,F7,39,70,F9,C3,F8,9E,34,34,0B,E7,6F,94,67,79,AA,F7,46,9D,65,3F,7F,F1,41,BE,9D,61,3D,ED,C4,42,97,24,0D,A5,5B,5E,C2,8B,90,B0,01,1C,9F,1D,B0,2D,CA,67,1F,91,65,EC,9F,DD,98,F1,FD,84,34,01,7F,F1,E0,A3,30,AA,5A,80,1B,EE,F1,5C,BA,4D,72,82,A4,35,FE,2B,D5,10,EC,9A,E0,FF,77,3F,3E,4B,61,2B,D2,D7,6B,08,81,37,51,B7,9A,11,38,61,AF,EC,9A,77,3A,A7,E4,62,8A,95,67,1E,90,70,B4,DA,BC,F7,C9,03,D3,BD,6A,FD,91,06,23,34,EF,0C,56,33,FF,3F,AA,79,14,E4,B8,DE,FB,7F,CC,8C,C9,05,1E,03,5A,9E,D0,17,7D,0B,42,74,C2,AC,12,72,FD,51,6C,90,04,CA,B9,6B,8A,05,56,E3,9A,D0,6E,29,82,ED,5D,AE,04,FD,B6,49,81,4C,12,6C,35,AF,7D,63,11,AD,06,71,77,91,8D,52,C1,FB,6E,08,D2,8E,9E,E8,DF,CC,AE,9A,9A,CD,4A,A7,A3,34,75,0C,27,E0,A1,80,14,99,AB,9C,68,AF,6C,5F,6F,4E,16,B4,FE,AE,8A,4C,FE,54,A0,E0,71,22,D5,BB,11,5D,30,B7,65,9C,E0,EB,38,11,80,93,2C,E0,CD,05,FE,F2,66,D6,FF,26,E9,1D,82,31,1C,E0,2B,59,BB,38,B1,D1,DA,40,8D,90,13,D1,7F,A9,FD,89,28,BC,BA,3E,5D,60,4C,E2,B6,03,12,40,66,6A,56,D1,6C,4C,90,36,B5,70,17,B0,9A,F9,4B,FD,A3,72,86,F6,AF,BB,2A,36,EA,95,20,07,FB,73,FF,49,92,5E,C6,55,F5,AB,86,1D,25,4A,8A,F7,89,C7,F7,6E,FA,FF,CB,39,FF,83,07,A7,68,63,E0,2E,FB,B2,1C,BB,95,0C,91,10,CA,B8,23,0F,06,C6,0D,35,95,75,E4,A8,BB,C4,2B,97,1A,BD,9E,22,FE,85,C2,83,B4,01,60,3E,17,AE,E9,43,0E,2D,EC,F3,19,EA,5F,99,AC,B1,23,C7,E5,EE,BE,7E,1F,5D,78,AC,A1,CF,C2,DE,D2,46,4B,F6,92,E7,0D,DC,CE,A8,F1,D1,6E,79,4B,F1,EC,29,17,E3,02,E5,29,D1,F0,EC,9A,50,45,67,EE,48,80,2D,47,6D,07,DD,D9,90,A5,C1,32,C3,9E,F5,38,5C,2E,E4,BA,34,93,13,14,F7,F1,A4,5C,63,47,25,32,1D,46,1B,C4,01,2A,50,AA,24,DE,15,84,30,41,4A,D4,2C,B0,44,60,15,1B,30,EA,91,B7,59,7E,B8,FF,B0,8C,98,3D,82,56,CA,9A,A7,AA,6A,AD,B8,A7,58,5C,B0,99,39,DA,F7,90,EB,43,0C,C8,50,2B,38,56,E8,51,19,32,3B,03,99,46,75,74,55,12,BF,99,F5,4B,08,25,A9,3C,E4,19,53,8C,D0,68,3A,14,47,38,B2,59,9F,CE,C9,2E,6D,7A,74,6E,0B,4C,37,2A,78,1F,41,16,9E,7E,EB,89,0D,EE,23,DD,29,D6,53,E1,F1,52,7E,A9,CE,77,B5,94,7B,A9,6D,83,E7,8D,86,40,56,D7,70,76,A8,18,E2,65,E4,6A,8E,85,BF,A9,00,D0,38,50,D9,EB,AA,4A,B9,10,F3,53,58,39,4C,59,28,FF,BA,5D,B7,9F,85,4D,F8,87,92,B6,B4,20,D9,87,A6,C5,BD,00,21,F9,2C,27,63,2C,AA,10,06,83,41,DC,2B,04,01,FA,06,F7,5A,5D,A9,3B,0F,78,EF,64,73,3E,C6,0A,7E,17,AD,F6,ED,80,86,E4,6A,33,82,7E,22,D2,99,52,E3,B7,33,1A,2F,E4,69,ED,6B,DA,5A,28,91,2C,7D,54,90,52,77,6E,7F,21,9E,22,29,15,32,1B,E3,D2,62,10,8D,D0,E4,45,C5,13,8F,B1,2E,99,9C,D8,C4,B1,B8,1D,BC,0E,14,09,1F,FD,58,E2,3D,5E,00,7E,1C,1B,92,BD,88,CB,AE,B0,AA,E2,4E,FD,07,2B,51,7E,AB,FB,BE,50,76,24,5B,84,53,B5,75,3C,69,E6,CB,66,1D,70,04,12,FE,53,89,92,12,BB,57,D3,53,4D,97,A5,BF,C3,6E,D3,4C,AA,75,24,48,22,09,4C,6A,05,B1,E2,4A,D0,08,B7,42,CC,5B,93,AA,AA,7F,90,CD,E5,66,00,BD,FD,5B,CD,DA,42,1A,FB,3A,FD,75,10,82,D6,CE,0F,AC,3E,3F,1F,B8,61,9B,EA,17,93,24,F0,D8,02,A2,A0,80,3A,80,EE,EB,0A,3D,18,A5,5A,E0,92,91,03,7E,76,3A,03,A4,85,9E,90,D1,3C,D0,3F,AD,01,8B,22,63,41,E3,93,7E,A9,F8,44,0E,68,3B,D9,BB,F6,9E,02,98,E4,AF,C8,B7,9B,CE,F9,00,F6,E1,10,88,6E,03,67,D0,15,F8,8B,E5,CE,E7,F3,A3,87,FF,90,07,32,A6,39,B5,5B,5A,10,2D,D2,8D,03,87,FD,B6,7A,B4,71,07,F2,64,3A,50,7C,6F,B1,C4,A7,1A,8C,4C,E9,C4,E6,16,72,8C,4A,C5,85,AA,38,74,FB,86,48,C0,28,EE,3F,3E,86,0D,E5,EF,66,87,55,94,AD,82,30,D6,4D,81,9A,D3,70,A1,54,C9,D5,C6,31,B7,2F,85,F3,16,F4,3A,8D,E0,5C,BF,63,82,F4,1F,0C,0C,3C,C0,D9,EA,0A,B9,D4,6D,71,16,85,AD,79,38,00,20,22,D1,54,2D,BC,C6,4B,CD,B8,9E,A4,5D,1E,5B,CE,81,28,91,54,9E,30,1A,26,85,69,6A,90,63,08,1B,74,F4,4D,4C,F0,7B,B7,1D,EC,4D,3A,DD,21,E7,53,FA,27,97,90,97,75,E9,CB,FA,2E,63,41,EC,CA,C3,FE,3E,B7,26,F6,4F,38,82,A0,78,27,13,48,B9,2A,D0,93,7A,CC,E1,09,96,23,D3,B9,E0,5E,37,F9,F8,21,28,FC,F9,05,C4,7A,E8,00,11,F0,0F,E3,02,97,44,56,29,0B,BF,0A,6C,C5,2A,69,BD,29,69,0A,93,E4,15,65,86,1F,F1,A8,A2,CD,51,7B,AD,16,52,FB,10,71,F8,B3,C0,D2,5E,97,0C,CE,68,AB,AC,3F,09,B6,41,41,F1,09,A1,FA,CB,AA,1C,FD,B3,67,3F,BC,1F,B4,0D,30,AC,F2,90,F3,27,DE,2E,D2,E5,BE,01,91,8F,88,F1,9C,D5,DD,F1,88,C0,0B,C5,60,F6,6E,43,A4,BD,12,29,13,75,9D,28,DE,9C,65,CE,C9,B7,CC,4D,E3,A7,E6,9D,A2,B1,9E,B4,93,DC,1E,66,76,4A,5C,71,89,01,A9,17,EA,C1,76,24,05,37,33,19,AA,45,07,7B,16,08,CA,BD,70,9C,87,2D,4A,93,24,4E,8B,F5,63,02,D8,98,40,35,E3,43,32,12,3F,F3,D0,BB,B8,02,AC,98,CE,DE,50,6C,90,CD,56,42,C7,DE,BA,CB,AF,E3,40,8E,70,DC,D5,CF,96,94,7A,13,3C,47,E0,9F,3C,E8,83,4A,8F,EB,4C,6E,3A,64,E3,BA,51,4B,D4,25,FE,07,9E,FB,71,55,5E,35,94,73,F1,06,6C,2A,56,E4,F3,21,60,51,7B,C7,9C,4F,78,91,79,62,91,75,93,23,22,E8,6E,FA,C2,AF,0E,B5,C1,FE,2C,33,AA,A6,50,7B,44,E4,1D,12,91,49,4E,B4,E3,22,D8,35,1D,0B,B9,60,DE,90,33,1F,BD,E7,C4,2F,14,C5,47,7A,CA,91,F5,72,93,7A,02,F6,2A,F5,4A,E5,BF,B1,81,17,16,2F,8C,47,C9,D1,63,52,39,B2,6C,84,02,D1,D8,1F,92,D1,6E,ED,53,8C,3E,C2,03,23,92,BC,46,D1,32,9C,4E,29,5A,27,87,C3,5F,FB,68,05,87,07,85,6B,E3,C3,F8,6C,4F,6D,F5,7E,77,5E,F3,A7,DC,18,C4,5B,6C,09,D2,12,95,E6,17,6C,A1,F5,FC,A0,B5,0A,40,E1,60,1A,A2,28,34,1B,6C,48,B8,E2,AF,91,A4,68,11,36,26,0C,5D,49,70,2F,97,77,C8,87,45,55,0A,94,E7,3C,38,F3,34,E6,7E,C6,47,D9,E2,C7,74,E4,82,B4,31,6A,3E,17,0C,84,39,74,95,7F,08,5E,29,D5,6D,16,28,06,62,34,92,15,41,30,5E,42,A2,A2,9C,85,A2,9E,8D,32,DF,16,EE,44,7B,44,56,6A,71,73,0E,D7,03,AF,4C,B4,A2,86,7D,5D,05,B7,45,3F,96,22,14,65,8E,FB,E8,39,3A,16,C5,97,18,1C,33,FA,11,07,F5,A6,21,A4,D3,DB,8D,A7,EE,F1,0D,09,2B,18,52,F4,48,30,CC,B9,42,7E,E1,60,16,AF,6F,EB,63,8E,F1,B6,85,17,D7,14,64,2F,99,56,C1,7D,BD,D6,E3,93,37,03,EB,7E,F8,3C,20,74,CC,AC,F0,8F,CC,EB,FC,1C,5F,14,C0,BE,9F,5A,E4,93,93,5D,C6,44,D7,C4,EC,69,10,80,7D,C4,62,40,1D,91,FA,45,89,4F,F8,E0,2B,E1,55,DB,0F,CF,AB,C2,32,4A,61,BF,B4,CF,BF,E7,8A,50,F8,14,50,0A,D4,9D,89,F6,F5,59,B4,0B,E2,45,46,B3,68,E3,00,99,F7,E3,00,AD,28,BB,85,EA,33,87,E0,D6,10,31,CB,9D,48,1A,93,62,32,D0,F2,85,3F,58,62,E2,71,D7,5C,9A,CD,E5,4F,10,AE,D6,93,30,41,C0,F3,60,AA,3F,3F,1C,D0,A1,F8,7F,8E,B2,7D,1E,D3,AC,51,4F,2C,8F,4B,1A,35,3C,52,1D,02,87,E8,20,2A,62,2F,31,9B,4E,18,20,D2,68,D2,A6,89,42,40,6A,C3,4B,5C,72,2F,8B,86,E5,83,2C,54,3A,35,C2,E0,24,65,37,37,D0,36,DA,1D,B0,60,DF,B6,82,37,8A,92,92,B4,8A,3A,A0,76,D3,4D,99,8A,A3,7C,4C,83,72,3E,8E,AB,84,64,9A,96,46,AA,82,C4,28,D7,66,54,F0,EC,81,40,2B,CF,45,C2,4E,69,E3,53,6D,12,B4,2D,93,0D,B2,FE,B5,78,A3,58,EE,B7,07,8E,2B,68,DB,04,FC,35,F8,66,C3,46,C4,7B,3A,85,1F,7F,77,FE,97,85,64,F0,77,7A,37,5D,33,D6,A0,EE,7F,F4,10,8B,5F,FA,EB,E1,F7,5B,18,25,BB,74,3F,C8,92,20,4F,84,F0,A5,E7,35,A6,8D,D3,11,64,95,1D,27,DB,4A,A8,55,4A,4E,66,77,91,6D,01,F1,B6,64,B1,D6,C0,47,CE,B5,D3,CC,E6,6F,6D,1B,7A,86,F6,A3,BC,CE,04,BE,1C,F7,3B,E7,F0,DE,50,D2,4A,29,00,8D,B5,EB,CD,CB,C0,05,7B,AE,63,4D,82,19,6D,0C,10,02,BE,B6,88,DE,64,11,27,3F,E5,20,EC,53,B2,8C,9B,5C,AD,B8,D8,BE,B3,C8,94,8C,8C,AC,07,54,13,34,6C,94,E1,5B,12,A8,44,E8,26,57,73,46,76,F3,3B,59,79,C3,A6,B2,18,97,1E,47,A8,3A,FB,2B,30,1D,81,41,8D,06,B5,62,82,FE,40,47,47,EB,CC,83,08,2A,77,AF,1F,9F,F3,06,30,E4,27,19,69,CA,99,A0,61,53,E4,AF,2E,CB,84,AF,FC,DC,B1,2C,E3,C4,50,DE,DA,F7,9F,E5,6F,FE,85,A1,26,A7,46,6C,EC,E9,A1,97,B2,4F,20,0F,B5,22,67,D6,C1,44,51,0A,5F,44,C1,9D,B5,2B,30,D3,5C,EF,D9,57,97,9F,1C,22,A7,AA,34,87,E1,08,3A,29,BC,77,D5,4C,E6,DE,57,EA,5D,F6,8C,F1,D5,6B,6B,B4,56,FE,FA,23,71,30,7F,32,32,02,0E,54,02,4A,95,84,B7,8F,06,1B,8F,AA,B0,EA,E6,03,1B,15,6D,3D,6D,97,CE,D9,2D,5B,D7,BF,39,62,5D,2D,38,56,B3,5A,0F,14,BE,83,7B,C8,BE,24,F1,E4,97,9C,E3,9A,33,FF,51,31,1C,17,AA,8D,5C,29,88,93,91,05,F8,3B,41,7A,EF,B9,13,05,AA,4C,61,6C,2C,B7,5F,DD,E3,46,3B,70,A1,A9,F6,44,94,A4,1F,C1,AD,7D,23,4B,E4,47,86,F0,40,A8,17,B9,1F,F3,11,0E,67,84,F8,AB,57,8D,1F,13,0B,4F,F8,79,EE,CB,A2,86,F1,66,9D,C1,B6,9A,93,6A,6D,50,56,E3,F2,E6,19,54,E5,93,38,C4,35,F0,18,72,D1,DE,61,32,86,AD,AE,EE,2F,8F,47,A8,27,2F,04,8D,42,25,CA,80,54,4A,C3,72,6C,A8,CE,E3,2A,3D,9A,A6,4A,A6,F4,E9,09,17,31,89,D7,4B,B5,D6,9E,D8,2B,FD,5A,4D,CD,28,59,1A,F8,14,64,24,3E,3E,E7,79,A7,56,92,C8,82,DA,63,D1,A5,1F,51,0E,DA,48,57,92,3A,C5,6E,A9,E3,F5,5A,EC,17,A8,2D,0F,32,51,DA,E3,55,B7,62,F6,10,AD,F1,F4,B0,D5,6F,40,28,99,02,FE,89,FF,28,B3,23,76,CE,92,CD,9A,3D,44,30,89,10,88,A4,D9,D6,B3,43,C0,86,47,F4,53,A8,57,FF,EF,F1,14,51,E1,E7,90,51,B1,23,F7,38,C2,82,6A,BE,0E,7C,E2,D2,C2,FE,98,07,44,85,BB,8E,E8,E0,79,51,E3,CD,AC,92,71,0B,8B,0F,73,71,B4,86,26,8A,D3,8B,F9,44,78,73,64,48,19,D8,A9,A1,AD,5F,10,04,53,A6,B8,0E,28,7B,19,0F,B8,A4,B1,3F,25,18,EE,BF,FA,6E,25,2E,AF,B2,70,2D,8E,1B,63,9C,8B,27,32,6E,5F,2F,E0,C7,ED,ED,97,67,FF,E0,67,D7,CF,24,B6,29,A8,F5,F6,D7,19,2F,B8,90,50,48,E8,AC,04,37,BB,28,82,9D,FC,E6,44,7B,4A,68,B3,8D,D4,CD,45,9E,E0,0F,9B,11,8F,58,13,88,08,B0,28,14,62,AF,6A,F1,10,93,16,0E,9D,68,85,A7,93,7F,F1,9F,EE,40,39,35,28,9E,60,24,DC,05,30,60,56,3F,E3,1C,D1,75,51,82,0C,D7,1E,A3,2B,01,D4,F6,6F,EC,BE,AD,BA,B0,47,22,5A,82,95,45,71,04,C2,80,1F,65,07,29,32,D3,D5,1E,FE,1C,63,6B,1D,37,50,8D,CC,AC,EA,14,63,BF,AA,30,86,EA,28,12,76,12,98,A4,8A,86,90,61,94,93,B4,B6,6D,A2,D5,BB,8F,74,D0,1E,71,E1,8B,92,49,26,A8,DD,AE,9F,11,BC,42,C0,A7,28,2B,01,DF,1C,10,9E,0A,C7,DD,F1,41,FA,36,36,72,5E,2E,F5,5B,DA,C3,37,E7,04,02,8E,C3,6D,60,C7,4A,20,D6,11,FB,0C,A9,48,F3,2F,20,CC,9F,1C,AD,16,D0,D5,A6,C5,1E,A4,D8,9A,E3,B6,BE,16,F7,04,E9,4B,C7,5C,B7,51,3C,7A,02,74,B5,4E,10,72,89,82,91,A7,A3,77,A7,D3,42,B7,46,39,58,4C,5E,C6,CC,1B,DD,E6,9F,57,B3,F2,9A,B8,7C,7B,20,70,02,B0,4E,29,AC,EE,C3,23,56,1A,43,35,79,A4,4B,51,60,F7,B0,5C,52,51,15,7E,1B,14,C3,44,C8,8B,36,AC,9E,E7,15,57,8A,90,AA,5E,03,AD,92,6F,99,16,63,BF,82,72,77,CB,FD,D7,E2,F8,15,81,B6,A1,63,19,E9,A1,F2,39,11,F8,B9,61,5D,39,C5,B4,BE,FE,A7,B4,A9,19,32,9E,7A,B5,96,A1,EF,1A,DB,BA,B3,F1,FE,F6,07,1C,4B,14,7F,2B,D3,68,B0,24,43,E3,D4,B4,6D,DD,90,23,BA,D9,23,FE,5D,F4,72,7B,98,3C,A5,57,75,6C,41,8E,53,7C,D0,14,A8,39,BD,84,BE,4D,BC,7C,4C,05,12,42,00,91,96,AA,9B,55,B9,8A,24,E5,43,FF,1F,C8,8E,10,2F,F2,C4,08,C0,37,7D,5E,64,2A,98,0B,F0,9F,10,4A,E4,4B,4D,8B,FF,9B,87,6B,BC,A7,89,47,DE,9E,C2,FF,F1,F6,71,A4,22,71,B3,22,98,50,AA,D1,63,64,A6,FC,60,10,1C,44,A4,30,6D,2A,AB,04,FF,87,27,B0,2B,95,32,1D,43,43,6D,5A,A1,31,7F,71,28,6E,EB,3A,0A,BA,88,23,D5,B4,E5,2F,56,5A,5B,A2,10,B4,56,C8,74,84,AA,FA,2C,7E,C4,EC,E0,90,53,86,D4,89,FB,9E,E8,29,C8,7C,C4,FF,68,24,84,F1,1E,2F,8E,C9,55,F9,1D,28,F3,99,C6,52,93,B3,4F,09,A7,93,7F,AE,27,70,F6,35,64,72,B6,EE,C9,D6,F2,79,85,E2,7F,08,D9,7A,C5,C4,32,16,6F,C1,7D,D9,2F,22,99,60,EF,DF,DE,09,0A,4B,92,BA,40,59,A5,E5,21,8F,B4,7D,9E,B5,4F,8A,98,D9,CF,F5,F0,8E,9B,72,60,B4,56,E2,2B,69,41,DE,6E,EC,3E,96,C9,7D,B9,C1,9E,57,AF,E5,36,73,DE,87,CB,46,D4,4F,95,64,24,19,ED,B9,AC,39,0F,23,0A,E8,95,D7,1A,F7,26,EA,00,F6,F8,B8,91,D5,EB,D1,26,D6,E9,22,01,DD,1D,EB,92,BB,21,E7,E9,03,FD,10,0D,1D,44,DD,2E,E0,D3,84,F8,20,96,19,71,25,A5,5E,73,88,B0,B2,1C,1C,FA,4E,88,1B,E6,07,11,38,4C,41,A9,6F,E8,4A,02,F8,51,4B,BC,FB,67,31,33,0B,C7,54,69,E6,3C,A1,45,E4,D7,F2,D1,AD,58,D0,9A,9E,9F,3C,8B,7A,91,28,3A,77,8A,FE,5F,1F,27,AB,FE,91,8C,01,0A,14,E0,4F,BF,ED,3D,89,9B,67,45,B6,3C,32,1F,BE,3A,2E,A4,45,00,7E,71,39,D8,30,0C,D4,DC,88,A3,F2,F8,A6,DD,1D,87,39,4D,21,9A,E7,EB,C0,79,36,B0,C0,8A,81,FD,37,D6,52,91,AD,E2,CC,F6,95,84,52,90,06,9F,25,DD,31,B8,B2,69,57,83,98,C0,40,8C,F7,AF,F2,0D,0A,03,7E,DC,5F,B3,25,E8,BF,55,E9,20,CA,BF,82,44,B0,BE,CC,34,A1,F5,14,29,DB,DE,B9,5A,12,C9,07,A9,56,02,24,14,11,79,23,5A,70,F1,5A,62,2B,B4,C1,C1,5C,AE,E5,14,D7,CC,0D,B1,69,21,6B,F1,41,4C,06,80,08,A3,FE,AC,FE,72,2D,8B,DD,B3,46,80,70,0C,C2,D4,F8,A1,EE,47,60,B0,FC,6C,D0,67,F8,C5,FE,DC,B4,78,01,7D,97,62,AF,7F,B4,DA,4F,C9,1C,FE,A2,C6,7F,E4,AE,9E,8A,04,F0,D3,32,C0,D0,80,7F,10,85,45,3C,BF,27,59,0C,84,58,56,31,6C,13,CC,1A,D1,66,6A,43,BD,4C,71,24,79,B9,46,B1,7A,10,B3,D4,B5,35,92,AC,2E,F1,B0,AE,E6,EF,C3,85,CA,69,11,01,12,FD,0A,4E,44,1F,E4,57,81,96,EE,09,59,D3,61,E9,77,4E,1C,8A,08,02,87,2A,70,4A,5D,4E,88,FC,65,64,AA,FB,A6,2B,10,6C,35,95,86,D2,3B,C9,CC,F1,7F,38,C4,B4,5E,9F,95,09,90,D4,5C,2A,AA,09,3E,8A,71,32,9C,FF,78,A5,C9,73,A4,2A,7A,DE,84,D9,A5,07,C4,72,9D,BC,62,D6,21,09,43,95,54,EB,36,55,FF,ED,36,2D,6F,56,47,99,C8,C5,17,3D,EC,8F,5D,DF,1D,0C,8C,73,F2,D4,86,1A,5D,93,65,FD,2C,0C,80,27,92,39,B4,A5,B2,B3,B5,DA,9F,38,42,CB,45,8B,AB,75,50,09,D4,A5,28,79,6D,63,89,EC,03,76,54,E5,69,05,93,D2,C2,9E,FA,FF,4D,47,68,64,A4,C3,74,17,67,6A,9B,AA,3C,E7,AA,EA,5C,98,84,48,04,0B,C8,BF,1C,EE,19,B3,B0,4C,2C,69,44,65,45,1D,9F,C7,4C,45,F7,61,4C,A5,60,F0,CB,86,EE,FE,71,4B,7A,57,AA,D9,DF,8B,57,5B,87,43,D6,21,92,99,1F,ED,AD,A6,B1,87,5F,95,12,BD,4B,89,CF,0C,3D,A3,07,38,45,FA,3A,BD,C8,91,68,DC,8A,88,8C,CE,03,FB,87,80,45,F5,59,A1,CF,A3,78,E9,18,0C,BD,6A,13,16,62,31,7B,60,80,F6,40,62,C1,73,EB,F6,03,41,CB,3C,2D,E2,3E,2A,D4,18,0C,38,3A,AA,05,46,C2,9A,08,0F,BE,28,15,EA,BA,BB,A4,56,B1,86,C4,0B,8C,CF,4B,90,C2,AD,03,95,4A,14,1B,B6,7E,B2,5E,E3,E5,01,9A,12,98,AB,AC,7A,4E,A9,21,6C,57,5C,60,A4,35,5F,F6,FA,4C,3F,50,7F,B0,31,60,13,5C,0A,D8,65,1F,AF,C2,F5,37,43,68,71,D4,97,E5,5C,42,D3,26,81,77,2B,F8,41,19,0C,F8,8D,96,9E,C4,CA,E7,A8,C0,41,90,36,B5,81,97,29,2F,7F,5C,CA,0D,1C,5C,EA,15,F7,92,45,EE,B7,31,BE,2D,4A,35,57,0D,3F,B5,A5,EA,E5,40,D5,D2,16,DC,F0,BC,CF,9C,28,99,BC,5D,11,CB,95,4F,52,EC,1F,C4,61,CE,F8,77,94,5E,58,23,3B,D7,8F,18,BD,C2,0E,57,F4,C2,F8,B6,EF,C2,79,BE,18,36,6A,CA,89,7E,FD,65,8D,5D,80,D4,90,B2,A2,64,74,B9,B5,7D,8A,2B,38,B6,3B,5B,56,96,96,4C,83,06,C2,64,DC,99,02,9B,75,5E,36,63,93,29,2B,E0,FA,F1,D6,F7,A9,BF,F6,F7,E6,A2,1B,6E,18,78,D2,ED,5B,4F,5D,A3,A9,28,24,BC,4C,50,80,F8,4A,A9,AD,F2,C7,08,FF,92,9F,C6,6F,9F,D3,FA,FB,34,8E,CA,C2,C2,F4,F4,44,66,F4,29,75,E4,87,64,6E,03,72,74,98,42,E9,10,C2,4D,64,A1,58,ED,10,D2,B3,83,AE,4C,EF,4C,C4,DF,8F,48,76,4D,81,ED,79,A0,02,6E,A1,29,64,0D,86,D1,70,B5,0E,84,FC,67,63,14,C7,1E,C3,72,2F,57,97,F3,5B,27,B4,83,11,20,7A,93,2E,A8,FE,62,3E,A5,AF,4C,B2,BE,31,61,40,D3,10,88,2D,B0,5E,F2,4D,4D,A7,3D,5E,E7,F3,8F,53,B2,DF,B0,CF,9C,B8,26,8F,96,24,04,0B,82,46,A4,B9,C0,B2,EA,2D,DF,36,06,91,33,3E,1E,6B,F6,28,5E,7C,15,90,98,15,34,38,CA,63,5E,49,53,F9,EC,7A,20,B0,7A,53,CE,80,E2,1B,A6,0E,F2,3C,54,3F,B6,64,44,58,A0,28,78,B6,13,91,B0,9B,8F,D4,09,F2,42,0D,BC,AC,D1,90,33,F7,97,C5,60,79,A6,F6,5F,BF,A2,E1,A6,5C,DB,BB,D7,CE,9D,D4,99,CC,F0,E3,09,1A,F1,1D,0F,5E,9D,56,EE,80,95,34,24,8D,C5,59,A7,D2,A5,BC,B1,82,D3,AD,6A,78,96,25,A6,ED,CA,9F,76,40,D5,FB,A9,67,EF,F8,C2,D7,78,04,84,FA,52,BA,D3,32,90,4C,57,D7,22,C0,24,03,91,6F,A4,55,21,54,7E,6E,CF,54,CF,9B,DB,7A,06,76,EB,D9,60,F5,42,EC,7B,15,A9,95,25,A1,EF,FD,6E,1D,50,7A,20,B5,E6,F7,04,D9,DD,3E,8C,E6,32,BC,28,F9,32,98,22,A0,8A,D5,43,71,1B,D4,26,96,54,D7,D3,DA,70,D5,C0,2B,7E,70,C1,16,18,C7,60,77,76,84,08,BE,3C,87,70,58,4D,3C,2C,C0,D8,0F,D9,03,B6,E8,DE,33,6A,D0,80,B6,83,31,A1,D2,51,F9,09,55,6E,F2,EB,49,CC,55,C0,57,46,7D,49,9F,24,C9,A2,EB,CB,B4,01,31,EF,9B,81,E6,A3,DD,30,B2,46,50,2D,80,62,71,B3,28,DA,E2,F4,A7,CA,DC,8B,BC,38,87,21,1A,66,EA,40,3C,EB,AC,55,8B,35,C0,92,21,34,2A,10,6C,53,38,38,E3,D1,04,C8,09,E0,84,1D,97,7B,BD,98,EA,EC,E3,F7,D0,D2,C2,5D,C7,DB,F4,CB,66,42,BC,4E,EB,69,51,C0,EA,CE,8F,48,29,F3,6E,E6,9C,EA,7F,4C,17,90,A7,CB,2A,DB,C3,A6,10,41,19,23,0C,B9,06,D2,97,49,EB,B4,F9,4D,EA,24,73,60,7E,80,8C,50,70,78,F5,FC,3A,31,60,85,F8,84,17,28,E3,05,51,E1,89,20,08,68,59,24,F8,3D,C4,18,68,AC,00,2A,E5,08,FE,B9,D0,AC,10,52,A0,91,1A,61,B4,1C,EF,CE,07,61,C3,82,57,C0,84,1D,7E,3E,80,5A,E3,C4,F5,6E,A0,3F,9E,1E,FA,F5,12,B4,24,F4,63,1B,75,10,0C,DE,BE,80,BB,38,A5,5A,B6,70,F5,35,3C,7E,1B,D8,B1,46,C8,4E,0E,AF,5A,CB,78,1C,E0,9D,63,A5,DA,CE,BF,72,9A,87,E7,36,3A,84,13,55,1F,14,A5,2A,99,A9,0E,07,96,CA,6A,13,A0,F4,80,59,01,44,5A,CD,E5,1E,31,06,91,94,1D,51,C2,2E,8C,7C,F8,DF,50,9C,7D,D0,E6,9D,59,C9,AE,7B,FF,0D,D7,A0,FA,A8,1E,A6,8C,5D,05,5E,62,BB,FA,FF,3A,2D,49,CE,95,1F,F0,42,B7,41,F0,5A,47,82,D5,B6,65,39,7F,77,5A,12,43,90,16,96,5C,28,A0,37,26,80,B0,30,94,6C,3F,1D,78,5A,73,FF,5D,56,C2,B0,DC,32,78,3F,5F,EA,60,5F,12,7C,D0,B5,58,6F,07,72,CD,F8,AB,FA,88,B3,DC,23,AA,8E,6F,13,5C,2D,B1,2B,5A,5B,BD,7E,72,D7,30,5A,B3,71,C1,8A,42,F6,CD,BB,E5,8D,8B,E7,63,7E,39,C4,B9,26,A4,52,5F,78,6B,4D,DD,8A,54,FD,41,95,90,6B,53,30,92,1E,00,1A,6B,4F,FB,A2,94,8D,25,58,76,5F,71,2C,C9,15,2E,AC,D9,15,00,11,18,D2,0B,11,64,5B,60,8C,FC,7E,82,7F,0B,C8,64,45,F4,59,E0,A7,0A,58,5A,32,12,CD,DD,77,79,DF,FA,8A,D5,32,56,C9,EF,A1,14,C8,0F,F8,DC,A1,CC,35,0A,8D,BD,7C,4E,13,CF,3B,85,F0,30,B9,43,B9,FF,31,B6,17,59,BA,35,5D,50,DB,FB,F0,00,82,D2,31,17,59,CB,AD,8C,17,A9,55,EE,F2,BF,D8,85,F8,82,D1,27,43,EE,E3,5D,EC,F2,00,6E,31,30,85,F2,50,52,33,3A,3C,46,F4,80,F9,47,7C,CD,DD,F2,68,5D,EC,49,71,B3,90,B2,85,89,74,62,5E,52,9F,45,24,7D,FF,C1,81,A2,72,70,EA,EE,88,91,0A,E4,B1,8C,4A,96,EB,41,7B,5E,3E,4B,87,6A,36,8F,41,AC,3B,28,E5,71,EA,41,75,5E,9C,F8,DD,3D,A3,B0,58,70,A6,4C,F4,AD,1E,C7,4D,98,74,4A,3F,04,F5,FB,CF,C7,E0,43,77,3B,5E,CD,5B,75,4D,A7,2E,F3,F7,4C,9F,B0,8D,26,CE,EE,1D,7D,66,24,78,71,5E,B9,B2,7B,DA,B0,F8,0B,87,63,B0,34,EE,CD,27,B4,D3,8E,26,5D,C3,43,02,55,7C,65,B2,49,B1,4A,A7,44,0A,4C,D0,AF,4A,12,7B,A2,CC,55,D0,FA,43,4D,85,2A,0F,23,CA,30,5C,C4,5C,9E,E0,34,58,37,22,E2,D2,91,66,D8,C8,04,FF,02,98,84,8B,13,D3,79,6E,A2,2E,75,45,B2,DF,A4,9B,F1,7F,CF,BE,07,9A,C3,37,F3,C9,AB,78,87,83,F6,97,32,C6,4F,E7,78,9E,64,EE,23,1D,29,89,E5,91,8A,E0,30,1D,7E,98,A8,EE,44,D7,32,F6,C7,22,CF,1D,C9,A0,6B,25,16,C5,5C,8F,78,E4,D8,FC,24,F0,1F,83,61,AA,BD,72,AE,82,64,E2,CD,4A,C3,A1,E8,25,6F,81,7E,D2,31,75,D5,A2,52,E8,F2,80,75,E2,04,38,88,7F,42,21,D0,0E,9D,B6,33,1B,D3,71,EE,EA,B1,C1,FB,FB,01,C7,75,D2,7C,60,14,7B,49,40,94,F6,0D,F2,0B,93,C0,03,28,CC,91,A0,57,5A,96,2E,B8,59,61,BC,D5,92,E7,51,79,48,C7,13,C2,7E,45,FF,3F,AD,20,FD,8C,26,6F,8E,F7,A0,1B,B4,54,DE,6C,47,7E,44,D7,36,BB,0C,21,41,1E,12,EB,B0,B2,2F,47,37,AE,93,57,5B,40,97,17,3E,92,21,0B,CA,17,19,EA,93,FF,E2,64,00,3B,76,1C,2C,7D,86,EE,99,3A,80,E2,18,E6,02,53,03,6D,9D,41,18,DC,63,4A,58,A6,AE,CB,F6,DE,AF,E2,1B,71,2C,F2,4A,9C,BD,C7,84,1B,72,2B,F8,DA,59,F4,F9,C3,18,5B,6B,32,84,01,24,0F,D8,60,71,D5,C9,72,F6,B2,8D,39,13,D2,C1,3F,85,1D,9B,EA,B4,EB,2A,71,FB,72,77,4D,7E,E3,2C,3E,4E,05,15,50,D7,CE,37,31,DE,74,19,8B,48,48,F5,8C,7B,F7,F0,19,4E,4D,64,BD,77,FC,5F,93,E5,52,F5,56,EA,7A,19,F7,0A,3A,06,9A,E4,F7,28,81,E2,1C,E6,A3,D2,F1,EC,65,19,A8,78,D0,E7,E0,30,FA,E8,87,76,24,94,4D,51,32,69,6B,D6,2D,E3,04,4E,A2,F5,63,08,53,C5,4B,11,7E,1A,4C,36,8D,CE,A2,C7,ED,91,C0,5B,AD,C6,1B,20,88,3E,38,A4,E2,6C,88,8D,85,6D,8D,1B,1C,85,44,DB,58,46,44,5C,40,30,8B,D3,24,0B,D8,96,DD,DE,FE,B1,82,39,AB,04,F2,9A,53,8B,44,0B,D7,69,39,A6,B8,4F,CC,00,AC,D8,08,3E,4A,7E,C0,66,27,BB,0E,02,72,32,90,C5,20,33,6C,45,59,D6,63,8F,12,67,A9,67,AC,A5,2F,1F,33,84,8A,A2,3C,70,08,49,42,7B,96,2E,DD,59,45,26,02,F8,1A,78,7B,25,F1,AC,10,AB,D9,05,F0,7C,47,E3,99,62,17,66,A1,E1,A6,29,24,3D,3E,92,20,5C,D5,24,BE,A3,0C,13,20,5C,7F,3E,C1,90,20,D3,B0,40,F7,EF,D2,4F,A8,2D,AE,C9,F2,45,E9,D2,E7,0A,06,88,38,33,85,37,02,00,D5,97,53,25,4D,6F,BA,E5,B2,CD,8D,1B,BA,2B,1A,98,30,A1,AA,F7,C3,28,15,9C,A1,BE,C4,ED,5C,67,E7,61,2D,F7,53,B4,F3,7A,DB,2F,2A,17,8E,F1,AC,B0,E0,02,0F,35,DB,A5,57,D9,89,36,E5,6F,18,08,A6,14,37,0F,58,13,40,72,E3,DA,30,B8,60,43,5E,38,4C,1E,91,CF,1F,AF,AF,CF,37,EF,12,0C,CB,55,F4,C9,54,21,C1,11,7A,ED,87,9A,A6,81,5B,13,AE,83,4B,86,31,E6,C8,71,0D,81,CE,A7,5C,B2,64,48,8C,A7,04,13,9C,41,1E,34,0F,C4,9C,C1,BC,49,F0,74,8D,DD,7C,12,04,BF,9F,BA,4F,CE,01,DC,97,23,A4,9A,FC,CA,D9,88,09,6B,8D,A0,B9,91,98,26,23,6B,B3,5A,9D,0D,B3,6B,6B,88,99,3C,4C,27,2E,0B,A6,B8,9F,3A,FF,6F,6D,0A,57,F5,7A,EC,F9,06,95,E5,C0,B0,4D,96,CF,91,8A,98,93,A2,F8,99,F0,70,94,93,BE,10,6B,9C,5A,6C,70,B7,86,E3,AE,0F,74,FB,8A,1A,B7,40,EE,DB,E5,37,72,B8,27,6D,C3,29,8C,70,56,A0,FD,D8,5F,08,28,C7,65,83,A2,1A,73,CE,E2,40,1E,29,58,A2,E1,02,78,B2,2E,86,45,8F,A8,69,24,02,5E,92,B0,5F,CF,12,07,00,63,CE,05,9B,72,FC,BE,33,4A,C1,1E,CD,E7,0D,25,A3,6B,F0,E3,47,93,1F,C1,15,29,3E,4E,DD,F6,CC,9E,C2,3F,AC,BE,9C,F8,DA,BC,74,A2,21,9E,32,53,FE,08,AB,AF,71,1B,8A,13,84,A0,04,E1,9E,49,28,BB,8A,2A,01,46,36,CD,10,46,5E,66,C2,BF,D4,F8,AD,EE,59,FE,E9,09,D7,CB,E8,52,AE,46,65,9D,69,E6,16,94,08,C8,30,E6,C2,D1,F2,CA,24,92,7C,F3,74,8E,D9,DB,82,45,7A,2E,7F,BC,10,6B,15,4F,45,98,9B,8C,CE,3B,2E,26,A8,85,35,FF,CF,68,BB,CD,EF,E4,A5,7B,E1,C2,F7,9F,3E,E7,2C,F6,F0,58,C7,F3,C4,9F,8C,7D,4F,64,0E,2E,FD,9A,19,EC,8E,60,7E,BA,83,A1,A8,75,BD,BC,E0,E5,90,CB,4C,EE,08,D7,C0,38,B5,1E,B2,B0,6E,33,A0,00,8A,88,E6,40,32,DC,61,50,CB,8B,16,53,1D,39,E3,77,1E,1D,65,00,12,56,40,FA,E3,95,B8,CD,69,B3,2E,26,D8,C6,3B,0D,DC,9C,7A,B3,8B,CA,61,97,FF,42,C8,41,D7,81,EF,B2,75,EE,71,2E,49,EA,B1,AE,3A,50,20,72,20,E1,D3,20,9B,3F,D0,8A,AF,11,3F,2B,BB,C8,5C,12,1B,6B,B3,13,6A,DB,BB,77,C3,74,41,28,CC,A5,88,4A,7E,14,36,A2,5D,A1,48,48,DF,5D,E6,43,B7,82,99,73,37,97,25,6E,01,77,86,CC,AF,28,87,9F,46,F1,3A,EE,FA,20,5C,05,4D,9A,BF,7D,82,FF,BE,CA,38,3A,47,A4,EF,27,4C,63,28,58,C2,EE,CA,60,11,79,63,41,BC,76,B5,A5,7A,AB,91,9F,80,89,41,09,CC,78,83,C0,FF,61,F0,D4,7F,CA,03,04,87,B3,DD,DD,B0,8C,2A,A8,68,47,83,E4,26,C1,DB,94,92,5C,F5,84,D0,08,62,AB,EF,F1,EF,72,29,16,C8,97,30,22,08,82,AD,D8,A2,1A,C0,5B,9C,53,D9,71,D3,B0,6C,43,71,75,C4,D1,10,4C,2B,6A,1F,AC,C9,3E,91,45,BD,0E,1F,66,29,C2,DC,D5,A4,8A,BE,2F,F1,D0,A3,23,EB,55,24,51,E7,18,E5,D1,25,39,D4,A3,76,B6,E8,5C,18,09,AC,6E,7A,0A,1A,06,66,A8,F6,4B,FE,B9,48,AB,63,8E,B3,1B,2E,F3,A5,1A,C7,27,E7,2E,41,51,F8,F0,17,9D,70,84,BA,61,1C,51,A8,A3,80,F3,E4,54,27,30,27,02,78,99,7C,B0,6D,2C,AF,E1,8E,A2,2C,C6,AC,88,0B,E2,35,4D,22,89,8C,B0,72,26,E2,28,A3,88,42,3C,76,28,91,0D,CE,4D,1A,82,F0,22,EC,A3,90,FC,63,31,DD,A4,8A,29,CA,7A,46,53,28,C0,78,17,B3,F5,9A,65,5F,1D,00,27,FB,89,1C,2D,1C,AC,12,67,1F,BE,95,D6,9D,77,38,09,03,EC,4E,AF,0A,1C,53,68,D2,DE,1E,59,6A,86,F6,09,63,07,FB,BF,09,86,51,1F,F7,C2,74,22,F0,FC,12,33,79,AD,D0,A0,54,8B,15,CD,0F,38,2D,0F,E1,43,B5,70,2E,C5,47,9D,33,96,38,8E,65,2C,68,23,07,DC,F3,6A,11,1D,80,54,22,0C,6C,0B,4A,89,C8,BE,B6,47,76,11,B0,7B,1F,DF,8E,E2,A3,B8,F2,9C,FC,AE,58,25,EC,B9,98,E5,5E,27,66,98,0A,DE,65,EC,D5,9D,CB,E4,3E,86,3F,C3,10,ED,08,F1,5E,89,DD,C1,C3,98,51,3A,70,ED,09,A1,FB,AE,F0,27,23,D3,24,A6,CF,74,B7,F3,76,70,7C,D3,35,B0,DF,EF,63,40,E6,16,92,A4,F4,E4,95,6A,22,EE,BE,5C,92,09,52,1C,92,C6,A5,F6,39,A1,F4,2F,32,E8,AD,43,1D,BF,19,74,2F,AA,A2,50,53,4D,25,E8,39,E8,6E,7C,82,C4,67,FA,91,44,61,8E,9D,AB,8F,BC,19,68,45,51,4E,7E,B4,B4,AB,5D,C7,93,58,3D,6E,90,97,15,06,54,5A,E6,03,4B,FC,CD,F6,23,2A,2D,CC,E6,7B,4D,8F,15,45,A7,B9,2F,8A,A4,DC,42,F4,53,FE,00,E2,28,79,5A,0E,9E,48,D4,AC,49,0A,EF,3B,2D,A2,2A,1C,F6,C2,8A,16,9A,31,81,8F,2B,96,38,BA,BD,48,03,B5,77,5D,16,F8,46,B1,1D,F7,6C,51,82,78,EE,47,7E,E1,CF,10,E6,F3,96,72,69,0E,12,41,A9,2A,DD,2E,D2,54,61,40,AA,BA,15,86,67,03,A0,2E,20,3B,DF,E6,98,01,A8,46,4E,A1,6C,1C,8B,28,B2,32,2F,E3,A3,75,50,B2,21,59,13,AE,00,2D,BA,F5,D7,D7,6F,4F,79,FF,09,C5,FF,64,C4,A6,36,A4,12,19,D1,F3,E0,A4,54,D9,42,C7,DF,52,DD,78,87,BF,13,1C,44,3B,E5,2D,85,EC,61,9E,75,39,5B,DC,6A,A5,11,0E,7B,BB,1C,16,B1,E0,F1,2E,0A,48,C4,8A,ED,FB,9B,2E,3E,49,38,C8,12,1B,5C,77,F3,94,77,68,93,BE,35,90,FB,43,48,97,54,F9,8C,06,13,3F,34,BA,8F,A9,76,71,74,76,AD,D7,31,F2,67,4C,65,AA,46,2A,17,DA,7A,01,70,B5,5D,F4,0A,7B,47,CB,91,E8,82,A0,8F,C4,3E,1E,7F,7D,E8,11,98,0B,B2,87,62,8B,30,88,79,E0,CD,CD,34,7C,1C,FF,EF,CD,DD,C4,2C,84,4A,78,A7,34,F5,6E,CE,9C,FF,EB,6D,0D,06,4C,7E,EE,D6,66,74,2C,AB,B2,4D,19,3D,A0,EC,0A,2F,FA,98,BB,55,5A,DB,75,5D,F9,0B,6D,07,18,9E,55,2A,C7,19,1E,E8,13,5C,0D,1C,B6,41,95,6C,27,99,63,37,78,E7,DB,86,A8,7C,CD,21,38,67,7B,BA,8E,8F,C3,EC,6C,6B,7D,1D,07,63,BD,75,3E,DB,3D,10,D8,80,58,6A,82,BE,78,7D,E2,A1,E1,07,8F,74,3F,B8,79,4F,FD,E1,FD,F4,29,0F,19,B1,1C,8D,F7,33,DD,44,E4,2A,D2,78,81,5C,5E,0F,4A,4F,43,ED,5C,EB,DC,90,5F,47,69,3E,88,3F,4F,EE,B3,A7,D4,8A,9F,41,36,96,87,88,7F,7B,FD,DF,93,A0,64,26,4D,17,C6,2B,07,81,98,E5,8B,95,28,98,D6,6D,89,ED,1F,FB,57,C1,9F,71,A3,8B,30,AB,95,66,65,23,4E,3C,8D,63,4C,D6,87,E5,60,7E,1E,ED,AC,6A,69,12,16,E5,5D,0C,78,13,B4,8B,31,3A,BE,C2,0A,D9,43,46,6E,98,84,F4,5A,47,C2,2E,13,E8,18,E7,B3,3D,D1,B4,4E,03,F0,23,DD,5E,0C,CA,DF,51,72,F6,73,9F,5F,1F,78,E8,4B,DA,08,48,7C,C2,7E,D3,DE,E8,D7,90,35,30,63,9A,2A,9B,82,A5,62,B1,45,AB,8C,EC,FB,E8,8D,A3,EE,0E,CC,21,36,DE,DC,A9,47,0F,16,CE,88,D2,CB,D4,86,B3,4B,C0,BE,D9,68,8E,5B,A5,45,A7,91,17,2D,62,A6,91,AE,43,9D,0E,59,A2,C7,CC,79,4B,A8,2F,1B,0A,2A,D7,F7,0B,28,C4,59,E6,05,65,1D,AD,BF,DD,88,26,AA,9D,8C,39,95,3A,84,FF,B3,BC,0D,E0,2D,25,B1,80,ED,C5,12,7A,04,2A,FF,9C,1F,58,95,FE,57,58,2B,40,00,38,FA,DF,1D,4C,F8,04,38,6B,18,00,C6,54,2B,36,F7,E2,8E,18,FF,B5,51,6D,55,F3,C3,88,9B,5B,22,2B,B0,0E,FB,C8,31,1F,6A,1E,63,29,32,4C,25,0C,41,CB,A7,56,70,EC,9D,BD,41,D4,26,3E,B3,59,82,EF,CE,A5,40,81,23,6A,C7,9A,D4,ED,0C,22,25,F9,EB,FB,95,70,87,C9,44,6D,23,A1,B0,C9,23,C1,69,3B,98,13,3F,66,9A,80,0D,51,6D,69,83,C5,86,8F,F7,92,61,4F,2F,36,5F,1F,A9,F0,AD,A8,EC,B8,BA,77,07,DC,05,BD,15,70,10,C1,48,14,03,D6,00,FD,4B,63,20,30,E3,F2,71,88,F0,78,A8,A6,6D,42,7E,AC,06,E2,C8,BF,6C,FB,D3,83,46,A6,09,86,42,80,6F,BF,9A,A3,44,72,F7,91,56,D4,F3,6A,1D,26,D2,C7,CF,BE,7C,96,95,65,FD,FE,1F,93,12,CB,38,B8,38,8B,E8,BC,3F,2B,04,98,E5,91,74,6D,80,0F,3C,BC,10,C8,09,A8,26,5C,0E,5C,4D,B4,C7,43,CA,C3,10,CC,9B,99,BE,B1,8C,5F,DC,A6,4C,C4,56,75,2B,FF,3C,8D,67,64,CA,D3,D3,34,13,22,B4,2B,62,BA,4A,38,82,4D,E3,EC,AE,29,3E,03,7A,E8,F7,73,CC,CD,8F,AE,7C,77,83,72,4D,A0,CA,35,18,86,85,8C,35,D8,0C,C8,F3,01,CB,26,5B,2E,2D,C4,37,74,41,6F,53,37,21,43,87,38,4E,40,C8,17,AF,30,94,AD,50,74,4E,0C,54,3B,71,EC,0B,7E,D6,6D,D2,0D,78,25,2F,CF,0A,6F,52,83,93,1F,F6,31,E6,7E,AD,2B,22,88,B7,48,A3,4C,1C,D4,26,28,6F,00,8C,23,2A,06,D4,9B,51,14,E8,A0,43,EC,18,20,67,86,AE,56,17,C6,EE,EF,60,17,2E,D6,A2,DE,24,C9,ED,56,0E,E3,AD,DD,99,2A,DD,41,3C,64,35,EA,B0,0F,D2,73,06,31,9B,05,51,09,9D,FA,85,D9,DC,CF,A9,83,F8,E6,4D,D3,E7,04,82,FA,42,CB,FD,FE,6E,C8,FE,F3,4A,5B,C0,18,DD,ED,71,0A,F7,E9,88,52,86,80,D8,6C,08,64,D4,E9,98,41,9D,41,F9,DD,7D,2C,4F,34,FE,2D,34,DB,47,EB,5A,C9,BB,3A,C3,9C,C0,BF,2C,EB,31,EB,53,CE,BD,A8,80,73,F4,46,7D,F6,CC,32,60,35,DB,78,7F,F2,E9,72,80,84,AD,D3,CD,4F,1F,C4,BC,EB,0D,AE,72,28,7B,65,31,F4,41,C8,14,E4,CB,80,C8,7A,0E,C7,63,9A,8B,B2,AC,01,EE,33,AA,2B,65,37,E6,1A,E3,D6,EC,A4,06,09,6B,1A,5E,B9,5B,FC,4A,89,9C,F5,30,91,AC,36,DA,52,93,F7,2F,10,B8,24,0D,18,32,CA,38,61,2F,8A,9F,AB,EA,8E,F0,BF,5C,A6,21,D3,5B,42,3E,70,F8,1B,A5,41,F7,F8,7F,A5,B8,F3,F3,FB,4A,7B,BA,B4,6E,99,1C,C5,9C,78,14,7F,C0,6D,31,E2,72,AF,EC,C9,C2,69,1A,3E,37,E3,0B,48,95,61,8E,A6,AA,21,53,DA,2A,62,88,A6,5F,1D,ED,D2,7B,2A,0C,66,EF,63,AC,CA,4B,82,55,2C,D2,03,92,F3,33,29,E7,B7,C0,AD,87,8E,02,71,72,9F,0A,C0,33,22,8D,F7,33,E9,2F,22,12,CA,88,F4,55,CA,A1,06,45,D7,E6,98,FD,EA,3C,2E,D2,1F,EA,36,92,FD,3B,DD,A5,96,B9,46,57,29,DE,5A,F3,6B,E1,99,8C,F6,49,50,42,C4,71,32,D1,8F,06,69,15,B3,54,C6,16,23,F4,D0,9D,FF,6D,7D,85,64,C4,63,2A,00,6F,DD,14,C5,65,80,F8,79,D4,74,90,D7,FC,FA,0F,3D,89,C4,E9,82,5C,BA,56,22,C1,50,60,12,A5,DC,08,6C,FD,64,E8,24,7F,A4,D7,3A,A6,F1,AB,4A,DC,0B,9A,96,5A,55,74,A6,D5,0C,8F,CD,24,5C,A6,CC,66,5B,07,18,BA,62,B2,8A,E2,58,1B,22,65,75,59,CF,16,31,1D,67,68,47,B1,9C,76,86,15,F3,E5,4D,5D,CD,6D,F2,B1,F7,E3,77,13,06,F2,E5,59,2F,C8,24,75,2F,FE,4D,E8,FD,21,A5,DB,68,04,33,08,B3,8E,87,54,DE,71,8D,3F,C3,AB,2B,68,86,54,55,5F,AF,F6,A9,4E,3B,EE,B3,8A,95,E6,35,FE,79,9B,AF,4F,EF,75,A5,A1,19,84,42,64,37,EF,12,ED,35,0C,9C,41,8E,A2,26,D3,79,CE,CD,96,3F,75,3B,05,27,0A,7C,9A,68,B1,28,87,8F,75,59,82,ED,E2,4F,95,FA,CE,36,2E,01,C7,A1,97,24,D6,AB,2B,34,75,58,29,48,21,49,EF,ED,85,98,2B,B5,FD,F2,FF,D7,C2,05,AC,83,29,65,73,65,B7,DB,D2,94,A4,25,97,2C,0D,8B,58,43,7A,3C,50,9B,FC,ED,BD,21,FF,F7,E3,C0,FC,CB,A8,D7,63,73,46,95,20,07,6A,27,3E,B5,82,E2,C9,15,6F,1C,F4,59,63,64,5B,C7,BB,0C,2B,DF,9F,E5,E3,66,35,6C,54,2D,41,83,D3,93,84,47,3A,02,21,C5,40,CB,1C,75,39,44,71,17,DF,9B,87,20,81,18,EA,71,75,8C,C9,64,C4,DA,01,AE,93,14,B4,DF,B2,61,14,5D,71,F7,8E,53,5A,B3,0F,48,2D,12,13,5B,9C,6A,FE,69,42,09,E3,2F,C9,CA,28,59,4E,F9,85,D5,16,6A,15,27,7C,0E,A5,0D,D1,68,99,B4,D9,04,B4,E3,3E,24,80,4B,3B,E3,79,59,8A,3B,23,82,EB,E9,2C,27,70,8D,C7,E1,94,01,5D,44,D6,96,CD,AB,48,3F,4F,74,AB,04,FD,3E,C8,B9,00,6D,7D,4B,32,44,9D,CE,29,7C,06,34,08,28,7F,BE,AD,16,82,35,AB,02,6A,F2,7B,9F,B3,ED,16,B5,09,F6,15,DE,D0,5D,BE,88,74,36,19,54,7E,E5,42,6B,28,26,6D,35,E9,E4,9E,96,0B,15,0D,3E,A8,16,10,64,F2,D9,63,87,29,00,81,DC,71,32,8C,44,0E,FB,8A,4E,96,16,F2,78,1B,4D,8A,78,8E,EC,FA,4B,40,40,D3,0B,A7,FD,2D,0F,8A,B9,A9,A8,7E,F9,FB,1B,C2,9C,D3,98,8B,F0,A7,DC,BF,B4,29,37,D0,56,28,F7,68,13,B8,A3,A8,A1,DE,A2,88,83,32,F2,1C,DA,FF,96,2E,A3,DF,CE,81,8B,66,F3,A3,4A,36,99,79,51,F0,CD,5F,F8,17,91,2D,03,7D,42,8D,EA,4B,CD,42,E5,86,05,74,68,9A,51,6F,2F,4C,5D,1D,EA,D8,75,FA,7F,7A,0F,5D,15,72,E6,BC,16,A3,17,14,7E,42,E2,A1,8D,8B,05,B0,14,0C,04,E7,F8,75,62,49,6F,00,EC,E0,47,5E,33,50,FE,07,5D,71,23,C2,0C,2C,F9,E8,CC,07,87,3D,53,52,91,DE,D3,EA,24,75,AD,E0,30,EA,7C,A9,D5,AB,DE,E9,F7,35,48,0C,E5,CC,12,94,BF,41,6D,5F,CF,E4,61,84,07,7E,E3,F4,61,FC,39,15,6D,1A,1B,A7,CB,80,62,D0,30,4B,45,62,7B,37,CC,F5,D1,64,53,BB,C7,66,AC,F8,7B,1B,2E,0D,A1,A7,D6,EA,2E,A6,81,29,4C,7A,EA,6D,0A,04,3C,16,B4,18,95,D4,55,2D,00,7B,22,B0,F5,5C,B5,90,0E,2B,45,4B,04,04,69,9F,CF,80,6E,92,69,7E,4F,66,4A,B7,E3,61,97,07,5D,41,98,59,C5,0C,4F,B8,F1,93,33,FA,18,68,B1,85,91,2A,3C,15,EB,83,7B,D3,23,F5,EE,EB,C2,ED,38,28,4D,69,DC,09,4C,8E,ED,6E,49,C7,73,34,04,98,FD,F4,FE,8C,F5,A6,4A,20,FF,95,7B,CB,B3,C6,A7,62,6D,C7,0C,CD,12,3C,AD,7F,DF,6C,97,7F,B5,F6,0F,37,AC,C7,C8,D7,75,9D,DA,5B,0E,3B,23,08,09,D5,FC,3F,48,ED,B7,B6,6A,3E,AF,D8,0E,E6,B0,2D,02,3F,BB,5F,4C,62,BD,17,08,63,8B,3C,05,0D,EF,AB,2D,0A,11,9F,5D,49,78,B8,89,88,1A,46,40,12,C4,BE,2A,3F,71,A9,88,62,91,4B,19,DE,64,AC,60,F9,0B,0F,E6,53,21,53,33,92,45,63,B9,C6,CA,9A,06,56,62,6D,3D,76,91,8C,DA,7A,32,81,AF,DD,A1,46,71,04,10,42,FB,78,DC,0D,96,EE,80,F6,04,0E,1A,B6,8A,52,62,B1,04,19,E6,D7,E4,22,C0,C3,C9,BE,8F,CB,AC,6E,43,9E,8B,BE,36,90,74,71,49,47,77,3B,82,D2,95,34,AE,AA,4D,EF,6B,A1,0B,F2,DC,5B,86,54,D3,F4,0D,5F,53,EF,24,70,AC,1D,07,07,F0,65,30,A5,CE,07,EB,8E,BA,79,3C,63,2B,85,50,B9,AD,CB,CC,F3,6F,11,33,8D,01,50,A7,7C,FA,8C,08,14,74,BD,62,43,29,B1,CF,DC,83,A9,30,12,9D,62,BC,B5,E2,E1,D2,09,0D,9B,52,63,55,98,BB,5F,5A,5F,17,EE,CB,56,3C,91,71,DF,37,82,DD,BB,59,76,FF,36,59,5D,0B,1B,6F,95,0A,B1,E8,16,98,05,45,58,A2,AF,1C,5B,04,D3,BE,21,55,F9,EC,72,B9,D4,04,45,62,4A,EE,46,2D,7C,B2,80,03,6C,C7,54,B5,55,B8,19,1C,E4,F7,D1,22,DD,70,6E,17,82,27,8A,B7,20,98,27,A1,15,03,FB,60,F4,E2,E1,FC,E6,B9,6D,02,DD,80,4E,28,55,5B,B9,10,0C,4B,9C,4B,94,AD,38,2C,4E,1C,2A,02,42,53,B4,95,2D,80,5A,73,18,46,A7,30,9B,A1,4A,09,16,31,E3,61,09,32,CD,17,70,81,74,D8,BA,1A,DB,28,0D,A7,8A,1C,62,D0,2F,6A,28,F7,0C,B0,3C,ED,70,59,1F,E2,77,45,92,2F,97,E4,D1,DA,82,37,9C,42,F5,10,D4,3E,64,A1,F0,BF,76,D6,46,65,EB,17,DF,44,A9,08,88,93,40,76,C6,7C,C2,C6,57,A8,58,4A,F7,D7,53,09,FC,22,57,9B,3D,C8,62,7F,10,26,11,33,41,C0,42,28,1D,15,FA,61,94,9B,CC,59,7F,FF,D6,2C,24,11,35,A8,19,54,73,3E,01,0B,B0,9C,D9,4D,21,7A,11,31,B2,6D,B4,5E,55,7C,5F,82,EA,63,6C,CE,78,3C,60,BC,C8,91,8F,C7,59,A5,A3,33,41,86,CF,6E,90,3F,F6,62,ED,23,13,82,71,07,0A,3D,AC,BB,DF,CA,92,7F,A2,61,CE,49,06,60,97,4E,EF,84,85,40,45,DE,3F,3D,73,F5,49,D4,A2,01,92,85,09,8E,78,01,C6,E4,F8,D3,9A,3F,C8,40,B7,14,E8,3F,B6,76,82,BB,FE,0B,78,9B,1D,7E,E3,58,8E,3F,F2,DD,7D,53,D4,22,F9,20,F8,CB,02,DB,11,67,31,69,47,58,BF,ED,EB,69,0B,39,10,B4,79,A0,B7,35,9F,06,5E,1F,07,DE,12,97,79,B1,B8,BF,8C,F9,E7,53,3E,7B,41,AE,62,1C,2C,C9,C6,6A,7C,80,07,50,76,C2,27,81,FF,22,8D,1C,A5,4B,A8,5C,30,EE,EA,47,88,CB,A2,65,32,4C,8C,F0,33,19,2D,4D,F2,6C,FC,37,74,5D,BD,8A,9C,0A,77,EC,54,B5,9C,0B,08,1E,68,0D,72,39,CB,2B,3D,A5,C9,18,70,4F,AD,CF,58,CA,D1,86,56,B2,E0,E7,82,52,78,5B,6B,51,66,DB,2C,37,F7,E3,F8,EF,9D,F6,1F,A8,53,2D,4D,AB,EB,76,B7,36,99,7D,67,3E,C8,C8,76,0D,C9,19,B2,E4,7A,D4,16,7F,8C,4F,31,E5,53,68,B3,D8,70,87,FE,B6,1F,3D,0A,1E,C0,E8,4C,15,21,C2,8B,1C,9A,AC,A0,4D,14,D9,C6,F7,6E,71,C0,3A,D1,C0,96,6E,E1,1C,7E,D9,9B,1C,FE,A7,95,C2,7A,5E,77,37,7F,7F,FC,D0,37,0E,A4,43,26,85,B0,CF,25,03,44,1B,D2,34,FC,B6,8B,D0,9F,03,D5,03,5B,FA,DA,FE,4D,1F,D0,A4,57,74,59,1E,7E,2C,BA,0F,A3,7A,BC,AF,F7,56,F6,32,7E,64,5C,37,E3,6A,FB,BF,79,0E,3C,52,4B,B0,19,15,E4,4C,AA,DD,93,30,FC,C4,63,B2,26,0A,5E,FB,BB,37,A4,A8,1D,7D,D4,B8,B0,07,D3,6F,56,BB,D7,6F,0E,A7,92,AA,0F,43,B3,CC,F6,AF,6F,3B,64,95,81,3D,40,2D,B8,FC,FD,E7,B0,5B,F0,02,A0,37,A9,BA,89,91,6B,0E,AD,4D,EE,AE,1D,4B,0E,03,CD,9A,59,1D,B9,11,A4,AF,54,61,35,76,AE,15,A4,3B,0B,0B,1C,B5,39,DB,EC,0C,B6,3D,55,EB,2E,3B,E0,B4,C6,91,80,60,FE,A6,C7,4B,42,9D,79,D7,E2,44,C1,B7,30,40,06,B5,1A,29,51,78,DC,62,95,6C,27,8A,5A,C0,53,C4,66,3D,8A,BE,94,1F,D3,7C,FD,AC,BA,72,16,FF,D3,21,AC,07,64,4A,B2,86,4C,E6,0F,60,76,BB,44,72,55,E9,37,4A,9E,D5,F6,C3,82,C7,1F,65,87,CB,81,E3,88,54,98,D3,9F,40,00,03,A8,03,0C,27,85,2D,E8,82,0E,49,8A,A2,3D,1A,B7,EB,15,90,24,DA,60,D3,FF,BA,5F,0A,8B,2F,F9,94,79,81,1F,13,5D,5E,AC,85,22,02,D2,EB,8D,5B,29,E9,0E,80,BD,1C,FB,5B,9E,B1,7B,B0,E5,49,63,97,0E,0C,F2,21,55,55,00,17,05,45,7A,C5,D3,DE,F0,1A,DA,5E,D6,77,25,18,02,8F,88,7E,95,5D,EC,C3,D8,16,BD,C9,D6,D2,1F,DB,21,6D,D0,FE,06,B7,AB,24,9C,2C,FB,C6,C4,BB,62,28,1E,65,0C,F4,FF,B9,4B,71,AC,26,23,0C,A8,84,B0,CD,D2,80,FC,CF,0A,CF,A6,E7,E7,80,C5,C2,0D,6A,17,76,97,A4,3C,6A,D9,65,2B,E7,7A,CE,33,E9,83,D2,22,47,07,1D,E5,DB,28,83,F6,1E,CF,EE,CB,A4,FE,23,BC,A1,80,A5,80,FE,6A,FE,81,C7,D9,12,6F,07,F5,47,56,F6,1F,F1,6C,EB,3E,DB,33,9B,CD,82,A6,34,15,3A,12,09,B5,2D,DA,22,28,C5,58,6A,B5,77,AE,26,B6,3C,5F,A5,04,E3,87,89,42,3D,86,89,4C,BE,96,3A,87,4F,50,6A,A1,CB,52,92,E7,2D,6D,10,91,A7,BB,ED,05,1E,83,5C,94,7C,A5,3B,94,86,CB,52,11,BE,25,F6,96,72,DE,8A,60,79,F3,21,BC,43,41,0E,0B,13,9C,14,13,6C,A1,D6,C9,28,6E,6F,3A,3D,17,64,6C,C3,6D,D6,A5,9D,19,CA,CA,86,DB,3F,2E,32,9A,89,95,CB,D3,40,4A,AA,A6,17,4A,06,D5,15,58,90,34,A0,3D,66,FD,4B,CB,C6,48,C1,1A,D0,6D,BE,8E,E6,C8,26,07,55,02,E0,DB,BA,62,62,BE,F3,42,6B,14,B8,B1,FB,EA,CE,AF,85,09,F3,2E,5C,F7,EC,02,38,4E,A6,7F,E2,B0,02,5A,3C,80,7F,40,05,B0,06,99,D8,06,A8,8F,36,0A,90,3C,1F,C2,93,B0,C0,59,0B,A7,44,BA,EB,13,ED,2F,E3,A6,85,80,28,D4,C9,52,74,A1,71,9C,61,33,3E,20,30,F7,ED,FA,EB,17,CA,08,41,28,F4,94,D8,C2,E0,A4,27,71,92,7C,82,28,4B,11,0C,78,5E,62,DE,6C,88,AD,16,20,66,E6,38,15,BA,F9,EF,41,50,16,A9,CD,A4,E1,17,73,8C,EE,F3,CC,B2,D5,F4,CB,B6,04,4D,25,BC,E4,63,E0,0D,FC,FC,D2,15,FE,FE,31,BE,B2,AF,E6,91,BE,71,F0,4F,82,C6,76,C1,F6,1C,0B,3A,B0,38,D3,62,4A,BB,86,1A,2B,22,58,89,4C,DC,43,EC,BB,48,56,2B,89,86,1B,79,B5,D1,CE,D2,59,46,AA,B1,D4,95,FC,C9,4A,04,2C,A2,69,2D,EA,C2,5B,A7,84,52,14,C0,25,0F,3A,4B,67,55,9F,CB,4B,92,D2,91,88,D4,CC,AE,0A,E3,C1,51,C8,33,C4,52,8D,F2,24,F8,49,87,F9,BA,4C,E5,0B,A9,EF,BD,AF,99,8F,88,95,74,3E,51,F4,28,F5,88,CF,21,5C,66,8A,D3,BD,52,FE,CD,FA,51,36,07,32,E2,85,8D,1D,BE,80,D2,25,C9,5A,5D,D0,C7,1E,5D,EB,4F,20,52,C6,4B,50,7B,CC,B3,6A,D4,AD,F7,1D,EB,F5,F2,D4,71,C0,19,8C,36,5E,D5,D7,D7,33,2F,BC,EC,B2,03,13,EE,F0,F9,8B,AB,7F,82,59,F9,A9,49,9D,C2,7A,D3,6C,FB,E0,1E,B4,6F,6B,66,46,42,93,09,C0,E7,53,56,83,34,11,F7,18,3E,F1,23,13,A8,04,4E,E5,77,12,D2,19,D4,AE,17,5E,01,1A,82,3E,5A,B9,F2,AA,18,25,C4,7E,E5,6E,88,C4,05,B7,C5,64,B6,25,DD,6D,00,AE,15,0D,E0,57,CF,8F,9B,AE,9A,6E,ED,76,A1,9A,70,2C,8B,B7,38,5C,C8,AB,F4,0A,67,F8,FF,14,8A,95,3F,58,15,83,2C,4E,26,C4,A0,D6,74,5C,9F,73,39,74,03,0C,A1,C0,DD,FF,8A,B5,6E,64,4E,5E,5C,89,7C,36,1E,A9,2E,AB,1A,F6,95,07,22,24,A9,5A,D0,A1,19,96,15,38,4E,8A,16,52,2A,07,8D,2D,31,C7,3A,00,12,00,A2,0A,95,8D,2E,33,4B,0F,B2,73,F4,B8,59,DE,62,C8,50,15,6A,41,CA,B2,F9,DD,0A,71,74,3A,6F,58,AC,7F,4B,63,F6,65,E1,3C,F8,17,D8,BB,B9,47,85,22,86,EC,B8,55,50,46,F0,32,00,11,AB,2C,CB,77,F3,9C,09,16,B8,45,FC,B9,2D,1D,52,D9,58,6B,93,87,A8,55,E4,18,D3,03,3A,C6,F9,CB,9F,91,F1,FF,25,1B,A8,5D,8D,BB,6B,C2,26,A6,A8,B7,C4,9D,3B,7F,34,3A,20,88,FA,2A,70,0F,F1,48,75,10,8C,9A,4D,0D,FB,15,8F,AE,1A,7E,87,A3,AD,85,E6,32,22,C4,E6,3A,BA,70,67,2F,62,02,73,8F,98,37,31,DF,B1,F2,19,70,52,A9,1F,FF,09,AE,9F,61,5D,90,C3,E5,C2,13,5B,B5,EA,77,8E,33,AB,44,E0,56,9D,69,2F,95,9C,03,31,6A,C3,12,96,E4,28,6E,E1,65,C0,7D,C4,C4,2A,68,1C,6F,83,EA,13,D6,6E,18,24,9C,AF,8D,80,F8,8B,92,9E,73,54,CB,4B,B6,90,65,62,F4,27,A8,DC,E6,5D,1F,5A,15,3C,62,0B,AE,58,26,B4,85,5F,83,A4,A9,67,2D,2D,AB,1A,49,17,E0,D5,13,2B,AD,C3,2B,7D,D9,09,13,04,60,8B,20,BE,9A,C5,5E,B7,92,4A,B2,3D,DA,E9,5F,C7,1D,34,BC,DE,BC,00,34,26,51,8F,4C,0E,B7,12,40,46,99,00,C7,E1,55,A5,38,65,FF,B9,AB,31,7C,35,5E,7A,CB,1F,9B,CA,98,9A,BA,1C,49,0D,92,DD,58,0C,F4,2D,3D,43,4C,F5,7F,C9,54,77,C0,50,88,39,5F,D0,14,5D,78,5B,C6,9A,94,00,7F,3F,61,E2,4B,5E,21,A3,B5,E9,03,2F,81,D1,71,B1,4C,9B,E3,14,0A,71,09,11,23,1E,40,FE,B7,42,21,67,24,86,80,A9,46,A8,B9,99,A9,4F,87,4B,89,E9,5B,5B,2C,6A,79,AB,E1,20,F1,B8,51,4C,DA,97,87,F7,AC,5E,1B,45,E9,7A,25,0D,46,54,18,54,75,25,D9,45,DF,70,E2,C1,6B,DF,6D,8F,C7,04,1D,40,44,58,5C,AE,99,37,EF,83,C9,44,AC,1B,B2,9A,CD,1D,92,45,E4,36,1A,08,9A,F8,67,97,53,2D,34,84,AF,4B,1E,E0,64,33,3E,4D,43,AA,68,92,D0,1C,CE,B6,6B,CE,FB,93,F2,C5,E1,1C,26,0A,66,9A,DD,1B,A1,F8,90,B1,17,F4,E9,D7,5D,9D,C7,31,E2,0B,0B,84,B7,C1,49,2F,8E,5F,E4,19,07,6A,B8,EE,33,C7,E7,75,19,F4,1C,11,E7,11,6C,28,8E,21,7E,91,35,DC,9C,DD,38,26,C1,72,19,CB,E6,C1,F4,A5,34,36,4F,0F,2D,49,8F,72,4B,02,6F,22,8C,D5,7A,AD,E0,83,4D,CF,40,E9,5B,0A,D5,C5,DF,EB,3B,4E,D0,8E,84,B6,10,DF,89,11,14,87,1C,2F,51,E8,60,BF,83,A2,B5,9D,BC,66,2F,1D,6C,CC,25,94,44,C9,CE,8F,21,37,02,22,38,E1,2E,C1,C5,33,22,5E,7E,A1,45,3E,73,7F,5C,80,63,2A,85,F7,28,59,26,7B,21,10,90,51,C3,2E,A0,91,BD,BB,37,6E,FB,D3,1D,A6,A9,30,B8,5E,58,8C,53,AC,64,ED,E5,C0,EB,41,0F,70,55,29,DA,D5,18,15,9C,BB,D5,5F,EB,E8,51,DC,83,01,20,B3,4D,A5,B0,5F,5C,3C,C2,F0,3C,A2,4C,7C,B5,A3,CA,06,33,35,70,D6,2C,4F,84,56,FC,F0,7D,4E,D4,F7,76,21,99,72,5A,EC,30,65,8C,40,0C,7A,59,30,39,F0,BC,E9,24,51,45,98,F2,38,57,09,B5,E3,6E,CD,CC,8A,5A,A6,BF,73,C1,60,1C,7A,99,E0,E6,BD,B0,A8,F9,4D,E3,C7,B0,96,12,D7,F0,A3,D9,DF,37,40,27,63,C3,9B,36,59,B6,DE,0B,96,6D,DD,AA,50,C0,DA,DE,60,10,C3,8C,4A,3F,22,0E,2F,92,23,51,1C,4B,C0,7F,E5,B6,EA,B5,2A,2F,A0,60,1A,B3,87,10,C1,F7,33,74,B8,D3,6F,07,8B,68,00,5F,34,40,12,C0,BA,E0,88,26,2F,66,19,78,DB,DA,DC,66,A2,CB,74,1F,95,6A,D4,E2,78,FA,C9,A0,02,10,7B,D9,F4,FC,1C,26,0C,95,55,69,FB,00,46,78,44,CA,62,E8,E0,3F,F4,09,11,ED,DB,6A,E1,33,C3,E4,0E,CD,88,2E,48,CC,92,D7,62,4C,DD,6F,5A,8F,95,ED,78,32,5C,B5,98,07,0D,D7,A7,25,5E,17,63,1D,43,57,C1,BF,0D,14,EB,9E,6B,5F,7B,5E,0D,94,FC,32,39,72,67,FC,2E,7D,40,0C,1E,4F,0A,50,3A,BE,57,8D,23,78,5F,FC,E6,EB,CB,C2,B9,31,9B,AF,41,34,0B,44,0C,7D,50,83,9E,95,BA,4F,44,41,AD,5B,8B,5D,08,CD,76,69,A5,10,98,E0,3B,00,1B,31,FB,D8,D8,1B,AA,D8,8C,0B,3E,B9,85,57,C2,80,B0,C1,C6,38,58,CF,21,AE,E7,A9,03,F9,DF,A6,83,18,B2,1C,12,A9,47,29,D2,14,41,6A,46,AB,21,DC,FF,90,1C,A6,A7,43,C4,1C,84,66,F9,56,7B,20,7E,AA,C2,8A,47,B7,A8,62,CB,32,21,E2,C2,7A,DA,26,34,50,08,19,E0,D2,48,26,23,1F,9E,94,E3,FC,91,03,E5,8F,23,6E,B7,AA,35,F9,E1,4B,B1,B8,09,A3,9E,13,AE,AE,29,B1,6A,41,56,12,76,7B,D7,B0,A2,F4,0D,B7,53,22,DB,B4,40,E3,DB,49,AA,76,F6,BD,9B,02,E8,BF,26,1F,7E,D2,AD,44,63,CF,70,74,16,55,55,1F,0F,D3,DF,9C,E8,AA,0A,3A,7E,94,0E,B5,34,64,FD,B5,2D,8B,F9,8C,FA,74,AA,88,88,EB,EE,51,55,EE,66,78,A3,5F,42,10,CB,34,6E,9C,88,EC,1A,74,A8,A5,21,0F,FD,BD,89,D0,36,E9,CD,31,80,54,AA,33,A7,BA,13,C3,9C,F8,0D,15,32,50,C5,BA,66,0A,61,16,E0,8A,AA,7A,09,62,F6,A4,62,91,2A,2D,60,72,2D,75,52,82,EA,4C,BF,3E,A0,CD,73,82,DB,C7,9F,B1,49,C4,3C,BA,18,F1,75,2A,EF,71,C6,98,A8,D7,5E,EC,B0,DF,BF,26,AD,A5,B6,AA,F3,ED,D0,C8,BE,43,30,C5,8C,C9,63,8D,8A,25,5A,B7,80,94,2A,30,4D,E3,EE,F6,4D,44,64,36,20,8D,F6,B6,40,3B,4B,DE,59,9C,E7,EB,40,19,91,A3,0A,43,56,51,E2,BB,89,6E,6A,73,27,51,19,33,61,64,CB,CC,06,5E,01,E0,F8,CC,AE,EE,0D,60,9E,93,5A,F1,A8,8A,37,0B,14,9B,45,C4,2B,55,46,BE,40,40,89,CA,FA,CB,E6,3A,A1,9D,BD,66,F6,AF,96,7A,C5,BD,57,34,DB,3E,8D,4E,D3,91,8F,A7,6D,73,FA,E5,BD,BF,1A,78,54,84,0C,95,72,89,C4,AC,D6,57,CD,D6,D6,53,98,3C,F4,FA,1A,03,8B,5E,87,56,58,72,30,10,EC,EB,55,CF,67,7A,CF,41,03,10,08,4E,39,A3,4F,38,0E,CB,90,BC,C7,31,88,75,9D,9C,B7,26,C8,AC,D6,82,BF,E6,F7,B0,35,28,E8,CE,32,61,59,66,1F,F0,74,6B,DC,C5,FB,CF,01,13,C2,30,EA,3A,0C,84,68,A9,EF,AE,1F,D0,0A,E5,20,46,7B,CD,F3,57,DD,DA,1D,9D,BD,AE,A8,58,2C,A3,A7,BE,5C,24,48,40,B8,BB,26,7B,AD,00,3A,26,8A,57,B9,3E,31,2B,A6,FF,0E,4E,D2,4B,A3,20,08,DD,87,72,22,70,A3,08,48,33,0F,7D,83,5E,C9,F5,32,55,A7,EC,DB,45,BD,70,AF,D8,0C,22,98,91,E2,F7,73,19,DD,F8,D6,B6,83,4C,CF,CC,BE,CF,91,BB,6B,C6,6C,4D,8A,0D,4B,BF,F2,5A,83,4D,A8,CA,D5,58,C3,45,F6,53,0B,14,44,BC,07,F4,AF,BE,F9,E8,01,E0,FB,CA,7F,F7,28,90,55,57,D5,A1,EE,25,75,EA,B0,5B,6A,FA,13,DB,62,43,0E,90,14,96,36,0A,36,44,EC,48,6E,D5,5E,7C,C1,ED,AC,D8,22,19,DC,45,9D,92,35,8B,8D,1F,20,04,85,CE,F1,05,B2,9E,46,47,93,1C,84,8D,9C,1C,56,55,A3,78,2C,8E,22,EC,79,A3,F7,F4,5E,64,E1,AA,AE,D7,A8,83,6B,37,38,13,F9,D3,46,EA,1C,BE,C1,80,63,11,46,A3,4A,93,81,D4,4D,ED,1E,12,D2,65,3D,37,A6,BD,E4,D0,EE,6B,2C,E7,EF,04,B2,75,0F,C0,95,CB,27,9A,7A,DC,88,4B,AD,16,D1,BC,07,C8,50,16,88,CF,81,2A,DC,98,CB,30,58,26,4E,CD,9A,37,A9,AA,EF,6D,D1,FC,2D,AD,84,7C,0B,19,67,0F,54,92,99,3B,91,72,37,71,21,D6,18,E3,F7,06,6E,C5,0C,74,30,59,03,6C,40,BB,91,00,23,CB,FD,AB,50,92,E1,50,AF,11,37,16,C3,31,EE,DB,0A,B0,42,AD,7E,C5,2A,E9,F1,38,8E,35,1A,02,18,BD,F9,AE,0A,E6,8A,3E,C5,F4,BD,5A,36,46,96,72,3F,3E,FA,68,CC,EF,4E,D3,A7,02,B6,AF,58,30,86,5D,27,AE,D9,3A,48,7B,13,EC,E1,06,45,67,12,2D,F7,8D,F3,4A,80,4A,55,8D,12,20,94,51,E0,98,62,0A,79,AA,AA,79,E1,92,5F,8E,E2,32,D8,FE,6D,4C,DB,88,EB,4F,F4,ED,CB,3D,57,DA,57,96,DF,9E,03,57,6D,10,B5,BD,AA,E2,4D,A4,D4,99,D8,D3,83,F6,72,E2,89,17,10,5F,9C,25,73,DA,24,E2,6B,75,65,DB,2D,DD,CF,A3,0B,F9,B2,C8,86,3B,E8,CF,65,D8,31,9E,D7,28,6F,15,65,75,FE,67,98,20,82,2B,76,98,88,D9,E0,97,CF,03,BB,FF,4E,A8,40,39,F6,33,59,9C,E3,7E,E9,CB,6A,C8,F5,E2,39,09,81,01,96,7D,AD,05,07,38,69,B9,E6,55,85,5A,E3,AB,3F,67,94,32,2C,C0,12,0A,AB,0B,7A,A8,E1,69,D1,80,E5,CD,B3,57,AF,F8,74,5B,9F,E3,26,16,21,B5,9A,79,E6,A1,28,B2,E3,67,23,16,D2,AB,71,A0,CD,CE,20,66,17,44,F1,B2,27,F9,55,C5,B0,3E,7B,C5,8E,95,A7,A6,A0,97,19,7C,5B,1E,25,B4,4F,1F,F9,45,98,C1,7A,14,3F,B3,47,B0,D5,E5,78,5B,65,E9,97,DF,E4,A1,F8,64,BB,B9,E3,2D,A6,B5,D8,7A,9C,99,19,E1,24,BF,55,8B,B0,69,EE,5D,CF,3B,95,2D,50,5B,15,05,53,CD,90,01,55,FE,E4,C0,76,52,97,4E,B0,42,A7,61,A3,F3,87,C5,38,F2,EE,B9,50,F4,7E,0F,BC,EC,8C,43,8A,BB,8D,A7,88,6F,CD,D9,E4,25,FE,30,CC,86,97,8B,9D,1A,DC,98,93,AA,A7,BF,59,37,8A,D4,A5,A9,3E,07,FC,9A,96,B5,72,75,97,95,FC,48,8C,3A,2B,39,21,11,09,8C,E3,2C,4A,FF,31,11,1C,C4,EE,5F,EF,81,D6,2F,78,B0,CA,69,11,5D,46,29,51,75,29,44,78,EF,5B,30,92,12,92,63,86,03,FE,95,35,88,43,BA,71,C5,97,C0,66,DC,9F,22,D3,DE,40,D2,AD,ED,B2,42,FD,67,15,75,CF,EC,41,EA,E3,3A,73,A8,DE,A2,59,C8,FE,4C,D1,E8,1D,71,EE,91,95,52,C5,1E,39,85,57,BE,0D,BE,B4,67,0B,A2,BC,4D,28,02,8B,C4,DA,99,03,68,94,BD,1B,7E,21,5E,34,58,D5,AC,2E,2E,12,FE,59,EE,16,DF,CD,3A,2D,B1,6C,A5,FE,D5,99,2F,1F,A1,BF,B7,4A,18,D2,08,9F,B1,1D,8B,0C,27,B1,A2,7B,FB,62,36,B4,42,F6,B1,8C,03,BD,AD,BF,C8,37,6E,A0,36,83,DC,C3,5F,B0,9D,92,C5,FC,38,8F,5A,C1,D8,DA,2B,B6,D0,7F,16,A4,4F,33,6A,61,D0,15,85,3B,05,84,21,D3,E8,3A,CF,60,8F,8F,AD,8C,08,0C,D5,B5,1B,C0,CC,5B,B0,02,85,23,81,EC,76,7B,32,53,B8,16,5A,F6,96,C5,F4,02,DF,61,39,96,3B,2A,B9,D4,C4,89,F6,9C,D9,48,2A,0B,02,BF,39,A5,52,CB,A7,63,35,29,BB,72,45,52,18,34,35,45,56,19,40,11,ED,00,08,9B,A9,C8,36,08,A0,3D,C1,DF,71,B5,AE,CB,71,9B,A8,CD,41,EC,05,3E,9B,27,8D,8C,67,DC,D6,E6,DA,8C,5F,7C,39,44,D9,11,44,43,5E,60,4F,B6,86,66,6F,CB,CE,02,C3,F1,F2,96,5A,33,82,36,81,FB,47,C2,5C,C4,5F,C1,6E,14,A5,A9,1E,C2,96,C4,A4,C3,8B,B3,BC,5C,C4,27,0A,6D,CD,D4,AA,AF,4E,6A,28,4D,11,F0,B5,B0,64,FC,C6,52,2A,21,1C,88,E3,16,AF,DB,8C,DD,6F,73,10,E1,54,11,C0,FD,EF,A4,99,F9,43,51,94,67,C1,6D,1D,03,64,15,22,DA,F6,87,9C,F1,9F,7C,1B,45,FB,0D,CC,E4,DB,27,11,28,62,AF,45,67,9F,42,A3,05,05,55,47,87,A5,35,F6,05,E4,E6,09,7B,5D,42,3E,DB,5F,02,F7,12,D9,4F,CF,EE,EA,9C,93,E8,9A,D1,C6,9F,9D,4C,B1,52,A0,D3,C8,2D,B6,05,B8,80,CA,98,88,6D,07,54,35,F3,C9,12,BC,D1,BC,AD,C1,AB,14,EF,31,08,25,3B,17,8F,A8,06,AE,BC,16,B7,06,9B,95,4D,58,7F,55,44,1E,F0,46,48,F5,C6,02,BA,69,8D,64,E0,71,13,12,5F,99,0E,3E,26,D1,70,AC,7C,F5,DF,13,E2,49,B4,C6,7D,EF,D0,DB,94,C3,CD,0E,97,4B,2A,3A,D3,91,69,B5,AB,4A,8D,B1,E1,5B,49,26,44,13,07,AD,EB,27,5A,27,28,14,3F,1D,F1,9D,7D,A9,7B,2B,3F,BD,F3,10,FB,E0,D0,B2,80,6D,A7,FA,9B,8A,9E,EC,C1,6E,4F,F4,F5,44,D0,61,81,3E,73,05,10,B4,94,44,CC,02,33,29,91,EC,DF,50,AB,76,76,50,04,E2,72,C0,50,E2,B8,5B,40,FF,9A,B0,E8,A1,AB,16,52,F5,A6,41,3B,60,C1,27,6F,17,D7,CE,1C,CE,4E,0F,9C,76,3B,71,DD,87,5B,49,F8,13,C9,4A,C6,FC,23,ED,8C,A1,1C,2F,D2,88,88,04,6D,E8,F7,BD,88,7D,6C,DC,A4,D4,14,0C,7F,1E,F4,93,5D,BD,65,66,08,FD,A9,6C,D5,67,2B,9E,B5,E3,49,DB,34,B2,BF,3D,DC,D3,B9,6F,74,EA,1C,16,CA,81,4B,2B,74,52,A1,1A,0B,1A,D0,5C,28,A9,6D,65,C1,88,20,3D,FB,26,2B,A9,43,BC,79,85,15,80,6F,9B,16,58,2A,0C,61,85,39,1F,AF,7B,6B,22,8C,6D,36,4C,21,30,53,3C,39,D4,5B,C9,F8,12,92,96,05,68,B1,12,C8,E2,EC,A6,C6,D0,9B,03,D4,51,CE,94,14,B8,27,87,A3,E4,BE,13,18,6A,62,09,81,6D,16,08,1C,E6,BE,EA,52,6E,1C,9A,23,FB,91,AD,81,1A,56,43,62,0D,FF,90,FB,43,BC,39,BC,F7,AC,3E,2D,A0,3E,2D,C1,DE,E5,00,57,1E,5F,54,67,97,9B,09,36,8E,88,BA,C3,98,E2,47,95,4B,7D,98,1C,F1,0F,C9,9E,9B,D0,87,F8,B0,55,13,53,AE,65,AA,24,B4,B4,B4,2D,E5,65,47,07,5D,40,EA,49,02,C3,6C,CD,57,44,B5,95,75,A3,DC,64,52,1E,31,BB,38,AB,1C,E5,65,C8,CB,E5,D5,16,03,B8,13,DC,79,21,0D,8A,D0,26,66,77,CE,C6,EF,A9,A1,36,50,A8,EE,81,3D,5F,A4,B5,7E,82,48,6B,98,C3,88,4A,3C,92,0B,4A,87,86,78,9F,0D,E2,D9,E5,7E,C4,A3,AA,BA,D4,2C,32,9F,39,B4,7D,D4,F0,10,54,71,01,9C,60,5D,94,DF,33,4A,7F,C6,1B,D2,BC,64,64,B8,8E,0B,EF,94,6C,DE,88,EB,00,E3,46,F9,1D,FA,CC,BA,F6,60,27,05,63,9D,3B,2B,3C,D2,84,A1,73,E7,3A,89,94,BD,F8,F4,DD,24,A9,4D,56,42,F6,1B,46,D6,A8,AC,E9,5B,78,10,1C,92,E2,E3,1C,D5,1E,39,B8,9D,A8,40,EA,DB,5E,8A,EA,C4,59,D9,A4,D0,7C,B0,FD,F0,E5,46,C7,E3,CB,E4,49,BE,72,0A,57,B5,8B,9E,E8,4A,23,20,D6,9B,D6,DE,B8,15,4B,84,4D,8F,AA,43,08,EB,72,A7,2E,00,01,35,54,C8,6C,D5,04,AB,49,EE,DE,AB,2B,D8,6A,2C,91,68,17,58,D9,A0,33,D0,BD,B6,AD,42,A6,9B,32,52,57,CC,F6,9D,B8,1D,81,03,72,7F,55,90,6F,52,13,69,35,92,2E,7D,90,B3,5E,0D,4D,34,4A,B5,40,C7,5A,D3,7C,C6,49,B2,63,0C,9D,D2,2F,FE,54,C1,16,8A,82,D8,A2,92,9B,90,C4,0E,97,D9,B0,D1,F2,86,A4,96,93,AC,EB,58,52,67,F5,9D,2B,04,97,E8,3F,C2,66,7D,CB,D7,B0,E2,E5,A9,90,C1,4A,39,7F,F4,77,89,B5,ED,D3,B2,AC,79,54,52,DC,FE,3D,87,42,10,27,99,C4,5D,B0,EF,8A,C6,D9,60,A1,A9,52,3B,0F,3C,4B,4F,71,43,42,DB,90,0D,44,FA,51,9A,2C,FA,61,E2,8E,1E,B3,31,70,80,2D,A0,24,A7,EC,C7,A8,62,A6,AD,EA,22,5F,E0,DB,3F,F8,5F,59,E4,97,D4,82,7A,36,E3,69,B3,F3,DD,14,57,24,DA,3E,AF,B6,49,C7,A0,76,C5,C2,BC,86,30,05,EA,B5,DC,1D,C2,2A,D1,79,41,79,10,9D,A2,3B,73,9B,77,8D,08,CC,A9,71,C6,01,75,27,3D,E6,10,3C,43,04,51,76,65,C6,4F,8D,B2,17,5F,1A,9B,52,A5,66,23,07,79,08,C8,E5,22,F8,C7,A7,D1,74,C6,B3,13,6E,69,E3,66,EC,96,A8,4F,6E,35,9A,64,AC,AA,A1,A6,8B,61,AA,7A,0C,04,B5,CF,D4,01,A7,0A,10,57,88,D8,8B,D0,76,B1,07,B0,7E,87,88,A2,21,EC,05,A6,B1,49,80,B3,29,AE,5F,16,70,91,6E,D5,2D,9C,FB,14,C1,3D,B0,35,8A,C3,6B,63,A7,48,3F,65,B7,58,1D,5B,3F,F1,C2,AC,6A,7A,FA,10,47,19,0B,8C,D0,20,11,01,3E,70,F1,84,4E,7F,D5,01,A0,EC,30,8E,33,6F,FA,0F,52,58,43,B3,E0,94,1E,38,63,69,21,BA,5E,CF,84,9B,1C,DE,C0,2C,C2,6B,BD,78,65,DE,FB,E3,9E,E8,E4,07,F4,3C,35,B0,34,96,B2,F8,EA,6E,CC,9C,AD,9F,D9,FF,81,73,82,7B,01,61,9C,8C,EC,7F,07,DF,42,22,46,F5,0A,5C,E8,C5,E9,2D,68,5A,CB,D8,F2,C6,D1,83,CD,9F,64,54,BF,D8,B7,C6,3C,42,36,AD,2C,B6,12,5E,25,51,D7,C1,75,92,47,79,75,88,6F,A2,8F,32,0F,E5,7F,6C,AD,98,6A,64,7A,FB,C1,60,43,A9,28,CF,A7,E5,FA,72,A6,B6,EF,58,D7,6C,8C,B6,EF,3C,46,46,4E,62,45,16,E2,C2,EA,22,F1,67,51,37,2F,13,51,D7,4F,F4,0A,F7,FD,F1,E9,8F,24,AE,1A,DA,A2,CC,19,8E,47,33,67,2D,8C,FB,F0,29,DF,5D,E4,10,05,A0,DB,10,F5,87,15,9F,25,D6,4B,36,54,F5,92,14,C9,BB,D4,77,7C,E8,10,3F,A2,70,5E,1F,5E,3F,6A,9B,0B,D9,2A,A9,40,DE,A5,A6,12,54,0B,BE,E4,D4,E0,9A,87,C9,B8,E3,E0,BD,71,F7,1D,FB,38,5D,AF,DE,B7,F8,8C,8E,DF,06,F7,25,DF,BA,AF,FE,1A,85,E8,2F,66,70,66,C8,ED,99,57,59,43,72,AB,36,8A,FB,94,65,C3,4F,AA,0A,89,17,28,D7,E1,82,DF,7E,F7,88,F0,77,52,9A,EB,4D,15,16,E4,EF,8D,0D,68,6D,99,4A,68,EB,6A,39,C8,B7,E2,BF,A0,9B,29,97,8A,E2,77,08,9E,62,29,A0,67,34,26,AC,F2,81,7D,77,7A,F5,65,5E,40,D3,D7,53,26,9A,F7,88,FB,10,99,27,1B,AA,CA,B7,95,3D,5C,6A,61,6D,DD,94,BE,4D,14,35,53,A1,06,5A,0F,84,8D,C0,EC,65,36,E8,6E,1F,3D,93,0C,BC,45,1E,26,B6,38,28,24,8D,2F,51,8B,C5,4B,E4,DE,5D,7B,22,98,09,7B,9B,E4,F8,63,6F,EA,80,46,52,2E,DF,6E,9B,05,76,7B,9C,6A,8E,C2,58,9C,E2,09,19,E3,35,0B,8C,31,83,FE,5C,8D,3A,3B,70,07,70,C8,04,68,95,C4,FA,64,F4,21,18,B4,5B,34,5C,CD,14,A3,B2,8A,36,6C,BB,A3,51,F1,D3,1E,B4,48,7F,E7,36,A1,7F,72,02,23,0D,94,E2,EE,96,F4,7D,2A,83,27,FD,DA,FF,6F,B6,B1,04,C6,02,09,79,00,6A,51,BA,15,99,EB,77,C1,58,9C,2F,2F,DB,98,F8,33,EF,1F,AB,91,94,5D,79,F6,74,4E,51,4B,91,6B,84,0A,BB,22,A4,C0,A5,C6,A0,B7,0F,B0,3A,74,BF,B2,BE,78,FA,58,27,16,EE,E6,85,A6,20,FD,F5,5C,F8,B6,ED,6A,20,31,36,11,DB,6F,AD,1F,51,87,4A,05,95,12,94,86,93,62,79,F7,52,C8,1A,D4,A6,14,7E,37,0A,54,BD,6A,BC,31,2A,67,DF,FC,E1,CC,65,4F,D1,C1,C3,68,1C,B0,37,AD,A0,3B,17,CA,D1,57,90,BF,F0,11,48,D6,A1,7A,15,F9,67,8C,A8,FA,A3,CB,C7,0C,48,E0,40,EA,3A,10,45,E6,22,69,6B,F6,4A,1E,A3,DB,AA,A2,F6,23,7D,26,36,EC,9B,D3,44,66,C0,5E,25,41,6F,00,15,94,8C,B3,4D,0E,1A,FD,6C,CD,D6,86,EF,27,4E,70,48,4A,72,04,FC,0C,45,E3,1B,0F,4C,B5,61,6E,E8,09,83,A6,78,D9,F8,F0,E5,84,2F,4D,B1,05,2E,CC,F7,00,45,B2,92,A2,F4,B9,F5,8A,29,A4,59,09,49,AB,0C,12,A6,0A,F6,0E,E7,19,9A,E9,C2,E1,E3,8C,1C,09,30,75,4F,6D,E3,31,75,06,3B,78,AD,82,F8,10,50,69,AD,75,D0,F3,8E,3E,B7,E5,F1,34,8F,8A,13,79,20,99,4B,AA,DF,DF,46,36,83,F4,0B,41,3B,9E,D7,BC,B5,90,4E,D1,71,9C,A0,B3,8C,B2,F6,D7,D9,B8,D0,16,75,4F,34,6E,2B,C4,0B,1C,DE,B0,6C,10,EF,3F,18,FF,2E,F5,72,44,DA,6B,46,EF,97,C3,BD,68,FD,A1,58,C0,C8,5D,5B,76,03,14,76,6B,5B,50,4D,55,3F,6C,2E,6D,72,7A,DB,63,B8,8D,F0,F9,99,DE,50,FE,14,05,E9,01,A2,82,DA,1E,84,FC,EC,5B,05,C0,62,58,06,72,45,83,3A,1A,E5,C5,8E,CB,F6,62,9C,E9,87,F5,13,A3,E7,6B,44,FA,BA,7C,62,43,2E,41,B8,52,CE,A4,74,4E,93,64,40,3C,2C,6E,39,20,E2,3E,30,15,CE,06,B0,F7,7D,CF,B8,2C,D6,A4,E0,36,09,88,95,14,00,C8,F2,FA,C2,6C,EA,AA,FA,B6,2C,C5,5A,5C,DC,F6,95,4B,F8,2D,68,76,F8,CC,34,48,39,E8,39,40,BF,96,E1,9F,F2,58,4E,76,C5,D7,2B,EA,67,E2,54,45,93,60,25,C3,94,80,C8,A5,99,EB,96,0F,2B,16,61,1A,42,FD,B9,6A,73,A5,AE,3D,D4,2E,DF,8D,36,EC,02,2A,E0,DE,76,69,89,6C,B7,79,02,10,DC,85,A4,44,B8,1C,FF,2D,ED,06,7E,59,FD,B1,AA,44,7B,F6,3C,8B,4A,E0,F7,AB,27,DD,95,3B,E7,20,8A,89,6A,18,B0,82,7A,54,BA,76,45,A9,8B,08,09,28,AB,C8,6F,5E,67,97,A8,7A,85,0E,8E,45,73,DB,E2,9B,2E,8E,41,22,D0,FD,1D,AB,E7,6C,D9,FB,43,5C,80,F4,68,C7,32,01,F3,65,24,67,3F,FF,ED,32,48,B0,2D,3C,55,99,E7,9A,86,84,5D,FA,16,EE,DE,0A,F3,DE,44,F0,9A,9C,34,D0,4B,4E,CE,23,6B,B8,13,5C,CC,B2,81,EF,BD,E0,05,3C,82,33,A1,F2,54,2D,18,B2,E5,B1,8D,BB,3B,00,8E,90,16,AF,F0,28,A6,1C,AA,83,BD,8C,FD,03,0C,7C,AC,EC,5F,21,6E,EA,DB,D9,C5,8B,77,E1,E6,C9,48,7F,EC,11,0F,69,30,61,7E,16,78,C6,27,89,7B,05,EC,20,CC,D3,8B,6E,46,F0,8B,49,74,A8,F5,D0,DF,95,D3,F1,D0,11,2C,9F,5C,8C,80,28,0E,C4,C9,A8,F5,40,32,4F,19,B8,9B,17,99,5E,D5,94,83,A2,A4,F3,1F,EF,DC,FB,57,99,3D,F0,8A,2B,76,59,CF,EA,B6,06,F0,9C,AF,40,EA,97,C1,BD,F0,F8,89,FB,18,91,19,C7,8D,09,90,44,7A,F6,4A,9B,E0,FE,5A,AF,00,A7,5A,11,87,03,5A,0B,B7,3A,DB,05,B8,CC,49,9F,54,B1,D4,AA,0C,82,FD,15,E6,49,06,2F,08,34,16,40,BD,3C,28,FC,F6,8D,AD,91,58,9E,63,D8,DE,57,19,6C,E4,F4,37,54,24,1E,72,8F,98,57,93,77,68,45,F6,26,2D,46,0F,29,EA,4B,68,26,9A,F8,C6,D9,47,2C,CD,4D,60,83,3F,6E,03,A6,8E,8C,74,FE,28,82,A8,25,F2,E8,7F,2C,0A,40,57,BB,21,0B,80,ED,3C,8D,4F,EA,88,1C,51,1B,2B,A1,62,1A,12,49,D0,B9,21,7E,34,29,13,0E,D4,5E,05,3A,F9,CE,C3,0D,3C,AF,D5,EB,F8,EF,AC,55,AE,3B,7F,65,99,FE,9F,66,0E,E4,9D,74,4E,49,FE,B0,23,AD,51,8C,D6,6E,CB,53,1E,53,67,02,1C,21,6C,67,2F,FA,C5,64,4D,31,23,79,0C,82,E2,D3,0E,FD,3B,3A,66,77,E5,09,4E,1C,4C,DD,02,C1,C3,4D,07,92,FE,D4,74,79,92,03,D4,8A,A3,31,96,E7,A7,96,1C,BF,4A,53,03,3C,32,47,41,46,FF,C3,68,D4,F0,1B,80,72,E8,DE,51,B2,3F,43,31,8F,3B,7C,8B,0F,FB,94,38,67,1C,DB,49,27,ED,A7,CE,6A,77,D3,F6,25,D2,77,DC,AB,C3,D5,5E,8C,38,84,7D,DE,EF,FD,62,50,8B,C1,70,EE,43,CC,5B,75,BD,2A,88,8D,C0,A3,53,A4,03,56,26,B7,7A,E8,38,E2,D7,D2,8A,0B,B9,11,A7,97,D4,DD,FC,7B,AF,49,D2,C4,AF,9C,20,52,6A,A2,54,D5,31,00,2E,9B,D7,F8,5C,67,62,48,32,29,03,2D,A5,1A,6E,6F,DA,B0,D1,FD,94,24,5E,4A,88,A5,24,B7,7F,36,7A,97,BD,FB,9B,24,E6,38,24,87,82,DA,67,49,96,88,D4,01,40,FF,2A,20,4B,E8,F6,B2,CE,68,1B,DF,3F,C7,DD,03,2E,C1,08,11,EE,E7,B1,77,C4,7F,8C,6E,0D,1A,C8,E0,BA,48,0F,BD,0C,73,2A,1D,42,16,C8,B8,C1,42,9A,87,BA,83,94,CA,84,B7,B5,84,A4,A5,47,51,08,AE,A3,0E,90,F8,1B,6A,F6,6C,12,DB,25,AC,37,55,EE,2C,B1,B7,D1,86,0F,4B,A4,10,DF,61,11,9B,50,29,13,56,0D,D1,8C,C7,32,42,60,D8,CA,BE,AC,59,F9,65,72,F8,98,0C,58,7A,3E,36,37,4F,2D,8B,7E,B8,C2,37,B4,B0,EE,48,86,54,24,61,02,4D,6C,FD,FE,FC,3E,F5,C8,65,F9,DF,9D,1A,17,C8,D4,0A,0C,D8,44,72,06,F9,C6,21,14,80,E6,FF,37,92,51,FA,CB,3F,8B,E5,7B,C5,98,4C,71,1A,98,90,B6,10,2E,20,81,AE,CA,D6,36,B3,97,2A,92,60,68,CE,B4,F4,A6,9A,57,71,0B,F1,8C,AE,C1,39,5B,D3,CF,0A,04,E0,12,80,89,D5,70,7D,F0,0A,3F,92,A7,43,16,DF,EA,E1,62,64,0E,C6,71,B3,1D,45,BF,47,CE,9B,D6,EB,AC,35,1D,38,A1,99,A7,A6,2C,53,A9,6F,11,9B,5C,FE,DF,EC,B0,47,36,8D,97,58,00,D8,DC,0A,81,BA,DA,39,50,55,C0,49,41,47,48,78,78,C7,7C,60,BD,D8,50,3C,84,CC,D6,A5,F0,C1,3C,07,BC,60,71,2A,70,8B,6C,1C,1D,75,E6,6C,44,CC,69,AF,E6,EB,34,5C,BE,AB,4A,1F,CF,6B,B0,5C,C1,22,13,7C,D3,A6,3D,45,53,4F,8A,83,33,2B,0B,F3,D4,6B,D5,DA,3C,31,93,82,BE,22,D6,9A,43,11,2F,8D,81,E5,A9,E2,8B,67,D7,9D,B7,9E,CD,7D,13,E6,7B,01,09,52,7B,24,63,24,10,80,1B,5C,44,71,8F,42,D9,A3,7D,42,AB,A4,50,AF,05,D2,0E,9B,E2,29,60,2B,44,20,02,6B,62,95,A6,A9,6B,5E,65,32,DE,1C,55,18,56,4C,DC,37,BE,D9,30,4C,69,F0,9D,54,69,56,74,59,7C,19,B1,9A,B3,A7,CC,F0,33,1B,23,C6,DE,3E,3D,E9,CD,BF,59,4F,45,C1,D2,DF,A3,FB,FF,72,1F,A1,CB,9C,09,F3,68,AE,7D,62,1F,33,F4,9B,82,07,D8,CB,29,FD,19,20,53,FC,92,D7,FC,61,C2,5C,F6,8B,50,AA,8A,80,32,3D,9E,1B,B4,85,A5,FC,31,F9,A9,05,68,67,9B,0F,72,CB,64,61,98,E2,7F,EF,C9,E0,D2,DD,FF,3F,B6,AD,98,5B,FF,33,43,64,0D,18,AF,24,F3,88,A2,2A,2F,9D,B9,D3,3B,1D,C9,5C,9D,AC,1A,2A,71,DB,6B,1F,2F,B3,07,E2,5F,4B,F0,98,67,EB,E2,1A,02,83,C4,D7,CD,55,6C,EF,DD,C3,80,ED,49,49,5D,BF,12,AD,91,6A,E1,6C,BB,4F,65,34,38,30,85,CB,56,04,83,BC,FE,F8,40,FB,9B,BE,03,BB,61,CB,DB,B8,8D,25,13,2A,85,E7,34,6D,34,31,BA,08,78,80,2A,F4,11,DB,45,CD,A0,CF,F3,9E,AE,FF,40,C5,F0,8A,64,42,B2,11,9E,67,42,60,3B,81,0E,7D,2D,5E,98,46,11,63,4C,E8,14,06,D2,89,68,0C,9B,5D,17,21,BD,14,97,8E,A8,93,E8,3F,F3,DA,40,AC,5D,1C,0E,B9,F1,55,99,D9,56,5E,28,2B,D0,CE,DA,8F,06,38,73,12,C1,FD,23,96,9C,04,4E,63,D4,20,8E,2A,E5,38,6B,28,8F,8E,5C,03,03,72,15,F4,D8,6E,C1,4F,ED,9D,20,20,1A,06,2D,72,0A,F8,3E,C7,23,75,BE,90,6D,78,E4,61,98,69,36,FB,F9,E0,D7,6B,C8,E5,A5,EF,59,8A,69,AD,35,56,27,8E,6F,57,BC,23,F4,EF,42,35,10,89,75,6F,A9,9A,E6,D0,BE,2F,F2,2B,38,A3,6F,CF,C7,23,A2,8A,6E,85,A1,3F,B1,16,AC,F9,5F,63,CE,BF,BB,A5,E2,2A,EE,98,25,72,7F,BA,01,E5,F2,0D,2C,D3,96,7F,13,A7,FA,94,3F,0F,F4,79,17,11,6A,97,28,7E,63,5C,3F,0B,2C,8C,72,64,26,E0,B9,4A,0E,36,1F,B5,1A,36,F7,BD,E5,91,3F,DC,92,F1,25,55,80,BA,D7,20,9D,4F,69,1F,BD,2F,A6,FD,AE,DD,41,8A,E4,FA,44,68,93,E9,F4,E7,DE,12,51,48,FF,AA,B8,82,4D,22,2E,2C,D0,8C,79,5D,17,A5,D5,5C,2D,A2,AD,FC,F4,2B,6C,30,55,BF,F1,54,F4,74,BF,0A,05,36,A0,23,CE,7F,8A,6C,AC,BB,E2,5B,F9,AA,28,03,05,51,68,09,28,1B,E2,BF,23,CB,8C,F3,39,52,CC,30,47,B5,47,65,14,57,CD,52,FA,78,C3,EF,9D,2F,68,24,90,94,48,42,E6,E1,10,66,B2,66,08,8D,67,63,DA,DC,C3,54,F0,6F,C0,28,C0,E9,05,43,B3,4E,99,B3,22,A5,A5,F2,3D,44,98,ED,99,29,BB,02,63,20,46,DF,DF,AF,A9,7C,17,E4,EE,D5,E9,F8,A3,FE,68,B5,42,62,A3,5B,5E,F1,5E,9A,36,E5,A3,C4,75,E9,C8,7B,5B,D2,F9,94,CA,B9,B1,51,47,96,D7,8A,2D,B3,B0,C0,9F,D8,54,BD,7C,92,E4,3B,EE,E8,1B,CF,75,21,53,A1,64,28,5B,8D,69,42,1A,5E,03,04,B8,F4,83,BE,84,CA,CF,79,D9,0C,00,B8,92,90,5C,69,DD,6E,F1,2B,3E,80,B1,34,BB,C0,45,86,5B,1F,F8,42,9A,A1,2C,C5,65,96,0D,5E,9E,2B,D4,ED,F7,00,5A,43,B6,EC,42,A0,1B,04,15,53,6B,90,F8,C4,D9,43,CC,03,9E,96,DB,93,12,FD,BF,0A,99,8B,C5,9C,4F,15,BE,6A,70,F0,90,7D,F9,E5,C6,DF,96,99,53,EE,88,C0,D9,BF,48,9D,07,37,1B,54,2A,6B,8A,2C,01,8B,A4,27,7E,4F,FB,9D,B5,E1,8A,42,7B,4F,02,15,91,75,31,B4,BD,1F,76,46,13,36,D0,1B,3E,F2,A0,B2,8F,E5,93,77,86,BE,43,F7,83,43,5F,99,A7,DE,0E,8D,1F,BA,35,3B,FC,C0,3C,12,0B,C1,A5,C2,80,77,71,46,B1,76,C1,B3,FE,88,92,35,EA,A7,5A,88,6E,86,01,23,A5,A0,DC,E7,75,C0,BC,CF,9C,31,F7,07,E7,69,1A,9E,31,54,0F,79,62,47,FB,55,B3,41,8E,BC,DC,47,21,3A,1B,10,49,0A,23,11,61,DF,C8,87,F4,29,D8,3F,F1,7E,CD,F5,39,44,EA,AB,D7,31,CF,F4,58,2A,55,01,70,B8,21,BB,08,34,95,45,FB,B9,86,0E,2B,26,F2,84,DB,17,0D,CD,59,8B,18,C9,A5,20,49,D6,0F,0B,58,8E,79,A5,EC,B1,3D,CA,AC,26,E5,B1,29,3D,F5,3F,B9,7C,67,D6,E2,98,B5,94,14,F1,F8,7C,14,1C,B3,7C,9A,60,55,38,EF,4D,B8,72,BF,1D,F7,95,1F,38,7E,76,6C,2B,BF,E1,4B,DB,45,F2,60,9D,29,55,BD,74,F2,9A,2B,33,7F,7C,C1,87,FF,B7,6A,26,7A,4C,AB,33,E6,BE,51,CB,64,10,C2,F3,34,46,2C,A5,0B,DE,CD,D1,49,F1,2B,42,52,29,FB,1C,29,38,94,08,A4,31,16,19,58,FC,03,26,97,4C,E8,77,C8,73,8C,FE,EB,B9,7B,B6,20,92,59,C6,44,5E,77,45,DF,0B,F3,34,13,1C,06,A5,C5,93,91,EF,CE,58,68,1A,28,54,02,1A,6C,90,23,3A,9E,AC,78,71,1A,1B,E8,87,1E,4E,D5,7F,08,D3,21,9E,E2,79,80,25,5A,4E,70,31,B0,A5,C2,28,58,0B,83,9F,81,EA,7F,90,16,74,B6,20,24,AD,CB,00,2C,0E,8C,A1,E6,FE,66,E5,37,43,0C,25,93,3A,82,09,61,B5,D2,20,A6,83,CB,41,52,E5,9D,4D,EB,1D,D9,69,6C,2D,30,BA,46,FD,B4,B4,FB,BD,C2,61,DD,18,0C,AD,D9,73,53,01,9C,C6,89,0F,FC,45,91,0F,BD,E6,4E,09,32,21,0C,21,E5,3C,82,8E,4A,2F,81,BA,76,4D,AA,5F,B5,B1,51,C6,7F,ED,7C,8B,F3,47,F7,CB,D5,DA,59,38,D5,F5,9D,72,90,C9,EE,33,3D,47,EB,98,C8,0C,1E,7E,31,A0,EB,0C,81,86,FD,D0,C9,43,53,D6,55,92,10,D6,6A,AB,85,46,6A,60,22,43,9C,0C,B3,A8,AF,50,58,00,0A,5F,B1,E0,BC,6D,B7,15,AB,C5,A2,1C,5F,02,6F,7D,B3,74,BA,25,73,E5,59,9C,8B,63,D5,BC,52,6E,52,A2,BB,B4,2D,90,24,A7,B8,E2,CA,CE,F7,F1,14,A6,2D,74,E3,3C,AE,30,0F,52,EA,C2,E8,A3,FD,48,88,8D,68,9A,1B,16,86,E6,32,13,87,95,98,57,78,35,9D,77,3B,02,6A,3A,2B,4F,5E,C1,85,06,D2,C5,49,6F,57,07,AA,7E,CB,37,E4,42,D1,8E,C5,41,10,6B,A4,EF,32,29,7E,B3,EE,48,83,1F,83,55,6E,66,5D,91,5C,54,7B,DE,78,9E,84,1F,14,4E,9C,8B,31,DB,9A,44,86,C8,2E,17,71,5E,90,B7,E0,FD,3B,E5,43,9B,0E,3D,46,FE,F1,B1,3C,83,23,E3,6E,54,81,21,77,A5,8A,8B,4C,FE,E7,48,EB,EB,AF,54,51,7E,D4,A9,58,F1,3F,BC,08,9D,55,D5,D2,14,E4,E9,9E,A8,7A,E3,A0,CD,5D,A4,3F,91,4C,FD,B1,3A,75,B8,31,A0,30,42,84,AF,C2,3A,35,BF,71,0F,36,A7,D5,00,54,DB,AD,F8,B1,D6,8A,63,24,AE,59,E1,29,8A,68,8B,CF,98,F8,D1,BA,84,9A,91,3A,8E,6A,0A,72,1C,1F,47,83,BE,28,60,0A,14,95,89,31,D7,EE,FA,46,DC,ED,53,1B,B3,1E,8A,51,45,E2,2E,9B,DE,FE,D6,8A,2F,05,B6,EF,63,FF,75,E3,AA,A5,71,98,5F,BB,B3,BF,F4,09,C8,19,4A,70,15,DE,02,B9,22,3D,8F,F2,EE,12,9B,10,61,E1,43,3E,1C,B3,E5,B8,EC,AE,E5,EF,1B,CA,B6,19,4F,FE,9B,73,56,4A,D1,52,46,D9,BB,EE,8E,D0,C1,07,BE,AC,59,CC,2E,3E,AE,B1,CD,2D,3F,29,14,4E,C4,9F,EB,D4,D3,C0,D2,FC,5A,25,AF,2B,9D,C0,C5,1C,12,A7,DF,A3,CB,7E,93,7D,4A,93,70,CF,E0,E2,4A,10,7A,72,9F,F9,64,3D,D9,68,3D,1D,DB,2D,AF,28,E4,DE,E4,38,44,DA,78,CA,27,52,B2,76,BF,81,6D,84,88,69,02,57,DE,B8,9D,DE,71,A4,62,12,2D,1B,DF,DC,D9,D6,90,CB,30,ED,D4,94,6B,BB,62,78,D4,44,FB,BB,72,2A,47,FE,B6,12,27,E4,07,2F,94,66,EE,37,8C,46,49,36,AE,61,27,75,98,9A,E5,A6,11,36,B4,4D,E1,6C,1F,42,DB,D1,B3,23,AC,55,32,60,65,4A,D4,AB,FD,93,76,28,59,0E,B4,8F,71,7E,89,77,F1,31,60,1E,B7,7B,6F,FE,1A,24,5C,E5,29,5D,D3,B1,90,16,80,D9,F5,37,78,7A,CE,6D,10,C6,E9,0A,8D,4A,C1,1E,4E,C2,F1,F6,D9,6B,EE,7C,FF,3D,DB,54,5B,B5,AB,92,42,FC,EA,6D,A8,A0,2B,5B,9F,9D,6F,E1,44,00,7E,D8,96,30,D9,AE,01,3B,5C,09,BE,29,CC,69,30,4A,7F,A3,73,F9,EE,AE,D2,6C,7A,40,F5,7C,FE,9F,E6,AB,F8,60,8E,82,93,B2,7B,05,FC,B8,05,D1,82,AF,64,2F,6A,53,EA,C5,79,8E,E8,BE,1D,AB,5D,59,8F,47,5B,83,04,E2,DC,F9,59,9E,4F,44,B5,61,91,63,CD,34,2A,B0,F7,2A,6C,50,61,64,71,1E,C8,8F,A2,A0,6D,7F,40,04,AE,D0,E3,47,3B,22,3C,6B,C9,7A,44,A9,56,A9,FF,E7,48,3F,91,C6,7C,3C,72,CA,32,46,26,40,36,5A,22,21,1A,78,A0,E6,15,2B,1C,6F,BD,77,96,3C,AA,4A,DC,D5,B8,36,51,5E,3B,5A,1A,16,2F,89,7E,AA,DD,A8,6B,D0,1C,7A,F5,F9,24,74,A5,00,D7,63,5F,43,95,2A,42,52,AD,AB,5B,5E,13,87,92,0E,7B,51,7E,AF,EA,94,7C,E7,02,66,C6,B1,07,1A,8F,11,68,D5,A5,5D,29,8B,B9,51,AA,FD,19,EF,77,2E,D0,38,FB,FD,B4,0C,03,FB,A6,4F,23,EB,2B,CE,BB,0A,86,05,95,2D,BA,FF,60,25,60,DD,28,59,14,1A,9C,0A,FA,A6,B7,37,D1,B1,4A,17,5B,C3,08,0F,F0,13,9D,01,35,02,06,CE,D8,6E,1F,31,43,37,19,40,BB,79,DB,1A,CC,A4,12,8E,1B,3E,46,5E,AD,EE,75,DC,A7,28,67,A9,CC,A8,F3,4B,65,20,93,EA,A2,13,8F,65,85,95,F2,98,88,D2,FD,4A,B0,24,17,1C,40,F0,50,17,6F,F5,FA,4F,4E,EE,6A,73,AE,AF,04,BF,2F,13,F7,47,B8,14,9C,EC,49,7A,AD,0B,CA,BB,19,BA,A1,DC,93,1B,17,D0,E0,F8,23,C7,C4,A1,FA,D0,09,19,A3,C7,35,2F,5C,AC,7C,98,79,64,02,9E,02,4A,1C,BA,06,9F,43,23,DD,AA,A3,BE,3B,B6,2B,00,14,EE,72,C4,30,11,07,AD,3B,A6,DE,81,AA,44,F8,40,BE,52,E0,3F,E5,EC,8E,77,F5,62,CB,A2,B2,0A,65,92,B7,7A,FE,E6,D4,05,78,B6,54,26,CF,14,02,80,B9,C9,9C,E1,1C,20,D2,6C,4A,CF,16,DA,B5,13,CD,78,28,14,BD,33,10,C4,F9,47,F3,9C,69,E3,0C,60,A0,CC,7A,43,7A,36,22,89,F5,C9,2F,41,8B,B2,9D,BA,0E,CB,5B,11,0F,1B,AD,21,CC,0F,C2,C0,0B,86,EA,B9,A7,AC,20,8E,97,ED,73,A9,7A,9E,60,A9,66,1E,D6,D2,C9,CE,13,B3,79,9D,29,E3,39,95,E9,53,3D,73,F7,87,D5,CC,B4,56,62,FA,21,2A,3B,A7,F8,58,EF,92,20,43,BC,98,24,4F,D4,BC,9F,70,32,B9,E2,4F,AC,04,AA,64,D4,9C,63,84,F9,C0,43,77,23,C3,CB,2E,15,BF,C8,D0,DC,40,7F,28,06,7B,7D,F3,62,CD,4B,18,19,4D,67,1D,91,B8,5B,A4,D8,74,DA,92,13,AE,BC,1C,5A,2A,64,3F,50,35,9C,44,CA,CD,B5,53,36,CF,3A,C5,55,60,1C,94,74,A8,F1,F9,75,82,05,4B,BC,46,0F,8E,22,76,CA,52,28,6C,76,18,98,E1,61,01,8A,9D,17,68,5C,67,45,F3,31,34,02,40,3F,D6,91,29,35,C1,59,37,44,FF,39,6C,44,CA,85,1F,8A,A9,3A,18,B9,0B,65,E8,10,BC,63,C0,E4,C0,0D,55,0F,F0,33,AA,0D,4A,68,C2,E5,29,2F,63,D1,CD,9A,86,80,C8,DE,B6,6C,7D,69,54,6F,9F,50,D9,75,46,37,55,A7,28,19,8E,7B,21,2B,5B,33,1D,39,E8,8E,C7,D5,FD,54,87,22,2B,B9,90,59,75,4D,6A,CE,48,FD,96,B6,30,6B,56,33,81,4A,EA,D0,74,9F,53,B2,70,6E,B5,D4,17,09,0A,AB,F8,38,C4,B6,63,BA,0E,64,E0,CE,60,49,A4,10,A3,10,88,8B,F2,9E,D7,0E,3D,CD,C3,2D,40,1B,B5,F2,6A,F7,3F,D2,73,AB,61,46,50,86,05,A2,12,A7,46,14,B7,16,05,49,89,FA,E2,4A,E1,A4,B7,DD,69,37,D3,7C,CD,A9,1F,AB,9B,FF,55,B3,ED,B9,EE,4E,02,1C,17,A3,90,7F,ED,5E,92,7B,9D,71,1B,D3,DE,AB,54,7F,05,81,0D,A3,7E,3B,18,4D,EC,05,0D,1B,22,D2,3E,60,76,C0,89,C8,38,E5,14,54,5A,B2,76,5A,0E,F0,29,C9,25,5F,4C,E6,F7,74,5D,B1,62,DC,8C,A1,01,73,82,DB,F4,99,13,C2,58,2B,48,D6,AD,B2,1B,C1,4A,3B,E1,5F,C6,24,0D,BE,A3,39,C7,D5,AA,08,B9,5E,37,75,9C,60,B5,40,BD,9E,2F,8D,01,2C,AC,42,E1,15,A8,E6,79,C4,48,48,41,59,E1,01,E6,A1,5E,A5,D9,38,0C,B2,2A,FF,0A,31,5D,37,5C,88,73,05,1E,A0,93,22,02,D6,34,AC,49,1F,09,CD,40,CA,FD,D8,5B,A8,AB,32,22,19,64,43,75,44,9A,C0,B0,6E,FD,61,E7,9F,39,5E,4F,DF,5F,AC,97,9F,A4,BD,39,95,20,40,6F,98,B1,F0,CE,21,68,9B,6C,9F,BD,7B,AC,CC,65,BC,EA,84,21,4F,4F,47,56,8F,C2,27,9D,09,C0,D7,D0,22,51,D9,AF,EE,58,C3,94,75,78,2F,3F,EB,DE,BF,6F,23,4E,77,6D,7A,AC,65,C5,89,BD,87,5A,15,32,7F,E9,6D,92,26,E3,FC,6F,10,7A,23,1F,42,1F,C9,01,33,26,9E,61,CF,03,D7,47,0F,37,F5,B2,A0,B4,09,8E,FA,F2,AD,6E,40,09,72,CE,6B,02,5C,A0,0B,3F,87,F0,26,65,C1,38,77,00,D1,DA,D3,DE,84,E2,FF,ED,67,CC,0F,82,3C,96,F4,51,EE,05,9D,44,7E,92,9C,86,5D,8A,8E,33,6D,34,BC,E7,0A,E7,A4,10,3D,74,E1,09,81,92,D9,6A,1F,08,D7,3F,F8,35,A9,02,90,FD,3A,52,72,E2,60,5B,11,ED,57,2C,6F,09,43,AA,7F,37,3D,C9,6E,00,22,67,1C,F0,8B,D1,07,2C,E9,60,05,D1,7D,AB,5F,94,9A,09,D0,7C,97,81,EC,D0,6A,E6,70,D0,6B,FF,18,EE,73,0F,1A,DB,01,32,8F,85,AC,64,D5,8D,D2,E4,33,34,D6,3E,9A,D2,18,E1,00,67,66,B6,1B,9B,F0,3B,64,EC,E0,DF,84,D4,E4,52,3D,F7,8B,08,A2,44,2A,6B,20,B2,23,76,06,A6,5A,EA,6D,95,03,EF,89,5F,CC,4A,73,63,D5,F7,48,9A,D9,F2,6C,6B,69,1A,9D,4F,31,4C,37,07,7B,62,A2,36,16,77,E8,67,D2,98,EE,CA,32,5B,88,49,78,36,DD,F9,A4,89,82,6E,DF,72,01,5C,55,4D,13,F2,C7,31,9E,9A,E4,51,16,7E,3D,DA,B2,1D,44,B3,E7,82,70,22,84,CB,6D,73,F3,48,3C,56,DB,0C,81,90,8A,D4,5E,D9,AB,9B,C1,83,CD,26,E0,13,CF,C6,F0,02,6E,96,54,55,F4,5E,73,07,E3,CB,3C,EA,51,B5,1B,F2,0B,3E,F1,C0,27,C1,60,D7,48,98,94,55,EB,1F,BE,AB,A5,BA,6C,D6,6A,C7,9B,4C,36,77,05,6E,B2,DC,1E,11,D1,30,AD,0E,19,E1,CA,9E,CD,46,4F,A5,80,78,3F,A2,B0,56,18,BB,AE,47,4D,CF,A9,40,36,9E,BC,1E,6C,23,A8,7E,46,BF,A8,8E,EE,B1,8F,68,35,4E,CF,99,FA,9D,73,84,A9,7E,12,FB,5A,02,E8,65,22,06,8F,DA,0F,11,D7,31,84,F7,97,1E,4C,35,F6,D3,48,07,53,C0,83,1F,4A,89,71,3F,70,12,2B,1D,D9,9C,2B,26,31,93,41,A7,E3,9D,17,6F,1C,0F,21,34,CC,31,14,6E,4C,57,B6,5D,91,2F,0D,E7,7F,E6,8D,F2,6F,88,99,A0,A6,87,68,AE,A9,17,02,3A,52,66,DE,84,19,62,AD,BA,09,B7,3E,8C,99,7B,68,9C,B4,83,B4,1B,62,94,C0,C2,4C,1A,34,73,82,C4,F7,BF,EB,20,56,80,6D,4E,31,40,FA,04,23,2B,A1,48,C0,40,BF,77,7A,9A,8D,C4,06,CA,C2,0A,37,F2,C6,FC,A8,F3,2A,94,47,34,63,97,63,0B,CF,27,0D,04,C8,DF,5A,73,19,3F,C2,56,F4,50,92,12,57,8B,34,34,C8,CE,7E,62,68,D8,FC,B6,B7,30,EC,F9,7C,DB,6F,0D,E8,F0,85,00,EF,50,55,46,C8,57,20,9C,39,F4,B9,42,2F,9E,9F,CA,E0,70,F7,78,21,FB,DF,74,D3,D2,54,C3,DB,19,72,BB,24,7C,D9,0D,C8,10,FF,6C,B3,32,1B,80,24,50,DE,52,DE,41,05,49,48,81,51,13,EC,F1,E3,48,83,B3,AD,A9,13,B4,52,2D,73,57,C8,88,4D,F9,83,F2,CE,1E,5D,C1,3E,C7,AB,1D,DD,BA,D7,09,73,14,F4,92,79,CC,8F,1C,21,31,EE,08,BC,EA,82,54,2D,EB,C2,51,DC,D8,89,97,8A,01,AE,BC,1C,F5,07,C1,E2,2D,D8,50,FF,F7,23,D1,D4,32,AC,51,2B,5F,EA,E4,A8,6E,D4,27,E4,90,3B,F7,3E,81,99,E4,BA,CB,19,9D,38,FD,7E,7E,48,59,B4,74,4F,CF,0F,49,99,F9,FF,0A,FD,B7,08,23,55,67,81,CF,82,C9,5F,F8,8D,7A,EF,C8,38,6D,4A,CE,FF,06,06,9F,1D,74,6C,0B,51,63,8A,BA,E3,3C,D0,C3,17,A3,C1,AD,71,B9,09,DD,74,ED,E2,CE,86,D1,6B,87,A4,ED,EC,8D,32,21,36,20,EA,7E,B0,36,5E,6D,F2,2C,98,D1,E3,3E,85,8D,20,7F,BF,F9,B9,81,A9,24,68,03,FC,C8,5C,77,5D,38,F3,CF,B5,4B,5B,3A,B5,71,A8,F5,01,56,98,07,A0,53,AE,E5,EE,37,60,40,9E,BC,8B,50,8C,27,D6,EF,0D,0D,CE,46,05,FF,88,94,78,AA,D9,67,97,F9,87,58,42,E8,24,2F,D1,02,1D,D4,D9,EC,16,04,6F,93,DB,68,83,93,FF,F0,44,40,14,30,60,6D,A4,79,1E,02,01,35,02,E8,EF,1A,7C,C4,EC,0C,4E,63,8A,84,B7,7C,C2,8E,29,C2,98,4A,6B,89,B2,F4,A6,A0,67,15,1B,2E,08,36,1A,CF,47,6A,DE,DC,74,27,A9,7A,B4,3E,2A,B5,15,6A,B6,92,95,FD,B5,6B,4D,14,92,DC,82,2E,E2,3F,18,52,2D,1B,DB,D5,46,7F,47,A6,5E,ED,0D,51,25,0F,29,C0,ED,75,7E,4B,19,5D,70,E6,70,EC,D1,3D,5C,97,90,D0,11,D9,68,99,DB,80,86,8D,BD,F6,04,87,32,6F,27,2C,45,64,B2,1E,6F,04,D6,EE,42,89,39,9F,0D,2D,BD,DB,BA,A8,7D,71,1E,B4,D7,CC,33,B6,96,53,5B,24,76,FC,8B,D6,BD,8F,C9,D7,BC,F2,12,D7,11,CA,6F,50,2B,B4,5C,62,52,C6,B6,12,86,85,8B,33,5B,FD,2F,DF,55,3F,15,93,4E,C8,EF,2C,C0,F6,2E,EA,E0,3B,13,80,E5,10,ED,51,DA,C3,06,23,02,5A,E1,47,12,9A,3D,6E,67,DE,3D,35,5D,2A,36,FA,4A,26,C4,E9,4D,9C,7D,2E,F8,05,65,59,EE,89,32,3C,3E,47,BC,D1,08,9B,44,F6,14,39,1E,44,0F,9E,6E,D3,F1,BC,BB,8B,73,C2,E2,08,62,DA,87,C8,14,A9,25,C7,63,8F,35,4E,23,42,18,21,D3,F7,1D,28,87,99,05,E4,AB,4C,53,52,12,66,92,2E,94,23,4E,42,F5,98,4E,9E,3B,BB,B8,A7,58,B0,81,8A,1F,8C,A6,3B,49,91,8E,07,2B,6E,24,F8,5D,77,70,AA,D5,C0,F1,78,2A,89,90,09,56,37,85,83,A9,39,6D,CF,48,04,01,D8,F5,9C,9E,79,EA,08,60,97,94,25,B0,4F,7C,84,01,FA,0A,65,B8,92,18,5A,71,03,05,D9,9E,2F,EC,90,1A,7F,2C,3B,6B,07,32,00,5D,7D,1C,D4,34,5C,C1,D3,54,8E,02,34,51,32,E0,F5,4A,37,54,CB,C9,C0,56,29,99,BC,1E,49,3E,90,C3,6A,96,64,B6,15,A0,40,45,68,77,36,EE,59,2F,C2,87,96,90,5F,35,5A,80,A7,4B,9D,22,92,69,A7,0E,E1,4E,0E,46,77,E7,AF,C6,B4,9B,4C,E3,A1,A1,99,A9,1E,C6,A1,4C,2C,68,98,FB,72,7D,F1,77,A7,FC,7C,0D,D8,FD,54,FD,C2,55,04,A7,F1,B6,85,AB,33,3E,1F,B7,7B,33,64,14,E7,2A,BA,18,EC,07,53,C5,F7,5E,E7,71,29,46,B6,93,D2,E2,13,4F,53,9B,BB,12,C3,8A,2A,37,62,5F,0C,F7,CD,1F,9F,6D,2E,96,E8,25,B1,22,B4,B1,31,F4,1C,DE,9F,0A,D6,C8,69,76,A6,7E,75,49,BF,39,A4,F8,E8,5F,69,F8,24,AC,A3,22,99,3B,7A,68,3E,32,57,07,BA,60,A8,8A,0E,92,45,A1,1D,BD,A5,48,31,B2,B5,01,8D,4C,98,B1,1F,C2,F4,02,53,E1,F4,7B,23,5B,14,0C,AC,3C,DB,E8,68,EC,D2,5C,AD,70,C7,BA,73,F5,4B,6A,65,65,F1,26,8C,11,A8,F7,89,8F,8F,95,7E,31,2E,6D,26,93,C2,A4,76,02,6F,82,8C,AC,02,15,01,57,97,AE,CD,05,09,15,8B,B0,63,95,44,C3,0B,0C,92,F6,22,39,24,6A,2B,E9,A2,31,F6,F7,06,6D,D5,78,80,F0,9F,03,3F,B9,6A,65,BF,DD,84,66,1E,6D,8E,C9,31,C0,22,0A,D8,42,5F,DE,05,2C,36,3D,C1,1D,BE,D4,4A,1F,90,B3,21,39,6A,C0,9B,BA,DB,3B,68,C6,AC,50,CF,77,81,75,F0,02,5C,6C,75,7E,48,62,7F,16,C7,01,0B,3E,E6,F3,C3,B1,80,6A,9E,FD,D0,D9,8B,2E,5E,1D,1F,20,89,09,94,8E,5F,0A,AB,A8,85,61,90,AE,77,B0,82,D9,21,4D,FB,A0,EE,FB,0C,81,E3,A2,F0,FE,7E,D0,90,A3,C2,6B,64,30,05,28,DE,EF,4D,D8,B1,2E,E8,C9,66,F4,4C,FA,C0,B2,35,0E,A8,EE,0B,5C,A2,A5,69,6E,62,1A,42,87,1A,1C,79,5B,25,6E,35,37,26,27,F0,DD,7E,AA,6A,D4,6B,A0,2C,AC,F3,CE,B7,85,D8,FB,52,66,BE,63,56,BD,02,5A,A6,94,80,74,A7,A7,92,36,0F,C2,E2,A3,8B,97,17,96,5E,1E,6D,18,F4,5E,4B,C2,3D,AF,20,03,42,A5,52,81,06,7E,B6,AA,C7,6E,F2,C6,EE,F1,64,3C,04,27,8E,37,B3,79,A9,A2,2E,70,CA,76,4A,34,B4,28,3A,17,AA,12,A7,5A,70,4B,6D,AE,94,B9,12,96,DA,F1,0A,59,A9,0C,86,92,13,77,A3,D8,DE,13,BA,16,36,76,6F,7E,24,E9,C8,7F,8D,3A,D0,FC,01,FF,E0,29,59,43,4F,2D,30,FC,D2,F1,49,7A,CD,A8,6D,29,9D,BA,C9,57,45,7B,1E,8E,29,EB,AC,B9,6E,37,07,62,7E,C6,73,CA,8C,38,E6,FD,AE,78,D4,78,19,89,8A,C1,1A,8E,44,84,4A,38,DC,88,73,F3,A3,DF,DC,75,6D,86,80,27,DF,78,85,10,29,7D,ED,F5,A3,AE,A7,EF,A1,A8,69,16,6B,EA,B1,45,B0,E1,38,A5,23,5F,B6,B7,65,5C,B4,F4,83,09,C9,23,E2,E7,55,FD,68,A4,82,5D,57,27,A9,68,94,B8,2D,D9,D8,57,0D,B4,D0,A9,80,77,8E,4F,33,F9,F7,1F,05,3B,59,DD,F4,1C,65,67,EC,52,3E,90,A0,57,33,11,C1,07,DA,36,C9,B8,56,B6,70,91,88,22,DB,7B,D2,A5,A1,D1,D6,A6,58,CD,00,BC,04,61,8E,82,3B,BC,D5,63,E5,AF,90,DC,5D,89,0C,FD,77,EA,FE,4C,F4,98,26,F8,B1,4F,95,D1,06,DB,9C,F9,50,CF,D1,45,A2,32,6F,2A,32,B4,9C,E7,FF,29,DF,99,A3,6B,0D,D2,98,D1,EA,B0,11,78,F1,03,A1,36,40,61,76,E2,46,85,35,7F,48,D0,0C,21,0C,07,04,AA,C1,62,54,CF,6C,3F,28,EE,79,23,1F,B0,D6,B7,7C,78,4B,E9,C0,69,54,79,96,08,25,78,AD,BE,18,59,5C,10,CA,DF,3C,FA,05,C9,A5,5C,92,F5,CC,A9,E2,A0,65,70,4F,B7,28,C8,C9,A0,AA,67,49,A0,AB,BD,E0,AA,01,CA,4E,76,B4,8D,53,F1,29,06,74,D5,98,6A,8D,CD,41,E6,EF,F7,9E,D2,36,E1,B6,B1,AB,2F,1B,1E,3C,4F,31,7F,7D,6F,A1,A8,FC,A4,5D,BA,CC,4E,3C,58,EB,E6,FA,3B,7A,F9,3A,23,70,D6,60,70,70,4E,CB,74,AC,32,52,19,49,62,FF,93,89,95,85,D0,FE,0B,9B,29,E7,D2,9F,BD,9E,C2,3F,23,B8,21,C7,1F,4C,2A,5B,5E,A4,0A,34,D1,18,19,C1,9F,B3,36,7E,62,E0,63,FA,C7,AE,D5,59,3E,37,9E,37,18,5A,2B,43,9E,89,88,BF,B7,D8,85,09,FD,3B,D6,BF,8C,77,1E,3A,3C,8E,32,8B,BD,FE,02,15,7C,FA,93,9F,6A,A8,69,A4,A7,C6,58,D0,00,1A,F2,C3,2E,4A,FF,FF,2D,55,AE,62,13,E9,26,FE,65,39,C3,D4,18,87,FC,F9,EC,F4,1E,90,D1,36,74,81,98,C2,0F,7A,6A,DF,1D,0C,73,67,B9,4F,49,E5,75,64,EA,8B,78,9A,DA,40,B8,06,1F,F9,99,14,D4,42,44,7F,5B,04,C1,07,A0,1D,4B,4C,BE,62,F4,D2,9C,D9,9F,D6,7E,5E,36,B6,D5,0E,4E,C2,BD,9E,02,D7,02,30,61,39,26,F6,5B,5F,2D,90,EE,A4,2E,79,92,4C,4B,23,7D,49,86,E5,47,EA,FD,76,F1,4C,B6,DE,22,3B,5D,90,33,F4,06,C0,DD,AA,2A,05,E2,B1,D6,1E,EF,8E,0B,91,79,F3,EA,3E,74,C1,3E,85,D0,04,A9,5A,4C,AA,43,EB,C5,CC,65,4C,5A,8C,6F,22,07,23,1B,0C,56,9F,87,7F,5E,71,5D,F9,71,09,B1,7B,CB,3E,58,82,75,64,C4,A4,7D,82,B9,CA,AF,86,BE,78,CD,0D,A1,F0,45,31,D2,C0,FD,19,91,4D,7E,96,88,FF,BA,17,6C,08,38,2E,26,5F,69,7B,E4,56,38,6A,53,4B,E1,DF,43,57,8B,93,8D,B0,E9,BA,E9,FF,C0,37,2C,9D,7E,CD,E7,A5,41,63,83,09,FF,E1,AF,E2,97,28,7C,4E,07,C8,9C,A1,AD,B0,53,F8,E6,C6,B8,9C,7A,F1,AE,E2,06,AD,20,36,AB,31,C1,12,D8,A8,E4,F6,B0,3F,0C,AB,B9,B4,5B,98,B5,78,11,55,51,B5,69,34,8E,62,6F,3D,28,05,C1,BA,50,57,65,94,5F,85,AF,36,08,B0,38,BC,D8,55,BF,61,CC,77,01,EC,25,52,77,38,C8,CA,DB,AB,7A,D8,44,34,87,AD,87,FA,7D,86,42,DE,17,FC,8D,A1,48,07,EA,68,9E,D5,BD,98,0F,AD,EB,20,A0,7E,1D,3D,DE,86,8D,14,FD,7A,65,17,0A,CA,6E,2E,0D,A9,CC,06,0B,17,43,9E,60,A9,1D,1E,97,C8,C3,8D,54,B9,F8,8A,C3,23,83,D9,A6,6A,6C,17,4D,F4,0E,B8,3A,30,D9,88,A8,05,A4,D2,A3,B3,E6,02,DC,5F,64,43,C5,2B,56,78,84,9A,93,18,DB,5F,36,B2,6D,50,B5,6E,52,F4,54,05,E6,B2,2F,E1,00,72,05,E0,F6,63,01,E6,EF,AC,31,04,09,D4,D1,FE,A2,D0,5D,83,DB,D2,71,A8,DF,CD,F6,7D,43,76,AA,DC,D5,EC,E1,7D,2B,8F,F5,7B,03,55,6E,31,02,96,49,E4,FB,9A,55,93,F2,96,5C,00,8E,D9,9A,D0,00,7F,97,9F,3B,CA,B9,A3,51,07,C9,C0,DE,CA,34,63,B6,31,97,D1,11,AE,1E,42,67,34,2F,70,C0,98,8B,50,12,21,EE,1F,B1,06,4A,86,22,67,BE,88,B1,26,5C,2A,90,6A,A9,A9,2E,10,00,CA,AA,93,D1,D0,BD,04,3A,EC,79,F0,DA,70,07,42,EC,AA,02,A6,FE,1D,C3,9E,42,88,2B,0E,E7,10,6B,70,CF,D3,1E,DA,7B,22,05,95,78,33,3E,C7,08,96,44,9E,C4,2B,E9,E1,F0,12,6B,17,9A,35,F2,31,40,90,B0,B2,36,4D,98,B2,FC,C6,E5,4D,83,43,66,88,E6,0D,CA,DF,B5,B6,2F,96,4C,76,B0,5F,3E,2F,75,FF,CB,6F,8D,5E,78,63,A3,7E,62,B4,8D,D4,9E,DB,2E,4E,DB,E1,82,92,9D,38,C4,05,20,3C,57,C9,BF,B2,C4,A1,E6,9F,40,2E,5C,3F,55,4E,B5,6C,3D,20,17,DF,9F,22,11,34,3A,38,C2,70,31,2C,2C,C9,ED,E9,AC,10,D4,C2,4E,93,7D,9A,38,D0,1E,4F,C3,7C,01,D1,FF,91,AF,E0,2A,6B,57,83,A5,26,B3,7B,51,2E,5E,CE,C5,28,EC,19,83,5A,95,9A,02,6E,5D,03,6D,1A,AE,65,11,5B,D6,16,A6,1E,03,C8,32,5F,82,DE,A7,C2,4D,0B,F1,23,3F,66,FC,EC,60,AD,A3,9C,B3,FD,0D,3C,94,22,AB,86,47,42,CF,C4,70,FD,68,BC,E6,F6,20,99,9F,19,5A,3C,0B,18,33,A8,29,40,A7,BB,FE,01,93,68,5D,DC,D8,9F,E5,D9,79,5E,06,0D,2C,BB,20,F4,57,82,B5,BD,EC,84,90,3A,9A,E0,88,CF,9A,88,BA,8D,C3,00,FD,7F,9D,B0,6A,2E,9B,80,03,5A,62,3E,41,B3,04,D7,D6,0B,59,E3,E6,52,59,50,7C,2A,CD,C4,E4,4F,59,54,CA,DB,D5,05,0A,C6,C0,E8,79,C7,BC,6A,D9,95,F2,B7,E1,6E,4C,EE,CB,23,41,58,1D,C2,FE,B3,33,13,20,42,62,3C,C9,C9,61,23,EE,A5,7F,60,24,B4,EC,8C,15,39,0E,AC,00,7F,7C,A8,9E,F3,FE,28,45,7D,F6,46,B0,52,C3,D9,A5,1A,3A,7F,DD,11,38,AA,38,D0,85,DC,AA,B7,BE,43,0D,CD,36,06,F7,20,EA,F6,F9,35,3C,0B,7B,9C,0A,3E,BB,57,22,04,EC,68,FD,3A,14,BC,45,D4,F4,6A,C2,C5,84,87,83,E0,54,33,E3,16,FD,F7,C9,3F,C3,B8,A4,04,48,49,9D,78,20,38,E4,E4,0E,70,7A,61,FF,EF,C1,AD,34,F1,72,C2,6A,2F,DA,DC,3C,84,C1,C2,36,42,09,96,BB,B8,1B,58,DC,99,AE,4B,BD,44,42,F2,9B,B5,0C,46,D6,A4,52,99,B3,68,9A,60,41,CF,FA,4E,FB,50,85,6A,ED,10,56,28,2F,F5,D7,02,52,05,BB,1C,7E,65,7C,00,FD,B0,9D,96,52,1F,8E,54,EB,98,AA,E6,B1,94,28,CB,48,3C,55,9C,CF,74,7F,48,DD,18,94,FA,85,A3,DF,56,06,57,0F,FF,4A,FA,DE,65,C5,DE,2D,C4,0C,86,4F,4C,58,A0,3C,79,32,5C,56,DA,A9,09,A7,8C,A0,1A,C8,C8,C1,B6,35,94,58,DE,CD,A1,A2,D8,C8,78,17,36,1A,04,3C,78,66,31,ED,4F,40,D5,1A,A9,FC,43,F7,EC,DB,F3,8D,39,3B,32,18,31,00,00,69,16,D4,DB,AF,B6,C6,00,EB,15,E9,23,69,8A,1B,9F,1B,B4,CB,B0,15,25,2E,CF,47,4B,50,03,53,72,1F,7B,31,5A,9A,53,8D,16,85,E8,AB,CF,17,27,9D,7F,1D,F7,9F,FE,7A,29,27,03,04,70,EF,BF,E2,90,E6,3B,9F,9E,92,81,A7,E5,05,F0,2D,6A,85,81,72,01,0D,49,91,71,DF,E0,8F,A5,3F,CC,55,2D,B1,D7,97,7D,C8,93,0A,D3,92,C1,DA,8E,24,66,43,2C,8B,62,4E,9A,73,0E,E9,4E,45,A9,28,0B,B5,03,59,12,8F,0F,1C,4A,EF,9A,27,BB,95,AD,2A,AD,BF,E6,77,8E,49,F2,5C,5F,2C,0A,8F,F5,02,F5,D3,A1,88,39,06,6A,39,24,45,F9,95,E6,20,7C,6D,C0,BC,00,97,4A,F0,95,58,99,FC,49,E2,71,E5,D7,E2,5D,9A,97,E6,5A,A5,1B,1A,5D,92,FF,87,96,39,C4,E5,F0,6C,A4,C3,66,C3,49,0A,07,15,BB,EE,4B,C4,62,7C,15,28,70,82,CB,33,30,F8,4B,59,C1,32,BB,B9,ED,49,FC,F3,F3,80,02,4B,D8,F1,CB,D5,81,62,AF,C5,A9,A1,F9,9B,E3,40,55,73,08,F0,6D,0B,3E,0E,B4,56,8D,07,D7,7F,C0,7E,DA,32,3F,92,03,F2,D8,49,A6,E3,73,65,99,13,5B,5F,23,67,9D,C8,72,9A,78,36,90,E8,B7,82,58,21,34,44,74,C1,FC,68,7D,A6,AD,2C,B1,BB,28,2A,AC,4E,C0,A0,BC,EA,BD,F3,B6,05,8A,5F,0D,BA,88,C5,E8,7C,EF,CD,76,37,27,76,7F,47,45,3D,06,EC,70,E5,DC,F0,42,87,7E,CF,00,4F,CC,9A,D0,1A,C3,F8,10,82,DA,92,94,B1,D2,F1,58,3F,49,0F,2A,80,96,A5,BE,38,6D,60,13,E7,65,7F,AB,39,2B,B8,D5,6D,AD,D3,C1,7B,72,BB,9D,9E,76,FB,F1,24,6F,E3,4E,1E,72,72,F6,BF,2B,20,B4,F7,A5,9B,4B,D6,89,C7,08,44,CD,2C,FE,4E,C1,62,2F,D6,00,18,12,88,47,92,77,C2,FF,1A,F8,01,C2,3E,9C,72,EC,D1,DD,10,43,34,E1,11,69,2B,0A,36,4D,71,7A,67,DA,DA,58,F7,C2,AF,4D,E5,74,B1,A0,85,AA,A9,A5,22,94,FF,71,32,F4,17,AE,CE,63,48,75,0A,F6,4E,27,32,D4,CA,59,59,01,4C,7F,66,B8,E2,12,9E,71,7B,D3,BD,74,55,A8,22,FB,01,CA,D4,11,B0,C7,5D,FE,21,BE,B8,FE,66,88,7A,94,5D,1D,56,BB,BE,39,4D,9B,4D,82,5E,03,B2,53,3C,FE,57,8D,C7,08,92,1A,34,20,1C,48,04,88,33,61,EF,78,50,34,03,82,6F,A3,6F,32,22,85,C6,79,C0,59,11,BC,40,0D,EC,32,9B,35,49,1B,9C,6D,98,D2,63,0A,DE,EC,4B,DE,1C,EB,9E,2B,48,E0,AA,C0,19,68,BC,24,A1,8B,5C,A7,2B,8A,38,84,3D,AA,17,98,F6,A2,A4,96,E2,69,31,C3,C5,0E,84,CD,77,44,1F,B7,C8,BB,BD,92,AA,07,07,CF,D4,19,DE,A7,E9,B7,AA,97,6C,F6,A0,D1,3D,9D,6D,85,5A,22,13,77,FF,04,AA,79,5F,94,23,5E,63,56,3F,2F,8D,14,20,56,5C,9A,C1,2F,9B,1A,4A,9C,A3,41,3F,79,1A,B5,24,E1,A1,62,BF,4F,40,E2,73,5B,9D,C9,45,B5,36,67,A5,D7,D9,B1,49,01,FC,48,E0,51,7A,7B,CC,56,40,20,13,70,19,FD,E1,3D,F3,C3,E1,A6,D3,BE,FB,90,FB,71,1D,51,2B,72,04,0D,B4,0C,DF,A1,9C,E8,CD,8B,2F,86,7F,B7,57,83,43,EE,E1,46,E8,F9,58,0F,1B,4E,36,5A,9B,BB,A9,5C,7B,3A,AA,50,62,B3,7C,2A,F7,C9,9D,8C,65,CE,07,60,69,7E,80,10,15,9C,5E,F7,54,01,3E,FB,C9,09,C9,0A,37,4B,AE,60,F9,64,6D,FD,CF,CB,40,F3,4D,E1,BD,BE,38,01,2A,10,58,F3,54,C5,35,79,A6,61,7E,66,E0,E2,5B,34,0C,AC,18,FF,29,D8,FF,5F,4A,0F,E1,A4,FD,6B,FD,1C,F8,15,3E,7A,04,58,8C,0C,78,91,DC,6F,79,00,11,B9,6B,FA,7E,93,73,E2,A5,85,94,43,2B,08,59,38,87,89,D1,2E,67,E0,BF,96,70,07,BB,67,EF,A4,29,17,11,C9,CF,AA,8B,36,82,4B,DE,45,EF,64,6C,AB,AA,0B,F8,94,0A,88,1D,09,A1,C6,EB,84,F2,54,7D,39,EE,57,0F,C8,51,2C,C6,8A,5A,F7,86,C1,2C,21,21,E0,51,56,C4,92,37,2A,18,AF,AB,3F,9B,D5,24,8C,D9,F0,8B,34,47,00,9F,32,CF,E4,ED,2E,46,6D,1A,1B,14,73,85,58,34,06,28,48,E0,63,1C,5C,BE,80,30,42,E5,A5,1C,7B,DD,1D,CB,2E,7E,52,E4,9C,24,CA,9B,36,52,29,DD,50,79,C4,3B,5F,02,70,D5,5E,B4,47,EE,91,97,21,22,C1,B9,65,0E,EA,A1,05,3D,54,38,47,80,66,61,16,FA,D0,4C,A6,DE,BE,C8,81,D6,1B,2A,80,58,DA,15,3C,5F,63,18,A0,2C,20,7F,75,72,B2,9B,98,63,40,99,EF,D0,E6,21,34,96,24,60,00,35,57,B4,98,C5,40,A9,C3,8A,D8,01,CA,A8,3E,06,96,FE,33,97,A4,8B,78,5A,9D,68,1E,12,24,09,7C,28,64,78,5D,FE,97,5E,5A,2E,BA,E2,A6,A1,2D,76,1E,7C,67,A3,2C,C2,35,A5,6F,C2,86,94,52,68,2C,B4,E7,37,5D,46,F7,78,A4,28,C6,7C,18,6F,D1,F4,2A,51,2E,85,F6,36,CD,D7,70,E6,2C,47,03,4D,B4,A6,05,77,44,78,E5,C2,C2,90,66,67,75,18,BB,D8,8A,F6,0F,28,56,07,BF,98,EB,80,AE,8D,90,C0,99,4C,A5,75,1B,66,8A,3E,C1,4B,7B,4E,C1,69,B7,33,75,3B,F9,11,C2,A4,3E,17,85,79,E5,8C,CD,97,6F,B2,78,55,94,AE,D6,F8,36,B9,C0,2C,9F,5C,1B,B6,F7,BB,20,6B,46,1E,B4,9B,0C,08,3D,4B,D0,04,A1,5A,FF,AC,76,16,52,4B,B9,21,8D,12,2B,0D,72,B9,D1,43,9A,C3,72,4D,A5,DC,55,10,6C,33,A4,99,C1,AE,B8,96,F1,4B,FC,BE,7F,9A,9F,12,16,C8,A5,B4,94,5C,CF,5F,A8,30,A2,8B,E1,B1,ED,CE,22,6F,F4,02,B1,EF,EB,4B,A6,8A,B2,37,16,DE,8A,CC,B8,36,B2,96,D9,C4,0E,6F,8E,47,B3,85,1C,A0,6D,B0,38,EC,A4,45,DD,EB,23,D8,A2,3D,22,26,3D,F7,12,17,A8,2F,1D,E5,82,52,CE,D3,9F,E8,44,81,7B,27,A8,1E,D2,80,5E,FF,BA,50,F7,02,72,01,B8,1E,CE,65,54,5F,EC,7C,AD,93,1E,0E,A9,F8,EF,1A,E1,73,9A,32,DF,37,60,05,A9,A6,B6,E5,94,83,CB,23,A7,49,50,1F,07,A3,00,CF,D7,FA,0B,3E,A4,84,D7,5F,08,7A,D5,8A,04,94,BE,46,20,FE,C0,FB,76,E6,B2,59,C1,96,21,4E,42,BA,07,B7,09,99,50,FF,88,28,CA,D3,5C,A8,91,61,55,FF,58,50,E4,FD,A3,ED,7F,D2,BF,E0,9E,E9,D6,9C,74,67,A1,EC,58,58,8F,CC,C7,36,10,00,B3,B3,21,BC,6E,66,CC,11,E2,BD,1A,76,95,77,E7,F7,FF,79,10,03,4A,64,53,87,99,A5,15,A0,25,C5,19,3D,69,6D,0B,78,58,FB,5A,D7,D7,24,62,6E,33,D6,33,68,76,A5,DE,BA,4F,DE,D0,F5,2C,E5,DB,36,0A,91,F0,F1,C5,E1,9E,46,DF,E7,34,16,A3,C6,D7,BD,65,98,CB,99,42,86,82,29,73,47,5A,97,75,21,25,78,AD,AF,13,30,ED,34,E9,B1,7F,B2,1C,70,75,B0,15,9A,16,EB,9B,01,0E,B7,97,9C,AF,13,38,61,2F,F7,F5,DC,5A,84,83,CF,E9,B8,B9,9A,39,6B,F8,A1,37,74,0E,87,E2,75,4B,20,D5,EE,FC,E2,12,D8,7F,D8,CB,44,AE,43,C1,66,3D,00,6D,35,4D,CB,DB,3A,94,B4,91,3C,84,F8,74,86,C8,6A,61,03,17,1B,65,69,22,00,AE,7A,9E,A9,9B,5A,B6,9B,40,9B,E0,07,C1,D3,E6,29,24,CA,BE,CD,7C,02,8B,2A,D4,75,D6,0E,54,1D,90,A6,C3,AF,2B,22,E6,F9,00,47,B5,D8,8C,3A,7F,AA,AE,C5,53,EE,63,E2,A9,AC,C1,37,DF,E8,17,2C,2D,E8,7C,EA,03,6E,CE,1E,24,14,D4,20,00,86,76,13,E2,A3,EA,91,6E,33,A2,3C,20,9D,FD,25,26,65,B3,5E,D0,C1,AC,10,58,09,CA,54,AE,EB,97,26,D2,1A,A3,78,A3,08,CC,DE,EC,E2,7D,DD,A3,84,D8,8B,B8,AD,39,ED,0D,BE,E1,1A,21,97,25,19,48,69,EC,47,30,AF,6F,42,5B,6E,FC,10,4E,92,0F,73,0E,E6,27,B8,8E,87,3A,89,C2,04,28,6D,4D,5D,82,ED,B0,2B,C6,90,07,F4,86,37,4C,8F,A2,85,DA,58,9C,CE,01,D0,94,85,87,93,90,62,1E,4C,AD,6F,E0,EB,A6,E6,A7,34,97,62,5F,0B,76,6B,4B,DF,2E,07,A6,4A,C6,91,FC,B4,FA,A2,8B,AD,5B,F0,78,E7,27,42,37,D8,E7,E8,A3,E4,47,45,0C,CB,8E,58,53,24,A6,F0,61,32,91,52,23,DC,84,C2,2F,02,99,35,19,4D,A5,59,B9,18,12,F2,C0,BF,7E,A6,B6,74,38,0E,F9,77,3C,A5,55,40,1C,F4,F6,46,18,D1,A2,BE,14,C2,5D,14,FC,DA,F8,DE,4E,66,F3,ED,E3,75,EF,1C,90,63,F5,B6,98,B8,DA,4B,E7,80,1B,1A,BE,B2,64,D5,C4,A7,7D,4D,5C,6E,CC,7D,A1,00,3E,0C,92,82,4E,67,42,66,43,D6,0E,93,3C,3E,BE,20,1D,85,40,3B,2A,29,61,BF,71,F9,8B,72,5C,F2,A0,A7,03,29,97,E9,C6,31,24,63,9A,60,68,83,EC,A9,00,95,21,3B,5D,85,21,F4,2A,C0,AE,46,24,D3,00,26,34,2F,AE,76,8A,3E,8C,2A,3C,82,3F,C4,32,72,A6,57,6F,6E,09,24,50,4A,2C,CA,FD,0D,94,34,54,3C,8E,B7,F6,96,3F,9D,88,D1,EB,CC,8A,7E,A8,9E,30,D0,74,72,A7,5A,E4,92,AA,5C,15,FC,86,76,31,49,0A,46,C9,D2,C5,B6,FB,FE,89,7E,16,DD,92,9A,EA,53,5E,D4,3A,18,A8,59,B8,40,78,57,D6,75,0D,AC,06,74,D7,63,94,9C,B8,E8,A7,1E,F4,4D,83,A2,FA,D7,F5,F6,3C,7F,98,85,CC,60,11,85,B5,99,EF,75,B9,A1,F9,D9,83,73,37,15,7D,35,4E,38,BD,31,71,A9,1F,DC,A2,B7,A0,69,E8,D8,C6,30,0E,3A,CC,8D,6A,F4,20,59,AB,28,37,C0,89,55,3F,48,90,5A,75,18,4E,C1,93,19,FA,B4,A0,D8,81,13,8E,96,5E,F0,AA,49,59,D1,15,40,EB,DB,6C,5B,97,E9,58,54,15,AA,E2,5F,28,8F,FC,B4,02,56,22,02,4B,BB,32,2E,64,85,3C,8F,6F,AD,1B,F1,B5,E5,31,2B,9B,D7,73,FC,98,1C,3E,16,1E,F3,B2,B5,BD,B5,74,4C,01,B7,64,82,3C,3B,01,AA,C0,18,7B,15,76,D2,C7,06,D2,32,C0,DB,3E,0B,37,81,86,C5,C4,52,50,A9,6E,54,8B,68,75,F2,76,71,99,99,50,1D,AD,A3,ED,67,BC,54,36,83,DA,00,51,23,E7,D5,31,E2,45,7A,04,53,72,0F,70,62,1F,4E,15,36,7F,17,31,23,8C,C2,37,FA,15,03,6E,AB,4E,0F,4A,DF,64,CB,83,E8,80,5A,38,E5,54,45,D9,42,25,BF,CB,47,73,6B,90,47,C9,F8,23,FD,04,B3,1E,48,E7,50,7E,E3,22,B8,E6,80,54,55,FB,D1,D4,F8,D9,6B,1F,2B,47,34,60,60,09,E9,D4,B8,85,A1,69,31,23,78,F1,06,F1,30,43,71,95,E4,AF,90,99,B6,2E,0F,0E,B9,52,DD,3A,BA,87,53,48,B0,6D,56,30,6C,87,1E,FE,BE,63,42,3B,12,92,6B,5A,FF,38,5D,79,79,78,05,E2,83,DA,58,D9,EC,9C,88,FD,3C,DE,E2,1A,90,6B,B8,B6,3E,47,ED,96,50,70,6C,3D,15,F6,9F,02,3C,DC,FA,9B,EA,A8,F1,51,C2,84,9E,5B,79,9F,57,AB,1C,9F,37,7F,89,6B,33,2A,AC,FE,E0,81,2E,E7,4D,0C,7C,5E,58,3B,B4,91,CF,EA,DD,DC,1C,39,81,FB,F1,73,B8,CC,7D,F4,8E,5B,8D,6A,CC,E5,FE,CB,E8,CC,84,CB,FF,28,64,6E,67,5E,EC,5D,54,58,38,E4,BD,D3,69,2F,F3,81,FE,D5,4A,64,E5,CC,15,86,4C,D9,03,C3,16,69,5E,DA,36,DA,43,14,3F,8C,EC,FB,C0,45,82,01,02,51,6D,74,0E,A1,71,62,B7,D2,90,E3,74,58,15,C8,64,5F,0C,86,01,68,DC,31,BC,B2,E4,BD,F4,60,2D,72,51,B5,0F,C3,2B,FA,55,E3,E7,4E,46,2A,FE,C0,2D,93,D9,FB,23,04,49,AD,AD,CF,5C,E5,44,B7,2E,CB,E9,5C,B0,1C,CB,DD,DE,17,29,9A,98,A8,68,F7,52,12,4A,BF,9A,C4,48,08,BE,A5,80,CB,D6,10,D8,F0,65,F3,3B,F3,D9,AF,88,E9,F8,FF,0F,D0,28,EB,FE,C8,34,DE,06,2E,02,16,B0,84,C3,FE,8F,A0,43,45,54,B1,12,9F,AF,B7,2E,14,B9,59,F9,A5,49,C2,28,7D,6C,6B,34,A7,4A,A5,B0,3F,01,4A,18,62,8A,7D,35,FD,E4,CB,49,69,02,14,38,BB,61,86,FE,19,7E,CF,3C,53,8C,4F,43,90,96,F3,F1,C3,C3,2E,5A,A2,6A,EE,F1,39,24,15,C9,56,9A,B3,0D,35,55,77,C5,95,44,A2,06,55,DD,C8,5B,54,26,EE,99,7C,6A,EE,BE,15,87,05,2D,70,BF,33,DD,0B,8D,DE,86,AF,FA,87,9E,8A,B9,56,51,B9,29,6C,EA,23,44,F9,93,C0,BA,D2,8C,81,70,9E,62,25,CF,DA,6C,63,85,E3,0E,7A,3D,1A,F5,B8,23,36,A2,7C,1A,48,40,54,B2,3A,C4,8A,37,0E,EA,33,DB,98,A3,EA,17,D1,B0,43,35,41,80,BD,23,CF,37,55,74,7B,A5,17,39,0E,07,2F,A7,E5,B7,FF,6F,10,EA,B2,ED,03,54,E6,BB,8E,9B,63,67,95,94,DE,7E,0E,49,94,D0,AD,F4,2A,9F,BD,09,55,FD,AE,2D,33,A4,82,98,76,BA,5F,A2,F3,8A,C9,D3,EE,00,13,60,2B,7B,5B,FE,00,57,14,8D,AB,22,35,99,A0,DA,1C,C5,A6,1D,38,FC,33,34,7A,67,05,EF,F2,23,38,33,FD,97,A2,E2,B4,EE,C6,D5,6C,E3,5D,35,EC,59,2A,B0,BC,4F,74,CF,5A,77,C3,B9,C6,A3,E7,3B,20,D1,46,CA,67,28,AD,E5,25,B0,7E,DC,4F,62,97,BC,97,6A,71,F8,B2,7A,FE,3A,10,49,E9,1F,31,B0,02,D2,BA,3C,F1,25,CD,12,A7,C6,76,17,6A,DF,B6,4F,66,45,01,6E,97,FF,A4,94,E9,6C,C2,9F,8C,83,5A,5F,A5,6F,D4,D1,1B,A5,B7,EB,C9,A6,52,B4,05,C2,D7,20,DE,76,12,2A,F0,60,C5,3C,65,04,DC,C0,20,54,97,B4,3E,72,20,E8,E0,1F,2A,41,9E,16,2A,79,13,63,00,31,4E,AB,56,EF,D3,51,15,7C,74,E1,3E,7B,05,EF,ED,B9,FD,C1,61,4D,D5,3B,5B,87,6D,54,07,DD,75,10,2B,09,C0,14,47,9D,7E,65,97,FD,F8,B6,A4,60,C6,40,3D,4C,FD,07,D5,5A,6C,F8,56,44,31,70,49,D9,9B,31,1D,0A,25,22,4B,27,2C,AB,01,95,79,DB,14,D5,44,FD,05,CC,C5,11,39,F8,6D,77,7F,28,91,8D,4E,3A,16,E7,77,33,12,BC,88,27,CC,74,8C,53,9C,C9,64,50,9A,74,9B,8D,49,2C,77,4B,69,C2,A9,77,D4,F9,ED,1D,55,76,04,DF,90,4A,9D,68,6B,E9,58,96,02,89,7E,4B,1C,CA,58,BB,AA,A0,77,25,27,21,D5,EA,E4,50,2B,9D,E0,2D,A9,F0,C1,FD,5E,DD,87,DF,80,75,4F,5B,34,7D,47,B5,59,94,58,04,EA,F7,94,81,D7,F4,DB,49,D5,0C,E9,B5,35,8F,DF,18,51,C8,7E,73,BD,F5,0F,D7,4E,1D,C0,B3,BA,92,72,B8,D1,69,8F,25,E1,AE,13,E9,2E,3D,39,7E,FF,9D,FB,D5,1D,95,A3,34,B0,83,58,EF,DA,C9,DB,E3,1F,15,74,A3,7E,C3,15,EF,4E,AA,F3,3B,D9,13,1C,1C,8F,3A,6B,E3,23,E1,92,52,AE,08,5E,1C,2C,94,CE,FC,7B,BA,91,7D,F7,94,60,8D,25,AE,B3,32,9D,D3,16,9D,84,98,58,EE,44,B8,55,90,37,A8,F1,25,84,73,5A,66,2F,17,7F,C3,11,5C,C8,6D,2B,97,2E,19,A6,06,BB,B9,BC,5C,71,90,B9,15,72,DE,DE,43,DE,33,4C,96,AC,84,B3,94,06,EB,BE,FB,4B,B0,B2,3B,7F,2A,28,CC,63,DA,08,16,31,DA,AA,99,11,81,21,C5,19,42,84,81,10,51,AE,B0,4E,09,FB,0F,69,3C,6C,13,E6,EC,1E,88,92,19,89,22,82,0D,D2,8E,F8,73,29,1C,81,88,4E,7F,3D,E1,35,24,59,C3,7F,F1,61,E1,0E,2F,46,44,70,60,F0,11,DE,31,F9,ED,13,23,DF,82,CE,7D,3E,61,E4,CF,FA,70,5E,B3,C4,69,01,D6,3D,35,81,24,13,79,4A,A9,E8,D8,B3,8E,96,41,7B,AA,0C,82,93,6E,69,65,5A,2B,65,80,D7,A0,7A,3B,9F,A7,AB,A1,B1,A0,69,E9,61,26,3D,E9,83,F7,1A,B4,6C,EE,00,15,0F,9C,43,28,FA,12,55,93,F7,71,DF,D1,7F,7B,FF,06,C4,56,5B,A4,FB,DF,3E,79,C6,65,7A,B4,2C,68,71,17,41,35,46,CE,E2,63,74,A6,97,70,F6,06,BF,73,17,43,AC,8D,AE,D3,FB,12,7B,37,99,A2,1C,D1,D9,5F,47,03,CC,53,63,CD,36,54,AE,B7,A6,ED,D2,F5,E5,AE,9F,71,A6,8D,D0,21,31,1F,01,AC,FA,58,A2,F7,0C,5E,79,65,19,FF,5F,95,F2,65,16,3D,55,AF,7E,82,8C,8E,C9,63,D0,9A,63,9C,49,F4,AF,A4,AB,E1,71,55,C5,C1,45,F5,F0,41,09,9B,44,32,5A,49,62,D6,DE,BE,5E,12,5C,C1,34,21,05,55,C3,2F,70,1A,AB,7A,4E,92,65,8B,D3,90,87,83,07,30,E4,FF,46,BF,15,BC,0E,E3,7B,53,D1,7D,44,30,57,3F,27,47,B7,61,A5,AF,1F,AE,FB,D1,AE,35,37,DC,0E,09,0E,69,7E,03,06,BB,20,5D,C3,6A,B2,3A,A0,70,46,4C,DF,FC,FC,37,4F,93,7F,CF,5F,CC,93,BD,0D,BD,97,F0,44,AE,43,62,C0,BD,1F,26,64,0A,C4,49,E8,48,6A,60,7B,A4,3A,E6,23,4B,DB,9F,E0,54,38,F4,76,70,13,9B,AC,49,84,AF,F8,22,E9,8C,30,D9,02,42,54,17,38,BE,74,3F,1F,93,61,E2,D3,77,A1,10,90,61,D7,15,20,A7,68,D1,A9,FB,AB,EF,54,F6,7A,F6,F2,04,4B,45,C9,83,2D,57,7C,7B,CB,79,60,4A,4F,5B,31,72,09,83,7B,47,A0,9D,37,13,41,EE,3D,53,5B,E4,B3,EC,67,DE,FB,86,C4,C9,9F,11,CD,1F,47,57,1B,41,4E,2C,1D,EF,5C,5C,AC,C9,90,A8,65,F7,41,E6,C3,85,9E,CE,B0,81,F0,F2,0A,03,88,2C,4F,89,7D,AD,E5,76,FD,E2,D9,37,53,F3,66,94,D3,CA,89,5D,70,D5,86,8B,FD,6B,CA,98,45,3E,13,6E,2F,F2,B4,F7,D0,BF,B2,23,88,6B,6D,47,F5,F9,A0,70,2F,0F,75,B2,2E,77,0F,F5,14,FB,50,AE,DB,CD,2B,55,BB,88,4C,7F,B9,26,2A,4B,8B,B7,B9,0F,B7,15,C4,C0,EA,0D,6F,1C,B4,A2,CF,FD,35,D0,B1,35,29,6C,76,A6,5A,94,F5,6F,E3,71,F1,8A,64,0B,33,93,89,10,FC,79,1B,E3,2D,23,79,2C,FD,94,36,F4,6E,F2,E0,58,16,F5,11,D2,8F,9F,5E,2E,18,C7,FC,DF,BE,87,67,9A,02,5F,1F,7C,B8,78,52,20,4B,A7,7F,66,D6,3B,58,45,13,99,5A,54,14,CC,C2,46,EF,9B,08,9D,57,91,4C,B9,28,CA,AD,B4,3C,78,25,29,CD,E7,AA,15,0F,61,6F,49,E3,4A,61,5D,19,78,D6,AF,09,2C,1F,2D,6B,83,6C,28,74,5E,6E,77,EE,8C,25,0F,CE,CF,42,4C,12,CE,AB,4B,E5,9E,3E,68,4F,65,25,17,65,01,43,F0,B1,9A,BD,33,A4,03,2E,08,2C,CA,4F,19,01,64,98,F7,D9,A8,B4,73,7C,23,61,FF,04,BF,B4,78,B4,FD,AE,F7,88,21,FB,69,D8,24,97,6D,BB,6E,AE,DC,35,2A,F8,47,CD,E8,5B,F5,79,77,B0,E1,B9,E2,D5,73,E1,2D,10,EE,DD,A9,CA,30,3A,E1,98,90,CF,0A,61,BB,BB,77,33,92,95,29,12,34,D1,47,FA,D9,06,1F,2A,F6,C7,51,93,02,9D,02,B4,0C,9A,4E,4C,C5,2A,42,0E,DB,C1,1E,0F,D3,EC,64,65,3E,B7,58,EE,7F,8B,4D,B3,A6,5F,3A,B3,5D,3F,69,F6,A7,08,DC,BE,4C,24,65,64,85,00,F8,1D,76,83,D0,3A,1B,E6,E0,3D,22,F8,64,FD,31,BE,79,C7,55,76,BF,CE,44,1A,FD,F6,2C,D5,09,B1,31,D9,EF,71,E8,19,1F,91,15,5C,7D,8A,D2,F8,F7,5A,CD,6B,BC,CB,E1,26,FC,C1,D7,36,16,5E,A8,34,46,7E,E4,1F,60,13,FC,E4,BE,E4,87,C9,A6,49,4B,2E,28,56,CB,7A,FD,6F,76,59,67,20,32,44,16,61,F3,94,CC,0E,E3,C3,F6,62,05,A5,CC,DD,8E,08,A4,F5,D5,32,43,B3,14,CF,0E,52,71,96,9F,2E,27,2E,6A,FC,05,74,07,7A,35,C8,89,5B,B7,12,3A,0F,92,4C,EB,1C,86,C8,E5,83,07,56,49,F8,FB,F1,53,1E,CC,56,61,68,CF,85,A6,F4,92,81,F7,2A,D7,81,96,77,AA,BF,A0,D1,DE,E0,5F,12,57,D3,89,BF,99,7F,0E,83,E6,76,E9,DE,A4,88,B8,8C,2C,23,98,B5,2B,72,F6,D7,76,28,B0,51,27,C9,ED,6D,12,DB,BF,C6,B7,40,F7,50,81,A0,2E,78,25,23,5F,A7,34,6B,F8,53,AA,C5,16,63,C5,DC,F3,6A,B4,DB,9B,80,10,7F,FF,2F,81,E3,B6,0C,01,B6,2B,D1,42,0D,4A,DD,75,06,38,68,4A,FC,0B,13,24,44,5C,31,70,51,DB,14,A0,DF,04,FE,DA,CD,E5,52,63,10,D8,B7,A9,33,F5,8B,EB,E8,12,57,9E,59,B4,2C,2C,DD,15,37,8A,4F,8C,54,D7,17,F2,36,83,9A,5E,3E,36,1E,80,01,CE,ED,93,12,85,C5,25,D6,EC,4B,45,5D,2F,59,1B,77,B5,1D,40,71,93,FB,7A,59,81,58,EA,FF,3F,42,AA,32,01,F5,72,08,33,32,E0,BF,F7,9D,AC,BB,E2,48,33,CD,C4,37,61,79,29,7F,63,98,8D,88,39,FB,F5,34,A1,3F,0F,D7,55,61,9F,F9,BA,F3,50,20,2E,FE,3B,80,B2,25,91,0E,56,0B,96,1B,36,3C,63,FF,F9,CC,74,3C,65,84,5D,7E,21,C5,5B,F2,0E,27,69,8D,FA,97,E9,07,9F,D6,73,BF,FA,51,E2,6C,52,8D,A2,FE,D2,A7,15,26,48,0B,47,56,16,22,BB,2F,80,02,0A,58,C5,CC,BF,9B,A0,70,7D,02,67,6E,F3,41,4F,96,AD,4B,AB,ED,80,3E,63,9A,DE,AC,07,56,03,F7,44,DD,74,E4,DD,F2,F7,02,24,6B,99,13,D4,5C,FA,97,D2,4A,0C,9A,FA,60,66,D4,AF,E0,29,61,4D,82,65,81,DB,8C,6B,67,AE,3C,4B,8F,1C,24,ED,E0,8D,A8,81,1E,96,96,F8,82,14,65,CA,CC,AE,94,F4,86,1F,E1,C7,A1,4B,E2,83,3B,EB,4A,9E,82,5F,9C,BC,53,88,45,22,5C,15,76,49,2B,98,9E,BE,64,D5,7C,89,AD,89,3D,CA,AE,6C,25,2F,CD,CE,24,1C,E8,77,1D,1D,2D,34,8E,8D,0F,B8,68,FB,78,D9,AF,25,B2,1B,E0,05,10,C0,EE,DA,DC,C5,DE,A3,97,E2,E1,20,A7,BC,2E,A7,CE,25,CE,6D,98,13,38,A2,E4,A9,A8,79,70,71,04,76,ED,47,58,90,9A,FA,5D,9B,E1,B4,98,95,38,16,C7,51,58,D4,A8,9A,95,E0,90,CC,E0,F8,1D,ED,BA,4C,09,BA,D4,81,B6,C5,07,9C,20,09,4C,A7,55,08,7C,54,80,59,1C,C7,14,88,2A,AF,64,F3,7A,C5,29,1E,9A,60,B4,1F,5C,84,4A,64,23,78,F9,13,B7,EF,76,C3,D2,4A,71,EA,B2,D7,1B,54,6F,57,73,C8,99,F6,54,CD,36,CB,CD,5A,64,D9,6E,F9,CA,65,19,D8,EC,4B,FB,75,E6,BA,14,40,08,70,A3,B5,34,3E,6D,14,A2,8F,B2,80,1E,CE,0E,A8,63,DC,76,EC,A0,EC,94,DB,88,FB,10,70,F7,68,47,39,6A,2C,19,30,C2,A7,B4,8A,F3,8B,CE,C2,56,FD,BF,EE,C8,5F,B2,93,32,69,83,30,7E,EA,4C,C9,11,8E,80,AE,E4,38,A1,31,52,11,3F,27,46,C0,4F,D0,A0,C6,4E,13,A3,6B,C4,14,B2,88,A8,68,F9,2B,4F,34,1C,CF,4B,9B,FD,4E,32,F9,6B,48,1E,33,A2,7D,01,45,58,6D,AA,F9,8E,52,EF,54,5E,71,FB,8A,B6,26,35,35,45,69,05,86,90,6C,48,3F,9D,56,A4,F4,30,35,23,58,9A,A5,C6,15,09,8E,4B,18,8C,5A,6B,29,63,10,75,A5,B4,85,A5,42,A7,B0,24,DE,58,97,F9,59,60,5D,A7,BE,E8,0A,0E,5F,29,93,4E,69,F9,C7,B4,B8,F7,3A,38,AC,09,6C,AC,8F,E6,11,97,60,ED,5E,8D,8A,C3,2B,D4,ED,44,C0,BC,64,E0,95,37,9B,D2,CD,6B,B9,7B,C1,45,19,4C,9D,43,82,B2,8B,FB,70,CE,C2,7F,CD,24,50,21,3A,7C,82,BC,52,C1,AC,5E,0D,60,78,8D,F3,C9,2C,E2,1B,A6,BF,5A,51,09,D5,62,89,DD,C6,DE,2F,AB,0A,28,F5,BC,B3,DC,0C,56,F0,34,3C,5D,5E,41,30,59,26,AD,3B,51,9D,5A,9E,AC,EF,03,67,C2,06,33,0F,42,77,85,68,6E,51,09,AA,24,48,4F,65,D6,E5,8E,F6,31,6E,0C,0D,DA,68,BF,A5,03,62,7C,E1,D4,B4,76,0F,CF,35,6B,0B,A8,6C,03,CF,04,6C,7A,6B,DF,6B,D3,DA,57,83,FC,BD,F0,64,F0,D4,F1,D2,5A,6D,D9,F6,A8,31,5F,B2,2B,80,42,41,D5,A7,C4,48,7E,BD,E6,FB,E0,B3,1F,91,0A,69,34,C4,B4,07,29,16,C5,C7,C8,CF,10,53,E8,F5,26,66,96,70,89,BF,AE,5D,58,68,2B,B6,98,AC,EB,85,13,60,66,7F,E3,A5,85,FF,76,90,E3,A0,97,D9,F9,92,67,0F,62,A3,2F,05,C8,92,C3,B0,3A,CC,35,6E,B0,A4,A0,6E,C9,7D,D7,21,80,80,14,F3,BA,FC,4A,C9,B1,46,83,1F,88,07,58,40,86,63,A3,95,1E,AB,CD,1C,80,85,D0,D6,4B,A5,77,69,62,ED,18,59,B3,98,60,42,AD,84,3D,22,A8,2B,7E,6C,30,53,EC,FB,0F,37,EF,4A,F1,78,54,27,B8,81,D2,90,DC,35,35,52,5C,E9,30,B2,08,1F,2B,50,C4,EF,07,40,70,87,3B,AB,23,73,3B,2D,01,E3,5B,A7,79,8B,0B,FC,9E,64,EE,D6,D0,B8,60,9E,1D,7D,81,66,20,B8,E0,A3,4D,6F,13,32,F6,84,E4,F2,95,94,86,6A,3B,BF,E8,EA,B9,B3,EB,BF,B2,BB,B7,73,9B,1C,C7,4E,DE,06,6A,90,F9,A4,39,F6,C1,E5,2C,FA,F5,0A,56,90,25,63,00,15,E4,39,A3,88,69,8D,10,EF,24,9B,FC,A5,FE,E7,16,FA,D4,87,D1,62,54,BF,2E,11,5D,5E,42,4E,42,E5,02,BF,AE,50,63,AE,E3,12,2B,2A,48,D2,EF,C7,A4,9C,34,CC,2E,2B,57,39,B7,28,13,E0,08,C8,52,E9,36,31,BC,68,8C,BE,B2,66,2B,4E,08,81,14,C8,4D,88,BA,EC,46,4C,81,C3,25,FE,2D,A5,24,BD,BB,F0,C3,0F,C4,13,EB,6E,41,6E,05,9A,65,39,60,00,16,AD,CB,AD,E8,D0,A2,CE,85,7D,9F,FD,1A,3E,7A,71,39,E9,CD,D3,31,8F,F9,B2,67,C4,F8,7C,D1,B4,0C,12,D0,7C,37,B3,94,47,21,4A,92,1D,C2,D8,F0,A5,A0,98,55,B4,5E,14,EF,1F,B0,E9,ED,DC,7D,54,AE,4C,B5,B0,19,BB,BF,21,2E,48,47,62,A3,71,F5,D8,94,A2,10,04,26,D2,12,24,6C,D0,0A,C8,AA,15,B4,79,62,C2,77,A9,1C,29,33,D5,5E,11,80,5F,F4,09,BC,3E,B0,D0,E1,85,3E,3B,C3,BB,5D,5A,C4,E8,93,3C,53,1D,FA,7A,1C,59,7D,CE,8B,9C,72,15,DE,14,51,C2,57,61,09,40,25,3A,1E,21,9E,3A,47,4E,0E,90,AC,64,AD,ED,94,40,6E,BF,92,8F,F2,67,8C,F5,F0,AB,A2,3E,72,6A,09,98,CF,85,F6,F9,13,96,B7,B8,AB,8D,5C,BA,75,23,EF,2B,B1,CC,BE,0C,E9,39,48,46,B9,04,BD,15,63,F2,11,BE,0F,A8,07,50,18,EF,3B,41,70,E8,5E,E2,7E,C7,F9,4C,13,D8,A2,EC,E4,93,92,23,28,D1,2E,63,F4,8E,1B,25,F5,03,D5,AD,B9,F2,6D,9A,0A,9F,54,66,F8,57,24,B3,0C,12,E8,94,1B,3B,92,BB,CC,83,C7,8A,50,81,88,99,71,81,F7,64,F0,BD,B2,89,0B,0A,E8,1C,8A,51,76,8A,70,16,4C,32,B6,50,38,EF,69,79,1F,98,7A,13,09,F3,03,88,23,F3,4B,EC,82,4C,42,16,20,A9,6C,D2,EC,57,B9,98,02,22,87,8F,AA,9F,F7,61,67,1B,B0,65,E0,9F,11,F5,5C,4A,BC,D4,C7,7F,8F,DF,F5,3A,D8,58,AF,7B,D0,B3,32,7F,BC,0E,B2,3E,65,A3,D7,23,AF,EB,30,8E,90,2E,13,B6,EF,0D,AB,26,C1,01,02,8D,49,C3,FA,5D,C0,D9,CC,CD,18,C5,F6,EC,60,8A,15,D6,D6,D0,84,A0,F6,5A,A6,71,08,4B,19,3A,34,CA,1E,97,25,E7,6F,B6,18,B8,80,B5,7B,59,0A,36,15,7B,11,D2,82,05,16,B6,78,DD,EF,8A,99,EE,4A,89,4E,16,8E,07,D2,53,5F,69,2B,2C,43,29,96,95,24,A7,9F,56,24,05,CB,6B,6A,12,F6,61,55,02,1D,02,F9,B2,29,48,44,03,08,F2,56,68,A2,E3,05,66,DC,8D,A8,79,D5,E4,84,82,4D,D5,CD,2E,C6,3C,53,92,35,32,A2,FE,80,F6,DD,A0,9B,90,91,EA,40,C5,12,6E,46,72,96,55,AA,1E,72,D9,88,4D,18,C6,D5,F4,DC,24,3E,C4,E9,05,F3,B0,D8,65,7D,44,34,8D,49,B1,52,E6,0D,66,12,C2,CF,71,22,72,59,45,B2,7B,D3,F0,4C,D3,38,04,EF,D0,B2,A7,C1,AC,5A,57,A8,B2,86,47,B5,19,13,4A,3E,D0,AE,44,A7,01,A8,94,4B,CC,E3,17,A4,B1,26,4F,5E,B3,35,FC,31,3B,67,DD,52,4C,42,D7,05,05,5A,97,3C,48,41,D6,96,70,D6,91,CD,AC,BB,7C,51,0E,FF,E3,25,76,80,B1,72,AE,CF,08,0A,34,F1,18,05,9A,2D,10,44,5F,30,EB,CC,BD,F4,2C,5E,B6,59,53,3F,DC,B1,FA,40,60,BA,A8,8B,DA,6B,EB,64,F1,35,EA,9A,73,90,EB,92,C7,AC,44,AE,DC,4D,28,74,EF,CF,6D,A5,20,13,81,4F,C3,60,41,28,4F,BB,5D,36,5C,7F,BD,43,30,DB,C6,42,B3,2C,4E,63,4F,CD,A9,82,91,6C,23,19,D2,1E,A9,60,F1,BA,BA,36,F8,42,5F,BA,DA,FC,4B,01,C5,A9,9A,60,32,92,C5,CD,30,40,5F,D0,28,FA,0B,CB,9A,05,8E,40,01,26,0D,D2,1F,34,A3,7B,E0,A4,B4,2A,8B,AF,6E,CE,EE,95,99,20,2E,1C,16,1A,B9,04,A8,E1,89,52,0D,E2,C8,B2,13,C7,D1,1C,22,3E,77,88,E0,FB,1C,AE,10,BC,C4,20,17,E9,62,A4,43,84,BC,AF,1C,29,64,93,7E,61,80,AF,34,A3,C1,53,CF,02,8C,09,8A,73,C6,FE,8A,AC,D8,E6,B5,A0,12,D6,9B,7E,00,10,FB,47,C1,CE,DC,53,AF,97,1C,44,EC,F2,69,64,47,EB,EC,BF,53,4D,AD,34,15,28,4C,0E,E0,AB,12,5D,BA,39,99,C8,6C,D5,67,04,8D,D2,78,BA,DD,00,51,E5,CF,14,A9,72,A9,AB,D8,98,32,82,E2,C7,1E,27,AA,B5,39,A7,9F,D5,24,61,CD,73,1A,2F,EC,08,66,D4,9D,E1,26,27,6D,B5,12,5C,F1,90,89,D7,89,32,2F,D0,BE,B4,89,66,20,AF,35,AC,BD,1A,47,7E,C1,B2,8C,30,7C,16,18,E4,57,8D,3B,45,4A,DA,56,13,79,49,B5,95,D5,80,15,BD,B4,7D,0A,18,B7,60,3A,65,CF,BC,73,48,85,95,34,64,79,CF,AB,04,2A,82,3E,D7,06,DA,BF,F9,99,E9,36,09,05,57,03,8F,34,C0,A3,EA,9B,87,C9,5A,06,90,BB,1E,B0,35,FA,8C,68,E2,FE,76,38,21,46,BF,25,2C,E7,E6,A0,43,96,88,00,94,B1,0A,25,3D,EA,B1,14,16,85,94,3A,5B,0A,85,49,D2,EB,17,89,C6,80,1B,33,3C,0B,4A,48,6F,10,69,93,B7,50,E2,28,B5,34,FD,DA,AD,07,A8,E2,B3,8A,51,AF,DA,28,CF,41,F5,30,86,18,E1,50,4E,6D,C8,BB,4E,60,DA,85,80,89,B1,DE,49,B6,E3,2B,56,69,51,16,60,87,F8,16,32,12,75,23,DA,27,0B,F9,BD,F1,45,16,FB,0B,47,FD,1D,DF,96,F9,7A,C8,C1,A4,19,15,55,49,4B,2C,F4,3D,8C,3F,E3,15,C6,7F,0A,81,BB,B4,61,70,A3,9D,1B,0A,E9,1F,13,AC,35,A8,DA,FD,3F,57,A5,0F,08,AB,9E,71,E4,19,61,E7,27,01,21,62,13,3E,E2,4F,2C,56,49,8D,F1,73,CA,08,C0,CB,B4,F3,25,CC,A3,CA,B3,47,7C,B2,D8,CE,A0,B4,FB,F6,C4,2C,28,0F,A9,56,DC,D3,36,AC,D2,16,2A,4D,A8,F3,DC,37,C7,5E,1E,C7,3D,38,30,9E,3C,9E,80,CB,E1,10,04,BB,80,A0,CB,23,98,94,95,D6,02,CA,DA,71,B6,F6,77,B9,A9,2F,FD,2D,5B,62,6A,9C,8C,12,57,3D,04,17,A2,E9,19,50,D4,5D,D6,DE,FC,A4,D0,4A,94,DF,17,30,2B,3C,B8,7D,09,C1,72,C7,6C,3B,7B,46,9B,80,70,3B,9F,92,ED,61,B4,62,B8,C9,BC,82,54,6A,2F,5D,E1,68,6B,F2,5F,D1,4C,4B,2A,C3,4E,0E,3C,18,C7,B1,F2,58,48,B3,6E,50,29,76,BA,84,F5,92,02,E5,72,BF,E7,12,51,1B,CE,13,DD,B7,5A,E3,00,69,B1,1F,20,65,E9,FD,EF,79,04,EE,5D,9F,7C,29,9D,94,EC,B5,CA,A2,01,DC,EB,6B,73,41,AA,84,14,48,26,FD,3D,91,38,E8,84,8C,A8,30,74,DE,EC,C6,27,62,D5,AF,44,5D,F4,F4,BB,77,37,1C,69,A4,4B,07,AB,D1,C2,F2,2D,AF,CF,2F,17,BE,72,F3,37,B9,42,9E,40,91,E0,4F,AB,4B,B9,91,3B,9F,F4,E5,0F,5C,05,04,0B,C2,C0,76,E1,E6,94,DA,16,15,64,03,47,0A,AA,F1,97,E9,68,7C,B8,2C,68,E9,D6,8D,85,D0,28,B6,15,9A,E3,4F,18,C8,7C,AE,4D,4B,04,4E,29,F4,E1,53,D3,35,1F,90,77,89,2F,A5,80,10,7E,12,AC,59,D9,AA,92,99,8A,26,2E,4C,95,31,8A,6C,EE,04,58,F4,36,C4,36,6F,70,98,EC,2D,29,48,B0,EB,86,58,2D,1E,E7,DD,C7,50,09,D8,84,C2,CC,6F,78,CC,6A,90,24,8F,9A,B2,12,BA,0F,B9,2A,CD,88,EB,C6,B8,63,9A,CE,18,B4,9E,4D,89,4C,2B,52,C5,C2,3B,30,8A,F1,6D,0F,00,92,74,B3,62,19,92,57,B0,23,49,7A,1F,7F,C2,6D,58,A6,04,16,A4,A9,8C,6E,E0,75,23,4F,BA,EB,81,A3,71,50,7E,02,BE,7E,97,FA,37,5B,81,05,73,FE,AF,52,6B,82,6C,9C,AC,D4,42,6C,1D,B7,97,16,20,AD,5A,D6,D9,9B,ED,7B,8E,5C,A5,9B,CE,7A,67,1A,29,46,B5,CC,D0,D8,74,28,E8,68,EB,E2,7F,E9,BF,4A,C8,49,E0,E0,7D,0A,79,88,3F,CB,C1,8A,EA,D0,CB,97,BE,3D,DD,F8,E4,D8,C7,17,42,41,C3,34,8D,9B,46,00,D4,1C,E0,A9,05,5F,93,43,0F,AB,C7,95,A2,A7,1C,DB,A7,CD,F3,46,4A,14,4D,E9,AF,9C,4C,16,C5,7F,9E,F7,58,7E,21,62,C9,F0,9C,76,EF,9A,0F,4B,BF,B4,AD,28,BA,2D,11,05,17,12,55,49,43,23,5D,FE,9C,B5,D0,96,FE,2C,51,F7,C8,DE,1B,A7,5A,B1,AE,AF,A1,BA,88,73,26,18,59,9A,73,A0,C6,FA,E1,E3,C2,8E,9A,34,11,95,75,0B,FF,9B,A1,E2,04,4A,19,22,01,DE,4B,3D,82,3E,DE,F0,18,5C,BD,F1,F7,9D,48,1F,FF,9A,6B,4A,87,2D,E1,B0,E0,CE,AD,BE,06,52,F9,B3,5F,31,0B,A5,D1,9C,0A,A5,B7,32,C6,B5,A6,E3,C6,BD,44,22,35,4D,84,E0,7E,03,D6,DA,DB,DE,18,00,7F,68,12,43,41,BA,65,BC,97,51,B2,C3,C5,BA,7E,59,4B,5E,AF,24,5A,EB,C9,E5,22,BB,20,40,01,14,3D,C8,75,2C,6E,28,88,76,0E,55,6E,6C,93,81,54,10,8D,5B,15,AB,37,E0,F6,A1,64,D2,4F,D5,7B,94,92,6A,B8,8E,EC,AC,C9,7E,D8,B8,0A,98,AF,1C,FC,A7,F2,83,28,81,AF,28,F3,5E,E4,CA,72,4D,8E,9F,BE,85,65,38,EB,F0,21,2F,C0,53,E6,C9,A3,88,EA,4A,1A,4A,78,8E,FB,92,5F,B9,BC,BC,4F,79,73,DD,92,1D,DF,F4,99,7C,A2,5E,EE,C9,11,3B,35,14,B0,3B,45,58,41,4B,54,37,E9,11,77,29,96,C0,7A,BB,46,40,7B,E6,4D,6F,B3,DC,AD,B8,F4,BA,51,FD,B7,C3,BA,1A,3F,1A,0A,A1,DD,7E,02,8C,4C,89,2C,CA,2F,19,96,84,A6,6C,86,B6,1D,35,F9,75,86,D3,A7,30,17,CF,78,83,BA,9B,15,53,D4,82,DA,F6,8A,11,27,AE,FC,03,51,8D,D9,DE,9A,DA,D6,C4,4F,F0,DD,D3,B8,34,E3,98,01,53,BC,15,41,40,61,B4,31,42,47,E2,37,52,A2,DD,31,06,C6,40,2E,03,BD,B7,DB,DF,97,BD,56,5D,84,1F,B1,E2,C7,E2,01,F3,19,B5,5A,4E,0D,C5,72,48,D1,F8,D4,5F,1E,91,51,98,9D,7E,91,F1,CD,8C,2F,DB,94,17,42,71,64,EA,7B,10,15,37,25,48,E0,02,6C,2A,EF,B5,E4,44,61,D0,16,56,97,0F,FE,6E,D6,D2,5E,46,18,BC,9C,1F,0A,B5,BD,2F,3F,23,D2,E5,E0,3C,F6,82,C6,F2,A4,84,E4,39,DB,80,E4,B0,5E,C6,24,CD,49,71,BD,22,9F,36,AE,65,FB,44,94,CE,A3,04,85,99,81,80,D1,8A,DC,D9,3F,6E,B6,A4,40,88,C5,3F,1A,3E,22,F9,C7,6C,F5,47,16,F2,F1,CE,84,2F,BB,02,F9,B8,83,BA,B6,E0,60,03,96,F3,68,3B,71,F5,42,2C,E5,2C,13,0F,06,35,D8,01,48,8B,2F,E1,69,86,DF,30,FD,3A,AF,1E,77,CC,D9,94,02,A1,91,D1,E6,58,32,25,6C,8D,23,EE,13,8B,D0,EB,F4,0B,54,30,5E,F3,C4,C7,0B,4C,A3,58,A4,AD,B3,C6,83,AD,57,5D,20,C7,58,FA,70,DF,2D,80,F7,80,83,F7,C5,33,EA,A3,8A,14,6D,7B,A9,A2,E0,82,51,D4,F9,8A,DF,2C,F2,59,D0,56,57,7C,76,A9,AA,5C,A0,DA,5D,1A,61,6D,B1,DE,B0,0C,95,E8,94,C1,AF,5C,30,94,5E,9F,29,DD,6C,13,10,26,4A,B3,B4,58,79,4F,F9,74,76,59,A1,3E,48,9B,2A,68,55,FC,6C,05,74,E2,7D,48,9B,89,43,8D,30,B1,52,BE,DD,58,85,DD,F8,C6,BA,AA,94,B3,F5,CE,39,DB,D0,57,62,FC,37,A4,0C,9C,81,F5,F2,8B,43,F8,3B,12,FE,BC,52,A9,1F,20,7A,EC,D2,DA,9E,B6,72,77,62,CC,C3,4C,B7,3A,91,EB,39,CA,D6,9C,6A,B1,99,E8,09,1F,3D,CE,75,F2,BB,1B,CC,AE,7B,4C,5B,79,CF,FD,26,F4,A0,47,EE,39,1B,14,DD,4A,45,66,D1,4D,0C,E5,DB,EF,9F,62,0B,3D,CC,2A,E5,93,00,E1,5E,8E,B8,F9,86,2F,32,82,6A,57,8A,63,E9,40,E1,8C,D8,C1,F9,B8,F1,A2,19,E9,7C,7C,F1,BF,84,80,9D,F9,43,0A,91,C0,49,AA,51,47,DF,19,AA,D6,35,4A,D4,BE,9F,3A,7D,14,AF,2D,2D,1A,27,F9,6C,A0,F1,7C,FF,55,89,22,18,0A,13,F2,00,9E,FC,B0,D7,48,67,B2,EF,B1,0A,44,26,5C,83,1C,19,CA,48,9B,78,39,3A,F4,C0,F8,10,AF,8A,14,A7,9C,F5,88,57,B7,57,CA,A1,F6,57,B9,7A,13,7C,55,36,DE,B4,1A,F5,C2,7A,21,0D,23,92,56,5A,90,11,84,85,EC,57,F5,39,53,DA,CB,70,30,43,95,0F,AC,F4,92,3C,AE,6A,60,6E,65,55,82,E4,E9,B2,C4,CE,B0,B3,99,64,06,89,91,1B,36,B8,AF,EC,1C,6B,32,31,E2,8B,0E,07,D0,77,5A,E3,AC,FC,33,D8,3D,D4,39,F0,FC,A5,60,2F,25,E3,50,2A,73,82,B5,0B,A6,C4,5B,D5,40,E2,91,55,AA,BE,E8,51,72,4C,3B,9E,DA,BA,D9,DC,06,5C,98,56,67,AF,8F,04,08,6B,F6,F3,B4,EE,E1,AB,F6,0D,07,62,B6,D5,11,5E,7E,39,84,00,B6,10,8D,38,50,D7,8F,62,9C,23,26,00,2B,30,28,28,18,F2,88,31,3F,8D,A5,97,C5,46,5C,11,EF,C5,42,41,28,B3,CE,1B,E7,4A,E2,E1,BB,23,80,F6,F6,A7,EC,33,4A,5C,AF,40,DF,54,FE,DB,41,FE,BC,F6,52,57,63,43,37,8A,20,FE,C0,91,17,36,CD,41,03,4F,F9,90,6D,02,6C,01,28,8B,D0,F8,A3,3D,B0,92,77,67,2C,40,A5,67,94,50,0C,62,68,6C,22,FA,00,08,20,55,1E,32,4C,A5,D2,0C,B8,31,59,94,A4,2A,57,92,BF,FB,29,F3,B2,B8,26,0C,7C,BF,98,6C,50,AF,58,4F,B3,94,B9,EC,08,5A,14,2F,52,08,DA,D4,5F,CC,9D,A2,8A,E9,3D,BD,1F,6B,36,D5,0D,A9,AF,D5,DB,0F,6D,1A,AF,53,AD,18,7B,FF,D0,F5,49,D1,55,6B,C5,31,DD,5C,61,4B,39,AE,1C,71,EF,FD,E0,E9,BE,E4,9F,0C,FA,A3,58,BF,0B,F5,70,54,16,95,E3,1C,32,B4,F7,43,47,2E,B1,27,F8,36,BF,29,EA,71,ED,E5,A0,8E,4A,1A,27,08,B2,38,08,82,06,69,B0,3F,12,CE,55,78,7F,EA,BA,C1,6C,18,27,7B,AC,48,E6,E4,56,54,10,20,82,F1,96,C9,F6,D4,A7,FC,D2,81,80,9E,96,52,BF,22,5F,99,0E,E5,1D,80,39,BE,30,A3,69,1B,83,EF,33,81,F8,63,EE,69,83,5D,8B,25,1A,AC,F6,5C,D1,E2,32,C2,0F,B1,50,6F,AB,1C,A1,BD,A2,89,B4,96,79,4B,5D,5E,70,BA,1D,A3,50,9E,E7,BB,8F,71,34,42,1A,67,62,F4,18,0E,05,BB,C8,7F,0A,22,47,5D,C5,1E,2E,9E,C9,5C,F6,A0,D4,8C,4A,1A,78,0C,F9,2A,10,53,54,06,99,66,E6,35,99,08,68,A3,7D,0F,71,B6,59,18,4D,18,45,9E,91,94,5D,D9,F9,27,9A,A8,D1,E3,C0,5C,D4,35,92,2F,93,A2,43,D4,DF,8D,EB,5A,FA,9D,73,07,80,44,6D,A4,2A,D4,B8,02,4D,57,23,3A,5A,FD,BC,E2,D6,1C,89,95,AC,5C,79,B2,93,D9,0C,6F,C6,01,BE,99,DE,1D,90,4D,64,1E,39,BF,7B,BF,94,AD,A8,00,2E,01,2B,12,B8,2F,FD,2C,8B,04,D9,B6,DA,E0,06,40,6D,78,0C,DE,DC,7F,22,A6,F5,CA,BE,5B,89,CA,6C,70,48,86,F6,AA,34,B2,50,22,EC,CC,64,2C,89,67,ED,B3,BF,53,9E,7D,5A,01,82,54,F6,8E,36,39,AC,9E,71,A5,0E,39,A1,86,57,14,48,74,55,20,27,A1,21,2C,A6,7B,5C,FD,EA,ED,41,8D,F3,CF,DA,E2,D1,5D,A9,1B,0D,31,28,2D,00,A0,00,CB,7D,39,C3,C3,68,20,ED,78,F9,0C,92,DB,FC,56,38,29,4F,30,E0,AA,24,97,6C,D8,F2,D9,60,36,CA,96,13,7F,70,4B,BB,36,52,5F,B5,CA,C5,0B,65,2E,2F,DB,59,8B,3E,53,52,72,43,6E,3E,9E,0E,E7,26,AD,6C,CD,32,C3,F1,AD,D6,ED,9C,DA,7D,F7,7E,F9,33,47,81,5C,6B,93,83,0C,CF,D9,34,7F,C2,37,AD,87,1A,9A,AF,5D,CE,C9,2C,40,1C,3E,D6,7B,AB,5A,BF,59,3D,87,9E,FA,E4,8F,9C,6A,D7,E4,77,63,E5,A4,83,18,18,E9,22,DE,7E,95,54,D1,9A,D8,89,BB,B1,58,06,22,1F,D3,21,BD,CB,11,AB,5B,8D,F4,D6,DB,E2,0A,BF,50,AE,74,19,7B,44,75,3F,ED,4D,8A,19,A7,DF,02,DA,88,9C,12,0A,8F,E6,76,63,4B,EA,F8,46,B5,9C,7F,E5,EB,96,E7,6A,0A,DD,DA,3A,5E,CB,82,6F,32,A3,CF,47,A1,24,68,4C,D5,D0,11,92,CE,29,A4,F5,84,59,ED,E3,31,5E,8B,C3,A0,F6,5B,97,87,15,7C,91,22,9E,EB,DC,F0,74,F1,6C,61,C1,F8,F2,6A,E6,F7,F0,FD,9C,5E,C1,E3,62,F4,50,71,05,92,CA,D2,C3,FB,8F,19,5D,A5,D4,7D,03,AA,76,DA,81,A4,64,BA,4D,8E,E6,50,43,49,C5,D2,82,59,6F,1A,EC,B6,7D,9D,1C,16,E8,CC,94,DC,09,8D,5D,E0,0E,1D,3A,0B,00,2F,42,D6,27,67,66,08,FD,FE,1E,CA,80,6D,FC,6F,C4,66,23,79,F9,9E,8E,48,9F,1E,E5,4A,AC,B7,BB,B0,58,A0,7F,42,02,79,BE,BB,C1,CE,72,D2,FC,76,41,56,DE,31,85,AA,23,63,B9,B1,9F,5E,D4,1E,14,E6,11,4A,FE,00,D0,2A,09,D2,D9,82,1B,E4,40,56,5F,05,44,11,B9,60,91,10,7E,C5,18,CA,BA,14,36,F6,C1,06,12,EE,D6,AB,6E,FE,E6,CF,3A,8A,3C,56,A2,55,59,58,74,80,E6,42,9A,D8,7A,0C,1D,1E,54,0E,B0,2F,54,AA,ED,C2,62,A0,34,E0,07,5E,D3,01,86,EB,98,D0,77,11,46,CC,D0,71,E0,B3,B9,40,41,ED,2D,5A,45,2C,8C,D9,0D,03,32,52,64,18,67,FD,08,F2,62,3B,48,7A,70,D8,C2,15,A5,7B,D3,FE,75,DB,66,37,6B,9B,97,92,F2,F3,DB,24,8B,1E,89,50,2B,85,C8,4C,0F,24,02,87,18,C6,EC,B1,5F,26,0F,1E,1F,CA,E8,55,9E,71,B3,69,FE,2A,50,B8,6D,A7,DE,CE,50,51,46,95,27,99,48,E1,80,65,40,F3,74,38,93,AF,4D,C2,6A,23,A2,EB,C5,FE,4F,0C,39,76,D0,53,B9,39,9D,35,18,70,C8,5B,EC,8C,76,B4,E2,F6,52,D4,15,7E,AE,F1,75,3D,9F,C1,75,76,2B,73,B7,CC,E3,CF,98,FC,56,6B,63,2C,B4,F7,D0,56,43,89,B6,F0,7B,D5,4A,39,25,1B,10,08,E9,C0,3E,18,90,FB,8A,91,43,83,AC,ED,F3,BF,8D,7A,BB,35,AC,49,78,1A,1D,7E,AD,E1,F0,28,83,B4,D0,3D,58,EB,A5,78,F2,B6,20,30,D4,35,25,CB,71,B7,5B,E7,CE,DB,DC,48,79,38,4E,92,D1,30,0D,AB,36,AA,04,17,6E,4E,66,B2,E5,E6,77,6B,0E,9E,8C,51,20,04,81,74,02,20,AE,28,3D,97,DF,0B,7D,95,4D,4F,AB,74,26,5D,C5,7D,92,52,7F,2D,88,2C,76,99,8D,9D,04,82,CB,BB,34,66,C2,3F,85,AB,E1,50,9C,28,0D,5C,0B,12,05,EB,9E,EB,BA,AA,0A,D5,77,3B,77,69,80,9D,4C,5A,BE,AE,0E,D2,0E,E6,EB,50,76,D5,90,81,32,2A,9C,E9,33,A5,4A,50,5C,53,46,ED,C3,22,91,0C,D6,9E,9E,F9,43,05,00,4D,C8,16,63,42,1E,24,B1,5C,EA,70,BF,3E,D1,92,FA,D5,31,39,9E,13,88,0A,3B,4E,1A,62,2F,4B,BD,55,DF,0F,56,67,9F,84,31,9A,93,79,2B,03,7F,72,5C,23,E0,5F,EE,3B,B7,96,02,9D,A2,EB,87,33,AE,6A,23,CC,22,BD,E0,82,B2,12,16,31,44,94,7C,0E,98,E2,08,A7,49,52,FF,C2,44,C8,B9,86,35,40,7B,D4,AA,CF,2F,C3,3D,7F,60,50,05,49,AC,CE,33,E9,62,8A,72,FF,0B,E7,DA,F8,0E,F2,E1,A0,0E,90,E8,CB,32,F4,A1,FA,DB,D8,B3,37,66,09,E0,59,E0,00,A0,EB,DA,73,8F,57,A7,16,0E,82,8E,55,4A,4C,2A,B6,4D,DE,64,2E,B3,0C,6A,CE,3D,30,10,86,AD,B6,C3,B9,E2,F4,06,29,4B,81,49,0E,78,7E,42,B8,34,B0,E6,D2,60,2C,F9,BF,80,8F,76,F0,D5,0D,22,33,42,81,09,7E,52,59,DF,01,E6,44,74,73,DF,03,29,60,73,5C,EB,6E,E6,03,0D,0F,46,93,2B,4C,F1,A3,3C,B2,CA,E5,D8,3B,8B,84,21,AB,86,7A,4D,D7,78,9E,6D,C8,D6,48,AB,E6,2F,E8,5D,49,9C,25,FF,D4,1D,1B,44,FC,06,09,C3,77,69,3D,52,25,8A,3B,D2,FC,90,07,C1,4D,34,9C,A4,1D,A8,29,3A,2B,35,03,B2,F3,79,64,40,52,F9,04,52,D4,CA,84,3B,89,BD,A5,03,12,55,E4,3F,01,88,53,DD,4C,AB,B9,4A,C8,12,CE,54,57,74,2B,3E,AA,5E,36,61,F1,D4,8F,AC,E8,B4,32,12,89,3E,6F,A8,A6,37,90,96,48,8E,BD,8F,85,0B,7A,F5,C8,9E,F5,F2,12,4A,90,E2,D5,E1,CE,3C,45,8D,AB,D4,6A,2D,13,B4,BC,3B,E8,59,25,9E,09,72,E5,D2,F5,D6,3A,91,72,8E,57,78,F4,10,49,5F,CD,BE,E1,2A,C2,99,43,FC,8E,6D,32,0A,3C,E4,D7,D2,41,58,BC,43,11,0E,27,35,A9,20,87,2D,75,E3,68,15,A4,EF,C3,3F,DD,D5,36,A4,A9,DA,15,09,4D,1F,C9,50,A6,60,FB,F6,33,FC,CD,5A,66,BC,68,25,DA,38,4E,F9,86,BA,CA,3A,D3,4E,BF,EC,B0,95,0F,A7,98,81,DD,8A,C9,C3,49,63,31,92,87,3B,C9,32,F0,3D,16,F5,1C,C7,D7,97,EA,7A,63,E4,7B,2D,FC,74,7D,53,AA,B3,52,A7,7B,F1,1C,B1,9C,CB,1D,93,8B,7A,CC,96,1F,8B,91,12,3E,1D,70,5E,C1,1F,31,F5,56,8D,51,16,4F,D6,D9,8B,AF,46,DC,31,AE,6F,17,E8,6B,12,A6,EA,30,32,98,40,37,DB,B2,EC,64,40,05,5E,8C,50,6A,DB,33,D8,12,DD,81,92,D9,C6,53,44,65,F7,8E,BC,D8,B9,51,16,00,78,9C,1D,E1,7A,EE,EF,42,D8,8A,F9,CA,3B,48,DE,44,24,59,AA,16,82,B5,0D,DB,F6,F1,68,00,69,9A,FE,A1,5A,5B,B4,90,8D,21,C5,2C,00,20,A6,8B,21,37,90,8B,74,3F,BE,99,A4,14,86,97,38,33,3A,F2,7A,BC,5A,0E,6D,F9,E6,CF,E3,06,94,F7,A6,23,0E,38,F9,01,20,F2,DA,E3,D7,6C,D4,C7,73,25,F2,09,EC,C3,C3,2A,33,F4,80,A9,BD,A7,A9,4E,E5,4C,7C,94,3D,84,4A,D8,E9,80,53,7D,98,A5,1F,FC,D2,2A,00,D3,F0,A8,54,C5,FA,06,A4,AB,D6,04,74,F7,51,18,57,C2,A7,A5,B9,70,96,E2,F0,7D,10,5D,2A,17,60,4D,22,7C,4E,C6,0D,56,A0,8B,11,E1,C0,29,AD,00,59,50,B4,81,08,1B,81,E9,14,A7,DE,18,FE,C8,7B,F4,8F,D0,D8,8A,50,F4,72,C3,B4,D6,01,5B,2A,0E,4E,66,52,F3,84,53,05,9E,C7,AD,53,28,66,AC,6E,54,08,FB,E1,CB,C1,44,00,DA,8A,E7,9C,6E,96,88,01,2B,16,33,A7,19,8B,3B,98,10,D8,EB,47,82,A4,E1,D4,DF,FC,F2,12,24,7B,CB,70,9C,9C,1F,12,14,95,DD,14,D5,C4,37,3F,4D,14,97,55,12,8A,12,F2,28,21,0B,B0,8E,AD,CA,3A,F2,C4,BC,94,24,18,0A,B1,92,68,71,5D,84,F9,45,30,A0,E5,F0,C6,0E,32,38,52,59,A0,1C,A9,8F,E1,CE,56,C3,0E,C2,92,96,CC,23,1C,1E,39,89,7F,C7,B8,15,1B,86,36,7C,34,51,CE,F4,68,45,28,97,F3,1C,1F,BD,F7,2C,90,69,38,FB,E9,D5,DB,23,17,A8,1F,F8,51,EF,B4,16,D6,ED,B2,37,EE,B8,83,7A,2D,7D,D3,AF,6D,58,31,16,FE,F7,EA,64,99,42,2D,33,B3,3D,75,24,26,1C,11,0A,33,71,9A,69,BB,0B,85,A4,4D,ED,1C,32,36,07,93,E3,37,AC,C0,BE,8A,1E,B2,2E,A0,90,15,8B,AF,57,73,BD,E3,5E,DF,AE,F0,4B,D5,6C,BB,52,17,77,94,04,BB,44,F8,36,94,F2,46,C3,FB,07,B1,C4,E9,50,88,E9,34,30,E1,D2,48,F0,E3,13,5E,64,C7,2D,2D,41,2C,D7,40,F5,57,ED,44,7A,5F,11,B0,66,32,0B,AF,27,15,B8,F0,7B,86,DB,C1,E6,58,80,14,44,C5,F4,7B,C0,C6,FE,6B,03,9B,C6,A2,FC,34,B9,1A,A5,9B,2B,68,F5,0D,CA,E9,C4,08,F9,B6,EC,3B,36,A4,F2,5A,6F,C0,10,B8,4F,4C,7D,70,1A,74,D9,B0,6C,0B,92,B2,EE,25,60,1F,C6,70,6D,24,67,69,3E,88,50,80,6F,CD,D2,EC,68,BC,DB,4C,4F,1C,AE,6E,DC,56,7B,5F,6F,CA,88,E5,D4,79,15,FA,B3,CC,79,B8,40,80,65,6B,1B,0D,74,C0,7E,7D,62,43,A0,10,09,5C,83,49,31,6B,19,6A,B3,25,54,23,3E,14,83,BC,46,28,94,0C,83,E0,A8,58,B0,9E,F0,A2,D5,F4,84,2F,48,5C,AC,3E,D4,3F,E1,CF,24,05,D7,98,03,85,0D,11,A1,21,60,79,33,A1,BE,74,7D,36,C0,A4,AC,5A,65,70,C2,AA,AC,AE,D4,99,EC,D0,79,9C,D4,CD,1C,0E,15,BB,8B,36,9C,C2,3B,59,5A,C9,81,59,32,D0,31,3B,CE,CF,17,7C,53,D4,42,82,66,8B,C6,AD,12,0B,4F,F4,FB,84,2F,E8,4E,F7,93,7E,A7,B5,46,86,A8,2F,24,A3,9A,09,82,86,76,98,97,02,80,A1,D7,C9,65,FB,B6,AF,B9,A7,C4,8E,17,0F,EE,4C,B6,18,B1,D1,34,90,71,41,56,1F,3C,A6,D3,4D,5F,4E,F5,99,B3,DF,AF,5A,06,57,A7,75,4A,BC,15,8D,BE,82,F2,1C,36,4C,38,10,E0,E0,99,30,66,8A,3C,9E,8A,1B,79,15,AC,AB,51,E9,C5,58,77,1F,FF,55,DE,2B,A1,50,20,BA,19,AF,11,C3,DF,36,B9,A3,64,36,85,10,5A,0C,6E,19,45,11,F9,A9,BC,4C,10,5A,E9,AA,C3,E8,29,60,EE,A7,95,A7,65,9F,7F,54,F9,04,82,92,41,D6,0A,1D,A6,B0,71,8B,F5,C1,0D,F6,02,DE,4F,74,6D,0A,90,9A,93,C1,3C,56,0A,13,AE,B5,87,63,62,6E,E0,9E,4C,B3,8B,40,53,21,CB,32,7F,B0,07,92,C8,D3,EA,E3,3C,DA,97,27,9F,3E,C7,73,FB,3E,8A,EE,DE,C4,6A,33,91,7A,BD,90,21,60,10,28,F5,21,9B,3F,DE,29,F1,06,14,8A,82,D2,71,5F,75,BB,A7,56,5A,BF,5F,A2,47,8C,63,FB,9F,9A,A1,BF,4C,23,9F,D8,35,52,AE,A8,52,8A,9F,5C,7E,18,85,06,85,09,99,9C,BE,D4,AA,26,3A,00,56,A4,F7,B1,68,FB,EF,D4,48,1D,C6,87,F4,1A,34,F0,F0,C4,69,37,74,AC,35,CC,C5,15,7C,B3,A3,92,5B,46,52,40,B8,71,6F,C5,E6,E6,1F,F0,D8,B6,D1,B0,B6,C3,C4,63,B3,04,74,1C,3F,82,09,18,FA,BD,B6,08,78,A0,F0,F5,D3,D3,F9,7F,A2,8C,84,7E,91,CA,6E,06,54,94,E9,01,D4,32,B9,06,8E,0C,88,0F,72,9C,1F,28,6D,3C,4D,1B,3A,1B,0D,46,F0,E8,82,AD,D3,7D,60,A5,C1,24,13,54,73,15,84,59,17,20,E4,E4,96,D3,60,42,41,40,E3,82,B4,46,92,97,32,00,34,A8,B8,C7,40,A7,23,9E,EC,0C,28,6B,20,56,B4,15,C0,72,E5,23,84,DE,18,B5,39,0D,A4,EF,61,21,A9,8D,F4,FC,69,89,CD,2A,F0,0D,87,7D,07,B8,B9,B7,DA,30,FC,1F,2A,81,38,D2,BB,E5,A8,0C,FF,DC,07,D4,56,D6,24,80,49,00,F9,3A,24,34,F8,4F,E5,1D,CA,CE,93,88,78,28,56,95,08,56,35,2F,D6,3F,A3,DF,10,41,8F,99,B9,02,CA,BC,42,99,E7,47,E1,6E,8F,FB,A5,C2,65,4D,3C,E5,25,42,FD,A2,F4,E5,E6,37,A3,2D,7F,35,42,E8,7B,F9,3C,16,A3,0A,B1,E9,59,57,F9,04,AC,6D,27,84,F6,68,EB,B7,97,CC,E5,17,90,93,27,85,7A,C5,F8,E2,7D,89,52,0F,49,84,07,0A,5E,50,BD,B7,7A,6A,9F,2E,B2,C3,AA,87,75,04,BE,3F,66,41,F1,70,A5,0D,5D,78,37,49,32,F3,41,82,DF,2B,0A,04,A3,5E,CF,B4,40,A6,96,52,FA,54,25,B0,D4,F9,EB,A3,F2,6F,D9,FE,CF,49,98,D2,2F,27,E4,2F,C5,37,72,89,5C,88,99,A2,C0,92,22,E4,9B,AA,52,24,D0,4D,8A,F2,A1,02,53,38,F5,D8,52,A3,EA,74,71,42,29,E2,C7,04,CF,93,6A,8C,8A,F1,C2,2A,C6,D2,8D,04,5E,7B,58,96,47,7B,14,7D,69,C5,AA,3B,FC,D4,F9,C7,B3,91,18,AF,B6,75,EF,90,02,5B,C4,DE,B8,28,20,B4,16,1E,27,B1,55,C4,0E,4E,33,3D,C2,37,D3,D4,59,3B,E0,5E,B8,20,01,B5,2F,1B,D0,DF,15,77,3A,41,A9,CE,E7,F5,FA,BA,6D,A3,04,4F,D7,CF,82,62,12,D7,8C,A3,9D,8B,4D,98,C9,07,1C,9B,86,A2,C7,4B,15,9C,10,60,35,D0,A3,4D,B5,0B,9F,C6,4B,81,50,AE,AB,A8,E3,DA,70,36,85,A2,FF,F6,FF,13,D3,97,8C,87,87,61,E7,A2,3F,B8,99,8B,ED,F9,8E,C4,0C,1C,9D,C2,F8,B9,55,81,1E,80,DA,C0,34,35,75,B8,F4,3D,78,94,A2,CE,61,BE,88,0B,50,DE,2A,74,C8,EC,CD,55,B7,35,FA,E9,FB,2F,35,46,DA,67,5D,56,5F,7D,33,BC,9A,84,0A,91,56,2C,A5,BB,53,D5,AA,C3,59,8B,08,CD,D8,C1,BE,82,A6,B1,20,F9,8D,0B,34,52,D9,D3,2D,81,E0,A8,52,87,75,C8,C2,40,20,21,C4,7B,AF,4D,9C,79,3C,46,34,EA,A4,7B,E4,52,2B,21,7C,75,89,44,4D,DD,0D,57,14,10,70,50,48,88,75,22,7A,B4,72,2C,E7,12,1C,7C,98,24,60,D7,D5,BF,D4,55,07,6E,69,79,F2,B9,55,86,3D,EE,99,EC,DE,9F,97,63,7E,B9,F7,8F,C4,87,11,F4,53,6D,A3,8E,B3,E2,FE,68,43,16,A9,3D,5D,F4,49,0C,B0,EE,7D,16,89,29,2F,6B,80,56,67,F8,57,9A,1A,09,55,29,29,BC,BA,DF,63,AC,20,2D,6C,3F,0B,12,52,04,31,3A,12,C6,A9,A6,73,2A,4D,12,D2,36,CE,77,9D,4F,58,98,27,6B,AA,BD,B9,EE,2D,82,FC,90,F2,30,47,8A,36,2F,91,16,54,81,3C,FA,E6,15,55,F9,29,AF,92,65,D5,63,B9,D5,7E,2F,CA,A7,50,48,86,DE,3B,3F,FC,53,A1,0C,2F,B8,7B,3B,B4,4A,C5,9C,68,A0,B5,46,1B,43,E3,23,46,64,45,9E,53,F7,12,E7,9F,6E,7A,C4,3B,FB,A8,9D,C6,FC,1A,40,48,49,14,3B,06,87,70,99,CA,CC,4F,2B,D2,9F,72,8E,AE,8B,D4,E8,2D,37,EE,42,C6,75,1C,E1,52,42,2F,48,27,13,B0,DA,07,53,57,EE,12,24,4A,E9,32,A4,FC,74,93,B3,AA,9F,4F,BF,DB,41,4F,5C,C2,3C,D2,2A,C9,6A,3D,E3,57,A3,10,F8,AD,BA,70,3C,DD,CA,BF,BB,60,FA,FB,3B,16,25,DC,D3,82,FB,D4,3C,E7,4C,AB,9A,8C,79,31,86,EF,BE,D1,57,6B,45,42,6B,C4,67,ED,87,8F,76,F2,31,7D,A2,4A,8D,13,32,09,DC,8D,CF,76,92,27,C2,32,C7,A2,4C,80,AC,E9,19,18,ED,6E,CE,FB,9F,7D,19,A6,41,0E,51,40,04,9F,ED,60,5A,F0,6D,02,4A,EF,40,F3,EA,09,0B,6E,67,39,0F,28,A8,5F,68,17,0D,B4,10,B2,DB,E7,CD,0F,33,9C,E3,55,E7,EE,7A,4A,9C,7A,83,26,23,43,20,F7,D1,86,7F,B0,F4,5C,4C,9B,C7,BB,32,B8,25,2E,7F,FB,11,4D,2D,A0,D8,61,EF,A0,D6,45,11,11,97,F5,ED,AF,B0,67,7B,5F,D5,BB,55,B4,DF,53,FC,A9,49,43,CD,C6,51,B2,C8,E6,83,15,D0,AA,D6,66,B2,77,18,B9,59,03,F5,CA,78,A4,89,A9,68,13,F5,A2,3C,FB,80,78,FC,F8,3B,3A,1D,A7,4C,ED,A6,AE,AC,54,76,3D,87,32,F7,93,7F,7F,31,A8,B3,B3,11,BF,26,04,27,F8,2E,3E,14,E7,26,3A,EA,7B,18,02,20,99,BE,CC,69,2A,7B,E2,59,74,E9,5B,67,8A,14,6F,81,56,C3,1F,2E,62,B9,1D,0D,B2,DB,A6,A3,5E,D5,63,0D,D3,A8,D2,D4,79,95,0C,AA,D0,80,75,69,C4,64,D7,F2,CE,6F,51,A6,8F,44,13,23,9D,9B,69,73,80,19,65,64,1D,14,DF,9A,E7,FB,45,1C,83,FD,D3,DF,10,9B,5E,FF,73,57,01,C6,56,DE,F1,63,EE,E5,08,57,DB,70,EB,25,BB,D8,B0,70,EB,DF,D9,27,33,90,2C,66,3F,75,64,1E,89,EA,9B,FA,5B,39,4A,47,60,F8,92,D1,90,6B,14,A1,EC,C4,8B,EA,A4,2C,ED,FA,A4,DE,89,F8,80,F1,D0,9A,F5,4E,98,9C,97,20,E3,7A,88,F6,23,1D,E9,28,1C,71,B7,72,87,F5,0E,1A,45,5B,C3,70,18,BD,C3,B8,8C,1A,45,89,E1,D2,F0,A9,04,84,CF,1C,64,34,9F,52,98,1A,2B,8A,D6,F2,47,42,92,D5,59,77,53,5D,36,5F,04,05,D1,C5,3A,B2,F8,95,E1,64,AC,E2,B9,54,15,AA,70,69,11,B8,0F,68,AF,EA,B0,65,48,EA,03,6A,A3,30,8A,DF,CE,1C,1F,14,66,34,2D,C9,3E,BC,A3,CA,D1,2C,3B,EC,CC,BE,ED,67,93,48,35,F7,36,83,0C,90,C5,CB,BA,4E,4E,38,49,A7,74,4A,78,E9,28,C8,15,62,43,DD,C4,58,CF,3C,07,75,81,8E,5D,4D,FE,93,E3,E4,11,88,DF,A9,C0,15,24,3A,05,61,78,F5,B7,E8,FC,B4,0E,7A,89,D5,06,A4,BC,CC,64,C3,12,22,65,A9,28,13,F9,55,19,7E,7F,FD,D6,6F,A6,F6,D3,88,25,C4,2B,60,1C,F2,F1,CA,1B,E0,AB,28,2D,C8,BE,75,A0,EA,CC,46,2D,13,E7,BE,74,87,B6,67,30,65,E1,56,97,F0,E5,C9,8E,3F,EA,88,63,2A,FE,58,D0,79,F7,CD,6C,9B,33,88,40,11,44,BB,17,47,6D,A7,E6,7C,7F,E4,FD,17,C7,0D,A3,FF,7A,93,4B,D4,9A,64,84,0F,DD,EB,35,63,02,E1,BB,6E,09,FC,9A,7E,0E,61,4C,19,2B,17,B6,6F,DF,8E,59,68,46,0B,E1,C8,2B,05,67,47,8F,DA,AF,5E,D6,90,A3,F7,6A,5D,34,75,E9,6E,70,58,F1,14,2D,E2,D1,00,A5,5E,23,BD,D5,20,6B,C7,F7,3B,72,70,7A,A5,39,FB,5E,02,6B,0E,AF,A1,BB,73,40,53,09,EF,43,A1,61,88,7C,4E,47,EB,A6,C4,A3,2B,74,1F,EA,D2,88,DD,B5,CB,CA,0D,2A,28,A4,B1,FB,6C,C5,14,33,6B,EF,AF,A8,9D,BA,0D,C9,1D,58,80,34,E2,98,B6,A9,D9,C6,0E,70,23,F5,8F,03,83,EB,CB,B2,B6,41,11,D1,39,74,8C,C1,B7,51,E6,1F,09,13,EA,90,AA,21,9A,60,E2,73,66,57,F1,81,DD,01,46,E8,11,D5,69,7F,8D,79,45,48,7A,A1,D4,E9,84,FE,69,B2,C4,6F,C3,C6,32,9A,C2,12,16,9E,89,58,31,DE,E6,F0,0D,D2,A4,95,29,24,A2,50,1E,41,35,D7,BE,6B,23,5E,30,DE,77,AB,9C,12,2D,82,B7,B3,5B,39,D8,DC,72,26,02,FD,82,7F,C2,22,31,16,85,34,F1,F6,1F,E5,C3,11,52,05,07,EB,97,79,AC,35,72,63,64,96,1C,6E,99,CA,F4,57,59,FF,DB,77,6A,9F,DA,C7,70,37,E1,32,AC,52,B2,D5,F2,CB,88,8B,D0,93,B9,05,CE,75,34,BF,06,D3,C8,BE,1D,5C,C1,0F,EF,02,2A,AA,C0,78,8E,25,2C,85,2E,5B,68,A9,52,D1,09,13,D7,27,99,73,04,A1,4E,3A,91,C5,7B,1A,2D,E5,60,B2,DC,73,14,D6,3A,C7,D2,32,88,EB,59,4B,8A,A0,6B,91,4F,49,AB,17,73,FF,AA,07,E3,46,B3,AB,FD,4B,E1,9C,BC,4A,F4,DD,2B,A7,46,15,D2,51,2A,48,FB,68,49,DD,3A,E3,C7,5E,F7,F5,DA,9A,D7,EE,B1,5D,22,CD,43,43,E5,2E,4B,E7,5A,EA,41,14,74,05,7E,61,C6,38,3F,35,AA,1E,C3,0B,30,B7,E3,A1,66,2D,1E,AC,22,28,B8,F1,AD,B1,E6,12,EA,C1,6F,47,22,C8,6A,DB,7D,AE,A6,5F,5F,7A,6A,42,AD,9C,0A,80,D2,1D,86,01,40,C2,94,E2,29,D4,06,4F,15,89,66,6D,D8,7E,6F,A6,A5,0E,72,7C,14,1F,D4,F7,6B,E7,2E,27,CE,CD,DD,95,7E,BF,B5,FB,E9,9D,41,9C,69,C9,4B,7F,8C,C0,8E,8F,A1,91,37,BA,6A,E6,38,73,A2,FD,A3,96,2E,1F,9C,7E,69,5E,2D,0A,67,5A,6D,BA,C5,02,54,10,72,A7,F3,91,8F,03,03,71,FB,A3,36,9C,30,AA,78,AE,62,44,F9,10,02,A5,18,9F,AE,C1,DD,CE,C0,0F,09,C4,7A,35,B3,EE,01,9E,67,29,8C,BF,CF,30,0F,DD,B4,C9,CF,8A,09,96,6D,05,6D,E8,71,69,81,BC,8A,6B,8F,A1,68,50,6F,6E,A0,9F,15,95,5F,E5,13,FC,66,41,E0,C6,C1,B4,C7,0F,08,14,85,E7,79,2B,E1,C2,25,00,91,DA,5A,A5,1A,DB,B0,9D,DE,82,1D,63,BC,EA,2E,38,3E,1F,42,C1,F4,AA,0C,D7,ED,37,67,93,8B,66,B1,2C,B2,95,04,06,EA,0A,DA,62,4D,C6,E3,F0,F3,85,84,94,26,62,E6,FE,AC,42,AF,8F,6E,79,86,46,E1,C5,92,5F,E2,2A,AA,EC,A7,3B,C2,DE,21,94,1E,70,AD,10,9D,F3,CD,07,37,8D,51,A7,0C,04,D1,C0,D5,9E,CF,64,93,05,A0,39,04,4D,B0,DD,0D,51,83,B7,5F,A0,52,5B,4C,79,69,9B,F5,59,8C,F3,B7,30,6F,54,C1,7A,AA,69,B8,1A,D6,1B,98,68,23,DB,9E,78,7D,44,9B,93,DB,90,99,09,D4,F6,88,E8,C3,F0,E0,CA,EC,18,08,99,91,CC,A1,DA,7C,22,6E,0A,B4,CB,01,37,A6,9A,38,8D,6D,DF,43,28,8B,84,DE,D1,1E,56,75,CD,EC,6A,D6,57,89,F9,A6,AA,F4,40,2E,8C,69,52,28,21,62,B6,42,CB,9D,B6,B8,32,D0,E0,67,3D,AD,DD,52,A7,2B,15,56,76,E1,C8,2E,A4,E2,B5,10,E2,04,92,74,4D,4C,6B,42,D3,EB,45,A2,2A,29,68,D3,2E,26,38,6C,90,C1,5D,34,E9,8E,37,A4,50,47,15,44,5A,1E,8D,F9,7E,6F,9E,E3,B0,93,5C,37,F4,E8,BC,25,0F,00,99,3B,9E,3E,68,C5,B2,1B,92,53,CB,60,DF,FA,9A,6A,38,E3,85,DB,71,7D,68,54,A5,50,18,7D,2B,C9,E3,C9,BE,D6,2F,1F,44,35,4F,DF,39,18,E1,F4,BE,7E,42,33,B8,A7,7D,ED,26,31,1D,78,D3,A6,37,1D,CD,29,1B,FF,24,95,4B,AC,16,1D,87,E0,C6,69,71,DB,F7,4A,85,A1,20,F8,48,51,23,0E,32,C7,2E,04,EE,D6,96,87,90,C1,44,44,C0,05,44,24,4D,8F,B1,0E,C8,3A,6D,1A,B1,91,78,5D,E2,B6,D0,07,14,BD,1F,55,58,F9,2B,B3,18,3C,F9,33,73,82,BA,E4,A0,A2,6D,D6,16,99,E2,98,01,4D,F8,DE,97,36,B5,D3,4B,03,31,C9,10,37,41,5F,55,C6,BA,53,6A,DF,ED,85,C0,D5,44,B3,64,3D,D7,2A,C1,8B,7C,7A,46,75,16,B0,34,15,3E,0F,F0,01,77,CB,5F,7C,2E,42,19,5D,25,56,02,0E,16,0A,C6,70,F9,A6,FA,74,1A,15,B5,B6,E1,4A,80,00,3C,42,61,41,7E,1D,4A,2B,FE,1C,49,2F,9E,2B,D5,77,3D,73,BC,B4,F3,52,47,87,8E,91,30,7D,63,62,83,E3,79,5B,03,AF,4D,31,C8,43,B4,64,1A,97,21,E0,76,EF,F6,C9,55,F5,61,58,26,33,C7,75,91,1B,E2,7B,CA,BC,D0,C5,AB,5F,F6,2B,CE,F5,15,17,5E,B1,75,25,A1,DC,7B,29,00,EA,C6,5A,7B,41,BB,87,26,BB,DA,D6,44,D2,38,93,6A,5D,79,CB,1D,C7,A8,00,99,F3,AF,ED,07,84,CC,8B,14,F9,8F,88,0A,30,7D,0D,37,6B,3A,51,CB,15,83,D4,29,8F,A3,E9,E4,DC,1B,6D,52,28,54,2F,23,65,D7,9A,C3,DE,3F,46,14,34,11,C5,38,4A,DF,43,B9,9E,F9,27,23,B7,99,AB,4A,F2,45,8A,A4,16,CD,57,79,79,41,3A,43,EC,9A,10,08,42,9C,01,AF,5A,05,F4,86,51,B0,00,06,A5,2D,4C,9E,0D,38,29,05,6F,4A,30,C5,C9,97,9C,BC,A0,EB,7A,51,03,A4,6D,10,92,14,80,3E,21,53,FB,7B,A3,00,B0,F7,1B,1D,32,A8,E4,7E,F7,21,C6,45,64,15,45,05,FE,93,45,E2,F6,A6,77,71,00,12,15,E5,7A,D6,67,12,0C,A0,80,DF,8F,D4,39,93,48,DA,0F,44,85,CC,D7,24,88,E8,16,25,C7,97,31,CD,AB,C4,62,2C,8B,30,64,80,AF,BE,18,84,6C,BB,03,FE,3D,66,C2,84,A2,87,73,83,E4,E6,4A,22,9F,AF,38,C4,51,76,43,3C,A7,AD,88,38,F6,35,2A,BE,F8,95,74,21,7E,E0,E0,C0,92,90,4F,3D,F8,F9,4F,F1,3B,A6,CF,AE,36,62,3F,99,02,EB,96,F9,8E,79,68,25,3D,A9,92,ED,0B,41,BA,E0,9D,45,50,5D,3E,3A,4E,F4,29,90,E5,0D,9E,BF,C0,20,A8,7C,09,0C,95,76,90,4B,F7,36,3B,9E,C8,F5,A9,AA,68,A7,55,B3,D6,55,2A,5D,C0,F6,89,A0,09,4E,D0,44,4E,BE,28,DC,57,A8,B5,C4,26,57,51,1E,9F,F4,B9,61,C6,4C,DC,00,42,66,2E,07,FE,B5,3E,69,BB,F3,45,AD,FF,A5,04,37,5D,28,1F,34,0A,B7,26,3F,A3,52,4E,56,03,D5,69,98,3C,06,A7,D2,66,8D,63,75,FB,B8,AE,50,78,A4,FA,4D,FD,42,55,67,82,CB,F1,53,D9,EB,EA,EE,E1,51,60,79,6C,6F,85,74,F0,F1,75,A6,CF,52,19,BE,B4,11,AC,77,DA,3E,A8,FF,07,CD,C8,4D,9B,4B,82,5F,20,DE,C6,19,DA,15,39,57,C4,22,12,60,FF,39,1B,D5,77,27,9A,03,26,31,17,D8,15,FD,3A,49,8F,BC,16,DC,9B,62,FF,31,44,DD,C0,D0,B6,5F,24,E7,5A,7E,1A,61,D2,34,AB,9E,9E,AA,29,C7,7F,44,E7,72,DB,DE,7C,E9,0F,0D,04,16,92,2D,48,96,D5,49,86,AD,AF,72,DA,A3,BB,5F,51,1A,AC,7D,7F,56,CB,BD,00,FA,60,1E,0C,35,1E,62,86,6E,E8 -keyMatrices_inv = 23,16,19,7D,DE,DF,51,55,30,D8,17,12,AF,87,4B,7F,DE,33,04,65,DB,87,B2,19,B6,E0,D7,BE,E4,C8,B1,0A,34,98,06,FB,A7,F7,28,24,61,4B,F2,34,28,CF,3B,B0,70,14,64,16,B2,EA,90,52,37,5A,ED,85,F3,AF,41,B2,59,77,61,49,F2,06,88,FA,8C,9E,47,3A,47,CD,55,C5,E6,60,41,96,43,90,6B,D8,43,6F,A2,20,B4,4B,35,B0,7E,9E,88,03,0B,96,6C,8B,87,48,68,20,1B,9C,4F,3F,71,FC,80,31,18,69,BE,44,A9,0C,42,79,2E,10,73,88,68,22,F5,31,D3,12,BB,B6,4C,AA,97,3B,5B,09,DA,D0,BC,96,81,94,66,0A,ED,35,C9,D8,D4,1A,EB,52,99,56,57,C3,F4,FA,8D,13,C2,B5,91,D6,51,9A,10,0F,4D,66,B3,1A,42,34,6D,D6,AE,BC,26,A0,BB,29,EA,50,D7,E4,B0,E6,03,F6,98,0C,2C,C7,9D,6D,22,AF,7A,36,09,C6,26,E9,50,06,87,AA,C3,5C,06,27,F5,B2,56,F6,24,78,56,FA,3D,EF,8B,9A,C0,30,A0,85,33,44,18,61,C4,8E,B4,1B,73,B2,B5,C8,F1,9B,B8,1F,F9,5C,06,DC,7C,D6,5C,BA,83,93,D2,B4,0D,3F,54,C2,70,22,1B,2C,F8,C8,53,20,6E,F0,AA,23,DB,45,A5,0E,3F,40,AF,E4,0B,98,55,4C,81,F8,FD,5B,18,0F,C8,18,AD,BD,A5,B0,DE,5B,64,D3,3B,1E,FD,C4,A4,CA,ED,A2,39,57,D3,CC,93,88,9C,BC,46,F3,26,8C,28,4F,5D,4C,42,FF,8B,FB,20,EA,59,8F,83,BC,D3,EA,9D,E4,95,3C,F6,80,D1,61,77,14,B3,3E,09,3A,F3,F6,60,82,BB,BC,63,2D,09,59,C7,83,74,14,D9,4E,3E,D2,9F,D8,46,95,4B,3A,36,22,D8,2C,3E,10,18,5F,C5,79,C0,57,96,31,CB,F7,77,DA,97,22,39,D4,00,ED,82,26,8F,97,E7,90,7F,68,5D,B4,70,7E,4E,BB,2A,03,DE,51,9F,51,33,38,31,85,E4,72,F0,E3,0B,F1,8B,E2,D6,DF,56,81,B9,C3,5D,C8,F5,B9,2A,4C,C0,2E,9F,38,00,82,A1,C4,01,F5,FE,22,1A,F8,CF,80,80,F2,52,7F,FA,64,21,C2,4E,F2,23,CE,D3,4E,FB,12,56,55,62,D1,04,1E,CA,BC,1F,49,F3,76,43,CB,DE,73,B8,F9,E2,40,88,48,7A,6D,68,4F,AA,7A,20,A7,FF,54,29,64,AB,F3,DA,89,76,AE,35,E6,55,B4,17,81,9F,96,E4,DB,DD,2F,1A,28,C7,1F,A2,69,9A,03,6D,BB,49,E0,4F,B7,7D,1B,85,65,2D,F9,8E,67,0C,69,62,29,8F,9A,19,5F,34,AA,26,0E,DC,9B,AB,5B,C7,E2,69,F1,79,40,04,04,30,F2,91,BA,8F,59,D6,A3,D5,B9,A9,59,17,94,2F,34,CD,F5,1E,E9,03,AF,07,98,94,CE,46,0C,61,42,F0,85,71,E3,2F,30,B4,D6,FB,EF,13,93,DD,EB,74,2A,EC,F0,71,12,99,18,C9,3B,12,D3,0E,45,AD,FA,3C,10,F1,1C,F1,BF,E4,C3,EA,CB,44,79,57,92,2A,5F,DD,32,79,D3,54,5A,83,C2,4A,72,87,8D,E9,40,16,F3,5B,22,04,B1,C2,02,61,DC,59,BD,C2,45,6D,75,31,CC,E6,86,17,4C,24,FD,53,15,5A,0B,4B,65,54,DC,06,C7,BC,E4,6E,56,4B,D3,C8,1E,E2,B4,76,78,D4,F6,C9,63,FF,DF,50,5B,F0,E6,A3,6D,44,9A,27,9F,46,49,1F,74,9F,DE,53,F4,74,3D,A2,49,AC,7E,8F,AA,76,DC,AA,0B,52,04,36,C9,54,85,88,EA,C4,3F,D9,8C,F8,EF,FC,A9,88,2C,CC,F2,C4,E0,E9,C0,D2,20,C1,7B,48,D4,3E,7B,C3,0E,F5,64,80,14,D2,BF,F0,15,66,D6,F3,4A,EB,CE,1D,A0,C9,94,4C,BD,D6,31,D5,8B,37,51,3B,0A,0A,92,BA,B4,E8,37,77,30,72,DA,73,4C,D8,8D,DA,A8,FE,1A,DE,68,51,0B,E6,8A,B8,D8,A3,42,6A,6E,E4,69,A7,17,4F,1D,0D,10,C2,6B,32,56,75,28,82,2C,28,8B,53,A6,C4,12,CD,09,8D,8E,C9,48,03,8B,0A,96,38,D7,99,5D,B9,E2,4A,E3,DF,85,06,19,D1,E0,EA,66,06,3F,9D,2B,3D,B2,E0,06,EC,89,16,7D,2B,A9,C6,43,67,BF,3C,9E,23,94,FD,A6,A9,D5,DD,0F,2D,FB,44,51,33,61,12,7B,12,C2,5D,12,1C,D3,68,20,DC,81,43,3C,A2,79,62,C7,E1,C9,15,58,DB,66,EE,53,0C,7F,47,CB,ED,FC,82,F6,DE,CC,30,3E,5F,D3,3D,DC,F3,6A,7F,74,1A,FC,01,CD,89,EB,E2,24,79,FB,A2,40,82,00,F7,F3,75,86,62,F2,AD,98,63,14,E7,79,40,27,95,53,DC,82,A9,E8,C7,1C,55,2C,71,02,5E,6F,A6,CE,BA,C1,17,5C,53,C6,97,C0,11,E0,20,A1,0B,E3,46,F9,77,6F,2C,8D,22,16,74,C6,0C,12,4D,E0,14,94,C6,4D,EE,8D,32,3D,44,59,63,DF,E0,D8,4C,C8,23,C8,2E,4D,CD,53,83,CA,50,EA,1E,19,FF,36,85,E8,44,8C,76,AC,F9,1D,BF,0B,22,32,C3,23,AC,84,99,D7,49,05,0E,B4,8B,33,F0,2B,35,35,37,23,6C,38,64,4E,7D,FF,C1,54,58,88,EA,F8,A4,D8,DF,1F,D5,9A,8D,C9,F4,2C,A6,57,4E,6C,CE,20,8C,F3,1F,73,6B,22,3F,28,1F,85,3C,36,67,B9,D4,5E,7F,99,30,3A,4E,C4,31,5B,26,B9,11,6F,6E,4D,0A,3A,F4,CB,37,B1,61,2B,72,D1,8D,03,7C,2B,9A,04,16,EA,CD,2F,94,51,AD,BE,86,F5,C5,92,33,71,D2,08,51,8E,C7,95,BF,FB,77,01,41,C5,34,BF,95,DC,FA,B1,DD,BB,FD,77,F3,9D,38,E0,DD,29,3C,AF,5E,29,DB,A0,8B,D3,5B,11,45,E5,A5,EA,BE,55,88,8E,A3,0F,7F,15,1E,E6,1C,51,2C,8D,0A,CA,08,F2,8E,27,BB,5B,CA,3A,E8,FD,C7,AF,60,3A,FD,FA,31,8C,D1,86,26,EC,D5,0A,EF,41,56,04,33,10,DD,DE,DF,D9,88,14,A1,AE,26,5E,EC,0C,10,22,B1,F8,4A,21,A6,BA,AB,FF,C8,15,4F,FB,DA,F9,DD,0C,6C,53,E4,3C,87,59,99,AC,11,7D,09,E7,88,D1,7C,84,65,31,DE,49,07,44,75,B0,4C,31,BF,B2,D2,20,FE,B3,36,74,7B,2A,19,6E,F7,9D,D3,D0,5B,37,FA,E2,64,69,14,29,6D,19,88,4E,D4,29,AE,4A,B2,57,D4,93,64,8E,1A,7E,C0,C8,5E,6E,57,27,A7,19,25,7A,E4,A1,9E,B0,0E,58,BB,EE,3D,DF,B3,49,9A,4E,7B,1C,C1,50,74,70,EF,0B,E9,D6,D4,48,5D,13,41,25,48,83,80,94,D2,1A,71,05,09,6C,C5,ED,44,93,44,A4,F1,14,E9,24,A8,12,F0,E2,C7,C0,18,A0,E3,5E,BD,7C,46,AB,35,E2,E8,98,BC,6A,99,15,FC,25,96,41,1B,29,B9,A9,C8,E2,C6,47,96,E7,12,CA,30,C9,A6,2E,E7,5B,E5,1C,20,DD,A7,1B,CC,28,F1,83,57,65,E9,40,47,DE,9C,62,12,7A,D6,17,CC,AB,13,F2,37,F1,84,97,46,7F,ED,1A,93,56,5E,05,A9,ED,65,05,CA,3A,8D,E0,F1,03,DF,10,F3,6B,D9,4A,75,5C,4D,A0,1A,A9,33,D6,39,85,21,98,54,42,EB,08,44,9E,AC,C6,43,1A,54,90,F2,52,90,32,42,C5,E5,8B,52,DB,99,1E,85,14,8B,51,9A,67,71,C7,9A,DA,CE,4B,60,C6,2B,73,7D,9F,71,AD,74,2C,D6,3F,47,83,E9,A6,8A,06,6C,0C,B8,15,75,EB,16,E5,AB,29,8C,E9,DC,8C,66,76,65,D5,F0,D3,1F,8D,CB,48,57,75,49,FE,4F,71,E3,A6,73,82,61,CC,85,18,32,1D,38,17,0C,F3,13,49,13,85,0B,4B,48,BE,F9,57,0C,59,CD,09,6E,0A,D3,47,F0,88,C3,12,71,B8,89,37,FD,4A,CE,C5,A0,3B,87,74,95,A6,62,2A,0E,47,1F,E4,28,11,77,E4,9C,4A,68,AC,84,54,F8,6C,50,E6,F5,C1,1C,B7,2A,90,5B,6D,F7,7E,39,29,FA,D6,F8,85,4F,6B,EB,F5,ED,86,4A,9B,3B,4B,68,DB,92,D4,8D,07,88,94,9E,48,E4,61,48,56,33,2B,00,B0,7C,25,6F,DB,A5,DB,6B,60,BD,45,2D,1C,50,6E,A9,A5,AD,14,A3,29,BC,16,E8,E2,5E,71,87,FD,F7,7B,D5,D2,A2,FE,34,CF,30,31,C7,CC,FD,8C,E2,88,D7,A5,C9,E0,EA,96,CD,82,B4,1C,5F,52,B0,0E,DE,3E,E5,EE,C8,BF,ED,AB,2F,D4,A5,5E,8C,A1,C0,E8,6E,2C,BB,63,3E,FF,B4,52,B3,96,29,CE,6D,6E,04,09,08,CF,45,88,0E,85,F6,63,DA,8D,B6,B2,09,19,97,CE,D5,FA,AE,BD,D7,4B,14,68,33,B4,07,8E,F8,66,F0,B8,0E,A7,B5,D2,A1,F8,8D,52,78,30,5F,5B,A2,5D,46,2B,DA,D5,C2,90,18,40,5C,9A,DD,F6,99,FD,33,81,1E,C4,C2,EE,31,99,2D,2C,5C,F5,6D,59,77,7D,C9,1F,AB,C9,61,9A,1D,3D,27,6E,F0,20,1E,9C,8F,0F,9D,62,5A,8C,64,98,93,88,8A,04,84,B2,BE,3A,C2,E2,6F,9D,26,D9,F4,46,8E,8B,D6,F6,98,F4,EF,97,17,57,FA,0B,93,6A,1C,2A,EA,E6,3E,76,0C,C5,D0,CA,7F,3D,42,3A,38,24,5A,BA,78,47,56,42,33,30,D7,9F,D4,2C,37,48,B0,F0,E3,19,E4,24,28,CF,13,91,16,F8,82,7E,C9,C3,98,F8,2D,B5,21,EA,9A,80,68,EA,09,3D,50,5E,DF,7F,B6,C0,31,2A,57,8E,A5,FD,57,66,47,09,61,4B,23,9B,EB,A9,1E,3F,20,59,11,65,4F,A2,D5,28,AE,A9,B3,1B,1B,AA,C7,46,04,4B,7B,21,16,96,91,B8,2A,68,F9,E5,52,4C,52,01,3D,00,14,D0,85,1C,36,09,D6,B4,4C,8C,28,11,EE,A6,4E,F7,2C,F1,46,8B,BE,CF,4A,99,44,7F,CC,AD,44,5D,27,D3,EC,B9,32,D8,D0,B5,D8,58,F4,46,40,27,6F,E0,C3,97,A2,75,C7,67,23,03,A4,08,6A,11,27,CA,89,59,18,88,1E,32,6A,56,19,6B,2E,38,DA,B5,ED,C0,A6,44,03,D1,C2,A9,1D,08,B5,B3,35,73,26,5A,56,54,E9,E8,C6,D6,3D,3D,2F,D4,09,0D,70,16,64,EC,8F,2C,35,23,68,20,DA,01,C3,9D,80,AB,8F,E3,6E,46,6F,07,52,11,25,85,58,E5,16,82,96,7F,25,D0,DA,4D,C7,C7,87,70,83,28,B8,F0,ED,FD,78,C2,7D,28,40,DA,9E,F8,90,2C,EE,8E,3C,B6,0F,36,96,54,25,7D,5F,31,7D,F5,63,B1,F9,42,08,CF,96,81,58,C5,80,90,12,38,A8,59,2E,0F,46,12,BB,49,54,5C,B7,B1,9D,94,38,50,DA,3A,EA,C8,E3,46,23,E9,08,AD,B6,5A,1E,61,01,5E,7A,37,0A,AD,03,CB,28,9B,FE,4C,03,A5,E9,8D,E4,DE,0C,22,8F,AD,25,11,DE,67,7C,0D,0B,24,97,24,03,86,B5,32,44,6F,7A,04,A6,61,36,56,FC,EF,E8,A8,A1,1C,47,24,33,84,CD,8C,C9,8E,77,FC,4F,6B,38,EA,FE,54,99,EA,47,08,A3,D2,1D,2D,82,32,15,0E,B2,5E,5B,7C,6C,F6,C8,F0,71,EB,91,31,87,6A,2F,0C,02,2E,0D,E4,60,C4,02,1E,8A,AE,ED,47,3F,38,76,1B,C3,F0,D0,F3,A0,2C,AF,5E,AD,15,03,5B,99,B7,35,70,67,4E,EA,5C,9C,D4,E8,45,19,E6,EB,34,CA,F0,DA,6D,A2,DC,07,D0,E7,DC,F9,90,8F,BE,13,BF,58,6F,6D,48,1A,A9,19,7E,3E,11,B4,41,5D,FD,77,87,F2,E0,39,7D,97,53,DA,D1,FB,58,53,98,07,F3,E7,8C,E2,EC,36,A5,64,7B,73,F4,C3,C7,6B,70,36,78,DF,04,F1,EE,C0,40,61,F2,29,B0,BB,E1,31,C0,51,95,AF,A7,14,58,40,21,EA,7A,7D,44,55,AF,E5,77,77,0C,8B,20,F3,AA,8B,50,0D,4E,85,F4,20,C2,21,EA,A0,17,2D,92,F0,C2,2F,FA,45,F6,5E,45,1D,F3,5F,EE,D5,4A,20,74,34,EA,37,06,1B,6D,A2,E9,0C,5D,F3,17,6D,80,94,C3,57,31,1F,C1,FC,3D,51,43,EE,02,C7,80,5E,85,5D,AA,3D,A4,D9,1A,98,51,B1,4E,15,A6,38,7B,F1,6D,62,7C,EB,19,6B,F8,90,D2,05,D3,F0,59,9D,55,41,43,EF,B0,AC,44,85,D8,D8,79,00,2A,D3,29,67,42,51,5D,AB,2F,F5,A0,8F,DD,5E,0C,50,E7,17,79,A1,5B,68,A7,89,16,D3,E4,05,34,F2,EA,75,C8,AD,3A,F3,DF,55,84,52,D8,BD,24,3F,C2,F2,02,BB,49,CB,AA,0D,85,F9,91,99,3F,B0,F6,0A,27,F9,91,3F,35,20,62,4E,C9,CA,39,7C,65,8F,02,72,7C,28,7E,4B,79,B9,18,E6,52,63,66,00,89,75,6C,32,8C,F8,9B,F1,51,10,1A,CB,73,F9,F6,7A,39,F6,0B,EF,EF,63,DF,A4,97,9C,AD,4F,7A,AC,EC,95,88,21,EA,84,3F,27,32,45,A5,7A,C8,95,A1,79,39,EC,81,CF,1F,B0,EC,C4,8E,7D,C2,62,69,1A,95,AE,6B,EA,48,A4,30,83,07,23,94,8F,3C,04,F8,A0,A7,E4,2E,16,0E,BF,28,E8,69,12,A5,66,DE,4F,D8,32,71,A0,17,0D,C1,2C,A2,E3,A0,AA,8E,62,4A,74,82,97,64,15,08,0D,41,53,D9,C3,9E,65,84,6C,BE,C7,25,27,3C,3F,B2,97,20,34,E4,DC,78,AF,C8,BC,DD,FF,00,7E,1B,94,F8,B2,57,B4,7F,4D,66,F7,E4,6C,B4,E3,74,9E,14,F8,6D,60,E9,C9,60,A4,4B,89,56,14,93,D2,17,16,B6,3D,3D,4D,0C,E8,22,65,96,46,7F,0C,8F,C5,39,A1,43,7F,55,14,29,BF,74,0C,1F,B8,CE,2F,BC,00,9B,28,2B,0F,49,85,05,0B,D2,3D,5F,92,6E,A9,A4,6D,A5,E0,EB,7C,43,FE,FF,3C,58,44,FC,19,BC,4D,E7,0C,BE,34,B6,73,70,C4,6F,4C,63,26,84,35,AD,6A,F4,D4,2C,C5,C7,16,83,F9,F2,F3,B8,B3,F5,22,6F,71,C1,E7,62,AF,8D,C8,C5,7C,60,F5,DD,E4,05,9E,8F,B6,85,71,7C,F3,74,23,7C,10,4A,DB,2A,1B,B7,56,78,93,0C,5A,03,58,9B,80,DF,49,45,73,95,D2,54,DA,47,11,0E,83,FA,12,4F,F6,7A,18,A3,5F,2A,D7,6E,01,E6,37,89,F4,39,EA,72,0E,CC,32,FB,71,B7,81,40,B8,22,54,CE,16,2C,5F,F5,81,66,17,54,FE,38,98,71,58,CE,E8,BC,F6,A7,7A,7A,B6,44,51,B8,EF,5F,D7,6A,E1,95,9E,37,8A,93,10,FA,95,47,26,B8,C5,C6,B6,36,77,C7,AB,30,EC,BD,F5,17,C7,8B,C1,D1,45,89,71,1E,0F,A1,F6,00,ED,BA,4C,A5,E5,7B,AE,AE,18,F6,A7,04,6B,47,CA,22,1C,7F,1C,AD,39,B6,B6,4C,A0,E0,B6,82,C0,44,EE,F5,15,80,82,EE,53,F0,A4,5E,D1,B6,C6,D9,1F,4D,DB,3B,4F,78,C0,7C,DB,31,62,6E,C0,C1,BD,88,D6,CA,D2,D3,B6,D9,D9,0D,D3,67,10,76,ED,C0,95,AF,06,F7,2A,7B,BB,49,8B,C8,FE,C0,18,72,97,C6,78,3B,D0,68,EE,8F,C5,D6,9F,31,4D,61,79,79,B7,B0,C8,C6,1F,58,8E,36,C2,B8,96,C1,EB,70,DF,C7,33,76,BE,7E,C3,E0,7D,5E,82,3B,B6,24,B1,6D,5F,E9,26,54,C4,12,25,A8,C5,B2,9E,57,96,A6,98,AD,98,6F,FC,A3,E3,FC,A6,AB,EB,9F,9F,B0,52,97,1A,EB,8C,9A,7C,08,5C,D8,8B,71,C3,77,0A,10,2B,2B,E1,29,F1,92,54,4B,34,C9,20,DE,8E,9B,8E,AA,00,16,2A,07,CF,34,15,4A,73,FE,07,02,1B,40,CE,B7,90,F6,20,F7,EA,DD,4B,81,34,0B,3B,D4,38,59,D2,AC,21,82,51,E2,1B,3A,A7,70,10,D5,E1,85,92,8A,FE,C6,BB,88,5E,CE,43,5E,EC,2D,FF,39,4C,A7,B3,2A,81,78,63,7E,9A,B3,49,EE,44,A4,50,1F,CF,8C,08,47,DC,58,DC,0D,8C,74,59,42,39,66,DD,A1,C9,77,0A,79,4A,CE,0A,2C,D0,11,50,0D,E9,22,3F,2A,CB,BB,81,29,6D,3C,65,A9,54,6D,54,49,B1,CB,68,F0,94,8A,F3,85,0F,2C,6E,EF,D7,CF,AE,C5,E1,02,88,37,47,81,29,58,F6,5A,A6,8D,4B,52,0B,97,87,3B,A6,5A,F0,54,D8,DC,C2,2B,D5,6E,E9,F0,D9,1E,3A,02,29,65,03,DA,92,9F,86,7C,8C,AF,FA,15,01,79,D1,3D,09,1D,FE,56,88,C6,88,D7,56,E1,4F,0B,17,EC,A2,EE,C6,55,BC,A1,B6,04,47,8B,0E,DB,32,A4,3B,B2,F9,D1,E2,FD,6C,E3,6F,06,00,C8,8B,7D,EC,07,A1,89,6B,A6,DC,51,4F,2C,4C,6B,DA,77,73,86,A0,08,88,A7,F7,81,C9,52,00,AF,B8,B7,11,AD,43,D2,E7,E0,9E,38,15,22,B5,3E,AA,FE,A2,03,BC,55,03,71,FB,20,7B,90,14,5B,C0,EF,49,AA,49,3C,E8,DC,82,B7,7D,7E,B7,17,3C,46,36,13,E6,AB,7A,99,CB,96,DA,67,87,4D,43,25,AB,EB,36,C6,75,D0,8D,F7,45,68,4C,0F,D5,81,CB,48,F7,86,E9,86,79,0D,60,27,89,31,40,88,28,06,5C,FC,D5,1A,37,F2,CF,4D,E8,B2,13,1B,4B,6F,DB,06,97,30,D1,56,60,CC,08,AF,FC,2A,26,A9,F1,7F,A0,E7,B2,C1,D7,3E,A2,63,BC,69,32,77,38,B6,FC,48,97,7F,4B,1A,7B,EC,A3,FE,F7,5A,90,F4,C1,39,C7,A4,1C,30,21,A0,97,2F,E4,22,F9,8E,D4,16,31,39,DF,AE,E9,DE,05,90,A7,A6,6A,63,7D,8C,B4,FF,F8,6E,DB,97,6B,47,C8,0F,E6,40,69,5F,33,1B,F6,95,AD,7F,61,49,10,EB,D2,91,B1,54,C1,17,1D,9B,07,41,D5,56,71,74,1F,EA,71,A3,EB,8A,2A,B4,98,82,1B,8C,D4,3A,98,BC,8F,EE,6E,0E,18,72,93,A7,7E,60,65,10,A9,8B,4A,8F,56,0E,8A,31,BA,C8,86,CB,37,EF,C0,99,0E,39,CF,21,2A,A2,5C,9F,CF,B2,2D,9F,3E,2B,35,8C,84,4E,F2,5B,D1,21,BD,14,05,9B,FB,2B,E1,4D,60,D1,B5,C1,62,67,84,C1,B0,B1,83,9C,C4,83,04,A3,58,ED,A2,86,34,92,25,DD,33,89,3B,05,0E,D9,52,57,D8,3E,7B,FF,2E,2B,31,22,36,4B,8F,D4,22,35,7D,75,51,CF,10,45,6C,81,EC,E4,C6,19,CC,6E,99,D5,62,80,67,E0,72,88,0E,BF,A8,6D,ED,D6,5B,48,6D,57,D5,F4,36,9A,A5,D7,AE,0F,71,AD,76,74,3D,02,3E,50,53,F9,E5,4B,F8,00,7A,D3,5A,F4,F9,2E,ED,3C,5E,3A,17,A8,0D,87,7A,65,18,46,AD,19,C2,0D,C4,C5,18,87,03,21,39,DD,98,0E,7F,E1,87,06,E4,F9,53,1E,9A,5D,FD,01,F0,2E,70,E5,7C,EB,88,61,88,1C,D8,CF,E1,21,65,65,FB,93,93,E2,43,7F,95,D0,DA,9D,18,5A,A4,13,A2,6F,CF,BA,45,D0,36,8C,9A,C6,66,96,71,96,FB,BB,94,02,8B,4E,D8,F9,CE,D6,98,6B,96,C3,3B,8E,76,EA,AD,1C,94,5A,C3,81,E1,BC,64,EC,4D,34,A1,A5,69,CB,EC,A8,26,30,1F,06,F1,27,C4,58,3E,EC,C4,22,AC,1C,95,51,3C,2C,D9,3C,F6,94,10,1F,55,D7,5B,06,9C,6D,83,4C,72,53,A5,8B,9F,F2,47,4F,7D,96,3B,20,C1,50,F1,02,5E,68,D1,0B,D2,EE,C7,29,3D,83,B1,E2,1B,93,59,B6,0A,3B,94,04,61,E4,92,37,1C,9C,41,0A,67,BA,E3,1F,74,4D,83,6D,DF,46,14,09,B2,80,5D,1D,EA,75,14,75,45,05,A9,35,78,80,8A,81,D7,4C,3C,42,A8,C5,0D,45,9A,31,6C,74,22,2B,62,6E,61,3B,75,AC,59,CB,58,D4,F2,48,61,AE,C1,6F,CB,79,6A,46,BC,F2,59,D7,22,20,C6,E3,A1,E4,76,9D,E9,F6,14,E4,17,52,62,2D,5A,73,1C,C7,9F,2E,92,FA,54,2C,B6,4D,FB,DE,FD,53,44,4C,6A,D6,EB,A0,F9,BC,F3,3C,12,FA,7A,CB,3F,F4,A8,81,42,22,E0,55,1D,A1,16,AD,4A,E1,BC,2E,DC,89,D9,5F,40,51,E2,C5,3B,0C,9C,68,F8,C3,E8,B1,56,2C,7C,40,7C,55,0C,94,22,09,4C,33,9A,B8,68,50,5F,12,59,BB,50,2A,C7,3C,2A,DC,56,40,3E,D3,9B,6C,07,C4,E7,68,6F,60,A4,8E,DB,6B,BF,98,42,B7,98,D6,15,2E,F0,1F,D4,F0,AF,B9,BD,C1,34,46,D6,32,8A,8B,DD,AC,0B,55,25,EE,C3,22,7A,DF,81,AC,FC,0D,8A,FE,56,D8,16,8E,0B,87,0F,82,96,4A,4D,B0,A7,C3,CF,C9,F7,85,B4,8B,59,CE,D2,4A,6D,4E,1E,9A,6C,5A,CC,BE,E0,53,D0,94,84,1F,D2,56,5A,92,F7,BB,F0,F7,09,BD,4B,72,F0,FC,A5,F3,06,B5,F5,91,63,33,C3,37,11,D6,51,01,5F,43,A5,78,1D,BF,40,68,51,E3,2D,D9,9B,E6,01,6D,A0,23,74,2E,83,18,BE,99,3C,F3,2A,D3,FF,D4,32,EC,D6,47,B8,08,F1,5B,DC,4A,AE,F3,51,CB,02,E7,DF,99,13,2D,C8,A1,31,3E,33,69,C0,A1,77,53,2A,CA,F1,20,01,0D,53,C6,00,9D,4F,3A,51,8B,00,F7,D6,D1,6E,7E,B0,D0,0A,69,67,8B,DB,19,C7,83,4B,A9,73,58,49,88,5D,79,07,C8,29,B9,FA,8B,E5,8C,34,BB,07,7B,7C,0F,DD,A1,D4,3D,C4,08,33,3D,65,9F,98,70,93,32,E5,C7,B9,B2,E7,D4,1A,39,04,2D,D2,C4,A9,2F,EC,E8,56,E5,14,86,29,32,3D,D4,B8,06,A6,C0,4E,A1,5A,BA,C6,D9,DD,8A,E3,C3,AC,E2,CB,8F,31,26,37,14,04,1B,71,5A,A8,7E,BF,76,35,F7,B6,CD,72,78,0D,96,DC,E2,E6,02,DD,28,94,21,09,22,E9,A3,28,96,68,6A,5F,86,A4,7E,C8,4C,0B,18,8A,93,F3,1E,92,76,0A,D5,32,92,8C,4C,F6,EF,8E,39,78,21,3C,26,BA,6A,BD,E9,BC,8F,34,CA,98,5B,CA,AC,44,85,59,60,8D,60,F4,23,C3,66,3B,21,32,65,21,03,32,6D,2A,85,0B,F5,E6,7A,61,DF,B5,E8,03,A5,40,C3,DF,6A,8C,71,86,5B,42,93,DA,56,75,6D,A5,A2,F3,A5,FF,75,61,20,B4,A4,58,D3,C6,A4,E2,6F,C4,4E,D8,44,F4,BB,1F,6D,D3,48,A3,C6,D6,6C,FC,C0,48,B8,A0,A7,85,BC,60,53,8A,31,D1,77,E4,D0,F2,16,8B,29,AA,0B,CE,54,65,DF,1B,A8,94,87,10,24,C1,39,E9,3D,44,D1,F6,38,31,0E,7C,20,A1,4F,DD,75,AA,9C,B7,68,B5,05,A3,17,1F,18,C9,2B,52,CB,37,A8,51,01,24,50,9F,C0,AD,05,66,F4,FD,EF,78,1A,35,81,CF,4D,0E,15,63,AF,DB,96,9A,1B,B7,6F,F7,E6,0B,AC,C1,5F,8A,38,EF,48,BF,10,D2,48,F2,97,54,B4,37,C3,2B,C5,B4,FD,22,80,02,35,82,43,F3,06,51,BA,5A,DC,9F,7C,38,CC,2C,AF,0F,AD,BE,DA,70,CB,C0,19,C7,A3,9A,A6,E0,7A,C7,CA,62,14,A7,6F,9E,DC,7C,BD,E9,A0,86,2E,88,2E,C7,CC,2A,AE,41,E4,EE,46,17,04,42,43,10,83,8B,07,85,85,00,AB,55,3E,60,C6,6B,C9,D5,92,D2,6E,E0,5C,F4,4B,4C,C9,20,72,D1,CE,2C,8E,65,84,E1,FE,FC,5E,6C,51,A6,75,F7,74,3F,33,7A,D6,41,94,E8,34,B5,D0,73,09,8C,CF,D2,1F,B5,06,37,58,18,9E,72,85,84,1B,2F,4F,25,8A,F8,57,70,3A,74,C9,39,F2,4E,FF,84,48,04,C9,00,58,02,09,55,9F,91,E5,83,F8,BB,F9,97,BC,E9,27,45,B5,E5,5A,94,D5,C5,23,59,12,D7,83,8B,59,8B,1F,EC,4E,5A,C2,25,BD,FD,D3,9D,7E,C4,CB,B5,E3,5B,95,41,6C,12,20,B4,6F,6A,63,F5,A0,02,53,D0,F7,19,CC,59,B9,44,01,F1,33,06,57,9B,E8,80,C6,FB,FB,67,B3,FA,D3,A3,B7,5C,6D,54,37,AC,10,93,04,E7,1F,77,A8,87,AB,C9,BE,B4,DB,40,FA,3D,72,5F,AF,05,F0,56,6A,88,3C,F4,42,2B,2B,2F,33,CF,14,46,01,60,ED,D7,D7,3A,C7,32,CC,05,7A,15,50,64,30,8F,8C,1F,AD,0B,C4,AD,ED,F5,C2,83,6C,74,EC,1C,74,BD,4F,8B,19,93,1C,62,43,F6,85,4F,49,C7,19,C2,F4,D7,CE,01,05,06,D5,1B,BD,0F,AD,41,25,3D,C4,DF,BC,8C,9A,EE,3A,B0,F2,78,47,DC,48,1A,DC,BF,91,E7,DD,1F,D3,DC,C9,AD,22,54,A1,E1,12,39,47,4F,3A,BA,78,F8,A9,56,70,3C,DC,D2,6D,10,8B,F1,5A,DB,84,0F,34,A8,B8,6C,A9,C8,40,E1,F2,4E,48,09,FF,51,38,0C,5C,8E,B3,25,57,EB,03,1E,51,FD,16,87,7C,3A,27,FC,B1,71,F1,22,CA,D8,A6,27,9F,14,19,E2,DB,F8,00,B4,90,09,27,96,BA,47,FF,08,A8,A1,A6,72,57,83,71,49,48,36,E7,CC,57,87,B5,27,09,DC,FF,1C,19,9F,88,9B,30,F9,10,DF,01,5E,F2,FE,10,5C,CF,47,4A,F2,61,1D,46,25,44,34,69,85,54,3A,48,A0,FE,D2,08,BB,A0,17,B2,F2,A0,C8,58,D5,B7,3F,66,72,B6,D5,57,16,46,43,35,F9,C4,77,DE,68,B0,02,0C,C8,4F,85,38,8D,7A,53,DA,6B,63,A2,F0,18,D5,B5,AF,C2,FD,21,BB,9B,D6,05,70,48,54,62,27,B3,CA,71,DB,26,9C,92,15,31,A3,3E,8A,44,CE,D6,02,92,7D,6D,80,BD,42,A9,9E,1F,AE,A7,25,A1,33,9A,E9,F2,58,C3,95,5B,81,6D,AB,DB,AF,F9,EC,B8,2A,EA,D9,8A,2A,A4,9D,7D,07,B2,B5,9F,57,E0,F3,E5,0F,A8,9D,E7,99,0B,30,F7,8B,83,3E,0E,AF,C7,BE,80,21,B9,E9,BF,77,31,85,B6,D8,B9,FA,94,04,6F,D0,02,4D,74,44,4A,02,82,1A,88,0C,77,AF,B8,8B,88,84,F6,1B,FB,DE,11,E8,7D,B1,44,2A,7F,61,EF,C6,B8,74,6B,42,1D,AE,0E,D7,2D,AD,11,F3,5A,C6,69,BE,1E,5E,A0,08,23,AD,11,F7,09,A3,DA,58,AE,B1,C0,50,16,5B,02,CC,0A,47,80,8E,8A,92,0B,78,E2,DF,02,5B,54,DE,AE,35,06,3B,B7,91,2F,04,76,1E,F0,35,FD,64,94,D0,B6,09,BA,9D,00,C2,20,FF,42,91,83,79,76,16,84,FC,AA,86,44,C0,09,18,6F,C6,C9,08,FD,02,92,73,17,4D,05,CE,9C,D1,3A,38,94,98,22,A2,2A,AF,CB,A1,07,F8,CC,2A,4E,99,81,FE,74,13,A9,08,08,5C,29,6E,55,C5,C3,DF,78,B5,EF,A2,95,31,1E,F7,34,5A,6C,79,C1,FE,97,DF,C9,67,D0,90,AB,2B,F4,69,BB,DC,3F,3D,08,38,B9,E1,29,D2,6B,F5,CC,ED,64,90,6F,7B,96,F4,D3,1E,A7,FD,80,CE,EC,D9,2B,BB,FD,04,5D,14,A5,DB,77,04,14,BA,3A,6A,58,4D,C8,87,FE,ED,0D,4B,79,FC,2E,A6,D4,05,13,63,78,E4,34,2D,72,D8,A9,28,D0,7A,35,47,36,FF,DB,E0,6F,C4,1B,82,F4,5E,E9,64,E8,3C,02,2A,EB,9A,42,0A,90,74,EE,4C,B6,DE,57,C5,E1,99,C4,1B,2F,59,05,6C,FB,D2,65,7A,BF,06,E5,32,1D,C9,F5,2E,10,0A,E8,A2,F9,43,7A,7F,55,42,19,DB,10,C3,37,8B,DE,23,EC,53,DF,A9,38,86,C3,33,8C,5A,9F,7D,73,06,C6,B8,1C,EC,67,23,A4,95,26,46,26,21,FD,5D,80,1C,DB,D0,09,4F,39,71,CC,96,DB,68,A9,B4,A3,44,AB,3E,1D,B7,44,A7,C9,A3,3A,58,93,E8,B4,53,0B,D5,19,A4,71,07,E8,A2,92,6A,7B,26,6D,2E,74,04,05,C6,49,9A,E6,2A,98,E0,33,1B,4E,BE,FC,02,21,01,27,70,E7,68,C2,07,BB,D1,50,63,0F,E9,40,DE,C3,05,AA,40,96,A2,CC,C1,86,A6,6F,60,0F,CD,DF,56,01,83,FD,CE,85,5A,26,DF,61,D7,46,07,09,D5,E3,A5,B3,81,22,5E,64,14,DF,A9,0A,CD,F0,A8,29,C0,43,F3,8F,2A,05,1D,BB,32,38,5D,92,FB,E8,9B,9A,16,73,0E,7E,8F,71,79,90,DC,1F,8E,FC,6F,1A,D6,86,26,B1,30,E3,2F,1B,12,07,5E,41,B9,5D,16,AA,AB,0C,3D,AB,10,7E,DB,9B,A2,DD,0A,9E,0B,D3,CE,73,B1,95,16,22,F6,58,85,AF,17,CF,F0,67,2C,33,F9,BF,26,8D,F2,B9,DF,1A,E8,97,34,50,9E,F1,27,A5,E5,AD,26,E5,29,47,BC,0F,9F,66,C2,B1,CF,82,4A,73,4B,93,58,94,33,B3,FE,73,46,83,98,03,10,20,73,D0,57,BD,94,2B,D8,F5,C5,68,B3,50,5E,C0,1D,E6,1F,E0,36,A1,7B,70,5C,A0,68,A7,2D,4C,51,37,CA,6F,4C,59,E1,96,29,4D,41,58,47,3B,FA,CC,D2,01,1A,9F,7C,34,B8,2C,61,75,F2,78,00,06,AB,40,9E,2F,34,F1,06,63,F9,56,94,7A,8B,4B,F3,E5,B7,E9,29,E2,02,EA,33,3C,61,4E,C0,CB,21,1D,B7,7C,02,8D,2F,CE,72,47,39,6E,42,53,F6,1C,2E,AB,51,CB,63,FB,B1,9A,C9,F7,E7,0F,89,C6,80,1C,5A,CB,5D,AB,34,19,B8,81,30,F6,DC,8C,66,49,43,C3,5C,57,6B,0A,07,6C,5B,85,B8,53,5C,B9,CC,80,50,10,6F,F5,0C,40,AF,0E,09,72,E4,F5,A2,25,2A,BB,24,B5,02,CE,0A,B2,A3,AD,EB,44,F7,39,55,D7,2C,C0,79,99,C7,68,21,D2,FD,08,C9,54,20,DD,F4,72,6A,37,DA,F6,C9,04,94,99,9E,07,0D,AD,0C,1F,8C,8B,E7,C9,0B,C4,5D,DA,A3,92,99,3F,6C,B6,5E,97,A8,94,32,C2,F6,C1,6E,3B,1C,5A,6C,CB,0C,AF,50,4A,3E,00,5F,1B,29,4E,BB,F3,69,7F,E7,36,E8,24,96,B8,5A,3B,85,26,88,C5,C5,47,4C,75,A5,64,48,2F,BB,FD,81,C6,E8,31,AD,7B,2D,1F,5B,FC,97,B1,14,DF,48,83,59,70,2F,0B,1F,E7,EA,CE,47,25,1B,E7,82,ED,08,F7,8E,37,DA,C3,C6,29,7A,B9,F1,93,75,E0,10,EF,F2,76,8B,0A,57,A0,0F,F8,E2,BB,8C,25,62,F9,91,7F,C2,36,97,3E,83,09,CC,38,41,3E,9E,BA,BC,FA,CA,D3,D4,E1,0E,20,B8,7B,A3,41,99,97,34,14,58,55,02,04,16,1F,17,91,72,DF,F7,47,6C,F7,3F,D9,3B,B6,08,40,F8,43,01,8A,B0,27,C4,3F,73,5E,B7,D1,AF,7E,FC,5B,C0,E3,21,1C,56,2E,C2,9F,9E,55,85,04,F0,02,9E,A8,B0,7F,E0,FF,5E,5B,DE,AE,44,74,29,7D,63,D2,86,2D,F0,76,DD,FF,DE,A5,9B,A6,6E,17,A4,30,87,DD,8D,0F,54,AD,8C,AA,76,69,6D,B2,E0,1C,8D,DA,8D,41,EB,9F,EC,93,B6,25,D0,D4,62,C5,D6,55,4A,78,22,A4,27,F5,4E,B7,89,82,46,92,B1,70,C8,7C,8A,D5,15,22,C3,A0,44,28,D7,91,07,F5,FA,1E,5B,A8,4B,55,5D,5F,82,0B,EA,E5,91,DC,43,A3,68,41,C8,CD,93,3E,03,42,3B,09,5B,BA,A8,41,8F,3C,63,58,F8,6C,B3,0C,1F,73,B7,A9,0E,29,83,64,AD,63,3F,71,85,E9,E8,F6,96,03,96,D6,4A,5F,6E,22,03,37,62,59,1F,28,02,72,1A,94,C2,FB,BE,65,AA,90,08,43,77,BC,18,60,73,C7,EE,DE,54,A1,8C,C5,B5,30,21,B8,AF,81,A7,C9,DB,47,09,FF,E4,AD,42,2F,1E,6D,88,6E,F1,F2,73,B2,14,5F,32,90,CA,F9,04,1A,4E,0B,FA,C2,82,53,97,8C,0A,EA,D1,34,F9,14,64,E3,64,92,40,6B,F3,1E,63,70,F3,41,75,3D,41,EC,D1,98,DF,1B,46,AB,C0,2F,B2,5B,15,04,85,FF,85,3A,52,E6,A3,3F,16,4E,09,E0,77,2B,B8,3D,86,10,E0,73,8B,44,29,C5,91,17,4D,52,0E,11,4B,73,93,92,5B,62,5E,86,86,E5,61,A0,6C,F0,F2,54,28,94,1F,5D,13,B0,76,57,77,5E,44,6E,E1,87,86,FE,6B,02,22,CB,49,7F,F0,E3,86,5A,C8,FE,CA,CF,F3,E5,1C,37,BE,5C,20,6A,CF,D7,F2,51,06,FC,8A,FD,15,31,2F,B0,30,C0,94,54,76,F4,52,23,A0,1A,C7,9B,42,1F,7E,1A,FF,41,DC,88,1F,B6,71,F1,49,9A,9C,31,62,41,F8,DC,D7,B5,56,D6,1A,AE,C4,53,CD,D4,4D,2E,72,8B,6A,2F,B8,E4,50,1C,F2,6A,58,C0,E8,17,11,F6,44,CB,9C,88,8A,03,49,81,C4,E9,F5,2A,F8,C7,1B,01,77,2F,96,58,E1,AF,D2,05,BA,9A,95,09,A4,12,12,F4,EC,6E,B2,28,D4,7E,10,29,D8,B6,39,D4,0A,D8,A2,10,9C,6F,64,6C,C2,99,D5,AE,FD,97,3D,72,7B,CC,09,3A,A0,CD,63,B0,D3,1E,97,84,60,A7,1B,6F,78,77,3B,36,11,BE,F5,A5,34,FE,02,C6,2A,95,DC,5C,6E,1D,B4,D2,98,9D,6D,5C,FB,A2,5B,51,16,8F,D2,92,AA,A7,1E,AB,40,09,66,B1,B0,F2,DF,41,C9,18,4A,BE,E2,D7,EF,90,D8,C3,37,BD,33,52,2B,DD,62,06,D1,E4,FE,D6,2E,7E,5C,8A,4E,A5,DC,23,77,A1,91,85,1B,57,ED,FC,CD,67,B5,06,79,55,23,F3,70,AB,FA,72,DB,AB,C5,8A,88,D4,CF,10,D7,29,E7,E9,1A,F1,06,B5,A0,16,B3,66,49,06,53,D9,16,84,A6,43,2B,44,AC,B6,A6,CD,05,0B,73,A0,AE,48,84,D7,47,A2,06,7F,00,61,83,35,BD,86,1B,96,96,86,68,95,33,BF,B3,7D,C0,D0,58,7D,0F,64,4F,C4,BE,0A,4E,93,A7,05,44,57,62,ED,6E,78,A5,BD,E3,EC,E4,72,11,88,D8,2A,78,F2,42,0B,9B,79,8A,35,1D,FB,EF,66,0A,C8,59,F9,48,3F,0A,BC,39,E9,4F,EF,32,E7,15,8D,77,4E,BC,CE,B9,05,48,E6,C4,FB,53,E4,35,AF,F5,BB,55,72,F0,C6,AA,8E,4F,65,52,14,60,3E,52,6E,C2,38,FA,85,A2,8D,F2,4D,58,94,62,5F,FC,47,48,83,EA,B3,5C,43,4A,F5,35,2F,87,2B,98,EE,DF,D7,4A,1E,D0,ED,2E,7E,7F,DF,EF,F4,5C,E0,0D,C6,25,DA,98,47,22,7E,A4,5E,1D,A9,F0,1F,25,F9,B6,12,DC,7F,F4,C9,A4,AA,45,CF,66,CE,CD,99,58,29,04,2F,35,88,A4,92,CF,F9,47,23,EC,1C,59,45,D2,21,84,68,08,24,07,18,F8,DF,F9,50,D2,45,CE,A9,4E,CE,C6,6F,B7,73,47,6D,B9,C1,43,61,89,FA,49,D9,EF,2B,54,07,E9,6C,FC,A3,46,54,CF,4C,36,26,0D,6E,C2,67,4D,6B,D0,55,27,D2,2F,0E,24,60,09,DA,BB,C9,07,3F,A3,96,35,F0,DD,D6,D2,C2,E3,91,12,8C,A1,EF,84,6F,9F,99,4A,E0,FD,41,E3,DB,48,20,71,2C,CB,0C,03,91,DA,84,35,79,F4,C5,48,A1,1E,20,CE,4E,FB,47,9A,46,63,30,DE,30,C3,AE,92,37,B7,50,16,8C,5F,5B,B7,DB,00,F3,17,9C,AC,21,38,10,79,04,11,CB,71,83,CC,01,B8,C7,E0,11,C1,C9,C4,C0,A3,A7,18,30,0C,B9,68,BE,9C,41,2E,4B,63,90,F9,4A,C5,C5,D8,2E,17,5D,2A,95,15,C8,EB,CF,74,1B,AD,87,D5,43,4A,A5,37,2B,2B,35,52,AC,DE,C5,CD,4B,8E,1E,DC,B8,B8,52,00,5A,06,EF,BE,99,20,E4,48,60,40,31,58,9F,EB,39,70,08,B9,86,12,19,A5,D8,CE,0C,A9,94,72,83,3C,B6,18,59,6A,01,1D,46,AF,DE,CD,5C,F1,10,AC,EA,03,C0,8D,2D,09,B7,D6,B1,12,B5,50,02,43,EE,38,FD,87,C8,15,D2,40,BD,4B,2E,24,31,D1,52,FF,B7,E2,37,22,BE,4A,C6,B1,ED,A9,A5,40,6F,33,1D,23,0B,38,A9,B2,82,5C,DC,B0,11,AE,53,4C,2C,CA,02,4B,51,BA,8B,7A,28,12,11,6B,13,6D,37,16,96,AF,14,F8,3B,06,79,B6,F2,D0,6C,E2,C4,A8,05,E9,2D,CF,F9,EE,DB,F6,F2,6D,76,6E,61,A3,4F,CC,DF,CD,D0,7B,C3,38,B9,E6,C1,50,81,27,A1,D8,32,4C,0F,9F,72,7D,03,67,B4,6C,88,03,50,13,53,62,6D,EE,EE,67,4B,2B,BE,48,A1,C0,64,7F,DA,70,02,A8,77,71,6D,FC,CE,DF,7F,73,C5,68,66,55,C3,12,27,E9,A5,08,2E,88,5C,7B,F7,17,80,4E,A2,F7,0F,C5,42,E8,A5,1E,C5,90,C7,1E,71,50,1D,6F,A3,46,F9,8F,4F,C4,85,CA,59,35,ED,2C,80,1F,D1,7C,D8,31,90,81,07,4A,DE,93,BE,B3,52,E0,E8,C8,DB,F6,3D,98,07,0F,03,CD,A0,41,E3,B2,95,CD,E8,9D,BF,06,44,C7,8A,64,9D,86,FF,BD,AB,26,7C,CB,33,44,0E,4F,67,0D,8A,43,08,EA,E1,E4,52,75,0A,A9,21,5D,D4,F3,8C,B8,07,C0,24,20,A6,0D,A6,4E,25,22,77,FC,FE,E4,EF,C9,04,36,22,45,D5,61,B4,68,67,53,3A,5B,48,3C,E2,23,DB,98,4D,BA,21,71,6A,31,1D,34,04,CD,35,17,30,F0,64,DE,C7,6E,B0,94,F5,31,5A,BD,B5,C8,84,B7,CC,A1,E3,A6,5D,D0,EC,35,84,9F,FF,63,7E,5A,24,94,B4,04,15,9F,DF,B0,75,9F,08,54,7B,F4,27,13,54,BC,71,69,AF,AE,91,68,2F,BF,D0,E8,8B,D8,32,17,F4,1C,CC,08,39,24,DB,C1,61,8F,C8,41,5A,70,BC,26,03,06,1E,C8,3F,D2,60,90,71,84,FE,E1,84,76,0C,4E,1B,46,C4,E1,0A,B6,BA,67,BF,33,38,D6,6D,94,4E,5E,30,B3,67,DC,79,37,F1,46,6E,53,FC,61,B4,B4,B8,52,21,CB,73,9F,60,C7,A2,C8,81,D7,6B,9D,AE,2F,76,6F,62,D4,1B,77,41,44,EB,FC,31,26,FA,9C,BD,CB,A3,23,C3,98,D3,83,28,2B,AA,D7,C9,63,D2,4B,44,A7,A9,A9,C4,75,42,43,D3,66,30,28,3F,75,6C,3E,8F,D1,94,E9,A7,A9,E0,CC,BF,9E,05,9B,42,44,6E,5E,5E,94,65,D6,34,2E,9D,99,A3,BF,3A,D8,B6,04,00,AA,2A,F3,FD,00,2F,84,3F,A9,6D,09,B5,7D,DF,85,BF,09,2D,30,AE,47,53,75,FD,66,02,9D,99,18 diff --git a/core/src/main/resources/org/bouncycastle/pqc/legacy/crypto/sike/p434.properties b/core/src/main/resources/org/bouncycastle/pqc/legacy/crypto/sike/p434.properties deleted file mode 100644 index f539bc3b28..0000000000 --- a/core/src/main/resources/org/bouncycastle/pqc/legacy/crypto/sike/p434.properties +++ /dev/null @@ -1,69 +0,0 @@ -ph2_path = 0,0,1,2,3,3,4,4,5,6,6,7,8,9,9,9,10,11,12,13,13,13,14,14,15,16,17,18,19,19,19,19,20,21,22,22,23,24,25,26,27,27,28,28,28,28,28,29,30,31,32,33,34,34,35 -ph3_path = 0,0,1,2,3,3,4,4,5,6,6,7,8,9,9,9,10,11,12,13,13,13,13,14,15,16,17,18,19,19,19,19,19,20,21,22,23,24,25,26,27,28,28,28,28,28,28 - -A_gen = 6E18D3A63313A738,1DCC496DD6DDE298,A35F3F7DAFBE2B43,C6B9A5CC670071EB,2EA3DB085283675A,0FDFE173A0297F36,0002200804EB824D,B999E9E259F7BFA8,2584D67D0C2EEAA9,80AB07D4E9625724,781DA616A7A76E54,9BE449736374F491,8C6F86E8B0C4D74A,0001C1D4812CBD98,257DBD53095FD263,BBB3C7A7B4EDB1D4,A817B7FDDD5BB8DA,F5DE963B242B7AB3,7F51B5362FC94CB6,E7D2496B526DFF16,0001E962CF69118C,ED9DC89467FB039D,17C71E114B5803D0,816C3379BE9647BF,B07F441A15434B64,CC65C1804AF4CBD1,F06BF5F074032C77,0001A251F94CF02C,A26194AB4BD1A16F,CFCD9F7F04D5AB10,1BB4A7C04C37482C,71DEE733632DA36D,7335784B5ECF957F,66AE2381533A7F09,000232BFFE6FA42F,60ACBE5D899CFA6A,82AC55A556E5A22F,437D8C2AC83FDC6B,620A8DA602543EDE,D19ABA8092A1E8C2,AFF1AA61981C95D3,0001A7232B0C035E -B_gen = E172658571249BA8,9D8F52CB15829DA0,E3A7C7F9F0E3F832,8B825DD0B9410D30,F42F815734752EDA,CB35DD9160997586,00018B3AAAAD0F79,CF0B435C40C1375D,58AC8A63992B36EF,416D0B3DFB0C1DF5,B257E9CFE8985F15,A493D98A7A1D6DF2,6D6781A5B3FDE61F,000179AC0D886A3F,E172658571249BA8,9D8F52CB15829DA0,E3A7C7F9F0E3F832,8B825DD0B9410D30,F42F815734752EDA,CB35DD9160997586,00018B3AAAAD0F79,30F4BCA3BF3EC8A2,A753759C66D4C910,BE92F4C204F3E20A,4B698CAAFA67A0EA,D73282EDB73B40B1,FF94DE30CDC73A36,0000BA73198F0904,9F7367022EFDF650,A8C21C687A91D6BC,DDB909C497C4BFED,66FD362A30232EBF,84AC5026408590E1,5378004CB74DA4ED,00008AA46B9E55B2,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000 -XQB3 = 821E631A922B742C,DA3EB61A6B066600,BE9BF948971BD406,AEF5D42FAF04075A,70165C6A99378F7F,EEE1058485DD1F9A,0001B20B9F7D4D95,787CA8B336944EF3,0D29EBA9AF11A6EB,E0BC6DA29BB99844,F583F3C8DA2FB5FA,BBCB2EAAD861B7E8,2487A88C3E782D0A,00011BA37E3442A5 -A_basis_zero = 6E18D3A633148F91,1DCC496DD6DDE298,A35F3F7DAFBE2B43,3B18175B7C0071EB,62E0C886CC6A1260,75482A45DD52E0F9,0001C5C62D4E6CBE,B999E9E259F7BFA8,2584D67D0C2EEAA9,80AB07D4E9625724,781DA616A7A76E54,9BE449736374F491,8C6F86E8B0C4D74A,0001C1D4812CBD98,9B989BE60CFF0D15,8B80A32171813F53,F4F067606A56228E,48F8237E159577B0,42529574B9E74156,D8D26313F4AA9F9C,0001279AC6BC876C,9597544CBE9D88DF,13801F440DF32748,E4ECAFF9C15D0CEB,7867D92EB045A646,02399062BA8C64EF,E9258C0BDF8BBFF7,0001CE4BBF872205,257DBD530960BABC,BBB3C7A7B4EDB1D4,A817B7FDDD5BB8DA,6A3D07CA392B7AB3,B38EA2B4A9AFF7BC,4D3A923D8F9760D9,00018F20F7CBFBFE,ED9DC89467FB039D,17C71E114B5803D0,816C3379BE9647BF,B07F441A15434B64,CC65C1804AF4CBD1,F06BF5F074032C77,0001A251F94CF02C,6239F7D1AD27CE42,717E2E83920EF08C,AA9328D01C5FDF24,824E9DEA2B1F02F9,20B1D0984E195350,4A5AFBFD02EF9414,000228BCA648BAFF,7DEDAD20B53F2C9A,E7DD8746364EACC1,743BABC72A5096D4,DDA2FBF4E96A5174,E05A5B3B71083AF0,69AB2A817C72ADCC,000216CFFC723E3C - -#/* Basis for Bob on A = 0,expressed in Montgomery representation */ -B_basis_zero = 214C34BB192F67A0,0DD49D3D02115D30,0700652C1A7B66ED,1F856B48F4FF0024,FBDE6F4E6A705221,B951A3D6C93D87B8,0000AE8ADB818ED6,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,51D889FE197209C1,191BCD9DBE4FE0EF,447818CF5E54DD8A,3F42710E8562A583,647BDBB01C66DCB5,F402D36C15EA12E1,0000A1E1D287C14C,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,DEB3CB44E6D0985F,F22B62C2FDEEA2CF,F8FF9AD3E5849912,DE3C0B31EE00FFDB,7FE7ED29C6E85C82,B3AABBFFB887989D,000185944B95E46D,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,51D889FE197209C1,191BCD9DBE4FE0EF,447818CF5E54DD8A,3F42710E8562A583,647BDBB01C66DCB5,F402D36C15EA12E1,0000A1E1D287C14C - -#/* Full 3-torsion for Bob on A = 0,expressed in Montgomery representation */ -B_gen_3_tors = D697601DCA7CA4B5,D16726DCBE0FD988,8119DD7AF0E6C87C,D1E1BDAB620C8DF9,27ABDBB336AF35D0,C36900B91B5F4914,0001E21CCC021AE9,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,DAEB901A8B0B1BF6,00CFA413FEE3DEEB,D8A152FC022EDD7F,69AEE6F393ADDBE5,45F3B54D85AB6DDE,19F7181A0B697BAB,0000E1C0ED0125C4,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,29689FE235835B4A,2E98D92341F02677,7EE622850F193783,2BDFB8CF80F37206,541A80C4FAA978D3,A9935F1D6665D742,000052025B15585A,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,DAEB901A8B0B1BF6,00CFA413FEE3DEEB,D8A152FC022EDD7F,69AEE6F393ADDBE5,45F3B54D85AB6DDE,19F7181A0B697BAB,0000E1C0ED0125C4,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,FC42C90C960A3D15,815F603FE9413385,640A06136E6DF1BA,71E4C95A57555FE7,BF7BAC5BE8654D6F,27CD8B340B46A743,0000259C6CF43995,FF585E4DCB517F6A,EFFCE64BA91FBE1C,FAEB260583830D6E,EB68E9A0F32E8E96,419A555BABEC214B,BA7A5BFD1EA7D14F,000220892411AA66,00A7A1B234AE8095,100319B456E041E3,0514D9FA7C7CF291,12588CD9EFD17169,3A2C071C856C8D58,B28203D9631D4F07,000013960305C8DD,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,03BD36F369F5C2EA,7EA09FC016BECC7A,9BF5F9EC91920E45,8BDCAD208BAAA018,BC4AB01C48F36134,452ED4A2767E7912,00020E82BA2339AF,FF585E4DCB517F6A,EFFCE64BA91FBE1C,FAEB260583830D6E,EB68E9A0F32E8E96,419A555BABEC214B,BA7A5BFD1EA7D14F,000220892411AA66,FF585E4DCB517F6A,EFFCE64BA91FBE1C,FAEB260583830D6E,EB68E9A0F32E8E96,419A555BABEC214B,BA7A5BFD1EA7D14F,000220892411AA66 -#/* Pre-computed pairing ReducedTatePairing(R0,S3,lB^eB) on A = 0 */ -g_R_S_im = 410F318D49162E42,6D1F5B0D35833300,5F4DFCA44B8DEA03,908ADE1CD38203AD,100CD330A23B7494,E0A2D716A265D0DA,0001C5F4777BD5A5 - -#/* Pre-computed pairing ReducedTatePairing(phiR,phiS,lB^eB) on A = 0 */ -g_phiR_phiS_re = E3F6DD5BAE3DA160,893B9874EAD27B9A,0AEB72FD8BCC2583,02FFCCC8FAFA395E,2303AE01DD252409,C6AD33482DFD53FA,0000978AD00D3221 -g_phiR_phiS_im = C728DE8E32AF6622,F179EECB0D4F3D28,37CA8F90B93772D7,A349AE99A7B40196,D81D98E9D4891BF8,4767F6BC20C22291,00019AF8C13C99B8 - -#// constant Montgomery_RB1 = (2^NBITS_ORDER)^2 mod Bob_order -Montgomery_RB1 = E63F0179FFC3EF1B,47AF4CC2440BEB81,EC3CD079857407E7,00000000008BF47C - - -#// constant Montgomery_RB2 = -(3^OBOB_EXP)^-1 mod 2^NBITS_ORDER -Montgomery_RB2 = 7A9991106B9F6535,7E06A4ACAEA6DA73,3D4C8710FC0ECD0E,AE3D0E8DC11F55F1 - -#// 1/3 mod p -threeinv = 5555555555557C0E,5555555555555555,5555555555555555,3C30F5A8EB555555,9A84C9F93D7058B4,410E5C007655D5E8,0001C70EFCA40721 - -#// Entangled bases related static tables and parameters -# -#// Constants u and u0 where u = u0^2 in F_p^2} \ F_p used in entagled basis generation -#// For the 2^eA-torsion basis generation: -#//Two tables of 17 elements each for the values r in F_p such that v = 1/(1+ur^2) where r is already converted to Montgomery representation -#//Also,2 tables for the quadratic residues (qr) and quadratric non residues (qnr) v in F_p^2} with 17 GF(p^2) elements each. -#// For the 3^eB-torsion basis generation: -#//A table of size 20 for values v = 1/(1+U*r^2) - -u_entang = 0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,000000000000E858,0000000000000000,0000000000000000,721FE809F8000000,B00349F6AB3F59A9,D264A8A8BEEE8219,0001D9DD4F7A5DB5 - -u0_entang = 000000000000742C,0000000000000000,0000000000000000,B90FF404FC000000,D801A4FB559FACD4,E93254545F77410C,0000ECEEA7BD2EDA,000000000000742C,0000000000000000,0000000000000000,B90FF404FC000000,D801A4FB559FACD4,E93254545F77410C,0000ECEEA7BD2EDA - -#// Tables for quadratic residues and quadratic non residues v with 17 elements each. -table_r_qr = 000000000000E858,0000000000000000,0000000000000000,721FE809F8000000,B00349F6AB3F59A9,D264A8A8BEEE8219,0001D9DD4F7A5DB5,00000000000244DE,0000000000000000,0000000000000000,A1CCD72326000000,407B7FF8496D02DF,B402E5F8D9CA0493,0000386AF88303BD,000000000002B90A,0000000000000000,0000000000000000,5ADCCB2822000000,187D24F39F0CAFB4,9D353A4D394145A0,00012559A0403298,000000000003A163,0000000000000000,0000000000000000,CF3B3CB737000000,4CBA127218F35AB9,029D831F766AA763,0000CB17C8A31D0A,000000000004158F,0000000000000000,0000000000000000,884B30BC33000000,24BBB76D6E93078E,EBCFD773D5E1E870,0001B80670604BE4,000000000005E641,0000000000000000,0000000000000000,710813DA5D000000,8D35926A62605D99,B6A069185034ABF6,00010382C12620C7,000000000007B6F3,0000000000000000,0000000000000000,59C4F6F887000000,F5AF6D67562DB3A4,8170FABCCA876F7C,00004EFF11EBF5AA,0000000000082B1F,0000000000000000,0000000000000000,12D4EAFD83000000,CDB11262ABCD6079,6AA34F1129FEB089,00013BEDB9A92485,0000000000089F4B,0000000000000000,0000000000000000,CBE4DF027F000000,A5B2B75E016D0D4D,53D5A3658975F196,000228DC61665360,0000000000091378,0000000000000000,0000000000000000,87335C8C98000000,01EDFFE125B40B7E,D00B97E36728124D,0000E1ABE20C0EF6,00000000000987A4,0000000000000000,0000000000000000,4043509194000000,D9EFA4DC7B53B853,B93DEC37C69F5359,0001CE9A89C93DD1,00000000000AE42A,0000000000000000,0000000000000000,6FF03FAAC2000000,6A67DADE19816189,9ADC2987E17AD5D3,00002D2832D1E3D9,00000000000BCC82,0000000000000000,0000000000000000,E21027B4BA000000,1A6B24D4C4C0BB32,6D40D230A06957ED,00020705824C418F,00000000000CB4DB,0000000000000000,0000000000000000,566E9943CF000000,4EA812533EA76638,D2A91B02DD92B9B0,0001ACC3AAAF2C00,000000000010563F,0000000000000000,0000000000000000,27E85F8023000000,1F9BC84D2642124E,684A3E4BD23840BD,000043BC4C3AD5C6,000000000010CA6B,0000000000000000,0000000000000000,E0F853851F000000,F79D6D487BE1BF22,517C92A031AF81C9,000130AAF3F804A1,0000000000113E97,0000000000000000,0000000000000000,9A08478A1B000000,CF9F1243D1816BF7,3AAEE6F49126C2D6,00021D999BB5337C - -table_r_qnr = 000000000000742C,0000000000000000,0000000000000000,B90FF404FC000000,D801A4FB559FACD4,E93254545F77410C,0000ECEEA7BD2EDA,0000000000015C85,0000000000000000,0000000000000000,2D6E659411000000,0C3E9279CF8657DA,4E9A9D269CA0A2D0,000092ACD020194C,000000000001D0B1,0000000000000000,0000000000000000,E67E59990D000000,E4403775252604AE,37CCF17AFC17E3DC,00017F9B77DD4827,0000000000032D36,0000000000000000,0000000000000000,13ECBF2D1E000000,F07EC9EEF4AC5C89,86678EA198B886AC,0002124847FD6173,00000000000489BC,0000000000000000,0000000000000000,4399AE464C000000,80F6FFF092DA05BF,6805CBF1B3940926,000070D5F106077B,000000000004FDE8,0000000000000000,0000000000000000,FCA9A24B48000000,58F8A4EBE879B293,51382046130B4A33,00015DC498C33656,0000000000057215,0000000000000000,0000000000000000,B7F81FD561000000,B533ED6F0CC0B0C4,CD6E14C3F0BD6AE9,000016941968F1EC,0000000000065A6D,0000000000000000,0000000000000000,2A1807DF59000000,65373765B8000A6E,9FD2BD6CAFABED03,0001F07168E34FA2,000000000006CE9A,0000000000000000,0000000000000000,E566856972000000,C1727FE8DC47089E,1C08B1EA8D5E0DB9,0000A940E9890B39,00000000000742C6,0000000000000000,0000000000000000,9E76796E6E000000,997424E431E6B573,053B063EECD54EC6,0001962F91463A14,000000000009FBD1,0000000000000000,0000000000000000,FB91CE1BAD000000,362AED5F9F9AB683,3573E0B5A4517410,0000876A0A6EF968,00000000000A6FFD,0000000000000000,0000000000000000,B4A1C220A9000000,0E2C925AF53A6358,1EA6350A03C8B51D,00017458B22C2843,00000000000B5856,0000000000000000,0000000000000000,290033AFBE000000,42697FD96F210E5E,840E7DDC40F216E0,00011A16DA8F12B4,00000000000C40AF,0000000000000000,0000000000000000,9D5EA53ED3000000,76A66D57E907B963,E976C6AE7E1B78A3,0000BFD502F1FD25,00000000000D2908,0000000000000000,0000000000000000,11BD16CDE8000000,AAE35AD662EE6469,4EDF0F80BB44DA66,000065932B54E797,00000000000D9D34,0000000000000000,0000000000000000,CACD0AD2E4000000,82E4FFD1B88E113D,381163D51ABC1B73,00015281D3121672,00000000000E1161,0000000000000000,0000000000000000,861B885CFD000000,DF204854DCD50F6E,B4475852F86E3C29,00000B5153B7D208 - -table_v_qr = B91B91B91B91BAE5,1B91B91B91B91B91,91B91B91B91B91B9,0E6BB9DE0C91B91B,18879A47F2F0700D,32C54E927DB88A64,000040658CB2BA6D,37237237237228D7,2372372372372372,7237237237237237,8A63A78A7E723723,B7898A3899D52E3B,D6D1EB429400CD35,000030F2C1819FDA,9DF0A569883D6A65,59DF0A569883D6A5,A59DF0A569883D6A,93172790C79883D6,298B605E3417DFB7,081016F426986717,0001AE3C15954874,26FFB1636401381F,726FFB16364013A7,A726FFB16364013A,EDF3527199364013,BDFF43E957D8E920,074E1DFE3B43CAA6,0001E902BD6A68C3,B29534AE62D85A79,73A1CBC35EA5FE1F,1FB29534AE62D85A,19C5E5E8785EA5FE,6B6158A5E8F068E6,0CECA7AEFD88C24A,0000CF8664C37D4D,C6092EF433268DDD,7A7EB10D61508715,15C6092EF433268F,83BED59416615087,DA8AD203B0BCEA94,DC0EF2686153C430,0001217CC87DEA8B,A1597A9A1597A9A3,A9A1597A9A1597A9,97A9A1597A9A1597,47173487D07A9A15,3062918D06B8B8BB,5EF6E4246C346412,00005CDEB10B32FD,5342B2F5342B2E6A,2F5342B2F5342B2F,2B2F5342B2F5342B,4305EAA744B2F534,71C32BD0E142A474,E23E2A390CBEBE56,00020B54D66A6931,31D09D29093CBD5A,A279F28F044339E9,1C3591FDDFA2ABE3,7A95272488FA8224,7A5F257CDC0C28BB,2F3DFE9FC01A2996,0001366E89ECB66C,79FC8C0827902CB2,2ED4817F4D755A6E,26199D587B0F39F3,A3A0E2151F79A526,1386C93E197B9F03,6B7E90520EBF0D2E,0001E10076731598,5DD68140F43AA56B,4AA53DAEB55472EF,A60F1009929BD460,3D4DD25C8193C341,35733EAA8A1EA07B,99783B0926D5C757,0001D6A91F47E8D5,1AC9583D8A91979F,71D48F5496803FF6,C01CD35C6E4198DD,941E3BB5DBE83352,421F7BB430992C92,DA40000C2EA98E76,00023324E9FB029F,952DEB9E62D9C2BE,7B98EE26B6AE484E,A57575A4B923F963,7F6E921069A934B5,0D34628FB53F37E0,84CD034670F66804,000233E185011583,2E520464D0564CC2,F0B64C978A80BE93,6CCC6215FCC6ED62,3727B865F5F6FDE0,A5963EE8317E2563,3AEEFD45F2BC2A1D,00008B27F67FAD8C,6B7A7DCC7F3B44FC,BA2952F78F79D85C,58AA10FC845A4938,38607CDC19E40DE8,F782E6EB3A1CBDE0,98DAE7F75A012666,0001E9CFDCCA840A,F1F1925DF1F95FED,C765FD5CD394560F,918500D0FB76A868,5C3B831FAFBCCBDF,B1E4D8E96D477318,C4EB9AA3919CE98F,0000CA5C17F444A8,F505266D38669368,AD2B0AFD3D136E5D,3CA7F0C0A4792B2B,F6CC2F16221333E8,74FDE820A0C50733,D749F43FD6060D30,0000FF30BAB231A0,F7799FF6EEB44369,9C9B01C9BF32BB02,EE5B00B022443ED1,16418A8BDAD79B04,264771819C98C2EB,07CB8EF625BB1BCE,0000DC5C646444C8,A52C6022C70D3B7D,F9B79B1003C84AFA,0765C85B2883915A,3C54570B229D2FC2,A59E1613FB354422,88D1CAF4B3C2622E,00009178DE51F8AB,D5539351F6A61891,A23B6DF42E15B0BB,E1EDE32164D9C3B3,A7DECA9161CAC1A8,875FC6BEE0404B9D,907741C12EF25428,00018B79DBCD1C48,18A1E0F1292838F7,BAE67B6B45CF66EC,2982C916B06A06F1,9A53622D7C86DA5A,9314B3E18DD3A3B7,36BB18009CF1A383,0001BFC9236F3E65,22470120336BBA45,11EAC8697B6F6693,FB672FD432B4132A,27792DC88E63B55C,30D776047CAC287C,DE79BC44A0443180,0001F651F5F1A9A7,3E09917AC9688DC1,EC94402B3F3397BE,56025A9144380945,00A1AE22A2253250,891F8847B8B78A7D,DA0443EFF16C706F,00022368A03A9304,D4F15775A9821722,64DF3D6397D527E8,F568724D03D64557,5B53D0D1B29D967C,7E629228475B7DAB,E2F8D30C52E943C7,0000493BB0D3CEFE,57EF7EC9AC7CE353,B563E360103A5DD6,C42C5BD044455DBC,41EA4366B0C69229,E97382F193D45A27,8B63E6E956D7C174,000190B9B4F7F000,972A66E90C6F6DE7,08772CAA4BC06BFF,F5BB1C1771A8F362,7609CCF88A4C136B,B995935C846B7647,F7C843EA8188B335,0001542E019C30FC,4246FA13382275B5,4734FBDCE5228591,4024F01C044310A0,764F2B4888774196,7F3EFA9545B4D464,CD48FEF1A7C24D0E,0000371FB2198997,0D444A482CEF0AC6,DB7957048C8DE64A,1DC15465E53A2A4B,017829A8B38E47B7,1394CE02BBC42752,30B81EE68A7D7B3B,0001B89AA7B09560,91E8F43CA01721C0,39ABE9BE4138C9F2,342B58F5DC8FD7C4,8BEBB3AD3C59CBD4,014A504F2E2D58BF,63B43021EDEEB875,00000CC6FC5A0F66,A9571A2B15CA47C5,136159ABA10347FA,C91B46A6CF975D38,C91B144F43D03B6F,764A2DFFD44DAC62,9DC2BEE6D762D341,0000A472F28BA413,E22367F18819D3B6,581661D0BA67F352,BB446CC1C435EC24,234DE0F57175551C,22DCB9526AB8B42A,9B132D68572887FF,000106208C8243C0,61524ABE5BC5AA7B,E09DD59654379389,1E2CCF9B77486349,401627FB5217B2B5,A0ABBE33F68582CB,5FDCEBB71DBF474A,0001A6CA9A638D47,0743A7ADEC4CBEB9,47D5F3C3612D8380,2AB1A136944C1875,1A465F3FB9F85ABF,EE93D67ED7FD59F4,AECA171A0F106B4E,000058273E8B0400,0CC45DEE3E386734,9A5A0BDFB68C83AE,5C1D5047058C14ED,9FB2AA0ED2404366,166F7D427E758FC3,95C498C32ED2863F,00018C4775225D1C - -table_v_qnr = 6666666666667DA2,6666666666666666,6666666666666666,BDB6F9CBC0666666,C31C792F24DD0205,27089D99E099E6BE,00011108FDFC0447,33333333333304BB,3333333333333333,3333333333333333,825382E362333333,F58D6A19E79EAA98,1EEB24A2C09152D8,0000120D2B1F6AB6,8B6BE9F1D2505894,38B6BE9F1D250583,838B6BE9F1D25058,9C0909AB631D2505,EA75FE266DA83956,B98D22E1CCB2BBBE,00007DB423F53C56,32698CFF3659C593,032698CFF3659CC0,C032698CFF3659CC,FC24A25976F3659C,EE93EFA540E7611C,15016B5024486E43,00022DF13C37023D,7722377223772254,3772237722377223,2377223772237722,36D7BAAAFB223772,7AA4C5D72FC85655,3369C65060D08696,000104009788DC36,1BB911BB911BB571,11BB911BB911BB91,911BB911BB911BB9,035E9BD3E8B911BB,EC06B024EB2770F5,F590D385807C1241,00008DC059443A3B,E6111C7042F3A8E9,A8E6111C7042F3A8,F3A8E6111C7042F3,E2F2B515761C7042,530947C450F471E0,FE9688F7B8604C8D,00005C0ECF10587A,ED731D065EB956BE,57ED731D065EB957,B957ED731D065EB9,FB2E1576F91D065E,F2D84E5C17F75228,5A258E938774B74D,000004472D355531,3337C993650C0D08,D089EDE9FF52557D,7620D4C829513EF7,DA1743C426DBF666,A107EC0033174F2C,AD15D89173C23C09,0000F99F9FB462F5,FC6A84D90E95D167,143E213087AD362F,B659C39FB886CE65,D6153F7A8F277FF3,39C5C5A13D9EDBF8,AAAC1FF0ADC9568B,00011A1FD239C2DA,87736309DDA6A943,091F6A7837911C71,0743D3FD9AC58005,E763272C18E09F9A,26B8C4C17D8D30CA,A460F26C8AFDB3DA,00014E6984FF9B2E,F4EC60AC7873FE1A,604D5A5B78D31CAD,21E19A43B14CFB3D,01179D702BA92065,04EA04B3126A1C70,EA50BE0D9B0E2C6D,000131C643902465,8614211F80B1616D,F7B81FD3A7A49E4E,F80B1616D86C5E7A,07BF548F41614211,C37DA826EB2AE8DF,C0411FD8C5ED8C6F,0001F341510F9157,295ABC8F38726461,50DC31E366CDE7A9,F387264C8615B5A9,0C75E33E8F95ABC8,5D38EFF0970FFA71,461FA2CC981D3869,0000418CBED84E70,87700C2E778D8075,43A87500FA58EEAF,9CE75275C96D2A5C,5FA19F2E462F399A,DF0F017B7DD8C4F2,280013794FEDAE61,000094ED77FF8063,9C6D58D8EF534C70,660CD680A7D28338,BDC9BBA390D722B8,A71C6310BFAFCB3F,B99B4BBB58195F7C,06691D6254221D44,00012108224A3BF7,2195F504EC8CE821,9D41075B38625AA5,9014203CA406BB05,6D62CB6D8B2DF2C3,1C86F3E3A5CCF863,203E5B5903F00EDA,000164F4C3C7C43C,F6674D58304FF4E1,93B111A6E31CA9BA,BC9F5567AC2B4021,38B75040103B443C,A69C3BA57D6DCDCB,A75A1F558C7AE4E1,0000906E5FF4617C,94129AFB594129AF,129AFB594129AFB5,9AFB594129AFB594,2900F1CD82B59412,20D6A4CA5E4BAF82,6793F3042CF7FB07,0001D02041A5E76A,DACA094D7DACA05A,CA094D7DACA094D7,094D7DACA094D7DA,4B05B38CC6D7DACA,5BB2D964C0D0DE02,801FF33FFAFD404E,0001AAD724D92DFC,E166CDB3BE58BCD0,E77C60E75642CDFD,0C39472A9783BE7F,96A7FC14FBC96ABA,5CC689CB13C56A4D,C328410D8CB268EB,0001A8A8A5004ABD,B346305840760AA7,B1B19541D3651803,C76AE6F315D7AC5C,F0B9349859647081,A9244A61C30F5B9B,6A76EE9B87BC5C4F,0000AF0668ACA050,ADA031682113D6D1,017CF7EC83494C4A,33EF143065596ED1,0276B5923C8389FE,0822C190F53979AC,33C32FAC0249AB9F,00011975648F1F39,6FF3CFA74C02322E,D98760896B12B35E,5DEE8FFD24640437,3069F716185FB36D,A97ABED04F5F5959,DBDAA58A321B6B1F,0000491708DEB2B8,A6D19EFB46E8A47A,B4DDF0D82FF93FF2,7EF791FD729C9B0F,1CBEBA7707E84CC6,E949FCCBE6E9F9A6,085AFF3FCD75590B,0000F96FFCFE49F3,7475B90FC40CE223,DC4E0065C0F5C12D,0B2928765F52DD4E,CB9E763FBEB91EC8,44396405161C4326,A0D8B0D51BD60EA8,0000A27A2002EA20,49EC0E19DF71A633,2A457AC271C844D8,DBF40F545519A32C,318D60D527180CFE,19A398A08B929CDA,CF17763B94DCBD5B,0001DD4F8A136584,FD97B0A56ABB6CB8,404AD893F967E82A,4C00B1B353FCAE77,F75B9E618F05FC7F,9C6E7902F4787FCE,E4E698A7B7077008,0000CF2A0C917171,C0BAAADC355770BB,9D7581EB3277D7EA,CDBA0DAFF2A59F6E,3E461B402A9B65B2,05F0D156E1A7A3ED,69A1891EBDCC6A7C,0001281AFCFED68C,B5896529877D4FE7,71F064AE68975B99,4F9211F7BBCE7B39,19AC9E4507FDCF34,E4F185BB956F52E1,E327A4E691DAE76D,000046219384EE75,1B49FE6D324A903E,4E33D89D1655631F,1E1C101410671389,E332832DFB6C742D,38CDD49E02180B90,1279178D8097B588,000119E5683A4805,1FBB103663B9C88C,2374EF7AF79F0D48,4AAEF2ECAB3EA292,A0FA2CB6396F22C4,BE1E1F8EC2B4A5CA,43D353300E514A3B,0001288094A6D8E5,998BF5138DDDD5D2,D1F015AF4EA7BF66,E3DAF7886068D9AD,99E9067025D583AF,CC498E253E868EF6,618AE02455C9B20A,0002322145632832,333A0330E480A5E0,D37D31D37894FFB3,4E09921C2CCDB4FD,AC7069BEE6F95173,A05EDFF1E57DBBEF,5C3678A72B135234,0001BB5DA10EE9DF - -v_3_torsion = 999999999999BC73,9999999999999999,9999999999999999,9C9276B1A0999999,24AAB5C6B74B8308,BA8CEC66D0E6DA1E,0001998D7CFA066A,CCCCCCCCCCCCC12E,CCCCCCCCCCCCCCCC,CCCCCCCCCCCCCCCC,1EE5F99502CCCCCC,1A381FE09EEA2DA1,D978110991782CF7,0001AB9AA8197120,41FAB8BE05474CC2,054741FAB8BE0547,B8BE054741FAB8BE,C9AE7F39FF4741FA,B1F4EE9D1CDDE556,1650D500E95EBA31,00005023E95DDE16,54741FAB8BE04FA9,8BE054741FAB8BE0,1FAB8BE054741FAB,16655C7EB0E05474,D849DDDEC437B020,2E677A183619E2D7,00019324B6AFA19D,8536718536718A34,3671853671853671,7185367185367185,88EBEF311A718536,A7D32684ABC9D6E9,86FFA027C5EA41ED,0001EF2D26807E04,8B01288B012888A3,01288B01288B0128,288B01288B01288B,F2CAF7B478288B01,B30406DB0864DD0C,7DE19AB6317E9551,0001499080A4B0D6,497819E2B03FF6AB,43C254E3A3E0C8FE,A1F98753F0030B9C,9D08AFDF66CDC06D,DC9B4D2060AC66D4,AA1B0432076D8C12,00008C728C65FAC7,7787B5638B83E57E,4BC0CF1581FF9E8C,1E12A71D1F0647F2,F874D414C6185CE2,B1C3CEFB8EF40E5E,D974CD64813E2AD0,0000EF9B64A50B19,4FAC336C14F326D0,F324FAC336C14F32,C14F324FAC336C14,7A441A68B4FAC336,F55ABB9E02E51BCD,7DF241E5CC125D82,00020CD99B418553,79927D619B60A6B2,60A79927D619B60A,19B60A79927D619B,C1836ABCD19927D6,056ED5F9FA770E50,938A248852AF05FF,000180454EC85AD4,8FC8F97836B765C9,79F3DDD74597E657,F40F4D525855A12C,B504F4CAE1D399D4,5B3EBD1F2ED83FF2,E84645130B2D0DBA,0000DA2062334ED3,C71EA489199E8B2C,4CA048F486023DBF,7D1F0775331F6A61,238045677D90A29A,A9A61EA8DBC1A3F4,7D71C1C648CD9742,0001075C2F69D7C4,C3A939DD014D003A,A92F1F17B5248C25,7399C8DD37028F40,78F15EE9E1AEC3C9,9C6EC31DE809B64F,ADC32BB57B097A2B,000182925F9D25CA,37B92BC3BEB5AFB9,C389002039BCC790,769F328FEC87C89C,45F48B81136118A1,771813745D6BBD3E,1DB0C12AB3EBFB1D,00014733DD55FF54,8D3D7757053F25DE,1BB0A5534AD2D44F,6A5D806D0822AA3D,81D30F00C5FE0658,DD7EDBA5455F0CBF,321F8C3287B5561C,00010C3B9266397A,58AFE48B66934683,2BD00D3BE2D0F3F0,366476DBC465DF23,CF46D882997C04CA,100047EAE7B1B0CA,E98B984D9BA8857B,00019D8D87E9F5E7,16255E514230CE8B,4CEE6DB1C53E2C2B,E69FC4293B640916,BEDB813769959101,75374AFDF84FA267,A08A7C370DEA787F,0001C42814BBDFF3,CA970CCFC4688815,B0EF9A5F6A27C77F,57FF227293F58D8B,2782596E2D3675FA,F3B4D13FBB928B8E,5F9B384AE0301D97,00015DD020A61A84,B9758CA6605A88DC,9B0E00E773B0BE3F,8D1CB3F2BBA35FE1,5BD852F804F988BA,5AB812185EC1F54A,81EE7303B3B11EF8,000167A5C4B8EC00,537E31BF0E7887B0,F28A3A23236AEF0A,49B722040DA1FB99,89C14F4BF6ADE22F,8303646A89C2A6D6,4446EB8898043332,0001C1BE6A2BAA3F,60904BED92E6F0A1,B75830F83D32BDCE,5303D79E3A35E71C,057F1D1FBF1F6424,09D29AFFCD4B9F82,0DE6CF6ECF1EDB33,0001B330E4A5A838,09DBF7B0AE6C58C5,45E3E366E4AFF3A9,29E3BFD3FA3102E9,4F66726AC8918DDF,AC46D1291B0F682A,197E0510E123E22F,000141E2A18F39E4,0611E67F5AFE0C95,73F50769BEADF858,5FF1EF605FF0AD88,C80A90794F63FDDE,A435619598EC3001,34AF362A0C54F5EA,00017A9719011B55,E183ECD15F816A3A,F6F117C4395997BE,67AAE2316B369528,0618723D3BFE02D5,947CE54AACCA22AF,4963179F500215D8,0000A69EB2B134C5,4512C7CB549E0613,58B3138052AC291F,BDB21A1D0DC8E1F3,08F33DE426C49F38,78ED469B002924BC,94FBCA884C534ECE,00016411608F666E,76DCF643092ACD65,87827A6E7863F18A,5FBB99DF645C6BDD,26E3468335753344,C6BB91D8121B199B,3BC17926E87E395D,00007D5A5FF0E692,2CD377F7AF7A3996,FE915A6848EB6335,E2796F2ACB922496,D5FEAE7013EC2D63,1B264179788453F2,3A50528DF123CA80,00003C2B61484D9B,0CD1CFE4E128028C,7E6F33F849117206,422F91D71D67A4CB,A9C6E809C409E2D9,D3D9B2D66BAC46C7,68CEEB5277B8DDD3,0000381E05A78010,4F4EBAA4A85CBB5A,00F6A3476ECCE55C,6DF6C3C9230F72FA,0DCB283C6564F0BA,A82B8AC12EDC42E9,5FBD7E3CB399C776,0000FFF6BD7C7E3E,DC68551ECFC41D23,C237308737FA469E,E6A81586A6FCD565,3DED4572B5A03B45,6946056BDF996305,E2F1389B1D6CF35C,00010CD02839AEB3,A5959A668F12A176,B310CEBDA555CD7D,078B28C38E9A01DF,6197E0DCCE65322A,A8D2A1E798A9702A,753603AD399F0CAA,000105A74C730C51,C8D0CA6784B4551A,45D4AE4A0850F0C8,391DDCAFE0C29DC1,8270BF6B173AC986,73770F0EAA80DDEF,BB7C9EE74BD61C23,00007A592BC0228D,A302403B141A0385,9188DF46965BF724,666234B05EB3A268,37AB02DCD5D0FB01,ED9FA4ABF47BF81A,31B87D353910E9E3,0001E931A394CEF8,9E46F21160F6FEAF,6359F8041E2E0FEA,4AE82F18B6A502F1,CC2D17C159C53B16,DC5076C57AEF74C5,A4D66592DBF0E267,000012E32E3B2202,9237E2347B57BBD8,E16C142FE156484A,087E8A48B3B14220,34B6225A95A547ED,D26CBF294A3E2E72,33C06874E35A7F57,00017DFC7A25D7B7,91ECC77A8220B97E,BD3818A24751F785,2E3FD75D7AE703AB,D7E8692B70CA482C,53C8B5DDEBA21D6D,5FC1E218D7085E99,000129CD0E49FE6F,3945471CC48EF6BB,7C3FB717D0165DC8,92F83793BFEBC75A,D5BF95D93BFE5316,0209E198DB1F16A4,E2086C62914F403A,000019D6352AA2CC,BFFF0BF092E15611,FA429EEA322007B3,99EFB4184EBBD84C,F6C5230835D383A8,F1CD8283C93674AF,41C64F9EA1AC8458,00002CD68D0A2571,570C567E928211B1,70459EE4560443C6,1FC204B885DBB2C0,7C99D3BCAF19BE0E,5BFFD67B5AA530E7,F8701F7AE35B9C57,0000F056DF1DFCBE,4183962A42D28AD1,FF8B6A5752A5FAEB,A4B714F92FE41B11,8CC5D5EEFFAFB58B,A53A15C837E4CFC9,1A79CF6122569F16,0001FE4DB81AE342 - -T_tate3 = 087CF42AB4DB902F,2DC7847A25C2D0BB,02EA717C1089170B,D648387AF59D578F,16EC71A5BDA7D98B,C02025B1BDE6B5F1,0000482FED00DCBB,8AD7A8F0578700AE,B317427ECCC5FA27,0043EE31091EAF92,2D317292BB029F77,FBBB529BB4CBB2B4,60580C9725507661,000112DF39343123,A434F3F0FDB57E43,1F19074AF93E2F11,543519D9822F9BCD,A37D58CA3D49D484,BF5FA675ABF1AF8C,FB287704C7B40291,0001BF7E42435225,87EE9673F98AC980,BA0821247ABC3FA4,15E15DE1E6F42728,C0113FC5F784DFF1,BEF4D30A12CEFB55,DA6EDD9E69F8D979,00005095BF6E331A,8712D8BFF33A915F,6FA3BBA2BCAD2B3D,3DA66FC51C479D41,E4664DED73E4F4F8,1DC84EF123484BDF,3830A0CBC1A1FB32,0002093CD1FD32C3,52BE5D7415D580B0,A038215031E30913,5D7CF2307F86F392,B6F68C9CA159295E,7C91CA90411DDBD2,738CEC7107271928,000104B080B38D23,782F2E6790E469ED,C4B78003E1050FA0,E0CA084A7EE5B883,AB2ACCCF86F46C37,1F32B66BFB23DD49,D5960A518B29111E,00011F1B4E73A529,EFC5D3474A129A11,5576852523BA0748,6B93C9ADD44CFFC0,CE812E5B9151006E,2C9F8A0911FE0C97,910D0523327E636C,00011B72F214EA79,1A0321DD62C5B1B9,3F9DD61C3034ADA0,94741AF0B2D3B8E6,C74C38965B4D0043,21C00F3322E375AB,C26D7F847AC9EAAF,0000BCCD45776F12,799308ADD29259EA,6B7CD64D6C3B7F04,AC37BFD305C534DD,7A5D6FB2163561D0,AC47BF7A3D8DCAE1,AEBCD5A1549AE57F,00010AEB563DEFA5,870E74E9DDB6717F,887B67035BB681CE,6C589E63249B07D5,23462ED5BC57928D,A0911EE4D14324FC,86C5A1C6E6D7610A,00006EE385585755,F99C75D5FD1C99C8,BD786788169F0B16,D870C3F4FC4D3405,883E82ADAA7EBAAB,45F9810FBA0BB397,742954D5E7597601,0000BC1CEB24C698,567D28386337D588,451A058E61D82479,9682171F6F2EF6B9,A30AD92F6A21E952,6835DA5DA162FFBA,CFFCFC13DBE63182,00000E18A5A20B5E,7CF1E2C85A4336BF,3BD672C9E247B93B,E64AC73819FD063A,B6229AC036E0CA04,A02326A8503A3520,2A0755DAAF4169B4,0001E6959E0B87C9,8D6D2A7F6F30837C,BF902E6320D3235F,21647994DA640189,5C1E206F4038BD47,33BEF2EA45AEE25D,160FFA08EA8FD067,00013202524ECD23,8B52AD13442077CE,E55F2B037EA7ADDC,BB4EE449E9D97433,3C9C89020167F595,EA9B9E3A82ADCB66,1E08BA4129BD5B25,0001CA2DA5BFC577,4299DCB647918CB2,AF86EB07DE2A69D2,CE24B54DD0C4B65F,4231A1A4B650B923,EE6DFBA9BBEBABE8,0195BE1CE395BCA2,0001840939C66720,9AE6708F03788550,BFC33006F72C5178,6FB8B0073442F23B,0DCC091F52DBAEFF,F34F1009782EE835,F567D3A9073710E5,0000BD48650F0ECA,590DE17FB7AFC380,7F7A56940C607B76,EA34A1DED0626E92,2A5E86FC27A7919D,02A939C77E67228A,902EC93718A484D8,0001D525EC65922E,A338F9FEA0D9FD2B,3AE49152EFF3EBB1,72EACC005FA0B6F4,EC65DCD4E95F675A,7CDCC1D8A54EEEC6,1963678E2115897C,0000068C906CC71D,4ED2850CD8521CAA,037B668E8B3464B4,B0538F23955CC4A0,89317CA4D87495E6,682016748E5AF9CE,08E8731A96729969,00019CA49150D970,C8CBAB39A17258A8,33177D7C5D70BC99,4F766FC8ED881455,AE27E8930854CD7A,3D422E5E0D4FB34F,E52EC94774679E91,000158125921CDFD,D958C12302FCB427,CC1C7CE47DA3923A,F48BEB644D67B3B4,0CB3E85E981789F1,690E38488F855778,8DF571936B9DE3C1,0001697A828BD480,0BFB5E671A41DE11,CB6E6ADD07E16041,7F6F7E1F0F59312C,A0C84CC72C66CF2C,1BFACA064061C7D1,81920D03644F54B7,0000F51E62948FFB,10BC57E9486532BE,FAF9AEC6841ED41A,2A4104E64469CE3C,202B80D69318DB79,417CA89D2A5935D2,A991C6404CEC3BEC,0000B47B0A935EF0,6E7687B28A998E7D,2BC789694ECBD01C,003F6E60BDAEB97F,556D30AD5D42D1FD,60C2A6D0B08E7835,867D4D0F64B409AB,0002192BBD62698D,37CFB96EC731556A,ACD0CCD8FB2E14F7,EEB912564ACA878D,3EDF98CDDA176443,36A39D2C28ADB9A8,0EE9427130BF5E0A,00013944C7977D23,E71E70C0472421C5,0E5EB07ADE978903,2960B1C908E63B43,5E5C8461A3D6BB04,25449D5F39BE1CD9,7D38319C4E8FA1D6,00001B28945723E0,02E4D063B45948CB,5FCDCF2209C009DB,E86EA48B5B6F3F39,B84BF12AD9132FE2,DC6D825944811BB9,381B81898F0A201E,00022059964BCBC4,DA3C7C2FCB5DAAFA,74F84B725AB8E5A3,720E9D56CF17EBEB,736024360E3A21E6,529A2C8828A26EC0,869C50C4297976A4,0000061588CFE53A,858EE17E03A95FB3,6D179EB603320ECD,A79F512866434C99,089A85A54E50F173,FEC0CC93361E6BEB,FFDE8D620EA6E9AB,00021A20B4098F6A,CA888F57ACA873C0,9A50D95DE7A71205,BC7CBEB3C8A98062,2A2905DF61B87ADA,B291F326FC02A2AB,3E609C4E7ECD502C,0000F4589C2CE8DF,ADAE53CEF38551E7,34D0CFFBDE9619CA,AC9A701D7B5C7C0F,B14E1F10C87D96E6,48D6572A797B36FE,B9683A45FC90701A,00013DDB71DE40BC,2F9C779613D1EB20,BD55351AF620C75D,97E623955DE2C6F1,0F00BDBD7698387C,51CBBA19E50C3C61,5F3642423EA425A5,0001B81B90642DDE,4C2EAEF1CEFCDBE7,736480464AA31966,CA127B84714F101C,7E419C0DAD15DD90,7CCCDAC3DC01253E,1FB3B5BDE2C93EBF,00017C77D3B6FD3B,E6F54C1EEFA787D6,EFD4296AC605632A,8EE5AE0226B2A8D2,9ECDD8D398024EEC,2E1CB33EA04D00CF,464AE77AA92E13A9,0000AFF71032B956,8477DAECBBF7AFEE,C4CEA77FC65DD0AF,708D21475374EE8A,A9071AA7FFD218D2,74299452AA96A753,C1D694EE1C0F6758,0000307B19DD1825,FC7252D4FBF8C849,0269C191CC6929A6,9ACC9148C0F65B26,ED2DBBCAE7A3E486,45B19AB48ECE5D56,5F7CD50692571186,00019B34DCB42909,20D1D5FDDFFE608F,EF7F528260E40225,A1A23C15C212B507,3DA7B29B1EC33EA6,CBAB15C5235A0297,609F3E2D4D738CE3,0001542B656331C8,1E65EAE77C59C667,D17B6DD36F481322,A3DEF060B572C354,9C5A706D158433DE,F2F48D157A95AC5C,5AE4305B0A56F366,0000D438B9D41AE7,8FD509195F1D6C55,B06FA1C951ECE50F,3E9BE721FCF076FD,85B2919E8DF876C2,79636DCF86FD975C,84C4EC3664D33000,00007C341F157510,137F69B41C015930,C13C66ACA7C5CD52,6492B4371600668E,ABD67760352A65CE,895F4E4B73A9CAFE,A1AA295248E45B89,0001EE2559C3EE26,B6BAD24034A03275,08434793738D2CCD,8D78BF7226ADF2F0,6600AAD89C607B03,C2EC1554C5311D19,8661531B0B8044D5,0001BD87A13AE9F3,9C5135CD8D563E7B,773229CE34DCDD93,F1CDCBEFF33D96EC,422C54F8ED4D022D,C63EB1371E0151B6,2D30AC650D3057E8,0000714F41AE5194,1433C9C9A70DBD1D,96177D4DC7B0EC62,C41FE314F28DA6FE,EB893CEDE552E338,EF3611F3972C9B7F,AC47F0BDD64891AE,00014FCD79113CFF,58ED9C42626AA8CC,5EA466A92F640AA5,74B558BE552CF55A,B09F4E37F0477C2B,83C8435A5F56810A,13C032465CD89BD4,000173FD49FB3167,8C7D55A2C5804302,AF9048CBC478E454,8FA3CB85FF47F215,D0B42F4887B1DA9A,465EF4C975A9F36B,EA5FBE9067832AED,00011E1D319D90CF,D3EB64FB1111F6B4,837CE168D01EB541,AB49D8A50F1B523D,7DABC602E9122DB8,01B7926B5B10F285,9CEA4D8D552A8D77,0002259ED960CCD0,8647501B2F078D49,B3802C6ED273AF1E,A87D2315C283F992,6BB53593406745A3,A1F5EBDEDFA6D925,60C03516B28987EF,0000531C8F5E5161,1087A27BB6FAFBFA,DE0A2350B689EBDD,F3BE02383E55AAC7,F66DAD79943D273C,F7AADBC781D4D992,6EF3455BA83E8D3E,00020CBA0508A718,B682C827FE77BF49,3793D366D2FA081F,AA66B510CF133D7C,B7A6BE26294FE615,8B05154EA28946F6,99B7DDCBDBA0CE91,000118EA775F78AB,E50BD823B2A03542,45C0C53C17CA55E4,5BBE0E61E28A8516,1059D843679D0C84,84390651B63D4BAD,F9B3AFBBF4F4D600,00017F38E897BD6B,E8619F571E12C5B0,1E5C51BF1B03D967,85EC0895F2F570F9,4FC66F6894FB2A42,A3A269AC854FB597,3768E4AC9352642D,0001E50C13265613,43FF722F23E7B39B,08AAF76417BEA3D6,337DE6591F20B252,B7555FFF557EAB97,92C0ED9C05F6F674,5CB6EA4B35632EC0,0001A32D2B13AB99,7C0B19DD9795431C,A3F410E327550376,C14BE091BBF57DE5,EC922FAC2CE3F75C,A423698F6E32C7FA,BEBD575278CFDA41,0001ED5C0FF427E4,4478FBB296C574E5,CB72B492D2B84210,C4B5E2251DE6E0E2,F2EC4E0A1E3306ED,3255CB0724E4424F,4381CD7B95081559,0001F40D655CFA20,C59C39DEAF46FCBB,99EAB749E62FF19B,F25B1FA436F8941C,AF8996BB2BACEBB7,999663137E79F393,FC895F26610594F1,0001F1999454001B,490CEFC70473E7B3,93A7F7ECD872039F,428D85225E39BDC3,D52FFDBA472A120A,AFC00C86EE6C6B3E,9A7D27F38C8C3B72,000143E21D7727E0,7B9D42B01DE49B6B,2758F20E54D3F6FF,6625862FA68DE442,8CA3CFA8B3E3B452,71D32C6BBE7187A5,C45BC036A7A8B755,00001065A9DB65B6,EC346557EEE05735,BA710B61DB246F29,438EE09DA5452FF3,2317284DD416080A,05133D1A4C7EE864,7614F7817AD7E28C,0000535261D1835F,E19D75885A0348BA,6C06FC0E298C147D,A4ACEFCD7ECA24DA,B5F6172800DDDF16,D2A0E0C5573C613A,086E8618A9F8BFA2,0001E0E51425ECB6,8F95B5D9D0CC0AA0,39D14BFC8A6836F5,C0B44B9EAAF2ED69,CC8F001DC363A2CF,984E37B715D4B51A,8E43E4020FB09280,000228CECD380EE5,835B1DED08CE7D35,D8A62AEF039669D9,2658D941ADA41B59,3D24AA4A5CB3EC76,D8F3DAB2407526E1,A1801D5B200E3EF0,000096BD1EDC61BC,4CBDA262398A1364,FD2C9D5146CC77E9,3AD2AA1BDE3F9CF4,DFADD925DC043D0C,6E3BCC240F2A90B4,F74EC14529FC9689,000029AEA9CC62F3,9762B237681EE8D2,6607554FCA35799C,D369ABEAFA64D7C4,AC854490EBFEE4FB,CEA9D92C3A947F6E,BD971CBE37DE1382,000177D6ED8C48FA,369DB1D3E70EBF53,88CD659600C8EC18,CC332FAACAA3D393,A673F79F69FB7101,B0740DA8971199D9,9B9430CE5CA7DFE1,00013C30A3479EE7,239E0B7B99D13ACD,C53ABA801782CA40,E11FDDF26B448B36,378963DE3CC0C1D3,F598CF3069EAAD9E,35245FFB3479BAD8,000083511A13ADA6,7E0B3C8094CEE771,2C8FEB1BADA65CD9,05B4703D07659F54,8C96265BC9DD86E0,BC2DEBA901B02F19,D98D49B706DCA243,00022308539C8095,1F4B40ACB4875FAF,A7B85ED9F006DEBB,CED0EC3829A18FDF,15009B60A3ABED5A,D8A8CED888D0229A,628BDF2E187B38EC,0001A95276866026,86C72E906503B572,43339911F647A1E9,7F47D5021AD9AACB,DF9C1FE903A1D9F7,C9F85B78AF919557,7DE1BCC892E37999,000003093EF87B8D,87B7064E1F8D40EF,5C78F1D59BAC5B55,0078C54D70290309,C5CEEC1A103AADCF,6C7138316B14A6E1,A98FA02E6D7410BD,000097389352BDA1,88BA3308B84FEE03,55114EE30106FFB5,0753E0E57EF982D8,4C2FA3FBCF6D9052,22582218944892B6,1115DEF5CEB61B08,000011FEF53EC5D9,59D56C3AB8FEEE1A,9ED838C20904927A,2B600488E266C228,29375ABDDE09778A,5CCBD231B205DF81,D67C6349B34933BD,0001BC163C1DC525,280355B58C110F4D,F10B7DB19E93F35E,314199DED0702BD2,D2DD5757D34EF66A,E96B85E53DFC194A,6DBF236D22C3BE74,00021AB2443C5218,BE997A06FD1CDF15,3CBF09F6DA2324B9,E794011365F2C37A,93882439EA7A7E3A,61F249F4DD488323,2BF431C0931717FB,0001105441C04494,B0F6FFC7015BEACD,33EC5DF84FC47D3C,AF0A3E130DB79B6C,896AF85CC18A9EB1,3E8EF3DDC69DEFA6,6AB020270CCAFF59,000166E79C86D126,E7C2306FE90BCC86,B0499DEB5C683630,DBDD3E06A3A8C319,AE5323E7129F9B4F,5DD3B00DBC22005E,4B1F18C0A3CB00FC,0001C634AB98D71B,7979376AED82459A,19F3D3BF09C8AC07,587AA7C0A12E9144,A644BB174460548A,B5E129638BBB96DF,863B9301582C18C0,0001C4417D6362CA,BBF0227C2BDFB4E3,A0F2F336BF7F931C,8D3666343D23F172,AD7FD7A1A93ADE6D,E8AD3883022A2E61,7E932AFB0FBA5311,0001E91645550DBA,B91B60AF5AD69277,9609B94BF41EE8B3,DD931ED87A2422A3,84F1D9239A9825D2,0ACC506FA6E1789E,C1904E8CD588C85E,00009251B76633B4,550BF45122BA375B,C1B5C340BD82F421,A10B11FC92C595D4,FB69C34BCFBCD423,06D0EC53E65C6DE6,6F7D37F6406837BF,0000BF7DD3975BC1,6A458DF6C7E26BA0,C2D9755A89AA9E85,74EA76F08EC65BF9,5C10666442B1AFE4,F67FFF9F03864BD4,2D08D930151CA96B,000014E2E48F9E52,B43780B1AA404BD5,1EE0F4EBA436785C,02C5F871347D6857,220D59AEC68637D4,05F7E658540E49C0,279F98E9BAC8308E,0001F19D2E92E2B5,7048D8191B321C5A,EE7254801B494496,CC1C6B456584D4B4,8DFFA438CEA9555D,199CCDF4887360CD,D0AA3D9E39DEA6E2,0001FEC898B4E64B,A1167705CC604802,9B0475E804B66EBB,AA74374DB1D02C07,C5F9051D584032F9,1943AE86ACE3FD71,3E6A71D30181F87C,00001CBCDE59123F,599B52AB71D7268C,0F3484FB328FC310,219D02462C485995,96813438E13E2630,0884F4F0AA13D44B,F3DD64C9126A7927,000061C76B751FF1,22ED0D64BE52CA7C,528980035F395C15,0CAE03D0D5A43C73,1C1287264D5C1AEC,84E9789DAED7AFFE,B4D9CA0724DE85D5,00009CBB00506503,9697F12BBB4F9E15,C540123C632E6148,563FEB07C62FEB33,60E96983F436FADF,142F689696B92FE6,2BE7B97EAFB4CCF4,000175E3DB54C653,56466284DA74FAC5,F7CE3453F2560361,59CD652D860735F6,C5B1F498B026D1E8,6A46771D4DF854EB,7B54C0443FF94936,000017B0792A0D27,0C6C2623A2B4B782,65C5D5CCA5852FA6,14C01FDF3C34696A,8DBA5CB98F6B1427,B648AA37245B17F5,50286375AABA2BA9,0000B7AAA6A8056F,52EC5D6A5EE7D806,ED3DEE0C046E62A8,8B9665851068329F,83C26D40D5F05564,E490AA6D9063BFC0,1591B5FA2A448FC2,00007DEBCCB15816,F513A62CD4F86622,12D53765336B8AFB,CAAA83114D2CB2B1,865327D8FCA47DC4,F45EB1F8C73CDEB4,8FC57FC89FB43695,00002C3D4552FF2A,E838C6E6429259E7,7C7411899F6CF3DF,95768E648101EBBF,41D8099C8544F62C,517C557CA8678977,5A9A890DC1E584B6,00002F9118CE7D77,2005760ABE9FDAA5,C64FB2E8C999A3AB,4FEC519E158CAC5D,74B5031081A1523A,055FBE3DAAAC9FB3,F55E353BF4600419,000134F4F456BF0A,F923CE1B72952198,5632F2DF369A7270,D23F9A2E1AAAD6D8,CA99754637E329EE,E8B0C4BF2F474B96,9DAC252ED3ABB446,00009260A82C0946,DEB616C093AAE330,53880514BBEFE53A,782ED92E2DF9E6D8,FEE32B2B2DE0B081,1C47090F1C5A953D,670803DEF462AD9B,00014C54E5932CE5,EB6D78D8DB18A05D,908ACC004FE7AA48,3E341378D9D6CB64,01B9BD602A8D4953,2201E45C5452991B,3AB75F313A6D5EA9,0000D9D595CE563A,2067247DABE833B6,B8B60516F45C65C2,7EB5D46365A4931F,E85BC3737CD1A201,D437A28C0C50ED6D,36E0C9A653D5F4E9,000065241B21F647,3CE693046D18FE26,97D3CB4623E24788,5D04D524DB413EDF,603C77B7364A12A3,F712FE6AD4D5D237,C5E6E682B724C891,00021E3610B487F1,9C5A7C8AB674E87D,59F719E4A89E5E31,9AC89EB43DB82E6E,B18919E5041A0D11,F367EC405470DB69,A2988CFE34964CEC,0000B53CDFF37DA5,CDFEEDD820E107C8,034992D65F7EA965,A95BF9A707A7DCD0,AA411E13BA542D4E,67F82E08E15ADA38,C69454A28DB9035B,0001C8B3E0DF6990,595D773002D49B7D,ABC6F7E98D944C8A,BA4BB388BC5B7752,2155F90A0F7EA448,953DA43650A1F12B,F71B2ED7EF6E4BF9,0002069E25F59719,C62117B322B679B7,CFD35A3E8FE0B469,865474FBAB2D7CBE,E94AA8BBC1FED13D,F6BADF5906923671,D3E0B17A18DED721,000016F03466B979,139017F547C76CFD,C4CD171FB62530BA,460629943BB5700C,DFDD92829CF80672,AA8DA5D45B0168B7,4A0ECDFD65BC0948,0002056D441349F8,7D67D8AEBE772690,51D13A8924EB30B8,EB051B1A30638CC7,8446BBA5B4394581,FDC6430D38FFCF36,6AC52C9F1CB0EDD5,000096864BD65FB9,96431B2C57A6C9A2,D107BE550A8CE5DF,D8EB4C8091C4582C,5BFA034E400151D3,2B651C2360CE35B6,7ADFD66DF540E7ED,0000D466AE1DD6EA,16770B0138AD88DC,2396203017DD5238,AB4679509EAFCFE9,B86AA9BBDDB82A9C,2E5205584CC5E657,8312A2B97E997BB5,00005486E4EB507E,281E06C8FB1A9CF6,A057BA3F45CA337F,90C62FC80CF9838A,A9A2EAC35E19B5A4,104824E446EFA4F6,51CD21CF2E263CA6,0001D9E214EC518B,F4D5858502BEE612,3E7E47AA53D7A61F,E97EFFC1323D4939,B148D2F00D4895E6,5F7C9B35B13646C6,B1BA45A292EA1BC1,000121BC84F21887,2BB387BC7668D247,C8FE3B8F40101302,B5AFF1158E7D004B,AA9FAF9493D86B76,2DA2BDE1D553485B,F6D6D3D355D999D2,00014408E95C3656,7A921AF479B8018C,FBF10D450D60796D,4D62000569562FBC,2EA9D2DEB125EC05,E5B01B634EAFCDC8,C8D296AA92F4B29F,00004131623D8295,A997F7718C608823,8A1F8FDC6D627DF0,B16750F3141BC4BE,A9D85AF18DA101FA,47156B1A0AE76641,151701260F55A966,0000FDBD6776537E,D7DCFE43F09B1CC9,755D7C03F798DEE8,DF50B90E371F95C1,AA9E1F3875C0CF0F,936F50B27D53D764,FF9772D61AE08D6A,000110235B24411E,661FD00D189CF43A,1B9D2F82880E339D,E58B0888031466DD,A30B147FCF7369D5,9E75A7501BDDEF1C,1C254B428C8DEDA8,0000A995B7D59AD0,417AA7CB12F5949F,085AB4EE232BAA7A,76E5C8532C0FDE72,1DA5A0135F5F8F1B,F4E8F13A636B3162,B0AF2C3C55D1FC5F,00002C7F10608014,9DF9CA0008906968,37A669AF80DDC861,F332D5A5083126C8,A6BC9FC053E1B199,11C8091724786D08,0B91604E0D883B46,00021748136D8270,32FA5653ECCC0907,9320D2D74D97F342,AE07EBC7435E2195,3E4A61F38A78C7A0,17A3CAD1913216DC,416BE69959FF68E8,000207D4565CF746,9D9F3F1E81F3735B,6DFA831936FAFB74,0E9F7F6FCFF20EFE,7B5001A9F460DB15,6651E738302C8516,882F9A96F2D6B84E,0000FB63F85682C1,1E86CD7681F49752,23A4431F542B898D,A009B12DFF118789,B9E7486C76C15B68,665DA95843519EFE,276147DEE9A6CE10,0000A6308998658D,8E59433A8928D537,87B0D3AC14DE3206,A0A764D765C369A3,5F19D90A92B980D1,5116EE65CD6B1A28,1CB4A8B5CD626268,0001CB0F468FDD70,7E8162A73C42EDA9,6E84D36CCB936BEF,D3560F1A46AF4246,F948E2E1DB08D532,06657B743D033357,C80C8D8BDCFCC4B0,0000630017B8CBDE,6813C2CA78EA6532,0239C90DAB42CB8B,828A7C1E1D539084,3F8D3FDC3EFA47E3,1EF9A368EA7C189D,CB9D162A07D0B223,000122D43C537743,C9F636E017E3B1B2,169F3FA9EF4947BF,E36DF7008112862E,62EE22415849A2C4,ABD5C7C940155AAF,6F795C3F0ED34B94,000067341A0FE224,FC640D49F99BC842,ED5B99A8897FEDD5,3BE81C9AB23D280D,0276DB255CAAA6A2,E965AD3D756D56FA,B3FFBD9AFC917767,0001CF00D0E0800D,FE36BF38356BE66C,B2171C2712CF3B35,F91AC8B1DE16767F,FB075D0E3DB01C67,6FEB3C7348477B34,A5F6EE511CDA4B49,0000D6F772E5D55B,A9F7A9B6186BD93E,5186044E8809F756,5C35FE492B0B7766,1A45537E1601E5C6,331F6A993C4C8CAC,3C2BFF1889FCD6BF,00001C53CCE51B05,9826DBBD6605AB26,46E86FA1200268BD,A2F260A9B28D3670,7BC117A02D0AC6A3,1FDCE7FBE6027308,B409FC13CF6A1492,0001CF91BACF82A1,E907F75B3A968B99,E47699C02AFAFB85,48768C4CF9B98425,7B16DA5471A9E53D,9EDD43701335C6B7,4B791853F21A6322,0000FDCA029F9EC2,B6CD17BBC7A43C8E,36D19A5B43178CD2,ED306A4CE53245BA,38C7DB7A81EC9B57,853CD3459B9115DE,FABAEF09391E3BB3,000159FCDDFFC63E,560B307BD4200FDF,67A9679AAFFFC3BC,F8BBC28F967F8336,E3338C68DE777232,34BFB6FCC9A3E4C1,ACD3E854C46DF59A,00004F4D6CDD103C,6E927859F2DEAE0D,C8977DDCF38A908E,99583037529B14E9,3ACA2A118E1C7976,45FD85B46B5E951D,B29C4AADECAD7033,00011D1AF3CE2564,14D736500F9FFA12,4450F18DB3AD616C,1C33F9559F67F7BD,32899A1FD204A0D5,D1534D316EB7591B,94DE464790D7A3FD,0002117484AA15B2,CE4F84F56F402BF4,2233262072C7DC79,D98708B9A05D814A,DB716CB98EB4F9B7,1989FD6C0C65FD53,1D7F883036BE507C,00011526FB9B975D,79F6B268817F4515,65E0A8BD9B838236,46764493B66C9AE1,EAECFD9638C813EA,3F20888D7774682A,FC2BCF942BD3B72B,0001C98CF7087F4A,50A13912001CF605,7AAFB190343D01A1,28CBC8D1DF727051,FEAADBB9958200D6,37AB86C82A7B3B1D,301B93B95E3AB8F6,0001F84AB9F39AAC,C54A5B714D8595DD,FB03ED8FA8DB469E,C41619A2FF6367CC,31733E4E59C0FE7C,D9CD40C63E3F5DA8,2B2520E37CF66E80,0002072614B572A9,5CE501306BBEBE1D,2F15F9232688E728,EC4805C61DDD146B,01147AD22A32FD34,F708DC7CB2F6B6A5,96228A56F567BF37,0000F6611B611886,11E9CE8A49DE36A2,F3F90225833DFAFA,B4233396586568D8,D4F95AFB622DFFA6,548F577872047156,5283DCCB7D4D6269,0001617A4F7C9EB2,A2F3AF8C811333B6,31EF97B3682461C5,1896E09D065D24A4,5BC2732409C4FD02,EDC25375FB3499BA,58B623AB99F3C477,00017040FE8A8E4C,CFB05747C092C915,47403FD4F98D7742,70D779AF48CB7C05,E93CA1051213E1A1,F37DA0649E7639FA,C9581E723FDC14FD,00014D02D156DD97,7B40D017096FBC87,95CB3FA51E87B11F,67960769DE4F6E2D,ED95497968D0979D,89945BA628768A31,CC07F158FABB9292,000098F681ECB226,7DA25C82C2613F1E,D1A0A71AB5D5171C,FB36057C0E5FA944,646B6DB171D0EBB3,B9E035817805D2C3,6ECA7CD9AA80A428,0001D81B070C09B9,A742B97646AE469A,0BB009D3C3F641F5,F26E1DB3AA2CA33C,8D63BCDB84F918A9,ED12E49E86B3BAE5,B7D243ADB845F38F,0001A6CE763994B0,2388CB8973932AB9,B41231883A37C1AC,257020E822C15094,B7E22D56A2BCD6D3,0F608F5879DDB1B7,7532A8ACEFA95A3D,000181350ADF2307,E333A525C71AD637,A9FDE30BFF75328A,26EA1E4BE37EFDBB,43BD72BF1A084A60,58448A1E79872FD8,51BC2341C9149ECB,0002108053F49EE5,D6FF8610AACA8BCD,6C0B2E287C8CD67B,ADAC6CE29FE7FD6E,9C87ED532819C20B,FFB1C6745BF5C8C6,4CF81148056F886D,000178FC6046DB00,E6B34A8ADB1EF7C1,2570DAA91CFDB43B,D35508C9B322CC99,2E2B67A20ED412E7,7CDD446A2A9B2304,869571A32D9C1286,0001377B80A5E825,9F10F20C2A7BEF72,C6C44746E9380A93,7DBC78A426BDE220,C8DEFF7CD6726E9A,ABBEBE9B82E9E8C7,E68027465AA2E211,0000B8A985F5F29C,E8EA6E9333FF7547,6A6AB39C8DD50C70,CAEE39561B2C7D66,F69512EC39B11BE8,EB6EF99E5E748210,3AE3FD876E59B518,00006B75BFA4B39F,B4F3080428A2BB6F,1853B34104C7E88A,6DE8B7709913AD85,6AD9FEDFF3AE11DD,3D3773D6CE6E8493,1884B84DBDCAFA0F,000078578AEC6410,8D3872E258C5E98C,8418EC1C81C6245A,0BF601CCEAA632E7,2CFAF5CF92537759,D32CCB8CEDBEDB10,EA31B38508F2E4D8,000151D254FE3B2B,9199119B0D01B6AD,766EBFD38F8265C1,BA539ACC32DD28B7,00913F8A84E9C001,86A640087FBA90BC,01CFE3142E75A7EF,000159C99B689E64,0169010C789897E6,09CA63A6F9AE67F1,F073F6459C758BF5,482BD7BED9FAB52D,891360E28857FE16,67ABD48788ACD4D4,0000B539842FA121,DE351B253F126F17,17A435D436BFAF31,D0DF6BD44C6AD3A5,D7FE84876D5316E0,8AD5043EE56AA23E,1AF037E264DD7446,0001BC40E227431A,51B9F56A80D5FF0B,699E561073423020,27B7C9A5A63ED0F6,219B234539C2A3FC,37102E2FCC56D989,E47509D00EB4E9BF,0000C63191073E19,82E72911D5E03D45,B09AC2C3F4773BE0,6DD920BD6070A394,3902B40E64B49EB1,716105DD4251C547,0AD5AE3E65B15948,00010B5BE0BF7890,161475B90BCB3CCB,04E4B1A76B4C6AAE,6A3F40495DBA2C61,AD5E385AAAE70B6A,9B713FCAE3919774,4175285380063A04,00010C2E7EA03BCD,51C5152546CD9E7A,13943EE8E92E8AFC,F3C4D20BBABF67F9,F98AB344B32D3BB2,6FA91E9F1F39339F,213B118B1251C91F,0000EBBF84D6EA19,CD0B67BDD5E019AB,8CBFEE99A3FF3320,4C76B2194F5E4F2F,0F8415F475C5B55E,A244359070331116,5E91FF7DCA61A6AA,00013B0FE596F113,FC745EA1FFDBF0A1,9847D39BC71BE897,836FF68B585DFF2B,6AF2117C72F88638,C3D6D6CA8202D43C,92F6C294BF5333BB,0000F72F55BAD358,5847D19BECF6D882,06C4723B9EFB5F78,ECFD355DC8052910,CB7E951D3FC1BF07,5364F1C05A567DC6,CF79D5E02DF5DD8B,0001D23A29F3BF33,B3A4F7702DCF304A,0866AC329404D80E,00F23333B1025FC6,C3E8C70EFB5B71CC,7B2C97766F12F126,9CAEEA3BCC5243D0,00021E0D985601D7,0972847F559F87F5,FC7194E6D8E993B8,37F6023DA541787E,4E2F20143B8367BF,0FCFDCAB2D85560B,120BB2E917AC752B,0001B74B5A9E7E16,8C21ACE04BFEE555,4EE17C1D7728A20D,F3DF84AC161E8F1E,6BFCBD80662B3B72,A2AF5B3577B02546,04EB51C00ECD7DE1,0000F1CEE5FA3DB4,31EFA80C86A9CCA2,C2F1B078EB8297D8,F0847DF1D602D170,4AB9CA9D28E2B612,E009558CA6B033F6,D685733A2AF4BC2F,000135A24559C81C,0757B995A06394C5,9FDF0B1F84CFEC4D,379A5A07B384D817,B42AB36A732FEFCB,F0E29A2F5FFDFFE8,6DF493528B935228,000207183A2B5FE5,2218DD5E9634EDF7,FA75BDE23CECC193,36A0EF3A49B1D8D2,E716C2A03D9CD450,5BA96CDE213AB410,EDC23956F534B820,0000B497BDFD72D7,440A73767CF27C37,841FE6063B5773D9,00BB9BB99F9935C1,1BE40C7E0C4FF896,D24FE03897F87C7B,5D8A645D0B0FE2A1,0002245230AF9EB7,9F468713944687B1,170F9106195C47A2,2D93C4CF4C878918,34FB7236224F52FB,C85B1AEC48928E30,86C8FE1B4FCC827B,0000510B602D6A7E,C945477921794C1F,199D5F500B774985,D9FB4CAB60A68BE7,0662703F3BB33813,5CCCF23E1A3B4338,46C3147C1DBB5400,0001700D82C32199,440E4415B0265045,2EE74C9DDF523CEF,E050C40CA5CD0C6C,947ED2904653554B,7C70754A7EDFEED2,6BE9AC3014AE0741,000111E385708613,24535B206B14117F,F14A4455139898AB,A3F127B45EB7D4A7,BADEAD4D85910028,AAA3808BCB15E441,37628BAA92E8C4F9,00007E1CADD10EF2,0B0E22F213DA3510,1CF0F8C010E35A4B,E04DCACA80AD1E28,86B1695C5211BBDB,37C0B5F5CF2BA5FF,38859A3C80D5AB85,0000836D531FAC4A,C891706EF73B2B0F,DFFBA0FCDAB16047,5F097CA4079B3D82,5A5C6E09D573B441,03427D5654CB1D53,87113575EE049D5B,0001B5CD36C1416D,D6A2C98D7BE78DD5,761B45FA26156D68,B3F3DBC7F7A684B5,C9D6128808C9CFA7,B871B08E870D2631,D645E2397BBF3E48,0001F9EB2AE8F6CB,9C49C3B84C9349DF,BB03305EE7FFEC91,39A920E47FED7ECB,A7C68DC0B4987B72,6B573504858741AE,FB369FBCECDB0857,000105903164AF59,4ED06B094647F704,AE5BBBED4CAA8D52,8CB4073FE74CC9DD,D629F07EEE9409C7,512D156423F32582,1589A1F27292F625,000231F80561FB3A,2339B8DB87F7E886,CDAC08549EF72E3A,B95A6CE5FF6FAEB6,651DA51DFB7A6268,62C3BD92869AFCBA,FB3855FF40949E86,000061697C51A3F7,B0446B3436872E50,AFAD37090363957F,81FC701D7BB7676B,036CB880CECC3023,904520E4949CB5A9,E9FF8DC7DCEBA48A,0000F2C11BD9A907,34D417E3DF7DBAF1,0512657F13047C31,41769A91A8DFCE46,C07BBBF0F9E96DC3,5BCAE0982179FE0C,6CB3D7671B5FAB9F,0001DBB65F044433,49F7A3BDAE9765E2,329D77AE796FA340,CEF5A1BB7DCAEFFA,548643E85C448327,8B0242FB9DAE89A4,13F9EAE19A94F5DD,0001A6C5163ADFAD,4B4F06479107C779,FE17A51F6D984DAA,77538C5768464B48,5186D65B7685F133,5BFF8466A34D5498,9020363580CE3907,0001483067B161D2,0E51504DB1DD0DC2,1FA24136101184C1,7F2659383BE9B4A2,ADDE9CA18DD5B9D9,3F81153E789C9F75,C3775BD15A3B965B,0001D1D53EEA7073,14E32B853D08BF67,3095933732B971B0,A4DA7D6974E66908,924735F398D102A0,BEB64D8E5964F30F,87488469EFD1BC4A,00000E0FB6568166,35B0744E79B68BEB,8669097111BDE82F,3CEB5DAFDEA458C5,69AE4858693B9CDC,1A8AFC22BC552B8D,652B2AA165BDD8CD,00019BA33F6C32F6,78E21540794C118E,7191AE089D34B5DC,A130D3B1B2CDC1A2,B7A26D443E442DBA,8ECBD0E011FFFCD7,83B87B388767AE7B,00007BD1F059854B,900C7210DEEA63C1,750E4CD088AB8525,27739B2FC9B6A5BF,ACA1E45FEC52D988,722902AA724875EC,C82EB4F3726B43F7,00007556700092AD,2A8117A282738D41,A161286A17034792,FC6F048D4AB1BC42,8E27140793BC8428,D7AF87D805ACF482,50A88A97F5CFD0C9,00010E0649BC4F1A,142B645EC8CA7983,F7296E91BA08BAFC,09506A81B2748D65,D60BDECC02A51379,043EC3954AE183A2,7C3F025636E3952F,0001E2E701B14761,78480A9ED4BC11D6,6B91F4ED1BD924D4,1A05D80B77126674,428DCCF170B5D5E2,34A2652EB84ACD93,EA81167D1323C22B,00009B68A4759A01,12492DAE6C2174AC,A4580164E3CD6152,0E4847AD5AA7FAB8,2EDA10ECA61B45D5,91A7CDAA4AE9D0B2,0E862BDD23300F8F,0001EFD166BDF8E4,5C283B97C3392540,05B4B1D62DA72989,5277895DF708EA5A,429F3267AA47AC12,7992EA78178DA6D4,D77AD8C4F5A151C7,00013091D434D113,A1CD51A3336D3F0A,1A2311C4E7CB33EB,A3E4FBA6BCF38E24,08FE070423C9EEB2,8D66212F010BE5E1,DC616DECEC906CAA,0001E6AE15D128BC,697CA1BA337208E0,7EE17760B3EC641D,F8971A2DAD2D308E,1E0C3E456EF8B856,CD95FC65536F3DFF,B15A7E104D74AD43,000073AD4DB27A2A,70A6B9D639E6C7B5,A2C170220ED2C02D,81CFCB4DACCA31DE,608660AE190B2D25,DFA67F65ED89E8F1,3B949943633349A6,0000A45341401111,DF0F371D728C7100,468809375DDC0C5F,E3F2D624B0B17E20,AEFE4B6DD7D6D61C,5EE7575F3D9DD60C,FC97A5E4DF4D66F6,00005293F56FC81E,430C4FBAEAE32351,A5A6E863AC48A334,D0CFF15989EFF580,9ABB8FF7720351C7,C2BA3734867238B1,251FAE217F9953E7,0000651BF3F92F5D,9115CF323B795883,8976EA8F1357B684,E172CD6AC6F2FC48,C380165586336937,052024E619ADC9EC,A76E00C82264E5E2,000182832B2CABAE,4A342D3F07BE63FB,B38722BEBE5F8E86,8978F684A9235ABA,DC4F71ADF3A6676C,483B0055EEE5826F,E740D12C9D6D5B11,00008B758AF8A619,64C5EB4CF849FE3E,3223A03713CFFCA6,4ACD72FD85833356,1F9830232BF05D70,314E56B3AD974321,7F08EC8D6760FF81,0001CDD8498AE203,771C58B8144435B9,0292ED37545FDED5,644C90B4831C8D97,4C34FB3CDC9EECD1,BC7093D9ACEB5473,CD0317DC24D7152F,0000E7588859F381,40E45A92EF8D3F74,0A7D2D3AB7DDECB8,5FF09DD578B5D205,C7FADBD1B161C428,B9DD688CD08D1414,83EBD1424D5DD9C3,0001E9216DE7A064,35F1E494ED1CC41C,10A8E1B82C8144E8,FF6866E5277ED927,C29F2332A65E4DC2,407159C0F9E03133,E02FFE623F27FC3C,000176588F6281FE,40D18071A7BF094C,26D5DB2C04407FB7,5CBA318B45497A7D,220AE7F44F23C5CA,5354240124E0E692,0A83C14C5F3E308C,00005C05F58E4373,7EE085E373DD31E8,2811640A3C486E51,2E899E770859AE53,170F82D6E917957E,56AFED3698934C76,CFDD59D1D8CAC235,0001DAEBC41E71DA,011EFB9793A0480D,E1E31195E9084673,9CF95A13F9DD2E36,88CFA782697F0393,CF8D66095B94FAF1,256DD4C6F7EB3496,00003961B64209DC,21E5E7243F51C944,DD034CB11CC8F116,CCF0A390CCA74CAD,402017335F6F4AE9,8E333D8A73D28C0D,FE66DC5CEE7D1842,000028EB1FE39BE4,3A3381B6C131DE68,92133C4F28132DBA,867BCC9E9F5811DA,346D95579BAFFFE1,96918FBF0F2A4B6E,776AD86F88F32F75,000061D294257F71,085C9A5D3A8DFFC5,D1AAB0B6D323E742,E9DBB2DA67E75333,62041DA12E37A062,2A5B45087872FB16,E0B2EB5686C8323E,000141BC811D58D9,EACEB86F027A9598,FC8FFDF99EAC3A4C,3C533637F45BCC3F,E74A63253C1583D6,CC88667FAA643D34,EE4ABBB031E903A6,000120D6ADA390D1,BD36CE2C05F93D03,9270B99A3E27B91D,43C8545F29A34D03,71754149C6CC41B2,DD6F53A9051DAFA6,435B9D1CE6B94133,0001F59B3E07B6D4,EBDDADC99A68FFAE,00077E83D1A5BA93,E6FAF29D0D342E13,9C770E70688EED8D,4F67116D2954BC54,10455FE00ACCC502,0001C2C5442F3B43,4B93603B729B88EA,6ABCEAF4358903A7,C3582876985F58D6,49BC6FE506B680F1,E2623AC4754C72C2,D1354E02D98B85F3,00018FF37ED2DE46,A37C3BFBACA8112B,46A104ED1F7A0224,A80AD17274CB4800,B1651EDEBF970F7C,F94D47CA71632FA3,8B95CF963EC0B52C,0001209AB2840197,7D9F3524A3757D33,1D29E3D8123D00F0,46C9497FF9537FE9,CA98F78E54F48924,23AF13A0C34A809F,BE3BD45F8371F3AC,0000260C92718503,11B13960F0681A3B,0BCCD055D50CFA8F,6E5AA1557632D0C2,320FB8D12E627CE3,5E2F619300D35728,0DDB7A0FF7B34D64,00020C7564B096EE,02968B12383123DE,DFA11E2CD3650FF2,510F891DD5B65A3B,46B5568C2632B566,8DE4B4EA4E56157D,D4533905A9A33ED5,00014E0E81D1180F,A64ACE11AAE7F01B,8143DA4812D31828,74DE31FA3B15305B,EB7050A32D01233F,2D7B164EE5E0E359,75C38A141D569623,0001EFE35159F4C7,95A1E4201E870D85,9DFED2BAC1F55E18,7BB8258D4B68B81E,2140082014DED918,C7C5A97B59F3B4D7,FE77BCA52360FA3B,00012B02E5FF9E06,40B5CE501086BED1,8B5AB3659420244E,79851EB1EDDF5397,E97ABBCDDAE239DB,DB6AA0C50B627D4D,B629CF74F7EA9CAE,00010690556AE07A,3C50A6BE954196FC,27D7405FB0131F0E,0A58F8C5B28ECC94,3C1E7550C10B4505,A8C6A73B1025A95C,010C9329DF50AC5E,0001F0E37FA93C73,F60D05B60460EA0C,51B50231465F23BE,E0447922EBE80BB2,235571CA1222AF5C,D6C250C26E4D9231,A6610FCE5DC7C7D3,000201230BFD9B87,E53815DFCF57AF40,F8E597419FE1919E,B23BD512845B0CD5,E41628CE95B70A4E,F2FEE4B4532EEC88,4841EB18E33862B3,000210CEA64E3359,42BB0F701FD85A29,1EEAC79A9C5C0127,361CD68264BB1647,009E325AAA358159,10A02191A0BF2C86,8EFC36FA1F1436A4,0000839AAB3D5BB0,982C741F94BD08D3,1A294BC442BD6112,3F5998B443D3433D,7853B1CBB05402A3,93FA1305B5EA6FAC,77F7894DDBF40C29,000044EF55C2788A,7BB8190E5160EA01,94720CC1BABF7B37,C8E298D0B7A64732,BC9C367BCF8DCEB5,4686E3B12137C4F1,DEED47F2921D01D5,000002CEA420E749,FC8906FD2F63D73F,2F861CF5A3736C1A,C97B5B065A7C6FAD,50CFA8C02F1BA68F,6081E6A510ABC81F,F157953E0DB1B63F,00022EE60423A038,5DDD7E970E548183,97C13CC1E0FADC2F,5E0FBD6B3F9E7838,B0791288BF03480A,B58283D2B1153EBF,B055C054045FD8B8,00017E0FD95AE70E,92BC9451108AD51B,EC4AAE98565256F7,13EC12ACB6B62CC4,53B555B03B2CDE2C,2E9E53ECF4052757,79FD1984CE863193,000059DA17A6D3BD,C23CAA213B325651,0F19DC27BE9D08DF,2DC5F79C48D0FB47,899358578E10CD9B,E7DBF36CC71BCD7F,61DF213AD3DE9A43,00020AC39D1E05ED,5A0C7F61801CB5DF,CEC694C4848C51FE,792551F8F18CDA71,3EFCF0D81D4E4C7B,325C1424EBF30642,11703780BCEFF034,00020B1358914CDD,8BEE8AF3407AF49C,88717DACE88A856C,FEB2C2F3B519E382,012A44F430649471,BD62E4913B5B25CA,463222B5E503073D,0001A374C36814B2,D2960B0DA787BCDF,EF5CB8244D209665,7DBF423EE34864E1,651BE9F699FEF461,F9629890BD717F5F,25599DE6EC2F669A,000070B29FF65728,5E809D9DDF6D13F7,4C875B8CF7A99D76,B68306BC2136AF15,9E6403BC2C521710,2421C40FD2A889CD,9DB0411CA2EDFF46,00001A9B81A55669,B29C6D0C502706E4,B649F2EFCF21F303,8566D0BA59154A97,AE8AD207550286EC,BBBD73FBD607E409,A03E993FC6BA6258,0001B46F14D19DF7,B63F4178B4E870B8,86D3D4B31984E3EB,F9FFA40FEAD2407D,380364E2376558CB,21668149CDFFF7FD,B076CF0BEBAEB8BB,0000EDC0EFAFBA42,B188996CA22A1012,9E428BA8AEB79F78,AE310F5C756B5E49,B292208F50C0C521,678BE2FCF03B248E,BA9085D07BCB404D,0000DD8F0A9B91C4,7708B76E420FDBF8,32F0251BEBD3230C,947DE8467AA136DC,B9CA1013281B427D,90A2C714EB930912,2FBAEF853E987DDA,000230F8EA86D8D6,91F2B9873FF9F185,52548F278B4A0184,950D18AC46C988ED,DD72D5407BE755CC,E9C7583A75833081,6DA9F3660E1EAB40,0001EC09160D46B1,5612EC3288182720,A4E4F14E08B7E367,25EA7E7BF305CCA4,18AF48CC15AB2B33,C52C7B589E3090AD,77302FB70E3E6574,0000B9B5AE068C58,2F885FB031310186,CE464E23F96A0437,C728C06C863D7AC6,78BD965B6A822062,482DB5E2E0F8D1E9,5FA5925E2F80A064,000051B067F9F1D6,F680AC6D7E909AF2,049FA8275D90D167,3D61B7E320BD4D8A,DBBEF12B55F2789E,154F1E2AECC542EF,7AE304DA2FE8DB1F,000109E1E7F6AD20,A20A9F6CD06715AA,4337ED911C9AFCD4,32CB8F89129F9077,ABF33DB593D529C9,2ED76EB1AB14FB77,73A0FF6A308754DD,0001AD19961D6C03,20581C111F91FA5F,07C4E3ECF97E2BC9,1037E64A547CFE4A,1A0DB58D1C1D4C85,6310C57D1F8F3592,3A44C68C2DC222CD,00003C3018750C1B,A670E11793AB53BD,E5B033E983B50C6F,47483AFEFEB2D63E,F31BD2C83C13865A,707B4CC6ED995E87,6997899FEA018327,0000B5B65CAEB6D4,0B47E9A8E9DFB3A6,8C8924B03088DECA,8FB268E26F0DD9E6,2E9E4EE5FBA7DAD7,1FAA175456AB669C,72EE16018AA1A000,00018524BD0C50C4,352DF1F1E338EE0B,0D9240741F65FD54,4AEFACF2DC8A2A70,5189A9FBD0C3BF11,894D8700A8CBBAD4,28069E8F8F831BFD,0001B13C96BE5C6D,C4B57DB667CDEA8F,DE32240E9ECBD884,A69365DFB7459564,C9704E7D81EE4BDE,B157BEB1D362860B,A59D6D8DCCB28BF4,000168A9C0C4BFCA,EB66967DA14E1AB2,6EDEF0D242714A28,77671CCF81036ABD,2F666652DDD86F11,53001850993EDA17,699185D1F4A258D2,0000B33C5AA033CF,BE5FB545332A65D9,2C9097081C7099D1,A508BD033D788BBE,3EAE1F7149F772C7,76EC7D391CD296BC,0D72C9DB08A4C302,00009CF6CB0CCC12,A5D8A1CAE35593A8,A75C3A48B399A494,6BC6280FFBF8EC4C,3CF66C7F63AB559B,FEDB1802F4F09C1C,B10F16D9C1AA5055,0001E1167422DA39,8B15732721ECC2CE,4DF0E7B380F09F7F,D69AE2FB5808502C,97E89080C2E0A028,AF778AE2EEAC576B,268C00BF9F8CA93A,00006838398CE566,3763393C39B7BCB9,8A13AB776CC4384D,A630578C478FAF37,CF0E7117FE90792E,9A35525AC4DAA2D1,5D6F24896EB4FE80,00002C18C4DF8E15,BD04F8216CF03027,0471A7DA573393D8,EA962E0C0475165E,F3190977EB5561AD,0556FAA6E5761397,1F1216091C8A9E8E,0000A4D6BF7FC89E,C5131CAF08E81655,F044A6FA15D902D4,2F19C071EB2BDACC,FA64614CA4472717,738F575993EC09A0,966E9A767F73C2D9,0001C35B2F0E4857,9353B1A9CD9CFF9C,7EBD59576D8A97C4,3F5B9F6644FCC5FC,83A8C7E1000E9B18,CE7064916D3D87DB,C8112347751089F2,00016831C80BAB59,F37FA8A19BBFA0C1,660AC67E46214BBA,B7182140541F1337,02F777B7CA861FF6,68DD27B914B3559D,B3A385BF038A7784,000046F144070F41,4B33CB2CF7C9C32F,5C2CB19DDB827142,D65B45D54CBD0872,B6CC6AF1A4A61BF5,7F9499E61A104882,5063EF7F80B9DE33,000051595400F5D1,AA2382D203C22AF3,AF46B6FCA83F75C5,2C524D1D89374C10,06D2D2F7CF56F636,3894C73B2C9C18CB,902E0DDC22AE5741,000206BCC4967965,D52FC40CC215D901,8D8EF94D42606ACA,63A4BFA86CCEF8A9,125D6D441422A8BC,426833ADCB3DA6AA,4BA756B1BFEC9D4E,0000CD1914EE9590,D69767AB5B4FB3A2,003EE1EA31280273,81FF950317C5792A,B72EB583F98EF323,A4FE0777914A2432,755725526955EF02,0001C0499DE2B560,697019583FBB5377,06E6730F15E85512,AE6621C9E637101D,9889784C92D45F89,CC46BC291FE6FDBF,6DC330E774E143FE,0001369CC538947D,D1B27B887204D904,D424FCFC344A12BF,399CAC53859218E4,B4BB281D73D45F45,5C2BADDDABE11716,155777862F5B42EB,00013DB173875F92,77ABD9E8E1B43DAF,4B6043152130D934,CC735E4067F77C6A,4F10A61A08D976F3,F481AB1C389C4C8D,DF4817D2FE237022,000064AE7DF0DCAC,85F63608A5E904B1,F632C8E4F5606004,050B0DDF349950B4,15DCD874B92A4B73,2F81763B3479D06F,660270FFD200937F,00006D2DBE1E8454,76B393E7A7F32F26,EA64F565343B9838,22166EC452BC79CF,182374C732E62382,590EF01B393AC91D,B8A1A217EFE25D7E,00004779B83036D0,6646C8E2610C0249,F312D973756E4333,B43F730CD0A2DC84,8A38E85EFE4DFCC6,6C6F00069DF843C9,4FC7CDA337353755,00007B0B89B74F60,C966CAFABF97F78C,E127B28A4BE5D4D5,0C4CAA53BA4B74EC,3A0D6CB375CF93AE,C5D27FDC6C6C362A,D6F8E8D6A5FFBB15,0000D724D58F9006,FB31A57A97045B3D,097CDCDED2A1B940,A3C9C971202D7BAB,2BA5DC919A98A139,3A403B4AC4608688,7DC86A056EA67718,000110C709DF355E,911188F433E7BEBB,52394A63653DFFC0,CBBE124D44190088,4895969C59BF5B5D,692364BDB73D3036,5A692EB89D736408,0001709E4EE07D6C,70EF3E3B9246C79F,24F391823F1E8D4C,8BB7DE1019D1C6E7,D1E844972D67017E,40D21714475FB552,2157FBE5EF5910E9,000004DDE9835D24,A7B4E90655FE4ED2,2350C513EC7BF192,6B1A517036BDAB2F,33565392178AB194,2D5957F5CBDCF097,FB818AA871783180,00007132CD1390D2,76D18A7C128D644E,9C27FE4A7C766A87,B63BDD3D47A34BB1,81B0B6F99D55EAA7,B35AA4D6898AE73D,008ADA28C43CA7D6,00003C1F575DE863,EE26D9E8743F244E,868546F6E4BA8C86,6122A2CBE0BF3D01,5E92F3C61CA1F1C9,D599926AD2C2DEC1,2EA894FCE157CAD0,00002BA94066E5E6,47E4D198E6136EFE,86CB354E08E1FCFC,B92E58640E415212,15F86E4AD4BDF9B6,2F0ED6C0B5DDD20E,A5A2808D2540C218,0001749E1623C4BA,FF2948E195A529E3,98BBCEA70EC0234E,3076470899A994F2,F9F976BCFC89B5B5,29667E85AC0F5EFF,E902E9A409031F62,0000471C5A77B0D0,0020A98BC45F7733,EC0A5020192B1404,7CBC42E2836A222E,2AAD21FCF2A6358A,F4B738E007E98779,0B69FFDF3D9178C5,000212B0F983E686,7C792D4D512EBFEA,AB82CEAA25FFD434,8BAE46E2B3B4F2C9,D1E873AABEE438A5,C5A0861998F089F2,66361B726DDCEBC9,0000ADF77199DA12,FD869DF5175919D7,C6A3EFE86700E154,D8749F06B251022E,8094625F6FA633F3,7668E9CB5856930A,372F80C27B225575,0000D34B6AE98F9F,73904ADF7D95A0F7,F7E8288987DD242B,CB84AC0F3B6A7315,338F5718E08B25BF,12A408037A4C1D09,98711F1C09D17B2F,0001BAB1D0C34045,239BD4555DFB16E5,29CD9258C0188B2E,EAF2999DFB5BC5CA,2E8BC53420E8F1BD,A21ED8840B989E29,59D1DAAEC141E8BB,000116946BCF5D37,CCFB8764065A88A8,27AD5CB4A7AE2598,D3F72B00123EC26C,D5A8C6F414E4F9E1,768C9F2471FBFF9E,C797AB4B4DD670E7,0002171F0B63B1B3,28124248F9F0CC87,930A36C7CDF93AAC,2713CB15CB9F5B65,9795FCB9593ECD53,5A81968173104312,CBDF2A7787C4413B,00021AA55C90D506,3579861386661767,089E29943FE92C69,B4C9F05715CF759B,052A2DBE04D2C534,1C21CC5F6BEA945B,D8F9DCD4C410276A,0000D978C22D6196,F8857CB2A32871C2,BE620709DADFDA04,4A31A0A23B983EA4,3AFC03181F8F5D20,4654E6E6531626E6,E0A9C610BE3214CA,000197143183CB73,945704927AFDD154,AB84D3361BDF0EAF,06FEC284F8F4E62B,0AD167EC91382C9D,5554C296649E3650,EE2A89D3D177BC6A,000150FA38DBA3A1,8C517948FEF25C55,D82C64BD25048330,4EBA322462C7C4F6,1E4870A37CADCBF4,0BD7DCE4B88AC802,6C42BDB46F45B479,0001F7ADCC2A1BF0,2A2169CFD0B257F3,7722A890D3C66E5B,FB41CD7BF88D4ED7,59C11FB86D507976,435D6808624369FA,DFD4FAEF4B05CED8,0001DE18501C6911,9FB0085CA40CECC1,0F31E13AEA693D2B,CF532302930C36F5,A6D25D7F805B9479,ECACC3A2E98D2FE3,D4965872C6B0CD01,0000E1D659183215,BDB9F02A9ACBDB25,B414FD6EBAA1F1B4,AC520ADBD3C8EB15,62658A17110E056B,323562582C75246C,24B20EEDB10F775A,0000DDD0001745EE,B3001479C5C92298,2E65A25223DF9F02,F99045FCCFBE6A69,0A7A3B971AFEF0F4,21279C533B5AAA47,D3139B62B185DFB2,0001006F10EDDF51,8D39F991140CED7B,0BBFF58E73F92E14,2D94E7E89EED6ED4,02697E136670F8DA,55ADA9CDDECEC4E6,879597CF7C21BC73,00000F8215B5343E,92E6A9E7D335D4AA,AF201E5743DAA0BE,8133CE2E67545053,6F9CD6D110A6A85D,67DB32ADAC09E2E8,2B463C61D65D5069,00020920C8E0D78A,A9252EB39AFC4763,B80212D95D53CA8D,17E37C3EEA8EDF7B,A44D690377656D08,0C917902BA3DDEBF,74C1FF092CC11A04,0000F49768E5728D,3F7583F381462AA1,A5FCFB09E022BEDC,D4C610E5E65D2927,DD3F607239172677,1EB6DD8659B306E1,E093808DBB825775,0001BB989231F881,EB7A535CFBABA823,ADDF411472F09F26,CFC3E5ABC3AED66E,7022B713403DA916,D4EB45EC696CA7D9,ED34ABF58582B05E,00016421F951045A,749EB1173AB78618,FFD0F46EBB1AB54F,AA5F1E02017FE393,F50ACE2705F5BAB0,94E378C88779F03B,D6E34A4DFBCAAA7C,000032A6689DB280,B9864757BDE796D2,086F3C8694B13CDE,50249BE45567D281,59914EC0803A8571,4C0CD6FFD9599B07,5DDDBA0ACE3815FA,0001AE5ACABF570A,E3E47A3C00456B2F,1C0FA9B1795A885F,2E97AD7FAE487CD3,1405533341A39B13,2D3E3E0694F173DC,9205D498A89C9AEE,0000FA3613095EC7,164EC4313BA687A6,9BF6EDA2B854C7CE,F04E5F505604D052,DAF340220C18421B,7F55A79E61D2B694,960F23265F49E75B,0001AA1A7F89C5E3,79B41DA437094C3B,EC41DD0CB7B24790,5440EC1545AFB9DC,BAE37A44935DCBE3,5588D6C73C94C0AB,4C50A3E7441D328A,00022F307473E48D,2DF8F75CEBA59E31,1EA3900A3AD4506C,E6D0CD89D95A4A70,F62AABF2F05B5AE8,813F477F5F2AD45D,939CF1B7E02E1C3E,00022DEA83D20A41,45B2E12381E04C5F,F699060362201508,00518137BC1CF442,A0CD0164AE681C94,6E238E8DD748C6E2,E3BC6424DD11DAEA,0001A6238D2C0352,23B4115BF866103B,949C8C4AC5DC27DC,5C027D57C217F87B,AFE6FE261356060B,899D78AC636C6F9D,031166C447949FEB,00003BD477CCC316,CE81B9CB9807EC8E,15CE009E86E3141F,D842A4099BB0CC0C,97537737451C456F,195A4431BEB27CC3,11C1370FE3811344,00012316433333A0,F77DED3BFBD3A2FE,05ABE380200643C2,A5BAE91CE62A896C,9C81887EF886DEB8,F496A960B6AE9F57,355D1B4A8CA9434C,00017EEAEF7F3CE4,52D06A6F0CDC9DF3,CF239C4C2C86FAF9,731ACEBF09F4C473,024F614993E34099,534DDAD407218662,81353DA55AAE17BA,0000F7BC52D6E694,D755705E9A3CD20B,C059B49A679FD3C3,59C51EA8B2B435F3,2186226B0BEBEAF7,F8D150B189258872,40E8FB943341D501,00008712151A60C5,7C2182BB14DA3D3E,8D821B9E86073081,9C96ECF5030D6FAE,235A9578EBA02AB3,208ADF29C01DD2F9,91E6EE09FEFC66C4,00004649A6B9722E,83AF09196A1E7423,5C4BBA35FB48DD64,03DE359D51C8A8ED,696450C2776CDBC8,75B821C83ACA302B,D7FCBBC21DA68E81,00016C0CA637CDF6,B14A09FEF9E4D959,EB3AF72B60700669,D28B7BDD89D9B1DA,ED3A1EBEC352C587,870A63D4CF310211,E3250D4233E2474B,0001D27E031F6B4D,D3855A5EC2BF2979,C4F6556F229A3AF3,82DF3795B792615F,84A5F806B8943172,31E0AD5F8D4AC6DA,509AB0EAA6936E4F,000143A71104B627,6669D9EDE9959C07,B69426B4729D9669,26F34A9AC5823890,FE825990708884E6,3510D0ED9C12D892,EC4CF9D43537D3DC,00007FD326879DFC,71F127E3ECEDBB33,30CE5686E78E34B7,22F9F3BF43EEEBF4,FE01F70D7656DBC6,6F667F56BD3A8A11,1983F2AB56C9480A,000123CBF46C92A7,D3E69A579E4AB302,87A42518B96B35C5,5AA6C364E88F7839,FE3E4A8A63ECA1AB,4FF3409B6666625F,DDDD6A57A7B798EF,0002047888C9D5CF,F3C1BA00E18E9CEB,D2C306380B8F0CE0,431C74E5C7658DFA,52D5F5DACBA812D9,5709B37FF60B128A,B71BF659B5D47243,0001E3072392F36F,1C23FC26A5207BC7,8EFD2CEAD0BDC788,11FB717F7B9BA0E8,EAB4966EFFD2496F,5CF6CD6DF19561F0,20DD7B4FED2A4E4B,0000B75B7CD1878A,7C49CC3464E8D162,52772D4CE760B791,71430F8953D98F13,4022EECE27F940F3,48D93CDA62092DBB,F9E1A0AB2E9939A4,00003FC0F9D6E912,C6E0CE9481B4414C,1459170AB018C487,373241BDE50FF0F9,C79AC8CA64B84792,67F093175A960286,70C6BE6A7D66F70F,0001FF7295F98A42,B090C4A68BFBD607,3B460805A6110676,CC802900A89EA9E4,0343B7395A7B2F74,2566199CDB6377CB,18F562ADC41B251C,00017EB0FDE19B91,21890D5A726DBA1E,43ECEA4B269FA3AE,229460F5BB56F121,4B103441B63F1B93,E1054644D8C327AE,00548E7BF4E62BFD,000003FB2BD8ABA2,7366C4A86A718ABF,14F411F0810483CD,096477826238DEB8,6AD6885CD02AEE70,CB6E0D73C2D1935B,05BED15B6698F7B7,0001889F4B3BE926,9DA56CF0BC285780,3CADCC8171429C99,AF71DBE92DB7ED4B,675F61C24E3E0D6B,CA62BBB2ECDFD7FF,82CE3304EEF474EB,0000FA23ED4FA8F5,FBBC4979435DFF4A,4F76F40C7822D922,48E279407D405BF4,9AF51CE384A8D899,C1243850256C8CA8,B69107A38A0EBBF9,00000A41378DB77F,8FBBFA402C299349,FE40D9B3774DA4F9,1A28894BFF01AA60,C7AE522D0965EA57,81E6FE46D237E7B9,065CBFCB843652A4,0000ED540871FA0A,7770DD3F014642ED,720A8A1A2D98B2DC,8DAF6BD65007EAFE,ACAFEB40733F5CF2,3FFAFA1569885790,5B1FB7E98E4F7E58,0001880538CA69CB,401F0247EEE949CB,A248E9020C021420,6B4028C7F2B0DBCD,5D4BDECD085CEBF3,C92EE53C55DC5241,08C0E8386DF06F34,000193EA6381611F,A72DAD79BE848D19,149D45CC5660CE23,339E9455E76BB291,794BE4BC5324D975,F681125D975B485A,CD63C3F95D28CF05,0001F1B271AE4FE7,4A63FA2914DBD44A,A5AB378AF1AFE9BD,7F69F6CC757FEE5C,70509FDCFD3E155C,3F89F47540B63DB0,FE0EF5C97E4DC962,0001A7964A59A472,536C42543E3FCE1E,3F80B0A7B17ED7E3,1C1E9F8F54568C55,48F24896200C5A1D,F91DAF0BF5E9EA1A,91F21EA70E5CD3BE,0000CC064ECDEF07,2761A3C527A983BD,4969848A87DBCC30,35CCAD9718998717,8BB61B788D37AF56,E4734163FB1CDF55,F4826D175971BCC4,0000AD15ABC06346,28BE3D926520C660,30E89364B461B697,A51B89352A123F45,6DF2D63EE11E9F61,D87A4FBB883521F2,D92CC8BACC0EE6CC,000028E0AFC9BA70,C05CF53BDE1A3821,DB6A000D884145D6,CCEC054D29B98A16,90D8F382E04F3F90,5AE261E1F2E872AF,5EB7289657CB752E,000158865EA81D19,C303E77129C4F193,7DE4C21ED307FBAA,DBE986ACD12BD98D,52F33871F70B9E44,EA54A77979CFA437,51533257BB0C08BD,0000510AB2191A59,A24242257400CDB8,C37DC6D3AD3DE897,D159449E5862CAFB,DC007C97CE951BCF,4992909F79E74BA1,38F28CF570F53976,0000239609C64EF0,DE9400815A47BA99,9395969FA6BB5260,1CD251C1417063F1,8BD1A403431BE46B,A6602897C068A8AB,2B81DB11999033EE,00016FC2AE2CA00F,872939526423125C,0CF2639CDF015FB4,CA4D08D90782B2F3,CF6810D3FA08AE65,764AC32951EB3A65,DBDC76B64794853C,0001E0E8C2CF3566,425C256EEDD00206,12B7D3543C5E14D9,DA94D4DC67B0379B,80771BAB08C67B77,697115FC4F6AEF68,E48DBC3D11E407D5,00000C739379DC2D,751D79F2063E4855,0938A92E731E3BFB,A8DE22DF46A23050,231006F05DD5AD51,E11D78FFE002DC85,CB6E932FA0D6F675,00013DA8D7C5AEEA,0B18C77D6228C81D,AA12DD1550F575E5,575898C82459C3BB,E66D0182FA7E8667,2F2B94B8A782C5C5,F5A294C053251D57,0001D0D65F5D6B5E,9938F5881D133145,8771BAE8312D9397,F127E3C49C8B6322,315DFC3190A07B88,B40C4316F21839B5,6DDBBD46E8FA13FA,00020AACFB071B17,9EB8A8C1378997DB,5A77612ABC0EA0FB,FC9ED83F0132A94C,04641F98309467A0,08816E54AA629514,A462B39994197AAE,000134886AB3C74C,AA219A9A06888BBC,C2F0BD84D2BFC00B,A445EADC5CF8D846,41309879A40F466C,445DB80D58A8B771,DA889A121F803ACB,0001089BF141B8CC,098005350FEA28F8,9BCD86A9348CA99B,54337B3F61F17280,0A5A910915924C33,C6196ED99363BC12,B8F24D344681ED8A,0000D9BC20C4C40A,E663262CC51E963C,0430F9E0E2C8BF5C,72D2C615F59EB1FC,6BB3036C9E286FA9,C9CF69D7E75363ED,15C80D2F9510C854,000207D539E4909D,AA1B6E3BBBBEC5EC,FE9CA4E6CEE7CC28,352AC3CDAF6E492D,3ED0BF0CAADB1EC4,448D3BC237EECAF5,47776A6E1126DEA0,00020D05E9FCC55C,23DB7335D0BE66BA,49F3FDECB09EC314,2B662268B178D3F6,344F128D972F15BE,C3F3CCFC8D73E0B5,CBBA733C149B2038,000026B0647D10EA,0FC29AB05E65A2CF,5B88B8305E110F25,86819294E942ED3C,4513B2C3D69299A5,1269BA411EAEE24D,F2748A6F08722312,0000D84A2E5B5A0A,00289FFBF3C88C2A,9A0C19187B7D0084,1FEF60BF3EA13895,4D921671EF51A51C,913B66A2B26D46F1,E9B9E6574850FBFE,0000FFB65B6E802F,59CEC6AA41AA095A,7A44E9459253541F,DE61444C15733D66,336216A9656D2E4E,97521C35EB1C0A57,08B3085A4C2EB0E8,0001A081C85314B7,EEE4E793D11C73DA,A83829407196D12F,66FFD109B6A9021E,4B15EE53B0F990FD,28BD888CB61BEC60,2B023046E8CA4FB8,0001F2E3652C0F0B,DBFEF3C1A9C0536D,7DC89F5D99E75EB2,B727771DA3C5C8C7,E90EBED484266231,B2AD06C7E1833A31,8C359AA868194806,00010BFEB7F82408,8437D60EDF4CBBCD,B65EE6EECFCEEAB8,57C946A2B6F54831,8C6FB113577B9B7B,86FC3B19F967A855,1DBE985264DDDE48,0000DFBAEB8DAB61,23759D32C8E8AA00,4D94BF3E24733487,7C47A52F5E923758,428176DC8B3E56D7,B50AFE3AC641CD5C,EC7B36D7412EF53C,0001EB6A8A973B17,38E65535F08F5A81,F717F4EF93306728,F5BF6232AAEA052D,22DB00EA9E7861F0,0C2750D710B9839E,3AB66C0D0AE3C699,0000561F67BB8357,4F71157227E9B563,3C86295F73822CF0,1C78F11FA5C0B124,6C5A7D3BAE39EE1A,EE1F82FCD1556068,5BA273515A7FB41D,000126AB173C2AA6,D95888CE8BED1E27,11DF92AE9C120C27,6BFE3A368A01141F,F2D4B7FC7B75FFDA,6491F8A79F9F79F7,2A5AE0C3BF492576,00013D96BD19E2E7,DC754BC53BC4873E,532132F2A6DC3BFE,DF38FAFC12EB150E,27EA5456FC5E0FCE,D8284841BBFF819E,AF34BFE1249FE2E9,0000C5ECF7618182,89E4BD12E892492A,4170DF1429714BD0,8753AF416FF63FCE,25662BE57B28D0FB,30E2771F4A2F8406,90BC5DCD44609E72,0000E27FDFB10C66,46EAAEA80FDF1701,FDEF184AA7A5A142,A020266236603511,C775B5EBDDCDDD81,A12773A9C9136C54,6229EEF4753CA7A1,0001644F3D25996B,DFF67C3CE7B4A19D,176AE837541A82DB,E68E29F77E5A178D,CB61942BF27DBCFD,4F4EC5D8E087435F,42CDF8A005AAE61E,000226408EC04748,6F424529C522DF42,093107887E92D282,D332F24DD5C05DC1,15598F9EA18C8EBF,AB9206DAB7E21713,00F72705255410CC,0000CACCE7624409,5DF0C8ABA1514D5B,1117D87D1DF06109,F536DE9522A944DB,B67F2C48DA4C2FAC,041A2F244E0A6C78,12C0AAF7EAE98272,0000640A1C60DD59,DB6D81D6B481DE6C,80371B5B96EC855F,3F326799F8A1DC8A,A2D3041D0B61684F,09BCF894A5FEFCEE,5F1D21CBDC9FA5EB,00016CDBA13D9914,4CAB6CE1DE509963,F4D0A309434373D8,74333F6EF5365E97,8006F59D6813ED11,C62C7573F0DD1B24,B95410DD9FE85C49,0001DB997480AC8A,716A332EE9BB624A,0EE68916A90FE017,D78094794A2231D1,A61108741ACBE9F3,8E3B00C0B1B46E98,28C1F112A5364E63,00007D8F16A9C888,1B7BD2E7280EBD6B,629C0A12625E3131,4E0126A4DF8340B0,3F00345DE018AD1E,84C06FA675D0D386,8838AA6E1781CC12,00002F5BC08E830C,02DF2A926EAA13E7,D075D458EF1FB956,2B3DFF76B5D74570,CDC967503391161C,FD20482587A8A968,10C46B7A3502F168,00007ABA1F63B371,1A1910DCBD513C7A,4BF52754A175D048,C25AFC29BA7F8CCD,268381FC7703A397,192DBC2819D09DA5,3588AD5BCC81EA37,00004E4E8FC2ACF2,249FEBB4C6DE45A7,4CDEA07DDA69E347,F1B03DC0729856B1,761534999DA16708,04E7CD48EFE46EAC,3EF99C44C6066EC9,0000D1087EA9D892,3B545D500E64FA63,16E053D573F84252,7D0A50A3D7BF7DBB,1E2CB23A5633E53A,E49A1ED620682E82,14AF53081ADD6488,00007CAB3F2FFCF7,DC1AD6558F61ABCD,4A3D3C0A9C1E2642,0420EC2D24470F5F,A0A399702B8CABBD,7FB75B34D1B9C858,B3EAF34A37610BF1,00018702D4543726,D7806EBA803D7EBF,FF61A3B112B17580,9C6F092C12F35C88,21EC0E58F2D3799B,4A9736AA7CE97FFB,B0ED5B9A1183D92B,0001FE50B70AEE32,A3E740B1856D927D,4BD9E7CE7C1DE7BD,942A464D16647129,7ADDA87B14245B47,22391D80246DFCB2,1C61B26B70F722FE,0001D4556689B589,18D442599247AE5C,1C2837914D3F2C17,15BC0C10639A1B80,202F51F00837C91E,37C6BD343280060B,C7DBA04DADDAD775,00020BBB0EBD4C17,BA5C7E01B27A11F5,89EC6EC2EA1456D8,58908FCB1E2FFD53,3F79DC3E1F8B24AB,F9E9E3829ADA507D,369AD4026BED0634,000022B1CC8CDEB2,216E7DD00FE0AE8C,9977314F93180873,7913CED29175B539,196D640CA34FE79B,E63C02302EA238B6,339FAF6FA7E30AE0,000110938B53F465,CBA3AC195E1EAD2F,4191E99061B60F09,5F1D344135E993CE,5CE9EDAB31ABDEF0,AE3CEB3A6D39BADE,A36707C24852989E,0001C07964B01F6C,94D63EA742088D30,F53A26717A1B8E9B,365E027D715E2283,8EB225A4384803BE,33CBAD1DBF0457A5,0DC4C231A2C65DF5,00017AF1083ECA42,1A8EE08748320B2C,C2649EEF66E9A9C6,DFF30BCCABFAAA87,C485D9DE730C6DB1,E2768DD349B36772,CDACC659CE4B3E2C,000197CBB96C5ABD,F6F1AC5A77466E1E,00CA6CA46BA94FAB,1FE3414D15249B85,E7A0EAF0BCB89830,1AC6AE138B15B337,274DA36AC062CDF3,00022B9D3EDC167E,25AE848004851A5D,2921F0E9A9019E2F,AC8994D0AAEF607F,4C313A235778ABFD,3CAE2441E16DD57C,777A95A3625D9505,000059756660CE93,0DB79383D5AC0396,0EE1AB3686A2319D,41F4D17B1B8CDFCA,4557E490AD78F041,CBAAD4A18E232D99,4C99275493A3D961,0000346417CF6FC9,42AABDD8E29D7216,373303BFEF76C90C,49B1EC787DB7F957,E03E11D88A222EE8,F30FE08D4BB8AB3A,5442C27AE443F9FA,00004D6A68C7AC04,59E64DE13335B4A7,E3C9289F8A45E2C5,DD9DB69D31EA318B,34C85C4C125BCC52,1CBAEB3A030DB8EB,0457EF38500E833A,000216B61190114A,8F785ABDC50EA12F,D4669C21B7D9B1F0,5D37D3FEF45CC2B8,F223820F707E7EEB,21012AB51778EB07,F4F55F17C8137F4D,0000B9215CB50D18,FA21E9DFABEA0CDB,4B85DB233B6ED45C,10744AE23E0EA544,EAEEE318D6E41853,2A2ACD8287174B73,C3E9EE1102776B0B,0000124E92FDBE5C,51D4E36781905FEE,D3A88FAB635CA0B1,90A1E77B6D0DD01B,DBDCBC5B60138E13,F24C4692415F252B,C8C7ED3180A80B6D,0000B1EA2026D7E4,BA9B6BA8DACD46C2,41A1A1FBA85BE96E,D26697FBC25F278F,67923176A7BBEFCC,6BE613B0F4D6E373,0E0348F4F75F2085,000189700367FFB0,7C232C3A83A0AC84,B193642304772D1D,A230FF80964F50D5,8C34D56E8BA82F71,D62699620414DD4A,4A09ADDCB35D48B5,000060EDE5754776,8A4D075D2AA281E3,F502079CD04E063D,BE05AD9B000C0F91,0EFF61BA693256C8,4D81ED688500AB60,8B7757A4724BE530,0000C11C48764E09,07DF7A3202E7E648,3A6FA85B933072A4,0A23C98FEFA19844,7DFBE15CD4C05017,917E66A5AA47D83A,1C4F07E9F5AA4C2B,0001E64D31BE4A3B,4DDD529DC406C929,2C8F828CBEBA6CD8,3E2A96EDA72569E3,D2B6E7F1062A64A8,4627747DA40B2996,39811ADD781971DA,0000699D8734B373,D0BC6C64DFA7DB5F,07F1F0B768518AAA,D49C1F66308BA34B,D983A3D33DF8C04A,6367124BDC111446,325F7CEDBFA28B5D,00002CA5DF00A871,D53886E3C6CC60CC,C469872C779CAB70,9B330C23A231E01A,34143A30A9847904,602346E355C34E0E,BECE4E9365A30690,0000A5274619BD6C,439837EA2C10B93D,342060EDB5D6FF96,AD86F0BD617B9DAE,F62564CA70CC5349,C1967EE0E35B541C,73212DE74E8BECD9,000004D1FACE8806,856E17246E885014,C950F47DDBBFBB7C,0CEC291EAF34BF38,EDD19A8C5FD000BC,BFC4062ABE9AF6B8,3011ACC1CB679F08,0001A87EC9AC2F95,25C8BC6F48816839,B0B4A7CB45819957,85B17D3EE6A8E59E,8BCDF50B3ACEB60C,25456895EA3144A3,FDD195CC3E6A407D,0000A4EBDAB18ABB,34778158F98459F5,88266D15716099B1,8E1B19E91C2FDA13,D31C92813DD53E03,62251B6F09633768,0D11EF22A210E493,0001F5277526DBB4,AE8D6EF791C8B84B,4A9D128D67FD0E90,E989805D1B7DDC2F,D30A3C4574C90F29,D5D659F0B758CF92,C57EC47DAABA33B7,0000FFEE1F7D2605,651D2B50514051AE,67B6DA2F58382730,F29CE460F7E33A30,393B1904F8C1AF8C,EF72256B15508D97,A67475BE1B517188,000196D859CAAF02,7C63E77C964A56B3,84D37044D65BC722,917183037CB272C6,D6D8291612E4F334,0682825DFC71E150,62EBE91F59544235,00021FDE41D4D209,8368FCFCA9681028,52677464C80E2354,281A7E9CE661D0A5,F50FC20E65E8C044,F45FB144A7CF77AA,04CDD56F6C0675C3,00012BDAA305EF10,A3ECDD2C50FFA39A,DDFA0C574E30DB38,6FA6AFDD2B4ACAA4,5BBAA35A4190AB4F,A9A5E09EC88B7448,74E8D4C68877929A,00010871E0ED83D8,55E1696C2DA8EB9B,4D90865D52E4F7B4,F250C3E547A7CFF4,FA3CC94799F23B40,FBCBC56EFE3B798C,B17FCDF8FA166AE9,0001B5F08D3AFA19,A80AFBA9D96DAF1F,63F171D6F1BF2AF9,97F15F47C71A7240,2EC301BD9A3D1EF5,7A0ACC56E4A1169B,A1F288480BA99164,0000C096D89AA1FE,391130D02782896F,F5E9C2A375D73134,C0B394E1A6E9250F,F08DD0766762D6C2,9DA5CF3E676420EC,62272DDACCA4AD4D,000165EC125589D7,D7BE42722B469ED9,6A775E30AEED627C,26AFCC89AFCA6E23,A3BD7131A776E148,956425D9107EDDC5,066C7E0D52B82A9B,000058325E47E1D4,9239520E039F5D03,92AEBE8A6F8557BE,5406DC66C87ECB64,50B7639129F5F7F1,C5285AD7ED80CF95,985FD10ED4EE67D6,00007C30D705AC71,8464F5EC5966EFC2,DAB2F53E7C55675D,42F0BD3E616F9FAD,08AFFA62649CABED,B68BF472B4AADD6E,8AE27FD49F348C43,00018FFD1D4C2BA5,E93794A203444DE5,6AEB67F58AAD3DD6,36AA9BD2E2AA5D5A,7800DE206253C65D,28E0C19EDB51B037,9D1A2DFBB2789605,00001F21DF684CBF,85426276540FDC70,20F280B18F6256C0,3FA9F082329C0465,19FA2B7C294FD3C2,1B5E031D26EAF208,248BF1385AE8068C,000145051FEF6EB4,3516B361E8599270,924B7AEB6EF9F130,601DD6B17B12268E,8690EA881F300F01,0168F60E27C51BF2,9945D82389A751A4,000002FE09FA749D,2305730213640A1A,3F54AD798C3ABDB9,9736EB3C33F8255B,9FEA5E068586AAE2,242DF0B9D1F37221,78E69A862AFD629D,0001ADC58A8C1071,23539806CC3F9187,B24704238ED2795E,5A96C26F22D6D66F,01CFCD8922600797,8AD321364C22C38B,4BF3C5856AD5D5A6,00019A967B0361B7,36D22BA4C742DD4D,5E5BE2999ADEF0D0,C884DD732764307F,73E7B35DDA2BD8A2,B73002DE32C7C5B5,99C6DC0E49328EE4,0000164822537742,6E5E8A3F93AA9B49,83CAD65F1F46B253,91DA384692717BCC,DBCB006A7079F4E0,AFA3690325C24783,D4126B4BF639C221,0001C5D18751B30D,7802EFC07303A98C,422D538C2D236E03,C5878A7539B24304,148FC4449D1C72E6,D173F4A440CB1FED,94EC67D5906C52A3,00021E59E13F21AC,097DAE280760CD32,4CEFA710C87105DF,109ADFFF06CAD233,B173C46C2E07E67B,DC4083653A6D7B72,891AC377239E42E9,000193046DFA044D,343A08A509A3DA60,75FEA52A4EBD7874,9AB01095A608C1C1,16DE864F072601F7,5FDC3D0603FE9BEA,E48B2A9EF8F4656C,0000B8828AEC0410,5A36426682402891,2250EC7677763075,CDE135D6A1ABF7D8,5BDA5C6827AD885B,91B859311DB47B0D,F31D9BD2B2CF3C6A,00013FFD0D1065A3,62F43EAFE01AE309,0838DD977D995966,26FDD35ADCEBF92C,78C5D50356723ADB,5D8091372C3DFD72,C56BD85D09549CC4,0001A684BDF92EF0,82FC7A208F6B45F6,8A0AA55537AEBE6A,D9653168EE9D8BC6,1120599541F5B5D4,23F6B766EFBF5856,D49B6F39765F0B1D,00016B92278CC407,E2971B961EDA1795,EEE747499EF210DD,6B36D6BACAEC7337,5313456DA72AC818,F8228D984286EE5F,875CE2C1A4DC8202,0001946556748832,CAB1F8E3EDB96CA1,70C02190675DA922,C32732C40B036994,565835F4311A82F9,EF6309E9DE2A6155,EE524F19D704BC1E,00003A1E55EE08FA,3E7AA3CC2A58E438,4ACC2966198978FA,948DC67276056D9C,B61BD93D4E69A1B3,7613D464517E1DC3,4F11FA8F8EE97955,0000280FE6D30D01,0CA053AB56B4E0B2,DB1EDF708036CF05,211FF71D966A18F7,C02AAB0EE8E0E5E2,F5EC4A8BC6A2379F,8E1B18F5BC14406B,00006B7389930FC4,BBAA9B0279B626D0,A914D20DAD377DA8,94F3FCDEA6D30EDD,017869060548F704,B508B4B8CC12F101,472D7C8107231B05,0001BE4D38349BFE,85765798263797A2,9FE987E328A68CBE,988B352D0FDA025B,EF4D8E1E8DC58B3E,C6AD9DDB2356777E,0E7E9D6684375A04,00022B369B6CE6FA,F9ED5BBCBA02A5C2,A45D28D089B3A2FA,C849C8E40A778C19,4299D6E37DA32EC6,A56768CD0B80613F,5E51DF5A70159DC0,0000E2184F1E1070,86E429A3D31F89BC,6BC9548DD05BFDD0,03E33C4645B5E97E,316F8C91EA1A9773,4964EE5D19286B16,769AFFBDF4387104,000040209D163E4D,ED81325E5331F052,76046F8839FB21CC,63BBE61A58E42CD2,8A7469DDA9959AF0,6BBC1DA476BF2693,517205CC593DE6D6,000029F35F787390,5DCFB032FD49911C,9C05D81B01EFB21F,F8FB2D34D347ED52,4606791CF96F6A86,3145C1964FBBD99B,446013C7F1C1044F,00015EBD9AB5117C,79751EBFEE0B20C9,1D097D8647E270FF,90FA155E83911F40,F53ED948F858840E,0D5658C030D07A5F,BA25F4B3409FBFCE,00005BB4B6FD3403,B2951B9FD03B3282,726C46312316808C,E32480D8D251BE77,9CF97B7937FB406F,8E7F062CA86B4D96,2B895FD2F2BDF581,0001B67AE813FF9C,C1C464CB060EEBB1,C3E4C2A14AFA9722,767C13A8BF866241,BB462E990041FB98,FD880A89C9A0F7AB,F5CFCD984629515D,000089D2515D8770,80818F5E94BFB95A,AE2C678DB1A35E59,DED19F766E848324,E4B958769BD51CDF,AF85FD701E029248,E42C99036DBFA18F,0000C9CA68C9B6C8,6B2E20CBCBBC9308,6283932F26AC0AC9,E1A74D286C23DD74,46E4F4D981FB8E98,9A50A1476FD698A1,C637BCD5032DF467,0000B62064BEFC15,3D6DE58E1B29C6DC,C14512DCB68AA4B3,4CA07672C6456DAE,004A0E27D70ABEA6,06D82915ED0017AA,6A760897E15ECE10,00019552716D81A2,FDC7F90F2B8B4843,C1976388F7A495BE,15F99016F3ECA30D,8FA7BAE00B095627,3BE501CD241DCD5A,4220081E0250ACC4,0000E9C9DA727837,20AE68C2BD36AF8A,B6EEEAC958DB6DF2,05BF3D94C9DF2F01,8659E19ED9713B53,D9CC530629A3D05D,04D91CEF28C06920,00002638BBE42C4B,36AB81A830CD0CB8,613CBA6B03134A02,67504987AD59584C,805ACB49BBE5E674,60656AED017ADB83,965471E107AD5676,0000E7D0520F077E,1746E364F22E87AB,EC895655AB7E6F33,2E673CE1198873F6,EBA7C9E632B853EF,2AFD2465AACB386B,25262E1465A604BD,0001331A7EC21394,D89219E20A2B71EC,44D77E528D919FE6,CC55B1A8C3048C1B,9D49AFC8DC093ED2,3167D3FE5875C2E9,FB6F73FB2DE658F5,0001647004B0EC37,4ADF101C6C3A0F78,EB919ABA58FDD709,BC550A539871153C,FEA51B9B6E75B3EF,B7140D27FEDBD669,0194C150FBB6530B,0001337374948891,F343FB797001E6AC,BF42C1AD2D4F50CF,385FD7B63F95CDAC,556CD7D51C8E7AAA,1762C6F700371BFF,AADD5C6DB93F8A1B,0001A270D807158B,8F6E6A551696B3E4,60BAABD4742B3609,AB563EC672762557,034BC93287A0B0FD,8DED227A0601E230,4D22577FEA720DD9,000167241C33A775,51755AD193D39FD5,21A56165EBBDB012,443FE4E06C48B2AA,6A95C46906356A16,A089B2596E3D879C,FCBF0C52BA9CDF56,00002B1C63847F55,986791388B2D803C,489F9BC56D197A83,E225EB1B90B8856A,C07B87CE90D17A0F,22D009EDE830E4DC,A23F57C16E4FFD2D,0000BDA39E607A01,0C556AC2CDB55CE3,509C424AEAC50F4B,D8BAC529C86DA7BF,BD2A5D3D9AB98A10,8C3E8D1EB23B25C2,A6D425DAF53B4B0B,0000117EE8BAF860,61C048D0782A5C11,BC076E1B0803F86A,97FD22A47EAA6A5A,F0C8DD2952BB598D,29D5DEE9A52F3F4B,E2A60B5F8DB6D1BB,00022C946AB3D188,4ADFD8AE9D5CF1E9,49C94AC6260F0F67,B1F822960015166F,E6BD1C806D425B6E,1BE3F67976A954A1,DB99F94A340D0DC6,0001A5C3A29A01BB,528B81BB03DF95B5,E099CB9B2DB45FAE,7E4733DD976D5DD4,57690E11B096EB25,4CE23F9231F86C81,9CDB6726CCE540CD,0000EEBA054D63D3,74620420D03D7BBC,8CEEB35DC3956CD3,F1429C776048E76E,89E53F07511A1DED,DAD538EC833C2F37,2B00B7941ACF26EF,0001FF3F4FDCC28E,686C407846A15653,3B19C90B3982306B,F891093FE02486CA,F8005F82FD57D5F5,BBC97F7518909B86,E9B74A91575852D0,00013127B010996E,E0D045D7A56558D9,8FB79ABBDAE3BAAB,FEE2925FDF51EB6A,82556F251FD948B2,64F33A96B73D60FE,A1748B13E237D097,00020E1F5ED00944,54963CA1C87D00DF,8DBDFA7EE181A0BE,D013073FBD893CC0,1D40ADD6D39FB259,DB17CAF608F7F61B,ABE66AEFF1CBE7AB,00018AE54CA47A84,5643BE2FB7AA3AEF,7385F8CB04506729,1D6D70A6C81A789D,EE47682AE036F897,BD15F59E7B0C5BF0,D75F610AC0488505,0000BAB184AB574E,24C381DEBD8C2630,6B7E7AA849787B58,FF5B86C554980252,44F392D3B964A6BA,C29079FB349861F8,21D6D12C58DFE2B8,00016AB709AB5FC6,E8D68BE1FF4CA0D9,6C99644DB69E03F5,C02B6A8092CBC2D2,19839DE0D7203AC7,47463EFB3D433F12,D7F69E3D5AA8167A,000093A23C4BF596,BF35EC887531830B,6084D9399CAAEA4F,1E359003A710287D,C382AA854E7C2119,262A9CB7E42D1DDE,ECC03BA7DDFB99F4,00007891CEA027EA,E691670CEE253F98,C8C7E2190E4FB3C0,193C772592674869,75A63313572497E2,9E4B76B209C15D1E,AF86678BF304A564,0001842846702D00,5A554B4E8840B9AF,C2162CB8564B95A7,660D04FB8C6D9637,3AC4F1BEF5461FE8,C77C876C7F830FAC,C2E7D20BB71014F6,0001895385E3BCF9,0044BAF4BB0B6A5A,79EE254E9B254A64,2D775AD5954A17F4,B417989334DEAA33,810CC9D7C8195C4D,7CC9AEDB23B5C8BC,0000CB64497575DC,B78F7912AD22C7B0,B1B5C004DAEB9113,78681F3D3DBCF42D,D5B851E8C930F49B,B242B29E8FA04F45,EFE544FE4A9DEDFA,0001D74C1475BE7A,C34603A9F7421143,C01FE788F1E5CF7A,ADCA1ECE161BCE2C,018E321F47893C76,3AD2FA9C6A45BF54,7B91076D5B615A30,00019722966B93FE,5445CB997DE1240D,E4258CFADFC8801A,54A9159BDC551C28,A863D62E4D950705,EDC4298D1B14EF2C,918CE46C74CA5CC3,00004DF10492FB64,0E87998CC9880A06,71D7D14B03FDCFD4,EEC4EB37F0E73D15,93B9498D8D826AA0,9174EB60EEF75EE3,848B9BDB29E5B3A4,0000471F450FFE6E,5550AA78F2F80C32,6C1D576656C7193C,0BDD38BC5C803D8A,E48F2C2B7A4FA9AD,4A3E01F01051F8E6,D390120910155BB7,0000934B63029F9E,5AFD82C3DDFDE7C3,255B05E55CEF8EE2,823E97F36BABEC0B,D01F3D66E4F76896,2EDDFEA550FA73A4,A3D7BB93B6BC20A1,0000298C1B15E8A2,7ACE42ACE5E1D6F4,AF158E0F1B8822AE,430146CAC232D44A,338E1E5CFFA45891,F192F53B51AB8693,690CE90BD5764729,0000B013DC0E526E,5FBC9E46135DE9D7,8EAA3BA687990ED7,52C8C48CF3D98230,F6B4D99FE896733C,DBEA0CA0BF39D323,712BEED21D2B899B,00013473A0501C5F,D11233B641716CE9,ADEE09F168687540,D59349EB979BA0F2,3E5FA588D7677B9D,CF8DCF3D17051300,2E6CD4A663673EF3,00007AEFDDEF4452,4E43957A4A64AEBA,4A5AAC5937FDED21,F330AB9CD918D54C,56A3A25C7831C99D,2FCDF4A3C4314428,B3416CEDED1D7159,00005F5B7FACDEE5,6BDE5D99C4476D33,78487B068BF17F59,B7505EF00D975BE7,2EC65BA455682DAF,CBACEC9A91953AE5,4F4000D030AD2402,0001DE595CA3C437,70E632D36C2E5DAB,5ECE0B5ED735F6D1,8000EA9AB7BC30D1,A2233C0AC507DCB3,56EEBCF09DF9EC04,F4E889FE10BB2072,0000E60A694C55BA,278D829EAA5E5EFA,D8D055605D651F93,3DE547FAD2DA1C8D,653820A6097C9D62,0FEF53265CA6F30F,EDF2E87D96606201,00022D429EA9D3FE,ED150499AB4A8CEF,3B1E1A084E8A2777,F07D3DDE993C489D,5CB7D80952D4B2FA,514353C782B88C8A,BB26998A5E39541A,00011A3003F6F36D,125C82C0CC1466F8,8440E46C39A4711B,809ACC61BDF795CA,376E9CF23BD74FE0,C0B8909BFC916EC4,F2AD7693C9750BA5,000082ACF2FCCAD2,CE18E6B26274D0B0,77DCB6E6B6896CD8,F7758DAB9E5D0191,3C5C2A79FFD1D9B1,459C725B4AA50754,7C8DA150B865F7DE,000004B8CB65EE1C,0213B756291ADADE,36430B12AA6AC27F,CCF798780BF8FAB4,B7D73BE4B4599B59,144634729ADACA2B,E58424C24B3C238B,000082B01250640B,DFE11C265488E035,9D191F2409833F4F,DFABE8F026893956,6C557181388F5704,38BD5EF519519CA2,F103D694CB5E15EB,0000B71C882D6E85,A2A7C95F79A0E84D,7FDAF7801D284040,0FBF40A7BA4B062E,074056BD4486525F,6E924945733CF12B,5BB12FE0B6985394,00022AD88B924E47,CE6C09FA16DA5D1A,306669C50A8B534A,A79F48013365520A,7409E510D9FE9461,12A4F2B8F4D96622,B3CDC9F56EB3E50B,00018F7F361843B2,ABB03CCEA01EAD34,EF6E86737610FC92,BD869738703A9EF0,22300AF0BEFBFA47,4CEE44809E791F31,482C042620596275,000019EB9FE6566D,C58B340745FAA1AD,EBE958C706ABB297,79822FFBB3FD43FC,BC3EADD4E7C078A7,46806F1F8B062B2F,113DCDBBD68FBBAA,00020950B11BB3ED,96522295AB2A15C4,EADC6D3D85EA9B1A,CBE81AAFEF7CA279,8FD2167598747CD3,92FA00B852E1FAA3,DAA3C12B7A7D82FA,0000B4851EA01642,FAD4030A02DB8358,FB1B22F346CA60A1,1907C174C7C5985D,6F23AAACF22A7E25,51FCEB46D5B6BC31,0266F4C0A9846D26,0000DD7B188C8269,0A284270FF527D7B,FE2839849E8A8A18,1B2F3AA0BF63C8D7,EECBE97409A826A1,8E18E359EF5D746B,04753F95F587AC60,0001A5359E5D8EDC,49EDC2DF09B519E3,862834E30A07C006,179FF92A77DBA460,11709811A7BAFC43,066E19F7BB35B153,2CBEDF3BD40E12D1,00012AF4C3A8798E,5288F8B44570A4B1,330F6DFAF2F88BD0,E88912F6AA521BB9,834EBFE2F77AA24D,AE6CD48984D299DD,035221A47391D148,00016B91BAFC08FF,7F98C2B06E6D3C6E,6E04383E6A455706,674F04B88AC3A6A3,A5DB0CFC3094C68F,5662284304BED671,AB932117CCB87B1B,0000A3FF89B9CA28,AA925BC63BFB9FE0,22A918ED40187786,D93E64B4068BF9A9,843E1061CDBC5CDF,3B156A7ED662DD04,1A6311CD687A78CA,0000D25A2DD8870F,5D6074A1B118FF05,29940BBC8C3E163F,DEAE13DD1D305E46,5A09E931F0B0AAA0,471F1C76C123727A,692EADD7985EED94,00001CF14A852671,5E0556B96010BA7C,71B5C5A4EB5ED435,D0D2961A6650DE04,C1831D05ADED5FD3,EA4230D85715E806,0DB9B8C33930C17D,00011105D17CEE16,1C87A68E527A9B7F,65576AC4834D7D84,60761A85ADCD6513,AF8C34B6ACD20AF0,3B6B3456DC6EAFAD,CA6AEE428C02B001,00021C285C2EE760,E30AF3F55E329F3C,AD877CF8F704EBB8,FFB898AF31A9CFAD,3C84DA4BEA778FA3,728A78C802DB3AE6,097EC91250557B43,000206B8F74E04B6,0419AFB3ED9CD8CC,996CC40A709AFE10,B875485C068DC6D6,788622CE1CB020DD,339B2A6D5BB679FB,A2D88B219FB414EA,00006AB6196A50AC,14E917F20EE1E7FA,B9EEB0F594DD25D6,923C2AF220FFDF9C,F53B67B0F7C13B07,1336FDECE0D1587F,982DD64AF2DF6991,00000AF6F242A8C1,1A992FFD09AD8873,B77C649E38E32EEB,D3854CCE074F9213,09CF2FBA1F2A85ED,A7B8D18A70F15C6A,2DB2BF7F14DA3A12,000114E647E2F0A3,7FA1DD90787052E2,B31BB8B534EA0F30,70AFDC7980F706F1,57DFC53F6574972F,A6EFD4C81CA48405,E6C77F4E8EF763A3,0001868DB1CBAC1F,283BED68CC2EF92F,F2DEAEA87D4535B2,EBE8A1DF14CC774F,7A6C469713164DC9,17D2EA726CA19613,6420D2AEDAEBA3F4,000080CBE16950BC,9ECF78E2B879D38E,7AD86D2886045575,668F1F9346192ECF,32F47B2D89DA0D97,D3CBABEE65AFA737,7219F03B7811C7D7,00012D917221B3B4,40230014B979FEC1,147FAD34D54691FC,27B4DE025591D9E3,70E042D8E0CE5DBA,E2DDF4E4C4511825,1B72EE8892FDD85B,0001252FD1BAF6DE,3A32C2DFE5E3FA84,074E05C4EB091D0E,2E46AD48C62B75C2,DD9AA19FE919AA93,D2450C5A19103C56,A772EA9755BFE4D0,0000237E3D18A45E,F56CCA23C09643A0,656F54AF9B0FBDA0,DB195DA9A8091363,A14985C277A2C411,1137D247C9F2231E,4E437096AFB337A7,000070BA92603946,8BC0DB2F5F6F7F50,461E38358C6DEA08,C457D1971CAD9B16,636BDE25D7632C42,F6B6041707E45887,325C679444C986BC,00001AE4AEE1C2A5,8A5CD8EFFE98AA62,908E900A96D71089,0E0A03AE645FA287,284182624CE14734,FD9C6AB6F00FCDD9,6E432A7131734D6F,000153AC0FC90F77,25FA2B41C71ECF3B,E66DEDAF412991D8,D3B9F059766A5EBB,D7386ECBBA6BB4E4,8E462EE4D3655AA4,0E118511ABE2D508,0001CC1F586DB2A0,5F9FC2434A597275,EFF31D164269012B,C85816B23E38B379,23B35AE536558C9A,25220C31100336FC,3C421FB35BF04F64,000225317BCB3EC8,42172BBE449C9CBD,4CACE1E653CCCE7A,3959D261B8B35900,86FA4A7F77276594,73E0112D52E4BC97,16F9EE69A173C71A,0000D2B978404EF7,5BA10687D68AC9CE,200553EB3C04ACF9,5F919628BD562874,4BC300FD1A9D8936,8B370795ABB4DC15,A89CC604D51ECBD2,0000B44851A7AD49,4DE3F37F8D11D013,DD98BD3409657085,FD5175E71B452A49,1440F6660B583E37,599E499F3780F30B,B47BC104402C2C4B,0001CA3D3AA0F379,6791028E18C9F6A5,E027E7EDC5835389,B863150D66862C2A,F2A68BBC2375EB88,51290D42FA785564,6665565B0B9EF245,000125B29769C3E5,7C935FC1524DDE29,2960841CAF0A4A65,4EE8EE790B67448B,13CA68E5F80FF83B,FA7D801E6660BAE7,8C0C755FB8B20C83,000086FDD2D55506,224D8DB9D74648B0,DA6E86FE344B1351,5A33C2B26E270B8D,03C5D59BADB41CE4,591B9E0417240CF9,476D171221E5C762,0001561A00BE3994,AB26F6AB7FCF68FD,2802333B06B32975,6E6F5DB174AD84EB,119EC176EE9EA87C,3AB357A452488655,324E9448E2DD33E7,00012DEBFEDD3F7B,8CC77EEDBBB615DA,E7033A5679C9EE93,AE7DB8FFE9C057FE,7A62B9E280635F33,102A3BA2BA0B4DCF,07E93B124366931F,000037B04F426B3A,96B93F6EBA9E5FEA,7D82CAA8CD242F7A,BCE09442554876C9,07DF8A767A22D8A2,43E69CB9DA7BCA89,3DAE94B1D603DE0D,0000FABE236929C5,1DDBB1D142EFB95A,421041B1348BEDD7,1DFCAE227D2CCE5C,41BA2CCEEAB19370,E50C3EDDEBF90B2C,603115C856828ABE,00010CD286429915,68AD950EBFCC58D5,0AD77B10BF40BB32,F16E1CB44CE63174,B0B69DC74E556F1A,B2453D6508184F7A,43D2912552F22AAB,00011C7C7DF23273,77DD5BE6F03A2809,FEC77197A6B82217,4D93CE8D32EA0103,D116394EAD103C70,71ED0602C52C8C22,40000B28F0FA69E2,0000E1EDCB97D537,6BCA9FE0904054C6,5369891367099502,7A4E1855B1F2027F,628B3156FCB426B6,4092440D04E60DB5,2256BC77254C92CE,0000B6319FA5CB55,2D59D12DF35FFE24,C0909BFBB09ADB6E,9B44AD201DA4B2A3,CEB060E988AD5200,0A0A578F8FCC19A6,2845AD0EE08E1556,000013F188DB8C5F,85C942C4567B2AE5,A97445C1D2041EF9,D1A62270E7CF1866,A433D4F2AC3FC090,6E12B6998A05AACA,5E4E7352FED9C2C6,0000ECF3194EAE5D,C76B573370AAEBEC,1893364350F7F07A,42441E247B49034F,DB54A34DCC8708CD,D24428C36609ACA4,01A678EA9F0CE3E5,000226887175BEA2,FED53D147CCE3243,1750D1F964531435,9A31B1660C87AC5C,AFEC7C35CFDABC08,0E2440EEF01AA589,841791B6F2F28E84,00003624CD473D2E,5374F637CBD3C0B1,2876E7485C1CCE4A,1ED5B78644098364,81350FA25C4F4672,AA01BA589B2855CA,7514E4B410727AE6,00019728B123D69D,16DD253E62BAA341,6765A109E688D072,9A9A649339122FDC,44D532C37B35EC7D,11DA8401C7535203,66EC067874C2803B,000145F350A3C065,17C132ED723680A9,55CCF7E2F3789E44,4087321F028F738B,38121B819CD99B6C,3801E50FC37C3162,701E3CF8C2E646DD,0002192A54406C13,C6A073426751B7A6,F5A1D499CD5973C1,444400F4DE00EE5B,68138ED6058D820C,41561AAB7FB9E346,FC54B7D90BC422F8,000118998046DDC2,0452A872FA3CE71B,A736556A97E93E49,2E34088AC2161A77,7053887349A87949,BABDB643CFDBA59B,7AC06F59443B1C7F,0001B7113372A0ED,542C343A75870AA7,3D9E26609A9BBB97,E9C85F0829FEA694,4693E3059C6786F1,1F2A4347AE4C5111,5EA0FFA39956D872,0000400FF6567448,238B62D66FDFF6AC,DCF56E344E477896,A1908C7B7EDAB10F,043029DC68AFF221,FAE2C100F5A23EDD,A3EF66F9F1AF6982,00009D7223376D9C,81A940ABBD2CCC0C,A5F436916A9B271E,1BD2938C90DB017E,C12D2B2EB59907DF,9555FAF72CEFE318,557094D0C938AE0E,0000321CAB685997,EA40FF1365A2ED51,FA7EE6F8B9CFAF70,7A2C32CF956C6AE1,4898478F5BA598A0,368BC1AC73DBE5FA,8892148805E4F737,00018AF4481EE91E,731CFA44431B63C5,83B99BE24152F9AB,4226672D1AD3963D,10E69C1D559F8937,A7C94A3A35A9D887,4C10F136F3B7826C,00013DB5CBD558AF,6D7FF6970B67E4ED,5FEB8DCBDD0EF1CC,95369D5231F0A349,0E1E63EFFDB1C678,0CFD618CBA5A00D1,A6333DB1544A1676,000008B9FF281877,3A63CF1B6128257E,7C9BED5FB1E5B09A,D54020AB764EAC30,5D0FE69F700F7737,45C4648634414F82,13328C966CCB48D0,000171FCE406F062,E77EA29FB0DBF01D,A4D051DA24B830BD,5F57FC5352E2F5C7,98B1D7BB84050D28,C910610655A305EA,2D94F68066A135E9,00013044DCBEAAD7,94A47DE985935CAC,3EA6E3FA2590430E,7E3E4C1AA59063C5,5E953A286FFE22A2,6E820EB5478CF053,3044BFDF011E81B2,00007D2DCC4B1D3F,196D7710C2DFE012,0386F6FF6BB93205,04DAAAA9CAB34856,24A30A0293C58B22,00A04768DE22A7F8,562972B4DDA65C59,000147CA0C2EFFC7,21A44C81C650A74F,EDB1EA5B483078FF,761C6AEEB844F275,2806D04507E2E743,98F261A2030E1B61,B872B9D1521DC135,00016BC6F516CA9D,CC5250A27D65E586,BFB656F2FD748A5F,00C6AEA72136EE8A,2A632E92F0C622C6,9C4DE770D4AE4A5C,E5D9CF157AAFB9EF,0001635537481978,C1586C91E570E1F5,922D4C0A42C5C493,FA680BF2382A0A53,5324B020BA3A6160,F8226F5AEE850AB8,576DB88147FB5530,0001C559D2FF8B7C,A71C524AB08C853C,4CC5D915E8BED2EF,8D20C00DFB018C36,B9933F53C594BEDD,E008E58513F9CC3E,8CB5C9917C4D71CA,00002AB869C8A3A1,13309A521CD19308,1C31A9B1A82ED6FF,F48A0E00300021E4,AF82FC91233F55CA,F95B5F8D874B28F5,A78E5C81C3942EC0,0002304162D92628,61E064CB56488C61,5A524C29436B4BF5,29D0E60311BA456F,926026441C50625E,645BBD35C82635E0,D84B5D9739D660D6,0001937ABE614994,ED4BAE9D0626D96B,E0974AAB495B2AA3,187A7E80F9547606,EB2EBC6C7E421C6A,31C131940DC8DF12,AE202C753BA2D430,00019F5210A3BF99,AD7479B6E9F403BC,F42D162DDDD0F4EF,FBCD385033B81E50,915C08AD5C3A1356,B30BA748114FBE0A,916177FBF71481AF,00009EEFEA6D2A80,6B63BE0EE18F8200,449285D43C4D9766,D054168C1D5E621A,839B34BE4D557C99,935FECE706E2DD5F,17F278C82AFCB951,0000A65A4C2CDF1B,5E43A85C0F7C390A,CDDBF5FE7F51EF7F,061BA252A7155AC6,49F48E42F0929F03,A4937E538955A8EF,47C7561BF1ACE8C4,0001379D4DDA1A37,28DDC5E5B1BE8CD9,D977930B8A9D69A3,4B539947D1E21E61,C0E929012EC083A4,1246E99EA698AB48,2C0FE020BB025FF6,0001A6CCF90CD84C,D3FF447BF2EBEB47,2D08E2412EA97B79,9928D4A70CCF6674,6B5A7596E467D76C,D9261D4B3D3BE1A4,D3D54B43507BF26A,00008D3E2F059B99,ED46771AAA5C20F1,6435B3755E8C4678,0E7B843FF42E5E6D,0203695794E404F3,C09F581F29A7C4C5,DEFD61C49B5A9DF9,0000E1919E69CE91,6C20C442D1D41B0A,E6E5DADBF4A8FF65,04210B1130F84D80,6B55875C89AD260D,946EFA0DDD01E05E,BEF9FDB2C39B3240,000139EE777A8742,D476C7953B371080,C1E87F961044315D,116A8219F7F941BD,5FACDFF217A62207,9DFB61A1F68105AE,41C0B3232A47F09A,00018CBB20FFB272,7CB6BFC24C5BFC71,4299265991B88000,6334B7E3D1BEA2FA,78B1D27B4BE7BB24,1E177D3B60D1B9A6,FBE5A0CD25485F5F,000098AC3309B2E4,66957F7085D784C9,1E131C75ECF64557,52525655E6B383A2,12305F926A9FA95F,5FE9AADA9B3E8A12,334E6EE43F49330E,0001DDFA46CB89DD,232168DBFBAC7AA8,1AC12BE4D81C4E2D,344AF3F76DB638E5,19ED427ABEBB75D5,8DBAFB3515CF7D7F,4941A5DF96A4E5AD,00014BD76D8C38D0,73B1FDFEAB185580,5A303277AB5CABB3,C627DFA44F6DE310,7B5D59FC787AE0D6,1073A15B9FC61DFA,BDC9FE5AC2928F49,0000A2EC26C4F0D8,2832E6F0C5A798B8,759C0E75D74F194E,0F8ED5AFB7409DBC,5C242FB42B76D122,B17355A53F59BC98,704ADA41B9252AD0,0001576AB3CEEDC0,C8BFDFD936032102,39D43B28538CB8BF,6610917768672BAC,1C190F4F8FFEEEBA,EC3A6021A6A7C5E5,F5CE971974219ADE,0000C6BC19E8518C,652CF9A2917E8EBB,BABC4E43310DAD7B,B411A35F376DED47,3865F6E3C20C92D4,2C9828ED3BF1781E,47193E0CB902EF21,0001196251437001,36B5E1CAFE97C3AB,CBBAA747132CDAB5,B55EFB896F9FF949,91D9A3FBAEA49AB8,E94B424702EC05D0,8A112FD0AD6C63A3,0000EF909B5951C5,1DDB5975C8CB67F5,843CF1269A84F2B5,BF19E1B60B2DB764,38D84BE39B7D599F,46ABB6E16E364005,1A0F00152DC1C827,0001F3E391720401,10935AA2ACEC4242,2D2D0BB85191C580,F26F7AF1F537445D,68C744241A7071D9,D6150E55C70B995D,B89D08F943A0DB1C,0001824C8911BD96,303B5421A72BAABD,41C44BB454EC40FE,5AF1702C0BE7913C,8A07F7A30B097D13,E31E6710344E5700,0DBA503D90F2D94A,0001152B0D40B300,98D410EAA14FECA4,3178AC551FB1FE4E,A474610C1C15DB23,1B9B2DBFCBCB5096,102E532AFB2D3417,B575E86A65C29B47,0001712B5CA05C69,D205ADA7C2CB1DB1,C0B89D176CD9DFDE,E0A984A50E29D8EB,8CE392CD317713C1,62EA5E544855C45F,4F593A6E8CB9FE25,000016B6A4091959,2953DEC3A4D3125F,4C20D2DE7B92129C,F557EC91D3BBA356,18067621E925950C,D9C85C555494868B,13D399D88E4EB881,00018725D9B7880E,8ED7194BFBC6ABAC,424A598BD7CAAEDE,735E84EDCF1E37B5,2C3A12F9ABBD661D,4EB89243E5EC1093,1F6C2E9963507C3F,0000B2983381D5E0,36BAF4E07B880DA6,45E65FD0E7C89AE0,FF1E19972B58F63D,1541A7C129264302,8EA223A6343943F5,3AC72C03DFD50227,00021FCABFCE4966,E74430B741A75FE0,06B2308F529028FD,0AF9F2CD16F89DE8,94A2E99DD5005DB3,F211CF25A89377E9,EE92C2AF115C39C7,0000D3195E44BA6B,45E4AE2CD6EC4555,7FDEB506E470AF1F,3AB133415822E1E2,37EEA8AB95A93433,AA5B4E911DA113B5,37FB104E8E529A46,00002BD73149D902,8F2DB7F3952F2B2A,6424A0835BF5D894,1B868F5A058D0098,B273F3CDCD2D8455,60B240C0239E47D6,972CA065B15B891E,00008D0E8040B34C,5C7446C2851F3DB8,C2300F7AEC3C0200,253B023760B95D46,9A1765F2FAADAE19,E1183E4044DC4375,6FD4D0C618252015,0001E78693A26E6C,8479A8896D115629,53826063F5F9DB5D,90DC79A747BE8015,2FF00EC61F723B13,2522F1A71A175995,07935B3CA6C5B136,0000B8607890F5BB,6DF90155D1C9C65F,52E1C15BA30563AB,78F3D55947BD273D,651AE636591EA668,D125FCABF1B0ACCE,71EAC3DC33CB74E8,00012087461F66D3,D447D646989E2D51,2C342F58429FD77E,B27AB1DCD47607E4,08D844AC941F4F35,C4CCC37C53EC8623,5EB69EB9282498DA,00018A7C49114136,E7A43FB4379803B7,2A878A61749F96D8,3A59540397125FF7,E75BC40960C973AC,FDE112A029BC9F9C,C07871CADDB51D36,0000431765ED8FE7,B544D8F4D5D660E3,0024CAD74CAC839D,105B93489E4FE3A2,FEF3F10AB99D4020,26EA80D98E9B52F3,F6DD5D86222A31DE,0001378643CB750C,82DA997EA84F1D91,0FFCF2C79D6EDC6D,4852C734C3CDF4A6,B479749810A399AD,0F46DB6909C17A59,7AF725B13EF7D9F8,00008C8688D2CA6F,071281B2DFECCCD5,3EC8205599998F45,5B9DCA10E7FBBF45,53254F3B2764FEEF,6255123B0CEEFB33,AEC00A28906D63CB,0001B7FCD983EF52,4435E81D4BA1120B,62C6F28F0109D1A3,52BF81C0C5C4573E,890E1E187E46B1F2,740919A8D33B0D39,5DBEFAF614A9F5CC,000042759EBE57C4,4FA48CA38290ED7F,4A388E53C727FF41,46BE02F21D2344BC,9847AC8D1AF2509B,D170153881BE6A78,70BCBC24C90FD2DA,000118815150265F,11E8C2FC0B9C8B80,B8FEDE65AE73FED8,B561D6DDB6EA595F,D98624018D10896B,F5E9B78F9333801D,705CF3259551ACB2,00011F0BCDAB1CD9,D7264A2006B97204,B462EB7C3816C9B6,35E44BDF97E66095,95453FCE291AC758,E07A611D5F9EFFB3,FCF78A7AC9F3CB0F,0000C856D04E3F64,109B5601C2FA87AE,F3F64F23DE7071AB,4B0B2AECF3BD35E6,EBC23C6CC7819B11,728CABEA9E5BF3D8,2C21D0B3010EF597,0001C6EB2F61312D,75DED298F0C3C9B4,AF18308C77FEE8DC,C9913656CB90D5DF,56C881FCE8ADF79C,389DD1D9558A788A,942C85EF9E11B86E,000177E3331F7ABF,66ED94C65C05E5BA,9772841F820EBA37,B139314B6EEF20F3,C44F22048AA48B8F,EE9E5CDAE4BC70D6,0ADF5FE763CB2F05,00010C90591BDE58,02DE38E0123E87C4,86A1D707EE6645C4,60D114CBA8F5BDCE,DB6D95C77198D31D,E915078310DFB1A2,07E8E4290C17EA0C,0000157004A00B3F,6580E07DA4D75ED0,95985AC65FB45014,DCAAA9C2683331E7,1EDB0D8FEF6FC1E0,E36BCA189ECC498E,576F78F47D310E44,0001B1AA5AF83526,54BC80AF997B8119,CE2C815288E2E680,67A6ADD3A644E8D5,91F8EE65D58F7872,9158C080F53D36E3,DECC564913F84724,00009BD705B6D979,AB079AA5428A3FA0,CD40E2CDD6479C86,7EB5C346D12C3BB6,FFE49701CDFB3747,32EF19EA8F2BF9E4,D4BD8703BEC6CAF8,00012B8983DFB2CE,875531C4AC47FF56,70F472331662FC0C,3059EFB79932C185,45B0EBAD8FB4B345,77C714654DE9C6B4,69290C579DB468C0,0000CFC71A2F63FE,21BCDD60D0CEC4D3,B8FFA3C468A16C5B,E04D0C3003CE1525,942C50A210BC5C43,86BF7157383D8A93,45E58ECBB13993E8,00020C7E9A4695F3,D35140473B462A50,87A5A03110D5252D,3D9B600BD5991FC6,16EC015E2A19A604,F06C9287183793EC,A048B6D50F391483,00010CAC160A2E04,CE33964F4E1A3359,78F3C0DDE777634A,CC4B3C7A5129C6C9,00F2ABF64469E208,BEACB6B640784302,8D1109677E4AA43F,0000A5BF212300BF,9ACC249EB640C76C,3EBE0C766D70EAE4,A0BFA1A122A8E172,9194D2CA621DE3FA,17DF973D154032BA,BF643F4458DF6397,000201E9BC296D29,F4213E561E046273,CB621D8DC4E3A423,DA5DD9AF230ACB7F,977B40A531F20305,0305EFA9A30FEF53,152B61BA53A1A092,000063E48E759548,20C4DD45FE639938,5C20B8DBBCA2554A,4A31A4894BB1FE48,D294366A110735D7,B07B542096B1C2EB,7CEFDCBAC6109C97,0001C5876198141D,5FA2481D3C9CCCE2,CAF73197FAD78873,73C1A61CD4EAAE7D,06E067F1236E50E9,5C27CCC45BA80418,73EE150752AEE0C8,0000EB8CD5CC5AD8,F66255B5A0A655B2,4A526598ED24CBAF,1D1316CD5EA6F2BB,78D89027F4B9AE79,A0FD8471570AA405,5494748A2346B55B,0000CC1542CDF0D6,72C6D1C9B72BEC73,A76DAAB1CFF3B23C,DFED9DC6E424788A,681300CC44A19494,C2137F9EC56E97BA,F3FC4B1CA47B460B,0001AA9A663500AF,B3EE2E13AE32F445,EA892DF7B66C817E,D70C9551CA0DBB83,33FE11DF7710C325,E1CBBEDF8F69F743,D7B20675B43D351F,0001B83F6A61C36D,8BB2214E6EE1AEEA,99E7809D664CC2A0,F6E6FDE31A643987,C12D8730986E4757,AF1D43A364E0EAE6,D966C17BDDED0B09,000122E98FAD7C49,C41C863B4A9EC144,A35AC6F1A6D9DDB3,886902378D091065,005EECC25759C561,7EBB1ED08122C3D9,6CEBA843A5E9C8A5,00020E8D523A39C6,C772FD7208A28A6A,E6BB727AE53FF92B,E3604018A7E422FE,3F2B95F6D129D744,E5D4BAA4A56C9F2F,FCFF330F47C497A7,0000B650AD98F61B,D0364165D325E6C8,874AF22D696405C6,EB60909300D3DCB1,7D6A9F634EAD9D6E,BE7307E2416742FC,D5ED3C1FB9D1A918,00012C075DF06E03,FBECC7B13ADC073D,ABA212BA02CFFE31,9C1AB8A25C6544AB,BADA118846F907AC,43819601A73EBE3A,5AA14EABD3E66AA5,000004D6ED38C155,D65730BB6EB1ABE0,4AEFF39077AC9ACA,03FB87E5E7AF5386,ED9C917C1B708FDA,A6D138A8D211424E,E228D4046A571F95,000218249CD38691,76AAEAED31FAFA6D,3C44AB8D546EDB7E,EEE5620DF418F9A7,917605435180F60B,91E2C74A8AA3F7FF,581A9812CA1411B6,00009F6E201BA99E,95201611B7005355,A0739F034BCBBC21,91DCB77B4A25ABB8,0189525750258620,3562A94BF8790D24,58AC05BD59506521,0000915297A8DA85,5F8B21361D8CF3AB,1CD1D7A18574FB76,0203EB21A7CCBED2,192080E861EA1A2B,27FE8AB207785B17,BD3F335F011BB0B0,0000BC3F9058D866,B7F21F6AF80CC25E,628B7075AFCE92AB,7CBCE0D6113A083B,E0A810DCE1BC40E5,CD22D3C48D3CB256,BA8C6F9E3BEB2C0F,00017D4253484AA4,38B4D4FC69B02D35,8609FE21FAEADF06,F78E9B3F6527010D,F6A38FA87B881B27,1CAF6A398B37F5D1,B334CCB98A6BF9E0,000093CCC461CCA1,B00168F75415D8ED,B890045B17F2C52C,31E52E9C06299EC7,ACE8133D1C5567AB,B9FF0A7D436627F5,E81D10766C55D583,0001E3B1FE42DD69,36C51786C8D0FAC5,CC60F99CA79A80D5,3E806BAF9DB50DDE,7AB388E152B0360E,DEEB2F0693A14746,65F58AAAAF4E5A12,0001EE73895859E5,4C5B9E63E3F423B3,055B0A4F9B5CDC66,7401C97C33897DF1,0C1034D41598C772,622715CF83E1AA1D,ECBE0362FF88BEE6,0001623E1555BC2B,86C60663A9B9D2BA,9385D1AB1EAE6B7E,2109387D39D19133,2210117B6CF10E43,325CA5D13C427B2F,67530F5BCC030CE6,0001B0B270832B6B,A322F4BD3C010E29,77F913BF92290B88,A98BC55E9D1CB0CC,B25539652B5B00CF,5889D32BC56D04E2,D1C8C2862F6CD595,0000CA1DD254EC48,DE0EB2F7EA03F984,28EC4E8EAC4A021C,D240E1317EB35044,AA5D2DFDED1AF388,3A6ED887E4C9021B,589AB5761B3B9F6C,000160A9E06EA929,C56822CB5947F0B1,812D49BBD832B4BE,07C8947614E19D94,1CFA88022A83DAAE,8F4D9F56F08FC4B8,5CED39E98F7CF730,0000FC5BDE2A9695,3E6C70B2830D0A0B,49245C2097BE701E,F17B3EAB81596980,6DC86306082C9338,381512C814751546,42ACD4AE756576BC,00011CDAA2244D4C,8696749D9D56245F,D015A60A8A81FB4B,BE4722A90E7858A2,612D6EE270C92258,E31458EF7A584A97,E9C6396C35376033,00011EFD7798331B,A2FDF9B84BBCF6C0,0D2B7C1F64712F69,FF025FCFF8F8A004,E73B1A7DBB7BBE03,D9C984E2C5727B73,8726986CED04AC66,0001339BEE79CDA3,D2C72A2683C81FC4,400D642263510C79,8EE3938D956C3D35,6FDFA21F49E0E4E0,13F7D35768C7EBE6,DE2602FD8D3B8580,0001018467595250,C6476A8E992AC365,F9A0D13F62B63D77,C9A54C20620E9B38,EC27E11DE5E15CED,DB054CB11B8B84CD,2F4D697873870D5C,000183B713E76727,C4562FCAF43ADEFB,17909CB5769415D8,A56A28F0E06017D6,63F7447A597E57D5,84BEBD120200FABC,6CF91A11345DDC3A,0000B4055D865D55,334D81DFA6504979,9F5B79F451EB604D,9677356DBBEEFF1B,A6313AC1CDD40E6C,863FEEA57CFAD334,4810B22EDC9C1F10,00002BC88B172CEC,5A37AFAE0338A106,BD4A13470B0549AB,267B159F167E5320,36E26FAED799F3B0,A8B1430BB53F8FD6,18B100AD06F56F08,000091E4AC288230,4C60B8B46FDC1C24,D0155121B531CDAC,45260AEF90A0C2A8,0E916F3E79A59B51,6507DE90813DEA77,49FD806F644C313F,0000DFCF98A79A25,11E16D73438E810E,B8D39FBDFF7ECDE4,589A969F38487995,E48F8F4B6FBC318F,B0A61588064AF6FF,ABB970DCF33BC485,0001D5AE925DB90E,0A75DF81AB56D484,CB874D7540E9F703,6801E61A51D086CD,D272E964838B425E,5D7D9F1F700D761C,F27FF0117E02CE3C,00012EA2407F4397,1CB224F7C249B03B,6496E00AFBAABCB9,6E2FB46D507C62BE,452E96C7A9F05EF7,3F5C0D20CED78D70,03C5360AB7C1DF34,000077B3E7F7AA7C,95D54E0AC5E9D51A,FE95A4B3B7FDD177,8BA7F3C7934168E5,2C2FB4C9EF14C0B3,E8DDE3C5C3DE63A2,816F4CAFE4A81D39,00018B1F219F05E0,AFCB18D280FED4C5,66360C3DD1DBB2CA,20E9FB1068BF703A,237F1FAB2B46AB18,A95DCB1727840E5A,2C42AD12F27CC2CB,000225798B1D4413,1FB33ECCF3DC557F,8C5BB92A73755DC7,C37AD58BBC9FBB84,3BA8524CF36E879A,E08C4748150980EF,F8E8855410D28972,0000D40B74BF097B,EB8E4508155206FF,3D81B4EEA552032E,477AE39EE283DD20,83915A8317ECFB0F,E5179B0B11AC57FD,4D3D82D0713586D2,00002AB5BEB53945,0B5CE8C3B6C896D7,A2FF33128EB976B9,04673F7C07C78CE2,23E4AA0754086698,13CBFBA510B2C0BF,A507B2E905250E65,000148D34CAC3526,ADBF5B4D552D704E,EA8D66467E99FD14,BE7468F9963AD156,6A98B07066C615E6,605F16DAF6526563,D1E0F5B6867249D1,0000AFE5BCF9361D,4F44E8FA3D0E136E,770024EC08D4F5D4,A6881151D3139C80,DFC28DEE3A8F434A,A73E6E08DC833B66,504AB7409E9631D1,0000BD3283A2E9C5,1109E7772C0FB3FC,98B6F806C8A812C2,0B8C513833159FA0,28C1D0FF3513CC5A,E61EFC82B18E0AFE,32EA3DA3C9800E48,0001071A3E091DFB,C98DEDA06579065D,4C4412E22D204B0F,1B6F2953EE47BA17,A04A132EF098E9F3,063186073BF2F3FF,047B194885775913,0001A40E2CD9DD4B,0EDC8E967AECD6D8,CAEDD3B99D55D88B,A640481F738B3332,BD79D32CF60A3673,B69F3C753811EADF,68799A6BB64CDA9A,00015AC7FBC73377,F6999109FE3DD190,D331676FE89271B3,77301C178B78C225,0DDFEFE323CDCAAD,42F860A3AE7E4BD9,0574835B9008F454,000066E7A8DB4101,95FD00CFBB18A3C0,06EBBC4A9BEFD101,A24D2DBB4F0B9737,E9A49719B3390DF1,D0FC0ECA1B04403B,D2CF2510EBB3D5B3,0001DC19C3E1CF97,F51AA674E444B08E,D8940C78FDA6A0CF,82B0B8F23706B2AE,10306E552AF16CC4,E331E63E30BA0839,5845B1732F03B9FA,0001A45FEDF358A5,DABA39F82BBFDF90,B6F3037C7384E40A,09169FADF0CF02B4,2D651D1DFD3F1EE4,A33CC492910CC461,603519947E24656B,00007A0DE322FF16,4264A1AB0E3B3401,6BC25B7EE4B65420,B48859C10788CFA9,00C017AF438C7187,BADC90F4AD830521,53405F02883C19C3,000200ABA815668C,F35BB5D33FE3F37E,6A98E4D2FF340488,A3548CF628978EAA,6C6641CD5157AFDA,012A7F0C03F8A3B4,F848C9FA3D4A6407,00013C43973B6367,964E14EC223BEBC6,E737093E3CCBFC99,05E3A1FD9F745566,DC5F47810B7FDDF0,A1C6F55E7CF13997,2F0AE60FEC43E4F5,0001D51DCD8CC0EE,5EC9E76BED3CBF95,FF9D22343058A68C,3B7A23ED50A2A050,E768328432A00DF1,ECEB4931FF91B99C,2155A753F082012E,000078E0D6094421,915E18F9229ED8BF,F70E040B0F82C61C,8E0A49CB431E2220,11896E130B7ED516,ECE549AD68334456,429D48786AA6EBD2,0000819331686F5A,445C7E41C29216C4,63AF4DF5B0517EC8,7B4781ED73E6562C,84B34F64E789F3E2,28124E2E7BD8B64B,147BBEDA27E6F002,0000CBE99D2B4C7C,2EB64DA202255200,800F6709CD003B9E,E9F3FA3503EB17B6,DC87E93F4241767B,A9DE61D676533394,E930DB4525BA3936,00001ABC4DB58DF6,349CD2CAC07EA157,A4AC60479115D169,08A1B09FE1988066,C1E5CDA6D2355E1F,014CF5A0738C2A39,3EC36983EDCE60B5,0000D95C9717B6C5,2CB23C78C6C8B20E,1B97C13D20A2DC02,3F1097605FF1E4E5,287AB8FB34032A67,EFCCD29E6602FBE6,4EBBEEC202540AC5,00001F7AF57D0E2B,E3CBDF342C39F713,214BC6B6D8175D52,743C42DCD22F27E0,C740970A81D6D648,A164CD2A5E8FD4C6,2E7D49A3A773A8D2,000165D7AC373523,D9918F1EB82903E7,B4455FE71C8A48A0,26D2FC4FFDA7F7D9,D252E168B903B7D5,1A65B8A6052DD106,F90618128C8C001F,00001F094AFB9B88,E3A536A5EAD3CC23,DEC985C6B5507E45,484A45F2713D1154,0BD3EC6BD1D5E251,8C06D8377C33A88B,7C20778EDBD50ABC,0001D9FF7EF6E00C,64F8711EB4882EA1,A50646FEB3C1F8EE,7CA2A45EDC464890,55B68118DF560BDE,AEA6BEFA5AE54B29,2578B727BF635403,0001546EF6E33972,0B577EDC434AEED3,73C617F4AFE92155,0D320E15386D8E49,2F8C5C1A71A31B23,8108051D9B3DC8B4,CE0C56B4EB153DDC,000019B02991C16D,BE7F3E473932C857,4ECED925BBEC4CEF,16415C4EA667D13B,CB2F3A17E8AA183F,D53FD63520A7560C,409B80A00015E7A1,000090C6B872B1FD,B12FAB1CC8BD6956,1E12CD3D60304A4B,FA4A62056891DDBC,E5D90D56599B024E,C99EC12627666AAE,8C48117643B3B4E5,0001241DE9495D39,7373EF2243026713,2A58AE967C478B43,52AF43866EFB958B,614EFFCBD209E129,FC0CD3C94D37AB81,42CB0E8CE2560C45,00005AFD99F6DA15,15867A0CCC9600D4,B7817D3497535AFF,D02B953842C0C34A,F0FB3034697C1448,C3451A444B21E3B7,0C86198A480035BB,0001B418AD6EDE22,5616F3E70B14A037,03127A4C7F49F83D,AF260EFDBBD96C5E,53E0D5A25207E127,92F3389288FE7427,79CAB0A255526A53,0000F731586A7866,1486584830984B32,D6339C6C031A0F4D,BD63FE3097790135,31E7A29F95B7A2E4,7A8189F6712C7B28,2CE48127EBFEC292,0000C51E647EB4EF,25F6550A1FCC5309,51A7FF770839202A,64B088D7353643E9,E2698062E484C224,24EEED6C923DAEE2,F09E2098C08C127C,0000CA65A4DF01BA,DE7D12A86193981A,19FD1025896BDE85,37E2E3D97C73A418,27254C6DA776561B,F6043F5807CE494B,D364B1096E429312,0001963389D9B628,F95E2D57A39D66E1,ACFC651CBDD51D38,46BA9DC6B63B38E0,83AD9AB81E7882CF,7FB21C0299C43A23,D5247CA54431A6AE,0000E3F391061C2D,BAB413A314433E7A,5291F28CDB6F5058,B606406C441FB846,1AA73DBB1C76D2C8,04B89B0E0F871563,0ED48E26869033AA,00019325A83F5029,D99C2DEAC3C59186,85011233DC6C9F19,3B13106DB355796B,37CB27C37A974FA2,3AC877157DC08571,C574BDF25E7EACD2,00014F061DDFD7BC,38A400E2D6CDD587,F9E6866B465E4AAE,AF608750DA74E94A,659B2590D79C9319,344E3BC798C8E10D,3164EBC36340CC8D,00016E60C57645D0,0CF7E77DB2F3BD11,F76D0E732171A832,D3AC8EF529FDB085,F018F01D437C1832,0E4619F61A648B62,4AD870B06CE5CD87,0000021AFB2AABC1,540D449D72F7532F,A7C452959BA45253,346565EC20ACE7EE,3E50CFD43BAA6CF6,DA778553E67FFBA4,6387B68644F97550,000213D594C97C31,862EF03D04CC57F5,8610D971970F11D4,42BAD9F162A36CC5,C73B0826D1B7E9BE,26E4C014E23FE81E,232005EDD9C66177,000108E717AC9F67,3C59A7134F96BB53,A4500CCFB1B99424,FE0505032F7C8CCE,784A871B20B312D8,8CA3043F072C674F,9851979373D38C0E,00013F742F0694DF,D14A5B59B5E79A19,9DEEBA111998137D,B45CA6F16019F35D,D1BCB40D3209C177,C4935E839DFA6A62,81908917827A6D71,0001CDD97028EE48,38E909FAE1B2E5A7,381E567D1C60B238,554816EC4779C24F,A9B2E466322944EE,2207550514AC2857,D47ACE47FA670DB0,000028C6BB29AB60,A762943FE0627F39,486DA780B118A213,5A487F09F6600866,09B6EEE250F20A37,5713B2704F9C2662,6214A52157A2130D,0000B907CD5C418C,CD146219DB2049F5,175EEBD26DDB199D,59D00C7DCD940A5B,EB0B90F1BD008968,54FB81076C04B7C0,7832F55A202414D9,0001826091CF68B2,5877397D07C17F86,7861E131F6B5585B,23341D74B9997285,25FA0CF32237348A,0A8535A8694CC602,2FA5D5E50DA9225B,000147C4C2EB8C5F,B9AAB619656D5D7D,12FB3E78770054A5,1ADC6EA483AF816F,E58CD950D458DA43,FE04DAD28952A7CF,5D0D175C3BB228F1,00001F44F4DCDB05,8FB56C06B8E475F6,F4CE48AE5301B09F,6EB3ECD9DCA5B3DA,EF63E064C9E90B07,7AF57E229867C358,3B02B0A627B088F3,0001917A87B78B7D,2A48566827F869BD,BB6EFD6A57FD36F5,A0E32800AEE9E67C,F68D15A9CCB0AFC2,EE0F3543C455B424,AF079AD8A43253DC,00020DD705B29D17,E3CEFF5021E19EAE,078CD2B4488368B5,09A34AB477C2B9AE,C0454686234B295C,06A1272C98FDE0AB,00CE6B82286A4A14,000096CF68075AFA,9A64109491A64E29,7D01391CFFEC9887,CDC4F46F3181A8FE,6AC0C9BF3F2C8D28,DC919F986C975CAF,03B64379F3629DDC,000121E55BB762DC,88B028B338AC60AB,B212354B0D3A3747,31FD8AC92D6C45EE,D43FE0A6FBF56CF0,BD88E8D30C77F4F9,554A56760AA8FDA8,0001A1ED2D6A0942,335E03D3A84F0B63,EEFC6511D46E5583,99CF8BED2ECA0EA7,2E6FE12BDFB0B24B,AE104B7B6D4F96AE,8A05D39EEA0BFB98,00010C809D0500F6,9B01D4350F62F8A0,4B1F2D102DDDE1A0,FB8B2AE29DBC82E4,0BC296874E07A392,02F9EEB92D0053A7,7A990B71CF8B3438,00013E747A9347DC,7E272009C8A74C7E,80D211834CC68FFE,3095165DB2B0CEF9,8EEF1E5462EEA8B6,4A4D6CF3AD460C93,F60D72A07BF4E4EA,0001B76F1F49D0DE,7161D76F8BEC4DB5,0D45AEBBDAF342DC,E0E775E400021688,895D329D491A899C,260E24B1A22D0BF2,1B31976AB20FFDD6,0000D1AC0D02D453,16A365C5D98362B5,F8C1E9F6FB674267,98944493FE2EE1C6,9EE3A96FBCAFB762,5D89DB2385E31EE7,A467904332A1D1C2,00011D9121E4FBD6,A680534EFDAA4083,60C218CC1E628D7C,A18D738444B069AD,B225B739D976CDA5,1D36C052151B19A4,71E0F783E5EF3EC7,0001659978BF6724,69674A5973A6C105,CCDEBA64E574522C,92FF3FC117D15EE2,BD504174998ADF46,5A314F759D0A4922,BDD61B6635C7BEDE,00010C7BF7113E83,9A8C22C55E3338A2,55E655976E52D4FE,993AF411A0C1FFB1,A358E0AB0E103D52,8211A5C15EE7E883,BFF75992794CFDD1,00012AA6A952CF5C,20B9DD64A1AEF7B8,4813ADB8B8B7C99C,47744892224C6064,657B0A06B28A3EE1,02681D07C0D68021,1AC0B216B784369D,0000945F40618FAD,E397ADDD5D249944,7D5E16BFBB08F2AE,C9074DAAEEE8E8F6,401A30EE54794EF2,5C41249F5C44714B,62FFC905D1426535,0000CD3E51C189AC,BF33D5515CF45BC5,BD8589D2646400C3,F3D97FC7FA3D9F8A,BF6DD53764C3191F,144C55F7809C3AF6,F2A0CEB48FA2D1A2,0000ADEB2A40854F,5FD15C7ABF0CA369,CDE0A7F781E7FB0E,AF3FC8B99154653E,D60B5C342034D9A3,680A248AE9D8A4A3,C8A118D6C6D84EA8,0001DE324D75D812,19A7827B4DC3683E,40FEFA2DD627ABF6,43725E127C077C00,BF8EC60AAACCB871,A6C49A2B3892420F,A3DBBB5F335DE1CC,0000C13EE473B452,D3657C4CDD9BD50F,855C21FF0D94E3AD,BDE4B85BFAFCBEB6,878DB926C6F646ED,44B11C0215458D64,AEC21594277C0A33,000049EF078FA981,A64C72455EAA0EED,8DDC9695FA3D6F9F,54DBA249262C2552,41EA9B230FB4A911,78C8A0EAB6C907BC,C2E7DE9D794118BF,00014479D8C514D9,E77AFA67C8549FFF,65B9F37FDB632B41,3DE3CC42A5936526,0B5926D123595678,4213EC8E431905A1,B3B5BC8982636CC8,00021D86EA4A3CC5,28F9B8C57C8D923A,BB94124DBF520AF6,727536EDA1405F12,37BFB99B0A86B339,19000D1B37CD8EB7,E75907105CDDB38E,00006887A6E4ED50,C859196EAB3F1ECF,39D52D7B905072C2,1F5E227F638AE19F,F54960D26433360A,5705D760602EAB52,6FE9B9A5E4D65AD3,00007B236BA152B4,8EEB7F0F89B633F4,4139930A5508F7DF,EBDFAA5111929256,7E20C5B275B7D44E,8091D0F2A5B4A430,1CB9134431665D3C,0001C0077C6493E9,361DF375ADE52B73,1749E2C27D86396D,0468D6C32F50C691,60915B5A6E1A147F,CD03AD0854484579,126B55D0C0CCBC29,00010484321BDC7A,56ED45A25DA99AE0,2A950F8F650A340F,456F735B8F12A828,7047200BA3B925F0,5EB5BF25C3D6D251,CBE75E10A6B725F4,0002274B72826757,BC72428CF2C28CEF,85B51D486933FD78,379A101C3AEABEF6,0720629AB355375A,3B974C4F2CBDBAAC,65E0670708E0AB13,0000E6389545D329,3F9F690A4323E243,43C39E4E9F99A97D,D90E32C3AF21B681,6FBB2977C0889201,99A67CE268F02B7D,81BFFD34E58A5398,0001A84031226D1E,7291FD44DABDD77E,041BC597BA83106D,72BCC2C324C3676E,68ABD28D7EC70478,4C3D982A5875B92C,7B0A9E401505E06F,0001428811D593B4,134DBFDBECA8A23D,9DF10C90E48DEB2C,C619DBBA7E690C53,1A3732E288FA8CBA,5FB2E6B8DE89C297,FCB3ED3B25090A25,000009FEA37288DB,19F58D8E34B21676,8BE6E4B0D074C147,B6B2F109381FDC1E,C376DB9F085911E8,1538EF498E716CBC,1E9ABE675232ACD2,0002174533DCDA6D,ECE04E05686BA11C,28A08C2B58B6D8E0,7C163D7ADDEE27C0,5F8BBC95BD2A487A,D8419D167E2BF0AA,76A2A7ABE9500F31,00003217206EC109,CF4129243153E322,18F3F39861A7DE43,28BE2F645BFA44B9,32A4ED80DE323F2E,DFC8C56659138136,EDE2C57BAC62CA08,0000EDAA6E6874F6,9010EEF6601C0D84,A9E8D6FBDA096B2A,6D565B4C5CB2CD04,146303C7652AC052,6F18332530DF50BD,EB37EC9CE041C601,00013033867B028D,FBA0CCD8435A3230,111D41210311C3D7,B0C8E0A091175181,E73637556A7AA39D,6C644310A766D2A8,971E03340838F049,0000FC65161F478A,3F72D119C3DA9D89,E6BCFF0609E9D0D4,3A0CCFFD4D3E2C38,C5D87D124BE137E4,F4858813199716C6,2B89B4B581AE98B2,0001A8051A6E556D,98495CF6914AB669,8237618FAA2554EC,80BA7784257EC3E6,454ADCBDA48BA825,4E30937D88434A5B,CEB301F342CBE9D7,000082E493E42FD6,33169BAD6F28CADC,3A71592810E28181,C8BC913B94616610,89D99A6FC00309D8,0291F61A1B006D2C,545681BDB86619BC,0001C314B319392A,22EBDA0B21AA34DC,9CCE12F604475AA5,EDAA17770B519E87,DB56A3529747FBDB,A834914531468D12,68CF358A32C173F9,0000D041CA2B056C,4C9651D70BE03C9E,EE535EFACD1E221D,7427BA3D9E09A1C2,259CAB8E34878379,8CCA558AF14CB7C7,8F42369112460039,0000B8E3F39122C9,33B153D0A14F05A2,F6798CB9D7A2ACF7,F6C45769D477A192,C38C19528D6A3D25,FB4325181229C158,8BCD3FB3100DCE72,0001B12D926B628A,E7472CC7033E9123,75C617B4E769CDCD,FCD2F9E87EB53EA7,D6FB5F9BF2828F16,7618FFD5F3A3D97F,1C18BAC1B2F1D137,0000FE075FD382EB,8677F5A8EC790E9E,5D432DFF074B0447,A6BC5ADB711D7915,EC61BFF6FAC5591D,F5DD9946E03D2E6D,A1F053F0ECF4BC3F,00010C2961FC5968,EF3B8FBCB45954D8,995660BE986A42E1,AC15EA0A5590A49B,88764662FF717AB0,EED9EDA0E2260317,145743178E97D50D,0001D6076DC52D0D,4FBB014CAF62CF24,B2271C7C719E11C1,63EF14EC25712162,F7B12076E43FC335,2A976C570916B43E,A19AA819D13A8EC1,0000BA7E7F3419C9,830191D0CA83D9F2,20EF009A735F96C2,94BF72B085C3F26B,3FB18BFB9E00C513,A01748D6384AFA14,39F95E01B58A877A,0002155C4A848735,40C03CB18B999739,E8158D431E441DCD,46F114B8B569C4EA,161E49C8A72F059C,7A59CD724332A06B,C7ED1F25D455566A,0000C7FFBD845C19,49CD9AC234D7CCED,1EB051D740185818,320E342CE16EFA80,84B88F72A22B0665,4D083A7C64C21743,779D461FFC9CB160,00005A7960E1EBFD,DEAB389413620713,E624EF15CB91C6E2,37AE648C159C59B9,A928E481A44B3F86,34F21A845EEC8E03,1A1E250472B6B556,00017CAADFEFC97C,CEA88349E9DE9739,3CB29CC360B86BCA,C660EE89873D6145,F757046D85302339,AB3AE62C015C6855,471929413C8BE2A1,0000641CA2DF88A6,5C9EAC02E2BB4F7C,0CA03840B56EA2E1,236DC0F9F08C67C0,30743FC1C7E5074B,FE0608311BDBF688,355AE78A6B3C42D3,000120CA1AD4E121,DAD5ABD7CB21991B,5522C999EE2181FD,A0E4FCCF9838AC7E,E7B141F499755C3E,E0E88CB1674B5B01,69117AE83CEA2E8A,0000D008534D6303,0B4682EB2CBAE5BB,044A171546182D22,13A5985BFC1B6DDD,B1C77D86CF1FBFF9,5A854232D6243CC8,0995F831A31937E9,0002193179E53322,C0E6DB982373311F,084F32FDF9F11502,EB4A2E9921A64DB8,1B964474E19A59C5,62708E5AB18B123B,83295BDF9D75C3B0,00005369B6D3090A,6D58C9CA5A185826,B39351B00D2CE155,9BF4662D80F6775C,162623EB9CC08914,2B2128E810FE4C50,9A8E08CE6CFD9488,000079D972DAC7E1,34747022A39EC00D,BB4C7C4882E91D97,730CFABB25B94BF4,93C1E307393E83BD,FE19F95BB15EB275,A7BCB1FCEB57E1A7,00016A34F457CD95,7DCDC0CAF9C2BF6A,CAC7C9B17E0EB6AA,71DA6D47A78AC328,93ED151A41939C64,920602DBB7066D7A,DA1F86E49CAF8A45,00021D2AF7752B7F,87F2D48955514871,10B14780258AC7C8,BBD4952DF93272B1,ECA28C58DC5485E9,576C088CB8334152,F888D74F1A92E392,0000F982ABEA1064,FF86C14CB565F954,1C46FB0D154B4EE4,AF645DDBDA8C6398,D0023820290CCD67,A59A71FF8BD67952,E8305E7577500554,0001F7C3C9D129D9,D5BB1709DFF9FB59,3CF57FBC6D9B95DA,B298CCD6830A90E5,F5AD6240C318E482,88DDD64B872047C7,AAAA99444E5A82AB,00017A98E532FBE8,6FC6372D72DB01A0,42512A5D1F7DDA78,86F3C6CC06750CE9,A95B5002F12DBBC6,264A2C4FFFF72773,14ABAA77B92AC446,000092EE2B5FA5DE,E384A9ADDBDC8947,EAA5F4E7437C1522,87B6EE37F725FF94,BEFB152ADCEF0E9F,09A46A15DE55724F,6817E89E00D0D9C1,0001B3D3C1D31FCF,B1778103BA8141DD,D8DCCDCBB0E10B6E,4957DDF2BC71093E,73578C818F2098CC,1D4A8E2EC75A8588,93004B0C9FF9A6EE,000051432B7E861E,E5A0A1A14E736EA5,D1548FD4EED7950B,9B51751506CF70CE,D98435D59255A372,DB26B65E688298EC,E47573969F1350DD,0000C2DC5BE5FC03,6EE9E49AD5ACAC20,98C0F0BD148C1504,BCD5F16B340E6727,010DD2E190A1AAAF,57D0A8633AC94F3D,E792A0F2FF0AB8D3,00017D62F3203935,0CEB7C843E1E7AFA,70B76805B874B32F,B61C29C5235E71CE,2AAAA7525ECE8080,3F1C6AF29E235849,A82ACEA8FFB69875,0000A14107CB10D5,CA39C94DF440C665,4BF97D4D9131FAA5,9017F1C4B409DA59,71CF256B868BB79F,9A7B8261B6459576,4FBBD5A93593133A,00002102B34B3D24,F00AEF350039D2FB,8D4F01831D914410,292EA2126ADEF121,35DCBF8CF5F0A433,67338778B46BCCB0,50B3D4AA3386AC1C,00003518EAEAA4D3,9D90DA923D122AA9,0DA6E1288C0DB1F2,8D44D5B1C6369545,FACADFDE554426EF,0E91A260D0C810BB,148B8A31950FDD88,000096AEE0766895,FD9172D0AB456F98,A2E7A2DD25224393,9249C65279610539,7FFF1C809F0A395F,EA24484F48F9502C,04F37C7A8FF7E59F,00014041921A4259,C9B80367C4F9BC41,EC221A6DE4E2AA5A,9874A04272C952C9,F25AEFF667A9DA48,5CD16E9D0D6C3B30,0E307FF8C757B726,00000A07F2BB930C,C2C7D7DB42D4E35C,6831DEA00BEA906D,F1972B0B1B95FEE5,340D60C14FDE4434,23161CF7FB53F10D,5F83324EB5FEE38E,00003AEB3384E9A0,205BF5E1D01C2F64,BCDF65CAF5666AC0,462E5E85DE28CE61,F4BC578D3A6BB9F9,E8D9B3AD7474C53A,5B8D49F5AAD392CB,00018E4B09E124BA,EF25C97FF51F3A62,2577DC6B020FFC1E,744F55983FE8E346,07A63DF17ECF6CF8,CCDC763CD26146F5,C471CC32DE906BD2,000225ED685EC9E2,7421D058AC7D2220,BC8992B1F58C4B72,90E1F967281025CC,7C867141220A1A02,E4C31003C23B1D91,40BE0113AB833129,0000E532E89CBC00,5AB1471A2E5EEFFA,B559E403E9011070,BCFDE4E620886765,454A1AF7C2F0BA52,E7E6171A4DE5E2E5,4DBD77E72E8E0737,0000447CF92D4892,BB61C03A2757760B,E0ABC84AE56A9F7B,0D89E2334734408B,C135DE9C48F9B2C5,33296DD9165AB6F4,C661CB9FB1D28DDC,0000D3A1CB03836B,CECE3CB3AD8F4747,6FBE8942DE44F934,4C913B2499235245,A50C3BC53BD95B6E,A955339216B2A0E6,1A99C1BD757A6D86,0001CA72D5586936,D4D1B12363BE4D51,552FCD74E342461D,D820FA1DD8037BC5,194E362595C5AE8B,D5B504C7E46C29EB,0F3B5A7E2082CE03,0000EDFDE0C92D0F,D79C7F75C04FD59F,76B6946C8CC2E920,CDCC45DD0C650DB3,952A6A18E05D1C53,05165330F22BE6EC,1011B88C0E8B0896,0001D38A69628F43,ACF16BDF5C30539D,87B0EA08B7823C54,D0E725FB113F852E,CC3AF005823BB87D,393CD91F62E68700,E31D2A515634A676,0000BAECB314D06C,523A215F16204966,595E201A8749CC27,10B8FF2A6BB221C5,B1ADBFAB8BF9D413,718AEE5191498513,29B01E970C06B8A2,00003C332116D61D,027A8A9594DE0F58,CA960B3C06FDFDD4,A02B1283F46E00E6,E3BF8B4E7676FB7E,11B9737503EE84AD,C3EAEB2F6E1515AB,0001C8A0DB5D41BE,9295530DBAF3D8E5,90325DC5A0AE629B,ABA90A925136AE80,87F46357F54D9C73,90E474CE183BB014,F937D341E6022FE3,0001E58B7113FBFA,67C93C38DE354A5B,999D84156DCD8796,88C85619FCE161D2,E88DB0B5749A5B30,FB3AC5D8006224F9,2404810D81F068CB,0001CB0D4BA98E26,7F66E1755045A0DC,0D4198C361E9ED5B,F44AA277690B8A71,F3DC5B683DE8E854,592771F75BBF2DF6,ADD2311BBBB0FC1A,0000E76DB8CE11CD,1D84F50443FDDB56,0B18B72DF571AF5E,5BCEF3C9D00424BE,771D8857E619C19E,98320E7BAFF0C5F5,4F2166BEDBB30443,0001D830CE1C6DB7,108EDC760FDB446E,A7AAA4979978C8B5,A28279203E30484D,F810F5C8F3CEC86E,2CC66BD3F8BB23D0,7F9D4587381E5A74,0001E4CF7EFBE302,DE2A873C0D7635FC,745262516BF50C2A,EED570958B8B3432,E135D5C68B80007F,A3336407D1BEE140,47BF95A9297E4E16,00017DE2564D3EDB,4300C2E7FBC7F047,3C9809B85C4E1417,809ED788EBFDD244,2E8A7BC30AEF1E17,22F7BE2F92CE3957,D9F14433D5428C4F,0001D1480DE5CD02,2211D15F8E262331,BC78BD1CA3153A7F,3D431742689C7926,9880A8E1336AA5EF,6D19C5B42E302B48,5CFD361762089D64,000027ED3F6E656E,9FD607AB7F5BFB8B,601D1E8F28061F97,9D98562D23CE58F2,867F1AFF9E856FAD,B32AE445CE79EE33,28A8152261DF92C0,00021322D6719C7C,A7D064F19A3B766C,6C70FFF87FC880EF,64A71182A8173CC9,DC01420CBCE0F083,1CE34E007DF3E10E,A27CDA41DCB50501,0000788394289850,321A468385F3C4CB,2E8B87337E5B2DF4,055CE68D7346011D,211C4F75F283503D,760E7474AA7D4D65,4A0E0253F940ED40,0000A916FD5EE6AD,50110D646390C270,86E8D3951EC20D9C,B6FD16E075C5BD48,5F07F24970C115A1,CEFBAF35044B271C,3FA8653FA6D2C397,000021FB7CF70963,AD63406878A34C94,A450503F2F889C83,B6F2A238CAD9FF55,05023DDF6E6251AD,BDB4345F05DE7BC3,2B5CE771D30634FD,000128240CBCB559,2CE714EDC3BDF356,217E6C473EB94A0F,57920D655C05E18C,BB126101B6C25A13,E30A2B768E1C6796,EE3FA706678A73D6,0000C3FD63D644FA,B735C051475DB5A5,3BF1095B6D64E1C6,AA49CC37E57D16EE,026C0E20CD9F6600,35B1C16E1F053607,230EFF870D31C882,000067D73F288421,25ADCA312A6EAE9C,E3E1C51C5694C8E0,FE82EF9822A4B866,27BD4C7D0BB97C92,BAFC69C4A8C421A6,53F5C5C0CA06323B,0000E1F46E647D51,05A2BF604D8C1763,F2B50258CF506E30,6EA0D11B05D949C3,8314B9C8331B9A16,531F09DFA1D95CED,15379B7AD194C054,0001372AC736D509,3BACD1724318472E,8DBE4C45864051CE,3281343E3E81F7BE,69515F477DC165A9,21DB1C63E82703C7,567227C494402924,000194E16265B465,FB088C7573C04246,D9D2BB685BA4D2A6,E9F226E6A4EC0009,F1E0A5436D1514E1,2F3C22902F310CCE,2CD76D2984306B2A,0000A404531E770E,E7572FDD04B018E0,CE009909ABBD420F,82E5E15477934400,21DC976085B80962,F8542C3F9344F4CB,6D6F2EC047746A4E,0000CA2CE1C26D48,A5D6195D7BCB4C0E,7DD8EADA8BE3D256,3C1B81966558900F,3EEF54ADA4962011,76F07142D675804F,DEF95C79D5787504,0000072EB27BD775,C18A3DDDE53E66E8,61B300BB1D994D8F,0C7320432EEE78FA,B727166634FAB1E9,889A27FB7D155BA8,A5D21E1C141244FA,00013299C740CC26,0DC9EC3CA3562323,8F093AE1772A81FB,C45E9E3A45EEF070,C231FCFF6FD14E9F,C36CE3ADCB07F4AD,18D79D4E8872C8BB,0001BE584D130CE2,5B38B7ACFFF69FDB,DE8175476D96A43D,35AC0492BE5961C0,98AE41101E7A91CF,C054957B5B674A2A,E3ACD33058015675,00003EF049C9C556,249A1FE943A1AB78,FFBA40FB0B3D3BB7,E9241DC45B3DE8FE,2EA0032E8D6BE2D7,CC7BBF86DA3C2673,54081B7288F687FE,000143372CF1353F,E9340A646C3D6336,792C64E4919239E6,1CD7F6FC0AE998CE,E47E45DCD6F1D39C,EB64A7DE32637127,19E930C01DB61B28,0001A14586E66FA9,5F7F36ACFF66E52B,0336CD8997CA7A2D,6600E5645BF5B406,83E0D73530A99859,D984C3549A5F9C6E,BD3F256ACD1832B2,0000BFBECE59FE03,CE52ADD9B13961B8,32139337A15B9FA3,8D60C99085A75A75,D79AF63122564C76,B05DE5BD32C812BC,8BC4F1EAE4D26168,000220801F9818EE,B29276B081A880BE,4720DDF0CD2B3198,66AD048931E14380,B4823652C5495F31,C61DB15B6731F3E5,86AF90528124EB39,0001F9A90488EA90,64D9B4792067E15C,26EB9580D7573612,4B2B9BECE0C15118,1F123C825B8BEAD2,7EC28F7E437BF1C7,DD65FAD83A0D051D,0001F824EA6FB3A5,FEC1D7BADBED9BB5,17FE5E55FC1B0FC0,5A596858014EAED6,A6A1753568BD0C67,2B967FE08968A92D,84358A7999C86278,0001CE063451AC53,DEC3C3D557271CB5,B1E6C62B09DBEBEC,5AC67448586F9A57,A0B622450784A3D0,5A60BC95BA23D068,B1039D856CEAE08B,0000D1B5A75F36BA,9C230F1BA354319C,8617F024A6F4C893,B46F0030B2797C5D,17DF4FF2274CB434,0DD9D91CCCEB67F3,80DC6AD4DDB3237E,00014F958130A42D,7973A16188DDB1B0,89979C9C0357798C,FFFD7C78AE3AB490,A069B5648991C1AF,0FA4E0CB7C176FE5,0539A085F4C9E957,000122CEC918D3AA,B4999DFB62B2F209,B95281F59FC290DF,DFE07954A9C00208,B17F7F2BB2D43655,64E68AC1C936A797,8FE6337825E96E18,00002BD519660667,2AC6449E13C4492C,D97807C01BAAE84A,6B906B1A303C6FF7,CA8A866D61061BFF,2243F350913B539D,D875D65B5B17A7E5,00000C6FE838E9C4,2DFE0C7D9D82F12E,D2AD3EF092CB42E8,DC0684C29F47D1F5,9F1C8289161952C2,798E8AA232B42171,94CCFAAA86213CE6,0002306FFD022510,9D2E23C936E0A543,7C9D6265D35F598D,024134294A6359F5,BA94C6CC3541DB2F,944DF32A94D860A4,8635906C03DEDBFF,000210DCCC627733,EE3FA10811682C45,9D329A0B021BF33A,36A1F8895E4533B8,488B32CB52369293,F9ED9B78413CCA40,F0FF66E3A63A3397,00000ABC2AA32C41,6124A70277F1D15C,C149800072287933,78B4F3DDA0B24173,B12C514941670022,F794BF268229589A,DB62AB898CEFB25F,00009CF4C4D12225,F04D98170810855F,FFB6B417564FCE74,0BE9FC0C057F7AB6,38B7BB8A63575670,F1CC9EC1E031685C,570921D01EB88A87,00001575DC510BE2,9FDA088A5FA2876C,C7CCA6229BEDA074,EC88EC0498439475,F4A89D7DE5A1D984,19D978E372302083,9F2A444BB54F36D4,000009089056D8DC,FA8ED7BD6BA567F3,B849A18C68BA3397,A6E2409DA5E46E7E,AD41CAFD1D1F857D,FC18D3401F016204,DC60D8378D80BE0D,0000C42E1B0A1B38,DAC964848C952111,134B8EAAA786F5EB,76F738494920F34D,86D7E8768F1BBA44,F1154A3E03BC7F41,6BD4E97463BDAC89,00013E65360D5A86,A9C4262D03C9088D,F8C761483E64F21B,D820EF12E39D86D8,43E1B9B7663B4A82,62B431BF20E21131,E2140E9E875FCF44,000079D64AE8FAD0,81DF8CA3A850A74E,BA5A2CD79C3A71B9,EFFBB2D8905094A0,7B1CF2C7149FA99A,1E87E02164A50F1C,DC33C8090B4188BB,00015E0A16D8B8E6,944BF31371F77FB1,E984B27B708C2AE7,0C01EE730E35EE82,C36CDC432770EDB1,66C4FAC4D9EDAB4F,0760F0C021937821,0000F4DCFC4C5C1C,D697601DCA7CA4B5,D16726DCBE0FD988,8119DD7AF0E6C87C,D1E1BDAB620C8DF9,27ABDBB336AF35D0,C36900B91B5F4914,0001E21CCC021AE9,DAEB901A8B0B1BF6,00CFA413FEE3DEEB,D8A152FC022EDD7F,69AEE6F393ADDBE5,45F3B54D85AB6DDE,19F7181A0B697BAB,0000E1C0ED0125C4,374B1CE5F2781984,71D5AD70126A6664,4389E57D7715FCAE,E3EFE78A9BEAC09E,455C8B14585F1F17,5F372F4049EBCCF7,0001AD446F6FFF06,D697601DCA7CA4B5,D16726DCBE0FD988,8119DD7AF0E6C87C,D1E1BDAB620C8DF9,27ABDBB336AF35D0,C36900B91B5F4914,0001E21CCC021AE9 - -T_tate2_firststep_P = 16747C943533BF87,B4497C90231C8CF6,5ABB26BC14FB0710,457A7E552E14B4D2,6E92EEF549069079,0565AB7E75A1BA5C,00021F0CABC7F726,39645C6B7CF4AD82,72CA8B9E5285631B,B778021E0CE0E39B,1255EAC0AC0F8ABA,6A43AE42E0830B36,C85CCEC4E3F3764B,00010F16B11E4DF3,44D662245513A8F6,4926CA3671265135,1BD215535DA13B6D,18FE224B9795814C,4010C29A1FC10E03,B72E6E05D7DDD73A,00004ECD639F7DE7,DFA0E79BF5633D28,05F9B46F9C06602E,22B17FDA14F3A36A,44E15C64A71346D5,AA9205DED17FC6DA,59B8583E58373D72,000077D7B7A0BE52 - -T_tate2_P = EC805BF7BF3C44F4,9544F219309FD605,57266A162ABDBD16,19BB58DC7DB2C684,94AC03F73CAF41E7,E74ACBA50EDF2704,0000C3C8774EB007,8D6C83984DF44C50,0E0465877BEE21C8,84AF8716D3A72CA4,B24BA37D544FF41A,55AE1D1FDDE2CF50,1FC6005B0A3BF598,0001F03B0D3AB5AD,9DECCF4D9DED8FCF,B174F8838F39077A,57F83822E25CAFEB,3102E1391CAB6155,227FA1883A32B238,16017735CEB0AC74,000148CD6FD6DB5D,2A01D357301F926A,CB4D81CD7FBABD64,6B82DEA4A30AB815,76E5F2AF75BEC38E,D26B0D0ABA831A53,1B9143452E5F9339,0000472E47104E30,6580B4E8616255FE,BEB1D48213D4135A,8B8E530E0979FFBB,7332BF0175E66A6C,1FC991982AE560F1,A63089887981F8A2,00010651DF93EDBB,138A40B5B601F403,DBEBDEEF56F7172C,850B270EBB655B18,EA99413F5D06C2EC,62E8C519B38D16E3,D6A087AEE5AD7907,00013BF25988A35B,BDA4E8A80BD58554,8F5AD2D24CA205E9,9FB501A9A3361E8B,795D391E5533B114,7AE37A1A8755126D,DF2E2F4B20CB4625,0000CC1D3836F3A4,BA317AE90A9F1F40,5CD96B10E8B594F2,363A99B394562375,16D9907278F5B7B8,03AD00C23270F99C,268847B06792AB18,0000EDC9BAA4479B,9B6A0789351E26F8,232122287972F869,ABF334899D2596EF,3ED05B4EC3155259,7D153AE088BEB1A1,EE1400032F6CA07E,00022F95CC45C80F,7E95894918D79779,928ECBB76806A6E7,4E2B5CADC7FF9D7E,3EF12F8FFE36B356,6D737A7E43CD3BA0,E4806271B8F12A28,0000D0A7EBEEE94C,408E6739BCCDB794,AFA9839E9ED686F5,9EE7977709708BFA,25F8FF292CBE439F,C9592A5D7646E46F,41A47FDC9F47D842,0000036971DB625B,D7DE6837A1ABBEBB,20FCE0F370405436,8869DB8FC8418E06,A5C42D3B0B9BB347,7FFA3574D7D5EF0D,D16DA2322F7EE3F6,000078CFBA1DCF15,A815AEF0BF8399F4,8CDFE4B9C791F68D,B69B40AB65F50C78,7A99360A56DEB801,73F1372B37835BAA,52B46F01879A8491,000196D0BCBEA9F4,66D9042B7AD20631,E2F40994B640041E,803BAB14A520E115,4B8FB04BB4407C75,2746731DF016AEF1,52D95DC473A19231,0001E688353A84FF,EADB60B1FA225B1C,5829844ECDE44538,A8BA69D1157F1438,9A5013CE37BBEB9E,A55A58B80006659A,4B36EA4E5661125C,0000E65382B5CD2A,26656337D53A935E,FE987B7E89B1904E,436D2F9722F581AF,08F8B3F66A8F46A4,9FF207863CB9DD39,7513BB4EFB10A0DA,0001F93DB55F5B81,791730F0307313B9,7FE8FF1A56374977,D2955E67E5C7E2BC,C9B6294FEF5D4306,30A601C9B98C9AEE,284BF19491A4209B,0000830D23D448DD,8D8A5A0DF5A3B0E3,54A28EABFA1FFB3C,5BA10B3F803A058E,C54D364353A14233,ABB9A859710CB096,F8F1F93A83990040,00014978080CDB86,1AA49D3AFA98A463,6C6DA2FA9F14B6CF,E26903D621527B64,547FC7310D472B4B,181E14EB3AA253E3,0A0721B617FE0783,0001E99EEA34B165,A9B8C03406426554,F2B4C5825F09678A,981530252C4749C7,F29F3AF85B7E7AB9,ECFEA4DF9FA9F013,51A67D8E5665BB0A,00009F3012AFD23F,5530A83019C37B7A,AF5AFDC8C3EFBAC9,809F533BC34A7F8D,03533941DD50EC17,89B4146CADFFB9CE,E4EDE6B5180628CA,000193D642291ACD,C52680F5A1D5D7F5,F26A16EA220A67C4,051683DEA555E736,C9307DF26CF08349,03400369D2D68531,6CD36316EFEBDD37,0000835FCF304968,E9EEED9A49FC4107,C111AB8833D02EDB,1577C41960237790,759869DEB441D1BF,271966E27233557D,07EFB1183747CA62,000180C94F1A1040,AA64A278C44DB707,B40B3790036F4F6E,F2F57F2AA9B2F7B4,6D586DB0589D399B,0E2A3BB7BFEDA900,98D09766D631F998,00021B347969E01B,B506D47E4BFEC3F7,B25652C1BCF5DA48,EA70506FC28B1499,2A3666DED90E9479,9E1E6860FD9C462D,67FFC42CB5322928,000179434D8F8A0A,9728BC42F646B3AB,F1AEE70E07D4D70F,059EEB6357C35AC9,B23E0EBA39E1B2F7,5A4542BC35E8FD34,4E017D5C7725B7C3,000027CF73C827B9,64A527550DCD5907,3678D09161817EFE,BED115C5EA63801B,9736263ECDB012C6,6B903280A8E74DAD,BD6C18152B8296A9,00012F2A1077202B,48D9422DB4A3B891,03EDCDEE2B344539,25B146C62D60B2AF,A4F160649E0326AA,A291E261A82338AA,EEE5E3064E0B77DA,00000105BD35B40E,0F4783294C135E1E,A5056685C34208E6,821C7ADCCB5496AF,FAB3049F340E60F3,B290A6682B4ED813,8E099C0AF76DE046,000124785BE30A9D,06FDD10D2556F813,2810FEE45663F2C8,C1846948C575D352,56DB785BE231144F,D696AD1BA6CE96CA,029514A98D851387,00015571AFD5B61E,E8CBF8001C741815,77B0355995A8F28B,BE4CFA44D8EDFB3B,E03758C6281A9E95,BD2BF821C2AC5C54,6F7CF1D311270F5B,0000F6A83D28167C,E00134075CEA80D2,39F53D0CD51BDF6C,9EA5BF410C5C3222,4DCE756CCEEDF29D,3CDD9D8B9B946992,4AC197F2379A720A,00021A5EC40B60D6,EB17AE69CFA246C0,32AB8A55FAF11D62,A34108F3AC58ABB6,26B8F2F3195613EC,14C63EAD61B4D5E2,365E422661915515,0001A24591098012,E2E6D1E1474947ED,42FA4D623EC16323,E90EDE5521144F5C,91CE2D331E2A7E0E,850E6D98B922CB75,B556CB1D67A349A2,0002114FE415E8BF,779255107AE35E3E,09E6D0061AC12A9D,BC60D00D01AE4026,A49F8250E4538090,FDBEC6D26803DBF2,86C1FE821736C7C4,000024C6915F258F,CE8BA2749878FA9B,E859F9258EDD3175,8A4265D885141FC2,4E51167C4F0E592C,0CFBB67893372F87,EC365D0DC5C4EB2D,0000556EBB8E388B,CBECFFEE9D0E49E8,4BA22118880EBAA6,78BB39B967C71E2B,887CC2D8910B6D72,6CAA7599C21DE9C5,5F38FCA2D8BB592A,0000D29EDB7D6BCF,65B7E0A8477B667D,29DEBF940550FAF1,8B31EA5E76AD46A5,732860309056EACE,ED98A8EFBCC1B997,19FFE4D0F727DBDA,00003BA2B40F82CB,60E457EAE729D731,600EF128147DBECC,B9590B8C64F9BB28,5E3C420EF97F4680,93476B581D6CA303,E6E9F1CF72812AB4,00005003F03BFC0B,D439D6D5EAA73560,F06A3C80062AAAC4,AF4335CAE37F5A58,74BA9BF16A7DD5BD,C89A68E2F9A0BF53,900E6ECAC98A891F,00001932C987ABB0,3CA109071F25F058,758DA3DE20BBD2D4,A5B958E96387B49B,D9BD787164AF5633,4FB1B19C44984020,3AB302C4F7C2158A,00012515483B15A3,0B6528F8CB35D3BF,BA4769181A02C48C,3537B032B2D8FF07,1C69541832F46446,FBE2C41D50D0E1AE,21DE168D7F787302,00007220AFEDB032,AF7867D34F3BF6B0,DB4C91FCD5DAD187,BDFDF76F7B17064C,232BAFFA1A02AC8E,050549D1F80C29BC,10AE173A14542B1C,0001BDD3A653C0CF,2E539937FDFE7D29,AE7ED2C03C24C3F4,4AA63D4EB4F8504C,2346DDD13B081DF7,13A0D691575A35BF,7AFB1EC81E8194D5,0000F4F8F2A2C320,BF23B1F69D1EDAC2,A39ECD16B70125EE,B0E53A50D9EECE0B,B22CC704EE8439F4,4840F99D830FB492,1DD8BA3FAD131F16,00018EFA369142E7,60DA859ED995FB4A,EC5EB0B7C3E7244E,6CE35165BC3C9E09,94740EA96A023CE0,32E556A128025F16,BA45528485F4EDD5,0000EFF0985033CD,6E158D126DB2DEE0,82FB9165FB521F54,3564147F9581D527,37A57CEE7A3654BC,0E9156B8B4E47EF3,3A7D3FD6D9A54B83,00005B1C49C6BCDA,559DB8E736B4F3F9,A519659F1124F25B,F2477A0585F8AE45,5671E973CD91B9BE,DCD7A48C8C3C97F0,214CBA473CF8B1CF,00009FD2B65E417D,CF52D82628DCF1D8,97FEB86048FC880E,450231D4783A4B19,847F6411A65722FF,A95CE3350E7B3566,97B2F0D1C47A68A7,00001208EF04B340,3BE0EF689F5BB450,C76F8D29CF9B6BDB,F9AAC51986968F4A,56256F725F6F30BF,A5E1B70EEFB49BE2,8BCC908A33938A96,00018AB876B614C6,6612C9C5D1794A59,B29357609F4C37E5,CC887976729B553D,D0B386D693FC0827,1FDEB4D44B64A1D7,565F7D573A7E9B5C,0002191576EEF553,85879C670E2DC088,12242C35BB697A0C,8526D3EE0EDE7472,DB5DC97753DEB6E5,2399900DDB6F8C0D,573146154B32DD6D,0000325F55372262,BA994F6EA5431FFA,F5C3F913134C3318,A8EF722CB20BD1D6,9A11E85CCDEAC7CB,3EA776C6945B7DF8,EECFE2889EE181F2,00020537B246E1DC,EBFF24875AED5B33,DAF5286243D128F9,23F33DCC4A5ACDB1,D224F507EC30453D,9A22A4BEFC7FA3D6,CAF88503AB48F569,0001178C5516E662,18E6027D4233E649,E9EDEBF20EEAD413,6B09697E29352C33,736EE33D69F9A9F4,8267768A86DEC9E8,16A7CFE6294D02B5,00003A43907C8837,8D80F73732FD5C8C,EBC5B2707CD96B0F,4F58A96ECAA4DDFE,1178709A071EC1EE,DAFC4B5BF4C91023,58E37310B575C8CF,00001CD2F757C98D,D2D24D9C3DEC9B66,55764D2A3FB0C42A,B64D4B8317F30545,DA8E716688B68F63,97C17DFDD366C677,CE7245F1198A0F0E,00013EAAFF0D6029,E6E48A44B43C89E5,729CEBE84B6942D2,164E27D64781A163,1CAC477220437833,45A3E96D49BF87D4,C6FE846712ED2BA1,00021B72315663B7,7A469AB0A6702F84,AEA9F8638D12D040,00BB052C5B755AA1,EE52128794CDAF92,0495DA559392F87B,1E2C02254A1FEA57,00012231DD7E481D,187273C1C37C6622,C9C7517D5C0B6928,34A7092D320B11B1,9249DD4C05620084,CA9EFB8591C88F3F,52D28AF4714725B5,0001DD56B54910A7,60E6F39B5C74C7AC,B5030DD06DA1667A,2175642C60F3D7F5,308ECAD7DFEAE2BB,F73516A21B97FB78,1BA5B72190DCB248,0000814A4017C80A,E67E5CE4B226D943,CE154A47A33B21C4,94D875AB1FE1C199,D5483DBF0A988DE5,441C1EA4E829DB4F,D561CF220941ED83,000096749EDC2A04,BF73DF457B525792,3C58A39EF96E0273,FF83338BE7542DDA,3630AABC466C745F,60B9D65A3C4FE8B4,871BB8EB8F9B9AD5,0001135758AB7C72,40CE9D13DF0E370E,6DDAAD3CCCC6C750,4FBC4D2E53A9992B,EB4E8EEB80C686A9,C85F619F10828C06,50D4DAD71D81060F,000054D92587DEDD,AE06A87F5BD90662,E9627C4A7A64B6C4,BB743848A6AE2604,374FA0A07416144E,B233F465B37BFD12,F61D02CAE88CCD3F,000185A97C9D19A4,AD696B376924772C,5AC02B5A506A3610,080A03934B03DBE7,C33F4BFB9450D0EB,56667418085DAC07,B4572857CAF0DC9D,000024230F6CBCCF,A1AAB1BAA37583C5,C22CA59BF0E0333A,E03E802AB9B4DEE4,3B29042FCFCBFB40,DA929CD11E32E8B0,66077E4869255DAF,00002830C635D6BE,177F1811FA04CAA8,4836D14C30233589,E1EE4266BB52CBE3,20D5F503A51D4190,CA43478014143DA9,059D3E7173954F91,00019A435D18674F,E3967A755C076502,D0BFEF602071471A,A58FBFADBEFF7AB9,433DA2CE99EB6B74,391960B98B84626F,C00B7E1F1977AE49,000027D260A8B5A4,5A836453DE1CBA8B,FD616603A337363B,F9393B0BF8671490,3AC8527CABB7905A,8D1BC7B150AC6087,5A5B1535DF3F9442,0000EFDD3198BE80,274D0598A60C7C7E,95202DD451175148,E2FEFDF91D536F91,C470BA28B4F3ADC5,59C5952F6EEA2C44,27100F13C937058E,000147DB847A4CD3,E38FF97A6B2F1AC7,4AD34D95B2868834,E0AD04599AACF7D9,2BBCFE084F17FB1B,20A63D8F4448B883,1D99DA89DC47F45F,0000E918D24E63CE,11F3A3E530688049,13B66716B1EF4FE1,6166686B0EBE8682,82F8AD6D3178CB8D,EDFC3907F5F50C27,82349522D1660EA6,00008B0D17E0EB7B,D53305B5135CCFDB,644E27D7A3939FB4,DE2DBED0E35F7B30,E13ED92C324AB378,95DC6139424AA1E2,15F728AE0F02A5CB,00010BF78DF1A955,39E878AC8593134F,2325B5A46390971B,B852F0EB171EADF1,EEEC8FF18D97F50E,2B33E0ADE5398ADE,AF307F18D6637BD2,00003341ED4DEFB7,E687D442A106EB07,8331C391CB831E8E,8094566C126A0280,5CB50AAA7D9EA242,02B2AD6ECD26FD7E,367DF402CF27BE28,0001C7CECA385217,DD4B0E2DD7DDBC14,E9B67E85AD89775F,E2087FEE03644152,69620A55CA7E4357,D2E683DF35B1E0FF,3130F5EBB934809A,0001B7C926018879,77E3B58CD7605288,F0DEF5AD0E4472A1,04590F3CC27CF3E8,22920C0C566FB80A,4F44A42E97AD22D0,29BE271E3B496AA9,0001147505FF6665,5AD5E44749CCDAD1,8047497239A91F04,9E3AFECB44E831D2,4AC36AE57000C5D3,67250EEF5D7040E3,1A71830D8FA8FCCB,0000D82D5D3F5B49,7A9B0AA9CA69812D,FCEEA7D9581A7D3F,B08636B23463C52C,7F95961642116295,8DB0517680360CFF,3BE2C06C7F73DD6D,0000CA8B7F8CFC22,CCCD0570AE0673A7,2686EAE265A85F1D,FEF11F7E3DAFC3D2,9D67B41DE63A9041,155BB7AA8B166149,29B6D78FE87157AB,00010D7B2D2BB6AA,466404F3F7442766,40EBB22AFCD81CAA,735E14211655A347,2353817082FD414D,C6F55CA742A1F822,0439A4FCA50F31E5,000065EA324C62E5,3E2C7B6DF0FBB32E,C797A8B8C12C979D,1D10213CB149DC83,1148B2C79B15A730,A81BE19B4E52A929,9AC19781468F47F7,00007CE5F0D05BAF,50348C2EEBA2EEC8,494B655DC6370024,C64B2492B20A7B9E,759D88D47EFE343A,44C0C69C31983368,05F7857C21B3B885,00018A431626585E,7ECD193AA1896FD8,2F087BAADA186D25,51E52FD9E04FB07E,887E0FB3010F5981,7DAFD8E9FE1DB04E,01DA39016C7BF888,0000F0CB6458D166,225E7598E2151CD2,951F38951B470D84,D56AAAE60F72E146,77587084FB0D1924,95963E04512362E5,7AEEA02B2F2115AE,0001B592E82DD6AA,268E948ABB6D1152,3917B6062DCAF5D0,F0D74C64625ED86A,6D76AC540F782A2F,EC19D13F659D1B98,202DA50D58CEB050,00022C86EF5BDE90,A734EAF2A84CA491,19C299100EC7D43F,98D1954EF0A26298,471C3FAB0B20BEA0,AAE1914FDB490BAE,5B932972B90B6245,00000B9CB030C5E8,1CCBA32FDDE25787,EAA51A8DF1768262,AF47EA613741342B,13C883E1302F7AA7,606C67352B77E68D,1585D1497D37DEE0,00013A558C4192FB,71253818505D82C7,142C2B75FA87086E,EC09FE11871F3DA5,9430A09A029E3971,2FB65ED26B57EB15,21C0A5AD5DC864B0,0000BE043E8C4643,7700D04C33E854A4,AA02E3CF7010D8AA,B8F9DA0996E5C218,6F5EF41BA3C72B83,37BC4BC873D5BE74,593209E449B061D4,0000B0BD82FE8FEE,2413042ADAE4F9BE,6E68919A3F9F520F,6D6FF86D609EF76E,5F03626516623592,00ECB52C7CB2BCD8,7F68229DC659A96B,0000C36F51C8F550,4A4DBCEE66CC5657,0AD87788CD4DC3BE,CEF299D42AEE66DC,9B3D72A3EF740163,67137BF882ED3745,8C68B0297D1A932D,00017B9459D22822,1F4C20ACD7E7ED20,2BA007237746E49F,E38902D142914DA2,E685DC008902E5A9,0FF5E1E1104EB8F1,1DD2C97332FE69AB,0001F2B7C8E5A3D1,9497B379043F8502,C87937F32408F729,B8B96C9B777ED3C2,435573BE3E876A40,75C4290D2F4D7B90,FD485BC57582DF70,000226C55409E1B6,5C9825CEA6878000,0BC42F285460627C,38571FCAC48B9C06,746C846C79D3AAC3,B5214576B416867D,384B758216E1F8DD,00019F3237FF2BB9,EEAAAA37F9C0341F,3BEBA6D9A962A4D2,FBCDFD09CE598BC4,002F509AF242E79B,78DB1F3251D72449,DA7D053B91B5EA88,0000D21153F1D5D4,143DF1CE74B49BC0,AE90824B3741E76A,6887499DFA10169F,2003E289C92A4E5E,370A661EC26A528D,06A899A5682EE73E,0000EAC9635A586C,F73AB0B598C2A449,CE7FDCBDE1324E3D,A11F508F2E35A4CF,0C4255E2C4783626,F44AB8DE707A6838,63E417A183B25A2B,000093017CE2A851,1A6354F1BC4EC2FB,8F283005F918DC00,EDB354F6C4E9754F,2AD9F00571499369,B2753E81FEC4DCD7,ECF4786D46C71E6A,0000E01E40B37E5D,BF37EE6E7C164F0A,BA6DA7AF17D430CD,1DFFE78ACDCF9655,D523D13CF3BB6219,D4E246F0B53FF8DE,F0F650ACA85CD532,0000F4CEA38E03A4,E4F8174DC7914DD1,82611EC56B1F75D9,DDA7EA743D9EE5B5,D8657A5676F1BEF9,F01EBFBE581D0C25,AACBBE117F522FE8,00002A75A8C1020F,76799A7A2C4F866B,02AFD04AC63C03BA,8AB7B19D71A65219,3063322A7C3AB35D,E0957088B9415A79,268CE0438252973C,00009283E93E59F3,DB819FE63D7AED28,C6FC71D8D72C3FB4,03A55B8DA022A959,8A59B3AD83875858,8CE62B25AFC1724D,30085ADEA92036C8,00011DE95BB715F0,C13FBED57E7734C7,5DAAE0DB2A28BFB9,B4EC05667E7AADC8,1ED3A82B37681D17,3157993A65E29168,F4696FFFD8E72ED3,000041CB2BF05715,AEDCF2D46B85F1B7,AA34108E4ADDCBA9,3214B5366EE44DD3,BC87738883D9AAF5,6764179DBE3AF403,BF54C347D46AB1F7,0002149A459CAF5A,D59E1B1871D8900F,FF0AA74278D595AE,77C3B9C68003A3A9,C2F7F1FB0DFF2614,281F3BBD38B2C913,FBC4FD1E31B775A3,00022D6A5C64C95C,7C29037BC2F52041,B1A31686A99ACB91,DB552D51BB6E8971,A6C169B9DFF1277E,9DE725BDCC7A23DB,47A9A82F6E989C34,0000FE1DB512BB63,A20929F1FDAFD96C,4617795C154DDD58,3BF2F1D422B1EE50,C3668CA6AF3259D4,E578A01491CCF79E,CC157C03B457F8ED,000120344D71B9A5,CE8386B7E46A310F,47A8289BB64E649A,606749FE1AE330BE,C8370BE8EB019BF6,7D10966E5D939BAD,5C6FDA7483E23A6D,000079D65EBA7A47,65861B5D4BBA3704,3F4553039308774D,5DB3A4CBC9960283,15F5F27AC0AC7DD6,840044044ECF5D55,6C7BCBCBA92FDFEB,0000EE7B7BB88AD1,ED18EBB499BA95D1,69AD6C48ED86EA01,8D65D15DDC7439D2,40EA0FECB3F7CFF6,3A3CBBAE991DBC3B,9D2E6C8C0A3B6AFF,00020ED203BBEFAA,6AB7D10C2AD27552,AE6C86197A0AB19C,B3835FAB32008883,446F0A909146E1B0,B317457AAC4949BA,9CB305C80DA06612,0000DA5E813754F8,F07BB2B27E318814,B4859B8A8154DB1C,DCBFB18CDC968D1D,60F66C74D96A54D2,236F6A506BF044E2,9BED08577B463E62,000090C421A1944D,BFB748B42FECB593,EAFD684FA83DA057,8CE98FD9B7A455CE,89A27B4E528632B7,651C2FE59B6D9965,786B53CF6E2DEF1E,000161A8C5337D42,94D231EA7A49E792,75B0B1BDEEF85B48,15B58B9B5AAE1C39,DD58719C544C95C8,A9DB1A7782F1D58B,4DD2A558BB2B14D7,0000C0B4EF8EDA57,E5D0DD8CE9F27546,F301CBFD26DD5657,7D979200125B0325,024A767E4FCAA14F,67A161EE3DC4BB63,448EC9CCCBEE3101,0001E0D747CA9E69,0E94A63551D45C63,4861D89252FB6EB5,F658D308CFC6B850,43A02BD6C5C25308,895DB9612AC6091A,8C54A8D1A64F6EB5,000075B28E5DB459,94BFF410654B4E72,7D64E59D9005772A,5C89CD8AACD6F97A,F24FF4566FA408B9,94580A86AA90D160,68E99D088BEF8A70,0001F0C5961D1B00,49CE2831AE2E41CD,2B6430B1282E4248,9ECAD102EE89F4CA,ACA1303085B17A6B,01B5FFA4A9C450E7,E834F97329DA3808,00008876C03F1778,B8D5ACFFF8DAA9DE,136E348A82A3B014,1A8C766B2C9E2B07,F426F0C27696F0DB,BF2AAABE7AFBCAF4,02FA5AF665DC6DE8,0000A810E61AC1BD,D55B18E90BE378F9,3F9FFE8DB0CADA53,7916D8EC36C839E3,9C29A7CDDFA5448B,88309E19ED3A5F58,5410B1B79E8E8E55,00012250886035E4,D339A9586315123E,D150199FED821230,B59FFFA993F08BE3,5A309588EE5DA8DA,4A4A3D5C870A70FF,3050B1CDF466F4FA,00019604EA345DD6,54F886AA41C4B41E,800ED21A7AF992DF,6C371565EB36BF56,5D10D8AEB0305BCF,1F71D5B50474C4D2,79BDC1D0061695F4,0000C4D31C98B975,6E6495EF5108F7C3,6C9A905CF3E98362,AA02DD548EAE07E8,990EC1DD949B0B7A,066898B0CD06E4B3,0B765B8289810460,00017530BBA6FC61,C95193E6AC920F8D,D56C9589A74A979F,8C7908E9FB1AAF76,5E96ED643B6BE6A7,6A55DFDBB65106F7,9CAC60F2C17A2986,0001EF5FA5ED38AC,6E1FC65C6EBD50A1,B653DDFE834FBFFA,1017F9AC08C38B47,EE73BCB9235B08C3,CB1335700122B396,DDC84510B9786F91,00020348C1C6F43F,CEE12AC20FA6D9C3,7EF1160C17B682E3,0465BBBCB75E506E,CDC6E65DB1F6F364,C1D70F3FA2B3BE5F,B10C24AB211018D0,0001BE276FFBF9A0,742BD8217D616FC5,CF784A6F467E5315,C640E0F2D3BA124C,36ACDA0569869B12,2A763ED6F7F7A10C,53778674E2678BE8,0001611BE3966E23,665075C75BE9180A,DC23C241600CD699,456BCE352F0D5F79,FC4088544E89FBCB,6E45F19D40B6C458,1672522A8E50B7B2,0001BDD395FC5F26,BCD88A90BCF4EE1A,956AEB72CD514C23,26389D7E998B113A,0FB8C8A8CFA4B97E,423ED1207D02DCD8,06EF5CE2F56D7687,0000AD8E8AD7D5BC,0EEB84B3A72E026A,0FC42BABC6BD5302,68CD226C532A4B76,6372947A936DBA13,404A36CCE12B111A,D5EB8866B3A372ED,0001A0F901993FA9,64A212DF55D2BF58,5F790C3A32D68C10,2E35101D5B0968CF,9598CCB51B7D2564,035FDFCB819BD12E,F011E6F01CC723C7,00011F8435FFE1E6,D202298966E9F7F1,882F73EDCAAA1BAF,800DAF96785ADE3B,BA0AC2E5FEA5A8F0,F2FC3F18AC0447E4,04AFC412AAB4D7CF,000118740442FD17,8C86F006A5451F40,F28D1E9D88F67264,C395C3C072716D75,2499FC15AA561486,FF3F0B8C617209C3,64A30A1F53EF247A,000121EC1F1F9361,7E809696C189EF72,6B95E761F371642F,3ABFEEB7931A0959,FF8222A5DDD9E60E,3A29A2162CDB14AD,4DF77169FABC13B5,00002D9985B378B2,1BB63F32CC41E9C9,B886FA297B309A69,C3505985E61657F3,4BAA0BE1E2871DD5,5BE053537E68E0BD,D643DDBFDB523A89,0000318CEA93BCE3,5DED0564E69AEE70,7A9B5BC4A0365D8E,C435DD8C1744D179,3B0C4187375731BA,B51D404CD622E106,DB8FDF0DDF7E9BB3,00006CED7D4D4FFD,E7C14FC05747E773,E1D3406A9FC6F545,D2C512BD7B53FE23,8C3F752C91673BC9,43CC149DBD387193,97115F0542208E4B,000226D76965170D,1B8F86847B24EE0F,5B4BDFED7D77FE34,4447907A63C4BD31,B5B97F6163047C58,C51736963E28029A,A8540982D2417D59,0000DB829C861CA4,5E2D5515B55D8069,2E653735B3767B5E,27192C1B39EF537B,6FFD59862E5CA309,D36057B1584219A7,2C32EF4C43B11D47,0000CBD68D47A8BD,1338464E7CD959FF,69B92CC604FFAD3B,76C3DAF05DB1A78C,3B930FDBC2B1630E,DA6DEE0F7682A48A,5C6EED4B165E72C6,0001029AE37135BC,9923F056F4961487,2FB191AC91A7FA5E,9DBB356A9DF0F58D,4497B56A55590A80,F5AC6F11CD2CEF32,3A80682E8E34085B,0001B5B36343A382,8009CDADAD24B6A6,C210107C92BBEBFC,463177B52E7199CE,F307224D2F57EA44,5F5E263359A074C4,BCADACAAA150C1A0,00018C0B21C95AE4,F4E8A047FF1EFCC1,2FD543B8BAAD56AD,62857F87EFB4621D,91BD6A26DC41A608,E09741C9628B375C,CA9F00831E2F1D6D,0001E6569E7987C2,D2DC093D24207122,9FE7E9597148DCEA,6C7707B693C2ECC3,57957FDEEFB4EF00,3B249B817CF41F4A,E583DC2A14C71E98,00010845E3917D69,4000B6E9E8133C2B,28189823DB2EF6C0,1486AFFBD2874773,A63E496299C02F11,5E54AC7E997602B4,6BF2DB0EE1E0DDB0,000209FD1139A630,EBE017429F57FEAC,A6C15A7B27D4BF8A,F0FEBC02E21A9E02,EC8FB6E3455B23BD,EB9CFBEF4ADEF3BD,020941CF3797B717,000199CCEF83ABB3,7424C9BAB2066AA0,6135D5AF4D19A386,345CD5EC84917BB1,4A13F45D768972DC,6CD51B9F999979EB,FA713079C8759000,0001D5E8A275FCD9,0AFD8CD2EED6DBEC,A2012F90B0B6C7B4,E673A6BF8350EFCE,292AADF76317B0F7,BDE6D0A561819008,6C21AE18663D825E,00002ABB04BD6513,4FA48297B04E9E93,464353B38D8AEABC,9F0E4FAC9229C0C6,BBDE4D257189582A,2A80CCB80759DF62,57E119E942680929,0000023764AF357A,2FBDFB429210A652,BCF47FD32BE90AE9,7CD2505728BF90D2,AE2E5BD874EDD15E,647681BAEC30297C,177BA8FDBC058F2A,00019F5A2A8A7567,1F5D2415F615BA4A,131C5A245EE2B417,216BB52AB232078A,920988D7740A8F5F,6C5A18E13520E50F,6FCB2F40B527338A,0002068FC773DCB1,3ACDEEE7E5FACB2F,2CD8E9B5C1878972,37225D2BF74A333D,DFA2912D865DAACF,067CDC4CC667CCF7,4091293340B76957,00013B86753A2C9C,A7E83C3955E32764,1D8018DAD5B444DE,1BC52D3FD83A97B8,83DAE013FD1A99B5,DA7EF80213F1C5B2,F6805B17CBE1E989,00007B4EAD93F849,CDA56C207CF329D4,2FDDE07F7D2DE44C,C92C95B374C1F502,94B02BE18333F7AC,65A2E840A62D415D,43DA52B43C1F37A6,0001393E9025AC19,F3BF549623FF8804,382F5252CED0381E,0A99F8B8789F3E1B,5C2BB48A8CA8C036,96FC7754DEEFAADD,6544E5C676DCFA76,0000AAA27301EBD3,B2520E8064945A09,D91B4DEE9418A84A,656DD32709D87747,43290B283D498DAA,59BC2176E909E8C1,77AC13014CC37A93,0002164096B1AB3D,B821FF0E12230B94,A338E1D490DB6755,EE73087D518D5186,43AFBC6B45B40750,2DA01A6A0B31109C,B98F9A4CA0F19FA4,0000EC01416092B4,F424F780A0FE9B1D,EA9DFDD10B99D252,DFDCF17E94DADBD9,036856B4ECD3077B,0BE2D1564B9DF4B8,C8CA10EF5140FC42,00014A51AF8C2D6C,6365462CE867D4C1,88A212B69C4CE555,12F621862F5DF4CF,4FE290A62C73A74B,CCBA2859EC5FD7FA,2F74CBEC606BB9A9,000163D732EE7381,45AE11D243D6D350,3497F77503972728,D0B708DED55D22DC,B0A833D8261CDDC1,86ECE4A0D0C21754,42668D8A3E165CA6,0001DD0390B7B919,C218CE1D00A5688D,AEC5D4A95CD23687,551445535D6DCD9D,D344DEF13ACD84EC,EF4E153BD3765E67,D879B9B26940662C,00021DCB644B01DA,5D5636EC93BFEABD,AB79259842A4BE03,617B9C2A2082B6EB,5DA56D984449553F,B47DB8ADC5D4D523,7F8A3192E2A8F3E7,0001D13AB3818F25,7B8A6EB12B9F1225,F1857938589F4134,3FA2C0EE600DF50B,48050B7775E745F8,64984E77DBCA2D1D,5B7AAAB42277724B,0001C0D52C6C541A,4DA86C1BF5825BEF,4447E91BA674CB36,B61ECB9A6929FE23,680D31F02DD89654,7BBE189B303771A4,D294BC2DF327BEE8,0001A4019E23BFCA,F2B377EA37B1506A,01D95F8FF21B1110,4F482FE29FA6F69A,295B6EDD37957308,99C5BE212C8F7B9B,4E3B84A4178883E2,000024715C6D7FF1,04E423D56B20EFE0,AD2CD1E6311B5EED,A3A483787005D938,31563EAAEC88C9A0,387B01CEF1C96C82,9E00009F4EE23B00,0000AB9F3CD89C3A,761FF41E7077FBB7,C09698D1E04F6B9B,E6DF4F068A2624D7,FB4B380814508D91,9AA72A495DAF9294,667DCA1D802C12F8,0001743D89B1DB7B,6C2511FE793C87A4,214A7F7E817E56FE,9207470D9D789694,919AE39F772EA2EF,F49C87F4EF3FF65E,311247B421C81A81,0000AC0D17FD2A33,7780DE1297A6048C,ED451ED325570229,C21B119DBF1E35C5,1BBC0BAE6C00582D,C285039E8174732F,8F626524720BB0DA,000213234A41D534,DBA4BDCE343841E2,0DF1D8BFEECED0B2,C09907089D299854,53850AAE6A5F1976,C8BA9010859127B7,B5B321220B08195B,00009649F8E7BBCE,5280F8C4B974180F,826B9ABA6E72D7D3,907EA2DF19212A5D,74726A9C96A3CDF1,2AC72754D6FDBB28,54A638C81C61E9CE,000055803B4DFAB4,A63B51A1DD127635,868888C56370EDB8,9C1A7FB57374630E,174D7B324F49EF69,CB8DBB4EE40B8DE3,4BA86979E3FED7A3,00002D4A9389B0EA,6D0C72D0ABACC61C,67FF8A8E24CA5C66,A48B31CAB70A5369,C3650E057CEE2AA2,7CFBB80FDE56A73E,34253E2BC7737DB0,000217BEEE6992E5,28C995EA8B7DB515,17BB5FF606ED9284,D60663CEFE83EBC3,411FD82E7BF5DB6C,A22A00A4211DA36F,F703991F49437C78,0001DA89B4A5AFC5,89619FC4E015BA53,15358E54CD8EFBE5,08BE4C22E6F5835C,FB8846E41326D933,F863CAEBE32412C9,9751D6F440EF5679,00006FFBC4D9E150,C78F6405D1903AAB,748623F45FAF406E,4B65BB434E54F5EA,532BC94DA7D73C72,9030EC04388CD370,4BEB2EC255AB0ED1,000179F4C66B7360,C75A01EEC1D80739,8BC90E58C2A1CFED,222BE3929CE2BAE7,0C64D6EA83FB8407,24D373920772D1EC,A43E3EAB72EC8333,0001012ECC941452,017B9230B923061F,32E03B5C2E8DD065,C1606877B122E356,8E93DF02FEEB6201,CBEC251C7045CB2C,A0ED8B6DD90264B4,00000A49B6A4CBE0,FA4487E5C84DD509,8216747DDE1AC07E,5E3B7EAD8574089F,A9C901BFBCDA69C0,D57E8EBCA22F28F0,F9A3C461943FC545,00010E787F543E96,B0355AB8804264C7,9CC22DE6EAD0B098,DDFD575FB89505C7,33A6A5D1DD9FFB2A,EECFACA65A25A0DE,84E11AB51B1EB388,00011628BA8C454C,B311DA319C87BDEB,B62F68B393846E62,111CF1C759433289,09960B4546CB7EA4,26DB3AD56381C72D,CB64328FC2E2E667,0001FC3C4BADB765,0ECF8097CE63933B,E78EBB33C31AF26F,C6B001115BF3AD46,097382527C3AA6BC,73BFBB459947175A,D09449417CA0F9A5,0001201172EF84B9,CE9A341D3F5EE721,633D0F0019709CE2,077A185D0293DD8C,F5BFB29143FE07DD,7E63F00BB78238B3,88F23B5B78797299,0000C2DD1E20DEFE,59620B3CD0EBF862,D5F76D198AA53A6D,B7FA31A4DA8481CD,BBA00A7E007E524B,84B7306FC33D44F6,B885BE9FD4DF0FE3,000079EB6429A338,F59222A8501712DA,344622A350BC29F9,B973920019C6567F,9FD7536A0E6FF9DE,886BF1591EF8F7F9,4A7A08E9C0E29C22,00011902238AECD5,B350FE03E8F41D95,40C793DEF3DE86EF,81722403D2995BD4,E35A3205EB78194A,910E25393B79A5F1,36AF2D7A574F8539,00006171AB20667A,9F556F28F04B8AF5,D954C0F5D4045BFB,61278067C7AB476D,E944AE563977934A,1AFD028E34C6E657,4A8BB659781A2135,0001B75189666923,574899DC97A813E1,55C8BB3F5B52B652,191DA0889A990323,22DA03EB21881C87,3CF3EBB780F87937,A65005BADAFCE8A0,0001E8B504E18AFF,44D7F3C5D3EB5023,61CF2AECC1B47290,A38309A4CEB91FEB,284A10C4ADC8B463,8C4E51B6ECBE42C3,84E45E3ACCEEE4A5,0001C26E373106CA,B0C1E133625AB786,F449E81491353F13,67173B11177DAB90,DEA134902F6A712E,86774A03417C9689,4E74BF7C73A4F33C,00017CCBFBC20594,DF976ADF4B23D154,71C7F5D5A481EDAA,ECBAD981EF90D05E,C9D72E3AD79841CA,C2F777CEB62BEAC2,514850D8A2936C54,00011F44BE04492B,1DCA40AB41B12D97,A1D7034AC792AC04,1B463C0A22ED6E00,2555C36E8D18A958,22E4A0C932237152,B04C3675A7CF77AB,00019024D1766A3D,74DFBC9E22925AE1,6A5A25D43D671536,9958A07031ED7B2B,F734011F974D99D0,6FC3BAB789C81D83,161789AD5328553B,0001492CD4ABA699,76C8BE7BF72FD49B,2604B829C961F1DC,3548D92400A789C7,CFEAB16D97C483B4,9FAB6728CF360C8B,17F6314503846EDD,00018A5C563F0A1F,CD640C77C65DACA6,4E1FEBEDD788A70C,8CA02A72A0EB26EC,BA1AC0936CFCA88D,0C127B9118E920A2,3B8BCCA71AF7EC87,00000F0EA89BE6DC,80F1C7A8DEDCBCE9,DA4FE804CAEE8CBA,1CA935B2B27A6693,4FB4BFBCB65A25FE,C0DEB252574B960E,AB013D72DAC23DFC,000189F6E408D8CF,1E7AE47F67327C79,7269F4FEF748F3B9,D0BA9932FB051717,725A0710DCEADECB,1F9DE0E722EDD646,3E8A184B22F39C72,00004379B5E803F5,908C0A3EB989C58E,3B2727E0BBA1F02B,3876816F1975A5F4,3D06EDDC9E856897,F101B54C04ECE492,19FF0C8DC7478E08,0000404ACBD7D000,A2E120407ADD444C,4FC8D9A4D452D6E0,BED9EA02AFBB8522,6AC15337A39CD56F,E072A0739629DA5D,4B36A8C8F14BF4CF,00020AC744409C26,6497BADA2E023E17,EFF47761C6BA6D7F,B35E116E986AE684,E27BD223FE337358,F516990E5466A32F,392B6522A9A8062C,0001A1C886744341,8164B768C02D4675,9D88C0F4181FD7C8,45E1653AD229278F,5ED0C4CCC562925A,8AC21E78B1F8E928,94127AAE19B1B77F,0001B67A61A4B5E0,A8B044C66C65E682,58D15CEE91FF3FAD,E255BCA7196D2ED9,7D800C065D935C02,BAC49B96C85A4F37,C31685006573C61E,0001CBA997EE367C,F958FA750BE9B457,2EF86DBF1836B4F8,99F58CE2075A1970,183D7C93DF87CCC5,D03A96B74A59B41B,83DED3E4241864B8,000227F7495C4E10,2E88B26FF7185A0A,F51C01B96799A553,3C0923CF20082111,FFBDCCFC70206FD8,1EDC9AF47A924907,2790D1533C6FD156,000184092860A877,9FB83EAB4E690697,A1F84A86EFD53416,47921E8D1CDAEA61,526E648F124FF127,C20C84B9BB8466A6,88A8AC021173C481,00010AA4DC8CDD3E,CEC4791F72B38AA1,A32BF277E373ADEC,7976212917FE8659,1180DD0EAB2BD0FB,2564C9C5B9536628,9DE12F350FCFA2D4,0000EF95EFE37A41,1571FCCA71CFDE98,80331E45768F0614,AB72F3AAA10748E5,7E76CC125A8F5A8D,674CC112B31EB6C1,635A3E84F5AEAF81,00019F20B380CB58,7BF176E9CB68AC42,D5EE710F3DB570ED,5C241531819969AB,114D1685225F8DC2,9DAE31EB350CF235,515707632DC237A4,000202B1BC5CC125,1BF5B344A6EEFA0D,A0D14BB2C2E44F4B,D2A624AC61E0571A,267717C17EBC0B48,03E9895D0831FC1C,8F87071782886AEB,000108D51509BF78,FCF0CCF6C5AF342F,EC9CA9363EADF617,D6F625985A0E597F,AEA03237CED636C7,15D35775DBA79FEA,902FA8F363A73DAD,0000B7848B5943E1,3A5D320171FE697E,B5BFD5A90B1C6646,5F64E8C0CDE8E105,AC25FF161CD79EC4,842AF7C5A470CA76,97B0C552BD4C4FAE,0000B9A508E50809,B9BC2E1151FBD82F,FBCE2A6629186478,FBAEECD091A817CB,032605523D714485,48B1DB685DA60998,F124929B81779F40,00003873C7B6D767,1E5D7D42A4567FC5,3E43ED29B7EC63A9,4F1608DA099C1A10,A24B02F6337760F9,F4AF0A8BC99933BC,449F1485FAD107AC,0001F16EE07BED9A,FC5B43C2AEDBB28C,05E777ECC0E971BD,2D5162EE498D906C,C1E9013993863C81,9D32EF7CC3F1B507,F1238AAF8A6780DC,00013A4BB041CDC9,E91F0F6F2CDA5C35,F616FAD27A941FC6,DE849468DB3E52F1,58B84EC40AF07531,76E636B28F12C227,2A3F245D67783766,0000FDC2D5BFB8D2,97602019EEC98C5E,F860DDC3DD4DCC02,711DBB839E0C0893,354CB77E68A64E3B,73EAA643C1BFE1AE,ED79641E4BF5E99E,00019E8643DAE376,E8F07B7A9C505FAC,068CB1D7622AD32B,A0EEAA01618A445E,F593870CBF06D1DB,4B2409E6ACF8E844,2252577E3EA6EBBD,00008CB1B390DC21,2362A5D0975C4F32,938742814E9B7C3B,1196EC97799A6C6A,C3F9622EE69A0217,EF7B960090686AFB,4D760B9C73011302,0000EE96496D1F03,82A854E009B107DD,25871A346A4D9CAC,68A8216F97A0B5B7,85AAB71C43E785B3,79683DD6BB731211,0F2EB72FD1D20E45,0001AA811CD23321,8A14A8764597100D,8C83C099F194AC3A,1600C07AEE4A092B,B4EA647EAF2F47B1,8C11935CFC5F4AE3,819FB9AD814B2642,000073CA59FB9C4F,26D150097BC02E94,327922AE0CAB73EE,736D37AAC8D0D8E3,A6879A3EF7D99D99,C775E0371A355761,46F3C12CF65A1F54,00006A6B6ACDF5DD,66C9F1C6C511FBCB,1C499C8EC3120186,959CA138955E71D0,006467AF8AF49259,8DAC101CEF156156,52E6C2C3E37B94EA,00000FEC0347722C,85DA5B77818614D9,E191C416FA2DBC38,60F208F2A7940400,EFDDE525B3DAC6C7,A5F541F7377C8A89,DC2498875B04F2B6,000227255EAF53F4,446050CC5664F4FD,5FDF63F954CC3CDF,D132BD10CAA78683,D995528EF0637FF5,D2264C7713B0832B,EED093EAB81537B2,00006A8407FA56A6,C144D76AB8D43678,3C98ECF58089C1C1,FEA2997490106B8F,9580B5F3CEF57058,83214178ACA73DD4,8AA1D7E69460B7F1,0000E001131E1A2F,B6E6BEA5B599FB12,EE084B0B727ACE2C,D654B9F76237E67A,7F39C15D90976B74,D9058F66EAD44FA3,3AF7A2C01A6FEBB9,0001C7C05B6DEE7F,9A67CABBB1C8C084,C304311FFC5F57EE,7927E9331B2224B4,F139C398B2F1028C,29DB4D3EB982FAA5,391E307FDBB02256,0000760F0D6AF192,00460350F950950F,51382952F83A8898,184F4F44F3028AAB,229C8A606895EF00,318BE9D25CB7ACD1,734CAD13DCD42D88,0000A5B1FA879B0D,C3869C60E19FBAE0,DF8020005C755187,08AD1E5C1F02C6B9,D019239D5178F7C7,5AC839E59F0B10E2,4BE987C502539B5C,00008A2F61CD9C50,976FAA36D439822C,0CACFBDEE4255FCE,BC2C690D9DC103C4,27736B1C19A4E5A8,1D6833E9E30FC54B,5203B3BD8A5FC66C,00016E0A69521CB6,0062D18C80071837,D7058BAD69CC7E08,AF8CE0D33BFA1766,100CF6432E498A62,E4A98FF983868CF4,8A66799F0FF0B2BF,00000A623E603DFA,ACB1E3854E7C8E95,FEF5D727C51F6AB6,CD5D083B373B0093,69B1949429FE23D0,C8EC2FD4EC15462A,C884A6FF402549DB,0001808E1911AE54,25BA279B4AA2688E,092B2C1DCCA4FC4C,34E4048035D2D7BF,879AEA07DA757BBE,AA0036C7F50D3213,416597DF1E2942C0,00003A2A9C936FDF,FD9D85BDB8810A91,FD0A9FBAA7BAC4F0,DC0F26DDA58EE34B,A0C4889FEC4BD8A8,8BDD6397C973C3E5,C3EE5071FD27F60D,00014FF3FCCB1F0D,3D7A6BCD61212C22,E67015F93F22B001,1181450648364685,46C357A5B96AE4BD,C3915F6D224E0126,70E26F9BC6B84E5B,00003EBCD90212FF,E95AE847F60BD03B,F175D5B185B8231F,D724F9B1A4226232,1D8A9CE7E5824045,BDFE64A9ECB1072F,CD0082DF6C1A576B,00009AC48C20EAA2,C17E744792956610,0533E563548B24F9,74F5195B1ED6E450,38ABCF83A6CCFE82,8D806BCDF9C42F93,8F00E2B2E86E0CC1,0000764D94B4EF3C,A4DCD033E0E0C89D,88483569D0298DF9,5E993A74F8C6B006,61966A154399D3BA,90D822366EDA2744,DBAD69ADE04A4D38,00010210F2782A62,E9B1AC94CB9C11DD,442F6D226EFA824E,AB1822B72E838941,FC45A41092404732,BF435DC48F877586,E592D33768C5265E,0000E9820F2683E6,8AEB0B58018584F7,2019B4426EEABDB3,E1692A1E341C668B,499D76BB8F85617B,1415F3C8FA31E77F,45978F1C0E533C72,0001BA8D0ECFF238,2A4EAF5DE4A3489C,0638D10C82F3CC99,E774796890F4DFD9,902E028A299C3474,0044C9150F1852CB,9607310ADECDA08B,0001EF6A88CCB8A6,DC5F6706E17C43CF,B3FCB4A45216690D,E8D3BCC81A28F351,E23B91F0F609B959,84A6CB956F047BEA,ED802DA98B35D47D,00015E44F28D2D53,187918D91CE5FC80,DB7D912A4E7F4495,FD4C1209B5CA331C,75A9DAE2FD63F61B,F8FEF38C52C427C1,13D709F7DB3BF1F1,0001FD90F3F18E4E,0BB2FD912711506A,E3464E6F351BDFE8,6CC99417DD8E6B6F,01848FC9BBE52FEC,34B67B6FE0B16AC3,C8484B3A9950B239,000053124165CEBF,9BAFAA6042EE665F,0F9709C433C35719,FCA6839EAFC63DCC,F2497C386483E6B8,B9503452C175F406,05BA81357C62A9B7,00004C6BDE4E06CA,CC87608AAD83F5F9,8A0E2171291704A7,8E8E33E3449AEA8B,5B15D00B126DD0F5,8896681F797569E5,F6D21393D0491EFA,000064CED3B8DF11,3D0FA4EF99D7E431,0648D2F0267EE11A,271AAF2A26DFB391,12EC02E992D393EF,1F343CFB2B9DEF31,84402092CC68FC1C,0000F1D702A4A158,D2ECBD0E44F9E6F9,CA985D2115633CF4,74049AAB7278CB27,7A9C3A477495F060,22A6335002486277,CD6FAA36711169E0,00004AF03E23CCC5,EF19AFC5D7F655BD,E6C450B3AB99F8C1,3C77B9739F137F20,1DA2AD0ED01F19BA,5DE523E61B721FF7,D599719A18243799,0001DF43B460ECC3,43853BE60610AFEE,162F009BB3093900,FBDC4671294BD911,0ED0C81A21E84E09,F43F45FB066564A6,A75525612A76831E,0001AEA100BC3D23,BCA33B59A48702EC,57954ABC1EDD17B9,65D945C5F283BA8A,F37C62E084E1F810,B0819092DF10C6CA,B294DF1DD3CA9062,000005D85C9C85E8,6F2E4DCC358C1888,42C73EB0FEFE058D,0B9AB7A0894F9EC7,419ED91961BF167B,4845BC629113B218,C3673B17327C585D,000030ED36C75694,4225886FD26DCF40,EBABC67BDC035389,2D58996599D827BB,61799CCCD553FB48,EA65A3CDDE484808,332106AC68E5688D,0001E5E009557B26,85AECC869899D97B,00EA3C3F68E04284,2E4A977DB23A45DD,BDC0D15AA2793549,9C80558F9FD68001,85212C2112E87525,0001226710CCE487,71C458D3ED96FDAA,6EE2143FC36433B6,B625E7CC13AD5861,D251FE829F224813,E0AD752CD5C9494A,649CDF9B62DC5DE5,000088B47558EAF9,BDDEC7D96A54183F,C0D55B017C21D662,54010DE92F967402,807B5FA21DAF3FA7,50F8F19DB0A1AFA0,4FA7E71087D36EC4,000069A97FE33273,39344F7CA3EEA9BD,3A140B74C2DF8BC9,2B5BD70FE78C876D,B886D6FD8753D1CC,0A2CDB25B014409D,EF0CB8C7C9A68941,0000582787B406F0,B3F7B94E869B7530,2E23F4D11CE957FB,FAC436046767B2B4,5A19B2F4DCE8E88A,FE0F7E474E434F8B,FA27075A97C81836,0001C8113267E60F,1FC2F4C5B7466A8B,9CDE6772F765362D,9269D4F2A3AC48AA,CFB83E9ED9BDA26B,39741A05637E24A3,1AF0DB8DA95AEC5C,000101D2F4A993CA,6B95FDFB198F06EA,6017C10851E1C9B0,20C162CF2CB26538,C13DF801907E514F,FADD903DC4D836A2,5415BBB4D95CFF65,00021A42DD74CFB8,7DFE0A77192D495F,5DB6C9FED4B46131,E6BE7A51F3B060BB,3AED1BFA58935DA6,70BB56F77487D7B4,3464ECB5F5CD3F62,0000C8EB32B21437,6856AD443B65BD33,E6FEEEF736555771,A36A84CAC26D4A01,CA95135707D1CF03,27CFEED2EE18DDFC,025FBE35D4B1D2DF,0001A59B122EF0B5,8C3D20ECC1E8CF6A,F134BF05C99F95EC,51FADEE442FB7269,55DB03ABE33E148D,4007388A42EA532E,1CA88834FFF8121F,0001B58245E35CB0,7FD4F61682702EBE,45ACE219945906EC,F51D5A1023A3FBFF,76111D9850E78B29,A265EA8CE57D1DBB,864778BBAC6D46CF,000186C704C5BF49,31DE9D6578135659,5FC97387506C1F25,7DA1A257081A76D6,6AA43B9DA8C89496,8CD1392BE2966409,76EB8095DDC15088,00002E40370EDAA9,F5C31646DBA23C63,1E954CDCF699D6AE,9EAE78ED4C83772C,46540C942762A6A5,B4C47C7DFC04DD7E,263B23DBC75DAB9A,0000A0DCFB15ABC7,EF3CD9F8446CF645,151832651FED8AD9,BF9997B957A5D861,047CC291FCC0D314,FDDA7D8E7A10B82C,4A4E5AFA92E34728,0000989080EED296,9FB38AFC39B5A93B,2D1E764A537AC33F,5F185628DA759A72,DB10A3A94C03A4F0,C1B0C09E90BC98B5,951D3A1032715A9F,00009A7FA1962109,4D3086EC23517814,6C00BD189A976820,66D599FFA5335541,A9954D9202BD5B5A,F7271C30CD53C026,A3E5E3916FB3992E,000189F5186BD9C2,06517E5FF937DEAC,6828A4A6E5B4D987,57D2C1A3CBA8B422,F47CE006A49C29E9,62504640305BE023,7EA809647201C015,000195D10EAAB376,858BBBB30A68F5EF,138BCDC9C16C5141,FC8C5567455B7C26,0B8732C952F3BDDD,AB31632442EE0A06,3A0245381D1FD40D,000122FCA4B4BADE,EA9412785AB74583,24E00A7153A7B2B9,D2BC39648211F623,9740EE7C97454365,1F9A049A41A2C72D,C820C97EFAFAB4AE,0001C927B67C13E5,7A213C06469F23B8,5057740ECE308B4B,6AE7370503D1DDCA,7247E60EB9446BEA,B61317394C0EFA8B,B6D2FF230A5A5529,00018A4B78CA2751,C07B2E6240E39E59,4BA0F086ED928D9A,EBD78677B7126230,D3A9959937E259D8,C172111724112E6E,F776F0FF5DFF2C77,0000880CBA0C88C7,33D4A1AF0B81852A,52D4E025F1385D5C,ABF7BEF28D485163,BF46ABB7A0618BF3,846AF3411E74A89C,D50FB50598A0043F,0000D8D5BCBBAC08,BAF31DA7B2D3BC8E,657411DFCFE19EC1,FCCF69BC8B442A9E,5F91D3F2320C9F9F,7D539D4D24D808AD,6604CB6BB7077527,0000153730243C7E,A03A2C39BB8E32B7,60E0AC013C3AF8A1,6DCFE47D7CEF9047,A8B729C83AE9E66C,709D8CF244D9B593,D1CBBC4D6AB879E9,000059145171D73B,25F5540D995A2BF8,BDFF516A56A90EEF,F13096232BD18F4C,8E50987F2C5E4C00,A55E329979035318,B4857E03A4F4C413,0000E3EE0441D7EE,82205D908A465BFD,F5AEB77DC15E07C4,859C48733E1D518B,3C218CF01D0AD2D6,A639A81134E1D2EA,5C5439C12A1AE614,0000760F002099BB,A3E66ECCBB39EC5E,CB2C133607FBBCF1,0BD1A00C9F9A238B,0C0B4B9720675102,F1002B15872799D2,F01D7662B760A87F,0001F9A118A37E1E,9D1F75494B947C68,A44956AB085AF808,97802D6FE9DE9A80,7C0C2F46AA54997E,775858E1EAC6846A,D8D3AB4B239D7EFF,00005D4AAC8F92B8,2D9ED6EC9F756F58,DC91BDACA74B1802,11762AAC1C98B2D9,0E4F41F281F740F9,4EBE30A67259B6CD,FFB3C75EEFD1FAEF,000008AEE69FC148,E1F49A3F6B621FB2,992F2EDF2BE34425,D937CC100EFF08D6,6C162861FA27EC85,735C067979E5F5BA,67A70E8DB9BB3FAF,0000DE4A95F589C2,47A304EEDC25EFCC,AA577733F1B4FF29,64D9241636B1E229,557940FB5AADED7D,184DF10A261A729A,FF63E745F45C6A39,00004894BACB7DCE,D39E5021545227F8,EB216975C4435627,0C861B28A8C44F98,03AD04DCF5D9C66B,0900D2C58D714836,771B800DF443FCFF,00014900E2063F3C,A228BADC577C84C6,0FD6C3535DF91519,40F6F7124BE8EF5C,5E18564ADC76E1C5,B972920E949874FD,29B178F9BBC50F3B,00015C8FBFE5C21E,AE5A5D25A95567DA,285A8B6A4C679606,CBB751C8F950E8B8,8F2106D4126D4A61,A968855B29B05536,E14CE8323A623303,00006076795EC216,72A006C906BC8EB5,8991F188107937D9,F01370308C26E6F5,DD6A1B9C90752D31,348B3F89D5D4D391,DB284B5A9C38333E,0001901C8A6D68F6,EF3119BD0EE2BE1B,8FDBE17F23173EBB,6F7EBE6070DD6962,A68BB5C452FF2038,C19334398E8940FA,1AF63942829284E5,00006891C1CB21B3,0D4AB572A5A6127D,D39457050D392011,E2B9E421EA7E4E7B,EAC3E92EDF5BD580,E8DD75F1BF61949B,ABB7709A3076C15C,0001A23C3622D972,E6B8AF412AFA0F79,384E445D23881760,8187D8F8AA442D19,D721C030CA28D4FF,4D00ABDAFE9EDED1,8A7FBBC107348139,000057758666BADC,DDFE322F4702372B,673C52AA0E6E05B9,7AA8508B286624CD,2D94BC4BF71D4BC1,0C896ED17C931F3E,0A1B81D912A29A84,00012409DF9B92C8,CD98C984C623A343,8A6AD711330EBC1A,3424B011E3C18002,1EE9B9C2E08DBE96,5CA59C4964750E55,66ED2298FA645FC3,0001D3E5A58E9896,98CF324FA377534D,0C4A62A66D985D45,F2ECBC2CB237A4C3,5757F06DE9C82690,4ED77EC0A08E97B4,7740E6CF640C17C1,0001F242E2C93B06,F8408BAB9F55CBEA,B671A8AD4A836B28,338E22B134B7A9D5,86536C61EEF82290,F857783114B1CE87,8F44BC9AC00A7782,0001E0D2FAEF3EEA,8F8BC75ECCECD304,9ECF60B9CE46188B,46CDD5B08AE7DFDD,F79EFF5B89E0AB49,376E411D74F863F5,57E3A31826763FCC,0000112DCF55D7B5,3DF4748460D77467,9D7654BCE5207057,7041FF0AABC0E0AA,3D6DEE80EC938856,C6878946431D1078,B35FE6D6DC2D1ACF,000001B82C78A8B3,44362FFFA9527A55,68B04EAB1A39C25A,C139C9310AF3CC62,F2E67CDAA6D428EC,359773BAA5D2156D,D8FAA84BAB73F6DB,00004CBF4E1C744A,CCB3AD043B98FA55,715DBB802789EAC0,8ED6BE1053B2C666,54CA0D76B967E912,70CD10F546F4E1CC,C954E3FB8D31776B,0001F3B89A728CA3,740B1719E398697F,EC01D82EA620AB63,4C96FED3C19D172C,934FB6120CD9E36A,5EB927E2593CAC3E,15C3530B66143A4D,000201C82B950E3B,8332C71B36C04529,E647F34EAF6C1001,D51C42864B729309,9390D547A825E385,368A172A7BE7CA0E,67F163963B70F212,00010B9411BA061E,B75CEA14E8EBAD55,CD0F3F6D7D81336E,4A1D0BCE8EF6CE2F,0690656AC7465B79,E0B52242BDB39A64,05D4A1A120860016,0000446AEFAD612E,AC130E88E2B251A1,7C74C450A58D4C98,67511475788175D8,44E0937118F6490B,33F0D80F883710DC,1C37AF6B4C911B18,00017BCCE19F1A22,44FE951E3EA7B422,A37C96B6614194A7,663566ECB3A670B9,DB5AA797242BBE8A,85765DF553478A32,552F5C1387F5B935,00002F7E383D0281,5B1D909A1D22F0B2,DB6AE2E5F0C2469D,F74558AB50FB3BF5,154847EBA22E5E8F,DF3E1EF2A9BF48E4,6ADED035F5649E2E,0001F19249B8E7D5,84658631FA851F63,217EF19B9F62FC50,FCF592051774D2BC,D79B50C9C2D75952,393DAE0EE90E8E20,B71E39213E97AAB1,0001262CC187E0CE,79D9E7F932141641,7639FB7FB131F51F,79C49DAC7D3512D4,915BC4FAEE7F39F3,5E3403184435F08F,C6C04BCF7C8F5CE9,000203DA6FEB58C3,B54E68352B16AA56,726AFE527C3209D7,8037213488E211A8,926579A8E1C41167,0936A8578517C693,B6094904A09E8932,00010F2F4DF37539,A42DBF0C7BBE8C0C,9E3D0572F30A7EC0,958C284486BB2C31,FE9A44AF1AAF1931,EBC35815D4A3DE77,2A902A2986D193C4,0000706F41D2C990,CC914C313DAA1B52,34A98BE35393AEBB,20478AFB9494E54B,A7830B7E069ECA18,8E27ACD1C95D1EBB,B042E13019990214,0001B3467990E7D5,4C879446AD89A0F4,5F03339E881BB122,76AB32F87E2B4A73,9BFC1591917C6568,131A24702B68B174,E41062ACF1CB8E98,00018B9AE88074F5,2979312D32D7ADD2,30C1649BE4A55B81,B593AE42E9EBF589,173ACED58943734B,150B4709F9F73D3E,D41518A83EFAF304,0000D6AA71339E88,09B9BEE62A1EB5CB,473C3765357B54E0,E08CB24BA9401EBD,F69FB75E4308CED1,EDEA732AA51A8771,FF1EF086CA012D76,0001D476F189D18C,5BC49A2A33C527E1,455DA56B94F359DC,FA68AA5C806E9E7C,3656F8F1D6160BCA,0B627B2F48AD0458,2A54FE52684C611E,0001E7514D786FC9,F8910C76C5722BF7,43873F26741BE24F,0116598E0387BD97,B62A89ABABFB39B2,4412F8675A974D4E,2D2AC3EBCA63D259,00005A71ADC0A137,C9AAB50AE538DE81,AF2FDDCDE2885ACA,5F3CC951EC11EF78,4AB4773977EBDCCC,3D5473A135928727,177685722E1135B5,0000F556F19747AF,8CB8D09443DFADFA,CA7CD18E4F45155D,4E857012ADB175DA,CDC75DE5FB7DE487,B5DB6F89E4824D6A,78AB97D77F87E161,00006AE71D61CC38,EDF92FCDDC0F69B3,22054E33CD29F4A1,D20E17E22F89900B,46783A48D792E6AE,ACAC5FAF24B1A769,ABD83E01456862A4,00018E8F7AAEDFEE,5D8B3B4E835525F1,D338EBD33639C7EA,439BE49F066EB03C,BB48764247230B5F,68885BC65E6DD646,08366871A6615AFA,00017D55D26D7B5C,0C6E164E0CB86B86,02785EC516CD9DC4,52DDA332B2D4E3CA,C8A390FE25ACA3A8,5851C18327D0EBAD,D6E9CFAF53E78D42,00006D3B17E9BEBE,3DE570ABE75F4D2F,B30A5CA799365E26,55DE6DC64986176D,C1CECC6644E8A5B2,072535EE49093D6B,9E520F8C201664BE,0000C19A9E893A1A,840878E7219E743F,039DB68F53EA7EE4,FEC1F26B24283D94,228AE2231A867951,2AA22E1920FAE30C,631CF651608C7D09,0001C781F804340C,89AF5F30FE5DB82F,16DA0567B94B6C12,51DDB36C8B590112,EF13339C8A11EB54,FD41FD0D1EB1AB0B,B2B9776A2DD95AEE,0001A33C3DFB5615,BC42B82FFB15445C,CE0E1FEE0B5CA92D,EB0ED23538AD67B8,9021B731E7CF0265,8DD238A3B7D24098,C5648D6365055936,0001EC9AA7DCAF9E,BEAE19C66BF85F15,3FB7AFC677C35AAB,49065D3A134765CF,C23095116FF27C49,2777F1DE183475A1,AFA644C81E3AD290,0000DD63CC92A3DD,69F8646475D9D40C,B05870F3D6337E66,30525F1BF313D0D7,990A57F173D2868D,99D59B478ABA7247,39A25EE6DD42587B,00007E8DEECE72E2,47473EF7D079A9B7,38EA88EDEE3B78C2,25AF458653A2E42D,546BAAF33FC4B816,8F0BE7A87F5515C4,6225C049D0F7157B,0000BBC857AD71E5,941BA3DB7B5E7109,7626E2A7BAEBAFEA,7E30B54679B13EA4,E6C9E151B01BD742,763150C8A5416F36,A1DF0825EA859573,000173C262DA53E9,CBE7A2E3F12BD2AF,38A5CF8941774553,F04ED3214C2D0A6B,BA477913541BA068,80D8B1058895E364,1CA12EC144119424,0000406D70257429,805F4FA0A1B9A0D2,5C915B6DDA337589,78A688BB9BEC018A,220A64CE49070E09,822B601B4C602932,3CF4338ED857D0E1,0000EDF1E2D64EB6,03049ED4FBCCA2B6,9F97CE74CF6A0C6F,3460BBA3DDDADB53,5AC9047E9EDA8087,8924B07EEBCA67AE,5D4FF1098EC592CB,00020683A60CB246,E0220A65831D96BC,62781468636E629A,923C182863EEA071,EB3CCE42F254724E,1BAD92D19206238E,17A8D9454BE6F478,00017EA83C22F718,7797D6B17F965EE0,CBC25447398034E3,CB205BD37C27AF97,5BC8EE281BDEC6B7,7E1DCC13605C265B,B4FC4F8C2E95811D,00021664A2B8B5BA,F44C7EBD00C514D4,A3346FEBBDDC894F,88F7BC7AD27D590D,B303B8213BFEC2DB,6865370B74E9E69A,3CC0C76CA5778890,0001E340865375C5,CB3E322B047C0B52,51CE9AF6214AE413,9F732D883E2EEE2A,1C7FF250E06968D1,96BD3CE8129FB084,FDFAC3BED2B6BE46,0000B51460F511BF,43358239BCB9EE8B,954D916CF3DE60E4,16A181718FAD4B6C,82D6FCE9FC51C00B,53635F8773B8221B,982338FDAF574CF6,0000541661AE3EC1,8B9DFA88821814BD,D323DACE14D90038,BB151CE900F4F04F,E5965701DBFB7B81,F716FD89448F6DE6,5D39EF230E82E562,0001F352D096732A,C009B1A980F57387,2C17F75C29D640A6,1BC001C4BC28ED9F,A3AA7F06B184047B,B18D93BB27F4C894,9AA4E60DEE025E92,0001A342E3621D35,D8D5488AFB0DA019,B416982D249FCD83,414E7095EA3EF950,3ED9E9B782DB6C05,D847946C62FFBE5D,C31AD91FAF41FCFE,000002FF07899934,1893AA083E982B5B,BF581580CA989436,B92F0EB9CD6FDFFF,8A03B49F9D71E9D1,67ABEEEB37E9DDC0,CAD9F045ED162083,0001CD80808D9144,CB796E0CE98E1998,02453827DE907DE8,C1BB6DE08F5AB030,81144E89614B8950,983AD46A8216C3F7,752E7DD502FE5018,0001B1EE574691A7,26DE6FF4EF164CCC,E81A5570D7805943,84709D92BB34B34B,A331BD7A3EE7B937,6528FEEF6E90CE23,3032B937B08E2A94,000146D0222534B3,8803BAE9FA5F7D94,11BFCFFBF13ACBEA,A99BFD280A998C8A,BB699A5B897DE5E3,C4B1EC7D6518E2E6,EBAECED2971DF74C,0000F84F5239B72B,366B7EA1C6BB2140,A92A9D2DBD65E4AB,F2C72A5E4F043D22,EF50A12F47360366,2F7F76B221A8CD85,AB4180B4D7D4164C,0001542523BD673E,9FF5F55B6B14EFAA,354F1E30449E7FFF,03B174DF521ACA39,D609F4C8B3229347,08AEC61429EC7BB6,7FCF152C33B6CEFC,0000F033CFAED7A0,8D5A5DD7C6FD139B,CBDCAF19C7B5186A,C182B53C1C068CA6,23505BB5E9E621BD,3CA22CB43736C6C2,012F7B0827878F9B,0001453FF079419A,312F855212002BBD,FF4F3C97DFC2253C,AE7E1D3C0B01C2E9,2F852E17DAE984BF,60412AD6066726FD,C70C7186641DC123,0001834DE952FBAF,77D5985CEDDD0D16,896F81F196BFF169,B22CE55B277F5B29,D53C289B2956AE7E,7E5515D0A2D8A21D,923C02BDB76A9749,0001F050A03F3553,2B37D45B35227170,8F89D95DEAA0148D,064BF2F150CDE18B,452585C9B36C414E,228ED0E01C66F34E,9E7D87034F27E7FF,0000F08F7C717179,FABD9AFEDF4A67A3,65FA193B0570397E,FA363B8E43198807,7E00117DAEC14326,8A84D9132515AA75,C90641152A31C6B2,00007BD95835D0FA,07E0CF3E34F3340B,842AD80BD1135404,B433B271343B66CA,6319CE48F3F19EC0,BC06377C5EDC1F08,DEA658F0245BB295,000115156A25C72C,7A2ABD0FCBE0D709,ABA0CF2F46441FB7,C78B68E63C8F168E,B6E6DFC3897EE0AA,1D39AADDC56FAACA,4D16B082774510E0,0000739DE70F4EDA,91A758A749ED2CC9,AA12C2679CB50096,60FF52B79D5FDDC1,C8E7A1C9845B3EA1,D3CAB86BA1B1235F,B2F9E87FCB77C7C0,0001259361C11DBE,D98815F744673D2D,F6DB2D8FFEB5C5F3,32F3A2FD336289E4,136A1DD0394C9BCD,7E7256AD3027B8EF,11D3CC397413B121,0001D12C4C43A1FA,65F258B388380983,DF2856CBD5354951,7EB09017CB5DC89B,EDD96DD547AFF391,D7F1F4B9529F1BCF,8BF24EA8B9D35E03,000122BD01900CAF,B58435C42B445EA8,FB277EDDB98F9406,DB226A156FEA8A79,54FCA892B640B6D3,EEB3B41127AF3193,8F5AEB945131B825,00018A6A1EF221D8,16FAF5854C18C39F,7DAAEF9B3DFDA298,C0BA3C887373546D,994D52D19781B819,CA357E423B77C1F2,2D6DDAAF64CC875A,000137CB3ABD274A,3A7ED4D98DE7B16E,58CE378E227282C7,D51A961EEC2CF335,CE9F63644AAA7D32,1136845511D7723E,BF91BF9BF2498681,000160DC78B94D27,D4E6BC1A0506D9CF,D2EF00FF38B88804,A925230F9A33BF97,7688AF5A33A01AEB,62D5051A31674ACB,982C2A41158192B5,0000EE92EAF8C22C,7B03854F051DE589,620EABF7081C1694,DA6D7ACEB41EFF1E,8C3EFE3FCA877C42,ABE82094C05206DA,E6467DFE86C943BE,0001E981FCE9C4AD,69D6B6D1CBA1A21A,F6D69D6FC6CB1746,0B118E174CC344D6,174148ACBD1228E0,7C8CDEA0C8B2AB50,E9BFDB4A8130ED30,000105B6A14DFF0E,F059FC459D5E7C19,29EA4F7619FB14FC,898932A92E602C18,0A2CFB8FECC165E4,48F93481001F8B15,0EB86C11F38AC648,0000460BF51CEF1D,DF088AE5987193EE,3E923DBED0C6C7DD,5D5AD459EF1C471E,457069CF8EF5554D,87FDA1CFF6050221,3233D812A6E46279,000165ABF63939DE,0583EF502E5536F6,EA6AB7FE41ECF01E,18FD0B025AFEAB91,3A481B88B68DBDB8,E4DEA0E2B3BAA4EA,03254D3C77534AF1,0001CB921D9438CC,8DFCA9F10E122B30,C604E1477E74DB10,8FE626BFEB7ADFEE,B2A20EBA2097798A,46CC10B723102646,9EC525998D16209D,0000B9C9343396D0,9364A17E1A86458C,C762F255026E40D3,F766B9AE6E352C2C,AC8DF26B05CEAC7A,22F64C0BC874C96C,30084318BB06C39E,0002134C9964D2AE,963B2169A8453A26,D779A5AB20F29DBE,4E1E426015DD64AE,B8526EA06B09E49C,FF7C2F56AB950097,8C430ABBC47A1D09,0001BC71DFD92BF9,8AE68FD81318FF8E,CE68E68A7D23B6F6,F85027A10F3D8A06,BFF1D4DA1162C718,386E6C2945BC6C96,4DCD83955C76A5EA,0000B2148C329ADF,80C4BF1D4BB4F60B,150EBDE869D79B1F,373DFC572D08C0E8,8154339F754F4F02,4E8A2F393E8BDE5F,5019304549E4917A,000059AEC46DE6AE,7E91710BCFCC75F9,CBB7706C172D4B90,2921D427A15E4974,64F41786CAB58F78,20C78A53B36EE626,F7A2D537BA4C557F,00006D8AA373C0D1,9FAD52B0D8F6C552,28C38E9E1BC330AA,3A16F3990B8720CA,B0A93B526D2958C1,3C809F2607873AB7,BDF20D45CD1A5F27,000128A133AEE011,43A1D6D930B83D47,CF3AFD93B53E8F43,8BF28AE8D9FD20F8,7958A33D58B8F7FC,D2B2AF55CD29A510,ACA93C0B0DDAE739,0001E09AA2AB9232,3BF0A2E02E4606F4,91712125C0F37D67,15C6593DC04237C4,4F33C4A41D9AE336,D69239226F811C74,4C8E750043CAB269,0001361F06226DC7,2CE80A610D7A01C4,F49AC9929D995C3A,E1C5DBF88F73BB66,D0522E324E4DA59F,C1DF5BA5852D08F1,D8387847D74CDA8A,00012B98E448C6FB,D49D8BB583AEF9AA,CBE7960B2A8C6301,45F038BA51ED2867,FD31F01690C7AA03,6A2E64DA831D6AA2,2F70F15FC28EE344,00011282310A74A4,33883E9822B178D7,B175CE8866D94306,87A0BCA5C92133FD,E2A8BC975E4882E9,79B99BAC23B9298E,83512685AB58BE08,00004EAA03BA6E94,CF1302E6FCC960C9,D3DE8806AAF27ABC,63BDC94A62C1FA64,71CF3A2C3A8106B1,913F62B8D5F93D3D,7F132D94851A571A,0001839C4EFDE7A7,FD672E133636A0FD,83B8575BE225F3D5,A9520DCC5DEE0E38,E048848B418092C6,E181374127848EB9,C1E10A7DEE271287,000110DFF41A2F4B,423B491EBFF0F6F4,D294DD9137E4DE57,ACAE1FBECC4EF057,7D27002876A6A328,FC2A204358081BD2,31BA3B73AEB96744,0000AA901DA61B35,295741240979CDD3,CBC36ABFF5FFD5E2,6968A0D2945653DE,34C85FF22BD40E47,936F8FAC926C2F5F,C0A8FD3640A9B7D0,00022AA5F5EFC93C,7AA3AE0A1B7B9F4D,9D1ECD81EB4EE358,DBF0EDAA1910588F,1C051C3DC24E1129,B481D61993B91574,1C21851CFF912C15,000116912EAF3B86,77C5002717E014D5,8FC0ED74AB085511,9C59BA94DB253CA2,93CC461E711B39A9,79AD68279F13D5EE,E6EC95BFA83F5A5E,00005953CFA51955,20BB6C661BE9941C,79288470604DDFD9,5BB4CD7338A15423,F1A3F36D2B60C879,04527216B63D525D,C57A2E113CE87E5E,0001416BE1523484,6804569C431AC569,F1453936A2B5A337,F625497E63D9B436,2158F31AA0434E3E,565B25D09C722074,997EB591055B3E67,000031FAD984FB8C,E39936CFE164F744,E418145957D6DF5E,B4756BE12D455C67,F7A1036563948A87,6F07864F6DE0CB89,6A8E60E4F309A78B,00017B87BFFFA072,8FC0E2421F35AC2F,237D64EB7C7214C2,36E8BE4635613B9E,36D2E119301B9662,AEDB450F75920D5B,CD70E3230A445927,0001096E421B1A23,2EB9DC8FCA259C8E,4741FEB1E236D52D,F521BA9C322B1BBB,75C158F34D0937F8,9172BB357F5A5256,58A2B1412A689C10,0001BE807E18FB22,CF6B4734185AB3DC,53192E442DE5A368,091FF759B7028E89,ABC2C4983D4A04E8,58159CBB77BDE370,F212007DCAC0C80D,0002185DDD852AAD,EF70A3CC55641149,967CA1AD3882C893,6B33B1D11F758EC3,152EA046E394528B,4C189D4D79E83F71,18A0FF8ED0402DF4,00003C97A67D5BDE,665F8640B6D82C30,3143DB436D9C0885,6FC63F5C7ECCC08C,0A1907E5B3A6E397,F5A6395ED921A50A,9627469D7C9EAB0B,00021AF6720095C8,A14775FCA7632702,41CFE8985C682454,C8704CDFB044F266,3737655BF76FA233,1B5E7F184B796C77,0375AD9AED949CC6,00003BE20E8FB77A,BDA9168813B96D87,EC55198091DEC30D,706D49EAE61F53E1,E4D46424D324907E,1758108294DD7A28,0DD88CD15A0E6373,00003D137B9FDEFF,5C3F208F9CDA5CDB,F49C42B4F546363C,D55B20C5C6E8F9B5,A4EFB6F0AA58A5BB,55D3765DC2F0E18D,EE3A37CB5787B7F1,0000D3E95D7113E1,43D5DD45698CA991,8D1D212F6B0BF9C1,D3B06E3FFD71651F,F0F38395A2E4338A,7325F9906EC941B8,B1C984EE0B94A2AD,00005D2F9436D067,09876E267CAD5D0B,369820CCB1E3705D,A58C9FF4C9E4FD90,C505F439471844D6,DDA28340927E3C1A,642BCFE6432F75FE,0001D142F181C22A,1CC3C750177EDD19,7E5E8B4EB69E3717,D55822D37AFB3657,EE181B9AFD6C39BD,753E9B9B9F867963,353F7DBFF083C398,0000A738E0899E0D,7F0C997933193517,3C169A33FC859D35,B1E502220307E235,13E4AB5C3E6E7579,EB6D769114150C12,914AE707CE24BC57,00014EBB9A365537,C849D4249AC55C9B,324944E3E10004C0,F5D3CE0C5F917FB8,F7DB0C3777DCF392,878F33EB03AC27BC,3A094C2F6C71D90D,000137C24B40A2A5,79EF7BBFC6326FB4,6B79FAEC29C748A5,280C90C4DF72C810,E762F9C62DEE647B,8710B6A695875247,E6F2417372E15933,00007325B0A90262,76023DDE0B3C45C9,DA80C36A5B058EF1,61772146DDE98F62,EB521DAA58325F3C,E62DB54591569BE9,4FB14D268E87B617,0000BFAA858B5CAC,D2FDA71CD6388DE2,2D408E9E9B247A4C,DB7F2C04EFFA8EAE,FDC2CA4E729F805B,175C4078D39359E2,DAB3A1C00F507F93,0000BFFAA4968B8D,F5A069E4775B551D,C5503CCFCAD46C15,5F1AF37C3F8B60A2,66DCC26082CD681A,DCF73F5AB7F6D4AD,8F65738577390291,0001D40AC21E2030,C3897B3261CF14C4,3C5AEB9058FFE92A,EE28E88171BC692E,CE29B0E457848DE1,5B77FA55F86151FD,0A53F633F7B2A2FF,0000A749A6A7993C,94096C1192111C18,92BAC2563A52A2AD,DDD1DB27D96E9881,134A0744E53F2956,4069D678315DD3EE,81C46DBB8EE966C4,0001CD4DB8C55F43,AC6F5BAADFCFA3CD,DD7972CEBC2EBA1F,DE55A94CD7D41699,A3031317A9136FEC,62F871427A776DA5,19C876B37CC7EA89,0000025136D54E3D,DA45EAF296EACE4A,1217EDDBCF733A0F,B0050A8AB0D2C513,3EE84B7F42E3104C,CA1751FE63E71DBC,03630556E48E9626,00012E8969607A61,5F7A02B2FFD4DFD3,7F25C56FE246A155,FAE2E2343FDFC80C,7CCD8C216795CA56,F9C881FB8394AF1F,8CA40930975A6FAD,00009FD6B7A1943B,C515BD1C79D60253,C462324BDB4E0F63,6901D5F40BB48D34,5DF97FD6046FA89C,EB4DF411FE412AFA,2F5A2BAF590B7D5A,0001139AF00E368C,1C0F6B3DF1E1AA08,EDEC8BB8AFF6BBEF,46C5E8384B1C01EB,9DC6E47861082462,1C5E6D030E74DBBB,45A8D55B85A98603,0001673DAD08B73A,66BB79D307EDD27B,065B9388F35A3051,FC846D0443F91DE6,0E9771ECBE3C2C72,DE554752E479B0A6,6E6B42C06E717B2F,0002104149E55743,33D0C31CF4803657,C65DC5540DE4052C,D78980950F8E7B66,7CDD74D2D7DD30F3,107DC282BAD401FA,0145573AAF347598,000038001793CB89,FEE97C11E4835D60,E8E826BDAA55AEBD,74F995281FCDFB82,16E830B445CA62DA,C564C8BB1C6CDAAE,B3A7048E5B6B9CC6,000217B322EB51A6,43B26D8D6BCB8D11,6A79CB7C8C18AE41,F0740C750D60DCD3,E25D588B4F9F292D,2A51D108A80AFFBA,E765DEE69EA0960F,00014C79D62E4C2F,FB17A7F5F253C45E,F70A4B0BDD1A9716,B0C84B1EF04E5D7F,724D4218B86180C7,272CDB21CF284402,DDAD7A672FD500F7,0000832D8FE385D3,E6C8BBEC7130D409,93D4182C185D9DD4,50B04234497EF25D,17F5FE346DD2D20D,8E5C867B70EE1B0D,9A1BA122E655DA54,0001AD57F922AE94,8505208D4D1925F4,23614BF8EC569A18,A0F3DD01795B67EC,3DAAD5235ADC9587,C9B9F39B8CB473EB,97B823168B399C09,00021C95123EB9E9,A8151E9E667AD66A,544F42BD2FF76EFE,44929B0AD062C635,DE61BE63DD0FB3BA,AD39A11C2D7C1849,BA34B4E2CDCA42E2,000051EFC24AFE0B,8A63DEBF6E79003F,2B0E8D653029188B,1A8EF1279EA0E7AF,1DB28F677E8C9807,7BA8E8A5718D7F7E,B83F1FA6BA960047,00004CBCF5FAF783,C007F813261216E0,B0CE64508DB5451D,278BFA7439801BD9,FC26C2D728C3A1CD,D7F0DADF63C3EB69,0ED81AA717FB0900,0001675C54676CBB,14C81BCDE5D8D693,FBE7A90DBFE9C40D,091A78244777FD37,C9A24010812329BA,AF25DBA1954CA774,AB80273A36A3072E,00006823C4E62FEA,1854D9D3DE12AC06,950E56EC477A9A10,515CEB5F27192A64,2E3DBCF3D2A3E506,3792736898BC775B,B2D53ACD7A3FDFDA,0000D5AC84CC3BF9,DB5583B49E01A4FC,9078DB10146D490E,4C54355276D1CCBC,AEFCBCAF9729F800,115BBC1E2FAEA91D,DF3913E9EBD3B6CE,000122FAB30DB591,1B82D67CE37F7D83,1F938EA6F4B4CE70,A9185D0DAC200CED,88773CF4ABBA02C8,786F4AAEF81BE4F8,DD360DB461542FC7,0001F83D6AE483F5,E60CB0123964B39C,9CDF42F3B4D9DC79,97F344AAE7D7A968,C5709ABFCE7C3D10,7434DB25A0662316,3BB07EBA168D95E3,00002099B9F07414,1DD958CEB4AA4751,2340FBBC032B74E0,D3E4CB4BFAA06286,3675E354980C1DF3,1451B8B92D3704A6,9DAF8FCB9760CC13,0001B41D32DA8F4C,073408AF8144574A,E952D18E82AC29F7,E2901AD2A80F51B1,46E0B653E6A0D559,9236F94C1E86818B,8BC0610353B2FAE9,00006C2CEA2F2CD1,36CE8798FA3FAA96,F2A2DC0879D24EA6,52147E57E273BC20,ECECE12378A35034,5D3CA219DF669020,ABE1EEDB6F9393E0,000051727C9C1D10,163A6F23773EB673,9253ADBEC7A2FBC9,942183A38FC63659,B7F19C7E3C901684,95CE00C1778FC810,942601DFDD26EFBC,0001DA11DEA9BC91,48104AE1C2DEA44B,8F4D02641BB51F40,55A1DBCAE9199FFC,A482E611EE9552D3,BE249B1650BE3F92,B5A44E1D2BAE3AEF,00010DC35631365A,A1E5ED4F4AC6C43A,D7C9A033F90BD3EE,D32F128DE3CED018,9E635A51B8B98055,3F495DD5E29B1D52,A5084E966212FBCB,0001F893AB529EBF,916E585CDED1F0B7,A391BAB711F9260A,26DBEE77FAAAAFB4,BA5A8EBE11204C1F,C235F839819DA4D6,09654A39C4FE50A6,0001B1888CDFD0EE,FE77E9C14C910E4D,E611CC89FC7D8E15,F4B94D8C4D02347C,340D42F6DEEAB600,BED598D503C7284A,0D62CDB3DEFF1C42,0001DF579041858D,D142547B46A05359,C8511663CF8E0216,E1E521D9EACA9D28,83ECF1E901A5B415,BDAAEEAB08D0C9D3,4878C02B76FE4B8A,0000ADC1F4AA15D5,A94DDCE6BD3C2F2A,8398B09749EE70BA,8F5C8E4AE529832D,4F911F1DC4FB9959,376FDA3E39F09914,E7417078E4A933F2,000011BF22D1FF40,0F618423B5C596EF,DA01D6C09B33190A,42879A1B599829DB,7BAECAB77CC5E3BD,528A77C174E333D8,CB83306990AD21F8,00007F00EF1BD60D,D52BF021AF365A70,424EECAD136DA1B1,A123D915C8B5ADAB,0FB0E0D1FCA587DB,FD4D32336C3C5EF5,0A75C8802359E930,00008731E3716B59,A7DE48762D9F842D,FB4E7941C41B7D6B,78B57B073C2FEF83,C655133342277D89,5483B01E3112B6CD,CBA06AFBCEA1A95E,0001875716DEB46F,B1AE5C4E0E68887C,5231F572D44F4A34,C32F422E9EBE867A,00A7BD524D72DCC1,A7B4C3C27602E660,08C3CA1E1CF98C7B,0001CD9A37A01A56,701EBF3D403D4F2F,94E79BCC53DF0BD3,5C64E882FD2740E3,133DEC3393CBEE4B,291AA73CA0D75449,6D68CFFF9007C093,0000CF99BCA824BA,B6F77B28C09EA029,107F7F9B63E596D4,A9FBFECB076F93D4,89D16E669799996E,E91EF340BCA4AAA5,274D35C55D42953F,00001DF062D5B15D,A7BD278EC8B69C20,249FD22324875C34,5EBF0E43967A0E17,9F80EB7F08777200,12F5343E641B8A49,A4623F96C1AE4EAF,000184C2F2574689,72E78B4D0EB8003B,BE4C176D97CDD61E,61A3E57598D7CA2A,1AB9E0DB1E4D7427,B9DC3FE3D68AC4D0,356552411060FD59,00001505CD1BF29B,B57357B8031A6C1D,41B255F8C0284357,FAAF24BC84527E6F,E2FDE8523BFA8135,982704A24AD1D261,CCD5F3C5DDBFFE46,000160C1CB04AD14,52F68440950C0FD6,4E50B57B336EDD13,D764CFF41CE02362,65A9D9F967ECD99A,37C6F9B26548C360,96B38E0B818C8026,0001C64272FB2BDC,9396C496BC5943EF,98F8FBA93C8D9448,AF7C9ABD3FFEA3A1,D35C7D6586882ADE,C511AAC584F7DC5B,E4059996C6A2B1E3,000233EF293865C0,0E2F30E271DBCF02,1C3901B79F9A0A37,80A09160EE6175CF,233C772144C7CD66,66FDCE2F6795DD6D,8F475229DA3BCF88,000182F276735452,B1B721D87A281A3C,A1AADB46609D8727,8E53432E02C5AD35,E32D7155D62D1252,602213EA3E42CFC2,B8070F3E83BCE3B2,0002088189A6BAC6,110239F8D5285CC6,96D8C3F0DE9DD91D,EDD5AFA6B99BDC86,81A738EC50BCC076,F1137127F4E4FC0E,0E0E56FFBD736E53,00020BB8621A385B,06699D9A56501643,F9F23D62F07D5832,5A6B21DE5B1B6649,9A4B66F65132E269,14B127C00FB6C943,A9CE2B2B36B268D8,00008B431B2C704C,48E84A4998C8FC2B,8D8FF4664325F6F8,29E6EDB7B7A7C348,C64F9A5BD00FC18E,1170878CB37772E5,138B9329EBABACA4,0000E302E803F1FF,7798FDF3838373EE,C3A48E6DCBC9A163,6AD5A56E04F7DF0E,6D19E018BC0C7D2B,AE976189A66062BC,BF8CF90DC420E06B,0000BBFB4AF48E84,7AE929360232B4A3,35CE5E0A013D8C03,3E49173662D98431,46ED81B4B156D3EB,E6187E9084D2BAAF,4B7197CE75A8E054,000184080B5EC129,EF3AE2F89A2D1D15,CEBAEC979A2A89D0,046BA7AEAFD87580,1C5A32260D925D11,27D3DE9A431270D8,87FBEE171CA24100,00000E9DB01A3C19,64B9434F36F0DBC9,DD50F06FF19C0F74,6D260C61EBF7A3D7,0842E41A5A03F4A8,98FFBFEA75D13EF2,5E3EE0334012DE18,00014ABF41AC76CA,4F3A12DDA2B57319,E1680E56E2ECEC02,B7593E9F24BC78B5,48912306D0E6582D,AD576F0D52054969,28D19FABA9514B98,000048AAEC323D96,78E6BD0C3D073D97,ACB7DEDBAF1739BC,8768A1A90C4B2097,7EE3CE8C5FE26166,A5BCB00928AF5048,47B768B075878635,00006A3CE0373713,03ADB9634E593DBC,102703DAC197479D,C0D2726F6FFF4739,95482A4BC1AD0A29,8C2557E95BBD8F43,79B2CACD5FE83E40,0001DCB5081F0AA8,824C4D07D2F40DAC,E2AD257A32F60759,51C0B55F0E5B982B,3A7FDEF7BE774F04,98877BB40A507145,C69E949D71DC8CF5,000080B5F86181A9,00533DCCEF1A8773,04CD91FBFAFFB86A,C11698C1E6B2176D,0B1C9A6F4B03EA9A,D3D091357E4EE9A1,D8B2F9E071EFE8BC,000192D7829F4814,2FB33FC61B9C05A8,5DB30CDD784309D5,14D57C31355E0FF6,D957857DB5E7CCFC,DBC324FA1284433C,C291A38A98D02C3A,0001BD17FB67BADD,F6D705E43FA54790,859B8EFCD8B1BFAA,A70B94F600A6821B,2D7F88F7286B7D26,E19015AAD0F88B91,D70B08AA533DDE29,0001E62C82D7FBB3,D51B81D85C05A683,1D08FDC7E788E81D,372C797D51ED5897,636E4DC3F6223B9C,C2C1D66B1A37C210,453D9F7F17508370,000142B4D42F7BE2,2E412A5D93FD6F96,E861CC56E263B228,D59F98754DF53173,FA61E3F91902607D,970F1C3AE5EF6E6D,0C499DBD388645D0,0001A80FE0B5D590,74B34B6B7C66C5F9,19F9FB6876BA240A,546A1883C923DBE4,66948309B6AA4F90,86BA360F7CCAFF3D,45A802901A4F5835,000232C7BD2A46D7,053B361972DB450C,0783227BC80B4011,F8624E10CDF4AB4A,E12AA9397C42D8ED,80DE366ACAF90F0F,91EAC7938714477F,000182FF504257E5,A571506A74CB7F5D,1AC00A5C545B8EBE,1AFCE6D141BF8EC3,547642978AAE7183,887B8899D332994A,5585DC0B81F1E361,000210A6B94A9C27,271294AA7F92EC49,170BB80167FBBEED,9854D5D06AA1791D,DA70936057D9B5E7,6A4FDF6D2C5B03B0,99A224A954CF63B7,00012AB0BB21FB7A,F6028D60F72E7790,7B70BA2B906783AD,8D26E46119B92B53,81DC7297F3B40AC8,2A2FC3618A74CA30,C405AA697365DFC5,000062D0A1B19836,B20BC504AFE76EF2,3D96B6ACC66CE388,5E01B84774C4EB68,7D8C8091C2A49FF7,80BD7C68CD8C63EE,EC3F91B774144AB3,0000395A89AC5687,5A1170222187785C,63310812F84F33DA,F5D01DBC07B5ABC7,95CF5D0210E08E8D,FBABCF5D463B4CDC,0AC7D03363CD6537,00006DE8D2AAF7FC,80BA935DBDBCE374,545EC22DA3C6BB7C,B41612A3CCE03066,C1F6B19E3B21B5CA,E4D63503FF776C40,EDD415CD4274B7F9,00005DB86F6E23E0,8A6732A884B22943,DD6583E29EA1AE35,05E1A8FA5E342469,062FC4579BD1E747,D0108EB1306C3272,71896D6703C9C3ED,0001C5141D0F1345,E6D9E4F7940B14FA,FC45142EF9A6B388,6B50691831DD68CE,385209F2A5AFB8D6,121E1B2B2F6557C7,EA3F43D761442286,0001A51FC1A963C6,FF31099140935219,7E605F0889C7D2FA,656F71A19C7F6292,2EC062E893B337AD,40F691D465096186,5957983DE56FBCB9,000099F76684E456,71BFE026E2FB6603,A1041ECAF524630E,38DD3BB138A3BD09,F4BC93B19D7EFA29,959305C977835993,0874AF1C687958D5,000186DC96FF8019,5AF8503288ABC554,826FB6D11BDB9A8D,CD5CE62AFB7D48B1,37FDDDE07BDA6351,C18883E9783B8E03,7A19E7C922446A79,00008E047917CA13,FEF5C0B2FC42AF42,FD4BF1989A9D16CC,0E576B3466DD2B89,D35B28D9F6D9EED2,5929A5E04D011E50,515682720DEA70C0,000121EB054261EF,1064BA8C39308B01,4B6008AB3A2B0179,018812F04DFC6AF2,9CF4C5C8847B1DCB,25CCDF543E650FE1,BDE556AD5B6AC46C,0000E520408D6588,EF9955C77D6D20AF,BFD2C461E5E712FA,00FEC7D9BE95DDCA,37242F0908479AAB,DE245FA618189C96,A8585D9E403D2E24,00022C4AB087E8F3,AD7756DBB7B61B49,A0E6322370C84BCB,805CC42D3CBB2DEB,820ABDD1FD26963E,6095A2B93E61EEFA,C59F95B786520D53,00005AE2EA952C5D,F22F7E5C71968EA8,B38EC8DCA29142D1,8B8DF2854C1FC214,9601BEEE590A4F52,E9DCBD6A82705A69,27A57122A3D73A93,0001DAE2483BD003,FFF9C1A19A1E0D51,2BC685EAA27671E1,C29CC9806D703E82,BC5B5DB9D9BD32C8,896218EF4407E271,4C3C0B74FC7D132D,00021152E2BF590A,1D4A2298BB3B354D,0CD328881E749E5E,D3330F99CD0F2257,C8B26EC990E8C236,FC4EADA05A4C54EE,B9105E4C3DD5E777,00008DDFCCB8D290,4FFEF2B55EEA48CC,FC82EEFD8ECC8723,27947A08C792F1CE,1ECEB74B2465D1AF,EF21323425A74F93,4238396ED4FEB8E5,00019D2E38316F3A,8803A940C5EE43F1,E72CD502FA26C9D4,B534E8CE416B382B,BC1DF13D5F352AB6,32262D65526D6D24,CC762FBA372FE0D6,00003FE5AFE7D3F3,6115B961F6C52FAD,EEC7D5763068CA14,C68D1D93595F391A,027DFACA57F3BCFF,C8E2703E4D1CC809,B546F652C86796D5,0001790337BEFD39,5E19B73432A3BB53,57DAEF92F645C80C,B3418693CBB4CAE2,328AAF5972ED6044,1344FA0C96C6A7CC,E4181C17493FFE76,00001A22548149D0,9E04243AD93DB3CD,DF513E6184FE7466,B3E9D06F28268B21,E5491142E3256024,BBA8251A83DE4AB1,3259A1989470FD02,0001551BA372542F,8DFBF56716E8597D,CE41F8AE45BF24FC,799A2661488136CE,934AAF649E7DB6CF,B7293A9EB5B353D4,1B62DA625E20F334,0000B93DCA38F076,300FE30CEB9822A1,3ADD5289AFD6E088,8955DE48AC6C790E,B6E4A0F615D02F29,C381B7A46A25C979,FE3F48BF22CEF7B0,0001D70CAD774962,3F0FFCE463C76519,382277D4CB9A3592,D6912575588481D8,4027860278D9EDBD,FBB22A11E15F8437,E06734E67DC9A559,0001CB0357B406EE,D98B13E474B7B263,98132DFE09E09C1D,CEA75252E22909D7,056034095FDA4772,203E7A4059A4B9B4,AD5C9C7665945BD0,0000C6EC89F41AA7,0B7C0CBBEF18972E,1073B362825F2030,8F8F4AD47C7D4088,5E6014AC0817B3F8,A2D904F8FC5C87FE,6E4980BCE843DD6F,000081C58CDA3476,55C0AC0A714E98A5,B06634A676A961FD,E62A848656EE3D6A,12F8A5107C1C9F5E,93E11B59A62A01B7,FE3E9B464D50DCF6,0001C39CCE48999E,25A1FDCF1AEF82E9,185AF36C7AB9B884,1FCBF88B3541FFD8,479C8B8AB11AAC77,BE9BED59D820A93F,A023884554662B6E,000035306C341D03,BDEA5542416F5030,A0E51F7CDC7713BD,2EF56240BDC47DAB,7342B530B0B8B73C,3E6EC754F14A41A0,AF5E698C54ACC25D,0000276E62436F08,1B90B80A8C958535,8AB86E002FC1837F,D55297C61DD272F4,3AA9CCD0348EFB81,1B59C8AB8F96CB48,940B38A77E6297D1,0000BBC45241272F,156C4B21E11F6254,542CD35DE0193B08,55C897B9535BB6B1,FF373530E989767C,B05BE68F2CA801AE,E7D686FE2C5BEA86,0000C25A7572E8E0,5E8181D3353C69CD,4F3C75292C360E6D,D57E355E7EA3C761,F2D8ED350F3FCE63,ED147A0FDF5B6ED6,5C2CC9A8E2FB7748,0001A7E333BA23E2,137B643D9783EA37,B1AA144D9FCB169F,0DE712CB87F4981D,904C16A2AFBAD3BF,3D0C444A28B4C9D6,1739FA9CA12C48F2,00018765A368E214,C700F0722913439F,98C87FA3026B842A,F7D1A4A113D61163,EBF1B503278A2043,A489477ED50C7EB8,81B3BE299935D8C5,0001A992B085ED65,15A014025815B165,77D5CBFFF813A4DC,3B023BE06F70DDF0,FDE221EB7D1FFC37,CA4475FC84FC0EA9,5E07B95CDCDFD99C,00007E7A10AF9D74,7C33A5B3BAFB59D2,FDFADF16606EA065,A4153C0492884A22,726A8270910D4C7C,2554DBFA656F50C5,59ED3B5CAB358CF9,00009C1ECD8E09DB,7705BAC435C7656B,85CD848B71D60357,416609201B8845C6,65CC383C8AC1009E,66F96B890B8DE3BA,95D0D5A19BEBEA8F,000043B1B4173C27,785F484FF763C186,8BDEAA843284E756,AB6F58673496E105,B9691A4D4363569D,58D71DB2DF95492A,0054CDE77F8F9612,00012A835E8D8A99,409450531603797E,DBA1F6AED08322B0,ED69E7E3D03FAE6A,38A8A668DB1D2659,A65BCD1DE80FF513,9781AB97CF78EFC1,00012613EA286815,C58F3CB1B75E5762,DF3422ACA15C5787,F232217ED5F9818C,0A94F19FEA1B3D8F,33B5429235601E81,1FE56997C9F1D751,000017A0D348A7A4,1365382120BA2C30,0C1B2A04240FEBBC,8F7E7F187BB51B7B,37992F25C81C7227,605BC46ABBF9302E,96031F56C2B64282,00020477311C62E4,F73ABA5889F4B8C5,A3466F1C23AC11A0,1E7F3273DA4E97A7,62CBAD261C9D9207,ED337227DA6627E7,A3696E20D22B2CE1,0001AE1CB4519682,CEFC63B593475EB3,87C54975F09FD597,58D81AF37CDC975F,F5048E0A96EA10E3,F72C9BE31C7DA22B,82823D6EE37EAF83,00000B61E14F23D9,A30C5634F9AF95CE,EB392CA9FC275CF0,A027320889821D38,AD26FD90CACA76C0,67117F5002F05641,34D93DB2C511E3B5,0001F84FC177C4C4,6CFA70DD0ED2673D,280E37E38C317B8B,D5C8A4F238A289F8,CB56C30A06EA0F10,4634A5026CBD69EF,88F70E41573C0437,00023407F09D8B2A,E818CA642F729E4C,A23628067F974CE5,3EDBA3D46AED9837,6EBD9778986A0941,4A06D28930162B52,AFD860ECA2D475E3,00019B6BA6823C1E,81758342454BFCA5,A9C44BCC2D173C15,0FEAB826432F1CCF,2FBAC9F89078C27F,D1326AA32BFFC697,C2461AFB11E72EBE,00013D647ED49408,7442CE63873ECDA8,8B3209ECDD3E804B,C498D0C6881FD2D7,B1AE56503237AEA0,E5107C07F3FF0AC6,6A0206B883B57DDB,0000CD0EC31EE6D6,150150A8132E88AB,824441DDA309D8F9,AD6BCA1D0FABDF7A,F18468885498CE85,09D472CE8E8F9C39,FB8CE1A1DAFE84D7,000117DC3560EC7F,E493E2F7FD994585,94775FFADE5A1A36,40E6C751892AAB52,3F035541538ABBBA,733AF84623032C27,6D3EAC93606E4286,0000B048FA62CE7F,134B160DEE40ADA8,2594D70C119D6E4E,849C98B411BE94A5,9A3941944037B809,7E8A39D3C5A006DF,7CFB4BC59C508BA3,0000903C7ADF75E5,FC96982749282CA6,F16877D765F19A45,D54D0687894F7C0E,74D4643B63AFF644,1F20FABCD44D912E,45AFA4923F817D35,0001722978B89632,F8F4E3B60EEC20E7,5D30977FD93096B6,8524EBAC3896B98D,261AF7F83DF4421B,58BC8E2950C56F74,6D07EA33DD1A3AF5,0000857F6B0A6BF3,7BA1F77D48B46141,FF265F40996FD054,48FF997BA843425F,7CFD8B82AB4A3A84,D7C07E32021F8471,DEE9EE51B446C8ED,0000E9E142C6CCB7,21E6CC721158F1D3,D806A32FD5C7BDE3,056C6C1F954E5A7A,1BE8A74B37064DB4,C38452673DD7AAF7,A518D30E164D68BD,000098E40D7DC484,D82E0FFFFAF42E71,5B66691838C4EE17,EB28F1EA06B1890A,D9A03D95E54E036E,6A8C33458F72B8FB,6F0075F96E28CFDD,00010A6733ED38A4,25188589DB5BF2BD,73253D64AD791D25,FBBC5EC40829B333,4119569BDA5223AD,AE64C18AA6DE95DF,7F0B2E497F3D920A,000060017B802052,EA193958483BF3BD,F9E1EAFB22D9DF3D,93EB26FE8A9C3C16,5FB9FD07E987B108,CA22A5092542C62C,556C5BBFFF7D8BC1,0001323A3380E28D,159C3E1F1841E3F3,9AAB4AD2DD95966C,12EA0A64CA6BD345,DA1A52713AAF1BEA,CC69B33801833C3D,8FA105E60A251049,0000423B458670E0,51F2AA6B7F8AA6DB,0D92C2ED995707B8,8A3067C3FA16772B,1B4FFE6319FA10A1,55E64B74692E79C9,457135D9A4FBF82B,00006831AE8FAD66,3026F96A0C2297AD,911D3135180294B6,27BB009ABB39B751,2E72929B0AA1CC10,DED80F688CD10172,E75C8930AAD334F1,0000F16E26492D19,A51708AF822DE137,8E01A3218F2DEEE1,1C482CB8485B9091,69BD3A01BB57F9D1,191C20DD3A2A57D9,50F5E17B6199FA5B,00010A3749746869,6B859396445AD74E,9432792F167A42B0,3A236F5ED422F451,8FB34DABD4FB80D1,6D8972A49D2458C3,DA10197F37912CB2,000098E9900F4F28,0598026C71E6A273,8AD858093BA7C2F3,8814B1B80630CE54,A2A0313A072AF768,7395A82D51E68095,9387D88EDD98CFAD,0001C05F9D004A55,1043C8D345B24970,A555173999C7825D,8EB17C40482E46F6,685DECA897BA64DF,CDFCB1A791274E95,7CC74A72600D48B8,000126C0CEA2C13A,256F7C20FA02DC9F,EBCE8CFADE3B56F6,81A4E3E826978900,2BBA446E361ABE8D,13971F679603C988,1769FDC730A47D05,00021B0CD1403CE1,55C18D0A2A2C7ADD,23FDC5FF1E8A1B51,895B02F69896E400,8BB54E5B100862ED,E49C3D47503460C1,DB260D7F213091B1,000146404412AF9E,D3AC059F736C7C77,4697BCE15572B41E,B23E542AC780F9AA,EB74CA320A05B84D,14102E71614B3E57,44C96452F0A0E5F7,0000102DEA62939E,E43771E6270D905F,32E5479DF41D5232,BE738281E30F9330,950C4E258589C77D,F6BBDFEFAAA27751,22A1CA7A0545C296,0001BB5B4047D2C4,1D737C8696418A8F,A29B725FAD50B232,8BEE049CE0E6B94A,B676E51812F3822D,23638B055086A9FF,17355A1C5C6BE083,000075E01E6DAAEA,5219BC0FD2C0891C,502D108C1E351AA8,DAE8A74753A8AF40,EB355CF157E471D4,1B093C4D415B9782,C45D78F7ABFA59FC,000082FC83EAED7A,042E416DF4B054FF,B4A701504C1692C0,BC9B6F4DF8ED8124,1DA2009FC44CCAB2,91207218F843BB53,AF80CB0947BA8203,000211C12787A2FA,75BCC97559E12FB8,E46DCA5D3B3A7C79,83DD3090B6D8A898,41EDA35CAB8DF3D3,4F5CA9A7AA80DD86,0DBBE5D8923B4E71,0001B58BFE2650F8,98A343B21C93D350,978382D305CA8784,EAF69726E01B9851,6216C87D6611317A,6FF7D7532588BA4E,724FCB31E48DD8E8,0001E5A44D93BD03,7E32DCE5F889B7DD,BE6D9A4189488557,C7B0FA437703D4CB,3368EC69017684A0,2DD7BEE616F26D3A,57AE0701396CE03C,000082D6D578C4F4,D606F3E87CB8B434,1589EFD58EB41097,726C703878BD86C1,87436EDF8F30EEE3,D673B1B9C5FCAEFC,4EE371BCE978DDD2,0000EB630C1BBF9D,56BB75791CE5186C,52EBE1A15DF753BE,6F3E2B4B889A6BB8,9FE2C80F3CA7FE2D,16A3621CBFF78591,29F9BA1A701FF96E,00010FD59446BBED,C93936CA5EE153F2,182E042AD7CF6B95,B7F909EC9E9075E9,8EC3925980D852F8,CBFB58FAFD406CAF,4DBCB168FA773BB7,000116CF667896BC,7BC3944E53C57900,08D689B041EC7C4C,869FCCF078B5D492,9EB1D015D7DA44DF,E09ADC5B3ABC1534,7DE8DC4794221038,00018F7BBA3F7C4F,5ED9E32321E28C09,C0C29ACAC17D0D67,889D858897270407,B61D5D1C4B7B55E1,67F31AD821718D4C,3D926E7B09D3D4A7,0000D178D4D3D47F,337CCF4F386B1C51,2292DEF2346EC0C8,D015C672AD66B870,B3CFB9F36F09F1A9,941B54273D5D478D,B288ABB71A45C726,00013DDB0BFB62A7,5B2ED8A3A89EE8A5,B950E96CFCD26BE6,7CA8D5D873B11AC5,5365812EA776A169,5BAEE388CE59DA55,7C25B6B9705B945D,0001817F2FD9A7A8,B0E26CD16077AB8F,0C7BCA85E01CE102,0DCD8F7F45D0522B,93842FE76A18D678,DE5A0C0B3C09FD2D,A1FF0799BBB0DF2B,000067455CD2132D,E25E131A6384C18B,3FED2A9375C2D6DB,962BDEFA92E12075,0035DFE7A82FC6FC,1C96CE4B569ACDED,1C38EDD1A70A9145,0001603905E84C8F,31324B86629C2B72,061D6CCB2BBDC22A,DB089D8B884BBE5F,EFB988830B48A1E5,3FBFC06C15B7C58A,B52EBF9AA8EEC077,000023E26908AE91,62569C53E143CC64,ADED0D047684BCCA,57B804DCD9156E24,6A6F770DF23807B8,0662043A8249DD37,412055DA89C6D36F,0001DB0CA32B80BE,B6A8E28EA30D6047,2D94A76E4D6A647C,2022C86E4A6FE120,16483048069BF7A4,E3EE047A9FB179EE,87B5FECBF8CDBE12,0001692285911631,C2378089A97EAF6B,6A5F59201A41A949,5149E59D919173ED,1BF0A5FE881DEA6F,D3F712AB85534276,66DF1BD87D204F0E,00012C7975CE745B,40DB79DD4586591C,5EC14D3F45A51C92,FED134D67C2AD071,B0EB374AC188C3D2,A6DA37C6BF1EDB3D,BA1BD67DDBC73EB8,0000A277AC05A1C7,157ACCD641B82838,D893C1E5A1E74F87,DDDC9197A1105159,9043856375AF2A94,5EBDCD0BE47B5CC9,09B7001BA8AB2C5E,000053C085063915,0A85770E3BC7E796,413DDD1CDE9A04F6,A7D6CB86106D42A6,AC0929114EF76546,D52E893EE56D3031,ED7DF7B4F4A19092,00013735506B386D,E667D2B8671E6A54,D5A992B67DB2900B,91D3CF5FE90617CB,8FC21D1D0002247F,513B80740982B795,A69391245328F021,00002E419AEDAF3B,67DAB27D73A75458,C6A2DFBCA575DE10,1EA5C10528D27795,1245F0EE0B51685F,6D7490EE10A712DB,269CF85B9972C873,0001DF13D9D56F09,D289220A47E615FB,5563487269DE4A4F,96EA927731041ABD,A34D007572DFF29C,8086733DFAAC4F81,639204FA8BE4B110,000105330929D33E,7CAABDB2B5348064,FD5E4CFC47AB3BE2,929E398EC6C0C748,91FBA9ECE61E113A,B3B9A2BC61AF33EF,9DFA3797808D7245,0000785FA85E74FA,9AE240535DFA1E28,0D91F8249275942A,187060CA4E286AD8,D6DC92E96B2C49C4,5C012703AAB653AA,B670B87C3D75A932,0001267B5D55A910,5EF56DAE2329BC6C,129AF9EBD5FC2989,0603DA13142F6221,20479C0B7499ADF2,05ED576CEBABC3E2,B8DC30684A6ACC7D,00002C54792C3081,E784C7CA4C8E9BC5,186056777690417E,332E257F12088EC7,7BA1552275BB542C,AC2872D24596C750,1450E4F57E2D3495,000036DA8589ED3A,60655D6A59BF29CD,DAA231E555066849,2363492B3F2FCC7E,2864C540319D9D16,21908A3FE0748246,E52B6883FEA9F023,0000CE5074325E39,A570BC2BD037FCFE,502864D2F1087E46,50211BDE4C28683F,BDFE6BFFB248551F,14D70A1528904CFD,3AFF62B487EF7A2B,000212118B1275C7,18C8B42924FFA7C7,984D332C7607A89C,FC5A70CEC5D43791,626D6A6B9121155A,C2CCE6818EE83B42,D7B2C1537DDC66A5,00001252427503EC,3E10CD967257757F,2979A20A92F442D5,2BC9E766CC83368E,87DBF727C3C9FC01,9D98DB88F9B49CD5,01F54B14538DF121,00000BF72D69CAF3,00F9733717888CDF,D3AC1E6DAB7F28A3,1694FE4087DB5C53,BFD4EC6FB18223FF,EE362BA55C8D088D,12ACD41DFAB67948,0001E72F6B01566B,8DB74913962BBBCB,878A2755D38EAF1D,64294478198D58F8,DB97507176B2DB13,AA2CB63156F14389,10B2A154CB9686BF,0000D97E096E6D81,D2EB61F9789A5483,443561E0D3186530,391E1F42DA9E7321,257A5525AB75D4B7,2E5016D842E18088,47600A452C04C1AD,0001598E5C2A7F5D,FF08F6B67816D203,27F96B0F39B9F1A2,DB429EA0C3264354,1EEDD5866C25FDDB,FA93136EB5801BEC,5E0CBB7176532991,00008857786D45F8,78698F0F1336809D,7505DC0E9DF90716,F74A955D1B817B89,C95F3FF88869947B,B6FA3D729E7461FD,D78C3AE055D1320B,0000DDCECCCC052D,66176241282994A4,F538E2B06A52BB95,7DAA90FE0E95C862,84CEFF972E78C719,D3EBE27545B5B511,BBC2F172F3B061B1,000097BE95E769D3,9D89D8FA6D699D69,34605B20A95C6228,463100CBA85C0111,EAB602EE13802B99,EA0175848C6D9C90,4F6A4EB3E3E122AB,0001BF07F3857F34,4C88EFB422DE3796,FD65D3403733C1DB,9575D53E1E0476A9,A7354CD1EC799D5A,786FFF74CE1F675A,66BA8CDB019898AE,0001656BEB193F08,E71C04C6F35FC39B,11BDA6677EA414D4,737FCB9EA24FFC25,112CC92D58D660D4,004736B17F639A7B,48356960819B2979,0002297BD5B51209,FEB3205C4BAABDE7,273FEAE91926DF37,8C7DC36C219811B9,A5415EFE672DD45E,CA186B9328D7798D,17DC5E20F3864CD1,0001F2306580E5CE,FF4EDE78FC607C84,3028768166437D8D,C678ABDDE876AE1F,831947E0B2E1D3D5,6A0CD4184FCFB436,9C4E03EC34FF6A7B,0000E8CB05132D0E,100FCBAECFDA3187,5FE399BF7D748250,2CB32A3EFFCB2871,C4767052BA76CE59,2608ACE723DD1F68,0A0F5FD7F7311A6C,0001A47A32B12094,FCA628A00A58DE67,7BDAEFE0080568AC,DDDE64D9087D5649,4CAF63FE287F25FF,C572227F55922C10,05F7B62E25CBE200,000109925DB2519F,634D97A860C7E486,6CF49314C1AB1401,3E13CDC17DD424F8,DD7DD4D0EFFF6BCE,B28E37B49E9E3D88,B96BBE125D0D958D,00001E75D9BDF371,2C61D4167ADA4EA7,55EF452669F9B08B,FAFFAB5A26B4B521,97EBF5BB0413CA1B,65F5F0399D10042E,378539AE755CC2EE,0000F7E6F571701B,B133CCDCB450863C,62CD4BD015DBA372,82F240B82E979D2B,894EC1762F0959EF,44894230F96A1929,C6E52CED6F581C7F,00019EF250852C32,7B2A53FEE2246AC7,C4AD57F41C159AAE,ED90570DD8FC268A,EA172A07A207CD92,2C39006090B14391,2AD2AFB3258AAC28,00013CE85A6A9E3B,6160DCDD43C5F01A,F0A8182D032E5761,02E46765D0BD6BCB,49B26A00D97E6CA0,83709D7AC47468AE,1A97A231F0932621,0000B951C40C4AAC,F06A2BD33A3A1337,532548637E1307EF,279FC3B7B14B9581,89BFE99B2FEEDBB5,53FF0F3CF20110EF,82AB1BE8E9021008,00019D9AA9B6A632,3D05060E9453E15E,6FC50D0F0FCB26A4,BE0917335F55B505,4F1372B94CE7A156,A7DC57DDD3CBCBB1,3BBEE4769BEB9517,000128C340C20E24,326FC857CE8EE9D8,AF5023A625C3A738,8C7F9CE4074A46A8,052DA9DA318B9377,838710035D8B2935,7094D3575501E3C1,000074D0C76420A5,E5659DDBF10CE7AA,C635ECBCA45E6BBC,6494EB65C2828AE6,50F8BFA661FC440D,78F33EF6B3F96223,87323F25D6FA4F55,000000F07E6214BC,29A3352DA0E014A8,B5B6DF44BADC19D9,9CAC46D041D86096,1C5AF5842D8E2FC4,05A467197C647A03,5D63A902AB511246,0001BDC9A796518B,E6DF273A22C513B2,210A9B05BDE1F9B9,F7993F5274140F05,132F4BBA6469E322,5A19D8344F358F76,4FA197A4CF7EF4C9,000033EDE59AC801,7F328681DDEEA951,6ADB71A38B1A32EC,2A1AB8DB36E27495,BF1AF23B31FB0636,DAA2CBE73457D9C8,6C68AD3E766EB70A,0000E6CCBF0121D4,B8C902F10B3C29EE,DB1A5FBB97DBDC16,DC7E3830FBC880D5,BA1AB97B7F0A0C37,D73322CDAF34FB53,E4A7E45CF4ADA74D,00020EA5A9FCC958,3FF59BFD5CD0A9DB,B2867D82AD300B77,378378BCA8874840,7618C7BE8556914B,81CDFDCA77BAF73B,68CA7ADF14F9404E,0000E5522F1BADA4,7E62126999B275D3,A592B9CFE30EAA3B,BC2B74F302C12028,0BF45C86BD4C572A,765A6F61F95BDA8D,688E91D0F341ECD0,000077F87F66D7D2,57259608FEE1981A,558FBE503DE1827F,FBE7051C7437A255,8D2BC846036F4C78,F0AC62000C415AD5,4FB9860F2E3DEF5D,00010D2E4AF8B313,F6B066EED9C073E4,5CEBE34DD93E6646,DA81BFB6A13E768F,4B8BD94E7AFC809B,A038722C28A80854,865D3628E7AE022C,00018021B0DACC67,9A9EAB23DE5096C1,2725624B3BEE9040,0C505500A260CF54,4C488629520BF762,C1E09283C678D520,9CF05BEA5B55A36A,0000EDEAA426DC1C,812C6E71BBBE22FE,8863E3B7BA3A30DA,3C03FB6195B96834,4C5D93F0F366BE5D,1F1B01E2C5E370D4,C769BD00CE903AA5,000088BF8882651B,D924734D6838E8A8,E032EF50F764C0EA,BDC974A72FA63597,7F63D2801993552E,B744501397607611,C97074C1B70BAF9E,0000DCC1F5D60B37,A77FF91F06C34A0C,BCCD3E2ADBC68880,86CFB04C666BFE81,1491F439AA8FCE29,34E53ACA62D46701,3D241D615FB0E495,00003D488DDEDE5C,47A38DE8B426B70E,F0055209D0C572B4,B4EF0D9BB5EDD245,13B08634289C8F6A,B1B7C53EA36D7EE7,20A32207CBD34F88,0001DE07E4B1C8A3,7B0F123126DCDD9A,D3F109BE1AC6218A,C34DA953564B9124,71B96F4704C89DBE,E955258F4A4A8E48,2EF86FDDA97913EA,000152801E2C1551,3EFBDF1506042582,29C3795BFE798F73,5445ED37FC95741C,B8CFC52FCE1FBA65,EF616F3B5943A59B,BD37708CC1AF856E,0000B873E6AC8BF0,757088BA8DF6EC16,38E548CE27460CFD,2AA2020AF78D6A6C,6B832DE64D091D35,CF5DBCB384750210,03BAA71E8F678A3E,0002278A3585C000,4018A7BF8C6E6A4A,A8768E67C5D3FDE7,BAC7E42D2C56CF27,750216370598755B,F364B21FD5A117A3,361A4AFD2F46F534,0001A1FD24B5A110,D7E6D79AF0F1D333,2EA7BFE5B515AC22,0BB4B009F8D1B24C,5B8367DDE9ED2580,87D708274CA5FC87,F850436FC2B7084B,0001E7C782490350,C51F3B523398F02E,4A79621211FAF384,806F29E10E3753E7,A920A7A0140623FA,779DA6F9D265555F,D87E7F53D7CDDE05,000149F7B7E800E6,33E040541E0B745E,AEC0E429C27E0DDD,2A9300AF6C565525,85B6EAC32CAAC581,A53C319AE2249FA0,70C9AD13F0DC4CCE,00016FA1C6726729,39403CB547AA7BF1,0898FC22A39C8779,F8E6EEFA86FF7A2D,43146D92233487D3,2C540159448F46EE,E70225C48566CF02,0000D1C3EBA4F5A4,6E9E623A006B7FDA,E570EA2F6E57C69E,668725A90D995223,E00987B98C5290A8,5BEE2C4D49F48591,14960C315FDC6FD4,0001700AEC7DA845,E92044731DEF1AED,ABF8B2737E298E6B,C4A65180B676C2A3,29050C0F7B4349A7,B289FA5D6249A91F,59B7A8626D9A8A90,00015E1E1423FA3C,18D17F18C6502B45,3FDEC7BFE1F5789F,D45C729F42B81362,CE9CF6090E2E7FC6,3A14D6B7FF21B790,41E58BB03D532CC8,0000F99601B0E71E,7B89BB899167644C,8582F6D7E3521C22,3AEB37DE39DF42AA,B8F203CE27EDBDBD,6DB03359CBD94B41,0FC64822FF1D62C4,0001B14973FD16FD,175B144B2092B503,46F8542E2DA36003,9333CCDA0BE10C58,6574F4D7F9F1246D,88134479D0B920CE,0A1E7C3D606CE330,0000AC3F2C0AC417,6DF32EABC2E82DFC,36CC436913AD233A,6C515FAA12B6BB69,32B798A9D5165D61,8EEB1056C8806008,D0B8729094194671,000154014D45EB57,DA05C4D21992A737,5DE6DE9938307D3C,356A6074009158A0,FA5D7C1FCE001389,C686F8A324BA46DC,CE3F61A7893AC10F,0001699470F035E1,E56F3C89DD88827E,54C2DDA7D67C72B9,9597ED45A77C7ADF,E9A8D40A47CBD095,03C763B1CFB3A28C,24779FA2A9BB62D2,00003CEFB9AB456A,CDBC4B19E670D500,D60BEF4F82667437,018049C63FCC8790,D7854E3EF9824064,A3E8F23F3F20AE72,E2346EB12B286EC1,000175DE81E67D97,0C936C115D2074BC,69E75EE93135AEDB,36BFFB9FD0DC6A99,B1FBA35023F17FAE,7522E95DE309556C,68D4BDC75560F8F1,0001FCE2B47CFD1D,EAF9C5ED2AF7FE7B,AD1400B4E61AD2F2,8CE64A8BC6FDEFB7,EE4B0104E91EF51A,757EDC61BBE15B24,40F0C89BEC91C483,00012D2202634609,8C738AE3EABF4F3E,FE89CF744B096129,F6294A1659578553,DAB2034B763F6E12,1F69F8232FEFC826,8BF00BCEF2A7D837,00002E1D491D2E2D,8F994AF5702E337B,AA076EC11F16BECC,4A3D03B1C1946C0E,43E956551AC23B6E,9111ADAF6DB54B91,B0F73A3D7B60840E,0001EC29D12CACFC,4F26A97B509701F8,20038DA5D24ABC38,BE819956470BFA04,856441F6BE71EF4D,7E80B190AAF15BBC,241A9E050C1FA794,0001A833D6CD6BDF,CEDBCB3808B8EAF8,5521C674B7F3C238,3969460EE8175E2D,B3AE5CB32FB9C850,4CA2C90D1426F39B,D1FB460902647BE8,0001AC8AE3032E8A,B3208C7EAB19A50E,9BAE8940B45A638D,786C30F5D9BE629A,0F2A8C2F9A06E21C,F8DD91C9084488EC,9C9652FE0B22EF60,000021B52407F008,10004CF4EF9A2778,7BB915417928FCFB,E436A88FE206E42D,FDACF0DC0906AA43,2CB2AAE91AF6ACFA,53ABB62D4C13AC52,000048B7B5A1BA72,F7278050566E9249,300F4FAFAFDCB153,B203C65DFE4BF5BD,9B2316CE116926DC,E068D39489B9E2B3,32DC2F27ABD7EF43,000129D4DBAA1DBD,F881AB66A8565072,5129D22EB84CA725,64DFBFACD7D97E38,0617095B8CEB2829,4F0648F9A8D4D397,862ABA78ABD6F1E1,000009CA0BA951C7,33BCCB49A10F6CCF,722A27581E91A825,DE9CACE4487370CF,2B13C432C62C6E2E,C4FB6140991FEC89,B96520008DE2DA04,000017C6B378DFF7,5F810376E65C5E64,2545C5FF7E725327,64243E7E04CA2540,DD85A177D84F2C26,0BFED32F42167E35,EEC049DF3F761609,000146F7CC513DEB,1F467D1130299114,0399CA3044A276FC,D697A305417ABA1E,13704E1F1DD64EF5,31453A4AD52CB3D9,BF05ADCF8E8DADC9,00000E3F3D27616B,BB53D0FE83464E86,BF445D9784300712,FFA8EB2455C27BB7,4D6C52C7E4F20B48,9B981F403C4BAD5A,524AF53683B6BC36,000053B3B31EA192,103842ED515C2F19,F66AB3B74BAE4B16,F533354981EBFC0C,6210648B721EE08B,034D76F38143C125,B11284AE3BD5AC0C,00011A0EDB895DDF,4FCE2114A73458A9,0B14E0A5E226A58E,039A3E15E82EFC52,97FF4631FD2AE50D,6966FE8CA9E23D39,D867C32E7F94B69B,00008365EC759703,76717089790C96EC,1DEC88520EAF6BFA,D3D873FA36F2C707,A46FBBF3FAD6D34A,346EDBC445D9A69F,8BE85426317A0024,00019AF1E1BADEE1,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,4BA72CA59B6001BB,E5FD2ABD4CB6A33E,8A98D19511F78FF8,2C5C5AFB9A978D78,73C9F51BE2B16F40,671834E521007F4D,0000451B04879668 - -T_tate2_firststep_Q = 6448CB5BD9770D67,3092CF8C8803D8B4,2542331C81C2C2F8,8066DFBFF024AA32,05F4E163CD158E1A,87C8B0AC7FF6B89F,00018466971777FB,414795F6A70D543E,DC7D2E0B9229A814,679CD711C5B2AC8E,CC92A943030F0D18,C2BB3CDA074E0076,19332E71DC423BA4,0001C95A2FC045DD,6DB3A00833C75E25,EF23EDA1ACBDA616,72B19555F79DDE6E,9DBA3A0E78EBE79E,1D187EE5215D71B3,1D24D175B4C3C65B,00010AEB3555065D,508F3D07E0AE1491,1C7EF18B886FDB38,AA1001FC42642F0C,D5536205F2F93C34,B647092B16484B6E,899C89AEA084752F,0000D0C508EA68B4 - -T_tate2_Q = 750FCD24D96F498D,E74B7652658B6360,54FB85D2945C71AD,A530239B59D34B1A,5E729DB52488A584,08EF15300FCCB833,0000CF9B1759A390,B751C3B1450C3CFB,FCD2CDCDC975A71C,B205AE03102DA534,2A92457AFE850487,11C5DE0150BB9277,092583FABF57B00B,0001DB45E9F74BA0,6E2824B9A6CD94A6,0326996F14616B5B,B8B059926FC41E14,81C1902B47804230,4AED4C52162CE0C2,FDF011A61D93A862,0001EF5325739A5E,78B9C0B9A3BD2967,71CB2BC7320553C6,316F5C32407BD0A7,E55D1AF3CE7A86A1,ADA2BE65BC44F08B,6DFECE85DFCA3C66,0001FC0E23853261,2DDD455D97F32363,46045C35F348D058,EBED02F21182F5E7,945CE83599BB7C39,BFFC17B98D65562A,0F2939B5BA82E954,0000A00560C80C10,474F1C272489BC2F,A564E546E5A201CB,B957D75CFF3FF629,3A76D34BC39747A6,0AA8D48E8E9B4698,CCA8F309E4BDB606,0000CAA0E8A11964,976CCC8431FB6C34,8C8284AF61466CBB,B0AF134D7B823472,1A04747E8B17FAF1,5E2440D685E770E9,3DDB066DB9B420C9,0000625F7441AC17,7CFA008777AD43F9,A4B6C0632363D1AE,9336E4719A6D77FC,5EABF971D76F3F31,626FAB5A44137369,F40400CBD713FCCB,00014F6A0CDB44DC,FDB139668120B384,1DED27FD8F13D564,9AC2B6A0F21A8FE1,67C90AA701E803E0,8D43D97FBF09947C,FEC1313BA4FE8713,0001F2633D52B220,FF1D65CA3CEC7022,B42F77A4ECD38FDD,10D4A99EF3C7A955,1B2303D6B0FD913E,A572DE48DA807A48,502F9A6E3E3A37E8,000037CC76C9CAFA,2780B7621B977D32,7C0DEF25CD7EA965,4DD4316EEEB248A1,305AC1CBF3AAAE7D,76EE1B4562B0B550,448B64F5350DB407,00005445283D28B8,7D0C48FCF2971A51,5603D7D476DA47F4,F3EA2E2B18DB0180,9FB26BEE17EB7153,9979BEB62FE54A8F,7BEA62C58A6755ED,0000433EE8B58E9E,EBECB7300254B1E1,D0BA966A73B96166,6A80F889DA560535,BA5F9AB3FF24BF95,83ED7166FCD75963,BDAC93405D97A232,0000D861C6B948F9,E3BE6182E764F224,207EEC37228E7DDE,E63CED9839EA5FE0,25C5DEC25FDD4617,1F8E938E85B1CDB7,75274B7A209FC0E6,0001839F3198378E,6B6F952BF801101B,3B790104ACBCA620,8732A25B16A39F6F,58838C50A4F42CF7,6CF709BFB949B38F,F7B30AD8E2FBE8BE,00010AFD93F23D73,5BC1E231775DB25D,BD14AAB4EF0F7D0E,B16B666A646CDD6D,A4B23B30157407A5,CC196DB00BAECEB0,823C20C85890BA32,000166D4CE5942EB,92E0CD7EAC79931D,98AC6027E2E6E739,7C5B6749716ED8F0,9587208313A6421A,1A264889F1AB32C6,986D989217672862,00006F058AD03407,8A28D792AC68A4EF,758DBEC36CFDC047,4A3BB5480742B492,737F130B7B7B07EC,2C2410E5B8112DD8,88461660FCA94625,0001A9B7CA9A7EBD,3F0D55442DF08455,C6FCFD68C4543DF4,E8FDDA0B8B397428,553102BC463B8655,E5FBA8DFDBD0EE7B,2259D7A195D96B6F,0000AE763E0E16F1,7C873A06F4E87392,483291D3C46E6149,630FCF37481539B1,55749A6554255C40,E93BD8E4541A00BA,D6052323E9AB7DBC,0001D9E8E2B76ACE,4C2240A028DFD1C8,E5E61CBE05C1B35C,0ABB89AB8647CCD2,A652181A694CD8A5,BE23EB2730D0E41E,93A4368F83A8C22F,00007F25F33AE96B,9BB49112E1992786,FF567E8A6A208CC3,E82B79721517C379,3D25B6E13998867B,2B1759EC761146E5,00848B6C4C60858B,0001581E213BE60B,FAA58AB579DC241D,DB9AD8ADF806E6C1,8DD926E84E3C8530,021A6AB3DC79E86B,815E030F6666EF52,83273E8F1FEC66D7,0000910F40660D28,E9D5AE8EF786F7C8,381ADEFD696AE953,0011775446545AFE,61047775DC13B67B,D1CD714D5B833F65,630DC4B85564086E,0000F9019F945C63,D3696E6951EAC453,8D3A301B3D438D24,C92AE0676C6F85F6,F08D5878E41056CB,5F01D4CC3F1C6991,7A46CB006E86FCF9,0001ACB66191B170,5DAB8F66ABC12F71,D31ADC09529629FD,CA5462533F93EBF4,1FD9239820B35EF2,C4006DB9D099E737,D33F192F3C60176F,000194C33CCE9747,034FEAF8B42A7E67,AB831F7FA796DBB0,1C079D015E7E2DBE,9FD78DC14C4FB1D5,32AE7FF62C72850F,7CAAC8E174CCA7BA,00022041D2B129E2,D6D341AA9C65FA0A,269CE4DA19787A0F,5C40364FBEDB730D,1E5BDDF054C72EDA,DAE41EFA9FD3DE60,B9E24619E36B6BBA,00015662A66F5914,5CD18C2F5D6C35C4,9BED59102C378CCB,2D42AF0D2A5D691F,DACEE58A11F684A1,197C8D9EA914E123,FE0106C5A328B9DC,0000F9958E1DD8EB,E1DCB01D0EC5BB24,A8C8965084B59D42,F2AB73AF5445D89C,353F3DA2A09B895D,448A1BDA9F45BB88,ED4CA9F58D3CD69C,00018641D1221F20,99766C73104FDD34,A0EC15986B4E96BF,56FD2630B8FE894D,37F6E0A38F687DE4,7155F8F92BD9CF3A,10BAD4A97A19C91D,00002D12F4F62D7C,BEEC749EB21AD7B3,7E4A5802AF46E40E,0CBBDB4823045A57,16C2AAF84AC0A36D,73FCB5D8C923A60C,C81696869435882C,0000E7FBAC22A3A8,1FA28C25DEC25548,CD267A99D02AAA05,A06C218D03F4830A,88AA3FC65324C470,3A1643BD10F7D37A,2C077987A57ED136,0000F8D12F1E90B4,982B36BB77C84893,21351AB71BB1755B,D170325D69937E8E,C9FFC37128F13C3C,2BB1EA58B3E3B52B,497FC1C7DB647619,0001BFF4F5970419,A849C7DA82EAFD6A,432F43E215122330,E0697EE4307E6357,8AFA2C96D5906B08,62910BCC532ABA04,8365333F5666343F,00017AB82A1C17DB,20B0BC62AD66E26C,83C5E378CA181D81,30CDDC6C68519055,2EE7B32CE5A3C27F,ED3BED5F9729B254,F462AB18AF63ED41,00009B903749BD4E,9E8B6D6ED4F2013B,26B43C36DA612DD9,15B847B36354D5D3,A973422CC6C26BBC,9090C35E8C528BE1,AC6900114D2426EF,000222E4EB1A855D,368DEBFE21C9F228,7DA13C45615E58B4,7A1EEF8121CF946E,1389B603541060B7,35939F7C849FAD98,5612D5495886080A,000126D9F7666C62,A59E23FFC30D7F08,4E863412FBF7537A,E12D5C2B11B3EA72,FA2DA80117B7E529,829D2C4BC870471A,55D25AF55CAF0CE3,00017E58E9A60B00,AE7AE0E86C75F5FF,05F731A8E705CDE2,58D769F2E36FF7DE,695C5EA9378A6292,3800F94F79ED92D7,95571F8C30FCC4B2,0000F95830B84254,736DF6FCAFEE78CE,4187189B5DC95A2F,624AC9761F193886,DDB9D8115854F372,C0A14EFFC8B7CFB1,98AB4109ABB6B169,00009A3B57476653,FA5379F67D64F895,E8DA1DC75B85E197,66AB894EFFFEFF69,D07F3ED21FD321A0,50CF0F089CAD08FF,F41CC7E5C71FCF78,000049CF3C122C1A,8839927AF53F1372,DB5E77050B6270A8,DF500C79F8D3E234,7397E4AF21489137,FB074F540CF5B358,24937D8B699276A4,0000E2BEB58E1F43,6C09EEBC3B808501,D08F5CCBE480B4DA,18A7DA53E2FA206E,D1475AEF5FF06038,224C25D316F1BDDD,9DF5FBF015F68464,0000F6CF4101CB6F,77D66053CB379B05,C30F832597978504,2502B8604C8092DF,3B8505BED298AFD6,16A7F7AAA19AE877,489084A274644201,0001520AE384EB88,4ED3669DF211CE2F,A947F59FB6D56130,5638C08919F3E836,C752FADE9CC53F0C,A0F96535831E8618,FC2AB5351383C7A1,0000592D92B69080,6E5D4DBA90CEA065,F18827A2148F9149,2D95C2B574EEE1C6,E45DF60BA50CD91D,F186C5FB7061474F,748912DFBE7E289C,00012C5D5F96EE84,9AAFE769FA51D697,DE1047885327BA69,6A5E24FF211F8572,BADE71E4BCC6ACBD,84775B0F03B8ABA6,3A0B4AF076484734,0001EE715D2BAA11,112166B515BA4D19,086EC702AF6897D6,15A1E4A44D712A9B,7992F8B85FD31C2A,A11306EAE3E7FFEE,B886F4D254477E21,00008989E6AA5B25,6840E0ACE4B22049,00FB9993EACC8508,FAE632398F41F6E3,6EEC63929229AABF,67B8C615A76C3FC3,6735EEA6B63DB765,00010C989056CD98,5E0E035D4869CACF,6478EE750E4BC97F,E4510F8F46C1539C,55BC95BCC99271FC,00FB9C777517663A,6F3E119669FF2B5D,0000039292ECF566,AE520B158A1FF06C,0080A75BF1A049CF,CB34F7C15C6EF9D2,37BD230485704A36,371D40187C0F944E,DBC6C6F6859511C2,00022CC2104AFB41,C4F21C38C5B85958,77FC5A339ED63183,7149B5D638A75E1F,8384F5A1B6181170,195FFD7ABAB3096F,F85F05D350A77AAA,000119E4DD8CA9C9,45C5BAC286EE7FB0,4344528D50651C4A,B6495C96DCA65927,42904F323A584C6E,0C10D98101270F3C,C7562A3AC2978FDE,00008B416F91D036,EEAE7E7259BCB358,18AF927D1101692E,78987E28398D7C06,3AF66C5F09A98CCB,DF2555D6732D3EB8,6C92E1BF5F717600,000138E67EF2A448,F8319F1300F7D2DD,91939965262F1B40,051891307FA41820,DED0AAF0E9A4011A,A991918474E277AE,C8341FFC284AD381,0001011F23114641,92EEB0CD4A3EDA72,37A29A8CCAC3443D,05D9F1528FBBF870,7FB61F292D692FC2,88D15383FF4A56BE,A6FDB103368A3EFB,0000ADD27B910248,C010B9E5FD0B4E22,1B87860533FF8C1D,3F8520CB51C8A321,16814AAD7B5281CA,270DE611657E481D,CF3CDF9123F41FA1,00000F662AEEC196,429C2CDDCC05C2BD,7F3A3055DD5EF785,A0E4E46191BBC4B2,9E9460E9E12E022E,DAF46BDB8E837D27,DA58050843AE7588,000207DF30753B7F,3550B48AC0200D55,B745C91EE805D147,AA298E7AE492D389,704565166CD5D5B1,AA59A4FB0BCC4426,1A7CF78DAC86648C,000044B0601391C0,D1A661450726B498,B58BFB5D1193F955,6FF51B55704C4C9D,55E3C6E54F0199D7,E11C76C9276C9192,A7662CDC876A0A96,0000D9E0829F8EE3,F4BF45B6ADD51874,8B3899A96438A89A,F4E8550053FD8473,42601A829975ACAA,039C77F5AF67A046,69240151C46BB4DC,0000688A0B45CE62,7FCA34CF8155041D,904479945B8A44C6,90115CED17794956,D51DB352ECD38947,48860447B4CD6A02,DC8991BF90F26B11,0001523F7D99DBAD,9D63610F7D3D2F33,A247B8A729F6045E,A6F3A4CC7D418900,983D8C6E6CE8688F,786C9C109ED1143A,50743DF63D0CAA90,0000CC4AA483307C,8DA2896921B1585C,A07A41C83691E425,A288EAE31405F044,BE28C17DC0BB9597,818E8648C8B24F3A,65EC5DA20D613131,000223F0551C0A59,E2BD65B5CC4BE833,1150F4749FF54D9D,0E768E05766B411D,5C41D45CD9FFA54B,672DA1B72A31AD99,CF7002CFB6326951,00003B6968E09EFA,E38BB4C3F4F620C7,2E79F60B32D74EAB,21DDEDD47725439E,E5D9F6BF09DC77F9,DFF664208756DD15,0428ACD53BCD120A,0001226BBB252DDF,FE31E477C986BD88,7AD0AD939B079CE3,45F0FE7F39A77A65,8D6EAD24A09845FD,9C71DAEB9BBADD28,12B38197606F8422,000101877C5DD102,9C541EE9A0A1CA84,55B2C6C7A15D6F38,4ABB1535CB634990,3A62123C09E11340,BE09DD098D140749,EF9567EE5A4180C5,0000E7381E9AA5EB,E345A5D1C0267391,5F95A27369ECEFF1,FC36026BC8DFCD56,E4706A91F95D3911,3B066AA2199B8411,EEFDE56330889865,00015B40BA009FCE,33C8FDD8DABC2405,C62C02D4311B1194,1957844458129140,E9831E61E297C362,9DB76C70BCD4C3FC,E9FD990132BF4FD7,0000F3504F8A78F9,348AF93894735D74,796EA6488296A85F,8F7A74EC62EBC8B0,53B43FBBE5B492F3,C246950105DBCFFD,F434493D77CF333F,0000898EFAF26309,2DAB6D0820CC0615,B2ED03D5539FFD3D,85ED74D694B9BB65,78F6B5291A412D2B,EA031A135DCF3B05,12734A94B8B95848,00016EDB379F9798,F77BF0E1EA9D4B52,DE093F6538580471,6017F905B867C6FD,25C9F644F04E4D09,FC479829C3E766D2,4A043A6E53FE59D3,0000D41BDC2E1B8D,635F4BC2F9226D77,C77C66E3959ABD25,F31C0ECEA54E5F27,85A272BD9DCC9A05,FFCAF2D916B530C8,5485831CE1226319,0000D0B47CC61D8F,F43CEEF41C8B5C55,C5F2F562A4FB10EA,A9AFB7F8CC902821,51DB94C6D445B6FA,BB7761B3707B30BA,41211E5822CE20DD,000232E891AD2984,D1ED3354B987504C,72AEF8172490DDAA,DB01D82F56A8635E,00FDEDD1EEFF62EC,151F3FF349D4A001,EA7B63C280789A59,0000DB81758E1942,331B87CC87DDEE57,0114832EB52ECEA6,ADF930A744B8453B,67D838D15D42B5AD,46775D0582447784,EA89D0462DD5C91E,0001153FBEF53CDB,A5DA43BDB0FC096F,DDAA16CEAE940CAC,AE3FBC8C349279AB,0E28C41678FD348F,27B96FBBBBA37CE0,5615718307991E57,00003BC3C98B48BE,F530B1230AA0FCD3,665A488958531090,35BB424D0050BD5D,E6BED192A33BF4D3,2B84EA50ABC9D109,5DFA07C324DAE3B5,0000BA6116E07D48,F2FF5CB16DAC164C,302E38C76DAA9A5D,92CC63E5E0FD5468,51D7632DF8046B73,C755E2B8731EEAE7,F718DF52CD4834FB,00012BFD94EAB720,D9889D6D1280CD16,529FC0B8E1862BD2,A22D3F7306E4469E,9388D17F3AA53C4C,796FE152F8A2FD99,3F378694231DE2BF,0001E38273E3E7E3,C6F8DEF4D664CE66,1F9927D097D3B18F,589B767C74678A7A,4E22485AABD9A3E0,985DC1E3F341254B,972B717EE08A9546,0001BA05397A0D8A,154E78C82620D1C3,D417468647A3BAE9,91AF7FC2E32AB089,DF52C692757E68E9,217ED2B2DB60A4F1,E2F4EBF1D45E242E,000122F5CDBB25D8,A6D0DF501959D27D,CD58A2C210A6D2DF,BAFAB657C1023509,FA2A4E90DF61459A,1B8D2D227E2A32A5,518C4E16BFFE0B01,0000E3B3F06CD1AE,2AE40CA2237517CF,1057E91B1E34C8E8,798B723CA0AACFBC,F8C4EBB86513A4DD,5ED2EC691A9FBD22,9AD0849937350443,00013F0AB9B3749D,6FD59DD48ED29E4F,73AD37F91F6BC02A,6D69E86711514693,C4E6AC81493C619E,ECF8957ACE020BB8,392FFB5E5A30CAC9,000233E162CA13BE,606B0E043703DBB8,3EF82DA8F543BDF6,1280E417AAB7A9C4,98C89457480D612F,55A5A0E73D9D8395,1EFC4D4346E7AA25,000184B87AB398A6,B43328672FB9B2A6,F5135022A33F9D02,86D9127EBC05EF2F,33336B4E082F2113,AD148250868D0D36,F2E28025F009CFBD,0000A9FA1C2958B7,D25DB04C800210A0,D16C3FD5C634310A,FA855808AC027AD7,F2DA2CB31A93C0A9,5D9479C83398C784,7CDF735EBC8521B7,00006F73C02CFCF7,2FCC4A773833BB7D,D04BDD554C99F904,2B2ED3A903D304D5,66A53F31DF18DED3,5A9CB198137837A3,96609B5A48894468,0000DC64E6C06339,7897EB11B6711070,50E2819BF860579B,1FE5262AC4F8748F,78B28D888A48AE50,C731F0B03F1116F0,59FAAC280C694B5A,0000B3E49ECE7134,28843823DDBB920B,22A4B937B8867D4D,1BF40909C48AC2ED,0B97186A08B17908,FADFB9841E862353,676494AE782F0AA9,0000CF539612C621,78BE5E202622D06E,84D3DC1081AA2BED,8575A16213B45A7E,1929E9FE9F259C83,795C8D53B1CE6F0E,C0C39F424B767E7E,0000D4BD30818760,6844845EC1A7DD31,0AA3EA7E6061B386,E93CE99F5B180E05,1D8F2B05965E2776,C42DC299D11DB097,6B41E262200D6CE3,0001935DBF7EADC7,FC4119977EF52A2B,A71DB91C2D7A8815,E88DE1FB970CCF4E,5FD7D3C40F6D0B88,85147C5B3667DF75,A7A5DE2B7857B29C,0001291C7CE345AC,57E72683298B9229,AFA5DA8CAE3F8629,F9DF3595F07CAB62,ABE139025C397B58,43202C1354BEDFF9,37911924FDC094F9,00002107D1C956D1,7E88D1012A9B2B1B,3DA110E73B2FD926,D549B788F7EC7705,268D1A15DC8BDC08,09807DCF1728C622,5A5A5A72FE302DD9,0000EC660A640F3A,171157ED47A21E71,311BA5ACCDC854D9,C68120C1FE1BE015,AF3F221E7E1F541B,97C8C1898B545EF8,145F8983A2745455,0002299F617AF7ED,F4B10D80C76E2639,430A75E3CBD13271,C2FA5F3D889B8341,710984F3BCC0EE81,ADE87C9B8C0D2524,EFB2758EA1AD0D1F,0000E9C56D5CB170,CE0FCFC28E6E452B,7DBA8D37E5640736,1C9399FF513A963F,DAAE4FF25EF11542,23CF54B1247B57B1,0D53DF587081875F,00001B76FF559708,94F0F92618D699FB,5891CA1175B01FE7,EE8D50D495DEB9B1,278E0CCCFF6AA2B5,DC171662EDD209A6,6EE787237CA7C1B5,0002108141E5A802,1D8DFCCB16B200B5,14FB2EBB54D331D2,28DFF699CE5B1D74,44128657F412F55B,4025722B7121DAE0,2596937FFEC24A2C,0000384760E7FE76,FF1B4AA5B0941651,09EE1404828F6F0E,4445BA71B3DDACF1,D2B2A7AE03E834CA,A296DB6A900F4911,604934C557B74AD1,000108F2976B3AD6,0B87058A52BD5FFA,BCAF7BE53992436B,C0B66BAFA8A77A1F,99461047EF1AEC1F,1F1C8E18BFAF2459,210D8DD96CB1E1FC,0000A7851A34C031,F765528E4B4BA9C2,1063C4A2F0146747,F047DD7B8E5B387C,DD833540B34FA5FE,6936C8784DF0105F,44496DF23B8369F6,0001A2E46723F58E,674B3E8B4D276C92,25B12CB4C1E5273A,ACC90537EC54FC90,9804AC89FABF39D1,2BFD0A63492D00F9,71D53946A2C3DEDD,00007B9FBD67C01D,3C9D54EE74EE2470,2C8AE0BFB25302D2,CA2903965930AAD8,3ACEBB22DE157FC2,A1881AEAF4BEBC8F,885FCD2DBBCE8380,00010830D500E15B,34FBD138C0A2E859,CCDFC33C65E43639,FA4B682B2D07F38E,4C7CD2949AB02B1A,F24424E87DA175F6,D3C4366077FE2E86,0000B14D1FE272B1,7E258E3296B20003,F762D9151D1EA233,2BFF26BD2C813105,61E75C78E179D7E1,6B44153D6226AAC5,2A7E968D4023B648,00017C8FCB67B4F2,0D88689D22C585D9,5F71237E2EFB9C19,B1DCFCBEDC185A36,B17B7F006D65065C,C9902AD7256C0FE5,7568C8768E9E8355,0001B545152835F7,E794362522F4A72D,9CDB852DB9738D95,62181633E73B1018,158C0056698372F1,4A071D4A179D92CC,0482BCD1F612D26B,0002089139ED4557,927E51F6373191C8,4809D6B5DEF910B0,52258A9D151E4D2A,8A3FD9070C614928,D32F8FFADB2F6A89,D1E687584E1B9663,0002014D140F8C80,BA1B9EE4C60BC9B0,B00F45449EB5E057,D2460C2E65FA8AC8,04E0D8B345D83239,CC33D75BF60C19DB,656CCA61EDB7CC9F,0001D488D02E016A,F2CDD9CAD47513AB,9592381B1962D2CB,6F1DD8D81345DFBE,F80ADE19A34CCCCC,FD63699D448D7E80,E326AC7C4FB6BFAE,0000F441A22A1C70,0C949CC973FFC3A2,1E6C9A28849520DE,E7DBD9CD41F5992E,9C2F4AF9D44C969D,F73BAF0AF45780FE,36C4CDA508D9794C,0001E850B9845BFE,D919F07A05CAAFAF,9F18A862F442A2D6,79F831FD2A97B879,9987F0DF81174DA6,C983C8EC8DDB9B4A,F656BCE03EE4A662,000208494A1EAB0A,3E653BD6A2BC85BA,9EA04F24D3B02703,786DEFDFC5D4F6A2,8044AC6D8FD4CC91,C1D9BC6D3AC56615,6E79ACAE603C235F,000013D43210C059,2FD0363EABAF0456,04059B27BBB4E650,2357E36B738002B3,168DAE28F8B2744C,D55AF9843075E46A,11E94E93F66CA78F,0001A71B1B41A7A8,0618DC0B85ADF04C,BD261A33043F16CC,D2F35FFF5639D3DB,8AE7C2B88EAFB607,EF19079A730E99E3,79294FB02F129B7E,000230DF964D0C2B,F0B68D0EF0D6F844,0681B2CB7F791727,FF6D547AD5C6BBC0,D0CD9CE5564B90DB,76C30CB919096825,9B420EE3C6EBE946,00014D03D8BEF2AD,C5D9854C3F47A53C,555AC6FF73723070,3A4AEDDDB37FC12D,02F48010D225E673,5960FE9973318F52,F0971747E94568DE,00016538A8686F3D,9F86CB7A864BDADC,E39F480451FC2944,8B2C96470E5A8EED,B4BC404B53A78853,C8392A5A610F8609,37666D17185D8C2A,0000D61F19F8D590,E3F9CA11C347F21F,9C5F0B053126BE4D,EE90BA59DD4080C5,E1EC570F161B2457,C3FCED00F1D284F6,F2D6803573CEA3B2,0000EF609FFB6CBE,6AD053CA234CA572,D38BA45BE0C40522,54AB67AEDDB865C5,EF26A8D4C95A90F3,E8A557CCB8F97997,7B4AD59D3E0ACF65,0001BD108E861A32,7F8F4FE7D1307A81,B6E15EA19D04DE89,289022FF34D6F164,2235D5488883DE64,B49CFEC222395EB5,DF16490FF92B2EF0,0001E4E682F05C68,3400570EBF4F0F14,37C8C495C85D56CA,996647EE855DA493,0EFA88EAEDCA9DD3,E4CDDFB198ADE043,A7F016B1201AA942,000203FE00F5306D,0CBF33DE9CE66E72,63F39723713ADF51,C2F9D49BDA02214B,490734377DCCC85C,8043B3BD3C698B53,2B8E30D4B26B8A34,00018C7FBB5283E2,35EC99377995D535,90DFAE57AA6FD576,A26A32BFEA846D10,AE31E473249B5E5F,D99A52981890578E,5BFFAE3DC2DCFE00,000116B1BDCCD54A,77930D5B0D1515EA,5E88B99ABDFFA177,CDC1E94905CF2EC1,E3985146BA3E895B,4BD1F138B8E98D73,32C70187FED2C1C0,0000C14C9D918586,D26A42EFF144D2DA,AE51B4AC93E97249,AFD523D101813D35,6CA665D6793F9A38,650B6090ECBE4FDB,FD10B1132204AC01,0000C24D5EDCE75B,1213DB60B55680B3,22E42ECA7DD21006,670CF19ED211E978,B99B359C8E7EE458,84FA5E025A25D79A,D58CE95A1CC77AAB,00019BF2818C2D11,E6FF85813CC4EDCC,C05225DDC53D3FF9,A4C8D4D0A2B651E1,95A3F1A4A992161E,E222D61AB6355E2E,CCCA276B8AE5B296,0001E63D8298B61E,3AE1AABFA7BB0FAF,08DD12643668D5C3,1A4E104CB28D9030,128D0F7D979F1365,002190A2325B4D61,34902E405161E575,00011011655F84AA,74DB558B1AC08D96,82D49B4435332FA8,8430C728238EBDD5,2F2D0A8EE7589FEE,70C476F26584758C,7BE1C7F205752713,00009562B99261C2,A2DB08A51BD073EE,2432380F66E2808E,8464CEAE12A4965D,08A8797B75B31CB5,939442FDACA17FC6,51079E2B60E8E67A,0000BB33DD2578E5,BF70C0A23E7A5DCC,5C6041EED04E65E0,78250EB2E6C5F073,523F0761C14C6E4E,A65C89B9627D52E4,C895E81CBF189513,00003AD7E27FBD78,CC72DEA9331F0069,044AD99EEE844A27,243086F78F554A1C,649AC2A7099469D9,1DE9F90ABB63D324,B4FF993A55D07AE4,0000B935B3469C7C,7A234F6351008DAA,0650F112609094CF,8CE7E713C145A0CA,2A185F475736C663,2DE2E07936489F7B,49C3D7203D0D761D,0001F672619BC433,FAA836B6C1E99016,EBE07D5EEE7D860D,CF960E525DA09081,686D65A136153EEF,AA28B64C17C1FA06,CD268E9CA64E8BC4,00014A4D34273239,47A91FE6F4F33FCA,1EB3C146EA8AF366,CA79B729CCE76B34,F3B521B2277FB500,5365945372A16966,D0AC98FC5E4EDCE3,0000F543DCF5EB33,301C04CD96DED4AA,F17335688CDEFEC3,02E4F7610B347863,4F610AF2B39FAC5A,D061538F2ADDFB62,525D439ADF313F47,0001883FCF08D9E0,E9AB716B9399538F,10D725BB0CB41B01,FEDBC320F18F1A93,F980D3D28C7F9258,EF815801B70F861B,3ACCC7E2DA2A54CB,000145932BD17E7A,F4C592EEEE53F6B9,BC295084D2BF9926,926C7A7712C768EC,0D41D51AB263B9B2,72508BBB3229E91E,D6FCF5FB059ED9CD,00004293AFEB0983,02EB58A6D489FB27,FFF1FEAA7B2294B1,8E5F8BB82F22E0E4,425C4F439ED226FD,87472834294B091E,14C6C54DFD9C69A1,0001752B22793578,EC1E13EF6AEEDC03,657075803E53909D,C350E7D2D3066CB4,408ABAB675C609A3,C0DCCF980ED1D08B,42A7E9C218E0172B,0001534730A952BE,8C9B7BFF78E757C7,C9A02632E18D33EE,0AF6BA3547C7B5B5,3E08307ADD136239,F9FAA76416A77DF2,4F690B26FE43BE2F,0001FB8AD5CDE633,0587DAD752BACCA0,7E2C0C487E90BBF4,CBC6FF5829AA4ABC,79E2E636B5E3E93F,9C99F006C2B70BB3,A262CE0FF3E781E4,0001AE4B1A48298B,DFBE385C1F05D481,C9D310D30BB002C7,8A4DF6B873826BDB,E422A79A1DF45B0A,8139BE7A1E536183,B57BDA077F024FDC,0000EA77109A0BE5,142009BD5C32C014,55E04974F0416D70,FFF0E6DEE9588AD2,CB279A927D6A7321,76D3316030B8D71B,1CA80155E1EF4BEE,0000B30C0FE90C15,B684605EB60F5CD1,F37776387F490518,FA39E744B6DE8D92,F579F767029C1CBF,E943E94DF91C2A9B,ABC0A1A3F4F55BC4,0000258B7F5E8902,041993BEE1555702,45696D1976E9C06F,75FD01AA22A00CBD,2BE5E74BC3F5087F,D1121019A0680B78,E5D3AC242FC36128,0001EE7C23CABA88,78E242EFDD9F6592,C12686605D7C701A,401B6D65133C6C03,94134BC81265ACFA,4C90D258C5911858,60E050B43B734941,000205ED43A746F6,DDBFD5974FD45EB8,D2F7C511D6B5AE6C,17B7D41E1437F95A,E09CC1F139088AC1,10340A9E075D1C86,683484A5E1FB1AF0,00015C0F3E56C231,A8FBB1CB7E2F9432,4E672084DE87E254,DFFC125D604DBFAE,FEB9BF3FA0E3C73D,3E26A27AD6CCBBFC,79F38C26D6CCDD45,00009511231CCDD0,BA19E84DE0A36558,8F8855C89FE98588,B965D2C14D46EDB2,33B7831F5BF98D8A,4DB6EE477BF29065,0A28484109EDDC13,0000C0482216597E,C56FB8C8650BBDD7,B64C9DC5A984B2FE,11F5553BDC0F0184,922DEF124B57747E,35E434C559290EE3,7A3A555D2593772E,00001B7F0C8C8623,332C0AEF5D326416,270B50CE325F491F,F55E54A726FDFC36,A60A0BBE6E9274F4,B2234EFE104FDE29,5FCF4DE2F26AA370,000087F13C53A25B,67A59C5441A2C320,75AEA67306A16540,567FFBA7E9DB8BA6,DABF7F0C110DF151,6FBEBE27760CFE20,CF5DD2F0A7219A99,0000AECB925AF651,3C138763CF994A72,B53ED28A746AABBB,22080277B9D6D8EF,12C6F070755F0953,CA1A6ED2B89CFF6C,176AB0F706CF3884,0001DCFED1FE08F5,62F823016BEDEB17,C74340CC1E369999,829753DB1D14C9DD,9A9B83CB89111505,45EC3BCA9FFFB293,A1807E3D444A9C76,0002339AFD348D88,C854CF4154A99456,B474ED6CFDE85BB1,B35E9F9D3E0F724C,2EBE654614F7BCC9,F0CDD0564F8CDBA6,9A9B57864C1E9387,0001A1C5E84E8E7E,9375DC2C7A3D088A,DD9A8F8052949DEC,CCFC13B4DF856898,E8CB80D11773FA85,73832D1799BE2187,0FAD91DF4D9F8D50,000012FEFD8E87E1,323E5D702F6FA503,E80D3973D21B2F86,CB67209EBF32F951,B4FDB1A2AC3540DC,CAE8E2A6BDD6AEE7,903857BE73C91DF5,0000F1D03B13A043,3D351DB6917538F1,66FC6D6D61DF35D3,F9ACCBB9F4AEB7E5,2F9FBF5987A6FF8F,6D817118B09E9E4D,CD5A0CB965B5B58E,000052CC30F434D6,ADD3A0079D75DD73,2D6B210894ADDA68,AC543D1C7B7E8292,3A6033E751D57E42,27A1CEA6CE0E07E5,338DB4F5F493AB34,0001D53EE74CF543,0CD7FDFB89C36DD5,4A3CF9D5EA5D9ACC,37B2875FD4DB77C9,7E74C8AB712522AC,40ECC3DDCBD05071,6893613FDE3542F5,0001F0EF414C1114,E8146898FDD3BD40,7ADC4A7C2A15A971,66F68460C56E3F95,A1944BB650115B8B,8B52C1776D022158,086849A9FA0A5876,00018E46F8D5286F,38AC52A8D13C0E3B,E24DB7122E13E0AC,1E3311A924D40B6C,63C7842722DD74A7,74D5562DD7805531,D1E73CAEFC80ABCF,00021E193D7CFA78,302B1D4F2D03D003,E349BCB6BD1EAEB7,5EF87BDC28D31474,0FE185CB3FB65AC1,79402C193CD4D678,3022CBCEE94AA868,000144BF372494A9,07008F2BCFBB126B,54893AB5D5936BFB,554A0A1BE77BBFFD,8AA3064387DB11B9,23D59D045973554B,B35D58ACB226C96D,000089915CCF38EE,3EC47527F44F7F2A,054FEAE18D9AA940,27D744AFF4E7FBEB,49D428C460C49881,CF93FB15F27A70EE,F7BE22A4CEC0F587,00010CD6F7FA6E4A,9B175D83CF043DDC,B79C5256D1A1C515,3D2F83212C2D857C,B61EA8593125F7D5,3D88EFB357A8EF99,744FDFA4E6B31F21,000161134E1AA461,21D0CDA24053EFC9,624117E76F92037E,0998A57D25BC89D6,CDE8E5E333DEAAEC,918C077547B931AB,52ADFB86CF158DC2,0000456FA09C576B,76D8B5A17744F984,EC64485FD9175E9C,931D80DC85FA78F1,546B5217D9EAD70C,88AC8FC34A9F5D97,F0316D811E81A3D6,000046C9339AACF0,CBB34B9D89BB43EC,86E7EC61A5A23B15,86D7CF1B45167C7F,87D3696DF4BAAA0F,D3530A33170616BA,1ED9756A83DF90E0,000222902002B703,1CA6C3D2B2E2E1E0,16ADFC353257E80D,E9C5BF59006614CD,36CA15F5582A3DE8,5358BA58B5207D48,0FF4DC683B7FCFDB,0001F608EE98158D,FC28A4FBFA65DA8B,B1474B0DC0BFA92A,2C8EF2C7622C97B2,68C10BEF3E0C95C6,8A17AB524DD917E6,197857B8DCC360F1,0001641150FDEA2D,5D3AEBD878427AED,0A595F596D56EF34,58080EC5F25702DA,4B04B56C669D122D,98232D1AB1A7BF76,2D8A4038FFCF6CC1,0001475E35588A65,8F1A467E185B02B0,4F7D39C893FA5BF5,D791AD1ECD2BCA0E,358DC0B01FFF616B,68ED91B60BADE7B9,B06427632804D6AD,000087A43B9D5D31,1800B8FBB8FC798A,B03A02285B53AC05,B01A2CB5FFB7CECF,0C868699292F52BE,DBE4590776ADC240,20B3FA20AB7EA465,0000DA80BA5B7741,4A18ED41CD795AAD,CD4B539C65280673,8D983A9724260496,09E0A2830B3CFDAE,6BF2A3FF55446C38,EFB3FA72C00FB5C9,0000BB57EF9A59F9,E0011FFFB13DC712,D48B19945DA4910C,3E1BB665AA46C470,C07DDFA9D7051FAA,02C7DEAC9CEBE157,3C2B317A39ADB6FC,0001510800CC8B59,08B7F2D718EEE389,F568B2597D5DBB4C,F7BEB892EC39F50D,7A1991741A93FE7D,ED75EFDC263CAF91,5C8CF66EED677667,000060B56AF7D72F,03C8E9A3B2441F7F,07986CD3EFC13BF7,BFE8838766AB09A4,45B59C53213A4A9D,5E5F0D09EE0556B2,D23A31B23BABCF13,0002252F6842216C,C2D09281803834EC,1E97064D1A2C41DF,87FD828723B958E6,DBBF6EC42BA6CFA0,108F46BCD53843AF,D09587C708D8B6CE,000189C8ADB3C20D,23C7CDD6D100CFEA,C9F19C20ED1184EC,9C8D90A57EB0098E,E2E05BC2E130FEE9,40B5AC71F9317C44,AD4CDAACD0C49D25,0001F6B5909F3C75,8BFD81B32A71F2DC,99CF65C5F1C2AFC1,5C0E7AA28F725F4F,A7ED4C812B1CAA97,74DE912D9C490B68,F200BB350DB70B4C,00021AE752818364,917ABE0A58AD0B49,75D96809F6DCAECF,86694E0F5F9B94B7,367CBB2D8991508E,B50B4A52F7B73A03,EC4C99C657326F53,0001063B0D5A0270,7391227E2F3940D2,16546E147F1085E2,FF0004AF6F2B0CF5,B74EDE1CAFF1CD05,C88958F4E05A02D8,692091B124383D3D,0001C59E491C9DBF,3C138B2667FE9624,DB2EE5BF287DF247,E7FC10A195AE5E75,B1AFFB47E106DA7C,42A7D67E0C3063D7,EE6A36C2D51FB3C3,00021EE9FE1E523B,C4B428465B34D1D4,B6A85BE9F4E145FA,7F352009EBAF0E73,A7395F4D5496FC9F,B22519FDC5CF921E,A62049ADD545618C,0001D3429C7DD58D,2866BC18CB46BD17,1C58D567E13DB996,72C4A57B5D5A7541,201DDF99CC6B3BD6,3D7A2A4AC0DA245B,CA51DCDBC07BD234,00005110BAA3D089,1116D30EC55E2CDF,469F44626B9451A8,5B6FAE4F802265B2,DE5AFE003510C2C3,84001F3737E6E5B3,0CC892254D0671BA,0001216BDE1E7437,571AA7461F23ADF5,7CD8A68F8546A671,33AA613D421E560A,92B2FF22E9BE3F3E,25C4C59534E579A7,204FD28E9EC5E8A9,0000B744BD89DD00,8BDB47FE78C58A63,C8AF96E36154ED6B,48CA77B0CDC0D9FD,4A76F15402B4E6AB,C54821764B36706E,3C310BC3CAE37214,000156B0323A0EDC,0011C4B546AB650B,2FB1832627AB7A36,E928DAFC1EC60447,0614ED00BF97455B,A06BAC697C6C109F,7E0789D8C01F7692,0000E43B338C83D2,13D36B2E0A82993C,82F771DFDEA9C153,E7C2D2BA3621193E,EF4C94DA9B01B3B8,E1A0C29966E8EDB0,715B1331197EFB71,0000AB8D2681E7F1,CDE41A4D8A7B2F38,0A17198B6471E015,A6892808FD52E49C,E790A5A9BA1F0E6C,6C72246B49A57BBF,4C7EB3DC4638D272,0000A8321E2F343A,4C693DF2D402EA72,1F66A4451F1FA9D9,6B7A389E612C81B0,24845D952DD3C2C5,AAF1A3BAF75436E9,4046EEDFB08F1E47,0001FDC2B1AE14F2,D09C7048B2693602,C695F335861CC110,3D753B4DC95F0D4A,147503B9BE53EA72,54B5A00195E2A82F,9C3C20E78077E728,0000860054859461,644172A1EA9E4088,0206FF42A4F4A348,A93C783264D738A9,631D107D59F640C8,FE0BA60D5B04B5CF,C8CE2449FE2EBA76,00015678C7BDA9E5,F06C1736F9B15964,AE17762508937BFB,56FB2C75A284C71A,37E0807DC1E42489,EE72E0DC7E893FB1,8E53FC875D42A13C,0000719FB8FBEE26,CDF93667CDED5DC7,C6F00BB3DA476B48,0E7D67CA55432F05,3D89F1D7EFFA56FE,707DAD6CC7F69745,4BD786B67A96D6C4,00007EC9B721B144,07A9147565FC88C2,38F9DA45BCFAA755,B45C3C0BC75BAFA4,23FDCFB2BF1F4AA3,D4B06526852F4729,94B3B4CE42C8826F,0000E6E131FF7431,50115ECD29C252AD,563E32B8C8F96EB6,03475096041F619F,4C8AE40BB5ABD7E9,82DDBB833206A05C,5D02B459BC59C29A,0000A790B0BEDB7E,BEEE458B606566E1,C9FF6198FA803325,5B95D01412CE2003,DA2EA59D7FAEE8F7,5C2B20ADEAE0B6DC,5FEBE137B4CE7255,000120EDD9EE527F,8C9E2F1E345DA0CE,8EAB7800406DEAED,2A9F68A067B46DDB,06706A08ED4937B2,E2F37840CEDBE1D1,39A4D5E6D00AE582,00018407837E6928,7085353078CEF7CE,FE0521C0E4B3FC18,D2AC37E4A8136051,1A51C993D7D8C202,76D8D888A3609C94,4B31571DB735A83A,0000E6912C387E83,2AD470C13F5BE011,5A25E2A5170E1687,15E32F5F6FD25315,942790FEAB3E34C0,0E7A7379C8989171,5B0BE6E3C01BA44B,00016DA8BBF2656B,1D573E6738D507E5,6EC3CCF804604CCE,68C2B5B032402C80,4332F1E9C6EE3925,DB5A5011AD12422E,DA611B7E0514B894,0000C997E4B07614,2ECA13A788636A2D,019C7B8747FA1CB3,3CBE8316B19C8D1D,063DB466A8511E55,2894B2485EB7C911,91CF8FB66AF0985E,0001A9B449B0870A,BCA642E857C69A6E,02A33C733CC98648,93BD861ED33AE173,721CE8F40BFA0C74,86B59D0066D84CDC,32AC4109842ADE0F,0001C9CAB1218A38,014164E4BA40C66F,89919DD73E4FFD73,B7D9D85605DE8EED,953E311A1E984E8D,59B0DB523A0B70D7,68C9D0ACD8582C56,00000CCE90FDDB59,060C103C57AEAC2B,CC04A384ACE34985,C5E3F037F5619732,EC811F49B2E13282,68F8949535C6699D,F6E1CB5C029D9574,0001661F1FBCF906,17F5F87E581DD90B,76C75C6DF6ACBDB4,F8425252A03D20EE,CFD56D2E1396821D,72C8635D8D6AD936,49DA47D5A840FEAF,00018F8065DED14E,81C7F31D8220B884,3A412B3001EA5CB5,873E7140CBFEFEC6,B2B2CC6B88AC84C5,8AA5AFECDB5A5E46,BECBA35116516F27,0001A5B415733677,EFF17513DAB4D8E7,0FD6AAF0B8982188,B0F4E4E1B9B6E64B,BA1F049576763849,775F9B5189A008D6,5A204B35C39C21A0,0002054328F3335A,64E488C8AE2102BB,7E576576DDB0FE3D,4FA1602913AB5887,4C9CBD4ABD1C9F34,B762D5E4DA2A5C59,EF256164ECE4DF8A,0000D8DE48CBB4F2,030F5D8DD9BC09F3,B8F7DEEC7D0D26A4,567A5FB5D33C194C,552D3E7DD367353B,9228546BD3208263,FC29154E4F455D64,0001CE3C35CD8991,C305106B26D2C77E,26C4FB697C1D807F,96F34594B87AFF3E,9819AC00B484843D,0707A6C70D9A41C8,036A8FF403940ED2,00015A422416F895,D5713D0161251F67,988F6AC779B32BFC,AB6E9B87FEA799C4,196274F2768ED7B5,34FE23EE102F317C,AA811D9E41C864EC,0000B62A2ADAE17E,639E0FEDBA8F533A,D3EF707DD977E1D8,8B5100CEE274AF72,C964AB539057A84C,359182836A510FA1,E925CDFEC4EB535E,000155EAE50CB348,E226A8DC0FAC8160,A9A96D6863695A58,735AF6C9BC45063E,4662B8CB37E7185F,A8CF11BD0F2A31C0,F7078CF89E67F676,00022DF11F1DBA72,3135C0E9A66549AC,576E31C4026E58C8,2D360A3F153DF333,8D78860FA6DFD8F4,0BD2AC0C16E2F575,73D4274A841EB0AD,00021DE311DCF983,F66C2DF73CAA5FCE,DD89D0517F62CE0F,B1213FBC864106AE,909B53AC064FC3ED,6A060E16D52ACFD7,B1C5E0BC823BA286,00021CC677B945EB,CB4BA71B806985DF,7E4EE57785A7D0CC,B79F5346BA30AF21,D444583E6FDBEE4A,FBC87789D9CB8F8C,43792A7BE59386A8,000024FA2500B1E0,4588B0C884E33CF8,985976A107824F0B,B28371C6221B8DD1,5D839B2890D03C17,C78ECEE962543D30,CB00D17A602BEDB0,00008756461348C2,A004A03F20E5B63D,DF759DA453A906F8,30A9BF93340A9DDD,13351B17F5CBBA8C,FD9F70C74BECEF79,901BEA04E3FE7E89,0000DE30097AF79D,D7BA4E2A8606D822,B16F5F17044301E3,49B2076A7479A069,4AC85DF8A28CB9CC,C4C5A36979DDC7E9,C38692A0F7F2028F,0001FFA2DF6C5548,B2A96FAC951349C6,AC8D42B8DC1597F7,138203922F993ABD,E99FC10E608DDE4E,50876EB46DA4D507,F21B3C6484E55199,000017B29EFB903D,C7BB4489212CF68A,CB68CA2E20D5E89F,07FCC4E073EB8E73,167F28BF1D650526,00CAE4AD9409A43C,8CF282B4A622253C,0001DBD125A4F22C,984BD63103D5488F,00B7E3EBA73D6097,F91954592649933F,00AE33DC00E84855,C3FEAFEC10C7D528,E4EFA47D7961EE87,0001AB870E79DBEA,CBD8A54FD79B8A6C,416E620CB2CB5D82,42D91FDEF7A7FA35,D2F30A6271EFCAEC,A60DA40344A5E808,5CBE259E18128D73,000220C29F94DE9A,73C91411808DC80A,03491A42ECA0AA62,CE26632F66FF18F9,B442BC97EB01697A,D2418CAE179700CF,C23B2CB73FA4E183,00014117AA3D141D,964102E56F84F6C6,3EB5055C4391E5F8,9497777420A6C167,F229228A95207113,4C86B4AD5CDFEFD9,D59057A8A0E5CCFB,000167CC724B7C4B,DA99CE5A72F48F3C,B56DDD08437C101D,D8685683F4EAD341,EAEC180E28FD5536,F7DFDF1708075354,CB3E9F1524000E51,000145356669D8DD,E6E31F32FD35B128,2ED431C2BC798747,7D0C00DC95049B3A,7CF706F6DA45D73A,631790885C209640,634E4ACCECF57216,00001C56CEF8AC6F,7FB51DF97F825E0D,512D8F04AFEC4D0F,C879D4E785D811BA,8B2C587AEEA60022,8D460617146F9DBE,5C358FCB9C4FCD36,0001C02AED73A974,BFF135BCA8DFF260,9D19FB5526B911DD,4CE74F4D395A9669,2751CDD6AF3D933D,0F2E63D4652FF173,D8EE0481DD63E654,0001B55011716155,17E336E3EACD0462,415A523E3531AF63,3BF3ED186532EDB2,9648C44F42942BDD,25CF04D5482C2C1A,49B34D0C765BFA5D,000226E8CAC7EA85,8FA17BAED0B117AE,D3E059A1614E1AA1,B197DA5465E8B033,BF33A61B5D4DF4AB,B69D6CA017336FF4,99C216A91074D132,0000CD5CEF213D7C,2FC15251645460EC,444E04E7BAFA305B,6A3F3BB476B1C964,75CC1A0D9CC71981,37C083DD6328E180,EE7DD99F4DB50C0B,000018DB0CB9CD46,2DE0E7095F9E432B,402279E6DCAAA087,C122885CEBE1D192,4530366A329BAD29,C7D8127BF80A327C,3F9A52142A5341E6,000012DF0D8747CB,F015D1198BF89513,C7295616FBC390A8,C828DD93B2C88244,9EC5762588D7DD41,871CC1F5D7638CFB,1D4764F1AB084D94,0001C3BB7D39BFF6,03603CBBBC8415BF,A263ECD11E1EA27C,532669C04539D538,A3FA40EAE86F2E8D,7AFA1DA9CCA13A64,69CA2836FCA13D5E,00010031240E70B4,BED38F08994DB923,E5EE785B8870239A,B53CB4FE55087EAA,E10AF74D5BCFA7BE,81EBDCA0FC2AA63F,F17140ED8CA25CB3,000105A18E2FEA52,27D57278F4170F3F,351DD83485585A0C,4CA9C5F935BDEED4,D23749FCF4088B51,686C775F9752EC22,94D7073E9DD868A5,0001DE5125B305A1,CB68A25F740B5A57,E6DBA61A4C8269EC,5DA202768649B821,793FA5073BD0B3D9,5A63B42388F07F23,05356B558F403B61,0000F0A19D805918,9315E5EB6F77BC63,2AB9F7EB2A078B60,7F06A91034A56907,5A5453DAB980A401,5B0AD99A941896E6,00DBF0F9F7CB74F3,000219EB76846A15,CC2F54AA41A33127,3C0A66AB31AE8618,1DF1762F1BBF7146,D36FB447EEFE27AC,0F9CE137885299BA,C9037C0E53AE4D9D,0001A3C52F4709BB,081A736028FCA9B4,6CFD2E08C45D85F1,13037DE01401FC78,010E7748FD806282,74A0784FDFB5A3EE,74641417CC54ECD2,0001965D210B9B76,74CA9A8DF0828173,C017D95337986AFE,0908D0976502F47F,7B0E617C10F3A719,0A5810608CA0B61B,29A3EDB33AF4A51B,00016BAA741D438D,C7AAD347C1F7CEC3,92C280D4B2759C2F,57BEE8AA537402A5,678B69295E34F6A6,7C713AD087631AF2,CBA05CBE63C5D501,00000854DFB6B3AB,956A29DF83F0E3E1,4DA966F8B92ECA8C,8F8398FED7D3B174,E37F46548C209668,B219E858CF8F0AFC,014D4056D74C2A65,0001F5F2428F91DA,030FE8DB8EB9B955,7E18F1E2E26F58F1,07163E9AC574AF5C,2971C981FAF3D808,5EFFE6EE2E77A3FC,542C2ABA37CADC41,00012223805FE42C,108A6BC68DE3635A,46E368D25E43A987,8BA1901BEED033E3,25BE01076DE2659A,CAA13D2915C066CC,F05EDCEFE0E1AD62,00021374403B79B1,2F743C02463DDCE7,217B3588EA10CF4C,B95910258A684F8B,DD03B1DFE0C18D3F,E86EEEB01D62894F,F418E35CBBE6A180,0000180F61AB004E,8D006F420F845F02,0930B66D7FC41C35,81E51DDE184629CC,04684F2A491CCEEA,DE12A8DDA7F74523,E60E5DBEE40DCAFF,0000DA5B775101FA,A1F3184358E9899E,D24984857518C270,8CE51CF7FB337759,E78D859147E88C0A,3A35A0630567190E,276B17D663F773EF,0000F04C608D35C3,DC1744BDC2282BE6,A20A1CB7B76449AF,A152AD8E5B89DE00,CEBD7D9E13472AF5,9F83976DCE4DFD24,EEFA65EBF2EC9708,00005A52EE996A1F,EFB429D56857C868,53E85CA24277AF3B,562636995BA13223,195728F853ABF266,8840A82F442DB5F4,A36AC3EAF9A9AFAA,00015B35788367D9,6A8143E61354D153,6F84336C35DAB238,95E6DD5389FE6D76,0E99542D84394EA4,046D89671845262D,C81DC7956E9C71AB,0001377DC9EE1C16,3094E5BF64EE8446,6AA9D2FEE499E1EA,166A4425E255F8F5,E549230D3987677C,953C32858EC3CE36,6CD3BBACFDDFEA3F,00004831EE8B4356,CD27C68D25989EF9,4B165542E7756B28,081029A70176C7C0,CBDB74A045A870CD,9E028A39B28E2E89,7326540625E94F30,000102FF6D7CC3A3,7DF239F46B469385,C71E29FF4BEC24D7,14AB2A3D24A3B118,C3288CDBBDC79599,FAF421ADA9C50152,B7927152EA7D521A,000186EF1C780FE2,55BDE2A7C37ADCDA,819809A5CD0BAEBA,0BDFDC925345BC0E,426244668DD92547,559D759D3F269DFF,7CCBFC0E4A248802,00008744CBB41749,2DFD159A84E3D935,9DD7EA4765E130C2,08CDBE4D7EB2B8CF,1E35C82440020B28,58E078D7A0060583,164588B223AA2FFC,0000DA9B105C647C,C16C6C6857E4194D,793D04132C169E0F,FD38F5D003166FB8,08368F1EB6D3965A,2195C251B2BAB984,2B8586165998105C,00021830D052D788,49E78BE05122C405,8A7DC217F7435FA6,CEF9FA6C1FF3A345,1D581F7459D53D8D,806762F17ED6D6D6,FBB99B4E017BBBC4,0001FCCBEBDAC3CE,1EE272F0CC551CD9,A91E6DDAF322DBB4,6C625B9B52FA453B,4BB140A5181776D5,0CE8CDFF4B907A4B,8768297F0350BDF9,0001AA2D2448B202,2E85871CA7164EFF,F5E64B30E1513418,D8265C8D46907338,B7D2E92395785E0B,CB3215E55AE640AF,7BB3CAF6F812E698,0000167F2CD2C942,E05F7B29FD73B095,E9C47A2D3BA1F0B5,0C5289C3B954352D,F059A65C867976E4,F69C62DE9335E579,887BAEC160BB0AF6,0001CBEEF8E61927,D770E5DD00F37F73,EA42B8D69FD89D27,E49AC4EEF38B9323,AB6C12B98B029DB7,C8BFF6286381241A,1D3D501F742699A6,000032D531FB88B7,1410C01F8573A46D,108A27AEA705FE38,0CACCA3BF7AF7A7E,61C1CD4957B43001,6E18780BB301434F,0153B8B33A48F281,00022A111AD78587,A2E09B4DDDC5459C,9A35782BA8C59C0B,58EDD50DD192BA89,43FA10E767F3AA1E,3B052596CA183C45,BC9C83397DCE1B27,0000A8DCC67A9854,32EEB6F7BEF9F880,ED80D3265F64AB1A,5D90898C7417EA03,C331F5CD121121D8,8ACAB7496375DA1B,7DCB4778C045E38A,000074FE500E117D,87883B9FA0E635CC,1C72CFC51C6ABD86,800D557FA904CEE2,1CBE546A9C0238C4,BE9E7FD23A1935A1,B415F0AFF27B7152,0000C7FDD331A185,209200C726598D53,86EFBE705E47A6BE,6B6819B5A304AEB4,385D11E4665E3F48,D79A3B49852FD657,420F584D1C478415,0000D4359DF9F980,0E219C920EB55B75,37158299E4315B61,DD2A64132BFEF70E,4209644F31987E7E,A9B2F9A9B7524BB9,51C2A8CAE8C7ACAA,0001D55C17C1A929,E547B9BF0B0F1A58,285872DEBA5AF50A,FFD08CA052FEC47D,9D2025F9F5CD84F6,6A54827778085E0F,F7B7B2A699650322,00001A4A2B00CA97,C2D24E7515F2252D,770E4293C6F49BF4,30BC90C5D3FC546F,B1C9ACAB4DCFAB21,3C05C57ECE7A0190,03D0AABF17DE76BF,000211E87293D95C,AE7CCFBC2D96666D,B4F8E23B0F24FBFF,7BAEBDBCA765B5CE,11315B75883502B0,34662F0D679173D9,6822FC9EDB6B259C,00003116468DC55F,84F43166599C6964,32D145CD6DED600E,560899B5C44DDA1A,9E523E600179D7D9,C99768C62B13B97E,B7FADD7519AC5C42,00006815859DD6FA,2BF583E878A9939C,CA32AF9E8EEB7469,8D05E1A1A6A16227,3CE580085F1655AF,20DB88E775C72DC9,6E57501B74A170A3,0000CB66DB56CE01,28E3A8A709802C13,996BD8D647AECF0E,A6B09BC15DA60AFE,574DAE815200D49B,10F5B95CF32152C8,1E78671E7A787533,0000448263285A9F,8B2DD406D31DBF65,FF1FE480A06A43FC,624308666A6BDB29,46ADD5459A73CD61,F9CFFB9174BF3555,F79C43ED8D9D711D,000030CAC80CC048,C7EE404FAE8C4B93,13265D769DEEFA50,ADF2B419D043D512,2BF2F7B455F647AD,6FAE83ECA115F074,184958E6D16848C6,000110C46B420D64,BFB518424FAEAC9B,C42E8214A6769335,65DA3932E38F7D05,E22CE0D4F5270EFB,8A35C5CCAE0800AE,5C4C88DBA65D1C35,0000D23810109B95,CC9785563D0863F0,0C33B152A09103E5,848022B87F16F5B6,73D15EAD9B301C77,18D0171021CC5693,D1AA17FFD93EE64E,0001020A8D58E1CD,129AE46B16A7563C,9BDCF04DAFDBF40E,F3CEABC6855677F7,A959B80477C772E5,8BEDE8D5C931E151,7D05FFA5C03B90B8,00007B80E6BDDF2A,D9BAF5EDBEDED3E6,EC7698BC30B530A8,3558B586DBC33C03,F7758630BC9250F6,D03CA0C2543DEDC3,F12E7B162337C887,000199F7CF03164E,831EE0295A845745,CCAB4FEB03214231,A1E1260D6AE3569E,866AC937CA4BEA45,207946C0CE60511E,AA3BDF3BE6473AEA,00001CCC887E4930,80087ECE06FA64CD,1A1CD6D232012188,025A93126638840B,88AFA87AFCD33478,39C6223D02F51718,53D88316635D9040,0000F2CFCC601155,3363301E79E7D4D9,A88A7B32CD8AC315,AC440E8E744F0600,4DDD179AD10DC4A0,FA24DD12B5D66993,F9F95858416E02E0,0001A765AF5E2975,1E2744D55AE87200,1921DE1FA00682E6,FFDB0DE0C45C34FC,38EB445A40B67D06,8966A3363A7F9770,8715DEC6549C2C5A,00019F40192723DA,C11BCAC845C0A278,C284D43F0FAA5950,07C364B1B3E29054,3723C6D239517BD9,372CEF626B95C145,DC155487AE2E931A,00006C16E7D5E4F2,2AA757DD1E04E97F,2FF7938521154260,1E58BD78E525C765,2349821B9A8472FD,19C9600A098813DE,6B73D650C8BA8FB7,0001600EC9A55AB9,84A7C78C6DD146D8,3ED1E8AB8A2173A2,4B6F85555D5C07BF,30473F111FFCCE50,798CAD07CDA9DF62,4EF7EC1A2CAF54D2,000224E34F89ED6F,32855D5917E2375B,7B85A1CBE5F7C032,3AF6AD32B081DC6E,2DA55F17464A4CE5,9BA1DA17494FD095,7120E4C4EABD4E7B,0001FD0288879289,26B5A9BD516DEFA4,7267F8818A0D0F96,5C6451B8F6D8B82E,625E1B8882A12FFE,9A10E7F9C1374411,21D8E691C13650C1,00020CC5B74A98D7,443DE0BBA824B0C9,5C41CEE787FF22F9,C0BC7C893A3C1725,047115565371ADAC,CA6A45128D004BD0,44C0686A95F1218A,00008C05A9146AD0,CB7F017F793688A9,0B6F893F161F7AC7,216C4D6CB5C45CEF,629B62DDDE5CC8DD,75F00C9552FB6CCA,DF774A43068D6896,0001B7EC15D03C74,5AE07D5D42B75B3A,1107872250A2C8A0,5566EF3AA4E6F788,02D59668891D8E0F,4170CE15968F3CE1,366509182BA372E6,00005C04AC223DCF,E2812F2129D2E30D,B3376E743CCCB419,84F6BAA8749F30B7,1F72F1534C834EEB,66606AA2CC2C6743,17383771B6877A59,0001ED9771E01F7F,B7EE682865B22D3A,BD4AD568DA4424DF,7F43899B74D43A06,6489A3061B335CE2,7A1DB2B688517940,B055DC3481ACB3B9,0001AA866A039326,14511CC10D4DA9C7,28E8B70FD2BCC827,ED96440AE7EBB121,B90D7C8F2C8BBB8D,0D581F2718C222E8,48849F09118A7F83,00007F9E06755547,1F78DC539AC32C46,F87D5660462397F2,33E5A3EAE5EA39C5,E2987424751CD2D9,2BE0E8299DCBC21A,FA24A868CF26DBCB,00018A56E915B02C,5C3CC7B660750027,5AEF691080D350EB,655E5698AACEFBB1,2F260ED054322662,BD07367CC21584D3,6DDF11F6E6E41889,00011C0CB8B73A4A,D965C5B012CCDB19,BB2A1606B739B3CA,E1408FE2BCAEEE21,9B601A9F7B9C01EB,6CEED0B1BACF0801,3A599748E401D853,0000BF2DAA2E4208,8F31FAE9D580943A,4087A885EF397E8F,C36BDF1B200734CB,DE33012A8A6C066D,A049A91ACC0E67BC,C97E543A138604F8,0002085E419C8B2C,18577818774D32F4,5A0B999578B0A220,494C6C04C69874B0,659B7BD4274D12E4,FFB31661588F5D15,DC8B22E1F64ED4B6,000088D3545131D4,0ED7E3520268EEA4,D21F55F57489D267,670722E419F27606,6FB10CC4C054B2F2,4AFE9B1E2588C368,07335EC9F158DFFB,00019CD7BE99D91F,5F2C637D0F187A1B,3C20F77197577173,139EE50D9B3D9C61,E6E9CDD3AA3E83ED,DAA21906C0BE47E0,1010CA9042F3F674,0000AFDBBB398A7B,AFE1490679C57FB5,00E4566328EA19A0,5DABF1AB3EDFEBFE,B0BD0FE2919A94AB,3FC27F5AEF36AB76,26FB65E3AF8B3345,0000F42235954360,34CEE389A3FF1189,1C18720BEA83FE77,6933E9BA3F4CCC61,6F9A17D33902D61B,E6DADD35CF766B4A,628AB5A69163C8E6,0001B729A9F0C2A8,C6335C5CEC8AF4E8,45F6C219B568D701,DD975DAD50031223,CFA3B26FDDB1AB3E,DFD25632094FE84E,D9F62AD025B4740B,0001F69D13BE3EBD,B7BD7567818B275A,895ECBA365BB256A,F5DE88A55583562A,9FD08EACC8BA94D3,AAFEB1F4DD80A0CF,CFFB9803D85659EF,00000FEBF4A62972,AF23BB44C2F21EFA,685DEE8243356D69,4E0CA280CD0B59BA,15F96F1BF3E98872,0B1462EC7EA089B3,D91EF72E9119825F,0000378485DE1A19,516747B2EC4A6C7A,0D70E3D75DC26032,ABB48EE144CEFC9C,C10B734C9AF098F1,7BA9C04CB0E31900,1988899F9ACF5B16,00010ECAEE119172,B219826480D60B41,EC4D2827578D2699,6583C723733F23B6,E0C410E9F0315353,154B5EDBCFC99DB7,B0627DE28550F43A,0002111913E9294C,B3DA4468CFB744C5,C06ED6B0F282B7FF,6CD133B00BEF6819,B3B9679F431E86CD,D9956E2615805CF0,0AB50081490CEEFD,0001287C8C5CCC93,4D960797D35FBD8F,3D7AF175B81FC783,ADA14CBB02064C93,264A15E8104C94A5,82BE28A9383678BF,7B6E43E6871C65F1,0000EB382670E50A,824FBDC87B4D9071,08A3532A73E9CB6C,E3D4572AF1E61DEC,142C0A77A3FAF141,60793072EA5A3EB9,1CACA85F6A0E666B,0000B606CD594B97,0CC66248117B9BC6,D611BC7A2C15ECDD,885B0E2B341172EA,E285AFB387AC9423,03F695A73AEF3533,FF8BF9EBA5C19398,0000883DB65F9322,A476622EB2EE9FD3,42A4161CB4C3A1A5,253B77B3984C344A,98AE8863DBFE57B6,3C5E0B17031E7B24,8C602044F4394217,00004A3E9F015989,949C369803C27A4C,0098BC91517BAE4A,B56F7A5E7FE54865,25217B17A505B873,D8C4399B8CED2320,BC08A5A4ED0943A4,000217FF568B662C,0808DDEA0BCC197A,4B0B1BA1D71A4938,111ACB3737EAFA21,C125AC47744F1EF2,11866D65560C6AC1,516D0FC3052DEC87,00000A199B26F5EE,C944053DC687ED71,F17738E3A50372E9,C79F3149D7B697E3,CAB04A56CC35699B,23FEBAED57F2F582,C9DDE5A35EAB44F1,0001F824FBE76959,B67E535CACBD5C1E,ABADECC9958011E7,236FB2F47E59D1C6,7F9254974139CA36,6E888F391B740DA3,FBAD94C756F52A16,00007B93900796E5,DAEFFC6EA5BB9F59,FDE45C25C374289A,EE5AB37598DDDB5E,0E5D72A20D1CD58D,55EFCA05D695C251,E2AE69A7DAD93D9F,00020407149C5282,62F67D2F2222EF28,5AFF309B4564C0C3,72CF7D0BE95317AC,C27FB41C3379664A,C47A3A22E93A87E0,6127D0EE5EA68A46,0000405A6D3EA16A,FB160FE0E3CFC294,E9CBAC26FC388AC2,528F22DAC7B66184,D994076CBE4671CC,3CF754CBF56080D5,6B10648475614DB5,0000FCDBBBA549F7,1A4AA13096A3867E,AB9628CD6A9674B3,96462E186B11C39A,88B961A041FF966B,AAE2505585E76BA7,1D68FC5F71C84A0E,00003D94788E69BC,84B4BFA1560D7C3E,3EDFA10ADDB81EA7,9120E11D33219C99,744381A4693CA35C,0964745449FF4558,924440472EF5A3F0,0001AEC741A04C7D,2730B150978EEA50,D30311C970FBE092,044FF8758EFF5AD6,DDB2CC26F84CAAB1,51466C925E36D267,89191B0EA8DDD4C9,0001DE95795D24AD,194BA597B128C915,3317A88DFC365523,E4C9FDD8F2B12A3E,88672B792A7A0176,5487DD726A65D52A,752244275B4B3786,0000DB342135310B,C6FFF58AEF13726C,996126071DD46706,4C61C01739E2ECDA,24477EB177F28EC9,690D286C49F788EE,CC46F0CDDEE2950B,0000B085064D36A5,E6C2DF9A84DE0A3C,5F60FFF5AC8F6844,A501075CDD111634,621A006435F888CF,3858A368B8B1F8A1,F7293A6EA1FB5CBD,0001CB3C0FD1298A,D5D952255F0902C3,E8256B302163E940,DF91E368C7344D46,81D9607DC86FD3DF,9D189F9CB7240899,A7E73700283896D9,0000D8843BC39CDE,EE00BE0C1BE58988,62ECA98631290F2D,588D46502B229701,625C70BCA65C8789,6791709E52D8A817,40525B0A2D5D44D2,0001BBC78CF52607,FB84559A45A69CA3,68A4A7DEBE647822,BCC4C9C09DF05032,A04FCF20E1FB2BD8,675B580309AA4A15,D9C056236FDA724A,0001012650A8E178,AC788A680C40AA7C,F98CE4A9992E4470,39C1E5531B28BE9A,0A1E67B88FB1DF13,78BA9C752194A4F1,DFB04E077710C2C0,000045359E967D44,38FD5351E8F83DBD,C63F16544CD8A09B,FCCD44D78099AFDF,6401175F505E5183,56A1E6A581B629DF,54B7866AEE784836,000224512FED666F,EE14F9157D08207A,CC8488ACB0DE2979,A74733FCA479E453,FC1FAA1D78B497C5,72CBC8339F8EC400,603BD9B4DA6298D6,0001EABF2624D621,30692C9E73886D47,F9C084D7B71D2E4D,325C0FF91A405724,645ED7A610574714,2E470EC33E19AACD,49D878633809C675,0000ED5DB0F4F598,702A6F5209C3726F,B27D4722C35E205A,0950688D7E94B338,B5BC0AF63A8B9BD3,0E892BDDA2BF0044,4B995040E46BAAEF,00014A8D3589B3D2,6A126F7775C084B0,BF5C52176ED59B41,8D3C251EDCF490D9,066F99EC89C09EE7,E35C68234557091F,41C19DE9ADD7C3B2,0002312F93557A4C,21B4E08A6022A316,0271680FCC438591,418C4AAFC5DB3527,069C4079058E0D25,0F14AABEF872DD8A,4724C5D6EE0C183E,00013CDEFCAE36F1,99DF76829EF6A030,F9C3B6E2AE2CDEF5,31413996A5CEB83F,F70C386C3022C7A0,2A2EB5857670D68C,54E85D20031B14CC,00002112F1D8D97D,DC8931D82E355C13,613165AB500C989A,12FBAEF02DDA434E,420A9D22E63EDEE5,D7BC12ED86F91B85,415A1C77F591F29E,0000B0C633E7AB53,E2A0605105789EAD,4B8C1459203C3F5A,E846AC0EA896634E,CE464409AB9CB5ED,3BBFAB65E4182570,86200E55D7D47535,00003039D21171EF,283FB8D812BA5F57,717BB21805552FF8,44872F219B3E1CE5,021DF326985AACAE,B50E1A4822445C55,81C3E361B4427C82,0001AACC0B9B5ADA,3D50C1715A32AFB7,3A895D32F6C74ACB,3D1C17E3DAAA7B03,4039B73B2E02894D,ADE2FA12B6A9C843,E98EF923807B9710,0000302BDC30B68A,E6315A9AE1307D95,F2282B5D50B97075,55463FE020DFD65D,A56F5DF8BB26CEA1,B7008472DEFE1C39,5BF3D79747081D76,00017788648F863D,F30A1865D23B9612,5247C0335B2B1F7B,3705596393CF20A8,856E4DBA77902B62,B36C785F31B91DF6,E98AC0408D05C884,000107D694A173AB,BDA7DB94588F1C0A,0AACE731CAA1529F,485123FE1AFF560E,664E1B59A9C7C969,C254481D550D2AC1,3BC83399DBCB2F21,00000CAA6CA670D9,C62AF1CCABF87CF1,355F94384D1B28F1,4804DC218BA761D1,A86BD9BF03483C89,49FFF18DEE06DB28,33C3F473C467F840,00020E1335C2ED8D,21D042EB906098B9,AA452A88EF795714,2AF6C3FB2C29EAA1,E0F474AD86F2F4A8,C018B33DBE859D81,74FB588F2F0F6DFC,00011BF4B8ADD92C,B2CA8FD2A5EF2969,A56A1970224D4993,F9EEF99B817E4265,F4CD5ED56B2B420E,AC9B91A66AC311F0,990BCC9D9BEDABA2,00020592BE256A27,48F5A212A01F1363,52B413564743080B,0F295086BF6E1381,6BDB9E7F3D258481,FFFF7D17E3DABA4B,6015EE3EB1BB4FCF,00022496CAC9CE79,66C0259654400228,5A7CE361C4DB0505,088800D6803D411A,9BA925077651F12D,9CDFC36990C7CE54,27145BE0926453AF,0001D31593C2516A,C9DEF35088D0DBF1,103E73BACCD938F8,AD1A4031B0AD5F2D,8412FD19CC88B592,F27A4A47AA5EF630,EB6357610275DF35,000129CB474F3DAA,BC9ECA01F6AD10F7,E5AC3D3D99EFC3B5,9FC67802C846BBFD,E11C1502A5EB4A1B,EA18F1D61968C0CB,BFC1EBD61F6BA350,0000967CCFBC19AD,A03EE6D168EB0FA1,19BA56AB81B47561,5FC33739E4F36BD4,8E1F50F504BD3E4C,D271038A49830AE9,6C905C731DB8A1E8,00010CC5982B0C57,D6FF60792E390051,4E284DF835E2903D,0601AFB86B9D3A4E,55A2FD35933FEB3C,C0D2E310686DA142,36468EA49F745F7A,0000D00C83579B66,AD5F1925C7C1DFD8,F305182398AE7152,6308C4D9C0EBEB8C,6221EB2D41C9B170,5A2C69A638B81620,4EA4074FCEAC131F,000025609791C140,7D71678DEDB48D09,21D53C22E7FAEBC5,B8E3EA5AD00FEAC2,5722F75ACD508D24,63A3A450AC85BFCC,0A0F9A6AEA58D2B2,00009C05C90F736D,8C4EA022B0F9CCC2,B0B50EC48B6D7556,643570E61BF329E6,EA11FD09A306292D,CCFA5AEDADA4FE15,DF3E7DD903204627,0000DE6CD87F6800,2135CD2441E197BC,8CA11D5E075D504E,88EAB81879C2E171,7916C8531F28DE2D,5AB0302FA55D3819,32FC12353800D0FF,00020C575AD12C32,FDE98FC6EBC1BBE4,071D1E0E063A5D82,888B9A08BFC9C148,E4042AA337B25589,4F1823F233E5088D,0D268FB48827F306,000100D6EC272BD4,C91932B0CB6D53A6,849ACFFB6F5A2661,999778C3A1785AF8,A33CCC9932E210D5,F275F7920084BFCB,780441842E414BCF,00000865E1CE5C82,A190A311CAD8742F,E8487B094BAAA80B,C0C484370A187053,84A010BD995305FB,6D97B8E8CBB7007A,E98A85DEF7CFF6B1,0000517CB9872647,19C9DDEA4B1BBFFF,CEB60507AF1E8994,0BD0136B40A73CAA,14841F4F5781E229,19EDB800FF55EA9B,D32AE948195130D4,00002DD16E745004,2A1124E53B0FBDB3,92C178FFF749678B,463E9FD2EDCCFC8D,8D9B019E68697141,99D574F962333D7D,0AB8553C760B2F2F,00013E731586E369,4BA489E3E9B6CDCD,9270BA881BDA3937,440D235746A318FA,9621C0193C2A51F5,E7767357C2E671B5,44B9353F3A5AA791,0000C5453F89E602,CD4E9471349674AD,1AEB39F78D7E5B41,FEF2A55E65C6FAC0,C1CD75EC65AC60B2,0D28F1217288737E,D96E226E8580E1AD,00000D1A68A58865,F5889CB5199EB449,1AA2C742C9A6C98D,576B51567D03CF98,1688661A043CE20C,5EEE989B1E675496,B148C437C75AF88A,00017C75DDA27CFD,27D37C6F3B5B5E50,E68D5D88F4D2E955,6C7F8D6914A8A237,F2534A55BEF4112E,215AEC752AF16BAE,F6C5AB49004250C9,00021D46716180FE,1C513C982EBF56F3,B3BD64E1A09EE13E,A9F5BF5FBA3F2A63,F7BE5378B2FDABC9,9AC1B7ED41A7D271,AD24D33179A1ED01,0000CA358D7DFFB3,9C1718E8A25FD4A9,B4F683FB21E15BF1,D17992E38C877F57,F112B9A98CA1CEEA,9AACE12318527A47,AA2E7EA8C581E558,00010305BCCC8E19,C179F1451F59716E,E9DAB2760C219FBC,3E209DBF639B7393,EC6569B61221EE01,1E9BF9E17E933491,CF80F272059DE0B2,00002CC7FA5829FC,900A370BBE3F25B1,A9B0FA960F868188,50A32D794C7F5B17,D0B74B1D138A6511,57BF0B0D2F188F44,9276C74EAC7222D5,00002D0606B2616E,8018D34C54274599,8E34D2248E705FB1,099101B735170702,2A47365F4FD043FD,C40B7B844493BDF3,C64DF9B8D90BB87E,0001E44BB3BCA7F7,762E053FA0B06C82,2CAC26D78DEEE6A4,5F4955A4D40D2CCE,DAD1649EF6895F44,214997333A180C11,3CEC66B5B6358278,0000238698B4A386,778D75AFC6D4216F,9CDA738BC275B42A,CEE048A2B41F399A,67A42D87A782ADE6,3D06F8DAC90D17DB,0734DA4F615D8F09,0001AEF0F242875E,1117250C5997BC77,6E6485785A265E82,22FDC5E8D9EBFCF5,2A46E27184BB05CD,91258DBA9487A233,AD6E9F4A8AAB00E1,000072A9872D1371,120024BE028D0572,F5D909A020B1BFD5,58805012397F10FE,4B8CD2681DBEEC61,A3DFABD2D3009B1E,3413E29E3F40D651,0001A3C40EA74EF8,B62D7DBA9E5640BE,FDACD032D2C3C859,F8801CF090256F4D,50803B65B266CF3A,E9E5D17C48BDAF19,E90F34184912A4DA,00001867649585DB,64710ACE2C333C54,994B5B09951C8C93,18B8F140AAD42534,163EF9FF56A0484F,33EB7DB446ECFE04,695E3B68662E1BB5,0002117C6558834A,2C3F926AD0DE44DF,8258C018CE873740,439D47E2DFFA354C,C3A17CAE4782476F,9B5A7EFC6D99B149,E3B64E080CB4C047,00005704BD77B10B,7D45240AAE8E6D92,0BA9E747552C2D94,E8D8EA0B556C7609,50A5A903B66ADDBB,94A604A82D9E28EE,7258A97CEF4B21B7,000144C03E455BAF,DFDB85E8B8F5C307,7D6252007CC3E614,A16E05F2EAF93E31,EC85C426C63B56A2,2E0CE09FA5CB2206,0D9E57D22EE1178B,0001E4749A579365,43D6D9E2AD7AF37F,EBD4883D12312F4C,89F1D090F4FB550E,95D0915AAA21B3E7,51004DBB5592D8E4,45DB3915E2D71F11,0000A5EBAC53A077,CC4AC2AC98D4AEC6,31E7E5E6DA974A01,F85BBBE273B7B9CC,5DF4D6496672E11D,17C26414DF64DA0E,8345DC17BE58D612,000095F0F548B2E3,C8EDD1B9BA3E896F,B7FF95549F5FFB27,B31C808D0809D0AD,350D20345ADDFFA9,BE2311A5F6F942A7,B60FE66519459F99,0000AD933DE53FC0,2D92B30880D4B500,DB62C63BA0AF3166,B696813D51C9B3AD,B3C1E1F3955D1355,03DE2BCDE9AC12A5,8140A62D5B59435B,00021701DA1A52DB,E645773332890D94,376B9FF07AFAE827,543485DF46844780,7A5079A12F8C0C4A,25FA15D969AEFEDF,3DDF083AACA14BDB,0001F296B0EF0E93,A9CD45F1AA4E9885,823923A355FD85EC,B3F24C830F0D1DF7,736AF9621EF301F3,888241C4B9C0EF5C,26D3264B24011BCE,0001E27994F597BC,4098A691E07A85A2,16AA8EB4808401FE,6E91554308617912,EE8FBEF97988AEAB,015063060B8F5474,875A3017DABB3176,0001EE02701DC0A7,DF2AB9A36AF680DE,AD882F5660A41829,F932D2800B955A4B,9A1B74BAC3A981EB,B70919602BE6C993,083493094C3EB982,0001EE376D7FC67A,59D11ACCC7C6DB46,4959C3D7F4392EF9,E5D2FEA28094A184,333A19BF9B36E1DF,B25FC2E4C463C160,AABBB815DEF7AF8E,0002297A65818AA7,A2F19CF2D5731597,B77FBC97D78CD338,D4882A71445A9A3D,E013A3DB9D19EC3D,56AD87A3BDFEC224,A19099E9B264AC9B,0000194EEFF00004,DE4790B659620F8E,1D8EBE8A6A938354,14F75CB966B06C10,AF9B6D9D5D7F52B6,2846D61928B1A9F9,70E1B1FE4C2676A0,000072E062EC5FF3,B5A555C1E4891A50,362E7C9B5A9A1082,A036D4D506B583D9,09274385D399840C,AD596ABA3A822989,2F21D9FF9A6702CA,0000CCB2384D5488,66C47FD6DEC87FD1,30C692E43CE579EE,18BD768B676C99BA,073DB19ED4F6795D,51B98507AE269F84,B63CD9CECDEFC114,0001120D1FB0FFAC,FEC01B601CAA958F,4153848C216C999F,8CAAB31B6E44343F,C867D86BE0F7723D,BB714A0FC4F2756D,3DB636779F7A437F,00003CFA562D33DD,06D20747B9D582CE,F138B8A405548942,48D8BEF52720B0FE,C1C61CF8DED42E61,B3E0F852BABCE44F,67CBA90FB6F48885,000078EDC65F5F20,011B3DD1654A382E,D95FF89EF801322E,546ED4C2A91702AC,5E31A87A007B2C8F,BE9C9F3F90B1668D,F759911F049B3BC6,000213EE758D9754,9B0D6B11043FC250,3A3C4A53355F5EA3,560A50544B5AFB6A,D285F98904A8B970,E4B03D7F79940006,4B655D933F707862,00015A7EB415D7DB,4F80B1679BBC65D9,37582866FB47E1F4,DE15F9F47DD30251,4D5449B7F5A6E541,6D08C69A8DE47626,C35E887C3557A3B9,000047AE663E676C,561D15746210360C,028B81AE9C1118A5,A510FC007928F845,38196EEDB23078E6,63AA0C300157EADF,B08F005B6C1AC7AA,0001EA077B7084C7,6407674C502FFC1A,FEE536C8F03C9617,1D0BFFF2001DC98E,CB44B09A21DB9BC0,6D5BDEA5CFE68E43,4F24BD46705EE98D,0001B7D014C7B03A,593FB46A5006ACB0,D37155E26BC0B24F,EF2A89F3A0E09B8C,1047C8301528DAE9,4D0FAC98F140350F,15A9947E311F9FD1,00011B825DAB9812,46D6AD82F483BB18,9389687FE5CDCC22,B39CEA78D808825A,D3574003C1A852AF,456E3C69A3A19431,11EA7ADB222CB2E1,0001F2CBF09A2AFC,1E744BE93DB0F851,58922852C0629E9B,E015AF6775DFEB3F,2FD9BA64E5CE16BA,B106D19621821104,7F34E98F73FBCC0F,00016192EED40960,FA0AEB44A9DBDDBA,8A695729DC17A6CE,DA97D76309A39114,949D9A00C5EC7A73,74FE0EC80B1831FE,60DA8FE69F129CA5,0001BE545E35D040,75340372513F335B,C23A17C12BB136E7,75798B9F82B5D37D,E80CD889C4260E36,DD152DEB37FD8B57,E6E575E56B8DF007,00006B9821A7232F,712C27504E6B7D7E,388390E60E5216E2,EE24EFEF5A714BAA,256DD6C3F87BBCDC,28709A6211CEEB5D,0932368E528C3005,00004B77AC9F4DAC,675843A3D9387BD6,90A693BFF71B2B4F,16DAC8FBC94AD2AD,E139F7877A83EABB,D9AF4677FE701576,46F4467693D17233,00013C9101105026,2E19ECB98F74A1B8,4E30DF3E9C80727A,4B0EF53F15ED86C3,3806B4E3E6F45597,712297955BA09E02,235D33ED876E0E8B,0001C225F4DB1764,CC996477AD11550A,DDB0DBEFF9FF2EB0,2CB5F8C0AE5A8546,8D4578231A11AE90,F5EFCF7DBF89C4B4,82C4B104DDA846AA,000014859B52D8BC,99FDDECBBEEEFF16,E153AF0FD610F5A4,D8140219C2B98108,FC9B7C12A71B8AF0,AB1E0B8B9B632F40,8F0396FE3F803FDB,0001146167EDF4DF,3B3C95E16367E52C,F489688939E1ABD3,B02D59AAB6FF9C08,CA2D51C56D005678,CF4D13F9E61CD78F,297053DC69C7EFA3,0000D72B049C86B8,53D8554E64EB007A,8E59871EA140063C,34BE31602CBDDAF0,0F2E0901E347873C,B6F5D30AD1A8F84B,37412005D46E75DB,0001B979EDC14206,28F0450F1A0A8FF0,8EE94BAB6DC9002D,CCF06E71C2C3C4D8,D90ADA806DDEFCBE,1B9DAC779F45E08A,647AC4C339256D97,0001E89958F8D7D2,088245EEC552430C,E47483A4AC27DA60,33EAC5AA442A726A,4DB92DA4DDDDD0FB,E3AC168D240C66D2,38865601A5231B39,000040939D5E2713,09489F974E9E9012,20370C1A96BD06EC,2A7A96D967E10A6A,544ED4DA1483A180,5AB046BE04D2A458,526EAB765BC6170C,0000B9B3360051DF,BB3FA13DCC714BC1,380611E9370FC308,18CF2EA856DA05DC,466B5F68464AC481,DE2CD18DA4A8A8E8,141D805BC84A6A49,000210E8A307F94D,481724E6DA35F60B,91DF05BB15A95E7B,194A34F6319D29AB,B001785058EC74B7,B520E30C356EC9F9,26EF6C824EDADCD5,0001AB220EA66165,47467FFF7522A4DA,C1FEA82150FD8740,1F0DF1FF14B57BFB,9F358F0224F34E9C,3E03404AFE4330C8,794677EF6DF0EC0F,000149255F457855,9D231975DE427EF0,AA1D124DAB81F777,9E511F116B23A118,920F4078502B6716,D7DE36D360D817DD,78938D2E4A8DEDCD,000192CF8C72E232,4406A19F7EEDD074,38BA3B3E64A5EB2B,86AFE67DDFE2ED24,60185AD73474A032,2C85E30D016D2870,E8B7B5026FB61B46,0001ABDA93970EBA,8A56EEF0C471621B,7B503769F662FFAA,030AEA8296A5F3E7,881330F4DBA67438,32C452CB7A45C9E3,D214D7139C229149,0000F4C287D42B2C,E634D57463EAEF1B,1371504488C49273,3748BE3800A70930,0A4A66325C85C238,C3A3A5E143948312,69B4EA0A2B3B8B2C,0001473BB3BB12C0,E7224A6452129E90,9F539E67EAC93103,70D95B59767716FD,166E549077C6CE04,FA72672D19400F65,E0D737164135DD54,000061CBDA520370,0338094C04C7D49A,600EBD66C1505331,DEA7581A40FF9EDE,CE2AD3C6A65F936B,C6AC8BD830C8D5F0,4B4453769A024243,000097D655D13653,80FD895AC3192B19,177A0ABE5A28F5AC,AF93D6D359535489,53DFCD78F8977A34,EE59DB211ECE7622,1040DECFB38D173A,00017A2814EA50A9,B426151C02BAD612,74CA3AF4B122D7F8,CB59FC6BB6589FFE,6F1E5CA344B4D37A,877A8672825F8DC4,CB653B91F392762B,0000D2D4CFBB7CE8,0DB3D34D5B1FC2BE,4BF3D4735562B53B,1D39F6219F551093,F7E78D24DF4312FB,75D30EC348BBBFCB,059170E5B08611EE,0001CCC6631CD6BB,D2E37CD76C58A9A7,46F71E92052B23A5,2348486B8AF6D29D,2EA794492E17058B,EC2CD2679D4864A5,0FCA9B1E4848AF9D,00005CF766B33F4F,07213A0A1E91B4AD,8776D9FE5F70C2D7,51A804EBE71FD034,369D4083A0AA579E,B7D2C4070CA39DA6,316C6E327C0C0834,0001EBC9B6F284BF,E1DFAAFFD9653183,84C6AE18E70C39AC,082FC652124BD727,D5EED5F32B529528,422F575B2C8DBC1F,5E10A004DF14A08B,0000E4C6EE890C33,CF7E218686CC14B8,01E9610BD6CCD1AD,284AD8BAF35C229D,F6D47D2D0525DBB6,C17C3D67F756202F,8D9289C89ED1D12D,000216F4B0CAB053,78161DBC5EF9CEF7,22D345061FF830A8,35EFD4464396E886,AF110ED976F785DB,D8975F505AFC7EED,D2CB55387B912F90,0000817B3641E29E,ECB9354338428F4D,833FACF77E8E55FF,F592D202CDCC7269,F216626397681900,8E4DE85DA11B47FC,68BA26B5F88CE7FE,00005BA33BD11949,21968C7D5288243F,1EB38E6E8D23F4A5,3F3EA2AF6F7D1A07,ED6899A0ED167DD4,70EDD03CAE5EF588,916FA19C2AB6976D,0001E0FA01675AE2,3A213F353CE006CC,F2AFFCD1292E34D9,57CDA82C0FBA5506,23647C6075128F28,379FF9C0BC8042B4,5F9EE5CDE44FB343,0000822B3AED0244,4CA5FD55B3694168,C3A973E190D2FBBD,8B3D86A87176A3B9,42CE6D32DBC78158,2B7B4A18B4B64EDB,E9D11DE8CBAB0BB7,000141726CC3DC6F,4F10FEC0B30144EF,E799361C0F913428,E6CD011E4DB88D22,722B8CB0E2C1444D,6401685D92E8173E,26B6F205B994F2D5,000191246242AE4C,1F8BD1674721B47A,19AF0CA51774C228,3245F4A3FD159D97,E6B17B0FCB3E9EB7,A0D36820B706E01C,828E6666A7BD87C3,000047F0D3CA9F75,D161B710D7B52E97,622BAC75ADBF5F63,9A709B2D97ECFC38,8E7EE581373B117A,F15A153AE5CD77D5,88DB04775C7E9AB8,00009BCA7C44601C,55AE4927482745B5,1C891988D600B9B3,B004673EDB858772,0A03EF7B3389DE68,29F8B288B7531423,2D50212ADE8AA3BC,0001B11E2E5FED37,A21A09D8A2E7F4C5,DABDDAF12CF23C9A,7A12034766BAD6A5,B2C57B5C88EB0C83,AE175BE5FD690185,DC19438BE004AB7C,00013456FECB160F,07BF470172D16F41,21A0CA8A23510B48,3B1014A7B0D9703E,DC0DACA54CE159AE,6C7008BAF411C62E,F7CC0654442AA13F,0001829B117A00D0,AE7106F42202FEB6,C46C450176163AD6,1D7B8BB249FF7101,644673A9211C7191,C4D3BA3DD4CAD6F6,7601619FE8503ED8,0001EE704315DCD6,4E051C6F57AB634C,C6EEFFEC2C5C6219,809E79A39B957305,1CEBA0DA60A0815D,C82C3AAAA74DA406,A745F227E012A740,00018DB0858B4D51,34E318751EA7D311,8DDCD943DDCBA095,12C05FDB3675726D,1CFA0FA1BDBA7A89,6C7673A492EAA3E5,1AEFA11A3077E7A6,000163AA019871F6,0C81B2029E47B26A,C6A1F8DA445F686B,47986C5A1C4A82FF,E4BE1018F68C2054,7540C53E6E172CEF,555360E2934D2B2E,00005764BCDA5082,CCE0042B279EF44C,B90B635363D64FA8,D37329E92E8EF0AD,AA18AEB250D47224,4EDAA0C5B067ADC6,6A416BB9451A1F2C,0000616E76A10E02,D3D1C8EFD1D9B825,AC76E5B1F4B57D8F,FD00C097B1D9375B,E69D0AE1BD3E51D7,6A0D1FA2C689C3B4,5F1BDFC53E7E318C,00022E3635B3EA59,9EA195D7A7C81714,D3330A9298C4EE0A,286FF1FB7B3B2B18,BD48AF69EAEB03F7,77A1AD478857E25B,A8C3B748C74E5461,00020226342E2066,3092A6DA2CE8F46F,A00E56D1B9FD3210,7AD0BD58B1D493EB,DD9D4A8A0E98B1D4,ECBC61FF3ADD4FB3,858DE730DAEC7B90,00016EED08105F45,FFAAB901A6FDF8ED,FA2BC8AED9516AA7,B9370204DB03D13A,99121EB8B9190747,0D309DCC7D889EC3,E93951B63C05388E,000103FB48FB9ABD,6AE28208F9775F7D,DAEEF885E009443B,DF57D977600EEC8C,83937CBCE8B15234,3BFB08D6DE1532BC,B73A0A0F656DDF16,0000CCC7B1267F73,02608D1820510AFD,49473D13C9544C5A,4918BF0BA4DDF5E8,F231570CDA63B893,48D2D395BD4F1846,6CD124FDC90F0C73,00005B4C55112B56,361E98CBA42142C5,F66ED2564DC8D86D,EB9F281244E9BC2E,666673C1EDEA0C32,71E74117903C0B1B,7655BE34C2F4F9FB,0000C5647FE9403B,F9CEBBB90E698CAA,B13CC83DBD2F4CDD,41B8B4733EA6CF01,62BE57A5543D93CF,0ABEFCEDC2B9F0D3,E91B8964828776A0,00013302F3FB0582,BF29E39E8074ADB2,9F5386CBF422906D,9119B3CF41404C4B,D80B0DE690A91CAB,F00E68373E7EBFD7,7B0BC4C0DFFB6080,000179708661F1B8,EFBF0677E3784E96,0C4AD7434F995A1C,5B340156ADC20154,8AC2F2EDFB8B9536,1DBC439FB10D26FC,5F0D840761B061AC,0000F478F1F9A896,45068CC2206E35FD,1FD82040DC975A41,40354971C6CE9F2F,A760C4DC3BB9B544,E2B134CBAB8A7AD9,60EE1C820C2F8BAE,000229BF00C8D96D,8C118CDE015B693B,AED823A93CDCD746,28D668A2DC7DE144,6189A840BDF16806,D310BD2E8045B0D5,5CF5066552D295EF,0001443545D752B8,46E3CE59BD0FCC91,797BCEE3EAC01D91,84BE318CD5B73D90,FD5B0CCF0BFBCC09,59C2A46348D4F465,C281AC21D73C4122,000217A9806CB883,438036B70A14F458,B5DC001E36EEA849,FC018AB18DBC02AA,5778BC5A2EB9E9CE,EED0E9EFD4A80327,33707794A7D60F67,0000A9E89E21E93A,F8AFD562FD97E0C8,2389347B48446517,E9F8C5C6819D1293,63E46474908B94ED,CE07F95B973D6877,340FF7CA0018A5D1,00000F9400FF5B03,7225FE4950CACF33,C49BB0A08C467A00,6C6F99E1B96C12B9,87F419E5BDF50020,48B832D2F12634DE,58A117807F25995F,00009AF1B2F3E92B,EF4D574A62AF12AF,BD833FE8AE3C30E1,D83A5A59B4A5EDD8,2E623692A1C9B198,C253213C9D6B89B3,20F58299268CF9B3,000151900EC61E69,73A6F5AAC158E006,5D01D6050EF525A3,79381C7F1ED47ADA,AB9C1D3405843892,E846BF239BBD3D3D,09BDF64F04B80A65,00019DBDD8378E4A,39B851D92ACB81F2,FE476C5D44A8A5E2,5A7411B65C3DE4A2,CC838711A94DC1BA,011C4FB5E1B7D615,E17953B430B63EE6,0002173DEB1C9C83,AAD9A4194E914227,C35F2D401CFB86AD,041E8051E2B94427,A1608C909CADA827,6194793F443F8601,ED4453B9AD0F33C6,0000F04C2EE575F4,9F19D9B9974F952B,B754FA65B9AAA880,C13CB955F71EF91A,6C4249A15E540869,0250F10A9F15FE4B,EC663A4AF62B0260,0000358C1D492268,0F6E449AB8B0A1EC,6906514BAD27351F,6705FA26B0AA6391,F1B7814A6BC75F4D,00733030BC67A6F0,E2A2DD7F353E6BFE,0001512ACE963DDE,AB03CC9FA99FC908,3F927D0D92B1E871,1B60A69AF058012E,48123ECF1E2A6BD0,A5521E6C72ACE9A3,7C9CA25AE26A02E7,000075A34F550BCD,3FE561A36F15BF71,49CB13D323695231,9F080FC53187CC5A,45999232B1169951,4CD4EC393094C455,D698A97D5CDC738D,00016BE14D820F52,05E6DC62A392D16C,17DCA5A91D139C1B,E25B3838A27F1999,4258A4C8AEF5707B,4390B42DD7A04D35,1FBE1C3881A47958,00001816FA6DECEE,39CA515215CDD08D,15483082981FB91D,828941593A46035B,658B87283CEB74EE,49585DE098283845,E1972F109EEB4DE1,0001AD73D37CC07C,CA172D06025251C6,2C6C5EC81A015E43,9555FCF457534E10,40DC87931476D42A,B616B89D710D4A35,7D86168C394C3602,000002ED8AE4259F,D60DF7D2DF1F94E8,27655CAD33440CFA,F31835486D7351F6,ADB7B31A0694CD58,84A5E045993CB193,3E88CFA559D0BEA0,000052786A620E91,8321507D26671D60,B8E9CC889621CA83,B95331F50165435B,C2E6C1F9C0178A02,1F7F1F68C21540D7,33E03E8956DD5C33,0001EEA37870AB12,C03072B7F1DC9571,4648E2C0628DE696,3FE54724742E42D4,773679BDE9D4DDC8,CEDEEDF8F71B7DD2,78C1A61411DDF5B5,000155D63CAB6094,A3A4441D144115D2,CBA4C841F92790DA,01913216BA15EE11,C32A6D81C87085C0,9D700F80468ABC45,90D2BA368219CBC3,0001CADBCB3BAD14,2A8A0946EFACBC22,F0729369A5502C19,9366BE7CECD66D9E,5C76E32E6C37C2F9,8B76F42AB2B8F67D,CF99670E1666CE40,000041A79D229E00,7F635FF58E9608FA,B27BCA8448AEC3AE,A58C80E084B0385A,F3F33CBB4ED05018,F83AA44B13490059,A603E860B8B2F0DB,0000D194908FB4E0,498C986BC3DA1A1F,B9855352817ED2AC,01B6538FE457FC1F,1CFCD70DA14B3A4D,ED69F162C44CD3EF,0029F3CD0D8AE5ED,000060E479C07E35,249978203555D1E6,596B6A0EA93CBB38,89EE91416B0C712C,DFF78A8B182987E4,F84516F7FDA42EE2,5A07FA3F47C8CEAD,00001FBB1F570800,D4F43FD184841CAB,D11AD33E8838DFCB,37E3D68ACA898623,0E68EC1954F0EB2D,90AE19A542287F25,715F8A9A72EF2EEA,0001761E1D46D488,174A281BE1D4052C,60FF55C66576248E,2A33DF9C29C58753,04199B20BE579884,E85A0BC73916DB0D,4750F93EF57347D1,00022E5D34B81E79,D550C04DA9AA4D6C,4A3110DFED974263,9B0F0F5390C70D0D,0F87A5BD3A3BAC4A,52C8C3BC6862D995,1806E1D935578F2C,00011A3169AFB5A2,0223FB1FEA20C173,0F80329428AD9FA9,B6900372AB8830F8,9D005E155AF896D2,0310C44CB952EF11,1CF11E79E8B19032,0001BC6C1CCFFCE2,128D9649D3C3445A,390EA9029BFB7D88,D3AC7C64D8A27F1D,92AA07AA280DD926,2D09FB1BE53E4BF4,9BFC8A96B4C52A65,000069FE6645BBF0,644F04FDE3D25752,CD23D5E01D888E28,2BC3DCD2CE6363D0,2172BAC4DFC96B67,0DB431C01F7315B9,D19127D35203CD7F,000176C64AE89F94,08D6D31B0B026194,3741A3B46B14FE5A,7FD3BFA7A1FDF20E,5B11644E6A72C0A1,99B71CEFE491965C,0680B1B6BA52D3B8,000015E5727F8AD6,B33C4E7B32ADAC19,DE714D430A9A535C,7EA0E010C8301DD7,22566D24A3BE5FB6,6633AFAB3CFC2FE1,C65BAD8ABE059721,00004A01051C2CCE,1CCDACFA31C3AFE3,F74139F183075909,3DBB57B46D83E998,44A267DDD3E2CB9B,F18DFB0FBA031B8F,8106924B75F0C57E,0000FDD68FAA2F1E,17B24205B645DF8D,2273E23C12BEC813,1DABC93328149D2B,26E8FD8429644F84,2C97939630B34F34,F5F9881F5F2B9E82,000090AD7447BFF4,7CFF0BE3C0D32671,8D13E931B65A0600,0FF9BAC3E12775A8,F55E0ABFFA504828,9B08D89000866E71,6ABCB43B03C894C1,0001C2B98E82F8E7,9EF14F626A5B0968,4F28464BF533F90F,5CBEA1059E12CCFE,0D6EB20C9C9D65E7,B09F95D1BD264769,ECB5E52E99ABDE93,00006818691FB807,931C93DEE78F8D9A,F8AFBD593A247EAD,83562757AD1526A7,C950BA752C59AA52,A802D7177D460D65,B48BE82A62210E7B,00006D85AB3F632B,CC4F8432E1D0B6E5,AA1D2831B5392C03,5F3A0D9ECBD6F6C5,357534302497F4FC,F34A4EF395610315,14438D14763D767A,0001F6CB342528B9,66C90AA3C25B7ABF,0D84FF95A090C017,21AA0D8845A1602D,402492062BDF0EAC,040F323D06767104,D757FA0BB63F3A3B,0001B6B136C18B29,DD743941FAFA3EE9,AD030604165FE546,F0041371E3CFFB08,D5A93E488A294A32,99506A0DD725F28B,7BD7A2B557D9D2DC,000139BDC4521C45,1E635C5B1E53F743,0915E0A7A7722FB3,55D02B0481E40FA5,DF926A6F61197507,CBB0FA81B3A0DF72,77A89DA7164D5710,00014E60B865D9CD,1C76A58A06337643,B95B45E4DEBA35A5,5F77622F2295AADD,95B05E9672DAEB4F,7EED400F79A2825A,91E01C949101BD86,00003571A91DE7F6,0DCB4365BA13D25C,6C8FA18CDC1A74E7,8E1C53C91A3ACA5B,F62E2A852A0CFD3B,40A2394CD9D6F1FE,4FD909C2AEB3397F,0001DC94587391C6,6CA06CA83AB428EF,2696505EC733587C,3363792D7FECD041,0CDCA60A3DB80570,4B8BA4BD686F5143,399673E7C9F6F51B,0000148BB37CA8B0,BEEDDB030C6CCD58,9DD064A95F371CDF,5D8409F478373AE3,F661745CE89E03B2,0FD795A3CEDBC707,AC11C8E403873D41,000043989F7D2FE8,C6656FCA558362E2,864B2D9C28D84D06,A4EF9A3D6054DEAC,52D72E79A37327C3,2FC54208CE16E823,5F3B947224B6A799,00002CB57F4DB904,2262ED8E00862BFF,EC1EFDE0C1453A54,E12CAB7E769D7074,914909205713E5D9,E3AB67D9CD40B0A3,1477A7E43F1B2C95,00003DDC0C23CD1C,8CB5227C54BDF9EE,E3CA0B96885F38D3,0D92D791855ED5FF,C84A352E7721363D,08763AB27D78CD5D,42B4DF62E77790C7,000218738C641831,D61686C40CFAD5BB,BBA7D4EA3BCD041A,333DAF2D9142151D,A63CE59C86E720A1,0C5625043A94BBC3,909113756D923AB7,0001BF5EE874E368,3196BF540EEB3F45,A5454A74194C5EA7,C4AFF5D69AC1FB99,730A160BB9DBE10F,5C39EDF2BDDE4881,AB4D7E3E602696EB,00002FCE14440B7F,28A63C1AAB3794D1,5CBE328F8DA07876,B52FF0C5863E4A01,02D95EEAD51564E5,A0BAFE9C55258613,18A773A831EF4B50,0000AB963F6A0C6C,8F21E79D5D8416CB,99F491224A19137B,DE4AD415CD11B19F,64C667BFDFB16C39,65C1640A92445F4A,C032D8D282A7DE7A,00012D50E30E8BAB,7EB94B7F78E0A801,C88B5F995CF32606,946328E588D32BC5,46DF53A5EEAD0A35,28646ED6978C0714,4A67787E9778DC5E,000133D37C3F9E0C,6F88C3C56F3EC76F,7774E4E2327EE19F,D8FCF230DC9F0DF3,86573ACDC9D68963,D10B2811B25566DE,FA2FA38800EB3C39,000118920DA279A7,CCEAD13988C1363B,C36B962708EFCEB7,F0DDCB2DFE9CCEDF,529BE48800837D7B,D8179AE6BF4E4383,94A41C430F563983,0001AE1B71696E7E,DE7A833F307BAF9A,6E623AED257515E9,3FD4A4CDF0261AA4,29D5A2E064CC71FF,13BE636798DEDDFF,F4E605D1B9A00793,00009D9C5E337736,A91DD642740C9985,696915965FCBAB3E,C9EEEC5D006175DF,F626C539B2A4F01B,6F58D19FEC150AEE,13403B4A8912C0AF,0000399132F0803F,C79F6ACC7A74F5C8,E577E43EEDEA330E,A53F39F793C4A661,E8774CF477302CFA,28B2813DC94CF0AE,10D8DC4E1FDBFD08,00004FA4B5F32584,4A8305467786376D,BC3E27A9838D5F37,EC296C7EAC6D2DF4,9BEA228FE88BD31B,2501A7E769F542F5,F3616C6E826D2C6D,000204A8827E82F3,120DC938DF610204,3071EDF6AE249D46,5F06FB699F6F5F25,4EE214529D93392E,B8799CEFF87A2899,BC3A94371638F539,00010F8538839295,5F4773544B449F0E,0FDFBDAF4A5D302A,D138794D82630266,4B4DF8FCA7E068C0,6445C6F9E7C51EE9,92C8D8D3277E78AA,00016D7930C830CB,0B38BF45B0F55A02,9688D72A618DF907,2665BC378E786676,ADCDC0996E6E13D0,D5D295A4101DA92D,7472E096FB9BB1E1,0000142FAEB833D9,45DA51FD934E69B3,A99DF860DE0A525F,AA6516A08E07E5C8,0F0F4CD156E286A9,8BD5A632E04962FD,AE52B5FFF3A86A39,0000A3EB2F52CF04,9D60AA206FEC0B3A,22CD6162F6FD932E,68EB408366601487,6E385166B90BCA23,F01D87A6B0FBCD11,7B8A78E86B73AD92,0001AC4942023479,7F3BF113FD2ADB89,E26CF289CA3D093A,740D52B609620416,C62FD487B5758F24,CDFE60CA2E09C87D,35943BE690E638D8,00006ED6C8E13613,4DF4CD78F91ECF80,2D23826BE51A8E5C,886EE4DED56A2DC9,F001F08D3E31935B,D20F59573C159709,98BDE91D2BD788DB,0000AFCA5C022FC6,61A3B5F9FD0EDAF5,A4BB68C8390DF532,B72312FDA16D6252,6A3FD35774FCF309,AE991209D6F1C9F4,A53640193B26AC7B,0000FC108BD443C9,AF697B7B27D3B998,2E410A79C176B23D,B240B26AAA533803,4B4CB3A343101905,B5689D5B1CA0E8D6,166E767076AD3560,000149A9B30673F1,748D2C960AA5D08F,C97FE0A4AC8A79F5,EB7A4517A4F098DB,41FFC38A668764DC,F87E459329DF0080,50C71FCBF220F4CF,0000B4752FA01D11,46BE20AD0DC4B28B,D997D73FD6358FE1,1C102F3209CE678A,A113D8BE95242C45,2E1ECDB0E5FAF381,938242571BD4C1D9,00016A86E3D59B9A,F74E07F1CDB7906C,A7569546788E2E98,7645C92058851372,B1AD19D3A53103FA,E3095DC4671AB21E,7AF9A2DFD5C6EBED,000034F99006DD08,EF8B7254F23B028F,B0EC2C4E30DC5D2B,69C14D75F99B445B,EEDDA90C85C09951,FAC3939829C69E74,F1176FC7193539E4,000146DCA5E4974E,80AC9419D6F57B92,CB0F687DC5077A45,26312579460F4FE0,4168008404F44A14,B2C77D27C24B5294,C4E509166F431A11,0000BEB88E1E74E4,A59E5D8854419C39,3F918A3FDFCA6985,A4570FBE424FA026,CB480422325497AC,7DF40E23E53E7CE0,D494FE952FEEF042,0001A5E3674E6C1B,3B5FD3AB940B7716,9BA4178FE4464876,ACC4B6E1C9EF69B7,CD2DF51E45BFD360,AB8ADA4A73A12FAD,518F94702F01C0C2,000210E2D7EEEA46,9E9E6C5C7D4FCFC9,948F15624D3DBD5A,44D5B4197754CEF0,02271F655B633815,930A484A9355C77B,B8C56D3DA05EA940,0000A75C625516B0,EF80AE7FE95E909F,B11C82F0F2C0A88C,2DC07D9EFB5A4590,5E58FFF8597B48C6,9469FE21D193F7D8,A6E3BF5D09F22F0D,00002F1FDF41052E,598D25EA469D8BA3,897470DCD3DC8D02,48D216B1370FCCA2,55501110533A9D83,329D1BA71051CC4F,987552745FCA0931,0000DE730920837D,F47DD4E45EBC968A,889DE3DB4B97AFAC,555917B863DB95D6,D2AA894EC8015890,15C3A485727D2E05,73E89724C68C6996,0000BD263E2635F7,7492AA9C58B101E9,CAF3B5E2844C771F,4FE8EB195CE2BC3B,E487418F88F5D332,BD0684EC022C4141,56991DAC483B6263,00005DB69DF37A11,3FCAB036B46C4D73,0C14C1C08442A069,23E1EE040431DD50,6C407F6DE8B8D1F8,3825177BCB362EF8,76C0ACC0A70CB8F2,00005D2ED43FC52A,166DC22DD1D6D792,B1D62BC34A508F3B,659CA5EF42E2F712,599213FFA5EEA4A7,ACDFDB064094EF00,9A24552F5826A792,000005FF9209B683,CD57D403DA40AEBF,FDDF15187770985A,C5619577FC362292,94B7043CC1BB5ABA,A1DF983939F15430,931165EC081D98EB,00020FA91E9DFAD1,8F91D0E8F5FE7E22,68FB08B18D868EC1,5C47D9633D2F3D6F,2E62E4834745EF16,7DAA4B9B632F44C2,2CBC7ECDA9FBE955,0001344A1C741376,A6F86B2200B048C9,42CA1A2DAD079D6D,9C6579ED5908FCAD,E8AEE86F80049A3B,C7BF190F7252AFF4,135E78AE16C927B5,00009AAD513922CD,17DFB7098EF515AE,DE0B43A164757DBB,C1EA4DAE4ABD03DB,A79487F2766CAA85,63CE740785E2D481,9F769E554C2E115C,00021953FC8A7401,3846FC0E7D7486D7,9193260B12858E70,444A0BDFBDE3DC70,F4D1553E81B1F231,8BB74844DF3B3074,4A7F7E3BBB211D22,00005AA2E14AC71B,1511BA378B579302,8447FB713C86E54D,20B85C232020B611,7B2DFAB630407386,4C61673F1421B2CE,D084800C959668F4,0000C21BF1E6516B,C862EF7588B0FA4D,CCB1E3D459FF5C06,1517B25DEA81FE57,80AD239428140433,03A6B14492101D06,58C5FA5090B2C4A2,00006F03641BDEC8,C4A312A856F666FA,9F837A7ED5364AFF,D85CAD84115AE00A,D03DE0D32E069FEC,622F8D8902DB9323,1212958BC6EF964D,000028449B95D5CC,BF790CF820472332,1DAEB58E61D65A8B,185BB692CA9E08FC,B7A53DD524E7DDE7,0928B25C710E1645,341DA2751227AF71,0001178EC1BCDB92,42A08F588EE46FDA,9682F8C91E0D607D,1439A1B3E9EEE31E,A6150AD0150750DF,2268577E84C7CE57,F8236671DD1E455C,000039499446E61C,46F97F09FEE9F93F,3B56401B4D217D3D,27A4F30FC6F5FF3C,80A85FEEC9AEBA40,8E23C7366356F958,7C6A4BAD9CC591F4,00022569419D3342,A581F492F00E9402,4C00C194DC9C14D3,EBE227BD2C7800D9,B9D5E5DCF5675D2C,707E2A578B203923,6B086C327853FDAF,0000A2BDFA972228,ED8C42A1B0838972,2D9CF6E50BC0C7C7,D474D06A3E4495B0,F3AD8D0C5C2A763C,1CF3979489CB50E2,E87D1CC5D7292495,0000530A07116FF9,C9DF6DCD9221BE8B,69BD422AF592A52B,01E9523796B99787,0D5FBA5CF175EB06,31C131EA645B9BC8,A8669046A3BE1AC6,0001CD2A72600BB9,5F6562B87826E01B,CE4DC73D90145400,7C6E652CEB2D1DDC,D3FFBDD6C9288DEE,11622FB7B2E03F13,0B979C64D8879C6A,0000C345A5078E71,DBB3FBBA09B27708,C84BF178717555DB,5601D0D0B74564BD,368508415AAE840B,614F24D56F15838C,200417BEA91E18E3,0001F0FA9A67E067,3E035B28F7FB48E7,9522BF63B9392F86,EBE07369A1E7358B,9BC475E605680FEF,1794B2743DB8411E,4C0001332FDAAEEC,00021F951A6B9E22,4830DBD5780B5942,64D64E699272B0BD,123A9F3D329A875C,5CEED18564B066A1,84DB7AD0AC1EFA56,646D30380949C92E,00012DA324D0AC48,A4F8D6E4A2CA7EB2,20929CEEC7C03DB5,691DFE81991BC66F,6A96B28215295D75,4BC94257729265A8,ECE78BDB75EFFDAB,00011C535B4AA3C2,28D713E847E4A748,6008A4F4D5D9AE71,25A7EE6DC884CCD4,001E1ED5B1A33E0D,B137C31B19946C89,BB25D5E1EC633210,0001F230778FAE9F,05D1AEAEAB38AFE6,CE4EEA84AAC67654,4E1EB17C76B80A52,1E6B97742159D2C0,7406298453D92F73,EF312CD8D4F4E540,0001624EF93C52CA,DE54112EAF2B7895,017F33CA34E94287,AB698129E7AB8228,EBEFFF584581419E,32F911A89AF8F1B3,75859C409F724349,00014E4E8B4D47CA,7C7786DAF0506E88,21DD9E31A3E0C2F0,ECB1615552682DFA,33C6992C43EDA9A9,1172569AF902DE83,AF3962C1E359A20D,00010EBECE4F631F,5039D574AE1B779C,636B34232422853C,6886CA54F3839851,FA1BD16C77E90F4B,5B717CA723A00311,3C1C0E2A8F30E888,00005DB4F431FF31,A8E30484CA2A4D32,73826B5CAD5A7219,B3C5E96AA2379952,AFBE95831850F296,45E9DE24D1E6B2B8,93FD355834C5300A,0000B3E96B0735A4,D595E9E42C5A4F03,2321E17F4B8C2ED2,98AE3F429ECCB371,9540E264C81246DD,C3750E523F24E5C4,D9BEC18FC1426368,000007F045FB6B23,0796E1E80438D9E0,3C450145C448EF4D,9C9F9E877BF93227,4F03163A9B24C1E6,E6DFD88CC77DC494,FD4F48B8E0EAB2FF,000146A86360F1BD,0D2EC040C554536A,EF566B980DC7FCBA,2C1E8E715393B156,EA085AAF5EFD7B4F,A7793FCFC955D901,7AC0FA0654BCD11F,0000303E4480A75C,B74DCB0637445673,C27AFD6378FFBF7F,F4BC4F62CD438BAF,7165B11589E76FA3,B19D81188DFF58C8,D274294FB47DBBAF,00022D10EBC4271F,D9377AD30F840974,7E0B114876DE30F6,75693CE4E13AC6D7,2396A45EC85FF5FB,EB1E1D1628028D3F,F243CCB8D590F74A,00012907F577CAC2,1B381BCBE74A622E,4C2569BA0E8D8B00,4251A4AE3494E255,EFD29D556A6A3F21,E2282B641054FF34,D31C4F26E87000F5,0001D77635F0A80A,6608019285890CB8,8E9AFFC1AA2E9521,D391F62342911902,7066121F4F1333E4,8B7DE76B9C6B172B,B7303F2B0CB151A2,00020EF76D0386EB,F11C546A56549BDE,86A6B78BD12CF229,5910DEFA329B5C8A,10AB69F52FF05070,A0C23E1C1B42C169,AF787FD8CE458269,00010D92DF917011,CA9401217A52B693,E2A8238FB362DD76,A57071232F09999C,D84EDA4077581D30,2FE806D32A055281,27C06902FD88EB49,00016154912DFA2A,8EE6A5F2F0BA4B2D,339751E61CA197A6,7484272C422880EE,1980CAF3C281B13A,C878CE71BF68FBC4,B1263F111708B2F5,0000F6BCDC99DD4C,E417DF0DFECA49CE,9C71112BA5311042,41D0C84895EAD2BB,00D316F3BF9D98D6,8FED598312371EA8,E9DB40357AA237FB,0001D205AB11BDD3,9E98107947A43657,0D4EDCF3A503B8B2,15E0EBA73D6F4F2D,BD3026A1460F83AA,0FE306BE65A7BF2B,2BCB71CC82FB7F2F,0000C2C2A1788997,9FE56A28D91A1049,8870E8B48B68386B,D39C1CEA9E301146,5DD020E9EEE80B93,207581B356122315,2C9B61945AC6A820,0001EAC0FDF5BFD5,9D4D862C2E94B430,27B342B2DE54641E,BE8C955E54E93CAA,C2D4584C77647C65,62D4B39101093E41,26E1A3A194CCCEFB,00003CBA15B6CD59,3AB86E8EAA4AF042,B7CE1B15B72A153F,60C87649346249E9,A7AC0CAEF8F25E80,B3701A9F63EADBB8,7442F9A412D4977D,0001FB109BDE7C6B,3ED41F3CB491881F,B9BB779238A45A9D,DD85F8763F8DA976,D468A1458A338EC5,EFFAE02189F8A602,9F2CA02130829343,0000D8F83CF2D84C,BA5AB82AE49E6893,D4676CA641B9D170,88D501B3EAF62A53,7B4DB491F9D66D25,518B5E9EF4DEA9A0,01BCD4BD9B07AF42,00017D3FE6068EF9,DA1552C3300996E3,E9465504AD1E7D44,779A315216C370DE,B7062D7A03016A0F,CEA1276622C49703,943D38C0CA4978E2,0001CCB2E520B4F2,D8718310E005119B,D44B36049DDA825D,5445F9E5E62E5547,13D29E9C652D9462,AFD77F806F494700,5282F8DFA1AB5AAC,00018CBE56DA9A25,3E3BC46CC146CE6B,6E434578501EA507,720DCB9C506F9E0B,72ABF94414BE6308,960058331913E899,85DB8B25DBA2715A,000052531CC74ADE,E6B97AAADC75330B,6981EFB5D6FAF8EC,57E262FFB4F88FB5,BF7CB86849478DA3,E7E93E17F0B7097B,82F7AB85FB26CA9E,000008EC691EF319,489F796F09BA8817,71D9D24BDDFCCA84,FC9BD8C23DD7A897,DC5427DCB810B7A9,CE7EB3A3D2EE215C,95821A3245FC6E28,00009911F3EFF893,76F41226DC8A3023,7BE200A488E52102,487627195F3851FA,4178EA05091B286A,C5821D7BBBC8D1AE,39E8A975376BCBEE,0000AEEB22142B4C,B8E3FB4B8368EAD5,FA2CEACDC78819FD,8C7B0736A4F4235D,0DB39AF50D758F37,EFAB2A6C37EEAAB8,32471BF3E9437ACA,0001698D34A2FFC4,94E779CBB06174FF,A710C2D17913F265,74CF8CEBC8216BB0,873E3C89E109A2D2,33CBDAD174E42AF2,556B6E273C9CBED7,00004CDEF5523B5B,59479F58397D7D49,6E409F3B94C939AF,8199507BE7FC16C9,31D51A16516BB8DA,CF4F30A5246D95A6,6D367CB671A8DB5E,00019943E87FF1EF,58700FE8CAC4CA63,09DC551B810381FD,0DAD8CF1B6AE8A85,46198234D62C5A6C,58083F4F805ADAB0,33E7758B76EB139D,000219BA0312203F,3C42CFE6210B3F5C,941A71AF0DFBD2AE,507B75FF78D4748B,69B2CBDECCB89C5A,94C898B57C8B59DE,98CA17DAA6DBCF26,0000FB3627D437F8,CC63B1CEDCE3A0B0,0CD32D70C9B3CC30,D5613FFC0ADC8958,D5701D8FCB0B23E8,4224B275443B8D16,9EFD16964724195E,0000BC4AC548ACBC,C4F50564AB0A898F,1191E0E421D96F90,E60159DAE586D25F,A5B3DD9044641C78,1439F6A2AEEF7B09,EF77FC9113AB6B8F,000052D98B48B1E6,09313E6BEB895D0E,6AF38699D035397A,4FBE29CCDA8B85CD,6C564B1A52E8E3B5,C8D117642E9549AF,1BFFCC77AD0410BB,000131387CD80395,A894DE296055FB87,5DB8470A2CA41235,FEF5B8443725D1B2,FCA66DE405FEC730,C4C544BFCFE70903,74CE0044E253EB18,00018259F34D009B,C3273CA14AE62F90,E31E217F636B3E94,A41C63C97C7965C8,F8991686F607B1FE,E37BC311F302B66C,E2EF85D8FE6FE9DE,0000D1664DFC3881,C4D90C0F00D51B8B,E59718F079173E13,608CD12E7902DD75,CCEAC254C5BEB15F,AC5F815370ED6199,D3295DDB1DFAE34C,00019D86F9D8651D,FE2A6047FA56CB14,D004D6A4BA6949A2,24689EB3FDCAAFC6,E1EF935B69FE5C5B,6CDFF99FC1866C35,212117C3E11F21E4,000079BCA3AB78F9,82FF06210E3EDFFA,272E07A6431EFD5E,E719B1822C5E921B,A906001B221DF812,052E6585D606220B,ED05E3331F99E229,0000579083AA0038,367FD304A45FC4E2,FA11EA91F1C6ABF5,39E59FAA6DC66EBD,CF88A0A6432AF727,A62C398E372E227A,AE74A8E35645BAC1,00015EEB6E65BEC4,0C634C4819A1ED8F,632268FEB06EE93B,BECF722F1E15D90B,C951162D2DA8FB4C,B02A1B6BE8A9AB68,9C324ACCCCC8C38C,00001B695A42186A,8E53D97D3EACBB01,1546816422E55F82,DED0DAD160D3FD5D,8249B64710AD203B,FCA69B2EA8E86113,7AAD296BB1437B7D,000125423B1330F9,7091AB1ED7539F4B,28419925E4BAD20D,E39DCE03BC0C1115,49EB10415FF2C1E1,D56389BA809F1E88,53122F69D5CBAAE5,00002572A0410415,94408985DF01B82D,D7EDAADFA0E53F14,4A245907960DB392,BB226A43832CCB13,7B277BF33DE3D23B,C4AEDAA89EB73B67,0000D21752580643,84AED6258A895C6E,36B24217E57E7491,9E6F1E0A51D27F06,0E4F5E0643E93D39,3896A837DD4BC3A9,FA18FDAC49BBAB04,000034EA6AE877E5,DFB4F8B82B5C4CB0,545BB1A058955AFC,D01068891A87987F,79F9D88F405217D3,9AB64DD5C53DFFC8,940D7DB71D845B97,000199FBF16DE3A0,D9379C3602EFA740,14DB81FE5A32C517,419B8B23501EBE3D,A6D8EE39DA5D0125,56107A9442B7C580,EAA6A10898EE23FD,00022EFAC42E1589,992694C146B577DE,0910F1157BBB6981,637CB38160574E0C,92D8EB069447957E,63EA8765CB69E1C8,DC9E59ADEAF236E7,00012D7DCC203D36,3AABADA2FB2A69D3,5EDAFF782EC99D1E,F10BB55F7ACB3D91,177BDF5BD06D132D,34F24DB9ED124120,54114B5129B22F2A,000049050C0B45AF,2F5CA0C247A406A8,DDE367BF0F642412,58B8950278FB5185,29050BF178AB4D40,DAED76DCF5437F7E,4CA8F29E78198058,0001063F8ED2EE7D,86399023050A95F3,01C06CD3E959204F,1A417A70FF5A7888,002B66036DD80951,CAC6D940A116FCCF,AF420C1858C09DAD,000073B6B8943D47,FBF1853CF4CA38C1,64076146CE220140,07D44FD9728E266C,E1D1C30AAE15B92C,2C65251123C21040,E84884BB24035B65,000185D07ABC9FC7,2CF9C3DD57549E80,FF75C7C5C8411D8A,5AC86B4329AA1E30,D4A1454728E83789,88F9A8848737DB2D,EE329A298C8E04A1,0001DFC97FF288BE,C44DD075B441C425,064B249A6E8D7A3A,E5E67E0D973363DE,6E7E9B098493454D,5B0C18272FEA045B,463CC69FF3B34692,0001993BD0E6A84B,D82AB92BDFDEE8F1,6BE4121F868511E8,9FCBFD369DBD1FB0,F4E3CE88DBBC3646,A53FC3CD2515EEAD,611EE870BCBA5C35,00001CDC2390317B,D4A38D9831C8757D,17181235735820DA,CD59E34A61783856,DCB8A1A8584EB55F,0156CAFBA65D8FFC,4D8CC567AA9D3DE6,000064B26D614845,BFEBB868B8908A57,5237682F9B452750,59CCF79AF996FB66,C05F593FFBF60426,0C182D64E091F751,EB0EEF94889460C9,0001B5E585AFAA16,FFF263E252B6E6F7,6215F00F1EF47715,085124C7B65F1FED,90F179181E54CF0D,5BD793B9654C55A4,EA53F96F9A483B6C,00010602D666D5AA,4E5E5DE514C96F13,2AC2C798BBF7B098,976EE2F3D5641BC4,0074576C261CEA95,871FDC0176077F2D,2BEA33718ADB38B8,000207B71701C5BC,50D3ADC2CCB580A4,AB07618076260833,18126A46026F52B0,74FA761F2E4CCD0B,4567554AC3F5659A,AD891EDE812893AB,000193060A996EDB,764D68EC155F7730,B7F19DB9A5ACF80C,677FAFC16F572F8A,CCE364F015C2E6C8,3B6AF86FA7CD3340,2BC1F998297666CA,000200C6C4126A35,0000000000015C85,0000000000000000,0000000000000000,2D6E659411000000,0C3E9279CF8657DA,4E9A9D269CA0A2D0,000092ACD020194C,898E8F7686F2F4E6,E21377ADF1509405,2C278C05C90D38F8,9E033CFCCF292CB5,EB1C3830C73809D3,64DE17327298FF7B,0001E05DC4B6D8CC,C4CFCE6E8DD591D4,48AF4FEACAA71C92,6B4756EE0C56E2CB,EE12A8E041F3BDE0,67C6B65234E8CA53,61A3D36CDB18D779,0000819B29E8027E,000000000000E858,0000000000000000,0000000000000000,721FE809F8000000,B00349F6AB3F59A9,D264A8A8BEEE8219,0001D9DD4F7A5DB5,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,898E8F7686F2F4E6,E21377ADF1509405,2C278C05C90D38F8,9E033CFCCF292CB5,EB1C3830C73809D3,64DE17327298FF7B,0001E05DC4B6D8CC - -ph2_T = 1456085945D0BBE6,A23060443A427246,6414C3E45A2D4823,31199D4A05995ECD,708B6618CB10EB64,2E199015E016EEFB,0002333EFDB53522,E1BE789DA9B9430A,6CA157BABC640F89,18DF05CDB35D8457,F5A852399993032E,9813A5F96E1A6F99,EBF778DB119C8E69,0000FEF5F10D76D6,89208B6FDF956BDA,312AC4F6E9C85F61,1B23FBBED83E9D36,1EF851C1C2EB17BC,A92211A301627063,E7CE55FD626D5223,00013BE0680A3675,F5B897CFAF9FE076,1E7165DEB9D50571,06C811BEFA0DCF16,20DB0016EA256AF9,9E976F1C93520308,81ECE186530EA978,0002286AFB77C08F,7F01E1B3ACDE3D61,60B5805D38581CCF,5910ADAEFF8407E6,07D3C32FD2CC99FE,26017F0905DD06BA,705FDFD4AFB2B286,000050904E766D96,2A178B7B01445B4B,4F8CC070A1E3F827,9C57D7998F0FA40A,294C04A269F86F56,FC195697B2307E76,700D13217667C845,00002F744FB2317D,93F88D69798C984C,A9CC28230B2C73E8,159DB9A1745AE7A9,9E243A74A4FC1532,5FC2EFD47B68C49A,EEE33086820795A4,0000098956B5DA6B,6D09B7EDABFE7AFC,12DCB2F666F066A3,60B97552D60A0DCE,D0530437CAEF853A,833A5BEC1C3E38C6,68E9208208B6C649,00018145BA177798,BDAE367B872D445D,1B41D5394F010B68,20AE4B45BE601BE4,9F7683B5A8A36BD2,5B208FAFF4874E68,36D4A78A0638FE13,00001CAB44915868,5413918A9C6AC04B,CC9AFAE9FE8DEF18,D1F1F828B7832254,E22C8D0E43FD51C3,84FADF17B3AF5989,D86D999F0763C569,00004868CD118175,4BE2D77B660001E9,EE67F358638B0348,1D2C0F8D8C883D3F,B6DD7E48326F1A95,2C3359677B50F984,E7CE202AE925DEDE,00021AFFA487FEB0,B64077578236B48A,E4F02BAF7936E01E,C7732BD164CDE847,178830150B442F78,B868604C0E1DB4B2,3DB54785C9924535,0001DEDA1E127F32,88CC7258461DF40A,1C1C0238BFDC8D5D,0B739C1B9124E80F,0467304C785304B0,C438C5DC4C138A44,EE637878D2BDCC56,000106F1CFF98A6A,50E03E36C8E537D6,9FE082583E09E678,BD50F262866500C4,1611AD005AB676B9,3D70DE4149F512C3,A5FE0A8AF42F9B28,0001FA096A6B5BF4,2E737AFC3279C736,5C80BE5804AB5121,334CE5B896B20A2A,B0B7628931F14103,F452229220177C66,479B76B25A8F2EB1,00008C24E4BE0212,52D2E72D5C3D7C61,462D101651DDE024,E874DEE1A884C6FB,2D7667BF2F86E7E8,13DCFF8FDF529F1B,30315CB0BD0DACA4,00003525067AAF90,BB718A4DE91D2E7A,6807B789EC770182,23B6BE2C1988CB21,046CDE8F3FAC4A00,32310A9FD779B9C5,DC6AD979889E8FE7,0000FE4369D5BFB6,7128D5A47DCEC1EC,FBBA33C573AB5507,DFE51DD4A059D5B0,6A41CD9B5B413548,EB022303D823163C,1A940DF4689B3443,00000F443EE50F76,730331425F914A2F,E375EB60D58291F3,5CE452B2671AC4B1,CE44F68469D1580D,AD841E807D413A86,50FC16FEB4FF5A42,00003FF2E5A5A9A5,09AF80D7A44153A9,4370AF2B95D9A70A,90CB86B7CD98FBB3,06CD65E6F1B56061,9421CFA5CC5FAF66,E00E9F1193A21217,00016F89D0922418,C9515C45B23273D2,CBCAF9DAD57EEAD5,C6576887BDAF34B0,45D64CD682E90C20,B918F02E502D0AB7,013D9A01210386D2,0001811145F8D31B,B80119C6FE953A3F,F3F28E9DFF74F31C,AA581012BE14AE9B,170AA4F561E3845D,D468ACA5FFFE745A,C0E01C98C00C58A3,0000344A29B5B5B6,B1F592429211384E,5FC20D463029A4C3,25263D0A0C87EC74,79BD50213B794F67,89A305543F49288A,996843733953A619,0000D51C5F4B644F,DFF06ED99F7EC554,9259C59CB4928501,A4545AE82AF29BC8,91F311FD7063886A,F82E939EA4D8681A,D2CF5CBC6A9F0FB3,0001DB8F671D9AB2,AAFA4CE80077246B,963FF6EBD9DD064B,2B06A139B49FB706,76F8457A9A582BAF,2304CF0BC45618BF,5AB17B66AC6EAA9E,00008A558C98E474,9F155A31EFB33663,F95B6204CF35A7F6,4B0053EA0103EA94,A45BA8515538037E,72804ECC51D322D6,2119C0E1B653A686,000098B3FA6B02BA,B0CF2756CA4C6114,81687D8900136C57,749BD84C9257E04F,CDEDE9CF24DBDFC6,728A1F711565AAD8,A8A326DD80C88C34,00012022BF99C88A,019771A4FD0EEB62,DA3F2EFBBAFB145E,3AE495E4D76E379E,F273A9807219A53C,5515C833E857FFB7,BC02285B7FE684A0,0001AF83BA6FEF45,3A64B1D009E1D0B5,62E06087B7F68551,CAA69A9A978F8E25,888A2381E0B3E34B,DF8D2B7FA3E0F51F,DED29D28421BC6B6,0001436F4C663167,AEADED14EBE1C10A,B93349324D08F1D9,DD298CD307B8F09F,1670303450D6840C,D68E0B2DEC883F75,F80265FE206A3C0F,00009F8224E96CF9,5E7EF143B4D277C8,D6791DE372C1E430,621802377618C701,C75CC19328677D77,1852166643F1828B,A6C939895628E2F7,0000E3CE0BBE3C3C,607A6A038AC3EC5B,D4F7318939806F13,A654E4FDA9A8F980,D4125B0B7B401E88,DC59B4BBB8941BA8,FB3F642B5DA4978F,0001BDC940BB4EFE,D01D2AF5B582E8B7,C9CCD273BFBC947A,4FD03A6B2458BBF0,578B412CA714FF06,9A624EC87ABEFD79,8DE90A634298DC74,00001C0993B4B371,02C69D5F4128A1FA,90504DF9E86E9560,5230B6A6DE367278,ACEA0270E9568193,735CAB6995BC3A04,19EA604126B1BF9F,0001051309D95626,9FF445EC6A1DC960,BB16F6234D6D8E11,AD5730F8FDDEBA7F,B2D3BBD7F6215755,4F64EA9E63113622,4643771394714FA1,0000C1491D43F77A,0864F7D7A82DB94C,2E2A477C549F62AF,86A5605AB36B74A1,48A3EC1D8DCA10AD,774A8B6A200D977F,581528C2497968A4,0000D98D6A7CA974,0F2A51FBC4A24293,58AF0734FA0AFD7D,51DE9BA1A6BBCBB5,2F818EE30724CDA4,4E695EB7D484D34F,D6816C783A25405D,0001086C36C75329,8E34FC538BBF8619,8024B4FB34F39CDB,4BC15C4B392EAF42,3C832875435A8F1F,8902699C64181057,DC90B3F196589EBC,0001CD905B034AA8,D688F3DBC0838661,70531F74DEE50E64,934829E784BE86C2,7FD580BE3D84616E,05CF54A141B41DF7,9F0EF599CBA04D4C,000130DDFE6570CF,8C52C0DC32A90044,1D5F36207CC20172,5D0B81F155A8E4B6,6D60BF794C25B07E,71D3285FAD4CC3C4,9319DF4C60F68B07,00006BFBCB6DF289,D54E13CCEE5B0D8B,1354B8E581371B86,500F99EC59C59342,FB6F9905F04A77A2,9FD1C2673016C95E,E2B04D4A4C9C0955,0001F4D2A1E76483,37E317606EF776BA,50E462D7083C8564,5B3A650B40BE2F82,0CFFE41073175149,431A5BBB1076FF8B,122972BB412E1C78,0000F383052E5F71,9FD3EEEC0C99EE68,BCC5B4D1B3E6F28D,06214B4ADA27EE5F,1518E018B666C99A,A5483A8EF8D24C09,CA9B93848749406A,0001B3A511864941,C5702381B755B0FE,7A4750F94B4B52AD,CEDD53EA28561093,852DC981C0B89518,3D531E69ADE4E9C3,48CD996AC464601D,0001F87DE52B393B,65F8F161C55EBCD8,37D5023B30021810,282D3B34CE7C195A,EFB9F3585FFB485C,1ACFD7B9E0933424,5CD2373D47B23E31,000069AF2E93AC7F,E539501CE5A7718A,6EE0159806A14C6F,D8B7976BA86608F7,ECB91811101AB5B2,2A4B44C7C95D4986,8D8CE044F7B291D2,000178E147D848D2,DC7A15C7CE123203,78F6F7F132C9A0B5,3CE7BCE1CAB9ECF8,E6012F79FB58E7A9,BDFCA4AF6201DFF9,03043E3559D7E5F0,0000527E1C450824,9FEF513A2D35B870,119F7604FAF2D380,90233865E631F2E2,6577F0BA063D599C,7383D6D58DC55532,9C5FB7E5045A1BAC,0000D25B23403C8B,9D730471A7890EB5,5C9E732E393DBF51,CC5B9DD94D9AC4E2,B89EBAA5A0AB010F,AECC62FF140DB04F,452F0583538269B9,000151EC753274F3,1A1D75F78310B34A,D22A7AF358107E38,4C552FEC96CC0A34,B1A5BEFF632DF788,093DE2C7F8986A4E,155516CE18C28207,00001EE0FCF82CCE,B3E459DE60CE5CFF,66BE88D00536C841,D6791EB4711B2263,DBC815C860D7D4AB,D4190DB5986AD3C4,AB2F2A2028CECBEE,00021801FE33D282,2990D115C285E939,57A6E14529C51CDF,373D97DB07BE86BF,4A42784BFA43E656,FFE97FA166F01A0D,AA8418E188BA92E6,0001F95F40965C31,5A256220DAB759F9,40CCEDE92813896A,91E1637B9F92419E,E9BA737C4C038391,E73E1F2490E3AF0D,B91D885B9B50C81A,000103CC7D988834,3BE80D2AAB63E198,C356D0E0383EB640,C6B3157528B48D58,6E819BC7C75BB265,EE287371A62A589F,A2B464B65205575A,000099B449CA74C4,C9E6348664E4ACCA,E1D9A020AEA63D88,F2B1C50D9D405379,28BA73B5EA1E01DD,D87730E8B58FD290,ABEF443603E150EA,00012D46C9EEE3FA,F85A5BA004888410,21BEF0F3604CC8C3,10FFC3898AB0CA4C,B85AF90DEC8C6FC1,C352EA2D25113E31,E7687A6DC2D9D8C5,0000AC92B3BD3ABD,EB061EC739309F41,4011A5A132719E4C,3BF2BA13A5EA17B8,B684783FDB0FDBC5,91ACE38768B25880,8ED82AFE71109F2F,0001F5730E025369,49C2D6CAD0AD586B,878F6D62E85136F8,56C20AD53193ED0A,25C6E33B46826741,5B0AA33F275DEC5D,102F6823C6F4B935,0002066B796C6578,5F49A9FB58F2E62D,63955F4DDC124679,4876460E83FB5071,AB350EC28436B1EA,BB035E65CF26E0CF,0E02EDD11FF617D9,0001440502C8EBF1,8A033ED622752B0D,C446440E4BCC5DB5,147F056BA42AC0D5,E648963C6E834B2A,8796E168E4D5D8CD,D1594ED301C38131,000002DEBCA8BE64,CB73974CB6D074FE,A4910D77A94336A5,0F7E4C5CD5C183C8,4C9BCE674391C0A9,BEA997EE04A18151,8457BC484BF82A91,000217B003C48D43,BF645C9E708228B3,10D7F331571C299F,A35EBD48F852C1F4,9B73786DB64CC36E,6B63A3B486379BBF,445EB2C062B9F7EC,0001C00C5A3F0563,0C7208B43EE9D3DF,F6A9EAE17E01D69A,5C394330A51E327D,C217F9D6C77F8554,2CA88A1DCF6A83DB,EB2103D5A915C843,00010023F5AE9701,F92ACC1EF01F63D4,BDE28A643FF0368C,EAC388BDFD216E39,975B5ED31B31BD0B,F01BF7A444A25CF6,E1054252D4989A78,00016D8E758BB507,47D23D81D31F040B,2BE7DBEDD3F87722,21A83EE88F879710,081AC1EB9230B48E,0FC1C407364956E3,02673A07BB4437EB,00001E849F301C5E,52A55CA9BD8E3491,4897CAE7E238B89D,B20A916B4505D4F9,C32BA4B96775C3C8,97AA1A50CBB530F0,795C16C326552874,00002ED3812FB6CB,19F8AA26CC61B3D3,5FE8B69F85AE0D89,632DC38CBEFE75A8,D4442576540FC345,D9637184F113B305,D439009F9DA870C0,000062835D2EEC5C,7CA029CCEC6633DB,9743D83920CE45E9,EBEA348BA2EC6D13,59DEA560CD2258AB,16E3F356CCB6135E,51AA8A59CFB61B04,0000486106C121BD,E8425766F682D252,04B2FE19080469C3,C48DBE0E42221260,E64D1E4AF034E0A5,A5664A029BAA9D9B,7CD698E318211770,00009A94E4090768,30973BAC0749510D,C7A62B2E4D3B5C69,C660EE166DA4E421,7F681ADBF7C773F5,42BEFF8065C26270,2A49FB0CC838AFA9,00014AEA30BC1BCD,455FA031FD2F7076,24A80BF3D4926DE0,B5C22B489C68ACA8,8E6894F106A47CF8,9ACF07ECAF1DDEAC,26F41D1E0190C368,0000763F1887F267,89A46E955BD22107,70CFCA86A56B9519,890BBFA4324CB698,3355CE64BBF199A5,4C5D559C4AAD0112,C7D963C4F8EAF42D,0000519963E20C24,A79BE30D8814A556,D8E7B6AA981639AD,A0CA5FC14A02EABD,A5AD334983F518D0,4C3CE0833FF42CAF,BCC87E0D77D42E5B,0002114B0C083B66,4BAB1D6D071A35B8,4210B329034DF049,B30034DB0E5B1089,486D1D54963B60F5,D3B64A54B5EBF376,F2A222DED20DB166,000149DF66E0AFF3,60FC03D84ED4F7B0,0B94FEF9538D0D1B,09F58C8DF94BA638,C9453AA5BB972186,605B2C84FFBC9B96,43CC6B9AE0CD4982,00013AF21272DF23,1E629DFB12D99AF4,982C6DB7CFABF0B7,378CC26B8C487064,8C7DAC044C9AF1C2,733023C3A849925D,09D4BC149FB10F06,000038EA4234EF5D,8F92C2724CA39C07,569C7CECCDFFC062,FF6FF5F080175936,6E27051027C679A4,E0AAF423F8ECAFAB,14220FE3EBE58B19,0000A0ED70C4CAFF,CAC87EC98CAE5FCB,6CF7D63521A6C995,925A691D25BF6C9D,4F5283B5C99EACD0,CF97F1C6807FBCA8,23A0EA5685F068D7,0000B6909DF693CB,E0250D13DAB59BF0,1FECE95F079F7923,028556F0F5C85F76,DF65C28360593C53,AC213C88D1A276F0,C9E84E3B3DE0978F,0000F294E1EC010D,73B3AE54195190EB,6659B38C1AB15470,4E071898E60E2386,FA11D1B3C6A96277,A3BCBE0B0C703640,3F5E6ED8A13C7C72,0001E45A18D3DCF7,6A46891657F85C1B,0B7C9BF705E015AE,1715CE11C2A7A935,6B5E8F2C06AD041B,DB18A2632185255A,842E311E692F41F4,00010D0B81C47C5D,0E1824086E8C1E2D,DCA639CF71B1F14A,A4540C2A0B1C0751,EB8EB87C183845FC,BDE59BA7D15D43DD,7BBBDAD2D3AE671B,00018F29335501F4,D21B7D29AA440E0E,E11BAB66BB4A62D8,201FAF628193F2A1,32B54506D7A33D73,4BD5EA7E9F45E10F,BB60EE2DF145C94F,00001B4A3249D8FF,91DE87CAA6F31738,15E7311B4D4AB76E,04532C44028A7396,DEBD1448C91A12A8,DE6B61FB84FC4D00,745E3405EFC5C82A,0001952517EB5A0F,45182FABDD52B544,D02AC7CBF96B4EED,F56AF48613A12468,5729D06A062F7536,237DC6530FEBE62D,6B49AD94281669CD,000171FD7595751B,BC32C3DABE33F877,C461C262E04EA765,97BB821C9F3456D3,4980E839CBABCFD5,C5D34D1C9B58CB4F,92DDCD2129FA062B,00011F96624B9617,941BBE9405A9A844,D46667BBC722226B,FC619FFA02D6386C,BE417958F6B2B2AD,781D212E50125709,52B750684D929FE7,0001A5B8468EBDBC,B431AF1FD7C2ED18,A1E3E5C0CF1EC105,66FB0FA36262D707,F84806B1CF402664,191A7851C03C70B8,1676E1CFA36BBEE3,0000DD86B7F2FD9C,33A42FE4847B567D,7E3F5FA30008D15B,51FEAF53D3D1A494,DF013636C0E340ED,2FECD99F3EDBF0BD,A1A6CB5E727416FF,00008BAC0C336D0F,817F27196CA6C708,59F235C75FA894A7,E0CC79D74D18FD14,A4ED10F8691DF49F,485E2B776FF5768D,8178F0F90650866E,0001A48E520F466D,D913D139DFC1B628,3DD9FE67A497FF95,5F290F2D3CB8B47B,1587258C7EF716FD,57FCE751D2968303,114F51A40D0B8592,000072F89F1E9EE0,1F03EDE8D73DA0D6,2780F2A221FA9DEF,AEF4CA7B16C61616,BE0CD2C09C7550CA,A2F7AB0D90BC9EC5,09DA699969BEE923,0002150E3606AD89,D961BF07B00ED803,AB38DCC23FF4254A,5B4D9C1F3B72AF7A,3C7CA8B7E0762492,B515AB889C66CC0F,D23B395A382A8A8F,000079EC8715A008,1E520E4E42DDB144,66322ADBD508DEE7,0D34F6B4EEDE5D0E,FCF190C4FDDCA6E6,94A34FD3D0D4B728,20BA0443F357978E,0001D5447435561A,DC38272BA5609AE4,366C9FE98F12CF8E,67312F80D59298D0,DC32233606398D9F,D8C576B61CCCB893,0996FCA56BEFB4AA,0000F965D5746389,53C9E4B2537D159D,94DDCEAF64077AD4,881F105F69494F12,8B7606750678782E,C5C85076C271C37D,D3B18064908763CF,0001CA622886A9CA,EFBBF8B4B0983297,B3010E2C044FB9A8,787FAB3BE1FC2EC5,9F2123020B06A3BF,156C3487C0001965,99E6E730A0673D55,0000B1F60D30D90B,B5451EB196A96BA4,B3CF18E5EE409F04,2C1EEE84B636C09C,3316F5535EF20482,12C2DA94D465FC33,1087B0B712994C78,00005A20DA308F59,FE0DE79F8D576A3E,52C94BE3270C884C,7D4563BBADA90C27,418F54BBAA2E4533,6AB0998D0080DFA7,EA5C659DDA510AAB,0000975090814370,87B875A2D5346812,681D59135AA65875,797D92F339FBC170,882362BB76ACA6B0,604978C235D1E81B,B8D7998B680DD622,00001D1CB0701574,D044F0BEF32E10AF,8FA9B28DBC7617B1,E0A1EABFEA97F640,A47D20527A2E4DE0,E6E29F4DC355B952,72BF1DA2684BF558,000151528E26CF9F,BB71D753ED3B9033,A2E0564A7E978B96,9143F3EBEC7B53A4,010BD6085A2E6CB5,4E2BACAB2B7CCB02,61B23C8160E06960,0000F17C7D2CF7EA,B745158EE686DB3F,B15F81FEBABDDEF4,67BFFCE9B612F693,9EF0E831B8875D8F,41BEC79439E5E340,6CDF302A5F8AD176,000160D19109A233,22110061091E1994,7BA8833C82CE078F,037B0EA1AEDFA492,84F672BC4DC3C3DC,2DB4C6C8C43376BC,1AB2BC64BBC4DC56,0000108C0ED210A2,5D2AF4ABDA98DF6A,AAA686553B953ACE,83D66F0483C16012,E5A6E36376757656,610712D26B2B7BC2,C34F01EC14DB895D,0000694F7502B6BB,7059A8CA9FDD8ACC,4E4DF3DD0037C865,77CDE35BA385F7D9,85EB8D7B4AA4345C,A23EFB52BCC8C9B7,1A8BFEBA24A631C1,000161A1AD026E0C,C0BA9FEF09537E3C,F0A92E7B6C8F6242,9C6121E55B1B1FF6,3A844652EBCDBF66,AA23A511EDCD5B90,B762D53963641842,0001BF15B2A71F97,F61024FEB759A3BD,4331B1C4E30CC209,64F67A1D37995E92,C88F5E80CDEE911F,EAACB9D5032BA1F6,CCC87B229F6B258B,000228F814B2AE74,BDAC226E4764D03C,A978AAC5443F1310,A99BA02D79CB95D1,61A382AD6EA923C7,EBE0A1020D35B800,69BE4B56C28DA89B,0000FE045DBFE452,57735A303A300B09,368B6228A45FBACD,9CB65039B924B809,D430447EDBF82C79,115730CD4ECD71FE,28D1724034E838DF,00021FC7BC79F08B,E0C792B249D6979B,9EB537E12F2B9244,8C690D7E32E22626,5D9E060AD352C37C,2B33047FC6534593,E4AC694BCB7092F1,0000B505799CF499,858FAC8035DA37AE,DC5D0FDA6998BBC7,B60E62B389453626,796542C48C650594,02339E70B480B214,0D79DEFB167CF38A,0001B27901D8401C,8A699FE74671CF53,F49C8D94A327C06F,F24F9AD13A2D1059,E9F66DEC6010520C,80ED146A4B77823B,29CE4752A8435A0F,0001B9B91A029C13,D42A992E1B8B9668,466D6E21A1B37F07,844A3D66F3145A51,F12C0F706BE90AB6,4297B2472B426A01,78591E4562669CBB,00016CB5E6F1373C,214636DF4B217F11,4864973F5B90B4BB,A74CE7A66C2DD889,D1177EF0015C6983,0F519031F8303022,B9F23ECD6C7E948E,00008DC593603536,729263606817AAFC,FB963AD75D625FE8,E79EE2F942CB02FB,BF05BFBC272AB9AD,3B8E814CECAE1C59,4FF185DFF4E647A6,00015A5FAD3993AD,12E8A193E75DF536,5E35ECD00439D559,006D0F04E1AB00CD,3B6AA94C7A473CBA,77AC044D1BC6DFE6,EE2A4340C27AE259,0001B6BF56991C49,9F63DF75C4CC3D22,83E9CA91CA2A529D,51FCC06C13DF81AB,21D3B578A78B453C,C90F2A5CD8C04214,CD8C4AC13DB5B733,0001DA0C04B00D83,85436FED5EB0AAED,4B6643AAA91FDBD3,DF7FCF2EACC17D0B,58E468A2A27B6798,A6439A193F71BD2A,99344752AC9FB0BA,000135DC95C73394,340002BAAEDE2E15,5C78601CB540FD4E,087130905CF155BC,78989F37FB713EDE,FC73CFD19C87206A,EF05113543D595C2,0000F758F22A455F,FD10224C8C5C0745,7A04D5BE4BED420F,C4E6F18B938A7C39,C5BACD16AB5728B8,12C3D9C11BACA938,7F71987BAB2F9AF2,00011A9EB9D90CA8,562F706594716E7A,2A7DCF1772147CDA,34E141FF3D91881E,2D654DFCD8BAF813,881D0AC916E571A0,81B84B812268C1CD,0000522BBE4D4A26,E2D0CBF1007BFF20,4EF83446CA42FE3B,628570112EC93AD2,58C962DC1AED833F,D30EEDAD70D13FAA,258506D28905D576,000012D68E9C4AFD,31B7E3250F943EE1,6D7099C75E9FE71C,CCA02887B09D3982,E38371392CB361AC,69CC299C03BFC625,F834309825ABE38A,0001C0F7FF8E049B,3A57B71C7EB4A5CA,70512B83E76976F5,CF99F9B0C9F68786,795E466417EB40E4,28F53B9176EE59BE,0C137725A97A42A5,0001C115C870103E,FAE5D83234CAE887,FC26D16422B6EA72,AD67CF85A1A19B43,6DEE824EF73B10CF,7E40323FCFA1B75A,0D1295259945856E,000047C3D78EAEC5,79E5303A8850CE0C,EC477BA0D9C93626,E872B49F677A5FA3,316AC133140DD173,2EF8F360F762EDA7,E105C26C3E84569E,0000E6FAB5F1632F,F421D501511925F6,59463683D3BDDB90,9ACE0FCD729F558D,7B1C937646A36EF9,BD505435CF40738A,72D74FB296009AFB,0001BCFC349BC82C,BECD956E396369C8,1FB2406D31EDB0A0,07B73CB99AF120E7,950CFED47CC1FEB7,BF52D32DBCD3AFEA,13F6D867893C1CDD,00006784699F4C57,C349AA09434FA4DB,6560F795BAB87B7A,2B06722A900A6BCE,0FBBBDD88756D757,478B1545E8554B3A,21C7CB3CCF6B8EEF,000114D458A9D7E7,4F97FF428E81A34A,DBB360F9E7CDDE7B,ABB94023EFC14A50,9749236B921EBB53,EE0F6DE7C0505D3E,CB58131301E0F3E4,000210C21C11C224,C02ED0F398A91C26,CAD43729C5A804C3,02262AB9D08A34D8,2ED54C9CA85AD26A,457A0EDB0DC90FB7,B0CF993C13FC2744,00008080B968BFE3,809AD887284DE5E5,08AA4B22AC0CB70B,2A61124ECDEC14BB,FA85C1804E4E1177,231AE00526BDA008,85D79E7486ACD55A,0002206C2BA8EABF,0F2FD18666272F16,44935B9329CCDE12,87D83335CA73C708,FFF2F96BEC1476C9,F889ED753A3B36CC,ADD1B8742AF5E1C4,00016E53E76ED40C,18B1173737C3FEE6,972ACFE074972D57,D266499F5229EC1B,5ECE5862F7E2CE58,70272FAB6AB90B47,21F30518AC990D74,0000AFE95D5FB7EC,4139B3BEC086932E,EAB3377102322BBF,6CA31725659AB7B7,8AB3A4D05D4ED945,AF15DCC775D65640,C84924E5ED539D6F,0001CA95AAA53F11,BDE12F4B58984A81,B30955189D7F8F45,E2F62829666953A4,510CC6E4CD31BB84,B037983B4947EE70,519257D7DCEC9E8C,00009CD4915B5BEB,3F62409D27B00D66,16293EA786D2A433,D9360CB0CCE617A5,A09CDFC473E23D31,F44A5A536953883E,D4BBC23CA610C4A2,00019F645ADC5F91,197FF7E9510481EA,FA088599CF15F960,98A016E98BF5786B,3B4F5CB115E3F44D,7A58CE7ED52FA510,0A1A3D1B80915B8D,00002873ED837CE1,151638E99C9255FE,E71FC2CD407EBB7C,B2C8B6CCFB7660A9,86BD341D08F0DCC9,A427C6BDB7C70E49,5F2F88893F6F3E48,0000F80B9B56CB8E,C147FE989832B4F9,B8AA300759C1E1B6,C4783BC1869BC05B,C46BE5236A3DA0C8,BB419C8C5CF118D6,4577CF8F29504237,0001CDD5E2326C23,E6C2C07A578E8857,FC5902793B001BAD,CF6DFBAD7D993D57,AF4DD0FFFFAD076A,0237A4CCA63B0536,0B5FEBAD2DB13062,000045167BEEAD7E,9997BABBE45CF9E5,C5EDE8CBE560FE04,FD65B49408ADF637,3CB88F9746D620D2,92EE68986C9BB7A5,544AFD9A48BD2364,00010E206A356A4E,69B11314B368791C,852CCA66C85B0E59,7087A6BC8FAD87E1,71753E8397AF3626,BD9795DBC4B436CC,A9F7B82E8B8CBD6F,00015ABDC1669756,F964280BBC1E2F1F,553BCA6ECA474286,BF5084B8DB9ED50E,6807D66B61F092D3,6304A78A6C677907,5A16A636F194FBE0,0001CBCF38B58597,E5C52A7D15CA9859,24007E4350750DF1,9CE7A4B144672F6A,C5E5DF3D69B8F81F,C2656552BBB47A5A,22DE16080DDD8544,0000764A7ACFFD38,93CAE886C435E16F,28372BFB9563CA28,86E1076415C4F6CE,4260FC86DFFE0E61,DCD3A5218664D955,6A6F8A4CDB53746F,00022B1E379434DF,7B703C4CFFDF01F1,4AE120626883DF87,C499FDCDFDA8623E,35FC513F0B5F29D2,7B92E68CC82B48F2,C2CB99839B8A1BA6,000119666A816004,8049C0CE7A971765,972D4A728E813729,B64AEDF13F68EE5C,2E26420477D62C33,2EB53702B88B2AAC,EF12B7BDB7BC3921,000227C9AA3DFBEF,495CE8880FBAB78B,775EEA1B1B9B2105,0B06716195EE8464,F4CB73B04D412FF1,09B7315E4C3DD6A5,3B19BBC874E434D1,0001FC91FE8554A6,4DC7FCC5082D4719,515C9477F69DB88B,6E949FA37FCD8634,1CF4B71E1289C893,8E2BB706688BBDFD,ADB74A5326553C4C,000198E5DBAA263C,7312627742A578CC,D28F4A79136C550D,F79D432DA49937BE,CDF1B7CD0A680B24,F142428CD8FF446E,35CE73E0F730558A,00012AB881C4B912,39CA4BBA65B46D11,549ACB47E31AD3BD,8D2507B6C8D3088E,1EFE878899C755E5,00EDD08BAA569BA9,33807BB3E9D75A68,00018789E2166829,0ED298A823F2C6C7,E724E43C50A5028C,278A51F0B0A9DA7C,A00FD80B5C1A42FF,A315D6EA5731964A,B29B784DF8DA881A,0000CB4E04815BD8,544376751A83D894,BBA58CD6ADD9AAEC,870D8AADE40C7B3B,210063A9D0834F5D,A52006E393EEF9D2,19688CF26E0CCBEF,0000A2A0CED08F47,893CC2E64CC3A51A,CACA164465A70D07,330687C8D9814C67,1072B111C9F0AA96,5629F299C597D515,E4B68ACFBA3DD570,00010632C04F46D0,3722B3E52F99D1E5,38E00777AA2C6D04,13D4751C24C39A1C,D82AA8AE40F0EE34,B793EBDB53FCD426,CC56EAE50F5F857B,00005585E492FF4F,73F78237E97A5F56,47F21731873D6620,56BEEC6DA883FF55,8614F16376317B91,EF6B8DF8CB6C96EE,25EE8A82FCD5E501,00013651D466E1E4,F6A62CAF7182408D,A07ABD44A0A9FA0F,EA5F1C1073037411,DBDC2280732C7221,A82A1B72EF97B098,31486F11D465E603,0000EA980931171F,1161DD5F15483FAD,5599D4916C629513,E9B20532B90A4CB6,BD57B4A7A801533A,0FC2763AEA268034,8E4D9348327EE538,0000333F09CD5430,43230A61C9AE18F1,6911D6607B2AE159,EFCE35764E639CB7,CF7924B5332DA5D2,E7BA85F30E9E678A,FF28A075A0D1DB50,00018C3290F8B626,004C32CED7C4A33D,7AB6593502435F7D,A5E1FA76EBD0C720,6B13921376FFFB81,5D5339FE492935A4,3D449A28EC3611C8,00011F90577F4672,8DC70C2CF2D70B7F,2499E1BB41300145,08340E16EE33ACD7,A4E55D28C63BF7FE,58527BC126757D3F,26B4EAFADFF75C9D,000120096A7C58C3,92F5CB9779F9D5A8,96A8BC3766F56163,6C1220957DBA50C0,894E39FBED4E244F,25BC89AD82362B49,32B454F50A70460C,000049FAEAD59880,656548C33CAED5A9,38127988461EB3B0,800FF0781077FDC5,96E45D0CF8116B93,6D7DD4AA47DFB058,4D154B7617905616,0001D558729C6507,B626ABB42250FD26,DE728EB1E6497C3A,8DA04EED15E5A7B1,692B356D0B996B64,21DE811893928FCA,49278769812519D5,0001B404C17C520A,7167F3F1F5AE4A16,65A4E5B0DF173E58,C3FF977986709743,DEAF4A750F1D267C,F1C5DBD215CB15EC,6EEF93B4D8392E59,0001AFAB5BE6858B,B64AF91D255C4B2F,4ED7253B968052FD,95E29E55298EB44C,5612A91A301003AB,5223FA905815A2F6,BC0CBCACFAC3E5D0,00012F4E48BE2AAA,4B9B3AF05A636381,FA8A774546B8E6FF,7BF1B1AE5AA5689D,64FF9119878FF5A0,04971D278F81A0EB,9CCF8D89C5B0DD65,0001E2C7089D9DE6,B1FDA507841CFDE6,4D9760B1277CD4A7,652387A092BF3698,34CCE1D91133E05A,ED4CA938E6A71F9C,CD55CD896C56A6A4,0000A9D8FB9C83FB,1E15F374A9245C66,4B422BF0F9EF5AB9,FAF009058678040F,27F79ABD7BA62851,5DB09ECF8927168C,CE252A416AABB32B,000098579D16088B,61D4CB478360BC70,7EFEF222E7EB53E5,E66408259417E67D,AC67D4538C2723B1,35478B94A85778FC,7BE6F3DBDC4FF00A,00016F34E4E6B7C6,AA4A9A8B4D54835E,7E5F56C035DE651D,2898F7E9563F8D66,9E06A2A101366385,004439821DEFA681,5C2532F71B1D3FCA,00017B410D4D2CD7,ADFD8B2C05D92FFF,C18D67BB5CD36C10,33B8AD36C32A67B8,C096D921088B7D89,8157247DD7AAD1FE,3938CB935C0D5367,0001209A50505203,9299EC54DB0912ED,5BAA3F5D6CEF6DFB,63ECC75580BC0E64,52C94F804B4E241E,B62D8172AC81977E,F0B489CA2E10E3DB,00000BEEE5C94C80,9CDD831EFF0D992A,FC8BE23B1355FE4E,F36487E9D2AE8CA5,2704D83638C40624,2981E05F579B2504,65A85765137E8A71,000140B29529EEBC,92577A1BAA342908,9B4272DBBFE9A58E,E24C0B4B0338F492,B0D70D46B37CF241,CFF3EC0F91198F29,1AC60C515956C57A,000127478E18FE1D,EAEAE1719F7D91EF,705AE630FF390F6D,0CB0FAAE564D7282,0C0D6042097DD99C,3641D6D5C819EC64,474BD038B64DE2C9,0002117409691DC5,B2935531554D9C95,828EE3274E51D49C,92FCEA62CF842057,5B3D9847B5D0CF8C,8E8EECD209CEFAD6,69B4061691E4DAC2,0001F7A4625FFBDF,E609E7D2C6FE9ADE,AA1A211FCE6F873C,EB1DCCEC96D3CA01,713BBDD637B3E34C,94B8B7658CDB03D0,21BA186914E6CC52,0001B861BE8C8B0B,C11E902F20BBC78F,CC411F32252B0BD2,45FB0A8DBD8C6E84,6BAC1FAD9962D540,99E8931C47C41D43,75534E9563E575A9,0001DC8FEE5E0D91,DB42E88F1037294E,1E211B4E45A17FB5,28315B71A81D3DD9,91C4B0985116D22B,B1F6E1B2266C86FB,47DA787E25C0A71A,00012C7162234701,F40454F3E68EF02C,3E624D37F7C61FBE,C00FD796A55ADB0A,F942E80B475A6D3F,FDEA89537F997521,892380511E105079,00000E512D8564D3,5305D0FE2E05CE46,A0AF3235F0B3CC5C,9F12FB8CC860AC54,5D570573B9BBA591,E51040ACE1A8B4A0,3827CD90897E94AD,00016482771BBFE1,2A2521FD33CB439F,BEA9302BEE3F2F93,965600FC3D3D7341,13DB0B4E5E2A7F5C,47E443B41A19FBC1,FB727CD35AEE0DEA,0000BA59783F6ED9,523E2F620611233F,44B98A8DC5F2B07E,F4105FFE32E48070,F51E9D01398434EB,5DE37CF8443A7317,DA6D22633E7B0B04,0000B5F20B5B1A61,D745B5BAC2C84E88,ADD1BD12929D9EA3,D8878D68B71BBA41,A58045DD95EC75F7,BFA1B5B6074F3376,CA4D9DB3D4451E4E,00020AF89CD95E0C,702FC3F31FBE9767,4D49CB049453FE90,239C2C2C0825F2AC,12A41BF5287C2129,591A0763B299B478,469835117A2E173F,0001A03EBE219CA0,CA1BA908FA90A6AF,70999FB619304611,5E1E88E9C68C2E90,EDAF0B93A5777AED,33C4BD0EF2B6F6A6,19D1630F28D02DF1,00001F89AACFFC69,2B124CD47FC51AD4,BB4E3C8ADE9DBA3C,037DB7629AE6D77F,5E9BE5F05D61E907,48314CACA657763C,DD78DF68F753532D,000137E7C5D81127,117312AAF42063B5,CFA506E68BFFF8E3,B78D8BAADC5659F4,9FDB7154481CF17A,32AA3F0BFACC72AD,F7E5D97167E5D4AE,000231BCDBEE68BD,3E2D70DC596211B6,D7443B6A8548DDED,C5941E9F46161498,60D41C798A8FDD7B,A835354B2EC05339,DF7DC574C096E964,000125F95438BE2A,1D92E586A8D38094,FD3BFD91FFC31955,2EB953AF48185595,CA407F2E24E063F1,E77DE1520B9B09A4,AA3A58327296DF2F,00017D715BA85263,9E0009BE6ABC8732,5974D4B198F92C42,EAF8E151CD78A1B9,90973D332FB3927B,C243520B1D3B0D1C,4BF36CF204FD4940,0002280F5ACBDF02,A46DDFBB6206DC3C,9434DEF787DB348D,2BC1FF83095C16B9,620E07EE1949CF16,89760C0D8EA09F2B,5709140BB1F4706B,0000572E115F9D02,AE709100B9B58295,CFBF5E4FF6CC55B8,790F541A046DA11B,412237684E174BED,06C68A94DAC5AC1B,08FC57C76A4C4C48,0000092BDCBB87A6,89FB316B49EDE38C,47EB7B2C7EDBCA38,038E55BEB3A5C8E9,EEB3225C7B22B33C,857C7CFA98021375,E20501F19CB1E280,00012439558D6CBB,3375BE495521593A,4470356C50E31DA3,7B6F890902A01BF8,2BD2FCE472A0114F,F130A79348EB16A0,5423A4E69130D341,000154F72795F072,326852A828663114,2F56CEEAF958BD55,0C0067AC16228C6D,EA1F18BD81230DD4,06E1A13ED677AAC1,DFDD198A29E80B31,0001A6ADEF2492BB,664EEB929C4E202F,8C40A0D794B7883B,49EEFD402AD20977,810253012BF1C525,4DDDEAD3EA2A2120,1AE1B50F9E295227,000190A3185E0911,47B1C082F16FBBD8,ACCB0102D8826BA5,3E4CDD1039C07F28,C01D191DA9D5A4BA,4D7D875260114733,F8543336A723AD87,00022DB602DDF104,581242F214F205AF,40C6694C01F85F37,CFA54302A557250D,E5407E133434AEC0,E87C06A7A637E3D4,0C1EBFCF07684B5E,000176A8ADCA4E15,9F3F0AB1097D57B1,72B966B5CCB2FB74,73F2B9408E6B934D,505CCF723DE68CF7,381673CEEC265E99,F4F0B626278DD78C,0000994F87DFBD9E,B511D470E404F21D,93D487E985681488,185F3E37E6D153A5,7B70ACA3589B1015,4408BC5351C9B780,9EE8864ED3814349,000165B13B1F5FBD,6706DE34D992C199,0DC23D1C41751A64,F816872488261A72,77CB5D8F55B88D11,0263E3695A52608C,E48E91488DF94428,00020C0FBC3E52EA,5F5C64D0FB737A9A,9655BDC9AC20A658,D1E41A1AE7473EC1,DD06D93C7D51D386,D026C34BF1A649A9,AEBA18BE79DBAC3C,00005689B8B5C230,3E834660F04E2506,8BAF7502BF451074,C3534377FF09BF44,145F35D85BC68715,8091684895E5F5F4,DC3BD984CAC38084,000143C58BFCDF29,4F6D6B770F398808,9D709A1EACF357FC,C669D67477F4BFDD,03AEB7F07ED30E6D,C1C2C24DC09A1A66,84AA69DCA141C3C6,00009DEB0B6A987F,B5BFAD10B1FE08E3,47F12852EB924F2F,1E3EB9916633D1DD,C06E39FF51CE692B,B3ECFC360556FC3D,97C91FF1302450FD,00008D82F6437CEE,91A7C19A7D1C038F,4777E733F6F26D10,BD3FD9A57208869D,9D177064DFCB38A8,AA6F77A1F4829FB7,0CAABBCB7E495819,0001DF2AEC29C281,E0FC5398816DC7B0,F6ABAF78A08421E8,A74939A20F8ACE86,03601FD744B514F8,D31EA8CAB0C08143,AD52C2FA410EDFF9,000182074A4C82F2,714D4A2C21BCA828,04B8E6696A6C1E14,DC7298B7C8ADF54C,151344468981E1C9,9D4FB6836193FF0E,9C7BC1884FF4A48C,000151EFD82716B0,9DC76741354D3CE3,09B8C28CD4CC6FA3,0E3EC30BB3E48857,0C3DE8B8F42F1A41,9BDB4A2095753A87,050EDF8F643D8BA4,00014A8B93DEC761,187FD16311E7BBA2,8056C5675F8CF343,E7FC60A0F8D06995,3464BF36C4457E14,3F2E092D35D31B4A,611E06AA4FCF75A0,00002022A60F5312,3B2F5882FB54BCD5,BA50088E47135A02,502657F7CD3217E5,89A1D9D82F4B1627,B368583FE68717F1,04E0C4057BB6C922,00022C4A739D5947,3B6E9FC957E03252,C5640998CAC03621,A61C204660387845,6BC3F4583F21CE7D,A0DFF68A32F1B12B,355C14B551C10181,00008F74CE46EE4F,C344CB71C6CB8E02,E58A691C983DD3EA,0AD0379F8046CF10,F165236A6452F40C,4D4C441797B594D3,27AE5965BE2098CA,00010AA6CADCB5F5,222761F2CA6E73CD,258942E523CBFB77,DF31BFD8E5664FEF,8A77BA5D69C7A58D,1688116F64557D64,D5F850B4F08EB74E,000070FFB3AEA24A,D38952A3E835E548,392A7E98532A718D,C17FE4B2470D9C1E,97393D78ABA444F6,7510ACBAFAB0D8E9,230915D2BB33BDA6,000213D23546F839,6A6E9C620B3087F6,4BA12A584D7B3D33,E60744C086B2610B,F919270A2B08E71F,E8FF999274C50064,3CDE127F9826F675,00006BCEBB969B17,DED7F0C510F78C0C,6DD9EF9435FAAF7D,F874E715D32CF060,46D21666D47082BE,D41BF1920E6F6691,5F8F027446BA1845,00020AE14D346265,8BAF939A8ABAE5F0,2F55AC8F85506D23,B257BA9E07079F3E,DEAC9FBAE23DDB19,5145A9C48422D326,0837F8A47627E02E,0001149F8A5E85EA,9D40F93C186391C8,DD1FBA2B9C58B51F,E1135E2D831A68A1,32FCFD6AD22837E1,D91C7F52BC154A7C,44F477B613A841D8,00010AB304BF90B3,A589907F125AF9BD,4B785B9BB26291D0,EFB8686E8A48AD35,8DBA63DEC441CDFF,55A6DB621D2A29B6,E4B6E0845F75C58A,0000557FF9886DCF,448CE35879E95C24,1528BB00A01A0CE6,4C05EE6F7218198E,E280CC7D5FC8FE9B,517A16C88627DF83,FB0200B882E24AFF,00019FF920748271,19B8DEC1EDE6122C,C959772A8DA7D229,289E229D33160CE8,D1838BAB0001D297,6A1FB8B5C730C90F,6B7CE39114C12DFC,000168BC9DA875D3,8A2BFFD17E2EC7B8,7142A91FBF878536,B938CB2B9B3A0B20,F829B88C130AE57B,D8170451B76057A2,29BE2C2A7CBCFF06,00011FBF716736CF,2019EBFDA5E5A266,B9F77EAD8CDF12BF,F01A7FBDCE417072,B88C6E2F43E88B4A,E585D117E23959F2,E597472032697B03,00003EB9AD63B3BD,68B72755C0EE50E9,777B86D688D4C5EA,2C083E543BCD2F9A,D531808DABA45CF4,87519BA38216A3A6,2B8F90544A8DD966,0001FA160C52581B,C9755E897E8F071E,B624D139D6EC11DC,77463822F0E04607,A683F2A772644768,D4FE42A270121B08,A18915809FD0188C,0000B638161A875C,D52D0B55E27068B6,69F125E2CB3BADCC,7F277158BB8481C4,77FB27EDC49059BA,FDC4E6B958129049,B81FE3A8B00E4B5A,00015C9784795C6D,BA3C75DECAC0EA54,53701C40350548C2,ABBED9E660C4563A,D56CD52D4CC0108C,59396DEFA575BF45,2CA5528C932FB6D6,0000693992789748,2500E71D8DD7B128,846FA9C8D13E3664,E182C5D4469EA6E7,5E924BCAEF87DECA,D707B4BA5AC2D51C,B3EC8E44C94568B8,0000CFD578AFC8A4,7D50CE6515A83E1C,D228815646665C06,AD200EC1BE28601C,035536051580860A,E4DCBE823A0FA29E,509524D4AC49863E,0000426379D83490,EFF66E722ED4D6C3,B3346AE4A6DD2A69,24FBDF194D9965A3,4D0A06AC8A801166,B223B953AE5D6CEF,43FF892BE6E596E6,0000FE97E4092D87,FBF8B3ED4DCB93A9,5A48EC131102543F,430B10BC394C6124,0E839FA6FA210D01,1A6CE279C46AF32D,A22D1E9B97D50ACE,0001394ECD849E08,445EDC09564E92D7,96EBC8B9727C762C,9885E18667E85D56,49370276CF4FF283,A811E00E64AD85E5,5868C201D42D6A60,0000E14621AEEB17,D7DB1B74D75E4D45,FC21AC01533DFC5E,6F93D3475E588A0F,DE2E5573E68278B8,74B47E88561EB4AD,76E0B41CA484FC67,000133B1F5F2B4BA,A0E82B7FC8E303C1,726E9B3E569F1B3B,2B6D3F5B165105E9,91F58EE63E9A0784,9BA2A477DE9548D0,8C3FEAE4BF4B40B0,00023248AB75656C,2EF77B54F2CAB5F6,315FA2FDDD9B464F,970DCEC8BF483BA1,0C1E7D83FDC6E7C8,79C268EB2558CAD8,B92FBC58DBB43BD5,0000B5F206981A3D,158CC2D46A570DBC,96A4FF45DF4ED3C8,6FF97076593CB6CF,8E7AD4815570DB5B,DCC663C8BC179D32,8E153D516814D229,000063F84CAFAE5C,5AE72D9FFE00850F,FCF8A8ADBAA0F2D2,8456F386BF3856F1,3CEC3B45C242244A,CA0649FCE46B8AA5,444F4CA2662AF9D0,000165901EE7A9B7,C2C21C74E7A60746,2FC8986ADABE619A,CC6BA0B4411C31ED,DE349B83680A283C,F8F7B3DCA01859EB,70EF3570331FE8EB,0000227EBB329AA4,0291CEE7EFB12D02,56B9693DE63743A1,8DC050E0FBF54654,6D4C6339DE6EB24B,B347AF7F268E8736,829DA4453D98A7B0,0000D308645DC1EF,9F7651CE148855BE,05875F360C8B90F4,DBE123E50D31379C,5BE0E9806A1FB83B,420AD74F2B17216A,79D657EF1AED6328,0000092DC69C6CFB,31C967ACED8357C7,6BBB31112F229550,FA018CC459A3BF28,1FBC8E3486378BD1,9D270491251288FC,446B6B821A6599DB,0000C558ACAAF467,847283C99A606BB5,ECECBF8D989D48DB,46AE9F65322D2C7D,0B10B2BB47027393,D2448D802459DBE0,037E1BAD6D7358B1,0001CF91D09C6835,777BC40755617ED4,518D7D1DDFCF37ED,AC72CA174E4E1CCA,A5DCF0D388D30D12,E39EE796B1A570FF,E8D4BCF6789ED0D2,00022E00F65ECD4C,03FFA54702BF1CBF,48FD95FFB8CA7516,120A158D567B5D06,436A9F50CA43A39F,12A6068939C67E11,43A0B07C06A4EB9D,00011E022AEEF98E,9017457859BB71BA,B500453FF910D3D5,25B3FD40E09F6C43,0E6110083967CFA0,25FACE87C34ED605,0FDFB1F7F5FA4F69,00000CAB27470FAD,2EB4BD795EBAC886,FF21089D173874DD,998CB5D6BBAD697F,053A4F1FEDB2C53E,84C7CC39EAD899E6,26988A25F0AC7799,0000ADED193C6BCD,4F8550A65FC61EC8,4678D2EC9CB89642,06699C4A8223FA3A,7E7CCE42C53FB235,7F1B6769FA8CDB5F,85AD0AC573340C4C,00019891D4DDAC23,41B5D5F7FAA995DC,6FE063AF66D1572B,1A059B67149BA3F4,4106F84D8085A4F0,85CEC17BE563D729,73A5735CB690140E,00009D42437299FB,3966FCEB304A8AE5,2827B5D729597863,01C7C9F89E2E8A82,ED37A8B742D0455C,ADFEE392BDC8469A,2FC7BBFD1B0891EE,00005AD729A310FC,E5A0FA02F0DF7BF2,B87D5D76548840DB,D404B6B0BA3C02A4,4A855CD624C7CD72,FC9A75B02F14874D,B6747301C06A5A1C,00004DBFC142BD30,7AA827273D3B8A7B,787A16D62B607C44,E665A85AFF7ABA32,B9364B525336B332,D6A62EAB905920D1,45CCE14832F4010B,0000883A77FDFFF5,4142DCA3928A4A62,DA4E2EE21E74B49D,633013A880E0D5FD,D91CB59D08CC87C5,CCEECB9E4E803949,71344553D368A3BF,00009CC43AA590F7,5FA3FA8AFF439E0F,394DA1D6180A2122,67CD7999C3BB471B,68242791557D277A,714DA1E9A4F05C9F,321E8042CD355FDE,00019D08DB358206,EA56F54AC8F85479,BC2AF91208DC777B,22C90E0C17B886D2,C5F3130D5DDA4072,ED0E9898AB14C320,AA4B9E0D3B180E76,0000A20358229C7E,9A2F18E90C4465D9,DAC556B82E3F10D1,E6212D4A38BB2FF6,C685B77D0F264AEE,977451B54C9C3307,1E1DEDE7095826B9,000185BBEF20E671,8B33F18F3D9D450B,933FE3D35630C5EA,3C1DFF17607E74EA,34EC7298B25CD893,2476743F7C4D4A34,055386B494DC2836,00006C888B585B71,C76729CF8AA91AD7,474278122646CC53,F85764440343B579,ED45D9500BDF6CA3,615793DF27BF0697,0CB7172597046422,000161388485AFD7,E1E45AFC1DD30FDA,1916C6056E7677A4,CBAA850A990C55BB,D1C5B526D130D541,6E5B90C94CB3540F,C66186B008A169A3,00007944977F131B,D6D3B1DCBF069F6C,B4765B9BE074D3E9,6A801F78E51F4A28,3067664A47CF6482,FFE2FC06F96DE35D,E5217236A8FCD0FA,0001E80B80934733,84A3579BE880ECA0,ADF1CE4F06101A16,BF6C5522FB222B0E,A342430F6BE305AB,2F2F587E11743AB0,1CAAC6DF305E5A54,00015FC5DE4A18A8,62AF18BAE07A07B9,72C6592BE816EA3C,6BDA2B59E42F856B,A2F7FD095CF814E5,76F25E0A2BFF7DD1,B9EE3B1D7B703E5D,0001A1B48B57849B,2CE60D186FD0AC7C,CEA925D7B244D83A,20769077DE0C3F92,2065F2AA3FE93F43,E838FF007ECFA122,3C9737CADA7D791A,0000253CFBB552B6,82C0F9C31390A9F4,F0C116BF708A5D43,7E5E51B1F83308A6,6B10DDE21D0B1DEC,90A55AE9E799C2E3,B74D396CE1E7AFDD,0000ED008691FCA7,48125513681552C3,AA3D3F2C4DB40B61,465A6B5CAAF6FC5A,ED8F6D4546DDBF95,60F7845B837827A2,640FB575EEB76C0A,0001192D6E1AB4E5,E0EE27D2209A5315,A9DCA754381C9826,DC0E3EE6759E505E,877C132781E79621,9B0DDF53E2AC875C,3D5FB8A6F09666AA,00006B11392FE977,A2CCF79B8031F000,67CA683AAA0711A7,EA0C7403DD459965,8ECE0CDA93808760,48E0A7643533E0C8,DF9869B6440E1CAE,00007712F1C170CD,39E2C576AE42A04E,24034777CF7B9CA2,D54CEEA8A3D34E1F,B52EA088A1EAE3F3,C04B5DEA0B859B74,DFB3861446DC1257,0000DE5DB86DB473,A86A7F47EFAFF330,698BE0E204A432E7,676DD31FFE6B70F1,6FB4BD7310A58018,52EC860639D70486,EC79B98BABF575B9,0000E92489310CE2,DEE774EA84704349,0A3E0B77EFAA19A1,802CD85745C42291,E23E33F34D553A9D,36835A2D1AABE316,65E5E987F842BF1D,00022E37BE81A581,A59D5DA0698881E9,C24D842F4E0B3029,49B89C013EE51793,0B8A46B8A9763347,2453F132B49F2971,D1A39C1EDB33F431,000052799FE9EC25,25959CFB559FA700,F3597F1C21B84E3C,7A62363F29FEA38A,6011D29C9D9B9C71,80C21CE48E203536,498D9B54350D074F,0000F496565D11C0,AAE27FDD1D407A0B,3B3ECE19A256E347,22D2D7CF2ED5E508,04F571FCE3B9CE58,80F03204FD99ED18,34EB005FBB998A5D,0000E9C999F57446,8529127343EB531D,62AE3D0BC252837D,DA14F4C42F8F585E,5D5A750C64B900E4,74FE09CEC1063D25,87A86039A37B65BC,0001D235472707D7,1632E7858A8E964B,19EA1DDF669B19B1,B3A73B30D631A75B,AFE7DE6CA49AA1B0,F191CCE7856E3D47,BBE240CE6E1D1904,0001D7F7F860A21B,7C21D2999A54D97F,99AFD7766F8A31C5,EC441495C03D0843,1BC8BDDF0454DEEE,35BE9BD58BFF99CA,31FFAD5ABA127B4D,000011349ECA10E9,672D79339AB53013,7A7172ED12930805,FA8EE509B74C57DB,46365C9DCB2F1F48,468964498457B498,DC5F5CEB4128E8D9,0001A731441B9A51,D44D5A91ABEEA091,2F79FE2CE32AE441,4B8743670FE0A66E,42AD0F33FDDB6C85,F979615D85328271,E47A96237756D2BD,000176CCEC79D01C,9A60F2EEE99D939D,4BA5E7F2EA52354D,1E79EFEA93FE7B53,F535E3C3FBF00320,FC8C7E118259BFEA,759343674FF00E1E,0000B68A7F2B2E5D,B6144253008D8C29,D98535C6A602F927,B0DE9EC1E52D52E2,01317C226E875B9D,4098254F616A300E,22F9E6119B5258CB,0000A4D02C6B6505,9E71D5742A64CB28,903DB1257BC0AA3D,1EC184C536F101BE,1E75513597DC5F81,16396383EC1E59BD,59D4EFC0CB912D55,00007C350DBF0480,C0B2C649835252C6,C52D7CEE6B8E92D9,EDEC50464C2AB813,19B3CC786009EA83,DBD426B71FD6619A,0E3FDED30689587D,0000A826D87BC5C5,B37EDA9DDC07F24C,75C3AD41DD3DF867,B8C052DAAA480652,BA98996B35AEB8D1,22DF9078D23821CE,2B0A97E06E0E96E0,000199B60FBF391D,94449CEE8331B212,49EF810F4313313D,694A3EDE95EBF6C8,C98985117881F2A7,66103ECE224DA13B,D6FAB3B839424E35,00022D96929B786E,19EDC4ED3255C0B9,56D8695F17ABA4AE,EFF7B6E1EEA81BC2,FE3086B503B14422,D9069614CE3CA30E,9F160B7CA7E5684F,0000C49F1B597BE8,B96E0B8EDC4B6A28,9BAB80B5C280BC63,2945B5632607CC68,722C40953A980509,4A559B503E3879F7,BD68F2D0BA7E852F,000088AA2F805FDE,A140A0816C7ECBE3,20E3A4A589BE1D09,E706E094EEF261D3,D9A62C971FBA4C5B,F6040DEB8FADCCAB,BCCF20EFED0E1686,000157EF100DE0BF,87F3F9203DC3B9C8,2991D157F1FDE040,23B8B0A5A1FFF8B8,F4286399A9007F23,2003F66E3C6AA0B3,190A3CE43C4BC4A5,0000449B9271B03B,07410E368530AFF5,8091660ED8712581,A807E1BC6DEE7934,54FB185F77E999A1,E937FF6152045DB7,6F0187D1D5E65B74,0001EB0E969FF693,B0D3C5630C9804B9,5A05466D2B993361,035BD595D91A4CA5,F8F1FA14BE7E2F07,FCCA11CB407A4AAF,38830E8CB4042AB0,0000BA265779A5FA,FB8D48DB73FC0FF4,5304CA271457BA99,AE817972A2E0C2C5,AE37A5F66642316F,E769E596BA229BF7,E4F06D051CDFFC53,00018375B2407860,E64CBA477ACC0CCA,18E152DF7D38D291,2D5D8E8DDE8DAE88,5B49CD033534511D,1F002C2104528355,60EE819BABD50695,00012B2B41FE778B,9E3A4C76EFAC439F,107064368057BC7D,9F0D71E412C5126C,1DEF747ED9FFFB63,9F1AFB675151FE4E,DE1A0DD5885B66AA,000022EA7A4DE4AB,1D6FB3AE2E41E41A,0580AB058CC14803,48D0384DB0E984F8,7277D040736BB7A3,53EB376A4B8E5429,554EF86EF64790BE,00008B18A3141C0A,5AF80429C0689025,119C3DC4A72197C4,538E9CC1041A4C53,5A500AF0E3A981ED,625362F3B7CE7B6E,E0EDBAD7F27B629D,0000D94E4FF59008,F695FF9A479F744D,10D55FCA2C649904,D137A4F83F9DF4DF,A279DB2AC6168176,AB7E2A0FF6CDDCD9,3CAADD3F5F322351,0001E44D2E00221E,7AC88F8539917087,491A327091C56C0B,89189C4B38E60A15,75EDF5B8613C76B7,8C6A1800DD16074E,E1FA4153EF8E4C43,00017BBC4F310598,4F4F549B35A66DB0,3653DE98110F0EE1,D49E6E02CFCC4D8B,0E56AAAABD6B581B,53BE59C498261579,B5EA1100608C2FB2,00016CA4E673C869,D84D8704FCB480FE,9B64B92F2D1BF7F2,D26B94C5FCA7C33C,03AAADBD636D4B82,9D5220ACAF89E49C,B4E5BA1F904B8095,0000AE84852C5017,8EC809D27DEFAEDF,461D21775ECBC5D4,12CA7E787E2EDE6D,90EFF9684DAB4E25,B90C392274E9AB29,1425A3A808B8ECE1,0001CF5984374297,6904284B38F5BC86,F70A7D2A5F2F48D5,31E4959684A15FFB,5BF38D54F86C81FA,3763589B26B3E938,2ED3DC7CA2176126,000215B0E175D639,0192959CADB19B3D,D9A11CD6E7628368,616DFA2E0DA3B3CA,1D073EECAB4A8601,0DB213B3AF1164DC,C16ADC36EBB796BB,000205BF9636A626,9D775EF102BBC369,E470F3AAB86522A2,885B64F57758E128,1D52399C991118F9,18CA489E918C3FD5,D012FC202CAFC571,00015A75F8A2F5D4,362D2D092ADF1796,DFF87A2C794B0B79,1ECC66D8CE838B6F,E6DFD41EE859B3A0,F83AE6978C045690,A4C5B7D2C3525630,00001AD9136EE225,5D9DB2DFA28F92EA,18308AC5934B114B,6D48AA774C984F0A,532661A203D7DF8C,1C955105EEF2A8E2,FB18D203E5A9A21B,000229F0C35EF2DB,74248ECEF0787DE5,E1DBF33B8AEB4A6A,CFDA6C96128F71B9,285BF087D99C3A20,EED4DA0A330677EE,EDF3C4448A8CB66B,0001D03DD41F3BF7,3814020371A311AB,34BA6E52B051F75D,E7C284F381D66B01,ADA8B350E330E2CB,B14B1AC8F4A49F33,905285124ACF4660,0001A39C9E9F0D42,8A5D461F51D410FD,0161FF383D641A7B,1C9C33F57572D37C,B948F55841C12B1F,40A2FB0014704925,59FAAC8F23817244,0001DD287BA4B1C5,9B32549D3A095CC9,A3A08315477C4C00,A19562FE54FECA71,50E9E27FE88C4A75,F7222B5E0AECD761,0BC89980A5E1A033,000123BE030F7DFC,362E94C7529FAA6F,D77D9CB61CB985A4,B94901E19DC00E21,66C80DDB6EA51890,4E01E821BA7B5380,967F8EF9DAD10E27,0001F455B51DF152,A967AB37B2FCDEDC,C0F923EDDA725A1A,3DD012F4308D7E2B,2FAA0EED6C1A2F6E,ED51ECB1F976A0EC,25CD50ED563DA012,0000037ECA63C62E,9557CF2A0182D35A,0035E93ED81E37C8,8D2FD9A62DF5CD6A,6A3E2C9FE04C421E,AC7D6CB2157138A2,6D654A1A8F21DD1E,00002C3A2B16C817,0F0C34530AAA253D,6B25DF79171E48F7,E648C0538B40976C,21A90AC1C167D712,F65A767A5C164EAE,8954693CE6FFFBCA,000073C15D9B04B1,F65CB817F5E25F9F,83A7F0B8A3455BEA,F5DF9A0912F0D27E,449720CA6B7FC5B9,4E42CA7E9A09ABF4,0BFDC467E292FCC5,0000E10DD4514DDC,1F936C05AE64FDAF,771F649DB906B806,BB5E0F902039B5F5,6BC48A767DB7BB1D,FA5397C63FC51918,285FCBB376AD11A1,00002AE2F498E0B8,3069D9C4D2EE210D,B690CC72FED150A9,9A21E690F2345866,90F15685A2DBDA7B,665474C05EBC4E8F,DC7D5A050A216AA8,0001A0F525F5D767,759918224AC02C9D,D70E0F1EB0F9151D,C8B6F7067082F7E6,C39D95D4235242BA,5653F0B8EAB5502A,07572FE460304EC8,0001154225097259,522A5C7EFA30DD87,0ABA16891052B960,40C0F4F9A6636904,E8AF88588D8DD2A3,FB6803BB55D265AC,CF25D64F00D2EAA9,0001D3C1DA174D04,636E220907161F22,32E3F9C72180FCAC,3545B7199C82CDEE,F0650FE4970DC8A3,02EC49CE5D3C357B,0718066BFF831AB3,0002061B75FAA401,BFF03EE7361121D8,59DBC99734DD902C,B182151924D90D91,EBBDB2435140F12D,EF407CF9B8D4C43F,F17B186E03A5AC5B,0001225049AC82B3,B4878CCD2809ACC2,678F9349E7A508EF,3AB8E34D0ACC371E,960C7407922B5012,3031599B3CF904BD,B117EAE396AAE175,0001E38FDDB8266A,DC28B93963FE39D6,9B6E04FE3DB45652,41848032E094BBD9,0F4307D888EE5575,BB13B33E3895BE68,E42DAA53FA174843,0000769F6A3A7BC6,6D40A11A340E5065,1630118AD9008CBC,F282E21B147A23F8,D3C93A0542D992C5,0E2EC5C294E3A51F,E1311AB037A70754,00022BE8B338AE1C,F66938231FA73E75,9BF5B31C8BA6A189,71DA51EFD2E8D4B6,B021DF5FCFF693E1,0FA28E2DE1F7DB51,8E00DC79768125D7,0001DEEE41BD01F9,7074D436747B830F,DE64F7AFA67CD117,3EFEBD961CF6E3A5,5F7D747429D12B36,060E18E85BA71567,3281FB10633D53FD,00019F223F3752E0,37C342ECFCFF64E1,E6300604EE362F7B,461632DE60B300FF,89CE55F48575A527,E84B04ECEBEF10C5,1221ED5CD7AA69DD,00004B0C4C506CBF,23C7B0EECF8D3D72,84922D4E524F3296,0DE30B87951848BF,91B795A6A828A272,3685AA11A188D018,E3206ADFB8E1427C,00013B89C5C61897,450337FC0AB0F4CC,DFF7F73FF77DCF10,92524CAAD831579A,8315FE028C41F4A4,510354706DD2B7D0,9D7C4A23D87987D1,00022FB286C20910,EF6390B94FD6B085,8B30ED976F205D4F,6854619F1B105A4E,C0A3CE1D7777E8FE,177EEC328337549A,6565E91EACFEFC5C,0000315BE8097C75,A8CF47EBFCBE7076,69D5525D933C3179,990DC0A3DD27F590,877A6857937EC03B,165A4C5F612464A0,6FC0BC7383476E75,00006B9907C8F3B3,EE0EC5246E6EF65E,11B4D581C1FBAB98,3219AC9DF646C502,39F7656519E62F50,D08CBE25B74417AC,303C81DB02145EC4,0001D77971DB765C,7A645B66D92F4F4B,B12A4B35B57ACE39,24009F3BEC091095,BE368912B3D2BB4E,11E85690CDFA7C18,FE156972F8F54F7A,0000C828B04934FF,2F6369EF1FDC9BB1,5F771CC03DDF3301,D1B8825869AABBF7,8B128DAB205449B6,41EF3036C1DBFDCB,2D280B2397456FDB,0001AB0E0A91F726,CFFD2A6DC574B6D0,3CE9DB24D6D9530C,705EDD4DE81BCC4A,E5A5128AA2B083F6,0367CA592B632FC3,9AFB68CB9641127D,00010E2B03381163,DC4E507DCC881AA0,CCDE20CA8E95A303,EE5610BE71C5A64F,46E65E1B9B697D9C,5BC064A4715634A2,BB4DA1B22EA298A1,00018717C66F0BB9,6BE590BBEE468A2F,3F181DBA786DF7AB,294CE54561F3A2BE,8ABCF3731EDB3DD6,BBF50FDDE107ECB6,8A47A2C3E9443DE3,0000813B8F44805D,97B8C954450B47D1,AFCF67EA300DF659,85A3788C1EF7FD19,59BA20D8EAA2E0CE,CC0201FF8E7180B3,6FFD63492F27E60B,00005C370EC52814,0E4FD3B06908F6D7,54091E78E735E804,E86A99B2CCE2909B,F3FD4D4FC0D348A2,D7823ADB3109A310,0CCE9B25FF1A3C2C,0001F2326B285DE2,C3499CCAD4E89B5B,AC7CB8CEB20E89C3,91ADFF004C4BF4CA,FE285DD1B5C2B6A2,4A89133505F76364,78B78F0B3C768524,0000F83A364279D2,EA63B3FDFE9D33F4,872EA68E0EA925CF,5CE358011DABAAC7,1E92440996EF177F,B6FBF89A8CFD311D,31C6094A80075456,00013ADF582C59EF,62AC735F4843725E,60E806AFC2277532,D5B5E16098BB34C5,EFF31EFACA354B98,0E8472334A26EF8E,66EC45A13FCD08F9,0001FC3643703721,5B554868AC16E9E8,74D1CC9EF2A099A5,F19FDAE47E3B8D09,ACC25BC705BB7FCE,05787A877AEB23DA,75C23759BCE15A74,000007EA4DBA27BD,DFF7B392D39F33ED,870219580BCF05DA,902EE41379786819,9AABF9B36DD44462,3E828A650DDEF8ED,7BA5A49F2AFEE17B,00008E1A85EA8ABB,605948ED70AE9733,5F1B075BCC808A0C,59ECA4E85FE96853,0172341378AE7D3A,3528328C45C243A6,2BE1B7DF077DA480,0001FDBC1A098E31,4A36A6A0C834DF20,235310F4CB633886,B18FC21EB4BDE26A,EB7E2D2766305C5B,5F40E5EEB4C8C52B,571A3D914CA7A4DB,000016E1D8418D43,842047B4827BB9CA,497D41C0626F6266,9F9753A7D8607DB9,0CCC11398C38C597,44F472B16C9586FB,125C8815644B6F49,000179CB20EB6388,0A9566FC1661BABC,0317D33E88D6BACD,7AC00489D9376EF9,7EFC2395E69D4F2E,63767F4AD2533F39,2862685238BC8E4C,00010A97327ABDBF,96737B41A0C46202,81E06D9D627A6DFF,645F3CFAA298151D,ED60D0DD73BAECF6,114AA1C2F4D9DAF3,D34667734DE51A17,0001E33B3A3690DC,B3B08E1B106F5929,09EB169F5156DB2D,E9DE4F848A824E7A,479E7D94F65BD127,4131D72C172666FD,21A039F7D9157F68,000143E9E6908D24,8E544970B83263B9,4C366B3FD57E6841,7311FFF758ED3320,250F978E0515F323,450721BBCB85F951,869CB29D078261C7,0001EC0832BE4758,5B98E7800A54649C,1EA63DDEDA211414,31EACDEC69E0DC9E,77124367741C90F2,6A80D5514086EE3A,A8A262BD1C5E6B4D,0001087615BA147F,A8BB1A9EE179C59B,3A9912B7E8B26B68,5E402CFB58F822E4,D7FF5022D01D7F59,4828B15F7AC1FFC9,0A455E02742522A1,000188A0E0853CB9,F81C1A3164B6A782,7405459C7257177C,90A6DC2C6BE8D418,8FF78B51B5AF0D73,34782B8093DD325E,05F4927281C2E686,0000C1B824AF25D4,5D9063DEE1DC9F4D,A9BE7236F1CD08C8,8E9EEAC6B27E56F7,24AE139AE3AFAF5C,ABA13FD9D707371C,0EB70D4AF77EDA41,0001C9C0F2A3C1D9,E7F8878B8BCD743F,9E95A98EFAB502ED,623682DB329FA4D3,176F9BD771CC9C86,883FB7C6691CDA16,E8EE67C5753DAE2B,0001F111D8A8A4BE,793615D2FAC952EB,4413D8D0954D81F6,F3696ADBF6E8F2D9,7C73D70EFE052E12,29C6807FB0715D0D,AF4AE2B28B4F3C56,0000AC8AF275EF91,C03FE0195837581D,39D30E5D32F25ED3,991EF82ED299EDF1,3CFEF47C9AF0DF7C,28ADB1B873249A2C,3DC1BD7D842CBFA6,0000E898A12B3B1D,1EB7749D1AF616B2,AF3CC3A2EAF0F4E7,E0C8FDED9A3A9D16,4B8F29970D097145,E66430C965F17DFD,9DE76F5E09859D47,00009984AB86DD8C,71874E5CFD40BC64,7726B0B6BC73AF4E,8661A5DC8E6F0ACA,CFEE13531CEEA7D8,1B7509F8B48C52C8,05A60AA1F59E949C,0000EA9A63F16276,DE29F7B2960E697A,E1A3B58A122939C4,794D01B5665CEFDC,7C71B71B3A40F4F2,D82A58B236ADE5BD,6770D5586919D4C0,00018B7A1A3E5743,A85060E93BCEB0A9,BC69BBC35A834A2E,4BFA934248B1976C,0682B82F974665CF,CC0ACF02BCF7F318,8144DCF8E900B9B8,0000651BD869C12B,59AB779566BC2B33,D1AFC28C7E69E0DC,F5B02DDF72CDC01C,F9C758B29DEC45D8,AC6684CB544ED53E,6D6411F5F6074F82,0001E2D858D2157E,854969B5D9043FCF,2B5129D542997F24,3D4433E1E98B2A8A,6DE1D227FC16A120,835011739662FF76,7B1805A96E6511E7,0001FD3BDCEFA997,ECD42D7F6C555DCD,222D01A494E6A427,A2EF53BD54F768FC,94A31BC154B4AAA3,472B718F9CF73443,82338697BE6FBCFF,0000AEC6AC98C171,9A7ACA36F2043BA0,5BD5BFEC1720CFCF,E31408B39F792CCE,9A79CF0DF1743A2E,D62C60D3A3312E0B,8F446A4B363A13B4,0000658C8ED4ACE0,D15F28A1590785F1,6D8D6CC174A87F30,EDF9D1FFD0BB7FC9,B26E98BBC22C1AD1,20B3203F98737143,B9538A4A6DE6B1DD,0000531BE9468920,FD4143A756EA0DA9,204811FC10E85A96,3169BCF8CF159661,0AC381D4930FA583,B437E4C85FEA3356,E80B956F1DB40536,000075810E8979CA,8F4C2F25965952E4,70BA11E6034C1BDE,2EBC4517F632A844,BF3B88ED2854E5E9,790763B51D8621AC,35E54BB723B7CF16,000035EC094C83E1,6BEAA2FA535CA705,7016D52330E23200,C5072A3D2515AD12,B3D78FAA47BBDD6D,126EF52960464E95,2A670D22EFD57425,00004944203F47A0,95F80F93A3A1927E,A1C6F9471B527B22,3FB74090E0D6F5F4,79174061F32ED0E4,8FFD913302A651FA,CC46E8FB2BFAF6D1,00003036F143A2F4,A56FF732457F3200,C974366CC6B5408E,A44C918937F41FFC,AA0007B4CF49268D,39D6083336FA79A5,128CF71EFB350271,000023F293271370,46682D9A274FD6B6,C61F85AF61A2BAED,C4DB5D8C2196215D,267D40B73C29A140,1018AA1CFF39B61D,F25A0C8562790F8D,000190823D0A2828,C2BA191628338657,3738F1F50ED4AA11,29C34443992335F3,9C2B639C6B50EB4B,6395B363C6999128,A38D4681A73ECAD1,00015680E65FE66A,84731D13AE51036E,58A0BF0B27C175B7,EB78874D84D68DA4,D9BC39C43D336E65,D6604D032DE0A15C,F4EE09B253B2E11F,0001CA318555314E,F1007BF48BE90380,56D65328691CB595,E07C82F7D0508132,331593B4E4CB1927,D54821F474464C93,17C790839B821D81,000102D39F862322,60BB8CEEB7FECC3E,0494659C6C55FF5F,C3BE37C3A2D52940,11018E988CBA9419,47C583318D67D834,A3CF414AD4BB65A2,000062CC7F366E8E,1B43554776B1A756,99E2BA42AA975504,A5DA59B1FABC2336,3DC65701443A07D3,88DC6516C02F5D8B,71F24DF8D279B7EE,0001983F7BE4EEB7,8227568A0858145C,909355E4005FA103,5514826DB333DDBE,859DD25BBB000CE6,718F39B5DF7129DF,C0484675C8D446D0,000046424620E185,5E4B7250067BA1AD,80510C98D979F231,52F3A22846636118,1CD594B3F6253BA2,33C11EF7B1EE0806,152A6B952FCA9828,000024E8E8D5CCBD,B4B5D532118EB568,32513F142A72969C,A8A5E828A03E5E8B,D8EE164AFEE6E824,423CC3C275F5FF27,A7F4681BE105234D,0002156F4D3D5FD6,F29A5AF407CA643D,65B69CC8E39CCA29,F54C4073B6347BA9,DD32E9262E0EC27A,F6DD32048BB09570,A427FF47E4D9BFC6,0001FA1D8E1FF077,BA7A79188AE4D569,1AE7BA77689913F3,956E9EBB4ED49B26,20715A7147211161,CDF26B7BCD391846,220AAB06D7249CC2,00019D0AE25EDC3A,B53F9231358093EB,C8A2059BC832948A,70EB945E668B4E5E,2130B9CEE5F5B4A8,4098283A3886CE52,EC75832EB81DF31A,00019C2932CF9665,73C97AB84F910459,1E250BED1544A9F1,86F3901DB01FC6FC,1308A0338A9CCDE9,587798199A9C707D,378BFB802C5E3FCE,00011C2746F3D8CB,A066AAE1B6EEBA5D,6F87F54766A736A7,83B81A66C337DF37,0DEB188DF813CFA3,E49836A91387446D,ED1544CFE901D070,0000AE951A8F8A36,8203758774825622,4F7E2B6A30961721,FBA0D007B3FC409A,8C5917C69AD7BF52,D8687128F578FDB7,E177E9DBC07DD8E0,0000E388D71054DD,0D176BA13600721C,F592D0356FEE172F,D5300254554A5B7E,315202E8EFED9268,00CA15E3678BEAC6,52515B6335C4A4B7,00004FA6C6F3BA04,115C9D361BF117B1,1D7BD6464439D1F2,77D6AC6E79FC2AC0,D0A5FF9C84FA1BC0,214DB6A6316EE78E,57F5427BAE32C85E,00013AC8F216139A,D57BF188574C271D,8A58ECCE86954E16,1E1CE1A1D71BD08A,C86ADB08AAB397D8,61BCB17484203D31,0F804616A13ACE40,000186CF228E0131,F80FAFBCB76AA2DE,E7F7C98FF865A131,83505E2CA9F2BB70,23418BBE693ED4E3,F4A9592571F9A77B,BA9FA390C971C4D5,0000A3A3D4B066CB,FFFB68C624227BCF,E2C0802976241108,AEAAC6AD4103B324,2939B51B2C539DDC,811A7892500F8A47,14933C27F81F3561,0000666A6CF008D3,E68F5B06447E91CF,9F6B11C78FD3049E,367B53F41740E672,8CCF55877AF175D7,EC2C1BED7B8F7C55,CB0F7F2004C690CC,0001708AB473784F,00434C348407E1B1,17F982F29B374461,9CE643E87758F374,7034655A92AE0AD9,E9E284981E1D0385,E8AA02601341BC89,00019839EF6E8B92,6105267BCA4949D3,E7036CFCA93057AF,4B84016D7925B688,72C27105B3B21A74,29106AF3EF162CAC,8E95ED8D2BEADAC3,000012E9DA42A386,94F8AB626F1CE444,9E792F7098910D00,D7F6151DF41BC3A0,A06D1C9800CFB3BE,7A26844E58F5ED18,E9F269FF50915786,000137D00291736F,7D2713F2E6C99A3D,4CE924CF7771D829,E70C1C8FF724FFC9,56D0EAC17F0DC4F8,267DA061A8A7C66D,88C82B97941D12AE,000004FB7E7F274C,E23C014F831AA9BB,FD15833C64C14C7A,9F95BC0AC4FA5449,57AB5415FA16D98A,637B0D6373E3968A,411BC083E618FA7A,000230F2AB44A0FB,8FAB1585309D6B52,47339A775539DC63,5A22C8F866452434,5EAEAA09DA41B741,1B93B06CBD7DBF58,DB3A96D1C9893DAE,000189C86C8D3DE4,9959846F1963170C,9398AA6217AA78C0,1C4B1ECC194C05E6,5414F59DE2ABA272,F6B498C47FB983B8,E3805C5C6908C7FA,0000040DC3AA1B8E,5508A8252C222557,26762A40E6FD936A,65013CF6CFE3563A,F727FBCEE1C58A1D,FF7D60E2A740FEDC,249ABBAFDEAE1D3A,00011378F4E241A7,C02D49776099FF0A,FCCD8050A8438111,785B12463946101E,55EA9AE9FF92B043,2B439F5BC9EC2725,DAFF98F469F1BFCB,00005003127264F4,E183582101EBBB23,2881C3AAA5DE4CD0,DD1C8D37792DB791,D39CA65EB3E81FFF,FBC699ACFCD0021B,3CAAC73D5E61D809,00005F8418B75108,7F42E9A63CF40042,D6B3B39D3F4EF219,5C2210D82887192F,FDA48ADAFB61FEA7,0B6106075E04EE4D,1BCABB6C386D89AF,0000BB7F2B2AC8C3,B82CD9CEE9832E5E,ADE60E68D3B1949F,DB505AB6B242D984,BDA49D81FE6DDB90,97C2496665534002,AABBB23985B493CD,0000DC4F002D4C02,740B8F1EF5127D9A,978B03BC24BB4B7E,33BD7DD994A493B3,4B79796C19C16FB8,DEB9F45D7E4E346E,7DFF90D81A66DA9E,0001AFBEF8CE7D5D,AD026A33324A943E,2BC220A266C13424,FA5776DC4E5A9E18,A0ECF352F83B7BA5,2AFEB5187F0D130F,C5E5C8135EFB9961,00022C8F4FDE7A89,B264378FF6CFAB1B,A61FFDAFC83EDE9F,B5DB5567517A2351,963E19F49A7E37DE,E9B32D20060B7858,D0B450F5C77FBD66,00020792622A6CC2,D2BF0B5E32F32FBB,826A67D9E0D60CA6,FB2DE1747774E1E0,E4818B8686A80465,F73F66C75ABBA2C9,43541D85B627104B,00002C7391C10F82,0E6C702B47BBD2D2,A773F5CE85AA863C,5766CA9D411AEC12,E7CE16512E411F2A,207C49A98CE12DEA,1EFA8E39CF823A99,000188C4DBB08167,4A0F94F70DC644E8,366F9F1324DF36A5,AAF0E05AAC6AC933,6AE03F74CBDDEDF6,3DE137A07A188AE4,28963CD9C7F9F703,0001E6688C0F839F,D79FFEF1CEFBFEEA,02DD52CE360ACA1B,318CA66326310FED,101477C78D1FB4F9,5C413BA0EE56B675,9D6282F725380CEA,0001F5DD40D7B906,4213B2D770896273,874A70C0C6B0CB9F,F55BF85529C6F11B,D2110FE090EC7340,B60A57A135BD0527,5A018FB67E172F8D,0001695EF859B413,0C59B0E46400A4A8,1D5D5071CF30FA21,9D526DADA5221033,A22F2B162A87C7C0,1B6E9F5DD8AB6C27,007F6626820177DF,00007C75FF63CCF8,CB5BFB75F4DF5576,4E8B18ECD7FD9189,404E90C11428887C,6105ABF5D896C6F8,3716AD9F675A4E7F,A02D4627AEA9D88F,00008B574EC0BCB2,CC5FEA04140B5B74,31224735768F8171,81592F5798DAB4F2,F1FDC8B8E35896A7,89B41540257CE18E,686BFE76C13CC083,000024AB82ADDC40,9BAB226D6D382EBD,4FAF855BD76AADE1,0F3454162A9B422E,279F99DED594FA15,A54CE3F7F823B7EE,FCFC38B15D346564,0001A45371710B38,AEC615B302FE5F7C,404EB077E67A449E,687D35740326A30F,09718160F57F795B,B0A3455146837F73,9291CEC168D21110,0000C27F4F1BBC49,DAA69AD8A983F3BA,EDAE9924018C69DC,745CF351722B9C23,145428103689A804,599DACAF6CE32AD2,BEBB508E2C3398CE,000044EBF53E2926,0AC3AB9B8079F462,98CCF01A382FCE4F,B119D4A011DD8863,367DA5B240E9248D,6B2AA47959F33EEA,AB29E4148D4A97A4,00002C9D2FD06C11,C6C6DF7625B486D9,188EC5593EB4EBBB,FA69010AEB189274,12E48E3AAA2EC07C,215D4B7C82DE7AAA,DAEA4500B359DB0F,0001C6530943FCCF,B44B6142E857F965,9AE1C9DC23873666,5F2E3B442A6141CD,B86D7CC66E61C961,3A4981625A272C8C,66C79037C9CC9492,00009A2ECEA79D3E,64DC4DF711EE7C78,8B447D4C9F89A961,0C137BCEB8AF7883,1CC0A38E8ACA0A62,94A0F6435CCEF62A,47C8C28BE1719F7C,0001F0DF6D23349D,7C83A4E17A9D3DEA,90FA72AA8D743BB3,6F7DB18B58E4177A,E0B53EC9EDE6FA35,EEFD9AF2EF71B9CD,E3C94E9FDE0D857F,000022A54A8FFF18,9B010783327CE306,0B62CCF8F2B52299,EF76A0D6623DEB11,DB766CE04660734E,4DB29C4F101A8C0D,62807B70DC71720F,0001C0FA751F839F,E4144B03D6D8FA64,7553F3EB0438B831,1AB4D02D8A73B585,9824C3D193392793,78F648FA63B8365F,95AAD23D7B867E27,00010AFC0EBD7357,9BA768CD1AC09804,18FFD55629F52B8C,A7A62773CD581154,3F3167E1E55A9F85,2EE302C9F43A78A9,47AE1F7B8653768D,000147D645010659,6494F545DD9F52E0,F4F0AB4AD57B9F00,0256E578A97A19D6,833FAEAE49D21BA9,05A498A4924C854B,C5CB8097C18DD315,00011AD5EFA30D3D,C9ABF6CFBFD6E2CD,18EA90DBE76F94DD,9653FB785CA397E4,0C819FD71B825132,8A06A0020B6596AB,E0B57BEDDA6FA380,0002195E1B74E454,6996982BBF3E7040,D3346A4B151ED516,E8119292316AB522,126134E25160B5E8,30EE11B7EF9F6342,666979735B716171,00008305DFABB392,382189321539ED90,7729C0DCE468EA3B,1DF63785CE963DDC,EC583AD4D9AC1350,E5D16F13D2E59BCB,8191ADE3AC7A5FC5,0001CB550A33F31B,4A755D8BB45C5FF6,822D8AFF95CA68DF,E48971E69C478230,D96E91BDB60458E2,215C8C437F7578BA,B4E4DCCAACA4C94F,0000F6F29D42C994,4F18D12F79A21421,53B0C6A7BE513DBB,34DF9572DB3B3F3B,59BB9651C29EB419,849804DAC89BADCE,311A32F0F269C690,00012F7B7CD9DC75,97037D9C7A3EC830,3965A83B6D0BA68B,5E175D365657C220,D89B5F85AAAEA988,B319DBA936B5F5BA,FF210DE378FA4D9F,0001B883A053396F,8335BEA34CACA3FD,C5FDD27B58908033,ACBEB6A75E1CCD98,97B50A6FECBA7835,538CA5A3F66AEC9D,D6BF5A45949F1433,0001B88424668D36,61FC28D3D21E25D5,CC4370C338AAC013,44FBCBCAE1DA6CD5,635857C9FD19EA74,FAC2C0E752A32772,CBC015691A6F15DA,00004EEA665BCD80,DC4DDE7552ED05AE,7851BC9BE26567D3,71A19C71404D2ADA,1B52052B7F3E4801,B31BF0D066572F63,B8D72BA40F250857,00005E880BA4FC05,2E1976B29CCBDF2C,AD29D8D32FF67E65,C92E70901E9B38D7,550CA614F8DD10A0,2DFACA6E532511E4,B5F010ADC60B5771,0000353A87454B19,9F4D0B47D8A9C907,BCA30585BF93787C,23F4CD32E757426F,DF5984BC16809B26,D362A38C0A9F0C44,10BB9FF1E4894EE5,000060D0BAD91B40,18A83A075D7F8D14,5D8676AB9882F620,86D7D12C63CB628A,FA86DC8583A52F1D,CBCFC75C0272B69D,6F1009D0D727EF01,0000074F44B66F24,96D170C4B97BB527,CCF0BA3E5E157593,7AB59B7CF8CBAF5C,42EA523A118372FE,B56ABD84A0A95A02,CBA17098C1599AA1,000163A33A12A503,4E6E59A6C062E5D3,831121A802307849,AA976A3E909E3548,58AD24A27EC857B5,73B3C27AA9EB584D,0EAB1E71F28DF9BD,00015C2EBDF45A36,C2DE99738F365662,1F52CF7182F18355,22941743A376B968,52B262976142BD4D,62A8B6F7AC4E7A06,15F855DD044DB719,000061A50DE703BF,B457C8E1B25CDBD9,E9E71F7654A947A0,979A7D8A61CB5A36,47E74919F2ADFEE1,98A517D1231ADDA2,7B99E5523D2F2CF7,0001BA0DBC6372A0,B2EAA222D0CDF2F9,56EC787DF9208E95,5B04F061F9AA248F,7489FFB65CD35FCA,9BE960511AA8623C,10F2A5526150436C,0000FB6712F459D5,130A05DA3864A202,DEF0334EC5782B6F,29AE1F98FAB58E2F,A531F287E9C3CE1B,41DADC9BDBE2460B,136B77D16D7A10C0,00009D9C209E0EEF,AF2991E3548C1679,2F106C0E6C8C5CA4,F0771A68C3E382E3,56D7E244BF875810,A23671B9D6019A9E,23330E73232D9D7D,00005ABA0F317FAA,06E0C5DD38487564,F1FB5C89079AD9B2,2BE2BD20C727FBD9,71EE657CFA8D3672,418394CBA3AAAE42,926602DA18887E2E,0000482858A3E5D9,E579FBC8175DE3B5,6B41688B74A0C72B,BDB8BDC82751E4FE,A94A69329CA493AF,B972EC696532D766,2235C833A7E42335,0001676D8DA206BC,097E810D48F3B854,E2AF852E9E62AC06,4299B230D2216FB4,678B0FD9B3B452F5,B0C2AE75BEB93757,9B7D0A08023947BC,0000A47571D58DC8,6480A85793D2FDFE,E856F4C6E3DFB5D3,03660926E7E536D9,F0A7F12DFA53CD5D,6AC12B4E9B5328AC,7599E3FF0EE8C4DD,000005E592483AD9,C6351390F81C92F5,EC1DD07792F1CB15,F87759D3773F1A16,2E3F8E840CEA2B8A,CA011CFA5D879900,E0869E2A719CF0F2,0000C530E23CB115,09D8F51EEC199A7A,A0AC1731B4A37881,CD0E3B6A680B0186,F1BF9742EE7E49B7,63789A68CC7A1F34,4001D8DE89218271,00008509507572D7,724429B17EE0ADA5,7AB946C70ADD9B44,3CA60C5D57891E25,9D7A4781D03AEB19,146A971F156CDF82,1FB16DACD7B275BE,000169CDD78501B5,143F3E5CF35C8B9D,0DF9CA631220C73D,C6C4BF8E883FDEDF,2C6F369E169A024E,ED8E8DEFB9C4F04A,0AA27197B1C91EA6,00008096D5558751,75D3B281BF3E1DD6,0673C751E112D7ED,A865A25FDACC4187,E3E78B8ADCF9CF67,E6C299E634D4B706,BA53FB0B5D56A308,0000F214DB5C33E7,E707C9A1C2F3924E,9B89253092DDE7BF,6CCD7EEF7A508714,604978E1817B900D,9BD9AE9B3C5F8EA5,C3F3AE57AA18663F,0001E879BC333E46,782CE999EFE648C6,D529E0330F02AC2B,9AB3FECFE42D7A5A,907DCB7364AFBED0,7C40EB27CC7400B4,081C351F448C0F40,00008E189F3223A8,50EECFEE79AB8AE8,6BC779A61D6937DA,9338C2BCB7169844,881988BF2110CC95,5C0ED2AFC09AD8E2,33C34577C274B1E7,00007AB939877999,E985D04BB8A9DBD4,FFD4BDDABB6CF54E,C1A5A79E96D11BA8,AA3539C800029A4F,6EC37A3B78DD24E9,709F44AC2856D8B1,0001D235CEABF796,FAB2C0E8E123F5D2,3513214B8F878534,5E52FEBDABCE0524,7BD53279FC69ECE7,1FBA6E6F3A4786F7,B9A947B17A44F5A0,0001B9A74703F84F,1A8E583F6D917A1E,7ED7E4ABBDD7B6C7,C9D6DDF1378A74DE,777D39D60CDDF648,ED33A55774FA6DCE,8A145B05FEE0EDB8,0002230B4DD54CC5,363946D14D6378C9,9E756B6B302FF5FF,1D2701D0E6C52D7C,FA81E2F6F4F769C4,E00F377B0FBD30D0,D8B96B8204F52095,00015F4A6D3BAF19,818621955A87CF64,3D6326374C04D370,5A6114A68474A643,EAEF51A4B5F59D80,2F1ADC2BCBA6C64D,A3ED95FE50EFD8B7,00014C3D2D51DFF0,3F5112A99AD16B66,6FB2ADC67F9FD56D,3729980D330801D2,C43EB65C43D47BB8,A67629FCA97A219C,1C5C0C8E662C0513,0001A14464B08A57,61ACE6D5A07426AA,40A679B39A21CA1F,D86A7B4F7D35D437,12DAD0D93A1DCD2B,2D5311471795F71C,1771AD547D87319C,000023C0FF3B6919,80BA6DAD31971A72,A05D022B43669829,EEA75D41E2D646A9,3B0CE2F99E849A1A,7A33610F9FC9E9F4,7E51C5F84F4688B7,0001B8DB44B21187,4B9B0CBD481FF1B3,E0DD2D9CBA56BFAE,F15E8C670C9F91E8,38641EFD71885220,0A25567B30DF7439,16E2454B1C77D3C3,00009A153AEB621F,8A82DA4800124DD8,1CA83D905856642F,20C75638AE1B5CA0,4B7CEB12BCB648C7,F2B1ACBE7B7CCE14,B58A415AB78FDD40,00011396FA01AD6E,8A1E538B4B892B4A,24D2AF7D7FDA7A95,88995655318033B7,73A352C8CEAB0309,7B2CF83E56B80D11,0D2E085B28D1351B,000168AA9733B362,858F72C006A7382E,ABF15814D0857364,0CFF5D662770A9B2,763BA22739D2D0DB,125DC52905533405,428145F7E64EA677,0001C91EB51EE451,7B60C14B9F4574AC,B9AC076B234F283C,A13424703CF04C43,B4AF189DDFFC93DD,3D99784D72339DAA,D209EF3A7DA511CE,000095CD0FB92418,1A91085B2D343884,EECA6C44D8859F76,5C1C4E095C9313C7,8B3998A6E9158158,45D8A49ABF2C2FCA,0BAF90F2C8A25D24,00006140AFEEDA78,8EEA1498C00C8B0B,BA1BCBCB0D745EE6,61CCAFFB42C228AC,7428A4954F83C51E,6600FE698CA87C1F,B33A27A9E5624D88,0002272AED872DA1,225534232E23E39A,FADF3E02297C021C,ADE10EB06AFAEC10,51917061A5B0291E,1B60E4A8A068FF56,9EBF504880B68FD3,00011556C0CFCB6E,702875CCEEF0B905,EEB01A58864AFD0B,89FAE895B1A564C5,D5AA56A32D9CC82F,9420AF92C73B8551,1BDBA046B8335C8F,0000AC3A8C883143,16D50E2D2AEAECD2,89244137B2EDFB37,046EC7153F0221C4,B077CFE0BCFB8B4F,C45758B382C238F2,A923A6398585B728,000199DD9E7F1A95,CDD835A6CBF8C138,FAF8277ACA9ACBF8,F60B956DEE85C2BA,849587D6A9D41B3E,9D71F8805E9CB2E5,33AAB8E5CF30E94E,00018461054DF1EE,414D60DAAE080557,AB602BA5BBB85C35,67E96232D44AAC85,29B6F161251810EF,BB1319CE967DEED4,1C5920E20D076F75,000056AE1B8F3B8A,2C8530846D29E26A,8566ACF863010FDA,427A16DF5072870A,EA1778069BBD0515,EC599D25FCAEF7E6,B083575FEB162820,0001B3EE01B25F30,0ACDF880219317F1,A046CDB63C2A306A,C41DBD3E2046DD51,F80D39D3E8CBF2CE,6EFE3A35B9DFE77A,FCC4D9B881C5EEAD,00016091FCCC8026,BE290E41E62D90BF,BE5DE1FE0D6A8612,373E775C6F3AADE1,73EAA33BD9FF3892,B8DFB2E2FEA218EB,DB4514F87D8492CB,0001D90FA6797A73,D1C138F0592172F2,912214762B444141,9E55CCF49DA459DE,B84F5049992F0BCB,69C818F3D3D6F5E9,88F6BA48DE85FDF9,0001F9C2D3A389D3,B67D4C541B18A3BB,0C017BCCC27BE74C,A6C066E1769FD77B,7306971F4BBF263C,BE189075296352BB,10647488D5FFFF96,0001397CB21EAC56,1569DEDD3E7EE7EB,55DBDEC2C1BB57F8,1039B057DC902B49,64C005E7AB1B91EA,FAE0473E55FE069C,BC82E6015D6850FB,0000D28BB1BE02CA,42B1D6A1564F8FA9,EAF18DA43BD7C5AD,B9520480F9892140,FED10EA45324E22F,DCA6890CBE8C50F3,51E122840C5B5A3D,000128A97DA0699D,35B5C26E129895A2,609ADCE35BB5D964,79AFBCFA000D61F3,110D130C1C2CEC4F,A8B9AD9B25BB8582,975AA2259181226C,000188FDC2891825,09D038A2FD365EA7,27174C13CDB13E01,6A53E7B0676312D3,D0ADEA18B8652509,9C5DC51A92C3CC78,4028B738D89195AA,0001E2D07EDC8856,24C058B0B20D2B01,F6667E33A9DACF66,C9D2E0FDDFD2B6F6,8D51A5AF66F30729,12ACA8057500210D,58BB04C819EFEA09,00022A32274607BE,CC7420BD239A4177,7C16B7798777ADD1,3A8F9B2E73196AF6,4B50535928F6B307,22D2F4D07EE33129,5D8AAE557097447F,000143263D49804A,C9FD811F83C4157A,75CE40D30EA5A0B4,818C4DC6719A1F50,DFBF320428ADBF7A,D62120419B964B51,62DE6DF2DC57BA9F,0002083BEF123FEC,70E2C3232651CB03,D07254940EF01EB9,E4F8A760DF4C13F8,C2E8C8AD08F3F742,02759560DD65EB04,A47291DE953A5365,0002335F4C56248F,3B6B205488D04816,80C0C1267D3D87AC,D968E703B1544C11,8B06DDE88599BA25,61C3099664ABE30C,291724701AB44A72,00020558D401628F,DE699BE955F22920,CA5DE9D1C1EFA744,3A6957C98B4584C2,5DAD891530B33BD7,F403828D8B5BF4C5,66A16F12A7FB7222,0000A855B8BBAE93,AD51FF9880290402,2A1591D8D379CA63,28B1B15CFEC0C2FC,C22F96FD140DBC92,1FC58A9DEF6E0F6D,0240F245DC169263,000173095E1D571E,23ECB1B603BE6159,FA54285384FBEC32,733029EF35214B66,A70801A2D0CFFE47,81472394C5ECE6A8,7BC5857D456F8A9C,000201FCC4FD65E1,339FC9D810AC7869,A32514E5B0F23926,E5E044938A949806,7A8BD118802F86D8,9F79BA0D055F2EE0,83BE09AC98DF2699,0001C6AC6401FA52,394F18584448AE5B,656C6B44AE1C6A8A,14D1235203C4C32E,E33216AC812E317C,6FCA7DDB67F7CBA9,1688B277A6D6342B,0002057AD6F0086E,94DE41E18A75B5F3,2A1F62617624A75F,8EACC864D1F91FBC,0DE46D04CC56B9FB,1CA20DA62B67548F,2EDECD07060CEE5E,000044142852E109,CC9AC5871778E576,B4F26D5D958C93AC,B52306D4FC20C0D7,6557D90957B5F5D0,D5E500396A138CE7,35C437E372B91664,0001237DC0AED071,0D9B085F8C761810,0FF74571B3D8BD98,622B0D54234B8650,A5F44CD96166A8B2,4BC9A1CD6A347BB3,864E3C4A2E1E47ED,00015866A3D8F43B,3F11B15EF526FC61,65D777525504AD4B,6794A16F21B8FFC9,24029D0C27960FD5,E760CF9C591E2399,B09CE68BED16E80F,0000EBA5A4CCC4F2,83B4B85D92A8B8FF,93129C0A525A302F,E94109E5553BF451,A48F5E4EA8C81AFD,653F5212109ACE0A,77EFC0BFB8E64D3B,000066ACF6AF79C2,2D90BCF3D282EB22,549100378A0950D9,2A19FD65540EE6E1,859531241223B9F7,14567C0BD6F34F6D,3054648ECD98CF0B,0000990975E441E5,8C1C8B00CCC457A9,AD8F2E25C4A399FD,9989E69915A8CC49,0BB88CE74E04BD54,7C52E41E0AF4F842,04820AB3511C2E04,0001895273927A51,3E36F77E055C7575,CF936EE4AF5BE521,04F1F7DD21C3B31B,F191B5EAFA68E5EF,973CF81B22672897,7A9775228B98C103,0000D9F915B02A66,473B3ED8065C461E,87D9E0B8A2DBD529,4007C4D96D28238A,4A96F0256F0C36C5,39002A0B01341E53,9FF266DE2FE933E1,0001C8A9D3E11657,7FB5A9CEB6F66410,21F218C4CB28F3FA,F66569908D4E9FBA,2991A27C7FD723BE,84A6B00AEBC7EE25,507848C0C5BC1E88,0000582009200C04,37FC1B32CB7E5641,37D4F6A6FFB6F908,1167FC1900FAE339,A2F03C0B6F4F3ACC,0AEC8F539145958F,6246AA87AE62412E,0000362C927CC6DC,2A50F2FAC4D337E9,5898E59CB59BCBB5,6CE850664DA30DA0,CF4BDE084E896112,A817FF67C01C783D,6977A12AB2DB802B,0001C4DED08589F1,F8283D3B3B5EB4FB,14967EEB41EE03E5,8365C582FDA31406,EABA86981B63A18A,75B64EF235F1CD4C,2E6649A3E87D0BDB,000160AE858E0403,3DDDEAF0F17ED7D8,4AE0BBF241C0FC51,196DDB45AA759E2C,7321BE24C158AD39,5EFEE44F331844EE,3454D69EFF7E0EDD,000136E5D7C3EB5E,58A98BBB7A5B795A,22FB40FB26A6F61F,F48D45C3BA444776,5E03223E5A6C0C03,E391110C153015F7,0B6D8D9085362D91,00007208A96C6DDC,7242F9A564B2BB4F,51999A28878770F4,BA361A45899FC0C8,1F24E44FEE1DEA9F,92CE2393D0DE98C7,11F266E38D9143C7,0000CAED1235BAFE,AC2B822965F302A9,92B37B69540F0F2D,A69A84879B609CA8,10D9E8DA54521E70,0E9D29398E65AADF,3CC0CF3BD15E9C65,000156C90B84C0B0,061EED6E5E6561DE,A79204F845E1651A,EEF3BEC6D70F94CE,5D6268BBA5EE267B,A7695EC4BD12A22E,A7167613C2292A84,0001C26DEE95725B,09D47CEDC259FEA9,E559950058222BA7,EE7C8D799FC30565,BF1B31ED2150976C,C3C0D36A2E7B9C8F,F646FD9AEB4AC642,000231CDD6DA9D55,435B4F62815EA550,0B2E19F1EC294E5A,5079EB8F48277CFF,35586D4C1C16A0A1,B45572370522DD62,3E0719BD8FAEECD8,00022FA4C88B04EC,E2BB123452773602,D52C81BF8AF3A11C,47BC1F6BB27AC809,4EDC31D06B735B8B,944E729760758185,2938B55DF8295769,0001D8BDADD74FC2,0B1E14A501F6952E,CD75C88CE874775E,780917C94E6058A3,D40FFA50B5A6101D,5059D705C8C8C5C0,226B02F976ADA79D,0001FB70C3430E3B,140E4D3A79CBA805,FB4A1CC469C03285,8B4CE7B29A45A700,9BCCB002A4A99498,467BED245305E7AC,8AE7CA533621DB96,00006BE2A5531412,36740A0C6DEB0EAF,447D00C9BB637CC3,4C5C2CD9B8C81CEF,2EEBCE6B2E2A6DB2,B06BFBEA49710F5B,B69E497F6BA735D9,00015F460388FE2B,C3B8E2DF6BFF2263,4D12A53049342EDF,E07DBB7524BF589B,750F0724EEED462B,14674E4F3AA77F64,BA09AC6DDA97A52E,00016CBB6692D4D5,0CEE9BE09CC9C258,68508A8F3ED6557C,BAA751A81DF512B5,CA82229CA6EE6429,0075CE54AB650484,1991A5997EFEEB63,00001D3CA6C9F905,39C0FEFE44F218DB,CFF49C525B973E07,4769D7EEDF8AC8F1,85840D64CF3BF5CD,73652122E976B056,ED0F8A55B1D17AAC,0000FE9DE3761245,A226D6B722C53C5B,2C9C5BAA911233D3,D7ACEDDECE2ED9DD,ED92FB47C4B92C53,48D0AC333C504DF1,4DBA58FAE87DD5DA,0001D49255493C2B,EF80E5FDB794747F,690537A9B1920126,EEAFBAC2EEB074E9,F512440CE8007394,E261363B3EAF66D2,C3CE8DF6EF85B9DC,000213A18935F35E,19F672F55992A569,53AD04123533701D,53C6C2D978AA46FB,E8DEF39DF382D2F5,71473B920E8B6D21,76A41C118DCDE5EE,0001BD4D380E8852,C12B8C6A66C23E63,BD4C7E52080C2DA6,F7084BE6796D892D,09416E827FA46F45,5F56E945F2AF779D,3ACAE199D07DBFB2,0001CE2949E5D3E3,9E3535C71D2CC3CC,6572DEF043B196AC,B7F27B001352F142,3C47A4CFEDFB3DD7,CD9E3258C95BB7DB,FD3C7BFD125CA5B6,00014B4CD3648E4C,9612BE5391F96592,FDA648E97EAED665,DCC27D3236B60898,13A30D61AC64C918,E21B87C04318A0DF,702BD30782F40EA2,00008CCD5AD2FBAC,DBC7D79871E8D07C,5C82441B6EC4BAE1,2497CD4F538E2436,595CB4D3781C3941,09BC7697C31D71FB,D20492B4246BAEAD,0001E5ACF98B219C,7579558B2AEC1D37,9DB134E186148255,B7BF3C67FD8D2892,73AA8AB91B8DF9CB,246EAC50C6E103B4,58EF7E53AA6A8ECF,000023A5180579D7,C200409ED2EC552B,58F0E93143419205,754D8B2DB6247AC0,C07A142ACE13671E,5520FC61A428888B,9393175754FC92E0,000135CD37401FE1,202F166B7A87E14D,9A8F9A421C1A7161,64DCEF2C62E558B0,5D266D19EABD4CF4,4927C9477370F2CD,9DAA39611434DD96,00010C246AF6FB60,05F8309737054F9A,11680EB902D2515E,A3CBD0FBC61A3671,86A7AEE6D43BDFD1,3561F09881C682B4,A3BA960CA5556551,0001C9D02AA30148,C099860D8762AD3E,F0318661BDAB85A4,B487761BDDADB47E,21F2A029FB955B97,5E93CDCFBD64A154,05B2FC0E89776297,0000E8E1ED25AB45,84926F8F179B8B46,27CCA4190D597AB6,CE291FFC21C79B4A,2AC02AA7CC957D42,B84D3EB95B032151,DDA5A8D872144572,00007657F00FF835,84FF48A6D0B20A51,3C6941EB11268AE3,64E9AC3E1797DE47,EA78DED463A89BFE,60C059A7CA8437F6,6BE77E9FA342DFDA,0001BF07FE5D53AD,F6680137A3701CD4,F837878FC64C0977,71E7554EBFA7F069,8DF6D19C5DE28867,341D7D177642286E,E259C45B23DA66AE,0001C42BA3B79C49,2E7F42B95210A33C,FCB028DA1D51176C,2E5274D1D74F7FFD,07787A6350BB50D5,FAD7AB9632C9EB4B,342CBBB16B992ED8,0001DA296BA3BE93,D77B524727DA42A6,3F9F631BB555FEF1,31471212D02D64C2,8DB7FCFB785C2CD7,28D84D1623975473,A183F0181DF8D241,0001EE81D1BBD0DD,90258E0BDCB5EB1B,EE8DA7D8799C309A,281AF5412BA87F12,7C2EB07DEB6AC0F0,7036B43AA2A0D8B1,AE544E3724E3D0AF,0000C928C47310FD,702A1E9D79EC0FCD,6631B56C24BEE361,685A464F66315397,3889790C87320656,EB6CA83295BE95D7,56FA7964347876BC,0001C18462178764,DE3A0A824FBE86E1,B9BAF80E05487927,A8D5A1088C181920,F243E0C2A5EC0723,294EB032B9BD4477,D1AC85AB7AFDBA10,000081D1E03BB349,EA7763AB4148E0F8,1D7E5B1EDE3A881B,FCAAFF8D822D8FF8,A1D4B7D697AB143E,DF1C3DB35D15870B,8B3ECEA9BC980323,0000841029309A68,D95EF7CB7E738B5D,2408480CE2BA6A27,54DB4A53BBCD54AE,645FA65F15AD32C2,B3C68F053EE595A8,1665E7DB32C7DBD0,0000625B6B7F65F3,FB40D5DE2E94A572,A4E1F6DCD80F7039,6A197B87FCF83EBA,2E4DC778134FDA6B,1907549FC3731941,B3A21D3112AF8906,000229556C03BF5B,B6E33410B93E7BD9,D504D61D0F6A56AA,BB72D35A483F65D2,056D8F36929D8D20,95268431065C50A3,2FD5FCD0F9807B0F,0001936FA18AB4FB,98BC084013A77155,40D8C7538F0F458F,B4955393E9E774DA,0FE0CD5830C4575D,50F57F8438C13AC0,0266CCFD3D045A5A,00005F4D34DFBC83,4D1D1F7DB596648F,0C62B7E75403BFBC,45B5C76A7DC1067C,E92F690BF76F32C1,AE921D961D798B6D,0AF9F448A4CBAB48,0000A004520B4B80,D5F69D8FBD7CF25E,BC1E96EA117D1B13,1DBACE91F858179B,E5885B135436EE62,AABC7674B7035ACB,01145BFCF3FF91BC,00004C5EA9C2AB05,D4E9C05402E31D42,8B77A8F5606899B0,6007B41F86D30822,D98E15AEC941E73A,D35361F4E8CFB63E,A50EFFA915202D15,0001078A0DC40CA1,0836E111AB9640C6,28F257FC89D9B58E,7AEFC011A9A86FC6,4D06AD84EC23BF6D,6FB5F572A91CD4B9,F22CBEBDE0F9D61B,000126B2EC8BF880,26F8378B8479C2DE,36D4DAC57EB8C425,32858DB5B62D23FC,C73B308F96A45E2D,0FEDD1202A0F5008,9F4219526FC29548,00013EA7A3364AF5,966A8EC473CF0BD7,B4DBF0B2F7B3014C,B009A48DC2B4977B,1D9B8BD6C730BF0C,FF61880316676B25,2CDC4727EBB14ECB,00018EF83D3B4101,3B4683FEB1F85062,E282A2DDCEFE4F1D,B51AF796C366FD07,D6456F85D56BDE46,194E75DD5A08D71D,1A0074D4BB713CAF,00008D7EF5796C9D,EDE2792DBF893805,E230268B90468D8E,483811ACC53E8F30,E855E4C6CE856B17,E47F069F92577264,2886BBF825E333D1,00000A30B8D2EB83,F386BABC2133B880,25E37A136A0C3ED3,C81B3573A475B489,23FACDC623D7F814,7E01DFCF84E4D135,03C541220C60D586,0001A13B55D46AB9,65E1E9A62C930F95,477779705D4498F9,BA428F8428706184,711EE40C74A6D7C0,5B797CC9BF785BFE,6E08313E89DE9FBC,00013F8EDAF5F2D1,A556ADAD3ECC9DB7,99CF5405E70A38EF,8A5B37496C62F5C1,2E5AF4828120B954,29C8655620A77AD1,2FEC21AC53E72CE6,0000D3E4E94EB168,EC7E631B66C710D2,A24B834F0596DFE3,898A229A39FED509,DFE7C496D2C48937,9E6CE4FB1355AA37,7B8C100E85FECE43,00005E6ABD0C64BD,F5D5FCE7920BCF8C,57183C018E973D1B,4ABC26A5A9A66F9B,247D5F978D1B5105,EFFFCC72734EBA81,A22267F676BA50A2,00019C07E9D4B3EA,7A235BC44F255DB8,9D9E5C8807F97406,5DF86FD518BAE000,CEED35FE624381D6,86E96C81214EBADC,64BA122D47CB82DB,000169F93CAB79FC,EB9A6BC6ECFFDD39,34D9A6DC3D86ECCD,A4D00348EF04EAC1,2F557381C25AA02F,D7FA999ABA62159A,AF800B2E9DC3C414,000223E18C8E5618,8132E245A5C680C9,95C65A9BEBF802F1,74FE3EB421F783ED,AD235CF35F9212E0,4217AF1DC073CD79,9A95F262E4F97369,0001CDB43A2D2714,A9A9809425B377CF,69CB21EC33AF62C0,524148DDF94EE637,2216C44F6DBC8B2F,27105A52247C9116,61F56EA066E622F1,000013B17B5EEFAF,131E18C95ED94260,07043C82CFDB00E5,40016CF9E552BF6F,771204D3FCBD109E,FFEDCAD042079C7B,592A7A5FF30FA2A8,000045E7E534B416,276460BC03A245C3,730C59D3B44CECAB,B5C31D8700D5EF59,02CC48D892972F54,17B93D0342BCBEB9,0C75230F3A57516D,0001C3E60C3F7DBD,1268F7AD1332EA9A,17B521E80934CC41,845B45A84D569DEE,0D8AE515FC5AD89E,7811688FBB322138,B16B87402AD8C229,00000BA931869423,052FBFE7E5CCB022,4C4B320B6EA5E695,D19A567FC795E15E,B8E37E0660D30E13,9AEAE72D902D2A5C,518B2570B284A8FC,000021A6A7B97BFA,CA1CEE4370915578,08CADCC20C5381E2,E5EE8FC690CB6256,130AFDB276B3AB1E,DA9B9B2C46DD0247,A28C985C165CC630,000156453A2314C9,7A36BDDCA0EF35AE,72967C28D8428524,916E4B5D4B54E541,51560471F678A59D,4E885AFE0D3E7A04,3726CE8C1957BBF7,00003AD4A38874C8,2B8C888311533237,25AB9ECB563E64BE,3C149B27CC305111,2B10E66F78B881F3,BE5D8DD71A41CE1A,FDA72668B1D190CD,0000953659F769E4,F0159C9428862540,583563F80B45F4FD,F6B6D39AFC7F0EEF,6BF8F06E39BEFE0E,4A1032E4C2A02B7B,F63272909796A7B2,0001B6CBFD66E776,6BB45CFB6CDFD21B,171A75407CCED94D,C17331B3970561EA,5922ADC1293693AA,ACBB7C142D981BC5,911675F3A7F39095,00021C6A2A37CC64,1A5394FC48FE686F,1795EC96198F78AA,2FAA91070A5AD4F4,CE648D6AE14D95C3,52C41F6ECC762660,5FEA6C4CD1D35307,00007121E7FEF55B,052F85FA40438136,56BB84A9A7C6E754,298D1DC3E5698335,5ABB70F120CE5944,D39238B80E300447,B60610B967FAF470,0000841A47A58693,D41DC99B45449FFF,231C2D84E8F4A0AA,61659D556DFAEF7A,29B49245FF759D32,E0505C7D11E42A82,6F8838423160B38E,00021A4646EC5DB4,C29F59696F2565CF,6C0CA8161D58FF85,04FB3A6A47840D6E,98B564CBFF4D0E43,E5DEB7611D5D71D4,DAAF73C514151BC0,00007B8CC467A859,91A0F8D2C7AB010B,4E3C8F110704133D,0D461EFA220EBFC5,52E4ED1A2A0C0DBE,13522AB7A75C9A81,3BA8BC80AF5683CD,000191FF8003045A,894E8508442BCDB8,B2E44003170C9E53,C2551708D3912812,552C1FCCF6AE3176,A4ECE305307AAEDE,A75B9FF5DBB4B8AE,00003AF2EDB8DEAF,FAAB816DB0B94ECB,91084EC01F60C030,E3375AD2E3950737,81FE769CD4BBE3C1,3908D50709A6E646,823B60F278E55238,00018BC6E80E6CBB,A60820D4A5CCA76C,BEC7BC1C7BFCF242,08AE2732306BCF59,AB90D4672C2311FB,94B4B9E45703752C,30B4B3EB3DF359A9,000213AA0C7BABFC,E40F4DE3AE32760A,8BB3E61ECD3082DD,193BABA813BE2B1E,AD8D4EE28A7B6B41,4E39A2FDF16C7319,6EECAD40943D8B4A,000043C88638004A,0BE9EAFBCD596475,275AFDE0B7A46ED6,B21302F2B6799D4F,053609DC1A83171F,65FAB2533F4624E1,9AC3EA3FADBF3F11,000006A142313EB9,116E38A6283C34BE,B6EDF4AB0399BAE0,F3223824616EC89C,9226FEEC3E98C711,34CF3AB3D424E4EC,B8A03E0095A4EA82,000025D7044E7640,D118F547A5B04791,46355E8C9582692B,E5C9216BA7039A4D,3728CB8C88BD14F4,B7942CF5A5311B45,8947F753BC765DDD,00021C95C9D9FDA1,C64B52C9E7C5FD9B,306EF930803174F7,2FDD010E76A1A6BD,98B366C3544EFD0A,BB2F2F6D0D4CA2D9,A3880577884E4DFB,0000D466EF45105C,F09E5AEFCEE47659,8DF3EAD186CDB825,FD2D93DDA6E39B6F,D5B155D14DE071FF,B07646704489087D,5D3012D26113B5D6,00019B8EEC3350B2,46382A723A88219B,1A2B7C6A4652F68F,9BF7FE19771BC6EC,ADE279B05FB8578B,5E170D000B4656E4,369BCB9321D7DDD8,000172632C91CDEA,081DC47C8A0DB90D,C881DB2EC04D2C58,529534DD48AE5197,11DBBDD46C6EE0AC,AAF31A70508FE113,A9AF318DBA44EE8D,0001C43C95EB842F,893EA9905A6A341C,87620F55C3EB8CC0,F69811151F67B9DB,8DA31D02B626FED7,B766CCA087F0FCC0,99D249177E427149,0000B55EE9A0A65E,FDEA218E5D1CE298,5C57A8C9D3435F07,7FFE17BA38B1444E,ED5C4E4ACDF93C45,BB1835ABD9606960,89A879ED73C7FF9D,0001B17E1A951016,AC6977CE94EDCEFC,8C5C20BC6216CDD7,B8C8F739753DF9C1,8902B0D16E1D9EEF,250685E90C47B7AD,93E861FF981B8269,000039AAD917510A,E7938B7DAB55F20A,C1BC2A8EFD88F1FF,9301B73872B08123,690547531264BA3C,0D4382EDBF0F1018,1C07397084240EBE,00000767E02FAA0A,2C5BEDB58AFC7C60,9B0DFFA1443B62D9,EFE806C6D5EE20F3,3817518033298EC1,1A2087E6342EF7C5,164FC3CE51BE9D64,0000096283A49167,1135669202EF4ABF,5F14414765AB69C2,967AE66E3014F432,D0868B3493877407,4302D00902839FE0,5CB39E6FC8F277CF,0000C21852A3E6B7,54620DD6856E3A96,15815248F77E03ED,3A7666A033702C3F,4DB5FF167816EBEB,EF24A30ED2A2E7FA,7B14EC8F2777C9C3,00020176583E8F35,A4A40A06DB2A7131,0CCDB29452FB3C07,6D3288C112AEF7B2,098CAD23136AB995,95774C6B40DC4E33,3572EC343B9A67C8,0000F0AB7E3208AE,FCA1225B76C85CD3,8A91A18919119426,25C70C1AAF4569B2,DD1C7B5C480E859B,43CBD375A96EE830,EABA59C3CC9DD83B,0001912A9CF4E1CA,F30441FB9051B51B,472CA6627B8B90EB,BE5ACF1BD6838B1A,1ADE4FE15E777F2F,163ADD3896FB135A,6A4E1B0BFDDE6578,0000FFC49541EE43,BD40773D18DEB95D,5EBBC0DA805DC858,1A8F949D02BC3528,800BF12A625BF243,82FA72C741994389,5D707E3524B43500,000055E9FA59F9DC,C0CE1423EE867785,23A1AD21FF540649,7B96384DCCDF6985,C754177D01CF5BB9,07FE78980496552E,AA624E311599B393,0001F943DA82194A,5A67D0C7CBFDC844,44C30711BDC873CC,2A80F405B81D6178,9E993F5398D33785,C9E7230DA6F80C77,0350CD7874C91299,000094A3F44DCC30,2FA74EEF068523F0,99337E75B29AA857,A6EC96D61ABDFB66,14B528D7707A130E,4FEFD0DC07A44144,BE184D266CDD4555,00018DEA788299A7,282AECA9D8C6EAB2,AA2948A1EF7A856B,BE2AF2150244F1EA,81D9377D02BB2310,0E5A5BCDDEA4FAD2,C7C0C13FF1729AF5,0000DF389B5199B3,E3252379338F1A42,40F65C07F87D6B90,CA007CCF39AE3B3E,07FB8CB3F5A25EDE,9E36DC9DB4827894,EF1E8429ABC568D7,0002306DB9881ACF,FAF843A16AC73311,E069F72475ABC60B,39F07C984532B825,346C17AF79DB0E02,898D0C14C4868489,CC8D82168E19CBF8,00018174D25917F0,2CC59FCA75A35E36,711B00127DCF2DE6,6305B2700D2B2028,CC29BBFDCA84DAB0,44F06B0BCDC6ED08,9A79661F3E728C7C,0001C2474A4F15AD,869410D5EB51B46C,0E59E8629233710E,572092239E6DE21B,7F0233046DAE8F3A,BF2FDF032DA99EE1,642A5168CDF60059,000160390BD001E1,C4AD2F2C6658CF95,566F80140FDE6E21,E719F16ED9001D26,E5F5274B77C2D4AF,3156238C6D694EE1,EBBB6B30A138A423,00004C4FECD0FB80,2F001147C7C4C0AD,9AA8ADFC575927DA,E4D7EAFAE2675410,C2E2293A0B628043,081AB8CB81464B13,A9B00B9E4A38DE3E,00009FD8DBCC9D2C,6922304BC170C96A,83E77DEFA5FA0DCD,C10891CD33E30C3F,D9209F2145431F9D,FDE2E6F17B658548,C7FDD8B09EF491A3,0000BE2A18304A05,BC57C7A7F5ED9C21,2368D78FF26BF6B0,4E3211112C6C5982,9ED4C457D1A50BB6,0DE28C4F13C3FB41,3B378DEB85EC0F54,000127F84DFD0DE5,4BB6A8CA87F1BE63,05BEFE67B6E9AA7D,632A0B440B5054F8,0D596DBA87427291,29CC7FFC411E04BF,55136F8D5A538A89,0001936922D2E3AE,80902864F1ABFB41,49590B2ADF68C018,13BE0B0085777893,DA07BB241499137E,73FCA236EEB30A1D,AF720BAA436BE48E,000205B5D3D6DF43,38A020CABA1EF66F,8C36931A7686926E,CB0726BDE398C7DD,7F748441F1AA9D4F,4C64393E96050C4A,7E41ED99FAED45A3,0001A438CB804469,BD0EA075E6AD5186,15B523E508E69FF2,46F31ACD34D23A04,70436969A32E9E1F,33980C40020C0DA5,F6E6CF176FFC28FD,0001498F6E824E2A,B75418A87BC913AF,859D0CDBFA8A86CD,93362979BB3807C7,1976EB4D020A5B48,C8211FF314480A14,090C97AFBF331BD3,000033F3982C1A78,242E93790FA4B6F2,374F0952F3F1BA59,F4A670123F8E8534,69BC01B451F2CCAB,F2969AC181E6524D,4E75244026FA2E1C,00006CB0E21FB676,BA9200E2A9873A2C,DCA919F35F09B2D9,AD0B0A4D820592AC,244007AD7BB4706E,DCE28A5FB6CD5E72,66910F4B782F6ED2,000012EE936DA80F,D6C0DDF9346745B5,8A8857470A30804E,551E0D05F3316EA9,75C1AC8E65CDFAE9,29D9D94A554CC6C3,B2AB44B397D70086,00010FE887DD6570,59849FB65A92E058,D1B8DD495996A3E8,71D49F035BC0D2CC,A98F673555B45C4B,8CDB6A9692718A7A,9AE4F364F5E86A44,0000437F0204C8D7,C73D2397D8020C38,3CA7AABC0A35F5B3,D7D42B99F9DF74FC,0C432A8F4F12AEDA,71D829679C57D762,561006C38E410C49,0000E9205F4A845E,97E2DFBA452C3A0C,2D98C3C82A69E56D,A18907BDBE850282,B1B0BD0102EE5642,C35EA4839CF27D1B,D5D694A6AB8FFD9C,00016BBBCA90440D,6C76F8779EFDF527,390E206F119C8A26,7E436E086A218094,C6718AB4317A4536,DFF4533044D3F6D0,417E61DD6468F153,0000A77B132FC944,0F28BCD58ED3378E,2EF66A67D75E2C6C,8D1D144BEAA0E334,4415E3371FE38AC7,23308F1D959443AB,00F3E5CBD45E25E1,00002A084C23FC57,5B705E6F975BA85F,9159457F3CA859A5,0ED079A4D5EA66E1,BD776EFE99D9EA1E,6B462236287996B6,B9B483D1C719A07F,0000389F436E39B4,995748FB343222EF,10DDF333A6835BF6,C990C1B4B24FA64E,2FFB8276FD3F511E,07BA7086BD3BDE55,825A0D0F6E37205A,000082FE604480F3,0C2DAB0D8A8D226E,DD4B2189B07F7987,F935BC80AF5313FF,1C1574EC3F706DDF,8B615A115518EC71,A0722B6616304C7D,000211E2C2D51D09,53D246D9C3ED8D28,4E0AC09E9CC82D35,DB6E7968B5182B62,EEC901A6342C989E,3EB26EE4A8C38511,E26445FD893DD080,0002173E30B9BDF5,52E2CD7F61844BBD,380E9EB5BB31E7F1,E22EB9752220DEFD,BDF3DADDBE72B5DA,95DF224094AA5EDF,EB5B7DAE7D523D7F,0001734B3054B98A,F65732FBA6790326,227D6425C0C6B2E6,DEF12D3212D9E903,AC5F464BA092F94E,E77EC5D346A4D101,E3A8B9D46E281BFF,00003FD5619D0346,7E5412FED81C136B,03BB8661ABC27B4D,254557DB603A7D04,45A2B83F5E526F55,B1C0BD2AED031F66,1B9C9FD719B2C855,000095A1234BEEB7,B6C66357CAA0CB71,CF0F13D712DAAF2B,6A4DFA20FCED00E9,43F42855A60F5807,0B9540ABDF233F9B,6F6CC59F7C4B9AD1,00003E4B19C4AC6D,80E6CE6578DAD1F2,05C92F5078A15E29,378363047B813435,1F9EF26EA7D0D326,D21B0332F3498DE9,1DFC172B61E7B485,000017C0D1B0CB0B,775B87DB3118A590,4FF47A66F0362A36,B6BE8C70BAB107C9,76244EACB534D70E,D5CFC36224A11A5C,2974C7EAAEECA712,00019C81F9983B51,DE5F707C5057B5E2,B4CEF34C9330B421,4368F47F5DA0BC31,6A934D36D7968B0E,0E8C6603F661D0C9,4AFF58415C50AF49,00018A0EB05C5A3A,660B9471CBA133D1,4F4890380A054925,F8120B61141C9C30,05C935151EE0DEB0,F5F0FE2DB3021D88,42C8C6824DD60885,00016C1AE1BF2191,EF0169F13BC10923,9E517D66EC8B0D21,E2730396D6A0A10D,8350B77E8CF65A81,F8CEB55D0A38E7C2,203E042DF2CB754C,0001A0D3FA230A38,7CB097416823C36C,C2A171352662472D,6B3BBE6F1CB5FEB1,CE761BBCBFE63EB9,28F26A39296BA725,22E342E93E36DBA6,00020C7405D0F289,1967080C4C25DF8B,1702EF2A6C03D30D,76CCB6D0265BEDFA,922C87E1BD5F51AB,E657F2C04CF7B5F1,24E27A9DA8EFA21F,0000E50D097E3176,1B0BCB7FC0F5CC27,4C6C2C75FE8CDCBC,A27893383336BAA9,B773FF651BD9D857,F88A6F327165D66F,072EE9AEBAD3182E,0002255639BE9EB9,C94532ABCA050838,B571A847CB171628,64C73A38207562AE,35E32BD67EEB3955,F0A788ECE1C14483,766ADE09A19F8B14,0001555F3F26F52F,E87473C48929E37E,804497490A8DDBEB,954CA53FA55B129B,6EC600A68FADB841,677C69CF757330DB,0184F606FABABCB2,00015E0F83263F49,3AAB424EAF8C6E1B,3B3119B874A6117B,3E6638E0F6ADDD56,758FAE81283A02A2,DBDB75911781D0A0,9AAB6329105A79B8,00000AA94A9E8E6D,6727570E8A5D5EAA,B84E594727856981,9B234D621B0BA00E,D24C612214A34E2A,550D0FCB49A42D27,5CFC4E14F2B1EEA6,0000E83A8059312F,6029BD5AB80780BB,460AD83380C119D5,1DBC39E7BC4BA459,1C268E3025EFC9AD,0E84BB32B8F85198,9D1AC9B14B1F9BDF,00008287ECDF3CD5,17193432C7568159,07299D74C00231D1,5B07DE4216F37EEB,AE54030DC946CAFB,E98A032DA5AE0128,F686B0B5CD437510,000169832E523BD1,5D17F9231ACB01F8,906B8156F51A2869,D23D0465A1B0EDD2,BF249DF783F29790,4146D6CA1BCD4074,DF2F3124AF1EDB69,0000FDB4544CF82C,998DC2C95573B3D7,9E49FEEAFC543FB0,B673DD64A883D73B,515C4089BA96C3ED,A58F715FA69ABE34,AD8FB76F184DCA0B,0001E973401A721C,F364DDDE9CF8E613,E6D2A9C7D65F3043,0CFF8F3172F121E2,ECD8D2EF0C7F2D37,F34F54653F62CEB0,3FAFC0FF23A06A0D,00018A76C659ED12,075492B01E9F093E,0709080D9621CC9D,EF27073E20B29B5D,228C3B77C8615BD8,05F80DE4C6CFCF04,FA22467A2DA02EB5,0000F15A7125D6E5,F034D136A2A63C52,12EE08E244DC400A,1EE7F5FE0509B74B,0E4AA12C6195B271,C871E27923051576,C57C0C623270CC45,000062250C3C0D21,C3F6FE8B07C8A804,2062B16F50411F2D,A4A9D2D07B425E35,DA4F5290F5465A01,7331FE207046F15B,83F113D2E612CB72,00019F96CC4A7C06,A13C6BE795544F82,C67F9C295ED7FFA6,4419709B63419DFC,D0B376B04A9A8D69,718D0A49578897C7,0FFC8DFBF1C2CBE6,0000090AC2258A95,C07CC74DCF3EA1AF,C059AA418E508873,16E6ADE3109755D0,CAC907690160154E,B7CA206609C4FC2C,9E66080FA70C65E2,00021223059AD7C5,ABD6CDDA65C3B7BF,581301B219D6952E,11484DA6413C7D49,F6576873381CEF9E,04681C4811393B0F,64E401897E12EB5C,0000DB10253A6396,3BD0532F5143C685,0A458956A962D5B7,E6B1EABA29370D0E,6E9B359057D38CAF,05CBB1CBCD33BDAB,9005105B46E547C3,00005104F2979273,7930439774288363,A4F68DCCDA77C7F9,4EFB4EF09877E8FB,8F26ED7167FD3F7E,925503F8C5F28116,4B075C5B0A3AA81C,000167C59EF47B6B,C3F93B53FF25B341,A2934409873386EA,5B61E63E5D407E80,4ACFA4BBC4A72A36,73C57E64D90F452A,46EBFEC1B603C1A6,000134FBFDC1F256,84C20A1577998F94,96EFFBEEBD9B79DC,D4169711CEE27DA1,AA6BAF65F79B4427,63BAC562FF143620,DB176DC21B50D127,0001F1AB567BE959,8157F1124A656CDD,C79112A2DF3B1C02,C40CE0F4C0975B7E,9E9A23C01D6862A5,A21B3AF89350A3C4,A79311F0A4E0A7C6,0001147B3CC17A00,3555EB3EBF508376,83723175CA93CA1E,6DD084A1682B5451,F38FBD9CB6228EA5,60B52F5C66616891,412AE84FE9C55C3E,00007CB6097D38CE,E5E851A6FB0824E7,AE604E645375C46B,32AD127FA7ECBCF1,D389B76D8414ED34,CA99E286AEC62259,77852665C90F6DF9,0002256D96FFBF7C,D13FD646749876BC,223B1AB6502C8AEA,2FA425263C566285,0185DAD9075ABCFC,617FCE2E341108B6,C0B3733518437F40,0001DCA1C66C7BFE,C2430B1989C6B492,DD325F9DA6DD8262,2AF726B5A9CCCB1C,0502DBFAE65150FA,C1F415065FB77883,67154B536D3EB673,0001F0D7908A5840,5F14F5DDCE20535C,0611549E27E1B88D,707464161C54C761,834D6E6DE9E2C3AA,405ABC2E43E94CD3,65450A2415B2AD4C,0001EAF7B4EB24B1,71E6F17FDD6AB136,7A81DFCB317D4097,47A1BC92E501229A,8B352AE0598809DE,523E23D54F093F92,981B376C64669651,000176E5750E8CE1,1672074210BD8BF0,676D052C3F7F9EEB,2442D9A477292FC1,6FCEB8A2DFF95F34,82873D83846A9305,6B4CC719F829B04B,000036AD2F51DA36,BA9A09BEC217DB21,81EE0F6CB26A89EC,4BEE2386711D1876,3255A12C55DD46D2,A95B41C5C0012CFB,0EF5BCDA67A19A38,000101C1CA38A45F,5E4C0547FB239CAD,54A0BDC176F0671C,9626DE6605EF5636,4394A26FFC6F6C62,B011381034B7CD72,E9C76584B1DBC437,00021B3CC58CCDAE,F3A43140A2234A02,B1D3AB2E303B9A2B,38A38853571D5E13,7F6044F81A7CE5E1,EE0F3B14DDE7837D,715A55B4BEFEFFB0,00008D141C067175,BC589CF641195BF7,5F8FCE25500F960E,DAAC769FB9C005A2,E7D8E7D1C2E480C2,62513A81DCC392FA,A1C7E0F7E202A123,0001CD3AA9309004,77BF0907E1F42C6F,8F0D388E4707AD4B,874ABFB9549265AA,DCB12140B791D85B,B5F33D30A661A880,110009181A17DEE3,0001EE94538AD083,F4F8DA044E01D7A7,71D0E8F4585FAE31,D80133062879748F,394FD5F0AA6DB158,C42C1A23835B4994,FFE4D35E5BCE9884,0000F2495E74011D,A4468E80A30E1F8A,D7BA373813E1769E,2D48E3950114F899,FF11D460A303BA42,54E19A0C7D25A385,FC560BA17AC89C35,00005D0D784ED263,66201477DC405DDC,DA049F23A5F6B382,338AC1CDDA5E12CB,8D80DC32DDEDD76F,6F0E24A8AC5E7C08,FE043F2CFD6650C8,00000C200C23945E,BDB98C1C6768134A,8C41410F4975D0F2,BDBD75F7752370D4,E39B32D71FF64165,460D492BD76CE476,C459FBD0F7A4924B,0001211EC2DEBB28,BCB431F7A319F03B,AA6E55916EEEBB06,7B6EDC3F76D18F2E,E2A8AFF334D8A71D,480A8672FE5A45CE,638FC8BCC79F9073,0000DFCDD5DD99A3,59D42C1BE8772DDE,1299A9DD928B1A8A,73F94646A947928C,E47007D267E2EE32,9DB0D7F7121EB70F,E4FDD09934D50464,0000A90E3F23A6DD,AF44CA595EF970C0,E63A8C1C256783CE,A4950B000B7B9D1F,E81D7C4CD63F16CA,A74D5BE2C38B68E0,E85A07995B59188A,0000B531DA98F67B,53F437DE184D7937,44807D46A2F79563,E0A17883FF6A6EEA,794C4827C51A9AE2,E87522C266163F9C,475938FFF4CE0743,000013695614A2CB,6ED415B07BDEA0F2,382073737B03F1C5,9C25FAFF678F8F4E,94081DF9E6A6AD0C,B88867FBA9C70F00,86EDC2FF76234AE1,000081C92975E9E7,0E3FB295948C1B48,F77A7285A07F04D1,CEAC7E50C8551B52,C12B037E87E257AE,D24E038BE5A08C94,26857B09D7A20627,000081C1A6CD7A9B,9557EADA77875A5B,BE7EC3498F502EDB,649F351D2E21C63E,DDF4161E76CF24EB,A1503622F26E8BE9,07244A3CC53E094D,0000B9AC740330E4,CAD644FF9D3953FC,386E49D7019ABD2A,20C18167CF3A1690,1FE478D75E14F9ED,00900703BA791888,9F7B9836D9F5A81C,00008F9642712F3E,4D1D9DF45C48387B,9355BA6039496EF7,97F060BAE2880528,A8403345BDE500C9,8D06E19811153060,7450C81363EF971D,00010B3458D2F9F9,D21ED9BA4225FD72,2C246F3D441A7911,4A4318D70E6A507C,898427C81BD25468,BE3298FC5E40BD79,3E03A2C1334E0A97,0000CC8751F79C1D,1D54A8658D21ADE1,3C77CBA870DFA2CE,BC28CFAF4EC1ECB8,2230F58FA2FCA8BE,D90D2D79AAF72C98,5BC4CCC8C72315AE,000100AF0BC572E3,30ED1CF4E263134D,57DF8D6B45BF8F17,54EEEF87901CD735,E726B659F5DBB60D,50563C34777D8C0B,8326E89130E03863,00022CCBB0FF3C89,B23509D977EEF91E,DC17FBA2EAB5896F,074981B6EE8B797D,F824367B0B77FB6B,EB9F9D4BB9DFB647,4DB045F931E1800B,000215C71A4081FE,3CBCFB4395A7D68C,F0B785003135CBEB,B3E70C7ECC647035,EDB1C95A040FFB86,75B492462F1D6ADC,A4DC192DD43620DB,00003A80F823EB73,85F9116CDB7C2ECB,3616A75AF3586CF4,AD72E9A631BD6FEB,E6414EE8396074BE,2C6BA761EE522972,774849C5CA08A096,00004969ACDAB91A,9ED724BCD6291DFB,48D18536A3758376,22831D5BCE42C736,CB995D68D291D2A8,0BE20170CBF35443,44CB06BE22035C74,00018FC385E9CC58,F32F970E785F4DB6,AABB37A11B4D1372,742CCBDCDDBC150C,733FA26F1D32248A,884FBA1F76CED8C4,ABFEE12D6C90ECAA,000061F1F728D330,2598F47952A31F0B,4119CAF8E2D6BD19,5F467132F7A6E790,B58D1E1D76CCDA9B,17AF1E608C6C3D23,9F791E25A0D1A1A3,000002C1F4717D35,6F29F5B46083E843,160A5BA78AE2C57D,304A00AA8C689461,946D192A56A1BBA9,B70C7E14CCACB026,273956CB0B1BD043,0000D709FCBE5AFD,77D6C0C9BEDBE3A5,B1C571D91AA70B42,736864E7B66BF2A2,6B8DDC39DFC2E517,21271A5FC404FD5D,F177760C163F1716,00012EE644E2164B,73573B232366DA75,DFDB1BFC5847BF91,89FCFA469609B799,C06C7D81601E2287,15C38CDF944C8088,C1A0AE4C0883FB0E,00022E7CFBB7F877,FECBAD8BE39DA457,83A2C0FCADE18986,8767AF92DD0E01CF,035FC6A683E0AB9D,01A1B67EAC964C16,F03C2E61D24D8F7D,0001F31E110C8918,B78A074DBFA94151,07BE4067AB8864E5,00CD685FA2F9D60E,8A0DAB0BDBF83638,45A43650DC6B9A23,352BADE00959AD47,000007C4BDDF53C6,F737015CE2085D6D,8E33E26ABD3F70B7,06579AB405B53473,AAF25D78CDF52DFA,A1B362F509E16922,86790D0EDC871737,00020D706C77B78D,638DB3D81044185B,E8CB3BC4671F0F38,4278FFAC4264F8F7,B460AFE561A29A2F,74CAA973EB094F59,67FB6AF379AD57AC,00014302FB80ED3D,290BCFCC49E6D912,575FD5E8302B63F8,444208F47460340C,E68AD9E641E99625,9A3C06CD9DA2A8F2,A77D4CC54B9124C2,00002C1BF86EDC70,429E27CB94BD4F6D,8D37988939E19AE7,CD325C6DAA5BF83C,198FE5B63FF2BB6D,E75280E08FFD775B,54D5269D5B04FE0A,00007766DA6EA545,D341DEFD359CEBE6,26E9E92BD8F64CC1,77688AFCE787C839,094AF23F9EB14141,822B74421E49F4C2,1E25F930DAA7AB5E,00017A0E59703EC4,FBE258A09AD16794,9FD02592CF0FC458,BA995AE113D492D1,44D819DA8AB1625F,574D9310D7C5AE26,13225A31E881419A,00004CF1CBDFC43B,1E4570FE5AE57A1D,11EB2298CACF714D,DEE5CB568DFE5124,F985E7463BFF4990,CA4F0D9001ACEA69,585F5EE8FA3F6C09,00000E962B97E200,50AA42B17B7C6B8E,43B7137D081C666F,6C30EA8D0C54286C,65E0ADBE7F0657A8,770C020DEE9C87B5,3D3B237CA9341A93,000211887092930C,CB2E83DE531046A3,A3FE4E6DB4D5F3BD,8EFDFFCC4DDD7121,644EC1AB41793243,D5706B5AB53CE5EE,270C9268D10DD4CC,00022C17ED86ABAD,D40652D881169976,6B6A72BE433250E8,7DA776D64ACF12D3,F0A5050E69052322,38135AE5FC15B893,720F988215E4E3F9,00021D307D913033,F6DD87836ACF4790,79A769FEF289B890,8FED3C4D22C57794,42B8CFE89E627668,C0907BCB6AA73C9C,2BCFAB75BC34C366,00017639FED34BA2,B927E34A0458A78B,5E9483DA8EA72810,114CB3D6CEF90CF5,7A02C6725293A7B4,96EA6AA442679FB7,B44191B1F5870458,00006E7E5A8F0408,92357E3D247F94B2,0453F6A55B7A71CD,C4AC5DAB6BFF5799,3AD2071573C7F375,E7F2C19F00AC43E2,4B5EE0CBD16B7F1E,000187C13F07900E,F3FC59003CF5C462,3649FBCFE80393A8,7BCF1FE153ED9EC7,1F12879B37706923,70C9C8D9FE6336BE,AB1263570631FCBF,0001B81FFC1D9B2D,C1ED3682FF2D9685,D5AE5AAE43B8E01B,2793711426F76FCC,C9B2EE1A781FB2F8,4A73023C04584935,95428AA176ADC9B5,00021E744A5D9087,91F639339BA023E7,5EF1EE05D1377B3E,D6DE2F9136F77E48,1B21C47571E3E4A3,A05E9BF7A0E4037C,EB529B7A62E47619,00003266827778EC,2B476FF4D5FB390A,896371A8F9E6ADC0,2B88CBF3A0450773,360829DD89C4F98E,2B3C08B0C0C4BA31,DA7CA139E90122B3,000107AE7FF4DD00,0FD1AB9D04A38C8D,4D779B3509F6C4A0,E6F5E1B528008236,D1B0A30AC8A33134,346D60082E30EA2C,CC6F719BF63D43CC,00001675DC107D9A,AE795397116E2B14,B7C999A4D990483F,A96AD2865CE4B481,A405F1B2376F8231,F48696324259A1CC,7F559B8E6BC29F37,000141E6532ABB4A,B6724E7139CC1EBB,D00D7607F82BFB90,B2BE6EC6AA8514B9,4B75647193151B42,0DF404B66592E84D,06E096AF280E6DDB,00022B87AECAE28E,E826ACA01034C358,7C569E1CDEF9A0AC,BC4712737204380B,6123DD4F0DDE46FE,DAAB9A5087F716F0,F65C58EF97E16AEE,0001980DD1EC6379,717DB950A63B1C14,F447491D31FBCF2B,258C10DEE8D519DF,90620E9322812264,8D646674B2C39552,04849138A292F6F2,0000CF1AB6D5D523,8EEF769D59006DEB,6C0342FFE25A187A,DA65440FAFE22A0D,9C5F2BDF47AFDF7A,F0ABD12EA2191F31,5E2DBA931D500202,0001A552266DCC5A,B5F2801E2F822FDD,A869CDF7DF3027B7,72ED890DF8C8BECA,EE0D376BDEB11021,04A9932282048A71,A56683C2D5956ACC,0000FFE456495109,9D6CC094B2A194CA,ABC7E43E4B3B453A,D24AF5F29CF8602A,F301B1CB3DFA8A0B,10E1242839649081,75CB8D076DADE5C2,0000B06D849FB008,6F3993DB99328551,BE0A0591C9320E44,44B1F56A3462AB21,5D5A2B713947F788,C31F90D68A6DD4BB,5BD6B7CEE59D4AD0,0001190FF3BDB6D6,B1DD62DE6505AACC,C1004F6FB9BAB0C0,49D1535BB6E66BB8,F65CEE8E985C178C,4F75F1D7BFBCAEE2,ED096E7F7E211E59,000049BCAE562FB2,CD54417D9990260C,9403FBAE10C9DF8E,AA4361E4FEDE6142,61CC522E5DB41C35,3812A1A5C01286D8,F02567621D3C8105,0001CABED5A6F0AB,B6339CB2C83AF858,257BC45D5EED2E72,7A3B3B67A3EFC6DD,E6BA630C78B3FDE2,DAE4DBAFAA4C2859,AF709950A5B0026C,000231F69037A60C,57F8897E20833046,D1919635EB9CFDF6,14B825B9F33663B1,81C0ED593CC0A11F,8DA0C318C9186593,90C63FBFD45D0DA8,0001336F002A3A5F,9771CACFAB812126,F75781C3398C0480,0C9B02FF0916757E,9C4E37DAF43A45DD,8710EECE82719DBA,FD8060F42EF6E4F7,0001934EFED3F299,16B0BE3AA43C35F4,549E22B6C2846813,6007A8AEA60C39DC,3F900146982CAA13,F1A65F7F479D14EE,DC0DED63A6A3FCB6,00009EFD9456F922,201027AE44597632,064D8EB83421F650,B894DE353DE98D86,9EA9B6F3A078A291,9190C73D60A55B4A,62F22E8F99EB81C7,0001B9DD6C8D4A78,FAAE6B213D4E17F6,B66D295730FBE97E,F72354C04DB57FE9,BEB32D601C1A4C3A,0225215687611015,E748BE03F09182B5,000180AD6383F84B,D88F252F5FD7B1B2,E349D6100BDB08A7,431ABF1FDDAADE10,F83430D93528A6AD,418237B42EC4FE59,C364439D87D6B4B9,000094F50F497893,451B6AA4EA40C202,9A0E78DF6E57BD98,6C6BF79989FA9D97,6DC8DFF9BCC91675,071B06708EF95FFC,E5D810DD2C229398,000148EBF729D01C,F86E95DA74204B2B,8E842D710D1EDEB6,C1BBC6C905D666D2,CAEA5FE5D2786AF0,181807BF972DFCE9,3B5A792975D8CB2D,0001BEC15961CCBF,94F95FEE1DEBD419,79474F605AE8D0BC,DF1057182608A53C,7B0A66F97F3F1BBF,051D430126045A52,D84895FB29B20F9C,0000572A43399147,8268045D6FC974C9,0FD04EABE4D9E53E,5714D0B5A7E260AA,4035CE4B35AD6F19,FA099DAEA20BB9F9,186D87AFBD575F36,0000E1FED973959F,026551872AEFD0E2,0128C009C2D1A715,C7A26DACA8FD5F2B,415A3CAECE000479,3D12B353E24B8BE2,36B7AF8D78577D99,000009F7649D8AE1,DDAB19D0C28A20E1,DEDF0566C7DD4EA7,918267BD1A890534,D7455F453D11860E,7515069DB7AB158B,D2F9507A632F7894,00004C974375E074,29F510B6FF2316F6,D9E1E12F757078F8,75B83D09B49096FA,371E326265CF74D0,9212243A542C2B8A,3F672FFB11A8EBA6,00002427BCA75814,210DCDF99E242400,93244930B8A44754,F681C1E749553E07,6A66C806BCA7217D,629BC5E2BCF384A0,127F3CEFF2275025,00021D123FCD56A9,3533C29804A7155A,D95E3C487FBF5C84,97681A9C7D96F103,5A90B2054BD930FA,FC83AE28D926C024,2CAC433CB7BBA395,0001F09AD0AB555A,309D9E2E7F8D9D28,DCE6B6AB6A44BDAE,915EFD3D54026F91,FBB27EE494D43C77,10111AA97C279099,905976B118288E5F,000018DF5648729F,09C66B488BC6C84B,A9D99BB078A3E615,5871CC3F389BCD38,CFE016AA2ADDBEB9,C314D0A3447EFF6E,F1905A86A8C49892,00022154A16A8356,6BD362A071D51DBA,744F86B96D27F5A5,B63712FF0015950A,7E09C6753B72FB91,270D419B6E78510E,A17535BF97C4D9D4,0000523AD9B90FA6,67B2541A2784E4DB,735AD34793F1700A,11E164970A50B983,6EC2D721A82358D5,02B21517AFA82E20,85BA3EBA2D23A762,00022EEDEF90BD69,83FC5C9D075855B1,57BB72210D3350DA,D4F7387FBF5BF6F2,BB2A919B1AEA7EAC,968036CEBFE28503,6AE655D4B54C4AB1,0001EAD255437FD0,111F78DB98F72C85,F72A8F1CAB64E640,78AF1D8E3C10ABF0,57494667FC99D8F3,98EB0EF032B6EAAB,0A4E1CD2DAE28087,0000082E357B9DD3,E4A65B422D519AA8,3A65C3339A061C2B,3401D4DD71349ABE,8A20A6E7B279A099,500C20938EAA0299,C0D69525F51F9BC2,0000E2C92E5855EC,D959A94201728D1D,B94D061C2AFDEEA7,C1A14900B2B553BB,9A423B4B56A90DF7,6328FA20DBECABDB,07AA6AD1C1749585,00012417541944D6,E54A014E8C63F373,0D35A8C701146E13,187DF3B579B93A6C,D938843DD9D3FCEC,509A324E7B548F3F,F6A653EBED6DA4F3,000218A3962E7F1B,FB97C54D0C3A8116,94071CA35202285A,A7BE75B826788B18,764FA387FDF00135,AA371B698512C725,A37B2736C14B2839,00012A937BDE2D6C,E8661D8A4778A226,F476BAE1E29D3582,99B71E2B95C4F8D1,A4F6DA11BD8F2A8E,822901397E0655C4,655BDE8B5D5DBE5D,00011B09703942E5,492BFE04A3B5C171,D11EEF6FCA918031,A38B8D861E8B3DEB,0EA87AE68076773B,F68A0777A359A31B,FC114783727885C6,0000AB5EE83CBC7B,80593A46885A774B,DB2E0D4DD7418F01,17BBC5F0B075F02F,7BF43629D831D72D,FFBADAEB36F78286,B6B5FC10FC4A8D7D,00001F4DD8A7467F,B19145DE8A837263,632B0F0D8C15D642,4AA98E5F1C951EED,A1A4F0C49B839B99,3542022672336B1C,0DF16C49DB0EC0ED,00008E5032B2A6B0,8CDFF12137292C46,94F9BDD425596E7E,69C7787FFB1B534C,DA31AAA4138A1B3B,2F2C86DDC61CB9A9,26F6A9657E273918,00014C600C454734,6D2DDE570B06BA48,DB604ECC83EF5ABB,E6F881B703603EB9,8B0C9B771F04B1D4,0B42FB1397EE7C53,4653CA2E869EBE95,0000D1B00485CA17,4FBAFFAE09ADC53A,156CAD153CA28E67,29FC564707D41E63,59D7B7BD3D29360E,FAD3135C6B661255,44235A7AB3826B62,00004D9944E514EC,70D9B369BBA206C4,38F9E5AB86A0816B,0D285D056DA257DA,C4F23F7906583E07,7844B094D5004B7C,C6B2AD8EEB817D43,00017545BE349809,84502A75C63D9A8A,AC953BBF3B2B94D3,D7091E15D5B1D496,06F048B4831870A2,F533AD6F983BF1D4,1986DF6ECBB1A455,00008578AA83379B,A85CE9AC16C9BC35,087C2A8B720C999F,475C6E1308E6335F,73479376737AA997,574B8D1872EA0F20,66C201434692A3C4,00009AF13476A942,28B67F9A7F4859DC,4CBE1ACD7C6087FD,B8CC66CC883B6EC0,5743E2E9B432E83B,24B9D1AEE20BF1E3,D03D9603DD17E63D,0000AD17CAEDF6FA,DABE7CB9E067EC2C,72A98C24673B0087,C829DC98A8BF46DB,B5451D8D740FD375,CC2B0047C113E7E4,BC6D69C8173B12ED,00008FDDA3968978,02D369DDAE79D7AB,551AC5DDC65BE7D7,4EDA0800145B54F7,D91DD26A61BF2462,65DC44FB21F3C8C2,89F2846961BA42FC,0000FC65A22A2799,ED5FB5B6FA752F2D,5621AD1634857C00,259E20713CA42BAB,034CAD9A8D1C2CA5,21E3487CD531FC78,05D8E1F3396E9902,00002D3EDDF0D237,8EAB3A5DA6E3B1D2,3A444E5AE4DEE76A,276D7C6B20FA5F6A,35295994324CE70F,9A4C617580FF91C2,08D08C1D4AE739C3,00022F896E6466EE,7396112EF3264BC2,14607E424AE6813C,383AB04F055E8440,70E26FBA9EE5D589,4AD62C657BBDF583,13756380F5E5DD50,00021C6F5BA947B1,8F74A426A5CE0D6D,D1E1AFD86897C83D,C196A9E363DA3235,8EEDD364085C11EB,11BB0A12877CA5A4,5E0B47C74DEF1CC1,0001163D91A6B105,9E82BDB796AF6EEB,93870F6ED549D43B,12CADA860FCDFF04,E0BC74D2475B7812,507D1262059D2A8B,543DFA7C5DECC2DB,000201E011545A1D,9438B6853844C629,A8B05694E21B86FF,70511F03F422841E,032E4667824016B3,3941FC0B7E4ABE0D,C84047CECB421567,00022F5FC0FC6990,F216FF0FC2CF3999,EB00861D05219087,281C50A2A88B98B6,13DAE138A00BD8E9,2908B24943DB90FB,87CBAA28E94E77DB,000219D534248139,D1B08863A9F5C62F,678D73EDFB59FC96,4D804C57685B5207,A2EAE8C2B4945620,E64919BD92A23F79,F99C368DD333B521,0000B079B8317299,09E5BF29317A6D0A,DADFFDBA36E6616C,9F3B85050E0523F3,AD45900FECD2E017,7DD7103EE4D86ABB,E07B295942F832ED,000101C5D927517D,7242771644599918,86CEB187651D1F93,43F739831D661DBC,486635240D78840B,F10D2F8512964F84,7A51530D90B74B02,00005A12F96CA4FB,6EADBC884AC95A35,15E8CF1A6D2B9841,8D0674CFDB6CCCFC,78261DD54B967D77,A0A9C0D0757451B2,BDF6BF6E095A5FCC,000076539B36D5A6,0A166AEDF09CC43A,D21CF84149A9380D,C8DAE8B261944F17,2760FF82555FBA07,D6B2737B1F655E8B,B844197A0581E8FA,0000F334B47B43FD,B794D359E024F5D4,E727A3979F09795C,280E5B7AA452CC01,913FDDDBDC4D11D7,1F893534BC7A5295,059AAB01B22C4D47,0000A3BFBEC9579B,0E640713D81B1543,38E81DA3335F2F68,9C094E23D77E6856,50E09AAB765B42D8,F94D0E2FAE32D1D5,6987ABA53EECA8EC,0002296F346068D5,824BBD643939E66F,094B8BECADDFA7F9,8B13B2179AAE41C1,3170CE237B66AE5D,7156DDDC76C9D978,8D18255BF34BAABC,000178B906BB9D88,FCDDEFDB9762DB57,C0742C031BA56D05,92DBADD7B5D71684,8900ACBBD5130F30,8D37754AC4A98EE7,C69CA03B4C8CE43D,000041774EB8D338,6F153598DC890D00,5ACD689293D5F833,E4D9C6DD6B060633,A3AEBF7642649915,68CFA632810808B0,4B5AB6D0CABB95B3,000072904611AB3F,730B8B092F9ADD52,F9896FFD98D600EE,A2BB3AE1F700FA90,B578E1F586320796,95345371B20F0D07,4CB185CF05327692,00005A9861269EFA,06D6BA5E2A5B6CF2,720EF8AE8B7F3BD4,17BB9F77F3031DBE,F22FC040D3E988BF,73160C6B6E01EE36,72E7C880ED16A114,000135C6C1AD35F2,BC533DA90B58F083,EC0CB1AAAF7270B4,CD10B28EC6A30F66,D736CC74FD2A054B,C445A60C50654A69,AA477BE1E5AA5608,0000AFB5465F65A7,E44C0838DD6E00E3,ACD8BBCD805CD20A,1A1E1F75989A46A7,76681D29D5F2842D,2390577CD8121030,FE6192446DE55626,00017F815D84C5F4,CAF5AC2953D4CF9A,23686CA8629080CE,BDEDDADAAC5CC743,9AF5EDAEF7D6F978,5DAB41602063F964,37E75DC5F77E2E00,00022036B3223514,99DE0854BA2E5FFF,7A9C75683481C34C,B5527BB1466EF281,686ED089C79E6C13,AFC61B471362E0E7,09A24A61E7F60151,0001F00A53D8F605,4D43B36E36A26990,7C5F502B23345FAF,C7FD19B60B72DF9B,63C7C0BE7FB0AD2E,0655DD6CD68CAA0A,C5D63684863ADAD7,00010AD52F7EDC54,3DF1B7AC1E4B36F8,54833191D32CECA3,67F2A5FACC04B8D6,34E0D575BB274CE9,D2C073C896614933,DB5644F42231A34D,00017DF9B432FCC1,D36212981A9B568B,BA9A25F97A9103DA,6F8E3CADA8040259,5C316F89F024AACD,CECB2C8B318DF33E,F76E7CC7D1CE03C1,0000FE13A475148F,0BA069355D3031E3,87B63B854BFE9116,1045BC715C642EF4,6465AEDC1896BA3C,61D825FB8576961A,C8A95DAF2BEA01F0,00022C54915F9A41,89699C370E6C1169,A640E3DAC796E4D1,EA20AECD085C6E96,9D03EB934EC6C8D7,60E9891D158B7F20,E6657D09A18ED098,0001C96B94EAD0FB,EE19B16B4336F1DF,CB2E2103444039F0,9DADA0987DBB8378,F667865CB8E507C3,E0C0FAA0BF099002,DFB61AC886A230A2,00002B6C9461D876,168EC08BB7540712,546DF7FEF4DF83E7,978E0900A28F54D1,0E840937F86784DD,76893C9B606EE03B,160353AC2F5DAA20,00001658D34885A4,EAD0C05BCF9C15EE,6F695154D42F0571,437A094AFCF6C33E,92778E4E4D1926D2,161AF6244253C1CF,031FB3F59F9C37B2,000078F65FA64FDC,3A623BE707115F7E,6B4420508FB83173,41C3D3206534C1EE,D4F08B307DCB3C84,488D8CB0B5FCF53A,7E12F4CE8EE809CB,00006DA505A50512,80D10BF2D48997F5,67D9A12BCDE404D6,13B9076BAECE1606,CD7DBAB03374D1B7,0A87DE87E66E191E,749BE5665A55163F,000066D1751C0BBD,C7113FA9F4C33990,4B181A55C3016006,6B2D53D85156B1B2,E77E0FE224899182,9A29549A3AAC6682,039A6D4B9E774075,00013B883C7C3838,D2971F914722243C,E7E4A1A63EBAE6A6,0006626CD4005F9B,D0C7AF31A8B7A58B,8120F5AFB66249BE,8A3FF1294E62F7C0,0000299C684ABED5,14A6508033F221F3,A1DD54EEC808FF3D,F77CB552F3AEA1CB,CCB94912199A6F13,F390FAF4E49DC3CB,A75E982DF407B8C8,0001A3B81E217017,964C94AE6E5CA534,7B9748C1F11B3BFE,27B3F4E79A6B998D,F0667B2C4A24AF51,552B0F84F07041B2,9D4B560C56B45DD2,0000BFE8C0B34883,8BFC7673A74052C8,3A16B4CA649997AF,1A11261A50F9363F,56CF09914ADA104D,9040FD4FF1375EEF,F12EB543DFEED1F3,0001CF05EF09C5CF,88AC438FEDF9F704,6E58655AA0B8B7A3,DB6ECEDE205F3897,449AD5FA4DF683F4,1D42FDA3DF2F17A2,740B23312E160A67,0001163EADB27494,ED505EABFF454AA7,F6688845555852CB,28522853753B511D,BA5A6FF44A98C14D,FBAFE19D85EC016B,D936645BC6E94318,000198AA7521990A,FE721A27160AB558,9E535ABE12F55414,833B7DA266983D20,E9FF755F2F3C71DE,742A59FEF98918A8,F30F21143194C8D4,00021596F3835E9E,12B24BDF8FDBEAA0,F9C3E8A3137D8347,212844B7D36E5737,A4A64613061B150E,B07AEBE448C071E1,BF26DA34EF4B2342,00013B8FEA57786A,7B4285A391FFC3E8,F49577DE4E00FB64,858E30AF9CECAE10,56EDB81B0A63BC73,DF80D8C7065B93EC,A62D3834CC20AD10,0001D5A907FEC131,3FBB491832C268E5,9CDF15B1AA24A974,C668FD06B67AC06A,02C6AC218FCACE23,4DF76B616C46B8E3,3A6AFE7195AF99FC,00009E6DA616628B,B44D68D84066A11B,7D0707C96BC69954,3786CE853A274A71,F9AB550523CA70E0,78502A690F23A06F,014551622C425D3C,000059DB564FE5E5,F2668A453E8CFB1F,06025891D878F4C2,28585628CDE9771A,700B9BC74E8D7D1C,B0EC464F6A3FB585,5CBB281C46BE6F20,00013E68A93AF0F7,85D7ABFDA10346B3,5743BDE5BF2075EB,5DF573CF4509B37F,5F7258668DCAE150,FA792FA2A4FB8044,7C880FAAE53678C4,0000FC984F73CD54,70F49455FF296FC7,5FAB4500A3BA3779,DA2017131C128DEF,0A93000535A9B606,95D69043171170F4,DE1993529D56DFF6,00016D7A969ED905,A2392F3ACFA911F3,2503521B220B7975,EC44FBB333F8D2ED,2BBA10E4387615B9,CADFF2EFA369F9EF,1F2B388B4F54C931,0000347394C6C7C9,64604899E0644413,0ED7753CB666FFB7,1EA3BA4D31555714,4311E3927FCFEC4E,4610F1666F253D23,1D0D8551D3A85F87,00000120B96BA8E8,2A533A812EDAE592,579510A40B5B6AB6,D6347AD32131A9EE,8C979E090225DF68,3F7A96C41228E587,7559CE246F4A5547,0001089A8E4FE9FA,DC2F4E6C2E43405D,D1300CBCB82BCAED,7EFFA95052079513,B23658A870D2EA0B,238A6226FF94A3E9,97670A795E794B27,0002302FCE72BF8A,D74C4BA2CE8BBD87,133BE14927C72017,FA01A074D73FF869,23A98440F77A3FD1,17DBD6B905858B6D,664BAD4156144F29,000029CB083DE8EE,117EA10DFD1E6CED,1C184F712F660282,6651AECACCDB5D17,B32524A08408E561,9A8794F51B0759C1,2DDFFAF4692678DF,0001793762A7A166,A252B7E3CB9D24CD,AE49CE327708D995,EDD5AF817314ECD7,EB5624C61450E457,E8504B589E2E9FB2,5C71C571C0748749,00000387B4BFC66B,780E0A11129FFDC3,A7D24EDFFE671F79,78A3F9A54F4BA835,95949F6BEEFD7BC9,767E628B3C7E70DB,E2F2A6EAC37545E5,0001829CE3EA153D,FAA953F3C7C6D57B,025B3D880178798D,CA9A936081E6E47B,92D4CC41434DDB40,586171CB98DC381C,2F3BAA921A9C01FE,0001B40DABEE798B,95FA45133B2FF1F1,6A2D2852FD1BC799,D87348E10ED3E31C,BA027F30B8528B72,792B18C0BADF0242,B0C3C736BA9D721D,00002606E7169596,559712B5B346D333,100CCB9E7099DC9C,FFF33EE39ADE3139,73BECFB18A76B214,6A9FFE9ACE7849CE,34D1CEC4D7FCECEE,000116A892B5630B,A5ED8E04A50C69CB,36614C0F1D41688F,C054D8A03D29C2FB,53FE0C2A7F261BA7,1A825F16D73810CC,B6F49B6EE66C5662,0001A6028AE450D4,BED4749F543BA490,D77968DE96B2B734,8CD789208DE59DCC,0C350550EEF81F6F,5CC8AE4308081598,F2C1E88070AAD6B4,000189AF39ED6B25,C53337DEF8ACDB79,CDA528B77A2DF7CF,DD4CD6CC628D34F8,31158BC5275C0BC0,00C02DB6EF088259,23D3D911C7D2D774,000077E29FFEFB93,6352C182AC3F9CC2,EF1BA9A47DC18FE3,C7E7CAF46A5755D9,5B7F6D748A1C934E,8AF76D9FB9473556,DB1AB7005CFE45DE,00000BFE973FAAC5,CBBEC7B56E546499,F3F30D6ACD0943C3,54FDCCA53D136495,A3E7321B56799CE7,44777456998D3EFA,3741121E8113A78B,00009FDC6222FC82,31A89EF87581C859,A16DD74F7F0DE057,AE96A8C58E3B4234,6B6ADF1CC1FBF580,7FEF39ADF086C62C,84763887BA0DD610,00018D50B93B99CB,7799755FE1CE14BA,B9964CBB1A22C06F,C7469521E6683957,9429A03B132440DB,420ACAAD467E1F9E,C2BF43E0567EAD14,000117882DDBF088,F772C31B21C26436,3C9BD1C64C7ED629,91A4FB71BCFCA791,70BA15112D181095,E317F5274C676D62,A86AFC4F0CDE3E4D,0000E58C8C56A63C,0328D950D7304735,F9FE38C450750C5B,E0AEDAF0D733D995,123A105077AF3E64,9E93CC8DDF2C3B5D,9255E9EF26C00E1C,0001D8975BC00295,FBC847423B72216C,778C249F6DFC15B0,112D517EBBDEC377,6EC4EA779A8ECDEF,DD8F7E46A80231FB,050D327CDAB006AF,00013D55495B1C9A,29465F195BF63926,99A4C65E2A959002,F027AB4C396A0EA8,428EC5645A77900A,C1EAFA5A647CDE36,899340EDACB5E88C,000146AAAB11968C,7239497FEC4B7A2F,7279C41D1EBDBFD6,2A3B483894F58DEF,1A5EEB806538C386,D4CA56F66E27367D,77843353DBDA96EF,00005FD369784BED,E1121052190AEA0E,F9EC71BE25D7D3A6,556A26CFCD909AD7,7769EF74D948676C,551173B6E44DAA1D,565E9AE8D1E1A461,0001370B58088229,F50C50D2C4537216,48CDEBAA54CFE3EF,561E2A2AE20B6F1E,C4D2FBC8D8E97CDB,5B7B30E12A3F9C1A,587B4D7180A216DD,00007B0585B90109,ABD2C99285F1ACFF,6CE3AA44D7AAD410,235AB675AAB0C949,AD02DDCA7A6FBB76,8FFBAB8882951524,F0240C8618574A4F,0001F318218A003C,A359E53AE6C5E55F,1291098C0B982ACA,6CF6E136A39350B0,AC982FC0B6917FF5,CF0B959E4A077A75,339F423F63D24E84,00022D801EC5B9AC,02171B8EBD566C70,5E65AFB3798E0EB2,10425651F695F8F4,05D27852843C18C0,2005AEDEC2AA6DA6,D9E345EE5A5506DF,00010A660867C68F,B133F39BA3754769,D22BD3FAB2A9C724,1AD1D5BB8315B8B2,CB0223B1B47CEF78,9FB7A0CDE92AF603,4B18BF9CA0AD85F1,0002194A47A2282D,9D9C5C225E4342C6,C77B221483ABDAFE,B4F61CFE8DBCB1C1,175FEBFE3DB5B4D2,431C202FE6DE54DD,1D46AA1EA43C504C,0000A1F8225E036F,9D9C5C225E4342C6,C77B221483ABDAFE,B4F61CFE8DBCB1C1,175FEBFE3DB5B4D2,431C202FE6DE54DD,1D46AA1EA43C504C,0000A1F8225E036F,B133F39BA3754769,D22BD3FAB2A9C724,1AD1D5BB8315B8B2,CB0223B1B47CEF78,9FB7A0CDE92AF603,4B18BF9CA0AD85F1,0002194A47A2282D,02171B8EBD566C70,5E65AFB3798E0EB2,10425651F695F8F4,05D27852843C18C0,2005AEDEC2AA6DA6,D9E345EE5A5506DF,00010A660867C68F,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,000000000000742C,0000000000000000,0000000000000000,B90FF404FC000000,D801A4FB559FACD4,E93254545F77410C,0000ECEEA7BD2EDA,4ECC0C645C8AB896,2DD42C054D5638DB,E52E2A447CEA474D,32BF52C92E831087,DC0EBBAA482DB8A0,21E3A039E1179A64,00001AD4DF754B17,02171B8EBD566C70,5E65AFB3798E0EB2,10425651F695F8F4,05D27852843C18C0,2005AEDEC2AA6DA6,D9E345EE5A5506DF,00010A660867C68F,6263A3DDA1BCBD39,3884DDEB7C542501,4B09E30172434E3E,E6618A7CA54A4B2D,38AA3C484A7A59C6,4FB5B5B7DD88D00A,0001922704B96FD5,9D9C5C225E4342C6,C77B221483ABDAFE,B4F61CFE8DBCB1C1,175FEBFE3DB5B4D2,431C202FE6DE54DD,1D46AA1EA43C504C,0000A1F8225E036F,FDE8E47142A9938F,A19A504C8671F14D,EFBDA9AE096A070B,F7EEFE285EC3E73F,5BC0AD996EAE40FD,931919E827701977,000129B91EAFACB4,B133F39BA3754769,D22BD3FAB2A9C724,1AD1D5BB8315B8B2,CB0223B1B47CEF78,9FB7A0CDE92AF603,4B18BF9CA0AD85F1,0002194A47A2282D,FFFFFFFFFFFF8BD3,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,44B18275E6FFFFFF,A3C4B77CDBB901CF,83CA0B82224DDF49,000147307F5A4469,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000 - -ph3_T1 = 37ED7978F7323982,04936C76D51F21F5,16050C18A973EE88,72F7BF23AB9375D3,47C989C9C28BA7B6,DF611D74933C983D,0001BC0CBF2A04F4,08A0EAC4B85F5303,B686A96CB86BBC16,8F36EBD4A443E09C,948222B2B2D156F6,8A66ACFAE2CCD48B,98DEEDA161F27B50,000103F846A96DB5,694F92DFDA192A6A,53DB650F045FBB94,914D7DD5D24B8A7D,332A4681B4537855,77B22ED3C97AA0A8,29F51E43F01EEBF0,00002BE99CC2EA3F,50AADD31483272BD,EF71AFF18F5CD2A7,2718B25973322EE9,4AA70233D7135E34,18E840E9D3D8137D,CC10E80D37099E81,0000611A286EE0D1,A9354A35B269FF9F,6FD04B074DF96AF6,C3106A5031DDC3E7,96D97DB085DE52CB,52E69CD3E0656B33,413B47B6FD5C630A,000099B4D7906FA4,4773AACD7C006827,6E0D9C18E227CEB2,970AA29DDA4FC705,0007DB2A73DC99EB,503DA274C8A57B9C,456519435726C6BD,0001269589CECCC9,00F03E85B4AA764A,D6A2D3F58CFCB874,92DA0409FD01266B,ADCC6564A5D4F6F7,C02F15A74EC243E8,7730B32C01DE2F53,00007E846A2516F7,E133F07C2ED3E1D8,B4326C2931139F04,6A51505413E95C84,736ACF58BEEF524F,538B2008AF8272BD,4BA606901671E978,000177FF06B895C4,FDC3EBCDD657CD6E,A247E9F561464943,3C1009CB51346175,F002A2B6FA005AEF,EDDF64F46D2A177C,83518EC200172743,0000CCB04068DD44,45C5EF8ED846E9A1,C594E2935A404A15,F1FA86D9065998F9,3177F334A98AB972,683137B06187B6C5,763E818699AF9A82,000025CDBC8D6DE3,27AE2A62883696B6,591D09EF41B582E3,AA5B4530E1582194,99CCB2BCAD4E2F47,AF7B2BBC1BFAEF2A,D2D3BCB820C00A6B,000184CF997B843D,D149B9FF09F549CC,E7CFAEAB0F338F18,9EA6958AE87055F5,408E4C22C8263BC8,17E57438EEDDC7DB,D58BB12D4423F92F,0001D7D0C433AD30,C7DCBE1AEC6D7C2D,8F6FB8EDACEED8A3,A92B7BA065B357F1,F6A92D93E4F369B4,D0B517306D4B0BAF,F53ABA5B52BEFB27,0000C56412AA646B,4B826A4831175010,67D08097812EF865,1950DA79789DA00D,ED0B99011BB1215C,5E5B32AC7AE8C701,561D7DE509792047,0001C21010F2BCCF,F057F3BC88DF9B21,8B8EE060C16EE48F,2FDAC5C9B23B3ECB,6AAEE97E18D02869,5EF58C8866A37082,9D42D0D7D776AAF7,00009106AA9E5BF6,7F7F72CA5B66613B,0049FF121C8796E2,446921D8A9193C4D,C46710A67EF0094C,EFEA22E111B76E16,2132DDE3208096C8,000158537695C848,C9B7E0C49271E5E6,9232D78410486561,15CB972066F892E8,A221C57C5BC43FDF,3CD91966B44E4005,4313785071F6AAD4,0000CC4419E3E98C,83EF71190034677F,B73C0DA961FBF58C,2D2FA4D06846EF77,249169E3A3B98786,BC1076683BEB81A4,45D0E9EB5D1324FE,0000627AFD457D2E,A2D211FD38E81A4E,E74DF34D9BDAAD83,FA9276E47ABCF316,E306ACDDA72C24FA,5B68BF41E7F5BF84,322D98FD53020106,00008902F84E1521,8C44089102E680E8,4CE3AD9309B0D800,E2AFBFE63C21F2F6,51D7493A7E0E5F24,5F4EBD5D1CCA229E,6B49826312FF74D8,000091AB97F84071,C363D921AA5766B4,5F78F0E41B0F5359,4A43F68C67C5BCE2,FEAC89F6BF98C204,9D7AC06DBF4FC7B4,26989B3B2D44C774,0001B6C805550CB5,D253F7739CCDB075,8318538FAD5D33A2,DBF3CCADFDE3674E,C6773568F794E12D,D6A71F2C69C17A5B,53FD7701967BFE2A,00005CB62ADF7B66,F1876400E4AEBCEC,DB7D4068365A6399,8D2B3C07E3AA1D93,B763B70480DB937E,6B209F9E89C1C38E,99F233803462481C,0001703585A8F941,53651286AF21B7BD,B5DC8DE712CB9D2B,8C8653F83462375E,A13993C7C4E915F2,964055D5E5966731,357C020389033773,00000CC534E50DED,FF72F3C9C8A650F0,CE49F4C2868EF761,458103FE62D5D7EC,5EDF0259B91D5E5F,1D08EB6816BD60E5,A946F4C5D79C5C1B,0000223E0CC250BC,2B51A049820E158D,B0AE40314ADDBCED,7ADA8CE98928AE66,54CB91E1C6E32237,C5BA6BBE489D3E92,C61076FBB6204480,00016725A031428C,19CC0BB9E81D0F2D,C74613BF54DB4817,372D926DB39C3CDF,2CE188DAAE451706,2E9D1F86190D2D03,07AF6FEBA83E7E98,0001239E39C886C9,18016CB681973207,FF2EEE394C8FA492,7015BF66C6DA1CB8,682A804E6C62CDBA,9ADB8BA7AC3527D2,5CD6BD2C7F57E672,0001F7FCBBEAF368,C9615E77B9A331CD,796546F9415693B6,49E2874740F92975,EEF96C473880186C,6BED96B40F3F4146,6F0183BCE2AC1B17,00022050F405E829,65707E635ECB4E9D,8B6CB4F957CB894B,A548A3A39C9F6A88,4FBE409960FB15CB,2122ACF1EF2316A0,F5A6FB61350D3FD4,000133795A80A6D8,4CB72711CA850294,C211F90452DE238A,80E6D14309CB28FA,A30C6A97C9FF1E8A,2430A4CF8D66F69C,80AFE7DB642FD042,000006868939979C,459FD7E2EF627373,BCE705FA699DA4ED,361BA49E03059B10,BA3AE86694E7AFC9,AECCF50BB95E2BD4,BD9B1FD6D6AFC93C,000144E505989609,0E8C5A33992BDE5A,1E43F6F8ADC4687B,CEB1842C9087709B,0EDB68CD7E5AD47E,6EE1502AB55169CE,A8AB5BF4CF196E9F,0000B16B329F570B,BBD392B020E491FD,94E0A3821045F058,4507C63B48F72909,7F06CB6D6E81C97D,8F1BC7547C099C62,A9EE5E02C3A26F1B,00017005DFFDF107,DDE3DB271B9A4338,0A5FD982FD0B4AF0,E31686BEC642E12E,07A80DB5D4B32EC9,C5151C20FB123F75,8252EA8E4768B901,0001ACFDC9EBFDAC,F9F03DC5A7959190,E5758D844E7AE926,8407306CBE092609,B6FF0103DFC5E9E9,A4B827DEE62D3AF0,C358FDC46FE676A2,000031ACEF775F8B,3AEE9AFA0A75690F,F727CFAF23834AF1,4D60704B124B5887,8F2C54DCA0B62387,C199B08D1BF36133,C8497DF8D26F0A3A,00006EDF8A6FF561,E3DC50CC98B2DB44,EE6D280D20D7AF8A,0AB02DF10F3EB2C6,F45C684A268969C6,64609DE2083F62A7,D5F322894E61F36F,000163A65A090CEF,BE1D168EAF5630DA,DBE8169263A15123,B93503EF4F1EA8C3,52200F4FD9684DFE,133D324EF92F3352,BA8FCD8662861855,0001F6D78A773767,9C82B7C999E240A4,1220E79AAC60F412,2F696A5BE3B50E85,B35D254F7941B586,C98A7E825C600FF4,2984553C9C9C35E7,000070D98ABB8FF9,3BF03B0B965023B1,19516B395D8DA1F2,7464C1F243A64333,42B77F8AA757596B,F4DEA8A5A296386F,907D14439E00BC3A,0001FE7146A8996B,D7A71267F37A1505,2AF0E82C15DF8276,52B00A1A190E239A,F6046122222A2E85,ABCF14323CBA69CB,9D196AF9DC177905,000050E3901669FC,CF6D9E37ACA7FC41,E3BB6F4674DA80C7,DAAC5E9A0A44C2ED,7D5307AB1434786E,622342575645CD0F,0E28C64BD43BFED4,0000B39968FC5CFB,938BBBEF5B9D2EDC,364AD80C20AFC700,EE2A7B39C1AC7E9A,66A182254E550751,D29EA3C001982C8B,BB51E4F503A3C906,0001958524411AFC,E8428B7A729110B9,2E8097378786016D,2F0328778BBE0ADE,B14FC0435B4DB89A,772113481A7CC660,986D7F22ACF37EF6,00011737B1BC4D2D,355E1DF04317F5A6,5CD277CA467DD1BF,4F6EC2BDBFDB407F,15CCF1A664666C48,5CCBA353639CB77C,91ACF89E2581873F,00004580EE384271,41E94A2CCE86F736,4C8C15CF21972171,E8E30CEEA70D832F,3568E1E0B9408B85,6137CC06ECFA3C39,F1874FAC5763CA25,00006B28FE92E335,04079F2E96D4C37A,ADEFBF0D4E81AA76,73C93F65C7AC3C1A,C413FEA1F936A2DC,898653899E3635C6,86CFE3C4D9012325,000052C45C688B16,A463DE01D72C1A70,029A864C11EBC266,FDF2F62E382A27C8,CADBE05B2D3FC1D2,7BCADE04573915AD,9B4C5206CD9A7A56,00013CAF24B79DA6,7A4F90F0CDF4AA5C,60213E8E82C6A788,4C6A474E2FC805FC,B976FD938065427E,4EF436FF608A0849,051833803AEA9329,0000654F30F79524,96EFB0DF2DFE2C8E,3A06FBB27B9EF0A5,14E37AC90144C0C7,464DD0DA0ABBD703,AE734F2423D4926A,1422C19B36EA6180,0001098DC36CC91D,3700F973B254499A,BB004B4BF0D3B116,90B567FE1A266551,A2FBF99C37634018,F758C30D975543F6,D0D48AC9501A4C71,0000B9AD678DBDD9,99718695CF56D1F3,0FA0CF4A65E2853B,6BFC00CE66341DB5,9A1FD3D8BDE2168E,A66312AB6D1D1429,C4F6C545D87F3AB7,0000684ED280FF51,BB4C6122596AAFB4,09975728556A3FC4,F737FEBEFB08A1B9,E2179CF8F34CA308,1F733D8647D99B33,8F161334971B8D14,0000302DCAACE7F5,E4E770D3A1998E55,0E50F7A43CB8F3B7,CC0EE4F49DEE0608,0696621C1C702829,EAAF7372E46AD1B1,6A697C9793AE126C,0000DCD786C808DD,62BC51904C27EC96,98659E35ED3CA154,CBEE68DBA5AEF1A9,84A6828DBE8486AD,B62C8CEBDA58823E,C0505E7F1EF6C439,00003E7290CF7FA3,259120C9EABD2A04,296350D8CC35E881,86F68443CA640C6F,A973BF6907A3D5D2,14037612F335A0E5,D8D2268298E642DF,0000D8266EEAE590,5249141997855FB9,09AC7EE090E433A1,ED35F7C7E9A6E973,436D4670CC885A0C,EAE89063A007DE81,60485A975654EE3E,00008A62063C2F5C,20D3CA8D414DAB5E,F0258C41FC6BBB86,43433C374F87A54E,4774088F8B175EE5,213EA6CCF17658C1,0227216743DCDE7C,000155CE7D303C44,FD853D5D19CF4854,392508A64BDD3A54,894B13B458027F1D,8CA48D136C13B85B,5731520BD0C4AA8A,52CAA13C82DBE553,000068EB8E1B6529,F2CD11D60502840C,2F2239288190E77E,0C54FB6F43DDEE33,8432E6AB6C48DD03,BC1C5C175CC8B07C,BA9377935A979713,0000AD160C55FE9E,E5D9A636DB5A8277,3B299FD3A9E82550,3F160DC2C89EC1F3,423C8BE2392F9BC5,03367279C42919FF,4ADF68450E4ACBCC,00012346785644F9,0D68C754289408DC,51DAAB92F41618D0,64D36752180AB1C3,8B5ED8FBD1A334CF,40F949620608B5AD,58C02DDCF3E3CCD4,000016309E490B72,B9174D2B0DA5B62E,29BF6AA15EF6BA92,5547D71A78FF4258,DABA5F729726FC62,D48DF9C370793FAB,244C37BE2D9550A8,0001608063A660F3,2454EB43EAEDD43F,3C7F0615382A914D,1D3B977EE568FE40,2433C72B68D09881,5D90C300127B5FF8,35B5BFA968DFA206,00016B62FBFB5093,1C28CD2BEBC85AAD,1EA92D8C711B11F9,F1441C840CFEDDDA,91F3632F3411D040,82CDC128C068940E,03ED528A97689B92,000103D7C12C5935,9F4122BEA9516475,38FDEC71E35AC118,5637F04F82B9D34A,618C456E7AFF7415,D228B1403859497A,972F88F825FFFF45,00003599BD2EBDE7,451721B7E01921AF,1324771B92077467,7987B70AFA46143A,207658160847F295,45AAE41A8EF23AB5,A3404D8312AAC63A,00022DE6B7333E2B,8ADDEE86131054D7,E97A6178E6D79720,8EA7ABCFD67A1D62,2D22A45E719681C0,72AFBB8AE11C6C0A,3CA2C1D95465587A,0001E3C708CF09EF,A2A1EAEF86053BA1,FD69E28F3A2E9CA8,FD6031FC1739E60C,BEDF49AE806DE468,506A2982151B920C,5BC815D2DD99C568,00002DB77C0FCB84,670B253E6A9CAC62,C65C04F49DCDFBF7,0BC23E4CB94E6E9A,A9CB01141278AAC9,1A523BEEF1D3AD67,47700A8558454256,00000FF2A84448B0,5AAA8BD39B7CB73E,DDEBED4AE2361213,30B66468B222DC24,605D92C7BC8BB2DB,8835E0F870F0AFFA,2A778A5FA977EF15,000020050B6EE9C8,25CEED71C603C446,98486A1D16B12A09,ECBC943445FAE29D,819990A109E73276,4EF0DE8C559A5DF3,3C7F22A2234AA455,0000496F3FC1AA49,8927A98470215420,6EC8A85311A84229,247F01F36031D3BF,354AE03DDB636697,F2D8C34BA94295B7,BCC65F1B5CC8D5A4,000094F581B780BF,45DD1EF3E0779BEE,BA84378054966FD9,81D263C16CCECBC9,A77B15A2F2171E68,C46434F71B72F2E7,77AB7265E70D339E,000056978FE3DA58,5179D2522980E2E9,2391C1952821720A,37BBA3B0E6699D9F,3D4937335A8E7160,E3C4F8CDDD171F4B,E1F519FC408928A4,0000597AEA1A835E,3E1E36EB2B476825,C0AD39C5CA941EF4,DC84844D2A04A14F,1630CA91B9EA7F6E,A408CD429FD64C5E,AAF1E240CA528C20,0000D81C2DEACC48,91E1900B00E86936,7BE0E846D5CE97FF,0721E690F017839F,3B4039E977C30C12,A3971F3A83BA6BC5,DF15512A4D70A592,00019E62F93D4F22,E43EC119B8E89DFB,4DEB15DD1B9A0AB2,64829D8F572AD605,940936CCC608F92C,51F47E94B0861D24,492F7EBEAD3CCE12,0001FC3876F37613,25C4A6F996DC1323,680A8A80AB9132FE,8E3C791DEB467E64,428699677462FC06,2D843757B703FADA,51B28D04B3643CFD,0001850339234F22,17A3112EF9C267C8,5BEF4AEC399A35F2,D9D791D66F35CD4B,4BFE5DA02ADD348B,C235D0C6A8BAB24B,FF93B782B6B7B3FA,000156430C23B60D,B6C4FCDE05363EFB,332D1402A997931B,580795E607F457DB,37483F148577486A,9EBCBF2A142B5717,1FB805332A8E4DA7,0001DAAE25FF7308,D1D273C0403DE823,0781B73D97BB67E1,51F4D81C1E0AC129,09F339FE1A254FC7,B2996EE412AC0B92,1760A8A6E2FE0990,0000FBFC00C9B60D,4C91E4B4B33A0C23,FC39A597CC1E04FD,A7F7658285DB1A43,2A2B5772E3B3162D,1E4A550641B5E3FE,33C3B321B9B99780,00017D6DE7225983,ECA480ACB43BCC1E,0DD01AD6A9ED2785,92828D3EEABD6021,11DB3994B9A081A5,3984BA2D4AC653DF,44335D2844147169,00009B7D558EC564,1F838D429EA62CC4,4A0D87DEEFC95AE6,4F8B5D39F65C7140,6AF51F2CF4EB68FB,4798FE25308722C4,3677CEA9F214ADF7,00004A559E293A03,97E9229297FA5A1A,87CE5DF0DA35988F,D09A7A325EF512CD,097FB235B1CC676D,65DD05A89495B0BE,20677EF46C7104B2,000024B8A8A7B794,3E8B19B1784E40DC,C77EE84ED7CD2798,129A212EDE8B5FCF,0DC03C11C78A5FC0,C0F0742520A5FFE2,80CE2428457EA6C6,0001ECF7ECCD9512,20A948B07F395A6B,83D3D210248DCE7E,70179AB1B0C9818D,4381BCE5DD6D7DD0,520356837E06C429,C5BE680016032F02,00010F187A80F430,EB8F79468A4C59DA,A18525DB1CF634E4,789C47A5ED8622FD,CBC952513A63262E,5AB4C39DF2DB191B,94817CCD0F5F6D2B,000065826F8F95B5,D42FA3AAC3418712,124B5D5AC5D6531E,3619D10136E3E4C8,665ED1D7B581123F,0CB56E76A6C76094,42757942896F00BA,0000EE77BD90E0D4,89B316FBCF89B2F4,551950A7C90336BE,73F3639F5F84540A,383A92452C6FA028,7BA3ECBD34060959,09678C50D21B17FE,000005717FC46BEE,6BBB9E10FBEB1058,8646FE3C8B810DE8,40FE97C5432F17E7,9CCA279822B33A8F,2E7005316443BD05,4DF6C576A4D283B1,0002258D129F20CF,03ED4B4E97F8EEFD,D200955A58549DE8,F383C4814573B1E1,E035730952374D99,E69C22AE2E87D840,A998D0A4F7842ED3,0001ADBECAA65361,1E90562B19A2C767,90916D779EC73093,0BDC75EFA2077D0A,DBB814AC43FA58B1,25C788853A25949F,5696D094A05F13B6,000023EE47B42381,2896837F061E5C95,18E00DFE453167BA,2187CAEB2813E16E,2CD5DD9E3855305F,8B53B210903EC228,40FCC08C8E186CDB,000196AB10027441,0DC0A94B96A6B56B,D9D9057B0CE59143,3B488D345718AB36,2EB6C75F6022472B,58799F84F8270C65,0396208EDA10B86A,0000F4A31E58A5D6,CFE883E4454B525B,0B01B46BC9B92AEA,15C9F9B353D8A7DF,7CB934FB3F7E377F,05A624D1FBE9D50D,4AE48CE6866E6C11,00009D77893330C7,C2229E88BA598531,FA7888F566F6AA32,F1D88C2022B21A54,01C992666343F1DA,320FFE3076C76244,EEC1C3215138A03D,0000AA6538747325,613DFED2CA10388C,C2CEB089A68F20AF,3CE79BC8488D3C97,DF5609301E603558,3EA599D90048596E,90ABB280F8BF1ED2,00010A0C816EA3C4,7B76D2528746143F,91734621CD60A92C,9AE08AC37D292EDA,632B3469BDECD530,9347186D2B907B16,48B3607A705F3171,00011E69A0D1E233,CFF102CAC6A9BC25,E7F88CFD6E795F59,BF66AA5A23854B27,4816668703F43242,20C296E0791828BF,2758CC11FA1C07BA,0001681CE0B76110,597DC92287F3F03D,B851067F414A56DF,53DCE090BEE9E880,E817868EE914C688,137D938724BDC4C0,36488FC78115D859,0001187641368CDC,57F41714259A0FD7,9AAA59713B7D7377,2243E12268D3FC69,C6EA6C147D363FFF,F43706D18618A2B6,2D980F2F037DA8DD,000168B1B42BBC20,55E7DF5904F12E85,4819B3ABE47DA6F8,C8E940549D5B8CF5,DC83DDCCE72D9B52,B49A25AD17733066,5FBF9F9E3CC8A1F8,0001A9D39A30116F,84D90559C8E97FC8,938FA91412A2D817,E2315CF1C1E69A96,69DFC18EEBB3511D,A409D353FD784C84,819AE43CB2377373,0001DF9845A995E4,B606B23D1A86DB65,8D5539CDBC6A4B05,5725B9F80B025881,374D5B24F660E747,75868CD69C75EE8B,E7D8DE35FA168C4E,0001AC4AA828122B,48CE050DF7D161B5,D5E1F6ACBA619A11,244E813E118FA869,28003E5D99A3A441,3B68B7D319069EA1,983688F4C9C84166,000168125925D30E,B13947C39CF64B19,28674DEF15D919BA,5EDEAA1540F3E427,0D6F262E411B3D89,BA7A2674093131FE,2BDE12EB794F83DB,0000118AD6EA8806,3CEF3CD3D46DD518,1EAE2B7C77E22AB4,0D82F3F0CE40D71E,19FF46EE106BB60A,3097D41585C6E4AE,39E6556A40136136,0001D1774685C42D,5C89902264D1CFF9,0C98B69C47844418,C0635FD0E1A62316,95A8D4D2B332F943,C81D1D5859CD2276,D93A88F8F0690296,0000449124833F5E,3397CCC0C112AABD,8C6F06C424A734EE,A622809EC0EDF21E,552E40F79EC3F856,9FA096D2631D94B2,B272AF9DCB59F80F,00017855976ACFA3,1D862A062339F457,C5D1B98E02E88616,F5459B8185444631,504EAD6371C25CF6,00B29D04BC820695,5794C4FB95A7F311,000082801BAC29F9,9D4F6C6F41845388,5E348455073CD766,6E21BCB1C8EA53E5,25D211AB4F104D00,7EA2248DBB70B2A1,89880CFCDD0A7E93,0001646CBBA9AE48,D3DA92D4101A2AF7,4F1D8E3A1E1E7BC8,13D4142B1419779E,6E437CB6563AF5A1,0B0568DE6A3EF073,8088ED7AE3DF1CA9,0000754BD3A02819,0050E7764AC0F64C,FC3C9F27856DCD42,FC8E1436B052F2D7,6FE5E4A462BE5FCB,602A7EBD505C9D00,E9147A4887A5D929,000068FD9755A3FE,617D377B1A9BBB33,1F85942061080213,E8F463C000B0DD2E,AF3356113AD75BEB,DAB7A3C7CEF996D2,DA81F226E1956921,000195C1D56FEE23,82A7DD5BCC269CF0,CD80708AFAF58D3D,479AABE4B45B6561,A7BAE7550B9055C3,86ED14C80C55F460,0B5B50238884E44D,000164BB65DC3439,0E0B05FB9DE4F451,9EDC42096981875A,3CF17A6D14332878,BF6DD99555893F63,AD7E442476DA6E00,BE8425BF5BD75214,00016AF9FDB9F4E2,C3787CECDE613015,04C14CAB66A68A17,450D11B9FE410E37,D5D3ED15557BFC96,DCDE6EFE5D90481E,0559B33FA0FBB3F9,000058305F213789,89C1297040D3A474,FF71C4A765B4B4E7,CE64AA377C9CD1BF,639DBE419BE2C45F,4F98329F7FCA5FC8,0665157168B2E4BC,000210B727EBAA37,04E2EA413C071AC7,C9D6FC0B84D652CB,E7DF5DD3B5C472A5,17D11EB4637491BA,A95AA02F7E9B40EA,BCC421D0B684C06B,00012A14E8F4040A,FC2DE4B969CE1150,D9C7FAD15E714C8D,19DE7663B89A7E46,BB462108A114ED6E,1D45364BCEE30A86,C3044F5F24B1CBA5,0001C4C5F668A933,29965AB0B440852D,81411C622890FD31,1DA061B9880278C7,EFE99ACD902E1828,F2533DEF24CC6E17,F9BE61936AED9F4A,0001EF2CAE490C7E,BB244C3DF0B84B59,8453C34FFF6E0DDA,90BAEBF94D38BDA8,1C5ED74AF26D103D,97F75C348B9CDCC4,0A648A4AE830475C,00005FB38D4F1B80,FBF59A236A6141DF,6F63ED2E63B0C79C,19E851A7899F601C,9AA728BD5EEBD222,61DDEFAB4B9E0B54,AA86F9B844C0443D,00011211185AAAE1,971218D2939FB319,A5FDF0D7D36A2D58,917CC7C553F8E12B,1F1A460486DEDF97,2079D4BB740F9668,0FCC675EE444D44E,0001CAFD996F01C8,23632D87580CE030,2DBD4286178EB228,77B34FA5D1FE4719,FDA468D28A460BC4,086C0BBDE29AB9BF,6CC22E4CD2A2A44A,00011C8160486014,3325F6FD96F566B2,48CC62C72370D834,205628177B556618,0DDB990ACD89DE18,9F690C91970B4C8E,6FF323BA69EDBA0D,0000775C14E1E99B,D5C4E990EC943659,ABEAA9368F1FBFA2,90A500ED99759515,773999243294A74B,338DEC509B073E66,037DE0EE14866D62,0000A5D875D8C502,610DC00581A673FF,7A2252C9C9C59EC1,68F4CAB28B0BDEA0,F09470EB9591CBFF,D613524F623913A1,392EAE8EE930C83A,0002301ED4962761,DAC1D5074C7FAC11,1201094EA3567DBA,6035395B9EF45314,448EC3463D66D1BE,F87A2045402F682B,F1DA3881061A01A6,000103C46E7BA7D4,FFB1C7745471413D,82814E0EA40A1DB2,6894EA66A68AA1AF,8208154BB53BC1FA,8F04BB227BBB6A2D,6A4F34802D71546B,0000CB6543ACEC72,3257407C69EAE7B8,CC142AF9C4F9ED2E,795AF9CF87455853,50B2ECCE460CC358,0B4A3A4DD5B7116B,2A90E327E0A13F6D,0000105559901176,993B0EBEFB56A8C4,C08562C18402597C,591E067D5C6FB9DD,A28E4AE7A5E491F8,41F2D1732A9F9D8E,89567F6E064E8F56,000160EDDB96DB62,95F031DEAB939ED3,68BDBB684EA98320,827CB6B6BF2C9C58,B7FC54DEBC89C71D,B51E046855C44A5B,938ECE19F1A2DAC6,0000BC7E6DFAF66A,6DAF1543650FE939,56E3F5B5A2FB1756,7EDE9FEAE3701221,11E76CD322EA40B5,A1654212EA5451B3,626666D3D8DE14C1,000096CAAF3C17D8,615E38D241FD05FC,3C0062D34EB7DE11,7D2F5F0FB354BBAE,85E2C91EC41BCD3F,9952EC9522F453E0,3A72483C32D12963,0000973ECBC9FA6F,809EC00ECF39DE1B,FF5F3A35E04124AA,E968E96D29CD7AA0,491ABA6854EA6425,2BCE677F4F7D197E,14B2B9E382ABDB4F,0000C9AFE7DF6771,A45B92839DF3F1AD,C373F0DDA9F8B386,59112C7216E69A30,C5AFE58EA0734181,665E85979C5F0B59,7E856B620359BFFF,00018BFCC3BCC553,047E98CB9F11B756,90E1F82E53F51078,2E428ED4D50F5C15,71B359D96627CA39,2C7A36D50507AF03,57C01F032A8B493B,000167580C80140F,9C6989438DC6B8F1,3ED036CE665A34A0,96E1CA7F38265B72,4D25A8A4FE908242,E5DC97CD31A61CB8,BA1F39AF3C58DBA7,000199895DB72E62,19F28BB8F8803F53,7E9231E9AB7FD718,45CB9ACC479BC93A,D3547EAE190152F0,86837DECBACC9A0F,0EB6E221561EC393,0001EF169CA564BE,6C32A6342FEFD3AC,2C2FF5277ABA1650,F12E3C56F074F51B,E55D6B3AF77E4335,EC227BB8310EB596,2C2DDBD0C0AAD614,0000202CD6DF23EA,18ED542129F57537,01A0915DC0B1022A,ABF7DC242D16E6B2,EC4DD12DE1262D06,10B9483ADCFCAEDC,44824E123E29B7A9,00008EE0734F08BF,CD09735185E3B3E3,E222A1F2B3E86541,6A847937235CCB2E,410080FA880548C3,097F0543C2C8ADEB,F39260F113B1ED70,0000A0C713636AE1,AC5DB3F8A9DDEC46,9244396D61E5957A,E0EE324364425AF8,BE71B718B4692F0B,DB0BCDCB37795CE9,1FF9B333707DA3FC,00000A507737ED80,BC2F4DEF28503752,0DBCB89B2D7CF897,66451D05753258FA,7D285958C7A09C70,5617C75F685D49D3,C812CF22C0564F82,0001C735413CB2EB,DB08D5E1A19E3C31,431350D75CE35AE3,1230A01410558003,E056964F7537108C,9F480DEC8F44D3AB,80AB18CB3DC14F71,0000FB93C00AB4CE,A4DA93C29946146C,167F004A73405FA2,DEC708A7EC726135,3B0F3CC805BAE24C,801B84A811A14545,0B2C65CF2DB0245F,0001781B2CFDF0C9,21E7AFAD2369B5CA,D0B6EE6F5A6B206C,5959BB0563A18B7B,AF861CD2988CDD3B,8F12C543169352CD,D0372DF1DBBABC45,00019706C59D2A61,E45AAB7BA40DDA80,FED9168291C6620F,80FFB8F004B0D0E9,4D9A92884ED930C1,27CB1BD879FEED90,A9C77814A3E3C2FD,000219FAF6FD07A1,B6EC30D266920532,8CB29A1369E7FFF6,7D5808C355431989,788A390BFD47B3B8,FA716A6AADB1D448,A3154330FF5EEF6F,00004B9DFA5CF38E,D603415471971675,105436BA268C0F11,2A2F580A31A6F644,3481734388B1E918,2C622457F2D99B28,C8F255807F1B71FE,000183F9510A06EC,FDB24066CE968C82,A6C866A07A877453,B6E7BD82B015C816,62E112927722DACF,FB7D539133CFDDEF,414DE44E3A26E950,000169C9691B344A,F6719926CB461426,876E28158BCC1ECA,3E18904712CD6739,A6EABDFB4F49CA53,E831912E525E0B4A,7B21681082748C2D,00014CE489ABA0F8,EC2DE2829A236D76,A89B5061BC31D514,4D30FEB3F4B046D8,EFC79370701D6D99,F6B38D4F70A430EF,88A3C8920DD3DD17,0001AACB7AD6D963,108FC2682F8B1309,F0EBFA41C1CF1296,D47CB36AD7B53903,D5DE9B9AED7EF00B,B9BA0155897C6D43,1A56AE3261D669AC,00011DB629347049,49FD8CDB826492BB,E7FEE9E8A1A31984,5FA80EA5ADCA30F0,6BB0607E3B5445D8,59460FBA1C339609,DBB9FDAA8D1886F2,0002253D19B47F6F,9C2D01F96C71C0EE,986698E464F17F4B,A2377AE4588DFA3F,CA1A99EAA06D4452,C094406AF2F7D088,00F852B42D12C2E0,0000455ABFC4A688,8CC232D0029FAE41,1FF0EE8967F2B586,89A2096A166B9876,E51E7BC5430ADD25,14E96D994B63501B,5A13BAB060EB7E1D,0001526C87977071,18CDCDB0CA56A7F3,19B29E0E63247456,1072F30249E8642D,B27BDBDD8458B19F,E2BB359016E681CD,F7349DC8464DA410,000122530AF1B8C2,D4DB80B99E71F195,1FD6C73CEC487A44,CB8EC53D4D98D038,8F9599E7AF896C9D,9DE70E37D7D3404F,25918F1C61F2E8A3,00002EE4FA576F89,6C3404ACA8916BED,0B3C0CC23AD3DD17,B147775302AD42D7,0C830CAD9EE1DE07,F74B80B2AD672AB7,F21C66A894C741D2,000169F44056AACE,F5A07BDB3E01FAF6,49B7C9537B05DB06,D21B12C2060C99DA,41A3540698821CD5,26C54378DDD7F95F,20898686440A01D1,00006EA345275737,B235CA9C5AF7606C,EFF72146ECC8B508,50634D2D69AD9BE0,B9848AFC80BC6477,F46113E8EEC7D3F3,E753C3F5FA03EA7F,0001E5229C55FE1D,FB743DFA8B66FEAD,ACD236F2AD5CC4B0,EA6E365C8BB2CEA2,173FE0D096FBE5ED,CF2C70C39B949170,3BB345C521819CDA,0001BAF42688ACE6,4E86B73ED656AA5D,37E91829C4A0C577,86ADBDA10FE51D3E,6E8FB8254861C352,B55ED210FE373B92,57834442773BFEB8,000232B5A5CE84F1,ECE750A6D35A3CBB,E58307B01454B86C,6A06F8016C4E9BAC,809461E1A9ACFD1E,FF5238035FAC462A,D05720F7747F325A,00002469F6C5F0CF,47E969466F0ED526,024C3896E3E2B8D4,CF8A698EF0FED870,7760BD23A0353DF2,0983A71E99B3B872,1FC5D0AD83A9FC48,0000CB2111A4556E,A66195CD209E1B6B,4D67A89DA9917AEF,7394D4F03F7EB4BF,183F3BD60624A393,F6435CB2CB67B30E,DD9ADBA7C44438B2,0000AD10EA2280E3,EA0B386349B03B05,3ADCB8969D5FB401,0EDBDBD1AF3BB46D,CA1DFBE7074248D9,E224390160186622,01973576A009DED2,00007DAF1E640C47,9B3F61FEE0ABFB03,BF70F2BC3C323D4C,C1528598CE32C6BD,7DEF265161A307DA,F2886238D52CEC15,E1E9BB4BDD68A269,0000092588332E5D,5CC77FA16AEF2681,B67178E6C7513C27,225B2E4C08339FDB,C29432766F501C05,9BF2D9DEC3BF2D80,891CCB6F95243C0F,0001A0D680E7376B,75B15F3C1272D5CD,4C8BCC658C60B127,B989A0CC76F1BC75,0D29411D2802DDD7,C7C40C240248DEC4,383D441CCAA4EECD,000047C493965C78,C06EE26FB9D32912,CDC32FC1A2276D27,723E492881AD3C0A,45AE685988E9F088,4855FCCB7DDE60D4,8015FA22A5A34595,000039E7B204AAED,E5BB13F23A0AE22B,B1E46565710307B2,01EEF46ACE694C9C,84891549DF15261D,E2D7CD5499E0E766,A668541CBE3359C4,0000027BE122F22F,138797F397066281,D06BA590B498ED35,99BDE9DDA97E22FA,A830D66B2161BCD7,8D1B45C8C31AB861,47D2C92785B22CA2,00001B4B394100A9,64FCECA5BB3232E7,A5352B77344F7308,D3BA633E275428FB,0B1A84342DD44742,B69C8E78EFD015DC,D717E610CE2873C8,0001009C130CF577,1E4E88F673D5DAF0,38FDD95E57DB4DA2,AAAFB03981004F96,8666E4010E1ED8C5,97A66F193ADFFF0B,B2ABC6ED8AE967FF,000166DE6B0BD190,984F2596723D638C,A08A1C9590C07523,872DD9B23C61C4E5,D038422958E2FB88,36F3ACA0FEADAF7B,884C0C9BDF225963,000210D4FD75B710,AF194496793F529E,CA64AB5739F1473F,16F5B776A24F33F2,BB6A017596C98D96,92E8E631E1DFBC91,43CE5C45D4477B2F,0000777F053580E4,0AE1A278CFD8D503,646C05085881F413,95AEEC497420FFB7,044432EAACF0C5BC,6D0C27F428482A7B,36BF0F73795AA970,00019B5D7D1CB06A,8CF1AAAA1528F977,30E061E79074CB0C,A707BCACAF089926,C4433A96484B2488,3EFC2B893CC11E21,3E9C16A82D794CEA,00001AA78C0619F6,6081FF811443FFA9,350E77FDCAB2D6FD,59AB0E00DCE80940,CA3DDE7ED63EE6E9,BC6DBA8E805469F4,9E00842703BDF5CE,00012E18815CBAB0,0DD8EC29C8CA1B3E,294FDFB431DF7FF7,5161BE8DC4F9B74E,2D1DA9FADA3A0D19,6F8E5E8E319CDC8D,141B4E90AB5C35D7,000209DCD53ADEC5,48BAEDD5FD2B1800,F0169DBE8161293E,B6552BB0BDD53BDB,E65FE0A7DA66E23D,1E1131F481DD48A9,2D1D20B8601744B0,00005C6C4116B51D,AF3F77272DBFC895,5566C60CE4E13FF2,6A2F921B830DD150,9713F5E579DB2A7B,EB5DB9E5173B29D5,E149A82C1F4354DD,000229123D77F20D,B67EF8C12A0F95BD,7D3E0BDECBDF5615,02708B77D19CF90E,23E07BCCACF17B47,8D47EB82DC6A1F7C,10A673E279430B65,00014CF38522E666,1A096E1EEB270528,933038843B893F38,88B613C19DBB7467,FEC6DA1CA0713103,240180E56E9B7710,BF2E5E38057F4D63,0000AB82D1ADAF55,64B0D1361328A2FC,9FD323059E7DEC31,176507762516522B,A298240070E60293,0C678C08972E3D95,6542786D3EF630C6,0000BD131F0FFF97,759C2CC404CF2525,1F18C42BB1269C0B,A93FF49AB4FC2F16,ACEA1D2F89F846B4,55D0B3D1B30B72B9,C02DD5194D73EE73,0001B8051FBB465C,21AD4D0C8B3B4E9E,1D4938F15687ED62,C490E543CDE63812,3D6AFEEC9FD48E99,404BDCF332999FFE,C049F5C227B38EB1,0000D4AF9FA64189,4C6F285F6239C182,C66EF01936A7320D,C4FE328637979F04,56D57EDF7CF75EEB,0BFCB5B4E5547393,9B9C7A301E3D6EE5,0001C1B26ED0C82B,4CDBE84D24218BE8,B808B0CCACD871FF,1145DEB3732F69AE,1BDF419C628D4BE0,A17C8038D3E66E3B,CE1DFB832A44C778,0001D94BA500B74A,76DBC6BF1905DD32,2634EF48A254C112,D6CA51CAA0EABF78,0C6328E6DABA4709,1A12187881954B43,BF62D0F7A9F849C6,00020A02C731C77D,EBD258D94F44FB25,4E423AE47CA55F8C,593C2E2DAF3904B1,A6730BC41DBFB765,05ABCBA39E82B35F,684486408C99FEA7,0000C0791F43934B,7028BCB2B280628B,E85E508AA59D338F,75D883E5EF7A65DF,2703E3E40C7C183A,B960C62F477E2EF2,ED805CF81622C636,0001F33CE668DA27,D24EFCEFACBB4507,E859FEA5FF78FD89,920BB19909373B75,07FFF9DF9C2465F5,C307CDC3BC25FC30,A63D94EF63913399,0000ED7041483B84,2A113CD82EF74316,25F3CD1F99B6A469,91F37212B85EC349,41469F7DA76CA706,066CC52A81908A5D,4E7666AFC4487BA0,0000A6A111E280D7,53157DA977573097,E2E41727861A0F67,C2DBC4398C642C6B,052CD3F578EDAE27,DC92BAEFDA69BA88,3E1170C7A23382C3,0001220D031995E3,48920CFA2960125F,3CF3F278AC0415D7,AC6612B4FF9DD17C,958CF8566E1E0A4F,E38F6D00C4CFA722,44DD4D60F7A1FE34,0000C3E9D4249E77,33F4899BFC7C3EE6,C47156BDF2864716,728E6FF200D9FA3D,B5460A8F51DF05E7,F293AF33AFF6951A,85A506D7608A1D87,00010AEA53AAB584,888D19D68AF4E1AD,0D25B0BEB0232714,2DD2984B27DF8BB8,2DDF53B7AE50CC22,1F9EC9C49B76DD65,AA1D9F1F17D33215,0000F0917A6C7542,FBDA2145C797476F,6CD5C403A1CD6D3B,89F56C9964461B50,23F5B252926D5E3F,D4258EAD67277D86,D5539A71F8344291,0000E737BB5EFBAC,90F367CC36133E88,B98A3144A93CC999,440C4DAF9E85252B,1C5EB877144AE6E8,F0DDFC2DF4195E5B,AB7A30B97FD198EE,0001C4B221F528C0,4DB27151549BB609,54736A4DCC4764B3,39B740256064F4AF,61CAE44808C102CE,7876252A843EAD60,289228F92C875623,0001754EF33BEE8D,404EDA8D39F641CE,D870F99C9F39FFE1,2DE9B0EB596C7B5A,22B0EFA0177E2C43,27449E7B89A6C38D,C7B53FC84AC70FB6,0001740C1CD62EAE,D3F26F1F9527B83D,850B832791ACB96A,0FFBDE8F888140FC,3CE0491FA5944FF3,FC36A1819BF21EEB,0C0B781BE5BD3AC3,0000EFA0DB34FD95,FF6345E89328BCE0,8D79BB07F0AD184E,35139A24BD461173,1734448FC20A9C8B,BF667217CA7A09A1,E8EFB503E7196C5B,00022E314F4872E1,6EB8AF1144E66885,A0664F384B2C74A1,BE5C5B9C67C50569,07D763D5E67E0301,97D9BB30D21837FE,7B8E0AC0EBB6AA84,0001D3E30FEC320C,386503F306755803,0F57F11BE69F5A7F,5AD5D1AF653FC2C1,EF66E6557A3CB2B2,97E4B94FF03DA531,1386737CE662693B,0000F8971469D755,0F04D0E8F962ECD7,B56E44FE43EAA2C2,170AFB64F110B4A8,7A8306ABE1822C25,07CB27D274B8FF21,E3FE38F8CE6A7B52,000172EA02AA50B4,0643C9B06E08CC66,2B87BDAF4E9388DC,D71922CF1672D873,E28B6BF1D657B51E,4EE86292969E26C8,774FA57CEFDBEBD3,00022356CA9281DC,00CF4DDC5549300A,E9413CA6F4CD4100,F7A542F8CF3404BA,439D8AC2A6FE8751,20ED88D8D653E5A6,3A1D37F43C306D15,00019CB3FB40E64E,30EF0546FB21C004,3B818951DE4FB322,C765E13150B1C2D5,D678825CF33E22EF,32982733B22CB893,103D3E24F664B502,0001C359727DB042,DF109C4B080306CE,1A578D1CCF3FF3D2,55602552343FD214,7538DD131E9ABB7C,D72C3130CB9A9C17,BA59DB23F49F0A09,0000CD2C2968CC5D,7414CC5229185524,ACBFC0F4E77368BC,D9E98100179F527D,9E769DB09985FE03,C782F37B113AFEF5,DDF36B5E5F45F31C,000103405AB2D43C,40DE33CAC0717450,C3B2E413E3A0F123,E53E09E084E1A6DE,DE1546CAB7A06ABB,07A16FFE13407D29,492B4FC12399CF6F,00001219277B863A,FB9A3F094C746CA5,81E2E7491C7872E3,EE7B2250BD534FCA,601224D10EA0C48D,2F34BA04B8B07DD8,6DCFFB47B6412E5E,000152AA294A9DB6,3DA4FB2FBD3C0BFF,F0D755D71384CCA9,BA2A155866B5DFDD,AF48DAD304B56D63,7D3C7D260FA4B19B,B06EC96A2148DE61,000015C585D390AC,8EA7A8FB6C35919B,7C75E88ADCB355E2,2849C06FC41098DE,F29D73C749CDCD65,8FF0B7A11F3AD0EE,729A27BFB0EB9D73,0001ADE07D8F5DB4,CD3F00D2031410DF,71A4FB9A0CE0800D,02B3BBF9AAED9501,CDBED9DD561A6924,B4BA31215E9AF8B7,E671C61CEE66F24C,0001360681BB1629,C4E35287B435A223,5686889DEA700377,D887EF0013EA1713,FD36C4988796A889,DFB874596A4296A8,C15C9FABE5C014E2,00016DC390DADF51,EF6420DB718E8CCA,022FA53308FA56AB,942E1FABB5C82FBC,1F024937482AC7B8,A13BA11324609DB1,EFDB248CA66B462A,000072F06D79F8E3,9A4DB208DB96B3C6,F193B9FD64A6E6E0,681FA9DC20DB5D3E,104B991877536BAA,6F1EFDFB41FEDF60,DF88781860A4D51B,00022A463C0BEBCB,ED6E3F02C7C46FE6,4C7AB61159472360,96E35359DE718AFA,CFDEEDD57314E67A,294929D4C604D0E3,1F26CED647677727,000219FC25DB3665,CFDC8FE63B395FB2,0479356ED76587F0,7941A8AA36E594C5,9DB6379AA5BD5E8C,B5EEEE5C3AC553A7,CF2C83741C73FEC1,00021559AC288838,3555F7322975B35E,D2BB2813B031EDD4,D383D98C41C4AC95,71E5B04EC5DB2483,C1ACE99F40E7C9EE,D127B2220B5C328F,000008EF07D64B36,8F9C314CD1EA55DD,0694392EBF98B8A2,0B251111C6791930,4603DA5542CCF7A3,A8C11246DB27A30A,1882391142DFF5E5,00014ACB5655C154,89C7E784BA9DFCAC,7AC5FD56D285ECF0,1EED5838A9744BF7,411FAF6DBE63D539,A6E7B243074FE4C6,0B37D3A6746DEFF6,000069B843253C29,CBB6CCDAD699F147,E407FD6CD2429B71,FFD8F22806765E1B,9BAAA7A037FC0C2E,F8373E117EDA3D78,CEEBFFF90BAF3B03,000080E00A8A1753,1DC7261C69DEA34C,2D366AB3AA66E40F,8EDFCF071C904EFC,60C3E72B5BB70A9C,4B56A53C01649C2B,DEADE364E0023CA7,00021D6660A39A3A,177D4F641E8C4445,E9F8A0EA417FCBB9,A39BCBB585D54F6C,AD7B9AC3AA5193F4,BA8B961E256977BD,BA756133BC0CB8B4,0000813871F29AC3,5DB62A851952AC1B,9B3F62695628E9AE,6E6B76578038E04C,E21CA7DDBDD5830C,A3D21C6FECCFBFD4,48CF797C096E0740,000080A32146236A,7CE03DBFEE575E24,B5502FA503B9635C,F6D7020410A9C247,AE731401F0227220,626FB4B1155D4A2C,D3B4121F356F92B6,000118FCAED5598B,85B3E3F08124B64E,F104133C18139ACC,28902AADDF6361F3,E8DD45B08B900D27,9FFDBAB1C0E62AA4,264C51B5BE14E180,000069BDB668EDA8,719DE1EDC7D0A421,6BC959BD69519685,B107B97645155E0A,00ACC868A7936881,050F46B9C022275E,2C3D1284963EF67A,00021ACE55D2850A,876A9B62899AE70A,A597032DBCEE2638,F80BDFDD8D6D24D9,6E8C7C9277CA1A72,9F6B8CF39318805A,DFBABD16529CB1A2,00012CECB1521941,E5E32920DCF5C7E2,977B6818D9225CF8,04C2C1A90AA10045,03F6BB1CDAE29B31,616EA6FF7C682817,F6520D1AFB4CBBB8,0000543E4A838328,2D820EDDC0651F7B,62013B028741C437,1B35E956F9177AEC,935EFADB19A405C0,12DFDAF2C5348559,05279F1FE21C8FBE,0000363BB39BE8AF,6CD3519BAFED8441,B38340789DEB45BD,AED44626481A1A53,46B118FCABF566E1,29AFBF3B872A027B,8E2B400D687BF795,000146EA999A9953,8D8E09D61F8B04BE,3BFF5233A5B23972,876234D2414CAB73,30F22C61DC9E5B6B,C9BE7B9418C51E7B,669DD4A7F3D7D45C,000109D73460E8D4,87A996347FFB42C3,1FDF5D79B2F4160A,BEF1646A2FE69D72,A8AFEA914DDE982D,DDA0F66F8ECCBBFE,7142C3A7533328FB,0000FD86470B37CC,7BE54C5FBF393E42,AD8EEAD71A1B0DF2,C7DF639A4B3E6D59,5CF51F3FC9BCF254,924BF07DEBF89205,B1FA9B5DF653DFEB,00009AA47F4C66E6,6B65C09FF1BF37E4,8B67A6412C1396DE,B1C3DB99CFC79ECE,2AF2FEB2FFD763CB,8CDA48BEFFC89561,7EF4ACB8820EB11E,0000C295B5E3C215,04FBFBD071811C44,7F9B332378872F9C,3122325CD5EFF137,890B5D9091E1FA1B,1AF7B7698754926D,BDEFC6942C1332CD,00018170143CDD6F,037B7B6E086E1259,2CDAC4FA9084F90C,07395E53E950697D,E193731660AB74EB,D2D9F2B85BB07E5A,9A24A36BED7E7169,0001D7D39DB0756A,C53D6B47AA1A22D9,4C31DE2344308D97,B5095B8FD03E4AAF,47AFFD594571C275,44D4DECE6B311FA4,6C04202276C75ED6,0000031107804501,5C2E02BB72CC67C4,199056847A147B95,1F5E769F5581E04B,2AB2DBC5984A080B,E892CB86C4C3332E,81D1F64438ACEA48,000189D5B472319C,CE16FD8336A5F12B,2D0BD200C05DCF17,759D564FCC3D1D5F,B050DA5152AC93D2,4A05AA3503015256,A9C2FC326D770AB7,0001F88396C8570F,FDBF0DA4DDB14AEF,E31C97CAAC2B1AE9,C1EE53A7AD179B6A,EAFBF7A9FAFFAF8B,FA0A8C02A4F7B0B3,B763F72ECB7E482B,0001E53148120D31,4D4CE2364C6A6F44,18F9CD80BDED669A,A8BD152FF08103AA,3873E8B339B5EF4A,18995B6BEF1E37A3,A651B0D801AFD341,0000674753C6055B,71B25620BA2351E9,470B289271A90100,5AC9214438915FDD,4EC4A230188AB8D6,023B64C76C199BC5,98DC0D68F585345E,0001A3AFF392A192,51B86B9C5BD849AA,86066077994AFBDE,BFA165C507A052B3,0F666F3D99F8DDF0,3DB1410FEC0802D3,EA21E37FF1B89A72,000181B3FA7BEDDB,7CF9C503C698917F,6D29EAC059A3FB6F,0EC171C079D4F79C,3A63EE1ACE6FD938,1F7CEE09CB71B0BA,735FC8D24266D78F,00016BD0946D1735,9B1F80F7C1A38D1D,02B00C41A24736AC,FF73205A93F649C0,0EE455544367650C,81B91666845B9B7C,65A4B598599C6F28,00017A4167D393CB,5FEA7615E1586961,F6CFC55A4E3FF600,AD12626592D51E7E,E4E9A2F63398AA6B,660564A431C03F58,80D3F23AB2BC5441,0000BD5D2F62FB42,7B8D6C84C1C173BC,1F855FBC9D7A2626,8A43C1EB4B2A1186,7E05D617AE981155,8C6BEDB65D55B368,8ABEC0F8DA0E19BB,000179B122228D23,74F79E8BC6EBDC73,EBBAB125D14022B2,2ACFA700BB2E4D24,3260C9E2A9346D87,12DE20BE9B6EF154,9AD472813D28322F,0001A843F9E12AF5,57FDAE3875A8750D,6D18736EA187ED61,6C8AFDCA13C92443,F118921FBBFEE1ED,1D5626A7695F376B,599DE0B91A589A2A,0001FBAD61F71587,72A9B33F06B83EE7,3D791D5E45E1824C,2D533C8F6861664D,FBF508F845035F20,7E4C27072918DBA0,EBE602F6C29E73E1,00022FCC4BDD7B42,78CDE4F9D6051327,CF10B1620B661D24,98D4FB1F5781A67C,909C5A7FB50BDDCF,FF01BF5791090F1D,8DFF2D3118FBCB63,00007F70C09D2EFD,CF2EDABA8295FD20,0A6F8DF8CC583746,FDA751D82BF865CA,2FBE1C53DE2C0424,4D55ED1A61339F79,B34234F2BFE697C7,00002E5856979B09,8816C79C8ADB0ED4,9339FF345CA7C8A8,535DC632C3F597BB,3EF3D718CACCF0AE,89B774C401AB4891,B5934191E05CB2BC,0000EC1FA11D8B68,8AB1A1F70385C52D,B94556CF9BF3D0AC,B4AA88E6819E5E0A,6D319409884BFA33,E4189021F087C029,15A89A91B12344D8,0001B2710E8F329D,5298F797A27F5150,92CA69210336675D,5DB8C32FAB48C020,1480138C4FC22048,E6325C0E69BE2148,EE1FDA3493C7CF34,0000197B8AD2FB15,287360F85DE134D0,F7BF6A242A2034F4,9398781FB7AA3F70,5B9D567F433BA060,C330328C0593C768,CE880153ADCDB51E,00004BBE3955FFAF,2BD285A7330F2945,9CEF6B1356206C9D,EE6C9617BBF264EE,B06956627D3BA3BA,B94687FADF39CFBF,117E6CA9CBD434EA,0000D4FE1A24A740,DC514777F5FCEEDC,51CB00476BB7B247,08D5E114884D6551,20A4959B8C8F1761,2A43692EC48A6EB4,C00EDA522A0E1380,00006C4DC102325B,AF0633E8A9E5527F,E2EEA66F7250EC0A,6CE7F2C3CECFDA4A,7BE5543EFC7E0572,1BD3EACAA7CB25FE,62B3D7DDAD19EC4B,0000F99063F2F137,450DB5A186E9D34B,8F37B9F2425D8EE6,08893C0DA2AAB45C,0FF81BFDBA648AE6,A40FD5C504D362EF,C04BC3C3CC54B8B5,0001D5C05322BADB,01F72B005F6500AF,718EFF708D70552F,3C8A47DAB7154E8B,16434A662EF12A6F,C2F96FAF1A3FD0F0,B3B3C304A6AD0B20,0001D6C6319FE55A,A09ED6D834081483,3D961759E80AACCD,B9E183993FAF1B95,3ACBA59ADDE57342,568DCB21DFF38F13,677FBEA6796492A4,000128AAC311C758,308133220F4A5675,D672D989540215C6,9869F3FBCE75871F,B7708AC22FBDB5E4,9CCF68316022F1B0,DEE2C6A84E2C5D87,00019878F83A0035,9310906A4C863A71,7DCABE89A78E922A,539E8976A185C160,6282B352E69009FE,EC000B175141C6E4,93E7BDF374F90EF1,0001628788CA99BE,B7F9BB65D8BAF28C,4C7BFA14B8D3156E,34FA213E1E1075F2,1F94CDD1AB61A46B,9D63052543E45312,2C9AC5A3C4E98741,0001079E5A2858B0,286787778402A292,145C63904754316C,1FACFCC71C294471,14E7B408D394AF92,1843A9224D6B7912,E88598FF4C7A96BF,00022F1F3142A93F,10174710B4AC3AD0,7AA8AAB51CB04D78,023C9486761FB2E2,0F22EA5ACB02192D,C47A9ED354B2C950,30F44322C9CC2354,0001D2AEAEFA4BC7,46DF8F21E4F31262,2222F9F0CFFA1405,9E47AC6AA5BDEC06,E0FF3ECBDC073EB8,4B3C858154C05798,C81999835CECA0F1,00008110F1B23837,3920DF6E58D73FFA,3770DD18D63F632F,5D39D84AFBF42931,02B67E29F9E13A52,95804445B117CC6B,EC4645C1B095E737,00018C16B829E158,B65AF2AA6DF1D920,8B26EAD8E215174B,B427002CA16FBB0C,7E64DB0FD00946E7,59A510B5763F161B,4094A25A1C2F480F,0001EA94B1C47662,B91425437778E7F7,8E2EDB1C49C16B0E,7A2785F78BBC5293,3E1A368AE6C66246,8161D1C4013AC402,301D1316C90FB6B6,0001BE2D2E82E769,1016DE3C0F13542F,109182BC1B760757,14680DF44F5A0C26,C8390A3962F895E3,9BFD11CAB43F31C8,DE7CAC87490CDB0F,000087163AD58642,ECE7A259AB7107E3,2084E61BA6A31A74,F1DB96C020F9434D,472BD63069CDFB41,B3012F8E23E8CBE6,138D20EB3D3F4516,000140F7C34576DD,71D64143FD756C8C,737F9C70493DC8C9,BFA869BD0077D5AB,32F7C76C19C2B3F8,185B8DE9CF33138C,04146A5ED121604F,000199DC7DF43EC5,1153FFFCCB348CD5,CEBEFAEA41DF75C6,CA8748480B814868,79E2C99FBE9E5880,2759ADF9E306DFE7,5446CBC43774951B,0001C2895200D4DC,DACECCAAA3C2A7CD,E56712DACAB019F6,7955D43F30F61063,9AC9F05FA4ED2841,65B5339DB6048BE2,0260CC3B4AF77C5A,00002F347551F8DE,8D58D309EEDC486F,112C5BD86E9E0FB1,858BBAA717F59232,658B8AF8E7B62FBF,88FB5C91F4AE85EA,22A6C230F9C90815,00011C19CAB72E67,1D90480AC175AFAF,7FFC8D58B9BC7EB3,827BD1874A612D07,9908D51007A0EBA5,2A5D23B758579A71,BDFEFC70358620A0,0001738C2B2FF3D1,C983335328420E5D,79C286A5071BF4D2,DFBDC55D634338E8,697511718C4AA293,AF5CF0B482CC875C,1EF2E2D292D0C957,0000977C97D9279E,0C9F66A0683B8C3A,54EEE9D8BDE994E5,7ED22AFD0860F6AD,711346E4E1C858C0,A692118CF50453E3,3036C4A5D963CA83,0001A132C155E430,0E6861A1FADEB275,2075B10C5ADE9821,46A86544757505B1,6BBB476E6583AA41,31223859B2B39372,19F39E6BEC13D373,00008C68B695D2AA,CC2FED47AE78DC2A,BC9A2CA6BD18F4C2,CF9E50B65018980A,BC6A2DF109C0CA18,2D664A7D1B84B2EE,25D97DBC2F591D05,00010EFBE11F08C8,4ED30A44A7D583B9,6DEA0899A47B6EEC,65A7C972D43E26BE,1D88B5C2F65B6318,7AA7EFB82F1BC251,17BA08A2FC3B1B68,00013F416D8C9998,6C6AB7915DC56FA7,44A62D6C0DBFDDA9,932849230E2C950E,F5515D4E0A038407,B700FB5318C1C881,68D705F045535BC9,00010C67C833867B,614078FE2C65F581,D10FC22198596A48,C12E3D2A7AF855BE,19E0DBF641D0D61A,95BE419AE23B904E,EAC47BD7C8A0C503,0000CEC5ED309E4B,DBCAAD67468C1E3F,E3868C7D24892DD8,8532C53E9F064304,5A84E56B3DB5641B,8F7271A31C4328E4,1D12EA24F6EB934E,00013D49DA82F2CF,095F6F7D6C4F9A54,082CFDA459B67E23,71B78784D9AEE8C6,537179EAD94CBAC2,B259E260ECAC9463,776C673D5A369033,0000EF62D95139EC,375D907A4DB2A4A5,8361B6F14332735B,339259421FAC2B08,E71E76267B6A20F8,E373D3575AB2C700,EA061F809BE71774,0001F8714D51E389,9DBF97926CC0CD11,7F4D4B16BFFAE26C,1A1C19B192F95A1D,C24B558E10922174,43B91A4D085C41C6,D0D9DA2EEB1F8E32,00017F3E0119DFC5,952FDD73F0B5DECC,1F510CA832EE938C,76D42E3E7895522C,0654856DD5E83684,B1F7480F90591155,6E41A748338C099D,00018D9BD8953D3C,DA29A1DD58C7AE34,977E44C3210B70B4,C51126523427AA05,A2B05B44C4803A63,378EAE846D0312BD,D72C2F48D8745C23,0000613C40A1117A,9F9D362976F40D96,D99BBE928EFAE86F,0077C1E91EFA831B,7E8A0807C5E5500E,FAEF3C566C9D024F,B9329BD4D006F227,000117B661F0BB6A,6F9BEFA1F740BD1F,FC9D3D553FC31FFF,F233FB831A6D605D,E35458D0041A4005,7EE3214D99F6A4A3,4C3FC466835214FB,0000CFA3F7A992E3,75225C779135BFC5,3AC1A77E6211EEB2,AA3E38A29008064B,FACEB3724A426F9E,E5B617D1110215A2,F5AB629A850999E7,00012263BCDA0259,21AB8166177C053D,D97C2DE0F5066E60,815E0FBEE13FAFAF,C8C1A4D7A2F9A10C,7700DA6B212FBEAB,D2E5C0650D9D2329,00002A8FDEF774F9,6EE28B87068A2E09,E1D44A98F93681FB,9E9F44B4F47ED0A6,AE8834EEBCA4A3C3,8E24EBD9DF32342A,50F0E7697122BC91,0000839792CF2644,297043419A52B7B0,6D6105739A378A07,423D295874F14F92,C3250F49F78A9844,3A5A24F25B2AD265,42BC8ACC48453D02,00022C6A5F6A79D9,D13E6CA77320AF5E,79BE8D435E44B0CE,133C68BE90E8DF37,568DF78A4A6002E8,5ECD671867C665D2,E0437E79726F7321,00013FAF53501647,F838BCEDB3D4B830,A8855EC221E60485,507CE532CDDEBA60,757A9CDDCF653E57,2E544610E9D02CDE,717C3C2A4663E432,0000B304FB9B47E3,6A7A2678C565779A,A2A8C43404EC85CE,DA6C3C4727D8C1BD,95C40C06C2D61FC3,344D31268A5E09CE,C5F675964FF880A5,0001A6C80FD4975D,5A8F68B8B0E78675,F92F400CBFCE87DE,6D35E78E1BDE0830,03C1AB45B5BC2EDF,0D1E2E249C9988A2,420461DEA4EA9A6B,0000ABD4794DD096,535590A143DB7CEA,F61CEA217FC37F9F,6DB8E94682A16E04,21E012004C8470B1,6A070AB20BA37D2C,6C9460E143D3AA3A,0000A37222A352A5,D86C4BDE8031F281,6BF12C0B987168F8,0A7F557020FE57AF,69FB1836B6380366,CBE1E7CA931C623D,323D1C387A1B4789,0000B0F1296A5E2B,7338F8B5C7E9B29D,426B5C75DE8C8DCE,B67063F4FDC3F23D,7C5B6B7971793736,CC4208DEEFDE9453,025166CFEF257497,000132B040B9AB59,8736318961941A53,ED6E0E9635E86131,7CA40E67B2E9AB36,BE606F2AC109A825,4F2B1198250D908E,3225091C04B09195,0000EC693D0AC3E3,4F277C9E73F2A111,AB607A5008F2D8C2,69A89D6B649D42FB,88E482741647DEE0,371280C3D5B669C8,8DD7727C23D5AFE8,00005D2544E7489D,9754E0126F38BF6A,F390592EEBBD8E61,A2402F58D7DF42BD,1CDC8CAC3014CAAB,8A2BA7F2186E0731,FF5703BD43832136,00013E474D088E22,34DA9AB4DE5F1482,9F66274A5100F430,3D1F1DB437CEF4FA,D949DCA4ADD35587,30B90F9AAF9B6AE3,FECE70370DEAC3C7,00003C9F1FCAEFA2,325D970D05B82478,6616D62DAF53E39C,13EEAAE4BD9A136E,7EC1490B48D5EB2A,E41006D47269FDD5,54ACE7AD07CF749C,000212DC1E595ADF,4F1521AC6710C6B1,4A66FC8804A125B5,B8A76D2289435294,EF9B239F99D9F582,EA91B734AB8307D3,0653A66567FF7747,00015C168BEF0B77,50C01DCF3905A757,E1CE4320D521C745,53F0757590043A6B,1A71A86EB8A6FD2B,014E72C72B290D75,7630A002EA8B0F0F,0000CB8375A779E0,3590ECC749A88583,63D247632DBF7A30,E841493B52CEB63E,165DDE01BF4E7E48,166EFEA23F42EB28,5E6CA655F80BEB35,0001AE8F655CCF19,59CE81A200D56B02,9B309C8DB394666A,6CCB522E3C19ABE2,AF3CA598140F2A92,79E3695A778ED089,57B667DAD3903DCD,00017EE2D370992F,7404181C945C5E07,C0F768D3F50EBE6C,D718798D962EDE01,B78D513962391606,A4C2DBAF6EC8B84A,45174F93F593AA97,0000CC1E32D55183,984C581089CE807D,A518A730544F9DB4,7C5AD283E4A282D5,2BF5DA606E8A633C,11237320F34C1EBF,780EBA8DFEFC73E9,0000DBC1A9E0D852,468AFBFB812D248F,4AC18AD78729B300,4A018CE7BC3039A5,4E85B312F13EA169,0897EF8CC903BD43,BF44CBC3ED75C48F,00017A185433CB1A,E1A67052E24D71DB,47D6B754C481AC8F,30E28090C771C4CB,48BFA5E75E58CD12,B396C1633BB3D263,9265A047DD665B54,00001F9D27150DEC,6A6A33A4EB026227,4F502D7EAFFE6205,29909B58EA9795CD,2E5A376EC650CF1C,8481563236BDAE35,5D75DB648B1E8C91,00005B21E1AF5724,DC685D0DC3E26B9B,DC9FA533B337DFB0,FE9946BC9C7C7AD9,A179D6F9A6433F8E,1ED2A05EB6E2BA47,9E7B699B1B65CAF9,0001215D31C38F6A,5BEFF278C7DA88BD,C839AD06BE540ED5,58B153B8FB3C09C1,1D80D8A58B989AB8,D16F6E81D3CA2D28,0113CEDF44C82AFD,000210BD230441BE,0120350D86A72504,DD751D0B26754680,BE37CF40A62027B0,565CA751D58D03D2,74A4C1E6AB6E70BD,300A8360CBE9D081,0000EF6AD7B8693F,6370ABC4412F5D23,795A34DB98CA5043,72A3CA17EA7CBCFF,1FDCBA4A976A0E6A,BB23AD9481B50D15,BC36ACB5975F75FB,000206ED60C2A89F,592E0D514B16C38F,767D73365858A10C,7055B50F355D6327,5AEF8B49E5D98C3F,9425F76AC4FDA23F,5FEB2CD69843E5CF,0000B7D4BB0CD8D4,6C1CD6002AF4A7B0,678E5C40558133A3,65CDF7E824C8B295,1AC3487DDE039037,E65C273A7AB63496,212DB48306A125A4,000136B991A79A71,F272CBA3CD86A1CA,F822B5DF9F50F36A,CD8149DE291894F6,C216223FEDBB77F4,5DBC34EA9A932BB0,06C41B441100ED30,000080A945B1C46D,21C81793E09D942D,5AB9011B38386BD4,4E726ED3AEF00762,758C643254DCD59D,3245B16C92BD61D0,1EE134BFC232D322,00005EFF9210CFBD,01358569E74C3819,61701E48C29C038A,F15BCE69DCAC9B95,2F0CE8A2759C728F,70FA1C5C1D3A1D73,53A549584551E036,00002E7F470BCB03,A22689292CB603F4,A2AB8B080CB6D5CB,CC062DFB57B7F088,094AD1D973A7E748,9A6541E2DB7EE6F1,8FCA855F8D648D9F,00013B33A2C2C92A,CF19198A0C367FAC,3C90232BBAC99377,0EB13848694390E2,04B85229FEC74DB8,21978AAF0E812A2A,F249CB7045C3B1E1,00007B170A4480A6,2A14A627C8E7D3A3,9592D3608A2D2640,0CFDC65013201699,FFD90242B7637E39,216E72B056ED0F5C,DDBD4E097A99BEE7,0000F086C3AAF972,24F22285DAC19C7E,F3777471B8DFB6C9,8F7845AEF2416084,72D3161A169957CC,87EDF60EC7CCDE6A,31976374B60FA750,0000290B66B05C0D,9120C07565546675,CE2891EDEE9A1CA2,D5676DA332F6BE73,671E4541BCEBFF35,242AED038DFF4C5C,3A69E28E95A7592D,000077A380B1599C,BB948AC7647F95DB,2BC3E282693CFE73,39D6DA4D7A206F07,845F4C1ED9901CD5,630F130A33A6E54E,962599D90A70697F,0001014F0432FBBD,9CF0E7C4B8A5465F,50350A811AC57590,884C66425C9C9259,3F1FDCE4565E1A04,75FF00229018CFBD,429253DBA75C36BA,0000EE660DB6E671,A42C5B2FE885B3D3,0C0C4F6C0CCC3698,B9B17104FB1E1DEC,CAAAF27A2F8CB69A,8CA66EB775641EEA,EC6A789BFA6E1503,00002441FCBA8AA1,DCA499773B929C45,C3A20FE6438E8B5A,45A5AFEDCC29BAF8,AB9F24A88C1E411C,34EDA03583918C8F,F9CC8280894539A1,0000EDCF244632AA,228B427F42466077,8BF746F0541874BF,5522B86B746370A0,BF3327C5BD107DE9,FCB7CE79B7F2CD69,4E17124213832619,0000EC8562F276E8,7A437C2D203EBE34,0684466D2F9E5DB9,56035D1EADCA8502,A33CC63BF68423A0,8D610AD2CC887089,7F2BBC9CA0872EE3,0000301FA550FDD1,6DC6E08748E8C9C4,535413D9D8D41468,2CA20531A67DA368,600A164B7CCA24DE,B8FACED9E033DB54,75B945573D382744,00012EFBCD32F2A8,B0EF8889C1E7E333,E225C16CFF150372,414E8527AEB622EE,FFE846B1DBB2EC29,7F46867FB4E22F04,3E53D47B5FE1D5CD,00003FA5E1A6A210,D0EA73BC61DF2CEA,F453129680FAC2AF,8BE5081C22CA1130,49346C79985BA836,C42043D67EF0F7E6,D5E436C0F8DF0D4E,0000400FFD3E2529,250EB74C7EE09775,A8FEEEB668E7F1AB,306C611C86A9D870,FBB26E1F1A9D12C0,CA35EB147792F79F,5F6060F64E6770FB,00014120133F3C09,CCAA61E9864982A5,F43B9182A0814DB2,0E819AB728F47ED5,7948D9D986F98292,F7D58765948EDCA5,032CCEEA126B2BE6,0002052F68023386,EEE200809F944896,26AA48F4A6AD5970,B8026C1A283E771C,CE2C17A3453E89EA,E137224507DCB55E,1C4C29E6F74A5D43,000171D10B64B3C6,96DFD30EFFCF90B0,09E25F49D1C9C8D8,4DA91F6504292BC4,8E19DD5670172626,3B7C8C2ABAE79EDB,36AC6C6D5D51C864,000207194D669579,095EC8BA3E346CFC,C1CBD6AF75C19593,488A8A16DFB80C71,1608F63CEBF02B48,03E8E77FA840F9AE,92644EE655F4D242,0001DFCACAF898BF,0A3EF5E88A4AF28D,C1733034606F3272,614E54173F0FF070,A5FCFE30F26F1DCE,0ADD2C87C76B4E14,94B1C85E8CB2AD91,000117BB53B682AB,2B388F44027F1CAA,21029FEA571C7627,E58FAD890CC9DC2B,8749FA1063E1F2E6,44468E8D0CCCAD8A,879C0BC0AC9DF4A1,00013390FCCED3B3,7089F618679FD6F1,27BE7E43D5F65F4A,395B1F2E138815A2,F5A8B1FDE031B0AC,33704C8B3A534F2F,443BB569E914F1FF,000125BB443493AE,1D1973AA826AA5FA,AA10043558E12935,50368312F6EFBF3A,6132A94DFD9B6F7C,FA9DCF0023C8AD70,FB7E426FD9942777,00008FBB48069507,2BC090C68BD8EE0E,764CE58DBC86290C,342F2B4087315509,6D6C844D366792D7,0DF4B07FCBA13221,2EE780CD2361198E,00015B362A1BE646,E7F17209CB8E1A36,DB89851D0CB308DB,6F04DFB4ED40D4E3,F44ED784565BB9A3,9D5C4E1C365D6A00,6A0E3B4F7B902C74,0001BF0885702CA6,182935E4F6661A44,ED1FA57AD444D8B6,B2817CFC86EB7B9D,0F27BA78E19D3F6D,8CA6988F25CB8F50,A62E1A0F6B46F3B8,0001D0E7C858F6B6,8D1C7818D04382EA,19A4DE6D0E912AC3,5C7BF61F80264FD3,A650F9F54BC86321,8F3C6400DFC78293,1CFEEC739B8AD6EE,000080F69214F75C,E85D6930BE6FE72C,C80B8F443322C878,E9C2D55B597F1E69,5B9B098E9B057487,DDD1A8FD742EE48A,2D9C81DB9A3CC4DD,0002341876BBA9AF,A2D713CA4DA69538,EFA983630A202D49,F58532E4A24C3A1F,A07DBA43E5532E40,AF7492709CE1A512,2A26EEEF9B7C9FC4,00013E1530C78719,E0E26F23FF29A66F,8FE04D27039CAE77,8E7F0F5F6E1D63BD,50A05F46864DCC87,5A20616366659FBF,0F98F63A203063AE,0002296B7724AE91,CDF1E9A176A9FB83,D0D821C77909DA59,B95C5CC74F1513D9,1899086C3FD8A3B9,E5B4E4F7862DEDEC,72227ADF6DD4E281,000136FC0FBC098C,2E089CF9935A4672,07FC8F4556BB1194,07AD2837DECC6176,1EE96BA08F355F31,189FFCD45A5E4ED3,E9BC5D7F4E0E3231,0000B675D32F43E7,722682B08E26249B,625C205CB137373C,773850FB6267C440,117CAE101635E96F,400FA1C9D733496D,43CB9098CA3E5E7C,000023A7CFBCA4A8,055F7AC19EC3417B,DAE84EFBB5BA989A,606A3DE840E41724,6113727829E7C873,4D60A8D053982161,234FF0FE7B22D35A,00011B714C308B88,977EFD821E662F10,4ACC6A30C04E0052,4699AC4BF5ACBF3C,AA51FB8D509B24DD,D7067667009B25EC,2DE710ECDB091B4E,0000CE727DDFBC0A,841BFD1407E4E26E,340A234FF09F43C6,6BA9B5F55257DC10,17D609C8CA9EA848,4B0B823418FD637F,80862168F9703C21,0001275AEFF12068,FAD6AC9BF8CEDF9F,3303560E613096C1,10BFB22C07D6BF59,BD46013D14408CC5,4F95F951D67E12BB,23854556E0A53CDB,0000A43C1453AACA,4DE8107878D93522,4671522019FB4088,698A1F6DA7A13F7A,FAE56702E5E45235,9D7730557B28D017,99A66B9119BBE749,0000AEE6C5B38462,4FB4DAB428834060,E543D0DDF03C2DF1,C29FE99C65FB781C,2DD5B12060A707FC,034569F0A8CA5EC2,9E3E88A0B8A07525,0000B0BD165A2610,AF3FB7E7716795A5,7AD36A2F1935F422,B1F82BBE3B41B53D,691D602490E09FAD,D65651575044CBFB,A5812AC05BC3698B,000023B85A4441E9,80D9DE02084A59EF,023F12E8C98479A6,EB37B64C82DA5A36,DF12F6FAF10BDAF8,189B10B584B9104E,C35E24E6F1AD4D55,0000F0FFDEBD1E60,6CDE861409C8C890,14FACB12CB84AC04,AC4045A116D2BE7D,EDB99688BBC3B9D3,53C6C6365329DE0E,5368F48EC3966CFE,0000039378A557AE,2799F97DF597D592,49C07A3BB43ACA35,ADE8D932A952DED5,DE1624F6D647D759,4DD12913D2175293,84239BF5DA2FBC54,000185717BC7D9CF,1D6F5733908AA93D,A378028911B50EE1,D9A075B956A69DD0,E5B9503F40C8BA64,AA44787CAF25FA2D,D8757CFD85C5AA92,00009189A25D54E9,F7C883444A28CCE7,4CCFA6EFEBC19E46,F4803BF962B82674,39733C4E3D599BC9,F6D74E81D87FDC20,B3B7229C82E0685A,000079DE2551A5AC,CA683D19CE892DEE,8D97C4CE7B878968,0C5B3CF751B05B6A,A92027EBB3339D0F,84011C11D8EBC1A9,5D6C8BF7A1071EA1,000093CEDA0D129D,D85A0BD98A863DD2,71963A806670B5B4,3D6639FA66817A9D,40119E8675733FBE,492297233F38615F,6B7F3CD9035A9B56,0000199C23F41964,CA0E1F60591CEABD,40FDB462A7BFDE71,42C032A44663A55B,76D408F7E692ADB4,B1C39A4E139318A9,C5B8FAA418E24952,00017B161902517D,A9477207388956DA,01F0B590B9476C90,A4FD636879065157,727D597D39B692AB,0E9436DFA169AF61,5FD1A0A263D94695,0001A2D645863983,910C7514D7F54929,A7C9EB6AFF759BE6,B24ECDD9800CD022,57FF6ABE68AE3D0E,D4A23AB50E0CFB4F,357D9A617B66CC73,0000DB843312FB2E,309DB7349207FFDE,25FB41DFBCAD1316,925C0748631137BC,6C279324C574D9D0,FD3BEF269FA2DC49,0DEF90D1F10221D9,00008E6479BDCAC3,6C1384F34C25765F,98448695EB511E99,23E92E9E05006990,A3912E8922FC4E24,EA4AA2E4CB19C120,17232578D35C569C,000192BB46F70239,64CC26D0FA313211,9B9BA33A5D033059,184062EAB4B72582,3679E17D8C6EAD22,3591B6809D2D5AE5,5BA93B62EFA11615,0000A6EBC90BF042,50E4F4B98821D4D1,B575CB814F310365,2ADC07558EC10159,A6A89B5061EE63C5,ABE4C0C41FFEF67F,2AE3D2951337E71C,0000F6050E9D52F4,513998B93FB7B8F4,F6BF005E2B8A1C25,FA82E07DEE27C541,887FC0B87FD94250,DF1F205D4C14A304,54C72C8DEF7202BF,00012F43D5E5181D,3CFB605CE4A17332,AAEA040B4B405D5D,878034393AB5BFCB,058A78023319CB60,7A59CBFDF4CBDE89,CBF4F757C7001F7A,000199287F695931,E3354273A95E742F,72A24FE402EEE0D8,5CBFFD0C1E600473,46CA38E9B3DAEB14,E14C54A93AA29A51,25FC090248E113A7,000116C76B8D8C5A,BC31759460FEEC2B,34F66F615176310A,568703F737BE1B08,178950B77374354A,1ECD99422103E64B,3C3641CABB5FD1F3,0000AD35C5A69ED5,4B92C984A3361EA4,3BB460616BD402D7,83740FCCB35EFB85,ECE0BF66C6349E56,45C583D7E4787BEC,93DC001AC9B3041F,0001FD22E6A24FCB,A23DEA0CAD67572D,8966D8DE6459FB88,CA42D02A039FE5E3,AA6532B6D3A687AD,5F949B6DECCA82F7,0DE95845ADE1BF7E,0001F8DDE7640597,AFE2BFC74BC9F271,A504017123B59104,8A6C96AD0066E3F4,60EE8BC87541C843,8FE520155C87252F,38264C323532C9CB,000088EC9277AA85,85AE1C149882AA10,53AC6DAA0AD9DCC9,494A49D85759FD3A,A65763F99403B901,276C02FE797FBCE5,FC31EA317B686AD6,00008D1B52DEDCB0,957C53280ECED01E,7278BF64F740CE3F,992D7106E08BBCDE,E913042400567511,B99702DD2C75E3E2,20EF8C192234B24C,0000A2B8C667DF0C,8AC50CA4B2143036,1295237A142E7000,3204E27D925A8DAE,2FE7B760278B2CD5,B1882B7B4DD1B04D,DE89A5C6629BC2AD,0000B57E7666984C,A98D39C823B86B43,DEA7852265C9E9AB,1EF85EF85888505E,867F986D3A44FB75,BC5B3116D1C5C5C9,81B27862A099ECE5,0000E68313271EE9,83033369198620B9,0EEFC56A3108A80C,5D9C10DD74B01223,D25B0E6697161B70,4477C5EB2E96358A,6E4C1324BB16DCB5,00002ABB5B332528,10711A48DA40C4D7,B874DD6F38501AC7,39913033073E8F61,CDACE4665A65DAB7,381F9C945A37CDB7,74A3708E395D3B59,0000FD205E728FE5,450C732825D39F42,6DA82924CDDA3398,92533B055624D79D,97540199CF72E85F,C5CFBCCE9E3D8665,3741EC05F2B37C8D,000110AC4C8AC67D,0A7C03B7A794A2C0,3900722857C30881,A8C441EF2E641D12,753C800DA8B95AAE,2E33B7FB49ED6FE2,EA829A0C10C83864,0000CFA2133FD629,99056B00E46EDA03,C7CB58BE96C3CBBE,AF9644CBCA7DCCDA,DA0CCCD04F8C7042,1C0C954C2DC9533D,FE8946BD5038C081,0000E7E5B4C3C495,8D1E10617AE6018C,3B2C930A125E3A88,60C44C8EC1B16FEF,4F211CFE26163B5A,F258F29D9DE7A575,6D64EDFC6902E2AA,00010C573A373BE7,8E548774845DB5A5,4345637A44BC2699,DA037714FA5B8B1C,B2C8E6856A6C0F7B,38011D2909351F9B,F057512080B9ECDB,0001B53EFEEA2992,5C647139F93E8911,213C195F24FDE0C7,40EC8ED568954FC9,39B6C759D4FE0378,DBD178BF289668AA,1EC3C7E2D8C8E446,0001A2A40734EA3C,B13209BA1A8B4519,C9FEAA926625A353,E94B61E435D811BF,48C20CFDC389AA22,2463892FAB4155C7,1BF053B27A757810,000138C6F4BA0B64,F659121E9F61C2E6,7E8970135AF94330,696F8055BA3BE107,5A3CFD16826D2976,F2DCB66A041236FA,8E0A81EE383A4DF3,000182E1A9EBB67F,FC481FFC677E1635,C678EBD18FAC00A7,097E8679A96B4962,CC075D6731B2FE8B,0394FF1008650CE2,8FE6D6037DE4392B,0000BCADE8B2A492,A131FE830394236C,641A4A6CFC021622,AB8145DA582C3F53,EDDD7188C5BFBA9D,643D219CA38C2A4E,758E45E65255DE5D,0000F7E62A420001,1ED7C0957C3538E5,78BA6FF2201FB760,481BC0C01367CCF9,B865DAECCC43959C,77F1F7806DC8C70F,1C2EC92AE51CEAED,0000A5C02B6C10BA,F31CC9E6FD0813E8,2344462F5EAF3A07,751319931D916906,AA885BC474B9245F,1C9C806D7D7DE4A2,AAA760C170A5B67F,000058178A7C5D25,D6BBD20CE1C81E15,EC53B43C0463B2FC,9C4E4E29E2EE4238,C58788FD508558E3,793D47E589D42F02,F17E896FE3E8B436,000211B7687797D8,62845FBFDD3605D6,9F9AB96CB199CEA0,FF027B962B5355EF,DFE590443F995C37,48A2C8C8C081BDB6,576E85E1A9492922,00004485D2DE7492,441AAF50A7765ADC,C85FFB9509936729,1B483388F704517D,D9B3181A1C1604CC,F77B1FA22F46E894,9F9DD17A3BB7C5E4,0002227E953EC04C,DA9A4A4A683A9E56,D65D4EFA9745D31C,018C3B0D12319785,A52A2F09E88C3E12,7921B8F458A4AD9C,D2FBBE08F54B445C,0000ECEFD08658B2,01AF9CCF2CA16A3B,C6ACBF40B74B1B79,1A1AADC8E4AFD078,A73825A7A740B8FA,4ECFD80154708C14,9A05F2F76E39048B,000199EDAC6297BF,F26CE6B3C9F32FD4,30EED38F8D91A2A9,A296F524BF913859,889ED41B52B989B8,F1CFF0B92ED0CB5A,30CD703206864ED6,000190640EDCF66B,E5FE2CCF9E20DA1D,2FB60FCC57F7F655,637083BADE7F8BFE,E9427D7D504BEB6A,300BEB63D44C6DEE,EB2938D89370C908,000030934DFCB34A,00009E039137470B,06F3DCC21AAF903F,6ACB3ABAF5F2ACCB,B6BDFDAD68FB4728,5DBC896D04CB6362,CA64E67B2CA76FCD,0001AA100509452F,F994305EAF53C5BF,4E05C37A0CBC0CB5,17768346A726A28A,011CF6926E3EA4A2,0649C8BEF51BA9FE,A74EC9A5A3C0E08B,000160FDB48B4304,9604E7530B283841,DE5D3AEC663A212D,B95145F1B99A99C7,90EAB5ECD4DE4247,D502799FE0311ED6,009ED934F7466777,0000BE94220B09DF,3A5D790A6FFEC7C9,8D9F3DA1C5B82737,97E32C881A0D83E8,DAA42FDED89BD1C3,046C45E92E997E66,D8D48CDAE7E7BA79,0000674C440D2866,BF5215000F10A15E,40E34A1F28B599C6,C78D2D89475A068C,9D63FAE954EA83FE,0048DFE44E002499,19AF3A7D8043C1A3,0000572446EC8AF2,B55AA3B660F15138,45B02987EF451A5D,B1A72430FEAB6EF2,1E61951A0D939C92,BF8B87F3F95D64B4,4B2E1D626868E114,0001B9350B4F7E66,4BA24D9CE94FAD0A,7DDB90E6850D3FF3,29D8928C50BD4BDB,685D858DC86D03B2,CE3495945B200E29,E8225B1A6F24DCE7,00009E342CF87D21,213AB48B00E29C07,BD99D3B0A4E3D108,72D5F5A36C3C1BCA,A2160210780DFD0D,E5C253444A62C137,336BBCBCE3E02F48,000039976769AC8B,070208293363DB27,B76E699117DC4B41,4C242367D51CB9CB,1BFA0A4634F0EC83,264055BE553719EC,D633ABE9F149B2DA,000139DE7B163FDD,DF015B00E02CAE31,A4422233AED1C4DB,C17F03068B13698D,C351D52F59457464,4B0F3DFBFF83AE22,9C56345ECF99E3D5,0000043AB6C66819,7DC26F4BD1960F45,3CBD87ADE9B3C4F1,E854B765FBE7BB0D,61C91F58FF53D063,B3B6B7B9B58D8803,518C774AFAF9FF96,0000FE7F74EA5E43,963CBF7E03089379,1A88FB2FF3BF8507,5D84C1ED51F66F3A,BA3ADDAAF898E5AA,68B961CE95E0FC37,C7B9D4C72A83C381,00006FD8FA0007FF,BA58E3C76C574B9C,D0D70D0230A00F6B,1A48DB416926EB79,6C5EF2DD1E2E4BAF,66A397BDF4ED066B,EF7149A223DBF99D,0000E769A2E98C05,973B0EEA2F002CED,F2D2A8397C1C5BAF,AA6D49F949237D77,FF19DE1EB4096DD0,56B9A92BAC5E1E59,8DFADE056361B410,00008F74F6AF1FCE,F9142769B8A5C09E,DC1F2B3A186BB2D5,ADEA82112DDD1325,508C4A72AAE757FD,9FF573D72F37F55B,2488CA3628A5E53A,00016E3834942F49,BEE741B69BAA3AEC,1F8721AE66510DFD,F884F9E41240EB21,823824184AEDA563,644B46F6356E3EE7,80E4D3D824CC0A62,000169E9FBA08CB6,51EFB82D1D0131BB,E477017A6C5DA5DA,793626A82B9CEE31,4E38D75D33B126BA,DA6FD67FE1257D58,F103AF20358188C7,00011D7AD28ED593,0F27871CD147DCFC,D47A2BC5830170C1,B3DE6FA5D1632FDD,C5FBF22AE9BD163C,C3B3CE5E0207A080,DA3822D40E59F171,0001FF4C77FDAB5C,EB2CF9E92B4E8E0A,39B9A2FCFE6BC6C9,D43DD07116F81FE5,B109F16D0F0DC03D,0D305CFE34D8536E,FFBC2E2E815671CF,000077F9B197B6F6,54D19C6803630BA8,B7AD1C069EF9B99C,A63D5752CA05A492,BABDC9EFA5CD01AA,4AD8BA7B28B04BE4,7EA42306B4CCD45B,0000185A8EF6A828,1D29779603072BCB,98BB0106F3C9D8E3,C0D167F257E375E6,3181C8BB9914977E,1832D37F1EBD500E,6602FE3329132F7A,00021878A5E7D28E,9085B7210BE48927,3E17F4E03EE5CDD6,EB336FC34B4DFE05,E2727B1F4E2CB1AC,FEC489A704A10B97,63EAC340E55BC180,0002054A25D35218,32990C07D5AD90B2,AE880262C4886912,5256D5C3FDDCA3E4,70CE3079DB211A56,0EC27AFD26BCE1B6,A557BAE72F5DA394,000098470924F022,B1EBD5D81A2F4E47,E02151561F7C3DAF,A59388D3E9C53D9E,7DED93F982310990,664A13B359E282B5,521AE1FA2D19EC7C,00016E9438796653,BFF32C1221077F76,DA58DEC4ED98DEFA,627E16ECB9686843,94B1302E5771C6D1,C32C45ED1CCDADB1,B9A85FBC7B24C48A,000168292646FA4B,86AB41486EC91E90,E58E4D03FC03E313,4CA1DC5FDA7A1DAD,5DD58A3C8596B0C3,0CB67E6BDDCF97C6,5B72094C52940675,00012213FE7A62FA,3E81990B60A5ACA3,9871473A15F8F7C0,5C5301D6AFEEFEA2,FA4BE332F527D55F,A26F8A21ACD9BA4C,9F855A6B18F9ED21,00016C393B4E9CB5,4B05CB864F0456EC,98753687AE1A8A5B,CE765F036910524B,4BA2F4A05BB34D61,C6B7B22AF514A63E,F03D69A9CE6F2ADC,000148606F00DE52,3101895E7B9E6BE7,37C69D6CC6897F9B,FF59C6354206328F,679622D90521BE0E,2BF9F1631A50E501,56491BA643794F51,00012030D295213A,E8F52AD253191A21,F977091C3F2E5E8B,BA8018B198231FDC,B3B17B160842A288,33A6E34665EDEF73,1B739B93ACC609EE,00009CB68EF014D1,2A18ACDAE36BF4BC,2F76A86A3D34093B,55DF43B6B843D61E,D5421B5744BA8528,362BF42D59A7CD20,D66C3F9AE3B7F9AA,00006D69ABE591D9,8EA81473E6FC49AD,C34E5EA9F9A2C9F8,C450ADE6A14038D6,94EACE30DAF7917D,E238CA5AE201A54D,E244B0584FD63136,0002033838E34C3B,106CBD9B10379484,94CDC7028E76F44F,DE460838AEC9E102,87B47DF1E4B8AA43,EE2AE0B906E9A809,198E4E7FDA9EC9C5,0000F84FFA1E9C5D,2792E12CFA1BDAF9,6D6ED1ED0C1166C0,3F860C4703C8DCAD,7F0467627ADBB954,04CB2F34F79B31DE,3A39C4F25052F25F,00008701EDBD7232,0C36425449FE4C2C,C76362E89FDEC027,46A425758F1CC8BC,CCB740616F7501E7,6DB2B232E18E2036,D9F27AF67D2FEF97,00002EC52247DEBA,339D5A50C49563A1,4F113DBF1F569F36,29ACFAFBB6FF86A0,48499077B38808F1,4971EC79066AFE88,706D35C45E802E78,00009157C002ECBB,802A14B1371B3C10,D6BD68E2A7072954,2A8A66D106B34131,1B378F31C2F00A52,D49B0EEAB656AD01,18D21280D2CD9A62,000150782C4DA8C2,4C185D6CDAD40981,BEAF2C501AEC6AF6,2C4C794323194622,9B59FE6643D330FA,2ABA615C945D4302,3F93FFEEF2333049,0000F39DDD2CE7EE,C7EB97C631AF8F22,6DE161DDBC8FFFEA,02F604BDCD0CF2CB,7911C61A30FAABD7,662769E526546559,AF480BE487AF2407,00008ED1939DE3DC,054CFC67BBB61113,8E0489F8EB20D77C,7278995178C64C84,07F569007FA69CC7,290136D3847345A2,8BE7C446AB69B89B,000119A9D1C82F7C,B5DA38569EC56E6C,330818C075DA3049,834FAC0004757FFA,9E5A90BBBF465847,58E9F80C959C330E,72E2CCDDAFCD42B4,00000E2C47B491B2,2FA2C04A577EDE78,7C56DC7374D48815,2634710DF9332C1E,E246F88EC0DF0652,89DEC8D42C65770D,E43F4DE7E794EE9C,00001572BA4F41ED,AA3004EADFBF43B8,AC48EAF6AAF0110F,B9894D0D6466E199,EFDE5F75DEC3B118,8C297E5D7A8B49E8,300A01DAB52DF6E7,000223E71288B735,5D7C754D4AD7FFBA,29EE9E36557B3E25,89A84459244EF533,FA934AEA25AB6B03,E399D9709FD8A080,46B9373F348C9D12,0000FC791149256D,E0153A98EAFE1797,F0C5F04325829516,621B431D1958B148,FCFEE863C0B98076,EFF294DAC0C81277,5A8CF85DE0E74CD1,00013008692F0DB3,DD007EE7296DE436,A9534C752958CACE,1251D48CD60E03B0,C157EA9B658D9461,B9638E2BDBF3467F,EFCACA4237DA0CDA,0000B5E2CFBE30B2,38D36B8053BCC653,D85BD7EFE1F32546,330B55E91F9A92B2,4F322F9BE10520A8,41A5EE76D9C45D7C,6B520E929A5E5DC3,0001359C616D0054,CF3315DA9DD95176,1B353BE82F0ABE81,ABC2FE39A18B8E7E,F6716D520C15B8D4,EE8A9AF5D2D66669,0BB012036DE1E388,000209090C2618E7,FA36260B659122F0,AE7C0A3B27334CA8,652C139D4C279113,7B1487A9062A4DB7,7056E71DDEB4CA2A,489A0AAF749271D7,000039ABF87F7379,0BB271BCE5CFD6A7,E99E513F3EE3BCEA,D3DDD265C8DAC8D5,6E668EF7F5E78B78,2661D03D07C7A0B3,44E4F91974384EF1,00014BCBD26B54BA,D91A032CBE8C3FC0,FB34199A793BFC1C,1DD537B266C75081,70FEF01D6F992E5D,014E8C9EFDBF5EF2,D5404CF18A1C8179,0000F9F5F57D3EFF,41179C04A9EA15DC,1517ADB40AB39A05,A23F9C61796608B7,7791976BE3DDBBF5,4A8C5A70A03950FB,8B48BF3288AF2A86,000084EC52498E01,154F7CED5C38297D,D1764B3C06C1ED2D,8DD7D7988677E62D,9AA33B4453385BD4,0FACCDB4D9F57E93,54BE8CD8E7A26B8C,000192A15F9CA469,5FC875D1D2411B07,B83467B2CF3C3432,B77F174E6D819AAC,23E83004F39FBB0B,4B057A99E52D25A4,0E2BD8B8AF6AF931,0001DFBE0BEEA2FB,3858EB9CF06AF55B,4D17EEFA279D9132,A9DA20C76DD0607C,D2723289AA5EAAB3,BF013F83B4C73E2B,FE6F84619C35D29B,000199BC0C0F1BB2,2A43306D5F587AFF,643AB0BE50F208CE,84CABCB6C7B601AB,4B4AE1D4CD76F1DD,7CBFCFB445100515,889F1FA2BC49F987,0000B6D33770F694,7DFE4CC85617BCDA,F7A39EE2F0911B39,1846A91B99AA3390,D261EA7F818E44B8,719FAFA1C1F9CF1D,B162EDC868F587A2,0001469FF4B24BD2,F9B7B78541FB028A,39CEDA9B1402EED3,0947A14354412EF3,03E0A9FAE115D650,7317B924C3A53EBA,E0ABC9BE9FA74E5E,000157592107C2D5,DF54738CB1EB1B0C,64EAE29DCC5DF9B2,7A7E70D3D78A124A,28C4445D770BA644,54CC77A69A56AC16,8C0992523F3051DD,00016474C7BFCB7E,111BD3479C2C2F09,2C55B065B7AA31C9,F0AB63FDD1626773,4CCFF5B67E5708FE,6212902F3E0D93F5,2E5A391470B31C32,00012AC647C4617A,B71A498BAD4FB1A7,6371CC037C9031F3,A0779521CCB2883E,F9C4126D5BDED025,DCA010E41B13808D,1A123CBBA47D1E7E,000060374E7BFC13,E37046930D00E43F,DBA0A0A7D957A6CB,227259ED16911B90,7D160623DDCAD6D3,B124ED3B07581A52,7346851C986004DD,0000149CF3EBAABA,16794B5EE6CE6FFD,704CD6C33A419997,CDEBE2298C56376B,B8155FE008D4425B,34A1CE4B27B6074D,AA672F6FBEBE1DE2,00003CFFF7A4B96B,7B06D906FB47A35D,0ADE436A48EBB807,F18E57FF265E4EEF,60302BBD1BCE78DB,19602D936D84E4A6,B6AB6D212BD2F9D4,0001C5B2485F716B,9DCF7DB2A5F9E59B,8D8A494A926332E0,9281B900FB23898F,9134D0FB7634F044,8224E01B80C52C1F,DDA1411D2953900B,00001CF6555A63B4,8A0C817BCC55C76F,C4660AA8C95FB91E,EA12C10331BA8333,2E465887D8F53D06,C1A0ADFA219FA9C8,68E1352733C6DEF5,00010D032BED5BAA,7B400E3886A892EB,D6B2017F8D71C09E,F21C23E20A5989C8,AD85642A580575A7,0CA9F5EF57F5CBF7,2DE38D73BFDC5896,000031579B483392,C8E31C8408FD62BE,615F2A587D326DED,35BBE790881B5DB0,2474377BE12E4D81,1F92991A880FBCE2,C3296840AC5197AA,0001B96DE3BE1277,DF31CFAC5CF38240,2246F0A68001ECA4,C543C5AEFD708B4E,A9841130894E515B,099E8F869235D4F5,567086B4A6E21CD1,000068C14676D6B4,B0F5879F5A6AD51A,0F882189AAFF010F,5EB4753424A2E873,D7E96198DC29001F,CD267581F4508F61,D4A238CA8D676C66,000061A4488CBEDB,6B9BC9FEFDA108AC,16A62C4ACCF81540,EBB7DB22E95B7231,4162EE47EBCDCCAB,862D5B347DB2A225,1525BD1ECB660771,0000098720EF290A,314F30B470FE3F0D,338BBFDDE03DF2CD,9074C6CAA8B38E31,A1D8B24E63884E7A,69D0659C12603622,F88EE87B9408A359,0001F07F51F2F0E3,D9C8FEC6A3F08986,ED62FE3466666532,D489BC7570CDC0F4,B4C576AC1DFC0F12,ABA97F744BD66893,3119EDEF1C555547,0001AD80E5062B9F,407A1EE9CB63E0CD,1900ACA836590409,E7317182154DF3DE,10D13D02A93D0162,56869C87AB10A333,B6B57F2AA55D730F,000223EE6CAA09BF,74EEF204797A8F9A,8BA811290B57D7D1,2BC288C7E0F5C1BC,553D9E8B56F23812,51AD3DC6D32D3F25,3DA5AFE68C218CCE,00016B19BD4C7F90,20EB1F6A9F75249D,5E51810A76D82731,DEE25145CCC2A89B,AFC9E1E784078AD2,4715EDA1EA8D3046,E28B0989292CAA49,0000DAF0C2C394FE,66BBB3AEEC191F5A,3F577CE42DCC6BD7,F9A2555F007884B6,FEDCC3441943011B,2F4E5C339CA22480,BE711B951CAB347D,00007C7C1EAC4BE6,8C3ED2178F61BCCC,B794A5D0D7C6D291,BC5BA1057256E5E7,4DA64479AA25E514,BD2880678A18C68F,A0B473A650C1C194,0001BB4148163983,7B1CB08592DF5DD3,1289EF1DC12EDF63,286082817CA374C2,EF7F5F2C36446198,982F8091DEB2C6DC,D5472513D786A5F4,00006B7CC6C1FCF3,9CEE29A194E20A0C,0A0B3240D4C08EAF,65DA4DCF583F51D7,8C470F5DD0AA315C,EBAB10CD15186110,6F4D74E4E4073167,0001213C3A8DD307,22F80C6BC5ECFEBD,AB636425D2E5100E,2528B82F30776A58,FA33F9E6A984628D,FD275E4D1DCC2533,8894357E48036712,00013DC115D286CA,BF19B2C615BAA99A,36E3B9C711C7DFDC,F163DE740E4F6A24,285BA2CFEC04B7FA,6E9C84829BD4DF4F,E99833D48C12E37B,000069421D613DD0,B66DF7C2D9BEB4D2,4B7EFF6758A66A21,D843A5DDE2D52E6E,B75253440E1C4844,BC78A529F0CC4A34,60F427956C1A5689,00009D080E3C7124,68CE2F1039846242,4DE75D23853AD253,D32887575C6A69EA,4200E254443DECA5,44C7468F49E52FEE,1E5AE802C3E4C873,0001C0D455EE0DE1,C090A9512785F30A,AA14387CF93518E4,9F41F62F4487BCED,853D124AE7A1E73D,A0E37851DEFE6C92,22611FF4B4655B5E,000017566E4BE998,59D5D937A555132E,D4CD7AA1D3137769,FDA68F1203A60472,615480DB66A3138C,E761526C2B2C0802,D16997A470399790,0000E6C8FB813794,8B00E9A73C402414,52B5615CDB18D204,C6640AC763205E01,DBA6E3CDA161DA0B,F2C39B9AC73132BE,A6EAD438BA2513AD,00018644360FDE28,766A55D8CED99B89,D39193B5800DB7AC,4ACA310B4550B75B,4DF4659035FD34D4,4F5DF3401DAEA9DA,F4DEB85808456E14,0000BB186F1B23FE,6290B485208D9584,DC324FD222CF8E42,B006A971AF1241B2,ED4282834DA4DF95,E806D8F8EA89B4FC,944D24B41456D684,00007CBFEEA7B1B9,472DFF1CAE75E082,02DA2E3A09BF155E,FE24D0378807973B,9E81F7952D4ADFA9,311126DBECA89069,0532FC04E3E31721,0001087726122F74,639EDFDEF93AC000,1A1DB7D2F8979DDA,44D860F411C416BD,FA52C938DADB0E9B,AA3A0DFBB01EFB92,21C94644EA9D6C14,0000E87956E25479,5B6D860AD125E564,CAE3CDA7842831F4,C34AADC750309EA5,AAB6545C578A139A,A09251CA46670049,F694790E60356661,00011D20E5E09DC6,EC67FA2CE2E71EC7,A55DED0D162B1CA6,80A374BAF04BCFB3,54BD8018281AB414,5443F4B63B2D70D2,56B76AD775B6328A,0001C49E57DCB7D3,7FA1CD60F05AEDE4,DB6354215F6BC102,069C71AA5DE5BD68,F4B09313CF5D134C,C28B51A7B3311857,9DD3B8049EA776E1,0001FF6B187690B0,1FBE8EBC2C2781A5,6AB3E87542503B09,153C4215B098C95F,C097425FA7E250A7,2349EE8B1378501E,53D880DB41ED5E1D,00007CFCE600E90D,E04BA3A855BF3775,AE48D93CC0D78BD1,AC9FC2FCC7BB7BB1,4474A2D9648C0663,08E6BB54CA9608D4,A638A5B521CDE7D3,00015BB61EC1452D,F66A2A390432740D,24041B587EAAD54D,B2ACD7E62A729630,4645DF23E43B1A97,071A8886D23D5BDA,7DCACD2685A0CD99,000054944A5C471D,D14ADFBAB0ADE782,06805D009BDF4D45,95E66FFC9C36083B,451F3597A8DB5BEE,79036FFC5D08913D,4EC5E1CED6EE5D3C,00003C9AD96FF78C,CFC620C4C77DE808,D24AA92E23C4353F,720EADA550F5CCA9,778569A2A42C8373,5EB093E2BD539330,D11EC11D95FD2BD1,000183CAB0BF1833,689DE2D325BD90A0,82D9462CBB120F0B,B8288FCDE5A417BB,D01CD9A89D95C49B,7230D01B545E0226,A771CC006784334C,0000074B54AD065B,3676198D6C9EA7E9,58F87DFA4D614823,2DF809FFDE284D4C,B2381EDF3AD632B5,A9BA06D0DBFC62C7,56058EC51BFD727E,000010AC7B16AC66,68C5D308E692B551,3F1028AB40C1E7E3,0FEDB13CCB50514C,5AD9BE12FEA70FF3,DD86F592FFB26EFE,3CE47FF60E3F66AA,0000105F527B0202,978AD4596DED992A,222AC0E1A6944BB7,91A2FC1F4FEDBB5D,B30539561F08A7B3,F8DABE0E8F5D9694,DF57E3681D3563D4,00008A19AB5B20A0,F15F8A8D2156E89A,B98F319AF99CA9FB,2BD96964CEAFD5D3,4BECA91813CE3AF6,9338027D9F8AD664,E8E149A477C40812,0000EFE7212E30CE,B81BC60D07102D17,9BAB3EFC559D1FF2,B52806E97F58C857,AC37C9BCFAEA5252,29C8E4D90CE26A92,20EE1827DD97CE25,00002A14B8BBA097,FD425E44482338D4,53D2947F6BBB456D,64DAA584D1C2AA9C,899B8ABDC8ECBEA5,324B2477FB55888A,4C6332B8D8E4B9D0,0001CF9612C64174,83E072F0CAC436E7,405FD8145E960EFB,56C3482918687DF1,F1A9E74C025B9B33,24F63FB54AF7FB9D,E331F4A7A6AC4AF1,0001E767CC4ED924,7BF76849CAEB8544,E1208E004A400DED,1908F1A1FAC2B9A6,5E034694609BD7C6,2FFFFA47A5E4BF4E,33486372FE6536C8,00014497ED6FB095,F154C65B6C275AF9,4C534B84618800A9,36616CCC466FAD25,E07457878250053F,9A47EA287DDE080C,B17C6DF83B886DD1,0000BD4CD80B690D,8E92A9239289BEC5,AE9C47A5F3075CE6,AAEDC8C44C1C235C,DBD93E0F8707BFBD,820DDE891C1C9788,50462C5BB24B7B51,000159866821E9D6,78AB72A2C6E0D1D1,8FDAF5D21C422510,F819E1D3C30245BA,A8CA110289EEC956,FD784AC9440DB1ED,96816BD864302962,000003683B4648B4,A16DD045F01598BA,1B1C47A3FD7A5AEA,7EA0800342314C1F,805EDCBC4F7B379F,48077F966D0ED447,1A1B7123C6AC1F89,000202D202F47F6A,A26D12DACA81ECAF,8C42F40677D86BE1,934AFEA3E509DAFE,98672E134C4CE323,BBF354DF0A96D5DC,9192634BB41FC7F1,0001E4D253F11BA2,F1C3F9D975E757BB,176A3593C8113C08,92A0C734D0514F21,1D4205DADFA0067F,1F4FAE047134EB56,E8F9047588B4AD28,00015AE0E4A5B86F,6B13C7330127D5FF,1628D39DBCF45B08,5061EC8B17C5A44E,F2A79EE2D54E1B17,DA78C3756398BF86,A28BD539340C6994,00001FC42DD49A70,3974CBC17E6A1384,267BCACA0B56CBB1,88EB53F2F5208A62,BC0A673467FDC4D7,ADE19CDC3B6A0459,7A1442313415047C,00002FF37CA7CBC3,289E2ED5F7117CDD,099A62FE9B2011CA,B064B46988B4025B,CBDC2657225FE8A5,D15256EB546C6042,EC032740C176C556,0001A124D7FE94B2,97DAF7951AA325B2,ECECD8AAE30CDCEC,EC90E896AEFB72C9,B2D812D1DA7FF89A,25BCCBEDD09159EE,05112B516BD10D74,0000E323AD18C05B,18B8239D92E6E721,8121EB1749B44B95,837968F8E27ABD8B,3B8E4D4C0D0213E7,B3D4090B9814D20F,A351D90AA32A56AD,000061DA8F57A3CE,E9C657BAE8C388CE,663089B223407364,38226E15A2DD1F95,594BF04805B697E0,C520A86DD322E87C,FF286B520F03A367,0000C457B7D5B332,7AB47C7DC2D8CAE1,0ACC74560CF99463,69AE6898499560A5,EC83A014181A4F97,2AAF629F250764C7,27C5BE99C310AC68,0001D47A579711BC,7F44A99726BCE788,F16016A706E11CB7,71543F576565BA9B,13FF661C5E248E7C,28B8CB5A7845F0C8,599280A3236C95AD,0001834B6DB5CA8C,92CE6C03263E1AF1,0B793B45B20B635A,5768FFE68A242EB0,2E8F6437BB7FE37E,E498D0C4FA9B873E,71637DDF47B5F7AF,000155A84114E7B0,46B01FE0C12C4439,D68CB66F23BC6052,62DE66ACE0DBF298,9034E2D0B1639E92,78D57510EE99AFCE,041FF377E391394D,0000AD5569D73086,074E5C68FF8D409C,A85A44A437338BC9,C11205338858DBDB,4705292DA0B7AA1E,1056B9429E7D21C3,3107824D7AE9182F,0001BCF327FD1D24,2335A28843BB0C8C,C70FA0D8F35C726A,D318CAB7099B3171,D4A8C264021CC7AC,FFF84BBAAEA931BF,1D6CA1FE80C3EE41,0001F61BEE9B9D3B,CA6FC2C9276E6718,2533F9B4F77F856F,53B0F548E4DE514F,2B0F3EF23DEBEFDC,782019AC1CF09276,840A03434FDB1367,00007F54FF35A5FE,07952158FA4ABC4D,E651DE057D882E42,31645885A010B122,18C0AD07F7AF84ED,5598F85A8AF5A79F,7FA6A9ED2F7B67E6,00003B385C69B9B9,22792FF02465707C,AAA24A5CCA38773B,4EED2F07DF1BEBEE,AA29EFC0680222C1,45D3E8A4CAB935EC,749AE2F6D69D5DD9,00001976700A8DA2,8DD65119657873E4,49E4381F7897FC77,25B994367AB58273,13B1178EA9687F2B,F076FA8C1BE691D4,1A78E438AC095973,000098AEE39BB700,69A7DB68955FE8CB,D3DD60E34CF07B5C,481F1B1008BBC796,11DE3E6E4F5AE4D5,CC5511BD54DCB9D7,EE83727AD5293D97,0001C8F16C1C1C54,F2FF8E6D5085DAAA,0679B5E171FB88DB,6D4F6531D5DBE81D,53205659E63B0E8D,FA60342317DC4F09,F4CCF522FCF50C94,000217A6C1B8C13C,90E64050D3C794AE,EBA2E0DF66EF966F,AE46BF87A1DD32F2,643033DACB5F04EA,1A9975EAFB2A63DD,076F8E3F286C319D,00016BD40FF55A37,765144A4B4233677,BE38135ED1C72E32,0B48FE3529EAFCAF,0ECC81562F0C333A,CE016868671C26C9,6F58324D08911C7F,0001C388F40B37BF,172A4779D40AA171,DB2C58A3F056B0DC,BF1ECDA696B3441A,E83E03D70F68D285,162915D3A2721D6A,AE5DC64E846A9882,000070EFCFDA3F5F,C0E73D459E6512E8,3C4B3F221759926F,AB9666963BE9A481,A817C06067FC88A4,864175C4A020AD76,9E84FC3E6F225970,0000D72C109AE143,3F48D690F1D98791,505A1ED68320502E,FDE9D756CCAB5E05,1942FECC09E21CF6,F41E7647C77CFB46,EC31FAEF3E584920,000191A987B33024,780986658F546AF7,AC27E5B89E641E82,D5F718C4D22B3B61,CF55EF2F46804FBD,4161753260E0AFAC,0CBBA21419F318D8,00007D15494B896E,3F8493E7A8F2E8E2,5CEA906E421BC420,9C579F75B48DAFA5,8760E85249544C26,D23F02B127322F39,7CA6685B2FE74A3E,0000EE302FD78DA0,F10FDA99FDDFA2A8,6549021F265AF50D,B03A864187C721C9,840E8AC91806388E,1D3E4F40815DE86D,FE044D815201B5BA,00008418AEBC2248,8F4A3F4B440AFA7B,FC3F673A4470792A,C20F4C91672057B6,D55C22362CF234E3,5BD647B98BBE98F0,D6C3C351B4297957,00005F9A8BCBA49A,A93C4E31E251CCAB,0636B3F23905443D,193AB1F72D3E0E84,88D66FED9FFAF055,65D0A21E72C31434,D38BE6116F552071,0001E0E4CD3FBA25,DCEC3A128A1217DE,D32335B3C577ABC9,2D01FDDB4849734B,9063F9F982DF9BB3,E2FFD8BFA029F255,1FBA6ECC25A10145,00021E994ABF71BE,786C8B22E2C511C0,3AFE8A73B058D3B2,C915B0840F62C97D,D2C3B58934AE3F7E,1F13AAAE91E64503,386D0CC3BB72EAFD,00001C3E842C7552,972B2674C97E9701,3E914D548D2EA6D7,B66A4C45BFB17029,A5AAF8B8CFF6F42F,E8614F5F715F8539,AA3078966D7698B6,0000FB7476B1E481,E15C6D5BD645CE6B,BC752249D24FF5E6,F96277795F82D2C1,375CB035C8B78D05,2766BB982FD7065A,1BD4805C5B49C98C,000215549A0F30B8,86BE67255D3E6ECE,C990AE7C1012A4E8,CCCE9338597472FE,415B910E2DA22547,DE73E59EF90E8221,64F58E5BF95EFF96,0001D0B9CD8C2AB8,B2483AD51EAF1DF6,74D0ADACD7F65791,CBD4DD5C8B9A5638,F9B74BCFAF318B66,EB1A7BD7103047B5,FB8B2C26EB526468,000109A878151FBE,D5F8930669741E27,D42996CA09054D80,9EFA220F69426557,58413140F716ED1F,F7FD166E629E8B14,372BB27ADECD9FAF,0000696FBB68C776,DF3E4441C7BBD91E,AA427987A3C792AB,2981789041E39A63,ABAE04114188C79B,BB48FCB317A706A8,57AE6CBEA8A98E21,000045AA45F4C2B2,6E9329AE6A18E91A,B82A6D227C16B8E1,A5C3DDD3C394500C,BE5254564619BD76,0FCDBDC7B060EB03,FAAC80075286A1FE,00007B880066AF7C,9850295AAFECF554,B42A40D63FAE01B5,5F0A866010FC00A3,9B714F12E6AC3C2B,ABD959078C77AA75,722DC6351D15EF1A,00015FAEF15F485A,C0F8B1E9D27D5F44,E2407DFB93FA9500,DB4E11245994F204,708AA2C6C4509AC7,89E62248CFB5BDB2,DAD9780F8C8BE912,0001B0DC22F57F80,635FA45713CC9146,8690AE1DF2BC66AC,596A298A6C3171EF,6F1B60D2D8E52100,D464C1B44FAEFD87,A13E2FBF7D88DBF9,0000C070B5E5F2F0,871AC5E3E2CEC727,F883050E5618CDEF,C34CE77987193D28,C72258569B80A9B7,879C1340E51BACD7,93EFACCFB1CD79A0,000139FFADFBE3D9,B02E003DA6402F9D,136DA31DA4B48480,CD808491F24C727B,88AA8A314FCE5A8B,8CCF093A6B780973,B1AEAC8891432D0E,000040CF978D62EE,930B3D73905C7F32,D351B5FA8B62DD0A,0C594F6C3F9E2C9A,618D6C0C20DA14A0,32F0A6617DD1157D,4272EBE676C89A21,00023211D5C165BC,91B0412EDB225148,472DF6B993B56792,33B301741BBAB3C9,B6404D6B5E86DF03,75084F8A7E08D2A6,F4F7EF658E6B9BCE,0000AC51FE56B22F,C7A9A6AC824367C0,1C17C05F872FA6E7,361ACA6415D0CC78,ECDAEB01B2E1B768,3E3E831FA38F8106,A31B47CC69C94F88,00012DE94FCB4512,87D6BAB67937BFB2,825CC2E0DBC393FE,E0DE95D420FA2F2D,AA5C18DB7A51628B,1C0FA1A9F10B301E,C7754BA989B19845,00011EABF045EB73,A170789EEE685EBE,C291D01B9426EFC7,513D097082775CC2,9D38A0BD9E4E28C9,4DA983DD7FF4B63D,0B494ABFC2E6822E,00004399B9EF85F9,47F2B5A0FA7750D3,2816EF2E0BBCE1A1,14606C2DE9A94180,AB830DFD54EFC156,1917982A67005744,EA88DFDA3DA7A71F,0001CAD0BA24371D,0FE7C0917E5D99FA,41A514E8091B8E52,0675872BE2F5F64E,E0C8F0D4E9F29279,4A5FA14D6F015856,E64208A22CB19110,0001E5F35C60C233,04253B0E89882750,18B52DAB37DDCA7C,73138C99629DD117,34166A5C01FEB3D8,66377950B22A2872,325E011BB4D01C71,000127EA378FC78E,AA6977B5B9EA730E,65304D375FD8D7AE,807191B726873FB9,8B12F68C809247A6,F03DDC4833F2BE30,E527F7615178EBD1,00021E622C1D6090,EC1D361C7A890C34,5CE698C901CE3FBC,E8BC75D40DF61376,E7C43A2217820532,5E979EDB4668B9CC,B9E9F20A2C270929,000130FFFAD19D25,4C894EDD11AD8CA4,9966F40801879111,047908D99215D47F,87CB2812772D1E32,3A849D8F454A7C38,5C0D0786DCD9608F,00001126F8816CE4,336A23274A27758F,1123B20D112257CC,CD783FEDE10ED5CB,995E8C269863BE7A,F53F3EE07883A2A2,52F4EF1710EF3301,0001BF06A53B8455,9EF9E61D120D2FD4,0F4B381F014A7F54,A1F309735DC79222,0742F9598CB2DE5C,4DEE0F7571F05488,80C287D0A708CEB6,0001B54FBA6C0D93,E8563D6716EA3FAF,55A5EB5287936190,B3C6574FEA0CF38E,98EAEB2B181DCA36,82F40CC3C9EB2F99,836C38936B8297F2,000195C3B3FD7696,54D500B00814AF95,F34A06783C5C77DC,40EB5BC84E3B3BC5,5799EC2DDBC6BF0E,6B4C3F78216A66E6,FE156EF85DDFC159,00001937D6A73A3F,DCAACD3393CFF964,1C1D0BE65590504A,37EAFB91E5F60BD9,78E36FB614586402,30D11CDCBB6466F5,C282A821C4A11F0C,000002945B30D20C,CFA87F5D23DD3DED,6F650324E7BB63BE,E9E5DF59DCA2F2F1,8C71C65D80253DB0,D07D5143EC6DD193,D21E6003EB03F127,000203DF40CC6B93,54445960FF5AAB75,48EB7212BE9CA9E2,B3735DE56593D725,B9DB0678FAFA6DE7,AABDB1564F6CEE7B,F3DBC01AE07A9FC5,0001DAF2C3A89724,E86D050B50BC6955,08673D6B5A882E00,751EBE97359B7F35,D83437A5CD119339,52A581A3B86CF2A5,29F4D58CD410F170,000049AAA15D26AF,0063BE3A412B5D12,601BB9545DA86433,0D5307F699D6453F,8F97813A4D4E5564,88D4B75390B174D3,6F2564C2063A89FA,00008A821FA61FD1,683B632153C6C3A7,E8F0ABA49115275F,595BD1419E2A49C3,9719D2E6DC959FF3,CB4A3748D3A99745,82BDF0347CEFA65B,00017A4AA693DB19,DE6D1170F68D1753,62DB796FF24E5A84,860500D0FE2C57D5,371435874B5E5FC2,640E5835580DBDB3,EC8EAE76E0F1D9AC,000141275DB3F6A2,20D47A2CF5B59F6F,7513D8ED9F485F51,B2B71D681339714B,4BF615D642C1D7A9,E55C671DAFF0D0DC,F3D46F1E942F63E1,000111936874693B,277486519BFDFE8A,093E0A713168F865,212D6E1484C77E5A,233750831FBDB32E,2A74B93344E0D76F,D46B4D5755FB0AA6,000002D1133C6821,FD017B4D00351139,0EACDA4F8CC8ACBF,D63A289F25A0773C,8271C326A55E364E,9AED312DCACF4139,B5688D216CD952D0,000211178C25787A,49B91B69309F0481,BD4A973390A0A032,4547C9DB90854819,66F5B337FF2A3725,7E24BF7FCC160DAE,26DEADB59FDB6213,0000486C1744E712,EAD7EECFC37C70FC,C4082617FF141D4F,83A1EB82CBC793DD,7C8584B20C8CF66A,6E6EF8E5FA042228,39AB8520FB1705BF,0000199BCBD0F6E8,B8B315BDE44F8722,D483EFF6B5B578C0,7201C0B040B9EB90,DA354460E04C33CB,CD72A76E042EEFF2,A8E0BB76BA6700D2,00023312E5E86EEE,A02624AF5164F7BD,44B49B5914B6CF2C,AB9BEF84D559FFA1,B620E606B33A2E73,A0B6FFD44930271F,36BAB20180DC548F,00002CE3AA2EBACD,50E20EE7001E2C06,2CC2FFFB34FB1A2E,C7A29E8B69A6A8EE,B4E67D1BD717E1E3,A6CF060C0EB9778D,A1AABA7E516CCE87,00018B48809181DA,FF39D48809324E6C,96495B563E333333,497DA74CCB982F45,8EBC99C1EBE619BB,5D325E6801CF6E6C,5125A711ED8940F5,0001F56C66B3C8B0,DE2254DFDD00CF3E,52AECE48BBB14221,E9D7EF23BD7EB884,DF03B7126660549E,7E40DB751E40BFB1,E3E2DADE2D49C974,00017141DF9A10D5,C3F1903A24A65A30,E363F1387C00A879,8E27B7D72383DFB8,AE20C1524A4A1AE5,F85773EE4E313CF3,DB34183C31F949C0,0001C1F2A8968791,1B9EDF9B892F7C54,0F1A289967B629D8,D452191BF073252C,B6D66863DB9174D6,0627FE69E99E4325,FCC7292E25027917,00007EC08A5F5DD2,8E32F5695FE42B61,80DBD0476DB4EF87,4DF9C3C88D2E2733,34F414C97BE3BD3D,352DD8818639CE25,9D7FCB8A30F5B895,0000557BEE28E965,DB5F411AFF826F7B,BD752B641B004218,9FB258566D44BA45,66E477A33BAE5DF5,476DB1E418F98852,42ED10283E3B6483,00018F02656A8EA1,71E0B1D5FA5C579C,6EE7E3373F725E82,1859EF3475678A35,E33355F44F55FD08,CA401AA86BCD89F0,07B37BD03D864925,00020C9591B36642,F328F375B93D94ED,64DBC4B37935FBC8,A4F35031FF93833E,C9994BCE6B9C1C37,0C1BB424715475B0,BEDD0C90CE35B1D6,0000AE75B5271115,7DA09F57B67B3B69,B048A6A3F7CD4B01,4CDA946395D9F2A0,15735732CE8CB482,894E6CBA4F5A1C9F,C454D0F46DAA993C,0001433088A5E8F5,16EDD231121573F1,3C7228E46C445E18,9395ECA32F79EB9D,10DE17B0ABEE9969,329E7C7B2579FDAF,402D27D40F43D59A,00021251EB60DAC8,0CC1D9D208220D11,FE776C05BE7B49EA,88547A5003CAEB4E,D1C81DC64DD018A9,0D372B9EEF2AF7A3,528BA68E73BC2C5E,0001D8D8F5452A25,8B9693D162106637,860D40E49FA44B93,B45E03FBB0B6880D,9D8B7A97620345E7,0954E77B1EBDF387,E6DB7A172A2E10B6,0000DCBD2232C20D,098CCD6719AB5522,2AB1823D9F773F5A,8107D1149B1AADCF,817292464845BE91,8CB812EE1AA0EF1B,5FDE8367B5A321C9,00010A9EBE7EB1F5,998C4416B4CDCE74,CC8C7FB1A5BCE072,DD02D529159FC3CF,79243D97CBF3ED6A,5CADDF2C4C48687D,CE54ADA1651E9366,0001702343B19A40,7D0260E0AE11DDA3,2C06C997E59B4134,D194E028CDAF04BF,484F5114D18506A8,65452147F4C9581F,0CCBC443EE98BB3D,000206A41B99E1D0,522E2D51AE951DCE,8B56D118B43F419F,3E37D7E9BB1AD1EB,E72D693CA698F2EF,72CEC13AD33E6535,58688A7B67245523,0000847C33634AE1,0364000D4D4E7001,D1468C7A0336B225,269119303C8EDD45,E03096075F011BDF,89D78CA210D38B4A,A4640CC54DD85CE9,0002232C24CE7099,04515E53B1C86875,B99D8ED4395F553A,F8C1D45FD5BBCB32,72B5B3D162B8FF33,97EF897AE189AEBA,E1B3AC57274F04E4,00006E373EED4E4C,E9C4A032EF0EEDC6,2F8556A4BA269A66,2DC1202BE73ED028,B1AB548ACC01BC2A,6B9C9E0CDBA03C06,1D41F3016B3C6A94,0000925C716F4096,BEB656B25DCA9C22,6545BEC3CA212DE6,669BA147AD23BD88,475FE8FDA073DFC1,7BB8001812419FB6,6F86C73105A770AB,00006B94DB6FB92A,08526A1A1092AD16,EA491C6522B8EF68,30FAA7E486EDB08E,4B5D2FA02254BA40,3CD74AE0A1867200,7821567E58968EFD,000031265A358695,99E75DF32CD549FA,F89973A411A82AD4,61C0A1B4A7B7A5C6,E464C9E614545A4A,01EEE7F0D7719685,9709776EF0D36600,0001934F7E3B7FB2,CCBFA8FEBD42C886,53A47C00688D65BB,84687B17CF2959A3,EC6B7F8E9A3D8C76,168415BCF2D2C9EB,53E022D143C2CD06,0000BF945126E3F0,186672174DF62E12,6A0E2520D0222785,32E01DD296C33872,DE043FBCF8B14D6B,EE232061F3DFC6EF,801C132B2729C7E5,0001FB6C9D81931D,B30FA9146F9B82F3,82CF48A64750FE45,6CD678EC616A923C,D64FD3D5BFB76EA3,382CF64B4838AC16,1E0C4C7ED30B777E,0002166147555E3A,446E623C50964A4B,DF88BC7AA4AC07F3,2FAC55450BE56B25,A577A8C300C181FF,2DEA04FED471D802,DEDB2EEC8B02E025,00002A0E8B5E1438,575CB3A82EA7E973,2159D7D597B7C04E,72945394923E2E5E,54DF63004844A56E,1F4ACBD0FF66C76F,57F27BA958403D3C,00000AE52B2201BC,729FCDB137C072CC,183B1C54FA56EEBE,08F7F249F0F8840E,BA3ACE9577F29E2C,1491A104B0243A21,81929ECD7043521A,0001835350FDFF64,EABB5B11E578BFD8,C3FCD2D4D7754CE7,5182E783A2777945,BCC93B9AA62A2025,E44D39097A14DB44,9D6A87332DC4F0FD,0000DEE6C41BA6CC,66CD22B5AEB13846,2ADD1658BBF4022C,0473D392F7D88583,183E57002020EF05,4996D20FB031BAB7,DE5B1733D945F430,0000C3767432F1E8,6C6FE341ECA81B95,FF8D1C8E58CD70E3,D745E2289AE73B3F,3D1AA99D220FC798,F751DCBEC73C4B5A,3D23402D90770566,00019480E46DA256,C935ACA301CB26BC,C71BBE51FD3403C0,8B404D75D67DB6A2,73E825B095250BBF,D9FEE44CDE0ABBB5,E677EB3FFEB2414D,0001CB6F9A2F8056,9B584DCFA6CF4E85,55A868C72C852F5F,8AEDD96C1AB1E2F2,1326AA63922B267F,8C2E2720CE784887,502C665FB97D0778,000024E23B0CAC34,3E4F7F5E0741C16C,5B98C66B0E3BAE1D,C68464ECD2A12E9D,51D1A7A2B96C5F05,E4B2D3E4735BD69D,18AE16C4300C1FC3,0000E88B001ED00E,6F9F1A6A0893FF6D,1ECC5C93CE737F3D,3009CB937ABB34BD,A3C26E927F981A0C,6965A2C204306C1C,E35413ED8B550DA0,000023C8AC1599D3,754B6E36893D72CD,57603520E302D03B,3A436847C9D20CC8,A09ACD59E5BCF847,DE29947972DFD9FA,1830FE12509D5B05,00002B87C9343083,A07F3559D74C3506,AB5324FCAA0C37F1,1B69EFAC9B386DCE,7710772B70183462,BB886C7343E2AA65,852EAD70F898AE25,0001649023E22174,E5D039AA41AC81E5,6C199A9F32E8352F,D0EC323CA17C17E9,F85C5918F13C8745,23F83288D08901CE,9B47519758D25FC1,0001328B8618D156,DAE53DB63EA6C876,C7B02ED386DBF867,2101028A9089C2F4,EA4E92E356D097D4,9A1A2255F107421C,4AFF4F8612F8DB16,00015F54E06D8659,23CAB87569C4A7DE,DD464417E560E457,E8DFA358CD1182F7,E741B0EE9AEB2656,EF71EADFF7C71672,987902CAA437C6A1,0001B930088EF38C,C19B46143828341D,BCA58ABE9B58034D,3CAFE3696387BF25,FBDFF875824E3E96,8FB4FCB050CC464E,5EC3AF169BF60EFE,000054B0A710E1D4,66B2D71D412B8B90,75FB9B35A96FF364,4A41E7D803C1EA70,B442FDA50F47464A,095CB655B74F4EFC,E2762804A48B199C,0000AE8FB19F08BA,BBBC57318C40EE38,3B2F9ABA67F1715E,3350110AF668FEB9,CF66D80E08FEF3C0,6F75CE363116C8BD,A4EE479618C88353,00002B4A5ED89A7C,B7484DC040DA8F83,B75ACFE34B3A7AA8,1956332485AE28B0,2B99A37A425E6421,E1DC5F9CF8F7044E,74C79C44E6E159BE,000018C9681AB49E,5225BD883BED7D2D,20C2679D07DE313D,835E350129CEB477,297F2045416B3A55,29A316EF622C7E02,8641CBC3FE6C344B,000077761E14B923,FD7C1004DF5E48D1,1E23DAD127BB0502,71346BC587CADD07,22C67404DEA995C4,873A517E769EC5BB,4C171F67DCDD078C,00019147DC1C1227,27A80083D14317E1,240A41A7E1BD2A37,79D1FCD075407399,714CAB4801C29F6C,C7A6D14174FF641D,7D9EC7F8FA86048A,000140527E30E434,29D4B2E1E17D7B84,50B5E6F4CE467103,80A35480DA7B3064,7B386EA9050CCC49,CA6CEAD20C69B168,7C698DD480EB4F02,0001179D1D824946,B3B4B953B33A6421,D3539C35FB007C0B,3088628DA9D1C5D1,C15801B2F093C909,2A69FC067A01D86C,831B1D90A3CD6715,0000BB8B7BF2F1C9,362415A88CAAF813,599C275EBF585EA6,566443304B184C2A,AACF19AADCDE548E,2FC31249E4EFD541,4943B9E912D817CF,00009417F1344643,19A20EDDB6F8A372,21628BEA52749860,512DC1C5069C06F4,B0D9A24E2540B14B,1F56ABD0A4A9BD4A,575C823C12A6A4AD,00007BFA5A1CB962,115BB9306D93CDB9,A372BF6450397744,6D9707F65E58FB23,D6D748A9945488D3,E01E24A50A680097,D109CA16C90155FD,00017C3355EB890F,49CF425C617200A4,0901AFA9F50BA8F9,01016561509D7D78,89B24725DC851889,42AA720DD4178155,D683E1EAFD7B5C31,0000AE0E9F4983E3,F86BE32EBB1F903C,CE4DF9F435D4D8C8,C172B75FCA838603,C99518AC1EBF9AA4,222D02C4EBB4D106,FC7568A16B6C8FA8,00013855819F5162,1FB7AAD0AE918EC5,79307E694D0420C8,BFBB5C4AD52D8856,76DD5D194A821BB8,DBD4D57415DBC2FD,DBB86CFB126DD3E8,0001B90FBE352C47,4180170BF187DFD1,3D20F7A2E5731F0C,2B29B79096A9A245,442A49AC773CBC4F,8C9CF9859B34BF82,501AFEA57BADEA05,0000129D4ACA0106,178F98476D8AB26A,9DC62E679AA869E3,DECD81B5A2FF4287,8DD6832E6B6EF36C,8533453283620828,6A84A82FC6B3D1B5,000197BAD1C5D477,93925BD16ABD042A,5B030E05B9063C53,824A1249B247A538,ADFA2CAABAF7C92B,2E7A521CF9AFCEAB,BCC6B69EDDC323B4,0000CD3AF077FF29,53A04F6B25F6A6C8,C4A36CBC920C9A2A,4537BEC88ACAB5D5,4396585634C774FA,02388C0567C6C115,8960F3C52683471B,0002159BABBE40A1,8E181A54A3EAC58E,CC830D29DA4B31C6,6031C923DBFAE762,B91C3EC32F9D5EF1,8A604191C14B20BA,E6896FC47296750D,0000721A410246D5,3ED39D51DAD842BD,4ABBE270659232C6,8A7C0E0FFE61205B,B8868DC0D026C4ED,328265C8CE6C19DC,0B972C30EA38E6D0,000122E113BF4DF2,D5410541D093064A,0B70528420E86171,33365F520D16096F,936F54BA7D586F9C,3898A047C9023797,28C60F3579AED73F,000138F0125D5C95,DFCBCDFB7C4805AD,B43E448B7E3E9DCC,60F9ED800A37E9A3,A03CEF6F6A56CABF,78629FDCE61E92A3,96A258EEBF131711,00017E4757DEEC2F,CC10D4313A8135DD,75C5007A6B0DB985,C7056D9325A4B75B,1A1743AFA537A6FB,68F9031402CDD77F,0209AA4971C2F352,0001959DEB5D742E,7C0C76D84C26F44C,E1C1E195D3933817,14FA1E6C340617D5,3F638152E4EFC99A,B430912D9A805B00,9B9BA4847FFE9604,0001C0449D2076F6,C7275B149DD1A5FE,6B24F1CC50DF7972,E286B78322F22C81,9946C35A7168E865,EE8E4BC759E7873F,8A64BEFB0A7F9A20,0001CB18AA039C25,6D28336C58F73E30,725B50C04460EDC5,5CF888D713FCC1ED,2E54BE3E35D2DB2C,494295D0E946CFB8,7210AB8A084C7982,000042FD9B30D5F6,EDA5D34BD1AAE0DA,AA56DE87CB3C6ECB,44D78A51DD85F9AC,807A46E94372867B,B81452500ACA79AC,9B390708D4F3BBBB,00021366D30116E5,64184C2240999BBF,4565AB187EA5B623,FE53D23A14B3DC65,69C462B66449CB92,B55F63716A7F4B66,AA313D1E702C47FA,00020B4B0C6D5E06,28213AEDB766D70A,BC56B59ECADB8DB6,345EAD5E9CB094E0,701D53B4419D8B16,726F4BA122BDB4F2,7F6277F789489550,000147F55DD5F077,B5DABB19882D1CA6,D0653EBBA634DE3A,680D1248F27389DD,DB6C05E99BFA018E,BF3F75DB70F8995F,95C9F02E20BAE066,00011D27A38FAC46,E5780B696D0047BC,7F2326E9BDDDF8A7,9603717332134044,07D4EBBB5D346896,532D2176AE4DC1D5,44A1882B27F3F864,0001884B6C3617F0,6869618B986AB9E3,6AF03C28713E04B4,34E132B80B8B3F37,303E4DBD03F8A262,F1AC57DB3B80D94B,0A1593F83270A71F,000020FD628C05C6,195D43C00E0C5A7C,CFE78F2E07CED9BF,72DF12D5BA3F6638,BA30C462C8626994,B1EC4DC347193829,1D7F028D72B50CF2,0000903AB5EF5106,07606F8454C62194,46A4C41BE40D7849,39CE9CAA07070E7F,5C8FB682E872F843,56A05C134BAEF6E9,E4C90ED6FEC5AD4E,000018B9769DDECF,B500561B57EBA29C,4D890A9534362A6A,54AEBC2DFFE806E8,C7AE4B3426DBCFA0,67CB4E28BD96981B,D1AEDA4BA1B1FB42,0002228B040C2C5E,67CB873DF8A2C398,8B29E9790941BF7E,B506676E78C68431,76DFA9A848602182,B2651498D5519975,35771E20E10726F3,0001135D89F893E1,6711E4468F956C38,6C66504A6FADBE92,0620A2748025FE86,4351E917E9653395,06993BCA968EAEC3,4636DC368EEB8338,00002E4F9A43444E,2688274E05EC15E3,C30290D7C2FD8F2C,9C3B86771EB6ECC6,5E42E53351BD3D1D,ADF69AE1CF78FC3F,A75229CBA120E2C3,0000AA81D63AFAC9,56FB8635AB73ACBC,7B08C4A69B97F485,39BCE756FBF1BDA2,73C83B07755D36B3,883DC07CCBA9C937,7637206E603F2362,00022EEEFFBDBAB4,A34FB49D5C921E6C,15D9C3506829EFFB,8017067261B8E6CA,BDE7D62EC1A1B5DA,9092286EB292FB89,5E1AB75A3CBBDA4F,000103938A4B5459,AAD89605EF6DAF0C,FF9BE7486AF576A4,49C7767ECD4B434F,AB32040DAD7C4CF1,1080A5244019ACAE,E49CF12D166A85BD,000036E406F47997,F86E6720378A8D76,B6C618C98EB2D0FD,595B15ECFDE582CD,9FCA16F68D4BBEAC,205478615AEB07E8,E59A63B3A2976B2E,0002270C4E8162E3,9713C6BC945DF6A0,6AF51243CBB0BC5A,11A4B45CCA01545C,17EE1491BFEB3D07,954F158CC7A53D17,BF90F17673C96F75,000046C02CEDECBE,71646DA3AD066784,5FF729C48A433944,D5D299F33EB51832,5A09CCB6E6729F56,D9CBB96E478F9741,2F3C87064670CFD8,0001E98A0BA38AE1,6BA17E7A8F4A8960,B5D0BB0E76D75154,843B4D98327A053B,36C0DD431984DF23,6CFCAE77C78C641F,B0D48FAE4CB04739,0001B7D921E5D9B3,0FE2DD134E99A582,087478C7119D9C2A,73AD49C3B9AA77CA,AF88BBAC08974F3B,BDC2FA3DDAAC6D91,ACAC4CE1DB25E4AB,00020E1626F6CD7B,FEF58A08C03A8514,AD9C83CEE35C3094,63DC7C34740FAF1D,497FBB8C2A8F2416,A815A25221E4BCC4,12B51BBAC77A37CF,000179009F926B0D,9E41417F1A1DA33A,973806A75E1DEF4A,6CF76B9285092309,123A7033869EC304,28A6110D1057831D,B98FDC2F6E1CF3F6,0000D56A39115A66,105D856279443F4A,A835B4D4696C59A2,CED4F6077405F53D,350513C07EB65D75,2470E3E8BE5F66F4,F432F04AD3DA6939,000131B20AE96486,4490A47DB29FAE6C,28B76AAB02C717E7,790CC2B39994C5CC,E509A1D16AEC19AC,982A5787ABF5E521,2BA5E86482EAAA27,00009DC7CFC39B45,23976930DF0492DF,7212140DAFAF2E04,DF00140D54E2F3B4,69C129B57C8FF828,F6D747AEC2296BE8,9E29B46DB988FA8E,00006DEBE8C3D340,D3CB76800E25D461,162298699ADE5D6D,A6D9603BCD217A46,284E370F81BB51C9,5D059DCA27177796,0B0D013EC70CF92A,00014A875791DC1D,32C14C775D1D7F17,3A0F1AA1FCF4F7CB,F2018CF4B9AA522E,12AE8F660B59E7A8,A5625F52494198B9,3D362EAE0E84B0A3,00016C708BEF4B2C,06F0AD69D242E212,9165D0186665A5AF,9D3538FCBFD479B0,17C924EC609C82D1,D48C7937407F3B8B,BD041F9AAF1016E1,00002AF4A06F96CC,B9D79BE5D9AFF3A1,25B9251C88EB326D,83FAFD08B9F46F7E,EFF73AAC816458D7,C5FE567323AB9CBB,E9D215BBF220F7DE,000119C19DD2A164,7BE48B8B2A004A55,769A26A3FA3AF6A2,DB4DE9C7A1229B78,8C8E28593579581D,B06837AD5EA3B976,9B6B75024B1C0D5C,00004D2777704721,E4D60D23944C84BE,F5C54A183138D642,5AAE7624775DA793,8B36666716372609,DD43BFFA76CDACBF,CCC2F8DCBB3FB105,0001CD44A2EE827D,4CF7EBE4E9EA3DE3,6A050C60C5657BD5,632920B8D3BDE5A1,F4FDEFE3DBF59A0B,13C715641257C5A4,B7C2EFA8380250A6,000231FA490721A1,C7FF61DE6BC48ACB,E12E0BE469935E5E,216A909333808A52,AEBFFDDD33B3AB4C,74E028367EB7E146,F5A6FED7DE7390F9,0000A4F875E30A54,2DDB0C4467F3B096,4B9C804850027C87,3B3E059244E361EE,A3D4502A459C29D5,603BB792FD548782,E51C390EAB618784,0000661A72C3C300,A6F5019003F4F264,FA6C85AFB86104C5,18FCBC71ED0911B4,2696769E7AC50892,7CB769C44F7D6666,223F804B8DD0D5B1,0000222976E52520,623876015A08F9A9,99AC69724B747BC4,BE11143A85B3C619,AB9BE8A087DB4CB5,7B37D9312205027C,DC584993EC9CF80A,000120488C2D9BD6,FDE273B8080D946A,DAA30AA10F1559AC,6B94BE96A8FAB087,543C42D82163D6C9,066F3845AC288428,6AA1DDEB83C5A2F7,00012DCFDC0B3953,F7F5A78E18E118FF,EF6EDB87A851796A,4A883DB133BFF88B,A47854C72AFC211B,E271AADF9E9846A7,6BC058274F89287F,0000A85D9B922380,24DDA7B31D7B1D10,D74E2236DD04D7D7,14E80A0CCE4C6CCE,5EB981721804DFE4,195938B89CB494E6,7805883C70376DF8,00019D235CF7902C,4A902CA33CF1D812,D18FDFE9CDDF5847,A0ECB268B6F6EB6B,70A51111AF2C3FA3,2F9404DDC202F4C7,6B8C4727D32B91EC,000224CF9FF59193,7374681C9FAABAFA,2ABFA15FB82B854A,E084FBACE5D54483,9B88C3D7E7E634F8,1904E2F29A7AC1FC,7CB89FBC66BCE333,00017699E62D31CA,E560358D51AA99A5,5FF39E30255C4DD7,FA9CF4CFC4B60F4B,9212D22E6F17C6F0,8D72E2C99DB0E6EE,21ED79954BCDD788,0000F90C6B97F33B,095C2E994239394C,45C7B5DFC6BD3990,F0410789606343E9,59F6302F2DAC96C6,B563075CA92A90F5,C1C6F269005A0A21,00009C12C9131A90,1D58C456C349C408,5BCEE2CDD67EB50F,B448775323C48CF9,A542E8824557BD6D,718644FC8B1C7F6D,A5AEF86A8F55E260,0000BE3FC3D65CB2,9A94A6CF063B0255,2710C93FE7D25ADF,1A2E92EA2A556BAA,98CC2271A6C8C7BD,8FC771F85B4FF377,7CC5675A6CA3F1AF,000079058ED91BA8,2C9273D40358B31F,20CD7753396FFE4F,20B42EF675B817A8,9CB9D697FD888D9C,B81A8B7BC33FE278,7D958DC68EC555C0,000166BE6BC686D3,97187E81234D2BAE,A45F1A6BA1F05474,6F9268E4AFF49203,67A4E8C15853061F,CB4F8A2BB312CE9C,DCC508BD596F3D26,0000FEF3C4F12C59,39CA940207A643A8,3BEB2552177D48CB,7B5E25E7838FFFD7,E57119933A0F1713,BF6449423A797F6A,9FEE983A7AE99938,0000DAB0544DDA75,5D4959A63824A340,57FF7C86C234EE8C,5AFFF6FC812F86CE,859CD13884D658BB,CE80DDECE4FEEF62,EB54C071E32146DE,0000F3A10280F839,564C74EE16322B75,27321A8039395531,E2482625A82D6A62,72FC01212235FF14,1152054A9DDE66CE,51D3A2768B1EBF71,00020CB7D51DC802,625334E81E1EAEC3,58E530990AC07825,C28A5106F4C72437,AF5CE43893912685,915686660CBE1A9D,A19A35CC6DA3062E,0001FE7117DEFB04,2730062F37218F92,FB8B7DD32A666354,E6ACA64AB9FD390B,F2876F4AC7134EAF,A81D2730A964FF18,4FA14D823DC16E89,000133DEB6AC0CE4,FDCE38DF5776A74A,F36A3A377F7761A4,57550DA64F48DDD9,FB58AE0583079826,758E9BFA748F4F9B,F4169799377EEC88,0000283FE4403AF7,13FA6DD518C2E57C,01C958342AF2332E,E94900CEBF4596CB,41357DFFA36C0443,77B1A85390754E45,3174C1456242293E,0001BBDDA2ED65F4,901030CD5BCE363E,BBA0CC9C88FDA9D7,852756730F9DDC75,52DEC1D63C482424,3248E1B719F2923B,1B9B6C13CEECB776,00002C5B2998F024,7459BD7BB172F50E,0E6C94D8367A1543,9D735221343C331F,25EAA4E2E3265D64,BD97AD262D650F40,882A50EDE7A47237,0000E82B2DB80C28,15A9978F10B5F149,20E6B8E913DC56A7,E2D92AADD06AD899,65457E827E4B45F9,BEC45EE9002EECAD,42A30CFE21E10D12,00000C6EA7BCE5DE,080A2247D02D9EDD,353BF45A5A7FB676,A563551A561FF7ED,D2D635E40CFD5E28,DDE98AA30866C92B,408F81E566D14EFA,00016D0AC3E59BFF,AEEF632F9D6DEDEB,34DB9B4AE389626E,3A9FE1FB2DDBB442,468A7ED382752B62,DFA4B3B1852E5EC9,5A9034F164F4986F,00006FD8AA1DC59D,7EB84A6F578D6588,136AC6ACAFAC2448,3BEB2BE425D9CBBE,DD3FCE7E3C250143,8A477AE935454524,AC7429E6ACE4A868,000110893EB9E1E1,AFCC82941858A893,89086F2628597463,06989ECACB625E20,8999E36659ECBAEF,40A939CC265E4ED8,C233121934122EAA,000113AF794EA65A,538AC3F1E58338BC,000239A175D00B11,05DB2232D115FE7D,A80AA129A3884CB0,A5AB7A431EF19FDB,0A8D74FEB720A813,000165DC276FA45B,8F03690FF465FF03,5EC5D2C0F887BB2F,3094AC0FBBE8FD72,83C61D82FBDAD1E4,E930110D43723E8C,E4BCCB5DF3D9B842,000147404C913DE0,C62A03D77DBE44AA,BF8356DD5913C689,C3DB2BE3C88F4672,7CF5F97C9BE26321,F2EB7D587F67F4C8,487BEFFC4D46052C,0001E8DBC62D6CA3,819955DC8E62F217,A6479CF341E0B79A,AA299A64ECAFD15C,9A5A07710D29FCF6,8CE34DB704A22582,3CEF0EC419A1FB03,0001BEF9B709FFAB,6B60DAD219ABED73,33565DC6CD08C2AE,E41CEF457198E7ED,391CF2A0D11AB66D,2EA8A8AD13F29D64,CEEA64D04720540E,000005D032645449,D8D0F5949F15E11D,56D074C7A2E10AF8,F16BB9B74A5FA619,044B1E6DCF3514B3,F6C19500DF474751,E864BD3298F2E401,0001BD106DF50C68,8489EBE1F7796E43,85BB6AA3CBC6A44D,F32FED21684D2E0A,57CAB2D8A5A9B50D,E0DBB0A7C22A405F,31083324A8AD5120,0001B9911F8219EE,31D243759B66193F,52812AE2B8AB4010,73BFB75372015E4F,5351C9B7211119F5,7311D4EBF112C8DF,25A11CF2E7859169,000087E97F4BE176,6C457AFDB222FA30,8BAED55176F5A999,DE18E1DE61AC8638,76408DD51E3B690B,953D166B747A564A,27CEC7F2B93C24DD,0000F005FB4A29CE,38440B199EA98DCE,55782252509A43DB,CCF85A7D7F544F64,94A009ADE12A8A74,764B6A56CF61CE12,390B44602679FDD4,000086922FDD349B,0AB10C8A67A46DC2,CD14DBF6E938334A,261A59ABB1001D09,2DFC368D51A90772,152F59D693BE3AF4,06D0CA06267903B9,00003A04AFCB55DA,0440DBD2EF66CB98,9D0E3F493AAE536E,703FB141F017F570,6606CA05C45AB8B9,5C0E56AE06832260,D1CD517AD2BDDEF1,0001E697CAE18DE2,6FCEDE3DCB0E0EBD,E0B8509B67A68FC1,F46D610F064420A0,4ADB1F760441D1B1,686126026EF6EB54,B3303BBD381C642D,000134D95A66FB8C,D64F00C3A4BF622C,0EF186CCC1E1CE01,1C6AE542C626CB4E,1367502D2391E0DB,A6BCA4C20980DC04,81CE3CCFCEAC0AEB,00007DD923434123,610DFABD99E08D08,1F912EF04BBEF35A,9333ECB90EBE2278,FFFA1A665F9D5A65,3041DEEC29CFCCA8,CDE93D66A319E9B7,000170E571177B1C,6045DD5D3548E45D,B7D85C0C7DCC45F8,C22A076DAFAD0818,7B5798466C0E7974,A3DA450658E672C8,5FB0E25C03632FAA,00007345EA805A1E,84C490A48762E734,D9D5A2121C4C908D,CF569ADB4BD75E55,879EF9A86F62A25B,94E7D1FAE895D768,AAAEF80EF5C7B689,000156FC4F666604,C83AE0309ACF3093,E415D4FF802D1981,43FC8714E3F2FC5B,4B74ACCC931B1DEE,0B9BA7DFDB44C380,7CAB0703F445F953,00003FAC4B84DE34,2AB70DB32CF691EF,E32BBC928E671EBF,00509D4D50CD55D5,5AC6A9D0A95BDAA7,9F08A1752DBBFD74,C1F613F1468E523F,00013ADEB76D9C76,676553185DCDC0C1,22144F92C76DEF69,01EAD0BC69BE314F,163B1483EA1A8412,B46D9EF1E23EEFB3,507B7F6835DB83FD,00018F60862C39DC,CE6EC5D701FFDA58,A1FBA73BEBEFC1CB,54ED5ED4B46AFBD4,8ED0006D5C62CA92,8ECCE74F0206CEBC,DCD4B160F0DB294C,0001FC74A2012289,15D7BF7B231B3B2D,8C60F596AE154F5F,473397219B641094,81B224823729B3D1,3E80D43D89A8F409,95052CCB6B5D278B,0001CB58CDC1C7F2,64B62820CA177D9C,FEF641546ECC605D,A4782ADCD44E62D1,F4E07AD179F6B31F,0BFA3CEB09208800,31469BB0854285EC,0000BBE2AD418D58,7BD4BF89B90ABB17,90C7D6F10E13D0E8,4AB2F5ADB26BB15A,316FA139F1811578,CD8C663833971F6F,912410B4F547BEAE,00022F242C096F69,6AFC7A3956111B19,BD7D1F71CAE7DA08,3583DE86039E05FD,0EBCFF53798112B0,DA8750490E90581A,B7D72138E308306D,0001AFAEA7D6614D,85E89B97100CACA6,3F079D8DB1F4E6B0,173D89FD71DA43F3,DCEE209C573703A5,439A80DEAD55C807,B3AB5FA83C1509AE,0000E4D390FCF785,B3D007BB61F95CBA,9AA02AC203EEC6D6,02B62ECA981ED3B8,BD1741DE16F81E96,5133FCADFB4DC575,D8EE353A8A9E9B4A,000219F432F2F5F1,5FD80ED39328EAA8,828920084ECC23DF,C7B70FC680A7F2F4,EDBBA6A2AF49A200,2837556E7BF08509,53E4939E9D52692F,0000F0E58CA5239A,880ECC469A28E883,741E40BD3DC27BC0,6242402AAF49D26E,B5A18BF816F889C9,27AC8971622526FB,449E6565E90532B5,0000E157A5B76473,02306BB9EEBADD94,D26CC55165CFF862,41C44BC7ECBEF521,279D4346A9AB1993,5834A05381E1BEC4,2FCC6C4D2AB1D6C2,000115694C58F1FC,06893273708C4A99,D232DF10F4A6FCF1,CC2D8BD7EACF1F70,F75ED6C1A3D6E5E1,40A0271D4EDC7E8E,4B71D6399BB7E2AE,00020684FC262E40,0D01432A4E6069D4,D60D11DAF31B85EE,D3F0AD1E102A1C34,0A8DD84D4C416915,0FE15117696E4981,42F72041C83F654C,0002304BDD439E69,72662CEE64944479,F51E4F59A076BC5D,A0E602CC617E13AD,20F525A8B8A2C177,7933A561F0225A78,E6D005B1525F0B75,00016DA8348AAD0A,0E17AA90E00F70D2,7C15C3102F907C77,3DFAB9326DF7267A,33C42F6CE6242D9F,4DB831C9F96B7F3D,F3DC012B1F45E9B2,0000B11C1AA79B2F,289E661949E50691,D783D5218400554F,D8D1C7071139D008,B8CBB0A809863858,D6F3E477E7EE63FA,84EB39ED482FDFC2,0001D246FD07C84A,578B8322E3CC0AA8,40410D7EF9F37817,AE7383A6DD303821,2E378A4C14EF4859,55CCAA7FE6D4D5E8,54055055C8576F54,00015442AA041818,EACEC6CFF1C13ECA,B33655B512557A74,0785D6DF1EEDE19F,1C913285D217BE5F,5735C985BE91F88E,B209F1F1E74EC68E,0000E1BDD7D413C3,0570481FB846B980,F88EB9E1CA6DBB65,9DE300573F03D9A4,691E9F0E95168822,F0FB7DE81B06DF9E,E7661D6A4DE3F6FA,0001CE53A864B95E,C6CE50ADAC5F170A,C364D01ADF6CE67F,8808F3DF1A25542C,B50B445A931C4987,9BBE8B8398B266A2,AC73C0803C142EEC,000050BA992F0E32,8C11C50CAC736F42,CA537214127CC969,9AC1381033D1E943,DC24EB7E8A24F988,F93E03E8E08CC4D1,F8ABA5716632E713,000073BBD6997DDC,FE6F115917AF34E9,5E3C5CEB184220B5,B1C6657F42B99A3B,4E1ADAFF82DC3EC5,3E5E17A360AC849B,D06F7CE78B221AE4,0000738C71CD26FC,13605F0D867AEBC4,B5E4722A820E69C6,4360B7C0EE57D6ED,54A4D496BB748945,6C9051904827FAFB,89716C501BAFF2F2,0001695EB6E43924,88DFC9E90259DB96,42D8ADE7F7ACBD2A,C641B5C706DE335C,A765A3F9D394D21E,F9076071A17E9CAF,ACC75CD2BB073EBE,00009EBBD417B6D1,BE0208C2816090C5,736EAC9AC72EA6A6,5E7D8895CC27B4E3,CADE7023A852DCD7,A027D4349DDADDF8,C78E7F141A9A5125,0001E8F8D54BEF69,0AEFFA99039E3911,8E085448BA7D8CF5,BE39F08833915C11,38D866119C5994BC,BD9CAD479BC4DE47,180C57C0011F1819,00008F6154EBF6AD,ABE356D428FF310F,3988BD8702A707D3,C7EF9B6138ED5C9D,CD7A1648ED63ABCF,EFAF0583343C7778,671873C9B670AEF1,0002208C5AAA93DD,FAAE88E2908CAF83,EF9AB2BAE520824E,23B48A6042786DC8,3BFEAC78C7EFC697,F5BD779194FB2ABA,571F237144F88DB5,000025A4869AC2BF,FCD331AF76248C8A,0B5044EF1980DCA8,49AE3F3D66054348,3B3D576B6BC56634,D40B81DFC46CE3EF,E2E62163843C1FD4,0000CDC812C9FC46,9C86F8083CA481E0,79BC93A2853B21F9,BAF30392A81C50ED,B0ED84D591CB7D37,286007BF4479BD8C,2F57F6B56C74CAA6,0001132F3DAE3C25,EAD9F6E76EED3405,D806830360716941,64024A4A5EA727EC,963B175433910641,3EA6A8496022192E,2B11DED50E582DB5,0001C0E45727CB83,2C4D388900ED53EC,48706010BE84FB9D,3C2E31F01E5F0267,239428A6D2E164D2,53C378662DFA62C6,D74A5492C6917262,00009E7E4F17124E,79FC1BB171F37F07,93C45C166CF5BE95,4D628DA3D54B8C75,D8F8803729FB535C,8F48A1E10C398D73,4A844C47C23BB090,0001226BE0D1C402,7D5DA786568B8C54,A3DF804AB8BFA7BB,FEBF0CC1968A15CB,C95C9CA63FEDDEB2,87AAB35DC3231324,F035ADCD6174209C,00000A281E654CC9,37E9EDE31E5B9921,A8930C5C9B7E98D1,8F7269CFAF3B78C1,5314C97F9E4B943A,9719C6D314F944AD,B4509BB881C22951,0000F881E9380193,9CB932C367E5C920,F87D25FE50E9E8B9,5C59EC9BAF4A22C4,34F4BCF9E5F4F074,C5C2CFFA261D8BB9,42961720EF72E71F,000140D7DE099BD7,47E645AE1A90E6A5,558353D1E87F3F64,91D82EBBAB40FF83,BEE46D51D4DF2014,EE4326540B67D0C3,816E9EE762B31FF0,00000C785773F834,33B62BB01BBB35D2,2EE05F2CC093A584,F2E79524C9FC683B,034B4FB05278D1AC,6C854E8038050419,E9810367FBD8EDE8,00014ADC2949FBDD,7D3C082AE28015D9,D2D70DB48D783170,1A0F2D0137C96442,28CF8971876B910B,7C633E18CFE4F438,18B31B914F31CCCE,00007433C89F3CDE,9A576139A43C9248,237DCD38A5155625,35A3A9F5D53214F5,29C596B44E33E646,826A284CE055154A,31F3FCC23A87F5E2,0001ABB7BB26D494,22BD6A506C8DADD2,CAB166159D554FC5,5F16C89805898F00,0BA8F4624571750B,677B30E150DC0641,BC2F91BF79806490,00000942BCE41B0B,16A871188DC33A67,468C5E9FA530F10B,C809F2C680D97F8E,9993D9A5F1C931CD,770173BF5488E51C,FDE9977F2851090D,0000C5283BFD319C,ADCC685D2245C76B,933C9BA25ED19D84,317733B7937C2A20,5ACAF9638E6BEF73,2B9489BCB48633B3,C1C6446FC3A027B5,00008A45A6F7BC32,F2C37D3D7F25F2FF,19028C677DF5C3FF,EBEAD4A3D6A0B2C1,69E07B7979344DB0,EC3BB7F297D13470,8DB0FA23653E12CB,0001A9CD95B36A53,D93BBD37A00B84FE,38200A6F625B6702,326B07800E93D8D1,5D80781D3B8B2C60,EDBCE17E61AF76EA,4A5EB79FCB569703,0000B2E171217643,98E095DD245F8ED6,5A1EC3BB9FE8B756,9B6D434102891686,A6DA0A2229C3E542,AD7AA08C791CAB97,7B66DCCA5B01DC4F,0000BA9FB757FAC2,3E4AA8F04A5514B8,9A737743383B7B36,83724E3F58ABF0C3,8B9B3399124C1636,9F413A524B7F0B52,EE461CCD7A86FB2C,00010415E0C01E5C,CBE32E8BDC2C5B3C,7FB62E643F39B36A,064CC72169F77E22,B27F30F0FED7CA86,8105C1EA608133CA,C9E6C6A04A4AF95E,0000002EC08BA9AA,4B84EC8A562DBA0D,F63BF8AE7D9DBA3D,CBF74B580CFF9867,E3233438E0F09F23,1B43FF93ACE5F27C,C76F6DF1846CB38D,00006E1260243E67,DB96F56E6D5FB4DE,570DDDEFD01D876D,FDD41F669229DD67,33FEF9020503394D,10F60F3A8641D2D8,7A8DFB6305FBCDFC,0000D3C4389F2B34,A27981EEEF565A52,D6D4BDDE3403FC51,591054F45787DC63,6FC5DF0E3D752FEB,EEA97D066FA191B6,AEB40218DB5BF211,0001F0683E337D2C,AAD1A549AF1202D7,F1306A05A9DBC9DE,9AA52E35515EFF40,C6FA6FC47515DC63,AAA81152432615BB,35666982877BE98E,0001B25EEBA706AF,B3C35CF4027184FE,C343CCBE30FCB3A2,F5E16A370A229FF8,44F98C5AA1FA9BDB,72533790501CCA41,6E8693BFD3E078AE,000162CE07764ACC,4AFDEF4AC3CC0065,95D51EDB15780033,6623DC3F037376B1,D5E3C524A2587A74,AFFD7FBFF398708E,3A207C878BD13B7A,0000B5BE4BEB023E,C75F3472B1A85173,D27CB8C55C01FD38,6B4F835618468DF4,4527D50D4A6540A7,466AECE50E780AB6,D54EE55250475210,00007101341C39AA,350613C412A96AED,4B16B55D99D679E2,CA1512DC14BE8AEB,196E20EBEFE2C78D,265806727667FE29,717701038FEE44D6,00014EF99956C3F7,63289C125127F6E5,3BB4FE8C3B45A889,95255476CF4AF87E,380DE838F25547E5,C870904690F5E3CF,3824BDA34883D375,0000E3135EE6A891,DC8DFB9AB25F1469,8FCA484C2EA49758,7FB3B8472D7B3736,97311D46024C7F8E,37D290D09703B0D8,CE534F7D754345D4,00021662261F0882,88AF58645E60B132,E6362CE10825AA41,2B5E6DBFD5714041,0964DD6315F28537,29D13030487433E8,BEE600EC88CA3728,0001ACA2EF050790,74F1D69C5B3F4D58,8C10C59C61D797BF,0E5633850DB56379,EE2B4F99657977D0,95A04AE55B92F9F5,A59A80E345573204,000013D49103656D,1C3FFB79B7704A72,F63065C052F66998,2E2DA761E51E7FBB,B323D20294D4FA42,15D09718EEF30C49,0E957F6CBB473DF7,000214E68586AEF0,217386AACE7BBB89,CDE5D9710ECD2DF3,CD5349B0F8E20028,11BDB94C2D4A47A5,C4C932BBAC094222,43AE58D8662B12C0,000036041B030FF8,0A1735163DF2DBDA,0A5441AF261AA50B,56F59115FA6E8503,AA94B68B84BAA63C,09FFA56A80E5D96F,030F6B8AF79106B3,0001403943EC97FA,7D1F5D73F76FF357,6EE99E244997982B,0E67C7786F0C50D2,F23B5420B52B53D0,5185FA1FD1C55841,49B82357EDC754F1,00011F8A7D1D5F20,0FB71F5822983BFA,0F284640AF455C93,C494F0386DBE9757,D08543D94A0AECE3,1203B97CB0140430,7546BFE82F30379E,00003EA06F568F1B,223E88FE6F1B4948,339B48072BE9C7A3,1EA706D1C8859C1B,5F831876181D4FD0,3F3E2572217AEC45,40E0091276BA683D,0000156D1D5F8631,2757117B91B4A7C6,5B74713C612B441B,655C7B3FE61D9918,4487AB3D88565A52,85B0B61A07F5DB6C,536F2BF750A5012F,0000E8C51EE4D880,83FBACD3310C1FD3,36343A80B72DA40A,D1E4262843C2547C,5EC1A041A5845F6F,0CF8118A875686BE,B3C78B64C9732CD4,00015540AD120B54,8F9E568C2EAE3564,F15224473912BF82,D392025F4CCCE263,CDC4A99B2D1BF052,BD48BCCBBED49568,EAC87A2B598291C9,0001E34F39609869,4163A41980E0D379,604B4DAAC7CF5B22,9B5229AE4141BD1E,75B4B0AE3311241A,A880DC198B4AFB49,34F5D3924B68B4FF,0000D2028A37B19E,8BB5F010A26D0B7F,E8F7BB82ED4A0386,9881999C63CC797B,96474B95BC6091C4,464BDCEE5A7DE3BD,15EE33CD7ECDA385,0001AF09D15DB217,E0EDFB4DAEAD63BA,1BF98BBDEFF8343C,9D51D945A94625F1,4B35A3D57BBA5F57,E07A7E80F06234AA,B7D8482C6B15B4DB,000216E3A32EABFC,B72744394FC1402A,9452AAE9E0BEE368,18D278B5B4D8FD36,028682E3F6ABCD48,BE63E50DE3E550C1,1F2FF40381B39E33,000095F3DE85694E,6B1F34DDD83C7961,E7BB51C53FF82E02,525A91A46DD7158B,DB309CB70801EE3B,D0E9499089EE02CD,5C3303C70475F419,000156FACA6B70BE,336E137AFCB0688D,C2A904F54008251B,6C6CD3E186B20BB5,CC1CA12A596E70CE,0D5125595C8EB573,8366E00C32C4AFA5,000213B0F3DE25C3,12CB11387D0E1247,8B948D25DA6FE598,902319117F24C1EE,04508553946F08A6,4BB3717EBEFEE9CB,F54E357811E1AF7F,0000329996C7BF35,7E7EAB1F276BA202,C3973A35C211C8AC,6EB2090B5AA2E453,0F1B87410E7AC7EA,60EEB312ED4ADFD6,10C8AAA64C32FC1B,00009CD4B509E3A5,B4291A0F2B18B33C,1BB875C19FD7532F,66DD90D6B31DC899,AD1ECC3EDFF340BE,9C45FF1C7AF2E834,C65DE4096B73AB1F,0001B8F5919A576F,8B04BE81E07153A0,88F8253763A9AB33,9C80AC40DA37EED5,8B87951C2013B2C4,B365456906124A4E,664CCE52F288162A,000140335BA62950,7CA7727695D9877E,58D29315846AFB55,D1DBF983C0C3DDCF,F2AA13A3712277B5,597C56705DC0715F,8BF6E1746DA886B7,0001E9B6C775182B,9B16C1BA89326063,BE2CD4F72C6A4A92,71419173D79FE08E,E99E797B397BB936,58C8EAF4F701CB25,43A2E99BAC8F3840,0001D22B5ABDC838,479190BAD02A12B9,B826A9251F1EA32F,97C467172279BC97,CD198321795F6CB1,78D4ECF4DDC0F488,D688A43F3ED1837F,0001410BB4D88E04,FF8A95D87E3AB393,AA1CEA7664FE34E2,2F259063046F10BF,B02352110CD1792E,6F0FC514C280554E,8C36872838D118CA,000005F87D3D8FC0,508E9DD9959D345D,885BABF56F8DDB8C,43E5F9D7F24E126C,50C71FAD1343C1C0,739446F0303668DC,FB22E70EB764F178,00014D95276FB744,3119AEC1557A2F56,B96AE4B28DC8020E,01B90776968C1F81,D4553930DD5F2AFC,B82A0FB3D9F2CD88,514BD178B749AB5A,0001BD9360F4B7B4,FB66635521BB0144,9041F13044A105EF,B27967CB012F2301,E170F384569E5A65,7EC1F5F5C5D8ACFD,123783E4EFD327C3,0002259D38D814BA,391C1AFF5FD14E0B,D638725C338178D8,24DB3260246DB696,0BAA152DA021154C,B757A346B3BBA6AC,9E8776AB55F3D0E5,0001ECA2D6A8D115,0D4B9C377FB214ED,CAD696F160E5CB3A,8D398B7124F73E27,71DBC5C18D1D6563,FAD3572319F922C4,7D685880EEB7F568,00007F06F4F77281,7018BB1BC6AA7371,5E815A2D3946FE0E,12D3A051AE462D1E,4ED345FC86737D8C,72D02ADB7ED4111D,65EC15639CAE25FC,0000309DD4DEA428,B67C28CAE3CBF105,35D9CAB0E94BCA90,59E51403A91DD0AF,F5D72DE70AC748F6,455A33A1E6509DB6,00B58B1CE838A165,000051F2CA32E819,7AD296680D645EDC,D81B5E62BC0E753C,5CC139220B356699,A6E45374731333E9,AE2644563893047F,5C57E74EE605F27F,0000DDCD68A72734,FE662224060714AA,43A3FF8740C53EA0,7BD45557C0956FF8,D36F361DF83B2130,BD7B1683D55A8352,9E48B079627A1284,000001A0E2F91579,45361EC387127DA2,576F1984FCC930F7,C048884DE101CAEA,8CFA4D7343113100,AAB582F06072D5E2,AA879B59A19BDF49,000168A5A15BA655,70CC5EABBEB91D86,9A6EC13F766325AA,A79AADFA7DBBA90C,A1F02B6F4F49EDCC,C09B45A4AFC0D78B,418A28578B188FA9,00008BCF0DF49D4C,B50AC1052CFB2D09,95336E4721D5F575,3AC6AFA0126A0F51,32539F1B533A8A48,51209B2EF6A6C2C1,92A68753E00D1380,0001262E5BA53BC0,C0EDAE3A2E1842EC,FB5390008AF2120A,9FB3E88F22750694,F70DCE62E8EC5CBD,0E2D46171537DA5F,FACCCCD5DB1AF009,00010C5190C89F4B,A16FE7C85927D588,B02E7A32B1763F7B,E872A8506D94E5FD,B170AC91911EC96A,ED503A53AAEC667F,7AFC6F092F8718D5,00006229BFF047E2,9C2A29520342893E,D3F05B617E923E01,8EACFFEC860B8ACB,5837072FE893DCC2,465EE85679AB088E,E64CECC56B684648,000057E74402ED42,A50E3FAA673BE7A2,B300DFC39A63B637,D8D8B989272DBB16,7B6CD05BAA6D7B33,1182A9B34D0A4A97,F838789B88E61435,0000E7AA4074DB99,0BBDFE20C0A6495B,55A4538A114C6F7A,51D2848E4FE49CF4,DF432149350D85D5,38032CF1D9879938,9E906C7EDDE99941,0000242F61AB1C73,3F599F3A9F26F569,ED1D367CE7918B27,295FF6C96E63D8CA,2A367AA4CFF0D914,49E6E989142D8709,B1FCFB31C583E540,000128464D679092,377587EF22DDF18E,DA4E55AD386999D4,46189A63F65B8802,22A7A43589C5BCB3,300C2D6AA0207A51,81B1A059B2E5CEBF,00012418521FB33D,BC2B31CC408DE079,A536314A802DAAA0,42E078683EB512C4,95A83A1FF73B58D6,01AC1681B238ACAE,5FDCDE18C77C0B00,00020A2A2198C256,55279B1AD61AFC13,063610837175E54F,F6E2C3D401BA1E61,B8F286CAAFB89A7B,03842AF650AC65E9,D0AD5850FEA2145C,00020876275CBC5B,EAE295D9EDD7B326,4761292AB1312CE2,B4669DCCD6E09A1E,6C97B1724D72841A,8344E7039DACE577,1EA877C468AC3C91,0001039C6B91B007,B9690741FE84ECEF,5764539F7F0EF535,0DF1EE4CAC0E0534,74312C89440252FE,52804714E143758A,407860531A06D516,0000C87E67470986,5B80658DC4B343B4,38C506607A0E5645,78C629B89D18576B,AE7A204E0C1669D2,0CDC4819ECB44D45,AB9ABBFE1D62E1E4,0000085B042B3C58,0F29C84D3A99FC21,2788992E22887431,0DE277C4A3189909,8B99E1C5B8B09BB8,E7E46B20B52D4234,69F1CDB8065C19DC,0001E91F6E0026C7,3E0FC8AE16A75ADA,B64BAE4F190BBDEF,B1E65D7AE14E2B42,01DC36817DE7ADFA,2A4512F5F6C13155,8EBFA9A51438083A,00016868589493B7,049E319249251885,B814374423A8FF4B,AA522D17B5C85A57,B11A1EA5F4F8D6E1,B9CE8A22092F4573,24C5F782A3CADB3E,0000289EB97AC61D,1E1F25FC05605745,FD3ED75E0DE25574,DC293B3F27D61AEB,9F2C2560420B34DD,7B1CF478FA889F39,DD115540E4690B35,0000993A5355136A,5A83F61CE953C1F6,2386B9C82089491A,6E30EC2BD969DB5F,7C8E21C7840DFA20,965C96B669DF17B0,6841D50D4E68588B,00017BE06FC6062C,6F9B8A2F6F4AFC0A,191647DA8843EC2E,36599D639EF20E9E,59993A2070A7752D,625D0A1DD8375BD9,3D8128E5BE2DA1D2,0002228E20866424,B2BEB6EB8179729B,E7ED7E5A417A8CFE,0FEE6355C268AB0C,966D38CD87523F6F,9972C6B91E582BBB,A3B60D06080A7474,00019699005E6C06,3051BE794A89906E,AB3047D40A1B9CC6,4DE53A4C2AFB3B47,B6AF41B110540A36,DE493C952C1BBEF2,3D14EEE0839E12F6,0000BE7A707766D5,30BCB28B309F2D2F,10FA08E511AF571B,09278D221296BFC4,4942C927E87D88EA,15D38FB2C60218C1,228C350DDFCE9BEA,0000F5D835AFFC3B,D1A6D2271819E06A,1FC05C9882718AC3,7DE8A19AD77CF9CC,EA1A106A59578ECA,C085F5611E2ED845,431A3BCE37B61C18,0000C0F75E4B0025,54F4E7A89CF333E5,1C12E05B63645AEB,7EF99D39E3EFA6E5,9F938C187BB9F0AB,C2281CC15CAF9ABD,C69A07595C632FA4,0001690F631FAE0E,6D14EA997AB75624,02E98188D7362FD4,5066607C8139DE00,FBF13729EC133AF0,7E2369D35A95C408,F70A0A9EA9CC51EE,00015BA503E4F717,6FF56BA88E348A1A,77FB43821C9838DB,7F861D698F3685C2,DE7134C378741E15,E77533961DCFC737,6EA8DDB18481F418,00016837F4B47585,4C0EC2608C5F4A5F,0433E5BF8B97ADE2,0E1850F84F46C936,E7DD27D33372F3BC,FBF3F9F964BC8054,D0C4F7D399130BD4,0000B979DDD16B8E,9A9CD3B1191675E1,8F71F767171E7B3D,568BD28ACFD8E059,0ADC251A71E600FC,764FD3F6D1324DA6,A70B8E2090955D87,000043AD3E69D53B,3594B02998B8C0C1,47F2AAAFCBCE7E2D,A7758E0C82225BF6,9117E3DA0A9EDB3C,38699684F1119CBE,6E61B0299F5303F2,00010C053F27B826,F4BFA3A358BB3AB2,6F9E7AC36B0C5D74,F13F5346B6347D14,CEA80B891E38A90E,AAA83C5EDB41C5E8,CE223F1B15BA00F7,000139D853E2C65C,ABBEBC4BCBD278BC,2FC78B567ECF5C86,4B388B7E1126C42A,0D3E73521A003DC2,7EDA45285C3B019A,0CF31AC841D576F8,0001896EC369779E,B0BD30EF357DC3EE,603CA34C73B295B3,0A31A8360F0BAF0C,2B98B75544078DEB,D6A6CE7FDC067DE5,C9F6432B6D286FA7,0001B59949113D41,8E8A73464230C913,C9469ECAE61132C4,D17981A7670700E5,22B911C0467A2B79,8865839A3411EEC3,9A483AACAD157AD6,000019BAD161008B,E4778CDADAC0F8E9,1CB2A8B3D9225823,B66C74F14368FB28,E8053207EB4C5DE7,9AE18770B14A0026,BC9C11CE766D8F01,0000C7EE73A44C7A,A4DEAAA1E3AC7656,C823C0FB8F81DC87,F43975F83CA91A3B,3BEF213C08810FCC,9C838381ED436256,10C9EF87F5BF0046,00005EA72636560F,C392349AFFE0A661,0A301A660210FACC,A4374C2C9D70CEBF,57EBE97D64CDB70C,F979F083AEFCE306,FF142A2DF718AC42,000190BEB881D898,1B0F7CAA27FF950B,A172B227B25D553A,5FA64569610FBC14,CB84223162C6CE8B,C51847F777ED8F2B,C481DBF4990F7E81,0000C46172243941,FB5AD75A16E7B16D,A00417348BCCDA77,E0A9166051AAF54A,870B78AB21B87BD9,16E3ADD9FEA90968,1534F94303958904,0000D480BCBC7273,E277F0A312BE2F34,0A72BDB044B54B89,E67FC4F35DFCB723,7D7D9924A67BB0C0,4BA7080A09DDAAA8,94EB2AFBD55988EF,00009749A7AC0189,15B32AC1DB037154,653CD0ABCAF7D9D5,28F9BDE0EB0E21FD,3C1878255832427B,99609E99D772064C,DE9C19FB263DDD10,0000EE92B0A7DC5A,C006547EA8869F3F,35CB546F8D1DFF6D,0C0C48F622870677,AC63B3B968ED94ED,CED1975A0FDBE185,83D00F88061D6E06,0000BEA1FDF1C437,CB6DF8251E4C6EBB,A0083B2B3E95FC24,1D61FDDE199BAF95,CE4D37B9F8C65AF8,2106D3B669B23A41,76F70096DF822BD7,00018251FAAC077D,13F9FF5F6A438A58,A1DBBDF9E893350F,F2688D9AC328A94D,E1244B6A23936329,7995E2EC3ED98C37,9D2BB3E620A30647,000191010ED8C9B3,D442B7BE61FE45E0,F2B98DEDDE4E641A,94EE0710455BA129,6864D2E4634F6B22,0778F2EC0C46BD9F,140CEFC11B1E74E1,00000A3EA52D43F4,BB7A41E68162E227,DFFD365A8231B9DB,C28391E9F09C2F33,69656DC317CEBF2A,0AEB3E71F934B969,C091100AC1A903FB,000088A76EC676E1,184C43C1A3F69E89,D6F6498BB920E965,4A92095F6D11EE54,34000A31B2E7CE65,98AA74D98073EA01,6C14F79B8A354EB7,00016446A7A8ECE7,943B3BC9AD0BEB63,2A77870C5F892B4C,3BCD58AC25FD9AD2,57F8EA61F5CA4C87,CB535850F668141A,C76EE046815B8846,0000A2B65A3030B1,095FC77C3871844B,488F14B8C0DAEFE8,935AC1E67F8B0356,63A67778AE9FF6EC,6E184C908BE60FE3,DE4A27179C438444,0000F4311A34472C,159F52F71CBC1630,49AEBFA0A14DB119,CCB02206986B7458,E04D71D8CC415CDF,FEC92CF4A163148B,71B4D20FF24EE036,0001682E0CE962ED,EDE9864477B63455,328C34F514592717,5F2C203B2A9E36DC,5CEBDDF689AE7281,48329BFBE000DC52,6D7FA8672EBC346A,0001D7208BD6D5C1,2B745BF857E01C8C,32A92FC9C438B7BB,004691E739A487D9,6865CC2C918CAECF,06941C4F5AD74DEF,38936E9C9F4B123F,0000C9031F6DBEC2,627AA2F99975FEBD,F14F89D258BCA6BD,D546E0EF2BFBEF6C,BD1D12D4971A66F4,82EC126A2F1C5579,111060561067C519,000067EE2AF50C10,81FEEBAC413FD990,0E027C4C17298E33,F1ECC7C51FEDDC9C,5FC23F86A6E4F391,5B8473F3CBE29F89,6DD733CD6A5F9147,000029810D16B130,B01CC21433DCD339,CE9407B8E7767CC9,2E72555A77D1B817,84BAD594E632743F,D458B9B491179F44,5DFEBD1186F02345,00018FF7B6F18F7C,0917CCDC9D8B1A6E,D36D02B3AFEF79A8,341CC5A2AB9355AB,D58A8E05B10A1E1E,1B00B79533ADAFFD,DCB18E50F93726ED,0001E55273D50EC7,9F39EAEFB7845C63,E20443ACF0A40770,2984F76A610C5162,E5E0B51CDFB9F7D4,401F58F59F8A1879,DDE9BF76991750AE,00003769A5304E1C,FF48D63D469A851F,6A73CBB7FB54A780,80AD8C6BB4638576,375B0AA5B69BDC3E,6DB4047000104B3D,8B4AD755EF483E99,0001B8E8FFBB2812,FCE4881E5CB75EC6,6DAFE5172B914358,8AB0126B5DAB3EBC,C9BBD3B78CFD8436,8BF85F9D51EB92D2,032CD8C70B314498,000164179BD25311,7906FE86FA6F1DD8,63ED266B14EE9474,CACADDD7E1DA78AA,688C2814E53B3121,74B214F0306C3AC3,46DC44BC9C7F683A,0000C1DF58651C3E,4ED9DB62A359D207,385282099CE643A2,B98DC4A7E527D634,94EB65C9BC377DD6,922CF69D72562547,6E9661EF8D05A2F6,00005573AE77F24D,F2FA13063082C5D3,FF133884BD62E0B7,15A2B57F99173A32,B6BCA691B32850AB,22671291C0C69ED4,A7EEEA0975EAA822,0001E5726A483B07,CFF91F58544288E8,8269FF777422222F,767A8D9624D00EC3,DA240CA06E6C2FEC,A936A9D860FC4AE4,431FAF790F0F4466,0001C6EBF25B515D,15FFC9BD84D91AC4,EAC607FCCA8B25F3,50ADBCB093402A45,C6D72B5D9F6E1B86,671ABC45D511942E,542EB3C5B9DE4E71,0001F7099C3F2D92,678C1B54F100EEFB,D0959C1575258109,31A512EFDD170157,47F82280C34BF51D,A439E47576AAA282,22F3E0A14D0B441E,000025E4FF2007EE,641097D94411EBD9,C26D2BF4049D4386,B3CA1FC78D071AB5,3D86C3DA06F0F3E0,54B3BA7713013FA3,3F7C8AA230AFAB0C,00015A72D5EA1D35,E9A27616627A338F,E9B0A4AEC6D790DA,1D9A51F724497A03,0EF3772C36273A46,F09A6B9F324463CC,F6AF696FC4D3A683,0000AD865C3B5CDC,91FA89154C102405,693C3420965E6D80,F98D885133D0D191,A06063670B6F6CE5,4470F825AD8D0121,47D70D4C691BDE11,00007EE30DEFC9A4,42FB9F89E581FA3B,4AC16F37C42609A8,0E776AFAB1E876AC,F695D7DE53652F4C,2319CB649D05933A,D980EEA04DC0CD9A,00008E09773BE8CE,F77E2526A6EB93CB,F5C034193D7DBF7A,3C78CA91C702E523,55E9DC3FDF08D3B5,6FB00AD71203960D,138B121A2A80803B,0000AE1167494FF3,6D50393F59E810EF,5F707669B58535A2,91148EDBF61602F4,1B547195EF496B12,A30C9A0CA64235F7,56FD145D11066029,000013990AB37E9C,9D310B0B2AA1087A,743B46E2F42059D0,885B0656509F742B,BFB2465647E75F21,C5310EA3FBF8DA05,314C023AE917D984,00018F953F37B7AC,3BD3649296B06205,67B4A6AD422BA116,BA311FCF087C6300,D0D7A703BECE148E,AA6E47F8301C4FE1,9321B27251BEFF2F,00008D8821BFF361,0E633AF6C2D478F4,C49914379D0DBA89,7DEB42B72E177036,F572530017EEFFC6,24750F593090C77C,4698FC267FB049BB,000120C8383C83A4,B186FF1DC758A02B,63DFC531DD8621FB,7CA564E602D7D479,EB6C90C85E505F62,AA16CDAEDEB7283C,A49C857389660B64,000142A5BC97D8E8,56F76C4A14D9B1F6,F5B9E1701D74BA16,582813FA2E6C9362,F3A9BF72B6D83F51,6498289CFEA60D88,4D949802B7A52E2C,000157C253B27603,B0C78D9422EAC3E3,5A996A040DF60EC1,2CE38B8C1A68C3B2,0324019DBC145D35,40AECED1D101AF7A,DF05F30D986BF31F,000114F6738AE35A,8FBBE43323433F75,D9F70B1D48F6E919,A5FF95AA57796166,694488909C237501,ECF5CD98D50D4D84,42305A893A3A5B89,00022DB792019D51,648438DFD687BF57,F61E4C1B74B8835E,678F74D7EB0C181C,CEDB6CF1EA300B4E,DD2F2BC0FE7DF827,08BCB92A31D3E1EE,00021401B6525345,7751DCF04B922749,E58042F531BDCCA1,E1CD1314F0867CD3,FC170A8E72428D48,34C70445EFCFDD1E,B97F8135FF785F85,00021BD7B7590D51,C6567CA6DE8CB162,ABBBD12F1DA57E3F,5D7F25655E080D7A,643C34DF6FDD02CF,789B7ADF973B2B11,DDFE75D018238F05,0001409895FC3476,E5896DADFC183376,3A24F0A4EF5DE618,C76673AD21BFE5C2,741AF7A75EB424BB,3106AF6FB5149345,BDF38B4CCAF103D8,0001420615E052BB,A555489CA8CF797D,DF01A3BECDB1135A,B2AB2EBFB8EEC55E,2F3CE2AAF36C7E5C,415A1876FEE609C6,F3F358872A897B1C,0001D8826120B8FC,E88486451C96CBF7,E2E2D9A13ECAD72C,B1873801EAC5749B,F602973BC46AD717,AC54358A8E649D67,C1DABE98EB0C7531,0000A186651A1AE9,232CA3EC1C95A214,369D2A54946EB4FD,FDABB18D37FC7529,F6A30987EBE69942,C2C5EB35EED47C44,6EF117605909C441,00021ADCFED14074,81E476377C6188A4,9342939A6EF03A67,D4200752A2BCE12C,D19864DC7369E144,B371267F42E0537F,3D050962A221243F,0001B48DD7B16663,0D8E246088769BE5,F24894222BECC047,89F28B19A3F184EC,2684DB124538EC09,ACE5F2D7646BDA3A,C9F51B79DB4BABF2,00006DB9E6B7BC7C,063BEAF31DD2A1A7,1B6CB88F1B41C035,169FBE6CEA1B5D26,084E9720E34938E7,90EFDDA4191EF9FE,5F846E6686BABA1F,000203736769E832,BE3C06C737AE4D57,32EABD8FEEC2B84F,8935B6DF6D373D16,261665160CDABECC,77583FDBA470FE16,1EFAAB64FAC0EBE7,000172B908CFA03D,B2495881F978EF98,1183B76919B0ACDC,E43DCBDA3692ECEE,4C397152BF2FC1E2,CCD10DC1AECDDE74,300E0A2F2DB03B93,00016591C5A7B426,0AF1346743AEFDF2,120724EED8F511E6,18DB81AB7BFE3F2A,031F9415AF3FEA6F,7241675D0B7813F5,4334E574BEF027AB,0000697E946D4273,59E13451A9CBFC14,F3BC74A0EA7B2899,2CA65A43270A7119,A903BB8303B36303,029799146D8019F6,D05A2F5CC427699E,0000366B08B954BB,26E173240FF300E3,01A529688A392BE7,7597ACDFC815832F,F8D7C0A9DEB8783A,D30C5E96DAE657FF,D82B537A1F26F64C,0000C1222A77CCB8,58FD170962DC4EE2,B84C1C815F4968F8,6F521842F9BD4DA1,337F6CE88C16A130,DBB55DBA14083F16,8D6A3E5B2A7127A1,000036BAFABDE9B4,B8D58AC83C1A3F03,F087EE13D0076801,BE1ADE65A2BF4C35,C4B1B8C43C677524,D117A872F91B2125,E9CACAD7824C69BE,000187253F46A3C5,841C7B4354D2FBDE,239C34E560DE5A9A,93C34C0010F9D970,EA2FECA543D49695,A00F362A0041F415,AAB308111E1943B9,0001A9646162DA89,DCEC2004CCFF6502,E4997297B02EFA2C,3A67419596E3A325,995BA4FEB92B44DD,E3C8B51D8F37EE3B,FD82DD96AE77DF49,000029C6345BABEE,FD3955F11FE5D8A1,85060110D4BE6B4C,515623082B7F5BB8,EDC9A26B02DA1613,D656F37B1BC0F505,53C690F513916B45,000196F964148511,BCC6F9DFBDB2BD4B,D9118139A4AD6BE7,F181B1269CB8F856,7D4EBCE2E29704B9,DD66A21817B4673A,4D2B02527BA6E01B,0000AF8AB2E28B2F,BBE91FE634F92058,A64E05D027B8B7AD,DC9EB523AAE25ABF,0CE93B1FA1D3B237,9049CA49C092607D,DADD5A2515F00B94,0000776E8B9F5FFB,7CD350DE75F2CC4C,40F7EF34345282E2,3232A18BAC233912,920B6F8EC6B1AD8F,A86E3E90D933DD47,4891C3E30951D81A,0000163D4D2E4C28,39FC6BB2C214DE28,8F1CEDA3A4713405,A0EF3116D15988CD,7085EB4980EB5A6E,B4A6E6633EAA1FEE,995153FEC491DC65,00002B37DF7E4D10,24B0D641638BD998,E7EAD716E43F6E29,FC73EDCD235F61E2,4798D4223A44672A,95FF2BDBEA70F9DA,A534A49D6B082C33,000160F307759A1F,9F412B3B7AF46077,34B6A3E08E76B835,32D83E43CB315E82,4E649DC0516678E4,2541188E52C5EE9D,D490678CE1CEA3EE,0001CF8EB5FA889C,617F884924DA6938,B62C9030DA1649A6,AA5080BC30A967E6,E8B15B49E1E17B3E,D2738282E5DF72BA,82E63930CEE02392,0001CE9CD7FDE3DA,1D8B02811A147165,12525EE6ED0B05EC,5CF6A56E1AD9EA1F,9D6A8C8D72CB5E34,49CDF00BD50305FD,82C622F53FD29248,00016C1D4ED23A14,C9F3D410A1B88CAD,39A3AE807AB8BEC3,A429145FD730E79D,7FFF7DE82BBA3631,BDB1FA2E5A7B8155,1DE1D5ADA726930D,0000EC52C27DEE60,381B382AB2580E02,30C947F399D4E455,8F65DB13AA377953,BC0661E7B3571F67,BB862613135D68AA,C554A1C9B0FA1468,0002324CAB533316,6E1C9A226AA2B0EA,F67D7604245789E5,FCA41A36D71C2440,AABB1D2F896D2A0C,3C21788F2E858023,EB6EC8C272269E4E,0000EF40FAB365DC,670F177E4E8D2407,D2D77112E87BD55C,C9134FF451BCCE12,56E30A297C86372D,B29D5BFFA5C10419,E630EFB50C627408,0000F0147452BC9F,24FC6D54FBB3D739,70D43985970805F6,64D9391F9C6E818E,4E24422D9CA6AC87,09614967652301C0,A1A82854AA548D72,0000B3D5F4ABBED9,947D3BF12AE4273F,B9A3EEF5C875361C,284625DB0D2133E1,5CC38FB493CDC07A,71A9420E8A8F1793,E1B260F50F4F6881,000072B718AE0834,9114E93B8519CA92,CF05532E12D2E27F,E19A72906548F476,BE7C1B3A22ED283B,ECE224A00354ED01,FEEDC2BE3885783F,0002102030FF18CF,A7EB468A88159E08,7482B379A955232E,5089FBE36FCC14AF,C1AB095182B74587,9B7F40C899436F55,177061C6B102C724,000201F19D2E0D7F,96F7D0952CF03BA4,00BEF471936CDE93,AD6699D02C6FDFD0,191742F8A44FF8CE,D0DD627BE54CFCC6,471CFAA2DDB91F0E,0000B23B7B3A6ECB,D7E975EFDBC42532,BE7EBE32CECDC504,AC88BC71193B070A,DD1A7CE520B8BA88,31E33F5865B636BF,428A5F1DE0F7064A,0001AD05C2ADC23A,081F61E90FDEE22D,9BDB22D3DBF4E904,172B4C424EE7A93B,595531CFB6719F51,90C3FFE5A860E188,766F9C816C34F80F,0000F49A34924046,7B997494716701CF,41945D900222B074,6A6B3BE957DC089C,2F81DC94D0DCEDF7,3F7E878FFC19D1B3,B3E93F0313270A80,0002269612929807,636DE284C66ECE9D,B3E91BB39DE0A69C,DB02BC6650FAF782,C25447AAF53DD803,D6E0E79E6ADF998A,0A7ADA45D03FA5F8,000116C95797CF45,BA288815CBA9BBA3,3C159EA9B8C28219,B34F4D48BC2C454E,6746931AB531C735,2189814A657ADBBD,482D3A3B70088814,00014911F072A8D2,89D7529D6D11BB2B,7453062C6BED4536,01D466047019F19C,D24C1CC4D21D0FF3,6F5D4F5A8D06D41B,5F63731C44665442,0000E505556A4F1D,15D87F526BBDECBF,60184D57E987294E,181AD10ED8AA40DC,E22B2FB40DDD1BA0,98E5140120736A97,CC803037F042A002,00023213ECFF7758,27C400E011C82358,A47A808C64BDACFE,D1AB0D7A09CCDF81,D24AB97453F62288,2F135D5FB7070495,DDB21D053B275546,00001F6FB2BDD890,7F18D6868F98B5B1,372D2A30E8045F77,ED6FF463886180DC,DD50AA8122631E35,ECDC6EC104EC6E4A,4110F6F15E3D8311,0001DCCF1618A400,698BAF26E5FA1C58,BDB41ACA242CD208,16A41B92386B83F1,F48FEE4C5CEA43ED,13B20BC808DB262F,F37EB17A44A8873C,000015B081629732,AE9E269F56D232CB,A55B2D25BCB62E9B,E72C7AC2F28C2F0A,7FABE9DA9F1BF11B,1D33F7F5B56A57A2,14E78D2817D45BA2,00004C13BBA4AE0D,031988C6689F49DF,44BB54685FAD3030,FE817A2FA5FA16B1,94AE790A2F1EAEA5,CEFD375DA4283042,2CC375D363C1750F,00018F6317D9EE23,96A7C878BB1EDAB7,40DEF16EE88927DC,47A11F4B4553DC3C,2EB5200C5BD46DCD,F11216909AE257ED,66F810F7D0FD0EDD,000086C7EA89C724,BDC78AEDC89E1946,2507316DAD0A1760,92576B5A54C69E0E,F9DE8220301A0A2E,AB12032BA97BB634,8EAF464C50BB5DB2,0000983765B8AACA,7050FA6D8FD84449,2330EFB0379523FF,9B239F90F6B5D9AA,298B0BC8941CC5D6,A262BD196DCEE4BA,C1B2CB1F5A9E24A4,0000B6CE9234BD8D,55763A0860350B82,903F72F9E27F9EE9,92ECAF5A9AB163B0,53BE3141F78FE963,7FBBF55A04CE6753,70CCD8282A1EB302,0000FAB77E935280,97A1B799DE95E718,6735735B436FB210,4E5DF6EC779EC951,0B11CD030BEF2FC0,8CAB7E6D905C43B8,DEECC7186BE02683,0000A2E8DE1FD05B,B1A5DD4A233B221B,A54D692FC443A4CE,C3535B32632AC1B8,BACDFC2DF8D132BF,7453DE996D1B65DC,D527370DD198C6CC,0001372E31FA76C9,FC513FF7A1AA8275,EBAB567D19E6BD93,3E14E09E2AE10EBC,7CF23652EF97D46D,44EAC7F8D6D21756,71BBEF3AF4C514C6,0001820E9F4C0A90,A0F70CD352E65EC6,5BA297366D5D06EC,172D0496867CA573,A974C0E61C1A78A3,FCB44912483BA062,CF9F033B3184EAF1,0000EC3A1A6FE572,BB001731A9241AFE,F3F2699215D3026F,51777995FAEC1563,DA9C83B345BF2D61,118DD8C6A754FD7B,F13C6A3E602F41A1,00019431AEC3C434,795850F05E5E271F,F78498DDE7B4A2F3,70186C47C97999C6,32A19947F1861E91,9D050A4C6F565CB9,9987BFC34F526C9A,0001A8AA2F68DE43,897EEA13B54D6AB3,BCC1C110541A25D8,D2F1D2FF4081C594,50B2B6126797689E,D6645C1F9E361219,192C50AC1D580066,0000E2B8044B69A1,D227EE067C9228FF,398A95CFA1DF1787,8675E243261FA767,391999E7E98E2FC1,7260A3AAEFC4D38C,A30F88EAEBEAFC08,00016E680BA81CB3,D7B84672C191EC5E,F0793167F5641EF8,AFFB66DF5C034BCF,92B537D95D289E03,0D8B2BD07B8A655A,C206A12B3EFADBDB,0001B4C4A784C2BA,F44B63B96369A385,CF195BC8DC712FE3,76665BA9F80225FA,8764B3C5400B5893,6A71AEC475B579CE,5BD5F48DD10535B4,00020E09A692ABAB,9591C582189350E3,5655D921F5E14D99,5FE29F23223A2237,38DC941C6B005D83,E193C91233855D92,3605D4392B5E7AD2,0001FA62E6D34CFB,0C7DE4DB15CDCB9D,44704A69EEA41F31,7FC700BF07FA5E28,5D61FA6AC409EB22,4033734C53B49E4A,90F078A1818B99C0,00016C6F17B7AF83,40C880A34B0BAD26,0847B1C9FD259A3A,ED39541E937F52CB,0CACD945B8B5AF23,D1C0C703C47553B2,CB902D4B90102100,0000D74B2826394F,25D73CE741F11368,668A44B950A0B31E,936D6EC7011D0B71,B47CAFF6F94A226E,85FB21E9B1524403,AA4EB71A1F2414CB,000093B431756B9D,0453869FE009B0F8,04937DDE2377E3E8,6D29E4F40ADCC056,B6723D52230A0940,761405E0A81BAFC6,1D7471F8BBC40EC9,000166FAB17E2477,209E606C1B0B3E3E,F49F8DB334DE39BB,A9DB3C8C1B17EB94,07DC1BC406F22AA5,74A71B23C37C0386,8EF6AAF2EE75493D,00003F6EBDBD400D,51608F8736C982FF,036A8D9B78374832,0E221AAB047D504D,1AC87F47BF9597A8,0FDF8AE43939A742,113A2720A82CBD7E,00009CBA01A03D95,E6C37FD5E6B8619D,3F2DF8127C083994,F61D2A54A6A79A22,2C859508B25BCF71,50A09C9FCA27227A,B62F6322B85A83BF,000088882CD1B74E,3833DBDDDEA6C29C,0D9A5B3B2C3F49E0,417382E525C9AB20,C53E95FAB42B7D14,859D3723831EAAE7,5D3AC504FC0856E0,000144A2428FA8F9,043CB6830595142A,0C2E3864106321EA,ADDA16615917617A,0C7070F73589DCAE,F2D5C4C9B2E17C3C,26AFD6D7BAFC8C79,00010AA03AC2CFCA,0323DB09DF302E24,1ECE188A530F0B67,7A76296C95EE8EBD,0A96774E6FBDEE30,3902867308187695,9A5D05EB4D17E866,00000580721F4A00,0FBD6B23A80A6916,DBB752775100C19A,5FCE6BD6E51164B6,E72DBE46E280D41A,50DDCD7E786498F9,38BAE021D815751C,0001B10314A0C4B5,B6F7260F0D2EC50C,8C16C335A0788B5E,4187D533017E9F88,7A0285C24F2B3EE7,4861931A336C69DA,40822BDC7AAD9A15,0001B9316667023A,2D0831C265CF01C8,8647FF51B9F9B9A8,EF9BF6CD31463725,1258BDAEED556174,E2680C9B573401D0,B929BD1D9C5D4D52,00023117CE03134C,6262E02EE28D7059,353CFC17FAC1C076,921EC6DD5CD7E640,8DD5CBA3C4CE8AEF,7F03BDD8B01CBD90,BD9A115E6E441948,00021867CA90BD27,8EBD906C144421D2,B05AB9AC931F87BA,77A8C15D66339C85,F87BC517E134126C,49212AE9F55DEC35,E37E65DC8A7C4980,0001C2C443258926,1B8CC19F4AD42E63,03E81133E706E2AB,8EFA02667FB1F21F,AB1C6271A90B1FEF,419DFEC03683B645,7FCE39E8387D6D7C,0000DCC31F749641,BA2D5EA8087C8BF7,82AA80517EA5226B,5CF30FF2DE0BEA79,E62D7E5CE2F6431C,1B4602E5103F8C54,7C49EFDF854C5073,00010D19E8929D27,932ADF478F92CAE0,50146B75B82D7A53,6EF72291203F27BC,122E249A8A5C52D8,9B87B652A089C4A4,BD77548351CFFFAB,0000A77250DFAA1D,B88A7F23FD12A44C,F64162524CE2440B,8FAD24535B221134,937787FD0DB091EE,8A45ED4B551CA87F,870BA995B0F09F54,0000EC58B50C27AE,CAEFC33770AA6A7F,EE55B59C9E3AEECB,483AFE2EA15AC92F,64C5E54547A1F004,FABEBF9EB719C4F9,D0EF8BD9477BB451,00010BD44605A8E8,0033D4D9C5A00D5C,BC8C6598DDE090D8,9DEED6E852D1ABA8,91E751BFAB805FA1,0B389BCF8C609318,390D7BA07091AF2B,00013C05BBFD258F,D9D901171EDDC6EB,76D454CA4EA58188,2E1A4B118DBA4B62,1F59E15E3435AEFF,57C071915292870B,2BEBBF71CC803E5E,00014C6DEAFA9A9B,269D2213AFE61828,CDE63325D2DB420A,3CBC0CD731C93E1D,4BB3829613C92480,CEA4E3ED7DA29B0B,4FB35394B2A137B7,000196B2FA14D4D0,AFE964433BE893FF,D4AA932AC981C620,6B690FEE1880CC14,AEB48FD1248124B2,F563A102BED41524,D9E0B499D137B880,00004B45BD575376,5BE060E58E3F7DFD,607DC5AD258A2103,183A33BFFAA7A857,8C5475C782644568,111FF3CF9AD73713,B330D7425903E61B,00016FAB9DFB80D0,606D5E27C884A3C2,640BA774AAF57740,ACCA4CBB219515C2,727C74F67E5A9DEC,78ED71F2185A349E,67BFE0852EB9BACC,000109BB201E7939,621207936A3C01AB,076B64CAE9DFF6F2,211351B70AA126D4,9377C0BF444C945B,35ADB51DAD723C69,05929E31C8225711,0001C2812F844174,CADEA7F50624BDD6,F1511E569AD59D8D,9957EB319143C99B,76BA8083F5080FAC,B8C798E5BEB4A189,380FBED1AD9AAAE1,0001F556FF5337B1,B7D4CB9D5EC3A289,B6962C9DC550BBAA,070FAF7620F4DA69,4FC408CBBEFD197D,62F3EB31C964B6BA,25C15B846848BCE0,0000A794C7B283A8,556B4C55A7C45519,BBBA511DEDBE4BD4,89050314E5D246E0,BFF68D99076CD928,463F6AF3497D6143,1D28F7765EDDD509,000022C3A44D6E41,D2B3288913F99990,BFE568477F99F884,2AC90C8FDC8C4694,3ED680E57EA01737,37A8A04181A5CE2A,6F91C2C1D6789700,00019CA325FC9CA0,6EF23D9E4E6367E3,3E3C463169A8640B,D52840654E1F75DA,D39C12A1286CED3F,66304F5916FFE348,420D8054223BCEC0,0000891DA5BF56EE,27341CB39CD3BB74,96318E9BFDD0F94D,7092D288FCCD3D9A,B83892F3AF6C0C87,27DBF18BB7234B60,FD42DFE887D60230,000078D065F963C7,E84B615FB6703AF2,E9A1487ABA8BFBEA,E82B88C77C222F24,BC019BF96F780F09,A70ED89964286B05,007023C916F74067,0001920FFF6327C5,B3A576C1CAC64B68,007EA901C532BAB6,9246F9DF36769585,93D9C5DDC8D511A5,4B843872CB6412E2,887EECFC3EE6ED60,00015CA5D4AC6B53,3A7C301AFE25D819,A77BCEB45B016D98,90FBFFB88B4723EF,B8DEF0AB99652012,1EA463C13BA2124E,229906DFFEBF7011,000191348CD3B8B0,2B3FCF50CFED94B1,69956AF12F8A601D,C2E638C5F73CD7E5,BBC7CEE22D4CC26C,B722A4C41EEA74FE,D45FED19CC643C7F,000233F9181761C3,D7D949125D41CADF,ED747666A30CF71F,EF37CB05D30B12DA,C5DAFFD6681E5E4A,5AA73DF2D191A97C,06E2492A3BF57B5C,0001D392A5D8E5CC,1E7208FB1A108004,4A158F72EA518CD5,6E3A0BD925DDC469,57DF2F8258BEAAAC,6618B5B6B099C81A,36ABA934111403F1,000215765EBAAAC0,1777584763E783AA,5D0D93EF5FB17D5D,04FF28A157F52F31,C52F2A1F13CC2305,765644F242BC5D4B,46BA3099F6DA6B9C,00009769D49729CC,E0B85949F7D999FD,31804BBE30DD8C1E,A648816639521A74,F7FD74F04EA74E0F,C91A45B1727D3917,D506B5A4F9A58AF4,000194FF39690551,8C54BDD59FFB7D4D,B615D9EF09378BB2,34548ED338AFE48C,BC6BFBA837396E60,2A617CCE63A9F780,02EF32324407F648,000232BAB331F562,005F0994E7E55D51,13A774B9433C1B57,8CA2A724F3F2D989,6DC499AFF0D60E43,12801D90C631EECC,5F4B872515C4FCAF,0001637DBE7B6E23,822C45290E73A9A1,27EAE72AF51B424B,71AC2380A7148ED5,C48E1473EC348DAA,F8E1AB291C5351D2,ACD0118D9D3FC9BC,0001BA91D9C991BB,D54CA6F8F700C7EB,B3E3B6C798E64917,2D7581CF639A938B,9A8C153170DD161E,373749C58CD131DE,CC974A399F97A215,000126413F19A2B5,D20C93FC471CDDDD,EA6753E7DB93279A,A8FD19573CBB7AEC,2BF80E8D33FD4AA3,0C32C8DB67AAA1F0,F750C007C6386A98,000133E3879FF276,506BBCAB910F5650,2876EE132A639FB7,406A3BC820EE1894,325F0986DB658A20,68C36C9C89F1D396,215DD51949392E34,0001C9417D1919C7,168C7C08FD0638F5,512815EF0F09ECE3,5FEE261FDF0C4DC8,5026C5F538BE32B1,661AD44646BD010A,1B81A47A9B5BF56C,00017D6E5AEF73C6,2840676EEEA61C84,667A23BE8BD05B17,E69E96C3E1750863,371044929F82D743,F71C905B74FB1A26,FF661F6D58D0CF30,0000ADAB4F930271,11689AF0F1F44A6E,9182F5FCA5F526C8,8B891433ABD380D7,7F0642B49B36366C,90BFF49A9BC3F0BA,C928316D79A5768F,0000B1E02E69101A,355BED08FD7BB9FE,94000E87C8EAEAF7,0603223C142FD519,1589C4E67E08A2B0,60D4C7E8A36E8AB4,5EDDCB0DCBAF8E32,0001E6AA9E72FFF6,B659FE9BB927DC4C,94F02A04EA1224A4,93BE841E411A4305,B87A814CED357D9C,72F1ADB8758F2FD6,34A3EB9D278A7888,00004CDE0DF95E3A,4475D9BB4042E344,FD5EA9272A9375E2,78E8DF894A22A4AA,D93D22995655090E,552FF88B55653A69,972A15474FA4B6AB,00008190DD6DA589,36066EE3D62C212B,FE1EA5D78078EBBA,3B7C86DB8D7F7915,0EEE231ABF631217,DBC64825272BD839,530741801B3C91A9,00013A9C167843E7,C46BB040620BF5EE,9605392771578746,55E0FA1FE15E595E,775217CDF523B7B5,0BE35CAF2EAF3EF6,FE5710BF1A5E30F6,00014D066107DB1D,CB29E93463D819E2,CD7DA128E8798819,6E40403F712A7C4D,123EA947E85908AA,F2701B9895B74A19,1F850660F2BEFCDA,0001C93866F0110F,783FFE8AAC2132BE,082163F31D3C7ED2,EFE04BFE48890763,30D0F991D335C231,0DA0609E4CEB2112,C15C67C354C9CA38,000168555425F115,481C9974C474A802,8F27F96E3D284951,101929E95AB3A412,6BE40F393DFA8339,DC03ED161BAB49ED,605A4810F88A1B1A,0001FEDCC7D924A3,FB6529AE4167A7AC,8F497D89AC1ABFA5,DCCB096C15DFBF1D,B91EECE13086D895,802B732593F319E9,EE6A0CD350598AB1,00019CD0F30AD370,E7C4EBDBABE37FAA,789A39824180D35C,E1A33A69BF2E27B3,34B7BD8C332620A0,181D57FC9EEBFAAA,A1F41DD827E9C5B8,0001BB3CEECBEE97,8EAB3264A91ADFDA,0A08B2B4BAF4FB1F,F633627A97C42887,BDBC20C1B1542ADA,BCB112D2BDB7B810,32B31D3378F1270B,00020837A899DD05,8A5AA931D151DFFC,B8F13C4F2A7ED728,8DB193A1A88BF4C6,B1D4D72E6DF9235E,410266C817B0054A,F91EE8D47B80CE8B,000057882ECFF68D,440072FEF2355474,8D938F776C8FA59D,ED6E689255807F6D,0652CE0B80CD157F,3FFAD39A60408079,FB4DF04F5D5CD028,0001B6348AB1400F,10F944D5347C5280,998C70B87D759DBF,82665F73E54A79B6,AE079975FD435FE3,974D05010F2A0254,4025DCCA0AF3554C,00011051B7F995B2,69A277BE7045C53C,0E65A54254A92A66,2B2D4DC2D8FA051A,71399E41D23B328F,158839DA8D7E3EA6,160208393612030C,00006260B1D3D771,BB5B9CD11C629FD6,3D5B571A3B0D3303,5A58E53962E6DA79,C431D8551FA94437,D6AFDB2E27991B6D,036B331AAC23DAD8,000168CDA517C8F9,CE63368999CE75C5,D6ED29DEC3AD60BA,1721D879D55ED9F2,C7F8EB63FAC6BEFC,E235F27E35130F13,DB12254F1B759A0A,0001F664C54FDA0E,D5C44428A5F16146,200A226F43032DB7,738EB9F65FF66D37,C76837F98BF693EF,F48F0A49BA62701D,50DF3BBC70ACF9C6,000013D4441F9106,9279AA93F3AC7166,C0AB550D08F13B2C,BD8C3A95FF26FB28,D34CD9D9A9529D92,39E14EDEBC5B2400,5525083508B50D26,0000B372191BD318,FDEEB9A21EBEE2F6,90D72D214CE9A969,1CCCC55D7FBB336C,B095772CE0A1E824,06F825BD40036133,99DB04A28E74AE76,0000F1F943E318DD,6CCF0A27DA3D1D3F,296A4B6B3F425614,81593BA180F95DFD,A27CB10D067D93F3,84AE80B6CE1836ED,1AEDA6CB12A531E0,0000CC6CAA6E908F,E702A08630B3A6EA,A4A33CF9442B991A,B227F74AEEF489EB,D4DE729C44A61D15,69DDE402EF17A34C,C5DCAA05F9C63E77,0001CF65E17EC9DF,23463A5BBC203F2E,35DA261E73ED5145,864E997F32ECC1F7,3CD72773AC77471F,B1471C8CBDF1F65B,C9CE72D5DB281200,0000B68C9626FB4F,6DD153831B23B6DA,9205B27A5B86B2B2,59C7EFED84131878,60A6B0B0BE13E104,573AA91138F30A49,8D0102053CAE2681,00010035F7845622,1D5A6B5240EAA614,8E1382178DAD0CE9,8DFB211A42272121,773B80357E863913,CD54007C11571ACD,959B4A7A2FC52B6A,000204C19E5AC9E6,627B4BEF3889BB26,D36FDF72F8CF1CE3,DE7C5E550CF8D086,120E7831A48E59CF,4554195EAC5779D6,1B18C63E1B30DE1D,0000D34495BFEE3D,CF45A904E91BCE09,585D386BE3119EF6,AEE6292C30FA8B7F,698D0A8AA447F6DF,A7452E45B26EF81D,A01CC28ECF20989F,000080F3560E5D33,B284EA1F67C7BAEA,1C5869259894F879,62F43BAC11507FDF,C0A2CDB6096CFFEB,B80C89ADCBF38FE8,CF67432187251709,00002D74ECF00FD7,E084247F403EB4B7,427785CB80D65A92,DCAFFB9401D25C8C,5C835695880B361A,E95FA77E49CB9988,514B97FBBAC3A4C9,0001E1DE0134B959,E5A4C0223A7E2A36,2AED26C535019DC3,2B9118EB35000BB0,2293E9DB0D8777DD,CF5CCD0E590261FE,18A53BD77BF4BBC7,00019F450C42843F,B3CE243598353115,B394420E270A2E92,20862B9521AB6389,9AF51328EFD30D85,726660514664BEFD,FAED4162E3ACBBEF,0001A22272FD322D,A887403A9A330B28,7094D9DC988C2968,B864AC54E54C412A,D9A5D5FDECA7528C,9440F125E3BD588D,D3AFCA2AE06EA133,0001F771A088BD16,0727AF0A01A49F86,3845D0A2AA03E096,C5E263DA139A3EB6,40DC10875144EC34,59C548343E5B1A77,7AC1B156A7056D44,000133342CE12F72,EDF92BF27D93FA26,6997773C4DF2533F,857B2448B54320D2,CBB9FD19F676F8AF,96A1F6BA660716FE,68AF5A4A666F7E64,0000BF26653067F4,08A52DBE2B12B747,5A295AA43D051A67,86592E633A342559,AFD804BC917DC463,76C187E4572B40B9,A94010D95D4FD5C0,0000F52854A82187,83D60C6D587CDCD3,37A5D9FAA80E6F97,AB9512167694998C,4483A204B581A85D,5B173C60FF010D19,F7501C42C7DA0F61,00020B3238E75C8B,F70F4150B5AEFB91,F30CF74595704F72,EC22C752EBF5E923,8ED53C379B4F2EBB,B9601F65EB7B369F,801D0D8AE213065C,00008E7FD4C9EA51,17ED201DC672353A,EB621473A21E84B8,1B056E60200BEA01,232B7705E57540FD,DC556FA4C3392B7B,15FCFC3E11F4E0C8,0001A4B64BA1F38C,3A2D5CD0B2ACBF51,57D9AE5D4C8A2810,7955D7F34397CB8B,11B76E942912BA80,545D436E1B392C87,7A6693BFF3C5532D,0000953B2A1DEFA4,6E64D43A15947672,2F2626F68E0C2613,555AF0E146EFFABE,FD86755FCDE2AFF6,F63FAF17A07138FB,93A35E894175EF40,00014ABDD39EEE4B,3BF383BF1D3AA573,07BB9A79B7AD6314,64178F71EA300451,01EFBDBFB13D75B1,0DE1FB519946244D,F7BC99F68EB8DA74,00017299CDC313A9,AAD33A7CA636763B,83E8C5540E6521DB,F4028F6A3EE124A2,E9A6F675F0FA7FBB,1A6FE37C7338D985,F659FB9F219A4198,0000534E592781D8,89E9C38AB46818B7,2D972C4E68010DF9,D01C291DBC832180,04F52CD52056C6A4,3ED8ED3E7010595B,1CE0F6059CECC7B9,00000DB5022F67FE,55F2502CDCEA5F08,A95BD1A142B1E114,F63E2E8DC03227C6,8FD3653C28AE276C,DD29AFDD6810A2D6,D9855498E83661A0,000212944D76A217,F80C31E07636F014,D120BE05140A198F,A10A649AB8C91994,411C32709A19718C,356AFB6CC613A39A,D80BAF2480FFC662,00006E8F9741C545,ED53A4980BE88FF4,B16F17D0FFE7DB9A,B6A8FDD07AD64664,3BFE70CEBCF72019,992A915414C2830C,DA5D3A3C516BC1D4,000075EA6E383DB6,72A172268BBC366B,03BB5A2B7ED4C1E5,DB6B151194AD2231,6DDBC606A105E9BA,E5163A9ACDC08961,CD69F7BAD9655383,0000A6ED89C28150,505934BF0EE09602,3951C25F2DBF55D3,25E7969F41F9F43F,06F9A98A2141EFF3,135B3E2E311BDCEE,7AB5114D73E13847,0001FBE9B1010B85,A2A598A41EF32990,B158B588842BDFBF,65668480F2E5826B,A585E2C825CAEDFB,AB645FD32C5FBDE1,B1944FEC8AB7DCDD,0000717D08383149,0723556DB4AE3F8D,03A061A967FC00EB,5F84F34A176EA7C8,013E833DA3CC0841,627D4459816CA516,E8EB5769190C3702,000083AA284AE112,03E6267BC774B923,5277030A4A1239D3,3A0030370FCF05F3,C6621947968A0D6B,628FDEB8AB66231A,29BE3F5878401799,00011DF91B775429,AE7FE94786A4C494,BD149244C10C0148,F5F4C3112E7008C0,CB4FECDCDD695806,E02718E4B9092EB6,B14DC9ABBAF84E08,00001221DE60D111,48B2DD458D21C58E,4FC2EF2E46305264,BA6336E2B50DC468,2FB0106F3FA5FB3F,E87BAECD597BD335,BBB0EDFF19A0C876,0001EF2ABA4C7340,5747CBFA67FB0BF6,BDD96F538500B095,3B031FDCC2B4667D,21614CE2B0A27969,0A12325167CE5ADD,ABF08DBED3BBBB2F,00016610954F9E23,A81D391B48F4AED1,5B2EB16E4E73831B,000B75C2465BE239,19D38A17F93D40A4,62FFA5F216D79968,0DC8D25F1A4C4AA3,00021A6C55FA0200,C585C31ACDF75F15,27AEF5C9140170B6,EE19086E5B6D0FC2,459FE7A758AEA172,464C922A87C7AE8C,1AAD2756DE22286A,0002058561DCF1D7,22D33C1827F0FA12,A972F7AB4E5E7DAD,0A18A447BA5560CE,0FA2846360AE9B3C,40162C7D1730E5D8,EC87C83040A13683,0001BD90BC4B5C5C,A9FCDE707AFB153D,9882EC56FBA1ED0C,30B8C93314824E75,B711DC79C48EF1E1,E7E1648B3C0579D8,636976ACF25C3E19,000127043A177E6E,B5D192B3EE9A23E7,422BE6B774D4BC76,BB89520CC35CBC31,CBBE71FFB6BBD82E,5C54E6179AE0FCEC,000FA4BDDCE75F52,0001522E954633C8,33EE7862561A9B8D,A321A457A3DFF2BE,46F2A888940BCF25,2D41739A595AB351,F9294C0BE4A61FF0,19A2392C4E6AC3A0,0002131D1926DFB9,CCFACA3944C3898A,F5B05B42B2DE8F6F,89DEBB951289B7D2,097528DA7388ED69,859690A39F79F237,00A6B6A34A5B07BC,0001DAC320D5BFFD,689B0C1B565DAD87,7064CA2681E3FD44,F9A4DCF17B951102,62B7979DD66B811A,07581E4C4DC1BBB4,3BCEDE81351EB32A,0001F72D2966B8F2,026BF49EAC52E6C1,6349760EBCFACC98,F8BCED60063E8ED9,61038B47E6547121,E149AD2950B097EF,E3FA1422057A7270,00008877EC664C6F,1F1BA7BC87514070,43225480FA8C4D6A,F00EB6ED8E468648,6A228895FA6E76B6,762D270715AC01B6,6376281A3BB490BD,000087D038D8678A,76558A856D4DA426,AC6CC2503E0D7304,40952E707A390EF5,4D0CF6E3A949727A,5A810611C296F26A,CFF52FBE90D9FAF1,0000878D97151DCD,A94076878F5DC53D,37EB828ECE9D23BE,AD3F6CBD35639B4C,0DF32276CF971921,D90787E6025C608A,F7038C9A82996366,000102DE083D9254,2400E370B7729B1B,26ECD7FC92F71C71,841993E12C5644A8,691D65765393CC28,4A0105CEC34EF466,65B4B79219DBC296,0000B1C0757CAB50,A729F9FE21A2833B,8D016C0E66701591,BCAFA717E6FD9AC1,8BC651D1CBBE6CE9,B7B79D5FF0013053,DA621C1283A371F5,0000D0583B04F2FC,0EE5C3CF3A5E454D,828F259FC973886A,7B2C0449948B1211,68160AFF2BDF4661,96BFFD773B5FA1BA,B9234054E335D4C8,000013F93081AA31,52BE8C2BC0286178,C2E1C8B7FFCB7FB9,DBDF28BA5F060721,F22FE315FC712DE3,B3FC2AF310110311,AB1DB071336F4772,00004F2531E9E9E3,DBF25825CE5B87DF,D0ACAA8D88CD14F8,8B44D62533B2EBDB,BB260A46BCA33C16,E6112ADDF9558226,E10024322A8A2948,0001B9C476B5FABD,F56A8955251AEE46,AC55D6C5168541B4,48F477FEDE57ED19,213EA9EDDE4E05C1,1AFAAD1BA38CA514,B8E19AFC454A1B46,00001D84E151F318,A30316B15BBAA8AF,CE50B8C68586AAD2,0B10B661B82C96FB,E4CF1964EF27B9AF,253E26DEF62B06E9,57236BE50E85F81A,0001C661090010E2,6289B56A0F6D2F27,CB2E182072C49989,F34A9846A9884331,6A21E060A0A6FC6E,A372633F46E99F4C,9FC4ED35B80068E3,0001BDA432BF2B7E,4130D893109DB90D,2A02AB6CD2EB6C63,808E691F7059798E,0F6AF801D71600AB,5802F3DD638D2869,9ADCBF1612C542EA,000222FE8BB1ED83,2D5075833158727E,896551ACB849CE79,A681AF617647F788,1723B5EDDBE45009,9B5854E0EB1640D9,D62688D00D7182BA,00019BA6EEC7E1CC,077514AC85F8FE7F,B1809AE785EA2C68,06C6ED5EABC9A5F7,070674BDF0E7404E,D56E93EFDDE8CAC9,2417F53265519D4C,0001114DFBEBCAAE,5AD2B639D609EDD3,CF707AE8328321A0,FD0EB9CDBB3E9B67,03DCC84DB2747F7E,788F99E1AA81E624,89285D9EAD58FAF2,000100EE7BAABF21,9ED5BAD1C958A533,08ECBEFD2F7E8004,02C51E8D9FF1986C,28BE4F7E03E8F96E,4E31D4A1E2E19C4D,E13532B544BFFD85,000063807C8EBF63,004E48DB2718C189,0F22832BC2DBD319,1014B3D4C276F007,AE0C8B5E22B206CC,94D40F9081FD4286,7BC1F98AC603050F,00022D2C55CC94CA,CB6B8F9D520E9D80,E539AB381B667F8A,249202E9866E1249,F527C91DA98D2C27,AC19181EB83403FD,CC88C5918696F4A6,00005001A3D48F32,3BD9746B54431F3C,82A5240D55F89DC4,4A1A73BB64F9B140,20F82C747F685C92,C19FE8486FDED4FE,2203D84CB49CC0CE,0001E880FF73EE6D,C0C1055035534E38,6BF0F508C87BD876,C78F9C503C5EEF6E,D7092C550FBE8E50,750D9410A1E5619C,AACF3B982D1CEABF,00003F8C7931F23A,10C502FB6A788788,6CAD8C424FB80F2A,281AFA60A1BD881C,425E76CB1AF1249A,4C7E2F9FA9F48D1F,5BBBFA8CAA3895DB,0001CFD817D564A4,46F35660279179CA,11EF6F70B27392C0,4F590F0007CC38FC,9EA48BE3C4E4108D,77DABDD786EC26C3,6ECEE7012A0C6E3E,00021D2708C80DE3,0D028A05F7FBCDF3,E23F62E1D51277E7,A1049833C2C6D24F,F11D6272CF2134D0,53BABC624861B4B2,15B1DF06BB15C091,00003A3A945AD4AC,DA12F91A68E8F80A,89BFB00F6CAEBB43,7D6ACCAF46B5503A,F968EE4748497AD9,8BC751C2CBC912FA,398B0B90322A413B,000129537A34AB95,42DEF50ED03E12AC,92F10A9635CF4E9B,87AF82A7E5CFC7D4,605531A601F853C6,D406D851F92E5092,76D6EDB374B4D4D0,0001A83105F8A7E7,3210B451A6540F70,2C4A1D0B5BBE7552,A1C9AF1457B75C3C,ABD09E267401E097,395249825AFDF274,65011599A8ADB361,0000E23CA61F5963,1F06C1B2C8502415,97BFA56270C1F684,41042BE0EE32CECE,AD070A3AF8A7412E,B8E7F8ADD3B7AC00,8FF699112963E227,000225C95920F085,E2DCD17133CAD0A6,2B9DD50EF829E74D,BAB9A951BBD39FD7,7B72851AF45FEE07,6437B201E68D797D,4E088B2032DD6F5B,0000CBDA2083597E,B7FA854786AF5AC0,07A5DC8209E7291C,1169AA6E93471504,6F86598C111C882A,632AB04739CE3699,DE9876A7284C1D84,000084269C032152,5F8B038957660A8C,2845430517B568F7,8ECFC5848B09126D,07FA5CC4B07ADF64,8C729000AD353D9E,5C32F17F662D27AF,00008BE8097F6AD6,AC776325C734F611,2FE2385BBBB71BA0,5CF4E1ED77737755,25FF01B2206AF6B7,C64C29BA5F5BE5CE,5D7325AD16951F5E,0000DBD3D98F45C4,38851C2247DC008E,5C2035037022E1B8,35331A89EBDDDB41,67AA9D69D5DA7510,2A0D1E22A301C79D,202B960831A9338C,0000F15BD902ACFC,01D5F98F9C510139,9699286F37571E35,C3654879975CF966,7F219D3601188814,4629FF37BB221CF3,42478C2A978FE177,000196B840A07260,433ADA22100BD55B,56782481A63FA05E,BD70CCB1EC794FA4,34588790D6958E96,9404208C1DDD0B08,02904DF0945CE569,000098D2D93ADD49,690C2682E502678C,4FF44A13A6B575AA,7BE7076FC43FCABD,2EB25C4B0E627C21,B79B9B03FC8AB4A3,801EB8F992107560,0000795E147F91FF,7C0429B65FDBABA1,D42E2FD3B0E69488,1D5F8DC0BCF43FC7,6BE9B306B508F1C9,6191F1A1C7994AAE,D701D04E58D22380,0002081420012AB1,6464DFFF602399BD,2B4A8E2A574A8566,8A178A50375B0E47,0BBEFA4479784FB5,4630EAAB397F1036,A3BE81440A0FD98B,00018EE771405161,3300990E354CC128,6349E80F1B91B149,B9E1EE6A73FFE650,01FA782F82FDB52E,EF2024DBAFD18437,39847ED4720FA408,0001CE5081E47C6F,A02F0C97DFAE7E47,B637B49189CB0814,C3F74B323BE03840,B31534EB340465AD,3234E3EB38BFDD68,7DC07CCB02369028,0001F414C8FDA45B,BBDF17A1189F892E,E36B701711EBAEE3,9246EB958653A11B,83CDF571CC3ADD4C,2995DA9A115E2745,5E59E02C5DF39A62,00006C681B957EEB,84EF739E89074420,F7756424F99DE4BE,4379E183A608DABB,7DBDEBBE169AEF00,BE1665D536F68CCF,E1CD3876BC9C435D,0001055E38120373,390D402CE5D3DC44,8CFA0A3677B6515F,5B5D988515E05F4C,69F9F742A9C22D90,8E6B864D6F3E299B,5347C49B541CE666,00000ED5A3DA86FB,F152430FBB0B1DBE,E3568C1C356BF46F,1364FC57DF940142,53A0739714D93EDF,0A7E14F8906B19D5,84C8104B46A7DD44,0000DB2434BADA3B,1F3F7FE37E16E784,8E4743BF96285B45,CB2146A4B91A2E18,B3EAB0B7937035DD,96FF028F37DEFFB2,187B521A5CBDB905,0000C7786821C584,7C9E71B5088BD450,E377B6299A84EC23,B283FCD8652C0821,9ED4A93C9A53B760,D3895089CBB76193,248C2AB502D79774,000086E9551D6334,4CDE82E4D578720E,897CEACA236F4406,D47C0EBAEAE4154D,F65FF050DA8B7E0A,078660BFEC5B21A5,98F50C69F901544A,00017B78FF6A399B,0529A98F90FB6B43,636BADD6951C6E5D,E3C69E3E5822D8BC,034CC5C43F5459C7,1CA19A068EAD9C4A,C5F411EA50E85259,0001BA8FD736BDFC,AF809CF54BE3F6A2,4CD22CF0D1A9827D,81FB22D3234D3F38,D54BC4644CBDFFF7,2218D94F30060068,2F308E0193F0DDE3,000042B77E4BB367,94747DE95EBA3DAD,6153BA2FA01D449D,E6CCB30D62922F3C,621940A023A262AF,1E1765A6F7EAAFAE,065084E461A39AA9,0000B6265C7D9074,E64A7E49BC1D0BAB,0FD5F6F13C39DDE4,5768344CBABD07DB,3B24F6E7BBD4A16F,38D39AFDE3B06026,408D4F292B7FCB1F,0001F704CF10ADC7,09F06FCDF010ED47,85623188384B6C75,1519B64C612EEE94,0AF14519CB1ED965,E312A658F621B753,A73F4CDA462F0D37,0002279A1DDA6C13,CA30355A6DE382BF,F5AC1F244DD80125,99FC0B644A578DBC,E0EEBD340362DAED,429284E4C3590DF8,3E80ABD06A82A75C,0000A70950492621,7804B0FE5705FFDD,BB4A15E989766C82,84033A2753BD5E7C,72D7362624013906,D19E7778B3BD49DD,DB56DB1412EBC326,0001ADEEF60D6A58,FBF764916C8EA9AA,EAEFCD394012C09E,AADD625ABEC0F454,7AF0838DABF003CE,9B4868F0E6C4D282,DF0A63D100B3DC43,00016FAE051DD39C,A6BE7DD4152463F6,684815D16113586F,0ACA6C2912CD33E4,4A2EE4DDAC35C32E,238BF66DB232AA57,E78EE0AB10B8AFFD,00014D1A8692A152,62940A3930B9750E,9FAB4A381E83B99B,3B4349F3A96F3CA5,BDF20EABF8279605,69FF11F9497B171F,B754B8BE488D1AE5,0000A126632841F2,ADB287FB8AFC8B02,2A53C3A01EE1F99B,D77E6E5CD5C1606F,942FD2705214D548,58D1A273371B6895,A76A78F45484E58C,0000E531D48FA704,C02E927D40A05C90,7DCE2C82CA8473D9,3DAB6F6FD45F6D51,2E17D123993311B5,027196142BA81E33,61AFB718AB8C2B4D,00018672489CDC62,48E38BB704F6AEE4,4B8782D5C7941576,30DD7C8269D1B8E0,D893FF3CB1482ED9,3EE7C152F98D5687,ABDDD372C3264441,00007914E3317D28,A89E2EAD2F70DA66,8D1E248381491E19,073D99BA53084D9D,E57523BE9DA21504,40E63C14D205DAAA,B1219AF57EAFFDD0,0000874A3661CEBD,5CC2511E038D022C,8FE05A9BB10BA084,E0767D5AA5532E60,6669736EB1EA62FC,A95ED77561157EEB,F4760642D8316F95,00015559C7EEB2F3,F6966A49A93AB734,FC88BD4B3946B069,2CB884198373CC28,77363BAC008101F7,8CFC4E02E0A837A7,580FFAF65F6EC0EC,00012E9A21D5002C,D266E6BE728C9BF4,A542A87E398C9AA8,050F61BE614858C5,5DE4A9F7DA1A6FD7,52A08152EAF7DE3B,BA6AE916FAD47A5D,00001B7BA0310D51,24116B47D1FE6659,4E32F7158FDCA0E5,1CF1C7111CBC8BA5,7D6C1BDAABB647F1,DBBEA064282D81B4,7D05EE18F2EE7D90,000231FE745F73A8,C1A591DDECED3709,BF70B66A6AB2638B,CE7F185ED93BA38F,DBE994643E5AECE9,A492AE884E240DB0,87AD9344EEAD69DF,00010E9DBBB4E870,47F1214544F1FDFC,26C218639D0C745E,361A32B9DB65AF82,D582A03B1CE0BEC7,D4895F190FA8E4AE,7A6EC93531DF50F0,0001A91214205262,2880FCA6BFC771FC,E8A1ED366C5EAF41,26DEC38C89ACC9AE,F433245E87B28253,ED43C4B08B4E1835,C605E763F1368AD7,00015274B28B2E38,768B9867C45D4BC4,4D682CC1A9E19CCE,1F015815A86514D3,9801C170584526D2,AF7C9183EA0ED04B,012FC4454B033E85,000122D555B3EB2A,FFFFFFFFFFFFC5E9,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,A1397C7864FFFFFF,0FC589FA8688D839,F86335AC52097FD0,0001BDA7D338DBD6,BEF0CE72B6E9D1BD,92E0A4F2CA7CCCFF,A0B2035BB47215FC,6D36985E0F7DFC52,6BB989478F1D3A0F,8C5988BFDF5F4F7C,00006E2AAF9B9D9E,15D9717B534B56F9,57ED5C5F28EEED33,0AA224149D1792C1,2B663432FFF290C3,65B645B7893F3761,8C45450423A64BF5,0002072BDFEECFDF,2E9A77227F6B4DC7,26A6145E0CD52870,E8E7255BCCFF6551,C04097B01E64680A,56B98EE30BBE9A40,F3BD5AE69AE90DEB,0001ADE268AB0C0B,15D9717B534B56F9,57ED5C5F28EEED33,0AA224149D1792C1,2B663432FFF290C3,65B645B7893F3761,8C45450423A64BF5,0002072BDFEECFDF,D16588DD8094B238,D959EBA1F32AD78F,1718DAA433009AAE,3D80DECAC49B97F5,250CCD95259A1463,793F04EFE6DC126B,0000863CBE6C6738,FFFFFFFFFFFFC5E9,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,A1397C7864FFFFFF,0FC589FA8688D839,F86335AC52097FD0,0001BDA7D338DBD6,410F318D49162E42,6D1F5B0D35833300,5F4DFCA44B8DEA03,908ADE1CD38203AD,100CD330A23B7494,E0A2D716A265D0DA,0001C5F4777BD5A5,2880FCA6BFC771FC,E8A1ED366C5EAF41,26DEC38C89ACC9AE,F433245E87B28253,ED43C4B08B4E1835,C605E763F1368AD7,00015274B28B2E38,897467983BA2B43B,B297D33E561E6331,E0FEA7EA579AEB2C,65BFB50A8ABAD92D,CC49CAF44749DE58,6BCC9B9136C1E1D0,00011149D163881A,C1A591DDECED3709,BF70B66A6AB2638B,CE7F185ED93BA38F,DBE994643E5AECE9,A492AE884E240DB0,87AD9344EEAD69DF,00010E9DBBB4E870,B80EDEBABB0E0203,D93DE79C62F38BA1,C9E5CD46249A507D,283ED63FC61F4138,A73CFD5F21AFC9F5,F28D96A14FE5CF65,00008B0D12F720E1,000000000000742C,0000000000000000,0000000000000000,B90FF404FC000000,D801A4FB559FACD4,E93254545F77410C,0000ECEEA7BD2EDA,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,C1A591DDECED3709,BF70B66A6AB2638B,CE7F185ED93BA38F,DBE994643E5AECE9,A492AE884E240DB0,87AD9344EEAD69DF,00010E9DBBB4E870,47F1214544F1FDFC,26C218639D0C745E,361A32B9DB65AF82,D582A03B1CE0BEC7,D4895F190FA8E4AE,7A6EC93531DF50F0,0001A91214205262,2880FCA6BFC771FC,E8A1ED366C5EAF41,26DEC38C89ACC9AE,F433245E87B28253,ED43C4B08B4E1835,C605E763F1368AD7,00015274B28B2E38,768B9867C45D4BC4,4D682CC1A9E19CCE,1F015815A86514D3,9801C170584526D2,AF7C9183EA0ED04B,012FC4454B033E85,000122D555B3EB2A,FFFFFFFFFFFFC5E9,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,A1397C7864FFFFFF,0FC589FA8688D839,F86335AC52097FD0,0001BDA7D338DBD6,BEF0CE72B6E9D1BD,92E0A4F2CA7CCCFF,A0B2035BB47215FC,6D36985E0F7DFC52,6BB989478F1D3A0F,8C5988BFDF5F4F7C,00006E2AAF9B9D9E,15D9717B534B56F9,57ED5C5F28EEED33,0AA224149D1792C1,2B663432FFF290C3,65B645B7893F3761,8C45450423A64BF5,0002072BDFEECFDF,2E9A77227F6B4DC7,26A6145E0CD52870,E8E7255BCCFF6551,C04097B01E64680A,56B98EE30BBE9A40,F3BD5AE69AE90DEB,0001ADE268AB0C0B - -ph3_T2 = 37ED7978F7323982,04936C76D51F21F5,16050C18A973EE88,72F7BF23AB9375D3,47C989C9C28BA7B6,DF611D74933C983D,0001BC0CBF2A04F4,08A0EAC4B85F5303,B686A96CB86BBC16,8F36EBD4A443E09C,948222B2B2D156F6,8A66ACFAE2CCD48B,98DEEDA161F27B50,000103F846A96DB5,694F92DFDA192A6A,53DB650F045FBB94,914D7DD5D24B8A7D,332A4681B4537855,77B22ED3C97AA0A8,29F51E43F01EEBF0,00002BE99CC2EA3F,50AADD31483272BD,EF71AFF18F5CD2A7,2718B25973322EE9,4AA70233D7135E34,18E840E9D3D8137D,CC10E80D37099E81,0000611A286EE0D1,A9354A35B269FF9F,6FD04B074DF96AF6,C3106A5031DDC3E7,96D97DB085DE52CB,52E69CD3E0656B33,413B47B6FD5C630A,000099B4D7906FA4,4773AACD7C006827,6E0D9C18E227CEB2,970AA29DDA4FC705,0007DB2A73DC99EB,503DA274C8A57B9C,456519435726C6BD,0001269589CECCC9,00F03E85B4AA764A,D6A2D3F58CFCB874,92DA0409FD01266B,ADCC6564A5D4F6F7,C02F15A74EC243E8,7730B32C01DE2F53,00007E846A2516F7,E133F07C2ED3E1D8,B4326C2931139F04,6A51505413E95C84,736ACF58BEEF524F,538B2008AF8272BD,4BA606901671E978,000177FF06B895C4,FDC3EBCDD657CD6E,A247E9F561464943,3C1009CB51346175,F002A2B6FA005AEF,EDDF64F46D2A177C,83518EC200172743,0000CCB04068DD44,45C5EF8ED846E9A1,C594E2935A404A15,F1FA86D9065998F9,3177F334A98AB972,683137B06187B6C5,763E818699AF9A82,000025CDBC8D6DE3,27AE2A62883696B6,591D09EF41B582E3,AA5B4530E1582194,99CCB2BCAD4E2F47,AF7B2BBC1BFAEF2A,D2D3BCB820C00A6B,000184CF997B843D,D149B9FF09F549CC,E7CFAEAB0F338F18,9EA6958AE87055F5,408E4C22C8263BC8,17E57438EEDDC7DB,D58BB12D4423F92F,0001D7D0C433AD30,C7DCBE1AEC6D7C2D,8F6FB8EDACEED8A3,A92B7BA065B357F1,F6A92D93E4F369B4,D0B517306D4B0BAF,F53ABA5B52BEFB27,0000C56412AA646B,4B826A4831175010,67D08097812EF865,1950DA79789DA00D,ED0B99011BB1215C,5E5B32AC7AE8C701,561D7DE509792047,0001C21010F2BCCF,F057F3BC88DF9B21,8B8EE060C16EE48F,2FDAC5C9B23B3ECB,6AAEE97E18D02869,5EF58C8866A37082,9D42D0D7D776AAF7,00009106AA9E5BF6,7F7F72CA5B66613B,0049FF121C8796E2,446921D8A9193C4D,C46710A67EF0094C,EFEA22E111B76E16,2132DDE3208096C8,000158537695C848,C9B7E0C49271E5E6,9232D78410486561,15CB972066F892E8,A221C57C5BC43FDF,3CD91966B44E4005,4313785071F6AAD4,0000CC4419E3E98C,83EF71190034677F,B73C0DA961FBF58C,2D2FA4D06846EF77,249169E3A3B98786,BC1076683BEB81A4,45D0E9EB5D1324FE,0000627AFD457D2E,A2D211FD38E81A4E,E74DF34D9BDAAD83,FA9276E47ABCF316,E306ACDDA72C24FA,5B68BF41E7F5BF84,322D98FD53020106,00008902F84E1521,8C44089102E680E8,4CE3AD9309B0D800,E2AFBFE63C21F2F6,51D7493A7E0E5F24,5F4EBD5D1CCA229E,6B49826312FF74D8,000091AB97F84071,C363D921AA5766B4,5F78F0E41B0F5359,4A43F68C67C5BCE2,FEAC89F6BF98C204,9D7AC06DBF4FC7B4,26989B3B2D44C774,0001B6C805550CB5,D253F7739CCDB075,8318538FAD5D33A2,DBF3CCADFDE3674E,C6773568F794E12D,D6A71F2C69C17A5B,53FD7701967BFE2A,00005CB62ADF7B66,F1876400E4AEBCEC,DB7D4068365A6399,8D2B3C07E3AA1D93,B763B70480DB937E,6B209F9E89C1C38E,99F233803462481C,0001703585A8F941,53651286AF21B7BD,B5DC8DE712CB9D2B,8C8653F83462375E,A13993C7C4E915F2,964055D5E5966731,357C020389033773,00000CC534E50DED,FF72F3C9C8A650F0,CE49F4C2868EF761,458103FE62D5D7EC,5EDF0259B91D5E5F,1D08EB6816BD60E5,A946F4C5D79C5C1B,0000223E0CC250BC,2B51A049820E158D,B0AE40314ADDBCED,7ADA8CE98928AE66,54CB91E1C6E32237,C5BA6BBE489D3E92,C61076FBB6204480,00016725A031428C,C9B7E0C49271E5E6,9232D78410486561,15CB972066F892E8,A221C57C5BC43FDF,3CD91966B44E4005,4313785071F6AAD4,0000CC4419E3E98C,83EF71190034677F,B73C0DA961FBF58C,2D2FA4D06846EF77,249169E3A3B98786,BC1076683BEB81A4,45D0E9EB5D1324FE,0000627AFD457D2E,C03CD433DBFD1940,AD1049F408EAFDC6,9413F0B3B5F855D2,B466E1E85E7E45E1,D353B33DE6AAFDBF,AF62EC1EE44B00A9,0000EE42010787DB,EF422805A8ECF8B2,EFC179F15231A992,0BC9F1827039347A,60D8FBD734560515,60E378BBF16EA78D,96AF9D3C96D4CDAF,0000C16C643E295B,19CC0BB9E81D0F2D,C74613BF54DB4817,372D926DB39C3CDF,2CE188DAAE451706,2E9D1F86190D2D03,07AF6FEBA83E7E98,0001239E39C886C9,18016CB681973207,FF2EEE394C8FA492,7015BF66C6DA1CB8,682A804E6C62CDBA,9ADB8BA7AC3527D2,5CD6BD2C7F57E672,0001F7FCBBEAF368,67CBA14AA525913E,2A26621D55F2EC8B,3B31A5CE62B44712,213B2FEF1D0CFF9D,9E30F07CC0D2D53A,883F84866709C5ED,00018DAEC58600EB,90378695AB6DC70F,F28CF06493FEF316,FBC1B50FE10764EE,F0FD9C62941B1F41,81FE1F9C80FBC203,C276A212D7C0E28A,0000A894531B6E73,82035719D951C650,5D73E4E48C7F1CF5,F661D60807952F30,3089A85460242F0C,2880A4DB87185002,999A96237AFA40D3,000147336C9CC194,348C81B999814533,182CB5F120A91139,918C4131CA70B7FF,9078A6C623B9E8BE,AFB29263D67669ED,53C8A59C45318A16,000189C6A62F5FE2,C9615E77B9A331CD,796546F9415693B6,49E2874740F92975,EEF96C473880186C,6BED96B40F3F4146,6F0183BCE2AC1B17,00022050F405E829,65707E635ECB4E9D,8B6CB4F957CB894B,A548A3A39C9F6A88,4FBE409960FB15CB,2122ACF1EF2316A0,F5A6FB61350D3FD4,000133795A80A6D8,ECFBFB77B533B175,AEAB50CDE3FFEFFD,4409546B8780817E,CC08202B547B4343,8A8DE838FFAFB80F,D22E90C09A6FE7D9,0000A9F2F5FDCF0D,718C8E815F5758F7,A6E06FA6EAD8C201,CD15CB0EC91BE0C4,42ACCD25F3243E86,35E63846562FDC96,88D2A98AD796AD5C,0002257C6CF6607A,E19E872603CA1A1C,268DB952AC008521,488E3BC0BC2AAD3E,CFEAFB68E859EEA3,C83D2F8A26E6C25C,14AE9DBA32791553,000120681B9F27EE,ED858188F54282DB,2A27EE3D8B657406,8D200617C2EA3B9F,4F0D0C886B0F473A,F0522717AFEE00B3,A45453EC4979385F,0001206830AD6B2C,4CB72711CA850294,C211F90452DE238A,80E6D14309CB28FA,A30C6A97C9FF1E8A,2430A4CF8D66F69C,80AFE7DB642FD042,000006868939979C,459FD7E2EF627373,BCE705FA699DA4ED,361BA49E03059B10,BA3AE86694E7AFC9,AECCF50BB95E2BD4,BD9B1FD6D6AFC93C,000144E505989609,AA02D69A7AA9DD27,3BE7ED4F6FAC748C,0DF08D3FFF1CE042,0594A45EC41BBF34,AF092A2E24662426,032907C83259EF8A,0001E654FD0601CE,0D8AB9B4F1464637,914D439A7D3AD772,1A01657B9A7C2B06,C7AF199D6DC47DF1,B6948222D9D57B5E,3CFAE56B4E6A1BBB,0001A6986F3D68E8,543D675586FE1C40,277125FD4BDE4D4C,BD3E505763231FF3,EBFA8EEA4AB8BB50,86ACD986B784D3A6,9C195DF7E8B7DF71,0001C5B107CEE734,BEAFA7EA26F62970,A161A3CF8CA00C57,42638BCEF0EEE383,F43A6E5ECBC63EB6,BF1E53996CD8FA66,218EF3C352D484F9,0001E849136E5513,0E8C5A33992BDE5A,1E43F6F8ADC4687B,CEB1842C9087709B,0EDB68CD7E5AD47E,6EE1502AB55169CE,A8AB5BF4CF196E9F,0000B16B329F570B,BBD392B020E491FD,94E0A3821045F058,4507C63B48F72909,7F06CB6D6E81C97D,8F1BC7547C099C62,A9EE5E02C3A26F1B,00017005DFFDF107,8DC92873F960C071,12249643C8697FC7,F0D001E41AA019CA,638299852191FFC8,EE8C83B34DEBD97C,9F1E8DC7ECD7CBDB,00021B0A9F9C368F,B0A5C2278BD9701F,54C3A8880A40BF84,5299B8BA210AF7C1,7D2CD9CA19C3E3E4,6C3DABCDFF981D6B,9D2C2A08F5928065,0001095A87F8DC52,CF6D9E37ACA7FC41,E3BB6F4674DA80C7,DAAC5E9A0A44C2ED,7D5307AB1434786E,622342575645CD0F,0E28C64BD43BFED4,0000B39968FC5CFB,938BBBEF5B9D2EDC,364AD80C20AFC700,EE2A7B39C1AC7E9A,66A182254E550751,D29EA3C001982C8B,BB51E4F503A3C906,0001958524411AFC,D750AF1718FF1697,ABAEF7EC842D0D3A,EF02AFF7EFB7CD4B,C5121B848AD9B8E5,D9363292FDF0BD28,BE7349B7CBCCC18C,0000E37C0A921C25,F81B601F370AB515,9718CB1D9BC77332,820B69809E9552AF,071469CE03D6C82D,82ED4CA05BB20F09,FA0EE0B3176D3AAE,0000F00F29F220C9,99718695CF56D1F3,0FA0CF4A65E2853B,6BFC00CE66341DB5,9A1FD3D8BDE2168E,A66312AB6D1D1429,C4F6C545D87F3AB7,0000684ED280FF51,BB4C6122596AAFB4,09975728556A3FC4,F737FEBEFB08A1B9,E2179CF8F34CA308,1F733D8647D99B33,8F161334971B8D14,0000302DCAACE7F5,3CE82C92FCA36EED,AD86BC910427CBB2,3ED9D973F0A74442,1D5FA3CB5B76A6A8,72A273A14D634320,6323DA781445BA42,000093D662E789C5,798CCEF93B4CDEE2,7F6C2D4D96E92EFC,6491DF60E516CE2A,0E8401A029A644F0,3014E918D0C95BBE,0BE324BC5C8BDD1B,0001534511694B9E,1EE45FDBA7F4D0A5,A1CD76FD4DB4EB0A,7FFB78522A923AE5,ACE69A5D8CD388AE,46A71C0069CD7FCB,66688F6CCD8075F6,00010840992DC3A1,825FAB3D3068B880,2937434C524CE60B,FCDD3FACC3D70A74,A1B284E716631EB9,62FC10ED7CDFF026,E8C37CD20E024194,0002127C297F67AF,E4E770D3A1998E55,0E50F7A43CB8F3B7,CC0EE4F49DEE0608,0696621C1C702829,EAAF7372E46AD1B1,6A697C9793AE126C,0000DCD786C808DD,62BC51904C27EC96,98659E35ED3CA154,CBEE68DBA5AEF1A9,84A6828DBE8486AD,B62C8CEBDA58823E,C0505E7F1EF6C439,00003E7290CF7FA3,E7FA00100D00929E,E3DB9C87A19D44DF,39D3C0882DB52D98,8C44470CD6E81EA3,A7FC95CCEA497684,47DE411F14569424,0001752EA982B5B6,7DAD95284EE41937,1E0416B96E7A5F8A,8C469B3A0B572529,4633E7F0D55E131D,88BC355428CBA688,8C158EF6F0E3684B,0000DBC4AA85FA49,4FCD82AF68488203,434ADECC0CBC9140,AB4F65432D70A4C5,32554FFD3D12AA5B,2B1E44AE79A19FFA,0E890137A684FF01,00004D89B9D12502,49F246888EE6329E,F17596FDC6C14127,ABFC9B519BE18D18,C18702604BF0F5BA,9E139A8BAD27F11E,315E9799DD6EEF31,00007ED9C9ED346E,259120C9EABD2A04,296350D8CC35E881,86F68443CA640C6F,A973BF6907A3D5D2,14037612F335A0E5,D8D2268298E642DF,0000D8266EEAE590,5249141997855FB9,09AC7EE090E433A1,ED35F7C7E9A6E973,436D4670CC885A0C,EAE89063A007DE81,60485A975654EE3E,00008A62063C2F5C,4CD74E53DAA52AD0,8B6F556B11A8B90E,20A9BC9880C1D9CF,10E64C7CFF911437,456570EF33273CF4,3BE32B31D3247ADA,0000642A69906731,D118CA3CAFCA633D,67F678D57401D949,014405A601FFA334,CFDB5AF2D0CD9DA6,13C98FE237000D4F,0979D8CAEA95F896,0001AFFA915B9008,B12A326ED9BBC676,D7DE5B0BD4522E47,A9E6D8842B2A1664,BEB0497CD50C458C,C5C316A98392C67B,4D9E4B5EF3567E40,0001CB755BFD5674,B8C5831C6AA49F69,0FEB8A0214FCC1E5,15D197F836B53533,24D813E652BB408A,6F2DECE9FCEAB2E2,6E516A4774407181,000221F1B18E2342,20D3CA8D414DAB5E,F0258C41FC6BBB86,43433C374F87A54E,4774088F8B175EE5,213EA6CCF17658C1,0227216743DCDE7C,000155CE7D303C44,FD853D5D19CF4854,392508A64BDD3A54,894B13B458027F1D,8CA48D136C13B85B,5731520BD0C4AA8A,52CAA13C82DBE553,000068EB8E1B6529,991D3CB9450ED822,E6D8228341C9800A,88C152836E6B96F2,6143BE170CF079AA,ADE44C525EC2BE9A,A52C016B7528AE45,00017913156216B2,F038877734157001,412D0AACCAFB28E4,7FF74C814593CC91,043A9B81BB791647,0F22A302086992DE,7465164CC9E82926,0000295E9B47747B,8ADDEE86131054D7,E97A6178E6D79720,8EA7ABCFD67A1D62,2D22A45E719681C0,72AFBB8AE11C6C0A,3CA2C1D95465587A,0001E3C708CF09EF,A2A1EAEF86053BA1,FD69E28F3A2E9CA8,FD6031FC1739E60C,BEDF49AE806DE468,506A2982151B920C,5BC815D2DD99C568,00002DB77C0FCB84,B7F2C2639C5F4553,8DBFE37A13E726FD,1FB2C22BD0730383,0670BA25D3F2D0FE,28090FBB3D0F1339,E601E04E4AC10937,0000119FDA27FD06,9ACECE4446A62F62,B55647F833B6BE4E,80303FB87C1BD961,7D6C1DC4BE8E38CB,D3C9366A3A099CD6,9F1E2D6904A29529,0001EA55744F4F2D,E43EC119B8E89DFB,4DEB15DD1B9A0AB2,64829D8F572AD605,940936CCC608F92C,51F47E94B0861D24,492F7EBEAD3CCE12,0001FC3876F37613,25C4A6F996DC1323,680A8A80AB9132FE,8E3C791DEB467E64,428699677462FC06,2D843757B703FADA,51B28D04B3643CFD,0001850339234F22,0D0D39F0D27C3F75,36A57108AA19DB81,3412A086F8A66907,04B78E3B9B09561F,E1B0121D7A7A8816,D25323C860715C66,0000ADE8C97D8AD2,EA616353338D3792,4C6B66E7D1963131,1FE234D20B168EA2,E8A1C169B89571D3,3BD4A80643A3461D,04B7BBEB9AD84B95,00018EE838EC0B41,EDAF05CADB8E0291,DAF47A15CC218ABA,61B556680B7725E3,53DCBE74C8924F35,7DD58616504C7A57,9B312880430480A9,0001CEA9F68D9AEE,5A319CB0E0D6BAAE,B6BFD0B499A604DD,EEADB7BD07D44F62,E9A6CA161ADFFBA5,674C902305B8715C,F04F383D689837E2,00016A41ABC094DA,17A3112EF9C267C8,5BEF4AEC399A35F2,D9D791D66F35CD4B,4BFE5DA02ADD348B,C235D0C6A8BAB24B,FF93B782B6B7B3FA,000156430C23B60D,B6C4FCDE05363EFB,332D1402A997931B,580795E607F457DB,37483F148577486A,9EBCBF2A142B5717,1FB805332A8E4DA7,0001DAAE25FF7308,DAC0756CB9A6388B,6C5E9371737E7ABB,10DBE7EACA81D420,6FAD339D714BADD8,1A0A29ACBE5C1BBC,85ED2D2523A62DD2,0000FC60934611FA,4E584C6FB9977354,17840354F7B6E37C,7347CA89776DFAA5,748CDD00CA7F6D4A,68B823C3EED214D7,E0D165BBAB35CB78,00022F14B5CE6ACD,02FC304A5D47D947,E76F3E170042CB7B,EA1B19DE16729BB5,1C99DE37BD74AF94,7EA911A2BF31D874,4523575ACA0A3004,0000A1201EA47044,1D59FFFA2F6B49EF,9BC1933D4685E736,CBF48D315AF92B99,BD571321EFC03BB3,35CDBE486117B689,BBE90B54E3A84466,0000E5A421AD97F7,D1D273C0403DE823,0781B73D97BB67E1,51F4D81C1E0AC129,09F339FE1A254FC7,B2996EE412AC0B92,1760A8A6E2FE0990,0000FBFC00C9B60D,4C91E4B4B33A0C23,FC39A597CC1E04FD,A7F7658285DB1A43,2A2B5772E3B3162D,1E4A550641B5E3FE,33C3B321B9B99780,00017D6DE7225983,DC163718EC88FCAE,2E96A8F49BAC4E25,B5E2C4E0904984DB,E63C7AE8E9F26E3C,0E0D827A74367AE7,6152BA01809BB89C,00002353FC221195,59258A37906E6CD3,C9859BE3ECFA239B,B78EF80A9130F0C4,A9D17BB4E15803E8,EF5086C5A5D95CF9,AB935CD3A0AA7B02,0000F1228EC686C0,E13199B41023BBA7,244F8DAEF041E1C7,6081826C3CFBB069,1526E89CC84081F0,BBA7ED68CE80D381,F08F214B88FD8660,00021B3AC0A52712,86ADD8B3DF54BC12,01023CD6D378A7A9,AE3E15AA4ABCA9B9,02E31C7BDA0AC2F2,CDBA7286B5DDFFC1,E319332FBAA5F892,0000A31657948561,ECA480ACB43BCC1E,0DD01AD6A9ED2785,92828D3EEABD6021,11DB3994B9A081A5,3984BA2D4AC653DF,44335D2844147169,00009B7D558EC564,1F838D429EA62CC4,4A0D87DEEFC95AE6,4F8B5D39F65C7140,6AF51F2CF4EB68FB,4798FE25308722C4,3677CEA9F214ADF7,00004A559E293A03,4DC6440C31E0EB3F,6F1D8AAF2E182C79,81437FA797B758FB,A9456EB48FB8CF37,67B6723F33797090,B2396AC924BE050C,00012719F4D97819,BCE78B004E1D07E1,D2D80D01C9A1498D,5F807D8666AD6D1C,2AC1BCCF44AC8189,2944B20F5D4431FA,267DC20F4E492761,000207E93D2C8EBC,1E90562B19A2C767,90916D779EC73093,0BDC75EFA2077D0A,DBB814AC43FA58B1,25C788853A25949F,5696D094A05F13B6,000023EE47B42381,2896837F061E5C95,18E00DFE453167BA,2187CAEB2813E16E,2CD5DD9E3855305F,8B53B210903EC228,40FCC08C8E186CDB,000196AB10027441,87F7A48338880A4D,A6E0A086C9FC4CB2,9CDC64D79929978B,D398C716D9141C5A,B557A0B10A759E83,1A4F2A7E27C60654,0001189951A3D03F,06FF1AF0B14CECD2,96B24B7A359B045F,3154A9746823F840,C650E752FBD93CA3,48CCEE4BC740509D,96D35EEE671378AF,0000BE5151481739,55E7DF5904F12E85,4819B3ABE47DA6F8,C8E940549D5B8CF5,DC83DDCCE72D9B52,B49A25AD17733066,5FBF9F9E3CC8A1F8,0001A9D39A30116F,84D90559C8E97FC8,938FA91412A2D817,E2315CF1C1E69A96,69DFC18EEBB3511D,A409D353FD784C84,819AE43CB2377373,0001DF9845A995E4,77CAF3A5ADA78ABA,4ED3731309C98E18,519CAAE8C44B7C48,A28E4F695DB08443,E64CF7E352D52720,68F6F5B8FEC87012,0000BBCC9954AEE1,A28E46C8E635C59B,F595CDB168EBD107,EFFFADE34390265D,06147D01D3C7D713,0525D14CF19CDA61,0B970104DEAFF2D3,0001189373D47DC2,E5233DD25B708E9D,80A911745369550E,EC53FF0957DB8998,9813FE51521809FC,C94D771125922F97,18664277BA33253F,00012C108CE12B5E,082426A0F7B4F73B,F48A31998E6AFBA2,15826D87451363BB,BCFADDEE30F5A468,1EB7B184AF185A90,D9863A0A8633C904,000164CE6E66DAB1,B606B23D1A86DB65,8D5539CDBC6A4B05,5725B9F80B025881,374D5B24F660E747,75868CD69C75EE8B,E7D8DE35FA168C4E,0001AC4AA828122B,48CE050DF7D161B5,D5E1F6ACBA619A11,244E813E118FA869,28003E5D99A3A441,3B68B7D319069EA1,983688F4C9C84166,000168125925D30E,7B57AD1A506974CD,AFC1002B311AC2DF,894EDF5CDA376F59,369E940AF89751E6,C8708A28E151F660,5F334D17A492600F,00015C130861CE70,FA66D8170B4AFECC,7827DAB5CF2234A2,11D4F694D1EF9DB9,F71F20D863B51CA1,2C7CA9F869E611BF,80EBED7536F5849A,0000F18BED30BA4F,FD3570F752C58B61,2FFD48C8F5697EC8,B6092D8F6E361607,85E6EB90A01000E3,C15D91CFBD1C38C1,18FA36D7C20D982A,0002213827DB2A88,F172D86A90CF7483,19C3F9B4B519D6F4,256D2919381A3C51,190ACA76398932C0,ABB7B0CFB4E028DE,F9CB3CFEE4A68C68,000149AFAB09EEE6,B13947C39CF64B19,28674DEF15D919BA,5EDEAA1540F3E427,0D6F262E411B3D89,BA7A2674093131FE,2BDE12EB794F83DB,0000118AD6EA8806,3CEF3CD3D46DD518,1EAE2B7C77E22AB4,0D82F3F0CE40D71E,19FF46EE106BB60A,3097D41585C6E4AE,39E6556A40136136,0001D1774685C42D,E086823136A031E9,0D783A655B733EC4,BAEB57E3C170EF84,6B2CDC2AC6206BE0,6AB0E960A6B93666,D3502209D7178264,0001B6D013167423,68D70D3C40F14E3C,F04F3808178834C4,40FDC0A8FBCE7B72,DF290F225A8B08EC,3BC16133555B89B7,8238E929398B3FF8,0002303277DEEE13,50DDE40910E91AB1,B972596299C4DCE7,845055C681AF6CF8,8611DBA44EC8B872,DF7574438F28486F,08CAF377EE674F0E,0001D67D2F5696CB,F0F1BFEFEBB366B8,7C848CED435462DD,3445A7AACB766136,3A3BC19FB15CD98B,4BC8BBD006CE136D,31A3F26468335B45,00006309A17B6104,5C89902264D1CFF9,0C98B69C47844418,C0635FD0E1A62316,95A8D4D2B332F943,C81D1D5859CD2276,D93A88F8F0690296,0000449124833F5E,3397CCC0C112AABD,8C6F06C424A734EE,A622809EC0EDF21E,552E40F79EC3F856,9FA096D2631D94B2,B272AF9DCB59F80F,00017855976ACFA3,17518BD3E832C7BF,0DDEDC4D02E12E80,9DCADB7A426937D1,F253E025696B4814,92EC17D7A3DD5B09,13ED83B9E9626ED7,000108B9A7DB9D26,F230498CB6B37C52,F021883338542C28,D505B8FA2465D658,55A3B430E9F63460,CDD9EFCD02696B85,FFA9D550AB95EDC7,0001A22336B3E5AB,89C1297040D3A474,FF71C4A765B4B4E7,CE64AA377C9CD1BF,639DBE419BE2C45F,4F98329F7FCA5FC8,0665157168B2E4BC,000210B727EBAA37,04E2EA413C071AC7,C9D6FC0B84D652CB,E7DF5DD3B5C472A5,17D11EB4637491BA,A95AA02F7E9B40EA,BCC421D0B684C06B,00012A14E8F4040A,7195B72F9842BD37,BDC20346794656AE,298F37A257BB710E,DA77FC1ED5E8F5B1,473DFD2A02F30D51,4F0FD858BF4314F0,000227BF05EDA151,4FE8034BF666BFB6,477CA71ECD43AA8D,0445365BD406BB21,D8C4340E141B98D0,A100F9440D0DCE6F,BB69D18488A3E368,0000A7B58D26E2F3,610DC00581A673FF,7A2252C9C9C59EC1,68F4CAB28B0BDEA0,F09470EB9591CBFF,D613524F623913A1,392EAE8EE930C83A,0002301ED4962761,DAC1D5074C7FAC11,1201094EA3567DBA,6035395B9EF45314,448EC3463D66D1BE,F87A2045402F682B,F1DA3881061A01A6,000103C46E7BA7D4,C9798D6D92B88123,CDB3C4F571B7E949,5EA5404BEF683A2D,5A338AA2486A5669,BF743E15D71FE0EC,8E7EAD1288038D8B,0000BD2EEAC46788,39DF6D7E3A0E0B8C,5947E0F3299D2632,F65559E25161373C,501AC62BA145B962,9319B67104C4D29B,D14905102FBAD5BE,00011AA0D9BA1338,AD59EF514C47481D,DD69DDA57766D86B,CCB58E187125009F,D7B83B91177A78BA,49CC41078F69A8D6,372296033AB2BEBA,00015FFD6E4908A9,504C685562C71EEB,B7C8DDDE787D9355,9648516EE93400A1,EEE381D87A506BFB,154E8C3AB463D119,4523664CA4434C96,00011A1B89565C87,FFB1C7745471413D,82814E0EA40A1DB2,6894EA66A68AA1AF,8208154BB53BC1FA,8F04BB227BBB6A2D,6A4F34802D71546B,0000CB6543ACEC72,3257407C69EAE7B8,CC142AF9C4F9ED2E,795AF9CF87455853,50B2ECCE460CC358,0B4A3A4DD5B7116B,2A90E327E0A13F6D,0000105559901176,B5527838A4F3EAE0,B4D4C0FDDD233F15,1B5068BCDAB1D01B,11A3D020505B0A9E,D0FD6BC0F3DA73F7,893842BD0D53CC0A,00017372A167015D,32956E857798056C,EA7FBDEAD42FC220,A18484F03AC52AD2,5A9453A6B267485B,772F0B236E715961,14F63E436B673F65,0000F5886CB43DD8,F398D8A08D3DF24C,A6FE4679BA91D7A3,21A5F32195AD76BF,872F0FDC511AFE4A,60589F4AC318B6C3,9DDDE7382C5A0BB8,0001C5C82728598B,F97D97075C792DE1,64EC771D78859FA0,9F5DD6CADED67A66,68A9B844B86E01E0,2F5B863278E6B2C2,028458C2E31D8DE4,0001958DAAC84549,993B0EBEFB56A8C4,C08562C18402597C,591E067D5C6FB9DD,A28E4AE7A5E491F8,41F2D1732A9F9D8E,89567F6E064E8F56,000160EDDB96DB62,95F031DEAB939ED3,68BDBB684EA98320,827CB6B6BF2C9C58,B7FC54DEBC89C71D,B51E046855C44A5B,938ECE19F1A2DAC6,0000BC7E6DFAF66A,1CE1942FC86F43B3,412A183762AA4F78,6A955CA6AAD6A2BF,09BB60F27242351E,1EC587FC4172573D,DABA4191BB36FB86,0000EEE0F3561D87,D36089A15329244E,78E65A6EB6A05CBA,452AE8C5BA97C3E6,2283E9011B9B2970,F7224332DC0F6EA9,021546220F3BE9B7,0001ECAA9A5EDBFA,F681BE1811B16745,2A43C9620637EC81,6DBD82344400CDD0,2F3CF0C5467947F5,02B1D36C44388929,674B88CA2729EB78,00004700327DA938,3AD966E3A12BE29F,989FBF1CD71B5E11,8D53C2978E8F58E2,F8D08B8A2CFE7A39,F5EE8016059AA8FD,CF0884447BA4A36A,000000CDE1636EAD,6DAF1543650FE939,56E3F5B5A2FB1756,7EDE9FEAE3701221,11E76CD322EA40B5,A1654212EA5451B3,626666D3D8DE14C1,000096CAAF3C17D8,615E38D241FD05FC,3C0062D34EB7DE11,7D2F5F0FB354BBAE,85E2C91EC41BCD3F,9952EC9522F453E0,3A72483C32D12963,0000973ECBC9FA6F,802532DCA3936A71,D211F94280C82BF1,4A6054A68499D109,4C262CC601B2A25F,D0B64B666BC4074C,FB3A08A247BE4181,0000CE88AD9EE8E3,181614747D9CFFCB,DCFAE009C245C63D,EFC20498067923ED,DB6272138A8635AE,91D58A03136BB088,6662D0317389DBA6,0001F397816FA65C,AC5DB3F8A9DDEC46,9244396D61E5957A,E0EE324364425AF8,BE71B718B4692F0B,DB0BCDCB37795CE9,1FF9B333707DA3FC,00000A507737ED80,BC2F4DEF28503752,0DBCB89B2D7CF897,66451D05753258FA,7D285958C7A09C70,5617C75F685D49D3,C812CF22C0564F82,0001C735413CB2EB,07213F4CF3366024,56F5CA85C3760117,ADCF03DE500D8847,D7636A9936771DDB,14FB141137680E4D,A631E6877B7995B9,0001584B36DAD310,6E360A690D4984F4,B7C8A1ABC388A32E,D14CF9D7D6B4F746,08E8EB352352522C,10A30C45AD941E8B,E682E674E598F5B4,00003F75BF43525D,EC2DE2829A236D76,A89B5061BC31D514,4D30FEB3F4B046D8,EFC79370701D6D99,F6B38D4F70A430EF,88A3C8920DD3DD17,0001AACB7AD6D963,108FC2682F8B1309,F0EBFA41C1CF1296,D47CB36AD7B53903,D5DE9B9AED7EF00B,B9BA0155897C6D43,1A56AE3261D669AC,00011DB629347049,A8E51920064BD18B,70BD02EEB72DA9C2,E8D0C69C7185DB72,94E9BC90A510CA4C,8572FF106CE4BD0D,FCA6CCF817FD6FAF,000121A45BBAEB9A,A8B2A7B857406FB8,798537AAFEC12B82,D287608502456F71,900D19280B58AD1D,71A96014DED1721D,825A27B891E2257D,00013D5850A6D764,51C31D1011EC45E7,80B0C5BC24A496EB,4FC2F5CB9209CC4F,9F652E1CEAC10E1B,FA2BEAF4BD1B3FA9,E59523A40E4B1336,0001103FFF370977,12C3EBB49B0C017B,E3D2D2BC9C341724,A192381B97F6E38E,6B3069CBAC53BAE4,61617F4893060627,60169606ADA9B57D,0000751B54C7934C,49FD8CDB826492BB,E7FEE9E8A1A31984,5FA80EA5ADCA30F0,6BB0607E3B5445D8,59460FBA1C339609,DBB9FDAA8D1886F2,0002253D19B47F6F,9C2D01F96C71C0EE,986698E464F17F4B,A2377AE4588DFA3F,CA1A99EAA06D4452,C094406AF2F7D088,00F852B42D12C2E0,0000455ABFC4A688,0143CF32B1679030,2CB23353ABF72C7D,144B52446C03208B,FCDD9E26F3B141AA,4240EE04E607829B,C44816C6FBFA480B,0000EE5BF73ED2E0,D15BF1F8A80F45C3,F12AE28C50376FDB,7E894671BE19BAB2,F25C688850C77B0C,F30CD998FC02FBC5,B87A664E869402B2,0001101302E33111,6DFEE4BF141AE97B,9967B49E300983D9,00B37BEEA11F8423,8C0E8E3F926575AF,6BCAC3667DD778CA,ECF5614D26457C14,000146ADCCF684FF,EC0FBB225E07EC04,851A1629E73C0362,A2C66664392400D5,3B91A5DB0F97A0A0,7FBA66950A40A8F7,A577D7B81D063754,00003558282BCE71,8CC232D0029FAE41,1FF0EE8967F2B586,89A2096A166B9876,E51E7BC5430ADD25,14E96D994B63501B,5A13BAB060EB7E1D,0001526C87977071,18CDCDB0CA56A7F3,19B29E0E63247456,1072F30249E8642D,B27BDBDD8458B19F,E2BB359016E681CD,F7349DC8464DA410,000122530AF1B8C2,2F60EA7D67C95718,D080934779E9A09A,BD338F2A923A08AB,D399D9478208F96D,1EDFA1097646140E,E694939290EFC5C9,000017637E708D9E,0EF2985109439F01,8756891DDD1A9E47,DDAC94A6A48480D6,746D16635DE2DAC2,554E6FDF021EDAD5,12146F6669FB4B19,00011D04B047B2EF,3EC9A3A04B5831E8,5B8C8D3FA2F93BE0,87F3854794B5CC29,089F3D8C4EB27C93,7DF551EBA1E4B3EE,8315000E064B8DC0,0001BE4DD7697E11,9E23AE7CE75625FB,C447976868368186,2AC959C1A148FE92,5715F79D1A34B88D,EFCA811FBEB30134,40EC78621AA16B9F,0002172A0B3BF1DE,D4DB80B99E71F195,1FD6C73CEC487A44,CB8EC53D4D98D038,8F9599E7AF896C9D,9DE70E37D7D3404F,25918F1C61F2E8A3,00002EE4FA576F89,6C3404ACA8916BED,0B3C0CC23AD3DD17,B147775302AD42D7,0C830CAD9EE1DE07,F74B80B2AD672AB7,F21C66A894C741D2,000169F44056AACE,8CBE4F8BB6B6B222,14D73147DD48A483,A5EE9A0C38C2D38A,428E4666C3E4962A,36E538FFBE9BCFA5,35C9E7FDF4767AF8,0001751BC481BD5F,984BB981CFA7F6CF,0CE1EF877871BBFE,2470A7704EFD5C56,DBDEEC9992820075,AA6794C980132A27,4316456A0E35B1E6,0001D73A70681DDA,9B3F61FEE0ABFB03,BF70F2BC3C323D4C,C1528598CE32C6BD,7DEF265161A307DA,F2886238D52CEC15,E1E9BB4BDD68A269,0000092588332E5D,5CC77FA16AEF2681,B67178E6C7513C27,225B2E4C08339FDB,C29432766F501C05,9BF2D9DEC3BF2D80,891CCB6F95243C0F,0001A0D680E7376B,782AA001ED5C273A,94534ADDEE1AD0BC,A932622F63DFD642,DD36A4287C543BCD,2E58D3A64FE37AB2,D4ADE5D69AE2A1A3,00014D849B2B0E0F,7941F92334062F5E,EE919F3BD8899FC0,07359C3F6E7CD2AF,6F2DC6966C225853,B032677D6956D66D,253BF07A196CCC69,0001BD627B2E2A72,0AE1A278CFD8D503,646C05085881F413,95AEEC497420FFB7,044432EAACF0C5BC,6D0C27F428482A7B,36BF0F73795AA970,00019B5D7D1CB06A,8CF1AAAA1528F977,30E061E79074CB0C,A707BCACAF089926,C4433A96484B2488,3EFC2B893CC11E21,3E9C16A82D794CEA,00001AA78C0619F6,386E11EF3C9ADE33,3F345CA904720525,0FBF85C12161FC42,713870D555AD571B,019BC840403F1788,0FB2C55A15F0606D,0000A62E0ACE7494,9A2A6064FEEBA7B6,817A5BD526F00A2C,1A0D6D7E501029D8,F9EE0E9F6248D694,37F1AD16EEF97EF3,765B35CBF5E84A24,0001F2469B0ED462,914DDC06CD058D0A,B1CB521AA015341F,764554932AD560BF,0DDADA204BB4EB61,DC5D65101FD1723D,ED233BF74AFC0753,00011C386BC088B1,D24F36F7EE6B2C64,390FC1516A72ED6B,38B9D3E1DD99197D,F686100F229E99AE,62183576EE814323,BCE11102ED020DCD,00004E15AB76609B,6081FF811443FFA9,350E77FDCAB2D6FD,59AB0E00DCE80940,CA3DDE7ED63EE6E9,BC6DBA8E805469F4,9E00842703BDF5CE,00012E18815CBAB0,0DD8EC29C8CA1B3E,294FDFB431DF7FF7,5161BE8DC4F9B74E,2D1DA9FADA3A0D19,6F8E5E8E319CDC8D,141B4E90AB5C35D7,000209DCD53ADEC5,5AD8C2FF2000614D,06A0009899485922,F60BE8649878A9D3,824413699961ECF3,C64207D8E56AE56B,7CC487A119E3657A,00009C6B456EB547,D79164F0AE4832C2,18AB4B04FF516A95,78E7EF83FE6F7F14,B49D5BDC652DB352,C0DCE40B3129F558,08F6D4E0D78C014E,00008AEA7CDB1E42,915EC782EF6E7980,C3891DDF0857BEC4,C5E30E839374A7BC,1780BA1F410ECF91,7122972E82E2A865,86995FDC92D0B278,000071CC3D2A1CC1,164434AB40812A11,394BEDC32B5A1595,A1CD4DFED75A0BA8,5085BE2FEC402595,823CCD0231DCEE8A,B6D712B7F5D773D9,000040EB00321CF5,48BAEDD5FD2B1800,F0169DBE8161293E,B6552BB0BDD53BDB,E65FE0A7DA66E23D,1E1131F481DD48A9,2D1D20B8601744B0,00005C6C4116B51D,AF3F77272DBFC895,5566C60CE4E13FF2,6A2F921B830DD150,9713F5E579DB2A7B,EB5DB9E5173B29D5,E149A82C1F4354DD,000229123D77F20D,CF80A2D006EFF4D3,D813D9B71034683A,2DF47B0858B74D19,699B2E6987F5B937,B59A67979BD19A8F,9FF50417A0C7C51C,0001452867161821,671FA199D11B27AA,B394846CC8902719,1214B1962D43EDFD,9FB04AAF55E979D4,A0B3646A2A6962E1,E14AB1763C13124A,00016F7E75B2F925,0648E314A441606C,70ABA22B1EF8AD4B,43653F156C44AB8A,DE655728B459BE6A,9356F6CCC7ED6214,E09D74AF2B543587,00013D3D7A473A08,6D3145B3A15DC693,87EE74A0119DC5C3,6EB3EAD2D399D3C1,8241C7A29D1BD979,FD6CDDE8773013A3,D10EF0D36DB31DFF,0001421DE85F2E67,B67EF8C12A0F95BD,7D3E0BDECBDF5615,02708B77D19CF90E,23E07BCCACF17B47,8D47EB82DC6A1F7C,10A673E279430B65,00014CF38522E666,1A096E1EEB270528,933038843B893F38,88B613C19DBB7467,FEC6DA1CA0713103,240180E56E9B7710,BF2E5E38057F4D63,0000AB82D1ADAF55,502DF4088EEDECB0,1410FB3E67C58CB8,198656792C37A4E8,4DE0AFE6029F1E72,DFE0B7C02849BDF2,61D8A089A990E61C,00015CBF26EC7D9B,C604F3808AD861A7,FC5221165FBEBDBE,7096DFF6A69A2FCC,B1F040801D15E3F4,BAB7C15F02815853,BAC3173868CF2F86,000108C09198BD98,D24EFCEFACBB4507,E859FEA5FF78FD89,920BB19909373B75,07FFF9DF9C2465F5,C307CDC3BC25FC30,A63D94EF63913399,0000ED7041483B84,2A113CD82EF74316,25F3CD1F99B6A469,91F37212B85EC349,41469F7DA76CA706,066CC52A81908A5D,4E7666AFC4487BA0,0000A6A111E280D7,08E4F12C60387301,2C0327333350C305,654B3E84E69C975E,1B252CD1230EE46D,93EC13BB0E071435,D6312AA2237AA214,0000A941117BF44C,D06B9C5F1D59DA2E,363E8F00AA1AC71A,A18023F2861D16B4,948F5EBD6D24EEEF,666F55D48D856AE4,C627819F38C6ED2C,000070C8E4209D9D,D3F26F1F9527B83D,850B832791ACB96A,0FFBDE8F888140FC,3CE0491FA5944FF3,FC36A1819BF21EEB,0C0B781BE5BD3AC3,0000EFA0DB34FD95,FF6345E89328BCE0,8D79BB07F0AD184E,35139A24BD461173,1734448FC20A9C8B,BF667217CA7A09A1,E8EFB503E7196C5B,00022E314F4872E1,BAE666426C00C42F,26CF0420FD295407,C0BA27DB997BBB9F,8BD7F03A41C0A6EF,591FC2A97A36A65E,435F8D4B5A43EAD5,000158C556A6127D,992296776C5492E3,A56A349270346E93,0B05E3B37CB4CCF2,A157AF55BAE8A3BF,9C48223428C3A094,DCCFC7F3EA67352E,000158EDDF305929,D7C86C5604239010,EF2033BB69E3D360,F80A504D47EED8EE,2F2982FFC989BDBB,21F9500849894B38,03348D62BCB154C8,0000FB91EA9C41DF,BE43F1042591D7FC,68B2F489C88B0656,A53B0B23780395F0,C1B3FEFFE0350652,F947D5D589987687,A5B0EE0ACEF62D10,000096A8BE06F151,6EB8AF1144E66885,A0664F384B2C74A1,BE5C5B9C67C50569,07D763D5E67E0301,97D9BB30D21837FE,7B8E0AC0EBB6AA84,0001D3E30FEC320C,386503F306755803,0F57F11BE69F5A7F,5AD5D1AF653FC2C1,EF66E6557A3CB2B2,97E4B94FF03DA531,1386737CE662693B,0000F8971469D755,C8064799BF1E72B9,6670AA87661EA130,0CDEC0DFD48524E0,085DECB5CDEBEFCE,07D661BF603E36C9,1A8C271E48D9592D,0000FA7B15FACA96,2754E6C7634B47DD,AD4DE2593DB70BDC,EFE555CECABFF708,AFE9C22F4A5E5726,B64977A84CFFCEC9,A875076F76816D33,000046B42F82B90A,1D1EF4891A10A797,09D0A5A2174C87CD,1E59582514DE9704,3940A491B435AF17,DE8396F3E6C72405,250323D82A61F880,00016CCC90282BBE,220E11B0467833C8,4703B9A764E4B8BF,7C98652DEEC49AF5,72D69564C062BDF3,DAC71C23822469C4,1F35A9B6730B49E1,00009618C1E62999,0F04D0E8F962ECD7,B56E44FE43EAA2C2,170AFB64F110B4A8,7A8306ABE1822C25,07CB27D274B8FF21,E3FE38F8CE6A7B52,000172EA02AA50B4,0643C9B06E08CC66,2B87BDAF4E9388DC,D71922CF1672D873,E28B6BF1D657B51E,4EE86292969E26C8,774FA57CEFDBEBD3,00022356CA9281DC,79D5C53DAB84F2F4,A9E38E3B640CACA5,8EB5FA0E9D457179,EA83DFFFCEE2D34F,B7756A9A698C6A56,1C2E63E5F5F94EBE,0001C70A050C84E9,861DFF7E8086EA85,D0D3D9DBE0B60B87,6FC7EBD7B7EA4D0F,ACD957CA1EFC597D,674AB3DD0A8A4A68,64FECB128E6267A8,00021980E790245F,D03F684814D93079,76170D91C18AE862,715CE4F2661E8422,3B151C3DF3DEC28C,2138500C7294A963,4C03650748673F92,000011D21D53E443,215DF9EE691F61F4,B09E653C8FA78755,EF4393609883DC89,29D78911DA4A1113,BD63E4727C7E28F9,A3D4F7564B901073,00010F1BB1A30409,00CF4DDC5549300A,E9413CA6F4CD4100,F7A542F8CF3404BA,439D8AC2A6FE8751,20ED88D8D653E5A6,3A1D37F43C306D15,00019CB3FB40E64E,30EF0546FB21C004,3B818951DE4FB322,C765E13150B1C2D5,D678825CF33E22EF,32982733B22CB893,103D3E24F664B502,0001C359727DB042,F74EBD503067A42C,91FD5E66FD9F2807,88C546CE93DEB7CC,6D142D5052D8131D,28B693F95AAF253C,9C71D15A25A76204,000093296544C54F,A402E80F39BCAAA3,A375A97EC1ED7F27,7F41AA440EB9EBC2,442CB4563CBC85DD,AA7C95FD16A78B27,3A9C4258D739E100,0000314022980AFC,EF6420DB718E8CCA,022FA53308FA56AB,942E1FABB5C82FBC,1F024937482AC7B8,A13BA11324609DB1,EFDB248CA66B462A,000072F06D79F8E3,9A4DB208DB96B3C6,F193B9FD64A6E6E0,681FA9DC20DB5D3E,104B991877536BAA,6F1EFDFB41FEDF60,DF88781860A4D51B,00022A463C0BEBCB,608DA1520FD3520C,E9B12ED60CC101FE,DAF96698575A7191,C93D41DA54C3199B,5074D286FE59F326,3685F42CC3076EBC,0000113B64618EF3,B839FD952957E967,D1C800823F554F89,59556DA71A539131,08D7923878A5CC54,42E592A7AF0E25EE,D9093304DDD65945,00004E497043E3C3,5DB62A851952AC1B,9B3F62695628E9AE,6E6B76578038E04C,E21CA7DDBDD5830C,A3D21C6FECCFBFD4,48CF797C096E0740,000080A32146236A,7CE03DBFEE575E24,B5502FA503B9635C,F6D7020410A9C247,AE731401F0227220,626FB4B1155D4A2C,D3B4121F356F92B6,000118FCAED5598B,EAFA2FB66B470175,30E87AE005121328,2F88A31577FF52B1,CFEFEF54BE7FA45D,61AD5E1CB48AB19D,2B593EBE6F21953B,00007C62F48E67E5,1B7B3581BAEF1BFA,50CE15FFBBF8B6F4,F7D5EF289E4852CC,57AE0BB595B89A5D,13AAD32E2B7E9620,11DBF55DC1950696,0000A2891670CEFE,9D3FD5BB56310B5B,4FCDBB4A5468EA54,1269F3873398856A,D0B6E5A3B049CE2B,25EB4C992C5CB3A2,78042A54DDF046E8,00006FDF68CD1D74,8044A6344D792F29,E748807D4F09BB63,045CF59B6352E0DE,FF05E523AB8CCCEC,D3A6B9CA4FBFCA12,29E9FB38FB4D68C6,0000BA8785175432,85B3E3F08124B64E,F104133C18139ACC,28902AADDF6361F3,E8DD45B08B900D27,9FFDBAB1C0E62AA4,264C51B5BE14E180,000069BDB668EDA8,719DE1EDC7D0A421,6BC959BD69519685,B107B97645155E0A,00ACC868A7936881,050F46B9C022275E,2C3D1284963EF67A,00021ACE55D2850A,898BE48131F65BB3,E15839DF988EEA12,509C88CD5E733E4E,1609EBC1EB79CA03,C96F28E85057AFBA,54921BDAFFDC67FD,0001B4A11D1BDF08,0D4A697FBBA3F840,480C56FAE876C1CC,6634C7A90BE98D90,067C8F1A197CFB02,C557CDCA3E1D08BC,5E8B15E7518D36C4,00005C5260A46CD6,5178990EC7416753,D3E7A43B8689D25E,A6D639D7A2E9B2F6,9FABC1EC98A4C1C0,348B109318082F2B,180A660A6213AFB3,000019058A1E7E29,46B123EBEC2A9864,8C82F5C34E70065A,5F47608551B7D269,08CD6DD23FEF5C5E,AE00D387FCCFC68B,DD7B97B185757FDD,000218A212A11D4B,876A9B62899AE70A,A597032DBCEE2638,F80BDFDD8D6D24D9,6E8C7C9277CA1A72,9F6B8CF39318805A,DFBABD16529CB1A2,00012CECB1521941,E5E32920DCF5C7E2,977B6818D9225CF8,04C2C1A90AA10045,03F6BB1CDAE29B31,616EA6FF7C682817,F6520D1AFB4CBBB8,0000543E4A838328,366A448CF82E8BAD,B48D561EEAE6DFDC,C6084E09627A76FB,485270F129E3ACB2,1114B2C643E7D25D,0BAA7E8A0FC60DC7,0000EF3B4AD3A921,1A42F823AED24BB2,B1E32354683F7DB4,6929E5646DBA982C,2A850BA0A4EE8B42,2D0D895254DC4910,8D0ABF026E117420,00009B37B29A1358,ECE5D3FDDA92015A,D9C92BFA89C61D08,2E7136099ED22997,E2850DE7E04222C6,C99575BC27EB2079,688653C67AB4DB6B,00021C76FF9D2E20,D18702F2B5286947,E42F676580E34921,7CB042D32758D79E,E6E1BDFF0C816C94,84D92C1005EEBD21,DA1F19D93E39DA25,0001D0E3BB26034B,2D820EDDC0651F7B,62013B028741C437,1B35E956F9177AEC,935EFADB19A405C0,12DFDAF2C5348559,05279F1FE21C8FBE,0000363BB39BE8AF,6CD3519BAFED8441,B38340789DEB45BD,AED44626481A1A53,46B118FCABF566E1,29AFBF3B872A027B,8E2B400D687BF795,000146EA999A9953,7F85C0742D06D762,16ADE4369A703CF8,05C0616EBE9B1EB1,8345B4C4C381909F,74588C4BB01ECA31,590037DED94BE0AA,00003AB7DE3CAAE2,BB08F29FA22D81CC,1FA616B97E05C828,9131B905B629A13A,06CE6FDFE8586509,59C56F398A650985,837987E14D7FE08D,00005618821A3DE8,CE16FD8336A5F12B,2D0BD200C05DCF17,759D564FCC3D1D5F,B050DA5152AC93D2,4A05AA3503015256,A9C2FC326D770AB7,0001F88396C8570F,FDBF0DA4DDB14AEF,E31C97CAAC2B1AE9,C1EE53A7AD179B6A,EAFBF7A9FAFFAF8B,FA0A8C02A4F7B0B3,B763F72ECB7E482B,0001E53148120D31,E342611E59B31042,34A38160F4B0FE89,236AB126F9D5418D,569662C622778FF3,6E1BFF617F506E58,6457E0518CBCAC2A,0000E90DCECD11B2,6DE0A64DBD620FFA,EA04616A6DA4B554,35BEC09E9F32EACD,3C364BF667956041,7F550D0B76DD9D96,9BF6F57974B48DB7,000146F2E393C1B1,57FDAE3875A8750D,6D18736EA187ED61,6C8AFDCA13C92443,F118921FBBFEE1ED,1D5626A7695F376B,599DE0B91A589A2A,0001FBAD61F71587,72A9B33F06B83EE7,3D791D5E45E1824C,2D533C8F6861664D,FBF508F845035F20,7E4C27072918DBA0,EBE602F6C29E73E1,00022FCC4BDD7B42,5D68418C13B9D614,FFCF3AE8611FB3D3,AC676226B445E60C,F5F378EA091C9F19,33BAC1DF195C59DA,AFD9915202890D1B,0001D0784F8F4F42,4DDD8FBDCE7A2644,5243541912B284AA,D09BDA56895D92AF,0C116CAA4ABA08A3,BE99D0D49254454A,85C5B53BDB411939,00016F29BB48E401,EF1DE09B50A4F245,D0B95B3635D0A2D8,D3608B43A0657567,91EEFF77F7C3A82A,34F13298B6272CAD,F4E8173A373712A4,000005434636112E,55E11A8D3D251857,CB68B3160FD39797,09A93FC78DB3107A,868FB7FFBE8D63AA,00611AA5A0B2B597,4E9C9A3FE51803D0,0001CA96D81BFF51,78CDE4F9D6051327,CF10B1620B661D24,98D4FB1F5781A67C,909C5A7FB50BDDCF,FF01BF5791090F1D,8DFF2D3118FBCB63,00007F70C09D2EFD,CF2EDABA8295FD20,0A6F8DF8CC583746,FDA751D82BF865CA,2FBE1C53DE2C0424,4D55ED1A61339F79,B34234F2BFE697C7,00002E5856979B09,FBCFF766FFBE437E,754CE7B163CB222F,B849A5BC4A0DC7A0,9F60F6EC4FC9C4A2,7CF33BFE698E35EA,7615FAC56115E26C,0001616D76E20FE1,0DE61615D11EF01B,46BE25F4077721C9,5723C28E5F160AE1,F657500AAFD90A98,598C4E7005A8AB92,DB08BF38D602C320,0000B9C975129CE5,4F198A137324A1B7,6FF849C5830D410C,1FB006DAA4951D77,E4460B76BF982F39,AD1F12B1E3BE38F9,AB5D8D3B524B72CA,00001DD0AB1E6EC9,7FBF1B94D9CF1640,C26D6D0911A74398,65A9B26124832F31,4AE23D0C025E4BA9,68D9789E237F222D,B7ECE01E56835E60,0001EF2B8F05273B,8816C79C8ADB0ED4,9339FF345CA7C8A8,535DC632C3F597BB,3EF3D718CACCF0AE,89B774C401AB4891,B5934191E05CB2BC,0000EC1FA11D8B68,8AB1A1F70385C52D,B94556CF9BF3D0AC,B4AA88E6819E5E0A,6D319409884BFA33,E4189021F087C029,15A89A91B12344D8,0001B2710E8F329D,646A04449FFBBBF7,F4D923532B1AAD91,2DCFAFCD6E36A52D,45DB3B53F6F5985B,FC4EBD3EDB941B7C,4863EA26EE5D538C,00014EDC74BAFFD4,02C3992457820CCD,316E66A30F7D2EF2,FC8CC1FB57BA847E,F1CF9478A8778DD2,161D24DC1B9D2378,C59E79FF5E4B2302,00018EDF6CE1FEE2,8DC9EE7EB81E5AA4,92B7F26FF3C5EE36,A01A474EF621E132,D1EA064372AEE4EE,A7B95DE88EC51F00,6A495DB60D987EC6,0001DA53C8DBC4D4,7F811980684FB3CF,601B85D72F0AF064,0AB4F8993D471163,F1919D90D9B43D34,59BA8DA39CAE9CCB,5BF9FEADED16F1A4,000196A4A17D748A,5298F797A27F5150,92CA69210336675D,5DB8C32FAB48C020,1480138C4FC22048,E6325C0E69BE2148,EE1FDA3493C7CF34,0000197B8AD2FB15,287360F85DE134D0,F7BF6A242A2034F4,9398781FB7AA3F70,5B9D567F433BA060,C330328C0593C768,CE880153ADCDB51E,00004BBE3955FFAF,02AD522BB777BE40,80263C347B9F5777,FE1F088263BC556E,A28B531AEAE0F7D4,F1CE3D837313B1B6,7BEF1B9C771173DF,00006BA43B0B093E,38220332E878527B,9A612E4711BEC953,67C533B0CD3EC95B,6E4B9E9FF4E905D0,887DA87DD651C10A,A62CA7BE213157F0,00020D5EB054E1D8,B7F9BB65D8BAF28C,4C7BFA14B8D3156E,34FA213E1E1075F2,1F94CDD1AB61A46B,9D63052543E45312,2C9AC5A3C4E98741,0001079E5A2858B0,286787778402A292,145C63904754316C,1FACFCC71C294471,14E7B408D394AF92,1843A9224D6B7912,E88598FF4C7A96BF,00022F1F3142A93F,D8CF10B3BCB02B84,5F03E923BB2245A6,8FB431F769123CDC,CD3B2F7858717658,11B42B005E4FF596,11F2BAB32FF606BC,00005A2C828DBD16,00B1DDB6DEBCDEC9,61128324155D3CEF,B0C0EBD93BF11C5E,730EE92BBC1A4EF4,86A7878F26DDA852,A24C2F5E269110A2,0001E5EBCF959B28,1153FFFCCB348CD5,CEBEFAEA41DF75C6,CA8748480B814868,79E2C99FBE9E5880,2759ADF9E306DFE7,5446CBC43774951B,0001C2895200D4DC,DACECCAAA3C2A7CD,E56712DACAB019F6,7955D43F30F61063,9AC9F05FA4ED2841,65B5339DB6048BE2,0260CC3B4AF77C5A,00002F347551F8DE,DDE27C39E5626FE9,DFC551A81025E113,94D22CFB476F509A,C8839688DCE81025,5815193C09AD94B6,9F98099882067310,0001511315FEB6DA,04A05DC3328CC6BE,B92582C9DB6E4C07,97030A5E1650353B,D450739D812BADA2,69747662902CEACB,142A9446FB95E706,0001081DB29E64F2,28731C1602BB8CB5,98060A1758A65AD2,2B053FAFF8DC9C65,F4B92909AAB802F0,17AC3B78A878368A,847C549FD7402549,00012F73F2112FC6,A531425205889461,9B72AE4C7E6EF72E,751D6A2951A6D4EF,1B05128457B83BB4,6526ABD5941C1F6D,3BD6D42ECFBF4D40,0000A09FC53B9DF8,8D58D309EEDC486F,112C5BD86E9E0FB1,858BBAA717F59232,658B8AF8E7B62FBF,88FB5C91F4AE85EA,22A6C230F9C90815,00011C19CAB72E67,1D90480AC175AFAF,7FFC8D58B9BC7EB3,827BD1874A612D07,9908D51007A0EBA5,2A5D23B758579A71,BDFEFC70358620A0,0001738C2B2FF3D1,4590F8BDD6C13983,A2D75E7F48950BF7,8186A357BF717C27,53C8A21AA095680E,298C8D12A626CA1E,F94CDF412036FC38,00005E0EB58BB81F,49785E3D56341207,06A39F43FEAE891D,EEE6890001BF13D0,FEAFD0A3ACC0DBDA,2E0C3A506C4DB6B1,FC1FF88539EA2773,000116C45D2CC742,81997CBD6C43A5CE,6B539C95A3EE9769,BC4EAAF59F6D6F34,7BA1C6E5C28A0D5B,B328EE3DF3467CD0,492B6580F8058DC4,0000339CB0EA72EB,8960EAE09DE7D867,F13485A36824DE5B,117E035CBC85732E,A58E19C9DAF0DC40,3BAF7EEC5AF1F40F,404F34B63C74D894,0000A23F8914C830,C983335328420E5D,79C286A5071BF4D2,DFBDC55D634338E8,697511718C4AA293,AF5CF0B482CC875C,1EF2E2D292D0C957,0000977C97D9279E,0C9F66A0683B8C3A,54EEE9D8BDE994E5,7ED22AFD0860F6AD,711346E4E1C858C0,A692118CF50453E3,3036C4A5D963CA83,0001A132C155E430,7DF5DE1683A44824,243D598920FE9A7C,0692A4A2B22F3996,D6B279FEA06DC015,9965C4B8F2C09939,F7FF91ECDC4E32F4,00013C650257ED8E,D64E8329AD199D87,F66ECACFF297A171,957460EC027D5615,0EA476FB14CCCADD,F608151FFEF3694E,D27CD80139E3DCB3,000003D625C6A9E8,0870988C29F0030F,5DE315F6369F31DA,E0560638A01894E7,A491C7A21DC59FC2,4C3F60076317783C,F1BDD6255B597B43,0001B33DB5C62C49,B3BE86D29967A865,DB38E3F69BAF6457,0AEE18EFF08AFA4B,9DEABC64475EFFA7,BA0A3B5BAE292ED5,9BBA7332BF019FB7,000016A7299C4E8F,0E6861A1FADEB275,2075B10C5ADE9821,46A86544757505B1,6BBB476E6583AA41,31223859B2B39372,19F39E6BEC13D373,00008C68B695D2AA,CC2FED47AE78DC2A,BC9A2CA6BD18F4C2,CF9E50B65018980A,BC6A2DF109C0CA18,2D664A7D1B84B2EE,25D97DBC2F591D05,00010EFBE11F08C8,D1E29BD5C1C4F144,DE77536B090618A8,B0DE55BD147671BC,34916BD6BAB49704,E395ED1D34017B21,54A21D25EFA3D59E,000195D2C3C8C102,C33E3978EEC4F1FA,11957BC9EF62BB9C,43AFAEB972EE9F0E,1DA8E0CFF9EABA06,024DB30F770F137D,99575EF21086A3B4,0001EDCA430703E2,DA29A1DD58C7AE34,977E44C3210B70B4,C51126523427AA05,A2B05B44C4803A63,378EAE846D0312BD,D72C2F48D8745C23,0000613C40A1117A,9F9D362976F40D96,D99BBE928EFAE86F,0077C1E91EFA831B,7E8A0807C5E5500E,FAEF3C566C9D024F,B9329BD4D006F227,000117B661F0BB6A,7A135BEE40757BBE,306CC8D10A3AF9A0,F7D6743580432AFB,5E59F7518EA17D7A,75AE14659521DE88,2F83381C01AFC99E,000099BE21C5E3E1,42B0D5B05F7F5087,6ED6B0E99ED7EAA0,52E9F33C0CB23852,6928168169CE5570,56E206EAA9BDCCA5,9F6DE5A69FAB6A13,000164B9AEC6F6D4,5A8F68B8B0E78675,F92F400CBFCE87DE,6D35E78E1BDE0830,03C1AB45B5BC2EDF,0D1E2E249C9988A2,420461DEA4EA9A6B,0000ABD4794DD096,535590A143DB7CEA,F61CEA217FC37F9F,6DB8E94682A16E04,21E012004C8470B1,6A070AB20BA37D2C,6C9460E143D3AA3A,0000A37222A352A5,1A495FA9BB748780,E40F4340E993AE9C,461369E6EC949FEC,67E587023F337697,0FBFF368A111842A,B27EB190E5596253,000219F1F119B1F4,7A5895E4C84400DB,0D4B450064E1A526,E44B762CBEA29082,FC0364D3B6558CA6,CD1B3734D1F9E573,140B822AE785BF18,000156BF932A8183,7E9EBB009BDC03B2,FFB2998DA699BF21,264181A5891555F2,F5599C8E3E3C2150,816F4A3CD7DC8741,EE6A45E2E3482597,0001781AEC94BE10,382370D315ED6170,A10372EE5D6FCAE1,5526E3D7FB2E880B,D656C5FBB7D832F7,22E319B35FEE36EC,42B6B4B9C267CA56,00007C770D535553,D86C4BDE8031F281,6BF12C0B987168F8,0A7F557020FE57AF,69FB1836B6380366,CBE1E7CA931C623D,323D1C387A1B4789,0000B0F1296A5E2B,7338F8B5C7E9B29D,426B5C75DE8C8DCE,B67063F4FDC3F23D,7C5B6B7971793736,CC4208DEEFDE9453,025166CFEF257497,000132B040B9AB59,C3C749855A1D8A16,4F1A9C294B3565B7,512EEAE9BFBE5AAC,43E3E4DFF1C62B53,7613DC64194928B6,F34CDC95BB824E42,0000163EA87C166C,312B87369225CCFA,EF8962E3690FF351,47D33612FCA91366,2AF7FDDF9E684737,22730257678BFBD2,09CD0114800B112C,00016A4D8B353ED6,CAE78280E308E6EA,D681804330FEE1E3,A4AB00EE90531A81,CD4CAA4DB872E204,3A9551A227132D23,3BE4C3178C0B5B1D,000111F7F53F5C77,9008BD4792E54A19,8AC7367A4422C0F8,B4005E7E7EE88D56,3F1546C8B7446D8F,0A4A1CCB16AAE96E,67D08471B9BA6AD8,000144C3F0FFCECF,8736318961941A53,ED6E0E9635E86131,7CA40E67B2E9AB36,BE606F2AC109A825,4F2B1198250D908E,3225091C04B09195,0000EC693D0AC3E3,4F277C9E73F2A111,AB607A5008F2D8C2,69A89D6B649D42FB,88E482741647DEE0,371280C3D5B669C8,8DD7727C23D5AFE8,00005D2544E7489D,EDEC5B680AF3D500,0D4520660EF4B55F,8C043F029D8FC5A3,FC6C2E01FF04BC37,217D05F4DE288E89,C7D30EEC1016D348,000155A08E78628D,447BF4C225226839,B883ED3FB3A52461,BB0555C0B007E0B6,31C048B559B46B16,D44E01207410D663,5BB01420B81EBBA6,000060C946F33E05,B5D3140942BE75D5,C8109C48B10D9888,1BC5A987D09F47C4,B8BF2C0F76AF23B5,E0E2A04664660647,6D58B7EEDD3DAE04,000129BA59C57913,08BAED70AB64391D,C77787C77AA099C8,E1D51DFD8AD7979A,48325767596374EE,C59B6B28E7333F64,61E346FC955B6458,0002205DA5BEAA17,9754E0126F38BF6A,F390592EEBBD8E61,A2402F58D7DF42BD,1CDC8CAC3014CAAB,8A2BA7F2186E0731,FF5703BD43832136,00013E474D088E22,34DA9AB4DE5F1482,9F66274A5100F430,3D1F1DB437CEF4FA,D949DCA4ADD35587,30B90F9AAF9B6AE3,FECE70370DEAC3C7,00003C9F1FCAEFA2,ADBA6E6B20629EAD,0319EAD085588C04,1AC2609CD6311FEA,C3D7A842AFD7673A,739DC942269EFA3F,EC0D7F0ABC7BE75A,0000B51F4FDF4A2D,85A237F40A3CFB55,D929B119CB741757,E5D7B98797CB6472,3233D6ED5389865E,9EF2B1D80F6046BA,90EF4087C0DA6CD8,0000052465F3106A,E1A67052E24D71DB,47D6B754C481AC8F,30E28090C771C4CB,48BFA5E75E58CD12,B396C1633BB3D263,9265A047DD665B54,00001F9D27150DEC,6A6A33A4EB026227,4F502D7EAFFE6205,29909B58EA9795CD,2E5A376EC650CF1C,8481563236BDAE35,5D75DB648B1E8C91,00005B21E1AF5724,B62D1B7813BB7095,3ED57C0D4ED4EE8D,1CBAC805E34C9084,539A41CE72DC3BF6,641B8E073281CE87,C76D2220D2C0AA35,0000D71B7BFA8064,CACC954B5C202809,814F68FB164B5348,6794C7912F47FDAF,519E5BFF29E0D48A,BE84C80F45F363AC,2E690DF1D38F8CC8,0001BBE38BBABF2C,01358569E74C3819,61701E48C29C038A,F15BCE69DCAC9B95,2F0CE8A2759C728F,70FA1C5C1D3A1D73,53A549584551E036,00002E7F470BCB03,A22689292CB603F4,A2AB8B080CB6D5CB,CC062DFB57B7F088,094AD1D973A7E748,9A6541E2DB7EE6F1,8FCA855F8D648D9F,00013B33A2C2C92A,E2D0CBDB512B7007,9E7D3E105A165E5B,9BF6C4B99F8161FB,5F1CAEC6DF2A6FDA,0516E72C1DA25196,F83F3FE5C9AD8BD0,0001D5D00062857B,55B4889775BC067E,19CD451D7DF4B125,5D5E1A13E9AC06D1,91EC48DCBA22266D,542D1CEE574ADB37,BDB1A669991B93D7,00021B396C35DD86,C253424B7400FACD,12E90BEE17A04E06,4B7100D70E6BC850,05AA98B79CA67F24,CC83F8CB15238D55,27FBFD6C5AC30905,0000CF74A9FBE99F,0D95FA749CC2AAD5,8F2A986435C362A8,DDA94651449BB1A4,2F2B49E69A206DD5,C946B1E876C78A04,7B99EFC8855928F3,00000CC448E5A1AE,CF19198A0C367FAC,3C90232BBAC99377,0EB13848694390E2,04B85229FEC74DB8,21978AAF0E812A2A,F249CB7045C3B1E1,00007B170A4480A6,2A14A627C8E7D3A3,9592D3608A2D2640,0CFDC65013201699,FFD90242B7637E39,216E72B056ED0F5C,DDBD4E097A99BEE7,0000F086C3AAF972,3D5DB71F2E0781D6,465E6D4788427071,6B31D00BED4DC6CD,18B2365A3AD488DA,74183D5CE7B6642E,2535A80523E21DA0,000129C4720694A5,B84837BD4B4B5B06,AC2374CF7B462242,1C57870F4B6FA099,C69988D9529B1273,7A0D22837A340B5D,21EB1511AE38025B,0000DE868A311361,1763890E4113B713,97DD0C1BEBADDEB9,B71200ED3F02FDF4,A41F1B44F94954F7,46F2EE5BBE823E48,7C10B74F106CD574,0000BB68146229EB,9EC9C6696D1EF2D6,29F41CB297CF38A2,375654F3339B49AF,4053A19D6751A39E,4020609D75D2BD3C,5CC066BC1375FAD2,00000BA841CF64C0,24F22285DAC19C7E,F3777471B8DFB6C9,8F7845AEF2416084,72D3161A169957CC,87EDF60EC7CCDE6A,31976374B60FA750,0000290B66B05C0D,9120C07565546675,CE2891EDEE9A1CA2,D5676DA332F6BE73,671E4541BCEBFF35,242AED038DFF4C5C,3A69E28E95A7592D,000077A380B1599C,C442A090CEF0940D,C96003F230F5DFD3,D972CF2A68980D92,290B01C1BD385482,381F00D306E39997,010A4E26E839828B,0000ED5D2A0EC0CD,62519D1E8C71C486,6CC0C599118E1EBE,3323A21CAA787BF4,42D7CA8BB2A4AA35,CCF02347BC6B55ED,831721472598BB6D,00019E58C2D29482,3151195BBA32D637,84F3565D83881644,093FE121B97AE6AE,6DD8C9F9F4165DAF,5338DA46203365DF,01E8F5599728AB5D,00008C77606E66D2,1B82C38E1D05EA96,A9E1FD5F156EF29D,0C09B9760CAD7ECA,DF85514541A4E9B6,B9A46DC1F48D7FD7,37C7EAD7A25A16C3,00008B848E829A58,BB948AC7647F95DB,2BC3E282693CFE73,39D6DA4D7A206F07,845F4C1ED9901CD5,630F130A33A6E54E,962599D90A70697F,0001014F0432FBBD,9CF0E7C4B8A5465F,50350A811AC57590,884C66425C9C9259,3F1FDCE4565E1A04,75FF00229018CFBD,429253DBA75C36BA,0000EE660DB6E671,BD6175FAC221EFA2,4B22C573815E1153,AAE777F553A08562,D14B74A0C4EA1FF6,C353AB0F4737D834,E7DB7615A5E6F905,0001831190D56D12,6BEBB99876899EFC,567162E7C4EA2F4C,D3D387E3FFB6C8A5,CC1DD593EBC2F535,09EF6DD7E87B66D9,6807A5EB956883D1,0001C35DAA2E4770,CCAA61E9864982A5,F43B9182A0814DB2,0E819AB728F47ED5,7948D9D986F98292,F7D58765948EDCA5,032CCEEA126B2BE6,0002052F68023386,EEE200809F944896,26AA48F4A6AD5970,B8026C1A283E771C,CE2C17A3453E89EA,E137224507DCB55E,1C4C29E6F74A5D43,000171D10B64B3C6,748BB5B8DA24B2E4,C3C697987F3E6F84,128CD9117ABDA64A,6042044E4E8575E5,B6C9261B195580F9,1B74A2F841FB4701,0001C529528C0B47,0F1FF09AF0A0EFE7,378A1BAB980108BA,7BB3144340ED44B8,5CD7F7BA5995638C,D5D6CCBC7BA84192,B9A1871A2B6D2DC5,000187C186A962E9,182935E4F6661A44,ED1FA57AD444D8B6,B2817CFC86EB7B9D,0F27BA78E19D3F6D,8CA6988F25CB8F50,A62E1A0F6B46F3B8,0001D0E7C858F6B6,8D1C7818D04382EA,19A4DE6D0E912AC3,5C7BF61F80264FD3,A650F9F54BC86321,8F3C6400DFC78293,1CFEEC739B8AD6EE,000080F69214F75C,8C691331EE657930,D114BE667A9ECF81,AD207E62316131C8,409A44B127B66CFC,7D8648F94DD2993C,15DF5D48B2086273,0001A9EA12312E41,280D58B75219C1FE,6F92974A8F0586D1,4C59281F207044D1,D8328DD8B129725F,C79751FFAAEE3342,EFC71549E60557A4,0001B58EDC25971F,F9A065D5C7D2DEE4,20924F853C5BED1E,3BAE976C9CB825D6,C44559710311BCFB,5E7F29A533DC34AA,3F263B184CB6946A,00018D06BEA0C8F1,36FB060D33FDB4FC,4988BA19A8B06990,8D22B53069145B75,AF7FFF7291C122EE,3B9C0936AB940FCC,85BB81E424183351,00003E0BECCF184B,E85D6930BE6FE72C,C80B8F443322C878,E9C2D55B597F1E69,5B9B098E9B057487,DDD1A8FD742EE48A,2D9C81DB9A3CC4DD,0002341876BBA9AF,A2D713CA4DA69538,EFA983630A202D49,F58532E4A24C3A1F,A07DBA43E5532E40,AF7492709CE1A512,2A26EEEF9B7C9FC4,00013E1530C78719,1703DA3AABD2C2BB,2A3BDE28A6F5F34E,36B9090EB0B1CDF8,B6E7958976925FB1,2F9329EB65B67DB8,6C1434CF347BAD48,0001B9BBE5CC8774,8A11FE770267C03E,EBDEC10B2F148F7A,0DB9661298D66C84,C1301D10C237C197,D42C55B228A79A6E,A41DAB18B18A7140,000000D299CE6E5C,F84F68FF780FBD01,75A6C70295F9C502,7DAFB1E3B41314AF,B2E3C53BA34946AA,89A7C83EC1F56106,7CAB1A32BCD4ED3D,0000FE592925C5B5,824E2D8F22AAC089,788CD4D40123BA3B,44CE79BE677C2E23,D87E0BE777178390,19C0288B88D4D75D,9E2A14544B4E1DBE,0002082473812168,E0E26F23FF29A66F,8FE04D27039CAE77,8E7F0F5F6E1D63BD,50A05F46864DCC87,5A20616366659FBF,0F98F63A203063AE,0002296B7724AE91,CDF1E9A176A9FB83,D0D821C77909DA59,B95C5CC74F1513D9,1899086C3FD8A3B9,E5B4E4F7862DEDEC,72227ADF6DD4E281,000136FC0FBC098C,04CF38718DD5766A,02109D8E061455D9,29313E6AF349D606,FC6191AF6431F9CC,3C43844146DA3F76,BB4B3F0CFD8C5368,000185A7C9FA00EA,CE2EB5763FA15596,A7C1CC3BE4D45B81,40C2AE24131F7C82,545AD9042DEA6F83,B6E3E3C91956EE18,472C9300CF69734D,000186C43E7AD5CE,5BBF9CFDE7BB8453,8CEB3A4B1D2267F0,17453AB197C81076,1F0AF6F2284F8921,CBDB65A4BAC4FB55,520638A4E48EE6D9,00015D40997C7A8A,1C107925B8ADB925,CB68EBC192DE6C15,436746CB827CA8EB,33FE20395242911E,8B39847C6AA6BB2C,23DFED045DB248A6,0000D7644D44F90D,2E089CF9935A4672,07FC8F4556BB1194,07AD2837DECC6176,1EE96BA08F355F31,189FFCD45A5E4ED3,E9BC5D7F4E0E3231,0000B675D32F43E7,722682B08E26249B,625C205CB137373C,773850FB6267C440,117CAE101635E96F,400FA1C9D733496D,43CB9098CA3E5E7C,000023A7CFBCA4A8,38C1D813D4A5DC6B,3CBFA38771160F12,B12ED79654978E0C,5A8D48941C7B7B9E,DB2E3C237A13F7B1,6DB25EFC590A5910,000082220A665531,A3AA4256AD780BA4,10209F9AF6776A40,E22D306BE4835C4A,842EF921B4B9BB51,C0A670380ACB29E4,7157E1F87E752C2A,0002068E149E54C0,6CDE861409C8C890,14FACB12CB84AC04,AC4045A116D2BE7D,EDB99688BBC3B9D3,53C6C6365329DE0E,5368F48EC3966CFE,0000039378A557AE,2799F97DF597D592,49C07A3BB43ACA35,ADE8D932A952DED5,DE1624F6D647D759,4DD12913D2175293,84239BF5DA2FBC54,000185717BC7D9CF,0F17073C74E5F367,75D5B957D5FA422F,F6A1161B2393EE19,E45E2F3F23312D25,669931B8C46F1548,6AE817EA5D47ABE7,00009E66081536A0,AE6F0B8EC93A5EFA,04E8BE6453050A7F,7AF891413407F3E0,FB92AB099949633A,EB8293FC1015EA5A,3EC8EB2A30A403CD,0001EFF3BF3FEB1D,6C1384F34C25765F,98448695EB511E99,23E92E9E05006990,A3912E8922FC4E24,EA4AA2E4CB19C120,17232578D35C569C,000192BB46F70239,64CC26D0FA313211,9B9BA33A5D033059,184062EAB4B72582,3679E17D8C6EAD22,3591B6809D2D5AE5,5BA93B62EFA11615,0000A6EBC90BF042,75E13850F9DFEF4D,EC3B071747D5086D,4FA68D20F6918B59,90814F459C92E08A,410E8ACA808CA92F,2F345B1ABF4FEF55,000031F65E0FBA6E,56AD002F898AA856,47CE4C8146BA86B1,82C088F0FA423455,1C49290CCEC6D070,5C2655A64BE2D5AE,36F041AF16954C0E,00012548E36E4FD1,D370B4509C649F77,25A24D9C15ED432F,0D324EBCAFCA09E3,23E99B1D66E4628D,82D2E73F726BA270,DDB6F62C7BDDC930,00010DDF32FD84CE,DF0C37C30DA02B6E,98E314C539EF301E,ADEE4C61BD1CF84A,FC991C6121ACBB53,88AFF9F166E949D0,D58BA8FE0910B487,0001136C6E818864,50E4F4B98821D4D1,B575CB814F310365,2ADC07558EC10159,A6A89B5061EE63C5,ABE4C0C41FFEF67F,2AE3D2951337E71C,0000F6050E9D52F4,513998B93FB7B8F4,F6BF005E2B8A1C25,FA82E07DEE27C541,887FC0B87FD94250,DF1F205D4C14A304,54C72C8DEF7202BF,00012F43D5E5181D,7EEDCE6A8D5DE95D,F5FA1324371EE79C,574EE6A0A004BE6A,60A8FF27DB44BFD2,7669530B4BBB843F,5BBA13842841ECB6,0000A0936330E281,57D384A28AD152CA,3ABD779394FE3448,DA76E8F3DE0B4037,4BDC0627FC8CCB6B,88E2E791F5210CC9,983FF1E7F337E5CD,0001367FA28F1C14,B2F25861353EE767,821513E0D5F05C43,937AB8406890A79B,90768C9385F9C289,DF8CF5E03D458B7C,286FF32582442D5E,00003AF3D28A71CA,2D5AC72A28422BD6,A4C1F2E50D20F228,14860E038C5C201B,806E53838B9577B1,B64BB187DB6A7D32,2760A99AE13C7432,0000FCD4031A1A36,3CFB605CE4A17332,AAEA040B4B405D5D,878034393AB5BFCB,058A78023319CB60,7A59CBFDF4CBDE89,CBF4F757C7001F7A,000199287F695931,E3354273A95E742F,72A24FE402EEE0D8,5CBFFD0C1E600473,46CA38E9B3DAEB14,E14C54A93AA29A51,25FC090248E113A7,000116C76B8D8C5A,8FFEDCBE1105DDB3,C95EA9E01F0463A4,4CC4E73BB4042D82,7E414D4A282F207A,D2F440795E72F08A,FEE339E71F605281,0001C57EE652C1CE,5ACEA5059F0950BD,90A8B09E52F4971A,59805C135A6052DF,38E8609B40E36F82,E0706C600BBF0621,08E5F37EC4BB379D,000194853E1B7C61,FEAB9992EA633ECC,79532EC650DD929E,FA9DC95CCE02922E,75ACD5118F98DD87,B77FF15F827B5980,E860085573D4738E,00000EA5C6CF82A4,3355B17CF772812E,A7D3FD2709D03A4C,A2DB950491509D06,B40DA33192A50A9D,66EBFF39C3A9DA2B,EFD0613FDE56A09B,0002183AC6C921CC,BC31759460FEEC2B,34F66F615176310A,568703F737BE1B08,178950B77374354A,1ECD99422103E64B,3C3641CABB5FD1F3,0000AD35C5A69ED5,4B92C984A3361EA4,3BB460616BD402D7,83740FCCB35EFB85,ECE0BF66C6349E56,45C583D7E4787BEC,93DC001AC9B3041F,0001FD22E6A24FCB,7F35D5669F5EA85F,64356B6BB6857660,5E25CE0D9121E63C,60552CFDCB048A40,C11F94AC55C335C3,55D3F4C025659DD5,0001B8F01380775F,61A1350E812C742F,0E7A68B2BF960139,C0CACC1ED26874EF,F2C6781DC082AA5C,BFDC165B8789D248,851058D7009C8A37,0001CEC589E05125,450C732825D39F42,6DA82924CDDA3398,92533B055624D79D,97540199CF72E85F,C5CFBCCE9E3D8665,3741EC05F2B37C8D,000110AC4C8AC67D,0A7C03B7A794A2C0,3900722857C30881,A8C441EF2E641D12,753C800DA8B95AAE,2E33B7FB49ED6FE2,EA829A0C10C83864,0000CFA2133FD629,6DB607BF53970F31,BC2FC39D8C8BB594,123DBBD1B0A48FE0,068B9F03C7C0D2E6,587ADEDD473A2E65,6D3FA7B18FDEFE8A,00018592929B8E28,0378AD36708A1B4A,A06A533FD430F3F6,80CC5F1DE9304DAE,932F25E295CD7C68,0BD82D3F91212C91,DF480638B3006AC2,000085A9C36EF42B,1ED7C0957C3538E5,78BA6FF2201FB760,481BC0C01367CCF9,B865DAECCC43959C,77F1F7806DC8C70F,1C2EC92AE51CEAED,0000A5C02B6C10BA,F31CC9E6FD0813E8,2344462F5EAF3A07,751319931D916906,AA885BC474B9245F,1C9C806D7D7DE4A2,AAA760C170A5B67F,000058178A7C5D25,D5D4A678944F4E9F,CC01254A0ED2209E,89A2CA5DA9F0EAB3,78375858E080F17B,AECFFAA0EAD00949,A2F1068357325D3B,00014A5FA0FED09D,D6C64977072BAA28,44B3BB43ACD8624F,6A0D011485A169A0,EA5162B8220D33C4,5A77B3BE17E6C173,6BB26282A27016D2,0001C3752AD9AB3B,0DE0A1934549B2B0,F02E56BE925E1630,642039BA1B07DD17,43AC1AFE50ECB59B,B7C96A8E2FAFE340,F1B8338A67298B8D,0000B102A3F4C0EB,9578F5AEA81D0456,ACA98AC201478857,BF43693331F05E35,38162A9EA8CE96C8,A7D77A9D727F9644,B8BCBFCB96C1A022,00012C352E40ED55,D6BBD20CE1C81E15,EC53B43C0463B2FC,9C4E4E29E2EE4238,C58788FD508558E3,793D47E589D42F02,F17E896FE3E8B436,000211B7687797D8,62845FBFDD3605D6,9F9AB96CB199CEA0,FF027B962B5355EF,DFE590443F995C37,48A2C8C8C081BDB6,576E85E1A9492922,00004485D2DE7492,7F6E5C3A7496BA14,655C1142DC33BF6C,E0C23F7A01FD12EC,1F69B23AD6B4995F,DAE79DC2BEE26ADA,F5A7F2CF65ED2D84,00007047D6855A2A,7E85838327123996,FBEA6792EF9E1379,F750E910CA4D48E6,4A231D72FA241D18,638C1678074CD8BB,DAFEB076D30BEDA6,0000D2CE89C66BB1,670ED66A85B397CC,631098BFFD72911B,335A6D7C255174D5,35A13EFBCD2D2FAA,87A2465FF6CD1902,F1B9D495B489891C,0001B00B77821658,6F18AF722BB30C7F,1B71AD600A9E9A35,2C3847E0BE8AE564,1015E7C5CFEEC10E,31D04C669767CD91,57924F67E80A428C,000070F982C892E1,441AAF50A7765ADC,C85FFB9509936729,1B483388F704517D,D9B3181A1C1604CC,F77B1FA22F46E894,9F9DD17A3BB7C5E4,0002227E953EC04C,DA9A4A4A683A9E56,D65D4EFA9745D31C,018C3B0D12319785,A52A2F09E88C3E12,7921B8F458A4AD9C,D2FBBE08F54B445C,0000ECEFD08658B2,C6EC4458A5484DB8,BBD8DD2EFBAF67D9,C5731DD7EECF8430,FDBC56BE5E02D136,6252AEC9FA679E1A,79DCFE66A6A49FC1,00017B0992E0EA28,79161446C4635D23,A1860B263FCF6746,ECC9687C4B07A5F7,DB2260BA5106BD8D,EEDE0A3B79EE73A8,1535C455F59BDAAE,00001A87D443D7E3,9F682159F576447B,0C97C783E52FBC9A,E06DB304763D580B,F363577676C0E14E,DA198797E7D7CCFA,8B27ADD97AF00D31,000139B2E237EBCB,545EB8D360A26F97,2EA8E39E523E1148,A0AC32EF0C968684,E3E368B616D43921,A99F764714D65734,E25D2DA2A18F9251,0001F426851A11BC,01AF9CCF2CA16A3B,C6ACBF40B74B1B79,1A1AADC8E4AFD078,A73825A7A740B8FA,4ECFD80154708C14,9A05F2F76E39048B,000199EDAC6297BF,F26CE6B3C9F32FD4,30EED38F8D91A2A9,A296F524BF913859,889ED41B52B989B8,F1CFF0B92ED0CB5A,30CD703206864ED6,000190640EDCF66B,5374868976F20FFE,384627122BFED35D,AB3B711576FA871C,79461D41FB3B6DA3,A88C50272CE5D2F4,7ABA5A27D8A64CE7,0001D69A43412569,3AFE70696BCBC677,E59BE0C5B05D8D25,C0B08E301B9765C9,9A3B377C55B138EF,A246597C08200679,AEAD737A3A2BF481,0001415A08DFCF64,213AB48B00E29C07,BD99D3B0A4E3D108,72D5F5A36C3C1BCA,A2160210780DFD0D,E5C253444A62C137,336BBCBCE3E02F48,000039976769AC8B,070208293363DB27,B76E699117DC4B41,4C242367D51CB9CB,1BFA0A4634F0EC83,264055BE553719EC,D633ABE9F149B2DA,000139DE7B163FDD,062BFE384532FF23,84B01FE7AE4B064A,B4C24B2A805A7694,69FC06E4C0FB9926,FB86330E05CAAC3B,93BC96F121FB6B01,00002E7DFD6EC296,F56533AD11BB02ED,E481719AACFC35F8,870A371206C32EFC,DB062A0447041124,A9B9EEEFE223052A,4030323A73C0BADD,0001BE03E8172B46,0F27871CD147DCFC,D47A2BC5830170C1,B3DE6FA5D1632FDD,C5FBF22AE9BD163C,C3B3CE5E0207A080,DA3822D40E59F171,0001FF4C77FDAB5C,EB2CF9E92B4E8E0A,39B9A2FCFE6BC6C9,D43DD07116F81FE5,B109F16D0F0DC03D,0D305CFE34D8536E,FFBC2E2E815671CF,000077F9B197B6F6,3597147BE0A486CF,3DFB00F4D8A60AD5,23D098A22C8568AE,6AF1491960EF6104,39DED34CD7668E31,48CBF8DF96D33591,00005DB3312C047D,915F847D99432F38,EB56CF680A227E54,03F4ECEB841F1F52,8F96647EA3F66659,93063E22D114B88A,E6B02B681D6D1786,000119EC297F8DD7,524C8C288E278086,0DF04C6DA4587213,660255D300937D3C,B6AE96481FB45AFF,A468E33EC50667F8,D1F973D1F424641B,0001E1E440BD06BF,3078004CB2F87442,A4BA955F4F4B4343,23E926231076C8EE,56AE3DD996773DC6,EA66091504D4AFC1,045527FCFAD8A809,0000283185584F74,54D19C6803630BA8,B7AD1C069EF9B99C,A63D5752CA05A492,BABDC9EFA5CD01AA,4AD8BA7B28B04BE4,7EA42306B4CCD45B,0000185A8EF6A828,1D29779603072BCB,98BB0106F3C9D8E3,C0D167F257E375E6,3181C8BB9914977E,1832D37F1EBD500E,6602FE3329132F7A,00021878A5E7D28E,C65BD888F99BEDD7,07D26C7318F3A0E7,9E0CA6E0434D5BE3,21D30A8C5BB5F9B2,91AD824606253D73,DBFB9198F674B2E3,0000740A04085FA0,14F9A7208C10929F,46F94158C3637051,F9F7C912B0143E06,8D18FBAC3B3A3FB9,495A0FF5B3E4A969,78965291F22826CE,000149BC2A39E791,AFACCCC9628B0A5A,99211AE8671B897F,D5ADC5684C39F9F6,2B0AF838D79024B0,9066FC62D57A5D4A,1A319D46811EE49C,0001C5E8CA970ECF,70E53AFAA2869878,729D84B0A8A88FB8,DA8D24C0793FDF84,DBFA064747430AC8,613550286308B4D7,D7B6021AEDA051F4,000103F488AE58EC,9085B7210BE48927,3E17F4E03EE5CDD6,EB336FC34B4DFE05,E2727B1F4E2CB1AC,FEC489A704A10B97,63EAC340E55BC180,0002054A25D35218,32990C07D5AD90B2,AE880262C4886912,5256D5C3FDDCA3E4,70CE3079DB211A56,0EC27AFD26BCE1B6,A557BAE72F5DA394,000098470924F022,B54CAD89D35A3C99,1CF69AD6368174A0,ECE1DFC0681983F4,5810B4812E61B175,C6629BDB99D17CD1,59F7F24926477E61,00000F7F779F4A1B,CDB210BFE962D26D,A226D3AAF626DFD9,6607410A1F2EDBD7,0AEA460E065DE1EF,2FBAD039AEF856B1,14E3BE5245D83582,00019BA37C46BE60,364327560492AA2C,C84B059FA29E5DB1,2CDE4EA25E789377,FD44F12959BBE89B,7CB817DB0955C0CB,FD6A959BBAD2DA8E,000180A34C77F930,7EA8B583A46866B5,CFC11F56593DD9DF,199A05B022A54DC6,E7C61FC71F29EA76,2ADAB8F037EFDF10,8177702C62D00345,00001AF1986C9489,B1EBD5D81A2F4E47,E02151561F7C3DAF,A59388D3E9C53D9E,7DED93F982310990,664A13B359E282B5,521AE1FA2D19EC7C,00016E9438796653,BFF32C1221077F76,DA58DEC4ED98DEFA,627E16ECB9686843,94B1302E5771C6D1,C32C45ED1CCDADB1,B9A85FBC7B24C48A,000168292646FA4B,DB801166802EFC61,B6786BFF6227C682,18C184B660242CDD,B63C60C2970F8AAB,A264A0B43810B3CE,C3B06C0707E8AB47,00020BF291B57C9E,13D38AA995F066D1,B42471DEC81D28E4,14FC13B1B335FFC7,5066F8967935DFAA,0ADC100AB670A6C6,E1DBE76A8844E6EE,0001EE0720B328E7,2792E12CFA1BDAF9,6D6ED1ED0C1166C0,3F860C4703C8DCAD,7F0467627ADBB954,04CB2F34F79B31DE,3A39C4F25052F25F,00008701EDBD7232,0C36425449FE4C2C,C76362E89FDEC027,46A425758F1CC8BC,CCB740616F7501E7,6DB2B232E18E2036,D9F27AF67D2FEF97,00002EC52247DEBA,3165E43C9EF4E28A,3F54531E75DC5FBD,B6834BF14E11EF0E,A3B3D9843B95EA6F,89DF4389AC202180,73785A8A70E43185,00003022D3AC25EB,439043239E1823AD,03379189B848EAC1,AC83150649D53514,1C8B10530579AD77,9D9CAD7BF862CA1B,1A79ECF406DC0118,00014EEB51674AC2,5D7C754D4AD7FFBA,29EE9E36557B3E25,89A84459244EF533,FA934AEA25AB6B03,E399D9709FD8A080,46B9373F348C9D12,0000FC791149256D,E0153A98EAFE1797,F0C5F04325829516,621B431D1958B148,FCFEE863C0B98076,EFF294DAC0C81277,5A8CF85DE0E74CD1,00013008692F0DB3,D138C6092900F7D5,6CF167F3D6252D3F,1F38ECD3D89A4145,3D4D0CE679208286,13FA0174C16DEB38,4047F2D26D5F8754,0000D5E2EA545425,92AF256C2000E1F6,E9B0490F4B817FB2,A5CCF281548099DB,1A78D3E551B58732,4B9AD8CCBB23B839,DDC0FED384DED559,00016E36E71AFC4D,1E593AB3913E4319,74CCE6911A18CA26,1E850CD0682DF4C6,C578E6468138ED08,184BF9CCDCB44609,A75F965FD47E2259,00004E8502B50F41,3D21C903135A0D00,432DBE75A7B781C3,AB72FE06290507E4,8E874ED23C406307,474BF58053A709C6,01F0CE2843BE9E31,00013001EEF4280E,DD007EE7296DE436,A9534C752958CACE,1251D48CD60E03B0,C157EA9B658D9461,B9638E2BDBF3467F,EFCACA4237DA0CDA,0000B5E2CFBE30B2,38D36B8053BCC653,D85BD7EFE1F32546,330B55E91F9A92B2,4F322F9BE10520A8,41A5EE76D9C45D7C,6B520E929A5E5DC3,0001359C616D0054,2A45CB5ED45F7020,4D10FEE8E47DC291,17CB3ED6F7B60E82,0F960C3D7AB24CB6,A612D8F6B7820208,55118A0B2563E3DB,000147B3C3A0BCB8,4C4E62E255B1D9C4,7F0762813284DB52,3BE9A46C8288943C,71FD8B0EAD12878D,949EF0FA54D8C003,6581DBCFF131B9CF,00009404B176E372,D2498670FEEE637A,2C38BD9D877D29D5,D4A12CC5572894F1,332552DBFA14302C,A49BF9798DDEFE4E,A17670BC6FD4A3E8,0001D421F862F9DB,64A0FBC4CC5B148E,83DE2E19558BC4F0,A1BD604D47E07FB2,E5C33C89EDB983D5,50CEB657B781D4BF,EFCE25011D0CE8C3,0000DE80ABBC3BDC,CF3315DA9DD95176,1B353BE82F0ABE81,ABC2FE39A18B8E7E,F6716D520C15B8D4,EE8A9AF5D2D66669,0BB012036DE1E388,000209090C2618E7,FA36260B659122F0,AE7C0A3B27334CA8,652C139D4C279113,7B1487A9062A4DB7,7056E71DDEB4CA2A,489A0AAF749271D7,000039ABF87F7379,CAF39CDA9BB8D025,F3296314A5DF6890,40C4D2816003E57F,05222E7820878794,4A7ED7B6C55D9A27,B70D012705188579,0001C1F9029973CF,5CDE3814F98CC950,59A6E97B748CA914,2A7F8417CE332B89,9F283932EF56D47E,14533E5CC2F364FC,D1DBF368BBAD9A7A,0000A35BCD967FBE,719B7DFEAEDD8444,C56DF8C55268BCEA,97501039B9862B9B,4D93398B9C6BC0E1,4A37097CD3C24744,3EE9BD5DD619D14F,0000E1C083488637,EF980C268FCD2BF4,F775207C2FB9209D,870296080E155A49,2B8F66E690D3D7EA,7A04759D0C5D250A,563AD45B6921BB43,00000B94B845D879,0BB271BCE5CFD6A7,E99E513F3EE3BCEA,D3DDD265C8DAC8D5,6E668EF7F5E78B78,2661D03D07C7A0B3,44E4F91974384EF1,00014BCBD26B54BA,D91A032CBE8C3FC0,FB34199A793BFC1C,1DD537B266C75081,70FEF01D6F992E5D,014E8C9EFDBF5EF2,D5404CF18A1C8179,0000F9F5F57D3EFF,F78235B9E46BB023,7A0D0BF10C323E58,C890BF06D98D81BF,65CBEAC1582E8CAA,AC8D9DDC98431BBF,E54BACA47F38E2CB,0000E54D89C0B14C,AC650D5AFFBBA37A,53D457E5636EB44C,C00A3AFFF4452601,97F7275AEA70B296,FA6A80DEB855E394,F86A5FF7AE9C7A84,0002252853BCA147,111BD3479C2C2F09,2C55B065B7AA31C9,F0AB63FDD1626773,4CCFF5B67E5708FE,6212902F3E0D93F5,2E5A391470B31C32,00012AC647C4617A,B71A498BAD4FB1A7,6371CC037C9031F3,A0779521CCB2883E,F9C4126D5BDED025,DCA010E41B13808D,1A123CBBA47D1E7E,000060374E7BFC13,E3E490D4269BFCE7,758CE98C7E069AC4,B53F83D6254E64AF,477285B896925C04,98B6A4565C4F7AB8,0F1125A1705D0E58,0001052F0BE42897,E6446B056E856F52,A989FBB3AF3A6967,637FB13000C003AE,6778C2AA9291FA9C,36339D88CDBE2B05,35E0F30BD4329E6E,0000039B25E51ACD,B0F5879F5A6AD51A,0F882189AAFF010F,5EB4753424A2E873,D7E96198DC29001F,CD267581F4508F61,D4A238CA8D676C66,000061A4488CBEDB,6B9BC9FEFDA108AC,16A62C4ACCF81540,EBB7DB22E95B7231,4162EE47EBCDCCAB,862D5B347DB2A225,1525BD1ECB660771,0000098720EF290A,BA830E03927851BD,C1D69AF357362CDC,E4BEA80339642CD4,6F83869037EEF91E,76A7A2A92BB8503F,EE3D3A9EB1DF6C80,000049AF730BDCC9,11CD502D33BBD4D6,56D69E4D9D402603,E67F0E1788EF06CC,622B8E5586880B07,FAB293679FB11521,40530623F2630E5E,00001CCAF3DB73EE,C970370C7E22CE1A,48D3126E3B234889,7E76A161C71117E9,47A43571753D5D11,4D5F937940A2E771,1CDD4AAEE6A894B0,0001FD0CD62C516B,CB1E412181A981F3,039375CCA89D4BB1,25EC0A191489D9B5,26675D96E7646790,8199B7D472C8BF1C,B4392B4201421B1E,000139BB646A881C,314F30B470FE3F0D,338BBFDDE03DF2CD,9074C6CAA8B38E31,A1D8B24E63884E7A,69D0659C12603622,F88EE87B9408A359,0001F07F51F2F0E3,D9C8FEC6A3F08986,ED62FE3466666532,D489BC7570CDC0F4,B4C576AC1DFC0F12,ABA97F744BD66893,3119EDEF1C555547,0001AD80E5062B9F,F1410B36D90C42E6,F1CA12750FE91BB5,86923CB542F47EE8,1BF8CAA57DC0331F,F4A42B21A48E030C,2A96F22E854F5D12,000158C7B0120F70,22C61711B71545E9,58F4A0FC3836BF2B,0739F1DC00FDEB27,DBAFC41CAB11A61F,B38DAD8D3BC143A1,E335AF36A03ED538,0000B278932FB062,7A03CD76ABDCA45F,660CBA9822180053,6013ED8CDD639CD6,D54932B7E5253459,ACF6DB95730A98E0,B76899251C69106B,0001B676903D0D21,AB9D67BB28678B32,B1006443FC1776AE,096CB331CE40306D,089C780ED7109323,B80E75366C299FED,A153690F255D31EB,0001DA01EB5EBB0C,407A1EE9CB63E0CD,1900ACA836590409,E7317182154DF3DE,10D13D02A93D0162,56869C87AB10A333,B6B57F2AA55D730F,000223EE6CAA09BF,74EEF204797A8F9A,8BA811290B57D7D1,2BC288C7E0F5C1BC,553D9E8B56F23812,51AD3DC6D32D3F25,3DA5AFE68C218CCE,00016B19BD4C7F90,2DE9D998EFA8271A,2FD7C3D557AE3817,7643654D1087B46F,2B6FD3F08ACB4B5A,55086A459F9C5814,69D2EB0F7C8683D6,000000C9233FD4EC,53A9E21DAB8757E8,F0CC331BC5932303,416DC7B691236D59,087E23D7314B86C6,11D4E8FE8454EC1C,5E53AD08B571C6EC,0001F81EDD57BBAB,9AD8980E1941A000,07ACCD6BDE9C9FAA,973C4088280E3789,7775CAC519E9E282,3A827A156914D66F,8452AD8BB8133E6B,000002FA57562139,B43CE5993D462E6A,7D7B472983403C58,AE4172DAAFA36F64,97EA72401CC730D2,DB24C8579B1CB3FE,CDBB11F41088C298,0000FA85EF29E0C3,20EB1F6A9F75249D,5E51810A76D82731,DEE25145CCC2A89B,AFC9E1E784078AD2,4715EDA1EA8D3046,E28B0989292CAA49,0000DAF0C2C394FE,66BBB3AEEC191F5A,3F577CE42DCC6BD7,F9A2555F007884B6,FEDCC3441943011B,2F4E5C339CA22480,BE711B951CAB347D,00007C7C1EAC4BE6,6C2816762D25D19A,3351AEED1B7C39B5,3C430DCB2C6FB19F,A92961C495ADBDF7,9E155A5A1F85AF92,D7905CB8D64DF350,00018F88F7BC284E,91459AA75335EBD5,F4CC867AA1DFA218,5800E16097D30B93,6A93DBCD8DB14D79,23B5BE2395DE2095,EBB445DC39824CE2,0000B12F965CFAAC,59D5D937A555132E,D4CD7AA1D3137769,FDA68F1203A60472,615480DB66A3138C,E761526C2B2C0802,D16997A470399790,0000E6C8FB813794,8B00E9A73C402414,52B5615CDB18D204,C6640AC763205E01,DBA6E3CDA161DA0B,F2C39B9AC73132BE,A6EAD438BA2513AD,00018644360FDE28,E471196316987C52,256FBA204E605154,DE545757769A68C1,79AA090DCDE27BD5,7A679F8B1CF42195,9FDF7949981D292C,000172F6FFCA138E,8E8BAA1C588456D3,B1179BEDA74CACAF,8FFEA7D98003A01B,963E4A555649F77A,A7C7603370BE579D,AF32A161E44658F2,000029AE42839E98,E04BA3A855BF3775,AE48D93CC0D78BD1,AC9FC2FCC7BB7BB1,4474A2D9648C0663,08E6BB54CA9608D4,A638A5B521CDE7D3,00015BB61EC1452D,F66A2A390432740D,24041B587EAAD54D,B2ACD7E62A729630,4645DF23E43B1A97,071A8886D23D5BDA,7DCACD2685A0CD99,000054944A5C471D,3EB591EED4C38DBD,BE896899E2FF29F0,2B9285F034386121,B80B784C644DC8C7,709D74AA163C61B8,8E93A60B109CFB3D,000143836877A9AA,FF4B4D8C06436544,67C5A91E807BB0B8,7E441C2B09E60C0C,21D4193F9D1E7CE5,FCAD5BD42BA81717,B9A06BBAA4B175F3,000161AEBC05B405,8A6D6B4C72A4474A,601E49CD19BC56A3,5F935BD26B1321DC,107A5863E0B3E610,A5BDBE085EC166C0,145AA9B6B368F30F,00009F8B2103AF4E,35FDC28021170FB3,4E40A386F9CEC5E0,E5A7B13F888BC18A,9240A82DF72AF9B3,4B78ECDE0B9C64BD,C4273550D867CEDB,00022FD7BF3F36D7,D14ADFBAB0ADE782,06805D009BDF4D45,95E66FFC9C36083B,451F3597A8DB5BEE,79036FFC5D08913D,4EC5E1CED6EE5D3C,00003C9AD96FF78C,CFC620C4C77DE808,D24AA92E23C4353F,720EADA550F5CCA9,778569A2A42C8373,5EB093E2BD539330,D11EC11D95FD2BD1,000183CAB0BF1833,07AC6AEBE8E274CB,B62D8A7584D0F2BF,8B9EDC49325F89CF,E0B92650A064E221,603DAA5B3C0D4A55,8C7EA2473C230061,00021812F34FBA85,D2820EED2D214F0D,4ED249FC2FC3D5E3,0A6174CB7884AC92,A70749FA316D6DAF,882058EDA4BB840C,709B34EF639C582F,0000C5B991C8C3BF,C7C939ACD02D06EA,E4BD99D8162E82E5,618AC96883D5674C,B8C1D815DBD9E789,19F33D0F4BB492AD,FAF6D9B34140D642,0000B181923289BA,19E0408820E5020C,508FD352D19F94B7,1802203C28999415,EAC5EF34258617D9,A53E430B28003C5F,E40A87D53489C62B,0000E97E2F0D9230,689DE2D325BD90A0,82D9462CBB120F0B,B8288FCDE5A417BB,D01CD9A89D95C49B,7230D01B545E0226,A771CC006784334C,0000074B54AD065B,3676198D6C9EA7E9,58F87DFA4D614823,2DF809FFDE284D4C,B2381EDF3AD632B5,A9BA06D0DBFC62C7,56058EC51BFD727E,000010AC7B16AC66,F2AD3383A52FC68F,92D3CEEF037E820C,5CB1AD96AE45967C,DF459B66331088A9,0B64D9D41774724D,AB0D979B88C1BC29,0000B0532EF5B463,3F733ED37D37F919,C1228B9C2996F61D,FEB083478205F499,3BC4DE02434B4A5A,39CFBD2A923697F1,B19D16C5664267F5,000232F5AC98FBEF,6996A29E45B86620,D67F1DFE3CB1C4D5,2B03EB293D00E677,D4891DB30E100F65,6034B75ABC204E1D,F6D4A79997DCD11E,0000427662E4D65A,F70D1F83046A9AAC,9F0F144384273584,312A09FE9A5A81D3,76734D0D3965F1B1,A373D36001C626C5,435BC8EB18315747,0001D42D5FAED57B,68C5D308E692B551,3F1028AB40C1E7E3,0FEDB13CCB50514C,5AD9BE12FEA70FF3,DD86F592FFB26EFE,3CE47FF60E3F66AA,0000105F527B0202,978AD4596DED992A,222AC0E1A6944BB7,91A2FC1F4FEDBB5D,B30539561F08A7B3,F8DABE0E8F5D9694,DF57E3681D3563D4,00008A19AB5B20A0,8517BCAA31C78014,39E70400CFBC6236,5412BA9B4497AA51,831AFE58CAC05FD5,A6F4EB4A9C89FCB4,321A3C6D9DAA7E90,000113F019228FA0,5A96D5BC11424398,F9740DF3FDE17F26,177611017C68CB0F,D3FAB77F513213CC,2D89C8EBEB6B981E,C84E0E12F7B1C3B7,0001F409BEE37C79,A16DD045F01598BA,1B1C47A3FD7A5AEA,7EA0800342314C1F,805EDCBC4F7B379F,48077F966D0ED447,1A1B7123C6AC1F89,000202D202F47F6A,A26D12DACA81ECAF,8C42F40677D86BE1,934AFEA3E509DAFE,98672E134C4CE323,BBF354DF0A96D5DC,9192634BB41FC7F1,0001E4D253F11BA2,DBBF5472CDC573B7,D05F79C625764DCF,7BAAFFE5C376B184,6F31174697C67EF5,D415F0BE701692EB,5FC75498660A66D2,000006E4C8DA6C39,E3A41CFBE98187BD,5F3DF54D46BD71AE,7C42BF730B0E7F56,EB10E5DD280E3E23,B99A27175BE3E2E4,C13955C8075B8769,00008C1AC288D7BC,7F44A99726BCE788,F16016A706E11CB7,71543F576565BA9B,13FF661C5E248E7C,28B8CB5A7845F0C8,599280A3236C95AD,0001834B6DB5CA8C,92CE6C03263E1AF1,0B793B45B20B635A,5768FFE68A242EB0,2E8F6437BB7FE37E,E498D0C4FA9B873E,71637DDF47B5F7AF,000155A84114E7B0,CB3D700C2C70B529,D909FA6BA5A2EBD8,D70BFB4B44B1809F,CD545EF71F01C1AC,C5453DB2E14FF047,77D2DE789C1C35D8,0001692BB2BCEB2A,A8C0D3FBE5286C63,AD995CA0750F828E,6F04FFC73F09627C,8106DC516BA7D8B1,925A19FABE5E7D21,473680B57169ACFD,0001DD4BF88D4F61,00C747FD91B58C38,1D90763306470357,690DBD5825238C87,A66EC28FD37B2260,1C594102CD0594B1,E19197ECB40A500B,00018D5F7C345BA0,322169D04839E559,E08EC42965C08575,3C541D90AAFA89BA,B489CD09421D79DE,D487813FDB8B10D5,7B99C718ED1A60FB,0000A391607BD417,46B01FE0C12C4439,D68CB66F23BC6052,62DE66ACE0DBF298,9034E2D0B1639E92,78D57510EE99AFCE,041FF377E391394D,0000AD5569D73086,074E5C68FF8D409C,A85A44A437338BC9,C11205338858DBDB,4705292DA0B7AA1E,1056B9429E7D21C3,3107824D7AE9182F,0001BCF327FD1D24,CBD743117FBA3BA7,7F1275F62774FCFC,D799CAA05AA7EDD3,611636E61E49D45F,791AED983672965A,AEC985C7D8EB2C76,0001FE9D5D7F33C6,9ECBF2ACEF9D53AF,92F2A50B87DE7B28,981DF92CDB1DA2BD,7340CA5CC1C95A8B,F7A3402469AB2476,DAC83BC2A720424E,000140F93F5F7C8F,CEF9534E595D5924,D4280A97A21CD844,BE4BA8AE7442B8CF,35784AFB46A3F8F2,BA491E8A2D1FB157,FAE4727EC8DAB1C6,00012AB84182712B,D940008B60A7B5D1,8E66F87650CA8B07,F177480A4AC38AB4,15A777FDC1F34ADD,3437FF7C45114797,448EF6B10949A227,0000AC98EF724C0F,2335A28843BB0C8C,C70FA0D8F35C726A,D318CAB7099B3171,D4A8C264021CC7AC,FFF84BBAAEA931BF,1D6CA1FE80C3EE41,0001F61BEE9B9D3B,CA6FC2C9276E6718,2533F9B4F77F856F,53B0F548E4DE514F,2B0F3EF23DEBEFDC,782019AC1CF09276,840A03434FDB1367,00007F54FF35A5FE,4429EAA13608ED6C,9D813919C2CFB8B9,E61BEC5E900E1554,9CAF2AFB92512C07,D3D006E56F8F5A56,94F86B135AC9AACE,0000101B8CAC6313,9BA66377710EC368,51F467ED9D218A89,B748489D9EB1D88A,BB2CF0397FC1C669,7CA05263C36C8E22,B253D89ECB207719,00004B9FA67F9002,5B67A00BCA672788,AD9DA18A9ED20D4F,E6A035AFCB5E6F41,97FE873DDCC9DCBF,E31F3EDD1E238225,5FCCE7D3F41B4DD6,000162C82BA5FB24,D1317F2479FA3F7F,BBC4F7A03D572A6D,DD334B07F5A1590D,352987AB2EBBAD8C,690BC7235FF00978,297655F890C05E1C,00003E7DBCC10A98,07952158FA4ABC4D,E651DE057D882E42,31645885A010B122,18C0AD07F7AF84ED,5598F85A8AF5A79F,7FA6A9ED2F7B67E6,00003B385C69B9B9,22792FF02465707C,AAA24A5CCA38773B,4EED2F07DF1BEBEE,AA29EFC0680222C1,45D3E8A4CAB935EC,749AE2F6D69D5DD9,00001976700A8DA2,C4ED848B79F74FD6,C50843D1D5BC73CE,8906D6BC82629C06,A49992374B8CB022,5B7B2B372A5E2C08,BF3C71A4BD7D5204,0000FD220BEA7675,4247CF39651D1F12,C9B1EB5AE6B49D77,3A89ED8F4911DF70,F6FEDB82E4A49933,93F61F7DAA71DFC7,E5FDB11C5E28E92F,000151FF50433B17,780986658F546AF7,AC27E5B89E641E82,D5F718C4D22B3B61,CF55EF2F46804FBD,4161753260E0AFAC,0CBBA21419F318D8,00007D15494B896E,3F8493E7A8F2E8E2,5CEA906E421BC420,9C579F75B48DAFA5,8760E85249544C26,D23F02B127322F39,7CA6685B2FE74A3E,0000EE302FD78DA0,C8CFD2B6DD5AB2C9,CD73DC2BD85EC68D,F77296B8567E16A2,ABBA143B17B366EF,8AA949A354A36740,55BCC2785783E1E5,0000621B4E85156A,69B0EA552F7A490B,8F6F92D627E7A83C,9773A9D7AC893212,E79D9369EEACCFA1,FADAC84F31D562E1,EE15E2A22B3AEC5E,0000D84479DD30F8,B2483AD51EAF1DF6,74D0ADACD7F65791,CBD4DD5C8B9A5638,F9B74BCFAF318B66,EB1A7BD7103047B5,FB8B2C26EB526468,000109A878151FBE,D5F8930669741E27,D42996CA09054D80,9EFA220F69426557,58413140F716ED1F,F7FD166E629E8B14,372BB27ADECD9FAF,0000696FBB68C776,2DB515030C3277DB,AF9305AE3D126152,1205F01198376E96,D5594B3F86F6404A,7618F977A5923244,40F4B1D315D06EAA,00000A7D77F5FBF9,4BF7334FD26020A1,6835153D9B52AB89,F14F41B2C8F47F34,03B63E8B8416AB58,53C8D42042DF1C72,50B0176CF3551B9E,0001F6C97A0F8CED,044E7170BE981A33,EDB0B5DE43615BFB,0B5BD82049CBCE3F,E5E3F3B2F5DC2456,59F2A0F85621618D,4CF956AF71E16905,000230C5334E2205,FAED045AA7A91A18,98F038035F5FD5C4,59DA72477DD61AB6,711CE8D75E5F57D1,31B98573CE21ECCA,54D18BD9EBB00491,0000F704A10205CA,DF3E4441C7BBD91E,AA427987A3C792AB,2981789041E39A63,ABAE04114188C79B,BB48FCB317A706A8,57AE6CBEA8A98E21,000045AA45F4C2B2,6E9329AE6A18E91A,B82A6D227C16B8E1,A5C3DDD3C394500C,BE5254564619BD76,0FCDBDC7B060EB03,FAAC80075286A1FE,00007B880066AF7C,682E25F0690F9ECE,FAAB97BD78648CD9,DAF232DA79F448BC,BC9CFF3C12FE75F3,97239B34E3C1386F,F7F4AF4FEB6D9633,0001C6343CAE0CB7,2BD0432CE6C07663,4AEDE5B2621F2B28,A5EA203D3EAEE18D,C670B44E970256BD,251A66A4958CC3E5,BB028203BC60F71A,0001998924BFFD8E,D25BF0C1E545EE92,7D3B8DB6FDCC1F3B,0068A46FC7F4834F,17CABBF9647E2908,1852EB038B34A6BC,CFB2DC089689E4F1,0001C3C2309B23C0,5919AF22BBDB60BF,30785305EAD1A9A4,56FE98DAFDF4B974,F779B82352EE7393,AB3C32D5A8E1FC62,833E6D3B7BADEBD8,0000DEE17FA81851,9850295AAFECF554,B42A40D63FAE01B5,5F0A866010FC00A3,9B714F12E6AC3C2B,ABD959078C77AA75,722DC6351D15EF1A,00015FAEF15F485A,C0F8B1E9D27D5F44,E2407DFB93FA9500,DB4E11245994F204,708AA2C6C4509AC7,89E62248CFB5BDB2,DAD9780F8C8BE912,0001B0DC22F57F80,4CF5EC00622DDD4C,1368F34E37A46943,CE832E7E47C5ED70,B06A53BDE05B30BC,258349F3D0836501,39DA7CE0229638FE,0000D59EDEA62322,DB940C74C6D185CE,AA0F38610C1BA650,F8A851294622A505,E42195BF1539F7B8,D2B84E9AE4825504,A3BE324F1EE22472,000229B099A97468,383D60ABB6B4764A,2F3773BF67CC51B7,79D231B65A3F4291,F131FDEF09803AEA,122FCA1BBA2F3541,B59E1E2DE70D7FC4,00007DC5C4FD9CD8,F74EB1A87B3986FE,72EA78AF21313414,2D1B614D7EF4CD44,E7C306C10555B9ED,589223CCB267A1DB,624E22F421EF20CA,00007436C499F199,635FA45713CC9146,8690AE1DF2BC66AC,596A298A6C3171EF,6F1B60D2D8E52100,D464C1B44FAEFD87,A13E2FBF7D88DBF9,0000C070B5E5F2F0,871AC5E3E2CEC727,F883050E5618CDEF,C34CE77987193D28,C72258569B80A9B7,879C1340E51BACD7,93EFACCFB1CD79A0,000139FFADFBE3D9,82DA4A89F7D5B908,7375C55FC1531025,19656AE4BBAE5B08,3F2ADDB299A56F63,A7E49EDBBACF215F,654AAACDB7146887,00020AC88FC283E3,C85DA8FE176D305E,77CB6D84DF0BFF3F,C4011ADEE8175A08,E9AA3A36810E5D4D,7EA23F0714752048,CFAEA8FBADC805A4,0000EEE88C8B04C3,04253B0E89882750,18B52DAB37DDCA7C,73138C99629DD117,34166A5C01FEB3D8,66377950B22A2872,325E011BB4D01C71,000127EA378FC78E,AA6977B5B9EA730E,65304D375FD8D7AE,807191B726873FB9,8B12F68C809247A6,F03DDC4833F2BE30,E527F7615178EBD1,00021E622C1D6090,55A7129ADA77F149,FC6F99A7AE0BB0E9,B3AE905BD0BD6C2E,6ED5F6BC5340B4F4,0E919EF90D9D95DA,3E9B26FC4F615436,0001B76368C5B612,3630A7D1AC02F244,6610C6DAC5431669,9A640D8B5E5B048D,40202A4FD5D78B00,F1E7DE7C0013DC0A,8140AAE3EFADC4EF,0000ADC5A1215342,54445960FF5AAB75,48EB7212BE9CA9E2,B3735DE56593D725,B9DB0678FAFA6DE7,AABDB1564F6CEE7B,F3DBC01AE07A9FC5,0001DAF2C3A89724,E86D050B50BC6955,08673D6B5A882E00,751EBE97359B7F35,D83437A5CD119339,52A581A3B86CF2A5,29F4D58CD410F170,000049AAA15D26AF,2D60E27C2DF331D5,395E70DD664A32BD,18FEB032C47D1256,8A9A077D966A66BB,A29AF608B2FB02F0,8FF8DB51B7F5CA18,00004CDE342ED549,952FFD5C832669EF,CF774D8D4DD033F0,B9671CE50468DCA2,AE16FA72FE3CD08B,4DD9F593067ABCDD,46BD5905098C810F,00007D455308F204,76D3F219E6169BC2,F71CB88D26350C66,C8BA0C039EBC659F,735985E8CA00D290,E37D9DA2EA561A43,1353EB2145264630,0001B463BF18521E,F064725EED9A7087,40B438DA6051DB29,13D2491FBE3330B6,8E52BA1398C2D695,37FC499F4ADB4C8E,248FF72F27749CA3,00014E0D62EDD309,0063BE3A412B5D12,601BB9545DA86433,0D5307F699D6453F,8F97813A4D4E5564,88D4B75390B174D3,6F2564C2063A89FA,00008A821FA61FD1,683B632153C6C3A7,E8F0ABA49115275F,595BD1419E2A49C3,9719D2E6DC959FF3,CB4A3748D3A99745,82BDF0347CEFA65B,00017A4AA693DB19,BF04C478FA4D76B0,7BFE551C27F4BAE5,3047865050BA8C21,3CDF6868389D486C,58E83263E14B7F12,7A7B95564DAEEBC4,0000A8E065838B98,EB8BFA92F6C564A4,7DB0032AB4B8AF13,EF59463AB5E388DB,6AFBC48DBF953258,0A8A5312137F9E3F,491F7957B54F5F9D,00009410C6FC5BFC,F7CB1062873FA5C5,17A17DEEF45B0A2A,4B42CE552FA07F5C,223BAC106B69F336,15B1DA0EBD185DEB,EB18832D0B385D98,0000F084DE286BF3,A52AEFA2A801D8A9,D2258FC27C31253A,A91977CD27AB51BB,15C9577E67FA623C,6F8561270F3A108F,B1F40B21BFB57BD0,0001C923394909A9,DE6D1170F68D1753,62DB796FF24E5A84,860500D0FE2C57D5,371435874B5E5FC2,640E5835580DBDB3,EC8EAE76E0F1D9AC,000141275DB3F6A2,20D47A2CF5B59F6F,7513D8ED9F485F51,B2B71D681339714B,4BF615D642C1D7A9,E55C671DAFF0D0DC,F3D46F1E942F63E1,000111936874693B,7A1FEADE41F4FBC8,1F307B96304A40D0,2C7026C9BB216EC5,18ED4521AB8ADE09,599906A1E8B64EC4,4430B68075753ABD,00013FF2B73D7A96,E81CAC44BE18B72F,51B7B65FD2A4D846,C0294A617AD87EA5,0F6D5ADCD8A996E7,2C4E13821EAD2A59,5325F984382063F7,00014DB8660B0167,8D1D825A5D3D866D,D2520326848CBEEA,555DFFD75ED4FD37,498ED1700DBDB0B8,DC06E2B0B57D1B06,BEBB224B2FB975BD,0000C0A4DD8A8558,66FBE984C2C6A161,7A91B3C3BD398A65,A96925CA957813A4,1D8E769298672893,C10CE8BF1C5AE52A,4A8A990D7BDDB92D,0000063CAB50A4B7,277486519BFDFE8A,093E0A713168F865,212D6E1484C77E5A,233750831FBDB32E,2A74B93344E0D76F,D46B4D5755FB0AA6,000002D1133C6821,FD017B4D00351139,0EACDA4F8CC8ACBF,D63A289F25A0773C,8271C326A55E364E,9AED312DCACF4139,B5688D216CD952D0,000211178C25787A,D9405E8880A2EB44,5340BB31ECAC975E,232E8A3FF61D73DE,FC41EE2EDAA7E8C8,27E28EA70E0B2693,A3A66E5E34D5E070,0000242BB806D8C5,C10145F777952D2F,6252F7597346B7D0,BDD64769F9DFA224,FA8417231FAAF7FE,DF451C82C47F5880,A257E74C58F4593F,0000E1D34D3036BE,1B9EDF9B892F7C54,0F1A289967B629D8,D452191BF073252C,B6D66863DB9174D6,0627FE69E99E4325,FCC7292E25027917,00007EC08A5F5DD2,8E32F5695FE42B61,80DBD0476DB4EF87,4DF9C3C88D2E2733,34F414C97BE3BD3D,352DD8818639CE25,9D7FCB8A30F5B895,0000557BEE28E965,24479ECBF919CCD6,E2E55513494ACC07,D72072FD8D482E26,05CB0250720DF1E1,0488A1B9AEB6D667,E3161FB69EC12D84,00022C50D305EE3C,9ED4BF50183A09A2,84A5AC08551E2BCF,D8D46452EF15EB4A,804CE86BA79D2680,8094D37367A4F659,065E4032164A92AC,0000E3FCF2D5DC89,998C4416B4CDCE74,CC8C7FB1A5BCE072,DD02D529159FC3CF,79243D97CBF3ED6A,5CADDF2C4C48687D,CE54ADA1651E9366,0001702343B19A40,7D0260E0AE11DDA3,2C06C997E59B4134,D194E028CDAF04BF,484F5114D18506A8,65452147F4C9581F,0CCBC443EE98BB3D,000206A41B99E1D0,A081D9C4B259BB0A,05C6F1B2BC71245A,58EFC61BAF0859AD,F2526D1F3500137A,810B8EA3FAE12D72,0E06A58A8EFD7DEC,0001001CEC9BA0B8,23E93E6C953DAC43,F3F5CC11B613293F,5334FC18BD66A4F3,A369ECCD9FD66A3D,74983EBD662EFB15,9C0E854B8ED52E65,0000AA55672DB2AC,6D17DD0E36C635FA,03582CAA1E084AD9,9A29D65A79D6F70F,B64931C36A77496B,C506A54438B6DF93,402F3A2C67F0357A,00014BE8B121E809,015B5777D80CF875,B430AB3B8E06CCB4,A30C7D371DF6ADC6,6B2190987A27B152,3C2C8AD91459EAF5,858B9477782AE2DB,00011DEB0CA281C0,522E2D51AE951DCE,8B56D118B43F419F,3E37D7E9BB1AD1EB,E72D693CA698F2EF,72CEC13AD33E6535,58688A7B67245523,0000847C33634AE1,0364000D4D4E7001,D1468C7A0336B225,269119303C8EDD45,E03096075F011BDF,89D78CA210D38B4A,A4640CC54DD85CE9,0002232C24CE7099,2E148A6893A3377F,85FF66B19FC30926,DF8D30EA233AC9E7,8B68A0FFD9003CE4,84CC5854D5F81C7E,5EE273D8F3FC1D99,00022818E157686F,E5DB26D183ECB3C8,9B25BC9377F48B19,F55C46ADF5B9DD58,2F384E23EF962CBB,D952CC9D9BC6EAF2,01DEA899A669AE29,000128E597E73A7F,EAEC517F34486095,91E31162693384E7,AFB4C7CC9E5E75BC,7E3BD8A4C5D8CB91,73384C6B61630C4F,73A490C2A240C6E3,00018C23A7BF5A7C,520D5763C4B18AB9,5649F3C4F58B22E9,726ED35C14619AEA,75858C5604802933,8EBEF6FC8514DABA,EAF0AF812C7C7E0E,000030C97406B409,04515E53B1C86875,B99D8ED4395F553A,F8C1D45FD5BBCB32,72B5B3D162B8FF33,97EF897AE189AEBA,E1B3AC57274F04E4,00006E373EED4E4C,E9C4A032EF0EEDC6,2F8556A4BA269A66,2DC1202BE73ED028,B1AB548ACC01BC2A,6B9C9E0CDBA03C06,1D41F3016B3C6A94,0000925C716F4096,A3D3C6887C4D3B50,82DD63EC6F8D6AD6,9C1030E36EC27891,82DE48DA284A6971,953D436E92D0B90E,70B48A25662DD99B,0000FE24850202D1,D41FF4ED3E1F980A,0E662593FABE819A,F1B6B51E0D789697,1B455D09AA448D2B,A5D2BC8F31F67E32,26256100CEF5A41B,00001E7A5FCF5879,5031776B1B9293C6,BA3E795A1148165D,59C1817B3D973F97,7A1E125549AA30AE,D01F3948B68BBA88,E180D22877250A09,0001FD0E6793538E,A45E7CF4ABAA2CFA,F7B9D6BD82D103E3,DCC36B28CC5AA224,5D7F4B012A8AAB1B,1952D93262BAB62E,0362604A672DF189,00021FA318616606,BEB656B25DCA9C22,6545BEC3CA212DE6,669BA147AD23BD88,475FE8FDA073DFC1,7BB8001812419FB6,6F86C73105A770AB,00006B94DB6FB92A,08526A1A1092AD16,EA491C6522B8EF68,30FAA7E486EDB08E,4B5D2FA02254BA40,3CD74AE0A1867200,7821567E58968EFD,000031265A358695,E4F6028AFDE0CF14,22A334DD59B0FA21,855D1C7987AFA5AB,D4FAFAEB81AED276,9DA77E66B3C9FC9C,8D75D654240D941C,00015253D8AAE0B9,34CA14BE825B9889,4DA052355D87540A,D38990A96DBFB0A7,E307BC0474701C33,82D14C0AACED3AC8,3BE4238B937ABE5B,00006283016EFA74,66CD22B5AEB13846,2ADD1658BBF4022C,0473D392F7D88583,183E57002020EF05,4996D20FB031BAB7,DE5B1733D945F430,0000C3767432F1E8,6C6FE341ECA81B95,FF8D1C8E58CD70E3,D745E2289AE73B3F,3D1AA99D220FC798,F751DCBEC73C4B5A,3D23402D90770566,00019480E46DA256,9DB40B6E6D676311,864C569011F224B6,AD6D4E9DD1E2573E,344CD73B3327C72B,BAA477B6394CFCCF,B3E8A98255C473B6,00014B4185A0A4E6,D0A89978C493AB56,66E788CAC51D7635,0DB551D179D7AB76,DCCEA0E8314CF5DD,DAF9C9A6434D0D4D,345C3BD317ED429B,0001006B8A3B38B3,23CAB87569C4A7DE,DD464417E560E457,E8DFA358CD1182F7,E741B0EE9AEB2656,EF71EADFF7C71672,987902CAA437C6A1,0001B930088EF38C,C19B46143828341D,BCA58ABE9B58034D,3CAFE3696387BF25,FBDFF875824E3E96,8FB4FCB050CC464E,5EC3AF169BF60EFE,000054B0A710E1D4,8791C5B6AA3938B7,C134A67484228077,462482CBD489D474,E732CC166A44B4F6,F00272A42EAFCA06,99E535FA723F4F96,00000A7CF67C7132,39280D345C13D4B9,BE5A85978FE52EA5,2A890212980070F3,94B859385073B111,C53D2936B5A6A5EA,2A7935A75668DA96,00016B77798A40CF,8B6D71CC9AB823C6,171AEB39ECAF1773,972DAE6D76B2B3E4,DEC21A33DA07E101,7D102C3551D153FF,3F1E19F96E77AD46,000081E348E4D5B0,86FF926A6FFE038E,39F5BF79CAA4BA03,607AE5BE3C94FB4D,4920F6AB3CBCFD6D,8AD06F08246B6512,AC96FEF1F41E5AF3,00006367183B8884,66B2D71D412B8B90,75FB9B35A96FF364,4A41E7D803C1EA70,B442FDA50F47464A,095CB655B74F4EFC,E2762804A48B199C,0000AE8FB19F08BA,BBBC57318C40EE38,3B2F9ABA67F1715E,3350110AF668FEB9,CF66D80E08FEF3C0,6F75CE363116C8BD,A4EE479618C88353,00002B4A5ED89A7C,C2115D6DD296CED6,AEAC2F46CDA54B3A,EBA88C89DAC25DDA,9F369123723F8A15,A1E020038D255BE5,12C286378DDCA7E6,00013D60C41402BA,84F486AD6C0C821A,94BE225ED8C87391,A6461171A40E6CD9,6983336F2DFBB172,29135F9AF8180BBF,31AAB42A9012EDE0,000091535C067EE0,CF366D9687191537,DA2F3C118F50411D,8A8EB896B37DFB35,CE26075F12F63CEB,667128E4E6924100,8D6C7CDEB8BBE655,00007284D6C47B42,FE31E7B144FACB0D,51C05D4E0F9FA631,D475499851D677C6,75C4A8A6DCA30D75,777936E42C24FE01,7F7AF5EBF7B1D377,0001C0A58C1969D6,B7484DC040DA8F83,B75ACFE34B3A7AA8,1956332485AE28B0,2B99A37A425E6421,E1DC5F9CF8F7044E,74C79C44E6E159BE,000018C9681AB49E,5225BD883BED7D2D,20C2679D07DE313D,835E350129CEB477,297F2045416B3A55,29A316EF622C7E02,8641CBC3FE6C344B,000077761E14B923,A651B079193847EC,23B25278AB30EAD3,BCBB1DB498AD6C46,BC3745046F374A31,22DAF18E411CD83D,3F85D330369B32B9,0001505F17631AB8,FD7B718ECE04AB47,052386C463A1FA49,3D2216726C6110E8,0320B26E3B6B03D7,7A797C0273085473,8CB4061AEAD848CD,0000E90FEBA7D12F,46B47C318ECDC97D,D322DD012F880529,D46B51F5A2D2AA87,2F7AE7F1A319B8B1,3876D3E943F00B2B,C0FEE2A49AAC0C16,00018D8E6CC1C0DC,E5D4FB78856DC1FB,5206264F7F524A20,2D6F72D23CCBEE76,FC79BBFDC870FF48,B5149C68BE78D6AC,277A951D716BA172,0000EEF78C6477D5,FD7C1004DF5E48D1,1E23DAD127BB0502,71346BC587CADD07,22C67404DEA995C4,873A517E769EC5BB,4C171F67DCDD078C,00019147DC1C1227,27A80083D14317E1,240A41A7E1BD2A37,79D1FCD075407399,714CAB4801C29F6C,C7A6D14174FF641D,7D9EC7F8FA86048A,000140527E30E434,A76B8CA804FAC010,B8C79ABE37CC7560,12504797490065A7,6C925098719F22B8,14A4CB612968B59E,D5DD65E053033B9C,0001900A426225E3,CCA9FC9D8E0C0DB9,C93E6DC98FBACD81,6225EEE44BD00F33,46328F3266D906EF,50C78CAF24E42316,58F20D684C36DB12,000105DE98D22064,4180170BF187DFD1,3D20F7A2E5731F0C,2B29B79096A9A245,442A49AC773CBC4F,8C9CF9859B34BF82,501AFEA57BADEA05,0000129D4ACA0106,178F98476D8AB26A,9DC62E679AA869E3,DECD81B5A2FF4287,8DD6832E6B6EF36C,8533453283620828,6A84A82FC6B3D1B5,000197BAD1C5D477,F1E82AFFC4C50508,AE354D7BD7DC6933,2A8DE17C679540CF,8E26B095C6D8A9DE,8D0A113A7A6F427E,D8CD72938C04510D,0000A64A81231004,07432DC877C25109,E0CC7C5A034FB449,E4367FF97286C8C1,0025FDE79DF2E100,62FA18932EFEBDC2,BAE28B811516F4EB,00013C7EF76D7BE8,C7275B149DD1A5FE,6B24F1CC50DF7972,E286B78322F22C81,9946C35A7168E865,EE8E4BC759E7873F,8A64BEFB0A7F9A20,0001CB18AA039C25,6D28336C58F73E30,725B50C04460EDC5,5CF888D713FCC1ED,2E54BE3E35D2DB2C,494295D0E946CFB8,7210AB8A084C7982,000042FD9B30D5F6,C09DFD096ECD7E8A,43597BF397F85CE4,1F3257EEF2E21E01,EB5B80C76CFFAF95,EA381C7104064E67,C184A403A5E61FD7,000060186EC4DDE5,954F21E01BF9998D,5F8814C46D5A94D2,C3657DE3C0ACD7D3,FDD94C076A58312A,79BC2684753DBDEB,11E51A878D1223BE,0002066798641AEE,AAC0A24B40C3F4E1,5E2C91F223972BA9,398D99D44BD2529D,5F741BFC3676D886,A232F12DD967CA41,91D8DF7B73C02EC0,00005A7384A12DBE,EF281AFB4A39CBFE,4A981793D090C953,38C48EC5F72F47F6,3913D4E8DF5F3B47,99BBFCD1ECD2F722,6B1BE4AF21A60A80,00009D12C5CC4145,EDA5D34BD1AAE0DA,AA56DE87CB3C6ECB,44D78A51DD85F9AC,807A46E94372867B,B81452500ACA79AC,9B390708D4F3BBBB,00021366D30116E5,64184C2240999BBF,4565AB187EA5B623,FE53D23A14B3DC65,69C462B66449CB92,B55F63716A7F4B66,AA313D1E702C47FA,00020B4B0C6D5E06,505B06E0F48374F3,6074667B9B283405,7719C8419E6EF341,61B9742BD7042596,A47F6A4AE0883F71,EC213D98DE13DF22,00011A989DF3D244,AC66F85AE7158131,1751DC219609C485,9815D2EDC39B7041,EA4CA2F167EA9429,AD283327405B8787,9DFB28B3D05297AB,000193D00B345EDA,35BD17F4BA5A4BA7,70E977AFB4C9F0FF,7BE7200057B27F5C,F8A2AE784251FA74,F9F05C1A3CD11318,EFC59D8DA48A5E3C,00005111E582F972,BCBC2549EC68FCDE,823DC23B9928FAAE,CA67DFB037298E6F,AC70AF2E2F59CB0F,F303D3F9FEA1DE0F,1FEF6966CEC1C6D8,0000A45351E4C3BB,28213AEDB766D70A,BC56B59ECADB8DB6,345EAD5E9CB094E0,701D53B4419D8B16,726F4BA122BDB4F2,7F6277F789489550,000147F55DD5F077,B5DABB19882D1CA6,D0653EBBA634DE3A,680D1248F27389DD,DB6C05E99BFA018E,BF3F75DB70F8995F,95C9F02E20BAE066,00011D27A38FAC46,9068144FAC93B614,6D1DD96E8210110A,1062BA34C040EB33,ADDDC5FAD8EC3AF7,C40E23557263EDDE,7D3D921FA93F38F7,0001CBDDCDFD9568,FB0B041651094E3A,B95E746D698367C9,CCD8C9E511672B3D,6DAF7DD38741973B,EDA96C3D57AC590D,42CD602A9DF63B5E,0001273C95C0B467,CBB68BABE871D287,34169DEEA7B7E71E,958E889C3212FCE5,C7ECE44F146520BA,5B30C9E65DC31CC8,9A789A950510C3DF,0001B0BCC1343BC0,8DC76D5585B4468F,B1D1CAEC523E4056,90108679BA558D28,ADBD10025EBEFCA9,4824559AF61592C7,19E7BD08BBA1E056,00006E4E5425EC76,E5780B696D0047BC,7F2326E9BDDDF8A7,9603717332134044,07D4EBBB5D346896,532D2176AE4DC1D5,44A1882B27F3F864,0001884B6C3617F0,6869618B986AB9E3,6AF03C28713E04B4,34E132B80B8B3F37,303E4DBD03F8A262,F1AC57DB3B80D94B,0A1593F83270A71F,000020FD628C05C6,9A89E43CA0689CBD,640233F6E9D471D2,2173B938FAF79BA9,7AEBB22E721876A5,B504AB80EB2ECAB9,AA02AC5DE27F18DD,0000A092B9F8841E,8914B44FA242FD87,A305924D88CCA294,39D5C0CCD696D33F,FDF020F1EDAEFB71,464A508097E3D6AC,3D9B72CD97694F22,00017FA978604D14,AAD89605EF6DAF0C,FF9BE7486AF576A4,49C7767ECD4B434F,AB32040DAD7C4CF1,1080A5244019ACAE,E49CF12D166A85BD,000036E406F47997,F86E6720378A8D76,B6C618C98EB2D0FD,595B15ECFDE582CD,9FCA16F68D4BBEAC,205478615AEB07E8,E59A63B3A2976B2E,0002270C4E8162E3,07FB67BAE054FCDA,D0760527AB909AE7,9102FD59C83A6623,FE8E6CE603F8A9EB,2C33A5D9863F6C40,924DD334D9E84CC7,0000B245B8D01AE0,AA53791584D728A6,CDF4EFD7CAA0FEB5,E8A8CE859D2A8BC1,CCD75E9B50B9ECAF,2795BCE93EF7A2A0,FDC933DC920D00A6,000139649A3F2F16,23976930DF0492DF,7212140DAFAF2E04,DF00140D54E2F3B4,69C129B57C8FF828,F6D747AEC2296BE8,9E29B46DB988FA8E,00006DEBE8C3D340,D3CB76800E25D461,162298699ADE5D6D,A6D9603BCD217A46,284E370F81BB51C9,5D059DCA27177796,0B0D013EC70CF92A,00014A875791DC1D,46AF50ED4241771B,D86E0239DBC02426,42829678B9424ECD,B063D73874D7BEF4,8D3A6DD88F76CE4C,E70EBD0B8BF92771,0000535B4421407F,4C1281082A366ADD,3C34A9F83DD489C7,85D957A854606CE1,595663BB5FA0291D,81FFCBFB907427A5,50851421B9C6A1E7,00005667AA50F0A5,500A55AB054C1891,2175302348E2854D,FB3756DD9770184C,74E416B857D53D33,D7FED4D83D845CE9,AB394F2E13D3AFB2,0001E016B121CF38,8CCBA32940728311,1A3267B6810A3280,E9E4CD9D0EDC9F8E,536F22D5F05B9D22,1B482BE79EAC3837,4108189BA9A1A52E,00011405EA3C013B,32C14C775D1D7F17,3A0F1AA1FCF4F7CB,F2018CF4B9AA522E,12AE8F660B59E7A8,A5625F52494198B9,3D362EAE0E84B0A3,00016C708BEF4B2C,06F0AD69D242E212,9165D0186665A5AF,9D3538FCBFD479B0,17C924EC609C82D1,D48C7937407F3B8B,BD041F9AAF1016E1,00002AF4A06F96CC,F5B77F2B8195AB19,123757CFF7E1E8CE,D63CB3A7CE3AA60B,899536E72DEF38D1,433C8B233FEA7FC9,48B4F7176794AB2F,00010971C9E957CC,B41F3B1D4A1D93C2,868B03C56348689C,0640EB189E020E0D,99ACFCA66B41985F,0B34CE6DE2A08D9A,AC558D3667A632D3,000034B40C82106A,FB6F2A72FCBE5959,AF320D1E294C5937,A25480638757B201,FFF60C9B283FEA81,FFDA6F6DA1980364,8EE8352D9527B4FB,000062C13AFBF9C0,B8C8A6098B2DE393,83F2CED7AB8E0CD6,6BBD0280A51F217D,54301B4940B4A922,E9F191EC15E11A5E,653C7B0B0CFFCFE9,0000FD29D443089E,B9D79BE5D9AFF3A1,25B9251C88EB326D,83FAFD08B9F46F7E,EFF73AAC816458D7,C5FE567323AB9CBB,E9D215BBF220F7DE,000119C19DD2A164,7BE48B8B2A004A55,769A26A3FA3AF6A2,DB4DE9C7A1229B78,8C8E28593579581D,B06837AD5EA3B976,9B6B75024B1C0D5C,00004D2777704721,59EE194CE5CF8A3B,6F845AA691287777,E545DA2729ECACD8,8375AAC90E8908E3,26E452139449CC5D,E9529FD58435A664,000159848F135BCB,7DB7CAA86B756FA9,E80E08AB7EFCDDAA,50B3774962C96339,953DB3965B3341A2,2D3C3F3B6A7657E9,A55E602F8C3C227C,0000B5D218DF3DBA,9B95E5058891CB51,CEB2394819878E9F,9F99C0BB63981570,3138DCE48938AC67,9FB0B27DB7CB1F7D,565685F888D52E75,0001CB224DEB0BA5,33CDA9A15A4632B8,51E771FB02BFD0B2,D57CAD02A947994F,B9047EEF3470430A,12B6DB69C544FA87,5CAEBD388562E302,0002271B6607BD9A,E4D60D23944C84BE,F5C54A183138D642,5AAE7624775DA793,8B36666716372609,DD43BFFA76CDACBF,CCC2F8DCBB3FB105,0001CD44A2EE827D,4CF7EBE4E9EA3DE3,6A050C60C5657BD5,632920B8D3BDE5A1,F4FDEFE3DBF59A0B,13C715641257C5A4,B7C2EFA8380250A6,000231FA490721A1,01FF96CECC1BCD6C,152A42098844B1CA,D7AA606C69533617,E6045ACD5018F279,CC04674F36E84247,77CD66AA9C6E7E6C,0000D4A16915EC7D,1929F14CE050A996,CD9B591CBCDE3644,C13075B43DB9D607,75FC99DFBB0CF922,B44F9AE8B8B479C3,84B5B8D5B857CCBC,0001C643F2505049,7374681C9FAABAFA,2ABFA15FB82B854A,E084FBACE5D54483,9B88C3D7E7E634F8,1904E2F29A7AC1FC,7CB89FBC66BCE333,00017699E62D31CA,E560358D51AA99A5,5FF39E30255C4DD7,FA9CF4CFC4B60F4B,9212D22E6F17C6F0,8D72E2C99DB0E6EE,21ED79954BCDD788,0000F90C6B97F33B,EF21E425DF5A59C0,A655B17D41F13DBC,29347808D5862E6B,4F427EEDD7CDC84E,8E4F4510984E9361,2A3A9E046C3336D8,0000E903F930ACB5,785BADBDDEBE2C63,C93EBF8FF9CFFB48,82E4BD717353896F,44E6DCD789E0C98D,ACF924307DC30C2D,C7A062AD7DC49921,0000C83FED7D9EB1,625334E81E1EAEC3,58E530990AC07825,C28A5106F4C72437,AF5CE43893912685,915686660CBE1A9D,A19A35CC6DA3062E,0001FE7117DEFB04,2730062F37218F92,FB8B7DD32A666354,E6ACA64AB9FD390B,F2876F4AC7134EAF,A81D2730A964FF18,4FA14D823DC16E89,000133DEB6AC0CE4,948BE6FD77274D8A,210600A750854B70,7AA2A56D9DFBB530,82FD6C3E866EE956,2BFC653FC1CFB9CC,6682E8ACD34E515A,00005B5FF5F4F4DB,17E8B98B9048163F,4343FA0A89CCE6A8,F92779B99B7B22A7,D63A3E1C35F210AE,7685F722683FB64A,4100249DD94CF82E,0000F2E73F768C36,B58B332CAB916F88,201122344D934319,148034C9905EC039,6E2883936216ED99,F0981D63EC7AB680,912592C2566286DA,00013A8ECAAE8640,3018179E6DE7CA53,1ABE6A61A32CC61A,1327D80FEDB7174D,9270D61C4AEB50D6,CABA1C716DE19107,984F75C458FD8777,000223AECF03E547,FDCE38DF5776A74A,F36A3A377F7761A4,57550DA64F48DDD9,FB58AE0583079826,758E9BFA748F4F9B,F4169799377EEC88,0000283FE4403AF7,13FA6DD518C2E57C,01C958342AF2332E,E94900CEBF4596CB,41357DFFA36C0443,77B1A85390754E45,3174C1456242293E,0001BBDDA2ED65F4,E370EFE3C9BAE341,9262FE52C1A3F9C7,BDCADC838A2F681D,A4F7BE580B6B6DFC,A638741A1415AA4D,DF4110D0423D487C,00018DDA57DFBADC,E9BAF3DD27456D2A,0A7C5B99D240B1CF,1A78CF6E54CF5D95,A11CC6AB86A19F0D,DACCE7B152877055,6B595311E89A170C,000060FDB8A988BD,8686ED997CD1DA19,5FBB786764D3C29E,63479A2A942829F1,D72BFE4181B771A0,11D9E45A3CE5A2BB,8EDE34CC3B8644E3,00016A2319FEF3DA,54DBC7860169D1AC,9D06546CC79782BA,111A7B21AFD7802B,54164B1B88E13F4A,00E351B8DE675C35,8525FFD6BD6BDC9E,0001B4E63EBF811B,901030CD5BCE363E,BBA0CC9C88FDA9D7,852756730F9DDC75,52DEC1D63C482424,3248E1B719F2923B,1B9B6C13CEECB776,00002C5B2998F024,7459BD7BB172F50E,0E6C94D8367A1543,9D735221343C331F,25EAA4E2E3265D64,BD97AD262D650F40,882A50EDE7A47237,0000E82B2DB80C28,8D5ECAD5F0CB875F,8D378B4F8A83785C,0963701055C701E6,669E3D346EA6F7FA,E8B20EC1716591B3,21FBDC5A0409649D,0001321E4ECA0CF8,952B76180D98F4E3,EB2CE804640A0DF9,29023A1E2BBD1E0E,E8D62DA7B41DED14,A5005901DD91E7D4,B374E36707711661,0001DFBAB9CF2247,482342E3BC9BE557,63B5942D7B81B4A9,BEC0173690C2E281,43B178DBDCFB7C61,A3EAD90600551D42,05084ECADC636CFE,0001A9D2E844D7EA,0664C83B31850E1E,74535ECB6153CBBA,B8CC07C4AA469864,EC37F6AD48E16271,B11E8CE2F865A1A7,2C5A3A1F2E766C27,000170BEF101DF5E,15A9978F10B5F149,20E6B8E913DC56A7,E2D92AADD06AD899,65457E827E4B45F9,BEC45EE9002EECAD,42A30CFE21E10D12,00000C6EA7BCE5DE,080A2247D02D9EDD,353BF45A5A7FB676,A563551A561FF7ED,D2D635E40CFD5E28,DDE98AA30866C92B,408F81E566D14EFA,00016D0AC3E59BFF,0029F8F3C171C9EA,37CFE4AF5449E515,004B41930F877523,A6A45C62EF5092B0,369A32A319046E7A,A8E497236911D6F4,0000D19212EE39CB,38FE34CDFD98F8FC,7E5C0CCC2FCEF40B,814B9013CB10E18E,00B3525F5C3D862E,50A10D51764E930C,DD4561197135C7F7,000178FB85105D81,D8D0F5949F15E11D,56D074C7A2E10AF8,F16BB9B74A5FA619,044B1E6DCF3514B3,F6C19500DF474751,E864BD3298F2E401,0001BD106DF50C68,8489EBE1F7796E43,85BB6AA3CBC6A44D,F32FED21684D2E0A,57CAB2D8A5A9B50D,E0DBB0A7C22A405F,31083324A8AD5120,0001B9911F8219EE,FB21DE1BC3C76C50,0148574768D9D3CB,C8358562F9EC979F,6EF2B795777DEC3E,27252888B7C9E875,12BC62778391A3F2,0001EC67969D6A49,98F26CFC864424CC,65804B13CCAB836D,5A7309DD73CFC68D,5EED2C7A1F2715C8,84283F0787738E47,147C73CB03DBA50C,000209494E64E36A,6045DD5D3548E45D,B7D85C0C7DCC45F8,C22A076DAFAD0818,7B5798466C0E7974,A3DA450658E672C8,5FB0E25C03632FAA,00007345EA805A1E,84C490A48762E734,D9D5A2121C4C908D,CF569ADB4BD75E55,879EF9A86F62A25B,94E7D1FAE895D768,AAAEF80EF5C7B689,000156FC4F666604,0C0D8C890147D406,A1E0E0CA234F4990,8B53CFEE9B4897A4,478267E3D87989F0,72B4FCE27C685BB7,4FB88FCC8A62FC6D,00003B77F4D18B5A,771678BD7F9B8AD4,DBD1298F8F06B240,451624C67894DABA,C11C6C92C606E12E,BBE551C4095827D0,17AA5FF49A2F58DF,000026D299E0AD20,472391455F2AEDF1,B6587C7FA7C91C69,504AC33B69F23F90,14A31EFE9971DE52,36FC8D8009A256A6,402AF6C5B19A9EDF,0001DADA1D60F871,5532BFC96A6AE251,CD38C8CB17B6C639,D711C9CE3A7328DB,791261B11B9641E7,F1E67B9A3FC38C5D,96034F295B89C82F,000050E8D7EB4868,C83AE0309ACF3093,E415D4FF802D1981,43FC8714E3F2FC5B,4B74ACCC931B1DEE,0B9BA7DFDB44C380,7CAB0703F445F953,00003FAC4B84DE34,2AB70DB32CF691EF,E32BBC928E671EBF,00509D4D50CD55D5,5AC6A9D0A95BDAA7,9F08A1752DBBFD74,C1F613F1468E523F,00013ADEB76D9C76,717E23CEAEB482B6,0238B0AC28ABADB0,DF864E5D965E8BBD,6A498321F7F6D14F,818421E33286F140,DAEEAA06A0421DEE,000096CB15B58C1D,37E850480C398380,9380062B28507DC4,6936C24BE9A79DD6,30441A6E015F3C5B,4F4653738172647D,3FE23048788A9CB2,000026C467BB4289,6E3262BDEE58D514,9A537427E7776207,E3182BF1DBC2DCDB,A524A93FA30C02CA,D3039DBC62A96F24,19D07004FB855468,0000EEC3403CA6D8,34063DB588ABF0C5,444B2EC9534E4B8C,EF5F1A4698C8741D,2A60574B8DFC2AD3,6A36978D1D75C62F,763452BF6108618C,000177D583EFE43F,676553185DCDC0C1,22144F92C76DEF69,01EAD0BC69BE314F,163B1483EA1A8412,B46D9EF1E23EEFB3,507B7F6835DB83FD,00018F60862C39DC,CE6EC5D701FFDA58,A1FBA73BEBEFC1CB,54ED5ED4B46AFBD4,8ED0006D5C62CA92,8ECCE74F0206CEBC,DCD4B160F0DB294C,0001FC74A2012289,96B9798753BCBB16,3E1846CB6DD8A800,063DCC0F18F082D9,238D9F47DDBC734E,7875AD3B8E3E0C7D,F1097D24844ACFC3,00005739C11E70EF,9F0748E8778E52CC,14B6D3A93D153BFD,E2080A331B867DBE,68FF669C489CA2FF,D2F4396606CD2F8E,6C2E6F9A44BA1CDF,0001FF9A8A25DCF8,20CDAFB6F42AA9D2,BD990C7196D5DD41,EEC035970046B361,A76FB28693E36642,DCC311658E2F7D30,04A655CED0B6AAA2,0000A817AFB237A3,3F52CD947CCDB0C9,8FCC309AFCB6C653,83CB787BEFCB671C,2BA40F340C42BA5C,528696E77C1E31CA,C69C31B5DC2FE425,00021BC39B630F7B,15D7BF7B231B3B2D,8C60F596AE154F5F,473397219B641094,81B224823729B3D1,3E80D43D89A8F409,95052CCB6B5D278B,0001CB58CDC1C7F2,64B62820CA177D9C,FEF641546ECC605D,A4782ADCD44E62D1,F4E07AD179F6B31F,0BFA3CEB09208800,31469BB0854285EC,0000BBE2AD418D58,FD1A8EDBB4BD8BBC,7EB997C5FD733497,4464CB2F9A598CC3,926372A9095C2AB5,6FEA1D9A93842E65,3232366FAB271C16,00010261EB54A2FA,55947CB8C00AD2D5,31885E6E8C0C237C,E6E0E6A5D1C49F2F,90C42A399AAB306C,19C80C674B93E099,8C68A96096EFC8C4,0000DD6C401CB511,0D01432A4E6069D4,D60D11DAF31B85EE,D3F0AD1E102A1C34,0A8DD84D4C416915,0FE15117696E4981,42F72041C83F654C,0002304BDD439E69,72662CEE64944479,F51E4F59A076BC5D,A0E602CC617E13AD,20F525A8B8A2C177,7933A561F0225A78,E6D005B1525F0B75,00016DA8348AAD0A,756744C323F443BC,38A37292276C2DD6,5E3CC4DB23D2C5D3,44026A64112D502E,43CA664169DECDA5,EEA0B6B6E53E1146,0000F664567486F9,4EA9B7A6BD99B6C7,80729D8CA5F41EC6,7B8609548AF56330,354444BDCA16BBED,A69F1C9789C9F0BF,021224C226C40146,000113ACF8CE7D13,13605F0D867AEBC4,B5E4722A820E69C6,4360B7C0EE57D6ED,54A4D496BB748945,6C9051904827FAFB,89716C501BAFF2F2,0001695EB6E43924,88DFC9E90259DB96,42D8ADE7F7ACBD2A,C641B5C706DE335C,A765A3F9D394D21E,F9076071A17E9CAF,ACC75CD2BB073EBE,00009EBBD417B6D1,8163D6EF0FC09E28,3B95661D45D64906,773E0AE79C2E2589,47CB19BEDDFEFF33,EB618B197B5F28E7,E5E5B9F8513B38F7,000018DCADE21593,56D7B9030B3E6BB2,35DA2EB8ABED53B6,57B4532682BE42C3,25F93153AB803781,8E9DE6116D67878D,F7E977E8F9C1B01C,000211BC8265C2A4,3B6D025BDD4BDF09,21C43009A1420DFF,60878EADCA98EBE2,35C75B4CE8B8C878,3C615CE9E76B24EA,8D297D0BEBB0FC26,00021BE01D065C3A,D83DDC0448820AA0,17D44264FA9548F9,B9ABD804C8AB0A02,E9ECAB01FBA7472E,7088EB64455B81EA,9665C2EDD6237DD5,0001460582DB9DBF,BE0208C2816090C5,736EAC9AC72EA6A6,5E7D8895CC27B4E3,CADE7023A852DCD7,A027D4349DDADDF8,C78E7F141A9A5125,0001E8F8D54BEF69,0AEFFA99039E3911,8E085448BA7D8CF5,BE39F08833915C11,38D866119C5994BC,BD9CAD479BC4DE47,180C57C0011F1819,00008F6154EBF6AD,4FE3B6486308B2D8,8A6F886B9057EB17,4D14D0C12CC84255,03B39E63310BDF55,46570699BF360706,BEFD17128A5F55F1,0001D1DE42CA95E0,92224E9CFDA0A325,5A3A1EA900B43EB0,2F3096CB3FF32515,79919C391E8ED1E9,C68B2CAECB6510F5,92D133C648769E08,0001B2F7DC4D2038,C569E30160D273B4,6406236BB473C2C2,6CD01C46DD4FFB12,3A43456B61D1AA0F,8E8C677B59D6B1FF,4DEE41DD1CAD2C79,00004BF8FA6855C9,2B38A5DCDF547A8C,AB31195F9ACF7531,7B08BDF885065B3B,EB1074C5A4A20157,DBC40C2C1B012023,D1FCDC8ECAA6A7D3,00019CDE9149C343,ABE356D428FF310F,3988BD8702A707D3,C7EF9B6138ED5C9D,CD7A1648ED63ABCF,EFAF0583343C7778,671873C9B670AEF1,0002208C5AAA93DD,FAAE88E2908CAF83,EF9AB2BAE520824E,23B48A6042786DC8,3BFEAC78C7EFC697,F5BD779194FB2ABA,571F237144F88DB5,000025A4869AC2BF,B2247E97FDE5FF41,C03355CA688D1D44,0AEBCE9E59B4FB10,F5A97DC0586D6803,F5023633CD5B9642,C73C55A7D52E8AC2,0000FB047C64BFE5,CBFB5B3EA0D6347E,B69F33C51950D74C,F7DF76840D3C5CEB,2246493A346E885F,4753BFAA754FDFCE,0BD5FDF9057473D4,00004F076558D29C,AC5B12C9F2F49B43,5175F26B8AE16FC9,67B08D52D8200AE4,31EB6A57D2C9599E,FAC1BB1012D79089,1789BBFC4CC28B17,0000D536AD11408F,E6B166DB54DEECCF,AA0725609C4B2236,93BFEE98A220D288,5F5B3DBAEFCDF13C,B9CEFA1F2B7F8500,44597B03562753B1,00015515678A02D6,FCD331AF76248C8A,0B5044EF1980DCA8,49AE3F3D66054348,3B3D576B6BC56634,D40B81DFC46CE3EF,E2E62163843C1FD4,0000CDC812C9FC46,9C86F8083CA481E0,79BC93A2853B21F9,BAF30392A81C50ED,B0ED84D591CB7D37,286007BF4479BD8C,2F57F6B56C74CAA6,0001132F3DAE3C25,59A7D21EA5F353EC,77BC1F2C96E50A58,C776EC933E7486CD,D409C9702FA02D81,E9D0AB136A3DC9EC,C835E860152138B8,00000D6BD90BE633,65C4D2526B924344,CECCFCC3133A9ADE,EE00E79894AF2483,667F371919AFCE61,91F82CBD4AA64218,EB072A56B2B95417,00001CCDCB9E7BDD,7D3C082AE28015D9,D2D70DB48D783170,1A0F2D0137C96442,28CF8971876B910B,7C633E18CFE4F438,18B31B914F31CCCE,00007433C89F3CDE,9A576139A43C9248,237DCD38A5155625,35A3A9F5D53214F5,29C596B44E33E646,826A284CE055154A,31F3FCC23A87F5E2,0001ABB7BB26D494,B632CB4A189B52CD,8FBC824223ABDE4D,CA784F68ACB6FC59,47F1BA7803E48701,3E2B7FADDB3D9183,129B34614B9B277B,00008F6580FAF51E,A197C25829C37274,68BCA862D7620C34,052C84117A450952,A020AE1AEBD926A4,CF4E0FB4AA47DA2D,195A49497F4C05DB,00008F5EC4888F51,4B84EC8A562DBA0D,F63BF8AE7D9DBA3D,CBF74B580CFF9867,E3233438E0F09F23,1B43FF93ACE5F27C,C76F6DF1846CB38D,00006E1260243E67,DB96F56E6D5FB4DE,570DDDEFD01D876D,FDD41F669229DD67,33FEF9020503394D,10F60F3A8641D2D8,7A8DFB6305FBCDFC,0000D3C4389F2B34,9584515BD4E03DEB,B8DE3C147ED7BFF2,BE0066C28B50C4A7,0C70B8E616A791C0,E9E86BC0F65DC583,43C7838C628A19FC,000069C75BBBDB19,F9211F2899C71025,0886EDBACA5AD717,2E1465395E681767,726024F86768F704,0DF097B01AD209E9,37A88C27CAEE1B43,0001AB95D7D98301,C8337B8BF47262DF,770AE04C066D8CF2,020015C68912D507,375D0B0C0163A8F1,1594E66608741E94,D1324A31C65B9CAE,00013A65129C1ADE,7A7FAF2CFC3B47C4,C69ED56564610FD3,14D70F612A0D0A02,05F39AF19214471F,BE4A577822DF8853,738C504286BE9E8B,0000FA55200410D0,A27981EEEF565A52,D6D4BDDE3403FC51,591054F45787DC63,6FC5DF0E3D752FEB,EEA97D066FA191B6,AEB40218DB5BF211,0001F0683E337D2C,AAD1A549AF1202D7,F1306A05A9DBC9DE,9AA52E35515EFF40,C6FA6FC47515DC63,AAA81152432615BB,35666982877BE98E,0001B25EEBA706AF,64863CB1B2C29C9D,0BC688B14C6848AB,4025513FF5AFEDB9,970E13A38E4B049F,E96B1541B53A000E,5C15DB14CFB677B6,00020D9976F18FAB,200F56B7EF4BE92B,46A2DC6DFDD3B87A,84F5BBB4B9C6BB3E,99FFA345B5B54747,4BF1A22A125A5A9E,4CE6702927132840,00019C00F3790FC1,13089ACF10472DE8,FCFB0A62F8F99650,26339341D6530CB1,F9C05F3D1BCCA0FF,C1313F4B94953E4B,683CD078C10DB4A5,00001D306BD6C62B,F4024A2172F4742C,3294D6C3CAE55FEA,B4C947D3440E3078,2079EC63FEAB3665,11F2730E5111C7C1,D6F185DC47961CE3,00012C07AF3E200C,B3C35CF4027184FE,C343CCBE30FCB3A2,F5E16A370A229FF8,44F98C5AA1FA9BDB,72533790501CCA41,6E8693BFD3E078AE,000162CE07764ACC,4AFDEF4AC3CC0065,95D51EDB15780033,6623DC3F037376B1,D5E3C524A2587A74,AFFD7FBFF398708E,3A207C878BD13B7A,0000B5BE4BEB023E,DAC795F02144083A,59CB1448C6E0CA21,87B0D3016A55A59C,4FDE4D1A1C0B5C2E,1C7EDADDA115E3C4,7CDD884658915F11,00021B428DF943E1,A324AF7974DAD0A4,35D2B72CAC1A9020,C6B8F51B3289607A,8D8EBE9FF6413293,A865F42BE8E718AF,A761DD51C4383201,000159F04F21E802,D3BAAC91D44683F1,259F2FC8FC244361,1D9E9C1E4422B812,2FF4DA9A6DF0E864,40DB955E784E41D2,22CFF497BE206106,0000FA8663C03847,6E587A165FD68240,23B494B3204846A4,54A0E74B1C253DB9,571BB1D210CFCCF8,9945A5B078B50995,C3CCDE1B99A1F6C8,0000444B7EC6D5BB,C75F3472B1A85173,D27CB8C55C01FD38,6B4F835618468DF4,4527D50D4A6540A7,466AECE50E780AB6,D54EE55250475210,00007101341C39AA,350613C412A96AED,4B16B55D99D679E2,CA1512DC14BE8AEB,196E20EBEFE2C78D,265806727667FE29,717701038FEE44D6,00014EF99956C3F7,3DD1A9DB83C6418A,1856E198A79211F8,3D26BF9BDFBF4174,C65AF978DC5F0BF6,325D1A2F77B6632F,30002DDA4735B0C1,0001FFE862A04E96,B2B52F9FEE8C8CCB,8C9793AF60C93752,989E9DE63F77F57C,7128EDACACBE70B1,05D8795DE50EEEFA,1BE9619223F2E3CA,00004A7E7ECD9C5F,0FB71F5822983BFA,0F284640AF455C93,C494F0386DBE9757,D08543D94A0AECE3,1203B97CB0140430,7546BFE82F30379E,00003EA06F568F1B,223E88FE6F1B4948,339B48072BE9C7A3,1EA706D1C8859C1B,5F831876181D4FD0,3F3E2572217AEC45,40E0091276BA683D,0000156D1D5F8631,FF75D7924545923D,9916651856E7AC42,32C757D08652F92F,D3CE147415D17515,BF8F9942A9F25CFF,380521F4199EDDEE,00015EA26F5AD22C,6B71BB951B198EB8,A6DEEBDC99524E87,607F27B9494ED99F,5D34F47C9B54B432,27C05F161B96998A,84B77EEA8F457660,00000AE562FF4539,336E137AFCB0688D,C2A904F54008251B,6C6CD3E186B20BB5,CC1CA12A596E70CE,0D5125595C8EB573,8366E00C32C4AFA5,000213B0F3DE25C3,12CB11387D0E1247,8B948D25DA6FE598,902319117F24C1EE,04508553946F08A6,4BB3717EBEFEE9CB,F54E357811E1AF7F,0000329996C7BF35,1D3093CB097651F1,AFDB67BE06B37202,E12EEFB1F65B8128,8AD735F9AB9FB91F,5C14EA01ADE5D9F7,7470BEBD21E507C0,00009B50371C9B55,502F5AB0EFEAA3BD,1CDA16ABC6764C5D,16F4BF04B74992ED,70D49C9CAA8CFE2F,F6305338D9956E24,892F8B806E341F8D,00019E255FC7817E,75D3146D75362AD9,E6C63513EDE0BC41,BBB7A748088F336D,AC0F776DF2096CBB,39E1E095DA3AD9BD,298A78C680ED0AF4,0001AAF08105DA2B,5812024A085BCB8C,B5DA0EA4C6680E13,4B892D4E32702364,CD43FBBC14754F1A,4C4176F37722BA4D,0FB43389413ADE03,000021A8ECD99834,7E7EAB1F276BA202,C3973A35C211C8AC,6EB2090B5AA2E453,0F1B87410E7AC7EA,60EEB312ED4ADFD6,10C8AAA64C32FC1B,00009CD4B509E3A5,B4291A0F2B18B33C,1BB875C19FD7532F,66DD90D6B31DC899,AD1ECC3EDFF340BE,9C45FF1C7AF2E834,C65DE4096B73AB1F,0001B8F5919A576F,8B9E7C9218B022ED,14D4A6823CEA4525,921D28209435A015,51B71BFAE00522A6,947B14DAE0D1BD95,E8F73E4FBB4B5462,000165505363EE4B,41670CC5D7B3A682,0177AA740637DEE2,E00F62AB186EBB61,B82271BE0FBFE5D9,0C31114F14B8F0CB,029C51F52D2E13C8,0001B1857D3E5445,E745464C0B8E8A54,414B1193BD85C84F,795FFCFA808A6FCE,E2EC2A7C5D0A2044,CEED293E9AB5D3F7,13703E6498C088E9,00020150F4839511,3187F1D8FC5B5D96,2DF1093D539C1761,D38A2E54AE9CD49F,BDC3F5E753214FAC,64A0958F9461798E,69609581BD201F10,00017EC8FDA33788,8B04BE81E07153A0,88F8253763A9AB33,9C80AC40DA37EED5,8B87951C2013B2C4,B365456906124A4E,664CCE52F288162A,000140335BA62950,7CA7727695D9877E,58D29315846AFB55,D1DBF983C0C3DDCF,F2AA13A3712277B5,597C56705DC0715F,8BF6E1746DA886B7,0001E9B6C775182B,79830FF0C584729D,6EEE28887724A9D5,6FEE78FCA3A0DCCF,C7AAEE962F402056,A3799D431FA5B308,C051E23F447D63AA,0000CB3F1B27BCFD,800C845C054E5563,FFDACFD250BDD96F,E68CE6E45F7B9D5E,FFBE47025391CD4C,AE170D8D6A0978E9,DB5AE93E15CD11CD,000151E68589C827,21E44A9FCD46E2A6,F16AFDA678E0AFB2,9B7BB00EFAF5335F,36FD6869A3B7D6DB,D70A69FB744D7B24,AB64E3B2DFBB40A4,0000BE65258E717C,E8F3B2352357AEDD,B80A895AEB3FE706,B7BB6225E15CC8EB,7F34DBCEC08B72B8,675EB381ECB98125,DCAFB7AEF81029E6,00001AD4286E5CFA,9B16C1BA89326063,BE2CD4F72C6A4A92,71419173D79FE08E,E99E797B397BB936,58C8EAF4F701CB25,43A2E99BAC8F3840,0001D22B5ABDC838,479190BAD02A12B9,B826A9251F1EA32F,97C467172279BC97,CD198321795F6CB1,78D4ECF4DDC0F488,D688A43F3ED1837F,0001410BB4D88E04,D22FA3AEA51440F2,C05213C2F70538CB,ECA39C2FC49C922A,E592BABF7F2901B6,71822667F8B0F7EE,759A4517F05F47B1,0001DA99588C251C,BBBBC746DB4F892F,5C0584C4D72BA1E7,764BEAEC281F602A,73F758BCA47CD5E0,9C7D87C43764B6DB,3A88965EE2D98A44,000026E9F2A4CE03,7AD296680D645EDC,D81B5E62BC0E753C,5CC139220B356699,A6E45374731333E9,AE2644563893047F,5C57E74EE605F27F,0000DDCD68A72734,FE662224060714AA,43A3FF8740C53EA0,7BD45557C0956FF8,D36F361DF83B2130,BD7B1683D55A8352,9E48B079627A1284,000001A0E2F91579,5DE9CC4FFA0637E5,9AF2ADB6B4BC53F4,732CBE4D7DF38977,5806A0647ED76990,A6A1CB4F1EA1D4FA,3D2A54350C927632,00016E212911D833,A8AAD85C97574823,4E6432756D8506B0,24D365E8992B3FFA,E93C4145E0CB776A,3033470C71605FAF,379ACE4B00463AA0,0001B0FDCF31A387,3F599F3A9F26F569,ED1D367CE7918B27,295FF6C96E63D8CA,2A367AA4CFF0D914,49E6E989142D8709,B1FCFB31C583E540,000128464D679092,377587EF22DDF18E,DA4E55AD386999D4,46189A63F65B8802,22A7A43589C5BCB3,300C2D6AA0207A51,81B1A059B2E5CEBF,00012418521FB33D,E83BC98DB14DF0F6,FF7B10D1B5733D6E,FE007606F1896A58,CEF7ABA2C766A0A5,A26746BA598BA9A9,44D8F01FCF1BC6A6,0000D41ECCA97911,E56C3DF53A8D5E41,D292D4AE1C2FC2DF,A436F1641F426F99,BDE17790AF0AB83C,208373FA458DCE58,D68C70202D18821E,00020DF3A68EC990,7609110401A74906,AA6928283D7C0D5F,D79E62E850FBBF57,928A1D21B5CA71B9,12D258F23A8DA7FD,F51AE005EC81AF04,00021874B8C31DF7,12EFFA4B7A01788D,A24BC5302ED2B21C,8A3072D57697D6EA,ED2B5BA5AF534CF1,ABC88617DB74396F,2CDDE9074C16CF1B,0002146694C4412E,BC2B31CC408DE079,A536314A802DAAA0,42E078683EB512C4,95A83A1FF73B58D6,01AC1681B238ACAE,5FDCDE18C77C0B00,00020A2A2198C256,55279B1AD61AFC13,063610837175E54F,F6E2C3D401BA1E61,B8F286CAAFB89A7B,03842AF650AC65E9,D0AD5850FEA2145C,00020876275CBC5B,242BD3BBE83F267F,CB2AB8813B4E6431,57E4CD87546929DA,214D92D67295934E,AE8B204B38E32A34,38B46DAE8F7D3244,0000D177F1631E2D,69BD86E1C0DABAD1,48F2ED211B8922BC,0B7F03954E0D2027,3CD14E05BC2F9E86,FD71D4B2C79093AF,07C85E606EAB40FB,00007B5F0002FA2F,ED36355EACE4AA69,F936D4C3D379C54D,4F8BB99D5231774E,57DE717FF9A49265,8CA9AD721B5DBC0C,D0E575D6269BDBCC,000102C24B89A99E,8D62BDD245308E64,BC82175CB26D75A4,1E148785EF3D9AC4,59CDAE3C5E460BFD,4B43D4BD9CAD24F4,E1689094523EF6CB,000024BC47342670,EAE295D9EDD7B326,4761292AB1312CE2,B4669DCCD6E09A1E,6C97B1724D72841A,8344E7039DACE577,1EA877C468AC3C91,0001039C6B91B007,B9690741FE84ECEF,5764539F7F0EF535,0DF1EE4CAC0E0534,74312C89440252FE,52804714E143758A,407860531A06D516,0000C87E67470986,B1FE72D22FAD9021,D456B59FD018EC13,32CF5D474F78D32F,4067196FA3E1C4F4,A74307CC4861DFE0,EA68958514197E59,0001FAF0FA967C8F,88ECA0229531518D,51A3737724786A14,91D59D071EF1EB01,A2CCA7DD91EE125D,19D1789DAF1AAF30,1C37D3FB481B84B2,00014C56A3980481,887682916B78EA60,9216C34D5632F95F,77DF5ED25A66555C,0DCC5719D917A890,E3E0FB7B757469D2,5472100DA71AF33E,0000B54418D59C70,8B7ADBB4AE73616C,2151BF1CF74DDC15,27534369BE915B75,ED08D73CF3E8C1FB,29A86E4B2B69BB41,CF5696EDC9BFAB6B,00010265EEF16709,5B80658DC4B343B4,38C506607A0E5645,78C629B89D18576B,AE7A204E0C1669D2,0CDC4819ECB44D45,AB9ABBFE1D62E1E4,0000085B042B3C58,0F29C84D3A99FC21,2788992E22887431,0DE277C4A3189909,8B99E1C5B8B09BB8,E7E46B20B52D4234,69F1CDB8065C19DC,0001E91F6E0026C7,72DDC2A683609E7C,BC3443169958AC44,2A122325DA5469B6,200ABBB9849C54E8,243EE3DEAEC7614D,49AC6F4D976814D3,000076645B81F571,015C8C73F0EB4A15,BBB8C98D4C2CDDFE,2604D79424678FD6,C5DBE53F081BEF82,A321C91EBA3DBFD1,136F8E7DB16D114D,00021425FD199782,D1A6D2271819E06A,1FC05C9882718AC3,7DE8A19AD77CF9CC,EA1A106A59578ECA,C085F5611E2ED845,431A3BCE37B61C18,0000C0F75E4B0025,54F4E7A89CF333E5,1C12E05B63645AEB,7EF99D39E3EFA6E5,9F938C187BB9F0AB,C2281CC15CAF9ABD,C69A07595C632FA4,0001690F631FAE0E,CD9B8344BAE2973D,9E245EBD282001D6,170651EE8A55E6BF,855831B56D4A0F84,73DE76474627D8B3,F01D2D0A2181787C,00011AA6DB04FDB3,B0FB7B2C676C2BB4,82548415333A5936,5847E40640FAF1A4,14EA3776F5C1295A,9117C238B05D451A,CFAC44BFC25FFA98,00004D05CA7537A9,8E8A73464230C913,C9469ECAE61132C4,D17981A7670700E5,22B911C0467A2B79,8865839A3411EEC3,9A483AACAD157AD6,000019BAD161008B,E4778CDADAC0F8E9,1CB2A8B3D9225823,B66C74F14368FB28,E8053207EB4C5DE7,9AE18770B14A0026,BC9C11CE766D8F01,0000C7EE73A44C7A,EFA0EEEB9FCB8707,7F670309CDBC0794,144B71EDB1589C11,EE97D607C698F8F1,380926DCAC8FB92E,5028A802FFEEA43E,0001190DA46DB521,425B210CED6F4DE4,F46091ADDE2F4BC5,F1865D27ABDA6189,E62A482545BB1526,3E1E2812AFC5195F,051C01C15CAA68D4,000003AAAF42F260,5C4081E72F7B4670,4FB40FD093D1446A,545446D1DE9824EF,6A6ECD1F55398B04,E8F7B1976ACA02C9,648BF2EE1CB5F881,0000C142A061F2CB,5FCCEE86B09F2D95,9C39E8846C557086,1CEFC36E3FE0FB7F,7927535204C3647E,C0B1B4DA01E8973F,7C8136411C0C1DB3,00008E3BC337083F,A4DEAAA1E3AC7656,C823C0FB8F81DC87,F43975F83CA91A3B,3BEF213C08810FCC,9C838381ED436256,10C9EF87F5BF0046,00005EA72636560F,C392349AFFE0A661,0A301A660210FACC,A4374C2C9D70CEBF,57EBE97D64CDB70C,F979F083AEFCE306,FF142A2DF718AC42,000190BEB881D898,E00129A87864718E,482ADAE811E42F81,15AA4E8D7E035D6C,3F8D255304A51171,6B9CFC017FF0B61C,0FD3440B631CBDF5,00021BDD4904E046,7778D70CC0B3DCB2,891CA6F2D45C1219,44E40F27646F5050,565B8DEAFDCF5C63,5487E4A2C97531AD,F9C4D86FEBC2E7DD,0000F4541B38BE58,E58588403111FCA4,3558B1DA7EAA39DB,8BDA15F4A5B48350,00BEEA4915AD852E,E7B8FAE69D87F7CD,EB90F5AEC5393776,000041AA873F92AE,F0DFEB9584F98D64,D3526E0705D55621,EB55E33642E14EC4,EBE1A92694551A4F,58F1F9B939DF3D8F,1EBB583FADF38EF6,0001800EE97490EE,1B0F7CAA27FF950B,A172B227B25D553A,5FA64569610FBC14,CB84223162C6CE8B,C51847F777ED8F2B,C481DBF4990F7E81,0000C46172243941,FB5AD75A16E7B16D,A00417348BCCDA77,E0A9166051AAF54A,870B78AB21B87BD9,16E3ADD9FEA90968,1534F94303958904,0000D480BCBC7273,2E19C78A03A660BB,A5F252DA9E13924E,93863A84A863BCBB,53D84E32435A0C71,4EFC2875559C07C7,958EEF3DAD062DE3,00002505EC949E53,6BA30AF53BDD2EFF,A3FF536404BF46A6,D689A44221279075,EAFC7B159FF6B0B7,2A429C32FD186F69,E281731B0C76F36F,0001598C6E4EFF61,A1067B7F9EF62063,B066E9B03880A34E,13F6BDCFC4467AAB,BA252479955F26D7,CC8F5381537401D3,AF16CB6C76B811D1,000213EE7EA100FA,06B79A27C635B1A2,6FA23C5AA002A849,DB5559D433E7ADD2,7E3D816B4B35CE8D,875BF7FA2AB290E0,82325EDB1AA0F026,000039C241968C60,E277F0A312BE2F34,0A72BDB044B54B89,E67FC4F35DFCB723,7D7D9924A67BB0C0,4BA7080A09DDAAA8,94EB2AFBD55988EF,00009749A7AC0189,15B32AC1DB037154,653CD0ABCAF7D9D5,28F9BDE0EB0E21FD,3C1878255832427B,99609E99D772064C,DE9C19FB263DDD10,0000EE92B0A7DC5A,144AB71822AE3A73,197398706EF7ABDF,3FAF0621321FC028,8BAA3090310FC75C,414AB1DB09EAA9A6,8F1D35E617A89822,000081517F263130,2823C7898F144348,D1AF23A8221F9EE5,E1A483ED9F0B9618,C3BA39C010F07415,03ACEB16831929E9,5842BE358776E0C4,0000458E55A850A2,159F52F71CBC1630,49AEBFA0A14DB119,CCB02206986B7458,E04D71D8CC415CDF,FEC92CF4A163148B,71B4D20FF24EE036,0001682E0CE962ED,EDE9864477B63455,328C34F514592717,5F2C203B2A9E36DC,5CEBDDF689AE7281,48329BFBE000DC52,6D7FA8672EBC346A,0001D7208BD6D5C1,643D1C5F5F42618C,D8B66E3231D5295D,C845F9F201AE6495,6DB5222874141A4C,2AE95B78CB46770A,6C2F2C7ACA0EEDF8,0001ED5654AA287E,5D4D1439B0948D87,9C01F06555C5CA03,99AD1E6525323879,AA3DCCA6F5A6DCC6,5567A2408062C2D4,2F6C28601748A38E,0000386C1FCC4948,7906FE86FA6F1DD8,63ED266B14EE9474,CACADDD7E1DA78AA,688C2814E53B3121,74B214F0306C3AC3,46DC44BC9C7F683A,0000C1DF58651C3E,4ED9DB62A359D207,385282099CE643A2,B98DC4A7E527D634,94EB65C9BC377DD6,922CF69D72562547,6E9661EF8D05A2F6,00005573AE77F24D,F575686154311EB0,E938BB510A854427,BD1FABC99BF51B20,DAA713CE71911487,719476B5C232E4E2,9FEBCB0E095A3378,0002187672897A46,54280FCD0137681C,C3076F709E6AC9D2,45FB36E98A2B6362,F92BCD101855B865,24E3810077CF4CA7,BBB0CAF5CDC8E7CC,00011290394A79FF,83C7A7C654457A72,4C4B601001EE67CE,66C0AB430077FB61,558319611AEB138C,098470DB5344602A,2B2F9191A69200D9,000122ABCF332EAB,02B5CADEA4814172,67B2CBB3F4D92E91,0D89B87AFECE265D,32D06291986E6ACD,5F651B0B3265BB8C,DE2AE7E8B8A85D26,0001087E1E7C45D0,F2FA13063082C5D3,FF133884BD62E0B7,15A2B57F99173A32,B6BCA691B32850AB,22671291C0C69ED4,A7EEEA0975EAA822,0001E5726A483B07,CFF91F58544288E8,8269FF777422222F,767A8D9624D00EC3,DA240CA06E6C2FEC,A936A9D860FC4AE4,431FAF790F0F4466,0001C6EBF25B515D,14EEE0422CF5BD0A,AC6D590037AB7A1B,4919FD75BA03090A,43B3E99F764BE6FD,CAFFC2E38C918B39,6EEAEB3EF7F245E7,0001D16B40C07D9E,A3F9E05FBFB9F5E9,C0A0712AD8330945,07B81594FA8166BD,E7FE92051989254A,6351F4D7303B34F3,BF8FE9BF41AC55DD,000081D27B4603F8,1470D302647BACA0,0D9558ACE090B2DA,B1B81C5BAC203265,76A343045FAFDB1B,223B86ABB9736253,4917DE367221FC36,0000488396FF98A9,203304A2BBB40E3C,CCFA074B8C0567F5,BDCAA38F7A37BD74,FC1440918608AF4A,69A4F830546DB077,95D0852A9FA357C2,0000B118752371F6,15FFC9BD84D91AC4,EAC607FCCA8B25F3,50ADBCB093402A45,C6D72B5D9F6E1B86,671ABC45D511942E,542EB3C5B9DE4E71,0001F7099C3F2D92,678C1B54F100EEFB,D0959C1575258109,31A512EFDD170157,47F82280C34BF51D,A439E47576AAA282,22F3E0A14D0B441E,000025E4FF2007EE,CE918E46E4FBE876,9801E19FC93DCB52,91C5A3B5CBD381B4,6C6C844D44E58AB7,8EA5214C7F50C8E6,0D021BA31244B395,0002031E1EBA90E4,2440531EB8EEE489,2610E6235CB71365,1469AEFA0E78AF6F,07B132079740FE04,F71D198B518F3341,C94D22BF5ED53FFC,00019F5AE3B6E1E0,2A4371CEEF216890,EAD8B7E0FF053D6B,2750B2993D6A6450,99C13FBC5AAB40E1,2A1190EE3F326149,E214C7062FA8D6D4,00022EE586B1736C,E927E82DDFA88CF5,C847F2338956BE09,E47ED865F0989744,B79C9A7F1FE1157D,EC822D4E9A02354E,D5783E1EAB683951,0000C7CDF3CE2165,641097D94411EBD9,C26D2BF4049D4386,B3CA1FC78D071AB5,3D86C3DA06F0F3E0,54B3BA7713013FA3,3F7C8AA230AFAB0C,00015A72D5EA1D35,E9A27616627A338F,E9B0A4AEC6D790DA,1D9A51F724497A03,0EF3772C36273A46,F09A6B9F324463CC,F6AF696FC4D3A683,0000AD865C3B5CDC,6A33AC1DE02E65ED,CC782BC8677AD36E,2A1F5CF72A977F4E,1286862CE67DA7F0,FFEFD5EEF48EF03E,1662D2EBFC8C75FE,00017C9C16489560,7C83510F1E073F8A,552CBDDCAA422FD4,4B0CE3064B69B192,026E774F4501B8FF,72126FF5CAD44775,551487290B5B822C,00006BE37157D248,56F76C4A14D9B1F6,F5B9E1701D74BA16,582813FA2E6C9362,F3A9BF72B6D83F51,6498289CFEA60D88,4D949802B7A52E2C,000157C253B27603,B0C78D9422EAC3E3,5A996A040DF60EC1,2CE38B8C1A68C3B2,0324019DBC145D35,40AECED1D101AF7A,DF05F30D986BF31F,000114F6738AE35A,0BED90BE650A877D,5C40BF201960B3C1,D17075AA640F9809,6148F86F25E28E3E,F5BCA0F9F89D36F7,6D9FE8FFD881816D,00013EF37025263F,05BC7982E46851B6,67D9F82BE2E45299,FC66FB83767F7A0A,8EEC5EC7B3825C50,A51B890543A5CF16,48841759DD689D20,00000E67013873BA,81E476377C6188A4,9342939A6EF03A67,D4200752A2BCE12C,D19864DC7369E144,B371267F42E0537F,3D050962A221243F,0001B48DD7B16663,0D8E246088769BE5,F24894222BECC047,89F28B19A3F184EC,2684DB124538EC09,ACE5F2D7646BDA3A,C9F51B79DB4BABF2,00006DB9E6B7BC7C,04F650848B594887,9C642AA7AFFA326F,08D0DD386768CF96,A7D0B6AB3199E103,2E3088A93452CC61,2DD75BD7C7ED2D15,0001239EA61E5FE0,E5E983D21D2EE596,6048597F75455ABE,63C258EBD356ECC4,AF45C93F42E7EBFE,4135E87D0892E951,C3B3F168DAE19C09,00021606F03E6E86,13AEFEEE61CEF623,395524FC30BB0C61,E604D87A398B00CB,7C4B3F85E46BA97C,F407037C179B16EA,297929D94F009B66,00021C0C34466C5B,AC7C30402F5AAA58,5CD217BAAE6C8B31,A85EFE7D5ACC2ABE,CF4807B272FEDB40,7EB9C24AE2A1DE06,917D14CEE6B09889,00003357CAEF37B5,063BEAF31DD2A1A7,1B6CB88F1B41C035,169FBE6CEA1B5D26,084E9720E34938E7,90EFDDA4191EF9FE,5F846E6686BABA1F,000203736769E832,BE3C06C737AE4D57,32EABD8FEEC2B84F,8935B6DF6D373D16,261665160CDABECC,77583FDBA470FE16,1EFAAB64FAC0EBE7,000172B908CFA03D,E9DC5C8794C3C281,6C4864085F84D70F,AC7E698F6F625800,A4FD8A6276964766,B50EE00C9B27606B,FCD661FC3163286E,00020110427F0256,DC2FD40F34446091,857A99B0A93AA21F,BC2DA259AF77F691,024A763DC85AC633,1AADAF1BF5D95813,B09FB1D12D9828FB,0000C81610C1FEED,C8BDE0E7B1BAA639,E5D47327A23F994A,B608D08200ABAB11,AFF071DC1FFE0381,7ACDC15A5BE5558A,AA3F94D433A778B6,0000A593879DF50A,972D32AE1F1D0C54,6C4C1386428A874D,EFDC02FCA2B1C57E,98FEC9F150BCBDB7,0004E00631AE9064,DD1B278130A99049,00002F76EA5B7097,B2495881F978EF98,1183B76919B0ACDC,E43DCBDA3692ECEE,4C397152BF2FC1E2,CCD10DC1AECDDE74,300E0A2F2DB03B93,00016591C5A7B426,0AF1346743AEFDF2,120724EED8F511E6,18DB81AB7BFE3F2A,031F9415AF3FEA6F,7241675D0B7813F5,4334E574BEF027AB,0000697E946D4273,DB6E7CAA695DE8FE,76780C9B0C6376BA,4422D2C4B3FE422D,5C6C8372783A6161,B70CF4F39EB155BD,47F5F15308B05B3B,0000FC6BFDD5A3B0,5C9F770B70DE8331,F2622FC9BD22BDB4,8CEFFD7AB7665591,455EBC78AC23643F,EA2DBD29417ADCA4,4712D7141BB2CA8B,0000DB4FBF60D970,38E6157E35F2CB8F,3866FD31EA04B738,0D11BD2F70A745F6,13A97B197861906F,B19041A71D5C372F,992F0B47DC711B02,0000646332028466,85BC7AE84CF2C04C,C7CDA0B86677927A,F88048DF421AEA5C,D136404A6B5E8E26,CA2E8C2B5B9CD583,5498FC2AA64BEE5E,000186CA7CB911D2,59E13451A9CBFC14,F3BC74A0EA7B2899,2CA65A43270A7119,A903BB8303B36303,029799146D8019F6,D05A2F5CC427699E,0000366B08B954BB,26E173240FF300E3,01A529688A392BE7,7597ACDFC815832F,F8D7C0A9DEB8783A,D30C5E96DAE657FF,D82B537A1F26F64C,0000C1222A77CCB8,2944C364B05DC02A,E2322AD2873EC495,C17A76DB90297359,4407FDAE8AEAEB8F,81C713A27B790385,6B6722CDB5C98343,00016DC3F5B3CF0B,24E3707F5CA5D83A,867BDBD3976B002E,04FEBE139539998F,2CD0000FBCCBD3C0,45F1695F0039E002,DC5311C8C16F17E3,0000E4002CBCFCA0,39FC6BB2C214DE28,8F1CEDA3A4713405,A0EF3116D15988CD,7085EB4980EB5A6E,B4A6E6633EAA1FEE,995153FEC491DC65,00002B37DF7E4D10,24B0D641638BD998,E7EAD716E43F6E29,FC73EDCD235F61E2,4798D4223A44672A,95FF2BDBEA70F9DA,A534A49D6B082C33,000160F307759A1F,B5F76080AB80FC25,02D67570F46E0B10,5651883A4979E4F4,6E7D291CC7B1CD26,38C72A4F70A8BCDA,B0F96AB3B69EA827,0001C9CA6BECDF7E,D0AB519CBCE12B9E,970C4871727AEBA8,8420A6C60B992CAA,B7AB00A6D54E8F9F,36906344EF88E016,B06153C84F5153DC,00015F0263200204,947D3BF12AE4273F,B9A3EEF5C875361C,284625DB0D2133E1,5CC38FB493CDC07A,71A9420E8A8F1793,E1B260F50F4F6881,000072B718AE0834,9114E93B8519CA92,CF05532E12D2E27F,E19A72906548F476,BE7C1B3A22ED283B,ECE224A00354ED01,FEEDC2BE3885783F,0002102030FF18CF,F0638805C1648B84,11C11F041EB94A39,8FDBC1975D96510A,842A86277D88BE11,2746337DE50737B2,29DB1393F202C78F,000092DEED39232C,ED23597169FD6AD2,1987E66990D89E67,517F18DFA2A1C894,906CEF66D99C266D,843724DF0544A69B,8F93DDDE788BDA05,00019100A6FCAE0D,B78529C97C1B9D1D,A2FA1D041F03CDF3,C306AABEB32D17CC,902DF2B861006A40,FAD36C4AEAEEBE09,021D201A5D6C7B0D,00019C232776B4A5,8D0439A0B7BEF8ED,96F939776F043211,5C2D209133653AD6,4D62838B446BDC78,EFB52824F7555C5B,49726205E0B243B9,000007D933B77598,A7EB468A88159E08,7482B379A955232E,5089FBE36FCC14AF,C1AB095182B74587,9B7F40C899436F55,177061C6B102C724,000201F19D2E0D7F,96F7D0952CF03BA4,00BEF471936CDE93,AD6699D02C6FDFD0,191742F8A44FF8CE,D0DD627BE54CFCC6,471CFAA2DDB91F0E,0000B23B7B3A6ECB,531E932729049C33,167BFEBED836B594,7872362032BB2B9D,24E7CEEA27C682E1,F37987AA3F6B5BD2,F914BD046608BFE8,0000687FC018D77B,D3CD014DB630B6B3,BF9C1FC22A8376F2,7D264855527860C6,E6EC229E1C21F041,3662575ABE9A3414,B877AC931F71C0E7,0001D8FF2B97BB16,C0EC2ADD71FE54E5,FCC59F0FDF5D87BD,02E54962D8E3E578,7560EAEE85D16A13,FB08B6423A000879,6D3992268C2CC613,0000B99911FF1AC1,D4A01A5D1CE22D75,ABC2590AD6D13193,73BBFAD3093793A8,2B4AF6BB47B12F0F,D1776BC36EB540E4,A9F3B3D977EFB8F8,00003560B7E97399,D7E975EFDBC42532,BE7EBE32CECDC504,AC88BC71193B070A,DD1A7CE520B8BA88,31E33F5865B636BF,428A5F1DE0F7064A,0001AD05C2ADC23A,081F61E90FDEE22D,9BDB22D3DBF4E904,172B4C424EE7A93B,595531CFB6719F51,90C3FFE5A860E188,766F9C816C34F80F,0000F49A34924046,4DA5D5474836A32D,AE85D5165BDA380E,7B6DE67A451FD04B,408E3271F6B5B569,FC509F10D8998DD7,45DEDA7A023B832B,00018E1EBE6CC26A,DC624CD0159331EF,47BDE4456CDD494C,35CDB385FF3B375A,833B80A92F899D0B,0362057F03D11B6E,37BEA8973B8D8C7B,0000F6D974CC3EE1,EBB89A768FC89724,05BF7DB48E8575EA,36944A271FC12241,037E5B434875E2D9,40061D52A7129E72,0DD0B4DB74CFB499,0000F2CE5EA2D1B1,6F6854212D926629,1B48496F573FF254,3C58708AB076C28F,A58E58F1BA47C9C5,8A6F269E8E150478,02A6BF95D3E16BB8,00012E3D6ABC066C,7B997494716701CF,41945D900222B074,6A6B3BE957DC089C,2F81DC94D0DCEDF7,3F7E878FFC19D1B3,B3E93F0313270A80,0002269612929807,636DE284C66ECE9D,B3E91BB39DE0A69C,DB02BC6650FAF782,C25447AAF53DD803,D6E0E79E6ADF998A,0A7ADA45D03FA5F8,000116C95797CF45,B71768CD629BC746,9D9A5DCD384E6D27,B8C38F254642448A,D2C7C73DAEF347CB,B37252F32D0C7421,F96A46B61A3862E8,0000BDED5A29F435,9C70E45C25CABAA3,C50298F0F354923A,AD95FF2BC8130204,E3D5C75C05464412,11ECA686864000E7,24480461D0CCCB12,0001ECEB6464DBE6,96A7C878BB1EDAB7,40DEF16EE88927DC,47A11F4B4553DC3C,2EB5200C5BD46DCD,F11216909AE257ED,66F810F7D0FD0EDD,000086C7EA89C724,BDC78AEDC89E1946,2507316DAD0A1760,92576B5A54C69E0E,F9DE8220301A0A2E,AB12032BA97BB634,8EAF464C50BB5DB2,0000983765B8AACA,0D8005AD4F804801,E058FB63BFCF106D,DBF519557BE9F8FF,9F530927320D4D7B,6905617CC9DF8585,6AB39D33D37EAFB0,000003B77B2A6F32,567B378070571330,9DB3787BB63D0303,D4175E3D6A50C5E1,4B5646CECE8C5442,FA33B4A79C414C44,DCDB30D98B8F948C,0000A0077B05D7AB,897EEA13B54D6AB3,BCC1C110541A25D8,D2F1D2FF4081C594,50B2B6126797689E,D6645C1F9E361219,192C50AC1D580066,0000E2B8044B69A1,D227EE067C9228FF,398A95CFA1DF1787,8675E243261FA767,391999E7E98E2FC1,7260A3AAEFC4D38C,A30F88EAEBEAFC08,00016E680BA81CB3,D6F558286D6D1C26,7C327190A872EF5E,C49F5346F70302F7,0600E595F6643AE4,1CDDEC6C70AE5831,48F58C7939077EEB,00010151BB268143,0D7228AF8BB8E730,7985B965BF4EDD18,0963FA8E6B4640AB,B45CC5EE71161CE5,1D8E2BE8B954F2F3,D42AF0154827A033,00008EC70D5DF042,8866F2DF175C0BD3,C3E9B251B8203A4C,02095C095934D7AB,256FAC5CEDE39A08,1D0FE32E85A9FB2B,45457A4F36E03F63,00009C11A97CD941,5F937052BB7B7069,4F6D88D0C3D49C7D,D5E07AE405E40016,1C848E15EF14527B,DA4847BFF97592D9,2C9E21BCE151441D,0000FDD63D59BAA4,D7B84672C191EC5E,F0793167F5641EF8,AFFB66DF5C034BCF,92B537D95D289E03,0D8B2BD07B8A655A,C206A12B3EFADBDB,0001B4C4A784C2BA,F44B63B96369A385,CF195BC8DC712FE3,76665BA9F80225FA,8764B3C5400B5893,6A71AEC475B579CE,5BD5F48DD10535B4,00020E09A692ABAB,EFCF26CE68C0C9B1,C27CEA271D875FED,C974D69F7BF52A2A,7C1A2D9ECF7B7E71,6743FE73C8F9A780,56DBED5FFC683A90,0000B8C4466581C8,688AD43A797D0C74,6DF256CF1FF0AAFE,B696466371BB5762,90985A758748703A,1F0F3D052BCC89CB,780AC9D8FDA74046,00013C02237B1120,7434AE2BCC0DA77D,04E16688AB1B1555,1843BB89F78C5337,7ADFD538B3E10656,EC6E762729166C40,B52D6FFDB09DA181,000116D99DCC7BF6,2DB9969A25475946,11234E267F8013E7,4534C989C4EEFAF5,B78674DD2E8DBC23,13C87CB3E2E23E9A,7F7262CA6F63FFC2,0001C0830F70140C,9591C582189350E3,5655D921F5E14D99,5FE29F23223A2237,38DC941C6B005D83,E193C91233855D92,3605D4392B5E7AD2,0001FA62E6D34CFB,0C7DE4DB15CDCB9D,44704A69EEA41F31,7FC700BF07FA5E28,5D61FA6AC409EB22,4033734C53B49E4A,90F078A1818B99C0,00016C6F17B7AF83,0D6C73DF7F9A14E4,A82882BDD2299B06,C55D711CFAD8B1F9,86FEC7D7C06490F6,C9B08CA66BE8931B,F6BCEBDD0999E259,000019AEDC7120E4,5F5C338BDA36F6DC,1DA2FB3044138428,7506A757261CE364,DE8F082CB207BB82,B3FFA869A40ABE55,16032E76B65AAA09,000229A92F293F33,3DD7EBB34CDAACF3,124CC111F9C5B56C,29F3385182726105,CAD5BABEB87AC9BD,91B4A0DAD81A4496,AF07D771EDAC948E,00010BF45902CDD4,A4354FB46557557A,F0A839CE210D6976,47742B7931007233,121B8E746086DDD9,70FA79E8EC06A888,BF9B52C132DDC8F2,0001E67759505122,40C880A34B0BAD26,0847B1C9FD259A3A,ED39541E937F52CB,0CACD945B8B5AF23,D1C0C703C47553B2,CB902D4B90102100,0000D74B2826394F,25D73CE741F11368,668A44B950A0B31E,936D6EC7011D0B71,B47CAFF6F94A226E,85FB21E9B1524403,AA4EB71A1F2414CB,000093B431756B9D,39A5DF70C8F8D3B9,E0A67C2A26D66E5C,A4B64C22F1892472,933710592A159A1F,D0F74685856AC788,A7A285F98245C4A7,0000B0C9C88B01AF,4A4DCF3A437ADEB0,D0945A384AD67351,6338E2A5280215EC,9ED08D1E0645EDD8,5118A311B7618F28,9E742BC8A15AFEBC,00011E94D9CBCE31,B6F7260F0D2EC50C,8C16C335A0788B5E,4187D533017E9F88,7A0285C24F2B3EE7,4861931A336C69DA,40822BDC7AAD9A15,0001B9316667023A,2D0831C265CF01C8,8647FF51B9F9B9A8,EF9BF6CD31463725,1258BDAEED556174,E2680C9B573401D0,B929BD1D9C5D4D52,00023117CE03134C,60779DAF4F64CE11,9D9A3AEA37D1DBC9,49CBEF970AD0D782,C101D76D9C3E2AB0,8ECDBDF6BE660651,61F38982CDFC3BA7,000049E641DF9909,3DF877EDE686474F,892D0F31F6041AE1,95DE46832D8348F1,4FA27A8769B88843,CB362C1961DDA761,E6BC9DF2095BADF2,0001910EBF4C0548,D9D901171EDDC6EB,76D454CA4EA58188,2E1A4B118DBA4B62,1F59E15E3435AEFF,57C071915292870B,2BEBBF71CC803E5E,00014C6DEAFA9A9B,269D2213AFE61828,CDE63325D2DB420A,3CBC0CD731C93E1D,4BB3829613C92480,CEA4E3ED7DA29B0B,4FB35394B2A137B7,000196B2FA14D4D0,7CC40D915DDC4BCE,2F43C0ADA51643F4,998DE241DD076287,28B4EA098CBC9605,44F5E0D274166361,08557C2C2BA559DF,0000861585FF9E24,BF441C5DA6D4CF32,6B7DB418FDBFB536,2FB9F3EFE2445BE2,C1C4FD4E3670D12C,7D9A4156058C38A3,38D72C1235A97437,00019BFB1DFC4F07,FB5D7E397FCA37E1,8437C36448C2DF47,5130A204DC0CDEF8,D42701B210EE3E5A,8602206D2C49E71C,7AF042D155BC5DEC,000021CB090AC055,F82CC93A140E1D0D,38EDDC1A8F6A2749,21C26A115C20654F,03448F4312B8CD47,B74383E301A53CA5,B1420F9A92984949,0001EEE2EFF064B0,AFE964433BE893FF,D4AA932AC981C620,6B690FEE1880CC14,AEB48FD1248124B2,F563A102BED41524,D9E0B499D137B880,00004B45BD575376,5BE060E58E3F7DFD,607DC5AD258A2103,183A33BFFAA7A857,8C5475C782644568,111FF3CF9AD73713,B330D7425903E61B,00016FAB9DFB80D0,F39E3C5020EA3B9C,4FBA36B855DFA26C,38331F719CB0B0A8,DB9420EA58F252C5,4529255376662427,35A6CE922B10C3F7,0000A50BE8FF88D5,84439342C38A98ED,0A98E483FA39F7CD,941E4D2E436AEE1F,C9A5BAD761F6954C,D98DE683CAF1FE03,4A2133972A31DA32,000191C3451707C2,F8951463B4929007,1D2BCF73710BBC5C,D2D152C01D028226,2A8B7A57DDAAF1DC,2718ABF21E6F776C,4B7CD08EE272C95D,0000948E5854837F,2E3652A672CE3B37,F8FF08579BAB49C1,50BFD4948027ECA8,5A45616C7AEE384C,3C6CC9853E9C5849,98F280152B900E0E,0001E6D084451421,606D5E27C884A3C2,640BA774AAF57740,ACCA4CBB219515C2,727C74F67E5A9DEC,78ED71F2185A349E,67BFE0852EB9BACC,000109BB201E7939,621207936A3C01AB,076B64CAE9DFF6F2,211351B70AA126D4,9377C0BF444C945B,35ADB51DAD723C69,05929E31C8225711,0001C2812F844174,60E60866049C2603,4145B9E3DEE77B8D,B9B1605568DAD3F6,0F29721F18769C8F,30A74A0DB5186193,BFBB1E8618CD4536,000059AE09428F5A,77638BFB8EFC1172,8F23948A56937313,489B1B17EC532982,584507B5879AB4AB,D02298BF65C6FCDC,43C553FEB4C98D20,0000F05637A2E6DA,F6E616EFBB25C1C2,9F175EF203BFBDEC,BEB19414EBE54ECA,BDDE40F6AE76846F,DADA0BD88123DE46,19D7160B1C0E14B7,0000128F2F986D8F,8E1E5890EECAE8BC,6C485261398CB132,7E4DE37D8A8B15D6,F210C8E2B874DF1F,52A353A7C4D49F2B,D5F3C5BEBB6DCB4F,0000EDBAE54E0DF6,CADEA7F50624BDD6,F1511E569AD59D8D,9957EB319143C99B,76BA8083F5080FAC,B8C798E5BEB4A189,380FBED1AD9AAAE1,0001F556FF5337B1,B7D4CB9D5EC3A289,B6962C9DC550BBAA,070FAF7620F4DA69,4FC408CBBEFD197D,62F3EB31C964B6BA,25C15B846848BCE0,0000A794C7B283A8,15E671537B82978B,C8F93EA779B2D61D,A11C209843A55DC0,BC97A76E0EE2F027,0B68D7396DBC3FED,9A4938377B1F6ADE,000008FB40E390C1,22F0C49C75B401E5,3B958830ED9762F1,06F53589AF61239C,A0D5FDA566A77AF4,FE740B57AFBE6B29,CD7C8E5557B7F5C1,00019B0EE0ED76D0,D7D949125D41CADF,ED747666A30CF71F,EF37CB05D30B12DA,C5DAFFD6681E5E4A,5AA73DF2D191A97C,06E2492A3BF57B5C,0001D392A5D8E5CC,1E7208FB1A108004,4A158F72EA518CD5,6E3A0BD925DDC469,57DF2F8258BEAAAC,6618B5B6B099C81A,36ABA934111403F1,000215765EBAAAC0,CF90CF78B98A021D,CF8E749D08055281,C2A03263F2E1CA72,BAC660D3509FC570,096257150287DA6D,7604DF89E18EB8D9,0001980788C52BBE,BEA0D78A1AD416F9,1F93F9A3FDDAA911,037678238E0C3776,E52CF324EB93B75A,0BBD3B9359D0C974,D87498AAB9952C83,00019597164EFD57,168C7C08FD0638F5,512815EF0F09ECE3,5FEE261FDF0C4DC8,5026C5F538BE32B1,661AD44646BD010A,1B81A47A9B5BF56C,00017D6E5AEF73C6,2840676EEEA61C84,667A23BE8BD05B17,E69E96C3E1750863,371044929F82D743,F71C905B74FB1A26,FF661F6D58D0CF30,0000ADAB4F930271,A3E7D2FF0BBEF097,3418AB9FD626E998,E0D702853D3202A6,7632E44073D1FB73,7A6C974037D53902,36717A97C597917F,00011007BD4B2856,7EAF980FB28C4CD8,27E9A2099C755B1E,9749A7D090FA00F5,0C3D23AF4A8B1100,D94905081A25C29B,570ADCB990AC7DE8,00002CCCB9A0B9C0,EEE13F58585E9A97,629F645090E83074,394929D19003DD66,CFC85B4F465BE0F5,1E17BABF34A3B997,1C6D0E428D7FACC0,0001238A9FF458A2,1189D1C521D9F0EE,5F99BA77BF461E26,A5B6787334B7B948,759DC916C70B68B7,DFFAB86B121B422D,E47888B90AA22402,0000B1D97CD6F070,11689AF0F1F44A6E,9182F5FCA5F526C8,8B891433ABD380D7,7F0642B49B36366C,90BFF49A9BC3F0BA,C928316D79A5768F,0000B1E02E69101A,355BED08FD7BB9FE,94000E87C8EAEAF7,0603223C142FD519,1589C4E67E08A2B0,60D4C7E8A36E8AB4,5EDDCB0DCBAF8E32,0001E6AA9E72FFF6,43441F661D611094,D6DD653ECF6351CE,52EC1A6E39D5D5BD,BDCD21F126E3004F,42104C7A2478961C,17D339706A36C877,000139B3342D48C5,35D2B8BBC5A1019E,6D84194D7EE2153D,C3C5C1C5017F2077,52AAD05DA55C6EE3,C4308CF5CEBCB9E0,9EC259BA2711E492,0000F05F942757E5,EC1ADC416300EADE,4574970F12D4A873,49C260B3BB18AD94,AEA566B143D38C29,72DF3D8860CF92D1,7464BD9D35034EB5,00013C0CE2C146A4,EB87A6538B71A430,DD99F9847F0B2B87,B980C42B103249EB,A96E0E5C0D9F88CF,39D7D9BB6E5FDF35,8CB548AD7E218B2E,0000F03901832F4D,B659FE9BB927DC4C,94F02A04EA1224A4,93BE841E411A4305,B87A814CED357D9C,72F1ADB8758F2FD6,34A3EB9D278A7888,00004CDE0DF95E3A,4475D9BB4042E344,FD5EA9272A9375E2,78E8DF894A22A4AA,D93D22995655090E,552FF88B55653A69,972A15474FA4B6AB,00008190DD6DA589,C937818F072C4C88,24FBB4B7D5B85C33,D6F9C09443F80D13,AAF9B4BA381D70A1,9EED0D779B175710,94316E84E1B9573E,000210F377BA8743,F24FF57223A1F761,2B8E2E8A817BE364,9C0122BA9E342EDD,ED4AAEFAD1619062,508C3400C0BB73BE,B5613374714A2B28,00011625C484A29D,180A52CA60EE16E3,85D88FB3D4E7F9BD,751822E2749970D7,8F141818E576E6F8,D8634FFB003AFE7F,4A52142BABE21888,00005B7A8DBB0702,4A9FAE311B872277,5053C5AB0E35B428,EBEBD7827E9FC29E,0C4590ADB12F24BD,C30F3B7E37E27135,A5C44D8D9DE5C468,0000556CE81AD2DD,36066EE3D62C212B,FE1EA5D78078EBBA,3B7C86DB8D7F7915,0EEE231ABF631217,DBC64825272BD839,530741801B3C91A9,00013A9C167843E7,C46BB040620BF5EE,9605392771578746,55E0FA1FE15E595E,775217CDF523B7B5,0BE35CAF2EAF3EF6,FE5710BF1A5E30F6,00014D066107DB1D,028A73813110F8CE,0459A2CB2B8F0600,B394AF578D3FF64D,1D93568B1A08633C,17EC24587E77CD7B,E5D81083E937052D,00010AC95DA87556,532CDF6E3FED03C1,DD62CAAA9269E049,AE4EF2F5A329318C,3B2BBF2A55CB6DEB,0537F1DA82896B20,015B2060ABEA734E,00012784F9F084A2,10F944D5347C5280,998C70B87D759DBF,82665F73E54A79B6,AE079975FD435FE3,974D05010F2A0254,4025DCCA0AF3554C,00011051B7F995B2,69A277BE7045C53C,0E65A54254A92A66,2B2D4DC2D8FA051A,71399E41D23B328F,158839DA8D7E3EA6,160208393612030C,00006260B1D3D771,39794B1BF29D1909,C7A6A2E3E1AD841E,D3808657789020D5,0C8E5833C2A22080,06A28F58AD598B36,F8530692C128E474,000184EC50800DE3,2AB5865EE64510BD,3ADC5A8820AAE1A7,A7E33A72795BD704,1568ECFDAD0AE541,9B4D54EF0F4D073C,DD19B2ED4FAE6FCE,0000FA966EB18D29,6DD153831B23B6DA,9205B27A5B86B2B2,59C7EFED84131878,60A6B0B0BE13E104,573AA91138F30A49,8D0102053CAE2681,00010035F7845622,1D5A6B5240EAA614,8E1382178DAD0CE9,8DFB211A42272121,773B80357E863913,CD54007C11571ACD,959B4A7A2FC52B6A,000204C19E5AC9E6,FB63FA0A9D0B7A49,3813EA3725BF80CB,5C0DB1E25B43E35A,08D9302BC3A7CED5,9C4EF5D38BAAC458,56527E9FE07A2459,0001A060D4241E2D,ECF6A91292689E68,20F3AC188327427B,A4A3270566893DDD,3D648A71249B0F05,A826195E22C0E4D4,7F666BA1DBFD31AB,0001276F98A29A71,8B0E38690DC88C07,CDA0D6DFEEAC7390,3C8D9E147FC761EC,F06CB113B0AD56F5,9D581256B9BFB386,7686CDF715219762,0001780F87A9C0E2,A0C5F70AA604E6AD,D5AF3C9A7B649B03,08EF1FC237FBD7B8,5EA5111E35D526BD,2BF16C5A99B76779,065642210704DEDC,00007452CF9B9D9E,627B4BEF3889BB26,D36FDF72F8CF1CE3,DE7C5E550CF8D086,120E7831A48E59CF,4554195EAC5779D6,1B18C63E1B30DE1D,0000D34495BFEE3D,CF45A904E91BCE09,585D386BE3119EF6,AEE6292C30FA8B7F,698D0A8AA447F6DF,A7452E45B26EF81D,A01CC28ECF20989F,000080F3560E5D33,DF9DA4CF31D2D60A,DC22C680CAE08D06,09EEB361FBE04A3B,7EC878F235DDC11E,AE987EBF22832D29,E8455E68EE76BF6C,00001A738EF06AEB,21C67B7EC90FFBFA,D90B0E8E7FA9AE95,044E2BB66252DCB7,2F63C5CE0A385C7A,0DA41BB6E0C1A0D3,B9E081DF7F378A94,00003106F0E62F19,A79A2527B7DA91C6,92F2CEED95D707DA,07AED6E603862294,E832521B8CBA8F9B,910C75EED2C825B2,F3A7B9322214A3D5,0000EC76811F770F,A9E6F9896BE6C8D1,4FA6073E82281AA2,64FD58B90DC4D435,4551B52901BE9F27,DEB82327A4296B7F,680D883F6EF91FDE,000170E3A06ACC3B,B284EA1F67C7BAEA,1C5869259894F879,62F43BAC11507FDF,C0A2CDB6096CFFEB,B80C89ADCBF38FE8,CF67432187251709,00002D74ECF00FD7,E084247F403EB4B7,427785CB80D65A92,DCAFFB9401D25C8C,5C835695880B361A,E95FA77E49CB9988,514B97FBBAC3A4C9,0001E1DE0134B959,66C58D3BE396F341,2AF6EA7788C46069,3B6541B120928060,8AC6D64E2455E268,3AA9BDDB8B766AD4,A1B2F575457C8272,00006EB75C37DEB4,EA95302133114F08,DC4617102CDC64C7,060C456FB372BE44,B90DD6D56DF6CD41,D23872BB18FC1A3D,531D9B8FF3CCD9E6,0000DEFFB9A976EC,E3009F8B55BEC82A,91A7E9257880CDD1,4BE9E288673FA852,68ADD3203C2C1577,E29EDF34F207E2DB,D3898B444CEA5477,00014B00B3B03B36,6A9357E9DF80FEA8,DE1804456C09C7F5,D1F65385B82A6CA1,487F5C8D48042B38,34018BE8BDF29CF9,14065DD162E01CE3,0001BC0430B46664,E5A4C0223A7E2A36,2AED26C535019DC3,2B9118EB35000BB0,2293E9DB0D8777DD,CF5CCD0E590261FE,18A53BD77BF4BBC7,00019F450C42843F,B3CE243598353115,B394420E270A2E92,20862B9521AB6389,9AF51328EFD30D85,726660514664BEFD,FAED4162E3ACBBEF,0001A22272FD322D,B3E8E4AAD70E2479,FF683DB32FC93288,E5D4AFC7F16DB12D,8D963521F4D20765,6A14913AE8BB6A68,614FD14F3ED18BC7,00013FD9AF6118F3,E9BB5A6ED9729F77,41DF3DCD8397A1A5,8F89193D0AB2ED71,61C66ABD4B21404F,221195969AA4E05C,FBE0D4E7821A3AF6,0000839A9C93E018,6E64D43A15947672,2F2626F68E0C2613,555AF0E146EFFABE,FD86755FCDE2AFF6,F63FAF17A07138FB,93A35E894175EF40,00014ABDD39EEE4B,3BF383BF1D3AA573,07BB9A79B7AD6314,64178F71EA300451,01EFBDBFB13D75B1,0DE1FB519946244D,F7BC99F68EB8DA74,00017299CDC313A9,E500085387FD8F0A,010737F09D8E1391,F4C574986AC443E5,EFA2F01E1ACAFE00,3578653A0CE28CCA,3B41DA89AB2FF7EB,0001786493C08C1F,D7356292AE120CEC,93653B1A029701CA,E76F82D445443E1F,6D61703B496D2BC7,54457F15C8ACB9F0,1DA8288F48FFCB8D,0001105F14642209,0723556DB4AE3F8D,03A061A967FC00EB,5F84F34A176EA7C8,013E833DA3CC0841,627D4459816CA516,E8EB5769190C3702,000083AA284AE112,03E6267BC774B923,5277030A4A1239D3,3A0030370FCF05F3,C6621947968A0D6B,628FDEB8AB66231A,29BE3F5878401799,00011DF91B775429,0F44E86F8417C7DC,42787E2414C678D6,D2D5BD0F109B4C65,DE535F260C70D941,9310BAC5DC84037C,148060B7840F701D,000106C65A4181F4,EE55B957620CB5C1,55E1166F0B57B7D6,77A405BF51CE4F25,3EB1349410E014CB,E25AD538613BD115,52FE81D84C2470E3,0000982BE4285B72,9C865941AEC9AD25,D9DD6942F1538C8B,8CB3A51A9CA9473B,FAA9FE4E18265FD0,5DABDD06C4C50B24,1DB098B9A76B1632,0000800AE5A9E529,1BC707105953EF09,646E416ECF160E46,1AF50785636CB7FC,BBB3094B88AF9DDC,64EE343627235580,121A81C260B1DF31,0001C553CA56AE57,AE7FE94786A4C494,BD149244C10C0148,F5F4C3112E7008C0,CB4FECDCDD695806,E02718E4B9092EB6,B14DC9ABBAF84E08,00001221DE60D111,48B2DD458D21C58E,4FC2EF2E46305264,BA6336E2B50DC468,2FB0106F3FA5FB3F,E87BAECD597BD335,BBB0EDFF19A0C876,0001EF2ABA4C7340,D5EF7AE21B9ABEFF,80A299F8608AD207,CDFACAAD71ACA129,6D67A4EBB3E13319,6EF921E4507BF6D7,D7103C9E40CB1519,000128FEE9E919AC,B7F5A65DCA063AB0,8AD8EB0D845B15C3,2992D04893C7D982,3A4FA3BE64830D60,389FC24092D6E4C1,A7918D68BB357EFC,000194E1903D65CD,E3B916CBDBD39506,58A4B4AFA78464EF,4BA018E826F3105A,CB63805393E0DB28,772B24965505BAC0,9F4490D66B71B41A,00009D0603560CC6,0589B15D879D1BDD,C5757CC100B06F9E,560603E1B5CC688F,1C53AF49D7C7F7EA,2F7DA4B1E0FE59C2,B7246B158AEA5BA4,0001C5C3284E3A1D,5747CBFA67FB0BF6,BDD96F538500B095,3B031FDCC2B4667D,21614CE2B0A27969,0A12325167CE5ADD,ABF08DBED3BBBB2F,00016610954F9E23,A81D391B48F4AED1,5B2EB16E4E73831B,000B75C2465BE239,19D38A17F93D40A4,62FFA5F216D79968,0DC8D25F1A4C4AA3,00021A6C55FA0200,A067665D810878C4,F08C8F61B896E7F1,38876433424B3563,65E81A5D0ABDB9F3,1BA11DC5D7449D93,E2609F60380E6505,0001DE0F8C286776,9D2ED0B9BFFDA9A8,7280F663EF99BF97,5B9A9684A4230E26,45623485877112B2,20D34CCD8D34C055,A99FAEC806D400AD,000094F218C148CE,35320879258D281B,B9BAD39419393798,BEC1F84599E93267,0AF7D33B4494A6AE,44D8FBE144675DA8,162CDAA02B9199AC,00004D1282AB93C8,47DCBCFF51C1108B,C7BA4ECFE1B70442,5A69211C6A2F4999,D02158C69F7C491A,9F154D72D4E7E927,B4780F6EB64438F2,0000F2D3CC4BC008,C585C31ACDF75F15,27AEF5C9140170B6,EE19086E5B6D0FC2,459FE7A758AEA172,464C922A87C7AE8C,1AAD2756DE22286A,0002058561DCF1D7,22D33C1827F0FA12,A972F7AB4E5E7DAD,0A18A447BA5560CE,0FA2846360AE9B3C,40162C7D1730E5D8,EC87C83040A13683,0001BD90BC4B5C5C,29FA4C5DCC44608B,24DAEBC77417B7CF,4C253DC60E7AB933,0260CA68A4515CE0,192996D60DA8F59B,0A90103BDED2D0E1,000219EB679D9A17,17AB8C3C0D3A3152,2A00D6647C8BC8C9,C274BC857AABF6D1,DE5D622A78114CED,E1029D3E448A5F4D,2680532FBA77486B,0001D88034DEC60D,A94076878F5DC53D,37EB828ECE9D23BE,AD3F6CBD35639B4C,0DF32276CF971921,D90787E6025C608A,F7038C9A82996366,000102DE083D9254,2400E370B7729B1B,26ECD7FC92F71C71,841993E12C5644A8,691D65765393CC28,4A0105CEC34EF466,65B4B79219DBC296,0000B1C0757CAB50,14A969BEC5DB1A59,871FB1862F336291,0907B04C14A86C72,657488FE38173755,9970D26425E9A739,4533E0AA24CDAE32,0001F75D331082A7,5B26601583C13C5C,0E09A5165D719A7F,AD8AA538602B9DE7,1E4D4579CBBFAB8C,7F3461C7638FE52B,5DAA64204AD523DC,000145A69699EE94,2D5075833158727E,896551ACB849CE79,A681AF617647F788,1723B5EDDBE45009,9B5854E0EB1640D9,D62688D00D7182BA,00019BA6EEC7E1CC,077514AC85F8FE7F,B1809AE785EA2C68,06C6ED5EABC9A5F7,070674BDF0E7404E,D56E93EFDDE8CAC9,2417F53265519D4C,0001114DFBEBCAAE,1B1FA3A4C05C2E92,1A828F0C63D0C314,862A472BAEC50157,3736320CDEAAD20C,96E9DD3B0F1136D4,9C3B665979C3DC81,0000BA7257F0E70D,CF79FDD3CD205172,44327DB60363A751,BB823E50DCCEB37C,1D7F17F861449549,42A182EE2558B6B4,2D2CB0F6D9C70974,0001913675156E90,FC2AD0CAE142EAC8,F3028E6768A050DD,9FAC46D3CCCBC00D,042051099504F85B,6E5E01D26513973A,E08A22090462C3F7,0001FCB27F6F058D,D442A2710D7279C8,47C9353107967853,3186B539B65ECCA3,2F9040AC3FAAEC11,FC81BC15040A0242,33421E047DB53C84,000181EF4D06E884,5AD2B639D609EDD3,CF707AE8328321A0,FD0EB9CDBB3E9B67,03DCC84DB2747F7E,788F99E1AA81E624,89285D9EAD58FAF2,000100EE7BAABF21,9ED5BAD1C958A533,08ECBEFD2F7E8004,02C51E8D9FF1986C,28BE4F7E03E8F96E,4E31D4A1E2E19C4D,E13532B544BFFD85,000063807C8EBF63,CBA318968A0080EA,6E1EA446FDF32F6E,3918FDEE0945EEFB,7395E3591BED04B3,9BF369DF4E1D1F68,20B04F1EDA6EC7A9,0001F65E0BA40D36,A30A39CEDD4A222B,FA4283DC48E5BA9A,28F21B66EEDEA5A7,F281B97309A457FD,CE8146C6C9506F0F,F137C2F24953699C,0001C832AE77E493,10D1C03A6D49BC4D,FBED2EDEAE19ED12,2300FF1D15A1FCE5,EEA2B1ABD907BB86,1B749CB24E5DF0D7,7F2B3B838935CAC7,00015CCF8AF3C88E,8957207CAB35FDA7,3F202E983A7C2251,F84C77733F94A993,D5E9BAC3F2480FAB,2AB0A873EA9DB538,22279784D7692684,00003E9DB4C486CF,004E48DB2718C189,0F22832BC2DBD319,1014B3D4C276F007,AE0C8B5E22B206CC,94D40F9081FD4286,7BC1F98AC603050F,00022D2C55CC94CA,CB6B8F9D520E9D80,E539AB381B667F8A,249202E9866E1249,F527C91DA98D2C27,AC19181EB83403FD,CC88C5918696F4A6,00005001A3D48F32,4AAD16DDA72E0B3D,4FE27BA2AD11DB48,33B1070F26174171,7C301CB1AC90C1DB,261244E5F9079EEE,E8FE75871A7C68AD,000044A1C4ABA16A,11676A8DDDBD0340,5CB2C0CEB9AFA00F,DACF20980C55013A,3072DF6D1397017C,CD8FD549DBBDED8F,52AECF1796CC84D3,000049D28C2E88AE,B65B1735CA655C4D,6F76CCD8558A35E5,4756098172764FAE,133672ABE7B8AC79,A77420038C2DF576,5C8602487789F5F6,0000CD45E977BA33,4405E9F98CDA4908,7CCCA71AEF54E06F,06CFAF82FED48388,BFF533C830EF401F,35379607CB533986,4312D54C6C5ABA66,0001CB73871DFE06,3BD9746B54431F3C,82A5240D55F89DC4,4A1A73BB64F9B140,20F82C747F685C92,C19FE8486FDED4FE,2203D84CB49CC0CE,0001E880FF73EE6D,C0C1055035534E38,6BF0F508C87BD876,C78F9C503C5EEF6E,D7092C550FBE8E50,750D9410A1E5619C,AACF3B982D1CEABF,00003F8C7931F23A,68B429BAD6B2774E,9748A385107A0501,E8C1C619F4E25A52,11C290A2752B1858,F03F885523B1325E,614F000D3A10634F,00011A786BC97D6A,9B3A5EF04A5AE789,C560859153F5E0D8,E0CBAC4448FFDCDE,28E77ED61B6E805F,06D1A53063B71CD8,BCB2A1656BB817B7,00004249D8400C62,B7FA854786AF5AC0,07A5DC8209E7291C,1169AA6E93471504,6F86598C111C882A,632AB04739CE3699,DE9876A7284C1D84,000084269C032152,5F8B038957660A8C,2845430517B568F7,8ECFC5848B09126D,07FA5CC4B07ADF64,8C729000AD353D9E,5C32F17F662D27AF,00008BE8097F6AD6,7D89D3929A3FB996,073895E614D1731B,69525E899F54687B,D420758D66EF5494,DB58FC5E91390710,B5137A7326DFDBD3,000034DBC48E8154,D214787A42B34E0B,5BAB3A90CA91799F,66AF1457F338AE10,E34D45E593BA63CF,4629FC74E87A2409,C9C511732392B012,0001188E1D7E9A74,A02F0C97DFAE7E47,B637B49189CB0814,C3F74B323BE03840,B31534EB340465AD,3234E3EB38BFDD68,7DC07CCB02369028,0001F414C8FDA45B,BBDF17A1189F892E,E36B701711EBAEE3,9246EB958653A11B,83CDF571CC3ADD4C,2995DA9A115E2745,5E59E02C5DF39A62,00006C681B957EEB,D79C7A3713401C3E,3C15A60271E5BA08,5A75226D8E7FE905,D133222B3A45B328,AF446C79B7610870,3EDCEBFDC33B0E46,0001E5C107CD7990,7B89CFDF854F487B,EBEE5F2F24618E2B,75A442065C2CB258,73C059841B74E5E8,67AC618123BBA529,27580ED44099CF33,0001C523C646E1BB,5548036B6B86B283,AACB716B6ABC7050,89CF0F9F1F6552C0,9A665F8400D87BA4,84D2AA1F1DF63636,6CDCEC2BE880938E,00002AB398292840,2B94F69AAD082CD3,B13850F11C95D4E7,E7192BD8FACF99D2,7E9D90C86D4400AE,32AC85A534E2B4AF,B91249979A9882A8,0000B6295FB3D086,84EF739E89074420,F7756424F99DE4BE,4379E183A608DABB,7DBDEBBE169AEF00,BE1665D536F68CCF,E1CD3876BC9C435D,0001055E38120373,390D402CE5D3DC44,8CFA0A3677B6515F,5B5D988515E05F4C,69F9F742A9C22D90,8E6B864D6F3E299B,5347C49B541CE666,00000ED5A3DA86FB,F6DC78F623D7E6F7,F6222F21867029C1,58A4C0701A4B488E,4E3B8B8547AE74B0,D5D3C557DF93FFF0,8846F7445BE15891,0001795E70C5F6B0,EC33500459DAEDE2,FA19D820518F3376,B73A6315501F729D,90B0F2390AE91B33,7D7DE108A2D5305F,A731403DDD7DB5D7,0001E61328D3B3A3,9907AE5C8C7C09E2,829A77D65E771750,EBCB0DA23A387DF2,C554C6EACC8C41CF,5C6FC6CF17434CDC,8B9AB73D5E274CE3,0001D6D62BADC253,75FC836641BC3BA0,66160AC7D263AF87,F272A8ACFEC28D22,29AEC47D8B0F2B2D,8AEDAE0C343E97DF,8F4D42A7272DAF84,0001024177DE4DBE,F152430FBB0B1DBE,E3568C1C356BF46F,1364FC57DF940142,53A0739714D93EDF,0A7E14F8906B19D5,84C8104B46A7DD44,0000DB2434BADA3B,1F3F7FE37E16E784,8E4743BF96285B45,CB2146A4B91A2E18,B3EAB0B7937035DD,96FF028F37DEFFB2,187B521A5CBDB905,0000C7786821C584,15D2C69187FE7E9B,5E1E586E1C413B8F,377A2CD34B273EE5,444AF3ECD606D007,448C5CFB70FB3AFA,A77280D2FB06E05F,00000F2F0B9DD6B2,F7A15794731CA711,1DA89839EBAB4015,6A628685D8AAC42C,68ADE67B3E83DFA8,DEE7A96D338D637A,BAE6D774CCB3EEB0,0001CB7AC39710BD,B18E188A83606185,19DD500E793EB5F9,12C76A87E568F3A7,568D47E6FEEDA55D,E7CD608C95E2A322,31C5EEAD9A5A8DDF,0001D44A00359883,BB9629B9F11E02B2,871EF19A1D125468,6AE239228B48B4F4,6AB3A7C2C690FDDE,58749FDB9E9DC64D,019F6B937A2FB5E4,000134DF49A77166,7C9E71B5088BD450,E377B6299A84EC23,B283FCD8652C0821,9ED4A93C9A53B760,D3895089CBB76193,248C2AB502D79774,000086E9551D6334,4CDE82E4D578720E,897CEACA236F4406,D47C0EBAEAE4154D,F65FF050DA8B7E0A,078660BFEC5B21A5,98F50C69F901544A,00017B78FF6A399B,4E1FF36CD7E657A6,ABB7C9BBBDB37F28,23967188A4B2E87C,D5F12C0E14AD5D4F,AE8217C059F26235,18215528BFB615F5,00017D9FFA6E5F1E,8F3EF16B6462AEB4,BB37519662D63BDF,D74C619945D19BBB,1F802B44351DE23B,D7D3D26D97C6642E,0045B6B0644571C9,0000376A39B9CF1E,A6BE7DD4152463F6,684815D16113586F,0ACA6C2912CD33E4,4A2EE4DDAC35C32E,238BF66DB232AA57,E78EE0AB10B8AFFD,00014D1A8692A152,62940A3930B9750E,9FAB4A381E83B99B,3B4349F3A96F3CA5,BDF20EABF8279605,69FF11F9497B171F,B754B8BE488D1AE5,0000A126632841F2,A1D6E2C81467F02A,6787FC23330482B1,12C08B821649EC27,27770AD80F13E3D0,A8482E97530FA1AB,2A6B9482E37BF91F,0000CD9C8BA6CF19,CB00E6CD755E2339,F28E1D920152F636,EA6F07B885ACD928,802F25F50676AC51,B8CE8BC8DF3FCB48,4B50101647FA93D5,0000856A3D3F007B,C1A591DDECED3709,BF70B66A6AB2638B,CE7F185ED93BA38F,DBE994643E5AECE9,A492AE884E240DB0,87AD9344EEAD69DF,00010E9DBBB4E870,47F1214544F1FDFC,26C218639D0C745E,361A32B9DB65AF82,D582A03B1CE0BEC7,D4895F190FA8E4AE,7A6EC93531DF50F0,0001A91214205262,1DD92154C952A9E3,07253E6EB1F5DD09,2950BA533570EAB8,B4F99783D14D82F3,FA8DE285BDAFB52C,621CC3C8DFF26687,0000C1236623F3CD,A28066213CFF86D8,8519BE9066E70EA9,ADA3B90C9C9D0822,078260120D02319E,63456744FA182ED4,B0D8F625E224DB95,0000AC3C875FC878,785EC3168B24B327,A652B12B6F4863CA,FE9336F4BC8B2ABC,449DC91E15F6FA6D,565C4F0DEE478F13,9ADEE49B0BB957A5,0000BF4841C7170C,261266AEB6489F86,70F47B3C026A7CD7,D53F719F592D2695,C8EF9E057CF90CDC,207ABC26FBB82D57,5F34AB5AD3B00CDD,0000FAC95A6BE005,2880FCA6BFC771FC,E8A1ED366C5EAF41,26DEC38C89ACC9AE,F433245E87B28253,ED43C4B08B4E1835,C605E763F1368AD7,00015274B28B2E38,768B9867C45D4BC4,4D682CC1A9E19CCE,1F015815A86514D3,9801C170584526D2,AF7C9183EA0ED04B,012FC4454B033E85,000122D555B3EB2A,AF3432BF24DD5D01,088931E27357EA51,B4BC4DEC5765FFC9,BAB5802D1F2DBE30,77945CF510624591,DF905FF2B98F9D53,0000C541ECFC19A6,D3CF88CEDDA56BA8,B611D9A6A8622C83,19986B1EC1D394D3,B45D8120DD6D0E2D,4DC51083A59F29EE,DD31431E3A000D25,0001E1A8F196D140,16EC5885A01EEFEA,4E449BDA055D1DDA,58F2FA8D2B55E29F,17B02F3EDC4EFCAE,50582C76E701EFE2,D4114A56CFA73858,00007FE05C9B4776,7B69B57C0CD4A1AE,11723646A501876A,6221F4F809449E57,03A5C8C953FEFDCC,74B91C97DE053B8A,5E7673BA3120D0F5,0001218FDE7C33D4,FFFFFFFFFFFFC5E9,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,A1397C7864FFFFFF,0FC589FA8688D839,F86335AC52097FD0,0001BDA7D338DBD6,BEF0CE72B6E9D1BD,92E0A4F2CA7CCCFF,A0B2035BB47215FC,6D36985E0F7DFC52,6BB989478F1D3A0F,8C5988BFDF5F4F7C,00006E2AAF9B9D9E,425529A64ABCAC1F,49734E54998F89B6,9C429949C1DCE97C,9BE2625E5A7B4023,07E239939824146A,B15C34D4A1653801,0000672443E98A7A,18D5AB42DC1B2CA0,71C6EC0E867DCDCF,26DEAB045FD561B1,45B3BA1D5BD767C7,0ABA0A9E948A246A,A721BAFBE893B610,000080697B53F1E1,AEF4EA78C6BAB2D4,8FEED1FA59A392FC,388326919250140F,1B94EB75B4BE5DFF,5BE9D0EBCDE6C767,63006B60E4B989E3,0000A140AE748A84,08CEA2016847486F,C383BC14A70F364D,2F2963663C26BBAA,342E5B2BD6F661DB,94F684BAC65F5EA6,91E13307F205794F,00015C3EB457D0C5,15D9717B534B56F9,57ED5C5F28EEED33,0AA224149D1792C1,2B663432FFF290C3,65B645B7893F3761,8C45450423A64BF5,0002072BDFEECFDF,2E9A77227F6B4DC7,26A6145E0CD52870,E8E7255BCCFF6551,C04097B01E64680A,56B98EE30BBE9A40,F3BD5AE69AE90DEB,0001ADE268AB0C0B,69C81B94AB88A2F5,52881065DEC1BF2C,D81C0EB80E03EA8B,042A15D8FBBB829E,2ADC2AE485616A64,7000B77296196229,0000B3B37F2C686A,8392008D794918AE,EBDABCAB9B836E2D,279BB892BC901E72,C16D3DF36FF6DB3E,BD3554E2019FFE83,AE5BB534F18B3147,00004E8CD30C178C diff --git a/core/src/main/resources/org/bouncycastle/pqc/legacy/crypto/sike/p503.properties b/core/src/main/resources/org/bouncycastle/pqc/legacy/crypto/sike/p503.properties deleted file mode 100644 index 8cd4e76acd..0000000000 --- a/core/src/main/resources/org/bouncycastle/pqc/legacy/crypto/sike/p503.properties +++ /dev/null @@ -1,50 +0,0 @@ -ph2_path = 0,0,1,2,3,4,4,5,5,6,7,7,8,9,10,10,11,12,13,13,14,14,15,16,17,18,18,18,19,20,20,21,22,23,24,25,25,25,25,26,27,28,29,29,30,31,32,33,34,35,35 -ph3_path = 0,0,1,2,3,3,4,4,5,6,6,7,8,9,9,9,10,11,12,13,13,13,13,14,15,16,17,18,19,19,19,19,19,20,21,22,23,24,25,26,27,28,28,28,28,28,28,28,29,30,31,32,33,34 - -A_gen = 3353B596D45A95A6,DF7E0A94A39B96C0,715DC90A72A3223F,CB73F56E5AD9430F,E4B5DA591AEE475D,322F1CE730413BD7,4EEA4028D168DAD2,000B254087875FFA,AC3985C5BB18D89D,45F2445C680A1E40,F59454B450FBAB11,95DC27D8152A0DAE,42A4FD439715E500,B958FBA1CD4CC505,C4E5AB2ABB732FC5,00268ED322F62ACA,DD27E5ADF7F57AB4,7C1379D2B09F0434,6E267408F1C8C89F,C3BB383C07B60035,9268C9183A95ECD5,9327EC043E0F021F,E63D2D907A9DE5A5,003110B6B4E0CD93,40B6BC5F5C2675E6,62AD4B61EEDC2C5C,A1CCA6B5091EF540,C6273D4E1D8FC7FE,266D8B99EE63A78F,39604E6927906566,AB8BA8F2C6A977F8,000CD759EE7AB739,1482EA2C7A8F5FA0,B42C8B9C007E5FE5,CFCFF2625C69E7FD,8334C3F384C268F5,D71E78E25FA4DB2F,64BECFBE41708879,00103FF021EF7BF9,002695BB8221E83B,0A08787E922A1030,8D34581F64BCE547,2FA5BED41306271A,EC24812ABD206DCF,978FA888C3CC6366,2BFF991CDB7CE058,A0BCCC1A447CF056,002425429A072D82 -B_gen = B810321963CF561F,ACA612873FBC647F,E5C29CB78215B634,B277ACABE764F907,76DBA8FCCDFF4721,1B4E6541441EB543,DAAB92E8B2DD0517,001ECAA65407E4C9,F7EEE8D8D30365E6,48F0AF97691E0303,A8AC75108BFDA627,07C0F65DCF8450F1,CD74E9CA0E92BECA,342E232149CA1DFA,8E841EC6D7725DE3,002429A4E9A12CB0,B810321963CF561F,ACA612873FBC647F,E5C29CB78215B634,B277ACABE764F907,76DBA8FCCDFF4721,1B4E6541441EB543,DAAB92E8B2DD0517,001ECAA65407E4C9,081117272CFC9A19,B70F506896E1FCFC,57538AEF740259D8,A43F09A2307BAF0E,45937210137F28D6,E76DD3A731B45FB4,D1C1A7F7030546EC,001C3D5057DFF16D,6E3DEF7C8A5A47D2,12D9AF90F92FC868,CE33D50FC931894B,2927354E05ED037C,4864AD1D8B6E4E56,2C6BB7E4CD4284DD,50A30A93843DDC28,0038195667C39958,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000 -XQB3 = EE99D64B76EDCAB8,24081A5326BA0FF9,2BCFD2861E3D63FA,A0964C6F4D7EB493,171019237F558103,A19A27B706871B49,ECC7384313612D3C,000A3EC9B9537811,A7CD1086A7F15A87,21A78B0FFA3920DC,BDBDD8A49264C6D1,925A193B79F45BB9,D3E14C9F15E21C4E,6A218D16356EE2CE,9D0D5E4AAA37DE6D,0017C49B586430A4 -A_basis_zero = 3353B596D45A9D99,DF7E0A94A39B96C0,715DC90A72A3223F,8773F56E5AD9430F,9943B35C469A0526,B964613981C02523,043F68F92C55B886,0018B5A8D224F483,AC3985C5BB18D89D,45F2445C680A1E40,F59454B450FBAB11,95DC27D8152A0DAE,42A4FD439715E500,B958FBA1CD4CC505,C4E5AB2ABB732FC5,00268ED322F62ACA,BC88BB85404378E5,61071195BC44BF8F,C92D13994CE9B8B3,9ED615392DCF6CA2,C4A95165FB25BFDA,EEEA8545EBEAEC62,AC09C1C3E91B41FD,000B43AC79A90A0C,E8B38A79E90EAADB,840B284661CCFC39,06D5091432C311AD,0DAFBD9CD646033B,3FAF77BC98339AF0,75F0C7A7AA5D03A3,D188DA98DE124C6A,002780B2B7B1C9CC,DD27E5ADF7F582A7,7C1379D2B09F0434,6E267408F1C8C89F,7FBB383C07B60035,46F6A21B6641AA9E,1A5D30568F8DEB6B,9B925660D58AC35A,003EA11EFF7E621C,40B6BC5F5C2675E6,62AD4B61EEDC2C5C,A1CCA6B5091EF540,C6273D4E1D8FC7FE,266D8B99EE63A78F,39604E6927906566,AB8BA8F2C6A977F8,000CD759EE7AB739,986343072253CB59,675F6504D2978FEC,A0A52D48BA2141EA,623302893A18D8D1,56B48005611F5B79,E398D5F901FB591F,E5A41D9AFCF35177,00391CDEF0EEFA35,E9B1DB43D63D7EE9,8BC7B3CEB5A89BAE,0C0DDDEFB4D9CDCD,B9873A36C1B0B949,97FCE091A32E2501,838C61141A0FB449,A4B61F965220A71F,0016978E2D5FBE08 -B_basis_zero = 4256C520FB388820,744FD7C3BAAF0A13,4B6A2DDDB12CBCB8,E46826E27F427DF8,FE4A663CD505A61B,D6B3A1BAF025C695,7C3BB62B8FCC00BD,003AFDDE4A35746C,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,440192590061240E,60C942451EC3E20D,2195638E3B7632CA,BA84AC322AA59D16,3751CBF97048E02D,6A583E4C816EAC44,7A984D4F477762C1,0027B5AB2E503D63,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,BDA93ADF04C777DF,8BB0283C4550F5EC,B495D2224ED34347,C797D91D80BD8207,14BDF59D4D0C4184,44E8550D8B58B719,E40A10924AABA412,00056916F74BA9B1,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,440192590061240E,60C942451EC3E20D,2195638E3B7632CA,BA84AC322AA59D16,3751CBF97048E02D,6A583E4C816EAC44,7A984D4F477762C1,0027B5AB2E503D63 -B_gen_3_tors = AA6FCA1A7DB3B9C1,8D12C496B3D530CE,909089D6DB66CE9F,026979B12182E911,D838DEA96EFB14F2,C70C12A9DB5E8DEB,BB4D79F4A6E1AEEA,002F6E7532C0487D,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,565D24EF17871BCA,5547441AA7195322,ACA179D99F24388F,F764EBCF575D78CF,6890A45614A3A134,0545AF60FF4DCA38,4730B86C7FC40E22,0025DC757FF39EDC,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,559035E5824C463E,72ED3B694C2ACF31,6F6F762924993160,A996864EDE7D16EE,3ACF7D30B316D2AE,548FE41EA01FEFC3,A4F84CC93395F5E5,0010F8800EC0D5A0,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,565D24EF17871BCA,5547441AA7195322,ACA179D99F24388F,F764EBCF575D78CF,6890A45614A3A134,0545AF60FF4DCA38,4730B86C7FC40E22,0025DC757FF39EDC,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,A71C6ED6210C87CC,C8DFD8D415B8B348,6F6F7629249932AF,4196864EDE7D16EE,367B30E71EAF8BE3,880DD782D08D9134,0E6A3EACE9EDA18D,002542106DA2CDE1,DC6CDA78FBC6D660,00AB35FE4E0DB497,4CD08BF7B90D948B,DD38F40AED30B440,5C9D9A2A66152FA5,8143357E694594D8,4331EA627E400226,00274E4E416D3346,239325870439299F,FF54CA01B1F24B68,B32F740846F26B74,CEC70BF512CF4BBF,B66AC1AFBBFCB7FA,9A58C14A1238E8D6,1D13DC5B5C37A2A9,001918A70013EAD8,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,58E39129DEF37833,3720272BEA474CB7,909089D6DB66CD50,6A6979B12182E911,DC8D2AF303625BBD,938E1F45AAF0EC7A,51DB8810F08A0342,001B24E4D3DE503D,DC6CDA78FBC6D660,00AB35FE4E0DB497,4CD08BF7B90D948B,DD38F40AED30B440,5C9D9A2A66152FA5,8143357E694594D8,4331EA627E400226,00274E4E416D3346,DC6CDA78FBC6D660,00AB35FE4E0DB497,4CD08BF7B90D948B,DD38F40AED30B440,5C9D9A2A66152FA5,8143357E694594D8,4331EA627E400226,00274E4E416D3346 -g_R_S_im = F74CEB25BB76E955,12040D29935D07FC,95E7E9430F1EB1FD,844B2637A6BF5A49,EF53270066899336,A235B168E9C24121,813113E8A462D7E0,002C1B13A2B9155C - -Montgomery_R2 = 5289A0CF641D011F,9B88257189FED2B9,A3B365D58DC8F17A,5BC57AB6EFF168EC,9E51998BD84D4423,BF8999CBAC3B5695,46E9127BCE14CDB6,003F6CFCE8B81771 - -Montgomery_RB1 = 0C2615CA3C5BAA99,5A4FF3072AB6AA6A,A6AFD4B039AD6AA2,010DA06A26DD05CB - -Montgomery_RB2 = 49C8A87190C0697D,2EB7968EA0F0A558,944257B696777FA2,BAA4DDCD6139D2B3 - -Montgomery_one = 00000000000003F9,0000000000000000,0000000000000000,B400000000000000,63CB1A6EA6DED2B4,51689D8D667EB37D,8ACD77C71AB24142,0026FBAEC60F5953 - - -threeinv = 55555555555556A8,5555555555555555,5555555555555555,7555555555555555,7CF1276D98503E1C,CF0186C74B5465B9,A3B114D6FC634CB0,00227636AD3027D0 - -u_entang = 0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,00000000000007F3,0000000000000000,0000000000000000,BC00000000000000,B48DD9032BABBDC8,87354452517EE94B,B55528D05AECDDB4,000D90684A9D9488 - -u0_entang = 00000000000003F9,0000000000000000,0000000000000000,B400000000000000,63CB1A6EA6DED2B4,51689D8D667EB37D,8ACD77C71AB24142,0026FBAEC60F5953,00000000000003F9,0000000000000000,0000000000000000,B400000000000000,63CB1A6EA6DED2B4,51689D8D667EB37D,8ACD77C71AB24142,0026FBAEC60F5953 - -table_r_qr = 0000000000000BEC,0000000000000000,0000000000000000,7000000000000000,1858F371D28A907D,D89DE1DFB7FD9CC9,4022A097759F1EF6,00348C1710ACEDDC,00000000000017D9,0000000000000000,0000000000000000,3400000000000000,1DA98B098303395A,959FCCF6F47CBBE3,1FFF7A7110C6991D,0028B138DFD8BD9A,00000000000023C6,0000000000000000,0000000000000000,F800000000000000,22FA22A1337BE236,52A1B80E30FBDAFD,FFDC544AABEE1344,001CD65AAF048D57,0000000000002BB9,0000000000000000,0000000000000000,B400000000000000,D787FBA45F279FFF,D9D6FC60827AC448,B5317D1B06DAF0F8,002A66C2F9A221E0,0000000000002FB3,0000000000000000,0000000000000000,BC00000000000000,284ABA38E3F48B13,0FA3A3256D7AFA17,DFB92E2447158D6B,0010FB7C7E305D15,00000000000033AC,0000000000000000,0000000000000000,7000000000000000,8C15D4A78AD35DC8,610C40B2D3F9AD94,6A86A5EB61C7CEAD,0037F72B443FB669,0000000000003BA0,0000000000000000,0000000000000000,8000000000000000,2D9B51D0946D33F0,CCA58E3CA9FA1931,BF9607FDE23D0791,0005209E4D5C2CD3,0000000000003F99,0000000000000000,0000000000000000,3400000000000000,91666C3F3B4C06A5,1E0E2BCA1078CCAE,4A637FC4FCEF48D4,002C1C4D136B8627,000000000000478C,0000000000000000,0000000000000000,F000000000000000,45F4454266F7C46D,A543701C61F7B5FA,FFB8A89557DC2688,0039ACB55E091AAF,0000000000004B86,0000000000000000,0000000000000000,F800000000000000,96B703D6EBC4AF81,DB1016E14CF7EBC8,2A40599E9816C2FA,0020416EE29755E5,0000000000005379,0000000000000000,0000000000000000,B400000000000000,4B44DCDA17706D4A,62455B339E76D514,DF95826EF303A0AF,002DD1D72D34EA6D,0000000000005773,0000000000000000,0000000000000000,BC00000000000000,9C079B6E9C3D585E,981201F889770AE2,0A1D3378333E3D21,00146690B1C325A3,0000000000005B6C,0000000000000000,0000000000000000,7000000000000000,FFD2B5DD431C2B13,E97A9F85EFF5BE5F,94EAAB3F4DF07E63,003B623F77D27EF6,0000000000005F66,0000000000000000,0000000000000000,7800000000000000,50957471C7E91627,1F47464ADAF5F42E,BF725C488E2B1AD6,0021F6F8FC60BA2B,0000000000006360,0000000000000000,0000000000000000,8000000000000000,A15833064CB6013B,5513ED0FC5F629FC,E9FA0D51CE65B748,00088BB280EEF560,0000000000006759,0000000000000000,0000000000000000,3400000000000000,05234D74F394D3F0,A67C8A9D2C74DD7A,74C78518E917F88A,002F876146FE4EB4,0000000000006B53,0000000000000000,0000000000000000,3C00000000000000,55E60C097861BF04,DC49316217751348,9F4F3622295294FC,00161C1ACB8C89E9 - -table_r_qnr = 00000000000003F9,0000000000000000,0000000000000000,B400000000000000,63CB1A6EA6DED2B4,51689D8D667EB37D,8ACD77C71AB24142,0026FBAEC60F5953,00000000000007F3,0000000000000000,0000000000000000,BC00000000000000,B48DD9032BABBDC8,87354452517EE94B,B55528D05AECDDB4,000D90684A9D9488,0000000000000FE6,0000000000000000,0000000000000000,7800000000000000,691BB20657577B91,0E6A88A4A2FDD297,6AAA51A0B5D9BB69,001B20D0953B2911,00000000000013E0,0000000000000000,0000000000000000,8000000000000000,B9DE709ADC2466A5,44372F698DFE0865,953202A9F61457DB,0001B58A19C96446,0000000000001BD3,0000000000000000,0000000000000000,3C00000000000000,6E6C499E07D0246E,CB6C73BBDF7CF1B1,4A872B7A5101358F,000F45F26466F8CF,0000000000001FCC,0000000000000000,0000000000000000,F000000000000000,D237640CAEAEF722,1CD5114945FBA52E,D554A3416BB376D2,003641A12A765222,00000000000027C0,0000000000000000,0000000000000000,0000000000000000,73BCE135B848CD4B,886E5ED31BFC10CB,2A640553EC28AFB6,00036B143392C88D,00000000000037A6,0000000000000000,0000000000000000,7800000000000000,DCD8933C0FA048DC,96D8E777BEF9E362,950E56F4A2026B1F,001E8BE4C8CDF19E,0000000000004393,0000000000000000,0000000000000000,3C00000000000000,E2292AD3C018F1B9,53DAD28EFB79027C,74EB30CE3D29E546,0012B10697F9C15C,0000000000004F80,0000000000000000,0000000000000000,0000000000000000,E779C26B70919A96,10DCBDA637F82196,54C80AA7D8515F6D,0006D6286725911A,0000000000006F4C,0000000000000000,0000000000000000,F000000000000000,B9B126781F4091B8,2DB1CEEF7DF3C6C5,2A1CADE94404D63F,003D17C9919BE33D,0000000000007346,0000000000000000,0000000000000000,F800000000000000,0A73E50CA40D7CCC,637E75B468F3FC94,54A45EF2843F72B1,0023AC83162A1E72,0000000000007740,0000000000000000,0000000000000000,0000000000000000,5B36A3A128DA67E1,994B1C7953F43262,7F2C0FFBC47A0F23,000A413C9AB859A7,0000000000007B39,0000000000000000,0000000000000000,B400000000000000,BF01BE0FCFB93A95,EAB3BA06BA72E5DF,09F987C2DF2C5065,00313CEB60C7B2FB,0000000000008B20,0000000000000000,0000000000000000,8000000000000000,1515143C04FECE86,DD824BE2E1F23AC8,145E12A5BA8E66FE,000BF6C6B481BDEE,0000000000008F19,0000000000000000,0000000000000000,3400000000000000,78E02EAAABDDA13B,2EEAE9704870EE45,9F2B8A6CD540A841,0032F2757A911741,0000000000009F00,0000000000000000,0000000000000000,0000000000000000,CEF384D6E123352C,21B97B4C6FF0432D,A990154FB0A2BEDA,000DAC50CE4B2234 - -table_v_qr = 0D640973CA6FDA33,30D640973CA6FDA3,A30D640973CA6FDA,9630D640973CA6FD,0B9B362A86413EF5,291A8D3DCCB3503C,28AA7266E86C4410,003E57A5066529FA,0EF755DBC422A858,90EF755DBC422A89,890EF755DBC422A8,8890EF755DBC422A,85ACA658F4ABDC07,0D196BC04A493216,E8EBEE1D04CCCD7F,002513A427F72A8B,EADE47323668C519,19083ECD7DC0E6AB,ABEADE47323668C5,F919083ECD7DC0E6,0B14832196A6135B,65C238AE07A19315,33892F2EF24CBA75,000EB6BD00093E7D,F17BF9E0B28890E7,F5AE5634A1BF1FA5,A5F17BF9E0B28890,5CF5AE5634A1BF1F,25C93809E47AEFCD,36BB725E0DF4FAB5,E60CED675C5D80CD,0023712156F96CCD,01C678311555200F,4D5264E0DACE9D42,12A66D44591361B5,5631C420E42BD0E8,00C7CA70C8F9037B,345253296A40C7FC,F44CE094886CA2C1,003DAD6A1ADCE6F6,E067F0F08021B5E6,11DC29B589407C3A,32AEDABFA1BC2B45,4481E32F9C45CD24,1AA9DD8D9554F1DC,B6F1C1F604160937,11DEFDB2CC29708D,0037004EEAE4323C,E36097357D9260F6,439C0A04D12BD483,66E8351E74487091,1421CC574D451882,AEB61FAD8599E2CA,48EF54E42C5C665F,ED1A8E11AC6A738D,0016259CACCC3BDD,0EB10F6F4BA05720,167E877244911B53,B87DC936138596AE,680CD578F4AED4BA,1694318AE2679DB1,1CEEBA16962876FF,73CAE996B2A0D8BA,00323A5E254D4A2D,AF443325C49FC9C7,F3368ED80D8E2E2D,5C49FC9C7474942E,CCD8E2E2DAF44332,471B92FFA7F05FFB,8C55AC5DD5163AAD,D41A2EDB81C0F26E,0012B9411FE82E2A,D3467582CC3CFFCC,629F4CF0C00C0C9A,2CC3CFFCFCD94B2E,FC00C0C9AD346758,3FB8C3F63F740571,2ECB1038CC7F3A82,F9707F59B63157EB,00115F359929F1C8,3218F78BA3CBAE8D,19C8ECF809D7722F,7097E87F9E319229,1FCB0DEE58D468E5,D0E9B55BF73DCF1F,1EFE4FCE69BC0416,EF0693CEC4EE816A,000BD45626E7A975,DB0929A1BD138997,F4B72083018B3DAF,576F0781228D05BB,59E79B4EB78D8111,DA7D2741F2CC8972,DF9C5CCEC9E387F5,1A7CC1B8C08AB119,003AFC9BC0E8ABC4,EEAAAB192225A66F,3D36F4A6197D1682,95351AD9A4013A92,737FCA70517EACFE,546BE45BE532FB91,CC1BAF4DF9C83B85,B7F98958BFF6909C,003A327C901E0790,77FF3DD1F9D16F4B,6565F407321E6DD8,B8A6CD6DB5D70AF0,6D5E2690BF53E87D,DCA29E4346D90AC4,1C4B31AB442130F8,AA4B89D4E4CCD33D,0016F0F5CF7D95E7,8CAE1CD478CAE1CD,AE1CD478CAE1CD47,1CD478CAE1CD478C,1878CAE1CD478CAE,FAD9099BBD3A4347,67F1D575139CB5BF,38293A715DDCB486,00123FF210860EF6,A3C6570E6A3C656E,C6570E6A3C6570E6,570E6A3C6570E6A3,266A3C6570E6A3C6,28B12AECF9AF8B71,DB47D42F34B82DE3,9556758ADED2F1DF,003AD3BE4F8540E2,CA6337B265BAB821,DFD5196D5A6AC701,5931D9A74BA1FF5A,D0C5E74C37D3F402,4D621242F79E2216,57F1976F8DF43182,F052D77BBE57890B,0026C6CA2E21363A,B4DB046E7F5DEAF1,6C97A33321B84377,39D110888DF1A1F9,3F0E8712AF7E5A0E,318610A741127CA6,8FAE99D54C14A492,B8E11ABEDF29D523,003610D24823BB34,BCEE07864886985B,893DFD453F69DBD8,846663A2582C0992,90BD04A8B4E03846,AC8F553BEBE4AAA3,21D7DE00A60E1DBA,D25E1FED110FEECB,002A3CA66830CF45,28AEC74774664D80,EF2BB2B32771F6BB,973B002353CD00B8,42E8DC31DFA1491E,913BAEE3CA3D9E30,ABF6D1605464DDAE,F3BBF0EC6297B06D,001F94C96F693152,13C45267DD75029B,2A5B4B4FF8E045B9,3A2CEEEDFA82F7D8,09E84B2F89B9CECA,6F9D9229FB56184A,E7CFAA7031AA43EF,AB559E585413397D,003410E7C5B657C2,E59C162702DD0330,117686788B4FC859,9130D016E8C6193E,95ACF6377DD58B43,886E99BF17505709,5785149D522C7B5C,35A0C131A77598A4,003CE98183E3A406,F66188E646E44D38,1DDB967838C24787,F0DDC924163B32D9,F3085EC466F80420,CDC2841D90A1671D,42C7CECE348BFCC8,56B81B6CB2CA11DB,003514702E4A9A0A,5F325943F0BC0122,19AF0969616185E4,395F6F8BF027BB07,3059A95AA6306371,4C8AC22B51821D99,8CA5493A42F7F073,3159D0CAF4E03BA1,000BA85326656B98,355770484B8F9E78,3CE74F9FB70AE2AF,29C66659490DA55A,4A4908AB5BFCCAB2,28E847CF76744D1B,D73C1DA7E9743E83,00BC0814A45DE92E,00231BAF63ED339C,8CA1F537B87311CF,4C08EDED850327E5,5A0D0300159AA110,AA2A2BCDD5424BAF,D5DE3F3F3DB4665A,B414A9EB85AEED8A,F42B8C9A1B8CC578,000FA3EDA9B597BB,A67D8C524B3E4E75,86499A8DBF7A9491,72F4B7F3EA4620AD,4817A8E2631DE824,BB8AFA3312167C4A,FC6430A72CDFEFB7,8D35B46A38FE2241,000175BFA3B8577D,CB088DAD679EF165,B4C8822258637092,B2C43661C46CF323,B9880541F96B5BFA,107BCA3032B41FAD,269816DB16A086AB,B5B0180593043903,0038FD7D2B147838,475B7B82B2D288B0,22C1F565B3292571,59C43DCA0D6C8F10,E1F36E62396C705C,F83EB8755AE3C245,8AD232E4B45B2625,877CD62B7C9672AD,00089DA6104B553C,934EEBD2D80093F8,48EFC56B31172CE1,AFCA4B6A73ED7336,995F04639C835D11,5B3B9A208FA56837,47FD72D865F2357E,9E3CAC4107E83532,0031CC176CE59261,4AD8213DCC0EE2E4,4CB861B5AE488639,A51A5B14C15122A6,11D3BAEAD457C643,69F81BA8151F4289,BBF7FD30D142B1CF,0EFF9B4443C1F00D,003A8516A2E48A25,BA9071A25161B713,D23BF87F90FB216C,0CCEFA630B8101BA,95CCD7CE9070EAC0,B8CEE68602DD9A73,D60E96A7B6065216,F90F1CEBF826728B,001F67DF31E4041C,B826A44841FE3FCD,5D362655AAD7FF01,92B4DD765A16E5F5,FCDB74BC0D0D0A6B,F41E518CAA1A182E,F07FC9B18F378B80,5C70AB82A854E783,001DD88FB06EF820,33EC5C7825F89FD2,2199AC18FDD5A835,75EAB3F2E9965093,162128FDABBAA756,ED6618E12EA9E8AA,300CF4246FAB5DDF,BE8FFF323060A819,00147D4620F25FE7 - -table_v_qnr = 6666666666666731,6666666666666666,6666666666666666,7A66666666666666,566281F7D63AE371,BFF8182310E4EED8,0260EA261A835DB3,003B5180C26A5D29,333333333333319C,3333333333333333,3333333333333333,6333333333333333,794BB3C497AE085E,B747BD4AD5331DAD,BBC9B92F7FE88E38,000A2AE8FE2D81EA,42F42F42F42F4303,F42F42F42F42F42F,2F42F42F42F42F42,3EF42F42F42F42F4,EDE69F6C16FE9C49,5F14E71311869A6F,4A3D210B203EC110,00361A6419F55969,E85E85E85E85E7E1,5E85E85E85E85E85,85E85E85E85E85E8,BC5E85E85E85E85E,160587963688731A,C89C86E2D4409C4A,4FFF66D7F74F792D,0011FD93FADD078A,2FF402FF402FF403,02FF402FF402FF40,402FF402FF402FF4,F002FF402FF402FF,10AD8E578684D15D,7D8BE80CE669C6B0,2F6BF0AEC5EAAB99,003FBFC2D75908E7,017FA017FA017F80,A017FA017FA017FA,FA017FA017FA017F,7FA017FA017FA017,4B59B05371A2C857,C201D772A296DFE0,1B3AC1E2919F26D3,0014E64D4502A6E6,95C05529A8FEAB59,595C05529A8FEAB5,B595C05529A8FEAB,DF595C05529A8FEA,2F45F28BB8ED273E,FA436C90BD54C61A,1062C7B1DEDB1074,00315A8AEDC8909C,C06F5DDCFE428877,8C06F5DDCFE42888,88C06F5DDCFE4288,948C06F5DDCFE428,AA9C9EF112689F32,53976445D5B6748E,7756462EC170E4DB,002C003A897F5825,FFEB87D96821E700,E6FFEB87D96821E6,21E6FFEB87D96821,6821E6FFEB87D968,536BACDAEA5360A5,587DE91F62936769,F9873A3AF7BA1771,0001AC726662E629,07D5FEC6230591FD,9207D5FEC6230592,059207D5FEC62305,27059207D5FEC623,49E0E7C0B24AB790,72A0A655B60DE2BB,9B0D09A6BA29F50C,001D311492A73E49,3DBF0903DBF0903D,903DBF0903DBF090,F0903DBF0903DBF0,DFF0903DBF0903DB,2E57678E6F6B36FA,6D14F41B551BD544,A9A9EBE547506451,00340F0593481A65,207B7E1207B7E118,E1207B7E1207B7E1,B7E1207B7E1207B7,E7B7E1207B7E1207,8FB1896621AA9BD5,ACE233C79D786D08,4762CA7D1868CBD4,002250D8F8670982,840F89EF8D6AD1D9,D860EB4F2F6A9A25,59D8EC2E0086586E,12947D34DB3512E9,F63A898976A47748,501E5E834CF73F95,8EAC965E265BB2A6,0034B4D6B0074D55,D3DC3CD9848C0DD4,F4482A22F4B792B0,CE877C0F970AE966,ABFE2EB4BE8939B1,D39F645922FB329F,183041DAFBDED6FF,35DDD811FD020363,0014AD647102E09E,9A9AC56B775830E6,349D4969F781C5FE,4A96A3BBEA5CCC22,E413030F74832A1C,4CD1307BD96041FD,AFCB8545E06F5E57,1C86CB1828C75997,000EC2C4397DD1A7,4301B37140F51F76,6F2795BD0148D223,C955484121E76B9F,3AE35055972784AD,109E0D0B1EE661B7,8530AF7BBFEFB9DF,2A20E1C05CCEC0E4,0009F5C0FEBB8ECA,4E3AF17430022B8A,35839EC8DB54E2A4,A3C6E03E4E9EFCD7,DA418C66D7C8A36C,1FD4F171FE1732C8,C625B70E60138FC9,A4E5092E399B6337,0021F760DFCCB761,5EEAD7AB9B19B13B,2CD37E80CA584907,38F9B3527D092219,2400FFCCCCFF04B6,CE2C4B82E6F44CF0,83A9B6663589197B,66030DD337B55803,000A2179BE9ED7BA,DD28279CDC678A67,4D6331D441594443,8D052A7E726EC043,24C4928EE44B7AD9,371ECF34320A1AC3,F7E715563D9223CA,7D4F1577FFD8B72B,00113FAE041A1084,E28435CF3C6F7D49,2A0448B3C90AABEC,4FDB34DA65E72DAE,8DB6017694201827,BBBDA1163D75E61D,7DD994DF4E8BB61C,4376D272F53F0160,002F782D31FCAD7B,13CC56E70A95B922,3E79A643C48D1142,193B7E19EC380834,1F43A718BEE0BD64,AF07EEDBAAC36417,1479E0460B4E85E0,E997B33A457870E1,0012792B8A001D25,BC6BB8DF2AF20DFE,56E5A0EC1FF64B46,739BA13928CDC001,D9A0886EDF77FAE5,641A73F9F6B41ACE,1DAA1F63D364ED8F,797D94D0849C5333,000ED06FE444692E,5FDF74D731C8412A,6FA3CCC72BC442E7,F7A328C581FF9506,9D43E8D9CE513419,E0969762B591CA14,A7A20D5B0A226CEE,E652DF72F7ACDBA7,00098B2737AA6855,15D2521AEA43D912,7DC88B6270806BCC,F1FE1E4FDEBEDBB6,AFD018F26E77AD62,F8BB0C784D9A7776,8F933FA003570378,B7A3F4080B1BBFAF,003043D63A75E546,2254A8771FEA02B3,8398EEA5EF546F3E,A6062563B110D486,5AD887813EF3AE86,EAE29AC17FA58A77,924599311ED77B3C,3DF2835E75922318,002EEB5411B26C76,9CBF7A679A9D0048,B4B201453651D31E,A4C91B0B01A9AE32,BD873B3D5E9CDD40,01869D6517CD803A,05F3A2180D299CEE,D46EDCD4F9A5E5C9,002901D3472FBC49,BC9C88687B4C473D,0B37349E2D384219,86A75F99B9FEA3F6,32FAC92124206663,BE37BE6B4BCC19CA,8F77567E888968B4,4308A1AB82A632E2,00028B00FD8816E8,F0C7DF924D5127BA,CB86F4707F9FBAC5,0B643FD9963502BF,5125F52EC4BF48C7,87F7A3330AF723A0,1455E18791E932FD,4DE936B1F7BAE4CF,0006F35FFA98F53D,459FB6EF424D1859,F492057CEBD9391E,E70ACB8F885C8084,CEBCCFF5FF922454,EA056AA88BDD2C5B,B33F747126069D2B,ABC8F606165AB077,00280CA098BAD483,AD7B42377A2CF64A,62877A76DB1B5C49,DAAFDC58FABA0793,6501BFB81B604B74,A5EC0D8847E461DF,E730BEA141B807F7,16209BF6A0544D52,001C131448A178B3,F09679A75D6EDB8A,85E0E32FA20333FD,659E89AE27506F5D,CBE8610A2E1C126F,CA328C6CB821E1A4,B0F6B45C68433733,996850439E5A4FA7,003D91026425288B,0C70416DFD912112,7B03BDB79F9194DC,1ACDFCB1F1986D14,572978ED23C5581B,FB1B4CAD724370B0,7DCCA0FBB9D5A84A,A33D15155FB6D48B,000861CA17970496,22BCBF7871766C3A,9395C19D8E87CC4C,B92EF7084D0FEBD8,8A60E143C87DB915,3FDCB6ED258F6167,FB9943E3BF11D380,E116C209F87D2108,000E76DDE2391409,C8A69E75B7B72831,300BCE8A5E86484D,34F0183CB8FBECCB,590030B5DC767075,2D8B65503007FE01,8F397E3E796F3B98,C77FB29679EAF434,0013554730291BD2 - -v_3_torsion = 9999999999999ACA,9999999999999999,9999999999999999,E199999999999999,F80F9506B04F6159,922628D05B98276C,536E7BDA3A893A25,0038C6C682DEFCAE,CCCCCCCCCCCCCC67,CCCCCCCCCCCCCCCC,CCCCCCCCCCCCCCCC,98CCCCCCCCCCCCCC,5E52ECF125EB8217,2DD1EF52B54CC76B,AEF26E4BDFFA238E,00028ABA3F8B607A,B61A6449E59BB678,E59BB61A6449E59B,6449E59BB61A6449,161A6449E59BB61A,B0A7A696AD14F403,5908519429BF6752,F8F5C2FDB95D626B,003415A91EB9B01B,59BB61A6449E5991,449E59BB61A6449E,61A6449E59BB61A6,EDBB61A6449E59BB,DCBBFD66B1210ED0,D1759BAF69F0DE7F,151E605BC94FFF1C,001AF11E41BC9044,865EFC865EFC868A,5EFC865EFC865EFC,FC865EFC865EFC86,CE5EFC865EFC865E,4CC228DC36501857,73987670F8421161,E0DF934DDA9372B7,002EFD8AF527F647,548FA3548FA3547A,8FA3548FA3548FA3,A3548FA3548FA354,5C8FA3548FA3548F,370CE767DB69F0A1,148A42FD9FA8E75E,95D3497A1836567A,003B176D3CEE7B7D,50217FB6E959A5E1,55D744B5F5B8D09B,F7A01245A9968DFD,5E2ED28291CBD92B,327D6A4F12ED9197,22F38DE9B94342A8,F08F9207C0BC4954,000092CA7D85CB62,554517694148E5E0,810BFDB74ACD2E40,AEBA25AFADC684DA,3D00922D4CB46FEA,9B6A27893DA502ED,70CDC63D75720D1A,079E291279150591,001EF28157438CF6,59D483698ADF25AD,DF259D483698ADF2,98ADF259D483698A,47698ADF259D4836,8A409FE323B0C564,7776BA73BB1425E9,A9C30185C47DDDD5,0017CB3BFFF6729E,6F92CEA41B4C56F1,4C56F92CEA41B4C5,41B4C56F92CEA41B,E2A41B4C56F92CEA,9D076460B8435788,54F113B72EB92D94,2A66E44EFC731303,0012A4AB560F3F66,2B1FB984943A94A8,30572CDCDFF75824,86B44D20E248E0BD,91D67FBFB355D2A2,1FB62ABAE68FD35D,3C9EB762B7B42EE1,9F02146D035C6473,002E16E82F80CE94,57721BBE9E5A5800,A2061AF8C6275649,3BD12A9F2030397F,11812DB680FC4074,E65278C2B095007B,8F2E2CBAE91FE5D5,ED8F5676C276CA45,003DF6D70A1D206A,BE8AB88AA30ECFE7,4BA78C308192D1B7,B3E24AC5F8070CA1,096351F2D30F7BBD,81FEFCEA948AD196,D3C5B4543AD9805F,00A75812F48753D9,001724C5EDAB3470,2827F23CACB56FB9,0157BD32FB57A7B7,70A9DAFDB132D060,792BEEB65C0F9BF7,E56FC183B1F50CE1,CCAD12C0789DBF02,8C2146875FF342E2,001CE0B3C0517507,49B33CFF3F381BC6,D8CAC1728CCEDAAE,1DF2FD00097B2467,0AB713DCFD459086,08836E5EA1B2EDAB,1716275997ADF384,191CA247A36D2F50,0032176EFFF620B5,4C8D46F27B6D17EC,50F8ADEAE3D0F0C7,545DC5F4131C3561,E5B904096E80374E,A86F14DB302AE72D,8F42BC329DB7D7E0,83BAE6D9FEE5F302,0031094190A0F887,8EB074F53A76A870,B126FDBA6CC46493,555A9BBF86580EF5,2D766D1384CC6DD9,488C1D0E043C69F6,E46574481370F9B8,20011A2950633B25,002C90D406DC97FF,25760E200D5A3CC9,5B029C9D13C41968,4CF262816A003763,ECB895F7DEFD5B79,5500D603F7586E63,D3B73E937238582B,E0717E4434F561B4,0024B97B8A231B62,3B59E87672CD3132,39065FDDB46E42BB,DFF1DBFCEE9FB3C5,95D0A17ADF5B0686,004F4AE55C15F6F6,EC7A661AF31BEEA2,0CA7A05464470274,0032630B4C55211E,9DB227BAE1A18E5E,2D8003402FC924D9,DBBA9E0412D57B42,00E3590E03813384,50E5FD1EE6160BE7,319EE53F2DE7E963,AFBEDCC8195A0FE7,001D66C22AE5E03D,FA1D721B8012AD24,4D5A34CA856360AA,2C74166DA03E082F,A334C1A0A8C0EECA,4BD3029C76081336,C17E91F7FE1620AB,602C6464DF6D7B5A,0037C56195A01609,F42E70CB53B77D89,971CD3CDB95DCA98,98BED2110CEA97D7,29E8E40FDE89CEA0,066762394F501B5D,768E393C98EDB0DC,7B7177B9782A051C,002419F31B5536B7,6B9078F75FB9FD5A,AAE697DEF085EE62,55F0635BB0920820,B6EB4C44F59DA609,9D20534E797B55E3,E586320878C2E00C,4B2C04D2265832BF,002B7A08CADF8ABE,A28AD65405737E37,01A7AD3DA645AE6C,A007C768042513DE,B862E5834961B9AB,D751FD817FF50BD6,D40A969925029B74,38326A08AA3FE933,0033A720FE49B1C0,6F33A8DC20803BD8,2846C4B267C2FEA9,3007D269048CB91D,149AF087F10343DC,A411643250BFE57D,FE05DA28BEBBD6A2,A1CC30AB16469EDF,00073147428B8D6E,14144FB077BA07EC,BDDB35BAB1D76D69,161ED689F2678887,635E2E3996327A7D,EF1D6C7CA5686991,50B90BE915F46926,1CA4E335B9AB5FD5,0027BAA66DCED0C5,EFA7AC2F83918F15,1180A29870F3D459,90347A6E04DDB73E,80D765C86450E8FF,B872718F0F19F98D,D6A86F096DCF4922,0B38BB34120254D9,002E5A1621B615F2,B2D181BD4FA52AA2,DC904B3EB8AF6F02,D6B25DF9558317E8,85BF914F31A23BAC,BDA3E9AB557B29B7,5CD5E1D426B1789D,8A6AED659E678CD3,001C56D6E1BB93F5,924E6058D015A38D,1E2EC7DD7A5132B7,A97C2194346DA32D,41EF1F31CD51333B,FB89E6E30C1162AA,4061678E5962580A,09ECCCCB3B6FAD5A,0037AF58627A887A,E8F5D903F0BD0269,200E1FFA8489B9DA,DE882C8D3156A460,8C4DABC11F877458,D54C3B40CD538F2F,41674635284DFEBB,AD9B8330BFF569FC,0030C2633BF078F7,75C1E6ED473130D0,FD624B7CC04D355F,313DC4BCA820911E,449D8112D71CF106,23A25A83664B420E,16A55C6AF6910691,DA58FB0631B2EAD0,002D42B72E1FA0F5,4AF98FC17BA992CE,19C1F944FD5AB7F4,68ACC73E0CE942CF,7B3F9FA6C110FEFD,3DEFD9B6CFCF2AD2,4B080446336C5FA5,19508DFD60080814,000FD442DBA88642,4EE43F3D8CAC1374,0AF2E7784E2460F7,50133AD8519FCCA1,BDB81ECD10C888CF,0675791FE9112FBA,364B5F4D282C51A3,A3A53FD5546E97E0,00261C6F73A8BA64,13DE8B19DF5E0FEE,1D05A6FE505FEA21,634E634AA1C25DBB,2C49E6E62282B432,E989B2E0D9775E22,104ABC59A97037E8,03DFAB907857260E,003B8179D525D960,AA3BFB6CB8587768,515E32FD38308C38,927E612E9CE18C76,13B2195A5D867C54,857274100A6ECFD0,10CAD97274DDC646,030BCDB9A79ECA27,0007F0790BC050BA,67F4FD27FF7B7A3B,7528EF9DFC6790F9,D34442AA02F00A58,51935D736DE84027,0FEA3DCBAF9002F2,B3D055C2572AD741,9F0EF6D70050CCC5,0010611302FDA1B4,8894D7E86C5358CF,E01ED56C2E374D80,1EB04AACFBB0B60D,1B0F1031360154CD,052257CF78935DF2,D1759C3E61E7823C,C5CBD367AD3EB0AB,00377C52E4424CF4,ED5FFE6B5FB024BD,065B8965C7A3F1BB,61A0E4FB6BAAF40F,D8ACB4A3CC9A6C24,38FAAD404A5D6211,F59F595458B10D72,13FDB0B2371936A0,001934F680EC8F88,F6DC60A5C5734661,9CD9E9A6DA083A88,EDA465D0EAA7F9BB,87FEE132D788E4CA,94D57ED92F0D0A7B,A157AC0056BDBFE8,62DAF28EE0E30FC9,0010E9FA4557999D,78942F9DE083A353,5FDAC52AEBA63CE5,905BC434EA6102CF,9CC2E0667372C509,E22094C33879AFDC,820B3999B77E5E28,7076A18C8D100A7D,001B55229ADA2623 - - -T_tate3 = C8958D5CEAEE9961,15656BE866831334,3DBF0E58FFD1403F,2A2E6D76A5BD8030,CB8B87470EB10976,BF2B2AC3FF0E5842,AA01464195495DC7,003301FE417ADEE4,1774317C1AE747D8,F622B72338E21067,66B109C419F65B51,3D8711EDC6BBD998,B63D65AEBC6BA7DC,01291072426592F1,1BD9936571211946,000DD17AD4188A2F,F88254ED9673F23C,FE13BC2A7A60FD32,5C477D4791512FC9,B60D285940223FBA,D4F04D230B01D6D7,AED3BA7AF814D35F,050DE8541ED8EB69,00070D8A04CD0C5F,8F6D06DEB1BEEBA7,728845EFC2E41EEF,C0899F1BE099641C,B2D53A9A6FFB638B,81DFFB91EE670A12,7F6ED051EF6DD383,56FE7CC0F271EBC2,0027A62D7A33CAE4,052F209522A9A8F2,BF15EC49DA5F9607,164BD51C1FC2F4DC,2E24296622C7558F,578D487C382796A2,AB9ADD2F0B1DAB27,A71611FFD3196A6A,001C93380BC6A35F,6FEBC2CFB6E541F0,A0E90B20492B299F,58D1C7665561D204,726AB02F7704DD1E,ADCAF51273B66C35,AFEC72698D7A86F8,6B938FF75A01AD1F,0025E913D3900041,3D782D5FBF4E9D25,8CE0A7CD3D244A6A,5DE270BA6D676D73,C7137CB67CD0CC07,8A42A49B803C1B06,0A6C6BE61B5F9D23,ADB2D782169A7FF5,000CC514CA84D8C8,494C083C726D319A,6A7A0544AA7CFB48,20BF934A99D0A326,0FDE6116074F7AFB,9CF64B6FC92E8B3B,01996D1A2E28860F,9C527774AD244155,000CCAB220E2CC6A,558C076E1F240A33,4E11EA9EA5AEC610,C5E1F18FFBCDBC66,C9A0DE18266F12AE,83E9A9054C991729,64F28BF07DC4BBC0,4F98AB9C8248C641,00380130CBD158A5,13B583F5FE1445EF,2E28143407376486,C3388A75AFF33517,1180CEEC3264360E,9AA81B55A88A713E,B0B585C6D4E7871A,7727044C3A91B54F,0034090B82AED8CA,43B9DA643352346E,5CD80A2E547931A9,52C64DEFA2869297,42550BF0D51F925B,7A5C596ECA3ED13B,41315CCCBCB0EF42,59A69D5A2907E724,0018FA7EBEF3D7A0,17B4FF96AE5486AB,98A04C523C0F8004,7588FD11603A8967,75D3A9FA885976C9,319EB1383D272E66,390D6ED7B9D98336,4F178CBFE6278E11,0010FFD3C9A1690F,59B95A5F65DC83B1,611AE8D14E568ECB,104FFA7B7F94B97F,F0EBFF6D81837480,3E0FC0257BF0208B,A335B99DB95D061C,3A05D7396AF06A4A,0025BFEFD95D3454,777847DB261D0C8E,316D64AD0DF8761E,1F7BDFB78BDFC95C,12D68D75520F6CE5,AD8922594DA44BD6,052D2196B26BEE2C,F56F8AC4937139B4,00337B4607E54134,E28F853A3580BBC7,6AC658838B3D9CAE,75711438ADE90FF5,90B042B090FDD7E7,396F3E95707FB6A6,903D06BCB61F51F1,7A89595551A0AF7D,003823C2BCB4ACF8,30FBC722A0A8D1E5,5C20FB9E09682F63,5EDA785D78735AC6,EACDEFF413E25C76,5B6CCE16AF1FBFFE,BAA204B461C736D3,3A2C5DA9681E38F4,0000D873080ABDF7,48EA7D1A8EAA38C8,817C468377955430,B36941B46040DF4F,D4D353AC3A3506AE,88875C3AA6E17B17,913E3089EEAEA7FA,4A756EC91340AE78,0023799D07E58FE5,DB8BF50A3795D736,91F358BC8714D0C5,94653037769E2588,071391585F29F6D3,3323D1202F4B91DE,1537C77A96148FF3,6056A81907D4C433,002121EC34AF435E,215197FE6EA6E31A,F99AD791E0E90BF1,CBF0A844BC107235,92998285C0447A1E,7B6D6B57A26B0385,163308F350FFD8A1,D75DB0B3BD04C81F,00380259EBA432E2,3A1B603C9748B921,E442778BF7E68F7B,C18D7F7912EB3BA8,A97738AA6A94B292,CA75DC8EBDBA768A,09EA20EE8BE90961,BFC40FB0608DDE23,003437B4025F50CF,59ADBCD79A4CD43D,DFBB504AC907DE13,1B320674C30D8AF7,19130F0C4D890FAD,A51C4182DE07371E,D51E6A288043EA17,77C9D0181A5D7095,001474DCC530DE65,02FFF407EA2A5AC4,4C1F998FAE9AEA08,1F18404A859AF280,58D9E124B68B9102,558683EE964318EE,C70041AF357A5CA0,7BF6DA77FB7FFBF4,0024F2DBE4601F9E,410262939B802A04,1C6C3272E99EA472,2CA3BABFC6D7B31B,1B27459EC0530457,FBCE8F37D551AF07,1CA4F10EC70009F5,45E564B687157DF7,002619882EC74442,041FD94D3816493F,3C43AD27D4DDE1BD,8E6524D5E6F70274,F124A431D2885B3B,77D49DF03BF4ED70,CB719BBCC7F877EC,0BDD570A4AE5F4E6,0035C1B86C412524,5C27C52F336B093C,760E352F13CE0F9F,3005961C7E83724F,B910D0879B11A93C,CA6250054F49E93F,C2B4EA9E521006D6,CC7F250134D90E4A,00109F0DA2F06B04,B31A22E737D960F1,54F35A87C8BF3BAD,B64A22864F9DE445,E76935A149ABDCC3,3A314D980FE6562D,89CFE04D814E533C,BC988C62FBD1175D,0000E89CDC935EF7,32AF9BC2289DB649,1748FB4EA48F5876,B59B2185EE4AE2A7,0F67B98DB2060ED3,D6A0940F2E8DDB73,FE11002C43D00FE8,8FE34DB948A55EB9,0008FA142A65DD9A,3A07B154D3BFBB8C,A89023C326755A79,EEEF615D4B42338C,6F85FD4BDEA87EBA,CB0A581FB61C8CF5,5A3D9879C6DB166D,ED45C7CF88EE4C19,00022D56528470E3,A13D9D61964CD379,DA8C473E933BF48B,DBFA60AC3B60F7ED,E82F50C2AD350D3D,36A822C9786ABF2A,00A590A2E855277A,0F40625E007D6CE4,000ED96BB72BCFCB,55DEF0577BBFE8C4,550A31D9A1652217,C72D388FF8569303,D85B0FF4F21A2163,344702DC9E36C473,3A3738B89E55EAE7,77BBD889350CF856,0020D9667170E607,EE654EBBCFD99BF4,A51754E593C8BD24,9EE410583CE28A66,959A3A1C0637EEF0,25B018DB2AC757CA,5C999C11E8BE1A71,406E15821AEFD399,0023E566DBF968CD,8B0556A8CBDD09A5,29A330F02CB9BC71,2C7A4CA49EE08EDA,A20BC85C23DE7881,2B008CB2ABA75ECE,D9DAD51971C97CE3,0C299DF6E1090B2F,003D366FA90735DE,C4A80F061484271E,57FAD14D646659E6,AC47A7E1EE5915BD,79228C14AAA868EC,9FAB6233F405979B,9FAEAEDDCD5C0B7B,B1ABF3654CE77537,002B7EB1000F0EEE,01ACB510F9BDD6C9,300626F7AB298E48,19D4AB3BA42040D0,F2244C65099634E6,AC98B66BE249B8A3,D54BFE9A19638B55,38BB6F006099B783,003EAD979CFAB042,562B64097C0E3D15,617A23EC3EAD0D16,C16ED610D3E26DB9,39CFD8008287C87F,C086978264A3CF3F,0976297406CCCDE6,4D29A168F4C24E5C,002BC6550814EAEC,21B04A0861AB56AF,81AD267496B0723A,0D0A6B1330F2658A,AA43D8AE67E02AEB,8C758B566009EE53,DB673CB9F69599D1,C7817897B57ABC15,000D6E2530200C64,0F3BB67FB8D15AEB,6A373275A0F9691D,C82F999933CFDCE7,F3C21A92123729D3,2AAA8D42CFF0166F,BA1D7820FFF9E3FA,3351E475C37ED977,0028B1856DB6B8D6,C6C147A917137F9F,115150CE171910BC,BB815EC83C01EF36,2FB127AE73D17E09,B18FF8B689017F63,FF8EFF8ECC1700A0,49E53A8E60F49646,001D965B930CE232,2D49263D0A9F5A06,2498081DA7E396B8,050F26C9D424D441,593C798D4917B122,3ECCA5107001C6DF,5A57EC5C0C24985A,3D2477C73B18234C,001367F6E2E2718E,9FE8B8D126C87071,522D05A4D9BCA6E5,5EDA963F2AB9CBBC,937686C66CDA1F34,C6779B5840C7D648,D3F011BA549D9CC6,9B45212BEF14B281,000FE3E85CD0C96C,07E00DD3B87271A0,00E1A01ED5AF4628,0DBB843F55DC762C,5991C124A6636800,CCCF5AA4973C0E07,028E2EE0E23520DD,C122201866705C71,001DFEEB2631ADB9,2FDA3DA37D56BF05,C5FFC6606973DB12,3A6C43CD9BC36D4A,02F722B325D4B976,326A2D1FC3596CCE,BEAFFD9D4F74E1A1,4803282EE21B9278,00392F11ED22988C,4853F1EE22BECACE,6D6F1A0248082567,EDD81C10C97D4036,C6C6919A6BF0D920,2C7F97C64804117F,F0E8764612D0D63D,4CE1C6178B2BBAA6,001CEAC0F775CC99,90EDB27DC607E009,B5490C02C50CDD50,0F9C35B037DE3C0A,FE0369234CD36A70,7FD8C7D067CB42C9,C8D135E6ACC397CB,ABDF5827C14ADE3A,003479F89C145EB5,77342C2DF94CAE02,7FBBA379E84D0B4C,BFEE92ED3F99A1D5,D81201938B6F48A3,E7D1044B05667438,461F1665EF57A27A,E147E64A892FF6DC,0016E022F892A0BE,2D623EE5FE5AFE33,37E6C8B5BAF01A07,E4E7BC2245CA7313,2EC198AFE2B1F360,F0A9E7E730369EC9,8B1253849CC85BAF,84298A884AE8BBA7,000F2855C467201F,BA0D9C53664C111C,F343B0084862DA5F,DA0D21E3D3294BC1,1AC43A3FC7AC3F79,8D3C52F86ABAF529,6850329404CEFFDE,301BAA527CB2E260,002B40985C0F2178,F321BDCDB73DDA09,EA464E4C9E08EE42,FD7EC5C95BEAAB0F,93F21A307A9D12CA,387E17D7D0EF456C,D924FD33AC95D92D,047A0E9ECD0695BB,002356452B8809C0,CE69BEBAAD414EC1,86D870FC8FAF2F10,094D3853A2625618,247D36F4FA0BDFD0,72508F97DD7DD18C,FC2ABE771A92A683,BD2D982CDCD7EA4A,001B1797E76399F9,0282BC0758B7FC94,3F38B35203F6C8DD,A2A503010B6085D9,3F1CDE784113B420,3824938BFAE808D3,49181DCBCDF7CDEA,8F46E81A781667CC,0032A59F67224000,DF2003DE7763A6A4,5AEC7D558ED9E452,7E20854603DF162C,086C3B0E69A59A03,10AEAE87416CC623,2425DF04C1F853C4,92BB528E935A35FC,000C460C4E6F0A57,B2C3A4E4E033FA22,87BF93C8E652A2D7,E09342302D9D150E,11EB187B1FA67FD0,3584671E69F80DD2,10B31168EA471815,E0C3081752989039,000B36D45AE5E62B,584FEF06B71B5999,F3389713AAB4017B,AA31756C1A8DFABE,C8D0EBB6053ED1AC,ED3A29B43599CFAA,DC5D5825736DF5B9,C9C47B483F3B638F,003106757EB1622F,BA506D5D96975A38,64316B6D7A9F1ECC,528BAFE4D9F6D493,6A4F0C40B21F7E59,C30B213A35042FCA,CA06DF89E035508F,AC38655331D6A33C,000812687D0F4438,4D25479F15E0DAB8,3BBED84CD70D00E9,FC9E6839D10B8ED8,750ED957B7E0A0F5,88BDBBF16F86A39E,499A6AB13E35F7D1,621682C224418082,002755DD1CD7B1B4,B38583EFBE4EBEA7,2622DE43A687A112,ED4D301E8C6212C5,C755777EAAABFFFA,DA1952C76C69BB8C,492B439EE76B0B9E,2991F601543653EB,004035E4A9B15C2E,7411F49456F80962,598AC83665879F9B,453292A161EEA54B,7D35BEA6250589D6,CAA4437FD8A63082,03CB1F128C1A3753,5EBE8981BF41D6E2,003D2704ECBFFD5C,2A3A42BFEF96D753,B4B38AA8F4B29D1A,1ACA4A8F30C039E0,46FF641C96C948AA,8840F27C49421AE0,6AA75B7B60F9134A,A75EFEFF070B73A6,001D81ABEF85D08B,4BA4846983372123,114DC6BBBE5B5E2A,21F7A615CE7A3E67,993A3C7767A5685B,E07A7A14A10C17F2,E93FC2AA075B7D78,92073F4FBA3169D8,00345C4840B95DC2,54FC84614A2A97BB,3BA73336B3145000,DE790F93D8731BFE,3B8BADD1C61CC9BE,5FC958A0C1129FC8,33BB83611B26B190,31334884882CD974,0003A930285DE115,8F7922EF5AC36FA1,F777B79D30F83FF8,0C90671DFDB5CBB0,EF0FC04361626E29,49D5FF514D8FCBA1,5D5C496DC99EB0C4,EA43770B34B3FE53,00389D14C0E967ED,9F72A976766F2714,903C8359731CD843,B7170A8F7D9236C0,8E10DC5CBDF391DF,87FF837AFD73C834,B3350774EEB37694,7D21A8EFFA78A7DE,00007B6C38B69373,37EDDABA0CC5D7E9,B15122F0BEBE4FD7,09DAC3CE3942FA72,0E61B46E52B84040,DC93DD8905C94CB2,24D3D67D0ECEC227,D40939C16C70CDFE,00155AB7130A876B,EAF6FEFCC4EBEC0E,2369BD1469250EFA,5566E7238F78C63F,6C77F7DE14F1053F,0C3F8D5016F6EC56,C7E7CC43911E95F0,82628621D0C55216,000C38BE0CC0D22C,E77273C5D735C315,B489E366D0BDF7E5,A7D4F3DD23083AE8,447C6D8E49EC330B,D29E22F30ACF2907,8F26094F15E68A13,3DFE15F9E8C0CDD5,002E3E8E2A43E98A,245C4D9588590111,8AA3D39D42BD4C0F,374715F8A26652FE,7DDB3DEFD69C121E,F344A1BF5CFFFE75,754D321A023CE2E1,4091B51E7EDF4D01,000F89E2AADF018C,1986A3A77C261209,836C6450D826B45F,A2F0AAE2789665EF,D0FDA0FA7F7C3974,A44B6E755AE0670C,1F69EE0EC6443BF7,4EEABD7A95795443,003026E70427CF10,F0CA5000FB005FCA,E0F11D92D5BF9740,8382582230E62A5F,545AC5342B7A3FB3,4292076663CAA4AE,E25DE9A4826A6345,46BCD59C8EFEE162,002EE72E2B189C30,2E2E8A516EB29A09,63FB2C3B7EC3522E,AA18342BCF88F857,EEB88785D98BF61B,5D433D9744CFE3F3,BEF0392BE00EB485,53C4A26942BC4106,00077455A2C49351,61DFBC5D3671B149,DA6B59207EDA517A,E55968E6D1D36134,517769F1C47B0CDF,E6F03782781D2B33,DE249FB4CB5344C7,1A0E685F74654A3F,0022C81B84C58A9D,B9F2D9BE2BF48E09,B8E10B8A7C9FFC7A,689196E5ACF0F2B4,41E3872D682E1704,9C8A2DA3AD177BD4,8410736AB7C91FBF,69B7A00E56E1647C,002DF49719286E0F,F0EBB77C49AE166B,3BB4F219E61E14B2,349A3735D511F8F6,3C45AE2B868EAD15,DBDCF31D737AB3A2,FFBD671A08997ECA,38ADAB66D1B6ECD2,002A47FE28E95C51,001E0EA7CDC0FF20,548ADD75E4E85DDC,BB50EEF7511D7B4E,A2338FF61F7EA92B,1CBA3708B5E7EF0F,81B0C5F59F5EF200,E417F49A48066190,000BBADBA7247F42,40392FB2FE982765,6E0323B5247BBF3B,4A293951A5775CD2,71EB84EAACDC038A,01B4A6A972C2E72C,EC187C20C70C6579,766A8DCE73FBCF65,001D462C39EDED9F,0F9AF735D90CFBBB,D368D0631EBE121E,286F3AFE4932AE68,3E605298DD4716C2,6A539EC30487728D,F94896D980B61A09,ECC78AFE9AF2EA61,0011467A6DE4F6BB,4653B5E4BE9F26EA,645B52DA88DE018A,9F6809CF6BBE0F64,1EC4C3027D3E4E90,58D98A7FDABA5047,1D186CE781CA57B5,44E3DD95CF12CDA5,001F341C336EEB5C,0D94D2DD0950AF19,09FF725D2A8208BA,0B24EEF7723C83A8,E6B6FEA3FBEF1C6C,204AA70A03CDC653,D3445315F598DF86,40146404A98E098F,001FADD644D7A91C,4DF4E621AA40BFFE,0D042A93B5874CBE,8767EB430F019F22,0F443DFBF0C07531,FF452AC1B80455D7,EDBD357505011528,F901E6DABB2A6593,002FA3554E508EA8,19FF19847227A3C4,BF045F0E599C55A9,6309A6DAB4312376,2F7BB10E2B933197,AB95264FBED9ABBA,4FF94F641525290F,39AF01E2292533F5,0020DF93570443E6,43D1F40D362F227A,F168E9D558A12D52,2AA82295DFE8BCDA,44DE7579F6FD3B0A,373EC860DA8B2ACE,C2298CF9ACE8B47E,362997010860065A,0023283F82E17D08,CAD6AF4DAEFFD26B,36450114A474D7FF,A3F94D648FC9F98D,5AB3ED0AD226D8EE,3476A338CB73DCD4,4C57CE009F65722C,30EDC8A1EB512A90,001B18D10C31A82D,EE56D34788E0B283,E236C233760FC331,373C77ED6E9BF2AE,33438B895DAEB55E,A74C68FCBEFE4508,45DC747082CEEE02,C7C8C950FFA76D9A,002BB821E97CD798,AA67F1D5FE33D409,4A42A0234A606384,3529A0D00CF3AF1A,A8FA8DDD97DE0801,9880006F0EECD8F3,7A969887BD9EF229,B5B855B35407829C,003C4115A5D3925D,616CE3035469CC64,05F4441B215C6BDF,0410C0605CC8D217,8331BD36058DB4A6,D10CC487A9B092F0,298A7ED0943B9FD5,4F40098702B951A1,000F59C5466FCDD9,CD1043B945474987,1C7857505D12DCA8,7CA67136FB10F0EC,B5610309219609A7,96AEF8974726EA91,8ED5CBCCA3B568C6,08E7EB9B6FD1E467,000415C6D3CFF947,43CDE1A5693E10BB,17777F63B9E66F71,0D4A7112002C75E7,BB910C281C8B7C0A,923DB0F33064920E,E1947E09EDE6FE53,3F7F54330413C8C3,002700E43966B4F3,1C42FE6F0A3A45F2,2F7104BEF57C594B,21778325361B0BAC,CD25889F2EB78E3E,822B850DBC107F1C,02E0410BE5D79486,32AF76FB2FA97CCE,000787E179207641,33B4D14752E4E9DA,A124F1F4E5EF0F77,08B9A5D0536ED898,6D0AD3AC6993B094,A61BEC3E591B9773,7027ABC0EF36FC05,06FD70F7D8A6ECDD,000ADDAB2F3C0A8A,89019DB54DBF80EC,12532F9F6BBD5129,DBC3D94A838A80A1,AFFFA23F8793EFA9,D0F8C7BEBE873AF4,3643A167A86DB431,8088C266DB8ABD13,0019EDAC05533FD6,8DBCE53EE8018441,E8335B6A765A2AEC,44C703E5C48F504C,1DBD7134FAB340DB,3F30F4785DF8739D,51E5AF0784AE037E,A50DDAB0AE459957,000BCB9751930BF5,036EF29A1600C7B7,03435DEE05ACBA8E,603ED0E0E8F974E9,9A3841F0A8937C1B,5DE201CD73E5919F,ED66B01658DDA40D,94041279B979EE71,00086C95E97C627A,472B8590BFF42266,D4E36E4438A458E7,6FF399F82A355D21,9AFB1F3CBDFA6083,17E72771426137CD,2D3C1526904D8FDD,BFA0CAB423DEA1BB,00146DCE2AC890E7,35CD156ACEC7EC61,251734F25BDF37C8,48C4BD9BC61DD67D,F966C08927B2FC46,92F0FD36E9A03F03,8672F5BC8E1F78D4,C14FBA8A757A0DD9,000A388387B89B70,DADB20448DBFDD20,4DF3B85542DF6A41,B3221A2E39748083,C1EF24DB9691CAE5,28C123A8EEAE01C8,283AD140FDB218EE,27755A3978DCD352,002FB3D407771EA8,D05D84E5B4AC0E45,EBE0CB36B1B4CC7E,4E0822A8112BA8DA,E9C05DD8CFD569E1,878195D8AF2100EF,88A5B1A7A81F4BF8,F5DE53FB471EE2D7,001A6F3E68B88963,B85053974714C276,55DCCACB58AD452F,7A5BA0E307EB3C93,5AEEEFD546E78921,BF0906E7D1E4870E,F81B85444FBC6B69,36D6BE3E3A58A7EC,001A78C7683DA946,4B5F4ECF88629A5B,1235059DE16A5DD0,A0D1203934DE4B55,6E25FA308788F47A,D0A93F2750B89686,79F3043613B9BF48,86B9DE3A36352658,002B49B1B9D78438,9E4F31D8BCBC8342,8A0E9D91B6F457B5,9F57FAC40D2A2E03,C208B734BB699048,DFA9B28F1F57C4F8,60487203B7ECCF7E,92306F409ACE99B3,00390E7A6031E6CF,802AF661775A1636,E9B552F89CC22423,77C86D3EE177E5E2,11FC4A3BB3B2D8A1,3B84E960E813BD66,F939006680CF1514,E9E52A03C3B3703A,002D3B3D8340D571,BFE73FA14D4A18DB,A192CABBE552833D,91F0CA460D7F6C32,C6D4B72492A0C372,881B3D32D886DEA6,9FCAF9D6D3236A55,77CB1695DED725E8,003CDBF0432C2E43,2CACC1965539A16F,1444D4BD0FCF3A5D,692F79DDB787E16D,92B8B9870D8D5D88,E32E4EC22037779E,196CCF707A683F6C,583ED5708F8BC371,002EFB584C64952F,BEA38DBE4643D98C,7E90DF5ADDF6C48D,84DCA818D39C6F7F,1499CFA090DA6CEF,6950713E288CFE16,6BD53566DA024E63,14B2C152CCBE2E35,003C83FF2724236D,89E25322395E702F,A13F62AF08819E1F,F8694EB6734CBE18,DB15BF7A670A90DD,2491FA006A1B698D,28D361278213C257,8A9CB53680BA1E06,001DEAB3D06E23DE,0462BF9F1F71FEDB,3DA41A22F47B5BD4,0DF1BC331D936E90,77CA3E7C939F87A8,B207B7FA9352DF48,0174E5F6C6444F7C,EA77D60CDFD46B74,00160B16B9786967,609F678B6697381A,2BDBD4D02E5D8134,277C82CD6CA1F0A5,C7A8C4EFDAB52682,BE251796B88DA11D,4D890348F3704430,EB2A0C55D884E482,000A23D31DC124F8,CE482437607ED196,34ED0228B7ED5ECF,D5491BF0D97EB8DC,0BD25272CA0A8600,F491DD993D81A2DD,00F69195E6FA1C2F,A4033AECD23B19BE,000EFB5528A46A52,0F674D3268FA923F,3704E220974F26BA,1A200EB4313E5C27,9D85B71DA1343FBA,DF33268109C58652,ED6C15D1DAF1FAE0,CBF8CE69E296B025,002DDB049DE17528,A0E506301109690E,C0A07AF954A8F06C,64FD23751F87C8B7,416D25B461ADDD9D,AFA0DB0EBA14F841,6B84687D04EE58A5,9A3E75F7CF26E5C0,00397D797B5B5487,979C29025A936B6C,4FD475A1891BF77D,B19E066E764EB693,15F60469669213F0,442B3BE3C73B4857,E56CDFA108DBC2BB,BC493899CEDC09EF,002E89028C5456EC,57437B91CF5A73E8,B1A1953BA1F950D9,B82D257217F9DF49,CAB5790EDE78005D,E09BBE1E131AC90D,D57028E8C9EC036F,7F0101345379E758,001E83CC91B41EAF,8D07976B68406683,E2B2646C1814A8EA,BD39B4E00E7EF862,8A9C443A77265094,75C25F87757BA53D,4DDF8C6344296E02,44F444C14C773116,000CA31EADD31399,32327699EF153FC6,74A131BB666702C4,10CEC5E163F7F09B,F0EE126AB0929224,2E5CD467BCA23F6F,456D8345004E1BF3,82BAA9150AA40D02,002AECFD821DADB1,5F99A67229591CEA,AC5955FC193012A6,9098D726A81D19B7,84800C0D79D30569,74738F5D5D6B1BDF,756365DBDD2A556C,2343E245707F66C8,002976F61621431C,056EB555E4289689,EB15751C51FBB899,BA048171B426F01E,11D5572F360BE6CB,F979C6F64EFC8FDC,210F851FA8793641,5753A965F0B4B515,0035697DCCF8A526,C019D1C1316B75AA,BD7071D6C4A3162D,6D638BE659DA1935,EEAF3508ABD93AA0,122295108C6B6D3F,71A2B3EFD5210C3C,5679AE22F6A895BA,0025F7E07FF202E8,6015EF3FC4E5F3BB,093F7510EC295028,B52F87F0AA9CC936,3BE3F2D1B2DA8BC1,1CFD107E433A1B31,0CD6C0B15AF6D9AA,CFBD84BAE91C8CCE,0006D0D0A9105E96,800F0EB3E01B729F,85E0A05F5A3BF790,B61926454767A77E,C82313F9E15770CC,106BE10A07AEAD9C,9CE8154E70A1C302,6ED64ADDF626C684,003645CE3DB733D3,D321D0428D48070B,4958E5E73C5FAA4B,9D3537F30EE3B43A,811EE7FFA450888E,12A12BBEEFC6A676,1B86640C37DCB785,6C098995F8B178E8,002D9FB8D05BC4CC,728E7E45A14618D0,EB73E6868480405E,8C2837E881A1F801,9725BF93AE29754D,516956847B7BACE2,F6C008E4CD32BDFB,317935C73BB6AABB,003FCF29ABB87252,6ECCFF2433B83903,9320EAB0D91AA40C,24DAFD70A0B7D394,B6575785437B115C,B74D2C56C560FACB,36E8FEF5EEE8F882,DB3DF00854AEBC44,003F172C671D99BC,B17219E5A6579225,0AE486D46F9DC26D,B2809EAD9C6260D3,E961DAAC6292C74E,25D5685B5E7C7F56,AF1C5DF1E052E7C7,3B1DEF0B1F21977D,0021703069343F98,4373559CA33A58B2,5ABA36B457733342,B6DD2342E0519FCC,A85A07B1AF76ECAA,8A2C8E9B4C0DF83D,90B5BEB6920699D1,D05B8787C0A7FADC,000301C9307505F5,3B8B45D0CD911AED,D973F04B97EE54AD,93A69C63C7692751,00EA38FCDB0BA9E7,03790DE330E6F6EE,D206BACC817EEE7F,FE699A1D2BDC584E,003A4B4C9E6E5730,04E0AD8E9BF266C9,32BBC0BFD92CE93B,DD065A1C86DDBF7A,24D0D80D9DE6CA5C,C92ABE1FA0510052,D8C500DBF07FF909,241AD45CB9CE1095,0020146556B92879,2A33FB60C4234395,7B60D2E3A6080249,C21A66F9AF26AD95,3A74A2DB74556751,4A08C9D916953D24,B0B4160941529D72,EA1AC59CB87A86F6,00252165CABE56EA,82C5ED002F870B20,ADBF72B352A14D91,AC0AF4DAE121EB9C,7C735BD962CF697B,052D84C63F4AE1FD,B452F7E768A2AD5E,07EA0314FB98D9A4,001C7E62CD343832,27BE2A3CF9CD1502,59642ADD9ECDF7E0,2EDD5E7657AF551B,CAF25453AD41C52B,6E68BEBD480A414A,0710C81FE9F7C4FF,E9A0CF317209052F,001611B28553979A,C953ED8C14B0403C,07B73E6457AE04C9,86995817F318B9C7,40931F896010BD66,1B2C883E79D9BB97,B85AB01FF13744E5,82280183A78E346C,00380EAC85436498,EF7E025A28DA1A9F,B2C38DF61E9AECB9,D92C9E7697BBB980,EA1D02D587049B03,B1BA6E3CDABF695C,FA512794AF4BA0AC,3F275B6C782CE9C1,0017E1BD94E5C869,D9F1F0ADA684D15C,B390011C182100DA,DD966981B7829593,4C6B7EAF20FA37E2,7713AE670DEF817E,1F2391081EF44847,F8245C9AC00C8284,002683CC7F878E7C,3024FB03513BE58E,CCA5743F77CDC027,8288591E26076BAD,72B7A5A920414F19,4144C51DC0BBB807,84BF87EDAB8C5E8D,8838CC47F2FAC99E,0019A262A874E4D2,9A34F26BBB9C9AE2,0FE3437533EA60B5,7B4A7BAE4FFF4F75,6D23C35A1C54C5E5,256EAD7399A3B0BC,4D13B01D775B869F,38784EC399F68A78,002883B7E45E8D5C,78FE41942F244171,EC3090E677D8F629,E0F42652C5466BC4,BBE9C30B36B8B016,8514E732EA57436E,88AF5CFE73BA9C98,0FF913354355777F,0012F14532CA3871,EE809F44B172F262,40F8EB011BFD0B01,EAE209C03D1BB65A,F5DE6B596C8152D9,F46DEAE6238CD483,80F23CFB6185EAC2,086F29F02944EE98,0000C3E9D867EE46,76558B3F5BBC4377,022B90EBB6CECF4F,1265B71309398C7B,11DE59BE68CEB699,914AD8D1E3C2E32D,2B553A96EA87A5CA,5CD24C4E3268F7C7,001E4ADB2690D6B8,75D57C8859A686B9,01F3FD34FAABAF8E,39ADBC8136CD560C,8D834525DBE4C2B1,CBB6EE355F22B61B,2C2B57103650E27E,9FB5225AB484CDEC,00179358AB355218,CD2F5CF3BF909C42,ECA9B539D403FE06,A9FA5F32F72B8DD6,25B8516A154BE988,19E6F65D95618FA7,07E85A031B092FBF,B5B987C06FD8BA12,0035D84B3D503875,554963C4565F358A,6DA10437D70892A6,0A80512E421A518F,0659674526264960,76CD3C1FB0F87684,B22F64DEFADB84E3,005575F7E95AF4A3,001B2838FF21D75E,D045560CE3C7A817,8AA27520B6AD4E9A,1CC22CBC60B2EE4F,99FFFD2ACEED907B,FF23473E54C8C8D0,253E6A8194568FB6,984CCADC5030356A,0037B5D42369659C,808FDEE52C09CC2C,3DDE574A7BC276AC,5B2176102F0E0B2A,64737689858689CE,A7FE4C2BB839BF6F,62C0AF898F03AAF8,6AB604B25715BA81,0000E096C659B3F2,AF9DDCD2C29F087A,9478F229D8D8C748,5D4CECC9CC657DE0,E12F72C0DBD9DF1E,6ED26D507889A88C,1C8160031D9FD8EB,D0CC42932A80B8FE,00389A4CD3E89FE0,69368691D8078F22,A8E334BE138B64F9,692A631BF9AB8F5F,8EDB21184C86B871,B43D261DFB3F99ED,9D4B9E6FF1208B93,99A3609AEC225370,000210755DE81DFB,DCCB4A02FA0BBA83,913C3C75B9EB22C4,F05B61AB2CF29B01,584C24332BC13EA9,8E584247F06B550F,7E2F43C81C8F042A,DCB6A981A350BBDE,0020850B217FE321,EFA0378FDD47CD76,F09AEC5F4F7FC666,6F5F44DE73F19E10,5167EB087F3124E7,64219CADAF7E48AF,8EDA2D9A986B8683,55BFAE950222EEB1,003E2256755BB80C,080058C01A53A1BD,7B2C248998D813D4,D0716F0FFA936453,FEEEF61B7BB395D9,437D12DB7ADFAF0A,436130B5A4987D25,84AE73DB84B4D663,0014695B4F0C7763,3A5166577941F9ED,C8AF6792BD29620D,A0E4384C2BE8AD13,3F372FEBFC623CCC,9FC3E1E0424240C8,5C3EF3BB38A35E91,3A8A8A43B2DBF5C6,0031BF56DD51A3DF,B2D9787F2C108361,F2C16F6680234AEC,FE08CA108D9ACDAB,8B298FBD4FDA84AE,1CF3004232DA3C99,21556908C7F200F6,97044C3C54207C46,001C8B868B47C4B5,BEC25F1A1C6D9DCC,BA6C600DA8C93D2F,2CA85D5A9978030A,FF0C40A6B174763B,C27062B73F1FA529,7C20857FBCF02F5F,2373757BB978F291,003623E6D7634131,B66B858474CF6315,7E58251D187429B6,66F941272EA54B69,96F5B2E1AF26B6C5,CC1CA444E17207BF,054576B0A8CCF912,B4ACB6CA7231C3EE,0010A13ABD856852,CF44A772017BE933,41D4A59012E6E5E1,4F716F7BC7610043,18EA57DBD3642C74,AF8BB0B758A831CA,C2E65E40401F4DCB,40611176F0A87E14,00281D44E0027F9E,5005AC58B4FAFC1F,C3D5032B618844D1,6936F99A1225564C,E39085AE30A2F218,1815ED4391D23CE7,80923A1659DFF71E,044C32D12D42563B,0015450C6E117B45,40329EB955A0FF98,3F7FA8B7AB47DB3F,1687F5D3054986AB,B8DFCD4DC7F3E2D4,018E3D6292FFFF0F,B18C16476EDFC591,2F35B040F0907739,0007B4F7EA0C87BA,3895A7F9F780E6E8,5085EF7159679825,92C9A940ED2D5E7A,B5CAF05E8EDB9D64,F50F5D9F7D1FD533,E8884EDDC700A40D,2ADD8E6F45159916,000016633447CA0B,6A3DF8085508681B,38E07752872EADAA,E9EC34AA2EEED4E6,1CCD5BC4630BEB5C,3D90C1A9314E818A,F84E160F086D5263,0B17C5A63BD8E4BB,0020CCC3D572D61E,489E34733819C40A,151343604EBC06DD,44E000641B7F1A6A,BF4A7E2C33CD072F,B6884F00473F93E9,C7A31F4503E3F6E3,BEE3FC9C15019DAF,0013E40A094DFF8C,24B76D35FC50283B,42BDF1F5DF175ED2,0ECFFCB7E82EFBE5,7DB2BD211F25B5D5,0A705C93AD203A13,86D43DF96184676B,A030E7E261EA7B8C,001341E04C845FB5,5A839039FA211141,CB5D6C2F61BAF490,3B7F97B5003D1336,82446C7CFADB3589,3FA153FE1567357E,9F32B4843513E98D,BEC52C1622C29FB8,0033F1148B9BDF64,55661DF2E44FC21B,14B31E74DA019AC0,0CCE5F8267B5FAE5,368C36517FEEF691,5D4BCE99E4ED0669,7D94FEB2FDCA8457,506936603E58EDB3,00374AF37CE55799,E7E21A995DD38CF4,AEF7A33B9884D49D,3FE47352DDBA93AA,7E16399978EEFDB7,9B5C008B7CF4E715,7E0216BD6D868B18,A103E92F170CAB87,001CCF370F72575C,B484F70EFAC1B72E,1B97D9616F71CE14,B3DE9CF2F6698270,8248FACE6BD1F262,3E2CE2F3900D6937,70863EC33617133E,085F5BCBBFCB03CF,0008B2FEFB35666F,396D49CAF26F2F15,B521179328D17D0A,010756833312F03A,E640EA17AE0170C5,6A9A384F05AC709D,9E1D4BA936F762D1,DAB3B6D8ABDBAFDD,002F8FEE91185C25,7FE9A5D9CA0C56DA,3BD976743AF0A728,57B6D48FB471D44E,7660BA4F297450D9,51F824E6C7705E29,1F3CB1E1B2BCEAFB,63A76D0EC0FDFF0D,00147665BF868F10,91E801D28D1B2A5B,12EB3B8B91A995E3,6DEF2E28931FD07B,E2BF07EA9E835CFF,F71557286C0948AC,572F27B4203F125A,ED5B752BD81C44B6,0022E2545F8A3E96,66CEB1CE201CB559,FCCDDB907231BE90,94F121820D1E55B8,095417E57E607F21,4C100EA2A303080E,946430AAB8617F41,4D0B205E94503044,0031A10ACFFBDF63,9725FC0F44EE2BD6,163DCCAF40D2590A,6C953E2F3B982429,905DAD9DD9ED20DC,0B56CF688E311680,2D97BDB91C698F24,893816D8FE85915B,002C7A76FED9295A,B049EB85407EB30C,B6364C28A98F9FA8,AE545CE50BE03162,F54214890437DF0B,300D870375617220,0CF79210D5738DB6,2232A3F3DC6A4E1D,0004A8DCDDFB3104,9AC45FC3F415065F,BB444FAC85468059,123D9906BBF95572,326AE496281B34A0,6B43C147D1F506D5,3D757AC95C091CE3,7F605FD8425C3071,001C6745A93987BB,544052B806C95788,9537FB8CAF7C9331,37725027B68707A7,7F5F08C0A68BCFE6,E5898D87E5F1D735,A97658134EFC39E3,CFB113A21695D437,000DB250BCEF81AA,834E663545595A44,E1AE5B0B9B4B2BD0,FB8083B8390FCC39,DCD4527009AE5380,B510D97C8B5499C2,A1FF49B6470927C8,374181443F12442D,000221FCAE1241C9,CFC6BF11DE44AE6F,DD5802C718B2F2C0,B251BE7996DA1107,C5D126ACAA2EA3FB,466ADAC0FD2B694B,64CCF760431FEDB9,AB529DC39562E029,00152744D4EF9C6D,EB8A628E2CA89364,5B83C5AA89E6351E,8705B736E6F977C7,11A51F9F3604F324,EC6743457D3CF817,AA9F543818847AAA,D9BD4E425BDF4796,0033C2EFD61D91D2,D57AB9706F302601,56386F9BE79A0E8C,3FC9A6E44B76E9D9,70A7E63A6B1F99E6,EFD7A488E16A3E51,6F97D7E0F955F359,4F31DF86B025F690,00028E0645CFABD1,BA8EFAB87F68DD4C,40139C56A042BE4A,51FF1DC8A4755DDD,02474347B9C1E457,80C78B1304D6BD24,D7FB12D927F1EBFE,F6C7752237219178,003C4D3C22769E75,98E3DF3743EE06C1,A6F1791E356715DE,F07F8F0DB6E05057,2E615F3D41C7DF70,6873CD0327876A9B,49E82B2FE436C257,E23179D374761919,003D55D5CEBCDEEA,A9FA6E8B3B00956F,93224D63B5C96C85,890A1C3D9DF251C3,50E1CCCFB8C53AD9,36F7A8FE3846FCCC,EBD0078C1EDF372E,0474E7B2CC861448,00048FA16FC1438D,3E22952D885BD8F9,549B9C52821F04BF,D18423402F2F56CF,E94A4A15004EB864,30CB73B1F3F0B412,ED83EFD7E9DC0D5D,E3FFE5F4CF1D3F73,0009DB6918AF3E0D,281ADFC69CC0DE5E,B2CBC69CA8178433,FD1139A388683240,AEF4B7777B67D3F6,11ECB3C6430DB99D,47394AD36A66425E,BF39EF62EE9802C7,001A4DDED7CAFEB5,C015325C24C0D9FF,E968ABD52BEEDCFC,19AD7CE1EF30F329,0E04B890F409F73C,9965C2423794C1CF,40B6FCBE31C1415F,465758BCB9F18EB3,003BDC36AD081105,F70A8B630F23CF51,AAACA813AFD54697,D406C05BCAEF1433,9EE9DA69C4D4D1E9,353B4B86CB4F27CB,9003BC2D24794241,6475D5C9C581083C,001711DFC806A64B,76A943FF6DB1FE24,BD9C17A71FCEFECA,AAD85453B0A48B6C,C9B5D55086AD62A1,82D94D61862F0FE3,6582E99BE5820A0B,C44E5AB6A1074762,00360D2E031F2F8E,8B0AE785F56087F6,9738CE14C10DE7EE,D6F65F55BCB66E24,7E962AA2A8F01532,8EC3394D25FDF446,6FBD4E9FFAA67699,F06BDFF69B2234F8,00064AA85EB90B3F,F73C4F57AD7CAD12,8F5A94522BD88769,A10A1AB6E91507C0,5CD2678A16D2AAA6,9854CBE5A3CC0F4A,C59EA6635E9E9400,C1849D1E43C896D7,00256DAADBB036C4,ADDBEF719C59901E,442793E2B052D506,62259A131C382528,1DE79E59E25C156F,234BAE23CB8FED59,E841EFE7E1BF413D,834554ACD57D3153,000F1768BABF0989,0CB8870E52C4B15E,06F0B401FECD05F1,C1EE6E9B0BD1430A,5814F973BF4BE531,AC28381D5859D4F2,793943AD101006B9,96DC4FBC6FEC3208,000B848D6763EC15,B23488E56430098A,2C2EC2EB03BB54A9,FDA7A872B71557EF,3C80362776CF01A8,28B56EFF094D213C,4EB885B30824DB3C,3A2DE7AF3D2B105C,003A4D6C84BB0BA8,514708FB8DF9FD0A,4AE0657B9D376A06,E6CF2C49A4C47852,577F9DCC33CD7894,934D52E1CB2B8F4A,3E27E4C77D5D961A,ECE0751241BDA182,002098A2C91B364D,88FD022724795541,4287D7A22825BC47,87C4CE6B075BA740,A24DC93CAC9EC4D1,5F03A363546B552E,DF462420908CBE07,56519CF61CBD3E18,0004CB8418569510,3E2269207912F44B,F0ADBD4BB8429A16,31547556147BD067,E974C7F1306E40EE,DD05C6E8A45500E8,3DD4AE8253DCA5C2,C695C6ECBC17EC04,0030694B32EDE53A,AA3372EAC8DD2D56,B1FE64F2DC001679,4A4A86C338C41A8E,1177773ED611EDB4,DA3DA1BB65B49531,143AAE929E1A9345,D8CC730BC95E3477,00298C0FAE7DD740,6598F6B46C894B2F,7C0CED8FAEA7E844,7A3D19E7718E8120,21911797E0B9CF89,5A1656E6CABB3436,880D666D91473260,84CE6646C495AF2F,003E58CA88A5355D,BF147F6EE7D92221,17A3C2C9117181B1,06CE0E8BCCC8078B,D51BBBEC1E5F68E3,B3458AD0888CD8F2,037E494ECF252D7B,4CDEC8459A01D3B5,002FC586440A9727,E3E71697DDFE3632,EA8D378DBBC7F211,E54B191435BE1F84,A7791570BBFD659C,E78523C7E327089D,C670082F8C9DE007,990F4C38FAB6CBA3,002CDA72D960E416,3F71B028EE39C379,759E58FA8D7B1673,34FBE55A4C7B781B,A4F56BEED567086E,298CE403AF4F6443,E61D646E9C2E6DCC,3B97A36D91FA61BD,001E13CB1E233101,9619EFA7A8467913,EECDA425D9176C90,C0140FDD84944632,774B7B540909039C,F4F90979AE416914,72170672CB3731A6,1D7595C22132004F,000B81C7D5E2D5A7,AB638B4A2F0614CB,A052447C061B44CA,9EC3472F4A2518A3,B1B7C85F507DDF24,BB79ABB06F7FEC0C,F8D2FF1367D1EDBD,E76B012891C2A262,001A5E585527107D,5558EC96B5047422,56A1FBD0F56DF266,6DCA2BA62356EB99,2372848FFC35BA3C,5B0585DD7B717B84,9F099320F36F0121,34BC93CC22B6BAFB,000F840BF79E15CD,7FB94B8B77AEEE54,097167A768360D99,1D3EF29F4B9938EC,AE2E0D8C54877041,396CFCDB20E6E08E,CEB5EA97B4F26647,04040CC2A6E3C164,0035EFB58A3C1046,B4AC67480AA4D978,9A0968BAFFC22B00,A19615827BDA46CA,041B0726FA823B24,F79D9A62EB98D027,A8CEAE1940F9D5F4,3C4570C8BC3F968A,0021A18362900972,34EE652FB688CE36,183174A7AD968B92,BAB9AEE7310B807C,87D7CE1ACDF6CC6C,94FC7CA9A14B330E,93271973569DDB60,1954B65EC734E8DE,00148AD715D0A8FC,822F89C9681BDBDD,D3ACBA94A09AD802,ABAE4579C3E387ED,38AD05DB2A750A32,D088E4005864511A,50CA0E3433C5DE97,890CC97C302AB55A,000DEC4E6CEB6893,6C547C0993DAE219,AEFFA3703D33B743,7A28506B366C0451,21B17A07197BD963,F373CB0E23EB5374,5B82A40E061E2241,1B52673D98B5A0B6,001BE859336654EA,AF0C27FAFDF92C81,B892FA9CA4C92C14,186E81DEA212CB5D,259D28B978F01B45,8949E1261B9BCBA1,25A5ADEBF0D4813C,6EB9F0CEFCDDC348,00244E0C06D7F5F7,099F042C7BD80C51,9D29AA37538B1D19,5D2B191C97AB9A88,B21991361D744727,8A136DC940445490,8D632A5D73FE1AB1,AD4D1B5F0819B393,000C3BA62011CFD5,AA5C170AC6DB7242,CE7F2C7C2A4BCF23,AE2DC38F2E2947B5,B32027DDC6A002FA,AB1A6AFCEA5A0CED,3F7E0A2007C1A18B,9BB5E479DF9C9B8A,003F5ED2118FF7D8,106089C1ABD2D693,8CB818CA9423B7F8,3C55F42A0D792592,FA38D2D8661FE5AD,41155D3B4162824F,C492D5EDE4925B5D,5D97A131A5C77251,002F7FA7173B6D06,6B4ABC5D21951AEE,A50A1A15D29A2345,4CF99DF8F75E4E0B,2FE3578852D404EF,1ECAE3D259F7EDC7,2774339CC7E7451E,C0526A676F71CA71,00007273BCA73453,0A7EBBB3C6A36441,DAC55199064C0831,91A93D09A677E9F9,B3249D3AF6FA840D,31BC075629530DF5,3CC865F17180FB61,286F69B4CEC29B6A,002588CA8F1EB5E9,1399D25EFE5D063C,B722E06657450555,850D06594EFDBA02,CCD8E0CC041584C0,1087A684DFA35C0A,9B24D4C7D91A6C6F,DCAA54F71AB1EC30,00146B8A2CC92DE1,51ED0BF47E9C4E5F,D92CABC21B8577AF,86F6C823084BCA66,8B1A285DCB0E05CE,47DA5421B33A82C1,2C23D8B9A8FB45D7,D73CD5195817D823,002A653F6BC448BF,9005DB727C0C37FF,8E3555443AA53703,F5D6EF713B1F7E1E,293529DDDD2B2A69,D6F04FADD3A5787C,8E30B3B821457DC2,1A98D5063F9063B6,003E2BE733DD10A6,2335CBF73079F0FA,C5112F033C2379FE,8FB5BB6C912FC1C8,34F2ACC5D12940B6,B46FFF58184B675F,7769664DC0245927,6583636CF6B3E995,0022AE9DBE74A244,E6F2A5EC1E412F4D,3B89B8AD7474BDD2,9490B16ECAD35F03,E4529806C3A83853,BF4E47495268CB5C,A8CC6F74AD0E7360,16E0186EDAFF7004,0008A89D992393E9,13932E0536B4A9F4,5AACABF9C824CA18,060A2D09A531BAA9,53ADA533DE5ED2CF,552F8EC693D40221,8B483BB68ABB8545,D4897CDFA1F257FA,0002BE7A45B73F72,E9AE8A8A6827648C,14564DA3A61F39A6,ABF69C2F356CB22B,C2E7FFB181177CAB,90AE306DBD9CE786,7CB469F3532B4F50,35BAC2E3733CEFAC,002C8AEEFF8C217F,EEEE752575AA1DE5,47A949E51C8439A8,CC7A99FD9E305644,F8043A3817E63054,6A1E58E024D68BD4,9A2A61B68448A930,9C411E90B88D911C,00357A7339C853DA,91DC2C458D99A262,8A9593359F85A331,551783F1FE57FC43,6979E42561B60C77,CC0A169D87B43AD5,08C9CA7502F8E961,42C27322A2AEAF47,0008FB699517F0B7,A8DA026A4322A9BA,EB5A3BF6F8B0A892,FB8CE0F08530817B,DD2958CE47EC21FC,B7FCF65C5AA76FA6,DE66661E73D090E7,1F5A4CEE4BE5946B,0002A483A9FBDE42,DAA09116744DCB67,BD6D1EB8B1790683,1D01F9370F4215E0,CD8B7058059EEC68,D5AFCA1023DD11A5,06C959B68E8B11F6,B6D596DCA71458A1,00290B02B26EEE2C,4AFE625BA9590CCE,EF4C6CCF926D5AB4,0DA8FE2B4BA25E58,C2CB3CB5C19F24E3,C05150FD291ADA1A,9E1A65582B935EE9,C96B17F4D25F545E,000A076DA05BCA89,206F724F9FFD0915,E8C12A7D2DE54589,DD51CDC520A0FD82,B337712B70FC5FC4,37581D9932688490,56C6A4C0A57168CB,A4FEF6CB886493F4,000173408530F0A0,088109DA2002EEB2,B25E6A4E588F983C,0DE6A74E6814C887,DF5DE0BA6FD54B64,41BF77BC59FD2393,7D69C16E597942BD,C770875AAAB7E6C0,000AB2A5AF3B1C5A,9C9BD2D9B84FD983,1F0E76540752F9FE,2754F4D17862E490,CA8F5E289FDA328D,0B82E40DC8A56BE0,9D4E0D3874732D53,FA6C42B7DFC3580B,0012D05EF97A4242,A18B1AE38264B725,1C23E25881C0F947,68F984855AF567CB,08C5F41A131A931C,D6619A44FEA46E3C,8021B69E44E56335,73759D4ABD223FAB,001FF5FDA75FA5B8,D9EB0289FD3D4D84,65721DC48961DE6E,758D88E0875FDF4A,08FCD2F56E8C7602,A6CA492E6130878B,DBE17D65F31338E4,DFE8D14601F20FB9,0034211DBE1CD46F,9DE9CA3C0AAFF65D,EE7009AC864F20C1,76C2A03BB24294E0,D8189D6A2BE37E75,1B391F899C2774DF,EAF6022C518EE963,2A5000360DF1CD8F,002B5F5E3BABBF88,D54CA793BDC0C673,F312B3FF8E378124,C00C781EBAD7A698,3BD7181D2F778D79,6A75E434B3454F37,ACE0D87962B786C0,EA44E646987E880E,00144888AE5F37C7,839320B82E306D70,54769FC440846ACD,76B6000C8FAB539F,66B8ACE3B459E001,84AD315C35AA4592,7D5DE42A8F367F21,A71D594073D8D88B,003C0D46E3B86BE3,2C3FE495453BD580,CC5F9B3560E47840,7D80040ADCB997C5,AE7BCE80E38E5AE5,5AF7C9655511F21F,75DAD74BB8A26D3E,70AC306538439978,0025CFD4FC533818,1E88DE2AAC79A704,C5C7F4AE70511D00,DF8C854A1FB71B67,4A9D5B1D86F3569F,A149E1D485B863B2,55D1DE226EEA6416,1DCDED0E440EC030,0006DEF433DCF613,C8200451A48FC7BE,C881933BF59E57CF,71D0A09004896596,FB493F739F90EB59,A8CBE0D8A3103642,6E059288F362D087,272D8A09F4C19562,000DE3CC6B2B8554,12AA0EBFBCB6A66A,816DD144D76399AA,7C9E72A4878ECEDE,DDA38E5BF57F6D12,A1D98DAF2C4D423E,482BF6608A277FC4,D822FDD2CEC15D6C,00250EBC641B7D44,3FCEFF4900DB99E5,D4CA2EEE75F49C46,5E2C70730757CC0E,923A40594EA3DB4F,6AA530AC8B25B9F7,8797F17256260255,E6F781668DDD3CDF,00288F7D501A3AE4,5F1F5057DE968869,FE95B8A70CC2636E,A32095A6D5657A27,E9D8B739BD7B7A99,180DF15A1B3FDEF1,E50308DA5F42CF37,DBFFD673F97B2A7A,003D470713663F28,BFA25736168035AF,49CCCF5FF087D4B0,54A3FC4C128D4763,2466094A75207B04,5222A501DD727F93,1E2BB835C2E27EB9,C4247E98E1ECB416,0039F661E727E043,6BF595869DEA8227,24DDC2B8D62A56A9,D3BFDDCA9F54B701,12387345957BA724,4AD0750B270FDBD4,4BE0A07EE206E6EC,DC1B6DC47B6C653E,002C2E418DE2B597,BBE9804F772941BF,EF03A56C4CC3BF24,DBA3CBD6B1BDDC9E,8AC9E1D1C3635A9C,C7D410F63D2B8618,3BB9EF624EFBCBB8,8891507AF33C90A7,00219B86BD051F3E,F34F81DA9C578B60,3A36F7909AD93E9B,2A6D304BB61529F9,658BF3BDAA230D2C,695F4717649E2512,205E38494276EF42,0CC66E2E24E5F989,000FDDD55B87BFE0,9A350380E034C581,60C0A4F70C2D920E,91E62B26E860365C,94480734D9BAD772,2236FE0B4D9D00BE,5782B49B3D18EEA8,47445CE69F7CB640,00090179CCD4B243,619D3E8CF77F705A,BA73C7F6B0885F86,99260D9ABBF2D6C6,2B49C478F875CFDA,2CAD2C3876661087,131D79A934D5CB40,B5756D559EE852CB,0007BCE84394AC51,F88AA71A863C52EE,418F760355B92C88,4DBBCBABF005A91F,A955B440A988D772,920D4A5827B1DC1F,C8FF39CE8E8D040B,BD7A1E784CCBE590,000D53AF4DBC8F75,8640CCE8B0B03CB8,D78EF6E7516C1F09,336E33EAE38155B1,40222212CE69EE94,AA181A828DC520D3,FA62B11A0184057C,8E9C2D3583533F11,0038BB3B6C931381,5FC53D16053BE0F6,20C37BB85BEE877D,1C9048178442A2CC,D6BA302E1EE24D9C,83B19F778C316C94,4BCC9B6E1102B171,C5A3900CDFF3714B,0013788EB3570A29,4879741396712CAB,628C5F7D966EF506,E6D7CF46D01BD886,5B933F42F0564749,3D214B91F09AC1C4,49D0B6EBC9BA23B7,05D1A21FCF07806A,00234ED340CD4404,B609CE85667D9734,79C7BD8F986C70AA,CD5286D051B89FAB,4064DA16A93C0F23,FACFB4CB30396CC3,4F5C0B6E9A4CBEBB,4F0D11374AC6AFAD,00351D4EDA78894F,1E1BDDCB871E63AB,85F81C06919406BA,362EE835E37A50D3,057BEFF8E0AC2775,002CDE86BFC18D3B,384D0F14043E6E12,489DB9D60F360D9E,003C384E24A3D289,9B9A92CC022980A7,3EF8C6CB6C707DB5,D4C491D9B7E6D740,67CF5F3F57E1D422,FBAEC178B98BC96D,7F4694F4BFEB7538,7335E1605DC4A65C,0010DDA94AA93BA4,BC50D1234B3A348E,F4E90946DFC635E0,EAC74675E8FB0F21,D00EBB5D9C0956C2,78500F11E1D516AA,146B74A280277C58,61E761FC941F7963,002F282CA376644D,E7D3AB7ECAC22CCF,E8937F0B3FC757AB,05D4FB10154FC265,B20EC865A74EA930,673D8D2FF0C30E52,37A993BCEC18FDC0,191826315B2F243B,0035E812EFA2C653,5330370250614B7E,A73050F769DEB7BB,AF9CA977B6D48178,92936D0917EEE0B2,395860987569B513,7CC4E6FBE7E016E6,4CD575A046731F32,003E12813F3C5189,8D05D63D1B60A702,946F33BA47804284,F612F8F6146FD531,C41205CCE502E9C3,8A0EE59368846A53,37A8DA60E4C06994,637AD17810684D80,002F0E44716A0F72,44F3E2479B12819E,4D9165433B724A2D,3E77C5AFEF287A4F,348817CA428F928C,90896568535E313B,92747435622273E3,277512BE6EEAFA45,003B0D1705FD5A9E,539C56217D1B3216,F197D68BF984D28B,9BBA7DD275864C28,F1A276F8F7E86C1D,2EBA8CD9C3E92D59,60CFA5A8AC483594,C8BFBF87B6C06A4C,0039B982C64E3C23,D9D7A17320B0076B,62454665599A50D6,56342860587C7849,D0DC20C3C8EA35BC,0600D9A881DB65BE,337FB13067A63A27,EBD2391251DD6633,0007898AB2340E1C,5E925BBECC276F66,CA26FF9A66662CC7,D7BBFE55B720D274,EE7DA16644A16D42,8466B8CFC7A2D78B,8AC4205DD876629E,B7327504258D4125,0015547BDDE45CB5,5E4E2A29F061B917,8A87DF73BB868B34,7857EEF0DD93A96C,361D41378C11EEF6,54914E471C13FE38,28B5C1A02C37EEAE,A782C083EBA12F67,0002B037F2BE431C,3A804358B8BB0C4F,DD0C0C886AF5C35D,4BAA226620C84154,27B8FAB740A6B285,9FA28CD525DCE09F,CCBBDB33C40E462C,C55804DC2C36C3AB,003123DEF54959F2,6415C23C55DF3851,01C7CDE5E9EA70D0,04D50BFD404B6EFB,06C5BBD4553C6594,E3DD4233AF07B5ED,5261F3B4FCECDD9D,FD5F8B556F46E3D8,0003D7C2C1CF89EA,48104E3C0AED4F0D,BA2F8025B171AFFE,9B92D4B5A00E9B27,A0FED17545A91A78,FBE92B0B65B08DBC,100CF80F84BB6CA2,A2497668F8C89DAF,00402231C81FA918,71287B197C7EFCD0,F3AABE82F0D07CCD,0184ACD9C0F6E150,CA7A9897EB273657,4187F313AB8CDBD4,6ED8F90683BCAE5D,2620F137451EC083,000E45B3B592FA97,E9EF9D1203F0A6CF,E67D1DB92B06E117,27D86A7CA093F745,0D542117154CBFD3,21E57AAD5D42925A,142CC23FE3CACFC8,2FCE8EA8A82657AD,000A2D77676A6AF8,1EAAB7268260D0D1,67071EDDC179DDFD,700FE834B64F072C,E2A8E543326E8A9C,78A1E22FEB3F6886,13663A6DDE1D8760,01CAF05E50BAD0A6,0008FCC8B6C1D9D7,44C0384818687117,969CB817DDBCA4F8,C95C46CAE546EA1B,ECB7C3B16D99B263,D18799DA4FAB011E,E837BD0E2E474F22,2245664CD3B99444,000FE9972C216AA8,4EACC14B5F245058,746BAE114AFDB8AB,12292636B007496B,2735C168B5E301F1,57C0AC4EA73CD452,D98325A89D30EB98,35DDECF7B51DA4A3,000513DF301E2D55,CA032679F82361CD,0B64DBCD46A1812A,3BE07FBDB1F44C17,8553598236E283EF,3AB55F97673FD89C,56531F110E46ABE8,3DB0535468870FFA,000FE38A5ED11B65,69C9F4C93BBFCE97,51D485DAECA5BF3A,855BE62517FE6DEA,B29294B18E82506E,CB596BBEFDF60983,9500EA40EEF28EAA,19199A2D78C45417,0006DBE07422B02E,15879212107B5058,A7A5E88B4CE27B38,BFADBE0AF7F2ADB9,E542564FBD1DFFA0,0A8D6BFF375FEAA1,CE96EB285A874168,9BC23F91DD1F0FF1,0002905AA90E91EE,8A2C20EF473A53DC,961D20F533720DFC,21B1491BEE9ED528,D5BE089B1CC41805,11F6BF8DADF7C157,F3728DF4BC0C7A96,8EE3C3E944B2528A,002620FA5CE9F989,A0FD1D550523E308,D8C40F07488FF334,6EEC497C310B6560,B4F339FB6D663566,F0685BAB1C6AAB83,7C712D85B94E585E,9A43154A4CE69E5C,003F7E1083DC6776,ACECC8C11145430F,E242226C6681B7A3,55EA22EAF84901A9,B15FDBE9ABC3593C,D9D532F7CC6BA5D2,127C76EA1954196D,77A78413C6A81603,00081C1F5C05480C,020C320047C6812F,7290161BBDD6025B,1FC2477925FA1CC1,64F245990AB54E40,561D61C5437810AF,4D5F4CFF32FA49CA,DDBD84F64BBA4AB6,0039AB26268D7BE0,9651F2048B3E35C1,3DDF87B3C3866F23,6F288920E2C9C938,B1A221F6D2C170E3,1D4C95EBC3E596D9,71168EAE4E67975C,AB4F3A4AF2C0475D,0002EE322179C7CD,EF6FF524FFC6E925,1DFCD72F7CBC3C22,EE523B58837698DA,9C7B6CF9C2E8278A,F69CBAECEF8EDC84,5CCC94F40FFAD392,65FEF2BD536A1D8F,002624AC5B63E57F,A397AE96C239E88A,24E68CE7F4A92C15,837A371B1E046CA6,43829BA37CDC004D,A1639075B51CB6A2,6D4F9525025B0A5B,B10680E655E0C9FD,0032A33AD4F66797,4F2F9F8BBC0C4852,0D89757A387D58F1,5E3E019349555173,66639D14337B0588,59DA8456413181C3,92A8953EDEF44D17,99D7CDDF92931E81,0026805A6D238978,034CDA652760115E,4785D532D75A8388,4BE3E88303E21B0B,D03606787A612A57,5991BD01E9358A59,A1ED8EDE99AC6265,60BCF4ACD6F6EFE8,001D799E993FA496,20C21651CA4A5A6F,4A0521711678CB11,E9C64C91302D9092,77F4759E9B9F6EF5,709EADA0B5DF6E14,061E521A61AB2181,E12DDB07EA4A451B,001E792BD518F8DA,8A03BA8118F0ED86,6995E175A4675CAD,39B4AF946C380B38,000CE6B5993E453B,E1DC794DB6F3E10B,A8413BD0BEF77BE8,923AC5610CE2A4D8,00251B722A2D8431,82B13F2CE482FE43,972BA5E475C8A7DC,DE4E14762DB01F29,AC3457F719966444,98E6040747824BF5,19D4B41F29CBFB3E,B55A82780E24A14C,003E460B7E9C929E,7D3AC336E49D2896,811AA9DBFB37A67B,397D799594A945D6,526F296DE6512F22,9D2E8D58F1F3564C,60FD209D1AB91CC6,C151FBFFB8F3A828,00222B99262E4A85,5C373986F471629D,0E1E88CD4C5AC04D,FBD222B7516B57E4,306B2D1CCE7B0E8B,C7631687FD00F17B,110020FA43214C63,3A8D50CEDD4C5020,00082D6C5F026BB5,2906B13A1924A14A,8D2670FA9D7E8DE5,D5CF13EFDB6E7540,72E8A040ECA33D62,9FD7C1B1789EDEE8,4F96F1F382A283E2,4A55858C94BCF964,000534C2F0129B1E,68E3899CAE2385F8,2E7CE8B4C1B77FED,629770BA69D8FF15,01E8CB0836BF0303,F5617561DE64B04F,07C0FFCABB7337D9,9E0AC19B6080FF82,00350E7637D3AB55,4EAFEB1CF6D49FD0,C7A592641B7FB1A7,C648AD6BC42F31F2,2C88BAD22E72436E,723FADA3AF35850E,D5705653365E23AB,54E955023047B495,003EE377AB795767,31FDD1EB985B78F7,BD19309E0DEF70A8,638985484A838CA9,D23E50D31D9D05CA,5CC3EEA5E05B2C60,54884211634EE1D4,A0939EE18987D564,003643B814B9F02D,9AB0A34C5155F38D,973B374337AD3E25,802D6DA431C845AE,D4FC0996ED22074B,718052E9987E5E3B,781794506E94C8FD,53801FA263C7D099,000551C3305A9717,AD4D9E59634FBC0E,1301579E1EAD1C91,D60FF0F35FA27537,5E1080B6C12584C4,1A9334CECD662A9D,F493F26036DD10EB,D821F40A43F9D732,00129716F4D4F1DA,93E685232962E0A2,4EF6C999F8209C0D,E0987ADD77C84CFE,36EE334871738C1D,3EAC9E3AC831AA18,3BDC27287F58D319,054D867A3198AE91,001EDAE9C5C10241,E07B782F239D34BD,023B70F765985ECB,10FC0CF17C1814EF,662AD72AE8F03E65,269996D5DAC48B60,E0CB654131523435,A67012A80C3A942A,003A3908969893A0,5B3921B8C995771A,1BA708F665B8C68A,DC37CD5C6D17E20E,48BFDCDF55721E10,E51604E5176A5D14,1BFE0E30BDECEA68,62A329CDA4836311,0037F066B3F32140,6F986CD09F1F9E9A,7EF1174552DD0B94,1D05A514BB4934BA,17C2BC2A3432A8F9,5270ADA2533C9DD9,EEF50EE29909EF92,19AF82A1E6864CA7,003DBBD6AEDF5604,EC55B836E12A39AA,47A13619967DD21B,A178E7684D1F2B6C,CE80950821CE89F7,3162EF27754BD851,6AFF22A3133C0F92,D2DC7EE6759D36B4,0017D6FF7F87A177,5C6AE619BD9957D2,DD919BA0DA8987CB,C7208F42A56FA5C8,D4E2C904DFE7076C,26B85F2D1145B286,0304BE014F33311D,68C8A152EAF076D3,000ED483B8039DDE,E306598AE79C5B5D,62682A6B49D95D10,9E10EF0202FF2068,6598A31BC9268CDE,3BDB6A7CA20CC0EE,9D37AFF7A6D19DA2,24E4F7A73FD5E763,0027B679AF6FBF8F,880B00EB8206969F,9E6C65E4B6573391,EFBCEF699F3F25CE,D94E82C8ADD9BB89,3359E1C76E66C9FA,89EE0C3A7C9632A0,426BFB12CA988010,000EFAEC5B855AAD,CB7E6867D418C626,FD56CDF93496CA51,6789A4B0F47AAE24,8D94B39DE4D3A779,AA5D4BCFB3D5D4E3,2D748877C7957AE1,B490F6B06BF9F341,001587668D51A84C,62D8EFA50643CE2B,A669C446B162FC90,339AA9E27CDC03F5,0609E29891F3006F,2AA48FA070787E1A,F3551BA1F23486B4,56E98500C3C207E2,001556611818DE7E,C45F220F3F7BCCE0,9A8FB65BC29AFA12,A339AA9DBD7B4BEB,C9A0D60205EAB0A1,DD5442684BA15EB6,9417FA7F305B202E,FB07F274A40CC566,0024476B9E68D1E6,3F7348E7F45DEC52,44F1674D45EF7873,82225D4EEB808D94,3A21F44201CDC3B2,C4EA4767E94ED73C,3DD728146BE68EAD,8C6A03770182291F,0029F6589D3C22E1,5B6F82D6EB09ABCB,04C40335BC0BD906,97384520E538BB26,1FA520C9BB270B78,2C6311C3C2673701,057C4ED42C90D2F8,FD9782EA9AC04126,001DF39FA9D14F9F,EAEFF52FBD1E4697,E2D381E042A868FA,DCE21ED0711D6BC6,1BB512BEAF851E28,3527E008AD54E272,C625CB5856BF4FC2,FD29C75F23CC7989,00122BFDAFA27E9C,D715580C850610E5,CBCC75B55B181994,A86BBA9695772338,46F74358AD02285B,DD51FDA0A60DFB82,C6D168844694821A,2E212959021E4A11,0038340040D86EFA,899F6A7D349965D4,F23A4EDEB02494ED,CD48E19EB07DE49E,77290FB98E19D4D8,B44CCD9A313B51A7,2175288F924879DE,4C569FB945DE6AA5,0039885F3FDE73F3,4CC6D3069DA1726F,63D51DD9AB4ABDF6,8D5F0A6360AA02D1,0616A09108EB0BA7,053E1229605538C4,EF335B232243367E,EF152EC4D3307400,0038A5FE7A6305AB,C7433E3BC30F9E9B,129C1D0C8088F08F,3CCFB34BED9E2B99,03095651C1406BED,CDA1D2031834E852,FF4E3B76CF8CC2B3,C5EDF8F7CA9178F5,001140FC488692C5,A8C4A12FEE726B78,BE8743199BF1CF76,3F16C1FFC8F448BF,3230EA826E2E86B1,900BF7BF6536FAE5,7A13D97C19C5DFE6,72A3AB9CBF327D4D,000946233215B4FA,506AE109502DB719,8BEAB67EE143C029,2D79739616119956,62BA12D16A882942,9D5AC5462F4D4B4F,F28B40633CB64596,AC0C0C966F97BA5D,0032D811DBB0BE81,D285CF779E0D4317,F6B7980E6BECEACC,D9BDE5D2817AE198,4D891E5AB7FB71CA,F9FB153DBB8BCEE0,BECF211A99B97430,9C74A9D0E062ADEA,0028CFFE572E94F6,9C24E4929D9D4481,174E3AB1F1C4F2D9,86B3DBBFBED79114,D3DA0D0AF7FB3789,7C8195A23FDDBC8E,5C48F1F3769538A8,28C62378004A8867,0037C0A47A295200,DCCECAF91EFA5E3F,5394CA52986580CE,C4ACC46FBF550011,C82E16DF1082835D,5824F1D08AA0C3AF,3E802B0BF20CDD55,50FA4C8FA9F9ED62,001AD9065C7C93C4,8F41E5FB88A5ACCE,EB61D59A4729DA08,B0E03D2572D63020,92517E480B891D5D,33BCDB9EA89412C2,E9CA7A57EF2A4C24,53C57AFF01638142,002D007CC8BB5539,D51F8FC620BA8363,EB9B5C94CABCE251,3AFE763599A89867,6FCF29065E4F06CD,6D632629EE741F69,D884CF5A7A0FAC66,DB5F7131196FC8AD,0006470B8FBC9E2F,0AEA71423C7B30C5,2CC9894A0BDAF702,347344B0F9C9597C,F4694FD75AD84735,B470AA621A72B4E0,26264A58F4532927,9CF161E1BA13235C,003412B8B9A0365A,06B087C0B39C8101,21E469E16C640378,210172A3D15034A9,92B0A658EF95413B,91EC122DCEBFA9D0,065D8A7DF38398AE,3CC14F6A8BC23327,002BD0D7FF79C95A,A67D4A5B3B8464CD,A194593F0165AF2F,9C98AE4327E00262,E2CC9E55F507DE0C,B2380274095FD75D,355AA6ACA22F50E3,6BC5AE759644F354,003A6429F968AD0C,71B7C3564E888B91,F3BB9CD3932A3313,E2CDF2CEF714586E,F7A9C145EF8E58FD,5779967C38422257,A396CE7EBB396EDF,7BD3E583CC83BE81,002AC09C9E7A2057,9E1FA057BB8EDFE5,E207CC0D2E448CA7,0663A20AF1371AE4,7E58EF2AACB7A82E,121DED016E58AA37,1F2C3CAB6B88C1F8,0188714831D9C8D4,00308E385C8EAFF4,74C5E436DF60541E,8F5710A517435F80,56A604EEAD319BCB,1F6474CC2F0819F2,47E0E5B34B18F3FD,CA4DD7F4D40FCA6A,566F103B494C4267,001A8D15B2E84466,473CAAB6356BD410,CC5174CAA71A7297,DFF25303B24D7807,4D986DAB59652A1A,1D623DDF26432974,56B7FD2FA6E7821B,4C55BA4ECB683A99,000A7A77E56E924C,723FEBF32574F05E,E2A5B691CB390009,7F01277C9D9E54BD,84850CDBBC857CA9,A579AE7E96A656DC,D39B58BF3D18ABD6,4EF024924FB07DBC,00057F3511E44858,077AFECDAD8870A2,ADE5B0C53EB432AE,618D90CEE62D0EA2,C1DA22891C9459BF,E9034D67F19BEABB,227362F03944C181,8BCC077599036A8E,0031DF465EEC0C80,21C43C3D67E03C0F,31788372961187D5,35B31FF0D4A8AAFD,4B4B68025DBB4DA5,8F9073729CC412D9,857ECA6A89E06187,7E02A99A108C9791,001B0132BD4F5533,DC1007FA1678ACB9,20D3B924892CB85B,EBB2EE22672C4713,638B3651E14891B8,521AD75FA3197E48,DC2F1DB6BF927DA8,FFA9B2D18B44D497,002932BA1B7B7AFA,9288C2932E6C824E,C2059AA43AD638C7,93F058766B627C84,596C41F412C7B22D,EDCF21F437FD29C0,ADEDB267BDECA456,7F42D9CF0ABB8383,001E2AE88FB22748,7B4B2B7FC0CE9CCE,AFA39EF95DE374B2,93F88C6C2A9B5E41,F95C9E664C4D8D9D,C952E930444945E0,4FBEEBA7F80B393B,1C9FCFDFD80C3DE1,002CD29C1B855DEF,A46B45BBA20AEB3B,5E362E94E3B1A4C4,9F6156E6FBDEAE91,8E6EAE8C472BB59B,D81970A27A33C8EB,8152F4A06B5E4071,055B2536EE9F9005,003269B51D4CB296,39DC36B040E51F6A,A9D20FD31AA3EB69,8CA3A0E6211FEC50,E9E102CACFFE99BE,2D0ED3C3C62E6AEB,502ED1990C1BDB56,EECFD724C22590F9,003213D2D25C8E57,E0DDDEECE7DC7CA7,41B1CF2159D3ED15,F0029E685F41F388,421779A135258063,BCE982ECD5D95A45,4B0993A2BD879FF2,09C7AF511561B5C4,001268635874C87A,0116FDA4684796C0,B3D2E6030C559883,817133D0AFAAB24B,331B5A6A4F6B1517,10456AE3D977508E,DEF738E48B9F693C,AFD30B355479E25A,0013EDFB48C0722B,15181D11F2673EF6,4E5C7816A97CF00C,D4242A6D82E51AFC,679555BD69F32229,68D2E63424AA3FC5,CB423EECBF41FB4C,8FB1CCF8D6039FAF,003A687332C4A791,CE4E2CDD034F7811,FF1CD5D4A7124932,EEB0C886286782E6,2F0D208FC084CC2A,F7BBBBC9B5A13AD1,D50BAFCCE159537D,5510FFF2F849D1D7,002AA11B6BA12167,BCFA287513F59258,0922A98DE67656C7,88AE22F5D0630AE6,EB4B102D54054E90,BF6AFF8BF030880D,F477B9CD76C25E2B,517ADFD831ED9CCB,00374B76077C81EC,9948DFFADB1743B5,896A92F89B83B88E,C8562D357649C053,6C3CFF149ED7D58E,971830741278DC09,276FB872E11F1752,5F0E313A9CC9D535,00088B6C66F7EE79,BCCD82D44938FC04,7128864DEB77B0A1,6FFC99015E6704BF,4BCED7CDDDF69D4D,3666CFDBF04B387C,D5F1D99B2CFFD1E5,A4A99A2620B093F4,000FD063AFD7EB4D,E59DD18829108869,7728DE6889FD5EB4,CC3F0B627F3905C5,514C2D5BA4BE43B5,C783D15A881F6F7D,DDF430EE4321DDB1,52A71DDDC22989CF,0008B10A4CB43F50,026907BAE399C184,9C594805E902CAC5,247F1671861645F8,7AE9124111924D6A,69BF5D38750C621B,0E9976C5DA8142A2,FD26CE3B1F018600,0005878732F75FC1,F49A785D9A9452A4,1A03CEAEB34A25CE,EAD7B3A6556A2CC6,0CEC344A706AAAC0,68D84B0E0621B97E,56D8C9681B0C3A6D,8222535FCF1A7C22,003C60F047450E37,4EE8BC8781319671,FE005C850DBDF38D,1911164A35BD0F3E,5E9E854FAB48424E,050251D49DE4720E,D722257C855F0351,429E3D8E20F628D2,000B6601DD33901E,0A2B3A52CC30FFDB,E3FF6A670064B3F7,DA97848FE653CEBB,D1C5C2E03C182C00,6674097CA8C264E5,1074ABB52F2A4EED,0E0CD6042B38F7B7,003AD4AA78F6A75E,75340FA9A77A97EA,D092B8DF1C20AD1B,4C08189C06147CB5,F0C189AC870AF67A,1FFCAB4457360CB9,D995BA2AC5EAFFAC,63A8A4C5070B0350,00320812A3A88898,2DA68D56D0E8C787,0425959E0021D084,C1E573EC2C60191A,B706FDD3F5E28F17,8EEEF9FBC2FC909D,B799147CA0CB1143,449CC06A931AE33E,002DFF43E675D841,4C48E2E10A52AF19,09CAA5210C322C5F,80C67CEA637FADA4,B31EEB047560C182,2E06787F9C85BB26,E2EB965D1F45015F,405164B80CEF8CDC,001FA85B650EEAF0,FB0FE1D7A92CBC03,1A23AAEA8ED45A7B,8FC0DE2F6C306E3F,BCE7AD4CA9B00822,5EEFC9CA5E4173D8,B5D59329B50701BA,F88F537B8FE0F556,00362F48EBA4D13E,E66973EB41E89AF6,1FFC68F59E25DD9C,3CF4A079EC887157,3282C261CA0CA513,91BF482C6C18B804,9513B25E9963C394,33A3E35963643C7D,00165E88F4200C30,078903832A459C23,5FCB1035FCA21E78,8C6DEF61C8FA4950,956A8CCAC0CDD7FF,951C17B549262076,988B3862DDB1CBD3,5ED8545C54741D7E,001984BED4912DE9,FC89A514DDB3A2E9,F9268679792A2111,4310439290499012,B49319A780F97627,6A8A047D9F45F74E,A55822937FABC2FC,7DFC3CA594660F38,003442620CE4FF04,2674428129A1CDF5,CEB221996DF4D4E2,7BC2609873DF6AE7,C982FC4D1DC4DA07,BAF115EB2AC2B809,712B838848656A2C,9101AE9F8713B30A,0006ADA246587903,8EC2701F5E0066B1,9D428B309AD1F733,0432F9EB8C74B446,FD5C27ECD1DB934C,D83F51E1DA317CF7,1F504F0BEAE21F39,B7AC601B51A25F82,000BD59108213778,2157710764245BC0,D82741F95F3B8B40,B862831415009884,3F5D32E228611D65,DD8FF5F6E6EBD773,8FEC2431FB0E372D,2CFA916CCD01F52A,0016E399954CB315,1AADBE2783D69B1E,5B2850CF463E001E,4967AA4F430B0095,6D2B5F0138C6E9C4,360A2D5C350100E2,D11D075A2788B7D8,7ADE0492DAD69A97,0035417E6AB3B144,0308E5D46B299E69,57F603A21EB48EBE,5B7D45CEBBA681BB,C5D68B5BB7060078,9233C2192CC44A43,1766AE8024CA5DBE,CB3A433BADD08DC6,0038FF2613998F40,29D077E3962EB313,BE242D6364407146,4350E8317DCDAB96,AC866EF8F4EB9E64,C1536A9C4D1DE0BD,1EFF63A4C9A80E75,91B7AA95F9E37B0D,00385E3D07360C4A,E8DACE754787D44B,1F6CCD99312BAF20,B3BC5FA8649D7A0A,417E09F794F27FDE,FC2D313AB73C8DE1,9495A1C769EDE8FA,5C8EA1EB5440F5F2,002220D9757D4B09,62E70BD53926BA64,2A3B934D85C33F05,C05A5182EECB4A05,8BA502CD1B5317FA,77B2A18B18B02411,E1F6FE5AA2D36080,1DD4DB1FD93C330E,003BCDCD84680B50,A5E3C610E499CBE2,6D0F748711D597B3,99A6A7B2125EAC7C,8BC16493179480AB,AC5A3D0F726C7AC8,91187734CBFF91F2,EBA5D7283283D9E3,000AABEE419EF2B8,C9A80F4FDCBAB127,957A78EB74069B48,3D34AC746C228910,D024744DB071739F,3F3586CEDC0804E0,DF89A326796628CA,9742CC6E3D4E8763,003A985E5C215D64,B7CE8B11E3C4406F,C61A44471A610982,99F92557280D5540,445087EE6F268526,3747A416FA05462F,339865D51B466D34,450B61E2EC2F724E,00361AEE392191B8,721F084C92D9F365,100E93C0DD81BB9F,14C28F7EA279989E,ECDEF829A23C7295,C709E411B987D0A3,F90BB13D6F977E74,AB10C4E113CE6E88,0033ACF6837175F2,CEC9B693ADFE5CC7,FED886FAD3182C7B,BC624EADC1606A51,4D2FA3DCBCB5C0E3,7F2C2885D15E21B4,BCCCE1DF91187768,FF3F411BBD5E5FF2,001F046318B6464F,AAAE1038CCFCDF4E,BA4D3DB64655AEC9,06E090F82744F4E9,18FF57D91DE2634C,AFA3073BD7E864D0,8D78B47244191A0B,F3CF4F16DFAAC9EF,0015093DE28C28F9,760D6599AA0C9BB3,86A081EEC8614EDD,1EEF13A537664A94,4CE6BB67329AA20D,64B9609C6453C772,B08B9DD8060333E3,CB4D3432D6094AEF,003E9A97112504D0,A0D3688154C5463A,72797C168D40C728,8DE653B82E5B800B,0EC4BD9B1B3140CB,64F65741E2C49C43,0CB69F98D5404B2C,6EC386288832B887,002EAA2474B4BD45,69F564A116F7D150,0D5AEB39000239E6,59FAF114ECE6F9B3,29A263D7FE0B80EE,9E65A5FBF722352E,2777A19870D9449C,1122C6FD53F75FE6,001654513BC49C28,B3F2024BF7C2839B,89DC1711B6FBDFB8,A914B5B36EA8138B,364EA06DB11B26CE,CF22AA8BEB7F4B48,CF5EC6682027D3E5,A667CD676D84FCBF,003AF4888F976F73,C356057544859AB6,9FFEF7383E858EBD,5EE63A23E2B404C3,EB50A501C4B1189D,71841FE2DD6EA067,EC8C1605C17C0E14,442993E73B82BF41,00349DCE0753DC9C,50640F789D21EF4A,BC143EEE38B08C0F,F93160B059A11663,70FAC7C03DD14A79,EA4126DBFD0241D5,455DDF2B2715C671,C70D4E9B80741EDD,00084A80BE60C542,2E29D4962FCA9FCB,C87C49D4506EE2AA,E32CF40A41001B04,0E3767AF1B32469F,83B56CE84CC78A0F,8385E6CCBC0B543D,A91514514F6A7CD3,00367C3196D0D4E6,24CAB0017C900614,743A352C0EB387E6,F5171CEB66386E0C,81342AC24CAB85DF,9CEE36715958FF53,171617C726CDFA74,D8440915D2B11595,00140E5226D304CA,23870B2B8FDF731E,BC800A26F9611FD4,956CD9F299167174,97B93429E1F5778C,95432815C0B1706B,8DB70BF146A1DCCF,CCE680D3B58C8ECD,001F364AC5C4EF92,854FACCB78838A03,4C4F6CDB49FE1E1F,0C80F568B7F0F5D9,43BC188CBF2841CC,7D8ED3A0C0683B51,C3898F049B23063E,D9A8F76CAA2523B5,003CAB1847C9F075,3DECD1B8A6ECA921,77E4DED0D40EEA51,CBE3E615C4C13399,7A4B044AFA7C702A,37FBD1BA3840786A,7946129870C71B82,033A7894BEB22AE6,00169ACC9C4516C1,4938F8BB45311292,AF4509EF20568B5F,B98285E6B0FC98BB,5DD6EB75CD849684,0F1EBC74E7670917,993306B6BD2117FD,E4E5112E7018F497,0011D15072A3349A,1B67DD46AB731201,55ED4F273076B1A9,79639DB640D3D694,A2CE7CDF2301E75A,CB9F0B7814D4206D,5896DE479A6CE4D5,BDE92DF105229C9A,0033EB0203ACDA51,7ECD963C66EBA721,E9842B3A19B6EB66,93E190FA0C1913AB,92A08C9138B20DE7,9F26D43467CCB0E6,875D0C867CDEAB02,7EDCD6FD48BB51D1,001C5121971E5E78,75BAAF4771B3A256,2ED58D980389679E,C8AABC6EEE212474,584A0CD59AF5C644,14B189BC904E954E,F6FFFF43650AD713,618D21F887259848,001A6DEB70A14768,DD78135E29DFCD46,BA2BD555905A0F44,0AD21E0B6DAD953E,A0167559038005A1,DB2224992CFA37F4,163B2347A655C80C,CC01BA8946BD1E5A,002DD5A52647249F,5895F7BCFBB7DFFB,3C8A07DE27E7B003,6FE58127B9734F8A,0626BB23AE3B8F02,D559D97C2CA4BCDB,545BB36276CBB2D3,CB33D1EA8F11923C,00027DA129DA4293,5AAF125911D2AF40,80FFFA2482A51308,813941E1E6F20EDD,18721058111D7D4E,9792FE7B41E4BB83,AD31B9D0A92D99CA,969BBB17FCF6EEE9,0023687D5949904C,471BE7FC6357619E,D2839BC52243355F,F2EC035AAFA8547C,A732A47D8952B91E,5E25A3C2742FE254,6C482C9E98742ED8,E39254E6BD61425F,002B958BAE0336AC,7072426302573F20,6D77CD3DB71C41FD,A80961DF7D340547,A202E3E95B3C13E7,46BFB780BC9D87C4,3A4277DDC10DF351,BD078AD14181EAEB,00282BBFA30503FB,D6B342AEE3164087,60209128625CBE50,96D7A690419FC888,D7DA0B7C8C921D17,88DBA70967B86134,38453A6A71363829,3D1288812ED2AEDC,0017122A24286695,01A2FF4D3DA2711E,F37ED62FF5ADB47E,08BC40F20C230313,48C3BCC945281325,E10B87A6F46AA432,FA65606A811687BC,AC608EEA7E8D93A2,003F675048034338,FA26EFBF56AFC0F2,72C7571FFA5FFE06,578DE1D85487B440,768D202BF1916D9F,0499FF5EF76E00A4,0430FB0A4B7EFC25,0B4DE91D06405B77,003046F787CE73EA,0F0866B9646E1FC9,EEF81EC7C7953277,3C3455A34B767F47,774B741A5CE65E9D,D817DCDDC8ACC2DF,FD68C715D126BD19,29BF192618E168F7,00155865DE4B27F5,86347F24C1894BC9,1D23B702204DDFD0,8BB529B1E1B349E4,260961AB220E2AF0,2E9D001310EE1F76,E3C7BCA0F6576926,E14A8331D5192BF6,002D5A76F8BD6E7B,8A498F86AFB67BDF,85BD97B3C229C771,9E22CDE3EB32358C,BDE8DD27141605E1,1134D4CD2BCCC685,924A9485B12FA196,53A118CC1190B3B5,0037267732E3CE90,3EDBC81049D69A8B,8830F59EB2D8D48A,DB1AFA58FE4E4D32,DB5A62343E711FCF,5E6989F40BBB6D68,D908634F3A9DC80C,8B0736438B8B165F,000E7FA32FC0AA6F,9112313FCEB94AE4,F2192955239AA99F,A0BA7DE6477FD093,9635BDB9565719DA,BDB9C9AB44DDFF34,CB0A7C2BA9BC44B1,CCB63816B4D107CE,00289B3D4DF4CB1B,42DCABEB301478A9,C350894F03317591,969FAFB913ED96E0,E255A32CFC5D2FE1,DC58503C3632D0AE,4FA0AF315A5776BD,3BFEB2ED083AD008,00030BAE1BF3BD2F,A7DEC04EA9956F4A,7CE4C113372169EA,72BF7E06192AFF75,DE5806F2D1F48664,D6D44090CAE70A4E,2D5B0612B7952F19,95209E96B35E3347,00135399AA1E4687,4F0B179909DBE1D4,6BDA0BE61CC134DF,C2F6601D790104ED,BFA54B8EC8E42F8D,D95F0D9287BAB4A6,128A62F111C128BA,30A6AF961D7CBDC5,002111477BDF1757,16C76456BA9A341A,1D3583999F8D5FDE,53FBC457EE47A522,589EA9A05A574DAB,83D4084144B3618A,C2B6B3630CF1E348,CDAB5C6F201B259F,001C98C981681375,29AD3407CC0BBEFF,BF55E431F3FD4C00,00B7B396DC01772E,2A72CE39568330EB,F315A9553A5D70B2,40FC5C9177E1B760,8B53DBDF2BA756F7,00110362DD7B278B,C09B8A123BDD22B5,41E323A3E38EE735,FC140B584DA2180D,034B5C49C62D0987,1647D7E87EA369C3,78A5BB18D07040B0,EC10F44005F917F2,0006754C4FE2FD54,BC8984D455A45124,697D2D2464FDD1B7,21125D9175320D24,69A11B55EE3F5C08,401C6313B6FF44A5,98DA5B5B13CBF6DD,0454DC9A323A9663,0013CF33574BEC8E,AEF470929A8B597A,3FBD6A9D37475197,A70C7A4129B31918,41DB04C911F7D8B3,FC5FFFFC3158796C,C6EAF9DADDA8ADE2,4A1AACB3B514415B,002050D13F7C676E,85F29D18F89BE844,F40C268B84FE2447,F7CAC5D1E69B41A5,44A2A4850C3EC439,AB4192336A71BE11,573DDA91C763FD62,97B29EF477B0A7A1,0010118993EEB0E7,C93BD6424EB7F2D5,A88F01D2CD1F367F,AEAC469B9F273B7A,BEE20233C3D9526E,CCCFA2B6C6D58B7D,3EC1815287B30977,4F22D905177E50C1,00200A3B8F523AE2,7EF5C87FC0B702F8,BFF1E90FA586D19B,961CB8FA1C6167EA,DA70E561501CDAD5,9D19CB88EA7712BA,ED461AD55A2F8D3B,F3ACDDD03EAB88B5,0039F745B8BF5C35,9F0A3E848FE38E96,A479157840FFA940,D777530A7BE97A71,5A708D869F15E45C,BFA464951CECC517,85CA61AF391EDBBA,94BFBDCC3577C29D,000080BD76C9A36D,E96A5F9D5234EC31,956A9F26584AF281,1EA5E59C13FA593B,0CC1FE2343FDB611,64468346749CB789,531D9A7B7D31BC18,B32EE0C1C1C72029,0018D19952C454F5,8A58820BAC540B21,AA6C3C837D015F61,3DC0129280ABBB98,9B14E776F0F4409E,532ED3B90D17149B,430317B2A3F66E75,7A0303F373444EA1,001D572B3A58B033,8E00B0526F86CDE3,25EFE34898C76BE7,DD10774AB2E89346,9A17AAFB4CFF1E09,069F267781D1DBF8,133CA6F3BB030C55,966309D562E741A1,002C6A6B4070781D,3EC576169AFE0AA8,EBA3E54EACFD55DE,06A77D08D306D191,8890C5E49E7D3BF2,71CE4970A19E5F91,E53CD4FB259CD234,A46FB4C96DCA9F5D,000BB69A70934686,EAE6A91740B62A6C,9D91F5CB4212D6CF,6D0D655B7546440E,25F0624A85A6319B,513BCE0D2ECFAC64,EA18619CB27B3029,00324A902AE206B4,00005EB469F76A25,4B9E8BD28D58BD1C,7041A4F834C3468E,A7E56F6A8660196B,E8F6E73512866FD0,192D2D9BCA694FC8,653BEE5C4AAF447F,375312F620FA8709,00261EEF9970D68D,FBB3884830870531,89F527A1B9F9EE22,08824C9306EB81F4,CE123E6956CE3EE2,6A56C3CDC9FDB366,8B61A60ED754B3B9,0DED6020B9B9E901,002EA300E199DF59,BDA5D33E8A74AD36,0FA2CD4F27AAE21C,FC45245096F2A8C4,850341637E6DFD87,6E3CB5743C4BA096,299E49DAD5A2AA64,350FEACEA19351C8,001EEBA35F6D13DD,BC2BF8A3A33F7CEC,4E0D409D77DC8BF9,C2D96C7072443CD0,08D58A6AA062F604,C2C078A6A38E27DA,AFA7774C984081AC,65F674113D9CD725,0003E81C4BC350EA,D437EA2D333A4FA2,3ED9BD49C483D4B6,9B79E723234B534A,974F877BBE4A454A,EDAF828A8287FA26,DED6E11FC07A6E85,51B35CE671240F55,003130D946FFC268,8CF713006120F411,F4BACBDEBDBEE8B3,A40C9FCFC94A15C6,152240AFEB8DC4ED,211E32C9207B1A0F,796913537F3C4987,9DD686915F3A1714,001392F6BB8814F6,DEBA14FAF0FDECC7,9520A29A8F24EDA7,A162A2652876A991,5575E870FD3906A5,8F00B2ABA4380FE0,45D033BB3164A97B,7C3720673447079F,001A429AC234FC1D,9BA084013EE0617F,0DB4912E043D0443,6C91AF433C864F2E,CE3B4F4EDED91750,7086AF54256B5C55,AAEAEECEA79A00F8,81DA8F934C53476B,00048CD398EE9364,E3C7352A77EC3A11,315145416C92903D,FDBFF8988838B44F,6F37B6577A19CF4E,1378DE48C6A7E930,4E0A652950BBAEF9,F58C71DB60F06FAE,00165902DE801B50,BED387B36C5D479C,5B2B8C410A4FF528,BBF5C4A60716E298,D1CE52976AF04F47,100D08A9957F6AE9,FB9173018C4B6F9B,51F5F6B5ACE88B76,001FC0A7B90EFA69,F9FF776381574459,714BE2188CD59A5D,8C51432AA7F21A37,B7EBF812D07AB099,32800365CFD50295,AA5B3B5A9C75332F,F83EDBDA50AF131B,00368618AC5B12DA,E1A423F6D10C4195,63F066262A08F0D7,BE945A5751EB4FB0,308D1251DC6CC67E,8555A94D059E23FB,8E3943F7AB6EFC63,6C089CA12C00A6FD,00214160B00FC6C1,FC432579B31518C4,05D41E10A7B8C531,A1E7AD9ADC464A33,96154644A145B0B4,D739968E38639028,F58B52D4E981F34C,C7A58B3CE4E325ED,0021D914E510C889,4150ED64ECA4A5B4,51040DA157D59B30,0E556E490662285F,5DE7A920B4BE221F,CC0A9A1369B2D3DA,CDB3C9F6465E7572,B4B9BE7D512934AD,00011AF4053E1443,2FC668C2F15625A0,CE8022EC5C900B62,75BD442F956BA9F0,2D96007EDA234D9D,A49321AC42F89CAC,313AE9132A0035DE,2928AD67651C6FE5,00136F90F33C57C9,946BB76F629168CF,AACB84C1EF01F0B7,BB35B71CB51A25DE,C33A887C703CA9D5,1063150F910205D3,9BFF8694AC10D3CE,AE539A61BCFF62DD,002F48C02C73AF0E,767322D71B96B45B,7839C8413DF88253,76DE1B1525283E92,34849EF017A80EE3,593415A8A147244E,A1F9C76CAD23F90A,AE52F202B12483D3,00391A392599F19B,3020F44DFA448F86,166F91E8BA5C3F9C,B69804BE21457031,DAFEE9494FF709F8,CC5114CD3111D351,D78E7F2A1EACFCF6,4EBE658FE6F8EF49,001D02BB12A516BB,7F85039465D3078A,67AFBB3563166733,0BD45E64658A4F3C,0A343338A5A97D33,79CA6B979DDD4A96,92C0D399C06E3796,CA6942D68D426163,000A6A38BFC1535A,368C6254D4E05011,EAEA7A103227F21B,57DBDDBD2DF8C418,722F943C22EA5311,F5BC5FA53E95FED4,C9B1750CA3EF1F41,44096B8D9043CC30,00298D19B44A1801,F318DF02A5AC8826,FE5451230B1C821E,4BABB50436CFBCFA,7BB343FA8FF2277A,8883DA108AA7B0B4,562CFFBEA46F1F06,51B07F465EF1AB93,0026D8808BA9F5BF,A88AB1A9833B4E95,8A3B75AB519D99CD,ACAF8E7E0026C08A,9AC6A3A00D6FA9CB,4DC79B8B8F981952,1938F90429FA8488,99726C4A4C1AE934,003CA80968664FD4,F5EDF90829902AC8,C5A6DC8461C8DF6D,872E1C1DE7D1F7BE,BC5C95998B612B0C,ABFE8E9B040B40A5,365F76DCDA16BF6B,C335764119DE58F4,0028AEE9BCE3CCCC,EC588DD4D051D04D,1A6FDE696D9FF1FF,7F0EF498E5D786D8,0506A9D609714F4C,3409C29939B37CC8,06CCF84AD76E20D4,6DEBB0612E4C17DB,001A5C7D06BAB8C1,0CA30FA38F6992C6,ACD4C5ACE6FDFFCA,40C4560A31101C8B,5E58B32148019EB7,F42DC2AC0117F98A,67603D88C8A9F728,ED7602B79DB9E747,00388B157D8A3FF8,2AF94725002E61B8,4E0A3808DD36C745,18DF5C7514D45973,723C91A253FEF7EF,6035D45C02190381,0C779733FE44B49A,DDD8A42C92F4AA8D,003E0E10BE38D07F,7FE88A28F4DD92C5,FE916749D3B717FD,ABAC64282E880CE5,6488C5F31FD57CA9,1D75C412C99839EB,A0CAB0F123A25E57,BA124D7FAD93B67A,0012C98F3BD2B45B,EDF9B2109FF006E5,D2F02D199E7BEE8B,AEB4184E7F388934,5232DC9176098742,8D938AD735C277CC,03CBCAACDA9E8120,C391F4A24B62E03B,002EE67C854AB661,27CD295765E1CCC4,CAA33E62ADD07AA4,3F0DDFDC67B724CE,4F19B84AA9BF8B80,4EF96F231F588852,0B48CF7AAE27B391,EB54EBCFD26E0BC1,00278B315809A91E,D8A9B3D747C19D44,31309B658B74BDD1,7C0BE9BEB5A10A65,A4E4193FD3BF5CE7,B11FDB37819CD623,2C006E37E530BD99,95B73FB943F6DA46,00134DDAB09FC13E,372CE257E42AD98F,E0F5FB5A3C2E500B,6790E3CFB0F44816,60367A815C3458EA,F0B3B59BB62DE9A1,75E508627DEDF0CC,52E811A5529F30F4,0011A6E8652EA4EF,7AB4B1C0329856E5,C7B5E24AED68C205,1C9D01AD092B9464,F23D855423017092,E1B4B3BC10762D0D,A90D52F9B074B116,C1E631D9C4A9CE19,00066F5040B8F512,41E014CFE322FCFC,AAF8C215730C3173,ABC8CB9851161707,EBCF663D2DA1835C,A85C6D14BCD01A5E,449455B06472BF4D,E5A5DC17F7D7FC23,00256335340105B7,671D0E61BF977035,E5723CF89998B02C,3D88E1DBD578E26C,5153B1A5DB9F768E,3B5EBC8C3C9463C4,533D0B70932260BC,31A7E0E88E638461,002B8FDCD6EF3507,A375B1177BFABAA1,5FF8B6640A56E8BB,FFF06D1D767D91EB,3E07DC03ACEE65FE,209411BC165680DD,D6E74C48ACDF8730,6A0425EE327DA0BC,0031072F0FCFD4DC,79CAB56727ED72C3,38B70CEE92831C1A,B400D8CFF8A44F58,51D0420C6F15A28B,203655286DB65E72,D218273277B4680C,F440531EADF83326,003726CF86C0209A,842D1F408DFEA3B3,4D58BC2BE15A2585,DADDC73E5486D837,781B3154ECC90FEF,26BDE6F5794BC6D6,6254ED956BD0FD97,F2534FB222C896B1,003B1F412D895E0D,B66954D0091DF4C1,6DCBD95C5800C0ED,59346BB952023FEF,247ADB1AF77A05B9,D0C693A07646B9A4,F9B56ACAFE3BA98A,4413F314AF5DF0E2,00345E766C2164F0,E2A5F66788E2F9BA,87B36FE3EC124722,6AC4FEB05AD637B4,AEDC95E91ABE6934,8A3DFF9D8BCD3CC9,F71850DD33E7F67B,88F1A07343127098,002241C06EA858A2,93CFD7FCCEC996A1,674D48B5D1582B49,45946A56CDF4CD0D,66136ADF2E5893B0,4F7F37684C6BCF54,111FE9FBC0BE6399,2D13599693774C6A,002E6FF880EDFCA8,A28B8B949ADD9576,6A73CC0F9C6F1FAD,0B234354E3BFFB14,E8F6305974B0E82F,5722750B9A82C794,88934486FE765382,C697639AB47804C5,003248AF10F7EB04,F2E6B0F1889B85B3,768DA9BF907DE487,D0F22FDEC50125E7,E34B58A977545D58,A178FC731C726A14,D198E85ACC4CA6A3,B25BDEA6F9B2BBF6,00273429B8413B85,F20ADE3AC0182F58,E4931907EF560A60,86CCDEFCA1B1329B,E06DF7C7D96C5984,321EF2225EE5D553,56FD38ED964AC005,B32A64365B91524D,000C414943577575,80B1F0B7DFB58B10,77062D0440E71A2A,54D8AC4156926342,EE0E6BADEED29F67,F674457FC9634373,DB6BA62AA56F2983,DBCB2D83939F0FBB,001349F722A51DFB,AA677CD2D96C5307,DBAF8C9DC72C8803,A00D48D1E9C43C4F,8BAAC500D4F8A9F2,76FB9BA578511226,51A682BFB5608912,54022F2D6A41BD03,000C2BFF57315136,0DE8A1F8F3B51962,6BBB26E25B6973F0,B66C414BA13BF9BD,B29EECCD6405293D,1B6C7B2F6A895849,E2F5598CD1046768,7FE4C39454C80FC8,0019DAB82C48F2A4,3477E40EACFA66DF,FB22E3042310BA03,48C80576C719DD28,9D7353B3EDD280B0,5B250A7C19F35875,B4699759EAB3C777,0B7127BEEDF65ADF,002AE5689085DBAE,5A54C5925E5E7CCD,A0752EB2C8DC8EDD,A2466B774A54DEA2,6FF33A04F8AD2D31,A7E570514FB1ABE1,8CAAF3AF68F17084,B1F17A6CD8A6457C,0026CD4D3877589B,E9B98FEDCCF2193B,FDBAC5EB8D1BC1DA,05712206CB8E0EC9,92B241CF54DF9AF3,0634C7AF286026FE,56F0198FC8AA648F,467939C49B076569,002FE8C3B2C44159,1A6F62A757301B36,580633528A7EF7CB,87734D5A249B0C4B,67AC5EA079352B15,04D9480A72B37FDD,3D59B3A99F1539C1,FAF527251B2D52C3,002C2A28D2BF6708,242D372C24B3BD84,BBC70077A1D91954,91AC0771F700A0A2,11F4C534F543F5A5,4FBA19A9C0CC20FC,F3CBCA18C9E4F805,329FE7AFEE1C7BA1,003B54911535E54A,ED13F6AA53862EEC,5888B9CFBA9082C3,1AF28C690E902B63,B63346564F891D48,C0BAA0B86695AD54,986F44D7726FC271,5E52FDE8E8C0AAFF,00364AE3F625451C,573828CF0FD1C864,7FD6F1D903C26711,C8D0967E482E3446,22993E30DCA28E3C,3F781FD4BCD1910B,F55656AC567F0EE7,F903372D5D4A8152,0016B835779B688D,3E3587202AF14BA7,8A255C30227299D8,DD075225F9C32A75,956B476ACC4CF46E,798DA7976EDF2B37,48941F28B310A4FE,6C5CC316062DF739,0015A7774BAB5C90,3EBFA2772CE57D19,E14C75CF9E6D4BC7,B1B64E6AE5613D38,D3A05CA8B9F0593D,B8308D10A5F3D4A3,B897BBA985CCB5C7,7C5E3F56997BD12C,001115E9BD088F33,9FC37DC4642ADD8A,5BE671796F17288D,EABF4A83392D6ABB,C2C8DB88818D93A1,58513EFF29E7CA04,7F1AD20A960C1889,AAC5C385CE8607BF,00029BFF7A19983B,033FFFB784DB0D4D,550E12010871DDBA,3B73230EB58AD902,74CD9BC96E248A70,F618767AC621FC60,D5C221FB1388C97B,A762CE603D195690,0014AF98276772B0,A476057808BDF8C0,AFD4F115F18ADC57,5A90931408F06460,E15D9CD09156D0D4,85EDEEF6D291B58D,CC38627C25999C96,D1197B086C47D229,003AA86016885524,3ACFC139A802B1F7,A4FCE9EFA582370A,46A67261993BB1A6,309B346C05338B59,57BDEB5653FCCEAE,917B5FE94C0B0B09,B2411463B3CA79B5,002101C96C4C45A3,2206A55371B6AC28,887160190FB4B54A,EC5D99E23B6FCF4D,264C1F727B18B034,A38BBC22918694FA,4F370268C4C4A4D1,3CEA2275AE169C1F,00083CC54340EB02,CFFBE68BC58CA309,4F32682B61F95118,C352BF71ED03859E,067FDEEA7A8FAE34,3E5B2A24AAE28FF0,FD898677F996555D,AD0F281A87F24F06,001E8C14FDE6A29F,109DA349B393BE06,0C4E0F9E451CD5C8,10FC9FDD306744D0,701B4D4B7B486873,E5A8AF98B393161B,22F47A82515E2254,5E7E7890E5589821,00299307BAD1BEDC,0B50DAD2FDC062C7,C846459DB1B16457,0B07CC781FFEE2CC,9A393943AD333013,4EFF09AB92B53278,34341DA11C039B00,A7D6E9352862B589,0001EBCEA1236B29,55583900297E4D01,4C98267474A9E152,63086EAA42824BE0,5748527428847045,7E4CEA1EFF12FD17,29DFA60626F08CEF,5430830130557E42,001859D0E321E6D7,58DE608600A0B2D4,FB666E17775F0C6A,69208D5FEBC522C7,CCB0EDB67883F183,4828B6CDBBA74991,DF1F541322B4A7B4,C05E1F06FA1DF932,001DA5A5773341F6,820131A9AFD2535B,723DB253BB1DA742,5A89FD82311D8A0D,BA57D33689C10A91,133E0CA740FCEBCD,452C55C580DBD9AE,57900914D9C24ED7,002F943B58E87EF8,122BD098552FE858,DF1A340DFFFD6E81,46C4B782AAFE480D,58EE1FD12BE64355,4081C246FF911AA0,411F66AB0A7048CE,625D8776B14BEFF6,001C2981AD0E7EAC,775B192204BC5910,8FE318DD475662D5,37109E3D5CBB52EA,206EE03ED639FA41,6BA82C794E86997E,A2031E27C7D1E1F7,992EF7768484B0A0,001D5DA2FFFE3A61,2B2864181BEE292F,BF197001326298CE,877F9F7C94ABFF0A,82B4946154DB63B4,26115214C733ACB4,DB707D6B10977011,C4A67F4D7010F670,00287CADA7941178,89165E0A5C15A3CB,BD68A7A0B6DE8422,1DA6693F067A8A04,2D8E75C773DEFAAD,7BA833FB32F7819D,C1F43C929A56FC12,7533E4BF3C6A46F5,001DA9C2F1620190,0AFF365B19444F5E,7F0358050AA28C0A,264D7CAA9C8E4CBD,64AC6B5E18CBD336,9F56568A83F1E473,C886B4F8DEA81F8D,C3BB844CF306FBC9,001BCF971F5C19FF,419B02926CC936A1,960E843DE22308CB,A7894CF57D49149C,3C0DEB149B44988E,5097E5BF7D762822,17BA7ED5BAEDE9D0,4B512D723341289F,00228F692F6C33C6,6A77277DCEFEA0E5,5F741E1A932A5FA9,CCA16FAD8D586262,00E0B86231DDDFD9,063080D0CB527438,FA0921E621D502CE,C025A8D15AC50A37,000C1DD4120A6810,7BCAB7D4FF4828B7,7D1C402F85BD2E65,0113F68441A98FE7,127C9A45AE07850A,681E620973B4F092,A4491E09C9D9B35D,D8B80919886D167D,003949DB7B21BAD2,51431196C770C653,CB8357DD981D171E,703DB1B7D960EF00,25C58739FC1D8FCC,23E174546BEBAD09,89F2E36912EE2827,EB9FEF687C263F33,0032B178F796D93F,114C4EB36A6FCADF,3D511E31CB6B125A,3A54B07D17100132,B7683585BD48CD10,A233CE7AA010C10D,2B9080BFE5EF4625,4D8F6CFD5CB55FFE,0003556B860639B8,BFD1D1F3175F3C6E,536BDA97F7E0A886,8E9267171B399ECA,8E0E45150D4FB591,90F56248832570B2,86641821642547B1,D5E428E134F2A528,0024DDD34C284779,30751C9BA8941C84,B093AD4AF6E65D8D,D7D24DEDE14AEF6E,90771195EDD3A412,D82741788A2F80AC,AFCDF9E1326D3492,4CA7C4DDF24451A6,00371F2C3707A992,13E954BE1C361FAB,3436633D2BEA1DDE,39C68779618E1296,DA9E963DFA905460,AA77BBFFAC0266E2,387FDCEEECB0B031,D768AB244E1A5E91,000013B6ABF6BFA2,C002C5D9D9112B60,9F7CFC2394951B9F,1191A93C1F345238,661E7BEE14CB0F68,B575ED468342ED20,A0A7C2228A8AD9E6,9E42879E8732C36B,002A81F4CBB86CF0,15F87F1B028AE5EE,980E63F81DE74D9B,9784ED204A491E6D,C508FA0AC82EB058,C44ADE9C7DBA248A,B57DE730787464A4,63B9EFDD3BDF3244,003169E152FFEA17,7B22C6C1DF3BDE01,EDD1D7E676EB3871,0728136B6708156D,1EA7EF71878578A5,59A9C207EABD8F33,18847590D4ED99B2,6F35252F96C3A011,003AA6BE53B8E07E,C9ABA2FFF467B5C7,940E7440C8203F65,6CFF6D6C06A4E186,BDB13C45C73F6796,9E3DD815EF681AB4,40ECA513B7DFEB5D,F4DAC282BEB27692,002B9BBACB74CC63,70F4824EDD6725FD,27847D12ADD4F6E4,4AECE4CA0492A1A9,D2F5F3369EF7B145,9FFE129EADA548BD,4270535881CBD087,A57AC215192FFFE3,003080ABB6AF253A,B7AD8C4C6B64A8BB,AD6CDB46FABC04E6,ABF33129FEA8AAFA,3A4AAD72C654CE7B,F49010BDA0C48716,4973075DD2D88E73,E7D7C083D8F90ECA,00388A9C91E57E8C,0564CC9DE9FA32DE,E1C6A04F685CB304,DF8C079ED29BB5D6,191C67B4BE3B1B96,74611FEE8A51D6E8,D886BBAC77F06B85,2000A2F156B54B2F,002BCB73F7CD972C,0CB97BCEF738CE9D,244071F2F18108F2,8FFB2B2D0D9768FA,FACE0BD7C7325E3B,52861A1E30954418,C57150714F29579B,75AE00E9AFC12145,002A6CFCDA610F52,14AA75BB5B205864,E8CF58BAB53AEE17,D1BBFE8A273A80F2,F0B88E0D97BD8E08,A2369596FAD48C6D,F64E6D5B56575B3C,CBD6BE5394AE3686,0004C326F610DDCF,3459328CDBA473DB,58C778ADD0586571,C2FB597AA85AA245,B89767CDE5BB67E1,23C3FF0DA0D0DDC1,37794F08192701A1,B1DD5790B70BE6EF,00280B28AE5F13EB,D8D9FA062FD96FA4,7C8F6BFE285B6A02,30DE5A7370C86446,A3E1275FDA6D02CC,0597B25F63A51FFD,A096D9D00D313614,C210F8C72D8E574A,00007D48B622F940,0F892893DF33A004,0FD887AC6288584F,AE47519E967991C0,AD5FDA1C2133FC2E,FA3424857028BA3B,E66727372009165F,2DBC79EC8C79E01F,0036814D27E6AA19,B772201116E01481,849B15CD149C3816,F5D18854209BFAC3,71340E42068E9427,BC29DF714582F4C6,BEB92DC842BD6070,343CA799E5F70C82,0020DDCE56B03780,2B3715AD6E9F51ED,1AD8BBA64022021D,5062CDCFC7AAAB47,6FF619D4B0F1B724,7854CB37C4667240,92EDAF4985F3082F,9AA5B53891138DEB,0007A3FB764676AC,9F48462E59A6DE65,51B402E0D07247B7,BEF7D0541144B2A3,A73CA79471DD52DA,45D34A9225DA256E,89EBB0BE2D448B2C,317F585F28F62EA3,002F6404793BD10F,0EE538317033AEE7,11E0F32A4F4B3060,A8DB763B980AC016,93B3315DA5B021A5,1A41BCD4EDD0C3A1,4B3197AB533E6A57,1032E9340A75C0FC,002CF37070FC661D,C401D87E9FD517A1,828C6C40E03244FE,76BE6F32F4B80186,7066EFB19F5E29CD,11BC40E1549D3C2F,0453072D35157D12,82B9C533C7E539E9,002096184DE74717,17528702C01387D2,936725FD9B3F3870,1460FA3293BF0AE1,30C172240A9638F8,8BE1D777ADC3DE61,A252F0C4D081F3B6,C9CCA9993CAEC421,0036C92F7857880B,1A2028A2B14CE147,C02D73471EB8DBF6,A17BB638EB15BBBE,C5D96FBB45645E85,A448FC66EE350B4D,4CFFC45A9CB5EF58,FD915D9BACE3EB0D,00074305F0B604BF,2C6418CBBE5B2EA4,A7C44CE1957CC4A4,23735D5FB8997B7D,90E44744A3A619D8,F060A28CB6E8899D,039CDAFE04F86019,7B2FE2811518EBED,002FF0095BEAC23B,4E973B1CE7E7EEBD,0174FCC865C19C01,6123E29B9F32232F,0100CAF4D64E3BBB,D31EA683E1106863,944988381889474B,EF6CADFBA4D22402,003487CC2CF140A9,30C8E44E40BC660E,B7F0B1F3F5933EE8,99A91C75013607D2,1ED183D4776573D5,C153EEDFC84DD047,4EF9CA32BA92E24D,81F7B6DB55A09C0B,001919C5231BD590,7E36A1A94F40AE78,D16E522355178350,3F8E56DE87629AF4,243730A777AC96C4,D2620CF58E7658E1,03142990771862EC,EC9FB06DF7190A9D,0026C5A541DCE179,CA8174E50DBCBD63,5789EE24E03D9448,CA6E2EFC1FB051BC,40B700FF8AEE3795,C60DD0CDEC7EFC8D,D0C3E49C52F6483A,897F93B9DC1E8B30,000FF56DB832D626,F793B6EDA061E7B9,843795390A208E99,D716DD0F490FDA8D,D1507A0A7DE5CC0C,80A394D4561BFBDA,D0C47597D68454C8,D97D6BCC29C33C74,001A932F61000953,573EE53D451708A3,218862891886DD34,165EEA8A2FE7256A,2A90C19DAEEE533B,E002796BBD325854,841C643090514898,53F839EBF8D2D254,003609E62C884EA3,AC3F1058B0D3B661,5AE937553A04C5B4,653EC519E12C037B,0CAA7CB8146021D7,6BF5FFFA1BDD24B3,E6345B4CB2B6C80C,1F5F10F395B008C6,00322DAF82E1894A,2CCB179DFAEC53D7,66825611AE6B115E,FAB10D154451CF70,A696F24962760F50,5ADA5E4B4730D92E,5F4264D6660FAC59,FD920DCBBCEC02A8,003F915EABDC9FB0,87A39429F1650BB6,FAD9FF9F66233C4E,F28DE8027DC5D608,05A232A5516543D8,D718B5DA7CE64A9A,378A59196B147FF1,15C527E209E9FFD0,003C3A8D046C3B1A,797E109E74F7F590,9C596885E88DD773,7CD5FCC8DF243EE9,77E00FBE1E1030F8,641344B4B87D4FDC,B760986F5B8F6DA5,297E571A5F6103A6,002A3187AF765938,C4F384A482800B91,4DE309900355DC71,1C0B1FD94A8B71B7,9ECB254AED5A2B3F,E58C81E02328EDEA,131BBEADDAA7DF48,D1F47E00AC04CA41,0014F54F181A3C85,9E0342B194C09412,EBDA23DB8EB1AB07,6E8076822AE5EB38,322BFA963E8AF824,28913692D6FC5A5E,0BFB2AA762F0C796,B912959E4C76B080,000D060287A94C6D,139307628CD59AE9,6E63C15E329A6BA3,DBC40F61D6CC3D44,70ED1010217348EF,168630E6E287EFBF,6474E1EF2D03CC15,8383BD56F8EC2B2C,002491F8E4ECE17A,4420BF8592A956FC,0C10BAF325FD9B7D,DDE90FEB70350CEF,1D56FB40F72ABFE6,CD2CE80F3E2BF78D,F0D024D6D09D73DF,1DDA0EF5418D50C0,00404A4DB89D87A2,AB480E2453FAE650,5CA89D84F6214D0F,9F16C94EBD3BDE48,7502D7DDBD102538,8F437EF8EE8693EC,86E22E8144B0D18E,812E07D8C731DE8D,0021EFFAB23A793B,12998AD18FF64DE4,19567B4C52D4264F,054C04C29F4C7C7E,3D3FCF3F24C73E01,0E827A7F84A0BDFD,274C636D4A7D3828,D2842EF22B1DA5EA,003F095393495621,CA165E067ECF8963,133151C4DDED6A8D,76DB5F79980FEA5D,4D2D5964DBCF73DD,9168C76099AD51E5,0D99FC14F290C139,A213C9A20DDECBF4,002E10B3F5720078,74E1DF6CB15AA578,40F25BDEC2D7A532,EFDF976907F3B405,3DB223B6B39EF0E7,CDD794B7280E8824,2FF553A30F2F9FFD,DBFF12C29FCDEB56,003BCB1B930F9402,F1EB3E0E861AF726,F0A9FC5002BBA59C,8C28F232B7FB1DA7,017B68329CB741AC,3BC8EA6345927201,155DAA23DB0B2646,41A8B664CF74D1BD,002DE6236530255F,2BEAFB3E0941C109,8F50BE6D9A32D6D9,EEC252003DF2FB28,1702252AC4E5B57E,E07C7B066F93D7AF,470766CF5F6FDC65,D98BD9062544E710,001C4CBE4872A37D,F383875E2E5239C5,51D49CE33D34BB09,6E4D9C702D148AA8,A21ADA2F0C4E8EB6,2ED1804F4ED636FA,2826F0933DFDD2E8,BA89E00139DC78E3,002D92CAB7D1209B,C117CB7191DA08E7,B0E7F6360284E610,A8EEC9BB4001FF73,9B27FF846FCA55F0,A87FBD3CB244FB7A,E845991DA03DE32C,510754B84AF09DAD,003D97AB17AD517D,A14F9B6B35E068E5,38DD8C5A644C37D2,1ECF4792C9147F32,CE36BCE9531774CE,0424CCEE97996F0D,B493AC26BBEFD952,F547D88F1FCE7078,0025073194622B36,CA645D0673702FC4,9589A455AA0ABCD8,37362C67684D417F,37968D5D682E8F5E,287D90712BADE188,2F48FBDF5FED023D,729527A3756724B8,0016D13D623C146A,4A726D6922B9DA04,4CE72C02B0A7B167,A743B4E1FADB18E1,D0ED204BAF786EC5,B032EBACF7B03B75,BD3B7B2E3451F699,46AAC3AE6CFFDE18,003D000A7FF1777E,818C972A5549ABEE,49836F06FE405381,5DB8AEC84FB5F844,0F5ABA5088822573,BED105525B82CD69,1EC4E072E909E101,2C59C5EABBAFB587,0039484D10EF9A27,1DD2FC079DBA3D65,901F7789C4750A16,C1B3D3686968C910,BD1C31FA9DF3CB99,CD085753BD486F4B,1E431F7B0AA43787,0DFDA06A98D32EF6,001230762D0D3661,A8B81D400345E266,291D3B8018C95915,DAE90DE3509537E1,F63C2DC3759D44D0,153B0B0EAD06097F,A99733687ED34DC0,ADFB9E3F944610AF,0021A105D39B9B8F,1715BECD3C9D8637,7EE12D3300712C1D,6B36DF1B9A474864,D3F942986E7C2F5A,C7CA71441BA323B1,5FA7D9F601B90C2E,364C54E6CE5F958D,0018ECF089067D44,5E09DBE6DFFE27CC,BDC0D9E803E4F610,A5C9F95863DC76EC,126E3AEDE42ECF53,6F1EA40CF3927BF3,69B876CF6149AEC2,DC20133F1F5F2113,0009EE50430091CB,BAF5DC9A710BCBD3,AF5C9EB185B52F40,C07B8A78A0CE6F06,94C02D663086980E,14987F3B9F47507F,DD9661261A99CA88,40D369B8263B47D5,00127022B7391AE7,E31747F8E95B6402,A9234DFBD68C53B2,3302F241FC9D0CE5,EB98D2370176CE8B,432FD9C821EA7C71,38DFE1D40959E5EA,F875B6A16C40A84E,001399BEE4C4AB86,B8A5FD580B2D05A8,A752B345CB916AC4,E4EFDC1D09DFF77A,1AF88038E969D7D2,4D60A9FD4C7A83AF,9B4B2CD468D9A57A,C74DEE12F2F5C950,0032B1806F8DDBC1,8CCE7D6DA1ECE2A7,1D8D2DE5642DBC41,6F820895385FBD9C,EBCFB0FE4873CC2E,064841A14941BD98,2C1F708954FCF6AA,EF020C20737E6F19,002E9331FE6DBD96,2C5F793E8A13D0BD,44554E3FCB2BC94F,4F99D2DE5DBB8C1E,4A1FBF543D24A093,707A5C43EB0058E1,7888BB7ED1D77EFF,522C799D0D3AFFD0,003CE172F9685168,EC209FF7F789547C,AB5CAF13859FD45C,8BA47944E2A81E82,68DC5C0D6B5FC397,C7E69285B01F6784,AB5B381E40635C21,26B397AB14CC3242,002E17FD41B34038,3974BF38F11C5D99,17D3AECAB9AD988C,96F16E5EAE2DD920,8645A60B1B8C7EF6,7C9E2AE51EC4C6AF,F287BCA152F99BC8,B4AE7ECC1C9DE946,0022E72AE1EA4AC1,0C4A45360117CC13,B15CEE40B1B82769,AE7ACD131EC065B6,5F9034E109684CBB,110BC76455AD245E,063EB181F64D0EF0,22690A421A1C31D9,0019EF0946E3CC90,869C87302F09D601,746EF5D4AD918125,11BACCE00F657AD2,574CF8CC599EBC0C,F5F40AADD90F1639,DF90B00194D45FE2,3ED6B67378EDD811,00367E697A424251,81705F303B867A8A,FD474EEBB60F5187,6F07FD3564175D36,B8D9BD18F9A8F453,0091F2625C14329A,F4E89F9B04FF12E4,820FB177F955BF35,000ECE093719C8A2,165C0BB5C455FB07,E3E2131DEEF119A9,7917C77CF81C4D14,97A787A90F17F1D2,C3912340D87E3EE8,35E3670FF4E5F44A,6F1E1AB4C9775AB3,00161C0EA8F2BCDC,426343756C30576F,DC9913D38E4C2AC8,B4DE451D034B01F0,DA8C5F7E58C9FEDE,7A2A011D5F9EAC9B,6DDBAEAAF9FE9BEA,5C3678851F48F5E0,00137A48E741D868,72D6C6DA38AD0003,AE4EF8BFAECDDCE5,1440631C07475635,2263DCC311F7490A,E0A03BF4E3484A78,C48BF5BBFAE4E686,126E262788FD3B58,003C9A9D3803A699,4304602E8D1D8A8B,BA3B5DB5F0E65E6F,250F1DAFF372C337,4F321C743BAC7F18,628EAD7534D63567,EE983E914DB47172,10F882AB3D2BB089,0032AC94EECA0113,6644095A65445912,F966E86CD335CCE6,5F98EBAC58F0CC89,B9640B7B6B0AF5BC,0FE36AE8745C72C8,D2C8BB65EA9DED0B,F918312F6EF1897B,00015330E8EA87E2,B72F3EEF8C4F146E,C7DD98A9F2FA1346,B8E79823E054AF77,40FF3902E36C8E77,045E135B4FBF92AE,A21BCDADEE3C34C7,34722C76B71B5BB8,0033D40CAEAC0204,0D2394DF58D3F61D,008CFA5DC80219F3,BED7CEAA75F6F205,7B8C3B459F41CF19,361A9642E558E6B6,408EC3A28A3B09D5,EF0B07628E9DD833,001C401E2B75E75C,0056385473EF9098,F11ABF70E92C92C1,C77B9801BF370210,12232C6B3778B8EF,5F4DBC91191BCDAA,53F06676099B63E0,3E2EB55944F84134,0030601644BC8463,073D04C37DE8C821,BF50EB3F842E14C0,6FAFF7359317BD7B,3C802C49F7AA6ECA,D34C001E426600C1,D31D103A53715785,10FDBC456DF21ECE,000E5F92DD5688F8,701753E03CF16793,E98583A8E7E60DAA,9C992BAE970FACF8,F1E25D85B307ED47,BF7B4BEA6FDBC786,03D9F965F6B0C690,1DEA641E545C4D65,0033A9A5866921A3,EF8EB7DE23AB94C9,5BA3E6887EC89CF3,537C63CA9537EFE5,20CA226A0CD7C062,7059FF8D93E8AD4D,B004A266A68226FA,30A674DAE45ED0C8,0032F4C4366116B4,F6B192C7859ED87E,3449AF98B474FBA9,14737889A89D62C4,052F3D7C011528CF,D52A4A987A77B16C,F9630EFE2A59C6B3,6F09FCB0BD29B7EC,003471F23D0A5EC0,8025045DE7CF266A,021970EB121BFC9B,00375778838B444B,2A67F41A79BFB9ED,BC96F21299999368,E4ABCEAD3AC36C1A,671F721984E410FF,00091D1AC7536B40,2EFEBCFCCD4873C4,5952BE697A06D91D,51DF50A324F9664E,C727FB28705F90E7,4D3867335A178137,547DD70EF7CCEA1B,B45FF464EC264ECB,00103B352139029B,BC90F3EF9B10DA6D,D608BA7263CDCB20,5BB33DC31F628B87,AD8A1ED71C545CFC,8805FC34DC82E13A,02CC8CC59F280526,92CFD88B99F70293,001BFF3BBF32F003,BFBE102283183B10,B47DC872E17B1C95,9C11F05EEC50B926,B67556AA8BED47A3,B78C5BA28C07A1E2,9EB0D3A750AB051B,29A6C611E59C915F,001406FE2733EFD9,05D092F250714676,A2D6D9F1F9F45E9C,EDEC210847ED2972,FAD5001FE08D7C2D,C094ECD4697FFC84,E38D92A1782FFAF1,2581780ED410A59A,002218A4AE68E095,60256F1D0ECCA2C9,65B97D1AFED66B44,CCB14A3AEBC6F0AA,6A491CC0ADE39F85,AEE07A1245E09F8E,7A41CE91EA321F1A,2E1EF3BDE3CE7E32,001B0EF19689D780,52AF7BF78EED9021,EBC6E24A2EF44A8E,BA82CCEBFC70BFDA,D4E3E89180DB15ED,A1EFEEAD184C01D7,18521CA2F8E21628,07132C81943FA9C3,002847938CFABCAF,12274A9B8B092392,1611D379EEB6FE3F,8362F1A333EA5E1A,589287691B68B975,91B5CAAA15706556,EC76D5E5307E7369,766C4116A0DDFE68,001D754E98B6B728,3D73C2C1187A0CB4,ACE19BD632406409,BC9CB2DB6371C74E,EAC5517D6DDE0FAF,58C785244528DEBA,640D06B71E027EED,B1540F582DB3E1D5,00168B07C361CFC7,AC8CDE18D9DAE6A7,AF90ECCA2070E828,41951C41A87401ED,FF9F800B2FCB375E,4DB6A7B7D79050F0,77F73EC0AFD19017,3DB891981F892766,0039C3F4F3F00254,8F19A35B6947FD5B,0386E26D956F231B,2E894B94AC5D9C47,D05CCD296493A1EC,CB569D24AAF59BE0,476D734F33C52444,0E5E476D4B20D24F,000AAF894F828F8C,E74CB21FAA8B2CA4,376A4A35FC4BCE7E,3533BAE53B8CE7E7,053FEC601D022468,FBB29991BEE11519,323EFEBB739F3DD6,4F075B01B2DA9FB3,0028BA853A6CA3D9,F52C5D9F83FCA5EC,BF2AE2297766ACF2,3AC16CEE1C0BEAF9,E5C11EE82FAC5A8C,79933D40B76B25E0,4FFED8F1D6016C13,EAAFB7AF3948792B,0031EE342AC9C8AC,2192E30158D114C8,353F76B5CA20C10D,92238174C85478FB,38F3FB161B70B3AC,009D391A984F1618,4E74B81E9330D249,3E3BFE108EAB8A9E,002EB11A8D92D63A,85FCF280C02F68D9,80CDF2BB122AD011,5DA76FCC01BA431E,D3C41840055C08DA,5BDF34CAB89137AB,64625D82D2372DDB,3C2CC83D4E10CE6B,000A71923035835E,4EFDF5FA9C8A77C0,6735910CE5D8A8B2,1957A02D6544D5FC,ABAA1D07E3239125,760359F4E092CD7C,4F8ACBF6E69742B4,70EB0F61CEFB5498,001AADC99C9EC41D,D24B8EE2BF84285C,D43E7BD60CBE0A4E,84FDF650D47FC27F,D5AFDF00181F00A8,89A04DAA90CFECF0,78BFB6B16BE9FF8B,510520341BE57B94,003EFD7E435FB064,F14F299D3CEBB643,E9CA388E5A4AC163,2A3B22AA69E92D48,36C88B2D356A1409,B017E24EE3AACE4C,FE4DEC6BA4D1CFA7,FC7BA1F9B6FD50A7,002CA7CB201114E4,23555091A6AF1D78,7821D760CA5469B5,100007F7C5F7261A,B904619DCED6CB39,DB41E98514F08FA3,7E52D3DD66B121C5,0F15F0BB3A9099F6,001AE71DAC55B5FA,FE9A5ADBED7CF470,9190BEA8381AC7DA,1C54EE54A9B06E1F,126329869CB98903,FA4A6708A6F26938,E3F2A87FF1F91B2C,C5ADD63FB19FA44B,001DF836BD265C68,165B28F1C7E26A86,87E80C6B60E9D672,E014FEA067FC2F49,118F56C199C287BD,E4C036B5BAC42620,9821C7152AF4C628,3703527B79BE373F,00070DBBF9BF2CFD,B639AD02CD8C55AB,CDB69D007B15BD5A,52D11E64B31080A8,A1F559F7C5E1025A,69B5071B4FC418A3,6355C3C024248D4E,040218EED8491B07,0025FD57609B9BA6,F5650081B4879FCE,CAC6455D88549973,82CF2447DCBEA163,9CD061CD4B8220EA,94DF763ED3940B40,F442F29C0E9717B0,A6C4499744DAEFF2,001F97D62ACFCA6C,442C7DC46AEDA402,9B2DCF2C35C950B0,755071A998ED2F8C,4A95990848A9EEEB,8C9F1706A7DA6478,DF3F62944AC4F362,98C04DE0B064C03E,000D53893687CDA6,316AAF6DB93A8804,249A45CBACDBA11E,F94A1B659719A399,DB440A2B6C09459B,23C032CA3FEF338D,F7E1E3DC1D217CF7,D0EB3CCAE28F6FE6,0027A7DF1848BA47,894EDF6AC606AA1E,73DEE80D197ABCF6,2C00338651E4C615,FAE9EE7DE19C7192,8EBFD3987FCDAEAF,F9C2D6BBF02000D8,049F3316EEE4FD3D,0030474F16D42EC1,5CE7AA241676BF30,EA2DF0D70B7A8B51,48620175B474824D,72D6F05910ED3BBD,D150876225C2753D,19F51BA05F8AF1E7,258072E6C85EDC30,002CD4CC14640797,5B01AF211C9999A1,AAD7FFAE004EBDC7,B11FD54D6D8FD79F,02F5528F065447E3,FB75F91EEE77C33B,6530280FDA3D6E75,D682BD1DA4597037,00212A1039920DFE,24DAEBB7A580E6F3,CBE6D9D501FA7F95,AA9210809054537A,C076BD4DDD372AED,053A570250940DFA,07B2FB8CC81E21C8,56C592E25CB22AE3,0032EB899BEEB125,0A1225EA0C41ED7B,EA56FAF411408D44,D3262B883BC7D006,5C5A8A1C3746B8C4,D4F065DDBFB17F9F,79089596222DA735,32DDDCECDAA3C0CB,001778D117CFF9F7,3653E1B694150C07,256E0A48E9D6B517,1614C430E7E5E2D7,78F7C6C65A03F2A9,12E37857EE008AB3,CA4C57ACDB272492,BA47425E36186A15,0026E3E61D3227B4,D1152125B3FF1A7D,F67DF2DDDF2B69BC,EF644EF4047FBDAC,086828F1C5C26A26,A00DC9158549B02A,F165D04B25445EE0,F177DAF49CA3B5D6,001827D9078CDAA7,FE57E6420BCC371E,6ED976C0DEB60132,5C986443C61A65C8,5F445A140A1A5A3F,79F883E734C40D1B,6072B1A98A8DF76F,67C89229E8495644,00206338464292EC,10119E8C20EC0892,17393D6FDEC76808,FB5330AC393CA51C,D43DEC27A66A62E7,D3B610D304682AAC,48A69ABDD15EDBBA,ABBF24564415582B,0036621D6AB42F0D,790845999364C746,F5884AFD25B6117C,3CCF91273020B516,0D70460D8340F318,BE8AA48C7B88A88C,4DB4A33C93BBA299,0319D2AAC500E0C5,0011C8653FF16E74,937964B23C196AC1,1D60DEF75CAF5E87,59AE162C1612B08C,6DDF38E11021C576,165F28BAFF73AA90,AE469CD0D191B335,E481DD5313F190C5,001A942333B0B2DB,BC00930F01EF2914,E29156496FD69B81,D3B53394DEBEC764,8AD2B788DA405BA6,19787885599BC3BF,70C66D47502AD5DD,85FCDCE0F3EE2F2D,002E8D1FC2ABDA82,A8E91400006081B8,1CEC98A9392CB152,3DC0C99FC813F68E,8815DF8C853CF3B2,2C4490A013674866,473D192D3ED4DA6C,DB68394F9584347F,0006BCBA0F2AD9D0,70244675FC1E1F00,85E43FBA86E72E71,5AD638E67C6CF890,67522D277FCF1841,AAE8ACEDFBECB0E4,E8E862BBF8BCE1DF,366F4B4C647D5E90,001EEBDD756C0D67,93261F9EC7AA7691,AC056AD6B73C6560,81DA22CF59B6675E,B814F5918CF1229C,F76AF37DFA761D7B,56859EAAE252B36E,13D42EABFC34807C,0031D3B22B0C9F60,682CEBBA9924622D,7535D53F5FF294AB,B8BB0D9585055B55,F8FFAA89BCE42509,F2F28B37ECE157A4,882924BCF06CFA6C,CABA95279583AED9,0026F05D2F9D59FA,C80B49F344CD683F,836CA95D51C91EF1,9F9236E98ED16269,EB9E65EE774CB0EC,35DA8B4E064FE32C,2B31F28792E79EDB,68BA5562AF8DF27F,003BA7712A2B6FDD,73F2A71F55602BC8,92CB2BD6470E6B35,676E18F8B217C253,B6C483BDE8C6C465,47F24B00D4452835,6AA7A0B73DC8780C,BE32A4EF2762A81D,001A70B9670D250E,CD0020DFCB7EC4A2,73C16F353B0A1A68,27C6C671F2C994C7,25180CE94849C892,1951FCFD8F0BA9B3,FD97FF71D8303EE6,2EBADC59B9ADA8DD,003489495FCAB887,E3AE25C40F9FC9DB,99D0AE5240699CFD,2CE0122C95DF0423,9F00D10254787C86,D15FBFD4FDF4E4EF,2326511F36019D9C,31C70463CA6A533D,00379256F125C7BC,C6F0F157F8813B60,715DAB1AE1D905A1,7A392641E9007997,A6CACFA568C08494,9043641437CE2876,8F697CD6CB9F27FA,1351D2823C0ABDB9,003D6D05E30F0E05,D9AC58FEFBEB2B46,28C0B3EC7E8FD774,7264438C6DEECCBF,DA8FD5B7CE66DC17,0F64F3129B1EAB5E,AF53BE7594CB86E4,771688DC6AA339EF,003D5C36266CA805,C834F218AFDBD30F,7D720391EF36D340,3685BE01E2A0DD30,FF0094ACFF9508C3,88BBEABC44D04599,4EF3868005365A2A,33C4E1ADDA203737,003355D0EE8D81AC,8DC57FA98078C453,F740F682C2522108,35AC63FF5CB89F0D,0002101BEF8BC501,EFC9D1309B4D7B9E,34B4726F93D2A204,4347D1E27DA03B21,0027BC3F0C8AA5DC,99B7FA92747F886F,31CA02D8F1BCE937,E594DFB19E6F98D5,9D4CB4CFBCC0F866,934F107472C309F8,D099CB4B2A6B83FC,6CDC1F2FE0C33B3D,00133AB0B35E4497,3149B21EAE1A726D,1AC100748128F9D9,0A0F434187877159,921B298727B906A2,31C661E86B975A78,C35553E98292C1DF,C1252FF6F8282C5C,0024131B26DC6FC8,B69A7146437BAB19,0B1E37F1F442E9F5,6B1FBBA31DE6EF83,670F337F120ED5F9,FA1A662CB0012E0D,3896D1B780DAE337,FE7ADA90D906C066,001BF7E2F3F80F53,6627C9F1DCAC60D4,B629BDFFE2B48332,47ACFD3A57AE7B6A,8DCE197CD0934CDE,DF362CD2B6D09722,839E64F392F3C6E2,B94B979E647E26B5,000800105BD034B0,E47D76B76CE8AFCE,FD21F15594BD105B,4237C563D2E161DF,16FC114518F2FDF8,16B5CEF4A830D713,786954D799C291D9,A815625DD453A107,000883079CCB3196,359442ECF54064AB,308D15CCEE726906,BB902D0FFA238B40,F75027ADAE2B49DE,889B22619F50E7C1,0BDC2D450F3C8436,C883B879F544AB4F,0013C6A3027CCA16,936E3DA7267B709C,7C2A08E2FE669F07,70241194C9CB57B3,2F5D4F4CCED4C5F0,A34D4F5FE31D7431,985C8035EA7F4818,1C07EF59768E0060,0019F3F47A8D2336,F14D5708478EF209,5C8120D06D055225,8E69EF9FA9EC843A,EEFB3DBE45A5A874,26ECD45B86FB010E,2719626381A03C1F,CA2B29FCBB6E9C1A,00342AAAF003FAA0,C7A7507746DEA22E,8CBA71C8117FE352,01D998F401641CD5,66EE20DB27EC8A88,5FA67B753FBE5CC6,0864FB048B24C6DC,12350E9FE591B096,003A8205E6C504D9,32D847D75EFA747E,41CFE2645B823933,30BD1EFD18FEC148,A9E378B22661BFA4,AE0D5CC75564FA16,2FA7417D6E9B6928,A1FBD980A1ECC842,002E6C9650E4B86F,E0B9AEC36BA0F2D2,25B62C1A5F4AE0E3,B2DBC0ECEE6E9670,AE7C70129C8DB210,2246D73823F06262,8343565342D14644,3428A5900275624B,00078BC60C4BD64E,BC100EDB1FAAB40B,482727805F0B9D93,A8143D7BDC41526F,16044FCB5FCE4AE3,73C4CD122133C270,48257A0E8EE5EBB1,86D733007A9FC0A7,0014A86C5EF0CD30,3ACBAD38EB0740D1,C608E5C9FAB37FF8,979BA0E81F29D8AF,6C2A9795A48C3330,5189CC5999F7326D,934329DAB99EACE6,BDCF2F0D5166397A,00373D20CB93E3BE,810CE3C638235314,3514BCB4D95B21B9,C01A652684EB03D3,C9B7EC071D49EFBB,687A02DE9EFEB343,FD41B8B12B96FAA9,7701E744122D737B,0020DE8B78DB8FC0,6D922FDC0F69A3C2,E0A79D11C50B84E2,E5C8870580127C76,BA371BE6A19C159D,3BA771A5F6B46063,6909F32717200643,110E4C2788F3D3F3,0030D764C6EF9117,53D6E5990F4C0313,3F21FDFD32E578B4,5CC9D07680695F03,FD914B0877523613,D4A038CF709A5936,584DE7EC3D8C9A69,D6C220CDEF3D792A,000FEFB98883B99D,991980ED63B84199,06671878911E3C3C,B6F483E789754BF0,D3D262DE6999B030,AC822FCD897CC596,D906201D1C6E2223,BB522F97090D7C3F,002BFE53864A1E9E,8F9E16F20DAAD2E4,86D34927B4431248,AB14A422D0C691A5,78E00B93119BAEE5,2E328C43A785676C,5DBE6766486A7257,3B45E1271D3EEF3A,003929DC1D4BFEAE,5649A9991BCC8BB6,0489B633C708FD7F,2FEA7BCB3434049D,3F88C8EBDF12BB4F,61B18A19AE49A535,B47467978D869BDE,38005F6714646AE3,00351EDEC9D81364,89C6B20BC0F8E3C3,9B64EEDA3256B0C4,89360FDF5B85C300,8A53318C20E779BC,067C69649D4246D7,2E73F5179A270C2E,A26B3510A9449335,003B77FEA4A257B5,75F18E55960CB58F,13DF41568140559D,6E595FB9F798C746,5E419DB4864940AD,53AAC4A618A96C60,311D475434A0445E,0B8919C951C4FFEE,003A7BC63C2EDF54,2D9E534E0BE76F53,8B5BF78439BA7C1B,BBCFB0006D00C8D5,29403D2122C464B3,D6A8877897DCF398,CCABB4374857318A,F2D3AF38B6053A08,002158C7433D9411,044278689223BC62,94E03AD178BCFF34,AF52B6D87A9E39C9,3D0526FE69D0DD38,EB43CE54D106009A,697F0D15E5B59A5B,CDA06ADBB88D1697,002DAFE02B2F904A,8EEE0DB83815272A,14FF68780A727333,AB63F9709E064BCC,9C6B51C21977431D,BB388443F441BA1C,23F5424139623545,11A820DE02BD83E8,001BBDD790C2697C,48EC9A5A84D4C15B,F35B25A6C4DECA8D,5143460B3119584E,D4768F268ABD9AC6,5E9AFEA5B782ECC7,29F4B4CEE68E9393,DF2CA07150D7817C,00125E6D15A17173,C4D8F319809EBEAD,3E365BFA76C1EF0C,2D7E2633340822E0,580F39121A74DCD2,14A06E13C70D78FC,B21258F156737382,EDD4A1C9793B5669,0030AEFDD244AF23,285EE0C61D42D36B,06AF4864BA1178A2,F91E8FC960C1D458,F3FBE37F4BE08728,72CE90B74BE9437C,628C83CBE91F6616,68618980F486EA57,00399ECC344C3D47,D20E448C4160E87C,EBEDE65E3BA3C25C,CB2FA930E8DB5446,4BD0A3152F46792B,3F337635DF01C7D7,C8008E46B16583C3,A792E71ED5A0E616,003073ED07E3D934,17833134CB41B7C4,FB8890FD47A17AFA,502DDCF8B9B197C9,C7E8AE3CB8E4F36B,B16D00CB386D4523,70C2AEB7FFD4D1BE,BAE29A79DADF7B3B,003B48BF8757623E,4AE4C918A0393CE4,9654768118A63861,8A9EE75039F9FDD7,6EFC31BDD7118991,AAC226EBBD1E999F,552F122DFA1F5F02,ED44C72DD948857B,00067B8E0C6BE5F7,1C37591FB328A3AD,214E957D4330592D,1EB6132EB44AB8D2,6D62982200DF3B99,76447157F5C2ED55,C2CE2D2B963BF6FC,77108F6E81686D54,0008ADA360E88690,A5D4B29C549C8829,AC1C76182EF09D92,FAF9554051D2E83F,7082D6749B027849,88C48194B757B391,4527EA5D2A183F06,20592EFC1E57E09D,000F3E24E103E8D4,B0497AD3CDD70A1D,1B3CB6FA6CD51D87,836C18FCA7E451C4,BA2DB8BCF1888B9F,C383BF00B0566671,14325E76DD67B407,A4299C22FAA02C75,001D04CF787ECF54,6992B3B78D5D5C0D,950BF0EA3FD9E7EC,4E025419847D0159,A97C84386BB9FD65,959CB6F20F668D23,16637587601AE77C,4863B79D3B319C74,001E0EA5D088F3FE,BD147081C3703B6E,4F3D33235324357B,4F85E1AC206272D2,892E3EFFD32652C1,31EDF3C36290CFE8,C864354DBAB14AB4,1DB92BDF047ADBD4,003528D0316063CC,774504D87D822142,3839E3EDBB1C8B7A,6238EC0E1F703720,0D599E32C06DE7C2,CEABD0A2DC97E46A,9FAEF947B84AE32A,78E38B4AFB0109A6,0018DA0A5C319369,989478F6EC032726,5538D328B91FFC25,2B377C76C857D965,B687FB49B400E0AE,A1A9BA67C95DB85E,B0313946EB969D21,D37B0DC902A0AE7B,000DF7A21F03E8BB,6C3ED22DB702F8BE,11CE331338D7E7CD,D2781D328C43006B,970453AFDCA7DB06,DAD04612C256B7CB,7F6729180AB571C7,4B9B043C248450EC,0030467E2C9047FB,1448272D23CB6155,DC960B77383C5AC2,60A546AEC30ACE43,E2FA8F27E9CAB832,A37FF9F0D21DF4F2,D3DE98D09E53245E,08B1BA71E4A048B5,00140EF6F5D91D1A,E8E34E6C010C630C,16ADC9408932E205,232BED112A0091AF,F2E278426BFEEEB5,7CFCDA8A7A19E5FB,BA75F5D07EADB9CD,51FD34F714D5B1BA,0015181DFC27DE7D,A6D9FE9133761C59,F0DB60D462DFB9B2,00830A07B2C83F51,B67F9A4D204F835C,97AEE1586976A47E,8F1857462CA193D7,B3425BDD9F093606,00182291419647CB,ABAD5B991800C3DD,0B40D68CDFF5ECD3,57ACF9C70CF96F4C,087FB16C7ECC57E3,4608787D8EBE0D71,0D022B64941B8745,0236F23B31FAEA5C,00303AF38F6A86DB,2ED87E9AC46DF753,CB852E9CB54D279D,84107FF0A797B235,A217AB0AF87C3FD8,6AC694718B1631C6,0B2388AEA7D2142F,C5324B1713F76D4D,002C8A03826ECE87,D03EE9A0E16076BE,66984A775988FE76,7EE7998ABF5A7056,8CE60821F5EF55DB,8C9D85EF9D66A18F,2E9D2DBDAE87D759,315D9BF7E5A60E4A,003BE66A4D8DC312,10250AD9A2C184D0,F47BFCB3CCBB4532,E1A139F1EDCA2AEB,44EEEF8E6B2C9321,D7BA6154F68A5CB9,54B009AE45FCC07A,C31B476C103553DD,0033D1F559B380DD,F947A585B1BB2A2E,3216CB085C320D0C,2C44AF9EB92201CE,CBE5793F2576B07F,7A85549B8C69CC58,B638EFF4060929CF,6E768302311E2911,003074D123757669,021B86C3DA88C0D2,DD70D98FEA8CC832,BF6EDFF793FE9150,3B5705681B2A6F39,E98A6E3FF3BE7EA6,FDB948AA4322FD4C,37A48BD524022BE6,000B38F08AE48961,BB3C78FD62ADDD87,17E310DDB980CCA3,2B9BF546544E1021,AC7A3403D3314EF8,748C1E9FF5660C51,E83DF90A38165C38,E50CDCFDAA02A7D7,000DB6FA453FD49E,015E3EFAE36B9EA7,5F958D41BD10AC2A,AE2C1A92192B16C5,69FCCD0CEDD67DCB,147CB3D0347D3297,1D9E5BDC8AB6908A,AAFEA9CEB1C02E21,000EFDF375FF0595,0C824F9FC9F39659,17D4A519E2BFCAF7,1A1C958C4A913A76,AABD6156FFC95BBE,B131CAE640E79994,3F580399CF537A71,83B9E04AB823F5CB,0008A09E381D4358,C1D373790BC18B1B,B6C4D6880892FBAB,40216112B43EB23B,18EEFA991EC513F2,6B5C1C18F45C874D,F5491AB35F0BFA19,25B1804626F37F91,00065B108FA52D67,A1BF96F6BB0B202E,E34B5179008823D3,1FE85E6708C3573C,18BA310E9A3229CC,BEAFB13F4DDA518B,EF1FE5E0DB1E512C,1CF33AAC0F81A862,003B400C87633542,2D0245034E2A1F76,1A852BBAEEAD44D0,A8AE93F8853384E0,FA4A07FA691AD345,D1B8AD3509722BA4,4CF3AD01761DDD34,EA682A36924F9562,0012A1E6F6F2C8D0,3101AB0238C7F066,8A4A919E2CC5F37D,B15F29B55C7E8F18,D0F231CA8BE71D15,53F8BC85941AF422,C36AF68F31E86EA1,A75AF5CA135BAD64,00012285F74D1549,B3BA4448A4805500,CFC949D14C4C1CF2,0B0693EE2435BE14,578C0C76A80AA191,C6EDB0D894E104A2,CC678354D693B656,F572471D707884B0,00006E09E25DCB56,95B35065E0291ED7,81AB9F4A8AE50C7B,C9BF2BE93CC0E94C,3015D4DF951EA792,EBDEEA1AF922910B,61EF7BFF50337386,29A628E22C3FE5AB,002328E40A091FC2,AC8CB1AA47ADAD6D,758C59489AC8F555,BE89EFF4613F9AC4,04C3C5AEE8773FF8,613EA5E6B48B0E07,F1E76F08195833C6,0DC099C632417A57,0027772668B0AE1C,8A8B2747B7FBBB02,34142535C6F77C08,01BBD3578ACDA859,65DB2A038A2A0DEC,B6CDCE136E2A8364,2B2EC11F33454F7B,9082754C3CB73309,0006395071E99519,ADAA77103C23156B,56516FD081C221EF,4B1B0ADC9BFD7D82,0BFC2979795A655E,F8A0E927AA4647E0,3F969E09CBB2F620,1F75C8A9E945FA74,0003DBF6EDEB94BE,208A00F73106274B,C840ABCD276BBC31,C521E845828C45F2,5316657E7CC84FDC,AB46555F0307427C,A0380D06AA24DFCD,7B5204A7D0AE2110,00395A4B290A0A01,5960365043772349,1669D8467DCD637A,F9974FA1815F53E1,01BC13495619C8BB,FB238A7418803CF3,8DD3344F13C2C992,97981BCA68235692,00394A10606FB97D,678E078218E973FD,EDD30EEF15A3E122,9B41D8A95510F2D8,53C60850D9F2F38C,1366CFC877221D18,90A85C1C29B9E46B,6FBFAC3BDAA22D24,000955842E86F9A1,64B442A6BEF521E7,CABB5094B91E8261,77BDFBB3F46E26F1,9CE42655A10AF0DB,B22E4AB493E2867C,A21096293A4F1A3B,F94641DADC53852C,001AC5FF14F05991,2B18F09C839A6E85,389C119277DF0F09,08768EE1833C355C,E91200931C042658,5A6F08F06324B661,E0D61D2DDC88EFCA,1594F3844B21C7D4,001011D45CF7AF62,385398C982E332AC,46F4A0A82547DA86,104C4FA22374CD04,4AB0FC9BCD331B3C,EFCFE3DB5C2D39BC,AE83E8CC8BAEFE6E,0BD6959A49757B7A,000C5B1B5AA1FD10,A50378F2BA94C6F0,EE5E9DF28B67B5A1,1373BA2F7B0214DA,65A45A6C5202CD48,A998440F969A8A01,3FA4CE7EE5996AA0,7B50AD8A9A352C23,0037023181D0AD44,0CF74138F4ECA3D7,080825D42E7CB603,305B296A5E983117,CF7000FE91E60CBD,002183C09F6E4237,06F11AC4B7F0EFFF,C8F0962CA369676E,000086724287CDEA,AF166AA11194E003,379B5ACC1DE9B3C9,86F1848DA8BF8FFA,EE14BA14DC979EF7,72ED33C426987B9E,4BA8FA471F31EC88,9EEECB732DB4E608,001088069EA136D3,C2F7A3D6F23F0E58,39775025DB8E0274,FC12FCF7DF417E29,38D6DA0BBB656729,62EF23F4349E5A07,035B2D338C854619,48F10F20F46556D0,000BCF6FE16E481E,FA606BFF6E26F1EA,1FE450E8AC7CF8D7,324F1EF1180FDF82,CC5F02960697B583,BD6D9AB825641B7A,E8A2658A4462F0CF,E7BBE5C3DE792AB7,00318A937322AB40,376A354082DF050B,BC017B8292977243,9964C1562CF3DBD3,6AEB44DC0B493C62,A67C56A82BE38B98,AED5F08315242423,C4817AC56C6C6A20,001F9B846C400C23,206A05C1C984A94B,B7B0BC56274EACFA,CE9DE9614405C924,AF0439D7E2A30AC3,739301A1FB2F1AEE,BBEAC2784C64F41F,6303A72958641D18,002863D05BC0B8C0,C18A3DA141848CC4,FAE49319E80EA5F2,2F2575BD9B1E603A,D93F9ED85836F9DC,2233DBEC6C7AD6F2,691B2F74BADD3622,180B941AABFE75B2,0031903A48164586,560D0E31C94CEAB5,FD5B79E7ECCA18B1,85DBEC94EF26ED42,DFA3464090397C2B,B74224E751335558,EEED3DCCDB8976A4,4E635926BDD0A02F,0023615D94E92283,DC61E5B3A818B3B1,D81260F09276DC8F,E1236E6332E733CF,FE763CC5CFA94F60,5AB69F505B1C7756,F3429E68421417DD,7149CA2F9074151C,0030252B6B66B74B,FD659F69ED634B72,7BC4BB2E839468D5,D558DA8799985492,A91C543A53EE8175,1B83FDF6CF38E0CD,8F22EE8C9163378D,C799AE278ED9F44C,0025ED384BBF7C00,E5EC20926A4424D5,593EECACD21C5A46,E6C43CC6FB8400F6,96FE9475D6ABB1BD,5C3D0B11E64827DF,94552B9B57919638,5A3B82DDCBE00AFC,003B0AA2F08E6472,501060B58792C49F,A7F1ECC590DBE921,2858EB4E9969A3BD,6EE92198234F02FE,8FD2E01375D51F77,7778B4A9FC056A4B,9E356D8FF0EA818E,0028CCB1F96C4E58,0453743B0210B3F2,6113A1C51EE00EA0,8B6C515D91563A7B,4DCD99BC5838A3DE,B75BDA848F09D05C,316A1A7C8485D074,505B1E0AE9B4C54C,002465D7B97FAC9E,6763F7FBB0600F1D,5DE405CA9D87BAE7,BC3F4CB079CFDB15,6E77DA5B80EF2418,5A644461B2CBA5CB,BCFF7F1242599F14,0FF225624FBE2ED3,002A111CECF1EA86,E372DA2E1837B0E9,488DDB545B042FE7,4640C7F8B678BDA8,8DF519490708270D,22529EA924749331,2C2E0D25C8CA33C9,62F59F1798B48A00,00298B6D18715C0D,3D37951D5559CDE0,6657B7E0248710CA,3A2326E0B6B39911,3907DD14DFC107AC,BDFA9EA84CB3F639,2EC671F6EE01B848,ED287735938E1B22,0018A2D150EFADB8,EDD1A8F9AB4583F7,E296895D7FAA7B6C,372333CC40410F90,56C7074085BF41FA,15EB7EC074B66CE5,99F140ECF0288597,DAB564419BF934D7,00018BAD64F34D74,D13A500464059445,15AEA7DC50A2E546,2CF35C52D3408E2B,9E8A945C5B743677,098FF64B551EF936,2D13D9C18F33BFD3,580F93B66AEBF047,0025D3B432E64F88,0FFDB3318E6F0717,1C7DB76E42327C67,B25B87E1EB643E53,400B767C54106B59,7C5E008D411ADD09,8E2A8B61C5B4767B,97F890949D241FA9,0018FF37F1EF7AF3,A28D64BF46728198,5A061D799D3C9A7D,72B88413CEE5D7E8,EEC2C0637889E68F,ED0922E0C53AAD32,817A959ACD1E40B9,7BC0D243A2159A62,00341C0B698358DA,46ACAC4B47EBB775,83F9F7C24F969413,CB65591AFB3CE8AA,593938196DFDBE64,789F53305F4D5B4F,D3292CCF53FDCF69,A493DD849416512A,00380881610713C9,5A97466082AEF352,0CFD343732C61B5B,14E664C1F2D44224,890B5951E74D5ABF,77EF69A6D1113254,80230BD78578D2AA,322DA34088E29711,0036F1F51B6D377B,59DFFDF2F180618C,FFA30D1C20400A27,441811FDF846FF65,DEF8B426CE3E5BFD,BE60F5B116EF4313,4F4424E6B8160628,EF862885270EAF33,000A5A0D6C3A85BA,D5CFD5F3F9C18DAA,0F195002314383DA,5E026A3CD297794B,EB7EC8791EE72C3E,411D1B51E97966C0,C16F862FA805EA51,F0C1E2736EFC10C1,001A85498D61358B,F7BAD07312A1DE4D,9A3B71A61BC4F85D,E9E1D89F7774027F,974D3C3BD23AAEB4,9DFC9F2EA5E215C7,B78C63CF2D7EBA3B,F3F6CD8F72C64A39,003309924FCE6031,0EE6B592D0E8A67C,5FC52903C2612229,9D24E065633C8DCD,2B752D8B88E16118,0EC15544CA1B41D4,FC64952205D86EA0,A0A6D7DD7F0801C9,0032A1323568DF1B,CAED3976B079E499,48CA5A79ADAF6F3C,1F3F70198DE1320D,08B8CDD9C952716F,7FFD55DF33DB793F,997D941FE014789D,D559024858C7A22B,0031041C23BE296F,BF27FA3D99B2211E,7DEE512B119E4CE3,FF3D9846202F9C11,C53987ABA89EF463,81F77E168E1AB234,4A6D03BEC25E041E,9AF9D8B0D6CBBC02,00097122783E3F7F,F4EB89AD329DD8A5,3D49E54B6CDE2F52,72275109F906A34C,6AC91DFE6067EBC0,EC1A2B548D918EBA,A24E8B705D78001E,584E6841E7B936A5,0020417FA361D40C,616ED5F456FA2CE9,A954A3F3ACAB1A50,D72D796923A2B49C,A8C5BB3B019874A3,9BCB081B41943D6C,9912DFDC9CB5C5E4,4D15FA6FB6749E6D,001F95C589D7A468,28CE50359C82C9EB,73F8D68329D399E1,7211F03EC691B095,720A8E1B76354CFF,B8E973D5F4B6D755,D5AB574F909B8845,C9D97BBE86E7CF4D,001B66B0F17077F9,39A976FF3B0905EF,13A59BBF45B931E0,82584DAD7955010C,145DFE36559C14EB,4C4D860CAE4D1CB2,8A8F2858F5CF04A1,86AD29A0D5D88F89,000155722FE4D208,10E73E0088EE1188,521105BD8DBB4389,DE3F2BC0627BC782,9134407D20B1C465,CD1026CB053D0A90,8626249C2008948A,A3B7C75AEBA0B916,0021EE200466F9D4,FB3D0866916E2115,B92685D234DC340B,95D6262B02E88417,8B94E29D09F3720F,C7899C898AEA5306,9AD504B73A7664B3,14E927225080AFF9,0035018DCCC3107D,291EF56D17ADAED5,0ED9CE127A8114AC,30E5D54E54416745,DA4350F79F83CCF6,058D5FB0E342ACB2,5C59BEB10B087CE0,0BD31FDCEF7684A3,002FC8B43E4BC0FE,5FE74C4DD80E05FE,038E29074B713313,8539275D60CE974A,BBBF77EF8B8EE021,CBF26BAD6903F457,DC7ED540B6688BDA,D81F20469EB9C5BF,001FF63A8A1D3230,A114C1849C3AFD78,6426B7D4A1EA5D14,DF62268DC343D0B6,15EC3570143FB339,61D439ADBF642958,85CE0C4CEC4BB5D9,6EE8431376E7AC79,003411945B0A0F5D,AF6967A925CAA9B0,14C1866D9C46E455,23E5A0A6A4A7AE5D,C4BF14F888828ED8,9DBF8A71DA122A06,6301869C6017087F,87C658A77EBE3F0C,0011E2CFDC428C23,672EB615812CA4B1,3855E1F8F4A6BC88,A8AB9BC3D17DBCA7,64C28CAA8DF3685B,5DE9CF4A7BCF61BC,5294DA46840423AB,324875B9A60CECAA,00314E3EE85A6513,5A91B4A7084982E5,DAAF04D25E3AB8F8,952443C0ED518D0F,B9F08F5B52DA9C06,852FFF270480E2D2,9F4F14DBDF8F8A87,0D0A0CDA5B17FEA9,001C6F29CAD0146B,7C2CAE91B88C6F37,3CFC1D158E52764C,6416361F2AC71A7B,6B153B1F83501913,248C2955A9520BE5,C4D3A1B41B36D1C2,674B053CE5940A3E,0006875FBB0C39E4,48C2C86CFF0DC588,0E5E8845E33121BF,1C726B4F56F50D14,35C48E590E1B3B06,85A87CE0DB0D4365,F5A9C23F1A7BEFC6,5F67DFA0EBA08A35,001D6986C60CF52D,DB5D9E132BCD59C4,7785443E480E8538,99BB48877844511A,7A8E22C0A1178F09,5F53E2F1A929B1EF,3E14131342F1B122,76BF78F54E9079F2,00124ABAFF787F9F,E3930DC39C72819D,857597F1CD0666DD,C2F837256B27ACC5,F369DBC20FA1F167,9464DC761C5EDBDB,9823C0A1DB7DC3CB,863A779F5FA9B34F,0033A56609472B18,F48527561AAB6664,B6131D3F0DBB186C,266D263000EEFE5C,5D27347C927F09EE,3C3910176BB7D875,BC1063849796BC4F,1ACE3362333A6481,00074E42A1ACA852,F9404B60E3DE8582,63139E3678DF5602,B717E800E1CE3110,AA65C4AFE8247C68,E594AD0FEE8E70C6,10741F08774D3CA2,7A973532E3EA0D47,00222896A5A60A5B,DBF06E433E0307D0,EA53CFDF277D7F66,94F26987C4888954,BCE729C50C606AB3,E26DD592E91ED9DE,F71C90998D2C064A,879068A96A76A299,001833C6B0258BC6,45BB9F4A839BB2E4,85B2AFBF22FAB969,13AE16B32B28B60C,310DF71AD22A3FC2,B2EB59C0E3622E92,E41BBB5DFD6704BC,3AC89F288536E9A2,00034E60B5ADF4BD,8454E4F9B7F1E826,D9F439C1834385E5,C75260ED29F9EF54,821F0EC1490AED5D,799449E2388FF264,F1E1840E54D886AF,F15E8F080BE79CC6,002E469D2A9E5069,47C8D2E6F253A4A7,4BA1336065CA811A,BC98BABA99E23DE6,E4B65E37457ADE8A,D9D6E8009423EB8A,F368F3469585C943,53C41601D79BE6A5,001C4FF17A687190,68995D81A766E64F,9E636AEAA1494ACF,1AF982D8BE4E1D0B,A59325528A6DB7CD,507A1C165481F15F,C91F934384D2E220,14410E688A03807D,0029820FCA7D20F1,A3ABB9DB20EAE98E,9FA8D0C27E40853D,96401824365F16B9,55C26873CDA91FB3,199A4E4EC17B3CC9,7CDB31594410329E,63ACF72D6EDBCD45,003C2B14AA0AD914,0C99B729EBDC54F1,B416645EF1CE723E,3AB37C5971F2F43A,4E45770BC13CC867,5B791E293EE4CDED,6603D4BBD11C0ED7,8D8791D229124A65,003B4F94690AB0FF,B0181D986453720F,E7CBCF78B2F0778E,55BAEC0794A76C8E,AA0B79B33FDFC62B,DEBA24C0BFD38926,8A78125BB98C672E,197C41A5150B2E6D,003EFC3E4AD64616,BEF1C89D19986889,9836E12E8C3D8B30,7FF3C581301AB8CC,5ED22435BFD2C918,EDCD9E616A9B97CB,FC8FDB5EECB02AB9,748838F9E77A956D,000EF030642D0BD8,73825F91635AD5CE,C5B08C746906E00F,F2AE3CD2FAAD261D,60E34AC0E270AD4C,3D362E470007CA32,1DC975618C798184,4547F645AD691D68,002C9126D177562B,97CEC28CCE8E75BE,99AA8B96780DA207,482D516850EEB7A4,B24E56C78CA68074,B1FA6573F9201FA7,6CD04F79DD77896B,9F66365FEDE8FB0E,0000F3BE81875641,E38CC8E469F0B3FD,6A2EF3A5272F400D,EC761702E049D94A,9B7DEE290ADD29CD,36368900C2EBC1D0,2B0B235D9D313C16,F68075DE6471E11F,00168A7414B4FED7,B5E2901D8128B737,B216C8C0234365DD,19E0E24E22DAE047,F0836C634D6C7B1C,7161A6DDB9779FB0,725FA60F7A50DCB2,2CC6A215D1B75842,00086DDB7378C7B4,1F5C3DC5AD81D366,6837465D484A4A7E,BE734254B0FE05F3,FDC14B5078274862,81FDA805F281604C,49B825A70F8ADE99,4AC20F04846F8E2F,0039E3BBA62726AE,1DEAB68D8F353DB1,5F78542E785B6D7D,87187DE93F40B8AE,E7A2F46648EBA2FD,7FAF8477D4CCB8C1,8EF68EBD9F4E3C3E,22E2F078A9E88739,001E1CF90A28B5D7,3990E532CDFD83C7,EDE28E549A8E7AED,F858A2EDBC040A5B,7ABC8D58262F3E69,6653BECF7A7B781D,7F15731D12738D23,1B0AC6B240866BA5,000D91E4B111A368,2A0032806B2C4CA9,1BA5656E2891F6E2,954EB5767EEF7F98,612F2A2AC342E429,FF54F341963D505D,AFD9B97AB7400690,28999F30A9AFA656,0001BE1BBC652A8C,D5881A73C38958D5,B51F4A50A87E0BA6,C3857EE4E1491ACE,ED1B435A704592CC,90AB4DD684600B4B,AE5209EE17C8C8E0,A144C436E3A2A6EF,001B3C090A1DE49D,FF97DFB3B5188264,0A81F67D07C1A78D,B81650958D56B1A6,E9C36A45B515BCF9,6F01C81B71B4C05E,8FC6D9AC3099E12B,1EBCAC5AEE2E1449,0029F6417D9DE077,5588008ED2EFD30B,03D4371B67E65138,6F979B86471691B9,82C5C9B0C4A776BF,6D3D1A36933711AC,24171BA13721C31B,62EF1F220CF773FA,00402AD26821B1CF,E1F7399BA49E2642,1DA9893DB833B9B0,3BA07D53900A440A,5CBFD221AD76CA30,573ABC36129C94B7,0692067992E3F35A,0B561D4833BF06B9,0018596C54E53261,48343973DFB212AA,D7BA5B6F9E0EDA95,DBADFE3D7FA8113C,8CFDBB6AD517C7A2,AE53D7EF344DCAEB,5DBF8D05F0F11D79,E491F3CB126B1D45,001385AEC6A20283,33803595C1D24DA4,6810ADD4E15D809C,6379303BF7765AA3,3A8B78DA7976E4CB,C49E41CB5BB381AB,20DF837E2FDC6B94,4468A1FDA491E425,000C7604EA9A4CC7,3BC5F97EA55D01E9,2AB6986E267ADA04,1CD35766C667E29F,BC02690295B74469,E2E330EA42D4A0DF,3F6820E040439345,425E8C7564EA3B12,00112C6A38A6147B,07F09764C56F525F,E62FAD630A6D5E95,FD69ED48A8D63E76,3E4431BAF0567EB1,39C79B8AC4FB08DC,9405A9CF47BA3E84,5EB6579A1AEF9C5F,0015CEDA5FE683C6,16814F03225ABE00,EFFF372C16214DA7,72E9755D75A9D74D,3768C1484B2ADE32,75CCB17175DC21C1,52E03C2D79CBB70F,BE4D48D005273D00,003BA16CA3AB55A2,2404835350BFA0CD,92D32BDCE206894F,515B00321F9DAA51,5EC1BE2D9D116A13,5621DD7B8EE3BB2E,C9923993DEC0263B,A73AD226424D94F2,002886CB020E8F75,23305D29B038156C,98359E7EC297B161,8715A0C6BD2F9800,D3674B66EAF6D4E7,0CEC6F0E023B84B7,DF6F1C47083FAAEB,2E25C6BC3492C23D,0008AF5E0C83F9C3,1CD019697FD26713,4596CE7D41AC4AA3,B25CD75037B3F49C,194A612A5B002B91,8C4EDBF139A3FBFB,FF074169BD8E00D9,30099BD63702ADEE,002AA64A3EED58C0,425A7558649CF532,BD1F357B30EA0648,AC23FF8A2A57B5CC,5151C6D380F93C31,271E48231AAD7E96,4F4A52D08924EF3F,D525D7108EE5DEBA,00357E2436C98972,BFD1D06FC19548B1,8FBCA2EDC6BF24FE,83A72BD4741A513F,F6BBFF22D64D6808,1E588FCBC44208CE,7487AF23997630B5,18D089B9D0F86A40,0014025ED9B28974,A318A329C3A87355,6DE2BD5716974062,4D3733F36E155DAA,BE9285B78B123F22,EEB12939400E1374,D190E0647C98A21F,EF50C8989D4D86FE,001059A5CAF9F153,D304176F8CCCAD76,83FC9C4454214AE1,A06F575CEBBE5B32,E48A366D6DB3773E,8E8D403C201C45B4,E0ECE31716953B10,3A207D4CEB5B678F,003AADBD4CE10B2E,C259912F7AF16EE1,497F7BC266E881D5,417B0BBD6F64D1BD,AF173CB741D2D172,97C74469BE195E76,44A2AD7438E7C8CD,3E7115473D29770D,00142AE7F03A8074,016ED988F3F35D61,2F70F14AEE175B6E,48F4CC8915C4CE7D,5E0D0053A2B4A6EF,B19103FA76592B09,B0A7C2B8F44E8A09,C7954B0AF49A6AE9,003E636A1EC4D9B7,BD9FB97474BE9AEF,2254547EE5053EC6,44080AFEDF9923DF,78CB2431C966298E,15C3C00ECB279A24,F4885A6B08156D9F,96E034FA53B68B1C,0035A26A8D74DF36,077806A3A4137D48,9F2D61BD11C8DA81,C93797ECF9578093,4D26C45593404137,4F22919470CDB1D6,844A96E46CF05371,15822A08412B7F21,0007B7058D8C4EBE,7ED711C8E691BEE7,623EE5A3262A4471,5D449F7F5206170D,187BC033C01F3075,A063F85895263CB3,8A3877293E16A65A,56F3A4CC1690D9CF,000809B56117D1AB,8EBB93CFF5599265,75321817BCD93889,C2A6A7B1AD72F74C,A5478DC16DF32BD9,EB8BDC5B94DEC1D6,5A32177B48988039,B5BE400C023953E3,0007DC909E0F2BB8,FD9AA8ADAC1828D8,55454C4364262BDB,6B5446FD42AF6E2C,2C35F24C4A53D8ED,143DAC668D0121BA,33133620B1D53624,ACE16844383B4728,0027EA87BDFE8C3F,7FBEC77F307947E9,E6FEEDB8B0110800,16E635685B84EEAA,6B91596E607C0A01,0B572669378A666E,540C6172F12A5E62,1595DC55B3ACA222,003CCE59BD031E2B,E554E931C9C3C3E8,362775AD93C474C9,4CB01E2A9D180C1B,DD74970E5C19CFAA,5F3D99B19ED51155,504699FA9023C4F0,0463E3C96AD3B7A6,000745B263A57C45,A7F40B25284A37F2,DF6D1AD79D8BABB3,F831133C999A8D89,AAD5FE20A3A6CF47,856A644585510EB3,81FAB32559BE5B21,EDA957B533E762C4,000CAF566887DF28,4C8DAE571431C6E6,DEF4D3D3D5982A34,9199AA4738A8B64F,C7064516EDCE8B56,49065EEDA179135E,8730C6194320CB4C,78F08EDA10074402,0031B922A5964B08,E8D812C315856058,39D15CD594DF9257,ABEDCFB1863CD2A9,E520DA5D84B5D445,CA90E504CB2FD0A4,05DA948CD1CA2C82,EC719331DA90281C,003EE9B887A4D581,194E4C3A51774B81,93810CBAF82870AF,80380777FEFE5DE2,8D803F8589823AC9,83AB2A3324AA53B6,7F475357339DECA2,C4D53B050C294499,000235CDDAC4359F,8A06B858C8950A33,4AD16044BE878FBF,856D450F39052C1D,363C13334EA0C728,B1D6CC5F263666E5,61F712E804638DB5,3CAC76C0AF7A3CD9,00147FF05C3CDD60,5E64D997B1DEAE60,5A4BC037DB27C9D2,28E88F2B425848D8,27E0DE772D424A40,8BC9E54301279647,E9FD01F61B3AEE4C,597D8C1E3C0B7630,0002D5D43FB86A33,2C53A3F3232F3D99,333554C6979E2379,26399F1526BAEC47,56AE3553AA2E88B1,3120BD229A2C43FF,565EC9161A402539,0E4365FC848C89D4,0024E930CBC5E8EF,EC44BAE4992450F5,A3ABFE295A829A78,7162BD2F9BEF2D6E,B1A30F717C55FD83,E94800D9F8A44AAE,035B6BE227156BFF,94FC0CA26B963883,0012CD20DF5055D5,C770A8BF6223FA51,EE85AA935DCC9F82,7C127DB6613F3B21,952CD0AC176AD872,B1B432FCBA6B40C0,19A5C990D6A57683,0961277C9F63559A,002DBC0FBA34B997,D7E8D468E964D9EF,86B35A96F337EB4E,44E11069106D7856,9C36F784A8A3F2C0,46BBE9F8930B2EE5,0BA93C03D7478F7E,2CEC3BD6FBE3CEA4,0012E47E80AAF488,6F9A05EC3C9F5FC1,CEF15DBABD1A2FE6,2D2BA5CF23837883,0F074C05C5EE796A,C5519632673FA595,C3467C0F72928CA7,8E7B305B4117985E,003F26E3BD356B5F,C8F1956AEA568B38,2B562D11DEA8D175,42BC28B97E1203AE,5AFD7EB8AC631707,895A4748196FF15E,DF619D195672C236,58A5CB62D27620A6,002E790C7EB8D41B,BB1C4750905F8E73,1ED19EF3CB8DB854,3D04234625CCB5CA,48415FA6121C6C53,F5671A35D2DBB4A3,9817DBDD02687845,5A7F9BC64BDFB03E,002D7BA02FAB03AB,DB92EDE3DB6C0D88,7A3F06BE415A8F7F,211E927BFBF20E19,43BA732040C37F16,47AC43CB3483B7DA,1C4D72B1EF7FC1CC,06F37D076A1D6640,001063FEF9A4D607,6BC62B30317EDD1B,A772E30FAFBDAB20,CF7E27CB2ED31977,004D4D433030EFB2,BDCCB77A6891A9BF,FBFDA69722B1F032,9019ED7F0881BF04,001A416BB8772908,60F38FC9347A0208,64991A5EA043E37E,8BBCFD379D62ECD4,C3E793FB5D9A802A,7935769CB72B60CF,380E0F2FD51E5400,A064455B913BBD44,00347006E7B2D857,CBF79D1C9FB33CBC,DD4B4CB4FD5400C1,09EC27710CBB2A35,D574208C10F40F68,948B3D0545C4BE92,4EDD32D0129BD252,A15251F3AD3EEA48,00196D50E579B182,0AC84F4270E7BB5C,6E20E3513466B3B3,FEB6273170BB5EDB,F8111B1FC4921A73,D2E3D5AB668D07B1,9106099F66BB291B,0EC726C961A53F35,0008F3A83AAB17CA,3BD4BC73DE9C377B,063F96924DDA17A8,5271E54970703B6A,6C76E7EE6D85A725,C365F4E607EA0AFF,4DBC3A6C631061F5,CFD24A07545F177E,0035AF66643A15A3,1DCFE6A66632368F,9C99E888D97C748F,6E02ADBC058526CD,C7052AEF8CCB6CAA,829E9462A312A73F,03D6F4F4267B9C4B,43945B3A8A842437,000877085E88C7F4,4D158287ED5AD12A,67BC5E3A84DF0874,F13F94D7359A6FE4,AA64690E759A20D1,5FC142B48D6520A9,5330FD3F547174CA,C78FF6D98CAF87F0,0005B250E3B3E9D5,1A015976AD54C7AF,12F1BD3631044299,86562E2B18EFBF47,43F4617C7400680E,4BFC1E3897104C41,EE47F22031A7D114,1F28F5C7E3292DC8,001AA8E0A9F603F7,9396C0A04A4B372F,C192B9D60B29A89A,106FC8E2BCB8812F,989AC695B562CA73,D66CBFFEA2E71E96,CEB7DA16791FA136,FF766B55CF66561F,000D68D70BE024B5,8DB0F586447B532D,8DFBF7D88F3D90E8,3C7C04B7F3F0D903,741BB0198CA2BA3D,7149823E7DD45415,96747F045E1B47CF,7126AB4F7ECC9ADE,003945E61215AB9B,4A16B5708625F2BB,600C2AAD3B640091,0E066BF5E09F93E1,5F4BBBE0DF16053A,FE47B49AD856EC92,002DE5409FB51399,F96C466422A03D8F,000FD3D286AA3D75,35CCB2ED9932B00B,A8DB9B2CB653427B,953FD89E7550C3A5,4009EE36BEE9A3ED,BB262373FD80A5E5,77AED856A5971C22,090FC6C881EA983E,0009DA44E3684F28,BB46F879B926C114,2CC3CD5A032C9E59,00D311E27D48D3CB,635E9A2F51C74DDF,BEF7095504A4059D,05AFC03E893EAEA2,4BA62CBD57907269,0031566DAF9D73D7,A252F188EA154800,7ADE7000D114E914,32D91C63BEA7BA32,06FAE2B5939265E5,872779F3A91A0DB5,5ABC4B20818614FB,B088312F9C81640F,001BE701C3BC58AC,E741DAAEA6726DC6,09DB32FFED08E4B1,7E683679E5D3C40B,B28DE072431ACE32,FA5C28897B64AE60,1A72A1827730FDDB,C943FE082C9AB28D,0029191FAC977AA8,44EDE8FC542623BB,2AF06852A430116E,22AECB4F87CCDB73,BF75555E71121607,C2B611DCFE0EF7E2,E2919D290C3D2BE1,B990693AB78F386C,00208D795462B655,CBDD7A741F5D57E7,DCED64B276A903C4,3BC4A1BF259F30C6,0B11FEB401D1685A,866E50C7E32A2211,11F928C5A008F07B,D49F442A3C56822A,0013EAEA59C4C005,92AFD163664526D5,42A3492FC35FAD99,B4B77CBB0C91BD70,BBDCAC3A8A623696,0DE07D176E28D5C7,54D93E0B46DF1A23,87E7A8C9C6AE35B4,00052F9B83B13CE2,2B1B191F91CD80D2,7CCA870F00179E89,EA557703F1D0B3D9,D5261B3F636FDB84,7A5E72CBB328976E,D09EAF501C182050,6015B92ABE522449,00386341D969A7D3,12E5CB3C56BF7F75,965936BE64E46504,3340B26CF6CAAC82,3D13FB4D25287CAD,EED068B0CFF8FBF2,02E613EF12A7E1E0,AA523B0636FE2CD9,0010E1D3BEC95DAE,D6BE32D357DB59F6,2BB4C796F4CBCEE7,3971D81605D80E68,242EC44EBD0D0BCA,B3FD3608B13912C8,66D6A02F49BAC11F,3668F19F63B75797,0001AA986BAE834F,F68BF9CE511AA411,2A192B7D51FC007C,1C611F536F885670,5B919D3D7C98020F,2476A295E10FE316,AAE84AF31660F237,41308FC77741DBEF,0017D51CE041F5E3,BF7EEF59D6B83998,206FF20D5DB05410,7E0ADD31B4F90F0D,06EC637DD1CF8007,927B5D5378698523,054A10149017B2ED,73645EA4927F2096,001E1B07789E47C7,FCEF96CC27846A47,872CCECB74B16097,AD5B5DADAFA829A5,23A9AAD0B7471625,D913F0A3C80DBF05,B169474341AA3676,7109814C8CCA2CE3,002CCC750D805447,7FFCD552F34DE14F,9A6A160B38C5AFF6,26A8685F19606992,2DC22A7F0B93D81B,46813292612516A7,A9876C091B84D2AC,FDC034B5F32DE253,00376FEE3AFD9F07,3EAC49DFB3AAFD5B,7F01A0A9710F53C3,F8ACB1508D6EE206,F2A9C78E46A3ACAA,529BB9C3D7497BFE,4EAD4A8C4118CE6A,5A2718BD3D7167ED,003AC36077AC80FC,D7141D65559DC2F7,9EED920B0B977DCF,3E3D46D794707EC5,BB38E7F66121D573,A9B0098B54F3BEBB,BC3D63F81C6181A1,0E67C7E825EB5984,001927828F03091B,1DBF9CBD3E4F234F,6D3E57A88C9B9374,C3B9B4F63229B870,25D2F5970C2D5163,C4E92687733A7813,6BD8063A1B013FAF,9B7E35735BA0299B,002A6E396C7E1385,3CC8974B404C5A61,8A4876385B2EA10B,3120464F6F094573,2814238E2E8CE25D,6E4C6C4D2C873373,A37D6AD02A6F8CF3,848591B8F468408F,000CE5701D1B5C61,B027C939FB8A272B,2C50D7A67F6CE2AE,DA42DD1B1660E33E,0DD00F510260D0AB,9E17A1E5D4E7FFAF,20E3ED84A833ECF3,7A21BDDCC3D1657D,000E13453CEFC9FA,2B8514ED53462F40,C4FA3C4D29456AED,07570FBC9561698A,CBC21CE603D2888F,072307505830EE28,F6E863E60C54DACE,8B86CE0F912397E2,0004F2967EC5A1B8,104B64F259F83320,3B2ABC0E049E4EEE,4F5216E7180B0E00,3BE100A0EBD9AE24,03DE682E33A6BBCC,3F6EC4909828479E,8EE149DE07CAB562,000A308BD37928D5,E4C19585421E2035,786BAFCBC7A72149,CEB64F3158769102,C7DB5887FF98F6E2,C0D067C1E753D90B,5BF1D89767584E49,8ED285DBFD1AC775,0005425E5D60944D,D6460C6D17E65349,B1674963C6162607,0D3CB1613FE9805E,6932E404F435DEF5,8C44797537988068,314D4D2D793AEC9B,20A49C895269458C,000768747BB98B5E,FDCAB370E61221CB,610831BCADC7A79F,5304EAA2F4F3F615,C355699E1B5A0990,7B7B107CC3155E8D,70D5DFC82EB4B066,1E53D126B82FFE14,0040340D11393752,E5E2F7F0A0F68DFD,3451956371F70B9E,E6090213744834D7,084B3C8A02508A69,7F6AAB761803A031,711154E0AF7EB9B9,AA48F531B35EA365,000E5E391288F97B,974B0ABE74EC1A8F,EFD354A0B42A397D,4E69B39F3578424C,84777D513C4242C7,77B6D37D8701F054,BEF7E005D0830D5E,1422E32CA6A54F40,00008C9BB9517F9E,D620CDA6112EC0FA,758312C4D82AAC90,B76D807AD04C4076,A2E7761FAF34D3CB,E6F2BA38DAC2D942,B5454E6F6034C4C2,D8F65D451C3085C1,001D781F7D8F583B,B37ECDA0518B7991,AF96ACC83AF9B164,BA410ACC26568846,BA1718ECCBA7FB88,B061705C3006A8D0,6092C66BC92A1094,6788E09675FC77C5,003C04E9F4711ED8,23D84EAD4080D4E3,FD92B39B15CD2D40,CF5D2C63EF60F126,9076BF3936B9BD2C,33CAB0B586A770F9,0A717CBB3843836F,BD1FFE5E0FC3FEE4,00239B527A06C914,54AC6793A92861AC,A9DB78AD3D5DC9A9,30AD9574E47F2087,68E027ADF9BA322B,0579AE2B93FCA077,0A857929EC394F23,0B2B420526158E7C,0003365EDFEB7B1E,77F5FBCB8A5004A4,A5A829D0C293E7E8,0B677DD4ECA55866,A1FC43A302CDA8F9,EECB50DD28B71553,C8DF3561E1D172FD,D35EEA212D6DBF88,001BD5B4B5AA1E9D,E5FE58D0A44E7299,D0ABBD71CB9C6C73,2292362AF816129D,1FF3EF68110EEEA3,9FADAD971D0490C8,07D26DF43DAB402C,20BFC5E1FE8BC314,004051C78F8DEACD,8504DA178D7A9347,AC0CCB6AC834B43C,BC2C8B8C4F95FF14,E8EA28AF36D0DB56,E49DB1FD4D709720,9D7A598A87DC4663,E7CCD1518F5E0109,003E6FD84D75A1B1,57B9F30CEF10E50C,81C2523E949564A1,F889F37F27CB6DAA,251F297E107F5463,216BA14C0C8E7146,948555E2036A27F8,BCF6F93A10172B99,0000A91F30F21F90,C1819BD987C141F6,32781013604FF091,4F3A49FFCBEC1BCA,2AA309669F01150A,87CCEB9697E74D3D,AE5C67E77FB6B352,8AFA87C5B72E8162,000C7E3CADC13CC2,7D48CBA04CC3496C,EAEC2A338AAF8574,60EC45E754A54C73,C28285F7707940CA,52B10A1814D32C1F,1E9402C45B3CE643,EA175DA2E95E7467,003CE2930E9E1F84,C076ACFAF02FD9EF,D1FCDA2F27DF984B,2E7DF56E2B299165,2B28E5EF89E583EE,8F7DF9A767EF637A,1AE7ABC541C75601,87201102CA98C4E8,000110E421474784,567C797FC821B953,571DF3BCCDB9C806,EFC252E03E9AD44B,C220829C470031D0,78060A1D3010DF5D,B2265E31B2A058FC,EA71E1AB6BE2DA58,0024D9253917EE6C,234062B6F80A3C44,1CF3E4E4F777947E,95FAC773482E19AA,109A4D5721E01FF7,4A303EEC4372D83B,9549566414AB4E54,3EFE03BCB1900ACF,00328D3657714344,2F757021817650E8,024016380D99CC1F,9725A9C1EE9650D5,86B44F09A5D78A9F,3F9637C463E4CD28,65790CDA4B7ADC39,F6C83D2793697F5B,001B35F0AA31798E,06D2AC7A58CCE9A9,8D9B82C69EB97AE3,D44E1742DCC7034B,4EC011CDBFF6B39F,2A1A7C0AA33D3BCD,903F2019142270FD,5748185834577EF2,003F1BD52089E552,A4FBED1AEF51B926,C7895B2D6CE53C97,56E86B2450963848,82424745AC30A196,397779D7D44DA0F2,A9ECE13AF608453B,AAD060B535909BBB,00137D521E05EF26,0080B51B27E37AC1,628EDAAAF9C48563,BA3C6088C2C075A5,81A616993753A097,0C532F9FF182BE8C,0B307C0328807E5F,364078B33C16731A,003D9AFFD70CF7C2,4A24297C4C73BCA5,2C1BC1DCAD811DF2,F5DA6DDADBF584A2,17AE1816FEB7F6D9,CE5C7B51E0BB9AFA,5F84EB54FEDE6F62,B8D14CDD8BD980DC,00383BBCF4B9570D,038D68CB3130079E,127CCA87A7B4DE1F,2D31EE3C3A6D3467,0A4F4C4B7B885B02,7FF064A50BE54E7D,877C83FE377667E8,F464C3917D91B925,003E0DCBE77039A3,A07537D416424E5E,4575F34F76066779,89D4DFDE091818B5,A1B868C620F14DD8,44F6AB2A157D2908,3A42C3014B8044A9,815BD4D6469963AA,00118493574B4DAB,921CA98BC8D90048,7D637CD4CC53FD3B,41ADD36AB0513AD9,1A00896C5CE9CE18,FE185832CED9EB60,4A28EC4B074406D0,79A9C7C7519CA122,001F466E2DC223D8,8D91B3EEAED87BD3,1D125F569AE5B14F,E57AAF9BC3BDDB81,703AFF91248CDDA3,3CC1A3F0578C2C40,05A7B3AE195A88A0,18BAAE305736FDF4,002EA8F5923DD75D,DE5467A6BA6730A8,30EC9F1859894CE0,1E3730076CF8E7E4,D729393B43503F56,0723891627E4863F,F81055B6E6F682F9,34F9C81CE5B01BA4,002CC5ABB21E74CE,11768593527D63BB,5D5587C5F325A50D,3A4CE088385CF6A0,69E99218ABF2C6B5,6719C8CB54B6C7FF,BCF60EA0982D7DFD,B173706D016067CF,000D8A6E5821D432,85C4962DFBF6241E,1193208B80E76FAB,2EB955F6837807E3,EEA63545A4CCF0E3,6E05FC3D03A71EF7,087F3C30A901B65D,6A126FA6BC8AF63F,003F5703CBE59BA5,3F3408200ABF661A,64547C632E65A71C,44A84DD5BEE4970F,D888421975673E22,5080233DE1E72E2A,13029C427BE5642C,7243D027F6135333,000DBE794800B56F,2916A58A279626F4,3AEA28AC8DFF7F2C,3307C5DB20DDA031,88EF8D33385EB8F6,E1A6D64E2170F1ED,5B2C5BA466835F9A,F08399F4D55538D7,003E4EF85CF19039,F5014B9DEB5C7B81,744EE0672CE1E203,36F15B23E8CD599A,1235CDB4CDEA7455,5B5A094557314769,CDA05B11A7BCFA91,3B3B9C518828BE46,000B260AFA8C5D91,3F6C784C09FE5275,850C48C341C65D28,A17AD3C30E0E4D83,A5BE7BA9942865BF,665E0F06CB5225D4,F603DB6F67784206,575BC5B0DE834D6E,00313F6E44017DBA,2858C291CAB4B851,BB07A5AD7825B06F,2EA81FF8943206C0,FE88D5CAC90A9B60,638A5014469EE4B5,0061470AD2483E3D,B656A372DE0A3F4B,003F0DB76284D03E,7729857475B15211,4C6976D850051CB8,D1A539F05ED5A2BC,93FC4775F36727E3,E2524D9CE0F274E5,10FB2035463CF544,CA6743E95AAF2452,0001AD8FD5456A2E,04BFD85AD73A8F24,D028B2ED811C4C8E,57CE3BA806694733,2E4889D48E5D23DE,A7D9C6575C1913F6,2B9D60B771E3A3B4,C6AB60835D6136E1,00216198C285A6B2,C9DE9FF0D918533B,AB71B5350FBD89CA,329618DCB294A557,2FED1D8DD078FF2D,915666F101A59B82,17CB16720F7D24EF,8E87B0AA0799EFB7,0014B56FDEB364CD,CC7795CDE291B93C,837C9F7B006260FD,1C054C6B46B423CF,EDB8EDC66FF10C5A,45547C7881F5939D,E1BA1A28485DEE0A,43240B99E36342A9,003C20B98B0C12D6,6ABD70928E50925E,EDAFF304BE345879,F048278B327BD6A9,E27DB78FF262D84C,B1C339E12180656E,F7B01554ED72AD1E,E1A7F31D6A637BB7,001506DF3AC4F15E,5914AEDF07C37C8E,DF2FA44D9CCA97D7,A0E8F9150278B0B2,6F9136A99A35D50C,33868E2066377576,83FCAC47FC3034C1,B429DB358EA3DB93,003E6D71817014D4,A3B24FB4C2FE2589,3EDFF6B241A60B20,CF3ECEF5D36F4D2E,0B83FCA455B747FF,897327AB06BA985C,AB48C28DFCAFDAC7,A032E487C841FBC5,001041104F6866DD,B1B935A682EAA3D9,9A36FCFB058080B9,2A35053C4ED74DF9,C85A4ADB5A9DD1B3,19839B3D4DC877F2,05233BA7380C8390,B64AB477F40B1813,00168BD6145CD74D,AC61E90E604093D1,0F3627F07FB9C6A2,A5F2FA3BE9396AC2,10303CC40BF2CE01,96520B40DE7A20B7,9BFFC2E01950E4FB,481A3D52F2762911,003868386B03CD2D,0FEFA5ADCBF5EB42,52592721EF9F16F6,465F3D5260EA92DB,C32063DAB2A1B2C0,F4DD6A9C6D33A11A,18376703AD5E136D,AD5060EE6C73ED46,00359DE5ECDCECFD,297BBA0C70F2AE2D,5A9A948969AAE9C5,312A0A8D684EF686,13EAC2E8EA0A52FC,5E5E6421A837B7C5,47C9FB01F97BB8A4,6604C2590B4680C5,000F463A7F9F7D07,B1B7B3E90A0197D4,044C66B892B3A755,050634EBF8F52096,D2E1172BD2C09FB5,687191DACF267752,7BE4052D686F8F60,04F3BACEA52B35FB,001423D99DF4322C,3F5A5C8E983326BC,315E6FE98D357308,37100597596FA194,04E90CEF3F507820,63DADD6B6D6372F5,48F9D1E66454CE43,05D07A85B4E81342,0026378E0C0F4969,85C781969C7B7925,730A74874BF892C3,D2ED4ABF5580AE48,B797B5F674D9F58F,2AADC286F4A05A6F,9BECEECA2CF4DA84,D422C569929CAE83,000A8F55010C7650,371DCD6D3A4A1270,EF0D3EDC4D65A80F,33071F707C32304F,080BC7782CB920A7,21EF5C2B62064454,6B35292340D6F0D6,9F694F874A474CC0,0037464E6F081FF6,C2EEFC8BFB2826D7,43D1E0B9C0572C0E,B84684239741016F,1E6036CE40B20DA1,750EC5547035A655,F3856E32864D371A,CFF105C16DA227E2,002EEDD5A0372C22,193E4CBB2D7CEF5B,443D8D207109B291,7F74D15F0E7176A4,AD7530FEAD0B560A,BDF4D2DF0672E1C9,D09AE43D3D12B0AC,6CE1A2AC3B96EFFA,0034D00595099A21,263168C8873B3F22,0AD004127D6AD9E8,F77EDB120E85E794,D6F66399B143D42F,AE14DC80C5CC3534,D2A019726F54B6AE,176E02B613F0F3E7,0037B8887A456C68,5FD4AB888390717F,A6D973AB7D858D01,EA27C922D08E5DFC,133AA7477CB494FE,0A3EB8B8AC077214,078ADF33D80F4EF9,9038865A7A449B5C,00251510D9BEB1AC,271E1118571EC863,7A1CEB4E2C143B6A,B9FC65CB3EA8C1CD,F4E1D61196120AB7,E19945E783C9FA1F,2EF5CC4E6D412479,2D3B28AAE8BDBBAF,00188C87CBD23CCE,B8F589AD52C417AF,B19BAC2FF279114F,ECA6AA6CFAA66820,0F6DB81CCB445DB4,61A5A70425E65B65,014C591F4065DFA2,84583A647F770E10,0039BF1EE55CCC81,4CEEFB8145C91B15,F6150686AE08D0E1,2EF0D300F844B183,E33BC267A58F0852,0FFC4A0B4712C289,955593FD801A9EAC,2DE24102B2226C8C,002142029E0D436D,B7DA3D03AF4B9A6F,FCD194F8A331CAAB,D513E58677DDF47C,6BACE525D6E6CA70,5E299FEE938FEC70,BCA68FEA1F1BFC54,2A448F74466BC3DE,00360C34065BC34C,FF402F74D5AB47DA,180F15C0CB4B1E7B,CF9291B98C2AF670,11743328E1F17D80,8BEDE3C35ABD7F35,F8D47672B6B322A0,5515BF59E69E870D,0017FAA9E6F28D5E,ABDECD2607C26B00,EA4E8B0A1A8B05CF,E10FB6FD875C55D6,A9C805B9476FB766,E6B256E1081DE69E,0D49F378F46F0A42,CFC66DDBC43620D3,001760E5D79D4BE5,4923FEE4380FA6F7,4D36FD4473A52F77,76281FB0CB67087C,D19D7731293DD7B1,DB2B80C42D852E5E,F1096489FB8BF32E,B7BE30C5DB1D5234,0031248D802D29A1,F013E55D283F6EE3,97CD5529724F4E7E,1EE2952A5A7F37A0,32ABE5F773292443,C8325F4BC3C0A75F,1301A9CDAA28780F,60A5ED5D57E4FAF9,000EE07E25485CDA,0C64DC887F96AEBB,9D56A35A844CC273,370B6CC680499AE5,8EA0A3F76FD35770,AC1198FAA247178A,FA37FB19BC06C659,E58FE3D34787B998,002D952BC9FB713A,DAF5500AFFEEE98B,A10E31F036FC0727,1B04C61251EDE681,531C93A950B23804,1AB686029C2C3D95,D0822D69097C839D,9BEB1305F3A45031,003C591B92644F19,D08DEF95D83AF945,FAACE1C25CC7B639,4E22BA05B0C56402,80438C2D1ADB1DCA,32736BAF139925CC,A05953BDE17AC7D0,2C7886022781C53A,001E980003697401,8AA75B8AF366CACF,697FD4B42FAB35C6,79B863A64442BE97,0098DC59260EF140,279E7F7C75C56BC0,0788F8A2F4E4E6C4,5C255C547910AA07,001CEC2F1C77EEDE,C9FB67FAE09BC2EA,7B7F69872444CC42,7B7671187D429550,50AA3B0AD237D0C1,0680493649C68A37,8E8D2D66F06002ED,CFCEE645342561EE,00087FE99987276B,B3C38E829AA30DA7,A821585AA64765FD,9097EBAD84E93A91,AEAD74110226EB9D,5E0856E235365EB9,7916D386B9B8DC8F,94D2F4D7605511C9,000E82D4202A8232,78E4F42D7C998652,1AFE7DDA7E63887B,CC6F874D270AFCA2,7E867922EB89D1C3,578EF852BC46863D,D69C8A657DB1041F,D36298D7754D7AF9,0023E0D106E66351,3400890B707DB6A2,675466F19E143C05,F9585EC6EC8FDBC3,575935DE82D3C8C5,972BE647E379DDDA,64AEB162DFDA48FD,4051CF32E8CC318B,001E5ACB016773B2,3131B99BB4D82335,81AD9CF1159F588E,425A12AB4E9E4054,19595423977E839A,2BCBAB65A84E12BF,9504B9001A0980B4,A737EF656BBFEBA5,000FEBF689E578D2,781BEED8DD8FCD17,DC987A7F012F8FF2,903B616C4224E379,9081233DB3AE36BB,C8C5E5AA96664044,187F522A47EB6F30,450DC8A4FF2C384F,0002F27E7B693786,F82443FC5DAA34D0,8006522F8F87B9AE,9ACAE9BC422A5089,0ED96194CA1FD8D3,C44E4269B401C98F,2543F8CA4FCC797A,8291E4B539EE8CAA,0007C2373B81446B,A2E2285D09E86622,BB6AE5FFA12892D0,1517EFD2B3A6A78F,CC24F855EFCC0EEA,D028898A9B4CCE7B,8E3CF34D1FCDA754,55294C3015B575DF,0003B8F64EB97CE0,0739B1E07A11DD0F,E11BD904D24DE0B4,AB7A3E5731F0E38D,A791CEB24A6076BC,399C4A0419866CBF,0CF66CD90745BA6C,DB4F46D5E8551521,003675E76AFCFE71,49549152FE4ED339,1D6BEDC745E7A624,A701756E004A1329,0561E4E7760E413D,0619EC964BC5A50B,703A358CB327B53B,4A547BDE2DFBCE40,00251A64647D13AE,0B7FEE3BBB2A0544,B870E3B050924DB3,DF433F271B1903BC,FA9B24AE31643E51,77757D84690048F8,9CDCC5AE6A35B2BC,A3D1A2949EC15411,00267725A3ECA4AF,968E0A4DC54D4050,CC885FF3C2F6A587,49F24D27A5771C36,9E7EE69D296733C3,06468B4A569A9B81,E3301E56BB8722D4,A0312FFCCBDA664E,0013E435A654CBD8,05DE1FBCC0A15FD7,1DE452A5DBAFA566,86AC616A104595B4,7027593A4FA37C14,D0A8FE92B84852BC,C568BFF0C3B1CBA7,842C5ACA7A399655,002A710BA8A444CF,4852E15514A9C00A,515DB50836F071DF,68C02215B14B231C,4BB06490F75C8706,EBFAEDC7FAE67FC3,F0AF79AF73E0572D,9D3E8A475B5609A6,000F15FE371C4390,6E30290AE04E8652,94BA766F776D0CB2,13BF73097120484F,52AB1D2677999B63,B5027554CA7F482B,53DFE89351E4E546,E54D586A9DB9F0C2,002AE4143EA4A4BC,4FD51C4FBBB4DAD6,D37CDDBD79E68012,BA7AF5E3E1F845EF,8170A713C314D72D,D2BDDD74CA84B944,CB9AC1475C217DA6,4BFEC2BAEA651EA4,0000FA4623C8010B,8E1215A017D7BEAC,92A215F96AB2C746,0E97811D47B3C362,340B3218D5FC5622,4A9FEAFB505BE7E0,70625F33C84070CE,AF8E76A7F1A33174,0003122A030C9D1B,A2886F7A1F42FE25,F4619F625CB64971,80F904F606ADB6D9,34905282AFA80394,94FED0F02FB22218,839A94AA73A54D5C,7052F42A446BF790,003C3E7A298A52F3,843728D8029F7D94,348D7DF0328B06DC,273B63A6029B4855,8CE5650BE840071A,C861FBC7626A6D7C,649BFB447C33C31E,86696404B80CFBE6,0020776195C730C1,BC4A57E0FEC8CBFC,E4E848111D796D48,18BB97120D32E8B8,CE0A347B7CE415E2,54AB4790556E80A2,56F552D7B12A05FE,C6C6CDEDDE81AD47,0010EB22504ED1F9,1ED6FE529628D6A1,B7037F24424D7366,0D4A0E31E81784B8,26876D3AD49E20F6,238375F09EE806E8,D17F7A5C48CD38C5,CB0D477A812F0CCC,002762FEA32B6C3E,F65732E1F688A9EF,4FBF97977FC11FEF,23819B774006D273,CD9BD9AA399AA2DB,BD6261B3506A719F,51509B0AA40E9E2B,ED7BAEBC541B2580,0024C3ABA9B410EC,009E50D975CC1384,ABA7E24026C6BB0D,08F06E7672D60B4E,28B136502B44A92A,B395441EB77EE53D,685E9EAB988586F5,D5F4F9CD72A96B96,0013E1FAB3146B5E,D4A9C7AAC3414C1E,F33C32AFC28584A9,D5DB0B2E4159F213,985C309B1B253CD1,AC963F1ABC535382,1778E35FCE7C299F,4A58BE5B83FF8D33,0009F81732F036AD,82A2A54B52E86936,CAE5DCF53F4FE308,AC324A86D0DCE89B,CE5704632EA74756,83E9DCE82ADC0D57,F67EE3F51B074851,F2A0C62395F0AC94,003959DE7F45B37E,D11C71901B28A1A1,879D34464D090946,4F1650C02AD31EE7,0AB38B7B21688DCF,C2ADD548E323879E,129A19E6A3E4DF32,215D345FDEDC8294,001C0004970A195C,C69C4DF641FC332C,10692C907CF0A1C9,868B26CAA9304E18,CBB7F942EB223634,1A3480ADA4A34005,8099635F991953B9,C3B8AFFF724D34B1,000E273C7B71B70E,0BA7FEB5BD53AB89,778E7337D21E0751,740D95C7E799D887,C45DE58181FC5EF7,913AC2E7F20056AB,F5A1BD53F7A21326,6BC355175CFA3656,00237E68C7E12533,90DD36F62B045F59,D2245DBEE50C7A0F,87DADC88A68F7082,D2AD9EC540D52727,9DF854A5039ABBA5,92256FFCDAD86C52,69388D313268CF86,001A06679EE2BDE9,0AFA5BB252B3AE22,18C5FC7EBC26BDD9,1B2A3470F4301751,CAD93A42FEA78C7F,1F6F9DEA78A15329,CE288AB24E6F520E,18EC936048C903D8,0024DF0C1B80A297,CB4ECFCE6D2303DE,EEED790A2F2CD0D3,9ACD1DF19E89985C,34EB9F34B5A63830,9A737273CB585379,D333152F6D58C716,DE57F02995834EE2,0013DE4BDE6246EA,DE0C1283208A1B93,B880F86A5514D9E8,E3D8B010B3AB7350,555A60A7BEBF3D65,837255E97A60EF8B,7797CB04AAB974B5,960371C2B645F16E,0039C31CB54BFA64,1BB8934414437596,2A5FE94996BB2A20,C5BB960C02A68E35,3E7A63FC6DC792E3,2D6CB1DC8FAFDDC0,AEB3405072F45CDA,0774F780B9AC0204,0009B70E10B4AA8E,9F895D2D8C14396D,B1E41D5F0643D386,A39EF56108001119,0FEE092E7A2F15C6,C9D828DEA464D964,0A48F9AFD56D7C78,F41232AFEE518FB7,002FA4C1D13ED278,3A482D84076D497B,87913A2950856E5A,CA6491EF13F40293,10DFFF16F54E8CB5,4ACCDA4658546FE5,B35A6FCCC34BB303,25E6BE3578124F80,0027BB2AA8DF0F3B,F07B7EEE822794CA,16D09FD67DD691DB,4C766A628150B7C4,74D3B79EBEFBCF02,359334600E2C747B,71445901D5277316,438AA81D7E8C67F1,000B0E647176E88F,BB8CFF498E827CD5,312FDE4A9E4BA6D6,FF3EF17B996D1862,9C23B90B9DC78DC2,014A3965C82CECD7,5EC34F79F03AA621,54C54923C3151A41,000723F1BAB2A0FD,168C4C88115E45D4,9C3A61BF34CE31A8,D4A10C959F5A1E21,87070D7BE7A9636F,36F9177FF030D4EF,B859CB20FA2BBD5C,9BA2D99CE04CFE94,00288B371F9BB831,DAD0C2BDFA52BB56,5301D60A8CABD921,A4646AF89434E79C,AF791DB1F1F853AD,BD7B3F343CAECC6B,07782066403C1CD2,C1CD94E29C13C8FD,0001116E57E97931,DC1307A6A18A3E24,77ADE03B708A4A0F,1AE297987C3CDAC7,33201081F439D9A1,0B76F341DAD5826A,8B32A8829BA05A65,827600F6161076FE,00392BFFDEE85EE8,BBA87FA386488D69,202C59F62D89887B,CC7F140D73EE04E3,6944A7800BE20C53,B3AB878CFF045831,4A4333CE87E67679,C8BC02CE12D3DDC5,000C092C271F674B,38C2552C60924EE1,3C2E455976F417B1,9DFECD3BD6918896,C45E88668C593E33,BA8C43C787E5307F,661E951F19BB558C,7C1A625F41F18C26,000D0FB1D71F7483,ABEB9A8F4A40FAF7,F5A5A0C7FE1E0010,F759A6C160BFB012,0256112857F3885B,22CE674C5C968947,BBB8ED8475DF701E,3F57E125B7957783,00117A5346825E93,B303664E8331A19C,9928A6A276E3EA46,E0E60BE2EABFD38B,8F3DA00C970584C9,3FD101DD5C6B6CDF,DF3904228B6F0FD7,283A8A2536888AF3,00250EFC0898DFA8,2CAA33276472A126,7D4B6A7A3D881BE5,63919B840464C310,2080363C93694890,2CF45A781F55513E,0A95C48271360FA9,3A36DD2AA3492C8B,002D491CDBADA6E5,A5FFE180704CC894,F464C038FC1695A8,9A94A47C6615F8B6,AF69B45923E25C83,F829FF55734469EE,6789EF8BCB25B7BF,6550D19286938F3D,00137FE71CA23489,22C0F73168BDBCAD,069681A22C84CA72,8C938B2555656C00,B6AC217ECF75178A,2E9935AAB218F561,21DA39985D3E23A3,7E3DF8F9E200D7DB,00123B5A8C12DA2A,1555482BCDC13DEF,37B9690E7D405D47,CDD9C2C02559EA20,418B1703B82A01C7,5BC2FA1DEB5511D9,E6D4FE59BA73C688,A3E12D7457D26CAF,0030B7CFFE411326,04AD803219AEA015,3B127AED74E9E6E2,A1B372DC9EA15C09,66104E6C7DF26B58,B0CE79CEAA320AF2,96AF9F8DD1AF658A,8137A8794E772FE0,0016F36E5CC82192,A248F9A712FC0334,FABC190A39DB8D58,6A02F0A7A4A35818,473967E98A1ADC3A,430DDB76CDEB9D9B,4F2EE227219D8B73,34F82CBF436DA16A,0035ABF270F9B859,0F3C5BE4290AD367,ED0365BD00803009,78560A61C5EFCAED,492093FE7B818F3E,70BDBE48D8841644,96635901DE8FD7B0,1A89B1784B12AA52,0025109649384628,2011DA342AABE4F5,382CDE111D8F56BD,2D9018C8ED7CDF3A,842BD9A95C4119E6,BABEBBA8BDA512FC,63764C8C023EE439,7B2CD5A52963D9B8,0005675588287901,364705CAC2B9E31F,963501D713DF38AD,BA575E9986DD6C80,FAA3E9DA370E4E12,E1EF838042543A94,E20081234EF456FD,14DAEAAF6EFD7D11,001EC2CE718A3EC2,D4771D5ECC381EA9,10A20021D425B7ED,E60FBB275A22C6CA,06732C6FD0836D17,0079B3EE79BAC2E4,6783645AD86DF950,A1EBED41E9A54BE1,002D1771D5777358,D5EEA9841C7BA200,8FAF2AC75417114E,FBA2266E67798488,8ED17ACBCF483CA5,B9034E006419C405,20CCDD4E5AF18868,5A79BFC89466B013,00273D781F6DC679,A58C50E6B57D8223,1DC2B7FC09D1AC0F,5F0A1690F731EAB1,73A3024D44F7E4C6,AD7ADB9CA9424E51,9C81A715ECDBA06B,5D17407821590129,00008F100FBEC8A6,66528367A9F40798,EC9E7778ED29211C,690D671E36B643F0,2A9F229689450856,A2B92585F1D8862F,C029B63C0755CC6F,6DD0BE9D437BEE07,00115CB39157EA4F,ED374F0AFC9ABD7F,D078941413D0F4EF,BDC4CD48B58A34A6,2B35D43376FF9510,72C7DCD49E00991F,01479364B573E5AC,3C061DF3ADBE3130,002AA23122F56111,99B2AE22BBCC28DA,BFEC81FFADC6EC30,E1401303CDF33BC0,E650107832288D09,2044562384E2F0BF,F02F2F05C83C075B,0C68724995FFD394,000A9E9D2B8C94BE,DB33B34A10888926,F2D0DA74613B1D1C,EF68956ECD83A03E,84518FA4351C56BB,328AAF3AB61BA04A,57FC7A343D5B74AF,A1C871D002F1BEEA,00348341CCA32194,7F5EC5B888B9F865,9E5C9E22D66CC5DE,6525CE2F727A1015,DB8325B20C320F36,F89EF08798378634,39E1D4A39E714E13,67357AF27E9F3CD6,0020348CFD0EFE4B,7C9241B464165481,15F85190C4F7D5E6,78B9C23B339FF7B6,39614CCE4CE2CE83,BFACB512355C8F8A,2F49FE11BA9C6809,7CDFD252F09C197C,00120E9EB6761AFC,BA5F153D0AB59BFF,9072CAD46A1E59BF,775D5DB04F989048,98DE6DAF455DD684,FC80EDF40678F837,C0472DBA504A75EB,D0C9588234AF4436,00369CCAFDA69382,139F6A61F2E4A98B,E332FE2085106157,BC57CAEE869F816D,6DEECC5DBB591660,02BD39864D3850D4,A7F9C7F7B1320CE0,EE1A72C0A1A8CC8B,002C9B648E485241,85F50F2868AF152A,8BBCC9945859D4FB,F60A234877AE9F3B,523530E9567B73F5,8C9A49760628D5F5,C93E1D8AF2DD7BEE,819178A8E7CEBDC2,0000B4A097CA258E,3612D264B4725676,5D7BAC06AE94B7C0,10AABA2A5F15FD79,A7BD19CBA25A6394,129864CCD972F4AC,FE3EB380055473D8,ACC358640642C937,000ADE6C3102BBDE,7356C641AB543BC8,FA35C706BD5B9D30,5BFB0B59C014402D,395188374158EC5B,743A219DFD2E63A4,0339759CDE854A98,9AB65D7F129B8934,000177622BDF2DAF,EF68F3A169AF128E,CB6CAA002759CFD8,DD7B7EA14732B81E,D5A5CD2735175146,59FC41486CFD5743,BA0706C64FD4C9D7,352770138259D369,000CC3EEB7F475AA,633B1A93CC9A599E,A0D8E8676E93D37A,442B24D022EF33AF,C7929F968F907A7C,7A0E256C43F4148A,ADF9C85830E93578,7FD8CCB35B764628,001A15602F5FFB28,19A4FA8B85928919,4B27C6942EB897BF,BDAB4D549F06CE93,6007D16CA5610221,8A59DE2796C40195,3762F014B088C4B4,29997AAB63EBB7B8,0000B4F034CDC3BD,30552236DB32D68D,FEC3C7B9ECD181FC,4E3590DF10CA8896,5C9CAB3B380B57D3,006B20E4ACC1A218,B580D9E8D4FFABDF,9C4743BD4086AF5F,000FD322D9F3FD84,AEE7ACF01B3EDCD3,DCCED786BA3AA8F7,5F5D3823DC8585D2,1D416CA9A3ABDF01,EA91AB88345237F0,852E19ABC77B57A9,F32CE825D352BA43,0020891B2ECB9492,FC621D9694F86FF8,B1BA185A3ABCA920,2184C4BE6BC533C1,6E695597FB6F2927,77B2AAF092E92F14,AFF1E40F88007EA0,3081ADEAB631F670,000C1EFF74E15585,48E51512BF3D46BA,24903B794C62D4F7,8D86469E68D9DF0B,2EC50BDD1338704D,E5572ABDAE3B8467,884398292EC3F8F9,7D84E7C31F8DC84E,0019A46DC94F19F3,E656202F676F6C40,CD8FC839052033A4,AB143FB3256F4C51,5A97FFCE66B1C257,2BF35CF67FAF9F07,17A8AE8B521B02F3,8DBFC8929D2EEE05,0020629FF9623D0E,93BD99E046E9911B,15B9DE0502C6E79B,EB42504C86C8303C,1B956670A4C32F65,1473DBC179311247,D60AFEED3B65B487,D5FC98D115B8DD15,003773E18AB36630,EB824734D2473888,8146C5DA08388822,8DFBC6CDE26325F4,ACED0DCE8ADEB80B,5F8469180FA11791,3E002FED2A4D7ADD,D018400BF0022613,0005B63BCFD85195,F9652105CACB8B73,CA5B4F88BB963C32,3FC224B1E5F5ADEA,30E94D86F8359FC9,CCAE232C6BB25801,2F984EF62E4C643C,09F1A9B03F550856,003056D862D0FF96,AA6FCA1A7DB3B9C1,8D12C496B3D530CE,909089D6DB66CE9F,026979B12182E911,D838DEA96EFB14F2,C70C12A9DB5E8DEB,BB4D79F4A6E1AEEA,002F6E7532C0487D,565D24EF17871BCA,5547441AA7195322,ACA179D99F24388F,F764EBCF575D78CF,6890A45614A3A134,0545AF60FF4DCA38,4730B86C7FC40E22,0025DC757FF39EDC,BF8E2EAE49386E91,B99940C92BD7882B,60C7FB2173F8D4DA,A764A666D970DBC8,BFF3C598783486B7,08431A95843DB6C8,3CC7639BF98D01AC,000CA9360BFA6359,AA6FCA1A7DB3B9C1,8D12C496B3D530CE,909089D6DB66CE9F,026979B12182E911,D838DEA96EFB14F2,C70C12A9DB5E8DEB,BB4D79F4A6E1AEEA,002F6E7532C0487D - -T_tate2_firststep_P = AEC40A3D269C8FEF,C901D47D0A3E4250,F92DBCF459BDCB5F,D1FCEC504243AC4E,035513B7F3D8DA9E,4BCF1E8DFB823BE0,B644A35C2747C746,001387681059CD8F,6A2A72A338B50096,8060F6343072AE2B,A41CAE35AE87535E,D1B133E259ECD08F,51410B1347F9CF32,2AFC37844B4AB202,BC46C5B8E68E0B83,0011FB79CDC2C0B8,4F5496068AC8BABB,2650DB615718D577,D0B19FC68436E291,243E6839C95A5B7A,300115D56D3DF938,5D16DD7EEE5A01ED,2EE0160F48638C9E,000C5AC73FE3B483,FBD0D3459E1F91EE,81858CC7C1478D5E,F96E35FDC26A7257,925AED6C82566ACD,FA2BA728C44C8FAA,E6F6402117FCA3C5,58A8F674A28C12BE,002BFFC6D4ED3CAA - -T_tate2_P = E15E54C7E1BF6AE1,BBE023A52C58B9BD,4773C7868E2AECDF,D0F31194C4F0F0A6,9B6996444464D978,0065E876D83C354F,DA6CBD8E40EF5ACF,0015CCA1A19B1051,EFDF6E4E6C0536E5,649BB3639B1EAC0C,C18DB1639A6E0FA3,6162920D5DF367D2,A709862B237844E9,C50C4249DB3BD4E8,E5D92B58A4AEA3BD,0029697FDB257476,3B872D3AD7E0BEDA,AAAC956261023780,70190ADB81D6FABC,4E1CE92ECBA70616,F500301D56BCEAC2,87051A2B36A943E6,D63B6735CBC97B42,001ACE03FE60013E,66AF64372C624662,F696F2290E102519,41F369211B7B7552,9A322E5A79C55355,C7D1D9FA4DE54101,717587C03144A77F,B32C380222BB1B21,00302D39CD6ED1E9,AEBB7B2EA3FCEECB,53D3CA97FC288CE1,7A398038449AA9B6,7CC60D7C50D8AE90,36973C257530E81E,F1C27F812B8AD4A4,1430510471B0B075,000FB3305F079FA7,6DAA239526566852,B2995FE00B68E765,8593F0492DE80A85,A5CA6D4055578C57,532E561A76D8257A,28EBED3231F7F11E,62D6F52397EF8068,00028E7267745552,468BBC2D95772E19,B2E1C62CA88A7120,EB10936312056DA3,806C9EF9B1561726,E72249A802556594,80ED06392AA902CB,4CE543889ED8364E,00027F87C1458480,69E441ECF8772463,9DF9DA550F8E6201,A53686138BB14EFD,B84A64E46493ACC7,CFCBB2003A302D56,5C02C10EC256DE4A,DC60F48476A2E8D4,00395CACD38AE3B5,B87F059172C6ED76,2932FDFCCE69E4D0,0B416F82BD24B0FA,B6DCCC6B4E8A9CFC,93701AF5335830AC,29F75A15087323B7,FF003D2F00D8D34E,003A26CEE191368C,F3EF2C0AFBA895B8,6D45204E9C4D19B9,28DBE2644D7528DA,38E371EE6E15EFDD,0127CECE338AB45A,13D4C7E1893B91F0,B962D4CCBAA4FAB0,0016D176542EDE88,42203947D6C06948,4BB905BF6EBB203F,2B7BE18BA628ACBE,72B234EEA79086C7,5160DCDBC5D7E8BF,2FD811B105ED10C8,F9DA215B8DFAC028,000F625997335100,FF17C2F57ABB9030,54DE338756C482A2,FA364465D449501F,9175FB41E0496DBE,166DF21B0335172A,19187B7174B5BF20,B0741C7C46FBABB1,0025BA7896023A07,FEFFC7D2AC702A6E,59CE9CBAD2F27073,113DA67315FC5E2E,D76BF86E8CA8DB50,0C9EB985911FC4FE,49069554D8B3C6DC,41A1C5BE8B94E11C,00257E4F254EDD01,ED61E2ED61F58EFC,41C3760267FBC88F,85CAE320285D4075,C6B780661903771B,94D0C0810B0F72EA,3DF026AAB87F4582,93F673FA15A9D880,000ACC3C203E7351,B42AEAC8F7D6E27B,BD6409E19C8019A6,AD50331C834B566D,0DAD3689BC01AB78,32C457DACF80DFF1,224F6C8340B17255,8841166DBB02149E,003F31ECF46340C0,F18441D4124FDE87,3350ED0247BC0F93,30C8FBAFA5DE4AE1,45753E34C9F8CAF7,63514595E095D04E,0C07ADE75971DE0C,7CAF53BC83C4FD5E,001B1752B7623A1E,54FF46192257CED6,401B2CB2E4EA9C35,FB92995B7BA05295,0333B487DC95D7D3,47F05B6B620CA279,BD79CB7931683638,65C0E17D2DDE2BF2,00204550CCA8F1A9,F0939C1464755345,719FAB828BD4584F,202ED13B395D9A6E,47A80BD43374AD35,4101CC3E3FD46C8E,E1B571BB2650968D,DEB1D79F1370DF78,000E5919C57A925D,541BEB354356A59E,EB6F34C2C221E394,59819227414959E0,048ED4FC8A982379,4F70CBED553F2465,2E9C67D2CEFFC9F0,9320E7440CECEBE3,00169264BC38A393,DDCDE127F7786D1B,B1547D524EE3F5B4,B7C90DE3E6C5A4CF,D120ACB3A8D1E78B,73109B5A0C8C81B6,43D3A78713601B46,6EA91624375C33D1,002275A20DD0F9B6,10DC9C67F752F6DD,D374D09CDE8D0636,E841BB01CBE857F9,8E6E1C3FC97617E8,0663386301E371F4,620AC2ECBCD0F210,B9FC4B559E6D1679,001A84D56A203C53,C3140AB54B0EA626,350A5021A22B7ED3,32FDC484C8A39896,05906F7BA27D83AC,F48EB70C4659CA80,FE18D249DDF54EEA,FF3932E4A2C9AB91,000B2BDCE81EAD63,7723EBFA12852698,35317D2737EDD95F,093118E00AFDAA29,BB8E773126124A98,BFCF8A04A71671EE,2583A77FFBC73C7D,C65A1506078DD6BF,003F591B9B315F78,8D96EC7B17C33B63,1629EF29EC637531,D29F473876086E9E,78AC820EA27CA6DA,65242C0BA614DFD9,9026FE6F40536C3F,EDC685E952B61740,00104B43844D672E,D90E6480A3D0338C,F27B240BC2B47195,0E7AB41432018AEF,02759024B28277E7,98839685CA190A0A,E01E8C369429D5D3,199E73C5E0764E75,000AE85D34F87FC5,8180BAECAD2D95ED,757F3E2E72B7223D,6A524E49C732A555,7F09CFE7F3ED8E79,E299410DDE3848AE,DBB6C0B3E9DC1A15,4E5A9E4381CDF2FA,000FA6C13B498AC6,0B94BC01EFFC7241,5934EB3D0742D36D,AB906E08DD6C95D8,7F754AE680FC9348,9B805513A2C4EB18,FE6E684DB6BE15C6,3D461BAECB444065,003E4589F0CF6657,FE9773AE0CCAB40C,8B8D4183DAC892D1,303ED6A006012B62,543FDF8863221EA2,685DE9BE01CB15E7,3BE65844FA2EC03C,5D0B380B54A6FBC6,00303761F84C8DFF,EB673F469BBEDC35,7D0EC3CEDBCFFF3F,9EC6E3E2F93A8327,F3C345078E0D035D,AB3010C3EB051645,78F1FA0B868103C5,CF970083593EF175,002837E8F43E261F,6C91AEFF22E99502,2BBF067C8577B4E7,813886523F7A19DE,8AD6CE1F64DB3007,447F06C6248A1604,D15AAAE2ED3A8A6A,284188CBDBAC1FD9,0010F5BF9DBDD49A,02DE4B9D7281CF59,86FE4C992432A428,1AB88AE7A8D8746B,1A99FC14E55D4E4F,821D34ED734EDAE9,3E82D47EAD64052D,152B70F4A4C31142,001E3B40AADE9355,DEB33E75EBA16598,870E35EE440FBAE7,CC95E3809C694B70,0D15B0620C34851C,176D52306FB9DF6F,D7544F9CC04DB893,E5C54205DAC38489,00039AEA9039DBDF,5E632A108F996BFA,92FBADF8465B9DB2,060A4C123D378619,2B659207E80244CF,CA891F118A2C6DAC,17FE4F9123B9EB3E,C4A161771F33CF44,0033EF5A1AE1046F,C85AAF1294CDA307,065D11275AC77D8B,57635D778C0C73A5,D7D10390AF4009D2,7D582C16FDF86FBE,DFDB7E204D69B52A,7F9C59F6F32EF670,001B9CD228B30FD9,849CAEE5B64618A1,ADA0CC1A2AFE278C,271E9E0BC8C529A3,56B4B88631584390,C7B8A2E97FD23384,8A867C6CD1CDF122,A1E040315001939E,001115280F06D680,889F9CFF478EA3DD,F3F7DB1DD1560A57,F5385C325AD9CAE6,7B5A9E3A75AC080F,13A9E90AD8AED44E,FED2A810E4107104,E8D41A737013F7D4,00020E4C39F6CC64,E9904305CC595E34,507F09FC05DF37EC,97A2F0F6FCFE8C65,48B1DEC2DF99EF7F,324DB7D20FEFF200,251B93E5BE3289D1,1E4BCB0F76D46990,00006EDA6544800B,87ABE04F21799F76,586EFEF9668222B0,24775AE96B7037A4,C258BE372CCE4A38,D9C3095AE569CA30,0E30215E52505725,4BA4B200836908EE,002F34302EF50069,310D621E763EA8E4,0C92C91BE090E8C8,0EC8DD22CAE76FB5,488DD1B3BD41D333,575497A1A831A87B,50EC8D089E052F08,68785FE21F65CE62,001262611643A70E,D67EAE4E3AB857A7,91639AF3C8C29F48,6BCDAA1A21766E22,092ACB50A9975B0F,315D02C1FEF39292,20339A54ABA9E617,260B0731D09F6ACB,0037BE90DC4F7F3F,8F6C0F39DA552D29,C4E0086C6F8C80AF,1FF987B1B86CE823,6C5C71902AF53C2D,7CB079F196C16E60,219A5151D6FFB82E,28D64BC13CB33BD2,003452B8CEA83BB9,D6FF821611B5FD65,144CE60B9276A018,D47D0E63C446EDB0,4223B159E842AD2E,9CE454751716C62D,9DCF891A01AAC92F,6724E360983BD4AB,003B37F451E0D6E9,FACD8B86FA8B137E,ECAC0BE18758CAB9,BA2AC92C2572D425,456822CEB3283C44,7A878245CFE53484,2D62B5F87C4899C0,A6E98590D1272A38,003A52454D4249AD,DBC848601A0791F1,CEB0065C762FEF8E,F2451336AC6799FC,F8FCB990E31D7492,13B3CB6FCEA44880,E02B631B7456106D,62B639F0060849FA,0009ADC921562F53,BFBBC4DF6675B9F2,D9379144D814054C,94CBCA854735579E,236F9627EC96ABB3,04818C7FF99776B7,3993C9E101455D94,89C857AB0567527B,003A5036D0CDD8F0,A33E79AE1656CEE3,7F8F1B3434BC4DDD,6A02BE414DDFA33E,714356967D6097E2,23A1382ED992137B,4F40C1B5A4585691,033CAF0976FBF0DF,00133F1C70B83FEB,3E91788733CC5B43,165C46263733442D,AD299E1F93206265,319F365A617E23C3,818B6BD9ECAE4A85,D2D5D5F4E64E703A,84180A49DB9B52B2,0028EF11107B4ADC,1816EA6F7DD5D905,BFFD911E5786321B,0187586B385F2734,B7CA2C270951767A,87973C7AC63BF3AD,04203CEC917374C1,C14FC8B581BBCEFC,00359273D1E2F4FF,4152CB2B3B9035BF,131FDF048B615D0A,8F7AD400B0CFF723,9D3A1BD3A72238C8,C6DC85208FEEA1F3,D560291C734A5162,51407ADE12CD6851,00211BB2B2891D1A,46F800DAF49F684F,DDF22A0EE8CABC46,84F774F985A783A0,BE87DFBA08E66FA3,7063A91201CC8CB5,C48B8C7BB485A907,94C5F972E099FA08,0018E62F73A80483,3213BE39284D40E6,1FFC79E5FF4B1A5C,5A91C034AED14245,DFA9B90D6B118AE3,3C0ED8A6DE8CD1E7,42FFFC53949D5C0D,258B96C5A3C3822A,003EC8DDFD03CED5,83FAEBDDA5C88734,A8B47010D69ED425,04BCE8A14837B051,7C51342145047001,FEECD3EAD16E7AC6,3EE9A6A0519E16A0,E142A6CF99DD3AB1,002F079B3BEC373D,956B2E9BBF478D59,BCF2D626AB3797C5,C5834AE64018F932,A914C8A81932F04D,073229B82BBE1BD2,9BFB1A8A157C1FAD,9942526833652554,000FA4625CFF34C2,F27D62BA5A1731B3,BADFF72944406F4A,392960619027CAB6,717EE528CD74B5B3,E6D9E3EC243BF4E1,28160ADBC6D175F1,E2865DDE5C797E28,000A7373F66DE3B3,36D03CEBE4E1CDC4,C6BEA54EA88E200D,D71230B52B5D82BD,0D0A9774D3B37788,0B88FAEDA5571323,8ED9CBC649051D0E,1FED65548E8A4337,001CB797673853AA,0A6751C6F876F04E,108601D3F1B72BB2,FEAEEB2D679A5CD0,4513EBDB13698C77,2FDFB60BF3E2E893,07AA37B447FE4217,C4B18B2E08F5F1CA,000A400A7612DDD3,8AAAC129351CBBA2,CC4390400D2FE639,2F32ED48680981EF,9F31DCE6BF5B4164,B2F3AC0DBED4BE9A,32D9489DA5695353,27BD4101C01B9B5B,000AEA3F9AF37220,DF7338596A4E2B3C,1AC6DB70F8CF65FA,4CD79495251056C7,D40F950AB9DD3E36,66A40EE40E80A95D,679402CCE935A2CD,CF70141A0DD2E2C9,0015B8E927919692,B114D9AE1E573752,7A2DBB1F04A84931,1F989C0BF842B410,32085221C82EA7FE,DDB8F7A4B49D7201,AF19F5C4C29654F8,52CCF6091B39E2CD,001DC3DAC528FD88,CC7E8F4827519CE9,12F67A7448C6A5F4,16F8592A4DC66D29,F3D782324C8911EA,EB69742D1EF820E9,44FBF37D76339341,56EDE23E1D651C70,003E1CDF5D587F29,B2540DAAFCA7BB0E,676CA56F50BCE9B6,62E8E52B0DB623E7,FCA468DCDAA7151B,0E6CD39D3079C507,BFFB5DE1194FD0EF,DB3D4A80CFB082AC,003C232D628C1C41,5CFB507A64F34472,08772DD96709CF6F,1D37987A27D119F9,55D92807FAF5C8DA,72397049759A1C66,9FAFA2D6344407E1,D27688D2DE227DE3,00059920D3E74886,97C3A450EFDD5644,1B0EDDF4316E7745,1B30857182EB9E21,44D9EABE59EEFC8F,269DD1068D1AFB84,36A95CA13A0F265A,D7BA5164063A174E,001552A5B5623792,6AA389C51391C407,D32045124398A546,20B391A2904AE4F3,F6F9E172E2D59396,1C9F427015702046,3C20155E8BE7F4D0,BA4E0BB1D775FAEA,000969ED3A94D3E3,B0B9595C63053F12,8694AAAB6C883F2C,486D16EB0E2993D1,9B0E912DBD00B762,E997B33C1F31A86B,BD9BC01FAE072AE3,52B1D3F553D2ED1A,00119901EBC7A2CD,4A7032DB2FE27812,2DF7D761874FE0F2,5288DB5A31D512F5,68419039A867117B,8220FFD3CEC44441,36600B384C3FE84A,DEDD163EDEFEA511,001CE3914065ECD3,E610C902ABD9F401,CB8C72A0DC3E37D7,C1856C4CABD81FEE,81C3230DC9BB28EF,9719B2F553C43F87,89EAD288A7FB01FA,BDCE513C2533BA0F,002301BA86ED7825,762E7575A0D2A9A4,9AFC4C46C35C94C1,6EC43D1F6FE55353,46E57EA6D4A86E22,C51FAB60616652DC,9AB82485F0A6C1BE,4C823774DE388C50,0026E48A6A566ABF,4B04A18CC099E246,76080DC94C4FABBC,1FE3AD0CC0F68E68,4679281BC8AC9DCD,F29BE43CC477DE19,B478861192B3A794,2256BC93F2C18675,000C6483918290BA,52A5B388F2D9FD7B,79FDB3D411915E17,638831F88CEFC1BB,5404C711889B09C7,79306BEA8B2785BF,C87D50FFA7B20E3D,F4F09B6E73217D89,00301D4A88077E69,495CE7EEF6651DDF,4AD146F6A1DD0514,A6D71DA371F4FACD,5E1F030208F31137,7F2A2BA105FF2BA9,6BA81F626D458DC3,64BC5AC82C3E4CC0,00201DAC09086D0F,0F650B396D80B657,1961BA17C230CC85,DEF993F730D532E5,61B87BA1DC3F1633,97F4F4D62307426C,3D7A628500720BBC,CF34E2AAD783AE93,00145B6E2C5E5D7F,05CAC2CD9C7CBBE5,2E9212384B395B8A,43F4AA182DEEA632,307BA3B9D4328369,4DB6BF665713A8DE,856A33D03FC29792,8F3BB83B58D4E9A1,00123394C675DED3,1EE7E1F53D6E7FBE,68AD4DBE5DCE279C,B945CA7C44367D1E,017EEAE4DA317AAF,2B69941DFCD71192,AB30146C70480D6F,895968AF05E92926,0034C92981650879,1D1F6E2DBBBD8B7E,13ECBF82BE40B24B,93360FF31FC39808,E7FF2E9E5FD8E043,8F19FD421FDD889D,45FBAC4DFCD83546,EA2FB0EAFA297309,002A6B8E24B5B3F0,77F9241A9436EEC6,69981DF53C49A79F,6E63EBE9788457FB,AE2B4DB2C189C5BD,90092AD0B0C3EA6B,BBC062648F35F5BC,763D8691BC0CFA09,002403E63718804D,4311ABAEE62E190D,0D08A36C8B80479D,1926D43E2F444099,4B4BC4359465CCBA,A686D1A41658F311,4853A02FF6C75205,AB5F53C78968B988,00018BB67AE65C11,01B000BCE2F11609,A570C261EC0AF32C,E28F2976B5380636,CC99FBDB77E4BF96,113C5D872E18A5F7,360A43B0819EB9E2,D96C7DA474598FC4,0001626B66057B97,B8563BD292A896C5,81129A39C6A7D2A3,27B814B5A97F5A23,9EC5E14159228D11,E0C4A7B1930A6E09,45ECB44566149678,6DE9D1BF1CABC348,0022AD297167C2DB,0149C8E3D0CABCD6,62629728B05E89C6,2076DD22DC67C44A,A521DA6FC805B3FB,EEABBBF6D6DA98D3,88C357F59322F3DF,F1B11EE288CB78C6,0023E1E062C90BAC,5FE0C3677E102F59,CB9E91B9B485E258,DB520CD6B03A5918,DA3B935BC402E781,E48EF11324602F60,F8D92EC2D547CDFC,C6571885EBED4412,0037EC9537E9EBA3,753A09FC8839D5F6,A25E3F1BB529391B,CBF43AE24C5D94FF,01D743BF8801C1FC,DA03A0F9074837BF,B39C11E79DD3DD6B,B46A9F2A73D47B9E,0037085E6B1C2B05,DB585B6D51E8BB20,B348CFA5B6AE6CE5,6264A6A377FFECAB,BBFF59A4002F02F3,68919F4F8760F666,0EDB65A42C1F304B,49438D7668639614,0017EE0B97A917F5,81B03047FB598976,A7C01AD1F0255375,C44C96AA67036FF1,61B87725A8961425,A9FFFB31E306D58F,56FD645EE9DBB332,70421BCE60C758BC,0038BF93E49983FA,2D7124EA20C07D22,1E29FB38CB7B2BEE,04619A7484953F93,82D466BCD1D5F35A,9DB1B24D41AC6C33,AD6E4B4A6C73F352,667435427F735D41,00343595D726E6D7,160B35F56C89962B,9909B0AB08082161,AADB69721D23ABC7,B8DBE63ABF7D0CD9,F18A044227967527,28FEEB07C26E8451,1BE676B434142898,0015E13C9A9155D3,6BD85874F92438B4,F2723457DD508A44,371536736E6358C3,253F51728DAA9826,EF2FA5DA0789A739,2A92F5B345DF00F9,6542B521D05B4A02,0020559BD14F7FD1,82185850CC1359D3,257861722354AE31,607266F198128E37,D7AC10BB0C1D73AA,CD1C4B71A532C6D8,70940D2A86DEFFA5,A04E30CB4347F1CE,000E400435A31FB5,CD5D020E5971E710,9C22F4EC0975F5ED,700CF6430CA49C4C,CC9C085C7694748B,EE74046E36FAF419,859FCDA965E9CBF9,817C06D6B96E8C44,001CE18195B9B150,872F220B45E1517B,9BB13DBC8A8BEAF5,83AA179D67FCCE69,05DFD09C9D9B0163,2E49453C9AD8A92E,D35893652A6CB03B,9F6F915C96F67340,001CE8B942559488,1E40B4031BA11040,11C692A0FB30D0D0,AE85A0AACBA17FF9,9229506BC50C6667,CF2B4EF5CC02659E,85058364F87C06DE,06F64EEE980BD72E,001AC08BFF96C668,98FB8AF06EDA28A8,2D7E9966ACAB33C8,32FEBE1800EC97AB,840844EEFAEE36FE,F1520F5DDC45AFB9,D10232D7F8A28B9F,C3D5B5FF528C4C35,003BC214DDC8CE6E,6E63CA49B72C5481,93D6E6D8F839ABB9,2459B7F8BB271481,FBCAB3432E61992C,8181E19C5AC9DB79,4744B3E55A09994A,ED1A2CB9B94EDA25,000DCE875CEFB207,E390E3D54636C3F8,E32B620DF9129F74,C977B814367D5700,65736890571C7E15,8B887F7009B8A4E6,6923546D54BFF93A,903F63CD8D1373BE,003851D78145EDCB,218AA4DC0DB9FC7D,27A8C3E713BEB39A,FE642B5152FBA4E6,356EC40E041BBC52,94EA15D83F606740,ABD2CBD693F794C0,EE939DC82F5746C6,00338E9E17F23459,A2DC782DB6810FCC,3855ADE1D0D9C960,68D3D891E0F98BD0,9591A938689F62BE,EABD1F96F58E7560,FA3C2BA434C45902,05071F0DB0894FAD,003CC94F2CA75E1C,7E89D1EA46AEDFD3,393362B309C188ED,B7A2F0B9D06EB654,947BA8D1BD29BF55,D62994A6D5041EB1,0A5C6F33EB38E60A,3D5CD16D1EA08B97,0033C23BD00E2B42,2BE4AF8BD8AAC626,A98EE98A635CF49B,1DD040DFE75C4EEB,F1AFFF1F694ADDD2,1E8DC2C1E27ADB67,3B5DD4549EB6EAE9,F3387C6C527F3AB1,000EA2FD90406352,FE95CC1DFE359598,FD15BF736377BD96,767CDFEEF44BB98E,B51BD24ECD64AE89,4FBD16D690366847,8208205C7235818C,CF558DE3B533B5BA,003EC45B61C40682,082ED41F535F5DCF,9CAE0E399C60A870,F5BA4D9040284CD5,CA928392C7176516,03B4DC02C85BA894,EE4BC7F376020942,55983D1D1572AAD6,003135EF4EACD55F,443FDC940FC1C1B1,4A27D17F6B6F08D8,FC2BE80DE00041A8,0B9EA2010E52CF44,90C95AFC4E86E587,EC9CA5E00FB00849,A97D93F9A5FD9623,000AFC514256658C,2811B0FAF4BEBC16,B062E29B3DFCF34A,09FC3A1951CA10A7,DD238DF1EAD1F195,30B8A7EF25562873,501D0D67F6996AD7,C0F57C4364EC44A9,001C9E04C96B256E,36A7D72BDEAED1D1,D747EDBD6F55AE30,EC6D22B21F4D5733,C4A0B31294C2BA8B,0561E14E0E9C8F3B,285FDED248A90E6D,5EF0C645F1C8EA52,00190D09CF3F289C,12A4E02E2091093F,736D7C1A6494F445,76AC3105FB3B2537,3160CB8480658858,025DB50C2D2233B2,F1581F64960B2E5D,9BC16FD6A9F7BB7D,000C0A554ED62609,A55E423C981C3B76,8E304EB581B14CE1,D6240E408C69BBF7,2F45F87C8DA9A94D,97D36F3D5A0C4A56,AE801A640665C2E6,1266112C7CC8CF3B,001B5EB981592644,78CDA75C350801B3,347ED587D902D626,D6F050D8FDB2341A,D44E049B2E765159,37397373DB20754A,F0ED3EF252A86A15,D76B1B95C710A4F7,00364CC94E8C2F22,03596A6F0E707100,8A27AA45D651E670,2FFD38248B7389EA,7C4568D366D193A1,F03D42F6574AB53C,3147794742B515AC,A957391D641F3FDF,00328D7A746F741B,F281EAF771CE3BBF,31DFA809CA99293B,C52661190104DF2B,660C3F657469D13D,B65F7C920DCFA215,568DBF4C71A1B345,FD3204D2B8783C67,0023EEDA7E07EDDD,D3BFB116CD648BF2,8E8AA8A50F62AD2D,94D456D5DA3DF884,93287F883C7C5967,74307ADB060C49C8,78ED403315EC0E76,8EF9833CD9B40496,003D84ADFC064BDA,CA0473503BC5D8BC,69481E6D96B09976,5FD98AB4F1BD6874,F965AE874A229F61,853E44FF19B8913C,66F813B77CF43403,8BCC1D1004B46156,001DB6DA3997A389,1BA49B84A2360013,96108230853F9FD7,A4773403896C2C46,2C135E355C626359,934BEB2928C3B0EB,BE24A39D1BD7D517,712498F51A52E046,0016CD507306036F,3FE0BA9EA88F385E,ECA60F9D5ACD8416,1B53EA963D78079A,3A45D648AEA6DB42,DDCAAC3B82F45B39,46C41A59E7B376CC,5DD58BE7F91D7544,000715567DEDB714,D031BA6A08A73F73,C82F6160CB9CF87C,0B87262E81795D25,85938E733BAD1040,2E62937354887218,599F8C25F7B51FE7,02241698BC0370DF,000804756F6D0FA1,9FB0E9EE78E81259,03B5FC08B66AB41B,7EC0FF818A9DABB7,BA326B3312B12B68,109AF1E858B36289,1AE23F90915F324C,AE05AA834AD40351,0016628C042A5B8C,0985FA2DC1E7E3DA,08200B81FB2E1786,CE225965133F761C,8E4E90A1CB89B74C,AF9EAF10ABF734C6,510A17FA63AC9233,2F813D5D014A6037,003CE8056925AB5B,067FBBFD0F32346E,3998C57A9DBF2707,47B01AA9F0063AA9,3D66DD85AED3CB8C,B21A04E07EEE7EF3,86CBAE119C5F4D9F,D34D89396D290024,00069D5FE9448FBA,588FA04152FD8DEA,A0EC43D32CFA3D5C,58A0A6D9202F2A3B,A9B52BDC3DD7661B,445EE286559E3CD6,E7387CED34280421,628424B3E9BE907D,0018080708A86DE3,0AE9EC38F35A1C39,6E21736E3C0D2C4E,1E89269138714042,6E9078C8B9E48D58,6C436B4D2A382C18,76AA5CB0526015AD,FF5E69D5D4019A40,002307D42C748891,B3D07C9685B6A7B3,AC21608E7A0C7FA3,2685223CDF1758CA,9A0E49FF9DE20AF1,0B95B2D8847EF092,4AE9FA57F194F57D,C46ADAD750E9C3C9,00082C3D8B5CE907,BE816C02A2A87A3E,F9A5C69723FAA8E8,2578DE91B8621DFA,077193D13AF0D598,A3566AFBFF8FC467,8BE86A92B7742948,13682A9897FD7FC8,0029A4145E97FA49,52908E9F956107EA,F2E49041F1C0FFFF,AE33F68C3007E5DE,52953374C04D561C,603AA3242AEB7450,DB043FC6213A5A12,4160CFAB80B31953,000C2718C3AC9416,B66A94FBB5B38F4D,D3F0CB8F7C3E5B8F,A1DC688A34C83910,2D04B84A1B5FF97E,2674DF73420038D3,5CB78A084D76A274,318176E08D68CB5B,00029ED0B89D996C,611E79BC9183124B,6056727D81C3DF63,2ED313BBE9542BA7,79EDBCFBE7E4C062,5B05D6BD11AF3410,3108A72049A2948E,26D332200F9FB993,001328AAA86DB6E3,528FBD5B169629C6,57A20D686A65D97D,AE83D365BB968D45,418C02ADA7D4EB85,3F5105FF4F15A487,EB54855EE15EA581,759E6301EEED716C,00022BD32A8F7CDB,1F1351330072166A,2BF306595B82D5C3,7D43BD9968AAD500,CEDD8D3FFAB1B639,A7D7AB9EB2C03107,E5C407984EB295AE,593B4FF379760D8B,003F51D692562785,0729CA6DF3FA4BAE,1FB9C0D5743D7668,2A3EEC327F2ADD99,A3A52CDC3A5F8B62,FBABCDD5C8D2557D,64B16AEA4DEFB52F,3B8FC096BFE8AC40,0016236A4C589A53,8A2E5EC172E9C170,219FEF82F25D72F8,A403166AC76A7F62,6EE3F59EA8EF3314,8C7B09BC5ED01A88,F5613504A72F78BC,ED8D17386DCE6B8E,0021A2CDEFE67596,038CECAC2EB77501,3BE9039792F03738,7DFCB84F30CF23F6,872750E933F5FF37,DF2C37A38D99B9D4,072E30703969E56D,6F7E628A85AF4B97,0000BCA9837E9033,43DB5D20516228A2,177990A4381AB2AD,242A6B0C78988212,EBAB83DF0233E2C5,4A4D0FD40C2E6092,ED5FDE82CB4D804D,EC185E7000B45FAE,003D009757A170A9,AC43AA305C215CC3,CD0622354629A632,93DFA85E74B94F32,8A962BE21215EF44,99662178FA11BC50,B0BE0407FCB49092,889A4967AEFDADD3,0013829784210139,9DBCC27BBFC2EEE7,4774F22F86AAEFBC,F8923F74C162EAE3,E4DEF5A1FC457821,E67F54873C3C8C03,F9B0D61F6E628028,42ECFE0C50E46AF5,0013ACE11C040DDC,65D8DEDB0D111B87,611C2E8367B42915,218A3E7FD40F0AE6,39B2962B8BE62772,8CBFDA8969E1158E,662EFCCF653E3B6F,824C2188E027ED00,000ED302771EF5B7,8F4B5430AD6F11EF,EF67A3FA02F9E76C,DFAEC2490174960C,96E999BE4D685FAA,57A6DC959DE29CB2,32C2B3E4863BE0F0,8CA031FC7A21A579,001809F776CA5D8B,26485D859A95C4C2,0455A084B646D986,03449C07F5643FE6,F586B1D959CED014,376F7EA38E652951,E8B657EADB1F3C9C,52BFD68E514F21ED,003FBFE275B0CC97,58FB7630BF5B5194,F87CA05355877253,AA6C0E4EDEF8FD1D,863C836B48CB9221,1E472A2AFCAA3733,A594747D5922A46C,B5F9B483834970E6,001AA5C4D5D7E6F4,2410B2B21C63FB7A,EEC17F2A80663588,DAF59543F5C94111,747C1E10205E4CFF,0358ACD8B17D5CDD,68AD77E60926AFC5,4FF02EFDE6E7FB41,003CA5F91BA46963,4A0A2D13319FD9E1,5F191D55D603B0E7,5A3CC3FAE7E4EFC6,262F99E45FCFD36C,751747A7FFE4D461,BCF6013A602512B4,7732762AD8718D0C,00043C05055C4040,F969E43051024A24,67047A9CFE6F25BB,432BD9D818405CBD,BEA10A26F7E2D9A6,12A86AE92A6E44ED,DB77471C5668AD8D,2AFAA849C0850D56,003BA3E5735369B4,F196DCF857A46266,4AEA54F61910095C,A0E514D12434EF4C,3AE1D702886D0E58,58D592A6E5A15CAF,53637942960B1602,77B1E598884B145A,000FE4123C179AB0,6E031CCE157FBBDF,5C62C3853B57B7F3,F810D0EED932C8EE,FA718EDA9EF5AC90,E01758DDB86BA9B4,73152CF3D3B14DF0,7F3C332DB4E1F7BF,00113925A42557BD,2C3F3226B64ED7A0,5E46767069DC78B1,076D7D858C82553A,C578585FAFBF8829,C4AF7F5F917AB0A1,ADDABFBB49166E05,570CCA9F7F1ECF8D,0009AAF0B72FC176,66F5B1B46FC61515,09AC45CD87048435,1ED32B0517DA32CA,B7D89EFDC2F1159F,60899C821192DA99,58CC71E0B6FA66B8,8DD97F2F519BB849,002839939AB648D8,8D1B406FC8821E3D,67380B65B6A68CDA,3F33EBBF38F76AAA,08EA52F24C03EB1C,C352A28290FE3599,F71853D4A8694B94,CA76A2C33C713C40,000B25CE6889FF43,F1537FD35F6E7001,07620088A2042B58,6118E4C5686A6A12,4DF376A8048EBEB9,1E07E0144E078E53,15F677D3A9F751D9,A766BC8D60427B58,0001BC0E8A5F2F8A,445CD213700B3F53,BF4106E02FD650F0,96787A1F3A43D3F9,C6354C834F07B2B1,6709F5BC3A18B669,42184F01DD778956,27ACB7F7DB7462F7,0016EE8D2691FEBB,1016C5BC129AF021,7862A3CDD0D42E9B,BE79EEC8A2DB3754,CF99EF1CDBD76919,F209DDFABCE7837B,C403873786ECF677,522B6511C9A5DCF7,003AE45CCA47C28C,FE5835813DE829FD,4EB1117A65A7C5CB,0D5AB05EADF2E65B,DF18B1944E41A01F,98F97BDA5982F2E4,FB673FC2DF351C65,1C9EB4785F3B3B8A,0000AFE45A09DD10,64426306459B33E9,FDE29D02EDB57EC1,3D64AD7AEC85AAE9,3A1D2511601F5B45,1B3DB1D49DBFD531,F8A188BA285F2A90,3C0F5F4DC03B4115,00226255E962EF03,9AA3C4407576C123,512EA53E7C6FC456,0A1351CCE4003F5C,967BC4A430BD7038,9F28235798A62270,ED89CBE2A38729CB,0BC3C774852BBD71,001F30EA53BE1086,EB34A27AA9A21FC9,B202067C251D52F8,C07DEBD8C1382586,32B4A5850A0ED30F,D1FC718AD2336508,846C37C5FFC85DFB,E2ECB8D2219D93DB,004062F9B9695F93,A3FBBF4D4C9AEC49,2F7C8FA851E557E1,730733E2A55F9801,20DA307FB48DA311,6B9EBB914F70F2CE,DA2AAD961299383E,5C7FAED8A78D578A,0024E466E8D85565,C30F4C1DB7354111,9C2DDBAE016193AA,05BDB8F2BA480640,EDAB72FDA7E7E82F,4A46006DBE03D066,175C1F11B4B9DD2E,B8C6849A519F4139,001147E475B81ABD,21B9379945BE8803,FF699B7C88DFE454,218A05E55712F9F5,0C6D2ACC31AB7708,0537EF1DC31C359F,977BF8A449650F04,CC1C097923490BB9,003D456333FF3EFC,96E2FB0DA73E42B9,AD22B8AF384022C5,0FBD6FA9AF07A2CF,C0D877166E946ECE,7A9A79EB2F7E42C9,E4199D86BBBFC94C,06A860303563FDB5,000F8EBAEB95FA58,EC74B106FEA91E7A,1CED984B09196619,399D4D0EC4F9415E,F1348A79E03F5484,63B61EF9EA233738,0F08208B72466855,26E3BCE8B7346096,003C5D766DD45590,EC896B68C4525E86,80C618226A79E114,E77276D58904D650,001A9AAF2865A00B,50434FB27D65D0D1,F0233E004A334C3D,22AAD6128ECAB338,0013F5C83C455F87,394457CF3B28A483,BE3A3E1957E83557,D9EC07064C5E4CF4,5F0F48A4FA242C7D,BC0044EED1D55438,F3C4EEFB99BC8321,378165DDE24BEBFB,001BD0FF72669D8D,2652D510518CCDB1,7F30A7A1376DA6AE,8400ED8291F6135D,EDDB591AB2A1FE72,DF168BF350389527,B33E547FAB4F3A55,46E5C3D26CD5EFD1,0019622E520C3408,32F4A0D813DE88B4,CC08E39051398E78,31BED6F52409BBFE,7F19A72024F48C00,8C45FA1F7CF19D18,A451387B7958387A,861AA1734AF12D8B,000017974879ACD1,3CDD34D472068428,114200B168AFE2A6,C749AD7EF04D1979,2CB4FA2DCCB844F7,C479440B0ED91275,BB2B43DD0EC882AF,3CD3CD79B5F7DD10,0018EA3568D098F1,F4405D11747FC790,5AFBBEBF8A39D33C,D6443DD814E50CB7,4EFC7C6B29077E84,D69E231A5DF05A85,14A9EC2061E830D8,1C87197292C42668,00077093219353AC,4B06C5D382CD8C74,E598EB9A3A63D6DE,F6538B318B1FC3E4,134233848960E735,DE76D93555719746,DBEEEA29B57771FA,09E8D162C605221C,000B76EED7F68D15,E9709C347421ACC7,0FF8A665A69AE901,BBF900637A1A958D,9EB5CA16F3AE6C2A,BB8AD0BE63BE8296,99EE2799755A7D87,DF7FFA3606FA57F1,0011426FCC5F2482,04218FA2C06E9E11,5F50F40ECBD7D7F8,9FEBAF1ACBA74B9E,6F24A108F1665D78,D303C647CD295CB5,7BC99C5BCBD783F2,5B9F082EA00C57FD,002D823EC008ACDF,88BED526A0FD39B5,08DE7E3C68EE558C,ED625E1609B43ABB,5EBA4CD902BB31D5,FF5C76049FCD3871,AA81207217CD27A8,1E910819FE8CC85E,000F2CFDC5B10392,EBD9AE86EB1F8CAD,3E5B64237FC06EA8,61E23223DF1674C8,A71ABFFD98E81293,357CC37F397A708E,77C4FD5333802ACA,DC5FAB7D3C53FE14,001E9EED706827D0,9F79450961A79883,6BCD7BD744E57FCC,73071B35CBBCDA95,72D87F9035F14991,C6CFA8F16DB4EA13,41596EDD6A2C1E2C,AE43A24295AF21BE,0023419687C95FC2,47AB376E32A026A8,C5B6E1B6866EDE86,505723346543991A,86E68F313CA5B8D3,08A48859140DCEA6,059A4642F5107241,F21B40E7AC935A0D,00357BB28C2DB97B,B5194365A4667E73,97D56E5D0432E095,24B15E85E157DA1E,32DA1413D58DB9EF,8C660CA13D51471B,B7EE3E440F7AB651,9E9BAF677AAA783A,002C8073B46B7CCF,8F0B6BBBEB178709,BD2B2A89826C7914,1237F6EF2A2933B7,1FB6EE2604D21D76,A2FE14BB2BCE1037,7777E815467A58F8,A6C7189D8FE0C8B2,0026D6DB4C0DAD72,CF2CB78A4F1147B6,1425F0EBC74956FF,36239BB3EA80FC4A,FC87113B6548C4AB,19ECA6360D8544C8,8F6590C10243F227,2120229F060089F1,002A5E099782D628,9B77FA7E0386FD34,58AAD06E1AE3F7B6,27A020E1AE993F74,E8F028A00876F20A,1B0F9C447AB16397,8AFC8632754EF5D8,C6749EBA6214BC7F,00198464EA582EF6,D22FF5474D6F810E,AA24898E0F87EEE5,E6ACD8B4EC7A7947,A540D39D2530EF82,FB980F7076447830,1707916A3FDA9DD4,8B0A5E1CA8379DFC,00323599C1FC2029,5B31D30B812E4F9C,21143093A1CEAF1F,A599D0C828AEA55B,86DE486BB3EAAB8B,D6BF9F80442C9874,30865A2E54022C19,9744309568955456,000B63C4069F1FD2,0D11493DB7CD53E5,E6BE663EA19B3260,CC218EC9DFB2D178,ADEC42BC73CC2E8B,3EF34E8FBE7D1346,07858841E1E9E649,D56956BFC6BE418F,000BB4CEC9BDDC3D,17B84551DB5E12E3,85DB6075C73EC9DF,F3910055E9F1A579,E5F8D5E21F943AF4,790FD12B89FC6D9D,2F7FA0C6572A7973,9A1B7DFF14B2138D,001BDA74EAFEBDFB,46C13FF3CEDA6107,EAF7CE455D608666,9BC5502463C8E971,5C419429346ABD3C,514FA532B365AB38,0FAB2866BD9CAD1E,D12651917EFE6B81,0003DB10AAFA0A28,049B46048A9A30FE,FE4A653E910E30F3,74C064A23E853C83,C34A8FF1BA3CBA33,6BD750B58E37B89D,875B14E38B8FCC3E,EAB3BC1414348F1C,0030946CCBF77B3D,A0D175E5A5782052,9A068C4F35A1A7CE,CB8309BA5337AF3A,5B2E9EEAD2B5CB94,1E4F7D07B1C0B77B,B5BFCE2242DA5A62,02433398C31DC947,00333B41AF4B060E,1A06EB10E46624B5,FAB66C4BDC59C0A3,C3313AB573CB525C,448079A83C6AEE77,70923A737239A8EA,C1AA445EA76400CC,8C014D9FD52FA767,00303F3DCF1C7018,CB0B4730E1A9A55B,95EE6FBF60827D93,2826EC6911228A7D,D4BBAA4AF3121005,D1ABE0EBC7760554,9072032FFF2D4A25,A9975ADBE0A75344,00332E390C9629FD,36D165E34533AB04,FBF63BCC5EE32A4F,8BC3D8B917C6C11D,81018D8FC5BA059C,3F38962A9B85AE9D,BB99351ACE0953F5,1D63AE6B1C6A057C,002425EB7B9400E8,3165D1C273B60ACB,C4366942FF255BD5,339D78C537230D9F,A0A4938581B610E0,2C4B190DD1485256,709A69D53E1ADC59,B0B0414396D56C64,0010F1E763404AC4,25659E84EF08760F,E1925DEA624E0DCF,E93256220B1613D2,9848DD50E0F3C81C,5C3258C868E2376D,30C8D71D5670368B,AE8CC55B14CF3E70,0036EB4352C07E31,10B70723F0919847,0A00B6A32BC2392C,6D850709E20F1F08,7869AA483007F6AA,918E7881BB8DD615,BA0D2EED8A9A4C6F,16F08C992AB4BF57,0033380745C89479,74E0633FBD9A412C,4ACAE87416EA73E8,28E39A023F42B4BC,78EA151387CE8BBB,A5A8C6F3DF4CA1C1,14B486AFB06E61DE,AA39EB2DB1BE9004,0034132B96939FB8,BF7235BFAD8E9312,F493EB29CF829F5C,E4C60EF963C72642,32294A29F272B4C1,87B8F1F000C52248,451160037B131FB8,178879DB3C4360EE,003E909C9F2098BE,88C672D65EFA9FE1,D7CE3C22759AC549,18330F41226918DF,E96A40C5AB192D6F,928933AF5950906C,B05A2F69DD878F48,99B11CD36ADB1F53,00405B0DF056C6DC,8B0C684F78E96102,FFEAE5669ACCC14F,F99D7AE46965F12A,ADB9FD306626DA10,9053C39BA2996ECE,5D3F7767756C7677,0244CDB442E19730,00115421BCF20153,1A32FB73BB507A24,BE2FB4590DE58B75,9BE77D13E8D58E34,555F2076D320950C,A626AE66C558C586,F89840B29925A624,0E6CE508931F4FCB,001758ABC283486C,F4E370CB9962A3BF,4B7C2C2C8983286C,1D3E5AC23553E752,B0DA1CB070C9DD39,AC81268E06ADC9EB,F55FE53EF4A19C23,590893D20A07309E,0034A316EEAEB0CD,AB2F66C6019A2C5D,B2D3AC05ACF09B74,56CA6F21B7B25E93,49D61D8427DDC524,440720C7E4A21041,CF1E06E7978FB67F,7C673E53180B2F5A,000BE84BD7E041D0,86D1F3DE890147AC,BB04987BB6A12911,FE10630E8B41F418,3E02C58B2174BB13,B0A1A13EEA19D4C2,ACE4CB35E2E00245,EF3430A9936FF8DB,00079D907502CADE,22BAD499AA3827A8,4B3F1E119E5C1FFF,6F080FCD5AF1AF09,29A93D4E05C93B3E,31AE0602447AF489,29CD35D79757DFB1,A5B8EA1DBC1E3B96,0013D7E595CAA0F9,58946FBCD5DD4CC6,2CC8008989443EAA,E2BB52F4D5C282C4,EFF44C8F8C3B6353,45FB3020B5EA14A6,69E69A9F2F471499,31AFD7A2A10BE890,000BC96D91B3720E,3BB29EBD9335996C,3838100AE664F291,20040944D616382F,18DD4AF83027781F,8BF9480718EA32ED,B98602F89AB81282,E809E39DDCBE7A21,002224A7B9AEEC35,5BA28414AD1DDD06,C140EE34EA02A1AF,906A1E870E7F4E3C,AA1B6BD771AC8B68,D69DB0BEFD8E8DB1,C3C130CFA300AA03,165B8CE49AE5DBC6,00258651909CE260,55C4B04729F2C20D,BE99A2D495761382,841E2E6F510FBE10,CC7AD98DC8730C6C,9E101271DC694850,1278ED0684E5737D,4F1072BE4639B041,0035A14A1C9B4DED,EB15553A5709A9C9,450B4ED98429A3E1,1C9D2D23367F26C7,D562182C5EE3BC6C,5EB1A9A8B74F6C63,8B0C7DE094E1221C,2EABF93F1692CCCF,002F42821BF9C249,1E4E57BAE436B61B,7DAF2C0BFD0F937E,40FA07236D8D2647,7240569597B142C6,B737FD65A4E3D6BB,703FE66C031544E9,08653CDA0C2168CE,001A085DA0A4C7B4,DA491A791F43A339,ABB7600BA7B14093,70E3CCE8094C3E14,33A4DE98A5A1E8D3,440FE618F4E56B3B,D39D75514C6B1256,1C5A249B7B08281D,000046161C734D26,85049B5E8DC2B092,999D75BB439080BF,F073A83F1DED81E5,1E73A023B92338D7,654E027B15DDE902,6FB585760D837E18,C86FB667D6ECE0F1,0014D054D2431AE1,1347E4250BD662DC,1E45F8C289A0207D,84652FA71012FD5B,D8486B964E52586C,5F706568755C172C,23C6B4354A2B7418,1D788B591B1C230E,0018008BACDAFF1C,80A7F5E6A421EEBB,828ECAB0508BC656,3935A686D5BEBFD5,FC2E4BB08CC9F415,CE1A132042CEBF5C,85AF8C8514600468,C43EBDAE9491692F,000DE602D88A4203,E237911207648504,8BB7BE827E073004,3AB562FB1F7437A2,DFC5FD03A24C7AF5,F6C695CB252390DD,3667965601555FB7,B6FDC18C3E6C6CD5,002D2AACFF43EE62,D12EF97F00D11574,52A1C7B56F78108A,7CA8C9B02689C2A4,C9AA045389C7BE63,A754A4B132B742CE,D800480B740A5B81,38F7242150BBD4EA,00028C69DE64A684,8A2CF033FC45AA51,6A525E128AF89663,2F0396C9D5CEF9F2,CDDD8A0F3FED9FE3,277769192D52B1B3,F02A474F5575C357,B1EAFF7AE2951785,003EB549D3C8DB9A,684A98D694D527A9,3993656F21E4D8D8,BC9662032A05F1EE,EB897927C8AA8A16,E6CA344902805918,DF6615363CEEB0C7,ADA0FBD7805D319F,0034014C205CEB4F,1BA597BF5EACAD9E,A29BB7673EFA4D54,A17F38A663B456E3,CBF4BD6F69267C43,D4D785422F42AB3A,1AEB8DB3390DEA95,D16DE200EF888757,003A028B3B6FCC43,9A30EDC32DD484C6,BB35495BD98F7703,9CAD39151CE294BF,25389D840F6F0313,0F455BD3973611F2,BF7017047AEBB291,528E832BB0EE8FC0,003D02B15EA8CB16,D28BCF687ED079F2,E1B7B87DD31595F0,97CAEE6055A88D98,EC91CC1939AE4E72,5ED4140AFF3B0A53,3B46B3B6ED2190DB,42F4F8FE56319747,0036141371CFCD0D,6AF590E7B46A07A0,36B3AEC898A934AE,B79C006F2ED1C99C,229332AE6B82EDD1,7FC2F8D29E6E6D8A,8BF4F584D233F310,A7F6BFC13C7BDC9B,00226BF38548655D,FD97AE250545B392,F3A79F2269BAD5A8,F17C97CAFE7091BC,245F00DBB8DEAF28,6BD528EEBFA46FD5,1536A7E9B8680616,83EA0F95CD97CC9C,001906D439356980,9341D52974EEC63B,641FE51C19F54745,508BB97B2BE8EF09,E068926705294A71,F82ADB1F93EDE103,AC80B7CB99CDB7F3,4997551F9DED0BE3,003859289C816A89,2450C480A6A234DB,8D0DCB2D91EA16EC,5127B59A6CBC5EE0,77FA104EDFC9571F,FE1F85BDE8E97472,8D8F1E7A1EE55ECB,C62C99BC55ACC580,00150749F3025401,C2D82CF3BC0B7B29,7DA5D59809DBA692,333D046695A27CCA,A90CEFB112E049F8,04B7AAD3607DF377,AB3FDF48BB20A904,C33BBB0EC34CECA4,003461789D7D088E,A6410C729C23518B,CA7C2FA04266800B,D9FC8B912D984F67,9FC19E615BB94468,1BF8801978A06557,B9B1668CFFCD9C7B,41A3E5C96AB7A388,003E8B791B77B2AF,790C76C92A222BDE,0E269CF1D12F69FE,4EB25C9B5D2C2C74,88E35D83A3490912,7580885D45BF5DBB,5C7766A1EE629590,3766D2C7455D1ED3,002B51198D19D466,6511BD4F3D88881F,0BB5FA24AD21EB5C,1E7E1673933570FF,E114ADD69F70B8B9,FA5A7821F4D8A129,80FCD4DF2061703B,6AE17AE4233C4A18,0036C76DE28DD9DF,4294A4967DC4D31E,068CA71B8DA4C100,591A5CA5C9CAFBDF,2FE1E044C538FE96,55A21570E62DD5E9,916390315C77D887,04D18407091BF61C,0021F5FE2B159BBB,DB7FBDC9DE947C67,94E47BB6D3774758,27DCE8E836DD09F3,9F79DA08B5A54F51,FC0C49789E007039,85591AAD6FB3D331,AD7ABA03467F817A,003C209860AF625F,D956C8940B16D0E6,E99C168FA8647E8E,0443981B12158A0B,62A73DF528CE43E6,12BDA7F3B2E58F06,A258E900ED001B9A,3E827DF2187FDE6A,001CF454D601DF7E,E8D41FC1C6DA6CC1,F27DA4B3D87EE219,8B956FB9CAF0A9E0,9AB6714415761B16,852EE1E7FE4F84E1,F1FB7AF94863178F,D4F5F92772C8CBEA,001D9D6D97DEB55B,9608223DBB03C7EC,6F73048FA477992C,26C67DC384A1A5CC,185B3ACB86AA195E,54AC275135854473,C9CFC656BBBB45E1,22035E06BE3D4189,001F0E6191FAE1F7,AADE5859AF740BFD,01E971698904E9CA,10591D76246DE61F,B5699653BD7A5DA8,749499EBAA6A1151,D69B1A32292C66E4,3AE8CFF4DD8BB071,002633AEB0860B8B,5FA27E4387D53E04,51C8321967C6C873,431D50BC65991A8E,53E42650F50D33CB,0B6C0B73752E161B,1B309D4DC3328085,D58292ED116615B3,00375DEE5471B5BF,042C26E752EB1FC1,B6D0AF09454AD11A,037FEE0769940122,5D49A9EAABFBB288,E8AC47B732E41FAB,E29D280204D92D7B,055330973A36774F,002837CA42595E43,84A60756EB7460ED,294F4E71375C9B63,004B974DA51B11E6,E679D6169965F788,0BD12F10AF3DE1E4,F9064A851F1D599F,40824F107929936E,00312E08D710A34B,AB492B7E77F1A722,DDA9B7B6374E2AD7,628F55EA4126A72D,DE9213FB7B1C0563,B35853FCC480FDDB,3FE86A18C62E9E69,FFB68AE526855371,001EA56CED5D3B3A,D3266F43B31C2EF7,43727C43EB63A2C3,ED82E22D156D3184,8EC5486D333A2DDA,5FBA48F3CC129FBC,A17FCA3707FC7F5D,BD1D0C818F04BFC7,0016349E263AE5AA,CEE0078D21A51225,304399D3777B2930,E55F9C9134694EC8,4432A2592F115737,265274ED9D87CBD1,FA8F7D2FD26C5691,8F8B0B47CA7ADD02,0008AA0A796F8C8B,94EED86E62DFB2A8,2D59B2C691D14BAA,9F28DAD9F642D39D,476F5DD5254EC662,AF7398D436088F06,F8D79192B24791A8,0D91CB3EA1EF269D,003A25DFE61BCDCA,01AF4BADA6EA9566,178C0F124F70F19B,243EE7A2D154D8EE,33C152028687F7F0,9255A20B07A93BE8,952EEAFB71FD5265,74A21C3350378909,003306CF33DC1830,A63225F393C7980A,83C1317F8505B9DA,59CDD03E3F1A575C,A4D6FE76C1F197DB,90249C39A4F53DE7,E2742B13D0F9BD7E,5D2411C605A6D17C,00024392AF80B010,EC80EF1D21F52C33,20B87630C00BE2C6,AB495FD8DBC68F4A,4993947FF5FB0584,DF68C7063B458E77,FEAA512EC1A85C97,B8DB234CEB8FADC2,00117D72B29AB2B8,F80567DD445F4190,27B344E83736F311,DE0FE0693E86D288,80E5C39AC243B12E,E731A8390442697F,B52995DC10D85BBD,983A908D958E001D,0014EB98C8A88BFC,7172A2A45CCD77D2,6FF18419AEDFFD58,044E8DE05E672F56,D5E1B1387BFD1054,029D1769CC93B777,C4CB7D8DAD3E37E5,2B2271050C5D616B,002AC9F1B34E6816,5964EC174A548BAC,02C361D88AAB64A6,57B1749604E46C2B,6FBC74F1C4B2BC10,8568C042E06F1E2E,5BA2E4683436926E,A29E613F21DD35E6,00025A65EE02FF8E,6E92A688A4BDD8C6,F0B8292BACC18BA9,E12573106B312252,6B3271A6DFFA14F1,A3E2673700527601,1466FCF69D624777,DB679341C2F83A3A,002EF5A1642748EA,B4D3F3E4F8C92F9C,DA6A388A1A12A6C5,3F20DEC253AA2DD3,5D31C2811166130E,55DEB5CAAC4A1C04,AC88B39B00B954D0,B91496C59EA25243,0026C7AD6C28555B,68BA3C1AF0449E72,B31FF8516251F2B2,66660C9153363B34,0738E9723B448FDD,7CD8E90585B20898,1DDA63E7289E59C2,CD55EFFF4D4C5DC9,002CFED3A1E79E6B,23C7E695A4663F7B,A33A91CF41A6E8CC,AAFC738D4FE65DDE,41354E6C4EFC3F6B,CE09ACFDE0A88351,B9B5D59D84FFB394,320E700A5B4A70B2,0011C07C6EB6B0CD,9A2B92D2CCC0B7E2,2CC322DC947F06AC,DA802EC9FFA78188,729A1576C75F6485,58DDA8DC31FA6231,12631F873B3E1DF1,CCB209304997B3CE,00157780BD4D6289,7A45709B2B25DCC6,772C166EEA2BBB6C,6EDF483E38C6A664,219A6159DC453E21,7CACE4BC4200B7C3,682C7029F7BD31C3,E0607BA36EBCB8CA,000336036D4CE929,669D3B924DE9507D,36F4011C2D1E2348,6B88C5BF3977D55E,B5B6D0A444714E3D,47CCA405E7965E95,1C12225588E82A43,78670B0E17F84683,0018CEC7F5D12C7A,5DA139D18AA02790,F50D387407304BED,D1BA23AB2D5A2452,2C1105899229B53C,3ED146116D15F200,09D8E41FE99E5488,5AE953753572C499,00346DAD0FAA1F33,62F404648A5194A8,65764FAAD907AAEA,0585E5252C191786,BF40B59B10E2C680,C2161173C837B1F7,E07C6D2A74859836,1ECDE61A3F74F2D9,00097149A405B505,FEEB8F53EA66B66D,4BF7A271ADE8B01D,E7007F9C02F8D5CB,965246982E51A804,290E657EFD7ABA26,BC040697AB106A12,14AFFC1F1DC62376,002D37963150FF7F,66496558448BB985,C716B523E1F41882,7BC241D6E1544928,9C532D3A1A126F6D,8F6C690DF10D6A2B,0B818C8DA7DBF2B2,7BE2EBD6C3F69AB9,00299FB85E7B17EB,7AB3420A07944A24,F59A52FCCB68000C,0FE3A8452CDFE4D8,E4E2BA8BF36C65AE,41145093BC69B1DE,6BEE25E4C624945B,C677029E2FFFADBC,001712D0912AEF0D,4A413C927195D2E6,D2A5059E2666E326,FEE7E3F05555C9A2,4CD7A4691BB0BD52,27E7BBBD585D8D76,600C34A32B1B146F,A682FC1DD1F45234,001CE66B6D645DDE,0390BDEAED233E32,B9A4093C601AC152,F54EEE0949FE611B,BEEAE782E291C0D3,AB7FA434AA95C9B7,BBF947B29E0DA2A3,39CB325824A55526,0002FEBAA458D4F2,546B51205606BBCF,D94CA883E6AE35A5,6CDF13C97D55056E,5D01CD588E244E7F,361EDF937C1E2CE7,3746CEAE590545BA,CC9983E6410D069F,003CA5F3C26130A8,F1B63250AC5F7FDC,BC0375C25A3B5858,D3FFDBE288C8BF63,FE07BF0522C314B5,99C58660027E39D8,E5473DF92C8744E1,0B84CD249EBA475F,002E8EC2E14F6FDF,1D48D7438BD2E58E,818AC2EB4EF02F11,D91FEC9A73698A09,9B3E992DD001888C,ACBA49EED62A3A0A,D0ADEB5508D8C10D,F4F140EF2D04FAB4,001E44C12F3052C7,93BA6542CC091641,92AC91BBA2AEF8A1,2DD68678BD641512,37995142B5BD4C81,4D4598BCD6B2CDCA,7E0C0262B791EDB1,ED246B0E2413396E,003C80014C42DDEE,10DA41DBFE09BF37,752899F83ED28366,C0C7C22F68E90ECC,E30975EEAEF5A8CF,D63E8E15E87EFCDB,199E6379042AA847,DE59F47641205165,00302FC591230A19,809C15014AACCB39,90A8B0D1CBC46D2E,7EFDEEA27715A5DF,C55D80B940803DFE,8A9223264EC832E5,CAA6E7D90632D306,FCAC08E3E0DA5E00,002F0E3D02F8263D,5B51072DBC626948,10B3D64D19FB7A5B,4CAA128D47B15DFA,3559986213C5442F,B3B69DE04F14D4DC,CA38B8B90E718D8B,FFB451628E6648AA,0036D4771BB0E3A1,3AFC19DD2414D09E,F517312467CD9197,309A8E409E03D67A,140A6AC5106D2EF0,A02428A86007500B,CDEBB5F991C1EA59,E7C84FF114FAC30E,002955FD717FDFA5,35C4A0080B415274,7CF9B96E9AEF6340,5E9D61C823E2029D,A3A1449825B03EB0,BF7B8F9D645450D5,80B16D688D9B465A,A2E60BA7A5F8DB03,0005FF1B830D7C4C,99181B17CF596049,00720B8556900D55,95DFDD18DBC36B49,BBE69663E2EB4C1F,885C48A4A7679D44,E7AFD85ABA3DC16B,E6CB9A00DC9F6580,00399B5C4F9207EF,7A00CB0D5F58A2DF,0E7515F1DF9ABF3E,67AE924D6E10C4D0,A8F3B73A28D025E5,9DA783D3667B7117,192E3158EFF0DEF5,FF4F966AA0A332E0,001F522D621AFC89,D6E0FFAE648CC168,AAD177A91EF5DE60,12BA0F542F632D9D,324CD8292E1ADF00,32B73212C274AD47,7E449AEB2A85E4BB,F32A5DFB315E9060,000737FA105673D5,06FD146CDBF97BFE,6B4ADF1B4E5DB30E,C862619DC9230F4D,5C9DF46F2C4FE8C4,19DD437C3226E6E3,D7B668FF0016922E,9FCDCEBDAE510F77,0028F671C4AE4484,6EAC6668A322F180,781D5AA3D3B04932,AB250D7177A90423,88883867A352801F,B2DF8BE8AA7DEBEC,B18C0E7191B25BC9,E453C8C61382CB58,001E1512BF0B8652,5AFE141F4823C952,D5E4265E49211589,F4C12F9318EA4520,4AE90781843AB51B,1CBB3C6C35998965,BB3693B2AE46B3CC,FB78A9E4B68ED6BF,003CC8F19AEA347F,62D1F2EBDAB1F3B9,B17DA9BA3D64F7B5,FCA40BFBEA967594,3335CFCE3A4FFCCC,8C3EBA7C2211199E,9EBE17D030988C1C,0027A331FE51E84D,001B117D99AA8D33,8B6A85E2FEB4C9A1,1C8385049F73E63D,65BE7FC56C961DA5,F38FECEB227BB791,C9D6B4DD0AA5F97F,2B2F03422807E17F,5B2E03FA35F04B37,0032C802DAC3129B,8A459636AB042B93,74155C0466162B64,4B358CBEE8F52185,59526C0B4509A556,E659D33C0DFE3088,C2F6413270588753,67041C3C637DA95E,0018604658DA5051,3CC33EF2695BDF91,643126F876612F05,7543070E47B87237,1863916C0B4D213A,0F7B97FD152F7FCE,A3DBBA475B64486D,756F8483EECEBD8C,001FEB4A65CE81CB,99B962F84815E70E,EDAD99C8C744E109,2137ACEC8C2016E6,92823D94071E0AB3,9A5DC381AC3D1945,FF9347EAAB507746,E6E26714FEB60D02,002DE9E749388687,7B576E2CBA8028F4,02FB8EC9D328DFC5,6E213C8B5856462E,D01C855737C670F7,000F7E24D65030B4,8CD6794651B8BEE0,450DA019113768C0,00101260FBA2E43C,EA669BD27A7E7BA7,ECE4F90FCC26EE58,52C455C7D4AE2082,1BB4C2687F9411C8,06F4404DB0B0CC7C,CC431410689FC680,C85A43864C2AFDD8,002FCB65893821C5,EB8C6287B88793B4,A17C9CDBA819DA64,C80AA6C12BC008DA,CC45CC09203FA38F,21E13B8F8597E290,30C6FC09D2242042,A5AE02CAA27E8C5C,003367D189D259FF,5CCC269873BEC13E,1B504DA2A33D2825,D565AF851F517C7E,257533E41B6ED468,C594AA4B01BC2215,3B0FF1AF0FF7F378,BEC7AE26371D41CF,0002EDBEACEFEB9E,69BFAD19190DF3CB,A4F5CCAC0773B334,295C438F7D1675A6,2B7D506A5D7DA457,CC3FFE505D16A3EB,59CF4BFAF225D634,52C289D0FF7D3D4B,002E58C1409B8557,8B3A5E6983E78136,A4AF23B0198A2C92,B52D8BB300009947,27A8220C5AEB01E3,A5CB8EA2C9EDCDAA,69269568B3F1AF72,15458DD8F47C2EB5,0025F1392492C842,F349E0B200CD55F9,D23F5EB77B50A16F,02E0C74AEA5F7112,2A9DC357EBBCEC9E,2FE8F1B399CCFB75,A7FC30C183EE986D,31395CC72C0059BD,003CFDF7CE90504E,1EAAA431CED14213,5484384D4CF6EE23,A1510BDA83B54C57,3D43142DF07BE2CC,76892FC9101B3A6D,7249645164B06663,106AB04E35BAD81A,001B578E0B80B3BB,B239F803A916EEB1,3432544A9390F14E,AA843628CC0B4D7C,7EB411FB918F34CD,9C9B935D803AD916,1908698D801871BD,34E6036CB15150BA,001448151E73870E,934BF00DAC94112A,55209E7F113A0275,302048360A487B50,B5957C48ADCD5DBE,486247ADC736F655,6EDA684266960FA6,0C2980D8D9464533,0039C19D54E526A7,49E4842CCAE70980,AE89228D0EE38365,016DC0E5C20821D3,54265619F7869A76,7C97BF3CFA5C0A2F,1F2A86038DBB9F73,D5987CBB6FBC3982,001757A127797752,216DAFDD0D207E4B,8330EAB8649C6726,CD7749BC248C0022,E7BBC5CB077AEFE6,EA93C453B69F1D60,459FFE7CF74BF23C,651CB5ACE33CAC45,001BDB57153D6654,B559DED8824DF2B1,0F30E2A2565E9839,E3BE19210DA89DE8,CEA6E544A5ADCECE,8735F384AAE1A263,055C57BF58DA6AF8,1E1E765D20687E79,0001ECE0CBB134E7,81874F9189BABBAC,1D07E58FB7403BC6,30784DAC183C7D56,EAE153421EF69278,0CA22686EA86174A,761FB718BA3BD586,3778D38FCFB8A47E,003A7AEEC5CD7A82,CBAE013D19E3EB14,1B9C9D704082D22F,E068081B87C1C5AC,E5F355F4625D7B35,C6B1216AC1DE1EA1,E72CE450E95E84E5,C850A375DE829D94,003CB35CD975FD0A,1BCD923F6AE6C7C5,99EA7BE0A7AB82F7,BDB1BD2D85CF04FE,123ECF75AE4CB0A9,676BADA261CDB58B,7CA538A7E5604680,70D37D4ED6C09215,0018F2AD940EB411,97C51DFB727C6205,AEAFBCAAA02AA800,D47754711FB76423,1C11E59576C4E615,4F4EB8BC8DD582D9,2489D25758AAA190,BBB8E009DAD9AEFC,00228E5E4330FCAF,21FEC562B04FABA6,756DC88881F6139C,2FC362AF35A97BC9,E8CBC8D7E5969ED1,6E9714CCCBB66A13,E883BC62F1CC1B4B,1A03B145C6F2E4AD,0005F4697EADBD44,CD8C19FF83129122,98154B9DDBC0F90D,A5A60DF368CAACA3,610E2D42CC03F527,BE2763FBE52525B5,A0B782EFBC514DB5,ADCD37A99872187E,0031A1FBF5553BAF,D3C8BEC669FD3D92,160507F112F51E4A,6163D6FC9C69BE52,92A4B2454BAB05AB,95C90296C5C258F3,ABA32ACDB5186F4D,DA681711CF4702C2,00330466AA957723,EC13E3D69328BF9B,F73812A7C31A6A64,7BF7460A2E92FB75,3579F3A26274F327,94505501629DA2FC,270B8D1D5D047AB1,411D3516473DA6EB,00167E091326DB8D,D9D2BDFA5A1067A3,F7780C7A17C441E2,CF755123470C31F1,3407CAC0EB6BFCAB,E6C41684FE6AE364,C460414D14248356,51D8C4F10B1050F8,001D9C6610DBDF6B,29D6BD6C92AA2CAD,2B4E8D508F6A6ADF,BF692B23C10B17EB,E867898CDB8E835D,E818EF535E43D623,BA84B74FBC5C42BF,19000E07E0DF2174,0020326C56773102,454CAB3EF66B8FB3,0A8D4787F370B96D,AE6CE7B711236347,8D588B640FA3D444,0E7C14B267291B37,46CFF9699C943506,B2422BE51C8CCA38,0004BB47481226E7,47B83E230FDF71B5,75B1FD509212B2A7,B77D8EBE0EE8E4EF,31C24FA85CF2B97F,B0262C4B584350DA,93563FB9242042DA,99CD56AB67D6F699,0031766C835748EB,EB200E601624C04A,7D8189836813F421,8E1A5F20C21D9456,1B532D51CF3E11BC,B5DE2F76D4FAF8C3,1FDC53E4FB04D75A,349302E8F6DC0DB4,0006B93859C9C52D,DF821ABC43C5C7D7,6239C551442260F3,1EF29311B31912DF,3815814483F49E3D,38AFBE61AC6E6ADF,D6875672C745E7B8,D8E32DAA544013B6,0002BC3124163E61,F8E3E9529E18D683,269D14AA9694DDF3,CFB5F307A1D7505F,E56FD178A9EA9223,32137313AD9EE39A,A7881B9A888F7012,F3D0C56EDA0B0B1F,002B4B016779074B,5AEF835F53CE2F88,361FE40771509630,01559B6C6DCB0DA4,E1775135D41CCA37,8C483FFAD2C32B7C,DCEC39A3F9A06FC4,C5660A87BEB8224B,000068124C8185F3,51E4AE9F8FA05E0E,BC1235F3A6F82D31,AB3F0D6F17C09B62,39C29E84660E254F,F425666EF9A1CFE9,72C9A19F61D68404,6D968E6F5C0ED151,00065576439F7538,96F9270C22BA998E,9EA9ED0F275FB6D9,C6E8C94C3FCE5876,C38B558398AAD1BC,09F13BEC40317734,181B95DCC1B36CE5,9F88F0E66B40CC50,000B103AE1E1A348,6F5FCD4D8B853B53,AA909D3431BECFD2,D44EFABEE75E30C8,03E5568BE69CBA57,5A8319DE24144E13,57AFE65AE4B36A3F,2F73442BDD4E84B3,003DDD172787BEEF,F8CFD979AD6D258A,EDEE19E6FE806E93,1C735E89A180B2F8,4149E4609544B24F,758357D6A6018E89,7C9246D4CECFD221,C8A962B3D9C97C86,0032F6DD1D9E5B65,F7C5F605897DB630,BD007EAAB5974D2A,D9422E413ED1FD46,A41F809F350A824D,6DBFD6852229395A,6FECF76818E6486E,B4663AADDEAE75DC,002E45F491D324AE,6619BBD56DBD6E76,97BD9FB44795BC56,1237A1CE54B8F045,BEEDF3622202BC4B,40DD01078DBD2EC4,E6ED4111BA63C995,9EAB11AD07D457B4,003F877529402E7A,12513AD413C2329D,D304DE6D1AAAF4DB,9E8E9C5F4AE669E5,5FF13964255FF579,F7334615814E3BE8,B47FE726D5ACB60A,7D16EBBD3CFE0140,0037BB15D6329E08,9020524360D06C9B,160867207A3C97FE,B76C81EA146AFE62,BE2272F72647F87E,DE7E3CBE558708D8,8B0A99DCBD399FEA,257FC85996C90CA3,002B52EC23761A87,691731558C0B7A2C,C78EEF7ABC86220D,D1CAF994E3E6EF11,FA6171115FF2CA49,3D01CC1D41CCEF62,4EDCDA02DBD41FCC,819E745D4BC60A9B,000B73C07B9563E8,8193335F929D26BD,7DD2DA0E7AC3F6D0,F7EBBA0A6120470A,C59572B64E37E13C,F1EB40D99DA4BFB3,3DF6397E4ACC4085,99102C8FDEA2BF69,0029ADEB52E74314,2A4EAF6D494EF602,9595B0E6A559A11C,B4F8F2F90C596CC5,671DF87DDEA7C777,8AA76F6C5696D599,4CB82935F2D01A7B,E0A9CDFD714C1C4B,00391E97885B46CE,E5D7640C3B8BC99A,9C7968DBEC9AE369,9F51A28348D5B249,B74F2B5CBAB827D7,6BF2C53F9FD1ECD9,76B27F280904D502,A826361465AF2CC7,002DB0CA80C528DA,D1C2780653998329,A7F160F61EB53B23,C1F72EE8D54C120F,EC5877FFB914D7A7,AE9471B98710F75C,F3DF319087BBE665,E27F41FD6E119000,000245ECDAD95858,C26D9EEA4E15A764,C4A5A8037E3BD382,F46F70FB4CA614A7,715DD65057427164,907F4B6A1329217D,BC5622CC0DF60B4D,1F87D4CD84C7649A,003425796BCD44C1,DCF149C13CE4958B,50D29FEBA1BC9568,39AA9B09CA6904ED,CD5CF49BBF0339FF,553FE262F4B1A4D4,ABD8F53743C4259E,00EC7592E1A17D14,00082719D0D72006,C046D5272BC887BE,64725F9737FDB31F,9EF37F2A947C9605,A6067BD3085AB3ED,749909C729114CFD,2306F81978835BCE,72D59C8A330F79CF,003DC42AE5E1E3AC,F17BC1380BD444DE,A59CDE6D7B18DE8A,946CC6B2AF2127B9,716D8AD11CC084E3,F4F382F31DF18944,B4E9A15A43050165,6084C32295B8EFA7,003FE07EC4B71BC8,D031E928B820155B,4395D43EA1D5F99F,42FD0ED68B5156D4,31E4A45E9A7D414F,28505ACEDC323C4E,67A79A16751288ED,609F9E41A296BDCD,0035E42EE5DAA184,CD664D8874E06D89,D81CD697B521A188,360659F29198C5AB,9E8DF1DAC484C034,8C286F1E21FB2193,53B27E87ED57C70A,FA01C182A44357BE,0034D43A6D620734,5D44820105226959,840B05E1BDD8B8A0,FC1EBC3178AE5B03,849E014973946E67,74D74A50C1A3CFCC,407C36E15411853E,55E5A9F776C292C0,0036BF410203DF1A,0E9343DD0A903876,33B25417BE058C2F,D1AFCBE76A7393E7,ECEF9582C877398A,653ED01923B99E9C,ECBC10C11BF1A07D,8B438105912625D5,000FE54C8A893734,22361E6186C89C45,B51BE1B63CFDAC74,C2698F53ACAB4A4A,D905AF30B75897A8,FB44319989DA67F3,3EBC537C46D24AC8,79C019836C11D900,000D1D5FF118637A,A7F1BD9E73F1A5AF,30CBA20663E4ED4C,0085523E0EC6C3D1,7DA59783C927A46C,74DFE180669B7AF6,3F135C1DBBF274FD,B8C341F51C6C185B,000993E9C0286C27,48A67CEA439A382B,6470383B9C80BE60,1DED6D75C9CFF3A2,1C2BE2B85A224FD0,DCF82B30ABD71142,495C5A8F860061A6,836FAA6A9A445F46,003E371E4B7AF701,EC6389468D621793,61C087F9FE1B5EFA,6F6F0B276414E0B2,55806E64D69E01A3,1DD392E7941211D8,8C5EB8E3E60C3698,A117A5E6FE0D860F,0001AC43F0681C5F,6A31FCB0C06A17E9,DC1CFE1E96B91EE2,8B5577D95CE54204,DE596B3E1B5A50F3,F8F6653B5100E614,831992FE07E63EDF,A7B0AFC791DB664E,001F54A8AD1067C0,84BFC08E27DD8777,361B5C2C84EF4FC8,4CB78A0458C50231,78C6BD938A7D97A0,00B189F85409531B,D22C33FA99DB9103,B00A9DEE046A30E7,0036088EFE592A8E,0F17DC275702A38A,9F36CBC656D5ACBA,2753279A7B9C237B,85FCE40DF527B5A1,BD91A40134ABF946,2EE12185B64C20D4,4C1DC78ECA9AD290,0031A778EAE7EF59,DD234D2BA92AADA1,56304ECFB4D55545,45BFEE76FDC66071,DA44D85456D7D8D1,B458F52FAC08F551,84349A257F17BC13,1D8600E1012A5FEF,001778FD641A8D99,9A8500C32BD2DEB2,4188628073C47082,9F280928D242AB2A,742360203BF02467,849347D7505B56D3,2B2E31331788D627,AE8453DC2FD8571A,002F76F57FD57487,E800188203343219,A03408D0C694FBCE,0BA4DD41C3E6D189,49A63C815DAB405E,1597A6D91394D5D2,20A49971BAD55101,8FBC25A76F9D42AA,00214F5714599E17,E461C284A5C29F3E,825C24C6EDFFF386,91FA457D03FC669F,65ACE2F985C860CE,401E717CF5F3E4BA,37AC68767C80F060,5ACBFE5608B31B08,0005FE3AAD7FC938,75735D41C399761A,9699E01AF9C91291,4C43A0DCC1E00C48,715F2157A187877E,CB172DF3B5B9C34C,D410CEDBEDBCECCB,A721E87ECA6B5240,0010E2E7DBA124C8,C626F4B5C8854BFF,820BFED366FFF406,2B758A75B56A2202,2B56983A3269FEA6,EB827A25DC4DA5BD,533151A891E3F345,90AAF2DE02A630FC,0033DFE14F9887C7,D956452549CBA2D2,472C79D501897527,8AA37E8FC354585F,05EF905EAEBC225C,0A8FFF37E4AE7FD4,843E62A5694A0283,3545EC96A1F46226,00319857DE4AF8F8,A75C434D9C23F5CB,C4AAC86892E7FE6F,068C270662219EC7,E5F5282DB8FC718C,5B4E6591572FF6C2,185A29DCC6EBDEED,7BE2551696737D16,003D2F27519C079E,7DDBE360F4695AAE,EBE036E24E531B9E,88E85361167EE373,A7AE3ECCF8C262D5,8BEEB11B01F6D36B,E281F9050E5FFA2E,E2F6B422F05DBB51,0038F221CC61691A,E348D84DE29DA92B,2B3625A6C818E5B3,B9FA33FBB7C206FF,7117B9C57C491965,D6FFFF4650F14A77,54967D6099076244,350F35F536ACF5BF,0021512FB4F8F044,F93F47EA199D0317,1C110CB7CB269EED,C4DE980128A3B3DB,E7E9DAD0D9C9667E,7728021EDA5A20B0,722D8C266608FC14,B692EEF9068C8B2E,0037DF770E0117D3,1C0F5B8484C02D2A,16DADCCDDCC7446C,852CDADBCBE0A0E0,6276A0A605426315,ADBAA546DD0E2457,57761B53BDCBF019,DF1C29DCBD72274D,003F852C02B42DFB,5FE741A3EAC0ED6D,C506397F3BBDE7B2,85CB8675E379105C,D99FE48CC5E0EC42,6EA6DCDD064EEF6A,AD394983796AF892,B1E641A467F28707,0014163499C73525,40E3F9FCF85F9F65,BA4F4F4CDCC5CD27,325CD276DF8284A0,4C46EB81506BEDEF,6C488EE5F23445FA,93E5629D1AD3CA1C,E0AE905E532F9330,0034F69A729D4F5F,4449A5401ED55D5C,906AD19B53FDD3CF,AE8F4AB6CE9C2E34,650B438C2E60B01E,9E2FB6C0ABC50F20,D8DC950D469DE06F,C69670D7382096A3,003AF800C0BEEFC1,082F28D227FB8DC2,460BCB5246D316F9,F05A8A6EC57A4493,7ACDD89EBA6925D5,E63B1EC564BF21C5,55745A2547C7F41A,FDD1044AAA8823A6,0006E5F0C97B7799,08EB97CB1E524E70,F5263D2045C1A17D,C7183CF9AB49B70C,D25223D4C7BBB13C,7823A9EC22AD35D4,460D94C8FC0DF5D1,7EBE88771F3E86B2,001862B5C49E92C8,30F8DF6D41018F28,4E0292547EF80F46,536DA484D8539842,235B343C0E58CB10,B7958C5E15CDB1B1,ABC3B6B3E343B0C4,9F7882C62A157A44,002255EFA19F9621,54870D52D52C6A32,E3A9776E9C12DD05,BB733B7F7CE9EB2E,2CC052397A6656B3,C675ADA8793F455C,EA17CAD440D91B65,9404558121E8BD12,003C5F27D9FBF633,A9F460457BD873CE,242AC98AB055DF59,5A070BB9F7609B80,84F4DCB06D8F8FDF,25D2062FC1ED5BE8,D8762F1290B9C8ED,9EA653DBF3909FD5,002FAA9532DA3E2D,514229239B6C2F9A,634C8C95BF106706,5C8CF5DFFB3FA956,2D0233D26D571212,3B0187535A875B01,447695C7D2070385,AD8BAB8A97550307,003DBC15CEFB8BE6,BBACDFF11AB96AAF,0DBAD836821B8A07,DF8B10DBCACADB23,C20C2BD038034658,9266A3851062AEDB,1409897B7E6A47A9,B191393D2A106839,00047C1360410948,F0C70BC7046C1114,8F841655AECE2F3E,2028365D7CB702F0,F6119A0333B5C8CE,618A85572CAD0914,63632AE6B33072BA,47B099A6CB4E3865,00297B7893425DF4,3DB66F2A96E96475,1E62476925BA67C9,1BB17650844C993B,9E20C1B94A6FE377,659E1B6765DB1815,FCD022C4B8621823,54A0E8CE880C92BD,00013D461ADAA2B8,A58A1B0854C1637A,9F935D57C906101D,23A7CD5071ADB7F0,4A60D7146DCF807D,B8C61DC5A83D7541,76D81DB10F918670,BE2A9BADF6739013,00337B270F994AF3,22FC52DB36D45E6B,FE90E8A95085405A,D346909867568402,5F499D15356CC2B5,542A80D2CD63AD8A,031E84EEB2F7CA83,CC4545A2CF007EEA,0033AC6E28AFFA55,F838307A9484F20E,AF7981A980F41957,458E43466E889E24,05A2CF3BAC8F8356,9B1640F6EC7EF753,6E7342FA89284B86,609F3B05F3B1D6C9,000A40CAB3C5B8FA,8D06C69EB83AD8C4,4D1D13E907F189D4,A861F6BDE7CCE09F,DD638EC2BF43DF20,A9C6682EEFB4F25F,13D26EE365B77A94,D263B1B58BFB037F,0034AF8D9D85B2B5,05AE6AB579942265,E630338B17B299B0,AAD6FDC2655C63FD,142A47CBAFC22D32,62EDE09A01780EC6,2159DE3C1A706893,C45757C024965413,00332D7D3BC52E8A,DC1B9A75E8FAD574,1A127BD816877FB8,1FBBAC68E06C5FA7,202052C8F593C6A0,B6E8CFEC261083CB,9E523EDB46053796,8D4B6B238E75789A,000237778B0FDAB6,3C9A2781049A8618,5C9B50D5AA87B2C1,D59CDDE36645CCD5,8D4D9DACAB7B840D,86C3932B04C65C08,AD6F5FDE47180E4E,3EFA9628BD0FFC6B,003AADCE1E2BBABE,3F8BD4FA61706F85,D89E7E8F81C88F57,1F8DBB90C791A6EC,11002843AE0A8DBE,0ED43AF2FB515130,007CD80B323A9E81,918EA9C710B38A1A,001785F84C1E3250,09259E5A11B6042E,DE2FAD1783CD3B43,05C887B82B69D1FB,0FA75E42B5678E3F,359DA41D30605E5B,48FA9053756222D9,6AFBBDC2D695F423,000E291EFFDD5E8E,15CB7577F91A1AED,CAB2D5B2FF953BC3,AC56CB4BC1B8CA2A,5F3D3DF2F37B326B,6849428A4BD2839A,9232AEC85614A329,4B8A43646B08A2DB,002049863ABA89C3,3B8E874A6901A031,ADF1CF02B97E4C7F,4B4C8798FCE80C43,5ED1FEF246748739,A7EA2778B6ADC0DE,53908D99D5386321,ECDB891A0072DB46,003EA170E0847137,C88B4C03B9B35B37,262354425567B94F,FED818B57FFDF656,006D07BB6760CDF9,58C136A64B1CAC15,DD225BDF98B2BF25,6ED44B13534B9199,000A951F91225257,898C6AAEE8600D47,0D813695300E3A83,B895ED032240442C,3DC2F3F4ADDDE2E2,3FFB9E749E6133AE,8074B90A868CCF1C,9AE95A5222B81F1D,00029E6D63D834E6,B7C64114EC6F18BD,65E4E9F15C7082EA,2FA4F55C26A4D5DB,D237CDCA55162793,E0DC8B72583D6BCD,9F0296C7B11CBD40,669887C5986DF5E2,001A9328C96A4554,64439D2C8406E257,E62B502D6ACBCA84,723E28B62C13B9F2,141DF9527C62F529,C9048F889AC809BC,FD5B3A0F6C059505,F2B869100A7C42A3,0012131E44F48021,7C23157676E6CF62,90DA15BDFD7F4840,3FCF1868A285B4A9,A7503473949609DB,21771840780C5F5A,4160C8E43D40543C,12BAC44BA015CB03,0036E1A8D19CEB02,CE5E0C7BAB65A9B3,C051A5CE5DC1F1D6,2A1310487732310A,24C20B98C5CC20B0,EA205ECAE711AD11,23F058EDE1F3D740,B6EDBE3DB9EBDE1D,000F63A6F2B77BDE,00988D21A9C30C38,5F143398D9A12CA2,B853D86F4122014D,DA4FCA12211E9B5B,6A5571768D7A1335,1AEB37926E5EAFD8,84DB19F1FD5567BB,0036396BF59B406D,0D5DBCA6E5550E93,62A87990977A7B56,8A0F6906ADEE03F4,F09EE1231CDCFB8A,19FD76F2C01B59AA,15DDABDD01496524,CC841B3D9BDEBE73,0020A7E47FE95566,425700E8925366A5,64F340CD3CB05A46,FED1939B53BFE184,71E4177035329295,7F5C0A321E9CDA05,1C1A497E9164EAB8,48FA7ADA93E6B499,002B1916EFCC06C2,E1FF5228958BB400,F300CFEF81B1C95C,D1205DFFF57DA0AA,9EA21689375C6B48,E90C53EFC14C4B22,04A7215EA8B819A6,46096C1E28CECCB3,000EC0B41919D888,7946DBBBEDEA7C10,05B09C8DEEA7D9E1,ECE893DA264EB2B3,F78ED247C4C7A098,CA0E4861D2911B2A,FDB6C70CFF1B3C89,6DB833EB6050B8ED,002E34E8F76B4E2F,BC4AD32E868EABCC,BDE854DFA556D4D3,591F9CD96B544DFF,E497DAB3E3A8D389,209634BFDB0CF5C6,AE0B03F765CFDF17,EA49894489896769,002B42BD4E77DB8A,20D3139D30419F0C,9BFE12696D5BDFBF,FFFEFAD8512C5448,E532A2ED48FB432A,844F60577211A150,6050E7E060FE9D35,97C5A1731AC04249,000FA3AA7E758434,20862AF2CD570DB7,28FBD4B5BC778A02,CC26AA8BE492B06F,9ED06A8C12B0DFE9,EC46391A4F128ECA,AA9914E0E0535266,18B630F9722B23CF,0002B179055833FE,0C66F96701C7F733,C213F0C1EF76F739,24AD20BCC1015147,30D8ACFAEEB02B2F,A10138FF3E61699B,D16579775F02CCF0,1F8B61D294DCC288,002789498784914A,1262AD32FE7F6A0E,3EFF7BD4FB8387F1,D14F549E0040DED4,5C38C34443D069DE,81C5659BB6F81E32,3843C67695A3D079,C837DB8FC3B0DB22,00183B52DECA0D0E,FDADABF0E511C3ED,60C2DCF07A4BC082,C8DE4E0D0CE7ECF2,88CE1DF1276BA70A,9DD8B41CD96DA95E,BE9862519DB90571,C246B7285B736383,002E1BC7A8DF146F,4646D4CB726C2C9B,2C25738231A80D95,E3613D18FFCC470F,7AA17E932B69AC59,F499AB85B6E0DC24,AB2F031EFB8DC793,9C0EE443EA390CB0,00299F70771F6F12,7017226FD3D1D0BD,23BD38AA4837C673,00D18C71DAF7B19E,959288655FAC0D75,27260C266E7A9B53,385401641E4A858E,4DB05CAA9C6F00B1,00013E3618889CCF,B242D99F385E6D68,FA5BBF8F887DE67B,0055A0C72F04982A,B15D931D28F741EA,A744C83668E228BE,4036F729725C5DB4,E94C175FCCA1061F,002D09379988270B,833E779B2CE9B391,FE44A706A9C9D81A,9FBAAE146583258C,D1D3D6741208DBEE,3E1A40DF542FE6C5,9E6FAE8E3D965ADB,E6E2A12ADAE56B18,0017F68C517EAB63,AFEF4CEF5AA5F58E,6747E905A3062264,B959C8A87424060A,8880C9C95F5AA98E,3422D6C1FCDC0C54,57875DBC9ED09048,F87A03F72FFE7A32,000E4542805EAB42,87357A92D68A2771,1722115966C6D118,0B11863A28922893,0CA9A2FCA25DF3CB,AC83CA438045C962,4D35B0AE09BC739F,B96D3AEF8444436D,000D630514399B3E,F019C0F306B95619,DB0A5F9E587687BF,B92CD0C079812487,FA07983EE51DCBC1,F8E2C583EBED06DE,05654CE1B7E7D366,76EE8F46C81DB5A1,002E91AEA2A43C91,C8D28391593AEE50,7B1253698278F497,1069635E3B534765,5630DBC522404D16,496E11A3C32A647C,2C9052BA7400C669,B67F38DDD8B5355F,003F225CFED9C27A,6643709F589F4DD8,D57ACEF47CD8B179,548DDE50F8D8D531,61E4FE196DF7E08C,604B9B7D22CB62FC,043645211D17645F,C4813C561F079DF9,003AA2F948245246,0F8EAE26F3DF6EA0,93ADBEF3C4015448,AE3D926DD00F3F75,4FF98DA8DE79987F,A3C500C1D6314DBF,22446B83C0D06CD0,E52711B9FE77AB18,003FD7DFE608AD9D,C9B5C9B537E50229,6F76272B66629673,EEC556AEAEB9A407,6B075B2F757E881E,FB0C48E3E8734EF1,0B5D9B5F4E466BA9,B9AF58588648A9A3,002D9324958AEED4,E7756AC48AB19722,87C544186C70718F,26B9C38D69417565,A48AC0DB5C029016,E067E1024047B3FA,3544458571E0E1AF,A05D92877FFCFE23,003C69B2FC03F636,4DC0EB36B1645B1C,6729FC340DD1395C,CA6B7ADAFFD4B63D,8D716C2B0D15E5C0,92518E7726050CDC,E459C42F28E28E3F,E5E7D351564C4683,00034D7843270B20,604EEB059A0147AC,091790245E1EA53C,C298E6047D7B0674,EE1EEE1901C0199D,DC84E0DBA4CA4CA9,80F030A49FEAAAEE,B98A4D48AB688745,0030CCB56437E9C9,6E197161093ECE46,438DBF61F31ED630,36BF64EE61F47A13,E4DA23B0192EDD4D,AF87CB6141FFD446,B37D61F9784B21C3,7D89C884EF226156,0036AF7077F040D2,818335564D444C32,2BB37AC8979B0E5A,273385675DF3772F,327B7989E9C15CD8,C129D2C8EEF1FAA8,69DA7067E0544CAC,6ECB24CCC50D61A5,00199D35B3EA7DB1,4A2485FFF1611A75,116D683C43AEE4C7,35A210EB38BC7DFC,7B94A6532F1BAEB9,3E6C3894B094B1AB,0A54246C0AC9CDA0,CEDEAC819EC84FBC,0006474D56B38048,08E065EDC8660F14,BA5169A04C45F040,B02122D52C9648BE,6D431D462B40660E,872D26C15A65F983,7A29C7161FE11D30,7319048BB761E1F9,00293139AC84DF93,AF043B54A4F100A9,6967D4E90CA4C971,AA01B4C0EF8851C6,90A1C00B5E3F33E3,5D858217CCBF29E2,DCC102257987324D,40F1BE7BCBC6D2A4,0013135100795D03,517E00655F982829,48D6D628D02F2B46,00E6A784552C503A,5F4F24EBAD72263A,9C60AB501860363C,80C7E630E610AF3D,8FAF2FDB503616C6,0038E925EE96B061,90BEBCCCE7EA611E,FA076E8A9D0AF900,70BE981390263551,C97B254C2D268300,518E6B31A525133F,430D969A1A272782,9BCB20BC25BD9F41,001389C465FA950C,78E89952E09D3CF7,5412D7EC53A5B7C6,69F36785BD3B586B,1B59EC8B009811D6,892E9C3F5FD20BD3,6B2D8CC4D5E2EB59,5BC66FF22002A972,0013B5793D8C8043,8B4724301C55C58E,A5A3F9A076782DA7,5360B8ADA677CB5B,0DDB233B83F9F353,2BE9E43549898F9D,3EA84579F89D6DAD,FDB698F0939C3DA4,001A501C6CEEA9AE,84BF5B6BB34DF0B8,38267780421767DF,F56B7CB3B0E25AD7,B65A9F400277032A,4636717DD37FFE97,792D1563F87624F5,3DD4FAB359D6A9CC,00364043A723328F,3652A7146772366E,BE450AA4D123135C,D999E3E010A3CF06,8EA6EE9C8B842801,3EE3FFCE7A7D0527,7BE32455D249B898,3D04555CD3E8ACB7,001A2E1ACFB28554,DF92DB1BC5DA0073,861B1DE54D007129,18470B897C2A4FA5,5EF70AE4EF3786DB,62E8573BBE277D90,041B16E3B047A55A,08C40F7A644E06B4,000984C6AAD97125,FB73E3DFC1553A72,18F1BF337CCE79CB,D3CCFDB7E0C7A1AB,83200ED82691FB30,1C1B1A85183E61B6,983DAADF8866FE67,D4C95D60FF1C7A04,001EE59CA6312D4E,D1FA864ADC06EB05,E742869628382DA2,2F7516CDF6C7B6E1,1E13837B4863626A,0F3BB6634B9A9836,2DE3ED9473B17CB8,1EDF7F97E008B24D,0011F30E5A4258F7,BD3079CDEA99C7EA,A51C042F6B5839D3,4F8F12426D2D5113,BDA4801CBB151F48,1AC06FCE7177C895,F045D535910838D2,04C30B67E1DFD0CD,0027F283C62BE631,2EC68CB27E2C5154,4DCA1C93703853B9,154B3B08D0A57D84,04A05BE1076DD1C7,AEFEF91EE16FC4B7,0F0F79DCE4939BFC,DC5AB58999706C44,003060B0A2FB93B1,5324C0622D7F94F4,FAC9A625B9A08D77,DD75D3291F3C18B1,6A5DD4D9DF8381FA,775880483E95C705,56FA00905F480933,9CC288FEFF4BA339,001C35A8D8DFAF00,1449DAB57F14E350,D76FC36B23D3FA8C,854B7DBB5E8350F2,02DAA15F11D4C9F0,75395EEDC3A4D0F1,B2DC7DF3F97F8B79,F9E66A82504647D8,0039C4E3E54DD94A,71D4C6FDA935723B,973CF9EB0E0B63E1,46CBAE5643D0232A,351D623AAA946535,67EE2BC19CCE7A3F,865BC2AA88B9E695,C5B1FBF423DD6AB9,002C6BB95CF3FEF2,032923C873027ADE,BBA01C559A84E008,AD01C79547F9CC1A,106E89A63ABA4DFA,6B4C4427F940096B,0F01D38461EC9280,0796728CE86E2D9B,000F9412100D2385,DA1741C1040A6EA8,E67556C8475DC842,0CD169CE96160916,8038F814E5614058,8EA5C211F850D593,A632F9CB9B5B30A7,1A01E1F59B786337,0035E640A8BD82D4,13200DC4173365F5,3DCDDE6E584BAD7B,3BB106388E2A914F,5DAB5651690F500F,0DBFC77469CA6649,CC20E39590CA3788,CBF19370EBBE9016,0024C76660DA2FC0,518F114124591A56,3EFBC90B86582EAB,92AD58C73CCCE0DA,9884BE0E18B0045E,55E86890765E0267,42426C26CDE3F226,0801C61EC1D6FA1E,002C24F9C365C8F4,BFB072911F968325,2CC767287DFD2E0C,081EC5D3023E1418,5ED6D4C334DF5B82,545CC5C625426700,4D8CCD29B8B4CD9C,1BC26D8A9B7BB413,002186C0EA5FE8FD,C27E82E9A23E958E,255E36BA46008B70,07F18D7E20A14534,3298BC769B3C7F38,969EC923F6A6DB49,49ECCAA2C7ADBF31,B61E25DA7C833615,0027F5122682BB14,480D4A743DB39C25,633F284BB0CE9D2A,7F9590391E3AAD60,369F35B68B79414B,FDC04C8BB49E35F4,7B8664235AB7E2A6,543AB51FFE2C9F12,0024F497A7FE7B3B,23EEFB806790198F,A05654D8DD340282,0745E963B992213D,11702C8C24AB7823,9708E9A379A6753D,BECFBF928BB277A3,1DF1C4A53A5A7956,000A221D64EB8492,910D19C0950FA5A5,180FD208CE5184E0,E06E0F099F0C6076,F329726401150BA7,F5D8F50643E656A3,ADB549EA653EF6E8,A3E02C2E3D9985A3,0002F8F232344363,62B51F14C44B91F9,957E966EC10E7F6D,91AADE7AC552D0B1,DC99DECE5B4C362F,78DFB4D10EAB9C85,6F4E6BB844DB3F14,90E464ACA19B0745,0026D03F8EF3CF74,37AD830AD8814961,A2BBFD76CF5246AC,9F04A15FD7447E85,E15A809E0DAA1E96,72064F66CE001977,F289D7BED9573DAE,CC9FE6791DC8362E,003F20D834E0B744,E558ED082D0137E9,9C5A7CD0628E2E29,0D01F60184080BF9,0307C6D608DCA5A6,AD62DDA0D2A59A4E,B9C88B007B5D5FDF,3DC66C4D28EFFCDA,002903A9A5F94F01,565B1D0AF835F59C,712763EF094C8A32,3C9C312D67C1690D,E57D3DFC825D6AB7,9E466566F285A80E,04868BC07D9D7B14,39CA4B4057AE0AB1,0039979A29C0D4E8,88388083744EE657,13E4DAC613A56AEA,A74501BA8EE5B755,937D7A5591AF996B,FCC29C7AFBCFAEAC,B13E91D570A24038,02329100C94E68BF,003A4A1ED8430033,A8F1A62D61B9C5F7,9F06CFE521352E6E,689AD283D1929474,51B8AE7E93CB955F,DA9E30B5A00E8A17,6EC7DAFC75123EAF,623DEF4BD26233FB,0027E693FD99AED9,E55EFD6CA67363F6,667E8F1781D7247B,BED3CC178EE64916,AE0DFC0DB82C41C0,9BF2A00E34959AA2,01029577E7BEF555,63C952103FB7E33A,00110F9331CC43C9,B7AF6BDB373C17E3,57771011CE7D1F61,EC6ED4D40E746CF0,0677134A1B780DBE,2721F0C56B02127D,54FAF98C67C26C1D,C10AA605CA9AF6EA,00375F168033C09B,B47207519525517F,D5CC3F3D3DB497D7,720D6F4890055F8F,B269FBF5033F51CC,07A4050C66494A4F,2847C55076204712,967A543587663DC4,001A742409129697,9B3B874A3A809E25,80BC1FCB61279C45,AB43EDC5617F73DE,19FEEA46CBAED6DC,762C07CD3DD9BF7F,7DA2ED18F2ECF08B,5B689E6FA9B3ED10,001D195BA4F91610,0E3127253D258A7F,0835AE2383F87956,0AB749B1C860763B,9F08FDA1C722E104,3A9DFA5F869B8B60,F882C4207FA1EBAD,45AF26EA0FA83A3A,001FEA5452DCA751,C69E00D546EDF823,FF5C692A14781A9E,57DEE687CB328A18,988A8F901B161067,AC6743A1B6E32BD8,F80DBFB4FD770133,0A8B6BA37DC146EC,00065ECF08743274,38B38AF41F60E091,5B387F22C32E2709,C4418487FAA82F4F,8C26E9EC16DF6F54,B4B6C8DA60925226,CDC087381C0A4227,2F8AD41712C0C541,003F13A97169CAB8,EAC9E0DB308802B7,1A16F5B8A918CA46,602DBDB588A8FBCD,F37CAEAC78434C0B,DAF015EAB9FA8F73,0F042E5FE67D27DC,62A6EC7657B5084E,001ECC785562274A,56FFB3785B466E33,18D7BE2AB7F019F0,F72C59FAF8CC4A41,0D4F79FCBBC3480B,B6AA296E4867DF2E,B1BA53C1182CF708,549A28EA1ECADC7E,0033A738B6BB5CB4,AD04409DCB0FB96C,6D0D6C648623083B,18087CB30F213935,8D18D8EF73052585,5A1F9A5C554DF43A,86D5F1A77EBBB8AB,D5DCA81E7E986D40,003AFC52302FFC37,6BFD476CA06A15B1,29C91298E4503692,BD91730E3D7855B5,0C897D70677B4DFA,66B745BC5AAAEB2A,F4F63990B7264321,422E17AE4BA04F4E,00084E23815F7812,C0D669B8278150C3,38C28A60B97EAE0C,D2D88243F6D46419,5FF9E705641BECF9,5ECE3A4B9188D82D,9B1C88E4182D864B,4F3692A13DB9A7F5,0009ED18037A56B2,FFE0206B64885FAC,4B94E922ADA5EDB9,3448B88A8B7041DC,2F1CCCDE7877B90D,B47F9E7A942EDF8E,5CA99BB3A6A5BEED,A23AEB9C9F2C0401,0005AAE02119174C,25336BC06B3481A2,7E99D9DD3203BB41,51886F85BC3356DA,8A8419A144093146,D1143196C757CDD7,17F74B426BF04BF2,09834D0227A11F81,00208EAA4A9A864F,3CD441C1311872E8,8F1F0236E880D7BD,22A29460CF09BBE5,7C28E9820075C69C,31A5F73B381924FD,60619D598E1F9BF1,1672CB70C0CA5333,0027BFC4B40385AE,C9BA30505D07D746,E8CB40E64476B37B,96F439756D0EC2FE,A852E30B2B86C7A9,BEA9DBFB9090215D,23A694A2C1D7E14E,202B6F68C2A836A0,00083A3DE1C0DC99,1CB37B5664430C87,51C862107554B667,C9EE1FE4EF747CB9,FE9AD5445B7E1E52,176E0B855C1B9F4B,54843D0D94A1ECC7,4C36EDD5DA17D044,003A21D99CF4834C,FD44397230A4CFF9,CECE75B0BB0A43CF,AE61910E8B3C3CBB,181D4471E2489908,87B79A6B443CE4A0,A94C10AF464D7218,4ED1AB6DED04BF8F,000833FC8FD03922,97532038CE89CFAA,EC2EAC72BCAFACB7,3D9AF1A417D1D333,DBB84E7AFB6D8C8E,698B6C2738ABF59A,18DFA6EEC1766D82,4B3C5A5012E9D449,001CD8C6BC87F32D,3EFCBCD1C19E730F,C0B4567AE679B831,86EA018D8AB73F8A,281F2CD7920DA3F1,4024F8143BE78EF7,E9D097C730CDF840,6000C81CF9884BEE,003785C4E22B56FC,9789124662F47E77,C7DF4E2C97CC287F,B5FECD312910E6F6,035E3DF391752F8B,5BBF33577397F412,C2407CF629B88D80,2318DCA9444EE36A,002C240052D2D386,9B6F9F47F61F6F55,8E107B386A625D9E,5FD707A4E2805383,4B8B888C0566EBD4,80A6E0AB7924CAA8,4BA47FB859A6B8CC,2A25527E2968F366,001BA2570544777F,08CCE83EFBBFF0A3,888A467B64FEF15F,AF0DE1AC396F04B7,13AE2B5EB7679528,3F5BBE581D2EC4C1,29EC3B6FDE0580A7,21888AE28EB6606B,000A61E792CF991C,1E3621A31A8A92BE,270B2FAD63379479,3881E23DFBD671DC,4DB5CE58A92EDD16,FFCFA489F8BDE456,7E2367F57FB4ABD4,6A4A531C6CDF4030,00380A79D798AAE8,60245F76DFF6C972,9A420CFDB5C6B0E4,94EA5BACF8A7DAEF,8EE8AE4BDDBC98AC,0AD1B560A4A8E10B,F2D772A83B20E67D,91449F2B3EB6C6E6,002113E8F14AFDA5,8C2E4FE3EAAB569A,4125730C1E693985,4836666CA244E85C,AD4C466F936CCDAA,9AB221E67FC3BC61,D9A6A1D84BBB6E4D,E152AF47D55D4D75,0016DDEF67CF2A22,2DD4A7816C53A2EB,38988F44A96EB41A,43C87807AD6D2CC2,FD5F6A88688DE68A,88C919683556B788,C7D96629B6F26B23,DB66426689AFDEEF,003B4AE6315AB9FC,DB6E7AE7E471CE46,8DF093D6D33DEEDB,7173D74724B4C1CF,C0680083487FA284,AC3E9D02CEDB6DC0,D813D32FB373B950,423191987FE93B63,001649632424642B,109DD2871C409A14,1154A200B0D3FB55,9242A59750C36AC5,3B6A4E7B11A2B1C7,10FAB3892F148D0A,9AB2E83FB7A508A6,A76122404B9EE147,003A2AC679B66EA9,4E68977C7BC6A2E6,DAE2386270C3699B,BFC14088BE82CBE4,116C9CD617A9919F,AFD59BA16DB71920,CAB6CB173B0F3821,F45D270EA8C0C581,00229522B55320CC,4EE675E3F0D307F6,BBDF8CAFD5231F53,A3787B1F94EBF2EF,9E6695D7BB1E1588,B125EFFCB98B4C35,9AED1445F392B57D,6235C0BDDAD2210B,0024DA6B28F0E1DC,56D6BCCD42351605,5F08BBF217F30F4E,FCED9077CD9F52FA,20BAB3962FA35B21,424A3B878C0131F1,36F198135CF8CF4F,E423D51E180E8CF9,002C3541C8063F7E,16EADA07D7EADABB,CC6C6DA9A72BCB9C,CFF1955462BF847E,3646EE7870003DDF,57039F385196D963,984BF200D334DDFB,46407F71890A1772,001D064F739EA165,0C0F032041C80E47,E408F0A903C6FD0D,71188BD4B05DBE2D,EA702E7D1B27777B,862EE9A9A2F822DA,FBF6F9B87CE9CEA7,305DE43BEB546211,0026F7984BD864F0,2CDD96ECCAAB1FC8,EE3741131B7ECB10,A76D0ADAA6615B37,697FE0A903CA86CA,72384D993C417CD2,D55F519225773034,7FE18B31F31DB694,002871880B35A5E4,3A6B1717F9C81B40,F9286689138FD3C4,EB703950ED3FB7CB,5EFE77502AEB068F,137798613888C460,95B1AF8E2F0A2BA0,BB61454750DC6426,0034894DFBBD01A0,76513BD72FD56013,2CD473CCC68A9495,13EEB62E1EC29853,099B3D00E0745D14,37D130CE959FCA55,C0B1CAF11A6BC170,CCA2567E27E0AAD3,0039642FDC16190A,77FC829778F00000,EAF128A6D7C1DDEA,6F601B912F955FD6,6898B96EA0394C19,A9DFF7C2AAEED369,4399865CE49328A7,3578E0F0C0EC523E,00311FDDC12E4086,3EED5FE37EADFDF1,C72040C9B6240C17,CA650CAA5019CAF3,49E71EE68053FEF2,CE61F9E170352C5F,BC3FE8931BDE81A7,5FE6E1E2FD619477,0026C59BEDA51D44,77745F48982ACAB4,49664D93DE045B78,5D7BE22421BF7CE9,CE5AF3D02D35F4FF,0A1381E7F9A55469,B9557B3A530F2928,6FF5B7C07A173716,0006B423FA5598E5,8F7B6DBD56234E34,2E7C22DA566E04DA,79941241C435D94C,398B2BC0E678D2E0,5C58FBCC74D1A0CD,67605E8BCA3C480D,7C40ADC0437058F9,00338C574779A302,D24B1C4B19A8D241,E6299D26FD2010AC,AD75A29013173544,70AAE8E16609AF2D,CAD88FB0353BEE52,A1159AAD663E5E56,5A08E33AFE19B228,00365E3BA525BC4C,9EFDC71A6C446990,12E5F073E8DDE119,496A027AA27828C2,6BF45AFFA1B0B803,3A37E744795975D7,D756B21E094543C4,8CE6A09128BB0EFB,0028D4CFCF8EBBF2,87D26451D951B2C3,CBA039CA404F1C86,7816D045D9EC1151,B3380CEB19E2E37F,F64E874A70B0ED57,34A6B746D9C458F9,53976F21D7749450,00312F27D2460E1D,63A5D0493568BD73,46B5D097FF51A837,073AE1F0CE2E34AB,C17C99D2CCE3BD20,1C2D2C716738179C,51A5C78566FC0A5E,0940E09387667B7F,0016892F4B6B711D,0AEB4A105123360F,225B432009EFDDBF,12A0E09220A820C6,904DA94E6E02D526,B86FA78D6301BCD7,EB27AB960151B6A4,4E9E2DFCF746D0E5,0005B547A564B5DF,0F37B3B6E8E1C70C,E9098BB8E90CC85F,69C852CDB3797563,6ED48DF5AB02D0DB,A8391AB0AE407286,E77B65AADC78E65D,DCF45FAC7E23555D,001D0FF193BC8613,1886E6951AF38C9B,80BE9746471C060C,C8C665AD6F6C3AC9,21FE51AC5480B05E,8942C4229572456B,B1A59AE1AF5BA363,45085E840078FD43,00081FA84D79CF1B,D8C00D358AECDA50,4F4DA0F68A2EE5CE,EC711704961B2971,43C1D62536A1BE09,E107C3709C8EC0A4,AA1D71730EA37034,C7814BE0DB32EB43,000655CAEA459A96,70913F42860805C2,E9F7096E59D9CBEE,B5D7DB5BF450C492,1A7D3EA9C653BC79,BBC2AC55C55F1A51,E0D1BA94C5B58CF5,931BF9D19715B0F0,0007C447398F2CF7,BCF03CA0837FDECC,80FE0E2D99A2D896,3F459D8782F47853,A5196C822A340D7B,C9A02B80E080B61C,57529718BFFD4349,3C8CA2E0E63388E2,000B2A1CED3EBF46,BB845D0CC077F345,483E2A9DA14AE306,32489F669E5DC9C0,51187E13CEE4A932,B6DC43EB618329F1,87D1392E3BF9FC7B,8B9F266FD5BD0A11,001CA33DF767D6AA,4F1D6CFAEE9AFFFF,43F5DD5B98992D4A,1E93BB5972110150,92DCFDB77CD5D997,73D88095D9BC2324,351E32F20BD36EE5,EC6748710AB60C9C,003DA9283CE9075C,7A1F02D3FC2865F3,DA6B24AD50D6FDB8,9C4043C3234EFBBC,664036CDDC34A1C0,CED95B9E917794AF,EA5195C8C9BEB8C8,F97950B82A8BB481,003C967AE4292FDA,DEAB113F1689526E,14E4225A02C5B689,C525E219B5F02CC2,C73E02EE4598F833,033A7DFD80891293,D0A2C0E1C28448E4,7BF1401FDF39144C,001BA7323047F36D,0E1AF0F753F4AE95,A8E0ADE490089E10,B1290E669378712D,955CBA5EB3AAED68,2CD6481A0287D674,BB213A721685E651,7F02DCF7DD770D5F,000C32883920E68A,D01F410CB9213482,24DA0D937D27D92F,275F09962AE71109,724C415279B94E4A,4BB4E4A6F4291CDE,7248C25789818688,80CDD252111AD120,00072DBE58024690,7A797F11B8B2AFCD,DA50C2D7442EFEC1,CE290362D78A8050,5008113F9A0520D0,038C98FFF202EB9C,9607B6E15A3EBC08,03CCC236DCED48A0,0036DF55DC7AD233,E5FBEA59673299E1,1031B4D679BD4A90,3DF780B95E0BFE72,C55C01FB72F68BE5,D8792F95C754A75F,C1A0E17D4322397A,585C344FF092983E,001ECC40CBC558AE,DF90FB64703481EA,C567E0DF26FF33D7,1B432F020E2EB58D,AABFBE1F62002FB2,5A48CB35535C60C6,396DC697F9DD0380,DF0BC199A29256C9,00085A61288B79DE,06B7DCBACE3C422D,B366B76CC36C1F84,CECA6DB3CCB152B8,62CFFEF48329E01E,C3A550561B88F300,A647A8409B3B575A,9C317043ED127051,002F09CE373E9997,768AFCE70DE0ACD2,3872F4F4B51F28DA,FD96B84C301EF069,B9A3CF73B18D2371,16451DDD4C835EE3,CDC454F322F72515,1E05E635BF3249BA,00233F47E435C415,D1CC8218007FAF4F,92F59D77FE623F14,F0D17D169EEF8B03,BFA77FA2515CF193,B1BB28D0D6A21A89,ADD064AA7605E71A,E2DBA7317E17441F,001E3508600AA4F7,56A43C55A9AB6229,5A2EDC2F2DF60B39,BC7185833B2DFF86,1DF86D60FE090361,40866B9E13C20080,AE07ABF346EE4308,455943F1F8CFF08E,0011B2478A4DDA34,2636910A50A222AE,7E5CCEE6C6AA31DD,B3C2132E72F87CF5,11C0904BB7B4C001,EF2F2519B2BEA830,2EA37BA6B9868BC7,12194F274CD7371F,003C053D09F1A97C,F2D3BAB95B59AA55,8B3ED8E5BBF66465,46443F5CC268F4A7,1751BB97BC734AE2,E4C769A85BF5A104,2865F17D958B504B,861F876BCC5CF36B,0003B3479722E2E9,C3398D9E32CDB3C0,F92D0D23704A2B68,CEFE8AC91211B85A,E8C925CE8A1BEDFD,66FCA8D8C1448F08,E55E57C65BFA0792,42C1B8D680EF97F5,0003F4CBD42D754D,7E33DD9C0508B291,41545A7B782DA3AD,CA44CD4D9DC05018,0AB82D342FDE0CD9,02C2849A7AF09C7E,7376E30813305516,A99240CD4551674A,001787E5C590F006,DF4B65590B8EBE23,5646722359657998,4BC261B3F431EBD1,BA72B2D8D1C719FC,4FF00C01242872BE,155D754F4F171FCD,099B3A6E87140A7F,00361268073D8C71,23EE09FC38A38A94,5CA2A6ED931255D4,30DC9BC211ACF9CF,3572C17EEE479AF0,19C00E8695CCD385,321395A672199793,5782ACC8BA269A67,0019CF2220D606EA,64553F4EC08238C2,ECA61D7F0B28179F,8470FE4D24D2D635,6744D9A71241B688,6CEE519FA3CF20EF,7EF696B8B65055DB,238A1D6704A4290A,0005CEDBBB086EA4,2F317638A12CE0A4,DDDEDB57ED7A3DB5,C59C818D6E0AAA69,F0E4E50F1C49A7F9,D184D85C26B771BB,B8BCA9B24C0C7C0D,042E8B1FFE1AA276,00032FD35D7B1E66,BA8374362CDED7D0,F8FF44F0AE47E84E,3547AA41ACCEB952,D844CEFB12551DAF,23C7234FF03B66CC,FFB39876142400EA,7EFE5390CBF74897,0021F8C8D7DD8535,3258C787F2B09618,64683CC7C15A81EF,FE09925E6C01034E,14D4D74E52272327,113E7D3ECB79AC85,3C6C0C8F7531ECE5,B5C2B667EDAAD9B9,003675AEF65C4D5F,65FAEC2DD9A995D5,6789C70D3BA87653,636B9CBFEF5626CD,7C13C5897B26CA16,5933586B00316D49,4441156984111B82,F82897490A361F4E,0006CB84100562E6,564BA419CA8129FE,416E5CCA3BEDD0B6,21454BB447AF70AC,0645BDC5B27E2933,EB1E5BA4A1AE1B4B,E82568B52D575DEA,17CBD55AFFBF3158,0005B70B5CD6625F,478AFA84BE10DB2E,625825A571496CD4,7A9055E8C52C87F8,C5444E1EC6E6F738,8EB75D96B98CA526,F70F76D10C8A6233,BA1E22CAAD6D49B4,002CFA1E886D0853,6DE09FB61A9A19DE,C2AAB09F07ACB7A6,2515C0F72DF4F5F0,C68B552B0019A955,8598298CE974AC0F,BC15D60BF55AAC1B,48026A10B8A7BFBB,0025A1D5CCFCB687,AEB71FA92720FBCD,A22E9A2E709832C3,C3029A8D5525D5F3,01848BC1654060C8,980931657D61284E,7BD7BBA61FBA28C6,827D9C6AE7646392,003C1BA89C37F0AF,9A4161BC3725B587,58FA59878B1F04A2,A48C479A9185550D,E6F5C3EE69077E6B,FB8419B35FBE3E1A,ECBF0E09B0A5B42D,94AA5FDDE60D605D,0006B88ED8C6405C,18776239173E1F93,DC94E06E1882751B,4D164CCAD0722B54,08EB979DCDC1D799,B78631BC957AA601,BFCA4F43543486C6,EE446198FD3E5161,000B58766BBC944D,C4B8975A9D395F18,AF25D6E45323B27D,663DC535281C3B64,1C68B8C80C9B2077,D1F6060C85B7F6D8,D69D18306BE780EE,6BE4E7C4B775F982,003CC2A1E92C1292,EB8556EEB924D98F,C3353172AD55476F,876A10D6DCECCA25,FAB630C3A5ED3129,F1C0139430E3DC41,84DE952C619B7CB3,850FD8CF880E45AD,001DFDC424DF1EFF,F557A98493F98D20,C6D026424A8E6661,3F9572E113E55483,2D9143649763CB4F,0F6B6AF891454E6C,902D61126EA9DA75,62966707F2B45021,001D270AA25D39C7,28F36CAD868FF1E5,4815209B71D3666C,C0AD2B911B249463,1565DDAA807027AC,5FDB93E69F4059F7,E4722876734A3401,709276BE43898DA1,003014A79E1008BE,46D478F19E8349B3,BE6A0C7AB2E68FA9,C1E6D203B73A67DC,C6BD02A1282FFF7D,7424ACA9808B0629,AAA835201F0AA6DE,1C48A087663A171C,00061A03F8F344E0,B25498F5E544A357,85EDCFA6B3734E65,3B2B9C8001B4E7E6,A5BAB9E7F857E73A,428D2EA118EB8FA8,BAC178D1DABC4D7F,FDD8AF86BEA75EDF,001124E5F32BF791,03F700892D0C08AF,2195DE84900DA9F4,8AD37686C7C1F82C,2CC4A6975521BDAB,86CFCE874ABC10AC,639CF5F0EE75E17C,EC7AD8B6A2348776,003C65668350E962,E02245EF3EF0446E,A2519734E0D616EA,73E93B202AC14C96,17E6F577F800F783,9D68B1DAF6F45A46,0CD24155FC78DA0D,E517653F3A2A65AE,00201AC648FCEBC9,EDBA85BE4A9BF3D1,7D06838173E821CA,7D759CCEDEC93046,EF824CF496F1D170,A19423D57D118AE7,3BB088FD952D36B1,2A029F0C13F6B234,002F0A6A309B3008,88E60D88369EACCD,05BCAA07CC895250,A1958CAD24EBFDC3,A51C41B3B26C40B0,BDD5E697E1A0E080,49423E35376CE441,15DBCD344902BFC1,00238F45CF1025EA,BF366D0EE20F7802,3312F33CCBDE8A36,00666153EB573E9D,BA81602D86C3A360,7B3E907A813033A6,6D68A08F642EE98D,69912C721D2AE87C,000E935E8910FA57,9382D7BBF76CF9C6,918ED62CCB496EC4,298EC96424B4A6D8,9495CC2F2F3811B7,290F1FEA8E57FD91,A43560638B6E928E,0E5560EBD3BF32B7,0011814622A6CAE1,AC0D05DBF786A927,3C7621C18475A444,99D81CC904907586,C5AE4FA701778CBA,1C66799890DDAF76,7BF7638CAF733612,A4AE198D26698FC4,0032BE973AB92A5D,8ACD2526B9DE4857,1989127BBE454DDA,FDAE206BA572C52E,9431A380B7A9CC25,8701EDF5D2CA3B75,991A8C8923061CBB,CBA3B649461C7205,002D88281DE0D3F2,38937BDA3DA2B83E,EAB2636A06B51FF5,02B9DD0AAA7B3510,4D011578E3F318E8,C2A00C742ED0D7A6,E6277665AF36967F,78E585F448F21492,0033A81DCCA16EA8,DCD9CF863272CC7B,104FB1BDADAD5B6C,1DA8B19384F81C66,92F813DC529027F5,8BDE6D560965AFA0,6B972DF498F7A109,3F47A0F16EC4B22C,002E742BF20FDFA4,94D1B42F37332550,C934B42EEEA4B534,34CF84DB1017831F,530588879137D9DA,9284227EA9D2539F,879FD9EB44C503CC,124CED33BEC92FE7,003736ACB914BE6E,110E7C3535755708,471B55450D418A5E,6552AB08D2ABBC65,20C52DB14FE5A96A,8E6599F15BB08FD2,358FABD6487D2277,DB0A49F725184C4A,00296EEC22506EC9,CCDBFA5EAC4A1A71,B01B71CF8A231A25,CA4D7F8AF59CBD0C,3CA424796AF38C22,F5C87C8BA7F1CB6B,AFC351192A53A645,F5E73C3638E5C618,0036D7BE734506D8,267B38A7A622A942,660B5BA3881D2EF2,4B8FE22DE7D69668,25E66383D66A60F9,1965FD83070ABBDA,9F463F90FB5BF865,F8714D20B6FBB771,0002722C88A4E16E,7213C37B2FC80363,D3797C8E971B3E25,10653960F29F860D,27D354E56EBC8D49,D2D999D5EDE35C17,FE9D90FF70D369C7,67A8BE443E32C9CD,0007E17A129A7BD2,E40D73C35433976A,A34A630879FEB60E,FDF02621AD51314E,82D4DA737845A9B4,1DD3DA07E2A9F22B,408EF86A785CDA59,9DA0C10595223B58,002BC9703A041074,F460827A9BD9FE1A,CC1D7C413D7E3A7E,B12CA7A99B534086,B2AFB805A89D104E,A57011994979F79A,371DD3D08A5BB4B7,9336870A6BA1F09E,002C3EB59C6EECA0,D6E4B0034D4B334C,130281A81CD3CC48,A78AE6FE0C51A339,0B734C3AD74435D7,A7884159644A3810,8DB9798DEC21517C,B70B5A73FCC51512,0010038EF80FA130,63ECB7C3673D3CC2,1B78D61B468D05B2,7751E71AC78DCCEE,C496994D07875361,AB8CEDB39D5E0431,25F99256F92AFA91,8E931813B3980431,0026A9E8E7A65D13,262BC360E817EA6E,3BBD56A42DA364CD,731098BA509A3B10,4F1E3D932951BF31,43B03A48A79EC455,15CC578CB399E0DF,0786F85ED35FA9F4,0036BAE3E90E1CAA,01CAB5E35EBC82E3,0EB7444B04893173,6A3F2554554AB473,87871D68416E301F,B12A8656201F990C,02B37F391FC1724D,D3EC4E2ECEEB7E01,0025EA56EE55BA5D,EECFBBE7AA220CCE,91747775D2C4DFAA,73F7B89C05D8D9D1,5CA6E595EE9235B6,20E71AB2738CF201,8BFCFFD1A6C179D1,801A8C3C401DC4A0,0002577B406942AC,40AE2F5DF62CC300,74EE81427BB0FA22,3C956AC87935C3FA,DD468C6A9742CCB4,D4A1CD4B37AE1954,FF95B7B5E6A909E9,410864BFA95B9CE2,0021F769F786A4DA,7E3F354B6C05B979,01776E96794FFBF9,30648BABD2FFD3E3,C3ECB69F866B926C,C4345290B791ED51,DB51D0F3BE30E3BD,331F53AFE9E4AB59,0002D9563A7C60B7,89AB94D8C74BE56D,F6CD9F10E3F25460,56781339E7ACF49D,D93757BF8669758F,EA455590CB110795,5FC681C88DB1FF9B,60534224E96A50FB,000495881CCF95C8,8D594E524700F140,CD9E5CEED939FE04,5416817FC5A89076,B418D387AB0B68C4,44F9A976E6C20BE5,CDFBB1FFCF70282A,5884C8439F586695,0032251342528D0F,0D684E7F4AFAB737,AE91087766BEF656,9C9FD976AAB4F409,11DF801665990BA8,1665037F8A43178B,2FC235B1192A737F,559D6A78A87DAF79,002A09FEF7306245,80732666D09369F6,EB27372C92E43165,8476F8C93CFCDDFB,0A90566817B18264,BEEA8B5B55E95C0C,0C1E36F7974994CB,9C0CB9BAF37A7CB7,00134AABE8E4BFCF,75418A8EEA990361,BCF037C429C5A9CF,4B1DC169E3F57C6F,70A7288257074198,42402A4D219DEAA0,A9FDBA35193BA4F6,EEB1F8A918C61C9F,001C7EFE3E1E23EA,5E074C42CA0AB55A,A665C7D361E4C6AC,9840F3FB1C62F5FF,D49A7664AA6099A9,5D957A681A458FBB,F93A6A787E099BBC,C308AE073DF423C9,002AEC8BDA9B4067,3E53FB1D1F12A228,3F28BEFDD8030F6A,4D38E13EEE3A452F,280F38B00B09DA9D,6A85E3207D55BE65,ED4B10EE8EA8396B,8459CBDEE1CF7588,00201CDBE141FF60,0CDA40E811E4D22B,36BFF03139447624,541E6131DB13EBBC,6E6DF7BE36B73778,0129CA1257D45C46,987DF5402238D3B7,E623DC7ABCE58554,003B5FB1B5A09576,5860E85793124054,4E310DBA83991726,333CFE8A0466BDCD,E5D3ECD2593822A6,10F569C96E6EF341,B36A90D448717C43,010C0E346A832802,0005072061357AAB,29A8B0172E5F03FD,73ECDE6C66A38947,39CFD14E1A414B12,ABB38A8882DF5A9E,526D7822ACC80C6C,829FE44B4E9CC2E0,CCE3D4C46018BB48,001C3D1A106AC909,86A0D3B575589DE9,8F8FD6BD0E2DAE10,6670A5CBD69CBCA5,E0F76530FCAD6FC8,EF0B7284A48A9ED1,A4DA9DF2CEAF14B5,F5C44A6FB2CC3C6B,000BA74A32400D0F,83349A51BB99A27A,8B686F994290D6CF,E216CBFCA7DD72CD,55DCB395D20E8DA1,2A9F549EAE620549,6F9028A9BC32AFA1,99D5AFEEB4909622,002823BBA9DE6877,1E1A2932495295C4,5261239F7BDF6730,9486ACC38B50E329,84AB61B25B3C1A1B,85525985DE319903,87A83326262129D1,249CDC2C0EDD73E0,001511E32EFFE4D1,6F7C841494186E59,F1C831E33E67B606,039E00F6F74408CC,342E63176804538A,C5B145231014DF7E,8B58B621204036DF,F931332393B182A6,0035EEDE6BF1FE85,B0D6AE4F449DD80A,4773B885F6741745,96EDAA7043329226,E5ADD365254B7C59,84047DCC98248743,AC83B0033A9917EA,75A0A11D212E3E78,002F054D0C73C5ED,25727750008ACE57,D1993E59BB9A0E6D,F22009FF61908E1B,F097BEE51BDB7C1D,53DD49E791C0F5C2,D0A44B136869B249,3CBEB02F773C2CF5,000F433DF900E303,0520352A156C4D9B,FBFD642F42984F1D,BC91DDD096AC62C3,5F06AF772B326492,D4AAB9D880DEDF2E,A5DF2B303BC925C2,4CBF75C71F17EC5E,0028C8453E898D1B,2A041AC637127AA8,02B815ECC718B007,D9F605CA5C10AFE9,F04DC8AAA9D82477,F61FACBAA3F6907B,63E8439E510F6ABC,138D2DA15CF9E5A4,00019274F44A0DF8,6BA6433FBF0FE0AD,4B2B1617F65E5514,2192403E53EA97E5,533E1AEE3340651E,470F457F3E936596,373851F27405D24B,282E2FEBD2D0B421,000D1B044B31AF88,E21E7A874CA8E24F,67B0042AFD063DD3,A39BD809BB9F0986,A915244EDF367A33,B6E734BE5114B21F,45D4C33BD639E509,4C1DDFDFE8275398,000D115DD03CB1EC,9944D7E7FDA0CAD6,F515D6FE7FFC7B45,8B086046203EB907,C2D4D8BC52BCA998,04390F7EDE611DC7,4F0D5DD4CD0E43EE,929193162CC6B0AE,0027C81D27DA5349,711CCBDA596520C9,168D8E450954F169,F8DEE6637D2AFAFE,1B1B947410BC144D,4592BC270BD260FC,622136C93AB1CF1C,A3463E64B008D832,001DA72B18A46930,34106FB04A62F229,7A31FCD09457C38F,94BAF4721E859397,7B898B4FBC829220,F3E963BC029F9671,26F8DE25A95FDFEE,EA67D08E295FA535,00228B9B8DA567CF,DE1FDD9E9127506B,953534C4A859AF7A,BDCD038D47662B96,A29F018D0D15E1AE,30D9A7B43032D7E5,0D1C70AFA31E0E3E,0B4A7A350D9AC85B,000B2698B9724EDC,1FEE40C6FB3E02AD,CD855BBD7E286C9F,A5BF69F7A275F379,129E89522800BE43,1E13CA43516E09F8,DBD08E60CF679B8A,7D44CB9D93E5EB69,000F6FC1EC65AB57,5F1838A150EA16C0,044F801489F8A3BA,7A65D67200634180,39AE9B661FF2AB9A,FAAA8CCDB3DB44CE,F5642C900BD244E9,B8EF09F22952090D,0030D8483DE12EA7,35170CA3BC88D828,6C9923552A27497F,43122EDE1CD06FDB,D6621034B0B490E6,C5345E91081B91F0,06AA8BD17949798F,F6463D1313D6F420,0020021EFF91004C,8969BC44A616066F,6E3966DBAE4C2B61,655D4BA97E1F9934,E74616F5C1EED2B5,0A8A95A5E66225C6,72F47AEDD0F948AB,7D76E76745C6DF9D,003429DFC72C6FFF,FCE7FACEA02A3B99,A73FD3D91EF7556D,B374184B50A96F62,4543A018F1C47B33,706C9C830C6B1054,C87E2207B5D28A7D,7FD648BBF65C39C7,001D6E28C3AC2AD9,FB34C493CF097905,A0D629CFAC520683,F61D8829822F486A,49046087A7295686,5FD65EE4BDFC2DAB,88C93C21E484009F,A4C7A8EF1E83F4D0,002C218ABA525526,A45C8F644626CA36,AEF90A4317E53799,277A53D36145A4B6,6CDE872243A7A89C,48E0C1B87946D113,5DA348A24CED3C47,FD4D37C875A4E4E8,003363BFA7F05101,0AD198D74940CF56,6A341D71C7F61689,36075D378563D624,BE05B4E238F63F56,AE60EBCDE894456A,8A997E2BB92037EF,12217D564987CD9D,00210DDB2A4DF2DD,2A52C1B93F8B0027,86168836280C71C8,683B7B03CAF02ED1,AEAAC66DA55B5E4E,AE40AA7A2B124D72,786DECF0692015BF,35B21040BF9378D3,003A352C16C187D4,77BE3AC4EDD8D296,3EA9C2633E9E6F95,F720DDA9ABBC2BB9,90FF62F1366915CF,66C5DD97BBFEAD9D,CAE52B8CDF456583,F20A5ED7E9AA1CAB,00197FFBF26752DF,FF80B0547BB3898C,BF4C1C48A3B72BA2,43765766708B51ED,82943FB02AEFE135,D581587526D7C241,C8A4BB63A5A69EBB,34775463857A091C,0039FC134C639AAC,A8F9AF19B16CE541,08EBECB586533D3D,CCF3EAC42F3C2A96,4E8D27A05550F281,CC6A3F94BF581A2B,0926BBEB83C90F9C,3A9F2793048BE93B,0008FDDAA3319232,09BA99AD3D45472B,DE9D5CC6EEA6997C,3688E594B32D87BA,5F7C05BAB42FC2F9,E2E59D992EC9B05B,FDB055932560431F,B3A52ACED482F690,002591A50A0B4969,6F0C3156ADED7871,C192469E402279C5,ADAB39BF8DCB70EB,6B3B369AFE9C63AB,0853BCB4AF3A4A76,14BFE771A28BE137,E75748C99137061A,003865F72D81280B,B6ACD8E50433F47D,72FACCF526C96855,4CBD656E1D05C5EF,0BB936895A6CB2B4,7643549AF840FB2B,51CD5E386CB3BE34,9E87B964E978B208,0004C3DB0392439C,7212FB9357A2B669,B45AE5FA705C8B5C,2D76A00AB3DE3F6A,E0012237E27420C1,D3CFDA5A025A2ED8,984D8BC7697E2531,B2EC207504A1D7F9,00195A87C62C3036,571679FDEBDF5C65,5C76D009DE3DDD4C,CF2A9DBA497E1109,83097B0297609D9D,53ECEE09BB4628A2,86422F4DAAD67ABD,A24FA1E161E86317,0018D2046907243F,FC6E1B8E1BB4529E,8C63780C8D17ECEC,9A738A31D62D800F,137E1782B0FDD9A3,0D88FC3AFCF6BD31,064600625ED8D451,B669224C15470883,000ABBBE1E93B4AF,35242AF4CB84BA7F,5E72728E74E21C37,2259DCBE4B310EB3,A47766AED581FC0E,809A027E5DD22F42,71C646843C33097B,E55418C37C80D247,000BD30A503F01D7,4CA593109B79C8B8,2714C7265F333AFF,50415E9236795D51,DD96A4A28C10869B,16DAB9C2CA0B9D34,19BA498BC17DE4D5,A3C5EA83D12BA7C8,003513B82D252A17,56C14AAE6EB2A80F,77991D5D810067D5,8BB993D3EA89A66B,7BC056C859EBC3D9,75D4285F33CED114,745E3BF846BA1738,4A0C108DD6C56140,000EC779155C7FC8,60C63406C7225904,5F409087C3E2CDF9,3A59176CD92F768B,F225F430EC316C75,1DC3D2F413DCEC86,D6608BB33616E106,4F68CDAAB1148080,00142AB86153D619,23448B41E8C17321,C33BF6857181CD9D,71D46C03F2D8EE7E,9EF17B050951C832,4F07A1C506F07234,5BFE5EEBDFDE867C,C50B322C86EDF8B6,00166810531559CC,2209548D913B38EF,368D964183E3997C,B0FEA01CDDC0276B,78EDEA22B1FCAC97,B8F80147C2CCE668,D7FB764A7FEAD7CC,1579BFBE2B14E3BB,001A49200C7DEF43,F3BFDF576C97C30F,A63E00656BD05693,49AAF0622398AD29,97CE4A38B67DDFA1,CFF45CF7799DCB68,A45E07A59B7F26F0,900FF2AC65082DDC,00304C982A639F2D,6C54E61C4D8AFF22,E499E418DF2E69E4,0FB374E2FE7C87A5,5563403995838148,CDC1466E7F115DA9,290F0F4E7A57D03B,DD9374F33546E993,0024183D65C3B9B7,6D75C67576B58D64,297AE9E9A931C5A0,818C17051F7DAFB9,CF6F833412B40734,16BA7BBDD27D592B,63D70627B2191BD2,F372A8D9F15B6B3A,00363F8BF1B8A10D,EDB07792337BF80D,644354C86018656E,B649CBA6530474DF,69C2D554DDE9BF0D,CB459BF53610682A,B810DAF25688B50C,C58E5B7F459602CE,003F79F51F258258,43AAD1CCE981A467,4B46CACD178F0F56,0847139BB4D085E9,AAE27CF2D515D20A,19F7ABB41789152B,09E7176F899CDA66,3A407A92764A3F8C,0006B599CA304D42,03C2C4BD365D12BC,3A53078B6DBF1C2F,C4CA46AF4BB64122,60378281BD23E0BC,CA3B4E4A36C1EFA5,67A35C8F74D073D9,7E26D71ABCC2E5A9,000392037B604BCB,E08ED4B6C565B01F,80E30F8D935CC09D,C10F2BE175AF6623,33228C5CAB1C1A38,55E62B01FCFAF570,CE6E19C25DA9D61D,24822F4DA929EDAB,002CBACCF9999D86,A3239A6268BB0E53,0AC22EA0481FF3B4,070B4DA35BD96B93,8CD75B88162643BB,7BA5FDDA74F840B2,D0C9043506FA1F37,CEB30EBBA23EA6FF,00051377469B489E,E2F53D51AD51DEFE,B60BDE1779E57B59,F6F30D6A2CFAD4D8,DC0F766F3865885B,3B74EC9DFD96C115,E8548C5BF75687E0,3D81228357C91CA2,0038848FA8EC1C2C,56188BDCA100C589,88820D2C3B6A39B7,14422058B4723D5D,CD5C610A8679A7B0,70F665AC1CC85102,0E6BCF9F072F834A,F1397690A54844D0,000779A56DFBB8E2,5CCBDF7551EE0930,24A36EC4CA36B035,F6E85236A8A540DE,65AEBB757E9AA6E1,699D659BD447A3B4,53BE8D2FEBC5E64B,18DB529B89399078,0014EA5A0A6AD238,FA901CD9AD073EF3,96C779AFF12A72C5,15A38ADC40CF283C,9733EB8F68AF7D85,79E845DEA3860B29,DFFB674C481DD4CA,FBA273CD0B061ED5,0001752F0995CD92,30200442CFD66DB8,9C0EAE6BAE49C514,7C33A3F3BBC78721,70AC008944221B98,76ED6AC60D9489BB,0AB0AC5EC057FA9F,840B42467BD3F4ED,001E084EAE9B0B72,C1144482B1829265,004302F15D0845D9,40D24042BB5FE4C0,C49421D16C83E4E0,D480E7BCA4FBBC3C,B14FEBADECCA279E,B13D7047893C069F,003F73971D7B2722,2E69A4D7D9928FEB,02F330172251715A,6D5B53E9B6E9267E,83B4C597C4C97135,0549BA77EA229BB9,5AAFB9BD58EC5311,33D4F110F9AF08DB,0014FBE25BF18AE5,277F6532B6199958,F5E1AD79E43FD360,917E208553A33E45,A259484DE4344CAA,FC3EE867640D911A,657B31AD6F040DA4,560E410EA4DBDAFC,0028E3F8D735CC48,A4CDFF1E52064B22,399E2B41F5D164D1,32B95524CC470532,9684C01AD19A2A0D,165998A02D380F89,3B1C312BD527D3E1,41F757F47089A2F6,000E2E25A970E111,0F9460FF74E76F3A,D4ED74060E71954C,85959DE61DB0C62B,E463E1C5921BC3BF,E815396A5E179A00,9842DD302D39C02C,AF783C9EE2B5F6EB,0020A12436AB816A,65DC0459ADD31A22,03A57EAB0FCE7245,EBE3D307A618155D,335D0CBCA3998797,4E87A269E86480D4,4A426B58CE0FF01E,A4C4B8A244EE3EB7,0010AAF1F4D09A0C,239B7ACF5AFC0EEE,551CA0A622D6D72F,F5205307AF40EE9A,98853A93530ADA3D,7E06C178856AA090,B79B07DEB31460F5,9D2415ABB98CF87E,0033F11D2AB19273,DFC775B5D2FA71CF,78E2A11D02DCC951,257679C32727793D,889B1F618AF65BAD,02179C815C6280AF,90356696635DFD8E,3592F1A102F68BFA,003FDBEF0AB70470,E05BCFD22DE23218,96DFFB8F98C739E5,E68CAE0E6FC9AB13,0DE66E5BD701177C,59372792CF7004CE,AE83A4D2037D27E6,1905E0A3C0C3E04C,00219083BDF9F0AF,E3F10E2E22906FCF,1AC048E2E9B55915,F7F51CC8D34499D2,207BCD02EDACDA48,07AF274150678916,038FCEB81ACF0C4D,58799E938543BA27,003717B7C87C491F,AC65A773271EB2A7,F5B43175BA3AF624,CEF2DD7D71161A75,176620DAF38D78DA,B4830523D187CFBC,E346FB6FEA14DFAD,6601DF7D8F0FFB15,003B0FA29DC70206,501AFD20265E8033,0F0828EC3CE50633,830026CB5507BEF6,60261500179BCE1D,9462E61C554187B2,05BBD6CEDB08ED02,3A05C8097D7323E6,00052D1104A3C254,B866846856AEAEFE,CC4CCBFFAA88E97C,EE9F99EF6C607FD2,7ACEF93234288A88,5F04CC98EED5EA67,62D9DAB3716CC59A,A6CF2B12FB7FEDCB,003AF7ECFD5FC03C,74B51F6415E8BCF0,A3256EEBB27C2104,F68E4354A0693717,EC9AD9458C72BF0A,6699037407FB5B4A,17EB581B93AA78BD,BEC67C7011ACE5B9,003FE021BECD09D0,11A7F372BE51EF30,0E631431AE26021B,8E03AB4942D78D79,F81E4F4142297369,B655F8A7C8F6B186,CB92A75D3BFEB9A4,32D1EB0E8AE5CF55,0002CCA516D03F29,197103B4C07AA213,A625B4AAA628BA24,C31EB62EF4FFD6B5,CA42DB500E66444F,B2754DDA4A217135,C444D112FC86315F,F18343C5628625F2,0015AC23BC61F5F6,A7F5B388E6C2FCC3,E150205E19629ABA,89713839489402E2,4700B9D9114482EB,411482E97A29EB97,FF89A22342627760,5BF40F47D655EAB4,0012E6A93C4DA179,E98AB47855BBF436,D7F067F63E078317,236E63E9E0609CA3,AE5E2678AC5868F8,549F296761473142,86EFB11990031A69,509B7F34EBE8995B,000A3BF9550B746B,70EC83992704A82E,36F79A98DF005A22,92497E33D3602951,B72A4C4FC4C8E5D1,A0316CE07EA5D32F,7D7EA177662FFAB8,02C64F07C1EC193C,001491A1874F1EF1,F0D251B808E33DF5,993259322924B31B,A0A0316288FC4EB6,D60EA58C52F8720A,B39620552A9CA5DB,CCC1774B97BC2CA7,FEA16D503E12800B,001EBACF089A0E44,6857B61D86F7E211,CA9D1A74D8515FAF,51958DC1EC0FC2F9,F46090B7F55B0CA1,D305195746F0BDA5,56FBE338A5B51E3D,3D717D7F9A7EAF52,0003EA30F5D1B4FA,063E622A27DAB676,9144F8A3D42158FD,D5B691AB3498F211,0F41FABD870FD190,075A622D0585CC3D,EE24F665201FAB50,961F3F71029E68EF,0017772CEF86E706,B6218E855B59E3D8,82E16B31BD2E6CD5,2FAD1802A97A0D74,0F7D461A1DAB5495,3FDECECF757DC160,1F95DC06A58C8DB9,53C6135318F91E78,0001D275E058E185,96B06DAD841D7B4B,ED7C5C80DEF4BCFE,0E7E41F501E58976,0071A3308AA340EA,11988ACF97B9A640,46F9E234F51F0650,D11CF4BF4F8F8B05,000F4CADED4F315C,851AB84719FA1F37,FAC73051A01E6B5C,09400662627BEB04,1C72A590629637E1,3A284E5E1B83CC57,5E1CED4F5C12E50F,2F12492843FBBA48,000C75D6D9B1BB65,732B451C4AE5A7F9,4F059DE0FAFBC8D0,7F014D66EBC6954A,04371F5E269B8FF9,0AEEC8369377DC39,D63A56F349199E0D,63E71B2D0F3A7B2C,0015EDA643525B8A,D8BF593819763F63,959F62113EB97ACE,497ACC8011351261,6897BC106D2CBA35,14B5F7273BB06585,AE7746CDFD1DC0A6,5D45DE608B645DFB,002EC7AAC792ADCB,37593CACC60494C4,837AF3D4AF41BB95,7ED1F868DCAAD32E,E80CFCDDAF1F8181,F5ACF4D16DB0DE62,E6D5D0FCB7D0A07D,DBED490CCD0F4542,0022B1066845373A,C81F667BBAE3E3E7,3C787F55B89E8637,7A0BD4F2C9DA961D,3562FAE5657A2074,592728E18C486061,83A95118E3ACE45C,6D2B715C380DE234,001EFEBC39397019,33C3A84930892384,1F2652EA401BFE03,946C2521D9EFBBD8,5ED2223C2FD216C5,D2A70457835D600B,29F7BF29C67BC166,92BFB805F16E91E8,0019782573DA13F9,16FAF4FCF5A9BE7A,BD9DCA2B0E062981,2B71187D7BBE97DC,8EA36E895556D91C,8D1A15D8570C609A,5CDF060D893EF308,27C5A0CC331F607E,003121B6087B5578,4A94ED59EA487BD0,EC7528C1D5F019B8,92F163EC51BD301E,D1CB4CC6A66D8FF9,98035B66EF6D0866,0939952B6D90BFC1,7CFB1682527E2482,00052481F46E5BC7,84B5230328710554,47331344CA62DC43,74D0F4BCB57A6481,F881CE26A110E74E,3345CE663BB1DFB0,7B0FD7371A29B33B,AC3710FB3458C1EE,0000DA10BC549358,3D06A356FE52436B,3DADD39C847E464A,91B11D0FA6590EA0,E08162FBFDFC94D8,C7C2B55FBE37881D,CA8437D19C03B5CF,EDAE4AECAB93F936,0001B8D27A2DCFC2,C56DC947FB11070F,43BF57D0B1DD3344,D9CAF737B26163F7,6C1ED22AB214BC89,12FE47DF6057C633,600E6797735D2D23,46A51BC99B022D3F,0034DDB9CF64BCBA,1E5C4ECDF3E4728E,2FB0AD735C2B0F28,F715A96C5BE07211,52071086EE1CDF9A,5E17834F316DE664,243EFA8EE8CA34AE,51604639E9D367D0,002851E79E0EE114,1DC710827B58EBC9,E8DF9508809DEB4B,499BD757C5F2B3BA,6FE450EC9F18FE23,E24D13D60BAE6A04,EFB970EA3F36DB86,3C7563FE355566AF,00236EA43BFC9F1E,DF4D121B853E7EFD,C00BAFBEE4DC33EB,F14D0A9542CE7A13,5E653E24ED384BB1,174248C569B38F3D,7EBF1BACDD7DB19B,1DD291CA523D1142,002DF36BA7F2F85F,8C579FA6A3D37F8D,CCA46EB6009DD255,710FBCEB30DBDE94,923F2936B214EEC2,61C4CB7DDF744C77,130DEFBBDE27C662,F23150AF5EFA89CC,00378DB3E848E403,4951A40F04880C48,7229B1C93D30BFB8,C876A10B9AD87D21,A64C980796B61F73,1829909AC754C364,6A6D349FF38D22A3,24DCD71BCAD87D87,003F866516736519,6DEA1EC761F1D729,A2F05703DD593884,398CC8015BEC61C1,E0BFB8432D170C84,C09FAF411245B629,B8E355BCEC4530CD,8F13099B4D6CF7E8,0020928604155EF4,2EB66C032BBAFAC0,170730A1EC592E0F,36AA2FF67E221233,E02190AE4DAEAAAC,C53EE351B2FE56C5,83597D3556EBC9FF,BEA0E92863E9DF7D,003767E79A0CA025,E56D3489B2994AE6,C06C99F4406E04CD,686EF706A507B00B,41A8F93305F6B94D,04DA09B4238E7CAF,C5E6838EAA208168,0A6668EDD08D1E3D,00394B2C8636991B,B06D409C3F816AC0,1AA054DAC6CA067B,963BF73E6F27F737,F6AC93041D78CCAE,E2100F282B74C9DE,456D45BB0A30298A,72394C387A15046E,0033A558B706D93A,C4BFE7708AA79247,1E688D727BDFD925,4578F27B15E7D3E9,4F4DD88BED667E75,0A9AC54E8B359ADD,765171D758BCC1C9,9D34C1A1C586E298,002400E76D5CB2FD,3119527F5BEAE480,EA6E028C99576560,DB63B1B22EAD780D,24D6629724B4706C,7C9769C350A33FD8,1AE97D10ED8C4124,4939B3E6AA15F4E9,00296B729F2EB265,651B34100EEF522A,C5AAB0948FB61499,9B0A97F8EA7C9863,70CD033D81B8DD42,4B4DCAC96F3FCA90,FD794A06438251D0,D440991ED92E9FF7,00212FB16EE9FA29,F59ACC8213E71CBE,65F311E94D95E068,72F7EB599DC83C03,BC02BB83DA12736F,7BA3446159696DAB,3EF3E3C3F8A2E182,37BC96A7F4A32660,00330305D6E607D2,C2DB896A599C9C3B,E001AD5E876817A7,1598A97E6ADCF3AC,55743863D2599A4E,E92859B3C28D7CBC,33A865D14D28544E,DFF5EBF564E0AA09,0010855F8E706294,B5A5DB1D38E633F5,F18C4FA7380C1E7C,226B79ACCEC40AB0,F720FBDAD34B6E14,851CD7144F4ACE06,C2B15F719B748880,C05112D84393C718,000624C35C279E72,9B18658F0436B5A8,3701A73740613358,DC688C8B1D1F18F1,38D654218040981F,16378053C26D84BD,89DF23C4DB75D81A,A8A714631E0205B0,00061BE25BD31821,F5B9A8FE2B424DD2,FC224696A26BB756,D16D12BAA2E46008,135D7F84F8783F21,DA926B9990B33066,8A82D655CD944CC7,BCDC4D813F0D2CCC,002E237B296E75D1,41B10D3094A465E4,7D0C7AE5075D0FB2,6D4560F0117C8503,BD21F24B861DCEAD,1C0B5BCA9254D5FA,9F8DA475E14D8003,0CF6484F2D2E916C,000EFA8045C481D5,2BF8D523E5A06E7E,E11E6C710F0559B8,AAD24363001BD0B3,EF4802464CC0FF58,6A2945A71533E8C2,8793AE27E50690B5,2A2CE891F41579E2,0031ADB11C46ED78,F264DCA27CD86F5A,D00E1093C3A74AFC,5D414070598AD923,9899BD9122411455,F5B885BC70C56E72,01F39106B9D8EFB1,7D6DF9684E57B856,0008CE7378065A87,885D2D0E74079273,4130C576AF4376C5,89335FA6774B5C53,07749A689738906B,76D670B97DBCB934,92270A9E3E09D1BA,F2937200AE754E22,0031B75B258A3518,4EF405876BB96B2C,0683E940BCCA1FB6,3AF3F3DB2F1FDBA4,0EB5077B140283D2,6AD20F36645C02FC,80B3C878AF180DFC,D603B709E12727A9,001C511EE70CBE6D,AE59F1C0E2B822FC,DD3B10F1EE45FE73,417D7E5409FB8E1F,71A4AEC55CA893FF,764CAEE32E4E4DD0,EC0CE3D853BA15ED,E8D4A1700021AAF3,000FD86AEC88EE19,80E5EF71790C7591,2CA882E162AB0751,AD8B029F2A33B5D1,95ED88FBE128EC77,67BDCEB9AA21275D,BE55926DBAF02B30,CF28F19AAD18A467,003BEF5A92EE8705,E7C95A8475CCB61F,3512F1C41BBC982C,B8B2CE3C03CA2547,DF2A4E50A26BAF28,EE20C4114AC0015F,D52CC7742DF6B1AF,0C903B6E599C34FB,002910E32F97B714,32EDCC49F179DEC2,9058B851754704E6,E19EA0C7154AECEF,7E5B22800AC7E7AF,F5C81055FF2B5F37,EB75FE2F2C1AFC6D,AA5FC125AC5C2E77,000C4E782F24C937,F57D167B5CCFEB5F,F58F360AE0FB88CD,E6E08014F9D2751E,EE0FEF655DE77607,EFCD38EB7A095096,BF3EC9322E2E46D6,1870287EA6AFAB0B,0038F3EADF810D44,74206EDEBCD2C249,B7BD07BFC143BE01,27108A6C180BED9A,D34639072C141309,04F823565EC25CA0,74C86C4608C3E248,959E76C6FA98B9E9,002BF13451263FF6,66609E8806CAD0EC,F4F298A38F177EDB,AA0C131AABF55E45,C027F853DE0A47DE,0C768B36E515DFD2,56476294812447B9,DAA28715F9F6D51F,001340DC8D414A7C,60168399F1DEF4D1,606660EC6521678F,8E2852BDCCDB4FA5,91A0B8159ACF6FAC,BFE36F48936DC32B,4D7D0B79FB5377DA,D38B8C105A731075,000E10EF81FD9798,2E8608E530D30060,05AA8416DE8B2107,CE1A0C97065E2DD9,CCA9D9C8848DD102,B0BA0487BB0FB329,B26B205305C8055B,1A1056A3474976B1,001BFBEB1A93E2BA,1C480AE40FC5494F,2A5E765BE3BC6CCD,213D9FBE571ABB6C,777D165F78E29C3D,CA9979F9E4D90864,AEB44807385D5FEA,D382DD893ADC5F2B,000B2D75DC990313,E322685C3FC97B02,68173265F6C4C234,29F04C5BF1173DE6,AD22020466692E01,A589CE3023146F2E,C832B1F1F6820C3D,188CE0C2DDCF6444,000DFF0A7A9FDD56,9F00CC116D46B823,D5D4EEB5AAC061F1,03CE401BF1AE9731,A3FC436E9E1213EE,0551189E75517FB8,AE9FD4D5BFB76A87,9BB7CB27EBBD6E48,00077177B719DB0D,BF8F7D9FB9A0E655,AA1C49503086B101,F31CCAA701ABBEDA,7EB1E89CE19D685A,674A0CA04E922577,2E80B389A89EEB61,E41A5AD22F13E49F,001247DC9208A15C,57987AB8352FE862,4492354F45560B82,CB2AE11B70E54F1E,10B50FCFA29C7641,C605CA3222617240,85DE5960D177B798,E459D9A46A078041,0011F4A768F61E4A,31C6ACAF83A9EAC8,AF406AFCC7DC52F2,9BA33985C1C5DFE6,890F177A95682468,8E663D3D03A06F03,984969C81C9389C1,A3C2450FB7285372,000EA13FE024282F,199A842CF792B722,4111BFDCEA43E954,97AD45F9D2412C19,EF12B93CD3778D17,64DA511F632A28DE,8C77DC27B27671B0,27821D7CC04A86C4,0007C1F92023DA39,4ED2D350734EE720,448E8D76A25C4735,116230C17624B0C6,D893462B1676758A,A6EBB986BD068C21,F0C21E41216CE0D7,E8BAE5721AE86A9A,000842056B7ABDCB,FE7D97091A5E2E5F,F3E33651D80FF16F,1DC6DC81AF214087,838417FE821A2D24,97241A6726B505B0,D37EC99E5624B990,C32230D6995F282F,000A5D9FF37EB0B1,5EC21345981A49A4,D5404C469AE92752,FF000AC64B449F27,9F02314E32D7783F,EFDE11B234DD47E5,A06BB470113D0F69,A8895A8F626F83C8,003DBC11171F1FF4,9EB7FFA366076385,54022EDF42C5B222,7934193C5830E0C5,14183210B388B3E8,647104604E59826B,8A2E47E92F7EFF2A,5D2E596E8A4FF69F,0003F5AC12DBA056,5CD79B74B8D71727,9B2A488B8A4997B7,AE717A86E8C91008,AF2460AE1E42A35F,546169D29363E6DB,755F282994427E81,A36B584C379B0D9E,001619989075CF55,77E8EFC63F3709B8,AD28CF8ED200371E,6DFE341D03123222,132237FAF69AAB61,1F4243B4CB79A696,D8A951B1136BB9C3,C5C73571E024CA83,0011A1D6DACE8A40,BB5699D724A19FB5,35EAC10099D07266,F020B134FCC9F9A2,FAB217AFB224C5C6,5D7CE2E6C03FF681,14D8110AA54B6A0B,FDFDD9D217E0D2F4,001C5A10E2349983,7230F9E121F19704,0A7012328EE3F606,1CC2D6EDC4C58546,12191CC79FC853ED,C1408571B9E10BB7,1CC23DC0B5E31041,415BF31EF738597F,0032685DC7D9DDA1,A5B0103239517364,1153D3F1624A7BF5,2AAA669466E97686,BBA357174076A7F5,3C76D3C53B1E8ACF,DE34B2CABDEAE265,AF78CDE7793677F2,0024D1590EE24DFD,E707FEBE7B1DCABA,8676D1FCE2F5CB59,2847C885A90C01ED,0BC724195783AA3F,D9E79992B8DF2D0E,E6FDACC7F4DB5DC6,E7D715603BF8ECC8,0012DA6320A68886,7963D995DE537634,D291BEAA2D1F06A7,BA6656237CF9C317,E360470B334E49E9,93737A46E504844E,89729252EAED80F4,3C8ED539290AE4C8,000FF4EE7518C142,11904C2DCAB35DC2,FA5917CCD509D4A5,AA2DAFFA4FA51628,E5F64FD78E3485A2,9928F66CC247A455,0A6402679A5B6C99,25A7FA63511B1EC7,0034758410E3C071,04707822A1A150AC,21EC2D41C50A9128,3F7BF1373EE4F442,945BD651F40B4E34,68F6EA858C1F89F8,22DD4AB4424F7D6F,BB5D8B9A4CD9E1B6,002A3FF76BE4C221,2FC7F14CB8DBD522,7AE4C5F5357C6609,4B1E2E3743B27E8E,CF074325A98D7923,FF3FD435E1638180,E861A2D529E203E5,B8762C9344F6845D,00124E887DCCE057,CED385CBD5C9E783,EA683083EAF8E56F,0EBDAA67FD155292,AC0F997B58E6C3CF,9F54A2E39DEF2E9A,DB822C8FAC33EA4F,3FBB722693535E76,000B2187CA097BEE,2CB6BF2A9637161D,2DB144BB0D694018,24C67A2F1F7F4136,3F696AE6B78340C6,0330025E48FC265C,7C94C33FFC74D76F,12326E8B0C6DD6B9,003FAF416EA7637C,EE06FACCE7CFCE76,A15A6C012A143581,7E777001191582BC,CCB204A40E62CB2F,E3080B2462518A5D,F84872AD413DC5D2,68E7CC15CCF69371,003E98DA9DE5A9BB,C851A6CF483DA816,2A1B4005D4FAD2AE,FF2B47C57EA4E0DF,FEBACE6FF1AF1777,70E8F47215607F99,5926DC818360265C,3483DAB66AB6EAC3,00321C3D75D2D916,D75C5214121877ED,924EEAF7BE22C198,748F4F8FB7B2970E,165BF3843CB47D28,1C3920E2138D17DC,2F5E8E2D6726F3CE,BB17ED78C94E336E,0021D184F2413119,4B440DFA95AD7F4D,8E06AEC8A3324C9A,776722DEC5ADED4E,D2FC6EFD81FE3084,2A1B79DBBE448845,912A8719D0BDA80A,CAAC07C4C7775BA1,0008B0B0E0189EAD,66270CA73B796CD7,783CF42ECDA34DED,EC6DE1D7354DACB4,F73D914ACD4A2A66,B83119669AAEA264,7429D9F36657F492,96632147E62B966C,0012E66B895305F7,5B80667254A592AB,B71AEF88FBF9F606,B798CF330072CF89,516B1A50BAEC773A,237616F2F15CEA18,559761AB47194203,BC6B1B50AD83AD0A,003AC206E23E1CCC,DB8C53C65D05917A,31A2183C5CDAA49F,9EB2800F95566346,45653F022788ADEC,5F362ADFEA283A2F,3CE597FE0387AD5E,9B3EB20DEC97E4B7,00355BC9CC1645B6,5FC25BE4716A9B73,23559011B3331F92,9CD8DCAF28793B2F,D0258D3F4F35EB5E,F9E7F175DFA82C33,A708544114536C9B,93D78E9B98FB4F05,001CF2A5E4290356,18A9778FE95D3B88,BEB84B5F58E35360,EA75D1ECC1D9279D,69FBCD5EF57B8738,2767B1B2BB60E09F,8EEC6F75B7714B71,7908225F04AE3CCA,0009F6537B454193,96E122751EEC6A9B,66DCA93565826745,F6BDE0DCBF7452A9,05988008B2D03B02,C625B54CE6DD5618,BCB7BB6888D993BF,D6DBA33F03FB2481,0034102E96B804F6,1A262D31010051B0,EE2ABD5AEE8F0AF2,B161A380FB46F6FA,B1A9B198ED72D9C5,C6317D896D1E7C2C,8D745EA65CA029D3,7D5DFD564A8E4BA0,0014A06940896B3E,E3611850E445542B,59FC6E330B4036FE,FE7E25498E723FD9,76556269ED0417B6,D0A81CBF4B18DD62,D58A9744B5844554,A28B72E895EF4DC8,00371459525FA15D,DBB716892E46CF36,491F6A0295DC6058,9A91F876794893A0,22D0F37C83FF2A8F,54D0F524BF4B3C29,DC12596C35098CDD,16D60675A4724844,0012A6667BCFF443,44DDA42510C9F463,CDB409382D930CA2,74CA40002DDAD19F,F4D49F9640B3A84A,789097C3C9DBFE4F,0670084653218197,D27FDDBF2285F0A7,0038FF2F47BB4043,FD4FBB6379CE7D04,AC71A42222C0CD1A,49E3F2B5BAC5AD30,44CE7BD50186AA92,E418F0D809E35307,5EBFEA43AFE48723,41215226A36A2D94,00048F0750A31AE0,B192C198C942F93E,C1FE4E122497A11F,A3E666DDB601D122,9D3B1E4BD8A42201,CE7DC1080C876DA3,793135B80200E7C2,4D0CB90A78C893AD,00397D7573DB19B8,4FEABC5543CA4EEC,632DBB55232B201A,86D767840FED4818,98C3D439E9870915,8B359B227DAE6DA5,51E09E10A2964BAA,B9B01646D180C3A1,0017B717E57CF2DB,38585DB4436B2322,E1F46490F42D85FA,536B5062B93BF41B,0EC48915CA8A837A,5ACD711FC9EE441E,5DA2694B93B7594C,F13F56A7AC858172,002BC59E609A529D,CBF18AA402150616,5B340DCAD2D76D2E,EECAACE002125040,021AEFFFB8766AC4,DA400C1733763C1E,EE6C0573C5076EE7,2F0BAD7E6467AF8A,003240528CB38E3F,3127D9EBE2965B5A,B1C7D7C5E6F4C16D,A823927FC33E70A9,BC7CE44D996DBFB2,FEB8576991650DAA,7D8114418CFF2DB7,02A6B22A74FDEC85,002A3EF36E60CAF6,F1FD80E6F0289D57,E9BC8E9B75BF993A,81F423EABB202915,DA0D616810DA4947,4868042A078B4A67,AD472A9D3D9E4D7F,F173DB1BE5FD6B67,002ED99F229D55E4,207A86AC5A3302EC,98F7E8AC8986C1D2,F845A1E1CD25235F,F4CEA81350E5FBC0,FC8248CEABEDB8B4,6012FDFC2AAFC9D5,90E4604C4EDBF288,00011718BA3424E5,477E1D5140841A8A,700FDE069A778B7C,E4550563D5460F39,1D98C40D3D50884E,47B9516BB969D615,C69B41B795BAD650,801F27D2AA632CC6,001B85A287B22BE6,CEBEA794E5EBFB99,C3CB84134D81CEDD,A4768B92FCA3F853,26907CC33E383B83,67051B01DEE8D620,A68FADA8251E53B3,89C564DC2C89669F,0022FA0FD2990075,3BB6AE42F3169FA4,89F4309FC453823D,EE86BB406176A768,94B89AF9737BEB87,BF6A603823F02E76,61A1CA522802FD36,51CD7464AC883E51,000643B230A01A4A,57D33E4E4B602067,CF7388C77A9CC1FD,C3F9F80CFB7A4D75,7C968AAF75ECA7C4,295EA90D8242A1E2,8A0691AA45BED0E9,0649142FE7FCB581,0012759741A959BF,692051BD1AFAE33D,741EED4CA5FE84CF,60DF37006E48801B,42D7A7FF449B4186,ABED0A24AE308180,7D852F3A11D1672E,574E76B34A8F8D59,0021963866ADFECD,5B8849921318DD07,DB388953E12106C9,B0186BFF2C172ED4,8D021A5A501CF59C,60769B3C3C4B5F51,47E94467352679E5,7A963E251C933A6C,0014D156B4ED2359,C91EB9501ADE5584,E6A3730836663311,9F4BE3F1B86FBA05,32EF4AFAE436F37C,81A95F357E59CB60,86ACAFA64461AB42,9335BEC52E6DF854,0006BD43ED3A8763,E4DF3A317803A47E,2DE4E28249B668EA,CDADDB2D2C486D85,63CE86EDB349C1D0,235927C0D81FEBEF,4E8E7FB04AD5E1AD,1897E39DEBDABBC0,00240089C34BA61A,24D177980F692F00,C800C45DB8E57D21,9C52F93E3FE21C24,A0F8023DE96F8BED,7F131EAF0151EEDA,E322309781340EFB,547B6343A88E2B2F,0017C118BE89C777,13598CF2892BC6C2,AB7DA12E2F2FC734,5E0C0D69DF2A5A3D,2C2023945336CF75,EEC09C0D4CB46E73,C8964C9657F29DFF,2A6B0FF457209735,000085C93E4D5259,C451CA144B4EFA82,010A3F56DCC62B12,073E9264875F0EA4,207166B1A7452203,7A9C3E44BB41505C,BA133E768A63FADC,296F9604A44B7AFF,0020A55F6128F55A,BF610B6FB52E1DB0,91F3203B0875205F,497645CB6C9F70A8,0257734B956B9923,670B028BA3E9196E,326D91A3145F8244,E3F11602051EE8E1,0006B8F1047A4053,A8501000BC480776,4FD7CB82693C403B,BD4AD98AC34CA6A6,199BA22710A86AEB,3DD8E8CC5A8B2870,25D2370C36FC23E5,00D7F8BEB5FB9452,0007207CF250F345,349D07C84D8D1ED3,B67A29115CBD65F4,4954E43D2A8A790E,C8A6924649DC5CF9,1285FE9428FBC3A5,EE30554ED7E6EDC9,CB568AA0E4FF6B01,001060B748841C08,7B58DCED84780B47,06B6C14FCBF98C90,B2E8D725668EE1AA,0F196D3912FCEF04,F89FB34163CD0D0E,37DB5E81FC238CF6,C5721E4D4D0E82F5,0036C92AC0527A52,1DA6A55F9582951D,80E28B3D4DA77A72,00ED558FF9883CF6,62DDBED0AA59985A,D4F6786DBB4F088B,44AE2026C2884CFB,23D1A1E456061E6C,0010B0BC75341D61,F466F60AF65532EB,82077D7C185A79F8,D1277A0796348B3E,E7CB5ED03B288DFF,137BE7C37484D751,FB35800A9B1FFB4A,B5F82469F742968E,00041CA1761BA250,613CB00507B423FC,D2984D57450FC9A0,6B0EA24CBFF5625B,C5A7C2CA0DCF1AB1,F832FD36764C72D0,67D747EFBA98A4CA,F40D39FD06F2B09F,002D3253701E0875,640D0B7ED2040A18,6E69B17628BCF469,713ED3A3F801AF4A,A269F921925CD9DC,577A29B48205D0E0,29C2E66E71AAE2CC,2E985D266C9036E8,00058258BFF58EAA,CBD778C5BB434D69,FA9FCE8561DAE905,545AB790010B1322,ED6923D780971672,4F13D21FF2F41AE1,50A4918CC107AEE7,5999C125A9476B85,003B89E7DB44AEE2,7C60A6213FD93E67,8A80A06925A4C403,830698A08342FD62,07831B8249CD6CA0,EF6923F19A4F5E3B,5C65EDEC8F6BAA7B,479662E847FBBE5C,0025AE05A40A644E,3BCA8F118FE5C56E,A1F2B27B8BE0E1E1,FCCF54306E5D7385,1AEE6DD57A750F11,F5DCC41FC69C75C2,C0AC6E4896015546,2F80752B8A3A5D09,00215EA4FBD4523C,C7398F0D12FC3A2F,2751D507CFB1BF47,0AC9E1AF3DE9D43F,5406D5631941F0AB,DA1FB2B7DCCE6D55,607C999F04451B4A,C2C87FE3CD30FF08,0012BA80DC37E685,15BC795994BB700C,2A9E086B8E1D9687,5259ACEB963FFA17,38BF1665794F1824,DCCD88FA728967AD,C05BF42047244590,38EC07C9692C939B,0007153536A190DA,87AF4E23452D1D33,CFD4696764E7DBF5,715556542E7E0D4A,B4DE7F21066290B6,00B47C1FB725FCA9,D5582FE0FD390600,CB11418A98365314,0035E72B43A05135,B755E3445AC4D025,7D51012DDB24B560,C160A773E31D7704,E6AD5A9E8FEF95EE,6F4B3BDC30C4A0D4,F4F52B6E36FC7AA8,6EECD53DB666B51C,002DF30F94871E13,B10514173E7A23D3,F51AA9EE1BF46125,9FF0221A0E16672A,3F6AE38C6B9189B3,510870D8AE88CF60,D590F20ECC00031B,F009459159234D5E,00132CBD570E2E07,3310E94E704202F2,3F26CF6ECCE36F36,B58EBCBF288520D1,F3BA7775C96A1E28,209DE4B65F82E151,20D1241C3E4184CB,26D7D0BD7EF5B854,000E94382A380048,D8215C231998DCDE,CCF89A92C86DF92D,51AF622F834ABA0F,4262B81F46F39DA0,EC0622A19882FAA2,8516C9BE30E53B30,FD048A25ACF756D1,00058A7AB0C20642,C7670A44560F8F91,AB8547B43C3479D3,3D569F5772456BB6,0FB5B53C0FA23B31,E75E43A12A8B4FCA,13D88118CBCFB9F8,DCDAD7C80EE953C5,002F8C069DCB4740,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,B1678C5AC22E6CF3,D3997F70E6B1F497,56C3B1478B8F394B,90B563F098BC13F7,E33BA6C4F7BB082D,D51B497D2F1C4BE0,3DE4316EA65A30B2,0007F44E0C9DA7C7 - -T_tate2_firststep_Q = 273F6C464CB9B30E,83722DBAE9836B36,7236DD158D1A1BBF,CE84ED2FD6FC9B11,96804584C42BBFDC,E3D6BF4D45241A13,C4D8AF04CC4F6BEE,000653193B290C00,03E3209393CB32A2,689964CCAB348A84,74471EFFCED8819B,661D7240B28E2790,71AAE7BAAE2179CA,5DA64F579D150D5B,17919259B69EA954,00077328AA89BBC7,3906E0889D1C2FC0,0C75AE81624C4EC7,08B7480889B54EE7,64943C09942FDB32,44E4802923DF1D79,F56CE97EE0F89851,1DF1A01FA1863680,00315A043E1D0C15,F50FC07FBDA91B34,617F5AFB158C037C,31A682FAED0AB32D,4CB68F9AE1F01D7F,4F468A61D183C4E9,692707D7F3EBE901,5084C7D3D549991F,00136698F774A6F6 - -T_tate2_Q = 85C7CA3E9EADB8EE,97873829844CF9A5,96510E240E86B156,EEDE7282E40EE2EA,834790477C5D787E,3B30922B819FBB12,503CBCFF9F6EEA85,00310DB49979557B,B19D04E98B392C8E,D2E39BFF2A5E96F1,1360F52AE4A91741,ABE9E841F06BD82F,9B0F10004369DA05,9773A80A2D5B4968,150F402F78BA17EA,00267889EDDA82D1,E4F3317EB16BD357,8CB1BCD465AAAACD,5BD63B8AD1EA3E14,75F4CE2332B5240D,58D711071848D94B,C3A1D6B6ADEFFDC6,2E60A7A9993D40BC,002A4DF4CCDEDB41,0C1BD72B10DA4FA9,084A26F4EE4496FA,34589B9528ECBF9C,0B6222BA5EECE380,27A5FA02EAD7F3F8,7663FDF274804B47,4954C526AFA4A7E1,00036648BE8A9460,CB251808FD734F84,EA1DB9DBA11457A8,0BE247A8E2EE186D,0275FE19B2EB7F43,DBC4D02713E06C40,5C7D6AEA148B13DD,657E84E0CBDAB22B,002432F09DC4483B,1637A27855823819,C3DC5597D4F788D7,D251D69BE7F1CE68,785BF32F873C30E8,4AD8725177438524,045DCB744C6F8F13,D216FC7A1F74ACFD,000619711080F21C,E01B02B0FFABF430,ED5F88D2590604A9,ADA943FA1DD8403F,5E330D59DC77889C,139080687DC5E98F,1CF2B81CD54F9FE8,4BB02BF0902937A0,00188104988B2CB4,B7D8CACDD61A57E7,B1AFF074D0533E5D,6A5C95740929D714,BAB26BB2A69E78A5,F277141029706195,C9AEF881ADC3BA1E,0E5715B4D01CCC2B,00176A061CC47CC7,C09FEE1625AE485F,8633DAD9226734EB,BF88C965D8CA54AA,EBCBD4B6E769FF87,543DD3C8707D9014,D35E50A6F9FD3B4B,7A28A562FCB3C67F,00405843C342F10F,F238C2032DBAFB12,E29F7AAF15F306FB,45DFA909E7653EBC,9325C090B921F541,7D18BD7B8A2FA1DE,C3036FC258CD9EC9,7D744123622097A4,0010E3ED466E3E8C,8132CD2F847DA8B8,4AFC83F0068DECEB,30DAEE5EFF8CEA14,D89FDB2B91756EBE,3BF36981E1ECF64E,EBC4FE8E9E8212CF,31D29511C2723BA7,003C1E06F04F5653,CBD8B07F4A9A3E45,1443092D9F914C9F,33A88AA7136FDD85,17F517BE8449ABD1,8A4E91AB3AA503F1,8372BD7EAEDDEACF,56450B847931748D,0006FDFC54AA439E,F6D3936A7E8712C4,525FDE819DBEBAE0,2874E4ECC2630B74,1FBC2C7D26CB7E36,F75681CF0E5462FB,93909F88676FC573,295E93A843BE4E64,0033CEAF9B01127F,9B8A62C5089194EA,2474CD26C67ACF1C,9776C45076A0977C,E805E224A4E0EAFD,ACB7D10D3BAB10E9,F8F389F69B8F5367,86A9B41152D32C07,0020E2F3D52A54BF,F4314B5F9E42A846,4721BB5334E50C10,2AF52E2277F6A2A0,FEC9E0B07EF0A81E,64D012D951925CEE,0C1B86D0291FE861,279EDD2B4083148E,003843ED590AC7F2,BE269B61D16536B5,D03EF1FEF08E1497,B699A3117FA61D4B,512788543423CF68,6C7F64B39A4E2E15,6B4E8D0ADCE0BEED,52ED5CE2D6FF84C8,002271E0661F2B91,F66F83C841E5822A,C4334FE8A1E1D72A,A042BDCD86E19192,570E5ED7AB554437,76E232A73F137EE0,2BF11712838E81B9,620CAD3081CF4F40,000ABFA98FA91B55,3E51D21636E0A903,9CFA6AABDBB555A5,8785D31D6B816F69,00A7AC7754211FD4,B0301E0BB9F4D945,C1592A4A7959CE02,9E4549F8438B08FC,00196357117C9D02,8C24774ABB7FA431,5341695414714243,7673CE34ADCB8932,9E4D78196166C3EC,B32797EA20E361FE,328A84C13F177314,78E496C747C09D29,001350733DF5ABC1,B7042BF0D6B8E130,C6A689E163EB578A,593BCBC303ABF6E8,1E4B4F8C9A09B9FE,E15DBF9ADD7DD378,BEF91FDA06BAFC65,6A21A6C54EEDF611,0002F3FBE51ABF33,8CD0DA012FA7D205,A86097FA989CF40A,4A7285B013F66F1A,5A7FA82A56ADE8F7,68637425CD3F8883,DA57D6A35D194D22,94EA55988E64D5E2,0011FD6C675540C6,4A3BEA3AE93960B1,E03E165866FDBEDD,925C330C1E7D8226,30FB772BB1A85AFC,436A12091E97D9D1,EE98C9A0EB42B05C,F63CD3C900A0A350,001D17A39BDD6600,6086DE8F8146C8B0,40566185C25BA161,E901C89884636E6A,B578BE00D22D4401,B58916BFA27EE2F6,BB29C4CD5D3D1370,561BFAC5817EA571,003261F12EAF245B,51C69FE4C2BD6C90,BA93C7516B3E3562,0C914015B590A73D,112F9F42FB703305,E86D0D63682C6968,89D08909C7F53035,95D8E48B6CEF33E8,00224CDEE2EB9524,655858D5FD89F1DD,E47C518457856AB0,6EDE0F13DF8B80D2,1A7A03582B70F298,62B5A5C54B3D490D,AA840FD16257E005,67E4472CFA384456,00048C971ACB01E7,5AB1C2CA90CBEB5C,A25F64938BC48A66,EC946017823C05DF,896C703B4F137BC2,32EA49999D906542,C8B0D06EEB790E74,BA60C32EC55C62D7,001AA03D36CF8502,86DB15CBA6040955,AF4C4A5B90F3C56A,2DF9587824678BA0,AE49AC5DDD49376B,B39B01B40BD1D99D,D968B251D800B4CA,1FB9A82972F38C8C,0001A2DE56B250C3,9E8FFAF253556784,308D2F92623A0758,E283E03D68849D09,A62A3E8DC4720855,BE933CA1DEA1F275,6009F11D5EEB04C7,48CF021AD85286E2,00352903B55112B8,D043C2E2D1B77306,63FF12D119064271,36F29C4ADBA2CEE6,FDB6B49216D3743F,97583BFB1634421C,62F50B77D0D5602B,4BBB0B43D24A746E,000E9F0633ED51C6,DFB8B695F3B4F26C,5926C2AAE5838D27,91BCA10F9B44E726,D1FFF3CF57DA04CD,A557509AE62E5C1E,50B1A18402085750,0899F58D853D855A,002E5F28E5B5A275,5E3A092F11893DD2,7CE31E0C582ED837,AB07330F1F006699,DB71C77A33D38014,37D84F386EE42EB5,077A216FB5ED21C3,826FC664DDB3B6CB,0039BA5D5EE95E97,455360834F72B7BE,5965D9CAB8F4EE6B,232B72F1FD1FE273,A230386D4DCA331F,94A0A28561ABDD7D,54A05FB6BB2173CA,07175AA2C518B12C,00117D3E02839973,5B11E861840A8078,5B447B97205FC6DB,CA02CFA6A69FE8B0,0C07409C6A41936E,B589C55662216004,28B0E362E168B785,11D6CC0D36BCE4BB,000C53B7973EEB92,CA9A36B9F4CD5A25,A2D743ED9D94288F,E11854245C2BE3F9,18DD5D0EA9C62B77,71B5DDF069A38239,462FF85D662B5739,8F0775F6EB9F7067,000E9028CEA5F5FD,EF7DDA0A270B0FAC,8D5B15C4B85CFDC5,A3DE0BFBA5540069,A6910D57AB8EFF6E,4781ABC5C99EA8FB,8CC560CA2BCF0E00,AE945E2C3B9CB9D2,002AADD1B133219A,3B176193FED733A2,8BCA4B181A55CBD3,CC578CEF7ADE923C,BFE1BE006218D884,841B3859467B2940,C77D877F581800BC,D98044F56633E791,003983D8E1C488E2,8F23E62C402FDECB,947EF73A4794033E,DF63C67CFBDEF4C2,C7A1E3299594F62D,2C3F5E6251D15207,DAE5AC00D90CCED1,BC7E64AEE5638D51,000BA3C4739DA95B,93FFE0DE8250187B,1D145333E5899F46,1904EEEE43EBB312,1383058CF8C03C87,F92EE48461F96224,2DA38D983DDB17E8,6D2186D33E59C36B,00250774ECFFA4DF,B368385C28DF4763,931E6BF4DAC47FAC,34A28F276A7C3C07,34E6BE5555D20E25,3423691989928F92,598AF984C0AE13FF,3DF9238A7426BC3C,001867401DE4D7EE,216C54D5330CCE0B,BC2C3DB4CE0888C2,2C92AA85C95B4DA6,9D0E9A4B6E7210B1,F6E6762771B5AC97,2EC536B830889B61,807C10D3B11DDF68,003FF77B9E0A89F8,C8144E0C41F30695,3E3216EF624A9A97,1CEC3E595606677F,25EC1B46F719664E,D3988CCE8D90BEE4,A6225EEEAC9FA979,BA1D02D6F0F81FC3,0016E7C4EE3397F9,35DCCFD70EF557F5,8D1980542AD4762E,5E0B1073DFE2159F,827FAEFAD1E0137E,34B5552A179F9441,F6246D207B94E9D4,93007594B4F7E044,000FE2D687655527,60DD66091EF9F724,1713DA394C304A7C,93650F486A1E3823,4748A18300898763,5CF0D9565529F133,E04370653045DB14,4C826D11D78C4CE4,0033AD7C5A501721,D9942C04B985BA1B,A04C0FCD1FE51A92,9CA6E9006C195EFD,4C4553E980A95FD3,0F8BE423B25A8A7D,5A1F67D1FFB29FE4,91A5BE542B0A932C,00063B25B749D19F,16A29B9201E906BA,B10E1938815305BC,5608FC5B5B876DC8,A5F59F40A6141C4F,198990E366A4AEFD,1F3483AB7FB179ED,D0BCC3CF8F74995F,001BFAC67531314A,36080686BF9215B5,602D018177CD81D2,E3641F6027AF998D,3B8E0FDFBB079394,D2A122A54B97B729,17F44B964268FFC6,AE4D570FDE71BFA3,0014C7D16D56D1E2,06466107E7069561,346E8735EDF6CFE9,8555074D6550572C,2BE3DD8E6CE42FE1,7D49E486C984BDFA,7E1FC7D4C20D1613,55C7A2DB2D5E0698,001D9DDA3B632481,DB9B3258205C48FA,67D583A5A421505E,B3527021E1986A5C,33C4DCECEB1A6B45,48D6918C40FE9C8A,CC046BDC8FF41783,B2D54654918CC0A8,003EE566368BFC87,4C1AA9CD5080A8C7,12415F1D2B7C1C47,E42D8F52EA34738E,2CDFE05607ADE66B,A3C5939C4B7FCF1D,8DDF73AF50F16E3E,31398F59CA516063,001CAC742C9EA0D0,4736685D0DC78377,7A9E13039FE5298F,F11631E4026205C3,6525796BAEED916D,CC54E633784977F6,0DDF4964C37E2E2B,D24A23B4B6FADBD6,0003DEFD9719D7A6,E322D17049627462,1FBDF2EC1BC4D507,ABC696715CF3BCFD,91AB243F06E274EC,FC5422F7E78C36AC,FDE102D5DF6E66B5,45790CC96C4AEBB4,00331AF62D67FA57,C2B0DCCD96D923B4,84FA2BAC0D3C859B,00C17ED893C59886,BF948BD94C3DC842,E5E8E516AD745041,51DEF67C63D51EBA,FF263CB3B7DD9069,0004C7694FFB5BC8,AEBE3F2B5F1491C6,C44EEEF5E128DD2C,8254867236B5A579,28009270DB328E6B,519CA7E8917CE06F,B44DB1F9E9B4DB12,E3334898D9E5610D,00393DAB9885267C,85A06E3AE4FEC073,A3D647A36A446ABE,ED36ADC92A5A996F,F8CDEF4AC24F3746,5842BCE637F98D69,5E77EAC96EFC10EE,63FD47C69362DAA7,0001712B1AE643E7,7D304F8AE560CC28,0F5DAC6B99A25356,1CF4C58415593775,7FCA44231F25C19A,4CDBC8ABC051A5E4,72D8EDD946CDAA49,B46753FF109F5760,000C307D695E4A56,86062BA4B21EB80C,3B42184AA93CD213,5A116C8CE0189032,501CF7F8103717DB,284CBEFD3305DA3C,6A08B7B622A34532,712CD8F1816AD4F9,001FD9B26CA27AF0,4DD5D695E595A32A,0A077A742183FC75,598989699CC18805,C2617B819981E73A,BE7C7DF06238CAB5,75ACC7DF17ABCC3C,A07B0F723DDFAB29,003E6FC04801B1E2,2F9420C8E8DD440A,D50455326469FF7A,06D2A21A9C77AEB7,1888356EB4EFD335,17C9E871EAC65AC8,D9FD6DCCAF50F40C,44903FCF9BFB1D85,0032C96C494E613A,33DFEBF9BF435BA8,8DE71856F6276769,8C0443A3D1BD7CF3,FA2F513362F81A32,3388B27A29F79BE9,8009AE009FC0B146,7C83CBC4821BB624,0021AA6406D46979,7BEA4D6BF644AC2A,715A3391352B1354,A8D5ACDA8730C050,60EBE04F5D109161,456FFE0E23BFE4CF,A3BEEEABE95EE8E9,F7294F5AD4EE823A,0004101A0480A75C,C9667FEEE14BCBF9,3ABDA0FF19DD27E4,11E9C4C666AF0D2B,B8DB81838D7FB021,355EE3390DD73CDB,DE5F26E8A1BD10EE,64BEBD1EBF5151B5,0018135EE1C69533,29A01240B1C2EE1E,67CAD17532A3C508,54E1853DA437B5C8,6A8BE5F77FB465BB,3C076A2CF29A6C19,5624367DB7953190,9AD77C804DB00DA3,0006DB7FA8FBC1D4,FFC3100EF5E51DD2,110A27EE50654AA0,B1A8A39D27489B6B,3EF9B5FFEB96A871,B05DAC70A59657C5,D235E6653A3AA0A9,651BFDEAB80A8CE9,001019F4E56383A5,FB7A89D1955B20BA,924C5A87BD5AFB2D,B0B0D6C7D4232D21,8D98880C758D5D1D,AC96311AA4B67097,56750BECDD4A6E48,109746A8DA5B66F2,003100355FDDC6FD,8C6443628F7AAA41,3BC15BEFAAA1CBC7,7921319E5AA0EC47,8DDAB99D89312A0F,3F8A968C2D716326,A539134EE39F9910,5A0FCB7F7A6B8B66,00134C6473BD6149,0CBEBE2065884124,743A7B4068112DEF,978DC72992EA15D7,C95C55CBA28D081C,FFE633E4860E1650,35053B4CB601AAA4,2205D2832747310D,000FA8FAE9C8FE2E,1C7D160D890CDE05,D8742A80A183A819,1886ADF7A0B3BF7B,DBA31CF776DC029F,72226680AC97C44C,317CFB844C3A1B34,49811E09CFE94A99,0039B448C64B933F,61E0EE4488589E90,27789E855B9C821B,086FF520A723A163,887D996B18FACA24,D6020E3A901FC02D,1F75E92931EC9BEA,F6CBC3B1A1AAF575,00179D40229B56DF,2EFDCC85AB8B6967,2D1802D75A852B82,E978331B81D633EB,8C53088A1FC33386,9AB4A3352C56E2BB,48E725BAB5931871,CBBE052C4BABD19A,001CC6A97C96885B,348427C7A43F127C,3B4E3840FEE58440,1AF900E7BA995443,39C8816ECC8CD8EE,EC20FBF864EC0EE8,229113EF2BF000D8,39E5C0411E22843E,000220DD50847279,B10A9D33B9D56524,28F47398604C4E55,9A40CADE380C7AE7,F9825AA6520E4102,4C224E01A87B0E11,E418576A1E9D06A0,974F408227C6F6D1,001FEAF83F938B69,B7F679C1EEC748BE,B027B21BACF66B2C,C7E475CD4A4C6D99,60EFF192D2E288D2,2729484C78828664,6CE25D7CEE015049,4D4ADC0CAEC19189,002A1152F78A3F32,AD8D3EF219B169BB,850C2D3DF19F74A8,B6FF920CF9060745,E4D82DD90B77165D,CE88608E441DB5CA,B97932BD74D7358F,3966E6A5E7879CB7,001CC62D760A1BBB,87EC741B5D1D3071,1E15992F2CAC10D8,B33834E9C9CD50CB,328F08183F17EF2E,4901EBC5CBEF7338,B34D9DE6DA244B5E,63AE35671528DA50,0029D96F18EF9AB1,0270CB6EF9DC49F0,A5905922947D744A,6316C6A2223E6B00,1B7826B9048F73FC,957C62E606440492,C180EBD3407C4389,063C0915CC2C1F15,00178AE4D6887F7C,E204FC1954A7BD09,54E6ECCAA01104E7,CDC90F59BA28C8C3,15F92A53CE3183F7,1606EC1AB1CA5BBE,0B2A50BA15FB7FF8,05F438D65032FB0B,001E6FF75E62D5B6,92C23A92F18D1F23,AD36E265A848396F,03636017D186CE0B,69BF74C8C05E9C14,B8E484C2CE33E33F,8B65E50B97F7DBEA,26CE6244F5F476A8,002E0AA168AF4EE5,480CE9792B6A0773,8A804F9E0B55BD06,864B17B813A110D4,5D8611F3909603E6,44404937761D1C2D,667635DC0E20626D,C88DCB751B28AAA9,00144EAEB10E9A8B,F9D9C38E6C953A36,4D3E9C9679B8224A,F56F5A259E8A090D,44244EF93A232DF1,CAD8CB902EDB37B7,A53174FA3DE07571,9293C3770D1680F3,001E5EABE8851D16,E8B33FB4518F47B8,196B5D41E04BBC77,BDCAE9102FDDCBC3,A79BF400A1372432,AA64F46BA8F231FF,66CF354F003EC308,C1AF4DF9BE30A866,001AAA5ACE7D8C80,EF9E9147D6821265,A75B2DB81C85BD20,E0484E709A8DC1FF,B5E924E6BB15CDC1,1400960C9DD43689,C296F66C0CB3B2B4,B3A71ADDFE532B15,0016A8FAA727A0E9,207655795F5D2ADC,5D5477DA9C7D11C5,41212F9D7C7E7972,6AFEECE8B6194D7C,E664272694D338EA,CD9FDADEC45BDFB0,F580EE41ADD39D7B,001BBD580E8D4C28,FACD8B3770D70307,82A66D6986974E18,547F4D48AE611587,160921D3650CB700,60801A978D0D9FB7,277C9CBA8F9678A5,3F7DCFBC9397374F,003E1A4E28CE9D8E,4DBE26B7B2AB6A08,098FE946E2334CC7,18254EEFF78DE57E,67AFF373973C5D4C,8969679A022727FB,3CB6E43AC0BE7D66,77642FB4B796941A,0033B98EE342561F,D40A3759B50F7573,8C11372753F4D466,9E4984B03947D2BB,666C8D2E04AE1E88,5E892C34F0DA0791,1DB46CE01E3D2E04,80BEFC1D62E1B981,0006FB2D6904DB2A,C0A247363371E214,6244F1855C34ABCA,22D7D24AA782F9F8,AF15A7BACE7AE9C5,F3BECA4247A49B3D,1E147D42B5C51F7B,C3C945EFBC2F5AD3,002A0223524BCA89,91D2F3A32F028084,512590D7978012E3,E0A90BDED483CA3B,D1AB59EB55D3C251,9F4ED0A8956C02E1,DE7B72EF9249CAD7,7F5183F0CFEE30F7,000FE2576AB6BA88,726FA5887421ADAC,1676D2B6343EDF71,64F870687CE0F93D,CA750118FE836D7B,E6DC2CA8211A6A50,A94B4B725A483502,FC1E2F013636D275,0012BD210CF7BDF8,6BD45DF51B99EB3A,E7CA6FAC72DDCC49,1AB6C13B5CAFDDDF,4A9B0FD485D0EF8E,8477A8E273011A56,EDD0EA6554B39A6F,DF6CE01A73FC4518,00118BDA0E8D2A30,00EC11592600A941,6367D137AA9C715B,F0B40CEC608208F3,339769FD4D336889,678BF0D232FE1C4A,5EC1DD97A896E22C,A46419B9DAA46A81,00062DBED4564A66,3983A001EA896008,1103D63BBEF8E930,E8141486D35B1298,8E02F260F0C6E817,283292B869C9C940,017C9DDC498EE5F7,BDC0DCFB8D8474C6,002DB7C1EFB55E34,B523943F5FDAB9E7,D275D27EE4CC7C0F,D76BC10F1EC58207,E8E26A59C19AA01F,105E5EE1CC7E2A58,CABF66D6B22F1C0C,3397DF8480CD13AD,00245746E2D7DE6C,1398F19B7E88C47C,EC612FA62327C4FD,57B9D1C0BA99571D,77E0A094D49C2DD3,0F1D48EFA3F8CEEF,FB71DC8E5C64A548,9B982376BDEA2E3E,00037C94CDE9E101,0E9F67B5625F5A41,0644D19873C84A1C,A408DADF509C039F,8214D7266AC91EB3,7E53F617FA48F934,2C43659A35EED4C5,11AC8CD36ACE83B4,0003BBA8D14FC838,326E7707DBAF3B44,C974444750E9197F,E68A4580BBD2B575,32E49A9EBCFC32F7,7F7836B8587303B4,D1DA706FA75886DC,C19BF72F246B7DEA,0003C2673CD369D4,D2243CED46E848CD,DB22C0D1367A603C,A858569DD9AF37BB,9601D8BCF2A87686,A1D9926C7E0541B8,89AEE0321D1B7878,C1FEC1F3B382F884,0024EDC04EEFC185,1A6B1F3953CFAE2E,9D942A8F71B7914E,CF20CF94BF3E63D6,EC697C1D8C8610E0,195599C98E66A49F,65D2B56D04D2E197,C5AF0808AFBDFF15,000D7B9D832C7419,B938606538D2E35A,E066402BEC86FB46,3D717129ECE111E3,D6175640DD2F5556,6402B11EFE03D18D,1DF0474CD636BCAC,1685E1B3A95E02FD,001A1B41B81889E9,DD704126FE9623E5,2DCF53207C769117,811CDAE98EB707E4,F875DDE415DFAEC3,F05FA208150ACE36,34332602EC012151,432FE5CD48E1E6E3,003925D3D3D47484,7179426ED33A00F1,C95C088DB6AC5581,4E9EC64F542AD219,7153EC343C4BC3AA,BA1DC1DD293C9F8F,1881CABAEDEB6800,9DBB555031A241EC,000071AD25D8053B,5C0CBA997A824085,434D27A07247CC24,AD018016D8C15586,E41E2FD2D8CCA16C,C4975B92ABF03546,3E766CF785440089,F2C9EBA6EFF8F7EF,00357E05442DC70D,80F618A6D7458309,F3261350CAEAA962,380A322CDAD4B4C7,B2624E2986C29B87,E784CBAA2EB7F53D,E4DFA949C056EF47,93DB8F10959F5992,002EFF3B08B618A0,4C7EF82370759C06,8DD04D3829E397A4,1D83974E5AACC19F,85730FD9756CB8A4,21D94B25747FE587,0F437EC7A34CB2BC,CD158099608EA822,003C864C8E3A6669,71C6415D9FE7708A,92EADB843C6FCE84,6DFA3BEB91EA6C70,6030BD32567D228C,AF0E82A35C872B9F,2DA0CFA3A529567A,DA64E949AD90C0E7,00026DC47B622B3A,25181423E9400763,E14B44CEA93D3B7D,A33FCA57BFA771AB,9835CEE72B0370B8,ADAA1D2AC57FCF65,E0311936E27CE5D5,4DB5E37EB8AD524E,002679AF58DEEB85,4683641EC4025726,7FFF9B467854DBB2,1C336F8BE4BFC89A,20A94B7F5C212505,012C1D0E912D95C0,6CD81B70EF7A732C,DAE248892ECAF182,001549440735526B,FA1E0E3AC620C56F,5EB0EFA160D71BBB,8642FDF632D5EADA,605C7697791FA569,8652002F8CF906D2,A014F3C429E8566A,DB759D59E93895DE,0000FDE585FF9BC3,C5860C979D2BC086,BB53690E15B6C52B,F76274D9F5DDDCD3,4454CB6EFF6E4831,D2089AEEB8791E63,45C22421D098F5D4,9F20BB6A5CD6DFA3,0015CD6C148A99AD,2DE16D82F4F83C09,F9B162B6438D8DEE,6CD67F54429A923F,D235D4BE4889A969,8E0AAC5A032CC0E9,E807A54C6F6C6846,4468051C3EDD4EC9,002AC7A39FD3C4E5,B85D9D098796B113,A30BEB0520D28F9D,B41131625252BAD0,B335024E589BB760,D9768E626454EBB4,BF66E773DDAAFE7C,FD12526FEDB08F36,003CDCC46CB873CB,8CCB378042EC0634,25D8CE4BE1BF8336,3798034279AD4C7C,88D7F87B59FC3983,D5C2C0EF56B02B2D,D41531A6DBCDC0A2,77ED14DAB68168CA,0014A1DFEA055D22,829D14BE24D678BD,05D8840379FDE8E5,A3104BC1499655DB,54742EE25410D39B,0413027A42BC6A9C,E8D8AEC5094B7F73,8A3DF4653F45234E,00077DD8945A3EE7,44F9F412D74C6F39,259C856EEB13B7EC,D1C6D26E90149D51,3E3BCF538F9B3376,01A803747214A2CE,B020E263A34976D5,FB61F65E59E831FE,00095E16BBE1788F,DFA26C264AD17D2C,5E138E8A300F2437,68D77F2A1EFF4D71,D28DF124EAFC7BEF,E1C834F80675505C,63EA6F15C66DFB5F,ADA30D555E0341BB,002A8A898199ECA8,BAA49BE6EE62AE07,9258C939A57D41C1,F3D3F452B6DD9D5A,88FF98FE150B154E,D2DDFD099FF0ACCE,EB874A016B9B4BC3,26C76DBA66E6E848,004008418CA0CE90,1E5D4DB016D6DAE1,60810577922AD712,DDF55B7B8DFF7BBB,2044BED8BC622EAD,32D46DE576BEAB09,BFCFD62A1953FF83,3AF871CCF7AA392F,0019D2C79120494F,07FB3DC9E426267C,FC685210CE1D5B58,7C7EF55A60C75B24,7C285FFA3FBC66FB,A38B676BCEBC1666,3092924CDB204F27,B657A9503A6727B4,001014190F0F0FB9,2680476EC17CF0C6,ABE893014CF95CD3,F0364EAEDF0BDB45,B2BAD4D4B06AE7C3,9A6C75C9F484052E,DD0035947AF5F314,9A5BEC28269AB97C,00220FC89C6EB57A,B8C19F0909188095,4AE92354F1C281D7,D1CA1DD10916E56F,A077F725AAC3ACCB,9C3D694A625F846B,5F9EE25121CDE32A,F0413A9BFC2347EA,000EF8EFEA647173,6C8FA4E56ED00350,AEE1A81F2E0B713F,F54C9385B0249B67,C3EE61D9173EC593,6B1FE0038BE430AB,AA68621AD96D9324,CDF7E1368AC98F50,003B5B77BE9A57EE,FD74AE5FE556C761,D06C0EC19856F3B5,EEAC21BF0EA6160C,8516A0565E9554E4,08EE3B5855CC1278,3025DD3FC7C347EA,8512196D42276AF5,00081417F5BB2E18,7623A9326CA53DCC,4E937398F4F085FE,E98B8CE58AA88498,D2FFDD7F6AA2FD8C,D85CF1462395C453,D00117764180B843,E288B98ABBD8DF24,00379B8F9E1C440E,D4840E903346B36A,A79BB4F4887E14E6,ACC280946B4C2BAF,00B091C85E460D69,B60F4F6CBD1FE539,46C57C4ECD6885DB,6DA4A2E0A775B7DD,000110E256455D62,62C4EB49B761C1AB,B6D878926F4B22D0,FDE806E02D71D9D8,0449744FB96838D0,E0CF7FD5ABB8F4EC,2417CDCBE5DB4092,001B81B71D573C1F,00097D9DFC1EE850,25EA5177B74CA8FC,0667A16A861A0200,21A67BF5638A9455,4C4ECF1C74F27A77,CD31C1C95B76061A,EE187C4EE1DFEBD2,DBA458303BFCBADF,000C7FD57BA420B5,7D960477CA6BC08D,71DB24E2D36601C2,5B26AA041427DBD4,AD28AB44FBEA48E9,D847CF6B53442166,A9F1427040A2034F,A64875DAB5516095,000D98C0691BC588,530087A2685049A9,997A435E795C8B70,5C4746CBEC6FD705,4F857FD5175D3663,D661377857B2F30D,86CF368A1261EE7B,04E93D2AA58F8CF2,0038B676053BEB32,63D0F40EFA027D5A,2846FDE6D92AC4FE,29AEF49497C40615,1B42FEF4743B87BF,DB207C0A79A196CD,8BDB7204079A29C7,E247E32F34C63BA4,00069AB83D781F71,25578F4A7C5E7733,83D8D6C23C13C091,693CADCD6BE004B9,2CF35857042EDE6E,B7A7440B1D98A4B1,B0EE32E5CD1EFF9F,6CA8EDAA9816A435,000A307E60F9C64D,0A0DBDEFE00A7C3C,234F8748B4B3A097,84D97B7ABDE189AF,E25E0DB63773C6A2,4852C95B91EDFCA1,C0F3F2A1438E30D0,40083815C3E8F1CB,00357BBAACDA124C,DAD856970F358060,95183BA93EA5D9AD,0C84F31B7374C1E3,CFC5B468BB365F29,8DF28B0CD5E1C746,30C888536F994C5A,EAD23071579D3CBD,00092CB6D6AA53F6,31F128BC03D90B7F,DE704C06464EAC02,919FABB9762478B0,74A90EE7607F5432,D301C10B1B7280D7,9E1FFD9310105007,899CB3C5F5285CD9,0001D257C0CBCCD4,3F3AC59B62D02E5F,5B64111CB1EFF9F9,73267ED600B5CBC0,91AA3942B5524F65,93423757C29615D7,AD87D97BFD8B7F33,CBE079AA15819A59,002E2A981EBE8219,477B1A89DE2AC4E0,3C491F7D20424C7C,F73DB38604D70C42,620A02E2CE11B9DF,FA717D739E39D3B0,36E2425F175EF98B,5C77D9D31FF6AA68,0037DD8954DD017B,CE1854AD5D1B5708,8A563C015F46D2F4,79487C3F31D83DA2,5950B96B9A686B54,4BEE0EC3BFE1185E,E54DAB0A9C910779,B7E7D8931BBA53E0,003518151D902811,BBBDA130364A1569,042375E17B844072,A83833AAB45E103C,7024422869721A80,449534090692B943,10AD5999BACC9A49,B20D8A3E3538C68D,00185BEF44DF3EC1,76B2E6ED88A82A83,B87AC3C8A5A03AD8,C66BBEF5A7D01448,51880A8AF804F718,B889C273D8BD50E8,51B417267EBB6981,74E3DB3AC255F77C,0018DECB12D605D7,ADE1DBD911589F69,836B5A2F996FC07B,1246C1C7B60A2E5F,FC9E61129F5D1C3A,53B23569AA593215,3C44190F4FAB0593,052E40C75D82C3EF,002A79DCCF05EFA1,0765951770CB0DCF,E3D7DFB47A9980B9,78EDB7FD4CF668E3,7625D28BC58183F0,0C64DB579E71CFB6,95C23FBC88D0F062,A30413828F451224,000CEA8A98BF9B00,45D2571012E58F2B,86754A706234BF7E,6DBD511D7071AF30,409312F7D7B7354D,CD1D892D99CFCF98,C5FCB930B07B01E8,5ED13849298632E1,001BAB757651EA63,0B830B66C0DE9D1C,2524C890118D3520,ED55D9A7F2A572E1,EF847CD773379690,BFF784D6EA3CA0FD,69E0319628D2F8C6,E301F5B198DBCCCD,00160FABA219DD63,38AD04EBA916D2BE,2A3E39755CF5434D,7409225BEBEEB85A,AC1D485D4A8B3A50,6ED6D3B871680267,59232244B3F6C6B5,44F534C337386FB7,00084FE9D305B11C,5BD07669558DF112,70285DBC0D331BA7,64FDFA5E5D328DA8,37CE823E8A5EAA68,175101A9F44EB2C0,58544362CC1A0FD3,B8A2CF805092028D,002A6AA2A6192001,9C5A8BE914DA27D5,D5697F951F850483,904589DFD67C80CF,8152A2DB14DFA827,751D6083EED499B2,125353F10948B575,C4F849FD97ACDAA8,000A918D254690C4,1E0100EED689CBB6,43F9ED46E1E4E9B1,29A1E63DB1DEBF84,F88F422BFC0AAC18,0BE15F1B23C4106E,514C14A93F0DB9A6,5A1B7AC694411921,002D81FEEFD3C823,E98F400ABE5659B8,A24EB8FFEFF0EFBC,935C5759CA277111,A5330DF913AE9B28,0C47D645870009FC,A5066A889BB105E2,45922D13F943BEA2,0027CBA4B5241B13,897B0EEDF58BBC41,98E38BD882FEE876,5A19A8A1E2C34D66,60A3AF0A782C20EC,805A5818AA3B9F6C,585BD71EC49D45E6,60456E9248EF91E9,00185E1640BF851B,8DA0177AB3AC5DFC,02FC2A69C2BDAB93,9821AF901999A336,76E71847B000C1AB,9901FF41ED78EB79,9A3591103E9295E9,CC789F5D2B5F9C51,002D44FF2C27ABB4,F1FCC6378950C5EA,E31690BD5CEA91AE,5B1891F4EC467070,BAAE7E8D2D363535,5C5E26330E7CB480,3849A1421A86E02B,78304D9ACA1FE321,001AE8F0CBD8075E,A635C23C3987C859,B3C1E069C69A5A38,01E4D360146DE681,B583015DAB0BBB4E,FCDAEB07EB09DCFF,469C8757FD53B231,95551E1E2221F9E8,0000DD44163E40EC,EF96CE955867622C,ABF76671AF13E49D,F2CD534F6BA6174B,E96C3C39DA399CC1,3D772C0929802AF4,234604F2DBD61850,2B1B68E2BB2B76BB,002403085318D4CA,1C93D71AEC9EB2A9,8A196FDA79733648,12E2E3EC67B7CB72,4ACA7CD788BCC596,B0D0589BD1775052,77D5851967522FC2,F7FCEDD9977A673C,002226337D349572,E9B50A4300B3D06A,5EC82FD55EE0FF0E,72764B0625CD4500,98353FE4BCD904A7,4CA543D06094332D,086B5AAA64FD3E6D,B2EDA05DEB451160,00327156BE72728E,D99FCC134F65EF19,3E2F87EDA795A170,7C5B444B6814FFBB,2FC0F09B668D28E0,44CB2D58B82758AD,97727CA3C8A1112B,410F5FE5178E1BA9,0028D45F256842CF,6952251403957405,A5BAF15EC8613C37,6576C085D04D5AB2,B724F281F6008F65,6A606BF20BDDF86E,D9EB3A6E9C2947F7,6DDFDF2FA7D425AA,003178DE840C2998,88C279932BC88A7E,3E6124DFDEEF11D7,BBA4DCC3A60D82A1,D87515746BE8F535,D33DD1D40E1A3236,62EBDD67878D916F,3B8B2EF5712EDBE8,00339B5201BA38DA,36A0387E8413CD76,8D76D58B224D4496,380F7653298A22E8,44A279C01EE651F0,FF837667CF10A72F,BABD35D519B3B4CA,372B65DFB1A28157,003B9109B9D11517,2A7D3FEEE19C8AA1,3D307F1163200FF2,A0CC490B269C86D0,9B9847FAA23CF9A4,BE1C9959C9C36971,46787A0F12454ED3,72D7631A90BE7336,003C4581032D0DB7,DB91CDA344C176CD,AECB25B0B052F200,1A66DA45D80E2BF9,60B4892A8FCBDF63,85A2F904A5A9F6A5,3D7A7D951F95C8E6,97454E4A8EE48802,003B7A2CD6B42C1B,2481649F75450EEE,97E471AD7ED219CF,AA19750F3D18E9A9,A8EBFC572F2A8E58,CD18019332CB01D1,6EDA18AD7A8C24E7,28AB46842647BBE0,002C08856EC636A9,03BD4ECA256FAA97,171A12BA2056EF66,BC269634F9180968,2E1A23617D4D1AFD,2AC8FFC841A9C40D,3828837ABE425323,FA9624F6DA20B100,003CE1005CD9EE25,8FE400A0740F4091,840B8730541CFC11,053EC4B497585519,81399D176E0FFDA0,9C612633DDB353B6,B2B89EB007A3B15C,1B7BD4727DFDA094,00273C066A578E5C,A1878DD95D86E217,F285C5122B6C4F0B,B5B7168A0FAD4B41,45E2CB08BD53E211,2E8316227D57D4C0,53CE5E42EA5C2F5E,B26EB4F46DB0C10E,0013C6F1F49CB306,E1C6738AD2568643,92A1F12FC2084B35,49CA8334CD44D75D,68ABAB76BE12960F,230AD76C96E21F10,890F216417778E88,017D21D8AB028F08,0006329633511AF7,772AED680D5A8D81,E24F881B033566D7,4935CF4CD5C3A262,2C25E1F8367D214E,288DDEB3D62167ED,75CEB293E2829615,5FCBE81410658037,00199BFF4C4F0043,AFF1320C7A738E2A,D08F51A3E7EA8E07,E5DD52189BE94FE3,8B3314A5F8E157CD,785B07F0AAA53F18,B2C4159680F1D550,79CF060030ACE467,00200A285D040ECA,4ED38856E2C19044,CF54B5B921B916CB,252A2A7F828D9FB4,6A0023C352F14368,78FE27DECA43AA99,27E962F4020DBEBE,82CDA38BE35C84C3,003C4350242681F9,DB06E86338544A68,23EB4AD1F3DB459F,1FFD9DDA4920886D,D8E743E0A44633A3,4A76640E862E4861,9020512895F8AD41,1E3EF9B0C152A202,0021EADECF7145BE,0D9E28E19BC86A08,3748071B4E426F03,9C8E4C44436BA202,D78F61128CB058A0,BC2C8B9BA4368388,8ECB1A8DCDB93FF5,3CA99DD4E44597A7,001348D6300281AC,DDE145E559E84474,B5009516C54D72EF,9B7D4F6A607966CF,4F9C4C4DA83D622D,21D301A9EE542DDD,BE43D9269CBE9EF1,C4F1E2B21ED30757,003BC5B96EAE73DB,899C792EFD35F980,6E99D4C8E29027D7,CCEE7516BDDD69DC,B5443FCCDF8D829C,0C68C580E9255FC9,E1D1472D74584187,3A0B124D78601669,00191E01CD0C3BF8,56E7562A330ED7D7,8B60E6FF8A3EAFC3,04B093BE14B73166,A31C1B506AEFC909,ED9477A481D2894C,C4D587D3354FC3C9,46B89C253A61B565,0002D76F4BF599B9,D102F141B575E2FA,FFDE0CE408638C1F,563F0DEE374B05BC,644EBCAE84F29638,21CBFE06B4D1B0DC,8AE8900CD49334B7,7F568CAFC14343F1,001E168BB9F71C29,1F301B7FF7B393F9,F132A0E89CA89F89,23F796E0804E4C7F,E8FFF91A2D277005,3DEFFE0F4AC34B50,84E4DA7EF4747C35,15477CC152335D9C,001FE0B75AB72BB7,1078353CF384299E,A978861DF7FFCF28,1524F4B9C70179A8,DB5DAEBA282E3148,52ED795E67444BC2,3093BEBACFC8C1E6,CC5535571728CFC6,001907A1B140555B,B3584D25ECD625A0,84B515DC097BEAC0,83877F238974F262,F3E810931FC01D8F,7138E5FD263E65EA,99559233B3EA12B5,01A6ACFA720A9B00,0018F4444CC0DB03,4C526E5370862804,94F741702BE280B8,94FE018632BC8B4D,CD6018A9BFD734AF,BFDD861CDA02A87E,8B0974115E5ABE99,7A49B078F76672FE,000D8A8C9D50F044,534319E087962457,5656C54C7E3D33DA,B1E58CF193722D73,89FDB13CF05E5B84,20CFB64F2CF487EE,1C0E70D1325D9E0C,57792B409D24C89D,000FF6B2FB5B6DE3,58BABEFE319CFDA0,67C17AB6A603420D,2757808E9FB7097C,1BF509787C636D77,CC6BB9B1DB5D431F,D3BEA2E8FFE80152,2E38636FD910C1FD,0038B7DC1ABA79C5,065AECCF4D6B335B,2724CEB70D9E6B2D,7821F2EAE7C957F3,F4E1F36C318E9681,2623639456A27A8A,8D0EA70AEB1253FF,A7FFC10017C90885,0000947AD67FBE54,264510E2E839FD90,AE6093B709F1F9E7,290451B3091878D4,9DC2C6FA8C93DBC8,3E6D927430FBA1D9,BFAE5BC99F69BF89,08B002DB6A3E8EDA,001CC0590E8697A7,6EA541D87491FE14,8616A8CB94D5733E,39DBC3DABB094B90,DB2006C8D5E496AF,E1FEC3FA1C1474EA,1CB8CC0DED043B05,6677DC7BBCC8491B,002E2C4BEE80FF08,3FE98D284F449A5C,8A0EB1908C7CA5F9,3E374719DCAA5B7B,204AC94BEFB7FE5A,641E9B47BEF58254,95EC03999A2AE744,73F275BF7BE3A84B,000D2F9C51E7F915,90F84D8EB0C2ABE2,0335C5A5486CB457,565C20F2E98D77DD,2614B113E60AF7DE,E2F8FD343768D607,57BB78F6B2A7BA37,C337768F02B3A9F9,00370FFFD9CDEFFB,D88BD6E085AF9870,75E77EB02AA0F8CC,473C5681FB42CE24,5E71ABEC78BD3C42,2F7BDDE02DACB82D,7CA21A7EAD71FFDB,9E22C01E969A6682,0031E66B6896291F,FDEB56876C0B351D,2F6D5EF5A5206994,76789E358FD62C3A,558DC0793AD13F0E,E2C16940FE1874AF,D5B99973D17DC2C4,0DE865DED6C51C47,00258ABFA61D3FB7,88726D458EF35AF3,8A9FF7ABDF529D6A,3B11A254C99EC670,04E5A6A36504C751,B3BA634F5D68A91A,6660A8E3E3D7D04C,01E096A449251B49,000033EF842D0C46,E12B899C7074ED5A,E10C4149914E3AE9,AF96880E28FA3319,57CB7EC13265C70D,47483AE8E6FD0B5A,FB857A766A846DD6,14CD8DB953AF8827,000FD67523C8B000,7EC67B3F1DF73667,71E2D0EBD5E345E5,378B8FF1B8CDD35A,C94615E8FC2F8447,F7C429D0255302C4,018E03608BFF9CEF,88C7692BE23551FD,001567F219D40536,F00C4F470373EF04,C67D3A96938ECFB6,A7225F8F5087993D,783273B5CF9DED34,F8D5B5E7E18B6B20,0DDB3224086E653C,0C974EF4E91B9A29,001F4E4DD3E365C9,3FB1AD1817E3FFEA,8C8CC25D5B1ED8E6,59C6CF66FFDE1405,42FC2030DAF5FF74,2C0054FFB4958D13,CF78481FA8FE53B6,5B4AD68A3DB277CC,00331D2854347353,3E468E8437867A28,67AFBC354AF6BC9A,CE9D7DDECE7D5CEE,A76E6C52D07DEB7D,63648F4D37ABEC3F,9E90547C6393C024,8586693660164EB3,0035F8F2E81A2CC5,88219AC7A6390098,36C594C219377691,45AFE246B805A101,5E2437F2E14398EB,72F24E994955901E,B767121ACED08D25,009D7F24C87EE11F,0015B34704FFF7E6,73D0D2987EEC815E,C0F153B445044583,2D13A95078097449,F0AF4EFC0738D7E2,A6837163F3B19981,65391EEFC292C0F6,4DDD2F14060BD77C,002BCA15F975F430,5A793A91FFA3DDE6,F0F06BB2571179ED,59C51CCD75ACBCE7,F94A139E5FE49B91,851F270200EBC7BA,988312AAA0AD9A7A,C695EEE6FC2DC4F7,0002D3FBCEA3E73E,E286823819BACA6A,2759C962924C36DF,D65C6EDA2F4D5862,E23A4CCFFC9B0BDD,C6755B34C2BAE354,1E79CD295E0B61DC,00D8E0CC11102A4B,000A65D9DAAFECF6,57F5B3396AE7EC7C,A27880994C84CEB0,A108D49B1CB7774F,FE3E9242D8BEF8A9,5913BAD3CE790C53,6F9D9F7BC7D2EF9C,2465A683306CEFC8,0022CF994AE5864B,A66E7E8701637B98,E6295372DCE7E887,1E3D485FE79A23C8,E22C64421839F69A,02E6E51A78EBF896,B4D527E563148CE2,BEA0C8D6D7EE8851,00016AC25ABD334D,D8AFC0EE42ECD5D5,6D7BBE9EF122F4E8,88ED0DD14F9D1AEE,41F5836D5670B9ED,8A2C931675330477,9E3D9654C69B67B5,95BF68B8F4327444,00254AFB0B811C49,0FB5C4EF03B77159,443BF4FB9F4914FB,3AB41756F336C9BE,79B213E3E518DD3F,E45D06D509B41EA7,DF6A53BC1807B152,E42196825D5327BF,00366947BC79F193,80E8D4681BCCA9E4,39BE06E229CEE4AE,EA74585486FA9228,BAE2F41A170ADFED,CC5707B9E6A0429D,3FC8776414806C29,D1F07420DAB33D09,001FB59CA2FD9800,79F0B4B4449CA594,27D0EC71A18226C7,4B2734B295638CEE,6801E3DDA230D3FD,EEFFA0D0C6081952,21B894593FAEEFFA,B60F389B24BF6B1F,0032FC08FA154AE9,E47EB04D5C81E19C,AA3F2545032F1A11,325D4581E1CE996D,D0125121A923E222,C527FCE909272E02,03669B2D3A145CAD,72112171C3B2D57E,003FF660C2005158,16ADB9E27456C1F0,E8219BE1FAEEEE12,3A96D265F5DB0522,A46E92015BD360C5,E18A0487626297EC,010D6EE1BB4D8272,021B902C03EE9AAA,00080221C2E3C41D,0C7CD443A6E6BB30,BE1933430E6967DE,A1E370D0D1C6373B,E048F1EB79C5C492,A6B28B98662C0FC7,2A18110FAEFF1A47,DACC9A98F1BB5758,002E38D9C8C9F209,A4435EBEE9B49AAD,F1252C691A48CF4D,ED2B62D2D58817B9,3840B55A490DA8D5,49B468125286BF91,E16486E895F446BF,079D6096194AAE22,003C51A8C2DEDB63,E0EEEDABF60910FE,7E1D5FF49EEA87B4,13843C67A3BAF041,2AC81A887206337B,138CF0E63867C661,EA1C59BE06304587,E751ECDB4597129B,0031F54E26C90BA3,19551D83751E330C,85D9DCF7389D2C25,6848A69AE9DC1405,00BB637575E177B1,FBB724F3AED0CA34,8C428A035D2233B2,63F51A9E8E9E4328,001EE9EFDD7D31BD,8F82A17784790121,3398A3859A81FF55,3A5F7FB3EB5AA816,C804CA97D1948A91,2D6BA62BB1FC4D23,97BDA6D05605C1BE,7A492FAF39090CF9,0027C0C804E3920E,3D510F3318EC4EE0,10D6D9E74214CCA4,CB21734F9EF49E2B,E0D69AB5CA53425D,F2B7A1E1691668E3,64362A95AED21DBA,40709095BEC431F7,003D7541B546F3E8,B3128A80229847C8,4DA8243E270A36E1,70F7DBEBB901275F,78FE0548777736D0,F55BB9F9AA1DE88F,8E6E8178F70CDB21,7EC2D14365B7D5D6,001F8F67575D7CAC,C5C9AE9294D64EF4,8D822BB1933C2CF0,16B2D8C093FAE622,1F44EBE1BE627B82,FFCBFDE53973E979,3F1793F0DCBCC798,F6DFBA0B80C13F79,003608147B8B7324,4FE0EC853445D58C,5017B8021B4F19A6,53DDF15CCFFC3BAD,E66585612E7DBFD9,F922291E71C9ACD1,320E83BBC9070109,4B9EAE0373921B72,0012D85F40056F5D,313B0098A7FC1C30,27DE97D14AA410D0,8C9C363F450A3057,3E91F992D7FA07C9,90D24F7AC7C32E7A,A7B8CEDE6159DF8E,6F3D1C0FB1524A8E,000EBE5961655E26,E34873BB17BFA945,A92137B991E385CB,0C1814049F0E21D2,4AC3D59AA6E6584E,7451D7266D218A1C,7724215D749094B7,B0C45837459D1EA5,001504D0E84D8807,12F369F669F2A978,2EE50C7990DB1A90,46669B0A5619C8AC,90556C871A04E829,55CD5710D25F788C,58FAF42D7CF7FF78,D8AB4BC26F75CF7B,002BE0E0734C10AC,F511BFA9E282D87C,C8232FDC845D13FB,DB7E476E0F92EE1A,6B7FC0A6911ABA70,C4C21A7C308F4CEF,0DB699286D7FE43D,3941ABFB914F1AD8,003020E25EBB5946,3101DD85C96F272B,2C9642E6D400E52A,7F6DA080EDFB5989,52663ABEED863F43,62EE49D4D6C7B30E,E1C47B7E94A1EB9B,088ABF2B89D7DDA4,0030479E53A5072F,351561D504EA8FFD,96353F8C28AC6426,FC69CB58899C6DA8,516DCED255EFC183,9188A3908E68C3D6,C2D22ED76F5AC486,DCFC0C7EABE745DD,0005FDFF94E4D514,3DD2B1BE08F16AC1,917F85F5F0E1DE63,AD54D14254031604,E1A1490C1ACC54FA,B3E9DAF0D786AB50,408C36C838DAFD47,0E34A2FAE98180C9,003589F2FFD78A08,FE284106596E970D,AB7876CDA9411B88,CE6FD98B93A957D7,43E31C5235F46C2F,83A95A018F3F9AA8,8382441DA2A4F8CA,C437D69EB223B823,002CB5C87FEB6228,A8A403CBA0FF19B0,5E266D267662D407,305B52CC7A5002C2,41333DB1FC47D0EA,D42B784E8A61BCCE,4A2C55C2C5638479,508E5D81309C176C,0008A1452129B32D,0423B728B9D9F09D,82C0C848ECA75D67,41BE0C82CE9EC872,7DAC8A3D03B6F3D1,D62B0DAA5DE7B0CC,F75E36CC36C0E010,CF6D22012F5DB24E,0006756CB5FD63C6,468786E1FB77CAD0,EC7B5DC72ABB8957,619F42EC9878958D,B456E28922D96701,A815781D2E09641A,FEF512A0C6A5824D,BA0CBF694050837B,0039F5C7A9834512,00D4A0A89E8C2D4F,F1917D7CA2F3481B,87B9FEF6F9CB3004,909227614E099978,99EB7616D021247F,FE01E74767AC401E,0274EB769B629B0F,0014E2FBA95121C9,94A75A75BBE7FF2E,DA75BA6E23E5F433,F828BAE75AF9616C,311DD75CA4E89118,F0525B171424E0BE,BD2B3AC01FCF5A66,E35EB80372499014,000309B01EEBA916,8A53B2AB3C3A3109,04D9198E1D3EC01D,D8957BC70A7BC831,753692B7A1CD24DF,4D089A39A4BA3F3F,A47D6E44451D3CDD,CDD52E28082F56CA,000BB35BBCE29F6E,73419EF74C26CCD0,4B8FB30AE5CF8D16,FE08B15FEE594BFD,BEB8903FF717CBFA,98DBC53912A6366E,3241ED9977C0665B,F469020E692955FE,0039899AF0CD68D5,8425E7720221BB70,30B9D738F5F077E3,AABF0AEC5528476E,6811B185BC271733,73EF819E07A6EF0C,4A5DEAA3C9F04E58,559318B98B4CA196,000C3D5A971B047B,E715475BE4A170FC,A3F00FBFB950F535,49AF6397219ACF01,3EC2DD71C0EEBC19,80C02F0F1B51223E,08F435BFE3822ED5,581D8FF1FCB9A556,002B8884E95B483B,A222525FCBDBC192,BB37D760DF9F19AD,BE5F9CC0659474C0,01C3F4819D93C509,D6D42E075BF202BD,33C131154EFC9CE8,3EF65690ABEB6CA7,001011D066A3F3B5,6F350B41B0E2030E,EC5AF6CA1C8018BA,DA19B9C99394CDA7,FCC1E865B0CA7E02,74608F326FD050A3,9C1933C5C0CCE223,3D3B0B3904225B5D,00188901582632B5,F3E9252EFBB346D3,14443C9A9E2F5BE4,74B956625B2153B3,77A59D98B8E2457B,68FEFBB7ADA985F3,53F806100289FC68,61AA662C51047ABF,0020DFE3A01FB45E,99AA6B1A45651321,0A3CFE7BCCF5F6C4,7DD26CC880D1B995,ACB2743D18121404,212503804A04AD7C,93B8394DA1FD4B64,FAE044F5F79D9D6A,002ACB5B533C5C4E,2B9FA38F8721215C,94E6A61157AA0B3F,C81C29CE24BFFFCA,79ED54406AB5D2F6,308759D82D3AD61F,3C2F7223C19FC661,7CC6D271FEC79528,00330486350857BF,26615F7B8A62BA0D,F4A7B78420E031E3,B7F47119011915E8,BD2D4DB8E56BDCD3,762A8954379A958B,FB34A0518B0DCDB4,3205A9056032DCAF,001813377CFCDDF6,6848C716E24720D5,8DABC858C3DBB58B,0DFFCB828D7C2D8D,4E65D59EC6D37BEF,C6B4506B81F4EAE2,FDA81357F04479BD,D00EECE7E0C089F4,002750E0210210CF,988FA996A8485EEA,A0FB1D79FC34ECCE,439A5E68F976E925,03883FC15F3B3C96,A4A7659381F01D47,3842CDD791E3968D,3D52DB376AC83AE8,00384967C5098F2E,9A06CEACF43F197E,4B496A033C0B6D4A,B9D10FF000937F02,8DD87BB11653158B,A230C5BA53108202,D80F55306423956F,2AE258BF1549D235,0021E435403E3437,6198EE2290442495,1A395D2F4ACBDF63,A2CBCB0BCC9BD812,D79435864E1CE8FC,022DBDF46B212323,394B4DA3ABBC9F2C,ABD92B2C1E3811DB,00379CA219886F0B,DC62B3C45930FA21,A345B17AA2F3A849,C6DCE60D7EBDF424,011622ED918D97D6,253F30B81DC90DF2,CC419139FD6BD18E,23EEFE20EE3DD71D,000F9CD931AED018,617415AB2036F66C,386E82F035C8F84A,DDB74387521DE814,8578191F3FB15B8E,AE102220387D8E83,49A553CAC8A824B4,68051BF29ED1CA7F,0003329719A7FA60,43BD05729152543A,1E04BF9934F08581,E8DB1C4E747C3A6F,BB3EA1974F8D0F43,A06AB925294D06A6,01ACB8AFF5016FC7,279E40F9B6F84414,0007FB1F19BBD2BA,69E59024279BC9A9,A535C16FC07CCD3F,922C0F631639BB04,A84EECC5684D16B9,028653374BCB8C93,DEA97F1FAC83CCBF,CFA2FB6C22EE4535,0037666FD8DD5A3F,B64DAA4540494ADA,74F65F084F078B1A,44B16BF9044DB1A2,87EA69F36E9A3186,8FD0006A183A430D,606C6640B4F052D7,2002AED1610B2904,003FA50E5F36D391,44F19BA5A0D784DD,6EF7006CCD563CB3,8E42A26E01235C0A,EEDB77C4D5417528,2EFB4A9F9A3F26DE,05FE7A23EC806C04,82367D0758C89C5F,0021D90674A3C388,1400B7EE02F899FA,2CBBBC9D534F5A14,0DDFD61CCE19B7F5,4729BDBDD7D90C1D,669148510F08FE5E,9919C31AE811416A,EA8ED4E5331D681F,00093195FF28F15A,C263CBC8AAFE4EA3,4DF0B218D5CCAD59,80F7AD3A83B9678D,2E87785F43554719,71B6D258D084B26A,A007ACB227F68FB4,8E0D708E46ACFDFB,0025658CA00E73CD,270F086A78DAD7A0,44B7E0C9A025E6E7,FE7BDECBFC7CC9D3,AE3780B8D8E79B21,625D10E57C0BB81D,AB72A54C5DC0198B,5557978AD4F284C6,0036EF0FCCE8083D,46BD285F4F017B2F,BCEEE8DEDE44729F,B266A608304C43A3,A5A0AE185A98080A,35422A88DCC876BF,30DFE372DF0098D9,235DC6EA67D48A68,000B6294288FD136,D56A3C2E01BC31BD,72B3D30A2A85BD58,3CF80932DF2BF04B,4634CB34E5BBBB55,398D4842747F8B48,360C39A89C1484BC,01605F9093FF6293,001ABAD51E5BBF21,49348A69015DBE0F,FE6B8D78930CC53E,6308C722001077A6,8640652D83250EA1,B0F88675F9393789,DE5BFBF8BD247DE4,B93FFAC0DD315E59,000FEF197ED80584,A4903A876351BC56,6185CACE787C3AA4,391CB180688EC9C2,B4DA4D3FAC916CE4,6DD173217C4B2A7D,D1CB7E8AAB35B7E5,8729F80D8CE2AF59,00338E9C199529BA,1E8F47F4FC6719B7,FF9FAAFAB1CB68A1,DD72CC297A4CBA6A,2414F8F1B99DCD78,C51A2C881FDBF3B3,DC5E29D025939918,1449B1996B6D2FD0,001EC44014DB5A3A,E7380719FB330C8C,70EE00C1AA2C4A8A,7F8FC4CF56EBB5B3,CAE893D0CDC80C5B,5C2E162C40DD761E,930E08BCDA1B4E1C,438F3EC46BF44D86,002EFB7F072B4770,ED2828254A805AB0,E3D03F798C3C7D85,2F980501BC14C42D,871CC1504CD88F0B,847564E81CFBDCA6,B2C41804F3EC303B,0B31EED244890F97,0037A4036E49F06F,6A350A11B31C1144,FF54733DE87A801D,3572732BD06E02AE,B24108259A6483F6,A569484CBD247B26,EA8D96CE7482D984,7187F654B940EB15,00332B0F969F15EA,4030ADFA554CC628,35D2B9E1F2A524C8,AA924F10B9113AC4,D85F3A0E4B41AE83,21BDF508C0259D51,C15C8B2A462E3701,DDD27BB0FB1C83BB,001A7183FC07CC42,EA5D0FD44E270C56,AF0FD99F9D4C3FFA,EEECE581C71D909F,5AAA0EC966667E03,626E1673E65B18EC,E184FD5724AAF897,B14962740CB5DE0B,0019EC6DD3A0BB49,785EF605726D1468,22B0009D9CB65804,F29FB86A299DC063,A95C7F5570258076,ED7AC6932ABE63D9,845568C78327CEC8,2BF75BE151488F81,000CAC2FD3EF2735,38D3CDAB650F6675,8CB85D334F77AEDE,789C7952368C3F7F,C9ABC4DCAA823433,086F819E94871B52,8059646CB4ABF3BC,3FE4B0A2AA254D77,0033CDA21E2A6A28,F95865B79CCEFE81,A53841D7D8636560,08DF60FE3FE9D5BE,D73CFAE53A2450D6,1ACB4B1AAEFBD76C,6F9AE5553C47DA6A,22F01B82D9D5C3A1,00222683E40896D9,2458EDAEC621C537,973D92BC482A86FB,06106D491703571A,C18671D79B002327,DADBEE6453678703,F0F375ECE74B5A37,E9CC103BFCA75AA5,0009A8822DD6FD2F,84BE80B67B1302D8,7916720C5E1CB465,66C4825669D0F4CD,D1737ACAF1B78DA6,F6979DB9A81647CC,2435E87251C826C9,13EE419BE462CD35,001211B57446F0A3,A88DDB1582857A70,3B306BD1524FD81F,2CFD164F06F3D5BF,9DB1B397861C7ACB,4680863A8BAED816,D0DC2D10D9FB37FC,37F17F8FCD224416,00158464F6CEB2E1,28805FB758720449,097096F71D510436,8465A57C7D0986D2,9F0510A4DFB0EC51,F098E55AB1A76120,A2E3CB6DA25507F5,A21C7A4751644AC6,001210613505E329,9318A04716D6C2A2,282BD96E421844D8,E2F0FDD727B78B5F,A40BEA0C619D19CA,84F53E8754CB0B61,E018907468F3A218,E2FF2B725FBA15DF,00263591649A1CD0,950735EE4DF03E7D,AE77DCBF9C4F5BDF,D8DB0F61AAE7967B,7D19107ED6FC25E2,AAFE36F1260CD1C2,F035B6B6DE840B7A,0D7F332FAD0140B5,003A19854DDA4545,0DC857901FE025E6,7727B1074193F32C,77127292D7413F44,1512F32D0DCF1DD0,3F52DE509F288987,6886186C1B608CE2,F5BB74BDF4111DE4,000F076311D128FB,BF67CCA65C16974A,3DE3B3EB32B1147F,EC289C7105A9DC05,57A3DE8AAC392F49,A0C9616E67483A9D,5321A675E55EF65D,23CC8EC5279862BE,003877F3B197501C,4C5B268E90FB519E,2D00538E3D23914E,BED05266F5B5D748,99AF59B8782CCC41,A80C9B40F0770F12,6452550A25E6236E,DC6E147A36DFEFBC,0038E93E6C332F82,90B7311D6AB70ADB,B8D12E0E7A352D0C,A236DE897DB9FE08,28B7C4AB7CD37272,AA12E3EFEE94D441,5E5ED1088D2B8DC2,142E68CE96B1718F,0009711A85BE6AF9,8BFA4902641C9B13,086C50B53C8D6ED1,069FAA0613057BB3,3255850E89D1B895,B96712AB19B6056E,0BC69F8E8841982B,953CF852AEFD3050,002CDEA37229ADC3,7B70674CA5F0FFE2,3B3E9FA9C40B28D0,C1A0C479D4CE362B,1E2F8CACE2045627,BF120674642F4DAC,0A59D3159CEC424F,4D7166E501076B34,002E7CA4BE5BBFA8,FE2AC67825D3A6E2,1CAF7F9D6F263465,6B1FC3751CF2A6FA,FAD134DA52AABA48,1AD2C0DA02FF7DB2,EA94024437D7583C,9EA0EF519F288066,0004B4EFECA67C3B,BE30441539000C28,1F1A3D8DFB58C3C4,CF676FE941C4D7F0,6D74646B900DC3A8,CC123F5EFC75ABDA,7E533258E48D5A01,E0321EF8E5644922,002FB43824E3958B,ED1A70377820DBEB,B4677E84D6AC8F49,E6F1DC6EE5FBFD64,CC9553685CC37CC8,B2BB20E8299DA73D,08EB959C054617D7,C221E6C76955EF9E,0023B99919DC4A56,B855520750A3B4C0,0F22E536979361A0,0942D0AAEABE8374,40682D731A491556,BE1367B2C5C202B3,3DBF009C7D740C70,E379FDCB61FD2B26,001883BEF5DC36B6,C602854139BD258A,93D2FE62C24FB759,5AD1CF7307BD42BC,2D5FFF7E1E96FB36,EE57393D7D622E21,118DC774BC422957,2F62EA64A7DF8B24,0022C9BC1EB01D8B,E0C0108B8388AF4F,2C42BBEC754056DD,054BEE615E6C7FBC,38FC59EA32CBEAFB,9F26BF363058EC8A,A76150B4E3F29514,FE3AC077917C7555,00227C0A6D0AD268,4BF96EC998A9FA00,C4EB4C37FD58576C,3EAEC45DACD24955,9B306F4096925606,6B1E9DB27E9A9E62,80BD5795EED3F125,4F6C497F0E29DD57,002401483C8A4800,E1E30CF683DFE784,F23413A1314C3A07,1D5EAB026635837B,591993B1A55A8BFD,5FF8A16BCAAA0CCA,F701BE89CD9E04E1,9C443497B9A0B416,0014B0F4D40AA634,69FF2187F902F56D,15B5694D301D3CF1,724D7BF142B212A9,98DD53E6B21B649B,2448A11472A981DD,EEEEF6AF6352B6A4,992C6DF3BA37AD7B,000DD76C8414C8B8,3B90519FAA531741,71A161B0808FED81,EF495C5BD4006E87,80BD62F0BAE0539A,019EE93F1520CB69,470577DC35C6741A,CEADF3AEF744DD6E,00308E1FA9CFE27F,53693A1040096A83,7B581AB560995BD5,DFA780E31E23F07E,02DBDA631A1BBD00,452018F982636F15,015A045593CDBC22,92FEE4117402CD3F,000F6C97E0ACD5DB,240926855E054D35,7F7FEF162B4C827E,5226E6FC739BD052,293C870CCE7D0816,38833B1F0AEE9492,681A6263106862A1,511B7E5C1A780385,0005DA98A16A8C67,07EED3FA743D3F53,A5DB36BDFA4C30E7,EB75BDB075E3D53F,D1188944EAA741AE,412FD2FC16F80EEF,79BCE1F75AB73CFE,30ED8D24CA0804D0,0006209011C3A977,21E8E43FB1123270,C91CBA5664F75811,C77C69C1E4566210,BDC9FAB3CF479D52,78F0669395B270E6,2B0D156436CB1C6F,0041966B996C68A1,0015D99FBD6D2766,1A2D284056579F20,AC01FBED2571D0E6,831AAE78204AC38D,8C488089C0B42EBB,FD0C6D9D6979C4A7,4F1B6C7D398D725F,BA2B4FE9F84DA9E9,00255E7A84679769,F8EB6FEB477B4DCC,321D26C35207EE9D,61802FFF8E3D9544,99349FC46A58F86E,E58E97796CE0657B,382B8361B7F93660,AA6D36E749396B8F,0025C25B7B103661,6C0A6FD5DAC93229,81DD7CFA295E77DA,8301ACB20ECD2BF4,AC79456FEE1708DB,1B63C767310E49E1,59D0BB38A3DA1B2C,2FFC656436C2BC30,0014DDF2CDA13142,6F669A179A9B8B52,6BB5B43431CCC687,3378C207A1F931B0,1EE2C79DE8197EF7,BAD36941DB597506,2EC7219BB97BE32D,C69802949F32A2AC,000F430123282487,4F47507E8FE97CED,5D689D5DD29760DD,ACD04B45A3232BB3,FB5DCF7F6E952FE2,7BC4C96A80C333FF,ED2DD19F504C5BF0,AD8292A2A45A1028,002BF6E42222046E,5AF5717938C64CB1,10341DD56A58A565,34920E6C25BDD842,E8C18A02F0C3E738,7696F3EA1CB6B672,F073CDF1337D873B,461C8C0EBE1BE6E4,0040442E0D19ACE6,2ADCF7661FE09264,6B210A2CFF4C3073,D444734596E24594,1041D9FB29CE3406,792ACC26B54E223A,B0B7B7737521BF65,F7810FB372E87F77,0021F9AFFB31FCF8,B57D5FDB947F379A,A54074DED4A53A45,397344FDF1D6D461,F5CDB0EA615C7660,5604EE7B41CA47A4,F714BFE6B529DA47,A69CE2112A7098ED,0009700A1C837255,B97481F7F4D6212D,F3DD2BAB9E1F67A7,FFF7B72E4D2C685D,242D0FB55D3CF406,673EFFE06F4C4EF6,DDA1BB01B8DDC36A,0476873A35626C49,000415DD3C98AD60,D4806CC55BE5B1FF,D10DECA34F7910BB,5D24444EC920C625,302C7D72511FA428,448122B65162889A,E8A5A7EA770FD38C,092D65192754C5D4,001F3C97A2770C6E,9307E65E05E76D7A,819661B26441F20B,FC782E11BF98BBA2,D45132271D0F5408,A7D446379683E4D8,C7A570E78F001530,E963F14A6304A414,0026BD4AE2397FD2,1BC84A9550FC8426,2E15FCD73964E330,3DACEF0AD382E9C7,299E7433A2B0D73C,EE9D68CD110B6665,AFAA41A00230E576,1016229C00FEE900,00231EDB650CD0EA,D2E8AAE8E90B28D8,64B74E0623BCCF3B,8D88848FB5C684CE,5F1956BB42D6AB44,4F502957B798963E,F135D3108BFC81F0,0D56215F8F803DA6,003DA1CC82FE0B7E,62A982B8B5626BC4,9249A9098612F751,11E4C214524C1B17,C121D4240DE9656A,C7F0623868742AE5,8F13B7C6D29D3913,AD4D2B9CC419EB05,0003DE39B0A4771D,85D57B3A538FE0D3,793696F50B3315BC,80EC9FC20933F233,797F02A025CCF158,3CFB531A7FFFD708,67EB644526CC14B3,44AE5CCD6F265353,002FDDB51D758EFC,9B7794C9A332A68A,8DA2896BC1F3ADB5,043FCDEE1A1242D6,3A7D4ED83F93DA8D,D797AB237B43C338,8A4962E841018A3F,90F3F533FA3D1CE3,002EC99EC785053C,DD779E3179FB8CC3,2A4758BF84250C92,66445F4F3DEFD596,D3496CA6984BF628,1BBFBA0ED47D56D7,6433277A2EB70195,2247C8507F1EBAA8,003DA1087990FAEF,0C1411072ADFA67E,9BF8E4FFC541C867,5821C61C138DB1CC,C4DD799091A11791,22A72D7B1C6F78A3,248C8916F5CE761C,8B7D5A61660B3B0F,00218C18CA0554EE,DD8354A676872ACB,BB860E2F0E2E6A0C,CA8A1622ECD6D29A,BB06DB3D72B275CD,9B73F7CF3951AF6B,7250F43BDFBFD683,6A36B2E8EE329F23,00177D7D1E1E85BB,8697AE77DC89D770,B4E7711B30C508B1,AE0F18F8B5DE9941,110580E1E294676D,0D16168044F3CE0E,A3729C58B5D983BD,7D098FF85806B1E1,0002B0A72F5D22F4,9A0C91E69A382A1F,BA6180454D43DBA2,15F47FCCC5679A90,A2E046E952542673,C0478ED15A376FAC,E4E76C12BD6E619A,CCFD5DD4D8CD2DA5,001BE497BB0F23D1,5519978390006034,A8253A86FFF2E350,9C38544011E80208,14F6140453F6D4C2,F837BDFD731D121D,9DB2E50A6C6DE2DE,5706E82976887FAB,000F7C3C05EE2AD5,B554C71BA04E694A,A05356E35A1252B1,DEF9B8D075EEB1A2,0C7104ABD70D04E7,32F6E3E10E12F378,3BFC4C597C707442,D8FB190684B1B9EC,0004AF8AD05B6289,C321547C087BE948,69EA4F3686BA5937,643599755E1D7262,EDD6F2253AD8EF5B,4D1E240AEA281A71,433FD0ABDA481DD3,778D992BF591AF8A,000E9C49E837FA9C,96AF44ED4F2FB982,B833A179F965BEEB,A9C6CC5F7DBA8C14,F1460F3DB21C7431,E3B8C3EA8DE930B8,03B9CFF486338578,D1CFB9248B0B571E,002469C6871ADFDC,C98870D2B5722980,D262EA07339A08B3,DBDA618A429135E3,CD033CDA26B0F21F,B77284491026AFE4,66D3DE57168B1069,AC890DB94B844194,001C8191CCEF8464,91E75263FC521ED9,3F872CDAA8B802C0,4AE174DB1006B94E,AC5E5A89C6A36DD5,08D5AE1AB8F70E2C,775652ED53070E9E,86A304CE97DDC0D6,003EAA3C19DAE7E5,1F79CF2FE90F15B2,016C99901E3A06BE,09AF066A9F143710,0C876F3F9B5099BD,A9AA7B03E3C49D13,5ABFA44F184F03C9,6C3EC451289E4B5A,003FE78ECD665F5E,F844008C1FC149D4,D3F59528AC9307BB,B593EFF89CE5872E,950C08D83A269005,CC6F51CB7706DA84,90F0C2BD1C67B61E,21FEABF835FDAB57,003CA1501B7598C1,45228D918D934C20,1F25FA7DD34BC67B,05850639F2FF177D,0919BE5DCB3D886D,E5F9415902194FA4,CEDA55A4F05BE80B,0459B626773F56F6,0001B1FFDB2D762F,F8BE181BA7F1F0EA,CCB667D74D5B0DFF,7696E760790E13A6,E691A4F67074F8B0,DBEDA10ECF0951BB,0A431AD6E2D12723,304E75D7BBBAA5F9,0033EBF5FAFF6136,F594BFA427D53756,608E67F94ACDB5CD,31A2E90D51BA27E6,440576A1A7E102F6,B5E781AAEA600099,1A436CDCA9AB0D47,9D86E0E666549115,00391B2B2554FB48,B6AE74041D30B11C,2C71078E35474926,5B7D3729E5E35697,1B160EB1303CB3F2,54A830543E2DA32A,6E661590FB7A273A,BF2566F1AAEA1F23,002D06A1D7E5F444,BFFAC8B7A5F9B112,DEB813D9D8A871B0,9A3C63F95C2BD259,8D73778D0739BBE8,0CF64DE70F171A64,6090539EF1F118B7,6325F5C8D96FA623,00041EE177A1EDDB,7A7F375F128E730F,5CF2C962BA6ABF36,D591B844DC8AA1CA,F1B5A4410E6ECC6E,EE61EB741058B95F,CCA246AB9D2A002F,3DA926970D0B20AE,001BA433BC59F63C,BA73DFBF562511A4,A035CA48D114381A,8091DAC83183453C,3B2B74B249CABA79,06AD01DE89C601CB,036CA60C35870EF8,31798552AF876A09,00214A8782D7BD24,8ADDA757A6F8A491,D6381ADD2C37F8C0,A37F951137FE034E,1D565CFDFD93505F,A7B1F146696E7B19,60D024AF7C458268,6E27901E8C80AC84,0027A89A6F1806C4,4AEFBB31FAF35AD0,5C7AFA2E5AE3F37C,F715C0498069B7F9,4506B12339A730E9,C9EDA7E704B17885,0D04B1B8663281FB,7E18B3D73E335083,002C359A53188828,56C312EED7C3DD23,69A86736B832F1E2,FD105586C4142BE1,EF7B89FB778C39D0,6D80A39907424B64,267692EAC2EB1778,55E52E5E963357B6,000D38EE15DE0283,EB26198CD6C04A91,7F0893F175B71D5D,34B181CF921320CE,92C64F5D890BFD3D,E14DE33B7F111C14,42B83E4B686F6C31,D3E25F9CE3BF6621,000F1D1693675DB5,8A50792B340185C8,95A6FCE94735B417,0046E92111528FB5,C73A1CAAE8395694,BFE7EEF77E8235E4,2F10879722A03A12,8926B84DBABEADFB,003463FD9D8151B3,79FFD62E6B3B0DD5,5F9E6F4E87E2AFAD,9209C4B2DE0C1430,2EEDE0028BA9CCDB,E41D6AF70A2FEC07,4EA4ECFF090382D2,1352045347D9C3AE,0021396CC90FD873,C048735E87488EAE,C0C96D143545C73F,E549B9BD4CF416A2,EFCEDCC8CFBC8418,33413D35FBFF1087,659390FBD8EC94D7,B6F4B4D2B14DCE88,0000E5C335479A13,E245A66DE1FB24B1,81B7E0644DD401B7,F77DCB5D9FA817C1,24E2F35FBD605940,E0B434F5249251D6,7B8057E6D5ABD23A,65C9A096EEA7915A,00340E8A50D38950,8652D6CB6DBCC942,1FE2F4B603B43E3E,88B308262F1D595C,4E7E11DE6DAFAA1D,FF147D032874FF3D,A8D079F95A45836E,9F329BDA06E06F91,0032C588F0408C60,6FBDFB444E9A0476,C66B41117A6FC7E7,89BA8AF7FE89B5FD,1EE51D3AA9A96D31,550D86AB2A5BECB5,4D3F0FF4246756F6,3EA847267EDB77B0,003CF49AE39A417B,510C422C035EFBFA,00551CBB5B1AB3E2,5A44102BC3FECD7B,339975D8A2032B50,8A81C3D335B24A1E,095A7DCAF84B5978,236EE927E8B31A94,00388A938E6EA9AB,87E8231C28733136,15BCB19D6C7360E8,F144414BBD3EB4CA,DDC75AEB05A8CFD7,981BD5D6F0F9BCDF,A9101482B6963017,B0C6EA91B917405D,003E0C35F61AD04A,4685E92E6F2E361C,A90FF5B347924C55,5F91B4E562762877,F98A95FC5D9CA289,5277D34BC866852F,8E3ED15BA5412BD8,A81F9E63C23E2F3C,00271728E32B18BE,E94B6521C696769B,A2872FC74892C4D5,1D56F978A858E07C,54EECE72A694CF95,264FA5AA7FD335A5,C948D5908AAF0DC4,688822ABDFDECCE0,000DBE34A5FBAA1D,3913D47DA2E1EA4F,4D026C675B5522A1,AE83CF09D1694A58,D978C843D5E7F262,D802F99DAE4B2C26,025FEA3584F26AA5,750F84FD1B8267A0,00062C45732B261C,028E3DDDA44DC010,3589CC501E75E89C,60942C0B8FA8A9EF,AC14C180FD2062C6,2F424D9002C6ECFA,A91DFCABA16798FD,E12E230951AA7A7A,0022C0FE952EBEEF,60AA9226EB779EA2,705473D270EC8066,E709E0661510C76F,382A24936C2A42A2,AC0EC76C10BF2E93,59D1EA8454D42215,C040DCE2B7BB70B2,002F52C774B930E5,574222D00AE4FCAE,A9170523F34CCEA0,79D4D4A018BF5DF2,0FBC69154BE0B5AC,439FE43FE029FDF2,ECE1F7C06A6CC539,7024188B5EA2C2D3,0008AFC3CE16BDD5,0E1FF2D05D38F031,36E8F0DBBA90D30E,069FFEB66E415890,653AF19F3B3EE822,4C8F81217BC689FB,92EA22B7A595C09C,EB4A517CDBF02240,002184ABE1FDD421,EE143B86B916167F,E921A2A725BB1E85,A22EC39C1650025A,A1E35024CDC20923,6AF743C2C40C7B8D,516652FEFD5ABE57,8BAC70DEB16C82A4,000DDC42960F8CFD,85BE403C5F94D572,D2BFA730715815F3,6F6B902EF8F6D947,2982E9666649E107,F2F7381169EEAB54,5247CBFB00F4F061,5D0ABD317EE28DE6,001353E8AE50223E,01A6901FF2102A68,F8B5E3F5E5C86D34,61482D659FE64E08,C9198D474CDB497A,0264A36C0DBD530A,6D79EAD747DF6ACE,B5B0C408C8919542,001D757A94B8A2A1,A6B5DA194FB212F0,FD47F4C990A4A1B5,6F37E556429748FA,A791B48C22BA93AE,EA70DD5EFA8E991E,EC9CB7BE1EF575EF,C8402E37E627F27B,0005EC8E947970B1,0A227406A4EA935A,A5734CDF2997BD9E,6867542E72C16046,5E38888CF91E8D9F,F13F4940F94DA1A4,DB952A7705FEB666,042F85F8A271D1E9,002CB06DDB3026B6,33DD4D6D895D3207,3E5C5711FFCAE6F2,37AB5ADB7398F4A8,1B18BB7A6A734F22,61F715F9AA8ACCAF,CC32FCDF317AD82B,2949E3CEC22B7DA1,0021C09874B53376,D18FBF578CECDE5F,6DF7CD9B63861078,E65C94AE30770778,C4CE23C87DEA5182,ED6256CFDD940D40,DEA1138D9A059570,A7D2D1A3D3D6C6A7,001B2433AA70D5AA,3FDDA70AD8F5359A,E60B99B9A48E89E4,C43C730DC1B0FFBD,746ACE18F2889B91,6C59F4D06AEBEEE4,B3B1AE7C21BD98A0,3B8F6C508235AA90,00189ED4E343C1E7,B1781614EE3E036D,25DECAD6B0B6A309,F88DF2C0F6E6F282,A15AE13AE2FB0920,B4BDA6EE6914BEFA,5C35C99E19F6FCE0,4B74927B8C7401FC,00059E6E88CEB785,77ACB9D647E37620,1E29369E52580F7D,3F922A1F8C4D6D48,F54A7280D56B9B64,8EA7D7816ED979A8,EB4D5F03E23A9198,BBD8DA21547B217C,001A2BF6DCB8821A,CAC31CAEB119CA16,FA9671AB0CA80FD2,2181AE5577756EA9,2AB58925ED382D5D,190B06F23D409F79,95C31898FF2E750E,D31FFAEBA3E559D8,001F5BC6AF3CA4DF,45A0CCE5FFFB3C4D,05DCE1BFC5FB682F,5E628E2193357366,F795BDFC7AF10A2C,602F61FBF856EC47,B1F644F558EEA60A,AF2880DBA8AB3604,002E2B6C181BC868,7B7C2CD0153A71CD,0BCD12F416EBC8B4,95AD8657FBC2C7F3,73009B95610EDBDE,2723F5E87D7502AE,B29C8E948FEB4846,4B29DE591DA28B7A,001586B3873ADEFC,F0001353DB054CD3,F8ABA1F87C150911,CE0E37CF49666022,55E4969E159BFD41,C57567B2226C3594,3CA899CC11B56E6D,4B453F0C512B8CB9,0033C661477AA72F,AF9EA8F0B5AD24E5,7358EF1185FC19C9,9D40341A8DC3919B,FB8E320BA6A618AC,21BEBF694B3F261C,8357E7503DB50D47,182AE6B9B43D9CBB,003C29EA548D724C,C81C20BF1B83F194,8E5C5A45BC7FB454,1DAE0FC69C81DDE7,712288C58CAE3898,E12C65C2A6939920,54A45994C36DF6ED,A13311DD01B53769,00277343981AA34E,376D44B19C85127E,5D3D418C2E92E38D,029C1AB7AF8A30CC,4DCBDF75DC70D5EC,878DCF789E9E7952,D42A20CABF20DB69,F40DB46A8E51C4FF,00155763A3316E8F,A56FC3307D3025A8,516E6132D30389A6,61F4FDE11814BDEF,6E604BD59109EF08,A6B44373FDA338FE,693ED85DEDF25578,8CF1C3B81B6FB917,0001E529EA1A6140,35055CA344319FEF,6FCF08E38113995A,8C414418649A12AB,29DFABD50C23B10C,750A0F86C5F0642D,D6915968922DD8F1,52B52DF98482AC8D,002AD2FB5941C947,91BAB3DD702698F1,2DAF649EE4BA43C0,922612FFE71CB896,FD88CD4144998C8A,0E934263D7176F18,F66B14487751211D,1E79F57EE1FA390E,002EF9EFFFDEC55A,2B66C8D54490E8FF,7AA7F4362FAB58BD,98CEDE4C3A551363,87B84DE883540BA2,5297A19081C216BB,1922DD927FA76DC5,F1802E3131C386ED,002272C4A2BD0E8C,5FBFF266C2CCD0BA,101D54F7A2946AA0,5357487D5C4A8C73,BE4F6B891644A383,2FF0A28B63529CD5,EA8CE33C417972D5,35CE6068F51EA475,00031B840DDD5C27,5692E09A51BD21A6,466D1022AB020011,F88F09ED79D9AA74,F53C38AF6ACD9FE2,8B57C89384208927,743C3D3F1151537A,3B0161E418CEC1ED,001F5ABFB3D50786,C44F2C7AC9C214F7,D37CD80AF4FE21E8,3A30FE09CAB133F4,BF19320291E7AD65,A054D1483A691561,239DED736D097A5F,010F0BCA988CA146,00342D9F0C229D07,5011C12CC6AA2A30,24F557F59BA3DC9A,9FE0079855882BEE,17CE19C432E8684E,9D3EB8CF68677B7D,40A17676EC876B16,26BBAAE2F056130C,000CF39F808BCB13,770CACBFD2926AEC,DD2E4F28EE75AB94,1E64EEC69542F814,D57F66D2DA1A2CFE,0B563FAE87E7A6B5,FD792AD324D103B6,CCBC22525D026620,00017C7B610E3822,4D05965B10AA2263,88D70875860FB263,44FAA5FA98B268ED,13A11E22CCAEDBC0,CA7CE2171E297075,AE6346828B60B0CF,48B5FA6E505B932F,00397794DF551572,0AA70B463394FB0C,DCB8C6C13370B156,2D2066DEC3DFAB91,0D67086F7D09C1A0,8A0E127003620F37,BEB59234F7658E58,1F8D01E69ECBE4FD,00255FC9F655E3AD,32946A70847A5CDD,3A64B4BD69F50464,3E497E4A1A0A2942,5B66B931FC17886B,983B47D09E146CF0,E12183B424D0F9FF,23A46997E518E819,003B2FCB5BE3626B,F14535C706D49050,07349555FF2A1BB4,F00280BAF94367F7,9801B2549F396785,832917ADF4B49132,E3476D03094395B7,F0F8B0B059496D69,00208FE6C421391F,62F4B5600A224496,638ADD23B847D083,D0B781C3782630E3,7F8CBE6A102257EB,8FCD93F755E35C31,97C893C797CC60D3,BE7E37F411BF5FC9,001BBD54EC00360F,FA986EEF81D32500,2DE5E3FF598FE5B3,52A2EE8CD41A4208,8F103B9B17325140,A72A5CC3ACD07F32,038DE4457E026BBA,0A4FA6DD094956E6,000A25FEA9BFDA38,809BEED387C5A203,5B87211ED776BF3F,F0176282A26DF489,65680710AE673D51,3DF4306B0D09961A,7A17EBEB553D91BB,35E561F08473C2EE,001C408D22486602,D3767C5156E90F91,CF677E64DF221BA6,655C73EB14B71D4A,887B60C6AD0AE803,92E024A78B290040,905C410C60C2853E,5B8582C96D864909,003D4E3DE8D9E797,4EF456D28DCECBC7,217414A71392B692,2ED71009D4D5BB52,BD704DA2FEDBC977,1180C45EE1A7867A,9794F843DA942A7B,440B6A740D293856,0008D91ED2F4EFFD,63520D4CE937ACFC,2CBB579542DA5E7F,86EC9802720A6A5C,74F8A727F4314213,B201C65AC5B8F9D1,5A08115B0A03B3E8,70A952FC9A07F37B,0015EE5CBFE61DD7,F161805BDA5663EC,87F64E09C1181D63,2817849E1A635475,54E5F2FB82B8889E,5EC72B5342F44352,763A04C090A0CCAC,11F26A479D63839D,0030CB354C45EA49,950D4D15150C452D,91DEF6C8CE529ED8,0E1687544AC1B964,7D201891032EF27F,49FDEC871BE4A05C,22072745573B59EA,4CE191A7C780A466,002451AC90D08AEC,6BA2ADF990A7260F,E2A1A2EF4003DA49,57D2C64D7107EC44,3A249EFE8FFA448A,EBEC4239EC993C0F,EF7377871F579D2E,EAC1FFC68838C2B0,003330C85FF9E855,E98D65D0D8619E58,E5D27ABE703E2518,7D9C447194F7A7B8,F2A606CC35BBA9E2,B6D9866F02D23C3D,07DE98733B966375,1F07FA5D3BD223C5,002551A10912AADE,781ED872F8C5989F,BBF752751EA329E5,E807562584B358FA,F6B1BDCDCD531CF8,7B670D7500907390,1378EEFCE1B6F8EF,8B72D9071CAFAA0B,000A44F4E877AF9B,73D83A9F7155EB19,80AC997B4C77F360,DAC2A7EE11DCAD60,A7673E41035F420E,E2127D12A269AF72,E8E99E42D2CEC5A1,0BE809EF0654E650,000CD5BE915B06E2,E3E478ED25EBC28F,DB104D6F061AD1FB,CE458BC2F211B8CC,4459DBD178367DC5,5A06B29D2EF33529,8638D485010625CB,7D17AB068CBBB19E,000727F9C16E1FCA,4A1C7639F98C0D9A,EFC779F06BD5D8D5,1494CF223016F28F,E68833184C9D7B7D,36035C684F53BF2C,7A209CF88AEF22ED,EA73A4A9253B1688,000955B66BF6A738,E8E4066B2A51861E,B8864429D4F0BC87,B717956CB55F7D9E,159A01FE289F9F7A,D052887EBD208288,442D7C655AFBB885,881CAF62FB209C41,000D96AFA127E4D4,12C17ECF3B13C408,5BF743C40BD37D27,E90495027D4E8570,24938C2BBD8989A3,1368C4E60C486CB6,2F38D3278D93BF79,BB373427533541A9,000392585EA0140F,796868799871DA2E,B26EBC5A06CDD2A4,4A71D0AFA077085C,F37439C86C32D26C,E0343E7DACF4D4F2,3583FB0CEC9A71E8,96F4FFC1A7DA244E,000554FF44319F64,4497A8049AC5EC5F,8F6A705B5A3E38F3,D9199AB2043CD8E2,2494BB97A8BC10E2,CC060F3112E83AD1,04E6E0C684336E22,540046623A8D9581,00101B23FF96F5B6,354518BEAA81CFE5,0B663A508DF92CE6,C8EFFE8FFFDDFF99,B0EEEDDF417E40EB,F6A63FE0F03899FA,B1464EFD6A32A290,63561574A8A54AA9,000B345A20052B53,DC767BF1C3383A31,8D94AF0AB43DE40C,868343A07460BAB2,741B871929F19677,A3B550A386DBF16B,A9BD91070AFB9D24,0373DF56245FD516,002034D1DCD66A2C,9227BC08543DC0DD,1977AC8D995C7B7A,87CF60AEE878DC41,A0E1C26E176ABE9C,49FB1406324864D9,1E101770605EB6F3,013DEE88887AD518,000AC77457446E8F,142DCEEF65D69B1C,B98AFB52A0431401,A941CA8457EE74BF,14F289E8AAD730FB,0D80617CA16DEDFC,03B244F2004C08FD,09FAA3CFB482410F,0004E2228C3ED4E8,62F9696877CF96A5,7AB63A6F3E0DE27F,964E8422C7260DAD,6318B4D9E297AF6D,4BFA02AB265DE063,B86BFA3DD5296FC0,40B7F712004F94F1,0032776F294FEC75,D60001B835D88365,B60D85472D9B0685,BF048A370A79B030,5B2319E0345DC02A,AC8B8ECF79E1F101,0578C89CB5517CD6,887E2197D654A2C1,00023F56A4F04187,9185DCF263A633B0,593A7292A2EB746B,36D1335B33639360,E0C9A7D4B6E18881,93595D328772436F,27C30AA880D79317,7E277C7D0B15BE86,003FD3C6D4811B1B,08351C3A76156206,D088D7DF6EA51D22,0286F63694FD0408,0A6887E8FE86335F,F554D19F3109CEDE,4B064AA1FD241C93,1953F23F1ADA1479,002532DFD5F2893D,68E98C8F45C735F0,FD6D79519D3333D1,8286EC5F328BA109,E8B53E4AE0FE676E,057035F1DC6BAE8D,78E8966B2F1188AF,4679F13F504DCBD6,0018AEA6EB6ED3C3,74FF91EC9658EBF7,F976026E4A20A04D,3D1F6B20BBEF58BD,6389B476714F925D,124A6FD50D4CF213,4C43CF8E458BCFCD,48131A6A9AE716CF,00218819793727A7,0E2B9E0272E8F710,464DBDC4B16C01F0,522AFD84F75D8533,C259579E1E784484,B98522AFF86D9505,82646EBFF797FD2D,D755F51FD01722F4,000700525A50FCCC,543623D83E84CDAB,EFB5D6F067DBEE17,394ECCB3030BD90D,740315680F3577AF,87848384F6D7861E,17FBB66548CACD06,9036537F89F7F911,0022EA1C0167DF5B,1A65FE7A38D2EA7A,8A854E9F718C9C25,91717CB4E85DBD55,22528EFA81D34CEC,6187E6E8539299D5,E14BA9BC375F7E85,0EE4EB70A55E88EB,0032ABFDFBA2F7A6,415C7AB790D1F0F7,7D5EA5D71891C103,5975B450F16A0B59,6EA4BBB9FE3918E2,2FD58000937A7385,F4E0761088BACDB7,56E2E5DC81201EA9,0023EBB691F0A1F4,B9C256AA695CA46E,3DDF9650AA14FBE8,4248162C97703EC7,DAC9AF2711E8FFCE,C728994F78EAA365,FDEC9B1DFEF903C8,1FA2F45F12D35C17,000E178D7FAD7805,45A370C9C2A0B149,81E4850BAF2AAC6A,F529ACFF22E3AC02,70622CFC74DB0D39,C8FBC68AA195120A,03F8C44483211AEA,938D4DF8994B7157,001B11F9EB8A945B,E5E2B9ED6D829B39,0A86144A141B5615,497B9C0C1CE1110F,D0ED9A47E9BEE6A4,D3DB268EE4C63AAB,B432C584AB122D93,112E8884B9BDFB47,000696F900DC6C2D,37FCE04C6D19BFFB,B86A2211C91A07BE,09F599F5E382776E,E31B30F45B033647,A64649555EFAC4B5,A87D7DDC8E4920CC,BD33F38CA96347DE,0005F732092B3173,665572D2B3A30188,21DC64409E6B75A2,2941D2625FC48118,F1D227E9D05FDFC6,0AFCF0CE36FA9AB8,79B81386A67BF26B,DCFA3BB5CB568853,0012E7C52CBAC325,CD85FCE211412E2B,96D02E15301F4022,B12F3484B9D30F95,05A7A7839EAD303C,06476406F02BCBA8,E146386A1BC3AF0E,256BFCF46FC45A50,0022282AF64BC073,81A2B035F796FCE6,2088F0CE012D4B27,B6825EFE4BAB0E99,D28899140BDDC2FD,748BAF160FFEFEF3,E38883488D0FA097,65C81FA7091C2B68,002FBD1889B58F6E,B14DA03B5245BAC0,58967A9DD2CE2678,1770D71598DB660C,47D2859A449975F2,01CECF8A6033EDAB,F53048E42E7B57EB,BC8003C16A961A29,00246952976F389D,2E3DA410544D4E72,6B9BDB4CF0362580,F3A87F0AB5D39A8C,4E02280ADF59DFC8,7FEDBD15F9356CBE,993A268343CDBBCD,56FD1B8D61E1752A,000D1C79D2B70B42,F330F84D269D846C,7BE19AAC189FFEF1,78706A5111D75BF6,20B67CD7BB3F7E3B,18AC5F0B120DE6AB,7899969EE07FF835,88AC235CDAA45245,00261B6ACBE7A6CA,19F0F661C1C7C04A,74BF7473D58B5DBB,3D2E8D58DC113FE7,E0EC832851EC3907,D92419924DA92D1D,7733A6AD9F7A1F57,0CD641EB1E648077,003AC60404166EC5,1C2EA564241A7182,8D04A34B04629494,9D41C698457843A9,A9A2462D2EF59F92,31483D1BE95F1DEC,E3D2584CDD27B4EE,788EC92F63D593E4,002D18C0D922CE21,9C9F3F7F8C5A08EE,CAD78B4E365903F3,DC57DF0665B8EAFA,7007FAFBB06CFD3C,2EC8C63AC9BDF5D0,B26F2D77905900F1,59E3A05C6BC9DB60,001DA62E88A1EC1D,D452AE3AE07BE91F,FDBC5FE8615CEBA7,C0ABC24BC34CEEB9,C37A10CCE08FCCB7,1EF767DA561F1863,CC8991B407329330,0BEB818F5E7D71AC,002F7056508F18DD,74EBB1072DEA12FE,1D7A8F42357A243E,C704E803260ED53D,793F1508E1725F14,B6D808BB290F42B5,5FFE4C3BFCABDE36,A53B7D8F21F7455F,0011F4DBC7A4B57C,9E14BE0ECDEEE02A,96DB752A3CC904CC,D77E6875BB12A25E,93EBC807D6CBAD1E,C52E126484718380,B1AD903CCE1C4888,D2F55476E81B13CA,0002ABD0B486889B,058ADB76F0C24241,413B527D1D23B60F,93CA6C5C1E621EDF,8428DBA53AAA490D,219D4D711566AB0C,0142DFAEF803F3B9,9F8252457A6617C0,00338E7CCFF1A764,936EE19F7968DF5A,6FB8A46F1A161F0D,9FB94F426997D7FD,1AA555BB0354408A,D622A8F52FC0F9E5,D06E7D971EBAF008,3D9183B870FEDBA7,002C6C36DC70A84F,DF8BD7C95EE5C8C4,C01BB011598F9469,7903534075F1C860,1563FBB45D4E1BE6,0EE9F3CE9C2117AE,8B190A37F9D4C6E6,B2138BE4900F35FB,002F2C607D790152,9AF326100BCE0E2C,EEF9F46E226D9D16,E71E3C209C9EE922,B39536CFD7E64DF4,F4CC5F8F27EFCE16,557A79EB14FF5F52,5F15384B77E1F89C,003395D8162C55EB,69B0A6180CEBAEE0,839DE73B3FF8BC23,20714F1C99484EFF,4AF7393F0264327F,577D829DC74B4FFF,EEE4BE8259485F48,6BC39527F918CEC2,004026F3B9D076A8,568EC71ED0192BB1,20F7FE27565CE342,594CB1DCBFE84736,A01566220767E8A1,EDE9B5BF57455C0F,3F539B316D5014AE,AB671C1B65D3C65D,00264136DD813D41,3FE10DB160544063,177D234AF820513F,6798EA88D75E31F6,8C5E24D612DBE6D4,C94EBC6223F90AC7,21860CE3CA0FB4CF,CD5E8669DD55FC31,000CBC34B475ABF9,8A7356FBD32452CC,3F712E5C1068F31D,BD121C608293FFE2,88C285B3B6167EF2,BD7B091DBC6B6D36,A5BC0799E90EB638,5E9272F55ED13C61,0011C30721677D4B,54767D8DF1937D91,C01CC4C15555EF55,70DF637C9513EAC5,BB50C332827DE04B,A1F473C5FACD0011,C0D4F2A92B6B11C4,E7780D48849B0E79,0015286A87C49509,537B2EA1EE0EBCEA,756A19FC02C3FAB2,90F2F9F12CADC9F7,0746AF394149BB02,2EBF3AD8104B99E3,65AE7F02B8EB36F5,78C6BF41A5708EDB,0007D6476C41BEFE,CFC3312F95CF0B2A,E37446C148B5A845,AFC984CB8EBCFFAA,4A9A702C0B2DAA82,86B9E1E2D73DA55B,63B5700D9CF6AD8B,B79FC42A254BBEA1,0016601A12B2EAA9,535325B61DD7B3C0,804AC7F824861753,C11D0C995C1C6F7C,14C63B4D869EA675,B0474AFA70F351A2,E5FC1059F84E7CEB,F3BE8F20ECDB4A57,0007F9D1115C28E1,7766F1C4653F73AC,ED398D8C30866567,4AF7C26D1485490F,CAD6B73A3FBAFF5E,8C720A94FC2DC676,3EB5B18E26BD1D2C,E7FE11E635EC568E,00130091BB1F99D7,768C66C31D0FD7CD,46870B92F7B0F669,B7523F9A65D832F1,FF748799540ABFAE,A7372BEB920A3389,822A08377060F23F,010C795C7FC498C4,003EF91562BB94C2,64778918348C0FF2,45605412FA49102B,C954F1B1A623FDE7,C38C616CDB5B76B0,DFB63764034D122F,A824AA66B52588BD,15A121A5F49726D5,003A7A61D3FFFF70,DCD6F792E86A15E1,F483BDB775B80173,85FF10BA034C608E,2BEB4C04AA6AE9BA,9F197FCEE6B2CE14,ED3CBEFBF9F4B805,7C98802572BBDAA5,001277087E59B896,A1872FE083FBCCC1,BE112C12E6ADBCDB,BE416F4B8F970A6F,1A1F658ECA40893F,20C99349CD77F302,9D299D84BD4A1273,4A470F1B1654B167,001F815BCACE15E0,1D69ED7416D84D99,62CE4CC58E9B0562,4CED04B8FA49FAAB,5B7E200E84389123,F6A3D368641EA0E9,09DD04560FD277F9,3A869FDFD2E90072,0029D02CF368D711,8116EE88B70DE671,9BC80C64F2DC6913,D609F3CB61919F8A,7C21A71DBC5C91A8,CD3CF7F432A9CA00,8A6F6F7A5869EDF4,1CC1468498E763E8,00098F0A2870E304,C4CB21B825A64584,6A1ED7DC877A046D,0176D545E24F773B,0EB12739759ECA35,624B4AD700884E95,C415C83ED46F6651,0650CB06CF7456CE,001163C057959926,EF216B57CAF7E882,08D9A8F13AB4809F,39A26D1C7A9DFAF8,8C00389C8E8DBABF,C905A7FB7093A7A3,987FE6C7ED691A85,4984E7C3F3AB7359,002C19D4813B27D4,5C705422E2679D80,0BFB7D5071FDF3F2,231032306BAD3C68,071556BEF9ECEFE1,890E93CC724BD8A0,7E8BB9C69AEF00C8,A4496FC0851146B0,00072C1910B72F9C,80159AB81089A86C,D065B4417B70C367,BCBCCD26F285762B,B73798A20B8C4DC3,1958A1B00F3CB09F,BD95A90E6CEC41F6,21D60466E3519FF4,002A2AFF24B7C225,527C64A901E25C9F,90FC7F75B933164B,FAF93F939900AFBE,FDA713B8F11864FF,D0B5BC32102FFB93,404B4429D77B1C94,A45DB8976FA549EA,0004FD34519FC03B,DA292CEC6AF18D87,27C944BC44FAEF6F,0054CDFD26DFA962,569CC44B1ED1D17A,F35E93474189F3DF,36D5EFBFDE669A09,F309207CA97ECD4B,001C284BF8407503,31FBA7F940958385,8F0EC9DF7A2429A5,EB37638EB95BD439,EFFD0B9B94FD2580,2588D643F86D56A3,F019F153490517F8,5FB855EBC3F70FC2,0006DF24D9BB796B,091ACB9C671ABF24,88FE9E9CEAD2612B,D91A4DF94E36CAF1,7820032AC6336ECA,F05F416276788CAC,03CB7F6D027B1349,9463391EA376C6A1,0025D36EA750EFD3,F77FA6E3E4C3C0C7,B8F6F471AB0001A1,6423530FDD8AB3B4,65B6139B84CA41D9,24EDC50F9F01C307,8D7337AEA598CDDF,2A8D3EA45A505BF8,004024DB63F837D4,266974F6E9E10CC4,793E8D793DB06B9B,38109B2FCD0CA211,AE1EFE8C45CF8D96,310FDDF5ECA60D74,6BE34C381BC34415,074F7BE78CEE06E4,002C3693EC51A971,E938C313912244F4,AEFF76B57D5C1C40,7CCB88AD6F09D186,B6E940576B138AF4,C8292141B5A746A2,C1C002BEB761F0B9,0DB41F5237BE7E1C,0012507B5804EDF0,8FF0AFA7625BFD42,41E5D43B97C6BAC7,1DD46939FAF26F75,800AFEFD2C0A1E38,05CD1CA2F0BCD2FB,06A4E1D142C5FC6F,F367774187773910,002B22BEF673DD18,59B23F2E2729E65E,0C7AF9AA164480BD,369019948B93DD3C,6F15EE3B98A10A97,4B3139BFAF0EB559,38A5F1CEA5EB2199,E5986AF2981973CF,00060FB367A2FD55,925912B8EFC9D31B,F544DC7F4B1BA484,9153CE3B3A662523,905CE33D47E36BF7,8266550B27ABD598,155A0117573FBCA8,71F90CBEB5B5C17E,0034704EAD34FEE2,1C650BAC8779AE7C,452279C14FA7EFA7,49839063800598D5,3BEC54549DFBB701,45FC9754D61ECFE0,EF25AD27A71B897B,932CFF4753E64F44,001121DBBB31D6FF,0528C450F12067A8,11255D5F34617CE5,6DDCD4269C217C39,FB32450CAFCB9B3A,A96AECFE63703A73,B8127072AD93265F,3F1DF7A403764A9C,0014C28C98D189E7,AB6C874965C8D03B,6F8BFC88F3B08D59,F49740255CBB5EBF,C5D132B179EF9ADB,791B8FFD71EA90EF,FFEEC6415A9A5A83,9DF747DDFE6EC708,001441E27A55A113,699D781C78184FB0,24F34CA8AC305731,045ED5F9EB6E418C,61C4160E4CFE72AB,F7E6DA11AD5CB40D,822D0F4F5FFFE677,5A3E2F8D9CB3E8B0,0027F425929D2AD5,CFEDC8838547147D,CF2493A07EA82E73,34138A2A2FB814C2,1259F6EE7D12E07B,8BCE35971EEC22CF,BF5DDE22CDF4924C,30AAD42AEB1EC4D7,003446A1F300F8A8,C8A9081D6CB85904,3C99A2CB48B3730E,A6A0AA5D9A012171,D03DC1E36A2DB690,45F1638730DA3A94,5D34684A43369E5C,D67D94765A942F22,00150AB19EB64470,88FDDD6F5559E3B1,2C552390BDFE75ED,DDF3DE7C3A68AAB9,7351146F5C6AA2E9,D9568BCB17DB055E,18286777ED7BE08B,16C643134B8D272A,00266EFDE80451E7,D30C16EADAEE5E40,0550993494F9340F,D766ABED456048E6,FEA8D7D683F502D3,4E0B4A9FBFFBEAC7,78164A600392C5F0,06B5B2680450F869,0006932CB2E13805,06F80A4BA1C513E1,CCC66CD69939D8C9,F9940022ED4A23EE,E59BAD83EE4FF727,D6227806E364F72D,E2BC601B30BC0D3D,F8674F4111FF04EC,00115D1468D04E44,81FA903F3CBBB751,7AA3F0175624EC50,75FEFD9034582776,2DB3C5299B6BE260,237240574CC39DBD,1B84D3612317B906,E5B1AB4DF50DFCF8,0009CAB11E74F034,0FE83F7A7538A8C1,6C9BCA8037CFE80A,A49C74E7020F200D,6F15EEEA60AB729F,9797131264D2E069,3074948FC0C9CA05,FCB3F240412AACCC,002BFEA10436B16B,A826EC5BC676B1D3,4BA28952AD7516E5,6A5427F6A38E00CF,FC0FEAB0BCCE3E3B,FB5D4E689F12F1A5,8711F7B215DDB4AF,A9F013AE3938B5C7,000B31F2A08AC894,D871EA5FD770088E,778C1679A389BF88,FEF9D0E5FAA2AB89,665C9D08AAAC45F1,5F1B8588177BC298,73D8433323DAC097,CD74F46134A368F6,001D8CCA7151356B,652C60AC4BCEF4F3,0D47E79C003B94C7,CADB985757C9094D,A1457305023B3858,87D3B69105A7681C,07A04600AE2F56D5,0628B4F896BE4461,002DC8EC5EA5C23D,63EC7D437E201105,53208DE521666D60,C997DA7A372C92C1,9DE927765936CB28,8BAEC97A756F5A3A,2BA19851A64FEBA6,8CDDBF9F75FDB758,0025D8EEBB076786,92852E522E3C320E,F15FDBC466449454,D686D23E7A4207E6,850A7DC61CB30487,B480647BAC4D8E12,C170A26714E3CF3F,CFEB7FC9AA8F540E,002DEE53802BFE2E,451905DAABC2B5A1,9CEE9EFFEDFCF083,8EDB3514AFF4FD14,BCE5AB1E18826605,968136DB3766F18C,1EFC8D0D98D166C8,664ABAC518E315FB,001FC4B142C8F3BE,489ED6A4B557D7D2,08A6DB2B651950C0,524A68843A6054EA,3E7D0F0BB7B6B384,C9A1B0876E24BAEB,FEA719BAF68E23BB,9379E13F4E9C7FDB,002227D90D17B517,609737113B95F8E6,B1C72B4EEDF9F7FD,A4249B01F2EF4068,614D55F4372CEE3C,82C2387851FCEFA1,AC4E85C72B33EED0,8ADD5DB82BE61C7F,002C8BF1DA40C34F,5A178B20CE8FD166,1B7DAD03099BAA00,FA7D667696257023,A3E5FDEAB7A5B5D0,609BDF53FA1D51BA,3F562AF8EA732C28,73B1EEEA80769AAF,0030D5A49A5EBED4,F657CAE9EA86328A,6F39AB8D3C5AC3F9,442691FB392F976B,8925FF4ABCCA90C7,5B746BCBB462528A,4E8B0E14BAEB153A,5FD1CAC1F49A9B56,003414FE1DA5E7FE,AA482D0247ED2CEA,C3C6D2EE1B222A3C,5E330018D254B198,2D726F2EB3C867C0,C23AF793CF452C8F,48B17AD2F6F545F3,FE6468A2AA01E209,0002EBDCBCA8DF1E,988024CF18924B54,F5D4E071962047C2,5E82745D8E9CF41A,FD71DBCF875F7657,1AA37C749A874795,13D56F3E28DBA931,A89607E9759A4962,003D76D8B53B21B1,27D8E311F5CB052D,6727C75FA36B3742,11E7B8DD06C058AD,81AC7059A987731F,3552DA16934B049E,B90DF865F4EE483F,C6909E8DCF143A00,003355393C1BA084,98DD72A6E4052324,8518D4D03B9361E8,49E6944D706DE03A,AC36129B49F8815F,BDC2E0C5A6D61398,C3BF52E9658F812E,C3D875D20D6E92AD,002B3D12FC1F43F1,ED54E51714BEC3F3,A82413FE1C5B442C,0FA56015EF64CFA7,8F4BA2AD580948B9,8B77FF6DE4DC2822,F6388F0656BFA509,FA88ACFEE6C98610,0002D15AEEB49C50,2C5317436AA3AE4F,C7E1E7ADB96D8AD1,A5B7341BE4DD48CF,872A031873808B9F,DFC3B9750E49AF2C,4722056DDC198DF4,9AEEAA6B524EF83D,0020F28437B5A5D8,F8EBFFF0E15753DF,E8DC60250A67A915,A218A949CCE764E2,255586AC44CE22AB,E6D488814B17D487,8391F7B7BF5BF6C3,46E4E8C7589D6BF1,003AEE6D70B30B7E,139EB66853044282,E5694548962A2DB4,EBB4D896D711D553,55D2DFCCC3818903,91F9BD94C6801A1C,A010D205BF92CD47,CDFDE47FA3EFA957,0034F6B4F3AFBF08,E2C322BEEFB4C4DA,E922F2DDEF87B6D2,1CFF76C98CBD30BB,1EB588582099A005,40CD46F6377DA9F8,CC276106247691F8,3C65585141BE4F67,003C4380F7F738C8,F74DCA8B91F49B22,15775C3D499BAA32,CB2DE0A3DB02AC38,BC556A0D8592E137,7D47E9F392DBFF40,BC73BDC8B5DFDDD1,C53CCC39E49FB239,00236D0B9E1C208C,90A46AF46945576D,5866E7A76D448EDF,AF2D4B6AE6DE7D76,53DF94F2B8A01184,317C2222ADAFC582,1C86C15BE04E049B,D552CC0D50A20958,002AD354253EACE0,507D8458AD4AA50D,775BA4EB9F27D402,3CA8E9A0CA60FBB2,C3AA02C16B81B780,BA6D9F49C9E1985E,B02A302E4B643000,35C4AAFF3FD53043,0002F6DF179B397E,CB8EA1855C2741C5,D51ECBE06E7E5E13,A3F0A8EE22FFD234,0023234ED7085494,144AE10A9408F953,A003E6214E8D5585,32B4B45FC60B6853,0020F21E51E9BE4F,3536AC9C465EE73E,4F899C7040AD07E7,8AC7CAD3B82ECA19,C8E7A945162F4B75,689E001485084FE6,67BB6EE669E57F34,7D6BAE9FAE1751F2,001AB2EB12EAA90A,2AE5D4F5B1C9B9F9,1C63A11F51220F5F,C2C4164B618ABB6F,E7F13309031D4FCE,B9636A0B8F7D55F2,175B706475A3CFB3,E1A21ECBC9892F61,003DF0E548039FDC,3A984FC7FF5ADC5F,661A421E9317FE48,65502CD7CC751059,7108EFFF5D553927,9A0F96C8CAD61A31,573DE382C4462E0F,73F42820492050A6,0012F37A983DB57B,DEE7CA309442DB0E,86BE1686DA2FE7C7,BBE1ABF884D916F2,3C0668619537FE2F,39D5A338FE41392B,1F19BF58DDFE4C71,132F30659F52B575,0015DA12717B0808,7B38132C51CAF123,4A7FB08616ABA90B,62F9C8F945A6F494,05C5763FBD09F26D,0D8EF94C853AD78C,14C827894C7D11F0,E51855E05AF273B1,000BA63588CA682A,6D44F8C8CA8B1FDE,1D4494FE3D827E87,E5C1CBDBD9A94076,CE27F702D32B4867,76A4ACB7B9FE4BB1,C81CDF8AB5997005,E4BE77E7990D5289,00391D296BF8B004,D509CE11BAE7C7F6,EBD5F8F540383221,BB31138CBE8A1D17,EB51E8700C514ED3,BF8F53A0F8CD70FE,44A1BD2A1CF36A1A,9CDFFAB27E7CC09B,0013BAA073103BE1,6A16EB484DDC2064,FD015449F09681DE,A40667F04E8ED2AE,2D98832FC9C026A1,24DB8EF3C657497B,581DDC35253C5430,C9731A967CF07C71,000EC2902F1BC511,812C1C7941E5EDB5,9F199105721F9A19,67521F9ADE132D3A,01022D52BD6DB1EA,690EDBFCAE13229B,82B9EDFBCD2B76CA,62FF7D0E5C9E206D,0005A16D45BD6B89,C7BC7B36C9F4ED19,756044E71777287D,7A1EAABE1D04D5F1,487B91962C97FA96,E760D9993C9EAE44,CF8372F3F692368F,516A8CB5F9F3B9F8,000C2BACE881E1AA,77D1B40E29F65729,0A7A1D760F8884D7,207DE24163B2A966,302555532E13188B,3BB65C0B8A7CECA4,CF2065554764AB06,854B215241A97CB9,003FE218FB615E64,A0B906658700E56B,1922B87DB25BBA2E,12C89A2D6C0C548B,4E1DF6EAE0C7EF20,C0EBD6CA26D7D648,380BBDABD7261CB9,51B816BEFF363BC6,00328F6BD7A715D4,3DAC5DFD5CA0FBD2,64EF75936E2BD8D0,379EE9D702B16249,BA15DC55682DDF91,68533A60B0904167,4687245F420BAAE0,ECCA64B75D732B42,0036FC8486F348C0,2315FE084482DFF1,5480CD17F6B93266,81633221858BDD7D,A5E982F68F509C1B,678E99975AAE4CCC,03D7B95EFAF11DDD,CC476F8F1E6F401B,000D554A52BFA1AC,432EBB975078FEA8,B6FB3930DBF3F056,52DA43D5B3970D3A,3BD7560E8E00005D,4303E2255B182E69,8079BBBF0D3142C9,857952793BA8AE3D,000484B6D28072A0,97E0E2A90F6921B9,DA6ADAB41779F566,159ABAB45EEB54D8,8DD4891B15D24CC8,403E11F89023AE95,839D1F288DB86E37,D8DD8E7339583214,000DD0313927834F,B356B4D9498E05AE,67E1474FF6526FE5,C17E416E7EF2649E,F57A71679C12F12C,A936EFDA102D8166,E9E18C8CEE9AABE7,C2737F7E18D38EE1,003124C7F1037C16,D1DBF0AE3335936F,26149F68927EE041,55251FE67DC9E038,09D7A5FAA2F33F52,487277B702C873B9,C1C408FF7E018206,1C9EDC2516EFA38D,003375E1247A99B7,3297A137B53B6916,A9C2B75C1C641B4B,98A8ABA2F71C9D77,E6B48175C765011C,7E9ECAB415D3DBD0,412217221ACA9BBB,555A797BFD452EBA,001C854B0CF52548,2BBD625D24C611D6,0ED0620932A2A0BC,7ECB7D96B39B9986,2ED8D0F28FBA3AF7,C1ECC600C2012DC7,3DB9909129D9DBB5,438D64AE687A04A2,0035901C51153F51,009BE912346C9109,41576881C630D149,6D056D1D168D0539,C1A331F6587A9BB5,ED51AD5A39B63DFC,2AC22E474266C012,1AC9F7488CFFE8CE,002DB2E6976192C0,26C426C84A257DDD,FAE15C4EAAC4AA54,60B76701299012AD,B321656F50F73B62,379545E8FAFBB1EE,C2F47936CC028B88,CA02A08A7F2B32C3,0020C5C7AC58FD2F,970F04B169397933,D717C689C2E9ADDB,02862D2E0D3B5704,DC5E7EE29042647B,79C5410967D5D068,AD405F50B6E63F99,F7194E9863A54C13,000A2B3ED899A273,D815ED259CC63930,49C37560CD9CFB06,6F5EB5A7BF85BF27,4707DCDAA2C60EA0,675DBE94CA8D8340,C0646B5EE6CE1424,0D5940E27FAE2EE9,0032151D6FAEE39A,E71AD35DA56B8648,18A1F9FE093AE254,32F5B17CB460ECCD,013E49ECC4A28E02,DB3BD1B6B40C439C,5F8A537D36CDE679,B22DB8F4D13CFFB8,003E6C69663CF72D,989B1E4AF1FC427E,ABF141DB43971C73,D44C430C9CFF3E8F,3CABC6B64EC923BE,9CC7C1D7D81FD25D,51AF0EDC88AAC210,F59B03AFD8FE62BD,002FD000D4E02CCC,ECE98738BF3C9CBB,105C2E52CB1932B0,4B3E90841C6F66CC,EBA6799DA616FBC6,13E0CDF11BCCE5E8,CE0FF9A41CC1494B,F6026D2DBF447A69,003E28D887826E7D,D3C4A30B07EAFED2,1E460E56D6668C91,7D3F168D7FC2B8EC,22BE892659F515C3,5D6C48F6A5FE7420,CFA265F9B6FC7A14,468B2814030F571E,0010F24CD0E14EF0,EA1C291FFEE50386,97FDACB79FA9D3A3,3156E529035C3DEA,E3E7558082337037,C8A403BD667573FB,97DB12AB278C1FD6,5D925E2528C34FE2,0036393BB5F50CBC,AE5C8B737C863BCA,E0C6BCADAAE2D5E3,E3ECC982C032D778,1C6C5DFAA617725D,128606A4E9BF14BE,E2178F7E17845432,12C70FDD3971B6CF,002302985FA727AF,4A6EB7A7C0E08A11,45E5D49F38978F4D,7B36FBB9AB828FB7,DBEF6D17D1D1E6FD,F14AA10B80434B12,5CDBF654BFAC5B04,95A476E4E38562E5,002435369C53ABD8,0A00650C47568C26,3C43ECD6B5DC8179,F78BB79D760B0BD1,5771A4C3EDC44016,8A0D9C8A93CBD55D,B9BF713CFC647890,A843FB9C42FB509F,0003518FD4630E4D,5CFEF941EEEDF29C,AE97474BF4425338,85D45DEB404E752B,3A653CF016CF30CF,13F47A8385D87E87,9921E48B74EEBC8C,16819DA66DC1824B,003084ED2A5A8920,7856B639949BD395,C2B1FFE099067074,2D52089CA22C4B57,CB1B7D176F312156,B68F1623D55C0915,E94FE111C646ED0C,06E6D2B5D9D8085C,001DE686A38A783E,278C221682E95182,0F120271DD13C10B,3E0E6F6EFFED7770,22C1E6526636B35F,70DFA3E0F3523ED2,CB7C2DF72C2147BA,48C6C4CFD2B1DBF2,003B7E9C93D000FE,874891D44016F01F,FBC62CA576B53086,B7274A845D20C1BD,D3ECAC0F8681F68E,EC593134C1AC3766,246E6C877E5B86BA,760EA13CDDE88DE3,0000F7CE284CBA85,5AFCC7B1AD3A4B97,29A531FA6E4BEAD3,2754D124C5B7EA83,4FE498306A4AC05E,30D9766F9103DFC2,A8D57D8463DE5EBA,C78EE734D49259DB,000A3A99E9BB1A74,D39AAE69091A5B7E,D9966330DA15A7F0,060BDD2197E5962E,E33E44DB925F3021,01053D03B8B57E85,91C29947F46B5BD8,E49A9DFC4343B78A,003599E8B2D55FE2,91FA1EA88A37F2AC,7B702AF299259959,E8CFC1EE8837AA96,6ED35303E3749299,E92F2DEAB017CFC2,1D47692D15EE9061,EA39D4DA35611926,003BE4A5485691BB,CF43097860D37D86,D4388E6F8341E87A,381506AFFBDB3A4B,33593E5A6F513877,22C143DC21E5342E,A85671022BC87957,CB4EE167C5AC7AB0,00132D81A29D149C,D6AEBA44270FE895,11B34EC32ACBB454,80D48ACC4C80A607,D5727E7728C57843,5451534AF9D91000,72D2A234BEF68A4F,E45BB0D4ADDC671C,001EBF5279BA5B2E,524BDC21D7ACBC2A,6377236958BF92C2,122B606865A6B3EC,2F32E0FD8D6E78E8,8B822717EF63A87A,B2180BAFEBDDB5F7,445706949319B114,00201C62CDB0EE95,14352AEB584ACD0E,8DFD3B02F7FC3525,5E83807A3A4E1CA1,FB884D9979C6E26A,EB3F579E9E681B3B,D084121F3A168095,B653F6E78BCDC934,000CD86EB89876D2,28BBDA3B81BD6947,433859058EAA534C,00D770AD2955A1A1,EC2A6B83AC1A8E78,4654D1A32230DB20,825BFD06C267CA06,17B87786CF298126,0003DE909B7230AD,56975C6659EECDD9,98C99F76D53EAF70,02130C453F58B2F9,7426BB02E4C0F8BC,B672AD535DE92569,669E0334166BDE99,A431A5280D725571,003937B7400FDAA4,FEEB2C4C41F5D15A,9838ADE6432D62C4,CEDD78228628FF96,46A597E95492829B,2842534465D15857,FED0DAB7124567E9,9E04D413AC631DC2,0007875613644B84,D8991FD938C92F1D,D39C5CD20DA49B4B,E019155D0FA51576,9DB0DE05546A8899,DA56FEC5DD00B97F,D8FBF6B0B2EC9AC0,8C55037D86E28BF2,000CD290BC8C5B6E,D5622C5BA127AF3C,72F1F19D502AEA48,ACA969630CD7A18E,415E48D2C54E17FE,8C2482A250F8B53D,DF59568F10E2CC51,28BFD6E04FDAA19F,001F1B691EA24DAF,E4A1704955C2B0F6,E2F0CAD04146F313,0443CAC2EB55A7EF,DA42FE24C8809116,9B149C06B2E8E351,99610916B4346289,D0348569EFAAA3D2,0001838886FD212F,2AFBF090AB0E892B,E69FC43A09F860F3,C569DD6C4C187864,384B00299DB37C40,DB652BD9BB88736E,DD1618F0C5B3ECF7,AF48F3A1144E8DC2,001694CB4624D7E6,4BA67AF586405497,87703FDDCEED7599,0CA02A0C61EA4C8B,7F9CEFAA31C762B4,96BC687B5799BE8C,B9D4E0590F121231,0E161D41AAC2FEFC,000C56F1E7C7BEA1,F93A00576B741AC4,C3CD338BD2D4F998,480B18BDECE27D41,52DB9EAF717C99CB,3112CDE8B98BCD9B,32B3E91861DA5089,ED52B5E602870DE5,0037BF0C095D97F2,0B48AF92423D189E,A6636725E2D2D112,CFCB3AD4203FB56D,93F3F28CA293AD1E,9C3DFD32B98F52EE,63EAB7D5D239A8F0,7C088FEC2AF2554B,00314128D2EEFF12,7A82E99A21777977,0D5C4CA9EF49CBF5,D4AC773F1EBA7FE5,E10B3B5176F567CD,1326B5D1C433A6C2,4B9F634D0213637C,33CEE9AE1808141A,0006E736C7977F99,17E6FE2EC4B32FE1,44C909FB643A84AF,8EAA287105350C98,584F4E04A2218996,BC4B59C83075D300,E84D03DFE4C7ABBD,D22939B9DC696238,0019BE6C199729D3,9DC3283CF41847FD,D0F623EFECDCA4CD,A4F2BCD58FA2D8EC,95EA298E9EC3C694,8AF5692A09E86E6D,3E671C65E8EE1979,B66471175FEDE947,0021604FBF4A4546,06394629BDE06F1E,1270AB4C279FA3E0,8A8F548195A95967,E45F0ABCA3DFE059,D79F5F5F9AED2250,84187179A8D2A830,196CFEEAF39141BC,000B7DD38F75EBA7,7FCBB6EF4D53184E,626DBEFFB5C06B67,528C431ADA807021,6BD8C8EBDA359470,3E3A3F05A3EDDF8A,1EE4A491ED9F3539,BEA8C47F6E8ECFF2,00025DA8832573F5,EEC08FB722D42E24,2119F06A95351EFE,4DA052B9C99150A0,B43A4666EC405E87,A469BBB85436F39C,F9377506355EAAAA,9719990B3A89808F,0006195AAE105794,73B9052920C5A1CC,ABC3EE679996EF3A,BEB3DFF132F4CFEF,8F78AD464813F353,51A059AFAF5575D8,5366FAF5D7E898D5,BDEE43A29335F3B6,003855FCB92038FA,CD7C4033511C98C4,92728225DD24E301,742210AC58C5004F,CD14D433A8365B67,F944EC9900FD04CA,518E3DF9B0EBA971,1F460D127B782B02,003F4289E65DF466,2522809D64553BD4,36DDD8410FB3BD7F,E5A9C43305CF5C15,D64603F01EC62E5D,273BD3E0E9A4C44E,3C62CD0D91F0DCEE,FC25EBA527D52A98,001462C2DDADC471,5DA82C09032CEE40,8EF5080476619FBA,F496F1FC19091302,F2917FD3898513CC,C0A46F6D2DB2635C,0EE285CD032F1BE6,AD4B4D8A84BF6184,001274ABF631EF6C,526CC8FCE1F33E66,53938CEE39F01A6B,9B060EBB3F2CAFE6,11C31B455E6DF31B,776E630BEC3C6462,C58F46C26D23F801,A7FC8EF071EA3800,003FC9C31383F234,C189EB84929AB0AC,0DB10FD8BD2D3B31,F45402A91DA10EDE,C13050E782AD38BB,F1902AFFD87643C1,C777C0804D19C3F2,6FE7AFEB89FC8FFE,003D8DA3245C35EF,2F2CA3E00B8792AC,3038D78808535582,2B9C6244265ED26F,FADEF2B90C302454,B775FF0A3F24284A,27C08FAD8AE18A61,7E1F91B90FE1EFDF,00074C375DD4D0CB,A6E8EB9E25406647,7B1948D4C343AB88,E68917C9414DD061,4A9037E692FACB25,53FC51F769BEA456,F43CCBE6FE792C8A,FBD2DFB0328EE198,000D277CF08D8FF7,DAEE9777512F6ECD,2BFF4D684A7C09ED,CE5F1A93A2E1B8A7,D9BA6DA20ED3E772,35F42DC07CD06B40,4217CDBA3B9E2FD3,3E7BA7247F79FCEC,000763E83944B4F4,347EF329E7DBFCFB,DA83E50BB867B22E,4F54C0D91D91A5E2,67578F0B015CA3C9,1BC05F25FA85F315,09A1240CA6C095C0,4A742CBC02D6819E,003ADE63668E5364,9BF53BBC66DE82E5,9745112065680070,8D928CFE77546F29,30A2EBCAA20D0A64,08050A48913D7F4E,A0909BEA0E31673C,C2F60E78636D8A91,00025A979E7B3617,9F87AE1A69D71DFD,E4B9515BA757204C,7C9EB68A2FB39BD6,0F367A61C1274607,E3B1285B40DC31BC,C16C53CBFEE6054E,81A20886ECA7B83B,000AC27969A82B18,D7A5C628667D9AED,756392D856D2AF01,6EF9C6255BC2F9C7,69DA9FD5FEA582B5,7B46226862E491C6,81E85C8E0859A1DB,38AF6DB525DD427A,003AAFFD72B0513E,CC63AF17FECB8E22,59F341ABF111F23C,ECBFD8895E749F85,2EF3022B462340E0,8F6A92531BE7D921,05249B014361A33B,1A8D7E695C03A940,0023E69273A0A0A0,31A810F6D7DE19CB,165487E4C2511C83,16735B1D0368C52A,E67010842579C09E,86CC9AAEC089B518,5D1F6A9404946CFC,4A291EF0AA47D3F3,001C5E7F47BC34D2,593F9EEB5576CE93,D5ACF9AD19E12363,2F6C302076778CD0,37A79D10B67C33F7,51164C193E755AE5,B928897DD5D3E571,10128484DA2CA2C7,0020D18778A87644,74E1187070E63B0A,6BA182775FA65917,50F6443C478A31E8,85CFCAE36E0A32E0,2D450189DBED912F,EC4310537457C09B,85BD7F477C3D58E3,002F544C7A468C58,E04E3EE89DF9CD10,2D5F391E3AE0C010,9B35CE7620268597,2668BF744EE7181F,6A92C614163F49BA,1D70378F07C849AA,6E1F04AC4B4576DC,000FAF8493D8921C,BE0F1EC4E87FF10C,98355C62BCB83C4C,4D8F1F24418A82E7,C07B869DF318A161,A112611B694B206D,8602267F7F995C55,CDFDC143EF02CE89,001A9859969CDEE0,8F5C220FBC1B61DC,85C3D69F6A1D198C,BA9790DFE36303E5,42F8F250671B0E9E,11089CDDE8D8AD4F,0A79F2FA83C561CB,5DB244B815A8D58E,0004072E8128B2EA,5310D0C9E6E727CF,3379E34C8255ADE9,CD6DB0803F4EA612,6A6F0239CB3283D8,F79918FEE6F01DCD,5D94F5CAB8E4960E,05F052F8923CFF7B,002A44B615CE7E8F,4CA668B9151F1FE8,BE8B7071F553AB51,26E51C369FF6ABE8,3AA93C0D1A9FDF3F,754AFC16468AD206,8D54131DC55CDFA9,4C537692AE773105,000EC07357F36227,EFF183F5702D684C,68DF3E6B51F2D586,15DE6D956F474F42,3A56EDF1FC46A13E,4AE84FF2D107B3C6,E6D2090E73FE1BB0,35A679808C2F1737,0038A92FE1DB968A,0B4DF80EB1CB1183,85DB43DBDE8FF6CC,399EC33DCFB22C0B,9DA53A64A8BE9663,03B2E79C583144CB,9561AAB56FAEC546,50151490B0E14412,000D9B6C7661436B,BC7366E0175128ED,54D507EEF35D5DE1,F7E61DE527E3F6C9,A1D0E997EF053BFE,D121A6D4C033D662,AE664F0A348F547F,42B4BF690A3FE7E1,000FDD21F5261996,0C891D6148267F1D,318D72A930658DBC,C88218AAF5B9C1A3,B73119E36399BADC,816BDF40D519B37F,1F0B6C112ABBE3E0,EA892026B67A726E,0014725248877B0D,F22B8104366C3B05,BC9A4EC1DB3718FA,A96B127EE280331C,DFE8D449D8915F13,D2A5B8F7CEF3EC03,F7E5FE3353DE92B4,96CDEEA90FAD7C1F,0020585616CD393F,E1C308D06B335253,49B77B610AE5EC72,34B4C128947949E6,53D75B2A3BE70FFE,F1B2E2C5F4307693,25D0EB51E9A0B7F6,605523A223760FBB,0020B58BE108A584,AC87C59568E42E89,B70296CFC4494FD4,FE8CF94A14248549,62E66F6164DC7BCB,C1D31C9440C49797,544BF90A08CE33A2,0345774241DDFECB,000BDB0D79A13885,5973911E4F0A73FB,1405D5F6AB9232D6,3BA323A33F6AE9C8,921AA708A677D68E,9A5AB588D1BA2150,41C0881F7AF4DCE8,D452A88D3B1967A8,003C4E8002CD7F0D,0B368288FB280B0F,30CA5CC6B5CFCDF8,30B8B68D14A97EF7,B15E628A8226A6B9,4A81FF01E7049173,54C02E9AEF83EFEE,DD5A0E31458D4C8D,0000BE1DFA0C7909,03462635A756BA92,9FF9C6D30B49E7CA,F7635185781688B4,D92479B05F627D58,939D0BD79B2B0978,B603E41006C3351E,73ECBC7C579ED5CE,001909673DE9EF68,3AEA64B8061F8E26,FEFD059B76566DD4,A2FBF3BBB343CD72,32A06DA51D9A145B,64B8E1472BFAC74C,0D05340D18930467,AA1DAEEDE436F9A2,00198CE4377F94F7,D4A6704158ECDE3D,E1DBBC37692F2D1D,AB032799CD847D20,F112A09763D841BD,C94207B46A50E640,2A226B6CB21E58ED,C901C2A8BF17C073,003F925ADB023E75,E345BAB791AB7BA7,3FB1FA7D72A15642,4907374984F7B188,89C6AE68B6433092,306BD36C0194DB50,626DFCE1FC64D683,7E63B14DC1925FE7,000AD2B300DDCDF3,C49A8604C9EB4EE0,C57C68411C37EE7C,01972AACDCF6BFA5,FB2799CA78D3C64F,CF0178447FB47ED3,2B1202B2B07FE32C,8ACC78222F68312B,003867009532B82B,20C0E2B4978C5618,E3089D5F1FA17D56,F5BF801BAD0D9AE6,42F8BAA87ADE2B1C,9752E7FB4E618635,1B3E471BE4A0E0A0,27B723C5FEBF97EF,003BFE6389A823D1,B61C290E385C0508,8263DEAD2A825054,9634D3425306B7E8,F33DDFC7C6B0446A,5C63E5F57463A4A8,704485D515CEDCB4,2ABDF0CE08F45227,00245E1B633B02E9,CC8E965A42A43E10,4305317D40B2D996,B406CC6F3C2A5734,063AD76A3A0106DE,C6A2C6598FAD8A49,964C9C4BFDC89711,866BF40E998C7B90,0030E17193E64540,98FD523E6FAF845D,130EB338D55FE2F6,EED3D8460FB58360,602A8F327516C9C0,ADADC25E1BA11183,378F811113F5B8FF,8FA4118FD7382581,0004416BD82C4E54,9EBCF9B0B02A91AE,D2294877EAFA4F3B,8D11F35B927806CC,7A2BDD130FA0A1E5,7021AB6254EC75FC,BA05F1AC2353E37C,B879D48F682D1813,0015B6B5116C7A69,D0FFD8FB1E865E9B,ED38DFB6A2EE4C7A,1BCC88130417E7EE,AAEFCABF636C98B0,24B0775A10379EBF,DA89B2C300DFFF65,FB8BD7CE48BFEE70,00273F4C6CFDD86E,C57F62A6B4D2A35C,25F5D61DBD328920,323D0843805C90A7,477014AE43FB2BA7,6A675B6C0EFCA370,2D9D08E2DA1155B3,B4A888580B24A7E2,003359EC9DE7B4CA,F604AC66B74131C5,6E0EDD56CF17358A,4EFA07B31D17DC3B,2D2D7893729449E9,DE96F8B56BBFE985,A0020DA33BA162F1,97992C855428FC1B,000F6EDAE585924D,5EE54C1CE7E4E6BB,518893D19CA59310,7C92872DCB2452D9,4C248197608C4E44,01E8580CE179AB2C,106B2E07386ED9E4,9C9B94BDA66A901F,00255E668E951530,22E7B12E24328B0E,1560E6A29B961DE7,D3B37AECF9546D16,27329B486C6AEC75,E7D4583A368F1D64,950909DB923368E2,A77A620C2B5D98F2,000B1543696C4C49,C2FDE51314D22CC2,8CB55BD405DBA7F9,9AB4672A79CAA8F8,763B40929579608B,735DFC4F49A9962C,988C5CC89FEC09DE,816C6870978CD048,0011E910925CA26B,4C5E33C0A541BF81,6CDA0AF2A323A3AE,CC4FC1358A3440FC,E35258976DBDEB02,B9EF3FB756646888,471FABAF062DE1B4,E83EB0FC90D6CF8D,001190C7D13869A3,A0137EBEBCE44DDD,ABF346B5AF5E0D95,D7A1053B802E65C8,845E84A36C78C511,4278F04019602CD6,E71A5E211D45AA5B,1A0516123DBF2A86,001C59DFA56B113D,34B6EC5B0734275B,924E7DD54F11F430,4C464CC7FB1CEA9A,1C799299ADD696EA,FF243F5797364628,44EA6DDA8D861153,CC929F747AA7E93B,0008795FA1E21C34,08FAC0E3559E1835,6EEF759BA02E98BF,EA7CBA27E06CEA5B,77A297B066B2E61F,7CF86F479F56D2F2,5A5FE3EFA3072A4F,AB56377DAA9809B2,002831BE1D185CBD,7684BFE0AD303C56,D8D2A37706DEAEE9,F37E6FE8AA31F8A7,2CE6505A812FDD87,73A0D6EDDF66D11E,35389CF804692B5D,BC3B8DBCF914E65F,0016609257DC2111,DA076217DF1E97E7,843883C003463E65,5A58D6ED22F05921,765EDB199782DDB0,F1C974B116E38927,1982EAE5B4EF5B79,65F820016B243472,001152E86B2013BE,7B4425E0E165B1EE,3E23159511DFC7AC,9AE3A16DC1932F4D,10A6E5C24B582DEA,F2B799B355091DC7,3F78C92B83CD8F88,8F2B20E835D13959,002380836AA77EDA,7A2057A14703F3DB,7EB841E8909AA12D,ABC16AD6C21541E5,531FF9D2F193A970,984F0593C41740ED,737E8D1546930F1D,DA1D7AD1136D8681,003A703AD2A1C86F,A8F71E8DC5C87CA6,8A0B75C788A5B173,292F82F2CEF5E9C5,AF9FA8CF39EBB954,54E38F700E2E2316,CEA338CE234AA448,21C0D34D2EEBC13F,0030269321068F78,D0D9067E92AAA6DC,5A2AD78CE79F4CE4,A91419C80465E323,59AF1023E41B7975,DA12F09080A4E917,DE8AB856FB7ABB61,54F25516EDF04B08,00035C3962C37F81,C566AA51C105A6DB,716D2667F5CFBE64,1B0256BF399E64F9,5C0BF2F0C1D4010E,ED1D5D43E7F323CE,91EE10DA5AF8FA4A,C1F1C6D2954B2D70,0036227CE8A03E25,3E41C47D71A0CB95,63EFA0409CCAD891,C9633CEC47CDCFD1,08F5025846A4FB6D,3C5ADD28872C9559,B04669BA4EAF552F,CAB60C2F8B659181,001855CB97FBE8BE,F55C42816868B4BE,70947EBD506A3A80,C1BFE31E437A6313,357FD845DB1D5F2B,0015A6D3F4FFA495,957FA42A5D93E4EB,AE64BA9C98483441,0036EB627AAB6BE9,FBFA5EED78922DBD,E4062C3E7ED6BA8C,98EAE4AF2A3B51A6,B20F7729E6727448,EA7EEA4D44346106,557AD14A4AC6681D,27182D8405EE16D1,003080E22A3FF98B,72214248A6DAB585,9F797D74199701CB,1C31A37A57CB7498,8A61C02CBF5BD727,EFA1AE900C37838D,52FF51A0199DFF25,A663FD52FC64509A,00137C39208818DE,A5E47425C43875AB,367AE5A5B4ACEAFF,DC9BE6CFE56DC639,025564700ADC88CE,39F9AB9C1465D621,DD53A59971F2A98D,CA6B6687C302D02C,00184E471AC1AD8A,5080E9F335C9C349,C31F8946838556FE,15AAC611141872BB,CC777D2B6EF2C3D4,2F1DB4931CDBF4EF,F0B86316DEFEA031,EC02242AEB2E9919,001DBB2DBBD7125D,4FE94FA6382DCFAC,13C589708DD36A27,E813F2A366BE2D69,291E0773309AF183,D618AE821AEB3862,3D486647C55BC76E,2AA8B812A5B39663,001DD11F98BB5296,A1B9B4EE408DD655,55106A3B8451038F,6950CCF46BEB659B,56EABDE59AB81A56,699553E782F737F6,A7BCAA68AD6C5FFF,A0617BAD903DA4FB,003BC41E6701037F,68F63A78C3D44274,993284AC9E1427B3,7D72B13A9C645AE2,109E78B179399397,BCD7E46E431D3343,CC770C03259CF721,7EAB1B9BE4167F09,002780FF602096F6,ECECF7FBF906FAB7,7D490FBF161D8950,375B5B8B11EA5488,CB885FB4FD1499D9,CA115742298451EF,9A1C03A5E890AD6B,2E426AC7C10ECA32,0026122FD0E542FF,C5528511CF1043C8,7C3746CE7D544EAE,70B146FCCE54AA71,214614815BC52566,4D773BD191D08901,798A6CD8B2892B63,39FCAF890C393A08,0023BAB1EB6126D0,BAE0B21E5930013B,605066568E6FA5A1,8469D8F671E02C37,6C00B629DA5D14E1,121D49557AB50F2E,074C63D5BD659E70,809DE545466C4216,003AB4DC214F2C77,2E5C4B458C9471B0,7C8D7F769EA22D79,B073990814871EA4,2CC4D377BAF56728,D7F2FC2313AAB170,6676F579D4B4AFFE,7B3EB570A60EBCF8,0017C499C301CA5C,32BBF391284D1387,11CB90413E07F3EA,C21B66E54E952078,D084AF3081B48712,B2FD962B9A3BAC7B,7E3339109AABE029,958E349B04CBFD3F,001C3D80688BF593,9DC9D1898D632084,B94EDA89E453B432,3D05991A0C7C82AA,38835E6436D8897C,13CA7DBA6DE49277,7A4870BA96143C96,6E4B4FE4F4D6FB29,0026CB0D639F138E,58D76182CB798667,1A718FAAAFA1EC48,8B2C9CB0FE9EA782,8468309D1321A735,AA1C5F2C43F7FDE7,747457CB86A700D2,101DAB2D6CFBBBF3,0015EDA9DE58B689,E17FEF9C82A1B3ED,D8DFF1004CCFF8D2,AF277BC20656B9B3,4532C862A1362014,FA14EDF29427F4E2,45D29E2F7E1F42EE,BABEBBD8F0C24264,0032998C9AF4EBBA,3307F72272C4DD56,A98E6723BA205571,2CEA98995423E32A,6C679224D3862A5D,07EC63C5EB2BF5A4,AC91F55B51DBA4FD,6FAF3D410A2779F9,00237041DCFFA004,C1E19C24054A3B5B,72C562504417BB7A,C80B2BFE3B3AD768,829F80FB831D3778,AA4D295AF19CFB5A,77D36876E3F6FC5F,0FF9F3F807C14563,002C8328B10AAAA2,D73106441814A204,06A3FEF11E3F31E3,98264948E8E9A3C2,7E64864827F6F6A3,22E85B97BFC74387,BE0904CA8477887B,F6D2075B14218FCC,001D0B26030F4758,39382851B620CB00,C42E230577A47A90,A808371D97CEB451,710E60D86FC992CB,3C9DE054A0925083,D6BC67645C96B9BF,9E24CA585F0D8DD9,003C1104F1AE69D5,7D42427504C5B602,76B8B1FE6501BE1D,FBFB40F61ECACFD2,A5F269BC79C0BA6C,89A7FFB13C0FAD6D,2042BE5B5DEE75DA,0FD70AE4A6FE54F3,0038ED58D26F7134,EFD20A46822BB253,3C43B1693B9F7750,0E83CA0444D69C62,F4E7D7C0E3E1F2F4,5E3F21971D03417D,8BB3D87787AC4C0C,EAEDE33B4AC23B27,00128854BA177D97,69B252B125B46ADC,C368060094395F29,7C095BA7BF7F227C,1C1D6EFFF4771575,35A4CE373EB659FE,9A037F3F83C893C2,E4D2B17983307DA3,0005DB30FFE3F3E7,C0D364194B578848,7D125E74E320E7FA,1B8E398C086685B3,901F090B098A5094,56383BF1B30A1438,05F276CE9A7CFB9C,BBC25D28BB83680E,001A7CBF2393CD77,B04B082EAE0963DD,8E5FB9B3BD80EAA9,926852EBD9C787E6,BDD4C7C33F91D7A2,426F225809089970,D24DA464BE5D33FD,A53BE668F1411A16,00203F9B429769F3,000CC9D08DD7D539,1CE994C33B56FDAD,7FED10C284F926A0,F6BA6658A909AD07,7C6A4D9DF04AA04C,0DD6A6E705E3CB55,454AF3F5D353D5F4,000DE52AB6C85A73,0D309DCB1D29A82C,0F026CA05423B46E,3561326AE5D73AE0,F0594D500060A385,E28E3F83FFE87EB9,200B84EED73EA037,A09C83BE87FF4785,0026F98A8B6235F2,1846FE81B2BEEA4F,D1B8A3CACFF2EBEE,27A6C160D1228C3E,1D59AB05EFED9D05,FA9A0D1317553C92,BD52008F79942A95,5F825824DBF46E11,000816AF69AF4882,B7DD61E2A35D2887,0E581138540D8D18,AB86A26D1F5C6079,442491CFC515763F,3866E5400DFC533E,5256D81E9FDE55C4,1358B277515D77BC,001AC67C6CA3AF51,9E0C928EEF7BBD25,23FC3EB7CBA1A61B,C04321230B1E68ED,E788023918888F34,6E13C06636962791,56EBA05C762C6203,19A73A4C54E6F337,001DE4728A0C747A,D2FA60C227C1873A,BD2B95D031EFB1AE,AF707835D5C08C4A,40FE23154C730B82,C86A204DDE8740C0,63585F28313C9427,80CBDEE8D5D1BFE0,0014525875054E63,AF06BB7CD39BBD2C,7D88EEF1F6B78AA1,0A24C96D0B614D6D,401D5517A8336CBE,1A669E78C13BF9CB,CD72F60314F38D39,6A2559FB41256BB6,0020A718B2A2B313,FDABAADB5C1AE354,628011FA0A82EA14,7215A92107917F34,046C32885C7173C0,65163EDBCDB0AA7D,59B033E13E63E755,E89DDF455F111075,001E127056432E2B,1920D9143382CE7C,A6258F8FB0484E90,C86AF2D906DF64F1,D8EE7752BEAC8913,D9FB49F00DFB64B1,EC20D868A6C91787,4359D6027811DA66,00308DD398138F35,3E82959450FAD176,F776066FDACE77A9,9F342C183834083A,8C2B9A09035CF984,7AF6F39B69A40738,4CA640DF2C6093CF,303E887731383D59,002E90CA6F3D25A1,D730DD796D26BF10,140F3A2A7B079EB9,9DAF3E3E064603A9,A0BA11BC14E35CBA,E56520A70262CD0E,31E9FBFF6C1BEAA4,84EC17F90F1A38C2,0025A60EA23C3E56,A43B30402E168E2B,41EFDAE13D1BA659,27623B1C51FFB8C8,A6297763E56AC927,88E4599C695C7EFE,B0E69858ED63F1E6,7412A8E37F60FB13,0006784017637113,647420061023CC29,5A53EE21188761B5,71180D88B1A67B30,FED48C2F49B56ECA,DE9B0C76BD448667,890391788E5A62FA,550F0166BEFFF210,00108D92031C1E8E,47E1BF269684DC21,C94E15C6777029E8,3A3659A96AD153A5,E6BBA92DDD632D0B,490362AD976B34BB,22E10A300A143BC4,3EC4E6779681D748,0031423BDE7E85A8,7783DCFC5E41B2EF,9E4637AA609C6C78,29F1818BA2677720,C2193BC24A42E8F7,B9953533699FDC77,4E2B836CF8B4DD11,931F4C20047070A3,001907585B6CF65B,CC3082679F09FBD0,D7FC0F7C623A9501,17BF2FE728874D60,B77EC2F87FBC403D,C45666EF38264B9A,17093F85997A03D3,04190D3F725BC779,0000CAABA9931BCB,6581F544EB828755,0F3706D17D4E2EFC,621052396C8AE800,3B6542B3C3156688,EC50FBFB0C366C18,3F4A3BB67DA72927,71B2210D15F3765F,00219C57E2F9B443,B7906280D9067CF8,EEEFFF867BFC23AF,8D504191A6D92DBB,9CD014F0FA8429E0,743581CAFC2822AE,8EBA1072B6F29BD4,BB8D9677CA26094C,00371549466FA8F1,27DACF79E0AC9BDF,625DB3527D7ABE18,3F688B3115F1C677,001B7A316909768A,17F7E9554EA2D10E,3D3B2CED18D91546,F340EA8117F105E7,0014AE3E09E4032E,AA2985DE3431D58D,0905218F0A72B371,01D42EA79A76A873,C2E07F8227E8AE79,6C47252F73E4ACDA,4B22534F2769C015,CCBEA568592EE7F7,000089B5E9ADD6F0,7DEFB50D32A2BD28,57204E151AFB28C5,39F9B857FFCE828A,39997C9E58AB9AD8,76483010A3DF9E7C,65D3F9428196EE4B,DD128886E0239899,0012E1E2DB473C3D,3431BE64E71E4D67,CF2D9AB6FC402C48,844029D9D19C21B1,ACDFAD192EBDB524,BF18748CD068B831,35B5A10F02D85F35,9DB5AC1C465942D2,000444703D65707A,7CBA7709958F7C9B,286A941F72D10930,9FB435B137BB308C,E89A928AA71379EE,E143EDCA7B650838,3BD6A6A1838A175D,CEDFEBD499B54391,0003E84457126C94,C5D1154C50092EE8,FC744D2F2F2BB1D3,FB63F0C4FAA28511,F428D90CD5F739F2,2849435E839F96A6,8883134F56FC7376,6AC77AD59D74FBA2,000F135A7F94741A,283A881D03F15BF9,155B713C950508F2,1167DB27DFB06BD4,26986218E479EB49,46B38AF8E6BDCB67,DDF51FC79798E5C1,6D26D5859A8B290E,001F3B7987172835,9352AD92F8785D07,6686044C895FADD2,6BE27D95475E0373,8A4800A9CAE388C1,79B0D6A1589560A3,0AD20313A906625B,8A3F0AE6D690588A,002FD0714BBA8400,5218957BA2BF1EAF,AB426E55AB30AF73,E468A22E533FB22B,B40333411D060EDF,AF3CA9BE7564F02D,F0ED1B1746F8C93E,58BD03CB9971DF1C,000A6CEF8E52D2AD,731B957DD61A45D9,458EAC690E2AD0F9,5D3D2EDD8E0481E8,115327CC79F2FB25,E32AA6B498431E15,09F09946A6458AF7,8F8EF6BDF5CD5BAF,000A0D5F929B8F06,4324BB41C08AEB37,669D591A2AF37994,FAA01DB11A21D67B,C0453D74FF27FAAB,21311D61D32FFB07,326B533FE149A39B,28E0A6EF4C7FB806,003D8186AB696681,D568B869534470D2,C6A219F0CC420EBE,E226E5541F415CE4,D4D8AB3D575B16A1,0F704594C77C1C27,8362ECF87DF0226C,AED88C1693C116A3,002762EEF490C32F,426823B9BC27AAC4,4A21E54A8464F589,136D418C55417385,79D56039061F2FA9,B9C780B8D94932C3,582B43D26A774B42,B33C668F676AFBD4,003F4764ECFB97E8,3DE78269918E2DC6,2798AD071969FC5C,B89864775722E2EF,C24582603BA42B05,C1B54DDAC63E37D9,73942E5E8B344096,AD7EB2FC73F67CC3,001232B406988824,DC22B10DBC0DEC60,54E86E768CDD4D96,4C7396EB07ADA2D5,269A86944EF2C544,03F4D6BF4B0CFC40,4690F3861A58DF7A,D2B191209791DDFE,001657256EDF3A61,84C089D3C270298C,EC27F3E3491FEA35,31B6737F72CFE394,DEF3EA3ABAE42152,AE720BB63C73A630,36D4E1533F4627F9,54DAE5549CE52B98,003C8B7978675540,68351D45BCDC19D7,3359433C014668C7,99CCB57AD3997023,8075EFF3C6BB1B9F,7891821E0EE7D223,B8F55E111AD04FD1,2E17E72B069EC1C0,0035C4578197A550,F0982D8883D7B70C,8DBDD2B14DFE51C8,9E65888C378F68FD,86FD0621785B46DE,39E31084EB5EDD68,BB8C5E992CF66AAB,9FE7D2BD37C31F0A,0025A73C9EFEC41F,D7298593641078A8,0BFE7D9F0A55BBC3,C779CF97EFFCAB0B,5C45122F548BCC41,7966264C5245B4D1,EBEB9199D07C9503,7DB42154ADAFC448,0033D87179E4FE2C,4B1F22946028527E,5DC1AE829267013C,8EF565A2A5C481A2,57600B9D9551D289,26773A4A9757F77A,2545F50E35654FDF,3A96E81579BD100B,003B93389BE00742,19DFF2C4FA57DD64,4F9F498DB7A8D03B,80DEC86414E2F5F2,DF254B4808869C58,E9C0A0576EE22974,3F3958750935B337,0FD13B9D89EA5C67,00148B882D00B868,07CEDD19311F2B21,D878485B994CE6C8,2AC339A0AC18CA64,1C75E5DC42DBFF5C,0B7DBEF909B904DF,BEE9644AE8FBF92B,636ACB9E2BE60688,003ACA900CF0BA08,77FF8053066E1502,10F3A88D44784931,18F635A1D63D8463,3257506DB5E17F0F,3390C9CDEBD1E28D,4C6E4F4AB1E1CEC2,E7D6899AC6987DD2,00354941D41F56D9,239EB158A34DAD38,3D2EDEA4F3C739B6,4EF86C1D926A7802,9447A0F20022BCCB,7AA5D9BDDC258D83,28F3FB3902C07E0A,3360A5243C932CD5,002A8B29C60B4E0A,ADDA7E531DDA30CC,1E7BC38F8556EF00,A099ED84E70A4F9F,42D038DE33E68DA2,34B094318F3F1A4C,D487B8412E418C73,EEC714737D95E18A,00017921BFB0ED32,2F9374856A877BBA,751A52E2C2790A9B,755D6FAEBF964B32,BECE7540A773CB2B,2154E1C376563AC7,9A2829C02DD7056C,39116873358F7E52,003925CCBD381BCE,E184E5E009FF4F40,A2FA69300A46765E,7FB75C449BC0402E,253BAE299AC46632,01635DB9F9F6DBAD,F754CB7CCDB346F4,EC8211524AC187F5,00266D901ED70F67,4A20CC8BD68356F6,E2CDF854D9857351,DBF7C1958120FC7B,53034B34C6751704,9842197F51B1CA58,92680FC58D7EBA60,6442C851367EF3A7,003AFE5B7571BEC6,FEC0BE7051AD2159,7DBD7814AE9A66CA,32A39FE108633A9B,D62C2B83C9C76DA2,53227DD67BD382A8,19A124523C607310,7C8B5781C30A61CE,002659E32288A68E,3E8F4A894E8A960D,C7EAB3F76ABC8A18,CD16A56C2BCDC18E,9551AC47C1D488AE,E1FC787CEBE013B3,75F687FD6704B632,A3DD5EE7994D5119,00054A65BF3E9A11,AA85236241AC465F,388C4C31D7958471,1F586E9796B00037,3853F08140ADF073,90E1DCED2671CF87,66C388E10F38296F,D4BF39BAD8C4BCFA,00027EB3B02A0552,117F19059B6D6603,404918EDA6F53CAD,0C3B1764210F9754,2A951282AD0AD7AB,C4852F6ED77A65CD,4BE9AE734D6601C5,D5D25294843BE7B4,0038D219BA5212E1,886996AB9A112B5B,2C78D0E1456DB01E,167E7B3EE37C76B4,B56F50BBC25B1239,3A7E925AB5FD8373,BFB9403DFD1BECA4,37F6E14836F023DE,00068AD3A58BC850,A7DB5DF3A0A08069,7EB9EB484648518D,14D86D941F3E2209,59FADD95AE545654,DE7DC9554EA754EF,A50E5ED2F7726442,7D06BB28DA829D3F,002F476D8DDF63EE,1D4328EA8E463B2F,ED387BFF059B9024,C6B6983A824540B7,5C77A08F8CBBEEBB,C648DE5F9EDE0C20,51BECA7B01292347,EBEB85F96CCE5A6F,0013DF321C391FF2,77E0F48001D66789,67DAB41753E4D84F,726C55593A8A6AAA,DAFB4DD3AEDB578B,38687C9600F1F991,EBB422914F78B4E6,B32332E9774F63ED,00349AC8F60B6B41,0F9D1655DE1F7CEB,2B1719C7CB199B80,86337147C666BD10,EDA865573340C402,E0C87FC685370813,3361F0DB37B3F481,2932BFA4C9E35169,0039EA55F06A9D58,75A4E8948343B518,A8541542D2CA922D,EC21B43AED570A08,9E6683DEF8BF8CA8,A2ADE92DEC61854E,200FA68A14E5BAC5,612A52626DFB0A40,0029CF0D0193DA7F,ED0F71A007369CE1,668FFEC134480DBA,753D6D782A88BA78,38ED84D608D5A932,2AA2E76BF32633E4,3903A36ADFAB59A5,99F234FD109005F6,0000A9FEC10DB3DB,5C5DE39BB5DC4B2E,B63AB16334E6BEA5,BBC6A2F99FC59C4C,D7A0DFCED2A144A4,854E3B597FA6846D,5D085162B627FF78,8DCBB97FC3E941DA,001396ED63559FCA,4B985E487A0205EB,1D28739998DC1F8F,710B483D06305455,D82121B2F1EA98F5,0E573E234AD88B70,496460779A83BB6B,1E89692577A69826,003B12CC9A0750F4,37947EDC31EF1860,6740C7FE33CD6841,51B8EEB572BEFC1C,DEC267CC958130E7,99E613A004953B1F,589480CF7DE76FB8,3AB0EE27FB7C2B38,00145D9AFF2714A7,1B0999912069E5FF,25C6ECDCD193B575,25C924C1D5B88799,4187DD73F19D7282,9DAB8F0A9CADE4E0,EF1ECCF096F997B2,A34271F6560C283D,002F1062990307B6,307EBDF38C0F12E5,3799A89304C94287,F640EBEC023B63C0,59D494BCADB516FA,49F82D1C87E5B091,2E807D5D171F6407,DFD14F949BA6C118,0036C3A97F9A9DF1,5C2FE6D667395FC1,B2E02AFA647DD648,BBF4D48038CF7162,509AEAF7A07260F5,456F71674BED3559,3224DC7137632544,5003FF935578FF99,000F63203DB73ABB,34FA9A75CA7652D7,34F9424F8F2E8BDE,71E93A8FDC2490C5,943A87F137BAB8BC,0D937C0ED52D4630,99119C27A6E3117C,638F1E45BC4EADCC,0016F3817DA85310,A968F4B154DAA5C5,CAFDFAE735292514,B447F0BB0AE1D702,8E87884F827A7608,6EEA49758D51A9F8,C6953FC6ECDF8922,4379767F16A18023,002FC64DB6453E63,3B5256C6AC8ED8B8,991C72E5A6C774D8,AA26CBB18064EFFB,66649BB5BC2C343F,B30F88D68539942F,09630799B141B938,2D3C0E6ED98D161F,0036581DE1ECCCDF,734D3D9CEEAB20AF,AD95C4C8E80A7EB4,89183BF37198C10C,8B6DB3B07BB9EA5B,65365566CF0268B3,D3BCA911C5C5F199,5E2FE2CC91C408D5,001BC2FBD23EC2F4,D431E8F177F5125F,3F4F2AE79F4A8D24,0D169F13B6F3AAF5,2E79EE77911CBFBE,49EB7D99704E4E6E,FC0E4CBF0342B1EF,91CC3259A138B52D,00307FD7A7C585D4,1292011A4F9C1ED8,A01C14E0B4A3F35C,5A78799C25406073,E2E1955125177B8E,B43CD4A41CDABE74,0F738D7CC5B93EB6,3557A4AAEB8D122D,0035F943E6E56A54,908BB99BAD39CF34,3F7FF7687372BE08,5355B6151C63B096,908B8CA2FD6F040A,7B1EF9D829AC3C4D,6457557F7A089E7E,BF486DAE6783F72E,001EA9B3533B073E,DB85E3A2D08C244C,3104C3A075E320FC,C1098114FF2918DA,EEE371F097F26ED0,331FFF33D4A6BD76,316F0986CF3F2150,083350FD149EA113,00356E8D9FD432D7,87B4D7A5346090FE,AE760E523D10C41F,BE85B02F41FCC1E5,DB8A8032A88D91C8,246B1AD0A387B293,46101DDED3B23072,9EA5A3D57FD730B8,003F9A5FCF7CC873,AFA7846A7A7C2FEB,737EB536F3340B23,426A25A2E267C427,71E08C109D2DC8E7,E13A8A3822FFC4F8,B5BFCDADD5919D0A,0DB0821B34F8901E,0003B09FAA2F4DAA,F9BE25D26E759627,C022DF1B38C7D305,AF8E510B4CD7E2B2,6F2952C7FBF662D0,450E3653D813E400,3D01DE38C78F6160,CD68EF802ABA7C19,0023756C2690B1E9,EC015B20598D3949,219FB828424697A8,F64982521E7353BA,A17F4726D124E30A,721B335373702AA3,CC134076C36DDABC,8666CB7F1C069C6C,001E11618E8FB770,291B18E78005586C,C4457E4EACCE410C,AA634B593BF7D7DA,3B564DE164DF11BD,A3280F50E8F5473F,D1157A83C81BB173,2294112A430AA68A,001B8704A90FE9E5,F35ECDED4E7F3276,8B10B7F4A9543332,E608366934CF9F30,432B8C52FB7683D8,39A07B1A743B689B,33D32CDB4382158F,0ABC25C233708D34,00211A5EE1867669,56B7E5F1CADF3313,47B6351D7109C43D,DD5666E5339FC4F0,DA8946080066E593,36994943E044F666,6A2B8F4464FB3E3B,6775ECBA97140B33,002F0B20C119E257,4CBE7B2A035321B7,B31EEDF4016AFC9E,F853E0F9EBD7E953,C88E9F8FE1BE7272,7DB096E448017615,D6FBF30304DA0BB7,FEF5D9A874327177,003AC6FA54D7DC62,82005D007C9AED13,E0B6EA116A5D23B7,AD65717EA4DE6487,15639FFD0B558EA8,76BFC178C5F2BDC9,461944B49557A700,C66079DF0C57F9D2,003B7DE01528082D,D5693E97D8B53A88,E4365A9243F7C564,F4FC3F444CC54747,DB2BF03B2AA1BFC2,3382B49DE21B8238,B839CE1A807B14E7,D648CB971E2DF0F2,00195B1F31C8B985,5CF601EF691C8411,FB61B0468185AE7B,9C8370B8A4F911F1,C7FEB02F1F842E0E,B516DCD90887BFE9,8B713061E5E0E4BD,2C17AD49DE6AD232,000FE60868C75312,4F2A7CF74F28C8DF,52A61BF256662287,46D63444B75DAD47,99F19B8F1ED887CC,5BF09FA62D79BE44,7C053959512E0DEA,3980E77E98AEDAEE,001AB407D73E50A0,AABA9D1340B05A22,FA67356ACC404A0D,5C87FC45FE5BC1F1,C24F06241A283FD7,5873FF137240B6B7,4F2202DAC0407A09,7622F95D076787DF,003E32D3538BA52D,71CF043B02F4029E,F2E0C6DCDE4B5E4B,9B20D0ABD80ADB52,A342518DA9C937DA,506C510850829AE7,47C6CD2CCD05EF9D,205D8CA94920A22B,00381E7404CE0CBC,ECE83AD9352C2823,3860D22F6A9F1B74,F6F983EE0F555ABB,0E54974EA7B8F545,AF6EF5DD3F2DA352,03175C4C42E185DD,FE146E5AABAA6307,002E82CAB178E922,AE98986FBA003312,99AC6AC39159C882,BF9ECFC393993307,65762C6F29AC779D,387A8CC25D4529CC,65C1CE3A619696B6,7E64DCB7C333CEED,0013E4983CB2C9A4,04DED04C4720EE33,5A64CEAFE858F85A,8AF32312E11774D7,274CFA6AA509D361,F7A0488C63B5A4CC,C5584635A10FC961,B0398F65333BC999,00291F2ABF0E10EF,D92E86099675CDC8,803A569E83862284,5308E8DA552D68FF,C796FFF8CA7256D6,1AEA521AC7316631,4FF75D83A7D6C6F9,4F81F1D8F31119AD,0001770DB9DF8F60,0A1076A18D981D2A,8F06FCF5D6DE4C70,CEC9733838097057,50FB065EA1CD9094,93161ACF5A59E2A9,845983D6512FFF79,CD0E1C06541D52E5,00042C7AAAA0BB1F,E285AA7217ED5CFB,13F7367D4AE539C0,FB9C59AAF663AA40,ABD3304310774662,E4214D6AD98968E8,5CE1BC2F5FBBEB13,EA77DEFD87B7B3ED,002AC905FEE0F8AC,9FA860ADBC72C2D2,989C4D2948CD6DDE,B18EE90BE1AD4BB5,D685F9B04E49181D,F38D785033731986,DA8FAB3E7AD81DC9,C327E652862489A5,0022ADE9F9C0FA37,7A813D7910A7AE4D,CD7698379F20810A,C2BD0C335C47DA8C,EDBCDEB6E1651F37,20C9C7D4D4E5B3B3,6694BF77D77167F3,9A99ADC1AFEB8EF8,001CB2E021CCF274,4FE2DCF4FFDF1F06,9A604B6CFE16FB30,EC3E031F268C7972,10E9199993B50D99,B089A13E702AE83A,8385530BDCA34E51,D870E484F8FC7945,003B2EA55231BB81,449D115DA5EABF56,AFC072E8F24A38EE,2ECE330359640FE7,F6E985D905956893,58182C9B435CB992,AC2A8C54344AC281,0A192F7AC0DB51A0,001B294C2F036521,30F634EBB1F06E94,B17576DAA833A32F,A256DA0896115659,5FA67941E88E3639,1350EB959F2EF3B5,788BE520132861DB,BE9D413D9492119E,002B2D7430BE22E7,1E07E360D490BC33,CEE2D395831BEC36,B0A948F75E8A1614,C1D62A8E9571A44A,945A1DD9B4339624,D48311E2151A0EA3,C77D6FB21B8CB73E,003054E58242A23A,2EADFD02C8B1622D,17BC72FB655AB2F4,B2D0DF3CDE1EC71C,2F4239B2A43FFC20,0390D4F85A306641,5F003E2968FEE3A1,BF137C501F23C0C4,00264CF89AD79961,1BF08B36A5181E07,6FEE26D63FD6D9F3,F4600638B8A000AD,95A71A77F83EF707,66C290996DBEC194,179D3ACC9A54B8D7,DB9334DF62BF7313,00142B500FC6EA78,8DC81B1791577D69,DBE49752CD507631,CE2795AAF59E2BB7,B38CC1B3220C2762,2BDBF7C667CFD33D,2F8658F790565B53,172AE38594D0A033,0025DAD03A1C2361,4BAFD338530545F5,882026B53661251D,A8861C4BEF1BEE28,8406C5861729CD70,028D90BC89980F9F,D1F68357340D9715,61851BF560009B7B,0014447D3F8D7749,41FBF1E190B4C6B8,86BC4E8C911F7164,683816115099D136,0952357ADE621076,9A4ACDD90EE870B3,3F1A3B5C44294382,36E78468EB62B975,0035D80D75E99C3B,A8FE70D5806CC71F,10E16A8D72145F33,D612B61A2EFAB7AF,3CFF7BD03534952E,C28FD239BAE71B72,34CFE87FE7424E58,F669A119840A237F,0035B3566567FA80,A8D5FF10491C8F8F,CBC997451C543D13,3E59F3855CF7E03D,85B0BE9B87591599,CCBCA3F11DD449CE,AAD1CAD2C2C7C11B,AB5BC2FE400F8C07,0004FF9C26E7AB5A,4A613CC203EE5C02,C81E767D21690F5D,F40BD4B57DA764A9,C8DEF84F2C7F5874,35CB6541E748483D,06E58BBE9A3E1440,FDA85604AAB25CEF,000309686C84AAC8,FCAA9EDB82A6065F,9BF1A72FD4BA7F2C,DE57A3A05DA9E64C,1A20E92C1DED19A5,6DCADAEC9FA7F808,5CA8E407A2A37175,2A95C7A08B7DC3E0,00290DEE95F437F0,7EF9A695A17391F2,E2471E611CF41741,B1DBCC0CE323B56F,D200C280E6F8A664,A32C246ACAFAD250,1DA20FBBADCF29A8,41580A644CE4FC5A,0039BA2590AC90CA,0000000000000BEC,0000000000000000,0000000000000000,7000000000000000,1858F371D28A907D,D89DE1DFB7FD9CC9,4022A097759F1EF6,00348C1710ACEDDC,C7670A44560F938B,AB8547B43C3479D3,3D569F5772456BB6,17B5B53C0FA23B31,38210235AF583ADE,49A527DDB6CFEFC7,076288D14F23F037,001620C022598276,EE37B8F9A6021865,8C5C41CEA26276CE,CE9D8BF310132F9F,876B5274C3DE6C59,59A9CD65B71D224D,5246877E7BEF62F3,109010B83B8E355E,0034CD34FD408568,00000000000007F3,0000000000000000,0000000000000000,BC00000000000000,B48DD9032BABBDC8,87354452517EE94B,B55528D05AECDDB4,000D90684A9D9488,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,C7670A44560F938B,AB8547B43C3479D3,3D569F5772456BB6,17B5B53C0FA23B31,38210235AF583ADE,49A527DDB6CFEFC7,076288D14F23F037,001620C022598276 - -ph3_T = 9C988666C8802654,8184EAC95BD2440C,E200344E0D5D28F9,C9BA078F1956DBA5,2906BC1E03C540B7,547D46164CD844B4,B1F040F7A98DCAEC,00149C072F5EB3E1,7F0D799C1910B629,BD86D4FE2D8DA37E,D093E71B785A0563,E3CE2A52349EBCE7,21843952BAE5404E,901EC526F4BB88C0,DA7FF2CC132EA904,0036A6DB4332CCE8,9C98F5B6D5C81D00,1E85D999D78C8540,B72ED89EFBDC2D38,0872FFBF30252896,E24A83FF782611A9,C174117B147D3FB2,93702F73CCE04D63,00279143ECB8AA7A,A3B0A72938D02581,7972EA180357F6B1,A240CE057EFE1076,E0736E8251B1BA71,2D710EA358B4FC76,ABB60C1ECD9CFE18,17AE912AF3591E5C,003E86FE0F9EB0B9,AC6B631F67D056B0,592176278AD019D0,8C681ADF943DCF80,8B534119923CBCFA,8DC5AC3D0DD5A847,B346DDF4C6CFDE16,1D852513DE83B7B4,000ECA0BFB5A4B7B,D2666711F049454B,7E454BE952117089,D3F999FFAE1B21CC,5CC07F0AE4984E8A,2B9C84A51DCCCC3E,1A76A2495250B61D,6F594C9CE6AEF270,00155EBF4ED9D36E,CF0EEDEE483D60F5,4AFB2C4D7F9DB8D3,9658325FBCE90413,97130CF056D15346,9F94EF01022B7B86,F53C8DF574E06AF9,DA2ABF66E22C84E7,000D751467B84986,507E896424C44313,DA0EA3BAD8D5CB8F,5AB1B42D97251EEB,F56EE4D0B8D7B88B,C1E1CE9F96BB65B7,1729EF296ECBF6CB,55AACAA7CE1DCB59,0013017F00154667,78D22D0C97EBF8E0,18597966B7386399,53735DCF43F1061B,A5AC480D2846C991,C0EE9E1228E59BB3,4A161A71AC030EFD,EE9FC4D499C05B89,003F54865C2A4A02,DEBBE76F1D22A738,8C8CD4B910C8719C,38877D494DF4FABA,77F2CB203884E2FD,6353D7B8C6632982,C701C3FDC2597FED,612A54C833D66F28,000FE5F367ACBC39,62FAD5A60041DA2A,7DD1A770A066F36C,566D7F581E9E39DB,2D7BC50C204AB39A,2256883E7DF85482,618034F61CAAF443,02DFD0844BBB8105,0025C9CA351A2E77,546669B3472C36F6,A2E071EF3F64843B,9DBA1EA75EB35A4A,07B4651D77CEE37A,80825DCE2C14BF80,2E887EBD2669B73B,834813581E66FA1B,0003139F77D99E40,A90BC0631CF6E5AC,52FA636BD1BDE54A,4569C1E84D737D5D,7AF91E7B8F45FF79,D382D3650601FF6F,41CBC0BEC2980F9C,645DC6F280A28864,00190E4A54AA2EF5,E518AE940B80EBB5,8F15EE0BD2B84DC8,C06452E6DA589432,B17EC5E19BE7E192,9B49EE5A181C8D4E,1175EEF9987380D6,2265C9A44EC1C1E2,00203D92A40728AC,0D3C8687DDD8C0F3,1719CD406BFEAA24,42884019B6625731,4B234660D441FB57,434275AD468E7A7E,17A7296E893D8B15,C243EDBF870C8B0A,002EF57CBF885576,AD5C7265891471D4,29729F561C8ED100,512590D6FA5C206D,EB134103EA32CB25,E9241137F91476EC,38C7EEEB1E271836,5DFB4F9F5AEDF5F5,000E5B36891B85CF,3AD78FFDCE75375B,B6FA684A8E9F7971,4808B4D98EDD7ABC,A8859CD33A43B90D,0737D8D5E550A41C,63670E0C46594321,A2C2B55E84BA804B,001F73293B5D3588,E3B936DBEA5D1B2B,FE361969EB9A153B,060364FFA640EE8F,24ACD933CE45BE83,0B6A042BD7209BD3,082522A1B55F3082,820244F73E8468AE,00288698C2CBAE40,115B174D8BE8887E,C4509994CED876C6,81F6A9050C32625F,E12F6ECA4B5BA601,05FCA4F5B0CEDA62,B76C8398E23A1065,79E613D8DE35EE2E,0031F6B174435810,CD09C27EFB4569BA,801BC242D4A240E1,BC7CECB19D0FEBAB,EF770D9F566CF40E,2D9F7EF61BF2510B,7B79B80AE1D267AD,0EE8BF3FB6F61A79,001A7305A8B38DEF,62E0B307DAE8E929,327737D48348FDBE,CAE811F7A8359B15,7FB113BF97FF9BCD,14142F90896BD74E,2400F3C256E311C7,5368A50F2817B421,0039E0B5E5DF18EA,6671633D77B71F3F,2205E5F39540643A,400ECAEC05E94E79,581446F77AFA1E71,ACF0CA2CCD7D9263,87BA351589031753,8902F4BF4223B754,001F0CE138A430CF,F304A171E9F7AF70,46572158652C9587,A92CCF2E7EE0F8E9,6D060B26ADEBBE0E,C334BE167E88C81C,48685E40E8E64029,A98E761AEED92A19,003877A0759267DF,4AB164CFEC84DCEF,6EDCF2C6C1F0A10D,5D15DC872CFCD260,6F5FC91B80DD5BC8,87CF65FFE9BDD69F,68121155AED7F3E1,016B4F4CBF7BF6A1,001BAA62EFDFF6B2,9B296C0B5A1AC63A,C5716037BF82A646,A62DB264B742BA86,D12906CE154598EE,A7CEF23AE634A18F,6C72484F4EEE38C6,D139D576E8449DCA,003927CFCFE5E3CB,FC24CB6BA03DC80A,B47566D5B14A1768,E218F1668F74998C,8B78C509CCC58B96,23BE099151A6A8FC,F3FCC4F15F5CA7F2,6D3F3E146B3ABA0F,002348E2192D5E0B,9797B7CC41254786,6788012BE1026E8A,6613F2D7B29F2DD8,0595D0587E9C6DB1,E06F5BE1FC396346,692EE10DA58ACE84,4B4601C57528EE5E,001702D2CC5ECBFE,9BC7A1E7FDC0D446,E5261774B2E7FDA9,04328AE86AD85AD4,A1E4593DB83578B0,23B7E31E6A9E3FD4,0DE8146908ACF95A,475DEF9BEA0750D3,001D8D5E069FD7E2,95C51F3B69166BF5,9563635268555CFB,F41684BF221BF384,A77B3A361E39BDDD,6E0CF1085DA7E0EF,4AE7109DBD004336,CABD5E8AF75EDD2F,00275409E867C1C2,E66592A3729818BD,F2F0A84A3BE47DB6,841E5084367AF0AC,71935E86D1265F31,1B6AFF7139CF7969,256771B02FE232CA,21BCADED78B48377,002B02CA94A5432F,A4512247F22D5B84,10CCB1BFF38FAFEA,BA3EAA132959F687,CCF684050D68E311,80174653C92569D4,995827DE8A85855F,590585BB8E4B3CDF,001F8A3A82D05BC6,13B5E8DA288BEB83,648A5CF1B0BBF7A6,ECC523F104342E64,F2839C6C4642C30E,8DB0BDE8549ED2BD,524E46D5105638DD,BAD828BED1BB06CE,001CADB13FFC683E,071D19B376C88BBA,47F4DAAF5882D067,008AB555DE77C837,0ED2F2F8968F214F,7B6D4873EB7FBC8E,24DFD97CC14249C4,E10235107426D2DA,002DCECDE21CD7C7,63B8BB9C1DF4B734,CDEC199282226A12,16348B5C1F98D48B,D2489DE3AE7D96C8,1C7A85E78135A32B,79372E37B9DE5DD5,A700310FF67EA5C0,00048E60877C67B1,F519DED21AE6A5DC,226D33E52E876864,F865180314503DB0,575F2692E8287376,E101825730E5BB88,8804B0EC216C20F2,86D7569F65D0D2F2,002A86A266744DDE,5D0134D9FD850616,5CEAEEE191420E8B,A209E140D44D2E3B,9BC8F64229CC0162,D8BD0AD08BF328FA,DF36063C6BAE32B4,A762906814DD6BBB,000204C7933FFA6C,105ECDEADD973F64,09B096698CB8E7F3,16C24B5F04635096,B9356A08C73D5828,A0C793F14B1E89BE,D3A9D3B77F9B12F0,233840E15E7E29A5,0008D26781D0C424,84A6262E1E110518,840D1233EAA689F7,B2C4DB97B16EDBBE,DC19966D81F4082C,9B1960BCA1895A2F,7757002E5513C2B8,E541CB565F9913B6,001B11A1FFC00FE1,DE48D1616E75FF04,FAAA70535327D7C1,C50C4DB73CDE62DC,5D6DB2F874128FBF,7EBDC7C5983B63DC,AFE5BCA500081268,4D84B4ADFED672DB,0008334C1F9AEEAE,74293120A4367F85,3D07C92720106B50,6BCB1C45E0276006,E5931EF2EDF65338,0CC923B23A0FCDC8,DCC750C0B2BB13E9,ABFFAD57D5D5DC98,00266D24B6849A90,4FA437BEF8D3A76B,7CC84787661D284C,52108CA30780A2CF,1CAB4D374FB5B34B,21FBA05A9EB9F527,ACB30B22FEF1801E,D4776876F305EB95,0003866120407F95,DA778B113B76319E,3A7211FD762C5874,2E6B7D7E23BBFEF0,EDB6A525B77046E2,55CF08AF7E3AA71E,43CF6783D64453FC,20EE50E2F873B410,003AA734148CD1A9,5F8B2DE052941095,46A6CB34FECEF48D,4ACA1371C8CD8EDC,B8885DC889FCDFB2,127C8B5F9C7D3CCB,4BE1E0754F15E940,937638741090C250,0012FF3F46E9DA9A,6B20A65CD8EEB5BB,2919B0DE43A052B1,B839E592F1221A2A,336AEA552382BD46,C3CE96940C2394E5,BB390BC5230117D7,38DC27C415D696B3,001C3528B9BFBCA6,BC50E2B04469C326,9889AB899D91C771,FE38AC4A165DBD13,E634885E9E9F49ED,6026112EB9D2A21A,8F9FA6D5372F6DE0,C5520AB13EF93D8E,002E31B822BC03BA,21B82332FFA4A26D,2A25186D3D4AFE31,F643CAF1F61965CB,7091B9041215EECE,FBB4648562E01C2C,9F53A9C32E6A38F7,4BEA434E4EC6B476,00244D9A31F528B7,5458C24D90879F42,C2FF2CF799A6A69D,A087FF0C6476CF51,931E7CD1F9E934E5,C176213F95E5C73E,8766A202B83EAFF8,A157CF81C64178CA,0005B6238A0B48B2,96BD0016BB6A5FF4,8B08D7986041D4D4,928CB1C422ADD4CB,15C4565C769768D2,6C85EAA33F5739FC,27142F4A9EC2B508,5A1E647775C9B57A,0035324392705CE6,4E4E140C02A95632,689A034D3F21816E,B8E8BE5394BB20F9,4C932F28D0730008,029DA7FDB4788DFA,D2CF146118A17A4B,F89667A3C3CE73E8,00361D33F76E8550,276298EB0C587937,557D2E1598FBE5D1,BE71A7924B569EAD,D06044A78DBB89F7,AFEDAD73544B4B2C,97AC7843D395D881,6B5322DC368E296B,001C933EE316FFE1,AE3819A10A74BBE8,56FE820EFFDBC28D,31A950CDEF516164,C33E61FE2718FADE,D7BE15AC8711B029,9CAFACF9BC5F192B,29B3F0F41639A36B,00070A7967090ACE,8F2CC8DC8764BFB5,D48D146CBDF39DBF,4B2C30284D501590,BA91AAB6CFE68893,3EDAE1C3CF02942A,A1B8B073F56A9B18,340465EEC0CCBF4C,003407C5089AF8D3,9299B5F034A9F886,007BD264F43623BE,54ECB2A746EE1166,36F2C064E17037AD,5D5514E14CCC79E9,E8B71B008BCFC5B1,8BF40408FD697046,00392928FDDC2D97,11B6001D8D68179B,F92DC485239063F6,0B7C8C4A28BD9FDE,9224922DAB3773F1,BC483731A7A1C9C2,FBBD8DEF671EC174,1658844308D791AE,003F7C08A4AA5345,B9DDDDA6C85473DB,CB65A9A1F96A92F9,A092CCBE6B802EEE,3B1DAE43B1567BDE,B5DAEF6B1C3F83C9,C81278094AD73C1B,1452D49AFD88F732,0025C42713ED67B3,F3994959917A0793,63AEF5702EAAC7F8,3CEC8C717A72CACF,4E30984A58DAD801,FC0E9BF701BECB3D,3E63E9AF82D17496,EA5EDA304E8ED77C,00344495AA4FC389,96CE8DDCAE7D8BD0,51DECBA3FB401E1C,7E9D5CCC2555E2BE,B356BDEC3F5E7900,1ED724E8678BD786,A15E2510B6C0D559,A568134647B5E591,00217EF93EF14E04,937A8503C47B576F,C8B9BECEC58A61D2,3E64BE43CA0284BF,EDC5075D49F58553,E7F60A1DB59EF562,2FC24FD7104F9056,B381BAD353A3DF93,002E806725885546,EAA9CF88045980F0,9ADED2BF8AFFCB79,B7BCFA54A15EEC17,E2733A005EAD5F41,FE4A7A957485E989,16BC1F3D5EB4AF48,684C98980C03FD0F,003D521701E4E5B6,8051456501547900,DC8A73D662C69E7E,93A9B69C7728597F,7029095B70E31E40,7FE593FFA978B1A5,5BC8D96F0718EED3,4C5F360AA500DAE3,0018EE82DBED1799,13F2282A400E16E0,84F8D3EB2A9A36ED,70322B55ED127FA5,7830063E2A51900D,291DA19E130F7620,9191F2851DBE2CD9,940FA686823587D0,000F751DE1DD5DFF,20C20D8E6C76BA20,51DC8AEE9765434E,D87C05E3DB5636DE,C0F808311B3486AB,130FD48E4F90B381,87C59B37BEC82FD1,FA7C0D10E7DDABD5,00385AABD1D57A08,0C1912C116309310,D5D79D8C99934350,4C80BDFDE20D38CC,9F78BC8C1E0586F1,BD957AF3EF807415,4F535CD1A44FA093,26F76D0A1AB3B6CD,0035FEC54C91B5E0,9A1AB6D416723262,619F15F5069BA794,E07686BB277ED2E4,1F393BDE2257E3B6,A84C926A905BD872,BB57E1EAB530E052,E409E9CF6F9A55FC,0025ED050273DB29,82A8DC3AABAD28EE,088CED05DCF79A42,87576BF3681E69C1,C8454429222D0447,4884F2AEA6FAB43B,62CAAD263C34BC5D,E5798F2078A04EC5,001A34746C6C9F38,BAE387D45608BAAD,8398438AB497F3CB,5835733297A1E400,129B2AF745751042,8AA934C55B3F592F,C96B90298BB611ED,DA32D56CDA5044D8,000316EFDE345F34,EED2D8259750921F,EC1289BCE5BC3622,DBA842900D16425A,F723BAF02F1BAD23,53A48A34C1DE758B,CBA8C0268EEBC8D7,2AE75F46B1D7AEF8,0006077477757227,7579F7E16970E26D,EEDEDC64272087A4,618D07BE03FF9EE5,59A69F70A833045D,C7507B7112251123,D8BDBF0499BEF8FD,F2ABBC486715D98E,0000552FA815EF81,7B98045A1010A86C,C16A31E405D862BE,8D3CC3F2D533D8FA,89524BBEDFB65969,C6F6ACF04A4476BD,C8A13A02A78DAC0D,54DEADA757C7AE18,000CC47B5BE55160,1035463AC199806B,43A35F65253FD7D5,EF022A4EA7B26B54,D1412B8F896CC5F5,064583E4B4D59CE9,7E651B47A7B407A7,7015FF70C1F265F2,002643339AA920E6,EF127BC173D940A7,EB3E2F7469CF8CB3,31E3957E7F84D69B,A8A9BA9BAF6B4AC4,5EC97B707FC3DDBE,4AD15BA591FB892B,482B08F2DF1B756E,0019DF99319BC129,C8172326F3491CD6,52930BB820E78493,8B0038D89A0EB1EA,5A020D57D0CC62FA,DE2B8CDEAF280463,FE9CAC8EF3127068,F91069FC2CAE71CB,002B3986FC4F1394,B3ED8CF237A39315,47B04264DA66466A,1630C964D307B36A,C8EE02806532B371,95F3C489BB519B1C,A2460BEBE3C680CE,53895026258E6836,002F198CB69F51F1,47018574647673D6,1483E00852D5F2D3,B47D96B22572CD53,873BAD5E0AB90379,56BA133F91D24DF4,FE113882C1D85A41,D7F2842D5EF56E8D,000D0900181A7C11,6275D3FFC23D9CCD,F5669C1E670EEBA5,DCB9F0DE83569AB8,6C9310E39B7BA72C,DFB280D8305BA625,00DEE0D20F39EE3D,9717B143A8066C48,000CD1D41CAE0473,6CD79CA56FFC213E,3D29686CD7BA4845,EF2B0FBEC57F4178,8725522DFE92D49B,119A7D5A7E2D2BA0,BA07BBF43C9051FA,273F57CE9F064A0D,002ED9EF9866E98D,10CA791633FDF14E,51F12F543D804262,8D6FDA33A756D755,D59A984A1080E7D2,3E12A219272B4FEF,8E7A2FA82BD11C50,17D98D5ABB1145DF,002745751553309A,D84D01D434A22E04,73798E81DDFFE7F1,41BDD2888F72BBA4,CFBCBD087645184E,F9B8AC2EB3054D14,D870BF19E2FAFF16,B0AB37DAFF08D511,0019312E7C023D7B,31397522C95E6D54,4797B3C3FEC67D98,4FAF12CF3E03A17D,F14591513663E560,817F80CBFB6D9CF5,B66F39DE310B3A85,1B52BF13211A6659,003350F5CBD5C701,291F2583FB04A7A1,9C1E81EF3193AED5,13C82698B8F1E4BC,B4B32AACA4BB9B50,F136F58AD3B55ED1,7A1AB8840E88CCC2,A0A827373A3D3A2D,001D1CD00A7E4CAF,947C230F07E07301,1867108A6274B06C,C056F7927F506061,1D658B0C81DEBDE8,3FF9F1CFE8C73020,54833D9961BABD97,A7AC2F5E60ABA1D5,001215E63E0E5B2C,DF97EDF082E86F6E,7BC7A6424474E2D3,89E4B398D8EEC06E,9D3D1CC1D47EB5BE,C76BC08AF5400645,0031991DCD646B48,65E53D0DD879B23B,000F239EC8C6C2A7,00C535E951FFB4CC,A1D6A61B6124D726,3D2B8876B7D1C854,85EB53E4848D5B8E,0BA61FC77C76BF8E,1D23AE540466AE00,81C352B8F029CBC1,0028B28CB3883FBD,ADB160ADA9251D1A,C4CF52FD6D82B6A1,31FA8C045CB15931,92C11807DAD5CF6C,C0E59F9441D5E67C,880B0F7B9DF35000,56E5EFA5EDF791BA,000FD0B25C85A0DA,513B7C736C47BADC,28EFE9D56FE46C19,E3C9247E13318CBA,FA3E529DB770E89F,4FF8758671657366,E7D4A1F1151F3B45,D4B30D2E8AA93110,002D42AE21483935,6F9146F254DF7336,FFC47421C91D64FC,4DA28159C5F39A52,75445FFB58F9AA0B,C571049D312C3B2D,805913646A362EED,16559A89C75FB6AC,0010F463E912D546,AB643B5ACF3FD087,FF9B2ADEA7888157,ACCC22B49AFEB447,5DDCD039CA1F339F,C8251D3F24D4C443,F9C0310C714FEF95,85AE6221DEACDD46,003FD79BD84604EB,B14492FDBC8DF1F0,AF11D3EC05267172,1E7CDFE9144D5054,EB5CF1CB85712076,B6DB3949499EECDC,E6CB4261F4F3B051,C07CAF8DFFD2F7CC,0021F238F422B413,457C7115F0838AF6,4C4C1770E8CA040A,403CF759A6104A21,7472E1978FB6B02E,FEEFA04CBB5B4D0B,B32C0ECA7252AE3C,EF7140DBB4073CE7,001DE1CDF3035DC6,7ECCD51E078A9E59,BB1099F06E448284,8BE3D916700CD9C3,3D1D1FC322CCFD0E,4B8952981228A7E1,9628C1F7D306F574,08507B98835A012F,001F3E48B105EC56,2B0BE2AB44914502,7D290C8A70A7E88F,2539136933164827,8266DF3B3DDA0BE3,52D65875C32150E8,175273BA8CF8E157,F63EB07229AE242D,003EAC9955B2482E,668A8AB86C3DB03B,AA379B8FDB78EC54,7C0420CCFF4368A6,40ACDACF8161D2C5,DCDBA7C6122EDA28,5773807BD32D42A7,3827605C4313670E,00111222B06F1CAC,392BF19560A0B9D0,C8BD13BBD84B1650,C2BAEF239E9C02FC,719A465840CF85C2,73BA21420AC6D862,AE2F62B6486CC5A7,EC7DA6EE877FD3B5,000E16E9D7757673,A9099067C41759C9,CD209A5C1CE7D1C5,F58A57231C712A22,BF4228BD14D563AB,0DAA01D99A650BF4,F8F5CC9F2C21D4AB,022F5567F772BA57,001370E63B23ECF1,067642E57345FB7B,A71A13C191361495,E0644A307DF53ADF,205A5ECC872AB40D,712EE262FE9A5B01,8715A7EE8DF29575,23A734C0CDF88B19,002D43E8AED6D30D,F54E019F3B773F08,78127CDD7132926B,B99D8C3EAA94FBC7,952704A97C114B98,9B7491E6F4F037E6,64523A95616A3EC2,0347FFC555933820,001F6DA0C8CAAB9C,2D058314B1ADF2C8,AB53561AB6CCEDB4,E46283A8EBE208E3,1A28331A08F53D67,BE884A7C7B2A197A,C486480EEB9F0B61,734947E4457B18C5,0010BA50EF7AD378,9264D552273DAED1,BA069046A80178E1,42C0E9A102AB63BC,95E0A52E80D37A9D,9450AFD671DD5074,B753B74DE0321011,3504AEEB6BD96B45,003423474CC6E6F7,09007F999027F897,8E5B0A541A0CBE42,CE4EF467B788BD12,C91D7FFD908F1533,AC9498C533075F8A,D8306755963BFD45,B5F9EF334CAB19E4,001B9E78D2DF44E1,F03AA0062E79FAD0,F53115A85B094C48,012B60D87ABEBB80,47D14E2B489EC005,B063352677CE48B1,DBF1C17EE02EFF68,C5A8A727FDC5A818,002BFFBDA81A0188,A0A54FBAF8A49E28,E8E0FCAC57476E5C,F01BA86646DC1AB4,34FDDBB6E56DB28D,A31C86F1564B2FD8,795903155F7DDE2E,F4FDC6F44BB87A82,0016CAFB8532908F,9E1C80B7C548CB65,A3E7BF864B205771,9B7BE3036768029D,9E8F3F73283354BA,9F7ACCEDE4F2A473,2F3A47011651F569,B32535A37189BFCC,0017C17FBDF2F728,087B2203FBAA7F7D,D243B87F1E8B6085,F5713B66BB2CE1DA,23E1AB8AD30BF23F,8E3FAD35C01CE670,6F68944D78D3C537,CDB37F1A000A161F,002CB2932FE49923,B200437BDDDE3539,CDF8949F4EC912C1,29FB48774A3928B8,1CBED14692177C8F,7FCD2DC8BFCBA461,2054A37C6634A25D,4274A9D0FE8B289E,002BD1CBB1134DE5,25A23221BD1279D6,F0D8520190368D58,664F693E3A9D2726,869DD7CC00563100,E2DE80B277F51953,16CA256A2708A6B4,CF5000FE7732E995,003C37DDBC374C60,45173154DB7EFDBF,9BF69F6F54FB713E,3447FB1462521F09,06342F189C55178A,A048544D15B7CEB4,3F29DB91FBFBBD71,55A6EEE17B5E6D64,00091B97F71EC248,422E87540EA88E15,CAD0C6350B61B87E,BADAE7C7A5EDFFA6,49155A48CC0B74C6,586E85D693A366DE,DAA057945EAC182D,AC741CE4A975A73A,0019D4A752A634C6,9213861034521952,C0B2C2EF7006C4A8,8536894A64B3C5C8,F0095B061EC2B0D7,43C09C5DF4B30C9C,928A0E36A4F43EE0,01CCD3E8434DE829,0030F4585AFFDAD5,C0159BFD212D8087,F15B4FE9A5537ECA,134A4C462D99CF5E,82BC290792ABB66F,CCDC54BC8D40B345,F07A69BE17DD14A9,33F64103FB84BD0B,0039C61EDBAB4C0E,18656B1E2277E6B8,91B298224C11E521,7E40790389E3B034,077D6570F19F42E5,9EC2A2D8A2105E7C,E4AF514FA9ECB349,A305CC2E3B9FA049,00256D361533428F,A4BC1E6963E5CFE5,4942E934A10DC70D,F10E7F21E99CFA36,6081B0FEABFDA38C,464BEA0E4973128C,7D911BEC2C4B73C9,F9D718DE1738CDA8,002389C5BF9AE96A,464F18B92EF07E5D,B83CA36F8150F09D,14EB644E75E58F3A,CB8DEBD2C9D30578,0A8DF54DF65C10FE,C7E06814FDF07A5A,828ABAA5B45A8879,002598A35024DDF9,95AC51E29D35A8B6,F6E2FC3D6D73D7BC,E73B17B0FFD32EFD,F59DC9D0E6652235,CA06D4DDE79B0783,BEB696A80E50438A,322FB02A08193B01,001A28872CDA341D,F696C192C0887A8A,654AF1E6812F91AA,C168EBB7C7469C74,C65B754E6744557C,1835BAA5639EF2F3,C2A6E678801CB650,159E575F4C08E1C1,002CA55816BC9A25,AF6CB2EF06461E34,B596A24E2679C76E,75C3A72F4A1C7EFD,B19858E4362D78F7,22E8EAE57CEF6621,0B6300290BF77369,B3D57FF29C5D98C3,00351C499504CCFB,133771B8944B511F,C858805FCEA5E470,38667EC4287D2B75,5F21A34E2A1989E9,D73A62B940F31BDC,60AFAC4ECB5A4AA5,B7B170FD45FEF8A6,0030B5D6178B52D0,5CAFDB07972FABDF,FA69D92233959B83,E66A8C6ABF572C25,F352705883F1C553,37DA29E8672B47BF,77FA05A768E29E7C,81319D24D3FBF989,0013F821D8134867,6AABF483319721AC,BB8951899C3704B2,E6947AAC4CD0B6B3,4A7F8A5A4CC33F9E,FBE7AC73A28B7E37,B6B5436323C44AF3,C16980AFE07CADAA,002C4EA6C55B025F,9227E2A749087232,D8473AAADF1F0069,2AFCE4944DA5C0B9,DAA3712915FC5594,C9973BBA90322AFB,9FEEF1DEBBBA6D20,77631346538D3E1B,0005120E95616261,DEB3DA5235B12F47,B1A01790AE46B7FD,E3F996CA3AA86825,2522098BCD20D198,4996E1037F196893,71767A1B7C5C5328,997E0B9220964520,003803605EDEAF45,5482CD3AEE93DBEC,9BEF115034D1BD7F,6F260E076EA4CED9,24B534DDE0F681D2,53B3B81537F72248,B1B74A1C7519E20B,76575B649BCBF854,003906A6A9D8002E,E7EB4BC2DD2B120A,E8E091832B33D67F,A04AFCBD4D04873D,282A8FD4E845D9E6,22BF2DC0FDDE0233,965193281C576578,DDD25BEE814A592C,002F8AA24883503C,2F2AB0B529798F11,0F5300AFA3B37617,454D8B94787D8DFD,CA517000CE812977,07D34705C75D4D1B,BB6BBEE06D1B1C2B,DE54E7D73AF3AE0E,00086964EEFCE912,6DEC6B9D809C8ACE,8563C70EE1D770B0,7B540380601EDEAA,1A97004C4E4B07E0,6321553FC0FA59FC,655963ED4E2AEFD1,39FB46D6AC01E833,002BF40FCE65E6F2,B07EC1B1B296535F,CB4204041BB430D1,F3BCE0C166BD81AD,C236566E0F43E4C1,82F4929E686A1B6D,ABF2A275B9F5BD87,7049F6CB3817EA2E,003562CCBA33073D,FF5D322AF6164555,E7398CCA4407E757,CF8886434BED3042,BEA2CA762B9BC51F,2AF213CD45E77DCF,4243955E279CDF87,F7CC886FF7917F07,001E6FCE28D785F3,2A7C933FBB1BA7EF,944B07997D9C1D77,F0DF822AC5F72DF4,60C8E6633E3E1160,5C3533C42F80E53E,FBD5BFAB2658C076,BBDD1EA0BB05DBF3,0007057E7F6E1CF6,6BBBBA28C9C6D941,39159EC8D8E9F004,CE49DADD9F06FB14,45A8B7092797D587,48735143B1DFEB7A,FB86FD812F17C86C,EE70509F6E09EF57,0025B8D1A6FD35AD,69B952C47B02B27F,4DB7D8508B7FEDB2,E0FB2C8F3ACEA6F3,0942BD1733D9580C,04E2A7AC88F06668,4567273F1FB74655,E0A7DCDADD6027C7,0031C2A0926B0F17,CE15CD2408C92A1A,058594DA317F38FE,0F1580FE2771C30A,D765BCBD6FF8E071,558B398C846A01B9,2F5ADDE2ACD87498,AB54030E8381F480,0014EC1C709F089A,5347FCA735B4F710,52203F0620F416C3,C038EB8EAA425C4A,6263250616DA741B,40120FC2C6BDC225,4173DB5FD04307F4,9B7B618BC57225D6,0035F28186A07330,BFD0E893356B081E,825124F051299D3E,034EC73A663CCCB6,35BACFFC2547427D,16FB915D637312C9,4E11D74E4CC3E4B0,69306EB2B9BE1833,00193080EFE8B5DD,9FF85FDB7130B4D0,9709916E72B11371,8D8948AFEF7F5D07,2A9AFA75EC298272,E6758E77B2D9AB89,A13BD9721E345319,A830E2250C548C65,00111F6A513F69A8,414C705E25A39274,EF44AECEAA03D4B2,2FABB5583BA685D2,29B4606D0E218A7B,7805394306E3697D,C67CE1B3A01CAF3B,F8D638DF0A93B157,00209FF168FFECF7,40997FD0D8892196,8C7A9F2C86CD6F9D,D666057636AF6EB8,E8291440737EB15E,C76CECB72CB63D17,B8BA4948B37D136F,194A4E956BFF7E40,001AE02F85AE3271,5A438B08D2EEF43C,790C52EA48E84B6C,CF6F4596D01B6272,46FBC80CFE5D088A,79255AF2069077FC,224C8D304017F55D,567DB8CD03108282,000AD734F5476B3B,E843830DD8A5F5F9,FE6559BC8BC47B17,514E32B1031EDB01,45FE90EA877EB0FE,C7339F2B081760C1,79C130FD54E6F735,1A96783C2E37F0B6,002BDD3A74D8B3E7,D3E6FD60D0114C74,4581388F89115662,B51E80BDE4009C4A,35EE446F49EF4604,09EBBE8678DBAB5B,C154AF57041DFE95,96F518CAB0E39A72,002F28EDCAEC905B,8A487100DF973A19,4803AF9C74105D7E,1B534682D296F141,EE90AE120A4A3AFE,94927D5727BFE764,297831360C6C7C7F,C5C44F0C03E9D280,003F00C0C12F53F5,D027E696C1E4E7C7,F0AC565027306465,F170451F5DBF6BAB,5E08B0BC4D5C621C,BCE96139D63CC3E9,9AF13375F0D11B4C,68C6AD4AEB9E2A2B,003FA6FBA42CD8EE,53B9A56C8E25926C,72BBFD85F7D0A7AD,3E0075EF665ADA68,CE15E2768788FB25,95423D1F27042EC1,78314E8A5816AC1A,C7CAA808BF594269,000685B42CBFF91A,546D81282527FD3D,4A2E415CEC1E58D0,FB144E9148FBD8E1,0C031579929C834F,3ED29556CC8D4924,0845F9D9B08C8F7E,1AC9B60FA12DF0E2,0034BF1AC488C540,C3E325665F5C6115,F5152E14B7B9570F,CB1AEF688D031AD0,879B9E5CF7B708CC,24E926D33F8BC7B9,D20F7D95B89CA941,FECF308130991EF2,0020BCED2D4C9C8B,EECEF0D62956C2CA,93FB0B574F4853AB,AEFBB23913F63E0B,27D6CEB96AC95BF9,580F5253DFF664DF,59314AF0EA3ADE30,DCEAA4A81645FFF5,002DC2357C3867F3,40764B2FA0F76E18,3F8F168D9CCEADEB,A19410EF63E3640B,A4EF737A53D81E03,0E5EA395F4C79A6C,A662E8B49F6E7A83,C1E26132AE69E9CC,00248B12BDB89BBB,85B8F69C474AEFF2,4F66BA5B0B79ACC7,90286EABF96C391A,A7959A5C3AE61022,6459CCC668A8F29A,2F1CB00010BFA7ED,18192C9EEF8CB278,00169BBA12E5D763,6AD3E8266617CD16,E6E1CF1BC2DBE391,4F7671D1B736AEB0,6C3F88DA878BBC10,5711DD39E711F2FF,71F7A521177373F8,6334A1F8C50E26BB,0008F5128EBCD733,D8D0064288E027AF,5D5E74C48D079EE4,BDA8CA30063811D7,4B9CA7A0A61C8D8E,3F1B8A4F9430A55D,88BC460AE98C2E56,A6ADE8F69A7918F6,00176525130B5A8B,9681911BD74666EC,F002A8EB5E1E0A4E,F4947C2BEDCD89B8,BD231E0C512047DB,23A30B4CEAB4477C,7E7E0213951E3C98,2048A3AE03AC3091,003D270F5318AA39,8332682F8369F2A9,96A5081BD097D4EC,A16FEB5BE629F520,758E4BC4275C3098,76A9D0B8AF4CD555,86B8A51B1AB53165,11B466BD9EFCB15E,00241714617EA195,785E3AAC66F1FC26,885FB32301E22BC1,CA08C7BED20BB6F5,E69189699FADEB22,E28737663C13775B,C12825719AC8142B,98C910A816085BA5,003230EC8D34C928,EB0D21D824A15240,E2BD4B8F915C3C0A,A8C96549E962FD47,50D0CBF1CEB828AE,B0D110A2F6E14DCB,3DFB58E3EF5ADF68,43158B44C2637F08,001DAAE5C50020AC,DA77C372ADC9E14F,747883BB42DCEBF3,74E5112BD18DFB64,460D776DAF52AAB4,083129D780C7C87D,635E1A4A36CCF7CD,8EB397647BBA3B24,00063714C69598BB,59A82A859C4BABD6,A6C4E14B286B55D3,F76EC7A97FA12052,A88615FC03A21274,F5F562C52C5822BF,552CD1DF69725FC0,420E5CAFF12C430B,003812288E4A2612,CA9642C70D05EE2D,B060A8138336082E,A2CDF9656FDE6123,FAF56F07BF55F512,EF707040F018F79E,F27F8A4E3193EA8F,88A3C2FD4FAA1E6E,002D739D43790C40,57A998E4D5793F1C,78D25970EDE46955,641037C96FBD2C58,883DCBC351BC64F3,7FF3475F20E87EFF,AFE21BDBF85978F9,19D6103430FC59D3,001F94B190CFF83A,AB88F77B26C2FDBA,EDE79AF03617A902,F37EC3626D7A1E1C,4943BD59DD7446ED,9A1ABD23FCD78A6E,F2664C708890D77E,5A60CA9261189FA7,0016FC572AC2BBCE,7B78FBB90D61DB47,952AC14BD66BD522,D215255824BEC0E5,FB284AA1A4B55A8F,F2F2141A493D43E8,A2E6ABEC63EEDFA5,433BB256DE3D8CD8,003500D7313E9E72,23D0403D1D5230E7,937565EA83BD0723,DFDFFE4231E7C192,F7798B297A9E21C7,E1D50352A867D7CB,6E6609A1C80056B4,DE21DFA6C9E52B8D,0001CCABF06B663A,504D8ECC484E6C52,AE488B6821196921,973D8BDCB52C6974,0470C5148D31ED88,D8A5C703DC35385B,8451910D396BA46E,1EF2F3D721093328,0033336983814CAB,ED3D9FD6A65E1FD3,816460A10F72C7F8,D40B324DD4889403,339AD50F87EC1792,8247E7B8010265C8,DF760FE9114DBCDB,2C3EE24DC644B770,00267BB338CA27A1,187A2D7EB1EB2B2E,2B0A22A8BA80B6B7,3CAB5F0AF87EAE97,307289036F31A7B5,DB1561AB3B276D50,A034F6F0370079D4,933A481579C04EA1,00399044BEC2D3D6,E35CC12D0B552784,1C5DB64AB7F24E35,2E8BCCC9A97BAAB8,36E224E3B3502B27,5BEE9495A7A16159,373D1C510D6DDFF4,8CFB88F9C15001BF,002FFC2E04B15132,B8A3E62EAAAB9A7F,0BFF4EB73F5568C0,A9C6057479E419D1,45EA0E2706F8039D,24164353292B4697,DBFBF0BCA03D1DA2,B14CA5C69BB36E1F,003438D737890EAA,1617D22C9CCF5E0D,5EA151211F04BC7E,B350EB6F06A72797,07C8107E6A57588D,AD02DC5A58C9F5F6,A56B221AB4CD1B89,39C7D78DD2897186,00127620AF5B9765,463227B27E6547DF,1D048C82FA7587FB,F352849D4A5B0BB2,D691D27D7E8740F9,5CF2E9BF2D4DFC51,2F763D3C8C3C245B,3C1735A13D62E1CB,0014A7C6AC9BA41C,343294BB2120B4B2,23FCC7F3B23C7FE7,2635097767D9A840,18C2B10F32E48092,7273D85D535BEDA3,34E12FAF1D0345DD,5DAE9A236624003E,0012D37E3617D8F6,98978E55CB6DEE68,1D8435F7F16A6F2D,45EA8A4B718F1957,36CFEC299C2AC5F5,07549EDBA7473574,9B2B53F56BB1224E,4C8151E5ECF6C095,0020DCA79F9E15F9,97BAD82028586DCC,EE5198BC272F06A7,BBAF6DBCC4EED809,1C1F8AFF16C74B8B,6BC90FDFE7635DB8,94EBAD449928C520,F6FA00E24FBE0557,0029E3913615C01B,FD2C38F2F0CA3F23,F4393A980D3A9266,1452B9274BA73AB3,2EE2FEC2103705AE,33731C7FB8043FA6,4A870812ABA7C7F7,9A9B9E10ABCD8F77,0031F51615F1D4B2,EF453B74AA481493,76CBD52CB9DFA215,012231C10CF8250E,EC8BC64E5DA5B222,6542BD0979A7DEE5,7E02D5835C65482D,5987732FBE5DEA89,000D6BF844F7FAAA,C83DC96FD5E1D707,E5DE5513E1909B0B,B99124B36B2D67C0,4328AED8F419B1BC,9EFDE131C82345DD,EAEDC37337917C68,9CC24BCDA130F5B6,001FF89BC650D8DB,C667BFC57F3E7413,DD99A616321E2AAC,772FBA2D1E4DA5D8,5DD9C4765D780CF3,69FC833B2BF321B3,D67C24AAB278BF23,288855AC736926BC,002C619972C8511E,523F3B17CDEC2F61,1E6EC3220229AEA1,EFE76C67BA201EE0,B1B7EFEB18240BB7,4CD317EF18DE43E4,6DA0ABACE4D8578D,BCDE06656C3684B0,00375C9397A30CA5,2DEAE115B7B0EAE3,1C4F29A846337EFF,5DF9F4B6F849ADDB,F9466E0D36BF5EA4,E4D75E0BAB97AAF1,A301839E037D221A,DDED265FC9E00427,002E2422F02CF2C2,2E55CBD206C84609,A332D896A91B35D0,CC8E0C83BB8FB1F1,08A610E2287996EB,4961A3E91A9A626D,E3EA66E5B90170BF,9C2D4371697253F0,0034D934B1F8E26F,74C4E6E16949E354,3A08B2ECF5B5FF33,C0646B3960368996,CE83C3D589D1BC18,1313CD90D2CB1D65,4CB60CD0561A4443,CF36B25D8622E4FE,0006D320A965A55C,9E3798D22EFF50C4,2A4742C863615666,E53B960AB6CE57B1,2B63090A6967790D,28F31D9C521225F7,8C4C6EBB01EB229B,58EFA3E5877E984C,001AD09C84055E5F,DD24CD8CBCC26188,708450105271489F,3F5B02D308D07A8F,0B048EA39A397C38,B0FCBE0D305AB971,8893639ACB2B5DBB,B412057ABDCB1755,0029ACFA1BFE8DB6,83C0F55848B571E9,CDCF75CCC23B338F,683973C0772F6037,F749EA89FF867493,C3E2E0AC1BCECF79,D4D55BA8C8C88137,7D7A7E6935CAA8A8,0011AD18E4129EBD,1B3F96ECD7699ABF,EA09985233FC6794,0BA234B03E3A477D,631DEF536C54AEEF,83332DCEF62784C9,3B3E58610FF1275B,8B41F610F86BBBF0,003598E38BE1EC13,167002F45AEB955B,72E4581CB51D2C14,ADEC53676AAB4AB7,0EFEDF179FF90205,BFF6480621E7AB17,C13AD050C82D255B,A8015AF0F4CD1984,003777F6D027BA55,78DDB8BBF8653756,3D844C4231F6FAAF,37925855ACD42394,5B71FE00A631A416,945AF86FFEFD3105,88ACE64BA0730378,74A831003F7A9D34,000F33B833133BC3,CAC1C4F476C59011,04B21DEAC5304DBB,EBACFDD60143DA10,A0E5CAF90CADEBD4,6B772DB85723176B,BBEDA6D0AACCCFA4,33F7A4342FB150AD,0023B36357B901ED,B459E7D41B8D5627,5309D80BF2663699,744089E66B0A2007,51B5D61BA0CD86A6,1FBB59A786090ED0,05ADC116E056D884,67FD72644FC479C8,001D2388AE014F61,4E183529639292F8,9CAC5EA013EAB40B,77C8C4B8DEA77FE7,9C4B69610FF0558D,33E587D2A37FD29A,E07BFD2C6022C7AB,9D6BDEE9D6F49A48,0035D68D1E855408,458A3D98D32B63D8,0A838410B982E7F1,0DE2841B43633D8A,F123A7F3A06661B5,6B52ABA90B7FB4D0,BDB8E375C035DB48,28B4369BFF59D684,001ADFF8C4339EE6,57F426EA14F4234D,C9F946CA0AB90EB3,D1130798EB165F75,0C0C906AA2FC8175,3D9CC17D594AEA72,5A00BCE35E76C569,4C2CF3785A8D23A9,002128ADDB4D3C25,27DE51FB2A06C4B3,5EFD3301BDEFFF9F,4B93439AD560C0E5,926F2C2A40883C7E,38F7B4E3BA249D85,66C2E4C31348C994,E093CFEBF89A2F4D,0020A09F27DFDC1B,55AD51885A7EF5F8,45DBB03C6B66C141,80A432BD2621E1E1,BDC898DD7741C3AE,A12E96D26CE37CD7,A6546152514D1753,856263A987C0C0F1,00156AB5FF5FC544,259983A4D37A984D,A153684E850D4358,37B032160EBC4076,A28B06F5BBD894F1,6507E0DE0BFD6658,D53133072959FA48,071D9D66BFC43FA2,00047A716095DBF9,70A50009D5659210,9B02A28B6FC397BE,A2DB2DA4EE22EFAD,8FCE4B0EDD8D152C,6335FEB6C0ED304D,6844F3B2A7BD16DF,4E4AA5FAF34F9B2B,0029AEF4159D8463,F8079D36464681B1,048C04553626253F,AA791F4A6DEE0BCD,03ADA02CEA507B80,49639116D89802A9,D6768C7D13DC48E8,CF6B8C7004D85C95,002443CC10FE6A0D,A8D7BDE61721ED3C,E1C332C3B9D6ADB8,E0E5332534A203F4,00226F21D5ED9621,A9C35F71B2EC4422,637441F88F64168F,A1091EBBC38C6E46,0029C141FE7A26B9,B82F2DBD897333EE,DCC638C156780F66,7EB98553D3794834,EB81482E59EB9C2B,FB4E8C6AC66AE2C4,AFE7E9D32E2334AA,4F0FFEA852F7C7B1,00073A86D890323C,B3FFBB4736FA007E,269373A1B4C7A5CC,1E327EED97B6C9C8,C2DEFDD6AC9E8F32,BF285D47E33133F2,A9C6F4ECE708CC01,0AE7CEC9D7C7D3AC,003B8FBF31668F22,7319A714F265C370,5FCE44DEBD62864B,51FCE4CCBC2356A5,7FEFB2F2F5DAB9B9,88F7D6A4EC75909D,16115711944ED60A,609F5050369D9525,003E3DC328CDADCB,5FACE985DE6636E7,621B2B8CD8E1FBD6,38D60ACB3DDB6852,2AEB6C37FA779FF4,67A841564A808945,AA5808F45F7AAA7A,E2859AC2E763E63B,00110F7E96C1A71E,B2682FEF4F3CC3A6,3EC19E0A1578CED4,048C3D6053E04563,55565E9349ACB88A,8CD6E65D72F4F8F0,1BFD16AEEBCF0F90,9964863263B429CA,003637E592916093,5F1967B4111AECE8,C55248BAF1674948,C67B69C209830EB8,3CA2D031BB9F9E3C,BEF4506EDE520DCF,4A09029AC6BCF883,A0AB3962EBA9B3CF,002ABA11E8D3E329,6A0E8277E0FCE606,5E839D7204F9C4A9,3D70EEEB8FAA7C45,CBFD3ECC3C3899A4,7D86B8F18BAB2051,0B94E1BAB194F8FD,CA4BD164D7D60592,001C66F1F7A00531,5F1E60C05370BA3C,856F31E1D7270201,01D32F6A78A10BEA,D6CBD4E1C79EC9AA,58333339D657D635,6699963180112E3D,D9321E86935FF66E,0008F807608C0EDD,25DF614B42B2D188,9CD9701C4EA11FD8,D5828D75BEE68408,A8894EFD4B3CB895,095CAFB5D974BC03,EE4793F6C890C69F,C25B0CB0BBD4591F,0002EEFF9D4040D7,804AC4EB3FDFC18E,1E1631E002DBAB5D,5A6F1A46F9FC43E8,E8588E289FB40C45,320EF031BF35C9D7,59D9590B3F6E049C,3C58A7F6ADC5CD40,00166F9F12CD08FD,3C46F6BA05079838,75F5A8E61C25FAE4,521F8B89BD6A5BB8,B78DF922DD5E61A2,F425E1BA7BAA0E37,A21DDBD60E1DA995,A6C4CEF171F50D8F,000785C0B1CF9A87,4B2101F16052649F,8884B18A63767CCA,46EE29FAE4FE7859,63C4BDBC9B08DF7A,4743ADF1BD61A971,EC47A698A68C224B,912914B0C8FA339B,00022A36F6877373,7B7A76C39D8E2302,38BE719C00C8020D,B1E7888A6D95EC0A,1BA23A449AF34150,B3D1E419F3849CD1,5A372AC73388A7C5,F9F76424CAD3D353,00156E3635050DFB,C0D8AD7B16C65F7C,4206EBE54DDD8F74,92920686F3788C30,7636AB0BD81C08A8,AAC359F9311DBB6F,278935545A75281C,69D1FA9E425592B2,003586B457CF47EF,B10BCFC84E6F1999,1364EF77044F3A65,7880A0B8A0301FB3,952F70050F169453,E08237BE978600FE,CBA64CED62CC30EF,9B8C7F74CBF20664,0038160CCFCEBB46,DE8BAB8031491529,17329AE4D8E13FD2,C4D6E194AFBCE4ED,1E589395B04DFE86,96D44D7EAFF398F3,85E3A9EDB50C3ACA,5FDB077060841F58,000ABBE6C02ED99D,2A0806982F23AE77,02C0EEF507AEB18F,F53AD23505AB7B25,D029BA45B6CA832D,0E236BCCC038CB5F,22523BA3EB69CC1B,0D26C8A7A72A8690,0024E52F10C6FA14,E6299F922D447564,C579E826E699C6A8,8257879C54417F57,AF1817C78394BF24,5477DA8C85158334,33FC13E1B99B5874,6118A138FE3A2F80,002247F34BA489D3,74CA3DBC89439024,086D287AD60B541D,FBB49C0753874738,551F5839A25B4C5C,F3C1AF9B43C94065,F1D558AD7A0F921F,D5049D9EED8FFE1A,001E530DCC835DE5,0D0E8EF68C705D14,A6DBBB83BD0CEBBF,D6D6C0655BE6388C,555C5BF1A8962399,4ABBA45C8F9147EE,30364A2E619B87FD,83652C0AF5BEA2C5,003A7A0CB30E4E49,3E5B446B17FE1AE8,F5E4BF14C76AFBC1,B4E93CF6E26BBDE7,429238E07DCC8581,EB4C1FE51EBEC4E9,9550A4F037E02339,2A732543617F4432,0039AE7DADC580CE,BF7CA64B337114CE,EB7778AFD94739CD,E77CE7C37FD9CEB0,65442585B2ECA7B9,6C682954559A7938,AF4A3BF79E67B288,29E4101862445B33,003584F804E59E70,80001B3F64C916A8,D153584E5161BEB3,533534D2DF127AC5,A668754826C86E07,E13E2C7F8A87DAF7,06F124478F2848F9,79EA1E844D40A447,000866D1CC7E84E3,9FDA8190E8A871D4,B267EB52893C0D96,71FE8D8762150B3B,544C73D410570784,8CB6BEFE81C5C0AB,D8D401D9775009C4,F057A095749DC4CF,002C00B0F0026D7E,32B4E9B4BAD0D363,DA9C670DC2B16573,1CE1968EC5C94BB2,44108222A3F6D620,2864252370F5AA69,3F4AE00D53FFDF40,6D51120D9D0089AC,000D7DFF8DFE02AE,7A17A2E73A936FE8,104334F85647411C,CF6A90DF2F4F5A63,C8B8AC6BD96E5FCB,6B72EF348EEC4FE3,90565DF3C5B7B114,E8FAAC9428C1ED16,002D5CCE44177E53,90DDF310113D0C17,BF8A76BC7ED0034E,2C9316E6F1C21292,FCB661BA4E3CFAD9,ABF3F2E2C5490261,22F4B218DA01AF4B,F21019D2DD882AD6,00186029E5C8412B,B1C85ECCA083486C,567F4E6CFB7346EC,466A444C27990320,BA74109422332CC9,1BFAC7C2E68BBC29,CFB070E4C6115A8E,FE0A515DFC7832EA,003D4F352F89FE34,D82612903771A5B8,C235014774D2C3EF,4A3553AC7F384349,F9A9E196ECD9BFC8,AC4DB72CC5C8C623,128B0155AF538C33,D579CE36D5395352,00199948B1B0215C,6A4A65F3A490A618,E359D4766F34E4E3,6A0A7F83F80CBB08,19B3D9CC2E39D68D,43F16323354ABF3F,AFEB65CE644AB47F,8A533AF56F068D83,003EAA1F0D55C2EB,2BC5158988F64224,200EF83967C91274,2739E99F8EB889F1,72AC63DDBDABB4A5,38BA2D9BF86CA69B,07461FDEABF1796E,E4FC0C1C4A6F2010,001CC9C4E03B46E3,C290622E399326EA,60AF2EC206BB828F,40FF4999C689A908,C95C9D133E08CE34,70BF73614AC72150,04ADEBEFCCB77DD1,B3EF7D6E0C0C147D,001196BA061D6298,7E6280BA027A5C51,850C067BA907032C,ED96F7B7BA9856E1,125FB2A22F0927C4,D140D87A2752325E,326FE5CDA7A1D09E,7899E9CCBB4AEFF9,000E051F2C6B72F3,4CEE586FCE20F669,289E06D4E8295DA2,BA0744573458524E,FE380B7DEC54D90A,64D5D5AB0FDC3027,1A83455E7ACDBFB5,F5BEFB72381AAB6F,000979A927DE48BA,2A6B0A268BA5F61D,1390AE29CD97D49C,3F0F61FC0863DBF8,F8785A823D6452BB,DA65A8DEAA8BFB5B,2416F4B1C9167717,2376BA30E5E3FAE8,004015863C817E72,8D729540251D2F78,49C6D68FE48643CE,C4E27AFD52D67C9F,9961CC78B00D1C41,EF33DCC2EE84A883,9FE49ACFBFDE5F0F,7B9496B807A348F8,002771DDA67618DB,B02464D932AB94A5,FA745D755D639E54,E254533D5BF2AFC5,D3A09A89FFE5D92B,8D4A00CD9D528358,CFEBBF04F13887B4,A29AD7EF3054B273,00079E87348C343F,BC35D3C102025F7F,04CBF1CE8C10FCCB,A49710AE8E6302E8,95B865EDE373D45E,DEFB6D16F7C2E547,3891C246B1D989B9,9860967D9B78A8D3,001B7DAEAF0DEA10,F20F197F1B3B06A2,25952F6CAAE6B8D0,8BDE5A319E975051,AABB3152FEB9460C,1BA34A1FC7A6CD5D,6D39DC9D3F544DE2,A11D3FAC278F3C86,002E58D0AC9FC9DA,C792BAD2B3775D2F,2A61B38FD8B80C4B,73CF5D8224DC5A70,F86AD6C63C73FBAB,C00295F5A2E9EEDD,0E4FE9BCB836E904,0960466A92FA60D4,001CCBA6BCAE95B8,94B439868BC1F786,2D413AE44B7584ED,3173EDF6DC2AC47D,2A067F32BF1A9AC6,60678A1BE4CB8106,43CF218F2EAF6C60,9F47BB6CAB2462B2,003861822ED50BC7,13F78042954F10D3,FD49D9A53FE60ACA,6392AC5B3BD8BE48,58793C9E9D64F204,148EE345F7590355,CD0F7AFFA20D706A,EDBAA5D8C90ECB51,001BFA461A39251C,BB9919BE83284909,21633A09ACF9104B,E72EB47DEBFEFCB2,81B80586F943AAC5,E7DCD74A059DE3B6,2DC34A2E8FA74E9C,95A102F05E8499F8,00362A06C25178B7,1001355E4953F534,D186F072F845B11A,853EEC477530C9D4,37DBC5C94F9AA3D9,21AA0E5CE8505FD8,4B6BA31C5D561BC0,BE8809B36E371C7D,000BA8ED6079B716,2CF3D91FBB43EDB2,E7B9E358AAEC1CFD,C6B11C9B2C6E22E1,F9887032F6717DA6,EBF32768940B97A9,D994B90FA41C225A,A736DD910B690BA6,00108452F6A3AD15,89D112839E7AFBAF,F8375E9646A8B02C,68ABE7B848F8362C,5B95838A8E9F3C28,AE6DDAF542254CB8,6427663607502FF0,8783EB7DE0E445AB,0002E0641C2DB90A,36AE10D1B4C27817,02CB2284746675E2,435D6AF35CE40D40,B4ABC45061327BCB,EFBDFA1A4CAB06C5,6D3E1B3981454656,9CFFEB1C0AA50B21,0022416B9E06EBD6,A15327F2FD25AD35,1726E304A5658D3B,B9F73C5D2E10B23A,A399CDD9EB63D897,07E208B7C05CC7D6,8852B5EDBBDF4902,415AF9FA66D5F174,0010C8EA48EE0960,E277842DE0657817,FF55BFB5FE88F8A9,51DB266618112B8B,39276371E4958655,4D35D216204A89CE,07C3AB99749672F4,F0400B155E076825,0024CABFA13511E1,7885EA6A94CE32E9,A27C8928346EF815,B195B78F95643DA7,483DBBDD19D1D1C9,2549AF4517798EEB,E772D9B75E5B4429,D2BE029F50FC8B5A,000813FD7BA6DAA4,C6383101CEE9CFBC,59CC0A10831D5DC6,CE88ED45790283BA,19E510143DCD2E86,9BBA19AF59682E9D,B614474FFE2462DE,CFD37D344F7950E4,003A68F5D3667839,8D87D89A9603F49E,5F8339F41955815D,21895CB6927A5DF9,76F92D78B2A6783B,BF61E5A1173212CA,F8A0F47DDD8C185A,2B0E8E5602C39222,001C770ED1C87D13,E0E507E4DC2B5811,AE8286687E74B6A8,03D712624E086567,0502C351D30DAE69,EB0BD48D326EE2C0,34F46272AA601095,B80B05E84607390E,000B79D3E26DE1B7,63CD9EB5EEF1C3A4,F64614AB26EC1AE1,45285D8EA1047D67,3F1651E614769318,C7244525EF52A932,2523295006477E7B,61C011AA649C62F3,001EF23F696F1E47,F7DE7EF81C8B3DAF,5155B5688F337445,5E942658BB9036F9,D38B8D7531CACA21,42455B52B755421D,9409E2416681F960,4CD19393A05FB7FB,001E0287BFE7A484,A66D32C20E45CFB2,3DC2BDA789F6490C,0CA3A191674ADBF4,46C6C945FBFFA7AB,32994E37B166F6C2,EC2E5F408BF86E95,37B7F967975C60AE,001A9450E4DE9550,3B86551D85A25E45,1A5C47E869906C54,9C275D7B6BAB582A,5F9DD7F59AA4274F,49EF2A0AAAAC33DE,C940BE99DA7D4093,479434C439583C8B,00003A03BEC9AE3D,CF57CBFD78EDF6E1,FF39C4057788729B,CC51B55AF6699C7B,BA8DACDDD0EE98FD,9E5BE97E8932EF6B,378A972E65360728,321D4053850216B6,0025FAD6083FBD85,F92AA73799E93C20,500C3B714B2A1E87,CC3044A79AF0D3A2,85BD50B55EB965A9,BAF3983A7509C05F,ADE096C528F9DF74,848E9AC6AEC71F46,001B76C5AF5FE0EC,EFF5E7A84F653457,663BFC2AA30C2DF3,12427E7E33B75648,4C3A1EA1A971A7A8,D96B1BDD0032FF4B,3EB4ED83CF5C6E6D,C927734F41AC9236,00393BB2B5954C52,91025A370ABB5FA2,AE3C53EABF6038DE,1F5EC808EBA39483,8D9A1BD40BA33D81,FB9F7CF4BB39CBE9,DDD578A25EF8F6C9,82163DDD4529505F,000A8F60A583DC1D,6D67235762EF871A,F6696D43E7B917B2,060E23D8F58D28A9,206BEC78B6B8C48D,F2750E08D9DE0E77,4517AD72F94EEA13,13E5954DD8C916AF,0025805B0B808F48,60097FAE9CE1E71B,238CB06F7EF911B3,C255C6574AF0630F,FF2B2903E7273C93,009011FE58F4EC7E,FE7B254359C8B8AC,44F2288FD7CEDA8F,0000421197C44CB0,238B8DE25BCF09D6,846125EDFF6143C9,88629296AAFAADB1,C2702753A987987A,063328D6365C5203,DB957320C8DE7E50,1DF2AA6D6FE894F4,00032E71634A9BA4,15A98F5C8BD22075,0FB5AB98A2E9B655,D7435433CC2A3520,91CE358B55AAFA48,5D075D2118445439,532778113187A9F0,7F985538202C48A8,003CE12745F60C90,13AA51FE613B91C1,0B1FCF54CA0B24E8,F10B13D9EBF68465,4C4C7671C57472F9,E9B6819D84E15AB2,6E03BFFABF7DD38E,A97799D05340F8F1,003C8E398ECF4B0A,ADC6750AFC4C5509,E912FDB389064760,52674274D22448E4,9BF64AAC969A8E37,F73A314C9F9E33FC,9911AB80D937B953,CEF5248F53B118D1,0037329891617416,292EF4253211BB98,9E0985C1B17ABE78,BE555DAC489B3BA1,42874CC033F5901B,838EC7EE01595E9C,689749843AA1079A,16222FBF56710B8E,000DDE18AB90E638,A3B35F1E77D5F27C,7587671B02F116B0,1A252558A65660CF,95CE7C0EB5AFC3AB,0215AF448DFECF9E,3ED1090B49484929,8DA4EF46A1EF8E11,002D27FB56AE2F88,F393B94C3E6A7D61,649BD9C258FC85A8,B14820C46E5073E1,F05F9C24005175CF,04ECE1382B3B56F6,0A1BEDE1ED884196,623648C74D88732B,00147772CF25B648,2DF10D2E2774CAD6,CC5DE86F564733FB,3B3C38EC1BBDD349,3D3074C98FB8776B,9FFE2F3BEEB99F12,510A48B06B60A51E,13C58AD3A8FE88FC,000032A5FD0DB305,0578EBBC62405E59,CCF7D1740817F589,C623D407874405EE,FE70553C19FEFB19,83202DF0E4A7A20E,6CEE0DDD34A2CABC,81E3A525E7C942E2,0016F722AAA4E726,70CD8F5D95736080,4B5BA8B1A618ABC3,B49665BE7B03A8B8,E83BE38675AA1443,5B860EA40C0BFB93,6012C4D3CC0B44C1,1D37F0D4DA3DD712,0008C73D46C41F2E,3D6BE0D646946EE4,BD0C4D5D4AC21FFD,5B27A993658F32E1,601F4026D470E724,62BB320F6C722469,47C91EFE3BFF442F,E9227389A7BB64ED,000A318F8B03F575,CEEB8AA00211A353,AEFDB3B2398D063E,89BA31D443CE3372,76626EB6E2A442DB,339073C5B32810BD,9D22005FB67FB89E,ABEE949C1E7D9416,00022A35EA90AA0A,9CE2238268CFDF45,52683E8EDB6B53E0,57FEA90E2327710F,81423EE079F16590,887547A6F38F8A8E,41BD181A06AEC942,821A4CBEB61EBCE6,001D5936D15FB623,714A8F0CB0D9BE1E,523E49DBD5C931CA,530AD1E3C020CF45,F8FE13A463F366C9,53CD4B65E44513F2,BCD3D1AEE732E48D,D70137605F63BC9E,0036177605E3C97C,8C5EF255947626DF,95979367F6CFA24C,6BB54E983F980C51,E114B67A4B50A21D,CC679645AB852E38,491CFE2DC5EA167D,16946A9F591257F5,0016C17A7C250CFE,D6E1621656B9B9C0,58F416BF30823BA1,606D7E87ECB9CC1B,A846D4C9EF9AEA01,098F0B454367528B,C8E91DBF7EFFEA13,1513E612443A4FC4,002D5A8CF89D002D,0EF17C6EBF86B5B4,8B689C263425E798,96F9707A325EC81D,C9C5CBF5BFEBD153,E21E8008518DCCF6,00EEB7FB934F04F3,80B29E607E76B869,003EB6702F8DB462,C390F414325562B7,97FF31F875FD2EA5,EBCB7F1CCCBC1D6A,3D5F088E0A648DAA,26977D746C8ED6FD,BEB064D43BF89663,AB09EB6C35D967D2,002279E4C3E50107,4FD741D5999C303F,F8FE81EB520A9D2A,5C072D9F1799139B,E33FC6EA7D540C3E,1CEBF797BFE3D4BF,C6069FC5D6D4B851,1001096CD46A3788,000FB6BA6F642E27,05B2C4E7A7A9BBFC,6EF797290D0D7615,DA6DB5FE277011B7,38D3F51BD4D62F78,7E556768FDE52B74,94988EA04D12DD8F,EB790EB60049E885,0007D2000E504273,CBB0BA145D37F82E,25CED5A695583C43,495CE00F2883CFB7,03D7FD3C006A83B5,4150772CFD929D30,4E57EFD863CDC371,E73E2714C06CBC0F,001C4757B301C824,FB26FEE0D72F78EB,5C5E438C23DF142E,5B5C68BEFE7DC8B6,2D9755E4E724015D,BFE4D721C3FD10D5,EE0D003A0D665968,F1171EA499569415,001770FC20008314,DDA73220CEC97F81,56977AD7DD29EDEA,24083A3F76A8180E,A08595BD0893D019,32DC1EB9DDCEE7FC,38DCDFE4DE07416A,C7EBCD6AB1D45037,0009AA6197D4AEA3,9B343AF68606236E,90A7522E97B05626,E19792C973F47B4D,3C68CB513A4BFD8F,DBBA19E3DBEAA0BE,6E66CA5D589D0D04,E0AA3EE1D1ED7D7F,003763E76141F277,2DA2C627C72A892E,12AFCB93E0E42DA5,1426AB1C4F26B006,B6E3DB198386AE28,EE4823CB897C94F9,25C315B586CFDCD2,52842F19BCA33FDE,0032D779072EF195,2D69F6B33B2965BF,A63AD42EA4EA03AE,AE5F87673C9BFF8E,2780409DF4AF30BD,C8EF2BA617D7EC90,D1FB1B103F50CE9D,92B0409F98C8131E,00318F4574A481C7,40CC77DFECBBC1AF,9750D431B02BDE8F,33C526BCE01DCE21,7CA2E7917F227656,B9A4A66F41D9E199,491EF013AE7C7F9D,24FBD07ADE3E6436,001B41B643FF8851,CADBF79CF76F3C8C,2513EC69AAF93C9A,98C8D0F567B5402A,73018239E16E6B59,069BB02D860B350E,6814CF6D137FE97A,F0001DA593475031,002F846BCE824862,A40E4E26CE709913,0E47D5B3BC800804,C854256BC293F3E2,6F1C993115614035,B67F976F2B5E5522,4385078460AFF90F,18C060B6537057F2,003CDC11214FADB5,3AF71A9A48200FD7,C23FD3139DEDEA03,C1C57838F0070F21,D950290CCC1EB3B8,2AE263D6CAF27360,041D7B6481B4A0AB,B9FB5C27969CB3A9,0027B231C7076B59,4B577EEB7D0A28FF,0EB6D3182341019B,5CC5377F90DC5EB2,3F0ECDD5EFE0C608,2AD68A83D019CD50,476A234D5C8BF91B,DE5B6DAF152C3B52,001D89CE4E714117,0728A8CA14D92A00,DD69952FF22273B6,CDA5BF1E4D52D117,F655342EF42EFC21,36703B4D410123F5,FE5E4DBBAA7A34E0,C9608E52D6A2BEA2,001353D65A34F6C8,F139D0A458695F12,EDD92CC6CB929736,CE54C2A2D8328633,A57723BC39947ACC,9EE2678EC6765A64,23139316BEF31AB2,A4B1AE3D34FFD0F0,0021165E8776A51E,D53E884284441E2E,DDF493EE390AB485,A5807E37B88D4B0E,91F6CA6100E6F6A3,F82EB7D3344714B8,A7A9E92DBA9A389D,DE83B06058AE1D3D,001B38B5D86A5BC6,CE81CE89B3615907,287E8BD4B206203A,9D9883E761BCE52C,A01D02AB9773BFD4,3A5F5DB22453935F,C17FEF17FE22B0FB,F516B6B48951503C,002D1B0A48B34F7B,C8C3CEDC285238C9,4877A5399A6CF267,72F0D1D135647736,839F5130102113C7,37D8FF73021664F7,33BC06B020AAB53E,5DCE04EAEC74B3B3,003F9EEE1E9E7953,603528FCBBE5B02D,2AB8E5367BBCEDCB,DAC10D35816DDAF4,DC259528CC2B5381,64294D6AE854AD70,4685C102AD690F65,4F0C8EC8062B65E7,003BE663BBEFEAB1,76F24C59BAE4A063,AE1DCAC2D8683338,AEA1231DE6C61AAC,C6649593DDF4EB94,CF30E5B41775865C,331E05F9ADAAD159,DD07DC853EB61C85,004056A6F1B9ACA6,0A1CFC42C3CEB7DB,F3E381894C9D3A32,9B236FB119070620,188A5B19FDFD0DF1,32E51E0EC1B10DB9,0A6181130CD9444E,9189E5A01540967B,000E74588143CE86,4C873FED7A4BB723,ED4327FA8A90FD17,4C65446EADC44DA4,2B96FB81E98547AE,BBF6DBABB3026ADE,EE99B80848552DBA,D592C823B40B63A6,003494D2C2DAA511,34CD8C0F66723747,D7B4CDB122944F7F,22EB07B49C9116AA,FA1F14118417EC04,B16EC4A374C4F146,6FF121EB4C7D0C9C,3F8DABA08C560F48,002EEA5483FA0DFC,EF9EEDBE29689983,FE5EDF7905774AE2,17F36975D6589C85,1BDBEE2222247086,8C807522B28F97F2,ED98E1B4515CF6EE,45934CD5CC53464F,0036485C5711E985,3F6D060AD352E012,BACC0CD4C8DEA150,9603126EB33ED3BC,7E72A5902EE7DE69,D8C0ADE2B139C4A2,53FB286955F21F34,F200AF7A99F9FD40,0017E087B0B65EF6,615A088F02815A79,F27CF480B4AE56BE,ED9CF68BEE95CBA6,3CE299259EF090AC,8B733B4332D03E29,1DDF5E9EAA24C177,6CE60A53B55DC9E2,0005AE00A2D71669,863507D25BE0051E,17A608C3E86F1E23,7895AAD626D46469,24330A36A5BCDAE3,91FD8380E3B2DD55,B1572C421EED98BC,192BB2D097E63D75,0031A048BAB3A35D,FC003CE9186F331F,1428775B187FF1B2,638F134C0CB9D230,DAFA2DBA823E7352,289FC235EDEA0B98,0D0CA918051AB6EF,1E841F2A79ED6667,0017247277B44B42,84C952E8CC397303,362EBE2BAF28A6FF,806C8BD27C1BC19E,4E3C7F90D8F6534D,F257783461349D03,2AC68E66F3C1E228,D20C10F43CD2603B,0007E2998D8CC7A0,866A88A2DF750C18,61B5FBD3EA8EFA49,7FB3EA2AF4808A72,3EAFD80CC55B1CF0,A67F0643AB60C2F8,A02EB28824187C3A,3DC3EB5089F5831C,001E770B7CC69683,A2960F3AEE79EE40,DDE9F52C9E323CAF,1BDE7FBC11BAB917,D553BC8B51723BE4,5227CBAEB12AFDE7,E6ACDDF86A41212A,4339C3A480EE8CC1,0021C63D44197954,72A0C3BF701174E8,744AC6967D5108AA,E18FC09C8A8FB43A,985CF363CF769726,DA2492D6781E0D7E,09CA5E6739FC6C28,6318C4BA813E61EA,003E0FD8CAB862AE,3D3C87FAA90301B2,C82BDEEFFC95F610,2ACE0D4BF5B81035,FEE280D56DD310AB,F914AE976BB54268,DFAFF4CE977488D8,D3B9F8086BCC23DA,003F806219FE83A4,A839C411305B7A3E,1C99A171EE29DEB8,AAF20510C16285C5,2E9B5B2BB240F846,1EBF46516A442B1F,341D6A8275F2BF17,EA9D9861F5C556F6,0034495C9DAD14B2,426CE85008FB5516,9D961192E93E158C,FB328984807216DE,A74A53AAC8E08A72,A285A851A880E2DF,52B5C19FFA2D0A75,1817D4DFF31F1374,001F83400959927A,A024ABF37352F21C,19B67BC44638EE0A,1DF5F3130FDABC96,53B9E094F505EE7F,5D944B0D208BB713,B64D534CDD37D267,14C79AD6526B8411,003F5E97284FCBC2,51638F543C6EE865,524651F0736AF80F,E9BB997772BE3217,9B6A1F78C00A0086,4437DF562661499B,CF4F17B288580974,B56689D6BD477264,000FD244E3235D53,369B23F951ECB9B6,1ABBC9353C93D337,0355C8BDF78001DB,76575E41B6A2E8AC,440D3AC2ABE7606C,495A620371DE7CA4,899F7F172A720782,001DCB18DF31A7A8,005469B8A30C10D9,E34E96DAFD134CC9,E1CBA832A34E2465,E1FDE73ECC33E7F9,42FA1D49F8B12FE9,682631A58D1D72BE,7CD8EB0340306E9A,001889187206C8DE,1A2F2832696B0DD1,6A607665F2A22C12,68231C68A66F3D0F,0D8A177A89190AEA,7581DD9E36E1D18E,DCAFA6188C8C5CCC,54BB7855742D0F3D,003B2CC044D63268,EAD077810D53845A,4C8CB30109CD2ACD,6B7A5FE8240B58EC,8731D16379B274C6,5B5F46877B63EED8,ACFCDC0AFE00FB12,5D720D7934CF9723,003EAB25651617DC,F59D49D34F0DEB41,4A267DFBC9B2EDB8,2FACF3F57A5C2104,97F8E2560EC1A004,DD59E8E4C60CF2C6,3517DB65584F5062,EBAF3E49393208DB,0031A3295DC975A0,91E3D8A3F8C89D0F,F030EF99F3D1ACC5,5333BB8CDBF28B6B,7E57CFA1C72313FD,60538BF4C8FA87AD,FB0C26BA4C3AE373,DE6CCEFD187D8915,002C5F1CD0B5B119,47F31A06AEA05B68,BE255F3B9A8E80F9,508C0259B154A09C,CF70CD753DDF1509,B128ECBE15B905FD,04802D1A0B94744A,D8881ACF05EC144B,0022FF950BACD8AA,103EEB97B0DF2B64,7A498047921CB116,0D1A92EE4E069FA8,14FB5BA45CA2A310,34F4AF35C3D486E6,7F5A734DE408B8F8,C1D3EF85BB2B55AA,003D7EF5DB6FB66D,14E856AA59B85B62,D58D198E5319A998,041680C4D78CD225,24497E0D1133189A,2EBA8C881CA36C05,C6EFA62CD6AF957A,AC27F8F595077F18,0019C9EDDF69F04F,3F9BF2A7018A29D4,6FF6F8F9BE5AD26E,E309EC43C708F176,35DEF7D474546E5F,0A523C51C2ADC289,836B16EEBEBDC577,9F6330AA82AC0FB7,0013353A86764CB1,D85940AC9F606506,2DD5683879BB0D3C,42A9CFA5752ADEEE,8CECEAF8E30E2F77,F7D8D27CF06E9841,1538774A1E6364B5,3248DC577947932C,000BA1B712D0573A,DCADBF1B0572DFF1,7CB2C96C520B7DD4,50E98BC173F3576B,2155F59B0A1ACE9C,05F3498078E180A8,0C84BD48950F6466,3CA8B138C0E6E023,0002AFA7A845676F,B54DF56754D2BF9A,B9EB4BDD7EDC24F5,580220CD28134ED7,DDFD949FDD2D283D,D78AEAB8C4D6D98D,731FC92473D8B1A8,B883C0A587EC7CE8,00138252667B6D0D,82A34DC1AB201759,6B487D088623571B,4EF9BD71C8E2E410,DABDA217788C8404,F513B8449C390408,975819BA21D4E308,4CB663C98CEA0FC7,003BD516DDDD235B,58C156F0B0CF6633,97A045CAE1D6EE34,3D8226DB683747EF,014EA6AAB64DA658,0E68623A97FEDE8E,912D7762EE10E199,2F1A6E19257CCE15,00238AA672C05D7B,5F2134D7B5BEE18F,0DD0A18D1FA6ABC8,22B4E4E4C62A1169,F3321809B586EEB5,442511DBE58EA3E0,18AF59F75B5A1D81,F613E0C78D09DB39,0038F9A909A4AAD7,7216BF81FB76D2B2,CF839F84F5074003,3544D0FFBB3D8119,180818842D857328,C8B018EDAF81E942,B8C9EBD4A97A0332,57125CBB93AA98D6,00119CAEBE483077,85F40C0DC76367DE,61D01480D393A0C3,4478573FBED1BE2B,B08909E94C46C045,0B4A05FDD03BD3FF,994E4261B278E49D,4D4AAEE9A93BE296,0013C27B3F18FCAB,BDA409ADFE282B13,321E5AC91D3F6FB4,FCDC3B7E8000EAFE,AFFEC8178FE2D640,A8101A260BF23371,9FD5B2B3405C53A9,35E648119223A8BC,0030B5B0715E7CE8,80E07EEC04FCEC17,7CE98A62BD6326F5,927F745FFDB92384,065CB5A0E1314000,31F4D5849B14CAE0,B0620439C39DC5B7,FFD16820192A45F1,0000B89192C462FF,CA6B4D21441EEB2B,E4C994901A14261A,E5BCA779E7A6F4E2,48DC4B88F10DB451,579FB1A063702836,998D5EF0C793BED0,025F18DB490C8FCE,003C6A94175FAC7D,6295D32A798CC55A,1E6C6DFED162D860,A985D62DF6862E5C,4784E07ADF5C78B9,A9BCECE345BF5060,79C5742E0A21B6B2,9FC13F9403385AED,00346F389017764B,AECAF2E70184385B,1066D46F5750E381,46A128C79011FDE9,E7C4F0B18D12FD19,46B936686F52C27E,E81CF2F3250477DD,3A70AA1C6DD2538B,0032628A79FAD0A0,D9F91EE83B8A980F,72CA9020A16D52F6,F1387C7C37ADB6C7,014EDA8E15010048,EB41C41EA63D90C6,3AC0B092A3CEFD38,3D2A851E64577B68,001813D0BCD62416,671BF674261B6967,8A648DACD54588FD,D23EBA465D48EC45,A40FE215C47F6CB0,885155DC95D5309D,D0035E04CB46F0C5,7C400DC9D5DBDE8F,003A2DC0B1443582,55D126E5218802E7,BCB2DC00712EC96B,48DB003B33A8B447,F03CB33E7118110F,A5DA17988CF16EDA,BC9C18E551C87BED,D4CA4952331951BF,00305C0851AF9F29,D4065E5F889CCC15,EEDBEFA8CF496A15,41B24D331375B6CA,1D8F9D0F246789AA,0DBD4429422AED81,393A4C4AC6CD25CC,0FED1A717EF7C1A0,000D49AF088CAC5E,DF04CEAE8E75CD7A,3C5C9E7861143897,C614F256F39626F0,F704965E0A717BDF,56F9CB426F430C0D,93D23A8DC45339FB,AC716AFAD57C094E,001A48E8E8AF2F92,15F9022F39D1FC96,20E31B5FAA772239,3F1543B6088954C9,4015193C49155847,CF7164BE84260119,272E28CAB30A172F,92D0C4650153A887,0020EFFB8688AA05,1C836810818EF7F1,E67418492D3A9D83,F5EFEAB3DB1D615B,C65B849191DA8DBF,9CB6FA8F0E3137C9,2222070B1FB32198,4D2238D8C229907B,002B037348CC21E7,99813C0C96D0157D,95B984A41886525B,4EBDCDA070A16125,0B396AC29E08CC7E,FFEA69AA0A51BF9F,6F956E7FEAFCA9EF,C0BFE6E048E2EA5E,0011BA884358DB8E,1461004352506267,B5E5ADB36DD7BC7E,92043E0312CED09F,D97F9B48480D3B2F,9549C900808EFA49,2837FDC6F3FB439E,51D0B5A231BDA4EB,0032AEABB738AC4C,4273F45B78CD1E2F,188472BE164978BF,FF1EC16580F92BEF,BC755672517DA57A,3F2DD64EBD5424BC,0FF3F70FD4CCD73B,242FBA3A14781116,0022D27DF88764C7,C928791D5E021CF5,F0C5D035578862A8,7EE536CA145C79D6,5AC460F3FD05F40C,F9AD0789C6E98D4E,B395662E28B621A2,1983C5A913F88D8F,000BE39CC3DCFB5D,8C465FE6A5008FEE,86DDD18D8C9A2032,5CC9A316390CD236,2EF05A65D9C3D835,EA5593EC149BD130,2D09D529F65392F6,24227E5DFA92DD28,0014E3F8FA837841,0E1AF95614B43D7D,386CCE844D88EECF,33EFD7924B8F3C51,CE027E925E02B0BF,93214CC31248BA40,79342A927436C3AE,D4CA9558C050E64E,0015A066D7CED515,6D37E0CD723CC6D3,1F4664D3C5B46D37,5A9FA917553594C2,343374EAF709FAA3,6C4881D6CD4F89FA,5AA461A959D3B23B,655F77646AB92C42,00350AB3B5756DDD,91154D4A76B607AD,BA15B5E37868BA2F,36A5011D0A0D140F,B28BF325F5E9D593,8C440FA4F62D7FCB,85073732464DB1ED,1AE173887901FCD9,00099539813A25DB,952FEA8D029645B0,5980D15AC2FDBF60,DE9AE176B881ED88,3CF4E751E9123F61,5B660242C90AA7FE,D3DE090B82434C42,B5E08D5991E8C352,0016494A29DFEBB1,41870177448D4058,5DB95F33AB37023F,ECEB5D71985557D9,F01A5F64004D06FA,F42A53BBB95CCE46,41ECD3E4677FD331,72C25D1D037570C1,0027F86E423906F7,8D875A77DB1333F4,46F8E2DDE383722A,5C97A2F433654D71,031D3EEBE8698FFC,A3F18B6605948A8A,CE93A936F7379F7A,73F3DDBA463C6074,0005032CF7B15D80,ABE80CBB5E9EA27C,01EEBF6C07B06D56,9E9EBA5AD2194094,7A2D84152A541F1D,80315091D827DF07,BA2D007B15197DC0,F29B0F97653B5E3F,0010BD3DBDE18494,6607F4FFA884372E,C8A56A82F7F13E6C,A0D5AB23C47AFE81,4EBC11C1B42ABF88,FD47DE307196D9DD,79FCF3930DF70329,AD4639888A3F9B70,000B0FB1146F488E,AEA62FB863FCC5DE,54EC6A8D42E262B2,6A27229E9E4DCF5F,662B6229A042095B,C20B0988BBD267AE,F0E7FFE2CB85EEA9,903CE205758A7F19,0013BFB387DDDEA6,FA20852B4C386A26,42B73C0635620829,63D65FEBBC7AA629,B41BE5BF31E2D1C4,CD045973F44014FA,FAC46AC824DD383B,24A2E87CB4E449E6,001EF954A0BA5F55,B1F57C91738D2BF5,84EB37296A426FB8,E75BD8A26D921CC9,82416FFAB890AFAD,585CF9C86CCBBD84,A1DF0780ABBBA582,73DE38A505498951,00048B2F47BF6B21,00306397BC03F27C,EF1609940FAAFAF0,6B2C441B754C1B11,28AA01A1BC9B9418,3F43E7FBDC70403B,08436F066E3DD628,E002373D9730B2B2,001D1293C3624743,83FE11015CB2B856,E158282039E5660F,A73D3CF9B046CB5D,3E822344285DEA73,57F09A7BAFFC0644,8DD02141045750A7,D840836D405057AB,0021B2B9BCAEB4B8,EDFCE7ACEDAF5FB0,42A7C6B50870E497,9D53D3C9B92961FF,55F8BEB06E6042B8,1D9C13692797FC89,E80D625FB6959A8B,CF2EDAB34340F6B6,000A35C58C6D7DF9,254807DDAC70A5B8,12DE889337C7BF42,5E9A4EA8629E089A,AD235BDF1BB48B78,3C1344133664F11D,97ED2EF908834476,AD6EDE050912336C,0024C0249853464D,F53AD258C005E143,202C87EF4C67A5A4,560AFCE7CE500CE2,D7DA35641162D069,36F8951D775A4A98,E919627BDCA56C6F,559887148EB6CFEF,001DC2CFDAAE0EB3,BB4D8FA334B9FD44,03C9506A7758776C,5556526EC73258D2,5B32B1240451920F,43FE0CCB27985BDE,FDEFD05D7C1DA00F,C52A2ED4185D9769,002C31AA4B343DFD,22C5D9CA7D02D19D,5CD7638C11E0BA63,D13B550B9BC566B8,291E20E716CE1A28,BDDB43862F598460,1677D7496D430442,AE8C6F83B891A90B,003F4BA35B7E5105,9D26E498BBC30B6C,6D546FFB2971139E,3EE6837B46467A58,A759B41A15A14AFD,424F02D68ACC21EA,415BCE7F828679E4,9D6FF18C04E1DBE6,00322FF3511EFAD8,E39D939FDFF5B01D,AD032AB372660EDF,5CCC5C056B805586,A2E79D9F4C156BE9,1FBDAE563773A9B6,B4ABCC1CBE332F6B,04FFC1EAD488B895,0012E1DEFD360787,D3B7F6DE5B450F60,9C21EA333131D0FF,E92934D49CEC5FD2,FD99B0BAA6AF874E,9608D7BB0A914D82,D87089DB4ECD0E72,3D2B829BF50AEB9B,003D66804702F8DD,4C6D2B11ACC63229,B5361D1BDF013BA4,F8555D40336E2C8B,2609F4DCDF4625B3,6EE524DBB592588A,621AD71819E06E81,A414312E556F8104,00198FD48360119A,EBAAB1ED1A6E9F5C,32107ABAC72E1CA8,1D85452911D1DDAA,492C886C7A0145B0,28E31ED74E4C3EFD,BE315E524DE35B1D,0FB3E3904E4F9E27,001787469535F571,14D9399095CA02A8,E6FC090F630CF41A,08E150A852294E6F,CB20B2734C6419E4,CF679AE04031E37A,A4C88EE802899886,7B00FED4BAB936FF,0032275B63C75065,69F54176BC8F8F20,1D7EEBFBF3CE8643,AACCBD66608969FC,07D9C35BFFEA301A,3582F2DF82227928,ED134081EA2C0725,FCB3826634C2E8E8,0025339A9387CE5E,7688620909E026A1,8E1CFEAEDC29605D,480CC56A36B6BD98,444553E378963398,F198D838A47EA72C,E32AFA0DA9498F66,C1F8B04188DF193C,002A47AEFB9A8033,A55E1B5C85EF9A08,09E6B336FCCB9175,93C52399A8C43478,7C81D40092A90D56,C21934DB57D8485F,2D920F791A5DD2F1,35C35CD05A422655,000A366CDA633F37,C3193BB2E776C656,27CD0C07D703D7EE,914300F5CC97AC10,1F7A72DD534F2EAA,EB17169759ABB8FB,9C301F15ACCE6FAD,5F5EEA3344A80C4A,0019080CD4E6FACB,C33354DFB75AC2DB,8A000E4B8FA84C35,48AB869905E1D128,13AD89C285ED97A3,BF8063F36063341E,DBAA06BF6B50D580,AE7F1B2E86B84717,00296533DBDD021D,4FAC8334D7F1E990,EA813AF5D51CFD66,A435C1EC1F5895D3,DA42249736DAC847,0EB9B533BD454FAF,5B876FEC27D3C383,830FAEA8E09AE2C3,00302DB299580ECD,D981E716FDA050F8,E8E3E81F046CADAF,96CF6F873C0481D2,1E3BC045978A784E,97047F347653612A,9A68CA607A2E07D7,CAD50C24518A759E,0002C4D2494141DA,4E20BE214F44519A,BB8DBBA3947EBD7D,4FC8E042973B2C88,9B193303074D2D07,BFE4BDEC8E78C658,C845357FD29070FF,60A40711BC3DBAD1,0024E3B0048839A0,983592ABA709E25F,997934D5FF5C2DAB,577996251B4F2247,F266988815282469,B3E93DE9FA26B3B8,1D5C980E2E19DFA0,A78B2FE0B37CEAF2,001231DE5E8C5C8C,C0B1EAB4747B5939,265DA8C1CE419E7F,16B2C33B568528DC,F57E99F4FA46C27C,7303F7167C3C0787,5F577E254B73B1A3,AD0010F59E4BE8D1,00136A7413636BDF,5716384689B26F9A,AB5F4087B3B8656F,32CF6F5924BCB27D,AAA593B724BC995E,65C6E390BD7F581D,FB352F2178FF0C25,C3EB9F72A34478FC,003D84ECDAE4C5B6,F39B070ED0571271,FA8E2D1DE371621A,A46D97EA72DF4E70,EA591C6A9B584910,F244795CDEB0D7D4,AB4AE12127DFB819,7C1B44F4DDB22AC6,003842A1B217F229,5E787019866B0556,FBA472CAFCE2AA8F,FCFC72860F689FA1,8E1E052D3C249624,5992B16645F4B9E0,8C553567E3D8AFA5,EAA4E7ED6D7709CC,001D64FC558960C3,02FC55E37B6F2FD1,7EFC6EAE3BB1E326,36DCD5E5FCE7412A,B6509374C8A46B2A,36CD800639DF25D1,1AAA5FDA75763C62,0DA7075119AF1581,000A238B6A22D310,020FFFEEEDF4F3F9,FCAEF1EFD825358D,74197A906C0C468A,05CC8A2D69495919,A75A6402E15CF35A,51E63D890457129F,44E6343D5D989239,000BB259C8D1BDF8,CB0ACB94217404A1,7C7CCF027F0EB288,380F0AE0C177E063,E58100C6CA49B0AF,BF80610D8904B9DA,55EFD8F47C52E40C,35A23E1287855BBB,001CECEC072B65D1,B216DC3744BC8B4F,36EDFAB2F2885CA3,91BADC9249A95B83,BA1DE734BC6CC543,B9726050149EE0D9,94A59286E8F931DA,FC2FED97973CA19A,0034C56634C18D65,61AD24D69E6B0F76,1BEC2961AE9A3946,5AACFE86E6FD649E,969E89ED72BAEB2C,E02BEB43268A6B00,FD31BCF69AC77B8C,AAA68AD36411C542,0016F7C21757F3A3,57C1914A4EAD3D0C,CB0F0D9D3C5D8F51,13380F5B39D25031,39377B2B4B8DA08D,D6C9B16FE42B8D3A,831A9EBE57D40593,371CE28C987B254C,002428730F4E1887,F61AE05DA907E11D,62C33E42D6CCB7D5,889D2D99CB6EDEE1,0C0B3F2694212214,417FEC3679584F80,51B4E95DE1161B7F,B6BA7661D65D3A2F,0030CB28DA9B39A3,64B6A4CB47E1C332,27053B4A84F2D8A6,4861B327F5CC3146,0BB41B8BC57E71F3,2F910C195334BAAC,5AAC84D81F9DF6F1,F0C1C05FB16D6C38,00093DD0E3F15B9D,EB5E8F6A8891DA93,669BE78E68C699D4,F36A6D1951A2282E,14A45FF2940F5AF5,9B3D835D618BC5B8,3B9ADCB40DD3A9EC,B6F3CDC75B58056D,00311AEC40D7E739,D5C491DB08645118,CA43E84F5B24EB9D,A098E5BAC7113547,EC7A112605E2EF9A,D625778DDDC0A208,BAFA4C3176516B67,DA7D65C01F86FA6B,00102D6059EB9AC8,2E8F0FD91BB3F9B3,52A17EFAB074062C,B15305773023BECF,E93D58C299BBB1F6,000A7098FD85D462,9F4842BF9545B1AD,1F43021F3852E6C6,002FD26325C77691,2AC8754C620E6AA5,2CB814880DF124F4,DC353466BDF5A5F2,4F27467E4033F0FC,883ADDFB35C2C3A8,C4420748145BB61D,CABB7596E255E210,0003672AD52545E3,8763B961B7FE5425,4CE5572050C3D363,372B7C9BE86DE419,E20076D8C7117988,157C2461918DE713,6B85109A3B860927,043AFB6D3153FFCC,003702D563CF1473,750877FF7480A0A7,75030F868DB5B709,AEAA0DD0A0C7AB82,838F90FCEB2022C0,5A0D2C85799E17F0,3BEDFFCEFB008F6F,8DA8484C728FDB8F,0038EB3D7D26E299,505005FFB5D94C68,CEBAB61C80146EAC,F86D82FEB6519B05,21EA29EA92E5B00A,B909F025E95A3C37,610CA71E4FC8EAB0,7236FC31750FA674,0024BC8CB34AE6E1,D2567183EE678537,91D40562F631C508,46826B767D5CB7C5,3F6E48DA2ABE4343,00F4D8F4F0403906,E37D979BF4DDF352,68D5ED0F34B84678,002E2A06D6B5BC72,78A66BF5CDDEAFF7,2CF2195AD8CF8BC8,7E978EA9A74C46A6,A801E2EB9591D0DE,28CEE1BD74FEE7B9,0DE08C985C25C9CA,6893D076AD9C30A6,000A12737B90DD94,7858839CD26DD889,32A28333673E3048,D9B5F9180BE529A0,003EFD535326F6E9,8B7F45F5458F7EE7,12F71CF7A0FC28A2,125D504EA6A9ED82,00163AC860345E51,4EDEC061024CE75D,0DF938700082DB37,02C0A078FC450C27,B719FEAFA4137FDD,DA77AE668B540555,57FBA7A7BE60B6FA,8B6D790355DAF227,0001E6F329547A78,99BAA1BBADE474A6,58905D5EEB85D691,BEDA47D2DD4528E8,0ED88B1E09C8E7E0,44274125021B95CF,3340BDAE9F281523,DCBA07EE5A6756F6,0025AE0544D3D8AF,9356DC9C18EEF278,9D6732EEF8E52CFC,FE2436855CFF46B0,733FD03FE98F9347,F57BED59E415F644,3B00538A5914B2FE,9378CDE06E337511,003FA17C26759E1A,5735BEEA2430B320,16EF76B0B92D29EE,F81BC5BA3134EAA4,B12C1F70EDCF9CEA,D5E9DF6CFFB3D10F,0F84AEA857561B4E,82E1D99E0B9A04BB,00127C676C13E9DE,D513F92983E09BFC,468B60F945CE97EC,26CBD7BB1162DCAA,5FC7AEB3C385AD28,3835B77AF6588DDF,7E2A688A3BFDFA4B,1DD0DEC6F4CF1D6C,0037389D1E032D02,564AE9590B08B7C0,FC03E004083D0B9E,0DE7361A632DCD04,6F6588185B16A3A3,5B2E2BCA3169A7AF,B0AF5E591404CD07,A1C2EEA075C918B5,002C5ECBC9E5B122,CE44085426D0F222,694EF8F7C4945050,4ED95375061A898E,4B9B53CEC11BEEEF,73C39319A4CFC848,109B4D364955CB71,E6034ADC4ACF92B0,0010A3D08B82C153,08E4438CD14D592A,CB2E5E1F0899A298,ED50064A7A5A4389,12D0C4BE6531FAC4,E294257520A8F156,A11BC0BCB8518EF3,7D1C11F9707090A7,0009AD3160880A4A,5EE2E230090E3BB4,0745C43FD209FCD4,A03B61D81F60B52A,FF62ADA4B4443172,3C0E38DC31F78273,651C45380E1CD417,81FDFE8F04FE14B6,000CB3CC876743D3,FA752D3A1DEB91B6,206FDC4D82A0EDE3,0AB0F828A554EDF5,7931A9B5EB7339CF,75C7B6F3438BCFAF,92F58D6E4FCAF164,3198D856B91AC4CA,003CB5824A98F8B6,212951D643C68C85,34DE5665697DE03A,6F15B9122A43B5D8,74C64F701EE920CD,A306801F5DE37192,8EB2837D2931BC75,9672420C634F53AB,003193865C583F98,19978A645EC93582,CBE0DEC11B5B1B00,0030426ED3448A11,0C9749812705D37B,50E69E609B4BB4F1,6E00941B20DAF6F7,6A16263BBD012092,00244E68A1EC0FFC,73C97D8A26716349,8D9ACABECA58D287,42E4449DBD94F0A3,7B381F2780E035F4,96DCEBBD22C97372,069E90AE4DD6C58A,C35B7C5C37ED1E5B,001F89258C196B13,20C98C2A554C35A5,C1B1D6708BA8B3E2,7B40595828DD34A5,546DC718BD1F8CC6,D7ED8C712373B134,CBB911B985ADBEDA,DEAEDD8CD669B532,000A0184BF9DD651,F14DB235AC6B1D80,67727340C606C313,0B1ADCB1B11AF4D8,98264CD4504EF11C,44F2829E189B85D9,EF73965725361309,53F4B1D8268724A4,0037572B5CECB6EA,C4AF31D8ADFA7744,B7F6D49ED7C8BCBF,5C9912A3E9E810E6,D57C14C061DA7B7C,41643AD6C011A1F5,FC7BEE7053AB2DF7,D1988C718120B806,001F5C04412B731D,287E009A0BA64CCE,BE6C1402CD5AD48A,095AACB2A54019F6,8672F922D3B4ED47,302FC9DB73275903,6C181EDA1A35997B,1A6647B3236262D0,001234F2A3ED1533,5EEB2CE7B0209044,E43BA06CA99C793C,83F6774E375AEA64,A2D08FE9B71BDEDC,976CE7B9370BDD52,65F28A3B0A0E00AB,A6A970759676509E,002CCA695BFE8A8C,3A931AD4291CBD23,7CC7AA6755C34733,1A1291B318AD2676,7A4ED82484493E5A,4586D3578087F27C,AE97697601CDB8F2,4ACCAFBB1C24E58F,001FD3A99B0AEA24,75C7CF176B1575A4,78B99514AEFBFE0A,E9EDF34EF0DD9AA4,5BB32C21CA2D6160,532E227156397270,C5FDDA80C3CD6099,FBE0CEFE58F86B22,0013A4B28B72D17D,7FB547E956D1BC5F,CFAF79DC970133D5,FC17CF767CA8ECA2,A33A9F6B7B09E80D,32CA4B88D3096342,F54CEADBEC9E15BD,EF7938F1CA82A3CE,00071A4E441FC34F,BA65901357348397,F7A2047866E1552E,D0FE731D3D3734D4,A288F781EFDC2055,857B66189EE5731F,AB9E9925614E9486,014946C4490B6A19,000ABE630FA13190,83C185D701E213B2,F0A7E55591C3E313,4DD0E95CBC8B7BAB,37CEC852D00EA37F,D95C884AC4132395,145D206B71BE894F,42FF8715583F120C,00078BED481D374F,30948189F3DEA916,E42910CF7173D60C,B1EDF8D49166FDFF,3640BE09D37F96BC,9F58B785273C2D8E,9A6F665EA1474724,3D3724CA87A4429B,002F42ECB8D57780,5F8D213F0BBE49AE,A9D875AC2591B474,B34C8CFE396BDB8E,3675569ED8F52863,6B88662AA7A4C483,AF279384E21008D9,B05F1E12AA764543,0023E8475045901A,0BA681EA3FC57D42,725A16751E8DE777,5243C38254F8FAE2,DF0397C1F65D5B1E,DB517E378D81FF8F,F0DE9BC246D28529,C7BED4D2F339CE98,002A9D80FB07BDE2,1483818D6D83EA8D,DCC532F9F1F2FF72,8E2085B23905F604,12DC0117488CB992,D46272C617406F5F,A71D6756EFBBF5B3,7680A6C2BE3D91E8,0016BD90C875F5D5,8CED944C01F4B1AF,695283F05173144F,EC8FDF42F91D0EFA,852D4C97FB65D3CC,45BCC0A0EF08533E,E8B13897917DE0AF,FE0593CE5C037117,003D015BFCC8D821,E9AFB31E5A26D4E4,BBDE6F4D65820081,ACA8DDBE7CFF7EBA,548A9E7707344223,EBC4330AB004F360,F9F7C3E59F0234E4,0617E9D451CD63A4,001D8A0A269D1315,94A901719C36D0CA,CBDE7DF6D9C082B5,7DBE48B123ED3480,3C787AE461B02213,56DED308F7366F05,E0D853BBEA4F8173,C5C105E791475023,0030F1774D980BEC,7DEF47364665E084,F608AFB820EC7DBA,485D1B8DF98FFB38,25E058498BE94392,F78D927BE900D4C6,6177C198E5ABDE67,2FB0DBE726BA7B3C,00361A640331A2E3,484872EB5479CC77,BB52ABE51957FD85,A896CA3118132932,330F9F5683A93A13,726A93B4DE3B60C3,6DD35B8E1E2CDE20,696FBBE9103CE3F2,000FEADD99507A7F,775B5C3A89A8A62F,DA1CDD929380DE4F,4712E4B3BD8C36CB,2171E610992C0874,31F1268540B7D2B3,4D0A01B311D7A725,DAAF732ABC1D7D37,0039BCB5B7BC4D24,D165BB00E26FC5DE,698C9B0E18C10B05,BEB03CDBB49460CE,80871BDDCE5189DA,8348F6FFB17632A4,897C0B2107D57ACC,B7CA58D7D23352CC,000050FCE38F28D4,30107CDE2A05EFA5,20942D6F9A24B525,E633FAC33035EAFC,0ACE13AB543B1D33,F254FE464BE483ED,E56118CD0792D09F,3E45588F9B726E20,0003F55649FF2F30,74ABD370EE5B1AC8,79CA0E481BCD80FD,F201276D83DD697E,84C7CA9DF313E474,5B1F94C3CBC50559,4878BC341754D311,D601820CD58757F0,0029A6B592D88582,EE448E6FEE94EE5F,80F157FBFCC0B078,239754017436304C,3B16D4C3D28DB64C,6D8FB35F2079F062,F446FB8B923277BB,0C64A62B73B35C89,003239D73EA6156F,D417B8CC81218BEA,BD28304BE6F478B1,CB2D829557916AF4,41A625896D0875AD,457F2069FFE1FEA7,4369D0D26FEDF9C3,4927941AC6F2C223,00128D43F3FC78B6,494648D529E2E34A,75C3A51CAA72C34B,2952431F41F7A228,A240DB7CB0B3DD93,57EDC611A243A475,588BF1214DD690E5,D2049F432548E5CE,001AF42128CCE18A,A7FF3D30BB2D034D,34D8E63CCD11FFBB,87276093A6008B00,DC9D23F3D24E037C,3C537EF921E11777,328430EC92B070CE,B075ED126377EE12,001447F6BC627823,2A1E3A19E9A413C5,F010D7AC372C2E22,8E0C7EB311D52151,DBC6DB6D9169DDA7,091FD6D5208EFCB5,9B565D36100924B1,5405FAA2D834DF74,00375804A68EF36E,69323930CCCD1CAA,659FA27C4F2D6FA5,2092963F4AE22D74,D200281F45F12137,9EF962C18D736015,7ECBFB59745B551F,2B884F17FD6A3991,000FD97AC3D3BD01,F6ABFC9751C2FF17,5C499A110173F9D8,50CC18DFF2F3782F,991D62AE216D8951,D5DB480DEB1B42F0,1E5DA55BC57C8F69,254836A37E0FFDCB,000CDFFED2E76062,5D0C2645B2238BEB,9F272FA8CE3F4756,6246927A2EECC2C6,0D8CE3773B6E3D68,63325BD0391AC0E5,DFCD82AD868279BF,71F16C65423320E0,001F8E9D2E2077E6,E9022A7A7CAE818D,523F1B12A20FACF8,C96E76A85B40E50F,EF5F71DED745CD6B,1D7F1ED2D5377A2D,D84E3379606C1CB3,C2259A75AA90165F,0007AB4140DA8B08,0E2B592E9AAA4B01,E3F0EBB78FD6C4A6,125F4B31EA0165FE,5CC8EBE300F82DD6,22D047ADBED3B4C7,874EC1356B042DAE,D30B769A7AC085FF,004030D70A162A81,C5707FD7065E8A3F,04CBB26E32840EB1,98A2FF688ED78ED8,F33E01C6C6B96CEC,2E653F66330ED6C2,9CBAD385759B9999,53AC1284C68BD6D6,003947F2735906A9,F7079E38B1E31F7A,FE8030CF9C3B03C6,4E2DD1D24F39E33F,18D40537E21396E9,6DEB7F9423CC6132,39A9868405AC80FB,EA862EBAE178E245,00188D9401CDD1ED,B14FE14363FB675E,F130FE74750D2FFA,5FA1144B0907E73F,A56D8845C5814CE5,C221144112DAD112,215F95918EAF106C,9401CBEA645CB5FD,00310850C5F563AE,C93C305167CCDA29,6DDE498CEA18A937,E0E3E927BB78D6C5,6707CB7AE1E735D6,8612E1DA17E2BDD1,14537BAB2A73BCE8,63D4B2662D74FA86,000F51988AB12D43,A0AF46DD375A72F0,15F2BBC2C195A1C8,35051AE3999D9859,B9995A916729EF99,D631336A47CD67A1,D320CBB2D88A8A95,E4F0127752E3F25E,002BC9E87BCEED63,82C14AF058506E6D,A2B6F323D8ADD6AA,D595FC5A5FFEF2E4,99B9E4B45CDDD332,A9C7BD5D3212BD5D,BAC2FC487D102C22,793819483BD00EB1,003A79797DFE06F4,256FF87B1230EF44,076C6AC226D2E441,D91B28ABD15D5878,865F7EC8980CE1B9,7EA02FEC26CD66C0,4B01065B8A7484FE,C907787EA217FCBD,0016FED507E1CCF1,668C3B2DA85D52A7,62B4E8AE67A86908,8548FED7F3E1233A,E863FACF6E1CCA9D,EA046D3779435BEB,6074915D6B1AEF19,FCEB479C8620B3B2,0023B0347943D21F,5180C305BEFCD846,446A6F232E525BC8,023B22A4114C214A,079B0D29058BF911,09682B719F9D5419,E085461EEA86099A,BA8FB6CE03CE0C30,00303DF0A5C245EF,DC9127C1E2283C3B,371E42755DECE4F8,9163C0B6384F2D98,30855404C1CBB5AB,CA77CE0CE0F9AE58,3E591B8C6BCB5048,2E83EAB9349BD19C,000D135B74E6373A,EA7D8379BCCE3DE4,7F82437E8852007C,A9FDA6C8596D6365,1FC37BC64050CC30,58C4F771D93D096B,2165CC2BF5057D22,3A6E00A3A939DB11,0028A3949151E680,5DF2F18E7167D40C,05BAFC61532F321A,38B0CBFA464BC4A7,B736FEC93636B1B1,EE7A26A730C8C3FB,D9524699F7461044,EE574E122F58E22E,0034AF00B10C4494,07756BE4AA0AF902,25CD136A8D49A981,8B316622D5FF9558,CF206BBEE71A6B19,BEA5289B51B50A00,742C6BD687E323A9,674A0AC5B8432F01,00165F5E488119AD,05F8EBD3C47A3519,14E2558308FA92B4,85C819F84C9E9056,71A503B3F8B0DA38,8E638ED293B79FFC,7FD0969436B7A541,039332E616F5448C,001691BA94023619,A2076C95C0E9D3F2,18EB4940F30695E5,64453EBD2409AD5E,BC848683204BC8E3,231F7AE25ED6B846,2D866952923D93BF,555CFB5240001A5D,003BD85207DB5C25,592FADC83E143D5A,B79C41B01A75D1AF,D60FA52CABB39413,5418BD839AE04503,23E289B5403E717A,9E079ED27B4CC32A,2C3EFB2B2353F6EE,00141D24645EB471,DD526F5935A9D962,E57BF3DAA0E8B5E3,43D9618F980A1602,031AA422AB037DAC,ECB0F6492DB19766,93E088ACC91E402D,1E7341A0D34EBC50,0016CBFFE31CC620,D77D194D88696BAD,F5CCF96DF9292ADB,9EB489DA0A7B15DE,385DEF9C51F56032,78A7E76EE1C045BD,BD5D7BA29022992A,4FB1300B7210F43B,0003F7A97A12D991,66F68A509F8BF278,1FE6EE63C13B8914,56D12125DA02F90D,687D0099A8F5B9CC,EA5AC32E6976B569,9AD4DBC4AED7FC15,6934742F412EDE96,003223BF9DFE6E8C,5F7A8C4E5B632E5E,52A9BAB57C6A983A,F5D5DEF62069BC23,6A23903E61A906B5,13AF2B762BC97B84,C4F7B1B94A74F387,AE8F36EE8E044AF5,00006E8D093A966C,3CF5C53C8747BD84,8BAC2F053C7B63A4,D9AC4BF888F3B5A8,263BBED01E86C7BD,3E8E1B337E6E927B,713E5D43BBE84436,410DE18CED169702,002337FD472F39C9,C2CB4003B85AC1D5,40392C0A4080E775,457FACB527824D65,D04A5AF49E88531C,4F83CF35072EF4F2,86788E06152E75BD,DF7BE9CB4643A4D9,0029B0C6099E0882,9B71BAC0425F1229,F601EA2FCED8A62F,E51176AB94B37C3C,A8D638D54E1579DC,54D07F3EF7E46B3B,56A9BB477752BE74,86F673C52CE8A99F,002C8069B2BBAF17,B00C777638663F8B,FCF2ECC8600B7B8A,B0FFD7429FB905C1,792F230F9CD92F79,AF580C892A67FE62,D6AD5AE121751D2E,422142393AF1D8A3,00372F49E5B03602,A8CA6DC1D25ADD68,AB3EBF9B14C0F0CD,23DAE822CF78BB72,25A096703162AA35,FE81CF3BC0A03C1A,8334406BD6324197,1EF8C061CA9E5C55,0031FB9A960BD6E5,9AF30049778F8F9C,F4C89138635ADCFA,436CCB7CE696FA62,13DC67C031937414,BC8D00A97DFA24F5,982F0E6AF7812E4A,DE2493C9A091FB1D,0026BE878EC8D756,B92A11C91D3C101C,F886411090D3DC68,9075EFFF978EC334,35C58E483A0EA50A,E785532ACC5B1BFD,655DD3B251CA13AB,4FF72D8997D30099,002439E1E5AC7D6F,9A030412548AD7B5,10F06A3F55F63085,9FEC298118BEE321,3E60E394EE631609,EE3E4BD689E630CA,AC79076B411D3A9B,D21961436A08CC1E,001A5EF0C5559CEE,133569BD87317A52,525ACA0D890E60ED,9046EE3C9A86C57B,1EBA2451EFCCDAAF,72ED10140C8702A8,5480CE95553CAE82,767475F4ADC15D1C,0037DE45594A5A41,7BE509CFC31F77EF,D7C46C994787BB6D,AD5019891BAE538E,BBCC874C27135EB5,81584659AFE29443,E6B42648EF147F27,50FE64A57BC3B417,003CCB31BA2CC206,542E5616918C2E49,CDD1D9B7CBAFFA08,509B4F735F3C5C03,CEA5D5497B944F66,73D5563252FC12B5,E0221112F0DE160A,BB08AAD8E2A7BB99,0025222499A7FE93,700021E58586549C,C03305425F01A1A9,04E63AD15B9EC7EB,1CF5ECF9E0472D6A,DBFEC082079593F5,5B8F17F3A326BBEA,9D4DECEE7EE3B9CB,001C0ED06309859E,A694E89184398E8B,F70ACF874F08EEA4,1F3F198DF36C6E2A,BC873D422E8751CB,43315F87BEFEC32F,BD30C806F0EA4A18,183EFAE5448BD5D7,0031C5F19C1CB1FE,748CBD14A91848BA,59BC36D5865BCE1F,ABB6508A50E15783,EA0C21D7EBFF2DB3,E35DA7D036CA9B32,93C5CE31A0678828,9698EF98D6D5C94E,000C6D7A4AEDE265,BB403EC97E78E0D9,6022020A1F5F3538,FE4A9D8A8D841FBE,8A29F21DB12A8F1B,B3B7B149A9BCBD8F,AE9B6CF6F3771AB8,5B1B6810B0CDC706,000A930116AE488A,BE8370A52E4D8C25,9D36B8B20F2EECF5,A54D2CE6AA1D26D3,1B169B1D65F92B37,9BAB79D30D839E51,8DCB04B90A23E218,84DCD137717B66A9,003A986F97FCDC5D,D1BD6B28CC362499,27851B93DBB4FB49,1F1B617D9175C9D4,F4DBCA915B29D611,38FAA300E378DFA7,387D917C2C2644B8,F19C38094D35CCBE,003A8018A5791D2E,3727C53BD12D8BFC,6E28E4542153E4B5,ACB6AC5B279342EB,C2FA6B7FA8CBA811,8E78D449696DE2D3,796CD7A287BF49AD,8A41082E48A21C85,00008B6774605B21,6CBFCCD673F3EFF0,B9AB40BFB85647B5,2AB3E8CF4F7BAEE2,01E726B980597946,D042A98302B9D929,50E99EBA20706BDF,EE53724CA219DECF,000E7C1DA05009EC,8B7802BEF7A3649F,338D4A88CA6BE8F5,D1973A667BA7B8B2,CF680178E6DF6659,8BBD7DCBAFBEFEEA,64452F3A4EB18DFB,EB52739D414C16A5,0012A44D3E3B99C7,729DE26F772D7DFD,94A68DD6C4774019,7A4BE1A42F7AE07C,005CC9387FBED223,B23C26FCC148BD1D,FFFB0EA7A9E23FEB,11E62440B48E5FDD,00037C89113D03F7,32BD944BE3D51B1F,496E095B869A411B,C771FBA421DA4402,2EC912C47E58E585,72819F1199E2B3ED,B666598DD338E10C,9CF3A9F9C15EE907,003097A5433C2689,93CBB10B09C11E47,3EA0A98C6E60B04D,8A74C0D00A2253A5,3A6E078D3C02EC6C,3C6694107D8D836E,D8DF4BDA5C196286,7CA692538F3EF5B4,001B0B9180831B48,C546943B49C6D609,A21149D8FFAEA62D,6264CA622DDB50C3,327BA1B19BE61B3C,F059758FD0938206,F83F428A7A4373AA,D395CC9BF0CEA18C,001AE76F8D72C4AC,C57B774C101B7D99,24B602649C328A81,12439FE64E503F8F,425C899C917533A1,986A65F8AD4ED4CA,DE2DDDA6F8F718BF,9C185FCDD5F5E5CC,003D873440974AB2,1A1B8969FE299C5C,8E23FABA274ECFE7,44EFFB3B961FD1E9,0CF897CC3DED28D8,AB4D7610BECAF80B,7CD400801ACECC63,732587F3D2338A09,0008BA2E78D5497C,DC5EF7CEAE6C4A73,33D62B4322A86952,A13771648FE0FCCA,E3F5CBF2C58227F8,BB2C7D06EAC30EA1,9844F28471976FBF,A25517A8B247D797,00342C1500AC10EE,68A3D5069B2157D8,26E84AC25DAB7487,F9C8617BDFF31892,DCBDA629C226A7A5,3CE775C7DD0B7296,C18F1439D87AD8BC,B1D656D4EC4EE1E1,00100FD0333AC5E1,E8AE7C0FBBAA7AD0,3CA9FBC6C43D8963,449D3177369EC354,17207695465374DC,77D52546543C1E6D,307774010A22258A,68918EE875B22E9C,00251E631E1EB9F6,7B2B6E8C49DA1077,3B7ACBB07FEDA73C,D3167596CEB4C458,B84853337452F0D8,62E67597486F88B7,8669575ABA1DD147,A96991BA65EB778B,00033E8779A29DDD,0CEB97554F6347A8,B5C125B6F49853E9,3BC0EE6924BF3364,8AD7556E81D79E6C,ABA4005669D7A460,FB27FEA25406F7C1,A4085886EE434639,0035EFA7D66CB0CA,D14545B54C9170D9,E1F4BB663487D90E,35F5E4C68179D4C8,F833E82D1758B6D4,D6843BE1ED3E61D9,7F8D1B108D658496,CF31F4EF52E04E37,0031ED76CD3FFD52,FB5756E6376032CA,1A006291D92FF870,B263692B26A3042D,D26681EDA7DE6FE4,9974AF05DCD23A3E,C073CDA335F811CF,369940940B08BB3A,0029FD783A54C973,BE1EEFAD10F6B779,90988217A2690E4D,9B2ECA49BED640DE,53BE1895065FF2AE,0FA8318C5D6F6630,476FC30455CF7CB9,B3095DEF63B5E6EB,000A86210F473CAC,DFBDC0C7E1134B83,57B2BB07C28146B6,6363293323D6199B,C1071AA8A40AC9D4,7C70B9E82CE3D784,FD4B5EAE16C5CBFB,63D1084F0F8164D6,0033B35247085539,350012C9E786223D,216F5E0361B0BC26,E77045E5F103F0B4,51245AEE2F8C0338,BA90473A98B4EAE1,DC66FBAFBE29A16C,A7BE6BB161EF5970,002076D25B9CBCA1,4FBC212841DEDFD5,C4A3CE4A601BF592,F728D4BCB65FC6AC,D1CC72E28D742CC0,ACA299C23168CFDA,2251A4D40FB3C55F,96361DAE9C8C0EC1,0027E9DDCA838B8B,87EAD6411B9334BA,5C5B8314D72BAEB5,57F260A00580EE7E,C7CB9A2DE75E12E1,CC8B69909CE29D68,0762CB36DA1D466E,F5FBAC980A61A818,00210BE33C58CAB5,9F9E778A839AD25B,CC57B20E08D561BB,DEDEBFE9F0A7695A,0EE60012399A8513,9492DEDC38E41E95,78A2B3477DE43FE1,84C0657D03FAB48B,002A64728427C20C,567BE6269BB104AA,D1024A175B686DFC,0C954735D8ED328E,88C3028CF01BF1C9,B72BDF749F2B0833,68D4879D491E30D1,D70D1285D4B38387,001B6F28F26FB7AC,2EB62942400216E6,B5AC9D487EB8E3CB,FAD8398FA445206F,B9959AB23A382B5D,2967050C0452F1B5,7528C489BB98104F,0C8121F456F88BBB,001981111CDCF3E2,7FBD498CE603D42E,42E23AE0752ACA86,5962E5C451024987,F328A91E78207B6E,9CD29F0E20814190,65B3718DAC2FE40B,6B2A8AF828CA57F7,00052B2BD49346C4,B9C1B6DA9BC26CD6,4BAB9DBE3B0AB477,9E26A43C5F52DE5B,3819129CE7657AC6,EDDE1867EB060FFB,B85E269D86994EC1,80E9B88BF7BAF392,001FA1608BEFACAC,F3E68517038AFE41,6CC50A8696653A1F,DC8ED43DE5B61174,A69AEDB153A77181,F754CD6B73B21AEA,DF5772F71510F9CA,A8094AF17803251E,0025720920D26B31,E5FDD4B19F261BF8,42BD3FB635739271,9B340578A17ABFB5,2451DB154E3FD494,C0930436E1486114,2300C1EC2719B841,9A0A737A612BABBE,002D5CF76F04E364,F0E8B836EA6F313E,8EEF39E2E6B2DAB5,C00512A5A62D7623,B50B40DB16F20795,DD652381CA845B27,F99DF3B79015B04B,48F657D4D23EEEE8,00306BB51A119CED,FAC8E0C7D1FD16F9,A5F74885A3ADD9FE,A401BE7413BFA289,7A1D87042F9F0BE9,24A1BFC691A80F77,06CDECEB3EFDCF0C,09CF1DAD4DC78874,003A98A81612C1CA,88E63DE8BBE68B05,079EF315AA710A9E,EF7E3973B18AA256,00345308380D71DE,AC293BCE0F96AB8A,1C4459422C24A635,072CE2840E64630A,002EAB603790FC17,2E6CFA4ED6330562,B4C72620D6078533,C3FF10B6C27B1D95,407064063E4EA60E,5AB9D52FAABEC898,BF3D6781BB591BAA,9F642629C6A0FE96,0009D2171035AF8C,382BC81C6CE829DD,E2BF790B66FE201A,29E9DB0239CF0A7C,C46C372A88CA1BB6,450004F3AF4A42F3,A670374503937FE2,7F0862D62F87D638,0026C523A41B0333,9A5F1B5B037AB9B8,F7D8029C116E66A5,04DA036C9119E29E,3D33A6CDB9C1FC90,4ED925D47669BA76,E8C1C161D7944638,F5050824807FFEB5,001C04EBA5791C7E,9571070ACF85D11D,C06F6ED84E66C982,5E3BAE62AF23A79E,C2FA5EB2DC7F04C8,20D7F027E85C293B,3EE156E5885BA918,9B91BB83C0C9A564,000B78CD5663C51E,7DFDF1007B73740E,73068A43BA2001E3,23E725C0C6E37A26,29F0E6D68519638C,8A1D1680F0D5B6B2,E1C565BD3C4E9EC2,E9E697382F96704E,003C7887C0E2F747,AE7232CC1D33D716,24EF5F29AF806C48,260B6F06A9C10D84,21BF899AC9AEEACE,836B0972B929C465,955067C2D073494E,C3135711ABC34C2A,001964E287CC9F64,7AF30672662663E6,741E5269987179B5,B7432CCB1E2A57B5,F9A3BAF044E425D6,E3B501EEAD2DDC77,E7B99D39F7147BAE,5DD5C4F1E42BB638,001CC02883582723,C6C0BCEF97EDE4B5,BCACFA46DBEC5C1C,D86DE7792D12AADE,91E04DDD251B6621,BF4B4DB8E1EE46AE,B6A09A8FEA0B245E,8406A30F35EAB581,003DC7F9DB3FE5F7,D47A5EB81755D07C,73D703E871C7BB1D,E63A96E20F6BA5FC,0B0B37A1BC4EB88E,0F0575C9AB25F0BD,3BDC04F0AFF49347,B9934739A03C84FE,003A8CFD944DC612,2668F381FEA1948E,306107AD73C6366D,E5A392A97F8B91FF,9BEE5DD0BF9205CD,77677211C7274718,D14EE383E2F1D4DD,220A3FE7E49BECC6,00340032DA35BB88,349F58BF06B4170B,6D605BB5DF0F1C13,1440E64AC708B30A,EBF3D028D7E44C03,E9A78D66549BA9B6,E0258049F5026AF3,4E61832ADB9D65BF,002EAA323F20EF68,D15E521CDFDD49DE,1FF6AA347CE1068E,F081F45E862B8E71,38B2F3D321B22B93,C0D3994C36D6C354,4B6299AD8CB3C4DB,4174CDE376EE7074,003735BCB244B9FE,9071612DF72B051C,A455B92631CC6113,7F84CDAE05A5DEDE,AF302F6966FD895E,5F8AB7B7EF5D91DB,85B275BF937EC6E9,30551D30BEAF9EED,000D38049A931AE1,459EF2FCE92F8F59,F8728F73BD27DA5C,3C62E912D86F6B99,3C3279A680E6FFB6,BF2ECDC4AC840310,619CB26D84F22C2E,CCE0D57A3106DE7A,001ABA919E2AF717,E401BEFDBEB973AB,017A47CCA1EA2F97,05CFEEF6C3C4F966,1668D867AA6E9ECC,744F2B13D23AB9D7,D583BDEC383982C4,E3ECB4030C2AEE10,0006F9254D7F5DDA,4C00D7DAEF5BA76E,39C275C08CC4C09F,EF1925A77FD189EA,0BA4A17A2A2A5AE0,CC1FFE6EA36F2A21,BB066C0D15DC3B92,580E4FB5AE82682C,002E2D3BC1B3CACB,AF74EA9490901CE1,CFAD3E627B14CC9D,342A4E4CF1587040,9177B672D98DDCAD,57EEDC709C417E23,6C63E3409B8A803F,2E371800E7593348,00083AC48FBB193C,62768C863B6E15FD,433027AD54136ACE,9DF72FCEEA9900DF,2232ECC9C7F3E482,8723178DAB8F4DCF,046A7AF72F89BD49,8556CCCF0B90C027,000C9BEC4AB2D9F5,9CB1C0B6FE4A76C9,59060832C907CB1D,5E438B83B83627C8,D17662CF88A561BE,8B6BECF04844BC40,CABBDB7AC505FA0B,B5F02616E1B24A58,0019437A9DD6178E,4D99D29D741608F9,CFC605901CF04200,3D3CD57E704A03AF,5EDC57D149D6C861,93B54A43CA928329,3318619704CA70DA,5915AD2BD861F76C,0017DF146457C8D2,D9609C002B22C823,A512EAE5C53CB72F,B34A203001977F5C,23E4E3466A3BEF8A,BF63C5B276DDACA2,744611115287F5F1,F94DAD11CD93FA5B,0021B3AD117FCA59,0960B64C25655603,675325D7A9F30446,DBC8930E5A179F15,B09D6C964B240EF3,E99EB0F82EDD6A45,EB40A902350789D0,B92E48E87E79A9E9,001661C4C57488E2,305376A644DA038B,1C994ECB381D6D4F,9176D17A8EF593BC,25D1F7D8DA543974,7C6863752A7EB7FA,D9D80DDF680A8146,A9845413F8CFB656,0022EA1B7920070B,CB016C3BC6FFA72A,7A2DFF413B0C2F5D,861D2AAC028416DA,56E44DE3726AEC2B,DD8A23CC3A0F35F7,13510C1463527ACE,9D17EE51E567019A,00317BB85E8F955B,844D131F651D1FED,17BADF9BDAFB97A6,B7B393752E2CA55A,8C244B866951B27D,ACCF0855136DFF2E,4C0A70DB7DFCB2EB,296B593FBF95C40D,00208AF28398F3EC,5B61266859EBF597,099FB5CAAA37A585,661A2129412C3176,96DDD5790F4D3AE8,3A9CB684999302E2,8DDD97622C964101,B1FF230CEB0C9CD6,003068C405C07C39,07608DEB8FB0B02D,D45F0C6E2587D66E,29BF3EED40EF21EA,16832F4D9D464AE6,2A51D76B585DE324,9FDA9A0F36727FDE,1059E0CF69630C1E,00174A3B18D99F58,5925E75EB36DF360,3A16FDBF77FA6430,2C44CDFDC64E4240,234F68F094776D1C,809907994D8E5077,61D4AD0C87A3DC46,DAFBC313B79C4E9B,003C5F48BE63AB92,ED430D36F9EF0EDC,7290FA2057B8DC3B,BB8049A3A4D1D465,96425208CCF216F6,2452A02562ACC16F,07F05BA18F7B6052,6A56BBC77A66A622,00249A07C08DD337,AF99EB90520894BB,D6D8F943D0375805,97FE7F54789653D3,A27FCE0BA757D1E3,76BE7B2DEBE3A832,FEDBC2561C89B9B1,5ECB541AFED86C5E,0030E51A804E76E0,AB77A09F2DCD6B5C,009D3FB468BF2427,8001E295BA153257,84F495244E6D3891,DFCBF48BDEF97207,591380D47467FE22,E15DB233D036CC3F,00177E9F92F817EA,1A802BE79A51ECA9,7F0AF6679E61ECFF,6D27E2EC250C0E38,1A87D43783EEAA3A,A9334E9C01A5E776,B85277793F833225,9E035B358DAE70EA,000E6F09CDBC1E8A,F18C8FC57BDDAC9E,8F35771723A311AD,595534492BF0FF97,696E14A71CD303C5,FFC16ADFBCFADBF1,E20E9B85E9BADA10,EC0E35D86C84FB28,0038D629B9A08F00,72FDA85909158D46,DE8024AE3D3A337A,33130337EBB05769,FFB20DDBFA459D88,57098FB517B4149D,5C591A05EDA84F53,8301D65E98CDD0FE,001E8B1141DD0DD8,19C9A86C08F6F2CB,C975D29E731D6017,D75141CC31D8AF35,3CAD1E19FA22DBAD,28ABBE1A74EECA55,A10628C89A674BAA,766412C97133BF2B,000CFEB7E325A34A,9363356A53DA44CA,8FAD62AA65F7B5CA,F6E4C75942133415,3A22230F92B4461E,C614074143FE6510,3BC4CC60B38CF9AF,CDEC47FC4DEA98DE,00404000F822C70C,D3EF08B488EC2472,CD896CA3BEE9151F,CB905229DB125439,EA6F55A4D678A5A7,7548CB88B50A57E0,C1810D0AAF2FB281,4FFF44448329F208,0030FB67B3F1A0D3,F9EB39C893FA42DD,BD400D138DB61C87,D987DD1E4A97070A,90A464493FA812DD,AFABCE6ED7C5A1C2,119C5284EEBFA362,9C410D12AA6B7CED,002BDF72D685F33E,9FF15C7407E9644C,C8ADC6466CC9365C,1CA864D95884719E,2A7E60696D5416AE,1C82D9216305D9B6,7F2043277763CA1D,B2ED136A82D22AB8,0015A94EDA5C53EB,C33401D46AF4A36F,F8F700C44F1F3F10,05E7B17B150C1199,BE71FAA3F1EECDDD,0AC884BDB4E73F9E,67F9026AF656D120,9F63932FBF0630A0,0011DD548F9C8642,D98E06941A2ADD8D,63AECCB43403E4EF,53C80F2410441112,24E91BCDBFF9D039,F745D3CCDEAF7E97,7A1379379F470AEB,FF1577D9BA64542F,0005DAC3E061F14B,2DF10E6541C166E5,B2CD4FE172AC1A74,938CD7F0E9CE2502,0156324CC0BC866A,95A51ADD17A0734B,761514CBFFAD9FFB,A7108FF626F49CD1,0032F4053D86249D,9AC4A5E521C85439,B9BE1F75EB7278F8,17A3759FD158A92F,98171A1D2B0CFAA3,61AC70881F42D054,08B57A8E9F68EC11,B7CE59C0B44A1530,0009905D095FAC6A,B64192CD90D8B5B4,FAD569F06C948D9F,1567D94C659C6B9F,B11F56E3F8E8243B,B9FCED850021E90B,AF5E8338B16FAE1F,D9F9386F0D253803,00056022DC59516D,EF2258E546DCA9E7,87FFD96BB7B8364F,B2BD5DC52865508E,7C22566AA43D5F26,5A5A37A200BEB83A,7676A0A9AAB7256C,1B5128FF69AFC9A7,003748E007D6C157,343CD6CC92F3792B,6277A55B66C9697C,7DDD4BF4B9500B87,4DE0A0A080554EF3,6EDF6A71F9A14E72,8FD50BF1831D6A5F,39E4875FE48BBCBE,00244FF6A96861ED,9C1F4178500ABB02,7041F2B4F99E570C,92F3C5BA697DEA3C,3FCAB4A6FEC19C3D,A389CC027A34CD91,7BAA94D769DD44D1,15756CD6970370B8,00364FC16B615885,1C910DE15B6B71C0,D196F5BD2105618A,B9B3370DD3355C52,3910663A09BF0838,77A3963C170FFF8A,D5172AF60ED24951,1966E3F64AA63A73,0031AA05C1D301EB,5550B59D0BF954A6,1693F5D25BD64F70,02FC4DEDAFF3518D,E932D3CD3BE28671,AA0881E31A613625,32ED86E23442E2D7,6B5B1E99B27BBB4F,000D3590C6C6DFCA,79DEFB2D6C268E9B,BABB50A0A64FD8F5,48E5F173AE2693BB,C5168D80FE1ACE4D,2255F10857D48E50,21B037C440BFF82F,90834C9603B47FCE,000B6F48BCD833CD,1D5DB2A1AAC89E6F,6156F013A6CBBD59,BAD7DFA91DDDD42F,519D2D46ADB2517D,6A0F03D4EE53D944,98FF62BA1C9F6884,DC23DE7BFB75541A,0013231C1D79F17D,8DCAF5BB48A9785C,33D0CC6DE9A0C310,C2447415CE75D37A,FB83D69B6DE9E2B8,8621CE2EC8E9299E,DBF762A759B93533,055E3888660E48DD,0036D3FF8085D604,200012C0D9FFB0AA,0FC9BFC3734BE73D,284003A5AF299F9F,DCE2E2FC170ECCDC,C3F57A60B7AEAFCF,BB9ACB169866576B,9C84D751677455FF,002CB40675FB932C,3A47A7525D351671,DAE3C027CA2B4C24,7F22DB5CFD7E9CF6,8013CEF78EC8A32F,41D5B49404C3D908,D0388A82BA4D8DA1,FBD6B3A66F26D440,001D924C282F7BA3,8346DC9C8B5094A4,D5B4EAF514199648,EBE6459F0366FE00,3417DD17535B6CA5,52D2C211FAB6EDAD,83337D9ABAC19609,0F2666019FA51723,000C52338671183B,D6608CF67A26B770,08676E77043F4B7F,EC2912830B6B193C,B656871058486984,D29E0052F7C20AE5,C8D654097D4AEBDA,4717FBB2502B4702,0002AC7F1F632551,442B175D5AAF4E6C,22C57C9466539E3F,D88F26922EB035FD,E5994EF5851B5AAA,CD2A91F05F167F0D,799984BE450314DA,52DB3CD27154482C,0020C40C669D8858,EC85E73FB59DE607,A3154F6FA6B74CF6,5C61B8D5B3A21D30,444FA85F6CDC167E,B41264C66BBE8669,6D7F846E49DE7172,640BAD9C23F3BA9D,002EA3490EAD8089,240EA277B96C03DE,BE492C0E09B19005,46ECE397B26342C6,80B4245CD2611FDF,85ECCCB3CF5C01E9,E5FCC40698F13A60,EE2E351DC8B8395C,00318DE3F36EEA90,EA37FF75BA408009,285D7600DD3D1122,4C8ACAE6621B774C,CD100D9FC4310C27,744A86FEE4194FBF,3E208EA5FFE4C29A,B10A97C6D2D46AD1,003378D86BD6374D,DEA5328CD029499A,DC3EB186E44754F2,D211D354A4152F2B,1F8E98E1995FAA7E,F56905188A99E382,6710392FDD92F450,5EB5BDA8FBDF0707,003C5F858259AE95,32446C38F6EFF481,25021D5B8E7A269E,90025F29394184A7,9096F69D36934C67,6606CE1DCEB024FE,FD8624050146BD6B,2C888EA7CF8105E3,000500744A067C20,69D9028B5AE7C2CD,FF0D9FE4169F6EDE,9D5D30946C31BD8B,3E9A7EDE7028FA45,1A609C52C5543433,2951E5EF4834C09F,957D0256B35E940F,000E363CDB4D4445,A89E4973E71BEAF6,449A37134CA8D718,4EE9D05F2C1DD3D8,A6B5FFD87330DADF,96554037F61A6D57,FD35423976DA81C1,65917A7DD7F2C688,003FC1C0F332C058,E7DD9E2A80C944B5,A1696BD52E516546,1B1EE8AF1C2D5A83,B691E206BEEE102A,39A7EDBDB8D57C68,E076DFF1639CC084,4972A4DDD0B2C6D6,0010648F3F5904C6,ED7D0A386AD4E009,342188BD68089289,D159F338BAFAAFE7,CE0D86C5DF52B87C,A361A79A196BC882,8B414CC93B60ED16,A8573C0A7D9BB746,0000808C796B3BB5,D87AF32EC9681DFA,33C6B9D9552B295D,EA55B0BA4C572C66,36208F17980155ED,5C2B7920ADADED3F,76AAA00DABBCB0D2,9DB4DA9E02E2E0D8,00370CAFCDC4ED9F,C28BDD92E2A0304B,8856B7352E5069F7,0F7BC947D2DC8754,87A8D09FFEEDB1CB,817E011492B567DC,0EB8F6BA96BF5D8E,66D5BB006D3AC3D4,002E88D6571D12D9,BCA27EB87DD93EEB,DC26176F6AC4D918,9D71E50E663B97E9,70489B6052B33130,62C526D7C3A562E2,6001976DD160B333,E3EFB00E5D5B544D,001FFC9A63AA3F81,A0196B6DE99C254F,52E1CE0CCE403D6D,080B62A89570D109,9A63F02E8BD644CD,0B623F6FF187D565,0EC73B73670D9F76,966F0187831B89A7,00111CF533F41B27,D4074BC503625F5D,974A12E33A6A5392,759A0334F39A5D23,5621F697570A9B7C,C3EBB31180FC8E64,37C4DCC5D6BE1A96,C6D82D2886DC52EA,003F1A87D0083C0E,E8FD14AFB6D063C2,C9D1A7D46410EEBC,2F383850E08A3F27,7FEDD55EC5EE95AA,568C9F310ED2ED26,462512D0AF54536C,F67B076BF22B5DBB,0008724A2C9E2C37,4D0BFD2C218B3B5C,89CCD81FD136AAB5,052D6AFBAD07E9A1,090FC8C3690B4781,877ECAA6B46F7ABB,56389D5599E7544C,2E6E68FFA744B5D1,003338777BD9B445,EE9AA0F7A360849F,C3D725C7DEE17247,37670ACC85181894,C135DF30264A71BD,CAD01BB75452BB15,540DD42454C62CA9,EE0DA2CD06D7864E,0020C7EF11E0E831,7D2EEF85244689CF,79ED10E1C61C9133,A75F9583A7FB85E7,79190A9A49279D85,4BE160EB994DB7AD,5E898675AA1C77F5,5446FBA2DC58EA68,00403A76FE4E3A72,C3A3AF3E26A5ED81,8A54F30852146491,C21EEE78CE565C4D,23FDAA0225111F2B,D9613265BCFB5A4F,F98909A3C0575779,A07A829DA2FE5478,000694106E661351,9ADF437D4B011ED5,0DA1F23A14D1004B,61CD2E29C1CB5DBE,6917489388B440A1,FEFC249E3049032A,4BCC744E307FF90F,34BD10E0FF689DF7,0026F58B078663A9,4DA45F804BD21AA5,258BA99C25662966,B053CAFE6935F46E,1B09D51374F96B68,41856194A3F64304,392CFF5FF9DA4040,3E2451D4D21EEDBB,002590EC3ECB15DB,60A7DCF94B154428,22F45DEFD705221B,B3321E91B61FD5E7,EF48C2A9F8D22EEB,90E132251A88FCED,6F980034B0587437,AF47BDE646188971,0037E16D39A8FE92,32F8CED8DD13812A,8F672BC9D61F2B47,50F00F207DAABF60,1EC83C930D864EFB,2F7D97695781485E,38EA0D7C7C20C076,A9303D22817629B7,001BC39E45A233D7,98105FC76088E138,61A2CE27873F074F,0E5E18BA0975E3BD,F387C628D8E4DEF5,250D793F87094DA3,E20AEC4313194864,611BD2CC2E3EFC4A,0007F31468FDE8CB,6EA967826DF55AB6,F595BF879C247E5C,A7FCB7F2CE95C16D,2538B9EF02DAAA43,0709748FF300F9AB,EE2B249486047C92,C8F4DC2D5F0D8F05,0036EB57E82C83ED,853163A062AE9D6F,A233663B2AF2CBB0,44412CEDCD4F2BBD,F695D99F57D145B2,728940011723F6BD,47DB09A684EE0EBF,7256CC391C0C3380,002EFBE9384CEB3D,F0B664F3DF7A89A1,09EF43C017B1E2D6,B0892F89F6BEE1B1,1ABB61F748B881CD,E55B4091A682A8B3,C704B861D83CB67B,B78076DE3C4C1DF6,000A6CBD44890D69,167A1D658B8CC205,1B9C6E7FACE5293C,6A7E6D00E0856CD7,2D7F575B7E61840C,30F977BA92C63F0F,BD3519F74C9EABD3,1BD263BF152E79AC,00064D531C10A27D,0BE96464CC18E408,73C777A4B6F1E3C9,809BA9F81915F273,C51859E1AF537028,9CEBB22338600183,E2197753D8077471,F30ED9317092753B,002209C1A4F7E26D,A3099EAB509F7A7B,90D4B3AA7C2BA4B5,D99DA1640A4FD24B,B055D34F44C7580B,E7A1610B4EAA730D,4472E6AC0B465CF1,1574742C862A408A,001158DE21FCF46D,46642FC39216911F,67343557001B90A0,B76963E0DDC1DDA9,EFA6976E218942E2,D16C1EE479D33B6B,1DDCCFBE9069ACA2,C6F51D6132D66A33,003F90821AF7A031,E3D65763522CC01C,D604EA81A1A3549B,53F4FE98198B98AB,DC02F7FBA1C70258,22BDA77DB181EFC4,90DF4AE8C19A11C6,6357C74DA12326BE,00391B58011F064E,9CBA907FA5F1F8E3,E245EAEF447B8CD2,AC31DDEA5F263A51,2D9D32EBB2CFC00E,2C73B296B25E5053,6BC920C6CD60B7F9,04250EE3F2D20CA2,0036F15B85368EA7,B7DBF7A50EB2CD4F,50F0AFF72F4708C8,8E5E9F63F5EB24BD,58ABB878CACCD82A,99F32844C96A5D3E,8EE134FA05AC4D43,952269BCBF958C7E,0026CD3490241B85,5D52883211E38036,0ACE03CC3BA7F247,72C1879140398C6B,EE4CC41693477875,E5CADBEAF4AE8947,31E76E28156F3C58,702A4C5512DD197B,003B18F714956C38,170F0CD5DC0268BA,B7F12D922EED0568,F61012A850EAADD5,5089BC3BAA894774,C20A097DD474B530,558B5723BB808B01,61ECE17B8FEBE029,00057E4D65812A9D,38BD24366271D004,C3C993DDD22F9225,BAA6109459612623,2E6C835C64532DBD,04DE86BF3D4653FE,019FE09764842F8A,7EE42CABF2D4DD03,002EE70F63AD2510,C292CD16B6C8D3E8,FEC549A17989A2B8,6D369D8E230FCE9A,4CD91E9CB16955AC,70D07AC21E124027,E69735638F877DEB,38A61A08450A837A,002C6109E2033AD0,217FE648A970F2D1,49980C0B94C8C141,E4E9F9F0E50A7FBC,BA4AC983C57169FF,71C09C0E4F53FBE0,CF9199D0C588BCD9,C16D5B6C7C4B5D07,00388D7AAE448970,A20934F3B3E02EFC,9FEDD917C780797B,1ADD407012ED5B83,8266C9975AE98139,ECEBA93EBAE4C17C,8E41A22472256A8A,A4D60962E22AAFC4,002135A9B6C4374E,341BF8B0A147E713,D5F2BFBAC7FE7AF9,D58B53C61FB768DD,A7C56BAE84FA7670,3DF7093A37AF4736,B6DD3103D98D200B,0925C3810F442C56,003A45494689A327,176ECFF23945B954,17E231EC9DF46F39,8671758EB2B54305,804D3A6F2FE2FC1E,2444D047586A1147,751A7B49E7B76A7A,590354C5C7A6BB60,0022EA9ADBE7686E,54C86F8A5106732D,45D2B986499630E9,78B975AA44B25936,D2DCC56661219517,A05CB1EC5A064C23,5BD37D1AFC74BC63,8358A2550AFA97E9,0024013DF0596D58,4E8CA1ACE7B002E3,00F12C01DCA19589,97FD82255AD6FD9D,0FE53AFB85FC7A82,F73F7D539A31492A,DF79DCD88F87F945,87F01308E5197D18,003DA516D802A7BA,455581D561E08DFD,A891820C0E6DDABE,C194FE678A69E1D8,23C3C80BE8C1CFA1,84137D11FA87DCFC,E81273AB925DBDEE,2960064BAFD50638,0003CB630835085A,FD5D1F7556B9CD0D,2403350C3128BA88,F2871210CD6C6A1A,213EA90E6E8F5B30,0E810CA9437FF2A8,20FD1874109D6C5E,D4223E58E7AF4D49,0020A330786411A9,B7AC612DF4F9DCE4,F009E44B38771047,625E5FD1D64FB0B0,2A82A5D12E17A38D,FB729C8F4E7413E7,CC2F2B1CAB243ED8,4A3A1A1D94D8501E,001D5BB2ECD2BAF5,AA8A8E80A90CFDFC,81D3DF5CBB24C334,70B11421D4F73542,5C77175ED4FE7097,842608676547EBC7,98B6D6DEF16C7CE8,63A74A3F05C20A7D,0018D0C4EEE77DA3,500921D972008A9F,FE07ED32DE6DEABB,FE48C7045016CC05,2599E0414946E987,E28432BFEE0FAAF8,23A7605E69757FBA,461FB62E08A5CF68,002D12B650977912,D840F2E2036C1D6D,1B4827AE3F8682D0,7874B2E051A530B7,BD274720B9E3F695,E3E604D5DB8044BC,87A8529808DE7DAD,CBF2DFC7AF6C81AD,003A72A2AB3D2063,5B4528387BF54E5A,177EA9BC5D06084A,7A9187E26AB2C55B,914E89FA146AD3B0,918367103FB8380A,AC2DF54695367262,79BE05F51F900922,0024FC41249593C6,FE1E348C548D1FBB,4D1F494D84B6E209,783F4D0CCA61776B,718EFBC56BFBFD44,0845A9771507C32B,D9E784B9FE97C6A5,67E578D017EE8001,000E327E86836943,F105387B22C9CB53,5B2A209A2F1AF22C,EAC05BD277A57C11,C606D55E7757328D,A2DC254D87074F9B,CCF562A6CCCD9EFB,75FAB83CD0AD7753,0012D0394F9630AD,FACA6CCF9352CD4D,87ADE27749F122AD,E18437D846CD2C8C,4A2F97E56A78C40B,02A3CEFEF712CBBF,1D0DF05A82B1E757,923B71ED4BCFF251,001488DCF2CB1C5C,98E9E25251D92337,34F335D14C2E1F4B,B580A5B08EB06E8E,80ED862D50303CE9,640C2D5DA7B044D8,EF5E3F9E31867351,FE2D1316B7602F35,001F9F69F88F504A,E56BEC3555DD3462,01740E4805ECB2F3,988B79528F293E25,C1241C4A1ED39175,5C88A509B8293531,109893AEFEAD7F40,0FB01D708E396C61,002AA3B03DBE2DD4,A2FD952CFFC9E131,E550367A5DBF3E35,FC74EDBBB7131AE8,469107EDD469E671,FA5AC4ED028292A5,5FAD0E21880DC956,44039E4DEF65C6F2,0032008B44D4DAA1,B32938C6B0E7CEC7,001DBD1E4EC1F5B1,B8EDBD5E6A6D13BB,396C413040C07ED1,B83C4E8B28AFB348,0C457FD2D4D6B9F3,C60DD8FA3023D29D,0025E4B40D0991D5,92F4A78E7404DD2D,317CD090AC97DC95,403C6EE81BDCE582,D99D853C40311E8A,DADDAB5EE48623E4,DBD3095511ACC9E0,326AAC09A2C854E7,000ABAEE4B50520D,4BEB3913B2B52CCE,01E6DC029CABCD19,DE5737C96B2F3187,C5C79A3F0C35A03D,ED430DF88D2F79C7,F15D9AC880717E75,D88F6DAF4A3D57BC,003C7D98BB289D5C,7FCCD66402764ABA,99B606850C88F366,2F225A3BD71BEE21,712996BBAA5E3EA4,127B3BC4C9B6376E,639A03EC96366624,9E74A5D9643DEE4E,00190DE33EB3FA72,7F71D0543FAB4D1F,524C6B17173B11CD,763F1702760140A5,218434E9D7C6AB87,21F38C0CBDD06FB2,E5011419C1D9EC8B,DE3166CE2766C8CF,0039516A2B4C6EA4,FFA448F01C774C73,29C4F8A86164BB2B,456D7A305F6EE66E,2C4833DC199FDAA5,D24977F0FE15DFAF,D7031C875835D904,62E52FA237FE3BA0,00248197F9C24D3F,A46DFA2151B95E80,D3ECD95785A72094,AC57BD494987DEE1,78BE54A1031207F1,665972AA01E58C44,83BA717D200ADE0D,02C11A0D91EDE9A2,0020E0500FA54F6F,69C26E948AF8A445,DDAFF992BEBE60F6,A7E6D64582A7EB5F,080E87F9D0E627A2,6B76E37CC0333159,C354637C2D8081B6,D7666CC743498F0D,00173C25C722A6DF,4BE703F0E0577C26,1D87059D01C0A8EA,F94FAF4B8BD4DD7A,C0D29AFE57A58093,2AE9C3EC94922A12,699141ABAA6CAA14,97926BB19559594B,003B2C2BD72D275D,2543F8417E166B2A,7C9B9069943BB5CC,17B59BB202BF6A31,0FE3F01A1B99220B,16A1A83537BD7C8C,ADF1ECDC1660DC3C,680E29BB198EA1DF,002F4689D59968DF,DD002FDAB113F1A9,D789CA6143EC5B9C,77FF83A2B2BDF189,BC7324705F576A31,C374A0623C85EAF0,E6FA24A23628E859,9D5383FA1AEA70CF,000B3BD9A2D4248F,67172249DBC26824,2019F6B22ED95302,00D4431ED73003B2,74F9756BE0F07D02,F7FDD5E9D179D668,D2F7EE3F76888391,747B001640EE2BCA,0008E48CD82A18E1,DA210C4DB9FA1EE6,4AEF8EEEB19198CD,E8CE72A645DE6F6C,53399874379F70C1,1D41582D5BA1FAB9,D5B03C20198B0660,48E51FBA742649A9,000459E29BD7FCAA,D3BF28C793013210,43B9D87E9D3C7E79,DB9707BEE52CA347,8EDDC8529DB3FE7D,0343DC23B4D36166,EFBA8A76F6CE6504,75F1C2A28E9A27CF,00231D0A294C9737,C64441C2832DA237,3D2D48C41D0155F1,5B2E2D695FE2F5CB,C2461E14DE37A74B,A347A586B79BDC18,2A9C073A77EBEC75,32C119EEC0C12789,002D78FB221348A2,F35EF30D280C483D,C41F2FDB9ACE4CED,E76CEF3A90E5CFE3,B849FC4650B3D7E6,17B16EB1E2DB6E43,FDC0E9003D2C02AE,D7CABA98265AF9DE,000B383ED074EB12,7A4B6221FBDFF48D,801BC8BD155C7761,5622423CE12CCD43,488CEF194D601615,4B3EF39C028B452E,25F0EA3A78A145A3,BA3F248CA86B792F,00050D28E39F46DE,AD3D01B9C34E58A1,A26EF4CC1F37C221,98854FEC6058FA74,1636AA22AB466864,A628990EF4C3DBAC,E0AC166C24E00814,002BA9C53B8A624E,00368BB9634E5B68,BDA2652611DE12B4,B077A9A634AF0399,D5D863B75E3FC36D,E6767EAC232E64D1,C497ECB9B93003CF,F18037BE64224DE8,8A11C4E657D8721E,0029E18D0996EC12,BA1C1F5960A5AE6E,C88AF60167BA9A57,190856625D5D708F,2971A0A151A39CD7,24D721C2357484C9,CD170BA51AC9167B,DCDC1C6ACEA480CC,0001F0581505F4AD,5B13DE9B1C162A09,DDB51EA11499DFF4,26A837761BFE26DF,A33AF690A33C70BC,4BC55524668C2010,0A38CC8167CE95CE,26162B15516757C6,00254F5AE26D52B1,B27B88FDDB0CF7A5,DFC542792DF3D638,64F9D767D668338A,1BFCAD0175133A97,ED2B0BE48C6BA5EE,D9A7424280736A79,379B8D04CB047EBF,0034828619864838,6D070FA9DB792179,DCAE655FBA25EAB7,5FB0998F39BFA8D0,F64FFC2C9E2C658D,C7A6159A65CB7E19,CDC02BCB635DA8D7,665A2FAF0177249B,0032EFFA9E773B7C,0C1443E1024A71F1,4A71137E4DAF423E,8B710503F680AB74,84F6CCBE2208C852,500CDA6A1AD3FB48,F71E73A23793EBC8,6E0E467D0F481250,00395AAE34DE8B6F,28E63EB230B76186,17A3442DD7F4F90C,79C21EF8E229838E,FE5D8504A6821C26,7A508805283606B3,663AD7429AD9D4BA,BD22769BCBD7058E,0029D0520F7FE57F,BB2F7FD1FF545F81,2D92A83476C6DF07,5B831EFD5CC8BA9A,C7FF667A313403F7,F6A7F47821B699D8,20DD7EF04F130A07,1A5660FC611BD8F6,0026D09698F3E614,56449510ED252686,C97ED2DCBCAE8EC0,A1481B91D32A4687,CD5838584AD5309F,9FCB3D2C365AA033,97B9859B389C6FE9,B7AC2FB674B161DE,00112EC25C06EA4D,F789F2FED3C88179,0BD996489A109616,16CD9880C7E857D5,5AFFE18C86DE082B,C072661D6ED8775B,0828921910E87DF2,92394477950D2C00,002483042F7B5D0D,92049E0ABD24FDE7,9C8D35D7DD4CE4A2,477C11054861B059,BF1F9658FD47447C,73E414400BCF4E34,A64D7ECD4E91069B,98FF07D12191AA20,002ED753A36190A6,0CF732AE643C79D3,0F252FA4E502EE6C,726E9DC64A97C533,1929B42A5DBC2457,9E852A34EE51BEE3,8CA550C7D427241C,7631F9AA9B18071A,0021D2853D571866,0DD8658058321C0C,F52E93708BE953EF,25FB4BA92095F22C,BA1BEAD9B4B0C750,742111957A5F9E92,F7F44879A5420789,2D9DC1B31FD78570,000178269E59A1AF,1A8239C6C5CF6F60,45BD32C05D355318,D5B835A680C3FE86,1471607E6A2A0E14,4359D29AA225F5F3,7F3BFC97553C1EF5,063276697319972B,0026763693C9060D,E03875249175D09A,DB400F5EF370B6ED,ADFC102CADB8F68A,5A09339E4AC35E8A,052EE039E06D8091,70625A8022C46EC1,DF0A8E4FDE476CC8,0001CE9C61B81E35,795869149F9A7E0B,BDE7DA61C702CDC4,ED010F10BA69B2D0,ECE9B110F7E3B243,3FB61DC51B42FCBA,9B08163CDD0F61A4,9D08F8B30328F771,001C352D75B2690C,E09FDBF87D89AC57,096E546EA9779A74,DB4A66631ACFD612,01B7B1369C2A57FC,C6D1405C8832E2B0,AB786B91842C3B3F,00D97340941D7DDE,002D6A60C729A9FF,A75937EFF674DFB4,EE012A41E7865B22,B9A11D20ED6AE11C,CFAA252A9EB57DC3,2A869992A5AAF47A,7BE6D79B84586D80,716B0965E87DE2BE,003E242711DC7EB1,1ABC23F3EE96D460,8A41E32F204CE679,A90E86E964B7F2FF,6D292BA20120778E,F6414EC5602E4321,15408C7A4FDF1D84,0C1EADAFE4668BBC,0031E1E7A54EB2A2,AD4A7556BC0DECA6,786CDD9F07F005BE,60A50EE487034396,9F657892C39633ED,ABD4514471214DFF,BC75277FFB60249B,A4ACA039CC84696D,0039D76F18A9A37E,FE8CA72F3A6CE92E,90E488791F4005FD,19A4EB1B032D0FBD,135C2F79158DB2AB,6273F25EE1AF1CD1,8D4F0DF78FB75535,587EF614705BB782,00264D5622D7FE15,2F95D4EFE70C6F8E,288536F6BAB07228,6FB7DF3A6A7BBCA3,3032A08DEF4D6A8A,78823BE5A19212DB,C4609A3FD7AB686C,81129B85D088423E,00137AA317EF1D50,86C4D5EBA568C954,556DD17D6286D687,1C7BBC965634F830,F5800D383ED54013,5A89D5CE60B0FD22,0AC5755CDD2C73D7,A05D9AEB2C0BBC09,001F28F7131CAA9C,3FAA4437C8DA349F,9365C2B420897C52,5C23736BF6505915,1BCC77A51253775A,7AEB134CF9FEC995,E07C170DE225803E,EC69C0AFD88DB209,0003C85839DEF937,AEAD00800EA3A4B0,4BB578DFAEDC28B7,EA15E9662B99C4E6,A3EBF78065D233E7,89E35C24A1443F55,FE72DE5D8DB91BEB,F7465155299D180E,0017F40D9047629E,9CA79FBCB3E77313,5CB8D41CF06F6937,FF114D8682ADFBC6,7C225EA84ABC35E6,7C19FD7FD0F5CB82,AC07E15A636CF0E6,8969D8213199CAB9,0034016BC3639479,8317615E5A02AA88,AD65D6EF7EDBD27B,E9408FDA7A83E8F3,6D13D8798BE3DFF1,FFD1A61AAA46121F,7D15904033B01BCF,425F8170CCD4383D,000ADCD09ABA684E,0976DC943CC7AE81,9A85487898FB1562,C882FDF6773E4396,570FE32518F55632,4A53D8B5F75997E2,3CE8C192504E4D7D,4940FC59A816A843,0027678FC9BAC93C,FFF4C018FBBC8EF2,79F3107512DA9D67,1B5D97F498DF6EA3,30398B4B8C59E7DF,25C05F9738E78711,3464BFE7D5EBAFE8,8B7951BD6A8023DB,002F0EFF1F9E3738,D2B9E87C06F94C5D,97CD2D71DB6E6D85,E9D269A91BD0522C,F1BB995A5B95E37D,F600C0009169812F,5E74545E3C51DD82,A61047B2A53BE107,003F7D324B0DFF21,92CB9BC2D9F7F609,D7C25A2CBA1775E9,E67134D6226614FC,9A13C4E091EF7370,F947834A9E1AA315,69913D47D9AAA608,28AB445551B65456,003EB24E881145B3,6890FFA9D2F6868A,820EE1A42E8F7A64,864C4FA074749D76,F58F64AAA02E418F,A37E31AEE8BD26FC,F81F0CE05F527F07,63AF8730BD12AE4D,002847AB0C4C425B,70BFB8C9E59FEB9F,CA86663606F12107,079E5CF89AC075A2,043D20A4ADB1FFD3,280CE9ED60DE07A3,9D80D6EA87EBEE32,3EEC0D48CCB7EA45,002EF661BE040E9D,7B3226806D0634BE,9FB32594FF4BC86E,131E924B28FEEDE9,FFC0124FF7A067D8,56388397A51186D9,994DD2BA55C9698F,751446197C6A2E2E,002536949E1D3B6D,45AC6CB3A0B643BC,081F66B1D17BDF40,5F39F15E5D715D17,AF7CE30B6B3EA443,7FB884BD06FF7225,019436967B60607B,459B4B661109EAB7,000E3FCFA88AF971,A98E581D553CC37B,789512B539195BB5,CCAD81816603611D,AC219DF3D5C7EDA7,E4CB5072E4CD3CEA,AC8D43CF7B3AAE34,0B2ADA5B182CF1A1,000C267370422AC0,10D97DD37C8BB3A3,5EB30C10FE3B7D0A,2D77C62A6F83EBB7,8DA66088E03C3DA6,9A6D48C929E4D77C,CAB8B78F98D1FB3C,5141618C6E741C81,003DA4E09364839A,4DD3333E1A5C542E,929854A193073B84,20D98D04DD312A8F,F16DD505DE0327D9,3591C5EA1ED96FBE,7A3D84AA30D63E6B,C8D79E537E073F11,0019049F72B208BB,59AC208B47A1409A,FA8B782108DDC170,5E955FC977622A1B,F97DCE4BB10C971B,480864377D0B0CF3,BDE9B6658AE436D5,854E3E67F9CCB0A5,0032B6FA7D56E15B,8722833BB0221BEF,491E115D8680362B,11BFDD7DBDFFEFC1,A509E72F4EDCFE75,A97756EF79B6D30D,32A170A70BC39186,988DB3545CD51705,00258A19DA388CF0,4484361BE2068F03,CCFA09FA79AD898C,549F45593086CEC3,BD9B0CC7EE911FFA,D5B7A2225AB87D7A,146364B7EDA74F3A,6BCA893B69761846,00209FB17569EF22,D8A842348B40A1A1,B64AA32E488FD4BE,9736CC27C24F669A,51EE1E0ECA025496,432E9766AEC6723E,9783EC3BEA2C805C,F9313210BF5B5E90,000DDCAE5E79E800,6420BC74C1F63ACF,F93901B4074C4DF3,B98EE11559F2F4F8,065E9B592F07F303,F63081D1A1612ABE,6152D2FF07CC39BF,96A2B6899991F2AC,0017623A39B6ECCA,3F5648131A7BC568,58B34A4E8F784534,CC219E1A8E41882F,8A33C123905A094F,508A559FF58BB7BA,57CB9D37CE2B0665,F7D10190B2F7A69D,0031B9D48885D7CB,85195202FB447E83,CB3E13A84EF1806B,009EFD0D8DEB7FFE,74BCE6F0561E19EC,57AE04BFCE2CCF62,CCBE3BC48B0FD68D,E6351E43D710FE44,003467F782F42AA3,C22AD70BFF4B7C2E,0F124449498F93C7,8285A07BC98B4059,477ACC9DA832015B,546A35528DB7700C,8B1E147292F7CF2D,B605BD122979F9DF,00035FBF57624DD0,1FE5A1CC37B5FCCB,BD234BC4893F464F,FD102044835AF164,3E0B6C431757CAB0,BB3B3E9FE68D745C,0D1D20972B0441D0,85E29CF056F23ED2,0019C02CF239DDE1,8E6586D8E2E50DFF,8BAACBD5464DA876,615BDFE10DDBDBEA,8B6D6ECA684B6870,D512BA6638E19FE2,5CAA8D4F2713E6AF,62767E0624576F0C,0006864D2BD52C4A,179B1AA5C1FD15DF,84E6DDE43A4A1F11,311D4306B648FCB7,265D64C01E524F89,2CBCD246E72EBC83,BFFE6CB3DE42E7D4,B424361672F850DD,002AAB3050E70139,38A67E46EC85CF16,348EC9481843BD85,3B1333824EAC494E,E89203AFD76D16E7,B91DA8CEC763D2C3,6836053F592CEF83,B95CE2DB40D04F96,0005500FF136A520,0CF0BAA2044AA6F8,7756339CF567E050,7C01CEB4455370EB,C0946F3C561DC02B,6C9CE4C36DD78CAA,DD4436D8A5FABAFF,18F27DAD2AF5B8D0,0027C9FF9FF2297E,927D05A6EFBD0D88,0D33CEEFE4CB8D19,52D213A0C4C6B4F2,1A849834A3B8C7A7,559812A80063FBC8,58B4FFA9753BE13D,6174BBD7138AFF10,0010D47467D80A5B,32E1392338BCF785,3AD3BE87AF9A3D9C,E5EF41F907C4739B,CECDFC072ABD4694,EE843A5D1FC9436D,097C3A47B26A5EF9,ABC72F817A8E7954,0037A650BD7AF817,0FBE8FCE64DCC6F2,886EA78DCC3E27D5,45C8AB844F032FA2,D0F1041A566EF4D9,D48EB28FB234CD52,335E35C77E2E328A,2C0A3A661ED06B85,000CF2AAC4EFD183,D8CEC322D36BFA09,CE238F6E25BF9637,29D0CDF8F521DA0D,982FB6E9788DDD3A,75CCD040677AD71B,53BF5701294AE26B,948D65D12D916226,000E3617F5E525FA,3C501C3875A10917,2DBACD663FD18993,53AFEBFED674DC11,B2F0572FB92FDFCF,FE21DF2210B831BA,93A760FACCE5015D,CCE32CEB73DAA922,00213C9B2598C46F,ABCC5236D1DD1EC3,D24DFABE3D45442B,C3F5A17BA75B838A,9B75C26FDDC51827,E9B0FB764DE6A39E,59B0530508F70934,5B9AF6EB200CB4AE,003DE6045EBBB517,162CBE0420BFA917,61B9A85A95008ACF,6D7A21C05223FD28,EC235ECE8D957751,94A473411731919C,54C4972E471DDF87,4DF717D75A194217,002157697D7DF49C,4DF744FC1B0AED79,3EC951DD37C4C772,E4616919FC7F6F3B,8FD92A7A9099B703,CF6B30C2681B6FBB,6DE1B990BA3E6852,968352890C3C31A4,00327379ACEB59CE,A7BB6186373913C7,70104931822130B7,238746724DF71C68,ABF3D3633CF3741F,6CCAE1573E5BD073,4AF7790CA738D146,893D504E7867FE72,0018B522845E4B49,BDE9DDC074F43DF1,2B9F8D4080A6311E,7503932126607F26,E9BB32D5EE966EEF,C6797AD0C1AD1832,4140225A7AA45068,2B60B87D7D33BC8F,000C886088FB75A3,9EDA0F7F99D27FEE,10EEF2B0B76C3D7E,EC06AB8CA7AD4A4F,04AE28EC504BB34C,8744BAD1248EC361,50D7F98C8B6326AE,4FA748253E6DA40A,0025A3AD3F23FC33,DD056EC79BF3E69A,B0A7BBA9525EBC00,67C1751B9C57DDC2,64ED6A83B8053BD4,9837FEDF623F2ADB,36D20FB8C44CCB30,B0D4DDC3B2884A4E,002553FFA8B55DBF,7BFD73BE6D961109,43A4FE9488F9952D,FB914CD1C765B5D9,06EB87AD8671B869,B5F126F8DE407D59,09A13491B7A7766E,DAEF7020D3D6AE29,003D97FD3747D71D,B5769798B36384F1,ED515D13F223D1A9,191A6F42EAAA2091,D27B3845ECC9C532,E03AAED98DA728F8,EE0005712A120F0F,B3EE5515F0DEDC8B,003135728ED57758,B31A7BFC2DD8A6F8,647F13B047BA84B2,D7B02B2B81678BD4,2361E935EB64739F,3843BCABE618E565,E8CFBD36AC85940D,8FC5CA13F873B8D9,0035737FAD4C92E4,6933829DBBBE5243,2271A4137DEA8A37,5EDFF09D712B772D,718574C9BC969506,CE4B58685ADAA391,173C7D96DD0F810D,F4482D37500F84F7,000A20119C21B610,6659B159D237FF24,9EDDA5B103369CB1,E48685E5540585E0,3A9AAAC31BE1A84B,78682C0C4BD6FC45,63BFF1450DEA8C94,EF4D31B7A24D6555,00115B32246F316C,0D0DA92134E198CD,607C345D5BA64357,D1A7AEBB8C915BA9,F77EE93B6682DF39,D7032134B660B7E1,EE3BC71BB909F91A,14C06ED32C24E025,000FF6058712D7A9,90623A92B9602F4C,03CF8A84AFFE6403,81C085E8D0311455,10CDC6991FF0C5F9,D1D764D50215496D,D960795ABFC97471,E10D58EBF2E04C63,003E68E4AAFC93E1,C5C4B946EDAD3C22,F9C42DC5B5B7B3BD,7BF3D2FE23B41080,EBFE604BD5E8DA8B,6FDA1B02CE247C09,97FBC39D01B0A396,D738DE953E62CF32,001879E9F8901B0F,766F4308745EE6EA,D7ED835A6AE7E27C,D481B6503752FA26,B0A84CA362462497,42ACADF048F5B48D,73D2DEEF1DE7721C,845D3B6DF04B7F56,000A021BA1B5F5F6,200C5754970E94F0,CA5595FC778FFC1F,8657BF91D1CE406A,968EBAAA536F937D,1B1F66B6B8500916,EE3CD681BB1B4692,CE534B56E3B48550,00364D45CB535346,4A38E8C81DF399A3,BCD5F6DC6C7C2D13,0D2DB50628FF0DB8,C73BE2E4294A22CD,E3EA8242EE2D8E1C,7D3107524BFCED9B,07516DF406B8DA1A,003C69E5E9F2641D,D0853002FD81FF51,18EF069E18B765DC,4EAD782406AD9170,84A4F0219644868B,CE1F47E430956CE9,938F80221E9A8F0B,3168BA4608A00741,002D35070F28B506,0A50E5E4AC13E8AB,4C970D767361EB01,F9C6A2FAC3BF3918,41DD7D67BD6DDAD7,91293222271C2C32,F92804B07C31F137,008ECBB2556353F4,0024785369188353,88F728270F1FA310,F7C863506B65BE3B,AF897AAE884A687A,F1B5407CE94830BB,B747C666420230D2,3389CD3D7602BD4B,56D787833B3B84A6,0010851457F71773,0AAF8D6C4E1507BA,42BD7A5FBB8A856F,AF99D5DEB3BA35C2,4DD5F15C46A61557,0D693A4E67879B47,692A9245DFB44FDC,A76DA40615AC0030,00348F788ABCB68A,88D9BF8A63FB4557,526E0A37741548B8,B8FBD515FD881930,25C8C80FAC0366CC,C340C7CC9DC6D136,4AF7AC88EFA5DC99,EF2A2BE0AD7D1C55,000F014732C54EB6,73652360EE1AD9FA,5C57D76029F217E7,3CDCF9277A5AA67C,880347EF505F6C80,60BD8765B20D1FD3,A1C2A277896C4B75,CC20FB07AEA34C6F,002A3B4CFA66EAB3,0649F3037C358E1F,B165CD39B06D63D4,A680629BC32687C1,72C15AB20448BA0C,5B2D526CE881819E,ABF2DD55D34F4A34,C506598CE45EBB1D,0015577C40C98654,001BDA561505EB7A,E439C2D51D0DE8A7,9A41AEF083227BEB,A3F13624361C0FC6,9828762D2308975B,2B5FF87D1FBCA1C0,0090ECF895BA0A4A,003CC6456B2039DD,1DA17BF06D3C3EE3,40D8CC9BE0AC63E9,6865A739FF04E27D,F6FA411EBC52D875,2959AE8A38B7A841,1D105437FEDF3CA2,36DB8F7B4F1FD159,002999F0BDBCA301,5C0FDD6D6BC15AFB,412DC813A269DEBD,D12CCEC1E744F16D,09FBF5ABA5527FC7,0F083C0546566E97,B88D4B0EE1982322,4C9102E783646ACE,003670F427DBE95C,527FF04ACEC98F36,FE01B57F64120507,09864CCAFBADB093,01A5B69736A9BE06,85F5F83B3C478296,26C9AFB308A0E873,73D5AF69E2FDCF4D,000D29418257D498,A61382D30F9CB646,30597D47C0FDC5AA,027BF9AA3087895E,7010348778B326E5,81F447B97DDDC209,AA0EDB33C3EBE454,A9D206FE94A31EB9,0027218888A76B4D,F7357D1265B5E59D,35935D3A0CC069AE,126159B66E0CAD72,BF89529E0E1C9C31,3A948E08393136F4,808615C40204C246,2CD6717938A9128A,00323BDBE9B169B4,1F12A2EEBC7F105D,87DB95E87DA9098F,65B1DB61D3A42FA0,F2ABC2261E074689,E3D30F48CD4F257D,F115EE7F75B4E9E9,5E32FC83C8C1A93C,002DA4CE790405FD,8C948E48E62601B5,EEC0525BA8668838,CDF159DBE30F7F27,6B44FB9E6C79D714,84F89EB6698D645D,C4028B98F7CD2334,E626E284CA3161CD,00391ACB2DBF134E,B631DF0BB599B2E9,70DD982DFA6E4638,259C5A7C78B0FC13,B3244795995850B5,FE61828CF61DA93B,1E76559D7A61EB6E,DF2B99B27A4CE81D,00290EBF501CDDC9,4A9BADEF1280E509,514436A7F6DBD2A2,AA6D1128689EBA80,63AF632147EAAAB2,5BDE15F916CBA33E,D5C056B2778A8F9D,5BFA09B576A6F911,000D9A0E1CCF2674,BDBD5C6765E2A782,CBBFE58BCD3D4D06,4D6D0C4B23921DD6,11681AC0548A50F2,DDD6E930952223FD,EDF5A842DD06EDA1,6E1DFEE51264E51E,00405D5F7D2F3D9A,232CE566885F6606,340E1657D006FF4A,75F3676EAA29068C,CE86AF1E56E64F76,D3DB61B84D85058F,F72B717FF23D7361,134157E2599AE41D,00278872EC57E83C,26E46F1DCC671CE4,F33BB889A74E374A,3D14480C5EF86711,50BA74BBAD6A282A,A83D7614A34205FE,C68BAD9DB006FCC7,2C8AD123BA08571B,002757765035B519,62E5FC2253C1326A,40AB9B29F0096840,F45D4D3CD8263777,C3547909260D1C0E,25F2B11CAF5F6C36,49F353D151AD7D95,BBE2D18BA73B424A,002259FBEF0AA55D,90266951732B01B7,36DCCAB243B2230A,68E2DBE8CC116DF4,7F22B00A962A223A,0F6292B6632EEF3E,1C1BE5EBA0579C6D,8A861FD49E1348AD,002E8FF44B67B286,4CEA5C82525E1865,1BDEA36EEAE27BCB,62C5FF3831BFC14C,99C76D642FCF3F12,74B5EAD13B2FA6E7,95B58F2501BDA9D1,4C08217938173782,0039D77EB1E8E467,C75C58A132BB998E,64A97CEF60755023,A754743EF52D994E,DA996A3A12508C9F,E1609A0BC2696151,E438E23B3223F38B,2B38DB01A9B8DA6D,002A9A2355E1997D,02CA67699AAA9463,1D9814FCCA24B76E,5BD0BE13AFB3D0C4,FBD94AFA7C219DB0,26C47DF2F622DAE7,C19D8F4F134C47A4,E7F6AD4FFF5929FD,002F290172D18CA1,4149517481128C84,7155D260503C5797,8A30D64A448146CF,8F04AA8CAB22E7E5,0F5E454F03C45166,B380698E962A6ED7,883535C2A3B0432E,003B55E904824D23,92047680F975FF43,16D42DA7FA24CEB8,3D3FE45D42FD6477,C7F7AD59F77B7D70,1F96B6ACBBAF6199,4BB61158C1F5E68A,244D39C3FFEABC7C,003ABC03223C1C43,C82D5C0B70408E1D,B0CF82832C5FF5B7,8FC72AC33015C4CE,FEF2A6229C078C29,FC467472AC3DB499,95DAA0D44B0DD251,89A0C31708F9A91C,0035048C29BAAFF5,A2F0BE55FDF5313A,58D8184124BC3142,3D5967CB8D3DFCEF,30A5F706FD6C2AEB,23CA446DB9214318,6644A3DE8E6114D3,8D2DD2B16E3B300A,00003071FF6C070C,93DFA364ADEC5426,15ECF66FDC76742C,17D7EB73363B8D19,6D929EEF3AA03AF8,EAC675AE033FC9D5,5246895533C62D0B,91E6D01EE09FD586,000578826BA284F5,DD13ADE160CE3A27,549DE1D84D509FEA,AEB7AE44310B560A,5562B7B04F4677EE,DA5A1FDAE8144902,8E7A8A12F720B7DD,E7BA3263FDABD0E2,0016B0B2B59E8C85,EF8EBF0812CC664F,F600B968DB079D06,02CF40D19892E888,05BEFE9402214906,9F2E73F04DDCF85F,565962F8DABEB1D6,A5DC9F8F7D7AE728,000B96FE4535FEAF,BD3367C19908CB01,B6A6F49D98EF3CA8,CE28632ED0F53B43,354A932F7B8F5F52,21A4C61655866340,01E9EB24745E1460,566B169CD44DC8C2,000519136C995AC6,F085A05B64276D4E,6F5164E803C56096,CE38CFFD68ECB5F1,38C81295D678A14E,72392A53495229B4,3F682DEF16FB5586,A7FAEBD1FF6E4854,0006CA4FA4ABC0ED,BDB1D52B18B8B32A,6157FE2BFF78D7E8,600D682A1375744D,3F1834F06CAECAC2,C5C9B8FFBA34345D,6DC635B934021136,75C993BECE0F6583,0010E5FF8EAAC7A4,E9F242AA2E77843E,BB12F41EF478C99D,46B2FA47A02F73BE,034AB5D3225F783A,C688A0D03263A3CE,62113CE6DE5FB037,E59470FF8187DBA4,0037E26CAE787045,01B0EDB958FA6BA2,EB2468CB3EEE35FB,E52165D5B4CC6967,84DB49A7EA8E69D0,D3B5DF39EA46D158,81860760592D6845,B8C9418B09D8DCC9,000FB0040AC8A972,966609BCB0A89CF1,9309CC164E666585,6DB3A66B9FBDCA7D,C4E0209597DB992F,F2B35643CBED525F,CDAC6D89ED04DFB6,7990E55AE62D1D48,0006B399A8EB0BF8,70E76A618643E05C,21639A2F037F5763,B3AF0EAA49B36214,23DF3F4031D9904D,D20C33E0EF8EE8CE,AE15D35AA7948EC5,9B39F5AE57E4D0C6,000EF6A78078FA02,AC8C531516963BF6,ECB5F1CF9B9CAA2A,400BA047E25F112D,2151D18232DB720D,663C55D793DADC2B,795E8F2ADAB9E331,2B689369B6E9CDEC,002A06CCD70423E5,4BA6B34C2720E091,2D3AA414D19AE96E,926DEF0B3F3D653F,7A6360FA322BB3D2,8A05306964F7173C,A5043CBFC46E07CB,8F9173942BB37398,0017917880ACBB0C,742A01E192658A18,11D41E8ADC5DD0CF,05BD8D8A66210BF6,F2A3FDD692266FBA,87BA4ADAF9A55281,D5B998747ACE8E42,A49E4A548B29DF86,001C71F741099DD6,9474415CA4D8914E,88EAB44D34CE58BA,0A9A4FADF9F59591,251C81856D2DCAA6,BABB8FC0C2022B0E,9629DA9B1FDD104F,134DC343C0C172CC,0031E4AB667C978D,CDD0627F77542445,4C3039374EBA2DAC,512FFC01A9C8EA0A,4BCF4E5B61D7FC8C,0F422E394A08E306,D2096904B0E4AFBA,36A6C7458B1DE702,0038431D78E42DD8,D9705134EE12E875,4A2583328958EBAF,37E9F0226681EBC5,E653BB0B73D72A41,88C08AA2A77B9151,D800E49EF49404C4,FBF4020EC7006544,00207271466D7C01,793226F513CC8F89,717908768517C0B9,5B2C6F58E0CEABEA,1A96AE7E914B58C5,3DB1CB66AC4BF52F,D07E4C5B7642008C,BE37C997ADB03773,003B32B9C9C84D2C,D1F8FE9B96469B28,732244A8F4534A8A,54B695F0D9EF242A,A05B7BF80BC20600,A1C4B3B077297618,0722E0C134262DCF,71B3A72562E04411,001A1838B64B6D73,F53EC0C44902EF4F,EC69310636B8D799,C51077CD30641863,C6DF965303A74061,DFDFE56B8A312042,9110CD86161C06B0,D86BBD74D7BD085D,00128C25713EBDA0,5D8A816E9332DE46,841B22E3C361F680,F5F1FC850327C114,814621A70ABB31B9,CA8294B48F7DFB1D,66524D89B4D852B9,B44856848C2514A4,002FF150083D87B5,00A027D6D3DD52EE,3B551767E6E9F855,E5BD3C6E507B3FC0,DCF10B7BDC5094B7,5F0FFEC99C3B5567,6D55714233D4A579,EFDA60E379E0902F,000EA35ED8AE48CC,FCF20083F5F428C3,A18E4F5418871812,E0E12E7ED5D5BB15,E85ECF54CD9331B9,BE5A6D48AD9184F3,B17500795FAEBEDC,A6D7AB1EDEBC1102,001459EC2BA206CE,F8E657D366964B1F,6717796E9EF07530,3A987D9461789025,2EA9B32B2563AECE,1738E3C90DBA9979,75A87EC09F14C84D,AB3EE50F8D39CB4F,0017F4E16E39008F,0FD7EC18FF9EBA36,616A27E038D8FB90,6E2FDA0864B2243C,157775AA9D3F3795,D434F1D1EC79CEBC,BA260FE4D6D2B39D,67B56CD39B6667BC,00403E625063D69A,E74E782E85619910,A4F3DDA6EC31614B,4640DD90CEFB4E4C,0A5629B9EB7CB33E,75C0FEB5A26BAE5D,75A2C4E0EBFC56DC,3A1146FBE14A75CA,002935A215F02E94,6161BD6D58FA8A41,4BD7B66502AD339A,97420E426C2AEEE7,4D0F21C0031A6E19,5E2EFEF5FFA2F82A,F15DD0BE7700C710,00431FB39A993631,0039709174CC208E,37C870963A57592A,B97A63D837B120FC,2CC5D03CD7150CFE,1AE92E1B7EC38ED1,DF33E7F840FE027E,C981F4AF85F829C6,0F70D0CF1324C125,0027E9531837C565,1B28D7540D0063F4,2EF0EFBACFBD78A8,B51278963685430E,B27C53C9EF63870B,3FA3D43201DD78CF,D27E9183FFC1C3D5,D1C5E00C3C2F07B4,0038FC5BD5E3F0E4,02BBC1EE7861B1BA,9E7F01F9E7A7F4E2,0BEF8453AFBDC31B,C2D7B60633A68E89,3E6662E389A58119,1A7661A29355BD87,0B098D47BBB3492A,0011AFFB61E7CC79,FA47632FF3FFDD00,2C5768FDC2057976,B8C786C0AD1E3CB4,6F27B11E80996464,7102088D0E874D5F,408F198F1412565A,E2C194DA65214D49,000FF2E04004EB88,31F80763739179F6,80F015D405ECA8D5,26D3957487EA4C4D,3665B9091C2012F2,C411ED9AF937E249,8F42738D55B0E367,ED5AD578904E57C7,000E8EB812E87D3F,7863D279557553C2,EC9DA5A7B7E6DB10,D5863A25F291AC5B,4C04AE294AFFC9ED,AE89E0FA7FC6008C,5C6C35A78BA1BF59,40B03AC3D7D9192D,00086DC32ABCA521,67BEFF968A6C4A47,3B4B1B972659625B,C3A159D203871DF7,9B5559CBA524DEBF,D1631873642194A1,370571A4C72195A2,85698FBC875173B9,000EEABDA62271BC,29F2B5867F163341,7FAF149A7966EA41,892FED12FBD6307C,1055DD04C0F48511,39CF6A95DA0386F8,CA7591715724CD99,0276CD6FF3B8A9C8,003C26DEB60AE7B7,FE5FC0BC32FA417D,3008B080E6F67407,0E39358F06A29789,706FF23B1EF87AF5,1E4A5156CA2447EC,505C3C220130E0F5,C81D5653592A0857,003B626CB362BC30,41F4D7F3ACADCF2A,3FDEAA0ADF3B08A6,E1FA47B04ABE4E54,96C7E0E6AA7F6E21,13545E7FCD1AA894,75FEC220E527FD80,D747E4E76099044C,002B8D407D2E00CE,67B4CB0515CC1E98,530BC0179C22C5B4,FC94E6DE8E8F5BF1,D96987A217EBA4D3,3AB06D004C618681,F1E623F198196D14,F202602964370BFE,0021A5FCDCF059B7,BCC695F9B1F686E4,0364A879AEA5E57F,A4A123BFA862A324,B370BC21C8A1833B,97F67C7FAC7AF2D1,B6043C639E016C25,11F2FDDAA8FD7B5A,003D77BDADBD8BF6,6A13BB52FC5B47FF,5A3DF2BA6D51D114,1213D8870CBD1089,4F67E858BA8DC36A,3E4671E45D144132,C3B670A7B74C7961,F2F07DC7D1F225AA,000C5701BA8E8C08,FCED64CEAAEC8F6D,7F381DA5A1739CFB,4717C363A5F3408D,8737CE0E6AD47D00,2D44137468761A1A,00DF266A51E00F34,7D723A4E56C370A8,002E407BEBC99010,A237832AA17E2DBF,1862F35E788F9CFF,0ACB00CF6BFBAE25,D1BC805DF8EADB42,BE49C1A194167048,C8DD38407AFF83D9,532F5645373CBE93,00092BC914680E6A,221B6660A13F0562,D9F7036FFB22B1CD,FB588661ADCAE250,3049BFFBFD34B272,B5D9D5C749B6F1D0,EC94DAA08A72E751,1C9ED264F60E26FE,000DEBF0A95C7627,B89B69B4FC1DD9C1,7574CB9EE7F1DDD0,CEF148AB7E5D1A2C,B6160DF3AB2199CE,F906FC8D9191B062,42A70202D9C4F11C,AB6B737646B81B0C,0016A9E47367EBF3,F1904383B1B6A61D,E098A4D38DD6BD62,FC48C5B79888CCD2,9B74AE22BAE8F07B,E896C0ED7852D29E,02D6A521B5028E20,558F112681E4CD0F,002C4CD8959C15FF,C06A2109D61472CB,3A7015AD35F83019,255340A0CDB2FB44,A831C08E0CF7DA62,1B66134E15F1B90D,0BE709E2EACE87D1,3B7DC2A569AC8F88,000D927220E82124,2C1EB9CDC3ED9F3C,5A08C29223E08778,703170B21E2AD32E,666819690FE40964,13A6FC2F32A79A9D,279D745844E6B628,BAE53E336EEDB002,00273C3CD5EA4337,9A5AD49EA46EF1FF,CA9FA1589747BB59,61D453DC06BB2BD0,5EF3B933952CE468,FED0DCA303728D58,119ECC73AE98BA3B,20FB8324B7295AEA,0036CC94F1D75BB0,AB22E99C544A31D0,C634467E1A0E55EB,CEFDD2B68BFA5D6E,68F964097AE0B949,208469324ABD8EFB,C349AB4D92196013,EA84F6C0413EC323,003956112E51BC99,39AD582811CEAB58,47D38E4494C5E6E7,0059ADBE2C291131,918DB334E80AA8DB,DAE0C771BF9E558D,C75BC23AEB988E55,DDAEE3154EFFBB97,003002EE9BDD4506,60138C0A91CCB6EA,8A74DF515057D18C,CA7AE11495CA2D9C,6CAABD2302823E81,5D64208207EE43EF,EF6319F421B6AAEE,67A3AACE9A0E926D,00191C76D5EA93F9,7C2640D16FE44BA4,F3F23DF312602500,27CCAA0FEB9DEE5E,33970257EABE5368,0630332BD7FE3C77,7D3880A4A89A6783,684292FDC64D786B,001D67E6AF18A442,D0792A1E38B69119,3F51362318D79635,41E961CB5D78A14C,A68A2D1C39AF1D8B,99E885C3B4B150D7,A6785BA6CC2644A9,D85176DD751AB73A,000D19927B30A4FB,DEBE71151FE8045D,C1766F8AAF8C6912,6BFAFCE4F844FEE9,6E5AF272BDB266B4,30DE908A84353C02,2E6EF9ED49846671,0ADBB182DE3A0DDE,000ED6930CE8DDDC,765E102C079996D7,F7C98AD7F815DECA,C69EEC99AA2E0627,D15744171B14E96C,E9765AB258BF5EED,89E245AA9F0F302C,A593A154DDC7FAEC,0005D16F71183B48,B12ABF29763C19F4,0BB89A4FE29A0D21,01175D35F6C780BE,E052FE171F9B0AED,5E832A4C61A50EE4,65E18CDD31CEFBE0,1274A8C1BE6CE29E,0006177324EFA752,49D16E9B03A9D126,A26C37857ABA3CAE,20C8BB07F2A5FBA3,250DC817F05725E8,F165F6846B28814A,383FE7399725CE9C,D7AD4CDA58DD1F0B,00199DF4B74CD3D2,02ADA847D44870F6,3881F23C5D203363,BF23C93A3C946AC9,C53149CA9F9D662F,E1651F4E4F0A642E,39E9251D8F78C0BD,B25E538CFB711CF8,001CBE36087D21A4,3ED8D00ADA8E7A27,B8F366CE2F351F4B,1D30808900DD6437,7ADC32F20B6B8652,EA6FCA234F63877F,0D040CE38C48254E,4DA3BACCAB834918,0003907BADF34AF7,BC568C222C132001,AA12821499A2DF7B,FDDFE63056B658FE,D650BC83A4254A70,8B070C40DED7A32D,747BCBE6D56B1C97,779C49804FE651D5,00338FE34E9EF191,56E2F7F09625A807,8EA912AA46B14B00,E3DFAA8AD80C0A1E,73732DB11359D630,A77DF9ED87E15489,6805F31B888D4496,7056C2C01F070C3C,001FC8EE42DBF51E,B898972EC700F163,1AE83530C6F4017B,5D49AB078B36952A,EC11035E638D3947,687511FA6B38E589,9CFD7CAE059F1032,E074843B93924BC5,002B534A1DAC4054,A97397D8BC6CD49B,F2BEEF956A61ABD6,6033393B374B8DE0,9C5C59FE6537F1F2,FEBDD0880A5EA3BC,9BC081908E84E127,7B228182C73B31CA,0013145C1EE2E5E5,D7A0AF28E7CD3863,9C3DAF631B21698F,C08DB009C1CFACC8,5B836FEFB1D0F85A,7E078B0860B03324,FC1F821DE80BCE6F,E2B41BA465331D7A,000DB8998D713870,4CC6C8531515E8F8,D7D269C90AB9FD9D,BA6BBDD74DE99578,4EC46C872C0BA0D2,EF771BF24EF81503,87EAC009E46BD5EC,380D3B3979107100,003CBA3EEE884D2D,22BA8ED232B92A0C,577D03D30707BD39,816FD57B3AF08A04,CC582BB3795DD45B,8768B52462113CD7,E40C3CADA3CE392F,B4E6989C0419875F,003C1342A3878DC6,A34B985B45C2428B,48C28BCCE4D5A26C,DFC8268951337C18,3BD2224DF0BCACFA,9A8BC53701A372BD,C411E8A067F974C5,FE1BB4144B79E9E3,0030F783EE280758,1923B3840D3DA3C2,C6B681984D8E946B,64771BE195147AEA,4486BAFAE6D746EF,498B5ADC93274D99,2B47FA1D63D4E693,3926E0B5E4D45009,002304A14858BB82,28441C16E3614CA0,6C05CED309840657,2C72AFE274426FDE,38D87145E2506A7A,3B8EAE36C9AE5076,32693E7C060012BA,DA88ADFF1C0F57BE,00142DAF20850D18,E33F81FC2AF866C3,50C2CFF348C3F6B9,C80C39FAC64D45BF,A5070E7E1790E335,38D41FE6AFE34BE4,8B701915312C81AF,FB1EB5A9FED43ACE,0021C2F054741C1C,0FEFBB89394F47AB,2C018FDDE12B67D4,7DB41995A8B974C1,DA772F95594C7350,3EE9B439C1CE349D,98628CC5EAD12DCF,B1EBB8914D9C818A,0015F29E1C0616A0,5AAA57A833E1E328,D667259386DAF51A,1E530624CE0C1171,E41FCDAF4B979BB2,2F04DBFC0DF12CF9,5B808B34BFC2B8D5,BEB39E0AEAA45FC0,002B16ABFFD15857,05E1501FCDAE3C0E,945BA87AC6592C87,6095808675144A91,F78BCD780884A16E,E55EC1209D19D7A9,86A1403B8A6C2183,B520AEB24F544C5C,0030002ED9AD11F1,503CCC9F2B073DCC,9BB7FD3DBECE2467,0CC55D5E38AEFA9D,2E56FA18A2815065,252393668A1533E2,D009E74A5BAEBD77,64BC9A1963767A2F,0021E0149C760D09,FDCC9A4A6F456377,6F288D6965975FC1,4F0B345EC4963DCB,017A30901B815AAE,FD685D1D6D5A1041,215EDD8A9A3AB496,534DE8FDB3FBC09E,0031D26182AFD8D3,5DB22F4B32FA57BB,0F7929055E786D42,5D9CC3DB93EB1FF3,0861E3501C88DE75,AED6362DCBF8DAED,D06779E159D76F6C,9C431003C17B05DA,000BF246D7BD6369,8722610DDA7D12ED,422F6ADB41C2C4A7,1E530C2DAF0FB7DD,A83773982601792F,1B4BD6E142B8895E,66824A24062D90DB,FBDAED787F15255C,0038AB4714EB71F6,5A16FCD68211FA06,E90649F573F01E75,2AEE94AE5C0FCEFC,6F267F46C7B26AC3,D42ED2614F5D629E,1B08F62C11CA5D5C,B3F715AF201BAFCA,0029E7ECA4AD9983,E89002F7938F1848,02B83BFFA1F13CC1,2FDC4BEF7616FC21,A8C69543B97EEFE8,873C160ED50C504A,1EEE5959CB02C891,31FB760630AD6B56,002317796E1C411E,9909766BE05DBA62,9129E3CCFB2A660F,516C85C6EEE9371D,22C8B3C546526FE9,A4A663341162022B,13C9B3D8CF7B9841,A0E8D326695B8D59,000351C2BD9E1516,8EF89FF2B009672C,7B71BCF502DD5EA7,75A6A14D487CF86B,3DF76D8DC43B5DD5,B2120DE1D627DB5D,A9F7F8B7ACF66BAA,EF34BFBB6B45E930,001253417275D104,8ABFD12DE35B328C,FA877FAF8423608E,C6A21FF63B2E41A0,A4321082E0E0C1F5,90F3F6A6FB4DA7F0,823FDE6AE5B4B089,A4987291F8B5EF7B,0027A47CDB7F4D35,897B1523692CED22,EB241575E872E8A1,5789B3680A31E88E,105294F962EE4002,A1F434290F3BCC82,F62CC2F405B1B09F,6939CED68349D43B,002CE3E410C10734,8CD3271A98612D13,7E51EBA3328CACB9,A7B693457A5ADFA6,4A2BCB6DB901DF13,6E52A32FFD1DBDB4,7254F168ED58E235,115FEA7591DB9D61,000F925F9248C93E,E6711FA7AC3B1A34,6E01A0696252798C,EBB2B0DC1EE96F64,0E6549CEFEC1A434,64AB83BA1C51CAF1,3AB472A0E56B7AAC,9B90CA4B2AAC242F,001615FF488B4909,BCB76100EC5A9484,B1E95EC56C212A9F,A38ADD99B48831D1,04AF1C5C3419C04A,356FF247BBD4015A,B4D63C1C9CB6784B,3357CCBBF9DA0549,003FC97F996859BE,82390E72A28575F4,252452AC59698A4F,7F8DA1D7A1A00F67,EA61C43632CA03BA,41A004FBDD6A0C6D,8C4A9B5B39C8BE7A,1E8533C51C31813F,001264E8B9F4857D,961FF67D593D15D4,8C80E6814791F955,F6ED42971DD7117E,B271F44A5CA4915C,76C348D36D2E250C,170CB0EF7FF06836,925DB2CBB01D89A2,002AA1B7632D2AA4,CD72C7EB3B903517,69799A6CF766BAF0,FA5FC0578ADEF41E,4AEA3F65A21A1C3D,A23B3A762AA7996F,CBF8BECE7C364484,1A743B8A0E94571B,002FCE5E249AC3ED,07E3CD5F2F891D38,864CCABFF3CB6330,630396646F371DE7,79C9013F41DA19CC,ECD56F22E0520904,7125B41CE7927204,433A0C878F32D93E,0005F964E5EB0052,A7AE7805B1E9AE00,49A5BE19E3041C27,F9BC405FE95B8F18,66909C7D7D1B5DB3,9AFE24926063987D,15C15AF51139C475,68425395417F9412,000DD3752E9BD7C3,6072BC5210A10A11,FE51022DEB2EEC44,55B45662BB5C234E,8E3FAFE8C9ED923F,137B40D4E4D4E41C,F7CD7C2CDAD4EB95,8F1C94853C295FE1,001C7382D4FC134C,222A8B0539B19EBF,EE592608474967F2,8C40ECCA8360A0E0,80C931E6F8CA7EE9,98F0226B40B9AD0D,068FF4A489699528,C87BD8972D9DBCA5,003AB851CDB01ED8,B69523BE8A417461,237C16508970CB98,45B84F1E40D178F4,AD07C5F118146275,F8191F001320280C,40618EE9EE8BFEF5,9FEA96723938BEF1,00381F6BD56ACE5C,D23FEBFE702144BB,5626D59AE3D109A4,40EDBAB6A8E372AA,3B097D0DDA9CC0E9,91D135DCBE5CB079,0C747FFE70037877,84D50D187904EC6C,003062A5CDBEAC56,91FBC2813493AEC2,E63880093A0A9809,3920ED948E0FA3F9,8B275849F7C2FC98,DB73C8BF631B7463,567A03D936E95DA9,4ADB6F486C9269E5,000F508EF1FA7447,CB2CCA792D0C0643,D9D831E1848C5AA4,7FACD6C7D8BD22E5,4C29709C661B4832,5A062444BE4D0973,A3B22A80A8741EF3,4CF4520812648B8A,000579B5015187EE,243626AAF89C1E01,6C94F4A37BEC84E7,3429694B47A27B36,99FD9E21D798C62C,94C7A859F1A27933,FEAD208C4E12C7E6,9BDFC7FC6CB6E7F0,0024232534F6BE7E,5B90E555D30F9D5E,B326A80EF97F6C6C,4B591808489CE650,4302218CD338223C,47DB8E950366ABBF,5F90385DFBA64457,3C95E425EF3655E1,003226006C11D276,8D08B52E48D6248B,EDAB5EE2E4D2B8CD,BAAA6E4FC1DB9B7F,C2078BFA41CD0494,35C93B20ED3EC8FD,E09498D02DE77E3F,51CF2D3D39A9CA31,0032F38258CE3DCF,4659593505277744,C50B35BBBDA9F7B8,F93765424A1F8DD9,1BC06DE87B713FE8,12FAE20179A12D9C,74211188A685AF7F,973F645F23E0FB94,0013CE96C45370DC,055EC239EF328833,0BB7DE7345FB35F7,86A1ACB45ECE81F0,487D71ACE0C31164,2A1626E671013696,C792E95FC745B70F,81582B138D90F865,001544A5C5B8EF1A,0F82C9FAC713B3CE,C0255349AB31019B,29F4347FD5754074,10CAF7EE2BA4BCBE,C8EA8D3276A2B316,C81E8DEF7BDA6407,FF1F0AEDA1A2F353,001538A8EDD3EC07,25C444A3E5A1D340,9C8C6B69093A6CE6,F5B614A7E4EE5903,8E5D8111F15F897C,A34F261E8B304083,C68F581EE22C9FB9,CD2CFDCA1C402A97,000EFB8885AEF785,2D5DCE444BD2ED66,A198D1DC3CA95B46,A14AECC85508E25D,01C543F63664ECF3,2594ED12CFCFCBBB,F9B0E4C8C98826D2,030F88C027759712,000D67C362A0087B,5398258722D2A292,6B8921DB72A767DA,778B5423A8F87355,6B5F7832798E2710,949FBB5B2EC6E8FA,C04791F5CF0E3D30,FEF5BC417C3FCDDD,0019DAE6A44C8701,FD961802FE79DD83,495E1E02F5ED456C,D04517CE87DEE3A3,E8FCCF09175CA4E2,66F0D37B13B23FF2,A23E560E6A61E94D,BD889B9E76938B11,0005EAF64F843E33,00539370EE8C9CC0,4D0493269F0FFDCC,445A50A348FA9CA3,B9D2FC4119F2FCA5,E57867F36DA4EBA2,55DCE2FEB41A9B3F,123ABDF913228D6D,0014637B8FC0C829,13F2275D2789F638,311F4266749430DD,4B242E2BE4D3D6C1,1CF16CFACB159FD5,108E50F5F07A56CF,E14DC90CE196AE8A,EB151ED604B1008A,0013C361D8387D2C,A539B9B4A235DC7C,9B316C806582A315,46DE48EED00A0527,D0A51E243DC9187D,90F6D852DCB3FD97,1644F8F58470D830,895B8B2200048E3C,002A78432D2E00E0,72B63DE1B65452D6,293437F65E04A9D6,4B0FFBD88EA50C7C,E089B6D2234FBC3A,CA45B679BDE1E2B9,33EA173EA26815DD,526522F9460BE1C4,001DC404E12C37F7,9AF0FB6FF3484C16,8CD61EB4CBAEBB34,FE3241ED247C650C,62C454C0661636B4,F7CD01FAF6A4C295,5F02851136597280,6B665AB9186FC07F,001E076C6ABD9717,114B8CA614C60E9C,2833AA8A3D5440EF,FA375D300AB0BFE9,5C77DAD5560232DE,0EADE366FF3135B1,64F00F12791FE10D,83EB421E9AF236B1,001D75239A4324AE,F177B1BF78E7BE71,7931F7EA26A7E103,563CB31A5067FF2A,A1565707721F70BF,D42AA79D42D15597,ECF46B6CAA39B3ED,F69C61333DE61D3A,000B3C19F92733C4,1172259B1B2337F1,4CC7C2BFE2E4D55B,3D6B5BAAFE564AE0,0C7829BA0C68AD57,A8EAD78FD963304D,F54D85E36FDB22D6,0059513C03AF5B99,000E0CB333717D9A,2C03DE5ABDD43C95,2A7167ECD91A8A60,1F5FFF067FB06718,C98348B73B12A5AF,BE752AD8ABC98EBA,3C374918619F45ED,5BC2BBEEAF951D45,002C11FD85A1DDA1,D84C65C38A9E130E,D9479E89F0A2B1BD,85E6CE8924A97B82,269A8B4DF6BC28DB,11B22691CD45EA56,A93BF4A7D9D0812D,ABC9F339CF6F4D5F,0024DEC28A90144E,2D0DB175EB70583A,E4B1F390EB12A2A8,7E3C992D9C0996F8,4D905726A67AA7BC,775DB475F293D7F3,EC2623EF00899EB3,1744A31C6F35822B,00253D37B49ECB94,F2BB9DA4D4E120B3,477F038809C55DA9,4BC5E1C21F11C1E3,203E34D42B61A982,C85F99FB40E03C25,A5191B5E75D9182D,21D83091013FDC11,0029283B44E565C1,0858D8E10A65170A,27B3093F90B84EA5,A8AACFA3B62318AB,3AB5471BD9C656AF,B43A1DC11AD6657E,E080B2418A87958C,FE2D2E62CCF4D376,002763E1502029C8,86E34146BDA23345,634A1060D4109398,81C500FB1AE6FC4C,3C6E005A89CBB0C5,4468D497B04C1A93,63AF7B01D585FEEE,3814980E6FCFB14D,003E2146E03FB622,4A05B99C482BCB26,2E9D0D1002E013EA,3AA8987C07A313CD,9694A28442A6F14F,652EB32D85C360F7,BE8465D93FE1E4D4,9DFF5DD9023B7AC9,002275D0DE47C70B,1DF8D1F97E875A52,71D2AEABA63108EC,5B16593126FD63B0,9BEB8BCC7F3D2758,AF3BF70F87FEAF0C,A9046A93B6E11330,A074CE2C99BAD72A,003BBFC2BC41C18D,D05D80F8914B846E,819C3499201CFC75,5E4468F01F0EA916,D59BE71157C3E0D0,A1B66BAD0E7AE65C,4BDA756F6B2A77E7,5189C52759F9C501,002A71F728DBFB67,E79331917DFF7877,7874B1826A677F35,507178606F6D3309,0FE753C58007C447,57972DEDD52D58BE,92E2E96AD5C41178,3F3E0149CD4DAF4D,00296E4C53950066,0C6F67ECD825018B,69C7566CC045EFC8,9F9C9233344515E8,EF0E70AC0CDF746E,A33E9D4CED402A09,DB9C3682476BB5F2,55887AD2D5FEE54A,00362DAAFAC26C81,3D278CDC3B147680,7432B11CDCFB4648,7F57F9485A673F3C,6A51F287F73D55C2,6CB236ADA7A19ACE,406D9C86C9180F0A,F577E09C565F30A1,0002463074059EF5,80F49A1B96EA8D26,F04C15FEA892DB02,341A16CEC6872955,03B7352BA5F6D9E4,0C23A50642525E81,93452ADA63C560DE,51F74DAC1DE8A06C,00075B086F0FD7C1,CC03819A4828403E,CD138FCD98D8A467,D679D4B53ED19473,792F533DBE190782,B689EAAC608FD126,BC0A787C052DC9B2,B14D061E236D1641,00308D70AA27D9CD,2CADC5225BD19AF0,EAC83BBC4F3CF7BB,78282BA70E66861A,E9A80DF4A25C0B84,D095FB77F59A8ACA,0D2AC22799F01CFE,983C1FCB2BBBF6E4,001F31E02665C69E,FFF09A9139213B48,D36450093133005F,CC1EB7C40FF2D1CB,519459FA6CC22470,9191D9FBA1930CCB,6D35DC2EAB369D77,DF8C331B4AE754B9,000701206233F9E7,CDA0516E7575B9A1,0C6F198E898CFE53,1AC1B38E84E4E8D4,655B8BEABD824A5E,B75DEAFA98B18060,2F07FCF8773AFD4A,57518A72F2622365,0034D5CDCC814829,73C1AC9E258A99B9,CFC59B6BDC99DD7C,C2595F8408470AAE,7681C8865BCCE405,B172442DA8DC449F,5C906886CB49B25A,9A1BC93F52CE499E,000CDF961FCBF8BF,2FF20E2DBC1D35A0,21D0AEBC30676B30,BBD5C5E7D9FDC042,B1F64DF92EECDA9D,8B6B632C862BFE17,676AAAC88791831C,156F8B022B3471E3,001FFCEDA318E237,3FE83B9C4B054914,4F66DD6181B2ECE7,C7497F6812409D02,9DAE32BBCBB3361A,5C1F128E0D8C5BC1,1DE428E99BA64910,CE5DA9461ADAAE35,003913E63F032C34,563700EED870B410,4D4B20F7E4BD43B3,03F00BEDF21627F1,237A807CC554A1C9,4785A8677255FBD6,0F354D109E113529,9D02E8E0D7C07D58,0021EBE6547678D0,53DB9BA3478787E1,FE43E7927A59E5E6,8CAFA3F3A4439FBD,D967C0CF02642422,44868E662E1290F2,1D12AB6E930FFEA2,713AC301C5814B1C,0016518793287654,3DE8F28596CD66E6,ABD566CDF2D04B93,6506329DD925FA9E,86DC82F0B5BA113D,26E60C26E0AED1DE,DDDAE800D52860A0,125BC270626E5951,001DF12939B0774E,C563465EB596441F,0F82C120AD0DA820,BFC30E9889EC8FD6,EB59751EBE08E74C,EF68FE86BD57760B,5C1FFE4DC244FDBE,F1CCDF7DCDEE2157,001FF22F601EFEE6,8025D27C9D509D9C,31C76825B675BA94,2D803122E32477E8,AB3B1EB113A414E5,4D0B93B13C3C93C4,3B42F7A00F4B6B55,D02553DBC3E989EF,0017EE4680516CEE,53709AC92FFA7CF2,E01114E598EB047F,61A31E128ACDBDD3,2123A5F884916DA8,1FFEC9D4221C9760,34F3FF7BE3FAC900,EF53A8C318D871A4,001188B6409F6F14,126304AFA76C0450,FD6D53C2407E28BD,F5DE0F0E87536785,C47BF3B99C5EB943,B0A237DC4DC9FF80,70342B7D31BDF9D8,F96FC2C3883D2D2D,0039F767994822F3,86B8F19B4EFAFD2A,53BDE5FB4A60ED22,233813C4160E605B,AD60CF6DCB87E67F,00A6A2063AD6E59B,4690625B2A930FC7,B5120E25EE29F6E3,002C595DDF2B98DD,E8B75231070DAFE3,B9495BC6564EBF1C,13B6FD3DF3EF64CC,1765B37170569C56,9F4FA46F52F85174,AD8FFB186B368C43,3494302879F3A54F,0017BC003224D6EC,CB1BC4421304F6E7,09FE3130AEFD6914,8825B97E8DCB69F7,A791CAE50BA06F6E,EF3167BF96F0D11C,9D8B9DB7CA066BA0,1A9BF85A92D8FEE5,0026F069514A3BD3,6DDE5EEFCFFCB095,EC1968D08E75BDE1,E8F9D2CB94F37050,2A85EF3DCF1E3102,81DC7C2E87A87581,63C7B0EC29EFB598,E9E70E6EA118ADF7,00062CA6645B8619,9FCA177DC74E90BD,4ED567E4C3A61823,7479CAF4E675ABCF,102C8279E3DFCC4C,D015E0433B9ED9C7,3A293861E167FB66,9BB3B83D19082339,000254C7EE33A12E,6352F80540337E04,AAA371AB13EB5355,C10E606D7167E896,C7BD1863D7DE3948,3F1465B55B4C1FC4,B696863B1A5F445E,E500DB9D98A2D08E,0036363BFDF68DAD,24F4E84BF807EA3E,5CEECB247473D814,4AC9DAC98EA5819C,6F4571437E553E08,1C55209A4A51A5A1,0A44F1F7C7A2A748,7C3BE0DDECEBBC3B,000429DA4034901D,118418B54B44DD92,92F26F2DB46E79A2,659429A357FCE653,1E728806CB4B430E,AA120B6514A19F66,78862ED3D08C8088,928354554B4332A6,000C17812DC3B39C,C7ABD3504CF70551,F723DBB5E9FD2CBC,61FC7C98830D4526,68ABC414D24B592E,C0D4C5B932D3AEDC,A652A63F1D716711,E778E3C6D23773DB,002D4C46EB7A705E,97E1963BD362D684,D59EAA70A45E52C1,93A630DD8A392F6A,8A28CB323A841823,F610FDB012E7C2F8,772F35444C07BF6C,CF007B36760BE73A,000382E29ECCDC68,A1698C15990625F1,174624A2025BE99C,6D12498ED55E304C,28E47DACE082EFE1,4A565411136595A9,B78476A7948135CB,2DEBA6D3851C4728,003A03D31EF6428C,C4974BF78CC846AD,7DD59BA4DA44099B,609AFEBF6FAE11BF,E0EC69083E6C3CC0,C64580F1B6E7240E,E43AC890675CD11B,24C44E0E2BBCF51A,002F078F4B1261F8,C17244B87721ADC4,375817DD7F08FA21,6A248086BA7A5064,24BEB7AA05BD62E0,B7274F065C165B34,E975D3D7ECEBFFED,20B49977A90705CE,0003BE683FFB72DE,4B1AFFCBFEA2014E,0EAB103DB3D958F0,0F81B76EBDCDC618,D3670E9ED45E8E20,0018A738278D30C9,C45CF28735A3BC1A,CA2F7CD3094583B3,00146419D1EA47CC,97F88DB389E6175E,ED85D197070C8E29,60CC37F5D8106501,72208CECECA82962,43C69A28865703B0,F6AF078DA59D2EA0,4C03BBABD6DA6098,002B683EB80D9E4A,3135266DA0F7FF12,D5E77E2BC4B35992,92EE6CF020C5970C,A35DB4AEE65298D0,39C25AEAD4C9B6E2,AA98BCD99558CB55,175BEAA42FE925F8,0016B7C4FE35A5D0,7C5F3A711170EBAF,B23A8A6C5425E460,F1F08AA96EA85174,747F127C99079E15,7A43831CC825331C,AD1EA45F2D723F38,0A5BA8E5867247AB,00173E0F3B84123F,AB2B17152F4D792A,7249F1BFD79F5AD7,732B1BC03EADC5DD,C1EECE8103C04C31,443A435D841F7FD2,20C400830903BA82,B5D5EAF219E9F286,00355215818D8255,8938A081E57CD990,9FA5B30274E710A2,7115C13AF41AAA40,D77E3BE0775EC1A0,80F63648C15ECD34,1C99C65BC4FA2165,D82E231E2E7000EC,000305A9A7A29BB6,F38AFE46E30E2CB3,0CD0C631CBB3F5EC,3D988AB9820EEE1B,C8D01F6D54C02778,BF9A732139C18B4D,CBBBCE812E307A56,CEF71E2CC77C25B0,0022E06D6A6D31D2,FD6D488AC04DC1DF,05A50C8F00B86D0A,FDC26F8CE3D8C66C,D65FAAD69A4A3815,FA9C5519EB4538FB,C15091045C859F3B,00C928280135FD4F,003F468173725306,C26E87A84A3C9B15,FECB8F7783C3EB0A,143E2D07F1E5859F,0950B92BEB7E3AE9,2E3ACB74A3BA964D,F2EDFC5E9D79877B,B312D61CE731BD9B,002F1CC9765EF15E,0D01AA314E5B2E37,A5EEE909DDD404C8,D97E71E9742A866F,252104412287C4FE,4982767F66F3EF55,B87AAAB0390712ED,E27C53746E3F6D87,0019232B4509B448,0BB9FC04D0874288,B044D2DC35F3EA86,D4777FC0D9901F7D,EF5F597A8F09607B,F9E1BBB82F964367,3C19A18B2F971056,A4E63D7F8C97A091,0005662E3CB733B6,9AE7DA64C6BEA3AB,72615FC7E2C79D2C,578D29E11A183804,2CA0BD6C27E87AD6,FB53007075DB3190,BFF29B99A311E998,4F587B5DDDBEB84E,003CF53BDD8B6240,9076A72EC77EDC46,AD8E5479682BA317,3BEDDFD8CE652AAE,7408422463B20793,36993F55F11C56BE,637FD7A97F77CC6B,8FEAC584E97E3D26,000BE2E1A9EED8E4,DCFDF21DDD767B1E,1879EC359A12276D,D007F14C3FAA2759,0E69C605DE1F490F,0F0A02281BED8892,C2CC4DC1250370D8,9B1F32AFA9C3A0BD,0021E706A663CF0D,EACF0D82872A5DCB,B6AA83C741B66511,6D8D1500EE175A42,A6F3F2BBBCFA9B01,83CD40B676DE4DC6,827361F98AACADCA,3328689B9428E08E,000CCAAF78B92896,363AAFF3DE040D04,7F1CF5EF79F3A127,63A4D3A52FE44404,AA94D4D5C4624919,6FFD33949358B6FF,A4556F807B811AFF,CD6E245DE39E127B,0027871B75AEC1B8,D839E9F138427C98,837C96DD0AB53205,14D6527F05CE11F6,C440F6F1D3DD4965,FDAAD6DE8F147C84,44E04D1CFAC6530D,61ADA64A0FCE1D5C,00175A7DB4DF11DF,947E7675031A2D71,364511B4DB60B56A,523DA9B82A1AA821,8507D50FCCD8A640,51BE6F2619689293,0425B5B2170E9DE8,B56A2E60A437B94C,00124794716A699A,924F286C4D462C6C,FF0BE6530C14A273,23701AE090A86128,E4AA2058A52B2783,06D168CEB6578D29,8A598AE17589E71F,856872F04A26DC17,002831FED356F1D0,BBE40B6B89CF077C,F2032397FD4A9939,79C1BD2A3FE6007F,A9308109F50041AA,41C29FE3D7A10F3E,E127E0F5F07D86AF,7999F3C7B732738D,0024359FD46A466D,E497CFAADFFD4BB0,14AB8220148FE51F,B6CE762B7AC9449F,A7BD2F4F631FE4A3,7873E778205EFEC3,5E5BD8F8FC189696,844D5367C32EE044,0013E5036E1A449C,670A14F0A49401A9,EA754C09DA3F818C,0815F1ED34CE42B4,E6E702289C964455,8B7F8A872A1D72DF,38556656BFD4E9E9,54B67896F2E33BD6,000D6F3623D8F91D,40186E68A8A5F1C4,0A4A077FF00024C5,9E7609F17086DADF,81F239E200215A4A,F17A2B88D8FD430B,E48E7732CEDE70BE,39C70547DD9FAFA9,001ECB672280417C,C6C3E4F67EB5D470,54D61C43F1CD31FA,2ED71F8760AB804F,50BDE567B0522800,71479DD6DBB01ABC,0B02F66B0B440D13,5A85F7381F54DBBB,002CD79BD1189F94,51BB9FB0233C098F,3D00939CE5F56059,EE2E6730A015CE62,46819370F18BA142,AE061D33F96EE037,7915074D689F805D,04FCC0DDE3C1DA57,0018C1E24E1CDFED,FF4759292147A2C0,829A83FF62EA1DA1,B0F8467FCCDF7B96,70454C34EB6C56BB,7796AB2D9ACACACB,A85EEA63C0AFD946,6CD99915339C3B80,00308871580A59E6,252544E708D3DB7B,72A8620B1CD559BC,7BE1837F96FE3327,CDE02382433D8FC2,C0F4A40BF15A661C,A6F6801F6EE62577,599E16ED32CA4D6B,003B1684A711F6EA,15FC4544BF44BC34,B7B8BED8DB084F1C,221B9D61FD83CE8F,C1AB34D6F5AFBFBC,2C4221D7B6AB9D56,6C6A47C8081F5E7C,A1244FDD34BD98A9,00046446B644DA83,F754162F69A26997,41E00E1B8758D40E,F52EF55C8B1A71E6,04D78D673FB6BBC5,911094E7E7FB3C4A,74846C7C55FB434B,6BF9015AF9BAA22A,0039D43598766519,56790EA8FBC9E319,AB6B7F2D20C24422,D91950B82CDA7B97,7D2FB84480640E3B,697A5267EB277B32,987E091BC44383D6,C3AC195FA84016AA,000FD75F88C4FDF2,9046125CB0785B6E,37431D5C2C03C8E6,F8F9E9D0D7F2EA1C,CB4F1448610E12A4,023E5CC3760D873A,BA2F8FC1A344A2AC,B33237DE1C4E9535,002F1DB3B4301D41,EB5CCADC08E3576C,341247230A924B0A,A2C04E8E093224FB,A5F19D5125B710DF,BC059F669289A521,51A3C3F419B05E78,616B9D47ABC444CD,002342C8DD6F437A,2B9563FE2FD82CFE,ADA178C66457C91A,EE6207D5CC2ED2E6,5F26294727EAEE26,98C84FC9A91EECDA,BD7EBA5732DF2136,3B1169D2B079E7B4,003E191904496BE8,9417D4782789B280,5DBA4048536F6B4B,9D55603AF99C1BEA,2CABAAFE6DF1E2DB,4B2122865ABAD27D,BEAE4F9A7610E18C,E5261C28304366B6,003D32B4A9369C12,98EA0C918F797C2D,537C6B5749C48983,D80D1644C246313A,E83211467783F70B,C54A4354A8EB79E0,845F65CDD5D725F5,1710A6ABCF950BAF,001BF27857532FC5,B0E046229CB7CCA7,A2DECCC536A1B490,2BD4FE7866BF418F,0F90CB501A8FEFDF,D816D1B36EEFEF3D,26195B52E080970E,52B93B478D1C16E4,00028A53A89AFD30,991B26DE98730391,092310C8BC15ED8C,121D56DB603A7A94,5FEC77E8F032C5D2,88835848742CFD73,6B802E8277FA1862,1F7CF3F0459CAB31,000EDA6A6D820450,1F71ED3CC5C54A9B,ED6E06928C28ABEC,3AB5DDC42EA5D5D6,EE6E77D98BB7F54B,379E09C9C405A654,524F328FB43C4452,ED20A008D857206D,0000511D8B90A1DC,9D8601768E8F3E0F,4FCD7A75A407E95F,52B643F0C5EF208B,6220AAAFBE014879,53BC3F8481A58BC6,B466C150C0B5020D,1C33D027858D2729,0035EFE65EB53180,871529A6A0590BA3,19F3D2A7D4F7ED54,047191CBA1D6FC93,A442F02EC5FA4168,23A6DCDCF05BF40E,C574A6D5CAC812E9,346F08A451233F75,0031680AAF007B52,061398EEC8B79512,79F36B72F480F4AF,5D219AA93FD72E9F,80B13EC16974331C,04CDDB17C35314CE,231CB4F0A47B85C7,C39BF747B93B9E70,0014CCCBFF62EE49,0B1AB58E60386BEF,E8923377C8B3D58F,4C37DB11F1294FB6,BAE717AE5FE4D940,0AEA8EBE1EB24DAB,CD68687B74959ED3,4358AD00A8B0C57C,0002B4697EDEE1D1,E41D6EFBCD13D110,30AC9BD630FC538C,E08EDDE1AC923568,1B960D670EDAB653,7F346C77250281AC,5D7E3BA1B4819172,353C8C625BAB9D3D,0020C62C4F938C30,8A45578730142561,70A92EE95E500BB0,A5C4C83E11069012,2284E570A0F69FBD,65A01F772FFF5523,7E04CBF404003F0F,37D8FD811D41B8E1,0000ABA22B835401,4394F33208A4C3C4,4C35F7CDEBB19C69,DB570A67FF8DBCA2,F29D42285625FF06,DFAE2D2218BEB7B4,D922C2BF87FC97CF,0A19B3E35C20F0B2,000195569B3ABB4B,4B8031EF2007DA2C,F6D11B603390D98F,94293181D2B7FACE,DEF819783CDE38DA,61194FF897AE3FF5,934EDC2E6B2765D3,C8B5A51927FDE9BB,00287FCBF4A0C6E4,7C7C8CCCB4100263,F34626AC5E7B3A89,3D589CD71B4921DD,C265F3934C5C14CB,4C6503ADAE26E261,64022DA619F5CEB3,6A06077E61C73870,0021FBBEDC9F0A59,B2AFB4DF50FC9B85,0018180CCAEE47CD,99B629402A8E434C,1D64845D1C262455,01D8FE81DC023588,5F0A09AFB869ED74,6AE88F827037DE57,003F1C48EFAEC928,F5D7BBE9DEA0233B,58B580A7609B7C6C,2F40FFEF75464E17,2F027F9002343971,D579BAC098B9CFF1,63B15A583F2627B8,8D8C5F46B871DD4A,000D03055CC3F7AB,E55E88F3F92A5F8A,3AC1B9019A514E1B,1BBBBAB2B5636DE0,8D2990503CAD9822,698E08332B6A3EBE,E8E160EE1332116A,09B97A68440B3A00,002D7731AC8A4722,075196D0845AD49B,6D1AEC4F09847585,32FA138C2DED9116,DB11DD5447F748AF,A4F782D48BEA80E1,9CAAA9B06E9C5573,D3167163E69A3001,003317CC4A15C2E6,E79B238B8EC6C5DE,1F4F539AC9BBB748,4FBA74F878591073,6902079313672828,448FC602184EDB5C,3FBF15FA9C5A40A2,1A232141B828A7BF,00277A714C0675AB,93C2CD76671A3A10,04D27BEA10C003D9,36D462950211E3FF,5F35CAC178F8D59C,0BCB9782F4DB456E,CC2D547FF44629F3,4826D87ACCECC1BF,0019F8389513B38B,1D2BF23BB5DC9D12,93BA7CDE922408FA,94DD1FF41CEFB9C2,2598E90C0085B33A,E2A9ED2DAC515507,7DE96254F717001D,2574E5DE488D06BE,000DDCE589D8CA10,A89BD801BF3D9A29,00B1A1B267C29DB7,471413C0FF5F04A5,1BB53004EA5A2C3B,16C153789D3DADED,D30E483B4A08EC98,2AE4133791B59E8F,003DB66FB1060B21,765C0E22232E1116,507917FEB820C00C,81A6B8F9960D9F9C,FDDF00F3133C78C7,3B380CA25367C43F,DE82CB189222C054,975E65744A1031AF,000B45D3B31F4EDC,03B54047F95277C1,E395D8E3357270CA,FC86E6921015D704,2742F8D513787918,ABD45EB5FA92AA2C,8054CBD619C3FC2D,8501406B06F6326E,001D6DCFF4394EA2,41E259BB6804CD9C,00DBD0682B663801,90CCBC730AD17480,BA807F05F4AD0655,7833BD5B58D202FF,D8AC42F72F273899,B66A2C4648778370,0009BAA722657C96,BDBA1FB679F66B99,FB44299711FE2FCB,4BD18B449CF453D9,7A2C1332204F9B1B,2BF0E87E657C5A7A,8B25B706E2430FE6,A9E4446368AAB211,000911FEAA4154B4,F44BD8CFC16E6A35,C52BB03BB23ECAEF,67B480B35B226130,A76C64125DDC224E,0F2B249D72A31C4D,409D6EC8E0ACB68E,EEDDCA946BF5A3D1,002C2717AF8B7D2A,0BFB43A3639C7DAE,B20F0677BF5DCA99,E57734C203A0D761,8FA5C864C22EBF12,39E4C9A32FCE2D68,378DE0CAB5FED447,961970A44CA9263E,002D98009F106C5F,09A7BACFD613CF30,C8972C3BF1F8D61F,4062DC5CD7112469,7504D36D896AF7F3,36C1C8FAFA2CA03E,E35AF82049FDE2D2,9B2412A5993B03B1,0006F79892BB7E6F,20F82B52AEDF4742,4BA8E5110DB6BCF7,533F8D0341BAA89E,5A721822708981C0,E563A76FDFAEB500,18678F804ECA6F54,5038A0C2CBF61756,0014458F6FD9AD00,7BACA36E63796A75,36A0382568505058,422DFD8273541724,AF7D95064A3A472B,1594CB7DCC2E29A9,DD799FEAF7A0BE5B,8F8EE10622FA464A,002F88924044856F,2C80C895413203AF,C3C579C5A6FB4195,17FF4BF123550447,606735277CBEEBBB,39DA5AA949EA3ADB,5EDF04925591E46F,4C9EF0E6C0085078,0011D3B55152E098,938BA2EC10A3A893,12C44A892A959B0A,E8CF659AD3BA284F,78810A4F87F927CE,196D4D6E429A125B,8D5E7F5D15CE4A52,7D567CF8D56A768B,002018EB1E91D20E,769200E2580E7F13,BFF180959D3B9120,BE4079980D9F4971,434CFD56AC7AB9FC,CE84B36E232E445A,A0E81E42C784313E,9E4935EE8A5091C9,00335CA945E6D978,0203AA0187556EFC,5BD6BB67DC8ABC05,3E0ACE3A7A2DB312,9F95454A530B8801,DA7D68151313990E,27B34CB5D7DE573E,601D9A92FE8FEC74,002A5E1F30417C5F,114842FDDE3C2140,FC23D82BF6767CD8,EFD569A83D16D928,5074528A35BFC700,53C3CE2252C6DDFE,EAC8B5A117A62C21,A2C172D976607F4D,000C8C5F38F32A73,F97A478960669CAB,68202BD5E5A0A7C7,CF12F7A33739404D,CC896DDEFFE05714,044BFF1D14297A14,399CE742BC029222,95C59B2F7E34D118,0000F91AA0966B3E,2586B04A768B00A1,328FDDA7B55CD5A8,F875B9D20D54E398,ABC6F0B176A68A6E,0B9B68491FEC1407,6D4377DF45FF1325,CB416928ACC75711,0031B962527698C5,AD31C5409FC4D25E,04E1021FFF6C21B6,98B23FFE7C83387F,CF2952AA18923217,73E82CB3B80F37C9,46AFE3ED3F3238CE,C8D57ED1A356E73D,003469BA13223147,E8733649893008A2,0811B183FFF7DAF7,CD177FAA378871EE,1CC3A2274630D8C2,5EA33C7573473AA0,BDFF34F2A9DA8E8D,5A00245617078EDA,000CB28CA2C3DD25,DD85C4BC213DF01E,55740169B82FE0F9,ABAAABD1D7FA3552,517915C9AA24EA76,66D86C1D23524649,FF44D293479D190E,1DF2981BD5365DDD,000C26921DE5C4FD,27A6A086082DF293,B2182687A45D58C1,16D0B815954AE983,553D5C152411B868,E1A61B8530D059CC,F7A17D4C13316C69,96B0000292B25863,00028F5FC024EEAC,C2C7EC092DB5CA65,1B57E52742A5699A,DC5F9B878010CF88,326A0C9320E3CF4C,48E3E2B9E6E4F6AE,077A1F866EE083E5,A652370A695C55E8,0023293AB5596114,995FB7920A55F8A5,D7FE8BAAD52C6B22,07E22B9BCB6F4EAD,AB3D4C68E2C9546A,E0A5B8EBFC5A1C3E,278664117342C691,195552DCCD3A2ADA,002FA74AEEE0949B,D2AFC5C49B312C69,0ADB3560CCB8CD09,A6C7EDB88E5C81B3,AB4E1899A40DF0F8,18433E52A66BF492,065D4933E5102BED,FC79F30A37C45692,00104DADA6023E15,FB985778E9283D29,3C777A049BCA2C64,0787EA71D0BCFDDA,7668D347B5514A02,CFCF5D92B64B9150,9DAA8302DAF00F12,968279EA1D24D1F6,0008AE5950373E5D,1D2D98B055DE2C4C,4C4F953800074EED,FDB33BE51166FA18,F32989CE66EAC536,62A998676B801D6E,14C59040F0FF87F5,2ED1F2937973CB7F,003686EC507B9C34,46D0DEB3A746BED6,006143801F4D983E,A032126EA20EC1F2,766ACB08FC394B51,B783639E2AC6D1E7,F58653FCC0C1B928,5EE556C6319C6B83,0029AB2409BA7948,5C12A311976BC451,0D512FEB81FEBCE8,DF77A9AC2200CD17,8A399298F812F42D,8081D71DD772A32C,76EBE8385B832893,3A1D37D0BA46AD49,0015B283BCFF9DE4,6BD6A0344AB8D748,C76CBE0B602D5BF4,FF16F9A51398A200,FA7525EF8BED14BD,DF92DC3BE0AB4B69,F87EBAC76D14DA1D,A91CAE165C5916DE,0032E7E4615DB03E,E3E77604C9146F6D,92048E3DD1FE8F1B,C2EB38A7D8A1F38F,865338A0AA3C9ADE,EFD7F7CEE57793C3,CD863BCAED1F889B,382E45B960F1E4DC,00057CA765C14A75,731A220D7015822A,2E8D0BA49D12942F,64C0FB3628284FB3,4920027E14B3FA8C,39643B9E6EACB9C1,2C5C405CBC760B82,B86FDBE4E30A36C7,003A15CB553C57CF,8129198ABFF8C37A,CFA8BD3D7EBD2592,69A42A97243248D5,8572DCC676548799,083212FEA3349019,33711223A2E3521B,CA77D662D49DABE9,0000356FCB8D4EB0,86AB77D36E426F43,B53BED17E59AD506,0F18C810B9E3FB29,689BB0EFCFBD6B6C,EB1BEA5ECF04D7B9,F3B33781AD2A8DBD,CAB5E38A1A0C6889,00267A39A462F56E,5AAAC859F705C697,863660B2810182D7,C655623852C94712,F978775CC0A1717D,CF53E6A26E367845,EA7B2249636DC688,74DB5AB65A6820A3,000EE8517D43E3F1,E39DF59384355060,516940D460796783,3DA2DF556EAB6713,6DA532636F36EC8D,37D2A3A00575FB33,8B3EB34A51751957,D5CB888E67B56415,003EF3A5D5685ADB,A17578638CFFD0D1,A3B0BDC8768E65F8,4288DE862551D04C,EC76C26704EE50C7,5A76F62CAAC60104,B95612DE84A4DD66,97C862EBBEFFD4D8,000B0ACFFB37DF04,7E39AB67B320E53D,629D3191BCC2C6AA,9932A53835261415,F1F00D5CAB1D11CC,52EC6261015A450A,D8E9A89A0E8D0F84,8C179DCF7097DA9D,00074A99EBA5289A,9FB70BFFF8ED4750,43DC2DBC1E2CDCAD,C528DCD386F11BD6,F6053B2FAEF26DEF,28866B39342DD6DA,9F223AB0B3A27EF7,26E6B28B82AA0440,002D09C6D52D2CB1,F9EB06E44A1E29AC,E1691B4608AAA772,7030DE32136C0614,94DA83A2C91D5A04,19A75F7129D9916A,8305B60A92A34FA5,A2CB03CDDC9DB8C0,000E838171D4FBED,6890D12827C8EB11,DD89A5610FB90ECD,8B6A16DC98D99AAE,66791EFD66844A80,9F2EEB349D45AF8A,EA81A200F8F704D2,CCA9620AD65E1A95,002887B68ED25AA7,41E51983E3122B75,8C6CB7CAFBB98293,BF5EF9A2DA443061,E52AF6445B198B76,42160262F219F795,AD0384A76F0D9FCA,E052D9FDA4222A34,002843295CC41E7B,F62F64A930032897,839A9C1A4DB06A85,11E6BAFB8A6AA2DA,717836740A65003A,62ADDA57023A2B37,3A99D5AF87241008,6AE04E66329C6340,0026F65F86F85929,4FF684D87D61551F,AA3A64AB2946BC0C,EAE69C27C99CABC4,0485E2465ED9B5C3,815BB02E3507F306,54B1DDEFC3D5965D,3F1C9AE256BE9B9E,0000679B6D4EF442,C58E4CFC6AB0D46A,71B09318A5BC908F,32B7FA25E5989E7D,8E12D13B2C45E33D,DB5B7D57E126C92F,78BFE5DF6D9BA983,61AF5BAFD42C2C2F,00042111394C935B,C04B7F221BE5284E,EE9F2FC222594BAA,0E629FA6EFFFC360,4FC36584386E7A69,FFD2C48DDE886C9C,D90059909EA6C64E,69B96D2BB44EDA70,000E2026AA67428A,024F4B7F0D875F6F,80AFAF2E3C893AF1,1F3A3A9B70381E77,C67E951F078DCE71,FF98D854A130287B,CE10B26DEC72AEBC,59BA5F927C8F4DD0,0020B67EED4A79CE,5E384E46ABAEB8BB,A1E5EE5B35D8F84B,4C6469117A946730,32D4BEA7FF9A0827,92C643F0E48493FB,744A13961499118F,D2C0E689E7BC9A4F,00008CDA7A960CB8,CA33E8845574DB98,0C6F30903EB077F2,DFCA6CB76E169935,A55A756CEACDAF47,837314F504B45B51,D9186404BC21A02E,401172805D74ADF6,000A55E5680ED27E,220EDF056BAD7F11,0340695ECF52ACEB,6554A0AF5E6DA466,358B25892E98039F,061D9529DADABAC5,644454F4C45B52B4,36238FAE606F1A11,00151BEC9C6D5D3A,79435DE8C48EBCE4,8F38811C4233C19D,BD2965628C10026F,53D899CDB3C6D92F,142E92CA05AB3EBE,FBA5470A6D4EE065,429A1F5C35035707,0018E889439233D2,3A2D1F70E6986418,09B70B75D9C72869,B1AC1E0AB49E80A2,7A1F4193EEA09ABF,730FA050274A8771,198044E2B067A658,477F111DC18CAD50,0012205DBEE400D1,ADA30EA6EE2EC003,0903AA03A4306022,A91A816494EB5AB3,324ED5E8B31B1538,501FB61A9B31A9D9,75A9AD71ED9B9AD0,8DC2CF943AC2F8A2,001B5D07CFC22973,8C813E77912E5396,D2600477F742CD90,3EDF668A4760EDF3,A2DAD4BFA0B72E7C,DBF0DF3538E54792,015261B21FEE3C54,FC548912C684A3EB,003D18A9DE3684A1,33A88FE3E5F4AD60,382B7A5E2647DB77,6ED617D9CFF7F32F,F96792E7AFD8123A,192AF41A40EEE7A8,F713D97855C9773B,DC642906DD7905D0,001A52CAE814FD1E,5774BD1D79266211,5F22558FC1669829,688D9E5F7EB34203,80E8393042EEF534,94642BFC7357C575,2D9E53E8D7964176,649A5CB99486990D,000811F8A6C45772,FABB7D6BDDCA3899,AC0BC6B4C6C8CF8B,C87FED48EF7DA46C,F6DB6824F6726E77,37D856D8D31F1415,FCD33740C07D7932,028221115DBF5B1A,002CBCFF0C74D87D,E594F91BE9F2D97F,5DD1D33B54167042,DDB2D08A6DCDA9E8,A4878411A3A9603E,78CF233F501FBA2B,DF2DB034926A0FF5,3F0E7D74CBF3CA65,0018533EE702D5FD,051C7D08F353345D,F91E9459B1CB31AD,672E058716501BBA,7A4B08BFB8EFF357,EA22CF8AA49E4ED9,D121B4F8B14F9E1B,1FBD133977B5E6F3,000DF232C5DB6811,8301CB1180AA116D,C280CB5BBDCBC74F,F02E6AF164820453,6B94E7BEABE58773,0FE9DCAA3568C8C1,B71CE4262DC616FF,B323A6AE659ECE5F,0035F01821D95C81,C1821832420E2D0A,6E75E72FA307D006,63FB43B0BDCDC697,31B018F582088672,3894D9C4F282DD64,03CD602F00BDF9D6,A331C3054B903297,001611C2BF317245,B49E6EC86CCE5806,2AE12A06DD472CB2,4CB9CD503F02443A,C154D46D6B900C0A,0EDD623227632D35,52D7B85D014107C1,515B60DA8BA83252,0001A3D699C7C968,ACCB0CD0077C182E,7CECF91B7FA07DEA,F2DB804D7E20E9D6,24224F00F9A4D735,E89B5FC85518CFD4,4601FA9C70BC7A8E,BDE02C1088718120,0028BB60503D068C,9FE73C4C333BC0D1,0FEE2134FA27E04D,0BF0D6C269F94661,3BD61BCF3F078FC9,90A7FC707A8398E7,34B8D4486D4B161E,AB04600FAB32628D,000A4A777C17BBBA,55E4FAF39D45837F,88DF44B59A51B3FE,F365B98D86E320DA,600F5B640BBD41AE,B05AD63CBEC81FB0,9B9DEDC0B5080A09,06D960A9BA799854,001E1EE96AA2143C,8E0FC2761139F206,B41635C1C87BAB38,7D7F126807994D42,B8D58A8FFC5C00A6,AA63AB187B6523E2,2A79834E5BA7A446,9A7CEEAB2CD748BF,000D105B18154E6A,1852658608E5B8FD,A486B345FDE0AC8E,7F509B38419D0F3C,D5C41CEBCDADFA26,6523B1A161DBA642,BFE0DBB7CA076360,A8A2AB2CCACD9E4C,000CB13A75D5AF69,C87C3F50C5E68EF0,777EBAEBB832C970,0FEC8D351AD259D5,0F666937BD65C68A,15CDF5D343B3758D,32FDAEDEB1EF345D,D0581812E3AB9822,00377E0CF1D1A8F3,D7F7C63368FB1243,B492ED4FF7962CAF,9BAF2229DB6801FE,294E4B3C0047F275,CC12113EEEA66774,469C79F280248D33,329981E65745ED07,0023A55107A92FB2,A0B779FDD3E9B2BB,7278768CFFC40FCC,C390C13DCDB702BB,5BECC9254B36B3C5,52EC4EEBCAE1BA3E,8E5C41DB53A156F5,D0D0127CF2FF1628,003C04F6500D243C,A807936B350B12FF,76787F2E2618EBD9,CC7F9A44406BBDAC,5C4B28A3E009921C,5C6809FE86145550,26E054B74011983D,1393B0AAF147C335,000F59B396FB2DDF,9F9EA511400D532F,47DC3FD40AE4B824,953104D3D0395083,405AE9A503ADD61E,55E7A9B9FFFA03B7,89008B2C030481B1,CAF37EB41B9A8B11,00200D1D253D104C,D8FD031E99167069,314FCFB01A7BD1B3,95D257C7268C3A33,F7559F644C44E00A,751C092D5810A910,1DC5878B064BA63F,EE4D69231948B3FA,0000B78BA0A7FC87,200385274410CC8E,C96362205AE7E918,518C78F94C02F380,150D2788CCD9B0B4,1D7F5C2906CEE908,3A85EEA35B2E70F4,600CC91A4D967356,0017966DF3A90179,29AA19A0A9FCD5F1,D179C07E5E7D7688,7B13FAF81A009579,2007A98AF14F28CB,929393E833177FAB,C761ABCB14ECFAA1,B700D1C778B6D499,00363687468CFC66,55AAA5C5B3F1A91D,28B710F20CB1BEA7,D2670F86BFCEB43C,5875359498586DBA,5550FEC793C1A1ED,A0270FD916EC15B9,68B726D27BA2366C,0001EBD7438DDE7A,143C249872FF8948,37088EA28661A8C8,08599E40A9F6A226,9D028CDDE02E443E,5CEFF739DCCAB4B0,5E8B26CBCDBA9EAA,B3E26AFFBCCD10C1,000609C35A58E374,67B41B56A28FA0DF,CCB9002D37C28BE9,567A82C7ACED57E6,21831FE9D37F57AB,8DC838EBCE285591,01A3890DE1617701,6890A3FF54952BC7,001D373C2D66D367,6F0E7978B3CBFB19,3F81467F09BCB209,AC98192AE6C0B3DF,FB051941EDA240AE,DE5B2C3AB81ED6F7,A49BD6E8C991ABBF,13D1F5A59AD75E1D,00138B45B2C8FB98,F6038AE2E7303857,F4707AA79E0536C3,D70B0338B54FF65B,1DCAA07BF4690236,DFA4857BAEAA7D30,41CE6F348E13A623,E6A89B62DFCB2237,0018B5CFD48026E9,A57BCEE566F4AA59,60D3E45CC7A567AB,C5D036A5A6DEC6C0,D0512D250268D386,0E89C77778E1CBA5,9B5B6E28828EC769,19CFFCA36576C510,003FEB211CC777C3,90D71CA22BA1DEFB,28D48A27D773DDD7,6BBFD4A2A5C74EF2,7EBBDF696143C53D,456D2E497EFA20DF,A7F9B173F7AFEE8C,5D19F66CC66CF6B4,0026767B51797902,02D1C8363C80B866,89F3E2D68ED6A405,A95E24C55C0076E6,AFCD59B23F7DCA02,E6B4C7A01102E6C6,959B47A6C56635FF,DFDE5DB5B06208A6,002C0BE332A5503B,B76ED5D1CFDA2BBE,F53FC4CA931164EA,D836A6122A4EC158,72FC78AF23C0D743,9A4DCDACA1CAAF34,0546272B79C8F40B,F6158C709B0BD059,000672ECBDFE28AF,7F93392C79063E1E,CA2B9C3C752D05AE,74AE3392A702BD96,F7EDDAE8ACC299AE,4A549BDDA5081002,028DD5023E0939D9,21D33915E7948018,003DFFF57DC33C15,C7785A1CF9A1E35A,FF2C647A0DCA6801,A1A76B5757C1088A,DF21E599D19D4842,20BD59C7613E6A1A,F884C54A49D30A65,3595C0B54B2B93C3,003F8CB5DB59C9D4,A3B84D27D11C8FA9,AED5C16932179E8B,C669A83C03BF040E,F8FFA5165B810293,4C476848BBC647F7,B06F63A480D306BC,A55D3EF790C2747E,003598ABE1D7F5A0,25FDCE068555B7EE,1AE2FCCF650679FD,3213EB8EF80D6AD9,073BCC2F043D115C,7BFFEE700F6B42BD,DFE39E18F1499E51,9DC7247DF8866DF0,003DA25355DF3B5A,E439F0235F3C6CCF,FC7443A640521E36,FDDFA635FBE89B95,4F0FC835C9D5456F,D4D9D820A301ECDB,8E23ED88A020B22C,FDBBA6D168BF15BB,002763089050AD9A,1BDAF6BADCAADA0C,3DF265F00B33144C,1E2DF11983B2899A,64AE685E7C4B6E1D,37D4FC5034CDE730,9926675AE241ACAE,8260725D2875379F,0005E670419C10FF,198BFA07B317CD73,FE3ADD9D5B906B5C,E4BC6CB2B6BD14FE,08AD694FB2EEDD28,4FC2E49ADC9754AE,DFAE6044904BA2DC,FBE4E75757A804A8,0000D48363BBCFC2,C6B4E65A6A78AE78,41D33D74D4A3A87A,5E93C800FEB17D48,1BB8E06A3A767F2E,95A905FB76F0581F,7D70FE78A9174F98,A95C55FCCFDCD09E,001FE8AC6DA7D179,D54AEF8425D0297B,DA3402FCDF4CAC43,D4FA927B31B1EE5A,19E281382A6E2BAD,2FEEC1FEF4D0DB68,641FFEFB773DC529,A6A59AAB4FCA3E4E,002B6BE1CD3B0FD4,D8B2BF6336B75A76,24D8F13AE6A09A22,2A2703937AF88F4C,5BF8DA88C6323794,716261EB55C29CA4,D53381D9E208780F,A491085B24355631,0011240A673D961F,2738E5D11EE66A48,8E6743AE1B40E37C,BDEBFAA66C86B174,D8FD34B7F9374286,867094CC5CAEDBDA,42AA1534166DB0F3,A379C2B5198B7B98,001997A2490FDC26,66E5C8D7478CD34F,0825F3040154FA79,04521FDE6D759F9A,33D2D4D3B4917CDF,4462037D0750BA98,833052E1B73D94A3,E27B55835CD8CC8A,00236054F26CF090,561B60A9CD418B2C,F11E2D533A538A4F,9CB56FDE7FE3E3BB,EFA11D9D52C40998,3BE75CF47E05BE8F,ADB3BB12B233886B,5D7451BAAFDDD99B,0022835AB908895D,D836277F8D6A359B,D67AAE27F8AC2ACF,F44A990A34748859,1976C8AEE0504B1D,BA743CB2947BB953,C9E176F57CED0EAE,79932B9B16189EFD,002F22B81A750562,5922972EB406A39D,ADCB11A5E6FBB755,D73CC5D4B0432D47,6248769F8CE7433D,7B6C5E558BEB7F38,748A8BD776C4A779,968CB13C33814ED1,000AFE11CC5F69C0,DFAF1577EC5F3D91,F65B0D42A554417E,13126D1D39615EE8,6CDDF61EBA360951,49350469B8C4C2F2,EF61CE2348541EF9,1CF54248C71427B0,002DAA6AA458CB4A,64E5C1E5B45D5A61,D4071053AF6E22A1,27A6A0531053A4D1,C18CD6338490EB5C,14008FD77E7956B0,24BC3B90F635CAEB,68253B31625A6DB0,000D0E56AF256633,FF10AEE9207F0F52,1A41405D65C9C472,A2B82801E192CB3A,3DD0E10D1D64026F,55C02AAF61C06538,9FED93EDA7B668C5,58303FBC786BF5FD,001D9E9F689F6F08,1AFC2BDA67652B99,87D1A0B228735547,839DBEFB6FA14B35,8F1975F58851A5E6,B1B7BE616F7C06B3,FD18285CB539AB24,A956AD744E594FE5,0022E1C3C5501AEB,6DCC4BBDA204656C,627B52FA2A60EEC4,DADB039443B06287,1280590211A56639,F8355FA54A78A88B,3CB28EFA608E6B07,99CEA2D4AF34F95F,001246E76CF13239,7796A5EF5C4919F8,60D667310826A3BB,911A469B6A68EA2C,6656655E44A9A987,1EFCCE66ABEE8660,E3DA663DB872AF49,B532FB2B23AE30EE,00208757810354ED,917861C5ECA2289F,04A5FD03C69213EB,63B66D137445700D,424A0B237A2C09B8,F4FB6FB5A2AFEC7F,675B3DBDC326EFA2,7E2C855207E6A94E,003BE686CF5B2BD7,8CE3DE1683AD0D52,1333D0D78B84F6FE,CCA905C62ED661E3,F8231F2280A3FCF8,DA0C568FF4B2195B,B9140E523B7097C7,D1CABFB23F5071CA,0011216BE1A06AD7,9C4EFE33FB3BD580,3ABDA3FC4E44DD77,7DB6E2481D74DE4C,B2AEF24284268D29,E1CEDD53B3B5B8F9,9AAB7FB99585EF36,FEC9B24DA2540E8E,000C97779675D9AD,5070ED74A49CAE7E,26193FBD1859A082,0A3AA596D60B0895,05B3ED5A5CC03C58,E47F7B4A482043E1,1D712E7F3EEB2816,8F8F009878B7DFF5,000E08F0C981B209,413FA7FEB454F87D,B6A039D093AC1F8E,656CC21E7AC267F4,71723AF05685177C,6F1DC2BC560BE13B,3EF3A698842F2AAA,D7CB6EE263EAE54A,000E8146B6FA76D4,A7B8AC92C2932427,4E7A8E4B3F6633A5,1F43BE07E48949EF,177F16482C5BD8D9,2598A14D2083F710,CDAF2DE47D790E20,16B73B81A4401DB8,00022677754CBFFB,1B43C0B62F61B209,B443BD36230DB468,3789F8DB3B898CDD,B698C31C2972CF6F,97EA56EE7CEF2127,D6E41E2FE3D7ED35,974DFF2E9299C25C,0000201E7E9BBD21,01032CBE8580DED5,7D623EFF3906B382,1F451C5623EF1E23,3BC762D0B3DD7A0B,E62C5B2CC88DB5DC,7CB0F7E47328C9D2,2BD4EAC8F84C7019,001478C7A22F1859,83DF048E46BA153F,461A2DF5052600F2,F6D1CB7BE7D20369,0438050D1BED7C25,EBEB77BA4BBE1E5A,4DBC4B6741468BAD,C2E2F3F186AAFD57,0032BBDC0E8A35BE,534332E42F7D49B0,5F94D35758A39906,5410B1A227740ACC,5B914C56DEBB1795,7C03D55C8B9F73A8,435EBB793D6027ED,3F37A7B69CDFBA8D,003D952AF6131B9E,23B78F8B4085CD9D,B040C51424D9BDFE,5E1F0E87DDCF6C91,D2A577C645BE3C9E,5D756414D6565502,B17E5A7F184AF521,AC9EE3EA5605EF56,003FD8F12E2D1E6D,7762BC75FEE4BDD6,A71C1BC22505F768,8917C3B9BB85886C,57AC59181C333F05,E03E949723877E73,B29B1966301300CA,3AAD5DEED5A689CB,001A2CFC7EBAE112,937F21CC7A40F411,32AB41471B17588A,A4741E2D79B486FE,EFD7F181770A632B,252BCFB50CBA9AEC,B4B085DC35D85D95,DB078ED073A43136,0011E5C10FD0CF3A,B2995DDB56751EB1,61475CB78051621C,D992140134DFB45B,20BD696F5AC08F2C,A9270DCBB0FFA041,33A0AD97D275A4F7,1C336659EFF10387,0013078B7BD77810,8D9A8970D977BC35,8FF7FF2FEACB17CD,0F6C06C09440E2AB,B519AEE6A9474260,6C640466F6495B18,1F72AE2BFF8710E3,03EE916575491485,0007B9071A0B8807,DE26B1C59CA543B5,C8CFC60A5536600B,5BBF4572564938F8,863424BAB1A44594,8536190060B38160,37342A90F9504FC8,9A6A113F87B6C9DF,0010431B578B58E0,CC0B49200054FECC,6BD9622058A8176E,FA6AFEC0BB86AF21,360537D9BC4262B0,0A1B78D8BF9A348E,2CBE0D7875E58268,7D50F92B7BEC4F02,000D03CF6DA8BF3C,21D952616351863F,0582C73C3357753D,1DC716FDBDF61ABE,B618ED552674A069,8F4D5ED9DEF02C98,039355087AE81538,36DA9DB1171D9A46,002B00F486FB071F,5B4DFE5A0337D254,619EE67C6CA91E8B,190491B42C7DB076,F95C59C36F932D18,977BFD6428B83792,DFBCE28E439391DF,DB538EBC2A8D91C5,002D7D2D7BB24620,B978B273A849CC70,1FA17E2432E3DA21,48A0F1181604F66E,76FC9CD9DAD33CBE,A6AE1B44DF56CF1C,0A6834DC3D1B23BD,DB31BFD296910D78,003FFE55A747B56E,044B2598E8A4FAA4,5B56F36813866E01,C733ACE25BA27458,556C4E39C460D574,2A8AD2680050A051,10FC260E052FFADA,0B19AEFDF1D13AE2,0003B83C3A4A360B,ECB579789426D472,E586722F555D4E50,9018F044B193BAC1,44F4AFFDEC4F5FCB,D377F7C95594C86A,99E0B04D00E0C8A5,EA084B427849928A,00027FD83E634E13,D810F281ABB1E538,AE292504B02C97E1,35C39863FABE6A02,9D7FB0FA11581EC1,FC31DF35E68A982C,3D9447E135327F07,DFAAF68DBB7EB770,0009C59387FF0AC0,6F76B6DE7331FBC0,ED1F9E0DAC1BCE3A,722179059712AC05,66EFE705714D12C9,F6BA03D809DE5EC9,44351EEB3DF46552,B691AB95C3147F41,00243152DA8B8D1F,8F5D5EEB361DB71A,EACF09E48A2D0B31,7BB78AB83FBCA920,FD9AB8E86E1AB584,3EFC47AA5E3F63BD,B19935EBD9DD5E28,CA10E574A872ADF3,002D9FF4431EAEB2,18AAC54BAB10FF02,0E579D9A254AAAA3,B7E921FC5841FEF2,04AD4FC5C1DD8665,B0E91FCDF3325A96,3F81FC22DE02BDD3,DB1A561B961FB964,001E56E1B17D0EF8,9248C6A275990B53,1DD1E2D872D49506,6FAF6C40F49D83A4,F9352096C2F2FA00,85A8E0E7EA633B96,7F4185E5CA3FD741,351FC51A90FBA03B,002D18B380CD5BC6,629D04B063ED2A67,9EF9286E1D54AABF,C42DF4C24610CF8D,DA81D08928ADA23F,7A157034373C21CD,7594A62876CEE2F3,B45AB0D74A0C5A6A,000B692D273D8D3A,92DE665F128F4B75,749262938C74C334,9E56EEB93597477B,CCF8D9F390CE4730,7EA9F95138C7E658,D26A7A6DC216FB03,A98A7D529E2C1F18,002347E530715C4B,8AF84132B0B40E09,6A4F8E085BB98D57,D94AACEBD6014D0A,2D4FDB48666DD740,ECEC27803BB117A5,C2A302AD719D6FE8,105157F7CEC1839F,001F33A5AF39D9A5,73AF7589B580125D,B15227F5168C4DC4,A947998E7433BB29,A6A2D8268A0AD263,A8F86F5A9BA25C0F,89D602D1ADC4940D,5ECD02BCA2DF8D3C,003A9DED85B0455A,DCE45EBE971BED3C,EE00068011FBCA6B,6A6CE986D41C0F26,ED3BF79E5598F287,C9F927852EB289CA,6535BFFFF73EC737,A26440C56B6F6A2D,000AD5CAF0BB100C,FB40C81B8577C24B,6A228EFEF2857457,606FEC144877C8DE,8984BD0AE02AD191,DCFD0D64A79B58E7,230DB98CE54F6376,551D0DF8CE796364,000D9821E7501803,66FA0CDC8E0CBCE7,718C11096AC4FCC3,1D49B6A40F445E19,EBBF54ADCF2BE142,B34B16DF17BA98EE,6746F6445AE61E19,39CCBFDAC797206D,002918986EEF7A82,B7A4E6A9F1F887A8,71164A4BCABE0D2B,4515E87014065497,87D1D2AF5B7D6095,ED69DE2E6F97C091,BDEC5353C8B0B7FB,048B73620BA31BEA,0040519B449A5428,E9EACCE6B8C199EA,D7C16262CAF8B47C,6A7311492F260186,A9868DAABE661458,671745269B8B6796,07F9859D7EEB4168,2D4EEEC4AFBD4A96,0013A2A74EA8819C,30DBB7CC14A0907D,F1E1AF975DC6BA82,550BF6A3977130E8,B5C8215A5BF21031,1B4CB1F8B68F7052,59F9E4EF4530D84F,A2E0984532DBAC86,003FB08EBB2145BE,AEC77A75D6C1064C,0BD949FE95B6F61F,D28250908F82C557,C67C1B117CD2211E,994527CD48241B43,BF393BA0A81C489F,BEE5F0D8C230605C,0001D51A0451018C,485487D977290E1E,1FABB83E1CD14E83,9C0003502C7BAF7C,4701C389182D3505,C4E55F94EA70227A,A390108443AA024A,9C0013F8540A6638,0007C5D30D311888,6222D67B7DEF5C02,00D5B345A2C48DC0,C3F97C316CEF26D5,53D7F3A4DB1FA663,8F2E1EF8CE8BDCB1,DC418A5390574B3A,85005E785B536CE0,000CC08D15EFA512,6E7FE88A4FE82A93,C85F70326533FFA6,227F178622A173D5,87485158AFF435DB,EEE688D5AF114155,F18F8B9AC371B6F4,375917E165B046C6,0023AC104D20409A,6599CF835A28E6BE,568266138A124307,47E92285A53C98BC,9E329FCCA12383FC,DC8D352636FFBF12,8E6700BE5F703CA4,8568F92FD8C718A5,002DCC1097B6DCFE,F5DEDFDBEDA43F86,D1E5CBBCAF4B2E4E,0EB03E874032A100,96E0DE0426F8C871,EF19AA827E30535B,390E385E4A93A202,DF2D183BD9DBCF0F,0023805BEE538EE8,90685F0DEC330896,73CBE06CFD3438AF,97323F16EF5FC63C,7E97957ADDE1F736,8CBA507299385A3C,47A522EC78777051,B121469697B133FD,0003E1C15FAD3955,58BE1E194614F247,AC15236BA4577010,4BAA4E4F43132ADF,55A6D3A7A114339B,ADC996D4E3980C96,1F566F210DDB01D9,9C429275C44423CC,0036A996C5EE2D20,8393E8ABDDCC8D88,6D4A7776CA64A717,E4FA9430D0795EF9,5344768BE4006474,2B15DB1C6A0113F6,D3EE3C6B6CAC0B38,250E6F2545A50F9E,002F1179AF575120,F0B705E5EFBD0D9F,2CA23DDAF70419A4,9813CEB2414F9439,15FCE5687DA646E4,3160AD95086A78B4,8A69CFE5AC1DF33A,8AE956756A9708FA,003EED5ED7FC5A95,EB985341033C5C93,80E4431A6D2800C5,D623FAFD2DBAED6B,C083DB8B5952612F,6109EF683BA43CFF,F122B6C2C6BE5BD7,FE27E3664BC56806,00105A229B3DD05E,D8018D1CF18A5E2D,8DBEE2F119738125,CFFDA6A3B45662D8,EEA05C8337F8F0F0,264BC55CBD4667C4,A4B387224D8F1DF7,F1568F897CC01E32,001794382C3F7E48,BDD6D8CDF8977071,38103F5539FC549A,B07D7560880CAE4F,BCE8DD0691FD4C3A,F8588472472D9C85,33E0D0EE721719B0,4E91C4A796D7CC34,00168638C2C3302D,9ACBF96C32155798,3ACABDEE16D89D54,E7B4E73BF4A77C6D,94C7A950FF0F7EA2,07AC80B961C8A326,01EE277CF8607E14,5C0C0DE755F4EC5C,0028F0ACC33A652C,7AD6194C761A0E01,D8EBB01C4136DE05,AABB6F1E54692841,6514BCA14977A020,B74FA27EFBB729A6,415A527F10385511,BDA13B58CA662FBE,0028B9C34D873931,659A879965E9AB19,C47257E5ECAFA9B1,EDF7BDF91CEBC599,3702358EB37DD551,DD557E9F0C8AD8DE,ABC489531404CAB4,6628F096F7D337E3,0028CA6A654F83DD,3722C1B623888225,CE39DA15C6443D82,988FFA6C8B44EB44,09E6DC12EB30CF70,0CDCB498E47B3573,583C26104FF6195E,A83C0FE53FA839EF,00103193E84D370D,9E4EDFFCEBE2C014,FEA3A00863DB87DB,36C69CF7CBA4BBDA,94050D071BCBB370,F6A9D28876297CA4,9577EADFCC241345,F41B4F440AC293BF,000B462FF1523601,8B0129F157B86B2D,C4918CBF886C07EE,AEB59152E86262C8,7A907E82EEE0C10F,4290A4713299DA28,1EE1CA9CB5D7026A,742D211CE6BA0BD5,00099A25FB5CB2E1,CDBF3EDE0FC7728A,02B8B2BDD117177A,2A307DD68531D1D5,3737BC38595EB5FA,2C718A3B15481D39,5318BD220C8C0BA1,709B3FD332F5E768,002D11BF8DE38D16,1A73C01CAFFA5D54,F088C6F1E0F091C2,A21D8306D181B9B9,D261BCAC5D367060,FC97580C73186F39,9E653AC6EE1FBE6C,285034D605A37683,00054E87069A45B9,487E72736932F80B,85C52DA93E83A6E4,F092C771B3D0AEB2,32EFFC24E82490DC,D6BE36849C46A727,A2DD6C3CF9C48318,48A45B8F5EAE5088,001897A277A27FC2,851F3475010DDEA2,0980F7640BC60A75,2F8756492562B37E,74BA6F76C9E4F8B7,1CBFDE0971C4E195,F9261D02BF6C4D05,43BC4A79B341DF71,001DAB02301EC390,458AD3DC83E9F8E1,1C72207532A98FF4,C4C79690897B2D3D,C8DEBFB0DB9EB4C1,C97A1DF2EA713C48,F5167D4829BD2F49,F15703E7B06BCE6D,002D2BFB2FBC6E89,AFDD735CF259336B,5EABBB263BA4220F,F6BBDC53673FB39A,5BC46D50CD968D38,A1BE6E22F94C28DE,6273C238BD5BD908,37543501881119BD,0034104F3BD9ADB8,6457ADCA58B4E637,A4F0EB2A0F1B21EE,3EB261487E3E513F,25DA3EDBDF83C506,1AC321761190C5B4,741A8CB23A8CED0D,96B9D3778A1A232F,0036E2E1C3BE7330,0A1AAE273E4095CF,615CB764828B56DD,F93BC7E14D81B1E4,158497D36A719F39,3ED2DBFCE529E8CE,E8F9BA9339F6ACCA,8D431382F1677A3C,002A707F3DC8D4A7,C266257D8A9A1197,0353280248C35B9C,621F05A2AA4BB20A,3E144E3D3006B92D,DB31C3F1F881180B,D8C70D8B93C84CEC,219B176E8C8E52ED,003A4BABFDB97713,5BD39EEBA08882CD,EF0D8ACB1272FE21,647895AD3CFDBB76,783D0E2913FE118A,1796ABE1B3686D9C,8EDFD3930304130E,649972E2385B69EA,00130ED26767A121,7C869C2A14FB6898,22108C89FADFBAF2,118479A99DFBB001,CB336AAF2737F3F4,84DBAE17ACFCA0FD,CE9FBEF961397D87,3A877302901C017A,00262EB4FA206CFC,69519B0D6B8AD023,C60AB0B51258A079,BC8A3C53EBACD540,E066A4F1FD769780,3F91B988D2D2C9F6,2D171B0166300E48,EDCF4B161B535EDD,0018E400122FCE38,D26D09DA942407B7,0DA7707851626013,514935F9FB103B6E,978C728EA2C6B77E,AEC8AFEF4D216C58,2BF860FA58D0345F,8749EAF0C93837B1,003B9368F9E3BCA2,D82F48534DADB5B5,8A32C588B7AB6A61,5E86045423A232DF,FE1F0DAF1D0E402C,15C366DE0390C96F,A4F2B3187623D431,BA4C4854D5CE4C66,003334B371DCD2FE,DF896C1802EF762E,631150D17E75132D,EF34D9AAE8C60FA4,E3DEF839A85C09B0,2ABD3404C26193E3,0BFF5A2052EA7A8C,E79F497ACB6B0E8C,000E2DCC5BEB3BAA,D91DC76D45362458,4F247FE054F02954,C9EC4A98A0E65DA4,5E397234EAEBD211,5ADB9EBCB3B2C5C7,FC2746549B148A3C,654350FC85F16151,002BD82D0F559C5C,E55D5612FCC3E5D7,6C8B37611401C7CC,8E1F62816A8D4FE5,4083F3A76C3FA3BF,8BC27583EC61433B,BA31A88132120FED,5A801FBE6CFF5DB8,000C2FC170E7014C,A8BDA24A0B1BCEE7,F7AEA855E2B95A5A,850DC131345EFF29,7062564DD7463144,534E31812B42C4BB,61EBF8D1443CD87F,4C2F727FE7A7F25C,001E8A76EE559E10,1DFFA2A656B93C33,94258B872E2C7C1A,56A45C97A342F738,A31F848536C007F1,FA284F77F9CBBCCF,74A095A8FBAAAC3F,332AA94E0D3DDF6D,003D9D778DDD196D,46029A648709441C,2ED0F63FD21B017A,733E104CBC8776E0,0F48AF8E708507B7,E547B78D1420624B,279AC329AF8464A6,571CB791F2C81712,002EB4203C9404EA,226DE8F21327E8BE,A7DE9577FF89481A,D14209BF23B45D8A,2425C850AEB947C9,960D07883188EAAD,36F09349E6C2BCF1,34CD80E354C09B65,00335B783192734B,931504F68F084062,B834DD997F86A83B,07E5FF6895D24BE2,1C9A082106A65479,0F1840391ADFF3BB,779BEB673009C70A,A2A576D3F7A01AF0,003280B8E02DF1C0,932936D39E9AC6BD,5A50A2BFA1803C12,DCD07C5F5BC940F6,3323E0838AB7907D,58C2C72FAEBFFC75,77E05F13202A10C9,B7A70388737AA74D,00404015F83E2AE6,6C98172DB08FCFF8,F7505F7DC0BD7D45,46CEA6D56655FF97,0B83ADAD4C1A2762,737A13B1D9C5286A,F0B72292F22CDB36,E217E8913145F53B,001B931D1936DCB1,8E2EFFC12DFFDA78,6FE86CBFFC276117,D0BECF5E06DE2C5D,5641063FD1647BA4,EB1FEF452777D024,69AEADC2AE3B2961,4946B977DB713E95,001CE4CA362E1097,29C6301632B41313,F88B03EDE62EA0C4,F14EDF270D4DDC38,D06BCDCE07E8E46A,AD541F745179EE8C,625004AC08C81598,B61B7108E656CF17,0004B2C2482E1E2A,6081B5A35E1BBE1B,015181B8F439FD5F,447F3313A6F418D1,40EEB5B8447557BE,A2C50EBF2FE4D2AA,717C64C062D6CC2F,E52D08D2CCE38E6C,003314A179A8CDA6,DBC3A00DF8FF3D5B,FE179750A29BE18E,38A0D7F0BC8B4F3C,A2BBF5C46B02DE61,6CCCDA958C077AFC,B8DA6B7C3427035E,E6FD7CEAD00CE5CC,002C9DA58D903358,C3F19DD4D122A8A5,AE40BAF8112E18BA,DCB2E106EB5C161D,6380C93BA0008A38,67EE0F3840D816C8,1A0F599FDA873F62,0A3D2FAAD4687CDB,003F0CC736F2F962,85E160BC1C34081C,3576E078C46457BD,3105EEC353E06AA2,0B9996D8BB5D1602,A4BD8064978E8AD2,27924D35F1B4A053,147F55CEAE896DC2,000694782164B8D5,05AE26B7F3FEF5B6,753A85E6C69F67D5,54C9EE9F294F33D2,4D7D4FF825A01C8D,15F192E9304EEE40,49CE463FC97E5DD3,524BB0B5EF7BD929,0006C708D8337EC3,870D677F0C1F1FB2,360A8219161A017B,719821B21EAE4D21,B1AD4FB02EFC395B,90E53458CCAFF9B0,F6661564663DB7F0,CE50469C7014112E,0020EF0E298EA96E,FC86397B542F76E0,3F6BFABA0D9C5BBE,7DFDCF99017E3D43,DABC81DDC14F817B,0C4BE9923D3C20CB,D0880936FB7BFFC6,391927631599616D,001FAE7FF590B081,D753E11B214B4FFA,D3BDA48726738E26,2FFC245348DE3269,17A7A845D777D01C,13CB180406F449E4,632C88D7E6486195,69183E1510871DAE,001952436FFA8E44,8320E20E6C7A5838,6B924E6BCDEFF7BB,EB8883CFFAC30D0F,609D36C9713B2315,4964BDEB117B2141,BE825F5AE7BB642E,63CA5CEF57521566,002089470880DE66,F69400CFED890E40,87E62FBB53B1BCC1,36542FB2B599D081,03070B9EC5C774C0,554B3FBCA7678803,CE25730BCAD959B2,298D5782FF741880,000EED975025ABAE,2E45EA8B3F87126E,3F752C19FA2BB30E,EC29298DAABF0ABA,274BA6B9759DDB98,18EE26729B77167F,4E8368440E47534D,057149676C82F798,000A269EB95DA448,880BDBEEAF1CD527,DA1972CE5205899D,2AFDFB3736DC256D,A3ECAB5A270BEFDB,5BE8E995148C30B5,863A9185D16A3F87,F9D6B861EE423950,0033D9A09A76EBC7,282D909398436888,0E71242F036C813C,43899F6261846D46,AA129A0AF05662DE,40E77B95D6C51870,AFDFD6C10FFCD959,B689A51C0A188F1A,000980C671293ADB,B71DD2AB18A5EB7E,5DED95C835D12185,BE2C986996564C89,6FBBAA45ED768EB0,97329D9A20041CD0,AFA84FA64DFD7F90,9EC71FF053FD0B8E,00207EB48CA4A518,9BF790C5C7621006,E41811FD0C9C2393,CAEBA0883B8034A7,BD6A09BF63B8302A,92BC5AE21AC17D03,BBB696B13907B58E,43A3463F150C8E15,0022A8E62184C142,D30CA6D944F52040,62CCD86C88EFF727,B3FFAC33F174AEC3,DF061A159F0AF422,B4858744F3CF178F,91FBFF24F97514A8,CF58709E08CB107D,00360A0BC8401278,BF64C2A921DDC0B0,7D53CAA19DEDC2D8,36AD298499908F5E,06A5EA2407FAEF0D,49BBEA899B85374C,320ADCABB6F85926,F01715273FC3FD08,0023AC3BA02CBED6,847765BF27E76147,F73AED5EF79E7FA7,6E93D7B1BAF4962C,895C99D9EBD1CB00,00CA8D20FEAA898F,14FEF1C142C6AFF9,A14CFA7DDC5CF9EA,0036A0FD7CAF5A77,1619BE2F760CE01D,A84964A38BEBE5E9,5B500517DCDF1DEB,B7668034422E918F,9C8C449784152E68,0F80FEC8A03C9587,A053DF19EDEA4D39,001CB41FCB757257,751FC3803BFB8204,1EC2DD591FDF7526,F43FA99676577E77,B7FD8E0705E4A7DC,5DD5CD84315C50F8,8581FF37893C19A4,E653A370389DA3F7,002C5DB2C9F01D15,BC34337D627E77A3,E1626E3D72452C7A,70DE1564728AA22D,482EBD51D6A8F9D8,6C8C0246D118E880,178193118D4A6A8B,37515A9635D0AC9B,0010C5FB8D66086A,8D75FD96DD8C81A3,7662980C9D3AC74D,869E28CF9073FFF3,231D83F2AD978703,36E402076A0C2550,9E548D6305DEA787,324B7ABC5F912673,000E16B6280FDE49,3A4AC32AFDCD5846,A318B9689ED6C60C,8579FAF06F9A30B2,166D030A2C6511EF,55F017D3155C6A11,F4D23B3651F12CC4,36FC915F6D1B1B79,001B5156EFA8AFD7,21B3774BCB607D22,C202F2F51385B197,D6DB733ECECC7888,1FBD8B7257800194,38053A2D2CF74127,0745A3E878A805D6,EC27D34727D033AD,003E909C9D6D35DC,6D75855D23604123,E135C5EFC3800248,0D9646CADA685D82,90EE3095C75DBBD5,BB91CEE020516859,44EFE3131D53FAA6,2FBD2287304B6F22,000FFB8344BB777C,5E86F72F3DFB8ADB,D3183F06E5859F08,1AA7BF4B08499E75,3BFB423E7F975994,5A24C0F8505F1400,296D80969047D047,224AF37B38E7DCEF,00316B81DB7D519D,D556F1BFBDE45C8C,7857911D150E1EA9,427127DB00CBF1AD,ED561ED11A700056,2E2FF7A6F9AE997E,54B5C42BB4574C8E,DFDF48361A40B1D2,0037926AAE14CD81,0761F69BDCFAB61A,80017266A58591E8,A68F29EA4B1F10BB,832FFEDD690ECDD1,D40DBB57A0D750AB,B310927E062EC566,DC6D11D598DE9C70,002BF3EA9E582926,1F09BC2099158C8F,2241B289DB9D0E84,5D506C6C6364B64F,44EC09B7C5803DEF,F50F96FBA2C88EE3,4F8CD6EF0FA4F840,B38F14E25E654735,000E4D6658C481C4,1557C8F956364660,53E1700069B7DFB2,F06C2E6DF8A7FF77,F25092F7B55533E0,6E7C0B6C6F01C6B2,4E3C12664306CD2F,A16087C127B9ED66,0039D9F9734E2491,53490080F7D2A979,E64BB39D01436B15,1819BB5DBF62C865,D65886260CBDD1ED,EB3F34D2059F58AE,72C684C888427808,2E7701347760B7AC,0025A22F4D92268F,F00574B00AC3AA6A,B668AA4C73A1C4C9,E31F13303D0A3FAD,50ED2F715722AE3E,30EC158F772AB009,09246B64F5CB283E,72C8C05D8BAFD866,003A3FDC07DC5113,6A9F9853906A7CAF,0103E05623C27E55,13014AC698717188,CDFBA895AA7A93EA,1B40216B4CE7C0C4,5E7D125C81832619,3CFF6E7BEDE51C6E,002BAD522917A5C4,56265FDCE4A74D8C,1504F17C23CA1034,B813E32443FDD326,9EABDCA97417D7B2,6BB8A50936F5C95A,AE5E43A7B93E47FA,18A76F932D1A7DEA,001701C0DD6CA3E9,884325136FD15B81,30ED0DC6BCAD72E1,9863B1F07CCAAF37,065DCE02CB3D8FFB,A096A9E45106F120,E068618AA7A6CA7D,1F33F0158BCBFFB4,003A7F540214162E,8C5E3D576661F672,96346D76ADCA900C,FCB868282BE7465D,5AAD06FCD891A013,1141757232F802C0,B68C2F5B189DC2A7,9D8A531D8178C340,000E7875081DF65B,598CDA137C877CF6,A9B0039CCA7B3969,B3C2925944A0CA1B,198182942C40C012,EB3B8D9A512C3C0E,25EAE61268E7CBFF,35B8C0353D18532B,0005417FE75CA8B6,1D64ECFC6570BA7B,4F25B5C4B9AAC860,75F7D1DBAD1DB97C,C97A6B17BF75D8F1,FBEAEC70EE236CE5,240E9124AF3452C6,C244E2DB791D42D1,001D5FAF64B2D62A,B344E619D3809880,8E1CBBE4BF4E5798,E542ADE3DF804D2C,19258985A2D0C6F7,46549B04264771AE,640B35907106CA1E,0B81773172B54C4A,000E8D713C710A1D,5D3F63DC32EDCE27,6455FE0669E2769A,295CD68C79668922,2D32FC0E28724F37,B77F8B45C5514B6A,020FF36F455162E3,5714B74F74950DC0,002E9DD04750DC41,01909B8D496C0568,BD6BCF61A91FB453,68DEA1A4A62B6371,C88E4910FD4AF11F,CA78DD3659F8CEE1,8927A959E09A9B96,58AB890872427D28,003394E76946AAAC,E8F4F96835573AC6,11068D13141BE2F0,97212C2D48103C8F,3C153CD6DE51114A,0D2B6D52739AFC77,9AB4D1820A42A3BD,6F9BC53C2997EF6A,00358D39CB0D388B,FF58C9418E0F5B45,02AE6CC8115C06D0,99215BBDD1416C9E,3C1D206AABCF3678,CDC53B7D1609AE3E,D60AA1A8B3E01D22,F4D874A8B2726C20,00318E3FED703838,3BA05B4E21ECD38F,435F9A599A820079,6D81CBFB4E3F0F90,06960374E454EC37,FFA6FE49C1F11780,7D6BE3F787ECB837,BEFF7CC2E2B8EB17,002A4597B10FD71E,B2E9C7AB07474617,F286426BC6425CFF,90A5FA917FE559E3,67DED3AB920A793B,E1E29D4E7774AECA,7B8EDF04D2A5B4D8,53FAFCCAE50C1CCA,00251C54AADEF798,D503241A22ABB492,B7D3602E0E2930F3,2C82C3C166095352,A3F5B7B41D57CFE2,2619B01F9A58DB02,B010E6A4F4797282,A55E8D78BFE34B26,0009339645ADE491,5BC38F94B6021FBE,E37D28D75174BF1D,80EAE68943CED6E8,05FE358C81CA4D8A,823699885D3CAD6A,CE4803B55A631D64,D5FE3DE5AD8EA01C,00215C967D273291,859950C1CEFF5948,CAB99C414A6B2602,F086E38A715E3F6E,EF9FFD6344D7ECC4,787BB1D74845D799,60E985425240C62A,F2A8F5DB7B5E96C0,003B1ED2569B93AF,88A20879AA253B27,36DCED442A1BCBBA,0C87B8D8183E0500,A0D960E795C35F0F,E56C500CE5A33CD3,3EBD5250F2FE8305,81C49271A44F34B4,00073DE467453EE3,14675BB4F77506F1,6CBB72F1808807AD,4A525F658A191E31,6A73FC600B459454,3F8B5631FE61F4E5,1D35CADF8D9562F7,15B509BF3F3972C9,00244F905C4968D7,C597FC1CAE350C45,7D2DF1388D96A335,F1135C1D58F2C525,3515FB65EF91C23B,00DC52E63537C595,30B58A0108D3DF9C,579D3B7BA26BE5EA,001F1B6DF250C8D7,2B32FE9EB1C86075,E8602DFDCF446E72,907D6D33661F2D08,03D8B8F52476A154,4586DEBE0B36AF64,857CE69A559CC752,11D8D1551644211A,002D6CCACFDDFB61,8B291B4BD49CEAFA,02FC64A4A7C6EC4F,08717E1F538ECD13,3F1497B05A29F5D2,239693F1C8987F91,52C1A8A992079900,02F7793490DB41C7,00242F438D1096CA,3B796CE149DD490F,DCA924D16C92CF4F,FABA43014DBCD025,E947F00DF3363113,483331E19E83350A,78DDC1D00AB7A993,86EDEB6F8554CEF8,000493E759F6BD72,D172470928BDE4DF,DCB9F5EB867807C5,836A5A8EBCCDB936,769211D88F9333EE,5B74C9E95485B0BB,3FD2453F24D4DAFA,9C49A47094430E41,00376310B03B28FB,43EB1C369C0BA677,F4C4F04C5AC623BF,357A70000815A5D7,AF70FF577AE4B07A,53E2199BFC04C976,DEA09246FE4E57A8,FE0561D08188E2CB,00174CB45FA78931,75ACA19112564E12,1C98190ADEE74C2D,492CE2495DA843A5,04A3931F1AB3BF78,12D683C6CF030E55,576712E3D516E277,22613915A5D90D61,0008161A40279081,681A4BBDA36240AF,BFF010CD44159382,4159408B1F347FD1,FA94CE1BF78EE1D0,E3B1EB724973739C,F4F6F25613B54596,9BF18B5298D608D0,00266E896070FF67,92BC14BBCE612028,D42BE17A36EC5BD8,F21C64A17A2ECE8F,AB827F57654C59C6,20E8B219586B25CA,DACC3ECD32A6626A,DFC1E3322D713BDB,002D1A038982359A,5A1A83F4174823AD,51227800A9075ACE,6AB7E04E75B10D76,583D4E205817AF03,5D3E1EDC1A602E96,9F724E0EF57D43A3,24734605140068F7,00135E7AEF73FA28,CAC5F838BA4DA5B4,B8107583FCB904A1,01FE760B7120236D,45336B0A30A2EF2C,78310856FF9C9144,20AE64B27BD95A34,032454DD8A76C211,000C177E086B176C,ADB8EA3079C6CE80,9CE810B08915ABB5,4FBF16BAC97009AB,935B374058849ACA,82740F09A6B1AED4,42B2CEBD4ACACCC5,A88CB7328231E5DC,000A7C32935D46D4,9101EC5DF2C3F879,3E33A1D74FEA9698,36E831A1D2B22DAB,1F935BD70AF6772E,BFF1F2BB7C1811DD,3A8552A303A5A9EA,0F193A4933223F15,002698C20F0891B4,2BFAACA813AC955B,CBD999F314DE5F44,54602358AC316BF2,57A1F0414E24ED9B,D20021B2F9816C97,D8C4D51966F84DD2,5D78937E60121F5F,002D786ACA295700,36F19BD72EB8EBF7,B5B2FF0CBF0FC4C5,35EF2AC1047CACD5,0F206FEF57970573,8A5BB83F39D4F514,620C196E03264A5F,25F8AFB54F55E724,0026F4D524DB98AE,27B5E559F1E8A402,D195FEAB37F21302,E891F0DA48D501D2,3D1614B4F4CA957E,5E81469A184A750B,2B38F2933D2EA87F,E1E5EFFB3D034910,001BC2557654AD8D,F3C0BDA14A5258CB,086CD6AA7454BC3C,1F4E16DD3768F293,93371157DA0AF597,8115A390AC502422,C9F2C27E03675EA5,A9386DC61D6AB272,000C58756D9580B5,1893DFF540C150DC,840AB53724315EDB,FC9AE229A43887D8,FA947E1D1D078CF5,62BF0F94FBCFE499,10DF2E059DF14C2F,6E3CD4D273CD4D22,001031F21A998992,C745DE7C857C656A,CC27E41B08D8190E,010DC6C4D9190A75,585BE9F07D11CAFB,C3F74D2675D04914,F2615D13F264BD31,6B29F2BE60888DF9,002E08BA8F165E63,16B017E63F66BCEE,2C72108A540F0AD7,6779CE72F4CD7238,33B2D04C5B9551BE,329F3FDD75CC6268,61703502460D3643,7595891718A8F623,002278CD0726DE51,7AF89B9A35C24CA3,765064466A46804B,AF025B26E4CA0B51,25BC736A017E6107,7AE01265321D4E54,EEBAACCEA8D9428D,602857CEF14C89BF,0032DD7D2C027B35,3269FE313104AD91,D03D81EB80F26B13,4FDBA7026292148B,77BEECCAD2C7CE47,24F677338DCC70D4,9D12B135C466C5DD,65CBBBC6C60ECE0E,00301970DC68A44C,1F578D95C520E17E,910BCE8DDF494442,96893C34C86CD92C,C57469476A06A48C,5F26C5590F71D15C,0A769EA6C3EAFE69,544C0EB9357204D7,003B1BC2463FC9A1,762780433A863860,6BA571E2669C0324,8A6AB390F6D57D59,4D88882D9CA3A4A9,90027EB59CE14E97,8F5C6F222F5F38F2,2A50E1014F9A98F4,00107C069731C7B1,67FC8988CE029644,731B04791E8C09EE,8AA284A20BBBAF11,5712BA2AF9C61E64,E1E7A3E66C936764,06AFD2A259C4A92B,AFCF7B60108E34B4,000A5A310144709E,2CB4D75B1DEE55B2,2427169449BD5976,269BED9097E2CC96,C945DA918FABEBBA,C8A1EB2A5B8C6ED4,3254AF7E1E93696C,DB49ABC3C51E9E61,0011A1F790B80985,1C96F093D6BB0C59,D96B6F8838E26736,EC845C2017A6D24E,02BEF364A1DDA5EB,CB699BC30492E859,3733E438C580EEA7,FD005FE1DED9E2D2,0005B682CD990B07,8870A69A0ED0A61D,D239B3DA9F5EAE12,4E31B8A98049FC1E,B90EDB07988AF1D3,B42481BF794865FE,1FBA0A22B1A743E1,1F9B8E47CF9C1AF9,001BAD534DEA6491,BAFCD93D63EB639B,37F67BDCE160E48D,66099B7FFC907257,7EB429FC87310EDD,95A586FDFC102A87,960A0A45A4D2CB82,E2259B661CF1662B,001ADDDB643C75F4,A21AF945CF86D780,6A4397397F0BEF21,9B6BFD66FE76D0E8,B24C98A261F2D5C2,5E287B95C622F4F2,185D16A79D85B0F5,94EF9BC265037B6B,00357F30BD930E56,B69400CD8075A7C7,24E172AEC932CD94,4E9938E57E92C3AF,DA8A9B0428D4CD9B,4B27F45DCAF15CD7,58B206E0FBEAF1C1,764F3A624D27C948,00354AD5A79B2697,DC70BA266CEE00B8,FAB69C20B7ED2ED6,EA807E34D890D0EB,D770F56EA9BF7373,B34EF7E894DA31B4,0BF4DEEFB3536490,2BB606FFA12F5B9D,001657F7E68E2BB7,090D71AE6FC33FFE,6390E21D35FA941B,C664F99EE1B769C9,B4AB5D2E199DC8AF,5EAF54742C4B0845,E8056A90FF653C33,B0CB454FCF8B4D50,002D7225C05825D5,33EA0179203C0587,C4B71E3B4B58ED4E,1D2BD05541E803B2,023EE57260C9AB39,978EEBD88B9D2124,E5743F3ABA56FC5D,D0F58FC4CB312D8A,002A1F5E7591933B,6BDCA273B9A9CF48,26CA62CE1CE6F884,34D4A9DCE5EBA8CE,894078AF66E14568,E3013DB8B3C17CB9,7F66BAC17A933A29,B95DD150C13EE210,000172E1BE98EADD,F07ADF6378DDF9DB,2C477EBFA0595889,89385DAA43695FFA,F63AF0295CF015B8,7D07268F2276F1EA,E64588B9389B84A4,E318639116CE63D7,003081185D36F1A6,DDED725623FDF5F5,E17576E632752598,25B0A134DFF6165B,940484CC28A23208,F599D78BFD2A063D,8B5C50440E13BFB8,4928E2CFB3AE0BAC,00401F95B302CF55,606481E41528ED41,037B330A213A7D9C,23E13CF14FBE4510,29BE8E06B4EC39E2,8E99672EA95F67CB,59E0BD78FA01710E,0313BF74DAEEE46C,001758EE338BC292,1316EF10AA5FC7BE,76298B9CC8877987,790905CBF865F945,1DD29234F6513EE2,76D54A5355736862,00A64027E9A3507C,F3173C210FEDC6A6,002EDCCB7C7156E4,BA5EFF9BC5990F74,82D0EBE0A3A69B6D,D4144B1858F09EA5,4244363774F9BC35,FB049701F6D84F59,2A386C62F962A095,AD0EF8C2B5957318,000DF512BC960287,B16F9DE060EC1780,AE382182D613C417,86CB5E35AFF37E01,9C7CAF6FFD7EB26B,5B897AD85C121394,2AFDE484C6234B74,F4858493823EDBFA,0028BB5EBB68524C,0B575C21C276B502,86951F357456C3F3,97F138980542E326,F08CE642BA6E5CF2,35F30B3E174249D1,F5B7878E4E94B9EC,B3318F5C23A24416,003DCAB3F64C67B7,D08215114B3E4FFD,73CF41317C61FFB6,E14AEC68EBE278FD,80733DA76A8A7B8F,449D215A027FD9F1,9FE3055D9D06E3A1,DD120534462F989F,001FA5B1FE7F61C4,19C55B16B147795F,F43EB97876200800,8736F821C40AE840,DE856CAA7D85CAED,0939D5C9777FDE34,F031BF32A439FC2A,B1F97533A174ADF7,0033AB4E62C8B407,67689EA54A9140BF,040B542FFAF8683B,FB2A0CBFBCA578A0,E6148F4FB11FF6EB,F299185A8A6F654F,26CD23CC4F2F2852,2AA61F40E4CEB2FE,0016EA8B43049046,8B93B28D108F877B,1BF1EFFDE73429A3,29481B4E9F5E757C,FB697FB603D2CB28,416FDE897F029369,5D263D6EA954D8B3,76A389D8B3908551,0033F3F689470611,D0C7601C7ACD7D3E,BA8B73E7EE79EC72,0077C7D23BFD1865,B24704BE3376E580,C150C52DD274A478,312B0E88391F63C4,6FFA25DA00F02643,0015483967B034E0,2577221796FE3FD9,1C61C558DE23B6AA,50943ED48708B282,678D1EF2B0BF13CB,FBC319787F4EC4BE,8CA18841124095EB,D2D0FE718F707D5A,003F4A743B090B16,4B41DB3C8E979716,CDC4D5AC75E2DCD3,03D66CE225260B23,16CB5D655E870AED,294A7DBE7B76F001,5F1D6D2B83AD9FBA,A5C37A87C61171D7,00248E8F31F8B248,3F2C6BD55DCE1E1C,237217B590A64B8C,88CE12949EAD956D,150678F2D821DB03,E2CF9DE37AE3769B,B9D36211D7FEC238,4CEAEFAF83569B2A,002F2146E53C90A8,5323DBE478DE1BCA,009F0513DE4DC6A8,62D555CB680D6073,B8BB43E5A220524A,3AFB026E911F7F15,A96D2A955F827095,4FBDB64D89141CBE,0004ACCC1AAD4E0A,7263D2A6C5A64478,BCA2EA3F38E58B1F,A3F8185614F10023,E7640830396A9B50,6D48B96DB0644668,74A43A3D09C82711,F3B97152C94DF3AF,001995CA9C8FB993,6748F1A9AECCB15A,346A16BDFA839A68,DF64E56FA476BBC9,4EFF93C3ED9E3834,26C6AFD7A0A0DCF8,FF1BB950EB997C9C,3076BDFC33B293A2,002F97E7630EE907,B5CFB75D827D5473,2F35ADE60C75036C,4E132BA5AFC8C946,D2D70B5F7ED5890E,C402F48A842ABD3B,9F5C62456E2F6D02,A74A6BDA84232719,002F1EDCA7F17243,8BB72FF78C904F14,5668E12071175F64,E20D6857572F89CA,8E72B0C795ED0184,8598D332CF40C1FD,CB99BC9CC9187EA7,0CE9356E16D8388E,0028BD723A62D14F,BC4925017007C28D,38EF5BE711B7CBAA,FF33FC935AC3E2F4,DA30C492C301D99B,822C89AA284E7B44,0A7E9D563C150507,5CFD378C4705BCA3,002CF2A056577BBB,F8B27CAC37E67F26,AAE3146D38460B01,9A97DDFFB8A40516,04F719F0525C4FE2,9BD62CB9C2E2A9A4,BAB281063BAE8B0F,81A908BB20B98F1F,00155C106FDA3714,7B21621FE158B095,C46838332E76C163,C37C7026284DF410,CCAF241D62B3972E,9123A41D1E12005A,F90ED47F80C8EE51,48C4E190009E15BD,001DDE032C1FDF85,A731AF3882B741DC,EC5C00E2B4D1651E,074A948EE491BE7D,B788346DD7FA461D,F92C2ECD141C81D6,020E79DD326A56C5,83DB23BC53DEFEF2,003704AFE3CDEAC0,1EBB9ED34710F79A,6239C74048BCD2B8,15FF4FE8045F2FCE,0E5BAFDA28CBB2AA,9630560B363FD863,D1832F367A326ABF,11ADE34CD7EF0DCA,000A959FE95D1461,4101790C51964F97,8A8B77E57635BEA7,91A4048DEEBC229A,17AD50335BB8D9ED,5B6918D11872097F,664F96DD297F5E5E,5C6CA60E288D1BA7,00320A1A2B16BDEC,90F7F1835AE4D868,F8F9106E6041F3FF,A394957B5F3A81D1,FEB0601638FF3128,7286B43FB253E2E1,29A53415A6B515EC,07494D97319E5FD2,0018CBE97689EE86,7B42762076C5C912,30F27A56856E3CEE,805433A3B3840920,C299BAF1A3001762,CB9356957CA1300D,B2A70B10DB90BC76,4A9D64677CF85AB1,0033DB1352D6C0F5,ED268B7F54689C9E,DA1D40375EA1B432,3B82C9F568B4617B,EFD204DC1B2DBCA7,E8D35F09AA705295,055E241914C340D9,349B8E1185B2EB5D,00349012BAE4A621,976607A0BF9690D5,21D5948E841C79FA,908F1187C94E5533,69C539F458A9E262,D191DA26667A4CDC,1E8499283BC25C47,A9D7344421DFD344,00287848F812D847,CA82898C0AE2D708,82E91796311A6AE6,2E97FCA5E399847D,7507F712E29CCD1A,FAEBC8F3F6E96B9C,87460F8B6602BEA0,A61434360CB5DA9F,003CE9270BEDF719,90FCD82CD6B0B07D,273DD3367CAA575A,770520F38278D23C,57B55C49FE51183D,B3C8D3E14CBB1664,F3B99AD89AA02490,74EC852786D5488B,002EDAEC4B4AD590,261D4AF4D4812CDE,1F7F6F0CF1DBF2E6,7A9BB69B6FF02872,66799EC80AEBED5D,D9E077DABA39A9A5,D98828ED1C1E656C,6B62FE73D779016D,001433B3A587084A,4806017B9911898D,0ECFBF96FE313488,D7583F3378D614F0,9057220581D001EC,76FE3911D83BF101,29989EAA3980789D,BFA7D29238041FA4,003F9F5CADD12D66,C7CAE2C2516D534B,F2A1CE3C2154311B,3F4C80CDDA6C0DC2,574A21D5423043BF,0AF5372C1751D89C,867B8EBBB8C70A9A,93DB221FDE4688FE,002F0A74212FFF5D,8242B4509BFFBDB0,027B28ADA922CAC0,3842583DC37E1F8C,C2913A9D59599D36,917B147910359AF4,F99D2B19AF549A8C,3AAC90C9FE047BAC,00243899130E498B,320A6CD83EEB3349,4309A0E16F761129,6F61A500F52E3611,7E1FB58804E3844E,34F9392144A727AF,8543A609FF110F5B,DEE669D741C6D287,0017693E124A8B98,6ACE0908D0C19235,7C9A5D2025400D3A,A9B299560CFDC998,C9A0832D3919E546,587515B12579CB92,41CC3A94A012CBDC,773B34A0E2D69B17,0019792B9FFA62CC,23A8AB9FCB7AB70E,6E360CF4BB548573,8204C0A13498424F,2E8700FE023EB9A2,71DD40634DDC5868,D418218C18E28C03,D83556BA7D4B2F71,002FDC8292BEC922,9D08295CC96A69AC,5655CEDF6352AE85,13A574CD8B81CF0E,4F970F4D47979C7A,0575CD7C2500F622,4E2EC50E2689E051,93B7EBD6C5A8F438,002D98DB954312A7,09AD618C930340C7,9598D8FF9E6D915C,E9B8E5AC8BFE06CC,83E6BA259F6AED4D,884743CD4D352CB6,4A5E018E0B2D019E,484D96E78DED2F14,001F2B081C2A7C13,6B39610A928AB021,0A8658050DB7C6F2,7D22EF1324066FC8,95B544E514347FF7,369C03460177DA78,E99A3ADAC75F9BEE,C7E3CFC4AF2EABCC,003BF6B63B21F488,035AB50967625BF6,99CCCADB011C0955,69FD1860363B7DDD,79E4B85370AF397A,BD45BCC88D82A7ED,6E8795C217771A31,BC0131A00C66BC54,0030164EF2134F58,3BF8450DA965C01A,03F257C85A324832,21D52D107E25D73E,74F4B7ACE5FD5913,D1252C23822CA51A,B4BA15B687966504,D9D9E7D50AC90791,000AD7CEAA5FD62B,292A9F2C162894C3,EEF317B3D5F55D6F,8255A2AB728E275C,4F0C84E83B450B2E,7849703216EBBA32,838E471DE3641794,80396830DFE1661D,0034677865DACC56,8C769F067D4F6D8B,21232AFC94C96828,FA24DCD7489D1BEC,D08E0FB4E5FB17F2,20B1F24E82F5354B,633A60F5FCC67F7E,2FB9D1D3F876ECAE,002076CCFE9AD0C8,33CFB2F79623F738,DE2E47315BE716CC,80FA38DBBBE99999,387AE36CD770EF7F,0B036EFC30B82F87,BE29068389624D3A,95C14694B5D8335B,0024AE176C90DE6C,CF99A3EEE7FF907D,4ED65BDB99FBB731,2FAE48EDCE1ACCF0,22A101984E010F1D,BB178A10FA25D43F,61F9AD32432092D3,C713D895E2E90895,000FCA82E5315FEE,0EF650A7A980D2DA,7C90B3018525AB7B,1B6D96B664EE3D65,289BA821FFAC0F3E,8D1D0739FBA3317D,7AD0CCE71F289399,C99B8A673A9BB867,001318D302CFAE80,D375167059DDEE3D,C39BB22E8E808E93,A7972A0F5E405668,EC625CFF54CD66F2,36EF66C387EB113A,BD711808C7B98AA8,7FCF5CDE65941527,00297CB63567488A,29499060D3710ABB,ECB56B9C346C5DEC,80AD25DFA42B5DE2,9513E0D29A4C14BD,FC17DCB031B21332,30DA7AEEC4C7BB4F,8E88AC06FE870444,00292CA88A33FD4D,538E4E33AA4C0A0A,5973501ACCAD98D6,DD12682620DC5AB2,A2D6989B40FA11AE,EA1F7DBE43188109,0BC14DA1EBA04FE6,DBFC8FE4EBEB9CDA,0004E323F66F426C,83A310A5A5283B93,78FC14DC96638813,2A3CDA8E77175092,AC0DA5C7964D0614,FC168B726A7B3D65,5D426F7773CE3955,EDBB3AF673FC0263,0018B5FBD685850D,CDE3D7C4F766675B,755D9C5B26B05101,FA9BB3B4834ECE24,7DD402037A9E17FA,45DBEC4B1FEED47D,FF91CF38227B9824,82D3FA5FE1B79D3A,0028163E670FE00C,4F68FCF9B1790BFA,8B0235E8E95FF604,0BE982C99F013B94,D786FA655BE63236,071D4019D047DAC0,DDF4F57F29670455,AB87787ECDA07222,0036B83A069EFB45,F29238E3D5EF59F9,32FE4B327385AD26,61B0769BC73EC11B,CD4E2904E8F0FA6A,1870C6B8A945F327,034CC56AD08F0473,8568B2F81389F6F8,003F2169FFAE5CED,4A6320DE2116F322,86E0CF91E1D38858,38A8AF678CEA782F,0A8FB57BE0CF2909,6B65A96CB3BADF8A,ACAD0F5CC9FF9D1B,A8A4D6F0CA2BDDEC,000433160E148813,DD023FA5D8FE7DA4,9965169539226BCD,8ADF46A2E692A447,C17DAF2DD0B12466,B036D11A9D78D481,E9FD479641E6DFF5,063D13AC1AB21B37,000CFB38559F2DAB,F430E3C5BEA524E5,4E4FB4744DE7DA24,16B7C1AD6DE6A6E6,9F4FDB09A45F1191,5FA1036C824469B2,2F5D5C3DAC360B0C,47C6F5CF15373061,003AD61F93C7EB4B,D13DF6B25B4E32B9,AD03793F51202EDB,EFC862BBA073B0A5,F90ECA4C2E534A08,4495A28164DE36FE,FE013B34EBD2AC98,0F9A321EF1AD9AF2,003401F8229F08BC,72CC4C0F1D9E831E,3BDD6E84FD8F5A78,26D2867DBB4EE2AA,ECF2F7660ED8D197,6A195CDE6967E34F,2FF9F037C4A62123,F1455C7EF03554CC,001B5A8BBCA9C177,5E645D8428A0AA1B,B559E0D1B196E15B,12D1D26ECB361DAA,3B5D9DEE2CE89DB2,FC21E16D7750224C,DC7EE40AAC951999,580912EE29BA0C3B,000D11044B6C2628,93FDAE1EFCEF3438,3DA86F83FBDE694A,1AF2F85ADF9D7519,0FDECD24B82D74C9,A052D036B0DD2B07,13B8EA6B3840EFD1,F1F4E8469CB14031,000F87411C97FF0B,644990AF809A3376,5C566B31D65E2AE9,225AB25900478D84,D67D5E4DF3C480FB,42ADD079EA502AFA,28014156753D450E,ADA69BD9A51C8991,0000DAFC5F45A6B8,12C2A00BBDDC91F3,0F3C02B3F55A4956,1FFB90F42C61EDBD,6B5C411A91A05D72,C79F4159433EC669,4B93637C36167897,5321A2B83C237AF5,0022114CB9C72AC2,AD2B95BD7B542926,A0F615D49A076B57,1ACD5A9BDB672880,ABFB9A877F4E0B08,F6D476C1BB8F5FE1,159173361B188500,2FB273B1493CC544,0016196C4EAE714E,3782788CC9693E3E,3557AC7BE9C41C19,62AFA18F4644D968,69CDB64B11CCDFED,10747F20D59C407B,FF4EE1D277DDD4DC,A434421834A741AA,003DDD4EBC10202A,A4189A2825D159E1,FCB0B7E9D66C21B4,7CF9C7EFB9E5A800,044441A38ED2BE26,A41978EB45928498,8F21ACEF572C1FD6,41218889CB9BEF70,003575CE8F05EF33,415019EDA11EBD2F,BBFCABF3167A7558,2E30BF4941645984,DE8BA0845D40E8E2,ACD515B533F002B2,B5CEB503099DA2EB,7636742C549F0CF4,001A2626E92F675A,7407D2B9758FE5D6,B01F8763E8288467,D947C84098BB96D9,3C53F46FEF98F3E6,00256FFF84693DCC,6A1AA0DD98BE1EFF,9EA3BEA2EA05DA97,003593099ABF1588,62DD2242BED177E8,AF916F080362D8FC,19E280FA75C2B996,9213E4FA437ABA3A,EEABF3D6516AC164,076DC55AA70338B6,32D063512C902DBF,0028EA4E4BD33FF2,DC345C8620E83DC2,D48E115183A9890F,BC458642C3D986DC,3759409874750A51,1A0EC369C0B052CF,12F74DA8E9679A16,12528641D18A7314,002AF97291599780,0D8DCE22BE613C38,3C6543CBF1347619,64C2AB74D4E2A2A4,FF14E27C659747B9,864A18E8486F39AF,28D427286D4FA8EF,F3C32E81A9324DC9,00223E06C1F5E94F,805441FCFEEE9629,3861C24A19418231,343BF8F7600BFA28,8844A75CF6C6CA2F,C976CC7CB0779536,7FBA4F212FE9FE63,EC075EC22E6DAF02,0027B69211C1144B,E4B75677BEA7F2FC,D81C3F65D1217C2D,F98D5E92A56D24D2,F61B2F59F65F061B,E63C2C76D4A352D2,534079ACDEE1887A,724AA3F8C5387679,000DB07857D554BC,9837CA18D0600A2A,A0EFE642D28416B1,83F85EA27141E336,31BE83893A4AD25E,4E1C3E6E5C611C70,E3D9CFE0B9E2A0FE,3D62C3F502B429CB,001C1439DF5A004D,3C7AEA147967DB3E,DD9F3F8F098756C3,6364A017E921FB69,CC78CC3BFDDCFDF0,D4929FD153388737,D7E5E0C89E23DDFF,51E3AF93CE6DCB27,0017934C421B6397,C2F002E2FC0014B5,63B777E1286F1327,1849B0A5D434F026,D770DABA3153F8B0,0EF6922F88B65A9A,62FD24B1FB0FE8E7,EC7B5A48906A42FF,002F9889947C2B71,D94F25F52412D41B,F6B767AD7B51CB2B,5CB5F6A2F853AAAA,453636513BE9E646,A50820D95395663D,C8D439ECF399F323,14E29D440910B3AD,00269F7D20B78EF1,ABE285110104121A,FBFFE565EED1B5F6,2040C8F8C21BF6EF,DE0D3AE77C158C9E,7F39D1AF40917B5C,4F04A7ECF7D3C669,4AAA52E4DD1F1854,002A5C3D7FD4FB39,F3A3ABC8833287CA,9BC04BC0C0046EB4,52C115D42EF71BE5,1F23EFC22EE060E6,2E6BC37F29EE2804,D11E8EDC04E48D91,7623F21B1590FEE8,0023FF6417FAFE42,8211F2193369F1C8,162EC7804B83C200,6B74A73901F8D19B,7178FDAF3C7391FF,C3FCBF7BE0B890B9,AB682E7B07803AB1,DA297829ABBC9178,00025A439F955043,433D3A8A83ACFA28,53DE562D6F4164C1,913BFD2791FA922B,8F2C8DA463B24624,A293E6DFF4E30AFA,20A87A34466F6D66,54B3E78754A48BC5,0009C704EE9C86C6,69F225A507365243,41344701BDA179E9,05F003E3AEFA8AD8,935FF45EB58F53E8,2BCF3CBAAE536074,E3D94BB6D08E5476,3E3B5B2F513970EE,00202BFDCD7FEFD6,F70BEF71B171B8DB,DA76D516BFFA1CB0,978AE0291C16383F,DCEC7843DE620DDA,120F79DF7292C2EF,C45DC3B4CABF5268,92FAABA3AB2474D7,000343F1E38122D4,81C44B1D9FCFD012,0D5F09B4F43549FC,855857BF2656E99F,F72A9A8F52776C24,DC4F759F4E9B36C2,1AC2467971EC84CA,CE732D7F4A06D0FC,0020883031E33DBF,452EFE76ADCC28E7,CAEE897904356ABB,30418B9537E5F601,430DE05F733C2C94,CE17AF3217FF1E54,792C1F68B62DD140,833D5E72EB9EEE1B,0005EC0803A16BEC,ED5B5ED4AAA255FA,7EDDD920D9E4DF8E,DEBD271942E79C43,9BF0CA44BA11F340,515D6E4BD54120A0,A0BE931332014859,67BCC5EAD13812B1,0009135677DABFDA,F2E809E42D0FE7A9,D162113EB08FFAA3,F390E0613D0A3228,EBB3E24BCD2B34A6,FD2E18916F7E4B02,65B2209F3A005CCC,D0D2782DCB008479,0007CB8095D48F46,5892615C5D86CC69,A511B4D16A267350,2E3009C755955D12,1247A237230BC42E,8BAFD761141B501F,7C5C33916F34B31B,0A9D08AC16A95726,00090A13ADAEC445,5AFC70F8C1222E39,462DAFDB5C8EA695,B096835C442AA482,83E4ACE15DB1455D,28B9CB6634AAEC80,64BBD2D447C8A567,2DDECD7A582B840E,00229F21D2AD563D,7DD3D2340F8CF58F,DF4720EE4E13DBBA,A5B41CFD81BB50CC,9E80A97F23A5B7AC,2E060BFB754B4934,87493E366E64B5AB,9498AF41B72B5DCF,003B0FC55EAEF2D3,0F97EB225230FAB5,F4A2A5606779DD3E,49A1F3632DF08F56,500D419ECACB9D7C,4AE446C0DE6FEC98,BBBC6D5F5297C63F,306C0501EF160550,000C9130F006A225,3CC6E6697EA0F827,EECC937FE86CF8E2,89DEFAC738BD25DC,B17E4F9610AB4B52,DD3BCA1042CFEB10,DFE224FF1B516030,3624F1E22F264D02,000B61691B7A7959,DD8DD2C098407BDE,4BFCEA4032B539D4,B2899CEFEC9405E5,A3F452C7C3DCB87E,A8C4313375323A14,AEE59E29AB4F62B0,F380F9A1A6A81EAE,0023133869C6A7E0,0CED885CA6897FEB,459D15104E9BB5A6,A2D2DFCE37F4BE77,0EC553984101EE56,07A73C725C79E0B8,B49AC04EDE7D31C7,6DC03FE5C03E08BB,003F0029C0200A3F,912CB02186640490,B9EFED1B48803C93,8CFCBEBE2F9F555E,E477621ABAFF7B7F,E95A7C0EA2EA6F10,A38753D8807F91C1,FC063DCD93F73DBF,0003AFA464C3AC6F,F37BD638EDCCF3DC,103602E97C7BBCC5,FF8BB7C90CB120D7,3CEEEF8B33F12A13,DEDCBA7A772E8D08,D11F74E469B1301C,EB69A2F093E5FB02,003014911A0DDEA1,B7A65ED834F6F16A,260CA4485C8158A2,8F8802EBBF6F0D01,ECBB4DCB02F3FBCC,68FD6A7B16182915,EB9B623E1BCDA856,5C7D9799213D2DE9,002D424FF3B0C5BA,CBC38759188E4AF3,1D91F254F4B9D0E7,368B6E8660DB8456,E5341DD80F62977B,2F66B28F34767B36,8BDB060C84A86D47,67B4175366017FF7,0010E86F57E33126,27833BA6EE12ECC9,402CC8299C61FE34,894E549F5810A908,F8F41E01D9E15076,8C3F84D91916AA84,0B67314EE8B4A5F1,D25477E80486C660,002A2DE7BCF6E8DE,A9291BC3AD42D82C,2D8631C8A4BA8FCA,252DC532EA4CC24B,7F9EE6CB0916BEA8,E37A20AD0083CADC,2574F446FCEAFB9F,637AACDB6A787ED1,0037621D422B10E3,34565238872DA0DD,34378EDFFCAD5833,2940A927CD3B2B87,4515B4116A6A315E,05C94475F58AE4FF,A0595D8F7B81594B,461247F34B230409,003036B1993523F3,B17BD9D27A0A80DA,8A321D36B7FC463B,797D3A7DF057DB3F,DD1E82FB5FAF4A84,A6154CDFF59B5979,5B030EC7D9EA8118,A14397D7D319240B,001EF4493B3CC722,A738C594CB451397,62DB69DBEF5CA275,F1753B10DF3E9405,05C1157DCA3EE7AD,62DC07E1403EA0E3,4262741C1922D2B5,8DB101876C1BB906,001EC63957DD9DF6,C50E8811ECE805DD,FFE021488E48D838,3BB6A59371B41C5C,E06EC26B2AF77812,5B682336848D495E,8ACAB154E8E5D3B4,9A084D32721D6145,002C0DEB4FFA5F80,4A58D86E159F74D4,A2CCB262F07731D7,044373B3F9E3576A,59CC51A2D0D7B37F,44C94695BCE57B26,578F9AA0379502A5,98826F7757D85C40,001FF23E84BD3F14,4278F7C5C09CEA52,0306D97F7C3D78A6,B3146B547B9C90E1,75D2CA489E42E0CF,7112AB46D544BF97,274F4FBE9C9AFDB7,DB0252649274471D,0011A1E3890B3F4E,EF6A9707B8AB21A8,2C70810C7119DFC9,1966A0C4A6615B1C,55967181D561BCE0,C19F8BF9ABC5489B,6E9C2AEA9C7D51E3,9F2421DB6FBC56BE,001B357737408DF8,64CEFFE2BE2778A7,03787F2191214733,061E5021831255F7,F8872F489E16F926,D156A6BE25E04409,E178C6EDD32BE188,EFFDAF6B8EF30CEE,0008855C9C763C7B,B8A008B48213E5CC,E10C841EB95B7C41,C6366FBF3C62EEDB,5343CB88382FC289,9FA7509F476852A0,D1595BD6CD9613E5,DDC1FFCD104308F9,0004A0D0C5B704A4,3911820509CF039A,DADD7DC578E498C9,51BDE989A1F9C4E1,8A0DE7F741FFB1C2,306B7302C615C8C2,DE1F98FF933CA28B,E7EC08EA34B3C914,001831E1EFD8AC3F,0AE7BD29CE0FC09A,8F3D554C858606F1,D332A0A3A7F175A8,D1D36064C16846E1,320916A3FE0B4B1C,0B109AE65B9E97B4,381DF5A64306C092,00342A6998CEE0F5,2AF5870B418BD69A,040334E903C5B9C0,FB8320B3C2CF6920,0C20251EE1D3F64B,DC22BE400F374D8C,0E34784BFDDB0A55,FE3233C420481C96,000583BA9759CCED,E2EC594DC0302FC5,69E03616347F5D5C,13C8EADDFC347684,50D2D1FCA87A5C59,A2D36571F079A6BE,F696B37E73B5A641,87F2955524CA3B67,0033D986382E288D,E9A9377AE9C29E29,E12EC2DC9C65A999,C347933D6E052F2D,337CE741382F24B7,58D30C9B496AF21D,324A1E33B113AA2D,E47BDF9DC6EE8E47,002B9E0F8AD18012,C09DAFB2B41D6DDB,D72B4BBE1ADF21D1,2A02147C677BCA0E,DEFBE873B4DE214D,F5150E6D6D3C9C27,BE125C5D494ACC97,FC0549C18C86D7F9,001B9E1E03FF02D8,91B17BB6FE6E5436,ACF938302A7CD0AD,9F894E8597975DB1,A952D70E00BAF2BB,63B2C26F0C15B605,E195DF0930F5821B,00C2D756CF7F39B6,0017799FED93F2A8,CE970059361ED16D,30C2E11CC95BA2DB,BF2CB64507605CFA,5823E787AFF23083,8C1FD7DEC5662673,8B18CAC50CE7A772,BF505A0C47A1DD84,0004ADA2F230D7C4,232A18F24E59866D,6C534433EFF79C75,E476C903DB7AA16A,EFAB15766BEB61BF,98E89ECB76EDBFF1,546A5E2360DAFF47,6654BC24890C9544,00121A8CD055C2E8,160E679FF467DB3A,2E3640D7F9D41F81,EF79EC7FE2417219,8EC4966E59C9C842,F39C8667A22CC462,CA35E838820E9006,03B467C8E78EF02A,001FA4AB66709713,D912D47090918039,B10682E3CDD3736D,C9331DA1A32FCD0B,120E829F74AFC1AE,3C7B2370762F02FE,83CF8A89E3B6484F,31390A959C3C864B,001A7FD8AEA7BBE2,DBD43A843471FC2A,48B835D64A7E22BD,2D9E937CFC1F81E3,AA084E33C512FA45,27EC71CD5962D27A,312136DC78F00958,15E797DBE0D2EEDC,00138FD914B1CC3E,1EB35152575D15BB,76DDC22027EC230B,6B9B7BAFF393FE54,A53F5CB8FC13A1F4,862BB0FD541B395C,586E63B4C00A56FE,8D4B4604D5C31E85,0008818B7345AB78,1D6B777DA600F5B3,15AAB2660F8077E9,A0F1B8A23428E590,43821B573E1B83A5,5DC6D8079A739E5A,423B4F4F46106BE0,492E02B3FAE0985A,003C320DE43D104A,DEDFA9964F90AB1C,E301D9DD810219E4,ADCE13765EC31220,1A42F507E3ECDC46,9DD415607186D918,1409CAD167901282,423B122E21C36759,001EDC50612D3133,FECEC24BA9DA8C58,AEF80A36454D4A69,A113C434F31B805A,071EC83B82B6F348,05865E36DCD8C435,9EED85177FEC1655,8F5CB681351310FD,003F927FA5EB22AB,C4523E5DE3DCCBEE,99B4AA7C7203CFE8,C042CB0704F850DE,7844EBE4152EA612,E6E055037EF71225,9D37FCEA77267794,31A47839AB99C923,00216597A82D16F7,A510A89A28E80484,7C35801850320E82,9E0201DC8A2598F8,C3AD664AC0D13837,F9F2275A3B8E65F1,FA6F3248AB4064A4,AD2069004C4EB521,000AD59DAF6DE8C3,AAA43C74A21D8344,FCD6C75C40470F6A,8DD13B29D1A257BE,65D8B6004CAFCB71,188EAC9A0405D683,4EF4C54B9D014889,891763AB977F5896,00002274AD3FCFEF,77D2396E78884781,738C1A88EE40D48D,CD07FDBC13F5EFEC,FB48CD790EC20C55,8F3D5DE068F7055B,C74667A8034539FD,5995F205B35292A9,0028EB6192CB23E9,AA9337164D1A9BAC,7A723F772E098059,EF5395C3588A93F3,E8731EDE0A5F323E,5CB03B4C4D5AC193,B4D18C31FFDEE4C9,3BFB81D344B75E81,002A48DBABFB7DF2,A64D5525AE9B547D,9604F80B26FFCF25,8592A7FDC8709918,2B83028004F55393,F94E6A39910FC080,40E29044F882DD00,3C22EFB7C9BCED63,001661252867A8CA,AE110652CF96C0A6,78FA4824B1A9B477,2E53B8B58E5A79E1,5FBE8C066A376964,0DCDF464CA43E464,F1549A4B49F4A22C,BFD99A95BB92DBAF,000FB15E0E9347FC,8988BC18177F0FB0,F9495AC7B61EA073,A6A64E8CB021D0A8,A298C9065F1CB10C,4CD5AA84911725E6,010EA5AB5FC07DF3,1ED7C07EFD3D4427,001E0C262DB5DF05,A7C4E3A3D2C50A76,70F6C744BB3C720B,B99B604D98B4369F,258E6215205EE3DF,7F2B6D2A0F98E014,607637F5298230EC,D4C41B96A06DBF39,00017EA8EA160F1A,86FD3B3F401248F3,4E85E9E43EB341B3,2FDAA5AC372104A6,C230AC6C13B8A083,2BF0242086D7EA64,1325AABF5DE571A1,E9DF21ADF68253B0,00360E744A203906,EEEF1F5A3BC53B04,D208D291B704D596,7A037B52A674DAED,55A229AFE41B76BB,69E759B7A92AD141,CA34ED6C7C862EEE,6160DA46D873D96D,001B95612659B032,FFFFFFFFFFFFFE03,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,FBFFFFFFFFFFFFFF,D79EA0B5BD998A75,E519AC9D8A7FE518,6ABC277B5FE2B1C6,000CB5A33DB8E265,08B314DA448916AA,EDFBF2D66CA2F803,6A1816BCF0E14E02,27B4D9C85940A5B6,23B534D9BB88546A,7966455F91BC3C8D,DF14B2D53614CCEF,00144BE19EC808C1,9D2E8A3C8B7BBAE1,68C1E04576CE9B8E,A286C6D6CCBF7976,EBC7056027346537,D23421C663E91261,F2F10BF520278064,C0C4D3F1DD9A0713,00372F9D243036F7,D03BCE07E4682549,5B2B10718F18B28B,0E67FFA2B2E0DC99,B062CCF6E807D4C7,E3BBA8BA550F97E4,71C689B7BC7BD7EF,D415944202B0BAE8,001313D5B31404B9,590BCC6A427FFA9B,F10BF2D23A60E7A3,B867F8D11BB549C6,71E51BA262C7CB4D,7B74352818990B00,F3EDF896512C118A,5885CA48BCD16D1E,00268FB6710F4CED,C8E53A0D83345F59,8DF4ED673A3A5826,0BCD4CD739F1247E,B74B6D0D3C720799,F45FB3A3C023EE9C,680863EC3D709C18,F2CED0265921FCB0,0023094DCA69FC05,5AE3E88EA78A1F29,BB02FDBE93B2E670,D95993CD4473E68C,255E35447853B923,273BEF43D63B4A8C,5767D8347E8E0808,F50BE742B61F4B3F,002ADA45B4AF70C6,E9BEC7F4EBB9F4B7,DF459DA83FA5E48E,6E10EDAE89622902,9379A0225508C351,39F5FB3B6D5EB9DF,6FB894294E4CA846,EE7AE919EA70B75C,002EB2BBA7E74F23,E31D1DF75E8FB3FA,103E655EC18D1CEF,94F6006761E4771B,ED09CC3C306CBB72,89D8D69F7D8C7C52,59E65CD7CCF8DF0C,598F6BB7DAD65D04,000CA5F5FF481171,FFEEFAA1AAFD1868,7D9B781AEDC270EE,61825A9986E83C34,829A68DDBDAF66CD,44218EB24954EB10,65DCC6E662DD9C40,B2E41E27AD3805EB,002A2666FEBBAE02 - -ph2_T = 85B6F6614C5479F1,125041AA45F3D3F8,71E9FEFE8A5D5695,B34124002BB38B60,83397A0DD88EFBAC,BA9505B09077EAC4,F66DA4912B0DF68F,002C381431E2BA3A,158909E5A709CAB7,C09C8CA347A3C9B8,A0C810DCFF2D5911,1B0A95E9F8509F6A,B8A66A551E5A9B51,1166B29974B94A77,1EF593D66AECBE11,0001CDFDAFDE77F3,013829AA37B1FB89,7D83D5D3563F56BD,317469ADAF16D544,AC46921AC5D39F58,201A85250A6ABF71,1ED3987B8C2AAE39,65B23F7D101FC139,0008879E27D06907,FBC04DADF9F41FC3,4BAA53B3F706A155,FB02C45996B09A46,D2ED3B0719782FD9,EFE240582739A43D,CE9DC4650E291C13,A4874171E2F00F7F,0012FA7DEBB0D4FC,8A61451C27C53A8B,7DB0D97B3FCE152B,CBD63BCAC4ECE402,45DF16FA273D1D3C,89840A33B35D50B6,DCA1F767C3A36E27,9517CCEC1FEF4309,003318B8864CCBF4,0557B64E24D3E6CB,F8FB1956DF3516BA,08A893E12E1B3E95,CB787589FF7680D1,661204F65D8BFB60,70868F274B502E2D,FC7651E28E53A511,002B70BF8328C1CC,9923331D1FC571F8,73BB250AC4A2E451,030E5A2F5A077828,5D6D0CBE318C100F,F21B9EA467275D55,B014C43A0F0A77B3,09F35497252F2F9C,001A33ABFE7A7CEE,1260B47B3D34B287,423FAC2F8FB5484F,78FD8162DAE0E690,FB1FB282602AFC06,DECC91EC3E40D055,2340703C0923E821,24F7ACD9E193E35C,0024257D74434802,0978AA1E0805D708,E5BBFAAF3E0F6BBD,7892B5241C59894E,63766149326A16AD,64C0071D6A2886DD,27E99DCCD647AEF4,B5829B6B04C18E1E,0011BFADDC073D05,9733363C8E17609F,48EF4236A1A76646,4FCDE1AA28859157,4E466935C76D8EC4,5AE68FC1A0824072,D80B5C55E719A139,560F4067653F7D07,0031D21FE9B46D2E,526C35420C3EFF7D,F7C15A57710DDAC6,1A2D7AA99AD484D1,5E1D9D3B52652352,E7C9C3CC36E7ABAE,D53795688E95F83E,8B14D0A7C70DDBE9,000B3FB90307BFBA,996DB5FBFA522858,E3EC505066C24E37,A5FEA806F9E329CE,6D83376D788D07E3,CDEBFB57BFA5DD11,C50AF07967CD98BB,D8595FCF6AE38076,0009FE43B69BDAD8,A03551C556F3624D,53525ED8ABE60D96,2BFAC4B10F93ACF8,A1ED44028C04DFF7,0520AB9A424541F6,4480E3B49361F797,ADB620056219D6C5,00343B7DEA0D2E29,B9F32CD2F1484517,476221E1DF79E8AA,0E893F5FADDFED6A,0C3DA098D4C16EBE,1D423661073DE822,1D01E373C781D6CF,9DF5C82E8762E150,00048A34B9555F45,4B68BB9AB1255390,DF7FFAF0EA80ACD7,67ABFBD7826AC6E9,16C7E61801107BDE,05ED98A76F18C908,1335F3C098C66C89,9FE7EEBF7379BE27,000BB4A5754FEDCE,4D1A7D773BEBFC22,62BEF8125B3103D1,2022CB2694B93F25,CE5A511291793EE0,4E8BBAFB1032BDB1,3A5CE8B9FB806B1A,8B50A743FE4F5880,0040462742211B2C,377727397E8CF161,E006DCB0C3AF9FD6,67809A6C4CEE0149,91801FDC88E0CA9C,62981C702E031E65,78C5F0F2EF487C37,249FF4B9015EEA3B,0000AE744EAE33DB,B7241F648F7E2DC6,A6DFEF28C31CCC0B,EE38A726E7BC8F6C,F46D6E07C79CCF83,F220375BDF985230,3AE9BCA20A00A3FA,1AC9CAEBC49C8379,0013995E9964B5EA,8BB247DC29139856,44923483ACEA56D5,24CC73512ED88A07,90E4BAB76456B179,475FB440110A6330,D159575AE7C9EBDD,DB0F839149FC79C2,00178DC20AF46399,4D0D2CC7AFB81FF7,4E9513D6D17D6A82,F47786B9CC04A03B,B185C6FB0AE41CAE,E816E81D23BD8D7B,13EF696D1DC52B5E,721B88179F35CC0F,003228E1DFFA4C67,5F76BF46724DF90F,C3420E1C1FE46D6B,FF2CA97582B60840,EFB6BD60B4EC79EF,C1EB1458A8FC1AC3,2F096FCF252F95B7,CA4B3D8866899BE1,00007C6578C7E086,62128A964A611C19,15D77C5C3D5E7686,281E0E768E11C62B,623B46D6484A20DE,155D5B6A0C5CE465,0171DD4FFC04F29A,F87C259C088F8B1C,000CE7BDB04A6519,51115E84F6F1F53B,E4FD0D7C1501C5E0,D6EF59877E88A3EF,21EC3C6DE3474CE4,A52F0BFD18E9E8FB,7B90C2612497C204,DCAB9548884E1690,0013B7FE3D2FBD47,9375BC8EB84A75B8,0AF19D6A24B9346B,76DA485C741152ED,0EB7A4A70E60E5E6,071C1D3FBD365C20,039773C39EC1AE27,39E8FB027853E039,00056FED2D8C7DEB,C610AF1076F3EDD5,6F0B7AE2786050B6,E454D89610E3FDAC,8826773F0EF2BFDF,BBFA924F560B676B,5F8CFAA772A9F153,A6E48948E4DA2515,0002039737786C96,AD32928632EFC3DF,712823587035E294,4EA6DCBBE94997AA,DF0F75F4E6071E67,AC37B0C837A29A09,D8221810608D2E69,A11720BAC8053884,003FACF10D3E398D,9AA66E64500A94BF,93F4B30BCD2828E5,E224E818BBD76542,587C63C421C32E75,44AD95508584DBF5,6659DEE2A3A26B01,84738BF6CB1715E2,0012C9AAC3307319,CED32B812AD5A668,2242A62ED88F91F7,E140E6B48B7AA067,B1A87A21E2D84C76,BC688A7CF8A8D40D,DA2EF49890E8810D,BAE2684BF60E83D1,0022668616B64D9E,C8F3900A44B1B971,913140CBB0C6CF4F,CD1B8381ED3360A1,A174EA4BAA21E4AB,0ABED8A3306C1870,7B03ED05C67123EC,E4BD2759683D167D,000DD810AFFF31D1,1A347FC4999E6DBA,861ABD8DAC122B7B,D11E182E7B0BD3E0,C52805D80105F0A6,A262D93B0256FCA2,D053DF5B3361CFEB,C94D3A56C485BD1C,003373952B9EE4FB,80860CFB6163BB6C,17660B20BA075687,3202C812317F60E7,2236B0176748F653,D4168FC1B6EA158D,B942476C0DB30835,D180742AD4E7FE5C,00054640A411CB63,A4926142362FCF6D,6D41F5F898C27CB8,2E3D2C56D9DB21A2,AA7612D96EAC6E73,786E0B1A92781A46,657C129D5F29E2EA,F43B965EBF7C758C,001BA54D9EE065DD,D5AFAD00BED79CC2,8235BD4939352AB7,BA934F2422E4B5BD,FCD7FEF49625A4E9,D087F9278068545E,3FDCDFABAFEB1736,1DEFBD2587FB8D5E,002EFE28323300EF,12503BE45B2821B7,3574E8A3FA068E91,DC691FC782DF8647,3F008BFE3630A856,A761089B9B20C43D,53611B08AC2FAF9A,D7E3D0AB29C2A38E,003ADDC823981AFF,B656828CF55156D6,EF70DDF9CDC33A19,E1B90FBA0298E780,611A535860E90CAF,D8EFBFF9458687E8,6AA22F101280C66A,0AD20368F497B2EA,0013C0B5EFEAAAD4,0CBCE84ED0F82424,227904D6F3E2C526,DAC291251949104F,7FA9097561ACAE7B,3F034AA692F35E3C,64E89081E3565557,6A2E0BE03C479E95,0000A3CAC78D8644,38F915D92C214377,83FAFA62B28249DA,5D44F5038D7B207F,F2F0909755F66ABD,7DC7025B0883834A,646C11980F586E0B,8159947000BED5EA,002A7FF9277CA7BD,D701AED2CF87B1F6,956B6850FD9D608B,85335A1228695F5E,1F6657DB5CEA565A,E62E81CD0D60FE74,C23021EE5DC06A60,5AC71F93807661AF,00101062C24A9F07,61CAF9068EA2B220,AEA91C74B3BFF9E3,68248730567DD546,893AB94720AD3BB5,BED894C308A0EA23,769D3A94180C1D08,9D2B120886BA1122,00335E304C8456AB,FF58C0DEC50075D0,0874D035F610777A,47081AFE0C3CC214,19177EB8DAC9A2DB,55FC35EF37579DB1,5EEECB50C0527970,28B34AA1E413BE70,00080F0FA4679A47,EBBE96C6CC075322,763EA127E998BE00,E708561062EBE258,D4E33FF4A3B52780,135DE95B7D927459,BEF24F34F177B895,3CE02E3C32838875,000BA663FC211DBC,A2622F962F718ED3,7D18A50B330FF519,29FF51FE3863CA7D,E73B6A1A7EB64553,E3A12B086DCC4970,210005EEF1E75B13,C94781EB0E2185B3,0003BBD29B5C68A3,514EFB1C96D1D33E,649634B06B1F9C46,143436A364AE4D43,96B02192F1E0664F,442103F8E74F5073,5D6318FE56E57D6E,58E40194A9369AED,000B1A649FC62D61,3EDA72C18CB8491B,12C587E684E04FDC,AADB95EBF7870579,CFE0CFF7D8381E16,AB032453E3E6589B,E50025AB26CB50FB,97B95355FF96AAD4,00243A7BDE4B3A20,63F736FB162EFE8F,362DB94BC71A22B0,31B4FD59E9C3FC67,65C93885205B7F65,35DB5E481A8ECD8A,3FD94D5F36EDF56D,BB48D01F36D350D7,004001C238CCE816,530417DFC5A0B7D5,DFFC1295C1667E0A,456DB89A189DBD53,9B2FDE0B786A933F,6BDE28CB3E741CDB,A3F51ADE9EDB28FC,83CCDA1D0B8F54AC,000A3CB3A0D4D27A,CE2DC4F7F90DEAB7,388CDF103D7E7057,6BE6A75998631CF9,523861FC28E182AF,363CAFB33326713C,9DFF68776515B7F2,7BB1FE18B2E09E85,0016A75AF9538BE6,19DD59C064042E69,F2A39A15C79AF423,0A9C4D59008B4D8B,53243D63DEB25AE4,A5655D589D6D42F9,B091FAF594132C28,8E346447DF4E7B78,0032A7530CA5B350,27136F59140597B6,0BF67EE2BD73D129,F0E58FDC7F0635BA,36262EEC34F19BDE,218599A0DA950845,8906A085F29D484F,62DCFAE7E4600D0A,0034018D4D55ACB1,6E809F8ACF2353F7,C5A146BB6FFEDB39,F5FDBD151C393D79,00259F95716BC0C9,F00B268CAB278B42,0E4E9E650925387F,E737B48C1A1A7E33,00016C2ABAA90A14,402A0F2DC5AD2687,E91D33A5C691B1FC,F3A1343FF30159B1,EE0E021FA515C238,78FEF1484BAAFD0E,899C90586EF07052,F08D05563D24163E,003183ABA0E53650,B482B1C6D7DEDF9E,9501BDEE4B05F562,906AC8E4CB38BC46,BB6CFE1DD69E3FB4,CF356A301CC497F2,DDFCEB485FBFFBC3,1E0D08B61ADC21BF,002AFA6A0970BC17,55C364F380F8DC83,C5E994478C82AC2D,ABB3281C3813F140,6CAA6508C08D7546,EE0047A507DE7D64,1BEF9F5417F634B5,B78DF41EFFA760B9,002D68140D10376D,041D116E92C119C3,150832A24775A8FB,8CD8734397934381,ECE71F9C81020884,87D231B24157A8E6,CC078F5360524222,428C512C55F38E74,0019179B021B3CF5,A61DD33ADF7B65DB,572B893B992B955D,D0B8D1ACFB9183E2,ED200806DFC22F65,726BB1F7EB04FCA0,ED7F050166F098B6,6C5BD697D6B00BF0,000C9C2C892DAB55,8A7CEF7A9C7E2863,7D6DE020C9EADC9D,D07016936D6A73E9,0BFA8ECF92E2E57E,EB5FEF5C18B515D9,73C60210AE44A0B8,ECECBB4A57CF31B6,001459246448B9BB,68569C84874B1996,3BC294899ED1F575,4FFFBBA67C79E192,2A66D98F9C9D990E,49F261650048B78F,5ECBAD1D09934BAA,332666B4C19DB7D5,0032EE90774BD5D3,4FE38984453D767B,3C1407C2F4612E91,139EA0B95E70825E,5F37E2794A1C7605,92CFE26C4BA37707,A7C69396F502C80C,56B71210F436A8E4,003C471BE94F854B,D06CF46A1084C636,FBD9E2FECBDBD805,6058E34828A98A39,ECFE0136AE338724,173DE70B1F69A2CC,28ADD9B15D2B0429,C2BE72A5D38A8707,003A1DF7153184D7,5F6074F3055E0DBC,C2371CE0DB8AD083,5E8EA802153C2E1E,00061390C99C75CE,2BE12CC8194EA521,5BF2E7408676F4CF,7FD5AE61B5F216FB,0017017629500EAD,991671ABEBDC77A2,8B8630E0CC744CE9,EB6A2FDB101AE482,98D07623C49C5E29,E93F9A51C11D6F76,4512CEFBBF202D58,94FA9568E4A56C92,002AB087FCD7D477,721AC1D06D08E32D,9AA94D434FCD1877,83564A3F71405FA0,EC051A2E76A9BDBC,EA31C0717F7B56D6,3FAE015B83F5A1FE,CB85D1E6D72971C7,002ECE4476F7EAAA,30934CE572329A6C,0822FC44CF65619D,D4030C150F7F0D3A,6DC5F97EE39D59AD,A2EE70DE9DFDA01F,6D9D219162EDAFCF,DB937770F65BA7E1,0017AE9C18AE89A2,6EAF73D2D770A6FE,3AF1AD81B02369C5,A235D84417D92959,F76D12431E150D8A,B3C6376818B5B20B,1BEC21D660263974,71F1A3D2EFFF548A,001DBFF4FBD2D4F6,CFC561EE604066A1,4F91EFDE4096FBF3,01302C8916FCDA1C,7E5DEE536788CF7C,222BA7221BB5DC0D,480943B466E3B242,BC1A6D261A2F2E6B,00376EBC86450AB4,0A1E3471FE45B447,396D6ED69B2AE77F,08D4E51D0509E133,88A466E525580BAD,2640A090FB0450FE,426B7A505E6FFB17,602810F02C39485D,002C9FC872BE7D43,8034B5AC591CDAE1,2D6D72E37E5F5FBC,46977CBC1ED60851,8D05D3AEC4D64C07,88D54F0E3BC74AEC,9C9736DDD5FD4B20,6AA383211EB21356,001F21EAAD45C34D,5B1C96C1ABC337AE,A2F501B5C06E8FBA,A99FBCA49F8CC4CE,3191943F2936461E,3FA957A18324E51B,EB2F6C1DF5B6C85F,80C77DAB9FC87F99,0011D91ACE07DCB5,D11B78E076819D5A,D7209CC0D9EBCE9B,4CDD49A57B221B5B,266C6204157D631B,1CF2708E38FD0B8D,58B05CF3D790B3C6,832B3DF72061AC34,001065E2FF954080,C1EE22E80DACE3E3,05F9BED4CFDB670A,DFA227B4C44520EB,7554457AA0EFB1F9,010E3E252FEC285F,866AD00685CA2630,B11843A329E32DCA,002002D380E98FF7,7E590ACB2310BE76,4DB1E4147ACD5893,3E144471891B17E1,754D2E49B86F447D,187AC869C6F00029,07FB2C0305E154C6,3CF90BEBB9D82817,00305341316F457E,66793A07F6B92A94,4CBEBABEE27C4B15,CA9EB2A31074B3EF,5739661EDEFEACEA,C8A421FE457B1F9B,C7D58272D6F2DC86,21AD37D4FFEC5E55,000ACA0839D02422,FA84ACD0F35862CA,D0140D64B9D99C5D,D28A8C475588E79B,0ECA6A9C9A312617,433131DC99D36497,826DF541A20AE21D,141F68D116E1013B,0002982F4CB745F9,C1D2935DA3C02E2E,58E8D6CAC61C9B71,9EAC33516B5B9FED,E7D6E330FD1CD768,20F54A360B14C4D9,5A4D131F3B87CB75,5FA399EC37DA022B,000CBFB0E09314B4,2EFE43573EDB85FD,08E19E22CB7C1EA1,59D9D8EAFCDC8FDC,0473FDE73403D9B9,8DBE6DAC5D7E6157,7A61D06C553985EC,76AB36AE2F083D1A,003623862A66F762,9189D83864249145,8A620EB44DCC869A,351781FEE454B81D,E5B9750092306C08,74DDEC0436873F34,FD262BF6BBD7A0AA,0CE3DCAD2C49618D,003513DACAE43EC9,808F9927F1E45E46,FA9427FCB826FCEC,FD06E4540CD5C598,05AC8B1DD922E42A,9C8D6ED9C680B9E3,CF3C21E606DDD447,26EE3B45D62A3C24,0010164AAC187B6B,1D2E8E719E634D2E,7F260332DD87B32F,11DC4209976CB17B,783E0BD0E49CB83F,08D79736112D045B,B4DE0941F63C8BED,CBA2007033E5EA8B,002532CEAD80E486,DAD97059153D513F,1C853C82D190566B,E1664D3A5ACBC79F,6A2D0F1B6B9511BB,0F3B42744A947A65,177B5A5F0E624F1F,42D7AAC809FA2553,001D05C22CE26A60,C12CA87C8FA86405,0C39C9E75E4870DA,C6542208433CF420,B03688A76AF8ECBF,216181A8AECA9311,65FD1D9F4D29635F,78CFAC8FC72F8E18,0024FDEAF1B4888B,AF6CCE605B6E3D1C,C4BDD0F2011434A5,BB113B705389FA93,C66C6DA22C6DD9BD,52D353E6FAA34B3B,2F411DA50A9C7AF3,41ADD794DA0FB28C,000646F6E29E2CC6,6688DCC50DF1FF29,45942204A3DB2C4D,0441AC16A16267C1,49223A621B73F2E7,474406D48D4DE837,66177D971DB0AC67,71C2F808E30A5049,000AA4C2D266D492,4FF80F89DE2FCB91,06260AD69AAAEB37,E4C5D21ED9674618,0D5F6971B1738157,558B451DE1263E67,E24F4A1FFA6BA214,25C1092EB3DDD288,00203B73F9FB04FA,CA7B9CAFC8E724FC,1E3294C49AAC710C,71E4EFE4C8CB1640,8E3CE2D510426858,27848BBA759FA2B0,861F69B3A5A16997,FA99FBAACB1A881B,0023098E7B5556A0,CF9CA9EF35A51BA7,728929CB1FC81ACF,1603F589F3989ED3,6F62B8254272C1BC,6FC9272EB27C4535,892EF4C7E1FF7BFE,7389378312ED2DB3,00160D27AE64240E,FB03F115613154AC,5C8FD80A31E226E8,2D9640416965FBEC,AEEEB9B2F4F153C8,76925E65B1E7D547,15E91BB31BF0CB4D,3DBBED6A70AE1AC4,0011EC79BACE0D1A,AF0DFC6A226F6CE4,89CC7860D7226E0F,1B5CCF6DE81DD232,1040305D1BEFECC4,75402BFF99F820BB,345671C98500F390,BB4C9E7D9699EE17,003C66990594A315,45487E7089348253,C4BE9FDE818F192D,F8BE19D6FA0261FF,016C4595A6D07409,51EBCA282EED8197,661630BBDA22E3A5,9D92640687076246,00244580A0D1D292,3542068147610301,8AA0519271502026,38BBF631A421A1E1,086103F2156C6D68,7482EB20E1E589BB,627E065C8D19CD23,9565658F80DC333A,00070E78542976AF,F4419F3151E8C36C,CB72C9C14F90AA53,130AA5DC1157D5D1,DDB3FABDB1C3E356,A0EEF386DA35BA64,EEC4CD0D1C4396AA,7F869B3FB09B8451,00151E1353BEF2E0,854F9958FB93D924,70F73FA2452BAEDC,A91FD52FC86D9C90,C31B292F116F2280,252C098E78247201,596CF8A7F46A96A2,EA0802BF2DE5A4DB,0003FDB7A36E9621,6B60E62D9165142B,4A397F2CB90C99AD,2645806302C0E139,733338059920E43D,10DC99342EC48578,5C6A30462C6439A7,5FFC197C267299FD,000BB994E5C661DC,4BD0B3BA57FD98CF,CDD11BEC016A1D18,56517BC8A49D43D8,54821264B489A7BB,811EA3182125382D,02FFD10D5DF3DABF,3ECDD0CCA7E6892A,001A4680C48ACD70,202A791C2FE16886,4A973898C6922C9A,98F0099C2442438A,57B798153DD59CF1,8484C9B7E0F9D42B,26F9E390727B9519,8F17A179838A836E,00224954A1565BC3,30864562E90A59C4,881C31C339B9E653,7F78E57F9A63ABB9,B4173DD8A4460AA8,E34D708E641B15E2,CE61978A118A5E13,F985B7F029CC9E6A,0023E31CA1FC6848,659853ED1470B3CE,9CA4F816C16995CC,49179792F45889E4,D2DC578B343C7F02,7B10D36DF9783ED5,1650A7BE92F9CAC9,F5573D05C9BC2410,003AEA406675BD35,16F81B5BE3AC12B1,4125D6442D0B3454,F890C606A43801DB,177F876071A62AA9,2F6AB2E84123B4B2,83FD910672C6BFC6,79BF9764AFC5A04D,000BAD792C5D6B6A,620AE4F4481B497F,0E39EFDC23DB66EA,1BA140901D2BC882,4A6CEE489073ED4B,262756FC0157AD3C,FA70A49EB1763736,30D4018CB8CB5C3E,00011C40B4B18F68,DC4AD268CFE2BF44,1CD12ADAA3484892,224A2E4B192904BE,FD3EA18E8F9C107A,F8C3BFC276FFADAA,1776D3BBA60221DD,9AE7AF9738147DA3,002BF8EC0E0552CF,3F5C9E468FEE7986,7B65D735C29A1385,AEE87A405D5D04E2,0F3278942CD026A3,622FEE922D693D02,F0C4E3C01AD7F0CB,D1E27DEADE00F81E,003BD5D5750090D2,168C4D0C0F91639A,C686D509515F37D2,25DD09CAC3B2B536,9A32789EC15A2A43,31E8C490D1B4A873,AFEA4171DF4EF477,2F2CD0FE557DAA49,00173D9022BD719D,6E0C46F5EFA62B54,5C52FB8CF693FF9A,1E8F8DBBC92C09AE,99A2AFC152A07F67,28259123B1A4D8BA,606632652070126C,AD5DA10A46C8D909,000FF83DE84C8211,C6FBE41300064387,A25FD1C7B6E7B47A,BA1296784A702DB8,2EB89FA3791A9295,95AAC388B52FDC90,1D4C0B1A467FE360,D40587F7DCAADA50,00220944611D7280,09ADF5420C87EDBF,BA8B1DE5FFF44179,966B208C5F8DAAF7,C0B3BD295D6DC95D,70F78138A8485604,6D133605841CC6CC,B28D85A41ABDA7DD,000BCF19AA665DDC,F0CEAE0965475BB0,F8112E4808D1D4F6,9EC99C5228239894,02B2BECD7B92BFC3,114D990D6BB278AA,61E719DF800B736D,2179A28F978D8E8A,0010F6EE882B39DE,A6F3747459DBF6DE,2C6A2F588B194E2C,1C2FE2790EB6465C,F1D83FAA7AA7561F,15381A787AB1E970,68E1FC431C4D2558,A5C5E766501F9D51,001F74ADB8F68686,C7E39C90BC0394A5,9D3CE2ED2BD3ED63,DAE07EF151709BC1,B781C9CA4BF682E2,68B1A9349EE70FD8,35878140ED96581A,839A7ED625B67803,0021F135B599F277,58943D218DD6EF11,F299F8403B597F65,2D4EB1C31039137E,EE9A4FBC55574DDB,4FFA7D2A2A2D7020,855B87821B970C2E,5129EC631EAACBA3,00304C28D463589F,5EC92A714137C095,F8F8C2B6DFF61CA4,67639841F5C705DE,38DDD9D5BDA8E4A7,F10A8E0C34241CDA,151EDA5F2DE0B5F3,993EA899D84B9D80,00058A3127220466,9114AC5B6BAAAFC2,13628BCD79D7A4E8,C27CD27B7B0E2276,A048D7E92A35AF92,A65B15B1D038C9E7,673B2FE029924499,6C484CFCAE3C9315,003286F6946ABC70,824F73EFB2F29760,66075CC2CBEAF056,2733610F474EDC4A,9012065F5451CA2F,39292CAA13EF47F0,37936A4C9343D49E,C8F06A4D24C2D2E1,0036D91C5675B9C5,ED52FC85CE900579,ED07B13A9EC07B24,1C58FF51F0A7AD35,40CC184716EB7E1D,A49DC7CAE8E050BB,55EDB3FFB3794953,F9A024BF6FCA072A,000F6EF900E7C256,5722FADE43DC83EE,A1707A279986152A,314EEFC73F7B6E99,5E6882F8BE436063,81D0D88C4C6D5001,46EA41BB25EE5B66,C03ECA9B6C998FCA,0029DCA4BA0D7ADD,99725C90FC386993,46EE280FED60C687,263E43707E329CDE,84C888A917C244E9,6EACACB001D8C930,5839E2047BADDA71,5F444787C58A3852,002145B568E23F39,EAF6585EFA19BBC0,B1286520A5EDA260,BBD61C161D3FFA0B,A018AFDA34CFEBF8,B49994DABD877110,3C0A6B77636BF46E,48C6E85F8D3C2578,0025082CF2FE9065,B8AD4F3A69FD9661,183FA0BDCF4EB044,1EC86F9F7EF52BCA,B2B7ADB7107D1F1D,365DE69A7E6391BB,0B2597015880E490,FCFB6BA8587103BD,0016219215EF2190,2ED68106E542970D,306144038F646520,064BC5DC4B0757F7,C1001FBAB44256C3,2A575B878B43F46F,138FECAE5E7DCA94,55ECE71E7CC03A55,002B7A3889715E76,DF5F459C8E8CCB80,525D8A4AF65ECF3C,54C18B025FFF111B,121727C073C36FB0,931D8DA49FEE93A6,BFC485BD5C4C6E87,7F301CFE4E44953D,002A8744CF6840AB,253BAC14DF16ACB0,A2D75D99D350F810,7F42D3F746FC48BB,9A4F79AAD9BFFF37,D0E2E546EBFFD671,CCDE9060C1C7641D,596121AAED28903D,0006FBB14BAE7A4C,38F6A848E1DA3B30,2E9AEDF602978952,9ACC28313C0B77E8,B32E5573463D3FBF,71C2A6C676ADA5A3,1DAD1EA0E6C7A183,22CCDD0FA2750AD3,003F9550FFEBA5EA,31680C1835F1F4CF,004E7C98508480E3,C457EC28C4B5C979,06956C4A517558F4,6F4C93472CC7079B,BF01A33BE6C16286,1872552860147B64,0015F52E56370023,BF9DD66B4D0459BD,22888E7605627ED4,1C4AC98CA33470F5,AB307DEC21FC643B,94924685DC7330FE,C91854B5C9BB74B7,3DAD7EE50370CCDD,0037C74C99ABF006,79C264BEBB2E782A,669424E3F23916B0,825EE98EAF795E10,4AA1D294A19A08A7,CADCB7CFCBAEA449,A275634C680A6E7A,1DCE6480AE965859,003A60524E3E6C88,EE7E99FFB44B8026,0A7417F23DDA8AB1,069177ACC214F1BC,C94B2496E77DD209,A007EFA2FE3C78BF,476EDA052CD70173,6E3C20FA4BE6A955,0036318649BFC8F8,96774AB37D78AE2F,CBA078D3F88728A4,AB5AFDF81E7B62C1,BDE63ABAB18CEFE1,111B10651820F85E,6F20932DC7912AC4,341C962B72255D62,00229BDA885F4E50,00EEFD163354510E,38DE6EDB986EFD47,21789640E07B9FCF,2D1870834E0890A5,88E45136E6CF1687,6F55304FF038B50F,CB08F8203754F71E,000F8EF904038718,D68FD39BDB34E0EF,FA2B039EE07F343D,958ACBBC4A83DB56,B96AA8968151DF37,5B13EDF76A1BB04E,C408E0E635BBF42D,E5B5E8C08FFE3335,0012B0A79FA63C3D,647C200BC4B99607,A9987C920EBD5C0E,CF669B31813E6AD8,BBC173800CD2587F,F4F409EF32DDB97B,5CA235F774A6F900,80E95089CFEEE48F,002ACCD6F2247383,D1D947929869DEC0,69549B83C2DD71E2,7FFF137350E07422,D5B8E86B74404416,218A3F9925EF909F,8170FCAB3AF97204,013F4A70080DC9CB,0008B864D2A0D02D,C2E87FFA01BF50FF,BCD239BC1617EC03,C882363E2DE02F41,1DB2AA98647FDD00,EB8DDA3A87FAE231,D88AD135875D589B,BC444049C1C1C3BD,0031BE764867D558,8FDD48E35B28C5DE,D60E30FCC66F2A9D,67893978CFBD33B8,9F8F3CA7CDCFC5A3,82412D0EFED48E2B,FA319606EF3BB807,D6A8960A06E5B43F,003A07214C1DD3CC,F18C01A69DF1A6B8,F2CDEC14A19C63AE,F3F9E1A6F59E398D,F62657C5588F76B7,6557056CFA3674C4,F2B5A924C3CAA0B3,DE0BC55349898084,00150F3F4A3C5157,28266431B0C1DD4A,A8438ED1FC848E73,28DE12FCF7CAC056,0F797AEB75A29137,A9F2FC8C11CAC4E9,8B35D5DD38D49ABD,14FE2451E18F1C91,001913CC86F1A5F0,0BA057A6D176851C,6DD3A7E31F49E391,F2665BCFE187F6CF,E87D6E740B154C16,A507C5DAFC5C1863,15F08567BFB64B85,1BEE8EB09384C01B,0001E59959887B0B,BCEFE24FB90DD207,9A7F23DD52529A50,357D42FDEBBAD83A,E580751B440F46D8,D15637B07FD86E72,7ED1FC9E946F7997,9839C29F75D74791,002B7DF335C98408,2207F1EA0A130C5D,60EBCA4B3D3FF1AC,135A6A4F35A4126C,D30EFD80994D0A0E,6B00927372CB3ED6,EA272196ABF8C876,39BD824FCA35F71B,0028A1E55E6EAE9B,62C27171DF6942E0,A72D87D4AD6A6866,5367E877595CA1D0,2E90E084B6F16F90,731507064618DDD8,859B76433DC6BBD7,2DC51E6B507B3069,0024CBBCAB04F1EC,0998D04F10E7007D,8B5B313C4C0DC284,03ACB1DC316BED3B,F2698CC56100E918,7746AA8703A181B1,4102F8E38811CB0B,99F1B1285831FF3A,0022D631B41FA6C7,9DD9D18A326CEE55,1D2A2801969D51D6,C2F961F4A2811081,D8E22BD8EAEEEDA0,2FF372404A127D6D,24B300EB8D77B65A,EE4FE03E06E98CE3,000F37FC387AA7E5,3D515F60BDA74200,9EC9A676F05D5F0C,1A7659A5DDD34469,699F95D491024C13,3576CC62A7C3B44E,1F111A2D65799356,444E3DB2F28D4960,00327E8BCE82902A,35D94D66A8D29B24,A32FA447BD119E29,E55D4F231482BF32,867A985DC328B115,B567F068A26DC4AD,3CA081FF502529BC,C22A88C32A66E0DA,001E0F2B922CE044,B248E0D7C8FC54B6,A7137A5FF3B1D065,A1072171CC4E8A71,672D46E65E38E934,ED61E4C04041B221,C9658CF391061D69,974B7E5C1B2FB5A7,00219545C4AE29F6,426C31048C0833B7,5582D008E5097B64,75A9812AA4B4C0CA,035CCC42DB940271,5EF50B2D48C5D145,9625A0B989CC9D04,B2CA6652AAEC7F75,0023FB700360A665,49E4D26E67B6218C,8FDEDE92D1899B95,C96520266CC53065,9FABFFC7D9E803A6,915DC2BD871A1878,D3E6D9AFA8DF17B1,12FFBD3371F56155,003EE8C1DBC5F457,48D864431978DF3E,4FDB9E90D6BF0465,C26D14D92B3B9BC6,FC1CBE596B9CE0D4,FC6A97242436093F,489D4A3F7CDD7250,BA9AEA0FD3813330,0023C46470A564FA,D5782D168A333318,C349441537D691F4,1B2303D6966C7B74,B2152D86C393D58D,CBFAEDA044CD8F39,D7E3D7E186EADE6F,A145C3468026305F,002C4F60AF1D4C53,AB29A3D37FC198E4,6B7D831C4D2D287D,28D85AD4437BD13F,6DD9E399B9C4F178,2EF70F670D083EC5,FC30690E9471764D,015EAF7E9E764C97,002EFA682FAB0D1A,FEB2F58DE9F6BB9B,585E2FFBE250CCAB,6BA0E437112F716F,F8AB73B9095DA47B,8B0E9E19F859880C,A449904A896C0EB5,577ADC6D0206F78A,001FB019FE974CC0,BEE69F2FF21EC8A4,4275AAF4ED9C265C,BA1D81EB2DC1DF27,8576E01D300B9B00,7C07687029FD5BDE,3CA2F131CB41567B,AB5B0ADA41DAA360,00214230B9A317E2,5AD4F0CE4150D57A,07B45D2DA59C654D,651DD14303E5C112,7691DFA88BB89776,EA813E2777687CAA,D222728CDCBEFC0C,CE370C548CFB5597,001C21642775DC25,2FDADF23E7FA2C8F,7CE24E720911779E,65C59F7A74B8C35F,63ED6E1B1AA117C5,D95C8A56788318A3,5210FF58A20368D7,78DE154516BB5116,001557E8C15BE91C,666C9F3FD1B8862B,C88613E664FD45DC,4E1232D7B55E1A52,E6851FF3C4436D04,E6D28521C8848AF9,07CFE5B14F179AC6,00255B2A1C449D13,00032B01F83D5D5A,310CB72CC4091D51,BCD0F7944A63E4EC,4DF988371632330B,B9F992D4C470BEAC,6D372BEE2BDC84E4,62B89730A91D3B5E,896CBE91F1237BEC,002323AA8DF853CF,DAE358141AD1A778,B4661F04DFA51B7D,00CE3B0CF80042DC,F338BBA4AE5877B7,F202376A040F8B19,AFDF43889FF1E948,A65B24AB83B32E2F,0014FEBCB4D6A6D4,B8891CB3E80A94F0,68D2907CCD9E6596,081E0B07EE67B121,61627949E462249E,672D2F269CC70F8B,783EA4968D4C8576,33330AA5D3D3A861,001A2E5762B07C5C,BD518FD2A14E142F,945DD2537163ACDF,182541081D6321DC,40884B9B320120C2,0ECE85CBC144D36F,86EAAA7EA997E782,F5A88CEDF112577A,00344E38150D5081,3387F955E276609C,79E4DBC2C5A429A4,9B3CCCF833D20887,EF55E1BE94B5E33C,6E53A12F04AE53A6,8820592BDC51E261,2FF48352FDB501AF,000978D03A89BAAC,FCA12EC0C1C10A75,CD0F2F0C7B001866,5677A5C529D7F8FC,DDC4364C04BF8356,0B02BE690D75B362,BF67AA4D346E04FE,07B70B3E9E770280,0014992A6C69D8EC,997B6FE73EF6B4B8,CDEF2FDD464F66A3,3E1EA9E8350E61C0,C6986E98681D315A,D537D35600A3F839,B3D9B6C8AC34F74F,D062AD90E19E1DE6,0016FC422FA1D2F9,947418AB2A63125D,A98B1680941239C1,1D116751322609C0,DEDBF6055F476B19,2A6A1292ADA5BC5D,1F93F79AAC6D55BA,DA32C276AC4F89A4,0039C458486C4AC1,94B6FA1AEC698C3C,E7F900FEDCFDF19E,BD70EC69F2A13224,16E7F8A0B966210F,520721DB36D5030F,237B6BBC63A80F94,D5942C881CEAFDC1,00032A3DBB51C471,E1F32D0F0A726CDD,BCFB6BFF66C1A2C3,0C90758695A81057,2304512A17489BC5,D0D7C7BCECB8C666,6CEBEC1F616AA0C4,0FE9282891FD3573,0031F0CB398BDAEF,2FCA2FA3943C1D22,87C160DEF8413F68,42BA398096C327D4,4F33FD5EC2DC4F60,4559FE70DF496F17,2C966787AE54848A,F1493FA680CC1F45,002462CB80D4FB28,B3DF1B8400624336,673C4E1EDF640133,67F4200CD8063AD2,8A832E307ACAF315,1B11DC0DD62AFB30,684F3BD40783CE2E,54627161A7ADB05F,0011D3F283AC4344,AD0921532B880B93,A72B7F1A4374C017,14B9C98F7CF161A3,7C53838478796BE4,AB199E61E0ED1D05,4470EB6B82E93553,5512A54CC791010F,0035491E8D94DEF5,CF79F5CEC160DA23,F7A9DE849C671E54,21BE2FC4D57B2764,58B708A51891F16B,76C11094D4E37A50,2F861EEE1B38CDF2,A8F72A80D5BC9912,002076C3CB502264,1CA05DA4969C1825,D8110F018033E0B2,A4127B1EF4334F54,EE5EECC9376E4F97,255E579B32E461BA,0752DA4BF4A7CBCF,7DE16F4C2F4B8577,0023785E06105482,2250270772567941,54F991B2FB0B8EEA,BD2295B0F1D5D414,A242D4B0D834159A,2AED2AF6F9BC3C3B,2DA89C375297D602,96BA822EF65F36A3,00174EC5C269A7AC,93AD2829D29CDECD,D48663EAE3A5B244,FB86D834A6DF4923,501A635EFFCEC47F,03076878C91437B7,F470003A7342C6B3,5F54445BA67FE700,0008AECBA67A1283,DCD7A891D00CF8AB,8DA6D7A0130103D0,BE4978BE04DB9F40,1D2B963CA7EBAACA,3B0AB5FDC84878D3,FE22B9682BA240F4,1DE9B1FA89DB68A2,00018E6747677941,7E0529A68B70DCFF,444A24CD0B355379,BE21A0AC1EF9E20B,FF1B28FC2552C6B9,AD363C26262CE9DA,E7D7BED1367AD0BA,D66F0C531F1DC8D6,00402902FE2514D4,B1D7AF30CAA8043B,09F313FD7611F133,E8E6160F58E3BA8E,C0E9079CCBD459FE,4BD18AA35D07AEF3,0608D7641969C865,946A3491B69F2DD7,002A69D194330F5A,CFB3923813F20F56,7357A2A9FA4358E1,FEDFD358B066D04A,9A2BAAFE613ACE52,BF3EFE91D66A5121,CA776AA14CD6E46A,08C4FC575F250660,0034AB8524A267EA,094E7D94AEB6E820,02C2E9595A44C36C,F10E0F18B8F695F7,1E5A648674E7B9B2,C7191F7F6D7ACF9C,79FA31E67B65A344,02219E66F62A6E05,003E99DBE567AFBD,E538D1B71F8D359B,661903202BBC333E,9D0FE7DB9B91A410,5C5764D844896EC7,883F6F4B969B6F9D,6F521D55EDDF5FAB,CD8E32A4D43F9FE9,00053AA5B38C032C,4294B256633E5F6D,080709845205B86C,750F764B872E59A4,F1CF9C08382CD83E,B95099887E7F8822,E0A12B4AB627399F,49309BAEE91F959D,003B09FDD1D951E4,258523346190C6C8,1E25BC716A14D5FF,7E1BA43BCD05D8F9,CFCA8D28C3912588,2A396253AA8B2C3F,CEB65EC86657699E,F5EF0B5B6233CCF1,0039FCAFFE5F8EF1,A1D00FC14A8907C0,03A37AF0FA00100C,2FB47FFCC61E9084,CF2349122C9ADEE7,D2BBE51453DF62C3,97EFEA5245063866,D6ECB3A9A9D5F8A4,00082FFCF7FB7A10,3618F6007D666BD9,CBE967C4B9BB8214,B1209B4C35B0C32C,EEE544D3ED901763,42CD57D76F0B4BDE,481D10F4EC43A6B4,B5C3668B0810A33D,003A8E2DB2FB4A04,E4DE9C9781D06785,B48C4519E44BDDF3,1FAD289C92A3ED2B,42066D1F140588A5,293EB1206EA6C321,AD789918A6ACD654,788C86EAE41C4841,0040423E4FBF1E1E,A53F21D266256075,680C9DCEBF111171,8F1905276ADEBBF9,0EBFCD5BB332B433,B05663500CBDA39C,AD23D0969A10FFD7,BB1F54A16A11B0A4,002B8F93C9BFF672,95F7E81B95DD755A,F7249BC1E48F08C5,4BC0B3FD32EC5DA4,4650EB0E39CFCACC,6FCEB3ECE81B8A82,7E921C9C8D003AC6,CDDDC469B88077F8,0022A53650919091,D4553609E5C326D8,8138A58E3FD6671A,467789E2892428D3,33CAA04314CB3587,F3817D7560B8F01E,3BBC50F2DD3D998D,D810398102AC7458,00070D04E5FCCAD4,876EAF9D7733D2FD,DC32A88B000B071F,568714AACEFE00BB,913FD9AA354C7C46,CC8C104CD32A692D,A2F21C202A03AA03,D8A3AB0D6E3A0599,00210B5FA840EF71,F804BF57B151AEAE,E5CEB9E78626D2E3,461065EC780546A2,4A0B534460B3DC5F,807B94429C5BDB66,98A9FEB2E65AA47F,2A1A4A8049E04975,0000A5FB4B74D5B2,FC1B42FCBA81B6AB,072338BE9BE79C5F,14A2E4B49195C4C0,D612378BE4EBAE3B,F7868ED82CDC7347,7D1C52D713B2DA29,D8373E60A900BBCF,002CC1447266CC5C,9C7ED3E47B1CACB5,8D796F41CD14B859,A1C2307334538F99,D026312947D63FAB,B7FC6CF1ED8467D5,63DD8AE472635FFC,4ADBEFE01A3A509D,002D600E2CF041FB,1B25CEC14F7CBCA2,75898ED607FFF95C,AC552AD7E6B72B19,0B39B37B7E98C08F,2EF72E612588EC87,8B40A8A5D0248452,A11630067E992F51,002AB26BB46F23F4,55C76EF1ABC4ADA3,8EE2571F08318C0C,4173F8AEAF329624,4ADD37458149281D,4470A9F464568B6C,1E6FE38981425104,26C60571F64CE411,0016D5030B580F9E,7502A680F9CB89C7,D20B79F6F2E0FFFD,BB0BFC7F9E446BB9,C97ECF63B653611F,6C43B32605168806,395CE519085669B8,507CA92703DD40C4,001A556E7FC28AFB,AD8476E4F6AAB08D,B549408793E4EEC6,7B64772E7863BFDE,B33E108DFF442395,44C5E2E67B02EBCE,EE02200A313C68F8,30ECF925378FA6C0,00215B1EC8924720,4F171742C9CB0D5D,45503EF28850224B,E05419583C4347B9,79C92A6B8FB92AC6,21336A5B1A746CAC,1F25134A74DA4D13,161D9B2818D57CA7,003D1E176EF1BC8C,96DDA35FE1F7668E,08FC6B46181F4D56,E73B626598CA93AF,E496333848ED8C9C,15D58C59A0CB7455,451274C51BA4C769,404C603D9CF868BB,0028A3F876413AB9,0047A6DFEAF9A75B,13319F50DEFE842E,160E2073C35EED56,DE78DA0679D18648,0E08EED19222FB0D,55A6A18F6E06406C,C5C3368D17603F62,00292421ED6FF26D,D2C7A5008F52EF6E,8F570F98DB3B7883,7A5EFB2FFBDAB3A6,2D65E98AAFCFCD2E,FD416D88B5FBA464,9F869A2A97FA5C40,803C76AB688142F7,000C9F73386AB768,BEBD4BF3A5A331C0,7C68E4BAB964ADB6,A301EB84672AEE50,839EC8A956BBCFA3,683CC2326CB7E074,5AB554C3CBBD40F7,2EB60FEF53BE4805,00121D7302409D9B,80CAC503C631315B,6CFB231F6F8913D4,DCD13A155E72C35B,C40FCD157F190CF0,7ADC22A4E67EBF7B,E800ABC4B27BEA02,516750A73AFC2D25,0006367D3E91D0B9,CF41883A2CA48F85,2A52CEB62DCF9B4B,22F912A9E4177C3C,3916DEDFA8B1F795,4A48C521A6476D8D,0C43D43B7A1A7C7A,E196AC975777D38C,0004577CE0D0B0DB,25E85AF86FFA019C,4B6356C72269967B,6142267581577533,362AADDE1CF20566,E532C1123627D450,8A788369CD0591B9,24F5804E48B40996,0025AA2763A56C58,52AD61EA24944A4F,B1E7010A12FEAA77,1F2953DC39BFB863,907BA02F795CF4E5,0B18E3F65E6B549C,E0C9F7F8735874C7,5EF6F6BC3AC16BEE,0033E88E4F907DE4,82129FB10D9ED594,9BDF25B82F8A58C8,5549DBBD439F60E2,857BA6406226F8E4,81CBEFF3FA6B4CF2,6F40D46803BDCA6B,41C5EDC9519BFB47,000B031E84F8F0A4,B832FE050E0308EE,879682E68AA3CDCD,45091D70CD48E896,26940E1A9ED714D8,FE57803C4D4B1BCB,BDD46273C5C1DB18,9EF8DB917B0FBCB9,003A375AC59F7B13,8256EF8673892419,24B0A86E26B15882,B8EB3B170886057C,E18D26CB2EB6B171,041930EAD80B127D,B36E08808724C5B9,946501E380856763,0015B15124EF731C,A080372A2BC13236,53C993F6828DA7E3,1E8A6661A7E42EBB,5C68F5140AF19FCA,89000804ECF3ACE6,4216B096B602D5A2,24942F1E24370FE7,000E796AC2C3B94B,785917A9DF85BF2F,1B3E80B32DD4D55C,22E57EA06704394C,F295B35A79893E43,480CA125BB6E8E3A,53BB5A1F187AE726,4024D74DF055A213,000B9767789D33CE,EB6D3DEDCCD4F93A,E4745FEAEE3F6B41,492516DC84B6BE88,312CE8F05BB20AB6,B215F052BBAAB8E4,A631F4DFAFAC837F,D2AFAFA093D2B219,002E2A56ED27DDF0,BF724F67889E6D44,7F850B51CEE1FD85,49A2FC881AF76DB2,0111DFCE4F04BB08,25DDDD7386D9FF81,980573FF314C72FC,0368ED5080D97FDD,000F84632A84BADD,9350C1E344225D37,B4170C010517FAE3,5ED62D51C7A6C9B6,70B2B4AFC410A98B,66260BA8FD431803,47F7A9F7CE8CF6E6,3063FA579ED19546,00132E60FCB559A8,7FF5E801D6110964,B87BB6917DC90CCF,6A06E5A725558C50,4CAD9190EAB06C81,7AE4ED90D5715872,D685A7320B748E40,4BB1D0D72669015B,00128791E7108512,9C9932D0ECD19E7D,60FD078A830D7EFA,4DAA8E87530139F2,7372CA6F99673E21,4203F16077250B38,C1EC3FE588E04CE3,A624777238C66D7D,0001BC8ED1B21D37,394F52DB8A7CEC4B,FCBB52FF8EED6B15,E43441BB7F98AD19,0D25E4A6B0E8FEE1,4CC110B5866CE391,DEB6BD428B731572,33D660E527E4739D,000A9448D11F5D4B,8F825326011AD9C4,16D4170A4FD21299,33942A6E3B330631,63625AA00E292763,6F96C40A4242E4BB,21514912A90D183D,1A59797E2383E905,003FC46F0370FD58,EEA845D838CD7A6A,5EB0514E7E49D625,54B2E0973805E398,17B61C20AE5F4FB7,07254FDA3A122A75,F4BA831CAC5F4D12,B51A3BD66C7DF983,0023D07841F07E3E,FE500B67F4BBF964,7630061547D430C8,2A09AD4348618A01,C507DB2787AA4F76,6CAA8EC23DE2012A,65D1C72D8AA870BD,0AFF48AB8D93DCFF,000496564BD429FE,F888640D6F81B784,10CE86ECCD17E5AE,19D492D718C2B143,B3269921B2D8F3A4,FA88B4BB7A339C58,02AA6214469B281B,1C047A1CCF83FC59,00028E74EC11BB5C,7E36C62AFB24FAEA,BE0C4DA454B6879E,354701F5027982DA,B1E0478C8D777B18,6859F4C7CFF46B05,3B78A095E67088BF,4E632AD6A5F9ED41,002FBD0D863CDBF5,0CCC0F070988C435,21F87036F0CEDC60,1DC274BA7E74422D,7104AFD7CACBBBA2,8B2469CF7BD97E27,9F7CA6E967506008,E8388479533B613E,0026F883394E02B5,7EDF17B20BDB1044,D2DFD368B011857A,B75A459663321B02,74C258C8EB31C924,28C325667110EF5B,260F5D3BB6F345F7,E858F7898545C645,00002135FC5C9915,1191308FFF0F4258,60C0D8AD2F76F8F5,502F99939C717500,801AD2F34E6A0390,6E863A224A0C44DB,CE4DC112CF6F6990,AEFE2E5ADB2F7FE7,003FC1845EE7666E,C87E756A0CB66D6F,C1AD1D3251A99994,3F9D7B1A953EE9B2,05ECFDA59EFFB30C,062D091F0D56FC53,71729E4D8840A403,86B78A7F77D2E15C,000C57F816A6712E,0411CF99EB90E954,065DFA50420D9016,755D4E2D83E42032,467B36BDEE06546C,BE7EFAE9A04B1262,FEA746511F05C42E,8C93C02E042A3127,0036011C9457A948,50176E0B6958B217,A5A0117627D23810,042B1F70AF833752,27FD85743D7683B9,E914589122A79E38,A5221A8BF8EEFA93,7FD493D0700650DC,00028A5DDD18A8FB,3F387132E46D0AC9,3E6EA9BF05A81CFE,3FD37F39E888FC01,962FDF54667EFC7B,EAD4552E984A3AE7,E5331E746188C4FA,CBBE03E8FAFCB50B,0029E4FE6681A795,90AC0F295CACA9F7,770835D6F643A3BD,49C2734BA9750A28,16CC5F1EEF75C2F6,BB0979D1D35D88CA,435D0EBE5EF0473F,D2F9901D7EC8A490,00101576C54B4CE6,F7E9A8553C02A29C,65A741F370F02BB8,6A2F3C6DD08AD9FE,890658E46CC1E0B1,05C785B53A9306B7,5DE463A00002101F,D2CC0267613C3FF3,002FA2DC66EDA442,A79346B3EA746046,745F461DC72FF3A5,A83096CA4749B8B2,94E50F392F656717,E64D89832C23D55D,AFC8BE640660324D,69DBC3C675259563,00178D1D29AD7510,8A942536D7683EF9,B30C4DEBC81C437E,9AB78CFA2F3527FB,97F497F7FCE336BD,2DC01BFA17040AD9,C82EDC7F13B08EC1,2249393106743CCA,0039972348270EC2,A46AF76BBB877245,5D41E72F78A4836E,42B3F64B30260A73,0FDB452DD75D8F11,C08897225716F0EA,459A1DE5F32A760E,AD93E2F1ABA421F0,001D66BA624BFDC6,87E15878CAE7E9FE,08801CDD6CFDC906,4A2165DDC197859E,25059C684DF0A058,F7ED8BE6DE4EFA34,2D89F4F25C8A9341,89466054B338DE75,001620E30A087AEA,B7C85A96B5E6F3E2,DA07225B9327C17B,20308DBB01D7F8C9,AD9C880F50E13799,6B3442E7E7F491B5,4DFEB7D1FC7AC3BF,43EAABAD3D267DF5,0007C2C92F8C4842,EFBD1E998F36F19A,F0A1F9FE728163B4,F4929182D6BA9680,EA871084455C0FC0,B50BAA45204B7B8A,64B5B001368512EC,02502F4ADF00A0FF,002FDF629C757F2E,4C7C7E375CF34E4A,828B8A41F46AECB5,00C21A0520AC722E,6ADC6FD98B3D1682,A8070D58BB0C4D86,5664DACA44881571,24209F5CF5E2E62F,0005D5612E889415,E27FE9345BB40BB3,ED2F85B3EAB4A915,A72582DB1A38FBAA,E488DFA25BE0F254,6896814B3DF7ACE3,7B9FBE122AA258D7,7B8E516442916BC4,000E2724D8E508BF,521A0E70FB483800,E2D5645F7C8B93F8,09453E6B6ECAD27B,E9954CE8C094CDDF,C9CBA55E2C75CB2D,69DD67F4D3DA96BE,D1A51F785FDC84BB,00108131DAA8E0B7,15420ADF77922A88,343DB2B3010E7B24,22E39169C5423D2F,F577FA4429456A43,C9187B0FF2C9BF29,D1427BD46CA51CA3,AF6790BDE3D8E36B,00350690B51EF9D0,822E456BFF7A376C,98A69571DD9F3AC6,B4AEBB8DD3B61BBC,642427B0D4C4EB0E,2C7AA2437BA7226C,D320B6EC0539CEE4,E77AA6F8CCC06207,000B26E53DC3970B,D779DA7740A82480,6CD30BA50FA779D3,B23F2EB6703B3A77,9D63150BBABCC89F,F3785CE6A0F7D1BA,00D3245DC9C022AD,1CC8DC81F4C3795D,003C6E47734E1C59,9CF5A7186618F29D,F441CF8C3240C17D,CE98D9CD7402A57E,C6643ED47FE5617B,8980757E2C6EB4CE,B882B735BE19220B,64AEA44FE05332A3,0025C1F1906E537C,4D085454FA27FA9D,360DF759CDC7538D,AC234513208FC243,8BE4A48F161EA947,A7755B9784C7885B,DDCB81FFD1BC9873,B5389044804209C2,000473553536B662,5C12C6700CC6BC1E,A62BCE5C16D7A319,A37E3B48D4BF1C8F,E890281E83D68503,0B09920C14B62563,C81548980117BE21,04A99E676A2DE1D0,00207397C01704B7,EB3228BCE54FC6A2,31916710B482969F,BA356CD7D5EE0989,21AF552F8216E4A2,919222390678A5CB,FAF977E36349D5A3,AE34AA441C281823,0021C966D5AD9BAC,7C31A58949B6946E,AD87BB8F1D636276,CE34D945922A6CA7,A4D78F1DA3D307EE,68A334DCEB71E2EF,A146491AA3C26AFE,123CF59EF5F54563,0024C7275221DEBD,477D1BB024AFF158,1FA1D24A7B675D31,B9E1A72DA5FD2C2C,3312B3B77F9EC078,44A467A21731EF0D,BBC8990B896BD697,2965820CF2C4041E,002D4FBFF391BBB5,E8304E807854609F,685611333ECA2DC4,158FDDC02F99F8C9,7A191739293EC937,53003727E76BC6D6,6FC0F1B2FA6FA6F2,89A1F1167F6F4577,002B40A638707828,A3509944DA90E8B8,ABC887F42F0A178C,40E212A38F05C3AC,75771ADC54690009,31F8424E24EB10B2,28025E216CBF87BC,AA664B9965D2B4E5,0021ED52CC5F4114,632BA9079314E478,1AAF9DCE03C075F2,91AF3C0FAF884B5D,BDE3CB9A4A979307,6527B72F39D73EC5,DA6EF60FA9CD218B,57AB3B051B88921C,00237A8103292345,A8AEC7D8092BC505,FF84A7A276B9215C,9364C3810AF997EF,0727F54E36A39211,A748A0EDE318A05F,F791FFEB4C7C3EBD,18582BAAA335A608,001EDB743DE9F22F,AE749199ECA7A714,862FF5012B77ED5E,09CAE9303BE7DAB5,10D5710A8C0C5967,A43F81AB73B3E988,6E5CDAE11F2DD859,93988E681E87D188,002C11881426EDCE,BD16FEB3F357C7B6,49B835AC75D3EA8C,0AFA584563E0B8D8,D6E8C246ABF1C6A7,A030B2ADFD081982,8A199D1A4EA5E30F,DD0372B7F0D859D7,00319DEE3C275F39,4CC79210CCB01F0F,038ED1B14861F1CE,0766953AE53C3BD0,86DDF07026A44353,7465BF9EC7052A17,07E47D7B8B6D322F,F3AD0F83715AB2E6,000209C10C59E628,CBE23EDDB86D7951,AA84D44FAF174F4A,223F664E1541E035,E03E362468755637,CA5E0CC9C1478DDE,55E6BD804F538EFC,5338381AB8FC313D,00371B444CA69614,D6A4B0680A276D3F,091EB86845C58472,321EEB496A1A2992,C9123E7C57ED6D2B,2B196C2C77AC1296,1209491A1E527134,50A30EBABDE00077,001BC657174C23CF,6560E817D3A4EB42,D50E22A02AA968AC,5F0918A1CBCE1324,B31F8CF32208EBFB,7913029FA68527FB,EBE3AF99F8608045,C0C2D35914FA431A,00171D306918B8A1,8A2A3CA3AED60093,9FFE6255857B9182,25B193CEB660D932,B11AA8DA84E8C8BB,F7B76A0C884B0553,F1113256896A688A,C762637B16BB0900,002EED2F83816C51,126F9E9F43D35E17,CC5E9A55F6700056,DBB1F352C70D2D25,A928695785486B57,259A9BCAA2C23583,4C3BE8AEF8AEB598,87A09B2D0B4187F9,002DC414B7BE6C91,D2E650BA9CDB76AC,9EF2DB7E543C2FE3,4D89034197760F8E,9490B810709C1F9A,947B6B69EE75EF43,0499F143CD9D2FD6,B6281AC061E5E95F,0003F84F34115D0E,371542B7C66007A3,9ABE521713406C6E,582F189A9834A17F,D3E1C6FF4E6999D3,27DC3596C68B2671,952751421A22C905,5FCABB517521E3E6,0023A98ED902E0B7,0335E709CE6749AB,48ECE2B1B47DDCB1,570B60197EE43DC6,17587ADBABE233EB,6FEB3176FFB4F8E8,DC537F8059F2DC42,52CE3C9FEC177057,002403120C221425,16DEF75C72002DC2,C7F8ED966AF67396,5C39FE3D7731E5EC,FAE13050BC536A10,F22EF9FBDEA1842A,84633193444BD2BB,6CDF035355D220DC,000D14B61F338BB2,4E064EE2356638A9,2366A9414374E6DD,854E7121FE1789BB,B33CEF2FF04AEF9D,F9E72726D3B88B89,670E7A2ADF7596FF,C8C6B49D7D8EB84A,004013DB2A049A6B,54CCAF4A79571D6C,26C7A2DE530F6376,B6A059F21CB45CC6,CDD507CFC6B02F91,CAC8881B8460EB4E,8C03C22446F06CA6,90AB42A086319F5D,00089ADE7A98B8AF,226D5A4712043139,7C7001AFB3FD07C5,88365C801B43ABFD,B7AC8F4060E6EE92,6CA3583F2D9057DD,6A6F388F6B4271F8,72BDA49806A4F4E9,000D5596A6701FFD,C0826C620F0D44B6,E78CAFFC7C8B7B84,940A6F23B2DEB84B,3C12604714A7D127,8433A2C68D32BCD7,29A0795020712791,5E4CD2D5048C71AE,00092AEE9128CF50,A6A911DD09D6D3CC,F26B64845A9A883B,18BA7781E14330CA,CFB368321BD4F796,76381C9E07AB9047,01EF509B831AA3D8,2A76B5A4F216A580,0029DA638EB96997,AC295CB16399F403,CD267225D12848F8,2E55F091BF16C381,6E46F6FB4BC5A032,DE08E9E36C89F60B,4A431ED2A10C1F2C,BAB48283DB5F42F9,00135F49BCFAD361,6295ED7842764A80,7D5D82C8AA6A6C60,B44F8F2328399E1E,C6587396D6D99248,55ACAD3CA018128E,F52EA6081E3B52DE,9EE4B013113FF99F,0004ED0277612F1B,11792F5E5935BDDA,399E0CA80A791F0A,BF85105CC161A43C,7D8CD9083395A06E,B855FCB041E2932E,124CD0BE3C02AF3F,1C2EC8B2C75D2ADA,00256F4E68E2356B,77E6881A7A345ECD,E1ED5A9FADBC4397,76BD04C8A6E60A30,031E3A7824C2DCE9,14B5F1C17282E4DB,93338CC62833185C,C8E69A2E1ABCE600,0036F894C7007B4B,6A34C97544228F33,501F3C582BB2B594,756DB1F7CE5AB171,C9B88FB1C39424DC,3AD8036ACD3A22BD,03AEE21B4E0BFCF6,AB36287DC0EB2D8B,002748CAB739F621,846D43C3433A8DE0,DB5347693B65FA04,3BC8A2FB4F691CF9,07696A1265A138A0,FAF7D9E2F0154079,7AAE2F4A9119AFB8,2E804AC4B641D943,00310218C5F2C744,9DC6580D2BCB3411,53CD93D097D0EDE1,0BB7C47806BAA0C4,C42B41BA304E81EB,F5DF42BC7E9D7635,2183BA3FD23EBCBD,CC0AEC1FFD483AC0,001BB1BECDE749EE,5122A8E868CA5BA8,6E5CBB38966BB5BC,4A5E914997E4D0E3,34F4E5F32AD7768D,80A476E4B82670AC,49F17D41D5DA8A7D,53D0D832940D9EDD,0027F4E6D359B625,DBADD7C6177D28BF,285F41804905614D,D16BB5A5CAA01C13,505DDBD1989DD7DD,9C2FA64CFBA0DFC9,2FAB334BA7742683,11E0A3020E5B8F42,0006B15796E43311,FF902C98CEB6B937,F80DFC7729A94341,D13D0ED165771CE3,2E062D3415FB2479,69BAA507E53CA625,09C14CA5DF1F5C64,B0B1E77634D486D6,003D65705BBC92AB,639DF3ECAD074472,12B36DD24DCF699A,CD4496B9C93F483E,20A586B34DA5CD66,A07D03ACFA897DEE,D7B3DCBE1BA25A57,8AB43C3CEBA2EB13,00108EC2C0B44091,C0B65AAD84DEE72C,51C09DEB9397AE24,956850FC87B00BA0,1558712A36DC13DC,ECDA009A325B8F5A,42121CF2C8A101A3,CDAE82E76805E7E4,0002433D8268F19A,621B903431BC34BF,023373306B93AF43,096F34AB66CB6BF0,1EB86BD91D386746,AC1FDE094BA072B9,A5DCC33E4F58EB0A,9685800C67419689,0021399B0A6CE2D3,8BD77D21449F3A27,A267F07B0EC901BB,5D608A9C522A4C20,34073A2A6761608D,FFF902B0C69686D4,4F8BCF5F4F30A3F8,D436E7BB0F618FF2,001933728C006EB1,B4D7AAE261E97084,14531317FA06E31F,72AA9E7D828637BA,19DE4B9D935B5C46,CD897D20516F81C8,39BC820E5B6DB03A,9B4FAD4F6E643E4B,0027C47D32503BAE,B1A22853C1373E7F,44F6153A90EE2001,AE252FC0DE61127A,FAC57A1D8F160A67,CAD88844F719430D,4A9329D0BB7C2B27,72BCD2F5028FCCC0,00297BA29112E950,1A7E5E5C9F676A55,8D702BD83AE69273,16F50B295D053C70,3E42F4D75754916B,58E7507368ACEB83,94C7679CD595136A,A93F2FBFA225C95B,0004082D18F3CC65,5994819B4B5D294B,27EB8F5D44AF6D96,AB4B27D9BE416F8D,0D47EE1FD0E7D608,F31D0868628BF28E,171D3034F98D393F,A40AB398DC0EE316,0010FC2FE847A04C,32DAF9CDFD23F99F,D72EA0523F54BC78,C7AC332094354EAE,6B3C80A92270A75D,D13C193136FAC43C,14F78C8F625760C6,66DA36AE5BFA4EED,00004C0B5EF7E436,72D711CDBCAAB660,BC4B219B634B98BE,55EDAF0C2255110D,9AB437209A7C9429,81701335657E6E1D,6A335422FE7C0E41,ED4030B7FB61BEED,003DA17B0B533B1E,3E3EE9CDBB6EC487,9DC557D0F62672B1,114EB567550D4142,A3CB0CBA9DA316EF,258CB0A49A8F2CCC,89E40AD474E63166,70EB65C451255C83,00230A30C7B0B25D,557AC9C1A174294A,AB7BDB46FB0C1F9B,28100FE5D09348E9,934CE2848A756C88,58C212774C42E045,90A6194A4734F8BB,AEC06A374EC5E595,0006DC5514F14894,84BD88EE094523B7,4938D8612898269C,8A8DF641470148A6,5BF7FAB7FCD60D41,CD6C5B8FAD7CD833,2726158C9827AB2B,5AD02760332F7FC2,0002DF9C8EC8A9F8,837A3502647F5D5A,4C8D5EFCEFF5CEC3,C8AED3533D9A555D,340E0BB85FCECAE1,D645E2378785933F,96FF50EF729725E5,5F4B80FC1BE18BD8,0021D6D1B61B7D3E,E8BC910427EA3F6C,AD6862F423B22548,D9F243BF18726A10,8933B04DCCF7EAA2,879E9E8596E19132,7375B2161024D66E,7B8755BC3C110E1C,00198C6CF78B9841,501E2EADF4F19356,E1501824CF587E3A,EB0D13E5B64AF110,AF5001E5DD9A8C1A,522B6C8237E3DDAC,3034781CFD581A1D,EE5E6334E0B925BD,003A63C66713EBC8,902D1264C8B11AE1,1D44CE50C2AD1616,BCAA6E47785B0C7A,FA2184C3B77B08FB,AAA9EE393AC5A70F,25F56F7055708EB8,CEBFA9F2927129AE,00359C8F468A60C7,80329850CC48E1A7,D438625B8EFDEA20,7087E6E213685B56,D67817192120F93F,92F73EFA6589CE5F,80C00482AB0E7E77,488B79F71F4E9F21,003BD5B6F3F3BC38,4935E8CBC29FB5F7,D6129E138F8CB82E,407CE90E4476A8FD,ADD46452E9457DF0,4CF9C79FAFC1F1E9,3BC38D7E5A163008,E5E5ECEB1E20E281,0024706161510757,B0FA7D552E804066,DE51BAB91D70C663,A15462690CA3786D,2A6CF056241BE00A,8EE6D73A8FD81DCE,0B3E8D50F636E251,9ACBB755211FFF0A,0002E579AAA88681,4F6D58FE3FCC139C,2D491D871E9232A1,3DEDDE867FEBC560,DD7F8895C95D9554,EC8A9D7224244C0D,81883CEC46764CF9,089F45B262FB2E1B,0009920CE88E901B,963FF8B954B0F720,D0E639C84B4297B0,B0A521BA6F6FCAD5,BADD4C3665A3CA46,EDA3FC8C97E280ED,4A28FE11F0313540,400DD215DE4CD17D,0007416C927C6EED,FA28D9078323AAE3,9AC73921396CDE28,10D380AD5DEFD6E1,88D5D9A65CD0B772,D18D07AD443F6B16,DDFC66E35246C6A2,EB3335C17060A9BE,0007EB8EBD03D456,FBD08B7237980C15,41A8451086ECE8A7,DC5776CDCD73EF3F,BE3F1B09C81F5A26,66893D4FF3E8EACA,B34A8EC1D5FCFBE2,0AD4FE0FD7E590B6,0006CF1BFAE34ED8,7043849A4E738000,E022F5E4A1CAF400,639D9A3D8D8CAEF7,CEDB8A0C5F627CB2,6ADD4C37BE1775A7,8EA8B97A23860C0B,F5006704C9A123EE,00021F8B40FEDD82,6B8C06E07B67381C,FCEF9EF4AFCDA5C6,F69A5E515AA19394,84233198A7B97EE4,865CDEFB46505FFC,08A597042691760A,CC5CEA9EE06EE144,0015684DB5F43A0A,EC08124200FB3DD3,7A0402F0868DC4B5,07BB35290788667C,F0C5FB1081934807,7E693826D414BD6B,317E37452057EDF0,D3BB8AD430D44ED3,0011465685B32443,9436A421B8CCD9E3,2060DD2077637AF1,0C90AD66592CAFA4,89C2C7DCD1DCB72A,0466F3C0C86D39E0,31ACA78191513BCB,2CB21DEA49BA52DC,001DE869C095DD70,7691054F48E819B0,D9E3397E1050C4F1,8EC45B9659015A40,8B890E2DAF171BCC,D3EE3A9B1264EAB8,7F2E5D3A545C3F4D,FF2CCA014021C0F2,0034C396D58F2693,7FDE33F746E78E92,13009A81AE7FB98A,C174931E4622CA3B,642E8FE08C8B1F25,76D3BF71AD40E6A7,D52D1FB52D7171F1,4A4DD5B651D890F9,000E65C33DF6B5B1,44E96EA8ECF3E501,09D64DED3785C916,4E2BD2A600E46924,FEF7ECA5EB1D6E75,30F06DE3114BEB20,6A63CAC97E01C9B4,F778DB4F368C61A2,00375CDD88437D56,9F20B6D9E068F10E,DC51A7AC9A56C261,47FAA83037945F48,1204BCCE3A472992,A9ED8B723D907290,D50D261FC0D79639,4F5E6464FF286787,0038C7C070858FC2,CB504716FD1A3124,08D2555D80BF6C1A,5451A5D457CFF6B2,EFA95682A8F57E0B,E8DAB8ED7A0D8107,529B577C2076C91E,C1F72BFAE75D9306,00335C2E0AAB338C,57016E0F65B6AF7D,4910B709CD7BA9AA,DBB346F7A97E9F3B,6C5FC637698715C1,4952AD72A80360CB,1392E286E4B99C3E,D143E6BC1B788290,0029CAF99F03A0DF,35990DB84C34EF56,71570A545BD697B8,094EA24C8CEED03D,DA2616ABE02AAA90,EAA27122A88892C7,6D978F58D3801DC2,E4087DC1897719B2,00287A812F4CA530,636D8B0FA6AECA4C,AEAE490E1E0B6821,A1A87080E75230A2,83B55E2F09D6ECF9,EDBE25D20BCD97B8,AD84094FB7EAC4F3,B0F82822DD443BBE,00360A8F77B371E3,1F4B3010983605E6,E3370637B18DA585,5DDFF9E93A4B6064,3E643920B641FDDF,265225F40CDDC55C,F50BBC27C63AE7CC,CEF0E51016DE8FCE,0030CEF363911169,166057C49B2A2FCC,249023D060438A7D,9415FC7AAC050508,03BB09218908B452,82F36E644BC1B62A,22A5EE8CBA6B37D2,98717ED1EDBD5C4E,0018AD3565189E15,476BC92B2FB58E2A,838EB6189A45FA5A,DBC9C2304E4404F4,0DB8107C61C2F694,688E1DC0CE19EB0A,0FFE23400D036DB2,682F5BE53543CDB2,003B75A6F9DC7D50,5CF99647905BF0DC,ED3AA69E72A693F6,3FE82A02387FA9D5,31EA8D1F7AAF6239,A039802A0940063B,9C953C79A4E090CA,7F5A3D0CDC868263,001265877D575027,9FD82AA4A8FF1BBE,7B705EE31B18139A,B4A4B26EE44BD650,96B806BC91113F99,0E7F8AC89A816DA4,6D45684CE1AEB643,66F31CD71F630D58,000930E458C7C619,DA5A4A4B50E4E1C3,B25023F7032587DF,CF9C6454904108EC,4661FC0008C89F86,A9AD6107862712EA,9BD670F1DC0A503C,F901F7B8B0CFC24C,002F0A6765466677,8C5C67C8D05B6BC5,B6552B35DBD1B087,7EACEC2011CB0C34,8D2620F5CDEE0B29,155BA01054A0828A,09C629EE3238B3EA,657427E6529D2C35,0014EC8C353761D5,B1A7DAC0C627C233,D0B45CED41B964E1,24424FA5974C7E4C,3E3B7544A8BB66C2,A1828F8A0A953CB6,C988C3652769B4E1,94472852C1B9282A,00103BAF04DACE06,96075F247EDD5761,7F38A87043A3D268,C7A5C5CAF448D21D,4899324F3F91F1D7,D7E576A1E67ECD42,8ED37DA135154310,450962AC5CFCAE20,0004341D4EF6FD76,5B01BC52EF60C8E4,B1E01B6C465EFDA2,79350FB9F50BC93C,B093738FD8124F35,C8D0A9BB7F91F27C,FDE822F104612E2E,75E29D5F874F329A,00395AEBA1DC6B13,1D4FA8E455323EE4,6C65255318266A60,AD5524696CC7521C,B94165B8E5657198,011F9E007EB59011,885150C302DBEF1D,EE9EDB4A98BCD6DB,0025A5E687D229C1,C801455A07006500,8C6F5FEA29EC7FA7,186374379879A9CE,F03CCF8768D6B829,56E9BD2F0B74F6EF,8E4E48870660834F,280EF4A26CE3C1FD,001164ABF4FE62BA,6BA1AEED19C97286,CAFCB538DF5BA1F7,1C3E0B5EA5C5AAF5,675AFFE93DA8CC2B,3980A905515E310F,665D4F108CD6ED1E,248CA1CE59E737E2,000228D649C09FD4,518A1CC02862E57F,62577A28FA6B8BFE,D87A80740FD7DB41,FA131EADEB10D444,80ACD861C148E4DC,AE3F06EEDFD1A261,16FB0C8A7ABD8B8C,0036EAB4F4E4C7A5,B1E35BB57A738DFB,4A3C837AAD7B76AA,518179A3C83B5B7A,FE4DB0AD650A55D1,EEDDC414B071EF2B,AA920A9C59665216,3E386E4E8A72CD61,0006C4D4292EF70F,A3BFDA386ED226E5,83B28BFB7189ADE5,A7667121AAC0A97F,A4FD66CF56E0B779,80386C298DDB6FB4,CAB9E776A97DF736,A932395A39203FC2,003E163CBAE3FFE9,39B95E1CEB5C618B,362E9F0D05CE8C4E,02E2955053DCF30F,700A462B95EC5E0E,D34D1CE361DFBC0C,B7C9D8B6BC92F6B1,A032C6A965BFA049,00260C99966882A7,AFB3873561086471,F2DECB7CB8785098,E419BA57C7073C20,23F4DF876DC32C8D,4522D94829BA5D30,F6232A51330A968A,B00741E46A02D80F,0037525D348F42EF,0AEBDC8DE8EBF51E,8DC0842C15C46A70,DB7DF763B1BCBA46,DE93C4650B8D5193,6FEFB01A3B8BAA47,214DE673D90E5932,45A7C36901C00EA0,0031096AD9507744,723F3DBB99E2CB5C,C94AE7A18F398BC6,171A4BB2502D78BE,98E74B1BEF4F58BE,D6ADBB88C153B17F,72876FB0F5B23284,B3E64B8356B2FA27,00327D5141E8F9EC,06EBF85F9B80988F,4ED7F9E4FCC92AA5,141CA33BE82F6D13,2F69D074087C0683,37201960FD223FFA,BC6ABDA56E7A5C02,74F216F1D690B20E,000A192204661B0B,D9399A518DD4A04D,45ABA211AD491623,FC737D19117A6E5A,520E739DD6DCF6E3,35A812021757AAA1,8A2A5C78F8BD6DCD,A6832DFD3DAE00B1,000713B5F80588F1,67019A91F93E719B,89CD23280F37D085,532FE0754863A332,376B7D695599EF77,CF90DA1B94B81C80,3FE23BDA8E2506E2,3C1A9B243F9689A1,003409F792D2D74D,8A484D00592E7110,9CAEC86D2727880C,FC0E417AAD339398,3D66BE46D7A3A620,2390F6E557340976,00AB92CE5A599415,C302049B457BEF96,0013884D59EF99BE,45C3985A5D39FE2F,9B74614820A843E5,C8716F4A21864845,E00004AC204E488B,6C81BF47ED08CEB7,2949AEA1BCA1BA9C,AAA05B7491212B8B,001037EBC0BE6F4C,60ECD5FA63F1D923,32826F18E063EB21,77EDB06F68D8C1B5,45EF23C503A729D2,918C3E34762BFB12,CFF6E79E371EAC0E,8A2DDB2CCCB64C9F,001F7146CB2546B1,F5E79AB06DDFEA78,696DAA674314957F,9050BCC02A705217,DFF6C5EC1BD7812D,E69D11CA7FC2565E,B451F223C2E6F0C9,EFD0A548708977F9,0002F5438B2FCF01,4D00C3551B6A5FC4,FFF943C7D0EDB897,982BEA0B5216594B,ECCD8F8F0B162ED5,EEB740E4ADA7D98C,C8943F817B171AD8,00B1A98F068D0BDA,002B89998C34D69A,B32FF6A360ADF573,C3498C4D7D999B13,021B603B0E794DB2,AFB1224743E9F4DD,03BB76789CB5C5E3,84E0D6E6D9F936C4,4D7AFA2A95177FAF,00097377E2FBB284,6F2AB7117BDAEF74,B4E76F3D9160F36B,7DC6AD3B5B0276B9,9880B35CCCDF811F,7EAF3CD5D5465C0F,30E2C5818C6B4F41,7470B8153900A88C,0029644E4DA5C234,038BD6658563C854,A40348EBBF5BE913,F399DA567AAA59C5,941E0D690F301DE7,F559030FBA09FF77,B97EF792EB4672B4,BD8680F6B4FE3687,002F37625698D66F,796A555954D9A225,194A3110E13ECACE,03948C4CF6B7AE74,8ABCD7924B2688A7,DEC556E03F08DCFA,F4600EB925FF7896,D1ED454A8865FBC3,0040669899354028,76B14B0DA56B2CFD,0870F3CC6942C878,7759CBB9B903A38C,5AF722EE7938C44F,31E91B5B4E3573C5,C88BF6C217876910,963C78FA653E16EC,001FB5ECDBC5D6D8,B7546027B8B70A26,857A36970C00DA6F,DFD684EBAB5A8548,20B82A1DE13B5CC8,C12D47FEBF7A7A1E,05B44AF42BC60803,E6E5ABC2AE416D26,001CB8AE6B89B50C,03007800CA9C9F5D,6C63EA31889D58FF,7E615D8FF7A70AF0,5479B2F346CACEA8,C979EAB9C25BA2CF,8B349AA303594AA9,74A23066EF58CF75,001237BD2D904A12,CD105E6818491834,907CBB4C945BCE84,A72101AAC1969EAD,BE3990D3564973A3,2AFA35A03DFEE53D,F8CF98C7D5034923,A4043BA72EDCC879,0039423E5E89C898,95A302D2F9AADFBD,030851580A9DDF5A,6D0A5763F1A91C65,E3EFA98E1C2AC98F,3E54AD3675F4C8B7,DE2FCA287C97B68F,79BEF83992C7CB08,002AE29546C9D1B8,75C0CC74A5D1CBC8,954C99641A418236,EA18143DE7DF90EA,D28BBA123FD3F17C,BA617E0E50110BB2,FBB0E27522A6A15B,A87CBA073E09643A,00078213ABCC52C4,0EB45B3AEE3691FE,5BE61CFBA382ADDE,4E60D5AC1A01513A,B9EDE3FAC92AE875,8FA78130A155D75E,C9EDE3AA3C040BD5,8B55E4EAC3DA2A71,001D741323F368C4,E25E3148F502584C,258E8698528661BB,BB401B10B142E5B8,4BE55D9ECA0EE16D,FD2256C3B48DC9FC,DEE917ADC2605E39,BC4ADB71A864FDE1,001A5D66D15EEF71,842CA286FF28E026,217F3022260F69E8,653ECF04FE095B73,6434AC5115EE6BA2,D9C82D620391F89F,BDE962D0F480488E,2D922CC609E32A30,003C859B20332124,F65F9C311D4E339C,E25E20E41939ED55,3D3853659C48C386,665D0CBC566081E6,26D7B6A5A43F4B4B,165F56755C6ACAB1,19D080BC2767D0DF,001DF582EB5EFD5F,96C8FE36E9EF270C,40131F2E2891803A,D9DE312286B2C82F,F7408970379771B7,E42B075AFF9A10A4,0559EE51BD1A6DA3,097664C87F42BF00,0025B21A986246C2,6A206F4C70CAE431,7AF9A0A92A68D01E,A8F8B4C6E0AFE877,F00EB9281A75272B,A98DCCE286355778,6938181EAF594156,6E6D3E50B715C164,0011B0B6C67E5631,543AB4BDBD14FCB1,159E73A05E5C3427,EB1D51925F118F21,39D566833AE85BA7,4CBBBE081F9E4146,974417FBBF1733EC,7FC21177EABDAE27,000F302422EAAC61,01D15629B746BB68,F3E86D16576379FF,01A71330ED97D36F,E97928DFB5EF56D2,FF353F95DF89B240,2532CB31528B0931,1C3C680F82E05310,000AE7D6B7FAF4CD,840291E1D2D3D5EF,66CB2004AB39A56A,4C7CF221EA73CA82,08A9D6A17F31E67F,EF79F0C327DDF5B2,25A66D837007BCEE,5E4F43CDB2FED422,003E2302A5773867,4818869709A4444A,9597ACFA28E11221,931999AA33D98EE4,5AEB855C1A765A54,BCB82A62E1FDC657,9A416CB1E0ACC907,5480AD25235039EF,00181ED138A08A24,4F7182CE9F090F1C,C51A0D8745AAF921,39AC636DD31364A1,2C14C5EDA4496FA6,6F4BC5CCFCAF8D5A,A417DEE894CBC5B3,3610C2AA590AFEB8,0022AB8330B79552,343A17A99FA311D0,6155D7722FC8B5A4,654D6BB22F36C9C7,9985BE0A5D506D28,9A66DF99CD4611F6,C2152675D35FA1CA,4C9F483973242127,00012AB6B92BEF72,C12B9E1E8B7CE247,6A12463BC41330C0,B1C626A01645F265,43F7023D6FC22A91,A17C56A161F9EE3D,44DCA4D15A9A9049,CA13E5053B73F79C,000237EE6B94C76F,8FE900D0C47C31CC,A1A77F41638E330B,812F412160BDFCB3,B60E5B1F6AB9EB0A,BCAB887298AB7380,FBA53BB656BC6514,7950D357065A9A43,003681633535C7C9,C2FC32786EBAAAF9,80C028164E3954E1,3F6841BC0FDE836D,67A06881403AA931,6B599E81239F5847,2C29FA51D97B5AB0,ADCE4B57FEE9EFC3,000B0D86D8D5432D,6F40006E49B98341,0EA9C9A75F01D1F0,F1E031F3D6F5B5B3,39BAD508B9BDE56F,B1F9D48C16E97913,26F2CE5F17B2D12D,DCA562F2846286CF,002DF70851CEAB2D,4E0957F30DB2EC53,DA2E2750EEDCB41C,A9320FDA396F47F0,1615AF0A25403746,424BE858B7CD5EA5,1879644ED1027B9E,EAD693C7578104D8,0021D6F30DDD9E39,50FC6518DDC64BA2,BF5733CD1B52960C,5AFA8E3A412709B6,02571D05F88C957F,85171346B4794AAF,32B3661B54468DE4,0171FCDF87DD3DF6,00344EB5192FC65C,2E722AE343300D33,D4FB3B15B4A4657A,CA8184161CC8281A,CD621DE10A6BB2BE,FE4B490A7EB6BA97,0FDDA29FE431A472,0807B5A4DD618E3C,001FBA479FFFFE52,20A9B9CAECDC86A3,04A59361A36D4907,1728042D142A1498,03EEE0C0DA9DF201,1C2F1B0097BE272A,FE8426E73E14507C,28CD2A67319B74EB,00132D06782B833B,E02D5CB7EF8BD12D,9EB3C83D61DC4943,C0FB20F42C7148EF,5FED09D9CDB88A74,F3E634C1F22B75E0,CA8A0AD7ECD11173,F3612D505F988881,000CA6E3997C13DF,B83B46D34DE72BEA,5D85852FEFE98F32,616D75EC985E49D5,14FC0942A06B0665,228FB167719D146D,658E4DE1DFAC3BD9,F24EA15DB3E3C1D7,002ACFD5C0E20D86,315B1B23D5F2A330,A79C1E31E9CDE70F,9C9A41B8667594C1,AE6F38D09B3E60FC,265CE85ACCE602D8,BF7E8774073109C4,83D1E8C88403C6A5,001306081791A518,0B8B0B363FC9E237,6F5364041E911C4A,F43D754DD0DCCAA8,2ADA4A238F01FA4A,6434BCBB03CA3F88,3B2ADD5B540BC920,94A4B643C4A1B8A9,001DB97B9638322E,6B7A48B99D0B5F1C,189AEA36C339BA3A,AD4E5A80F350AC6E,E4D1A1E3805A4E33,67421B97430AF9CB,F7C0D93A76054BF7,DB324EB77767DDBD,0036596B6C9FBF7A,F07AAAEDECC55909,E055806501F7ACB4,40CCDC5818228A08,04555BB393D183CD,DC0441E250DA311F,A560D256F0F2E7B6,20A37C039B70BE87,001FF7824D1855BB,1CE5A1082FFDD959,302D4BD1882B7CAE,5CFE282273349498,839EB81647C8B24F,3C769D3A85B10EA9,CA00B1A0896ED5EB,34C07148AE9A5077,0029E70577C39CBF,6ABD584854244DAC,D4473C2658CE1F22,B1B1002882EEDFDA,6A2160D5696E4D50,7C71D84FA4F7845C,46F60E34A097FE7A,F718BEBA8BF72522,001CBE9E47DD3CBD,0AED7329D612C51B,EB3B71A22B969FF4,69019B9C8672D4DA,A2453014AD291159,E03C740082BDD09C,1041AAF4B3BEDC67,E468728E51DD9EAD,00006119ED975376,3664A800C615E0D7,ACC517BC9C9E61E5,78192BB5C28465B2,11602E094AE02409,3F9F9B335D3382C3,C39F2CCAF8DDD409,0AE065749263977B,0011E226B6B3B0F1,42319989B8D5D75E,EAB74490E700C284,15C6B8FD53E806F7,15BF76BD5153C945,54B4267B4B42FC8B,7B09DEDE52C475A9,B22E971286C9C8D3,003F623D00FD8ECF,1591A0C45D8361D9,1ACF10BCAAFA46F2,BCABDDB27F7B5CBF,F3C6A91A8AFEA31F,6232A38451A6D29B,AA1F4F855D0B1744,97B5B183933C6D62,000291922507307E,5BB504A7E1FCF555,F73321B146132EAA,7FB75F88D82C6D4E,BBE61EFD88F71F02,310BC77E4606A51F,E74ECEE53855A84D,F942EB226D449173,003D82D2C4947C6B,76438AA61E577CCD,4D71A54AC59CEBFB,96566ACD40010B72,930C7FE05AC8C63B,AB0F537E41FE1083,3B0A776FAFACC84C,6C20F790027DA2BB,00344CB6BA49779F,F303D4A9A2D82EEA,A233E945A4F2518F,EB213334E4A16BE3,630D7A516A7B6355,0EBC33656FCB182B,750F6ACB7761FC8A,EA61D1A9446F7190,003E3E44B4392D33,CD67AB4F0410F3EC,D70FB9BFC565FA97,E67B87B28E4EDC32,F3A8F7F2C5E3A2A4,D7EDC40F94C45CAF,2213FE12838815BC,2CF43F273B8CC0FC,000D1DB3CF3AAA22,BE5B99057D611259,CA8654685F8F9CAC,522235FEA7A9EC4F,F896C12AC03050C6,508AE77108AB1B1D,9E30667BED3366D4,F079A6EE1D8AA11D,0013282C3CA90409,870F39F1B4B104AC,E8C39830EE596BC5,7B32C9464F4A81B1,D547BDAE4792AC9E,030974CA2D13757B,E482D5865680B94C,3C90146A881E13F6,003DEBACE8B364F3,6F3EE03D3CD2D258,EA29ADBFF1364961,8A178E0FB05CD70D,D53190E323E7B475,984AB67547AE8533,69063992EBD2A519,8881B3BA66E31D84,0008F10B9F570E95,41400A415DEB7AD1,2E56471997A9096B,E3C2DC8A6E23F8BC,68A4CD097256B0C3,A02FFB6B77F0F672,D3726925E276975C,7D5F8269807B53BE,001F00E30CC9B41A,152FDC1648111730,F3540A15675C13F4,A274378EBEA2FF0C,62F443E6C2FE09E3,8DECEB6B2EB16128,4DD2BED800DD9DD1,1A90F3172B873C6D,0011AA66A1B47977,C95A74B57C1A897C,E75E39A35E9F6BBD,9C1B27CC9B6B3A03,C21DBA577EDCC1EE,93BEADA6E8A25427,0A60CE314BA90B54,3276C7CF6FCDD633,0022B34210C91398,A0E95DAF3FCD26A7,5F879DDB5E0D28F1,2261E8EE5DAB0AA9,7B33C6060CA46D69,B1644E0BF57954BC,D128088EBC386F0F,14E086D07A78E4C7,0034F319C51A28AC,05C42EDF9CF445CB,957F52BB1589F2E8,2DD61FEA532AFE53,CB587F5B4ECDC050,1D2497BAF0AFEE6A,26303CE00439E3DE,FA60331EA7B93190,0015DA35787F4263,FFBE32902AF0DBD2,191346BC1A4A0649,0A1906600C2494F7,AF0F9AB85A0AC43A,1AF253254E752724,26A970A1264B8211,B501EF4EA647DA05,002934962B517269,73AECB1AA6386018,034F2AEAA1ACE2EE,86AD3669D6DBA0A7,C0D177DA1C3FA6F0,1529DC1F5C2A7235,894B739FB171149E,83FB223419E67590,003D21058995DFF2,54A4BBBBA114AB6C,FE6F7286D1522541,5A9A6A247B5AC603,F6776B9E1D29FEE7,929D38447E63D8E1,BBBD27965DCEF91B,0C2D442700816977,001AD5DA118B146E,344B84BDB9FFA115,7A5775664B265BD3,CDE6DEB10BA0ABDD,F4D4B0583BF3B62A,F2D41B2CA3D53A40,294C04E78806D6FE,1B307AEFC05C8C77,0008940782BAA71F,3E777426D19231DF,CBE2792DF6AE002B,3022829521CB9BA2,CA1EA1F2446F1F48,ED6E6F211FADD664,9C976BFD032D1545,3F85100705FBF7A5,00377E821587AF44,C0071FDB4506BAF3,E047CF69D7FDC2AB,F786086DDC7F476D,0E2774AF00F555C5,AC6A3B707B2FC5D9,D23E0055C3DB4C5C,21FB409015F2F5DD,0015BF493F8A03E8,2155631B63A59E6B,272B4997602009C7,6649BE221BE711BE,5DC7A7F43BBBE883,7D29B4955D6FDDD6,1C0A2B6E8E2B461E,C6C0D64677982224,000D37F9848B7162,C396EF7AB4ED546C,552CDEE0D25939A8,FC9B9E848CFF1633,8B92EAE46F3EE073,C77F9E3EB883726B,A881CEA2F54A04F0,500FF17B8273D23F,0020D56F7154F047,A1A2376F16D99591,FCF828CBD5AA378B,A5B8D8D4D89E589F,05433547CC8E426A,4787230F932B92AE,FB86F9C0BAF3C33D,042AA2A35702D2CA,0009CCBD8C4D6667,B3DA185E39CEEC5A,8A7FF01AE11EC8DC,39EBE5D98CDADD63,5BC9A19BD216204E,2D2860A7918775F5,D885F0DC8666DFCF,8AE05E25503D8138,003DC2D17ECC97B2,E2BDB60BE645A7BD,43DF84260A81B1A8,DCDA8D148368CB93,C2480436EFC907B4,16E664AA8FB44DBF,B52B687B87ABC064,C850A3F0ECE8B701,003F685DE5C2C6EB,D02B29105B781C87,29188F02C8B10AC5,3E816F47A8BB700A,CF1EFDC1544EC09E,3919081B19180E58,9A449372EF56E8ED,248AD3A07006E96C,0024C2835D0A3F50,D78B9206242A976F,B1A10FBB962C6F95,4B5DE32E9F547654,43264CA363FACAF4,C0CF610DAD109DBE,E59D22FDEC56D278,D8D694FA7AF4F319,002FA98AC94E1671,73EB8487FE8C89DE,49CF78B23C3B895B,BAE9DF8D532CEF68,4B3AF09CD08D742C,D4A8BB6D9F0E1244,F1B058C462DC98B9,EB91FEC9686C244C,003E73EA54BF6524,6C6C10344543959F,3AF9102E8B36F6E9,9E28C373DAFF54F7,6081BAA5617DF455,64767BB55954EDE3,9D1EB544D386318C,1219E9A11C5159B7,0013769C49D79D70,6DB7BC53D9F7EDE8,7054DE397D3E094F,6A18906453C6A030,EBD7593DEEA97173,C7866E0424A2C879,C96D3385B1F8AE1D,8938265C0ECCB7F2,002B25CEBCFD4FF0,9B2FBCBC60D6573A,AFD75EC76CBBCDDB,3FF61627893394C0,A08A46DFB2212ADC,2342DACA333C7E4B,D115407315B0B5B0,E9FA1B66612B89B0,003301CDE0D95356,6E34079547590318,537B098A97C85FBD,7BD787C320F4CC1E,4F94F20FAAB01C2F,BAF429D62C1F7410,F36FE892A42904AC,D4254AFC0A5B94C8,000E420F37686FA5,A3C92085DE84A899,D8C2DACB160C2258,A18EDB5638572120,FAD03C0265556AF1,A968C8411A6B22AB,BDD8823C1D87876A,45987AB6F969C2CB,003C46D6DB90BA12,7A3C61D955680F62,871FFD4EA24A58DC,4DE00FD9F57FB1CD,488DCA16C9EE0A15,0F1A0918CACCD6F6,658D0E8073C92983,063E749151F36A63,001BB27374461182,18E1B6C26A209069,C82604C3ED8C5176,6B2D87245BDE1746,987485F1E4508A4D,F4C83248E4925BDB,F3187BF447C85B9D,BE0FF428A81AC9C2,000EB84DA9016CD7,387F6466CE72B8FC,CDC76B174C32F14F,1D16F20E01629FA4,08C56BB98885784B,C9CC74525E13EE4D,486CD8489F1256B7,E1F82E194F16D4B1,0006A144892C2A97,7DA3DA642800F208,05935F4F33F9F37A,055A8F5A4E96F8B1,362FF37E830D873D,77C9A138E16B5E1F,692833DE43F1B351,D133B1545F6C4590,00069D4EAFD485F9,55EB9433AB730BB4,8EFB2381648A3A5A,4C701A983A47AD97,228AF5DE3B639C24,267A5A9D47A0B59B,87ACE4680B758275,AE453516E36E373F,003043024DC5A6DE,FAB08F91F7FC2029,2803908863B3B9A1,6E9CF47A30763951,33A1ABC462750ED9,A58D99CBF1CDAE48,6181A03B9F2803BD,B443B1B3D48AC19C,0004807BB94D62E3,95B4592D158A3014,EB6CFCB2731B88D0,FA96785E51546650,DDC1E4C92A044453,36EDBB51F65865C7,C7716E719B1C3DF0,D2B26F096362474F,001E4FB4CC552A58,D8362223D8130726,03D3870842D35E54,DA4B3C673BB734AE,C6C86D413D287794,0F74E32FB8D176FB,15EADBFE6F09FBAA,9F16D80F0E6E3196,003957624B71F5C1,FFF468319114F589,B53809B723FB8F8A,7ABFD9E4C1A1C2AF,83421CC37583F166,4CBF0029F9218F97,06487C1A39A94EF4,0CB21D2D326CAC8D,002EDF89BACAC24A,6A95794ADD509311,76356E9582D7841F,5868B5F291335211,B8F8C80941F88242,A37B62B5097DF457,03FFD79310A6FC96,9A108159B62D9B4A,001BB0231EEFED89,ECB235AEAC911325,8B82112317368E87,33FE3FE58953080E,717CE99E57202D03,50A12155339798B8,1A97074EBDB68541,1534DD7A5648E08D,0012AED50C31BB6E,16ACFBA8E56819DB,D52BA1E3B667BD79,FB489297A6D35080,643E6D3DDEE176C1,0C3A3ADACE123AEB,0B091771E70BCAB5,9A4C918C4493AFB7,00384F9F6FF650BD,6546A7CDC121FA2D,AFCE863EE1CFA3E9,6A934C6E70A6BE87,E8655D4B5662AF88,6A1F2A0285342F21,46C11B627918D724,E4BE6DF9B9659F80,00390911841E308A,2A73EB24F0A65A33,E0BC7EAF41784949,E73C2B8C6EBB6385,82BD75F81882736C,DCB4AD9625A7DB4F,CEBF1102537B422D,353CA0A587B89A9D,0000E9A70B3424DF,F8773301736F2D77,41063F34432D2398,49D819C0D91DACA9,3EB0B5898279832C,C13E2402ACE02DF9,44DC9DFB5CD17D95,88E0B64C5BD74746,0038CAFC9C72E843,BAC98F97231290AB,A45B913F6AA2B50B,AE1A9C68551D1A1A,A36C6DDAB5D4BD35,3EEB2442C66EB7AA,8C13141A0E8FE7DE,46E099B58B89E512,002784E6E3099293,CB67D4108AE6666E,F8D510A0D8159522,5CC654DA676D0B3D,C123A2BF2FAEAF2A,FC1D9CBE64F3BECE,C2D9205799171E08,8D68A915EFF4997D,0038FB7376D4D2EB,E09589E787A87FE9,58ACE8E910D03D86,220201F377CCC114,EAED308ADC0F32C0,282A953967F829F7,50296FF8F863B425,755A85B656C352F1,0012DFB90BB01BD6,A5DDDDF8D5F4AC87,5F7D9187DB043CD6,83CF2FA283A7D73E,0EF5702C965609E7,093EDF9804C788C7,9BE12EED9B7FBD24,E632E733950E0772,001E68164B161A6F,DD26E141D285341D,000DF4D60D7B6E56,B94C12CA6242161E,1AEB75CD4D299266,D807ADA47E239BFC,E069F089071415F0,08F60FBBE3A0DBD4,0010404B1FA853B7,CCCE43A15E1E5FAE,35B5B31E4759BBE3,28B23FDFBF414503,901227CDFB632284,C9EAAB6F4BC960C1,BFC4E09A1F320A3E,5F419F748166B08F,000F79C7772E0EE3,A8B901BEF4239EEB,1A4C8554390FBF13,EFB53F592CD3FCCC,0A3589E4C1A366D7,A8A48481A5B59156,24217FF6AEA4F02A,623CE943311B6305,0014D555E4C92C6D,BB52EE477BD2E631,EBC3D2186E20AD81,CC83F164CC6FC054,A4C59392277CF453,47176E5647C0E680,BE107651B58D3C2F,3DECD023181E8800,002960B1AAE66F3F,5675E219B9C1EF91,10F192641232DDE0,1398A003C7D3F882,08665BAF15FBD43E,8443C158F425F4F8,88F7B4481D8958FC,B4051FA09391182A,00084630C6DE6671,F551412008F280D6,697FE59EA58367A9,B8B2F55995238002,485457171EFB2AB1,57AC0809FB01A791,F7E7C89978FA9508,4AAC34AE64647BCF,000B4C5F142FAB65,118F793257B42CFA,64CD9BF710F1D234,37479F0A67F6EAB1,13D4E3381B5DF5CE,219E2A26F03F249F,6B78DCF8F204C81C,71687650C03707E0,0022659DD168D5E3,AA16DF38155CBA93,D98B2029B33AE8CF,4DD2BA708583D220,E752B2C7B360A76F,7F30F548DF3FC6ED,2BE0B914DDFA761C,7DBAB38DD3D8B5F6,003D4699CD7449A7,07D6DF8147853F0D,63993A0AD4C92E86,B5A1671D038106F2,D127FC1A94A5EB4D,6A1558637CFE965C,5BFB515E8E91BC57,254E56DA46F56A00,00209FE9FFA8CDCE,6BE9ED91715B8F95,4AB10A94CB322FA3,407AF776FAC0824F,AC613FCE40E10604,662E2C296536FE7C,043C52262FBC3720,D1E3A52274617294,0025B817EDD8011C,EBE493C3D0CADAF0,0159099AD85868C2,9FD956E7C597E1D4,6F89EE0EE87BE0E1,B0EC2B4E4052C1F5,8ACD4402A0372C69,7A08FD927FD46BC3,003A4714E948A10F,77CDFC5083A0A25A,F906EFDC45D490C2,6EDB4ECCF141D39A,54EE71D2E6D1A40A,41173B5EEB57E77E,E295D9E1F65D3C46,DD0F31FC0DA93FAB,000549C961679C10,3FDFE3C7C7A9D52C,93E388F6B59AC1B8,D0300D098F0A347E,6EA7AC70C3F37E40,5FCEB7DD7A5AD3F7,438910DA9107D92E,C89C7658CE2A957E,0009DEC051561DD0,9E2A4D04574B1251,D8ED0F063AAB6A83,07945D265C7E42FA,67105650E84DB0DA,28BF124970B468B3,6A94169F307D44BF,B2EE2BCAD4FD6378,001FFF930F0C2A5E,6D7F2FF6A049D71E,76634551C6B073D6,10640D3FB9F35B76,49484DD4CEEE7A22,81440E07CAE2E0FE,19037F6085887529,9EC9992AC7199134,000DA2B8E3004171,27821EA419C9C2FA,9ABC88D3CFE56BF4,A122AF04C3DF4FA1,FF2E26D43C1013E6,5762C0A146213D8A,3F615191281E000C,9524F82AC69BE70F,003E17A6133E6ABC,05466AA7BC3F5F2F,4350037AE8FB1E47,8D18A2220A621DA3,788EF5C279A51B52,0D1A9730C0BE1D31,D944FED8C1F94D3C,94F58F686D312D0A,0002A0B5A5465930,11D43E8D67003AAD,4FBACE50EFA8ABC5,4964779493915321,7531EB1D778309FC,CD39068196E06899,6A69CE38A251DACB,1DDB731460734102,002DEBBC489D8C03,CD06A1C8EBF2B504,A10FE96AC0077106,084C3B062D721726,65333C6A1D84907D,045752765A44BCC0,C8FD2F45D703FA0C,1B69618CE517D9E3,000FEB3D0AB2B601,15DBE789DF2AF7EF,E2A01FA9DEBECFA7,5FDC9AB6B51123F4,29C8D07EEC9C5336,43109C47CD0FBF6F,4135930F8F86C4A9,C48E70B81F0E8837,003D081A06D5A3BB,7B5B122A5B20D064,5CF18A7430763970,17F66F87A2F798E7,9ACC84439A596AB3,02986FE1613F2151,5716D109C40D7A81,BB47335E4DABE328,0017D548AE75F57D,6EEC52AE44BB73C5,554D42315671CCD7,8B0CC6B7EE7905D5,9A817F694604C8BC,D13EAF5622088935,5F920C89E08F18B1,12FB0FED9012DD45,00401F6C80B0DEF9,796C88BD62975DDB,B82E3931A97E30F0,8631BE0950D24BC9,FE930B2701113AAB,A31664A26C860FA0,71A42646CC4A2120,FC55208F7D7CACF9,0014C9CAD1A00FE4,E739EBDE68024385,14613CD9B484C88B,D8C30AAA97D88162,E5B02C9F3F2ACAF8,434F123ABF889092,0EFDA685CF6CB926,857936056DD2421C,00046602F23D4B00,5DFA3AFF43D9A444,1236FEDD41E3FAF8,D7E138C160789B61,431830F2C3C1DBAA,7807C5B9ACE1BD54,BC0A2D176D242D9A,867C278ED3E7FAE8,000F1F669F6E6B28,664423EA8DBAFE18,5DAF3D59BD2950C9,EF4A0E3779CC5FB2,CC81F360EA356040,A14113B5E96D8324,6B5D128F85CF46DC,C7FF1B5AEEA644CC,0028D773470A6A6E,15D838A7ACCD9A43,76D8CD4CFD41C7EE,55756BF6799487E2,FEDF2342A53379EF,78C5ABFEEA8A8A41,5AB8C33068F7B638,C40AC38A3575F728,00161890616BA663,8AFF56D69ADA42B8,4C791BC3C07B1E3B,EDD9FC59F7227ACE,D10FE3B5BDC93687,F036B48D909DD8FC,47F47AC134002697,0351E3F3B8BF2FF3,0019582CF0693413,94AF16CCAF048D2A,B81EA8638520378E,A4F3325950D72CBC,6976F354C90614EA,4A2FCD2B55C5F3C2,117F8E340375AD45,0027CC54C328A891,0033F2066F89C3D4,7A4AC920EF90E40C,14DD8B3F0249CC7B,087194BBEDD909F1,5236165C70A83BB8,4EAFE4EC059758EA,5D44A78D1A0C5013,DEAF3E36A0C5A300,0003896A50CB5D8D,2C084BC371C6E4CF,93BB707C9C4109E3,770D88E8C79189D5,F14DB86B4FE91CF6,0561077730F66899,286CA950D6927B3E,56BE5D4BD98C80FC,000FA30C69007C20,23AB74F48F9FAF65,BAFBD729FB558670,131DE5C7963C98A2,CE1D4ED520F39FA3,DFAD1EC344D7FA00,A37A44F1EAB93A5D,CFD1C35E8EBF8A0A,000DC9DF45F83AA3,A9C17EDE18669CA0,39A7B82006758FBD,64B0259221EB22C4,B5D85C65D5E88168,16436F8669754AAD,21B8C1A748116F14,2ED397552EF6703C,003F978E064B5D36,40B3DF97A27BF084,21EFD321A40049A8,57D12F721CAD15B3,AD5E957724EA1ED0,444B273FA4BB8D84,82E591B74A331AF8,46C8BE25FD06C7B5,0029C4500DF3D073,4F8912FBF96F566E,4BB34FA98561A722,EEF0B8CB50E93A1F,F53E5CEF5A6D65A4,149C6EB5C9CD3C46,4E0954D519B0933D,06FF8DF80EE0EB36,0032C98E02558737,43B8DCA9BF32C1ED,A9C38306CB330BE1,9744F427AEA006E3,F88F41E5012FF811,DF663A6637F408E1,A1FA7695492AC459,B32AAB94F3E19F1D,0012BEB0EC4BC70B,271B0AF620CF0578,286703DA93B7C29A,F3727BEBA3915FF4,6BCCF6500B255F5F,3427B9FE89180845,6140F65C1E22F268,01003515CB7FBC83,0025357008D953DF,D3653331D3C87F2B,4BA41BCCC74FEC57,74E8C4C7BA494949,BB44C86F4DE60BD1,AD3CA4FA521CD21F,AB9996D2563A1F7A,E2DB420A5250D218,002E3EC4D1B86E04,3D05F53D0FF2F7C6,0DC17DD8909DDF82,E3A8D208724CC7CC,9EA0A8173737EB67,610E4E00B68E847B,5412788ADF414F6C,49CC912BD65B124F,00274CF48CC310C3,794C4C270D2C161D,D19E13F26EF9EEC2,75D3ADF084265ABB,11DD9F3D9C9E3F27,92710E4D4DCCE0FD,D860C27BC982F4C7,580EE8D6E78C8F19,002DBD010897AA1F,4E852E4C3CA109E3,C91D98B53B21D6B7,0858D6A05FAFB70E,792BC2FB5301E912,8A82C8A3BA3FBAE3,5E2A3E3CA8EECB63,FF0EA9EB04FF9CC7,003B2EA2063A7E75,4AACBB14C14ABF85,BD76997734A83FCD,0352279F600CB281,38504E3C2A920F00,9144E1237963AEB3,CBDC6C7CB45FA066,9F164C54620116F0,002B459C41E0701C,DC4B60BF97780D38,690B044855305CCF,593CD8D289727824,54560D9FA09AE5AE,32A3295DE28D23C8,19B52D70F63ABC5D,D2DFB118DDCBE737,00304A3C12AD1B80,5685CEC39BBDD60B,70D637A449D90B57,8934D6171B23BFFE,E30F49041987A1C2,E4D2F4B313015C5F,0241BCB7DF7E1A81,631E8C82F425B639,0023C9F877560AD9,28F04BB19451521E,F8156BCD668F0E45,9E1E96AA0CFAE74B,AB8CBD3A7C4E96D6,27B404DB285046D3,773525C402D6538B,81F6E6D54CCCE942,0005DC5E97B3BAD6,288323FACB5B4257,953C22422A9F204A,1C0ED7C6268E82D7,0A446979F7850B54,76B98D2F8B07D7E0,60FD0D827D4F7220,61098ACEAE05A8CA,00389870BECDC095,3D3FCDD607311F83,9251FEB57F06D973,0B566032FC3B33C7,D3A433C5986284B9,78E6D2C58F45E212,0593EC0613DBF0EE,E3D38C2147C01188,0013718562430EC6,9A4621E414B480BB,98B143D60C9DCFC2,4BD8DE11CD9A8E37,C8F386C6F0A25F58,1DE6167BA50E7B34,4DADFB936E1FA694,2CE76D4E4051E51F,00291337F0E71DBC,A88E724012DFDE3C,C3E830BA332C0AC5,F4099AF3334E01BC,1EAA677497D9A84D,FDA1CE4333C554BB,668F492F63D1EAF9,9E35A6B76E2CFD88,00161DCA581E3ADD,E8DCCDEED99E9CD7,CB7F5D9E166106B7,183B24A61F3B6E18,64BAEB387D95767A,70F31201B5807D2D,0F6CA197835BD43C,93D9B892F5C5FE26,00310CB53129DBD2,C09E9FE6ED6823A9,3850F61AC87B7542,CE9476A73CEAE0FD,A3C22B187FAED29A,28C10E506598E2DB,F750C4300E591FF9,F47D94E9E9686A2D,003FBC242A1A280B,3332BE29325B9C70,3C7F72F80774F712,30FDF3FAA08FB1CB,833EBE35E4380018,96ADA42E4F8D771A,F35018756766BA8E,66099C291CBA2FFE,0034B700AADF1B24,3E7591E647384456,6B7AF85C78763FCF,D465D2522361A694,6C82789F78684C32,3AE1C6D1E34C3ED2,4193EF9CDD4DBF9C,6E87A1A06328CE8E,002108BA8A05DBBD,CCD03BC1413973B2,EB9FB42703940754,F189A8748202262C,5F90B065A37E355E,4826BEFA5945F347,3C67DCEEF0FEAA7B,AE2799527F0473C3,001F2C9249617D00,D4C28871D3BC505B,FFFB216866709142,3C63444DE3262775,F5ED7160CF02F215,5B014E0A9F8C5BD3,C1862D28808F21B5,F870C68565E36F20,003F2710B60593BE,BEF1D60D991BCFC5,4B0A129CDB07D3A6,99A9314A9E41996F,6C96D92DAE2CBAE4,BD3A449F5D654ACF,802447F6A2411674,F08329209967BE56,002FA3DFA8364997,DEFACBAA3549161D,DBFA6A007DDD8010,ECE51C69BA2F5EEF,AA0D24151A3D874D,63381933CD247E51,6516CCA6BA360AEB,32E3B9358A6675D5,001C46E8D52A0B24,72EDBAA8382BBD33,FD319DD2DC67159D,9B7A496A36AD0BA7,1E41915C4D696B4C,B2DB39C6FF76DA45,92FFE8B8F8000CD9,5536C2BB42D3C942,000C3CD7326B900A,A9AF67873844FBB2,B0FD43A15A311C64,1AEA919D15192872,12A8E381880B4B51,E70580E415DBCE11,61D9324CA56FE26C,BE23514F3FEF4393,0024B69C9EEE6957,3A27ADAE0B64748D,1ADBE4890696BEF2,3B4B57C89B32D53A,5CDF971A52047E5A,B9FC1C17598567C6,5BAA4B429944822A,66FEBE75AABE1978,001F76B942E071A8,9FD8FEE44F3A95A4,A586152102456816,EC0A781B5AD45CD3,E3CB07F6D4851437,AB4A3BF9F09E0BDC,3DCB42A451F81BDC,29B84E82ADD5C85A,001451CBCB232CBA,C096759145C9DA3E,4E3155A6796CE01D,88D503918B45A19F,1230F2C8B09BE58E,8D220BDC095F552B,922376E11E435D63,08E083544B2890DD,00094D5220F26782,C1B456DE6A4B81D4,3FA9750014729D76,7A79BFECB89AE809,BFDF44378AB1953A,2BE74DC0EF32DD9D,81976227A272F9E5,8ADDCF78799D90EF,001996B638513629,B6F63E8A1E45D238,599EC46C51E74244,F6ABC24E8EE013B4,6EE80309C5A45C10,9DCA6246121AA3FE,D1571933FEDDC3C8,733F0CC3420C3E78,000CF0604E020A23,93319E7FFBD520C9,2A657C99327C19CC,080FC1AA0A5A2A5A,A3872A28AD2F9C6D,A39597A263681C28,006C1335BBD8488F,B7A7A011F7888CD5,002BAABF3731994A,5DBED68235D58F2B,F89883D6D562FBEF,97DE11384EFDA114,222A682AB82E42B0,FA1EB286FA954C9C,39382CA977697709,D39237A378363B04,00369627752FA9DB,A576560C2EA5069E,6D02CCB503774075,11C46F0CB709C497,EAEE0310562AD98F,89284135184FD534,610190FBE58BA6BB,817EADBBACC7CC99,000689C27CB71649,D402C5C3CA2C7BF2,AD16E0FE50D350C6,CC9C4210B89CC74F,B047732D807196C9,1154B51C38C78C80,DB5A12EBDC473DE6,0A22552BC61360B1,00131E6B1054ED1C,F4BA0988E1BC8109,CC40ED73B5B5E88D,2322F64F4B1489DA,5B0D539BC1E0BEE0,9249DA4DA653D787,40CD9E564BA2F2C9,C801416BE2BFFBB8,0009DFFD7737DA9D,5F99666D33799D45,F716D080DE19B52E,DD971D273CCD4DE0,D9AD110074D1741F,C943304470E9B77C,23BE47C1039B58C3,A5C1ECFF368EFA1E,00076E6F63816ADD,A11D51161938DCB1,D8B99675910F6D4E,A9A799DB28EF46B3,A05333BC1028B5AE,F787D290B1488382,1572773AEBA711B2,6ABFA436414B9C2A,000C2E02D421B98B,9E4AEAE86E05683F,5A2CC3FF32F4C285,CEE14FFBE3E568E4,6887A9E68890E33E,592FB6C4619DAB5F,30CEF2F95E31EC88,452338FF00D26F05,003ACB500B1FF850,C05BA6CDAC6D2FCC,7C61ECEC6709C922,9DA23469DDF948FD,5F2EFA6CBB8A071C,6B80585E18083C5B,ADD8EB8E865D1E76,578E41085EAB93E9,003220C471367328,2CAC7BC36FDFE36F,4051929E48D6426D,C9B830CAEEC02213,E5D645FA373900A9,2B3A6ACA8C3760A0,B72F27DFA3252041,93D8E91275226683,0015A2092BDFA436,C72D9C6AAE2E0BCB,29101AA7512FE240,DDD26281A55DEC81,02F88BB74293DDC0,6C62EFFC0381B82F,E2B85BD0D82D3D83,011BAABA61105C8C,001CA66E399EC772,28EB1F1AFE062813,98A2DAC42D603FDB,25FC3F495F3CA85E,8D886055BEC29BF7,C83C0F4B4C3A4332,D13B949E9F9D20E5,987E87F301557A98,0038DDE5F7D36D41,928DBEA56E403A8B,362FED6431F7FE65,8376D137D286C01C,720B352B02F17AE5,40584E6E74DCF41C,D600B63CBB7CD5D0,1D80F0FA0725C105,0039D8F24CE2C478,AA893CE3BF0D115A,74776A6F368D1DF9,CD79FF051C509BB5,728FDDFC5975F55C,ABB98E868E41FC49,3EB17A523F42DDBC,5F8042888EC0DDAD,002F17DA3027302D,97F5AB0C81D2FF18,6C64E0B001EB05A9,A288000B211C1ECD,EB387B742439C9A9,D2BE940E02B0DB6D,C14EC9788F52A610,F12BE50D57133881,00386D875D489C6C,600A7E162F9A1BB4,FE8125A663E7A421,1D642BA1FD783BA9,000DE14A1FC8AFB9,D92E9D68C776F56B,B5710C620156735D,EFD06D22F650D61C,001EC8D0186809E8,BF3E9A2070CECAA5,3615DA35C94687A0,D40A534FA9FE3228,E8CBF3A9308A3CCF,E75275CB9C144ADD,0FBD9F41BE9711E4,FF67DAF80786E519,00146FD2BB6DAE7D,1D7848E29647298B,0CF3FC06C0F4400A,2C2F670232B67DEA,160AC4FC945774E8,61E1303F6A7EF020,FD85F80B31E9D578,6856A93E49C07727,0037B3EA5E126065,DA10450F20E7DCB8,5FFC0CE7100CE3B6,61CA82199D42D4F3,D43A24AC2516AE0B,13F9D787F49E3C0F,62855A9FA5DF7548,E1B41D3C0556F83A,00173A17FEC2EB89,FF244D5E0ACF52A5,2CC191AEB51141E6,B9183DB37380F34D,87B24E37C7C3D714,2F84D62B296A1F24,868D3829C0211A02,1496870D850C5A01,001A51E68A656CED,90C25A5AE66F816C,F2AF762FDE674CC0,DF920AFF7DAE2A3E,1D978E7137360F45,1BAFDA0FE1732259,083F3D7512554DBE,6BD117A45904A308,0012D1E9EDEA37E1,5F8CDC211855420B,664BEEFE50FF09B1,30A39405F20D467D,C7B99C128BDD4E0E,AD1A17A58869FF6B,6AE9B47CAD99E306,6AD4F0496A6EDB49,00273619672BE9FA,22C6C9FBBDE263BD,85618211349FF3A9,E5A39A608AAD1E90,7AEB4446890DE58B,35F194A9289510E9,7224527653DC64A9,23BBE3E57DE803CB,000938AF2A98CAD3,9612FF47AFD1DAF8,021779C0C608319C,630B017C9670E3E9,4751554E2C156C6D,527F41607FCCA039,A77B584C1F16BAD2,829EBC360E6ABED7,00297B832A0C6AF1,73C33F49ECF40DCE,BB3FD8F1BD41D8C4,B5DC14D91346C4BD,BF7C767BFB64AE42,360637E63F49871F,4DD50B7FE3E014E1,4767D3E69AE87F8A,003F274662A5CE12,C4BBB9FC3AA38FDF,A460292DEF5EFA23,C0C200A6018ADC79,48A97B7ADA84AEDE,E525ED4AA96189BE,B0E8B57E1DE6C489,7637A06BE06D7350,0028A91208F0432A,3DFCAE0556ADAC48,392202075005E977,9BD5B0678C603F2A,9B04FB35B14EA461,EB2B86F23FD704D7,727F0FA058406B21,ED58A90965743F96,0034997CF4B084DC,E2AF724FF66C0FD1,50DF35955B980BC6,265AB93888DCE6E0,744EF22A38C9E71E,327053D660198D77,D9BAACD95BDC402F,78049642824864E2,00310087E02B21B6,1DC6F25EB7B9622C,E36A0F6FC31629CE,EE8A878A44F5C091,775F281AB96C1F85,6F59A026543D237F,379F3689AC5CF935,3AFA0F2C7EC27E6E,0002796D1ECCB5CB,5494D13A04BEA185,64F53E4FA7D4EF15,245A999C541BDFAD,541209F84318B0D0,5D993E50451356DC,9659DBF4D8D87A78,169D2A1EDB02CF42,00363FD45436AFD8,0A84FC6A992CDCDE,21A5AE020ABEF234,96BC1C33D1F2383A,63E78E2B3346AEB3,4F63980302EE0486,1D14FB4833E5D22B,808F304FB1C40364,0034771B99F54778,78C95A4BB375B00E,348F1A80070ED789,9C11F18ED934E0F7,D64C47F4E4AE29FD,10C79B81F9A56CBF,FE2107F556AA9B1E,F7BB3BA856B26A61,00024D0A653D9C4E,A8845832CBE976F0,D01DBCE13B4F426A,DB2453E2F0E1428E,B8D90618AA23D4C3,356D5B0458501666,4FFD87F772CB3ABD,6FE566E99097E0DC,001C088F624E833D,631929D334A7CDB8,FA5C18048C79D8BB,F9CCF708F18CBBAC,2F02C055C57655DC,27BECC664EFFB2A5,A420736950E526E1,ED615F84D2C7C532,00092413EC10D361,7EF2FDC4839E5BA3,84A5F428E5DE16AA,489FB01FC8B50A2F,28489A29DC9DFF42,A982AE79C89E7381,E9977F61E20AF365,59875BA22486C22D,00404F8A652B08BC,71D8BB5F082F47B9,1B565793213C6BC8,AB30CB49E8A53F20,009D88BED50EA52E,7F3601EF67998B53,3AABDD1070C1A8E6,411F6665C703061F,001392E7D77098E2,A31A4BF8876D1197,F5C9ACA2EBCD0B71,4C9A8D6B74700FD7,4640DDE48D2C3066,57ACC50FF2E96190,58376B2BC5B696BF,87484105BA6F357D,003B2C493F8A2121,91D6DE6D1D17A516,C7F072E3A789C183,28C12CC74CAC8A18,3ABAFD93F40C39A5,2C78616CC24E1E7E,1136AF85C6E40C65,6EDF5DF4D61AF16F,00094DBD3F6F598C,B21A819B9A6FD292,1CAEC88DDE622995,91CD618D86CBCB0F,60FB8E0F0291051F,7B97A7B1BDD95680,5467B6DFE42DCA37,2B0DFE37F0730F00,001D6523B795D202,0336049CF10BF2E1,5F59317393248A11,E75FA67FD1589AEA,924207FC8AA3E251,D8A8E83C06F9BE2A,02D5AFE4BD696FCE,D16D8B5D3CC809B1,0015525B97301FB0,314345959018C3BE,659254B0585CDB21,AF8BEBA58F1BC975,CC7D8FD1716A3E0D,4E070A1AB5E5C55C,A9DBB3FCA3AEB7BE,0AD4B4C6AD1260BD,001F9E0CF59FF375,94813DA97E2F8BC1,F9B658CF2047FA18,C713A0DA44D568C1,39E395DE56A0ACC8,9AC5D8AFB0B6D530,EA6AA51F119F5946,46B38377C30F4E2B,0021AB498D858051,C73939338668C495,7208751B59FEB2AE,5A629D0A03071429,D39787E2B55B110D,E15EB8A59520B116,EDD06E4E8AA4F092,329E37BB0FAB80C4,0039A74EFB722D20,CD401D8273AB5A75,9D1963A4B8533717,45470851E799F135,7EECC55F2ED6A876,41563171EC2AA645,AD23B6D6D626B742,09CCD5974321E082,0008E9D38E0D3814,3E52C83F7C5A62C8,C51A5C662E9310A5,7D5939F0602430CB,CB6592C12ADAD3A5,635438F3CCC793D3,6F7E847D00032AFB,D27A214195586C00,003779E0CF289C6B,CAC7BA0C0A380054,DE347A37A28AB418,91289BD6DCB7FFA1,944B759359F82DF9,07276B87745A18DD,84754879615265B9,F80452D196F9FD81,000F5B070F1077A0,E769019FC15CAF22,AA1E50866146D908,3300CFF4B1A70812,DBB3923E64505DF0,EF2666D7CC650DD4,D9B917A305BD5DA4,C7A42C098DA0915A,003CC762BCF724E0,94AA2BF19CEF61B4,8132FDD8FA77E6C1,B6452A50F09FED14,551CAC903720E327,4A6B0A0E15194C4F,96A7FCE28EDDE82A,4EB6064373F6E83B,001B95D22A39D109,57CF96E2ED5487CD,E54A7A9D79D0EBE9,197C9DBEB995D464,1A1D27B256848D7E,58AB83538E633B26,1A0BE2B1CB00576A,9FDC685E93BF382C,0019386C283BBC43,75D701B0C698D99B,8586DD968115B47A,BA84EA25DE643CAD,64033C58E81626CE,2779BED9C85AF18D,7BF584FCBA319F53,BA5B4211922B69A0,000256C27809CE49,74F690385E6F147C,61D019570EC2032A,FEC47DBCFA1B9F93,0AB0BBFE47B67627,EBF8522FD8776C83,DEE0E2B0FFE995AB,70C4CD2C61F1B681,00177E202AC8D498,249318EDC01B3CC4,EBA99B8C6098D8D6,CC5863D9A921D3EF,A2AA63B341628D8A,E4DC896CFF5DB730,71D53E3AECA3B7F3,AE638CBE82FB7018,00283BAF94B4B7E2,2B3DB607CA6079E1,14383A711D40C7DA,BE3B11E03EB28684,00C206C777C5B4B3,91DA281D352BFF72,EEA85C62F3218E10,21E3BE8835D866B4,00272D2A680662D6,4448ECFC9A0A7629,B1182522F519B9A3,9456556BF3440742,C51A2EBF5BCE7885,3E0493375EC92A0B,3B41A43D4F021E4C,D4A9AE4FB6896BC6,002CAF5F67F3E722,CE1F170400869525,C2C66919D3DFAA15,F5E45BB08B546E2D,22FE47A3FDAC5AAA,B088B6F4ED79C3DA,DC6D5AB6AADD5A55,40DA50DD62AC4171,001CEB66A2107DBD,2483F053A4C56176,110F72965488DB10,2BC4BBCBF96C0468,D1547E46F2508909,F86BA150F6BF1C5D,3365E9CA0D54051E,8D21DCA4017CBDAC,00325FE8A5F05A9F,CD3BA097F2CA826F,427E9A8394111F04,2ACBC5319690B71A,C8DB6D7420D78405,201828990FBD01FF,F5616C374FBCD71D,E23FA3D3526B19E6,0031738E3EF93D66,98D0EB6BDE834D38,9D61758925C5985E,1E0D4A6CB55E4FC6,C2E1BC4944438349,A3BE217ABA316184,42645C5D9A5B2EF9,9D50978F68A6A327,002983DF37CAE703,1A485B83F6DB8908,B35A5E4D95BE1ED3,A7C272B29C5177DA,4440F8F4E26B0854,985AC8B508E7A444,FCD0647085DD9969,3D882C40768D287B,000B6E8432FAD494,CFE04705B47BC7E0,7674EB5DDCCFA14A,7AE1DFE149965C06,C1C88D0C07A058C2,BBD2EA534CEEB8AF,007A87338ACE7B55,229C75BA3DD66B00,0002BDD287C9144F,521D01B48588E4AF,58AE419EFE171E2D,6CFF92EA5B6CEDB0,E3D8694D91912045,209371C628E9E34F,C8F751596CEBC440,1119ED35FDF21DF6,0025824848131A97,AB01989E637820A2,72E05C4D9172352B,88F05FA27E9C92C0,53BBFCF8A2388259,F0C87B077CBFB2DE,ADA4FA000DEDA483,D9F976074532751E,003DCDF9F4C6A756,D145623423E1DAA9,CC69DD5E234075E0,29D708FF1F0D64B5,F52A3C5559895717,4DEDBD3356ED413E,D624255A9AF2BA96,0AF20345064F1D31,00135BADE608C516,C967D527E5465C8A,654B45BC29B618A4,F51452E61FAF2971,DB4BA76523E6C49D,DDC09A2004B4BECD,98755DA3D5E1B954,8229155D393EB3C4,003271DDB5FA746A,173F24E0D0C4AC22,1675DE801AACAFB6,30B6B2FB90542A72,ED3D5AFD967082DD,6A4C8ECBF044A8F4,83F80C3D8C04AFB9,4C3632111C1C6F4D,002B9E79B8C9B464,E12A53491590EE41,B393585253DD620D,B72AA42E87BB986C,79C1115D6D9F60AE,3EA371F7E13B2685,C286C8174D89511C,C182F65469D467D0,002FDD201D3512D4,9629E906D4BEA4A5,E7261287ABAF1B36,8DD89A24A3219058,FFE543A866831611,4377EDF973C94F62,BAD652DF25AE406E,FED749157198ACFB,002A9D4DB1D5EEF3,B0CF72E65F87A05A,D852B5F7BF471DCD,9A1F1BAD79986468,AA104299199B423D,5842BC02D1C60DEC,8773E11E8B25E4D4,C96FC1CED343EC67,002064452B30A68E,DED5EB715564B2E3,74B50D3904F1C20B,2251C45820AACF02,FEF02F7C02394905,A7747DE5C5E9312C,A580F49EE4B5EEE2,F0C95BE4AB8ABC16,0017F47DF2C51557,47B30667B552FDE3,2BC8EB27B8CD0705,082F426D37536C42,0F496F110B0B186C,A29F6BC934B7616D,BD42ABCB49414ADE,A17B241FAD1DBCEF,003D001C189B4622,A9C7FA27FC426408,D5AA26C4A4C0BD14,99C9F97B567A8501,37659DE0A9919B1F,6FF92FF990B025DA,309E10E3B9384950,228027623697AD01,00162EC154EF70B8,BEA7EC1E6F74853D,D09B37890C6F28D2,DCFACDBF85B15E3C,C4F4F19F63CF4089,70DC71CC3F6D5EF3,0AB34526135A484F,07B331CA4FD05E74,0022B0B5E50116D1,87E4DD2EEB3FB95C,A382A3E4355A8B7D,E698E966569B0A1F,A98CB5DC4E8ACBCA,CC271ED37293B5D7,F6560ECEC68FBB1C,1E44E4415899164C,001D49493C76B0E6,1C35D90D0275EC8F,44A4B1E396873C39,A0507300D873799F,121BE0250711C94D,680AE543FEF208AA,FA437AA3DBAD3A08,CC1C406163AE71A2,003CE5A378EB2CC4,A0534410BA8CBE2B,C917C2D1FB73763A,0328DB26B2305567,9153FFDBA347EEB1,868E06C393F21D1D,3FED47D1260230D0,742035A2F9E8129E,00046B8AB346937B,CF9DD4BAE75A8F6B,E4B9E615DF4DA1C2,81C5C8B6B21C534E,BBC4C5CF14953BB2,54E6E80CFE3001DD,49A5AEA1B48553B0,A2EA003F57686E08,00268702CB64202A,038F9FFF7B2BB348,15DBA714D60FDAA5,975138A15CF1AED1,B4FB3BCBB158DDA6,B1A7EC5B58766E14,FA39E77765132DB9,4B86264A65BE950E,001417336BFEEF42,ECB6A4C009EAA8BC,F6E6A67FBC82879C,A234452AB38B5053,3A1B413F40D86391,E32F2B081F1E4361,27C2B0E81A663B17,D7A7567224F14063,0008CEF3BA51FBA2,91459EAC3A5629F4,CADAADF5E39A7D5C,60DEDC3198941785,1A22C50A1780D3D0,695FBFC11365796C,DF40C3C9650BD1B7,7B48DB88D8136AFD,0032EBE418D09136,E63B6E810ECF726B,B97CDF98A6DBC71C,FCD20EADE928127A,372EDFC4BAB18EDE,00A29205C2E91083,9069F182475618B9,5FFEB57A92E2155E,000FE975C2568E06,DC013CC6F6141DFF,CF8CB3DEB1925178,363685A8B48AB28D,4C43BE8535811B15,15627306BD1377B8,882CBC96EE54D446,23DBFDCF07CABF41,003FBFB512405945,B0152C5930490CCA,0F5A570B9EDCDD91,05EDEE8555782885,E4CE1D9F32D9EC96,BF4357CB6CE0BBDC,808FBC35214A6DDE,A8D34F9FA1A4104C,003F0BC8D452A4EA,307D16ED052B81CC,7E9D624DE73CB275,930B0E9B1FECA556,01E7068E5CB5A0DF,C7BF2A2F308D958A,DF3F515E1D2A95B2,FE9A0A6962604D30,00358C01E425D867,8C9C08D646098523,379F6E9BB702FF7B,66058305AB4AFE43,18D8E59BDBA6250F,CF436F614D86C04F,0BCE9600B4DA2847,557EF2BF0E3FCCC1,0023E606B9ED5CBC,4BF53F675A26E2A1,78C108FA9AD8CFEE,241250342958D616,89D7BC58CF7F78F5,4DE6395637908C38,A94457055B75B5FB,9A3014182FFED566,003C1992B0C427A1,EA4E1751DB905BED,2EFD0C03904352A2,F6413BA5DC7EE672,1ED4CFF4C2115670,A0B4AD9F731A70C0,043EEC14FAE18AC5,C7899A28BA8C8905,000A9C88A5752172,AA2D79632FD49ABC,EA2353BBA39F18AD,67E3D687F6E631B8,374B3B8B36003C42,29931590257BC9BD,C6886A1E17539E08,C43505355B59C6AF,0021B2B6A2899264,CA3A595CD7BE995E,2CDA51079E2E0DE5,BB1845ED9E75E19D,F46AAC70095E56B8,023E8027C4BE71CA,98419F617346E1A8,B8B90935E9EE642E,0034B1BB79CEF49A,B629B8D5FFEE23F1,B800BC795C401A94,5485314A481464E3,7EB30F997EF74F80,5B895FC269D0883D,A2D95E9C96BC3171,65031FD87E1C3A9C,001FA57DF30C43E1,BB016D982160A93C,E536228253FC8CF5,C4D74A84D5355F10,595BFD6E9DB9F5D8,64F069D57E311418,503677202159517D,DBEDCF080E8141FB,0004C796552284B7,12F426F33803255B,D7E3BE01E32BC649,E617FA022DE9B5D6,E8E7FEA756F6AEA7,C5458F699329B87A,8B91F4151313452E,60241313786017BA,0004E25A5F5DA16A,8A41467A02422A17,80199D02458548F7,1C48CBDC71ABAB03,607DF9E1A9781E9C,6588B38EC783ABE7,D0B55B9FB13891DD,0F6724374D476AA3,000D540726D350CA,1718F9F2149AF1C0,52B79988C51F5941,3B4030230C7AA7A4,825A05B65A077C3F,0CB58467D083C79A,E4F5FFD84EF99C00,56C0B432FFCB8A33,00354EEE3E9AD95B,8145F35E15F647B4,3FB256112732C350,EB350758EBD00F8D,4499591D91143518,E2070FB771AB0E5C,561146FB10ED2035,1085A721FCB3CF0B,000E541D3397663A,E90117B3E0AE9B2D,AAA77334951758BF,CFDB50797C0FA149,DD17C280DC21B549,7D49C1F875A8BAE2,E75BF473D008F962,4167CD8D82EE3947,00281C432E048039,D112B62D628173BC,273709A2CFFDD735,D665F8ED19510D97,AB7448533F92C669,9C337FBD90228B72,EFC787E8AC79A46D,6890A85062143E35,0004F07342472E46,1900943D1AB4B955,9BF517D8129B14EC,255EE2BA641422E4,C0279FE806FC42C1,B0B82239E3A122FE,50B8A85E774D572E,E2B3BF2E43483DD6,003E67551C8369FD,8D66300F9CEE056A,8010E1311D3A7417,1B1D3ECCA7E77126,C26D79D785E3BA45,D8F858C32AFCF9A7,67FB6BD6DB19B91C,99A323776355FB0F,0029A0286DB959CD,68F50F99013C3EF3,2A749218E02D7B04,5CB35DD30FDEB21E,DC1B930E18416772,0C0C946D7B55258C,80D9F510172BE5B4,3DD8C2D2BD5A0CC1,00155636499BE95F,039E2E819A7F2508,C08FF2CAC27F330B,1ED97ABF26F25804,F1D18567E82A98B2,06CDBCF7BB19F281,BCB0566B3F8945B3,F01E0FBB2656D9D2,0027204208B1CA81,6DF134EB3E60C1C6,AA26E72AF36BBD1E,573072F7E41E483E,A1BE8E71FFEE43EC,BA5CC05D59050B67,BB28305EBF5DE4E8,32BEABEC75C69291,001E708DC27C5291,4001AE5B61A53055,6A02170A1D9CAD98,0C1392E140318E45,48B0083536561731,3E9CA574EED47315,A149B2A12936C02A,B670069C4A4E90E1,00148973450ABB5D,7DA56B2BC6EBF9EA,07FDD370C9D27A65,02E9A2F7458766F0,DFB292B07284616A,C1040800CE1C85F2,496114C82EAD612F,D37A6CE40819BA8A,0039C04C3DCC6645,8D20A654DEDF1FA6,08CE0EDE55FD8F3E,37802B79B7A08E93,1C5F2ADE73CD97B3,76720D09CD89E08C,75BA3F5A28AAF747,55F904D8419C305A,0025A03BD62FC8F1,C4BA06C20C4D1CC0,9CEC95B8BF05A12E,695F448700A4A98F,04235FEB4547D5BF,1F5F0866BF47C9C5,8B1DCC409EBA0910,58FD48FBF5DE3D09,000506B4BF983150,89539B96A1881897,FB6CBB1D6923B804,5DB401970266F687,B8447AD7075D7616,4C3A0B8EDED05030,51664D3B097059A2,5D8FB2F106E7F944,003932ABB123C358,0D0126A1DC0F71BB,29C21FEA37542900,F306A89A435A270E,ECCF2695D3BC3A95,44B5DE3627C7AE49,5B565710246F8B03,563B0ABBC18C2637,00121CBB4E8F04F2,C49148EAC96819C0,72408119C859C896,FD2199243E6A2F9C,8183BA69D32D4893,B56BB415EEEE6E8C,4F156EAFF19C2BA1,C95AD93CD57259DC,0027A7DA48E0EA4F,5B768DB53C86556F,586D3FE5D6FD208D,E9C463DB25229F64,BA503B6B71A2E18A,7EC6833152591E54,95F9B7DD2FBFEFEC,2F229736990FDBD3,002629CBC1069719,BB617B49F16BD532,A37703F733AFF58C,B63248D595DC3687,C6632463A958C328,611AA540ABACBC5F,021FA52C0647CACA,FFF53FB3A8CD103D,001000CB670B0C03,515DE70853DD1182,385BB6878BE745B1,B73E48D826F44331,C90A62A5465D532F,7D681215A3810E6C,90F969B2150957B8,BF281B139A6D3B35,0025F6E4A1C3CE0A,C16343AF1D5C4527,C22C1DBB9712E267,FE016AEA14FE32DB,4456258430EA0B26,2B57CD1D221D6BC7,0DFFB154E20E0E54,52A72B91E281A00C,000CA9ECA1E0FADC,FE1C0DFFD4D5EBAE,1AFE2E522404ACBC,5914F2BDDDE3EE6B,6F7176BF15BD99E6,D9F6E2FCA2AB72BA,6EFB55583B61B111,8786A730207C6C34,003B138C47F9088A,F94B164AB76430B3,A295355E74C7EE5B,77F92B52D18FF54E,775FCCF202D953A3,5B8E2E574BE34D5F,34B6E70341A31C4E,ECD9D4E5BE4AE719,0029AD665C94FCB2,CDD6F1943D3C10E3,8567CCA051A5B791,A3B5F8C5948DE6AD,8E73FB78647D99E4,0C351C2104915831,429D682DCA2AC8F0,AB520A63DBB6487C,001FE3E62F8392C4,7DE04654EC61F41D,67824FA484C652A6,6F756C9108131600,CB92530B8505D42C,5CCED0B48C2B2B50,3BE292E9529BB29A,89D10913FF101461,0009D4B0431E8504,7C868DBFD353D16A,568A3404B6669310,DD74AEE375DD8A91,3F1655DD228D81ED,934ABD5EC0BD7A94,5EF9517F3D4699D5,111BB9DE1DD001DF,003D91D1A88F1317,065B636C7722C27F,BD0C44F1239F123A,55AF6274DED331A6,0C6568F98895CB58,A870EA3D9178DA87,863A41A7B8A330E7,C7CF176782C8C1BD,003FB9578500953B,7EEAB6E0228AFE14,36659FFCF6DB2282,40A9B5A049004341,9EC10E24A11462CB,E333D48B77DD739F,D2A855AB8F7FE2EC,6B0E2DF0137D8B56,003DA0C23C0881CE,AAACCE0919581D8B,39F7F92D0E80A105,D821731B2065D7CB,2CA03893B8C19F84,44C4A77E5FB07DBE,9B5675F6128CB40D,9E49E0B78BEBF42A,00007F2E4E8A5EA1,6E05F83F073176C0,9B3D5A93D0758562,A5B8876CCC8082E6,C7E9525A34E46EA7,3E6B4A5526FA6962,ED87D94D510403CF,06CCDFC5C2647E66,002901DF6F037F1C,74CF2C9B87A5F2B0,CEAE987999C7ADC7,35E9A727192F6E03,4A4D3AD4B49D77F3,D27FD5E0C4C54710,DF29B97225CB9872,6D8D82347FF40649,0018A405EF23015A,56481FD29477FE7A,6AA2386605419C51,41A41FB31E99D8E3,E6BD6011AA3E5E57,65F09BAA91EF5F1F,A3A5380F861DCB49,B9E6FF8F316E65D7,004000ED89089B6A,FE0FCD954F088FEF,53B5EB509734B66E,22E3F6C7A12CAB89,0C2980C2CA79F9CE,C6DC4A4221310A83,5DB81583475C44EB,6E10D904252F17FC,002F5F4BD41BF85C,15D7C3656EE5ED45,97B74EFE23FDCFD7,CA96977BB657A7F6,20D44B54DB914666,CB91BFA928C7EC57,DAAE20A43DCBDA69,229F1687572FAF26,0035B3BA9BFB4D57,6B6A8D28C2901351,4C12764166920D54,18A86B303CEB8998,1182A8B27ED0A1D6,D498FF4791EE6B7C,AEB2C4BE0A2C67E2,5808A67D1D92F74C,0014814B13363F5E,858C553F1835507A,07ED51D9914F27C2,40A3D17D9CAC626D,39097AC44DE0D75C,F2178638B7D1F50C,BB7EB772591F0A7B,9F686255EF7D35A6,000A9064140A607F,1A7EC5501263C22B,E3687812C25A350D,BDA7EAAB02246114,68E717DA0DCDECF2,7CED60465A331FE9,BB74949DABCD53EB,4A919CB351D42FB0,002D92759A4932A0,F44ECDB7BE9092DB,1A53955E9524274D,8613EA1ECDFAB3D7,EA20C9E7D21B9955,7F011339B2BE026E,EEB292231C71306F,2D0D5374975ECDD7,0014AE1D3FBC32C6,C1E7975E66B66242,7BAD6D22196F63AD,78F0928EB6A6E063,FDD48D7E0F884266,9AB6F4660C9BFC65,182064972A5A6F12,D4228486073414FC,000AACDB2CF5CD6B,FB433D0B5A270360,94D983CF1F3B6ED1,EBBCF923C6C903AF,057E84737C3C44C9,7AD64695AD957459,BE3C2C9CABD67C6D,D47FAFC22C195E1B,0037FD8DD963C06B,1B7CD7257DF43481,4B84AB35D72CE833,0D80D2067BCA7902,01F98AA2A59A78A1,4F22991E288D9625,D323ED993F7D0844,8271E4B63793EAB2,003F874B98B5176E,418D5407ACA1463A,2BC513978309BB61,A1A6854C3474DAC6,D976E9A909E3A5C9,B1AFE01782B31E91,B0785390C33EA7D3,A6DDA849AB3BFC11,002186A57FF0C18D,DBF2BD11080CFADC,36AB4EF61C4D5B87,039992E60606BCD8,CFC6EF76A2979969,6634565282DB8357,8F728D661B93B9A3,FBDC4B4CEA82801B,00368031D32DBD23,E82861AB21993ECD,E40282622418771B,028717F907DE3142,D1E3A076AFD2A966,7EA256547E42C323,83EF2FBBF8C839A8,8AC3CE85413DE658,002AEE8E89513FDF,EA28F4954EF91327,36E0CC8CB74E5366,9DECAF4703633A53,8FD18F45745E4389,EF42919FF8E3EE05,FBAF103E020A2A1E,35F660310551415A,00010632AD398091,04E0B44F49CDE901,E065AC369DACF8A9,F323C58FA6022646,E3D7B09E43C303FC,3BED0CFB6DE03DD8,EF2D9E16D7DE07F0,895D3CB0F8FCFA87,00109BFD2A970458,55209A57B8F4B176,71DA5E3DC7FF3E4F,FC8E65CA3D06A7DE,670E7C40B85BD26C,599A572B553CA428,6201084FB931E2E5,31D812C28931FB37,0036589778299FAC,D9C462C5011ABC89,B6E6CA855815EF12,5CDDBC4E63848A35,EF528ED208FBC8AB,32F87A51152B09ED,46A6F8E9B4599434,0490F47669D4B0D7,0007C2BBAD7BAD16,FB23CBCBA5FA44AF,F5E7C1238E95E52C,D255B251B308E959,F0A3241F03282148,B65745906E33CD43,18C57829DDECF5EB,6C7E3626CCAFA7DC,000E911795C16AC2,7F0CCD978898F256,764D0F63F900A730,FD8BFC81C69FDD04,401750913347A716,B2683564BC686D5D,3397A816C0296C70,A922C9FC20E44B2A,003C8DF343407AFA,B8F0686168881CCE,93B626B916306A31,FA51B65E769DB9CB,E843E5B00DD0D67C,D80E7B66FCD0CA0A,E588206AD35F6245,D34A3D2AFC4DAA5A,0028B8664A34F48D,93170A03F72552FD,45EE21540C84963C,BF3E61FB7B3FBD12,9D9C143E9ABE2571,671541EB2D9AA5D3,A5461881817C9932,7F2468B3C925E260,001BEC81C3C28246,099C687C514D7B3C,29752601BBD15C73,71F916291DCC0C6A,E33314CD9AC62831,66B9323E3A686776,58072F552134465B,9C174A62D7878246,003BA51FDAE8F72F,114867FB3BEE10A4,E11B1B569AD4DC8C,C4AB64899388F8E6,F49A09AB85A5D2C4,5D0672FFD334A2A3,0751092DD440DED7,73E549B17E3AEB16,0000F07873553492,C8B647F9E1C0ED8F,4ADBA093E6557704,97B6B90E4DF6AA43,22F4DB9483503872,8FD5BEDC4F34DD10,60F3AB30924063C7,73A70380645B7ED2,00372650123CC3DE,2B6E939A9292636F,A5C4F8C6C866FE38,12A58B09358A0C34,73C99BA4A23C7408,980B528247056EFC,452AF51F3EBBBBF5,8643339158AF4015,0039AB4AD465A168,48BF4CB7F15C81DD,A64F1732B05B3BC3,D2AB1FAFF50FAB4B,CBC64114481139B8,8DEE3F474B2A3E5A,625AE83FABDF53E6,52E99FBBD47805FC,00155FC935C1E72F,4BF0211AB842DA21,394FC4A99C5B2977,17FF9DAE802E2FD2,C5B19C236C955EB6,860965E93BEF977C,7FFDBF68BE7A44CE,F15F07FA372B03B2,0006E0E100DB4D36,EC17E0AD259DED95,9D22F4001CC183C8,48860DB9973815AA,C87B8112F4A3AF13,B5DE391C2842D531,D0038BA75C802144,63888B28BAA567C8,00182D8209CC4878,D7E9E6C88EB465FE,8039430DADEE37C2,3E8426FFA2FA2EF5,B7E8C603E3F37F16,DAE6FE1A547765A5,A6A9174F8BAD3A4C,EF68BC5B91DA2F0E,003F359225C2C5B4,465EDA917624FC42,278A694A4AA330BB,0A961155066BCB4A,32A5319843D2A645,210934AF80ACB74A,26F7B087671EC345,33944E4A7A62B506,002B7C0A04BD8286,A2141EA3A8C23DD6,38C3F3122D85D125,F15349311BB871E6,1F7B25CDC914A40F,31B73CB5F831F591,DDB6ADF5EF69D0CB,E7AE453D7D40D116,000948D8952BB7FA,5D340E32ED7BF68A,BE31DB861CF6B000,FDC8595CF25D7AC8,848C1553970EA408,F9F569DAE3AC0D65,3008E1587ABC86AA,28EB6DB25BB4985F,001E651E9A3C753B,E89B1B6841564105,990BB8A068D5A1EF,BBCAB97DFA1D6703,529F80A55EEEDC07,8DA41CF96A58B64D,13C0456178342304,9DFEA6552674C4C0,00240122A3D4706C,F0721209D3B81AA8,0C0091C6E46CF4FE,0F407433D5FED448,6B3B8694F3590EC3,57F43B96ABA54AC2,D965D6785A2D1516,22A85B7EC978BE5E,001FFEED257EB868,68BDCE5E27AE6A67,ED4962414926C6B8,90C423F5BCC17325,10115EDDF6C497F2,1BCD60DD92C6D0D7,EF072E7489A72DDC,C2F561EF20D2904A,000551163270BC6F,560E7D9BE474F3A5,8AF56A149E24133D,C2CF1EFAF553B893,333EF97AE711BB86,95288546BD0D1982,11ACEB14080C4BFE,2A5FFFB9639A2D9B,003B394666E496EC,90A4D55686DD048C,5BF273D12C57FA72,3A16B8786138F2DE,3F1B7243932282C6,3B6BF94B588DD498,97FD5D001DDD2983,8D5EC212C7DCA867,00038895A68D4AB7,C4A86433DBA729F2,7473E277AAC1ABCF,3531CE769AFE79AC,134173278B1A1CBE,DD6454D4E0CD03C4,DED2FA7FE133A336,923989001DD4E1AA,00389E526823419B,DE50FCF86369C72F,E2184C39ACD11D78,646FF940C8EBC3A4,110FCD305ABD64EB,08A7201A4928D973,870CAC102A99CAB1,CABF6C7533B5CAFB,00040621819C7846,2F328A1D33F2F8CC,2CC8E32E0EFBA4B0,F7E6293BAC914755,2B8B49301B02FEDA,A9B3EBA711EB4C60,7189CA6BA50140F9,FEB8D79EDA1B658A,00176AFC18E1235C,35ED1C259CA6A6CD,1BC9C94B006A1613,EA0FD02543F6686C,524658CA2D2DFC81,900C07B9A4A94C43,595B8E0CCCDD27CA,AE1935021A1F4059,001379887BD5B732,B2AB6DDA0CD98379,78A65B1E6183A0BC,0D0B0D9862682726,13A48F9A92E04B9F,F572E4513B7EAA91,2D862D99B2A43733,0BF0623C3E7FE69C,001488D90A0ED986,4C6CB5BAAC8FB2DE,D42595B3D586B598,1A73037BB60A8953,16F9D10116D54E97,80B81344056BDDD4,C77D2BB98B403531,8011CB9AE4D3D8CC,00363F1CF6AC7A4B,C03142956F4984AF,577CE47E1C6A07CA,CB7D8EF4A07A69DE,FCECA0A05BE7FC61,1B08A08C75D45012,4E92B1BD57E2D2D9,A1F50F7C86B6AD3F,000F109FAD3A8817,42CA05F83C543C92,4F49382ED7AADF76,E83E247D1DC86BBA,040A84AEF3814D62,47F2B8ADA0E8332C,956CF807E67016FE,D6BC0BE6313ACBEB,0022033AF63C9216,A21DEA1C31D5678A,F68FB221D84FAF18,B2DC6453412D6C86,12AD9CAF0B75563A,5829E24D263052AF,FF3356CC2BEE5502,E39AF7E13AA7AC15,00262F5473381F4F,5CE0D791F123B705,47695F0E5F62706C,4983AE2C81E00C99,5D40C1FC3B17B529,79712FD77CE6E817,E99EBDA3AAB0079B,D43BD5A6C3A6C7D6,002CF3AC85E4F2CB,CE4E37251FF09922,4BC2499B8AFD8AF4,46DBF7FE7A3AC4F8,8EE5166E80084176,3869A9C098A6BA19,3D9FEFE62390ACC7,93D3E2A77D2E383A,00041349D571AE44,42C927961D3BAC25,917CB4C4855F8B30,80717FE7F0638480,B6A304D0DE5685D3,EFE78BBA24CBEB9F,362FAAE98AE24A0C,64A04645AAFD1DA6,001C836FBF1BBACE,A9CC2AF23972A0BB,B0EBBFB581934ACE,9BE8281ECD772FF5,1C10F7B1C74333AA,9971D86BF983998F,BE8D4B8CB6E4068D,5E872BE810B17EEB,00309388E47B4B40,EA29579C6D50300D,7C7A6D920427F197,D04B1123544760BD,9AA8236DDB3AA2CB,C7431DFC0AD2313A,5113A822527CBA43,F7F41924B4059878,00013D512E8A3250,E51CF302433C39F5,9C2CDC34BA24BEEF,48F634A9CF10F9C1,056020028606215F,1B8ABB3DC22D50FA,4924F8CC5C9139C0,D05E857B246998D9,00135C82551031EE,C3A1F21E1F8A0289,8A2C62B19B52D238,4507708EBA93FE95,2A3DCF1210652F41,A95CA0918C7FAFF1,BA4E1AD70C6133AC,70245647E5D4DAC1,00233DC23029586E,81A7C40F2D14235C,60569E20BFC6D329,B389496530F3FC08,D7A1D9C8DCD37FA2,070878AC8665C1A5,53510F56AE7DBEE4,984E2FA4AEE246C7,001FD35694FB8CDB,946D4A970AA8665D,49896DB3CD367D6C,0A0507EA7A757534,C82841B6FE90E0BD,146F83907F1BC03C,25910C34CF152BE5,2F3B3CDB4FDC7231,003AECB61E83F8B6,A2C43A4944EB876F,0F6058E78A0B953F,87FDC939683DBE36,4ADE198F8BA4FF4F,D9488A06F83DFDD2,CAE617B0C3B3C0F0,6FE54E9C1B202D09,000E286E3537B4F2,38BFC721CDDF132F,B0DDCBCB899945BA,62AB50C76844B209,F2597B48849098B4,E9AD85579596DEBB,92721950344AEBD9,5EBF195FABB4CD6F,000DAC7BE207110F,322FEB66AB952C2E,49FC3B3CE1E2ACB3,C6E27B0C67E7C8A2,E8268214ED511CF7,9C965281B9382D6F,6D4952BF94E7B575,D0C93C92449FABE6,00103CB75C515ADC,C1919E84033EAAC1,14B3C3397192F5E8,6A4429B151798EE1,5536056DA0143330,F6451898B93E3D83,62EFD5C8D77D69A2,22215C041DDC4F95,001260A12D47FEA7,1667FA7B1B03AAB4,CAAF3A7DB70E0601,F2D0E58893F8E85F,7DC8F4CB3358A19B,E2089CE59E0A7322,798900DBDB31DD6C,00923184B350F303,000CD129377B2ADE,5E9AE6C6BBF49A69,E7B9EDF506CF1106,12C6AB8A2A4589A3,0D5CB0FC9EF4A60E,5D8CFC8F0B5D6BD2,D41446B20D80A67C,B2462A9EF9029F46,002E0F65A60896DC,4B817F7B1EE19796,3B28FD0B88558ADA,7AF05E915E146C91,F2AE7359F737A362,44155A2C6556C06F,DA0C42767CFD8380,50FC3070E4EA5DAC,003C16AA7E3EAA03,3E52976357BBB6B5,D711B34FB6DC5E7E,C3078E41591D1A2B,21A71D6568599980,80CFE4E54FAB34EE,B5EA044B012EE3A2,A1CFF32FB89C8E10,003EE4A88211894F,F647BB0F5902B9E7,B8C950621979B009,C0B3023E3D51CDAC,5A2A055EC78B0F33,825B39FFC2D0A582,F8B67A9350BF3521,787D56D29200DB59,0003B21E9950F5EA,7DFB4441BD363DB2,B6E054FF129CB81F,0CA7B08271045BA5,E73290456F50FA98,BFD43F83AAEBA7BE,A4242F43AF329785,84C7346DA757E56C,0004F0DEF674B8B5,FD4EFFE8F087483B,DC404F63F686EC39,0CC9BF033DD46690,08F30A87E90E174C,BD9082C267D50439,A6C62D165CCEB0E1,CE2DF864B99715D2,00164F7312A240CE,68B15E701B66370D,DBFCB8B27A0A8E44,869FA19FA394C9ED,F4D0E724682A10CE,BCAB2A645D8510FE,A274E3BCC7D7B28D,4B732474A86BB349,001520E316BD4FB4,9FB96878747B67D9,1D3D853633C2E608,2A2DB40D10009C5F,CC9C0F39F513AC31,C10A6FD328D30579,1BA36FD27349E01B,D522BBE294F97F92,0014E880CC342568,11F3EB5CD93AD802,BEBE6B4E06143A25,E735A77D64F0C927,03D80BB34C4D0752,DA02EC8624627073,374695B74D8FF33E,D715705E2A8713BB,00206156A447003B,85C04A2D660F0498,D2A83146E08A6B15,73A2E94EF32AA9DB,71E120D13E2F1541,F9FB01A959027C52,32A6B67EDA01C63B,7E8F5E40D5EE0498,00273C3FB2724FB7,3D92A5C29A803C55,823175CF4457341E,77133DD566C6003F,0FAC1BF03F267A0B,C675D4AA444F69F1,216DF8FD364CE17E,E121CF13E1A97556,000E34823FFAECFB,4D5B4D404EDA6EE2,24227151AEEA0F76,999CDBC64DB201C2,125508989DCC3B87,0B9DF2A16000A315,049E3552163AD488,F9D4A913C49516AD,00084A8F18C5DAF9,BDDBFD843B32ED7A,00A42D8B1F638B2F,A1272016C83190DB,6DF22B0B4684D936,EE5AF8C7BDCAC7D9,1513E4C3AE46AD73,863C19A4CDF43B8E,0024DEFAB633FD3A,A36CEA31D7F301B6,CF66ACE6A6C818B9,E79FF0250E6EBE58,26CA74AFEBE3A1A3,8B8DC137387BEB34,62B87BC4BCC03652,C97A0D482386AA95,002E2179A926B858,A47CE195A3E76555,9B83DF0EF3AAF5B6,805681DF5089E2FC,6A06D2BA3D6830FB,792A96DA013B1795,EFEC3751F2E08F71,F9ECFE358DD50F4D,003D09E937986F4B,A4060D743FE52829,801573459341A3CB,6FFCA4EDD18374CB,88B543133FAE7537,19F110417AA009C9,6637A49346CEDBFC,F00E30F9122FF1E7,002B3BD1AFDADFE6,B46FE7A55493C6EB,825137311A62B54A,9762781E2369F11B,72EAA048C5D70C4C,AB26106B85A84D09,75207DD9998EA52A,2AC31984589D48B5,00079A05EBCA23D0,6A121B8717D02F3D,3C52A99E67CC43BB,C77FC87E3D123067,B02D682F5152A790,01995715C89D19E4,AA7BF76EF0039414,D7DC1ADE80BDEFF8,002CD5FFE43F8C40,BA3466859B66B9F8,36D093715BCE0E76,C744E624AE435F1D,B8938FB681D6A4DA,BB3BFA7F5BCA51EF,C6FEC577EB8DD803,E0D2F28AFBFC329C,002FDEBD2E5C7956,54B32A8CA490F84B,324E51B3F3500A32,B293A6500030D81B,D9D5B8F02F75F469,C75C168D0DF8E639,9883B081970339C8,19A67F0E6136120D,003D7B762D874945,F872029BF4F4A01C,DCAD32207F89BFFC,BDE0F7C1A768A602,4D332052DC048627,98F0EF3A9AF46F9F,7619C1DAE40ED6DE,6BFB9D56938DC4D9,000E63719BC8E819,7893AA2F6DC2669A,FB7C0A377D267534,F1C874607DCAF65B,AAA60AA2205E51CD,27F386616525E68E,5D119AA119130E61,F29D88BDA93E8841,000F5EBE171D20B1,C436F98330CDB5BB,D33531EA4BF89C63,E0BA8803715314E0,D2D3195E7E74CACD,3900A2BC3538A3ED,CC6901880194AD73,66E1CBBFA7F7458A,002D16C57C05E8F4,4E0C25D6E74D739F,B51A32933AF507A6,A90994F4B10831E0,A6B92678FAC76FE1,9D934F15CDF84089,14506EA79D0C76A5,58031B8BEEA0197F,0021FB4CBAA4A2D1,5BEEF420BCCAB585,ED8DE562B162E160,CA1566B802F269CC,FA0F1FC2906A9272,B37A3EFF83E63860,2CCA13A08E2CE9A4,7BFB7CCAD31D30B4,0033AD81371B92CB,C4CD18E92342B5CB,E20F9F7C029C997B,7F1986E936329000,F69BF13B89E6A873,0A49844B0A04C41C,2960E506F9403615,1564581185F7DDAA,002624B658C108C8,9A11401A59F19B4A,1E6354B4C65EB1ED,8763C0FE16EF0BAD,DB878529C0A91C6C,C96866FEF588BDF4,32E4B8ED493EACA8,847FC50093A6CAB3,00046D8688EB291D,617A7231719D9496,8B94BCA56CB42783,025E1EF3CE689214,B0FDBB53421A6E4A,CE402299F7CDC41F,44859C70442F61D6,1FDB9C9FB66CB457,003DEA4759B64B84,1C51EFF4C9D84261,B078A792F9B1327A,9A310BC11B957D4E,6DA1B8430702725D,C03F03DFA4F2050D,2B8C4A6D32C6F007,9AFEEF91F57F8663,0038EB1BFCAFF4BD,94963D3A0838D3AE,DFE003CA03EEA8FB,EE6AECA0711406EE,EC0C5FFE46BA0DE9,80BA6209C9A8FE17,BCBB6E8D7D45E365,99E83061B0C79EB2,00390895904F9A06,BA532894714518F3,90E1A05FFF804F1A,7834C13406D9F66E,AEEFEA2985B222CC,590A9AE96F788755,13767D9AAF933ABD,595185073120F05C,0026F9E3CE47CA5A,5331E094D146B247,55508A2DB90F3FF6,F2207B2308CBCBCE,C4135D8BE07F2868,C152F9CB345771F7,8D906300C76A83EE,D00A48A5ECB7C7A1,003AA539CB700912,7580DF37DB6066F9,70067BF6756A3C32,A5C97B78EAADCDE4,CC7130EEDB69A2FC,CD3D1CA6EC90D0A4,15AB110981DD86CF,9F09DD785B7F1894,001F708081B7A785,D0CF575E6747CB61,B3C0B1B9786A4DDB,72AD9456529C29A3,F96BECD6DD7A0E16,8A238ED98DE0FBC9,FF964781CD5FF07A,9513CF617B78AF32,00380EC0B1C333E9,DC174802FAE0071E,1836EBA86046C438,74BA16FA5BB4E451,60C880D6C9AB514E,769980880C3C83D0,581B1CEDEBB901F4,E64A34E7B4D209AD,003BB71228246106,1A8D765F659692B9,17095B5F052E39E6,B9E76D6C7E9B06FA,1B40269822C809B3,395255AA86B3CB0F,B583F2C12E001675,C7BDBF08BB323521,002D4E04268795D5,D8C961B22908D1D7,995E3120F3D385AD,AA401A387FDE33B3,DCC35176CEF2F5D5,55D0FD2AEB9798EE,67C4EC3B81F6474E,B3985E3222A5662F,003CC75765C3F979,846FE7A2D3863273,925597C060A9315A,F69ACF509F38B1BE,7F0E6E72E044ACB7,E05B66A1EFD1DA13,1FDA99F742AC1CB7,43C48D0430E66BB3,0033F528364D9B04,501D924A30ADA43F,DFE40C3A06BE24AE,F1EE2F6EB27711D3,B1E093F4072F18D4,698392764A1DE185,AA9BA69C6D080857,205D17AEEB82D65F,00341213DC07CA0E,1C8877242F358F22,55229F2E909F07FB,5DE8FA539C9DE630,76B0C18E38251BD1,54EFDC179074DA43,9E14A80E0962F2BE,7E9AF97F6452DBA1,0028E82DDB742821,C5BECC701A429E25,D58A3FD7FC3C4984,0D0D8BA9B35AFD5E,35F891E2EBD0E0F1,6CD9036F0BF3BF5C,8D6633FD285B6B57,9E6C115E893F995C,0035490B4F55114C,5582FBE0407F2DF5,DD287AE7692AA5F0,23704428F18EE7C3,82F57C3CDDE34913,DEE4E48A1B1AE052,230732550B3C6629,1C3515763340605C,001BA54EB635705F,3372B17C4CBECE68,75081F58D5207CCC,03AE5FCD4630C16C,5CD99E75DF2F801D,E9F3EC9C8A9D6794,625AFA26E03E10B6,A799F4AB61C9DD5D,00401FAEB652209E,89F4D1D9698625A5,36ECCCFCB40F313B,4C3D09D89553A693,3C731840701E6D27,2CEBFA4DA83A749F,61A5C6B7A9CC03D8,C9B51C5576BEB4D3,003DE57DB9C59331,7FB11FDEDD6C034E,5F18EEB333F81C97,F49D831594495728,36F715EBD755737F,94A40A38AAED07E4,4AC28AEE89882C06,3B45C99683ADBA27,001BE5C2F838557C,B00F04B8DBD56BE2,BF251B0BF4E7F7D9,8CCA7E80467C8200,4FD249C53C3E566C,3E70C16AC93B61F8,1F7933C04E9C02DD,C1509525D13DDA47,0037AB71A468B2DC,61107B37BF2986C7,23CC0FAB24DA5406,DAB6765697B62D2B,88523C2991A5780D,3FD0F421F3AD7D5F,8AF4424DC4EA92C7,164AC382AF6D989B,0010360E723BFEFE,EDECB11AC509CC50,754AD6DB16136AE3,6DE3539B04D4CC69,7D7A59956FFF225F,3C3686F51B94AEC1,87250EBCB93CC9FC,4D25AEA8171FA91F,0015ECA6AA8C3B4A,E57DF7A2A419BCED,62EE5C398DD0D4B8,B93D5B2DC201F8AA,0B818031B06656C8,633903C0E57912C4,CF42316359BFED17,023BC7820615784D,0013538B5C7D47A8,7088D9EB8DE0174E,81278757A35C2A95,D540C4B42ABB149C,6E98897C9B3B831B,3078C7BA0186FD1D,F97F2647EB5264E5,EDB0FDAFCB4C1A81,00161F114C3E6ACD,115C250DB7581950,48047BB8BC47F259,50DA6BABD6501B6C,9E481BFEF8571B7E,D69B91BCB493270C,FA8B9D4281D213CB,A26093BEB6CBE5D5,001403EE571BE8DE,0605E442D3A96BAE,DCD6FDB21C7F6A18,230F4FF5E6D654CE,AD5860DDB5FA6522,A762943866C4755F,E6448D10CC274A7A,059EFF45EA3262B3,003154DD14C06A25,900786C532E7512F,C4AAA19B0C898B76,FC607BBAA7B8BE6C,6490D560056FC46B,856B12FA822BAE4D,4B79893360DD23E8,D67458D9E44F5054,003C2C90E6212BAE,B88583135BF0B4D7,EED5C277A6D42E6B,D1888B99A4BCEDD1,3F9584A68481A3E2,6979A17D85F135D1,7D3E73CE75AC873C,DECE0B52993E74DA,0020AE6FC59A4FA3,77A60C50C2A13BE5,616CF63A851C0BB6,70ED42BB98AF3A51,CF921BAEB82E5CD5,64D7CCF876EF4F28,0702D6FB166FEF09,539F5E92E92B00F0,00351224150A4FE4,453E47CDC32F1A33,027422018730AB6A,57B9CA8A39D06B52,64C69B635A513A17,3ACF57C9DCB131CA,6B96EB6E0C05E543,00756A44AE3293C3,003E22503DB7C56D,B05508163CE28036,F22FE2C538ACD255,36E259A24D1F682E,63494E396BD6140A,0A95C38EE905EE4C,50FA91AE9FFFB553,AEDB8BDE48609BB9,0011360BE657A21C,480A3220B710C1CF,AA13E794A6F50F37,D878BA2151241EB7,7C5554F363859CBB,8BF801C32EADD939,2B2D6CBA85BCD2D7,041CB06C8A3CB491,0017C68DCEC5C873,885A2EE914437ECB,CE46626803F1728B,D3286F5A75458FF2,503FEBCBE14C920F,2C6325A2238BE1BD,0405EE73BE591273,1D37310E8CD91334,0019A706E7F69A78,A9A7DAAE5622A78A,95C22746DF4073E3,4432EE7C4829EBF4,27993C711E58A49C,E4E138C97AFE9CA9,5E03D5CD328C2B1B,2D52146A432AE2EA,000E6E6DFF84E1B8,A8C07030287E7E75,A92FF79EE9F543E6,861E42D439388822,D73F38EDFEB6A3F8,FB59CAE3290010C0,A67CEF402DF00532,CDA8594CDAEEBE37,0011FA1BD5F7BAC7,8431DFE6ED172A5B,04691D7024E77022,4C714D8F5B55E85C,24E438FA69AB61CA,AD865D228B4D4D18,EB9B5F769FC70A93,67FDF331036D5ED2,00283B75C1C3098E,5805A0D012B5383B,CD797A9E12E8B8FF,AF30E7E570E397C2,16F75CEC91F9AFE1,497090EAB7ED3E00,213CDFC84FC6FFC9,C0617AB1C67C1250,001EF56A7C452D89,72C3C9D5C9809DD0,8ED7827699F0BD81,7ADA795701E9CC4C,8108DAEB064924D2,CC9A68529EF4461E,14B6F3786023E3CC,94A8A7ACD930D685,0021B6F8168176DD,B82DE2B5FC499678,3AFE0E7632284C54,0A3684A969446845,1A41BFF224E53A68,AA163B2906ADA9A6,700FF1A60336E9AD,A00434C007001E28,002390B218E40D04,812C2DFD3938EA4D,E0D95A14A6577B3A,F657A507532BA399,59A427F5583F7CAC,5D6F1BFAEB10080E,90B12479064CD52F,262244FB25B387AE,0002B68B9D4059BA,8FD4B08B53282DE1,AED868E698BF8676,23F1D9259E8E2E92,8CE6593D555A2111,BDCF09991DC1B2F1,18780033AF9D62CD,AD738D5719D16652,00316077D0D2AA37,2347B0FA762E643B,A7F56FADF6E6D2B6,94A1C6D32D04AA36,A65BE02159CB2D4F,B956861139322F17,C082307B43377034,C54A25D547484617,0026877ACA131656,7002ECF8BC98B1AC,372C639F96009CC6,D424F4C2B9D4F892,BC1C8D0306790D31,4D89F1D43FA0570B,DC98700D576C02A9,30E303222879C65A,002CC7B750762BB3,BA7CEF918624769F,57BD092D02005ADF,79FF51B74CA4D868,5F13516E6415EC88,75BF15C6712FBCF0,F17C3819AC47941A,FDBF55B16A0006B5,000F3083C52F85FF,C09EA15BCFCAF9C1,19ECE3447019A212,21FDA2FF232A35F9,ED85C4B42A99FD5C,D61419AA777A3D6C,6F032854EE19E162,311DD7BD864E537D,000A88D4CAFF8A1E,494DE0848A3FF601,AF3090039CAA62F4,F5B7536AE0DE6052,5649B2B9DBF2DC5F,C4F9DF29B0963DCE,8583422E1D9B9E35,682611FB6217DC62,0019F0767934F26B,961A5B4874745584,F29BDC550C207C0E,981C9F8EF8D73F62,B40D5850FB118E34,E88469DBABBD06CF,E6D70C4A3FAE5AB2,FDB17F9AFF4CA798,0000559E43D93915,719EB0DDBA13912D,67597D31863A6124,95A9A0A2A6E3DB94,BD1D6EAE28BBA18A,7613586E97B12F3F,FD5770F493A50575,0C047333E62132C1,000E3134DE4570DD,379B57D9D3681CB2,B13A4B52045F5032,28D8ECD4BD297F64,1F8724E9A7C6145B,B4C05A980FE4EC41,DA85E397F80814F1,DAEEE38BDF0086DD,0038F79BEDBF84A8,B8942EE2C4BDE5B8,F0539BFC7E681C5A,2854287338BF3C56,51811ADF8EC11E08,F80D939DD06BF406,3C4D5753B4BC6649,56F9716E420D21CB,000115ED96B8A33D,93F2B913DCEE1629,4F33089E16CDD041,C2C1A6BF055F215B,7433D3C7431AA5F0,554B2A386E8705CC,75A0F037DD757576,6B2063613671CCCD,0018703927A1BBFA,489AC245E3347417,E174500565FDACF4,9D326CB931D06EAE,733B25692DA63ADA,C34CCFDFF7609193,F5A89B0FBD450DE2,76E6F92B4C074F2F,003FDA9F96714616,9996E01C2542DD38,343F2ABA84A94CF5,C1178C77EFFC619E,6324F92414E68134,A660CBDE7ECEBB9A,4433FF3C26E10C71,89ADD4DA8B2AD23A,00386D553D9AFBD6,3BFC8FBC2EE96B6C,E22466A4BD3E487A,F97F1BB6695CF96F,0CF823E75E44B07A,6A30784E92BA016D,368AECEBEDDC176B,3232E9B919C24D88,002294D1A38ED3BC,F890BFCC13F40E5A,206DF343F6562410,28AB5CF91BCD4AAC,8094BC8D827C3DE1,3B61C1CE37E7DD47,BEB03484BE8FB772,61CF1079CD0DA95A,002FBD845AB23067,CA1504AC00D75018,7CBD657E8D64A94D,E28DCED0D68AB20B,D5F55938CE5D2904,B58FD859F11976D9,149290FA20CC8BE7,871F9370A76EE20E,0027716DDDD9E70F,7C571CF52E19EE7B,E129D07314EFF8C9,B391B22B33524C30,6AAA712FC00FDC4B,0131A55ECA317295,45606A98B743DDD9,FFA51622048E18C0,000A98CD0C73C7D1,72EA9E94DB3B66E6,647D367F6A304044,6275496EF1942282,0B67FDBBD0CF2668,B51DDEC13E63C076,9EA2C2172E714583,9413628E94B9997B,001E33056D871BF9,266A6B8A100BBC35,249B98D67366EA06,1475B1EC1744E6FD,9E82DFB0ABEF3275,AC1922A5235AE039,A000408E81737412,0E10C3CDE20F6EAE,0010FC797F5D9919,7AFE4331EA180603,AAE3AF64A589D44E,C023E2EE13A4A926,1A4D043BD3A6DE3F,0C3A8A19CD309FE4,BC2F31ECCD7023C8,953233608EAFE7C5,002E82E48AE1C35A,2CA1E85D20A9D769,A123EFB021DEE0D4,45C12E09F4AAE343,24CB589CF22FA88C,AFD3B8B2B2E4B2A9,A43ACE62AA7F1721,74C63D5FD93A8FF1,001DB5DB93085CCF,D4E360ADE0E65423,E3179E3077377AF0,C5A26CFF11A15E67,559CB423B6C96D8A,EF9E04DA79EDD1E7,606FAD489FEF6D19,8E2E37889B9BB550,000B1A9D58AADEFA,9FF42436108B7678,240550F47FF5D5F1,C0E23F5FAA136922,4E0D27478FBD9B63,D13D1E78F9A519F4,9FF889DC7E990845,3F3A0A22A3B06123,003080621944C7BF,E1E81154CB845699,62A389D8135D0A3A,02BCD90F9C6799E8,2107520A3F248EE9,3BC41FC35824454D,C6E1FB6EB930DD88,FA10CCD5C0902018,0030B5C14EDD81BD,5C47F5A017476992,B27059E0BCE21BD3,FFEDB6502155F830,FB7B78F461F49722,1EA10D7C04FA3BB0,29727DAADAD11615,2A35F444E55A126F,0025427C3F3A5441,6D402C18F0FBC16F,66581A194E9AD089,866BCE9871916AC4,9EA66D8D8A83497A,3FCD564B72BEC85C,AEEDC3AC6FA29202,7598D3E250F6C80D,0030D574CBC778CD,CA1AA28FCBA31AD9,84635085223BDBB7,4D1873F6863221CA,664C056B2EBA3D6F,23229F8448CA462A,2F4EA36CE2D7C894,E0581D4A7C7FDF37,001DF3BC9C2D5D06,7A65C8E1B6B4383B,58D6D164EBE15895,FA492A82CB0110F8,9A4A548677C0F53B,3C6F9AC31E584B71,619AC832A5126224,FC2B89CF416A2E36,0024B23959091623,408F317DBEDA9027,4046548ADAD63335,F7BCADE9B0ABD4B9,1D650CE751EB4D16,16BB018E198573A0,F44D1E276384A523,D255B88CA1A52845,000B6ECA081D6898,8F47532E696D288B,E0EA4B7666777AF0,A14BFA3C7EB9A8C4,76C50A62E05BBAB3,AC596382DFE94F9F,65D4828BC9B915ED,B51AF2EA5D97AEE9,000EC5296EE001A5,75EFE48E180DF9CC,C8635FC24C58CC45,8AF2D087ABFE55CD,E94806C5EE187766,663F0FFB5812823C,B0FCE1254799C7B5,0646531F827F23BD,0040335E814A5433,21BCBDD144691E42,4FB40CC4A9BE6011,686CE10ABC6EAADB,26F60C144F31E63F,070E6C89A1A44233,C1F8C6D106CFFE27,80B71E05D43AFA42,00125E6D5D411A74,BEEABD030CB2CDBC,4B01CB573C265843,DDE47BAEF41FF94D,3AFCEFC6F2A23560,2981ACF6C16A532F,6259A337CC6B8673,3C15C024376DD9ED,0027269C1E44FA38,C4ACB50CB001A5D1,C563EB00DBCE5EE4,942DC115ED8DFD55,955696CE95F95099,21FB92A29EB24FE2,4DAFC9D1EFA9FC1A,488CE5046DBCBBD4,0037C209C99C4095,326E3F035BAC585D,2F92B1EB017E40BE,DAB635B2B51A2275,97F86A0BF7318FA7,86E36935B8A1FCF3,C126DA0297385DB5,097EBB33EBB3A107,003DC063B1A64177,27D24A247ADB21DA,4A6CA802B11FED11,09373CC5CFEB49EF,76DEE6C05F8C7B1F,C411BDA9B676F0BB,FD399AAB6E7A1033,F056074C18A49D51,00059893555BAE0E,EB7F96C904A7A6A3,3F54F6B25E3A313D,1E352B789D45D973,4B86F09B46A42526,B55678E118130691,580030098D84AD5E,13CF3D88E135973E,0015B808679B5292,15D495322F75327A,CCE3994457F4DE18,FC0B1C2F06E9E992,3A0D86D62945BB7C,EA38117072145D0E,391862042CE4BBA3,18339BE02CD2CC59,00050C3EB1E356A2,D6BD6B8A6A314869,E77345C8C1AD9301,571B3A74890D6ECC,348C7B2DA8F47485,B37BFEC606EDA6B3,BFAAAA4C431D8DCA,B15BF4C7386C7B2B,0020AD37749FE4EF,FACAEE76A425096E,0143CC1243E18DFD,520308171D6F36DB,2792874E08B3E09A,A71AE2C28707FE72,85D86FCE956D9D25,B12A566D5E4E950C,0007D528E447B373,A938A91779044D86,8E9E39A005290B9A,81B642B6B2F74D35,03B2FB2CB699D2CB,67D46FC6139B8560,82DB1BB8C51AC407,72D026FDB173911D,0024D0BFC93818C9,680E713114AC6B1E,1DFB633F013ABEBD,5A006796E6F5B8CF,77B100E429EA5BFC,0D745E04FF2949EA,CAC57B9E6EF1AEC9,F314DCFFD350A18A,0037879CEB85FFA9,7D3F976395DBD972,CEC69DD191DF4039,1982A1231D5911E6,E85C5F751AC4BBC1,D07CE08D6A21196D,B4B22B3E7CBBCA15,E85CDF94D06EC445,0007480140DFA271,5E310D81DBC9FD49,1E26761DC42C6699,0FAB73A8BDF0A42D,E7466B8D2351CD5B,F0C32657CD269ADE,F5DED15C82460CE3,D2C8201A02C95EF0,0026A65DB53E26B4,63F0EA9029E1466B,E47DEDAB5806F4CB,98D3C0BB94514451,F5E6C3D52A3B6A46,8B6B0D16BD76B48B,565185BAB2DB9AA6,1550BDBAA9D1E40A,0007679BD32BD684,96A94B6F7931CE3A,D60B03437F21EED4,5FBED02D1476BA72,DD4F44D82AD99D82,B9AC1F4F6F1C3200,3A2C86DF831111A2,D6C45BA7C74A29F5,00055BD486DC23FB,D14844634D13C205,1186DE2A5B55163F,8F27C39D934DB14F,B0C7103A8DF12C3A,CCE0ADC734E9BFEF,BE7FBB0D136ED9A1,5F11840F426C0BCE,00169B6D5C52E61B,A3EEC5475A16442E,D4F76F4FCECCCB95,52C9BB940F202F15,D667F8C0253C031F,2F337B06878DCDAE,A66CB9D9E10CE9B0,7F5FD9C50FBBEFF4,0034D48E54880400,760FC63B61358A11,87E57B0DB1BD1DD4,0A4B88F3545E96F4,8722BC70C988C095,B0925AB51719C871,560BBA84DD1B65A4,0C28F2A680DD2F1F,0038DF3E9452534C,19A12960A78EC441,113392C2D85C7BB8,B2C24E78B1986E94,872878B6CB4CD25B,B5D440E09A377679,22757828E617FDD3,72C1EF9F2135B19F,0034470222697C57,B09FDCBAE238BCF5,43FBCCFABF9DEE01,26EE653366BF33B7,36901B7BF25399CC,126013267DDE9BFD,0EBD19325C14A0C4,755FF9FC94CCB895,001AE83D4DB2C08E,1DB03C3FF9540679,934F5379BCF95D46,689DDBC5F6F80BAC,537DD86E5EB64CD8,547B5F1ABFEEB733,6D1022E900875DE2,22AA90462FAF244D,003E3EF5C942BBA2,2AE81EA359BD0B88,D399E62D307E7CCF,2780CE3F3DEA8901,91022AF6F7F0BB6D,F9C41FFE4ECBEBFF,DD34CAC4933C14E0,33172245FA91D172,0016BFCE1B07645B,11A9596F07A9A17C,FE1A4B34E1B2C94F,22F00EC804CD636B,65603007E9AE455F,9621D31DF13888B0,74950EAB9A37D0EA,8182DDABA62A9A3E,003618E7D6C5500A,89E98DE8A2CEA112,853DCFCBED9C70DB,1C5D5CCC6847BAF3,EDBA958FD4253A0F,C79197D1DC2A6CF6,5FED65C1D7B98D04,ECA62B20858AE8FA,000CC438470A234E,1B96428646698072,1E8F3E7BE66D9682,05D27C3BC928B480,C712A98C596F37CE,F3B30C6467B52B18,9021D8F7640A8157,1A312A74F39E579C,0022C44415E8F93A,7002F2F41305BB26,5E9B2EAB42B7A189,E780F9A3481C6976,707F03317289AB76,F4F4A9DA5919D596,ABB4191AE28C890F,C43D5405958164B7,002ECE0137D68A50,AD39FF037358F31E,52914447BCF707F4,4EBEA2646871191A,C744BB629882601A,5BAABF67358B0123,810C1C6189D447A2,1E4D0EFFADB7B36E,00336DAAB40D4655,3D5939473B9D04D4,FC7C410401198E60,98D6698702409614,26BE47D33ED21AB3,B62860E24A791277,E1F49828D568B432,F40A3D5EDCBCA7D9,00019907A459C411,6C08F8447CCE0333,41382690FF13011D,E178E0A0B4B57995,5DC526C1B23BA7E2,EC4EEA0D849BE173,FC0CCE9B07ED334F,10BE6EF0DD12506F,0020EFF6C775C712,D95D25E25B095DAE,F724CE798B77253B,BAC24AE77C406473,B85B3625610F34AE,D8DC67982B402484,802302F4B0D7CEAD,82DD48E815F80065,00165CE88CAB821E,C2ABBE5ECDB551F5,4115EF8BF6DF730B,A9C44B741686CB5B,AD299B2C9CC298E3,C4EB0FD0BE7EB069,39420E6603AE979A,CCCB9BAB766B0919,000B4D0884A262C6,232AFD703C366B56,9F8C9C962A049C3D,7F7D6B71C1400933,6D2E1BEBD3A7A71F,7106B2D3D56848CA,66001D2F03DFE792,11EC46FB362E2462,0016825F26E62048,CDCCEA2EF4C801C1,72BECDBA81CCA559,58D7DADDDEC55FB5,E279BF629E7AC9B7,E3E5574CE1FD9063,CDAFF7EB4D98E24C,2DA7A6427CD51E24,00310CC6288BBB10,CFE1A0F8403DDC64,376D564995713BB4,311F0C8D13CFB1F2,C362CBB136AFF282,FB9D1DFFE741278D,49853ECEBFC883A0,1E46B97A4E999628,002669D001C02AAB,F29A897EE5F6DDA4,0391F2C7C9F54917,8EE97E4C465A31FE,C8A64E2324B270C4,94DE0F0209AAAF0F,3B07AED3EF637752,AA647B28A41B56EA,000D25E8A082243B,91764A7FCB72F711,54DF61C771272A3D,676CB5F0795BA22B,083316D71E967ABB,74E347B2163DBFE7,A76A6665944D7D2B,49488F4F0CCA33E2,003C4C7891AF10C0,7FA2A74BF67E5AC2,5BE277364C772214,4B7EA3A2A2BF3A3C,24D42063E6B5F882,0E1F3158CE35209A,5448DEA6F87588F1,13421ED989E8522D,0006D37A3221466A,E49E953E79C0FF7A,73E29D59C07F01B8,458066343623FA80,B2ACA195F55E6D79,B76A6D222BBED85A,8C15C4F87FF69D3B,8E7F3C737CF51CF3,00380E5D7EA6D789,4DC7FF9452AF7CEB,28FA3E6E0EE4BF98,53D08EF6815469F0,DCE0F79A5C20DE54,A537F8FEFC48D98C,C402FA92E053A199,F1E5A923A46564B9,000B2DDF731DD7B7,DE9CF8D8CBB6CBAC,EB18E75673CE698C,7380E4286ADAEAC3,300AAD0D4876EADD,C023545A951BA058,431730F408C29671,0E744A9394D95024,0033D4CCC0B80F27,3647636DA34398B8,8F776125CABF824F,83CFFD087F24D4FB,E1DECA87FEA31C9C,19AD96F6115EC9AF,7A3B23085F6C31FB,E1EF4DF7BE0E0F14,0002A15864BA6EA7,95EB22833A71BCCF,80E6E511E6F31A4D,1A514CF1D383BCD3,5AC36F321D1ED4C7,4E595B3E60C75FE2,19CB8E5A74AC6009,7A421BAF419979CE,00240D393CD8FF9F,2406743101E6C9CC,6CD4A93342D9806B,503F7DEBA7A80EB7,B02990451D57CED4,D4307242E88709FE,A198B675E93AC786,C1751D84B946CF57,0008234DF2CBEF75,D3CC3DEC300D6829,D2C3C4117EA0A011,F4FF706645A08CEF,999573460B937165,03E85C79D0A967D0,7782752D8FB17E24,EB2CE89CF9032236,0038C5408358B466,C6CC07FC846CA4F0,D20111A89CB3FEE0,DE6244DE6BA7C565,13DAB4C88649316B,75202E8CE26A9877,2836E0C336CC518A,97BF657820E3C435,001E73662B56B521,DA4772A9B566FD7E,E5B492E0E54125E2,A9AA2D680EE032C0,BC69188C4584A99C,514EA8D1C43ABB3B,6E8F5FE10187CFCA,F45A79105F8BB303,002EFB1F6E8EB56E,FD795F144EFB39E6,2D23E36575F2EC57,4CBB8A76C51F2E76,31B5CEB3870D4544,255D1D17758470DA,D9A12B6A2992438E,CE117A04F4758927,002A502F5C41F8AA,7CFD3303098DC459,12D5DDE97047FCFE,DDFFE03A12CCF70B,7C5288E103AE5791,7A58E0D0A11C2712,76F75EFB6613FFB0,DF8CD411C21F6EE5,000F84B68324155E,CCADCC511EBBD21D,8AC1FA0E3AD758C6,AC6080AB622FC1E6,DC6AA890FAD99D7C,61E2CD2B457BF8D4,DC2C3BC58071DDEC,7EBBB67A9DEAE6F8,000D7C3EBEAA05E3,819D3131B6D5E372,BBA34CFA3E47888F,CA71D3907FF773BC,B67B238894AA23C5,E0C64D78B1DB43A7,D7951577AF813A3A,F1E7E5423ED3E631,00240586614B14A0,465E3D6DD34AE47C,9AB5FE59F2395694,D4E40CC17E1ED3F7,D39577B38CFF82C3,1F763A08B92CDABD,906023E317AB9FE4,0D3271F63FDB8809,000E377A1A5378EA,1FCD2BD159C8EF87,9FF03B1D63C39E51,1850445950CD67E9,09376BBF8EB285F4,6D5519715B93FE45,BAE09F28E0326867,3F7FE000EA86530D,002F38418E9C3C3E,595CA5C232A488B9,22F3DFB2F3966D76,2C616DF77B51151F,C64E6562E24AB54D,B97F335B58E533DE,5F539D32512D18F8,88C169A8FB11346C,003A5EF73227E0D8,6FEDA97E071C58B5,CF8B1404C2F02CB0,DA1D9F23C4A84047,9A25DA08160181DD,99B2A81033584D54,A9D1DEB4B6108762,91679EABF1E27EC0,002727A7F40A50C9,569EED5BF5669F14,2EDA30F1ED0D18E9,1365701727606278,09D29AF560DA6D7C,0468EE82206D41C2,5B67EAA4AE5B2D46,6394AEB5B32EDF36,0009E2EA9C966097,6A2132F5E1036CA2,79CA9A24A541DAB5,59F3226FB28196EC,B587C9FAE0E03FFD,4AE01866643169F9,D7BD8CA25DA424DF,F6F5AA5D40AAC2FE,00250A9E67886C22,04AFCE849D4569EE,E87F26B7A04F4D52,16BAB1BA5BB0590E,2766F5F72595746F,E680E8CE4A4F26AE,49527EA87EA72CB1,54E98458C00AB048,001C624F87F0ED19,4843CCB33D5A3733,FBF95DA05A6216D9,5B7D8A0442D87152,F659454E9D7D770D,9DFB11E1EDA9BA09,49D4DC240AFC4477,1621B6AD7009521A,00338565E2AE946F,DEA0CC502756B6A8,AD8269C7270A6F31,FC0432C77C63B877,FAFB6274DD653509,DCCDE246911E11D6,621CC607EC775EA4,BD7EC26F60BD8222,003C37E1E76A3C18,890294BB048BFCB1,AA08095987F8DED4,2C102EF706A1D8CF,6705B6CF218572C3,CE137686CA12509A,A6CA1C7D3DB1AF12,0E79F817EDD5B57A,0005D9B287A4B3BE,249E2BD0ED34B5BC,7B379941DD107B27,2BFC1C2BA485183B,ADD46D4541611061,A4FF4FD3AAC55011,2036871F8DD55412,C19695B2B12ABEC5,0028C0B56D3D7407,696C796BF0C286B6,36B97D561C4906BA,C460FF147EE05FAE,BA166095086F9FF5,E6AA2048F49E921E,B106C056A2BCB0B4,902D59807260510C,00209E9E77595485,CD58EBFF3D12B322,08F5C3B2797AD005,145987A86C6FA737,53B2872134ABCADD,1918F8EAEF805A28,58399F4C584C60C4,C8D6E556D3C74A35,002FF8CFD334BAB1,B9DF15FEFC4D6583,42DB07F5A157656C,05D030300922AD27,52599FA7A72E24C4,FF6CB40FB12AC4A4,C94EFD5E66AB6066,4C14F367E726CE6C,00049A5298578CB2,F59530E88F8ABDC2,F5046028D633E6D3,E5CE9234828AC28E,14A2AF11B623FED0,4BE925231F4B1110,A6924621C88DB8FF,0803EF74E73CF4BA,000DE1DF91DBF325,7C1302B82DDD9104,C1E66A79F41D5C31,A2A9B674EA1D9076,5E332A431B6DFE2B,03AE8AB0910D7AA3,F163930DA8BF6FA8,136E5C08ECD6EFC8,000A7D657A70AD7B,9B1017300B3E3774,1B4552DEEC30F8C3,81D97B89495BBA3B,FD60A938043484F1,A9D23B139D0851A6,BCC1C27C7B8FBE02,1E9F39183C5D8C72,0011AEF46F84245B,B3970B7B8C5CD0C7,DCA166AD70D45A86,2C151C1FEAFB9FE2,E7E271636AD24586,8BF246AF9EB5C652,DB9C26ADB06A0EF2,BDF472DC35C151B8,000AF0B809767F17,04874CA8E4B473DD,E88920068F82F2D8,19D1C2EAE3B52A06,0B8760C15C35B7DE,54333296B9D556C1,C2BF5FACB497BC8E,DC0AC3217E3B4F0F,001BD473BC15D54A,0FD1F7380DAE05A8,97AB99778903E99F,D5BA779586D34F7A,4B385DFB2728BA0A,14CAC421D238F9AE,E6582F01CCF812FA,F17B6A69C665F93B,003BBE0D356115B4,671E8951AC6B7580,1205E528AD7E74ED,C999B86E1B59521A,B52B2F9C7688A69C,D0B3C0BFE081C9EA,D580C3B23983D0D0,B12422F2E8ECA774,0037B5BC31BE886A,DA5EFA725EC6CA69,EAB49BF05A4D851F,8AA96AF9380235F9,C6A930F7EFE8ED20,2104692ECEFBCE87,525157F66D5EAF5B,1316235EFB9649C1,0025DDE98BCAB45F,82266F5CF41A44D0,D1FD341595965AAD,7701AC9170324D78,0EA373CABCAE6725,8B77FB52F77D4CBB,A4F77C38A388FB42,038E5A7497698A41,0032C8784E28DF10,6FDB8F9214C66F5A,0248F4983AE13E77,2C4C1258FE0BBA37,FF08F67A74209E05,67B8C65CE9EEE165,D3255831D64AE5F9,DB320CE6B8FEA07D,00177EFCCB1ADDDE,34A954A2F2287F48,0A4B9FB152D6F51A,F53552542CF3F2C2,5E9FFAB8DF356312,CBC84EDDD33B15A3,4F58C42B3D270F83,09122099DA5C39C2,002CBC0B0EF20340,4F9A8F53B94DF270,ABCF8F444E6B2210,A2053E47A762A482,5C28670A61BCA515,B0690FBDFC607D45,921691949F5472B6,5D74280819EF1A98,0016479C78C31811,0693D8DF1EB5D76B,2385C08BC9FC611C,8F564E6A5425098C,5C32921865C99B50,89169886FEF12F54,357387FE27CDE61C,5B8BCE23217F4B00,00012610285C413C,D79535E6A5A95D0E,1B6F13BAC7507426,2A4AC2D8915913FB,9FF0C92A3FA33D5F,32E3826139CC845B,3581D01AA595AD0C,7EBDEA41B49C563E,003F0F8E5DDE13B8,08FD5FBD3C6ADC27,E0FC13A438379939,A35064F498ED97ED,23AB1BF1EAEB44C2,CF7702B066AAEDB7,368D2727F985E3B8,3E675A04E7C8E584,002E5D54F95B269B,088E3882E87AD7F3,DB7A14ECDE825CBA,024320C9F1465925,FA333CAA95F5A18B,BE63295A47274FF3,20DD85237192981D,D9EE5D4D514E4738,003433720BDA426D,07005D982405CAD9,CCA36A0310F94785,1F8EAA7A148E8E4B,52FA5F192DA96423,B3EE4D06C64D0D8E,2B81A9D737E36F98,20A0D75781E9F3A0,003297EAFF1725D7,7355C92C9FB0D576,C0D66174F8C865E9,3941AF49E531E864,363DCEEEAFAEB2D1,C07DEC1ADF30417E,F9817568047A2762,6C9748AB3D1B5EA5,00092EAB9681EC55,9E56B573DD5E0F01,EF9312533128C7E5,E22C7072012CCA79,65C356BA1287061C,3E0E91E2F4CD7A1F,749276263D306AB1,08E78806BABC792E,00240A7871792CD1,51296D5FEE00067A,82109AD75A561ADC,0DC59E839E353A2E,A31AAF2A32DF75E1,66DAA5B043BC9327,A4999677F6599D5C,831A4C4FD070B2FD,002FD25EFDA1CA15,8BBDB38125AC1BC3,CBF86E421DE98988,D2808150FFE6BA29,E45D970D4F1AA172,F96825A5507560E2,922F8F874AA27F83,2692B6E9FAD79321,003B3D05E609FCB4,57A51E92F510A13A,F7A9C1A82E754087,C7303505EA39B35D,6FBC60B3FF48CDA9,A66E885A56076ACC,D0C8D81E32DE24FA,448042F1A193A7BE,00345A27E9B52656,61041E5485F5BE79,B10DF164F0E30E26,03C08E2793499350,2229A49668849314,F094EDF847496EA6,99F840676BD81A23,A33B9768D81D2962,00304E4B8F628582,93EB8120FCE42EE8,48FC53C0FDB34FF2,A46F9C6F6BB530BA,AB7326CF15B4E740,A92614AA10B11B5A,A2CB50FB3B7FA51D,5F229CC94A872EE8,0036F6172EEAA75D,AFD152E067796FBB,5FA2AB4379AF9FD2,3A6FA86B3B999897,11C06C53E601F7FE,0339E9B15BAC57AD,58F65AC0FCCA71E5,C2E380918BD7FEA9,0014BA5C1BEBE2C0,BD24E7193A7B3FB7,899C1E8153AF118E,0253A90E5BD51830,EAB4BC7F1B8E083D,5CCB609EC85D153E,483E023605D4EF23,6AF15E81CBAB276F,0038F2A0E5C70B5C,6B30BD587F1552CF,871F8A8EE79994D2,307F806914C0A5D3,A97D0B869105FCAF,EA364BD8771C400F,F79FA1A2E0A91A38,3AFB83CFA9BA9A9A,001DD0CC0F5ACF29,D7243354C79A2D91,B8BF4C35B540C4EA,AE33D4C7C0514D77,72C8D10320CD1676,2162E81A7CFA8EF8,474E32FC2AADEBE4,9E4A5BC2C4C4D9CC,000692909BA2CE43,264AC43C59AE09A6,42808F164D04A479,D1E2692BB48817FE,B9E85B350D1FC604,0D884F9D324858BE,A44AE53CBBF82F8A,AF183A15DE8771A8,000EEC5D297DC82D,3E7F1194DE9902FC,BD0E848683DFC36B,7D81A9F3DC31BEB5,DF738FB4885AB96A,9F8F9EE7478873F3,1D35F6352C4C63C2,5FEA383F6455D3AC,00133607576E0472,B60B64944BDA3BFA,AC4C07730361A094,60351D2D3D11E5BF,0191B2CBB2A2CB1E,0F979472C9EA43E7,A0171AE1D5F8F207,AFC839AA2E425249,0036761E06D7B274,3449C0900F977283,24912849465487B8,627778F446F7E3E8,880008A5E95F9F5C,BCBE2ADE4DFC0B32,4FEA386C27A93DA4,EF212A71244F2A71,002C99931043050E,24B223DF4A61F528,AA69989CC8C36201,07168D96429D34C6,A68C59AC97499CF8,5455800C1FDE5F3C,FDBC1D881B28B306,E1BEBB0E2A525644,00063151AA6DFD5A,F014727F662879DD,09E5E97508ED257B,8D25FBECBCE3992E,592B08D07C60BECE,F4D15E07CC8D0502,38867A82FDD3623D,972B71B4E28180A2,000F9E90EA40AFD0,53AC601ACD3FF43B,F4CE84DAD99AA092,62967016C0B2990C,4F8E311DC1A67967,EB596382F824AC15,78C18BBF6A032830,13E5A7655D59DB8D,001C59C67D97D767,89B83A772AC04CA0,16700ECE70E11F63,0D2FE546C155EB24,79E690301D6A84F6,0B4A48BB5ACBFE29,135CC40F3A051528,9EA8585BCC2EC45B,001F24742414C5ED,0DCE81D5C773A69B,45F0AECE59A24DCC,F913D4C5092C8935,8494665C548B23AD,A409CB0D3CE08C1B,3D7BE1104135971C,48F60FB602FCF105,000D137A53584316,66B7A7B59CED1638,BE9E7A0E32043E7E,D8F4E6EE9E700FCA,75F0DAA36323FDA9,0316516CEA29ACDC,7A145B4B19B4CA6B,F79A789E2901154C,003B0BC3E81BD47D,B6678F7FC6528D2A,00E1E8B2CA1B61E9,501579506382A8BF,AD15857D4877FA99,586084A7AC8AF405,B7CE903BB8B3E9E3,696E06034473AC75,000E50E38B4F3012,EA1882AE3BF7DC2D,62D01485112621D4,966FAE0BD0A05B91,937A45A5F6A3525F,9C7D8C360C9CA275,9DC9C64800280C08,658EE4643C331E75,0038B6F6F3991976,DAD56DB101CF6725,A04EF9E64F35A583,54FA0F52AB78D2C1,3F74F52D93869BF5,623E938534B539B9,53AA92770064A611,EAE66CB8AF26B31D,003756819D50EF90,4F86151943C84B53,55E8C7B947301812,A1662CAF4751A35B,028DB9E0C81EAE5B,8FA442017AFFC1A5,60714345C65D1A80,27BB42D2B1D902F6,000E55E28CDD9631,773329FEAC656D03,48EF057AAD14B837,CCCED68034479C0C,940D8AC9B4EE3343,69361F9AC304E392,95CE16EABFA38C05,E72DD59BBB68785C,003F67037A2338F9,F8C90514977619D3,147270CD29DE4438,604B0BA9409447D6,814A209FB5FFF970,D9FB7077355FF9F4,4FEA22760E317648,5E5D62F5F84ECBFE,000731DD19D14936,2127FC002F42C36B,19A60DDB6141F45B,92DFF004D19D2704,0ABDDC201BC052CE,8F581EC869455EB4,AA85B88BBCB9A771,174CF89F79D94796,001204E57F80F0A4,F7C99A7CC18A5F88,9EFC6A3AA23F65C8,419EBA759B24F48A,5385E79EB74F2C08,1C7BFCE800B40233,83FA3E267831F8F4,96408314BC7DC448,0025EBBC69F5AA91,78791118491B536F,296B623176270966,ECF8E4EB65E8B258,894A988777815069,2ECBC000BB123CD8,DBBBD7779D4A9E2A,11F47666E34EE74D,002DFB4C86C9E486,392704E6001E1B8C,89C16909EAF14B20,87E07BFD3AEDC608,C146C848CE662749,EE44331014287F85,3F0BC155FF0DE668,597452792138C89D,00202692985AD962,24CA407FA06E99B3,6848F24EEA15D706,F55CE6605BC5028E,192F4C64A5534193,39B451703495056D,B1E142994D78C586,9B3E02B39C9A11C4,00327E98BA6CB511,61165FBD6313613B,03310CB9696E003B,5752667BF2AA1B21,3945D0DB94BA41BE,131D408BCB4B8039,DB1B1E5B5A267018,88416F77504DCFAE,002EC987505A741D,58F8D0604750A643,A43935E4F3848190,BD9C1AD6128C8370,04407CA2B228C893,43B8991D52D4CE84,76081B6DFC702CF5,B213D19A8BFE9B59,001647BB251B80FA,3598EAFF3B7CDDA2,B544DED1A0CD5469,DC5812C0C9B1E2ED,FD0F919BA08B14D9,17A80D19BF896611,1A6387C45472E45C,8BEA8109A5468872,0016EC3B97702782,E519C96828E40D4E,4922BA6DA3195A6B,CBAE9DA817264446,B29498560CF65E31,27FC5A4947E574D8,3C43CB8F7894B9BA,B4667C1D8609CD0A,003765DAC57818E4,E053CDA833D23F94,13BE33C0342EA42A,ECC78F4F7CF0E020,B71893C45B202BF1,3AA70B2CDCF0879A,4021E00942A37146,858F0F66E8D519BC,0016CF65CF8E9FC5,D3E4B8D322074CA2,F002275F01CE8C27,D4F9CA4DF407A0FE,3A655F0DEDD252FB,F112E8FC0B86B9D7,2B04E0552815CDFA,9A1EADB3DA0DB143,0002EFE296CFFB0E,F817ED8F1AFAD4DA,C6A460EDD089314C,F770D831A643B377,4956E949AA9C33F4,0965FF3DF7D37CAE,DCB66414CC93022E,B61CA22FC4B1A181,003511211571D69D,6C7B8FDE009C19F1,A5C4D0F73B324653,D1F4B04E5122F6F4,5F771D49B9D51A80,9B62FE4D7B518225,B8E5D8AB6718E795,9772191E57E602B6,001736209A47CE60,50BD3317118586A2,606F1FE1D48C1186,79D1E0FEB788458C,2634DA29C3F77EBE,E631544FA9156FFD,D5E36E6E571B764A,F2BEE5FCA31D25F9,0017B349B6EA227F,57F2852E9D72EF6B,AC9F92099DF763FE,A90DB29F9BB570CD,4ACE550953E14AF3,84E36ECEB09F6ED3,2122620AA0F2AC67,13FC90E873BBDCBF,002B14870169B39D,9C8808811143DBC8,CD90D51A81396A0E,700FA35F8445C9DA,F650434802A2C806,61472BAF071F1ADC,EEFB85ECA7A28993,F23CFE97F36E5976,0015DA36FA072960,50BA1D55952AA700,EEEC6A9C229C162E,3137499168890555,5FD5750FCA76C1C5,8ED067BB2F225061,F46A058E6E82E6EE,FD9F29EEEF613B55,000ABB30B3C1F977,FED1820D677DA2C5,F74DD0DB5FE7F120,B72C06B84D7C2414,9D1B76E02C439C50,432D7DABF1036030,9132272CCD93E32F,BB1CBFC62CAA5432,00090CB564E0ED68,4B469EFAFA5402F5,D940D02A5F9BE69D,94B63CA18D2D0E1B,469794A39E905C8E,7035A75846DF3F35,A267423A28942DB4,32D517BCF1412B78,0006CA3CA5FAA99F,02A7457D96CFCED3,792106A2861B1251,CDCEA5CCA07E5D15,6AB32EE9B2C68BF2,64C35D06BED728EC,C8745A9E6A4C13E6,1C9D22244B52E022,0009BA59DFC4A40F,DD01B95B3D7BDC0A,D4D31A33C6B3CCCB,4D5BDC63B967AC16,147983EC18A323B0,6001EB812DFADA01,4AE93523B8C0DF20,AB49CD9546FC5C35,002A39D3FD297E4A,EA58124FE50CDA11,88C6F0D86A63A45A,934A6E20B2FF4E58,C0AE6825497411C9,5AE61718C45A12C8,65C3C25216DD60FB,24BF3E189D31957C,0019D094F5A3C747,7E665653DB43E009,FA8FFFB914C34167,9D37FA99EC8B3B41,D2D8EB8A8D574391,64EB5CB0B8FB9027,BA45B38813114493,F33693A6BCDC35E7,00099000C10C57A0,1195680806424ED9,30061A4E4784A4F4,EA5461237FBD7185,C23B95B3F6A1F902,65A052A94131C7C2,103037988E81E934,8B7ACE175E33959D,00226F24C72B8755,2B15089E68E7943F,483E26FF07D912B2,E59132EBDFB73749,918F7D4ABA59F7FF,8D2A6D9CDA920B6A,4C3AF59F28555EE1,740FEE910DB312A9,002F067561499E5F,A67717B455A9730E,8F1FA1892A572D14,A09B196F6E21A24F,0A7A942EA636A340,954EC5319D9DD0FA,7686ACAD7BAC080A,24B622D56ABDBBF0,00067B1207DD99CB,CE3B148FAA6325A2,8463D98FA06E548B,6B29C7ADA57F045A,0E9963CB8B905E56,8424B1E77952E0D3,35909D2251422FF5,0D89273FB667B4E1,0037D65D8188B709,CB11D983338A67CE,5A73257A83C505B3,020A96EB115A801D,151BCCB766F0F45F,D9E6712CE74BF8BA,63DBC109068FA830,C9C6CEE54C497396,00131FFD2D4E048A,94BFE43D4448810F,40886484825A5AAE,B0FFFBC4494E88A1,4186BFFB3E195ABA,D0B0BB45F2E886EB,8D74ED5E64BC81FC,AB0CCEFF112D8A05,00225838176E695B,3FDBBA5F6D8EFD75,63E7BE41F235114F,43661AE0B6C6379D,83717F80E36B45F9,4FC375CF9E8FD4B3,9BD9B26563192AC9,079308A58840CAD0,0003BAB977F1CDDA,70653406C7859E32,3DE3DA3D09E0FE09,072643D0DB57A014,88B4834CDAFAAD35,3FCE7B65CFDD5518,6F8AF3A5A8997E0D,B6EC52D59BE5B259,003F9B2DD76106F0,AB27DAF325A2E0D9,6B29CEC8E5967A5C,68E51A3470DD41FE,30E64CEF64B61B6B,52EBE1ADE32B612B,78686ABB89AF1440,A14E4CBFDE904B42,002F5DC698F25A3E,30336513719B3112,8CCCDDE3499A6904,7835CF66F1C57480,7A4222FD1ADC48D7,68EEA52F30171E9B,5925CA38767B3BF4,2A2EB9760EA1F28A,003C4676350ED38B,7473A7C840DB5F0D,BA92A560D4561880,2C5EEEBDE46DC22D,FF0B4C7E8C2F8866,06F63E3A0D15EFE7,3CE97716B8AB1B5F,3582B88612484FF2,00173D436CEA81BE,C4B167A124E7C74F,DE9803032AF34602,A970A3D9B48B6D93,502C1B1C546CA26B,538D1A9B55DB119E,205396EA0677588F,D89DA210731210CD,002CED433832150F,8293D302E60EA1A6,BAF520DA6DDE712F,3C20E6A18B06B8A7,F643162B367783A9,AC04C8353E5FFA56,BA2297792101890C,9A8330FF4F7259F5,00278254F733787E,677D624B44E266D3,4B8036D6A3B3546F,03653500CB50EC4F,1ACE2BE1087ED0A4,B02D6340CDD98795,0A935321C221F762,0C96A3995E106B20,002108E4CF0F674E,B97CABFFF2043BC2,2B7992376F86BF54,87E4EC8F26558D1A,08659023428AC9C5,DE924F3CCE79F4DF,6034494001762263,425F37195C655F16,00160A923353B7FC,4A97698926BD36CC,66A659CA0D031A38,226B59952F7D92CE,DD200590E0AD3AB7,D2DDA9B6030B6AB1,CD8327C8EC7735EC,87A93B59EC666367,000CFF4688381957,5F33B0DE697D7F30,D1D86D38972C3397,B8CE2EF32E7289BF,19BCDC1A105AF41E,97B719098D9B8326,7B41F889236EAB39,2BAE7403836D0D82,000F7117D4335A34,44496C62A831C85C,42CE6653F3A7B9FE,09BA339F8BB99331,F59EE730B8164F10,D9ED940C8195E4A5,46B49EBBE3345BC8,CDA0893D2F28A3D8,0020AF44033011F3,320A46CA92D56715,92760DB3330341CC,54C42D5FB50DCFDD,121B7E518D329501,A6E5CF494D4B5E16,841FFABFDABE091F,99E367A8F97673B2,00187E06FFA68885,2BE7C16CFA56CC39,BD0A3F7972D5D48D,2965B71DB1D79DFF,6CABCC0E3B84BE46,20EFDC9E8EA3D093,4431CC12E6D5155F,48E69EC3345848B6,0031C33433D6FF60,6FD71754F1A15508,597671961CB8BFD1,D03E56665658A0BD,5840220D04528ED6,483E84A8DD237C07,13CE9CCEFB22F164,6806B0B391BA6375,0005B6008B0FBFD1,8B6AFE6EA687E121,6F661EADA81F2AB4,A9645F11DF477FD7,579DDED123D08362,F9053D5280235A2E,ED5126E32292E77A,EC8CAE498FAF0348,000075C764CB6EE2,20ACF772D7578BA8,818D4F8D1DDC830C,76BECDB8F2035207,60B2D71B6BA40307,7313C00AB7AF00F9,47761C64B14D7860,EC76B08CE7E77373,003C8D60DC04E63B,20906D79CE33CD99,BB53B087271587E3,6F16A5AADE3B8C30,B66BB2CFB7962826,106A237B03825128,6E5E9CB20E15410B,8E5BEFB1236FC9A9,003C87E5D9132039,8F9A512FFC4180EE,83363799B05B8674,72CDC05475D24798,F3566F2BB57916FE,73F326696865B3CE,1293DD585F2CB7AD,271C81FFD9B3C40B,003EFB9D4ADB2D56,E0ACCBF1D2F0EC47,88D2E5DF4A6877F0,6C30B72BC563DF2E,4F40E1D9678BA1ED,14DCAFFC9DEA3676,464C0B4648820933,0EC615A808452FB2,003241AA3A3AEFBF,C283188BBDD5C158,8535C5AEDDD535D1,9A5EB5E88062E075,AA4AF4F8C45C2135,491122EEB1E2409C,D360DC770496F73E,80AFC8C487658FF3,003371053A0CC195,308EBBB19371BA5B,3B74AC8209928ACD,D9B7BC7A9CDE11DF,3F582FAE24FCC38B,267FB6A69D8E2956,BDF41941092E5828,EB5C9DCCE2A58EA3,001F8E83FE1BC79D,2628C3654A9FA9AD,FE628CF26719358B,D5B284D0B7668B30,2AD930A0FBD43E64,F3886341C022FA17,AD8F0449C57757BA,BB466A4239BD3D0B,00094017CC68FF01,E644AFBE3FE34FF1,66236DB488C31F0B,B7806176D41ABE68,30D6F9B3C5F77F20,BF700DADB62F6E59,55D45F13EAB87EED,24802216314EDED6,0035F1B0CEC08703,3800FEB022522261,FBD790D3B43DF915,FCBB7C6D686A9DF3,47AC7116FB50DAD2,360CC523B9BB5C02,86C7386DBCA856F6,CBD4645FA3CD03DC,000E982DDDB4E020,78756BA1AB649726,C88823C085F9466C,D15B8389322711E2,69D185B07E2144D9,A51919CC3D4B5D24,EBB4295B566E5980,2F374767494E88C7,00373C91C8E1ED45,F36E958DD279D3BF,0569820C8FE828D8,095F33B5800524AD,D77F4E3243A37195,15881D0C159833F8,D33A466B8D63350B,F215C886C2C96E26,0023E9F524C6F786,6EEE282A201D6879,FE8159CF168C41A9,C2736E58AB760DF3,BCDC6AF5E87B0AEE,8D2790A35A0AABD2,3D9F142C17004BB4,AB68AC8BA7D74427,00097F125608E93C,7BA98B9E3BA11F5B,0CCE7CB44D204976,F9D50CCCEB8859DC,B0FD5FD8B2160D5A,BFB395A0B7C45488,FEEBBE26F8D758D6,A2AB133CB256E083,002248188136FA82,2595A22A7BA14006,B7323DE82C7DC647,EAEEBE2CF392B45A,D53FB88CD5AC12E1,07DF6445D1178301,DFC85269596DA51A,5C894660B4BC1C8E,003B931EF0E286B2,417D1BBB3AE0C54E,7301FE9493194F87,42C5063BDE6D2232,09A20BC407997B8F,9566A1011161159F,428B292A615BBD16,02C18E1CC6DF9E79,00272E5DE67FE3F3,8F1310D8FC64B989,AA3E88CBCC7DA844,730E7D29BF0F47DD,FA50E5117B090520,EF2DB5026F71F4CB,6D7E9C198C991320,5754B0C34C5192BA,0003B9675B693692,9218AC87B0A64569,28916CD4215073C2,4F8F37F43190D226,9D44E715965470AA,539F741023BE0255,E7DC75FC5240A2D7,CDD260930F3AC567,00231F62939B6209,F8824C68AFEE27C8,8A00436622D9B795,999056A06CB9D529,ABF31AE13B6FD880,41EDA3AC583B6E64,DB9BC8D629DC8E03,106D62E8730A45C2,0017059A9785C277,34935498A4458109,2AFE2A460600877F,152A299453851F7F,BB4574D10AC6AC70,3D19530099047AC5,849AA79C4E8A3EEE,94D783EFBDFFB1E7,000C57D749994FB7,A2EA5663552F3FCD,F286BFEB2B07F705,4D7824221A26B75F,12CC10108D266E08,F83F7DBFE9D31704,9189E925B6931E5F,1C9F98F7567B1C20,002B81061F30BBF2,0FBD40A4840516DB,EC77557855543DC5,781E05A2DB01F806,535DEB79AAF294CE,771B292452C9E7AB,FF4E0F61DEF19DD1,77B2CE7DB1CAA514,002FB9FF0FE66E1E,C5491AD083D0C7A7,766DAF668E9E07A2,05E33372DD767F20,1AA4E3ECA7EC7FDA,ED866283825AB459,C328EE21B26AE246,7A8666C2927AF9B3,001B1B4C3671ECF5,CF0936F85F47554D,2EFCC4E027BC4E64,F3793E9C804D6F62,966F4216B016C359,AF7127C7AF6ECF0B,56849548C69C0277,749145681381C887,000BA2AC0A33C5DF,0F99B091F9CE2A74,155F4A7EF67A0277,60D955AF7530B611,C5E1193E686593A2,F79F78D6091F131A,8D2C7F61CDECDDA5,C6777ABDB93AD973,0023CCBA961225BA,AE5221A045D9D111,883C3852A89C74B2,D20E9005B444459A,2C918202A28DD13D,79B26513F7C46DF3,3DA56E707C7785DF,F295C6F3D2768C19,003694682EC6D55C,7BC2BC774C5F9942,D384713D7637DAE3,392D22083162982A,3936073DB31928FF,BB81835AC8D8DE4E,30F3D25F475362F0,14DF0D7BEEC8576F,002BDD2994A47D57,1A1DB8BE9032EA6C,166BFD79E4371C94,BAD8717845938E2D,7DD6F6A3E8511E62,8E5C7A982C60C14D,669561B511FBC4D9,0E2CB474F3CE02F8,0008A481C4523476,E42795444F8DDEE5,F1E3FD3BF71AE794,E1DC120E2432500F,C349D813A1CA5215,F1DC46D7986DD799,29B01463782A95F9,B218C031B99A8135,003238278D659558,3BFF95D8EE85D927,3B7365C30568433E,DA59319D3C9E0E39,F644EBB0E44B3D38,5F1F29F1AA33B136,722D26A1EA316AB0,E4097FB2ABAA3F3D,00346F42C67F2995,31EC9101BF165B63,A7A18B30977A8D0E,2D6185D1BF2C4A33,942E6C3479607768,24BA2303A75677A5,8AC554DF0E5FDD92,363B0707C75F244D,00223C5B6091AB3A,677B4116F57FEFA9,C8C160FF81747DCC,A4B8027E021FD433,4777C88CD2A3031F,58DBB603B5C5F3EC,FB49B437B36D5E56,96BBF10689D00F8B,0021D9A8C2E5DA76,F654638D8D5F0F4D,75DD93CE29CB2C05,6171ACE1C3D59D8F,F63ED24F12ACC16D,A5A239413DF3A62B,23E8DA1BA4C28349,A2B94AC66DF1FFDB,000ADBB03D3EA13D,F51E02C55DB5A305,C221C36E8D0171EF,061B4C45B32D543E,371A9ADAB5016912,3D38636F2131F08F,8A0BB82377DF6990,7545357C17EC4E5F,0008EE1C205B11DD,D11E5A34F99B00D2,7531D2FB5D14166D,93AB1A07EA28F23B,D6FC13BD099B3CCB,BD34FA82AF95CAE9,9C923D797B54DA92,AA2D2F771247E793,002C0FE277B3340A,F432A15712F7FCE6,F56D93AABD6DE7FB,9B75C40A470922B3,7437B1F80749A3DA,8C4C34A84B60A4DE,99D81F47E8AA76F3,3E51FCDCFFF7C861,0019A1E46220B240,D2BDF5933E567D3C,89C2BACE2AD6A250,395814DD71174F43,E606339015397354,5809BB4927A3BF58,DC7AAF730EAE3527,EC26A65363131183,000571CF97040F65,044CCBCA8A8BD941,8071BEDCB8767FA2,CFF233D638FEBA32,2E0A65D19E5C59B6,D836837760DF0EEA,FE86F0A15B2D43EE,177985D54588D989,0024C8741FC978E2,DC291CCDE8959817,73DDD377271A16BA,F7A11CD3E58F36D2,983BEA529F503E28,B387BA6C6DC3B367,F529C17D998F25BA,BE371BA6350489AD,0029C0ADB6875996,03FD0DF92A5A0D9B,9005FD1D9B58AECB,246FCA4710E5AF9E,743230287FEB79C4,F059231AE3FB6E15,CF20462A8185E895,7DB1F01DBED26273,000F2DA12CEACE97,662640090A1CE97F,4F90D655481C74D0,C69861F19237AB12,7FEC33F882373908,D5CAE86B6F6887E5,4E612B3E9CDA3A59,2017AD39A56532C8,001F9C794589171F,4934F881EB5BC0DE,A32963EF36CB52FA,50DF84B2EFBD7CFE,77E120DD4A3305A3,A5BB76E86C250749,597F5E4EA8D7C0CE,2B63F917360918B3,0001BCAD5723FFE8,DBA45E579CFE255D,5E171C27DFD26C0D,EA93686281B33E96,B13478438E428385,87CEC25368FFBB0A,980420C1CD9CC031,5ACA9575563BC1AC,001537A16F5A8DC7,23CFA6FF8BFE04D4,D5D9A839AB716E28,FF270BBE80FB7BCB,121E8AF1B951E858,C3312C6283EE0D58,9624174756E243BA,B36DBB46C67A697C,0033C089E846EA03,3162176823E3E4A2,3A83009C161B8F01,37DCA1996574EEBC,70DFAAA7FBC5A18A,5A105710D1417D11,5770E84864796F95,C77D61024F1E2905,0026D3209263FA4F,60D3C2BDE1D09DE9,4615CEB6472D95FA,50D4CC9FF589065F,9F0DA988C9110B1B,89ED6C739DB33004,49AFA7FA9F7BFE81,BCE32641C0B7EF7C,001FDDAF66E84F92,97EB579463B282A2,AAB47C66BD69822A,0328BEBAD0109DB8,B85165C507205557,1D66D7EC3357D7AF,BC9F7DC219920FAB,B6593E8793E8AA03,000639598137D3FE,8E37E22771DDE99A,846BE2698D5F5E20,7F6CDD246C12A390,48E3546E517E6FB9,E7A5D49D9A551E74,0895F2BC010BEF00,37C1CE86CA24BA9B,00209A14D2B48908,4209EC2872F3D5FA,2531FBD4284CBD32,43FCB67CCEC7F764,C9E9079521F3BEAC,FB0BB794DBA971D7,E179DF141F3B10BB,57E375E659BCE372,00347BBA4D62DB9A,BBC014DF0E1251AC,46ED3A8DD0ACAEAF,43CA005C28E8F786,72056E5F5B397DE4,AA08FA5F555C33C9,CE2E31DDF029C944,3247AA4ECD763676,000639EAE9C8464F,9160E1F38F354B21,48591F5B81D9BC6A,73E1C5D19BFB01FD,1A4F3E644B93FF2F,CFE9CF20940ABA37,A1C90B5A2C07880D,736CF2320AF28134,0029C0404F909D38,609DD2D7862A71B2,DE17F37455B4BCCE,5CBA2A07482FA328,BBCDDE4E129231EB,3A0A4538BFDABDEE,4836FF340DC0200A,C1EB43AF33CE3360,0001E1026C1A5669,C3833BDB9485558B,30584860D3BA47C2,045AD4EA861531E4,18AC5909B0DE261F,A3F0533424BCA57A,9D99DA5BCD37557E,B09DCB64B5555593,0032EAAFE7278F14,0968A2132E47A402,BDEC1AA583D5CB63,195DA16DA11EB093,13F127AC8045A9FA,7EA9AA8345EAE3A4,A01131210D38E597,E91B3A90FBEEA245,003E9B50770341B6,400E04C7172A1894,7EB094719085D64E,9D7ADBC02AAC5F5D,A34855ADE38C3E2C,C646F44CEBA573FF,856CA5E0CD0AB2E4,75FCA89DB79083ED,0002B1F73E93A35C,3572F0867AA15ACF,2188722310EB76D4,F1A4B2D24A383FD8,5607C18CD886FC08,02897583FF7C7258,641944AFCFDBD601,9975EE8A0587BCBD,0002DBA2C4890C5A,4EB38990AC5C43AC,77D684004A731A53,5634F886410CC16F,1CB94474724E8332,475340A934E343BB,39C3B8B5CF813FDF,2B593040E37184FA,002C6E2E2E567938,544A907CC46FE15F,DC23DC4BB0603AB5,E5D027D6EB1C4E02,B8F1392480A0ED5D,8422E35C0450C073,0AD6875B318156B0,2C6B51DB5E25993E,003139E79BE8DAC9,B590387F71A83845,077A45E35B59F735,71CBA06CC2D69256,87193EBAED2366DC,F0C1A5D9B6EEDD23,13443A97D7F1E534,D6EE05E7AFA37F79,0003112F76BAD56F,A811A0D899F0F85A,37F7431AB6D1546F,3B95696BA70B3653,CFE4BA6E83BB5F7E,ADEA026F8385FCCC,24F2603EBC8B07B4,8B6FA76F581D53A8,0017A0DF9BB0E0BC,1F88F60947BBC2E3,79BFDDB893AFF996,47413C0B51ED4B2D,81BFB1465BC678D3,5DF55599786555D0,EDF54207EC94624D,BE3DD6B2060C7C5C,0021B04B0A29AF04,AA2A6FA87DA22659,2C140B0E2A295203,BB8321D968E72940,FE324EB9A9C03D76,76191CC876324EE2,ADFE03FEE3C3BE58,C249961B9A80AD2C,00374DACA07E313E,0F5198045B707FFA,A99BA65CADEAB90B,9B085316A70CD896,FAAA73E6B865313C,AFFD1451FA3ECA04,12C4A8237DC1231B,6AF02A0C71CF55FB,002478C64F530638,84971FD0EC10F612,8F1C66044208E87D,FA1460916B4749D8,575F18E4623F92E4,29D6BEF1397B04F4,C00F8C76B543DBA7,3F684FF964565992,002597894AC83F5F,ED3A3E73E56F532C,34F1D60A9661E8CD,0A140AB202864412,EB8F2D6F372C3DED,398B25C20DC0EC30,E65B02953E73A32D,AE73B70DA5FFBD25,0033BCFDE70F0294,941140441262B810,F83D9C2DF5090BF7,CD7E925D520DA008,E3CE5DC9B5F9F77D,8CB148AD0D935615,104E21C2D97C7CAB,914359E29B3E2601,000731219388097C,3318C5B5BF3C3C51,3F8957F5F8D3FD47,5A202AAD34CC3A16,9EBDC560A13F05ED,AADA9430F926E78B,BD83E3989EC2EBF4,DEA6095D73E1E693,00087BE8492EE804,169B290559D467C2,2DB6CA4221B2639A,00C94FFAF39E566C,49E13726FE8EB7E1,7E35E355E6772360,D83F2F641E7C952D,D58DA110D5F897C1,002FFDE9799A4DED,E89A703434E6C03C,4B89340DE4388380,0CDCEB98A0B8F359,62AF498AA4D940B4,0AA90FE47CA3AFDA,D957D85DF0BA0F1E,15F0776FCDD575DB,000E8E26DF03E2DA,D5BC5D56F889818B,E20B216796169938,56A16624A5F016DA,8895056FF80441D6,B75B321C8C80A8EF,D0CB6E19F3492721,74FE953F9C74AC83,0025EC99CA23F8F1,B4DB913FD80B1FAF,86A7EFE80863161C,25AF44790CA40918,8F91A6745DBCD87E,F2CF397EAB9A0797,7A4817D51E3670B8,5B8927082E2F6609,00120790E26DCAB6,83D03FBC006014A6,355A3766C917F371,487943DD6CD6347F,B762427DAE6575E0,70ACDAA3B70B360E,BD583E83FA8808CA,73F96E3A873D5B1B,002BA4546A5E1F2A,0B40E147FC16B50C,71923449ADFBF4CD,FEFB793E5372CF59,AAE1615819309C4A,D83F9BECDE193CA3,25DA0A23C93DF858,90A83251CF959ECF,000BFE326E45C740,23D2A86B2B86F9E1,D7FE06909727BDD9,8A5885B52DE00A9D,CCA00C29D06DC967,14EC4B0F140C01A9,F31E4A0D82B20106,E367D6CF5AA4798A,00381D5ABB5455A2,2141CBB3AC486B84,E741CC7858920149,15A5C4968F7FB87A,EC816C3A2717AA92,984244CCD021C173,23A3AD3D1172840A,F69C2AC6E67B9CB7,0008408A79AE3E7C,8A2CA64E40DE4686,197949BDFD693875,4E88FF545CE30024,50253A930D5A632D,840BF20DA5C4F2BE,E7C6FD73CD6EA401,1683A3614BD44AF6,0005D4B365DC8FAA,1B66B3897A8FE91C,BD40D32EEE550920,BD0BBF5F6FB0B2E6,E57C74D37C97B977,85DE059DEBDE6371,5AA16A1F9F9EB2CC,BB945F44B20C0E14,00272B6B47702633,B1B89898E38D8FBD,08A1D995F3E4727A,B2418A443991DDE7,78D5918FF9A81351,51B48CB38F2B1436,9FA38D3B6AF7C0EB,6357C1AAF5AABDA5,0033931DFD084424,ECC496BB4262BBEA,3F9370954CB84458,8ECD7692A16AC20C,9910B735D1D0F107,70586BBD2CA52C5A,D32C301794677336,99F427F7F0F3AFAD,00046508B6CFDBED,991D7DCC92031785,4FF9726C9410E1C1,E4ACA2CA3661A0C7,87ABDBCF48F4F5E5,ACEFA5C487434A4A,7B1B1E5E2692C6DC,9116F1BEC089DF2B,00401BFF88F7C1E2,8997ACEB95523C4F,6FCEDC873E3E7ACD,FE4388BB483C2C0A,F1EB339B77898983,4C57EA48CC8B4B6C,E526D167427EC114,B38EABC05D824050,0032646A325CFB98,FDB22908672305FC,6306DB56DF96B1CF,F8D92FFDBBFC314D,CD1DAB5496268894,C2BCD93089D4B294,B5B799A0674FE688,FA4445837C13B478,0000B39FCF99ABAA,F2703269A0DF00F1,D10B7841A674C166,EEF65A72BC93F06E,CA2BF6EA911B30EF,BDF70802546094BA,64E77DA5C5BB959A,BA462DF8F42C3F34,002DCA3952CEF9CD,5281C0E4B2E2C979,1C6C8D95E5B9BF3B,3E74548728B19D28,F5B51C52325551A5,6CED00B14D37FDBB,44F069ADB1B4B1A8,74E056E0E36E198B,003AA7ABE702D2D6,01BFEF12C48F2154,3D8BD1286B4D3942,4FDB51FF3C1218FC,A1645EE2B210D292,192706E9F6F32DCF,8B9AD975F237890F,D7C73D6D34119A7B,003E3C9790E1C16A,C6C32E9F2B1BD0BD,9BA38AC2455C51B1,AD2D6D4CEEA5328C,A71A1F3EEB69D978,15CA1889E4BF5716,1CF807FE9889A942,2066E881EB03DFF6,0035A6309325BB2A,E55BBD239D559214,CBF3F670E3542D4D,1A351CFB64420970,3A164B43EE2850B7,CD6242B13280A7F6,925B6F4773363407,D827E32408C21AF4,0012B43BB63BBED7,443CE1C1C7C7E519,F962E068607B294D,F614B08B1BB41481,E65341D9BE6E6F12,FF6EBAC2A7FF715E,8D75839B5BFCC1AD,945D97B51628AD6A,0036E9CE89381D79,ECA21430DAF10EED,98480FE7147843DA,E861E6FB27109CA5,C67A645809861F85,FF169472C5719DD9,14AA673F81B1A8DC,A75020DEB805FEB0,00115F65F1B51202,6E39A6C891F5A68D,83D0BC9F0ACA4156,DAD6EB131B414818,5F6FD8AC3F1AFE2C,D2E2745B84AA8767,BE9B82E17D622257,AE9B125A4966760A,0014815BEA29D38D,B7B8F065D1C60FE5,9C2CC410606CF03C,31E27106D79F9834,7BAD6D0F5DCC65A0,1964A9405ADE6A80,09AD585EB9BB5C8B,B2D56CF23D9411F7,000459FA9AEBB62A,9179A48365E8534B,E44B68EFF1639FC9,3E90FB27FEE01DC4,080A66510BD769C9,94B31FBEA92C5A02,65B9630F236FB2CB,5793E454A082B029,002F198315ECEE75,0EACCBDC3320EC8E,3EA54825A30ED568,FB340982796E9508,4AB99A484EAF2391,951BCF6ED84F3F7B,B68EDFD7D4FF7F92,98BF9A74690E51F5,000561AAD1A0780A,E7EC32402E7EE7F3,CD2159429E1CAEE3,B15E7A92A1BC810C,3986672189CABDA6,78010DC7689B6A98,A712075F2139CBC2,5633FE995A1F1F17,003FDEB93808104D,4313890DBFE36200,356A428A02CE403D,D8DA75AC62117A6B,67831EF6A9B49570,C5D460D1444D158B,62200A8FA05DF965,57183CE17B54A285,0016BB48F2F0AB04,6526B8FA75DE0977,FE05084715C04683,51A0B8243E837A9F,4A6A375F220C32AC,E5BFAB044EA6AEE2,0790E1CFEEB850D6,74A11539A09E93EC,0009FD5E1E4FAD3D,55033F49A5F45407,2CDBEBBBA5B44E88,6E8968F3F93B3FC7,232429F59C32AC85,AE83868ECEF002CE,94E746A636D31FC3,02E7174446437275,0030235293A4B9F4,AD6B2906BCC05AB2,A62F28F762AEC30F,D458E76DAE1BAFE9,312CD97269D4BF8D,1D7E904FB32FCD40,57455B63A2832DF7,C3A804A16648C1AF,0007D0F9F8F69834,1C45F9033B73FD2E,1128398A5C41728C,695F406505D8ABFF,1561FA4E4B43ADA0,70A1511EBE04CBB3,3829C3408128C780,A039EFFE04A5446B,0039454756297A4E,4CCF559C77CEEABA,A63E49874003E554,30E8163487581C15,78DCA40E5025598B,E19572853A7D6590,001E7FF64F5C6137,249DD584C57CF4AB,0011FF86651FC5E1,20F7D1445F94BC32,362F1BB7E3C68407,6957FE288E5F1806,7D662FD7EDD1A1D9,CC2371BFBB1C03B7,AD32AA0D2E038FFA,0231F2599D03CCEF,002EB24E22072D94,5586663C73188D1A,FE39A817B7D81059,B740431FF1A56F39,F4C8898FAE429828,C08177E2348A23C6,DBAFA2DA416CBAB4,ACE3399E8CBF6059,003CDD3E28B9E722,FDBA4FE52E05581F,B0DA90580CFAF706,60A210BD5D649CEF,2B9A84224197D703,9336D1A8F771929D,CF85B1D395A83BC8,5F9532CE2B59CD19,001C06BD6841B7A8,57F399B79B231AC1,E59CD17ECE8A55AB,AF9D704B11185A66,379CC8BDEB53F5F6,92A243A9C9B815E0,D98B0EE13B34B52B,EA936474FB2CA165,00172848209E89D2,1FF7323693AD76AC,242C551238B03A3F,3F09FBCAB8E9C27B,85420440B51A2D3B,E43DB8ABA605C613,E8F1EC9EA5087789,7ED552957B37D9D1,0035F740AC388911,58F8A9175B1C201C,776FD0F5EAB5F25A,C854E1A620676511,A8A523773F34E431,D294DBF3CC81CC11,E935A099EB5A224E,B05E343841B7C7EA,000B1CBF7DEFEB97,9973ECD63CCED090,B44F106F0E4CE466,0CAE3108D63F2E98,95879E3643C6609B,0068DBE2F9748E11,4D9A644838F945E7,DF924834E2FCED8B,000F763D63A18C36,FDBC3EE45721C4A6,7D4611E3389BA12C,8EB2AD5B6007EB64,C9045FBC49F9A7AB,5ACA1B29367164D2,2C6963491C7DA85C,F40F20A3DF2DD4C0,002203E48BAE8002,59319953FB13A8F9,242AD46DF79E3137,4419091D1F382163,A55E3E206A2F2FB4,3AD911097F429891,B743F1CB356EC72A,259378A55104CFC0,0038DB49AEEEF0EF,605D776BDF1F8405,AF96879F82CB7561,3A55C770F63367A2,0E1BEE082DA301E6,7FF69CF9E5261B8C,B9B38A3FCC4EC296,B4B750139E3013D1,0003730D84193119,D57A0D26C7FCFAEE,E43608E765814BCF,9BEC2CA2C1928CF9,BD9B62A315FDE1D3,9821B24887847ECA,F18194761632BE95,36DABAFFB53C2E34,00319CA3F6548F8F,861726085C086442,7A3BBB485AC44DB4,B009007ABF4D5BF9,2B30F69921D26FD8,8AAE35CC285218B9,840F3D1DBF1812EA,A550327285198305,00071F1B9E6B1D6B,68BCA0961A47A446,7E7E9FDDC04CB33F,115062B5FF835E44,D428D5948CD5322A,931027AA8BBFBCC7,473D05EDF1D657B4,E65A046C456A7B2B,00337B21D4FA062D,84B790E629C3419D,A4796CE81C66BA41,DBB1408E98432B2F,D39F84165130435D,AB44A99AD760CD38,2D9F0D1978BC0BA2,5F02C6EEFFCF7673,000FB1FEABAAD6E6,F54FBA8C793C4E1A,E63F31ACD8F38CFC,F366793970E1B49D,CE8D2386D56ADD3E,4AA00BB9BF5FAA0D,8287E1631D5612BE,4D8A965BA0A9AFC9,001235CB873D2A6A,6EFC07FECAE90A69,1FD94F07FDFF906B,0EB61EAD255DF20F,638A433F810E7BB6,2BD3D291C98FACAF,091CB8C342858A54,81B3E051ADD2C7C1,0020A9539EED045A,82B028846BF89A16,438157C524276233,548C1A3CBAB28A89,330AE2F49D7BC57B,15194997722F550E,DEF8FB91AAAC6DA0,C5BDB7EE4588F1CF,001170F87A56024D,8E69BA6C0D07E80E,F9B1402292223611,7C5CFE4EDB85786B,F0B3597B0B59D9D2,E4570781D856BEC6,99A79BABF797A9C1,B5A81F41A0BA5CB2,000AD5891AFEF145,FECB9B34F3B2E275,1772522FA325B4AD,6E0862B84909C459,491A9061129C20AD,D90C3F113113970D,6715D3112101BA7B,1DCB00C82B0D5CF3,000C4B6035409860,8D4DB3EC455E43D7,A17FD091AAA8B8A9,B955CF75497992D9,E98CDA200A349F17,44F728E3D58F7B2A,5FCF425EA0B307F7,F71F539DA3748277,0023A54A26C4ECC0,6839854F4CE38AF2,E963453CDCFDC05E,E7E0B2B1A58A79AA,D2975B26652DA526,E5CA6E2B1BA3EB54,D4E5BC05E1AA2882,BC1A65934902AE9B,00373CA8D5D374A7,E4854BB00CF95E36,825BEB903E6ABD3D,43880591C249EEEC,8D920FC5213FA31E,22CB6B4747830B8D,F261173DA03B6B5B,739457783C0A46B4,002C1D0019614B70,2A12F21A01DD1C45,D9C0D7FCF6BC0C9D,D319B3E7DEB17590,4B20944FC43DCA4F,D3C602ED23A88F09,6856BB4F6F7E3DF4,68173B60BF2893B3,0024AF1990515A49,9203ECEF3356E24E,6F6DA0933BF581A4,18CC10A5932A7845,04A6FFADD77B9949,16137341A1223715,8445C9728669F525,5E8A9A00923C1AD1,0032F3C0FC6716B9,392A370B5B34B02C,3F84C9B2BF63390F,21CC699E3A9129C2,912C32E52067D2FB,740B18D80A27F13A,B446A3405A987D27,3E138BF92A1A37CD,0011859F4C953336,0053F6E2D4D23E9A,E790CA2222A74BD4,26408ADDBB889698,63D5F54AB4E11F83,9D690650591CA931,027D1E51FB29DAB8,808CEE9E0C0170C7,000705ABBE703F00,9B280FA6E4D562D0,F6A7F55C50817E8F,53CFD32480E613B6,091702366BB6A5D3,45D444FDA2BDCA64,33FD125147AC6775,91805696FBABCE66,002AA3CE4752F865,1F37B67DAC0B0CAC,9909C9A8212C030C,209E77E97EBDC6D5,184E388FAC6833E0,E1F3617502EF8E4D,726C88AD78D9FC5C,CFE49C70F088B5DB,0022231304E54210,A7B15119E75FCFAC,3A454FCA4D9D978D,B566BA74DD836DC6,A4DD3A1B4962B3A0,F7CBC2BBDD2421EA,019762C0D58833E9,DEA14565415238EE,0019EAC286F5BE27,09E5935B14EC98F9,C6E1AE22B3295A4F,09B625ACE87C51C0,A73BC8F70CF66521,D815942CD2F46A9C,5C3212C0BAF78DEE,68CA732895FBBA2F,0021A7DF06ACB328,3C5A3671890218FA,5FA8E9642849B4A1,0092FDB503691643,167B3E26258E1AEE,462DD78222142C53,463074AD22C21535,D88F84D793EFD0A3,001A980CE4EA4F8D,06F1B0596533CB4E,2E9BFD01E9C50D54,629F49AC81AB8BAF,1E0AE3B75280E822,10345A15C82EC68D,EA6AC1AB882F16B1,494711526CCDB2CC,0027342B41BB3ADD,8DB143CD5E19D752,915279A4F0415898,C29A453C9565C6A9,726AC89741913470,D8014CA2C15D1A95,EBC974F102230063,22A0B67330CE7212,00131071008A9E54,3292FAE290CC6C97,2CEA03B1A2CD312A,29BE784C27D3B7D3,AA541EC28941B6C5,3AB92891749979EE,64C2D545392631D7,16B4449E326A5411,0037A32D1C9A4187,5104CEC34B2DD78B,7CFB64138B099026,C7D3E7CC40BCFB8C,656A944C1BA41D30,BC4E9D0DC3BCE7EB,5FAC45439F765D9C,176E15FB0FEF39BB,0008161AA49F979B,0C1F749E52F6A5C2,1C55C369650F881B,05B5E61E76932F21,06D590A48F5D79DF,C09D9E6EBE986FA1,A27B23EE39DDE8B6,4FECF37BE13302C0,003586B75D065BA3,E7E88C711FA5CD27,5DA37D92D6BFE85D,E8202160E4B904AD,1A3350A929900AB5,904E5DE0AD542D53,A665D257AA13087C,3AF484BF4166A312,00357F7E14E5D913,4A227F928215086F,3CF2CCBE33165635,F01C2A3962381EB6,9925D2952D6B2A27,4C40D39FD265DCAE,E1DEDEE851CF23AB,3F046D48AE0F2D5D,003733587991F4DA,356CE882AD39FF0C,CF8223779A03C6FA,375296D8CFAF1EDE,9663140F8421861F,653460A3B37B1A21,4678DF37321DDD7B,0114B5B5969F41DF,0039D633425C8608,FA70EF459E7B9F7A,522D7784187D2A83,55B17D46EDBB59A8,B1F414C721DA4ED0,C8D80656CB0DF0E3,9EB48FFDC055EC76,DC290BFBDCF1B4C7,002ED4A5C38444B5,81A959D3FD049AB7,B96622FAE035F2CB,86715450EA8F5DFF,5D0E47AFD573414A,9B9518AC3202143B,FFDC52F68ABC3E75,73588BC7ACD4A2BE,000A4B8F536FAAD3,46D2014F3397ADC7,46FD5C69D8D3A71D,FEC4EF53F091E216,72DAD46D67B7733A,CAA9860202945EB1,F123F866F8714A86,575D6A70081B7257,0008069EAE527BD4,16B495D1AF2A474F,FA6784906102839C,929D219357ADCEE8,FB69006F01457727,1294A87145E77B54,5633E3D09DC36188,3D5183870E05A388,002EA88AC85B123F,CA7F3A186BA8A8E1,F6630B246CCACD29,7819E64983C86301,84616EE458AA86AE,3938F4DE980C45E1,45B9F8355A22BC40,AEB190AD888DF5A4,002B7A905AFF7C88,4B8C05D88269E459,223C8349FADE242F,7B73FF0DE070388C,4FEA093A1C6F48C7,E1A45F7F560D9E35,07089B49DCD07033,3CF6687F5591B61B,001497E371E5D1C5,5BB73114FA641139,51B1BA1C5DAFBD48,36D8EB583C5E05AA,A64DF7148C07D853,7CD85B0D2284D724,D7CF1CC59FDC1595,E886938D1DD09862,000D3C8A250AA8BB,06EA9C4AA3F9D2F1,B16DF7257A433313,132B38FB9C54D619,5DCF8C0C401E921F,EBD3A8E5CCE86679,C7FA289F8B7BA8F6,5F47737AFDED06D5,00231E750F425273,7E3932B8454C364A,E3770D8CEDFC5845,622C31E86CC0E093,59498749404F38B8,2FFD7B17D111C46D,BE02228D5B40264D,EBA2F78895B3ADBD,002360212F3529EB,88520A458E10EAF1,34E56FD814371A78,74B651C2F546C1A8,95B47F5F76EAD216,D751BF6E9A88AA4C,96D3D2E19937D93A,EA8D973721B2228C,00020E4E4E8DC3B2,D85C1BF51337E9BC,5240E6B596814BE9,CF44CE789818EFB9,1BE289F8AD597208,DB96C8017698197E,9E22199CD8A9ED1C,74AD079E7A488BAD,00099ADED25555DE,4A97C45A6673ED54,E50243D7A4249DF6,51E391459D805F07,5790326977CB66E3,7213ECADE9258279,A5320608F9CB183E,3A516A04A7C489D9,002405667057388F,828508AEDDAAE544,2CDA5D415D77D90B,4BB58469B92C3155,EDBDE12E741A9289,A4F5FDD4EBC9DFDB,C5F3F5520AA485FD,AC181BC2745CE436,00024AEB7C137DEA,EE6B16BB849B2636,3ACAFBF84FC30FF9,026FDF35C4372A8E,7FEE07B1C59B2A16,D0E0BDA9899A2DFA,CFD7A49E42AA5EE9,B174023ADFFD014A,002CC6CA79A7F14A,2F05A88B6E1BC238,BFAF6C7F227820DB,46F6FFCB557F7780,5501857027FC75DC,E54E412EFD7E7EE8,8804E21A14AA9A0A,F6A37C59F2A80305,000AC8C75DCF49C7,71CC5393C2C2F5B4,9B1305AB6388D147,7F5618D18AC36CAF,3B13AE57BAA387A1,4E780DC4CE2973D2,623B318B72768F92,61E79E5A63D6EA71,001D14D139D03814,B2A947F1C50138F7,673D93B230AE72C5,294E48434BC95751,7254E1EAD0E2AAB2,003E5E390FBAFF03,643E4CB7C4CDB5B9,07904B24BD0BF335,00403C57449A45D9,57515BD933863BED,24B4EF5660F8D4F0,BC9BAF3698AB93CC,E5E443AB50C2E39A,A2A4C557B732836E,E9AE1F42E54F7E61,AE5326D9AB87FBBA,00247EE8BA5D533F,63A0B00C4D86F811,B3D4AF705422D836,1CF48D03CB3BAA58,3FCB8FA56FBB1438,AF6F0AD67B10E43A,5F2BC08F9B50FD7F,DB6E66C19CEE9B96,000E8C4A308D6D63,1D9AF301220C264A,EB459ECC3D999000,E0795F77E189FD05,F1E18C4B1E87BBDA,1B849B75D202924A,D7DA5E9F799E28BF,B6F9D24ADA20DEC6,00167351B0D97E1D,77E94C72C28DFD21,7798601D328C1BEF,48A82065736426E9,291297FC5C38F4E1,D2D8F8B02096D8FF,B7A06267D6936BA7,B33F70C61741E734,0036D46BF78BE614,2F04820F31DC3575,4AF2BC015FED83E3,95625EA94706E11E,289039AA1FFA72EA,B547FF2D5C5DD9A0,F2F791CAAA21E84C,7AD14F3BF48B999E,0023D9F50DE8434F,C1CDC4189151CC75,D039C431E4B6E33F,05679FCBE896CC42,D77ACF50C41B922A,78E1979273F9740D,796D7D058D321A77,1C1DE9D27CEF2D3B,00070F68759961E6,3E656947FDEEDD19,B251B651D9CAE98A,2968B20BB73EFFD0,1B2D80F9440884F6,13654755BA049B3D,206019513FEB532E,D42840D3A4BC73C2,003D4ED197C2405D,66A66E300C7271FE,9651FF3F4B11F40C,0C8F5E2609CB0F1E,E81AE82535A0868E,346E7A93FCB2A5A4,D7182B6B3D38F3B4,83D67BE21CD7ECD1,0003F9B166D5EC99,C3D448F9BCAC43F0,BFD39C31EB0EE2D1,3B2074EB475F2C44,814BD10B39D3B717,C30D095211AFEB50,2725C962A494FA15,DF984961F3AA4DDC,0007A6DE36B201D7,346D06771C1756F7,F55D5A88DD00D844,6B78F91343EC19A4,A9C1CE08E1D2A271,479AFB0201C99D25,51D4B9312B597CA4,91EE055F34F1DBFD,0019077C208ADF42,8BC2C0AE26584E8A,808E7A3EB8554419,3968513885E082E3,9913BD11D57CCB13,8162B81990AC1DFE,6DDE12D95FA7D59E,E1C9459AE22EC58E,0032C77AD5878011,A8CDF86595781FEC,35BF72BBDC7382F1,3EF1515C619355D9,99B186DD2D98823A,7D6A24F3D1250CB5,07AA1EA80EF59A8D,D5A80E81B69AD8A3,002C10E57E74C20A,5B8D7DD4C69AFCB2,BE39C63A51F17D1B,86939573FED194AB,59619A27EE3DDEE4,514E0694884502BD,2552B46355C4BF34,6C6C2AFD37E4F492,001851DE4DA2321D,87BBD45ED3A99489,3D9848C51FECFF97,9D171B620E740A0B,C903F112599DD581,ABB298718989F990,1AED93CF334B9FC3,9DE6B93C0F5058B0,00199BC23529D9E6,7FACA4DF89C0B54D,319D2918DAB55EE5,79FBEB5E92F97607,32ED8F80F47BF78E,9A8C52D6F7FD800D,DBA3FD9ED8B00FAB,3FC33B6D3316E8AA,000F8FBCCDB12F20,8F25659E56DBDE8B,8D55D47B7FD812F7,F578BA6B9156B4ED,DC1C1F7B8EFDE707,82237D54B6AFED67,8400C6BC4E622A0A,F1C7B84FB4CA4F7D,000CFFA0D0D3D25F,5F15606D8315B2F8,3BFE4FE977FF733F,63BE359606E548BF,CEE293CC6C4577B8,375FE9B99572D10A,596610D3150BAFC7,BCE25515B4E07008,00053EA12C16E9D4,CD71CEC8DC1558BC,01EA64F0C9BA0D46,CC647ECDED5D7B15,2DA8F73873BD4104,DACE44E94F663C47,34FD5C2831BBA007,0A7DEA98C5FBE899,00214C14BB20A9DC,4EEC31AA7C133DAB,CC75416D36FA51EA,07FD068C2BF6CA67,A92DAB3AB5AAC223,BE6BA23B34D0C69E,74FD89318AA24EC3,FFFB3AB52DF1176C,00161B1F73FA44D4,613E5F9643F2404D,E59F606F804994FF,DBB132A3893BCA2E,F12121A2BFD5D644,199195620F99099D,08F7460A24AF1278,E8B4183894007A27,00139AFCB7633459,F53BDF53DB98C75E,1E3C22943C4E2B38,9FEE00DA16746138,6329D54C73866EE2,891B314C3EC96557,845BCF2C320A4DC3,4D7F5CFBEA759D61,00106F7BB9F2DC29,3AD84E4F71287E7F,642B7D584AA73140,5091233846D4ECE7,0CF4FF7B1AF3148D,C9F53EBFD1AF96EC,EEC34E8DF7EFF0FA,870D60B8C8B16384,00177F6019DD15B8,9FE587DBAF40FD3D,4744C41819B7A484,71CEF8EE6D5A18B7,698C9F6E3E308E19,BF41C291190A9E38,22D5F78ACF5C93D9,66564D37F19FCCD7,001E16A1392E8FA3,ACD0E0F742DA1509,08073D1BAC761E9C,2648B3E47DEA7895,76CCE84BAA901E96,C4F0F88004094F20,C9567A9304CEADF5,C514BF8013E58D2A,00033DE406E9CA61,8BFFC081E6948411,17447A1841718F85,F9B257392E13BF9B,2A43B4CDBE2DB0A6,AF1B88A50D5CD509,509DF4C6E36DCDD9,BEA8E95654C6228A,001FC33D661F29E7,71FCAF4FB7461012,D009130D77A41BA1,B6207A3728034933,7155310476C5ADBA,61539EE3231F2D2B,E02D42324380B6C8,94F3B154627BC1B8,001618C409ACA472,5EE4DDBC98F7C679,A5B5E92AE460A58B,9C2D994367EF2778,013BF7C8CAEBAA56,A2FF606012DBBD7F,49BC3751BCB2C40E,7CCD07B1F382360C,00351AAD20E1F9AB,81D50A1ED8304460,1AC6BD48722728D3,A4E90A6F33DB2E38,7A0A3DCCE0C19E0B,8B3D496D2EF22194,360E23219C7AF891,A3FBC41B77BF1D1E,001D55F51D376B06,F80D3F85BBC6CD0C,D7BA36E2765BEDA6,F48FAAD9D6B8E49D,F997A21075051B0A,B7FC976EBC0A0119,9FC670155CB0C263,4A64C62AF96F88F9,001CAEF7BA08E0BE,85B29E2A830E7DF3,3141B18833EF4FE8,C2431A8FB63ACC36,24708546AA408A2E,08256CEB9FD86F9E,2C65C3236DEDAFC1,60829C20D5B019B3,00258D1CC58341D1,B6D10479D373C1CB,E6FC7CAB062F7E3E,F64A5D168F836182,D0AAFC600A1D6385,DC32ADE1555037E3,819233C66C29F48D,51F6F6EEE8B2D012,002C38B5EB3E5DC5,4C8F4DD6C165A9EF,A40A826FA49A5D7D,027C0779C205C286,20357C97F2FB7A3C,9283302C5C3649F1,1F3DD53456097E3B,EF3298FBF9319B8B,001FB58E13C4B269,24F3FD10657DF528,ACB1515DB1B6AEC7,BDC5C8CEC766F075,849398D31CBBBAB5,4BB19415222F4EA7,3D3D76BA0FD9C137,51E5EE43780982DC,00275A9120BF8D70,FC5949D3E3476D21,AF22F0496A65DC2D,5BF0B66AF51E3BE2,DA22A6BD03147993,BF266C60D542263C,513CA49EDB651EF6,9CF0932F2E049791,001C24827D8DDEE9,ADE775B386DAC709,848CFBBABFC1CD85,7B3C50B8D9DC3D83,CC27ADE926FD3C44,49714FC948B2D939,184801F55B7156E7,F10C3E98106F38EA,0025E7E90C7D4AD8,80111ACC4DAD09D3,37C6AC8C7E1F0588,804AD2C0B7DAC716,5AC1A3990CB2AEA0,D4ACB7C5E978E5AC,BEFFFA6A705930D3,BF4A775443B6EF30,0002FB5BC333461F,FE4FB97757076601,15DCE40B8859E182,FD2A3D1878D26CAE,B3E401613EDBF519,D2C52C3192DD3EEA,BA42D54AAB83A085,3F415BBF03A46304,00372657C4E5558F,76DEDB636D317EFD,3B5734C3EAE98935,E002ECAE2DEB66C2,DE637D9F2DEA7B2D,690816929BD094E1,B55D22245551B9F7,72FE0468EB06CDD9,001E6E0CEF031D71,3BEC65F44EE3806A,DD6C97AF11022CA2,DA00FB8701ABFDF0,94EB0CC8C44497D6,73F794AF1D30B95E,A4A74B818EE4F259,C6D007D609949E54,0034822C5181AD81,C919BF113814F378,038AE2935E7066A2,547A2F4636203B13,47E6F5A0A4F7F96F,8FD6A9026E82DF4C,1963240891D06BED,F6F0F9E3AA7170CA,000F129EFB0E4E35,0D307A66E9D8DC29,EA94A049A0E4917D,AA9CB17A54322D57,3BD1B386B6B10C28,37087C39F5280EA7,096CF3349115BB59,4422465885B1A422,0024315E27BCF11B,10C85BC61A705CAC,3FC8F37C7FF80800,D8A315E5480F1FCB,22F2ECA444CA622A,7F6729C85E59D519,3F1FF33B2662DCB4,F124C6FC11CBA212,002B28B6A54EE291,936FAC8ABE94B372,ADC18AB06D6C9A92,BCA4978D6BCF94CA,2A883A55D68B01CB,8C986C9E314472A6,3E661440199BCEFE,AD8CF85BDEA0E20E,001FDD736B1CA731,713D4F1D40A6FD96,06DB3DFD1B017ABE,D228763D3DCF3A23,D000934732674D4D,BE12DBCC73C65E12,BBA07182866665CB,D5C3F8317D64BE16,000B2E46160097C1,C33E793652D6795C,284F95452F804507,AAACBA9ED8213EF4,85BF8B31CBD43E8E,00D18DAA58BCE02B,238F2547E8B00F8D,D3D50F7886089FBD,001F2426137D02BF,1BD5DF773432E48F,F6D7F759F494DF03,DC17321D38FC4D7C,D51DE1357727A36E,43170D3C5CF11E13,AB9A7798EA21B8F7,BB9E3A150A9074C6,001F6F6039B8EDD9,A362BC5D1663A822,CB8C8CD7978617BC,7F0FF22CD031A0C4,339674B3A5C372A6,1B3BF5CD4A1D440F,4D81154541940DFA,8EBCF27850146B7A,00317033423F5611,1C872862D922B33E,2CCFF87992FF439C,B61E6A85386F5750,99CB90CFF1744247,0133AC4BF55EB5A6,1BA99B7AE35EAC83,0FB5614A02CB6B2C,003ECEA2D98C036A,AB05356A5DE3DB86,AD396C16E560FF61,DDE1A3C3AA693D02,5787D5BADC2D6F2F,AAF108D21251E5BF,AA409588A066E464,31E6867A5EAD31AE,00383D428816F29C,F89E44C373ADDBB4,F546CF4A92308F12,EF3DAF19C1FD0FD0,2C6B4CD839A18074,3E2ABF01296FC00C,F64BCF41E702011E,F2CED831641E6ED7,003D4A3FA5FB6179,33D65710D9A55F20,FB888C93E97079A5,962A6B004CD5904D,B39FCCA023FB546F,AA2F5282C3264809,67C7A70C31F87178,0D3B32E088046748,000F038D354C0124,C969616685106117,0CC8C26DD074FC79,8EF78BDE78887200,23FC6A235B87B19F,0743656ED08DE036,D811F2BEDEE00900,063B00C02E4A83F6,0016E11CFF4BD6DF,11761966E3B4B79B,0A93D6689DC87467,287CF91C1F5CFF91,D672F82A67B329F7,B9BE610C5D609B6A,C24792CC6B46DD24,3B568E48B157F29C,001B800D9AC7452D,A104293BD259AF8D,61E7F50267D20A93,A72A0160C2ED3907,8510A0AFC96FD5C1,9F7A50E549C67CD5,AB6853E8563A20B9,14BC9EC0E579A3E0,0038291A63CF74A2,E25FEC2A89C5D3C0,5060B1418DF5B1C5,53CD58D4174F1B6C,C3127496586FA29C,24A88C53BA6C6EDB,110759F1174E3427,0E01C866F915C242,000C0333E975DB7B,5FEFE654E4DB90FF,6EFAF93DD9F2694F,D6C753B27C97E063,22D2CF05AAD24A51,00191036A8373E8B,1F6672978E233A29,2D25A1E125DF2494,003E3E7BA1D14579,80EA669F73662D23,FC44E1C4C4E5FC78,6F02592953D62A2A,0ACF483BF0F8605E,1C3EA4F044B39760,2D8F22A89C2BE09C,E8A20DED8F638883,00191AA0D5D450E4,13F6DC62B887FE90,5C4DD50BCC136754,A24BA30A7DCE9E85,02B2A1A89F5CF5F4,B5AD908E14634FB7,EE3EDEFF65494796,237DD82606A7C018,0038B37D6D382DDB,E64413D4BE6B53A6,F7B238E642EC673B,8A90CD58965345C8,78269F90A0B3E2D2,271082C4AAF5CB5F,8EC876EE350DEE60,4EAF823E3F2358FE,00174200068C74F6,BE3104A7B0B416FA,1A931CA8D574E8E0,5E96A3F8F43F0767,1F6CC48012598ED4,E9A860C691BB328D,886201510CE46F89,909124044E8F38D1,000E997CD38EC36F,DA233A83D48B512A,2FEB6076378B65E7,AB5D61EFE69C569D,EA249074D0935FD5,2D905515D363DC9C,70C2314B9F75BE00,AC1227B278411A86,003708509AC054AF,E3EBB1241E430A84,26B5A0546997EF7B,822E3A3D3065298B,F8FB575D580642B6,C4828BC1E22AE474,7F43264D1222AAB9,795702878BDD7039,00138A7C705BB4C8,7F67B8964E59997C,F76B6FA560AFF7EE,87741025EAF23D88,0B6CBE39F159FF72,E68B27F67FCD0B20,A58A3D819999FAE4,9CCD26D7E81E85E8,002D789891827C1D,8141EC803B0FEC13,E334EEC7180DA3DF,3A590912A6EFB787,E5C9ABA3D809B530,A3050ADCAF278182,235F49AE1CDF00BB,8FAB00B0E4843513,001D066C7965EF56,30283F15BDB12E85,B8529DF83C45AE58,B49A17F9A10AF9D3,B07518127D2ECA0D,8616DA3FC112E4C9,8200CB7C4D17A898,CBDB063E9DB9FF95,00045294FC650D8B,6F52628290F88E26,842E0642F2BC2DD2,B742F452F99D3ABC,28D174748A094C83,D634D64198B45D00,3E218EE78FE96392,CE12BD23CC27BD4B,00268567E79F1B38,EBD391406492AAAD,1FB71A94FE25D54B,C20B40D693C0F029,39EAFF58C1C7569C,992288ED7AEEA442,7E646D09721E104F,242B7C0A7BDDE1EA,0017E1FA40D731F1,AF230A6681AC1BB5,B85829AF1888E003,3EC4D87E23A3D46D,258BA8DC834EF757,875DF856816E67AA,951EC11348E5110C,522432AC4914DD2E,000A39BE7971F7CB,F15EC48B1F6F24E8,200E3DA62697138D,0CA1DADD844C9B89,65CF182DFEC6F4CE,81F97AB8043A0FD8,7628A83C41C27FF2,9268FD722F441563,001FFBCB2C1B877E,737EED4F05ED28E7,88592E184C7759C9,809CDC1EA0AD8814,DAF8EEAB31E302F6,7C6D7FCD009800A7,B4530679D6A0A893,CA8C33BCF6CF81D7,0034F7BDCA8265BE,B1041CEC27A126A5,561EC5BAFD53B06E,4B6B368CC307C408,B8513350DF996543,EBB5DAA8FF800E46,3D19B211E88B6837,288FEFEC45BBBA09,001A8C7E8BD73190,5D6F4061BBFA4E6F,55A64EBA2F7024FB,AD234BDF654E2927,0DA87849F2416288,7BBCADBF0D32A0B9,6FE3048E60864776,FB5EEED5CCE673EE,002F429059402601,26E41EEE468332DE,F9ADBEBC2DE1CF86,13386370ADE988FB,E193F193BF32887C,890DA11ABE48301C,291BECC54254869F,3841BFD9D477E7CC,00106F2D4A5DCC8F,419FE351F0F93DC4,445747E8BB6B038D,547E22C7FFC1C663,560730211E64BDC6,56FACBF3A3A02344,262959A8D8A4C6B1,463E8A35DC1B7796,00231AB7123A4BD1,D699C2F5583C0E53,B59DC5B6F52E8824,145F17BFAEE6F9D9,6E154AD84C315706,E9FF8923F5920B81,3ED9413E687D47B6,71EE9A229345F5EF,00060DCCC8B9AD9D,DA33BCF04A95BB2C,8489C348163256E2,D043C339ED2DABD2,B6B1AA027137676D,E341B3DD7E133835,FA2CAD6873D71014,885E55716F4AAFC4,003E5B26A552F875,0767AC904EA5E113,DC6236D7CE196D04,59E96CE3A626C6D2,857FEBFB280F2BCC,FBFE60937296A37E,3F993B4D90F4A214,7017DBBE2F1711D5,002B4FAD5B38C05C,7391BCE211339330,38FAB467A83CA724,DDD5391D1F48C560,B669AE4F3784E169,020210EBBCC4D5FB,191631333554877F,CD057750FA4FB32D,0023881EE6892DB5,C9768C749449EB6E,DCC5E572BB882173,19ADB8003B0703FF,812D521B1A1BDAAA,821701D717136757,69201F63E25DB71C,FA9A2165FB8464DB,000E1EE8075ACBF3,289E6B780119527F,4679A3976BBC9D65,56FA0348583BCAD9,9F8D422CB2867F1D,5ADE92EA0F9744C7,24E5628779200845,2D580819D931F7EE,00004A2AF25FD488,527B1EE3010E9DA3,1C28FDAE39A145CF,B70BB074060DC66F,545121867B5D15EF,C3A0AE50DC8D0C97,D9039EEC13F95B55,C6234E13F0C594F3,00334B7BD71D2643,A4823EC903551E52,BF7C47345A5348FD,55722290950233BC,9763AAE8902114DE,43351DA5F0F1D11A,855330197FC2B34B,AA77A60E8903BE80,003D2D90EFB62552,B029017B024993BA,79CBFF3D78956C77,42F26375C7D82585,6C715097F4AD7D38,22CA44757446854E,AB8A7A4280E2FD5F,DA6D521AE4AC25EC,000A10D5EAF0F368,9A110F336F289413,E203AE1EEAEAA0E6,1D84C242BE8D2C7C,4FE12E6D7E0D0A9E,30FEFC6784DD54E5,5A286E4C2A8F1B2A,1F7B781F82E37614,000925979F95ACD0,9420A09FE59D0AEC,BAD957D7CD151DED,D8BB21C1EA8E2034,F00B45595AD4B0AC,C7CCF912FC325E9B,655359D5C1A1CEF6,E064EBE7588A8A29,0019E620543C7D32,9962912847019E24,8634E01D72BCAAB1,485C3D422206FC02,0C1F6223618FEC42,7E352A21A016A19C,CFC9153301BF69D8,04F642F5F767620A,0003F808C804BF3D,F94304C0FF1B5F23,5F29C6FD229D5857,7D909584D4BDEE29,8B3B58F846B067DB,8DB6C4FB7735D19C,7CC870281A5F6C73,ACFC25C44C7CB2C6,003073C3B115C55B,C5EB251339075BE3,E3CD02AE2A2C9C05,CD82B692C96E1518,9D1BB0DD5C5A65CA,7EAB9607DE26B832,6427D1C322A41DAA,FF9279D5ECF13047,000F40E77D570147,2DF200CA7D4636CF,7960DAD58E90FDF9,403284E89F342EF4,3CCBF9BA9D28F99A,0E0F2F32FF60DC46,1A352CBEC77954F1,46C7071150E38006,002235292A4327BD,DB7B97DA0DE47679,728A54DD448E57E1,F9FAC0D1F517DE61,287993E377BB48F8,21E831028679FB74,4BBD3E21221795A0,75BB5A7F3205C662,001B93701480F0FD,708AF38C805BE814,EF01CE314A8991ED,6A8A57DC1985DA70,B49E9368CAEE8FCF,AB4256311BA6E2A5,BD933CFFAA0E6D3C,8AC272474E6FE842,003407D14AFDADA2,2DE4C28827448B6F,0FCD49525472C87B,81227954E71D08F7,66885749412400FC,74FE295479001A3C,4C09302557B7BD86,F38AC5BF6F1D25E6,0016DA37F1BF0DED,FF9BD985233C343B,9609697689A68A38,FCBEC959DDB12CC1,F97EED7677DF6C2B,E9FA6567B574EDEC,F4BAEB7A6569D016,80640004A8681964,0017CF97E0867413,1D636EEB843D39BF,AB1BAC80F9D9D86F,4ECB4E0FC71AB639,BFDC7ACC0F1E6FDB,FAEA4C3599B36AEF,54ED4680D24B84CE,DA49B494DE983B33,00353BE7AF78F655,E8301892CD6E3D45,05615A526EB1A76B,8A61BBC7B51893E6,1E468406CCE6D523,9E13916DB717AE28,2529EA4DABD6F18C,EF68D1FE6333552A,00038EC86104C3CC,EC81F34A34AA9AFA,35018F8063035FC2,59DC0F0AF815423B,30C0BB46F9F2B37E,8337CFBDAF8035D5,9231372E4AE66794,181CB067EBC0C5E1,0031E479B0E22605,6BB0A550B9D3E16C,2C6DCC064F5A8F84,138EBC2F8F405964,A6559F1ECC769EB8,FE744347A6B3EA8A,B07924E23D4FCB86,773E0AD1921F00DA,003419173289CF68,88D339D4C11DCB28,4A012CB05F39AF52,B90689076086D6B1,D5993310E88102D8,0CA5F1E9976E96D3,BC902E9CD4BE0C96,F20521A7F4FBAEB0,002FB89959360F37,543BD4768068C1D1,2515E6E643F8E1AE,BB796BDE37073EA2,41A5537D3279D996,BB5E6433CDD97F68,9C427C8ACA042472,3E2897B4BA765A92,004028501C644FBF,1A646511A4FF37D3,23D4C1DED3A232B3,78CAEF51FE082C8D,56383D7596C74DC9,2DFB7DD49D90249E,AEE0B14F68940CBE,26D6A738E5220676,00191302F7094CBC,A1E03E51F4CA6BC3,F60FBE8B64DA1682,E0CF676C056CB2E4,B1FCED24124D5FE5,D9C96DEB6E2A3AE3,C2B6DE538072574A,4FFC9BB08F3C6C16,002BF2E7E965013D,0F5616E5A4B2B98E,9635983EF01C8DEE,0294CBC6374A4E05,11CC810E6AB2CAD2,0EDD898F04C7B3D3,90636E884621BC00,9F44A81F8B8BB6AB,001543594DFFF108,C7A78E9B55B4F4FE,24AEEA5D02565ECB,B88040A575C7D80D,008A48F24462A0CE,3FC88A18DFA04AF7,7085B266ACCCAD31,240EDFDE49A7A570,0012F86EDE458F69,ABDACD08B4835CC6,5F43982BCA0FA48C,D796BFEBEC17DE17,067CDE94010BD2ED,D65275DCED810F65,5B608856315F5633,16AE45D99BE5438A,002A2405BF93844A,C66FCFC4C2A1D805,BDA6038C494914C7,8FEDA5A93F45D54B,4B75F442DDB0377F,E3F96666439383BC,CAFF74342DD8073F,110FB37EE0625FE7,0029AA1A0D06F2F7,D40CEB7CA285C170,7BBEDD9CE610F29C,6061C4CC151AC23C,2E5AE674BB01A9E3,B5F98D8D67D64EFA,3BD0FEDDFE59B76A,33AAFA500ECFC33A,0000F2D020D03126,C478A877B7D50390,FFCBAC210A875578,1FD9442D9D067224,C1AA1383471D1E10,FEBC5CBC0927159B,28EC84E417C87BBC,1564C4E1485CBB5F,00378E75B421BC4D,C3A72AB791A409BD,D1FEDC4B69B66ACD,EBF792DC8189E01A,8594683BB1234C8F,F7614D9A3FBA4ADD,BF49880BCA1A045D,BA8C0A8C7BADF37B,0012230229C58944,7D5C1800605097D0,FD2E5E1128F33212,387A0C2B49098F33,71EB538DE6ADA579,480E4C43F41544CF,7DC5C202FEE66F6D,42903CA200F512C3,0019A94870DD71CE,3E44F19997A82EB2,E6845280EE95DA08,7BDDAD1BA9492396,62D505B5999378CA,B0304F42561BB8D3,479FB430B247D457,1C6985D7E42544DD,002D52C1C20C0533,ED4F1256A68C6C1F,2C7E63F853C245A1,EC45DDE00B0E795F,1702A3C826896641,F3287EE98C40A30B,F46922A42D2EECC8,F131690FE6753E18,00189E830B45F451,2E81AA4C9777E5B8,CAE8AB6CA3B3E899,6915DE80E5BC8950,9F89DDE0E604E2D2,2D7F7F62CC440AF6,F61EB9BC5209DF22,05294525E0E00ABC,0000C09269402D21,528F9FEDB410AD63,0850D1798FBB510E,FDF33D3F710DC46E,001DC70D1172ED0F,83A6F62935206CB6,8975BDF72606CC16,A6C5A62F2190678A,002C92548EE195A6,379DFD6285E21A07,C0FF1A4AC1A40F2F,C0919DDE2D898352,2BB57D07BE92B4F9,2F3206AEB8417607,B1417A97B20EC1A9,9F2913363C319996,000C61BBBCFB7BE5,094EB79A801327C3,01BF2F185D42BEF2,62B03F37529B92E3,A291261A12341820,7882B9E0D9B74686,FD7208388566E6E0,F9A5EAB1B984CF1C,00154B438A602A19,50CFD70C575B8559,39F270CA1580EED9,2F2B819DEB6F2059,8188188CADD7F666,9AD3D5B44D86B31D,5F5A1C6C39CC3C56,4175C0CE88A5B21D,003ED77B97466309,1A171C0D609D5ACF,A02B6AE3039865D5,5DD44A296C45AC5A,5B51F356362959F2,77A0ECAA31F9CD4D,55C4D6B9C6EEA4A4,54572AC849551AA2,001B34ACE7FB9EBF,27E26E11235FAB52,E53D8651570F7FDF,CBC7465E010DDEBB,E89F7BA302B95AC7,9DAA0E01B092AA5A,A9B8BC0B851D8ABA,5041C712651FE5ED,0024F707C1A7DAEE,A418A0648B7DC2C5,85EB6973635BCCCB,7AC86B35E75E3205,3437C65B391418AF,199B6F13454672D0,F2335F5338E352ED,C16FA6BC1FC35C55,001742DB961540DA,EA855BC3F2EB4893,4ECE98CE26989370,F88ADEB4E74234F7,AF52982CEF71FEA4,420C917CBB89D398,DF641318B91D9E25,9A3A5C58097638C0,0038F808F312971A,0FE5A674838AC5DC,F4E4621DDE20D697,77945F6116D8F7A3,03BFCE90BFE11E27,E50DAE9FCEC5605C,D097502FD34A48FC,1EF2A5C684EBB442,00162B0D07833553,ABC1C233076C8E68,F50715002C37EC58,2EF44116CB248317,83461C47697BA464,364441DAFE13B391,9C784055D57F6206,5674A74215313AE8,000D20BE55E6FDA9,160321FC94AC59D0,6DECA3818A8A3A86,342E776F925BE4CE,28527F1B1FD3A672,07404C88B3BEAE04,3145C8069B28D062,FFF0C558D1126727,003238EBAF4E24A2,FA455DAFFC2E9868,011B03F1C12BC369,8D3B780B4038B077,7BC200C75740793A,6729954E84591D56,AADA21894B636896,0F45345AD8E42B16,00154431E6D7C881,8A4E6E0FFF1AEA1D,F36D3A28824B4E17,AE72EFCD59BD888F,C390ABC66D58D7F7,0E6A8C425C793AD4,57BB783817530EB0,F42EF7586D86E954,0013836FD2CF7C1E,258C56CD53B72D2B,F2994C6637BFDACB,935D10B564BEA35E,0E780460518BF18E,FAA229B453E375B2,82EABFE7F5784878,0C81CA2C44191D73,000238C52D5AD1FE,CFBDB54BB4A77540,C2A4CFCF20F496FB,B4491F1730D41AB3,AC375063C95A24B7,596A1AFC2B48562A,5AE77B0C7F616E58,8A44012C8B34FF47,002451722D36B1CA,E5F23976E04A1691,AA9B1606DD24CD06,F3A7F6E14BAF9E10,9AC3D73455E65208,7F4E80BB8579926C,E118152488F0D907,2FB66DDE12D2799A,000D2E20B9AAF3B0,D7B3D06FDD6FB726,DEC9D8EA88AD51B0,D64F4891049C3B3C,5224AF507526C0AF,D3FC5C6553D47A2A,A8706293865BF5BC,786C3C24776B277F,0015D3D1C8F5F012,589B44C6CE0CFDAD,D3EDC49946049FEB,D7D018F4B45C0787,D76171CB5AECC7E3,5EFAAE568A1AE151,F045AFBDA5C97602,B1C8BBBD8AF5DEC5,0006F45EB44133C4,1210EA59278386B5,93BF02FC9B04FF78,BBB5BE6CC44BB611,59A30208E433231D,9F8F623EFECCF1C8,B132CA460B59E827,180C2C6D25737473,002D78812D51AB9B,03B89B445E9F4477,7ACDB88BF2447AA2,67A13B02AE136F26,38F716B747411635,5EAB673C266D261A,951971DC0DA15875,0B896CD746D313A0,0015AB3E7B022A04,B79877ED786E1BA6,0AD965AEA027AB09,FCB2E74E47688EAB,69EBD9BB8A71E504,EA718BE948CA496C,C3E8D54A038C553E,F89FF64AA72FBB1A,0014D7D7C112C18D,1E8EC2F8AF30B4C4,B86CCFC80B598822,A6792839E77EAC72,B347F99DDBE7C751,C68DA5EDA9AA9F20,F039649745AFDF5E,7AC05BFE6B532354,0011F9F33A2621D2,69AC833DF38FFAEE,C5006C364D313DEC,99672DF4796E5DEF,B4FE93E1BB783DF7,34BD4EB69F9B7915,7AB0AE81E8BF6AA2,1326FBCB69E93AD2,000C61EEC6FA58A4,E29F85AA49F5123F,F9C47EA460EA2FFC,B69F4B72FE634812,916009FD3D5C5BEE,34F277750A8380A5,775545C8B7CB2DB3,8950766698ADD781,002E6EE9EA799E18,399DCFB448279797,18E42B9EA826FA31,46E9BD977B778842,A869D85412A260F8,49F76E7C3A5FB63B,0F1470CCD628CA0A,7FC4A1AC93D10083,00006DAD5622E87A,4BF7D737A578666D,B90B844E1999BC66,0A10FD0DEDAD5A6F,ECD523A5D668F551,2D10BB4CDB35DF23,4C495111701871C9,F4D727EA616754AC,002D86A0BEDE4BC4,5FBCA1EBA30EF02A,1F6339344D458685,021D1550F556FD8A,6D3E97FF64310040,88E2C2D5D53F855D,8DD5506074F3B1EA,7C07B6944E40550D,00014ABE51B4F41B,BA6B877955C1F861,0528F6192A3E8144,4BAE8EB817B41D34,24C2ECAFB19D5BA1,230DCDBAC11C5FF8,D634A3CA3A8E3541,C9BF9E2235153E20,0001E572A8E890E0,08BEF187613D8870,412FB72309D130CD,548C6D7854E3DC34,D65C89685C69A933,1246BDBE6E705E0A,C5A3345B3F597352,DB8BD1D0A78664E9,0014658A7ABEB063,9B30AB02CBA60B08,5DFA9D31B4152BD9,3C338DBF8FC44595,CB70A0E0671A61F3,FDA3BA2177252E3C,5FD448A9D54471BA,38A16F293DC27D80,002214CB04BA7328,CEB460E5534DDBDD,7158909F7475B033,677CA1ACB1CE5206,BE8531B4E02C3091,7EE1AE3B32C4CF21,A62F36ED5F5E1BB4,BA2AFB1EE9B18D08,003AFA92219B78B0,41EEE535C2AB5727,20E3DA2D3C4E563D,E9B27121A4673317,E51B30D6B9C54A31,F9E7B74D30CE2876,CEC3FB291FAEDE39,AF7DE97A9A48473A,002340C564682292,04B9C88F53C7F0F5,D5EE0BA09284F5DF,E030E394857A4D32,62742C96CA2D6D01,1CBC854518FCD319,8BA0FDA3F84D7DA8,F8DF4BC7EF23EFDE,003D2B3F782BCC37,0C59978D263757FC,02B823618C648310,44E4CAE48A4255E6,B0D7687FB32F087F,5AEB9798865B6C33,8CDC8ED767A02AC7,7883CE0F4A8B835C,0039A0EB2A3ACDDD,378BEED62A747385,09A6C209D6651BBE,5E538C67806DF3FF,E78F2797A683C2E8,1A816BD17CA93236,223AB321D9076537,C7320333A5B97072,003663DE743AF622,15CA3C81664370E3,41E931A6BE4A7D0C,4A42E0313CCFCB2D,CF23642573159E1D,05FC5AE9F354F284,DD2B602173FEDEEF,41C7EE0307D4E537,00225516919E8C9B,45FB38E8E273B038,9CE028E48CEB57AD,FCD185CA6122B1CC,3A03444EAF44929B,2D1976BF88665783,506B74DE00F1481B,0CED93C4BAA297A6,000ED5A685FD4A8E,7D0F25F4A69F305D,D89CCE6FB8F841F2,EAE5808B91E7E895,D36017A482C3E3FF,788F37BCC0AD6803,94702330D93B0776,FABAF0F4894ACD30,00034CB56D4C3D40,22B5D3FECC8357BE,17CE239C1F6FD1BA,1DEC9A3102F07A38,6781AB27AFC29D5A,E2E655B522BFDDF5,5842B0B6F3F7E89D,A43D6C0597554EBD,001366B939DF6215,6F4548E09EA9246B,A3919BC49AAB3375,BCD2BBB2C633BF97,96C3D9E427022176,ED855B2B02145C06,3868CBF478271B1B,2168ADE8337526C5,0010CD9F3C0E7889,B002D2AD32A006F0,E720DA7DDDA4B69E,8160451E755382AD,41D3723C5C4BD54B,7E2DE83C1094D2F8,553937B5AB78D804,77A5B093B2785750,002C05F6CDDF9F20,89DAD0E3A2BD4DB9,6E8523D91C3D7045,B2E90E8ED7C63DEB,E5CAC106E8D3B12C,F4919F2EB0A34312,7A062ABE99FE7D33,E708096A3E7DDF68,00003E0F9C3F78F9,694AEB7C1C072442,76AEF9624713F6F5,AB3FC5E62F3D6517,2DE20C3A14B54ED4,5BF63E0FF7BC2743,5CC198D5C634654D,0D55F5A0962B8880,001FB4ABDC4CEA00,98D23A5EC21584D1,26528D7F2AB4E656,49C70E4DE21EF9A8,12B49A7767A6EC85,681AEA7001F74DF2,DDEB8EF435D89F64,2A412DE91C3EE59E,001A0E0FA5B97A7E,3F56FF5D6A42B09A,F4E819B331AF6946,B3AB37F4FF39C9B4,89F113EFE877F97C,30EC08DD9AAA568E,6E3781310596FC63,46EC7D9E5D5FA0F9,0032ACC13B50619D,2DF8902E97692C8F,EC0FBA14B8D1D02D,F5EB4135388C7F98,0B08D6180FE7F37C,1105C3B3A27DE407,266C58D67ED020B2,211424FC509D7E6D,000E61836245B3E9,08150E350F21AB6F,87B9554AFF4B36C2,5EB5C5F8994BDA53,A885EEE5ACDA5015,61F41DEAF1FE920B,1E459832901A5E94,DBFF19ED350DB585,001B3C1DE5408759,712F692453F98298,38C85F44912BA8DC,09F4CCF0CB906E77,E9D282E8434611C1,AB3A575D6DD63EAE,74AC8FB6D4523618,6F17D00AA1CAC1F1,001B86389A14F56B,FDC5EFBFBD7908F9,63452FCA430F996F,304762D98CF578D4,2E2D38B505773745,8884CB94B7EDE740,FA84ADDB73A85BD1,EB72111801B25CD2,00193EC11F5C9E49,D8A438BBE834079F,B1DC195204746AC9,04F138E81D49B343,6C5E7EA8E84CDF90,60C31ACBC1B4D669,4EC7CB160EAD74FB,3D088DCF2C49348E,000082BDACFD8DB4,C872B51B4EAC052A,17ECE8DBFA63F390,A8860CA673FE364C,D7BB23BCCA9B513F,E0AB32B56FB8FD22,1ACC56F68F0B7FBF,B2229DFE625A5B7D,0022CCF67C4000C4,80B45817486C5C3D,B550FF5712109C0C,81A54643405BF971,A03A52660E97C519,9D6D68D0A1BF8484,4E445A29D42E5B0F,4D4E1E88352687CF,0010370B5867843F,5E450D5313406AAE,5C33841E8B6ACF3C,04C7179C812F82EE,4A658C1D6EEBFF88,FB7A7EB419FEFE27,261ECBFB3D907D09,848D823B106279B4,00066304273CD73A,1E8551A6C99B8372,0C9FF4A99C8F551D,B16E23965063E349,DA2AC1D298A2634E,B2A606CBD9B682A3,AC8B1D3209762059,8A456E0F2D5C06EF,003DE974613291DC,F1EC5D3DD18AFF41,1A45B86F0EEC4439,01F5DCE5B1782B41,2DE83A5DD2D1FD93,07F54261A0AE9020,643FC2404CFCD12A,F6048D0E005CA199,0038E2E0D6E4368B,46608C0E591A9255,171FD17F72BC822B,3D3F5A1D3E848000,70DDAC9B15B5C926,346564B04C2F3EF5,179E143F8CBA3311,65A23099240ED5E7,003F0AF59045AB34,6711090D062B7FA9,BDA7F0A2A22DD6FA,FCF16C6FCBF60FED,23C6576C655AAC0E,02DF87CC0BC0BEAD,D87FE2DD06E95108,125B8087332C225E,001C5DB179C9D929,75C080566EB3715E,F73796E5E517A382,4AF471D6BE9DE5D7,4BE9DAFFECEA0244,962029011C4C2E2B,C171D4E47BC97673,97AE25259557056A,00066294234D0F09,97D2BA3F488B2C5B,ACBEC51163AD50EB,E7ED325698D5C782,8EDAB86843000678,653D2EC75F2ED91C,F4352C2E60665948,BA5B99370E47F917,0031F9F0BF87EC03,4F4B3EDE73967C4E,CB7977D39A325ECA,826D26DCF7190EFB,B075BB4234FB2B5C,72FB32C9DF8DECD9,6E2D9AA48FC4A49F,5CAA7D454BA63A83,00120BA306578525,A285A5CB0CB6E9E5,DB50BCDAA62EFB21,1DC95CF8F5AF970F,2691A51450DF31DB,171140247B3119FC,152B09DCD13BA632,8B1CC6C97DFB90D0,00360DA9F635A904,E4A67C964E5499A2,7DF893DFE66FFFE1,A3FCE93831DF2542,73471DF2DF09930C,B4891AE6D58C9AA6,68F8F00BA1089684,180230218B9D5E65,0023165F7473B817,6C300B0BF795A3F4,22173771E4649026,DA8E179AEF3B6684,D6D0D85F0640CC44,2B7BC5C1FEFD9ED0,375352C65755B4D5,2F98A49EAB69BF9C,0034FC6577466699,7DD4F4265A2A98EB,0E95BB9E6258076F,C5F7DB684B042F29,AD74B26CB3562FB5,C73F3E1A645A0840,ED56F86DB317212A,4D9849A6616811C7,001E1CAF90AF2BD8,B1B7EAD7ABC51F55,0FF49EF0BD3828A9,DEF2E2747DDF182F,17A55F4F0F29B93A,0E59E33270E9B2AD,9076B234A0A6C05F,13B9C9E1CBBCB502,00160B96D2D409AD,D3122EAC1C0E7973,2E24DAAA1CE79EC3,AE9D799704B0B1C8,08790E9A2242EAC7,48F95AF587E3C72B,0499C6153F608A26,B1EFC8C0C6C4E7F2,003CF87D80ABCFD4,7A6B8143095C66D7,A5B33190CECC5B7C,742025B90F12A949,C6AA6C256B3C2C5E,322F79642C8BB8C8,A1BF77C6E2D93AE7,8F07961D4D120FCB,00364C5685B598C1,4457FF922AFD1E56,79C97ADF4A7BED98,D504F1149D021364,4AE62013BB69D5B9,B473706635D8D2AE,A2BE07AD4E9014B5,2ABCFD897A3A4E28,002A9989167FC2BF,9442D6EA3662FDAE,0978CC2A1DAA18F7,CF1E3EE7C9AF81F9,8690196784677595,E25B954B7AC7022E,F1B040114285443E,6D7A839444E7A526,001D14441E2C7AE8,D353FAFDCA3DEDBE,63CF569EA407FACE,4261C8BEC54C7FA5,DEEAF28F6E52E148,BF62422E51E90A20,3128ADEF8DB36722,EEEE2408CDD9C055,001A1827A19531F5,2D0AF79D9A4C25B3,1B0A57F508804AC7,3583F2E9A715532D,01B6992455DF8874,9E69432B2D15950B,A7771006DAA4B6DC,F7E8245EF0FF1EB2,0015E892E365F06C,DDF35D146CBFD2A4,406896EBD14FF11A,820D61DC645C4F93,0C9687324FC8B30F,246F92FB02F03FFA,7D7631055771382A,4691CDFFCDCAC4CA,0003F674D9CFF611,8ECCE81582A1515B,1E8981C4A241F06C,7B662BB32BAF1B04,DD3DC601BACDC989,3A625D34D71B2AA2,5E280838D7AF61F5,9E9F438120F6111A,003C8D5A2DF1E113,76CBA6682147C7EE,9CBB2268A3839ABB,E42C8BB069D81D1A,6FE955AFC6F61F21,EE259B1116D8108E,87E0FB1EAAD91EE0,017A7C57A286283A,002ACE2A996D10F8,F7CBED43D780DDC1,F780B4A4673C0240,24196F0E06C7B453,6CEA41EF44A61051,3CD309DF6AEA8976,60CC4D801969741A,3EB415A38A08932E,00196A2815B0F476,481A7604E85D75A3,076E85A7EE729592,532246F25039D8FA,926C1737616451D7,98E3F6E84D1779C0,D7FDEE395EA8292E,0E86741630C078FD,00050CD640158148,2BCF306275B43E68,9EC7E5184E3C2E0B,2E59476D1C101E20,144C8824648624DB,677D1BDCCDB98239,FE093A2BC71FCBFC,911BCE32F0921D36,0034668A69263B9F,3ED8198AF18D8007,BDC7230EE4BFC2AA,C9F743C3E8C1E979,0103437EF3247EC1,5A40F36D7FDA5D3D,29A5E84AC706059E,FE251F4DEF96A6B2,0022BF383ABC8138,410EA507E81ABC19,B1A599413D2F4045,8719592C89C2C952,AFC73A1997DC02E8,45813E3B00DF56B0,406DA4074577AF62,D72C57FFCF0F3A01,00189247AA8BC8CB,ABE7764F27DD50C4,F2CCC95F47ED3C1C,337D5426339DCC6C,67163B15002B4A65,8CCE8549AE7059DF,91A712E461553E31,2CCB4D7E99E85494,0007BBB3D056CBEF,9B5A530D4B0BB77E,569526E79FDEE227,50601417AA4BEB69,E076A79EEB877EC7,366BE0AD32A786D1,599F39C160538D10,193CC9D9C7BA1867,000A0A54BA39685A,9636C266775A85F0,D1A1C52E70093062,218C1E63EF1BFBF4,A321E1296F1609E8,A77B0C2EF3BB22CD,ABBD2AD8908A4ED6,34FD45724A9354ED,00257D7A2781DA62,B2EC9B792AF64E0A,00003E652A7D9121,F1D880323BCDB186,09DDD9EF896D8346,01692077188F7CFE,E1B4F197916BD784,A76EA30DD135C96C,0027600B197EFA67,A41621E38742B572,30031A4DFA994251,61372CB250921847,C941C7CCD1374D7F,54D08F7E489B928B,65C9B53FEAB4195C,1DD13492BB651A32,00378474825D827E,C96965D9B22BFAB3,1925746103D34EED,773E45C5259D95C3,D452EAA4A55DCB41,440E85CA99A02504,39947E3C793573B1,1CF8337EF24C1FD5,0002A53E1FCDF250,34731D84565E522C,614E3285ECAA29A4,A69359C318FC555D,E887227942301B3B,EEE471540C5250E5,B42B710E7C6AB38A,5E4C1729C1FCF440,0006FD5EBB3FCC70,B3AA83C40520DF3D,DD31D68936F3A626,EBB03E2BDC5ED7A0,BDFE875A043C19EB,5CF3522DD3B1AF49,EBEAA49D8918D858,9C59C35A0CAAD700,002612057B929126,EFAFA83DAD0B821A,31D482440AAB0514,0343F2A2DE4C3560,F103C894D254F5B4,9E3ACE4C46AD7F15,81FD961556C3D962,F53F39CAD747DE8C,001684AF5822E9E5,1F090E95D1A2DA74,25EC96A1004898B7,F2E5BEEE6A4A4EB6,2C6A01187E0ADC99,F0BB63BE7BF1DD66,BD62B3DD922FB750,E1407C3D8F0DE1E7,00399C5A11897BF5,A75723D09B6088F7,806E57ED64891731,3B89B8D186196A79,837ED1CC215476C5,47BEC309AAE7938A,9AB9DE45B74B3CD6,89A5696B7066685D,000A59C2F39C3AE1,1C18F97B62713BAE,4701B0AA399336EA,2C8D1C3DF4DC3CEA,788136EC75FBA593,BE9813127DA8C22E,57B5B9C301D539C8,8323190AB9646DA2,002CD8DEFA5D2538,E24B3415482DE89D,ED2B8D364734B501,86770FD045737C8E,A82DFEA87A1BE92B,43669F1CE4DCB6BD,3427C44FC7843DF8,851B63B752231015,003A9B10E0D836DF,7DA65F70C17917F5,1FC01410BBE0D8C8,7B63970BD39304D2,5A2E8D29A684EB49,F4FB37D33DB386C5,46C9AB415C676DD9,8962ABEA74CB4474,000FF5EC27BC17FB,AA57AAAED9777BEE,B846FC29BB9A7550,D566D6D7010D4767,4CDCA4A95F3695DF,1A01E7BA50B6F88A,BB8182618A6A2499,5FF1693C9BC4A1D1,002A22E47407D0F0,5D16F69ED905EEE7,13BB4DB154015359,8AF72AC3E0080E80,017151801188D2EB,11D1192ADA155E13,B1B85897CC8B8F0B,9F75774C52C52DBC,0006376A6C891A32,242EDA6D43A7D4F9,4C4A18E40290B0A2,7E0A941FBF9D3781,24AB98E7E0B92BD9,EE2B279C64F6D854,8665C417FD84A830,B2719414E71CBC38,000B4F483F2ADACC,281D7B113032138D,AFE149DB6D743262,514FE78467C2ED02,DDD8A1DA01FDD025,0864E9E9BEDFBBDD,E511A9106959E305,3EE4352FD70D8808,003EDC5BA45C1246,96C21F33B145BD79,22288349828665D2,CAA20188CA902D0D,EC6F24B699914164,A42EAC9C162CB3A3,33D068677CF9FADA,31AD66ABEA325799,0031A85645E301F7,7F7408D36A3624AB,674E74F04B96151A,F7F292576957BD29,2C4FADD324DABF4E,6D267F918319C814,A658E8A312F5DBDF,B3AC8FEA699D1E48,00169F06FC5D269C,3113A764F6873BE4,5C56A4991572EEBB,5394BF758EC599D3,ED7D8A33C9025051,55298DC897C8BAC0,F416BF3B664BA221,9CBECC088576FCD9,003665F2F7729323,43DA95CDAF3EE516,DB1FAEBA8089F849,511A5E56640E9051,6436D19F23F5E9D7,184B9A5524FCCC3E,F980B2949F8971FF,34A510585D2F8D15,000237453B89CD4E,44F893BB77C53EA6,B0D974B916D1514F,A51E9823BD44DC02,99827B5910A667AC,40DC7AB42E8C1CD5,DEE4F4104C146CB2,B7910A8A7541C3A4,0033A8CAB7FE4951,1AC8DCCF60C78BB8,88DCDF1017916890,3ACE5588DD3CFCFD,F800BD03EA253671,600EC996A17A6A4F,8178F9C7F1C18486,86CBEEA0B9C5DB9D,00399BF87A318CEE,39463E2B194117FA,162455C170414D63,B8FA6D10F8B901DB,BF3351D83289E30A,AB583F856138EFB4,203D4CF133155842,4931461B540FF170,003F815D641C8E2E,F3E4C4CF24560090,2DC8CB63A5E09B58,E649F92A0426512C,EA6ED5FA895D3FEF,F17BB6EE9D8B7CFF,34E3BEAFE6A80706,0D05202850C27042,003D0E1C45DB559F,F7F106C698098E98,B65120A796004EF9,96D955AD122FC45C,1CAB9FECBF9356A0,7C7D1C11CD26EED0,464F9D3CF78C3366,024D1E0727410DB4,001F9BFD683694E3,B4025280831B527E,25FE12AC0B51A077,F1BB4E543599BCD4,39D43CFDBFA5DECA,7CB1911D233F44FA,CE52C4D308A8236A,018C8C31BE3F4967,003174E4E310CD9F,DED9514A01398AE5,168064A3AC583AEF,C7E177FA82D86578,D6BDA9D457A8CAC0,45816D76BB5C79FF,A9681490F1B31506,59ECB8F36B060A11,0011E6E02B6596D8,6555165F587D87F6,649851B742F7661B,10ED2D62B890FC4A,2F183CCD7C2AFC0E,606C2669DFE8A8EC,A16D933F96392899,6C3D595AB6ED24E0,00284846ACEA4895,A3CC0DC3AA2D876E,D8D4130D0F723074,3DB3A38F8E59241E,B4A1BAED5A631B0F,0E63507853672922,019070AF16BFBC8A,7183628B005447D0,000E940D811486F0,8A52A1EEA8D6480F,5A9843D3C5BDE5A0,DEE817BA2178065E,F5A22AD5FD528FC4,EC6EAA167DF42578,EEBEBEC331005520,0999AEA2795A9508,001CAE1A2A67F899,7E8352AB75E1A6D1,76E9E25DA2807022,AF5257258BB73A17,0EE3B632B7E2C8CC,FECE707BF7F0C711,297D08AA57E22926,79A60F5745561165,001B82AED92336A1,03279E56D2144C37,19537F6C099A0D0E,436CF69B7F88AAF3,CCD57E6F01C3689B,826303EF2815ECCF,889969D79C8E2CA6,4BEA7D5092756463,002A6FFD8B3E2819,0DB2A56A45B14EAA,5EB126924FC65F7E,255FEDF679C70A94,6C21F91F2E6329E6,F3E1D0BCEDEA35AE,F02BBF978217B9F4,C9E7C1D2AB7F0D62,00026855C03AD65E,67AFD394A5318AE4,0B83BAD0E0367888,50DE50A013C02499,2DF763D1117F45E1,98946B9D0C8DD0F7,EABE60A6D9C5DF17,E76D91CBCE1F670D,0013ECD929080B72,6250C5F6A3F8012B,F6783A22D8E7CB51,29CF63605A9E6B41,72AA7966A40A6204,4CE2E635B06B0399,77A542E2ABA9EE13,93926B889453DB1D,002963BF17466C0F,7989B11086A2BF7A,2397A3F2759C89FD,9D0EC4FA06DF7CE1,0D04F65C0326E6D3,76694ABD4C239045,EF79F8A3A1BFD282,396EBFDF82F499B4,003907765D32D90F,FA4D3FD4627089FD,DD337C0C7ED270E8,13FCE8A07CF69723,2CB3440D1AAA69C5,D1683985D0B60717,AF8C86558DE6AB42,ABCDE41523253E9B,000E3054BD4839A2,4F9D4FBEB9280C40,0F31DA1A6C3F88DE,E5BA7BAB07B83861,0695525A63A004DF,3D9F3D80BC99A3E1,A1EFB16F56BE4DAC,8AF108338084012A,001C6A14F7D4163F,E246BB1E2C137D86,54FA8184709AF794,E26ED2BDC4E59C04,F0029FB0339BD9EA,F2BE20B4F2AA60DE,E54A00B8C64C8EDC,CE889819B15538AC,00389DC9D88A0CEB,A45099D11244AF80,9C79E133542579C0,FA0CF3B5F1522119,8ECE916019E072BE,33EDE19F269F556F,FCE6EE905215DD48,80B3C560ED266E68,0009158E5EFF28F9,6333606709ECF11E,252B28B8D6FDF36F,983A8DFAA38C97C9,5251273050C3EAF8,4EEB1E062B16B114,0ACCA5FFA1CFDA7E,89DAEEF122FAFC6D,0009452193BBBE9F,FEA2E6E260E0332C,55C4AA4312099874,4A1320CE0EB470C6,A4A96C9D789C1F0F,E05E09FC8FD1D5FE,F9744FD41EB615CB,FD100C177D8A32E1,0015E459595A6D6C,3527325C70CC43E8,074E3E7B0E50E0D2,1EBF28CC61D82DF4,F492A817F3A00D36,6D2F79E17F7AFB90,943ED3F8216382C0,BCCB2EB61A1F2315,002DAF65AE366AD3,42B7F9CB463A2E57,25B99A9365907090,63D45C8868AFC22A,3D57F15EBAF07F8B,FE9CFE61DC55C65B,C98CE2E1510189D1,020B61F6B608DB14,003663E11557C77C,35C223DD4E4E266F,928C9F1EC844BE48,938691A9833DF143,A7203EDF04F65AD0,86E0728E119D42B7,946AB82C9ED557C5,BB549E13CE2D4003,000F57B3C1182DB5,E5158D7DE637304F,63C04BA93A072FA4,898CEBF156B49DDD,50AA9C49EC4C7F1F,3C376D5CE14B25C7,03786EF74A189854,4C0CFD5A140FDB18,00026696E5C0865C,BA3C3C6253400019,49212CC0E4507A6C,208E7E62B958E4EF,B0B0B416ECAD50C2,3A1049F783478F99,6AF2F675D3638E97,18B094D53570D56D,001776C02C25E691,AEA2270D7EE50AB2,1B13ADC681EFCD43,BD96F4E78330CDA0,3D7599B2CF14D6E6,7D1744E8803A07A5,DC6D045BBFB59FB1,0AC76C5F4AFA9F1E,0036097B67B720B6,C81D70614997F948,5D0DD7C1E3118C91,0B7A751E071536B8,677930B3AADEB97A,874E669BAF5A37D6,AB01E8E00C22BD52,246BD7F7171D5E30,0012402035C9F4FC,0536208AEFE68E31,F21D3ADB19F1B1BD,E6FFDB01E58C1716,DA02A5A1966293DC,90C863D5CA6AD651,78B41A31F1DBDF07,42F56075EDE7C16E,003622CBAAE5A3FA,DF31C90D214C420F,335184122419569D,98A01479D47C84C1,DFF0FAB04DF711C4,A78D1AA2B02B7FFC,CED3B1045A1804D9,DAB82E9063BC72E6,000AF99C477EE3DF,A849189082499C00,975DB0B3BB3600DB,552A10E3B8CC9219,E37ADDCD6719CA55,4C9E1E740F2EA6D4,97F683DB23532CD3,B791119E3E2FD236,00305281F8C9865F,82BB44D51B3F730A,12F4173B0BBC8E10,62E9E33E69C90C55,27CD7BA7E4981E7D,8C75645F955E447E,02D0156D1D5C05D9,7D0FBBA15F1430D7,0020BCAAAA73BDC4,303F9F5C8DF73340,1A4397686C1CABFE,34803E18B33CCAD8,2FE6AE8CD90D562C,BCEC15906DCD58CF,E23F0D8EEFD83049,820B18EAC95EBDA1,001D1644B87357A3,E7878B3570B19FCA,EEE173839407CC66,E27770C5DA5A8398,B572022108D582DD,A7FEAFEA84748EE5,36470A54E4B77DC5,3CA5542CA0EB6A73,00031C5FA9CAF373,326AD0E1BD493B7C,6C7EF1EA925FA1B9,293B7EEAF865ED59,A73575FECF6096FE,C7A527C01B24D302,EA9B35719C1DDBEB,C315984B0032447B,0008F236B82563A5,D68BF28784D7D499,76C107A54CFC5634,0D0B95B2BD7E7176,BE710EC637E50DB4,B6A15B402F398E55,6501AAC1285C95A2,0A5AB9FB8D0F2305,002CFAB222DB963A,07F2361CEA9D9114,491C93E7F1944533,B354D77B31A323E7,6D86751752FDF646,9F0F3DF037C28358,7C83D082C4E6C681,CE4D684A001E982D,0000E7E405D61203,C78A6A6C8AC87E6A,0FA674ED977BD31F,AF1C3B377AB3ADF7,5B01962637BBBAC7,0C9A4045BD7AD407,1FAA7ACB29AFC617,DD3CCA81071969B5,001BF978BCB83646,FABC2DC21956CDF1,D1A2EC33DD8758D2,8C285E5300072C1D,152F21DA0BF68F24,D0BAB2D4774338DF,C88F95FD333EEDCA,C8D22F0B67853791,000DA334445E8213,57DB5DFA22B5658C,0BF8137BD8C711BA,8E7DB54C2711A167,B86F2362BF9F3743,94CF01C30756BEAC,B59F7ED6D46F8C19,1968FA6DB32DC15B,00065349BB9F43E1,72EFD999487613DE,566785A44367DD9C,7D1509365408C1A3,F3D20E5774F04B96,2AE41A57FDA3D1AF,052360B4B3BEB2FE,9D21615DDD319593,002A46C4082760A7,B587934E44ABA8D7,2085F5F1A42D0BB4,0836CC45E4202632,7A7C1A39FEA8D660,2CB70B50B67B687A,1E3499052CA4C4BF,30E5A5DCA255E181,000DD61584933D12,0B2A4974B3F39265,02C1633941AAFB5D,5456DD416DED285F,9BD1EA73CF963851,16EC97A93D84BB03,EC5B0592327E762E,8855DDF00469B52F,0011607D0DD5EEE8,A1AE37C139A6482C,81204F98F6A966F9,6569047377A58423,95D8C72FBFAF9276,B03E1AB53C086D10,80E459A385D3F7E9,02D1A5134CC35BF6,002F730A4D5EE811,9DB740A11386F5A3,7BB37EE4FC931FD0,FECDA29C86038E5A,252E6447572DD28A,6306A3C6C9FC5F60,64AF970975AFE16B,9116D24E5FA237EA,000B3035C9A3F4A9,0C28DDE9318F80F9,AAC6246A17A01FF1,1BD05716745F4142,FA8561F16EEAE6C0,4B797482DF82E16F,5ED21229D842E355,CC94054F5A9BFF75,001266146076C1F8,FB98D47CE8D15917,43361EA7E25C896C,08A2E0B9D832DFA5,96A6A97EFBBD6AAA,4AB2DC6983B43E64,85E38D7815347F4A,89C95FF432F3E919,0017662916D0C443,209AA5F950DC1D9D,8C18F3AF7047490C,07B04261F4DD6165,2A609A98DCF31334,9B300FCFBBA6262F,D751A4005DA58B3A,71F0214F8685C293,00084664CB5CC1E5,9A19D8E965611259,07D27EF0DAC812E3,A0A70F4D45375DEE,575E80FA84A87DC2,957CCF46EF49EEBD,80B5E471BC9C30B1,FB622F7F44394333,0030D1BCD52A3301,4B71F4AF2565A838,1B2200754FCB034C,40DADAF0A822A41A,CF55F3391283996D,711970DD1ABA574C,195448DDA97AA080,7398936649BA4116,0024B2DB95EB0681,D8C9540186D1F5BC,8E3B1CE9DC51D285,62A4C3ACB1CA405B,4B74322EEE6A70F0,5D01DCF3A963B4BE,75BF198AC8B86CD4,D96491538A23D258,00304544AC6CC421,48576B9339D30DDD,CEBB102115F7146B,574F8DE1C550CD4C,016D21F216014427,46F11D754FA73F69,11077B8CCC3DB38A,5C605AC26364F3EE,0009BE95982B5789,7A8831E0518F1937,0EE6F03943BE2015,5D324212EBCB6F9A,6BDCAEC56B2B2E5C,30CB9756795F4A52,5E64829162183A8C,66EF1AE3C2DD5636,00329DE1734AC5BA,6D2D4A083BDE5E45,DC3298815EBCF052,B4E6DE229B00B12A,59C71CE164E99CBA,42624F0F4A414A15,96C2FFCA5DC86970,059636E360DE3188,0037176F2B1E1368,DD3E10291143497E,7BD8D6DCDC53B058,FD4BBF9BC48F78B8,C3BBFD1EFAB058F4,33E4DD603DD83B40,6C7F9BCA8D1109FF,337C3D82F0E48DEB,00250FEF077F47EA,051253087E2596FD,9FEAB8A3FE238DD2,B0538A1413A66265,C1F7AA3E29D69344,2F16D71305EB6C51,6BD57938265E4B15,88005E15D8FD2D50,002FCF7847A96027,1CB4B3588BB0CE8F,D113F7B3E4D5E896,B0232BD6812887AB,9702E15504B32969,D20997807B2A4403,DF0B1D5028BDE381,8282BC72B5949E47,0030F59086A7B500,2A3DAD5C56A6635B,880B8E13EC33FEE7,D77EF886726D6B41,9C211B761D0F30D4,C9FB0DC653878C52,AF85F1C45E56B64E,18B88203DAE605E4,003A65BFFE67A5BF,FB7E70CAE97607B0,C04DB25D10AC4298,D0861C265FD4A244,6FDBCB9A3504FB58,CB803ECF2A999BD5,9C4A6843184BE9D0,DF6609EB095BEEDD,0038AC2EE4275122,2E2F6C61D50FD207,07CF3C97913483D8,D67CF7882A7117EB,D3D6CDA043D30B7B,F720D7883C4E6267,2DEA024C1BB0A013,153291D814466951,000CAD86EA499ECF,1C7B35A587BDA70A,D25F16FE6B07C69A,B2F0906E30E7FA8E,C370DA02A76C7B72,1455A1AB3E1C3C79,148A6A37758C8537,7E26984B3B8AF708,002D8E5342208238,0273F5B15276E9B5,A3B4149AB8FF9C90,D558E56A3F4610A3,810B120D47E46317,2D9291965D36DC6A,31BE5A24B569F02C,012E08F0D93363C6,00076375B8BD6602,2DBF495738F0B202,3A255B6486AB8CE6,37B494E517DA9B0A,05FED127DDCBA6D7,BBBB71F8FCBC00E8,C36D8D3D686EE7CE,FE439CA8D4C9BAC8,003F3C79B539BD55,4CDD7D04DA69E22F,78EB3AB42AD337CC,871E51D437C7CAFD,2BC2A6B88DD8078D,89C713A5EBEF5C0F,99D709C6C18AF827,989F88D86C53E771,003A0EB288968376,89644F5871EF15CF,A7260E250C896478,894096DFBD2711FD,0D8DF64C2A661B90,F6EFBFD04AB172ED,3F0B0B0EC30498E5,232BAF062D099715,001DF751E638A59B,4C39BBC8811F9839,286F6A144C60C89B,1A538568E3552BAC,ECA7BD34A3C93078,20678B80BD6D15AF,F9321DA74F4AE7E0,9D18B9D3F523295D,0031DD675719299B,7D7BDF6A8AB970BC,5AD2D4EF7AB0CC08,273F140E9C49169C,D32DD543F9700FAB,10F67C02CF803FB4,969FEA0EDC643BC5,242E1A4FD6D5B4D6,000FAF845B7D66CC,D3CDADD1B452887A,DF30127C19C273CC,A5762E4A95FFD30A,6C79A880C85E0E0B,55D592BA24262315,B5D0BB7C64E871B7,5A6DFED2744C4867,001AC8479798BA13,110874CBD4BA8118,51104D91F4D9AA04,F82F7B62465E3B89,8829411A288F1871,139BA183743CFC76,A5C38F72A3C34560,74D54024A3CA6E99,0015E3762BA4C9EA,05868C2334921704,6259DCFDA62680B1,F676613E96DF9311,9FFF031BEF3B142C,87B315D1DDC9FF8F,94045DF865738EEA,27002D09CAE47E9B,003F3396CF507291,B95CC1898F2E566E,A07CA85BF483E6F6,15B634C440EEB06F,409E722B1F389E7A,C067C13452BE65CA,7CDE5C5AAE84EB4A,B133781E200F98AF,003093BCAD401FB5,2DD85296CD59145B,3DF5ED55EECF2332,14465D97DC26D406,6B6FC3792ACEDCCF,8E23DF94086EEFE4,5FF7D7C3517A8EDB,EADBC58E1ABB0536,00073D3B97D42BF9,93BDD43232F40899,93FD7125072E6326,D372143EAECA5AB3,C73A379E7DB26369,024B02B386916AA5,EA06F01272626C74,0C6705842403F841,0007D1A593EF00BF,0840C6BAF457826D,7E74C673355DF9B2,D30A2F879E541C08,11B1DDA910583688,631BEDB02BEC4D05,5BA8DC07BBB120C4,B32E784FBC024602,0027331C08D9EF02,1A048A8473532E17,4DDD6648DE4BE9B3,0CAEC5B2E0ED1A70,7D7C201F9A701196,D7A3193D2975DCA6,46F7C80D6F0385D9,F78867F5AC7A2ACB,000B00A55F9EB4BF,8737B0E57C183B82,A660395C5C026B41,29E4C7D82451AC1D,C5D70EC2F43CD1D5,60CD216736EB5991,47633A1DCA9EA487,1A7AA431EB8C82DA,002D911E08CDD348,B79E98B7CF3147CF,AB3DDF80287F6126,98F00326F62FE119,EDC07174269E95E3,76FB085B42157714,9237584048256AAC,82787E4D4497015D,002F59EADB4B5495,4275A1AEF46ED598,5ABFC7EE980AA02E,3FB2692D7698DD5B,5F22ACBDAF8ADE50,E227F4EF84216BA8,8E04A2E3547F715F,FC758593BCBB96BC,00362615F14517F7,019C81CF13B178FB,22CE773B7C56A5E9,24071F33B98B83DC,C33D9A19A14E7F77,60C5048CA2F07F01,E39E2BC0C4D9FB85,E82E5AA80E3F15E2,0035409C02AC4A2D,CD1DBDA4D1E3DE51,97EF02D2BC43B1C1,057ACA88DD326975,D9CBDFC9AAE6D27E,C5C8532C28ADED33,A847DF62018A43D5,CBAE833D809BFBE8,001A763C3949A462,3AEF28A10311031E,6B5F7A3E08101BB2,099EB964AB986359,BEB61CC451394A67,63194041941F6F59,9376FAB7B2A8C5A5,892B388DEE456D8C,0030119ED5824645,52A8A3941385226F,BB99DFDB75A1B27F,5D26542BB525A3F5,05082183BB2667A4,87C6A35C25CA2FDD,18221DA750C8FD69,1F4537414C2E2F00,0018547ED6072593,DD1FE81E88BF3802,1636DB85D04B784A,82BFC46DF50BB618,3808D2205D00BD38,7DF997E493B3762D,9F2E002C978BC19B,5577CA1A862E28D2,00251773D39A1578,E9D69FA59DE609B2,CC9398E676F63B74,54E2A7E6F70A4456,2380EABCCD0AAD97,85B8E7B1BED3EEFA,BF384881C80C034C,183B8FD37945848F,001699C96E7B1996,CC3FEC7BE121B39E,66F27986E9549BF4,A0F1C382490CEDE8,3D1C3C7476BFB815,965F956FE08DD536,1C36CF9E209C82CF,AB611319982E779C,0013F2197795F07B,D5269BE6C9E2EAC9,0F778351D4F41DAA,2B4C9EB1F416A28A,F783A474764AA178,675169C5607E8C56,7075F7D24E0CB01F,08BF037208FC8B1F,0018A6BBC6B30F71,8BF66E9B977EB4DD,158A5BB1AF886AC5,AA91857E854F7A7E,934A7211EF08428C,A0BA3FB3E9DE325A,D1D8937F78DD3315,5EAB35CA1A52A654,0009B028F9E2CB6E,8BA2D74A21D41735,580428B2D395589F,79C2B470F30D9DD3,D4ABEA14614DBFDB,7EDD4373877BC455,1745AE76E8D70162,E3C7D831641A6E2D,003407513C7972B2,2F5F53871A35890A,CA2E0A4D130AEFA7,A9CD8C8B0CE8B13F,E53E7A768DBDB8C6,12C5CB8475562662,B90E25D75142F9C1,30928F51E2B1BF3F,0002991A68FBCA10,26F877F005FF4FE9,F229C5E4F18F0C4F,B3955C21103A857E,55DB657605A1FB35,242DC4519DB16EB4,8740B3886961C014,160671159F637EC5,002EC41F1A99C4E6,72AE7ACF64F5458D,E9D3E2F0C4ACF52A,9C6DB3DA6AF8A698,9FA7C9DC2AF1F9D6,CA767300DE287CF1,80A9A25F1C56FBEC,47497AB06A672A92,002952164973C48A,12FE772C01BDB023,E528007C8100F8C1,D48942CB4796F3EC,15F580C57E51C658,BACD95A58047B5B4,99A6674D111429A7,D718928614BF0E98,003D5679333033AA,1A8B26227F509EA8,A500CB9830E39E3B,BEA76415C2E2A858,1BC00EADD2D598D6,C41993CD7A987742,B1D74C80F3CEEDFA,02E86B8A6D1A03A9,00157C26B37ACCCA,5B29CCC22A38AADA,528EBA81B6C43D1A,A73D817B6D4DD00F,60502AC03F1B86F6,D21C0D19F950F96A,7C16A6DB5A1EB524,B5DBA7E2AB7B1BCB,003C62E2F1BDA4C8,8747AB1A07EF88FA,E9ABF840BA951F19,69328A91D4609024,BD3B335D6E73BE1B,930CCB39308DADBB,96C78061F64BBF69,6076750328C3F00B,003F26AB6A633969,F47011204DA4B26A,247D7E5DABBBB6C1,49A88A3DA0AFF1A8,601D526AD587C972,23B6AAB5EF720A2D,796CCC5B053C4C1E,4E0F9739F0FDCC94,000C51F61F793154,0077D76D5F1844AB,38B22CCC3469B692,240D715AC43107B3,D9DF77519BFF94E0,9DF3FE075C1EC624,11E0911825729626,7509061407B9B8C7,000A599E3E379B43,FE8435D5D4A95BD7,7ABC567B032F3D81,2C9F1E735580B8B6,1FF54D44342E3BC4,7AFAB6E3C3E9A8EA,CC67286A9B6F9890,867446856C78D646,00199F1480305963,7BB7D02F6E3296D1,0C6FAE1823FE54BB,8EC24279E0F3EE19,A6692BE811343550,E90952071B17522F,D519F4AC4C828209,E7063A6AA81FB219,00226C8490CB9914,0659C2242706E1CB,69BD16A95959356D,3A5571D7E80CEF15,5CF56D79A89ADA48,47C48EB2B5E67782,4101DD53C73E5D66,294421761888002B,003BD17B13338614,C1987D87ADD9E47F,D48F3EA5A587522C,4C555B32A6B72504,88DB17D1AFBFA84A,F70E732CEB5AED26,C06AD8DAD3D9C89B,5561F4E98542AE8D,0001993DEB60FE10,63FB0F8608CE3162,75CC6565D8C4A76A,8BB1B1438B633A85,D5342FD01BB4D881,8DB6C8CC0999F948,79C61FF7AA9B7A95,B90DE272C90CBE24,002B8DA3B5E4B8FC,04074B90F593058C,E6F9FE5FB5C6CFD3,80749C9104612DB3,AC79EE3FD29EFBD6,CDC30CBD40629776,1B20C22E98DFC355,AEA51AAD139EC0DB,0000C61D39921122,647DB3D6E1AE4C70,E26427E89F6E2ABC,397EA16DD46908AC,26D4C2F40D8DDB60,E2933E197BF2CDB8,9C37BE908E1C5606,661A0407A3C50A80,001351E0E97A2FE3,D131CC1D4A625E8A,69C2B478AD49F635,5557C5772C1E742E,869B095AF8A108FE,636DFEDEE7092D65,4E590F5645DE5F0C,454FA6F136762E56,003FFB04ADDE037E,B3D7088220D6923F,664D9DBE430718FC,D07FBE866C36BF37,C2BA8CD570DDEB57,F5023CF3F07C68E1,8C3D7FDD257D39E2,CE5C94AA42C0391D,003D489991B9E4F0,BF5C9D2660BF78EE,3C29F443A8D4416D,5BD08E54942B3540,69E5B42D5AF8570B,D1AF1612182AEDFA,DB2A5C1DC7055103,346D74553ACF4560,0013D8B651CA5B3C,CA3EFE0221AE079E,575AF3BC609F50CF,9AE122C436A81154,580CD2FACBB97C51,AB29856BADEE1090,E6F0DA1058CA1C07,732F232E4F374047,00302B47DEF324AB,76EB34AE7E7798E0,A3D5D5CD265C9E28,5B2107027CA190D5,8187E37D635606AC,32B93C75CBC7E1E5,BB86D7D012DC3FF8,1AC08E89409E0024,002B97E6191EB066,19807076D743D602,F3335A29E11D5510,B8CF2A3E3A1DAF26,640EC36904FC75BD,45E96664FBE508DB,A643F6B5933FFEF7,B730BAF0AD72DFF1,003F53C1B89E3849,89229232AAA46700,577DF23C56B0B153,062DDD4A447C58E1,2608CAC48B4311C4,8D3BCD3FFA94130C,59F76ECE6C16E34C,CD107BF39804E9ED,0000D256294FA96C,A06B5854CA8A2981,EF3CA61FEB102D0A,80890B9487926B62,E3FCFDF1ED721E58,0C80E260B233765F,E5BAA60162C70164,06CE81D587975370,003A7AFE165DF124,8020D4C0404EA656,6B72345C1D5DBEBD,5ADAB785550EA5BF,7CCB05C8E48DFEA0,734703713647CEE3,DD78F0686F8500C1,85824B050130278E,003CF17032BFCC38,85D994CC3C2FD700,3E402BF2E322D7F5,5DCE37CB6564C60D,EF80C8E177F30680,9BDE1AC9EB998F7B,D85E975E0162A03D,0B72EEE2786B5843,0024B17A2C5CEF6B,E61E7308AFF6BEBB,E46091BA455E131A,4AC7CA5DBD2F09C9,12E8606B3D7909C7,775FB3598B0209F2,D1887AC60F2088CF,3E1C4BD0A35CCBF0,0034D68B292671D0,6C81C3A6557899BB,412C6988F49598B8,23880CF201D4DBD4,2FB648A5632F97CC,925C05FF7A3C97A1,871E46AAD16739CF,C362431249935FBB,003DECD67190B5D7,C66AB00AA6522712,453D19160494709C,30126342DD70C293,FF960677B4D69861,F01BF81977F958E0,ED0656D4D928CA6C,0E9E1A7E1C05C074,001D405764450312,763F3392B5049352,D3CD348D56BDEC1F,FF1F0B428C0DF6C7,0301625CE1BBC9CE,2EE8B881D4F9E14D,A76270DC126C55D0,120F061D335DA895,001987FACB9FB9E3,6A2D0C38804160CF,13D5B884FC9EE4CE,6C730233D65918BD,8CE7AA688409E3BE,88373BC0D03E9986,4F1A68278277849A,971D22091653D436,00385F27EDC1FE12,162ADB1E1B84DFE9,E75A5BAF9F9F2699,7F54648D57FCB25E,B71D1CDB55220756,42275543CBF702EC,4FEC2AD9B2D20890,04824AF6BF5BB708,0012430EDDE4618A,E102BBED6A11081A,B8D8E570EC5E09FD,7680C744F7ED98FF,068C9C067EF26FDA,304371E4721E9B70,E61EFE93735871BA,E7811D4248DAF637,002BF2C6FCD62A67,893247F31ED9D4D4,124C54902E4B12B9,2A16E97DB9DF542D,6207314974153983,45476212DD568A29,33ABF8F12679A40C,6347914F09C8E90C,00145E24F9206428,E630F97E0FD977DC,FC34FB8186572DD5,6E4536855DF559E5,93CD2F2335E15F19,19A83F5781DE3CF1,EE4ECA4FA8BC40EE,6EB84CE7A5B506A4,0038B80DB41131E7,2CB4A095B56DA57C,5CE1C6B88488D351,E9C3EDFDCA6D6106,227C8D501F1A4BCB,DC46ED9448B9331C,153888CFE6D83518,CFD840CF7F6E305D,00034E399D4CCDD5,433EE771A6F366CA,9E38B9C413BAAF6A,D66B478C93229FCB,998025A9925A74C2,B5580513BC2C5C83,89F27D4062A82929,C3BF15455EA534CC,003D09DD2F6CC5F9,532F6D4151B69674,D49C34C7A06997F3,415A73E7566E4847,F9F250401E845650,C261BAA1A85F4FF9,C65A400167E6E5DF,9E4457FA4C781ECB,00368C65BE3DCA3E,06C0D8CAEFC7787D,FFA9FA213381A073,C4F4CC6156D282F1,723F322D0C082281,EFEF0F6B64E32EFC,2D555614B73840C9,78F267E17274A3CC,00003CF9E0A5E344,351380FF6A80C87B,FD2DABE3B30BB42D,3BA737FFA509EE24,B747CA231B5F8300,5C0EB343A2CE4751,9A7CB27D945323D9,94604B55423BD1B2,002150042C0B6BC0,C4CCC44DD3FDF08B,6490590085318A69,190121A64C72E7F9,6316C0FED64BF49B,F4D4A31D550EF4F2,1FDD822C5F17C06F,DF2F687916F9A9FC,0037D2CDF408E9A5,596A44AC49ACF509,9137396F0E9340DF,BC158DE542EF9432,DC7118D1D9E5B007,EB0AA9CB32347B8B,7526956D7317C345,DA9AE49F8C1EE691,00192C09F2F7D7C0,24845BEAFB0A7F97,5B41FDED87A0ABF5,D052161B358989FD,3ED784250B4ACD4E,EB33EF9E06C7C7BC,423F258EDAD620D8,C6EADC9A5FC68251,00289A2EC811EB95,74189D752B043EA5,A105046F46CC7825,F28B628276C5DF69,2078FA8A5397B2AB,5EC4071FFC5A2A06,A2AA28A5BFE407B9,09E596B73F43FC9F,002EB231DBAF4E07,29A13577D61B1B0E,B2EAB54981068AE4,FCC3DB65F3A179E6,C504A2D26B0F34FF,EA309D388EC40E24,6A017728DE6E991A,9FEE87284C4E0FD2,0003D28DDD00B064,84A0EAB68ABBE9A4,1D88DB37DA6CEE4B,946E259878E53524,9518FBD01D3EA195,0C9B73F5DB3BDDFC,90F1C48757B47C3A,E15AD5F398C4ADB5,0002FD5CC5E39A45,CB7D47C268362D68,394D633570225332,379995240BCE528F,282C22F61081AAA0,848AD01C3A32EB5F,FA69C5DD8058C73E,B2433FB7011A2242,0034791F0809F314,C98DC3EDFE2DDBB7,3BF7A6F15902D9DE,6014319DE0C84379,9487BD4196AB79EB,31BAFBEFE94D5D02,2AB6C7A2EFA4C099,C18E2102056DA154,001BAA668368571C,732A96C9188A1F60,59F3C179EA54FF7A,2E8B28CA1FE77F4E,49F70F0EC0280853,1068F010EA49ACB8,FB97C7A5D4E231AB,12AF8508FE915727,002D48FBB897F668,5EFA75CE5AE0909A,B4E020EBECD6DA2B,F491274029A58A4F,C932BD8B08D59759,B0C24E968DD77C03,0602118D624B6840,7D258D80D3707E36,001FA08E0F8B63BC,B1FC0D76F374ED62,45B51024965E6BAE,67CF255AED86310E,B1ABD8083916A12E,21814259ED3A7AFC,CB53F114B20EA70C,C4C131AAB19B27D7,00028EA1F2D4DA5B,8514C25FF538C498,CD9566D382F3B331,A0F4B9DE88F43A5F,6F80371CDDF89DE2,0FAF96553114CAAA,54A6592348B06E2F,FD40A27A917E8562,0016EE6CA3130A38,5A8DAC6B4836A714,93741D92C263DDFD,535FE995C5E10EB7,53FA7430EE258488,7AD09CCC0C83DCF5,E68E684B71061388,EB9CE39EFCAF8678,003C04A2ED69FEAD,BC6BB7ED64D37AA8,395FF815093A88A4,788BCB140BFD56CC,C58BFF888952644C,7410708F4B5E27F8,38234520E57A7505,0662F910D87D1F75,000ECDFE240F432D,A618D5F5C0935F55,33B37A90AC341BB7,6E0EF8BCAA82AE88,A6145152303238AA,634EDECB6CC13646,C50F69642B430605,F12B74EF2170878D,002D7A870F7E2040,DC2D5D17D3E40579,E2C192570890BEDC,5B9D9F0DAB69B393,E3706F089309EBFD,DCE0F5C263E7FAF6,BBC2D8342C361105,15B754B888D9ED3E,00269077EA5EB54C,8DFC9F6231E24BE4,5836316C5885C65F,CD1E106D1C9E770D,D1E4B87D01BB9F6C,DA25BBB525209FC5,9644AFB554843B25,73C012D81A8329BB,001F940BDF8939CB,6A5F43571733A809,EA4F47B4EA04910C,037A991EDE285D1F,4492DED94A8A556C,5CBC4C4A4AB4C7F2,AC242CF3D5543202,945A4E5693F0BC88,0025EC2BA83FE289,22B229AFCCB2123E,BAD115654D21E5D1,949C2D56603447B0,2A5BA988CF15FD56,7CA4540980C8FA06,CE0AACD6F8CBE745,7561BFE9227F5A8C,00126A6C2A940399,9B29C976B3B5B4E4,4E01099EC3DABB8D,78D42CEAB68F71AF,5149072AEE5E1E19,B0F7F871C08EB09C,CE21B7589BCB308D,35BE6529BB0C0244,000423BE1582B831,293D1D0C30A13333,4AE4F39F6C627E27,93E9B3A00E695EAA,7FA0B5E287C71F5A,5FC65DB7774CB5BC,0AFB30698543AB76,D223029CF0585480,002E420F8335AB2C,2AAC4030F40FB3A4,FA5BA10166461DC6,6A8EBAE25022A987,61115A04CE509B5E,BD496EAD83F6AA4B,532B13B8AEA43C7B,2F0DEA4433B29461,00191C03A36E06FE,E5F891A79F0C0172,AC938665391AB674,1AC01709B61C2709,8095780F80839720,B175DFE1A4318DA4,6BEFE6F9EFB40FE0,909546D00803A9BE,0014C24C66385A6B,B5C67109F89D5DC7,970301339C58A79A,2E3C3F6CD0D4B15B,AC616CA240140C64,016F7F9FEB6C0A27,F0DA9820D7BE5F85,60C63BA3C4A6E1AA,003EB822CB502871,267ED0D094FCD3AB,01DC28990DFBCF50,C9AFB2D9FF777EF9,2FE53A0280AFB06A,0B2F625E2E38F647,592C28C2D78FF479,1D85BC44EBDDE8AB,003323245354CD9F,041F5A57D3918B24,312280CC1A3B5210,FFC57852908AE9AF,FBD64A54A6B0FBAF,DF75E77B4A13CE0E,8B9613549F3E5A64,40B0E0BBB997AC8B,0037A8BEAE80DFC6,15F58C2F537214A9,DCF357BDD718481B,86212914EECFAF9E,7984926967D8F60E,0010C7345AFA4E5E,502AD079803A187D,06D126CA2CB0E69B,003E72955D8B2A88,612734EDB5430F56,83F357DDC70E973E,CEE24C685C3DD02F,0613718C614A1FF4,DE866FA9EC599700,992207C5229DE061,12BCAA5D2D252DED,003CA2FAEE04C9FF,86D90F5B96299D77,EE299DDF54BC0973,59F25DFAC36DF867,F95544EE2800948B,76010A9CAAC73473,46FCBAF5CFD02D03,AAD3BB16D61DA44B,0012F9141B202F45,65DB947EFFAAE7B4,C93A9A539E309AE9,10520B2D66213764,5073ADEE9339EBBD,D492341D1416F827,D2D27BFC51D47D16,1C71A13D19F7855A,0033355319FDF0A7,B2886E2FD8318121,0361DAE7EC098C33,AF6D94933D18A73F,FDDE4F13974A0A65,403F4E4DCA0E7971,E6B2FDA25BF1A615,88D45924E555BF5E,002746D5C5F43565,D9D0D53F823035A5,B2ACC546DE126B78,89B29892AEDEC4CC,13DBD38D18486674,5F1DF664F87C598F,7F97F25DED34DE4A,6263E5576488EE8B,0036DF12876093E8,D5C58AA21D44BFCC,907998A5599E47A1,E7C15E7AEF12C781,FE58E93D6D125D02,F94ECB85970CC914,453481B32939B20D,CAC00F43B3AA06D6,00377690E1F764B3,DA72022427F041CE,6EB378FBAC37D0F5,B645385C3D0053B7,27E455640ED780BD,E9703C0014A49E3F,ED6EBC437870EAD8,8201734F45A3BE8F,0030A68B36D6A7E8,6170674E0853767F,A0F90B45A04FDCFA,208BF2EE8D542C73,6127D65CEB1847ED,D258BFE50E8AD25F,B4E75C92AD6C2964,F948F7EB4DD2106A,001EC62FF1492470,38FF08FA62C1C2FF,08AC6CD3E26794FF,95FC6C5A22121758,BD5DD3D60E2AE823,21375112C7F30F42,5A510F30D1D8D524,40385C6DCE6E620B,002B2DD6FDA6DD38,2D8765EF84153981,A60D76275BAA8BF5,809404E9AB1513DD,9FD654599CAB6A91,D1C3A085F42A5A7C,0047A676B79CF10D,43EC701882E27B2F,000295B10A20DB0A,6E8F2461B53AC815,42BF51B1B9985705,65CCDB2ED56CA3B6,BD8B7ED366B18435,B8FE78D830CE0F8D,01E801A50C8703F4,936A27E8095744BB,000EB36AF4ACF2C6,0A430B1461AA9F6A,A046690D79BBF971,48FFB005A31F82F4,6E6C0F92EDD806D0,AFBD6CDEF0EF3D37,A443BD87004517C4,7D7206849BC296B1,002537BF70B796B6,50336938E944C13A,3BD3EAA6433F743F,575B35A9269D7B83,D7910F1CEB310CFB,1D1D6E5CF30D12C7,DC84E2193040EC00,E5AF1D183E453592,002D0E6CF413E1B1,CDA679B4C41B7C97,97D3741A7CDB7BBE,5C2CAE3A86DFFA96,C73E77F1975F7C38,441B30E2ABDC8EEA,51638AC3B7B12B6D,567A76A547A286C2,002DEAA8C90D3E18,645E3171A8C1D004,1BD32273ECEFCE60,D25F64C96BCA4A70,4209B0F322748A6D,64F0AA6AEBEB404F,D4E262EF6FE2574B,7ED82242D1647A38,002F5DC07DB289A9,BA539DBAFF2F3539,36CF7174BCC75CA8,89C809D917C5A8CF,25ED20BE1D178387,3F732C161DA1EF73,8CC6F7D852F677D3,FD79E04AC12CB055,0027F9F275CF71A4,3D9C09490F061F80,FEDB056997179250,A1277F801C4EB828,71BC5FD5B424885C,34D025FC84935D33,8CD710883918E185,266A7E0F094C29E1,0030B53EA82D20F5,B550076E967D12EE,0FCF0BECD9EEC395,5590902D535ECF9F,B0B72AE177FB044F,E495ED3932E84083,D3079DF10CFAAF0C,2540BA8FEF5D07CA,002539134EECF723,C08C6BF910A28076,E9149522762DC577,616714E287ED361B,1EFC33DC90B876A0,D43F3A00E41184AA,676C38AB53B2D896,1F34CFE97A7DB035,003D2BC2E220E13F,0DD903CD9C11823D,F5D4BB883E4DB181,6FD2DD0BB2DC63A7,ED15E59997C9AB22,D65EF4EB4ECCA763,68CD84FEF12CA458,3989A062D80DFB44,003FE15245DE3190,8116A7F4F0841713,A5BEDFCFA1FDD861,381CCA8F3564816A,E5A580337F4F500C,64726289E0DD4EFC,EF2D2DB981885968,D3A7DA151CD09C6C,00339477FD65067B,EDEA8178765365EB,7AED41023C5E08CE,CF5FC455FD038663,33934621A0537B4E,3C91B4EFD6DF3769,A6433A914BACE820,B1B2F5608949BF15,001825E3CF0FA788,724E98817B701E7E,CCBEFD7E73000B3A,3E5C0B10E1F5EA47,07622FA66B26E788,D2EE7C1A258AB916,352767DA5D2B296E,2737F0137AC86387,001369A9047222A2,6836D89A9564D012,726E61C6C1D53A51,B421AC27F51C443B,98ED5655A78159FC,C88C73E4CADEC24C,737AC55FCD436E58,8FF8A69FC863726D,0019406203B141B0,DB6BB0DDAD2222EA,B18C780EE0A3D673,40B20EB7BB9FCB03,ED5A3C608FDB2808,2FC653BF52F11AF2,5355265B821FDB91,132716AE0740792A,002DFCDDA4AE4929,E43DC279CF701CFD,273AE3B4C995DE2F,E74B84DEE3A2186A,B993F5908EFF5379,14E26E7EB97C6700,A0BCFEFDD83B9B56,F88EFF0AAB351B96,0028A91EB2436384,CF3C422F68357A77,EB6C0DE5A77CE978,C644FC0EBC95BCF8,FCB13F75092E1C06,49301DB2CF8BB067,FBC37705FE2CB85F,F8E9EC73E1A52C2B,0026FE58F02C9750,B2006AB67DEC329D,45FE6CB04680C5E9,996AB93A70CF481E,5739AB3E8381D6A6,A431AEAEDD73F465,92D77EF9709AA605,593059C24159047F,0039FB2EBB7E6D22,80CCFF7CB1CCDAA4,7BB0140EE1D2455D,A45FBE0500212702,42A9EEF82AA14087,DC6180C2BB97BEDF,4C21B17ACD30757B,DC88072AD910407A,0030D16EB901A4D1,3E6FD0AD45EEEA30,3E827A58561E1A6C,8331B0B189620BB7,31DD3E9491373796,3D7E97BB66629582,75DA419D2864BAAB,C70C220C7930769F,002BC16B031BC7B5,5AF4574EDED8F683,90AD606127443495,95840FEACDBA83B7,72318F81247D4413,16B0481171604EF8,E31D3D715E895626,B4B7CCD38AAD1EC4,0037487E24BF5206,0C0ADDB3F421DCCF,09FD2F3C318F302E,9868F022A63FED57,A506892502A2C24C,34831387AA223B0C,2156C30866524566,04A48173BA4CA309,000390CE6BAD1413,4C941DB40C0138CF,DC751714C36D8F99,7BF983C8258510AF,DD64EC7F65B97B3C,77470A3433EDAAC9,9436BC07DB63A941,7307D94A97F96654,003AB872E4F584D1,1E2F16109FED72C9,30D8DA22092BCC17,E97A8994615FAD8A,A1C4D93C33A9FD5D,CA78FA0FCAE319C8,C9A9BAA27DBDEDFE,87DDA9FB66BC1EB4,002FA7F3BC05E23D,12A3761A7AF41569,D956799746ABE4FB,2B74C1094C22C697,E46B19C3BC2E47F7,71C89604369A0FC7,E32D1F055FED5DF1,F52A879F083672F8,0032FEFCF8B399F6,B193C34841EAE7D2,D8CD0CE41F55E143,E200C1FC7BAD7E04,950AD636B3E4F65E,610437B3B8DC59DE,D9D11BB1C66F3FDF,473D519D2D4BCFF9,0010F252AAD46463,721F4E16D10714B4,7E28DEBEBC1C696B,EB869E97477110C8,AA4494638075ED0D,1B204FB35C7BC149,0A4EBE5516220171,2F81749D101226EA,001FCA7AFB5BA9E2,0A9586BA79502BE7,DFFAF77670E181A0,AC330EA452CD947E,069B01A6B97100F2,39A7634D41E40EFD,C195014F685D9126,50986CC39CC034EA,00370B259173D1CE,25253DBFFCA32300,5AD4FCB4D864663A,586599D162D3CB8B,4F6F4ABEA35E6645,045E3DC94AF57C56,8429E4BA17300506,FF755167C3FD99B6,0032EC19DEC74528,201834C51BF937BD,20937BDADBEA81FF,4F9D211BF56B80A1,AB5D1C466C2FA59D,0316E1A59C5021C2,D7D12BD9A7D00D1A,A32AE30B552E6EFA,0003D1E87352272D,B36895304835C631,D6B3B06BD70940C5,A99827A8B92E9A30,B91DE30631B1AEA9,4E0AB2CC3F5E6524,4B2D6CB3EDB3E5C6,99F04C2140F169AE,001A0C0CC114A514,141C10ADA415CDB3,7DCA8F4E2CA79AA8,5375701EDB192786,654E8A721AD1B282,84C9047B723D1C64,BCE32787A3B08F68,7CE9CFA4FEBE4244,001EB87707EC43D8,C22F2C3D96FD06D0,D0A250050BB919C8,3D84629A52FD5A00,71835D943759E700,32C50B17D3804320,0DBB89223526BE77,1A659AA5588143C6,0038D4B2FED11C46,BA43C97843765803,5442291B10F0CAEF,0F6A08CBBDCEAFF8,A6D57B1B4A346BF7,009B54D15FD1DBEF,DEFE211CC2B956E1,8263EB9D5A9321FB,002920942C142777,B21A8814FC907345,BBE538BFDBC113E8,3F6D7D20CEFB4A59,AB3AD1B6FC513E96,3ABFA258A6C9C47A,9D9FFEC21C1DE4F8,EEF0218128378751,001E4CD3192E0D6B,6A0D94CFD2DB236D,25EDF92BD5EF4F69,5357AE817BD12811,941A2E215DAEED16,3F1A1372B2EB4844,00115FACF637E6D7,89F6B3C2B281D76D,000C7B740521C355,30034CE087790C52,EF0FF8E24EE857AF,1156B4EDD70C2931,6A785153102CC231,2E422101D8E89A34,F3D32A172D4CD9FF,0E81E885E4CE856A,00280EC6D4AA56A3,3E2DD83A7BFF5D74,27373BC1FF66F65F,D5BE05AB903CF427,44AE128F0D6FB63D,A1FA0EA51FAE6787,07E2036A864ED897,0BB421BA915B501F,003706A0BBB52C41,B01F2A76FCE894E9,CED4243F12247EDE,3F11BE4479908049,58AF50BEE2DC51AA,9F15ADFAE2EC9CD9,7D92B2B506A59DD3,3AE0D78757AF1140,0009E977F111A491,871E0D57BA6DDFE0,09A3F6C8FE962C1F,E287B01FE88E2935,B3B6D701786E6C40,EB24C2DB1E40FC1A,BAD8865E9C5DE409,9813E86982DA6CD5,003148A0FA55B831,4C4CA412209277F2,A2881D174B36F20D,053C931DA3CFD17E,1E66705E0057D651,3D2EB39DF9185720,27A139ADE8610AED,7B75F2639EA349BD,002E74813D28D5CF,DB56B52CD2E98E55,4672298BA5DB4DE3,62378EB95750AA49,9E7D555BAF2016DA,AFB462029816ED43,E096C47CA862ABB4,FDF18E38E88A1B92,002CB61B53C05017,BE9671EE002B253C,1D2F81D6FE1A6FF4,8104D61A2570A822,136D784F90EC7FF0,67B55E0947D8460C,DFEA85BF8F3672DC,933197A48BE8BD44,00135CFFD374A8A1,F95E879C9C41753D,0418F93DE9AF8762,ACABA44C535A94A6,6FB63C5827A2E4DD,CEC56AD42007C860,1518212D09958B1E,67483D2AF241C193,0036B50D85A280D3,07AC6999B832920E,9AC1301BCCA8DD07,30F2EDECF98751BE,270BFB2C48ABC843,D70D1210034C7B59,A6297763EFC0C314,4F60793E851DEEA9,003A82807269F3A8,06905F0C68A1AC91,A6C5317CB1750019,86844E21D094C374,3A2B70B1911D78C0,510361C1309E54CC,2FC808AF3643AE81,406D699E6A442997,0036E4A67BDB54FC,02BC5539CED0152E,06BA556956CE431D,A299B8F8E8C95692,95AA4F7EEF1911B3,E1AE10A1C1A60D48,B16F502E1EA69ABA,AA2D80A2F1C7E7C7,003ED20767A554C0,BF9AAD13313EA760,9CAE8E02BA91FC70,54DA9C6E6ACA6EF6,9C194E6AD0584933,2CC0B95F14F68FC2,8DDDDD70ECEA15E6,E54C71690A40C41A,002B3A09E4EF2B8B,964F780E7DC7FD33,2BDAE06068B62E1C,D8A931CA1C5BD3B2,F037AD61BC3E043B,D02926EA08A25598,2E7119A322AF8A34,976566739A57D2CE,000284A066E3A6DB,174C86772AB893BB,C0EB088253F57806,2B3EF330E4846015,40C9B9A15411288C,464B47D7DB0B0FB9,052CE596FAF8EE9D,EDFE7FD6D992462D,0011EBFC3A20FB28,069F1EAD8289E25D,BAFEA7624DCB88D9,C09EFFFD02553F30,D20CCE4E5B03B6AC,D652AC69D3B91673,8857F7B35CF70180,83F907C47D5F89E1,0035EBD732545CDD,9A301B66C37D0C7C,90BE4409EFFBA0DC,B8E841C580635131,A51469A97086D614,04879167C04C07FD,44E722B2238A5B0E,CD60F4D786553092,0037D75639DF21E5,C44AFF4415B67A99,4102A93EFD81EA2F,FC4337C339169A25,8D8F6C8D4CA07670,483CD29528D310FA,EB36FE4D5F89A1E9,27330F4103E1805D,00276FDCBDBA1C53,A1618FA19BBBA49A,6D01AE4A2DA9DCC8,6AF18CA5EBBAA4FF,5A002DAF1EF1F4D9,20873C748FD277E7,D4F943C16C73CA29,7C6900658867B79D,00294D654044E1F6,8C936813D87B026B,5852E36190907E36,B1FDC6B97C4CD4C5,6F55AD599999A56D,9479E7886E486881,84DC62956EBB8ECD,3C4008E26B917337,0010508519967EB7,C8E4E66F4324F100,AC8F82EA59335D23,4E56DFC2C21A806C,ECFE872D0D01E8F0,70C44EC18200F611,658BC925BB8F0529,813A1FFD471366F9,0009C368A08E7048,AD3A59F238C3DD30,A49868148F2582F0,F8A2CBDBFE031FCB,C66B64B927294AB2,471B0AEEAE1A87AF,B2289021E18E5FE9,39386C7651F57188,000716C43D188FD3,A97267F4388E30EE,FD47CDB645033938,4CD50E40EF888896,3123FADEB53A3CC3,A8809BE7E29BDD26,F9674846316433AA,EEE3CC42051EE84D,002299E6A15CC590,5DF14D9D1AC0F95B,F81A567F41468749,7A3EE287AAB541F8,2EE8DD4A375E21CC,FA6EA2D7878B09B2,46ED4781DF95F1E4,C9CD7BFA9058953D,000A38E64F04A7A0,AD9CEB1CFB77B573,ADF9B6A03ABCDB18,07AC914A20AD339D,7E1CC6EA57E1B929,0F04CD557675F24C,215AB7E83AAAA710,3F67AA5E72A3544D,001A87C47349EC58,E26168F1A95BA3AC,B12B2415609077EA,DEFD32522D05D989,9824AD2A847F4C5F,947DCC00CB1D920E,7C6BE12321062C60,F3CD5D1808EBAA51,002197A1201316B6,E4816299EF57C360,3A841403E09EE7CE,13D45489C3456AFE,DD89D90CF949453E,6C53655FC3813B3E,F22C039C518BDB5B,70B573D24382AB29,001175D42DBA1425,F75C0C3F7F1E468B,F443B2B7DD41C648,9DCFCAF479E593CE,2DAE0BC5B5C9C3FC,0E74AF024E9DBD7A,E8A496CF4E7E2925,ED7B1C24C32B6489,00277C420DD38BC6,49D58E2499BC85E6,18FCE6A58D62E6E2,79DDC9555A049222,8C37544B8874A5C0,F0D68DFCF366F839,D4E6E524A01B4CCC,903B0916344B6C8A,0038A1DD61692C45,6EA4639B4C799287,2532B07236A53341,D3A6F09A1B18FEE1,BEDA5A0597F4DC36,C8044C1B615321CA,B54E234DC3AD0062,B93A1C13F72D18B9,0019677A113A06D9,B63FA55D6CFB3E2F,A112E82CF7FB8B59,12C09478D76E9917,6221B7724627179D,7F6C5C629344E1CF,7FFEB22E78F6EA27,AB951B74C73E7C29,000BDA81D7B404E5,5FDE030ED37DF50F,5514809132F6644A,2C448011B808B035,C97EE79990FE23CB,4FF6688F5D6C861C,F50D2341C1752A6C,B7B7BFA85A955E1C,0037D0144D78FD42,2F409A16B81F32B2,CF7DB465651BA8FF,521FA1337A6C98C7,06A6F54D3973436E,AD3BA12A8C9AE83A,A6FEC405D99ED319,39B5010960FE0DBF,002213FA8D8E0291,4550296B6173F269,1C042D1C3B9407CB,AEB5CD5CB6A77638,C7EE377515D7931C,9EF282EE796A33A8,00101D2006EBA8B0,072CA2A9EAF5BA58,001F8892FCBFB84B,07CDDC291698D9A8,8D9D4561910DB112,6EAD3E169CF3DD59,36BE29B0965401FA,F04852C0B49DDC6A,121BCC0A043FCBC3,BAF70DE5C329A254,003CEA0E4423628A,8C2681175B3FB01B,BA65D770E9420F6A,E80817106002B713,B9FB429307C5F48C,660437556722113B,26665704906BD449,E1BEB46F7224CA3F,003D3B957352F88A,EAB79963F2C0177D,8BF87992BEE35650,A48FC1765AEB2D23,8824D184413D9D54,32EBCA8BD44DDA09,4294419D7E5D8C77,1901E3B02189FB49,000C1373124FE17E,ADB84197B6ADF10E,3D16F15C40F440EC,7C8B1F207E841340,2C2A7132FF1BD3B0,FD455C14B9A2A914,0EAC60CB14100E21,3FF7D5E031F30CB7,00369FC6D5B884DC,635A760950481409,86751B969B22A341,A1670D20E42B71F2,21F8E39DE507B89D,E2C5CE673467D45C,BF24825062559D8F,3013FD1C7623C67A,000C48C9A8D9CDC0,D6B76FA358ED6F24,83FEA62120D02FDA,F3AB9E4325C9AA1C,ADDDFAD42EC28CB6,60E4AFB4C8FDD09B,D4C634B567134AE1,937848DB527F0A9E,002E891264E455E9,17B42146C75725EC,6B3867D8953DB2B4,1A5B97B7AE7E5B40,BB22B4E9B256FD83,C679E76A105773A8,34E38BFAB1652467,FBD84B55D1DBDC42,003A1AE9BCC4A405,7DDA454C987C7568,0D6123C2D74AABE2,04E05F0569C2EEBB,D75A00EB36B1974D,735F10A8CA665E1D,28D7CBE8866D0B4E,7C390C237560BC70,001F575651049FBC,3750973ECA1B7D05,8D3B1DA8450CF9F3,0EACA05073F125AB,B6EC4862079444CA,CA8994B066A12DA0,0C37AD6FD7CC8747,BB0D5426A074EA45,003AFBAA87B3E923,2766C038EDA29F41,961A20F75C73D5FF,8FA3157DE1EED7E5,332416715A7A40C1,909778A61155E4F1,9DB8D9946A8C85AC,70F0861022206CE7,0005C8AF4C345129,36A9C7DA020DF9DB,DCD44705C5F60C5C,8339853E7E45DABD,099150EE09CF5686,5450178427E8727D,CE4584E48A3E6F90,7C8C663D0D1712ED,000EF138C710FFE3,714F1B21A3ABD59D,5F11E67D87485EFE,8F21B2DB2B33192C,8009C58750B162C6,196076A7C3E02A4D,1E44C282CBCED021,509ED914BD94E7AC,00375F17F4F7F997,15D2784142F7C097,D3BF27A609D39065,02390FDC401D188C,D36A83ACBAE0D563,BF5C7FE7D0DB0A24,BEA12EC93D4AFF7E,F4EAE32EEBFA8C1B,0026351CA3834F7D,4537FE059BC3AEED,659C1FC99D49919C,9D96847AF3ED8426,43A306419DEC9D1E,470F70B2DCE0AA80,722A55DC99D7B0F8,9FE7882B2B7507EC,002DF2653F3FB292,508D95FFB6A8D1FA,76BAFAE7AA1D25BF,9F4FB312B14B2AB0,19968EAD70AC0E33,0CBE60D5A49F10FD,4FEA33864F76C1D7,3F3046F589494880,0034444ECC962BB2,2E8D1C269570CBA7,27CA62139673E61E,DC909F784CDF135C,7B3BC8018CDDB351,0A03A0DAE590E8CF,66A8E753733D2607,624C069E4DAEF9CE,003AEC0916FE309E,A1F95E42E93937CA,7B50D53E819CCFA0,6CA6A1284399AFA3,74579C92EEC35841,ACDB048A58F09B3C,6E4C5B034861C06E,3F8F29C976C5FE60,0000B581276FD47E,4C2E1A7EEA465402,964E6674DC1F59A8,829E75DCC0191013,9F02E7B7E6875816,7312EE69E84B1382,5A31EE12BF710D52,F243FCAF9A1D5386,0022049B914A8F8B,DA1CDB1E323CB3E1,D080168880D83C18,9C3A478F990F6FD0,EBC3B0231D7A200E,93BF9DBA253BBC4B,29E222653ACE0E85,D33F176190E0577B,000BBA1CEBBA4E86,7B1636E70783DD6A,20F97A77C27E531E,BCEFFD8F6E6DD2BF,6A87E7F66E8C6D53,C57286D97062B799,1EA3AD021D06277D,F90B0AC174B7B75E,003AE582FC7BA4A5,5036B9BD0B8FC1E7,25B5E65C15B0F21C,7A7C359AA5CCFF5F,22F7C83564105164,50837E8BA25AFCA2,19D3F46F7377CBC9,0F62ADFE007592BE,0015529754940AD7,77C95A717AB96EEF,42310316D6A95511,85E7D807872D4F43,9E25E44745817508,C28933C33C4B4987,790C2D5A1FE7A0AF,8D86A5701B7D3AF0,002F0D93CF188CC6,92B000726E5F6D44,E70A2B4A2E13D6AD,6D609E8915F8002F,9C9E584840BEFAB1,2FA8F5E652466F57,F247CF9874C3D5C7,8D53F8C51B579BA3,0000537B61B42E2A,652188367E0DD4A9,08248F930BAC9E3F,532223E5D838E94C,529AA11FEF00823C,8CC2E7123E4D59ED,0E1D72DB400E9564,A0C39408113184FC,003F6FDFED96BBCF,C0AE7E8AF7408588,CDD69D5568897188,E7B91622BE8D9A7D,0B8F8019C3D24B64,7A404D58B826E670,163AE2D48BB9996F,8033059DAC0030C9,001C6FBAB0A84DE6,DD9B62E52B3DF64D,E4F071F8F2355141,F94EDD49FC9756A9,802E15A64E4E8676,62335A54B0A81E98,C0612EE726A3A859,913010DC7DCA5FE6,0021B4C92564DF1B,D7D84B3BC2999A31,FB1744ED12436E5A,F66CE1E366A03BE9,A008FA1C57EBD323,E0E37A29EEF14A67,6658E67F58026936,9041E1D7ED4C8D52,00344853080B0CAE,A40CF021BD739CE1,5A014883FB84AF3E,854988924E9721F2,24209ED3F85456F3,A68854CCCC77E69F,D7FA431C1B1FBA40,A26025CF3DADD9AC,0015F1A126A1B026,683DB6B56B27D4EB,86A1D5D57FB13C67,CB4D37C3D07605A5,6311C11F7C5D6157,714ED94912A9F81E,2A0F29CC0B50E120,98794FADD0F137DA,0019490FB5A075CA,2B6E8ECB0DF0C62E,7EC53E6F6A0B7CF4,3DC2F5F7A5DBA58B,F9668F66538A0D1B,1EF7FBC919917CA1,CA545ABBB8988B81,B0F6D19F995E2B18,00269034800B0D13,EFE354FB0FB2D994,F6AE6BFB62B1FEB2,927FD4CD58F60567,964E544BA845D3A7,A53361B7E6E30E6C,4917FA831E7B4722,6FA54C97932A1FEB,001AE4CD5411EEF3,E3709389A7292C64,29998783258B60F5,59764D595C3898A9,82243C63E92583B8,A1CBF40925573781,2E53B32255746170,979E8618A6110488,0017962C7FD94EE0,A3D84D28808AAFB6,523F8DE21DCF1E6A,FA3922FED3CFDB1E,F1512056C835ADF1,84E8351039EEA3E5,90370A1A814769B3,3611867C14E0C765,002A46FFADD11BA4,63BA4D20447FB008,E4C87921F44B824F,0454A1807B4E0422,9408465EB74925E9,A9DB98C6C99974C5,77EDAA45A3C3161E,535C0DF9D4754BFC,002E0D76B224ED03,EC6052E533BABC07,A5442DCD3DF56EBF,DC43CECC4AD80531,43AE12B7C7633922,DBA50FFC4670ED08,F9006FA4090ADA4C,878C393463D1C628,000942ED913DD89E,F14EC3EFADA5B98A,1C9408F57C25A481,6472542531EFB3BB,67DED7CAC7B28584,F5C06022C264C282,ACC99A74284C9187,380B252591FDA9F7,000B844254275D59,35006768F5F5D254,ECF57C591D4E2D1A,1052DD7031DA17F1,95AE6064240E89CC,EFD9BE89F1D2CBFB,BB9B133B006EE8F8,E69D7BE1147BDE0A,0002C7617C069A60,C7881188037DADD9,83D45D15B931BECA,099EB42AC65D138E,94A384C1A602CFDC,1941F8ABD7B88973,1E4939EE66487496,50246E8FB0C211C3,001A47DA577968DA,A7E2CE0FB37F29F4,C9BE0830820CB30D,726EB95E311447AC,922AC49A06B8D775,E40E87CA0B9B4402,57F0F1FF4A9CB8D3,83D5D327BED39F4D,0003328702949763,42112B7CD1E3ADA2,D18A2B39DDD744DB,2174ADA4671E3A52,A8D61D7C2166F1F8,C0CAACDE0FA9CB45,205ABF49F829FED9,45CE3DC53ADD20F1,003AFD9F48518E12,D0605099745D3CD8,C8C39181EF7276F2,CCF7487120657325,6EDA70F77EC46F20,43DA20C227072698,E6E32D4D1D5AC0F2,EBBC5F10274F5B0A,0029210825190FCD,EB995413436FEAC1,EC05B5B4915ABB1C,4105C7DCF6E34FFF,BA718F15499E5439,E5F0AD2C1882F5D6,B640BCA69739F265,18043D80A34E2365,0003E2F781369796,447211C1967F78E8,1CE8EF8C5767624C,8C589D033BFB3418,C7252B62CF0864E9,5A26F3F7F989F68F,E4E232214523B93B,494B813F17ABB4BF,00094141AFEC9760,EDC2EB778FD946D9,784764FFB4F560E0,6C294CA65D0BED94,877E94451C922E42,9327124A18A4CDEE,FAE92AFADDB56A50,EC69794AAC3577F8,003F26E8309765A9,9E33B5670C907DEA,3F845B4719C14C2E,5EC805713317D0CF,C473365B5FC77D28,07B9CF2F4EAE9C2F,3DD7A91F13E1425C,B12FABD25E0A7F6A,00185AE47AC65FFC,F1D9C2911583E4E2,AAE151ED0F0D1E74,4F55A7D5DC915AED,06ED6D4F03E88ECC,1C4E857105637C70,E71E430DCA52DA35,4A0CF742B7A2B7A9,0035D567F9B73734,0E263D6EEA7C1B1D,551EAE12F0F2E18B,B0AA582A236EA512,A51292B0FC177133,F6B9D6691CAE6B30,347DB3BAB12BA379,1638CF7B22D4ED26,000A918D47C9E6EA,61CC4A98F36F8215,C07BA4B8E63EB3D1,A137FA8ECCE82F30,E78CC9A4A03882D7,0B4E8CAAD3634B70,DDC44DA9679D3B53,AF161AEB7C6D2565,00280C10C6BABE21,123D14887026B926,87B89B004B0A9F1F,93D6B359A2F4126B,24816BBAE36DD1BD,7FE14990096D19B2,20B2CBCD9DC9135E,73DC4D732E422CD7,0001400D10E9B874,BB8DEE3E69808717,E3171073A8989DB3,73A762FCC404CBE7,E4DAD49D30F79B16,B8E167E22887F110,36B9C4A7365AC473,16FA457EC2CBF010,003725B3919486BE,1466ABECBC90153E,13FA4A4B6EA544E3,BEFA3823091CB000,F18E70EAB661ABC6,2D17AEAE098EF1C9,655B3A21E4448B49,4841893D3729816A,003C83FDC04A8688,2F9FAF668BA2C327,373C6E7E108D890D,3308B78EDF9A8CDA,3D258F08813B90DF,CF2E3B17FB0AC108,34B8C97B5E23BCBC,748967ADB32849C5,001745ED1C680E50,BDEED4832E1C525D,2E75D4C62228BB24,DE8B525B98E1C5AD,0329E283DE990E07,523DAEFC12681C5B,FB41377E83547ED5,1A7788F89F9A83DE,00056955F92F900C,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,FFFFFFFFFFFFFC06,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,F7FFFFFFFFFFFFFF,AF3D416B7B3314EB,CA33593B14FFCA31,D5784EF6BFC5638D,00196B467B71C4CA,D0605099745D3CD8,C8C39181EF7276F2,CCF7487120657325,6EDA70F77EC46F20,43DA20C227072698,E6E32D4D1D5AC0F2,EBBC5F10274F5B0A,0029210825190FCD,BDEED4832E1C525D,2E75D4C62228BB24,DE8B525B98E1C5AD,0329E283DE990E07,523DAEFC12681C5B,FB41377E83547ED5,1A7788F89F9A83DE,00056955F92F900C,447211C1967F78E8,1CE8EF8C5767624C,8C589D033BFB3418,C7252B62CF0864E9,5A26F3F7F989F68F,E4E232214523B93B,494B813F17ABB4BF,00094141AFEC9760,1466ABECBC90153E,13FA4A4B6EA544E3,BEFA3823091CB000,F18E70EAB661ABC6,2D17AEAE098EF1C9,655B3A21E4448B49,4841893D3729816A,003C83FDC04A8688,9E33B5670C907DEA,3F845B4719C14C2E,5EC805713317D0CF,C473365B5FC77D28,07B9CF2F4EAE9C2F,3DD7A91F13E1425C,B12FABD25E0A7F6A,00185AE47AC65FFC,123D14887026B926,87B89B004B0A9F1F,93D6B359A2F4126B,24816BBAE36DD1BD,7FE14990096D19B2,20B2CBCD9DC9135E,73DC4D732E422CD7,0001400D10E9B874,0E263D6EEA7C1B1D,551EAE12F0F2E18B,B0AA582A236EA512,A51292B0FC177133,F6B9D6691CAE6B30,347DB3BAB12BA379,1638CF7B22D4ED26,000A918D47C9E6EA,0E263D6EEA7C1B1D,551EAE12F0F2E18B,B0AA582A236EA512,A51292B0FC177133,F6B9D6691CAE6B30,347DB3BAB12BA379,1638CF7B22D4ED26,000A918D47C9E6EA,123D14887026B926,87B89B004B0A9F1F,93D6B359A2F4126B,24816BBAE36DD1BD,7FE14990096D19B2,20B2CBCD9DC9135E,73DC4D732E422CD7,0001400D10E9B874,9E33B5670C907DEA,3F845B4719C14C2E,5EC805713317D0CF,C473365B5FC77D28,07B9CF2F4EAE9C2F,3DD7A91F13E1425C,B12FABD25E0A7F6A,00185AE47AC65FFC,1466ABECBC90153E,13FA4A4B6EA544E3,BEFA3823091CB000,F18E70EAB661ABC6,2D17AEAE098EF1C9,655B3A21E4448B49,4841893D3729816A,003C83FDC04A8688,447211C1967F78E8,1CE8EF8C5767624C,8C589D033BFB3418,C7252B62CF0864E9,5A26F3F7F989F68F,E4E232214523B93B,494B813F17ABB4BF,00094141AFEC9760,BDEED4832E1C525D,2E75D4C62228BB24,DE8B525B98E1C5AD,0329E283DE990E07,523DAEFC12681C5B,FB41377E83547ED5,1A7788F89F9A83DE,00056955F92F900C,D0605099745D3CD8,C8C39181EF7276F2,CCF7487120657325,6EDA70F77EC46F20,43DA20C227072698,E6E32D4D1D5AC0F2,EBBC5F10274F5B0A,0029210825190FCD,FFFFFFFFFFFFFC06,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,F7FFFFFFFFFFFFFF,AF3D416B7B3314EB,CA33593B14FFCA31,D5784EF6BFC5638D,00196B467B71C4CA,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000 diff --git a/core/src/main/resources/org/bouncycastle/pqc/legacy/crypto/sike/p610.properties b/core/src/main/resources/org/bouncycastle/pqc/legacy/crypto/sike/p610.properties deleted file mode 100644 index 468de9a6a6..0000000000 --- a/core/src/main/resources/org/bouncycastle/pqc/legacy/crypto/sike/p610.properties +++ /dev/null @@ -1,52 +0,0 @@ -ph2_path = 0,0,1,2,3,4,4,5,5,6,7,7,8,9,10,10,11,12,13,13,14,14,15,16,17,18,18,18,19,20,20,21,22,23,24,25,25,25,25,26,27,28,29,29,30,31,32,33,34,35,35,35,35,35,36,37,38,39,40,41,41,42 -ph3_path = 0,0,1,2,3,3,4,4,5,6,6,7,8,9,9,9,10,11,12,13,13,13,13,14,15,16,17,18,19,19,19,19,19,20,21,22,23,24,25,26,27,28,28,28,28,28,28,28,29,30,31,32,33,34,35,36,37,38,39,40,41,41,41,41,41 - - -A_gen = 31C8AF7FFC0DE9FA,8A8AD55D2AC8A709,95A4DC49B64E5B2C,F08C77AAE90ABE83,675E4FF97C95845D,F8A22591248401F0,73F573A4FF34A84A,37D18A6C3D989158,0EE73973862A3E95,000000024084FCCB,4B8C9CED6DEF0B8B,652C800D926AB992,3DFA6D6B8FD37D80,A30C578CD98EFD79,9FC067E58CCBD32E,2B0599AEAF150FDB,BA321B31886F3292,E0011F56247547A1,28CA0747910BFAE2,00000000FC020A14,2728178178DEAFBD,D377C4656DBC71F0,968642007B807932,B8B04B1039062A21,F824771B468A977C,260F1C50354F46AB,78A3D37CDBBD4DC5,1FB1BAC6851BA175,0A73444F1CAC4A10,00000000F3A5C2BB,4F828B752E825BB4,82CEA210AC766C69,8B1BBC87DAD8BEDD,9BFC5B9CE215B423,F7E1BCC0C541177C,7727E3A0F1A1AF24,FBCFE4177D2B0221,BB15BDCC160D902A,3FE1467B4A911446,00000001A495CB35,38687702D78D1A93,58C09FD23B1E1B56,C54917327D5C0FAB,0B6D55B7BE801A3C,EB3AE21C8B93E9E9,ECB45AD6D24FF76A,850645B4F39EC5F2,E6F78202586C9B3A,2923209A250F7F66,0000000026FB150F,5AC7B27F9096F718,487DDD2820132C83,6B21AC48569E12D8,57B54E5A827D1CD9,DB7C4BEB143E4130,B6781CA1DA245EAD,CC09878A2A6D7C45,980726C5232C75E5,50D3A7350792C35F,0000000172B595DB - -B_gen = D4A2CF040BC56F2C,58F1D1D2B190EDE7,2229F10D3BC7BA47,769AB0F0EDD86AA4,097F1214B80D8463,9B23774D13ED3EEE,9A182E846DAA95C6,343741369B273442,61FB37462569D4BB,00000001815EF8B9,F380CA27C26BF32E,D594C3EA0698D298,21D388E632D1CA2E,DD1E0B34330E0AB0,EA7B89CAD59CA8C2,28C129BFC584BEC1,48D1E802FC7418CF,11F3A548C5DFFDF7,DB0E9AF98D314F67,0000000219918D2B,D4A2CF040BC56F2C,58F1D1D2B190EDE7,2229F10D3BC7BA47,769AB0F0EDD86AA4,097F1214B80D8463,9B23774D13ED3EEE,9A182E846DAA95C6,343741369B273442,61FB37462569D4BB,00000001815EF8B9,0C7F35D83D940CD1,2A6B3C15F9672D67,DE2C7719CD2E35D1,22E1F4CBCCF1F54F,838676352A63573D,88B72428E4D5F16C,5215D742081BE0DC,A0620DB14AE42733,A68175C8C4B68925,0000000062651A3C,4F62205A5DAFB369,A2B75D5BC06C691F,6B82C9B893D51C38,2C2467D7AB7DAA2C,8A8D5AC13C2C5ADD,BC3AEC544F8953F5,BC43C1BE1B1DC069,B8CDA0908AEBCD84,A213356DB0FBFCFF,000000015F063030,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000 -XQB3 = 4E8DA387C42D31D0,83AFE0DEB4FCE84B,E819FEA7B6AE32CB,A3DA371FFE9EE0F2,4765959DBFECDE2D,DB446F20746721E0,E2596FFE42E2D7A8,1FC46DF0BC2B8759,9F5106F3AD0A27F8,0000000161083808,A88E809BEF28310C,506DB48241A76019,E9FB9219833DF071,342D697582036AEE,25F078F10F357AFB,43CE96BEE1668B06,0C540E958A6494D2,46EB300B952B437D,898338D77E9F811D,00000001FC9961CB - -A_basis_zero = 31C8AF80CA277BC7,8A8AD55D2AC8A709,95A4DC49B64E5B2C,F08C77AAE90ABE83,2DC44FF97C95845D,E25D5D22CB0C4641,EDA1E4D340EC56D7,2AE81B9DCDAA0FF1,B4292D8E409BC484,00000001D5B8282A,4B8C9CED6DEF0B8B,652C800D926AB992,3DFA6D6B8FD37D80,A30C578CD98EFD79,9FC067E58CCBD32E,2B0599AEAF150FDB,BA321B31886F3292,E0011F56247547A1,28CA0747910BFAE2,00000000FC020A14,3CA84837D69D8728,B2BDFE3304CB7401,8C840937950AD3E9,CE8094A539AA6C49,F0802AAE490F29A0,5458A8E61BB9D01F,3592A73DE4758511,7DEA75B85A60F316,F835EEAC9B12CC1D,000000011C4E0162,087A90900552B058,F34899FE9411DC6A,03807CF5B95B0168,C986BAF1E3FFDED4,1D10EAC33AA0781A,D9569230F9A2D512,F8295F6189DBAAF3,26B44D4CECB1A5E8,9CA4CE754143DAA4,00000000AF517DFC,2728178246F8418A,D377C4656DBC71F0,968642007B807932,B8B04B1039062A21,BE8A771B468A977C,0FCA53E1DBD78AFC,F25044AB1D74FC52,12C84BF8152D200E,AFB53869D71DCFFF,0000000088D8EE1A,4F828B752E825BB4,82CEA210AC766C69,8B1BBC87DAD8BEDD,9BFC5B9CE215B423,F7E1BCC0C541177C,7727E3A0F1A1AF24,FBCFE4177D2B0221,BB15BDCC160D902A,3FE1467B4A911446,00000001A495CB35,59DD6DAF69D05BED,D76AC76FF586B73A,7FE9D57BA40A785A,D14A8A25B5B1A187,A96A1F6746EC4DCB,3D12E7FA86078B0A,37816E342D89C86B,0EF93BD5D8E68FE5,582A083E04E4D83D,00000001A402EB75,439B3817B316DC12,AAC33FB9DB2CFE99,103161162202C633,3C38BFDA7559D6F5,B4BC209633AB8D22,A1724B6332EFE4FE,81919EE777E6B9E1,D15DFC6FAB242CF4,D69C41AF15E2B7FC,0000000274D72579 - -B_basis_zero = 203596CF0245B227,FE7D4CB978F11517,EC79574E9D7DD13A,D24627B69D4DFF63,85B4D3B2B5426BBF,FF0237C357683FCA,2C3E0FE7792534B1,8B68DB1AFC3F9CDE,5AFD2B5021786921,000000016CFF1918,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,DFE1CAFF47350FFB,7F6641B5806DBD07,D558CE2B43292C47,28EB4A4147C77BD6,143218EB29F5FB6C,5F457BD167A2260F,26D9639E9DD4A15D,EC9DFA3764433777,9D8C59E2D257CACF,00000001D2D65779,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,DFCA6930FDBA4DD8,0182B346870EEAE8,1386A8B162822EC5,2DB9D84962B2009C,E84D2C4D4ABD9440,B276162552F27063,6EA9AF5D8B6AC4F9,26ECD7DF1484884C,2692E572306F6F6B,000000010EF78E50,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,DFE1CAFF47350FFB,7F6641B5806DBD07,D558CE2B43292C47,28EB4A4147C77BD6,143218EB29F5FB6C,5F457BD167A2260F,26D9639E9DD4A15D,EC9DFA3764433777,9D8C59E2D257CACF,00000001D2D65779 - -B_gen_3_tors = 1930B476A230B7BE,03A42EE16DC949E2,838416CC861CB74D,E43303F18BFF483E,30C6C49AC1829C11,40DD7E521AF62273,33AA27D882B23CB2,0A970F369B7A93C6,DBAC55CF2FEFF179,00000001967E10A3,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,4709DA258D7CF239,68142BD88204D1EA,AE14B528AE909088,8D813E124214BFD6,8E6949403E0D509B,F795CE2041AC8CA6,20F1E1F2A851B359,89B489710FA8BD76,1608B910A609EED8,00000001F957263F,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,E6CF4B895DCF4841,FC5BD11E9236B61D,7C7BE93379E348B2,1BCCFC0E7400B7C1,3D3B3B653E7D63EE,709ACF968F648DBB,673D976C81DDBCF9,A7BEA3C375499164,A5E3BAF321F7E713,00000000E57896C4,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,4709DA258D7CF239,68142BD88204D1EA,AE14B528AE909088,8D813E124214BFD6,8E6949403E0D509B,F795CE2041AC8CA6,20F1E1F2A851B359,89B489710FA8BD76,1608B910A609EED8,00000001F957263F,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,F4209DFFD5BA5848,5B5A41268B033DBF,7487D67F15941658,E0C6754A260143AA,DC40C6C153BD4F30,A37675E3DD939202,71830795095B5791,0204F7BB4612B47A,196818C06A9FA46F,00000001C82644E6,C41ECDCAECF46668,3303A35DC32C0272,6A10EEBB3E7C798D,800B26C6B6F0F2B7,E0AA44F811ECA6C6,38BB298B83C41423,5C8E988E2C1B6909,D61B6FE6260A9672,E249E98EF30D4401,00000000A91ADF39,3BE13235130B9997,CCFC5CA23CD3FD8D,95EF1144C1838672,7FF4D939490F0D48,8D57BB07EE135939,78BD245D26969C0A,3E5926B6D87490A2,DC3A4313EAB98EB8,9F4627335EDA948A,00000001D2DBC82E,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0BDF62002A45A7B7,A4A5BED974FCC240,8B782980EA6BE9A7,1F398AB5D9FEBC55,91C1393EAC42B0CF,0E01D804CCC71E2B,2964B7AFFB34A21A,B050BB3ECAB170B0,6827F801E748341D,00000000B3D06282,C41ECDCAECF46668,3303A35DC32C0272,6A10EEBB3E7C798D,800B26C6B6F0F2B7,E0AA44F811ECA6C6,38BB298B83C41423,5C8E988E2C1B6909,D61B6FE6260A9672,E249E98EF30D4401,00000000A91ADF39,C41ECDCAECF46668,3303A35DC32C0272,6A10EEBB3E7C798D,800B26C6B6F0F2B7,E0AA44F811ECA6C6,38BB298B83C41423,5C8E988E2C1B6909,D61B6FE6260A9672,E249E98EF30D4401,00000000A91ADF39 - -g_R_S_im = 58B92E3BB6DC9E31,3E280F90A5818BDA,8BF300AC24A8E69A,2E12E47000B08F86,B01B3531200990E9,F63C539B47B5A4FE,9F70EF0C3FFAB9BA,CFBD59EBE2438F9B,1E7E8AD9F5361552,00000000C2DDA200 - -Montgomery_R2 = E75F5D201A197727,E0B85963B627392E,6BC1707818DE493D,DC7F419940D1A0C5,7358030979EDE54A,84F4BEBDEED75A5C,7ECCA66E13427B47,C5BB4E65280080B3,7019950F516DA19A,000000008E290FF3 - -Montgomery_RB1 = 4FDA7CB300F00BFB,8559FEAD08AF7CE1,6C728679071D8D77,FBFABAAF1825440F,00008D0536062AB9 - -Montgomery_RB2 = 5BAEA880514636FF,32B4BD3B3F4460CB,4802A8E49DA81538,9F99CD971298B1A8,E333BBA90FAF20FE - -Montgomery_one = 00000000670CC8E6,0000000000000000,0000000000000000,0000000000000000,9A34000000000000,4D99C2BD28717A3F,0A4A1839A323D41C,D2B62215D06AD1E2,1369026E862CAF3D,000000010894E964 - -threeinv = 5555555577AEEDA2,5555555555555555,5555555555555555,5555555555555555,DE11555555555555,C488963F0D7B28BF,AE18B2BDE10BF15E,463CB6074578F0A0,5BCDAB7A2CB98FBF,000000005831A321 - - -u_entang = 0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,00000000CE1991CC,0000000000000000,0000000000000000,0000000000000000,3468000000000000,9B33857A50E2F47F,149430734647A838,A56C442BA0D5A3C4,26D204DD0C595E7B,000000021129D2C8 - -u0_entang = 00000000670CC8E6,0000000000000000,0000000000000000,0000000000000000,9A34000000000000,4D99C2BD28717A3F,0A4A1839A323D41C,D2B62215D06AD1E2,1369026E862CAF3D,000000010894E964,00000000670CC8E6,0000000000000000,0000000000000000,0000000000000000,9A34000000000000,4D99C2BD28717A3F,0A4A1839A323D41C,D2B62215D06AD1E2,1369026E862CAF3D,000000010894E964 - -table_r_qr = 00000000670CC8E6,0000000000000000,0000000000000000,0000000000000000,9A34000000000000,4D99C2BD28717A3F,0A4A1839A323D41C,D2B62215D06AD1E2,1369026E862CAF3D,000000010894E964,000000019C332399,0000000000000000,0000000000000000,0000000000000000,FACE000000000000,84EEBD0BF76B38CF,8E40A1A187FF56C5,9882D55D30E7225D,CC13F8F7C6CAE46A,00000001A65CFE27,0000000338664733,0000000000000000,0000000000000000,0000000000000000,879A000000000000,58652C2F447BC171,819983FE0B6EB3DF,7EAFF7C0510A1F90,1697E12D3BADF048,00000000D0C354E7,000000039F731019,0000000000000000,0000000000000000,0000000000000000,21CE000000000000,A5FEEEEC6CED3BB1,8BE39C37AE9287FB,516619D62174F172,2A00E39BC1DA9F86,00000001D9583E4B,00000004067FD900,0000000000000000,0000000000000000,0000000000000000,4E00000000000000,422063C0EB0405C2,FB45F52C4D26626C,71C688F1E11B9E29,BBD9D547F61F7637,0000000065F68046,000000046D8CA1E6,0000000000000000,0000000000000000,0000000000000000,E834000000000000,8FBA267E13758001,05900D65F04A3688,447CAB07B186700C,CF42D7B67C4C2575,000000016E8B69AA,000000053BA633B3,0000000000000000,0000000000000000,0000000000000000,AE9A000000000000,79755E0FB9FDC452,7F3C7E943201E515,37933C394197EEA5,7484CBD136BDAB64,0000000103BE950A,00000005A2B2FC99,0000000000000000,0000000000000000,0000000000000000,48CE000000000000,C70F20CCE26F3E92,898696CDD525B931,0A495E4F1202C087,87EDCE3FBCEA5AA2,000000020C537E6E,0000000609BFC580,0000000000000000,0000000000000000,0000000000000000,7500000000000000,633095A1608608A3,F8E8EFC273B993A2,2AA9CD6AD1A96D3E,19C6BFEBF12F3153,0000000098F1C06A,00000007A5F2E919,0000000000000000,0000000000000000,0000000000000000,6FCE000000000000,E81F52AD57F14173,87299163FBB8EA67,C32CA2C802908F9C,E5DAB8E3B7FA15BD,000000023F4EBE91,00000009A932D599,0000000000000000,0000000000000000,0000000000000000,96CE000000000000,092F848DCD734454,84CC8BFA224C1B9E,7C0FE740F31E5EB1,43C7A387B309D0D9,000000027249FEB5,0000000A103F9E80,0000000000000000,0000000000000000,0000000000000000,C300000000000000,A550F9624B8A0E65,F42EE4EEC0DFF60E,9C70565CB2C50B68,D5A09533E74EA78A,00000000FEE840B0,0000000A774C6766,0000000000000000,0000000000000000,0000000000000000,5D34000000000000,F2EABC1F73FB88A5,FE78FD286403CA2A,6F267872832FDD4A,E90997A26D7B56C8,00000002077D2A14,0000000ADE59304D,0000000000000000,0000000000000000,0000000000000000,8966000000000000,8F0C30F3F21252B6,6DDB561D0297A49B,8F86E78E42D68A02,7AE2894EA1C02D79,00000000941B6C10,0000000B4565F933,0000000000000000,0000000000000000,0000000000000000,239A000000000000,DCA5F3B11A83CCF6,78256E56A5BB78B7,623D09A413415BE4,8E4B8BBD27ECDCB7,000000019CB05574,0000000BAC72C21A,0000000000000000,0000000000000000,0000000000000000,4FCC000000000000,78C76885989A9707,E787C74B444F5328,829D78BFD2E8089B,20247D695C31B368,00000000294E9770,0000000C137F8B00,0000000000000000,0000000000000000,0000000000000000,EA00000000000000,C6612B42C10C1146,F1D1DF84E7732744,55539AD5A352DA7D,338D7FD7E25E62A6,0000000131E380D4 - -table_r_qnr = 00000000CE1991CC,0000000000000000,0000000000000000,0000000000000000,3468000000000000,9B33857A50E2F47F,149430734647A838,A56C442BA0D5A3C4,26D204DD0C595E7B,000000021129D2C8,0000000135265AB3,0000000000000000,0000000000000000,0000000000000000,609A000000000000,3754FA4ECEF9BE90,83F68967E4DB82A9,C5CCB347607C507B,B8AAF689409E352C,000000009DC814C3,00000002033FEC80,0000000000000000,0000000000000000,0000000000000000,2700000000000000,211031E0758202E1,FDA2FA9626933136,B8E34478F08DCF14,5DECEAA3FB0FBB1B,0000000032FB4023,000000026A4CB566,0000000000000000,0000000000000000,0000000000000000,C134000000000000,6EA9F49D9DF37D20,07ED12CFC9B70552,8B99668EC0F8A0F7,7155ED12813C6A59,000000013B902987,00000002D1597E4C,0000000000000000,0000000000000000,0000000000000000,5B68000000000000,BC43B75AC664F760,12372B096CDAD96E,5E4F88A4916372D9,84BEEF8107691997,00000002442512EB,00000004D4996ACC,0000000000000000,0000000000000000,0000000000000000,8268000000000000,DD53E93B3BE6FA41,0FDA259F936E0AA4,1732CD1D81F141EE,E2ABDA250278D4B3,000000027720530E,0000000670CC8E66,0000000000000000,0000000000000000,0000000000000000,0F34000000000000,B0CA585E88F782E3,033307FC16DD67BE,FD5FEF80A2143F21,2D2FC25A775BE090,00000001A186A9CE,00000006D7D9574D,0000000000000000,0000000000000000,0000000000000000,3B66000000000000,4CEBCD33070E4CF4,729560F0B571422F,1DC05E9C61BAEBD8,BF08B406ABA0B742,000000002E24EBC9,000000073EE62033,0000000000000000,0000000000000000,0000000000000000,D59A000000000000,9A858FF02F7FC733,7CDF792A5895164B,F07680B23225BDBA,D271B67531CD667F,0000000136B9D52D,000000080CFFB200,0000000000000000,0000000000000000,0000000000000000,9C00000000000000,8440C781D6080B84,F68BEA589A4CC4D8,E38D11E3C2373C53,77B3AA8FEC3EEC6E,00000000CBED008D,00000008740C7AE6,0000000000000000,0000000000000000,0000000000000000,3634000000000000,D1DA8A3EFE7985C4,00D602923D7098F4,B64333F992A20E36,8B1CACFE726B9BAC,00000001D481E9F1,00000008DB1943CD,0000000000000000,0000000000000000,0000000000000000,6266000000000000,6DFBFF137C904FD5,70385B86DC047365,D6A3A3155248BAED,1CF59EAAA6B0725D,0000000061202BED,0000000942260CB3,0000000000000000,0000000000000000,0000000000000000,FC9A000000000000,BB95C1D0A501CA14,7A8273C07F284781,A959C52B22B38CCF,305EA1192CDD219B,0000000169B51551,0000000CE1991CCD,0000000000000000,0000000000000000,0000000000000000,B066000000000000,B01C62D467945597,6B7E50B3292AD5D1,486A2C0733645917,D8CF73F29CCFE895,00000000C716AC33,0000000D48A5E5B3,0000000000000000,0000000000000000,0000000000000000,4A9A000000000000,FDB625919005CFD7,75C868ECCC4EA9ED,1B204E1D03CF2AF9,EC38766122FC97D3,00000001CFAB9597,0000000DAFB2AE9A,0000000000000000,0000000000000000,0000000000000000,76CC000000000000,99D79A660E1C99E8,E52AC1E16AE2845E,3B80BD38C375D7B0,7E11680D57416E84,000000005C49D793,0000000E7DCC4066,0000000000000000,0000000000000000,0000000000000000,AB34000000000000,350B1FE05EFF8E67,F9BEF254B12A2C97,E0ED0164644B7B74,A4E36CEA639ACCFF,000000026D73AA5B - -table_v_qr = CCCCCCCCE168F4FA,CCCCCCCCCCCCCCCC,CCCCCCCCCCCCCCCC,CCCCCCCCCCCCCCCC,76D8CCCCCCCCCCCC,03E565465D2C0BCB,B12E9DDC577A588F,1F35C932D0B247B5,0521DAB18F8F36B0,0000000231AFE7CE,666666663D2E160A,6666666666666666,6666666666666666,6666666666666666,EE52666666666666,5B25D1449A5D48C5,D37242D15A2B4239,263FD38E8023BAE9,F8DC6C2184B143B9,00000000948D7F34,2B7522B7524531E5,22B7522B7522B752,522B7522B7522B75,7522B7522B7522B7,ED882B7522B7522B,0F1639645024AE01,4F035B12DE5E50A0,73C4980ACDD7F1A1,A42840C6580DE412,00000001DD62C7C0,915BA915B759C347,A915BA915BA915BA,BA915BA915BA915B,5BA915BA915BA915,0D2C915BA915BA91,71F86F2E9E45744B,40364B61A6454DC2,F1CB7911E8296CFF,22098A2EFDE7A36E,000000026EBD6120,AD9149BAD91637DA,9BAD9149BAD9149B,149BAD9149BAD914,D9149BAD9149BAD9,9F25149BAD9149BA,D62B18FB0FE869F1,C55BADFBDB1E3966,D3983013C35F72D3,CDCBA5EC343A38C7,00000000A9663F71,375B229374E412DD,29375B229375B229,B229375B229375B2,75B229375B229375,77BBB229375B2293,2DE6294756311D89,7FD8288210926F0E,959F6E4E9B17AAF0,D0DF547715963752,000000023F992A62,095AB46517CB6558,F00AC4C8322D018D,C4BBB5E824213413,FE54FF999E981B8B,457485163ADB696E,B3837BF2C2444F67,AE6D4CC9D80D6369,16560F053370AC84,23263644FE26E906,0000000070C8ECA4,1499D806F149DE33,192F79503F8504C0,8136E31922FD0B62,0E3640C9A3BE918D,827DC7EEC12747C3,816C63BC5D0BB5E8,2B161316CBD65F8F,113FC50958EB09DD,6F238E5A72A41216,00000000ABCB36F8,84665F30F3CF95E5,C3B84BD34725A330,3A6AF0FAC575EE0A,9C71AFCF5C78A658,B84BA4EE269DDBC3,8E25FEED6714479A,6FA95E8F73EA96FC,4E8F67FDBB4C1B14,9F723476F170C736,00000000BA3A5C22,9005A1C185D2E4DD,1804C2F06A988218,5C73BC15BBDE0797,C72EA5FFC1BE0B12,5F5D25F1D4AC4F2D,D90ACB26BB0EA9D3,771734D57DE89542,B9B7016789BF68DA,4AFADFDC405345FF,0000000114409A09,69E362D42702ACE6,9FC36EB7EA12F1E0,9CCA7DF3BC005DFF,D8FB897860F89087,684E603A54569145,59A0620287865C95,A1EE61177C586BBF,DDBC6767DA8F6EE1,9C092A6A8396897F,000000027991721C,E70C93731F788DA2,F9415624BA1759DB,C894EF9847A7245A,E2380C3455075FCD,63CD08DC462AABF8,0A1CFF8CECB706A7,5BBB070AC484296B,F8E970373DD450FB,F985BF0108DCBA20,0000000243AC61BE,886DC36536F16AC0,CE46420B9809323C,8F0CE1E1A569DA62,574F7A978263CAAD,93BE116009D2DB5C,E47CE9FDE2BCB17A,AEFCD1BFDE2FB352,6596D37050A6FE96,A936C53A6B044AC2,00000000BAE5C165,DF14045D75410E1C,A73CCCB143DBAC13,20FDC4139A3DA98B,B91023F5D83E66D9,E7D50F33079A6014,A6117DAD2E4A7E4B,78B9C7A26D42C39F,8856BF64102261B1,31F624C6B2E5E24B,00000001A9000C99,4D1B7C9879B8F55E,2A149D570FBDDE34,B2B6E11841366015,BCF5C4F2C545EF76,939396F37CA988F0,2F66041FC5F19298,60D9027E6FDDE5C8,594434D0D278B451,DABB15ADAEA1D3E7,000000024D1C996F,EDE936859CC846A4,906F12AFE543BFE9,57F752DC24BCDF97,A7AA6C41ECE9523E,70D8DB291C664F5E,C2D8762B1F0A0862,F538248730EF2597,E1699BCD8E10BBF7,4A5EA2590DDB6DCC,000000022EEB1551,F2A95939B0FDB788,0220AC9E23E53C0A,37C7FB2D043F1549,17A39CE70F0B8E54,F8D84DD2D87A4331,CC560AC3C2D4ECB1,29AFE290E4B8470D,5FD3854406911AD1,16284324DEA12E26,0000000265A1E3E1,72512896E203613D,42909204E70C74C1,F2787ADE891C95AA,726631D78DAFCFF5,812D335F7915E3B4,602D763CFDD14E0D,F09DBF94B4B8587D,95CEDD56F23A03B9,35067361D5A1D79E,00000001FD8BE4EB,401CA1FC04E9C123,90C26307F5CC0A0F,485D5BE49E59B0C3,04FE729949842C2E,DFE318C2AE76911B,D12311AD4DD78EA1,E40CA0745241900F,3D124917B409965B,0BFD7D5AFE6476F0,000000006D74FB8C,2F3F273A24BD4ACD,BBC4B38CC68BA0FD,E8B2D539670B7871,EA60CBAEA93B6577,487E2AEFF59AC1CB,D2D62FD5A457C222,778BDCA33D649C39,D6463F406CBC16A4,726CA44086DD4B26,00000001D3824D0D,BDB1260A3702AD09,2D6B1A339991FEBC,AA9F6C83305EA847,A046C8AD7DFDC0E3,D44F15831B61D266,E5069559BBEFA954,D78E56E41C84CC4E,0760438E0D334C5E,AD70552405CB2442,000000026FADBB00,62D4D20873F55316,9E0A17CCEF05AEAA,3297B1A6560ABFB3,C178F3490A1BFF80,30F33204C7CD322E,BF67D1323DD3AF36,C26B4425CDECACD6,FD1804929AF46345,6C6AD7A3773EB3E9,00000000A0F5703F,7B5586A15EEE987A,712704F03450E84C,6FDC36F98F02AC0C,A1B5EBF84C82B74F,070B06DBC6C6FBB4,F49DA4BBBBB4A081,D539B581C8C78E70,C505DC913CDC308A,79302B7361615850,00000001FDAD6EA8,C864A00E76FB7862,7F79E3208CF1BA8D,CEBB9173B4F3EB3F,65B5CD9A69BCEE1F,2FFC82DF6866F802,372294003EFDDFB6,2B4A606D7D21B67A,FCCF899A749472DD,60AD6F3318245C4F,000000008A94EC6B,3B540A505CFDE08A,1F4FA2605E47B5FD,545260EAD2FAFEEF,EACCE2AB9D6A73E1,4DE929F08605608A,7FD4E8C4330111E9,ACA7C41ABA9F32CB,81CE18FFB987259B,CF27FAA2E00078FC,000000013C2D3CF2,AC298794E336248F,A36E730E1546DE9E,ACF027D5C26DA122,F5F2E5A8A5CC01FA,BBDC81BC339A2257,70D7847A7AC291EB,653A274765BB19A2,4AD77CDA41E716D9,909862AA50015453,0000000214843766,28DCFDDEE7E75520,926112237D3B1FF5,01C7EF82595F8671,1506781F7F3CBDFF,6085630169990327,E99E1AB62629523A,F5124A3DA6D4B381,6238E3E6BA5CD147,FF73FD00F4AE2505,0000000267B4E1A7,4562207B3C7D2A3C,5326B1E0C543FDBD,DB4DEB9EFDF44D2C,4127DC9D580DE9A7,0B5A21F4968C0B6A,551995E644DD6F9D,A410258D02B6BD1A,38AD3333153D132C,BC05805A3AF78F5E,0000000118462D9D,6BCC76AD0919255E,1CE349F8E0113FDD,9FDDB44D41754041,17B14F71175D7A86,FF025B1D9403E728,0B066EF99669BAC1,823A70C11307F544,E302A74F2C217B92,44959A86BE1185DF,00000001AAAE7CC1,BBA91C2845FB1C23,0FDAEBA39658D3CB,D20FA6CF11D6712F,E1F96B50E371876C,8FCBEAD568182A6E,7470BD4B6F6ECAC0,854B204F3377B675,1A4069A8A9B7FEE1,D94275FEBB51BF6B,0000000278D27918,6426BB8949C81154,F8E70C86ACAADADD,0254018F73FF1D13,299DE9B99FB375F3,FAD85F5B9455BC3D,75B38230DECC8C86,84D8352EC4455A3E,C63E8F4D14896C61,ABDCAF24FBE2620C,000000018DD5BB6F,F983D3F93B7E21FB,A1EFB325856DFD63,B40DBF77DDD2F2C6,90765A64B6E3095A,5C97784B64B13624,A66B10ECDB13601E,56B0519E348B08D7,0377A62607E2C784,BD9E2E4BF13D82CB,00000001FF451525,10BEA3C10F74187C,D1A28B48103C996B,71DE9B27B2DEE637,CCD9CF6314DF24F6,A3509CFF5B01D17C,BD870219DBDE553D,0C24847905D600F2,3F6029BE326908F1,956902BB0608AF31,000000019FBAFFCD,43909A8B57B3D387,011CAD4DD5E94732,5ACD10DE50BD4786,A485CF553F041B2F,78621C881B370A7F,54D76CE547ACAC13,D2BAF160F13C3B9E,4FDE5E64A3480204,2501DA6825E2CC9A,00000000D63111F9 - -table_v_qnr = AD4AD4AD4C6A88FF,4AD4AD4AD4AD4AD4,D4AD4AD4AD4AD4AD,AD4AD4AD4AD4AD4A,A6D6AD4AD4AD4AD4,9AEFF6AA14208728,25F686D3A6B965DD,89CFD24F7B8B05D6,3277900023742A0A,0000000181A60983,95A95A959CABB803,A95A95A95A95A95A,5A95A95A95A95A95,95A95A95A95A95A9,EF5495A95A95A95A,9FD9D03AB2C137A2,D6D285BBE104B16D,2D2DEC66777C8B23,F413D3CA7DE5EA6B,000000005EA0F8F0,890EF755DC154E99,A890EF755DBC422A,2A890EF755DBC422,22A890EF755DBC42,E6F8890EF755DBC4,992CEA18AE912E4D,78C13445EFF8450A,FC7F0B40B903DCD5,3DEB2380F4A72BD3,000000014B83DE77,5CF29BF686807934,25CF29BF68C35902,025CF29BF68C3590,9025CF29BF68C359,0E9A5CF29BF68C35,298A955A6155A056,8F77CBC74E2AE5F6,366A3337A563ECA7,B5182885FF4D6097,00000001885CE5B2,01060A07FBF2642F,E01060A07FBE7D7E,7E01060A07FBE7D7,D7E01060A07FBE7D,832001060A07FBE7,ED7D83B8855A105B,61124019E05FD124,17593771A74013B3,65ED650971772921,000000027986C521,CCD20A70CAA86EA0,3CCD20A70CCB7D63,63CCD20A70CCB7D6,D63CCD20A70CCB7D,E023CCD20A70CCB7,46FB7D673A1F3731,4BB2D66D1167EA52,455020A49BCB6949,65C58A1BD6024304,0000000079DA31E3,0C8A714319269CBF,3EE6C5324FB03682,820C8A7143192186,863EE6C5324FB036,EB040C8A71431921,136A320C0C040BB6,168E5DED014E95FF,823E3A98411D42EC,BF3B909BE84CA071,000000020313C368,79102520ED23EA0D,4F1889D99670AB6C,6C79102520EE923E,3E4F1889D99670AB,415279102520EE92,70DBE13BE1C34F41,5B5EAA3FAF145AD4,783FC4CF8CF9BE6B,137330EF8AE1C880,00000001B4499FA0,4634145CDBBC7D65,BE4634145CDBB9BE,B9BE4634145CDBB9,DBB9BE4634145CDB,FC11B9BE4634145C,2FE8FEBF758B8693,62828E9265ECF9A0,1C4ED813B3BC7207,846F272559B2E04B,00000000B0BF2182,20103473E1D7FF3A,2920103473E2E529,E52920103473E2E5,E2E52920103473E2,896EE52920103473,11F70027A281C06D,3B5E57817B07BF75,AB30DBCF075069D5,7934D8F49EE1D2A2,00000001E5CF7B77,9A1999347725E051,99B2E2369C46A0F7,477258EE57C21979,69C46A0F79A19993,56DA2197999B2E23,CE319B8B5D5BF252,5FFDE836E4511966,3C4EE6DEE16E12B3,F9D395517385C677,00000000C56DA3A3,A333A4F9F563A486,16C18290308AE972,9F5BF3DD45A35733,0308AE972A333A4F,F74E3573316C1829,6C7C6702DC7153B0,77D40082BF6132B4,D95D312C4920072E,7E9DE8AED502DB52,00000001795EC244,BFAD90149BFAF2C4,AD90149BFAD90149,90149BFAD90149BF,149BFAD90149BFAD,7E72D90149BFAD90,06866E05B5982496,C0A9956428181AA3,692DDBE0498CF749,8D9D8E6C9C0C1C9F,0000000123FACCAD,A4DFD6C80A1A7714,DFD6C80A4DFD6C80,D6C80A4DFD6C80A4,C80A4DFD6C80A4DF,8425FD6C80A4DFD6,8E0BC711DB513DD0,7A798B500484E43A,0B493DF45AE3AFC5,35B299EB698262E2,0000000251C8F93C,F106BA2361C0BBFC,267751BCCB188710,CF04E54D6488BC95,E9C02260C68B4DBC,A0F2D5B56BFB777B,C62C2D54EEB3DD6D,8C3B7A47FF6C7E8D,E7AD379C550443FF,E820CAF499D9CD06,00000000BB9BA44B,CECFBC1D4AD7905D,269973BD729F0BBF,96F247430346373F,3C32617FB97A7BB4,170F7C62323C3A3A,1B9DB0A6D879BD7E,DA82AC8B59360996,0A26FE113F634C7A,7130F589581CBC64,000000013858DF6C,7E5D2D52571E03D0,F75D1072B445F79B,706331C41D88D1D5,265B33A4D24975E8,C97488655D632ABE,6D82AC11CD7F6048,B030079E0A9EBAD4,A7E87B1B62EAFB16,9522F6F141D35D44,0000000082B24B60,242547937C0658FA,DC6E5DA7AEE53E68,84EA07953DACDA65,E92546CBB60D8BA3,A612BF6B9CFBCEAE,B2353AB9010C800F,1BBAD6158193C629,5464119263DFE2DF,50E7B308405743DC,000000020FCCD43A,6D72564707F57DA7,44E62AEA7A94D72F,C60D55CE4D3ABF28,C819D3C0BC081DE5,161317D2034B91E3,9A84FE10A373C3D5,D73276492F6D4036,5332ED7A2830AE9E,CC28BE76FB2DF00A,0000000120CA3CCB,FAB2620720D754B4,B0B9E340EEDF8BC9,1653DB4EA86AA228,AF4A45B466A291F5,6F2D8FB5B3D8182E,7774D2D36F2E881F,C3D2516E474E557D,92B45DD23EC32833,3984A07B8619C7C9,00000001CAB80BBA,0E7CC90E6EE298EA,99D3392BBC06C468,E8F51B6B2D8C36DD,7477C602BFC793C0,4CC9A5B9824BBB8D,66B8B5F5427D3453,0CC9FA954AA043A0,E68FEBFA58A0024E,1C4E709FC346F24B,00000000E0867832,16134C45F74D2894,0645075230AF517E,638788BD12EAF884,BB57CA874264F15D,83B306DD1713D2A4,623C0C908B287197,BA8FC5C2734F4A9E,FC971C3F17C55B04,61546665082121F8,000000018551EAB8,047236352CCCCD4B,807700F6D1EDDCEE,17537341BAEA6CBA,504419A64B50C73D,2591E7171ACC64DE,EB04A5C122391E85,D96557BF89D24F8E,780CD38FF64726CB,FDAFF780CC4EB54E,0000000011861577,302306EE9997BC4D,3E045AB634949BFF,CC742F753994DECA,7E7F0333368EA0FF,8A8430A2AB229760,0E1D75408F952D6F,4F3D600657F280B3,DE89E80487A538B0,68D1E57A19D64620,00000000D0027A4E,5970FB914A91F4D4,EF97BEC7A9F0D144,693EE802E571FE58,CE320E8569E81BC7,2FE521976533C96E,E5D7F9268E7D0519,0FAFD246C31C4833,7218544447E13899,EA1FFC738CF3C5D3,0000000095EB5BCC,5B105189D0CA2ADE,CEDD8AD3AABF2386,0A052407BEE2D471,D51FFCA04EBD31DF,7CFF2C4FBFF9840F,68E863DD7BE0FB3F,71ADC0F419B76B2F,9F2486034EC06308,EE7F083774F1E588,00000001782E172E,26B06F653E426CA3,653E426B06F653E4,6B06F653E426B06F,53E426B06F653E42,CD29653E426B06F6,E25934934CDB47A9,368EE07F45083838,FF81E126E2784509,B7FBA2C6FB2C0307,0000000066F35905,7C84D60DEC9AE6B4,0DECA7C84D60DECA,C84D60DECA7C84D6,DECA7C84D60DECA7,5F6E0DECA7C84D60,5E606F56135F2DCD,6D881359A8F60397,381AE539FC37E98C,29BF8428D894967B,000000012918EDC8,BF924F1BF0EB7ADA,C78EDA5EA1CEF780,048C247D7D53CFE2,3FE9A831F3E25AF8,C4223C70A27E8F90,51DCF86B78B6D4C0,029A14DBF09A8A42,35B0B186FFA03AA9,B34DDE1D41C9D131,00000000F56A46E3,253AF4484C94CA03,32A226E35D2A4AA2,4FB18C5BBCF1589A,3E17070314360DE9,B94BC9B9873E96C0,8A3E6EFEA06EB882,C06DE286FA2EECCD,124298F6432B070E,25CB59755BA0A18B,000000014B1CD916,BF83218A8CCC3E78,5BD5A5F17E801598,2F948F576364D3E7,F9D2270EC3408B6F,C00D05257D2C78BC,3CA32AC0114D7EAF,16D9296AC7B7D2D4,6E661F03BA457337,3F69FD67E3F62F31,00000000A70AFB41,67B914B86B6BD1E0,9E7D53018B3CF47E,4A5172C659663E8A,CE0F42ACA114BBDA,CF29856D865D954F,DC1EF1F853824B06,8D28378F21C8EB01,8140F83D8E9FBBA9,00EF3B3FBF4817BA,00000001CEA072EF,B04ACFA73EA0C46C,CF933F68BB9B3F4A,15AE5CE2F27DB04C,1695B1823A1F6D59,0D753A316CA51CB6,7445E2D99B0BA50B,00B6F9A9A580E786,51545996DACD4F17,112B452323F4F0A3,00000000AFBF4B5F,0A8982A5E43B37B3,4D1DFB947C1F2BC7,7A938628C766F64A,545AB97381CCDA04,D8ACCB93F83D4C5B,CA5959634A186221,9E72DEA20E161486,03FB2EF9969B4F6C,0A62EC7356550C78,00000001C0F7BD25 - -v_3_torsion = 06EB3E454124AAF4,EB3E45306EB3E453,3E45306EB3E45306,45306EB3E45306EB,0286B3E45306EB3E,375E62F5BC7C82AF,650BCBF202B9AE38,3FDD465F450DFCFD,C63A99445C986900,0000000250ED785C,2983759F1FCF38D7,83759F22983759F2,759F22983759F229,9F22983759F22983,4EEA3759F2298375,87430979EEB424F2,4D75F319566660DA,30CD05437A146239,0A2641600BDE8C04,00000000712AA3BE,CF43C7FB897F2FE2,3C7FB84C2F0E011E,FB84C2F0E011ECF4,4C2F0E011ECF43C7,751C11ECF43C7FB8,01D007C113B5D095,4235B0D5E66773CE,9E42B6C94350F39E,B98F10656ABF493B,00000000A2738C79,C023D9E87818892A,3D9E878FF70985E1,E878FF70985E1C02,8FF70985E1C023D9,52445E1C023D9E87,C4A56A1DB3037852,BE1F9B0F8C463146,D7DB04211C8A255B,87C4C4B67CF93C1C,0000000096C2BFBD,BB5E4448409D1B64,9650668A321ACCD8,48D39ADBC2F1339E,8F7071B9DA7AD093,DC2BFF88AE51552D,67B12046E4504FA2,DAC40568A6E7ACA6,62ACCE83A2BE7FE7,CEBB880D5DC0D19E,000000025FA2A502,12FE408DB093593F,AAF044FB38FAC1A9,02726CD500D0CEF1,1605D37D0757467F,01B66F6542117A77,1350C0D1B1A7435E,51F0069F69135871,203791450029A4BC,42B7E3FCB870BE19,00000001CDC6F300,7B5CB802B56792C7,BD1E27BB33DC664B,C2399B484A347FD4,5CB802B42E1D844C,7699BB33DC664B7B,A62220120D0CB91A,24AAF6ED9C3527F0,1FA962A3FE0A08F3,219A48CC422DF1B1,0000000118AF1785,2085638DAFEB8A83,FD68A923B68BC5DE,9743A21DF7A9C724,85638DB029756DC4,09A323B68BC5DE20,DC5A0F3CC5799C18,3CDBDDF993C3E933,399816785890182E,3DDF5FEAA7F4990C,00000000AC3F3421,63BDA9468BD342F5,7403E8DA50E41EF7,7B32C72BE3C39E62,A4AEF030E69A6DAF,C8E9EC938255BB45,5AE36274AC3BB919,AF73A8FEA01C6E98,6C9E0C391AEA075A,DE3F1DFEA825A09A,00000000495C0A99,CDBBE48241B79B59,29FF396B0854C507,C91466B43E7DC219,A46772E1FAE15C03,C113B29586A5D8CF,44FE6A6E5B9FB7B0,11825F97D892585E,C1F3209A0E0006B4,313425C4139E19C4,000000014DB5D37A,3011EB8A0C610EAE,8632968FCBEC6D1D,EF749BB7DE6283EB,1038A58CDB855B10,5574052BEBB46182,B3E1CF3C83597C0F,A718ADD06AD56610,359FB5AA447520F6,CDF6E662B8EB669C,000000009CC50ACC,4E213592827CF602,B80C916F6BF2EBB6,D05F9D238FE11743,5FC7793D16D042BF,BD58FD8E99F594EA,C1100B4C07C4A897,29F16A0996A54969,3A7EB43A7FC5530D,B3EF41DC7BE3CE6C,000000004A3A4407,32CEC987C02E1E16,B7E44C9BBD497EE5,59C0313782E83DF1,2C71AF09B871F5DE,E44DFBF49F9CEA51,C4BD0DF1CC341EB3,7EC7C21EE53DE39D,2B1B1BB9C6276C2C,F86DE3A5ABE9539E,00000002302FFE8B,28DF22C8DCD7982F,426541E94DCF04E7,98CA1BA8F9B2855A,F4067E6F7EA49E1D,D03034D68F095472,7D26821B325A3A85,87DB2B11EC3322D6,73BAAA33C117FB57,92225964AC014B47,000000012E0D7FE7,DF2479A490E3F3DA,E07894F7FF684C36,9A5E7229EF62380A,E88DF8EE954C69A4,800A8000EAE4D453,AE77A73EF2BD6B7D,DA18723BBC2CA8D7,F186FA30727D2A31,291452F619104C5B,000000001E7F1399,3732F21D651B1FEE,8DDCCB2BDD071E43,9641B49A54A8A116,DA68148CA4D341DD,C32B7A049A23B8F4,24932D3124EB482F,84AE00B5C46870B9,CEAE14C3C3D55562,097148EC2C4193A5,000000001D94CB43,5DDBBCF90B937BD9,03E84379AA3442E8,CC25DC2808E0C528,FB444A0D98465DEB,D69F5A96BE71AC2C,13938F1D6E581318,37AE0B4F7DAC04ED,863F2AD318BF5A7F,397673E27BAC9DEA,00000001216A9621,0904B65B8E15A658,C7BB97BD7B0C45E2,93CD91DECA863B07,07E159E553BF8497,5075FEF394A53914,E7E384970BABE75A,5968B82EF98ECFC6,29B5FE78CEF214F8,E3F63B7F9DF9725C,00000000FDF9B378,57CC8084740AF239,5703E093ED1DEC26,700B10597FE6838D,BDADB8A8DE7E5988,3EEB9E3F634109D8,C632284A295D87A2,0FF7ED47380421F0,46A42D85372D6D51,CEB02C53FD6561AD,0000000068700397,94083C312FDD1CCF,8D8BBEBC2683FDD4,DF6AA14583575AC1,DF3FF19FF44AEEA3,CEBEB4FB032ECD7D,09CE783658636286,7B3D4444C53B3D32,0B8749FA7F3A9070,C415DCDB6A0AD61E,00000000B7869319,139CF42869D49482,0BC6F0C720A8973B,28E407583814A9E0,F00EFBF2ED7F95AF,7D480A57AEF5BFD3,7EC46EDF97D9EAC2,B3F987339979273B,699F07E12CA4729D,7A1D6F1D94D877DD,000000024F8BFBDA,971EC29363AFF4EF,0A525D0504E28FD9,B1499925B9A9134F,3790DCE6BA9C9907,9E2EB2BD7D2BDE58,B1A37E98CE909692,4C9EB9AB58C0D4A9,77A16CF26A2492C6,B2121E58A818AFB2,000000005FF8FB81,D59C657588B26B4C,B824E399449753E5,B2EA59D067504894,2E77C98265BE8415,3A34AD15D89E7895,6AA2E3EAB0F65905,3A464491A81B6AD6,64AFCC145F1EE37C,EF30841D92867D4C,00000001653C11AC,C4A62DC72662944A,4BC6EC7683E05B2E,DE0AB70705491613,7FC5FD6400FBAE3A,BE093F12B7441F4E,754D61F85BE9B748,ED144F4AD57B89A0,4B6DFB51DECE2551,67980426FCD240D0,0000000075699852,D3D4BB413D7061BE,18AEC9D6854ECB25,74912785EEF65EF3,428B21B602840579,7BEDFBC19961AB28,E537045DFA2E6F0C,AF709EC9946F55BB,D4633E3CA2BBFE3D,DDF84B965ACD8170,00000001837A2775,FB8249F345205225,DC81B2C34B0B30FC,F5B9D98AC4766CBA,8B37B96AC565EDF5,AB88EC455AB3E730,F99410A2815AE199,926C8A85493EB093,C7082D622A51444B,FE11910D6EC752C1,000000022D0E6336,FBDC842A96D96B13,EE3034ABA5D2EC9A,5D4BFE83ECA3D306,010CE1C3DB0210EC,645EB45E9AC10E46,99085D8D171BC2BE,9F361AF1FC456B18,08D9D38D8C416A25,B071C0B7D59CE33C,00000000D89DA6CB,770A7B6239055C1F,E9767FC8D42B73D3,FCC1954DC3AC1EE7,1251746D17D4CA40,0D83FEEE6736971D,B0210B1F8D0AB262,3DE49D676CD13FB7,1657FEBB10C212AF,2F61A2D8A3F81312,000000018E3342F8,D08AB92DAE048DB1,AFDFB841D45B6CDB,4E16B9F649DBDAD4,8F7BD80A86CD6FE4,E9D860EE31368282,AB87FA97EF9B4B4E,595B5FD6D5CD3C22,8B2AF45E9CDA91B3,2DFE5B32A817912D,000000001FB079EE,6B3EC443091B482D,9248D66829014899,0638D81CC4AE199D,5E8DE73EEB6DE96A,55771848724D17F0,734CB651B4339600,FD2432CB79D99C1B,373869CEA55DDEC4,39D83CB6F4815AF5,00000000D31D84E9,8FC08908D008677E,F50D53E90F7118D4,38984342BC5C5F12,9EF8ADEE9D890053,2E9134B510F28488,8951AC1CA56CA72C,7CFED4FEED36EDEC,CDF3038414AC384C,A2C3889B433C8C6F,000000027A01960F,A3526DB518930119,DC37B0E13644ED3F,6E31E890F08A37BD,A37A5E57024A8AA0,40B194BE09CD892F,F8D9FD2F6BFCA6BD,20DFBAEF4B42549B,45F0B1D7FBC11721,5E7E3BB644063BE0,0000000171428956,B637BBC305F67791,204FF0D2AEDF672E,F92D3782494289DB,24F7EB7320299A80,977CC127123CD922,B6C51C2947B68DB4,BEFC8E5B0AE18F09,FABDF4A65AAD3791,AEBB5AA66A4EC660,000000009F9CF17F,110C3AF5E13E1951,F40DC401CC686B06,68EEA45A46B10505,325395A25A0F0DE9,1C92E56F56D28E24,D0F8A55787894E1F,EEEC7393357C5523,5FB696B3518CC792,D39D05F3A9382E5A,000000026B74CDB1,BDF8A208F713F4A9,18481280856177D9,10BD738108662F2C,1EF37C1AB5531600,98D3C52040B3E9DB,8E988D26C011FF69,018AE98AA255688B,8E60CDC1B136648B,7E91BFE825833F56,000000013DB93F4A,0C90DED2C7313B98,82F6CE5855C8D3AC,D22BF07E7380D124,E912C49BBF549FD8,BD34790D9C351C45,4A1A372896AB66BF,44E6AD3D3CB7D968,473B9962DF10B605,2DC4E87221525887,0000000000D61465,3E77A9B726C4E35A,72508865383E24E9,703A850A1795B24B,0B744F39B78F82E6,BCA3D4CB44C8DE88,98BB9A1523EDC1A1,1055B9EF0ED241A1,0DF619C4A7A3305B,D3CAD19AFBE71CE8,000000008A810A03,78553A5AD2AFD1FC,87C486E5D053F7C5,0D49A2C8D3988259,D059B9BB567D1CB1,5D10F35FBB64BF63,B6A58DE0F78BF9DD,CD0DEBAFEA4B0478,DAF46A0964D3FD0A,8E33C74FE2F70AFC,000000021CAAD2F8,3BABE989C4B7C8C6,2BF8F447EF3BDD7D,20EAAD8C5457CF18,8C176F27BA3E5B6D,6994DF1010BAB10B,C508E30E46C0CA1E,A48AA3C16405257B,FDA00D371BEC4681,9D86B52EDF6EC9F8,00000001C34BB8B6,ADB4F379816C780A,C25F504173CEACF5,1DA0375FEB0BBE8C,0B87264B37860585,E0E1B8080C0215AB,A4E2CD906374B7FC,5326260B7A3021ED,168C806A9FD020B4,DD2E356F2066C037,0000000110BD582B - -T_tate3 = 1ACACEE95C25B36F,8283860F86A452E9,E463E8A5F4ABDF67,5F4496B7DAFFDFB8,B96E4571923D8135,C0A7D039BB9DBC00,5B4B7691B62F4EB9,D5DB546FC843767A,0BB5D5CB6F297EDE,000000008683C34F,D51008F74037048C,08C9DA54F68721E6,6E6BBBA73729328E,16A7B8815DA44FCF,B9103FC3DFB5402A,4344E673E040795C,F6CBC30639B40D70,B5B2A09F36AF62F4,391A008C7948C385,000000022259942F,2E7021FB37C11B7E,135FA1CCFD99A476,6DFD54E21ACB8758,48F64935DF5A5CA8,1541ACB019E2466C,A9EB8C72617BAA9F,52EAFB8F96828E74,12699D6A31D85792,98E48A0A28C02C46,0000000177CA30BB,8F692C912C63FA8C,9DD48425F0A9B9EF,5793C472BE67B781,F1D532FA444D9A39,B181C2847E631112,6D791AE36802A83A,FE5F4F1D7D5803B2,D87D8AB8CFE2A161,76D777B51A654279,0000000035C64E9D,5527494F2E46C083,B43900E98786EDCE,60E4E9E9EC328495,A48B3D4A7745C7F7,CD9EE90CBBE6CABE,EAA8C52F8FDDB50F,4FAD073D21E314B3,0A6D657EC69C36C0,67E409EAC1891280,00000000DBADCBFA,6D33BE2991DEC70B,512447B1C4BDC002,1AED6BCADA4185C3,3079F4483460C2AC,6B116A3D4AA94F2F,C07C8496E931546D,01AE8CDFD601C143,D92303156AA0F57A,1DE0BA566C5629B5,000000015B563596,0DA3DE36BE80D087,22FC2AF2844A8C06,646D8D7BD0712EF1,5E4D6D5F34C4A489,3BB015996D1117A7,DC0EE37A9D34567B,19404A3D28B8A0F2,0B1CE29B6375A6D5,4989F4887D3277A9,000000024C07B525,F90274631CCC83A4,AEBBC3B48C46ED79,8C02C364901C02B1,0EA3FFF739ABCBDF,48ACA55813A71C62,791A160A5D4F457B,862129402458149C,0146C4F8AF0DE533,F72D8EBE27DCA178,000000002A011EBB,FB9191F0337FD0D7,B9F089316C0ABEFD,4EABAB267D5DDDB1,1302D1CE0AFA532A,29C636375CEFA2E7,3A20872AFE799023,CCE299E108929F5A,33C9880A78D6CC28,1766177816D08D0C,0000000232633AEC,6ABB765D111280F4,0B3FA0F69FBE5FE6,2CC308C221F6BC60,7B531D96DF381494,696941BC179450CC,6E3062E981011710,239F0EAB20A6D7BB,9CF3E72C3E9D288C,777732CE1EE9ED00,000000018C81AD05,0C6CE6F6ADC742ED,CA9CBDD1A11A4B7B,6F16DBABF46B71FF,5D2ADA1BA07CC48D,F27FAB9317A14FE2,7A611517B1354437,F0987FB423B89B7C,E7E8517B071DED71,F9BD7DE55681399F,00000000E44B326B,B58A4BFF6C53DBCC,D20A86786F271AF5,7E7DA8096082B9BB,C41EA838A43686D4,576A494AA092A6F0,F5BB223A90449212,E33217963719B01B,A462F2E06692EEA4,6C7BCE7457CB47D5,000000020D043AE1,F19295B7002E708E,1C9F07ABCF85E8F6,538ED666BC5B5344,9A87782F5A21E198,F1535C02026E7EEE,2378F9CACDB8624A,023FB1CA0A23C745,6320ED558AF96900,98E01C8B085BFEFE,0000000089BBAB50,82639109694EF37D,85D819A8049521DF,41D7382F6B6039FD,5EE8E300A016829C,E2B0EBD1905973A4,6F29250FE8CA0743,743908F9249C72CC,2C796E42E9C14823,F71DD3553208E166,00000001A179B8CE,5251A2207F56B6EC,E7AAD77257403ACB,A590FE2E023109C3,51D90FC3F7994D7D,C3B4287E71061F84,4E5BB56F86E02412,BD03A79B805BEA3A,B6C1E699384E27B0,82675FEDEDFE37AD,00000000535228FA,A8B0122BCD12DA71,5B96E8122F53015E,D0341687C5841242,4FDB59FA5CC4B088,5B898956A9B6EA4C,95D069CC76067D92,EA62207276E7DD7E,AD64F2C7EF1E99ED,F22EBD3F4175829B,0000000264E33ADF,A034207978A4CB62,16C5934BB4E742B6,1552D5DCE5329C23,2BFE231BB5FC4BFA,9B33EFA49C6FC93D,8131F22FF8F1DA49,31F859AF529FB508,BEC4134A398991EE,B1EEE30DF6B43A6A,00000002390BA54B,3CA9CA5DBA1FF9A9,1010A095753B125C,ABF4B85892DA7284,1E4FDBFBCF5A1330,12F9579375C70980,5B73BD9B50C75C5C,EABF95C6C28ECFB7,11F0684A2E8AC911,D164CD55548C29AA,0000000072232303,30415AFF3D8A8F7C,A28793A9FB3A6582,6C5BB1132814CBB2,F4BF41BC91ABB70A,3EF7C68D4784215D,4166557BD2BF1CB3,F99E3258CE82EFA7,22A97D44058A9C4D,6607A0D24C84D55A,000000010FD42BBE,B8392C4B50FCAFA0,7DEE2A7216988DE4,D8A4C4B5134591D9,695810DC6208E33E,AEB0CD02F6A062FA,E3A3953841019421,9F0D7E1C0F2B7616,526017584D0F8E91,E61009308DDB9264,0000000120BBCEF8,271036FC409F26DA,4B45483E16C2A866,FFF1B6D4064E5FA9,5196EF9D9C6EDE49,5968656E28567CE4,B046EB1AA20ADB79,2203C46D44DEC109,DA113BD05A169F81,FC3DC9EF9C33B338,00000001BBAAD406,348455E317F2F62A,99841E1E570F974E,2039233E5E759DB3,52AF42439FAEF541,0C7095155A03A97E,00CC088FF1C16EAE,C96538FA5714FA7C,247E0FFBE3BDEBA0,A082D3AFCA017888,000000013E022416,3757A1F38FDA8148,C6E39D79A7307B54,5EDDA6B34B2ECBED,E9CD0D3FDDB9C161,9F1315332C9C4D3D,5EC0B116D4C11E0C,854FE07BCE1F54A3,DEEA38EED144A9FD,BAE628C32EEBD6C0,00000001EF0C85A6,63DB32EEF55B6BC7,EC1AA7CBD77F1BCE,E2AB63DFAFF2DB0F,01255C136869D147,909C74B58E93A0C2,784CC514B6E974E2,1B1F044422A73CE3,AEE1A7AA82E578ED,1D739B1EC49CB056,00000000D717C3A9,1945D3CB7820B1B9,C1AA1250807A9C00,110426E382E05551,37C1D53EEA312387,E55138931091C680,EC690D33481A7D13,DBB241DE3AA0014C,0294492664F9497E,FDCE714F890B0987,00000001611FDFCD,26166AF39C54B96B,D4378D7A30D512BE,995EF437046087CA,B3022E8E0D2AD110,FEFA04528F215828,DA0CBEACFA394840,AFBF6E78BF3BA329,63AF26D7AC5D4E03,D7298715BAF87A3E,0000000121D661C0,55F4483F7C607429,0D3A1734919977A1,7737DDA1923C6D30,68EC16AEEC101F5C,78A8B15C5BF0EC4F,EBF11DC80736298A,1C451C1062D96BD3,5A4555341350D4BD,EB7B3143ACBD38C6,00000001A6D6937C,EBCDC091A2FE1BDF,244BDB92550E80F1,3373215FAC683F0F,446F85184B189EEE,6648A93EDC28D57C,B37EEC3A05BA7BCF,E35E59F3082F6ED9,8B1377E5B924BC38,79E90A939A78BDD6,00000001D63039CA,69FC17AD594DB90C,F152D2A7CE9F531A,A48FEA0C5005AE47,8C70D3299C7D7FE7,ED2159A64BF2259B,324FDAC9B868BD51,E0A61355FB9C7C77,CC477DCBCBFE96CF,D382A74FF3879F6C,000000005CEBF7D6,4C63154C6EE8C2C7,0E222D294C1BF099,37F50C48E86A16D3,CDDC8D582A7803FE,D43AC94C48A73170,9D35220292DBA87D,320BBDFB055803C6,29C62338DC802A2A,11C1CA14C0D4CD84,000000000DA86F3E,07164A5F02225DC3,D431345B26FE7922,9C65E70C7BDD5072,D1917DF6283AC0B8,FD06BE81F4267DFD,0C0924553D943333,47B3E41FBC8AAB90,18A6B57B8EF90AFF,C32CACCB78794345,0000000241D1492A,AC587564C0F8EBC4,8C571DD2AE6D1C67,572007C2088CC58A,2185FB9738369D3B,3660FCC6C0146F13,F6E42D0E29478260,E230A2B1CC34A1A2,8851938D5D610A9E,F276E09FD902DB39,00000001DF83A7DD,EBF6D2507DA08937,1742E76C5F81852E,CF0ECD796B0D9FCB,9D687E70F54907D0,599537612883CD6B,1C3E2FF596C0D129,7339C833F1D025BB,C6C77BF766AB18D0,8A5025BE72249E0D,00000002321B6C5A,29F3E05ABB5192BA,AC3214DEB794F2C3,9CDD895EA9AB6A63,69B7AB6DA55A6836,BE88D2F20B92325C,532C020898CEAEA2,2495BCB424B13814,BB3951FD6DDB5DA7,0D48D6CB1C2BE27B,00000001A031B5D6,EC16B8A86DDB49F1,3AE4D1BDB1BB886F,5D530DD998736474,1A3F845BF0A4CD04,6F8DF3F3C6FFCBF1,16E7D6A0B6A7D62F,108BEC71A19CADDB,E7A3C2343BB05FAF,0A755C06965DC539,00000000DA54DAB4,EE9A685E81816BB7,A6FF256F6B267C9D,FB601D1BB3248AC6,79108723BB40B123,CA44400B6F84F3C0,2D76684D838574C0,DB11F30D1083A151,2E0076EADBA97F12,52E36C6422503151,0000000061228400,8E2F37DED71EB74D,F6D22A75D6090E68,D6F171CA0A8BC9C6,C03800C657F1132F,DFA0A46CCE9D18D3,3BE102C976C12C40,71EEDFB72472A3AE,059CC6E3CAD4A55F,D5AC5A39EA58083D,000000005C79C748,E949A1EC5732C470,8472EAFA9A4BCC07,8B2E28F1F0F9220D,51EC25264B18B3BC,047959658F96B085,C1AEEA79B2D154DF,F72D6FC77A6BBEE5,08867814305FF9B2,E0AA4C972ED071E5,000000018AF7FBDC,787370F982C30502,7EAC30202B2D2D95,E4C49E84314380D2,D97CEB7A74D6C949,DAEB4E354D68DF72,92B5E8034F6BFB0C,DA98A728E889EF00,9E023CCA75BD7F0F,AA407096AC9623C0,000000007CDD7BCE,FF2C83E6A622EAEB,D8476AA06E47E5B5,65B3BE16322C99DD,1AA6AF3A7A87D438,E9BDF33AF29CAFAF,3B1FC66A0A479205,F8C7224A6BBC1CC5,5E8EAC926813DAC2,DBC008DC8B95D010,000000004AD55439,3A821689AE3B02C2,6A1C24BF0A3FF05D,AA137D0958250B8B,8F18E6313EEF1FBE,187A601516164373,CD831E04DB1EDB9E,822FC8D62BC3CC73,8323B3A3F2964CB5,EEE09DAE09AFD70C,000000025A8637B1,270E3ECD1E5B6863,4B56539FBDBEB0FF,891ABDAB69A55A63,19A54BC39D200A0F,6E0C6A8AE78AFA5A,594FE0D60FFC5D98,4AB2FB7D44D529B3,F9D445B7A32FF31B,7FB2EC8EF4971C5A,0000000167660A9D,35E7492074F91FF7,10A0E2EEA8CDD97F,20D95A2471A0D3B6,6DAD51A5546E7859,8FAC5C59E80FE03D,4F3E4A58AEC5CEA1,30CAA20B4AED7AD6,3311FFD1990B2FB4,CC9AD13091DC4EAB,00000000868CA09F,458492DAEF78CD47,BA6FB24BD276B27B,027AA0A1215C7E75,CE7B95CF0B921519,0050B5862F036EC0,5C950A0680EE6B60,DBA06656B465D79F,22FFE6BA2F497EF9,FD1D5DB641E3D9D9,0000000195C462A6,4CAE3F74236F7388,E70F98EC98DC2873,8C67C42A9DAB695B,66A49DB0D5D5758F,75DBF123FAFCCB9B,0EBBF67D72B5D7E7,F62D0A8CF2199686,7D1EDA66B6C69AF9,189B77692D07FFE5,00000000495BC6EB,BE1F5CD639A14931,D3E72354789FA0CD,EF95D6A7569E5BDE,D082D71542BE61B4,439B61C7E38E8FD4,2809B6128BDC0271,1BE9AB19E70C846C,53DE82BB2D4733EF,B8A1A1AA36CD6A85,000000003B893477,738F94EFCE69D4AB,F0528FEB0664F961,5635EFDC176D10FC,3A16AF05705BFE32,16BE984ACF67A258,ADDB7BA938BC830E,3E1507928F4C9CF9,702E95DF73FC7404,D6A20B1AF813A45D,000000013F99BCB0,AC74299573290C54,8D585E90DA1DFB43,D8AEC4836CA10302,1F3CEDE77C407B9B,240B0281A73CD5AF,F3834835721900AF,57F912F4F7381B74,A282CB3A0E9DEFA2,A7B96E48652E3B6A,00000000C582FF1F,BF3156F0C5D3938D,7ABAF2910E8C1E97,F535CB8F78BE9235,09142C25DA47C74C,E824613BAB5E131C,59813A4738EB4B85,C1B2A05DF381888F,833102A9AA31C5FF,F80138D9C5EABD26,00000000A657BBB0,42CB34231D0128C0,479A30225D9B6ECB,182CE707A2405418,9C8F29EA47597449,8D7ECDE3C25B690F,755FE32A4BEB0F4E,C3FDCEF3F17F86B4,6D8CCFD383426948,6FD4214DD3E8908F,00000001A8F16C41,9C3DA10F85B02A2D,5109026DC50941D8,4DD2589489A3C341,B37846695A4E94AC,05A2754970A5D16F,ECA9631B7CF480DB,560987C241B88338,BDE61EA935FD7A00,3B0A356D664B55F0,00000000027CA99B,9670346E3E9296C6,F2820842D8403153,633CD97FF3C4F2AD,6E7E7BABE72A99BA,99F73110A26861D7,EE87DE3FD7AA75AA,9D16B10B3836DBC3,C1405FBD03816330,97EDADE95F7BBB0B,00000000B2C1CA97,4421EF3679CA138A,A99E442419AA2462,B47708B5EA5606DF,63FC27553640AF25,275035C93BECE1B0,0F9F691DCCE77E27,207220E41A4C3051,28C113459D7ACD94,44500419D44D5213,000000023D48BB97,66251897A3B244DD,AF9AC36710F04473,E2305ED69576402C,7BD19F5613F40D37,D3664EC75ABC498C,B2B3E6832A599334,294F228FB5125E15,FE5588BA76803C92,A2D47E6CF05776F6,000000025AAC6D54,AC511348A572D6FC,CEB62327517C9FA1,6FBE8410AE9D774A,66029A9B99B0D154,A48A8878CB67BAF0,E4AE540B10064456,0EA637103E8B29BD,B55804841AE272F8,EC5327AF19A29CB4,000000008ED88601,B1B72AEDD573DEA7,69470D9DEEBE72B4,FF7707A6C6084563,AF35F4807376AB99,812B0F718DC2C36F,2C674EE824C199AB,4E8A50BA09BDA56F,EB832FAE28A0088D,582DF346AD3204F1,000000027084CB9E,75B6301A5817C1CF,C7B14446A4F49797,AEEC5C720BF046AF,95822B18647C64D9,8EB7723D8D0FD310,955236D3BEFABB6C,09AAA01F7A2969E7,FD92FE0D3036E819,26C236B10C7F276A,00000002407B9259,6CB46F61E5467CF8,FA3CA00529CCC85F,A1978CC674988E07,767C293A216F37B5,C618EB9C536EEC52,DFDE92204AA2C703,633BFD7658F8CF4B,1B0743DF1A2C5B89,18114F3CE2F5041A,00000000F7FCB9F4,3DBAD3492C091EA2,4488B5F1C5FC3152,6E973856FB4F0945,4BF6F57E8E4D5709,B312264D9148871B,CD838D6375A0E52B,1A66C3514602A2F3,B24F1FA60F596425,6BD10A77AC785EC7,0000000268AB804F,283E8F58C40643EA,448085D94991D27D,B0890AA7A82CE3AD,17B37AC7DB148730,9FAB7D497E8E0B07,2044135E45D82EF0,B361023467022D56,51FDD636186E0E08,D47E000968987AE6,000000002907EB82,90EC594C73F89FBB,EA8456D2ABD41EEA,8099CA1B945B3B7C,E474C49C47E34E65,8A698605D028F71B,40C338CE0482AD04,C4F02379D8B6AB12,B49A755033CE3D86,5D375D8230747410,000000025BE191BD,C86E955F036755A0,07896D17D7FE35A8,061E197C059C5D51,5F89538C88AA9226,6CDF9044A6C68FE2,0EB34F4291D14212,F4E40A4F2ACB224E,08D53030AC462086,B3BAF90E57039974,00000000627840F3,7C9E5A5C1C4B5FC6,F04879228C7E9058,91973BBDC2CC5A39,A1955EC8CA629D1C,6D075C665E18D5AC,6D373CEC535275B6,54F2BF3B6B9AE790,B8A147F04220C609,A39AA46EB8227920,000000016FB83936,F24F3C4DD9B95786,F8FB3B77572B42A8,99EF190C04AD5917,3A91875419C2EC47,B1267570BCDA65F9,A749907D452190EA,5148D188E655BC89,85A37817D272F825,93F3D1CA0929D466,00000001BF1043B0,B69CCCDF69C8EFB4,3B1A6D865074C537,35BC24A2D15C67F8,1C95A21CB171A24F,C152B1487C93C3D4,AA92C8628EDDBBED,2CC42C87A2163B48,D606C4B4F078EAA6,9F3EE7887E3F8A09,000000021D2D8EF7,B6951F0AFF6E9C8A,B6E3E7C396A7134E,2AB7942FF251772B,F5835E96B9872EF9,1AD025DEB341813E,8CEDFB89084EE22B,FE81407D648C38FE,B6B8D0AB90E2B13A,B8949CDFC87C6897,00000000C89734BD,5AE7946FBABA3544,A11322876430879D,B975E8D5CE24F019,8748C493CE2389D2,0A12AC411CA829A6,CD5BD531393C1704,D9F76C6F6FE2E1A8,E61013662639FC46,8544D63010558F44,000000005602E7AE,1C5A7DC292421E25,1FD9CA5638A8A137,EC6CBF2E5AEA1041,A50E3B509D8C99F9,F8EF0A63E62058D3,2320E562968F7DA6,597FAA00B7A9F06D,52703D06D0FB2F2A,278430FDDF9E7818,0000000169942A9D,7172392D1346C593,14BA9DC124A6ACC9,FAB7E7914C7C580B,CF2FE819430D4D8D,B8C786750496BF7E,121113DFC9A9126B,7AD4189F4278213F,1D8B043EF222BCFE,511A5C4BFC93D238,000000027B077424,15F0B99C978201C6,C63AA0A216E3D102,843E050E53ED872D,EE6DD9F3F74BAD6F,E5F0757A8F60E98C,C30BFD2E414E50CA,279EA8586246C44E,B9F1A28E0B54CBAD,B48A54494A06A8FD,00000000E1BBBAFF,A28E7523865C5E3A,657E94281D5518D8,33E7E9C2D4FA542B,B76EE1CA36269F68,BA3D325188D0A07C,8B1FC5D601CB5F94,D34780A33D0CBB73,D30E5A704141C020,13AE0CA2B4CBCF18,000000017FC6A2E5,AD354A8F4D7FCF07,0DA0FBF1AFCE6F33,57E65C83CADB9713,BB435EBD38182AB2,2E5E28F259D0A2BC,1911A2DFB6703FC4,A26D2B2258CC0EF2,889F90DCE9975A80,A03668D086D63C72,000000014A34CAD2,5BE38DAC6EC86AE6,98A0DF1D74F9510F,C3A27682710133F3,EE03F24A974F9585,D54F2F74FD922590,A29326F7F9D36115,6C372C2CE72F0751,D04D4BD21C8F821A,C61363DDE9B3A2AD,00000002758818DD,D1D024764CF6109E,73633005A1FB2007,2645547768762587,D774F2204A4D16D1,AAC82D31DB56A219,A5FC50555C9CC7CE,AA7E5F13FEB28690,845F392BEF3C1E48,4DF9C0711E496533,00000000823D2C91,B105973D52B3BDB1,C3D2DD622689FFC6,2C2F9F01D3DE85CC,84D04F2F53E24E46,C461155B2BA95894,F38268A17D1C66F0,3763D7A5E5419D90,F9BE2DF830D25DF8,564524149C23C8E3,000000016CA4FC50,7AEB1CFFFF7382E6,F9971EAC9F586EEC,F65B798952212CAA,ED905C89EFF1B7CA,4873CAC8F140A757,9E3DA2655E865B61,5BC949A4F3C6D319,F2797097054D7138,A7A66632E58293F7,00000001CA83EFA9,4EFC63F1AC19F2F9,015BAA7EE92CDEA4,FB7E1C082742F142,D359E921A4044E91,854B58E7C326612E,2C01BE6F0BACA9B6,DBB484C13BADE694,BAB204B665B2DAC5,4ADDE78D5B43A566,00000002468C4CF2,475D9E951CFD3430,FB0C6E4B05DF8C73,7FCBC485E09B0857,769EAFBD79488D5A,0E077BE20D19FC6A,C52E335F1F94DDFA,EBF190B6B4D31285,F6FEF00A22904F24,D1057DB2CEA856FC,000000021002E4D9,55A3C0E8B9D1BD98,27E1F91E50AA0E0A,21C3BB9A3A296FF3,62BC56B1127EA5F3,7BC4AA0B6AEC3EBA,F5508D2B221ED76E,8D47E0C700446143,F135D93089FC6FF6,53A1F29DAB0567FB,00000001A6FC64B3,3A16476F3DAF4046,549011D02B5D3AB9,FEA151707DB592F9,64CAAF4D4F51CEB7,EB6E51DE03F5D04C,CA6BE9A69276B941,57146A0D8006090C,A130130D5D1DC30A,A4E8D3EFD4FEE2AA,000000025A8988DD,5F1906FE4BDDB02D,D90675C849BD5A91,2654548EC481CDC2,FA2D57062FB2F91F,49AD6CB8236A68FC,F51AEC61BB313F36,EDE423196D3B8739,95EC805ADA0B8D51,A23F5F5B2F850651,000000000DD7D01E,C29614312151A454,6B0F5A60EDAC0223,C1E5192A76F92DC7,04E7CDD29204E0AA,672A69E04D5254A0,790FD7B39CB9D836,5A15FB6DCEB1763C,B86927457FFFF94C,7158D9EF87CF3084,0000000214E30F27,F0E1761ABDA9FC37,D8A8D3B55B34C2A9,A67C30587FC23962,6C97CB2A5C4A75A2,273EDBB357AFE65A,BED7DC26EEC561DC,36615F228F8DE428,74D063AC70C4F45D,4EF0BEEAFCF6F620,00000001A5E2A092,AB9DECA0DFE8BBB9,4E1669425A1AB9BE,6D680D8EEA752188,FFA18DC6C13DDB59,A8222266A9447227,F6570A2CD1A0DA99,FFF7C77730C642C9,B07AD6D65C99F687,69D8A802E7191BB9,000000023AF09CF0,2CFD94775388FC35,3389D16E9ADF97AE,C2A33CD9DCA67C35,3B045E19AD6D77BB,4539353DA40C77F8,5562748615FB9715,5CD2D2C197F0C80A,AF9BC9DBCF4400A5,41DEC2F8C81F99AE,00000001DABB9143,46E2FF28DF2CFC2C,9F63E6DCA4734573,6B34712C2202FD04,B61D68E7E5D8BA80,C6C563226D8D780D,A5977193E19BC3B2,D236CF938577178F,613AA5607E636FB9,6D8DEFDD107F3218,0000000188473C61,A76AA4CC4DB88B12,30D0DCD12CC09053,368FDFA03D875936,877740F303EE34F4,53198EB858A242CE,90FADCE4D9CD247E,028B4D6C7B07F9F9,7FF9EB6DB14454DF,E0035F08C648F3E8,00000001A0DB43B1,BEE7190ABB2622D5,CD8B61A72EE3D825,C04211B8B5F97A81,68BC56C47DBB4BA2,9B4F1638635DC8A9,B9505FD4F2BADD76,4FADCF5F2958931B,9E5ACC89EFF1B6AA,8A494B8A70D30215,000000022AECF49B,D55CAFECCF173717,840BAF5B6B69A2F8,2B855EA5F8DBABCD,2C5D1461AC46CE0B,53052B8739ABCEB5,E609DA45CCC4EB96,919167625EF3E479,6984260E648478FE,FD562BEF75C27F2B,00000000F2987133,F950D33C4ABF14AA,F128C533084BB53B,BF961AFE72D09EB0,A6A3694EED40A3B9,C8A5C9A0D61C5ACB,309380561971BFB3,691113B10EAE2523,4AC17D602C77B3E9,6CD039AB54A735D4,000000009272BBB6,AE3D3FC7893C9352,8AD49C5CADD06DDB,29DD94174A777CF9,27821F04CB09D8CE,6DB8B2365D8A0356,E27BE3DC47E4511F,16F447278F78C765,EC5D59DAE319774E,497FD153526126E2,0000000109CF9DB9,8FEF2397D3F5A0CB,E6D0D10D70BE90DE,74E9B34E69F84940,04F6A4AA687EAAE8,4ABDD951A6F5FCD0,C50EEF53B3B4249F,112289C8F4CCE50D,518146E1A5166D71,BB9FE3AE5E1C7C93,00000001DFF0A938,1D9058378D8E0540,71093D33A4C0E521,8F5A813EDA7FACB5,85FC691CA5969126,7A2E8FCA192BB768,ADE3FD273218FF5C,5BEA690ED9DEE099,3B053D58FEF41852,51D8E316E2D1B1B5,0000000169E7223D,13D6A7F09FC93A4A,847096199C19E860,BB1A4021BAC71A9D,C7C2B17FEBED444B,46D1804C3D99A0AB,BF65D68E6FB4EC76,4B3FCB769A9C4094,DA35F0A9BED01184,7E84D17B69A7FC82,00000000C0846776,3418DA1076D51E6D,54891C9856037B91,3B4B7EDF701846F7,C3C9F50F3BEA2374,8230EAD9A085430F,F56B79B210B8AAF7,8C608A8E5102F6F8,E0BDC14CAEE44427,2504454D6DC89E17,000000021A71B12D,44536397204353FB,E524B1C93CDEFF74,917FA5DAFC5CAF9A,328926C56D5B6156,0BBBCFDF366FC549,505D8E836AF1CD51,DA5515DC5EED67AF,9435F07665775E5C,636C9F199D012F3C,000000004C08B1AE,08C4CFD3D7E47F85,D04CC5F051014A02,C3538FD61A9DE601,B713F695D861D7FB,372286EC34B8CD89,EE47511D7D24B93F,26AB258CC404A2B7,17A065807121D07A,722518089415031E,0000000147257506,29113C0075327BC7,E9480DF66386BB46,236A95943455A7EF,E16D8F8508C9FD39,F4C490D75BD8AC7F,E9566FDD20406356,8C008201439E2DC0,4E15889914234E59,8CC209EF1587ED57,00000001CF9C6C0A,A7E499E469D60717,BEEC9EC46D837B27,3DC66A4B8151D7CB,08ADE2BB0E56F70D,B2252A65C22B36C7,E5D71DD78B21B361,D7C4F358104A3C54,07D56137BBEFCF57,E78792011F223EFD,000000008C37B5A1,6054600304EB0FCC,6C7D149E05BB3DA1,4BB5A493CD531C92,2959D69308986EA3,1B8C121751BC63BF,AC5B488EB0768A87,C5EE5CDE90CA3753,DDDFEEAA098E6A05,702E1B73CB8160CE,000000005EBF153D,AC305B508176A913,E12E73DA5ABA14F6,4EDCF4D6F62E7C8C,12297DFD8DA7D6CA,5D046071055C04A3,F304DADE82AB0AB6,8C4718F23620357B,04B3D15FC30ECC4A,9DB59A7C2AD687E1,00000000E6E8F897,2F63089D05E2B441,79B9C711AEA8CA03,18CA60630800AF79,78DBF426BC9C84AE,E6E3D210A7355B2D,60A39B3C93C88DAA,CEB63B882A38BF16,021FF097BE86A37C,615D52FC96DF6033,00000001BFE22FE0,EDA8BE69AF59F295,494506CCDD60A65C,605A71BDA98BE8BB,1FB99F72F538F9D0,4804292AF97BB64F,1A35CF91C14E1093,6B2AE607B9E29BE7,5CC28435EAD3BC3F,CC2B4C91C67B6BAF,00000001BC3D2BE4,1DF0AD756C11E8ED,D92E40D03F130C44,CDA850E131C965C8,002C73D73E0E5476,950BB2CF94BE1E00,17FF20AA787037CF,01796F9F27284F4D,0E1694A3DA3867E7,A5FCF2582C5C395E,000000021695305F,DE8FC99603E23F75,CE598BF3387D2B26,5930E04F966433BF,C0CE8CFB6161A98B,30310A327EF7DB48,E90EF53BFF532B4A,2C4351D6063BCE6A,0482556D7A9D3EE1,C524CE7F39E3155B,00000001AF09AE91,EC3F4C9FD67FC41E,1D8BD322CD1DD92F,86B5EA2B57A8F1D1,F5831C28B79F9061,776350F00E32631B,C1F5213228199305,8D08F033A2CA0F8D,1142E55919165F83,35A56397B1D9D9F3,00000001842FC196,563A8101347B6436,ADC9EC22785F41B3,EBA9B76C2B2A43CE,AF11215CF6BD6185,1CCADE8242AD0E79,B1B2918E604947EC,0ED47AC8E7ADF4FD,B4ED69B0D4E26BA7,674608263E9C6EF1,00000002679876EA,83A369FFFCF76C3A,AE3EC3AD0D26CEDE,439261E85407E7E8,72FDBF2C3AD15BCB,4418A9FE1B1F1DE6,DE15B6350AA519AA,A82BC060CA9023AD,2E07189C0952CA05,6872C2BE7A023201,000000003D5F4CC5,F563EE0711487404,438A5ED0A43F9352,79B25EDE72955585,80935F658281970B,9D86812E9E9B5783,8EE2F66BCDAE32C7,281079E977C87790,605B7ABCB88FA932,1BBCFA22879AA38B,000000002616DFAD,25DD3D1863519D6C,87F9200B1BA7F477,9AF585F3A3BB9AC9,0AB845F15F9FDC41,A92B4F334B2960C6,C26CD8ADD34829FC,EC7DFEE16A854BF2,4024CD8472E5AC09,8C332FC7CC944363,0000000047627CD5,E8A154744871D0F7,010D91906C55BDB7,E70C3046AE8E019D,A74820BF00D70BB3,B1466999183659B6,A768739BBFBABE86,4132AAA7BF924A3D,5D9D8C13F1CF2209,167C0D376178588A,0000000140248498,1C7CADA40C16CA2A,83BF4A1E284E16ED,A22CAB0F106390EE,141A21338CBF8C88,80E18604D67CC684,052FD5A3FE2F8EC3,DF844E4654A23113,0B0D29DC4259DCEA,10B3ED68DD723B7F,000000012A10CE50,C5429E85CB798A02,81334ABDFB22AD64,E7671EEF91AE62A7,23681684C65E9ED6,730BF6F34E9011AE,2E7BF95789026952,41F202D469673FD4,6A91F6353C135FCC,3A9E7AB8276840DB,0000000123CA6E18,33A772554D3C416C,D2D14190F2522E8E,739131E07DB4D9F9,4D1FB412EF591D23,68B16A89C38CFBBF,101D572358A49D60,CC0C4B4352E17DAE,7CD3E070E270A5AD,98B92EDB07A987A0,0000000268F9BEB5,79C215EABC7F1D43,F0C5285AF86870AE,EF50993C43AF005B,A2159C7DB9742FA9,808558CDE8725A62,BC256292C16D2DC4,33487F8A56B86DD9,D70EAA278B069528,69285CCE26D9DFB0,0000000138ACA774,C612255B2CC131B9,529906C22ACD41CC,9393104F9B119BA3,F9A14EDFF330BA38,68E75800E91234EA,CE1342F0DE14210E,BC2A3D3995AE5961,C77CC1EEF45FDC1E,31E28F16C2DE54EF,000000019C45B093,C77C6F015E555736,CF8FEE31BA74CD05,5BDD117BC31C37AF,B54845DF47FE341E,91141AB80176F6E3,EDC9CA76D0EB0DF3,D05886F7E2377891,C07F54323B0CC9FC,FEE7239719137A26,0000000221DB4B6F,40917DF9A4D74B93,AD5643961BA4A615,2C4637BD2768BDD4,02C0C5881D0D9942,2EB39D5F2ECE2A73,F9379DB6DE0D55F7,E53CF951BA95CBFF,AFC95CD8E752B9BC,48155A7DFFE81EEF,0000000120CF2F10,9A690CD29AA0326B,556BAD26AABCA886,74E8D9AC84701E9B,926EAC39FBD8F6D7,1821B2A27655C8EB,7F2E9EAB11C5A553,E38F932EA8A14A1B,19CEF9CA9B0C6270,26478C21648C5385,000000024D054F27,C5EC3D418AA8929A,09EC1FC14FDAE248,4AB7178950646397,B99A6035D6DFF938,B712D94587D7C107,4A555F1217144198,8689BAC05737BCDF,614642C57274B070,2F7D4F0DCFB71980,00000001BB1013CF,94BB65AD1DB51755,7C3028717EEFE58F,8B8857A874D5FC32,326831E01E40C5B0,0F39FD09EAF76D75,BAC188E7D3059B2D,93C0DF168DEE9D28,A3FAC48FBA2587F3,AFCF2463A6097666,00000000A8620A02,8A5C1D69DF6256C7,0EB058E56E40035A,CFBD62E5A46A52FE,7B3D28D364498D2F,0B3B92035F91787B,FC8D38B469553B84,8135EFDAD112A4CD,0DA1A7C6D6E6C063,8EEB2EBC300C3912,00000000578F2B1C,55A0E2DA4BF16C30,A8F25ABDAFF619CF,188EF0F1DF098C37,B64621A3CC53C82D,FCBACF8D7ED51D03,C76EB5B518469C8D,E1108E622CB76914,2D1A20B5AF5CE7E1,FB8251F7A7548640,000000022C69997F,DB581A3A2A87EE74,2CCAF4EC6551EEA0,CAA6BF8029E09C81,5238CAC433EF1FCF,4F4A4A4A462A09F0,5161691559AC83AA,99B1AB005ED19AE8,6036DD84D5DC9108,46CA63893AEC9277,000000026653444B,FA90B898386F410D,80B4103712C505FA,4895A592805C9A56,EF0D6AA391028551,83B01ECE97B629CE,CF1469561FF8B27A,BB3ED1A2BE69E6E9,ADA4C55F72B5418C,C229704B55CF3330,00000001DDB43A34,F19DA3FFBD32B246,B0DA142457EE3CC4,A7F59FAFD35C2115,0A14B459FE152B32,323A9D0A15C10196,CE75E21A5AC2F655,8EB294CEA60D9E43,FEB0A3FC6F95D036,A9BC70985AE34783,0000000037FFD12E,CB95E6AF4F306C6E,DFA3C434B639D79C,29F1FB53E85DEE47,AA6986262430C115,D1C12EB79FDAF466,56BC7C217F9927AF,D0979BDF8CF72EE1,9C7067A06E807C39,EE82933635012622,000000026D63591E,3B279E9C48B7DB69,905B5D1215A92805,33252923127C686B,2ED55E92A6AA2866,C07C523D7450C11F,18CDBDD68242630E,3EF22BC254EAF22A,881DBDD43AFB98E3,824762194C30786A,00000000C7ABB85B,268C109FFEFF4AEC,C2163C626F140424,D80B36519B44F2A2,1E182796D97B06F0,FE069954FD8F2990,44EF7B5E3AF66CDD,D94F0268C4355B38,A8668A3AC44C6D18,383042C39AB138A1,000000010237C1D8,418A3C3E721C6653,D485B8AF16F2A7D8,1578D9C6863BAF65,4AAB5BEE8EBCCEDE,D6F0037983B7252D,134DE302D3C70C81,AA615CB5411F838D,53C4C8E9B4D3F810,D1388CF30B799618,000000011734E756,C70C919093107CC6,845B682C90923F91,ED0EBDAF29FF3623,0160D7FCB2F98C63,42F2477C37B4E4F3,068B2A755E865033,36D6B07E976F2F3C,78566416D77635A9,E3BFA9CA39051DF4,00000001D6AE0964,AE3BC337B7700074,E2BAEB979A20BE2E,0DF6B744C9921C96,62177BA97CE0F2DB,9399041A7D167AD8,36B8E3F883442CBB,BA4FC598019BA4A3,B8C1638B5F35404F,DE7B496C8DEEC5B0,000000006C6189DA,270A420BBFF343F0,F7AC357CE2F26E15,3ABE6551C50E0FE3,41C33F8D146250CE,BFD2A149842E865D,4A3A552296C98D33,A0B5EC255E0439D4,B9EAEFAD3AC27E4B,283F88D73C9FC2B2,00000001F5803204,46F0E800BB80FD32,F497F4E56D4938B7,9DBA9AB94DD56037,179DE2825A07A627,16D83B8B94BDAE7C,46C82F6833EE72CB,910ACE8C00F53FD7,ADC2CF93CAF30D44,87832578FD5A2212,00000001EFBF19CA,0BD983A811910073,50651F3DAF78CF43,66CE1DC4FA5A0596,05F9AEDF3A6CFA1F,D3D454C209C45AE3,11D36EA92187CCC1,B147608C221674CA,9FE5DF9D817D3CDE,5E121C6ED88E8F33,00000000B86E673F,77B0AC2F033BA151,D8F13B51A316D431,6C843252A178D43C,4C92F4153F1073FE,3DDD2A6CB5422D2D,637424B7D63C4800,542E69B352B89127,884EA4FA455CAEC7,BC872BF04FC218CC,0000000138BC003C,4CDA897BD257A697,F8327DAFAD437F32,0BD0FC317053277A,53B052193180B3F7,4E1B14101A099BAE,B149CBA7724AB6EC,B7F55B71F49DF0B2,6EB5869CE2CA05C1,D4E334B2D0A11B25,000000026560C426,8BC5F6C1521B86AC,7D209D4196F419E0,CFC52CC91CBAD276,A2FF7836BA0FCF3D,A7CB181E7E961CD2,914F406241C63D24,DD6CA6D41BBA44A7,5C16F540EB213E21,C06ABDAB14429CA2,0000000257028AFC,EEF4436443EA3DBD,A0BE66B18FAB246C,EC415E8BE7FEB54D,C27C7D3C7CBCAE76,4F5D34346539A3AE,58AE67FCAA2C3EA1,4673916BA56F6E2F,1BF1896BA65BF1E7,BF256A848CC86C07,0000000022BD068B,8E61A70C6BF814D0,F1A643E8299280AB,9E445258622FF2F8,3CC12E411F73D9C4,2EC7D16097B8FAE9,6E92634074440E5C,D727E57A1F819F06,42B4A6F742E8C1D7,36050FF9F4F1FCB8,00000000A40F8ECA,756FD40768C6484C,178FD721051C5B9C,FBE10BFDA0970E9A,0DCCDE995C540AA9,98E2C2B407F29C72,D8E3EF6DB8EDD708,1EDDAA9F653D6FBB,8A7FEC8D463050A4,0A8492DD1743179C,00000000F4C42C37,A66355D7FA89DDD0,0640D88686A2DE13,EA7F9BED71063108,579AE69C7DB314A6,B77A6AB4BA185CFA,A5CA3A9D84CCFDF6,1AA45BCECA50731E,C388010C5B517F83,83DC44250402693D,000000006265BF65,1EADFE8DFE777948,3E449AE9005B8107,1F6AB66731373822,E4F421EA32868423,6794A47BAA3B8928,E7303CB93A544C5E,B8116052313B9722,983E65069A572055,46E7F85BE683BB7E,0000000107F85CC1,8254AC1996B93F63,93FF7ECEABA1E4E1,877DA3E884DDAB64,7367485533E4B51E,F02B28DAF317A609,CE78A2B74E2CCF0B,374AF6CDBFB322CC,805FFCE525A67802,495409014AF35BDE,000000015255E9B1,A8BC2F9EB280BBC8,C7784D85534A5649,F8A686E6F9E75A36,F5A69EF455D5858C,892057AB28831AEC,F375B2E0A33A81D8,DEB03FBB03A19A66,C318F4FD7E553F49,1285A241C1BE4CA5,0000000037DE43F5,8C847D46EAC792CF,0A43682C53056339,959C17EBBFB2B864,16B9BC1EECD7B8BB,9F249A1A5102FC5C,9C6FDACAE5C5B8C1,8ED910345CB8A6C8,290CB048F6AE97C3,F9BD66CF104A4AB2,00000000623FCEBA,48124D6C3C1E1458,1AEB00460AAFA7B8,3A0328596BB905AB,DD46A60A15A09E00,2BF3F74E2B69C089,183B7A02446960B6,41204215683FA015,33D00479CEB1CF7D,EC08E9404D42EB10,00000001603448F1,50C189EDA1DB1A45,B538146A01CC60F2,A76D7B09801BAB7A,0890FE1A1CBEAFA7,90522A16BA57AF90,3DA30E8E9D33A875,FE7B0160B1B9F2A8,CDD0C8385CC1BD48,C2999FBAFEB9F339,00000001BA3C0490,2B51081D9F11796D,F3C9750AC9B8F3E9,C9605E29237D85C5,F2F939A2D5B40791,DCC9B2D1887FBF23,4403796E77B6FE23,F5EDB96A3C0E28FA,D6635438671AC999,EAF7B590111118C4,00000002202DE044,D6542AD3F493485F,96CE8CD820DA742E,5E33CACBFF3570EF,A18B345D87DCF65C,4D1BFF427C95E782,A884DEA7BE9B7946,A20F00A7C9CC7B7E,12DE5392333604AD,0388D8B96E98D105,000000026C4CBBBE,A5A38F638B3D7B99,42D21874D678E95F,36CD9213599C8F26,F99BC3CD385EB5E1,C67609626D35E921,B6CFA438A3B7AAC7,DDF073B9488B6565,0426B898AF6A5E66,0F0ED564D82EB300,000000018CF1F49F,6B6C33391E117925,B16DF292044D4E95,CA86DCF7FF8C94F7,4C89E074EE29D01B,FBDCFD75F675A09D,DB63B9595EA692D6,FF230A8DBC5FF60F,CE407EEB99DFD127,A3F0249FFA6184D7,0000000273A8512E,3DE71B114E86BD66,D0409D8A4D6D2F8D,85BD6F86D71D7D2D,D0B4C93B50374F3F,B762BA9375F99958,9BA9DDE0832FB78C,E62F689523953793,EBBE7365997E8933,CB3E7988A91DD06B,000000013394A8D5,1A9D2CB110277BAD,2E6ED53EBF999E1F,C96B68BEA0D5A888,E72182CDD9049658,6D8A86FFE406F763,64DD80457F4DA85E,1C4963BB9BA21610,4ADAE87AF38A7A7D,574367778D5778E0,000000004391711C,55EEB9742238D6C5,B2F648D106DB59A9,95A3200A3C2CDB10,A36F4BD1027294ED,81C4F1BB5ED8E3B1,24EFFB6A14BE58F8,5B1C559EAFC36FDC,E0FAA0585D4F511F,E42D85FCA32D28AE,00000000E0E1C2E4,3CC3090CA1B5912A,A123956BB186E0DD,360FFD43920588DD,D020618A4FDAAF17,ADB011B49D026F03,2CA60CC90010D160,30BC855429C8E70D,49AA2FFAB370D5D1,919D96FE339B93A2,000000022CCCFBC3,A824ECB9216D4941,3988F50726FD5A50,CF96B24D4E34E67E,918B1EDAB2B4EDD8,8D8BBEFAFEB2BB1B,E208935826E8F920,F6CB438D2073F58F,A96680D60C5AABE6,331BB5745E5EB343,0000000179484AD8,9BF8B6BA4D7BFFA7,2BC98AA05B03EF8B,7A3EA9C2719EDAFE,4E3B9823B2EB7830,DADD3413F6294728,CAFCAC73B6F9C839,C6302A9D5E1214F3,4919FC18CA0795E7,E95C3633807F0E34,000000008D7A21DE,7B91E9DEB75217D0,FC3C0BB405C9D7C0,C91DF6A4F342B90F,FEA250197CD2C666,59F33C6ADE34C1F4,8D83D6017B52620B,10DD1CD014744FD7,1A403C6BBB332368,7E687591AC02C175,000000025EF936BF,D3B90F52D2FF5CAF,F38CE57B062BC618,685448899BEBDFF3,E65A53CFD39E05E8,7DCDFB731D06A0B3,DBF934D6D4ED4C7B,3CB5B91F693F753E,9F34179B5294E62D,CB798668B1188811,000000008CD73FA5,C3156A6D96BF0E3B,8AF329C47044360A,73C993F55A56ABD3,E8CCD4B56751D293,0A59697ACC8FCB5F,54E17F89C1942EDC,A73D0EEEB4A2E216,0CF32D3A7B0B9699,9E65CA3530F641CC,00000000DE786848,DF562EF882B87802,7F82520D1B42C5C5,25F2DBAC10F9D6F1,12013F4255180242,BFF13F6EC34EA997,BA41FB7544727F13,A80E96FA875C8A76,AD21C040F432B6F5,2EC13E99E4FB32A5,00000001D8FFDB10,5C27C1204B7E48D4,5015FC6393046638,E389675BBF43B883,18B742A026292704,F208DEE8BD0D68DD,2393BC18653DEAFB,228E65EE800AE9B0,4A0CC03AB44173A9,0853C563E7A0464D,000000002CD65499,63AC065D1787C2CD,8A3BCC717BABCEFF,795DE65654E9909F,CCE0FD5645A7CD56,CAD021722C057FB0,D2176B2DC558321E,83A7BF7808E590B9,69E444B310516787,4B39CE75EEBB828D,0000000065A9B1CA,9D68ED73C97D328F,2B6FD75ABD77C960,7BB0494989F680CB,3E8852528A8990A9,7FCBCE20047055C3,62E6E2C1AD3C93BC,F7D5B232F0C949B7,BDC170B3ACBE3864,141E6ED8012AF651,000000025A14868A,BDC658F45AA4CA9F,8C76294AAF41E730,3EB59AE038323FA2,EFFC1D33D9DF289C,8EF48BEFAD1B73B0,9C17489B98890A20,38B7F7DE4E8F90EE,5F9445658173DCE2,D5DC756FE0E0D8D7,00000000A8C35DE8,6E10A5E0AEED6D3A,B89BA5C00B5DF1C8,6AE02335034DA55A,3D004CDD19F38300,62F686DD053CD605,D81BB5E27DB285DD,D0BB415097B28871,B9E69A337BB028E8,837F46CECF75934D,000000005331A74A,CCEF8346F9E3EC81,FF6107070EEE0CBC,49DF707F5827A837,D72850936437CCB5,29F3D5C47372C7D6,096A4F0D9E8440A3,56EF58C057F88695,1C62946CDB555170,AA4C4527EA36CBEB,000000006FE3166B,007EAFB0E0DC162B,607F355F84EF98C1,86F069346E4D5B79,3E091DF2D2A41C80,3F624584AE1AA74B,485AF14ED7B3607B,9108FEACC451B054,FDEDFC247E3D55F6,C66B8C77B9FBAB24,00000000BA3C3B87,711C7689EEB09EFB,5BF6B9E517833C2F,3215AEF1054BD737,B3D941D285715673,62CD8841E1FAC073,20B462EF264A0BAB,9FF05834FB18A14D,9D44CA4A0C795537,A0804C0CF0F59D4C,00000000AA496CB8,2B8FF4FF89F7193B,59F9643A5EE58D19,FA6F2290A24890F3,11155C5219842F4F,2B9F1DB32F74465B,D01B546022CD9BCA,084A149766EBAF56,049EF5BCAFCD2A45,C745F59FB96A4898,000000017FA1F7E0,23FDBFE7ABE5471E,AA045AE8BCFCDD62,C6FC5FC9F90F7DFA,04A33EE115BA04B5,4E4E5A39F17449E7,4DAB45BE12A37986,0D95CF1116D1FE3B,F378F1CEB875D546,727FC4633945294F,00000001E92AA7F3,10528BDA9972C897,6B6C55660D0A2BE3,2ECB24EE9F6C7EF9,E52C362522DB8E9F,36B8922AB941EED4,B2ED710461583754,48FBCBFD9B707114,BF214D4A18EDBDE4,457D79B64D2634D0,00000000561A9542,83B4B377854C20E2,26E1D0052BD71244,833A89993642AC1A,5A719DBC4478D3EF,22ED31CB9E9DBA7A,84D5953F378C8AFC,5392A1369577A369,014B71F7BDBD5F96,59489C5A869B9183,000000000B396E6E,0818EE25A6742DB0,D990F03149B0B02B,A8952B1D459ACC7E,81254A26AB588890,1F6E4DD61150AD08,56D4215E6FFD930B,677A73DE7198634F,9902914C44937896,97132FDEB744B8EF,000000013801A610,D9FD89297D2CAC44,D49B69762A97E88A,14C8811B0568BEEA,D533D806603AB3D8,05666A2273CAF3A8,DD2EA058A404303D,DB7EE5727F77DEA2,CE2EF00CC8BE0C29,A5AFD22363B08211,000000016A7809FD,172C8CC034570270,6BDF1C5417F0FE04,D3E10AF409A1E40F,CEFFCEA50F4EBF1B,AC0C4931EAC39EDD,589AB5C4D8F39E4D,DE581833571780C1,BA45734DF62D8BEA,9A046624CB85F698,00000001317751BC,26FE43F1D204D89B,0FC8F0770774583E,B276E127FA05B54E,C067B0D6F137AE54,52E2D6F843A76BF5,3969BB82970BA995,0C05CF8A728C53A1,A6128EBB5D092EF8,190FB7D022CBF010,000000017A731199,7AF60D1AF8971554,455E26B4C0D3D9C2,4ECEB517E9DF4EF0,2413031307476BC5,D0F173E5677A1F98,801614B5699AB298,28D4659A6A4D4819,9C9F956F8279D530,985B6ECE3F180714,00000001F7CDEFD7,C17028B0FA91A90C,0F573A6E8C8FCB41,2C1DEB43DE702FF3,EA8E6DC6E380BB6F,137240DA705DD905,3C91ADD4D279B200,4D40CF513D5291EA,39684A0D8DED7DCF,5A3423C53AF5F395,000000003E4BA6A2,ACC488A8D18346C9,576B7FD9A22B18CD,8482F58E4BF6ED48,2A80B5D96FD74813,D4DD23D174535B03,4DEDCE831EA1C477,76A98770DF75EEC4,87A988DBEEA5ADE8,920E4A817B93D5B9,0000000133989E45,8E335DF1BECC1415,C686ADB45A79B99E,B8BFC198AB936EDA,04479860CD49131E,316A255A385CE00C,7B5A9C9060761C90,4DC75DE750511E76,F093C0AD4B88A353,BC4E5F2C64056E32,00000000098B10B7,B69FB952934E5E7C,E2699A695789A3BD,9131121537851C40,4CB14D5BABD12693,3CC9813DC82CB7C2,BDE8BCF2416ED055,FE67EC26B199631A,047FD55BE0A746E2,9351378D6EE7B076,000000018D129A59,BF8228B3814F9F01,0CC946884DADF8BD,90F1E88BE2C0F891,334DDB2BD010E4C3,01E1AD4AC5D3562E,38E1E21BC49E306A,EA32BC401D2B0FB1,E96EC8B1AAFE4914,BDFD0C92AB5CD8B4,000000019616F2EF,E2CBFAA4C50998A6,6EC71EB53A7E306A,46F349F107244EFC,42ED6B4B940F7552,723C0E464C8DCB30,D29AD88902BC7899,4D219CA2C585E704,45942D5194CE21A2,7B6F1074DADAEBDB,000000004EB351E7,470A166CB9592235,BE1A010126496B25,58EFF3221389623B,50A4635B6A1743E4,2881A4106E644611,D5ED51AF46103562,3C42877EC6B6AF4C,9217D2E6CF538842,D922E94E11643328,0000000261FDD744,14E4295DBEFA8B5C,24DD93AF3218ACB0,60DD02BCB0D1A940,32686F5EC89F15E6,F3F0927028582AB5,022BA0D7124AA0DA,96CD00BA66CE5677,8CE4688449FC9935,E3937D957F80A765,0000000278FC0F3F,92AD78AF298EC803,AD9AA706C0043934,B1FFD460450BBAA9,D6C29CBBA2658722,6229A4123F2E7A7F,01BAE830884D549C,8B55C000A77B2DCE,6324C9048AE9CE85,A0255F19AFF3D781,0000000123E32096,18B46F8132A755A3,B46B06F3D9C28361,FC8E7A971C5D1D61,2963B3F86DEE1A4F,848C2684874014C9,CFAE8B90730AE082,0409DAFAAF9FC202,014979D85CED449E,C7C1020B3569AB60,000000017B5BD073,0C6467ACB64EB6F4,5FCFC04EB8D8F0AB,A2C5EE49C858E91E,0CEDEFF280791300,BD2021D2EBF46845,E2FC00919E36B8E5,D0855B0C04B0DEEC,B6A4F9F8C66711DA,C3881920F9B7EA63,00000002259AAB18,6BA2A865D9D4F63E,F5291A92E7D78C31,9714D0453FC3CC4E,2788AFC2AC2372CD,2F996C93B87E61CB,DA631209374951EA,79E4EE9D32B078C5,A5CF7E829B90F932,30644A922427B8F2,000000005B029D90,B2D5A734DAB45EB7,FA8EF321255654C6,866B5303DE720A21,0A752D9008855D2C,1E55358F86D6A275,047CF5A854DF89A1,988EE227F1EDADDB,848CD5E710F1A2BF,91DE3B9EEE890BE9,00000001D6CE0FEE,2DDEE3B5845654C8,C4F4CB216CB3AA33,46DF70D62FEF103A,35070466EA42D0D7,6289BFAFB1C27707,C3CBF6298E163F54,5FDCA295D5F3036D,091CC77C8F4076EC,187C35D8B6AF43B7,000000022E7A1425,8FA9D35D63C453B8,9FB4CD365C6D386C,A51FB2702FE2BB59,D01273434141967F,80D94C95F54227DE,9E822347ABE5AB32,806B97BDC5E83D01,EE24CA67D032C049,C0CA929386B03649,000000014317B408,A8D88DE286C2D705,33F369F093481EAA,20D45FCEA213623B,4BBAA5BD5FB8F9C9,C84DEF499B63F96A,F80CF1E6E9B63182,90836D07200AE488,8481EE010ABC2441,9A12B308B07746AE,000000022E8AE55C,076ADAE38FD2CCA8,D11E64BD60FF476A,08B29D4E48871469,3545ECA2B38CF642,E89B0714F22E23DE,02BE5AA71A724AFE,D4957DE88BD5399C,1B58B1DAA165D1A5,FFD29812F28441FD,000000023800A30E,BF143B91B17C6251,2FE6BE9956DFF297,7099B6EABEEA0588,0D5B15FC350482F8,37CF6DE135B7D274,9EF3415BCBDAFF6D,0BC93C26362D7080,EF5869BB79E48C8D,B343DCB895A1B747,000000009B4864DE,B9D7C019BB7D5645,B3DC06CB575C66CA,7FB5C00172121DF8,D74E3DCE73F1A1B1,761FE4B65F2AEF5E,DBD29C337EF8763E,3F71C54EC444F898,DBEADCB9737409F3,A3147B48E2F9D97E,00000002656824A9,F7EBA8DAAA842697,7360CC957E833407,2D625ACC1531D65E,FBB93263BB9B0011,BEEF792A463EEF0A,7E8748247739B267,D5F2A193F84DD447,1D5F4E50C1E775E9,CB72232F44D45602,00000000C52C1883,DA2ABA9E5090849C,36B3E58B9EB24D24,2F635D5FCC4FB947,F94F2AB8681784CE,14CAD941AE6BCB65,B15B487B845D278F,073991FA072B0A49,C3EE66872EA774A5,9D8752F4404E30A7,0000000108F9EDE6,15C9178C80C3C4C4,1F6F13CAAE3560C9,A8BF0949191F28FD,2475993C266665FD,9DC5891C7F4383F5,61289DF555AA7F9C,028714504C243B33,1E1B40686E5C0DE6,E2EA3DC49369D4FA,0000000084F5AA56,9340367CAEE140A3,A86D80F7475FA011,499C30C6A4AE9016,C4E4C0FEA9BFB2CE,39B3F2DBC70DB7E9,967D9E53DFE06E90,E1B0789550D34B47,F6E6A55A81F7116F,CA45342172E4CE8B,0000000200B9832C,9122376871DE8802,E5EBAA71AF977CD2,D4FE479EC3A10402,DFBF8FC92A186710,E156634B05AFF959,BB880A7AA06547D9,83232A2CE400395B,4FA2F7EB2E621EBB,22B20A6A985263C0,000000016C7FDE4B,DCC1B9701B59AC86,AC8F56FCB4483044,E1923D77375A641B,46EDF30EC651CEF7,B8ADB5D9AD3A5249,2C337706D2DBBFDD,E1499BBF987FF2E0,BA3DBE6DD40679D8,D1C39BB2C672E643,00000000EE5F4DD9,A3EAE6465BCFFB11,696B01F2AC58EA6E,BBC66A8766E7F22F,524FFF18FB28F324,311FEDF05D618C6A,E4716D25E98A0CA5,BDCD0D0EF1BF779B,6EB076B6BBA97FD2,562A704255F391BD,00000000EDC8EF1F,4596F8BFEB651681,4E1683ABC9D52E02,C0C903AEB8D2E40F,471DAED6BFCB005D,866DF2374E422237,4A80C9E789D7D1CC,9602CE239A9968BE,64F0864A452D3980,835D22A74D376969,00000000793A47F6,545D763CC37345F1,6057F1BE66C7A84D,28DAB384443128FA,D9AC8157FF583184,035B8F2A34E352CA,8E07B2C7CAF82083,5EA20D5679F4C87A,109AB6A0A70A6AFF,137585600EA2D87E,00000000812214B7,85FCF568ABF1DC71,26930D43CD40FD3F,100E25D75C3FF986,A5BDD1879560ED94,43DA73FF251BE6F4,C121E0BF77FBCA7A,F702314613A2B58E,ABD8DE024421E543,3E3105D0EA10156D,000000024DF41077,080883F547B74117,E1529ECB3DEE5A9F,5390DB29C6FD9E61,4BBE62C23933C736,0D4C487D7C440801,2A4270F211F544CE,31587700FC41A0F1,EA5F82476A1F67FD,FF9EE6A6121302A5,000000014DC30A15,1B8D6709E6936E32,F053AAEA7E822261,B791642365B977B8,1A0802619CD42084,228977427120664D,13353CD824183E75,94C663653B5F943D,6E24C4B09BF28EE0,DADA1F71CABF683F,000000012A8A7528,1CE9DE640BDDD218,BC5B6ABEC5AB3678,465B63507BC6B65E,768DF0AB398382DE,7BFC20DD5D4E78A7,4169B6ED58DF7608,E4A812B399983BAE,32FE09F2346992FE,C3010C89E8656378,000000020DFE21A3,22F978EB50E231A2,787C0C2611FC5824,191568A715ACCCE8,1DF2F3C26F69DD8C,CD38A6F2084145E0,F4F91454E869A01E,A0B3FAB14E36A33D,45B6019BEF7E8BCA,0A4524E94E5E8C0E,000000008361A0CA,B709295F0CCD3DA7,EF13BDC85DE289B6,7C5117BF16D0D3B0,14A33B58B9CA73A7,53F78890C11ACA1A,35C953E37F508FD3,5A92B3CE1F7CA6B1,D7012FDC66492728,1E5487FA54AFC7EF,000000022EA50C43,1373CD3B0534293D,3E1D635A6D482305,DA7EC92C675E3F79,AFACD631EDA7CE57,CCE3AE319DDF6C0A,A6868DB3CEF543EF,95903B1495818468,90E28EA86610A5BE,985E2B98B21CA282,00000002360D9EF5,387D50C868A5DEA3,A5C4705F76E473F5,5C2CE5AC05DDA731,401475CF61AD77AF,AAB0FA23A8E07FA2,C943B631F6EF0A72,D500CE97C3523A62,C988E98510C40D19,D94B755A405ECB5F,0000000113C6A4AB,56432EA0A1EA11C2,7DB9144FC78FB1E7,6B50EDBA1A903CDC,D91B819C97CC8F3E,5F539F6AC8AAFFB7,95324A30E94EA466,10AF5BDC3F942ABA,AEFCA745C47ECD2C,7DA86900CD212741,00000000CF455157,21C60629FE9C5019,9C8A9C2018613484,505A734BA8978ACB,D7FAE766779089B1,C9279F120688386D,4491CBED4DD2D9A0,2A876DA65F5B5B3B,693E126D6457B421,9D557793E1C07577,00000002387D32C0,B9948952CA7018B7,53266D3B77507CB0,5E91438A51E539FC,8EE51357A9F68C31,DDC2AA2FC19AB3E8,5DEFF672684C1107,F0C37231ACF8AC1C,536FF9FA6E126E4E,23CCED3846D9FAAE,00000000151B2659,017A053A7F925C40,6DF319FBDA0C6F67,50D62429073BD6B0,97632FC0A0DEB56D,0A4B94E585DEEE63,A61E72F1B7FBDF7D,0F2AB6CED169580F,C7664C0E7B711341,E8B5AD32E63F09C0,00000000A978AD31,E32D83BE47D4BDA0,D67B8CBCCACB8F34,DD49B437A9B9098E,332EC4B8065C46BC,6B8F15E922E72E70,F30F000D936ADED8,21519C595406679A,547B959D87ED6F73,A631E523B6C5A413,00000001A2035D3B,F2026FB11DD345AC,AFB305E5485DBC0E,DDB6996F08123D7D,0341A79C4999CB7E,F9A799F1CC8F49F8,AAA743798D68AA30,1F3F87B27831542A,B4848F06A3BE0B4B,172C6D0EFE8BD932,00000000C65AC6F0,90D4399B1300B5EA,AB8949AB529E1A77,59CF9EF7FC7624E4,4821C80C597106BB,1227A1CED0DE710E,F0B7E117966B32BD,DC20BCABE59CFD87,6E1058F59321AC38,2246E8BD32D9113D,000000020A2D16DB,DAD4CBC0E524096C,C3D8D54EB15CF5E3,37EFCBC05267286A,57681189B02C935B,DE4FFFC57CE1718F,2EE8B2190F931BF4,30347556F1FB5793,2ADDD2571FB23898,8D1B1F6FE8D24FD3,000000014C93313E,5E62E243C09608BC,BBDB708271E78E76,2F20B873C6F85F0C,72E4AF09E431CCF8,3260A98DA0D3BD45,BC44B5D33682110C,5C611E59B0F05717,8970B0F9D29AA865,B669753798A8F3B5,000000011310ABF4,2D07735DB2062ECE,F88038196D8D4413,CA35A5002E4DE925,11A7864D2548CE91,1A1F482FDA1EE7C3,E18AC631C87227CD,F3C1B5A241931137,74F6FA1CE92389B9,0429E4AFE0D789E7,000000011137D3B2,D6FACBAC7F75CDA6,8D4CF6631551A9B3,67817FEF8D5E879F,4EEB4E16F2B78DC1,E7456FD7F1DFF9B6,BA49E41C5F1765F2,5280EAF2C5BE04B8,5CC2029CDF79B4E3,412825050201C8EE,00000001936056A1,4F9AD31787325437,D64EC5C700417F45,8D777672F1A43D07,9FF22D203D94AAF0,92A9682ABF181FFF,F4576FA54A6B4639,AFF6AB0EFB66F1B8,86F3D57473595C4A,DBE198A63EE2A654,000000005323CD97,E139390A49E80CDA,F9F48D45612E8AD5,9183D487EA956371,1B77587793811409,E7873AA2FAC3D98D,5B4EFEF267EF6E73,8011192CFE5A61BB,64E315347B7243C4,0F30B5A455EF0927,000000014354B0AC,1CB4389AD2D7BF96,F09A0202AD991C1F,965E258218430344,3B75EBF4C871761F,8A0C124863221248,93C1AFD7DC788DEF,A43C3385D633136F,83EA07811686267B,56695F1E480AD981,00000000A7A32ACB,4CFCD73F21082B0E,002E66AB1F566F47,55FE02C00F1C8185,480BEC9730AEDD73,D2DF8A8DE1EC2EE6,19D3FF04AF22A1C1,8BFDA332B35CDD06,755153E90D3D1E10,1388EB444DCB13A6,00000001E1BC6D98,9F74B79D3037C838,10B9C12400314ED5,DAD930CB975699FA,3425AE3CA1FFCB57,C4A5A8396D3DF8A5,2FCBE72F845940AF,428D04005BB6F624,CBAEE509263090B2,5DC8D4D863537829,00000000475D9D60,E89DD91BB89EE00A,FC382B6C9054C15A,6BEEAA9B7FF7488F,BD2ED60391BD3933,1360B4D78BF746A2,2040B32BF082671B,1C536821ACF14A62,430F66F74C5FE0A9,D2D6C4885F1749C5,000000021DFF0A2D,4773402CDD365BB6,BEFABD5F6E16A12D,77FF51184F7F034D,4AF37CEF6FB4129E,1F63047408AEE589,63AD1156D48D1F23,71D7B31C41C9B4F1,08DFD546F58DEB36,730832AB67834306,00000000EE8C8141,548282B806AA2010,064883EAEF824CBF,5170CAAA696A71DF,6C1633096EE628B5,E7147EA7F835E3CC,99264F828B5185F2,723A334E94E6BC87,876A245F17F011E0,1B2B39E250F83421,0000000099304DA6,2D3E7319F39BA098,4D5EB4C97335FF45,60FAAD7CEA745852,2F09B938E3D1019B,73362B16CD861B66,72BC4CE4FB3A5ED3,AF8DC8A42B8FAD7C,9DC6C109133C4302,B90A8584BF01FD61,0000000186DEB384,1689F65F209D9EBB,36CD7A15C8BA3566,C708520AC8A5E208,4B02EB88C24D929A,51719D0A3F46C86A,4724C0C9053CD1D5,CACD3CA997456ED2,DDF32E57E6420E83,D50000A2D6D3ACA2,000000007283BD8B,815D64799B6D4EFF,E3B115FA5C4862BF,C8F0BB8974D3E72B,8754DB5A1F1DFBD3,EED0819AB80F591B,2FC2290E02B046E8,68DBDEF3894B17AB,7F632802FD404893,A42743A8F10D7665,0000000087435920,79BEEF19A705A1EA,49FD185C639F61E6,7E456EFB282BC44E,57BF8987A45FA7CF,32CB80D10A23E894,12B37C7CCA6DC252,8C6A35B7D476DBA2,2ED580203A2D6C6A,0BEAA0863BB375C7,000000010F2A196C,D2F963AD81E7BCB6,6034AF137A7A4952,B5549EC9F3887CD3,A6957D8A71002D6E,50264DC8F50AF381,5A7C757679A09F7E,C08BD4FE3A40F754,F6BAD5FA68D5BECD,582B628D8EBA6825,00000001C18B8A3D,38DE8041D870436F,743B8344721BDBF3,4E2912A6E9D3DCBA,03D25A2CE940D24E,E2A5F0D2946747CD,5F77DC7628A21071,FE7796A91536B7FB,8B6C3315E7F2317D,1B3CFEAF6343A85F,00000001CA77040C,4C8BF26714A94E72,4A5B340A2E5946DE,AB55C2985C85BB74,C9EA850BE7A24652,D499CC20C4CB3FFF,2ADD592375FA0635,DCC7C69D1B9D8E55,857ED7AC6A774058,4DAC4B0E7BB5BAD1,0000000135CFD105,C86C543E7E47FB35,B3AB273A3362BB30,C86BB6B0CA3A1C9C,2FFF53E38CC6A88D,FCCC0F95538A51A2,45E498C367946ACF,CBD368CA8FEE4558,796717CC975D9408,D099400B1772DC7A,0000000237E079D7,5F666470AAFA8F8D,A737F743972547AB,E221407C2F298F79,F307FF3D393C35F1,316590B7D80330FD,1B53D551E3646D2F,77F0731FF63A7204,59678BA45E9E5347,A0B872D6354FF729,00000000106C67AB,D6514BF1A662BF5C,9B9F5EC01B414CD7,D4715334648AE28A,E5FE735C8188FB8C,BF1D698A793885BE,8638DC3521DCBE8B,9ABC818370A0AE1A,DB3FE14B73A38271,7CF14762C985D9BC,0000000272D501FE,7247B6D9572C4D23,3EA5B86E4B9F25D6,C8322ED2295D3304,746F8ACDDA4747F7,8FA42B0EC0A1B354,CB55345DA2254F45,215A1EE02E2FB467,6251DD4498CBB316,1A8645D250C8365E,0000000255E7A964,7CF05D5FF0FAF7A7,84DF79992C0E4A71,C4125C2F29DF1B7E,42B0B8FE3D989C79,BC1D609804CD48D0,907D4CEBE30728FC,B6DBFAB68ED4F424,79C320746A82D220,048AA2BFABD00DC0,0000000072698A6B,E416354ABD3A0048,EA5AC73C372E5D66,2B7A10BB70A9B78F,1D937EB544C6D948,6A92512C96ED90E0,7C1C6D428A23D404,A994129F6EF1AD96,9A2ED07C26D47CA5,08FB6084B62BE430,0000000232B5E222,71C0C301E382B74E,178E3A9FB50B33BA,CC3CF6164F864C73,7791B9A784732E00,1980294434A268CD,EE8596DF67F0F50F,5FCDE130D803D51F,C5B78D8BD2F7034B,776D6465AB6181D1,000000008EFCD6B1,F87054EB6EC08B10,CB3AE2273C6104EB,ACF85BB7CC3E6A34,CF1E923784A911A2,59C8C33559329F69,F9E1FA3BEA83F16E,6FAEB9735F7D768A,594C1D87F9D32022,C658305E1B2603D6,0000000105A25214,9FA377DA2AADB260,D37AD0D943168058,409A43C33CF15271,0EFE95EE1277C2A1,D7F082D1F55DA352,A544A9D459A28E86,8F7C24CAE0F972DE,26EAFD69C1533B7A,33A6733E490D2550,000000007F65125C,5DC72B8C17901D9B,034103B422F75C24,ACCE8788137B479C,EFBEFFFC7B5F6D78,3ACA677160D988B3,EF53F9319B671EF0,CBB32805131C637E,3F19073BA5BFA0D0,38C0A7FB2DB2D69A,0000000163CE4465,37052C310DC5A1CC,F69966F5AE3BF24A,8F338219097980D8,179032A03BEB5C12,D252DDE1EE4DEBE5,4A05F7746D948C33,2089072F85AFDEDF,A98525CF59871AEC,2069BAED2158C796,00000001BA6AB496,EAA46FD8C6F1949C,EC9730B2B3107489,854028AD6CFA97F0,E311F6AEA2D0125F,DB7C47263EB181A9,30A39BCAE9F4CF60,C3409803ECA4D3A7,1BB34294C26A0FA5,4B8EB735714B644C,00000000B814AFD8,3F7DD412B0564971,63D160FF09DC74FB,B82E56306C7A6914,24F0D2A0113A1C96,D975FC9D82D54952,774CE8EB6A680237,DB42C7FDF13DFD19,BB5558C4174CEEB5,CACA7C9EBD8C3867,000000000CADE95F,353D5AC513114887,141B80DBD6523466,A0AD15BCA9E19382,5556F42FF2528CE2,DAF0C2D52C26C56C,7D2F5F19697A2C6E,BDCD16C8E95AB737,D2FCF4062C1A26B5,DB387E324E240684,00000000075891F8,9E220144F01E8B93,FC5CEB601ADDFEA5,ACEB2EF678F35D81,4E80D16C89D4A4C7,A81E83BECE14D340,608B8BF9A688D5DE,AF0539A8CF761298,E16C30752B49A4D9,8905A04FDEEB0394,000000013D34CB25,2776880D408237F2,54AA300E3FEB0F27,202436C219D7FE1A,1FD569777FBB121F,2C0A9FA89379B427,A87642CC33CD05E7,3F433D702356DA90,619EDD23B846EDB4,28D55D60645ED77C,00000000243831C0,594AEAE36665D935,8C33E711B212BFA3,FE1531DD743A2327,2A735BAC42AF21FD,321575BAD48EC499,BF201D7E80F0674E,B3645EE6AD7EFBE7,497E7396AF27E4A9,96B38896B37094BC,0000000007053E5B,6823268B710AFC89,F2DD7D11C4685056,B8CA8D795F158422,3F0F309C228EEB89,A835BCCB8310404C,D28C03C7209E4D9A,3D77692B12B4131C,E39302EBBD6EBF5E,85058244FB032DCF,0000000270834830,EF1D68A4473C714C,4F677F1BEA81D761,7DB953B21CB04462,B9D56B2308E83B06,D2FEE9EEBC242A7C,50494F1D713FFFCE,695EAF43FE4BF875,7301A22957432D52,5E2DEC56950AA246,00000001EE229701,B58964A85E4634F9,1B7BA82980B4E352,05FC9324DA134EAB,CE01F098B5349C7D,745830A35216F8CF,4FA806A89FB5B0E2,0F89C46477D92DCA,6DCBD4BD3A33687C,1B6F996C0D88A528,000000019CDFDBFF,4A3FD5603DACC5BA,EF69AD0E4FB0385C,25174676F2FB8D3D,3E6387FCBC8C9065,9BB47E0EF40323D3,3732F4DDDBF70A5D,9598CF2722D77B49,3A828E642706161D,164F796BE506809F,0000000146853819,03212116359F649D,D1B9679D2B43D916,290EA44A5336AB5B,89F67453A7DA7F01,CD4E6C155BA78BCD,8457EDCE5A458914,4B478E2902F5BB07,5061B07726ED10B5,7AD266906A50E326,000000025271F8EB,295F3FD004580207,8D95C2B2282D9A8F,0D64E3C6DB206C8F,8EDEB41F0EA082F3,7F7FB0C0B97E339B,6C94BF3F67A34AAF,74EB411C30ECF6C7,E5EA2B39CAE8E293,CB10321A8A6FE2D3,00000000675350FB,92437C1B0D9F03B6,9AD42D4418042B4F,DA703F8C2441CA4F,945E7D9682910D8C,6B67FE1F057BC4E1,C64F9B91714DA0BD,AB7EFC6F6B0A655F,77CA0C6E30203406,4ADFA7ECCE35BD5A,00000002389FBAE9,D30299AC6306A791,8A7A8DA1FD754456,80AE767A44D74C52,1DD208CC9D952B9A,90A2E881374FA256,CEFAB1E113AECCA6,DFA10F9A35DDF8E5,F8519619A3788324,726EC617DE7B9FF6,000000013C5BD78D,26D688AEFC6C3C7A,17700D5B2F8C337B,95B0AAFBB13E76B5,E1AA59878128A189,C99373209873BE0A,CED8CE2A64A00CBE,05D421E59B0EB1DC,A29609A0D2203471,A4CD8ABAE5A78C66,0000000027EBF707,31A9A695E40688B4,08F39EAA85AA0410,28DECC8BFFD05230,0A6080CD1B92DE88,8BCE2C702828371D,F6B3BAB1161B9313,C1A266527D9B9383,8ABF96B3504CBA76,BE8310F034A20EFB,00000000A94FAB52,4B65127A696CA7AC,C452FAEC6FDFCF6B,59FC450E1013DC48,5F725356B2A96AF8,86A2266D2E3D5D07,C8C799F9FFD2F4BC,7BA483B4037CF4FB,9673E57253878CA0,31F47932566D3148,00000001BD733995,2CF58F272227C2EA,069E000F9BC8581E,523BDF5A99837F6C,FC1357E8906A27F7,116FBAB72DA21981,74B79B869F521CF0,9B1C26AF243FC55B,DB638FD53CE66283,10CD8CDE8DC0F4E8,0000000103204DB2,766C1E4A2FA0279E,7290C930FE1BF6A2,DB507B069CEEA7BA,B8290E7B86471542,60D94AF11E4414CC,5ABE4E29068121EF,A57559A6F00D9E32,4A6CE4F4811E150A,DFC1A7B24B30729A,00000000220810EC,6A4C4EE2EAB254A4,55D2F6B4CB4D18A4,440491476B5127C9,076F0FBD408B2371,1F31680A04C7255F,DA39C1900E6BF568,B2EA09EA88B95F8D,99CC62A7A47B38C5,6C7BA9E9A03023A7,00000000F4EC8D8A,24860584B8E8DA54,4E6106DEE32A3674,6301B0EFE7D3C412,81E585F107B3FC19,B08DC98045F8BDAE,A7195DF661EC4281,2BB88F843850DC16,B97C43C3BD072DC4,E8FFF6FF376BB884,000000024BD7D41B,0EF716C79EAD3D2F,659B5D2162F85525,A4AEF2517F419557,F069DD728B868ED5,9D7856716F1ECDBF,F13CA45B5D4D3E6A,8816FEAD9E685504,C6BACEB4B0D19759,B9BF9F897166D7DA,00000000F43B6D6B,69DD45708D0097ED,1F3C739FAF0EE3D7,144757D0CA186F01,4CE0600C61A8D554,21CC447F4BB94A5B,C2D147DEC6FAB783,9D51A4A832F57BF3,2C519310D4FAC358,F2540EDB36F01DE1,000000018D6C89A5,2FBC387675EF7D8C,68815DFC2FE535DC,3BD750E5606CD53A,1CFD359EA8A5580C,0CEA53ABB179BC1F,451CF003B07E7114,DCEC9E58615B735F,DCF6F8AD4F276968,55F692963BDF887F,00000000D79CF706,2C074CC57D5391DC,D1682B1B7A92CD31,F18DBAEE22D49FDF,C242D20C460A9FB5,A17E548103ED688A,B98825A86A14458B,EEC0956F363831B3,C5345E68DE35AB3D,A1C5A60FEADD06B0,00000001325C05DD,867B150B97806F21,5C59618018D093C9,A067F488F88597A6,7D9182BF145F1545,598B8BAF60EB922B,6330CB904EC2DC44,E87D4907A2742CB4,2A6969F092DD0EB5,ECDD660CC2943D82,0000000244E723C8,832BF249E07E3A0B,FF98C2AD1255A25A,FBF87E47E5131F4F,5BFC1C1AE9CA70DB,D457DB2CD79C0CD7,2D41BB357186BE46,6B5B6ED0085B86D2,7D737FAA919F9F6B,A0909D74ACB50650,00000000C8648281,D933583E98D81656,B28B4B53536F9E58,FAD4E2A213FE5B90,A43E6142D56CC263,A4B2941B13908293,E7F599A165398750,038290579AE529D5,CFA4AD5940B18067,26D1B69A337D52E3,000000005EB3B567,687A86A5EF84484C,D63BD15339D9E7F0,FD6CCF65FA03E9E9,C7D766690CAB2577,C648C149532FCFAF,B1AF5650E6CA29D3,FC0730379A781655,AFE6C7362D900310,CE78ABE29D659E7B,00000000CA5F6129,D2C0E3A3D879847F,4646311E1A026783,5EE6871803923A96,8560F688928E8E99,82D4C880845B1C91,81E2B24FB94F9E8A,C594011B734045A2,1B7245E3A15D2FF8,804C59021169107E,000000013C834306,B132834071E734FE,42EE345F70710982,2C0DC5B10DC8F5E4,29A395107D58AEC9,764B4DAB24225E1E,7CA2D5A1DF167C49,0388AA46855A7C1B,27ADF37BE739C31D,CD55816346A56A19,00000002482C7834,999E86B6A1436F1D,2A6590603209E1F8,A3AC028940121D7F,E658ACCB378DD104,67002263098AA77C,AA2C985C31644841,0C65F9370F3D394D,5A082EE62A172639,889E9E7B68640F16,0000000126E780E9,97E578838085D5C4,E899FD3C261AC48B,A1F785441B69205E,DB829321FFB2F2B6,A00D76737FB82AB8,7EEE5120E6362F9D,689C44889A9A1722,DDACD7BA67B267D8,2FBAB6513436FBE7,000000017760E977,768ADA845F1ED709,71228274A4652CFF,CF3E3A8646A9A282,0510CEF69C3B9C48,6FC270A2B40F5DBA,93565765588E2BAB,5B910550E41F63B4,40E548FBFE2A9200,68FF14B9EA3E8FA6,0000000089E35C0D,C6327265E62C5ED1,1EF2088CD1C15784,5472815782C14A98,FD4CD905FC08D6EB,A74E2497B8497CCB,7D72B5EF794A049A,C0D951D1840853E4,D9AEA0A288FA4EA7,D0A5C5B52344BFF8,000000016F6091B8,FC662F615490ED71,8E60FEC750B7B00D,AC8F7C468DB7AEAC,87A7E4943A8E0FD7,1EEA45805D79D64E,DCFAF1A241BFFA5F,0683C34FF6D158F5,4BAD9FC7208839CF,DA1AE4366FB8FF88,000000023CF0EE13,AE2D4C65962D8794,0AA925D777CB58AE,DD1699479292BFDE,84FD709E287EC8B4,DE3FDFE3081937E4,38492AE423FFD063,90EAA193A400511E,DFA2BDA36FE07C93,28D5FCDF64DFEA58,00000001C4EC7234,FFE5489BC3149B27,2943DE28CBCA6FCE,036B7A12B137C834,F353996A0A467DE7,53FB18429E762CBE,8133870637FFC571,3F6C9C187C58C8CA,E2E3B73292990FF1,4A24CE568E0243F9,000000006CC1AF59,0023B2BFDB14DEB7,91F758D723D705A0,6C077BD055FD8ECF,A2098D7017E02084,91A77939C98DCB9B,21B1435C89BC0849,C0E9FEB68A104F6C,0CF86FA339A8F1DC,12859B8FC33CAB3E,00000000369E1385,0A5F38B49C385EE0,D0500F3DD77A41F3,82F74BA6FA30141A,D68A7CCCAE8A0239,3C1F19FD0C09F154,1D8E8C36BFDFAA6E,042B15682297938E,134DF38A58070520,AF5EFA46EC0FBD77,000000000A479C4F,CAA2C1B707CCD116,1FD586755655131E,0CB14512CF8BE12F,C51D6ECAA08A76A1,2582A08EC02DB360,7D44A89680467717,92C08D84BC98A935,1FA41DA3A49D29B6,AF3EC3D83A2E9C19,000000001CD41822,665EE0A0A1204B9D,080C7530EC74B340,917D8251B3523303,048E06DA732BF3E4,514D6B9FDD21DE3C,D213C9FEA18CC7BA,8A4D6F78EFCEF401,23D956C74271FBF8,1F968D3F907807D9,00000001EFCCD766,B3E4C5E86652406B,6AE3D4AB79B049D5,6DB67E1FED1E8645,7A8FF66F4C6691E0,E9D5CD3F7EFA5019,6B5EAD5DCAC92EF0,60BBB1117269CB00,CA455F6760DD58E0,C423381C10F6CB5A,00000000EF41A684,0C2B955FC8550545,2B2C1AF78CD55379,C24D5A4BF8664047,0C102AA4F875CBB3,AA588ACC3D9034F9,0400EE5953377112,E6576D9BC0BB7657,BF52F936984BD838,D2A5114479A287B7,00000000721268B5,9FD3F50ED7BF812E,1C35B752768D8C42,408B0036C5B5E432,71D50B2FEB82D758,33B517601D8D8548,27BF35F77DDA78D8,78B6D4026FA4E948,803E39374F92CD12,40EC34BBA3B8E103,00000000FBB31D60,5A67C2F9650860E5,E2FF234CC18C44DD,9AB68DB634971D39,9AF04BD71A21DC53,8E69130D1AAEA46C,3094C9C04B7F0638,BA248D844FA41D30,2128A71B001F85A1,1C24A2E602C17B79,000000005EE7507B,9F2AD1A0F238BEB8,61DF461E3D57FB81,6856A20D6B543EAB,C819226A53270FF3,E2A29D1691463238,E644BD3E04A87BC5,3B1A442BDCEFFD99,C8B5564ACDFA0CD8,37CC20DCCEB572BE,00000002630AEABE,004DAAC1FCE0A189,28C96B459FFE577F,44AA3CF1D1612864,F3A8B539BDC26DF7,D482BB1708CD3B84,E2E9B46DAE46F6F4,B365C73BE4F4F9C3,6387D17EA281BF98,029BD4FB60C94FDB,00000001A9BEC8A2,462C7BB016C5EB97,5153D0BFB2204C9E,3CF42E90074DF180,BE322C4E3E2C5E3A,4D8C3FA91CB052B1,63FF378C39D5A80E,179112A465872E7F,EFDD30212107D5AA,29017F6B4D94B70C,000000010A993387,25D99C928576EBFE,55A23210CB03ACCE,B237F50408040E70,678219B6512E6DE2,68185F29AD3FE40D,A22A4F8F2249C384,1F07675C7D072F57,DC3D2799E5560300,35D1FADACA2EC37C,000000018359CAD8,FB8840FEA9DC46A6,DCD40FEB10234FF2,12D853776F824028,3909FA7A714D7944,A5D754246A8218DA,92041A4AB84163B1,309B5CB0738913EF,FF977EB04D035EE4,A51D024217C5E814,00000000DD038766,50874248B228B06F,DBDE9965D6BDDCEE,20D58AB8273E4CE8,5EAA170E30B397E1,55B18998B913C098,52B742C8F2723E6B,A32F2FCBA149EB87,E96BEE25D864FB12,AC5924409022DA38,000000016EFABA97,6FA6D505013090DF,99C453F05724AC47,6848E3A4D72E5225,DFB5AC9CC021D997,E36DE9244129281A,C1E44757E721AA13,DF7AD9626DBA8A00,ABBC55470962A35B,1AC2DDD33AE25702,00000001213B502F,A5DFF60368D3CA02,E64F9FF4A4D2CC9B,5940327470FF9188,93DDB784FE180DEE,1381D89F9F47CD69,846FF440CAA2E5DA,95057F23AD4337A3,85D6950B3D9B3A2A,C394051B1B76E50F,0000000195246C53,DAAF325A8630A262,7F3B23034968BA5C,F92D0B51975C56FC,30CF7B470C38260C,5CB623A0B931FD9A,7823E57F0144158C,23C4185FEAD7C6EF,E2C62CCB3562BC15,2FF7F33FF13F3232,00000000E4CFB724,F2D0A2576D7AFA72,6E4046ED2890D4F7,1105304F6139A5BE,C9174E0AE3654A12,21743818551DAE77,15E185DAC49E077A,1B64F4CFBBC75304,44C918BD8CD57D67,768012B19A2286DD,00000001AF51A747,4086F80D4B19B332,4B9158938BE578E1,7D0E7EFC85D266B5,8CEE13198F6FF5F1,1158569058E6C80D,5594D8910899BC51,DFE242445EE2181F,72FEA677ABBB2091,4F28C589418642FD,00000000C1E71059,5E81197B090D9493,2FABBBDE85858B7D,C7D01BEFFCF5871E,E31B80CCFDA9091F,C0523D8F900E6515,A381E79EDB8B9424,A565266D4E205394,A13A60D0A7BC6C14,A3D7CF146A60CB44,0000000086928382,2E059B0C11C362E3,DDD1C13AEC4FB29C,E69F712E5132CED6,79F2732DBF3741F2,DBD513C42CF60333,31DAA9B61C457E78,FAB0F84861B808CB,FDF617766062DE98,6A7B01BB0C4F0EDB,0000000243FBB677,1913C7F4F5BA00E8,ECF267D57316E42A,39B66CC75BF374AB,9763FE9BF0B244DC,6B98CD4EA5ADB4B8,B9E53CAE9FB2C7BF,14DFE4045F4F8CDE,6C773664909FE7F2,FE5F2CED7FEDF01A,000000006A515027,06C74875B7B8A980,AC69083616767D31,76DFF3498413C848,6041917AB850313C,6B5EDFD968B0B656,19513942E253D61D,3CE403A174D8D8C7,D4644E0D97EB85B0,D59FC0A567392D1E,00000000081369E2,FF72CD22BED032DF,DD345491E89F8AB5,35597F8C624D9879,4E158A183150D14E,AFDC4EA513505916,6B02ED05ADC3AB4A,46BDA59FC4EDEE6F,2CE47A06AB7D9805,DCF7EE360806808C,00000000E22F0D1D,F7E1BEB8C1E1B29F,01A1A173F4C18664,BB5E325327FE3D4B,A36DDE85217E1749,16E3DF839DF4F2D3,8A3EDACBEE59EF67,695791A9B561077A,FF7B954880E7CF98,333D8CBCBA247D39,000000010BFEC78E,46A30BF6509163DC,8BECF2EBA4B05E54,0CF7C406A14C138C,A99FCEF62E8DE2F7,1E588851259CC2EF,2CDE9AC11E874EC6,3DD13C4E69FAFAEC,85A8E9CDFF2D9FE4,39717D8DC3A70FA0,000000014C558BCD,7122A7E81C1F7D16,B2F981B01A3E274D,4D5D222C80F0BBB8,4827014A9DF94DDA,5A46D6F02E681164,9D68694D61E41E81,02B4494D40133D50,2F5513DE71B68AAA,D2112B4EF7F5F706,000000016AC75C7B,20B2767F0EDA93AE,A34936C91CA728DD,FB2C560CA4268CBD,534A33AE3359C7CD,3A242F7B1B1F6AAB,C83871C1C32EAA4D,A8987C8B40B3475C,72CC2360E114302A,5C700131E58AC696,00000000199ACE8D,868398297233C66E,043AC36D535F8478,76AB48254053B0E5,1B6C84E6A49EBB67,102FF3097112C696,F5B2AD5AA71A9049,BED2D53414B31C80,B870322A43399C46,BD05CE3AA8F9D474,0000000272A5A2F0,FF373EE441863949,C5F981F6EF23B14A,6F6EF23C9DBFFB5F,CE938AB5E67E494E,8BBE18F4357A97A7,F5BA373552EBE043,1CDDB17FF2F25A01,3E6ABD04474C28AD,E60212965779A122,00000000B9BCAF89,3DAC29C30445B405,EFE8A3C61C70AD88,F8F0605324E7C0D2,5A4C4758F78D1BA7,B2A4CD872855916E,36F67D41D585188A,5B7C5F79DAD3398F,E87142ABE3569E8C,C50CA394611701D7,000000006B386046,FE1F500ECC75EB19,950417495D87B449,3DFF57FB18E6CF9F,ECC15C46BACDF990,0BBA2BECAF8DB66F,15367E104398C3E2,4E9D413B796BBDEA,D7E2A76DD372315D,2DC3CEAEA62182E0,0000000191C595EF,A55588775254C2C4,B3511FCDD7D10FCE,6FBF6A43C31D8554,B4ED3EF9629E174E,B4123F33A17AEC20,1B5A0D7299644E29,3780633D9A44E315,96D666974AA3EA66,1FF2508460ECE3C2,0000000063D934B9,E1D83572232B6213,CED0C64DA5BB640D,6406F172EFD74224,6EA15331FA64E613,2107397398AD995E,7C701B1C5CEE29A5,EAA4E0F2CF23F7AF,8A1795030FE57C8E,7FCCC2CA20647585,00000001DDADD0EA,6E3A7DD6D3A47C72,18DF23260AD5CF5D,3E1F3435D97E04CA,2D200E6EB8A160C2,754C5005B3FAAFCD,DA72BF334C160E4C,42F93BAE1A624182,469658BAF58A9EC4,89DB6947F92963EF,00000000C580B2CF,FBEBB76A5C60DD87,2028EA83D36F9D76,835265943ECD337C,266EF1C2E80B162A,D7C0160A31051698,11E5B348AB57CB0D,FC9E5CBABC50E10F,EBEC321A4BC7F585,8CC0DDB475FA2059,000000016B483871,1B613D70E7F90DF7,311FDB5E3FF94E85,87BB4AE90CBB92A1,A1CBC3935FB2A342,BBAA9385BC1E91EE,EBDA477A3A335A5F,7516B7A319248964,A74D20D289FBCE73,EF0B77EB42C314C7,0000000100FF9245,6E7EEA80C9078588,4D53102A2ADC444B,6E6BD12C090107AB,DFFDE7DC4A0A5844,B0474A1DFC6236B4,4CFF42198D5A3EF9,00ABF1589E8863C8,22FA69EFD60CA1B4,D3C5C46735D52974,00000000E0D2ECF8,813DA74399192D50,ADAE323E691B775F,698795BF0A12FAEB,916822BCD1832E87,60043965A4EC0270,CF1D8A7514D5A1A1,7C45364B0BDCB172,1141BC69244A4B26,80E77FAAC8E4B953,000000002D115C2D,31E515ABB2E43E02,3E5ECEF9826E5B70,D337E9DAB1B3B03A,023B04F173BC4D44,DDA94D7FF337D69E,306AF14959929A76,6707030DA616F721,CC23E1EB43672110,EDE44081B95E3B0D,00000000C71A8D15,B3D067266C233263,A750F38A6586AC3F,2ACD5B49BB4777FB,A750DE400F7335C6,648C799D37BAF4EE,A9B575C8293E574E,C70EC2970A62A1AE,6F9020DE63B478C3,307DBBD9EBAA8D45,000000015D47FF74,95596EF267D760B2,F20F81364D3F1105,2708E6EF21173E77,1FBFAAD4D6419867,F6A53655DD05E8F4,45F7922229F62C0A,D01241B619A7102A,CE9DF5772D75CFB9,87AC7BB1E146406B,000000016CF6D6C9,FD8E36985F76CBDA,679D2620455292DC,1EF27005F5DD8918,EDC6593A008676CC,76F534D2AF6F20C8,57FEC513B5A27258,246A0E509B882931,2B589A666EF84F31,64545506A1FF315C,00000000F3FA4058,EF3AFB99CC9B7124,1D9AA86BEFCC9195,78011EF5637A6E6B,ADD5458846DDED72,241893CF250EA02A,8886B38C0B535092,7639499C14AAD30A,A6D0E6A483B8DB67,4C0B13C89B5ADBB8,000000005845CDE4,FCBF014444FD3250,03FCEEA7850B0345,30327CA7BD39E5C8,7354F4E93C3C4B1E,4AF2435866BA8D4B,1B32BA61DACE3CFC,89E981125B30BA02,BE6EB588C884295A,5FF53AE15F89C4CE,0000000043403341,BDC8956AC417F294,52C341AFAFF1B1CD,89F46AAFD06644BB,20DCA68D7AF846D7,1FE87D8337A9D22A,CE9E784CB5FF78E2,C08994E47B98FD47,44958EA7080CF3B6,C02DFEDE3F4DAFDB,000000021ED14F79,68D097583F1C80C5,9A1E5CDED6F9902B,4363ABCE320E2C43,F045A763BF9DB6DB,57C82A3B553F6644,95021CF4F7665B22,80D88EDC09008E8E,23FE439ED18B7B31,9DEBE7B89D458BB7,000000027892E7EE,1C8B0C4E2B66114D,B9F6D728D171760D,FF11A3C5F00A116D,81AEB2BAD5B1469F,B442A199AB455247,DBA79902E73F682F,E018FDBC063A3553,F9BEA9F6BAB37523,C24611A87AD0395D,0000000100FCBE9F,44F4DA13A1DD2823,9B90E251596937A6,FBB1B5FD80CF1B79,6C05A59DEE02C109,99CA60699A602B8F,39CAEDA56C3BDBC6,ADB08C7417491B6C,D409BB4D2AEAC730,164A01ABA079754D,000000013E31F532,D6596070DE5CC6D4,B846F5F108AA7311,544656558D177B81,F603690C24C9069F,08034718381B5FA8,C771F02571833AAA,3C5AA6C59A2ED87D,943F9FDC487FBA54,9F9E1784FA4C77D8,000000015BDE174F,E944F52278122144,FD73861C991580C7,A2F01C46BEDBF40D,C797E42CBDF48E20,FF2973F68EB4A666,1BA102A35B7D9463,CF7093EDAA38B8B8,B9157658B5015B31,20069DECD07E3367,0000000205C438DA,2CDE57A923882400,D82E88ED90348F60,C5AB4FFD1A1E158B,5B56A52257CC5C02,1F462ABCE301D996,6F0C25DD89D09A71,009A1933562404EC,F5B939169BC7F1F1,481DD2DE6CE5ABAC,00000000CD80CDE3,442F84A688BC1A21,516CA1301873B5FB,8BC05826F621A660,6D7A9AA3551CE47E,837133B3E8A4B788,AFF4F56210B45246,8D40786B8E485B5C,8F2ED05729FFC47C,4A55A15261EA2160,00000000B991BBD5,EBF08C2F62AE7F82,6F85DB81D7FE0483,CDE135BAA9E83655,9D9740C49E7AA887,CD647927A68029A5,74B2DB33CC8F05E2,60FBDFC0E843D532,2BEE35AFD23D04CF,14E6855E4FE80B59,000000015195F3C1,43B36545F01DCFB5,626B4083B2DC784E,95750D740B68486D,DBF9B2094DF2470E,8C5AAD86372DC890,1DF26FEFC9FE4E55,DF40F3FAECE45F2A,1E5691DAE326FA27,6AECA105197EE3CF,00000000DB0CB4AC,0C2DB3DCE573BD1D,BB8739762F2F0F22,193BD25A1A53EE09,83F3D63B1193FE9C,4C75FEE2217B2C60,2ED4E0EC7817A4D7,21C63562B7508AC6,FF33FC32B423F07F,AB1F9C1C238A1BF0,00000002601B0E9C,23831128CC37C8C2,62D6A4FD53AF446E,4848DA3F0F09E451,C0D3063D5E7AB700,9062AB281F76C692,562CCEE3F0DBDAA7,1A6FE5DF6810B280,72F3EAFC83932998,1E3B381161A7EFFC,0000000246FD061A,C2186FC9F56E80BC,94DBFD661BA935E8,91569BEDCC82F65B,BC41B1EE60B6AC58,FDF935E8513A2459,0C25CCDCEF5A4902,DF9127EDDD9909E8,F34C4DD7505B516F,599D04AE88A370AD,00000002398A8083,344F1A3567F81C82,D5A0DED69E989BC2,832C74C54FA630FB,A752E271325DE174,A5F188613141B4F9,301D7491B6F828F1,DD24E8AA7DFE0238,B549A58E8BFB9619,4C62894FA5EE2FC9,0000000217B62C32,D936D02C364CB209,769F84DEBAB2F219,4C47F5E39B5AD867,BCD959F05389E331,F484BAA5F1F5A547,D1398D7E848E8057,AC5FF79DAFCFD043,9CCC4317D481C562,23D0E3FCCB02A7AE,0000000277284676,CAF5064A7C7EF30E,9308605FD31B8CBC,8FEB57444B6BEBB1,234AB57004610EE7,9C079D68DBBA687E,3D407EAA70C929BE,9D91BC2EF8E2F3CE,05C03CD8DC1148C5,EBBA36B8AB215C82,00000000072C9EEB,B4C9F8EEE1FF8793,D24CC6DEB49ED859,100C344D30C86C1B,71FF65082B917150,D8CEFD442F43D211,D459421BB63C6EEA,0502D0CBCDF92D68,5EAD1786E9D1D172,02689A63F446F263,00000001659138C5,220ADF481561E608,523BFAE923B997F9,44A7E9AE911F498C,5B73789CCCE09132,5CF94B8BA8B7561F,995789E170873A8D,47D7611C1C9AA51C,EB41B44D88D927A8,DB970E522228467B,000000027811A822,E965B46374BD70DB,98EEEAAC847C877B,4B031D434F3DBED2,63CAEA664C805AD6,F324F1D0057EA257,E16BBE362E85917D,64C23D3EF7811546,C2ED8B5672504B9C,C824CEF07BF21EAB,000000019E69A1D7,F2FBE8BEA518E030,E31D8330A927B189,071EE7546792D877,C76B5122869A9DB9,BA620A748C8B45C1,7A73A270331F2646,0C92D023BC27EF5C,61DB114293E9F901,C1E581AC6FC5023A,00000000875F3E6B,CBAD8DCFFA56C117,0D119F1110F5EBFA,8D16DC36B8DA2468,E1C0D5E72C6CEEF3,BD206B3DA0547232,6CE8F17DB3F806E6,664331C59DD132A4,20CB3204531A2522,06EF9EA8379A6653,00000001BB43B3AF,1553DC6257AC49DA,018267BA72720B8C,316AC340A8CB511D,35FD74138BD3FD75,E9CB68FCFAF57373,200829228A959CF7,945A5887A75A0D23,0CE269EFA439941D,C248A45DBC8F47F2,00000000EB3BE487,4CD5188F5A1628D4,C42434F6311ED859,5B2E7B02D4C7B69F,51BD842A3D6427F6,1E4C0F4E2B9D1443,CB60EF5C03E38952,2ECB8C27F86078EC,CCCC89AF42E64BE3,A939279632189D1A,000000015B41001A,9FB1CAC55D464243,FDF13E2D07A27451,ECDF37D6A5FFD658,3FFACBBB8FD8B6BA,8AAD43E2ECAF3F37,261033949825C9B3,83387F742E699558,CCA7D12E77B43D96,387DDC5FEF52516B,0000000063A6ACC6,11402F41A161A276,B64604D550589BAA,14DCD47E56F022DA,8B29AA3056317D5C,DFF4810799537640,D10A9935A560EC90,953AFD109E78E32A,38304DF763EA8C46,788216AA2CBEF6AE,00000001DC69CA70,194B6646F268F736,CEA5D8726E21079D,637944831363C669,3681E20220827657,15E4794DC12809C6,4D9BF0789F95EC9A,56698830C8E0E9D5,DB1CFCB8FF69CF2C,CFEF1B82326FD423,00000002710E28FD,745001BECE4B765B,ACBB6FF24A0DBEE6,B57D3EC9DF4455BC,10204F4DFE1B2FBB,1A4FBFF185448A24,3B9572FEFC5617A3,D95E3AF3FFBAB074,B6260BF5D98AE3B8,17DF08C5BEBA2614,00000001D9BC1888,C77A285BADF320D1,3966018DAC94913D,D75D3ADA4D28D3EB,2A1E7BA9445E7B98,124845DA1156C4AA,E0A1D8F617D480FA,460A82F5D3706BE5,C5D27D23FCBAAA8C,5247EE5B7BBAFCA4,0000000043C3D3F9,8D9F3D3247F11989,245EEAC8845EF854,EB421D728A220B76,189B9A5204D72EBE,2D4A77B1A958132D,4C1D3B3C4E366A4D,A1CD3353F53F4FB0,375F4C0DEF433CF7,DA31B954A0B91426,000000008B5BA1DE,6DD7FC988475CB4E,7F13BA6A3B4C10CF,376B84D673C6A50C,182B4C590B5FC771,E8C44CAAE06C5351,9FC6A4413A506F85,954033928585B190,04004DB3BF3CA8C0,E8ACC52C6756E6F5,000000021925CF14,E824229026A00BAF,74B4491D2977E340,FA26CE22BE8EF19B,79908DC4A3E7A532,A20263C91F159D05,F2CFE431F9071246,D87F4906FDD0A797,372EC3A022E6A5C7,EFA0A637FF4BE148,00000001416A00BD,68DB7DBA027751CD,3F786A9D3021A4B9,4EC5F1DC00C0F8C6,61FD5D4529615BEB,81C8F7557371B72C,EA081B0DAB878904,39C2AC4250BF3586,EF0F03A8AFCCFF99,9B949CD8B5507E6D,00000002305191BA,E442917532E5B009,5ED05E484675AD41,016344122E528044,666594B2E4A76451,A6FFB9C578CF29E3,49174F7D9B71EFEF,4B286C637B3ACA18,06F9D9254141E712,3780056798771EFB,000000018E833227,DD9E4CBF40F7EF41,1BB25517F1947C5E,1E62CF7145E926B9,44DF7B31A96794B9,4E80DC6E93ABAA1E,B2C70F18EDCB27F7,6E49573040AC6FEB,E60FDD58B7EACFAB,0196BBDDE518E4DC,000000006CBED0A0,29EA28C02AB518BA,B18D2CF19C159B60,C7E196F4DADD57BF,CEE4CC67B4D7E8D4,5074AAFE7C5687F7,E48037151F214DF4,AA08023E65B8B72A,0FD49B5146876263,192870EC54BE94C0,00000001F01D1233,2E5F87A641ED0D7C,ABEFEA912D5DC4DF,939FD4F16522B159,8F197A6E70008844,BBF511B8C2115505,FEE788D091C3B129,BC4D6DF6E1705507,7A434DAFFBD90247,6532483C62FC3306,000000014FC0C97E,B96231152A3E72E6,7C3B76530A7E3183,C241243E76579229,AC737408E99F354E,EC661A9AE1BCA173,2F37D91E4B3A8188,F6DF11FD26CF8783,88F2C205A9494194,F383B3E52F6EF014,00000000C2F1A366,E176CE469E9F2FFD,27F821F03DEE7853,9CEAD822C787B973,EB932CDD55BB3075,3A8CBEAB8EF5CCEC,93103364E89E1838,FA5703218799D74E,A35C07A00D3FFE4C,9BF1BDB4C25E2D6D,0000000221BAFA50,DE7F7001B6E1177B,6AE6ECF96EC38988,21A5F355C4793B47,64154166E7E63891,06CCB1F8701B2815,5F3E256A0DA4C34C,E07980165DABB1E0,7A81A062731FA0D4,6A2189614E0B5E44,000000007FDF33AE,E875AF9E0B9911CE,2B4A3A613FA3B36F,8004083966351A3B,686E9D19FA193669,199EF3C2D2B1D469,FF0466ADC1F05AE9,5FFC9683E54FC0A3,16BFAD61D9DC1617,9830E2B822904767,000000023A0BF007,ED69C2C543A01228,862A46945D904F93,40EF50B924F8E627,45A030B0F4E8F22A,60892CE4F48D67A8,7AE50FD3AE74BCBE,E153B99DFF9638AC,5CFFD13A6774B611,CA64E78A0D3C8602,0000000141700F03,9C437E89322087B5,B56D213F19393662,CF90FC3A873A365C,A4418083B2CBFB27,E656C9049EE229F7,94AD43B3CE9BF5CD,F9569DBEE9AEF81A,B5752C9D442F8D6F,F4D9562F76040B8A,0000000234206FC1,B5D56958EDD32B12,6C16F3BD7D855393,063EDD08078EB1EA,6AE4E47480449888,3E72426D5E518378,4B5D597A40C2B4CB,706C043AF8D96FEC,11BB4825730C264B,02F135B941899EF5,000000017146C8AA,D6D1A1D018F7F74D,D4A4C385BC2C560F,F33DB730C84524E8,605E004FF5CEC53E,2034155D5B1D5134,355CE4157E7ABC16,AFAF8E332C6C246E,70CDE1C31A209B8F,8FC2BB3BBA475A20,00000000FA02CC49,ADB184776ECCE360,DDBABAA3AB7EFEF3,0B886C5146E35AB7,FFCE28A50002148F,F0A9825AB496BD0B,96028078FD49DDB4,16FF7FBA94C87540,9EAFE3237AA228F7,9EBC47615CC1C49D,00000001DEBB2528,4E552A9984E6094A,4CF5446B21E9AB0F,50D30A73AEDA9029,AB7CFD146314D6BC,C2B958CDF9D6BED6,C0D477A0A8AF4B28,B5249CD527106E45,149995D1B1D779FF,3BAC6759A20DFBE5,000000005E33B595,4FA0F1C067065BB1,5B0318FDBA599FBE,1D5411AF77504C2C,E9B4BA96FDF55018,3A5FD8F6368ABC89,C1658E764187A29E,D08FE2099DC585F6,94935F56A7CE6534,84F35A5343C4A7E0,00000001EDDF002C,76188E970A2FE56B,D6A6C9A2912C40F4,291CE68901124FB0,96FF944EF1C73B5C,2E1AE2F58B8392ED,8CA2EB8EAEE0746E,B765F488BAA8BF62,9C544ADACBDCC835,FB20E2C5F1C50AF2,00000001536D95F5,89504CB5E831046D,B97F404A0659EA91,6D040ED0F3F1C882,18C6D46EAF8A9401,4E28A337C0EB78B8,9B32913557AEC1F7,D87F43977C6462DE,6588C75C9C1B6DA3,6DE56034D5346538,00000000BB3CA7B3,23BEDD34C8FEA789,4DC1EE2C817C7625,A3074196BAE78ED5,F5E9A4DCFA8A7058,172866FE606B28B5,FDD3C96A70C76FC9,38C0BE6FD9FE1E81,6C2084ABF9DED229,501AFEF60259E374,000000024CA4E910,920FBE32065E8D40,CEE6BD86D00168D6,940DAAB6DFABE051,7D6D824CF39C2CBD,8D81356C81D7E7AC,1E05EAAED737C9E0,84A0CB27DAD449E6,AC2FAAA7ABFF7355,6DDA2FE0FE9C4D54,000000002D299C6C,AB82D6298781020B,4BE6C1BD3B64E293,6E9BE90328CE679F,EF500E99295F6C11,056024C47312548B,FB986322F3C6B34F,971C11BD0AAFCD48,5D58EE5AAF98D845,E39B31AD32446A9A,0000000061791980,ACDCA00FC2E38252,BB15AD4FEA231FAD,69AE0D26BEC478A7,CB48D79B53619F5E,1E9C416A8B171119,958F8BC58C05B298,DA6B62799A150EBD,1036C4AF1DA0F243,DC65F4399098DAAB,0000000051C56A2B,EB5183D67B3BF326,F49B027239869D41,57DD2B12EF1376D1,4401C196E7BD99F4,64B0D99B5FBCFEBE,06E15D0A10072EEC,F41EBE54D192A622,CF4D83EF799D1DC4,914A0EAB5BECCFAD,000000023BB86A30,3D9EE5FB6C515FA8,B798995B23E58002,06C383305D5B3547,35F043D56B7DC5A3,E5CB68B9E89AB123,EB03B63ACE72D5BC,29D4B3B6706BB1A8,572B5416A9C65473,B28284E614E9C3EE,000000008DD70E34,EF57C4D28D1ABEB1,BF1547A9DAD7A67E,A4596B8E44E4B44F,0C9E07613CD18D1C,2406EBE8F08C9864,C4DBC559B9464684,E8CD062625C4CC20,D312068D85C39C58,988E169C1B1279BE,00000001E35FEAA7,9B4003D17B3809B1,91E89CA2645864B7,5CF604B533BE4FC4,C773C11199F29A65,A1AAB99BD63EDC76,EA257619D1967E96,9F893B98B7B662AE,3F94D643D2AE1B82,C4E1891FB3059F3C,000000019B64EC54,15A01A98DF34CAE7,ECA38F8CAF62521E,C08995187D1798BB,4C1E3C5A0D08F6EE,E3200228CB9B7F6D,EE85A135B4451912,21907A7AB4305721,F7364FDE9C72D1D1,FA8C8CFF0EA79926,000000021A7FAD06,DFC9372FDA47CAAC,CC7FF71BE59B18CA,A4EDBB06BD7D2E5C,0CF858D9CAB8494D,32AF29A4433511F7,12BB463425077D5E,648A8FBAD7F6CAE6,EAE5A8B602533AAD,31B2267D4C019C17,000000024CF462E1,CB2DAF9BD69F9956,A93CA34909A762E2,74F63A79993F8FAC,30A16A885ED0A518,10DBD64D9F8E9F82,E2E999921E995062,505B042997F00394,417D59A1F8F3740E,537FEB33B69287BB,000000016E1591B3,857D1F27DE9F0EC4,F9CD18596B708959,3FDED786DE34E281,B3B2638DF8C24B2C,FF2178AF38F5EEF8,62DE4CB1B1894B11,7AB8AF6F2C13F8EE,23F522A37778A78D,C82F3E37D4C32F7E,0000000137A2AA2E,781B282B0223B8C9,F9A649E907939901,9FBE810F70A767FE,FAAEFB192DC4870F,7FCDFF7B14A2BFE3,43E78B86D65B940B,8D2864955E432406,6C764159402317AA,10754D108232DB0A,00000001AD067921,F0315FF3A89EAE28,4AE38DC9B1E53BCF,D1910E84FFC15CC5,6B23F22B7BCC102C,AFC7EA7C8C15543B,545BD77D2D853A96,5A5A2484BDB196AE,9C9779DC9B65512F,7B8EA8F0974942C2,00000000318163C2,B8B0907278046F81,BECB9CB2B4CDAD4C,6156B2A94942ABB6,C083989990324CD3,58FF83DEE895775A,5F74CBFE587353D8,A74F4D46B24A02D8,B3CCF85E8F5DD079,641A1C681FACA4EF,0000000197D327E7,9E0A7555AF7BDBB8,FB8C755B3912CE8E,019010324DED045E,286F23EBDB12C529,B2D1BBFF2E9E5A49,0EBA4AAD84F6B70F,20BFE5C6F079C415,EA41C64025CC8658,575CA39770302328,00000001CAAFAC1C,A9C83309D1C34ADB,6AE3735EA32A2130,3469EC2AFA7E4982,A8F2A743091C270C,E68EA6EAA7ECFF18,0CA70CBEDA55307F,680AF27575056061,16223F5AA6D41D44,DFD85084008635DC,000000025F2721FE,6FD7C1D9629FA029,3FA51A99305DB201,8C4956254A7887BD,C683F95DA3F4F47D,53A396904388AFEC,0997DEA864B23061,ACBDAF41E02CF541,11F9EACEB056C41B,EB017932B8DF8F58,000000016F317A56,14C239A19CE1172E,408FF6B7040A6058,048EC989D95C64BA,9FE1171BE9B0ED76,1698BCB332BF5874,2AAC0E0D3FA01C9A,E06AF58C026A2663,9581E5FCF8325CAA,3D70358F9A36F23A,00000001E0BC30F9,E354538BD211DC02,6A80FEDF41EC1AE3,FAA5B38611A65C5D,008F73C4B4E9C502,8D6D8FB10E746830,97F01A4DC276F7D6,66B397BB03D6800B,590338D94DC04A1C,F1B391A4F911A6BC,000000017A9E0338,DFF572C33910063E,E0BFEB6FE7A85EC6,19A9DC629945A813,EB51E7523B3726E8,D4F149EB3C922F7C,628FB683EA8C8958,9670EF857D24A4C9,5471BBF65360FDF7,343C90C0F48984C2,0000000233EA9128,6E8A039D21E0B3B8,05D625BE6E52A69E,489568BBB6056894,A7FB93F96F58E849,060A7931D9611F66,26DA32B6919405E0,7D2ED26ADF4D92CD,81F1EEBD27896912,6D45B054598B26F3,00000001D0B5F82A,11748DC5296BD163,96517782FA90E35F,9C71E125BA19591C,79B08DFFA27A5FD9,7B07728BD65D967D,D73D57F2C2C0ABD8,879B7077414F5DE6,119D9CB1DB220457,F4DB07EB8CD9E563,000000011A9B336E,6C2572B494DADD99,C38EE55A790F9DB0,E533B855C09272FC,80CF5D3BED8B13D4,100DBC39F458CE16,789E54BDA30E1884,4A71FD0CF94329ED,783BA576EC4176D3,F23BCBC7E30A010D,00000001D764BBA5,6DE6FE104BE4582F,01BEFCD22BF29D74,E55A1E00967F12D6,37AEE30C2D05190F,8417D1DE284F00DC,83C0FB3A578D0044,FBFFB0C11EC87A96,728A24EB639F3197,6B223A0D03842234,0000000176F47EDE,5469B1732D0BA298,8CA4C7D5640ECD20,AE57E31EB6448EE5,6789C8473A39F3EE,427A69626643D4E1,12633030BAAB13C5,4CD030C5F4F5F50B,BBF79C60EB311115,08BDE8974BC00D8B,0000000224241E65,BD5B0F0046AE6DF8,E54AA5D0BF95C9B2,8F1E6217D4A182A0,9B9303CC42BC8B8E,5E3554730F04FF74,75FD913A94DCF4E0,FD679C99E57E2C38,9CA3718418EADD6D,54B563256B2B83E9,000000023BEAEBFF,320098EB1BF19045,BDA8AAC734C0E392,DD8AAAD93432AD59,FF1D887738AA4B02,7CCF83B762E7FA9D,451605A66FF42B25,F813C8D42B49A95F,03713F244B1E3FD4,CE6DF595A1A65C18,00000001BCF7AA87,67FC559E500A70F4,993075A44CD405B1,4F3B3B1573838C9F,9629B9F12DC48E47,A707F329D1690EE7,D1E0B09A16036EA8,FB0A053910F944FF,E5AEF72137B317E7,B30AC357FE44BA64,00000000729628BE,C31A981BDBC816DC,3094605B5D045E26,EAE717DE9805E011,28EFA9154DCB955F,9B7394C425BC7D05,F8F9C66DEF48CF05,C2AAC728207102B9,EF5C0D430B7FB329,5ABC2F5A04BA84A6,00000000B75BC8B9,27B83E9D1C9D51AD,89ACD7B076F3A676,33DB2DD25142B314,42E30CF592FA2DFF,8C5FDD6AAF781484,9826E3E53A8A5D0D,6EA9DE5D1B647A65,F781E1FCFFDE80A7,2FCE0FBF53F2896F,0000000174DE5D9D,8297594972F9A028,A8D96A59E91B8643,424F76AB9949AFFC,1811A4FE3F6C299E,B6A14702D60EA272,D5BFB714FAACFDFC,6FDC4B412473AAD8,C27FAE014B464D7D,B36684F044CE78CF,000000013FBA2F73,C8D8E7DD09CFFA1D,3F7C72FFDC4DCCF3,8A5E52B82A4663C8,80C3EE40B8F8C3FC,C4F384D160C1456C,599B56B4C8936677,D27927D26A74316E,8297D84F6A08F43A,3546B0EE3535BC1F,000000006F750A96,D6FDA1E45E0750D3,47094FD382D0DD74,AF8B316831AFC9F3,B0221B7072A421B2,1221A2AC9DA81E94,7A0A544F85165028,62BA0EB50AD4A939,92341880FFD262ED,A9FC08B78D2C22D6,00000000E574BE12,202B334789BFC8ED,EED2419784174782,5E7B511F23A9441B,E0E1801663FC656B,C19CF0DC679A7BF6,D8F508806B18A31B,F5160DA30DBDA2DF,7144A91DF3B51293,5729910F36A1E553,00000002469979B0,58AE51CDC0A294C5,91196235CB03BF3D,096B3D6A76EDEEDE,19F184499331F83F,9C4D687E6778F46A,E6BAB2C7EB473ECA,443256E2E90321A1,792824388CDD60E4,FE459D3A9DD773FD,00000001F7568F26,301B6D5C99974F20,0111A1CFF366715C,89D0D211D070D2C9,C806D3100C8C4CCE,A57CA5E8C1FE3CDB,AC62CF7E0F997004,D37F051B7113523D,631478709E60A906,D3DB854FF058678F,000000019DAE18B4,31E8DCFEEB8835FD,FAC00B99E0B82F58,9984203ADD43EA94,9F3468E92165A598,7146835EA19B6DD1,BB1AC4EE191F4827,2A2422BC299C5A2B,91391771BC74E204,0947184F9DC3A1D1,000000018A870B29,C288C0E4A0864B70,8F5E5681F46A9538,1D9BCEED9BD62415,92ACBA7D87F2855A,75018468402A7901,846EE2BFEDE45198,626DF13CA95A15D8,C4FF4B58CD20F946,356253009302958A,00000000D858E76B,4DF9C7070144B3AF,C1BA69472BD12949,1CC12B7DCF1C0AF7,3551D992D87BBC0D,FB0D922A4027B50A,8C92097833C2874C,6E9A2B3AA7EC35A4,A6CA662F8D5DD71A,57FCB0762B6A81F6,000000020F6EF7EE,3C48437D4AC79BC3,5F54AAA51D6A7EF6,43AF1132EA20F59C,36A0BE3D7DCD65B9,099288A0093AC3EE,79193DF5ABF99D9B,9A1D62C90EAB909F,7DEE65EE189A5E73,CED40DC2AAFCDD74,0000000030C5B354,FB7A3AC294CEC31B,B6D8F5D8A86EA6CB,1CCCDB83E4954413,A34A6A5B8E3667A7,37ADCAB5E250B8C6,676FF06AA268DB27,A0C2114CE8E6D9F6,9FC4822B87A4987E,87DFD12712A7AF95,00000000EDFF2D32,2A0701048B5F68A4,8072FE83E521A20C,3ACDA302AC64A660,DB69BD2B03ACB938,50AEBE3916D8D571,70A5176F6DD64C4E,BA5088921DBC18EC,9D673AD249CD01F8,047D90246869EFD7,000000000B7036A4,4E2DF8E0EE92EF19,D618D8EB360B7218,04B246CE8A79C262,39C8EDE26CC4FA6A,61294F6BF2FE4380,064633951E23B485,19D172C3C3E34D05,0A6DD38F92FDB219,F05B1FBA341D1583,000000011C711EA3,A6D410650299077B,6216CEA48C4B02DF,6AB1EDC0C1B13D57,A82BD9C0B4EF5B76,152CB2A360008A5C,FF39A47A9051F2E8,25DD5ED2D60FA235,B274764634D6B4FC,F8FF27FF02812381,0000000090434D4D,1D1BACF77D6EF876,CFE4A57749C2E2D2,6B972F0D5DF60119,6CEFABD663DB498B,D41E6507171C840B,FA08FF8BFC05765F,730CFC97ED73BFFD,6C8B3168D4CE8CE9,5EF200E9EB1C16D7,00000000CEED4D26,CA83FBFF43D9A671,25C5F78B615DC0CA,5DD9C1F10C12AD3B,F0BF0CB4E5923B2B,0EE5D4074C3AB4CE,F87EAA6B37D990D6,BB639B8E34D5A8BD,3033815B610CBA84,AA29A909A5BF1CD5,000000003BDE0F99,C4FE336001CE3BBC,9B334C7C5BC7EA0B,151F07E8350B9914,167D2E61C3E0D713,90F2116B90A49417,758B80EDB441D053,EB227E8A2ADE1E8A,8FE1ECDD8791D1FD,0FBE7496D8B1CA54,000000026EF58782,218147A36F783C94,6DAB42224F8747B6,0560CC3A897577B5,4AC1E6F8198EB265,BDED859E5967B32F,3828215D31E12FCD,91263FE0AA8E8504,6F8ABFF28FF97378,61B45AC59EB15831,000000012A50E775,5C57E6046B28094A,F5F70FE8A53E2ECE,3FDA6D2FCB722601,2026F5570274A78F,1181569F4C1984C3,723857764440973F,1F024EC28FCF3FA4,AA60B9C80F5CD6FB,B7A6F2B65910D77E,0000000175E6B188,C5252B05C13802BD,E0A0433FA5D80F8F,2F64EC12DBE896E3,63925DE7DD00255C,4057A27A42462D41,4639C306DFBC7B0F,21B9EFB211F2374C,B419EFFC2D62F984,E9401A3BCE0C9FBA,00000000F28B3024,7421E6B8006CBB4B,7ECDAE82CD54EAEF,630B562C9B352212,4DCC143E5F8C595F,88DE28211E6D37DE,8E8B26B8FB8DF428,A17402847F73D907,921D359EC26F5BA2,164D0EB083D5FA38,0000000240AF355D,12AC71F1A9F0343C,C6963E7AC33BCDA3,773B8FFAFB1CAFA4,A72ADEFACBA9CB52,CF151B64B8E17A87,6A1E8CF554A4BEF7,9DD86DFE47B44419,CCD6C689FBFDD8B4,4A16809BB45F188D,000000011A88F995,69DDDA9F8BFA5A11,451ADB53840F4624,B5750242A7292FA5,44199C356A603123,74E69920197F2D87,086D3DA84D4A79AE,1C08B40A24EE3E4B,B2C19822F45ED2AE,204C85BAAD52B1DC,0000000247D4E2E3,2A3989643BC08278,C7E8DE7B8CE8640B,9967DE613771DF9B,F16809E27956A9B3,CB5813649ADFD4C0,FF35B7D9C28802BE,7665F035981D47FB,4F4692835540AB1E,1DB40BBEF7F0E41D,00000001B5EE27A7,8795EA865F348911,EAB4E029B53A5C4E,985742420DBE144F,959F9A8EB3D5DB31,8716D7CC6C051641,D2DE01BA188B1F37,94EA2A8250EDD5A2,DE376752D8C3487B,1C817961FFADC597,00000001D508B858,98407EDB6854D0CB,057D261823685BEE,2E6335EFAF1483DF,63D79ABD60FF932B,4FFB35A495A944E0,0E66F3642957A73F,E317A02F0244A327,C5534193FDFCA0E4,986DBE254A450B21,000000020612BBF5,4836B8891FBEF640,4FD0AD95F5842F40,831A934E93FA17CE,670059AC69D8BEB0,A37498D30ABB5285,5583C574F9F6B70A,9D66A4CB27FA5349,408180DAAABFCCEC,21A0B9525E40B08A,0000000045EC3A3D,8B85E1AC8E0338EF,64DF519DED575D44,3E287D498522BFF4,0CE6CBC6A3975EDD,08E486D6CC6DA216,BCB5D8D9D77B4193,5DC9C74E69DB119D,71716840727972E2,A20F0ADEC6479EDB,00000000CFAF0714,745BE2E54AFBAB82,53ECE6A5E99763D0,2CDEA7FA0E0B519D,82E4C36E94402538,9617F237439D02A9,95B435E7F63F4B4C,66B573F88FDFCE8B,9381087DBA20C0CC,45FCF291433BA8C6,00000001438E3008,F66E9CC90104DC75,356ACD2730C1B10E,D64AAA5BDFE3DDF9,77B8BF172DC3B8F9,F40FE89FF571D75D,7BE8459E2ABBD7F3,986637C5D6CF2EA6,B4209411C22F9F74,C947B3FBE205D164,000000023A59B373,EA5346293B7B194D,9BC400627AB70956,4620CE231A5B8648,70782AF0D9B9959C,8057E5763F3B55DA,2D7190EDF283C804,8DC5A9E53AFCDC0B,02B4B722EBEDCA2C,C6BA4CAC55359EA5,00000002370C517C,D52C588D50B28025,B132D22A0BB0DDC9,3DF5549F3C90DD41,7458BD8F654F1C07,5745C41EC43B74CF,EFD3C18DFBBF3CBA,4C958C2FD1FD32A0,CBD08ACAE9919CE5,3F24BEACCEE51103,000000009BA51569,D5666B28351C5329,3896C7CD08D6B4C0,24538E6AD7CC1098,D7550221F2910F69,C857DFA7D61ECB27,E5FFDE29B9A50A42,37618AA36C278FC9,2FF577F71BE05B8C,F5353E5CAA0E4D33,0000000051B7C470,791C0024945E2B7A,6F674C53EC61259B,988CF5832E6F2346,3CD82E81662B5B03,557F8CB1B47AC1EA,E266DDF72AC0F8D0,B18471D41A53FDB2,A13E3B18626DB20C,8E26E8115AF52765,00000002421E71E8,9268E604AEA9485B,25A9368A1F8916BC,AB981FE38E0577C1,51F715D6C5FF090E,305DCAEE3EB174C2,57628DF73C056AD8,C27D1312FC1E3438,55D7E11E1ECDB988,23FB720E50E66622,00000001D89D369C,41E4EB3F43293E61,B4271ED75ED52918,042DB6A8FE525D56,ABE9B9EB290F09A0,8DE8A49138E3C919,7300035A5BB7ED63,279BB94BFFA1682C,9F644B8B9440C38F,9CDF007832260B25,0000000079A9BCB2,119C2041AC909E62,4BF060C3938E889F,514CB1DA55B75032,C27DC3F424BBEADE,6B1B5934FF89E8BA,2D41BCC9D9D3189F,326E40E7AE75F3D5,A3233B97BEF40E2E,90CD2757C61B8DFA,00000001D6E32BBE,266ECAD084C8EC12,FCCE737C3293F67A,FF9224C9021155B9,11A7651ED002AEE9,729287E3EA70FFEE,C37B20E304CCF80F,70E99ED1EAE6FA5E,F1363438AF993F60,430B70F2380D99B0,0000000085E30197,F73E643696437E42,9A1B82D137F4AB5D,51968EC667FA5C04,49D6266D25FF9327,F89524D7C63EF03C,593F3DF557CFBAE9,F43E3A2F0F2B5A67,66B91D7D839DB1D5,6C433CA9896F8BC9,0000000111E8E6D6,1D44BE5872165B34,C9194E7CD84893F7,4F9EF034D937A84C,AE1558C89986ACFB,5BF9EAF6DE88C10D,C38FE710F3CA0805,EC198A67B32EA10E,4B0E791A6058835D,1714F7C0BAFCFC82,0000000097A2C2A4,FF7AF71C6586EFB6,D5D22013A9289D54,22F0909A5384358F,A6FF0FC370A3C097,88DA095CAEE5396F,AD95A39B8BE08A93,C178DCD29671A96C,C71CC5EF0418BAEE,22885A3F1875F52D,000000013FAF06B9,43251586C5F689CE,7A28E0098D46BF77,03E02BEECB2077B8,E77C00982E7368FB,4B24377C4D72BFDB,4887D5BB49B5B950,5E184E454161923F,4FCFB8B0B6AFDC77,1CE5CBFE1BDAFD12,0000000009EB2AE8,56249D119CF6B3C3,9861FF7FC870C6D1,A1E26B29710E29FF,37875569CD465AF0,3CA0DE9ED4E2B633,3287B0D05AC2E7A0,A953BC8F64A9E2B8,367AEC3E25EABE07,AEAC72B52AAED0AD,000000025A302ED5,2AECE8F919A1317B,C0753EC598D5DD9F,F3D64849C70C2756,5AA6181172A63EF9,B41D418377A1B63E,A009007CA89F5C06,E22BCC300E4EE732,A00BB35F94AAD948,28196A8571539FD2,00000000B9E0F88C,FF4482CD322E4822,1212E5A50B99CE81,E4C0DACAA3941C15,07F27B7AF7CD4A7B,5841831CC5A062D5,8AE2C3E899EDAE0A,89A493137A5FD632,5C5C3AF74044D070,62DCB52612267D22,000000001D595BD1,A587D9F99230CBD2,2229699F1560EAA6,B2F8D519380E19F4,02EB4A7383CCEF39,AB6456626CACAB80,9EEFFA90FED800CB,F1DD64BC86EA6E6D,19C49EF63DD03A19,FE002D972C91D5F8,000000023CF59964,4A6229E6252B7F62,0B596CCD696BF462,824DACA5C3455AD4,88EBFBA1E9FC48EC,DECE0FA4F24B1EE9,C2AA6130FAEAA310,791853FC8B0D64C6,9D076939F8846016,4804F51CB6E0D9D3,00000000BF237C32,A34DF522AF1F31DA,3503AE8E79040FCD,6D3B7BD6A9DF59B3,705DC18CF2A0812A,87C49BE9933169FF,20184419A7F8DFBD,C8D0FCB55920880A,F261DDF9CC89CFF8,7F660CC16177D288,0000000234BDCF1C,664C872243F1792E,F2A606360F560095,EFFF6D79B203C922,574F8799D7AF7F79,5CC9B517EA3FC415,1D5E0DC796B0AA2F,2BD5F918979E31F7,C6EA05445678458A,9C524D1BB437C66F,0000000061AD7CF6,E7C7EB3815539D8E,DF508AAC563F5362,207B69F6D11F80CF,D0C241D3AD93E32D,F8B1CDC326F08290,CB397ABAC1D0A028,75F41D14B6995C3E,C0A79DB287FCA16C,066236EFA486366F,0000000211BBFC95,2FDE86D0957EA341,E89E0F950A61E48C,5AD034CBB60B27A2,B8639078B5BFCAC3,268C0CC5B644261C,680EC37BF282E922,5DEDB8D4A3D57C8A,57B4607F110EFBB7,E4A9FDE001BE7C16,00000002250FFF2C,07AA9C526C7AC005,5D12A64C7E184C57,B9C122C9FF26B316,364BFA563817FA72,A6789E6746ABBF5C,A387D17207562778,CAA7A0EE52992F11,AA6A949C5E172D77,E39BB30C6E5FF779,000000001429AE5E,08CCA8D7EB5B85C3,245948045A2ED3D0,83F2C95F96BBCA7A,56631CAFB9FA15BE,5A5450225CE4A19F,670938ECA7A27D92,A3FE0CC39C041375,E0A30971C511A60D,88BAE15BF83EBBED,00000000573BFCC3,3E606A206C5E771C,DF43A11DEAAE4D96,23A2F1F828C081A0,CD9C414E39F0C445,4717339DB2146238,6F3298E5D6B6FC46,852086DAD113908A,3E75CFC7EEA2B43B,7156250362538E62,000000010B33C925,D105EBA4C0CF4851,E30FC85E2076F3B3,428C9FB16E61121E,0B4781B32D958B70,829C20377FBDFE7F,73F533CD5D098F4E,8CE11A9C9438D765,034DDE99EE14CB8A,8FBA553B78B8FB63,00000000BCD130F0,83927C279C76A975,FB3BFE472F863217,280DF2CE2E523AE8,8DF6E9A5225ADD89,680937A628EBA759,0CBDD0E7ADFD447A,EC173A3C2A18F445,08655297E8555CCC,3F9BA40E2A869708,00000000EA4CDD9D,32AFF6AB34A264A7,24E64A6C6E1DD456,293E95A1379A5615,E9BE736660AFFB48,B1D0212DFE4CE20C,C1205296D0E93277,6466CB1CDDA7624F,07FBAA9FBDDB33B9,7299CD7ED5555F5E,000000016B76AC52,13FF2110EC65A70B,85F684B56CDAAA95,E8B85DC5A264BF62,DE52D547EE14DB54,8C2554694FA8B351,C9A11867BF724EE6,E58133F42487E782,1F8B0476DE398D2A,278BDDD5F05111E4,000000012B0D3DBF,A64CE8CA1506B898,FB955AEB6757BEB2,9C271022CE8860B1,35E08AE36C5F8C72,4F59DD0454D6B2B4,E32833C9AF1AD9C7,5532F8D6B9707713,C7F4DAC8862F3B05,A09D5D33759B181A,00000001E7F2112B,039FF49FBE109E2F,EAE4591962272C5E,7821E98D7C02540C,C84EEF2B410C325C,8524A7B8463ED792,0E5F9067D993A910,1742EBDC72C1BF43,69079CBC2D1187A4,8060BE1387914F7C,00000002202AB04E,178ED5B8C712C7B8,D51E12DD2314E820,78FEC1F8E809AFC4,E18A12B92074D731,4D361A835DDCEC70,D3F45B32C343CE5D,D3CD4C71F5C12AC1,92C904655CEA2B1F,6BF64C09658D10B4,000000027A99B4AB,FDCCBA4FD28A26E2,EA2471BA83BAAE96,A9316D8F5F2C8276,E188A8F3A3FC2A1A,6C742F2B34BF2847,8B1EB22BB41D2D94,7CD4703FF5549B9E,1B199205FE159096,D30A2D7E9778D66F,00000001D5537AA7,1C3A0173EA32DF7E,F99E61C97FCE825E,3D5F40854720D022,683535BF7EDC529B,CC5EC2F5E910E942,33612E2C99D2A84D,5EF7611639A6ED40,252246568C8DF4A3,4429CACB825A3086,00000000AFF093A1,C6CF36128C79C748,429B6AF068A2CF1D,FFF381A3BB8577D8,7589BE1EEA442E99,5E75EF2428218602,9F28C64984A756F8,A4482923E606F872,0B9F130309EEC3FE,DABA9F9BF101A07A,00000000FEB3E44D,A0D1BDE3ACE1D78E,FC01F585E539C7C1,5D5E991C426B553F,DB062B1747E047B8,9CCFF6CC1499947C,D7A249071DFB0AF2,F83B3D4AA5C991C0,76B1B3110354D62B,3D087CF8286FD69B,00000000E15E9424,A3AB7114A31766CF,250B3093220A190F,54CFE35ECD40113E,6F2B24E40E416D7D,A32FD3DB641D2EA0,4EFB76D380EFA6C5,DD0C335266246DCC,2A4A79FA96674618,D62E8C5851E5C43E,0000000125438C53,4B4F46DD9F1E6FD4,2929D2ABDD42B8C1,DBF3B851CD7B362B,F15177B822E64D8F,2645814FDB2EF785,CF7B1CB534B58105,08731A376CC6CB84,045D8D248572C043,CE2841E83AAF3D93,00000000E296CE6E,9DE7A1307DD7D792,E498570B8230B5A4,55C2623A30DF5B99,727BF75586ED994B,A3A993AFB291941F,562F2CD8BB13B1E2,6A843D46B29CBE26,25EAEA84953B53A6,16DCB295691C5E83,0000000060A4C84A,AEF84AB02B4425C5,817460C91A807379,10372F60A8719F9B,2204E7EA299F07CF,1049160FEDF1C12F,B807E91A7D3363E2,65458F7A69EECD2D,65A6016AFEF20014,9C34FD3FE60D9518,000000007D6653B9,814376136C0837C8,74B7059DACC571FB,5A1922CD88B1F7E4,6F110F0E14C81893,B07F2DCFF64D79C3,EA1D7480409EA60B,386FDFB3F0264663,C529CC1180E174FF,C55A81FEBC9916DF,00000000FEC5BD49,D7F7DE5DCB0EE710,D6B4A4FBF0C9530B,B652AAA8D57897BB,56390D282AC7D621,3A794A569E859F27,E1EFFFBF2CC6A097,E41288280076D97C,E5F50B1619BC3B4A,ECE4F386CD423D84,00000001AD0B6F13,73E566007C659926,B21CA60BC081F23A,4422B3B01AF3882E,90C44FBD73EB6133,A3452F307B6645F9,DD68B1F8B2CE4571,C58A49062CD87E95,0BD5FBCF05D7D0BE,DAB0079D1213AAE0,00000001A3FA0BE6,4FF87F89A923E46C,B7E4D9A84A418E5B,550A6173CE8AEB93,1B1A519EE8BDEB93,8EBBD816B23FE058,43C5CD725E5C333E,8A9EB9E271695386,1CAF445BFC26DF73,1FEF4194A363448A,000000019468AC99,08B48B592DA35D86,D71EDEE07144A97C,81C5849613DDBEE5,60D9E0CB3166B468,71A4251729198B60,36C528220831B43A,4D4B7C731B645E09,02280B1B32EDEBF0,E7033529CA29AFCE,00000001B6ED41C4,A6719A8408352647,149436BB27476490,EB8B144CFFE35AB3,21C820FA277F01BB,51F6FA001C75C043,1242F013380042B9,60DD912B0F788D6E,4AC16DADD6270BF3,EB2927B7EF6794BC,000000015740E1E0,BA4904AE796A896C,61A6A1AB93EAD6AE,B718FF1E615990AF,9FEFDCF466D77BCE,FB7E93496649F0F4,54E9B42B1977326A,0B300A123866DAB2,FC1B86CDC86AF8CF,9251D916AD952A79,0000000030C58AA9,B4264B873EF8138C,74F34255739AF6D3,83D5A6A495A89CD8,8BB043569160F1F8,49B1E818EA26FCE4,1EC029DAC8E93DA4,C4DA3605D98E5355,E5668BA509398E56,2499CF040CC97EF1,00000001DC3A0323,6990FF58CABD646F,B0F77AD8AFD40B1A,EBBCEFC363022F40,82362FD7CE13154E,B19B2D980EF91F40,53614B2B8024AD56,EC4E0135AFC1FFB1,E3264FB0402A4388,6E9B1B26063BCA8C,000000000659B45B,21CCFA438DA4CC6D,77B28CC6BA631859,FE3A6DBC69D25E05,04F8A692ED2BE744,45CCBB6A818E8C46,60DFC4483A0AC756,F434AC8884AB12C1,581D8FFC83D3DA55,BDC5113FA1672AB3,0000000260DEFEE5,715559DE2E08173B,5E099A0863D339EA,2FA991E4E089C331,26D47450D901BFCB,8DA8DB440C4D60D0,9E0C10C86B8E9B7C,33203BC5AFB52BF8,F2D971A9B3429946,61D767F7F3E02645,00000000A9C3F321,F306C3A9C5870042,9DA737CC178F3A42,A6B60EF856B59EB8,0B6A15B44B70B011,4E88A57B6DB99A68,2CF8773D4137709C,9767CD7F84694923,460632043592937B,4A08A2550F378A7F,000000015CCFD078,56171BD7A25396CE,EF00BF38A69D6174,A3C2C9A6600250E5,E6390F75B6277160,7634BC3FAF8D552B,9F14A67FAE4DB61E,85FE0755AF4C04B3,9D633A12C07512E5,7E0CB746EF6F12E4,0000000104B2CBF3,F0CBF54ABFC805DC,E8B1F9045CFC8DBA,D8ED19DDCF414222,F17FDF67E15C6192,C2ADDE8B760C1088,37A7F2343080F1D3,63E7D28D2C6E6E45,297401A92A7ABF8F,DD6D417BCF8487B8,000000006C3FB22A,3023C2054D3D181A,1CBB195A277B6325,5703B848D4FE18D7,5724E4BB580591E3,DDEA9851CFCCAC94,BD24A7AD9331F717,9A834713BBDAD4E7,9E7002EB4FD053EC,9B5FA983296B37EC,000000000077361B,A84699A2BA886BE8,1D2FA7D7330A5EA4,C55A5F418BC198C4,B0E7B4B22347B88C,B8DF0D87180FAD1B,75DBA336DBBA1DAA,70A5927807849250,E9462109A72F52AA,5A3BF3849DC148AC,0000000168053514,401A39B4C14E88BF,6850750D9DA43CA7,8BEEADDB09554CA7,995877B1D59D2452,B7E63ECFAAB576A0,A57637F8063FE876,60CC5974D9B52CA6,E61D977649777947,C7A8E6E914D3E10A,00000001A4169489,39B8F88B818309E8,AFD2079174AD0029,BB3E55CD4BBAD22B,22C6D3FE7E93BE3C,D6687077FF01AAE8,01716F9B457CB86D,D9D1FA6C61B7B85C,A092F6027E6A01FB,7E101AD235A7452A,0000000263CC47D2,1097B869E9188105,3E95744B1AB3F5FA,91927F0FD7907344,4EF6DFA1B874F25D,94A428CF99A378DF,FAD7806AC86E646F,92921A0C1FE883B3,CD4A6E5CCEB4F878,77A1998D5AB0E51E,00000000100E0B7D,46AB024B8E3CCD4B,D6F915DD7B62096A,5EC64292EADE2725,19139AE45E4F113F,ED4C177ED1954B57,480CB96313C19DC7,98BDF8D2D631160D,60AB5B56F0059AC2,FAD0863014163C21,0000000125425E26,58B1D00444398E16,ED4B7E9F00A37F5A,8B95A3FDBDE46A52,016CA7D05E777374,245816304CFECC08,3154C1DD8F303088,604886F40955B8C2,18A8D0B633EE94CA,4CBC30BABD4934F6,000000001D603920,CC00FBC1C64B1036,ED5CFC7D758EC0FD,230250ECC74F23DF,E57104213724B69D,2E90427F3C0B8895,F294FFF9B9169BDB,317F1605A8B67FFA,B8D4D3D8DCB4CE2F,440E1077912BCE48,00000001877AF22A,B2B7946016E487A5,9658C93139AE789E,D3CC207845544C95,1109FC82C61BAA24,66ECC15C5135DCD5,AEBE7C331C948E10,353E7F7B033C7FF0,E6063F101F948E35,5E86ABD5F27BBAEE,000000009AB05D69,D26E2D0BA8B0DECE,91330877F4FD1B05,B11B92FFAD2C61ED,0B33EDF7429D9501,7F0A4211D648F16E,0A4AF3B6C7BD9867,82CEE0164838465E,F5B8D5514ADD6BDA,3E0079C69773A6CB,0000000125EC04EB,A5B2DD564CDCAAB0,C14A3E7877D2C208,22AD6C96889BA343,604BD65CF12F0FE4,6F86737ACF597582,B4A46370DC608D39,29A68654327AF63D,E6DEEE352396C6FC,CAD38B4AAA3DF2E4,00000001FC49B89D,D6DF7E0C629A25BB,B8A91CA74E5D1EA1,E8B3ADB8B7EEAE73,594F519B11CF38C9,27DFFC660C2BF091,424A9E11AFA9DCA6,CF9CD43FB4B15B10,B45FDD84D105C7E6,A8B82094293617A3,00000000940DC3E9,C8D4435FB77C5B3D,97DE04B589D2A2FF,32C093340BF06DA9,43EB5D3E1FA88CF3,2B2D2539D660BE81,12E39DF2BBC9A83F,66B040CB076C5CCF,976A153455DB268F,8C1AF74E7D96C770,00000000C3C130DA,171E6ABF415FD0CC,EB02E44E847C6197,49DED6B18DCF6E23,C10A276F9C931B64,14901FC624CBE764,E71ABC65D0F0ED94,C94EDDCD2C737168,EB8D04680B9B431A,5F604DC4BF88D358,0000000234E49B3B,AADA4114DD22EBAD,629F7E2347542AEB,CA3C5FAA07118103,7C582CF7767DA47C,D5CFF3A036F95C0D,B52C6B9845E4B848,882F256FF50FA445,FA89569B142B739E,4318328991542445,0000000258E7C468,4D5FF38F36D35237,5030F0459A845183,EDAE0D79A4864190,BCEF6C1C507600C0,4FACAA09ED15F465,6F245B084143EC35,3180682C833A6D6B,8B209E3AD36F0C18,434D7A8EEF037FAA,000000026A3E15AF,765729448D7AFECF,27753925B25753AE,C7ACF723025BAA08,E38389B4D3483D7E,4475FFBCDFF245D6,8BE17A7FD5A72EF4,2D8DBAFC05AC6BFA,D1079BA79E67FC09,96CD73DE99B52134,0000000126118E9D,3D3B908C81CF93A8,42503A3FDAFC31DE,BB7EB1AE108CF1CB,355641A8B3CF55E5,00400C08B58881F8,87757045537153F5,2C728E14E6737C7F,30A4CCFC49530B1A,F2C97D2A3618F5A0,00000000A6B12F97,2CF7E4F4089C059C,3340E4E02D466C7E,AE8B97882530DE45,F5D1C3590506699E,02EDBDC67C6310F4,6F89C37C6AA5D38F,9F83426BABFA7452,AEC84F0DB0757104,5D63DA4F776575C5,00000001CB6D080C,5E2F80505BE788E6,D179F95A3A923514,52A6031D2B424EBB,AEE95476E04B1D51,778D7D48F1F5316A,ED76F14E4D7DE228,F4276F982E2175B4,D2C3A8EA0B8D07A8,A79240924743BDEF,000000021A8B85EE,B4A7CBC36FD22B36,9A8DCC0522ED2BAF,5B2A358F53CEBDB4,C677C2B085279677,C274A28F805E81C0,68F3982EB1EC2B23,296A67DE4BA957FC,D2EA5D85C65A77E8,54A4041B682A7E03,0000000243367B49,2E0B26C99F211040,C3C73D084B4D6446,B993A5252BC53548,17247B08E3B835E0,536AF21E7F00AA3D,33AECAA64FD6F6ED,00D280F9AD2A7920,53A7784FDB35FE46,F75494A552764513,000000011A89A011,83D652F44D03D48D,05C5302A478A00AC,983D7BFEB891469D,937B141F6C85F098,738356E41EE1BE4B,56E2447BB3DFC37E,0271FC1D05BDFED2,5108DC02CEBA3267,B62483404D5F532D,000000016F357564,CB49548E0E41D04C,2051AB25DD2377C4,A635D7A82E761946,B6E2D6546003CC92,C0C1D2EDA8DF6767,A2DB90B8EC515DE4,3571C474BEB8F155,73F305A589569088,56523C378A9D2DC7,00000001182A229F,E28A24BB509A02C4,7AD6C0C258B0E52A,D688F791654BD70C,D118FB78FDDB650B,9C8D94C96EDA51A6,DF96A2B7F6794912,63621773A3B23268,81EFE272EDE09C8A,0BA6D74DA47BACBD,00000002539FEAF4,BAEDC8496FB4C784,99E788BF6A28B4B2,7BF2C1D05358F6DF,D988BCBD33BE02B4,F42CB7BF95730325,3CDA288F673FF1F3,3856941B64301C95,7C0426C4272E1A8B,1CAF776BD11D7AE6,000000019160FFEE,F85F402238840836,A5E17D31D4573DDF,C7679725162478E5,AD785ED195E8F9CF,5C415A8373CB99FC,4E27CA1B9444C545,F82E8EF82EBCF915,A36AED956F5B1B4B,97951A26B9D887EA,00000000E5A6DB1F,424C57AE7B532ACA,646ACB35001CBA7E,CBAD7BAC69925AF0,79D7D27B6E9B64EF,4DD66FF8F294956D,422CC45BF16D7041,E301D10974DF0478,81FBFEE0A32E42D4,23D52DD10D041B3F,00000001BFD2777A,5657D5DA70E78B4C,B2BBE0099D6E1FF0,920A66E3C729497F,20B9E7C878E631E1,B50BD4E3EE39DC7E,A2E0A26530694765,7E8FD9F97812748C,190F749B8A208862,B73A00D0AA330A46,00000000A3190F59,11D8BD1D2A9D02EF,ED8719B6526C1A16,57E8EA82E0B06EC4,52D15EDDA9D6383C,92D5E49F379AC278,2C1BE62CC74983BC,F48D943FA02C2F25,0513756149183F11,CBFF9302AF1BEF00,000000024C130C85,239C24B5BBB7935D,EF0C2BF551381E04,27818A4A5BAE6C43,93BF95F324DF610D,E152F34A6E9A9648,0CA0317AE64214D8,9AF21A23298C046E,14C1FC8DE6906AA0,CD9FB199E80B401D,00000000959AD26E,052DE990B0CC572D,AA9752F70C79E80B,BA9D7AFDCF1D8996,E98DE08217BCFE9E,64547204E07E1854,264F4E4E53AB7282,43053FF9CE468052,F10312787E45730F,3127E9A1629D55BB,00000001FD4CFF99,0DF8BC21F67E0E0D,BCC35B8AD44C9828,FE0A5EDD891BC57B,C32ED04303FC4A04,A82D7FB9CFDD3DDC,23197D1B0E3F0947,F504C3938D32F095,1B75A115C8BCBCEB,91E7EF18798FB256,0000000101258C74,FBB79AA008E21FE4,F1A1624B07D0E596,0E5DAB5F7E148736,6C46CE88C8E86A5A,F341EE0B5E1D54D6,859DE903661B0C48,1EBC41F1CF150DEA,CC33EFA4F6986BEB,148668E1A86E5262,000000026FE5AA25,C5E5B8FD5E5AC972,662BA4E8C1652E62,6C00300550579687,A52EAA9DECCA2E03,DB847DB9934C5B80,A285E37C6D16BC8E,3133521BFB165CDB,F01B0A45A794DFA7,B0FE778194E03100,000000006968332F,BBD887E372B99AD2,388E9BD2496FE354,20C710EADD416C3C,AD7309F35BC6E7A2,4A713270C2EF0C98,23527ECCA8461C19,26B96CC682A16A46,1698EFF7C5286F84,EAE563ED0A80070C,0000000193C6DC81,955F447F8585F4C1,D4AA50808A4A97DC,33769C8FA64EDA80,ECF20B9255351D9E,16EED1E2C0DBCC49,9E3C7D7853CD00CC,F51A5786F593C133,C9E6F5312CEC7E46,B9EE7773D8D568E6,000000025071CAD5,4F76DB3402BF5C0A,82E48DBD9FB99F2D,B55AE8B16E8F2637,3643C528D3954349,39A3E033979DB54F,712ED67359762CF1,E7FFBE62D5916174,8C7CF371292B15CC,2A5E10B834B9E49B,000000023B3130D6,E1E316C0DB6C0B39,EEC1DCC6342FBEE2,DA0A8ED54F648198,33DC8941D04D5EA4,FC842DBD8B437819,E7DDF460E2BB27D1,F53B48EB0EB18D31,2314CF6E6C78E128,7B1D62B7DB211B78,000000003A3501E2,14CD783EB3347721,F77CC8CF14255007,17DB35B6FCF4334C,8484AC13743E15BA,C0D0ECA77E06C065,DDCCAE5B8D1AEF90,D32998C83DFAA59F,A55B849F0F9DC192,7D397B3DE689D5D8,0000000152BF751B,5163FFFAC09A3825,D3B94C8CC3341355,DC86AC6EA1B79691,1C1CDA614C74DE93,DA2E1BAAA939FD6B,B4E8BFDA38C3CC9D,D1D66EED0BB145B3,55E6825F411E5CE0,A89D655A7E6CC30C,000000023353C67B,EAC9A16F2FA52EA8,EDCA033304376B7A,4FF7D0287E7CC3B6,E9B720375BD78D13,E0D483036017A0BE,0B49D73F4A9B15A1,A4876B74C419B889,128CE5F464F5AEE4,EEAD47D1ACB74C88,0000000170FAC04E,0784CC53FE1AB7EF,ADC61098C15D772D,BAD4104CD38DECF1,2AE867F67E74686D,6FAF963814723ECC,8B00CCF93DEC9C57,70F918D2FE99B2E7,682412B193D1712C,CB8440C4B0EDA6E3,00000001EE505312,8842209157FC67AD,FD86B12410C2482A,44C7A70B79398ABB,9E18AB3FE596DC12,29A0A57A9EE405A4,F0B017DBF5A269B4,503725AEA082350B,C46FE095F2B424DB,2E27F7366883F37B,0000000061719150,BB8FFC194435D5C1,C028580DF7D237BB,6ED2330FF58B0B74,F0CF8DD63A0BB281,9DB01994590F0122,90429186F45B1EB1,DF099461AD05E734,AD45AFB5CE2A1D1F,1CA699C7202EFE68,0000000095CF338A,7D35A00ADA89E0F8,2B3A15602176B852,465B84AF3E94E4EB,6159C91F44AD7929,DAAA5B9EC0863BF8,CD4D9C47DA6EAB8A,7DC178DE811C37EA,C28220569F6F59EA,A330197346CD5F44,000000010E98F0CB,10597FC281285997,EBA0F14D8AA7425E,756DEDAD50258BA3,9DBE71A23876D177,7905787A4A30A344,3EBD390E8685B07D,21891099E180856D,63F034A7AB8AE870,A0179C56B8FC9B9E,000000023BBB0D0B,79573342BB8F661C,EC7AE430DB00D583,E65164CBCF9AB779,771AD647A7B22554,678D5E9D067E4868,887DAD620E1F9758,51FDECF9B4F83079,63D2229938F3A39E,FB193A24809E3EA3,000000005CBB4245,4855992D860F12FE,D80FB9663282F34B,6908D625DBE15D09,6CA096080F99A56E,A8F2586B786ACFC7,E7228C27D5AF1EEB,175424A697B82424,EAAC7060B0F18B61,E647BCC4E6841AA4,00000001557E0DB8,BE27200363431C6F,A7B98065EF95ADE4,1A35F729DBB866B1,06E278FFBD2177CD,9E7977FDDC082DE8,78DFCB3C02FEB06D,9A194D63BE0BDBF7,556205BEC439F100,1E48ADAC4904BBA2,0000000000C4891B,AC8B0EFAC6EA966F,1AFEDEEC38BED955,705A4375EE984FED,209C71B20168D1F1,E2CBE02F5A9FDA63,2AEFDAC8DC6CC3EC,251C8408423CF193,EA23FB47AF67505F,AD8C288CF514F6AA,00000000DAD6975D,B8330A92DB3649DD,C7D245D9C2B97848,5CE20F7D2A14E239,D35D2BB818EEB548,1C56C295489F828E,B0B6EE426AF4A3B0,EAD34F711B9B8755,1DDB5B654CDBBAC6,DC3BA309AF03D278,0000000080A1CCA5,8451E9CAE99DAED1,9E2C8AAD8229B42D,CEDCCFAB0F337C2A,74F152A047E30D75,1876743054118DE9,85047430A8D82974,76D616D9B02BFB53,E86233CEEE4CA45C,8E2B6F4238B96B17,0000000168120706,7E6501656BFB5220,65469070E49E12E5,6EA2F0B5BFDE5BFE,BA006CBBCB9BBF62,D076C0EA11BAE854,B58D61959C6D40B4,260C05B71677EA84,2B5F2A2283E65B8C,E8EF6040009ACDEE,000000020E88D89C,C7A4EA6B9060E10D,6328926E6D9C945A,6C05742354A98670,47B550582308B425,76055BFAEEDA5505,07BADCD6E9C618F9,8D4F56AB3ED224C6,FA69F60BB08BF22B,A00F528AB86CA4D4,0000000082EA644C,ECD076EEB71E176B,B7520C8874D2D3C0,57BD701B5DD19C92,AE866A40C2D9FAE3,E40589D6757890C3,16CB3BD0E58BB9C7,49F8F4D3A5EA6440,492994E042D73D24,E4FEEC9F4B0453C3,00000001CD0F89DE,B7498576F20ECCF5,1697FFB15291E421,92B3B056E08BDC4B,3C583C1D3867EDC1,ED1BCA61B4F86958,4DF704D3BECADD88,C9C94D024121CE92,7D0D6A6E8C11CBA0,A950F242D86F7699,000000004C2290D7,C08A37284F9E3559,617A7F8F85C5302E,AD06843B137A64F9,D697EB7CDC5C59A1,263B19FA3FC011B4,358E431D16A272A5,7CF43684408F8572,80E7CEF247E28A7E,4E2118603EBA82BD,000000018F83B5F4,A415BEF537C4480B,C459F57F7ADF5233,0C8243792CA69D53,3EB69544B5022A66,079D6C07F5477E8A,B8A3004F758E6F13,B307BB5EAD60467D,946B0F88EE02B984,C8AA76518296DE9D,000000021A4DE23E,829C5175FC3B5E9A,60F8ECD36FE2B215,8D6F9FC1469D0FC6,36092E98BE75A88E,6B0EC1EA4FC0E1C5,45FC6FD239DB11F8,BE0091B790B0F426,27C8E50856F648E5,498655ED8C74ED3F,000000020CC7D4C2,EEE4E8481CEF788E,491E5BC82571F4FA,79DC8C85C14DB583,573A394050C289A4,9E5373745CCD79DF,2D583418DEF8B6DB,489124481F186516,5316D108DC89C9F0,100990D2C8CCEC69,00000000DD15AB26,F791798C09951E7E,4AB3AEEAC9E735AD,EC1FAC5DB463A60A,7CD752F1FFE9FC9A,B89205CC7384D3B0,167C525D8647D3DA,002180B968A3F15D,C8C4D73224390BBD,F7135F4097D7D3AE,0000000102FC90C1,7D96553D6DAA44A1,29B7DF6C8DCB13B1,EB7247A021132FF2,C4312EA214D437F7,C81753FE943E2FFC,C9684BABCEA954CF,269873B01EC6CB9F,63FE102110D7CA50,93FDA17F80022240,000000009D184B4C,7FBDAD5DC368E553,C4DCE19B9A379E3D,A0FFEA5877DFFD0D,881A2BC760E77DD8,096ACF1DC812B2CB,A535C4939DA63D24,CB5882905A9EFA05,CD20655097B43DE0,E2FA0967F6824750,00000000F39DCC76,32E962E9B9F76EFD,8AD1A1642CED62BE,E2FD44167E076EC4,D365862F8370CF0C,37E2CF007FD8714F,7E26CE55CCA9BBD4,08B82DA9724E8218,21F7623CFE4231C6,A1C58166AD0F3A97,0000000185A1DCB9,0D2CBE31FF8F55C8,884F4C651062ED8A,70D9358C1D73AD3F,C055974A015BAE6B,D2DE6B6A0CA37EE2,DA9BDF1451BE3B96,F636BCCCE7C1F9E2,0C4FDCCC149E7531,C418988A0C229A94,00000001ADD523CF,B03FBDBC3C297216,519E2E2484C8FFD5,5A7CAF9EE940ACC2,E23E9C9A77848669,FCA4BB410190AE21,B332CEF660F5C94C,310D94A90921CFF3,D5733863AB4E4156,B0992C51D7E9D05D,0000000090B751F6,D47DD867F35329C3,A38B48C156D73460,3A18217F72CBB6DB,1E761B5EB945798A,6A60E94925312BB3,DA034847769F3AD2,E19BD485F3293387,5F0E2858B83BFC7A,9AB06ACAC1C219A5,000000000E6B8A7A,688337291304A250,00070FF0ADB5B381,9DEA9A4F4F60904D,31DB6C35243BAABF,9F5B1A11964B1C88,23260AFF1B422B2F,960BDCDE57CFF36A,18CACF08766EBD8F,4023673CF2F20BE4,00000002557086A6,7CCEB034E5E66F32,018D5E48711A00BB,38B2F16FAF757D2A,2040391EBB4DC1A5,3A768211A8C2B069,3D4C04DBD61623C4,290D3654AB7F9331,3DCF046534B7F396,9B78AAB5357282BE,00000001AA7132B9,CBAE791C47627050,B42A5E345B9F12B3,3B589509BDEE6164,E94EFF7DB1E00CC0,4148F155402CC6D1,D445B94F90DBFB21,C8C92516CD97913D,B96ED1B28F98932B,499621C61A305010,000000021729629C,43683FCE3C2C03B0,E7DB63CD9CECC6C1,719A77D6C327B85D,B405B25A0EF80A83,F6D4903ED894C557,92BC54046BA32ABC,B741D75903F68F1A,246772CDBAF3DD4F,0118988E2B5BD4AA,0000000221913092,770B34739EDCC80B,D7E39361AC1EF9C6,6B163D3852A7E1EB,08CBB61359124DA5,B4B00A318FA664F2,1C433B0CFD6B5B18,44E98BC25518FD0B,91687322C9CBB7BD,283124DB834F7759,00000000D86838B2,12348F28585D2D10,9573CE4FF6DEEACA,9BEC04808FDBFCD6,ED51B13F9732F90C,36F93EE6D0C19707,707B429DC1A0D2F7,6C974D9D81853F2E,475C1D2C6C572F79,1258BA04C68DF94F,000000026FDBAFF8,BC38BB0B4DCE6276,608567A6BFA138EB,5AAF726ADCA7CD20,A48EA9228F9B2EEC,551CAE8E360DD750,8F9046011FB53F12,2082808B2094FFEC,BDFB9F32E025EBC1,FEFBAFDBFA4572DB,00000001B9554DFC,BAA1916F919F17ED,2D455A1FAC8D8BC6,B7A741221422C5E4,F9D376AD772AC3CD,420FCB270F9D326C,5B5D2FB59AE721BC,F84A1CA45CB7485A,71D9F1736AAF4494,8DEE7967CE5DD002,00000001E2AE2FE7,1F97FB973E2A0C10,D3EECC67A9110E3B,6C6A3BC6A75955B7,168ED1849F7C661E,928993D6064BA442,2BDAB731E36E300F,BA4A7F9BF9BE76B1,1EEC949E2F4E3A8B,9A823F7B087DE129,00000002048BC15D,8B8F32609239ECAD,ADD3B152AFD362E4,D4143C131914F1E4,C6484749623E73B1,E1ECB9357A52D35E,3A021415CAD2AA1D,EA55D14319B41DE8,8ADF38DD162D3D65,6D519A3E7E659DEE,00000001C62F2CA6,E3B27B43A5F18211,E1EF3A74BF7D45C4,81E7DF044A1E0830,CE790B4FAA4CD600,A2BDA6ABA3E2B77B,363EFEEA8E5D00E3,6F12737913B55E88,B8A1D5BA92EDBBFD,9ED3AE45946B19CE,00000001DB131EEA,B29191161B867FD6,11D90B0C6C28FD3D,CDB804E700A274AC,BFF2BE5200097283,7BF6992FF4C69F06,EE1167DAD18233CF,5F4B6C1B56E089B8,8B385141546BE89D,EBA938FDAA00BD34,000000016C40312A,B73B004CE28DFF63,DDEEE063377716B7,B25C5B4C5A4C66E8,ED6C3521E945F387,6857DCC8D5735D0B,0C8232362837D786,CDAB48E6B0EDFDD5,122C5CE896E38157,B76CAE7428766ED5,0000000243C3CA75,83673DF6D1F3FF48,CD12C48150D460ED,DF9A85F46B1790A6,77D0405C2674F5F2,D4F0C10CF2C66649,CC771BA9BF99BCF6,845CF34C4858349A,4485C0641A5A6863,91CB51993C2A64DD,000000005BADE32C,3E37975A910BE4AD,AAD8E0DB1BC95BD7,5616BA87939FDA85,168A55787DCCDA69,8C3919D8D58D31CD,7F344006E5980917,2C1E48582F4700C4,CBDC9FA96AB87410,AD13E9287B83379C,000000019508C5A2,EEE521FF61332BF3,923265BBB64B7124,CD8D170EF69EB4C3,000ED0B0826772D5,C5A505856FCAB5D4,3E78FB5BC9D27E6D,05B825FF98D12E76,559C07FF27CA818C,78D075F67303F057,000000007C160614,136F6F33E25B63EF,3D4AE8EF0216E30B,AC9BEC50F608D721,111EBBB8F9B30D22,FB1A5B7AAA56EB8B,EAD0AADBDDAE74B7,C758BAA0059B82CB,B4805B7C1A13A0E8,B6A7F5F7481F7439,00000000FE3D6A80,7741DE5BEFA07A7B,F7D0296AB80F48C8,C6561228EB712E16,4BFE7E60931D619A,819B802275EC9C73,D48FA43D99169931,327CAE68A3220CD5,6AD81919F92BEB2D,03969DDBF471D09B,00000000AD74E004,E0544599D5BADEEA,69AD3414FE20CB0D,E9C19CAF71108583,1A2BE224DBC25A3F,C8FF6A0CEC9D22C4,A84DB0EDF0AD125B,9ECAEBC494889FC2,6A5E8AEE7A70C561,940DA6C5B6A249B6,000000020FE41004,730878E8BB76A449,E98B4EAED1E45A27,BE9DF49872ED2FCD,E0107E538323F9E3,3F649FF6BF9C14DE,52EEED8114BAEC9F,42B10076D56482A3,53FADBD57AEDA20E,2E8189CF208F3A2A,00000000F1EE1F25,B5EE8F8E08F2FD3A,CD0C42789E58301D,F969B296D11F7430,6AFEF986FECAD265,4A7C08FCF9536EA6,344282356F65F85B,0F397360D2E28634,CEA1F0284F39D2C6,60EB9912A89DE2C1,0000000031B9D572,51215DB2601A21C4,C04087998CF60874,FA20991DB0BFB09A,E59C5EBE9E558EBB,2C204AFDD6877F2F,117DF9FEEFC90C70,4ED3AE5E032B4869,34CB8673F0DDF03E,4C26FD8D7C7CDAEC,000000006254915B,D47C2FE5A0C7EE8F,011ABD79DD11F8F9,FC6095834D656BDF,5C9339F803C22924,205337F87F2F79AC,72B22115FA1870B8,78AE2621AAE8382E,1F4B116D73FE534C,E1B2D27BF90E02DC,0000000216C54C0C,D892A7F36318A8B4,C692B08C93A7AFC8,F3D3B3CA44DC5E3E,C28EA801BC773125,3600A049633AA0EE,3C9FEEAC8E64D36A,16D929BBA2179E3C,CE6FF1C37FA704D3,70D2D8316A7912C6,00000001F40025A6,3ED63FD0A790422B,3AFF3700D6EE817A,7ED0A810031CD873,B2B188439AF3D755,E58AEE49E521DAA5,DEC002CE746339D6,A50813D9FDD10110,899A2B20EAC066B8,ECA80C79D2DB5676,0000000222BB6218,955FEF780DF4F572,2FB5FF100417B397,BBD27A9A7938E121,CE24438D7355FE6C,BC78A66CB37F5920,08A72337D0EBCEDB,54DA2FB7D717E165,52A315F6B6DAA793,900CD3B4F9FC7A3D,00000000247EF79A,7D20BCA50C9297A6,F89438B340AF2AFA,971F45416CBD358A,1BC7CB10A2B168C3,A3958C5F603D8E07,AB75CC655699D8AB,7D1A5035BD718180,B82B5377BE917940,D1A04388914F0244,000000027B866B30,7893E35A4D2D8D79,34E2834409E18DD2,EA1807E61B44FCF8,82D979960B0849C5,BFCA2E024C34FB20,748C50F5B4FF5990,541F0042E787D036,C54BA8D11FB60EC9,5E6880319B3A4A32,0000000083DFEED8,B0F60FB0CB426AC2,6156A8AB915265B3,B8863E9EF4516ACD,4800D3AE16C8064D,71756B5BCFF35041,B642E79308F825F3,99841FBE77861E90,CC8C952056BE7107,6B54AADA9E2A32AB,00000001FC3BABD9,58E8DF4DA9A53CBC,74DB28536701B77A,B18AEF79975D3289,B08C78B5A1DE18A5,987F2BA2CDDC265C,8E91962EE6689A01,FAE2F8A622FD6BE5,34E1CFEED2490D13,D3554B93064EF068,0000000044FE1EF8,20961CA2FAC70104,3E2CC3A4029163AA,272F5138E6670FD6,1F2CC4C07C07ADE3,85DE4F74F378C8D3,89D3815E1C46D00D,09674AAC7FBBA968,F65AEB8F2E1CB0BB,3EE95CD02E10A7DF,00000001B0FD6030,041A1473AF34D0E5,2EBD3F51D93CFD22,DDE2EEB69CE6DC7E,8BC7B429BC308B1C,6A9389EA57EFFDE5,09BCED573EE6CEA3,6296664C24EDB97E,6466DC4C2FB1A9B4,552A4CF9B8EFD5C0,000000006D2A808F,63CDD8A2EAE871AC,587880F9499DDF9E,54B20CA6282EE1B6,B5B785EF6077C161,A41EB258655EFE0C,40AF84765AE48F12,C16CE55909B7C8F8,4E05EB50CABA958F,195BC0B280C33271,000000012DC01E3E,4BD1FFFCD1EA1C2C,793C9B123BB3D2D0,C54745E1A831B60F,82613D9CAB1E14B4,94AE01B635AAD42F,DDFF5442424504BE,FA74E83BDD620B0E,7270B01CAA5A826C,172CCC2FB9FC42DB,0000000204C7FD6B,A232A27DDBA3965A,3CC7CF9474E7990B,AE315A8768ABBE9A,441CB15DCFE00207,458204BC966F060B,27D05C658229A5D5,970A58762B4A615E,2D49500883D0357E,262A5FE7823E2F77,00000000C828A3B2,934C206316D2BF1E,80045A6128FB4689,A5747E22E6241C2F,FAE32B1A0A5B9F2E,7303D6F245F6F459,9F81127B44EA286A,E5847311D96E1E57,D9187D1F7EEADF21,0809480D0A4F7239,00000001E86B2F06,6DCADD8DBD018B0C,5E744C7D14C12A73,BED36A14F5E51302,3776E7445F5F1839,5116CE3814B6F0BB,19573E35756F5373,0759BB9CF7D82893,979C25DB74031C61,5F6FBDECFA15DD69,00000000876406AD,B62CEB4BEF4AC6C4,6CD1D5AA71B72E12,F6D8517BA4A4B8CE,68A631080D84FBDA,E526C5512651E5B9,4EADD387DE91CB86,C555EEA006602AD9,4F4CD6A9D7C1B1B6,8EB72281DE79E2D7,000000026EB1AD7E,5B7CBEEAA34B4CF9,44DE35DC222A2DB0,BF6F0B2572389120,2E1FD127DF1B9BDC,46B1ABE45334C252,D92D759353105F74,E018335E2F352AE9,6DE2C77FA2D9B053,42B2F58B62A317D2,00000000785B1AA1,F1CC30631FED2C04,51E875F4BF276784,8A093C1B97BCC78D,1E765D046D2B8D96,758C37DC5317C369,7FFBF1DC0F458888,09BD21EFE2147665,213DB7D2A7EA503D,8827B8231148B758,0000000239038F1F,2D8D3EC22CE5103D,1E237D05D8C02ED2,3440DA8BADC75D57,CC995442D11CCA82,7C9297A567D8685E,AED4B0BE5AE78C20,5E690CD3574F3EE4,0D9FBFEE7A2D1B79,67304DB64E35D32D,000000006EFCED8F,A1D9981ED0AB6CBF,4013BF29EF6F512F,CAC333B69E285DA4,A7AF21F5F99C384A,7851F6F1253D2F82,953FFDFDA3E23A4A,8F486E143892A07D,865AE6980E4C07C4,21B7A671C8D49AEB,00000001C35418DA,435CACF32BFE42B8,2D29848216773A06,9F9E512A3C65EA2B,3A02F6698DE0C6B8,70740A9C80B87B88,592D69BA0A7CFF5A,B28623191CECB564,7CD3269F6190C949,F03DD5E25AD45AA0,0000000085320FB8,D3E0B476074082B5,B91D5739EE0AC901,58F7369BBAD2EB1E,16EC321BF59F5FEE,0275AE24DCC1DE5A,FD8AAE97559C8D85,4AEFDE8B5E813972,987D6ACBB1057521,B07D725AD73A7849,0000000201D9687F,E8FFEB8D5D2DC713,7A8E159859A9BFB7,4C93F68A8ACA7FC9,6935F4A48C7EF0DC,04B8263A54889E97,47BA02642B384E76,9B4035908441397B,2F70A4BAC6BC87B7,3637A0A0D4791669,00000000A74B0DA1,EDA130A1AE2A0115,CA6D54A1CAAF1352,ABAED1B0DCFDC723,E4C0A5A4FE463F0E,0A20C39F759E66A9,63DC96DF0DF3CEA4,1AE119C3A9E16958,1C58236D52B405D8,F5F0E56565F343F5,000000025FFB92B3,FACAE3BCFE2B8325,53FDDAF1824C7E43,402AC14E1AAC2B68,5FD8A4AED821748A,34A05BF7A2B7BA0D,2609B26C49817BCB,9BBF0BD07AA3DA56,27673490C519D1E8,A5B89A211CA4DEA9,000000015B88F72B,5EC81D3E4AE95393,16540793685FC78B,3714622C880CD5DA,245BA73294D5CAF2,6CB3C5130F2E1820,A5FFEA94BDA370CE,BCB4A606182E467B,282ACD48F8C0B6BA,B39C4818F94DE58D,000000002D0A9912,452B14EC0FD82E1E,DC9ABBB31E59B37D,FC6F5B4289655B8E,ECA225C467B15121,81E81C068BE48BF0,1CF47D178E6CCB22,C284CAD69B00B80F,1F141CFDCB8ADF42,89AFBB3961B703C8,00000001DC5FB713,587CB61D51CA6FF3,144936A107356024,481411B9E1844616,55CC0E72FA20973A,11E4101DD481F5C4,7961B31527266F5B,484BDD498F5C67B9,4B3FE6C63DF78B26,31AA722AD09FB2E0,0000000193DBF29A,7E5F58A2022A1F9C,372A109B42D86164,078AD1C03527ACF0,13460C8EC69860A6,B6B4324A707042FA,E80C72BBC35FD4BD,8618485A23A56798,14080A5D528BAADD,2DA223349A22FEE9,00000001837CCF53,F0C3A0FAA34EC770,C207AFFC51ED4FA7,A520A62B16CB5BC5,A935C7FC2BA26816,7A7035AF903544AE,DAEA9DB7D23DA4E2,8DCB84581B52528E,CA33835ADE07433C,FDB7C5141DA93C52,0000000197C255E2,6A5294A286FC6FBC,3A504AF0F7BC9064,BE9BAD19181AF32E,5FDBC170FDDC8A15,58A54FB9FEA05E21,5E20C1AF6757FBD0,3C58DC5D4A698F71,08603794BE71E2C6,64438D7525BBCDB1,00000001B08005E8,B8093E9D2C9C89B7,0E87C84C7FC61FFB,8B12BB4D376144F6,397C294DF6EA0AFC,0D4018FFC41B75D8,7CA450BDD6AFE404,6A5899FB123EC416,00ABB62133535285,9A4ECB64BDFB15ED,000000003629E34D,F000C6A4E77C4CFA,4AC9C0EE33AA7691,E7DA730A59BA5A22,DA5AC0A40A12CF3A,B1EFD6318BB3361B,04073C67A1FB0D0A,4E8BA699EDA01F7C,63D92B6B7CD40D95,DE5D316F5344C7ED,00000002609C93A5,2B59B4EA891C2787,3F4B5A80F9D1B45A,A0FBD62CE881B046,D3AA524A273DB6EB,3C876A70F31D648C,96600C56147D7F28,35E93FEFDD529EAA,BD96CA0771A2936D,0A002CA3C8F9DDCC,0000000178C026B6,EA20B56E7FAA059E,4F805ABDAD8D1012,D3FC7E567A799FE1,591F982454050C7C,F4519A26C702A6D2,400ECA26B326A6F8,0F7A33E578284D60,4A85F02D52175A6B,C85D499322D15AC2,0000000133A6E890,C8A231F29A9D9D36,F4F4C63D9D531F05,F9C739A1E8E0842F,F5B4CEC71504296A,8CA77EAAE2B46A99,614A4D49E1A45457,7706E1CC3D84C306,D591765E4786D5B1,0C983DF3C22FFA5B,0000000076950299,6E147CE48844B7F1,3687C67CB9BED958,470A165860D5C360,230A8AA83DA56C6A,F1F2CFD42A22098C,F9064AA520B561B2,A0315BEFAD9E8028,9B3D2A9F3A01312C,BC38739E9E71C8F5,00000000630B6FFA,890AF5ABDCDD6974,E8207B8CA8AB912F,94FEFE15F1F599A4,A51E6C48AD9CAE9E,277C5DAF30B6EF23,E2C1D35C21E65C77,5A634D351BFA9CB8,C02B5611E1B22B6B,193298A5DE87B639,0000000213DEA794,B9EE5EC84C210B36,4CE7E11A2FF4E6F9,BCFDD673610DD425,5DBE5334961B5A29,82D3D00A14BF9C72,B7A81AC3FEE49EC0,0B9ACBB6FCDD00F4,B34CEA7C666BDA23,2D30F3031A596EC1,000000021CA6C271,5615F90E6008FDE2,3195B04F36D2A8FF,71EFB8C16871F759,21A3FB66049C510B,AAEFD5D09CA24AF6,70E4AD2761F7C2D1,3F7C7506562B8F21,1DD6EA1138261F37,F28AF1DB4BC39649,000000005833DB84,7897D3D272E0B203,4210E44BE59C0088,0A63120AD90FFF8B,61B667EE63FC9EFE,555405740994370F,AA148B527052A11D,7D54539DBCCE75A3,32FCD664B4159165,9A7A50C64AF57A09,000000011D7A5C5A,E06B5CC101C3AD67,95999DD0ADA25B9A,4FF2C33EDB614192,C170B0050FE3D713,C3586FFE425FF94F,72837393DCD29EBA,B5B8775DBB15E144,B5E6BFD91E52C8AB,DE3A2E9ED329C010,00000001E7BBF433,5C4BF45F2EFCD500,F6AE660C6711208A,4D31BAD36B6F0FB4,3ED4D8E17146237A,312DD3BA2B00CA1E,6BA0E5E906965F36,AA5C5F7F9FDB1CA5,0C908716B9EA646F,7A0F1403E41DDB30,000000021BCCC705,E49119ED04B228E7,F90F9049421B7F87,3805F3CB37A6BB83,D2E2338204AAD581,2A761CDAACD5241D,2CB6FBAC48CE890D,94FF4CF5FE2060B9,FEC895C518E504E6,C4D67A04F172CFB1,000000009D64B1B5,C61668B659E46A05,7B6EA27ED32C8D48,228C49A58D7F663A,D2E604AEA5898963,188C1AFE054F030C,A32AD59D2F163133,B33A77CA25555614,D85AAF70F7BFA18C,B589A36CAE976150,0000000092F0ED2C,3DCF5BF866BCBC7B,07929D299F3D26B9,070BD61843E989B6,2C8842AC1B5FA82A,8108B458AAEDF25B,64483208B530F0A2,7547A2DDE700F5ED,18F5DB63D4526B47,0249F227E5FC1853,00000001F160D0D0,2AD32E350F927EC4,5794ED1257D8F8F7,11BB7DDA750562E8,631FE76F6BCD46BC,9B7F0A8A94D13AF0,9366A48E7F9DFBC9,7E0A693664BE8AF9,8E169124F812D2C1,C75A027A0361916E,0000000181DC0607,AB3C9955D0589B56,4FF5B0CA3C7C3EE3,DE621BE9479EBC16,05158EDE10E994EA,6D18DB6B155F8C30,4053099A8DA22FC3,75FBC055392F2E5F,7015CDE61F44E9B3,6B5C95A3552036D9,000000015ACD36D3,18CCA6BE6A017BC3,97BC50C9362B0175,642FD825C9D53A37,98E0DC43E13BBF6A,A93438E2769C68D5,0C99372DA6622104,3947707B6E3B9D12,AE0C7D30ECCA8A74,CB47618D1C09B199,00000000896E5D8D,24C59FEC1C28A3D9,B2D0E6C87AF82CE4,92916727065B8A62,A233A233E0625290,FB61E1CDE9FCBC8B,6CFE016AD880559D,CCF7B0510195EC6C,B4B9E9D94FF0097C,5A900524CCC57723,0000000198C28812,206FE2589B244DF2,9D0408CD9EED0656,66CB41B723234038,D2EB64AA2876139C,1A2733E66B4042FF,AF052E2B58D03FA7,554F1947B0C86591,9ABB4639EE73B13C,364122A47C5D7662,00000000C1CA5F61,C0F523D504414A99,B4E14BA5E1FF7C97,DD33466E9255E6E9,FC0F93696D5EE5D1,66ECF3822EAEE9BD,5C6218833A80D7C8,C06A917B59D43AEA,4289E257FC25461B,2B9DC9A95398BE19,0000000270481B2B,6B097B4D4D0B293C,D885165F9351DA69,7400DA7638A8C37F,2E7771F6AFA2131C,A23493CCAE34B0FB,05473CDA7EF7953F,0BA45B3CC996C3EA,D322E2394F1BB7C0,687827A87EECF3EE,00000001B4131640,A64DACEE822FF769,D7ED7E2EE38177C5,3AFAC04A29E22E19,951E6E365F031F25,CE634C1656644FB5,5B7D8CF22AB69088,BA651422C36166EA,E3E9A7FFF8E515C9,F6041426514553B1,00000001D6434184,41F82107559074CC,7EEBCFE0AB8C33D9,8CFBCB37C4476262,EBCD5B67B140712A,D4DA2861A043D9AD,68EEFD9AEBF4F181,61D2FC61932E76D3,3E8BC9DCDEA46F29,8477237773BFD85C,0000000011D98050,609481B702A4DB18,3A49FCD89A349CF5,CE25131E81848625,4CA6B449624EAB20,8B9FBD201D43A3DB,DACF0C3E8F95EEDD,6E21B4A9D59CD388,8D8C4C84E1400972,BD205A29937B2292,000000023479E502,D8F711002E39D768,967D49F7F8D8A45D,536AFE68A31D0B3B,66ECDAC4CFD3DA97,A1BCA640DFEEA236,739A97BC7072BEF6,40019AF0750A9DF5,8C149F9F03567490,ED8F9531B30A8C6B,00000001139D78FE,F04B1FF8CE339AD6,3573BDFFF4D34CFC,100D79A0B248D7B8,9AFA970CDE15D143,D0D47974F166301E,D2A9610E7E5B8C44,CAACED48B9C210C0,EEEBE66AA7A38736,13819C7B58C59ECA,000000007BD22C66,239C8375886756BC,20C734C6310A4B3E,CDD3BD5D6F9F7685,80321C1B26B5BAA6,241699EF0B22B4EB,6CC6BEDBF78565F7,BCF2B6A17A4B093D,19BA0335D7942FCB,4F56004092CD24F0,00000001FBC86978,ADBA8F475D55469A,D3ECA9C51FF016A4,C3EC22DD545F53B2,50C60628623E6EA9,58CB16F52C190C34,DCC529BA1B441067,1FB7353B1A857A61,48359768670B0F15,8BD8011A6A3C7D29,000000022BA3B608,E6F15D64ACBAFBB5,C70D3A0EB300A4AB,6F38E8F0B0F23558,E32293EECD0F7EE5,C788D8E1010865E2,CAB12D1D53E96E89,21E4A1C870E27B47,F130FB3E48D5BAAC,A8D43283D640B702,000000012DC82CDF,4E40E80A9389E098,8D566A5359DE3BFB,54FA9AAFA0A4E140,0E5F80BD65F67054,733212699B58CA0D,CFE781A63F7711DD,DE74D19599878991,014A5174B1CC1A02,4971C4EE15990364,0000000110546D87,BF444479451DF407,0A605E6B84FEFFB5,37D14F63AFA3CC25,1CD1C36A465C7822,C6A2B0BCFF36AE70,5542A070CB8ED99A,F57D566A3EDB0F82,7F2054ABB9A1B043,9E579120E3398727,00000002183490FC,859B2C4A2BC182AD,1338D4B718921F14,FB8E5C225FAFBF2A,6D6210CFC3471A02,2DC4E597A6E7C2D0,DF43D2556C8A582D,DDBADECAA9F83E63,3AFCD0191A011BD1,04A1CF66729903F4,00000000CC128BAF,1590FC93C2BA5D4B,4D731BD3C29B69F6,92E6FBC9FC1F42FF,BDF64491D185BBAE,66F9B4D8BE5E240C,A15B67D44E6E923B,D21C8B167A953FB2,D62FF3A29212F072,557D03969B3BAFBC,00000001E019C06A,8C1E4A9DC2C03D95,9B5361CD96E3585F,AC8D22537E462B11,6C509BCBE91B7123,2DF98D4E2316D8AF,4F8DB536F56C52A4,BD9F411ECDEC2A25,355FA2A01E76DDD0,B048806E94F536A6,00000002432CAE89,D093F8B9F9EA8CA7,BC5E08FB997420BA,ED35351E872548D4,04A357D7BB3B5277,14388A7EA6E52161,691569611DE8A92D,52AE9E25553CA618,D52B2CDBDF5F7AC1,79060A07B7B5721E,000000026754D431,E80F8C779BC35ECE,3CF1E636DE627978,43D276AD0841F499,38D89460FE1B8CB4,D5717F4389D93D95,083B79F60FDBCAB0,A09CD9AB23DB42E5,5A682FA4CECBF73C,9CD5FA9C7E8EB69B,000000021C5CBDC7,41CD4CCBF3D56749,D0A19958B1007A40,9306530C26021E7F,454C54F82E8E5AFE,97293B81B50CF730,110C1880C4BCD6A0,7AFCDEF736866FA3,9FBD1E4962160CFC,264D55521E343B58,0000000118B33CCC,FC7F7FD13E1C15C9,9F350E47C63E8F13,1383B5870232FB26,B8B384D2DEA4688E,EE7E5E198BEF9B86,EE2EBFF4259D8F89,7EA4137B30DF87AC,1D97891E49C33400,14192FE70FFB7E5E,0000000242FAEC35,209A0ECBB2B30BE0,0366A020154894AE,28BE283FDE7A51E6,A91F715541341427,8E3C2E37044C34A7,C261E32CA22BBD7D,7EBD9F708FD05A0D,BF0EB996B870E8F9,709AB2596ADA7BF1,000000003F7C692D,AC69A0EA7D1FD1E6,8204A12F8F80BDC5,7385C9AC53BD8D8F,D3493D14ED576841,A7978AF682F21882,6E07BE6271F16906,F6B2C32245417085,AF013A4BD2AB5A49,CF796D1AAD6FD8BE,00000000C9CE4C75,B97E9323573185E7,FF7DF971A0F623DF,F00D25DDBE2FD251,5EF7DFE2798E8B40,1D125AC246A51D06,923CE7E9BAC190C3,88267F9A6957400B,097042AF052163FA,9A1DC90BA7C1ECCA,00000001A64152C3,A7D8D6A821A02B2B,0F5753A59C329832,8B025AD0B1F420D2,C78A585D73E02B13,9569BF397781DE02,2AEE677B0521FAA2,DB9568305205A50D,91C18B56972FB39B,2ACADCA9946F20A6,00000001E62E105E,3D0145AB0E69EC96,66EE7404B5D9DE52,29FB1E02052A5F3B,B477F81732AF140B,6C1A392777B61A4D,5B3F12E8EDD0B0D7,6E454432CD3422CA,3674978041222052,E2AA8D73AF81470C,00000000CA85E742,B897BE92B4B7DB34,69555623C896C16F,01EEB34DB61F78C5,F0BE57BC39C54453,EEFAB3FF77B1B0A5,D4549E665F67E2B8,908F9F5D1AF3B323,D936F6556D26C639,B3C3FC0D651A8F80,0000000078387BAF,C060D0DAAFADD213,58DEDC9572350E39,E041C2B0B303B422,681F79D10021241B,B53D6D9AB83C1FBF,4550EB21D8D3DA51,64C1892EC6269D2A,E308195085380DC9,EDE4B0FF67BD2E81,00000000E7566B38,E28AA266F196880E,62A72224C5A89306,BA387728512A1353,ED982B0884759026,E003E551BF04504B,5EA1AF0883D07F6F,5693DBA7FB0E19FD,7ECDCE9ACACFAD72,0812411D89372FED,0000000028017792,B426DD473E1082E2,AAEC5926A31919AF,7BFCA5CEEE21FDC0,B05BE653BDD379E3,C82B699C079EABD2,4A1AF96307A86484,13D116D3120AE6B8,2AC3ABFCBEBDC9D1,A0B4339EC8EB5F1B,000000001A82EAF8,8B125C8E592A9BA9,7F449CE55E68CE7D,88F2477A6586C3D6,6A9C9714800420A4,BDC4D6B90B9EE048,0AA172C6A135250E,3E526FB00FBBC0BD,5652CE30903C9EF2,62E275750941CBC1,00000001237EFE7F,D8CDD38C22B846BD,3732D41FA2E5297F,06586ED601DA77F7,56BB4DF3F3F3949C,7AA739A6B3B05C25,7090029F1330F6F7,8343687C35C9EE06,CBE4FAF806B643E8,C700FDC25B9746D5,000000009A00B91B,C01AB9AADFDF0F92,C8D883D456218B1F,0B06E8410F4E223C,BA971C9A6AFD2750,01AF7640BB06D371,69796D9C3D0542F1,D9D2D571CC9579FD,3142A429DC088DDB,E4BC4C85470133F6,00000001949AA2A3,CAC4695FE15E6076,564ABAC9191F3173,88FBC62DF830B506,6CD29A972D1DC01B,F3A49056CC2B00B0,B823487984B44744,ED9C3B072D3265A9,660A997042A614FB,88A9F0DF997C5331,000000023E4FA4ED,2E923D5B0BA6C44D,F55E0AA1DD1A7928,A83745D0E58A3E60,BD2AF03651E35E53,9793AED45A770D19,1DF2E8DB23DEF588,F7DC758FC13D7929,082E3EC9621EF0F5,53A9A8061162504F,00000001FB72DAD4,835B4FDB2FA56FB3,795EC5D1ED33F790,6D081184FB7F9C00,61500E3FE1128754,CA0D2D999EDE4FB7,9BB2A14A996A6CAF,84263AA98F4F22C3,BF48AEDE76D43006,A23A877630C102E6,000000014D076729,1D601905DB874BBE,840893AD9EFA504F,583FA6F98760D341,BB700F696922F514,3EEA17C2CB919BEB,60F021AD3C8D0A13,A2E09BA646FD1971,65106B30E8120467,9AB044D6E798F4C3,000000012CB4D06D,07B2C6240C4D1A78,54C585BAF70379EF,3900D56DEA58857B,A48F9BA0683C0D9A,07812ED5E476C50E,9ECBF69BEDB672B5,AEEB962D1B8F1160,D59DA79BE0EB920D,C5C95320F6226557,000000024FB5419B,C35C61B5E12838DE,C73B8FB351CB1081,6E80D39053C6624F,99E63508DD7BE59C,9D8EA18243C47F4F,98C61A3F3DE52B97,C11439F5C7210C65,4A0C95DC184ED771,E56C48F1640562B9,0000000213BD728D,55546EB4E1F9F810,B332B877E685856E,A694DAC906DEA5EA,C6ADC05B40E05FE2,A0B6B236929E9E60,B4B96F6439B8ED52,CBF8B16542B83F38,BF684F387F3CA8FD,603D83A7C4C46496,00000001996ED2B2,2FD83564B2138B16,1507589D705D5CCA,0AA407442B24442C,565B7080FF543D3B,9FEA7EBEB4F0FD32,6BD26968FACA6265,13E7E6BB3E91821B,F500EE3BA984C989,1AFB39C1F42ADE31,00000000A12BF8AE,546AAA462C71BD64,BEAAEE68BE7053EC,1B7E20E0C10B13C3,E6AF97D9B630B486,6B94A088DE5E30E2,ABBE72B67621D479,F031FEE54564E3C6,32C16FCA3DF7C09D,76A43FD2CC2AFE03,0000000070AEA1E2,7EA05FB2A380B9E0,BEA16D55E5F4C69C,D5D5C8EC86CCB63C,52CFBE78E3CE80E5,44721D73E99CA7F1,D1B7F540647B78CE,AEFFBAE35AB952E0,2446C0D013E36334,D5D1E1CC65A311A8,000000003A8CCDAF,8DF1C5D6BF46D8AD,ACFC9EFC568A1B29,FA3263D840DA6095,9F0B88C65B876DA3,B0134F10ECC6BF48,977E1BEBDAFD18B2,C10FFD415BFA5861,8389DC34D0715269,221C7796E244F9FE,00000000898E891B,075F00F779865FE6,82FC4CB8ED9F2ABE,AF5D300C9814E4C1,7CC5AD2295EECA37,44275725347D53DA,0CBCA27957EACF87,185F840DA7F627A7,3B29780D1F15A0A4,8214964A402D92B4,00000001266FA6B6,D2ABA4879E57648A,3E153044A3F7E341,BD4CF4DBBAB87CCA,C16886335E79CF75,7BA8C62663FD2B9C,83D2CF90994F25D8,DED5D363EDD66DB7,2578EE07C980CB64,15CEF86967B6DF99,00000001F5228332,70B033FA02F558BB,FB89190A29809963,827CFED7CEBFD7AB,EB080523D881865C,C2677C9C7760D561,DF1B064CFE81D7F0,99E056F891E6ED36,6EB2C5E638EAD9D7,CC82AE39E4E26BEC,00000000DCEE6013,BD62BA50C7EF1EC1,D2C2B98D53DF5BB0,2A020F33D84E1045,040D957C16FFD264,1E698F7CA16B01A4,59F980A708543CD4,5E6C9F2B4FEFEFB9,6A4B8668C08579BB,1E4B6186851DD3AE,00000001D3D9C61E,E1E35887CFF56ED9,7052DFF946CABEAD,7B3B04316285A61C,FCD8E385935C1D95,8B2C15CB72500802,1FF53982D71B4BBC,B824FCDC6121FCC6,D7770CF5D800B8DF,DAF7CF3CF31302B7,00000000C643CEC0,BB7DE1716E58028E,93C2056DC38518A4,AB2D85B7DACAD157,EDE39C7DD0763C6A,0D115B46359EE5D8,A7FE723298823F28,FF6024D6C0CAC792,D9EB9A7F6053BE7B,2B8B17B7D4EA6009,00000001D8BB2619,A37AA871DDBE50F1,FC7200DDE9941389,F379E94F1E7922BC,4D527E87A004E3CE,017AD05710E109C3,55C02D3C2795E60B,3833A91D81FBCDAD,37AA0E6F23375EC2,BC761D71102DE24B,000000019204C515,F58A0AF610D76EC7,E29A346291A88276,577A54DEB830C1ED,98CEC39DCC70B0C4,4CC591E272219FC0,D1F29A642B6485D4,3E6E2CA77972EF23,B61093BB3CBE030C,45DA0B44242AA924,00000001EB9B6262,0785F558BD7FD993,DEF567F9ACF4C47D,BEB5D0A2A37C5C07,9495708C24BCCFF6,02B802DBC6C0C8C0,3F85D2A1F14B5217,1F2D4FFF2F804922,8CA6948CD5098C6E,F72C9F8D25E51C16,000000027B93920E,3D3495BA10914D25,37AE8F8679CB24A0,AB6E9B74D76EE652,D9EACCA6043C36D9,7836D0744E5A26CB,C024D8C73E1CE94F,D015F5D8E80B5262,FD279C9BCC1ACEC0,03C84DBF90DE9389,0000000004E6B53B,220BC0EB87316292,4B64CB1451D5C488,7048DDE5AF5F64D6,B39DAC2A8727AD86,ABE36BAB08876718,7D60538095B49AFD,9116724E2981C168,15C50005E4CA89B7,8965A44E69BF6406,0000000209557842,8B8C3690BBFA0B31,91C244B0EF54EEB0,B6B515167F172AFB,EB3304E6F34CE170,ACC0F195833FCD6E,0E2E31D6FCB52A50,8EECAB5A3614151B,2695B1522EBAD978,F535A019A64A9AE4,0000000136EEC32E,4E895CCED4F5E7E2,6418DA670BF789F2,946E297E2A18A2B2,338EE832CA5947DC,BE6828035CFBEB20,9D00425DEB190647,1048EC4E41C37E7E,3D00D2D60029EBE0,F3C91829E4DCF821,00000001EC558C2D,5D9525F93C9D2874,83CC932970140DB1,D1A78E73246739DA,9334C0EF13CFF159,0BA0FFA8B9C3C561,473719255F992979,FB6F55573DDF9DFD,17E9B8F7FA45C4D9,BD5674869A5DEE1E,000000012865C91F,4FBD2DB5B4FFC27E,D13CCDD19BA527FD,2ABB0181BC1680F8,B811EA194854024C,1DD4AAB825509876,97861E0BE8E0ED2F,4868F7B8D1AF4CC1,7119F0421D2047EF,45ADD852B7F2E398,000000007764F2AD,56A4B0084DF3A2B8,0C4D42337B70D70B,B9923E797729F713,626BDF6CF7BF7C00,64CAB8A977FB9397,C56635000EC8652E,971A11A8182C725C,25C8BF80B24F4CA3,F68E42D1B975256D,000000026B9142D7,64427AFF3A014728,F0F801E55083D496,23EB2D5486D52D6B,6817AC715D5538E6,4E5FEFA8396CE709,69C926D30687517B,659A36BD55D9EC5B,71F206060955E8E8,7C682E16055767F8,00000001C1F5D260,814326DC40825F08,1A6BEE89BA05EBB9,48F89603B410C92D,CF558B348D26D2D9,D69B64C7DFDF74B2,26B74BC1118FC5E6,8A5E862EE58CFDD6,B98A46FEA0814AFF,3252B38E16CE2850,0000000223A6A4A2,4F7BF1C2B2B819F5,53850C4E3CA82C23,86EFC6FE181E84CE,D49A9DBF301DFD7A,B722CD5ECFFD0FFE,9687AA95F69D86AA,6CEB9665D660203D,8B92A882D1979E7C,C60F5A7775CFA55F,000000015947C996,E455376B9646C727,B5E741332D540C90,6DA0474DC57C1A39,35E33CEC6164B007,24AC72837314956A,04D62C127AE79067,C3D3EB9033FCB07C,5B4E97D4DA165B9E,FB5BC7D4577F0CE1,0000000091C5DC89,20FEC8033EE7E617,1D1541947726DD67,2D159C2A71457D7A,4692B27814A7F72E,0C8017686D60EA6A,04C8952D1DA2E26E,65F710060721F8AE,4872C8241AADB803,96FF1818F380D504,00000001B188CCCA,AB6D56EEC1E5EFD8,D4E49556DBDD7580,9FF7BD5DA3F9F81E,56B13BAC07461012,3A0D8204ECB331AB,43C7FCE19153507A,67BD8986D7065C83,55BFDA092C9F2878,B3333DFCAAFFB01F,000000003F137110,864892C2062FF5E0,B1C940F3D1600863,D5E3A67A35DB64D6,85498C879EE7FD5B,04C25B210DFA73A7,3FED1A76DFEA15B0,F2FC1EE766D1CF54,F75E41A18F6AAE50,A7B86CFF9BCFDD7C,0000000038FB186A,45600C1EB6CB0219,31DA36DD86047A29,BBB7F24CA96F4A08,A47E54BEFAC2DD66,FA126FAF626C9C3C,1229002FECD119D5,1F94547FB36572A7,F16127F5842E9F3E,1EBB882BF0C52BD1,00000001B106E8B3,1E2E5C5ED52DFCDE,ED2E19A2DF06730F,29A06E61AC0A2AB1,AB368B1BDD09EFDE,185C5E8ABF936431,BDFA82B4E0A55004,C9B75423065327C4,146A1A9246E27600,6E251AAA2336A7B2,000000017ABB3371,17AC38D50CE96AAD,DD0B1D3EE0DF475E,2D54CC6778407304,D7C71C5ED9AB8E04,21394B05EAF04A7E,FE9468315DAEB3AE,4A6AC86424B78A5C,574755DE7010E895,6A497C60EBD2B469,00000001F33C1EE4,A4317DCD0A5568A4,51EC5319D9B17941,5C683DBCAB978FB3,3F24AC22860EAB99,0C38AA47A95269E7,7F43B7CB64315F8D,19A27F1ABDC78EC1,CCB09A22600C946C,AF255BDB7177085D,0000000139223A06,AC43A5E4BE5DDEE7,48258406C627E7A1,C8201370F1C3BE5F,BE436C64ABC3DB3F,0483889D82728692,1D8C1DE4D8E78A28,C1BF58E690023F81,BC4C101C2E442850,0ED9214CC5C9B8B2,0000000261421560,C907FD73ED4F89FE,2089FD36E6E9B619,FB50474C5AC5EF84,78EDE417AF8C6E3F,9E4A2518AB750A16,67ACCAE95DD06138,3920B618FC21988C,C2AFA0C435D91FF2,9A52BB177F457CBE,0000000174C40021,038A07F6F2AAEDC5,4CD740C36E61BD99,1D828252CF2A6075,34D007222B748E71,12E6D5A3CEC7E01F,0D0FF585C76192E0,5F69EFD10383488B,7C2F9D3EABBD2929,0DF93141CA62131F,00000000BE57140B,3AC0372B621E3443,CA55AB691FCF52C1,D62E7DF3EB7CE3DF,26EDB6A47D1DF413,A2C292CF6B179C81,AFB18ECDFF78FAE9,830AC4F928CAE037,FF6795D6DA4F1350,C901FC2857B95A5C,00000002119CBBC4,9BCFE75FF2476582,B135E976E7F0E34D,6A704467C05FD844,4BFD5542DCABB30C,D2DDE0E41021235B,78E538371E1D1F6D,8C0532442A8F5C5B,5A30687BD161BB7F,03B0AFBC7C603A28,0000000055E0D604,FADD1BAFBE6F9799,31816522D888E2B4,93928DD49A73C788,9518AC3D94DCB6B4,D26BE08D3E6F6C81,9A2B39EC34F3FA09,994D2D5CE9E836EE,830B84CE354BFC2D,0FA2C57DE77D639B,00000000F0B79703,7C063936E18BF887,F1A96C206C9EC568,C8C0089868CF6E32,7DFB3AA4954E7DA2,7C702563491E1FB2,39393075BDF3A603,76C24E57D78DF441,1010CFF268D9D9A8,E01EA57F223BCFC2,00000000152F02DF,88C9F237317C8503,312BAC6AE387A378,6A2501311B61D97B,B75B5758D2193E0D,2195202F344360C9,D16A3100F0417B90,66E71DF2D4AC42CE,BF2E18F01B0AA418,E6CB9EB5490431AF,00000000F773B165,DBA714D489DD70A3,14F32F1053DE64F9,2C8E8DDF76B7026E,BF0ADE80C203163E,9F016BEA314D57E7,44BFA45547E62DD6,9CABFA71C838CFED,8DB0A0A3D4E5C164,3493B09AC2EEEB6A,0000000262E9D0B0,9DD6990EED62E6F6,816387332F3112E5,D028BA543C46DDB9,075EE2F51B9B5E43,093A1765898BBB70,F5E1EC744D172662,D3BDBB0FB59DA6BB,87D43239BBC3D752,0C3DBBC6C6075034,000000024B5B1C4C,A288060E9A8E04DF,352B4AD82BE9CAFF,872CF564BA60BBCD,DBE5A8773C40D5E6,1CFF42486CB74E70,29451739FD977B88,096AB31ED8F92799,DDAD46BAF71544B5,293EDEBB45963A0A,00000001A6563E3A,2E684154CC6C492A,10C847F50E65E4EA,CEC666A28506077B,847807E3E32ED46F,D950E37AD2816582,C6CB0E63535E61CD,28C2752DF3DB8B60,2EFDE34ECFE90234,20FC0849345B6758,00000000133C5309,8A76E8D04CBD03D8,BB2BC96AED0F718E,B5A5BAE12E7DABC5,E3928361258712EB,23390C1EB5AA00EB,140F1F6D6341C271,94D3A1E15B5D233F,F15F1195C21735E8,13293B115D5EF57B,000000008D64F212,DF19193C687C939D,FFB849C1F603E028,A0EAF2AB5E1C2F5E,26A5D2141A0C9D9B,09C8A1708BC466BB,0A03F06F698F1E57,D4B89711E84EB1D8,B84B7E93C3D9C296,919AE730A89A2708,00000000FF09B49B,22E6400989C89E96,0CCCE317312D2A92,4224A37546436354,3F77FD88FA965E94,D203E5163A7A7D76,2931D5FDD7EE4005,7A26F5DE9FB30DFD,155F2C11C5BAE6E5,D165FC137F41AE4E,00000001391B36FD,6E477AC0704A39A4,7714DF9A8F190B01,00B3C34C9A60DD4E,85814F2B9F97BF0C,B1F0DAAB07157920,0DFC3B725EFCBB96,CAB5E02C581DB653,BDC338508A47187C,4E6894964EA8EEDA,00000000B6CECBE9,CD80739EE56EE3E9,A3FC91A7036423F8,476B4B8265FEC102,456BDA1AECDFD037,FECF6827FCA2CFDE,A684D8C232D05EBC,29EDE1EC1E193111,560EE1D798F949C7,5620033205904937,00000000549E9901,BD3409D75BD5A07E,31E8CA9F69BADFF9,17DB3DEF93D91597,8B7753AD2B08ADB7,B9AD079D0AE58E35,B426FCEBA3FA0B32,DA66E04F906F7B81,3610418067867A9F,C164139383F777E1,000000011BCBF57E,AFFF66806E9A8F8A,21B7956A28048CAA,EAB6FB928B9D0D1F,68159F71A7CA2E13,5C9307F6901E65CE,892BEDE49941A186,0D6517A38FC9BDAD,443327A194A07FE7,62AB58FF3ED5FC83,0000000183CC23D7,C2819A8A6B6CE662,B2D031AD05E6784B,247672C95D88F7F5,B8883F43A12D3CE3,B50F1632F9C655C5,900E6D885459CC06,9C228B05BAE9FE7C,D20E91D0F692F10C,752BB595D922E006,000000005784E35B,38450C84FE448926,4533C425BA5F05F4,E643B6ACF66E7537,4A022B08613D0AA5,E90E062A7DA516A2,C92D82CF1BE7D9F7,548853456C6CE4B7,7A1B54F251FECC70,9D43DC02B65C2F47,000000013908DE56,ACA0A9EB7AAB3EA7,6FB10EEE294E9345,802F4732AB717AD4,9582028E4BF0D56D,92B9097B6807FAC2,CD252EF86E8C76CC,B1033121579B66FB,7DF0E9C92308A63B,B58E0A57298E5365,0000000226686878,E9E3E0776FE1E8A9,1C3A903B91B075FB,25FA5583EB485955,6FAA7D069C7D1D65,2C87D0C6C8BC115C,D3F4C3F83C45BE0B,F4B907926419E279,FC48FB97C7544A59,1D93E90494CCE75B,00000001B279B2B6,89428856879F2382,FED2BE6DBFA67FDE,62A0573CD2CF8591,F308E570C9BD6BC7,A28FD520273C2B0C,EE536FCFA91C1A09,32BF4943FDCB0A6D,F96BAD2FD70E11BF,B7C4C86151719D02,000000007EBB1234,A082E513E1AE5E79,3EB18A3EF2C66023,172A7A0A64C59F1D,33EF92A6EBB05691,98998A77925FFB0A,4BC91651DC514F1E,56AF5ED6E74B586A,28517A050277FB92,F611B291849B8E1B,000000003F3635DA,9EF1478B5F8E6E55,1D5DAC002CD0248B,2E806D9D83DB1223,3BADCA54AD9DB610,2EDC44B8E21347E9,16174219B437F2C4,4605F7FC2160555A,840380E6951198B0,E92F9F17FBB5D62E,0000000028B7C6DF,32378FA2EBED4715,E8B444FDEF4A9D90,BC587CD22EADC0DD,639679E941BECED7,84666B256A8D3210,F7A1D73AC1E157C2,35E9DCDF87C9B7F5,61C7A91EE3847E36,F54A40C330C040F6,0000000132B10673,3245C9A9A8893463,10F1685C01B2F90B,B3FCBDA0BEE1903B,6B3E7BDF3CC13CA6,CF98EC7738A92A5A,6D121B2FFD7D090D,7AA413117FE766BE,9D8F1EA42924D854,ECE240F737F516E1,000000024E7FBC22,DF42F8666CAFF1F0,584B9FE7896E85ED,B3890ED61A71BB22,0D7A86523D5A50D0,DFBFF2D0998B57E3,2510F7E3BDEB7B12,CE1FFF5796AC3656,79F75F2912690752,FBE31EE8FD8696DB,000000014DB971CE,64A348E3C5300F22,F65B73D0423F594B,FAC2F3B2EFA21529,EBA7D8C86B29055E,2B38E2E5AF85C39D,35210D92E759E3BC,3FF47BCF089D5A6D,7FA0C82A12517D34,CC641C64FD12B1A3,000000014C265857,299DB9A0B24AD931,69CDA4FF16D68B92,AB67304F94F09667,AEF5EE0FE7047626,6CD12F1B03EC9071,CE1FF703C7E0F56C,2DE00C49BB21BA0F,9901B1B2434664F8,4A265FF7EDBE4F82,0000000135D95390,8E9C9EF735095782,10FAB588A9EF6CB0,9D71DEBED4A2E128,890EB0F7A7E05B43,D590A77E64CF5ABF,F8FD49FE7ABDEA1C,B503EAA9036DDC73,8704E2A0E93B249B,6BE99D1767AAA1E8,0000000000505D30,57A36DC8776EB996,9C6928684DA6C64A,A9FC9CBE19B57649,276355AEDA29B267,3BF8555BBE292D02,11B51C1E90C0C421,F5DA76CC8BF0D40A,BB7F5FFA84B3EB09,BB433F1522B2A93A,00000000968F0B9F,3EBBCECFFA5EEFA2,EE3E6941AAFB5F56,C6CCC1072DE2BE06,B6514C4A3BF6A498,1982534DAE0881D4,6FCD156B0F2AABAD,4A9BC67065851694,24870886ADDB2649,B931AB9C3E8DA4BE,0000000045D2691E,674C7D6F2C63BD40,3D51C51495C9DA6A,7A72E7DEB4C0E489,995392A2BCD0B937,2E9508AB143DD066,CDC0850114EC6BA0,4559F53131DD7F7D,61CDB501403C73DB,DDC46180FA7C17CA,00000001CCF57C0B,18290C8827E676B1,8AFD47A3CEE0BE7E,917875D07665AD89,F89C3262F0A395EC,FF35C80D4AC2EFC3,41992DEEA2A957BF,D3490B914E890305,9C3EA931F19BFA04,4D1569A3998EF9A6,00000000417C68F3,64CCA1350CCC0CDE,024E14F45A75C976,DC8F08B3CD3D78BD,3C0E9D21197DDE9F,26DC68DB8223BDF2,48EDF6DE8265BF01,22352EF5E364F835,1C795ACB239923B0,C2F67D4FF8662F1E,00000000146011E5,BAC7EAF7E522FF35,441464B3D16F7153,DDC68DA5DA441380,2736BAB1179B0CC4,68011048CA2EFCAF,95E6FE0E840446AC,50D322FEADA94639,39820B6CB3F0AFAE,0CE329C103A54DBE,00000002785AD777,6F3A86B45218608E,43536822765C9FE3,499059FD63EFCF77,7C2E6D346F2C37AC,003FADA111CD7FC3,1DAF3F6B37331576,B993DC93C43FBB4F,303A5BB1735519F6,26173F67AE8AD7EB,0000000138CAC575,2CC66680B491C793,EB88B9A67CF7E8A0,F948E3639917A7D3,751F416772A91C6B,536E15A31DE9E0E1,40DC176417E23404,1DA097F7A892306A,825C94B623611E5D,DCDB197FFF2225C4,000000016D6FEBA4,AD1DEE02F9BD6531,BC60D1D2205CADAB,2E75551288DC8BCC,D3F23117710846EF,7959EE3B905B4E4D,27B374FAC7CA9B82,8B893E32461714EB,4388574645396277,FA07D1CD83538F58,000000021D662D40,1C508DEEA2AB06D2,F698B6FCB519F6FC,E0AF547AE6DF9EB1,2F2B706595C236BE,6E2F529A4E1C4ECE,2BFA7B001679F090,3204BFF4BC00CFB3,E597E961B99E75EF,4C0A3D09B64F09D0,000000002AD9E3BE,1F9C66BD8DB5AA86,DA52497760AEF3D8,AF5BFA36381075DA,B61F99B7F8F2EBE8,0FF0E970C48042CA,921F166776A82AB7,9397F5C9069197F0,9B28F25D8752024D,F3845F297C416523,00000000471F8384,2CD96F1EAC6CE8F6,65E86D116E74A4D1,8EF2DB763C4016C9,B25AC5AC2E607996,0CF786441BB19C7A,E59F738058C3ED8B,0622C357A4915CCD,60F01254B9881D63,CFDF5A0E2D53DF81,000000019BDF690E,3A18EF2FD448BD7D,29C2F2419B022BD5,BEC0E907F0367EAA,DF8E05E5F6CA105C,42D854DFED8E78FB,C0FDD494F1FC325F,F63A7EA9012D97CF,033DFD5924AE811A,FE6C0E29AA8AFF01,00000001EE67C9D9,A14D00C7F4A288E8,1BE9B37B3991D91D,215B6090175AD48C,FBF93B1B67AB497C,3E8D5E3033AE6F00,1832F6C4920E6022,D5C2D75713BEA6D6,EA267D8FF547AFEA,80B80C5E7F5407C0,0000000169FBC642,2790995CE6BD3ACA,90922FCF2D3E8C71,6F12163EEAFFEFD8,B0E006354A09011B,600F9E2E1E22210D,D18AA4D8140D1923,05CC4BE5038F8F36,474DDE942A15FA72,05BAA422844111DC,00000001D53340F1,44E1E24CF16C1624,F14ADF339A956E77,CAD1C67CC850B408,FDF7A4E47DB9238E,8C6E57D1D94EBAA0,69505943AE0E4061,A206AE762EDD3900,D23EC8BB8627D7AC,A1D015A1B8594D63,0000000183CFD7DB,87BAD2E6F3D35FCF,BF8B8367E7474322,B2F103CAD1669A50,1652E113DC3D3A33,1ADFF9794953B9A9,DD78AD3F01228A34,C4A5578BA33EFBCF,45F37C1F32496A5D,E49855BC3D617982,0000000103AF04ED,7E269DB363EE7507,371FBF9CFA021F30,91A1BCE3D37E9B89,9621DB5C3A31D601,22814DD5B0C27FE6,CD027A8CAA22D7EA,DCFE6174F0E88BC0,C8C30CEBABECCCED,D348603AB5ECB4B6,00000002109983E1,12CF5B474A0A01A1,9963913DC8BE90A8,AF43E60B44ED715D,B7D20D8D334304E9,D18929FA5DCB908D,518B990B6F8E96D2,35FE5787FF38BD1A,981F9CDDDACA5462,9582414EFE6681BE,0000000206C805D6,F900F53A173996C5,3EC4BA9FD5F6E1AF,AC40A0239B3346F5,463A4F4DBDCA583C,FDC3340739D45DC6,D002FA638D7F42AC,7133B01BBB1CF3B5,7A604B57F178A9F9,A8C7E73BF4A24BF6,0000000204306F37,665104E87CAED457,1B724865A342646F,4E4CCBE0049BD8BB,635C549B83CDBFD2,CD51CEB79CFC4754,7046C711D33F04B1,BF59D27D82592565,B1AFFFE35CE9AC53,E05F336E9B7057DB,000000024D396244,FF96B6D319A496A7,BF0881046791CE2E,51D9C6D953819417,7193C234A5AAB704,6F95420609E667A8,DF9E64911EFDD525,B013BA8F3C18BEFA,DEB48DF03B1AE23A,F7DC077905DEFA38,0000000177E07C26,9DD5903DA8B1E3E9,F606C3190E4CCC2E,D5F04B8EC4E13B15,D8265B5C86D53233,1EFCB4E7511B51F8,38DE78EE4E2794D0,18436342CA972DF6,4B83AE68F5CF3F47,69C22939C915BEBE,00000000A7C12E52,FF28C301DC6CB1B8,D13D91EE2FFA32C5,2CA89483AF949752,216AC4D7497779CA,F844A683E8098E87,DCB6A20905710F07,AB1CC0805630A84E,CAB8CCA3C705999D,F3465BBB982DB0DE,0000000045F556C7,0EC65F30E1DCFEF6,ACDC60AAC10FFB5A,02410E71A894252F,769CBEF5765183B2,BF087D3DA60B4217,491D0A7708C5D6D8,4569256B4F97916E,5B272788969E6404,CC37246C367A6C57,000000007F19C0D4,0C2839895D5AF464,5C55F16B8437D696,4C3ADEC64664B881,A8206794E0A4AA92,EA8B8E477A188BFA,577E635417CBD8B0,A41761A82F8E92DB,5C53F8100ECA69FE,24FCEF5D1AFB847D,00000000AC68268A,1EDFEC88F45A615C,8302AFA34C22BEB6,D4DFC15DBDA2BB4E,E6A3E1873A9A419D,3D24989104C6143A,D8B35E786B7B88F2,3A4C97C87A2F3A4A,746C7EA2F7BD4A9D,D9EF277E4155F6B4,000000000B0EAECE,2D3CE8A90E8E36E9,6A4DA1CD50603D73,9EC376B60FD10C32,EDBDA31A23742E6D,882EFEDB1ABDA000,909AFCE9C73F86D1,DC45ED43B7092B6E,5986D4630A145D79,AB80BA5929A4213B,00000000860407B5,7C49E0825CB58515,759F36A4658CB570,20296E8631AED44E,75BB8A051007EA6C,C9EB7F3034537F83,5A85EB88EDE3A298,5030CEE0C03E2F87,028CF0277BAA0156,B23B5A9E2E8B8FD7,00000001FD026C9B,A480DDD55551C8A8,A26F7A474F0A68A2,F2996AC37E8DB51A,2B46DD03594519E3,DDD99C29537137BE,513ECD751F9D88D2,99ED414DF4E208F0,65C7E9536FC219D5,93071F4E6CC113FE,0000000065CDBE2A,2184CE8C4468714B,B49737070E65985D,BDDF47C78B486D97,E5CB1D1073CBB4BD,C7F42FDE8A093AC6,26F30B50F1A8451D,B144A6658BCE234D,B6E3F1E91EFA8B99,FCFE5F756B61FC1A,000000011F448B9E,63C53D2AD62D6FE1,D3B701CB4B65447D,91270961FFAB3A14,EA9B26D2FD491F42,3ED5625AD51BC341,B26EC32493FDB627,4A9922F8C991C6CD,120EE6E1C6D1AB46,C349B6DFBC4F060A,00000000F74FB691,1E55EF174D558578,D92DA8DA9D8E8141,FB8C5DB33AC2BDE0,360A6E7306282D77,7827DA26C3EBC7B9,826AA864976EA94B,A691FA3CC58BF368,D1EFC709F0F2BF50,1008C516EFD60D24,000000013A085C35,90FEF735734D713B,1BD9CF9C99F1F68D,DC9910C59BFDD7BD,A7A13A565F494610,2904CD8A597B59FD,E6C1FE47422B77B0,02BDC9A53BF03DF5,DB6F379FD25188B5,2BAF593E00B881E1,00000000734BDF83,0AB64E30BA9F498E,966A7E2F99D9B123,BEDE9B416E7F4ECD,7F51ED912FD76FFF,0C45F1BA21B29146,96FE51757AB0C255,6E7AE0944986D574,F956266EA5A62C67,A7C9A707D3EB6A9F,00000000E92A21C0,BDC723BFE719C017,EC00881D5A16DBCB,EDF969342A4A38EB,77657CB38BA03B5F,5302B5EC77097DEF,4D0FD568D28F9FFE,FC2E3275E80FFB4C,779FC35323C38434,47FB893D7E475279,00000000089ABAD8,1AAE5CCAD43B0BC5,5D6D7E2DBBABFE20,31C11238FF1DB6DA,3B01CBA30B87566F,A77278F94C129030,9849C78D21591E3E,506F7FF31BC9F569,B38BE7FFAFC9E5FB,C53E4F70B562868E,000000009BEC318B,1E12545FA1AE47CD,3F448B2278B1874C,71D4F6E80CD1D0B5,52ABE343FFB01ABA,2E9AB3372F2C10E1,34DAA88D5BCCA763,F6CFABE74243667C,F122DC81DFFA9897,A9DDBABC05701280,00000000FA7E1E10,A129E05271590822,4229B8F9A5F9DD02,3026D2A9A264C266,42C8C5CA8107D11A,43047B6BED1B271C,72066BAFE2902D59,4305F2BF68566E65,E70A2290CFDDFDCF,D66C6D8FBD653CE2,000000007C91E8D7,DF73458E0E182B2C,8B3832C8C0CCE693,BE406A78BDDFD4F0,65D2881E6BFE97A5,946528871BF3D17D,5CC79D1FE7A7DEA0,514ED0C2E12E63B8,1F7AA27C456B20CC,DB589E0733E5AE0C,00000001E7083012,47102C9BCD9B3E8D,6B7EA8D869F843E3,54A50F6E448D23F7,FFEDC47A6428372F,1AB355733ACFEC6F,F6AFCC91EF616DDE,613BF6EDB128DFDA,431A22C71D195C03,C3810B50E0F7D68F,00000000F79DD4A9,1A8511652309F607,168ECA656072818A,A12C39185460B2AC,1E561D5CBF82D15E,315C17E90BA34075,FB27FF960C362AAE,DEE05C1D2A5B2C1A,E6CC8FB010BB3B40,047FA1C3670F7C43,0000000048FC944B,B7BA6EA850860960,DDCE129C36070264,CD967750119F8C25,DD95B3DA85F96A8B,F96586C75C0D3DFC,68C554ECF16BE8D3,E27A72F386E734DE,B112B3BF3CE34DC7,D2AF0175394D0CD6,0000000196D1586A,4288BC885734E14D,CB3FFC350460C01B,68F914055DE798C2,3E2ACEB6F8840A9E,5E0289AD2425B10C,4629FAF0A5D64BF6,DD875EB854182373,33B6B9D0F2D89EB3,C343EECCAA472B9C,000000024C725107,1F6FCD66688BFB32,D68A8A4DE7A788A9,2B198661DC39DBB2,E29FE49C70552592,AE6CB47244A18073,EA271CCEC64A2FED,C34DEDBA70C98A4D,A2352738B4BC8E20,E1FB892639D7D721,00000001C7ED3683,D7169C9E10B5C8DC,8D0AAC84AA81B157,43ED3091295399ED,9925E1A029581925,F58A0B4125B801B2,7C6E7558AA21869C,F446610C66FA3F8C,0B52ABEF44BAA02B,532481AC885893FD,00000002755155E4,4A936A5C2839ED62,F2C1CE12BCC2012D,47620FEF0CD4A9FA,476F1E3FF8D8EC8F,71D3836CB82D7E98,0AB59129D208FBAC,3CBF98F752D02565,4E0BDBDBA214F2A8,018D4FF630EEDDEF,000000012D31EAC6,559C19CF8BFFF79C,056F9D4FA457F492,1176A672594BC1EC,93E315B650925694,0489862EC1AEABD7,DB34259EE23323CF,42C42794CC3B6F41,2A80B250C2DFDA93,0E0760D916C63583,000000002785FADD,F8E68D642AD79094,BCE97174B7BE5113,708A6602DC5AEBEE,9C6DDE2618E61A4B,56529436B07CBFFB,5E05CCD319CE0EA0,B116485C6C8CA635,EC834732A602D481,6AA81BB69ECACB47,0000000192753BBF,72D71332D7C6C658,0D5F8626C96ABA02,B740FBFE1FE7EA6C,316B097DBF4DEDD9,7BD1CDE049B4A829,E1C21AA1E43167CE,AE10076899C41417,3EBA6E34642CCA13,874C0C4CEDDAB90D,000000015D46437B,7B818B599BBA4C86,71DD0431348E2E5F,C7712C3179001504,9ABDD55B8F279CCC,6135D5465C13A653,0174862C3C837916,8E567AC021A570B4,348B2E2399BD86BA,35CF3F7B65DE88D2,00000001AEFFB441,A52AE90AF40BCA7E,72B46A13BE3DFF78,FFCC8D7C0149032E,59CBDE91A7320687,4C3C6D94C53D9AF1,9EFB26D04425B264,F28824FD2567D163,2CB2E767ABAE7ED7,305AB84B2615C379,000000003AE9A4D6,70546D268E151C9D,94D422842EC57182,8C74D924FE9E5140,2BC6B3D6C9A4D16E,36048AD61ABBE928,13E3FF08B18A7AE2,C11AF19AC1425327,6B95458F0169A83A,2FBA145ED6C3A5C6,000000004218996C,229A2A7AFD5056AD,DF6F4F236DDDBA85,3210C3ECE32B5DDB,93739A88842C4029,6E731940492C16F9,F8748EF02D63850D,F4054A3391F61197,4A459ABACB9E98C2,C77C654E722E1F95,000000023732CB53,CB9BAEB264C7401E,919C320E62EDC09B,488BD3EBA66D365E,4FE2D9ABF24E1D8A,31D935A493B8401F,2CB76A31A5926A54,9C2E91BC29B72B24,846276C516BC768B,CBD9D0EAAFEF6D41,0000000076060B8B,70494F5E7FB02AB6,729F3ABAF981F56B,0726A9B8EDDAF431,AE1B6741F658E427,C37E270B39627F3D,625A784ABE53B2A1,6569C2962762ED61,54CA9F65B258E219,CC409C1EC35B2CB4,0000000058C4E053,16F5C4B3EC51F74C,5F517E46B6268816,346E52570E47022D,C15D01D83C297F81,AE3342833A1F2D5D,9937CEF72535A786,BDE4F54C82E4F942,27ECF7AE8AC5A89B,52122697CF793F50,000000014C1FFC97,6B0CEEFFDEAED071,12A2041481BC0695,B59DF70D433ED486,D4EE56BC1FDFFCD2,C9F348F8E8639C00,3AC9C3B0B59595A6,ECEA1455C097E136,E3EB5F42E5973109,8CDC76360D3902EC,00000001A6DC3EC1,B1399CF28A701075,A0F538F511BE7BCB,68B0D70D9FEE5289,4FBFC010AB3BC90E,E32B3305E752C0F3,AB6C523B5413272D,0425525E0DAD7360,0DF09AD34E1ECBEF,20C526C5964FF5AA,0000000213A6D65B,4052F67E7A3A4056,0A92A7AABE7C06B1,2AE0661EB8C5F160,9836EC2087095CD2,26C1BC61A86205D1,7BE3B1FC3BC27104,94F49D301BCEB630,0D5C1B690EA4DBAD,FD193DD0506006F0,0000000277A08A36,2B1D6241328EA686,B6BFA7CEC6AE21E9,1FF2B4B0172F4F2A,6C00729156A03859,7FD6651A6808826C,3C60B9B4C48C4762,EA5027A51F94A8CA,A6A238F59406B693,95D0C415537FEC6B,00000000E88CEE10,662939D5C87AA86C,EF4B7A5CA9F03E35,4CCEFB06E28E4370,AF56BEE3738322C1,665B86816BF2776A,C99CC3797ABBE03A,4470A2C002D69F92,30FA883C91C6793B,0DA5AADE80F5BA04,000000000180C0C0,1F2AA18099591009,806C7D993B02ACAF,D37EBD92BD6085E6,16DD7888FA91CDED,19F3BE98BB441E10,9AC7AD9DE76A7AB0,CFB666AD6031FECA,AB1E4DC342D97D14,EE905D56AC82F96F,000000025E480FCB,DB88CE5DB479BFE7,7B3E43987174FF78,4F1B1BDF8A5AEB19,059574EAA69F4D40,022A845264BFC2BD,374B35DDC261459A,0CB86DC3E4AB161D,F0447E05D824F1E0,5E0488B5214C7B48,000000018CA67852,BAC263162DCC1CAD,1E403818D991DC63,CE1FC63D509B73A0,0EE7B09F364E89FD,FAEF34114323C946,DAC8D0C5C0293AA1,ED7AC1EFFA4C67C9,7659DB2BBC649ED9,5CB5C4F88AE74349,0000000002F1280F,033C59F7126AC75E,1EC9B2B10299650C,008B2C8BFBBCD40E,D3F2F15B138FDF80,16188247D298B7D2,F8119826B5BF4056,3893124BC358FE19,82340E5DE944A228,0D3EBDFC84A7847D,0000000075F9F108,9562DAFFFDE19F23,EFE6D7ECB53E3F8F,CF94DB09FDF320AD,B6B609864AB062A3,4B0B4AD1E98A691B,FB5AAE8827E8E281,F46A170EC7164997,517E077A63829CC4,3E65B80E9F2C5C2E,0000000132C64466,646E956973D84F02,0BBDD8E56A83F158,61BC22467E0BB225,E28A9FA96BED2452,D5B1602F02D2953C,A9089B73EC2BA3F0,9652D1821CECCA81,551BCFF735603F02,01F178072564D085,000000016D6B9EC7,49B36BBC20C11BFE,FAC086160881233E,4A7CFDA9F9C9949C,D4C3151148096761,9CC765FE908BEAE4,F27B7D8D3F4BF6FB,6A9B15DE6424C336,0489F6CA5F898A15,E1DDCFE11E3E9097,00000001F5609ED4,FC61E04EB7DF45E6,ED7FC353A3722033,A8AD56CF81682824,AE12E77FF486FA48,C50337A8C6E87BB6,1EFEC7181C02B25C,0489E9CBB4AFEA09,F9A73EBBFC6745E6,59B89F64AE872BAB,000000008A3C5EB8,D5925B46CEAE6EAE,087489FFA9C4681E,38DE35091A05779C,363FC842073F988C,1404260007E51749,82AC07B861FBF3AD,4976B781E3A7D751,E350692411F8575F,B16D3B515E6FEC37,00000001D6FEF224,3AC008BFE2E848A0,CFBA2CF7AF295525,FA3D091D5C2CAE48,5041EF955AB96175,8BC670EA7336B36A,1FF81EED836EEC7E,59EDE8C4A8B30D15,CE9DB3AE0B6FD530,77381649C14C8BB7,0000000133C56590,6E08B3CDC6115F35,DF4E5AAB3BE46703,B055C2E393A07A9F,BDE05BB20E1102C8,23D7762B7389CAF1,B41268EBE9BAFF67,3763D3E4922D9EAC,1A2F69C32D30154C,B2B8F0E03CDF9610,00000001AA64690A,22A31590E142DBF8,BB3A8FBDCB096FC8,3DB192414E262DA5,64E7DB1FAE8A7B38,19B983BA8528350D,B3B1CD692722FB96,3F43546821753844,71EA5FC472CC4B44,BC2F7BFF74CA85B3,00000001DD3AF0DA,8D433E4CF27467A4,08039D5AD6D60529,C368D83AB5086365,D309308609EF090C,593CB466800AB588,D9EE51C958F77CC4,14C8589B435AC99A,5B2AB2E6592048BC,FD59A42DA1FB2102,00000001B8515313,F0EF8A6B855419CC,D95FC47F98FEEFEE,6BC13B42A53614A3,F039B9D819705EA5,575F431E4A5274CE,7F35B72EB2E7C131,ACDBB51A918CF8D9,32E87B68DAA75643,EFDF1E10C30F5165,000000026F0643EE,2A803041852D6637,79FE50D71C71FD15,C4DFB3176124F25B,B035565CB3736E17,AA0953D53C41FB73,312D77D27B5C65F0,33D3BB8E06454D9E,CE37D4AD00CC6B51,456066B85F9C0C3E,0000000224FAD31B,76D89D7EAA9F9227,FBAC25461ED53844,D158F427F65A5294,634D286B15E294EB,89ABC911CD627C70,1BDD59828BE1C125,A34D84FF5A656120,FD1EE0DE8A019812,A781562F9511496B,000000017C653DA9,22DBF22B252C8059,9CD5786824FACA2E,009AC7D21F12C9CA,749DAB216FC9A9B3,6EB67EAECD27A28A,9CEC5AF61BA6E318,6DAA374CED185755,BB07E4B9D9B6C1B0,DE745BBC36F30334,00000000280E141F,929260E9262BF3AD,54AD4F96448CA2D2,7888BFAF272B41B4,AADA56CF22827C03,8FFCD8B4341C0CE9,A9C7BFB1ED3E825F,C6486C59472E25DC,E44F1A9572016BCC,07AB58E679349D07,0000000172FF5022,663A0CFB5EFCF160,D3E332AFDEA48A34,DFD25F9790F8D043,84D138F90DBE2048,31DB6CB26CAA57CA,3962913CCEA0C310,70CD2ED95E2AB233,A801D435F078C48B,6E2DA8F1A2E6C160,0000000068A86559,8722275F80D78DB9,FBC60958AE183297,8151C112B39A905A,7B318B7BF3CC7ACA,EAF78992F205619B,03C4F34576E3B0A6,037C787EE627F031,4454720F9FDB96F7,45CBA8256E3F7BE9,00000001A431E66B,8C765D208F64F6DD,F181AC09F4A38F40,5EDC7A2053764374,A76353B4EBEAAEA2,3D3439A1AE071348,1FD01895B4C3BC17,5BBF508470EA7EEA,7BF983DCF044FABC,FCD8D916051382B5,000000019F8D4DD8,17949D904796D2EA,ECAB4BEB751911C8,4F6B6BBE0BAD03A3,F40E9BB9FC17C876,53194E20E74CEB61,F12336816DA976A2,35B63EFEC98E1757,AF65069ABD8ACEB4,D9A772EC6593BB2D,00000002381F96DD,99E96BC9243E8285,D5EF86E3AC447C1E,CEF6AE926FA566E7,FD12DE81EDF722FE,A676C533D23AC1F8,E8C5F94D3768DEC5,3C1B0EB432C486D6,54B232FE05D5697D,AA1CE8D9CE1C79C3,000000022CD813D7,A25287F60E6C4F73,DA0AD137ADB965E4,E9FB3A4088A24C88,E17B742698E47B49,E284356D7ABF25DB,209A416EA6FA9C14,5AF28E14F933760A,27035BF054149145,37AB23F7EB3236E4,00000000CA68EA93,34A421DA9BD343C5,CA087A29EF025BBF,63D160BC75D2EA7E,8767793098B7EBDE,5AEEBB0DE8B76B18,5960631150E64031,626591C6BB4A3A73,99C417C7C21C883D,12297CE4A49EAB00,000000011274DCDB,B441D202D13AC957,1AC9C9D1F95C720F,1FA9F0FA26DFB22E,352A8CA3A854D21F,DBB429FE1BA1193F,49A76E320C7F0A12,2F2D5DA5E9BAC8AB,CE0C0BE94D036FBD,F92B30600729D516,0000000162F33C41,31847E4637A3EB31,413C113B9AB2A763,3B537DF612375388,453E25386650B08D,053248B634365525,1C4C7C757B41803A,1316244962A1A971,58EF9174C95A5AAC,17804233FBFB1CA7,000000006BF60FCA,CB5DE9B76AADB0D3,CFAEC37AD02991C7,304FCE5E371F5BAC,E6737B3642459339,DC4A5B93E4D1CE35,F8AED15961B4B052,ED98FA4EC828C531,A711E1C47627432A,69939CE55E1720AA,000000003445BE51,D527B512E5325793,F72BA593BF91F634,783EF6966A36B970,AE0DEB77CC138D2C,B66F10C63E2E0E2A,8544CD348413D6B7,AFB70A3BECD6A6EE,E8E91A57B3F4A25E,FBC81F47393F8F60,000000002A24485E,72DA6D96F4BE397A,7BE40D131BD049A1,E86E3921C412777D,5F59D5EA69291005,CB8F695566D2D800,8AA32932317142A4,60C659615451DABA,F4673D628F6CA9B3,3867D11F05269A0C,000000006809120D,A06A255BF22D8A13,E5A86F9B400DD239,204E8C6226902504,C67D4F1C45944204,293E8EB8DB073E38,193BFCBC3D8B7C3A,3E70437F4A33DE45,AA2D3AB9BA4534C4,C18643D831E6769C,0000000064AC79D9,95F6939EE96C20D1,C771AFE08939753A,FEB2B576F9CFBF76,6BED3516A759F7C8,B1D3D970FD41384B,A5A823863EFDC372,257BF3D8FF9AD442,FC3401805B9A7AC8,1EB94CC4CCECC9BB,000000012A9B5B35,40F54610C7398418,CA2ED0C0BECD008E,0AFA33433A2E5422,8213A5F674F52D2E,31DD26BEE48F2894,B461770DE1C8D062,3A85007AA1F52010,9E97A5559D82BBD9,FD5CDB1DB096717E,0000000078EC307E,DA44A0ED664CAE8C,0FFA38DD667F202C,0A13A09776019932,BDB34DE5BF93EBC1,BF104B48AD3655AF,D2A908EF776DD111,A05A85E690D11EC7,E1A1AFD93CBEF40D,12F6B51D8D766D4B,000000010F75C3B4,68E173D814469D42,D6EB52F467F00031,922EE5B92E0090AE,E9AB001D9E607EF2,A2E910F438063FB0,63D2D637C7A2AE50,3CE16FFC6465709C,0AFD9B14984F941B,D9AB811DBAF6E55E,000000013997BDE8,124FD3092AA8D9EE,AA54DFC78A294E3E,7D98EDDF2513BD05,16ECF793DED73C62,92227C793649D13A,BE5085F970FD1E12,640124CD726B2701,9312165857958C3A,B5150CEB63055414,00000000F63FB67D,67691BF468561FAD,994FAD57CB7E5CF2,E7A5646BB1CC09D9,7F3DE20722E6BEDA,9214817BD92C3643,D0911BA2E5A0C4C8,16E455B34C92DE53,C6125461BB8A9AB1,C87E5BC9C35D7F10,0000000056C6F718,ABC2ABC31C567896,AD43336A6E06710B,455D715B621414BA,DFAA5D2FCEC9A72D,E7DBB6FC2CB154C7,B5436594BDA68F80,A946C3D723F143B8,9729C25EEFE24AC9,B06439F839A65506,0000000012F7CEE4,FC43EA9C2CED4423,1E5593EF29D3222E,7085AD5571752CE1,F8BAF9325AFCD86E,68DB8AECBF61F13F,EF7C65E267F9BD7C,2A5E811E4E6F35B9,B6EE9C7545973D57,29588136B89F2102,000000013A1D7E8C,80DDD5E9D69293D5,CC47819A47EDBC2A,CA6F2FFE54112E93,6A4CFC62074F7D12,EC230CD54A1A33F9,969048092BE2645D,C1FD5F4468250B6C,DC7DC08676609FB1,2585AAB16C8BE10E,00000000397EDBF0,0E41A3B33BACF699,ABF6E8F387DCF09D,21F6B884D7C6221E,886E78937B1006CA,F6F632D668F07659,4B0F82484CE7E89B,CF021EC76EC405E3,5FCBAC6556ED1015,9B476BD552B78765,000000025B30C2E5,AA4A000C544DF7DE,1445A2036F8818E0,2F88B94238499F78,0E7CC72BC5F8747D,3F69CC1A9416776F,75B920F6AC701E03,C87AF4748AFF849E,5FD25094D8256B93,DEA1A67590F1A124,00000000FAA05C60,AB240A692B986E29,0D9F5E19F97EEE3C,8BA56154A1641316,3F8F9D9A44AB23CB,ED0EE4F6112C3BAF,E47A8FED4101AD29,2396C6C03FC6BAA5,D11E63A1181F4585,43C7BDC6339596DB,0000000237E9E076,AD359C6ECB220CF8,698241E500C17ADE,C468EC54B0376B06,ECD60CA2F06A4C6E,0BD5E61F01048DAE,CF8C16E95161B095,051C88625E799838,A6C4A5E821ADBD90,39AE89B8991BBC90,00000000B80672A2,23D793F92B6AF9D9,FBC0CFDEF924D921,71D5FB7963EAE708,EBFBFFA9304ACE95,5BB754F6E828A604,4382808224EBF0AC,7575D51F9E4BF530,49554FE4EC239FA9,78BEB2D10F233414,0000000159065A08,C2EA7E7DCE82CC1E,1C0FB6C634958DE1,FCA63146FA476C73,554D12A240C760E6,515199C04A5C1546,415C7A253EA101DB,1C5F8CF6DC07A320,FF5C4ABA4BB1772A,DF73ED572745B95D,00000001A1DD19E3,0B7C4A23B4D4A3A5,C99E4F635B90B5EA,F053BE8C808E360B,19394BA7A02E98D3,B0D9C50BF3F49BCB,738D69C7AF1BC8C0,BF4D0162A584FCB4,99840E3A156B36A3,E5B4479D0143BD0D,000000024F9B45AD,F69660A034260C20,8AC8C3533465A59D,16113E56BAF5DFC9,F70DFD3B2298F5E3,06D38DD7A10EB7C4,DA45EDACC530784F,697572F2F04DB034,7995BEA6D5C035BD,19A2893C3AD85AC8,00000000D1C1E818,1978DB161283364D,1046B4FF431A88A0,808E6133ED2F86CD,94916D4C4AA0BD0F,A2A0E9044D8E196F,545D7D0BBBCD4A69,F249A33A882CC8FC,2276F405CB478D17,96396D59A58BCB15,000000027256DDB0,4536A6C2C5172C76,514A3CD04A5EB77D,D36E1AABFFAA1CBD,3C9307E64762C3D3,D95D14E198FB71FD,294A69F0EAD142C2,E06396AFFD247317,41D94A6A875892DC,F73AA62C7DD45FA2,00000001937C9209,CB24F1DAA6BEB991,434872FC39EA9992,0FAE9CBB1334AD8E,8E74E4EB82DE63AA,6212D6791985C6BB,10341F4FDE974687,B89AED77B04E24D0,A7969915D29EE850,E060EC8D9D6ACEB3,000000021C50D60F,7C35FC2BCD6FD3C7,4C3A608D8784F9B0,A3DEE3B28BB395A7,B93A3936DB30E7E0,F56D4310E5AC9094,2EF7FC2DAE1943F2,1264A1CCB2D5FEFC,18B26ECB12665E66,B1F5DDE35D99D2DB,00000000A8812A46,544901229FE9161F,F0805F40DE06A52A,C4765F9BD9901670,2CB95128B92BE2A7,F3AD29095A50D24B,E6EDA7D25EF1D253,C375849644A271A8,F1D9148C6428CD90,0EE5CEFE53406036,0000000160B8420E,08A4CA1A5850827B,7DE4F1566B556FA0,212693CB884208CA,6C793BE8D078F782,F0355F6BA9D872B2,9CD550094B09F486,1D67ABFF79BBDD74,1DEEC896C2FED7A2,934A35D3096B10BB,0000000274A48596,3BC71EE63ECF0945,271131E5850A3C7F,131CC0F9CA92B0B2,79420ED2CEFD5BCF,97DE607DFF39C895,D849F34B8F0F8ADF,F2F2FC8F68BC13E0,9978659755EFF7F6,FAC0E6F712B9B904,00000001DDF9F30A,4F3421A062E9BFFE,7FFA17EE2D6F5476,BE6B267F4EFF9BA3,7FBB22DC9C5E4590,0AB433291B364DDA,6073092791E0CE7C,E288FA507C68EA60,BC255B920961BD69,9F11AD0E2800486A,00000000F8FF32F3,5A84EC87642A15E6,01C49051B32E665F,8FC7C347AC62DFFA,EA8EBF5EF8749A97,C2C9E4E10E48231A,AB540B6717CEFCA6,4B50E94F5581515D,6DCD23F28029EC50,DF2693BF5D1D1C06,000000023C3A5B21,9CF7E265CFB1D6E2,E71B8C622B704ABA,250FB0FD32B791B8,FA05CB6C1EAEB6CF,6E37D0BCBB149A7C,94FDCFE855291908,1D5C2190B45DE7FB,E97513925BF97AA9,F316A9C51F1741BE,00000000DAF266A4,D65E3798BDABD464,658E034FA5F8C426,8ADC285B42E6B3D0,3251CDA5430556BF,CE949C942BB43456,D30758EF561AC825,9D1CDDCFC9EAD298,32EC47AD542389BA,A661A6B992642E24,000000010DF86F4C,0A9E51032AF751D1,0ED7DD8036D43D4D,87D28EAD3EEE37E0,9543BC9EFEB2389D,5EF4B4EAFDAD401D,CE1767465E551081,ADEB4C22AE0F2A5E,100C3B540C932F1A,4510EA23E9246166,0000000106FB6ED9,B6DBCE6EF13E8F62,9E186F41A2BA6BB2,420D16EA1901DAD1,49A83D2894B5E33C,928323511B82616C,A9178332106A7A58,C5C91A4D44F581FE,26CA2FEB191BA57A,D7BF2A61AEDC768C,000000006A4DB2EB,D7246F0FBDE5E91C,25135D20FA60E06F,901D663C907080C2,6C5F455A3EF41190,5C038C54B5EADF0F,D7C9412FEEDEE88D,EDE402F569F3942F,AF9DDC96FDDBCC27,5F50B609C5624A8C,000000004F8B80C9,34BC9E94334BCFBC,3DABBCE4038B50C5,927907B6FA8DA7E2,03D9382702EE5B96,ACDE22BD84BC70D3,64C2C250A6C9415C,BE3D75F5B784EA1E,41BEC1BAF6AB7B39,84A740F29312F66B,000000024CE10CF3,7E87FA87756AC1E2,7884536648194A2C,C81E01E1F41D9539,94792697C9FE36CD,5493DFCDE7E8FDF3,D8AD2C49F931DB11,6229A9835437CD72,43D378B674EC9DD6,59020DE5971E0F10,000000015F04AD71,86D5BB532A131B32,E31C1647045E2C10,704D55079CBD31CA,E05E1E1A0904544E,1B72CE04CFF18E0C,0F9EFC6FE84D61D2,691E9E59F2F450EB,9B44E4AEB59A5C5B,2F5D1FBAD28DB210,000000006CD87B6C,9F962A3386154F12,1344631F7E45A975,13524E713F4CDC5E,F4079D6EA4A6E4BE,0B1E24B25AD2D3E3,D9A094FBD7CE48E0,F4507427BEAF63A1,C18EAD4B3E4CE947,CA630EF08269FFD1,00000000C3FF40CF,59C22105D42BFA2F,669EA5998D350CCC,B7F2E99E7B8B1E42,BF27A4AF3C6E0C57,F101D6FC6450617F,898A05A8B2506910,D53F18F59BD99537,DD7C22B0E4917AD2,CB2639455F4C637C,000000026A2FFCB9,7FC18DB6D39DAC85,7B4714BEB59C6322,A09254BB8B1390D2,B681C652452E78AB,03B976C33E72B630,8166E8732A718D6F,02267C5B0CBA9276,570D9447B0F4A1E4,A3C4FD2873372704,0000000158008D70,30E27090A2308C20,376CE45DDD606F09,B7AE473D88E0B7C8,D005658634455E1C,4A7FEF4FF284C09C,ACD6B7F562B7650C,57498295FDF39A83,DB1ECC081090D90B,EDEE107F73D5728A,000000023B856DBB,84523BD8AC2C66A5,E3E177DA83F022B8,5D01C01024987397,97482FF3BC853481,D615A0B7D2C385DC,9A820EB08A5FD961,2C908CA978A4E3DE,4D2E693CF2BFB33E,8BE84359145D2DB9,0000000190306760,93AAABEED8754D89,AA7F979CB968E7F6,1D464F7EAACCD0B6,4533C3B2FC46581A,72460742811D2389,E33133E4E83C0EB6,F179ACE593A8B4EF,2DA31E83375136D1,ED53A01D3E585DA9,000000010D4F93D0,28F9F1E4E340944D,F1B584C30670D230,177830783636C5C4,8A78BF657A1A4531,E072648DB2DE7C39,44EB4422A92E3EA5,2070BA7C63B4D2B2,734BF7EE6A4EBE9E,15D94C3388E66CEB,00000000F402D480,D92441F269A90A5F,95A773C4458C978A,4DD625EFC354214B,0253190397F9E353,728285FC0511B868,14C736BF2B00B7A9,082BB9B4F300D6D6,E615D9C2498B51C3,B94E3BF07DDA6235,00000001D4FAE3C5,53068B76A9477476,6B4FEE4158054052,9BA7B740F31775BD,E9650946B239294A,D03F374157E64E6E,7205002F0753179D,B8454CE931CDE513,7ACB0C6E4570055D,A33F115ED20390F5,0000000053604346,8959B02047585FD3,AAC3C222012794C1,62B72F2BB4C0B859,47348B56C64795AC,2F4A97E27E63BF00,1DDA3296B8833D1A,749011B3CE121EA8,46293E7FEC3DD734,B1D1E1C15FD43D97,00000000D9B6E326,D23A52D88E438DE0,166942414666AB0B,01ADD8AD467A1EFB,3E6BBC93BC357A1C,90F734F499906425,F199799B75EA606D,297873D69D5AD6EC,24BA3FC01A8319C3,183FAEC5A039CC8D,00000001CA6168D3,FC7E1AFD0E9BF737,E441EF9248A153A6,771249D07B3D7A40,FF871F0BC997BD34,34CD9445E3D9D257,60E303C021A9B0BE,4FAB589EEE3383E0,3B27AEF6CF52263E,8CADC59A8200CC5C,0000000144AE8CFA,BA92DF180FA202BF,E142A9D2F83B09CB,5FADD20156184E4D,A8F9831B86B40875,1CE9EBAAE2DC1D19,0CA8DE87CB86E2EA,EA83DBCB77103520,5EB9D24BE47BD0D3,8F4D13828E6B188B,0000000069FA75A6,03D2CE05B7FD2A32,6FB9E7EA6432DB59,B1FFFE8A54BB5A48,669701AE2E9694A7,C20F5C28D1E12CA3,3606947FCF818687,671E118F2B318F4A,114AB4A12BC1ECEB,E7C372653D30A149,00000000BD91B660,1F6A08C20C5F0185,562E91C2F4BFBFC5,4A55561C20ECD7A1,86244B307615AC11,CC38A78FF575E8B9,BC1C9ECC949EE60F,9A4E953E0A913820,37494172B3184BC2,CE34BEFCBB2E875A,00000001774DDA2F,F8B41BB7EB798BB8,D712DBCB3586CB23,68BF6EF6E65CF9AA,B0747DB461385BBD,8E87255A167B184A,9880C5917D9CF1DE,80E11B2DBF33B2C5,E3113CEDAFFA9994,442D3CE19C9B624A,00000000B7D10875,BCD101164CD6226C,A47103FFA5329A9C,4823EB0E4A8A643C,A0CF0603DADA8D72,55F75F72BF56E15C,63F9895AB42C78E9,CFD1F00B7428C0D2,3E2207CB81371453,3705957DA464A0BA,00000001736881BF,82AF9F61A2FE6614,E3B9F6EE6659500F,1DD0025F2F9C50E7,66FAFD01B7A7B3F9,67F057207184F54B,6FCE0BC2D036C6A3,45C63F508181B4C7,01E3B749599AFC57,E2B6AC5083122D61,000000000CBBB744,6307E7D0E796F769,5038FDFA0E31A032,FB6D44EA445A4003,51DB780B192252FB,D8389F04FF188E40,63C5CC6287F310F9,4CD3DB79F4A887E1,37D0F7D660E3520A,F75057FE6E3C0DDF,0000000131FAB8C4,50EC3F606C70C6B9,3FDA45832E6F25B8,A412944C999AA85B,32892ABA72053FE2,16DC6E00AD55B9E7,A3FED22D97A2EC22,70351EAFC5CAE69B,200F7C77A4A4207C,E0C9675BB7B4B7FE,000000016EA5D138,F09105DAF0741294,D51D274D85FF45A6,8EC6051482CF5599,EF9114754D1AD2DC,6E2A1100F0FB38B2,3FC42FAFC0F4E109,C09D41500C1B79FB,EA129A01B00688EA,3C537ECA8D997815,0000000184976881,43F368F78D15FA27,5E63AEACCE376E71,B1B768C58FDD73CD,B15B3523E93445BD,3BDF5F5B830AB9E2,E3A2EC0CE69B9749,77CA5DAF779B46F7,9E60E34643283067,7169596598F7259F,00000000C14851BD,42CDB44860F6D7D1,043777FFD4653099,C3ED068422034A53,F94C0B532C02EBAE,183AC8D214B6BDA2,99AC60B3CA289D63,CD3919E6D9702E13,FF58671F2179D281,EFCA8EE8FE31795A,00000001E51BC196,909173CD60FA6D35,4B07284AE7B2A956,CE326133B6E75CAD,E790525A09A7DB12,C78DE5E2D6DBF57B,E295E282E5BF82B7,DD44F6829E7DEC04,36F2BE9D65A77686,FD9DABCE0C9D5362,0000000215351C46,AC6481D2AFA8A922,F51C94082C1B8A00,46ADC3AD14E286A8,A39561C46E5C5641,26863A6198A0DF43,FD2D49C2F3CF9770,D64E5A914D794BFC,21D178E1E0BF3775,0FFE6348E8E21323,00000001ABECC030,50A8B51E876464DC,CF3A718EECC216C6,61395ED9B7489AEC,3E23759D96A7DE65,2E1BB6F47B0C4FA6,79E92B446E8D8C31,B10AFC66BECD214B,46657E21B8A4EE16,2D1942D078B9FE1F,000000008DBBDF78,0EEB29C9042CA8D4,8C20C9B9DEA240AA,4ADF5673C06561BB,373DAD2AEB8491F7,C30DE76AFAFBFF48,462B9785289DD410,06D7B85611C0A093,EF2BA077DF2AFEDA,033562DABA5A9E93,000000023EF1D0AB,4268529C0D242801,256511F16097A1E5,E00A30317C9FEBCE,ADCD5759F88F72F8,ED56AF590C689B98,3CEEDDD9D41A9765,5D1F528E12759A6D,2FD7BE541E06093B,16C61528B234B531,0000000148430F18,D05FFE9F0C182DBE,8B6A064ADCD99574,481AF741DFD2F9F6,4038E560000CC4F5,45CBC355E90E75F2,42F6B06DED012A4E,3C78AF6B58E4ADBB,3803619CF9ED5145,8BA88D1FF83592E8,0000000009337E4C,37824EF55ED6FBB7,CD9890FD578FC872,B218859BF0F30197,9113E18064FC494A,8C2D462B9D910FEC,AC89C7A15CC2F789,2AC44D32D08BE367,1D948B4A6BBE9FA7,60DAA3DC05672C33,00000000B93F784A,D4B3282C0EFAF522,39069D0B9768D56D,25CF3CD0CE57A807,598442EE88F63D10,95BF9437E3C7B391,90919F615EDAEADA,5C4C96642A77D102,30A3D1D983EF659D,9865EDE7074E776C,00000000FFA01406,140C1A3DCA05D682,04AD498A17AA24B1,2201B8E7C61140EF,4525E203C8E9031A,49FC213890390E7A,71AA01C7AC92C45E,F211216134553A36,6DBDD3426494ADB7,7ACCAF0FD86CC29E,00000000945FAA9D,9309AF06F8103302,90A6B9207E90E46A,D5D177ACED561DB5,295D6469A5B3AFAD,2BEF6DCF2CF8603E,4258185E23D866B4,4B0D083EAFB06043,CBF2C02D7C25F30C,1653E1BB1D58B43B,000000025629683E,0BBA1FCE82915666,5DA2E8AE7581B451,CDD9159A7DD7D76D,B920A589AE67EFA2,61EE2D7DE8147EEF,A0BFCEEB9BA76E43,F4F24D633FC8C60D,3C345FC57295C737,C8F1DDCAA93A8808,000000019E14303C,EE195B4883FE875F,00EC0430B5B303C9,CD8C1BCA0DF1DEF9,86B55B0EADCD8C4D,00C930E739E25F27,9E8061FA4BB0048C,74FC0EC3ADA3C1BE,CE1F4728DEA7DDEC,52CB3B1966E6B667,0000000088CB2FE7,879198AF8E93DC1B,54ECC79094AFF84B,C83A1DCAC1A3EC7D,D11BFDAF908564DF,6F27069606B4D21D,237968881D7C47EF,69AB1B6ED6F92EE9,E1F793E47F57D372,D04B57F6A6B5F66D,00000001F5FE9407,3747A49CB528EE49,B9B151A24B5A75C0,54CB2AFD0530037D,A890B2283F465175,451C5B2D84384FF5,8839AD15EE639931,F965E1CB2B12D2E7,134316EDB96CD7F8,69E3487441CAAF3C,00000001399B5047,59B363ED7AEB2650,71A6AF6B3AD28143,92058D6B95879658,D3B4B4FBA0AE78CA,196DAF356C002C66,6E75CD88B8D81D40,2700BD310554DBBE,DA535AB23B6C0ADC,A4E7980919CA95AF,00000001DBC0B5B8,3DD669012D639276,F2E083F1C69322F5,E91DF50EF0931B15,D1E89702D91B824B,F90940CC4BE0B98C,B2B313F26DF19008,497E3142D4270999,E629FD5FC812A188,31DF294651544FB0,00000000D8011C24,2906E3D8833F695E,775F373A51C90E18,D47A2798B64C9222,22FA3A2B94DF0BEB,8FA66950EF9F9122,5E476D4B3C9972FF,CA5EE43DF9D8C48C,D36B63672F8AE9B4,77C2647DBB340690,0000000073C46163,89AD19EB543DD8FB,727D6A6B9D4ED50D,F3C8CAEFABB3F2AF,0C7519830363D854,3B07E92F238BFBB7,A16BB1F7EC111FC4,257C6588B6F61506,BA2988BA8050D906,61B4EE45D0032979,00000000287E94C3,B6A8361605CEDA40,F77CD9DA61B94AD0,A2974EF304F6D7A7,08958C127F3A033C,729C6C0381F883B2,19FB8F863A136210,E102E4F19ED2CE81,19E35DA3ADBC20F0,E7C1D269466A4D75,000000008533CBC7,A892E43A70661417,AAFA266BBBAE33A7,B51EEE06FC23AC7D,7C5765084730559A,A7ABD9E9332DB969,69C370E3F4588C80,CBB726B017195159,26CC1250542E20AB,C7DB20632AB09C97,000000012B2DF4D0,27986E22DFE467E1,DAAD92ECE6D439FF,30D800FA01CBCD40,01006138291DD5CC,DB13790617187843,951B6BEF4F6FA24C,A593276FC9B169E7,245E71C162FECA76,80AC2CBD328E5AB3,000000008AED32C6,8E734918000C7969,8E4057E2F13FAF0D,03926A8C7D4D40F3,3D86206D7C3A8D7B,609B1413D445B654,A18D2C0FBF7CDCD8,5533514B46852F36,A091E075047A503E,DA9DA3181A07C97C,000000025860797E,ECAFF0B5E01D2469,32CCC6E9F7BCE649,CE100C0E9B3CDFEB,1E8375DC645F0E5D,90D2438168D2DC1C,FD0093833415FAFB,AE12E3529FBF7855,B139FC4C1B9EA8B4,1CBDAC544803A1CB,0000000064F28A56,2620FDFF0CCEC444,96164392D2E8DA78,C2C3BC0E57421B17,3656D5B6B59AB886,B7F6748C23AF0EBC,F4655B5891F28127,402C3AD82F648261,E6704BA02EDDEC54,776E67753DC50D5C,0000000118C40921,AE21B280F909E2FA,B22C8799F5CA6E51,73F8B02126408300,5246FF9AF4F452BC,C1A8160891AC2927,E2FBD4998DF3092F,774070371A384BF5,DA27E907437DF733,54231895E778BA3C,00000000F2829322,EE03736CA9DDE4A9,285B7DC21A64AB3A,33049A60734AB4BF,8DCA64042ACEBC0A,10838E2984D9219D,549AADDFF7464B82,36D4BB7D20D5427D,A28C76837D85F61E,49BED9DD7B98BE3A,00000001977C5CAD,81F7B1750FE78DEC,6EAAC78FD45ADA81,F7F674BA8BF33080,B8854EA4763C6C4A,C3F958211427D553,4BCFD657DDD9AD1F,08C86284D3972493,44933A40D0B908FD,1A68142EE398FCCD,000000025494D05D,9992698D2BB5765D,67C3AD1FFDF857D6,F9C6EBE0E8FEC5AE,2A554D5284F17C1B,928177B00B1E3869,17BBB4762F6132E6,90341B02782B937E,0FC7D41352C3730F,32F73306F97B6AE7,00000000EA17B587,1A71E33264548D1D,897880C826F968BC,AB6BDC7FC0FAC8EB,D3DDDD707924BECC,7883BE8E21F4E59B,DF6C86A5E8A02AF6,5E00B7FEE89B3F54,10CC6460066B39D2,BF4859CD8067B8E0,00000000347C5C54,E16C064C62218246,BC70AE3941C2393A,EB3D1BB2CA802287,C4EB15A5374C70C8,263C46477D9F8C06,D6A3DECF0A950127,AC46705430305F62,4A30F74F493036D2,8CBC3729541C8C88,0000000077A042AE,340483B66020AC02,998DE368694CBBEB,C2C59FA4D9F0538D,4A240E23E2993377,C6191EDC93547AB8,BBC6DAE5966CA91E,A61515B7C81A87B7,E057F11CB617AD08,17A65E380916A1E4,00000001652B3850,C9A21DD8B5500E57,BBBD0DDCEA508191,385C009007FB4173,1D8082EA162A27CA,EBBF017CD8BC0DF6,C1BF127E48D74029,C6BD6E2C1DD5F7F2,1D9DD65A14A8A19F,6B8DBAB014193FD6,00000001BED3DCED,A6148FFDB3E2D5E7,F42D33E81EB99BA1,665E997A672DD01C,F5D879CB5A98DE5D,3D8BACA99A664C0C,D11929CA375D1B70,66C9DA7E857BB785,D5BF1E4D34224245,59A3DBB622B1CA0E,00000001AE72807F,C32259DA8545D4DA,14DF783A05DABFE0,436ED7B3094C2995,A9758E310022B993,DA45ADACE094AF55,2998AFEE04677924,3667F314E8C4B8E8,93305AE3AD9016EA,B1E3F964657F41C1,000000010F051095,2CF25A1FB27252E7,FA3106A4DC711CF0,1FD3E9FD66645CF5,6FDF2D7FDEFC17B4,2BFB16273CDE666A,1D6D4C62497364C3,452DBCF768121E08,8B4411D387183196,4F1239CBD5567FB0,00000001C96619C5,33C6B9853222C189,7ABBE242D65A31EF,013DEAD13D232F68,46749CA33728452E,C805E4BEED3E5BBB,75603329C5F45A3D,BA71C5A31E3482A1,95838E928BF4FBE3,67F9A578A2CC7338,00000001113797D5,7A042A82D04DEBD0,491CE081B68D238A,A54C7863CE9E31A6,AB17898865A991DD,BA59F18DBE14274E,419F1231A0C8C4D3,71B4CBA80DA7AD2D,9619042BE50E225D,15F37ADBA6D9ED70,00000001B65706DC,2D43C5ECEA1644DD,D72D78F65A7A4812,455F8DC901CD34C3,BA873D7850E4832A,D80581D51D654F92,545D636AB882D140,34086E2CF0F7C60D,7B374C07CCDECABC,2777CC53663D88C5,000000020565ACB3,1BB4E63242423663,52EC37A1C65543BB,94E3D3299003CF9D,E414DDB3709C3BD2,79D146FABC04BDAA,F7B0BF663E5C6A09,8A489EBD72C4D4E1,CCAFF529231C3504,FEAAE7C53C4DC89F,000000009DCF7212,D85CAC1C4D1770EE,1A2FCF99BBF87505,BE6C6688807378CE,489ABC3587037187,65092F76466829AD,CFAA77C7CDC4EEAF,1147A6696AEC98F1,28F15EF561D127DD,DDE4B44124F1F54A,00000002788D2DFB,9C67B17881695057,129B911B4770A189,653C53F8041ACEA1,B74D6466FD398E56,48179FCA2A4FB2DE,F077F1D80E5DDE22,DA21C5E4C34B279E,F8C39C86C12B16C7,8B4C371A0B738680,00000001C31A94AC,B229ACE324825A39,8CE060A184238EE2,F8207A809754A409,8CEFB7715C5CFF2C,C6D48380F9AF378B,77ED9FB783ACFF7E,A08A6C4DD932AC00,A444E16643EC5B3F,AF9D94E9C7C2728E,00000001396AC386,30DD47FAF13C7B52,74256174FDE85324,63A81D40E5694706,8CDE17666589CA76,E9AD6F723218E558,F4909CA83F13C7D2,BE160DB1A3A0286A,1ACCBECC4A9D6F85,91BD2D8705535166,000000013AB79976,AEDE0F3354D39A2E,C2F3755D2D961E91,120C1597A21E9FD2,BEE9D915D11493D4,72B193CCC0DC3604,C7DE6A74068E0D96,435D9F8016ECE21C,EF1E2FA18C6159EC,0C3712CC3A8F788D,0000000053E621EA,2CEB4E91DD1568DC,DF12D0117D199445,12204F2F325268D5,E51AC729354F70D4,1799C89583A5C0D9,C1B3A83CF7048755,FB2B5CC41F13C723,63073EDCD9A1A9F8,A27FE3BD8E7FEE19,0000000246644ADB,209C90194E31D5A0,1293659913839642,4A24F387650B72DD,603244129EB72CC7,6E23DA7972ABA55E,C5B1203191AA850F,3D27D733F862D563,E3DC2FC594718982,9219497E25DA29FC,00000000B6D66391,34A5C486D6CF066D,04AFFBAD4E982B0E,CB2BEAA804260287,ED7BFE05C418C362,ADB98EDAE8E8FF4C,07D2C4174FE83C83,F7F525E7D8628F1F,A6E335E28AF75297,758F6BF501909180,0000000118715A04,5CDE0C597FAEF9E4,0AD2E737D9E4898F,F67377BC6173D4C2,C8957EB2393D0596,806F5EB9C5606C45,12B94FCA7C12535A,32EF1164574205FA,FEDF58443B5BD77D,F8FBEAA86E678895,0000000275DCA4F0,84617EC689E08899,F892F88C89BCB715,E191B7DC3E96E8D8,4A8B0BECDC36817C,CCA38826EDF5F672,7B72A85AD54C70B2,050C77C7B55D551C,460BEFA337306678,4FC44244BAE4E72D,00000001CF7A9443,EF506D4107B4E5DC,61455B6A181ABD17,9E1B9536F3075991,B4C8504739DEDDAC,A37E5C6652FF31B6,AC1B83013CE51980,472F8E0B608C6EF8,4C111ED7DAFF24D7,350D21597B02C40C,000000006D81D3D7,F7115BFE80A02F29,1B938115E7CDC5F1,7B817B028C23F4D2,1F4F4E583F7C605D,67E61389CD5E13B4,F93CC1D05BD1A2DE,F6EBB6DDAE21363B,91152D7200D2C561,CD191796A040E93F,00000001B280D27D,A7E29E2BB7624BF7,6EE44B6B5BE80B00,2345B7E2D5759831,A9550FA4C7F045A9,B7C9B262DE343101,BA646A4A4EB41261,373C37AA5DD415FF,BD64F3B002A1CA3E,EF762C383B95F290,00000001D80DDE2B,984414E0FDD62666,BAE97975D1092432,30D809C8164F601E,66A305CAF53559C4,DD0570165496B761,CFCED119192167E8,C7ABAE981D5DF0B5,2ED64581171BCE3D,1CBB54E68EF4FD0A,00000001C1431A08,8CB048E6A47456D8,F600BE49ED92D4D7,01FC39796769C0A6,6E94307452A9F8BB,740C5C50B9AAE224,BAC8B3C135A2E2F4,E49A28A8135E56F3,F856C805436895E3,F1CEE08B3504CC83,00000000BCF36352,22690A6382DC3BFF,445816DBB2429306,A06A5424CF0CC87C,ECF05BC968148850,38CEC3B2B98FC2E1,968146E8B7BC1385,FA0437F5332F0928,2A9A1E16C2A312BE,2DA68877564A2537,000000023789298E,842877FD1D5E558F,3AF6CBC788B180AB,556CEFEFA2F445C5,ECC2190258204C28,AC244D088A8E5395,F0B2169815B5EB93,31F59377960B541B,8C83D5E2C1AA5437,902527B8DB28DFDF,00000000E5F5EF33,1163FC91A12EC215,98176AFBC2A94563,6C90B8BED481636F,CF4CB67B0FBD26AF,9542F8116F519F85,0DF5F3B7DA1B9EA8,BDD5D475CB4E7508,126214EA0DD00B02,7E9A61060BABDF14,00000000F9D59132,F697AB5F3A1AFC36,BA01D25DF0895130,9E4577DBFD120BFC,24B330632E198D31,E006F9037E5076FC,F7DCE42954239C0C,BF257C341B3F6C0C,E0758BC7F0928DEE,065D24B925FC9E42,000000023EB434CA,612F6A15452B5865,3E2DD7BE238CF9EF,561A3128E5684096,09E924A910CAF364,C5D6F6B235C499BB,24304EFF080F237B,FD9704C46B5EE1D5,7984F214E801D964,8E4FF89DFB3F6D7F,0000000107613980,BC48B10FEE3880D4,21C40850E54A8E94,D46A22DFA5FBCA92,DB75D02EB1089D12,3A9EFAB11D6A422F,DF10592F19BD5D2B,AE2242D9D8D7C255,7ABCD16CA0FDEBAE,4C103A12EF1CA9F0,000000010F789EF4,5F4C1B9A00FA4D6F,86FADA4A6C609178,293DA33CCF44E948,E3495689E5797C14,DD1AA0D9BB186CB1,62CF4CDFB05C8125,A686F2269559741E,4FD73D57B677295B,6ED2BCC888A1E516,0000000251700F64,3109D49625ADED0E,9166834317501E55,FB63E9E4523ECF87,7DCDAD3F69D9AD47,F98140470DF2AA9D,B9CC7825113CF619,447386D68A691CC4,E65262466F669284,4E3C30A1B408EA44,0000000265CE9A41,9A6FBD4A0F897F85,9A36956FA968A4E8,C7F118F406D1E569,81DA29446B93C943,FB109F2A9388BC27,C3607AEEC059CB85,3B0687C0FC754171,BC31BE3B418EF175,1E33CB246AEE1A2B,00000000EF8CB32B,C597D678DCC9F5F0,C076EDBACC713655,28080A8CC9DA5092,89FB0CE392805BC8,FDC33AB0768CC1DD,D5CBFF2C540C9ED7,2B135870102A63BE,7A8B8D2F897490C6,AB3723ADA3C7224C,00000000C8FDB9A2,382BC7DE2594C10C,80DFA5E0F9624256,369E2A1E4FCD8D88,4AE4BFA572727E34,3A51581D249C8CE6,B3FB586FC7C2A97D,BDEF6F1AFE355EC8,DEEC780F30E5FDFB,4810C7DC575A5BE5,00000001332B6685,5A94C35C1126ACEA,55D4754656F53A34,9023C82267CDA27E,DBF981A1DF7F878B,45FA3CA7EF136455,77AE2424151AFE01,AEF2140F713156DF,400CCF897F3055C9,974069C62224BF39,00000001A7C05975,E0161B464CEE604C,142986598AD5EA3E,F1ED822B0D27F30F,2E397DC99F2A8E87,1D2306050F616981,150431E170CC4162,762B72C29A2C3053,A8E3C77E0AAF93C4,C8354980A4D61542,0000000235B5D356,10D456DEBC7E1CC6,AAC202A1D5780273,A58C1366B8F8391A,60D0548ACF70445F,095CDC77330D68DF,A579CB19D301D5DC,240AD4F373368D63,3C8CEEADEADE5097,7A6C87D1B417EAD1,000000023D82AE3D,144D5891742DBCB0,B8F9D9816A8A7F5D,26F7A599D445826B,9E2163D037752635,3863728C2CE4A3BE,F3E1EDF562394E4C,5DEFD017C4CD8493,F17218BE90752561,ABB6C5D92D9CE1ED,00000001160B0B5D,AD3DB07DAA5F6CCF,9CB3ADBEA66F9AD1,D63B738B58240A0A,287AC2012DB45CC7,3289771C64B159C6,BB44D28CDEEDCE3C,5306EEEBF98952F4,F356AD10FAADE198,C9B47ED81D9DCDD0,000000000F48A6A0,C192560DBD9F6025,0417721C97681D04,CF861AEC992E6394,B4A6C0E57F289B7E,EDAF15D2F57619E4,B0DCEF59E1648CCE,22317A41C7F97565,CBBBB6BCB5E5DA6C,96E8EBC183D61EA8,00000001B7739A94,7EC49418B2B810D0,E4D079402DB9C188,8E53C68DB8334241,55756932306062B8,1BCCE7AF5A94E4DB,CFF4DA3DE8B96DA1,2082217EF8033AA1,D0B4E6787E422C72,4CA784F5990EA996,000000009F41429A,6B4FAFCB42C88980,8D11340C4A667ADB,D9D5A354085B876A,A5660CB078BED32F,CAB24070AE97D7A2,9CCA9CBFC163E080,B850452F83EF3105,53F16D8846C746DA,9ECE100E678FCE17,000000002EF8A938,B5674E5D4E6FCB8D,501D5247B2016E87,80E344C0EB79A679,38FD3F3F4C3165FE,CF0A1E46DF3A0A84,09705F9B6728434A,929BAA58BA9B496E,AE64FFCA11497D81,9C5718C214C7E0A3,00000001933F406E,A497FBA372B94C9C,D84FFA0EE19EF506,B7CEA62C743A1A64,2DDBB641DD4EBAF4,2EDB1B581CE376F8,802332DF67DEBC77,5F3CE33E92F89A5A,C6AE56DBE327BC90,EAB857579A8AFAD5,0000000045668F8D,98CAC8EBEBD183E2,0EB52B70C7F5B0D0,5D30A82F658E3952,AB74E682ABA27196,E764FFC3AF467284,E0998E193AA3AF57,564ACBC831F9FB9F,5CFA11865E72FB0C,1E08D757A71B1180,00000000E51B27B6,24403C7EFE866A0E,A9FEF031BC9521C0,74AC1B5B77B6589A,21BA19AF9430BBFB,4826558631727C82,32D60F58A81F2C66,E569D1CA21B6AB03,8CBAF3775432D759,029C201C1F19CE90,000000027B579BC8,F5833C52D9C3D07B,EAEA72B38994B37C,227D247FAD5CB923,4B2ACB220BDE1CEA,538084A34BA8C115,78B8A6159F8B234C,77D8116B8E03E119,B9867671B0AB574D,E4F10801B7079A28,0000000108A0785C,E8241F65CBB0B62F,6C0C08F1C8DC5ECF,F381BE10610B1E5A,492485569A5F9CC0,D310AAA98EE3E6CB,4FF9A0FFB2D3543B,CF5FF7D678585582,B9ABDCFB32F4C19B,5CE845D73012A5B5,00000001B61BABD0,CDA0138E70037BE7,00FA3A34DFC249E0,6DEC14F793F58A69,2EA72A1F4A40A166,2BC5681095E6B3EC,708992A79596958B,46A3B957E1776843,AC3D109F4ADE763D,0FB548C3B316B2E4,00000001E9C3BDE6,0B82AC992A7842EE,2A77FB861461B629,82F9093832DB64C3,7D7971A6CE9E6F2C,75DFCA8B75083F55,F5FF3578C604905E,6F9531596884F24E,BCDE4DB313954080,C64F648A4E561D3A,000000009D333B0D,03495706C3279980,B07BCE27D6C4539A,452A7B8CFF0A41B5,AB13B9885845CCC5,F41449361CE2412D,9A3A892FF6F0F32D,BBE10431A46F054C,54D0EFCFC159A211,5C6AFE1B3D48A5DF,0000000107BF6CC4,635C4D20BBD61B97,BD39816D3985A0F6,F06A85B0425E006C,02D3A9A5828951E4,178E7EBE009D7DBC,B75679B9A6A753C7,308C3CEE647023C4,C025F2046602926F,909A87A7F31188A4,00000000CA0A5913,DDA189A8B28FE40D,305F1EFF2AA3A01C,3FBEBC396130B2EE,F4C5FCE21AD6AC9C,2FD81CF649AF8736,960228D6238FB84D,30F2D964F619EBEB,C32376C61A427371,9E5B2E3666DD218D,000000000567E220,A529C004C94FCB6F,28A34B3085886C22,048026BC33E03318,7B983BC658799EA4,8702236DE3FF8A7B,B736B7E9D93F8EE9,F1EE80D5B9BA52E5,3EEA115D0547186D,E1CB91F2FC7314F1,000000026458098A,8CC18B4AA1F0E11E,A7756977C05766AE,08982F63889713C0,684B64F7179B10FF,2EAE6ECC80289FFE,CEA0E8E9A11440E9,01C354DAF2F11ABB,CA10A7E6C14E3011,A2B168AA12DF804D,000000014902BDC0,D6EED48C0E8CBD74,6C57A6F534D56498,9D57422869E8B7D5,1FE6E83F2E8AC0FA,9F157187217DE1C3,9B366BD921651C25,7378058E94BB27AF,629A7C4111A004D4,00EFAE8C87B446D9,0000000105650F0E,B4CBEE80D41C4A94,64C3B66C5FDDD6E8,732349C73567D592,22A1A87A98486520,CA500C4C7CE3AA75,6589F1E8D903A167,74DD9197BB6E2E68,CB8DBB291CCB5F91,02CC43C747A33A05,00000001AB29C3B0,5C1700B42EB5E766,D64CBB98826C38C5,93DC3E1120ECF852,FA010A77DE56454D,FED9CB95E27F6FE6,CEA43AD737992391,7A75C13EED8F44D4,687AF2B2282E681E,CE95D0CE26068B84,000000015ED182A8,911EBC86EFA4B182,13EB8BC18D63B79A,F5D62C5818B03102,93F58521785312B2,1134151363F4E71E,B59DA9B80A580F92,839543B0BC3F846A,301C7A750941CD20,93AA1E439D385935,00000000A26A81CB,F6F6F79E5C4D6F23,C71BB808A839AB8B,A68C166D7F0FF58B,74544DBDAAB637EF,9D1C17CD70C55979,52D39DBD1F9017DE,E819965097A56CF6,904C814F5720FC1A,4CF550FCA750D703,0000000063386A4D,E0D291865FD46DAE,84AF7A4B08E66397,B3AEEB3E3E174333,2A50B7BFC269D55D,4C27F0E5A5B187A4,A1A301CD84987BC4,8D02D38424F68A6A,6087B6E8F402C002,61C98682E00114F8,000000009853C2E1,6F5A7643A4D20617,0701E0179AE07AA8,025AA049CD13DC9B,34862B5A04D0B8A0,43F17B8C49684883,38680EC075C8E9D6,E37BDC37AAD0610F,4C66A7DCB2E7D694,F4F735775463A518,0000000008B47D8D,82CC2E677FC943C3,73D36B7AADF63555,78E35A53895FC845,CFCA26A239DC0927,1AF6401B5A7AB2A6,1CB605ECE4384446,023F9C669B954131,3B8D6322ECBE7D5C,46466593FDAEA970,00000001A965CA5D,994D71359B9E38BC,F24971584BD95089,122A4320DF9C2FDB,0EBDAA2303C9F9D1,FB843542823E1E34,7B89EE1EA0F7E783,5C6EA18A8672543E,9D45C402DDF4D512,0A799B75DE37245A,00000001DB77D0E2,5432583E2928F3DB,B9CFE6980E35FD20,7D97ABE3178D62E6,1E8FA3937BB7F9FF,4B78507E96834DE8,69A5792882694BC5,D11B8404576CDBE1,26486968BE0E04EE,6702A2190FCE4A9C,00000001971BBDFC,7A367F60C99DCCFD,86ABDF8BAABCBD1A,5B74B008A09F9B1B,7D6C57E03827ED82,A5741D878713A5E0,BE259F2357EC01F9,8BC473F86D686744,BA02FF0C20CC457E,031065AE04311D65,000000009C1E3E2F,C6585A9618D4F1D5,1591E533D1898F38,C6834101E5804D14,DD4F25D1663E4240,F6F9AF98FDA16223,D849B99E42681F99,CE8DB48FB182839E,C63F85FC7E1275EE,1FDBA284BB0239F5,000000019C0AFD12,3A87A293D0488221,5406DC4D4795A48C,D8D50999AAB4191D,7A4E9A9290C8786A,667D01ABFD55E76D,7C5512F921895FE8,FA28690772412ECE,D4C4E73C6F0E502A,69A6AA352F0284F7,00000000BFB176DA,4E56176ED50627E2,D5B4B5E6AA5CE88A,09CB6487CB388AA7,F9CD455FED5B4853,7FA6AA9EED5DD2D0,61E6E7ABDAC02F01,C3F1B00A7B1A315C,A59688949AE707CB,4C850303F964F051,00000000BDC8CAA4,8F5A4AF3EB392709,72131342BB605964,E1653D159FCC01A3,FF4A3B0D9AE26C31,72FD55D5C4E8C034,98335EE20BA1BB81,4ACFD8D497908256,B38979B504915215,6F8154BDE27D7259,00000000E85ABDDC,3F37513ED3B51346,4D811B35261503E0,BFC7ACD3D05A9670,D66268823110B8D0,1313204D2F68DC2D,C3452F661B92FC8D,C845ACE5EF2B6B5A,D411F672C1FC2F22,45CA70525C06AE5E,0000000051160B22,9FD197B9F0486AF5,54CF63E39966CFEE,8A4038AE94C5538D,2758280B32656AF3,F1D8A2FAD6E82A1B,12C67E50B380F69E,A38B7340029957A6,F3330394EE13C318,8BC69D33B9400563,0000000031C9471F,0A3324B621CF6F61,48C8992898581CD8,A6DF40514698743D,F9E8CB974BED106C,EC04C25A7C8C873F,7E14A5B441540487,BC9FCBA6ABA4FD42,25A72ED592660D4A,74733285F0F6C367,00000000B2281CA3,197EA1DE87909231,93C40C24832C23E2,DAD6CBE3E01A26B8,8200D69C03322908,CEF3679077808155,CCA88E754FC65606,2BC7A719EC9D5293,99D4DB748EC044AA,984E0D6FB11FC930,000000001854451F,672031BF27D84760,DC9CC4D514ED582B,87F6EE5C530B41DE,87D6799FA63315C0,AEF22A4062434E1B,ACD4C251E3FF8771,5D3A1318A60E0699,16C3446FE928DE75,35841623F8BB5895,00000002592AAE66,5027042328F18C9A,EDEA5EB8C7D3915A,7E459D006968EFCE,7B6CD5E8A1154212,C8BBF0E12753FEF6,670B09C3518A6A8F,D2ECA2AF0E96AE62,5C5020E31B9993A1,190166DC15AC7213,00000001D39070AE,D1FA3AC9A2FD056F,25C0E7E5A95F6460,5EE1E39F858C52F8,D5B347176F965AEA,7A92E6DB9E422DD6,F23249A24ABE7C41,3D042EDF8B6EB375,98CB039AC7844DC6,E4CCBAC9AED646B6,0000000219EA7D77,C1FDCB3BEF1B5F34,4C4ACBAAB810498C,1EAF4EB012972590,763B078F4A0D964B,59937FFECA8E05F1,86D16BC880D88091,7003B234248E6127,8DFF4DDB2A12C038,0C1AC98DB7415EDD,0000000037096C55,673DDA9856B11D71,DD19C50A5FC2F109,4BC9CD6CEA97108F,3BA37F5A238DB89D,C341DC27C525B7A1,ECC8B6023F72D4A2,A835DDE777468F08,234E9AEEF991BF15,FDE2EB1658DCC1BB,000000003F5FC81B,983160518C2F38EC,9B3A38025D69B9E7,CCF5346691486F6F,C2A5FD3796DBC456,364E2305D53C7774,92D32762099725D3,0FF9E66E7F1187AD,E22946BFC1FFD111,64896BF6B4A37BFA,000000019238CD2E,E3334F5298CB16B6,B5239B232083B0C4,E4E676EAF17B4191,92EBD566959E6705,C4ED238A2F345C17,06B43AF026B4829E,0DE2BF14D6B4E91E,A79899BF9FF92105,A66093DE798706D2,00000001A0A9B6E1,6510E4F9377AE0FF,6025621D98BAB957,7F8F7B275D88EB74,FBD0A2253A499847,217A65BAD1FCC9C9,5F1612C5199AB61C,3A5F66B58E99B2EF,BC1E4D38960297AD,F5EA9157F7D8FDB1,000000019C7B7409,3CDA1E2735599401,4A51861FF08EB6A4,3664A29B99080515,D4D9A7EABA8BE029,7BD86CBF133286FE,01294C7EF2DFBC49,AEF69057CE967554,C5E282AD7381381D,689621DF937E1860,0000000066FE4BA0,B778A9E6F78CCE7F,70C9DFF081925487,13C040D19118D14C,5E88BC2646D5A3CF,ABE49B40ECC4F74B,5418A52C4B6E8039,A1873C468233FA59,9C9081005195091F,B3FF57EE539C1D6D,00000000FB413366,5788188059A21FBB,6FA83F9DB74E6302,C441C2ED6CB26CB4,CACECD5A624AD79F,F823CE395CBB9666,A0946C1EC2389729,17E148A6920938D4,6FB342035A2E68DB,11CDFBA68FD2A205,00000001DEFA4686,DCE6F2093CD7ED56,3A79465A52A528F1,3F9EB4CE8D47CF40,0D76304234459048,42E471B7FD5D22FC,B2A526AD743D2B26,60965602A12447CB,46AF2652D1A2A071,899DA72317AE71E5,0000000210792D36,B9565081D17A7493,34775E1DFB47CCF9,C8760AC80C1494B6,084635C72C172EAC,205DB97EE42D0761,365AE8E17A87FBA1,0F18FD262EE4948D,65C6545322CBF6A7,3842E2AA29C7C0DE,00000000FA72D7AE,7E1C4A1CA3334C09,984DBA2E0D08979C,BE2B9E54DDC9907E,DD5B8DCF6DD2E304,1A8215F9D14AD85A,8E14A565EC88B0B0,B3A6E6FEB4BDDDDE,A31EBBFD000BDE4A,DD4D917F6CE9ADA5,00000000FBE61EC5,1DB3EFA204393271,0608C45CEE593E1B,F98B1D1DE2635256,FD1C5CF638D73F2D,16CE0838D939AA35,9EE033BB7FFB80FE,43EAD66F69EA29CE,73401A95D23FEA9C,2C8242EA0363AAC2,00000000EEF98B9F,5FDA0C68896A06A7,10DE1C58B8EBBDFD,1A409BF44EDE5018,FD26C0FCAD9FE774,2CC59774C8EC1F9F,54E037828A6B8757,0C956E594F1B3CBD,07EFB35005C7F66B,FECF300E3B0BE851,000000026AC112EB,7994DCF6336427A9,54A84021169E09DF,AE16DB038F80B6CC,28CDF1C7D6AE594A,C1F2CE166BC886D4,45D5656DA9613564,123F32BF29638C6F,DF3EEAA8B1054BFF,7029BA48744B3C6C,0000000265011531,EC136F6EFFA50089,DC93D8F44BB96E35,524A77CF90F1FCDA,6590A8B4C1703CB2,CD62A4FB6AF3C971,4B924F028684C473,01551BF69549E31F,E39E8053D71672D7,2A7FA7CB6B6698EC,00000000E1E67724,5B5BB0C515401487,48C875E4F93678E4,24EDB1140DB96149,21E76318709F4D85,73C2FC47FD245E1F,59DDD1DCEBE287A4,8EB113025C52A660,FCE0EACD4B0EC9E3,487F0892E86223FC,00000001F1FA79A4,5334C08475B65EC5,FEFC9A141E5DA102,1E3341E394844D42,D2EF74DF8205FDEA,0BC9CEF16B6AC744,AF51E52D1A458822,F0ECE2438C571CD1,BC5BF1DB16A1D42D,2895B174BC69B33A,000000013F78FD02,3800767094420742,29D808584C750CE1,4267F41AC0117628,E85733A479770AD5,BCFB7F1500DF402F,3E572DFB136F94A8,364ED6D57C6AF969,1071B1E4C84394BE,2841C98FE7DBA3C7,000000027A75A1E4,9DA12A519240B6FA,B930AF9F0F43F80C,5A057E6DC76C8FAE,22A88D4900102056,416B8A178D82833E,E1D7F5B91B1B506F,7459DEA001BF9C2A,CC214D80CD59838A,9D59BE09E7FF960D,0000000243034EA3,67CA2CB0C39FAD6C,0C741CCABC5D3584,4C0763814C06E972,B291AF2701E9623B,2A3F04AF27A21CEC,9E934BCEE355ED6C,1E51282405F39518,6B020D4B6C2D0023,2D706C1A162BAF87,00000000EAC3B054,48E712646A96CCED,A7FD0D0B83CD06DF,6431E73B98086163,7B641832E5FFF0ED,7A570E5DB1EA7A04,A8FAB7DDD60D93A0,86F960CC53F0D1B0,3848BF39555CA131,E56A6381C50ACBFF,0000000034E3A469,E6F270B79BD4EAD0,149D631EE5078441,FBE5A40A01FFD11F,287599D6850E6286,F5A215676EB9A082,19A56B48A127DF7A,15D73E56F4648B33,3BD5F6BC5F4D1364,C4797CFBFCDA4CD4,00000000ACF85B00,BD164513F6F3E526,361356A1C3F3849D,F0BFD4FAA48D5BE0,B654F39892A4B93B,04A441252137DAE3,C56D2E923E3D954D,41DBA1F75EBDF244,F577C54670454590,07BCC94FD6011171,00000001C722DE23,293B095C551C98AE,1405F1D085333A74,7A569525DA299037,B0B6B1EE95987E7C,BED2C85F2830F45B,B2BF9E763054979D,3186716330BF1358,D97405C6A6923A5A,EC03FC6450B840D5,0000000222837BF8,A1F0EBE58E7E9518,05EF03FD2DC02BAA,34FCEBD030A743F7,C7D6AAEDE87B3333,A95FD6E1B68E3D05,6505789DFF2A1EAF,F99CB3DD8AB4A94F,E0F43078DF657247,8EF22098E7E7002D,00000001DDC66895,49684843D3E08623,10AB84EE829B4A26,C7B0F2B5961001F6,8485F4B426C45683,2F83C650A36F537F,F4287516DF54D8E9,DE87E91C7B61076D,D4F1E2396D066BA5,5A3FD1D192598147,000000003EB1429D,2F6CD4A5563929FF,2AA137818C41492C,FBF30118293DFFB9,847B7646CC39BECD,4E29D651D215CEE7,07B260D510545ABE,55E39F375C127C6F,795928097C52D5BC,C5658554B320A8D8,00000000744D912B,1BEE50D6E69C641A,A3D1420D1A53E9CA,7AA5FA3B3495C7FD,D329D830276AE3C9,DE744145AC5C8D37,8759AE43DAA8F2F2,0BC501F4E59E42B2,BAFF428EF27351CF,D4ADE990CD8F6386,000000026D286CC8,4C063A527E18C110,288790219C6A16C7,DF097BB8B1A7FC27,2B1CBC0A844FC07C,A0DFEC22AAA7A96D,8E22B02FCC2685C2,24C536BAAC0698EC,22181F6D352DAA79,ECB02EF4FB4E96C9,00000001EA49846A,DCCE867A8FD39E9C,E4F43522CAFFCBFF,2CFAF018D82DAA73,9CD813F6C6ADBDAF,130D0DACE39DF12B,E2809CBF83357B7C,901DFCBC1BC34A08,420F6F7A8A4E3EE8,EB31894E2BD7D328,0000000055C97A10,A7C0164EF2CD7414,B6E93374D93B9A93,34CC41FC8E418FFF,F0B8113C0CE7B60E,2C3815426FCBCF4C,E6CF67AF514380D6,83FEB541B6018199,E16FA33D5927DC0F,B930227C625E62EE,000000026EA8CF08,99DCB902CCC8BB83,8C9BDBAEB939F407,6B07538E5B86DB7E,4FC906577053247D,07D037820C722FA6,0467670C095C7B9E,EE3158E78C0F62A2,E217ECB5BBD0DE2D,364959BB1777C3F4,00000001FAA6EE85,66845833698B4AFA,E26D3FDC34955AC9,F0F917F516970F02,74A91587BFBBFCCF,FAAA84466981E912,DB23954862394EE7,ACBC2BE7E8743FD8,E2E98B3E5A1CA563,D53992291C190026,00000000B9FA4556,0E95603C8DA05D82,B82DE8AE727CC789,CAB6E9FAAEE68C0C,1AC9C2DFCE9E8171,818C36F7BCEDB457,F288A68E21184537,843FD8BF549B06AA,0C88A0B4E806190B,8D68D4E652A23365,00000000AE1A95C3,77F9813222A1DDA4,6889249584688844,10CF5F7EE2F64BF6,773B6C1BFEB0D868,EB3FFA00D4DDB728,0302D6E8830594BF,C59D494DECB34493,09673819E23926A2,D659CF871F5B0B86,00000001DC883264,A57A73C6BFEA99AF,37AE5D082D133D56,562607BCC648AD4A,B8678BBB250AA94B,A34F4D137BFE86E8,D2EB7E928EA38BEE,F2F4456E936FF781,8FAC966ED600D8AA,8471D339CCEF5FF8,0000000017265A74,27C6F7F3C07CB5FE,C6130A8855A6F273,D01186B7978665D4,4F4EDE5F3E1BA1A2,5D017BE6B3A40B94,90DB43FFACDBC472,8EAD548A729BE9AE,855F4C43E7245BB2,59931E2BD7B4A6B4,000000026AD6A34B,5E6F88E023E7EFAB,B91BDA2B53FC7472,B45A1C8E325623BB,4B0061E900343112,3C3BBAB089E1F857,79A86363668CE79C,07DCE2A6D60015B7,2A60D2B152586292,0D2C7C55AB48E378,000000008D2863CD,24C688C37CF81C4A,6EDF75DF8EDB8ABE,D2605BF4BD560BC6,680EE0D525282FFE,46565A406E7992AB,59B79028DBA8C6DD,084F533AFD103A11,3125120C5FD7380C,EA4285539A3C9529,0000000207EDF2E3,83D6B02E9BF65B5F,0191F590F002636C,9384A66AAE03D3ED,F9354D93E1230094,64C3AC789318F697,EB1CFE8615B287D7,3ABBB7322535E9F2,8092C3D6D45BED11,681DA1985A58D11D,00000001855F313E,58ED36F55E0875A1,74BEBD574D1BF50C,ED493092D86A3C54,C343C62161575872,8F16A41896D46894,B2C0D2653E0E8F67,A17F8031EB8C7BB7,DA02DDEAE3346B50,3CDCD09009259F13,0000000076EB1C2F,AFAEDCCB33CA316E,B660DC85853C78BE,D114FD0EF01BDBFD,01527442E68D4691,0D33BDB110DF845E,52E98467BFDBF3D9,1A6721BD2831045A,1348CA423A51A6D0,9C70EE4161FA0AA6,00000001A8917F72,5901C327999067D3,7CAAA4271A80A269,5E1180F71DABF7FF,E2B83633C1137B51,73EBB158AB262323,29F84E6C864CC601,208AC8D325F5B100,D806711DE896DE7F,DD3EB53878667D74,0000000214C83075,8105635BBA6678A0,2690DC6B57E0B583,0C16AD71E74DB822,CDB56B90B9038AB5,C497CB1D4678DBB8,C0E50EC62D7827A1,D2BD11AF85FFF8E5,6DE075AEC1703768,62ABFF15DF1625F4,0000000107B11FB5,49C9F2418BB85056,E9379A2F32A7C426,73469301CF68CF1C,62FEE79A59440ADA,A1B8F399847B6A18,25061E2797A680E7,97C94ED183259FD9,CFA25D2E1BA1D464,0C75840E3C15333D,0000000213989154,D28DE72EFA853B3F,836000A08F3E8EE6,35FD20DF59654F0B,470FF922DFBA8D5C,E0EE54C41B9978AC,195894FA5916BAF8,8EDB242978335ACE,A47D06BD2B99B2D8,EDCA0BC5A1DF90BB,00000001E46B4F5D,8D1C77FA44D26419,E6C42C3A3106A595,F359E1FF008B2897,7C08067429278137,24DC227F943C36FE,0BA9C012D56C074C,A7B210E4D8561F1F,40FE795B84FBD8B0,60FF76C1FCAA0449,00000000DED6AACC,11690A4947625978,72E692897854EEA2,5962A349969D3061,6E57F24819ED5F17,EE6E6284F981DACD,DDEC644B34F7EE96,1D6487F651965A5C,159D87A64E9E4C33,B6E19298E0AD9A0F,000000011762AD0E,FACBE3B33239C3B3,5BDE3751A46CE166,4F0B695777471BB7,DC95A2C106F58AD7,D90EE6B1CF035576,650992858E628C23,490C910A8BBA99E9,EEA3669FEEEE32A2,D1AA1346CBB3FE37,0000000253D75EB5,D9C1A74A6BF697F7,BD360B330477B485,2E1D6B57A7730816,A42AA8BCA82F4283,5D937DC363747A0D,A0525F7DFD439840,8E517B37E4B13376,23EA30C7BB284879,BB8A431C70FB6A88,0000000233CFF688,C969035837E25941,4B0E74B165DF4062,DBFF6FC80F111B3A,8ECF724C4B1229B0,AC2F2595D2942A21,D656E0CC2ED3D5F3,DC4A71773BE0E007,9A3F36B4C443BE54,7EFA35586D5E5CDA,000000001F3700ED,2403E412668D0C6E,EB3085238E9D7BD5,5DA95CBC2411B6F8,9EA6178ACC9971DE,ECA9FD6176FE0888,2B5D4A7FF53C48E0,940D2E5AE20A5E16,B3DA3043DE7941A9,D6BC139C60D9D3E9,0000000151BF414D,62F3AF848C7D9DFE,C0E9A14ACD374969,B39D0AEFE54F7DAA,82CCB9442FDB612C,AFFDE8C98BF2BCFC,513B18C4A355DF50,2D9AFBAF2FE5E486,C862A17AAFEFDA49,6E0F58FAE56F38FB,0000000223817FCC,92FD2644206A1D22,7F51390BB88AA340,E53A04CA79CED159,3CCC15E9D2B21D78,B6A2BF561BFC3706,8BFD4C7956C79D6C,49F40C14C0269C6C,ED0FAB87C6AAAA77,CF3BBFCAE09FB841,000000024AA046B2,DBDB1D4ECD7814C3,8FFBFD7419F19986,05773615126C05AA,0CFD3258DB3F593A,46394B5F1D63D283,1ADA6179704EA5F4,66C1B85641C7CED1,E0DE57973EACABB8,4E49C0224D63A6A2,000000010913FDBC,EA46CC3BDC6084FA,85A956D385D9D9C8,D951E6E1554680F5,742D310A8B3D885E,AF7A71A2CC8CE1D7,220E4C2D5BB4A71B,973F67D0702E75D2,5D03F54035DE449E,FE43C574BD2980CC,00000000FF3E3491,845C996DB2DE83BF,3016408A0728535A,7A85919B23147948,FF08BF3B690FB035,DA4335B684EF1B39,A7FD4FC66BB90E58,AE9E3BCF0C9FC445,5C4D677615B7333F,75F70B76695F73CA,0000000074CE3725,1D0ED3E967D5C715,BE15D8F93255D723,F9ACF401FE514EB8,0F5A77159A40C65E,8FCE7D7102B3C728,CBF461BE1B5D5F75,0903FB6B2B04DE60,1A3D3FD53B346EB9,7773F21D290A185E,000000004AB2D00D,6FE46A53A2F0C8A4,72A328491CA8B8B1,124F154E8FE4B851,8239EE87DD5065AE,A300912C14BDB63F,EE8743EDC2C64771,6C73E922E10C1DB6,CD539A3D3B5CEA47,F7E905A72E8C4B23,00000000225E8041,6CD493F24CC25E90,9C925CD08826967B,EA58307E0B32A8B8,D0A3DFD1B52C5AC4,C877421B6DA5E4A4,C3FBD2464E1AFFC7,9FD5D9F967BF68A0,4D45F321E0804F98,4A3DA8A5D2253A01,0000000023CC5893,27AEBDE5C37049E1,AEFED3A0425F60D7,18DF09C68FEC5C4E,97709A2E1051CE3C,3C0CEEE3976A0B88,D7EF9A8A46E3B4F8,FC6B9C4AD3E05E0E,D41BCA44887ADD47,712D90F91DB1BB27,000000000BD02E56,1A611A702B8BDFA2,ADAA783E66C47DAF,67D32B76B3EF6303,50FB738D2DF4E822,0625E6CA17832DEF,0D8617F81DCDB505,925B4C08DB4EB168,C3195ADCA5295CFA,B4A87693179BC87B,00000001B785D87A,9FC279D1784B4100,609D26140078D5DA,9C5002D103D523C8,DB03000907CE9040,46D40822D9109FD2,39803B76A7E27606,6B5C9B2789EAB713,95FB59373BC85736,02C1E7CFE8FC0099,000000024DDEE132,4AC8FB28407F8417,9E68B39934A756D7,91B31952B1691B43,05C909CA460CC7B0,8187B5DC608DF68D,FBB9B38D44EF758E,07D2C84C7047508E,72B42AD61954B22B,B34C62B8DFA5ECA1,0000000169C985B8,2B8F046C0F6A2A50,50D9D8C9269C8F8F,4B68AFA59A926A8D,AA108DC910313A1E,2074E1E2CAD2A6CB,CA8E6C5A87248290,D9CDDEFAF22EA17E,772D7A5FB0A664A6,9903D0E89B4820B9,0000000191E2C812,4EDAC09D2FD066FE,B1B91BFF20EC4491,1278C8DE12C5269C,12691FC44B452DA7,D594CA71FE00689C,76CCC777AE4958D3,D83924CBBBC8AF14,DBF327A027C9384D,96E32158C32AC4A1,00000000601A0BB8,216B4D216BD38C5A,A433A799EEF0062A,62FA3D8E7E6AFEC9,A45B1DBD099E90DF,A58ACE6EE086904E,C33D9C025C4D33D3,B38FC7A3AC050BDC,73214B6CF9D2BA40,F173E4171B6F815A,00000001EF51D918,13505C55E158118E,4A509FD0CD1E03F6,E59D62BED8FABB92,CB0B0B134CB387D4,217BCB63569B673E,4F97CEFC6F764FA2,A846E2D159DF036D,9E15C141EBA96229,9A1AB152C1530527,00000000A2174C8F,7DFC84863AEE8425,E7B8DD8353D6767F,AA74AD4C86F6888B,59948B3E954D860E,90D97B67DF3D57EF,E65BDF87A1D576D5,51A09CDAD6D15089,087EA9A08E7AE534,4D68490CDA590262,000000020532CF1C,9C6234C82EB41DAD,173A7941DECFE212,D69B41CC7272CEC7,0FF966A7DA21C302,D8C416C457806E84,8DB778184A804D7A,8F55A58298E5DAF1,AE0D5DDA6AF2BC94,6E6CA4723352BF98,00000000355A1174,667B3151B01E6925,EE6DDAC4494366FB,4CF2C5A774015058,47A581A21E327082,807477AF050AA0DF,1F4A11B226017603,312B15C2BF07FA49,29B4D89060210391,59C98BDE5977EC87,00000001AAA7E0CE,22E58FFC5D38917B,C5ED1CCC9F193DA7,6EA83203CCC8EB7B,ED83D18C9B068A16,0A1E5E86C2D8AF3B,83764D1581A0AB9C,5F7529C21B150D06,2BE812D296BD30D4,64A2F2268CE26A3F,00000002485A1697,0B7E797C605447C1,F56694516AD73D78,32FAB484894A2578,3FC14FE2EC46C144,0FDD513B6943D834,F0EFBB7E7B66E819,1150FF41A6EC2B3E,89B81C89D8B38435,A0855471167EA19E,00000001C2A9754F,30D6FA7CFA1C7855,40D930734DB6C3E6,B453DD303017B5AA,1E470ADBC5225314,1957E0D46A37D5A8,18FB0B9D8C807239,A5CFBBBFBE92D285,0EB83542AA36F7B9,00F8054E76C2BE2A,0000000084DDC469,355D201BFBE52B5D,E7580CF448528808,5E16889469BCEA50,1F274AEBC211189B,17E4AB57739BA60C,394C158FD51C6609,626584CE9261020A,5BBFB01CB0599B9A,5D35F71F2AE97E59,00000002518DF8D8,FE660312A5CED2EB,3F8ACEDCBA0ED333,5FCE057D9E5B8049,02C454313567FA53,625AADD4F70776D8,2526F8A2F24DD442,37CADA47FE51728A,368825A25254868E,CFAF09A5D89D91F0,00000001BA923325,A69C9C3EB0C37CC6,931FA8D2C95F80FF,7BBF8123F2BAEB7E,F4A1C885ED83554E,912AC9934D9E2E2A,BDF6FEF21F21FFAB,9ED6BE673C6DCFA0,86944BC5FF9D1415,9A3E1EA834CD7C8B,000000017952E1AC,026CBB9A107AB34E,50503306329F024C,292CF2A7AE8C574A,1986CB566D157D10,0EE3B41587041CA0,78F273637CF88FA4,6A0E1F8AEC849A28,3876E23F732D160B,B880CDA0270A20ED,000000010BEA1739,6E1D7A5EDD2947B5,47DE3F879045835D,9104310DF84458E9,ED37D9FD1DB8A2F3,1F09EC110406416C,436AAD6F7CDD6BDC,3D5927218507DD69,6AC9831BA539BC40,F0BEA2B1855526C2,00000001EBEB5AF8,870DC1E27F690960,5656B0F309DC6300,EF6BD08F0AA9D282,B805DEFD86FF4363,9AD84346D1F30ED2,52F604E9D8D3A48B,909A02D7D8C9BF19,6816D7D27236FF31,92A3CB2D7B1CBEDB,00000000483F884D,66EFC82D4E1898E8,678B124426DB8E27,B1CA109DC9C9C2B1,E73BC2F830B1B8A8,69740BFE4D50112F,399704C7605420AC,40E20318D3058C9A,ECDD4DBFE5B9BC8F,2C4B922E6E222D08,00000000101D7029,A18B9570D090CC5B,77174100AEF56BBB,789D2B4CC62C3FE9,A0C61340237C537E,167CFEB979194F97,F02207803B030E34,7994EFA10C63D8B1,A86E755E9660654F,3204189DC428AF05,00000001F5E467D1,A4648DBEE711F2A6,D616416AE58E86B6,71C3DDEDF3765045,DA01D214B3ACC919,81B6CC2D7D742BA2,282B01EE0490AF25,55D92DB1355CC19F,8525D40D0D66510B,C622F6A443D2938D,00000000BCFA8C4D,B25E9D0FA1A3F037,6B9B06DF161CD23F,1028C4A9E159D2F9,9716FF366558271F,F091526033C45331,F44747AE79EAE65F,8F5E6E392C8E3BF6,F56140AAA46CCEFB,019262ACDCA157EE,000000026015E869,E5C7AB4705BE9E2A,CB718CA84C8CE59F,9D0A60DA68591C1A,8FC1F56DD95EB701,41A44B3014A7CCF9,9293425E2EA2DEE7,D19BD053CB64D00E,B9F07620FB0AB23B,5AD4EB837224F695,000000018D87D167,B88BA6F975AC4F41,23A7622AB46A7509,A9E3B7DD31ED6045,BDD118B7EAD97663,C1394083A2292B25,AADD9A8DB2326B22,C11C3A7C6792B0D5,9B68EEDE2F4375AE,FA60F88A5B736840,000000023CB7516A,B1EA4D87CD853F68,6849D64A7C41D032,7B6749398D57C9E3,51B283B6910428BF,593AB444A15C4AE1,49AA8C2CF803F200,A6D460CD94906901,21928F8E6C8FEE77,C1CBC0AC220D3CAC,0000000250C81891,ACFA58ADF9CEC175,617B90B090151F2B,015A96A47D42EC71,7EBDA1247FFEBBB8,00066B670FD6243F,984D81D7D22B8050,B8E31162D4B67E8A,48362449545678FF,761BB636A724D0AE,00000001F47BC85E,10C751A35F97A224,11CB8CE2B7F7530A,602DCFC018480074,BC098D96FE375BB8,87F47FD29A4C080F,F1BFE5D9FDC6C884,40DD02402746ECAB,12173F9AC94013E1,B9E2A6B071F02855,000000026C53809A,BDDE441BFBB7761E,20B12F2C8D85ED3F,777F791E3AE5A919,5510DBBEB0C7D88D,3D4ADCF5F32CAF4B,B7D303BE18DBD2A5,6AD27E95A613F9C3,E87AF328E26C4575,F7769EC62F4945A1,000000022E357919,095D45F97C347A00,91939707FB3F69E1,DA0E3C9857667B9E,BA314AC18B3C5140,DD672882BFA4E975,3B461E92C9E9936C,3BE2AEECF9DDB34D,F655FD945C430961,D07F130102FF4888,00000001B8D7581E,14165A9852F71A9D,1348D5D355E405D3,A938418CECFB4FFF,017826E2BBC9DBE9,9C035D4560C6CF34,442282D5DC44977A,5F7F5383365EF0E6,5B5F70FE9489DA85,7985E1CBDD594705,00000001B32A2C2F,F5C1E96ED05CA863,01BB076837E07029,F253BC713BC80F5D,7ADD73006B576E4E,34416A5D8C02E3A9,F0582ADE65C85E74,65A2AD59327AE592,134C2EA3466F03DB,71E7E16332E57F50,000000015A47AEDE,B7D9272E57B4C6A3,25151F3CD2DB3836,01C11CE55AD96950,5ACDF39EA6A63785,B495FED547CC1BCA,F1B8E43478E08363,30CA71060B685881,E0404A7A6E46F4C3,631A5EB51C77C5C0,00000000D6842FD0,28657F3FDE12DB62,3143A2813D02BAD4,DBA6C071FFD9DE01,B0AA40AB6ECC5F88,269F1C50F08F2B8C,94C597FD663DC8E1,0F5EF231E5957248,3EEC82AC87FA7772,EC42EC092FABFC7F,00000001B2CA09D3,23312BAC54DC851E,901B846E0A0FB736,99C2EB2A885FDFFE,A57AD10E9825038E,63063243520B1787,47F6D18CA69F2F79,E0C950B94587948E,00FC126354C151FA,320E6B315855AC92,000000018A0E877B,2684BD33ECAAB8F4,9E2B3C4C6C6E1700,9713772AE0B6ACA6,43823E38AFCCCD30,571FF2EC4CFD9F2C,97F808AE8D5CC812,8A9F9AF0D17B08EB,8139EDA6717D6DB7,AD1F3180FA885854,0000000183A50524,73D2D56DCBC2F685,B9482DD633B194A8,A5A3078B26DB0B9B,ED6B3131FC52008D,B023CCCD086E6D58,A5B3EE46E8CA5B2C,3DD1D7551C590EE6,4B25710BADB11B1D,4BF3028C9E1278EA,0000000264035321,8A5A897EFC094522,C88B2DA896112E2C,CD7896FBA4D66608,C3446ADBE37CA4A0,6B68C4CF9FDE9C65,2D41C40C40C82853,503CA6B1DC761D61,FEC88280B4FAAD85,84C9C5EAB98D7BE5,000000004B636E6A,1403368BF50EB880,07B04B4B81385A04,25CD3CF2651CAE24,9E25228962830460,6FFDBEC87DBC2942,040A6F473861CD15,302A037BBF026953,484B3495EC36A1ED,D277CCFF61B5EE63,000000006A52705B,DF437F775FCD8430,F575C5F148C75C28,C697C015A8B5D795,3FC0FE312E5932BC,2C61B0A50D34330D,137A9F889790046A,6DC4421E7BF92B29,73A84523226F45AD,255D6F43CF7881BC,00000001FE1FB88D,D434D2D72DCB3A63,741BF6ADB024BD2C,250D5D8F859BC5CC,33FC958E1D1A6F2D,C02F1971E4F7BDD8,A7EBB91E112554BE,AB9C7C202ECCDBF2,42603879F69B11F4,2B43679F8E435E31,00000002754C54AA,01153CDDFB3AF1EA,FEFACECCD638476C,12AD09D106D6D127,A29559668E511453,44F2691308CC7846,E3E66A8B45E2E699,C1786DE586B5D1C7,8CC2325E6A4FA55B,208E49EB91F33500,00000000E3E9D47D,FC946C044ACB13BB,261492C46BE27802,C66435DABDDAE08E,E3D549177C3EB66A,F223354B7FC82786,7EAAB248BE83DDD3,DF5CD48720A644AD,AE0CB2E6402269B7,99A71ADEB4B4C582,0000000125D59A4B,C673115C7473B062,DCBA8987035C555D,CEBA69633F352708,53DE7A466F8C151F,A4801F488D0796E4,B33E3BC0C4F0CAAF,E938BEB35CD1DB2C,3BB4D0B4CDD1D206,44B971A9C797D8F6,00000000AEAD918F,B9CF4433BE7BB423,5DB27B16069F5FF9,2A0151272F623265,BAC78C1D000ABE02,2C898F32158F01A0,2104AD308D4C4F02,64F5ACC360FE7EE1,498B51E8ADB6AB0F,D8AA02A63856C6B8,000000012B6D25A2,B17217611518CE28,BB21881BEDD31E73,26D85E0CA5DE63B2,B56AA7C49348C716,365BEB6CB80CEE64,83F5FB8AC6658083,825ACD0B3422FF0A,F33FC1B5B284D628,1399DC99297744A6,0000000228E8D787,EA299C167C62B7D8,822013CAF6300E94,A9CFB96599816614,53901FC9499A77DD,E5EBFBA5CC28EA63,F894A0DBC8050E5A,E9DBC48F0F104F26,2BD761D9DCA76612,38C5EDB455C46977,00000000C58A54B8,B6DF6DC458DB4798,77BE57AED5B27E60,695DA95E41CE0CF6,8BF806BC9BC0FD0D,860B955CCA7E840F,76812BF5DAAC45BD,7BEBC7956254A28D,522443A9CFEB5DDA,6A655AE4E40D1E30,000000025EA2B4AF,03E65CAF2FACA8E0,5621C31AEB62A646,3242D0355F559298,1E0FBDFAC11C6898,97A2E55C22E03C0D,6B11A7989D5B5C17,B519786C1F67E037,43BDBE3E6409B027,ADA04DCDA34DDB8E,00000000E38AC52C,1F3363372B51B7A2,C56A420F0E1DC82A,CEB5EBCA66F9D691,F84DAB3992A7224B,72282B790213FE60,01C6F9BF023D6773,CBDC2F2DB7CA48CF,7A352D1E921F7EC9,2C5005D3C3487270,0000000175F97ABF,BEA8FA93C4A3C008,FA35B7A3279187B4,742082AF56FDC1CA,0DDADF8BA265C369,2321F86EB9ED3C4E,DD23C38179E3890C,044E5A00DB5983ED,F43E8B8440565C53,31A0C4E292E31AB4,0000000032D26C1C,0B96B8C5392E5AA0,F967FB8B8D6E34F0,A3BF2F32A369C666,996C4E909D281F5E,60D0E61A9CA166F1,B9935BC2CBBD3D13,31A86B64FF9D9CEA,27FB952B295519D2,537D058E9D30342F,000000026C570B77,C9B847CE20AF14EB,3CD3EB2C824907D1,C1869613A91C23E9,5F5065285475D222,AE2915B1BB4C8D0C,1FF87A3AAFA9A42B,F1715D2ADAA3273D,79DF6EFF31223978,D2A3343FA221976A,0000000276C9B736,B11C31188F9EE8BD,C7B3A9E83A3F0D13,0911027A87D0DDDF,A011E8E720CDDC94,3F6AADC21315ADA6,432F992EE4005F5F,50534AEF2E12EF3E,A8D1A8D695C1848E,0FB23DE1AF93FB8E,00000000D6C6B598,7FAE77069DCD10AC,F330810781B86261,08676A5ECBE5F30A,962585B761506EC9,3CB5552C42640F8C,53993AD46349281E,589ECAD26BD88607,EF2ED48276829741,A44C5E0DBB2A3DA3,00000000E729912D,652FAA8D9C8EE49C,76277B8BD4F8E8EC,3E73CDEDA50FDED0,52F5BE08B36976AD,9655B91E529AF3BC,6F4F62A5ADE930FD,6B54C9B5E5FC9DDD,9B217A35944D3A96,2FCF4885B377CDF9,00000000131D0B21,B3588A899AA64454,360251C9ECDCCEB6,9C4F17F5AA2CCFE5,3C5B9E7E2EEA7733,3ED9CCF62E6C0474,2F2E51E279E91416,CA167D0BC0B39357,DE4FED73880CBBAF,2A79FC106B6EEA1D,00000001C6115E5E,05E477A133D1BC5E,1A6BD3769D1753FF,3EA5F23540906E6C,6E1D507BA807E790,4FCD13BE5F30C9CD,913E0DE2CA50720F,618EB988FEB9DE31,FF775C6567E85C0D,7E220A328768B4DB,000000006B5C1B20,BCEC6132F4B04948,F3CF0894AC5B78F8,58A039B8693AC11E,B9C7750E4D81B29D,6008C34F30E6ACC0,19FEC7DB20AA08FF,9B18914D49A768AC,0F886AFA5188CB24,5D763558277A50E2,00000001AA22F20A,ECDA82321C951342,AF18015F66941375,9DC06959929EDE9F,05D5A2EE63482F61,F353949B7EFF1415,C6CD25DCEE5C539F,16586B729B0701F2,A36DF34150805756,EAC22A8FCE2745AE,00000000266D5301,1AA946A6B75F38A5,056FF97AE920B6D4,1E12F03835620A6D,9025CAD02470C51D,66F57B402A19F933,C566178C429CC655,360BCF95A2773488,81A3AED155D32FFF,8DF2B55FF3AC39BA,000000006FE41826,F70CF2E3A1A79CDA,5680099CE736242E,A5CE4E09D964CA16,0B26357464FF5C8A,41446193D97A601F,A37AF984163A77C9,BE635BDBC46162FB,6F0421F4A8B70427,3375F93D2E289DDE,0000000048BC58D3,463125ABBC7F03F8,41088ED90397DC72,87FBB9852F92CDF9,5F6448AFDADDA359,FDCD309E1C6754F9,6051AD4CE665CB6F,A2305997B126EF5C,5BA7E7FE4C817A12,DEEE75BD7C0C115A,00000001191DC0AE,EF950C7F013E2223,39203D9D630A2ABD,ACD3C238CDEF43DB,EFF4103631A62EB7,B6ADEE709D268EF3,AE9BCE4CA9162D8F,9F24A42B34F1E8ED,2EBD57218FFCB1AB,716216E508D89B33,000000009B689A9D,78E244CA0219E48E,7A2D307D0A737223,F670FA144D8BC456,9A74DB7B055F4ED1,8627041BB2D88339,86D7062F334E50DC,4F484EE6EE9E26B3,848AD550BC46AB7D,46E6E7A4C069540A,000000002EA20458,582BB2ED9A4E0918,8675C45CAC0B6D14,4C126A61FA214A23,0F1CDF08EC408291,E1ED57E0CD6A1919,FD1F302223501434,E892EFD3F9333F45,32022F2513894023,60340741C3AE49A2,00000000B74B383C,BB6D441E03B8AAA6,3128465494250FF2,6F68711AA8C780F8,D3330794A3C08CEB,D12012CCCD1AFD08,88027F17655F1BDB,B7C7623413D53B19,CE033ED211D2A153,71CF2B4FC05AC24F,0000000222BCC4B0,36AE29E4956BD8EC,1C5DF86D7416A61B,FDF709A41AEBAC0E,4A37541E71A07DF8,D996EAC9517D6074,6E0C897BB5169719,EC05969BE842FBB9,61C551EAE91D23D0,A0E99F35288D53B4,00000000F8F4C59E,4C8B7851698B461C,D19202585AF17B0C,76B1FF9E843B2EC5,2F6527BFC6CE4033,1689054FC2E1B617,A088575F2185F60F,6A8400E80C500E87,5020F2F620E2C2A5,E901B0125A296F14,00000000DA17FCB4,AAD3B148F575CD34,8EDB88C64B59D124,B5DA9C5BE69A712B,C6443B686E73D77C,79C32A6C6CCD24E3,D809A0A9FA18773A,F62FDAFB3247BBE4,18790C2A3B5C1CE6,29A44BA35A185DBE,0000000200E8B0E1,DD6137A9651C4DFD,5347F33689B5F49C,92BAF0557A191850,BDF69256B0A08F0E,9A646DCAA103EADA,92167949A4218486,140DE6B7B7A91D2D,BAEC00E8F0749E64,A9EF5509DEA4FF8A,000000006C31F5C2,8AEFE447FBA8C4DD,A87A62BC9582F00C,DD2E40ECD736A7FF,E512F4058850BD44,979854A1C0983D4C,63336CE80569B317,1DFFD6349D8F43B5,E93D441C92AE245B,649ACC4EA6327794,00000001D34BA0A9,76BFD0E3F30D12D3,00358E6CB6149FB7,D6A74899568C067F,850A916890FC0908,82983AE7DEF4AD8D,D836CCD300B8E4ED,E4A9F4E76E8BAEB0,E78205FF031C4A0C,1ACB19D2AEFA3139,00000001243F0F5D,22110174DA40044E,5958DBE87C362954,514AF2BB004E2324,A7B88D048C4C2DE0,7FFEAE45A926CE7D,B62AD2ED1D15D14D,29E23771B32606D7,97BF87A0E8E8A4CD,C9075E9E70D8B915,00000002739419C9,7222823C717159DD,A8C765C9C884FEAC,17F365B3DE206905,8EB32C6B963BD378,D6E5AA5BB91174DC,AAED6ED507FA7C36,D005C00223DD614A,2E588A31229BBD18,93AAE1109A6AEA88,00000001127F527D,EFF581A20BAF5954,0D4B42FB4290B152,2841C54885F20DAB,D4E0B3813184F3DC,3BA483D11DBA6126,3EEA29DA0B5F21F3,57253FC50CF68877,C17EC43D9E0D44D8,67C9B867DAC47FB8,00000000DB9D13D8,72DD7C8676A64099,F8E278EB669274AE,C9A905024896F728,3CEDBDB82F72E065,3AB694BE481B520E,78DCDCEFDC683AC0,2778DC6C510708EE,424083014F9FB042,27A5D839F47E4F81,000000014AAB2028,5082858B0A0B8428,78A4FA5C7713C78D,44706D95C45C97E5,AB766E9168FE1B39,D5EBAE33F6FEA2C4,B26999E52727A3B2,55AB58EFBDE0E8BA,2B02C319D2F50BC9,5164D6C3F3787AF2,000000022C8DE677,20F6593713F8D435,7103886461790D6C,FD66809D30CD836A,D01CF3A6AA702A7F,9406E9DC0BE4A91E,EB17E8B213E4257F,CEBD98CB15066FA5,89AD5E3E1D795BBA,0A8E3F1879B3CFE9,000000002845AA8C,18B4498B24BDC3F4,B637DE7A64682E96,B712FAF1ED95B31A,4B57DCFE61FB196C,0EAEE824924DC7FF,ED55063690D924E2,0A34D23A45780D8C,F6D38C51AE094C7C,0A4066D9D5400AE6,0000000113DB1AEB,975BFFE38A592117,434D8982391CFD9F,79E9161681ACCC1C,742D032771422EF9,4DE65B59F83AB4F8,1CBA7EDEDBB8BF71,242BFF6B07827888,B148F6A3D2C2330B,1FEE2C095FA526C7,000000015C3A9111,066912F32CF70939,7A5179496BF4AC16,342E657D1EF9661F,33024408228D2BC1,23F90BD93F1D426D,2775B3F30CE8ACE5,20EF451E5341EC88,F37B4D9DCA345C2C,CC08E207E1C25FAB,00000001BB69BE10,DE37935D39574114,80BDB6A011201144,052B5DD2E3987743,1083FE03781A1EEA,1DD99D5C8D12EF64,BF878DACA3694BB9,4903BB6BCC836B1B,388BE9E6DFB97258,F667665C70C1A0CA,0000000097B676C2,A69BB712736F8E6E,EE83EC6359D1D7A3,4034587C2086EDB3,545DB8C8CD973BB3,0645FED637BF9324,A3F6E562D12ED17F,EACE0609E2187FBA,0051F650C93B7A32,A0DE576ABF66F09E,0000000211E784C6,6F9A09D7C468CF55,319A0C17F03806C2,043D341E7E3A3590,9C32F137E7D4C255,4B8FB5F860601A13,F1CD6AEC71BED0F4,CE88D8EB924AA31D,5F852A8EE925DBA6,8B97F59A8F3E858E,0000000232B5CD8C,6B3FDD15E24ACA60,FBE291EB3850743D,16C0C4E51196A33E,E3FD7643B041F847,5188EBD9C79D61B7,B306AF9D6478800C,34C4F93353DA8802,3274B2EDACB5B9D1,7D4D747F08C62529,00000001EF6CA7B3,0ADCBDFCE73D505A,72B3E2B46529F9D2,625FA10CC94120CB,29337BD25133CB9B,19D482B3B3E262B9,03EB45862500EF7E,4D5A959ECC1F5909,7D16E246FE9D87CE,10A4157365E4A491,00000001DFB74E20,1930B476A230B7BE,03A42EE16DC949E2,838416CC861CB74D,E43303F18BFF483E,30C6C49AC1829C11,40DD7E521AF62273,33AA27D882B23CB2,0A970F369B7A93C6,DBAC55CF2FEFF179,00000001967E10A3,4709DA258D7CF239,68142BD88204D1EA,AE14B528AE909088,8D813E124214BFD6,8E6949403E0D509B,F795CE2041AC8CA6,20F1E1F2A851B359,89B489710FA8BD76,1608B910A609EED8,00000001F957263F,73CFFC32E9B7CA37,F67644739E040DB6,0820A54C0C46F61B,95137B08505FA716,981FE9E46DCC3ECA,81B2061969F6DDEC,2588EE0651AD8E2E,9BEC9F1B09B345EA,67E641D1CC333321,00000001A98DA956,1930B476A230B7BE,03A42EE16DC949E2,838416CC861CB74D,E43303F18BFF483E,30C6C49AC1829C11,40DD7E521AF62273,33AA27D882B23CB2,0A970F369B7A93C6,DBAC55CF2FEFF179,00000001967E10A3 - -T_tate2_firststep_P = 5BE1ED524F33C52B,0E82A6C9C95E44A2,35AC19AA3D2D0C8F,C48D5A6EF316DCEF,A75B1FAE1C70541F,BF4709C0460AB142,6B989E232D21267C,1C8F0D2F1F827A73,7A1EF44C4B138F94,0000000076F38CA3,1E89B04824B7F00F,B0CECBD277603CC8,A7D3D9FCEF3F333A,96A48E39362C5CDF,562632BF879C83F5,36E6479094FC0145,A58ECF8D41DDE052,DC3DA3C376FAA4AC,6658A30D41B00A4A,00000001AC7A7CC0,04505A22B44048A6,19F3A6862BD40254,7C43EF221BCF02B5,6B2DFEA48B5098B6,6E06586FDB2FB0AF,1097E2BCBF9ADEDA,B4EC7813CE4DA07F,D12393C9E4990B29,3FEE313BA5FD37A2,000000001A17AA2A,F167C294F154F59C,8A597350936E94C2,9FA898086E4BAAB3,E81E3DDE95E49C58,3FCCFAEB8E00D887,731B0E03E4A278D4,4A66222E70B0D80B,A63038C5CF23DEB0,FA9EA4C23B762257,0000000035EB2E52 - -T_tate2_P = E76420CC37DD8308,A92FF26EE4745DAB,377A25B425FFB178,2AF8E297BFCE0D1F,2589D47C051EF1EE,DB00E9682F7F9205,0E9967060F9E3EC7,154FE450E6CE6B92,DA2544169F466B8B,0000000021CDD1EC,79CD0FC4738F4FC5,CEC3E5C7DBCAD38B,A94B3CFA13400C01,10E6396CABA4A834,72E8F09F76B2EDA3,669163F4DC456D51,BDA1AACA2C93BB37,D239CAE9D0D64DBF,F72FC60D1961F96A,000000001A017D00,B2215859497ACD04,A752EE064241DAD5,A76D04E5DE9CF1CF,0823007A316BF06D,30A19BF25506241F,8757C8F92E225574,74F318F5980DBEE0,4F61DA2CF0B3BD1C,D12DEF2F28060036,00000000B854AB5F,0611A44C308A6CF4,921C2D38B4AEA068,F71BAE5E2F48A77D,47F3F57089A01C34,27177E7F6FDDA550,4B470FC33533A72B,400774262E5F56F5,9B8C3B105B3C883A,5BA5C8655ADD44DD,00000000B4BA6DC5,474076BF2DFCD8B5,A8EC91566930A7E5,4DF93554A0B82B92,2BD5736F76063698,61EFCA5F3FBB56E6,176E73E317EB5415,FC9C5732C9773153,9BBA66FB3D0E0D3C,2BBA98162A1E811A,0000000191E8A2F9,5CCBF592A41F9C47,477BC6E5F680BFAD,A3BDC29575D57A6B,2A6767D8EE5A4FF7,003275482178B202,48FD1178BCD644B8,1449677E9BB6D2CD,841E2100C7643702,E56970CF517A5A45,000000004988AD97,DCAE6F11D7427B31,48806E91A39CFE89,A4849BCEA8102C03,8E560FF5C279EEF6,D3BE8E4604A31BEB,5812DE6ECE9D598E,CD5F2849753C339E,D67B5B8417E81027,94CC38B6A28B2B8D,00000000F2EA33DE,CD71A58E3A9F4EBF,95D0C9FE2DD1E9BE,D636165223448FD3,6ABB6BC4DFA92689,ED46D50784214072,CBD1ACE6988F45C9,36E5F1FBE59DD554,0DE08F9F492F0C1D,30E441A59E5F4778,000000027B9F69FE,AFA56A94C9CF483D,2192A57F6B1EEE3A,6F936772964C8407,84941A3BC590A2CA,15F3BD3F6B677BD1,9D7D7560E771A039,4E381B7E59A38FB0,5B6A32FE1C82DF2D,B97614E6ED143343,0000000052D26742,F810F7E3F4935152,6FD1CED8B51B14D9,D7684DAD708166CA,770BE11C32D8A0AC,2F4F7AA5390A0DFE,E64CF61B5E914CCC,8EF26F27A5898206,7938B247C3675069,3882B198890C175A,000000016D795D57,B5BECEAE19C633DA,6FE9C2EE9D63CE60,7AD23A78A93A5F7A,8D93B66E673424AC,2144807DD60D5324,009F20C0BCFA9259,93B4379BF699746B,B6CFBCD8DF2AA34B,0CE1E247732921F0,000000026D3A1A70,72307622E528A148,DED7BE01E4138773,E386945F26C2F9EE,F1D3B7F082E3DCB2,D9A4D835F6BD545D,8B3E666CE7062319,224F19D6903000DA,CFFF4EC9583E5055,BE625F853687F2E3,00000001F47531E9,60AEB69F0F12FF49,920740A6171F31A2,264301AFC2E17945,1CF025E2B63DBB10,DF9AC49BD709F687,1258DDE964761EE1,43F01D4A52B7EDC3,915AA0928721B0C6,EE8CF27857A3EEA1,000000020CC71243,7B3E0F8C1E67B876,7849E97064612AA0,55D9C72DA054EF1F,B587DF4503C95FD5,41211FD23DEA9BFB,FADC50A252B22A1A,62250BB1EE9AE790,687DB2EB4C1EDC59,AE555824C68D3085,0000000268C77918,E64028043D9145AA,051A41D2047159B5,9AFA848999D9EBDB,757283C61A603CFB,9627FD75F5CAA530,7BA6322369D5CA66,D55E3D1B51685784,5362FAA489789D67,F39972999BF3B6A2,00000000279BB97A,AED1216787341C3E,908C6A7BA6B01037,9BE89656D0A36351,C8ECC4A1C7C34628,E826D224B22FE427,28087201B385B63C,995D7CA3814C7CD0,861C6BAF8C50B65E,AF2C1646F2F8C01A,000000014FC86E03,15829DDC1C8BED71,4EE455BEAF68966B,ADCF0B3CE10416BD,205A26EAFAD24065,F9B1423C42BDFE7C,275664B9C7E4A57D,60328D087BB6B69A,DDED5244047A515D,BC7C716EB05A45AD,000000007C2BD20D,2251B27901ADC2BA,220C9711C773827C,A20B17312E44F884,C88AADC105C5F445,DE09F493916EBD95,D0B10F356B40F22A,93AB334CBC5796E8,592B6F2CED55E2C9,0E758384132E52C0,00000001F65576A7,405961B9774C8761,E67D960CD77FCB54,7D6D34BA3898949A,02BA7BB1D9668BD8,AA1E7935632DF103,2F90954953A09BD7,9F98D7CE473C0EC3,8DB0A93865E6223A,3CA39555922E04F2,000000003E57684F,896080ED05DF7596,BD5C1C6F7EA8812D,AFAD6A5F800B2232,CBF98BEA3CE9573B,CBC1F2F3CAFE767F,4057675C8D4BB81D,46A123D9FC0A4ACE,2B490E814AF89C16,DB090953996C364B,00000001F40C886F,89359E4181E5D9F3,289DD05377DB78E6,B3B0C07ABCFC4A04,BD9EFC5F8B614723,4EB2CDD0E5A5B679,3643AD7B6003F281,BB07F8621EB37434,D32525E1627940B5,AFEC13AED2DC5FFC,00000001F2BC16C7,4F25ED51F2DA86EA,A5BBEA03A85E0E41,C6ED4765BFEFCA1C,CE64415005DFA33D,F5E879A55E55E458,83DF89E567D053A1,B394FE355FC88700,BD45B34EBA3AEF57,634DB44F8252C18E,000000020C521A1B,5D414B47ED6DB7B6,2BBDD0E469704FCC,D1DFEF455A164A5E,446561D0FBBAA3A9,C63ECEDDD494A83E,C8B89E35D49D21AE,83C69A46B3163CA9,96649CB8B176E336,B585F986D6152C3B,000000027832BD3A,0AB284D12BF6EF07,724015760DF5BECA,3ABEE6F09B1F3D87,FA2FF92B57F927DF,F31033DCC310F9E7,EBE0F34846D0CDB4,EBE9AF6B6C2837C7,9BAC7EF70985D8B5,DA4729D6ADD221EF,00000001F03B652C,6E506EBAFF26728D,7FBADEB1174BBCCE,2510BFF6FDFB8243,CD05098C173FD8AD,AF4E01D40BC210E2,F9D81C76768C197D,A3CAC6108C447368,A530B13CD0530348,49FAB031A6F487E2,000000011F4F7A6F,00E3147613CB95CE,17FD57ECD5A6298C,649AEC524CB72202,626005084F0EE06E,3F6A9C7186D64CED,4445B842868A7C72,D492216BC9D38B43,B90D2D9A90124185,ED282ED0FEBF8921,0000000177D113A1,E0FB4E10339F6732,32F1F5FFEDFB7FFF,49E129B87D8D095C,016B2B8E489B9F77,F68CC1FC6766A782,D8BA1B1398F7A9CC,C3DB37DA9680463E,800986502D924078,D3D39E201323B77B,000000009A39C58D,219D3FA18644ADB0,7987936057F48063,778328676CA162A1,4571CE486E4F4C91,4B249772A513320B,78E49BEBEB112997,DADB1B2F08F4B59C,213CE1247E80CB01,E7C599AF93153182,00000000B5C8029D,CD9C7A4CAC8A0140,5C7436524631F66D,363CD9D6BCCEC2EA,D9BB67FBBD221151,F87FCAB6EC617EC1,61496D9B4BA33C9B,86D21FADD8F971B1,846B5D081BD0BBAA,4246650BDAEB66E4,00000000BB8839A2,A4168E3E2662097B,7CCE694E6257FAA6,4090C55FAF7D4F5A,AD41323B1BFDEF80,17C9A0E3301B3FBC,C0A32CF7B884B6F0,62B12714EDCE57B5,250A56A91AACEB3D,326B8110C4E42D44,00000001A1127288,99B76D5A92478668,F98E82F10BA11E0E,F8965B56F42029BA,806AC1EA3CADA7C8,64B4C1A762C532F6,28A2CE7ECBB49755,70649676389AA360,FEC48A106BF3BCFD,4386A55762AED59B,000000014D8BA5CE,E06F2D9A0ADD20E8,AB8E156F5DA77B84,99251B821C70B313,75209D3079535D4D,88A2F8278C5DDE28,95EB3486D88D8ABA,2DA8571D8C35FA75,0707960B2E840578,E83477D02EE09AE1,0000000233E750DA,B20C4F9259ABAA68,0A88712F5410FE02,E7D1DF0C078D5F8D,10D2ACE2B8FEE6CF,4874DD476E33AE6F,8A9DC49D76C575E4,8A6C4EE082BD0F1B,2EE343D3EDBAAB7F,782DF49B60DFAAE0,000000001D3CF6EC,DA039DBF649B76F0,4F1EE60413E08EC9,31B41CD288FFE9E8,BFE3D7FEB5B179F5,1813268CDD6035AE,9DCF1980BF4D20F4,726851313FA7A58F,09672EA2698C2934,C953FE0A1984339E,000000001E8555CF,97DE6B2CE588D2E6,EAD1E7B8D3742315,4281015C056B41DA,07BA13EB939F0389,979D086D3702E0CA,6C2EBF075712C2EA,265F91A8551F6A90,6C872CEF618BB4E9,10F4E82C6ECB568E,0000000105E731C5,E77A66D1083FEFC4,AB3CA15697810493,B3A732490707FD39,549C851E6187EA7F,B2E0605747D7CC12,04FE14F316D2C2B1,CC48408467541C24,2293EEDD324DB79E,33EA5662EC9A13B5,00000000F7C878DA,C55FB0D9995CE980,84128E82587D21A6,FA293DE0BF54F650,C1CC805EEF4F2565,361596C7BFF7E59E,13A8AB93A61BF17F,A7CE7D5703AF21C9,6C75640667FA542F,21646AEDE30AD0D2,00000000A1E5ADC5,E8C14E9954441911,BB751C7E4503B610,9DC233824EF39E8C,9C6CC2F0F5E66BA3,2328850A7E2E91FD,9DC18006E2959348,D178627DB883A560,6401F5E27FB2F056,AF7A85C313E7C233,000000021BF516F3,BF82CF53F7BB41C0,B62D0AFEDFBC99DF,091E3CB099986CFD,FAEB3EB957D8C9BF,95C44321ADB4D834,219F7193E2E596DD,84BD45B8B6BCF5E2,7A141A32855421A8,065ECF440C0857BF,000000000556255E,D33D853CFB04C515,79550AAAFFEB01B1,8E243EADBB6701C7,A116C9BA0FC18E03,C6EE1B25B4D2B756,9474A3188E820134,F638987EF8C41994,86FD25D79F9512D0,FC74AF1E53A4AFA1,0000000237E38215,7F8FCA49FE36C3A4,56C33104C810A9AA,D24199045963A9F0,68AD10AB825A87C7,E8809F85847F7F72,73AFE69BC5749447,384BFC3193963EF2,BEADF96AC12E785B,C31321638225671E,00000001840E6952,E1AE87AE6F1FBD09,E5F5534F2CD246B7,A8CD425A587A69B2,DAD1D1BAFA862E0B,066B9A0E0C25E59B,86F0932B0711BA79,D54A0E09798495D7,CA41F3A266933888,E2AE43391A457A06,0000000126C301CB,327AE126A780E487,126578E66CC2060F,407302340EB486BD,5D78B6589E80A85F,685A55148C78D9F8,76F981512E1C079B,B22F7153D28792D1,5114F84B078A0F9D,D21F2AE78FFD92A6,00000001E362D487,75B91155065EBA55,1BB54FE61C418ABD,0DFA14C363BC8922,54AD04CDCFA99C14,B143BFA276F78402,0FFDF77719435D80,25352491BFA22FA2,3768F23AAE737551,5149B6A1F9DD163F,000000026E742D61,B7261FED5A8BB54C,4982AC0BBA3B6334,2D1B6D690D240106,2CB4835781266769,43BFB8F39302EFF4,1249BB84469C6712,AD35848C228FC0C3,D63BD8F29D0206BF,7CAC51F4B5148AAD,0000000022DCE8E9,C041C66B0F965498,C32E7DF9533D6AC2,6B3E4BEDEA58BEBC,46561824233D17F2,7D5CBA047053D414,76F08C81430162E9,A7558F5D33B073B5,7FE4428E89BCE0EE,61C036FB9B8E32B8,0000000098CB91A3,6EA3BCD8B427A820,266052A007EECD7C,03143FEB93AFF16B,1661FC4EA8F1AC6C,FC9A4756EADCFE76,6CD18660F9BC8509,6E37828C7C65A540,C4ABB702472A16A8,BAFE492A10506BB2,000000001FDA5BB3,0904784AD9D2D0A0,E783ABDD0E5F6787,3EEF666AF19E1113,10E110927F450B5A,CAE5CA094A867893,85A5B2DF61792F56,825E87204DF3D7F7,694E5AC79561CC9C,0BA616986BF3F777,000000009D65C76A,F0DEB8036304394E,A5F2C85C0389DA69,63509B9D20613BF2,1E065DEC39C2FFBF,16A130524928F702,33F5A5E2947DFEB8,80442AB6BF9EA028,8FB9A1E6671F74B9,2D7ED8EA3C2B98CE,0000000178AB574C,8BC7A54ED1858082,3098FB596582E588,7077860BD9DCEB32,9907E975CA098453,2AFC926C7A68CBF4,ABE613BD90B6AAB8,49C6B51D3863DC42,2CCEAFA5C77AC4F1,FBBFAEDEA2414688,0000000190557DA4,39EDC186BDCA4191,FA65D343E4FD3C6E,297CD79F6964841A,1A52A580F51C01D3,E1DC2E6006A2A18D,4DBF1AB06EFE61E0,75EBFFF04D86E21D,3781B3D99AA6DEAB,D07B4CFABAA092D6,00000001FF634B84,A920327E0583F3D1,1800978CAA6C0C6A,6BEB8954E7B870D2,4962B0D7F3AB3255,B4B9D14EE4C675DE,FF4A0F6B413DAE40,0B03093813E2DC7D,95EA8B632C2BACE7,6A5859D4AE5C3559,000000003A215BC1,E4FAA5A71C338D45,BF24D6C14AF81A98,734AF19D0707731B,0D08A3148C104F39,2A6F9A04F6969959,AD8646F1580CFB7F,AA95D33BA454C634,740EAECFBE4D0C68,B719B3888F1A285D,000000008E01CE3A,C106E85177C5D526,184FE1BE167A535F,CC9A7B6A7B653849,8295EEEADA2062AC,AAC600553043CC4C,57E4BDD4D79ABABE,E054AEC1A2A226B1,976FA519607B111A,CB0803D52E8E00E6,00000001F051965B,7497A1845E1635CF,B59C119ACEA2C9F3,DEE7387C3A6BE5CA,068771557B1FFB3F,DC0C04780CA7662B,C30BB02ECD8B5B4F,866CD81710709863,E63037AE241F118C,93CB696582291963,00000001EC911179,50379D761B4E23FF,9B9ABAFA95DDBF09,956455A347EFEC70,B83A771B71727CEA,96365721C0096432,BB8DB479F3512AD2,12426567B6A6CF2A,D808FA559C2B4B51,0256D264DBC593B1,0000000026E16A47,FE640047D2C7EECC,7082134A09477858,B49ADB1193AB1C8D,AC4B045EECC9DC2A,D0C071CD86AC09EC,22875AE2A9E8233F,D00C1145F7377AB3,CF68B6F7A37FE1BC,D8328BD6A245B592,000000017C62FDFD,0A0279F7D488438A,8E54CAA7D31EF7E9,317E238A4D5A4660,98699BD9E542DE60,5987B470BC5BDA77,D7A46A46E06E7526,4EB2D3911F0C6FE6,5E878A1443B494EF,C6A8CFF9A4AF13CF,0000000193EF77D1,6E78C3DDF388866D,ECFF3F2009735779,8AE1BCFFF0FA486A,468DDBC2E679EAB0,3F009A2FF05868D6,EE62C36010986466,1B47A01D66196BCF,0F7C95BD1F857550,6AC44008FE7F8287,000000014539AB01,1070E13D1BCC53E7,6488D783C9D8456D,467B214034BDC4DF,32AA34155F9C80BC,CA62EDAA49493859,B79ABDED05EFD0C9,CF070568F90C1D75,E6D92DB2E94FCD27,036BB51D18DBD626,0000000118BD3D83,F9D1D95C29804E0B,E9F12C1B18AC444F,0D9FB5281880251D,1C7E8B0B361205A0,1617AB6D27D39257,00282B9DF3F4E597,C88694EFB973C55E,A7F0D13BD8A42C74,233B66285F5353B6,00000000482DBC63,CD2B6877F14107AE,4E061AC0FC7671F4,5CF45014700616E3,9A10FE737230DB61,71AB8E4AAC44D2D8,24F90CB35D6DE518,2A301D7E91070402,2D4A652312589761,6B12E7EA9C1E2257,000000020491C74A,52C06AE6E14E6C39,AC46C8397D4BE928,2E8038BBD5E407A5,B0336AF6D3F749C5,968AF38E05A03425,84FFC4AB9B32008B,B97584920C6C0872,EAC0AC82A13D3C7C,794DADE11357BACA,0000000234384673,C788F3E6FDFB908E,77C5443754E48F90,352A714AE258EAC2,D004276FF87992D1,BC4647C00FC78AB4,986CF329AA822FDB,AAFF4BF276433AC8,C469C0892661C1F3,81ACBFD38778963B,00000000B6B8EA97,D24635ED7C5378C8,635E741118869C06,9E52DCF2DE7743CD,AC7758E11429C987,714F8CD5B3F72A82,3470C8443AEB6670,633063BCAC8D92F3,4AB705C21F71C67E,1E9DB727CDD82D8A,00000001C88817E4,E16C9459F8705F6A,42DD8683855C9965,E3FCB08717953F05,0D7287F108AD807F,1E890CFB21AD5775,E3E6A4A5E1903EDF,FC5D63679B8D3EA3,692EC22C554027EA,2C08A81A6F8576C8,00000000806BFDEF,DF17E789492BCB28,68BAEDDB602B6877,509FEF9339868109,A02BDA966F33911C,8C50D0AA89705A82,72EEF72D9B66BDCA,9D508DA096CA3347,6E9900A4005E98C0,0F6C43AA53B036BD,000000017B6FEE43,A8E195A5E2BEB51A,1C4BC9D144EB46A3,E5E482F9295EBCDE,18ED5FD6EE087A03,BABF0F8D916ED616,EF336362F5FFE824,C21089040E1E04D3,928CCAFF03CEFAB8,CD8D8CB3B5A6429D,00000001F0136FE4,033F3C62573FA28B,2C0788E6614E8C55,4F4945240EFC44D1,EAA2DDC8A7E75DF9,AA2F6B6937577705,5E34C82595F0113C,D2DC5E8BD521B126,59E808B03DE5E0BA,7896C71BF1CD2282,0000000237148D38,947D7D382C1609F0,CB741C311A126BFE,ED41B84116A9D504,4AC65566097E7444,31160BF3EC282438,CCE5D3006FC0BDDC,09BF511905735A72,A2FFA734E2A724DC,711E52FBF184D5F7,00000000E8C3E393,983006A5FB88F719,9DAE4ECC5476BABB,BCCD7C22639B4704,9AF49636AB37643B,32BF0EAEF85B1326,8DE73144F26A3741,7B677A3CDBC7C35D,47BAC732A4DB6507,21D8A6D49849DFAB,00000000222CC459,B830D660DA31A720,DCA345715EDD772E,E73C8E45591AEA95,848D35956AAC5672,A4AAF3F477A4C384,68625EFE45D8C7D3,FFCBF38BDA3FE6B8,3F3A617445760F23,CAD1731DC4E0F498,00000000B4BF4487,5352F02F0D0949C7,8CFC3DDBDC7B13BC,44E29A847FF0F957,5FB8E9382B063B80,267543B251C56295,F921206989330EEE,9FEA8CFF7C56D4A9,C0EF14B76905BFE9,A3640C1F1D4FD39E,00000000E6719938,DB5BA13C74A62DDB,22E4658B5B652CC6,9F167C815A16C460,27CD9A0230E3C9AB,3FC5D88055A2F125,7FC77D69D821315C,540D19C29692FB8E,F42847988201AE05,AE459C0A2E93C21C,0000000013711701,E7842DEF3173CB95,06651651C275BCEC,7CA877351BE0AE4E,9C226FEA65A789EC,0E52AAF82474DD1E,335EACC58B7082BB,0BD8CE047BFA1CD6,43334EEFF153EF1C,4CC6FD5205BAFA0E,00000001C58BEDAA,8340CD49569FB33C,D48A01993EF4ECE2,0AAE5B8A34093271,98B3B7C7B03746FA,23F5E9C6D943FC7D,7CB86EE8D3466066,010D1A0CF6723C79,D47F66460F63941D,4B0264E98DD494C8,00000000181C4BD0,5710016B1CEB8BF2,B1D319EA4394BC09,C50C8A3A03EB0BCE,6BE0A9B553938C8F,C74ED1994C06F736,93CE7AAAF3D5642B,7F48691780610F41,8289B9668C67979A,68F559CAC9DE324D,00000001E28B5326,A552B1CE3DB98948,8D64904C0F82C2FA,4F44776A9D25ACF3,1402AD85C47ED6D1,0137FEF025FEF536,441F3E4E02E7FD82,9369DEF92E24E87C,871B5411F8B5CCCE,457F705D610E6F34,000000007755357C,41EE4D9B6B0CE5FB,D1BFB6887C6B946E,0C51643E0353577C,395F9B5DF8F0EE00,15DDD1C220F07210,EF169B081881FA30,66527990B37E1805,ED9C220B45546409,F06CD44D0DC895B9,00000002671A0DFB,F3319C2237045F7F,5196A6DB093F74E6,2976731EFB9F95AA,17567B9BA57ACEE1,A4661DD0CAD4C25E,D763BBE4F839D916,D40B4A8994CBAEC4,B35846AD18CB2B06,97CF5A7FF04F2249,00000002114DFFEB,52792A910782E731,A404E798186200D0,611E174C2ECA15E7,C7289CEDA85C11C8,E656623EFEF6E753,90CA45E4C7DB415A,C258071A4AC4CC25,CC67E213E2437D08,F6983A05D12297BF,00000001BBC7F3BE,2544AFF725F80EC9,32295884B963CC6E,8DA3D7AD35F6FE09,725BA2A23F9E5E5A,C0F722C050E12454,67E2BE7FAC69AC00,B911CB830598347C,A0C44BA2EDF2203C,7CB3AEE49F21919E,00000000871CAD6F,D93D23DAE2109898,10254AE504910375,685859CEBB9FE213,B7D354ECF678105E,0602971529054593,C34BBED54E354076,16B2600F0DC14806,D32A330460CE9C9C,EA2695AA4E2EEB47,000000009CE02DB4,1AE4B6B60AF18E1E,B3242DEA514BAF4F,09EB0FF67226A34B,B2BA162D3D033AB3,F561E106F365CD0B,3169024FC4220B5F,D6B5B348A2BC9940,C08B3B6C27EDA5BF,1D4D719BEC5285A8,0000000240200888,F685596D2D38D3C9,431F7340AEA02BE2,7526F86BF78A20CA,26D5D1ED0E6DF6C9,A634F6AF835A8A96,3B41215BB4C803CC,98CCA992AA073D63,339B3EDECA149F38,218DD09FC2F54639,00000000680E6EC1,F41A05CD0EFDB28D,5502D27E8E23B460,537518C938E8B0BC,9F5414EE6547ED29,11DB0F855EEFE621,5744FF1743F864D9,CF495439E76F80BE,144E54D0433BA92D,09403A0AFF7C429A,00000000C17B97EF,3C4E56A2F44BA2D9,75A8CC3F9D7F3E53,87331982B391852C,D807BBE3EDE105E5,5149398905045233,8467F0639EAD990A,B2B59384ADE7DA54,51939003E745AC94,93A2C6964F995063,0000000016ADEA5A,6E63D2D749F62D8F,DDA011E6CA109D43,B26F7452B4CC482C,FD674FD2E55A92FB,56EF72FF17986DA5,F7D756028040C3D1,E6829CA1DFC633EE,3607580BBD486345,6D0CA44D5367A413,000000025D03B989,EE93E8AABE02DAD7,1B92AF96F45B03C8,8324197344415E2F,362E2691FF53DC9A,9041FA99E2EA9CF4,9990567826567B0B,81BE3537C69E1EDE,167659EFFDECA9E7,BA7A05B74747F7F1,000000009931A425,D705BFC3579B77B7,D7168BBFF879D2A4,6DDE8E7B6FF45A96,D9BC64029F12B66F,011C2DB72A6D71E0,C263C9985C9CCC43,AE6986BDDD03EC59,72B837D3764AEABB,DBB0AC16F360D940,000000024644E447,F6F9ADC9A3A69F4F,9894034283218412,97F1D029962C6674,D7EA1A6AD4E7BDA2,829E25015DBA1E60,932435299E00A40A,4288063FA041F093,88BB5A88FCC55C58,67497BE7D7F3B7BE,00000001BD8733AA,F2F81BF6AD1E2AFE,66CAC80466AF00B1,227D94A5A03E8553,0A223ECE11A95331,4899353A4C332B0E,E7DE6D05B81EE084,8AA3F861D72686A2,58863AD4525CFC53,52F696D7DB643B2C,000000019C89361E,39C8A797D7A0B659,3E46479B27B7E2AA,028BC37C739EDE86,F703C4EE9E9E88A4,8DF882D61BF92C11,7C67803D7D192104,4313751A6E40644B,275B1C3912C9E5F3,3C4EDD93A499F4A9,000000016FD720FA,FA7AE6CD7B9A6122,4488C28B41604004,C0E6ACD0AEE30317,25418CFC469E04B5,44D0AD96C45924C3,66F096AE8F6C03D4,203C81CD65C46174,22C961DFBF8F1F19,C88798BE43383172,000000022A9CFC38,66DD0FE5D56E2688,6A1566B6BB069484,13D2DD7EC0DE2534,6D81E208B1A2EEA8,8B1B1039ADD35796,3E81156BF3117477,6D9BAD8C4D0D300F,7AC8306447E9367E,A80679540671BF43,0000000083D374BC,E41232D734B000D2,1E516CF0F887496F,B89B6AB09C1D0738,25868AE81DCC3CF8,78A3B06A6C938820,6A447C4DDB279C56,60C46038E271C4A3,6F21ECF669559BC7,4A70D32083F65124,000000000BD8A281,054882B1762ECC36,7BDD8E61FEEBD4ED,72DF06E6B5E8F0F8,1F89D723E85E719A,06E870B84838382D,2139E61B384C31B3,C7E636AA1378CD6B,165C9BFCF3EDE60A,D41F2C185CF4777D,000000016DD8B8B0,93E6840C003C6487,E45E7C7587AC6D5F,9C0989A937D33167,45A5535A7B5E9CE5,6FCBD21492BEBBC8,7E4FE309C3985CE1,6EACA073C30E32C9,AEEC5B1462EB1384,DC4050CE0BC76C13,00000000FDF06B56,8E935B864E0D11E8,E81AB704921BE624,9EFE4ACDEDBA0991,4BF0EDCFEAC5C270,D4CF5AF46E7FB0B3,E35F056897793D6F,29C0B3EBC9C6D407,4B59B07653594C8C,35FF7D13E29056D2,000000026CF88696,4659227F00230652,C1DBA73807FAA412,F21206333B01A08F,DDA8305FCA2595A4,531FDF95228E5142,D348B56DBCAD8EE5,BB7BE5C924E10E72,6317757B96AA8A3C,C79E9428BA805803,00000000547551C4,E793EF318486A69A,C34D3DA87B2B63D4,10BC44AA520ACAD5,6549BA60B80F7CDD,ABA0B64296EC5DC6,0EB5043160089C02,0CCC6F41CCC0F54E,CECA571BACE7E846,D7D58C0783D7F361,00000001A1195361,9BDF10BBF3656FF4,805991B1922D1DFA,98E54C6DE480EC95,08D27F0E7E40D94F,58296885E9F1E2AA,95DC69C6982A6D55,04B057D711BDA0AE,0545D9210DBC6539,CF21ED60A1B99232,00000001C6251918,239B152E2D558E64,A898D779E5F3CCA1,17E2C3D1868406B7,E135B52E2F6DDE55,E68EFF2E49FD0D81,A3D2821E570D9A04,A0E299E022DC9B7B,8B4A5420E4EB0AB0,DCBA05D1D24FD230,00000002472897A7,00586662FF53BACE,30F2646AFA8420CD,8AD15D2F02793738,9EF32EC2062D6F66,297C3FFE4B440551,73B5EE0CD0311845,315F8D14B9D22EE6,14C5658FE9A8ED3A,CBBEA460221393AA,00000000DE3706F3,52A66B669E282192,4668E4EACFEC370B,46F7463C7D052FF4,B028DCECD92B3195,5062D0EC1360F3F8,682983C821E2350C,E75716428A79B34D,C5988A49ADA57756,17EC26DBCDFC535A,00000001F2D3CF58,43B6E78847E2BDF4,445933F36ECCB1D3,BA888C5BDB9F3C86,11C16C8A2CAB5951,10F3B767CA89CAAD,3ED79895DC63779C,0BF5C51EB1BC3A78,371997C68398E6B7,568DDBC3BF714B93,00000001AEF56A34,C7FABA1F486AC68B,B05B18E82C317642,EE405FB81BA29951,8019EEA216B5DDC0,E1EB77DC1FAED455,4A0D2D941BC1A348,E54A21190E5A069D,84A91F134205D5DB,9C00B2F853140B67,00000000C3515640,8B8A7D10525C1B24,46B587ABCB1C1B79,A71C95D68070903F,5354C881E5EF7105,546231EBF6C06340,4F317DA7FE877D08,B42A2001DE4C1F36,AB44E3F3654F5458,EBAC6C61BDD50153,000000012F7AD072,07B1EE7E9E7DCC20,3CF5C356C5EC9AD6,C97C7B5A096BCCF9,2075928CF70F6BE8,21BFBCFA174D978C,CBF2890CACD07331,B461A347ABE171F3,299AE34E75541796,6D3BEA306B2D8F5D,00000001B061C9ED,A6DD9ADD70B920A3,9C3C0EB9C8E4DEB2,7CE28FD2257AE0C7,E8DEDFD737CB2459,937D0180B970E4B3,BAF4DC333F43B8D9,3E3FEAD26C29AD3B,8610062780438D31,6B88631FA95DCA7E,00000000ABD00816,96142C29557917EE,3A67F707EE8D6B0C,C287069CE1BDE0E4,A387ABE745780641,3211E162955ECFC7,7F6765B3C30B14DA,C5EAFCBFDBED667D,23F7641BD3FE9FB5,8CE94C04BD2D1A18,000000010AF5FE75,745600F6E5D852CE,5D49948C24709B30,C5BD78134B4F90DD,B4947914886EC769,A0EDC9892BF4A862,343AD14AA76AEF8D,8AB6E63EB7E72551,F31D428AD6DCAAE7,D759F16C57B88A3A,00000000E2352337,81E1415547E94D2E,EF6A808B3BF12645,01FCF50D0B5C1970,E466EF1091AD1EF1,44BE3D312E104F4A,1691E1C85E18967B,053A9D744E58BA29,705C3EAD656476FB,6277615AF73BC21A,0000000188BD0BF8,269656F54329E0BC,311692FE11597F45,4E9B05DA5A9B9939,6D96DEF7B73E879D,639AA90BB22FA4B2,6F8409C3C3DE09FC,3C3C150EB5718447,601BD807E8EEBA57,B97AB8E024B9CF36,0000000170C47E13,69F0E0D7586024A7,2C2D570E32C07EA2,E202BE8DB9D05A76,5C169ECA6E58262D,2B87481D672FE3BD,769A2B340B83217D,7014FBF7AE4CAC57,88234338CCFF377F,73D72E9AF5E44C6B,000000001AAE23E2,D3050BED48CF2BBC,EB5A0B8B3D079DEF,E93E02DADEE441BF,6872CDE89D72EA0B,0D6E80305F772DDC,97C9EB4FD013D6DF,F42CBDD31E89E520,54F71BAF3A2C136F,E9FEC3D563620CE3,000000026A3DB70C,D23DBE32B2C0AC63,653E81119FE79F27,956C7F9DC9B49E76,557C7778BD25473F,485F729405172919,3284224A2CA51107,9E7A133DD991E56E,7FF57BBCC7E99B63,78F0693381852C6E,000000010BCF1C62,B1F918C6980C9E17,5D6B5D49AEFB2458,41274BFE5CB2C5EE,9BF5213F6152367E,E91D42F010C76CBF,836EDA14994E6FFE,71A16B314EF9D450,BB56716F17C6A2B1,F4E0DC5E7E46F9E3,00000000C45A06CC,A1FFE38B78EE11D1,DDB60DF75C0BA660,D799A2B2C4B5F7D2,A324151C1FBD38B9,5CAC50961EEA6245,3994548585A83840,904660F1C84127D2,3D7F6D3BBD6DD055,58F2C451A77B307B,00000001470C3B5B,512838C07EEA7978,4CFD709B20D7A424,F516C5BD7F6F971B,4CC37CEF79EBE0E5,5749674EFAD3C5D9,F3500B95A771E2B2,55D75EE8DA1A5EC0,68FAA3A9D958AA55,730BDDF88417D4E0,00000001303A3C80,257881B1EC19FA1D,5E1CCB9E44ACBB1C,CEF29FED45C6EB26,8E8EDFD9E46CAF56,188F77211F520E28,7818EA44E62B5B55,95F1DE8FF80E370A,54607F3DB6D7F565,A1B876C796FEF979,00000001BCC60726,21AC8FD31E882581,5F39CE6F2828F083,0BD817B7A2D5E856,038C0604F0EF85F0,1864E7E840DD5253,C23CE580370A17CE,F72D8DEB04F94F41,0AB60795AEE15E40,F0B57234FC009168,0000000025E45959,288706F4EC67229F,C263CC8C97E54316,330A953E252E67D5,9DDA5F002E1A91E9,8E4E6FEB02AE1FBF,B3BD9223E152D2FB,0441D22C35418DA9,402A8F2800EDA8EB,DA02414ABEC445EC,00000000D7A3B238,6B24650E6EB8486D,0C56E88A7DD742A6,5ABC0ED82977F0BD,7249F164DB16976C,79E5832E99CF6B25,09115B1D40E5AC53,5B76086064F15A88,D1F5A2B61543F955,213B834674D79593,000000027AF18D58,0716207E918138D9,D039B194DFD0C6C3,A6BD1489AF130B9C,70EC0D2F62A8BA9A,8F393790FFC3C07E,487F08148AFDCEA7,C432A3B3CD1ACF47,F0D553796AF63D90,8F68F417C095BD71,000000020CC22ED4,1070B1C8479341C5,48563D27595421B8,25E9C03267332325,46FC05D1DCEB0E9D,32A04070031A56E7,32DEAEF4B30223B4,CFA96BB4F3560026,79CF3D0AF4F9E033,BE232301904CEB35,000000021C3AB054,BB0F02F00401B8E0,65D306D6882A711E,5E637104585C0175,989F9332F7E276DB,77D00AF671D9B2AB,23E2143941C14C95,46019E84708E1A77,E8B90E79EA21C757,69F844A3A2F124DA,00000001178E9366,78AD964ADD4CCB0B,7A501A5F64C52FEC,84D88E49A68F4BC3,FC6FBC3D07224695,8F2171B4BC9A284E,1A41257B79D074E8,126703B5C74B23A9,B61192D2A8C45191,A090542A417F1D1E,000000017E46ADD4,C057A1FA94C76240,219E64F335724259,B6D9C2EE8135267F,D2D6C61931111F90,4CCC7DEE6120B40B,523C6648306406AB,9B70BFAD695F66A0,50C7836C74B77AD7,DFD7222E2696597A,0000000167343944,148170A0825E932D,B11812B638FFEF91,E4344AC212CD5A75,7653EDA9C1876889,90645CAC59A44EE1,49B9BEF51C19D1CF,D61324D2C3FEC121,B7F1EB844A77ADC6,691EDA9479A83122,0000000051217CF0,E3FBC84BD746BCB0,A5B496BE922AA18D,FA792778C7E23309,472B48D0C6D6694A,3D21D73D3019F5FA,171275F00D32C756,AC9EAE429430B3FC,D12E6E0E27B13738,9BA6723984FC78A7,00000000919454ED,B946982D264A6778,DF907F66284D6E23,AC604EE17E6E6D17,208877618F1802F7,D848B1B58F69DBFC,D15A173608ACE0DA,092B6B0AF9F6DE19,F4445039E1A5E1BB,E18897D77C732533,00000001D0E135F6,B5F83DB68A580E90,314980253A769232,0449D1ED5F4B8B5C,D2A19F9432F339CC,02A47E40D5970D6C,5CA62C423CE24EEC,AC17CC6AD42BBD43,FEE2190285F4BFD5,A4AB7EFA38D05456,000000015A06DACD,B72D3C162F2B5EC7,DCCAD6AC4DA7C22C,714F895540BF540F,E6681C8862827EC2,7C2385323550C49E,2204FE587DD635BF,E1A6C6A8DB257897,F2AB379FA3CB4E7B,8745350AC8E81E2D,00000001722DA9BE,FA62F300BF65EA7B,210876FE36C4DF8C,C1E380AE847F769E,CE5171073ED0AF83,9D7F0690506AA6EA,079DB0BBFB7DDED4,800AF71AE9B90545,4D8B4B5F182BDC5F,17B7ADB02EF5F3DC,00000000395BD61A,742B4F9D6BAD1169,1786B3BA0B4273F3,13F94CC6D8A568A4,A02668A58C9B7D5A,19A9E6564677FB24,993411A3D956B5FE,635AE25CCA82C6AC,94F95E65D6EB3285,BB81492BAA0C162B,00000001852A79F8,17FB0CD68E5E4B25,6C1E1EB75D84A36D,589B2DDC6462F15C,CDFBB4FBFAC10D8D,718AD2A02930266A,6B3DA414C1A979C9,589D2E04450628B3,3613301DFAB2B1B0,5336CAAB257D50C6,00000000BD5A91D5,67D765AD1AB61E58,585551AAE2141443,0B522F6DA80DD1B9,E67A4BEBA229C3D8,CFB3809BE56CBFA9,17678B12D2DBC6A4,2BA355C3BEDD9683,4B062AC95C1195D8,812BB8861F138A8D,000000009FDFFDFB,7BD79D447C189C91,9AA8D6FC651A684E,9BF4CB276417AED4,A480C420ADE0C1B1,D433D4B2AD1869C2,A3F71EE34A1B0DC1,BD23E280C78D9134,55950DE3935E4D00,26E55E898E3724AA,000000000DBC5CEA,B84B2573212BAA5C,67D7824566A63B1A,389947CC212593C8,87A5F033544E188D,C67E423E9598230F,458894561E5E37BE,3CA92CA94877C6B2,AEB49FB3FA789824,F18BA860E8111BAA,00000000D47A0E27,471B6F40C61D9B72,1A5A9D460A819023,49A1F336059511E3,F4E432E383DF7345,A164B925A6F1670C,E8B0F1F94D9B686D,DAAC373B0F81975D,645ACE7EF4BBEE6B,4F23A4C8E90A4A71,00000000729D7A3F,1AE1C4D20AFA7EFD,140B956AD703B3F4,A33EDD7EA026BB90,D20B65D62D7B8520,5E987BE4BBC2BF98,1A67A3E951DAEAAC,A73AB02CD7EC4200,FCF3070C4517DE20,36DCFAF231EAE4B4,00000001F2BA551D,C14E51F37952C124,F82E24FA99D933F8,054BD16DC29520FA,0B9A840B00839E64,88D628C3DEF9D3E1,7675AB3E2BF9279C,04B8CBE1B00F9DE9,AF9390ABDC16C232,086C3D1DD5FE0F65,0000000035F9BFE9,51860E11179138AD,BAB073EAF2F839B7,9E22E144AE6BCD5B,7DA19D9BFDF4CC71,5B03BAF28F7730AD,EF7CC9157D95AEDE,0EF863C0DFA37DC0,5F9F03C141B1E2BB,E21710776FDEFD4B,000000002449F342,3D9E1F5A3244E742,A0A8F76A2D1C38F3,E7440B4D4F888BD2,439A8764CC8955A4,8F9C9FA23862BF70,B85A58EB52BBB781,DC1BCF4EB20B191C,08B1959A50EE4281,8AC8D83C5F9B9E3D,0000000227DF9F47,4D6906B671C5B0EF,0E710ABC3CB36E1A,60C2F4AC58BB56B7,D5C12C994CB0AF27,5CBE2D0DB5AF4E92,9CC1E1EEDBAF1E2F,18994AA4197B5CB4,7650DFA017E70C7B,E5F11BA1FA9FCA3B,0000000224310A6B,50B358B27C7CAE73,2AA8E3CDAD7B09A5,497591A46FF9882F,6DC79A59F9D05D10,99A04340E724D8FA,8F9B328F40DA9E62,A554FCAC85F54AA4,EBC2F1E428165EB7,7B00AAE3B658AE5F,00000000DB5677EC,B78C6440C5E3EEC6,DCDA187EF1E34C85,D6FDACC686345A55,D8F153F0C181399D,9D49C42D0918CFE6,8E312B4DA9341878,97ABA0DB022264F4,5EDF7F7ED5908C36,2697E4D4BF8B2CF4,00000002740B2255,1112CCF10F9AAC6E,806BDE764143EF27,A79F2D1276B641EB,EFA5ED7C5529F75D,9C4F87784388A52D,FF3B140A1F307255,697F943C57FAA194,F79148412FD675C9,8D6D44529D5354E9,00000001F9CC77FB,0DE759FEFB49C086,3C73A28C867C2648,D7BE5B8924F51B6A,2E6A99AB53772ECE,8EBE0603DB724A17,7DBDF03832546F48,A7D612209AAEAF8A,29E824F677934B9B,3542E226B0145408,00000000908B6DDD,5585071F3A9A03EE,EEF125806A3E8B7D,6896967586D57BFC,FCCC3E1F26E95520,18A5171E46F7AA6D,B38CD2DC6DFD7377,24766181A2754381,6264B5FBFA4453FA,BAA288D78F6FD5EA,000000017E49B0F8,55E602A3A8878CBE,C3D869EAF498C26A,AF34A98513F29BF0,511B2E77C1D922C7,8306D73CBBF36C34,987D465F7A9672D6,34BF91B07152EE5E,8E62703907FE6D77,25630C6480B7348B,000000026339A4D9,B696688FE4D19AFB,36F8F02FAD3DF062,D047AF3B72EAF4BB,CE61268F9CEEEB74,E6E809DECF601F44,C9E9972099114FBD,C4A39E31CFF77FD9,8A86C3FB8C0127F5,EC04580431411C20,0000000039BE154F,F655C2E23A72EA8C,C26DC386CF1641D0,B092B12E301EC7CD,205A3FD80C9E74B5,6942950AB2E36229,9C7124EED03A60CA,5C815564D64FAA97,07ADACDCB6FDC86C,5ABBDCB9D9BC98F6,000000012FED6EDB,8B5D9E0FD7015193,89BE16B688BBCE07,849A1B14FD1F0C74,8D067619F8317974,84A6811DD67CDACB,C5C96CBC22387ED0,579233BAE836AE0C,DE73931FD3AA373E,9F4604518C160FC0,0000000050330D64,D3EF1DC3B7094CB1,28681982648F8390,4E42BC7D8134E44A,A1A3FD01F9BFC721,21BE719F374B28FF,1838D35F7E61A391,6AEF78D5C379080E,6D875B6E5B0AA2F1,3CF85CAC6F3400DF,000000018413C27F,B2C277AEE3EA8B6F,2EF02131B4D9A5CC,9E3F78C229BC609E,157DCE66B8F0E5AF,F06BFB5CB2819BBF,8D021809D1E59CF5,913F85FBF11267C8,8546B25DBF0DE6EB,8EC3F9573A5FB990,000000019E988CB5,BC0F93E7A01839A6,E1CCBCE7A0D1A095,A78F5D51A88C3E34,B8182ABEAABC182C,8B1465DC58A1146C,27DB7C66064558ED,2A7C9445E4F32313,B314CB8D2AF8CE73,3ABD3C04F3D15BAB,00000000B3D4CB4B,AEC586AD2DB82739,87173C2519814096,50589CC0BCE996CB,DB4D08A2716F0FED,41F48303C36D5F14,4243FB9A87451680,FEA4AC8074F92A56,D8DAEE21801D8BD5,612A638B71645389,00000001FA2E20EE,DB9F05ED0E7DC885,B8BFC2F81EE5B6A7,39844A8DCFAA3E91,D9AB049850CD6DAC,64231A0C7544F729,B3C4DC8B733AF9A5,E6D25D2F232047A7,1397A18383DA1336,10C1EB5C459B0023,00000000193D7DEE,B1726716BB25B69B,22006FEB3E74504A,9C59E19748AD0635,52F83D0119E7D9A8,002F066E4377979B,30A2E5D68E9B0FC8,CB7E581A64C48933,54BA65EC076FA8BF,D23442873BFF66CA,00000001BB4FEE08,F97D0D6C513B6BE1,D05E27799E481B30,61765AD7D0D748B1,B1FED3E68F1468FD,28C6292DD1559D70,7B4370FF66013490,68761A0A4863FE22,B7C030714449FA78,2B7D35C89D35AE12,000000018D8C4A3B,A89D5809CA318AD0,D86DB68AE1035E5C,CF707C51EF005205,7F8900FB7A842C12,6C4F81A58BA51279,4C39AA89239A441C,8019E85E157319E7,8D007CF31DD795B4,F136FC65F83FF4D3,0000000112A20050,B616773ADD23D8AD,C52BC6601A0E1944,88BE34804EC1DEA3,7F6011A0D4AA3F88,D9CAF3F43AE4BA05,4554491575D3A7CF,A0584A088C02F819,651077CEE57C072D,1B5D799482FDC50D,000000017C914538,B8ADC5DFCA4E735F,FEB0970983EBF88D,C6A27DADFA596DBF,5F82A0A1CE753494,D7884A9BD7293F35,537E512F6B7AB88F,95AA38E055A770A1,1225CC31006B791D,1CB4FB4C3B5D0222,00000000A024A51E,AB5B9B3D7856C519,1E59267611DD46D2,C39C7C7566422EB3,8005F5060A59C1FA,9840AD9751CAB080,3D485EB8FCD885DC,955FBC12E6196257,B446F46645434D00,15B716342A3EBA07,00000001742F072B,17788D5FB14D092F,53FBDA5D9E5AF4E0,AAE45DEE84DDC466,69D3151BA1651B22,44E7D6452DBB2600,5FE86D58C8FED5E6,A6470E5F6035C95B,1BE5BAC4004B2271,E8098A55855A5DFC,00000002196C10AF,DB831285255E66F1,B240D3B5DB8A77A1,625BB1162D29893B,C8A014A8B93B1153,130AF484EEA977DE,D5680F1F532A5B50,C7AA22EC6DED84A6,1EA7A46E8BF3CE5E,F0FC92E1A8CB3FDF,0000000090393547,4109EE27EF1118E4,8763AAF4FC062292,A837BA60F0D45DB8,98FCAC5630F66AAC,A54970A98CABEC5E,BA2EEFD02840D812,81133B835B81CDE8,707BE804A51012EE,6BC1C332FB15F9B8,00000002624CBFA9,55F76DCE96FB5B7B,3C212472D700DE72,7300F9E8873989DA,7C65882EE85E8712,463085EF56BC1786,469D4C029C14C936,87534E6EE3F33BA1,1B888C7B13B6C275,80B3155ACC6AFB3B,00000001266056A4,AE4780F6580312E9,4E5CB70BC0EFD222,6D4B58A75A89F602,B3EEB7DB8C7B0D7D,2939A77FFD8215A3,5B508E4F360AEAC1,98C7D5CD059934B4,45A432EB07AEEA4B,C652D34767CCE6D1,00000000367A84EA,99151F2685F4E282,D34081C596E0553C,9FDF2D9FC5AA5FC6,5F3D12BFC1D5610C,4DB297B6689ED4E7,AD2D60A2F58C1B02,3E5D1C830BA7E5DC,9EE7BE99E45BA0F0,D2D73023C49B5A5D,00000001F0A246A2,87EBC2DDA4180143,AD25BAAC72735AFD,C3B4FC27E0BE004D,D12947AA3FA74DD5,8B825325100E410E,AE982EE66C8A702A,5717A390D70A698D,CB2B0B98D523EC23,10F4E916C2187260,00000000014399B4,17F0488E429D25BB,732B4DC78E6F8289,90D6A234776780A3,5786E3CEBC65A5D8,828DC94126B56D6E,7B7E6BE7FB4A7C7D,47E4714A790EE4F5,70D998F1C4D6261A,68F75F3EA21BEEE7,000000017BCA3AD8,B850A5447549603E,FB215E9627229305,E3EB0633683141C9,F56FA3F9EA8D498E,C7A589543D89B3F0,7F4D7D2AED59AE9C,AB66829E8DF59873,B2828577767214EE,3C2DF31B7582F7C2,000000019A4F4B1B,0A6ECE4C272735FF,6983EC627BA1BC33,4E710DC645C0BBAC,05680019C8EFB430,9F3508EC793E9C97,8F35F81B13FAB71B,6213FD7079ED1AC4,A0D28DB5085F335C,22B235922773F21E,0000000144974A7E,0F0F32B5B7390B43,99548C0BF603C22E,F5464AEE2DEE5CB5,BC53210B4D2C9605,AF406F80EECE89F1,484A27C082FA5C0C,8FB7C7F774369CA8,E48D52678EFA5364,2C11BF71810A0DEA,00000001E6506C88,021FED8B2F6BF0DF,1E0AA570D6D954E9,F50B405FC10DCA27,EC2A9C039648D322,F63A6AD8957685DE,E8D8E5425E4E9DA3,3611AEC3AD74194E,C4ABBFE5A802B85A,7047A685E1C672EC,000000021FF5089C,E373973B83C9EEF2,9AAF5B4C6B008D00,EB6F3B12965F89CB,641CD2176ACFF942,EF12AFE829211B57,8330162A88932907,FEE98CD35259FA7B,C0641DF9E951F9AE,D14CD0E67E76AE52,000000023AD38F4E,B6C7CCBD3D478A32,DB54DF48FD9B5C5B,FC00B7CC79AFF5FD,9F371FBFBCF4E771,5F21F666123395D6,5A5B3653F3B36F4C,BA1955AE7616C87E,7C7E1906BC45DBA2,C396A12B67DA7381,00000000F27C52DF,670C28859B238185,FC53EA62B90C0FEF,F997EBDB8DBB82DD,2D8F9DF19D7E822F,4CA0C0E981E7B9C1,7752E308099A3C68,D727DC950B6D254E,77D177CA4540AC92,FF5B45286807988D,000000009581AF81,AFF6A79799B4760E,30E16BC07C7D9009,55A276AB588ADE4C,D3DB991FC802B6A2,1E0D83D723F6ACA4,6200F446803226CE,984DBF2B5D05771C,08D260FAF4744F91,457F4A423EEC0A42,000000015DC506D5,87741F2B324B8D1F,1CEA26EC42DED407,5E9A99F109D81E67,CF9454982665CFA4,B09843AEBD078853,71F4030ABB6D2CBD,D695A4C211591181,2C75BF7F11733D14,393C6DAF63215D5A,00000001CCE256FD,1F77B2F895A4CB3C,6BE11A9394116CED,1843A1828C86EAD8,D87DC93CB6209E9A,7B7A1B7C26D860FD,DCAE39480B866DDF,FF920FED6D25A38F,B1770DF5BC9EEAA1,372F9CF9E2FFE12F,00000000DB8180A4,5E90E12AC5C718AB,1C2F34478380C873,1858EC614159B297,63611E495BD2740C,AE2C511B16EF2B90,A6B2D1BE2E3FA769,C696D88E55B1A6A4,575EE7ABD78266A5,8017CCD072556D9A,0000000258EFCDD6,28EC66CD451106BC,C85B323A7A647CBB,FD43E424160F21D8,E3B4D9D093F515A4,CBF2E462C421F204,62D70BBE7C8FA206,5331DA5A14B4D51B,3D38BACBB532D3B2,D0433C66CECE6E89,00000002518E8B4B,264D44BA3055B82F,E39618558E4F1AE2,C1908ADA72AD52FD,EFACB76CF8AA87B0,3D9F95CFEAB049AC,BADE3EBF8C38B24B,4042845856352CC0,07EE6C35A9711029,75A40DDF3BA89359,0000000106C415E9,71CAB998CFE56780,18024000C0806163,977CE6D5F692E523,23D03D3462062177,A9CB214AA9222361,A006FFB0238BBCEB,4940BAD990926716,0AB0799316958502,C4C24E7E2B99C7E3,00000001CC4AA387,8B665B9EFAF4CE7A,5E5F55826CC0C02E,044E388323CC4F12,4080628C825AA4C5,A2DF67DC681B9253,2B39A4D145230F40,9029AA3507DF34F5,9C1FE1100750F8B6,7CB7A237E6F4C49C,00000001DA707F8D,E2C942E9A6A95111,63B3419D05F51C1E,2FA569D73E2D3DE6,7107406BC2715FD5,1F58B55A9B2920D8,E5C4F7FD4BB972AA,EAA6322E5CA65C4E,150FF31055D784F8,79727B9A333112DE,000000009F91209D,847CEF44BA6B2383,A470CBBD7F95DC9B,E8CA92BC72E1E5D5,5C729E49EF0768DC,49E628654779CD60,65569C2C570A8CBA,AF2459C95C894CFE,A96AC4D6343E3723,E6D36DB9005B16EC,000000025BE5048E,18D79E84558AA723,FB0A6A6DFBE2D146,240C9A12C224C771,6B0BE2C20E1BB6DE,55E5D3119B17DEBC,3742394D24C61659,ADAFB41C9CB49C20,EDFFCFB0DB595AFF,9B7AAC31628FE13B,0000000043CA8E81,4532D359AFA4BBD9,B1E2588F45CF2DDD,17AFA553F15F651A,80694DDC3C15DDD2,F9EF4D072C3E1480,D12DECF5974BCDA4,E4CC7D1F13AA9D04,066CB5B883A543D8,604FE08168B9B727,00000001C462D98A,189089F20E8165FD,B6D3327309201889,603CD9136B6F2AB6,D527968AF059186A,378366AC7845A329,AB979F4A5818FFE8,DBE60499B54A0484,9664B1EA715FBDBE,31B168817B6ED5D0,000000004AA82BD5,E74A4D9DB911BB4B,8D0AAD4E505192D3,C1B1982426A372BC,5B7DCA51A630BC9E,77F3B4B8E26DFA15,249F3735F227622C,B6634EC70EF6FC8F,C97C34CD07F13DF8,5C6FB1513BA7F7A7,000000001F40B34A,850C1FF0DB1FACB4,CDEAB62263023401,888805708FDC0F4B,5E3DC860B33636FE,8A15016C14C19A26,D9ECA421E8ACA694,9B561233F946EDAE,FEB5FEC7A9C23AC7,A6460B1321159F85,0000000011B7E017,6F37016398E6C5B1,987E817E8FEFC5C0,62B55694AC40B3EF,715B53560A71F42D,3E5C6D2BD62A90C8,302156FF34AD8C22,3B08FC83102B5595,FE2D1EA90B0AE648,6A85D7B46BAFCC69,00000001CCCA7C5F,54878D156BD59061,C339AADC7E3059D2,ACAC5EC880394F87,632029B6F33C8643,EA974D3F0099EB00,86E64A85C7143CB5,63AC026349601695,2C9EB0811D69D3F4,01FF57FCCDE200D2,00000000396C79C9,38F3341C73CB3645,EBB0EFFC42F702F2,15D1F16EEA8775FA,E4BDE30F1ECF1B6D,A49FD87F08C116FD,AE2CFB71F1195AA2,33E4488B0BC219E1,C508EA55003C57FA,C8E8EE3314F600FB,00000000207D434D,07F8E80157305389,C1145AAE9E0F02AF,9DC62B5D9EB94F7E,A5CB206B92CB5910,FD14E9E5BC35D24A,F4D447BC8536F2E5,CA459B39BAD7AB2B,71B78AC27C201A17,101B6DC5D33AF5B8,0000000198C04848,38FDB129E961568A,0091347D81C8B555,7276206B82E24AA1,A335E24EDB37DF66,AE1C32385968E9DC,942FF74550B5C5CE,5421B9BBDCCEFA1F,8ED81E5725FA350C,9B16CD4C40AD030D,00000000BB940E0A,85984B6505EF0924,5269CDA80049C4DD,A07435B0CE6F02E5,D84ADB43C01EFCDC,8C983C4934E241B5,A3C4F68CDBD20C86,8A9AD9420E6044EF,09E23E8C8B322BAB,5F5DB7E4B5A10D84,000000017F3C9FEC,BB5B99E9AD511281,6BE339763DA8D453,D9D573052564DFFC,4C9018E45A539B64,4AD1573A9E558438,DB95BB8A3627EC58,5F3E134A47EA18AB,8388C1D7D33F348F,268DA2F679516EA8,0000000166F94804,30CCD04A3500E6CE,6AB6E5A7D6C96300,17859630008A9D3C,246F76FC100F388B,4773DA6EF0C185D8,263AF4B8278B43C4,4757FD0C693D09C7,3C6884CFD0747F2C,A34636B8D7CE8970,00000000261FF4BC,E8DD25E6C3AA9689,C4155CD8E0766BBA,CE392C3E563BE329,5D26F482F95F5CB0,8474B8E66A7E5792,E249F5DBAB019092,9BF94A356A0DBE34,4207B3FBEE8A059B,63629617AF5F3620,0000000121ED1500,6F7FB1AFF6F3A595,00F02ECE677B405F,B85CB5C6776C0B1D,6420ADCD1B865EDF,3BFBFF72E448B757,6DBCFC9F0F54F629,8E752647D601B8BB,41BC6D37A3EB0529,BFB3E7545D49B714,00000000C6D6FDCB,7EB5CA86C0B8C53C,7AD4363C7C068D59,5098E6A5A6C2FEEC,2A9957EA02E73CD2,41C99E13A2211575,3EB2CCFB8AC55C95,05AD6DFC4DB18874,8BB2C2492A4708BC,8BAA4F25D5376144,00000002705F7E81,7624D635206C26B9,B261D9454E1BB395,C8C98F2B4B89A1B3,A717703CCE306B31,88138748216BE6A5,CD0DD54F823B0D55,B56BFBAF22863403,E9DAAE89AA219DAD,C451AFF5158E313E,00000001019FFECD,7848742881C6B734,72B90A6670FC88B2,CDB2B4192F03D94B,0951589C2DD05E17,57D99A525CE82566,542714354E24C5BF,44053FFE2776C146,94D16AE3FE767D81,6FEC8BC494CE0241,000000013C6E8696,CD318B84293261A3,7982E165010A1786,E2B6804FEF5E40D0,07047CB3A07BDF87,80FDA2E07451AEC7,4797F22FD4947677,9FC80476DD9CDB13,9929CA7838F18A11,1728E259A27CC505,000000001B158E83,DAB6925D4FC44BB5,CBE2CB7E67882E17,37C9BFA7915BF35A,106721C2F6FDCFCB,2738A863588EC239,5A0151B27C9C8D6E,751705604A1EB8B7,857AA8F70C167900,D74B517DC0A92280,000000010D6852B6,7FFD7D08718BC84F,3F9FD8AE8C5B766E,41FF9983C9C4B624,5A5CF5B76F6A3751,39FC60FE5069FA4E,C0FC820B62AE98F3,0859A8D82BFD47CE,787E96168F196CA8,1CBE89BBC873BD2B,000000024C90A38D,3B8E6FD248587472,BDB0E9088FD28439,FE1582641D8A2A26,47EEBE6A81FCDB8C,D84C4B48DEE55E07,D070A703A318C52C,11BCBE6B853EB6C2,1303C753DA6F2A33,3E8FAD6F8D336BB6,00000001E6191602,6BD421FF5300F8D2,EA1D2416A3C5E242,82C7DAEC18B1D8AD,404E105D47B61993,A2613775556EA2A9,BBC920EA3DA770BC,664C4AE5EBF30DDF,292DE0F9FA6D03F3,070ED890748B0CCD,000000007742217C,C03D0DCB3585AB1F,E0A61E26431AF59A,0FF816E0077F748C,281AE2BF0007D3DE,F1511A65BDEA15A3,B248E4C8F643F287,FE761DFE1E348133,71AA998DAEB0A121,3D36F82A779742CF,000000024DEB9987,C184F92152EC1B6F,6371740E3CC847B9,FF2828B1244805A3,3EC5B9973D8EC772,6F3D6CB1A30FBD4C,0663D3830B1308F0,420519F7E274B2BB,5861581B54712D0C,3E41EE40654CA078,00000000A4C07BD6,FCE63009B0BD8579,73BFAFC143785900,7E6D19117B7CC54A,492827DCA21F494C,8FD0F369346BA9A6,75F2DB5C07E79C26,95FBA7749669E6B1,B514A96DF8C8853C,93FD216C99013635,00000002011BF5C7,52268C2D51D09005,ED00E141F0649852,6ADEBB9F6763C0B1,E4DEE17C75DA072F,9CF73A1D782FB01F,D0B57F0B138515D2,E4DAE96146E3ECB2,9DA6C4CE89DDC3EC,050AABA44D025294,0000000160057826,0FCC5129E67ED711,7FA647A5B3B7C0A0,1D5B738197D3F0AC,808836CEAD0DD942,C665852DF33679C0,B2A6A59B7D8FE9FE,3369A358071F0E5A,34965B61CF1A7D4F,92C4F5629949C0A9,00000001120F8359,17C0882C9740EADC,559249983B0F38D0,C0E168D6D780F9C6,C89AF5920CF04081,149E442BE53B4781,26D975F40432F0C7,072C588AAB9C5818,F0DAA6F24AEB2BC6,28BCFBF01FE8AE2E,000000016881D41E,AC7C6922A79C8502,A98E94E621297BF4,FBE89C1E3782A96B,92B1B794A7F9697B,AD8846B23AB52AF2,9939A50A28E7DB9B,85C944B9E7766900,FA7EFA430C6F3A34,63DD2D8F01AD3910,00000000E5A13D11,607F4FD8F5EC51C7,1F45EB06E05053F1,6F6CC33E5A41CCB2,5EBEEE702FF03CA0,13CBD00B7B87F425,AF10D3EDDAAB6221,69E443E16251C2C6,E91AB8F974EF7648,913516C69A52A093,0000000146AF6F0E,31BA897CACBEC6CF,11A42BFDD9A71559,C57C9C7D4F0844C1,3E03EDBA7406FFFC,C0DC1165FC87493B,A436A2ADDA13A502,851EC87BCFBCAFD5,99BDCC41DBCD2947,BA263CD5BF498126,0000000013ACA1C0,7AA1280EE91FF822,FB573D3850F5A3EC,EAE186F73C054015,2450E7C2FF605CEF,3A6CBF4E05FFF843,4E809AD730FD616D,7D1992E8CA2B4449,83584AE6511D1752,616A5F896B152ED9,00000000DE73A451,4FBE91F8308D0C30,B832D9A44A0139BF,7316DA7D9D455366,F077961FD076B0FF,FEB1EBB970549E96,6A7E8BB7E9043E38,B0C49D5763B79ADE,219A8C65A439D0A9,552145F2FC77433E,00000000DBADEB06,E15A65A7EC98D8A2,4C1F017629BB675C,94824BFC377413AE,5E3ADEF8B646547A,496B88966E2BDA45,2ACB6884C0A2889E,AB1B09D40B6777C7,ADC70511816013ED,6177F07FA9788DB2,00000001C3F917AE,21A351C4216EDE01,0A33BE527D71D0FE,F154FC42460C9643,CCF63D8984B7E22E,C7FBC476765807B2,08E59DEA882A9F74,10B01CE45ECE251A,EAE4307833AE323C,5F499512A0FEFBAF,00000001B342DEC4,A5320E41C5935926,434473BDCBF25625,3AE8D6B919927C40,25B857E2F51C840B,40BE79F17BA20A41,41CA80F6AC5C2981,A841891D5977AF02,3E239A639A92D088,8ED0E0C3E2FE8AA9,000000002AB49187,127CDAE083DAA6C5,2F24790B0479D7A4,EDC4F60DAF6D5CD8,6F98538793C6E46B,37260FF0C214BF58,CF0DBDF6B56ECCF1,C3C6871BBE9DC614,6B61FAC13565F512,95A22944DC70E2D6,000000017BA39EB6,ABB4D2B0E1158F87,8ECCD34F89A1DE58,2FF24526770CB2A5,A52E7C2E649764BD,FA453AD79D514691,2ABD1DBF68E3B2DF,D671C2EBAA443411,50AE8ABF4FB0F3B9,928A425C2249C8FF,0000000142CEDE8A,D1AE557A7BA07AB9,A9B170ACE7B69AE1,B3B254AA4FF6B85E,173F3CF3B95CEE75,262416D0525EDE7F,0B9EC2AC55AEF1F2,9E3D336D159361CB,E593D8DCCDB9CD70,14CCBC8C13CE2C66,0000000095B6DB7B,5BA8797ABD48CFD8,D1AB2E9C2F280230,ADC76C19896B958A,720C507483EFF595,8E70A95DF0F25395,96C7B685A72E1F34,262A279F74D1C85D,DAD9EDF0C0D6F746,B55AF426226A17A3,00000000A812F862,E95BEAA8D9BEF6D0,03C3FB3B925ADC33,240E397B6870C0CE,98844C716D168AFB,7EA9B1FFCA457895,DAF3622A4964A1F0,6088AFB727EB4C8F,3A401736756A707C,55F51D53D20607A1,000000007DBA19E4,D4E9EFB64E15A04C,717E669867ED3D26,129556186D063700,15085EA0A87B6B1B,F0E1DD4FE66FB431,4F9BD4F5CA108828,AAD7CD423B41443F,60CB36722243CAC8,ED56D404E5A4B1B9,0000000022C3A461,19E833307B2C069A,DE1F1E0AAB2676C8,41A7E4C20DAA90B6,90FE4F60D12FB563,8FA1BEB900BDD244,6E25C08AB67C2844,5305D475A643D8B1,984C7BD255405533,F4928D32A798E24B,0000000057B6767A,0FB40BB46A00D81A,007429499566EF94,68DBEECB02D4F2C0,AC70C8ACC01A26DF,05E758FEA7708AFD,F7553F730C0DBC08,D67230F8607AA830,597CBF961887D81D,B0BD085D898FA725,00000001A75F7BE8,FA0587089F5F7200,F0A28E2D61AA43B4,1CD0D2BCE2F57DF0,32224659A18D6672,5299201E7445B146,6827E3D18A904D99,D9302F4E6D84A997,405A9D05B808B0DF,62452A4617DCAA66,000000026F42FD70,203C6626CD8AB3F1,D5DF2FE7D5D8A5D3,B2936D45D9628674,848ED11A23991F5C,30492170C05911E3,91F7A3C34ED28E8C,91FEFACC039499B4,DC9073CC0E3BE82E,95FA57BE9C717756,00000002776604A7,26F24F4B2951D2C6,754E1DEE8490002A,2C360137B717E040,F49F963854145620,1FEA6C941792BFB5,2F08DE37A6E0A6ED,E0389D97A84B5699,76216D56166FE13A,79F38ED7A5266E64,00000001C136A138,CB762E80C4A4190E,EAECBF4617290159,93F7D94318B63553,1FFD247F638ED7FA,943197968D1BC5DE,8C62CD6711091BCE,46F1D537507FEEFB,72C9E8779F64C796,E321F80EC97B922A,00000001CB111D40,FE367AA4989EE1E3,69BA6172D5979766,5E6C4A1C29C8467E,29A5C798F24024B9,371C4C8E47665534,85E7C1EB42A59583,E0EE3544CB04ADE5,5935A168644F3D29,BBDEEAF8BA5CD505,0000000207EEF12B,343465DBC48D1AE8,5D5FFAE5C95F4B20,E6A4D4B21F0F9131,3137C3C7C3D7C90B,A19A9F57714CE0EA,A5960E575BCB30D6,241F33F266DABCD9,72303E9DE4D5D821,3EA131D378D73D00,00000001033FBE40,BD3014C4EF9720B5,1D3243924C7ABC97,8499D5100684CFF1,7F4FD9C80394EFFE,E5A6BD533D9F883C,E721005680B6A28D,5ADA93D1C53DC998,6980D1072B1AFEF0,016E732266616825,00000001F5FE87F2,3B31923279E8365B,B7683632CFEDF4C3,62E4CB5E866506D3,941506D8FD23A96B,8D24625970EDE7D1,906159B2AE0D64A6,26E10C36CD63720E,0C3995C531D8F12D,AB351EA95675FC1E,000000016C325FE7,23BD72C8F7BC9DAF,D06FF70D2A0110AC,D768451CBADB46A0,3967F31D04AE571E,F5B08DCFE08AF02D,18850D49650DB201,EC4BDAA25EE39184,222EB744F0FFE36E,CEE26AD984B9AEC0,00000001D3274E07,6FB7BFF70921B62E,AB006ECD808C31A8,7EB9143E8CE3307B,7BB6F6FCA8CF0411,C1BCFD01B7754C7D,9595A5D5619A03C0,072ADB676A0FEA9D,ECE916E42CA6EEEB,BA091D64A9694FF2,000000006F3E7A6B,CC1E6AE8B0F0325B,3567718FF6256A92,8BB83A3D8BD3D37A,9E0A9D680FBF7435,B0DF8EC2412F312B,45763AAC0D432E2D,5FAB61107E4A372B,549C8BCB5577762C,73F59AD6F15640B3,00000001F6708315,BF671959D0467DB3,9E38397887EF01C8,0BD4BE0C8A36E6DE,C2CAB9806AEECD59,C42AA58EBA394F07,EE8BD45940ACFFA2,57516EFD989B2F8A,92184D07ABFC22C2,1F6E2B207BB8B4C8,00000000DF8081F9,C4DBA0C37F7958F9,05B94B442A0CE026,C650871829D2D859,4ADD2BB1B72A0CBA,F254ED7BCFE8ACAF,9A2B7ED7282F0376,3032B45D3958C03A,675D5EC95F9CAA9A,9A6BD89DCE9465DE,00000001EC632D71,AE391C7A372CC9EE,2A8BE98C8B925D3E,3C865B863899E2B2,85888E7332C64477,FC6CBC0E536925EA,82EBCCE5644A52F0,28E80D4702C6BF9F,FD7D536761CDC495,C7DFCF8C3E7D171D,00000002187C3B02,D04228D8D12968ED,9FC564B9E7D4FC09,B1BBE60581428906,3CAE1F92E378BAB8,B11C10F348461E1B,149CE461CE3BF3A4,BC1FD743EAC1A927,13E879C6FBE5EB69,93C62420A3FF0422,000000002DBE93AE,A21F844F4E4C0E68,6402ECCDAEE93BD2,9FC7C9AAE1CCD5FB,A4F20FA12FB44ACD,F83B7CE30CCA6163,23452BE2353B7F68,576EA3BBF5CAF52F,F33C1319391B5FF9,179A6A8DABE353D0,000000024B6A5326,2DD651FE2228A521,3B21FAE62D66551D,F0B1BA01E2239844,F09368366D2F9569,F8EAF9098D514607,B51FD61E4DE5B7F4,29109E4CE3CF80CF,81FD243259143CAB,5E8EF4C9F363D1EB,00000002342E5564,AD3E20B6C083C56C,6628A1920437AD0A,4EC1CBB363F73EEF,F1A4E5F4225BDE4C,D5CF4AADC64327C1,CD607B28D130A080,1F8E528EB7651263,08DC6BAEA387A48E,9384170CCE792CB7,000000013DE37E84,74000E5F6E0936C5,55BCA60EEBA35664,35450828DE0330EA,A3F569F01F6BD7FB,B54446F00359CA9D,A96DA5948F251F2F,84FA0944B809FD47,C4C174AC33BECE25,20A879932D478CD9,000000014434CD16,D6D784431B4C484E,865614A824E1ACB5,F5064E457FCC741F,F330A9F1BE9432C9,9DF68F06706CF511,9476BCC1696F9DD2,245B5E1C8724F5A3,9D32381A13C2F9AD,EB062FCC909E8713,0000000266071DAD,FE54BF4C51F704B8,F4E6FD0DA5EE2948,BE5D73C441589E3A,20EAD3CE89BA5C1D,BB6857769ED7B44A,AA04A879F7CECFEC,4D391EDA9ED06EEF,A132F7372F88B762,0EEACCF52C1FDB7C,0000000250674753,517B8D773550A050,E03E340695A145E9,F426A927436F97AE,B094687EB85CF5D0,1BA8D030922EAE1A,313B597C8EFBE4B6,1EDF6CECF3EE956C,1A9678FDC83AC349,967F6AA6DFD8A6F2,0000000187D1D81B,681E8DECB6D386C4,3540F8D586DEBA5A,F23A0A91B640106F,EAF832D0034B5120,28CF64E1FB87563E,058065C86CEDBB5F,23F9FF7023810BDC,61795E872C179C50,990D596F8F9BAC56,00000000C5929FBC,375879319A0CE1B5,ED4D1F7AD79A3A04,185FEA8A13E1A13F,FD47F83C4E03B5F8,E57C8CA5147DB098,56DA2BDD3361C522,64F68E89442071B2,5C21A044D74F936E,D067B3109F974FDB,0000000114C3F88E,EE428C7EB791B84B,1E7C138D704BE693,E060DC42607DA956,405D0809F2874404,74A233BFA86FAB29,DA1998C863C238B0,E4FBB0B037ADF2C4,3458CD5339D5CD8A,9AFDD81E415726D6,0000000056E2C1CB,793F0BC6A40C99F4,5A4A3F63EF80466C,2C148C8A1200F981,7AB7FCA547751E66,B469439C7DACC7F9,255FB4AEB5076A17,E73362DD0D639588,922A73A1072AE796,1B71F48100542A1F,000000023E74A637,CFB866F9FA769AF1,D744CEB34776750D,DDC8E80B5C8A5173,5CDA74E78B82EB4A,E854D518087458EB,4D3A5BA11FCE5525,9F4392230A9E3FBE,FDF21B447D0EE723,F1CA1D5CBE6AD53B,000000014B84171A,DA489A1476A62C39,8034DCE500620AA0,8006C2825F803D0A,D564F25D5246A4D8,1C512FA41D64B41F,3283615BDDB126FA,A056122FD667DF5A,1338B65BD813DD0B,278776D775BEFD7B,00000001A93A01FF,12803C156E332592,05872D3FF6D4807E,25FC92BA4D15D20D,52C9277C94875159,794AB1385DA1B50A,FB287B1B19124271,A0863E4257E0105A,EED99785526A94FC,CE382227F88A8BDF,000000025E490ED2,1DCE9EEBABAACBC9,5E3B9125FB1AC971,AE9F53713815C5E8,4660C47A5B613A95,C2DAC56C30ADA575,229EB9BC4B715B30,D45AE2B96E4144D4,4FFEDE92416C0ED0,A95DF99238FA6B23,00000000806A8A90,CD6A400C255605EE,BE17FC5EA8DEBF65,833D01186A4C54B4,4D1C8695AF7459FF,4506BB09C13724A2,915BC3BDE2044BAF,F6F7D11B3B497E16,A1FF728814F51401,1A2DFA61AA3E6286,0000000039FC9441,43A16221E47C4788,0F993CFAAAF22DA2,FAD2CF71C454E1B4,BA3F0628E85E44B2,44C23D73AA2EFDDC,67460603A5E81E71,3B25B61085A5E6AD,AF0F663F5B0A2888,6B89967E812A6C42,00000000744EBAA2,2CA9E78371EEF413,346EEE50DCF229C5,00524207FA8FF213,2E098E7BE733B76D,FED4386746A7C85A,94DA4EDEDC494760,681FE897C121C92D,0C7EDA3857AF2863,E900F50824AA0A73,00000001579F0D74,F4C60F74B54A97EE,8AA4F8D2EAD1FCD9,096A961C487E085A,43D80373E986838F,32C075F1D76C32A5,C70C7F19CB6FC5D5,61DDFB2DE150A819,9ECFD08CB209B9A6,52768A7D46E8092C,00000000A15D9645,619AA23DABD4D008,DB8C6B3DD2143AB0,2C0062970A4B0C62,884C21C5A76D0AF6,BAC057399025EE4A,E7844078C3D2E9AF,18969972E3F22D5B,4B23A4BB6881C618,0C21257B6D092678,00000000C9093AD4,5AC282A7F58D8A56,7514736FF8FAB302,C15B081C6CDFE9C7,3F45CF6C1C7A1B23,A7D3D4A4496DA5F9,E8B22D9EE06938D1,12A3A3B89EF7D74E,6985DFE42E242FFE,587E4A0067F94243,000000024A6CEF0D,1A76B6474A3A7004,BAF8F5F99746732E,143101051818A10F,8215A51A25D0270C,6C4E667F76CE9149,58DC45D142E5A8BE,F3B32AC6182C7F02,78A7D0156C331DDC,6E78E62860205705,000000026A94576A,7AB0431787B20AA6,3C0B7879F0BAD34E,23500BDE42F85A58,DEC9BB467642AA86,BFFE971CCA7B7208,9EA1064D70F86DBC,E4F2472826A0EF89,561C1C74DEF2F8EA,6A983E23C0743A0A,000000024430AC56,2734ECE23A263569,33B4EE4630823E30,D98B30BC7F7B00A2,1E094A3AE06F41FD,9A96E982740C07B3,8CE43868EC77A0EE,5142CB91F7EFF019,7EB02078DADC4462,C6B8B68478DF3113,00000000399AF83E,BC69238330546F90,82D7149E74FED49E,2E55A1304ABC75E0,AEB1B9A6D1F65D44,E8BF6045A6691761,F74C181F41143C41,E48F8C714964473A,594F570FA0DAF6AA,D4A62CD0E9335A34,000000011EC2BB65,B2C70E254C9BA140,E675580679F5681F,25AB884E5C79792B,6CEAECE845A1142C,E9BFD0E0AD8CEA88,360A5C697C62A1E1,41B6C769E5FAB41C,A5BFF9317005C485,022E119C7C9608A1,000000024CB9EABD,E9D80CABD4656173,041EF93D3F48C0E5,73AEFE597CC96FCF,17676824E00AB7D0,690588CE29948570,14634C500167333F,D11AC814448D537F,5A4B587323913647,6A3279396367450D,00000002045FA9F7,1BCABEECDEF18BEC,2AF3C9686657BE87,F1D57F587991273D,2FCF7C9A4620E653,51AB4B63CF39F177,4DE131EBDC113245,79EFA2E0DC051B40,F9E045BE79DFC9D0,1B3C2CFF8549F7D8,000000000DE820B0,8CFD6A3AF61564DC,B2388CC9BB0558F3,89A09A14D1143D95,9B2995F342A9A35F,86BC27A25B304FC3,B52AC8E72F875304,5E5CB7F218BE2915,AEE8F48BA792DA58,039D25C90E8C7228,00000001EB738448,0D5D54ABB4AD135B,A4C0D3F40C9D5477,3E3140E252CA89B1,87483AD7EA24E88F,A745EA25916218E2,1DEC3EE785772D5D,3B452863AB51987D,B6FBA293D910ECE6,1450F8CCE2300375,000000021599DCDD,FDDED3C2EDD0222C,1E568D4F4B3CB5A9,825683B9A352C4C3,D397121D84C0BC7C,C8494C920CE2B1C0,0637BCCC7B73D473,23CC3F65B49A2271,F63CCBF0F80CFE39,25973FFC06194473,00000001FB674B39,2F067C1947636FD1,6C1E91736C5F5693,AE0577D36F32F7A4,FE104B2B0AF1E815,70800620581CE20E,3CA37EB2BBB90934,CEB09722104C5368,A39E1D21CA0123DA,B80EF069E61B4FCF,0000000199A2A08C,1207C921250D037B,90E99E4B88FB7039,96601A818078C4E3,22024FAC657666F6,AAD429A231DB4B82,79D4FBA41EF37664,B2053EE498DD557A,487F44F1DFAFA8A0,DE2EA9A6C32BEC19,00000000CDF4DA04,0548D49BB382EB61,943A2C15147CF4D3,D61E61C484E39B23,7F23F06FDF9DB320,0D6BB06A95F5E04A,91F2AEE50C2C7D26,5B31971E00AEB732,940A64A11ADF8EFD,28619984805A30FB,0000000039270DAB,ED3BDCCE781FA458,0526BDD5F14A3748,D9701C0F36D4CA58,F9E4501A0C47897E,67B28C70A0E7479B,4F156F952765E834,95B02EC1088070B1,0973130782231247,4600F4E944D6CE8E,000000006CBB0B9C,E095E822C617FC89,690F52FC40B50B76,DD12E70575E74982,A609D00F758B95B5,4C0FD0475B42B495,674578DBC6ED85E9,E752FBACC68D4CC9,A86E7F63F830A729,F39E49399C88A123,000000008439436F,4E51F83EEE9F4E1B,2F078C734E89E93A,37865320D605135A,D9918438C9CC74D4,BBBC4B3795092D5E,A570A3C05B3B34EE,86E3061DF4458DB5,D8CDB7C1742BCE64,5782281C0C668FDC,00000001D84394B7,F7752119D3EA7625,4E28A908387B2AA7,BD84D9DAA3C8C795,BABCF86FBF4E1EAB,3AA9D681963DBBCB,3643CDB477D13237,B9959FDA99787E6C,AE98A5A2A4AF361E,773B623D0EDA5E3F,00000000C42C82E9,0699687409F42D00,ED0C40ADCA60D1F7,076D2CF657720F58,5B89ED917E9B3301,0B6D5E20F06E3CC1,CFF83745B6CDEFCA,4B26EE5C4CAA5AE9,4CA4AE6FC4B71647,C26D5BBF9F40C67A,00000001BF200E74,65F3432208261543,BF5E0DAED457F20F,9A28BF93A913F152,807959463723D230,EFD80DFC7504CD38,65A7DFBD51C9E195,889B500B4CB63A60,D17ED7D360E8A989,A5F7588CF33C5EE2,0000000270782A63,E30DFC966EC9D86C,8F6375C4721BD981,8F92B0BA25F59466,0B20BE2E4694EC34,3EEA2F4E790AD193,D23D56B870EBCDB1,1DE68B24D4663324,47EA0697D4017E11,76307DFD51A879A5,000000002B736090,1C6B279A1D988371,F103A40FFBF4B3BA,59DDCD9F95ED6BB0,8533343AAB2F1CC2,CDA65BB1C1D7E1A7,937040D58296E0FF,8A3BC0CA61D44ED4,0E609FD30668D13C,163AA2C504AE7BB6,00000000209AC723,B4F2E916CA93B82A,18B91D2148040726,4AA8431D8DE0153D,B29C9E37D79FF435,C26B557BC90BD111,CD2BCC464EC45D28,9D2BED1D24D3C3B9,96977A591CDEE7A3,BDE38C490358C848,000000009B0A568B,AF44DBA1647C590F,8F13D390A3462794,F1A791A7DADE2894,A9214904E22CCA52,1F94AEB56A01ED81,F16BCBFAAAA150F1,DB3A0304DF233286,B9E6E40511DD8474,C746B64830E9822A,00000000452DB595,AC1CD618A0741386,F09F9533F1E31D93,AFBDA1853DE170F2,E5C273E283B431D3,635050E270740104,EFE182C5C67C98DD,FAEB4EFC07B198BB,EE261F609AF0FA9E,569043C24CF7A88B,00000000B2A5B36B,0E9BAFFBF8E7B563,AC38B476E1899C83,DF70758C44F7CCB8,9FFA94B7933F96F1,CE13D299096AD4E5,676304A6F07851FB,47C60879B5D46C15,758FFD518209A160,415BD02D739AC78B,0000000058B008DF,808B9E965F7CFD1E,DB098FE04C384DE6,9608986C45F184B1,6F68BE54CA190B03,185707A6A06D46FF,111204E23BE2E4BA,704A5473E88469EA,492B8CA7D9742282,3E86E3E8747D16C0,00000000223C8F12,03DDB79AD71D7B85,19E8EC6E8D8D714E,0F94D3DB2596B6FC,27057B31EDFB8203,7B5C4710BEFF7A32,891143192652E8B0,FECA93F0417E25E0,A8A471CA2CF4199A,836F0A11AF008DAE,000000008E819956,A3A9224CAF59F519,55A474C602AC3F24,1BA5C6743BEBF350,003C75CB03A0EFAA,3EC99CBA46882162,3BFD6EC416936ACC,E746D49EB1674C3D,6E033EAAC121237E,BBAFA4031EB113DB,00000001F2E379B4,84D85DF11B9D53CD,59F5B233AB832F40,71CF9F736054B781,F44ABCB0C2CD4844,295FA9C74D0C5200,3FC2DF2BDC464ED1,466A4CB62E941B2E,A87772A1CF06B0D9,0A191732AF393B1C,000000017E4660A7,9EAB2CF99AB32F88,A9071FF76AC3D3A7,BCD9A573028905EC,FD3146BF02758D68,9BB584CA9384A444,8A3FB38C927383D9,E2E9B8984A1D9B30,166DB67734FDB582,03610CEA50968F1A,00000001848B380F,656D309BA3E22D0D,BFA1EA087C80985D,8DAAB81F42369885,AD4E62CB4AF70345,110C75EAF56517D7,7CCB77724A959B71,33F6F9A29D6DF60C,39F8B1269A04B881,BC8BB692EAAEBE6B,00000002323827F1,249E159373627D3D,2F4E0FEE2FDE1541,5D1A6D6C3D2F5B31,B1D90520547CDBB7,18F7397D61DA7168,C3B0E24A07CFCE61,B08B3587D1A4BB66,F05E1ABE887039FB,288EE2BC2B1CAC73,000000015F1E0152,F884DEE1DF7EB869,9EF03C54F5D0BAAB,F128505FEAB6A926,D4AA379EB972945E,A69E2A87FD20AA63,92851116BFC2900F,B18902357507926C,9DA240A9D839E869,73493D27892F3935,00000000D34F7D4E,9ED3E6BF99428038,6289248B93D4BC14,CE2991AC0CEE483E,EC49FAA3CA6E429D,3B3E11A50A9BACAE,0015362252A97243,E37B226355DD292D,884C3F0E3A31B05C,60592CEAFAF66578,0000000059EAE56B,61D5BBF671F9B7B6,29125E88625773EE,13E6433B68F93F44,03DD08AF7D59FA91,8321542BF5C15EA7,784BB6313BBBB4DB,E91E495688E9FAF5,133A7238D7E8309E,3CA1CB86D2B0DBC5,0000000115A19683,E5510A9A7EBF68C4,90EF03A0141532A3,07275C6269EF505D,3605F7E10CEEE332,B1F0D5DFBAD295E2,8AD7085F2BA01DC0,D86066B8394A8345,508070A7C2EC77D2,48B7D4D650CC331D,000000020F19606D,729B03BF25FCD71D,E006C1B91D7E0F46,AB2EB948CE663DB6,5CF4EC1AD3C81956,2F0DADACFA1F0B8F,EDA875B86FDAB1E2,B4E42B93D1E7DDE9,84A696AB1BE42FD7,13487F2C62DC52BC,0000000076B0ACEF,965573E85BF21BE7,AF86D782446ECB63,148BC38EA244FB5C,1EDAE5824F694E6D,CB83E5348A1F5920,DC44D55B98EB760E,A9325570C953EB53,87067F1B3669916A,BC4A3BB8FEF5F479,00000001C63EB8A4,AF0E420D9697512C,BA07565EEB7C55F3,5CADA4E716C48E52,7F487B6531F77BC5,DE470FA830FD0EA6,68379F87908277F2,245CB8F7B416FB29,FF7868CD8447BE36,F38413F57FB7C22A,00000000FDA86208,CCC4C00E8AE05431,F7414F8CF1EDE7BA,59A37961AF3924B8,6BCFDB7CAFF69821,CFC27900F258D215,D835F427308A6F76,9E50C0F4002CC2F1,1C13EBB385626551,19ECDF4D4E1DF9F3,0000000069B9DA74,D398FA516305EAD8,1E0F4BAED19E22D6,F73DD870083687A9,2656CA134D973FA6,231D34FF359C3F1C,EDE4B086B29CA3FB,072A47B2F0F87825,8026071D786ECCDA,0C6CA39440A2C71D,0000000037910B91,C359024D810D239A,7064F802BAFA11D9,55A847D653E3943B,E1C12D9EC37C013D,E446ABD68CAFC5AF,FBAE669C5EEA1A79,80E5C02D5E6CCB8E,F5D03D98563CA271,50CD7BEDE939D927,0000000002867D61,763959B7A22C81AF,4252E80163373683,760E74AFC219B1A0,6D9ED5986B85DE69,ECC0A943380395F1,523F4998EC37BA1E,E24FFA14C988CDCD,A166209912D67040,3DC5D1E367A42D05,0000000079688C23,4A90486D76BFE15A,1B7FC4D44445A702,DCB455A1E3A05ACA,3C1BC827FA0514FE,3DF2433B10AE7E65,1D99F16AC04584DB,061F42009F9F36EC,B7A6B74C0FAD61D9,AF55AA494356772B,00000000807AFF87,ED110A6F1D7AB7EA,F7CFC12003D8F189,5D0F9DDC8EBFE45A,8609CCE973A51495,C6D526EEB5833AFE,75A05A6658168687,8061069792565EE6,C48EC64ACC369EB8,0EAAD88AABE07414,000000015BC97E0F,1A85953E4236A111,02484C75C82493A4,3B2517AA86326A3A,0F66234609B78B11,0CFE0D272366387A,B6C87DBE9FEF898E,1804E4F764A63E7B,668F54EB4B598ACF,8C7AF46768821210,00000000142B70AE,3932B1709E4C9A22,FD727D6B551F7F61,5615B42A2E467555,2C990DD71F4DEDA6,4A968E287FD43884,5299022B4F7F4F70,E024C6ED28852929,0D45FBC5E212D330,449A0238EBB25A5B,00000001F8776191,34E54EF7A98DB969,B23AE8F9C5B88687,6DB7ED61E176B5A2,B8400E8B27E17B6B,AF2A37B4E51FFA35,E89B613A80473E38,18EEA543FDA939DA,EF21ACF100794FAD,62FFCB66C52430E3,00000000453FE557,04DA5B0AB6EE84D2,03D00F8A281D099A,F11EB6767C4AFA81,547AD0C0684C1280,79CA80FD78FDBFCD,E254E43700C191BF,05F274F0B8A42207,6CAD9A295442AA37,523F09612F71E303,000000014C759FD9,BA0442BF8ACE02C4,9221B86ED37D62B8,BDE96E75DAFC9833,3D3BE99AE192A286,C57105E367C5D62F,A6664A10C911B18D,EA0824C4283608C9,66810BC8481B5097,6E34AF9AFD94F734,0000000171C55350,1A99E350C6A982A6,D6A83E67EAC17115,AFF8299FA875948F,E97C08BDCB986601,1DB4AAE3AF037240,1C31892C5373E851,25FF85D04BC33BE1,13063591A05A0A00,A86B950A0D42EB77,00000002070DB71E,1B647A578F9DDD0A,5E101094A4FC3BEA,CB75DCBF1DF134CA,0B028C7E236108DF,3C575B83BEA64F8F,32E1AC4B2A2A440E,C109A7B4BE29BA4D,5DE06F42F4F65C21,0A6A8E05B2B8BA57,000000017F3FC9C3,9B80EA539448DBFD,2FE69E11E6032D6F,34202EC6D8C99142,0C65A761F5D47C25,15B004572223EC40,55EC4317D0F4E685,205FA8D735C4A8BD,5ACB07CC71280784,B8E93DE65801DDC9,00000000284DECB9,8FF09E467D056D5F,6FD391E6D6D83F92,F44CB45BC761523E,C1A2C96484523138,B0346BE37166606C,1846842A6D242ADB,4A3E68C2217D0831,B3D344837F0CBF5A,032B02F9B822AA60,000000001A5AED04,FB5EF70EB3CE5208,28D1C0C4DE16D61F,4EBEB38A4035A84C,E4F1F20008555C63,74C9F99B0997F51A,1563AAA660006DC7,DE9D41A11EEE958C,1CDFC445C33AA3F7,86286758A01FBF7D,000000007D4929B1,DFACBCCF8FEAFCD0,5B52B45EABD5F61F,41085B9AF728C533,7057A7676F537ACE,21FDE02700F71E54,B1ED98F8771069EB,F696FCB27B04ACBB,8E115CB34065A5E2,8A72D3C9FDB6E138,00000000DEF9BA57,C834788AFBC1DB1F,728028AB514E9C6F,C9775CC251D26BFA,4BB14366E366FC1C,3E81B64A49F5829B,B73FC6BD2A9EA2F9,7404B59DD32EE757,6DD2F05D81E4793A,EFD8CB0557D30FAB,000000005E70B7CC,71B17578A073D328,8EB5551BE42F99C6,326C377A3951DFF0,0B27142C58B18EA9,9B2A3972BCAF3A0D,A05736ABBF50A28E,E23CD9108B3E3AEC,194D9D99F4BC95E1,39079F60B04900AD,0000000117398BC1,F34A6574F2E49F49,BD6413DF1752CB47,3B03C6EE4573285A,3244BF0934A7131D,4B54A79C4B9DEE41,9E881EEFE5AD7337,68CE72F619A293F4,3FD43EA34441A5C6,96130CDCC4E71D14,00000000E45A5063,4604850758441E9D,54441ABBF26AFF58,DEE14A122AAD99E2,E197F2D09BA064F8,E7F8BC33122CC91B,86E6A6F21542D2ED,AD666B85232A2D09,57D28A33EAD23368,DE7613DDF8324B83,0000000099E4D2F6,2DAE52FC2207C8B6,5DD5880CADDE32EE,A419F8E235325CB9,769228988DF838C9,4896B5008D422A2D,B5EEFCBE62F631A1,068EAA42A4D55411,6C8EE64D93CEB18B,90A20F9D9957D718,00000001D5B540DA,178692B23B4557A8,9CC5801C7C55DBB7,DD397209EA250208,46943D5119D68B0F,CD2703121F7D26F0,F34FDE2DB0F9FF54,3E9BD0228D9207F3,3395FC384393EB75,4FA502D0D0BAC2CF,000000011BAF42BC,B8A062F24491E5D5,E2F0F39F6A19A11D,372F42067AD27994,E9E43ACD795C7286,ACEFF2CCF695FCEB,3B1068EA5A3C3524,24C091F5FD3F1598,5DC281306A458DB7,1A18BE7D68B78938,00000000B56E407E,8AE56588C00BF537,BCF4DD47BEAB25FE,991B1E0EF91E2160,0BCFF91D33C70D7C,5F65D467FBBB728B,2857938CBFDE6AD8,D838DCBE0CE8ED50,3338DF60CE1DB1FE,A521BF00AABE49B7,000000005346BA7E,AE8191FA42D1ED30,CD01F1A38AE9E5EA,FB0FDA2F4F55B153,0A2BEC50B1E181B9,B6428CB12248654B,620D1A8C17CDA834,CC6A9C85691ADAB3,8C57B275E9977836,333621397B04107C,0000000039FF93F2,88640B4E20D5FEA3,328CAF8795C0E10D,7F1199D857BA76D2,EFE880206A069B4C,DA18739D5E60D9FE,64F7DE365A2F0472,E4C9476F13570C81,0A46E27FD2D4AA91,9D6BEC1A009134BB,00000000661E69A8,525622908A059010,B02CA2F419DAC721,FDA1819122A7AB2E,CA95B9F895A1D182,9B8A1B861479A4C1,587AA5706CEEA13D,8B979807AC08057E,3BFF4CC1107E5C70,DD2D9C56B4A4B289,0000000049E565DF,A45FF97A132265E3,C0228E174FF465F4,CFA5CB54FFC72039,7DFE7BAD25A8ED71,FB59B968CC182F18,7FDEE31052AA0077,D03AE5890965FDC9,780F4E7BEE276503,11116558625F2A76,00000001349F4FD6,FD7290F756A20A48,DBB4BABAF1B0354B,277E7B9F729FAA44,91DDC0F82AA90EBA,6A5FE0A7138A1918,13161F9EB75E9FE2,7BF7FA0A239A3908,EA1CC0BA334A9AD2,BE0DF8016F88F956,000000005EAA4EB2,97F37CC3C3DFCC84,31E35FB0D7B34231,FB3DCC5957612CFF,AB097FAD8DFF7C43,C133F637824B4149,585FE4EF87D73AA7,89C9056A8263B384,781588F04D20AAE2,42B82A1039AB4891,00000000F3295A8C,78535CA24201ED30,04B0ABBF8F4AC185,2F8240EC6B0CB9E2,67584AF5ECEBBED8,66E6D60E3C1E2F16,1C1F933F2F0AE937,E31493FABD84EBFC,E9AFC1A19DB9CCAB,29DBDC37B6B029FF,000000021ECACFEF,8CF88061571A933D,60DAB12482154C5C,490CBB91AE4F9BC3,93B091371B4E5CCD,17C380F15EE31D30,6A8F75BB52E221BD,F92BA50496EEE32D,862788FEBE8E2E62,F98EAE6224A6FBA3,000000002CC77CCC,9B46284DC4607CB3,A5E4591FA1D72373,870930F289E6021F,04F84CD95E9135FB,97A7F6EA4224783C,8ECBCC3480AC9E04,DD378672834BA4C9,DD9E7C96DF217B34,995594FFFC0A8B55,00000000479EB38C,802CFFF90DEE48E5,026D0C69B66C9C27,6F763FA0CA163053,276C0CFEE1EE69FD,DF13A9993C3315E8,616660759412BDF9,2B9BC940103F716E,20ABD907C4200DB1,7787237C2B7D5928,00000001CD0BD016,40A6861018F1474D,A50F7F2A824C9C23,5EBBCEA855050894,C40B592743BAE7F5,8357B62E72459C38,22DE00C986DE3C3E,A799B1A2991159AF,BA04639FB40354A7,71F0C130AA0A9AB7,000000020E6A80FA,B88698709A2B66C5,7C5CECCF7FD7C917,F410CFD421073450,F3BAF6CC9FA2D960,2A58F082BE9BAF03,2518AF63E11108B8,B98A7BF5E211A8E7,BA02F0B4FA607A1B,7ADE02C5364B6D66,00000000CCDD8247,AEE6799893B27EF4,5E843846E384F615,FC3B902CF6FE6095,8FEE49E3F8DA0B85,EAB83E05B5B2E4E0,97CFCDAB413BA8F2,8AB9A0A915F11F42,BFE4814FB2C4B78D,FC3B485587EC9FF9,000000024460978D,9B65923ECBBFC508,797F773520E71C07,8944CEB2923FF6F7,ACF924705B94CD68,011EB0DE49698719,942640D92F0996F1,FC8236A4A81749A6,4EC1E0B02FCD81C5,D16978D25A172663,00000000E2791207,956BC04434D963D8,4CA981C663143B40,6E2D135ED51B7277,498BEEF725E72BDE,72A6F9EB038155E3,2E9B7E2073C67AF1,EFC77FD77F903664,1B3E9A0A0695394B,E0F833500AFD6C72,0000000146A98684,5FFE427502EBE7C3,B822934EAECE3726,FC4FBD17BDB2EBB3,287C883E1A447587,641F454A477ED5D0,5946497C71B85617,6D4C5A4826C024AC,DDF7AC7E3BBF1E8D,1E555D1D41C77B0C,000000003E1DFCD2,818AA63FC32EF5C5,19268A6F0CE26743,EBAD1F785BFADFD8,0CC029DDD6D836C0,8EDC0E8A26B2CC0B,9A53084636DA42E4,1A45CA2113B81A53,DDB8B680163373FF,6C1A9BDA871D2A30,000000023D9F389E,1B1072DE6C00F52F,4A84D0B7ADA1D0E5,422BBDCF58CF07F3,827503C43B74EA2F,DF01BC3028A1C9D0,E2A612E816E9BC9A,610CB6CF39123079,2750421414DD0689,A9952D94CEDEEF48,00000000AC513097,0FD0F5AC0EEA4465,17796B4F593189B6,A57B501AA5C61B72,F92CA1D859F8A9E8,195429A7847693B6,710AF40A8CFD877C,96D1D8EFC8B2A1B8,F596B635F156AD4F,8F0F0152AD6177FC,00000000EB21BB15,31F613744DC9D25B,30C3D5DF8978D989,6087CB74CAFE61C8,6ABCF2AB305BF631,84457423106B292F,60CAA53BB7C3F279,AE669FE8A89E21C9,75637E00E5DEFA6E,C94E191133354100,0000000022B973F7,09405C78CAE8A343,C7997DD581A56C74,1FFF8F25EFFF44E3,74E08B0D24DDCB5A,B6C978891AF4379B,110176CBD02D3407,733F43496D8886F9,CB17162E25659489,6DBD11DE21E67572,0000000040688326,4246F38345A3FADD,BDAD804AA0BA2C91,4B87757F49446C4A,1F7BFF8AC7100FBD,DF8FAFDBF7E56FF9,5822C4D36C6259AB,BA0247A33F0BEB0C,1D6190D5D8A6182C,031BD6F24152E37D,000000011C34A519,78FE91AB60CAF476,4DDA0A62FF6F223D,34B5300E2EAE2936,C0751F66D6C93696,AE042D7D9C5192F1,183DD527F54F30A5,71EF4FB9840F921F,74CCAF93E0191A48,976312E51C41AB93,0000000247A98A1C,39B7993893D7A01D,950F27318AF480F3,AD92C6F2035A43D4,1B0351284590D96C,261D089A7CD86EEF,54E8C679B2FDE4EA,547AF7AD39F50C31,07F9EFB0BC4D08E6,42B33C77F158C31E,00000001950C30E0,D121626BC79EAFAB,7F99AC7E82DEBDF1,849ACB6D45AF332B,C713FE5CD540E21A,B755F74771D42DB4,E3074C27D956B032,A9BC37EF3E360DD9,B901CF25C0E94797,34E497BE0E719604,0000000034241BC7,77B7830E72C14098,042B3DB2DC753CC8,8AA5469D9A4A5E6D,8C5E29EB5B8C2455,BC4460608B5F75DE,22C3247AFEDB60D2,EDDC8B0EC60FA0D8,6ED66DF6214A5AA5,7E20B63B58D657AB,000000016E37C7FC,FD60BCFF5BDC6E42,D34E7F4BE4D082ED,0552AF7B81452357,1D9EB7830D955BA0,350D80A757EE882C,365FB070F9FC0DF4,E724825625E7CD1A,D3B25EB3242257B9,627E271BA07E04EB,00000000573257B6,E1A4F0E0FD549749,2D3C36E905F2E2AA,EA4FDF6E5716016B,D8714BA63BEBE5CE,571AC1590F58B094,14DCAEB3E1FEB294,58002980337C5094,EA140F1614DCBF64,B340919DAA7BD377,000000025F974DAD,F1C9C130AEA693BB,76A887F85FEC3D05,F9E2C2B312034092,E53CFF1E78A25AA0,2A8EA2013A47E248,9202E3E11DBA5E4D,F7072D1A4A042BB3,F716F43C6C0311B2,8453FCD9E05CBD68,00000001A9F4FC9C,DCBAB4353AF5A161,BDC2BE1998CC8D62,07CFF61468532271,7794B818CDAEB8CA,DE28F533798BA147,B6795C6E5EC86BC4,2BAE9E59211C076F,D04C167799A9739A,12DF41EDFEB6422E,00000000048C1D82,3AF7FE54717D60F3,2214BE92A75E4195,AB1BA3C89686EA8A,A06648CBBA9FED8A,11B63CC0FF3C73DA,39D0A5F6C88688FE,C56D727AC00AF349,E3C8BC5DDD1ABAE3,3AB583A12350AAE1,000000016EAE3438,F7188734E38E987F,A79F178765C40BBE,77B2C2542D1FF151,76D2D294B1C7BBFC,2E324680203AB076,CCE5CFC913A7A588,581C6B7165631E0E,A75D9BF8F9C5F4C9,6428BB5A7728EC9D,000000015EC6778E,C4AE1F610C973791,B259963B4B14B441,11C568D73B15714A,305B3D17280DCA3E,C235904595908D9C,FFB94AE681907EC2,38EC0EE5055BB45D,7DE4AEF712613065,7DC85D9A843C0C41,00000001BE67102E,63B3B8A50D296157,ECE70E64C31C1EE6,174A3F6B39CE7FBF,64703621E6EEEA60,9CD59A6AE9508EC8,2C93560FD0EDA550,0CA8CA747FCC2A32,DDAD6CCE9ED66741,DB48896CA60B5F9A,0000000162F330AD,640A7A609566281E,8E7F7487BEF3BA58,82D4D5E85F30653A,797EFCECBDCB9730,20304508E170EFE9,05EF125DBC2CC6C1,3958F2C967D5EB8E,851A19E8D7178249,E0166F34678F658F,00000000913A2623,372CE6C2D6D95FBD,236BD694B8B64C17,726D8E2926D7BE88,856C1B8E1E15EBC2,8E68E68224C194B5,F543EC1A600CD00A,B0F41DDB15E8B265,0AD45ED401F0B66F,F927D5AB0E4245C7,000000026924858B,FD7EB0125FE2F1AA,7B2314CC41A18221,25D78F03CAA5A8B3,C6643693D8A75783,5EC022289F11E018,B133FD85E600F32B,0583103298C14E2D,AD8F332A7EFF1E1D,94922091B31A36CD,00000000C4329D25,7C42DAE5F80CAB4F,9C2A4715E73D94D7,6E018B9A66107C63,9E1D92925C30536E,C6E9ACA8A1C2C34C,AE58DE5269361613,4529C5F61C4ADAB9,A51A371B8E63D108,09EE9EBC9ADC344B,00000001AEB85D83,9F57BC3CAB6592A4,E87CCCF7D4B574E7,DE75398B57A3724A,02F3FCD7E0387924,E09ABF220933A527,DD380A50B06E1A02,7162727828D6E828,914D55F31C1EA62A,285665991C75E8B4,000000005E4E9B0D,3A5F5A6A7733654E,A08845BF36DA978A,90E8EE45071B6AA9,340164065E589E98,2466D580D31F4085,928F6259E9177644,1AECB5DE7BEF0442,96BBB00BC706695C,95D0850D797E7055,00000001475DA11B,B2D76D21B81983A8,4559C330CAFC40AB,855F029ED94EF1F5,18C4A40BC0B48A37,3299DECA7112C3A0,6DBE602DE144F510,BABD8A5CDB8E71A8,70CF927BE38A9DDE,A980662930D4135E,000000005E866006,427956D4ABB19873,47C4D15E1441F3A5,F56282928CD58B99,9473D06C1ED67158,F42CDB9E29786F0F,71F064C1C7217363,F329CC46081B7F7E,D89633EAA0186BAB,A58889B0533B05CA,00000001636D7E5E,24B233EBDBC0B54E,20BBC894702B0037,055475A523380819,5C09E41D6146CB62,2C1EA76D464232B5,47660F9AE73A0F91,B75DEE739A97A8BB,BF9C7B46A863EE20,E6F849D72ED6919A,00000001866C915E,AD197FE7315524D8,B9C7AB92BB86D17B,ABC18F04381E9C86,E52D0A570090FF15,0AEA1003EE6E493E,3B2C6D5090FE7174,D34825CF44649996,EFC8E0EA31132D13,D10C6ABC8C10F643,00000001A049E93A,3BCBEDE817C26A11,0C484E55030D531B,F3AF6E4DB8AAD1F1,00021B50A17D64DF,0C1B7F56A4CEBE48,552155451DD13819,89421C19ECAB45B7,31E00B4B6030FD04,B34D7E64210F9761,00000001AF547F0C,5FE7B213341AF79B,4F0153F41C9AC450,C51756D569EE5CC5,CE6584653CF8B9FD,83C38E77FDF8E53C,4E2429E53CE39F6B,F2C311879C1F4626,934D7996D943D108,03DC92B46ECF273C,0000000160894D35,C7496A34C54A69C1,E687C147769EE6CC,6233E333807F2CCF,4503A1375B6F9FD2,3C36CE61A518BBED,20832B7B03237A8E,24903CA274D0F9FB,CE81A761E7654968,0AE95F23619BE14D,0000000272274F4B,AEFFF4AE687EB346,F55849D9893F1FB1,5EC072E6294CEC0E,CCE919DB1119695E,B3FA393B9F646F51,6DE6A4A2D57DA824,7B1B9EA7A40C1920,8799ACE77AB18A54,3F365313EB0A7BF0,0000000051BE0BEA,D4150DF1C55BCCF2,631D325F125530AD,D86548A2C81232AC,BE4AEFEE8E3D323D,C864D8483BD17F6C,EC3B8687E059CBEC,6C8850121E92F92F,545A14E45861AAD6,E51F9A191920E0A1,00000001188B86ED,56474F4E30EB1051,54C4F5392F0A70DA,9346161D043D5393,3726021241909CF3,AD72551C1A164035,EFF9D0BB3C1441D2,F94D41E52A4A5A26,A545952B704B99A5,B4FC0CB8E240924A,000000017E34A204,5E9526CD23C888A5,F50C95FF6D95E4C6,0AE84916960908E6,C94E7E059E4BCB12,61FCA81E093B64DD,1529C19F20E58F7A,93D7BF98A96C56A9,95EFBE9195F45F3B,BA00FA3B1F788F73,00000000FAB3E5F2,BC442DEBB32C8AE6,8BF2C4762CCC2BCF,496F60865C5418DB,EFE1BA45AA35F196,6EEFB0BAA525C68C,F3BAE53E0DA5BF38,765587C5B6693ECF,32D37A2722E4568B,2397635A063B27F5,00000000B4C032DA,3A9BDD4FE5989846,3080A9E2F8801710,9F42B567E019AAC9,0205B834F28E9CC2,F9062EEF8C6A1F5B,BDEE5A00102209BB,E085402B69E250CA,E622644CAF428AEB,C5057816357D16C8,00000001A5765E01,E26078C2ED155EA4,DF2859CA98C3AD89,4254220854B18114,E3372C6AE091BE63,E4360B29D0B69A95,AD76226935E055EB,D252E3F2E77C853A,CD66EC840639254F,516F8B3988B6BDD9,00000000AAA9671E,4366CE3B42FA2EB7,336712D6F6F59BD5,8419EC6DBBE91D0A,07AFDA416D0BCFD0,A52FDCE86278EB37,C4235F50EE6EED25,D9D42238B4C5C60B,01A6A48836660694,D7385605BC32A6B2,000000019008A29B,4DF7267B7C0785A8,B9FBDA2625E22DE0,E01662ECE63F1CA1,A5DCB291A3B1A633,2340A712CA01F6D1,6FA1CAC562F795B9,A85E1E918A918F0C,2757182DA994A9D6,E2C1A4505535521F,000000005371FA6D,5E7752CE1DB4B066,2A9F9BAEB3CD3085,A391379DCDB125C9,E9EED19F1B3BDB98,C5625CB45A19C304,963816A040055324,442D23E00E570DC2,D48E13AD2301AF37,43BD073330E396D5,000000025635485E,863E88C2D5BF343E,172C4D2B3EFA49BE,251B263CED192E36,30B02EAF757BC83D,80D33013CE2845A8,54CB1E91635C633E,8FB8C0538B25A0F6,2A32D47928349720,3C9D49E97120BC02,000000020D6C2C31,15D6BFFCF5D25BD5,442F7203ECD95FEE,71C1029F0B0F63EA,9BED40E0DA1EDA2F,45328FC33FDCF661,A1E5FD135ABA7B1A,99E3B0624ABF52CD,D5120A772D03DD6E,8055F6C1A801357F,00000000CEBBAD39,152F85A6C899F4EF,EF1ED0F996E25C15,0EBA2E6CDBF977FF,AC354EC3162409AA,EDA47A39C1A8DBDF,2682AAD7B2207815,896E8756B93E6289,B83C69449CD6F7A6,4CDC0CBF209D9BC8,000000011EBC7927,7D01B073C0584D75,44E73F75D4CF0375,95E6744ED42C0BD1,9178D1B4BB159A98,C035C8837A7EF5D1,A9BFABBB2357A6EA,DF7A35835F4CD796,BA89DDE6A8E7DDAD,01B944BC5C6CDF3A,00000000C3203EAB,7E9ABD0BA1DF246F,865F8575B71EE978,CF0C3237152F74C5,026D369BC71A1AB8,2918870347DD04FB,3592A50B937A2654,BED8F5FF267ED270,DCBD099DB1A22FFD,CAF84DC95B92C7EF,000000011E865FF6,A651A1C9CA6F7D78,8C736B3234B0A5DF,E54DCDD2B55D3FC1,36F80B677FB9BD3A,608B13FB9937DD75,2EB707FAF49AF005,F61BB79E1F80CC6A,D838C155BBBEDA9F,786FEED53CA0238D,00000000A9BCFC08,FBA2A48AE6168DA3,06A1BA6F25A058DB,031E40F37C229B28,A280995517C343BB,042A968FE2BA9701,057CD53947532CE3,6514BFCB49A30482,99BACCEE97C93545,D06C95CD982310DE,00000002006B0A56,BAF4B55D31FC6F33,C607154F0BA7A265,C7426718B4ECD088,BF35EF92A14796E6,9D36CA1ACE87388D,C218D62C82A83F55,1D85E0A398499366,6B9F65B8F406742D,20A88A0A3781B23C,000000016565C017,E80924F974E7822D,AD403100D8CA44B5,C46BCA8136568060,0A352A69812843D4,3CFA0FFE323CE7EB,0F6038C7406BB0AC,6E26827F47FF9410,6AE30394893EA16F,C7EFCADF0F3F1BCE,00000002290FA6EB,BF62BA2C18BE78C9,9E14A8554041CD44,C850860D9750E5C3,08279472D09B512F,AA10817E85B4F67B,50E8A7E67FDBD4BA,9C04DD40159EF768,5E8D63692C7E6C84,628D58D20DE47767,0000000052034050,279B9852E9BBD93B,61DE68535DAC4B66,FE5EAB5D16C1733D,0F862257EB45EB8C,688A1B699D0FB1B9,B0F654AD86CA60E7,72714B2730F1B11F,E16A98C34D843095,EE9BCD7ABC9C953A,0000000109FA5985,E25B812CDBD92E80,FBAD5318C0881434,4CAD8B6A718E7AF7,2C9DCED4AC3255EC,1706E4D4AC18C87F,393AD0121B330D01,20A933A6887A6F87,AFE37E41AA48163C,C99D481B2381B362,00000001EFDEDF2C,17E7F3B4B8BEDE18,058D67D1B1385C00,6663DC6AFCC228B8,DFDC21E1954A7311,86B4D1C5960F5309,A140E60A0AAF962A,F0CA0342BD55A4C2,255FC7713E83528E,9DDDEF0058F69C4A,000000012ECA2CE6,96E74276EA1237ED,08B5CA0DACDB9DF7,9647F6ADD783892E,CC144A3585638E76,F211790643F0902C,20D73B9BC202EDA1,D6043F5FEC122FBE,39CAC058039D5F9B,E39FC27BFD654FC7,0000000133C1AB44,D916033A6D3163A4,D0AA7D7807A3C7E0,A9F5B90C43FBEBEA,553C82DF15E645D8,4F6DE395C568B7F3,5396C293FD78150E,19F36DCE6F18B285,57349DD99BD7A32F,133D31A708FFA348,000000019118227D,B85DC818F0129B66,6B610AB7E44ACE62,077B4FF83FE0A2D0,3C4AF8AC567C85C6,E8061E1380BAF7F1,C6E96F180B321B4E,4C202D74B0C27E97,8679D62C53C3B7A5,ED9C52D5C37BE791,00000000D5CDFE67,10073F783575CB32,6D4F74B1AF89FF43,BFA430797D414161,B1127B6944A4280B,AE3C8502743AF788,DE9D333EBA6B3C3F,9DFA3BF43D77EEED,29406607D9D90930,00F1407DEBA7A2A2,000000002CAA7309,F9ABF7614AD90FFA,A3411EDCE7550977,0AD5FB7FB8816536,31C82446AE55FE7C,E1283CABB6B99152,553565BEDA54BF6F,3DA93158030483D4,A146CB75B96E16EA,1CFC62AA1D834285,00000001E69E2691,748F60535F403FF5,94347B0698AFAD63,E39A0473A7397265,B26BF77DD8C032FA,0625F244D701EC78,25C9FFE4C8BD15E9,8C6B5F178BCEBE0C,D1D2CD4856133A5B,C7490F8DAB28DE92,000000014F46BC91,EB8EBAD2E1684783,F142938C165A3B20,A9F16C57AA851C97,E48491FF7F55A8FA,1F558FB7EE1438BA,90F29422FE332605,F900C4BAABEF8FFC,8C3DA20845D61A70,78CEF4C7F6B4046D,00000000E7491B2C,8ED25B4213D04A58,7A3E0DC032D8F7FD,53E1E3CB4C985AF9,77B95F096EBDF4D1,97361390DDFDD030,E91BFFF9B96883A2,7B6B038BE64A08D6,3BB100493A8BB068,9190525C8B80DC95,00000001E8540D26,0C79AC9BEF33C807,4B5A28C9704D0C4E,ADE397E248E5542E,ED9C48BD7649A8F0,7DDE31BE168E023A,8389D0B04519F922,14D4027C1F9AAB7D,95CF646B940E2C2A,54A488C99BC10908,00000001F27CB5B1,6064ECBCF47C9E1D,50C67A346D47EDA7,80D93C51027193C7,C1FBA63D5F5EE8EE,2D9A648262017D4B,7AB29C4EAB9CE0E4,42AE27A506058CB0,54082DC43022F547,B8ADB8418825B8C1,000000021CC3D136,479A8AE6655CCFA2,FDEB15B8F97B18EF,19C8A6EFC23CDF52,112B2ABABF277992,E89F7DAA1760A002,26661C4192305AF4,94A7E246CA1659BE,59B41E00088CF192,72C55397708C4DC6,00000001ECE08850,0FC0ADCD2CF41E73,B1D4EE8610444EEC,50F71A717EC5AE86,4E574B4A06C26872,A8AF4CE5D25BB92B,69A451856DE88D71,C3F6C1B8FF00EC6F,1F5050A6332E1154,CC3C19CE5AEF936E,00000001D0AD35E3,80F95C4C5CC2ED6A,55669C61257180CC,4E2F9F5BE2640E89,EB190BC136371433,BF8C2261B1A6EF0D,06A878A43D80225A,0D0CC17DB89591BA,61C8F1F3212514E5,4E5F6A395F405A0E,000000019818DCE8,51C5453A41DF4A49,F8884029750BC9B9,1C311F83BC7AAA97,205A51032097B453,B36D1DED1A4B290A,4F0CAE27775FBB80,F5FF1ACE062EC87D,4AE5BD531FFB0EA9,D2D27CD015D0A77A,00000002758731AE,24AC8DA2726ECDC8,6CF412699688DC46,E828BBA256AF6974,96E51EC0D5021919,B172E34A3A86609E,DE23EBC2114E9171,38FE0930A1D01537,7C23C9A029F8C29F,2D1CB4D76590B658,000000009686BD3F,AF5FCB350AAA23FD,D8FA9ABF12E501CE,6B33F27286D8F7E7,807E4D064553010E,2F816A0A25C603FD,AA557BA0BD34B23E,8F98BB5DA58533E6,76F222802633C16D,BD39CDE7D8056B6E,0000000030F20B39,6213571D121AAA3A,8E3EC344FFD9B279,64A54FF866DD44AD,FBCA3604FA3F40BF,D03C8F6739CDE7D0,A4151D95809C5F9B,57B2942FFFC21AF6,58CCB1C275CF6491,92A4D8E74F5FAE5B,00000001C02B24AB,651D672B51EF06F2,62D6919571D3FABC,565ACAB3E2F320FC,04206313D5183868,37399CF1DD81AAB1,9FD17EE44BF99021,FEBED91555FEDDAC,E8C41D6B4C6A6B1F,AED4E95BEB5BB87B,000000000CE98A4E,3CBBD41EA34D9A19,A06DE2909F7FD973,42EE5B6B331DAEC5,C8ED79A1D061607B,998AFDB82CDDC73A,EA8E8FAA4749E49F,47DF73418F22AAC7,4FC3F7AFAC9FEB99,A0DC480058C6827A,000000006EBDD05A,D62B40C6824CFD4D,1051EB18202E7B67,E867FAEB2739EFD5,7C0CEFC46B344164,CAB61A02ADCA9C19,93F86DDD22F09AD0,7CC08E51FA237F03,79A049DAAB20CA7C,172346517B115439,000000019DE6B7F4,9134B0FBB8B51E08,8C9C0D85091CC496,811D6B8699238F80,9AC1BA644139C123,C99F7DC4275BBC59,D5A132FBA86124AB,0F8B4AEFA8D14688,DF091AE23B40105D,D61AA197D1F789E0,00000000F23AE761,4B879A61DFE2551D,DBBF7A016A6C3D38,F2DC96196677DB04,BA60F72816AF8C6C,1B04C7116397AC71,978527FA2981C878,51990179D749A5C4,7282A2F652778C48,B9F869F5FD2C7035,000000019CF27EC1,50F556763F280194,0599948EB510621A,0956E88EE6C6A0EB,9B1819292784EE8B,F823215EEB675B5B,664F28FBE2590B2D,3407E075180C872D,E767F04EBB85D75E,2EF20AD130018C31,00000001609C93AA,529EAE00117A8790,2D53D58CAFFBB664,0D4648A39CE9F0B1,FD1768827EA85BAC,31C19A87DA27FBEC,ABC84CC4E638E768,10409ED481C44AF3,617992F5DA1A9989,74659198BA103D44,000000002E5DBE41,9B496524E60C320F,242522E52F6C45EC,C88A335EC5F5E5E6,30D08C495E0E22C3,38DF8379EB5FF5EF,200E17B913C58385,75B0A171256620B2,747B8D7C6B9F2355,6E3DEAF6D7E653FE,000000017E894227,FE7E69F3E31CFEC5,2D7F86F6D536D650,691E0995A0E21D18,D9F682BE800050B2,D04E6C60D04F10E1,B5230F6C892E5C52,20791118DF9C01DB,8BFE5DC1AC94750A,59B1BA43D2828D72,000000022C45C1EE,2E3CBCE0BC4F3E1E,408F734585F0E866,6FF2C9A26F2CDEAC,D5D05A16782D2AE7,2B693CEE43CE83F2,704B3A3CB84DAE77,83BE7A828FCBD146,63FB1F75C08B14F3,B915851495E0B993,00000000893A40CE,E050E59C63DB4969,C06B27E362DE2903,9D8E4B9A5D1DD5E4,184708AB02ACDC47,12DDEB8EABA1E615,56683AA8398708CE,6F7903E43BB42460,ABC8C9064151040C,8E2AF28C388EFB82,0000000112E4DBA1,53E4A5D3CF5D7066,90F766F4ECCFADA1,E91CB83942A2A142,33714AFF6E84AD44,E9DBF158FAE19D5B,0CB58D27F20A9DBA,73FB31B1D7E1BFD6,7BC0F7BF92C91FC1,5E6FDFA15A336AE4,000000008863273A,5641C6F7D6CE8B28,5A0C83EFE38734A5,BBA5C4D2DB6BAE55,12723AF4E6D3BE49,585BE75E40AD7FEC,CA917B4BA95E1E5B,EB4DFBCA9A55B3AD,AE582BEC2ADB318A,C4EA99D0F85E848D,00000000AF0CC109,0ABDD938D5EF9CCA,913357492CF7308A,7BB0B98CAD7A1695,2AA95026460DC227,D9A34EFAD0DEC2C7,EDA8F5DB1D4B4D0B,BF9040BCB89EC2EA,504187E7FC809ED6,D7D432679D606F44,00000000C3B70388,FC87317610BCE606,7AE44C57EC6C3BAC,148CE02841F874E9,FD67D194583A51EC,B08F35CB7EBE00A8,5F562D5B224AEA77,4A7A9D5B27EF1A28,0A20DBB7A0203296,0930EE688094168A,00000001C9ABF6A8,7012C8A7CCF2679D,76FE38675C40CD1D,5221A4E37548EDCE,BA7482D1567D3641,F509C8FE8E99610D,90A29632A1A8CE0A,D634818D6C45D25E,8A4CA2F0486F804D,DA0D08E529633DE0,00000000DBAC2573,35E644918AC4733D,AD12666F2F13E7D6,1F620C8FFDF46E90,D1CDA633122E44DF,E322ACCFD2AA96A3,712A77977F3243DD,152196819DB40EAF,36E803E23DA3ED02,887571C96B5E9958,0000000212832427,D5B32FA60EADB644,358DE1D8EC2BBBF3,534945C674D7B36B,BC8DC1E5EB3033C6,A26D5DB45CE8AF1B,FFC8E34B8F80E19D,7A5309BB24757D84,E9E30C3B6CD0B187,AB6F9CCAA2323C8F,0000000003D19520,B62B4BD9C6322929,53CF77A23EF34FB3,9E0147DE5EEC1C8B,4D4DCD975D3DF301,5F746680E84CA2A0,251BF8833BB9AE02,BF1762E27F81A265,69524423916D463A,86A9E510A9E61735,000000006FF37D16,8AE361F8EA80316C,95E3360DEF412F18,3FB96C289E6B008C,2B98F53D77C45502,D005C80EEC613F84,B4E7BC006B9EA3F9,4B4A0F406F0A3A51,BA1EC59C5DDBEC7E,2E4CB1D6A42C1490,000000004D850D12,56AD5565D875ED0B,619E1297385A3647,74B1E2A32F15D73F,120CD99071332974,6190EC26947C629B,6B9C9D423E02E924,D762AA3AB078E15C,ED6B6B039E964AB7,2126EC8AE734ACD7,00000001AC1E6CE8,237F999C0C4F7FE8,D780D9B64C427AE4,4ACAEC69B86A906A,44767689BF1FDA32,79A2438ADECEEB9E,88841EA95F2D974F,C86E0CC3EFE40820,87D3515C9480BA9D,43F8D74B95EB734B,00000000D9055EE0,7AABD88B63C6FA3B,89F8B188B0AB7963,B4FCAF191582B566,AF89A8519C47E629,3BE7BB6C3AF059CC,96B7EC8A27193A89,2B66FC64B54F3EC2,3881DD888D547DEE,9A32EFEE7FCAC53D,000000011EBDCCBB,5A977A8A7E794E5C,390A554AE58810A4,79021C8103056C44,750A8B8A7EB58941,D37F2D35BDCBC541,64A24E44ABD4B2EF,D9D3312B989E89D2,269763AD1AD0F7E3,4311C85AF7C21948,0000000246E08842,A729AF33FCDADEDB,4EE7BD147AB8D912,794DA1649FBF0176,12B84C1077DC133C,141608E9B8FAA47D,B71FD3276B9614B2,9F13B6D4E48B4AAB,D423B90A43883382,E66766C675F3FEB5,000000011662BC20,E84D20A845B11C08,F71FDBE1E5D19962,90757401BFD130FA,D6003BB643C15C48,F190DBC875FE85E6,C201A31871C7C588,806A45CC28A8D3F8,8FA1209A564BEA58,D7CB71234FA786D9,00000000738446FD,99E4024CF9EB2DBE,CBBA14998E75DE78,377C24D53DBF8056,FFEAA75DCC9BFDD3,537B008E1B7FE6E4,47F1EB54C26B3AF7,66224FF1997DD4B5,FDACE9E923145010,B62CFB6B8CD95D75,0000000154406ADE,90663EDA95E62E42,4AF5F03E8D57C349,008419C661620B2B,5921D65A2CA8E658,B418731F901B2D40,245A4678A1866406,927E1D76E0CAAA09,50DCC6794305E297,AFCE165A98F0E279,00000000DFD6BDCA,71C5E88387948BF3,08FEAFFD1DE08A6D,8741DF9275281522,0FE6C067F5A001E7,85B909C9601AC84C,A3AD2CBBC23A48A8,B2EEA69C66B4AF93,FEC1756CCC9BDFA7,CB990CEFF9C801BA,000000014C58A4C4,A1D854132949F22E,647F1299B142D930,7F00B5160820F28B,313F3A120628E85B,52875F305710C189,F43538F5837ED403,0920C3C2C449E4AF,0F53F284C578BBF4,379180AB89B6AE4B,0000000153C026BF,D007719EE7E3ECC3,D7E89C1827E76B5C,C1A6557442E9870D,506A574D3A86FB32,FCA552BC48502FF0,334A29DC4934D40E,32DCCB13A112A2E3,DCFE86B684ABC2F2,0467F6D747A73FB2,000000006CD206A8,E3D97EAFFB665480,04BC0D72F8FD2DA2,CA43F6120FD578F9,2D95DFEFD4381B53,3E7323E06C9DCE95,322D85DF6B26FB11,9919136624172588,8CAADEC802FE99DB,455B9112D668F2FA,00000001BA64DCD3,B48A1CD59A477E21,0E207D84621ADD56,E03F4954B044169A,7EF31082D88C7496,8E50A72505127E68,CB69DCC67C41578E,342DDF7DDE268A40,672F196CEFFAA2B8,19891A5EB0F23B53,0000000255EA1CE0,21C8E116B9E46E90,525B35302EFA2E6B,C11191C7F877DE8C,A891316C341BBC9F,F634034E38C1B962,058305F57055AA1C,0EF57CD45912C36D,6D95ADA642D8F57D,08992D6791DCD83A,000000019BDBAF16,3349009A9E07DA70,389BE2F2BCE58684,BF4E4AF546DDC5B3,83E80A16A55EEBE5,E1EFE1A0323A7B89,B65DBFB88B86D5C5,75762918587092D2,2AB5B8B3ACBD29C8,6EB19F0809F1877D,000000006A8428CD,15EE6683571A240C,512378DFCCE7D554,D64E27B3DBB7034B,FC22F031A447B88B,A7D691B447670328,6D109BC236E595A1,618F80D49C98A674,8BD900E44B76E8C2,107EBC254A7D6D3D,00000001B10AB10E,A99D346638862BBC,7871CE18ADA0ACE4,8F50624CF526FEA8,70D279AF727160EA,07D8B251446E79FB,E7BFF565967DBDD5,FCF94FC7900BB93E,CDCD3C6B090D16FF,8B775921BA11A181,000000001E282A82,A9835AED73773E53,591E90BD95CB09EA,8DEB0D504374FCA1,69FE0C86C56B48CC,BF5880F4D05E3542,E92F7ED6D6BDA48F,5E880655FC0A3554,F6C27C8FEE2E7F1C,7A5A1D9ABEA0B4AE,00000001A1052DD7,55479A6090168293,601071AE0EA2CED1,64767638052F100B,474F84A5287B4F43,4EDE313451E66632,0F113D38643AAB59,7F37ACAAC9EA2965,323AE7D3A9B40876,EE6A5B591683E6B7,00000000952FB7AD,A3EE39090F950CD2,6DFD1290E77EC884,D05B2C7851276F7D,30C17C4CA505E0BE,369AB41BF70872FD,45D44C40BD4D2A0A,AD8E4DABA938B10C,7BFE0CFF9661CC6A,510801F0AD3404BA,00000000FD133936,9E12268E1E720A1F,434ADFD28008B0E7,86697D7FB887B715,86B6761D883572EF,7668379F10964B55,8E6A1983DE0F5E08,C3E64C7520DEA89C,86A6854F318D50A3,FCA1AB7C2DBE4C58,00000001A0B13891,1F3F4472FF076E67,5A38D26B8085EE3F,19B221875AF7E889,A61044ADE5C655E6,12265291594E6122,650229A92FF072D4,6D0DA4B310726245,71C72D5F00A8EE8D,261942662791C556,0000000187CE8104,25AE87FDFF29E9A2,C34DE7B2B7758EB3,59838186FD31963D,1681ECF8A2E8D1F1,F78F7939B07714C5,F9E64444341C5B59,C31E8CEEAA8A27B0,A624933DDC518514,38EF90E228AC89C2,000000007D3F0849,564B722B321B18CD,852E5D36DADED34F,31B66DE94E464284,213BA7C2C9113C10,F59708B7D5F959F4,1FAF1C3C66365D4F,D102E3A3EBDB6D2A,BD91CC421E8304CA,5DCC53C4166CFFEA,000000021689E259,F02A4955E21CDA34,256BF52392E40BB6,C642E9FD5D5E98A6,4530D85D8B14E6DD,064F4887E8D3BE7B,397C2CCB8D9579E3,B8C01042F6BEA89E,50BB0B276CBBCF33,78EE9F1497E8D793,00000001EFACB660,8BA42D997B6221E2,FE4BDA4703F7B71F,C477C5FCF4E4D959,4DF660409022473E,748994FEDB69C2D6,B71CE0B445B3099A,ED0801FD61F25783,1B1CC0FDE0638174,6309E78EB6A37C75,00000000C2847FE5,40D9FA8EC0DF5F82,7B64D7045BE7D224,8C80DCAB39910FAE,43075F89C220926C,9289FF549A147D07,92D68C65E1C17CB3,AD8CAC731C75419C,53FCD1DA5C5D9D00,B3467905A227D7E3,00000000054DD387,A66F97053E5B3944,B43E9B620AB6944E,49E98B434DF7C13C,073136BC3F65B6C6,49C50078669655B6,80B5C22126D16179,D87EEB065319B335,7427F75075C6D724,1BAE752C034BAAF4,000000006A80296E,013EB960CFD87971,3AA38066E35147EF,06F4CB4F36473B10,3109BCC98CA49DDF,048C47244CA01E6F,133DB712BBA971EF,B7484967428F505C,67310FDF173C8DE2,10E32D749F98FB97,000000020813910F,6426F485A4F713E6,431C202F3ACEFF62,5150676E30A03C7C,4E00E7E77B909C90,81B66E2F1B61AFD8,95288474033EC5D1,C2C633B342D6DED5,7ED7386990A3469D,70E8848D4C6184C9,000000017EBF30E0,C37330C94FCAE687,7E22C702DCD710BC,48F1CEB4F8EE1D93,B2FBC97FC3C15612,28994EF33E23D58B,BE568E33E50FE154,E09EC3A82099B1AE,F83B10BFC3CC8B2A,16705EFF489FEDF8,0000000271842F08,414EEF6AF655DC81,B9D302DA9AAADB56,0DCC24E265AC69DF,B4F7EC8D1285572B,E506392E009C8C62,AF49E8DA1CFAA7C4,F70EEA7DF2211F50,F01FB6AEE768AD34,03529EC05B0519F1,000000005C6CCBB9,3CAF15C4F6BD1433,0BCFCADDC5A9384B,EBC5427EF90710F9,7A379CD22FEAC64F,9B6CCF9A9523721B,F3489E4E94059FA6,90BF1E11DAE2493B,BBF1F59BDFA0288D,024CC81069A0AFAC,000000024FD84861,EDB57DC6612892B0,811962C0BF107C3E,45A04D53F981E4EF,15E0F0914B240924,423ECB467038F10C,507C59CA0D8DEC56,765FB695DDB3300D,49913384A6A15182,ECC91D7B5EA7E885,00000001B491EC0D,C61D5E23EBC70CB5,B36A7CDEE9C54616,9E91734048F5B498,D767775323D53E63,8D92C05895C04A5E,B1448085090EB15B,AB30BCF60084472D,EB523463A9631D84,1ACD375AD5DD8A47,00000000AA74E356,71646D9077FFD7A7,2F34BD5A77EC058F,4578892E02BE313F,A287524BB3BCDD23,76CE85C6B8CC931A,B3A9F6EF131862BB,7C8B9945D5CBD73E,AFECFE0B0CCEFBB7,3B48045FBF169DEF,00000000C0908446,AB1489616562055A,85496DF23D501AF4,0AEE2CDF3A4ED7B2,53F6FC1F002D6586,CBA7743A0F1001DC,1DA298D8EAA67015,98799CEF8EF1EF0A,BC4EA07BF9C2BBBB,A1899FAB3F02DD95,0000000225487FEC,AE6D486EABC3C68D,60856596D6435F02,482C3309FFC8A27F,6103F6B018A909F9,34B712203E281183,FDD23251267E61E9,55434CF3DF8BE543,571ABDFEF35E1598,6A6EC5C66EC12489,00000001C3D97DFE,4F98B6D32A7D0218,7766461064A62425,F1032B731D98530E,13302CE5ED16756C,4ADD31BD0918C16B,23EB8023A922D0DB,B0AFCCCF9ACF73E6,C0E8F327024F6347,2AA469E83AA1350D,00000000673EA99E,7A4E985A777C1CE6,5F9859077A9A56B0,F18F275D4383B53A,DE88CD6FA5106D98,B43DFDF444D3B26E,7F7413CE6A2D987A,73820EC1297E84C2,5CAA1BE785A88FC8,9D31DC7546382E83,00000000E2958F41,45E04D202DEE49E5,295E2F19096D06FD,5D86CD55AA1B59CE,D202CC7F968D268D,5FD2CEDBB49C1B52,FA09A62B61FE49D9,8F5079340229F8A9,CE0FAD24FEA1978E,B2DAC736BE99A058,0000000182C21758,7F9C43877EB97CAA,503A37E5D1BE8526,5301D863D128C4E3,E20C27CDC5AB17C2,587FC5A5960C3F41,F0E513928099253F,0424BC9EA45B8426,FF7C17A683937C26,ECD8B72FFC0B612A,00000001C4D51068,AF0978F6DDBD81A4,675BE0C5057CD426,A8D695B78785C31E,1B1058E7CDCD2CA4,45C6A746E1760D0C,558D64613AD4EDC3,D233CF747F1DC463,2F353C252ACC4488,8E711E73D8E9A137,000000010150F3C0,681FC0B6D26ACE97,F87F0DD6061B19B7,1A7D7208DCE1076D,30FA51FA243A9B95,C70A3C4D042D0289,6AF9B81F9AA13D51,CA4D160C637E4F43,59D01B0E9A05A95D,33A3930CEBE5D42D,000000016490A471,5BAE40CF6377159E,903E17F8389BE028,EABEAC5D5FD132AD,F80EA7970FBC7F0C,93608A0BCC38203E,C82972BD443C43BE,81808AA0CB77C465,E841E3EA4A5763FE,A760567BF03B2CAE,000000012C31FA74,584D107BA49D1CEC,0529308926C02BAF,B446D0E1E640B618,3D8E929C6865563A,4605DA48624F60CE,5FDDB94D4F3CD8A7,EBCC3E8921E4D9B7,EE769640C076CD1E,6E95E7453A209F91,00000001ED1AA321,5964219DCBCFECA0,D85CC14B30AF5740,811E1C4EB8F9838F,8107DA262FAD3895,2E5B9E8C16EEDE93,A8950CE8D957E8EE,E84195463E7AB606,85EF8E3F0E4854AE,54C45A3F0091DCB5,00000001E50D951C,DEFCEB9B2C88A58D,E620DC28174E743A,B15B69C676CD1BFE,37D31E5F636FD9A0,EBE0DFB2078DD07F,FCB9F6D548946B73,13EFB61C3C454D68,56A059A107FE63F2,2C348C4006A4EB2C,0000000055FF74F8,182FDFDAC78ED776,ACC752BCDE9805F1,91B6843F844BF01B,0DB7CE3D4A5B6163,520BCA5AD2A369CA,AADD129E6000BD49,3D9553D96CA55E41,B117764720443F9E,5108FD6AA6AAA23A,000000012D8AFCE8,FA171C74D1F97022,F60D78D9744FD8E4,521FBEC9DD688902,0F8FA656CD8ABAB2,76AA2CAF7C842165,8AF1B049A1A8823D,0BB885CEB5F3C0E3,212D04254E113C3A,BC4025A07AA769C5,00000000E60C278A,3274F3F6BF2E577C,9DA0860030CFD812,04F68D6E42C8DD36,9F21B0225289A2EE,DA34E7517BA532CF,F779D36CC90DA8E8,0250840C1D3A503A,91FB017061F47381,19CBA81C94EE7072,000000027043B5F4,5124E93F6AE28B4F,1220A0500A459148,35528B0A0DFFBD65,20A38F258CC8C90F,97306B3D6B8497CC,12480EE44450ED8E,91DD222E2A7525E1,E75FA795A11A24A0,78CA301FEA58D952,00000002348755DE,A800118FDAB9C32E,6ED5CDA9571C66D8,F58950E064F43092,1777F5A3FA33CD98,4AE3FB12A90AD87E,F4C97D470410C3B7,8A64655D9F7E7A16,2CC3D66C743F7D0A,6A39552E83728E24,00000000F4809B43,AC2169C9FAEAA7D2,EF71B62A76802F60,6A9DC4C374472CB9,B9ACACC344A1DADC,F12BD2E2DC150E8F,45DAA911F3C243E6,CD3125B03E48A08E,592FD981509A186C,FD31573457154E8F,0000000054B2B3C8,01F178C58FE4C9FE,AD309D1645297BDB,A3227438360AFC47,BBD76FE3B6AA8D2A,41721A36F6D84583,67787B769B9C86BC,2A2C852AA88FBF7B,624740AEA14B807E,F9E51212D012E791,000000014DDF8E5F,0510CE41EE489C43,6FEF8CEAEB60DB74,B62EAEF78687FB66,AC53C31E820D8A60,37DB7372B194A03B,898AB599A0F89213,01D88A1906470142,D56A135BDF12F378,DF3585A47A811890,0000000142E7DAEB,AB83D45F6C0D5141,FB351C8CDA93D1EA,27B1CDF5EF8C3CAB,20925680958C41C5,1C2AB2F00C68076C,B86BFE984AA18C84,692CC4FB503D1DD1,6A583A0329F10316,71A4CB5C0E056906,000000008E541B25,9F09634FBCBFCCC6,5BFA76A084815106,7FFACEF3F9484EC7,475797B6D4EF12C7,3CE8392CF9DFB4BF,39ACB63F5747645A,504B3C0B3EC65BBE,23BFDCF0C8C6CD66,08573C37E3679580,00000002460B4AD8,93F92C5758C451D6,DADC0188DF7EDAD5,BFCE1B30D27481BD,73AEFC68323BE03D,C48609E821EE5265,9D0B755ACB2D17D0,E9ED3F01FEB5C04C,701AD86FDB0A67E0,F6CBAFDCE34FE2F1,00000001940F3CF2,55D03F8FCF4E11E2,EBBA5D22ACE43FA1,AAD15F9BD7A7F7C4,6AC935E44D4021DD,277801A013C2DA5A,0ACB0D5CCA48CCF0,2C260E85F7551BDF,18D5D1BC1B08D349,8A8A40F4DB9B75F1,000000015886E272,0CFADC9194F51882,88B5301CA8DEF1B9,023ADCEA9F61493F,27D32237137A9CC6,3A1D64B088D6FF04,511F51E342514758,A6820D460BDA1B96,7A2B824222C8D0A6,341831F5A049BBBB,0000000194661C39,AEAABC3751F4E078,6ADCC84E334A518B,CD2976FBBE48AF9F,CCB6F312EB58B8D5,6E58738C6F3EE2AE,2037100E0A2A3EE4,A27C3D933177FE0C,10285CF92E5E1FE4,40CA39F4618ABF93,0000000121238D55,30BC85D893F7E701,AC1FED7ADFC142DB,72BB5E15F02BAE30,5D9FB9CFA70400D9,A16DE09700C10D95,238D2FF8DFD5C3E6,55272C592514ADFA,9D10F2EF56450318,03EE1A3ECBC26F2A,00000001B7CF655E,7B35455F72A69588,0591B39E80991C2E,FB22040329E1DC16,8E67CE6B45E23392,3D80C610FF04ECE7,5FCFF9914F8B48BF,768577F4756BAF10,A7F3CBACC8F7B7E7,4259611019CFC03B,000000018F8C65DB,35ECA2B352729688,BF2C988C531637C7,2E007FA1DC2B730E,6F467F8BC4320B47,5B6985F2EBD535ED,F88EA25D134DE470,7E9E5E09496D4553,A467919E7794F7A3,A1C8499C85D6732C,000000023C7ABCE5,B30A92D64577BC69,E128A48131F43018,6E7BE1FC0BE8B079,48A9C7EEE7EC2438,7DABCD03A1A5EEEC,9DBF352B59F8EC40,709E1490DC2C25D0,7BCD932070F0DA59,501C3E4449EA26A3,00000000B8EAAC8F,EA042289CE4BDEBB,93D74CAA3FF06CCB,85B31C3DAB13B085,49EA7C4BB3714B86,530D6118F9BA1E34,4DC83F1E7A5AEA5D,5ECCE408A340398A,C6429268C3C9C7F7,5A78C1C5E342DB6A,00000001E06A11E7,0362E20599DB3EE7,03DB694981BECC19,3B6B1B9AF740F2B0,58F90B497DB68586,F91D5619AA7B3802,56D3EBD5B6BCD830,9665B4B711614F61,BFF88C97489DE03E,A666870F7A256E69,000000023D20C97C,B0097B8B78E8F5C3,63797AA9A70F4521,935154064A1BB65B,5B7676072DAAD173,CFE859FB5DB42D81,6C0A918ECBD8B040,E5540EC4513F083D,E46F80CDEB9FC780,7144BAA149D955FC,00000002328F7FC2,70AEA222D96715D5,4EDD420FB887C8EC,C374A73643AB6140,6BACA93696E6FF6E,306CBAB5B13919D1,F61B66456F42ED27,DF166C1BF006E9E6,A29359F054FABEC7,E8E06843F4E878C6,0000000233C8A121,F69C249F63F60B53,54C199C486D19E42,08126498EB57492F,EFE7DFF0D1742CDA,05D433E1F3FF3159,7ADDB12A1D96F279,AD667089D1471A5D,4CEDC92DB04DBADA,6F0A1206476D36BB,00000000B55F17D9,ADDF2489955E7506,A39B4D160FD96835,8B64FCE9DD695C7D,621E29D296E6213D,854CB8F3A30FE479,EBE9D7298B1D7E74,D5315EF42D9E1D5B,0F55CEAED5F3B88C,57C3DB8F6B4849A2,00000001C91351CD,FE3BBA0542AABECF,792DAACB936A9E59,7F31A12E93FEA311,63617C6C6C387915,7F28C2D083389ED3,F4A6C07BFA2A5F09,BA31DA69FA9883E5,0C5B3D1B49E05047,50F54B20388A1752,000000014A163058,04FF1BC3FCD4DF6C,216C15B17990BC06,C87616A15FD98EA3,EF1CB059F3290746,0134622B2A54B547,EC9C32D7903A3D26,2E815AE5C60F4A11,664758AC06FE9DA5,396F87947242D9D1,000000008DF3701C,CB388A636EA04ABE,5D87DA54EEF98A5B,E645B24C0D936152,B44C45BAB32EF9D9,F40222B528D247B5,DF3DB2D4487CBE30,CDE0615CBAAE205D,1302FCA25FF615D2,B130E9DDF04A3D28,000000002C7D1056,3B1FBED57DCBCC04,760CD766CE07BEB0,26E247F40CD3DE35,9476CA7CB0784583,78FBFA2F175B4C55,03F45503203B92C7,3C023E5A7F7996D7,9B0AE52A7C6B269A,CEAA81D18C5402F3,00000001E184612A,076F327041341150,5C5133014CA0F292,FE00BC7103D02FEE,10578ABC8DED99FC,1763EC958668EBBA,FDBF5918A071B91C,022C6BB9095A6634,0FBE90B1AF3C3009,F977FE181D0CEA85,00000000D6A26636,F60806382F7846EE,74CD9345AFB42351,59A9A5D7E8F9244C,DB5C7945991CFC71,0781B3D168F382C7,FD52F71D1FFA77FF,18B495C834C7A612,0A15BA36B2BE7C95,88E366204E9B1A86,000000014BFD6841,E3EC3FBAFD816F70,37C148AC93853262,3530C4A823A4B36F,E79D8B986B2D3A5B,E05116800BE1065E,C30BE093C1D3EA72,9D8484633DF4FB51,EB92878D1D48D2E9,6E538B89DAB7C574,000000001F666D04,91C0EEDA31CC9B04,067B7EBBE6C8B612,C8DE4C564F443B1D,7E8C06E958EF6B38,51868B1BFC9BB040,73C8949E9033BC61,54DB0023AE30A027,1190EA7995D7B826,8BEF734A1F6F8222,000000018FC53FC6,F63F320C8F72B653,0EC4DD1583FE9C73,4C838F980B27CDDA,ECD28B5F99DE37A9,69DA971041B80777,8EF631908813A7EA,E5115215C1D93FCB,1CCBF2BE552A9975,13105F7D017F60DC,00000000CFE3B850,AEAE142A59304F8E,E058725DCBCF5E9D,8D4B086766C00CCE,AD8F86773C04FF85,5FAB26C698C0FC75,F590B0C665A6D03B,E9FB9471E9CD33E8,7FC85EF3DE8B28A5,9362FD271AB5B7D3,00000000FDFCC31A,69EDED9F6D1E5F71,548F7EBF4FBCDAB2,689BE56D1F54BD87,7047EB8A9963998A,A961CD54FB81D1E1,34DC050F2BEA3613,DA86C9FBAA75E25C,A2548B0049075B6F,56D9E99D122EFBE6,00000000474C5C4E,2BAFBA63AE92194F,CB0D3FD5AF1D9D29,76373AE0CADD40F8,C6EE31B39283D169,6F7201DC0C676D6D,2870181002DB97B9,8D4350D1959C486D,15F38157A5D594B8,24B2B33D44A348C3,00000001196A20E0,0C24178089DFDD9C,EE0C4F3701D8D069,4D8A1A44CA40BF0B,55ECEA09E631B505,74408EC219A77B99,9BC3893B6320D44B,FBBE3B614EDCA773,59AFAF80505F6A25,931DFEAF8D4B2F3E,0000000127DA6E09,960537E9DC0BCDCE,9A9B62A757E212C1,6B2F3BD789781B94,171B80DB3F57F133,051C366DE399BD92,494ED25E0CF41F19,13A630855EAF5E9F,3C0A6CBAA79E9FA4,6A9436128E1E2F45,00000002304BD1A1,E68589360072ED7A,08351AE21DF29574,73024314F4C56A5F,825BBCFD15DE9DD9,6C08E6B90156547D,07EF8FCCD01981B7,E23E7B6399E4779C,D49D397166D92C9D,66B2231CD133C892,00000000994D3747,F4EC63EC4ED57DE4,3F6369B34D8C2298,2D898258CE9D7B74,3041C04AE93A2011,C81300673651DBBF,ADC3E224C1996D64,7C8909EF15ADDEB9,3D957F89708F30A7,31C52F7297890BB5,0000000225B195B5,B2DED81A71C05797,C87A21DAC3F6DEDB,9A8EC561AD0EC55C,7ECE6383D373B2A2,BB4F60A8C36DC326,3D1D03153E48C2EB,B5423EB218640B44,1D9BA757AA513303,9756A4082E6407B5,0000000136B816D4,CF0FBF4F93132A6A,3C9D6770C6F00BDA,986A9876E62BAAD5,98C5C57C5BA2C373,CE728BEE0B711392,9563FE5A858DFA76,711810C59E52E330,C6128D9569757A44,69CD2C856B7670BC,00000000C4DB2E7C,1B49A4CF07A211DA,EF5D3A579F332E37,E86361D7A2280FAF,F52787015C659A99,E7365EC493EC4834,CC728E408C4545FF,15E8C0635CD8644F,7C7753AB6F68B62F,EB6902ECADAE14D3,0000000109D58720,564F6138CBD62644,DD84196AF197027E,35D8A5DFBE5E1742,7B94E974D5BDF48F,FE4C282E009D4108,289103918CEE0551,66D2670129D78B56,3F454BCCAD5981A1,998529EA4EC10D24,0000000253E83C65,811E957AB4259A56,DBA3DE57FAF875F2,48BD1DC776DFADBA,6EFC41BF5019288C,96071741373D581D,1EA5411E280B1446,C2E35FAF644093E0,B4F944DC96D32286,2D9362638C3C5158,00000001B9B38B5F,2769009C4EE99D2A,F6D8753ABA760FC7,75853653CCC29BD6,E02CBE7B24024CE4,0346034969B2AE18,EAC6EB3AEF41B7A6,002E3FE2635F6A76,6CB6572DE1BB7007,57815850E32846C8,0000000065219984,488EDE9DA4A5B294,F8B2B9873C45405D,B40B8E2DEBF13B90,01ECF02D6EA82DE6,015DA4576BCD8138,103A45B458BEC3BE,352D2F6B54D4C1F2,687683A13A5D126C,266BFBEDF79A7668,0000000113A9EBFA,4BBB86EF986ED00B,C5FA7F49401D1596,508123A0D47CCC6A,B6047CBDC6CE54FF,A096080D697BEFF6,398FA61488A6DEA1,931B8F4383234871,CB1C64BE6EA4FE14,1BF1D49A44818856,0000000253D6B84D,DE4ACB8A74F96470,2DBCCACE5DD330AA,ED4BCE17C9754B10,5FFB74A93B5F4776,4BB12DE454BB12A7,5F353E011A71D2C7,063997934CA702CB,3678EE6A0662E385,2C5D8EB6CB5940D3,000000018073472D,3C12164D6FAF256A,5E8E90CB72EB72EA,FBE2EC45B17C0C72,4F6C79C539873327,0979828E0BC6D81A,8A56278FB6232842,928EECBF5D82B425,A2BF0DF44CEB64C2,57DC257B6BD6E889,0000000014DF6A25,6D88FB5EE546D032,4DF395CAACDC9A4A,D2773597D451B3E8,1FB76CF09064ECCA,3C50CBDA40C39FD6,DC9EDE3A9D59686E,476756CA3600BC8C,AF8891830511025D,624C8B21EE81C391,00000001B40EA5E8,CA3769941EDBC962,B8764842BEF2D546,14FE99782CB1EEB5,2F8BDD5595C65E0E,241C15E459C1BCB5,BE082575B2ED585C,695FDBA70BBBDE87,D2E33F9316F68A22,25F5271E143AB7BC,00000000868E1361,C77DE22D9938C343,B7545111458D7AAC,9E0CFB3EFAB5DF92,FAAC9C8E3472F460,507404BA472B4BD0,6941F6E60DF3BF6C,F791E92AF595236A,AC49C6B014E60442,6ABE4685BD394278,000000003D836906,C7793169D41A319D,EDB2AC03283AA194,DF3609455B82612E,EEEE0708A3EF6AAC,1271877B2958B1AC,335B2D2F8EDA7686,1F9F863A78EAA7FA,C7ECA3B32D21B5E6,66D1498B210EEE56,0000000031DD0AD0,EF8F39A43812C342,AC18F63DEDFE5CFC,E93193F79D04FA10,94508D47311ABA38,EA48474A0042359C,BD5BCC7D7D57F644,D2B9A668CE03837F,5FB43189FFB9144C,2AE68FCEE61C4551,00000000C1D90760,E79B533DD210CD0A,B35819A44F1C7BB8,4063264A97DD29E7,7AC95C04EE257D57,00479E6F2DD30DDE,727CD0AE2310A55D,65F9183C42998391,F87FF5EB52C77DE4,E10DE8664461AFD3,00000000B47EE925,B086128C5E2E1CAA,4681BAF26AF0B8E4,AE3CA046D2DCC9FA,9BDDA281B27C76F4,6D2224CDE3A37FF9,6B52FAAFC6DCEADB,788E6D23E2FDB4FE,BAACEAEF47BB0341,D51B59A92F1559C3,00000000DBD09DB5,D0C0A5777E311FAB,C74A3F32EC0687F0,4E64EBFA85FB560D,23091F73EA9B5587,CB734988A0097F75,D2C73B678E3B1416,43366C37BF9664D7,0CBDCF7784F8B08E,089205243860F340,00000001232BA67D,9943A0A7F12EBFEF,307E3A8D05640858,124D9E4FBE35C4DE,DCB1B7381D3E0E5C,4EAC275E7F2185C1,D2774754BA84B0EF,799FA24D537B384D,81C5A25FD89BC8E0,D3F32BD250234D00,00000001EA38AD93,4C0BE21FDC268E31,DD904B565602C8D2,950991C491FD00F9,1171D3262942E467,2AA3B0A846972591,737BE5704F4DA322,912DA7B5BB8C032D,BBD6A6BE5C69EF19,2ECB5DC6E8B58D4C,00000000A0794056,E6DF359CB792584E,E1D4CA3D19C88222,F7876C6A1F1C721A,2EBCEE41AEA949F6,FAFFF0BD8A9F8AF9,89EB92480BA5D93A,D4CA7BBDCC48EB85,891B52BEE62F119F,524C56BB25E45E66,00000001CB0486D6,B657CE8F61934FA8,56009A7165C49D42,53718D69A7E95D1C,17475D1CAE3F2813,194D6EB0EEEA5483,713F761153A06422,604687E7AD294869,55282FC4AC8DC14E,B2F331F09C16E0FD,00000000E0B1F2EC,D0B23D0E153DD699,96DF9901C841D5C4,2975FA38EA5C9927,8A2E59BCCF2F985F,91C95AFC055D0825,9C95554615AF499E,F6A7DE65A33AF8EA,4FB4F5C86D03628A,D483A38D78930249,00000001A5C459C9,BE96686A8B9F4925,3FA6B2718BFA905D,23461425164EB436,ED4A5C5141D21C14,1E43D7AA48EBF6C3,9DAFC54920252817,7B36D39F9524F3B7,0DD2011E8B67CD55,C5713259EE63EB1E,00000001FF74BDA7,297AE89F2D9A3535,888E5D13D7D61131,121C8F46D25B3263,AAF33BEE7B7A5C97,B20EBAA009E3EE98,E993BD62D59E13DB,D3DFB4E947E3CE2B,4E327D79C4D4A1AB,06E336AE0E25D0EC,00000000011CEDB8,AADA0A16ED22DFD1,CA72730A4E0ED7C2,9A6CDEF04BF38C97,84E6E85639D8FC11,2A972EFFF263E161,EBA2988988595D57,6A9A03DDA47436D6,4DEFB968F8666F4F,4AA5F82B94BF06C5,000000001F6D10A1,FFCA84807B8EEA16,37BA6A478028CBDE,275349F21B0B3E6E,E72D21BCA44FC3E7,84164D7E82DBDF14,945843C5F9D4B328,C7185C524DA8FE65,2447E358A69590BC,37D14F6DA6534F9A,000000027BF41659,AD53E8ABFBB6DFA7,2A35251AC4F5FF5B,ADCC0A9A4326235A,C2F9451A17923C1F,F6519EBD3C61CD0C,319442CE1F74F0B0,13B022C2EF3BCD97,183679AC7BF63FF5,2C4C8293C79564A7,000000005716FAED,BA1B1EA2A32B3C02,E2370D293B0A6C45,D0FEBAA18AB88D00,C9F124022C9BB501,BD4BB47ABC1E33D9,DFFF1A5A2F36C679,E7F28E2B95E211F8,72B21DDAFB229103,3362E8A9E8912608,000000011A170585,92859D43DE5F792B,58E9AB8F05A8B83F,2B7E93F872CE8CD7,A54B2E98AB5B4CC3,DDA93F6CAE7C14CC,046252EBB4556CF1,CA2980E4B0692603,24134D3CA0755514,CAD10FD95CBD075E,000000012BF6B520,921B9F8745F1475D,4774B791A3C4AE78,D2CD8846D2C95A94,67DB07D6E07FCAC4,33ADEDE703E253DD,9FE87EC9BC947DD3,192F6AC7D4033CD9,2ABEDEC98E89FCA3,EE466447D64CD6F7,0000000190454DA5,288ADB2CE87C0B9D,6AEA333CF21CDFA7,FB780DD87F876123,BE99C5792BAAF014,C3E815C66C158834,4B21BC2CE24F376B,BFB79FE7C71C0EA4,DFC0BDC1BBE0F233,996470157B657BC9,0000000268C92880,5813537565003CAA,C8F7D471E7591F6C,300DFD27D85EB6A5,8D2B123E2E9E5115,5AC840E45B6986C8,D0A03102F8738046,6E021CC48DADC477,413F2AC0EC4A189C,3065443BC0DE85B9,000000022E6694A2,7E45EA9246CDAD54,2F506DEF6CF232CC,DC1BCB39386A9617,0F6550F5F56AD8E4,3C9C5A274392ADA2,B0C36F35490732DE,C0D276A10AA570CB,513A9B2BED45FD22,0BC85392D250A943,000000026B22E557,5BE83D085398D2BB,4E2247EFB00EB248,C631345111DC0D24,FC0E35CC121688E7,70257DD93BEEBEC4,6DB24F03293B7E2D,36E917A5E8A1B767,8853464C821C9FE8,83EB4A968E40C74E,00000000FE7BB4F0,60F08FF8F0E340E8,E525C640D1D1CEE8,4FBC6AE96FA77A54,944BE877E8AD0525,C25B7BF3A0FFEE99,DD8A5AD88795B3F7,3F930BFE1359AB98,29B8E1F442825D49,44AE94CB0FA5D13E,0000000109308FD6,AEFCC245DA10C2AE,E52369AC4087D2DF,80C0076EED595D5C,0FEA3F9DE14EBFD7,BEA6DEA1CDD2CBE9,9920ECF3A674AEFF,40F6A1D5F4D160F9,03B66954C1F3CC9E,1C0191CC40D87413,00000001123E3593,45C09E972A2693DF,5E1AC1D99208DD5C,737D1B8F2680A42A,07A369E86677E826,42981B42EDD72503,EF4EB668CB67AB1C,86ED579E591C6332,8D44BB6BD684AA59,7C739C0A6180B338,00000001C91D4406,BC92460991C7A1CD,B8FEC8E4A3F13771,CD439BB38ECD3C00,6A19FBFC5212F11F,DD2B17B4BE43787D,93C0EB15E02F4B46,F7D1E1CBF162BEA0,A2A75A7E3916152B,51C22C304BFDD006,000000001DB03797,958D497CA1D33DBF,0363C93124A60B66,877BCBFFB76771EB,474BDF3B609AB13B,459868F7B66C888D,A0489C1B4FC0BC2D,18BE97BBEE36B22B,9B2C638AE80CB292,F43A9AC4ED9A62AD,0000000223F2A9A6,154755BEAEF55075,C19B1FEEB8833C2C,84688B40DCE69BEC,231A7D95DEC02520,72890235E3021F15,931CDF88C696C8F4,3124054B8A1556F0,67E6E3165AB94E99,4BCE99EFF1170FFB,00000000018F12AD,D4317DFE091A95C0,0262205810A61538,326E5FFB31002A71,5846B1ED97CD1A34,BCE5E532D8E9A1E8,8D3A18EDA8F48EAF,9C8001C0C0E57F02,06DCF1579A5F9F2F,DDC27E06ECD6FB71,00000001481D0C96,601EA1475AFF7B9E,E9BE56DE3FA1B42B,CBD413C235AEC0B3,33700117F710DEA3,81E12AFCFCBC623B,7DFA47EF7E694AF6,B6208720AAD7C2BF,019EB69BB0A8F965,6BA43CCD4AB18D9E,000000023E8A09E7,3AA0AE6B3CB24364,68983DC177AFAF33,E631F9165C0F3CB3,7D1D7A3C67D4E58D,176D43C328DAF5AA,DD60960F0663CDA9,847D207A4B99DB6E,A4FA53B5EBB89531,E092B9F047B3728B,00000001D9D4C7D2,EFDA3810FEDBA852,CF786D0EF76C43CD,9F1C2F9F3205870B,B3A84CFEEB69391C,BCDA60B15DD20636,D282457ABBC2D31F,3A52065DF8827C3B,9509E4C09A9B165D,CB6009207181531D,00000001CA8E18EA,955B2A0C56434466,E6EF02BE92720C5F,9A33118F2E6AAA12,74E13BB50D6994AA,B67E6E2E53C3589D,AA3C2ED7FD0A9B5A,43CD09FB5BB8A11C,AF3CCEEA37E397F2,D2163BD702508CFC,0000000219CEBD82,5B1C071F795C6AB9,2540133980D85338,92984A74F04D7892,5898271BB65AE3AC,D4105C1090D13A58,E368A2FC4C0530BD,8E1E3188F97AE8D7,E7FAD581B1FB7509,8ACB07A5AFBFC3C7,00000000FDB8BFD8,9130644D2F0F1F02,2977F7A558403492,137302694BD29775,0DB8ED8C198492CD,9956DD321ABC9E18,024B3B0D3641A359,0C7262E56CF7213D,D7F418F945F78513,31C637FC823AE7F6,00000000CDDCDAA2,B5E1CDB3E33DD424,AECD4B4415CB29EC,F773AE5BF30E4BAD,8CAB4C33AC75A0A5,1D7EE9319D1B0D58,6381B9A6AF5ED1EC,75CB2C09B3EC789D,3D48E3353B641746,86E10709FB1CC2F7,000000016194C6A7,73B4F211A7A81E85,4C5EDF0E05D717F2,73B7E332B2829696,0E7D99BCC48EB571,0301BF965216186D,3CBBE7BD353DABC6,A158C59871A83253,13A731093E83D8E4,0351E67D0A751B51,00000001ED182ECA,B0724790068B381C,EAEB78ACC8D44B24,EA87065389473536,490ABC5C16531830,07D617D8F7F2B978,932492553051047C,8E9EB77B0F5A2236,93997B5EE1FE08A5,3A8FC63B62F078B9,0000000019451E07,AD03EA4BB6B86634,B133DCFAA65E0415,48DFD8840D3E44B1,A1D2B33E9505BB66,F74889F2F89A44EA,981FB38BBD66CAB2,247E5EE0EC114AAF,91984D43C8D9D573,6FEF7B61B9B0CA43,00000001F570C152,A27B484BA6B7F105,386B50FA4628C066,C3743F435EFFFE30,C11E816EB2CE4525,DB124BCD60CF4383,34F11680EFF131F8,10EE2062306B45A7,BCA5C5408D1BFE5C,8406DBBE28F6F5BF,00000001F00B3C8C,8F4DA845DDC60B05,0AF7DF0742620040,93EA7C8675781EA5,C835E602D67050D2,492886D51075C09F,83A6D2D21B3C2391,07208949E8E44E27,EA1D9D57D92B6328,28C8A06F0EB49B7A,000000010CBAD422,A0B43F9443812A14,8B513298055A6683,2D30357BDD3CB650,B6DAEE0C42579884,3381FA03B708D663,FDF60E6F90DD798B,24CE43E03A0A2DE1,BB667B2BF6ED672F,EED24232F85C1139,00000001F6D0AF89,E753573492A887A9,6A47D8F7A32B9657,53324B978959162A,C209501297077E40,BF7964C89F7378E1,4EED7CA2F88E6CB8,0956DC0B753FA439,0AAFD62AEEAB5CFA,C5FFC58AE7309A1C,000000018C76C195,55BB02C3926A7179,D3EFA127D98D2285,E31B29A591D84A06,AB6B656F145DC1C3,BEAF6F15C47158A0,13F864DAA04E53C3,9CC68D5A6285A8B8,E814B27110CB7356,857CB261AFF51502,000000011CA20D93,A601E664B5DB5029,697132ECE9235E05,024B375FC8286C32,B3F98CC72659D932,FAF51DC655FC8A6E,052BBB082EEC6793,9C25DF2FC1747803,BF4A569F9C5F16AB,7B542822294FE8E0,000000004C50247B,B16E30C50542A6AA,C9C0AEEE0CD9DADF,1994A9BEB20ED56F,5153EDE471FCD0C2,CDF5E4EDFF9DDFD8,DF5EE981C6BD8E86,BA685050A1A759CC,28F5572F4280BC99,D9BAC2B0D9250452,00000000B1109E5C,C31BA7B2ABEE6C47,2FA870B0DA75DD9E,FB3EEB22518B439B,9DCBD7E59F6581EA,93CE09397C812456,B7862B466860BE8F,F20EACA222B2EDB8,B97F7492135B9495,51B6CAA93834B5C2,0000000250793CC5,33C6FD5A6464B339,72B3E75EDD68227E,9B66B5E1BB0080F6,395C2A9A614AFD18,B5CE27D4A65EC651,93E248D06E8D4316,5EB9BF50936D4EDF,1241D5CA31B85B02,F5AB34823B9EA2C8,00000001FB0CE7BD,1E9E5C5E49434B6C,610DC64282B5456E,E94C96C7ECBBB2B7,F06B6375AF7B2171,A2CF87B92CC1B0AB,185496B148531141,30CDAF734920BF87,C237173B29166F98,10074646FE3BF092,00000001A2D28B15,76AF7EA6962952BA,0BAE1C9F76BA013B,C485FD353958FF8E,9676809C697FFD71,F565A0EBB79F1F26,46D5BB0D0F2F9041,4410EBAF2F23BB95,EAD0F2C419A53407,E9748666C679CB0D,0000000220D2C62B,907DED361C91CED6,563F7A167A11ED6B,5C2889F8518BC395,B08521A966D22CF5,8ED2358E93BFAD3F,FA5D8B45671E6FB4,806B86D9AF6D92AB,3CE0176AD06E9BB1,8D67C450AC006478,000000003F68BC38,17844F552B6C6F71,6C311E743835CFB6,6615373BB3E6A310,9F1784EF7E65A098,5CFEC147DD2B9FD8,7A2B4F361DA30743,43A8E645DF1A9520,FA5E0DA872ED7427,0ABE81683FBCD1BD,00000000ABF169BD,5B7A2A7659323147,A9815C77B1F1B0FB,0A6BE008AE7B1DC4,9A25E0CD5880DE7A,C15E1A72F9CC3B56,350BDF2ADEF9DF7F,A5C3331AE076AEC6,685C3156B6D67AAC,7F325303A5356F9C,0000000273618A53,79A956A635612437,9703BB0483168DFE,3EA79BC2760FE8A6,DF7FDCD5C2AB19AE,75F69B8D21B74E58,F6FA3086C0C6B6F8,659E8318EB184E97,32EDCCA299043D75,A5B5B0845EAB3652,00000001F590A703,5BB80EE02D2C7ED0,F0F0DD1C3CCAAC64,6506E26EA63549E9,CA366F644E32BEFB,1805ACCEAF21207C,36D15BEDCBF4D5C6,92344338D70C81C6,B809D29600821A01,FE733FF4B456570B,000000015045387A,8E75E912AF04BB32,2D34529E71A2F25D,D33558985BBFD0CD,75AE57CB9E52FBA0,59010ED170C3068D,D2453115059D4643,7C63BE63510600B4,2E0A8559812895BC,990958DD4C9B09D0,000000011E5F2650,D2DD824D3DF24B08,84A31288DCC19926,83304830DCCF6F01,9118B1C2CD802CEB,A568F2B0C0757183,6D4A0FDCB786656A,B485338F2351AEAA,7C82DF01FA10957E,E50FEF1BFA1036DF,000000016CF5F46D,21E2172BFAF6BE2B,B9030934A91AB484,C0574CCF635D2166,DC42450BD6DDD750,E1947CDD7DDF6F3F,176BB773BF8F625D,0AA9430F015B6B3F,E24EFFB41C589770,694FD0AC35445EF2,0000000110A2984F,940CC764E9E30395,82B05BFE45EBB78E,BD2146E53A77187B,E0DE84A413AE6368,A442B54F50E6B57F,F97C52BF16B9B734,EEB2C6A28F2B3C11,E0BF878356E71F38,F764476F25100F7E,000000011E712C2F,F0354F57DFD30D5E,E79AEA645C603BD1,0A4B17C7E9CECBFC,126450401D255883,1E3AFDDB260352E2,7D91CB60CFC4CFB9,C81087486EF799B8,7D9B0040AF7BA698,F6879269EF30EDCE,00000001D1DFEF2B,B2C912E3B5C1C5B3,AF1BE0278F9BD8D7,0D60A9EAA529A31D,DC4F19B4FF54E29F,A9744FA05DC0701D,3578C5CC225FC891,0C4AE8C67F69060E,D5840B2B6576E721,73FD8FFB874D44C9,0000000104FDD5A8,C72B47717AC37D5C,AA43274E28766EE0,9753DE0F89A2A26C,1475166A094BF3C9,4DC5857A41740A9C,A82F6AC928BDF36D,77489EC4862C5215,8BFB5398F945FAEF,06DCA64A68414F74,00000000C8B69BEF,06E95F32E009D104,0879A7CA0B213F07,207DD750C55475B1,DC5D8B57B7A42708,D55D6C1AF9A18FCD,E502B2DB06782AA3,98DAD5ADF0C5ACD0,8BB3DBA5917AFE10,872217BDA3DCE61F,00000000C2F3321F,8EFB0FB4ADF74ABC,C16E115D1B58EC74,68A81E4A8E9ACA99,F1E8773BDC3E97D6,C249152D61D3FACE,A74DF2CF116D9747,C71A17BA3981E34A,DD5AAE7DB00A05A8,27CC581E40D971EC,000000009AD51F50,10F1EB7EC85BB70F,48FF92CA83D43141,C863301463D2772C,46BEF0166A625654,B5C60AB6681649B9,3E8B377BF70264D1,C4FE385F212375ED,21C8B33479F9D6C1,500135EC062E4419,000000022195F49F,6C671936744E5A94,2797CF267458EEDF,9C37F17CEF09F386,F40BD79728201E3E,A32CC73777A7AD1D,0972DF2EE444019C,2005C103CD8829AD,0A11E3CD90FF4B56,80EE63F11C5FD847,0000000270A751C3,6DF39CA95803FA56,27CAC3C2BB41BD51,CCF25B7B7029ABDC,9C2364E4C5C2C646,6BFF13301B488AB4,1AAD63DD2AA2C90B,9093038C13E801F1,78337944721D3507,8B97B0C0F6D5DC83,000000017D550F95,90AF3849034640D4,20C87C8F309F8317,7C4828AA169C9E5F,E7361ECCEF1477AA,624C2EC85100C5C7,C77F3C8F44F60F94,E95C099F63502C2A,CE6FE4C3F39DFFD6,057A1EB522A66E8F,000000016C70DD80,907AC0A272B62736,20B9ABCD4BC240A7,F5482CBE9DCC680F,FC728958CB435FCD,982D51B8819D4165,D14F08DCD447B8B8,42B62AA9A8FD12F4,7FCB1488946FAAC3,6C4238541327E7FA,000000023D88EF7E,67E9C4771DF7E4B7,7C3389EC75EECB26,FD5912790A3E1969,EF05E085E9A33A38,F061FD6B22E8D79C,353D803197FD7F0F,7B90C14E412C1A5D,3BDCCC78D30AD272,403828272E1E4CF0,000000000EA663CB,D977BF5F1358F043,66B1A4E5E6A53CED,9FDA06A86A5532B8,A890FEABF879E605,429CBEDAB59137F4,CA4BE0D7585B0640,FCF25162301C8A05,8507E731D60A5E3B,D8DFF18E33291522,000000026AF2B3C2,DC5340211767022D,CBC3F2FB373979F9,5EB1B42643AE3FDE,96AA20EBD96AFE8F,13C9808B20047611,9BD5F4AE9B2A2821,2D4443E2713D6DF9,A7A7F030B2BC02B5,4B11CE4807E2B13B,00000001E649D937,2DB76B983E94DC1E,9160104A36F69225,674762A5FB44CDAD,CF954DE1143E7470,3820B2F84A3E628B,9EBB4AF2860F954C,F56E77D39BD4B704,ED0793A3C3C4553C,99E3802468436278,00000001D360B833,45815330170CEF90,0D6D478CF2C260D4,804A175AFB88961A,B857AA1C10A3ED58,DBE1ADE5BFA58A1F,851147CD4B94FFF3,0816611B291074AA,F89327E12095076C,7C1BF243F2AE169C,00000001C9610254,135B366FF727F629,255DB6FFFE0493D8,FA1356DA8E3C53B0,6AD01EBD2F1B19A6,2508C9C5FC40180F,C9F064E2FD34FE52,160EFA5454503C45,F3CD354B4FE47861,66303516A8EEEC03,00000000BC99236E,E9D6D31CBEC8CF07,632ED575F75124D6,3240BC24FEDC3CAE,274A77B948498177,976BB492C942A075,4FF5D7D95DCF1990,F01E87B64B16866D,B010C1D7635609F0,6870D71BA3C8C69C,00000000E4124219,5389477BC1FBFD46,436B240E0C5235CE,A6D2E353858D6AAF,DEA93598559DAD33,D262F1B48CBCA598,3E0D43A8E51FFAF8,AFAEDEBCEFE417C7,15C14B55B4027588,4C654608098FCFB0,000000021385A1EB,3EF3B3E093BA9318,EA7BFB1CD0E7F6A1,7A6173782910C53D,94AF2D9F5F0181BB,610A0A14B38F1F65,41CCE368B656B48F,BA17B0506D2D577A,6B05446832231A75,9E1B5FDB0A3AD39E,00000002527C7D7A,9463E787E3FFA209,17C85BC8CD6A691A,DF5909329DCED4CA,07DE73E7188EC93C,0910B8D524A00C5D,2F89ED5BCA678871,F5270A68FB46DA4A,1C9C4F539A434487,66873FEC785355F5,0000000027FE0FDA,8B11B30273856BAC,5CF74C80C478F9EF,E1DBC079315681C5,3C69551E5AF6866F,37C1C79D8A87210D,8E21A7837ED9BE4A,962C34F9A695A204,3C11638A24A3C089,C6B0C9FD921E7820,000000003850FFA3,B3566B25C146AB5B,CAA0F0D211F5EE68,09448F0AA7C0C3AE,46F49DA6B02A1E61,7476CE561457E01C,C8CCB6AFD813A3CC,883A97E8170E0E66,04E974732C6ED9B5,27BCBFD59F8594EB,000000016DBB02B4,95D7A49576FE8024,CCFDD4C43E74A541,EE59E1B00D9F6C99,7B3BB5D6558FAB1D,041A7B7C1DC0E25B,5A8343B5E01F44E9,94F3CDD6BD232C2B,734B0283F25B0BB5,1983149D6A52F1E2,00000001E9A23350,4A872F20E5383666,D106E42925C954C4,79101412AE1C2896,70CF1EE24DDAEAB1,FC1206AE3E57C212,F5A6BE205B2FC5EE,A63D987C2B777AA6,7CC0B725741A36FD,9E4F63C10F560824,00000001859ED8FD,23623634E5FCD034,A93B9EF4778F2883,C20A0A32B06DB7F6,1114268002561CCE,5C66C73D9A63BCA4,1E539E816842554E,6F36753C4712F289,7246DBE0C6C63BC9,F45CBA5E3A37D9F2,0000000005161575,6A6D47F78EF749D4,E7F4709C0F67B730,7C462EFCBD06BE06,8C1809CF7DACF1CA,36C776CFBAF8FF36,66B69CB1A2521BA4,8794B7FFFAE593E9,AA03595787C7AD30,9A2D79245E974613,00000000DF3965FB,B3671A1A74D97D56,FC9693282593D00C,6DAFE3C9304D5F23,41143D5AE73F4BD4,B9A6C67F8CB6831F,4C161618CC5B42BC,97B5C605D335760E,C750761B53D34F80,063EC511D5170590,00000001ECE1BBF3,CFE664B9F440F860,61D92A8977699F86,C652CD37D088D675,7A3F37DAC9E71D20,38A27DE9AB9CB2E4,656F1FC482B30E83,B97EFED7D0F7025A,6B750D74959C6094,6161C217DF7ADCD8,000000020DE32E7B,74BA3B2392439335,A2EDB5E1953C735F,A8B1D7516ABF3ABF,AADB2DC6FB85A36D,2D06B48AA8A7087F,FB0AC99749803717,4E5F282E4FA5C54D,55F81D5E16C8450C,DD6A33E3A11605ED,0000000038CC319A,74852A8BDFC476ED,7385E4E5B8B3C05D,AA63296100684848,F963C5808E92A3D3,AFCBA6002AB9BC82,17772E8AB40FAA56,FED28D0534C0CDCA,F7A654A14A204B18,F36C38B41606BF5E,00000001D8B7A19D,DDD2C01F8E4D997B,52EB6C6F98E78D5E,A5DDE7B0B65BFD8D,5EF4FE8B6118F5AC,591102CEB16BC5F4,A20E64309D7449FF,77DF6DD428C5A43A,FE2A586F3B6CAD08,6559883A83BCF5D2,0000000104ACA4C0,B226D236C9B4746D,433E5FFD5CD22459,A47BA6015EB3E4C0,4E79CF5E48CA10F1,719AB3685DA973A1,7FFBB1C3AFCCC690,D032DE3A56DFE0F2,D7A4F629071FEEE2,6E9DD0F4ACA22685,00000001B8F3CB16,87CE9EBF5DA83A4E,3EFAC6866D6111B2,6472EC56A4C0171C,F755CF9137BDA17B,F17B24425D0D58C6,54668AB3EDE86BAA,90FAC588645B8C97,5C6AB3082C543362,E81F606CE4080214,000000013EA746E0,B84AA4F819FCA6F7,B13CD6E6CA756859,2CB3A946CB4CF57A,5F7CF43695866004,1037B6DFE8C590D7,E45C0B89DD5F97F1,A4856B70C40F9CDC,0DB297BA598EFF55,23E01C4678E8245F,0000000067B92F3F,45A28AA04E44A09D,195F5E918F27B78D,134958BE081DB607,75C54F26770DC997,C0F6313A87AB8B61,D66A2A72563384C6,F0FBDAC572DD4338,B0EEF38994186479,8B207AD89518CCDC,000000024644E8B3,E0B4F837016C7B83,128A21AEBF772475,0162EAC9147B9175,4788D6369F25BF74,1F99BB9BCA443168,3346BF98524E4EAA,3548278401E43651,70C28767F1B23AF2,E8FB6C787EA407F3,00000001FCFB934B,A762457BA3E21582,E3C97471A84A7555,B128C59F1848AEA7,864336DF1CDC45A0,DCF41BEFD39E4C6F,3BB443AAEEE7F014,B34B228C7E148422,44784075DE3759DD,701EA96CFC32519D,00000000D678D433,5EE897DA90202AB1,112078930FF031E1,910E9B932E1C1C6C,BFC11894A8401A12,10C9E329958FF224,91561D0E85E3C92E,934A28DBF89276B4,36F3DC70086AB150,14E98F7EA271545F,00000000EAC3A744,8C1AE4307C87FCD3,8237B7BE541C331F,4B1AEB306A92FD33,E3C13677BBE0F2C4,78B9213B680F5A18,9BD9BFC3A7ECDE00,5AB90611F7BA0F0E,613E1FC770101866,8604C899E3C35C9D,00000001C55170D0,CD3AB27993D8656E,EA9138ED2A9D021E,24155E805EF14B41,2B68F63089EDFC8A,ED82EE478BFDDE44,E60D50DE3868333C,A9B06E63B0D83B19,1BC5F3C8E85E6B57,EFFFE64133BE7496,000000023A6DBCC0,496D0B0A58D64729,163D5A86DD894052,0B6159CCC8E4C38D,E29175E31AD2291D,6F8E25E50A1CBA11,40ED2DBD777DC9F9,CD39DA5747D38B15,E34406A70DEE688A,E78592161F968B45,000000015C7E2D4C,FE8719F24DBC8902,F04900FA9C37E064,BC54A320C59D7627,818E9EF561AD0573,40776A1B3E4BF36C,A7EC45D03EC848A1,732A2BA50630158D,48689D2DA6C04ADF,976D81ECD8460556,00000001F0B89CFE,4AA84CAA189ACCE1,90C96E32B743A329,A3087900F88DEC18,35E07EAF33196DBD,BD7B714639CBD1EA,6963E26684192ED5,546B952D481FFF26,E8C9721D3493AA0D,832575BCE0AC966D,000000026C5E14E5,8CE284804D4B8C64,2CBA89475315F044,BAE45A74430AC1EF,6A1FAA95121742D1,81F9CBD0D004F0AA,C1189F2963C627E9,49F113D750D7A357,C6EDD008C79CF2E5,A527AD0385912F4A,00000000523C26CD,8A28FBC691D53142,ECD4C105640DDEF2,712A44572A8D0ACD,39AF0B901B94D268,6D5F58F0985EDEBC,5700003C710EB2D0,16EBB774B2092899,A9D0E3915DF69329,44B5F7C54A941DDE,000000020F65381F,927CF8A1114C65CE,A57E25AE54880D54,77EEFBA6DB48789C,E9FBBDCF4739AF66,014F6609F0DDDF6C,96BEB3CDE1E326E7,D4A29900A9CE757B,19FB01EB3411C9B6,268ACAF242BE94C3,0000000048591BFA,876427084013093A,5A5681BD9112E77A,5DFA5DEBB79DC06F,A23A3D82C75B63B4,FCD9FF06CAF28CC3,F2BCD4144A057BF3,5BE016030FC2957A,6217B83BE37B5F0F,2A6BA5583B84DD73,0000000054CE9C24,3444347FDDFD1DB6,515F46C08287623E,81168ACE56D4391A,6ADD22D00DBCBC6F,259B0FE55C631FBA,0515454C1B4F1DE7,9A342F422CD48C14,AACDBC77DD9E0C1E,A6D7FED2A0C4A35E,00000001AA07CE6D,3D716D1168B7EC58,E78C669B0D7CB819,14F6C3F882593E60,84E09F56BEBE149F,B71FE0500B919D85,6B0FECE5559ACEEB,AB8094ACA9D65819,D97D8C87ED53DBB7,D39822C53B10071C,0000000103600C15,32E090057F40EA3E,240C73094925AAE6,9ACB761EF500ECEA,45507E24DF603DB5,3A2C6EDFC12B5E8B,D6B9B0E2E644CBE7,ED4C3C756BBA4924,5692F118D1FED278,815CF4809E6B0928,000000019C1A6D38,8CE2FE9C50B02A9C,51A6B0FF201E1CFA,718D9CA444BA7851,8D13C0CE96444758,F7A0F2067D36142A,25F5E51D48C429DD,DA29E8736191EAB0,EB7BA0A8ADB8D273,191DB24629D10535,000000020D4ABB0A,6D356CF37603BEC0,A3E89A4715704B1B,968130D8A22A8AC7,CEEE661B372B6650,A9D7F13056323BF0,2BF415F4373E7226,7D691B4A83233AFC,C21DD60D2C9BA4CB,96E879556D1D329C,000000006A5F6010,3D979C1211A86156,5C7F10E40E14A40E,339366597321C923,12F2C78AB4C4A590,4965B2821EE2DDD6,4C5CE6964F4887AC,3214C387E84DBF64,B5842AB6004BD931,5AE8D389393CA525,00000001AD661E4A,B7CE097C505508D4,BF848CAE6E54870D,5644736419E35401,53CE2DFC81096D9E,89E8D3FE804A15B2,36760A54B2966DBC,F509F2088A7B68F1,BC1C6CC75DDE48DB,05B168D53391C582,00000000E5F5B759,CBC3A27AB1EE96DC,0043657EAF0E8BFF,1716374AA4994400,60D4441F0D3E1264,A7BD0E9FA0942A87,69E2689FC8498134,52E5EFC0E9145F1D,2B71871D78A7FAC6,88C6FECF8E655D2D,00000001E34D26A3,62D28C6222C2DFD0,F66C7E18A2AB200E,BF810245FA1AD8CE,D559E159884A6D10,6BAC295EB947450C,3170B2331A484C0C,6842F7255F2B61B0,BBCD5A638DE89C11,F34131A0DD12E201,00000000BB8D405B,07E88DE5C11F46BB,82A5D4CC7010E0C7,8970E2A175CD4651,CDFE4BA14BBB8D41,724070731A74022B,2AB96D5C83684FCF,64F9BB576AE61D08,1EB90047CB896180,F63E77E80BD9BA60,00000001ECFB0FD3,697F700A8872258F,FF9F75F6BA72B47B,93C4A25BB45F0357,5C95D2037A871D9C,BEA5361A1EF27FCF,24F5FB0ED27ADDAF,0EEED7923A4162F8,7DF399C426A952CF,7478461A7312CFB9,0000000166517D36,60F39CC928FB6D49,6377E0397D2FD8BC,667637109F5A9103,AF529BE03C999AC6,9310A8D3B200D671,BA6D910C4AD013B4,CE8C5DC29436D63F,8EBFF26A9E28CDD2,B5BDCD526268FF75,00000000BDF74F2B,414F3CA62B297063,32B99A5013F59D9F,706B5D138609353D,16273F161019D037,AD983C8B12BDE084,E7F07F1485168C96,9D89963AF12EAF6D,6CFB8AB3738DE008,5FE375E41D25CE8B,00000000255971D8,17B50D7E9C2ED567,33A966DA7A4A6349,D096BA2D6BB29235,CBE537B5A3299998,2E6CCDF6EBCCC7E7,FACCB5038C064D05,CF8310D293DF7B34,5F2E9A71CDCF9E6D,2C497F2DD38821E2,000000006CAE81C5,EC19C31E503D808E,E2A1BA3DA45B45D3,A4362F976278E818,D07834B873819E0F,D7B5C09B2FDD580D,CD78F4875BEE24E5,FCA38F169A2292C9,DE10B688A3657FE5,A8A23C108234A8C4,00000002642A71EC,F5FC10A61DF3190E,D55FC545E5AD0220,D3193B42E3B26DE9,60ED089CD2D8EB67,18656EF562D8D411,DA0CF30790AC1C6A,50CB9DA05F9B76CE,99CF958C7CE4292B,F19D162A43B876A3,000000017631D17C,296DEF5602F0F8DC,F17EFBC48BDB52AC,63F30EB18AF1811C,30903E8984A9E0A0,5E4D487306DBA8B5,DF6AA884D9D6C5CC,BE604E2BED5E1479,2EC2C7D12A38EBCA,0F4A315C8E32B1DB,00000000CCC2C748,7E4576C4B6C799B2,CAE5EADA6FAD590C,BB3AA4D0D5E8B0F8,30F118CD43C4C681,B778E3A8DD5C1262,FFCBDF770B7F187B,7234CF6B643FF3E2,E4F6CD90635AA91A,D1F83754F5B5571F,00000002262E1962,078B1D92E7B0B70A,2F97D3846FE116D2,36EEEFB24BD31634,A2137504BCE504FA,E6E161356608653F,14128489AD4AD8E0,C2DF1408EE01ADA3,C79390CC9220A814,FB4B2BD4D54AF58F,0000000047A6AA75,54A91F7419E94127,6DA62E2F53132B97,F64BF181BF88536F,20AE733067875804,F07ADAA32779CA3D,5F8850CCA664A5A4,49AD82921086DC13,F8F8732C67E5E590,D2CAE4C9B746065F,000000007BE90D92,18748FFDD5BC6886,3043FE01C4597785,6E89A8DB7A79B350,7F6AF6C4C8B34905,46438197E299D3B7,CFD4CCEC056399BD,E740325618478A73,D03BA6C957999B79,6C98D4E6A339DBFC,00000000BBD53816,1395B06EC4F0A34E,B00C51DD7E54867B,9FB1ADB0231773EF,3A4DFAC08F04DA10,43566D0EB9BD213F,03979D18D01B6DBD,DA2686E9312AD645,6C4394858C87B74D,71B0D3B95690814E,000000025491AEEC,F7283DB75E8AC67A,72A6F497D30281C2,F74B56CE4CFA2E76,0F54450184F4ED6D,7E1703FE863C9005,7F9CF01162AD98DE,917D54BF5EC38E0F,B74318D794676C3B,4334486E03796FC0,00000001C5A257C1,360209F374CE2B07,2F51CF05D14BD874,2CED2368FBECD851,688E6C2AEEB767FB,1F997119C27208CB,B41FFBAD48E736DB,BD696D17C753CA85,D49BCBCBF29C9C29,CC3962808CDE66A9,00000000912AA469,A47410C92A5A42F1,374A36D14BCBD036,6FCCB4841CCE826A,FAC60F7049C7C5BE,D1D327272254D751,AFB8B064932B68EC,AB27C0F4C059EF37,3094840D23C29B17,62B24D50C93491E1,00000000D4D675C8,DB5B2544806AFFDC,6BF60D194C2F298E,57C75CEAB922026F,DAC8282C318F08FD,4077CB8F648E4CB2,FA348AC6DC7F5550,2B87041EA809A877,EA77F682F43D3365,32CDA470C3F6B8E6,000000026FE4FF48,5FBF060EB29AB794,A0B900B7FE220FA9,7623132077F1C307,4E2549C7D0CC66AD,8EA7E7FD563687A9,E80EB3A3E910562E,7A467A680CAFC26E,B2502FA3809C7F37,C76E7A7798509E1E,0000000155052EDF,04C99382C64F69BC,E0DD89C353820FE9,8556DF94BBB09DC6,2C2271AFBB6B8023,08BBE4240CF2EA84,32AF978D071FC129,72227587238DC2EF,81172AD96F40EA21,1C9A0DEF41DE62EA,00000001AB028F49,9668E25EF577C488,4301502DD24FDE7E,9B5256D6878C7CEF,7C4A361B77BCB0ED,8344D763F2BDFA24,B3A5D7E50E0347D0,6393D2C601BDE3DF,5981B6BA3E299361,DBBF387A87492EB1,0000000160F36631,CB21CCC6DA46E65A,0F554ED7B4F08331,D308C7B6F8061D1C,BF1DD4A8B0E7FA9D,2DC9CCC34D90FD58,0E8AE8940ECA4E6B,DA001C5B3F0E0763,B32CDF5809316893,5B5374DF8AE52C79,000000014BF6F0BA,D6313BFAD7524469,AFDFA4BD09015AA9,81B06BF2FE366A7F,E051A4F6AEE33795,E28D197D5C37FF24,D436B0B5F666A66D,EFE3A40C15B87C90,3FDC7E87AEB98FCD,CB0914D166F41817,00000001A0A7E854,8BA351F8E86C22CC,117B0E80697E0785,9D780A83833C03A4,928B81B3D110ACD3,45A40BE7D1059F04,2FC52203FE918B04,559F56CBAF995E9B,9C9E91C85AEDF44A,CB0375646057C91C,00000000B78D07F5,B893A50408E6E3A3,E174427FE61AED6E,89E4C5C6ED163CBD,B0486E96D008A64A,C37117D7F62377F5,3E5ED5CB90814300,36FF684DA3B6AF18,E8FB83808F3BCA93,1BE01A930DC7A622,0000000187545FD1,8BCD8E92CBDD6B68,1DCAB34BCCF2CD10,65F34FB90614D860,876A480451F2BA0A,23A2AD18E99B45A9,2F7BE95A41F30907,06253B445BF212A4,93FB78F261800AF5,DB48C91006275FD6,00000000D22600A6,30B9953AC8EAFCF8,43F6AE017F6C9FFA,5DDEEE09A1D9CADA,5DE4B6C4864FA5C1,4096585296B8B524,30216321D184B805,2C2301ED3B541A9C,8B657C9033420853,4FADE8C4DE4F51BD,000000003BE23741,3C18D11D4C4A4FBD,AA6A765A470B87ED,DEDA69F26398F4A3,D46BF827356ACC34,2EDEA234283443BC,AF42DDD322157243,92B7A38C6AF90393,4E6E9B71A9B407D8,9145E67D25780023,00000000C1E2EBC7,094615754805F5A9,0DAD50FFA8B8E7C5,C6AF6D94CCD21B1F,60866D16FE364243,462DF0C749B26336,F6D236243639E302,B2A6E826624015FC,7E1783A61CC19B4F,51B91DD2599A87FC,00000000D6486B16,83E0C04A0C4D3E10,182213CA56B9D25C,B7B54A1B25F7C059,39D38F9099AF5362,7319DC1459F42615,A97B71CBEEFD6CE4,65C598B47D6BCF5C,56330E1990F6C2B4,C0457A5CADBB4785,000000021D00285A,3B567470FC23A56E,EED4DBDFDB2EA396,92D53A5EDD8AEE63,33E6120DBB3B4460,32C85AE9490FCB39,3FCFA6E1F1512891,BC4B1E05B21CDC93,F4FBA5A9788228D3,EA6CA436218EEB1D,00000000ECBE2AF0,93B8F1A87A74FAD5,484CEF16A37CF65C,04228C7E27442EDE,1386C7F06D95EFA8,13981112306DABE9,849C7D20A8DFD346,7830E8D137A891A5,4C7E0B049A65EC32,2A04249BBB7B314D,000000011FE0E0D8,F090172C44337633,D6037BD08AB07C4C,F619485236BA9AF4,D2E48DA6E512277C,78206D366520804D,DE5FE0547BF9E27A,96E3D5D006DE2656,6CB779E76291B1C4,2B99DF84AA4F5B8A,00000001D4F693B1,916ED37D7484FE2A,BD3782667ACA30F3,0B7F01FABCEE9D5D,C74C7CD108F3BC5A,A1810F9A17DBB943,34C5EA7DA681B5CB,8D04DF9245D4C7AD,085F95C5EF69CFA2,7A85F381CED62B0E,00000000BDE8AE4D,644B62B14F67D9A0,4F3C1430E7379F6D,09025A07DDD41C57,421D680FB5C520DA,1EFDA8A1CD4F1733,83BF1FDA976E7346,CBC5DB35B8C22D47,31006944E5DC6EA9,8BD82B74F37EBECD,000000025FD35EA2,453EC94BB558ED8D,B7C234708A78F8FF,893225780A4BE704,99D0DA0688524BE9,EEB720FF1FCE42D3,A592DE465725D077,484A702D65ADF4AE,4CAFB46FEC206CEE,F2419C7DC023FD77,0000000226CA065F,305F976EFB6001E3,45F05C8FF1744C57,537E4F34AE5DA4BF,3349F9F52BB02CAE,6861F3A60712BF9B,19FC680A1E62853C,C03E38E7EA797B4D,CA6E5B4E1AC17395,B13381B952EB3842,0000000068B9A2C0,A631FBE6C2954058,64F810D098219A8D,85A24AEEE243C948,3B8E65BDD1A6F2F2,8ABF2C8072F698C1,38E3E1AFC10C40C1,9FC01DE179EBB2E6,9B6A0A739CE1FE8F,728EBE94AB463788,0000000073C43FA9,AEE20A7F23115DFC,C1B4AE10B597C0CC,E846443E4E9B2372,62A2170AB9209F19,A03CCBC5E9A7E8D0,F72D99F8F9C44FA4,2E4A0077514CB591,A5ADAD5C481148DD,CF6DF63A007A59B2,0000000224C169DC,48B0566C3F2781BC,A2297424AF3F2DA5,3661220660FCDF2B,0482606C38FDCAC6,9B70C76BE53A29E0,B459B9557B3F6F34,B836E3DB4AE2976A,A5E3AD4C27CF46BD,28A6006039F81CEC,00000000670A70F8,9E0D4371F5871326,32F0CE4C88FF2D0B,861E194E3DFE4A78,3CACD61AEB36A4AD,955527734C839228,D152F916FF00CE3C,E346AC73A60AEA2F,BC0F4F8F11C84FC6,5D0FB49873ABF75E,0000000269380447,AA8C80921446F66E,672B1E0D3404D7D8,9DE62DE8C798679D,1A842488B3304389,624E76BDD4EA83E3,92E9170EF0B9F87C,69337630960979D4,49B7FAD68DF450F2,D670CB98993EF60A,000000013F1AE618,562A9AC4A5134A4B,4947F4516036DD8E,FB4C5FBC2F97A07C,ED83DA9F4B7B0A8F,73B3BCA63A32A656,492A14C7FD1432AA,B64EADF10F853C20,30B8ACA72EDA0D20,B95C0CE64742EE1A,000000004E16AEEF,05BADDEE53C42C93,957A2EE16260CA31,37FC52E1C9702C8D,EABE5AEF35BCFB21,063DB141E6E0BBF2,D1AB383B3C454FEC,711FFE472F8E873C,6F3119BF266D3437,B5E4BE943C9EBBAB,00000000404ED8C5,1ED090FC184E9ACC,607EFD6655C3CD45,0937888DA393FD3B,2CD59DF6F4314B37,06D9387F9A3F0E44,DF8248BF778C5590,A49EB82A663FD7A8,A138B7D0B4222996,0E3820043E8500E0,000000022578ED4E,62543D88983BE752,E6235ACF5A8E1186,87EE063586C01BE3,98A7A11137B891AD,497F3A92F8789546,24E6AA94F15D3588,318A8F67F8FAE6BF,64D3B8F05ACD81C3,9507340AEDA0BA74,0000000259478671,C717A6A3120365BD,BD0D40589319F46E,A1BA3DC7CAFCB5DA,A7E01F157C3D5A34,FCD020E4DB70AF40,662BBA621D526D39,76C54090E51ABC7E,1696313B82D8755C,6001973E0F067ED3,00000000E4DEA98C,8017A261367A4635,38D1A56BB529F405,C953652655C88ADE,3588044A20D4793F,63A4F52E67E7FE0D,B4B70ADBBF7B52CA,13AA13B1F79D37E5,77879D2D6A8B560B,27A4B43A20F1E84E,00000000CBC88D87,C1C7233AB6E732FC,6E45B5643FF917D9,99DF918002FC81F7,8A5F25A4A58BECD7,3F5670B3E3067854,675EC1EDED79C5DC,D556F76D216A8A28,C6BDB52DADED48FD,394EC150667836C1,000000018C3C23CC,0B008CC4E3BAFBAD,03BE437293B2C8EF,A66577F3FBF344D2,1758FBE7D9EB2D31,1B930B2DDAB21034,51F369D6B811F570,09FC6711D55E19AE,2B6430046C080EAF,5CB3ABABBC4D7929,00000000368690A5,E252ED770F37A335,B495BFA23B4B5487,19CF726906A47632,6714963AE777FBEF,7866C8C1C71CC3C0,80988770F6197E6E,F4F11567C4887CA4,8DAB4795120FA596,7F08F2D1A2F354D2,0000000074F9D30D,2F5723EC5ABAD4B2,5EADEE9C7301A1A9,98C906D480A7C6CB,A1BF125076FABFBA,AA0A5CFF5A1D4319,CFE345F422199C85,932909F200F89D95,CB4B8D6ED7FA1E56,1487E5524196C4A7,000000020CA7FB72,3200FCC37990A768,357BDD163E1AF1A1,2F4D64380FAFAF02,840E80FB37FFFBC7,3332957F0F8CE21F,34D206D2D95FC726,D0E79CAE6DF9C7F0,1261C42FB49B3F39,11812AE25C1C033B,00000001BD18AAE1,6444880254613DAA,886C6C9BD7F87122,A89853AF0C52B098,5DD783F68C9411B0,958C9586BF423131,6DB0291B18555CF7,67EB5A0E74510859,49839CB2C4F0D222,099DB7FBF134EF20,0000000023C35904,155EF5CAA79FFF8B,E136F9903252DEAB,8090B09B672C38CE,0C156906A59E1F45,0DEC11941A36A14B,D1B672C659B21839,170B59C451DBBD5F,284F3694B242E1B6,D64E3C0814A1854F,0000000105F760F8,4F79B6E9F76CEE0D,5FDD44681AEB256C,4C79FFDCB83A10D7,AC9BF9E6E1C6BF2D,DD3DF85702954B17,667BCD49C735EB54,A3136B341BFAF648,FC338B01061DAFA0,AC8DB50D58E43B51,000000021200DDDB,E08DE70A77900B29,DB6FC8816081328B,F8E6D2502F61DF88,B3130922DBB92C3D,5CE1B90012D7B58E,CBE86565EEF8432E,C7EAA1FDF60974D3,1F0744D302B59195,BB324ED4ADAF996B,0000000260653FA6,B232044E2288208D,B827F59D98F6BAC4,6AC079659902BD18,58623C5F36FF9D7B,E46A24262AF8D7A2,FD7FE60F201CCFEB,2760BCA4C8615958,0ADA9680E07A1378,6A98E5B9CFAB8229,000000002393A6D2,B4C3BA5981451E6F,04E02AC28D625956,E34FEAF590D32D86,AF7E2B47D9D6625F,DC0D47C599530DDB,0B372261FCE42BB0,9ABEC82860394390,919F948084BBBED8,E2EA20B59F6E0AA9,000000021A9FA4DA,A55871A23725CBDE,4D29DFA671986192,EFDC54DE890509D6,7BB1E45ED55E7193,5B37075DCF045CE8,C771D599A98EA826,EDE090A2403FC75C,0C049CE071F32FAB,AE7DF5D885803247,000000004A5F6F6A,EEDCDE287140DE76,EEAD5E5E945C4F51,DACBDA030EDA12C6,2AE5E8D945F099FF,54665FFD31AA5044,EFD90420A397438C,49F176FD6DE54348,7C94050D6387C06E,2950E61E9B970DEB,00000000C5033A07,425A74A081BDE65D,07E49A5C4F10EF6E,61B4949014BA369F,2E9FBFD4D43D483B,62548C08F547DF7E,12E771B67FC9D232,A57C2519437313CC,E8FD5E13A8FA6600,058053C6521E4E05,0000000231483D51,C34A1FB5060922FE,27650BCBCF505A21,F638D834DF03A49C,9C09B699AA808E17,326AF58E27741256,28DCE24B231CC56A,036D16A9F15EAB5A,3ED10AEEFB9C59F2,F898FD31B3066ECC,000000017321E117,6F4CE5705E183509,B8DD81F1CA2FD3BE,0E01E7A7AD505BF8,C2F3982D0B43A34D,B1E44FDB8638E7C7,FE4EFD2F6F92BBF4,735AC9FA4DA1AD55,1684A97C8DACD160,2FAE811525FEB969,00000001373AED48,E3EABBCFE8A2EF30,1BB8BD2764E49F24,3C309C8B38F439D6,1639EFBB2AC44B5A,CBF55CDDE556F0F2,A4A464BFC60C9E13,AE3C3FBC18CDE561,FCB2B8E645514FD4,BFA6FCD29B15D0F4,00000000096A9102,E9C06DB0BB475D0B,C9FE63FD8A6B1F76,F6FC04EEEC5D3AFB,CF39D2815FF448E1,81FB9A5044F9E2CC,264A2EEBCEE49CC2,9E1AD1BF2260F4BC,08CA6E5AAB9B502C,F8C289A61E900D5C,00000001D7D4E9BA,276D46BA493D6030,0DB97A3808C9E551,A98773C9B6CEA1C3,B8587FA52A07AE7E,2BA36DC7C973201C,8DE305F726059473,B142EC42924A5E81,36451445EB9386A0,D3AB2A6B625D2187,0000000233B42F0C,18A5904824F4F85C,F9635808F427E1CE,4A67826709A89EDA,3F71B408668D2809,D03A1360F84051A1,D04F04044A7ACDE3,1B819B1DFA41129A,994118037743F8DF,123542E2EFD1B273,00000000384F03DD,3CEFD51B523108CB,A67410ADB49F6C6E,BDB3CF1D678EAD53,1C497C49B37C05BB,D14163421A054B22,6C33B89F791A35B5,83546636C36426D1,7F1E0FC2544B4EF4,CFD9D8F83E87713F,000000022E42890A,0E33B3B75EE5A71E,D300A61E2F65E7BF,D3A30EAABF524AF1,A37B3421B9ADB03B,402066464AC3DC9F,34C0DB51A34E173E,4CF64C76E7919D79,F535767D85A95CF8,5623957B1123DF9C,0000000122D22EAD,29993E4CD66E02B7,231FE179D7A787A6,8CF02BB15E58442A,62A2BE6056101A43,72CEA113BAC527EE,99D08C75AE2B78FD,6BCB3C46E5C1F376,1206E952EA2D6E24,69F3F388C1ED9E26,0000000071E17411,B980BE5806595C07,4F384FB3F2053B89,8D1B6C20155554FA,F313D7A86A701779,21080E41C1C3A2EE,B7DF5D1242F08B7B,F87F04A4CCB1E35E,F32175F6D821ED2F,4533B1B95B0B9B5B,00000000E620EEA7,0D2BFD4DF4F4EFDD,7F2699EA4ECFCC6D,DA4A562F41838873,8053FDB1A233F42F,6302839E1ACAC01E,74086D0AB38B546B,B59618EA73DE28B0,406E76D58291266F,1B342EB3A9D6F641,00000002731C463A,F8B9EF061F48414A,DBC78DA806634FF3,744D0CE50905649A,77EBFD9F4407FAEE,B24F352CF1AC2C19,09AF44FFC31BC9E7,E646F3A182DA097A,F2DDF0E1B2AC4D5E,B7EF96F10C19D6EA,000000026068FE04,790E64CE1DBEBB05,B496D5EE34BC3F1D,5D44A21F6CA6C1AA,12F8962E61635BBD,57B3C2AC6C0D8C4E,4FFF54549549D096,574095A99F8415A5,41A6ECF4DBC48005,1A3395E340D079DA,00000000FE703F98,5DFDCBA5334C4BD2,9ADF6112611BD474,886CBEFB27567572,151363F494F89250,EAD6F353817C006B,3D99ED786CFDA919,CE4FCC4632840A98,C285C9C75F355640,9EED96561B345C9E,00000001B9035D0F,0730254098B3ACD5,8703B827D5A0DB00,E3C97AE529D91AF8,685EBEF8B9D34305,ABEFDA366373E2BF,1B2C887C2B1E1A83,EF4AE42F3E34DC90,C91448B2E31BB8BF,86D431BDDDB7512B,00000002400BF63E,7C51D100B28B847B,00EEA7FEB4246064,FF581C7EF52EB112,0F01F05B62D25D5E,5D2943050941D109,8F4185467B44F666,618F3B3DA8B077C1,F914EDB790A7E235,3D227FB753D8C0C3,000000024E8BB919,8F8D3CE0A0D4D76F,104B64A1132ED0A3,1BD448C845E3A6C8,9C7124D207CE8E24,0D24C7D960EFFF11,1B84E9131F645FB6,6873AA02C53ABF60,283E7B8A8FEABBA1,EC831AA6263B2B5D,00000000E4868115,5A5EEEE288312169,FE034A1544AC9CEE,E68822459A5E7A2C,FC70216F1C37D9CD,E36616DA31932E6F,E97B1E3E56D7F764,71B43F1C91EE78C6,4B6F897A2C3001C4,104406C111B38698,000000016C78852E,2886ABB0C6A48E6D,3CF6043D96443A14,83EF417A73FD9BD0,1F67F1B956281E96,FAFD0DB564684D29,0891E6DBDA705C27,9B615AAA125F1D65,46DCD2B7B7723ABD,160BE8C915572CE6,00000000FB542CEC,763E187DB27F59CA,C7C9F7697DA2B9EF,FB04204BA175AAE9,8B7586ECEF8E1102,B97C6B7140F6B97D,75A3C9359B365307,5957256C487E372C,E5F4661A6CA655AD,94233A2B7A758060,000000000CD86011,F2B3C48BED753899,FD0652FFCB587E26,24BDBBAE19EBA6DE,2E41AF455FBA1E4C,A5E0E859470DCCC8,7F3817869FAC48E4,717F280CA5CB5FA5,372E7E7B637339A8,A6371F5BAE532A33,00000002146B11BB,1AEC3C8F660AEE96,17D7786ED788BF59,045579B5DB55BADE,33949EBDD249A575,FE7427EEF6278328,D5F651BB1A9E9D8D,EC43D59699759E67,09736A788E8154D1,D95E4181C4331CB5,00000001B0FE511A,ABC15E4D510CF288,0CFFBDB0D8B7FD3B,A20E4DCEBEFDB115,8EDA5CE0EFB324E5,306C767EDAACFA65,8389E6E8E198BFD3,66676CAD1CBF0944,30F3E511A100E0A4,7D3260928332F6C9,000000005B07B9ED,FFD6A21662E95F65,F6B2584A78CE8120,37C8735134B5340A,C1AB64638A3D08BA,91312C36DD710BC3,A7889701FE6581B8,CF759C4C09670BA1,41504350BDA2D662,1C81D1F89E4C9E65,000000009577DFED,8B8B5F3ED78901A8,3536587886877D4C,912336131EF692C1,D600D13141418249,A1E6415B191C0A99,54403D980D94346C,1151BCDA3EE92F81,AFBAC6D528E63CDF,4D57669BED34B65E,00000002090C966B,E99115C4E05AED3C,224AF9572596C2D1,6D5F7EB4321E2933,309AE521E5697720,FB6707149648B45D,FE0AC7115739EE55,A3EEEEC37337F34C,69000E10373A6712,BB709256F996B8EE,0000000099CED199,490CCAD64701B2A0,8DCDD1C4CA7784A0,ADC9BB7B8E22CAB2,81A7999D14648EAE,A7DF6C97496F4A2A,0138008C7D0273AD,D585693954792476,4C5FDF63531F2E95,4D34CB30C2C20C0E,0000000270BBBDD1,9F21BCF440E8A06F,60391507C6DE389F,9AE412ABD38F7B7F,0DE40B7F24192072,902283A9AFEC4AEA,04D7A03CD4EBED3B,E1FA6E3D5DA046BA,7D1DD04FB13CC143,1FF3E8580368EEBA,0000000142CCA8BF,D013FDC6075F483A,2BACDF7EFCE8C2B4,3E8D9C7D5C099F5E,C79D1CAAFDF02A8D,F09498B03F3A75B5,745F61C74045992C,85A408D186F612DA,94CE108D9D50262A,898405DC73F1FA21,0000000042C748BF,77283B475CDA09FC,531833038CA5F09A,6DB3022F743C2E6F,09B9549C2605E659,B8447F1C3716656E,349F8B58D29D4617,521C2BDA30FEF470,C24B86AA9BA1BA91,84A6F2FD5F187FDA,0000000106E2507F,C682C4844E95E5F0,442BD6950B0732AA,60CD545B72147A73,0C20727D97FB39A8,8DBABAAABA203961,23327C944D7FD458,57CBA91B160583F6,94DA52C064FDAA7C,FD62A4DEBC391C1D,00000001F052AA88,257D13E0F011AEAB,EFADB3F3257BB2B4,44D7A573460B3990,2C3797B6E6AF718B,A17C2977A6D52A12,95D30ACE2FBD092D,F1228020A879E3F5,08CD8204261D6B0A,4A0FF8410A5EC063,000000014E6F6088,DAD94294CF40B5DA,522669F156152E0A,63CB632A2994ED19,EB7CA3AE7C9A2E7F,D4415D6341A936C3,796D10CD84024098,D96136DFBB2290AE,CBC58357526C890E,3D62BB625B723CCD,00000001D375DE7C,91EC31B74F8B1B0B,A69949626DC86E16,38CA4EE6CA27228F,32F7E38762C6A93D,CB433E696DA28CC4,A3959F5E06A25B05,C0A6AB4C259B48F6,B889051023F86BF0,BB2624E54B8156AA,0000000193D59F0C,40800C73E1E322A3,3B81BBA91A572A85,C1DF92EB9C269A83,F4448C5452FC026C,449A6E22C6E58C7D,89F23B5233344176,3217C218850F1251,21E6D803D67722D3,E441EEB2F9FD5EE8,0000000033FDE48C,AB1927B7E4E3117B,F5EBF26FBF9E3AA6,793C8C0A38593107,3D0C33391C236CC0,20D2DEC9E41D7231,E68DFDDA6BAE8DB8,8C0F79A484FEF4F7,497D23F846E846B9,DDC6AF88E626FF0A,0000000043E726C0,357F4B0D81D4CE90,50E99A4A9D003983,DC48D5F884FB989A,4E406CCB18F7BD06,04915FA722CE27C4,6DF58625890726F1,7D7A9785219221F6,57083745494115CE,BB94CF36E6CC6BA4,0000000221491C97,39E214EF379069E1,659B92A674C7DFA6,209A9F4947AA6020,B97634504D166618,DB524916297AE0DF,CC3A9D7CE7804C7C,FFFC7370AB05FCC2,F8AE4FB3FC557502,AAC6D388F4E80EC8,00000000CB36D506,F0FB122BE19F6BDD,CA442CC987F76EBB,169F51670FD0BFEE,269B0830E2D53AF4,126BEB6FBFAA6DEE,14C4F8B430135FD1,548F083B1625E315,DE1C4A877D86B6AA,292A3ED1BBE95591,0000000275B0D117,9EEA6E407B90E477,3AC5FA322D420AE5,57EAACEF47545559,3909933666D1B1E7,4CCD021C6B5B0C64,633FA7D0C16C5437,B79E0525B1ACDD89,DCB2F3CF3284426B,A492BA36F8118AD6,000000022ED314C4,D75FD20DE631C22F,94010366320AC15F,6C1EACDB9380173D,1FD073CDF6C00439,F20C6F3E65DD7A50,33C0F3390479F9A5,89D23E050155D058,C2ADDC2CE40DB0A9,9B6B4BBDC478C015,0000000195E71C1D,E0D344011F1EB120,C9A60604BE121AE1,E39E0BF7E92C0B2F,30B35BD7BDB67ED6,AA395074FB670093,2739B41CB043D180,FAD598DB17B4A943,23C304602BB5907F,5BB24DE6AA04AADD,0000000137C6D9F7,1FCC9267BEA55ADB,816EDB30AD6DE9E4,9C4AD30D88DC3C29,B0D48055A7395E4E,E34792F5BC756258,351E32D59D852CE2,00D8B1557E178E53,528A18742958C824,9E4DE852CE611707,00000002404BF52E,8FA3882E43B0033D,095D35B95ABB72A7,A89BFE337C66CD61,A6D36E0BB07B9574,3B9A51CD4CFE9AD4,BF778D3023EA6BCF,C203EF53A9908969,EE5E66081FF93558,17B297F9F3D82F3C,000000025C6E14C8,3C75F07C4CA14DF8,FB20E4B03D7320D7,20A23F54ABD48DD4,065ED89525B31943,2BB8A0B83359F69C,9B77FEBD2813D9AB,73C605782EC1EC72,3E9C3A1418820463,5B3B6BABBE9CE64C,00000000071F47FB,3E1151F0E62BF60F,A5DC21649B20188F,529F084E2CB4A79B,BE0C0A889C97E538,6902C924DBDF774C,12E759631A9C1942,B19D7262C84CF5A1,38CAABB36F028FBE,8510AD4355385457,00000001E1EF0748,2B96833FFF4F29B3,1CF9A308FE4904DC,32473C4B0BA74ADA,9FCF97F069F43132,03B952EC5DEC42A9,922F857E49297BA2,5042CFB76415D955,39C245B5A649C2CC,ED694CB4F4F04D24,00000001C5D41905,EB1DF4F6981FA39A,670C9A48AC5E713B,26E3789046A3F485,27B100BEB0DE9321,4A305206E910076C,AB9C7419CF6238F5,559B86AB6AB08FBE,2378A3EFFA5488B0,20504B7015D59D4B,000000006DBB9BA3,11C4778AF03B9478,397BD392FB714C25,A7179A8FD69C35AF,A46AC895FE0C5024,C8166C71FE200B70,C55FBFCEE0816CD5,796334148C77B20A,117D1D98F5A99B5D,AAFC43CEF155ABB2,00000001780F2EA7,C0813AC061BEF779,D5891491A27542FC,2C8224CE19BEF903,E00A5352F4F4DDC7,976CF9AECA446CC8,59F9A4ECD8F2E932,D3CC9B189FD9F26A,6FDF294631146DD7,508C4475EA1B5453,000000014F7E76D7,CEE0FF8C5FD6DEFB,44B0F8BBA5770FA7,5DB16B2BD870342A,0D53CA9860452438,E063BC85D15E669B,88FB65754CC4F28B,A4262C825EECACA5,F3AF671BCC981BA5,92E34DA245BE29C4,0000000249702878,40E8C9376109F600,A3E87F53B91A3396,8511184B1B6C6DC9,F5719E43D3F7057B,3FAC69F3D2EAE706,5CCA4263F3C36B71,1E6B4A455656BCDB,FFBA134995339D7F,6BBBACDE9E6A89F9,000000004AAC6702,392520653D09FA49,8E585FA681930B9E,A71EEB4489A7213F,B2BD2492F6FC369C,13C075CF5ED2F3AB,496C4BF54C325CE9,6C41320E98B8710A,C38F5DE12D676CB5,9B473228B22BE13C,00000001BFDD776B,86643CD262337AB4,F1252C279476EE17,8391655F5D0967D9,B31B0146DDFF7122,BE17FDDD487BAE5D,B26D51198A0FB0A6,44959BF0D9597CA9,20BBE25FD0319A33,E751B4857CD179FD,00000000E71684E8,AE86014D3CE4E433,8DB4EB4194A0B4AA,D75B08F61DEE2974,3FFA8FDB08EA19B5,36DEAA08A8BCFF73,E137B9C9CA7D6800,ABF4B4635715B4ED,0C59D56CA2E512EF,A00B5505AC362FD3,0000000194DB01A1,7A1B3E9719A971AA,CE598E2855840DBB,5CC0B8AA71E92B1C,70C21FA7343E181F,F735473AB417A360,1830373E65F23E67,B6991D55292649FB,E836A1F0C508830D,9FFE8DC6C149ED81,000000023D9ACB63,15CE2DEBAB34E8C0,F1E7EDBBFE222930,0D1A92C4F9241286,128562245E7CDF57,CD382492246354CF,F9BBA05B2AAAFED7,37567C0950319D30,73680AE8294BF9F6,DEED629782B68684,00000001D234EC1B,BC4ED93287F144B0,50D394596663029C,0821963564F3F5E9,9D832AF3F0146122,82A870D5049207C2,68D75AABC497C4FA,0A00EBB09AC55575,B468ECAA33BEE297,A9CC4BD631082A13,0000000182FE0926,78569A3CAD17BC0C,904F4C311E66FAA2,5D2884507856247A,576B2771E6E6E7E9,6425535D8AFF44CE,C906B4B9931154EA,6E2FF69AB7BBE9EC,9E0308ACB8383A0E,1B8202BE8448ED0D,000000015A1003EA,AD504F063756B4B9,048F66D8503815EF,DB2A035A65D61462,1E173B38062E89DC,78FBBDFF21EDE1B1,4B48B9C7C07F80DA,6E0F0D05CE993377,438D332B04575C90,F4131BD0661EA0E5,00000001813D078D,8D9E6EDBB02EA5D8,7D9DC34EBB588A44,B513677741C0BD29,C6969DEA28E4FD5F,8CDDFD21BAE2DEE6,A858C8A0B7C5A0FA,640E8F6405A30871,D369FE2DF581F302,D201833F57C7BF41,00000000B2BE5F15,DE6F8ED0C5235E70,24958C016B9C2565,3098CAE3D0D4F9EE,7254923DD494953E,B86A7D0110413E4E,EC52D7C5A7E9AE2A,7BB0D2BFB38F0498,4C452C028AB7026E,BB73BD7B857D38BB,000000010DC28BD1,A61D6359B6BB234D,15FB85648B3EB70B,F164E874D38DFFB0,32A6584613C958B5,75B7C0D033A0AA82,D381F62BB4A52DE9,58F98B6E4B4E704C,ED483222602CA4AF,FE9CE7B2909982A0,00000001AED7EEC9,6973F0827B922BAB,C64E5E31DEFA1A3F,4E9D9CFD928882D1,3D626F1CE3451F70,2F08728FFDF2F57E,17549ECEAB376D31,5D3C9AAD10079E32,C269B95650379B1D,B0541E248678F2C7,0000000262E2D06F,54DCE9C7E947B45E,EEFC8D2FE12BF75A,2C55ECCF4A8B5F37,07D343B1753F5469,5C5499D868C10D92,57125C5C76D73FE2,572A6CB45DCE038E,02B49C12DA51DAC3,FAEF22C54109DFFF,00000000CF76A28F,97D5F47446DC54BE,00D80FCAD2CFF0F5,8936B56D4AF1A1AF,D292FCC72D5AC5A8,AA105BA17BB748A0,1E8C7E1F038A74D0,7EEA31369CBCA61E,53A8F49941EEB4ED,4B7B0C0FB3946628,000000018071EDD8,4D792A755F66B64F,AF636CFA7D564AF3,A6C65F66257D8E59,BEA5CE30636D56A1,CDE46D984D714666,019BA5714DB0D6DC,3BD93312562D4B52,25E4F0B687753538,E90A5A4085DE0319,00000001E62A2008,F3A761433376F5C8,A36668A30804F154,9D1B4BA0FBF76F7C,FDFDE3B4C0D18FBA,BFB66A53CFA85A0C,D0E50EF6EEE59150,B0F0C1C728CCBDB4,F6A709690A0AB641,7A4541849822539A,0000000085AEAD98,73B6AC1678A965CA,11799CD12FD7CABA,8669F0F93261C5F0,6B50ECB55AD91492,C9A63CE91E399056,65D1C8D65EB18F19,0BB0B8BD2768C0C5,EC8953D56D6071E4,272F17D153B1B0EC,00000001F071A858,F9EEDB909EDCBF57,72F7AEB3A3CE4CA2,572654F1EE8C6828,ADBCC42A2316F29B,11C584EBA53F65F6,977746645EE526FA,00DC3E0D25188D0B,1EF6C5D4861ABAEF,AE5F1DDD7D0E928D,0000000016CE0C66,C1BF76011D2B1208,B60AAE7771AA2619,12BCB54DBF065865,F8413DD1F69E9E4C,B7BE7E423410D251,C5182FDACD3DC4FA,58C51FD7A212390F,12A2BF84793F3173,E317E40C8D749E06,00000000381B844F,8476D4EE897F58A0,8626163B5E40BC65,77F3A60CEB54B84B,CE41C17F309FA685,697A9ED594AFB9E7,A877178520CE86FA,644FBED2185FBE5F,70C6215B6B0C4C68,CF0FCC45A24FAC0A,00000001BE5045BE,E6D7E38574FC5974,1F2611137358D52F,A79B59637464D668,93E9EB15A9C7550D,6BA75D27688DCA61,F71317B822425F44,91B9891032176090,807C1D71F6E0D342,C3FB23AF9552392C,0000000238167E97,31EBC04FDE81B207,9962BBAD54A4D058,5BEAB74A61A9BE76,1EF17965B31751AB,4DC6819F8E7D44A9,D2C185075696443B,1E221A3DFC0959B1,AD017D11CB47C30E,F2867E6744D09B41,0000000042941BCE,EF15AC21D2B4DDE6,7BAC9C1F4A9B126E,F218299E143BB8D0,B60ABE58161D4C79,7058531590CAFBE9,8CEDFA0D7B92CBCA,7DAD8B6878675EE3,0A769B7A777BD2D7,73A5A81B52E84875,00000000206813E6,0B13D75724D7F9E6,28604CC883E6FE5F,6F5B4EB0D088FA8E,30BF655F40A6BEA6,4103177F0AE0EC46,83769A47ADA81680,852E7AF5381A22D1,8342DFCBB1F40CFF,BB1F987E27D2636A,000000003BA301D8,924AA74FFD9C7370,944FEE5951AEF780,F8A90B8A1230C870,D203DC9DC332A6C2,D194D3BCCD854FFC,915342BAD2BDF748,9CADC7A1D932117A,8EA4F1D4B1A53652,B69BA068C1C04104,00000002085CCFF8,9B9FA95D00A5CF57,16FD381C38AC7F3C,2765309A60CF920D,D058D6F503CC24B7,039474958A92302D,D734EA73DF170F7C,3432A0745E435530,81D2D7ED81703B39,B4CDE0432278E823,000000021BF611D2,86D48B1584AA7D2A,078F92961889D5E7,BB6359D9CCA7C64D,CE811A71D7091EC0,9227D8B7EF2B3BED,E8AE4CA511B87276,073143A2BF492DBC,EABFF03701299741,CF6F46D6B553D3B0,0000000126980A58,6FB88EF64318D9B4,2F4F658B15934377,E77C345A4B634B18,ED248ED7A273B6F1,AA5FB77D100B4E00,92087E4DFFA1653A,038B603C6F267EA6,589978A5C808D304,D606007D8E95FA9D,0000000103528FF7,BF4B75F41FD5E7D8,784A10359E2709B0,E1B14B0D6E61DD94,BDE154B9D3BE95A1,F31EF21CD2CD54D5,EB3FD8BC867746BF,A5A6788466D83D10,1340C7BBC0E73427,03BD9EE808BA33CB,00000000FD32D3C3,E58BADF9FFB4928B,64D69AEFE80F556D,EFEF2C38CA4EDE67,9D085D3BC683C194,C4A14EE015106818,55BC7CB840D3A5EF,8F1FC395693F363C,9096C7AB16639C59,F5195825F85D9A71,00000001B463D689,80E7B81BF25B5F9B,70F8E6E3998DB270,A9FE99A70D535ACE,B1D6A85A5920FE22,988DA91929EB828A,8C5FEC36C4A87173,E3BDD1CB008E4CBC,D6AA665C27407F58,F3958F09769BBDE9,0000000243B4DA8E,C24D7E5CF04EB3D3,5873C27F0B805976,CCE3B6C926E63643,652E012156A7F795,77C612327E407EA0,0F70BA39EE923634,F0D0B0BC061735FB,037D048ED59F74AB,C31565B66CA35F46,000000023F6FD477,6151458B06FDC44E,2AB4030C4B015BE3,18A537174C9F649E,E44144C87ED08A58,BA8D2EBB25418C7C,B32E5A6DF849A65F,33D6FA391A8B6A02,1D0650B453D54783,0DBFBCA50FB7CC8F,000000025AD86303,6DF56D4BB12033D0,A4B49DADBFB4691D,F8DC9A3D8BAE7FEE,3EFE040FE4713884,AF937CF8ED0E9745,9A88B7A97B485E85,4D843A61487CA30D,596F094C89B2A44F,C106FA313770D3D0,0000000254D66020,F29EBF2B8B05C837,B071341ECE8FC608,4A8ABDBA05263B5E,ADB88924457D9A59,8EF1B8C7E4E6EC24,5360D84A1B5C3E1D,02D8938452B74FE1,8BAB36B65956FC74,7C0B76B8FBF1FBDA,00000001D9474F4D,F41EFBD5AE1A2694,1D52F637F63D0CC9,E4E4F95683BECA9E,DB3F52A0178F32FC,1870490D8BF9F53D,1B112D227FD4F533,AA0F7BA0A7B9AE95,76216E3C312153D6,42D9B0B757A14596,00000002698788F2,AD5305C1E7689024,EF09C3F7AD2C1FA5,F753DCCD10B712AF,1E815DE07CE8158A,B4E139E530BF0FB0,2EF3C5B5525247BE,B7E844887027DFE5,B38AC464206C5976,422B791CF347D3D9,00000001A1F111AE,8FA27CCC474F619F,D7C773B68359F24A,3ECF56E0CEC1DE60,B2432AC70C69C1D6,62FAB4363BE4481E,7360C4D6433A4C85,DB71B5BCAFFF1C92,8B316B82DF7E6E97,D91AC45650BBDC41,000000005625890C,5FD60D3F7CC13900,6D39AA5039076AE8,AD50A473D4F53B63,17833C36FE05B6A4,5634A11AF1E67609,3A7A3C2AC0E039A2,9F6E3EFC790DBDE8,F85D47CBD6D3617F,207E43B9FFA54B25,0000000004FA56E0,0CE86384A87BE31A,7AC8E9EC32901281,3CE4FFFE51BDC455,92B94D6FEADB2076,7AE2015FD3A8B6A8,F3433AD88E440799,032BFD6371F2BF08,23563E86315903A6,59DCC7E8414AA53C,00000001C20867C0,2D2260C646867203,4B87F7AF13DAAC9E,3F618D9DAE767FF1,CD9C82A2CCEC5654,2199B882C4C216CE,77954B22F29194C3,402C5A041E59B8D6,36F10A5082ECAE3B,4FEB3331C1CD497D,000000020F0F815C,8A1741B5AB76F81F,F75914341448E165,FF28E30CEB6F5839,4B23F63F6CCEE73A,427E95653E7EA82C,5BADDA12F4B8FD5C,9F012BAF90A8E8C3,9A976D2FCDF5CFB6,A1071D84CDCED202,0000000217BAA979,729D5E79585AE78B,8E84AB7F3B4059E6,8231C32F98A8196B,DF6D812404CC52D9,09E76EE01FE337C1,2B32880CABC27890,4457A2341B86F99A,CF46895BEF43D0CC,A8030CF1FD01A2D0,000000008EF837E8,F3F1955389E4B376,B2EE6877D9F5C038,CE56503F87C3BE20,64275D48E9A36815,592F4D3DBAE23212,1433E61582E880D1,B9B824D538AE7D34,37BE7A6320AE2DE3,0AB0A75899663323,000000018147BDA2,203A070A37EB25C3,1D30786826695931,F2C56EAC5D52A8B2,3178AB369875AE05,DD5987251D50C075,8C08F386326C1B6B,232E5A55E653EC6B,8E7C373086B2FFA8,E853F111CF92E1E4,000000000FC76F37,56C20F8DF5E7FE96,06CCB7867ED6E8EC,3D40B95EAA5C81EC,B5D857A16F3A1ADB,82019AF209EE97E1,C0B673C24F368EFC,91230F735FA0A551,7D794A9E7E90C50D,D48558BEB6211DFF,0000000049360F84,1470A79A8C9E3EDD,4B85C24F10FF65A3,16514E107BBBA907,B8AC4AF9461F6D44,279D33098E55BD84,D7E4A4E2377327CA,6D3D0C9D27AEE98D,2959C1116A85914D,ECBE5764F7348BD7,000000023749EFE3,1F48382C971DA604,A22431E28ACBE82B,4A4EA6BEB0C4232F,E395639820265AA0,3B16480C6B4C2F46,2846DD310D0A07E4,3FB997F7386D9E6F,251E6BD249137777,68850F9EA93B6CEA,00000001D35CE5B5,8CC9ABF9927AEC7C,ED706DF8AF0E2B34,9AD8D3C1A9F1CB92,5697FC1E60226215,F92562DFDD5A191D,8D4A9AB87E8B6610,6B9EC25A07FBDD44,72CA4404C16B1186,B6DF89EE26586C4F,000000013D362D2A,DCC2F817154DFA41,362D172927A15FBF,23EC973897E1A167,3E2215947B26E2E0,C0D1789C104984C2,8355D26B7EC52E72,1202C2F7EE74AB57,D08E11903F5A1C08,A2D4C142CA378880,00000001F076A841,731538D31540214A,E04674CE488935BB,4A7410C2EACA8726,B30FFB798B06BC63,6AC32C88D5F5FD51,552C4E132CFE5D07,0742C8EF9042B36F,C41CDAF4753F480A,EB407E3CF7F43E03,00000001D1C425F4,AF1C669402EE6E87,E356940052D20944,22D433C65D888C0A,C40C5F3657B685B1,4D82CBF249C6C2C8,DD09304EDC8C3D0C,B31905F6CC663DA1,5D106F60BB12E2B6,EBF34289B299FE96,00000000DAD65BFF,BD89825E773C651F,2726B2BB95C244AB,3DA0DD9191D7144F,B04D4ADAB43EC65D,980FA9C0F363BF29,58ABDE5EC0934053,2DD8B460E50A21B7,AE6CCEFA207299D2,E89AB8F2CB04D1AA,00000000E445334F,888254B7528846CB,7991DCE63472F5C5,470F41BB83CE9DBF,FFD7D9E8D0168210,66CA88E8DA560D0B,E73D4ABEC7AF9874,C2333B0A02CD19A2,16B48FDA9FA116CA,58A9BFFFB22CC033,000000025D7E78C4,99C912884D9701CF,15ADE3A7E754CFFD,9AC24BB57783D94D,53B2134BE921BE00,3577A928607E7CBB,7434D6084B31D081,8B6CC3A9959B2AC0,1BA657D89DF9D869,842962FE62E9E5C4,0000000065B3E63D,1530FA31070D4578,995C74A675D3C732,B67569F7C5ACBFD3,8C7D65AC4770AA3A,1A30238184805E64,470885F23BF09418,1FC1A7C8A8267E61,2E3F5E2E208D0CDC,5DD305910D6AEE71,0000000001D42C9D,63C970AE1DA4DCBD,AF04A01C9AFE664A,5B10B15C0D866626,F0D4B205A1BC95E8,53A9878ED5060F2C,FE8B01FD194E1775,18E623BBFCE434E8,6DCDFEBC8A46443A,8A322350C29B423A,00000000C58A62E8,41FAD6C0943A3AD9,A50B334166C698DB,61A68274441AADD9,FE1FEBE30657CC54,3A9225BB342AD6BC,CE2C09AF2E1257DD,27513488EA3CB529,5C3F679500CC2469,E5D6A62805217183,000000018B342909,38BCD48EEB8A7B74,02DEBA7C1D1DCDF2,B8C92AD39FC872D0,B090B111C7912F42,74824A75991DBDE7,9AD4E40A9B55E4B6,A36F155103FFB040,451E0857CAAD3B15,42343B2850C38DC9,0000000102D0009A,12665C556FA9A7FD,0C0075EAA53697C8,CCE63480031C42CC,ED4386278CA9B8E0,EF00E1C5FF52EFEF,65F9237E39BCC623,445E0EE72892A148,B229630D27884700,014E1159D554C24F,00000000E564849E,1AD7B7CEBF9B95E8,BBBCBCC60AF9F736,EE14E3659F671F72,08F479CD817B28B0,0EFA5E525099BDB7,A6E989FD0ACF8C24,0A7160C1D838D6A0,08C0AF5930A4AC8E,C201F86E5F71E387,000000005085F707,B21363D2C443C673,70E9475CF35BAC18,C4E19D8295F2DAED,71F8FEEDFBA736B8,D8557BA1190BE07D,C524E062DE64913E,D1D688E0498E9EA1,335C9D14EDAEFC33,8F9F6D4E0F37DFC6,00000001E661B51E,763DCC0C7D3E51C9,A03F32F96CBDB994,C69E9C46C053C45C,F450F6A386095C7A,E7A5FA2C82FEC10C,C4481CEBD9E9A355,8942B6496A989838,A5E1F3387832DF2F,F9FDA1ACEEFDB704,0000000120166E6A,418133E6758EB3C6,8703A49DBD289C9B,F477EC2CE088E97D,CBBD1F9B0A019D86,98AC1442EC8E1BCD,9391283EC97F85C7,E35CCCE4F95AFDC0,DA3792D300451E14,22BF54A9706A2067,0000000069FAA47D,ECAFC046E22C0E53,84CE440CC84A927D,7E9EC18D2496344E,B11E06BCECF07C7E,6958EFD509255E88,3B9A14637BEB1FD5,0FC5A98CB7AD2222,1E5C8AA831A24FF0,A05F3DA3B5A6E925,0000000125E4A675,91B5BFA843BCEEFB,67524DAB5FF61489,D89FC475F227C9CA,2F7850D9F803885B,1F69BDCD3D0F57CC,29DB926D0D860DF4,F5D0573970826CD0,D7DF6CD95CA3D041,690CD80E263DBE04,000000022D99065D,C4E725BB2EC6039B,B66574EF6F51C7F7,687782B5863A4563,E79F85BE983DC0A8,BB0199C8D9F3CFA9,6634B3BCE10B1092,7AE383AD07AC27E2,A36E9ADAAC6E9B53,8E309EBAAA6F0BE5,000000001732D8EB,27B660F7BE72B921,685E0A69CAF1C505,2B948DF62AF194E4,6D5464A007A9FFDF,D93766F089A16221,6F786EDA79392BA5,2F7D6BA50DFB33EE,5D24EFA5A05265BF,BB40C0EF366488D3,0000000092B9BB2F,754A10AD4AA8523E,4C6BB5B9CC50F4F3,4CD425967F6C5173,00A3B58A9E00CAC6,E7C2625C1BF8B25C,2BFB9755DE3255FE,76273C1AED19F919,4E69FF5DEEC59E15,0E36F31D0EB58CD2,00000000B3A23FC9,BEF9D414DFAEAE54,4785FD7CD064C062,A163A0FD820A0556,AB0BC6D310BF73BF,EF9ECF3428E48114,3828B12ADBD8656E,BF8D361C46B891B4,A75A0005A0B4711D,974D37F839FB3310,00000000C79CA993,9F111F8FE6539490,F180ED0212C32F09,358B3580C44BF165,6E2FBE69E997ED31,173608772C744DFC,D71DE25D13931739,A838FE621E366743,0F115F98278EF877,2C499A683A8E5519,00000002623745BF,2FFC58C21D105611,08D855164D400DC7,252110BFC6987718,7EF72C5115C667C7,0E7C66F20C8D8816,178CBE145930D255,E7B3609496646FF6,C480FAE16BF0DDCA,9A923C21052F111D,000000008653F655,E8A62263C3D5CE4C,12486549943931B9,A07810604BFEFC33,AE62E9AE60D782B9,5C55097EAC2A4B93,728624E4403665C9,D19C09A926009F1C,3BE21EDFB6CF4C4E,F2441B32BF7B1CC5,00000000F5B0A770,CD0F893D9149B8E2,EAA6E2B322E5FF72,0C2AA7A8664A9B1E,2A01DCAA0422EC66,C91B4BED44222EB4,028798B9A6C8B12C,888D73302AFA7547,D94511C7BC42CD1B,FB48E7B5D8283BDA,00000000FFF4FFB8,04E4BE86D5342B6A,C03D7FDF294365F6,A1284E7E0F351389,8721D9C90898D94E,A17FD27B35C26F34,690FC3EAB115DB98,6DADD2C48D9B828F,1DC6372B2C55B194,4437934C6D2B8CC5,0000000141C81DAB,8B29BECC55BCAAC7,CCC3E37A2A2A7A3F,F82092B5510CFA1B,519184E954F674DD,A1D68DFA0FB63A49,5B8CBAD915288BA2,0219606F3E8F983E,9B2C29F037B8C6F6,7A62842845FE6395,00000000061B2264,ACCD4D8DB86595B0,9AF952679D35CCBB,1A0C8466CF22B3EC,18054DE3E3F65558,64BE38A61E1D3ECC,B4C2345E08F11BC1,C7A3F1606F5D1A4D,4FFC3689A21E45C5,5E774112B0CE7FB6,00000001B33658D0,BB949BD530847B8D,653418529B07C2F3,2A3DA4EB575C7EBB,3D501E434EB091C9,0DBD10F4A4E5A1C2,E5E4D0B48897F43F,10D692974299B752,3E25792EB75492DA,4DAA653C0E94CFBC,00000001E63965B4,5F0AC11765A7BF8D,3EB0F98BA0F45551,1FEF512B7CCE1C06,91452BB5250BCEA0,0915D24ED41EAC64,3797A980F1E40534,38E66FE141838E33,FFA64A06153377D7,B7140A22DBE4D7F9,0000000118738B89,C6E20063619CA4AB,8154BA1D587AD754,0C75836CF52507A0,0BEA1C76EFFECD01,F212DD40B2F43535,FA6714A2651BB889,0C039E26580C5CF0,CC2301C5B80BBC13,AFD9E21753B75CEE,00000001C4CE4AE7,3C999D352D4AF534,852BE948BA18CA38,0213D7540C8F4650,71131EDD24C2E40A,5B7459A239D8E3C9,53D920311E2081CA,EA7CB71003B2714A,260B02D01770AC06,A52757FA8E9B5C4F,00000001F5A4669A,FA38137E5398A6C9,637C35C2B9B11A95,B09E2DB2817EA4AB,9A1B771B2492ED91,F534B0B8C3BAEB23,4F5359700345A245,A40CFF7994A0214E,1D87D114B15466DE,20832F852A5A7D21,000000007A196B08,C68DA807686D6113,9F674CAAB628447C,DFDD758762A6DB41,C84170F4411691EF,28198E792AC1A906,1F313F56BBB22916,236642A60FB8A6CC,A5C40928B6B04D0B,1B1A01F06BA691B2,000000020A9ED8DA,DF96A91CDE7BC2F6,E5F25D819C645623,AD1C296AC50EAD25,C7E75989B42084CA,BDD5C2ED91EE50CB,ED84D7F507C70715,923CDDACD3C3332F,C82E83D7917196C0,D12BD660ADFE3B6C,000000000D9C00DA,A9AA53E96561B8A5,3366B7A7008BA3D0,3C4ED1F50D2D380D,0A43C04639AFCE5C,21A85A1C13CB1C35,9F7527FDCE55EF72,68C0F595754A10AA,3B12C2617E6215BE,50A6F1C836733AA6,00000000F5A9CDFC,6E6C286C63C1F49D,2A29CEF533BF1D5B,7CB4FD095266B318,174DEFE4EAFF97A9,C5E937D5C0D3C0CC,285627F5D6F88C50,9633A7BBA3CFA42C,7B6CBA2EF693D64B,AA4163C81CA7C3BB,000000019F9C6180,756DE07AB5F44609,19D99BAE271C5CB2,83596C48276F5B06,0E2790539CEFE8FF,0F62E4CBFF2DDAAC,DA9CBA124FF7B26D,E36813D1A91330DE,8938FEE974C311B3,EB3528BE1815545D,0000000071E0E156,B1D785F8801A73DC,8600BE8C55E33C0C,187E10C72C3A529E,5A6E729356933195,B5284E57D23C1DC0,BEC38BB7EC6FA884,55B0127CFDCE3E3B,0E2EDD5C08062DEA,2F566EBC88574BFA,0000000241C12B29,140B9213941512A7,7AAE03972F9BB3D0,F73D17EB4F4F332D,C817916CB646A93E,2E9D6FCAF6E26DB2,695EC870F3D8EE34,22C22A8168A96533,1F33634282FA4507,21C83663A9BE228D,00000000D829A905,CEF93BFC3EA622BF,E072A8C8D6378BB1,28A14AB0713BC3F5,A4084642B2F95A4B,6664A1A6DE6E3546,8E98387759198B80,FEA8E94E8F288491,0CA1E46E11F0B0F4,5182C5E104A7A675,00000000D52CF859,850E39D83F4907B8,68AD051575B947E3,410395D4D44816EA,ABDF7EE08CCF4426,FD2F5F4866D367C2,FAE85342B487D2B5,477EF49BEB4F3041,CC316F91658F417F,E5C25914CB36E58B,0000000225E929FF,65C375609ADF8A3D,E0694FDA1B294B16,EAAACC265FB6423D,4BD60737602C67D4,A46A030B21649187,1A605C1ED049639C,1FB7CCF6F0C82B3D,7C4FBE6F964F84F3,015E78576537BB06,00000000C4AE367A,89C11AAA61CAF695,76E33B0A66C9DCAE,3DE356C58FF56874,3AA6EF6DFDB6E0CE,F79E2E6F021C71CE,5E1E842D132A92FE,2B52F0DB3714AB27,AB0E4D275EF5EF26,BB050FA9CF64FBC4,000000015F910992,D3DF6AD4ECAF18C7,6A0E978BAC06E90B,0E6488498E076743,858DB9F07FA52D8E,135857E76A7D7172,467A8F5E36FC8804,2DC82085FC82BCA4,EB136AC7F8EB20BC,BF506FB1CE704D87,0000000133617811,A5449548D7754F9B,1DA3720D8FFF5681,3C09B2E112076383,ABAA8E7FD7ACE1D9,5FC71444D2611992,D1C7A173A802B83F,B7EE3028B71062B0,473A7FC33D8E1289,CE03BC683339C669,00000002345AAB4D,A4AE8821BFF63F5F,1AF0018526BB10D4,2E6AD8BC3C1B1B46,6C062F6970930866,D035BB446A5CABEE,BA9CB66439132ED8,FF99839B9C12C3B3,68A6D925B9966110,A671B5C4953A9F6E,000000002C99FFC4,8C081E2E424E27FD,7AB8769F1F5729B2,39A28F443B9A06E4,D43B1E3187C02043,05452C2FC04E9C6E,1192D0B877B0C7BE,0477A32A9829ECF0,D8DEBB29A29326AB,DD2852AA42362606,000000018917924C,D816DE34622BBC54,EF56D2993D83789C,F064B5153B3ECA24,34F16E299DB1B3CB,B3A69B58620EC092,EE4A8B3E9192446D,D354180277B2CF7A,23B73E125C2185B0,AB8CDFDD31BDF0D6,00000000B2E1021C,1EBBCC8567C392B8,45A4D6C7A43EAE58,D2655F25307DD679,262B3369C00C9215,0DCD91DA835FEFFC,E634D37237E4B9C5,BD7468A11010D9FB,33364B56974C061E,11A04E52C9E5F1D7,00000000A5589C08,4CF8AB5E4DE0E4F9,3750809C7B60D368,7BA7D4CDC3EA6191,D056BE205538C5CD,6450E19E6DA10290,6AA842183D5913DA,0967A68C5933F9E8,2B9A24F73C225FB1,7E8428E55E7DB958,00000002729A7AD1,F91E48849C962FF2,0E5C7488818DE6C4,2C6111811070FD4F,AFF891EC66F1EDB0,CF7ED22142322A3C,1235AD106F8B0106,7F4A4B073FAB7581,905E32270AB1B002,D5D67C7A5A20138E,000000009E540DAF,3E13196EBF9DC095,A2A42B888455A773,558E46B450BA1558,FBC62A6861C0CD5E,6F7CE81DDE8F4023,9EEC254636E0F319,C22C337F5BDA7677,DA9830F1E8B1FFE3,2DC4B7E70DAF3781,0000000201F93974,69C7FC3367AD16ED,7457A140AFD54B38,AF7D02793271D96B,D881EF6593716C43,2425F6A12C64C45D,318A2D7703F5AB1E,579919F2DC862FCF,47AD8B3743F9A5F5,970A88FE96FA8B21,00000000C85F550D,F186EDA5495FDB48,EE120B859DB55A68,AF14DDF9F20A0B9D,A6E1A83F0AC80D78,D8D3B0097865E071,2670A77C35FA9C6C,A4EE8C164F2DF90C,256FADA08BCDBD14,382DABC63D77149F,00000000FD38C940,FD76FA53ABA996E8,498B96EC73E3F9EF,6717EEC29E68E758,65AA9E664C5F439A,B4019D87BB18EC36,2EA3DC5CE74898CB,684B0BDD8DBB2088,B2E1AD4A50EDC3F1,7EF7A263BFBC0526,000000023875A19A,4ACA209030AEEBCD,0486878D8D9833A2,0C11066E3596C45D,223AC0F5D6738E12,DD1D165862648D96,4864F1610C1F200B,997DA376D8EFAECC,98D48CA3FDF8AA0D,4F2259B29C57B1DB,000000003CBFA567,F6972B4C696B4959,EAE41ED219B82510,E81BDC9862219998,AF0302433D6FF329,E1E4FE35C830F23E,2194D5D8D0C254F3,7C6962CF4CDB005B,7C523DE3C19E6B29,9FDA4431C9D63B2C,00000000BC1EF428,3ABEAFF39166DE60,0B1457C6D0704B87,6786D8B641DAAE2C,B2647BD423BF5BE9,1419C7C15A8CC388,8F02F20F3518E15F,DFF2C9A11BB7FA07,AD2AA843A505C72B,FE4B0BF56D6E97EE,000000002E7D20BD,D3BE5FD9FA6AC95E,90E0E13DDDE2E0BF,227A7CCD74DDC04C,E5B0097526EB02F9,573BD5584A8E3E84,3CF8CAFE5600E3A6,8D7BC7C1A195E974,3C7C651EAE33C50D,9E04F49D0BC1B253,000000025E4ACA71,352246AB3F6E64B5,45CA7B4AB0CF1D9C,5AED22E075337169,93348F17C5028A3B,C0E5D42637ABE2DD,13209290D9B115CA,EF3332F33FC130E6,A04FAEAD6DDD5F62,ED4AA026B365A2CD,00000001027E8301,B8D371D1A4535B9B,59D8A02A90F5DA19,1C3B23412198B9BD,4A4542C256928731,C1630900837869BF,03A73388ACBBDAC8,CE965F4E5412ED75,BEF0AF451BF2BDA5,BA478679D37103D7,000000011E0F3F01,6BB2877E0AEB57DD,F3DC7E6D52626B37,5151018772163C71,F3D8ED6659CE726D,57AD24C8953EC45C,983499F90C4DB3AA,D104663D31FE5CCB,4AE2CE8134B73B4F,10A571A16670D9C0,0000000030790CD7,3DED0D19173914D3,86151A214D1D7AFB,59483D66F4A207F4,1A2B86AFF634FCD6,77BA4A5102DAE3EB,CFF0DC5F221A5B92,8178D10D92C724B8,5A4AB5095B82C5A1,B11559C36784046B,0000000245D93820,5FDBFD64BAD1CF6A,7E8DE5BE0F9702D9,DB4FC8664FEC408F,776F7C993505D0C2,3BB363C15A036C22,D43D2B8B14E65DCF,91C862EF8E5880E3,A9C78B7FB4063A88,EA0CABC25C3286C3,0000000062C30F36,05C9CC4CB803A182,4FF7B5FC04C7A8F7,60F6587962FC256B,0F5A361D59823C27,80CE1B22C2BB9562,B1A44EA5E6C2A491,B3DB5DCF94904A16,63B802C7A2E32910,3148C244F15003B2,000000020C7438EF,B1BEEDE607683829,43B31D7F8CF6F63A,6EB311EA4938AB79,8396270E10B589EA,9123B111C3D9AB74,35D268F9150261BA,42675809C0ECD498,0D642B4487BF39FB,CF0FEE6D975C0BF0,00000000C6529582,5DA52DE2E62B02F0,8AD499E1D30B71B5,D150DB9FDB01AF9F,22849B2AFF2FEEE3,2A9BB481B64461AA,BDE0D7867F35DD76,0106B2FC48688AE0,4E296EF9F5658A9A,74BD0DC8A72456FE,000000010A432664,BDC781D6EAB85413,1F6B72302B6F7437,83609B5F775E5DD3,BD284763B66056D3,4187EF60E9115701,45FC3392FF997702,C816564334EDA76A,2E069C976C6EB91D,EE640D22DFD304F7,000000013DB1DCAF,C652E92E49B7F7CD,8A36721FC2159DFD,EE0C2DB716CE6358,358BAD009C67E421,CC23F014446D8AB0,674F5B0C1D9E3D4E,B64E9575A013FEAE,C41B28D1370EE4C4,C805538035FF1607,0000000093C1EB96,E691943DD99B64C3,69E342214B22EB44,E64C8FA68312CAA2,8527AC642DECA70A,0EF3B7DDAAB73DDA,A730C91204F5DA78,1079839ED0960C60,8EF09BC8D9F97BDE,B20ED42772429620,000000026824A853,571E9C8D909F906C,1C2F274697A0DE4B,2ED47380C6AAD9DD,2748EA50CD296289,444669CF3B7478F9,1235EBCF7ECC29F5,07D91D7E64D9941D,AA186C7AD5103363,48579431F80CBBE5,000000008EF4B421,3B32FBBE2DB2BC9F,24DFE9DD88711824,73B1989BC29D8584,B8EFAF902A50BDB9,AE70FCACEAA8BD93,C84BBD15BBA034A8,4235C4E1BE2ABE76,2CB69E58FF330EAD,04F2C8C52A2769A9,0000000275AEC34D,66E4B3BC6D503D2A,967DDC2786DA3FDC,75DE885CF7077A28,D0288C02809C42E9,DF4C0C8F0E59D67E,CC7043DD7D4B15A2,9FE1D369BDB20957,C4B4B251DD69F196,0AA90E17EFAB7CC6,00000000FD8C050D,C9C28A5F1D4A607D,CB1FB025E68AF2CF,1936CBB5A252574E,301C1488C512D81B,74A84B4D26E3DB9B,8826758EB226CA7B,CC3F25C91DC5190A,A30A13ADB1404396,4638B7DEF1FF8366,0000000126C77397,0BBC24311B22BEE1,AA26492DF7FEE2AC,37613616E23B9490,3D288FC114138A32,A04622912DE0AEF2,E516AA8786FB3B64,C681F1173291948E,810BE75C3C995C9E,048D6E4625744072,00000002693FA1BD,7C4495E28C08FB40,6CC20EC7C5501A6D,E1A423281D5727D8,3CDA803A747AE42B,F293BDFE899FE942,6A63727D6EB6A7B9,4F577551A8B93A75,9D4FE5F3F2A6C738,2A52219A2AB66B2C,00000000EE73A837,76DF701AFE0A7892,9C01ED466F2C4FDA,1EB87874BF72C942,C22A46E7CA64CEB0,40282D499F872916,E6CC47E467A1C936,E4720EDF18686A2D,DE157AD320F659A5,28512D44AB3D19AE,00000000D92FF5E1,B80A80FD2F99F5E5,B0C648671D058E3F,34933005264DB7D7,AD514A0980ACBE52,64B81574A82EFA99,AFB2AF6776022E88,808C34FA35FD53A9,C25994A4D9B06CF9,10D46CE00D4E1F41,0000000192860BD3,E3CEB0FAB5C3B9EF,03AF90E09AEBFF02,7227045F656C3C36,221CD85B3F2E9139,82986E2D3BB7C0A4,BF844AB18BF02E11,DF10E1B7AB5B277D,A370AC999D3513C2,1A1EF9E71E4B2688,000000017919AE71,A389C48D3968F3D7,6DFBE9608EE8DCD7,14B8BA30674040CB,1A41A5E3B1A737CA,9C88FF1429C60C17,55882E4B4E4B409E,2560C7465957AFC9,26822C716C02F0DA,C8B691285F10AE6A,0000000278EF07ED,7D398EEE46D9347E,C098092213D67999,33FD761B970885D0,E2B97C428DEF6DBF,75F6AD9BDEF9CDCE,7D40893748FD8573,7FC848842D59C12F,A34C8FC72205F1F4,0766B8C0058E83EB,00000001324FD0E1,AF0D1780F3C98E2B,9205F12E21EF47F8,191809A403552F0D,FB6EFBF4B2C4C9D7,3DBA39AA7A88748F,00FC49A0B4DF1E28,081D083F6D2B4B31,9DD30B48CA4DEA40,86E0951C7372FB69,000000022E552E72,38C19A28E142FE07,EF2AF32D5F2ECF78,9AC7734A0910907E,4A7E68756F234589,B3D9DB49F6A8CCE8,C42A1CED1C9EFE07,1C3984B9FEE33B29,2B0ED24F3A456F5C,DAB17C348E29BB01,00000001741C17AE,209F42F8455894F8,6FA8A3A1B7BD3BE1,9F32DC8B3C0FA504,BAB1B4758D6078DC,D52D3CC33689B40A,9B3E0ADED2218157,E5CB64BA7A79EBC3,98F145A388451DE0,5EAA8449598957D8,000000025AC64FBA,067205E15175078E,894BB12AFE2FBCAD,E7C2B8FF7C89A4A4,3CCB5C538771A30E,1AFC884966422A98,3226153F17164CED,2880A9F90F294C6A,30EE7C6EBF29F024,3C6FDBFCD1B524A5,0000000254215F1E,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,13A2C637E95545A4,CE90FCF423F58113,59162A1251761C47,22F6B23510F407B0,3FB40A7A3898A0BC,B3BA446746BCA3B2,7A837A4454F01666,79A9A22B85C4EE99,E1093BD17C27343A,00000001737968C6 -T_tate2_firststep_Q = 02C9E53071352D43,EF4088AD3E54C6DD,C18E7055D2CFF348,24B3268C87D5F690,A3E6D94ADE7B0A93,489BAD43902F0B0E,A1A300A465CBB34A,1E3D0279D17C14C0,CC6901CA8B4EB6EE,000000006DEB13A0,B84B1E242A63879E,D3A74C3D2770FA06,49DF32C277DE73A3,CA452CB04EBA1741,0E36EC74B21763CF,EE808C414124F7B3,CDBC7C4C7FA2F565,6EC6A04436A3B6DD,655153FCAC56E490,00000001C8AE36CC,49FBC511D3BA2DF8,DAB619C2019157EC,DA5C5F3D92BBAE54,49DFA8B23EA68649,4B0ACA57CA833E4A,5897077C5879B49B,2292FCCA2466BE33,67ED07E1BDBC7A44,524DABA6A86CF688,00000001A291037F,66B1FBDA9D4C0E29,F387AF93CD5EDB70,D7046A31DFDDCF13,BF285B931FFC64B3,200D028613109DA4,A8503FE4DEED0131,0BC04855F33EE906,287557FA56072977,DE18AF410CCD4F3A,000000000F7B7EBD -T_tate2_Q = 0D8A293B6CF2BB40,E1B641C07DDEAD64,752811982A639080,5EF082EEF14391C0,4E69530B77F63838,E5342EEF727F6792,F833326993E90187,ACCA058E8710D072,55F4B4F98DF5D0C5,0000000024DBF832,AD40559D73A22753,4FEA70030F3D7C30,9D351D611C377861,BEDDEEC5B19EF48D,EB85498B19F2BB0B,81699D09B184FE3B,5192C626B954608F,BE03D730E9EAFD39,B1CB16413A4315A2,000000016254F779,C8864C028ED7D0CD,5915417919728699,0FD11B78802FA9E8,69FBB78B682C26B2,65F142FD521EF5F0,E5F9EB77B3BE7118,FE0A2027A9ED7638,D7BA06F4CB96D138,80F1310134488F3C,0000000045BF80D6,535C6E813E9D518A,0AD64453323044A7,B68696F72CAFB024,67ACF707BBC8B400,4DEB973E18A70792,64C75184C18B7735,C143A2C5B37680B4,37002C2DB2585AE6,7137052C44ED8446,0000000050623905,25AF94FA7F46084B,FA16E40C4015BEB4,30B5F128BD2D717D,3001A48F6C04ABA9,1EBAC5083C31DC97,3E2216F817DFD05B,34D63D8988B80FAC,53D6DBBF58318C8C,EE135C318B0B4FBD,0000000061BE9479,DCC602C47929F513,CBB3BA8A118AB151,3561D931143F076B,7A5650B3B71E4440,81852B1B6CB1C60A,19A793E2D2032748,209ED381A703C869,90DB88EBE4C731E4,7AA62EF4EC9D7127,00000001615D6152,B7306FE6C6C844AD,CADFDF1D57932310,4FB22989A00760AD,4DE5D4CCE59DBC2F,9AA0897142B34383,7DD86FC4567E949D,9260F5E77BF68C2B,7A3E0578161B1F91,DD7175E107F0E9DE,00000002313D9822,B209045D4051D0EC,27A160D0E5FC64BF,CD99808EB0E7CD46,F89ECDA143F74D6C,416622BF3824146F,FA7FB456AE512FB6,B0E4F93CC69D314B,97729DC4A7F13D8B,5C2D47D495FEB5EF,00000001079A6B9A,9AE4D9DD682A3F7C,7DB6EBEA0F950DAA,7E32B56F928BFBF2,89BF1FE99DC0BDB5,87612D25779867BB,0DAB5C143F03C478,CADFA7901D346B96,6A760FD92C65CE15,ACF2085B33A86416,0000000198758E70,E3EB3AB8143F2340,DAE56670F6991736,A79D1B2DE9F5E2B4,490044836A4C4FCD,A6E9EEE8B7FF06AB,A7D5C63BB0227849,25D81CBF5F39EF75,949DCC7DA7D8BE9A,4A7DE4544BFED9CF,0000000179E0634D,7503D6D3CFA98967,7A3DBF374FD281B5,8503065669A8E21C,8550407D68B26BF2,B177C65F71B8DB7A,5A0D45B0B9A837CA,DC8077F4A3FB45C4,153F3C5CB9E7C411,17D2017D1D0E9A84,0000000002E11E8F,B706C3A63A31B996,CED12C91DEFD3A2F,D463340FCCF53A95,551D854425B67A71,28DE78F7E4FB7D17,6E194BB2BB980245,F5B88FB1AEE07F32,85F35A860C5069CE,5F90EA8F44B15C19,00000001AB064103,5F22068AE94C4166,C7432715BDAC1304,AB480DDE9A1BC065,D162573FDEC6853B,35DA082590792F4C,2DEB1D9A1F6B404E,604CE900AD128374,8F33FA9A1D79371F,3D7A20EDA39EBA74,000000011D8D4C4F,4495FF76C0BEE7A0,3AD1B456FDD7F86B,12AB903D9992AA49,8E3BE3D4211FA9E7,6A9534CE89C10EF4,ECBBA15E69F5C65A,FDDCE4D0CE5CBCD8,481729622964F7A8,36377FB17C18D508,00000000FBE3B978,A3C3156AD16D1967,B588C8A52CE721EC,F6E7479F9D828F3E,40FF05D220618A1B,74EDB36E785AA55B,2BCF392004736123,9E86DE8F1E9DCAB1,CDBD9B5424A7145B,592DC689502FED68,000000011366FFE6,013BBB9C1B414E1C,D9AAE4D9D8B2AF0C,06D732141024FD8B,437658E4F1FC83E2,6AF94F0A48D4088C,3526A5FFED777880,C0AEAF3F9C1BD66E,5ADD0233869DAA1C,660415191C524BA2,000000001B1C818C,A0B9F640337949B4,743D4EDE527AD851,2B0805A428E85026,4B8021D7FCA4208B,DC579898CFD992AA,9DD7BD0AE4FB28A5,A2CBE0BF4FE509DE,34697254C6428572,327B9DCFD35FBD38,00000000CC1395C9,F1361CB3925213A1,DC63BF3604B80029,5E5D30D348944CB0,8BACC140FBB0CA2A,3B4B28636898829F,67C2F0F0545F5FF6,921EF314EB6E797C,103F92B66822A959,673BDF2F3FA93052,00000000F60342C0,8F9948543B99ACA6,36F97D42A2D36739,7DBAB23D616B79C8,AD727678D082265F,9AA4ED08A53063F6,62A93AADCA656130,EE4EB68243F93FB1,919EF72927726452,043387AE2E23418A,00000001A8D88C04,114A5F37C004E7CB,F214DAC001515C4F,341693E0B4C0FDB3,84D8576224802B1A,E0ED480067011D08,1A2BCC2E5532D8BC,A040F74C0C3D2A48,9C77DA5CBBFC1E72,440E480406862351,000000016FAEF420,32FC47412AA23764,AEB94B77E74747F6,4A5DB04DCAC62563,A966ABA8C195D200,6D573C118E654059,2FA9AB15674CC9CE,161EDBB4AD079952,CD9A458D8C76B2CC,7F007FB0DC570B73,0000000263A27A36,2BED0C1FE378F2A8,DA2A696BC0B3494F,50C4F1CF4E48D8AB,DFCD6052BA3FAC7A,8335F1E373F5AE6F,85C65A19416959AB,FCE4314639429572,FF7FDF47AD3E1FAB,FDB0F6514C9A30C2,0000000078783D53,230D045A79B18DB2,1E68580164026785,D671CE8CAB69255D,1134FD7E383D9F01,29034B57E92E00D6,781A01B4CB80F823,D5B0BEE3168BF4E8,C84C3CA6DAA23D1D,278D4719D946E4B2,00000001E90610D0,7048353A8BDC45EE,C5EA8E4DF6503627,75D7FD7A14AC3D5E,AF2A17C0FBABF167,B2F06FDBE7168BA2,61CECB7C4F8FA68C,11A1A27F43B0705E,FEAA2B8F812D86C7,E469C3E3B3559E03,000000018240EC9F,A92675E44A8C4C37,658E0A94E9D4D9A5,06BC9B662F494C1B,DAFE8559BA3E1DF8,DE44293B06D5A0CA,1A7F9CCBF38731D4,FCCB6B8068CB4CCC,59AECCD0BC88B911,7EB6963EAC6DA86B,0000000187BA26B2,BAB5987121504DDB,366C3B3DF4114A58,2EEC6F679CA0C63C,6C070FA1C6EDEA55,CD878F98CF05090E,6F5A044649225DFC,07081A7B7459EF13,1F31F9530B2DB722,412FABDF800B31EB,0000000148B46D40,495AF93A016E5F58,46F75E958C209690,A400E4CCA631A6A8,A82752772D4A4496,89BCEFC688FA5429,C5A5483286443D0F,BFBEFC4D167ACCF3,A45795FF298A98DC,6CB2FAED780DF603,0000000005A4E860,74F374F3AFDDD98B,44C89434120D6D2E,F401B2042193889A,B93371C269702247,D01997514733E4D3,48580EB8358BCC72,F040C70DDE52DAE2,B89401A0BB11FA5D,09CBED1BF6FBAEB3,000000013CDF2630,D66A304FD62CB10A,5B5F6AC0883DC531,41C3E11A22F343C3,499823BA6C3922A6,CC2F58B528A4EC64,F91BCE15545EFA56,9B00731D9A250208,5142E922E648D89A,C1B3F3739F808B89,000000014D663531,59AAED308D3B1704,5CF6CDF81E0B0FDB,CDFCC18AA85D884E,83AAD261D1D6216C,EF9D9332F29B9805,3AF7649EE92D4F8E,2BA88ED38A6C41A1,CBA08376808CEAAF,66E9914C13EB39B8,000000001FCA1944,0D3D42403679AD82,62DBC05C75294BCA,E621CB241200ECB6,6360EBAC16390DA6,336FBC81DF7482B9,3EEB6169B100559A,784432B3F3631AF1,0EBE5214715ACA3F,61F930A38AC1C914,00000001C3F2DCB5,04B7933C7EA55A06,38807524175D9E98,F6B8841D7F83A4A4,69DE1EEEA7509380,E98831716E539DB4,920B78B60CD4E9E6,669165E748E8CA78,296083B2D2C98BE4,55197B31435F32E1,000000017436B5F7,56B471BC3178BEDE,5E024E620DFF6883,8E9D78FB5ABA96D4,7569549D47F84F24,7D0A66C2029075A5,16478E4B61EE69BB,BD72EB2EB1A90D44,80AC7479F21D9E24,8B212D95644AD21F,0000000143A4984F,28B5AF5D56CDBFFC,528CB9D9B21CC751,72D66CC56F07FA93,C1210F83201EE242,6916FF2CD2A8CD73,186C8E31B277DE6A,646D3D76ACBD4965,43A2A3081CD0C090,16059CDC55D8DDBF,000000000BA5900E,192FC0A416495766,D9AB13F2A667A98F,891AB6E2EF60C157,D218A531C411B34A,D2E05758A116E190,7A5163330070EA6C,482EDB3DACF094BF,AF9383D30193419A,8B268C74BC4E749B,000000008184D5F0,A172DBFC9CADCE6B,2754699F27C56FEE,B8F2EE436D9DB687,4B12A71BB0758D50,156E8F7635D205AD,A58EE00AC06C3BA6,1DA197092F116EF0,20F9A93530ACE49E,9935E367B10DF943,00000001A2165C35,D60B3DE7D04B4D80,8815DBC4E44E3949,C120B9BC6535BE7A,4334403ED19F8D29,E3269DEFFE38083B,B066EB77DA9B1CA5,85D7EDB2C71559F3,E69AEC407C4FD60D,65751C3A74E029CB,00000001330C7AAE,2681CDE9AFB1EFD2,E6B61A7C87E4849D,55495CDE8A96479A,229446DBB1932328,70EDF88FA8EE5F0D,4B2511B06B9DDD93,703FFA7685AB4275,3D1163B24F38E828,3A1B34198EBFDFBA,000000016C893BF8,8A08D4ED3362009B,CEEACB8BB44BE9DE,8961D64EB8CA89A0,F8381AAAFD9F5D11,22C56EB5C7DA1592,770A0671AF79C0D3,86B99FD0A62CDFF2,F2B41EC94289C975,DF3CC4DD537DE087,00000002201BCEF3,2AA8CD224B2F7D6D,A6734DABF1B6BFED,8010A84842280324,104C2556EAF398E5,B188B68834B313CC,A0EAFD30AFC12DE8,CEF3BAC1BA435682,DD7293935A5E5D37,75A4C9ADB6BDBBAD,00000000CDDFC49F,63EA2C96339E24B2,4C3F97341C55C784,A3974C7A01DC0F91,72616595A7342D84,B7958C056A4A1F02,0FFA025C32A63C8B,A9FB257805E123DD,AED191BDA4085C54,12D2F4D76B5CE484,00000001AFF682C1,87C03132A936A5B3,B553676B57FCBC5D,39067649CAAF734A,69F0C81D2BE357C9,69B41B8C5756D129,47F50EB03D7EF088,FB2A61CF14F43BEB,C65A6B0A530672E9,BB159DC1AC175C6B,0000000210CCA106,1640B0318C462826,6AEC0D11CF5F1EA3,9B3A4CA591917194,CDAB2BE379984218,2763FB622D58A965,66E25E7CFB808E9C,2DEB005666D03312,59922AB6C7454D82,E3A1BE83680C0D75,000000020CA9844F,8C6B9C391A4D94D8,12F89D9CF053BF6D,0E9026ADE0C74B24,4A06C288C4C46E42,479B6699573D91D0,14630ED1B17B6165,E1036C2B198DEA43,463D14DADFA2D7C1,32BCB895A5597179,000000012544B648,63472E2CD585A951,F610C3BA6E356666,289AAD47B7E3C0EE,A7E1D26EF70E4868,312EB338F08A9961,1253FC5BBA3515E8,49F306062D992603,6C083754F9F8B791,53F299CB9249149A,00000001F7AE9E8A,0FAFA7038F98ACA3,3587A7ADDD62850F,BFC0D0555338C346,49F0225252A047F3,83DCBD167BFA5429,4175569B93323F5C,CB61DF6362EF1491,5205BE9E01A38294,CF84BFF4EEDF165E,000000023D3431E5,9BF2CD69EF0EAA0A,AB6336EC548E87AB,DD8B11B294063FA3,E01F6F890639B576,7416F6C266ACC44C,239BFF3120466A1E,6CEDBCC733143B00,8A36D478DCF9FEE8,7224E36B685F2B57,00000000599F8DF4,0789C284669952B5,1D8162DD3D730A08,EB136E49C82EF7E5,75224A5398187B85,47DC4FECD3A32FB9,C4FA0F31758940C5,8303B8F766ED82BC,3B9957A4F623A483,DFCF87DCFE83BADB,0000000241E755CA,C1EF4933FCEE677E,AEF34A2D8CDA036D,49D8A63D61663C0D,43B856CC72ED457A,897A9DD7571C3983,95554C1070A3188C,B10BC5D8F6A0D62F,A6B9633BDCFDDA97,B067E99984D1F23B,000000012DA40E31,6288F3663EF7B740,C930178F7535C7A8,B07C04D81B422E94,60CD417134853362,0643A14DB580B196,24CC07A55ACB952B,16493E1849FB2B87,2A252D48539D6975,4A5237B3BC682CC9,000000015028C557,987A15C4130C74CA,6C095214377DDD5E,F316E6FD9F15953E,0820B30BEE5D2165,A4DE814F427D3A41,CAD3D6ECF45B9F1E,C137DA104C7ED63B,62D7F7A52A46D5D8,90E738C4EE435020,00000000F87B0CA2,B3C6DAC8DF38226F,5DCF7654EFF59EFF,738D97792CC55170,37AABEC24B49DCC6,EB13354793EC4681,44A578A47FB958A5,70AE96107CD4D7FF,A27FFB8E70B5EF8B,7E0C181CC1244B0A,00000001803147F8,E3981C1B3D6FFB3B,33596926B5AC0DD0,D087876F64358F0E,E3AA8C4F665C7900,17C71B2D2F59D589,0C40CD420083D498,8DDB6D014FE616EE,9420E07FDA295641,4EAA592CC5A119F9,000000019B35B42D,FC4500E4C26949B0,982B546CF31AEAB4,2AF4DEC11BED37F1,7655399D07634B79,BC85835D0DAC01AA,29E6C408370F2FA1,2F9425082637E63E,C7084A427445D001,030CDA7A4C730C08,00000001F7A786CD,8D1C8FE5C4A00803,FA789D51B48F1BF6,C08928E058969E6F,CBC918BDA08EDB63,FD02878DD8541000,5070E83BB4E23F43,B1C84B2944CA5781,F8F2658F434D00A7,A6DC44AA3D4C7609,000000024CA26CD5,663FB44962F9CB65,AFF90654B288A114,ED3F802806278D33,E2FE782498ABC9FC,B53DACF36F4C54DF,B4CA7FE0B27F059E,319F6CD7DC53ACB9,357943144D3A6D81,636CDE5A52714B87,000000010AA67425,61AF98AF02C824CA,04E0FF5D5B759065,FA528E52FBC4052E,346AC7BAA42A32E1,A465A42367548D93,ED6D5FB47AE9917B,0A2C6F46A6D5ACF1,1D29D510859B47AA,A86DAFB670C79D61,00000001881BC315,7EB25AB2A364993B,8B910F9B746725CC,E71BB1C25FA868A0,80189A7087F2DB1F,83789A429A6ABF06,2BA4F4B1C62167BC,AFCD849827D6BD49,8A5E5496AE4BE71E,83A8D751BA71C30A,000000023FE1C14D,57132F11E208A443,F5156E2240348DE5,950561759897B22C,9F06039D1A5482A3,EC4FCAC98AB7BE08,ADF03FA4A23F7741,B373A34A11C45908,493E052653698F3E,CB9397591ADED3BB,0000000083FBCA3E,0CB7A0CA10079325,564E707CB9FC2B02,13FA1051A22345C5,5FE29BFF0427BD95,5A46D53D7D95268B,AB842510995F9FFB,9125C1681E78AE50,89AD57D3C52E3564,802E1B23027B8D79,000000026D0BB4AF,B774D4813EAC11C1,4AE43F37B5812D1A,D08C33FBB8CE45F1,830B77E63FD61E57,B26C2992ACE8447B,6F0AC440ADAB63D6,4CA1B43F6A5D77D4,E1A4C6D9797268E9,60F6D7C7219B190D,000000019D03420C,C401F3BAEA2667CA,B3774F1C8E2F219C,A4190419A25CD5B5,69ED88E124FFB00C,1C1E5EC98660A645,C134D7E9CF2AC0F9,F1B8DCD6FECDD4C0,7DA172324199D67B,B2E6ADDE2A4FE872,00000001A97A1FEB,521A25EE041D477B,B9D76C6350085B8F,4607E17146DA2C46,E64CB2CC41DCA660,12D44999E012E118,B27C33A5B745F755,51FD062F3EB47143,767D84EBD3661646,7ABAF0B7170B871B,0000000140102334,D80E7FAD10CA2F6A,2C7D6538223E1E4A,751708CD3068606C,DA3BAFF229939A7A,6D6540039104F608,E403EB54CE9956C7,73EA5DBD291EF88D,F8D19A9F0850969E,9FE5A3890FC87325,00000001F9571FBA,0B659676C1A573C4,0BEB887BCCD59A54,0F0A78B8794E73A4,E1FD48896FF9B4E3,1BF78DDFF3B8BE7B,3DA0237E3A9FD395,8DF6CBA794389F2E,8DC9F9DF84515118,301B26D1A448056E,000000007A2858E8,FF66AA7966D0E2B8,904F31DA567F90E6,5D9B325E919638AB,DC9DBF31B8437AB3,C3225D90F537EFC3,736FC9BBA4301EDE,89100B1AF6D9394B,5FD8D8EA4C8AB3B8,56BBE83E6794DA12,00000000BA61245B,1931C8CE6E69B253,71AC68AAE6AFD897,3A4819E223911668,E9C7A3BFE34A8289,E7FCBE26145CBCF5,A0F719CB2060D0DE,B83737D62581AA50,C50A1A37E17299D1,FD90CE76C33FEDD9,00000001DFA97B16,D490C88035357A89,01F1D1A6E4FA78E4,22B0BB17853C431D,6D8526ACB9FFFF07,8963A8F3197FFD3E,6C15D87070E8F748,4D3CFECCD3150822,B5D75FD49EB3B8F8,020ED55AF8681C46,000000006823EE78,6632BA7D9AEC1BDE,EC006DE1C2DC4C9F,8F54A41F3E770698,871C8568D70DE7BD,86BCCB1768778586,87A737A00AF76BCB,5E8ADCE6FCA27021,F7DF3BE7BA518F25,22B1C7ACFAE5B37B,000000004ACB8FFB,1BDE1FC69CBDF3AC,38AA9222836CDC10,39B4B45BFD01CF89,5C0BCF66F690606A,6335D1A344E1702F,84F27DB595CAC6A4,9731DF321DDE5E9C,D46908D65EA24EF9,3427C54A2F31710D,00000001EBF7EB3C,E09F51F291EDBD2F,0E5FF403324189A5,1E44CB7E59CC4F6E,16FEF66969BE26ED,97239A32B49DC773,69CA086E5E2BD3E0,94EA261B68D432E4,2766AC70E35E0C2F,BCA156136567685C,000000001042D64F,F6C75549E78C1D0E,726E8E5F21C4C0FD,FBD23A6DBD52E4ED,7E2B658B9D8F5AC6,97427A32CD644D1A,04A77C6CB286203A,D0DA43098CE189C4,A73CA159BD9A892D,239D3918FD6FAAEA,0000000262E066C0,65F7CF1BB1E94D7C,EA22CDAB452542B0,EB88F3BC9623E803,9DE16B6ABCF79031,5C16DAC9C43708A2,8608B48DA164A88F,2A9165993CB421B0,4F617D7B628BC371,A85D0A3BC36A296B,00000002293B23F5,123A876DC19ED2C9,EB606E3D8197998A,E265F33ED01116BA,46A6E263D364D763,79EC81557C979D0C,C9EB5079FB916174,81787E0C2B4E6716,9B87756B36141650,77D6951B940B0A26,00000001E88F2A5B,528FC2D85165A774,2A2128C7F1AB692B,68D687A74874AF58,1B465CC24CC8C9D6,66A2EA4B25A93DDA,0E7868D97237A32C,8E7300A767B5D5FD,250C73FBDE5B1630,38BE020BF2047F5A,00000001B5EA1332,3E0C904CFC9F27B4,68EC6A05B4B84BF0,15F86EAC4634F525,6B829AD93C500767,5CD1AD50CB72D2F3,685E45BD0B8E03CD,8FEB6ED575CF6FCE,E80E66DFEEC428F4,F253B1841DF666D9,000000011515F561,3AEC92D0C61E2F01,2621B24DD76A83A3,7AFE9014028F6503,27D9A7636CB7E44A,387FB88D3AB30119,9C68F48E40F52082,8A03C572259C2374,7185E7267915B83C,C8690C4432A8C51E,00000001EDFE6D77,F5702FDDADCDDC83,3725FC88E88C6986,0243FEEE1F9EF8B0,95345FB94D68E240,FAAB91472FA8C62F,A3E8731D6375F7B0,3E2912F253271FDE,C704183642F09A63,70D0FA923BEBAB56,000000009F097DF4,34C134EDA2037B18,78EF16CB2A1B8BA4,9DA4FEF217A734CC,23CA49CBEB5AC385,5A488B5F9F1F5FE4,7C3B969B2BF12D3D,EF602FABF17E0411,00CC2E718DE0BBE4,197283CB900EDE98,000000001ADE8821,1D5904D4CC55D5CC,7491913304D1E514,12DD4E2039BAF1AD,65EAE25CB530E9B1,75D7D77ED5040DC2,9BBAD04ECA329143,D8584171416B52B5,44861AA72393F59E,D228529B0022CE22,00000000444983C3,EAA679178FE71663,04B0EDE38AEE76FA,D74FB79C831F371E,C75F52FE3652C22B,E75B6436796C48A4,B8BF47F90448F373,8B4503D502553D05,C54A5F55BFAA1AF6,CD2B4FE0C68B48A3,0000000184D8BEA6,3C402D71A39A3EBC,72360211C3F6ECA3,5B7711DC0DEE04E8,26117E7625B1690F,5C99DA0E07C1FB84,E231162E9B89D69B,725B41B111AA6EF4,79D9482AA5489A34,A5C2ABA14252FE7E,0000000172BD5EF3,6A91593BCBBF4BA9,9E1DF6C4B8B5083C,3D3477A51EABDCAC,E19CCAAE11781EF0,A3989B17A1A387D9,4DEB4501171C52A2,677E3E0ABF786418,17B5D4287D2AC1BE,D42C37783E0EB3B6,000000009B4A65C2,C533F3F2AC990D8C,44B4A6835E03411C,3405F6EC5FA23AD6,C6DEE0FB07731E37,535001390B00347B,B8F2AB09DFB964D4,ED40B9A8BBEB4F47,935EADB7829C11D6,61B50E4FC81B1DC5,00000000A23157EB,31CE1197540D4775,321C3A0B7B16006C,2B7E52783BCF2B21,4456D981B006BD5A,98DFE42FE49B53D5,AB2A66D0AE7970D1,D5206AA1A4CD7695,6157FFF4F98E7F15,DB5C07F2AAC95C40,00000001A854A007,A02ABAA33955576C,10C66DC4031841D8,B8961FEC4D21092B,A81E49F5EE5C04EB,E196A99F8A9FF7ED,32CF0C078539C972,B6286D6F3FD3BC37,DFB7D276D4657E1B,D1BB77B904E9764A,0000000251143CF4,6971A69258451F98,61408F0EAACA9F8F,3EFB44CADEEFAD0D,FFA6C4CADA5391EE,B549783E07E1B124,313BDB0A25F95049,26BD7D319D0F1943,EE771B3105F86EFF,F408F893E9A9CC8F,00000001A7222002,CCD6B75D199F4A5B,2F3B24325145C2D2,2301EAACC422FFE6,DB21C4A45CE6401F,0A3D3A5EF8A14B18,CA7B58167E6E2D48,FE3DD28FCE22B710,BC9B40B5C8D03265,B26ED15901AFF025,000000007AD83554,0DE65211A95293D0,EB037104DCED04F3,E7A019EB8AC72CB8,5B7E199FDB804A29,D480D87A0A99AD8D,EAA71A6BCA46E4C3,31407F756A5C31D7,EF83BEB7360AEACA,03A189807B256266,0000000185995EDC,423A8DEFEF246DC2,40E9135EB4F149E0,B14ADB534F784581,7C7EF59D54AD9072,3273398BF187C33F,6DACF48C8BD8511B,13EAC0441F9B2EFD,AE677D3AB0B59452,65DA249C6F1F6ACC,000000001E5A1DDE,3996C32E66BA105C,F13C733AA24C1977,A63EC47AD146EDD5,7A3290DB5499C339,227DB17019123440,4B862A048C40D26F,C375A7CEDA886FEE,744B73E50855D97A,521B9726D044F488,00000002465DAEFB,6CFC818255940BD9,D750A450EA5EA832,E3562BC4619F4B41,ACD5AFFAC7C95AB8,AAF8503D0BB7E3DA,293F4014FD4616D5,72896F681605DB07,E3D7220EE83261DF,913C214476F9018B,0000000163DEACA7,7731619411B62571,3E1747BBCB66804E,2342FFBFA7DD39BE,88730FFF008C6FBE,EB9CCFDE46834399,D0484F85C2D616AF,875DFB28AC13EFDC,66FC795309823BB0,8016AC75EDA434D1,00000001455DFC5B,C8EAC3C6239886E7,5C7FE864A19A2716,698047415788CF6A,092CB19554D0DB7E,2E601E6D591A558A,F2B25DF232A005AD,54F9731094B4BFF8,EC6CD52AC62FF139,40E5E728A0A06708,000000021A77A821,3F8E881C47A1F208,CB9293D0A1649A52,0BC4AA74A19C6D3D,A219C20AC7377FD5,B1A0D4248D2C8C7E,E71CEAC53FC127DB,4F3D8E699B468334,5AAE420CB95C2126,E78E1DE7225E805E,000000021959F564,A26F52DAAD9DE889,9E627691B6A4AEBF,DB4E5FB26F54257F,00E89C69E3AD4D75,28EF8183645C9E97,F953A91BE4E8D416,437FAA2CA6C2F752,C611893DD22A6CA2,40519AC45F6A38F3,0000000114F43C92,C5FA9363CCB75B9B,B1A77D21FBFFA00B,FFE4536BD2FC0753,0665077786FAAC5E,8259FF865486801B,2E2D2393662F3853,EFDF4B047F5B6272,22E346EDFFCBC6B8,1A282CBBE4235F21,0000000100B2E2E8,3A362EFF62719CC0,B7A1F13F13074C4B,1E5441F1663D92CF,BD0E208E32B4DBEE,A4CBE7E030FC528A,7362700F593C3EA0,9ACE449109346D6C,4412439CCD833A4B,642714732CC44DC7,000000022E0D0DEF,7D0D7400EABE632B,B6209D309E86B7B9,22C664FEEC5323F4,11BF0DB7FB2790DE,CE7234A4814DAB9B,993E00CB3764AD60,426AD1F6DD1DE9B2,4F4979311FEAE04F,6AEA4A7512EE27BB,0000000158985CDF,03AC0819F164E37C,1C93CF27FFF4E0DD,B28897142E35BA04,5912DBF0A8379841,033A2ED6EDC4B51F,0D124A8BF13E0E69,7FD4BB21492E2819,2CE1E0EE05C90B54,3893128A6A171DBC,000000013A1E025F,4B8A185BB27A9DB6,306C877512860BEC,9F3E50660F0BC38A,597C8DAB0D3EBD92,528A533FBC5DE8E1,E77C938CA2C12DD1,DB980AEB910767B4,882D9A051865194B,93DB29EF85E1FC6B,000000006BC27E98,E218F6C383D2D9FD,56D553C963C77C0B,F5EC08C455EE9115,FC717AC3DFF6D7B2,B84F1351FF12B413,76FB094E6558A6DC,8463E62222E1F70D,45E90CC12683F6C1,732CB1B2F47895BD,0000000251A184CA,AFE15B13D8C35EEF,D3BDAFD5CAFB0F1A,D776856893AE8D7A,33561CB3A8E0A58D,E7D6D011BB8B3F8D,9D49E6A3C512490A,BF18E231877C3AC0,3B6D30A360F1F1EE,702A67E337AFD84B,0000000160AC1FB1,D53ABABAD1551C7F,FFF2DB98B585571F,A292A8107A31F3D1,A12668F6F9631E86,F0A838BFE90924B2,2390CF12B4FFDFF7,4A51EC363EB2E51B,427E17F146E4E86C,538B7E4C6DD95D72,000000000F6FAF54,5B8165FF21361464,B3E15FE4D3AFDC28,FFD115A8314219C9,9596220AD39C6AB0,2A08726B5AFD00A2,D23021B084FB4048,94BB350E7075CF54,08B34D6AC53E298C,EC891B8105E583DF,00000001EBC2CE4E,123BBD2186F857E3,BAFE58D06F738E99,B8F26E9CCF02D9F2,5C0D032ABE80C623,06293D8B17599717,7C27E19F4E3F47E1,B50B22316C6C641A,AA536BE3B1D1EC25,5B62865F3CBDA369,00000001E8C6CE12,7B55B35C5775DA28,350041B21016DA26,EB9DCDC919489115,8A409C14CD2071F6,F5640D22FE2EE431,A3D1C33CF70F5C2C,487902D08ED8496C,80C33B0DDE5944F5,00109AFF59555766,00000001AB05C4CF,4263890582C1C573,2ABA9812BF0D9FA6,320726CD77D620DC,E0B107EE69120770,73FD2CE1EE661FCB,F4068CC2C018731F,A08268DA5E5824BE,CFFA9DCABDE3C48A,388607041325A4E6,00000000BA4D9D4F,A985EC150E478AFD,187D082BB1F2485F,22CF807FB92106A4,04AEB2B4476D02D3,84A14EEC0B1E8D47,EB45142150E35D5F,C9664376355127BD,7C58F2C70C722874,8EF97AA1549D14E4,0000000050B0F562,9BD5A452CAAE467C,DCF80CEEB8399DEC,AC89E467964C9274,F25BB6C226DD573A,1CC1A779BA6452CF,5F57E95446FA8BF0,CEF407C975872D8C,726FBF98DBB5F479,1DECAD8D9C2BC6B5,0000000001BC0309,467D82B4FA7D5F8E,994EB14CBF4FDD5A,4C54ACF280CDF336,80F49532862C40A7,EE4AD2CEA5B73F4F,D413E50B6BC47C7B,5357572FAB8F59A6,85A3BB3D582CEC15,B1B884587ECDCCA1,00000001750133B5,7BA3EF76D73964D0,BAFC44C8346E7F35,E234EC0291E3C3F3,AED545D2DF38FD35,38FF53A2BCFDBDB7,7E1A9292F3F75FD2,97BAA7C7D12815E7,2E645D01E15FB338,862DBEC5BBF51C1C,00000000AEC2BD7E,C05A525455E867E8,AF1D17FD297F85E0,A26681C4297A1A96,D423703745AED2B6,6AB8D9E537D13C64,8D5589E765F9B286,EE01FBFA91684AF0,EDC8CE440776A508,FA8FDD9B5176A383,0000000254F48B3F,EBDC37EECBDAECFD,9CA891A08888D106,2986941956A41ADD,F06312281DDF8CD4,756A499D13E996FE,99A8D602509E46D6,F8A72809833969FF,39CE2B20CD8BD5E7,F62BEF7CBE107C14,000000005E85BBB8,5423917CAB352AFC,1494ED40D6A56B97,3D43B1829425E704,C6E51D9E00C2ECBE,AD6A1E4DA2279A99,92EBB6F3CC03C3D4,E304A6E1B27A20CC,4851683FA2C9EE52,9F8E35B2EFAE9F73,00000001F2664056,880EF8DDAEA1C816,9A624683C4302FA5,40A266FFC6D86D81,FC8A92F03981A7C6,9D7B6D5D2733D5C0,4652CCABA5DCAB42,51B3C954FEEAD531,7FC1495D356119D1,55CF96C01CE6AFDB,000000012D965CA9,7DE2EAEC8D66028E,26E06EF036C095D8,49AA87015CE4F70C,93076ABED854757A,961FC074B509AF76,9EDA96B2C76FF1AD,46C8FD594D12E0B3,92243DCF854C32F4,D889A124B3026FFB,000000012E68B4BD,72F8A8E695451AFE,99F74E651DE3E9E4,48608E5F64C5CCE3,E02CD4FF460462DE,FBD79A4C3254BC76,4D8350F3BCE0FA57,8965D1D809D2BEC9,69C599A9F01EB2F0,897A4D80EB89CA92,000000020E91BD5B,ECBACD331C1DD066,ED560E78DD931BC6,0A9A1C45255B3F11,CB6E58DE2D599922,A73E8F1C024E684C,E8F2C0D196B01B6D,E767020905868B26,98BABD35A5A2DD5C,D859124AD9A2B335,000000011FC49E06,58EAD497710F6FD3,95C3A880866D9C68,6D088A7A29E39D52,7EA669F1124C1F73,B5B59009CF7174A4,2D6251033AC47305,70FD0234680DC947,235B782E257A47E1,73BC9314C0A4BE87,00000000CF780FCA,1D9606D4454F1F86,8A5D03D931E8F18B,55D752238A4044F3,93B7CFF69A8CA10D,E3CEA34ED2E888F5,C2CAEE7677B841CE,D33560A9F0F7F4D0,0ADBE38C1CFC1B64,24CADD7AAD90AD13,000000013D21F7B9,74CBD092F9F4B614,361EDE8529E4FEA1,6565B722CF1BE245,6F14602CD34139D2,CCF97D31F79F0077,A8250C1EBD0738DD,61EDCEE5F99172F1,5466F8CC45702705,4912C7929834635A,00000000471BDAF5,DE54E65387C10243,770516D52B7519CF,F735BD394366AC3F,9EA856007189DFA6,F7A1D80992E4D3AE,576ECD83BB9C822F,CF05F66DE28017BC,D252B58D60E4FA05,AE9288EC99A28FB3,0000000001217A85,25B65502B13ED275,A41D0D07DC4E2151,246618E06FF2688A,293B769EF63DDB51,A8B7D221EEF2E287,89647E3CBE340AAA,73F70C58C2DC88FE,2B5357F0795C6A5E,7B70A5C385DCC95A,000000004538F6B0,0545739C38654E57,78285993BAA8EFE4,BF430871BD809F2C,57D4A0F7E2E0CA51,1279BA761F871D15,B1675624F172CC32,1B2CC8DCAAC284BB,AFFCF5FEB1D847B1,C23F2CDAC9D2C871,0000000247C9481D,459065C771D82B66,6293C14CB8A4757D,787EEB6D06499F55,9F8CB79CD4E6B05A,1ACEA1784BBDD436,5862D36639E0A9BC,792C225039D48EC8,47A11AE202FFA2BA,2136E27609555927,0000000262C60123,786541588FC11E68,25DE13F0078B9DC1,4DED147ADF0FB4F4,4555E0B6990FE31B,3434FF8A7DACB6E4,787455B5C3A1040B,8288EC928A49FAC3,9F482A4330C97B5F,82811E8126784F86,00000001EB2E6FFD,28972A9AAE63A8DC,C5CD6EDAC081F437,E8F03122BAFC1212,B1766936B26D4B02,F1367ABD7C0315CD,377C858B1CA642AD,8B9528ABFA23E024,45047EC19E436C15,6044E7842EFAC486,0000000214B73603,12C12F35F44490A4,0743A00300A77D8B,0398EDD2F74878B5,4578A53D1D95CC2B,3603C00515497986,297337698ED8DF31,CE8A8318CDEC35D9,70C759334A6C0244,24C043416B4FC349,0000000006482A1E,6279C55CA2B860BB,DCC5044E36D6F6FC,4F49C6D356FA6EFD,AB2B333BC5EE85D9,2D222815D1E39FEA,152675C456FF7CAD,B3E3A7AC9DB13051,A965DF4D5EAFEC12,F9643DF56D0994CB,000000015BF305D5,06903B486F7C8CE4,5FAB6DEA35BB31D4,9BB92B375134C736,ADBFF645AC985D0A,8818DD8BB9D30D61,5F3E3AB8108EA80B,D984113D138C255C,5717D36CEF3434C9,FFA6B795DACC4AC6,000000013A80C0BC,DACF76523085EA79,74A02D5C903DD7BB,78BC0360422867E0,29BF458EED62AF45,2E810967B81369A1,9203B781D72173D9,0FFC06B5AF242EA1,94F4D58254FD9D5C,DE2DF1FDB677548B,000000024C36C173,875C859E2CB913D8,2FDA04A1A00DB3E2,0AE9402F6549F65D,54B989000834AAA8,3AAA490CF76D958C,8B6EE1451582E7B4,618A28449278918A,BB1C9AD1A2FD1428,1A1FA03D43A21A39,00000001F55EB62D,AE91013802B984EA,AC0DABAD37452125,86C0FB09721898CA,EA1B790E8A1782E9,FC1B26FD3863A20E,FE4D35FB5A837EDD,57CCE275E383741E,C209DED0DC353D81,67F25E45CDFCB48F,000000018404691D,8EE1C4F94CE918B5,3FF5DEFB6B6E67C6,BF7B775FADE81384,832F58EF0DC8DE57,C96A1FDFC6ED5159,EB948756410BF716,AF5A8049E0242372,55BA15C130150AD6,23D9463B040AD0E1,0000000058AB25FE,14AFA46C2F300DC2,20556E164FC8C4E8,2D741BFC84566FA1,66F957EFBEC86FB1,75A0A56F202B9D65,92CB64E4E3EE61E6,7B9CD84DC779D930,FF8AECA77DB3F5F5,1BAD8ACF9E60E131,000000011FC8628C,9A5A73B4C370C595,9DEE93EFA2D17C1B,70312C1B0F0DD983,0D83AD8390968FF4,7B349BB4BE8CB2F4,6A0935CA61DA8B15,DB8D46BF1870547E,1E833A3C884511AD,D59060895324A8ED,000000006EB9146B,D420749D106E105B,3A4FF9F823AA3825,2CD0ADDEECD6A070,EDA6C5289E8169F5,8C3A173C3232237A,E3FEAB78AEFC7DFD,CCB44E45C8D2A096,74718B27C85194CE,087B9CB4EF242CDD,000000017C203EF8,DB39A5240C0CAD13,02D7D525C9E20A13,97FFC42291578A4B,C5D3180C6BA04A64,192AC972D4498BC1,A2FAB095D3EBDF43,D4AC461981D8CE7C,3B60B2ED754E83A8,D64CB754F87A8BC3,000000005AAF9401,39AFDD0FF4BCA5CE,14A58685BC950CE0,6D15BC82A380A7D2,B784930028D56BBB,98BA84259493F500,E91A51B45F13FD41,ABA882714D594BF8,1671AD7871B908C2,D99E98BFD4BE7BDA,000000001493DB3C,21490CFC39855001,02DEFFAD25A9C574,561259FAF916ED05,A6D8B9477DD0FBC7,0E23523989602F36,22231451AEBE34E8,114310DCD8E2FFE4,5D2EA138E50EFAF5,0DA8C06110F77762,00000000ED31BA40,20A91CC119E09088,A83D03DA90DF5D1B,E21B16C062E7BA4C,98217903A047182D,1D17CDE09EA2F383,7B38388ECBBFA369,9CE0FDD6299105D4,7348DBDB6CBC864C,9B6C01CF6D1C43FF,000000014A723A5E,F0DEF0BDD1C12838,E4C37BB35D1DFCCB,F2464C587D56B4CB,0CF7A9E657B19339,0F0DB26438AFD1C7,0120A7074BCE7393,4E813BD370ED79C4,BD646440E43CA1D0,BA26975F376B9BF2,00000001343EBAEE,3F160E3B8F99CEE2,B9F7B2A27DC39367,CC9B2669F2740E73,FEFC7D1C9A81420F,F25C545E2E1E8C5E,8701CAFD6713E71D,A1D528097DEDC596,F656906FED480F10,4725D64916DD22FE,00000001C370BE1C,A57DE610346303FC,11952DDADB859D2C,B09945766408565B,10788158DBE62774,E961E67B99E053FD,D00FA858B400C1D2,C626E74F44F11B04,FE5E06E24354B4ED,EB70594EDBBDD051,000000013C492FC3,1C0494E90B0C0861,9F23F7FDAF6D546A,A1936CE57A5F4C10,967DA4DEECFA5B6F,2EE9CCEA59A82671,CD319C71E3E84610,76E727E148E5A0BB,9A15B6B23F72C0EA,77247F6095AC3402,0000000247A20548,BC7312007A9113A6,DEF18705947BE6F4,8043296EBA390386,31E9026E0A4AAC12,D5AE21F056FD00A1,3D3842E7412CE374,5BD002ADDD6D4A8A,5CD7509721DE8C2E,2BEF46721527BA4F,00000001B5F31874,3EF26DF54994196A,C321E585CAAE26BC,3786ECCAD2C711EE,FED8C6645B725172,9250D4E7FB5683E7,8AEB608C268782D5,AA30EDD91190D256,8B77253988B89045,F6EB09352C385062,00000000F5466AB9,67FABA3D13BC68AC,5C1C999148EBF5ED,C856663C8401A4C9,50FB4908C24FE44E,F45C87AD7EC92225,8F943B20E70AF40B,088FD323004C73C6,1158A7636EC55584,2EC6768B16A870C4,00000000666FD424,0E499D5B5617755E,A3E227F2FFBE355C,30B7E83876DAEE70,61E33B055E69EDC8,89A46A35705263CD,129CD44EB8AF599B,50A7511DB0B115EC,D616CD0E745A0907,5AA723A68CBAF929,00000000D3C8DC1F,52B2177F236F8CF6,C0801028E43FB04E,3946420FFA08AC75,448AE22AE309E067,40CAF48BA134FE69,0DDD8EC488AA7FCF,8B9F03B58F8BBFEB,A917185954EDA8A2,E1D54C6AEEF5590A,00000000EA77116F,54638B2C985B767F,3E70421F91F0ECF8,923134C31F79CC34,25BC7E6DC0A9D374,8BC9A7CFFEB79B98,D6BD05F3C8B947F6,D1D87991A68C90E9,5C278504DAE51A25,8C6581FFFC6FDEFF,000000025488943C,3BE4B2CEB9639765,5AD9A2F640DEE1E7,2B6C3DA3E05E9DEB,757165A7264D8DDE,26B1A69F315ACF79,0E034FF4EE6E1DC7,CB8F80FCE42EA7AF,3BB3B928B02F50EC,545A168FFEE11BE0,000000003E8AFA78,55DE7BF1A9CC537D,B35B6C4F805F3FF2,FB8349006A77FF0B,ACA807409AC43AFC,242504A48E5E75A1,E0842FB6D5C4D38C,BA9AED0E505172D5,C231F1D68CEF1CAC,23D147C0A18CD245,00000000F4FBDCAC,554A7853273E0845,68753C62F95A326C,E50F36F13005A8E7,AE0E55F9057969E2,E2E78080DFBA44CC,BEA3B22466D7F799,FE408CDF6DC55BDE,7AAEE969F339A857,CCCB82050936D1F3,00000001662DC8B9,602FAE1733F620C6,F16B11C285D47321,9CF03771CFD27426,05B3F04D26C799EC,FC92A54A24BFD079,FE480B41A6901D81,8F8B145F96FB8652,D42B2D66D0106639,09EB86916B769EA8,00000001C1CCD37B,DEE0E6CDD3AAB5A3,9F304598AF70390C,9B35C6A74B9F3821,656C47703F739B34,A7BCDA700DC32449,709A1F3B53DE037F,A4D634633BFBB9B1,E436B0A09089B2F8,4C9FD46948CA83B3,0000000154FE1C7D,D6E1DD0282D4ACD3,C7D9C74D6D76AF6E,2A167E84602C027B,BC61DE68A4DED2AB,BD80C3A8837A9D42,3176735A9B188774,83821F833ECD403D,A08E2868065406A5,9AEE05C00E92DA89,00000000503C871B,C625072B89ECC95D,9EE6A2F319882939,A88362E896CF8AF8,F3259E6762EA8854,A52FFA1E903F5444,3CC889239757DF1B,162E4A20354CB7DD,4D56D597960381BD,0A7E00A95B46E571,000000007E3E6D19,795EFDECAE1974D2,AA3F2E7DF653C1EB,D26142842D4157A5,35F1594D0F1DCCF7,1552C5863C11923A,BDDDB6F9D85288A5,B3BEABDE2EB71174,6410C4FC3D3861A8,A1FB67B2B6136BDD,000000023FE00D70,17304202F5733466,90DD1BCDFAFEDAE1,9AD8EE73C599E68D,C2FB68CD2BFF9DC8,0417AAC93FA48A42,5299D1FE353335B9,75C0269D62F73D25,868B46A97B4790A7,D5414D81676AF255,000000000DB3D870,49BD265928EF9D73,1B89EE0C0F194567,6FBD9AEDEDC21552,B815D8C58CD6D291,5E42EFFE72007988,AF64FA0580BD1FA8,7677D4FBC137ECA1,4E8979CE299A099F,3576C95A0553959F,0000000100FF56D5,8D44057FC6CC0985,3EE1A31B1F075852,2534D7B6D135988B,7D1BE429B6E1ABEC,8411EE86ACE393A0,8839DCCC6E7822A2,9871475FA06E9F80,289E522371C0F109,29BC54C8FA73B221,00000002120D487E,BFC52771BDA9AC1B,34BC698717390ECC,D39C490055BEDFBF,2EA5B63898CDE661,376C351450922CAA,1FAD0009EAFC7601,9B299A109B4A25DC,F3C5C650F1EEE031,DB785959C9AAF93C,00000000CDB411E1,A25329D3D7D583D2,B80879C3AC8E000E,D4745C8D9F86E2B6,95F72F79389B21DC,2A69BA65768A1147,24A6384EF9DD7167,B37667AC4942C4D4,92A1FEA8B72AB15A,AFEEA8D6AF9BED1D,000000003D5812BA,3128E0DDADD18A23,3B952E7CB7A6C065,E107D54D686E9005,153447E218F61198,3FD7810EB91FD2DA,EA6B3A5A17E97FDD,9649B55E124F2B03,F61403C63796FEA0,07DBE9200B5AF20E,000000017865CF96,630E500707EB82B3,AF328783F3E1EA9A,111F17D8896F83DE,DDC6899C81E9184C,4FF3AEDBD2C43545,0B431B92740E22DA,07EBA14EB5F0097B,1C26120F815F65DF,4BB33A0EDC26F788,000000008BFDDCDF,7E5302A471E5071C,6650AE2BDEACEE6C,30ADC136E1C8BF78,B462C4003BDCB9EA,4CB3F01EE24640FC,296BFF96B773FEFC,4C799854DB788F8B,D7108AECFD11DAAE,7737D210381DAA08,000000012DF76332,17D496B13865B89B,DFBF9AEB09D81868,372E450F50CF2B4E,406B3C6C5E233626,33FEC964D67ED9C8,C2B0B5FFA7A7788D,1D999934603BAB8A,67CEA06F666C1665,C6A5216971003750,00000001ABFBF76F,27DF189C36241ED6,920247225E7624CE,AC29F84E5D9C2860,E0B2EF56EBFB9260,2B238E401E0E3288,9C25FE80F75D78E2,6972846009AE96B9,8D9F308782DAE300,962F5B934600A47A,000000024CFE8DB8,688E5958A57C2BE5,F1BE363E37509266,15583CB530F38BDB,016F48300BA4DF05,B7FE0A1234AF9E9A,3C441DE497D75262,D531B3B323A291AD,E2104B09DDA29EBC,97AC69BD6DD24727,00000000A1B907CD,47115F6A0A87026E,9EE95514ADFE3357,C9936202FACF7E32,8BB92E6888918D2A,F79CD05B6F3EC36F,8B171DC00DF64616,3F457716552B1169,CDB05CDAF6AC72FE,47997D1108A5E074,00000000DEB19A94,3978AE812674D9AC,659505A27AB04D1B,B6BAC0D0DB9E6A30,FB280F7F4A05E31F,73839B7AFD0E6665,271A1D0D182C5E74,3A85F041ABFAC045,D4FEB73B8B8C506B,F1872674AD6CA305,0000000057A2D65B,C6CBB315EF221A1C,5A1339FBCF832EC0,BF656581E391678B,4C7B474365CDD14A,4F7E44A9721AEF21,0623BDF81227E36C,22FA40FC1B00A82C,B25391F81872693B,5DED8AFFCCBA689B,000000023A882328,2C6D037CEB09100F,512020479BE8DA3B,7DCA979E9CBAA567,0B3538903961D0C5,97D160C04D963ABD,31F0D42F4D64B381,11A0DA9969DDDD86,9B916731C18C8771,6E785C9EF0009E63,000000001F6B9364,50DDFAA4EBF816E1,87D435E636C1A01C,385D26B2B2BDC6FC,F2BF4B9657079D1A,E5C7DACB664A2E5D,159A37717511D589,DEEAFB2DD45F272B,699B066DF1A32D46,A8F96E97028085D8,00000001C972BD75,67B01397EF81E957,D28BE7AEEDAD835E,B2883E28315176BC,B696FECBDFC3FCC5,E2ADD187211341AE,11DB1F22EF29C761,F80B26B490100CE0,1CE4784489EBA44F,41DE779EA6B6E022,000000004D2F5F54,ABCB72568D5A933B,DB8D8C883DE6F012,8811A56695F7ED50,391852548972689C,5079BF4DF223D642,63764599C888B553,229E50E07CFFAF6F,92A8307069307DFA,92A2FC3FC6D46046,0000000100FE24A5,7CE87A4C343A2BBA,8A150BDF56048AC3,262EEB1D11D2174E,74EE6231EBC03F47,3EAB2BCF445817CE,5A0EAA74C99E5EF9,551428762A41D3CA,116E03DC044CD27C,50BA3CAA3DF0D0EC,0000000277466E78,10B9D97FF15D08BC,856E0C7579F7378F,AC640E374AE57381,31F48B93A5E95869,C670C9C75CAE131E,E810C4D964B59F31,315742F00398591A,977A681602543E49,AE8D36D8034A003D,00000000DE93C160,DE8CADA0AC54040E,7CFA25282F927F3E,4230583057264FA6,F7C4C55BE4E225F9,5787B7E34A951223,79AA9B565D3A5C19,9491D1A714CBF4F8,7D41F12DA62B2927,E7F8DDEE3135558E,00000002025C7BFC,688832A0F2866022,B5D187601611753B,EC3DAB186369AEFC,FD3E79BBAF1037A7,8B2E7C1BF20BA2F8,6F74DFF4E2150178,885D9FFDDB0B4F8B,A831097DC81BCFB9,D04A7C292F11CC84,0000000176267BB7,EE3C3B31A1966BA3,7FB0C445A868E97B,12F7F7BF76C5F3DF,5D669DC6FBAEBD3A,BDB877E72868F984,06F4D4E902F1B5B4,CBAE305C27CA68D1,56AA7F0ABEDDBDB2,15DD516244FA1F8E,00000000FFE9DD7F,D30089F3F14BD475,1FDBACA3D14AF12C,87E49D9BE8FE3DA4,F2D18D2BE8ACAE5D,CEE2F892F0F39C35,660B62F277199DA2,AE81200159676C32,E5A92FE000040612,1CB4291C5B724C93,00000000B2674427,C337D4D2CC2C27F3,78BFFE56FAE214F7,620B592C3AE1F495,4BE6E715B9DCD103,ED55DBF9CE399B22,789721382093B12F,20D69EAC3518D7EB,6B7B160D06230CB0,8054853AE1125193,0000000247A48C1F,2DE19F954DE0A042,9CC3D6605A3DEA27,BC58918B1E066D6B,BCC64E608A2538E9,536B0C9A7968EDA4,30D508E7753971A1,E083FE3F12B04392,EFF900FC85C97C9E,B0E424D534AA8442,0000000014816A9B,5BE15CB938EA9CF7,A2F29EF7C77169E9,82176C8707B639FB,482E398ED9FC3760,16BAA51C94310ECB,CF751C3CF4CE4113,399F76048C6022C9,7F850BE9CAA0A94C,7100D4ECB6BF901F,00000001ED4B624A,3A49D27C96812F48,C144C195FF18E70E,EECDF349E40A7288,FAE48A39FB94ACE4,7293388104584BCE,84FADD0BA70B2516,881DF9DC7024C3A0,0478ABDE0458B72C,81041C483332F322,0000000219FE091B,36E26EE23759D76D,B706F7EE46A88796,0E23D2132BBE5399,286BB19E6A502A42,A1C08AF7677E8096,B59F507E3AFEA932,8BEAF1103EAB281D,A3E14A533C1EC23A,C68410F6FA7712BF,000000015FF091CC,F55820A14555F60C,78FA1A781B82DE35,D41C8860AE33C74E,F8F253F2256B47C8,6E278BE437DE0DFA,AB96C9C697986BAA,155BC6A24542F2FA,53EAEB57DDB34BCD,77C7A31C1386DACB,00000000B8C11FD0,8CD1C441B80F0BD4,8345840B813DA230,1DF3205FB189F358,6A5743999D20C343,0E63D4364FDB5A66,C0E4D302E3A6570C,63413C50694FEC5C,0FFAA5F89ECCCA3E,EE75D08BEA5A52EB,00000000ED9EB010,B99692AB862875EE,C08D16C9B621B6DF,AD05A35C66CD908E,D573A7FE6C4752BC,135DBF960F8A02F2,77CDFA13239F4D1F,CD8611177AB34631,939EDED930E898CC,A03AA524606D749C,00000000D9D79098,86D711FC4D812D4A,0D220C3E2412A2C7,8FCECDFA6C225A66,EFCCD43D4520EAAD,6998DADE33F53A9D,D92D4D77C6AEEC0E,CC10FBA4803F6D00,E267E137D74BF021,C7F05DB5B4627E25,0000000171FF9D28,111E7DADFA0A377E,103D32C1A76C5F25,52EDFC4311870FD3,983732298646AF8C,92169DFE77A608B9,EC76C0E7242104B6,B77EEBB45D7B12AE,28FDA5DC619917B7,953AE4DD03681671,0000000212287019,DD8D8A73FA4EBF90,CC80E1CA9FA41FCE,9EBAF6C2042CCCD6,79CFD263C7FB9720,F42288D991BF15CC,E015E641FF717A32,3377FDD4BA94372F,2983F9416D0661BA,19285ADE8FAC4902,000000024B3ABAF1,D2788FA09AF76395,D811A7E9AD74A3C5,CC5F18B2E7848EA7,7C9B9F55EC16D776,D4683C38C8F150B4,43399CE47F06A77E,2845263704BEF5AA,02D225265193ADBE,ABF5370094EB9F19,00000000F936806E,D1EA659235DAE5E0,69617ABD93B66DF5,0066005757CD5B59,01E608A6E02C2ADF,9B6962701994A014,8B96E50AC8246F73,5C1D20BF0707957B,5805E97B94369169,F7B4353491D2A034,00000000CD3F8BB0,45428FB71CB075CB,CEF5A82D8F5D18A5,A04B9B4FCD27EAA1,13FC19E49CDEFD3C,20B5575A0E19D89C,EDB3FCEACCE08AAB,3B266F7F2E3D05EA,BBD309CB5BDFB8AA,E4515E263D12DCAE,00000002181B6BF4,BE3326EC8C352F0D,D4652D9C0386ADDA,58A6BFE7328C431F,937E457DD870253D,DD05F7835F935CAA,BCE7BA83CB32B9F8,4CCFB1061D1739D3,95451C86B229C885,75EBBD8292EC5067,000000027B7246A0,AFAAEFD923FD9498,56F910C0CC4E7B98,E4D2CC0A7E9FD3B5,E7387620259F5D05,4689B2DA51D36F67,66AD6B465EE7DA5B,A24E62928B36A1ED,C22843FCC2A0BC07,E6D9A026D0118629,000000025C4AAF3E,2435997583CDFE5C,2E0643E90E5BEEA0,BEC315662DF83821,8C76B33AFCD147CC,BF67CC9CFBBFA850,EB82FDF53AB8A576,E8576C5E6388A2C7,0474E4307FB8BB1A,B8EB37C18AE02DF1,000000015FAED4F4,E4E6FF208C67DDD5,E7148F4B17A63CD3,2C32356F6180234F,D46B47D2F9A15FCC,99AC348D59FC558C,F57274E35DB5F7A6,98D552089AAEFADF,65B4996ABCD417AB,ADA2416E7D69B850,00000001AAC177B8,7E8B43D0F454AF50,8A4C0DBDAD28B383,BF586BAE003F3347,D234C7F542DD82E7,EB6890662A05F0DD,FF453668190F9B6B,08CBD0D60C5B5B38,543DF06F9C1C7B48,985C32FA6DD1103C,00000000D6B2F984,25C88A60FA8409C5,AA80585E36272CED,E4D88C04FBB5D0BD,44B629331B24BCA9,B1281DBFC411A83E,E3C0AD02D3D0939E,30C11C6466AA18F2,F01C65A73E2F2F06,E7CF9D1A52D3035D,0000000247624AB9,72A939A0876A517B,E9B217364F79C375,9946C83A06DD9AF5,C249A71F1547AF03,70DBA36189695E21,FA1932B344A630CB,9987A305117FA84D,A8B84F34478F32F7,B3ED98360E90881D,0000000098948AEC,41234AFD2FD1D139,70488C56D308B309,4782329F96C1FA7C,16B6EA6AB74D6FBC,BDC77A453685EE55,8A3109A8B1B9F21B,617553FB7B4BBDC0,79BE438E737925D6,33C049AB6C1AD38B,000000023F9BDEC3,D69AE08E9DDFE79F,C60BE8FD199A6BE0,19F7A8FA3050DB2E,7EFBEEB14BE68537,3D3895A4F91D7A51,C84BC34A473745D2,2E627D3D5971714D,8EA6F573BD0D3BEB,9FC9936A9101995C,000000020372FD3C,08B6A632B5BB46B1,357CD28B85377F01,79A95F425806B3E3,9331A0E19D4D90C6,1D74E23359DCD3DD,F9D9A739B7458586,2A2E1A16282664D7,7B73D8CF7A7415E7,5EF6A0A71B75B65E,000000022DC3224A,A09F8DEF836E649B,7DD595726D9511CF,CEC1C118CE215D63,912A7C76B8F9F750,AEFCD2E487F268A5,B29135A3A5E111CC,CEC0D27230C2A529,00A280364B3D150D,7DF31924C97F784F,000000012B8E910E,3B5113214A438CE6,0D7AA90B5EE78F97,ADDE5D474D2F9C3A,FE573FC45D5CA19C,92845A3A5EA1ED12,901B1DEAA4708371,0CAA8C807559556E,3C05A0FE5A43D957,B0A60D27A74F5F80,00000000C947DFA5,13330EE77FE477D8,23312FEB0E35FA83,C9A9DC3428299E9D,1C9029A95E3388A5,859A0D2D10B15559,827CD23E3A2BB02F,FDF5DDBFDCADA869,33A5A3A9E35F3B50,0E5509BFC80CB921,000000020403AD3F,D22A82D248E18C3B,833E276DD82F5D82,37FDD0E671D2A641,65D36817DE1F300E,D26A64D569AC9B1A,765DCCB171E216BD,24F36E87043F3543,6A1FD1AE583566E1,C980A503CD65F581,00000000BDB94D62,E17A7491D602E404,26B0A5772E0E3465,5CBF46837A1811C5,465BB1D8D6069EEF,20AC94C727F060F3,379B59B82141C521,04541AFCB7087550,A562B30C2D7D5116,105E356CA2B19F8C,000000018F55141F,571E72FBAA49B4F7,8CF92F641BADC1BE,C9B7FB8855504A9A,5126D271A9D422BA,5246BB866AE6F44C,20B07F7E1D680F25,6988F498C4AE0361,87243DFE7A660E74,9CA0A572BE729EDA,0000000119E6CED1,2C487F593C2925C4,81274385D98018BE,2E0A291B3CD09CC5,A0893E3548413D0E,8C10F7D9A87F6C3F,5F8BF91A76A8F06B,800D91FA5D77A4A9,6EF6386FC144E3CB,A07D6700679F775A,000000003D61BBEF,A78215DE4B86232D,1CA22C285B0FF97D,2E617509EA9C9C74,10D08D28E95A36D5,DF7506A7DB937059,8F1593EDA86AD6E1,5E1D6B800E3ABBE3,02538A703A5BB412,3D169B025C8F148B,00000002722AAC65,3E062BB82C185485,3C953EEB777F5487,9F39E4537D700B16,88FD94C11E3ED09C,9AA6A6E1CBFE7910,F3CDD7B8B3DB6B59,39052477DD3187D7,2F14803857140BB7,6432E7CBFE5F8A62,00000001FDE1AC7A,35D64E97359C2A79,4E4067520F13F773,F0504718DB8C3ECD,63665FC9AE31DE70,412F3B935B9E8314,8FA97127394CF2E2,2A3758390885A13F,76716A28DFCBC4FB,C25B25FE6C1F01AA,00000001A9AD0702,9B6FAEFB5227CD3D,5CC6417289755FF7,1D8A1D9DAC942554,75B815B72993B2E2,57F96EC2B3F571B4,A770C891145C2F54,4110A875B6D390EE,E7D779ACDEDA69DD,CE016A3AFACE016A,000000012623FF7F,69012CFC163DC291,BA5A834251764177,47C1E1C2FED158A2,375BEE75113BD313,002797737663665E,BE2E7C1176C06195,35E2475900B9340B,141A66B9A61D8ED5,E1F3486088244699,00000000DA541D29,8B6DD5BB1F25405C,9FF459395648A5CE,FB1DA4FC84800D00,17E895FD08A9C7BC,B5B85929A068D10B,DDFBADDFBED0C142,FA1913799B703799,681E4BB9F298633F,1D21D61B64460047,000000013FB98A5C,33B6EF8FF8AB899B,E7F77D48669FFBBB,F939EAF6AF65CBA1,8B04B7AF59A6466B,B920B7DF129392E3,FB4CFB9FE4C4E4CF,E7759139151C0503,F234B5711673C700,6743909AEAD2D0FB,00000000C47CD208,7F3150FC5CA0D970,B3C74F9F08BDAF8F,FCC8DE48EA374EF0,8ABFF6DFE0CDDDEF,2EAF31046D4810B1,DAA01805A46226B4,E7DC492AAA2B09EB,DC7834EFD7DD59E5,D52621CAEF8C4B46,00000001E65593E4,3996237933C4C849,F781C8EA430EAED2,31BD49602BFE7852,BFB70A5A1F41A7EF,C6330E17B17B6269,5FA6DD62283D2AC5,B8BABDDD5803FD13,0AB2E45485261D4A,CBC2739AEB985B76,00000001A50E6DC2,BD36A85E83B25495,D45D1ADC47BD230B,D1E8C54BA09A3E1F,AFF6DC3C39EB2E79,E041F71C45EE0A96,BBEFFE1292C34BEC,58AC2C75B74D9839,559D28B0C1A01CBF,0AA71B709C5A8E7B,00000000EC8CD963,89E039843A02396D,0060D92CB40A900D,E6777AD6ED89AE1D,CBAD0DE579C8F193,822CD572A6D8C0C0,5CE571EF30A385BD,0E442D1067CF09EF,89148C826528399B,DFDF3D470AA98E74,000000017477FFB5,7239B13B051D43C3,1F8FDB3F2EBD05E8,E1C77C5401220C93,97B535F2CFFA370A,2DF5553625074166,11789DCFBDB19730,FADAA088BF176D3D,3F92723B92EDF7A6,049FD8A0D30FA38F,000000023D9F061D,0320DE3AA291D038,91EA086C93BEE06B,4A2A4DF91644739E,60D7C3DC99EABCF1,CB25E83DF9981A56,49D2076A66E751ED,2F99C4F1F4E9DA8B,01696327C3AD0CAB,CCF8F76B8AD26FAD,0000000278638638,706BACBF9FD5E243,616DF50D7BE75036,1DB78BECA98E845C,CC7FD98DA3EB5242,6A8FDBCCD5CDCC59,510121C7C34B0136,231ADE05ECBFCF71,C05EDF7372B50A2D,118FBFF9379771E5,0000000090CDDB12,85D9C2450E235B45,01FDE6275C1D0134,F1037D9B2951A02E,AF6A82A381E4C2ED,B024C2C554D9BEA2,33DB202FCB151774,199FF00383BD7659,4AC5C2AF8DC258E9,1D0DEFC2065BF91F,000000024288A78E,20A2240E99EA8B1E,D6FC9F4028AC1721,A296C8C5F093F947,498B66444BBB6614,02194686FE6C7F08,776CB956BAD249B5,B7C6C4D9D91C10B1,8F461863ECAA6B5E,6A5DF8A1FAFAA16E,000000003971D43C,414E6FF1F3DFB666,F195736DBCCE3E3A,E514B685498A3D34,9A1E31EAD7CD8FA4,B5956B4B4D704803,B79F6A5286C486D2,9D9FC10464D54547,BE13F2BBEE9F7771,48AC9FEE1B435102,0000000049749454,DFA685C7967B3DED,7F8EAB9DD155641D,116A803F80DE3A55,C2DFEACB36033D62,6C4A74DB3C38B098,3F7CB8B9A467DB6C,52998151E7D85FDF,FA8334AD5C1BE151,FE8AE24B10DC242A,000000009EA6895B,9612771488C7CA49,6883476C83DC41B4,0931233DB6B1C90E,72DC6745F3B1DB89,5C0FEF720B4F7813,5AAA61380E329918,C53546F50FE71387,FA1C2AD057E83EC8,99DC8DD15A7EF06F,000000007EB84481,3A78B663E0009860,13175AC6038F056E,1D3B858B01DE41D0,D229F3D7F4A6D4C0,D07CC5FBC1535F3E,39802ECA9D158329,A7834F0F237D22D2,686FB6CB8FA183D3,71711F80E0288188,00000001831D9408,FB0A39DBE77C92D2,2F008883F7D3A6BA,74462C1EC9F67426,1B416B4F9631A8C4,C4C2FC77103B5F9B,9389E6D894F5FAFD,2042614D172552F1,B0127B54969B376C,175128885A7EBD16,000000006829A71B,1D1DF51E86C24DDD,8EF3D56655B897AA,0265E742C3A77AAD,D8585B8FB9260B0A,22017B20B5B14E20,3BC5AA5C909C3BD3,93243BF7943626E3,DEE92AD1DC395462,42BC2C2A88F3F91A,000000025BD7E1B3,E59ADA5255917589,87A186192F7A76ED,3108869A9DBF094E,8CA19ACA2A68104D,5B4B1AB311BF7F1F,00A0CB4C9D4E85FC,62246B112211CDF4,BBA0588BDB5739AD,563E75C1B6C363CF,00000000569779A2,35FCE08D625630D1,507B77EBB381A730,7590AA5B02571B5C,4A8AF82C1F72B5B3,C571E72B9AE5562C,A9681783B70084B1,B15B6E30D6581477,679F4DA68B6CC4A8,2F46F97B1B667D30,00000001E9C4AF4D,01F055A4B3503AF9,BA68EBB78737B0F2,E3580A89B3EA82EB,2E6AF49E30458FB4,E25C806F28410118,54B4AE7E9021D255,016546D1B124A5ED,2A5DDB02B7CD2278,D514B25D2192557E,00000002750F5968,3D7B7844DE2E7D02,D377FEEDF3218FBB,2AFE0EB076CA57B7,094BD10A996F141C,FD9B5559907B9D99,352F3C3088E3A902,BC65D069E4AC1F2E,1CEF4A0D56FDF949,B6302BA5ABA5E876,00000000CDE87676,8C044F8E5498CD32,BBB20B7AC418861E,74FAC9EE5394469A,B4F67C4BB448742A,9C71179809BF1179,36D581EA526DD2AD,D2AC36369485F062,6BE69B5D012671D8,F601B9B1D2657875,000000011B8D565F,6829FCFA064BB04C,CAFD7476E1474CD5,A8A9B3B2A25F9127,2E0CE50544B02365,7F5D56EC32C03ACD,2BC494B9A2EAF447,3248F2967BE06452,EB9532ED5EB5BFB3,639682CAE8F85217,00000000E0742006,F379E5DDB0006F3F,EFBECCD271BE7013,BBB2115DFFC96258,DB16622FF585B1B8,7B99307542134F25,18A4A69AA2451671,D2489DA75B50C14C,9E9D2960FEE67925,9E0EF012A6205A1C,00000000C41C8EAB,D09D60C418ABB5B4,67589B3CF7A4E492,568335A0D5EB2047,42D6EBEAD4E2AF14,55FDEEE21BAAAB0E,0A5C659A24566385,60E2A67E577C3E7C,B0F6C5824A9B5195,FF4F66DEE7E41A34,00000000B7890FCE,DA5D54F15AADFC68,407508944F42AED6,C5F36C4F41019F27,80599BFB00281E18,E960883A5CC5AE6C,5E3CE281C8E918C9,A8B55DC885D245B6,5202D0F7738C815B,043ED206FA6FE105,00000002410145E1,CB88706F094C8B75,8D8B3FA22723CA05,6CF5C2E9FFD547D6,754D16C0EE1C84C2,DB9BD65062FBC871,8CA3524DE2A73E74,B6F71B33E1126E3E,17F56AA9606713F9,7EC3F905B8C40223,00000000FFC426F4,A768B440084813E6,CC19E02932C77F30,D3A4B71833965E69,FED37EBC5ADBE70C,A9A52C79ED860D73,6B6267D1951F9626,7B7C7B3472DE7969,86D75E69C15B9BF0,5B3E9C5786D66E79,000000016519E54D,478D0E04F522E5A8,F5CB7B81127B58EB,A9F238332A570D92,40A30B424703F1C4,0CF3412B4DD4B4C4,DF5B962274C75CFA,A7607D0D2DFD59BB,1711FB67226385F3,F25A91D723E635F8,00000001EC67E746,DE83304987BEEB89,27943E30152B0011,F972D6240EB52365,4F217346E20FE326,73E50E839458B98A,95B88B284C7EA614,7BB8C5D60152E232,06A905D9981B4D0B,E6B9DC0501F9A9FA,00000002148192BB,2841A46FAC0A793A,8DF927C239CB0262,20D12655CF3A1E52,0A2F148FF2955037,F1F822AFF5437A27,7363A490F4B23C42,F09CE426FE9D5987,4051BA6FB38F1A9A,DFB33AF32A615EE8,0000000074EC051B,E24F598217F7B4A7,964C0D16B043F037,9BEE8F45FC333445,3C560E66D4F71DD2,50BED5D84056575B,1ABC72BAD8214407,71B2AC353B401F65,6058151B56FA9A67,5F207F98FBABD855,00000000D86A3DB5,89B734F9D2B6FD8A,E8E31EE932B32529,5422C77DE3F7F78C,5E17B43E2AA02C1A,79B5EEEDD2D28447,964B33E1B87130C1,78845494F7177E07,CF96F232A056C608,F6CBCB9ACF939DCD,000000013B5C489C,D1E684471164A76C,B2B546EE82C34B2D,1BEA38AFB06A9528,B52535D8888BB6F0,E2DD7C9041E24801,B87E6D4BD587EE73,A294D19871D8E81A,10D79B62A004876E,276D21E30514305D,000000001D56C3B8,9CA84EA17FC55AF8,9C5769F140C00A11,6B63D9D3736AC230,CCBFE8819AE9FCE9,3F43301798252675,4617125787B7B612,F65D93D85D6D92B3,79A6D7B0EC2A134A,30A925F7BA4EB518,000000020F9B6514,BB8BC0EABD826DB1,506CEEC404096D94,89E788E2CFD039A6,FE77571F963ED7DD,FC8C108CE2D64E36,B95A4229B95A5493,5559C9C4CFC9EFDB,512CC7F1275BEC85,5295A1231FB3C720,000000002418A89B,74186F9528AD8945,5EAA814D0AC68D1A,367F550B80531800,4A9A27AB2661B882,AF5DF149FB550E3F,BAF886B111065326,15A3EAC357366F03,F5FC3D4803728812,D471A234DD3BA160,000000021CEEB13E,54155DD3AB81A1AC,18A00FA37D0D4227,13E0AC6D080DEC7E,B963889A58CD347F,4ED6A06FE3CFD16C,3940988E077DD68A,68CFCFA0B29A7DA8,16B65071444A77D0,6D5A84B08DAFD20A,000000005ABDCB89,8AA8258FB2FD30AF,F7B01C7707A793D8,30718F58E7BEC70E,DAC3AFF97471636B,9B7C0D5CA181696D,6DE41967EE12AB7E,BC17FCDC2FD6EBC7,52EB1E11F3225CD7,7AFFAD306D08077B,000000024DCD39A2,FB301BF55F6D3187,DE54F3E61C603879,C0FA8E1AEF114958,7B446CD7FA8ED7A7,BD5080F97C5C3F40,5F6AC17791E54111,03BC742BB92D9AD3,C983DE6FBA5A905B,900E1031E41F62C5,0000000039EAC35C,98BFE5367510BD2A,FC4773C19C8D1941,641C548084E5E38B,53EDFDF73049D64E,198C35363C6C094B,204376C12BB5AE47,087561A804164542,4E71B3603D6C9052,97CE91957D079828,00000001710F6CAF,6A0D51A508C1B22F,A3033C53F9C34247,F3CDFF9C8C0A8BCB,6FF0F154016AC85E,5B201BF126B833FD,84E5A29E046BFA6B,6DCE6EC1CD92EDEC,0E3DC93567B4FA6F,BD48C7E6E618F61C,0000000159B0C693,67CDC9966C9A67D4,A718EEA2E6D61E13,F6EBFF945BF99772,3EBF9B6EFBA348C6,D2DCDDC337728333,202D6B5F04CCBA83,870E32B57F4AB789,9BAAB06FB43EAC57,6FB5E41A391B1AE6,00000001D4220407,21E1E6405C9FDD09,6E41C39528177F3E,A43DD6BDCE3F6668,F3EFE229AAC63269,852AB70D60D859CC,64D7EB832928D06E,4E5F3C95D487E2C4,22CB3AB56C394E97,37039C4F3FBAD6A4,000000025F9AE735,4CF6B8CDE5F163BC,AB5F8C0F6E58318B,19E9CF821B0F80FC,C204FE5D68F679D8,AD1459D892DA27B3,402EABB07F300679,E872F3907B569A4B,83745556FA6752B5,46B1581B2AEB9E9C,00000000A61252F5,64E14A4B16608742,61F9E63634FE1AEE,C0B4312DC95B0125,9A08580EF85DBF2D,BF5FC6CE0C6EA279,5618008C82A307D9,B414C91D3027F836,53FA3B38B4819DCB,D062FCBABAD2B6B8,0000000277AE7DAB,9B1D7F4A8B1405AC,7BC3A350E41B18B6,BEC1E89C1B924870,7FCF37F9F997E42C,8A7CF02584B3F3C8,141B5D124B86941C,991B487F787B551A,67AC81EFD1B91CBB,B88B5CE7A39E4532,0000000266AA0D6D,79A4E5EDC28DE415,E09BD9A5EFD7597F,6C573CFC224FEC42,BA95D61A6374CD63,EC5763811F6A2DA7,364B724081115D13,028AD23943D7BC9A,5D631BB3E831230E,4E85DA7DE89BD78C,0000000189A6356B,4DD18AC44B6F923D,2359574B09A837B6,5FC3788A34849F93,CA1301661707F4A2,D5D656623573A6BB,2D43982DAFFCF5EA,E7E31125D6C07D62,C1D93A4780483059,4D984EC67EFBCAA7,000000010599CECC,FF1FE1919460F56C,FC93079198D26313,93730B81288C1A6B,228C7D05F44478CB,C69333056E334374,3E1BEDB22029D8DF,60FFBE80B48897C1,37C2394482761D22,2270956A0AE6DCDB,000000023B84332E,06D8E7A99DADF29E,1DCE9B4E1F0A8EF7,59D6713F2AD78128,707775708B686C55,1ACDADCE493BCC71,1661DD9B9B95738A,DAD8C24AD4EF4BF2,EEF066955AD96F03,28A9AF8B47DA48C4,00000000AB862F3C,0F296B705FF4195D,8950A30A35BA8C69,93DD5AC9975E5E02,7EB9EAF62F4D0100,F08FD6FCA32F0575,1846E18E4A444598,7ED62EFC0EE94BB3,FFFE99166B6FA8BB,8971CC52ED494BA1,00000001FC723629,339F5F7E661F13CD,3B52A8E9E2DB7723,2C9DEF1FB93BA0D4,78EFB87EF5B5714D,30321B50A7C2728C,88176C6E3EA51452,D58D273FB3481102,75912AD403316873,A87872069209F4ED,0000000278F62732,AA83B42ACC9529CD,0A553DC6653629FD,BA5F224E60350C72,022ABA80448F2D19,66A4723E5E23139D,D199CA269DE44159,A3E9A8C09CFDB9A6,0320542AF98DCB58,1F6056C0DDD6A24C,0000000040FBB08F,7B879B0F859277CD,790901A2E049C471,3117D60BBC3DBEBC,2157656BA8290CFC,4F5D4FD648A9C5BF,73936F9EA93C3638,A9265EBCB70F97FB,EBD7E582FE9062E5,8FBEFC34C17AFE8E,0000000160E2FC72,AB45B00B43C107FE,F8994075D30BF166,3B522DE404678802,9A26F53E087EC1B1,AE85C361EDD02D1A,43E360D191778A3A,A08469CE8E5C590A,28C1E343725415E9,94D8EC6DBF53BEFA,000000022753AC28,0CF11B811546D2A9,263D709983818B76,40ABCA0D0DA71BE0,9CA882D7EA9591E7,F1FAAE5A2B4C93E6,17C4836C150B98A6,74B8159243116532,F7F0F8221D68A52C,C54E4F62EA7AF839,00000001BE63D589,9BAA4ADB92560567,55030392041CE737,347F87F5CD75F9C4,582C1192E4F22F21,4888A0CA4DB2B9A2,94CC10719AF8E273,C039AE7E5D1B65BB,1B6EFE7A8B28D49C,4BBBD18E80E2E396,000000027317DFF5,A2646C79021ECF49,3BE3268C89367CC9,A00DC0A87BCB1C1F,ADEA271C50CEE6CC,0AFED7E600AA438F,CA51A7AA8430F6AA,4A136AF405BE7928,3F4F40056B4AE07D,201D891DE5BFFD09,0000000279310EE3,6DF05BDB4CA2E424,BD1BAA40A85A1C59,CFD30C0D11B7B8B8,5DA76089638B1C8E,4908BA3F2191F4CE,B5DDD249E91C73B2,F095800B9986E21B,0DE8B239F653E497,5776F5213FCE557E,00000001633CBF65,67F4CFDEF9E1D23B,F47FF07189133F9F,21E58B542797B343,D257E87FD8255A44,C89FA330A18F5081,C55C12F5E5F8E4B4,6E368346C857836A,97E10A9821567E04,622B66DB3BFEDF20,00000001014525ED,AEEA2BA6C42EA7DB,1C3D2C8B2183F525,8C8D44CA673F56AB,A685D585A8D3570A,D7257C9C277FFC04,4F1E8506F097D93C,0EA2A0A8BCA3A924,3E51197980BE9270,06DCE1B494849594,000000015FDC51F2,0E7503FED10DA98C,60C613A626A0C6DD,25336CDAB28A0C6D,902D0C8CC3A5C9EB,4E0F97652DB6E07B,45E6024EDB509595,A2880DE157119029,C866BB826365BD00,EC48217D6AFC7ACC,00000002173C7C93,2C937B70FCCE331D,A8C0A45382981509,39650CE75EB6A297,B81C766580F73748,74C2F8C6805573FF,C469151FE887C1A7,56F26BE116C00A99,710CD1AA007D59B6,8894667C90705B5F,00000000423E5FBF,0B8941FD575A5C73,B8D3A9BA8C87B5CE,5693FE2735EE3BD6,E067130B36F0EF6E,BB7172D3A8A6FE3F,DFA99F77AB48EE2C,016A4BC4469E1F78,0F68293CE6277736,B5DD12F2620724C1,00000001326C9DEF,3532F9A8208FBC14,4025DE5BE3F54D06,A68323416F1FD188,65E57B8B843E0D7F,D4E3DF27FB5ECA08,886321225D4034CB,9B23C70E58E4FCC0,F5CE0E71CF3F0009,51FC36F81B313E25,00000000E2EF4BA8,0385AD3104CB5065,44178781D50B19D9,0C24BF447BDCF3B5,2F88CA0DD6FA6D46,6E07486163E36AA7,9050A008C5DC83DA,FFB0FBDD697EEFDE,F8BBAB02BCB75655,DFFFAD2C3BDD7449,00000002183CD65F,24DAF65D85668096,645E05E714CA7B1E,1915A87BF8306DF4,7C946D01A3D6A4DF,32126B8C4C222C82,F50CDB783F8F2C67,27F5AD681CA766AF,8440CEA438966188,0ED5586AD747A73E,000000020B4C9680,C61624952207B6BC,13ADB7D4D04DBBE8,8669AA2C0BC60747,16339A068DEBD3F6,DC2FFCFED98396B0,6DAADA1B0539FAE9,1BE3287ACE75A6FA,DE5D8B14411DA911,3DFDB35098CAF6D8,0000000220AC4E01,2E4B496ED7839C44,4520463E9AA45744,982AD67FD0D3DC14,F8D23331895F61D0,493FD561264735CA,E9A2B873A82EA110,DBA2ADF70E04655C,D7A78FD28B38E4F0,33F19A8670E59737,000000007107CA87,5587BF7B8ACC5193,2D6C1A4E3B4567A3,392CE9A7C4B480A0,F4529857BDDFA196,BAF4187FF0C497A5,1E6AB4489CF71E89,F10D4AF0BF354EFD,7083936955BB54C8,2391BFF2585ED1CB,00000000D9A919CF,562E08BD3D85480F,246EF47E35EC08F5,C3F734040224CF07,7579C3045D9726A9,3665D0EE471F5068,1DEF43EDB6CDDBEF,466926331D8E1214,86162065B69FB7EC,AE2894F1412E050A,0000000139A3099A,0714FF97458F33A4,FA3152D925D214D2,DF21D44EA6A73A62,38E70783720DA85D,993A4A0D42782553,05938360D4FF2BE9,530023D3D9978725,C31E07A67CA1C069,EAC7FC8E927E056B,000000014CEE1D23,C6F61A53B79D787C,D1A5C16653DD45B0,F98B24C1954F3028,F016A6036BF0439E,90FE7BD1AEFDE425,D7A17F7FF7DDF7B4,C4428D4355ECD85D,FE9722E1B0D1446D,BFFB5058CBE95C5E,00000002396F82F7,7C67AB30685620A7,84E0518E1166E716,DA6575F426C61387,4F1EC01EB32512AA,18464F3C3C840A06,F07F244A802E944B,452D77248D7B9C54,53657E590BAC879C,2EBF3A8CAD43F6DA,0000000088D58215,2847F6F937CC6B88,69AEC135FE98C610,AC282D41908A43DE,B1803169D377F194,6FA9DDBD2C6FA55C,6E8FD535E3D010F9,EBD339E64A103774,AB1F47D3F66C6D8B,2932B292681C0795,0000000099C12204,9D138DA29876C415,785971EA37B3F9E7,99CF94E1021E0D31,814DCDD601B864E2,CE1CE800EC583CFF,E3E8123295B58D37,D4EB51D44079CC1C,71C19D2CF76C2E78,869A48ABF3A859FC,0000000240A0F8F8,A14E319EEBEF1686,1B384E3E43A0CC02,680A3558C1C9D78C,DEEAFFA05BD50A5E,451472879A532D4E,F618A8D3EBE2BE60,82C5E675D2B15D4C,47F5092E9286A838,19C016FC96E2EC40,00000001F50AB826,0700125DCC2C1975,3AB1B7430E892816,435B704099C8A6E1,299A3B07283553E2,01553895565879C6,BDE4430B9052C445,8BBCBA22C93DD5F4,83B4AA41C520EE26,7E5169C8B0B9BC8F,0000000081CCD0C6,4E3E5E6963A1C07B,022FD00D67A37EEC,12C2EE83B6F6406B,5EEA502A73340B71,4FB723D5F98849F4,3814DBAB464CD9C9,2BA21909B6B7FAE8,73268EC3F03657F1,4DDE8074DAE85BFF,00000001CB8A648A,A0B974259BD9D478,45651D9BE007EE25,3BBD0CA3B76CD696,78A8174B3E98450B,D6EC39336A3EC5CE,8FACBF653AC3F760,30FB49D2B48F15EC,67B89D6E8FAED6E3,1D561431F0543B05,00000000E567EBCF,644CDB2D2AA424EB,8130F4510A9CBA13,128DCB969E835455,8454F6B495DA5442,E55B22D8CA203FAB,231BB1BACC446F7B,614636A0499D2195,E9056C9A18C13BD9,DD8A2F666053F1F7,0000000215291DE6,AFFAAA029AA74A95,13D4D2683217C1F0,8C2373FF0BA9008E,D652ED68CC72960E,1E9D2BF6C4A56F89,3B5D658C2EA89E1A,DF813BBCEE045897,E9AE912F486BDB85,B5052DADB5C27A0E,000000013B0E639E,944B06E34AFA642F,2B4F394112B92B0D,29561FDE1E54A260,E649969751416E43,C92CBD60ED457D7F,59515EB98C34A22B,180925B6970BEB98,029D763EF242799B,4852A597231331FB,000000020ACC5303,49A2C9E557F28DE9,86C8BA8588136EC8,FAF3733EAE0E5E2F,780188A36D48100E,9036220079A8AF6B,BF9BFE90768B90EA,80B36139CB586C18,1EF0ABA11ABD3E8C,7D4D3D18796565AB,00000000F130070C,D153E860A0803AD1,AFAAA048A123B5A4,FE05F619581147C8,167860D7507A1E77,7EF65761351B488A,1E837F0C8CAD98A8,F793EC26DB66B5C3,F055556BE0930F68,1947D64CA0F184CF,00000001B75EB44C,2EDE93253E166EDE,B58333CC0EF6D542,197BBF397795BB8A,53AD320DB6913FBF,44E2E26A0E328CBC,2D6E6BD5408F2928,6A52B8AFA8D11FB4,791BD41D63573DFC,3F293D0FA8B2EF2A,00000000AE305729,84DC639C87D16C9E,E6638D0D3750267B,A5C6D3D6E96F1094,7FC2E424A34C8BA8,5711455B9E2EEF86,318D63F86807D313,9D684ED0018A11A2,F77FDEA80636B084,EA4B2AB240306ABF,00000001D4F7F8F5,F837DF6E62FC2F06,59CD6A170C3E208F,26409C8D6DD308DF,1A7EA49587E7D9F8,A5B8B28A4FC8B92F,FDB8294423FDE288,07127968A42F6E36,63A00A0A187D07FD,1AF2E55279E7BA02,0000000276C10A51,4852C6E78A4071DC,207C9EC61F834001,B4448E36141D7899,81BBBE94FDF57481,2FDE06E1F31DA7DD,E8D773E455E3904A,BCEBC929F93C8884,FAB27FCF07DA88FE,78574BB9E4618CAA,00000001E231F565,A8AABC79A95BC8A4,5A5B2B1D7C9A581D,E3E42E6BFCBC1C6D,5C94D2B06833C2AC,9734D1D8DC788046,75E8DC2A77E627C8,D382F48EBCBD5AD5,356461FF2B6EDF8B,35B34A20D0CA13CD,00000000A30EEA6E,FA0C6CADFFAB8F58,615916BA3A2EDDAF,33F3DE27DA2B2D28,B94BC7412A4B0AD9,1CCEA315BEF2FFCB,5CEE8A6FBEA89B17,6771FC77186073CA,0FF2FE63DAC7E848,71EAEA9103F1CE7B,000000001E0B8196,999DFA38360D70F6,122C9FD7B6307802,674F67142CD76EC8,C28396E1FF45E9FA,BE62B50DDDE69AA8,E3CFC68F69196240,4B828A1DAFAD83F0,C42EC0A8D19F5CBA,0FFEFC1707E62A7F,000000015BDE5BB8,B0969953CCDEE419,FDAF7A0A43558BFF,ABB516D4368AA6F5,8C3CE4CEA2980381,B9126D5A7A99EC7C,AA9AB73EAB4F2A12,1DFD60222508A300,954269F30E6553E3,25411E6CE9F50273,0000000260C6A63C,BA3EEE629812387B,D066388B87F32CE1,EBA9E00397CFC7A1,7843D57B0517198D,3E774AA3D21F86F4,DF5DC3B98A37FA2B,CD0C6E45FE0E0B68,D3223C1C3617C270,10D368BD2D567D60,00000000A71696AD,D6A2D0625D25463E,4BA4F812AA22D923,23F45A04D0D97276,C24CC05A9552423C,21FBC5F7862CC7B5,7DA9BA8181F89963,5D0EBB52B12E3559,9F065FE54B5FC41B,54699C221CE56606,00000001A5EF46DE,2F66777B5FAD5A5B,7CB4D256A7CD3CB9,8779EE0A6986B732,40AB55F0C1DF32AA,CAD03EB2A8D964C3,D419D0FCD8BF4382,1590FF1F2498EBAF,EEC05008D6A0AD3B,8252F6AA87DB1A1B,00000001FF3A175D,FC2E7B52650B30BF,75D54483CA19FC82,C9FA65588676AC81,E5815431E64524A2,D62697F8AE7F46DA,D1C593D6B8E87AE6,CB76CEAC40A2CA94,9E289C25209B1EF6,EE0CC0D2545D510E,000000012A832A3C,2E2732711E297C84,71078530FA84DB5D,91D89E3CA53C711E,A8221757BDD71444,6D7D15EB77684AA6,4DE168CFDCBDF7D9,8576E3CA08C5C683,186822C26F6D6372,0F2FD5FE934D37E0,00000001827A3589,03A8C106FD0B008C,C0B5434C4E1FAA20,361D3BF01F749784,0D2892DDF6A640EE,DBE3760CE00413CB,F3A6226693A88D69,611C12E3A0186F74,C302264701D67A6A,30D8C132DBCE6231,0000000033F28DF2,2C37379FE194D03B,78C62CC4A01E9891,70CF099D49E3A0D1,728A359D0A100611,25915740CB8304F6,1FEDE6D4F072209C,1B5E9FE2A56E791C,0E13A5C6018FC9C2,AD6197CE86D2B87F,0000000107EB1FF8,EACEDCC4C0709C0D,472F91762C0F6194,B5C7847B1C8CF5FC,130A1A9417248EF0,083737293A24DF19,5DA4048B45705BB6,90CF854279EF3ABF,59438359AAA080FB,9C11CE850D82031D,00000001C1481404,D883065A4001D355,EA6AD6E5128682DA,1988DFB2920768E1,C627EF3855FE2730,7D4A0F185A46FA52,A2BC3FD7CB9826C3,E84CD86CD90B3F04,937890AEB25E4745,5325D2D22A6F4619,0000000048284FFA,1F65453412194E7D,CDEC22A4980D841F,44F870D2B06AD24E,C48181930C6245CC,1E106869334B859E,E27909BEBBC23A30,0E8F8F66922B1E53,7C04B817203532D5,5C2A81EBF73F84B8,000000010B5357B8,79998CB60F7D9CBC,0E03798C28FED25F,A024CA543A83F5DE,5D87E9B76D9DA6BB,254CCC8E8A27366A,15A0026C9E135998,53EA3932476249C7,155B0E7C99480A6A,7BE9822D177D6879,00000000D40F36E7,63EE30B03BF49B56,0A6B4F66D5BF4BE7,BDEDA56227A96477,7BEAF48726A67D6A,D0B489C0C0EA88B5,0EDEC950B4370DC6,7643DF0EECD83843,CDFD6E7FCA2A7231,3662D090B0AE4EED,000000008F4A83E8,D7077B605E661EBC,D8702A4C10C03E10,2B4DCC48A7532F48,1EFF55A8E37D5446,C81E7F265F1B7A07,A40F43CF8B844EFD,768242FE237085DD,6D3EEB7E7C0DAB14,9620A913D5F2C112,00000001AA348DA1,88FB4567636D33FF,50A74A8DF50ABEBA,FC74DD75EE2235C1,167261E85DA665BB,9E2E63664640C0E5,83D0C6B3430FBC1D,FB22CE542BA13C2F,3B8700CE4DBDC1F9,DC022F8C433A2A01,00000002765B36E2,E436BB8F54586643,71D4316394CBBF19,21DA87AB12D7BBCB,1ED0901FDB0AEDFE,9DDF5108D0C16C86,459005E0BB0C65FE,32F0372573DDB90F,33C01CD2229A70C2,32B11DB1C58F9C58,000000016CC1E00D,95552D739D6EE898,3341453486781CFD,DABA9A661FA4B359,1BF1D8BF511D1106,C14D749C4D9EAF7C,A1FD22EE5887AEBD,54D4FBD38C11E38C,1679CCEC61DD0B1A,2C8B24F684644223,00000001D261F702,1CA848A31E6F0EBB,49A992356F7EA735,AD48E5B1426CCDEF,AF15217D67522922,A5F5CEE0FAF81BE8,F44E8330BA834E19,1456A648B7FF0F39,DAF96BBE0C933C45,9A2EE25FAA435D88,000000018E73CF2F,0AA9F9AB0BB06A9B,7B86A2BBD0F3F105,85BCD8BD27D82462,C917C82A01A236ED,8960B2D679B8451B,E4ED80909F9917B2,AAAC05D97AC10709,3B89A68F36EDB4FE,18A87007C52EE227,00000000C7DA6A72,CBF154FCF9707BE0,EABA7E377497B983,E78088E5D4190671,677D5D101AAC6733,C10130DA323EE831,AEB6157E0BC717FB,5DCBBFA52E6FCA17,7402F52871143DD6,23A6DDDA9EEF907B,00000001EEE7A925,2220EE6A04695363,377E43D3BBF5871F,CF22350DB92127CC,EB5394F74622ED4B,203D09EA5401FBBA,FC94C5C24F39791E,6143D9E59445F7EE,6E98CE6014F2AF60,2CA4258E15666533,0000000011BADAB5,173469C748761712,D6A2AD0E70C5E0AF,1E64E7455B4FD7CA,837D098B1273A30A,BB2D71BE73DB923B,73933449E4FD93F6,EF412293E1E4DD95,EA00B8F72A832913,9A060825988D7081,0000000086613BBD,7DB281330DD05759,F60188F7974366CE,B0017BD52D263884,9B039E44859210F7,81560BC9DF2F962E,32E1F2CD85982D1F,7D4CADB38B98E0AE,B568482D05C5FF96,0035FCB69892EA17,00000000A9C8E58C,F7A5CA1B14385F15,6CE81BC4B0A56E39,75746F35FB6F514E,31E9027740D745A6,A8FF6D28BE46D103,9656FDBACFA72751,1882CE033AFDC317,0808FCAE4F385051,B19E4D315A931361,000000021ABD81D9,59903C87F06BF5B9,8FB311384074DF2E,08C98F2EB5BF7E86,7B3D15D73A5D2968,4C8C5894DAC4DE0D,939629E01C9514D6,711CAF61BD7F6D06,7A5D814A7DB0E395,E37CD73D7C904F3A,00000001DE0A6CB8,F0DC2E0FB97664AD,7D567C5AA8D6FC85,32A4F4487615EA3C,A84E8EBE099D9CC7,3F9C4346996869AA,850A14CAA3E1FE61,71C84C80EF3E989F,2206570E43ECECB4,96B2CEBC4369C9B8,0000000084AEF592,1E815EF4EB42F182,DE29CD8679E9BD8C,10E5884733255A48,05B1A23DEF002085,BF18A5466C9F44A2,7A4E3CA2632DE86B,8325BD06D593C593,497C0D9E31E0D758,A7AA0BDCECFDD662,00000001C9537819,46DC6FC89CA7AF3C,5C388A4E8B827614,7B0D3BF033177D2A,B6519CA2521D723B,F7BD13DDB290F57A,8366082FF5629A72,8598B9079B9BB54A,6C5D67D4746CD62E,7315A934038DC317,000000012279A3EB,76EBD14375FF7772,5271CEA07C5D134B,D414054D3AF5DA67,FC75C29CA1EE4C62,68D06254AE0994DD,9FC521CD34FEBE25,33B983A7B3450E0A,75E8C01E8A3EB46C,B267060E2F5D523C,000000007B632F3F,33F0DBED5D64104A,A0DF11032E7931E2,FBA8C030758C60A9,A43683B91D675432,8CFEF037C4844039,3DA3990DD27A23BA,FD3A604498D992AC,6404C97831748670,A875ACCC9E406A42,00000001B71A38C2,4214DBDB648F269E,207AEBEBD4EA3B4A,AC01C5A4BC8DC2DE,715EA80D3E6EE044,C11B0B0182A0144C,0E1F297D7669FBEB,407EBF10CF5434AF,6BE19040AE46AB4A,80408595BE998D7F,00000000213B9E3A,53967C3542488D34,08AC3598139D4A48,CF22A4BED7631A5E,2488F84DA27151EE,E6B801C26ECFC3FB,A00BFF54993F70AF,C6345F1A03336BBA,C705F8E1B5AEF5A3,38D4F90D31415512,00000001F6C20499,993C570E4BA8875C,94AEEDFD640DCB84,9E1FCB8F9B66EFA6,F53C89EEFD140DD1,21022A301C8C8E82,5F5E56EFFD16300C,DBDBB64C95FF658C,16DF4AAEC5170AA2,33C2E5F79555F3EA,00000000E981C836,3265A75C8EC9DB44,9573B607BF5E0C3C,B92AF1BEC3DF2C08,9E6F4A8FECEC84EB,C32672732011F96C,2A823E20A4A1D9F9,5F73F02C5EE012E5,1559D1A15DD7032D,BCC1F927B0409B92,0000000201D9795D,0A913C848453D995,A1A648217FAF2AD4,A048E8A0AEF8C400,31B1814D6B245251,362ECF08EC16FA6A,3E00A052F643A72F,5E8C850489324E16,9EC8F813B2B4F019,C4456445BF2FF7ED,00000001803C584C,05FDE736AF4F0ABA,5D5DDD6EF5AD3C5A,F99BC4D6D6730284,B78FD27FFF8A71DB,039F9042AF31FFC1,A8DA8AC0A24C56E2,D442E510D238FBE4,4E977F40CE5A7A3B,3EB3977E7CBB876C,00000001E54993D0,4DB2C85C38FEF929,CBF4B560DA24F51F,8EB0BB9F4C0669F7,5C091ABF62173288,6579B51CB3358301,7E5B71C02C40124E,CAAEB2A36B4D4861,A16F0F94030DAFF3,C656ACCB1F2BBC24,000000016435D7BC,2AECFFEA541EDA4B,E3AE19D067D32C4E,77A307919B8279D9,A3D5FF2CFB9E411A,5D05C9C30670908E,37C0F8973A287EFC,8B01D47F35971C84,12E152D526E1BB9E,623CDF0A3291E493,000000012E46AEE9,E36BCE1C1CF135BA,7367FFBBE6CE09C7,38CBA30A8BC9274F,A954484B7BFF64EB,7E5D0F4B37195E12,308559B37379527C,2226FC595F9F2EEC,2DE53E533659DC11,22D05A6089E30FD5,00000000BB66E678,E61BD0EB3A478887,46730AFA0C7FA9CE,C685A67051FB3767,ED8DC5005CA1E995,AC61D99D9639F581,971B78D295D4866B,4B6CFD56EB5D40F2,EA2DC2B14A84C6BA,617314BD147A7FAC,0000000173CD2AD7,FE62543F037AE670,09BFD3E7BBE275B2,2FC5C2ACB6BCFFFF,24366E1212FDF17E,8A058D1988FFDC27,1464559FA1346EB3,EC90213F749214B8,277D2443EF491794,967AB3725DA184EF,000000020590BEEF,2D8673F8D0C6BC3C,DCFF04624B5DFCA8,151956BDD592343A,2A05447B2B8F20EF,3615AB7893F13CB2,F7E12D00DC3F12EE,EEFDD7CA832D5AA4,8F21959D58F52F17,A69D43D6E25CDECA,00000000B4ED7AFA,67787D5ABE17B8C6,4739527BE49CBDB9,5C7D8EE3F0D85691,934E2360C5C07AF8,DE80A018FBA13351,54C1A2FE57836A98,4FFDDCA860842E5A,C46F331D3836F545,6DF70160D56E7496,000000004C80E455,C74E58DFBE617127,0C4C1B3BC85EA359,0C37FA21AA5B5481,B123B0CF06B554E8,B407AF020BC27B24,7E0A7562C37214C4,092350F1A98E0873,AAC8AD9CE9255EEA,1C2BF77F795006F0,0000000111A5ACB4,A62E8214F721D627,55E2C3BD55F7FCB7,3FB3F11985154206,79887851C465C79A,09477D5F24188158,574DC837C7F6E470,8C2CD309BC271C21,642B5FA5751DE0A6,54FD432428AEB057,00000000ECCD1708,BCC9F90272BE43F6,453801B50414FF9D,E3DD539C72252392,22AF6443A40D5610,D3846450BAA2CD04,6F99371C331D67BC,976044A3408D03D3,88DB5411A8462D50,D79B98D645EB808D,0000000156BC4566,A14A68351B339645,417780E6665AD437,2F0691672BAB80F5,BB72093401AB61CA,BBD1F188C6E50408,AD77987CA3BF5778,66021C72689142D8,81EE6C9CC61814C1,2EE1CEEE15ABACE2,000000023CEA2F04,72694408844C5CF9,8104F157EB9EC165,41075E84432DAD3B,8DB04845C4E2C490,7D381857D5F98F65,89F42714800CDE42,A2863B04F7EF1323,161B940E177171D4,408ACDE5EA924BD4,000000011A8B0B1D,C1BA9A5FABC4EF56,6E0A1AED37080A75,BA76A3B011CE0506,A5A6D57C89907DB5,5FB4BB4870AC0A91,BAF69C00BE0EF6DD,9476916CA92F0A3B,5146DA1964D6095D,46D80679B62AFD7A,000000006082D8D3,DE3770D9479BA67C,840692E8A9B8DA6C,B3FDB18AC6047D1F,8278517ED04FAFD3,F3ED01E70B64A863,39921D64B8E65225,609649B1118F7E7E,4E6E8681EAD47F01,ACD3D7AD9BB5D049,00000002144FD541,81DE135193712C5F,8885FB82B2A15B19,53202B71EDF43A04,C76873DDE578BC61,069EBCE10A71EBE6,78E663C37C8F9285,DF5EE0B38CF8661F,F45DA14F3185C044,F9BA066C11F0E1FD,000000010436C682,AC6129E6F5E45A10,9E60376728EEB69C,AD9F19184366F8C9,F504B213C1EE3B39,B8EB219A7936AE67,CED99E65E2AD56A0,BBB1D6B3D5B02737,22FA14D327851DD8,B8DA550ECB56057E,000000014B9F0100,1E8C30D3A6238D2C,F10A4E0F8DDB64FF,C07B86A7361430C6,BC9104CD80DA71DB,6B0D23B79B54B36C,DFA03A30CB8BBF37,54085C79BB5025AD,FDA6091E383822B1,FA2E874B32AAB321,00000000FB934E7C,1237C96E8948B28F,B9F0FABC33875C12,CA592C0A7B08FF4F,6CF10EDFA4523AC4,A6C172E4EC8EC377,86DBE43FFFE96CC3,37E78A3C23A6B906,05181D96C80D82BB,BA1FA96AC2D84200,000000011ADC056D,2070270A005B4036,A3BB799C09B9509B,84F37ADCC7754AC3,456E7585011C4E66,9226A3632B896B97,D94A1BA2B0BBFED8,3C995E3406B62067,00F35C8AEA41A465,DBA511446F866B8C,000000020D625B26,948B311ED1EAABCE,33674502B9E00CE1,842FC2F885F870DF,50548FD9043F623A,B17562053843AE87,ECA2AD318AA075B9,30D7D3CB10C0740A,FFE9FED80820046D,E6B4BFCE0A9D3B28,000000020FAADB46,98C638E3D59A60FE,FE0C64662B1F2B32,246A8978E60466AF,3BEE193887456F94,88BA8BEC3BA9D703,57236A2FD2A5FE6D,238F72940D505482,4AB1BEA4B33A4CB0,E61DCBB9F47B04D2,0000000034A92D49,7A6AE6346CA47D99,996C37CDCD6DBD2B,AD592085906223CB,A185547F221F1E68,31C88A1F79099BD4,F60A1B405019F295,6E0C6AEBA051DD59,7842C534720845AE,6226ECE4026AD286,00000002457FAA7A,B7906DDE2F04BEB8,F45FBAD5AF20976B,2BF7402823120598,54B09BF71B9233BD,86F1112194F140AB,EF36CCF2E85BB2D8,76F6C6425EADC1AD,4A80DFB669DCAFC3,A52227E1B6BABAF4,0000000084D672D8,03B3B3544B740952,B3A07C01D3D564AF,D9E279A6D982D45C,59BA9FB2C62D9BB8,A791ED50D743CCD0,969F92454BD70A21,E2F62B1BE43E9047,B42F5BF6A1F1FB83,3E8E6152EDBC7128,0000000192FFED65,9DFD4F444F292919,3997A0B5617F18FA,C1D2855554CFD78B,B0EFE92DF4CAB159,46A83E7D5B71ACCF,20AD5896EB545753,149C07D12652BE05,CE36E8A1AFD5501A,177BC35F7B128E33,00000001CE85BC6F,84DA992879B86382,2B2DCE6BA6BF5D8D,F0A5ADEBFC337AF2,AFB5495AEDD72951,72BE11E19C1D5242,53BD4669C8942CB9,D6182D5343A2ACAC,4F8C0BE3E0314839,B2C50F1FBD1BBDD8,000000008DB20438,D5B406082ADDAB32,6F53EB1BB4164EB6,28183192ED062F8B,967ED1BC677EAAFE,2C3F0E47F0E24FDA,6041A07C6957FA7A,82A05A897254657A,DAD374117D7C3EF7,61EEDB3F0769200B,00000001348AFFAD,843FE5BB973CC181,6A8EB706FEBD93B1,893900D7B34A48AA,C75476691E91E89F,B4E7D29A8DEE534A,605134ABACB46CB2,B8D853B23348F6B2,0AE4575DE85E8AC8,7313A78C6246AE93,00000002535AE067,1E022B008E25801A,6748567CC8ADD95E,F5404D40C0DC186F,DE80D8EBF330EF30,17781A7B036F6367,72119308D5769F7D,A7998BA4AF206BD2,7BAABC1966D162EF,3E7F177944C1C741,00000001B4BDA4C4,2A0EDFEE6BC7FEDE,54523077A091EBCA,79A95A0A6FE9FDEF,44780E24067F402B,73792C8FEE90EEEF,F53CF2D8ED3D38F1,00C0607D7D0A6A34,3B6B2170C6FFA664,EBD2C43F763C9D88,000000020035D740,F10F56EDEFAC4A50,3F932373B0DAF0DB,0BA57C7EE4293AE3,1499C81372E88B9B,4201AC76A140E435,F39DB91F59A1F6E2,E96DA6E6EDC3DD2C,C10C3B0EAF1DDDDD,2AEDFA1BFBFB36A0,0000000248FEA378,0F1C545D37470701,D642E80EBB339A5B,4C2CF68B55CAFC41,147E17D1AEE43DF8,C84CBE30C120BF84,923D13CA680E68C4,E8A09A37698D7F9A,580984225969622D,266360F8EABC0CCF,0000000192888083,A42A8492F9EBF9E4,FA0F9D21141017D3,44384D4B18B300B4,1DB6C0CADA990BB7,64F7E42CD962DDFB,03B4DEF2B1F2CCE3,5738329B5D5010EA,D185679A935E05C2,4C73FEA3F9425FC9,000000016EA0FD82,51B6500FDF222895,F466C8EABD2B7D43,4D363CAEC9E60640,3EC15050429624E9,62A3B403CB57487D,755F3DB1B5291BA1,24D977EAA457B96C,03E96953A2D2D59F,AE17B744F2400EC5,000000025152BE8D,874E34D71E0C5DCE,34D86A3F98F77364,01355B2DB17613E7,C948069C0628CB5A,5592BB0BB14A8D89,43B68ABC56E3971E,1CC9C670102EB341,CE37ABDAE0952AB7,5D2CD06806E6C3C6,00000000FAE27F69,B74D42960F5B2178,D8F1DFF378718C83,061400EB0A491380,E43CD7E8EC9E379D,E82BEEE3A7986B71,7CADADB2D0095774,626EDB817373443A,C58EF9A1F409AD6C,125C254DD07E3A35,00000000FA4133FA,9BB52CD08A709522,6FB5C218F0284A69,EF91C475BDED185E,04D7E27BE80CC4E3,98AFF4401DF7B6A9,00B9A3190EF6726A,ADB59C63618F4420,3AF65CADE3A46A54,73D0185D33861AB2,00000001A984CB75,E8D988D735E65846,9EAD781CCC16356D,3516476322C9AAD4,4E20AA8ECB73C3B3,85A36B726F35CF4F,A144907D334BBF93,4AA7E15B39C8FC26,F45D872D2C9D9DA8,85E528097F58AC4B,00000001195319BC,9B9E677190630661,4F060A0741984461,92C97C45C430DEA6,6AB182408B2D3D8F,BD344D89C1CDA90F,AB46E2175C81F4E7,C00A77CCC62CB9E5,2F6AAADCA2F2606E,0D0420C41F5CA2BD,00000001883300C5,3754E2CEFD189830,6B4B137DB2A7ABBF,5C0E38A284DDE1D8,0D1A0CA8F4D9B59E,4B3F658D7EDE4B75,EF92B2E77D4CD6E1,36AA76CFC52FD6C8,34C85669E2E93C50,6FE6C359D5127792,00000000BA974C77,06DA4D199F4830E2,4E87BAE279FBAD5C,02D2FAB235F9DB67,9D21B17AB69C1C9B,9D8C067ABF94D61B,BC24C50DB352E5A7,9107A5CD0C47838B,FCCCFC50D403E19C,BFD194EB2842C468,000000024321FC62,8D120F8695C2C314,F8824E4706B1EF96,7FF20E0D3151B561,338EA73BF880D284,AEC7B70605AF750D,E9B59396EDBCD9AC,A28AD4E46AF9C07A,8ADA7DAD7E4251A4,863C1C9E5BDAAA03,000000019640A865,C767D406008529A9,A7E0503349E80F4D,F87E52E1C6715287,734343550B4CD719,97803661014A83D8,461E29C2987C0CAE,374E9DBCDB761819,62BD13FF875C6E6C,707256EE5DE4CAD8,00000001A0955DC3,F97126DEF06D8996,7ED48CAF8F210D1F,09E84D5FCFDFD371,F0A57E93A7A7E5D3,DC5B17A85F92AFEF,00B5B0893BF373E6,75516BDB7DB6BE1A,476519A4072D6919,311623F75883C0E0,00000001A43FBC0D,2C1AD035BEA194CE,0A5ADD7E255DC8BE,565383448D1A8D68,540D24F72D128744,86B2B5150090C884,AFE5A4E5324EFBA1,275B05945812083D,997138A59FDB3FAF,E12928024AB47343,000000015A887289,B6B516345CBE3D24,F0F195ED69A46601,F888DEDEDA98F413,AA53D7FE0AEC59EB,EAE5B95C6AAC3AB2,9369BBA475BEAA99,D1D17B5849C7C7CD,027C6F67E8FBEEF7,85D29EA9478B353F,000000015D72D995,19FCEFB70DAB32BD,080FE12DE22367F8,DEFB89A10FD537E9,097E19185992440B,70824E802A4CF30E,E66A6B8D516B3922,FE51E5B97066E31D,C5DD1D8481946C8D,2A895107CA7F7AD0,0000000230305167,5AE6C220B38FFC6D,FD7173ED72CC5233,18EEB5B73CEB7AEF,E5308A45417D21D8,E2F7F8DDE05BBFF7,EA006B310793C693,21D9605070AB24F0,0EFA582A6B2A4BCE,9D05A9575DE49F51,000000014E6C4D5C,12BE2D98FD956EA8,0EFA2FC0AF2C5195,5E0423F4EB162FFB,4B568CC936A6B0E1,A8B7AB1A3392744E,935FC67CFFAC7D1B,CD23B78DD68FFA51,D997E29FB3848A29,EBC0AE8654D43652,000000000814AD58,F5B8B4A138D518E3,B3B4876172DFB037,C436B9B59128BCAA,99DF38AE14407CA8,AD9744247A73F8ED,713ED9A5854EE34B,8D2C2A5530EB694A,1B5B5893BC29D31C,CEB3B05DE517EF85,000000004F0C62C5,DA828F83FCB5FC57,09CDAA47E030B13A,C39CE6784177DC4E,624326774C7E0633,0837252590F2D7DA,A42210B7D594D566,7DAC55F76B243F8F,14B09CD43C5B8636,12A2E79345931307,00000001B6D14799,AD21240624DE60BC,A649C06819D1FD77,4B570B23425199EF,210E50A24BAA615B,1CD2556D2596FC05,A63B8734BB9489AF,AAD758AC0D649352,A293062C6C021A54,A610A3012CB7B1B4,00000001A2D3EFF7,7B17AFEC6E0B9BE2,EBEB5FF47A259140,0F6CA0A62913171A,DF826693B25CD22A,0197C6C9C0E4622E,19BA205878A5ED0A,BEF9782181CD14A2,A6E6117C15195A1B,80A64DC5210E712D,0000000237731B3F,56263D4D9EA27CD8,9F2911F5CAFCB525,40E2FD434E764B25,3FC97722C8467737,9CD5B1F5F5A99881,6434FBD096F4C1B7,F3362B20E3D626E4,19BF1301ED987434,F58FDF88F473F617,0000000122C82A37,90E1E9968C09F774,B2203E4525A06166,B19459D78C87E009,9775028E422DBBD3,18C496EE0B41BF3E,881D01B199AD320D,B3412A007B19C27D,7B64D43269811CB9,2964E9FA7723159D,0000000111FEE716,813F0105FE2E0EA3,FB0F08187F269CD3,24CA098440F6EA0F,73C90DD20D1C90A3,977E25A76739BBB0,5D24D1FEEBA138FA,B16CB730FF1CAD30,1616F5DDFB35FD1E,FBC41AE50D3B7B87,000000008138C203,06D2F0FA4EEC9EC2,8EBD9B780E724DA0,462CD82CD5A57B54,F4680306C82C4EB8,99B289587DE4C135,DF0A01C1398C7752,A88ADD072877B906,9D592156A6BD86D1,A3722E36A7994C93,00000000A44B0381,A6C63ED688559496,0C457AA2661D1B9A,1D460BEAE7E2EC8E,0D51ABF66DB9784D,0C1CBE6F4149AED7,305A58C67597DBF9,BF13C769C529D9FF,554F796CC530B0F7,F4A51C0E02918EBB,000000002CF805DD,FCB395D429EF286C,B03670B08D0B8100,D8C700DDB3AD7949,622FB1EA9C2930C9,A1E317868E7489E0,DE9B605CEEDE62F8,879A3D4FF814DCEB,FA6BABCDE71912E5,957DC644EACEE6CD,00000001E1ACD24A,0428B990B1C26CBA,DD890059B124CF5D,806B9DF3509051DC,93BA96242AE50C10,1E6B6FF43A310F15,31C236B0A29BA2A9,D4CCEF9483EDCB5D,8EA34C3342679DDA,4D5333CFAF6DD467,00000002431C2F80,66AC3A00B8F9C2F8,C96F966D54FAD297,43AD55B69DBBD1D6,29EB39A1485E04E7,0AAC20FC78736ED5,EF7703FCFC1D69FC,1A3DDBEF3DF03ACE,A99AD9382675A040,EAD9D11320F60D9F,00000001E77A7F94,11F7A69FBEF665F8,2347F9A133E2A7E8,FA58A2EFE121786B,22D32325BED9DA37,A820A059D2214B7F,9644D08F60C1AD6E,D06E2F3491D125A6,A95B237AF7E5F4DF,782DED93AE90A1C5,000000020149F8AA,9574C7D6CF3C2F31,6BE3A6E1B05391AE,81A39CBA78B57282,25B56A46778E9FBC,89547427BAD953BD,A222D6068A26E103,979991A17F1C96A4,B8DA57540AD6776A,05C962AA86A11B35,000000005B5CC8A4,935C80E47260BEAD,3C92468E7B1530B4,D73C23E70BA1CD4C,A0EA889485368DB6,56324A0F207B3530,9A6201FCE668A7CB,43D374AA93A174DC,800E3B224BAF98D0,E4A87F3592CAE1DE,000000006E17E0F3,9C00F3D3E8FFF737,1910AF366373BFC1,F3E1BBF767BD4F82,99B9860207ED3ED9,D18EF026A0C0BC78,FE963B8EDA5E7E66,F6C423D3A521438A,9EE3E37FCEF9FAB2,2DB80366E193179A,0000000101659A12,3CCD22FFC186C2A7,486679E055A35F03,2DA75B896E5ACD00,570AB320E567A8EF,D422062DD81CF261,79F3F317BF2C9665,2E9785796C0B02EF,C55EB42A96DB79DA,F5E0236645B0A9A8,0000000258DB5785,A5D851A3BA05914F,5982B3E7DB53ED84,EBC3DBE4EDBF48A2,BB9C9962684C24B2,2986A27B70CF14C6,F05D7A8A79AD1836,A1FB9992C85163DE,9B98B2D44444F825,29EB4D976ED63D4D,00000000AB4E5A1B,743D625F8763AE78,2A8F4A1ADF268209,1C8FF1EBA3AC0000,26E25D9FEEC2E378,897B0F8CC71F5FA4,9B48CE1E4FC86886,34D503501B9E9B85,A0AF2F454E765365,B4708BBDDF4FA0AB,000000005919B356,63E00E6D9CF55FF7,B5AB8940D649508C,D09317FE70D090D4,81F03A5B14AE84F9,D3DC658C247E3AD6,071C8292AF434BF3,EA3A782D4A8D3AEE,1E0746E0E39B478E,5E429C281F2CE798,0000000043E4998A,AB9102BA4AA3645A,AD73385B3DA1AD8D,3605E6E7FF22C42A,D2A052FD4D5AC913,F6DBE43891B4F053,9523D357F57050E9,CD73E3527770AA47,A190DE947E49AC60,9B05736BA4CF756A,00000001C8F93613,6FB98954011C0F7D,8EEC404715E7D96A,FCDD5D4FF4DEB1A0,95968977BCFE476C,244A43709D4944F6,24AF5539DE3FB2BA,BB149E33C26974AB,AA2B9A17CD69B982,CB8A61A4D1117277,000000008A5BE581,983EB8BF9935506C,8380EE4F0362AE47,A46C97D002C15D4F,631B3B385DE6540D,0546B11CCB5E9F6D,5295EC011974C417,4C460395C2DC72D4,E480F0713ADD8501,43E7D77A2B0490A6,0000000225443713,C4A82E47DC436477,30C3392FD2C49ADF,036DF29C53AE16A9,B627F70041727D70,15E41ECB873898F6,B419107ABF7CF3BC,0DBC488043E02144,71546852800FF3E1,4B8E7AF09E975135,000000015477C826,ACB0792A48CB8F06,0FA139264FD137FD,06CD866B53CAC54E,CBCA76CD3D0778EF,6186E4B058CACA0C,DC3F816E468080E3,72914A7BE026C9BF,7326581CC65684D9,A086E28EE69B3049,000000006E5F25A2,314BB8C3E9AB0C1D,9076587DE5DA08FF,BAEBF74905BB1497,130D73F271DC2727,8D921F9BEE61B333,360F974DD8AFA97D,5E56760EBC80AA84,2E110E08FCDB078D,15FA1AEB80BE0255,0000000182FA0BE4,D0E175CC1C68E683,2BA0B1A9F2B4A00A,6FBA4F53ECB03CE9,D35FDE99F082A883,979413D90632D941,671D74EB8062DAE1,53CBF600036838A9,C3326B0DFE908478,150E84567805EB27,00000002771275BB,C14DAB8EF92EF76D,B33BBA4790FAF961,3C3F96AAE466ED3C,204578A5A67ABC55,C34471682CEE7019,0F4F97989E929ED6,7F8C7D9984751EAE,08EF42CFFAF8C64F,856697D40C49DEB3,0000000103B49B60,CF87EF03DB440633,066FCDEEE07671C2,645154C84FDED670,99E93F876AA89ADB,0C0555D0AB08BE3D,DAB82E8B9F39E954,0FAE6765C649459C,FC30CD370EC82A36,BCC1C0C02CA1DC2A,000000002070C214,7F0F60F6F4B1EABA,EA330F7A8883BFA4,AB30F2B207221EEF,BCF4FA7835F02E10,5D3DC4EF17EC6C9C,14C7320A69D1FDE7,5555CF5243618659,5684BB05303D2591,125F95FD6E107BE5,00000000EA2B38C5,1765D27D0C3FD7AE,600CB926D5E419B2,049A2818E948705B,1920D8F12C8456C3,7D89871CB626BB86,C5D11C72B967B12F,3682AD18EECA6C98,23277B8030F380AD,C61233F4AD4065B5,00000000D2125668,8720B8E2CBC5286E,4E093F9E8C99C35B,109C988A45D7D7D7,89C12F99FCF5B167,1FA7AC56E29500FE,B60FA1B74655EE9D,288422485EF3280B,EA9753D445D8E172,A07A8297DBEA21DD,000000009DCC4506,5CB040381A294083,E3AB858C736CF6B7,A1FD34601BC9F977,F552C5D3ECB7C441,EC3D7AA3686139FA,6D71089B7332076B,9987D3DF1CAA999C,8B636635E5F7DD2E,A2D2BD81F0E5F6ED,000000004C5AA3FB,F6D348179CCE187B,7413C6C35879E989,D9936B74B3E070BC,2D7BF0CC0286176D,0C26694124ADF899,A4F197E6E8A595F5,43FF2C4A3FF91065,CE732F50975C56E5,1AFF812512939B72,00000000A70E54BE,E79DEA7A3F35A38B,880DC2A7B9F66DAC,7CE62758C5256EB8,BFD0A245137E3FFC,8BA8543C72FB2468,88EB230ED75026B5,8AF8AADB61AF896C,9FD4FFC22DE2038D,B1FAEFED3ECD118D,000000004508C6C2,D244BA97EF9021BB,F926F0A27950B409,AB35DE640E0D1793,577F144FF963BFCD,617CD2C9843BD02B,F73CC2859303A956,045CA313AB3EDE1B,B232CCCF49D1EA38,D865A8CB154A4B39,0000000049379A17,8A0CB871E7FDAD86,6A0FEFF4229E76DE,B9CB43DC7B3CA9CB,2A3F67608E950ADA,50F5CC2DCBC9484D,8D38C4B54A89FE31,C3AB8904B2C59992,3A9EFBF10BA057CB,6067507D2207C5B5,00000001C6A7D5ED,8A0A58CBA55AA054,29069A518D58D16D,7D45F08F7FCEAB3B,B5CB16311C128A48,8A13FBCCDE03ED19,3468C6C7F747534D,12F8CB8853D0697A,EA1413FBF977DCB8,D650B34E7761956B,000000027B585617,23DF2CA58990C003,4C54C30A9903A8FB,344DEC72DE4C6BF7,D9C574BA1999511A,1DBE27170355C98E,3A36549337D0483F,94C2686E5E0FD34B,2796AC1C2375B855,EF9BB1C4D06EAC01,000000006700008E,B8976EA8755CC232,AA35EA1874421D96,3EF04C2827511402,B3FCBE8619D19170,C0EE636724D86B8D,2B1395E4B6172619,7C9E28D3F63EE5AB,D78D2FEE4FFE4356,7692ED2F4BE75CCC,000000016311A2D8,FE5CF172AB3622FF,00227DA7ACFC0E7E,9399B48F4EC8ECE2,72864078040FB04E,1DEACC8CCD62EF79,92DABD0071285CF7,C7697A6DF0D2D43F,83E3EFBAAFC06047,609D073F66167A1F,00000000184CC473,2CC80589DE34B1D9,922C90F51E88C2A5,7EBA9EEDAC9A7098,A6A0DEAAE5B5EEA3,9477DCC317520B34,A7A4BE5C657F6F17,01F30DE12363B61E,93121230E4036D99,603859A1A675E2CD,000000020418F78D,3E108F46B65F5083,4FC52564C377B85F,34C996D6AAD0E6F7,CD47084200E3A193,B52356040A0ACC63,22C8D07507965B0E,8A8EA807DEAC38F0,3096B08A5FCBE2BC,C21CB49700D370A5,000000024037F62D,B8560C7ECA570F12,7EF5F7ECE14108AA,BBAE98E1679FA778,EF42E23097779D43,919F2AF151AF659B,F7CD034229385ABB,47D377160274B85B,A5089564B98038A5,629872142397E3B9,000000016612F169,1F1E2284E36ADC53,0FCD1EC5CBBF1826,15D411CAB2B26814,BDF064746C81A30E,290638265E2D8496,958D37B989EDAE82,8FF1F02E67899C39,1833C1A469FEE7FB,CB21D3763F4F81A0,000000001657593D,522037E02C7643F8,83805E74FAE73B3E,DA37F72B6AE02257,CA676D871D0838CC,E1E4CBA147BE0AF2,5077D903048A57E6,EFB2F2248CA62580,5B6BF4625CE3729E,2EADD62AE8F446CE,0000000250DA8DB3,E2B51D43C894A805,83C2C7AD271AA35C,B2A0F17C6BEC1128,9574AABDBF691F4C,E9F66528548C6F9A,A55744029C5E5DA1,8006F6B16A1AD068,95947EBBAE875A77,42EC3BC644E54771,0000000057F30C1D,93A21131E8D43FC4,82EB3C0A7A26F203,ACE7601056FA883D,C935190D1F06A52C,A671DBE3D71EC8EC,2824E29526B9A612,0FA3EB5DEBC4E487,BC6228BF7B63DB9D,AFC94310781406D6,000000026A1510EB,769D3EFC67399170,6696068938C1B468,B12B1A98F4DDE1E4,A235127ED95A476C,2E845E2E6C730A2A,17F27CD44AFE1109,1593AD422CE4FEE9,83720F5F6783E35E,3474C33FD5C91B58,0000000018EE3C46,93ED0E055DF70197,8833A2D7E7A4A063,D4F909643B247C3C,44D1EE62D085E8D6,0C4DFC80EBD286C9,28B72F13F2F69141,84B5A9A0E23C9D58,8C8F3DD06851BC7C,6BEB3DF62921047D,00000000D048EECA,A990B0F97CCB35F5,4EED77B74933E127,D40E960A44CCA313,1402FB750F0E4995,AFC5208F168D3BF6,952DB9B9FCD85CF5,646BC524FB87418C,9694047FD93380BB,7853674BB86C5426,00000000C8B0828B,1988C0B185978E34,0665F8FB4FBEAB4B,7D112C90ADAEDBB5,F6229E5E57139331,C929CF1FF6012CF2,E7E75D4D26AB7CC3,FC2A506DB8D40345,7CEB4ACD7769998D,18CA3116D4D71F5D,00000000A19346C5,7A7FCDCE6ED9D63B,1FFDB61C78BFBF8C,7F9ECAF8CF60E0BC,FA943434F5E1CC57,11219BC796A2E336,61D0B03EBF5118B8,9083E608ACF3A434,4835BD5B0B37C364,0E76354D6226C455,00000001A278690C,835C6130B7AB7088,22FF6DA8AF79FC89,581D34EC53BF3B56,E69708A8CFD9B10C,5231E3F5273BD0BF,2A045A66B7B213C4,B1348C87A9F867B0,19BC711C46242D4A,089FCEACDE4AA38B,000000008C19B23C,178437D8085D7047,3F7A167C28ADE4A3,BB483B16DE36E283,1D564789BC7ABF93,C52E2B07AD2EA780,0925C95EC8768090,F8A6043D2D5A0CE2,FFDFFBD6FDA27491,FCFBFC376A46353B,0000000263765ECB,2B9E3C2C8A84E802,6A87BB492BD41648,EF940E097B9D7EE6,EB942C6A3B2E3400,FAC43CAA96F2178A,0A7A00220D709AE3,2B7ADB6D26AA8A5C,3A3C5CDF1CF984C1,E1C365C7A951306F,00000000A5B3C2A4,893473D00975392E,EDB551803A8C7455,D2DBF9F1B202AB84,191A02D53A262822,B5FE93EFB94605A7,2C9B939D97CC6ECC,36EE266A13F02697,B8B0539A8F17AE5E,ED006A047D5021DF,000000011D946D51,D43CCEB68A0B0740,4A1287D1FBD8E2F3,03CA1BC44697AEBF,6E43F889F923B44E,0EF9096CBB919927,E60A3F1031CE9D63,109228DF7590DF7E,D31979C5B17FF9F1,0889FB03DA7BD07A,0000000157C24538,BFC6DEF28413E86A,C4B21BD5FC11EFE1,301CF4A219B14341,96982E21EB16DC7D,AC7F94EB2768B101,A40C7B4996AD32FB,6102F61B06349609,413F9169BFA39D69,564BB40326A76909,00000000EA83255B,838DD0955FC869C5,BD507C89574C0FB9,2F699F0153DFB16D,98783FDE542DD8C6,4A2EA727AF765D93,34456A80779B7D0D,C5B8E40D2F1F1D2C,0FC696DAC7B2EF2A,CA9347E7CA0CC12B,000000014DEC4EE8,8CC5E19C9C82F65F,C1AA411FF2FAD627,597B3CD5F80F2CC0,8F6E6404D3136EF3,4D2858430D8FD132,6BE6DDAD9C9B2238,B35AD1C519BA97F1,1510A7FE7A39D318,00A44ED5817380F1,00000000649A1CD0,0E13538ADB0176FA,325B160A9E508009,ADF4E43EB8089B93,A29D0EC59E19120F,5D77F717E3888B2D,0492B801575EE0F6,8788B56C8253D6F7,ABB75648DB05309D,7ACDD0E55CA9313C,0000000150192C3A,B09ABE0005C3E639,A6AEC8EAAE5D4565,850C77946978F1A1,E728387CCEB10A45,FEC9810DB2B19947,14DD0512390C54F5,1B832984D6B82117,863D426AC200E26D,D849C54791961409,000000003B7B7DBB,38A23DBEDB54C162,A6F7F03B988C5376,D78F086DDEADF45A,B2633D105F44DED3,D9DFB3C29B89C6FD,A4FF7A117B042629,C949B447C9BFD962,1879AAFCB24D040B,E6F5BB58B9240140,000000023802FF9C,97899749A0F4DFCC,4BDB79A099351068,E9B6400CAAF70AA2,E0281E8D809A67E7,51AAD5A4C3D1E8A7,2E1EBA28FE488652,32890871B2AFE9AE,F9980B9E1816DEBC,4263C5FCF71AFF0C,00000000680CC7B3,0C8FB6CF38BD890F,9C2F68736CC03CA0,72F6D762AAB35430,6F680C0EBF66FC94,6482C8A7FB1E9433,5E06921D713BAFF9,BDA9480CEA4D6547,792572F5B323AF05,A296CBF2E4C318F9,00000001DCC930AD,09E1E9E0D713666E,B4E7075A5302516B,E94E93DD07EF758A,03B7B71E0E176A31,335D36D7BD6A0600,9DF6D9FBFDF045F5,BE33CE3FB9D23EC1,FD2760EED0E0622B,1B97FB3D08BB131D,0000000006D2A623,52A6AC2151E0D4DE,6BFF0F7F5CFB5B31,721780973E163253,E8A8ACA5FB15E3C9,FB1B557E574AE911,7CA01344A183E515,80D9508C139CF57F,BDB7E7E068C81F3A,B18D94CDB5E6AFF0,00000001A5968121,C0AC89B5EF2D87E9,F110B014448E5623,BCD8816826A364D4,DCFCB469E09E9866,2FFC38A00A4BDA8B,CD040A692BD03148,F8AF1102C0435FB4,78E60CFECF94EB9E,6E9B9059092655A5,00000001E04C354C,9A77A7EA6324CF91,40E0B14379E5D463,C17734E3C5DF02D6,A6FF8E7AE535AC79,362D0842EF42FC9C,AD34BD3B9F569BC7,C950B8A16444FCE0,9A2CCF3E7C0FA985,D3DEFBE0CEFA1FFD,00000001CCCB67B4,33396ABFD1C67165,7B1B0AAC74D953E4,9B045E25BB0D5AE6,ADCA9A3C026B1350,8D6B47EEC883DB73,74E79A6709DA7B33,8B60E9AB139C25CA,EF8F47BA381C860B,79AB8A201BB85008,000000005BCBA066,AC5D099E81A9FE23,618053C7DB7B9CE9,FEBC546231C69F54,3BA5FA24E2CD4D9D,61133D3E099121FF,AD8BAF7A4B31DF42,2B0AD66D79FDAA9F,7B581E67E4BF179F,DB187D4B27890B38,00000000DEF0A129,1F0BAA62B5BA0E56,B383F4C13A97F206,7B4774126B67374C,A7622B0849CF0B8E,6D203A640576F4C4,FF3AD9BAA32FD6EB,7D66B8ED7B8C56F3,7204BBA553E02881,2DF997DC63BFC29B,000000013A61CFB6,E2EFD1B388F132F8,4487A63EB7000A21,B11EB8DBD99535AE,99A82A5D678CD882,D8D397D1F815387A,026DCE639D76A5B2,E5BCA6D325126EF7,DD34474294B47645,C527CB0601E45F39,0000000209F457DA,4A9BFE0CE60D4537,81D407A6EEAC2330,55138888B6A089FB,C2F6F878F448A3D4,DF3CB23DE1F63E90,0AEA95C1F21383FA,84DD0567C9D11366,04AE33E0BC3C4844,4836454508ED0383,000000001C31F591,51BC436B0524C08D,267C481A806D26B9,51529EEA68CDB2BC,CD73D2AFB5E10160,5DAAF6E62981D365,3AAD43B7A07BC959,57A06B58E147694A,CFAA171D03651603,674302F5CC710B13,00000000BBE847D8,15750477272531FC,4D193FEF1AEF3CB6,28BED5C0F0CF29A7,9CA6205363C22BF8,E16997AE1CF6805F,483D2EFBFA60CDDE,863E4E6083453395,97841BA6A9C5D337,18A4437692AEA84D,000000024E788CD6,CD4DDEC0021F8655,0241DC66482A5B93,AE6835B804EF75E4,3B598690A08B90A8,5C572B5A3C3FE73A,4281A4753787D5C1,28D163ADA9EA91BA,8B90EC00B9FE7C82,3BA9E527C792E261,0000000237EF3DE7,738204E35DA2652F,99AA6BC83577F3BA,7875E3FE142EB722,C467F2548ACA099C,F35804934B23885A,E9FDE8E33C716849,171845413FC67D71,C15BA8ADEE4907AD,86411EF960049E07,0000000161C96050,91EAF89C7C8A86C0,EC35E0742DE3227E,6388FE613697C4C1,862B66263466B314,BE7DAF296214FB61,AE007B3FFAEA15F0,5FB5D861D9B211CA,1AC35477786E5D19,E43B1B29151F8BFA,000000012A4E11BF,56A1D7295AEFC08A,FC76E221D69F385B,631CAE958C65DED3,635275564AED1317,DC63713FBE95890D,C5FA1D0943F39884,B19D119A1B8FF62C,C0A75BFA738E262E,F51C03ADB1373ADE,0000000031E44123,6EDB714CBCF389A6,C3CC0C8003C40C6D,2A2F38051B7F6EB7,95B3855116B4E0AF,82A778F1737A311F,CC57DEC6F484E825,FF22D4947883FD70,A558B19DE84C8793,988AF49A94AA3560,000000018589814A,790E8BE226F35487,E09AE53668B1821E,03CDEB43A14C39EF,CBF2E20561B74D95,F88177882386D84E,AC6D28DDFA91381C,60A05683BCABAA11,611CDED57C3943A5,8B4E4AB107C8FD32,0000000062159002,9DABC66B03C44B17,FD3EAF24DCDCE78F,CA54F5547284E14D,20B3989A7C30CE4F,4919D472C3B6F396,5BC8522E94D76942,766817078E0F6EC3,A85A502B810B658D,07646BAA6371E73D,0000000230FECB77,972B6F0EACA23396,0D65F486E435D3DB,89E5B046BBE042EC,826D6D803CC8C5FB,D17F0CDA2358F23F,19DAC86A829F2F6A,D6ACC3C45BF20DCB,DE09C3FB57E111F9,E457DBAD02F76095,00000000824F528E,D1F02386CA7E58F9,9E7A144FFE08C7DA,92366FE7D7A9BC73,67663249CACBB91C,115594152C6C0170,E9B84C85637AB155,455AB17EDAF3366B,3F94AD1691D6A19B,C7158CFA2582D514,0000000195763312,A06135C1986E8269,B60944997B8CADF6,71FADC7EE9E612E4,380CAD021B9B5297,2F4D89E386EF5B68,B4E911FFD409324C,A1CAFB1B6DA04C94,0E1DAFD375FDD793,69619A2350D63993,00000000D1F568FC,26FAFAC457E68D97,93F7DE04E94279BD,1D7F8170BC610263,13ECBC7B86C3C4DD,61E7E559284E725B,ED2BA50DCD20FCD9,DCA352B521E1427C,D52F111CE6D09216,1B2ED182875A132D,000000021D7DB32C,F9550CD0FA0FE3BF,19FCFB5AC4023B07,49824A8F3B70CA2A,E4CF5BAB9F0DE70E,78E4237E3880A461,82B129471DD35EFE,8B16D8FC9A7546D0,2CB5AFE18F40F9D3,BA2466C610245427,0000000157DD56D8,B76F115C5D5BD376,A39027173AA35587,D737EA8575B88D07,A17316B0B9AF123E,809864D9AABF8E87,6B2A6D9C454619D1,6ABF6CFAAD31D001,CC3AF19B4700AE5A,F1C692DDA89CDE3F,00000001DBBD3EEF,C87B30AE9F05CB4E,ECBD14DB92ED1493,C07EC2DC89CD47C2,ACCDFC831AA14E73,D9433D47376368FC,4AB7ED1252A74518,1D87B47B019B97B8,BC83B853DC1C2A5D,5B22D892097DE6B8,00000000FBACD320,F51250C7DD19364C,55CE7B230F6DEB13,24D68F8A802F43C2,61A44874D6F13171,E5A36A7E54C9B3F6,A7DBAF518CE86D97,AFFF607932D2A550,352E39419DDDC849,EEED62AD797F53F4,000000017DF73834,2997087B8ACFF31F,30B0730BF40ED99E,F04AE71B1513A437,0B378E8648BE614E,4DABEB3DFD98FD56,3FA30D8C51E20E3C,C706EE5196A0D4FC,3A7FA68AB111C906,97C105B5150582CD,000000000F843797,6F9372072A694285,B7E2B6F970A537C2,2B1FDEAEBD206A86,4BE83E552CEB7D23,769E2545EED948C9,40DF6BEDFC06F7CC,493CD99AEE509932,AF47DB0D78AEEE45,AE323310C4BE341D,000000019046A7CE,96002C80332C9ECE,1BA13A1FC6E18B34,8BFA4C3CB41B9E8B,1B4EF546C4238D88,9402D123E08E36BB,BF642A45B6E0EFB0,070BFD84ACB9F48D,7749E62D024DBF61,B006BE74649FFD9B,0000000193DE5370,A65689C2F8062907,222C997BC2BA6F20,DD2A663AB78147E3,E96A6F1ABD205672,DB5A1832B8FF69F5,110A8A030DF56325,F188E611B4B67062,BA96D5470181D162,542D27A986013918,000000004793912E,D8839CA3F78FBC5C,2247241C395841E0,DA39371C2E89D13E,9BED8DAC093C152A,C7B48C8BCF7BD851,2AA0C5087EB4545A,1369CCD5751A649C,29724110FA8B59BA,502ED0692A5FFB76,000000026198E6B8,B96ED6875F99E7BC,83FF4C878E74AC24,07532D455E653620,DF4D45AFFE29F83E,F2B7258CC296361D,CF8327E0CDEB04F4,092A69DD3769F988,CC5E61F642F0FA7B,40C08D2296CEA0B7,0000000072D5BCFC,88E22C1F262FFF7D,4DB3115BFD4F5859,BB93E8CB742C8A70,1B010A2E7B5893F0,B113714365FE0483,CF875ACEA67847C6,62ADACF7D834DC39,6AFB1364EFE12D2A,6415837CC39DEFF4,0000000279EAC22C,4C0DFCD473F0CE35,CA4D0E2AD172D4E6,55D2630E00CCB644,643755B341EAC29C,149368B9E6D5B536,27F6E1049EFC3653,74CA99987FC0E463,16AB76AEF946898F,89C7D5D0F4BFCEB8,000000022FB931C0,5256BCCADF82EA34,41B8D45F402D5059,5372754EE49AAFB7,4F19A3CD8E264AA8,6A67688BB60AC2DD,B7B13574D5AD47F1,2110315AE74E3019,8BCED3460939F2B6,1D473FF259B8B802,000000023FC3E373,5329C6C7DCB6DAF1,71067C896F9C815A,0BF4E847F037F6D4,6F5D1CF638459101,1702C93BDE96AA79,7B36EC7D4F24204D,01AB0A240DD9F73D,96D72B44D2238AB8,CDFABC9558BC8B39,000000012464C3BF,D622C5C4FA55D98C,ADC96B3176B80EE8,C45086C3C4ADB0F7,DCCF917E4471C863,E2A2304FECC46D9A,536F92A6EE9C9EEB,6085EACEA2BA4C01,F2ECB320D7D183CC,769812A22771996A,00000001CEAEE6E7,E36735EC9FFD4CDF,0A6318340C137F7C,32DDD0A7FEFA0EFA,8FFF02C03F11DAE9,1FA6EEC013AB7DB7,A42F002CDDDD5F91,8B105763550593AA,F2EF0471CB2AA23B,1CDCB832F3CA1B8E,000000012BDE63B3,8B7DEE7126130871,8B88482EAE8EE926,53F04590C5425FFF,F8936177235D649F,C08B5ECCAC0CDF6C,DA6BDC80D146A478,6D1AB540258119BC,61EC389E33586561,BB8AC998C8196EE5,00000001357C16F2,C100AC64C0D1F4C7,F7EBCD5A8C1FF86B,66B73FA1389DD557,3C7C3EB9AF4C14E3,FEBA4DACF8197433,9CDD62D0F81A0FAD,49D157FC392DBA0B,0CE0BC5103E5B8C2,DFD276CBED233960,000000009465B6B9,E185126503479DD5,865FAF7770A3C3AC,44335900B29935E3,DFAC7B703C87E00E,89379969255CCA3C,7BB78CE7721EC6AE,5057FD4BB534D581,52673729FFA9E8FB,2CE3C05EF9B67CDA,000000023E06D9EF,9C8148FA67A2F6EE,D08C2FC7AF76C666,7F4B8DA8C2620EBB,D2F46399E223F08F,697C4AE1B07A1326,444B229FEE7A9172,428160BEBA4C5EB7,1F3E726E594945CB,F47EA30283612E86,000000011A3AB956,C2C16CBAA34AB090,FCC352A16B82C9CD,8B4DDD40392E4641,11DC4AB260C36AC6,8F57737556E59D2A,501E97F2C08D445A,B4A4DEEC6BB36824,496C8814C9B2C638,466B2528861294FC,00000000CD9587D1,29FADF174C944585,66C5A64D201341DC,7DDDE25A606A4F43,075D76737D7153B9,136F3B5329B9311C,6642FC280013C610,F104006CC8A62998,315671A9DF05A0CD,13E2ACD3D37D958A,00000000CE8F5843,4460AE2846EB7F5B,CC83F525CA107555,75B4BE86586DB68A,7EF736D70E3E7B80,82E1AE8C0E4C57B4,589B1C9DA28168CD,96EB49BAD7E11761,1E13E9D47B6AD6EF,F7546374D5B312D6,000000023994B83F,1BDD0C3EDB4F8C6B,6090F422C5F518CF,759A88EEC4DB5E49,BDB6265A73E790D4,7C2DC6F1898FF0DD,9389B611376CD7B9,86490C58720FABC9,7C6F76D4F0004964,E16553B44B844B5B,000000022E0965E3,A8D8E0F3E097F444,52CFC561AD0CC649,25F90F7DD92D6358,38D540E1850A9CB4,F15031D08919900C,7F65843F23F5CE13,D4E1F39712612E06,B636310E2231C4A8,E3784F837C0D8524,00000001469ED469,AB39BA4AABE82C69,AB712BA3A33B0BC5,8909DAA0F66EA5CC,0C362A9B12EEDF92,486052EB44777DE0,917B7A58CDC65C94,367345AE23AF9538,EEA07AAA500BD330,5A8C5F155C1B073A,00000001715B596B,9DB7D19420CD0570,E224FF0FBE270293,6ED93F43B2E232F7,FB23CD3B82913196,0ED4C14A46435A20,FB58AA86936EBE67,B3EB5CC352B69407,9100E2856F015C0F,F648EA43570B9486,000000020310E6C3,EEFA1E66404A0BE3,4374C345FFDA8C8B,62FA3B244DE1ECE1,9A01F5604153E2C6,F5B9ED911FF8D7D0,F965D66AA58C0ED8,2A61C611BAA5CFED,6DBA67E08F7E4104,E4756F3C83E7B06B,0000000004AF79C6,A9EF563B9EAA4954,26F31294DFEAD430,7BEB225208DF4D71,D1CA1CAC39393B8F,3E8FE7DD00E06A60,3FAEB637369A6B5D,4F8E3C9F4B1945C9,80B12C82D10FD6C0,FA06F2E6792ED574,0000000208C59A6D,306E30A791613F49,3E869A399173E223,2FB6354BF2718495,131740C8195898C6,104C178FD1BD13D7,DFD07F5E4EE3D17F,BADA4A01D90A3558,346465575CE9FD3A,3CB1EF3FD7A24E5C,0000000035EC460C,C840316DDF2F1AA5,E8C7688A5E064538,49FA91233CB949F4,892C8544A917226E,D7AE5521D7C71EBA,EB90F6E398F3EC50,A1B9DD237C05B968,D45415D2D28081EF,D7130BEC1B89D72E,00000001A59A3B1A,FF5381177339AEB1,00D94A1DF8D79D9E,78F00085F995E492,A2FA05D933D23BEA,3FE46F29B04452EC,CB138E646DB79F9D,3A8E56ECC12B4CED,D3AB10937D3C4F7D,8A875B8CC479922D,000000020B04BD5B,BE99512CF5EA36CF,CEA41CBB15E30BBB,CF8CD8CCAFE207E6,0E47104E6ED2AD9A,CEFAFE7DDDCBA3ED,19B1B6D47A45D055,31EC6B1E2DB8C29C,2E62C4C21C39F656,AD00A00D957FE1EC,00000000F7C23FF4,6FE851DF8EB17E6A,13B4E1B9EB7F858B,1F9376EC6284D7A0,5C6583261B794D07,0A0790170F6BED14,AFA1ACF049B38FF3,A06B3C9E55509718,DE6BC7ED72B0AF3B,5315E03B00E95B27,0000000100EE57E7,3BDEC94815F26F23,299B0F70E5406EE4,B5A2F100567E49A1,00B3F5A06AEF2DAD,77EF63FD801A046D,DF5542E72038BFD0,ECD943FD579EB11D,F0174B9FEE12F6C5,7DF17DE1E43F26BF,000000016AE7F90B,C2821D196B7623A0,039E21512A84EC01,5129944CA0F1F3BD,98979488A018475D,6A19A1D65FB98BA9,D046B53A76AAB27E,4A28785F55AD94C6,D02B0CB1D38C1EDE,54098AE3592C98E8,0000000192180B6C,F109FA8BD1FAF6C7,B5122E99F751A36D,50CB64709A59C710,9853E24772980799,31A509B2E2849F21,7408ED7998125284,6E73B08D1AF32D33,C3E214ADC4B01B8D,542B5183A183775E,00000000DF710240,7780CD909A542CF5,B500F0F0012AC04B,96D0B40652DB1EC3,E72C4550678D598E,91140617DC79D921,70A6CD63E0F671BB,2E3819529C69CCBD,7EA4B526CF6690A5,A599DC16000B6DBF,00000001597A4DA9,B923D62FA81E2FA5,0A789B93E05670EA,62536463D1B2B142,32039AD58AAC6AC2,D36D402BBED167C9,7CC8E9DA84AE8ABA,DD22DF909685C503,D4B0B1F679F5CF8E,DCA26B6AFC323987,0000000102AA364B,7AECC882ECF0E5D0,D1CEC6621F240688,F455848D4E13EA26,B56A52479998E2AD,F5AA7D005678D89C,17C85D3D0EB0F9C4,E2232690698BA9C3,61266200F8A4DFED,AF0E337C28A60617,0000000077A99767,0D85FC7932900B6D,E1EDD21F2ABC0214,ACA3A473973E257F,BDDEEF54C4E30ECE,BD619E93B866AD5D,6F9282A187A1DF9E,50FC3C1B66A71A28,4EC9B1AA0C03BE03,7383398CFDE08E3F,00000001C971189E,D97126E8BACADA8E,B4A656CA7A90E9AF,76F0A46814BB7A7D,ECD609E1A9A4C0EF,A33ADF4CDC85271C,D565E22C8A65B176,729A148E01D58F44,F11AD300808B0942,12D3573AC086F8CF,0000000185FCAC28,F7B04EFB9937C026,D1128E5F3FED0AF7,5E0CE2BA26F871F0,D139E37A7CE785F5,C9BEA6599774C2CA,78291F7034D70BCA,846B04B690E34540,DE99A2FA0A747486,6F93E503C7678285,00000000B30642C7,4FAF6528C193D152,AF6C5FC6566A5080,F98736ED970440BC,8FB4F795597C7441,4233E099087217ED,534B7C4DC1997E51,8F022CA0A1E64EC5,7750B852E42E8417,A6FE586218C92091,00000001840C0732,FBCB387BEE2777C6,72F151B77D2D1854,F17E1716A4660D77,0C6037CB423A4EB2,8DED0400183FCB9F,E15C733380212139,86ECC8328BC1ABD6,8C2F6F3BC86CF28B,6014EF339F389E37,00000001DDF8686F,A95370260C390020,A6FD29D04CEC6D87,240AED21F0EBF971,0BF311B1F10AD195,42F356B9ED6DAC1E,854357F82061B602,10C4A12547F9D236,98513D90C64347CE,3D66A5C94E6940D7,00000002709070A8,8BF98960823758EE,A4734E06C3302367,B418A1180AEFA0DB,60B93945FAA6E7C6,08B969AA934DEF48,E28FD066D277D2D8,ACD6173E430A5172,79FDDD26E4C7B2C4,ED68D96324A9ED01,0000000002F7FBE7,5FCEE40E9ECD5FA8,9B2F415A6DA02869,590A6465A974F1D3,E40F2131DC0D433B,0A0ED50BEF72961D,AAD565A413F7257E,53B4F36BD334BF31,D579548A9707FF61,7D295156F9FB8ED2,00000001DE2541C9,09B603E9407FBC98,A8F25C14035D4A16,48D1F546ED03006F,55E082D87632104B,E6BBBBC8EF5B20FF,559443C566599CE6,D880602D788364D6,CAFB1FED0519507E,7271325AB1C48304,0000000139354DD8,B422EE4B4CA2172B,FF4BBD5C3C469505,3B5BE668B3513A66,2FBC1A96DCED964E,2FA69AB457C68377,51464E93DF50BD73,DF0A5407B147F7BE,C8FDA1BAB93D0794,B30F2941402E05A0,00000002182B6130,6969310788F6EB90,6CF2E673DED5601C,5FE46B9C6BDCF025,73B3CEA3914151B8,229AB91F83A52A4F,06A10A5CC9EA4599,F11052D58C791795,15049F721FC0D33B,F45040C00F289EB3,00000001FDBFD71D,481FF49D41A434CD,C2C56B6CBB1F043C,A2F1B7FFE4F36C2A,54EF722AB4CDFE5C,F08792224F41B208,B2AAA25FB49FC28F,071F245699A28D14,D6DC61CEB7873328,8CCB98E94B889A62,00000001C90A596A,67A903400BDFF235,1FBC62423E0E9FC0,1C31B470ADEC5F5D,6DF9515D1271BD8C,96C7259D7D9CB91A,CDE9622F40618784,8E285F18163B0BFD,E70A226B965D3960,9C4A1AE8802EA12E,000000019EA549F5,D491E4FE35A0EAE8,4103769B94F39BB1,EDB9ED64F133F454,FC8F64B461991B55,6D81F1DBCDDF24AC,38050EC765FF94F0,BD5A10B444B5C359,DAFFD75CD3BC9810,0A6ACFF71A5BEE48,00000001744DB276,D4388E7D7E7E0150,918685DCB2CCB470,ADAF3946DE3AB538,0ACFFC5398781D01,7E166E10B3B26EA4,3F9A77BD15DEAE57,C988FD340556C9A5,C1CB5DF1EBDE584E,037E28D81FFE8218,00000001363CD323,A768B2F8ED8EDDA6,84E292174F4F6D6C,E266678FF1AFD4AD,D2A33128646D28E9,CA83608113EFC522,94CB044C01921367,A69723BD750E8001,BD68323D76AE81AF,99BC735FFC75214B,000000025A084AC6,C314E6AADB64A8BF,E5971010DF7F88FC,7668C336C3EE985E,780B4F28F2D9F22C,19B0A61B321A51CB,C302E601D5C7C21B,D856A1AE12CE01A5,A123002E7B9E59A2,3B02CEFD8459D21B,0000000234820E42,6657ACB159DC4336,B635E277C5774E5B,9B22957E63915584,4AD059229349B122,16D4D0790B435B5D,B8B27B648D2C0D9C,7C00C79D524343D5,8B05DBE070EAE46A,220537D485C42BA7,00000000DD939157,0EAD784DFEFD94CE,1BA3F79B854CA45B,3E3A4AA2E1169464,FDF594645DDD46D0,CB4529D51AC85ED1,1FDD9C852355B900,2D9CEE2F0672CB89,E5BDF9C1376802B9,0335BAA6422A0CA1,0000000070E65014,AB930CDB5AB319FB,42CE9883F08BE34B,9AA8FED1FA108FA2,5C750D054ED8FABD,BB1B07DC57DF96C2,C8745EBA504BEBC4,A1652B093063D672,6018ED7E55BAFAA2,352F0CCEAFFEF882,00000000F8CE858B,B984296EF2490651,471F27E57A3544EA,406B0198CD47EEDD,124B64A213CF1B78,1A731BC5360E7741,B510D5A86E3269E2,8CA98D70C6B1FDFA,AAEE55EC6A475195,207037F4E3F7B2A7,000000007D899447,54217DFEC7372498,91ABE69D7C548A3E,193DD07C975F3044,F0C843EA68EA004D,201929EABC591D78,482249799DD5FEC7,C4895D970616FA32,82A4582DD087AEFB,29117F6531A5D9DA,000000020ACBB493,B7BAA57BBB5DA085,B95CC4CE38D8D52E,7356DD56AB2CFFCA,9AB7995B8FACF1F9,D69D59DFF6CB3CAF,3C0D7276C62119F9,D15214F2948A2863,52A233D9CB7005AF,3AC05D35E1BD05A2,00000001A737CED7,0344F509A008A821,4DB2466355612E71,A3887B5EFE979F03,0C621FA4A5C846E4,1C04AEB698946646,0B50C3D53FA05831,096215F9EB575DF3,A33ED90249E6A4A9,2CC9C6E4056D420F,0000000181663FC0,91ADD4784B3D4FFB,D6B459B42ED072DB,0DDF89D13BCEBC7D,3DCA16F84490FFCB,258F23C994076A90,88E8F18F082D5526,B413DA6759F9041D,2695E2CAB6DFEF00,4FF709C496C95EE2,000000002D0BF4DC,AD9AD648BF45642F,90E65CB4E0C77678,0275DCFD8B3F7429,91A43C0B79F550CD,E454CD8F75283BC6,AF87833E670DC6AA,57FE1211B64715CD,A84F3A62CBB30F47,33CB3B9A26131CD0,000000021E0AEBD3,5EA05C20A492C691,38F8F6CCC6F8B541,2FE56B5931A0C6F1,96128A966BAD3CAA,21FE0398A0297279,815AA270023E0C25,7E0D6703F2F958B8,BD84E3ACBE653F82,79B66B9210F9ED15,000000016BECBDD8,ADE94821B7F09F56,6FDC91D5921E818C,73DCE9C643364089,217ED8C120C8ACDA,C0F64E29286BC380,2741DE1FEE05363A,E5C4A4E3F286D9E2,8CA3D9240EEC1205,295DC1838C4A8B45,0000000270C61A84,C2E38BBE7A8869D4,4E7C3B13BFC4F850,9DAD54B9C65CC4A7,1F3402CB955DCB95,E604651F23DD5F68,E80F8070FC4AEA98,735F2C5C11008DC7,2626AF349DCE5B80,5314CB1690FA7293,000000012DE06CAC,27E9CDF72C507E15,3EBF6EA50D1A9F4B,E7DCF27C3DFED1DC,5D6574C21A108C7F,394F5D55BEFABCCB,A230E4EB2FE79385,8D344F24E585109C,54FA1CECBBEDE429,90B810DDCDC82BEA,00000000CC1C5226,645BA26959D94567,41A07151F49335ED,2039169B31991935,DB7EDC51268A82CE,F7793FB16F9012F8,89F1771068419E36,272EDDDC09D011F3,33A29F0BA86C1688,1048F9DF263AEB84,0000000103B4FF24,AF70A88788937726,BFC68E618B2E0AD4,B3152B2EE5D7B5D2,70273059BB3F4597,B81702842D4EB8AE,DA5E8E5CFA152E63,29108DFF7F03DB01,B10DD63F9631BEE4,D0B980E87E095ABF,000000000C6D9E1A,5C39DB577CD8E25A,B053D601E92C7816,D0C90B16E3F57AD6,6043C33FDC100699,CB3419F6FFA2F89E,B0D048CD52696A1D,9C38777691B42D62,9A6F7D14E3F4B0C3,9C970976ACA9DE31,000000013F4E61B7,1A43C2339D92677A,D229B59DCF03A062,C799383CFA62152B,561AD6F326EA4528,7F792303A3FD1BE1,5B7DE432C7F902FE,ADD84DA223EDDE96,B59D31A1C26558B9,3865824325C7412E,00000001BE14C227,0CDA664197B41B01,EDBB199E9398C305,109E1935A3383CA6,3E07B1F420E10A44,341CC828FB7061D8,70431D613624A852,4E33CD6F195A5D81,E7C14D8BF9DB482D,017E53D9A30956C2,000000013C07A315,325585EBB06CE50F,B33C756B795730AF,B444E3A447416A16,D6271B9A11AF3264,D8E83A3FCDD3214A,F37CF90C5653E72E,A05DE5455E625AAE,7915F2F21979ABDF,2CBC50A1CF3881E2,000000010C5D6A07,FEA464A4716E6703,1DBAABBCCC43CCF7,C8DA0D9C0A945101,A31ABA4143FB5AB0,B3584F874AA01993,737FCD2389EE58AA,487FDA299789D165,98C0F4DF5F293289,47ACD571A92B1345,00000001D25CC71A,FCC5300DB55595D0,032E63EEB4006A44,78C0F983919C5026,0CFFBB2E9940D813,F1147B481B95BA21,4CD2B2F251660905,3D1850249A03C966,6AD54C14ECC3BDF2,DF7EAA7FDD98F106,00000001053AD3D6,572BBB58875453A0,2646FEE34CF69B91,2080B00CBF542787,B6062F612DB22589,275BE404C6354655,6CA77397EF3D14E1,0B77E472041DBED8,6B23EAD82F53E5D7,E1574106D326FD01,000000026EADA064,AF273391FE5B93C3,8975B431655F5A8F,CAC7E8217790CAFF,6DEC9D4033B71A61,65EE1DFA0E0ED2E4,6E0D799E0DE4A15E,3555E01585D52F19,3A08F01B4361491E,E6504A5F43310942,000000027A21976D,097C79E339ECD91B,2F0AFE6B3A9856B8,23E92B9418DBCC73,5FBFF4D4485EF600,E1C3A99B1D0E9207,AC3DC580DDB55604,F9160608E5C18E1C,4063BA68F41F2D5F,D81BC4F1F296364E,0000000142F1A009,E4B0039CB8480392,B0BFBC0EEFEAC205,71E3E3D8F81BC335,DDC78CE5513925A6,88780589FEB5BB30,297D91009B9C0BD9,F28A0CE312791A99,7180A7FA0DBE5FBA,C0CAE4D5CF25C7A8,000000014BC1D6D9,95251DD4D6D6D81E,ABCBD08328581768,A8D6217075110F32,3F3089B88B89AA9D,15904F0D36E5701C,FCFA2974EA2CD2CA,6BD1BB2C3A334022,DF5DB0EE8B9284B7,35E78452D203393E,0000000080432852,7CF7B47541A34EB0,7AB60119D283412A,711CE5C2271BF98C,F2B954C2BA7A425A,2C7C14552DE25BD4,0C89613379358A32,CC227AD4A516FD77,A4FD5A2C76C415D8,C7AF77834D6D7F5B,000000011D1C1DA4,3AB14D2CF4B310F4,AE2DC828B3568515,420AB7350BDB15DD,BB128AE35AA69EB2,C16312A7085219A1,F3ED697E10CE8841,C18837CAC9108208,749C59D72357BB1D,16BE27752AFC1B14,000000026613BD76,3FE5CBFD22396395,39906F9244BDEB27,B892D5406459EB76,3995D4E861D3C0A2,2AF7A5A6E93DE61C,BA5C3777516D3E9B,FA51824AE357B624,60C102B4D29D3653,9120A3F74C45ED1B,00000001AC92310C,A54ECBBE37F7AFE7,D0E968A6978315FF,1ED2DF526EF32A8F,34E7D74AF7508FFC,442F8CC3DB0D3413,440553EFC01E0DB7,65B5D8EB5908C71A,48668C24A947C8C1,711E9638EFE40EBC,0000000223E4006E,2ABFEC6CDBADFB08,ABD9EB6F1CE1619B,F2959E2F7D7D456F,A5D11F4B26B4366A,FE3D9B6B4F68A7D5,EC051BCA85A97E24,2AC3ECB797301692,B826050F16BAB94F,6489CC1F0224D7BC,000000004F5044CF,007DC98C9E49537C,3449871E3AC72D70,9916F282969B45A2,999314C5A3E3BF3B,1B83A42A3155E148,F8F5DCB2032525A4,C1F32ED8CC48E343,55E9DB7849C00867,0C3B07D9402CB638,00000000FE8A1118,B90AB43DA43BCB18,8EF3280BF7C2C700,B1E8144F25B1610B,594CFDAE31A8E6E8,8602B8333504A63A,792CC5F0BD46E8DA,A84718145AD30A28,6160A5B432878B9E,5BB32B0F2B52C494,00000001FA186DD2,2BE326272B782997,638712B7BF460538,3A6ED25A9B380901,2D22F1F97A195A9A,F215C31C36455792,8F95DA1F2909991D,4364E0E8AF9B5EA5,65C593981E2F6F1C,63F634F2F406277C,00000002368D7CFB,D417DB4C3011A1F3,FA63AD4A307A41A4,14BD2A7717396767,B3ED973660A10947,7F5BC5BD4B93974B,16F4BABF8708FDE5,96C484DF3A225DF1,F6727BD7EEAA242B,ADB4B9D92E77C97C,000000018E5C4C5C,E048AB36BDA4A72A,4CC98CE4FEA5A195,25E18E72416A97FC,82F7BD43CCF48278,7DB9AB3EF153507D,CCA06DC0909A1049,18D3B51180ABB3E4,E97E6B7E10EAB8FD,51E731201BD36203,000000017742AA5E,E74D78159501A97D,3B4ABE10A98723F9,E4E5D5973DB1593C,69A7064BED6436C3,64A4DC44A9260E7B,8A3CBA5F5697E8CE,B0C4FC6A02A2E48C,EF6C2603FC19B582,0D8E7C600F6ABEF6,000000004B100F6D,264A5FF9539B7B9B,8E75D0907186314E,A1FC150548490FE0,C9E32CF4E422EFBB,F9AF4B4E45EABAB8,5D44FE4DFC069B31,36EED61BB905F044,BC56A486D1E5D941,CDEEF305FB62F03C,000000001113D713,242D348DFC95DF41,5736B9DCBB1A05B1,DBC28227745CCE4F,C67CB217052CC2A4,72A497A3C74700BC,D5B0D7EEE964C4D7,D15A7D95EFB6DCB6,E7AD3860F2B3B11C,00D138059AB71329,000000012EA30A05,B9AAA28FB97E8E8D,6FB9C0ACDB608989,BC73BC420D696C3A,CB5B634E7B72AF02,3D76D41E337B5BD1,D61A6134273978C2,546A385512A75B09,26B87F363C92F2A1,B31883862F9D020B,00000001DFF69289,E69A1EFFB1C40407,A01951D316B3E6C6,E4AE0AB8709E9C49,C0575619E6A523D7,D329748051DF2297,2458AB08A42EE438,5698872A50447186,60647520CCF83E0E,837A036B43E96922,0000000225C57139,1A4E605A933D5059,4E28EBF221DA2A89,DD8C25DE47B8B59C,7BD99F6BE812D567,85E3F4660CF2E7B7,E232615A14B34E4D,6B88E649B171A7E6,4BACC3DCC3B7FA02,4277FF784E307D81,00000001B484D3D7,FCE99EE0C6F3BC0E,D46D3F4913578ACD,CE1207FA123EDEE1,40A611F448BAFB1C,9A3FC84439368ADF,22B0DB85F64AB1F7,423F6C7A6E0AF148,6EDB40C2E977DE64,BBE0D428AD8942CA,00000002783408E8,3E9DD55BEB43B90C,59DEC7F062DCE6A3,5B5BA596174AD2E3,B81ACEC413677294,175FE23AE2F49242,6D6773E63BB8AB69,2D1AB336CE0D08E6,79474803B4D468A1,10ABEA4534B818E2,00000000F2664FC4,A45FEDDA23227835,48CDD22293C70A6A,976C92A9AA674071,EE7AC22E3F6C4FC2,F1680C9AB06A7A5F,31D40DE3DE3A0B61,C7DEA352C4CB5D33,635959B95E78D190,39DF17F414889354,00000000AC54579E,B90F214D4D631150,071C53F816C16845,804DC156220335AF,E4EA54AE47A953C2,4ECD3F86ED9FFF84,FAC8C3FEC746B547,20E71C30615A3044,0BB41C9BDFA3EA9F,ACBD0B1CC9263EF7,0000000278C94F19,092A2E01F4F6A70E,D6632372E627A8A0,CAA37A9E5A822D5F,43526199EF0C335E,EB5BBB0E38BC44C8,485CCC5A45681E72,20895A83EDBA073D,4FBD984D1B95D0C0,3C77DF176165E06A,0000000136D3460F,77B4FCE812497542,65155A026E0E6B07,184D1F93803A994F,852B6AFE8C04F621,461CB9447441A1B4,C66631E4D57E53C9,0E155D8F52204A91,CAB956AA03F6183A,E78FE90BE4B132F7,0000000068BA5367,2978EFFDB77AD745,3CB8D8F77D0B5D53,8BD1B6AEB7E09518,AA6E36643B11658E,077D0FF4BE65AA94,729B8B045A604CA9,D8129A566A2C3241,94564FF0880D7E51,A908AB103EB174AF,00000001B9708D6A,9AD86F4987681581,AB093514C0545AD6,AC95B3240A45AFA7,DE3BC36C1885A5C4,C71EAA81FF8AD301,0DF112FA9E9E0661,E4EE0879C39081AE,D59F7137B69B1B16,05B2A30C8D471B44,00000001AA658C9C,478BDFBC261F4707,01D32107F5B5D377,B766ECDD6ED3EF29,07C2AB4A66FDB84C,76BEA4D4297993F4,63FFF53964F8BC97,991EF2F83B122233,27FCE952D4E35673,89B20EFC6B8B3E5B,000000002DACB100,7BDCA97B1819F4DD,8176F1CB56FC5EF8,0ABC521A8B24FAE8,2767E7C180FD9146,E24E5CE37A86A319,D4ABC0A64825610A,FFC68A68072FB6A8,E2543A35CA77EAD6,D0DB7AFC6C01009B,0000000177C91F01,FAF7F11B20E79A5D,C23647D971161432,97BD5BC7FE43F79B,6988DEEF1083E0A2,E791F6565542414C,921A3FB65E3CAFE5,462866BDED4184B2,25B221AA4B016AED,6EDF49138702B4A7,0000000090921131,DE88875E2B614491,42B0E8C044668244,E40ED430B8E10244,55C6F75C1352543B,D302E8BAB70FD137,712E688178E83F7E,63BF20D81FFFA2DF,74C86989DEB26382,1FDFE6A156B9AE89,00000001907CF163,673446D737077924,9E7CABE786B70B5B,2C7A72758F92B5FC,44DB91C6CEE4414D,FC0D96896F4854D6,A3405CCBE453AC77,C47ABC28D09EFDD3,6B8D6A0558903498,738F0D467219555A,00000002762A443C,EE4EC1CE43152D5A,CCFEBFBDFC480CF7,F3EBDC1FDE20A3CF,920A57C9CDBEC751,A69FF647CFCA7679,6EFD66557F75405C,FA965CD23FDF8E61,69059D54855527D3,FAAB524610E01E2F,00000000B3A27C84,E3C0AD3CCD0A7411,EC3902220B895A5F,916663400FF30140,933EE248E8B7B557,AE78E2139265001C,7E9F973B7BB0E408,89BA8F3B12DD6A0D,A12E3C8A750CA323,2D5F6179540D8BCC,00000001DD2F7CEB,4450E34F06CBA34B,C38806FB7B9A9D4E,ACF870ECCF075A50,CCCFE2A7440FBB40,97852CC2C700AF19,869A6BC54E1D1A9C,46ED9E056110F0E6,9E08D0CAC13A4CE1,CCD65045F26B0EC6,000000015562829F,2FF010C963F57B25,B8759B75CADE20DB,0FF773CBAD44B77A,0356200AD46666D9,AF155688B2CEC82D,1CEFDEDA19764CFC,D73CC5FC1E69A64D,3817E76D30CD6814,E5DE8FA47A0A508F,000000019B3048F5,DD66A20614F7DF9E,C0268F9C85CB41A5,80D5CDF380DA898D,1A8A2E3DE3CC873F,DC083B3738EC8BBC,1973E2472438E94A,FF7E63440E47902E,EFDEA39E179581F9,9697258273CEC893,00000001C2379B8F,C1E432814A80B33B,C4755529CB7A1C6C,ADBE4E39779270E3,DA918604C3680067,810CD3C95FF9DE19,AC6B55F525AF6E10,4A44716288ABACD5,12F774E364A39681,0225BCA5C748A4CA,00000000F4B2A771,1ABEE94E2E67CBC0,3D5465C57450D44A,EDFA46429DD84A33,D67886289E83C453,8781EA85BC711A54,DCCC030AC7921934,8B329FE4DBF08C7C,19AC58B76FE7E16F,22E3941032DCB790,00000002783818EB,1121748C14E81506,3BD79E31CCD0ECE5,353CE22BE0EC3E2D,2C2118CB4E71A4DB,638A21B7E520A419,5FAF7154D45093C2,4826A2AB02A2DFA6,29190AA5EC315D55,38824BCB88200471,0000000090E93516,743E26648FF63FBD,D09EABE6BAF23844,2469248A7A4ECF30,496678212F89D042,03A1B09AFAABBE5F,B98A0894A8939A9A,EEDC86BDC09645EE,E640F72E9030BAFE,BAFD098B1FFD0222,000000007DF9CCF4,E4E88C93B491BC24,A36D0360DCF8AD93,4FBA995558BDB48B,FCEAC4F51CD71D2E,E2FBC26C2213A352,4BD7328EC5FE89B7,8F62813441874B06,B6EF6D4B0A5A2F0E,C27D7FFAD4BC5C8A,000000025F59CB77,544580F8406D98E1,22E2DF0809FBE2E3,5243BC57C98D48B2,83B6C24795B47967,CF803390F06A3876,0099858E908FBF79,1FD47EA8FC6F94CC,1C42CCE700515F35,CD04D378218CB13D,00000000199623C9,64723D4B4CD55046,7FB9878F9D828FB1,1224C91D9687DB05,E9A7D53B5897C8B5,857D64874ED8C689,D9E1A6D051AA334C,BAF50A3CA2C07245,62203948EE9EF8A9,40CF4D6CA2FE341D,0000000133D83F72,61831C5347386148,A6FC78B710E04CDA,613530BCCFEEA4BC,33D7B783B611D9F6,A1A26C09D6860C4C,4A82DF1D1CCEBC51,A28F0DC42BC89B3E,BEAD6C545769351D,F573946F6478C66C,00000000C9E9841C,6DF28ED7E5264504,1C8A601538C33B94,E1AA664EF65E5F2E,CE285AC935F88E77,BC0EAB45852AC024,0F8B26427CA5EB6A,B43643F3F778A659,000F9E12A8A99DF0,BBC2E9222A961504,0000000061A20D6A,B3FE84A5FB13F42F,29D17F19B606B4C4,CE33E10B3C44467E,79F67B8E7D58CD9A,C2F0E14D64C27034,EF9A2171325534E0,5D2B880272606552,50C990F820D7F3F6,B86446C67C9F539E,00000000F2202EAD,BD78F5F61C574E45,CB0C51D021044E66,A8927C5AA4F46CA7,34D50ABFEC2FAC6C,233B8DD93E2967D6,9BB6E7249B549526,E9B1562A67855D7C,1238F63AAFC51DB0,76AFDA7015C439D1,0000000019C4E2E2,AC3A70AF106171F0,0F41C36764024DE0,2B778FF07EE3F476,DEE1B11915A0A795,7E81285FD2BD17C0,2B9A56D7B2DF3E8F,C1B9EB3661B87296,E9A0142106C93D5D,6D1DBDD04D77ABDA,00000002170B15D2,229D51264F404458,A30A5367A18C614C,99C827565210E7C0,DF5CF896D99E1DA2,B153AAF6EE3C4761,4C1E1DD0B66FFE2C,246CF74255E8D19C,A9ACA644BDB832BE,6700217B72B3EA2C,00000000BEB4E7D0,2AA54DEB72B5B463,4E3960E61BB7EBDC,F8AD1FDDCB603FB9,59EB3D54A4675A86,6CA5F0D14799AF86,8E9FFD57720C32D2,6FD1595F822B9F93,CFECE10AAC68FDA6,25896263B0068DDE,00000002635C9E2A,F05A712D8836BB64,A0A7FD962E4C96E3,50DE2BF56C971DF0,405892644D4D7973,ECEDBECAD4DE2E11,3DF0DCFCF06C7DD3,9587C05712B64112,1615652333805DA6,962B89FA37F905B4,0000000236AD9B5C,43B0E674BD5CCF4D,270F51AD589477A3,6B627AEE106C22A2,B498F15FD7E2BF86,4391FECD9512945D,6F0DE5B434B45A5F,D91B359A122A1CAD,472DACB9AAEF7161,DB855A8A9367DF16,0000000115AC0EDF,17EA99D9E544D133,D9B64792C5801897,8F63EB0CE279B6F9,93D4856E18712375,CF73F6F77C5F8A34,689AC81FFE2374A9,7A55A5CFB1FA8FDB,E5B64A7C570CDF3D,3264BEC5FCF81A82,00000000283634BE,6493F86573EF581B,2DEAA46689FC406E,1FFC92E4850CC7C1,F1B4353362A10423,DCF81962E9C38D26,EC7E81394D30E381,684D610F6C96B391,C8EDB34154D60A9E,F5DB0C967E3A7D1D,000000018D452E62,3B50080B71F7E978,77C4ADE26DD5D929,2186149241A1900F,1B4294200D2E4D45,8E4D50F115B201EA,1EC82966E9A1126B,13268E3E267C9E21,2DE68E571E9A2218,90D194F3975ED961,000000001068CCA1,9F0374571024BBC1,E06C569D8E207036,427720E06141D60B,A471E3E45707CB94,99900D47330F38CB,CFC49E55972EDBA2,DEB04C52C5FE6A2C,F575243918250888,CEF89A59E35F69FD,000000018519C18E,1863BDDD6EC8AABA,EF429E427913C239,8A72152E75D60A94,6489E0007C2D07B2,A268C3F788E649C4,8F68A7C19F3F76D7,A368556B15D4A7E1,ECFD5AEDE8035426,453D971CC66F7568,000000000FDD3B1F,599AA8CC02E5D5E8,604FF7E3AE5F347E,CA4E2CEF15CC5713,6C43CFE9E19B7368,B3CED8453BC850A9,5E49FC2AA6F3F1AB,15650661D61976FD,1F84283090762401,47027EE3A9925EE4,00000000A6B173D7,0B9C1D8B3A198776,1DC15A25A75B62CE,FDCCF667FDDFB86A,69B812C7BCE912A5,27FA126E143AB71A,962A4294128B9891,6D82BF9819219085,05E646BC650687F9,2A6CE9FF2E329B2B,00000000389CDBC3,759880F26310D71C,8C0E701582528099,194051880D146A0A,C9CDAAB16FFA6F9B,E3D6FE13004990C6,3E850A77ECC1DD59,E7C95C63A49F4426,4267B1D300EDB2C1,9764370261935BA0,00000001030FF826,E594B777BEA6654F,4EBA4F19A5256607,AA3F70EE7240C560,A281318C9779054F,F991D755CEA8FCB8,4317424F27CB8CAE,669EDE30CB54CEAC,BB70A598C0185633,FC1B0FDC27A138B2,00000000968C0DA6,7AAB04B1A92A500B,58CF990253789C88,150DAE37430E1957,B4D8C9850D29736D,1FB504F5D5FCCB5D,2037E0F5A6E40F2D,0C9F1AE12C406565,144699754D792660,AB9C71B56A2BE4C2,00000000B7A26FE5,8D9FE129FC746955,AF41F1314482CA93,3203C6A4295CCFAB,3C8995DDBFE3DA61,63A956B35DC3B14A,6AB4A83BCDF51AD0,1CA10FFBE86F08E0,CC0D3B1E42AB5016,F94D2E9EAD297F46,000000022C008DA0,FD2E3DE39D2ADE4B,DA7617B06F209515,35B0BD46E342D3C0,0EA90E9C1D0AA5AF,A841B9935C254AB8,B82E106B399DCB16,CA62C4C521A00FA5,1CB769D5D8395E84,661FAA84BAAB6730,00000001844BD753,19564650234693C6,7F21D3485F7BC969,32BB0878DFB32305,C321CAB5F85C6631,47F0303EBC2FFE09,E41A56825B01DB00,091DA9F3B87CF6CF,924861CDE2D976BB,04A3424295BD3037,0000000166162869,1CE30E35122A8038,D15213F976360E73,6C15320C8B102666,37D7746E258471D2,C8F31DCBF0CE54BC,DB0356F699DF3A07,149FAAA6EDF06BA6,A06C7832F6CB06FB,2D6EFE30B1339287,00000001DF57798F,82300D19A0D1CFC0,B01F8173D79897C4,7B3FDB54CB7AF611,A85ECEA13F7AE1D0,4309552B1AB04225,7995C5317D67CBDC,B9D601885A4A1C79,A30DD3A2F1A227B8,ADD709A290EA3211,0000000226A30C37,9F305DF38D4E6527,E44883A89BAD4526,B2FDB1211EBA2223,D59FF5ADB3063403,C29145F3B518A585,F5700CCB1DE31FFE,7AAD0D1466A62B6C,D18FB540CB001BC6,B0C2BA83D34A2461,000000022DCB175E,623B0E261DB94A79,CE2B10CAC65515D4,4BA7217A909B6DCD,9D46C14E15A6BF6B,47BAB4F68B05A51A,B0812858C162175C,34F299A3FB50E6D8,996A8D28EF5A4BF2,72BE66F96E9E0090,000000016A9F9D9B,C88688A2A7D6B657,5A07C2F8943D3BDD,586A6E68CFCCBA25,3A0DE7E4CADAFCC6,16FAB3A55B2F23B6,6B46294A3F25897B,B9D8E63A12AEAA74,5C098C229316C763,0B90830A6B7FCBBA,0000000097CFC1DF,252B777B2A0FA63A,C19341F0889E29E5,FBC28FFEC43CC3C1,7B4964FBA7075F87,AFBB93AD315D5B58,415CB6BE8A066E17,6F94856F2EC4DE4B,FB0DE4311CB92B6E,4DD55E8699FB5389,0000000120C94708,3D3E9101432580FA,805C59F32363F768,03112C6FBF1553D3,9B50F12AE501D330,9EB215A9B6BF02A3,507A63CBD2CCE394,3D176A50132EFBA0,9C53EC750CDD0ABA,140F1CEB3B23E8D4,00000000E7220D32,27AAF5BDB67609FA,6E2C7C71B9928F0E,854EAFE823CD0BD8,7671D1DF369290F9,8BFEBEB09C459C52,1F930DC0659F184C,66A1817FE5175501,2A12C9EDD3AFB927,25CF888DB32ED821,00000001F9FA97CB,82C4049DB85C7643,457ACA61944939DE,4141CE6A1F2D036F,63D6D15994352E3A,35F693AD240319D1,E40BB4A55DD69F6C,49C2790C5E2A9875,12AEF4C327474F4D,0FFD45184C2D4326,0000000163900647,8B8FA008EF14B6EF,51429DDE82E3E27D,12A6D6D6941F003B,01C15CAB863B4679,BEA6DFAB530E949C,EFE103829D8F185E,258D0B8CB203189C,908B471F854A86B0,1954141160CE63B0,000000016BF04470,B432DE4F0C4F5DBA,0DD882A4A2AB66B3,43D7E9169C12ECC3,7B4C02A95367F585,4CFD3095F5CFD8D5,6C924F8050A99B96,4D0C34B9302D2296,19AB983A55F4F3EE,C437805BA976D4A1,00000001D3DA0DE4,F791CAA769136362,FBE951D54B55110F,506FB3187369DCB3,2D89AA8454E0C150,AD4789D5242A225D,E1DC2F867B41CD99,B8F31CB67A87C024,ED12D1ED8441DFDA,AA849A73B2A73907,000000012FBBEE1B,E237D9D0899E35A2,96F4DE7BBE31B6E3,2283358338BA039C,67ECAD64DA193CA0,DEF7B77B80B24C52,642802D32CB48914,F476FE62095E40D8,83814E243D9EFB3F,710FEC5F7F79A65D,000000020F02E7F2,3C51130373D74A48,78205C019D7ED6CC,ABEF676045D5844D,6ECA0067888DE4FA,6628ACC77AF07EA5,770A1E639EE4762A,B81DF3DA926E4530,882659A22931347A,85461510E75D9FF0,00000000C5EBE86B,A56A9EED3392B26B,9B7A7DE6428BEADA,8787DB9B9DE2B8B1,6FF6A1BA9AF1C604,FAAB038A07775689,E9C2F82BC47521DD,A70619225A10490A,52C0F824570EA676,8CAA95010B119A96,00000000C4B31C36,FE2463D686E3429F,2F3F6E9DB3BE4AF0,9944B5E4375928BD,9458BECA7D736F83,7E11C20F405EDB8A,A5E92D8EB60F7C11,330F39AE362DE2A5,AFC44C33E3C70F27,B43207365B98007E,00000000AE2281F3,2308CF4A83A8596F,52DC0E473374600D,946FF6BCF102D373,189106EF713026F3,3633294EA222AF70,ABFF1FFA2C0EF93E,ECBE21AFFF505DF6,A8E4F37B2B4CCFC6,18933A3CBE16D5D0,00000001E0CE57E9,545A2E21209FBF4B,89181268D9FA762E,38CC8F2FD20676E2,5EDCB0E5C3EB9E18,092996A923F9A2C3,DE463C5940DA671B,9774CDF3D0B40440,618951B262A6CE44,A3270738FBBD2BAE,00000000914CE71B,79E500D0EF7BB5F7,B136161251C82B27,3CECF427474136AF,04CB525683D9C873,FDCBA468B8563214,4415CB37DAF2187C,08152528B90727B5,BA27D924B08D719B,E405CCC558FD4B40,00000001D2F63462,6641C80F3C39D820,68F81F5D19C78822,23F61F1164815F91,6952F434998A64C5,877853F9290D2FA8,5B5AB28C28BCE6CC,0D3B901FD9D60E21,850053694BAF30FF,B05391FED4661110,00000000A2DDF805,72195F0AF6F68CE9,D2E129C84ADF0FF6,BCA17815BE5BADCA,7330E20E22907C43,B99FF234C073606E,55DB9D7DABACC4E5,BEACBBB8EDD331D8,A424459967EBA69E,ED5C696537E57C91,0000000017ED0BED,C991E22593CC979A,F3B1FF9530EA1A91,87163E93C46C6D1E,9023352C7191692D,A18BDE906B55FDD3,FC8FF87D59375819,D73611AC00933CE8,EC9FC5A35B908186,2172806017CCA10B,0000000264C86290,438C46AA028B6E22,76144E705C51DFF7,58BBAE66BFC74BBB,EC83087D5958AE36,672D69CE57086A8A,F905262075C621F7,26ADE29282D6D011,E577D93DB0661FF6,865A045FD30715CF,0000000181F3DF87,D00DF487F148D9F7,B44AB019FE7EB214,2F3C69E65F728513,7F3CD11D8ACB5D9B,236A6695310E1DD7,965E0F66BEC15C23,FF7AEE5DB4A42709,FE2972C69F79B42A,BBBBD9C012123851,000000001B545D7A,D78EF261B0266B09,8102DA4007E983B5,7F660E31BCE2C95A,5B0730C4900548B7,258C85795FC4E58D,742F1125F6BEB012,23DA0CD77B520FF5,2B82C00521610A08,3EC70F15AB21E98D,00000001EEFDAB8D,672DC786B2A7EE02,B83FEF28723422E2,D2FD51A96163F2DA,2AF6C72492C36DC1,320DCA42FD152064,385BD2A6BAFF9F8B,FD7E07FCCC17D616,0D291D341BFF9E4E,588DF9F9B6E61AA7,0000000252C9FFE6,DB1CC408FCF2BDA1,0DF2223D043DFE78,B948BD235FEDA1BC,6ADC6DA366F62124,0FD6DC845DB64BC9,D64C644DF0CA42CD,CA43033DD2C98F20,675FEB0B011B2D09,8D85CEC7AD814D48,0000000040F971C2,B9D0859AD5FAD250,14E4CBAFBABFBAF0,F9DB8B42474EAA4E,6370F2A8BAF6525E,9800980D40DE2164,CFE45A26AFCF8DFF,E3F8F35C13D07F87,B782562CD8F55698,5F6F62973DBA3FAA,000000014F46BAFD,99C01C4CF0BF831A,F19BB16D70D2E40B,9F2D0F6120228C9E,ABEDF0619C9AEBFA,5FC508DF57B521F3,A40FDBFE3377F805,B1A7A536F5C20456,A1AF191F24E1D3A9,CADDA7D12D0A529A,0000000034E8ABAC,41FB8BE4C60AACF0,CA646A1BDF53365D,05CD337864ACA570,86FEF6025070C3CC,423AA07FFE0EBF9B,CDAED26AB8AA5B01,0F1B694ED01E163C,474E0019901AB1E5,81CC1CF3FAB9AB2A,000000009DF54316,9EEA22162B764B4D,FEE98A692149029B,7198B10ECA283718,ABFCDB0E0ECA2BAE,1BD25DD5CA3CD088,54DB5BC027F9393B,AE7D0B058BD049F5,5FD119174DA6CEC1,A1B7BA84C0956D1A,00000002633E3685,E47B86341D216057,E6AFE1B648607F93,19577C7086EEB557,373EE9E701C98719,7B0E97D71AAA1E29,6B333633B6B7F539,E3CD03C6E35C9C31,B8FD6FC3B4209B0A,E57CCD1F3082892F,00000000274A8A25,C7B5521B0062D4EA,E4C3727AB0C1F1CF,F909FD4ABBC35BEA,9399B3F92030B31E,3AF74EEA1FDD5E84,A954E2E3DD857CD8,CD49D44E883D5CFF,78BA6F8B57F8DC4D,849B9A91D2A95DDB,00000001E2A1946E,155FB56DCC956601,598979C36957401F,FC3DDDF80C6BE9F9,E8DD6BA442EA7704,D85227F7567C030E,5AD6D6EF6FB39F34,31B110524C09F75E,2D5876B80CCC79B0,08C050343BE9CF43,000000003FB32471,3327D4CE454EBE1A,B0D9FF9C3B3E16BD,EEE20C6823124793,E159E239CE69325D,41335CEC677734D9,E00A331A0D537B6E,988B9140A9C3F6E0,0A1B9D23780AA419,CC0C55832D1F0457,000000006C58B72A,115EEC99F9291B2F,45E0D18D3D9C87AB,D63660721D897B2B,8798D55379EDA9D1,76720B9FAD4BCC71,79603C6C39231DC2,E5239ED740E02F54,11D0BB711CC84AE8,3BCF11A9A234F5BA,00000001E5286105,E4324652BFB13294,970C4B6708DF5B56,0C93739B42741C97,901AAA78E78D889E,25F2E690460EA28A,B204E7A15D2C8568,60100E140479F30A,DDC78C8C27EB32FA,46993F1A1086DB3D,00000001914436B6,872C96C6D30AB971,03580B4FB097D2AF,214E095E35E4E9B9,C9F56EEF9AE34AAE,8A67420097220A54,C2A3D9DAA47C0465,A03B2C276043419F,C94EE1369DFBE9E3,8BEB931822399BAF,000000006C22104E,23977D4650363D12,D3E5A9B05099DDC9,EA534083FAF04E16,A384B5F7BBA0A810,F2C6529B9371BDD4,7D46B9DFF5D93757,96717ACFCFB5B060,AEE46F52E3C2FCD2,7EA7FEF79E7466B8,00000001D44F2507,D87CC9C303862398,D4F59D7A16AA8BC7,E0A3DF36D23181CD,B1C3C606B495FAD3,B5B25B73B5CA9809,96D345E483140ECC,35BEEF65F549D257,D9311616F8584718,EF7B69CE1BC51CEB,00000000F2015D56,85A97C2002087CCA,8622139810893688,161322C7455C94BD,D8CD7CC534DA9A85,9D074401BBE28C21,E5736AA103C96F6A,D33803DAAB4AC6C7,7C582C9072D22623,B1BFA4EDB97D4D6D,00000001F5E74DD9,C583AF900F8C67FE,797EEF9E566ACF65,19F0DD401F988767,7625E34E15FC70E1,5E3265876AEED8B0,907120F1D234C229,238079DFBD2ECD0D,36CB031CF020759E,1F4FADEF098CEF20,0000000144D4256A,A4EE9C6684C9C39A,E8BA592FA73EBC00,49624EC88B7D1070,06766AF4A3473532,76EECAE61D93C5A6,DDF08C0E504E7E03,7CCB2EFA26E8B40A,D5A2AEC3CEEA8277,FCD9B2EB3BA68E64,00000001E23FDB94,A574BD355744790F,8F2AC1B23ED9D40C,6DCF5DC28A9854CC,4E8D7D729B9DA84C,2886A79F7344C9CF,7779C91FCC95ACA2,818D81F909414F1B,A98082E7F47DE3C9,81C6DEC676E65E9C,0000000207A70463,757A568ED352E313,62E9AB846592718C,CC811E922888EDC8,2A665DCA51743D23,281945B273A98BFC,4D19824B3249C116,8E8F7DA73E902569,7AC91D187A693B28,94B75580A4C8AC00,000000023BB5F3E6,743DF8B0B8FD0BAA,B5109C4991AA89B7,BE922E60B2567B1E,9D97BB39F2B4AAEC,F0AA1DC5AD0ADF1A,6229F0FFBD5C5B4C,D9746FF701614FA3,895AE766DA17EF1F,B2B52DADB145FFA1,000000025133D0BE,C0FB96CBAC7430E4,D2FA4D8E691CA620,93D77E96617A43D4,DAD1D7714DEEBDA4,7186ADA1E0D6798B,59A3695E461D68B9,B63CB7132910AFC0,15704C7E198DA260,473098857349356F,00000000DCC77F87,3ED2C596671B6D38,76D9B348EF9A7738,18F6483892F71575,7CF0F76887383255,7941A6EF2C24CC1D,E53D313BBEB0E206,8E0BE022A0664AA3,302B9391EA9D21CA,511F24FFC6C69719,000000021F5DABAC,2B10768DAE727762,3213307879D2946D,64BB47F57D3172E8,9C67D41A86754157,6B8A5DB3ACF43855,901C3CE9D76000F1,9BDEB3D64B45374D,10DD0B8ADDE0BF16,6628600A96B8CDB7,000000023728CA58,B701ABC5FA25DC43,B7C5916144B1C8E8,19B0AEED1FB065DD,9374B33E83F78C50,D458226240178E22,026CDE8F74854ECE,4FFF2703D161FC24,092DB0F21A1A4AA7,748839CBAC1A082D,000000004B1DFEF4,A2DBDF7D121D523B,0F9D55C15DE4B1AF,7FDA5A88EEEB5F10,7BDC60899F28CD2D,D82A2112B03BF3DF,B7C188BC34323A8D,BFC2F03A91D189E0,7684A77661AFBA3D,BAD0DDBB12AE9A0F,0000000128F39DC1,2567703497C1DCFF,FA94272E7E2751E9,188A0B88F319A61F,D142412962A75886,ACE70FA1EFCF56FF,B7BF08CC81C7BDE6,A781189DF6EFA0C0,41231D267AB514AD,3375C81968088930,000000022A565F67,2E02E5B88A185305,2C79AE4AFC9E28BE,E366267BCAE8ABCE,5FC56A3E1F53364C,4C4287012D558503,511293761B4135FD,5A3E645F3FA37AAA,8149B6C77DB33E12,59189770B032D951,00000000737502D8,D8B5D60AE8976901,AC1F2A1AB0277220,1B28DAFA53A62C4C,84A6DB508F500AE7,10DCD6BB8BA40323,F83CEC9D8FD42F9D,EE30D81A9927A380,47622B4F5BDFF67F,2665C34BED79D024,000000013E8D99C4,0D0C07F41B2AD481,A7B876E48A3910A9,F4199DFC3B26E1A1,15984C18ACF60FD7,5F88F2C379EB7650,E2FAFC8450129914,E79B9FE188853603,E2D1E8BB0A2BE338,836D139671F79723,0000000251FC3DC0,02EA54B88D85296D,35EBF5286709C6EB,966A918CBEE3C903,3DF2EC8B7385B71C,A557062F3FE43966,1EC8902FD25E3969,D24FD90DE6F15944,00AB75CD6C7860BA,88DDCEDE4CC1DDC9,000000013CE5B342,204DB34C203DD176,DF6BF3572FC7064A,5DF436CFA68840EE,D6F69860E2B3A0D2,1FA0ECAADE549A25,756036F6E5FB8B24,F05409E3E2CD4D7E,B816E4E58F0E2553,DC2C9D0564B06D5A,00000001868A75B5,33C910012D6E7FC7,1639A87DD37B7F01,A33AE07057A90821,C26600DE98C09C38,E3854F4642DD1525,43FB10036CBC3691,BCA1F338E18B1462,C067BC297CA8B029,250AF4E36F71972B,00000001F00A4A42,90F167C1A5FA581C,2530D54C24689F60,982C874DC9256480,246F884DBC88561E,A12F808C74AF4F71,E590156D8C6E37F1,1E4FE107A0740C46,3B74F658B6C5A915,4520D8E2ED977320,00000000AD79BF5A,35F2676C7F1217B4,57362958644DA2E1,13AE3C0D9DAE563D,DF310BF4A35E0FF0,AE23FBC17120DA35,ED6E94482F4F92A7,C25FF2674130F4A8,CC2588680F4F9674,52BEF0D810B47032,00000000D6D41E2C,8C7207BB3CE2BF93,22A08542E1A2C67C,F0B8422BBC7B3BF2,906CE36B51523FC1,BF84A87AC9770B04,1331E06C5A0A35F4,F8EEBF4EC0B02676,3F7524B558F2FAA5,EA6D001C3DFE3D4C,00000001FA455C8F,FD4FBB828093D8BD,BEDF6C45BBE4BA60,119707CA51D076FC,F868C278515679E1,2A22B7224FE75055,F03F44A2625B6B4F,8B2771205CE5490F,F238B547817046EF,3A5975ADD4BAED5C,000000007A490709,A31C6BD53093D9DE,338FDE615C6D3AFF,D2933658B72922E8,5F2C27E404BA1807,9E6E18A042B595D9,F5B24BC70D4379F9,787E88E766381514,DEED2028F0BB1874,1D61AB111F592C7E,000000001071F8E3,C5C5D8D4C5FF400E,B5E16A24B27C4978,C786A54D51E7D65F,D4A57E39093016CB,E683A1CABC7A9C96,E622421AF2EE4437,817E1D30B49A6DF6,46B4898DC6F818D5,02422F9E529CAFFD,0000000216E14660,3BE5032E566C72B7,FB4B334E9D3D2858,1ECAADD03CAB4150,B0AB4D0574015493,8A65480B67460689,717DBDFE6A78C61A,7B688AA1A781DF12,7CF5E20938EEDDD2,E68529486F05C8B7,0000000181D5D0A6,783558FAFF349411,BAFD1D1628C67B67,F9F9A48719525554,E98A88F3EDCE485E,6DC0CB6649033189,F1AD590D5CB1AC1D,FB1A6ED3E976615B,0166F7524F0B45A8,975807307EC3D63F,00000000FFEF96B1,F634BFB26D2CAC72,66F93915E378BF76,68AB29E29A0EA186,06303232385B1464,5574BB125E6D3ECB,454CC6927425DE65,B0F023694C4565EE,E195B874D6F5CF20,C6A9304A7C4A0EFD,000000011FDA5D47,A0B65DBB8E1A356C,8D3ED7484C77F4AC,0FA1B5C5E74B0B74,DBA1F309B4371351,3B28348DD7AE81CC,823FCBADF11E9259,3B7F9E4C8189ADBA,B320C606FD9219D2,9400CBD7AB83E1DF,0000000085B97F84,5E9E2A5FC890B5BF,4B2159D014A567D1,A16B3E4EC6187481,9C0B56B2799D8F1A,0896A09FC9E5D031,D974794FB8B887EC,D56E286C9563C8AD,8411F8B0B7AF4D3D,F3975B47FA519BBA,00000000BAB6299F,C70092FBF3FE65DB,5FDF9916283CDFE9,2B33D0E261D51270,82DB51FE195F7AB3,87D2528F9BB2FDB5,61A98458B23A83AF,AD432D3417D1743B,923DDCA0E6511A6D,2D0311EC4061CD64,000000024390B94F,96A9CC6B2F56123B,3C0E95960ACEA034,53A5FD617B3DAF7F,D7A6715633248B26,560D4A09A38C5070,CFE72F39CC68428A,C5B1A5A79F286F76,2D8A4BAA74AA2030,66000EEAEF27DEDC,000000005E68C220,E10CBB5590D1EF02,C048482B28F36912,AE45BD61C24F53FF,8F8EF19B1F668CC5,10DF6F67F787A554,727CBEA3CD7A6C7A,21A94AB24E3795C6,E321D7EFADE0EAA8,CB0023C71CE255A6,00000000D0D657C0,CEEFDDB3ADBC36BC,09ADDDEC2FDC1CB0,C28BB3A130B81225,34D8F14733D8A9FA,4799612B1044305B,87C88A525309C765,C5C5D64D91E7599F,B0FBE20434D73941,86D80D0B849A5B9B,00000000574FB5DA,796CDC97A323D218,24EF4DBEBDE3E90E,F8FE93B7D2917FD7,0AC4A6AB4E0B53D3,10240AD1E209DC40,E087DDFA3720DCFF,A6BAD6167683F950,E65C1FF5DE0D599C,C64F4DDCEA279EAE,0000000050510F23,7FE6AB9E37C03222,FC922050789E3F97,8EB1C0764863B651,CCE9AEF1FAD5F411,BE70AADEB18A737D,6D83399CD76806EE,DC102A8574F79036,AF9871CBD37693D1,7DBC1AB0C9FF5956,00000001D0BF96A0,6A461245ABFA9812,01F24B9BF0C293C9,B49822904FDDD637,26EFD058F0ED3943,7DA9233CDE2E95FE,A0349294315327BB,164C4F9A7F13DDC6,429044E160BAB805,4CBE06FBBF0D273D,00000002516E3055,3029E45C6F526900,2C51392FD11B727D,2C29BA7157C4F82B,D8D2A96696CB7431,7F52C5D6DD3751C8,E5AE119A7AC0FB11,7A3B72891CAE1417,570E59E96FEA50D4,F998A8FB8EDAB176,00000000A0877FF8,1F8055C0D3670EEC,3A9FBCBE10737C53,13C52DE4DEE2BDDB,1C669FEF12381A25,0628C8446249C81C,38E7C691DBDB3EDA,E2824ADBB411ADD4,80A9CED33CEE08C8,EAD57CE490A61DED,00000001504D4403,F2C0EF4503A9FEA3,4A654C9EB06D84D0,9CC4C9D2209F1A62,690C34ECACB1F464,1649C7EFF79F4DD9,15EE49A9E45A9807,C34AB7B769545102,067E2A7F3E48D9AF,30762FD43AC565CB,0000000057DE5E70,C340664AD66F2760,58B58940D4B22D92,8199D64536ECFDBC,47E06313A1ADC904,AB58C4CA03D10913,43871C41AC4F4472,83E1038D6F05749A,9AD135B8F4F12307,FED8D684F2206511,00000000A8355FB9,215F98B662F085DC,978507A78F49BD5B,8AE115548CC27A02,E8ACE77893F38F7D,7A1E7FAAE9F5E180,024DD729D785ACF4,3E1308853CCCD30F,7B2B2F42DB1E965C,7FF1E9DFC5EA082E,000000016E9D3F54,40437E395EC73F1C,FB2F799EDE71C704,25F0A1262DB84169,A03F977834301869,6607387AFD9467A1,A10DAB1695E682DD,ABBC6CA99C8BBAC0,4528CAC83530660C,151EE4EF0CDB30E4,000000020BD7D088,1CF79A5A1333196B,F48DC70113A5B728,D127385D444F272F,E0547603D4181AAE,5884A40B9AF89DAD,80F6CF96E561E3A1,ACC01A6E3F603829,B6BEE3D9D7BCE674,9022B8A777052FFF,00000001C7B350D8,613A151A4099A8EE,9F1C78CC2486942C,05133AFD28088AB2,322E50906B63C186,D747F153488FBB5A,B8A2A74358A1B9E6,4637EE307574E574,919CFF9146D5B31F,41696D3F9C023230,000000026864C5DF,EFD7241DDBC92301,F4DA25180DACA9AF,B91FB24C749B4206,F61F5E8702484F44,71421B977FEF3121,90C619838D27CFD8,10AAA556249F90AE,DBB6D316C3561960,7D04E1B0D4F96003,000000008476443A,B8E33F7341B9110C,F573C3615F6563E1,703F202E9C81AFC2,4DCDDE216A9BB612,6F5AD9FF69DC89F4,B1215E7DD8CD6A5E,5E48483139B6E4A7,B8113F07921AA93C,1820A8185A444F6E,00000000CA2757FE,2F242A2F907278AB,3B71825E9085ABFC,008ACC4EE8FD3280,2B4D4EF79B346B82,8B569BEB89F9BB2E,0BB7F460C1845E9D,2019A73140BAAB1B,59A01E2FE2735AF9,9D8B762617FE48CD,000000016D21E00F,B3AB11523FC62A9B,AA05A7990FCEAEEE,97A79B14E25B0EFB,C3791239BF2CC234,93BAAB96443A5CCC,CA388ACD5A83233C,36F837842B1DF724,ACD983A0A9DBFC7E,588BE974B0FD3819,000000013A9343C6,C4357401BA1BADB8,F5CA42BBECF7ACF9,10A55819B169358A,51E9E5ECF996370C,2F08442770CEADEB,E96CC9D2580C4AB7,9CE98FF8C67A543C,B51DDA4151E23A1A,4F9E89B7DFFBC90E,000000022579DB3A,8FC871BB9F2E6ADB,6FBE45594EC33C75,5885AEC94261F1C3,67AB7CC2108DF49F,F4889858236D654C,E5E74B63A6B29A53,7AC08EB8BC99B638,40DC7E2F23B3149F,B0001C595A2916D7,0000000078A4D9A9,B241DFE2FAFAECBE,BA7A6C59687686D7,262D3B0D459703C4,557DDDF54C198E97,6202F924F22A2BE6,C8ECB51F4F56B301,48A0EC38F6038E62,D5C49ED437FAF39C,8E5DE9256404005F,00000000C4B404EB,B50463B57E9D470F,90D2754D6772D708,EC5ECC0EA23BB60A,ABA78A7CFA527343,47BB4D7D4664105B,E9A421F040BBF1A8,59776937F01528F0,507E32998B16E54C,B5172435B85AC7C1,0000000213A06C19,8DF9625BE193F829,72EB9469BAA6186E,530BEA72AEDD0327,CB3F4BCAE4A756EE,50E3CBDCD8D7FDEA,32C4CE81FDDAB949,A6A678446DEF5E78,7CDF73E06ADCB6F2,EE477D4278BD0875,0000000101A3CEBF,534B52D3688395A5,A0F7CAF6CF1AA186,FA72205C45006383,4F0830ABFC23E9F7,4BF966F69C62C3FE,0B8A1A4553520EDA,B04509B483B503FD,52841A7FF19B2EFB,03DE68F437017470,0000000046693E32,87E1C9ACB914B0E7,14383543F11EF74B,94C3ADD28E305019,D675CE8191B1DC71,4C2A96238AE1D13A,21AE767B72D73D09,A6A64B9353C3E4E8,C572507CA62FBCE9,30DA796B245A72D1,000000002A48B29F,CEA4853A0CA9002A,79D219707FCE6DD7,A089A62E7DA6826F,EF8EBAFDAA175880,0E4BF1A4D9CD3818,8D2D0904DE26E016,E015E54F2CC655C7,837C564B69FED5A2,B9027568C9945C99,0000000102B94143,A679B452BCFF1354,E2F8EC9FF963BF70,9FF3C3E3C6B7309F,91FB1EB0CB6162F1,2A84E3EF51B29847,F45B3E43BE27634F,753359545CEB5792,A94814781BB9BA58,57B9A1636208A3FA,00000000BF495CB1,05F3A4D040D9EFCC,D282BFE201375D53,15DA58BBCB167CA8,12591A734664B527,89414CC8DEC5E7C6,A87BE6989EB01B77,42616BCC6CC23ADB,41201EBB3511E9A4,65A06FC69685B70A,000000002EE4EFE2,6480FF1B4C577EEF,E3C690ECB4AB18BF,406C0361DC7385CE,98AC2FE8A7345673,53E112F0295CF4F8,9F81293B28F53E0B,5F70A365C09266DD,79C298E2D81C0347,AFE7F65526124F7E,000000025191766A,1A35A74BC2EF5A9F,232BCBBB59CD179C,A6D5A872CC1D6973,0513FF007ABDEA84,A5BDA0AEA28F57E7,D25899A328FA4619,772CFBD92684D285,73F42E304A37DFEC,070FB632097CDE07,000000012395D551,E93900FBA4109AEF,700D3DF99A6CED17,D920EA596C71AE51,735B4D3570AB1C22,55F78E2BEB4E19B4,026B9479D56835A6,7A25960A9DC467C7,B54747FB222DE4A7,B982FCD382C5D0A5,000000025F533EBA,3E98A136EBB195AE,A9ACE3614C69191F,9397FE43C4CE0D2B,CFF578ACD9B2F67D,6E664D3EB28B91AA,0A59A5C4875DA417,004A652D1B31153A,E806FC67905685CE,EEA70B612154A7F3,000000021FBCD47B,A1EFEA09E2EE9B4C,2E9FBEFD86D8AF1C,1ED8C41B2F42D46B,57E2A6321F2D82C6,4DBFF3CB8731AA19,45349EB47AA04F9D,38043A38DFA882C2,837C7459645CD503,5451C111564550BF,000000015B4AA129,CC1140CB0AC0133C,14C541EF93F79AF7,653F7242CA644E4F,33BE0FAA19546A8F,D9D2984BB7ADB01F,6A4A996B2F94CBE6,B37C04ABB619B90C,274F34514EAC4C85,2B4F46E57DF26E89,0000000258958334,5469F1713F8E2916,ABC5713D3DE4F937,2360B7919D6C6873,D0ECA61A38089E5F,D5C78EF3B7CA41F2,9EE268703CFCA591,BDCB44ACF714223A,70862598AC8A6D16,B7079F0BDA398B84,00000001E0B7D55A,9B5FE2D89DCC309F,D15661B2EEC1EE4B,DC1D5AACDA9A5E3C,0D557922FC4D3977,F30C29C4A821103F,E5D2EBD537E813B0,1FC5DAEAE911AE4A,C41902D48F50B6D5,87782E2EFB2C274B,00000000042D9868,1B00C26966FCC4CE,A4747599D3034E95,FA6BF0F00B3EC69E,6B4C9F6C44A97978,50ABD55A66E99591,D1E3252AD6A01F87,3064146C0E0F49AC,2E8F6FB8447B5596,5C4AC7CCA4E5E3BD,00000000AD4C549A,7C95D4A56F66EEF5,E1B2F7CBD2457EFB,32B2E09D069B55D7,3EED370F84517DB0,1312F407752275EC,D94E9DB35C764A41,70E09C3383E64B42,F39DCC5E05F6D93D,3809ADBDE542F9CA,00000001C9D85A03,C0F243835AA6B461,17C60B796CF95092,B5CB6581AD29DD26,000AF780C7DF0BA0,587219C81E7E440B,9C14B36396B2DF9B,EFC7DACEC1062DDA,BD837E1E142BC559,99E4C1F56D43C56E,0000000084FD0D8A,6FD62341BA5C3F28,21F2DFC06DA5DF52,E779E0B19F7C0F4C,4EE7CCE903B78097,26545603D9DA6D35,79552C9B97318425,54D93943C80DCDFF,51B114DF4ED28343,FCE9D465F1470D10,0000000093F5B46C,1C7525DF40BBD468,CB8675C1E9EA77A7,7C89BD2651FEFF7F,E2E22E33DA17239A,CA6104B701C60C21,8F09E392BF9D74BA,264517459F8E6FBE,40FB8FD3948986B6,9AD48CE21FFB9D09,00000000D275351C,09937A9B6499FFF6,9A3F97174A57954E,1C132C4C6C8B1DF2,F218F494E906E36B,62979CC83CC23648,B86BEC75BABFF50F,2EBFF4828EDEB39F,5F72B82E45D84AAA,0BA1C3F67A36254D,0000000000740375,3B0465C7E162C684,48E2A19137E14259,8DB213F10B45054A,77D53CE1070620F5,F7C83FF6A8C258E3,E558C3F900C6B89F,56D6990A832C2E88,13D0CFC7B8B690DC,AAA09D10E3608ABA,000000021F1F7D80,8533C36699C2F707,89ABD244A1CEEB44,CED5EE29617FD639,EA272B9D3E81ECDE,820582E94503F278,E7B3B75DAC86D249,C85383F6B35A68A4,90E64BD011AC9FF5,7B5FE6B287283EA4,00000001BB61856A,D09A6AB8986EB8E3,8972A47C63818894,5FB03AA18D713B74,663F2204D648AF3C,3774FFBD7DEBBC85,A30CB8968A830228,8B58C23DC9DDD56A,33EFF51F0F013396,CF37D4D7FDE97D25,000000006E6FFF33,FC079267ED7452EA,6F0FC37402859939,57A7B24B429EAD1C,35FB0213C31A7113,A10E8D7AF945F7C8,A7AD3116DA9D75F5,38B6D54653B45EEE,5A6811E8F948F5EC,7F85DE570B2C04D7,000000024A52836C,94364E8C913B445D,663E2A14D3A04138,6F1AB19EE62EC5B1,F874E91DB1A2E389,B86C56895C5A20D0,CEF49F715909B2F0,44970BD39782309F,EEEDCF09F379339E,EEE7C11AE292F189,000000021445D0E9,1F9602DBB23C3466,26F4DE6DE7EF8B98,C0B90524AA8C693D,A0700964A20CBF4C,85D051FFB4BB18C1,188F7C23E5C09BF0,8754FB2196C300BA,27054149F185EAEE,72EAAE2B97E874D6,0000000159E688DE,23CC087629E36B0E,4FDB55C5D903E410,CFF2E4BC2FA0CFD0,B59A13B4D773CAB6,A51DB3D023FE0AF8,B11F7226580C3811,632E46B831B42D5C,98BDE3F6A39D4977,4B3B3A5F1C3218C0,0000000014ECB410,8B060E77F084D8EA,971B93DD503C17D5,4002B8DE021272A6,4EB3D7C19A592477,87B9BC0B264CC382,DCD93E7295F69ADF,F4CF84A31C4CF501,5B67E8A4B6B8C70E,8B96C7943A19CBA4,0000000028B06F9A,63D12EA714749DE8,A17FD13572445CE7,3352362391C0CAD9,9E81192B0CFAFEC7,BAFBB8C2BB7FC75D,26AA2D7FC35713C4,81CE15EF7BC3E3EE,92AECA779AF1872F,357F9486E42BE8B1,00000001F1216B75,87AAED33D5D83AAE,7B334172117FA45A,91BA797A4E70C46B,E6A5E50567FFA709,DDAD276042511F9B,FFB3CFB809FF5AC2,43666D0F8DBA2B81,001EFB93CC7120AC,0BE490911312D5ED,0000000221BD625B,ACFF5245E7BA5286,E0126495EAA012C6,015DA2F05EE0ADB7,AB7F1730BF31602B,D424FE2931C328A0,1D48D35F762E20F3,21D6EFCDA2791DF1,BD7F40B4129D10A2,DD0AF3C42E187F97,0000000059DC7352,CCD0837FEDF61F17,48149311F12E3152,3B564078021D5C35,773E828B62A75F05,C0C7D391695C2426,48F96E03490E0D35,6A77347455F9F41E,305DB16D73072EBE,5682F46F090D0948,00000001F86B93E1,F98C3B62A14C4E0C,8F9EC444A18AF324,2BC634BD97FF4727,B4421357A13B7D9C,B58EDCF621CA1133,BF26FC9D857BEE32,57C241197E9082BF,9DF6E7B98BF3A253,A734908FF658D9E6,000000011195EC46,FF00221AD011656E,653633FBF51B8D02,648FF69ED5ED3F44,845A13AF06B1B440,24003BAEE6598810,488177FFAAD7E129,398B5F894A6EE330,8189623E2A5CBEA0,FA64176C916DDC4C,000000020F4DE01E,36A64946F6EC0690,C47C3B36E4DBA434,B2D0B35356F0B0A2,587C0A684D47D8AD,CE1B9E9176858EA0,E5E82BBE689978F2,3C03D0C2348C916F,D6F886294BABECBD,CAEAAACC99AC922A,000000007CBBEA04,280CF92B02706457,F0640FA1A71F876E,E4CE0E18CF4AFC66,17EC6D3257A064D3,21623BBCD0E10B9B,815C40ADFCCAD5DF,F9D24F0FE9CC4A81,BD0A93E19F922317,BB01F954FDDCC917,00000000F0AF4C30,B328AA64DBDCA21A,8F7448960F6DC4DC,24B0D9AB785445D9,C3A1A9F91CCCFF93,F52EF6DF422C5D11,4AD247B2ADEE4A26,1DBF68230FA40961,6BC6BF96E8666079,91CD9B300C0BFFD7,00000001DA64743C,5BC35F024A253A8A,0C9663EB6B6D2416,5DAC7C35C3FF8E33,86149B67A04E6D1D,11CF013EC430DAD5,FCBE5C884D9E08E0,4DB83614D04EDFD1,02588AC27DEDCBC3,9B4863BB858FB3A8,00000001EBFA81A4,472911141F05C338,6886A64F4113DE0A,7B8EC9252749FE44,144D81EA7E95E9B2,68B615B8B56DDA31,1C818E0AA7E4C08A,2A25CDF82BA6B5E0,C9BDFBBF5C8794A9,0B6899996510583D,00000000A8374740,497B7F2F6A561723,3F57001CE417ABCB,AA89A93BEF3CC795,1E6650906806C853,898E1DAC2F4A0D6E,89AF51CB27A3C5DE,19B26D309BA14C63,2F647CC62A70244D,576475657AB3A35A,00000001A7C9D896,7ECDDF7CF0614A57,22FF4864B25F4155,98AE21B402359F39,106DE93860408779,56750B1B0357F376,033ED67F163C9B6E,3B10AD3E18649BF8,54FFDABBED7D41A9,53851C898AFC94F6,00000001653718DA,9E5FFF7F6B723F6D,6C692C61555EAC63,4123DA568E67E342,586E04DA3639546E,1B598EF19B5CB1FD,DC97D91CFE2F4877,6564E77AF74F82CA,3E333896A87D503E,50570FD3E42592AC,00000001F1DF01FD,470C3A26601E7C58,C0C47EA9D123CA34,F0748C608BBBCF94,DE03BA2190F59450,C2BCCDD43FD10249,B6B4BE3DBBC40AB0,D7EB17D177F18E1D,277E478F9613FA18,E41AED09464C5AE6,00000002208A3A38,0D5E208421A0A5FB,2549474A6049B14E,3051EEDE6525F790,6AF005837A141A45,A66304B18E62C252,FFCA0BCF7924E62F,7B3FB6C813428B46,D1979C3E3DF032F9,C0F32E90A15C7D84,00000000B035CCFA,61AA1E9406F99D61,DEF66061105B886E,A8D663021AAB19D6,1EFE6FE574664C5B,48364940CEBBF816,3B9AC88CD2C5D0BC,C82515150E88E3E0,0311AD47F7996E7C,758D8131F44DEE83,00000001E504FC78,5A4453104876C2B6,BDEEB4DA685B4003,1A32D2EA0E16C455,B89C093917BC981F,379F60DB6BE0F914,12D7C86904A9DD66,C0F39C420B0BBDA3,E35DBF76F0EFE3CD,14BE8BD045CF3028,00000002577261EC,82F60F2C202A9F58,0970A648938FEEB5,901EB76C2E515C1C,8CB2F59BCEF99267,077F7CEDF43463C2,41BD97A6B6ABFD36,0A2877A5C86F40BA,9D1D6EC889FAA956,5A50B7627C46A2DD,000000014BAFFB9A,D7861FB9ACC72E98,1FFE0365E77421B3,20025E30AF7F8684,665AC570336AA030,81C857F22A9E701D,30FEE34700088444,C23F243616200084,FD5DB335F7073F54,CEF63B062AAA02F5,00000000572DF6F2,6D4DA7D0BFC4137F,DCA2361B5F3C30C9,6EF11A916507C979,A77417B885EFEAD2,91C8293D98FBB85E,99F0EE2FC871A5F1,501C746B0E47F589,D537FF10B60EE199,A56BA9DD7FC5A83E,000000007733D4A9,D3DE9F1705567236,70B3A65316FD3D9D,58D1076975B0A9FA,98E14E51AE732409,662BD67C3392A214,8A7C776A2EF44804,EA2AC4BEB1E9A5CE,911FD6CD6A74214D,7A8EC891D48DFB50,00000000DB7F651C,9DC6DE50FDE6CBF0,720E27A35441A6CA,48E2CEF841FAE4D1,7C04A8166977455E,60A118DFF1CFFCA6,F3A2471FF7DD0E04,299B0A2ABA22A536,ED74F684E5DA8F1F,F9CD07652E70A81E,000000002E5D8C5B,FBDE83423D0EFB35,D6B8D96513355EE9,8FE80E027B523B8E,42040875878667F6,73382355197D574C,A0C7624B26F2C69D,5F07955857E46A5D,5C8477D4901D911D,08E0E15F3CA287F7,00000000ACAEEB2E,A2F5F3A15E1A4BBA,7D16DD0B3218A2D3,FAB1E5F41BCDEC28,D14818D7E93F5AC8,E7747B9B7CEA73B6,5ADEA05C050E9057,A191C88EB1D27963,47820954A7813F69,0D81BF59F2971672,000000003A02C2D8,C08DB7B40343F6B0,6A2EC4677239C591,9CF58F1EDB6CC898,65F4C2303B0A5F51,A46440500F8E7A19,2E86CA06ED013357,C07214BE23A498B9,8B5A1820D234ADDF,BD17593B440F8644,00000002458BC06F,53E68B1381EF5830,7030B6930BE00DE4,8C98E8F32BFEACC7,7820D653760B83A8,073EF4CC7B854369,0B096690BB9C20A8,F41ECD97A4861306,3FE5597D8B85C8DA,F6CAEAEFA529605E,000000007D1C5A95,5EA236742682E91A,A72E377B69270151,92EC9879AF53210F,2541F6AFDA70062D,2B0860121CAB3DF3,52303DDDFA5A3916,CA282291FD2C3495,9832812F5818F7A6,61038FA94AF6D80C,0000000141BFAEA4,912FC331D2549D90,3CC05240FC5F6FED,922341008665BF31,2DBFB2099A12855C,EA568F0B66CB5274,1B616E5D5C7AFB11,6BD56E15A4002449,C2C04C9070D03E9D,77C060261172D571,00000001270257B8,9B8A8C92EAC2CFF5,6668CA19D5DAB6DC,E39EB25E03240F7B,92D0D0C300AC76AD,9083C3D305547BA0,02E8652C70CAF5E5,4F94EBBC53A7FF88,14C8A3C9BA4BA0FD,6EA5FCAA5CD78596,00000001FD38B86F,56472FF0A676C62B,3E3F569797A0A266,7A2F26A8BF1F01B0,E6B4F2E6288624C5,C12DC2BD0CE04022,D5C742D502B136BB,77B2CC62C5EF20E8,37FF61AD7D80DB48,D9B3162F48CF615C,00000000CD5E76ED,6913B96DB74E7188,225612FDAC660A4C,4F6AAD7DC7A8BB8D,8000861E54546F0D,F300F74543FCAB04,876A12CDC1FEA4E9,C42BCB329EC2867B,0F1F4AE46736624F,7260E1199A785CA9,000000004B8F1E6D,8A128E393B069278,8E9D8A6706A0858C,A55A19CE5FBD3ABB,BC94994744D45C60,0D6010D5124C9EE2,8AA258AB5FE83EE4,42AF06A6977B8C49,0480B7AD011D6442,621878A487E3975B,00000001B6D635F8,50CA978BE5B27B4C,EA8CB71D657E6486,0788F57A3E24EDB4,B63E494AAA87FFEC,ACF852945261319A,E9419EA4B3A677F8,D7509E5DB6BCFECB,23093FC25A157FBA,90EEFF40939A3001,000000003379A84E,5E19EA2BF8704350,7AF73D53CB4B371A,89F37C136C28427A,BEBD0EB88B2D611F,21B4C39CBFD5FC09,D90CE48B82487BF9,AD71BEBDF65D9E37,6697471C99B7F823,5F053F4248761783,0000000109112827,1473F280245A0F40,834230C5699D700C,D6E43232D458D343,3D284044E32EC317,78C4346714ECE44F,AF65ACD85EE2EC16,FEBB7A12B2D0266D,F86E30ADE2FF1518,EC13BC5BC2FFF97E,00000000A9B8F771,83FA55FA277F3130,7DEDD4ADC6D70FC5,A58E83F9E7762321,6DC0BD4FCD6D2273,1BEC4E370DF9FBE0,9A6DBE0F3F92FB82,70BE19C9A4993E50,C1DE785587E4BECF,C2CFAF68C501C6A5,00000000E96BC3BC,D6DE260749128BE2,EF54F07534BE04F5,E3F65FC9B864D5C1,AD1409541018964C,EBAC9279E295362E,6EA42D98F4F885DA,F079D2A906FA9690,25D7C3D291676846,27D106430D6890C7,00000001941A80BA,46A18C0024A82FD0,D25E0214D54B6EDE,BE90CAC2882AE1C5,0717B5D95E91F8AC,F9152BDBF724A193,DAB7566105EB7C1A,4B10C202608F58EC,EF9F0F0D6711CDF6,03F8997B2B36385F,0000000130B0C8F0,EFC5106381260802,6B6D01043C3EFA33,BA662BF37CF61169,529CBCB0186B33B5,CEC5378F28FC5CB7,0607739769431665,1B3FF4DFB05E9434,0FBF1BDBD45559FB,B58932E5489F2D64,00000001847B5CA1,03BCA48D9A7FD248,FE99D92CD6A7E87B,EAB61166AABEC612,3901DE1DB32778C6,2D61D8FDA86116B2,B62710CA0C3D60C3,039B68862F05EF8D,7E678448DAC79D6D,056517B2CBA17827,00000000CE71A741,A895FE550F882736,922F2E1B43893341,2B605EDFE9419C99,1A03EB420C6A7065,382C0816BEE1324B,B131D67C013A1314,36A7DE07297CF895,84C99402D8E4D799,E0B5AE5750293B18,0000000138C09D88,FD73A0EA2C229271,8204078D941DAA0C,FB19AFF9ADD39063,FD2C9894B0276E1B,73E26ED7EF4F2F14,44510D98DBD0969B,46973A8E80124497,19CAA697FD529D9B,9DED96AFB0D7D138,0000000250653680,14078F8CEAAC1D74,57FB45616DF0EACB,6EB091955270B202,6C8439DB177FAD12,8C490BC74499AD60,19FCC4475E350E75,B848C9643DCB2E98,F11BEA65DD57599F,B1337E2473934CE9,000000022EA554E1,8BA89E312DA3D14C,DE3343494FF9F94A,4762EE354A884BFF,A3FCA5DA187CFE52,7CB04720F428D5A6,0B80D421DF99A1BA,1CF43FE15AF64422,0A95C7A7DF0BB209,29E6B7B9B8CEDC24,000000020BD34A02,AD1303E6CF080ED0,0FCC224CE1459C58,C5A87DA1B02DCB57,DB7F292E0928E93B,94315E9CE6A29277,09E1DAC6ADECBB8C,93D44E6F94D52172,43FAD7AC3CFA5024,211B61A18E950792,000000000AEC2428,41A1C98F4BFF6B40,A64AD9D27A5E4F1B,09832B6690E789AC,59423AA014174546,02D58BF28A6ED248,72281082B75BE5AE,806767262713D0E3,701C281A1BECFC7A,836E98E24128744C,0000000116B2D1AF,AF214B65DAC67E85,1A8B751214824E76,05DDA1965AF4826A,2B580863DB5F2CB3,74F001FEFC07F1A7,F2293CC975F99AAA,6F3A105FC633ACBC,5A8CB2A3206285E8,B2D38CBD1198433A,000000006F50757A,67B250079CE999D4,63206F2D7013CA06,3CA1DB9F0B3AB0B5,128956E6F5DFD28C,F307EAA1EAAF817D,534A1FEB0AB9E57C,5EB3AA97F616BB20,DA3487FA3073940A,23F237A4CEAF3DC6,000000004271ED9F,4F7283699AFA8E1D,BC0E73FFF43AF9BA,C187EFF70B49DB4E,E2821990BF585F19,F05AD9CF27A567DF,6F0008E2FF5073C2,A1327BB089EC8C90,AC0E18787512B78C,034C1F08778D5210,0000000169CB4B15,9C8583935725F515,8AC9D856356FED0E,4496767E7B1AADAB,268A34D346CA334F,427C2903B8E6BB80,80371734724E6487,205EBAA0BEFBBB37,5C897204003560BF,968925177759E971,00000000C056C385,ED096FCCA88DF15E,633176A3210D4350,D0AED01A04316B52,2D5EA684A119A304,C0A70EF6FC8AF38D,7618C1092EB8D696,97429EDBD9961870,7EE3202A2A9D3F2F,FF928610E756F4C8,00000002383C3DF5,C1AE3D5838DA0105,2BFD42685AAAB514,981347626C7B3763,4A288DEC22865D04,510306D8EC93FDD0,21CAD0B97659BDC5,050AB531CA0A6422,592BD1CCA786A1CC,AB537571BE32578B,000000020EDC616F,74959BAE46EABF28,6DE438B9550546E6,C6454E1542B5C532,6A8B183C14A2BFB8,14D55D0CBD386FEE,355C1B943B956E82,BBA9BAB48A6B21A1,6D6523C94263C452,83697CB3311A7A78,0000000018839A93,D1F8982C25019173,D1D0D0D4B9C797CC,3DB8F68081ADE8B4,1F62B50D35217BA4,5CFC2CD9EE4C8BEF,87CD08CB1D49FA23,91C95B6C39BCF45D,9749FB45F86572DF,4C30B2E874AD8477,000000003CCE134D,37AFD6B5C3A00249,28529D0672C63D20,2A8C9A9EA095EF5A,D44990EC63E0B959,B3506541019ED404,5234F1C9FAEF1EE2,CFDC9A3D8329ED21,5772C643744D5688,1BB33649A2E6323E,00000001902C459F,FF2B40023FB4D73B,5EA261EE1F702E37,C6F7AC2B7B649931,85FEC6F7DFAC4349,D8B854C93E5EB31F,325B1B055D4F1C95,EC2032FC2A975897,5B4D194ABC73D165,242E726F8B06E80C,00000001288EC7F8,1F79197069F9D6E6,23BEC01F30E4D3A8,5A5B0EBB7CB63767,44AC044CF1F3BE91,B13F030A1B0BD036,B4485E564BEC830F,BE307335E5DABC12,B0547B387589268D,5B32AF0D3AE266CE,0000000004B4A4A9,690E420478064B77,97ECC4B3EAB9BBBB,84ED223DA69C3CBC,F8AD4F600957D332,756873B097E340C6,BD785A9A8943906B,241401321172E122,8233DC6338AB0F5F,BD23E85AF82F6B82,00000001417B8885,BF528B6556ACC9C2,11D82B32C4F1E1CE,8EDDCE54B875EB85,CD5AC5549DE6774F,8012376D661C0233,B2A6807879282BC2,35C584701AB0D0C3,9A72DAEB04522A08,6C382138740ACC74,00000001F30CFA10,33720AE822AA3437,18F19798EBAEF856,3587434050400465,7D4358C4E960ABFB,5A23B6F8486E0C76,CFEC8E26BDFDDA49,2EC9A911BB036C9B,AE1DB182AAF02B66,58960FC7E6B5BF55,00000001B5C21B93,BAA762886E542212,9A67C43297759E9D,54B238520E0B8E5B,4779A2BAB6F36D74,36D6B7E1EB6CDC27,4B73F1E438A77BD5,4B38B95992CF35C8,054E65B22597294F,BAF35FC0F940BA54,000000023322A630,25AE53FF2FC895C9,394CD24BC011D04C,68C7923333618D32,4C39AE8B1A415E6C,2949C2A1622B00FD,6C940C06193A41C3,7E76920FB278EFD3,3D476C8E6B5E1F68,9357BE8F5424AC64,00000000A7906061,7FCBD8A3F5C53FEB,5D1CCE65736F7930,F2DB73FE9F8A6D90,77AFB6BA905403A6,3A39F5066E2AFDA0,07B1F9468FB94C0F,44091BC816EF9659,E56C2948B6AC2BAF,759EC6BBA01C2357,00000000521F8BBF,3BC54C4AB52C2EEE,BBE77D66D4AF6463,4AC7FEBBF7F13865,84848C5C0BD7A841,F7C90D9F4145B93A,38E5EDF08134B5AE,2FC07B763B9E8D47,9A87BCA09B210A22,474C59A0BD25EEA5,000000023A05E991,E2D7606E56DFB649,F6550ADCA118E735,1556D04BA961AD87,08CD3585E85DE678,D3275B8773DBDBB7,19910AD6FD7C1236,5F4C631F5B7EB661,CA9A92F74548EDCB,BE8A46672F049E8B,0000000198990CBF,94CC6E6E06C3D2A2,33016E1FF4FB3483,04E3AD39E0959501,45AFA87B26FDB108,5E0BC60503904AFD,3D0DE8E83F1B22F7,6527587332098DA7,227F1568E943271B,01FEF1E2F8F895DF,000000000BF40E10,99EDF393E4C71817,E530D1FFCEE4C474,0CC798DA5ECA35A1,9862D3493E4263AA,E88975BB889B3094,467106576BC96B88,D879AC8D36EFC6AD,4D08F50B06B08938,0080D70B21921847,000000002FBEAF54,1E33FA11B86F7E4F,39F77BDF4D09A43F,CB2CEC66F228F804,0EAA073586598E94,7BB3534C044FB347,85D56B2ED809B3F9,5D3C325F624EBCED,D66F988E6A2011A6,739F737CCD3E8251,00000001F7BC1303,E9474F0D094E338B,7ECBC0772EA5C4E8,C7FCF57112BD5564,7A16739DF431E525,39CC576578B8F8CC,71C868E03AE02329,AE80182583E2069E,6F350E0500205DD9,C07BA8F56412212A,00000000718AD93E,95310638D630FCAC,BAE868443542E59A,3DA32D2DD3A12B83,4C000DC24DD610DA,6A9AF3FD34D28A2B,A5CD4F8671BC63E4,12F1644B15CCF928,2FFA273A29C6AFB5,9752C26F0502AE17,000000002C551E89,E2D1D857874BD9F7,25DE821E70B830F5,A51510C7A47A771F,843D33560052CC83,F4A6BB84BC885AB7,961523351317E70E,4B4A9F6A8A55668B,A52727186A75090E,63F889906B91EFCD,000000013A9A3A6E,F5D0B5B7668AF60D,DFE89219EB178345,8C5B1E93BD7D7242,23F49FBABAD3366B,072CDA863D8114BC,E763F588FB3A03ED,E83C114BB337D628,D60511DA41D4C118,C8DBFEDCA080B914,00000000D589485F,41E0D021F85633A5,BFF9CB171EDBCEEB,4A1D1B441E1D7A88,7110D599FA345D08,585F03C8808771DF,7970C68CB1A92EBA,53CAFB76B3194801,BD8E120B96BBA008,080A87B1AE06DAE6,00000001FA99B4EF,C099AC9E877CB81B,1CE5BD3934AD8E48,AFB433C946B4623B,9BD6A6E89723149D,F0853C7D444F76E0,399FB6293EEAFF4A,1BAD89450DEC50AF,BB63E5C9947717CA,A285E8C5DA31C8AE,00000001575DBFB9,5A068DC63864C21B,2498EF93964EFBFE,2EB76AD8C613ACC0,2921D9234F483550,BEA63C33F2959029,0A6E1D838A78EBB6,8A9172A73D477B3B,DC678291B44D4E1D,AB4F2F43B472C0DE,0000000037B6CDB3,E2E79E636D2E41E0,BAAA6BB6FCA3AA14,5D93AC86807EC92D,E41738B0D6559E1B,E36B3D978AF7D756,98242CCDF076A130,91218D701BBD1498,94D7F76805F960C5,D0DEB417BE4C840B,00000000B66DA491,8885B5759541FBAA,B9DB2828EC528353,E23BF41BD520732F,4AB4B8E55D208D29,D2FA2C40D5173F8B,8709DB383DFCD2C3,7B3A8B2486152EB3,A78E9D73033174DE,E7E630D915CDA0D7,00000002424A3788,AD8B89D5CD9755BF,8599B046DB6F6ED2,F7F8E75DDB032173,2CFF3384496FF37B,8AAB6640FBDF3DBB,4AF07F58B0EFD18C,5036EF90E0D95E82,1577C28EA2178078,9D15004D682EDC18,00000001C6942ED2,685F60038073712C,30DECA815D696128,809FB05720540728,0C0EE283E878F607,45AB9DED76CF14C3,FD45239699D241C4,BF90E5BF576A169D,8527AB18F383576A,7D3165DB3AAF9B06,0000000118FB0737,238A4C695CE3CCE1,E5BED5243F74D30C,3FBA5878AE3706BB,E92D585BE7B7F338,3193E901D297DB5B,5C3380F0781F6FCB,F7798C9EC22B2A96,C3321E10161CE095,E8CE38DB818BE8D6,00000001D6D87130,678779B9ED62DBD6,06C494D14D5CD9EC,0AEFFBA87C7C6B37,629BAF9ADFD2A6F9,8FFEFA7CA6FC265C,A80CBE8B3B74DBD3,A136C5A42DB8C558,90E82BF9461BD82C,C8D7738C5B37F96D,0000000054688761,848FD81FBC66F687,45AEE6307528427F,C6E337E6F65E9D02,EC76329EC4140362,CA2BBB4DFAF9F56D,14A13482D2EB843F,C306F41B6D275246,54D45CFC2C383023,E6C7AD5525267BA5,000000019B20939E,2E3907C85E97CD77,1F1AEB936D1BE009,3A31FB4F526AB500,E8C9F881C7225CC8,B5A4F166D6BE1333,954C74E9887C2F3B,E8B9F16EE4ED8A00,35CCCFA2D0115819,0DBC4A1A17C9412B,000000014C57327A,74468A3869B2C6CC,465FDBEBD10E8F4B,EED50288A0254AD5,252DBD61E6EBFA7C,80A837538167EE72,39D156861C429774,214AAEF8B9933E41,EE1B4C39530DDC5F,354FB962C2B2D9B1,0000000017BD8794,8C78CC9E7B775226,082CA3253BCF347A,8B396D7676A56C95,944442601B7FF309,F9604BDFA91C78FE,4D86F519B9F7177B,83A573B72D12995E,A529D788AC1BC96D,7FC3E9B28A5EB473,0000000184198A07,F24B0ADBE96B8353,572196F09D42F6A8,0508F26150BFFB60,3C514EF20C94F864,5E1316F91527505F,803912E28C6622CD,FEE71C547F709FEF,7B912F9E3AEB2B38,0F49350D5F936F02,000000004E10BFD2,979FED35DAEBF12D,4A9D862498359A15,CA8703843A87DA82,8B92AABEC7FC6FD1,D1F5106A59AB7C66,FEF72A2758F3736F,107BFDD168860552,4A20EDA59E464628,4551E0E3545E9FFD,000000022E3A88BE,147C0926B7F92045,F1145B4BF244B4D3,8F285BD34409E26C,5C174813FEB92AFD,873B57262527209D,951B5EA5DB359A25,5A4BE2D2D1CD6A7A,1232A4E35493B98F,1F7E4199FCE3E490,0000000254D9D0AE,F0F6DFCAF14F5F41,930A9903E6844050,B0B4117F4616D3AA,0EDB0EEDC81FDB8C,C35666A3935575B0,B79876A79636A0F4,2D3ED0632053DEDF,C0F241F436DDE009,46EDFB26DF5E3C11,00000000718D83BF,6924BE882548B6D7,71F78EEA22AE04A1,6AEC2E2E8D96A340,37CF80BF95E5EF55,0C1395647075108A,10DCD163E639A0D8,15528A9D56133029,F5BDDB38897A73A6,A609B98D72625328,00000000EA8BB793,89C0B4B8F0A01554,1F9EA9B69F9E63D4,8D932A4C860DD86F,5968A5A951B983C3,2D2DD9F07FC910C5,8BBA74DD91E75104,7472CA8CBB5DB2CE,22B326D8586908B6,B81BF8E3B25B65AE,0000000176E961ED,333A34E1301B40B5,1BB2513845CA4F0C,F635E4F591DFDD56,84CC7336034AF933,0D38EE04BD058ECE,EBAA09180D07A2AE,8DE71D9200476884,5CCC8F7293906EC9,3085E63E2DD772E5,00000001B1E33F84,7EBB1EC7415F617D,DD73DD3D0A4FBE49,E2BC0CC1525A86AE,55AC7973C7863903,F5A6E09E75C60001,6543556D1E9E2A1F,CD6EBD58C5E21576,688BD93F12F0FDB0,B89E2BB8FC114267,00000001632A7C6E,8539CA00CC2DC8CA,B6982BF1E2D7D332,62BCBE33FB37E340,ABB01AA6E5D6F583,3DF4208B38532FD5,9D3426D32EA22C99,59C3AF86EA5F61DA,8FB844DE4F964BE9,CD940D0F4F29EACD,000000021C17BA56,265663A3F08672B5,5892C03E5CD632E5,C376318402058EFD,B9C235341D911395,30F650C9E6D536CD,5BABB4427F5681E7,96BFADCE12657CED,6767889270A6EB2A,AD97AA23FEEB7487,000000027BD23E49,5C88B14AD355FDF9,102B4A6DA8BBF20E,629CCB6546BC1BDA,EB9682B9C403F730,539A7B26DBC7192C,437BF91E4EFA145A,98D1DA3D1EE47E30,E72603EA7C759BFF,324CE288510BF488,00000000B8F055B8,368D48E2A6488CD1,C75A35EB1A53ECF8,6F2AC698072F414E,F825967E5DAEFABF,9CD75FB0856CE904,5BFD0087A93B9AE7,CFC2A56C73805F0E,1D5CF98C0BCC76C0,281114D7E4310D94,00000001E29DD909,409FCEBD06828DF8,4F9DEC394E4D79CF,15D1E906A94404D4,9B4B5806A5D0BBC1,FF3CFB3CD4AB0BFD,697DE0B6271E92D2,2CFA42880054E908,BF82951E5E6A409A,D5E14FC14677DACD,00000000E2A30CE2,F7058A61AA76B014,B0B0542ED47F821C,8FF8DC08740BC45D,F899FD840F941C54,8E9B50C05B2C5E5E,2EB12424A79BE3E0,63B22EB14BB2EA30,4BDE7951E4552104,8C56D5DDC51F8F36,00000000DC82A900,5D00E8299FD42B11,95872533E484FB92,9EA31EA314B34ADB,03CEC9BB6C1EB06D,3963181410E93957,C0BC826212BDE6AB,3BD1602322527B88,746A993E26E421EC,62DEDA47A3B76867,00000000BD3E7BDB,139C38065C9A4485,DF637AF2397CB70A,504067477577C777,9BC29E9C4364BFA1,62804166CB6B622B,D683D263A7C8CBEA,1F38C3241525EB7C,153817B051F88DFA,721BE8216FBF1A4E,0000000132644D3B,9381E383C203E5DA,EB15B3A7C707A9EE,31D2337AF7DB510D,E4FC64520B6C49EB,F4E14CDEDAE4EA87,6F7DC209E243E7D3,0FC5D3E706F193D3,19D3C02647A98C2E,74DB49B73CF3DE0C,00000001B50C95C0,FE80C3DD8C3B3F2F,276B9A1BEECD4997,7F1759E98A5161F8,D9C920AFD6D776AE,75D43C97E3FC0BFA,D647FFC56F3D16D4,D66CD23919E64D41,0F9252E299BF5251,80147DDB39F2C2F9,0000000056B01EE5,C9DB9F366BA56917,6972E77AF302C871,112B76C670CB63F8,DA63973885581425,11A116A64B8CEA6C,FE73886F51D39DBF,2B8EC42B2B18E246,45C2B3264387DD4F,3736F7E250F5992D,00000001F7C38A2B,AB72F6C16BCE9F4A,F00B64EA8A20A890,C0869FB8570C759F,9CEFCB7B8747D6CC,D49456CB73309B67,E8943F9A6C3A469F,52384739DF9D0D8F,1E6A758666F266E1,26CD80E765C44522,000000017930E828,0E24AC6894A3DF65,847CA39ABDE25B64,AE12ADBF5AE1C557,568C5F1B34D44333,FF69DD3D947D212B,CC1B65C9E0DE79FE,C6D2CBE56120285B,91E34E1A4BE1B2FA,43C0D0E9D2DF34FD,00000000330D4801,068A36A59C170649,E1F67981D83370ED,F05111437CE7932E,6374CBF66A05210F,2DDD9EF76315CEF3,4DBFC7B75F7064C3,E18C0876DB3F2B07,522047D95863E146,722B019338B6C563,0000000147E94CF8,96D296B2EE58DAEE,543E53697867F047,D41FFA3C5AB47782,EA60EB9C60B3D847,B5AD9222B63CF9F4,15AE3F0BF852A292,A1114DF164CFE245,4AA7C5DCD7A29673,33A0D8861106174B,0000000179DDB064,C45D47A02B496C12,D81F798B123FF502,A517AD9A5E88B983,64E120C7D2901F63,7B3C24B920A51CDC,D69E68F37CAAF20F,FE7F92C81083953B,DC3D264D0F322C1E,DB44819FF1B3FA57,00000001642F1652,65F6171EBA0117CC,56F932B537F2C36E,A958FA0019A62247,891AC372ECD943EC,118CD633368415DB,777247783F4CAFBB,A4E28C72B75E1F1A,B16F742C0D404A55,657B1E87104A2601,0000000036DB712C,E57866ECCB49C901,7D0A6388C9784105,82708F37EB1A297B,837CA2EADA77D88A,B60D853553FD3120,C40DB523846C41D5,F9E3E000AF3630FA,B12015333D5FFB82,39BF8CDEC44506F2,000000008431869A,2740EBA93E573F1D,B8F549736C4D338E,33E3C42795245E80,C8A1047F84153AAA,D20F6935DCBE9A9A,33D9C90E542A3263,3BD3D945C3E3E565,A4F2451B504330F2,01A73B8288973988,000000023F48D00F,EBA678A66B79D3AE,FF711BD219109A3A,6C0DFC67DFEC9EA0,CB473FC42CFC8908,110EB131DD4E0B53,3957976C8925F477,10B2FAA5157A109D,8A9EC0DFDCD4026F,0BB1FA126F974D44,000000001B8D4771,ED714FF38807F970,35EC87B09C6142F5,0B27B54A69B16858,98FC07C417C08457,ABB74EA096F92B71,53D923D35371D6E8,EC3900D2125F8264,94481E2744B347E3,CD9A1DF1B92E311F,000000005DE809D9,CD714811000DF7E9,DDD2FEFBC0080819,1D0E74018E58C0FA,CC7687CC82E3764C,49117C02FE715AD6,2732F76E930CAA3C,186C9AFBC2007CE4,E0F47397E266B193,79B2BF4AB078E042,000000016E51D28B,82F5B3D76A3434F1,F59FCCBD7CB3A7EA,AF48707549ADBEB9,B82BE4D5431D372E,9E6AE3C67D7D2DC4,3B34FDFDBA5066F5,AD0D794D3F5739BC,9E552049F6B46C4F,07E46C9368E87617,000000018A8EF4B3,E4AC79AD8C5856E8,799CACC10C825B37,9BDC30BE6CBE7082,938D133D912A9853,0F71F12018182679,2B6B95A070BCD81A,A88036F16052F007,58A66FA9F37E3F8C,81A4E976C39DF4D9,000000002DC9B88B,A7109DE1C927BB2A,308C5D190C04D526,7EAE9FA6EB3862E7,C3D7703EF66D4CD9,9F99EAC99AC0D1A8,AE498FE8A947619B,2242F65B7BA11E6C,44173A1739CA9073,87A0599D516331D6,0000000138FBA5D3,514117A88645E1C9,68E440F56E55D434,544CA6B41284EFB7,4C119C554461BB9E,0F7A4FAF5465820E,0BD3158420C37D8B,EB1EE6F7F4F2A631,9AA9A881499840A8,767A7E7C79D01A35,00000001CA2DD385,FC154253C5983415,2743FD4FA2E16E5E,BDE019ECC3AB369E,E1B2085724A7AB44,FADE1523A3583C10,EE60FCAF940D49F3,9D0EE4CA9D6946A7,D6D12483326E4CDD,7D33064C845B7ADE,000000018930172D,8A12754F5400999A,19381C3B6FB8AFE1,72C233072FBA3FC3,CA865119FA53B7BD,902978FD63A082B8,3EEF694F2CB0E406,316418FF4985400B,0FE3DC3B0CE152A3,ACE29E0348AB60C8,000000021D47404F,0C089FA673CEBE8F,DF102A088FB35950,5438F85336618479,B3423CC5C365F0FF,964CC56558E2CC13,BEC4B2A21CD9B3AE,2131465766CB90D5,F31E1078D646033E,68CDD7B311908459,0000000021EDDF01,ED0AA2AFB8296C88,0D28E3DC27978117,BEA6BFF1731DCE21,C623FF82E130902D,DF781EE441557E76,4215F3048935BF4F,1C2B3A08B0493504,43DB746BE1022755,63154CC8675F9AB4,00000001201DDA9E,397E71C549732F8D,432AB7EF0D3F7058,99CFE128A7B8077C,53E9711BFF869847,5CA75EC2D788F24B,CAD7D2DE1380ECB8,0F60BEC594135855,9A4853845BE3BA44,70596A1FE238F0FE,0000000163DAF1F3,F91682FD0AE57151,71864A40941F0147,4DC2D02D12014C82,1F0C6C808DC47DF5,4A243817000D63F9,F194A1098F3272A4,D6AFF11A5A628000,B020C4A292B847AF,4D685BB2BF1A1C82,00000001B88AED8F,002E60535F8A5B7E,2600CF27A5610303,C4D9850FB3CDFF62,6C8539F3CF78D692,8AAE044E0F39ACEF,265E2F013C92CF68,316CB1D49EEE36BD,28C1D65058E94AD9,9FE3969F80BCE9F7,0000000196053617,435A4013E5CB2F20,CCAFD73B5446292D,74F742C0E2AFD734,3A8EC0D583E53691,97DC6E0E49216648,7A8D4CB96E825B10,487B7423B1EA38D6,F31D84362D38D56E,2D7077D2C0FEAC45,0000000235E50B94,C3DE16CE72BFAAB1,AA5C18169FBEC749,22BDED92130EEA43,9F1B8BEC77C70A4E,377C0D42884CE2E3,953DF8E72801C902,41C0CFABCCBECCBA,14847CE6AC5CD6DB,63B3CCB896EB566D,000000019DDC4646,65893D0DEAAC5ADC,31D5F1D6241AED98,A76632A23402E29F,AC9840DE40FBF3D0,DAE6CC2A432D272E,1C9457DEF6CBF304,968BA09B666E5F9F,F2B12EBAA8A17F7C,9D5B1174B7ECDEB4,00000000D3BC3E37,EC29A109DB15D3EA,5F774EFCE982C2F3,05F74E78E44B69AF,120AFF25CC30DC39,F71EE68F95F24CC5,5579A3008FF44A2B,DFDCC986EA4835AF,C4755B7973B615EE,D33F8E58C0E9DF80,0000000014199E4D,4F00D2CC87C14F3E,F4F8AB117823EA29,0622F0579400CFA7,AF3DF19C6DD63E80,83766903001E88FE,EF42D6AFA2FDC67C,4CFCD51EB134EB18,0760F71AF87AA908,366F1045F162D131,00000000367AEF1D,D16EB72180312CAC,2252E11AE7460535,E4EFEA0C922884DC,8A6CC793EEC2EABC,334DB3A40D63960B,67F2EE5A9B7F7390,4AB4AE8D2F5E1BEC,79CEA82DA3C95932,D06E05E29E0A5193,00000001D5E13755,DB22E7BAB36D65E8,D5ADE73DF81EC28E,7E8456E23AFF6B57,87039DEC9700FBC0,D727A7CF153F5BD9,DAC9D28142709220,555F2524643F9436,FDF70592C3786A82,C699791F21858C77,0000000007EEFD92,AF2D3F1D38E1808B,AB3F885D7EAC7F85,F19265B7051D08E3,97939D3E435A0F2C,355E5409F340FB7E,0E11A830068D225A,36BED4869D545BF7,4B404B2257F118CE,29193119E20A7797,00000001AA067B9E,7159368FCE435A63,6FFEC6BF9BDA2368,92254F42DFCAE57F,163CE418E38E010C,1E9969AFC3622FE9,DADFEC9F08BA1D64,025674CDB31355E3,95D009BE0FAC417C,85CD7D9FCAEE2F58,000000010E5BA14D,346C217C9CD60CD6,CD0A4DB898461F8A,3CAF1893582D1452,C075F8E13E1C0CFB,D3CBB8B006725B61,BDBE17769177CA69,36FD2081A9F890C5,8CC9A9337F76CBF1,BCFD4BBFFC7010B0,00000001AF7FEC68,B51D21A91292CDBA,5A555FD766E4E4D8,D073E7173901A297,5D983AF03F4E3BA8,8D2FA9E21491C71A,6D5BFD445C746393,BE299B1842C32898,0B7AEB7F1624CFB4,018AF8D3BAFFF114,000000014B58DF3E,6C815F35B76FAFFF,3FDFE1EEB5ECD35D,9EA7B38236A05832,FC3F27B815209582,C36FCB720A6CCE7E,48DBC68F9DB9B3D9,1F8BB18893E673E4,CC168CAF349F6EDC,0BDC16DBDA0E8DC2,000000015BE82603,3E7D0E31F54C3F3E,C48A8FB59B9DDC39,B9E84DB3D80F8953,6B51302E99F1F671,F400D562824DAA52,07FECB24E0BAECE7,F4854A22E9AC3280,61CFFA674730826C,A2572E0492406265,0000000125904822,8298517958F7FF6A,3BABACACE64F52D6,972AAAF9CDF60C7E,F7B319002A629698,F1722C0BCE4599FA,571388E70E98D9C2,AE998EEE5F038A40,CA3DCC0420F9A776,C25878C6D94B56F1,0000000062908803,1B1C43947C0D17E2,3D44D4102C255E6D,338FAD79A03AD351,6469718AF7978FAB,27446F867C62DD31,079FB8E5F3790FAB,E0CA7C68BBE677A2,F40BF98377D60B41,B6CC0D62B1A18207,00000000C5CE2A3D,486DB287C2F370C5,1C2AE6A84E04475A,EC4E2893ABABAF1E,F9BB7FEA0043D08F,2D8E75A853E0C0D6,3592999166259FDC,CA252D865D128B25,FE08F58A6E46CD04,4F57C6C4C02B78CB,000000001B5BCF85,7665C2CC49DD73A2,79B317BFFFD9DC99,6378466A4AD19478,0378AA5D21A69910,12F9733C6A382B66,22DA5048F012598A,D3D462C668FF936C,131E0B76E60C0D64,0ACE81437F98D20C,00000001D8F79E0A,7D9C4A63143D6EB3,5FF5B5E4125A5CBD,30E26C0212353A3E,48E2E20A7134749C,F25CC02C2EC854B3,A6C249E0E2404213,4956B072A5D6C1B2,529B212947D3BCD0,E5421CD7FDE252C0,00000001667FC8CE,AF4153F6AEB6BC09,C781C8DF4C260895,1430B38E81A6D386,0178FB186EFB1A72,7E3DEA164E9EC0E2,F647FF1E7DD2273B,B7B0A9F6C909CBC1,FCCEE194AAFB7A09,90E0F43281114383,000000009325776F,9AB054BC84A483BE,2085EC547152A253,6394952D6A784686,1118D146DAA43EF7,C8EF6A8FC65A7767,ACB115F5A8B68C27,4D3EA047479F810A,D64AE74ECA5167EA,E7AA45BD3F864452,0000000258B4BA6D,48A933F87C4FC4E6,A695E5B0A58DA22C,3C02770D65785BAD,935035D748936F53,E7E6066665363FDC,4AA6A2565A2AA2B6,AA0519430B39017B,EDDA470F93340CB2,4A663DC53EBFA7C3,0000000030EB2C22,2DAA234D150B5F25,6A0BF7BCE763950B,39DDC826FBBC3C15,C0B037E5BCBC4A39,D0DCF7741936C443,358EE5075685B230,E9B419009F8C7E86,1A86CE44EF95EDBC,FEC5A8A3F2F03322,000000017005902B,7854473CB7189F8D,BF417B7F84CDE35E,E29B9BEE1CC87691,7A0CC6AA5E4A3B6C,CAC569F3D7BF90CF,8BFED5D908BABD39,B1AEE458F77B3B6E,75488443441A675F,42558989DE40DF68,0000000234A4A392,3BA49548331AD539,D176FC2DEB3637E2,DD11E0D59ABFC30F,CEB09AFBED0D4F41,9C561B3A64BCA0B6,E2B8A4F28FE9FA2C,CD0E79D5C9BB6510,45FB81F5C643F66A,B84C52C98B281460,0000000045EEC506,0000000135265AB3,0000000000000000,0000000000000000,0000000000000000,609A000000000000,3754FA4ECEF9BE90,83F68967E4DB82A9,C5CCB347607C507B,B8AAF689409E352C,000000009DC814C3,067205E1B881D075,894BB12AFE2FBCAD,E7C2B8FF7C89A4A4,3CCB5C538771A30E,472E884966422A98,CE478A13952D16FE,97E302EDADBD26DA,514EEB8A7ED09CDB,CE48CDA905F9FB56,00000000E0BFA119,CBE3D6D2008C6231,0CA857181A6CAE47,DE5F7ED987BA1F46,02846BC6BBD212B7,8A5E804280871124,48D564480F8ADB7E,2DE4D3C9FD8DFC83,EBEC3D5643333E56,DB539F526557088F,000000023C5B48EA,00000000CE1991CC,0000000000000000,0000000000000000,0000000000000000,3468000000000000,9B33857A50E2F47F,149430734647A838,A56C442BA0D5A3C4,26D204DD0C595E7B,000000021129D2C8,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,067205E1B881D075,894BB12AFE2FBCAD,E7C2B8FF7C89A4A4,3CCB5C538771A30E,472E884966422A98,CE478A13952D16FE,97E302EDADBD26DA,514EEB8A7ED09CDB,CE48CDA905F9FB56,00000000E0BFA119 - -ph2_T = B1662745692C51F9,7D112F9529E3CB65,D197985FE3BA9E35,C7218B1D6F96D08C,F81C88AB84530BB9,DAEB3FA2025F5139,8FC68EF3278C667C,11F0CF3A469A94FD,8705518AE0C2CCB0,00000000FCBD2A01,036DA26A97883B0B,2475DAD3D5536A6C,5864894F54B94DE0,F4588A5A494D4152,50CC014F35902C17,3182C1C74E8C210C,6EA72DB01A895A9A,D0D7CC58929E30D5,0A2E804E67E87A33,00000001177BB1E8,F2C529E73E9A02A0,70DAC74CCCCF18F9,13456B350B54B453,B1638FA335F950D2,3942573057561275,D877977B47DBAE51,4D74BF15D4409920,57029818490F5F1B,BEE9B373411DD41A,0000000118DACB6C,BD0BFE66DCEA15DA,1C11F9C6914F1B1D,71F4555569EC06EA,4648AC1FE55300CF,B90D7A66B7089591,137DB0778655BF6A,FE361335F06EC68E,ACA05F38ACEBEF34,AFFBAA5877E6B512,00000001AAB822AF,77F26AC0E2A4877E,BACEBB2B5B676442,810B019FB10A1A5B,0637F6B73B0607AD,FAB656F7DE8D6ECE,F94034B552AAE862,05D824C5DBE90B0A,FA6B0E57BBBC2D6D,A1AC2946E855A23E,000000012307F13F,4494EFD83D638657,1DCD6904C4EA95E2,E3D8E6B2EF2063E5,E60BDA316493214E,03C22D3AEA81D9DD,5AE932FF68DD44C5,E77534B6480D6DF4,B69E9F0937D9E7F6,93599E66076239DF,0000000265F954D8,66B7BB1DC6616CC0,171E9CFFA77C97A8,34391BBE0CE2A87F,0B73A6C62D5D8FDC,5B126FA80FBC7B89,0A228F9B50726799,6EB5747B35FEDEA8,E1493706590BDB95,AD5D22ACE06894C4,000000027BBC5CFC,7C9C3BAA4BD9D0EE,D27EBBCAD6E6D967,A934F6CA48A86216,C145D7D843824B43,596DDDCB48C5088F,63E552CB98A5DBA3,E3784024914538D3,8C37C52ADBE83A90,34A0DF49C62C20F2,00000001BCAAEF69,C6CDCC91DCF2992E,567B42E62CFED059,411D160D247A10D5,2B715DC47F11EBD2,744A6576C42477D4,DC7BE67DF091B0F3,32527C3FC2671E47,5C8CD25A2AE03608,355E45C3CE969036,00000001EB154874,7C4F48408AB8C520,FE309DDA2C7351D0,D9EAB31D7E0204F4,BC35ABAE92376239,BDC44495BCE93C5B,800EAE4EEBBB2EB7,98139330F442BDDD,D7AB1FE940D27A6C,E80F928935C403D1,0000000045FAFC7C,E191C88ACD41A81C,B13C656B9B0A2CB1,29D635D2BD0D79BA,5407DA90693974DB,5AAC1B1B8E72FEC9,E2B8DD20079B23C1,98B6DB8DD39AC820,657E997880163606,8A2AB88B3F660592,000000025512781A,990CA6F0F50B9ADC,228FEA3E5CDEE8B1,255240AF7E48D771,5C5502D785B65D90,5D770F950CDB549B,993F71313EDBD5F2,8144657E1C7686FF,7F722AB9CC6C39A2,B2F7E0EC081EE427,00000001B4A2B7C6,B2118E3D319830B1,B0AD33267D9076BC,355F6F128A66724B,387ADBAA81CC7098,EF1FFD71829563BB,40D80A3DCB0AD084,68DDBD512FB899DA,EC1E4A9476A88D2F,314CD93DCAB7743F,000000018834E1D9,5F146E947089E787,0D6987015421B51A,3AB7E1B26DEED377,11E1F02FF4D827FD,4995C3F8B887F195,C4CDFCA7A777511D,74FB596ABF5B8321,9BA72E376AD061C6,5BA0B8063F22958B,0000000220A639A4,5D871B8B1F63AC55,F1900B78B3866A57,A44874C267A7B84C,9F2292971D79D5F4,B38F2DD74E246C16,63C0930F487B2A7B,B18BF106701AA044,CF1722C2DB0CD994,E111FE30A46663B3,000000022AB2B57E,F1E64B07BF0C5072,97C956175BFFCE3D,434C4781B0EEDD88,17EB80ED4A536D06,AD401DD389843377,86C18EBBF24ACDDB,69CE7AF5E53FCFED,E0E50396651DF1A9,70C82E89E1459DBD,000000017B690DAA,BFA10E50722032F9,464D680D99006B45,D80AF704CB58DB8B,9ED0856A2C90DAF1,D5493049E706209E,ACF8338A65332E16,2C2335DF884B32CD,6F81C91BE04F6527,F1499A72A36F72C6,0000000176794253,DFB5EB72FB3FB09A,7BC0D1AC3E1CADB7,E2F057125174AB95,D57B7ECEEB44C1E8,3C848BF551544062,3D9293C1FED73618,8C6AAD60069071FD,6A0E12BA234E6DE5,E49DC7D284EB70B0,00000000A383993D,0D677E3D6A960AAE,A82355F1B3537699,E79EB1F23290C0F0,985DE5F73A40D326,C3E709D7DE2F90FA,135B55F99ADF0C2B,C79D4A12C03A5B57,A02DCFD0A2C71339,0B0474FC37B979B9,00000000E346FED8,6D2ECAABA3E63635,6D9AE6A688D5F76E,6829CB6776EDC8B2,3A563F71FEF4F32C,3A80E794F5979CD2,DA82B375438D621E,DFC0830371EFEDBF,F37A310907227360,BCF063556BB8F5A7,000000026A4628AE,728BCE79D8BE170E,12E99D787117EC09,613224E9830AFD20,A4E44704AD103E14,EA79D5C72EDD83F8,C140E73A630AE58D,8E1AED868F13209D,3EDD045C9B29ADD0,C5A089705ED99EB2,00000000E87B87EB,3E1A697F7DE29766,DEBD12EFDFCBD7EB,16A8ABAC65702E4F,929C2D320F44EEB3,44500859337D6764,C1B18C50E206B580,657C2DA8F297D090,B89B23A987F24F7A,EEDB667CCE4D1EA0,0000000150053960,490061B0DF2913E6,72C149032BAEED02,33E7A289F72E643D,C7393D7D32E83BD2,3BC99F125697B930,81521EE2392FBA5C,1E20A422C55DE701,0F51AABE059422B7,FEDDF58A2A2C4090,00000001340AF89A,EDEA94B27F566213,DEC250FFBD2613E9,3B51A2CC899EECDE,ABB00299A53F3FD2,DEC51708D9CF0207,4FF784108CC8967E,E69BF389B23DE040,76DD60970004FCC9,F033A03891406E1D,0000000122FC881D,6169577148569693,7A3C551B7B7C470F,980DBCE6F14470FE,025137EA355920E8,1AC1572BEDE8AAF0,2D74821812989AD9,6C033E81AD62CBC7,F389DFCF8F4D5C84,1AAB26364D818618,00000001A448BE0B,0F13F48062607A31,C7AD9A0EAC51B804,AA9FA1C61A8A9D11,D254C5723108DFCC,48EA5F715080ED99,66C5B9C0148E65A1,63E05F5BCD755937,6B6D1A93DFD7D7D3,50F5B686DC40B7E7,000000020889EBB0,5E0A54DA3F026F23,69EC337BFF2EB821,9002F9292FE1774D,A4AF297D03DC5606,169E49DFC93C9B87,53670B724AF2791B,67E79312FB6D6B99,A3B0477158AF8A15,C2A074CFE73A5FEC,00000001CDC83117,A2CD9D7132930B27,5A22C6C5B7C105D3,B2887A29D70982AE,85D19F2AB660382D,64BF9F8CB33546E3,42E9D0D91E9EED8B,29CD59A4B620B634,8631E5D71D0E0652,1AD1D006E2F5722B,000000016C70A2A0,BB23921A8E53BA27,0BBC38E4772FF093,4D8CC07893FAD8FA,9301B263F918A781,044290E749D30D0B,FB92E7CB6F679EFE,BCCD7E332CB8AFA8,676DC8B880B79939,9B71F825FD170237,00000000153452B1,D029C9EE15187607,9BD93E5370CDDD7C,286364B8BA079C5F,D8A16A5E26C6016E,30DD197493312632,2D70A8E1D6435020,63E42E78CF95CDA1,50C5C5B07157EAAE,3E12071B3F273137,000000023BE00E1E,B297613398DDCCD2,F6104F0225C35757,4995A6CBFBC3B623,1707A882FD2170E8,79C4A1D55ED61C16,446E6D7A2CE4BC26,252FA1F11BFB7A55,F3E36300CCF17AB7,1246F0A0C18F9319,0000000000EA7624,254CDEF1365F10AC,0787CF9F5230D1CB,BB7199EC1131200C,3A985AC3AD27E281,EBA32F4C59B757BE,903FF1C90832D2AC,170CCBFAD40A93B0,4A977539D39FA80E,34DA74BD80EA7A07,00000001D6395B85,AC59296815994E94,BBE2541380821034,5AE6A581C6CA70A0,9A17F5B536B7019D,1A6749C9D248993F,27B94EB99B9089E6,450DB4D6F91AF537,38EEBCDB77632641,BA946475054C04B7,000000021BD2123F,0A48341C5ED4E825,E3602ADCB1BBDF26,188784A33A69DA6F,CDAB34C613DF6D40,F6E5E4056C51A643,F1A6450DEC75CEC7,5E116A2CDA2B0EAB,9AAC39AED7E687F3,356963374A7CC9DE,0000000159C11DA5,D8B6B1656FA95893,485D9194271FB4AC,BAA8DA3D0CB5D3D1,9B9417AE688FC6CC,F985CE83BC3C6EAB,13E36D449D6F5E09,11E50B1F63040E97,1193C906B511644E,B0B48FB26B0A38C4,00000000EFF2C8C5,773A466D1593792F,48B6F9C0F9490055,EFE139E758E5EC26,26300D4E6D66E3B0,FC70C3F4982A4D44,FD76952E8995637A,AB7750FB85ABB2A6,50320C716788533B,15C3C1CBF4F70382,000000006D4068F2,7A1553AD839BE8B2,55CF41E4F26DDEE3,E381CA9BC69D0C4E,B6A20D8828471850,711B2FC84BA577E8,3F57716F292193C5,BBFA5DC5E76744ED,234845F975148F83,8023D615CA51642B,00000001B9A5E965,F455A4578600F224,4CC52311DCE94E90,504483525190C75A,99A03FA147554697,0021F79B0436845E,9A0758A873CA057C,643A4D81DB3A0DB6,47E0D878F1448549,3D71C57C8F34ECBC,0000000130509CD2,E67B7DEB264FEBFB,5E146507D9E90333,D4430AEF68B7BC9C,2F437D030FAA7616,C89FA8D2DFED90CF,B52E2CE8FAD90CE2,C8A281B4F36BB4BA,6E2A2E6305F1606E,93E808C091EAE825,000000027BE542C5,527489C4C97B2F5E,DE23068DC29ABCF8,3A7CF618079CA624,5C3535763AB172F3,0ED35736173E8FE2,C8D0D57F1F8C89D0,A2E28D29BF5C7FA6,BA133834D993F663,883565656A3F6014,00000000F50468D5,AB30D5C454AE9E0F,3F9C4AA66EDCFF0A,C4D5DB240B14F6C0,4D7580FA99AA44D9,6F548CDFED9892C8,1226C057B96BADA4,27475F5AF98447CE,B26784354FDBF977,EE3ED7034A852063,0000000112925D9B,E7D6434B55AD0131,722937A6D1B83BC6,5EC15E0692C2A069,966C5F529FAE85C2,ACE1E15C02D040E2,EB1487AF9B7212CA,37D31B085B4317B4,196AC95C36BF76CF,8C22B953EE755982,00000000833E2001,B51976A4474B6CDB,07EF9475D467DC2B,9F8A0FF9764ED554,20FC8911D7B49845,3E466ACA542F0864,729754A32B1675AF,6B1D72457AC68EF7,92541274B06E6C65,CFAD85AFF5993240,00000000EBF406F5,CC146E6B641397B2,23DC952D5134B979,C434447D4C38AEDA,DE6F5958E344152A,C05BC5F8667E7E3E,1CD7E128E8A7419C,1CB661EA11E0A9A3,4D6DE957AF1C4791,66DE1510B2A9C4EC,000000013AE40BE5,4667E6180473707D,4CFE916BD09F1F4A,A7CE902F23154740,FA178C6B0C3A51A3,DAE5A7A63AA5EAD8,263665703D92931C,1E97B25506B0D464,638F6A64B83C43A3,1215DEAFA41B833E,000000000862A8FD,E12E9A482B940C64,757538B1E5944FE2,720A4300F6EAA698,F5C48F5FAEDCAB43,D1737D463C8ED50A,5AC71B16C421F22F,524BA9419CFCE015,ECB8F29A558D655A,1C73BBD8B876635F,000000009FB5FDE2,E95F0307ACDB62FD,1C0DF4B05A2139E4,6BB2D183AB992359,1EC1D5650A99D244,DFDD9463631F9C0C,A1B3BBC8DD909643,C2BFEE9C17DA2905,4E15DDCB6551D329,9575F63BB956B0B9,000000026ADB5874,C3F0F8289A4A1833,74776C6F88CE7867,3B02B3BF3FBC3271,8D84021E5FE976A2,07AC3DD20719A55D,78A9E8188547DC8C,008330FA387B4FB4,0173A69838BE3050,0D9EB8145D95FF22,000000022A7D05CE,AF73435B1F4A0061,247552AFA74E888E,B3F396FA864C0104,34AD50D3F5D14DF1,2E7C05B90777708A,DAF29895715856D6,A88F36D059E697F0,B3FDA225053AC13C,12208665F14B8802,00000000EE928BE3,9B0A85286FFE88CF,AB54EF45824B2EF4,2A53C215ECACA8D4,D3AF3371878D7479,716D0BF2AD03F36C,394B07297E623BF8,CC97D90EFC5F3212,1942F7FA3DF5BA1C,B1E09CE3839F6EED,00000001966C103D,8020589A85D03A59,C41C8C27405CF7A5,5C51D0B96653557B,9B5AC48EB8AF2C52,9426E78841C3B388,D28A3C7107D10968,30FAA9597F24BA08,E5866A70BA9B2A2C,02AF8E56F1702669,0000000256407E7D,821DE68B46992BBA,384B7A579A2BAD73,A7BE59DA42E25953,3A8D7394C8FE0700,BDE97ECBF17B006D,D4F82CC3AF596B05,90D58B973C2E72E9,3C0E49206BF3C1FD,8AF8414270E7D649,00000000842DA8C2,EBDBBA8F6EE79EB5,5E121F4602A06309,CE2DD11139C697BA,9A6898F52CF220D3,E6CF37F59BBF7071,ECC689D6119748BE,5913BFEEE688D57D,00BF3A115DA84603,F0AE21F53E7013A4,000000023B66552A,4219DD0A06A2F8B7,4D77A21E3CBB2501,52A3F2CAB0E6DF0B,692E11D2094CA249,D5EAE747C9D4B2B6,6E4DA6FCA4A10BCB,AE441BEC88989E67,A010FB75239820FE,111E5CC9EA20E526,00000002068D4C83,6DCA3A4E4DB452B1,3F0C444E7E444C34,ACCDE083D70BE70B,6169855F0ACEE7D3,293E93B4A18AC1FD,3BFC691AA234B3CC,BDE8D6355CDC6FF9,8956D672C5B89B9C,1F7D7E5AB0048C6A,000000014EDC8084,49B775743CBD6957,5BD0D45DC9EF4F27,6162147F40ABE6BA,CBC4325206AD3259,19FDBF2BA70B7BB0,14865C7E44BF254C,55D6DDE253CD5A94,44202FE82188AA3D,A8CA60907410DD03,00000001C4BF0BC5,78357323A3FCC517,6C5496610F119686,B1226DBB88879DD3,213EF2535113259F,A8386A6225D55F3B,EFFD4CB519F553D0,CD056FD5C989FE42,6535CAA386A3BD52,20AF376A82ACD8DC,00000001320E14F7,CB4034FB2C43D48E,34677499CDC9D8DE,EACB9192680BB653,14C43E9FBB67666F,F73405FB847FDCC8,A467EFEA39453988,664218495D720627,4A34F7B06F29B0C0,C582C6EF0362F0D0,000000009C714308,5BB01D62E8EBCA4A,F1E4EFB42E124509,5D018E409243E150,637F850E543E68E3,3943F1DE48C920E9,71E309061111296B,522DA2B3B361A043,D816523EA0F2AD53,849727BE70B98B4A,000000006F152746,2A7CD5ABCB6393BC,8D5037C382FF9870,5D3B509D8B40E11D,EB7D2AF0FB9BDA05,3DEBD25162918AAF,29305CCD0B8037FB,F5C633D9B43BA3C2,A71229337523F190,F44214078E5658E9,000000022AF644E9,D95A1EC676F925AE,D3988745BC997491,EBE915BE02953463,9B9D11D068A78F63,504917665F0CE4F5,04C847CF52F8D26C,ACE81D4A487F3D3B,F6170F1A2C92EC9B,51BA9EF8428D5C9B,00000001ED26221F,D811932F87DC66E0,6ADA41BE7D8D3190,1ECDCB36D9947ED5,63AA29C74C746ACA,4666BC27BDA14A9D,B3DE03361E6EA188,BF7557FD2BC04937,5B3E608737392EAF,2999CF0AC7F2D52F,000000011F85A403,229BFE2F24B7B84A,F7024A04F68004B9,DC7F7EFD89F1B180,D9A82DA9BB57C289,6A331E54E5E06F03,EB9AFDE00DC8F70C,9811C0FED6CEB378,DDE684D27F3A3A40,C1249451AA100A98,00000000A8459361,CB155BC8AA103F32,238AA8261CE6C82C,BEDEC57428E7327F,1A95BFE1CC5AF81B,A9AB9B9DC4977805,D6B404AED87BC7CB,F80A536154745DEA,A4CD2664685F9AF4,06A8AEE8DC56BCD3,00000000346C2437,AED192C6E514817B,F3B76C8B0FCDB093,B5AD044BA51A2768,4D64A1F05BCB81E7,B36267CCFCC26A04,60C3CE4DE2B869FE,58F4FFE88351FE5C,26CDC018EEB63A00,D21F687F4B0CA2D5,0000000092725200,1C0685A0BC053586,FA342C0EC3E34562,8D73E5FE304FD7AE,9B788422C1CFBB0B,E620A016C3BE4D55,C211BB0EDFE818C0,129A96059C52BE87,55A77FFC4304B1FC,020AC29E86CC1EF4,00000002083A1BBA,4234184BD7DE9257,FCE80782C7C24E20,6DF2AA9F906BE08F,65AF68A2DBD5BEE4,79A7D1E0731E4C2E,B057445E80C36A38,163C585A69F2D482,0BF4AD3C971DEB2C,C7A9F97B3CB56450,0000000094740EE8,A166211027A4AD25,8071ECC430E4F2D7,1B8F03FA5F16B99A,A8BB3A5CCDB26A3B,FB6A2984F42AE907,2FBDE0EDD815F480,A26A4873F10BA103,A831F46540C00497,6165B625C17B710D,000000008FF871DE,C26BBDD07043E08A,97ABD8571F464CF5,A4674EC92FACDA5D,478F124DA6004959,DFD602FC084F45A2,333A687492CC8B90,052B9ECA222FC1E6,6E4298F609DC3FD2,CDE19171EA01AB4E,000000022DC60071,FF82C2523872FEF9,E6C805BA58A902A3,59878BB0A2FB7B00,2F5D02BC91F4A45C,F2599FE1EA4936A4,5AFA69513CB4E21D,1B1CC86655A0AFD8,0B038A0FD871B7B3,75DD6C7241DC12C3,000000002248C4E0,13A17352B513DE5F,89054E8332CF5EF8,18750F9B3D11501F,0C49E6567C7CA21B,F2E0D4906511745A,49BCD63427CC7ADE,28E02D683E170DF7,203CC9D080FAA2E7,551D730F23EE51CC,0000000215927E98,836CE74D185C097C,C74EA3039564A2DA,FB91F25B5DC0B635,32B4ED0FCC4425FD,9CCB42383203C53C,E1A4D3197745405B,DE9D20D1D85506C7,614530153AF4E410,E69E490EBCD7E50C,00000000DDF4C81D,97AD64CCDCD5BACB,BFE2673A61A74103,6BE414046C609831,5F685D964E8AE9D2,DE18AC6C5E7529AB,B0CEF69F137C44FC,A232B4EC1F8F24FC,8E1599620705DFF3,84B6D296A8972BBA,0000000045847C88,C9282AAB88F8E142,538C229979395856,114BA6053F30F833,064A293519ECE0F3,C18490140DAB46F0,5A6D638DA4D7B077,F8666C7B0951AA56,B09E5A927CBEA8AE,DEF116973BC7AA4C,0000000004823A7A,952AEE798B0BB40F,4F73EF9C61ABBAFA,2FFA54EB30BBE8B3,16923B9A64A86017,1D13746C44E00416,7C4755D15BF2C1B7,6D98510DB8A75AFB,911B3248C34805CE,4A4922D60AE3FE5C,00000001572BAC22,98832F8DFBB4BE14,8BDB92DB8CBA5D25,6DB532596C354737,B7CA6065B866261F,DEDA91E5E7B5B5D9,51757A083C069854,D87CA44A9299F11B,B8D65A92789E527B,02F97FCFC935B772,000000005D6111B1,F4F777F917F17465,803DA859AEC1312D,BA6661E152545267,A0DD960C16F99C3D,D6B897AE5F31C7A3,0A6E7A7FA4A23C58,2BE318FF3830F1CC,F2D5A57F983C7B76,AFB77587025C8662,00000000F8FECDF4,6F9F238F8E721EAA,80B07917D87FC5BF,8B56C9CB4DDA1F4D,CEEEB4E551156B77,2D949009D06623B3,B7613F62A9CBE28A,BD1FE08A6172BF1B,F29666C125395E3A,C3332F3A1C578191,0000000102499F66,29367995CB6C42CB,31CFA09C34A7C3E0,3F27B71F564A4B9B,E2A4EE74E7F3F1E5,B65F4081C3A3E133,1BBAC267855AFB29,F4E4C9251115F6E3,1D819626D835F50F,2A1843FC200C7571,000000020D9309BB,D10F842E7ED0B4EE,80BF3D370FF0ECE0,B5087696D5F13ABE,25E7CC1EEBE2D28D,F981CC5C8FDE7328,7CF29CE87D4723FB,8660F002F91C2875,092CA1801753795F,5CBC7DA62AE8E27F,000000013F41C780,1FD20FB269FE5474,2E50028472C74B6B,D9012E3C87C0DAEC,5470F2171669FCF4,2DC86A9272EED7D5,620E0E57913256A1,D99ED8C0B9DACFE6,057AE070CCC7F7F6,6A5E787FC522E13D,0000000017DE3202,4855A10763EDD0B4,B622ABA0D3F6FE39,3D0B0B7956864950,F3F12324C23ACA52,DBE1A62EA95CA7C1,05A39BBD4ECF9A01,A1700E68C3BC95EB,C7F766ADAD4CA79E,3276B3FBFFD6B3BF,000000010F4F81FA,6D756A3B6184BE43,316A28CA92539BAD,BD3D98DF90CB3E6E,8B23F6830596C821,BBDC462B487767D9,CD6126C8D4E82BE2,FC77ED83F1E94CC4,679C6C39FC03D46D,CBACA41F9E2822CB,00000000E8F1C778,0029BB1F90135ED9,8ABD0EE760CEBB9D,EF387DE532B1E2DB,C4791E4BAB451464,E511F4DD455C1BD0,3227868DFB07F8CF,C5D4918EEB7C0C9E,FEBBBDF4EE37EBD2,749314F605791A22,00000001069DD354,D9D69EF3A622A530,B9941E9C038ED2C3,D32C3701BAC3DDFD,B96EE7EDF120BAD3,AD65AD0BACE6F1C9,C7D7E28D8AF282B2,483A91E123C420D9,5BF485E1A592F21A,A0C89E26ADC1567F,000000026FF02FB9,1D9867F6D4069CD7,94A8619AA1B18C71,3C0C83EE0DE3A88E,BD1B9904BD074B81,142ABEB6FFA3F3E0,BB832E7F00F606CA,5735AE6FC2CB1D12,E9629220844F80C7,FC032252DC85D71D,00000002625A8883,C11E267FC28978D5,F94BBD096E84635F,83369898FC0BCE67,1A8FBC9029B9C66D,E23B3B89735D2BB5,8645107F14CEBB66,FC7C97EFD7056356,1C619A6F5853AD85,A28F36CD3CF50528,0000000234C386EE,D7553AF8DC80D7E2,601FBB3D9AD70FC4,740C670F9A81372D,0CE582B7731FC541,68C6A51A6A0EE0C3,7539BF0073DB8812,916458B8D85AEC97,B71F6BCEA26172E5,834C134CE8D53CF6,000000020EC674AE,9B4D7C2B4C801D71,9FFFAF4BD4AC8AF5,94ADD84043B10F80,A53FFFCF728A93A1,8DBEE7A340C3745F,652309AFAEE8FE5D,3305CA71B6668E13,BCBB94007C48AFFF,571030D3541B41F5,000000023EC84CB2,7A46C9A77FF8C07A,3A86E1186398DCBE,1F35C60E4DEC7B13,4083DA3CC7F07EE0,5AA3BA4E95FF2420,9A9ED579359589FA,171B81A603A235C4,007E5CAA3C2F920A,899A7D2F0CE59475,0000000247AA1046,BF70B84A77CBED7A,14406BA5D0A2B5AD,4E9477E5A9274855,111CC5C86BFF9250,C7D4C35EDC673BBA,87F0451A204A950A,885541C979488159,DBFBDAC536142241,00C8B80326A9FAF1,000000001D757895,FC747FFA693D5D23,A1A330FD975B8EAC,A5715AD82E85E456,62661A179FBEAA8B,A12D869AAD7F46C3,02E0974D4B3025D0,C0D4CA015CB86F99,37E3E1C306A12EA5,5B0AEEC0E401E1F7,000000021A3B8C87,E8D38F2AD69AE1B5,8206F5D1641D4117,EA30EBB5CB070433,5D163795CE3E5268,9C4C14358B4392E6,FAFD06000702B799,68BF8B4A2EAA2816,FA570B56CD4B9739,DA59FAC3D7AD1A8F,000000006E3F9496,1246A6A8A5F7115D,18569416CB2CE3BF,90EC7FD87149FCC5,992AC0826C933DA1,F142536296F4CC01,E0FBF5ADA5829352,A680BF22E55A7D10,66484162F5220464,9214627D691DBE5E,00000000311946DC,6D35E55813658F97,92ABCEDB06C1AA58,6A26FB13C91A1E3E,9C1E9A236D619761,AACCEC1CEA19D5B0,5FE0F1F77D2FD8DA,C2E6EDFF18947068,2B163335F5ABE340,B2680F59FDC356A4,000000006C9B8059,602A5F3D5094D540,3681D84CA7A0B2EB,680A09AB4E6C0640,25AA70C8A995F8B9,85AD6A63568272B8,85A74A5DCD2D2CC4,15EAE6C6115E3627,83814F119B736E2E,529DBB9118EF4B7C,0000000143D34D04,227716EEB9595E1D,8D48333A2FC17FFC,E0C6543D4A6E9DB8,085B5B3C12FF2E2C,5DE8848382903918,3A4DCF8DAD58158F,B14D9DA43175BB8B,FE096CFCE309CE28,53FF13F51F32C904,000000001CA7CCC7,E6170CF1B14EC5EE,FCED33A8BB2F037A,C27E9884CF58C47F,70DB9ECFCC5AA66F,236DD24B3714CD91,0C4A785F93A9F59A,08C178AD5BE9FE04,EEC5E7FA9A7D2E7E,F14FD07829C02812,00000002346F469A,DB973586B935EB98,1B5AFEACBEC84B1B,5DD4F5C4BF79B518,B2EC272A223502C1,B1AFAC484744C9F3,E881F815689C8316,C26F93E75EDB726C,310A97980BAA1451,66700C04D02013F8,0000000218BC0CF4,B372B706E105C35D,D7D3958C8C94CB64,DA2B09392625CBA1,0C5A2F4D9F0249CD,68DC3B72A4E87A3E,E9327866DC7D0783,73F1918BAC776051,72E9A0187BD6A03A,CEBB5D5FDFF0C2E2,00000001BD1A19F2,1C0D272C5409B1E5,26C153BB3D38A0FB,61A6C54C0441FC2C,5987F8FC88756451,C0ECAE9A4AE26A00,B2BA14B67E7952C1,99B0D283442DAEBF,921CEB51D8B1039F,30C56C728A5C0D26,00000000C217621B,045425F9B58E3C69,54B0A885715382A8,78AF3B4D0967D90F,5C40A43D9A2F367A,A93ECCC5DE5B7AAF,EA1A298A062607E5,76847696880EC39B,129EF770CF90C51D,A14F3883FD8C3B30,000000021AA0C489,ECA748397F23F1B7,6BD5650107DC4F82,8CA27156F61D9D33,832863CA30F948AA,7B15189E0BC64CB1,FB0EB0A3A6643FB7,761ABBCE9CBFA2DA,972A73876BDBF1ED,D2170ED5D0147F66,000000011E2714D0,DBDA87C87CBC2829,2D5FBFDD8E6F82DF,DB48C65CDCF21B56,8F9055C1A8BD7DE9,2D51ED3E02586E15,997C33EB1C0E9479,2E1CD4E398973760,9973B1B844BC2A51,BE0E8A4F580DE252,000000001F8EE961,75CA85E388E3F415,6556363CCDB9C532,3F64DCBB84BFE585,1691B1644E88BD3F,9EA449A3E5795753,B1AF7800A3F5398D,534A93CB7AF2FC10,4244E6F1C44F7430,E90962084B313636,000000018EE36094,796FA13B3355344B,59FDC7FF60A66207,0217BECDAEB613BC,0FFBC07C298AF783,7A7653CC4E361BF9,CC6AF45C38633C1D,D39369D324A8FA58,7AD8141C03AC2E95,8680712F787E891C,00000000EAA1370C,B8A15E4EBFD49E5E,8EF44E7FB4CA70EB,133125E89BAA5E49,C8B0FD7152CA57E7,B32BF0153C2A1E95,4DECFF07C99FC4EA,4AE3E72CA1F989D3,1D930E81C5B089FB,9B276C57E0670347,00000000270FB17D,C2894D95A1942F54,032AD619E55F2F21,0BC433D191EAC970,400DB33CF9D822DD,868DE669923D868F,4ADF10A6FB10348B,7A30464A91259E06,DD2DDB370F2C0CD4,B25167C8DA40090A,00000000BE9BE1A8,EE3D479E411E4374,F38BCC41C13F2502,35090EFFA7D6CAA0,8F02FF0654C61562,40C87C4EC17E7930,74E05C1A5B1414EA,AD22127865AAA491,1C93B1AFFE3DB52E,0E9B3078B8952395,00000001BDEEC0C8,1D46F4787D7C4E5F,5DB2916672528246,A8E7C8D282FF9EBA,6E1CB9D7BD445E0E,A44F5A18D1C05E4A,95DD956265D0F1C3,64F35E9C95B1C3AC,DE2692CA8BF8DE2F,6DDA045992503C16,00000001D3E93207,47FE27C36A2F9A2B,C4B02388C05FADDC,6EE9F9575AC882BC,2CF50D1233F4CF2D,C0F11298FF2F24FE,0D09B826876FC2B7,907E0143BA202C8F,4BAE403D7071D89D,E5421A8057C0CF14,00000001FD03C993,15819EB651FD9835,D4E6C40A6A01C401,54DB450E926E24AF,39B4C116068B9B72,A3F7574214359D0A,3956C5D26983E6DE,49200FCAE63E3730,E3D4CC0E8C390A79,1E6A06CE1E3B8A4A,0000000016651FAF,0702DAC39E53B620,D04C5E6B7AC14AC3,775E29D587114CC8,B7595A4767718A37,BDCC0B27782DEA2E,EF1840DFD6A1E677,0EFF90903A92EE1F,F98B531040CEB3FD,C2E0FC24E3BCACF1,00000001B419F630,5E353EA1F8674171,9AD31D699D6A7C76,EA2C79B210BE5484,0BF3A67940734995,D1DDA6A92923B9AC,5116CA7375ABE4C7,5F3A9F4F105ED90C,1064A1F69212262E,5BF67CBCB7270EB3,0000000145583C08,0A955D56A6B14125,83CB4DACF03624A2,54806FBC255AD6EC,A154CF197C88E97B,EB01295C133F72D9,6DADE63394DCC2DA,02A710E97B956BE0,B7F802B04F7E2600,506655967BF57B46,0000000101FA5B84,866CAAE8F4CC1572,3A10A60EFE8B3CA9,046389447D86A19F,54852822C138DA32,CE2BD69691C8B0BA,E91EC34F185DC5E6,6E142B309F182F36,EDADC13DD9F2DCC2,496B8505FA033BAF,0000000043861FCC,0DA7CC316DC6C7B6,07972E420C0BA19F,CCC9A0525FF5E01F,0BA0D4AFEE025AF6,2CD49F21B3FB8DAD,8FFA3DED05AFA18A,843B84F838759E4F,D10C7008F365BB62,5CAD3A01FCF37AA0,000000019F6CFCC4,FFC31F955B1FD917,E17823E9845EB427,276986471E9C9452,C0D0B9B489EA2811,14E3E503FC3C4FF7,B33549D760AE26B5,90B6FDF6E32DE48A,ADF34F45BB072D89,2315A73A13FC5812,000000004FB86E5A,ACF854C736A5DBFC,A27DFE92F587024B,DD26E011BD3B3E67,93E3D2B6404541C5,4DD4099CB5A7811B,3CA2C31C48F7762F,3A5E70941F650F74,1379FC7DE1BD684E,5B1442F31EC17D9F,00000000B4C8D8D3,94135580EE21928C,3B7F639046EC8902,49537F293ABE8BB8,E291CC6A8ECCBF9F,116307F20C7CDE50,6F3EE8369475A279,B27ACC84B0ABF6CB,8BA553095166B121,B176F863414CB9B4,00000000710EDB7A,170A56A320FD2686,78B839B8FBCC99BC,E88D44B7980A541E,00F32D3B9BC3EC08,76666AD1E998E494,604320EEA160C010,FE160C9BB3943B56,0F42925F93D619D2,78B4034C577E010C,00000001D15AEAC8,2BB9931C8A6D1F97,9E7BC7D8DA9FBD8E,CE3DA5B4E4D79861,5F680C850AC445FE,0FA3C32444B760C8,1C08B624A8D06880,70FA36A5CC406C9E,2419797799DFB816,A09996BE5CED8DFC,0000000217E902F3,3359D5FBEB0B744E,750C62E3013F8C0A,9F91F12A759B8794,A029B4EB77AFDB45,707A6EB57945BAD9,3D5EA4E851A3263F,0F41ADD6DE373642,6035E0300C015801,B2CE9F99A7DC1C80,000000018EC9774B,3250DCB7BB91F7A9,7B9C4C919235323C,18CB82A222671EAF,4FBFC1EAD7484813,0DFD72FAD56A30B7,073DD778B20EFB49,55CCE7E18F562CC4,43560196F1EEFA05,2703BE58B59DAF23,0000000180F1919A,A14D64D3B8B673B0,3ECDB59E3224DFD3,A1DEB4A80EB91209,D934CFDDF1873EA3,9116162CA1208696,BF68AB401C58C8CF,745D7C0FA5AD4347,D72BB4AFF0F8378E,E458883CC7225CCA,00000000D34ABD84,6532405584D9E2DF,2DFCF173F45ECB2A,082EDE7E37B9CC89,61ADAA99D72193CF,6A0918603E442A2A,A4B945387F41A626,100BFAA01BFBFD32,9BDE3DFB2CB0F891,155E4D4D44AF7AB8,000000000BBB6D44,7E9D5690708A4E89,E1A5141D20A91C88,AB29C5A174B22A14,04AD6DF8A99D497C,469CFD2F659C7FE2,9B4B9DA575C2E7BE,149C944FC92C6394,6AC7A5FDCFFD6F6C,D71BDDB4FF0FAA9D,00000001FC1F044D,A1026CCF86ED664D,86581DBC2553DF0A,964BAB57C46B5C40,65434CDBD1882BF8,8E189C11263BA2CB,9DCD8BD385F3E58D,5C52E43DF99279F7,9EA9DD62247882E8,48E1C477F9301E82,000000024122B892,57656D24F02468EF,BE1A5E3C7973A8EC,EA3FE3BC23AC4B28,AA4EB14E54FD3405,9C9A18EA2091943D,D8154F4E9BBC120F,E8C81C8B085A3C3C,E63B6B48E884B1BD,1F51AA97C767DB26,00000000B9BF90EE,91EADCC061E2CB19,E26A0B72D04E0B7F,BD9256FE8AB32041,3E0C5826323ECB6D,D5C0BF19B4302846,B048A24C59A96692,54DF7044F9F4E6D1,D4D7B94DA2A0AF34,1B1F50CF904DAEAA,000000016F8645AA,38764451797BDEED,EB1BF2D30E848764,9F2AE89987725995,49F868BA646A5F58,7CE3EF5BF90BE6BC,919A2471CECFD6CA,59AE5CA7866C90EC,3DC4CB2D86809F7F,AD1FA01E4E6EA65E,00000001B433C986,E4A75C43AB9FE5A4,2D6656B5D38F7385,BBD6AAB7003E4191,F351A894D4332296,20981D1B952B0FE2,AAB16595BEE5D25D,9ABA6048CC3AE6C6,D08BB40513959D3D,4FEF3FA17323E1FE,000000014DFE8F43,C38240740F5B6210,7FC15B88243E5A92,AE9C3E18CDF9E9E2,83736AB7D38EF096,889075BFE3B7FD4E,48AAAC17541B6D18,9F287C2732D8AD17,B9E147A8E9147583,F4CF4B0600DE1512,000000024957F0E1,627A7EE430D600C0,FF669315FD1A063E,FEFABFB5B129719B,349939D9310A2482,497424B9B054D040,FEC595F7CFBAD8FF,93F3229C2534C014,F42AA2E12A6638D4,FF22FF68DC36BB91,000000026B0804DE,0061C81922F22E92,1783257C2786AF8C,A2E4995921D1F055,E588F79443993B40,8F11380DBC3227FD,5239C74C31C6658A,A3877E77386EC599,0ABD6D374C3C887D,209A1200DB172260,000000014C42F642,1309CE84731F2353,352EF15D14F19853,F055BEC9834F5ABD,223EEC57A523B339,A7552BB8857AE14C,5669799A85557DB7,7F20897A0823E928,AD61A23E85D23A4F,CCDA034D130255A3,00000000302216B3,2C276740150D60C3,7787414666D970F8,FFA740ACE397AF76,6648D19B7117483D,0AEC1DC753EC90F0,FD83FA816DD722D1,26DBF7E901CB8C2E,F59FA54235132A20,DAB3550FD064CC02,000000002D22A556,C348F1E9646C37B7,7C377080B1D38A90,24E895E773FF7694,664796A7FD546E3A,17D56FDC24FF2A7D,7591BC602F32B73F,46A3C1841990B259,3F616F055B646273,9A3E25AB08AF8E16,000000006A9B23FD,61AC1F8DB0833A60,D88BFB548022133F,BAF3C188B15D7031,F98E3C19E383DF55,AB4AC57F5118C8E4,41DEACAEDC0FF459,4214B9679A180B73,F4094D46A3BBC6D6,35AC1B1ECA76ECC8,00000002139FB652,F9CC352BD800AC6E,C3CDCD88597406B9,06BF41F4FBA5E458,06427AA766AB74F7,D5A8E2F4ED7846D9,5C9DF238781B16B6,7D19CD811B8B7997,8959BF0AD05F8A18,4A03FDE81BEA9E42,0000000241B205AF,CF9BB4AD196A61D7,86BDDDDCE475CA3E,04F293E9C971FA7F,C0C22CEA7F388AA4,D0C6CB92202789A5,C66D5A07D8440624,C399B93F7715F53F,12AE41CCA7706039,6866F79E79EB1560,00000001E856952B,B15AF9C55A0A3570,CAEDF7A35D103C05,8DA4C38D1242E5AD,9B775EEF3545184F,F0967F7E6BA96441,5B82DB59FC56A2B4,04964EEC8222BA74,634FCE356CB0D950,E1521A44E856EAC9,000000004FC2ADA7,2DC9B6A613513C4E,A1CF410790A66690,C561B52CF323F8CA,F698985F9E2F6923,3CED7F3704BD6537,1F09C1DFB23B1D67,E655D37F8575705F,5864C738155335DE,09C476CB61274D28,000000012F94ED43,1E93FEF82EBE199A,B7FD1D707A9F52BB,D19B44BE91B9BFA7,CF6C06357B44A158,CA64A5F3555A891A,93CBF2449D599F5C,48A24BE7B8F2F149,28C433446CB52E6E,CB711921101184D7,0000000180D95DEE,90EBB5B4C32C985F,53CB97C553CA5056,E73CD71A08613E0B,7641BE93E5D766F5,367C94C77FF283E3,580340358BCC7182,30CAA3C0FFF63EA1,3DE6BFA60D25F076,313351BF20A0D9E0,00000001C44FB061,74662EAC75D30147,E9E22AD32FA1E186,AD047ECC33C6FDA5,8AF6DDE0C9DB6A84,3E813BB9A8C72700,434FB084919E063D,18EB00798FB32375,84B380F0D23150D8,BA447B26BA38D5CC,00000001258E38B2,E7A6AB4CCF3CE245,3E955D9EEDB5C831,AB6403BBDAB7684E,B07CF41633A5187F,659B0A9B3C8B01E5,62C6479203F3C54F,2434881C580560B0,95AC1271E0E17BC2,790C36A8240F35FB,00000001CE05493E,EBE5CF9EC6F4E789,01FE7F2D7162931A,C0BE856B10906690,7B9AEC14E52F03C3,2E2B6430E4784CBC,4CCEC46850E12C4F,A32BF1E342D0C595,085B2DC9B78A9988,8CC475809D8CFF9B,000000004E191552,C8BDF08B03B50D68,E2A2577A8D92F3DF,A9D0C8066FCF98D0,0EDFE36B35E42158,8CF58BE261E4684E,F00E5CB241E1027B,4E863C97272C7F79,57696F9ED757F40A,FB0FFA5FA473CEF3,000000022E27DEEF,4FE8555B56C1BD49,E2139BE91D6DFFE2,6B5FDDDBD5140DDA,F57A737D864595F2,A7A68ABB28285DBB,C4987F7CEA82B875,4288C4C271B690FE,5FD076DEA09FA203,694C66D4921BE0E3,0000000073ECB0CE,10FAD587065701E4,172554852754535B,970702AFE343660E,A1DA92D7D7533678,07F3F8ED7DA06FD2,F4A0195599889458,54EC69D12E946B86,BA963ACE5E1B48B6,031F95212A531AA9,000000015AC5E671,50C41BDA2FEC795F,9851BCE0683E4AED,A85C68A0DB462BFF,3622327EA2B77A06,3DBA2D212BB9FD09,172560A89060A03A,A24BA680CE1491BC,02202048EEA6FEE8,F4AD89DFABAA7671,0000000133EF06FE,51ABA5B8C9F39A58,43AEF284EF16610C,4DC1BD5BC857FBBD,0FBBC91D03D812B3,55B3ABD6C9F4BA96,7C38E84F86E7D7EC,4BA7D3E55DE75498,422B6C6FB33DFDB4,D963A97C2BBB399C,00000000F99C346B,1AEFE94D9F0384DD,1EF597F4051E779E,CC5D98F2AD6C79AA,F44866BB666BD7F1,6B8182A1C4453FA7,CED065B8FA33DBBA,BEAFD26777C8E538,4EFF2DDB02530B4D,D1C2B7435CDC9B0E,00000001702E57D1,DD2D395473564710,23E02DCE3AC68EB4,AFDC7B87B28DCA81,8390115AFB896940,D68CC61210715B84,2CBF7769C7725637,31C81506542A2EFD,868649A0289BF22A,3C594854A0458EBD,000000024AE087A2,1B03001AE3DAC907,E41D3ADE59EF54C4,77CA4D3D9FBCA996,A3000E543019B4B9,D45650271C218AD3,517E366973543A17,4C41F78134DDCCD8,CFEBCF5485CBE712,B802357F8BC9D45D,0000000099579DA6,12E631729459877A,83A6DEB425250E05,A6F2AECEBCB66E10,8E11A5DFFCBC9741,9AC8F60C15C1372D,22A1C36DBA018808,E00B0AB21259A7B4,031F646A41E7483A,991B3C6D537FBE9C,0000000030A6853A,FE559E5F37DFED6A,7878B5D2A7C5267A,497E8209AEFEE750,6EA70BDFAE09CA57,661F90F279DE5550,BC9223B7FA677193,44271DC59C567926,53A56AC45D566FBE,9E8747264794AC4F,00000000BF28C98F,13BC77C96110F4C7,D4F0C81300FDAE76,F8703FCD199A1383,F3F7578999FF9894,30053BCC51FD4DF5,7CD776B5337B1F55,A37869FC367F97D0,73AFA4775E287B15,47EDC8C88C51ED73,0000000055073F48,AE3E683132D744AB,1AEA48D43A4485E3,2CD19F68A819303E,66C3CF04EA756DDF,DC72FF13051DA36C,028DB9F1D2278067,AEAE71665AAC13B1,143F26FEE81AA86B,2A569724DF93BC22,000000001D9867E9,8C34003A59D7F68B,878DFDD17C593D64,52DB0A614C073205,9EAB4C89BE42BBE4,2DF059A602646115,FA63787F4CE38E84,87C290686A76C061,60212DFEFA06A023,E62E46AA7EC007D2,000000007CD1FA2D,BBC3D9776A803B88,37A180817A02BAFB,07674FEBD57051AC,934C14B02299148E,705983E12A5A37F7,36A46E80F66C5326,E179731639B1A120,0F9ACDDED5536E74,363B7C826984CF8D,00000001DEDCD40B,21880EA18E472489,1A8A669DB590CE11,47B6293307EE1BD5,2FD9B93A19E0D3C6,6E30BF7808C56F92,847AB04796066B38,F122D41108081E11,73C1CF2EBFE0629D,F724F98A5EB5692A,000000023B1430FE,15741C47F6BA28C8,7B6A218425D1B6F4,7B1AE009811CE985,589760B522456ADE,D6E7C0F3CF94B527,01DD856E3FAA494A,052BCC112FF831AD,E47D82F23EE4819D,F23BF347FB1FECE5,0000000194607BA8,BBB146B3D4201BB6,EB8F761A551DC4D5,CB2E1060C16D9030,72152CABBA38A4F0,142EF9B0AB21DBDB,019DC64E97AA327D,3EDBF5A714C8653E,ABC8EE0BDAC6D76E,493459F96A2FF7F1,00000001F58F1B2E,1CE299CED57FED58,E02D178B6F171CAB,3BA26D2097988FC4,C7FCE1223A20B2BA,6A9043FFC8169BFE,BAE7BC00B30D4B8E,6C28F385B33E9637,9CC8B5A205E1409A,19C19965DC26153B,00000001AC108DFF,4C103FB46EC2810E,008FD479EEFC6262,BB9C69C4FBD799B1,F3137A2002DD7977,D599F104FF7EEE9B,2D5DDA1EE0158DCB,A853C024C91F8367,684579C1EB1F21B1,BF58284331D0E64E,000000022D5B4871,83F62457C9DFFF03,83C223EE0DABDFCD,0CD142B7A51D2D2A,AA0A41B80E074CD9,BE22F926B6F7DEEC,66A0525FEB0C3DBC,A970390B9BC4C82E,F40F28FB895F4601,708D6EC42525EFE5,0000000138B8EEB6,860798D6CED96ED6,1288CF0BC6A0B4B3,9B23621BCBF51966,5E5272A019EF9A74,0054A7888A069BAC,C159FF6FC69E0DF1,CD117C6C948BF6ED,87ADB4DF8243BC46,CA3BAA8336DACD41,00000000DA48484D,598678FC1656594E,CAB88D8C1FADDAF2,01869A9252181E70,64C6E4A3A155FB98,D87B37333B5EE54D,34C230496D3E3D5F,08E57F824317208E,A5B30EE3009DBD08,28565AB283802312,00000000E6E75EA9,5E6CBA2D16FEA968,651608936E196632,FE667E403656B810,1ACC5711CA9DA7A4,918A8A34556A0142,F9B2672BFF05D899,A27388FE1DAF8C93,BC57A90996783903,9A4CB39834149B67,00000001539D9457,0646B7F2D9B42613,090F7963FAADCD97,5F70A53ACB90DCCC,CFF232FFAAC9B4C8,639388D1DECAAF6C,595E7BBB7C63F012,1AB62634D5BC71D5,CECE1E4C8B8DFFE5,CA02AE5C1E5A0AEB,000000021A9E66A0,ABBF99887001D305,5562BDEFCAE31263,E5A966C20A16DE16,6DD20156807F912F,E4DD5BDA1CF506F8,EF0803D886269BDB,0D5AF70F33AB4D40,1427E4EEDA22B688,8DCFA629257ECAE9,00000001294D8FAD,69ADF760473AB737,B4A8A28ECEE2CD5C,17248CA34956076F,5DA4B6270AE9078D,28182E1AE5C48174,48F196DE8D8043E8,B9998B57A25BD1EC,2F729CAC3D7AB470,D2022D369C00CB7C,00000001048A2CC6,DF5A6B116368EE4E,7C2BEE885E77E463,40B10712FB6CEC57,7C5B26E9F9FDCC25,9B3E2D2DA623D324,A390AB2AF5F78859,733D8CD37DF6CE3B,ACBC4069C2589D58,BF12E47547C37BB0,0000000265440E34,20A3FA9BA359D7C1,821A5878D66D4136,1B7D5A26B50B37E3,486E91DABBA9AEEF,920BFC7E8A723229,AE81C181B8D5C774,0859727A8F6C1C46,BC27420ABE309DC8,9EAB932AFFD038E4,00000001AE926728,314D611B9F8B1858,B228F54CA9F3F507,74CB6131C3C11F6D,84F696FA26F568DB,BB34327540A1B314,A9D8AEB2C8F9D596,83E674BAE38E70C2,673838DE1611B708,D081E9237BD87232,00000001B423FADD,949A41E9505C171E,67EB1057BE61B6A2,15648F6FD10F8102,AF4F5DEB4D94B024,8D97167F2C61A69C,ADF566F0E2E68483,27205E6CD03336F9,DC97FC248523C48B,FD48ACB39874F168,00000000836DA45B,F0162CB7B3AC437E,D4274D1FF42CBE54,9E6B8B6F6D1AB09D,213FD9DDFD319C88,4F8D15616BD668D2,CB26BC269BE6A85B,309A33C1E3CCF87C,DEB4DBF6E907FAD6,63150D674B8789F5,00000002071643E5,8DA00A76104BDE6B,6ADFE424564796D9,83EB3A1A02253AD9,3933644606A47877,9A2AE7F961E72214,0456866760C808F9,B4962643A7431B48,CE9908DA01B9CBA7,0E200A321D7714D9,00000000ABF6CC69,173267358C6D37B7,90362EE282E31C22,EACF0B8066516A0C,C249835E46E6FEA0,8215CB127C9876CC,0091ADE82E168555,B530D8D5CCBC1AB8,120C37C509CF91E0,69748D463F21BB33,00000001257921F8,2C8019653029A7EC,DF7CFDC6502E91C2,B1A81301549A92B7,D0546AA1C2CB88D8,3F1BD6DF3D6B0C7E,D399113CB7960C4B,E4FAC18CD0D7CFE4,4F657256BFB944E4,D2768DB3FF8A2620,0000000131527419,33CFA2C394BD6334,FA0F1A56854163C7,BB455A887BFBB335,5FC1B5C7BAC7ED58,C7307B23BC1D669F,3DF72E860BE07540,30BBF912E2CDAA60,3F398A8A4B746ECC,CA742710DC569F31,00000000F5A26701,187E8076EA20E584,A051273F6FADBF2C,305CFABE7D0483DF,04050C54BA038590,832637E9CC5D1EB8,832C7C1597850E55,3B1F63E8D7942658,6915E8EF3C18BBFD,34D7407DC6E9B332,000000027A81A60A,F93ADFD2F468072D,915603539C30A642,0BA259D6AB8BB528,04DADAA769377810,063CC785118EA740,DC5585E4F469503E,8CF57D2411CBF641,6FAC6FDFF4CF6782,C94EEF26459B346A,000000018F68E1C7,AC0A2AA53BBBB08A,F52B2D49C0BDBFD4,A55952585C8B2B5F,D2C72CD5151C6CF5,F28F419A865C3741,E215E956D5B0DD15,31584921A9C59844,6BE3CE1791D8B76C,3B69281799D59EC8,00000001A8CBAEC8,289AC7B117940B64,F95978EE629196D1,C3B2B5F8025E9FFD,BAE73420E8829378,3A51919B7A0EF2A7,FAA5F528770DE8F8,0A59F255F5A50EDB,C95EBF603909B6E4,F46D2C5AA4E2624C,000000006BA4112C,554AD6AF9D28F6FB,2771A97B0144A3EC,491EA46442BB93F9,9FE82A7E941634C2,D9C53098FD8235DA,FF61C3DA02CDCC6F,F9601986290E17EB,84ACEAAD6B9DB3F9,CADC561CB87F9457,000000018A037E16,0B8E816F228A3A42,9B2689AA1D8F5FAB,4EC98C59B5E2F886,72ACE754720F88E4,61C9B97A133D1ED5,ADC7F05FB227F250,1DDF9291CD0814AB,9093BE8B1E2E2591,A6691FC50F01A756,000000017731CCE2,9A80BD64801B52CB,E2E80D64C1CC06BE,79D042DF150347B6,1BBF4EA8B062A3ED,4B4019E41DAB212C,7878E2B95A14C34D,7DEC49E3B9F01A7E,BB7CB5B0D46DFBDB,BB7DF1724E1E0440,000000009F5A6D0D,EF06610A9C24B563,056FC2AA8467B97E,0A1715A28D177E83,1C5516F828372E69,977BE5B2E2BA9FA7,AD128C8A753460A9,DFC03FBCC8273184,66B37FF9AFC9E046,B83B84791AC8EA32,000000002CA27295,0B83DA1FCB6A0176,CE9BF7472A8293BD,1DC1409B9C3F80A4,F672FCD86CC90289,D3B5FF73A99115D7,921FDE0E1F054BFD,B793057C98A61EB4,A89A99BF37F37030,B0DAE70CEB18B500,000000016790CAA3,3D97768CB59B57B9,15FA45BE7BAC8C24,DD4C905547EF0095,A083D681A8C3C8CB,8D132AD1697089EB,F0353BC2A123DDC7,6B9063E7B52F831E,46F6198E52A548AC,57514403CE92D02C,0000000139678A98,B0AFE8635C0AD9FE,8D9E13A4CCF3F58D,E8BB0EB3B23F6024,0AB99A558CBE15CF,508CAAEE2198FD5B,6288EAC1C3C8A1CA,10B8371DC379E28F,E0BBCE1C0D84D576,2C51626583E6B26D,000000005891658B,8CAB33426C941139,19759624FBCF7F7E,6A0E1D3E7401F03A,AB5D7DF55D5C8AF0,78554C58A1955A9E,D39EECDCC7F85088,3C66BEE7B7171AED,58D0B04ECE253976,B4537585C2FE285E,00000000247EEDC8,41458116061C4791,3D2086D00E6767B9,3E4CC9D5A2B8C228,8D59BA8EAAC8ECD7,C75B7EBAD3596FAB,65F3B888915ED5A4,6E79E5486A5ACFCE,331E23824B48FE99,741146FCE7303293,000000024A42EE21,3E852DDB2E20FFE6,24A8E84222B84FD3,27FC729C2086585D,2847ABDD149BD7E8,4751986A33E82013,9F1959370AC89B0F,57CC3852BF32039D,BD1A8666F03AE8D5,5EC4626FDC370ED9,0000000083B07183,312E0D8C4EFBD755,96C97BD6B83D91CE,6973D56BEDD881EC,F00FBB7A6870E26F,AC6DDAEF756EC938,CB555AE7878EFD05,FFEF5FE0F5FCE414,D5BBA308C0B37A87,F2FB373D64DA8D38,00000000229C49F9,DA13B11AB403857D,817F8DEBF337C02A,43B6F1C1D84E63F5,DA2881AB331FEA41,82D138E2A3FC816E,60D7F7A299698FA1,E09993FF69CA0360,27E693DF36178474,0A6465E0F532402D,00000001BA14B754,9E3D071C752D6DDB,73CDE348255EBE33,4E017B638B66EB56,AB0A8F6D107549D9,219E613C03EF5E9E,0BFDEEFDAB524682,7EBDAD9D76D6E6E6,989DA40D2C91F8B1,D2DB0D785A310ADB,00000000DC174068,997BD97486AB520E,949240F596907144,8146F5CFF083A50E,9CEC0B8B278D1527,818DC1A7F46122B9,1F303E1A514A467B,4A1D362FFE93C1E7,007A80295E1291E4,4616FA7299CEB0E5,00000001B6BCBCB9,312FDA6CC5849762,505C2D5BB8AA6760,F01429AD5C1298D6,BBEE2198904F022E,E8829A6833D9581F,A20EB212C40873C0,FD846A6AD852799C,461D9ADB71AAC807,81146B7889039364,0000000157A0BEB8,C05737BF9086CCFC,390D00EB1DD31916,5A8C5DBFB8633D50,CDA872AD6E1BC462,A6C764FBA8346BEE,BE2D6F0D56919143,520C2844ECC9A3FA,3AC90AAB3A855958,5798987443FFDBEB,0000000185CB7715,0325FD0076087FA7,7EE01446CF7578CE,692E8A6C6267BC2E,CEB1FA6771D963ED,29C67AF7793E7E04,699E77A49C56D63C,808198BB4624BF22,0C49D60F6AF20DF3,4603F26E70C484B5,00000000850FAC10,0A9CEE30BD0FBB56,E23B9C3203747BDD,98F93727A094E87F,00777D9ACFDE5F6B,6FDDE71496C5E725,DAECBD8F924876E7,1E22014D05786E3E,D13C815D4399CDF8,EB84571EC3B62311,0000000257D7DB9C,D3531157C5AD9A2B,400B04FFB95B733A,836BF084DCD95F98,FD5BA15F2E6B96E4,666C054D6C12DA6C,587E7C9510705F40,CE6E491DA0FE2B4C,470A53A1848CBCA2,2F7E10103DF15A21,0000000193E133AC,A2376A78A549FDC8,468135DA8E349D52,4610906CD9C2186F,9003702BC12CBB78,F37E07F8ADD21DDA,9D83054A988A43E8,0F3CC48EDE8FBF51,AF6C830703D72522,90A60B0867AADC7A,00000000FC2BCDC2,341037F92E115DE8,A7A5387F0DF94E31,22B6E039063CA567,0715ADE2A9F93EBD,BBFD8F8148328F2D,9A31C8DF18F41E9A,EDFFCE5287BB5C56,BE62B0452531B1A3,1BA67A15474B219D,00000000D6BC3DAC,7AEE47E7A62FAAED,6832C2E51C1AA2F3,9EC2AEA33545E371,AECE1373E244EF02,608CD2EFFE28423B,080426292FAB388A,1C9DD91ED488C22F,2C9E70078207DA60,1D2BA3294FE06593,00000000846E1ADA,63AF22717BC85858,86C59A8D9D713E18,3361F98238893338,61A1EEBDB3758C85,753FEADA73E85159,50FA4CD774D8BDDA,89B05C337DCE6267,ABE1E8DC635E5E2A,3457CFCD38ECD674,00000001622591BF,B9B41A3456FB1786,42CF545450510A5D,A0DABD3124DFF2D3,3230BFCCAC0E1B57,504A7E6B9B235F3E,A811B7285E564667,EEBF152BFF41ED16,5AD2ADD7DD7BDC44,C9B1D9677919D455,000000007E3D66D5,4F0E73E08CF2EABA,7C6E769F661EFDFE,06FDFB9C2ECB028C,BAD086B618C77543,52DE6B321227E537,2EFE7E75A3FA76A5,69F113DA39F88ABB,49F70B7C8DDBE4A3,EAFE2DF557CCB2D9,000000015135976B,21015A33E84B4DC7,A38FCD66418E8535,7E8A0E37DA2153BA,28BF82546266CA92,499787285745D596,546AA776F2ED0902,E1E56C95FA7E56D0,4DF1D69C56C34E26,9EBDC506EA0DA8B9,00000000EB915A82,A815EBBE132BBC7F,F9F4E2C1EB769C9F,600A70B2F20D519C,71B3611F29FF08CD,BCFF7622DCDCFC9C,68F1F23032ED5BC2,5800B3E7A692A249,264F153AA62E2553,16452F065D496FE0,000000006BF78656,C9195087730EA524,27CB8F309D883FB0,74D4D884B42B811F,EEA736A0AA813087,78BBA6129498D4B9,3992BDF68D273384,45D38D3304E9FC71,772C46FEB8F6573E,195D386A3D6130D8,0000000011C51C91,E4FE23574C17000F,050C89BE1B22E506,C8D3409D1BAFA818,EB1DE456412DA5DA,BAC3CFE621AC75D5,A916943F0B488D6A,208E7D3FD85E5889,15D8CC16B9379B05,68D746A32F1F380D,0000000264C69426,7B47E059D7F7B1C9,BA65B7CB05F4CB87,83CAEA9F30C39940,21FA27BE6048154F,5702605A3A472FDC,C1D3B606C912E227,DE79D1DC8496D65B,9A64AD546AA14056,1789865E097D8C2A,000000021DAC34F7,A1EDB55A322E0B86,73E95D1B225A672C,CD598BB88E998605,0E3E09379BCD9D48,B61863B3540BF739,613F1F0757FB5C16,11F9F928A600C3B7,44E41FA85177C1D4,120BFD44D1E39E80,0000000001E791DF,786C5C37C0CEB210,CA46E142E27BD8D5,089A9C3EF7AF8EA1,A4FF8BF37D5D11B2,E07FCE1941DAA358,8BABF00281FE6DA5,9832EDD32DF4584D,A81763B4854DFD59,BC9941F4900D4BC0,0000000065AF98CD,C9C01F5AE06A5E92,4E4EBC510E28BF3F,554D5FC555D77A3B,5A63C0C7877C7633,85F729BD0E8A2EE9,647389B0001384C5,08732A88A61350E0,C7A83631493F0660,6499B18AB99D8FC0,0000000077CF9C4C,ED2AF18C6CACF4AC,5D029EA4386F9B4C,FF800D4B1CC28236,5D8D81261CD7B5B5,1F9CC669034BB131,2B6276B299719FF0,8F04D61A5D6A1C67,76B5DAECDFE7FF44,197F7E936804C659,00000000BCB0F8A9,2BF06F9B6B8CB792,EEAD716BD4862AB9,004B37BEDCF759BA,B60CDFDCC2620E42,1E56F950E5D433F6,0D617BB2813D6BA5,9CC7DFFCC0FA833E,5DED8429F306825D,A6E7ADF1CE8DA791,000000017869A550,57BC73A928AF1998,73175F22C0000BF9,5283BBBE302A1669,50645C8167977B6F,2E07570F7DCA03AC,1B28C46AE1C4B924,EB80DD9C6942E7A8,571563AB41DE6E78,EFE623CE1DDDCC96,00000002217648E3,8DA62E8B32D0CC9C,4653638989E70850,99D236ECEA842D7F,2EBA9FC5AF470D63,0BCE3847C04FB8D8,496E97BD87FD5249,B21B28CEEFDB56ED,80FA8419B7EEA5E5,5E4EB864CFABF77B,00000000DE01CE9F,D700A931A92C84B7,4A0BC733D1C9E7C8,45130F3DCD408313,BDB76DA340F12B49,8252EC8000B9D9E5,D4205CD15CB17F2F,1E3068DBC6B93FCC,5192B65E9A673D6E,A3452EBC775B3477,00000001AC041A0B,947FD0FD024EDBDD,5FC1F2533216A79F,4E6BB75CD9C14816,CC94124DF76435D8,C1E1E1E3EF73DE3E,D8C11B8377E162BC,C44381D0A7812846,580A1658DEB2E591,34B45A684DF33960,000000021B0B2EDC,7C97EEB4CB6453E6,BE316CE0774E693F,4C65E47ECEE4A290,9630F84C4A74C4B9,1947082237B0ABA2,1B4C13AC01912C2A,0350233529A650DB,AA66735057F2C772,34B9AE6377CEC776,00000002500A9A00,D77E1E81C13AE7A3,C186889B39D68B66,958B073C86E4D582,5B3ECFBBA0634E85,A260441502B4A1EE,6A4888BFF27DEC38,86AE05B80F0B2EFC,8C79817E8797A667,4F2079ACED8FF31A,00000000B4E06AFA,4604A12FFE1124AC,5484A835F6A87B04,2B69F0F89C4D068D,7EF5347571781AE6,3D5A25936D696C3A,CE5CD4CAF0BFBEB1,C6D4F6C43ED2EDA4,F72CD1D7BFC0D13A,0CCF947F5B13192E,000000019A826873,BA39A7DEA64C6F35,839BC44BF1B0B3CD,2F31E088AF725C04,469D2798A611246C,648BA95809B001C7,126901E7151D774A,1F27B25CFBAB5F65,59F667CD0227ADF5,0041661B0937AB40,0000000225813ED6,9FB6C561E8EF8E11,BFCF2AA4D8E96F8E,18A8B3B8DB5474D6,C1015161671F4E5C,0625F53342256B8D,45A267CABCFDA7CD,CFBF052666407096,232E4E3ED747F894,A0915A1FDE39F6F8,000000024FB3CB3A,F2D15F5B91B41868,832395DB4EC21B75,BC55D9AE5247F365,987C14873F7DB9B8,E30CA1C881DE3133,1C0F9DEAC7CC7782,2DF89ECD6CAAE8E6,2AFFCF74225267E9,1768FA1489EC4C8A,0000000086733CC6,F4C27FD76D80D017,4A3F7D1C2A51E446,7136C0986F2FF2F2,CD4C1D28E44F1B8A,8984EE69979A5FC0,23565019B11B1219,5E1A6C920F369159,33BCF3F2E5D9A717,C4E41CF27C29AA6A,00000001046F198A,F3D0B4D47DDE8CD7,DDE526F06EC37294,18E39670B2691C52,FDB0FDDC644FBF73,10108457D354D313,DDBE643CBCB10B92,C82A97991C247E9E,E30109B91322B538,317D724D42A8AA0F,0000000227B140C8,76B821CB50BEFAAB,C84BED04B924880F,196AFA982FDACE84,4C5EC32CC0DFDADF,E84B50C91C406CC0,3C6823098244E878,6339045B56B80E7A,3F2EE84513983324,9666F4CC3DEA86A2,000000001F244C7A,6B6909FAE1BE13EA,3FBD66A5575D88A0,D2A01C9400D405A3,9BF14FA3F82D0811,DA3EAB6373EE4DA1,5CFE49CF0BDAA34E,6C955D2F3BA0F8F9,CCB7929F023D5476,4D2D1835B848CD2B,0000000141A34FF2,EC3F6EC98B8E10AF,67F8E82C47F9E36C,66630964EF50A0BB,78CCFE3500B7E51F,7A30D274AEB908F8,2CC86648BBA7550F,024EDB0F4FEA0166,79DECD12C71396B9,C228D48559BAFF4E,000000003C2A55E7,BC47CF50D7EACF7A,AEB26760A8DDD9A0,94D45C4F51E355E6,2700847A8690FB5D,0065B75EA1FF568E,AA7A21A2222EC712,8D8A5AECB8174D01,3262080A315A8BC1,EB99395092D37E73,000000013EB5618B,9100F1CE37B8E9C9,7D4F9778823068E2,C564953A90122B02,782CAAF487A7A994,8B120356B858ED95,A30226CE86A564B8,6CBEDD75B5CF9B7F,4D9A157DB8F50669,B0FE56189EA1D539,00000002088C092B,98671B16A498A9FE,D65853D6DBC0B4D2,7A3D27CCBAFBB63B,3BD675909FF6833E,2DAC9AB3091A1605,57CDCBDE416C3AB3,5F234853501B9E36,9F0B4F12C9CB81FE,CEB9562322F8B99B,0000000027F8CD8B,D81E0DF0630B5388,7D7534C8F84C53CA,114D1260CFCDD05E,E659FA13C340CDCE,0417F93F516FA32B,D2CF9CDDB265B7CC,FC3D27D99A87F6B2,12472C37FBF04C7C,A7B9D0E97765F5A2,00000000907A6A9B,D184AA8D87183FA2,8D335DD4B8AE2AD8,C37B39B7B4712F05,32F79D06D4564A55,5CF34C505CA3B68A,FE3ADFE84FE28625,C7233695BFF87C22,F8ED7EE20543CAC1,5D5AC18FAF7E9F33,000000019DD45F2B,3377E234EF793912,1B3FD2344311B59B,30A9E104BC04C873,436D28698991DFD1,17E5CDFA9BAD7F00,1747358565CD4CA1,F00B2B79DD97F223,A77F6ACDCDE0E45D,B5772344EDFCACF7,000000002250A906,9024E05DB56BD52D,8408B10310EE2D56,EE78433C7126F418,B58349077797F1D7,3DA42D6338E79D95,A0AA9AE34C9953DD,86C24DC876A6A8C1,A5177157DC95B87F,F08A0C182B15B101,000000027289BAAD,CE0E34C7CB499CF1,65771EF9B568C962,62D650868E52B81C,4F28B8B2FA956937,0FBD9924314D028A,6678B41569B3C5AE,9B1137B5666E0C60,54DFA6B34E362485,BE97194A404FDC65,0000000224C73904,61E3F8027B56EB86,2D0F5D13B630E1B2,EA02E33E7FAC8824,A91AED0185467BE1,2FEB9CD5E719D394,5B552BDE339CF5E6,C3A62F90AA96F6A1,8136BC2445195DEA,D0FCECDCE03F85E6,0000000242BB5CDB,5729DD2441806A13,25D6DB48643E747C,8DE631F2C8C3E8E4,1E11C2DA7F5260C9,4E6C4382EBE2EEE1,4A7027F641E56084,F042B6F768F410C5,82403C165A737D79,18DDAADC9606C7D4,0000000256031030,4D2227319E1AE490,4EFEEA4F832C5E05,CB8A85D6F2A31C8C,30D97B79A62F12CB,804EB737A87C56A3,6433DC4231F397E2,49FF572D46254DDA,57F6691E0CB75982,6019ECE2D24DB0BB,0000000004A58700,E3F491E116075440,EC6735CFEC6CA54E,7A047330C5CD54E2,4964E00E8B3FBAAE,A1C51A22B5EF1C00,8EAEC36412D74093,18BEEA2696713F9D,5379ED32BB9B5770,9FEE2C6D0C078124,000000005FBD62BA,39897306E4969C94,2961ABC0C12EA90A,7902CF8EE8E451FD,D9955B0D11113D9E,0126EC0BEC8ED6C1,0892AC71A3BF63A1,9C565022B3C14B9F,C50A953ED816F211,F8F91632934B2B89,00000000F7057B6A,D020A5696ED1049F,A654C19D66CDBD34,C7293FCC6EEA0B0B,2B2C2C5E23BC0033,0AE3C7190D487E84,DDDE0FE16A311A87,297F896FEBAFE623,8041FCCCEEDFEB32,BC0B5E61067C7DAD,000000006D6335CC,3BBC18F97D5B5ED7,9DF75B73F0F9FF05,9388A32B75D42AC5,711F371AB5076734,99BDAA78A57C457C,3D7DDE57DFA67600,35589102E3AF1F45,1162F3B964302431,E7D071471FC68EB8,000000006A0EC5DE,6BBC4F03D1C94340,D49B703190374EEA,CD7433F320C4D00C,49D2E27C5870A2F6,DAB7277E4B8EC72F,336804612989F8C3,3B7764DE7318E79B,F748C48C7180AC23,DE3E91F340B4E568,00000000C76E619A,82F1948DE85E319C,23D092B0FD848AA9,B5CA43FF54746180,125CDE9AA93CBD34,AB10115E4149AFC7,B670AA05B8F59DDB,EAE40315B1642693,EAA34A14A92ADE47,27F6D50A0DEFCAB3,00000001C9FE8C63,EF21DD2379204ED8,BAA71CFF01EF09C7,AE6B76263F5F70CD,8C2DC9D806C3CEE8,FC08F6D612528493,F32DB30E1864C646,89053C3F97A66945,61A9A68B162D8E0C,5672C2C6FAD02364,00000002022020EC,23EFCD38B673EB1E,7ADFAFF02EAD3639,DF1681DE510D9042,1B2ED88667F527B7,B1FB755F6CF8FE7E,02B527828E2B3248,B7C66E759DF2C7D5,4CA02F71BBAF4E93,A7CE934A2C712976,000000023250EB2E,912993D3D95DB8F3,B34F70B4F56786EA,B97BF07FAA241D8A,3080F8A34992516C,32CC4C2C32585F97,1058C5682C1B38DE,F12621D1DCBBB933,5C71585D25963633,05E337957DD12C85,00000000C4277A8D,3ED540BA6B72A25D,63C75589286D79D6,0FB85DA9949CCFAF,8A6714704276596B,C35001C866590091,406AB8F04FE0FA70,49FFB752A8B9952B,3769BFFC017C2537,24DC359107DB2893,0000000019527259,6C8162113BA8BF13,4482271CDE2CF3B4,4DC44E9517BE2AD2,4109211E3A4504C2,4ABD85A75B466B81,ADA85BAF3FDF30CB,37297CD1340E53D4,E2486173C22DD6F8,933FF36EBAFF074C,0000000031E76CEB,E99E309B682CEEFC,29BA128AD48B7AEE,C1A3BFCC26D4DD79,E891A5696940A8AD,A9F2ECE4DEF39722,4ACD923DCEF3DEB4,10930F8751CB9308,68309879F2240D94,D71BDB0D9A25FD97,000000004E59E822,F95516F541954AA8,C7BB930AEFC92E68,2200E677C2878709,57B88883082FE533,C766BD541200CCDD,D82A11041783F0C4,99750266A6792475,A8CD91AC39C977CE,4C41621A2EDA1CFB,000000022614993C,F25D2027BA8D5FEB,B3678AE2B65A0E15,6893EC154FD7A4E3,D04FAD86C35FE90D,F59330EDA31CF367,F5BFF8B5E4345E4B,6E88F1868BEEC476,C0727CACB5C0342D,888E77B34E89A84E,0000000040656AA5,51724D0434EE3EC7,28C4C27E240D58DF,DB577C1B55147D99,E5FB3234E918043B,7772700857EEAA80,898B8040C282D026,8FE9F9A9BECF6CD9,F23E61FA90BBAA34,5FB3110B9FBA5506,000000002DA34758,5185DE08969034B6,ACEAD58D4C06B697,1686A6EFA860EB56,64892A6FBCB9C705,6B8FCC3062E4A2E7,3F0E22FAF3B0867A,91A39C45D82E04BE,05DA65068B96E5AF,5F88BF6B9C4584B4,00000000F7591D9C,42DC85EA0E9660EC,466F4FEA6CA5EF27,DAD11856E2997036,CD65CDF241B314CD,D64F9E2FCBE92BC4,F4CF7175B2E21BB5,C2FCB7442B4A69FC,AA0D6EDF1BB7447F,2838D36D976BB6C3,000000002137BA50,0F8DA75A2EB482D9,DE983C738763D15A,623BAC293A06256A,AB63633FC79A5AD8,B19BD6C87E909A92,5DB594A0418382FB,3D41C108161B828A,618FBA73E2581A2F,37E8B479B0257751,000000025AF25419,452734CD2B707C9D,2D97D9984C26C9F3,CF29A0F4018076B1,8C65292B0F9C4957,AB833B25F26EAFE7,80AA59BF00E84DBE,8BD4C296944ECE31,05D9F61A481016E1,25DE9F3DD09E7EC8,00000000899B0CDF,3CFB4184C0FC4134,1E0C6C29D538BEE8,ADF7E2AD7D0E4B0C,7BE25EF88DDACF51,22D6D73EB541F81B,764D22B152E324A5,B2BE411ECBC34435,E539CC8CB72F82A5,EFC28A6CA30A444D,000000008451FC11,183CFE1667FDA520,C5C2F6703AAA51AA,741F74BCE55D6FBD,727828E964981E89,16247CFF503768B4,3BFDA938B62C5BD4,60B6E18EF0ECDC0D,65D2C53290875694,B6406604EE7957D0,00000000CD58A3A2,FD639CC8C7E309CE,1707327C43AA1E58,FBEBCCBA8080D37E,3E41346E0F124F5B,67B4154AB0247AD6,F9A322969BA621F4,29CEE845F59034DF,C38AF9B1BE137BE4,CFF1734B3F82926D,000000021B576664,FF56CE84EF195F6B,F63CA288F1305953,724C83A09A040055,26FCD281E180A823,06E8BBBA12A2E985,3331CA27D350E8B1,A12C3837F5517915,51C28402D84B7EF4,5327F106E806706E,00000000E3E70A17,94E9A2838E4AD31E,4F23631FC383CA1F,F0D58E88811D10CA,70CF7D4968E4DE54,52BD64DB3B4FED52,C9C3E02CC965A92B,B7ED5CED9392EB98,44D16F57C9216619,E2A60C8A2ED2928C,00000000BB4F61D5,A10D990CE5EC0BCE,F1D3261C5CE3B6A2,FDEFBC0D85A0D1DF,F311C6ECFD35825F,2D07D68EA3A160C5,E8C9B7FE3718487F,DAC0EAB5E1D0BE4C,110CADD6F9F01BD2,710C0798A54C41C5,000000011B5F78F5,9C17F5F54C340B5F,6B7360C1945583FD,ABE58033D4CFBFFA,8E5FFB613FDBF599,F749F737A3F5C60B,090197492A2FFA88,47F32803D53690D3,8EB6B981BE206E78,AFDC03B81508CDBF,0000000230AD9EBC,9C8CAA6ACBFC5CA2,8257107E3831CFBE,C11F3AC408881B2C,9AD09EAE06CD93AE,D9D10B69D181A741,78FCB53EAB70E855,0A21D394162BEB74,80714AE690EDFAF5,E0BF1971DAD3B81D,000000015C448D92,538C7E926173B517,AF2CB8B0A23CB9DA,3B6295BCF11842A9,09A33F43627957E6,A07C6FFB241B5782,9BD0CFBE05E53ED8,915B6D822A575A8C,B1E805158CEFA8F2,62DE2E5B7511F05A,00000000ADE41E0B,9F4FBF1E8C2EB3FF,CBD1BEC333B445BB,BBC28EB694B8EA40,A9545840164658F2,6A41EDD47DCEF9BF,01AF7199256D123E,DC69AEF91EF8864D,AE687ACAB3ADF505,30DBFA8516347C47,000000013232F072,E14C95181BF480C6,025E2552867251DA,AAD8E1BD11E276FE,4A904787E7BAE78E,8F7DC6F1DDAF7FBA,4D73E718459D38E5,5932C780F33E3816,EEDF767720ED3AAA,AE53A8BE583CA2AC,000000018C03E7D2,CFACFF7D793D038E,7621F5FC44101431,341A454B61907C3C,1DBC5D9360B27805,764D3C3D3ECEA7E3,66932F452C7A7135,934EDE7353ADA3C1,FEA030CA8D8B76EB,15EC8A8A9D291BD0,000000015350B9A2,293D8F65F07B39A9,1FEA37228831C57A,A06E315FE89457B1,670C66F47A64D89F,07988118DA48CA98,1FB5B4FB0ACE15A0,DEB4625112A752C6,247C4C97862D9C32,2D28F5EEE0D64E5D,00000000F2CBBBBF,9AB4F64B52ECB8D9,DD3F3F6C518E34FC,A417610202AB5B28,69ECAEA1676F87EF,4DA808F373A81018,5267A034EAEEC9C7,78CD4C05C094E6A0,4EE58022012CB2E0,121662713DED931C,0000000226F075EE,340D44215DF15F97,430370BF45F5EAE0,2CA30D80C0D45E5F,6A0A57D7D0430242,BA692E90DC8E7637,5FAB67AB21C2D967,B9771BBF285564A4,9AD39CAA7DC925C4,0943633C5F3FFCE1,0000000028AAF6F0,F1B33FD30D409F55,644D02FAC1879435,D66BFD8989B081A5,8AFC9CE370B921FC,85DDDAEF067C4C31,7038B2593F630A1A,1BC09B5AEC14C482,50ECB1E35774D1D7,0180DA9CEE454C1C,0000000153D850E4,98F433384D3A1C51,75DD711F601F96F3,15D7C397AF297CD7,6000FB0B07E19954,88A486F18E21A6A1,FACE3EDA5ADC96B5,95D7863D48E1FA8C,925A874A8F299099,CC6DE444DE546254,0000000012F79953,EE307698ED1924CB,9132B8319B713C3A,FAFCD5E42F000C20,400A7E6C95B0A4F6,239EDAE5185E2066,83841F44D38D8472,A6B443A4F7B97127,C1F6A4E2A9581EB7,E90ADF4CDB77D2F7,00000001C05E07DF,AC98DBFD20A99DFE,A5B448A65149189A,3D3BDF7F3FF585C8,A5D0F5F84BDB24B8,B499534C7C0EFCD9,E1BAC8AEA30A7AFB,ECED451EEE141C17,992A9A5C8E71EB55,4D06A3799706D2DE,0000000226F918E5,8C76A83CF0E21CF6,1444671AA4381272,993438D4D7A40D81,48CA2C27D87CA438,073454A3DBA71D73,873E982D442DA3AA,F95954046F80CC18,0E9058443FDA2F5A,CB7F7B575FF9F410,000000009E7AF39A,5A6CBE58081F55E8,DDA9751722FFE4F0,4B6DF3CC996DBB95,54188E240B5E5A85,374D10B0D6AC899F,64DBD140C4397BF5,D3065532E22F3F30,DD87BF6671D664EE,C8384D1A75CE8C95,00000001101C8A82,96F510E7AED3E7CF,605F3FC2C6184151,474B7A8A707A8569,3AFBB1E231A91A24,9D9777849E44C4D6,D042ADCA6A0786A6,461E96BD08687488,AA04F519D014576B,9EE7CE6C2BBB3B56,000000000CDAC434,CC6AE9B5D6FD45EB,2489714833809451,C564B227879FDA34,F20922450B736666,071070581E6400C3,A21E9B294A6980FB,AD7ED9F15AE11CD7,9415F45CC07BEB0D,302B220E983694D3,000000017CF57348,F77673B48A1BCF97,C0E5B12E9A3ABE53,3983391320760329,153C72529734075D,D900DE5FE25485E8,0BAE49163D7C9189,08C42589DCC7729C,FB967FB1981ED86E,41761FD1C5541134,000000000AF4D506,9D4364721FAC25B6,BBC9CDC7869CF95B,3AC78F03FC764251,5F4A9FC3CF7CFBEB,7CBB5FEEB8EF7051,2FA848EC420DF9CC,A6CD701015A0CEF1,6D673EB02B49ABC6,EBAD59AB73A17F7A,000000012FDF8F60,70778F9E97F79A68,6BEE6BC1FFB86BFA,41C6F5C6BE65B7EA,9EE8E3ACB6B52747,78AD58AD6220D495,9DE9254B67411DC7,DA48086471592685,3A89381A31D7D798,0684A89126A9DF54,00000002497E6101,6D7482F89D8B1326,D3B520DA84EA659F,A665DFE475780A95,C4B262AB2B35B938,0688B00EFE16CDA4,CDC5D9BB330BD9EC,535334C7C94DF919,F00B321259B5B45A,99BE118C839F098C,000000003229177C,1F090AC4E1DE4B60,9620F1177AF74E74,9B32B71434683913,3CF24115DEE5EBEB,160BA969CFB9AC3E,537D75715A5AD1C5,91C1600A3EED9BBC,2FB5D21E3B08A504,3FEACEB7DFF72CD0,000000012887BAE0,1F584D9EE66AF8D9,0EF0408D55F97313,723028F780231F14,2596367C01FEA942,180BD1F2C86262F4,C97616E888A49AD5,5FFBF2368ECCFAD8,F9C866F017FD79D3,725A6537569EC360,00000001E7A091F3,93568CE76915442B,D8AB09F581FD5F7A,943146E032E3A6C7,9F078E8C9863EF44,071F2F7D3BAB3B04,94FF6629C84B8CD2,62D7F670DA15306C,E6A920C9AFCE5376,4F7B1C716A9D2C11,000000020D8A0D5B,816D81D2966FA9E4,4CFE663B5711738A,F0AC439356D9A5C4,8A3296046E7ACF19,97AFEB070E85F82B,C8EC4697302E3002,7884BEB9945E9219,278B6EB708997161,FD6F1295BFC7DC7E,0000000142FF0242,20141BD97EA3DD19,B6F0B6C7C8D603F7,56A1DFB9F05C819A,A07DC728F05EF499,1B07161E3AD70A9F,E852A37C01A82599,EC4865F38A25C313,D370FCF9F9DA0B38,A964EFF8640F0A9B,00000001626ABA10,2BFF76B270EAB2AA,5BD9AA7FC204600F,DBFEA5BBFCD72A8B,32E2E54531773D04,B106F839A312E6DD,77EC9B3053E9EDB6,C24AD38D391F2266,99E64825E6F7ED82,7C83A9866A507E26,0000000235C2D159,1234F9E2A5ACCAB6,E3D364DE2EA80A0D,AEC2EE7363EEF7D5,6756FDFDBC4D333F,7B355217BB932E4E,BBCFFC36FEDEDFED,8705B8A366FFDA94,C1872F03F5E4931A,85EA53243DA7CC91,000000009A1C63AC,ADC03962E0DBACB0,061DDF6AB25838CB,A697768164FDBA6C,4CA02ABAF95FB351,7BE657FB27B6A172,FB6348C658CD5BA5,70BB92B0F2AAF7EB,A7EB97C172BE6E5E,5D6BC1EE541744BB,000000000BCB9CE2,2E697B762FE3D47F,8942CA84165099DC,0EAE11D3E0FACC27,96D2D418F37FBDF3,AD1C73709C481E10,B0C63C46E841146A,41F04A3DC96751F1,7D555F227E5924A5,FD1C68C771781485,0000000241BBB021,8F49EB9410877087,6BB46B36B114CA95,06C0C0F547363DA0,EE26C873D97BA835,BCEA384442C433F8,60D574D709459F06,FF147271AD84AA03,30BC0C54A9539A58,1AF60402A0308BDD,000000013F24F4DE,B5B8965B53DA470B,90A9151F553C6888,AE180F6833B5851A,02CCBEF4073C3BCD,9172AC581998B407,2E33A17020D50A12,BA766ABCAC252795,16F256713D577CE3,57CA63759B3FE64E,00000002314471CF,D0BAC21CB34D0847,DDE87595FE4FF8A0,232874B5D6F775D4,23256381922D2169,5D4E429F759F5B12,18BF4B932E10FC17,30C94A98E36E0887,CC0DF3AEC344C5EF,40D18F6760A8A956,000000013CC74DE8,EED2CA1F8B93278F,73F50600476591DA,154BECABEF141639,E17FBB51F5238235,C0DEBC8633FDE244,01CA14C97EF0D23B,7FA2C666F1F8A681,A123C6DD216E531F,133B4EAFFEBACD10,000000017A25FFBC,0408F37568F32A27,56CBE0080982B970,7CA02091C7F17284,E63C804A6EA194CB,7A28CF23ECAC059A,01B7DE7F6D87B22D,CE950D40D5CC6C95,71FCD1EFB2CA1CDF,EEE9CAF1024AF11E,000000000F984F62,3D9E4A117E0D46C4,A11FE76BF710E446,C1F20A4B38907A4E,A8BD59639ED9677A,747B4721F14D1268,6CE9A64FB78CAB94,2C33931DA4FA8C60,6871A684838C9057,69D06E5D1698FFDA,00000001A0954AE6,709DFE5A959CA5E0,652C3EF8F6D0557C,C3B0DBF0AA736B50,DFB1B8B3D3B333A4,9CA9CB0B81549E02,86C4404F761F35B0,9EEABA87DFA4E892,A9D0D1BDE66FC86E,2E925AFF8654BB0F,0000000005A3215F,26DBE12A819B80CC,BD2E236207BAEE85,2FFB53F66E9508BE,3DC37DEEE60B9C0E,F6B84EAADEF5C96E,4D6C7D13D1512A5C,9DE92B7FCD7EB530,3B437D6D5BE8C1C2,1F6D2A5AA56DFC2E,00000001103CD8CD,AC1CA2FEA77B9DEB,3148C5D5A5E618B0,4749D6CA962FEEA4,8B27281801996792,EF025BF61A7F5A8D,982B78C4C4574E55,CA3C802731CD09C0,FB1622D0241898EC,29A8EC6875408717,00000001384BBC1C,074EBA95115B7046,FD7151D43AC45BD3,682EAED5A5AA17EC,7F8E868FE4746010,8D20E251AAFD8EE7,52109A9E618DAA88,39DABFD09735B4FC,63D5A8805844E098,B38D0CD6DBD93885,000000009607B5A3,5FC947FD2AA02323,5920C31A48A121F8,60BF1AE5A0DBF89C,51BBB02E3C83815C,64C58AC531EE9785,6D5A6D335E4D7EE3,0FFA2A5B613D542F,21E7BCA125D16E37,9B57BF6DD4C3849F,000000007766CDE2,255BDBF14DD01464,6F91DCFFDDC287BE,9158D4A5E4DA59A2,0209D54534468DAF,A3CC59F41665E127,F8DD9C93A7A5F1F3,8EAC8145EF3CC295,B107732286068680,A6216604C08A8935,00000000A2DD190E,7A4A16672A20353B,50726ACEA344693C,B3E39C1EDB394D39,1441AE1A412808E7,7B7DB4C9A68614E4,B8291F4C796F2497,07C4EFD0365DA946,6983E2930AD34778,91095592D8204067,00000001F349175E,1DD91A41D83ACCE0,92117B2A78BFC079,C147D4A9D4C3D3B3,E5AEF854A039D4B0,D1645D0FC240BE40,D40A46EB39B313EC,4838AE959334F441,1FFA69E8B7D5707A,984DDA4A9D497CE5,000000011F069CEC,5252C6DFBDDFBA99,321184CD88C568C0,4AC10A9243AE6837,444F3FD75F506591,C67B011939EE8319,861A67B92DED66D9,A4E5C57866BF56F7,10BA6C961A8137F3,032FF36720709B84,0000000002F71945,3C1210AD9DBD4701,C2DC4351E91BCC02,8578369E90D2FC70,ADFB2FD2609CDFCC,C7C17A34E23292A0,339B6F85687E0B45,9572690AC3326336,03C3B92FECF6D169,30736F6A9D2D147B,00000001799D6E23,FD7B8A5E5F4F150B,044FA1D6FB956A1F,D0CAD5895D5C1897,13C3D7FB90D6DBC5,46E6A5B5022E5CE2,1E3DF36D165FAA14,2B2017F05277876C,67DFAAFF537051D1,DFC3922C4D0DACA4,000000024B03416C,4B70D4F5572EE0B9,C48AF1035C49D25D,3CCDADC1220CF19F,FB4FEDC2493D2BF9,187CB07096D7D9E9,295120E86017C454,D714873717DA0614,DCD91E586F2B845C,9B2603F7B8E95605,0000000196CD6FA8,AF052D344BA3B6E9,234F5462FFA531F7,2527BD59306E8BFB,44D2A3385B97285B,BDBE0E4B38BF720A,D7C57C431F5D62E7,7091086783A64D13,A3ECFEC9E43F303B,825C9143929E6DE8,000000002CC4E24B,8C484FE717C27CEF,8287DC3C94D40494,D343799B80331F53,1E5728033EB42E07,D13986F6F3DE7D2D,E79572B2CF6432DA,011E4D11830E81EC,307E60B45B3B2F0B,9FB00D867CEC56D0,000000021EE9DEFA,35BE912E528852BB,9B10F7C0B7446505,A01AAFBF2A47F8D7,7225941B94ABCB96,0C9646A82E4CE4BB,B2749CC5FFCAC7F3,55F42BE7ADF31542,93925AE3E8308E89,200878A62C52C606,00000001F378B7D4,49FF0EE276EAAB6D,4FB31C775D5AAFE5,5F192B76506C1CC7,4A2BE2CF23E9F41A,5705E2C781595973,6EB77A848E57F3E2,7B0444A1D8EAF695,10BBEE4E25C0AC57,A5AAA8F65A0FF3B5,00000000574A829C,81E0E0FAE4BA38E4,57D332BAE39DDBCA,BF4C03804DC2D6BF,8C24C92D4C866F1F,2A385A4B7968AD01,EC198EBB5C02C7ED,971472F6B245498A,D596128FA09C98E0,8FF337BA87D3D84E,00000000D9F99619,9EC84610769BB325,2AB61C8AD59AEB2F,86A454BB99655D03,AD6E4C3B3EF8070A,3800156986FF0A14,D8E96E7C422966DA,761595208825922E,029EDBD38EB9FAF5,5F2ED2E6C090D9BB,0000000008C49A2F,66D20A082BA22F6E,EBAAF31CEFBF56B4,6A4B8FA4DF936C15,126E30DF362C0EF8,040B2588F1E88FFA,17DB1C762B143E61,2AD20EFDABB919CC,A7F5CD2AE09B7D5F,241F0FCFF4073F65,0000000222EB83EC,54BF027FBE73817B,65AED57C54A4A48D,091E0CF85C8E1C0D,D85AAE0C26D48019,F950D09DCFCF016D,1EB317FAACA2167E,7D7EBB2164FDC425,CEE3A8C17923A099,64B4F3F43D2CED34,000000017F340AE4,57A4BF61E2F86F7D,F37DA6C11D8C3F77,4CFAAFD43F6C69F0,37E175E5B374E32F,91CD20E11AA449BF,A177503EDA1AC737,EBE0C49C7A7C69C2,5811261C4BBF2362,CE52966F36FA7D7E,000000016002096C,C566E9A668A4346A,8F5FB0A25D5AA593,E287D4518E7BCF23,D38646A70B17DAA3,EE13C7E2449757BB,350C834C57ED4FE4,8314FB8DEDCE7F42,0F0551AC9F59C16D,01520E64BA803CD8,00000001BD7D5D5D,F5A0AC7F5214E471,72AB85ECC409B677,21282666BB333463,F7BEAB6E9DA67240,952FB11F689F2721,000F391A0FB2E78B,72E4416C9CD7F2F0,B191CBB974D1034B,85A97269E00A671D,00000000AD5D9ED8,D837144A87D1855C,C549115AF38EADB5,6025999B3ACA1CF5,FFDB678E68655ABF,729C0A0BE12281D1,1B0F25EA430BB72C,462F5AADD52C77F5,34F72A2FA48177BA,F5D8C0E61FBCCECF,00000001F0E423D4,6EA8D277FAF3A30D,9C6A9D592618C236,2085C25F57343AC2,5C67CAFDF0D582F0,58A1002C028C561A,3DC47B287883C052,648087AE0AACF7D8,8FFA7FE86CCFF230,FC1934CE3424050C,000000018CB81373,299643B0A1F87FC9,089C7773694F2794,1F17E55F6F34BB00,3FFD7A0D8747D9DB,3EC418FCC3134A70,3FFBF64C7410FB84,BFE9B1A02A40D633,93FC1C1AACB3669B,E8E564DD224DA576,000000023A745AE1,30CC1401C6E65C8F,A227B1946A0E31C0,1020BE274EC454BB,6738B4C1C4982F07,0B53160E3166014F,81C426672870FD89,5B96A8ADFEA044CD,8A444E2EEA8F9E30,5066F1DB2465C579,00000001882938DA,E372E51FEC35C1CA,17E738D87A8ACEDD,CB34E17272DCF850,F839038946BDA56C,415AD3243A7A0051,B64D08BC0B1B66FE,11D14936012AC023,C2D08DD2C0F0D6EB,C05698639703B78A,0000000102ADCA3E,C9DD9500CE4BABE4,4B20295E45547F8F,EB8F091CC6B095F0,4EFAD83FCCCA95CF,44A7E7FA993A39EB,117BED7F9E8F4CF4,63FFFE2A8DE0B560,B7FFA3604B4A011D,0887B2B306FED4DA,00000000CE004C98,39FB38CDEC6BDA25,AD7A6BE2775905A4,7E31B014554D20B0,241A93A8D9DA5562,717270CC28765504,C76BE5B2E546FF92,4A4B2C5486FCD524,90D4279B66CB2AF2,77C09C1AE2E2C629,000000014C3AF96A,4F7E8FA915059C12,0AB8AE24CDD4C63D,009AA75D3E6BB514,0201452330D57AB5,9AEC949EBC54DDC5,44EEF1D5049560D6,ACC536E053140B42,98F84C50777723D4,A4D8B5F3B82961D2,00000000B074A5E6,AC2C869E2BA71676,95C880A1CCD37402,76A3B2A22A3AA8BF,2D6E74B4904946E3,E963BB81AD6C55F6,A874F9712CAF753A,FBC8AF5743617D7B,620A2D1229D2151B,881C15245DEE50B1,00000000977AD827,9125C1D485B5E8E4,6EA3AEC4EA852F0E,15E67F994E56B095,492479FA7DF76D61,54FD53463F50A0EC,ACD5E565DDA1D439,8CE0DF1D17EE25D2,FD8F30887361680D,5A380BAEA05641EA,00000000A84B5D09,682EA1A89207CEDF,7A0288ACF604EFEC,FB53B8993217EB70,A35529B1CBC38551,10C37B7D80E89E05,1A70D17B737225C9,34358ECC6679978C,47340AE0A3B1F755,A08F1CF1C4BFEDF1,000000021700B87E,DECA69EB3EBA2384,36E3D09E75042C89,3646DAC035CA2312,3C73C5F484479ECB,A49C7C51DF89D1D3,9FE167CB2ADD485F,C653D1C2F247B88A,1C977D1A7B65A79A,D6F5D88832023DAE,0000000196BCB3EA,78A3F436F17FBAB8,0191AD12ECD5CD92,1FBFB595B54A9EE6,5E01FB98B4A4E3ED,CD7F3606D68BA11B,3CEDB307AF7241F9,7E66EE8C4CCF6485,A4125837D3E588F0,41F6FE8E832DAF31,00000001B5AD8EAF,0C4C7449B199738F,DAAFD08F1CB8D0A5,4BC1270FBC0E20E8,3A94D60087E14A6A,CBFDFB9BA4B80FF0,202E2A6994F3D77A,9AE8F1A5E775F1B3,D35331D977C18C6E,BB646BEEDB334076,0000000241E954FE,90DA859CAC02C03B,9915756DAFE5216B,51A91533EEB1F373,F79E0E0EF8B36C70,F23C3EB4F952456F,7F62AC88779908CA,29E28786B29B23FE,4707691B728F0143,71234CFAD4C503CC,0000000021AFC2C2,349564D6F59A08A1,111562B196D8A23E,AED723F930E29CAB,58C57D078EB661DF,93C3B8C1CCF1E226,1A4702F9D92F7F71,22C0EA5CB174AF49,13EA55E678EBB595,7F832CC367E0FC2B,0000000192A936BD,2D5F1903F5A29E7D,A3EF04E161E10876,8359AC660DC4AD0E,70905C9E18746BFB,03459385956F536B,91540637A0CAC0CB,7B7D692D7F69CA4A,5A66F69B329C935C,FDBED1DDBAE02CD8,0000000139BDB4D0,E7E697CC6D8DB044,9D4D3C478B96513C,E6198A58E06698A2,9DC8F115038481C0,7389F407D3042F5E,0699D90CC5BF5820,D4FC7AD96E3CA48A,56E1B2FA797A0E55,B0F6168C354B1B87,00000000862009B3,9837BB52155FE320,68760CE0EEF7BA45,C61FB8844612F255,44F88E4855C2E69E,2CD58A9E410AA34E,B3C001D1CA9892D1,F1EFAD50A9AF6B12,5B9528C56F4912E0,8C22F9EE793AA30D,000000010F8E10FD,FF58006E25E99050,ADDECB31CBC9C30A,6A75CA0E804179BC,54642C4D6BF6A29E,41BFD39C4DCAA65D,0AABA319417ADD6C,FF9FA8C5AEBF4C45,EBF6AC0482C8E251,7076BB97CDD6C24A,000000014EE66DB3,4241C73188C4B9A5,82384204F1EFA691,31939688B5E7924F,02CD9DE60582A340,09CD9F992DDD8CBA,E621E063247DCA06,936DCD278792F21C,1CDFFDBE2E7C55F2,EC4316ECB6A535EB,0000000041D1DE32,CB000E45B82F33A9,FDE1A86D3944B9E2,89D9EB573C825030,7F810BBB45E9A57A,408276D4148D02C0,C787BB2ACA49EFA8,E68D5E3E9E8D583B,3CEAF6E6A272256D,54B796A564B7E0D0,0000000271701ABC,2C5CADDCB5C88108,6AD6C1F304E45A2F,7FAA256D9B7E7860,ACBBB6A7F8CFF15F,14156A64C17F70A5,3BE4AAA6B7893E7D,CED583FC49F66730,1A5D7E09306E0375,CE1DFD18E892833E,00000001D87E4FC3,73A6B19EC2C9597A,D401FCE1C13CCD48,3FEA03844A41D2C4,2EEDAFD58AA9BC38,C8029B167FA4E814,F6B6689FBF82C4DB,DD68570D7F525BAB,645FA1686F8332D4,40FA1DC7FB5802C4,00000000842E50E1,37A1C903A9933A25,517FF950B446C594,9042304CF73B0037,A826E66DB8163070,76C7EDBE2ADE71AA,A633BCF45409686B,F54E82467D6859BE,72256C3B60C188CD,0EBD70E99038D0D7,0000000071918985,7676DE6DDBCEC7D7,52CBA83B477A4FCF,B419986FBA204D9D,4D77DFD66508F434,0A8A12092F5956E3,9F162B070B3B5FDE,863B9157274BB58B,64FB3D18342790E5,F67DDE1925B2B226,00000000385FAD2C,59349AC704143AB8,2DCCCA5E1A26C934,9480BF3C9C07C9A4,0D61387E45211ED9,A7351E7467E49302,A75130B66B8B8F9D,A5EEC1CF0C61168D,82A1E2CECC70313F,F2F5BB8F098D50E0,000000019AB28C6C,805D8BDE982E7A71,D67F923B1D1500B3,0C9E40A819C2A425,6D19C9B220DBA167,180BDEEFD02247FA,A7ECFA5BD97FBDD0,DC33550C6C1D7786,2B1766094A1F2F57,B563F2C02102DA66,0000000183331ED4,EDACBD84B32375B3,3069700FAAD92FCE,61F627E9D77932DB,FA6F90C03E635032,38AD0164291C0B4C,300C0304831090A2,63B94D8B9B32D308,63D3395E5F9BB510,AE741A154EF22247,000000022DCC03B8,486E808F93EA7629,945945B1A9731EC4,939E4E7C3CD2DBAE,38B616BCAD79F83C,0EA2ECB23A69893C,4D28D575F88110C3,FFAD954743892B9E,6160010ED92E064D,3D979EC4D14E372B,000000001F7C4CB3,39734D94C0E3748B,5CCE1B90CAD4E1CF,C4BD93275BF47133,0C7D18A366B17D19,CC3570C563AE02DF,6B4B35F6F729B6C3,9462EC25EFA99802,4B051ECDD3A74360,55F1A06915B8DC56,000000002D6FA264,ED9DC5B725DF7953,64EC2A87032AC54C,32063C82425A68E1,91886B9034AB1491,75561B2DE4A970AB,D3DDD4881D2CB320,40BA5DADF108656E,CD5B7A2877A875DD,A2ECD25567534B8A,000000005CC4C8F6,CF7AC89CB7E681F2,1E8E6B3029CD94BA,59CB9DD0C7E21C54,CFE1AE1B66C12674,5C6275D402FF80B5,878117E979C87CB1,B1E5FF81707CCDA3,D3AA4D9F134D0C6A,64FCD098755F584F,00000001C1805B21,CE62E436E3BB8412,9205000AE0DAD55B,10EBE3A44BE2B737,ECB6E567E14DC3E4,4E3CD9F1C28C8185,9D465BA217C69FE9,A2CD06F1EC836581,4EA7645CB116C87F,59659D555AC45B72,0000000127933DFB,E73BFAF68B1B2058,6C3FBC7568D3C2BF,E59584E28C702310,B4711D1308CA5851,37E9667A3247EFD0,7B64C328F7B75FC7,8183C9BEAAFAA97A,4FE3FE9251C7828D,D26C96524CFBE700,00000000698ECCBE,2EDF5F4E99949EE3,77F2A90715951498,631066C6970840B4,8A78FE3111254408,14A8395248E6DCD0,7C1634AE94453686,E058050B6505D9BC,31D8C7D8E027466B,2DDC747011BC1F98,000000013510EF05,01CC4F7B13C6039D,B57425190C08F3CD,47FFCB0E6FC8ABD2,6F76CB4A1C8E0560,35A3DA8C8FF00842,C51A3FAE77976D3E,1FB601CCCCBAE848,B0E8A8845F1ABB58,630AD2D2AAF92649,0000000075DD76D3,BE1E12E4DCC29585,63FAEBBFA792D551,6538AEE62B9D13EC,B2CB88C935EDE29D,59F4D4F3587810E9,8D3B4DF73B0A324C,96F58D10BA8CCCEE,D64D72ED37E378C9,081D52A8987FE557,000000003CB2472B,9F6A20509E0A3A43,8707712BC646DC0F,BC07E6C7A261967A,A16B9E51788228F9,10714CFABE3B3D26,6047DC876C219304,4FC361F9D1D98CEF,713B6EA8BBA52701,D2CEE61A01EF7C04,000000002A7E5AE0,7EFD56723E766E08,28AB963EDDE4BDC6,DB1DFA7AB3C05689,2521388AA5542D48,9148440164E2BBA8,59EFBBC78F207138,C91C92B8ADA94A22,E42645FA61EDE827,D49A61A29D1AB3E5,000000000F4439DF,757973336F1E6076,11A9B8D74F50147D,523B42B62B40915A,94CBE52AF5E20FFC,D73776B286524A44,C8858CC92414D53C,E3EC2FF8C7E1FD17,6841EFBDCA5C29D9,0ADAFA991B2D3E6C,000000021086B49F,358F4FBE30F41112,35F82EFF5E7F8EEC,9A5AD581CC779239,D17A7A78A2EE329B,07A0A2F19AAB8FFC,9D8B407AD9290638,FECAABD19F50D587,81FA112349B6927F,E0BE0EC6A1294FAC,0000000064B03DBF,BA79822B76FCA728,2D785EBEA480D76F,11993550BA0B75F5,87A016CB1E6F2E04,84A3CE2E3736A792,0BF22D02B1E8F406,054E6B6E52A8BE33,2A61B0D162CCEDF1,29FB23123DFE3A7D,00000000A7892026,042CFDB6A72F9E9B,551068BB4D3B0741,D0916D992E8F255D,876E6636781FE511,0F1CEDD5FA52184D,C874EE59CD50C2A4,456DB26EDB1DE6C5,3F9C76182ADC4877,34D6BAC157EA6B7E,00000001EAE669DA,D94F9DEFB0589D90,95174F5A7912DB21,2D72678F13062D82,B33CA0F40EAF5C47,C745D326029C8469,69C35E486CD4A8E2,73716E87918E2EE7,004D50622A9F5383,CB8BB6086C05CA32,0000000013879BF6,3FC6E86FD09361A2,FEE74D051D216E6E,4412B23CBB8062AE,E4260675A1037C3B,6515BAABA699F593,C26A275DFD061BD0,55AAB29D3FE1EB3B,A1B1D3ABB5679DC1,EBE9380450172896,0000000152097971,4C1AEF68FA56B238,C97F95E5D6850F6F,B81429CD1EE24CFA,B9B258E48907DFED,7A6FEF17D4D0D635,FC27F6672C24AFBC,FC26CFB5BBD1C203,476EFDA4C20887F4,F0138E01BC29DA62,00000000C6107BED,1F0B8D1B443A37F5,28A7A1CA38429D73,AC2D08AAF5FB68ED,CEC71F17B958DC0A,36E253BED5BED1CB,439EF68366902444,2D89DF19AC66F76C,7285D89D5F59BB94,CFDF015F3FF9A738,00000001E6819815,D6223D72AD8BA8D4,9B6935A620B7DDA9,257680D4EE089F93,FEB88263565E9874,638C31F374BFA417,71E9A7A76CC19673,77A7DF05B1187153,DE935310BFB76604,919FB06E1249CC37,0000000004B11F50,177A0D0C2A78BFED,30912DF6DC082427,ECADC4A89A8BEF8B,68A935132C0D7318,BF6C877D35E9A215,7332A98847E7AA5C,7B85700A355CA6AE,0DABB5A7F994CDE3,AA39F4401CF9260D,0000000110DD4DA5,0DD2802170B01669,A8F30E238C973EA9,E38A85C4FD73AD12,424056C78AAC1BE1,A155E2CC7239EF00,A9AC8407CA4BBDCE,B27C9973C80F0DA7,D1B2CC0DE8DC3B3D,32EF0BF8E5A6D86C,000000009896C9EC,6A93F8C5A03F0AD3,62BF475BE510E6A6,1A91BBF802495604,D6C6768A54DCD808,1070DA937BF05ED3,AF02BB229BD17DC8,3E946F04F39AEEBF,7ECA880C052E5055,81034D4858047992,00000001C9173143,8790B507413BB00A,C91E7E669E8D622A,2D2896402909EEE7,199C952E365B9F80,EDFA0453703DEB47,049C4548964E185E,223421683BC1FF93,5FB772DDD823839E,0BF258908AFC0816,000000011BD65D6B,D69158C6F49F3679,2B5CF327CC4781A5,3B0EE938E49E1DE1,99C8D65546D368EB,AF8D41DB334B0593,9A08383FCD5CE046,8E7BD02B05E96179,92A3913379223B7B,F251960723AB7B98,000000005C30D799,63D1C5E488897B0D,AC34588B75D470DC,9063FE5673196FAA,115E41EF8152C874,878CFA4AD10DEC32,3B899B037A099F3C,B01A69D5E43B1935,229D16B3F6F0B0BD,D359304E4CBD3DFB,000000026BCE6F5A,D910DF273BA99CB7,9C4129F3FEFE0496,3407E14B330A07D6,1425A8A0DA1840FF,68E1062E7EA3CAAB,F3BF719893F1A906,3A19B3720FB2B024,C2231CF075F3A571,97BEA343004F25B2,0000000059C9F39A,3D05265E0FB1FEA9,A69C8774E8AFA004,3415EE0ACE7036FE,4CEB334E22A8242B,D14B03A0D5F31B9C,97702EA6EB2AAF47,8A5967AB499D5FF9,4C27006C6BBC8D10,4FB8FA486CEBB917,000000001D271773,473CC408DE38A2FC,CB20BFEC5E0643B8,F44FF05A8EF43BA8,57AE37A1558099EC,1101480592B98179,FAFC83FCB4048495,002A53CFEB808A7D,5D386212A2E83664,521688BB6BA21E1B,00000000F7AE8B05,45B74E6F94B0D1F5,21D45949D9713862,3CE9BF2562AA05E2,0722AB387903653A,D2D198981E0EDC78,AD2DC38CCE568B4D,55E748731022C1B3,5D69683C7695BC15,F84566C709BB69D4,00000001D03F5700,5B4374DFDE89D954,CB492A2BD63D6B87,EFFE7DB182B329B2,E812DBD9B2ECF451,DB3C7C263E614207,DB2EDE8257C2DCC9,F0B10DDA602F39F5,A26DD94B51C7D007,2508AC0CFDEA2599,00000001A33C1A29,5E7898234899034A,0F249B7ABDBE377E,E72CDD296D269FCB,28CF97050DECBE5A,7D4360AC8776A820,D6B26B5B2DEB49D5,D4C39679D442FE7B,E8B6D8860E64BBFC,E54502EC6E0BEAB9,000000024BA8D653,AA7F891F2793A2EC,1CCE74BD28C42983,5C2646644EBF2822,9FE8CE196D593F1E,B1CD6F09EB4BB3EE,FEBF6BA6053FC21D,CE175FF190F484F3,557DE67454E567AB,34E895AADDC63FE6,000000010E65AC8B,93F34B6927FB07BB,991CAD19630B4196,63D21A8C686F34BE,A2A9C3A6E1C00A30,0D5DB8E00CEA8E7F,07446C3CA0463491,EC5252E6B83E3F4F,E67BAA34D4BF906B,C7A6F658B3B4750A,00000001A76A220A,956CA9CEA54364C9,C347DB9D945E2023,587031196699C941,1A5A3244B8A82CC1,E2C0C8BC55E71CA6,235BE2D60B6F0AA0,BF0E8A2454BCC4DD,946016DBDE568D1F,858D50A66782C179,00000002709FFB5C,6246BAA68FA5D0DA,1A80B78BFF4BD05D,9313D0F24455864F,B668E335943497B9,531CDE035AA21529,8DB626BF143AA452,FE74AC4E75B55B1F,E772CC71BE2B2237,4805FE45F326CB8A,000000008932EABD,0221170DD4023594,E8D9DB63999A5D8D,0ABE1AED222D22B1,7D0E67E524F19412,6B2AA860A21B7679,D5A7E9479C09B345,16D3F149499428E3,A97037571C10E284,C5F36C6AA66FE3A8,00000000F972D639,0564F97874143B8B,2045744F9FE4B550,56D46AA1BCBA6C3C,D35D77D688636A4A,DC4816859FD98C72,3C39D9BFE3778FE3,B7D98F0F5892D2D1,0288045801D9E137,395B2C226051AEF5,000000004E719639,9B5E40E8B596C141,C494B08F5FF4139D,F7E07F1B88609736,D926C4B4AB8234A0,198AB22E70DBA577,E9A531C578EFDB47,819F05F31FB941CB,BF8C70D866AE4E29,8896EAA6EAFD2B35,00000000F3A2E5D6,F5F18C4296F431F0,7E09CE9DD5689C93,CB8B6652E806A6A9,6E61E0B57433295C,7476599D345C0DF1,B18B174CCE72C9F9,6CB64080ED267E75,14DE2F4033DC29D0,6BE0642C767A5871,00000001EE8E52E5,9933FB01D1ED7A5A,6957589D898AE6A6,D90801E5B2FB9151,3423A2F7C3FC18BA,834E89BA246B39D8,C26FFAE3CEA3DBD2,B4E4E5B4F6447BD5,18A3D8E44E01DFC7,5D7A413A41977C81,00000001BBC2E85C,20F355D9AF75D7C6,06156CDB56A3E283,0146914758F2FF75,02068455D53217B5,AFD17D47DD4AF6DA,E08EA80B21DD2377,FB0C3D4629E98F0F,D50696271DB664EE,153F5DCAA36875C5,0000000025F7A997,48E0BA8813AE3208,3E89E11FC7044F7D,02B7767FE80D146F,149BCC2649A8570C,9226DADA13D3BF72,CE53483C4EB0BFED,B8E01056E329402C,4FF9764FB3FD81F2,F65401E82F29368D,000000020A1DD06F,ACDF4C0EC30234F5,E8A2F44025E0B282,CD2A409BCE83BC0C,49AF8F4085B19137,3D370B6E11F6E9A4,D954D18B55615092,D8887BABBDC4A5DE,EC42870E416D4401,62B39A71967DA895,000000019DA21DDC,EFED41FC6B792F3A,6A95E5D5748243A6,84CF7504A3D7FBD8,8A7102EE960B9780,AC8AEF2E3C32F9D8,5D30A29E35C4D448,A23A40C6FE2FE5A3,6AED33B47864F2BA,96066E82CD3EC624,000000019B332BFF,91AF9D6FBB798548,9EFBBDA8752FD63E,370425C1A1A29AD6,39D82C8C798988E1,F6F265E1A554EED9,2B190EBE0A87D70C,E9484EE2B3D217D4,5E81F15BAF2AB3B3,CBBBE0D30D10E64E,000000006167AAA5,4A2DFB23DC37B60E,539BB9CC6837CE50,E0CCBF4B4F49208A,FF460D3CCB00DE31,C2357E813BDB4D25,3BE0FBE761B45523,6E1F379DCBFC9FFA,2868202CCF31A8DC,E43224E0D54138EA,000000020865FA61,5EDB86A2FC021327,B617236A43B28CEF,0727A3B0B2B3638F,0626D403C6125931,A8E2B733F0C7E11F,B3C74C3B6C40795F,D7CAC0EE90DC7C55,7E4BCDEDB48C6F5A,812B8A45009E9144,00000001C44D8A4F,C364118656BAC7B2,A0E9FC0B9843C42D,6FB730B8DE3B9513,163DC52EC2E36512,7F2E55178A3DFA78,BD38BE1DCA6606F1,2C5ED6FE5915390F,69866EE49E3467E6,12D8951725581752,0000000114849D12,5EA7FCE526186976,E2C4C2E01236217A,4B6B31792BF46D75,2A4ED4BE974EA8B9,84BE906185D6FADC,55CE0E20A06E6BE6,FB74F5BF756765FE,040B5148AFC5606F,A12FC1B29ADFD241,00000002076DF40F,55DD7110D44C2A32,6B0F770B9ABDF7D3,AC3A9010C3991659,45F3E3C7A1A85609,5EA51E39DC89852F,077E9FC0BDCDB4A4,C646233E27F45566,33B21F24C60FCA83,703DB35F49091724,00000002144D546A,2E2310DF28673862,E6C7B89F18840E40,E0BDAC7BE3F9625D,51399A7B3AD225CF,53850B31E7FA4E73,5F1BFCC5BAD27BFC,BB349744DD68C76A,C45BA4232BA823B4,C335D25EE94F1643,0000000060E7661B,980444AF09DAE3D4,4CAB149A4F27F3AD,01C8B05B2693DF9C,911904D90D11CB1F,F989696A53F33A12,2AA5D24FE94B451F,543317CF89382CF1,811A6A582239C3D8,FCBF85AE62DEFD0E,00000000275E14A0,23982A7AE8D39685,CEF83B9E574680FB,B9F2AE66B1F310E1,323327D6544ACBF5,E482F4E424C0BC23,6CDD9E49DE77F94A,61E9C67898B137C8,5109177250D7C9B5,E33BC632902FB6BC,00000001F24BFAEB,EF35920CF79A56E6,80B84E8AF833A6CC,8B0C8F57B6D68013,487BD58C87E86D70,F30596085F98FC01,F5000E1C46390167,A6EF73BFEFA3E29A,C4717404994B17A4,CC04430D842A55B6,0000000067CA8D1A,ACCEA2A97D38B41F,EB85F903E293CB1E,E013A4C515521CDC,0FBC00B174AB1554,9FC571F395C26F34,3F479CBC491F19E9,D32A5D380628401E,77B9395811EE26F1,83AB191CD80654D8,00000000B9BCE67C,64109827F05D463C,DE12041F493A4F13,D61FDE0803880931,C99D3370017740DA,0DF74328BE2B5B63,3AE687A68F35D72D,174BE64D7B34BC15,2AD3845CEFC45EDF,38E3A37C049BEE3D,000000003D34BDD6,319E48C8CCED4A49,F55E3179EA48BA70,DD0A87B92D6C0AD9,36B8E357E72835B5,F1B4FB1CD4A63B0B,F5C2C0362C18EF6C,028E7FF27D33787A,966641B1CE6B46F2,8859031E53E6E16E,00000000AF21DE22,406F91FB0E89B271,319F876D817F186E,93E893B2287A30CE,29D6BBDFF1151A79,9CE3F7E2252A0FD1,44F3516FDD97F172,A1F708746045781A,AC410DFD9E938D7F,5018DA35336C325D,00000000EBB232CB,4B7BC844F91E0F26,E816CCEEB21567C2,3924F62C3CD325EB,7760FC811C253A5C,3D2C4AA516E03ADA,D7B8C235670BC34A,8179BD4D20584621,3CAC388553F33427,7E5EF83737601781,000000000615BD30,CAB9D72A909AF915,AA1941C08F87ADB9,05D3583D4CEEAAA2,0A375D3C232FBE72,C916A191AFC77F4A,8595E5D6E4196335,F941CCBB21841748,7FC6CCC8F69D898E,77F21891F84493B6,00000000286178AD,1F5D2F8CE1DAFF4B,5133D33A81B040D1,E266E7C6DF5F0872,E2AAD2349607BB5C,09C43DB6F733CE09,3ADCA8EF683F2674,5B98D1FF67BA391A,25BE0BC9669ACAC9,84C090B12EA87380,00000000ABD12B95,CF83EEDD8AE72FD7,3FFD61E27810063F,CF8FAE201BC3BD3F,42F43F5C43CA19E0,6D4943DF98790235,C76A91D590F86E21,85F0751DBA526799,58714CD993CE923A,67C4C6E3A0F932C4,0000000211ABC14B,95D73F90BAFA20ED,7FDAAA6BA34BD9C3,6E65DCEFF7BB08ED,EADB381A7B07ACF4,91B4D824AEC59CF1,C3B496AB772BC1B1,3C508E03900D1260,5B63D671D34A231A,7BFB7E3B79EBC770,0000000215587BEC,CAEB60C927D91C46,2531F5E19A60554E,71223ADC59D3D0A8,4E096F5C4BAC29F6,B04E47624BBD7CFC,CEDC9D1E7B0DC6C7,C8166A87BD18A649,6F97DFAE00EF21BD,2E45D461B6AC31D6,000000022D205FE5,0B4D7EBF914A3586,A0F9AB2A5E123A0E,C4CF91B4ACCE2551,7FFAE782DC7573A4,8A6146BEDE6B95A6,B6AEC14B2C507217,555F5D35AD60D840,8E80029381FF00AD,136785DD4DB214D7,000000007768B00C,5872834DB40561B8,9CC29303582D988B,31A4E849B59AD434,764D035B9F23DF9B,1379557471516AD5,CD0819B0593EBCA9,7F36C5AE1353DD24,D758A0546683BBC4,3CBBE368D1FD07F9,0000000021964BFC,836D97C005CDC39B,BC82DBF8DBA7E240,11E60C0ED73022ED,A3879222CDDE7407,569D3976163548FF,576B2946C1AE8128,ED440C8D88B500FA,670BC8AFDA250AB7,DCB9B60355C01A44,00000001188C8469,A8F2AF215AF4FC32,60C226963EFFFE25,7EF77BB30094A868,0DDF9C912658018C,6ABDE4DAA90DEC24,784B9DAC5C5DDC3D,865E28D639E94BEF,072BF40CFE33B450,6E0F212CA775D044,000000002A41C6BD,F629491071073BD9,762FDF5711217EF7,613A403A290CFCCF,7453FF985A730F4D,78C5E5435DDD194B,91946DE496323008,85A548B54DB9332F,81A58FFD1A3AB0D9,17F6FEBE9AE86939,000000018BA08D12,162957483493A024,4D6308654081EAE4,3C5310BFB1F2E036,32C13E40BACA7451,C8BDB9FA86DAF2B6,4CA78BE045732E4D,60FF4FC96D7F5143,B88891C1EF04F10B,47BC6E95896695C2,00000000F56CC4FD,C717F1FE6A55E6CE,9875BEF966CA9EDD,C61415748D916CDB,294AD0BA91817B28,DD10EB05C02CBB36,03C0655499C07A35,925D2FB5470908B0,88DFBF44CECAD2DD,EEC3F801E60211F7,00000001A1E7ECFD,E7343FA89B5C3BC7,E98F13A2ECEB6C6F,D646B9039F1076B2,2BB92A0FE6567774,790A87640529F6D6,5755AAD5C4114D67,2A337A025471362E,FEC1D3FC4F4559A5,5A34525A07B7D502,000000000F974375,DE5CCF515656651A,D7EFF439C4C22E21,D1FA876CBE7DCBD4,7914CEC4B6F52F4C,20F0FFA8FA5CE867,5F478DE60789DD61,AC2F25F2F72E2E73,CC5FADFA9103E394,5457F210221142AD,000000014DFFBF3A,E685B241FFED6C5A,0398BD556B93433D,DF2FFEBA80E10030,F65FE409D0E9A626,85FDC49CEF30F435,FA5484CAC27F22D6,B73B0AD6A2B7B8DD,02DA8FC6644EE942,3A439D4CBF42A4AE,00000000005513BC,F9A12A1CBC7FDB11,8FB598FE03C5C4FD,258E2EE2836631D4,DB89943A6DC8F736,99802BF41ED70935,87A14C1BD0626BB3,5541D9E7C7FAF0C0,4E241C5EAD068236,873453493AD4B244,00000000439ADF84,F955DEC4844519DD,44CAC7597EEFB066,6FC7D21CDFD980A3,5CD4A9F71DC90BB8,1DA726AC399614A3,4B1FD626D8EEA051,C410A0BCFE0C2CE7,02CBACA42CC42F55,85EEE50C382C31AB,00000000BE08638E,357F53D7C1E2DC06,C6394C92FE972ED0,987ECC09254EC1FF,41741FCB4797B683,599B2200D0C06455,4A15D4B2A16CFDBB,3BB3469725737E4C,FD0C81AB7031075E,1A7B67D5C18D963F,00000001A58FE307,1635458060268010,8989C600D0C284DD,1C476538C9FCDB04,B02986F384BDA64E,271D4090051932B8,7A856157E7541CEE,648FEED82526C29E,4CF66251F2CA9B2C,25A15C2178793101,00000001B2B5772E,DD5A0FDBFA42734C,E99DD7AA9742E743,584E2DD5C9AC9D5F,92728BC2BB17A538,CBF7985690F87C18,2D80BF2FD5F65EF9,72A7052D51A9DD3F,47B81EAF928A33DF,161F8C2E2405E05A,0000000083D5AE3A,6C6EAC1ECFFCE224,B35A78EA40C0D9B3,424121027BCCFD8F,1E8419C3E77E2EB1,98918DC4200AB75A,352AD9BC9E9407B0,FE891B99A8FFCF32,D77B182C50B25D4D,A8B1B2BF28591E50,0000000014EA93C6,CEB98BD33E129668,51A888876A4C98DA,45A8B676ABC84441,CB96974D24FD3A8B,25559081A324B155,9799885A54F6C103,FA788DCF17D09396,2E0CBB45A0D469F6,DA2A410D610BB651,0000000231E32910,0AA84E9DB4D1BA62,EB004F4027A3CC2B,2C2DD0F525EA07ED,B5FB2DA265071CB8,E0189A22C7EB87A8,70703B883301F46C,8C5B558DFA82A407,7EB69954AC1F2440,1F47FCDB8C71B28C,00000000E7673BC8,FA30D9C18F88A1E2,8F07D5729DF30022,D0A4BBDB4FD3182A,60AC96D065244495,1B14762B5C77F564,FFA79DDB28CAC57D,57F846352C2D8971,4A0962ADD746D124,F69F73C6DC343638,000000021CAAECAA,916DBBE842D47271,319629A79D0A4471,48E86BB5628DF06A,3AF61AE371F928F2,AFA187D3976E61DC,04A1D9341396EF5B,689BDF5FB401F2D3,5AA2ECA4F317BA30,ACDB1A202038776D,00000001986ABC6A,F16BE176D2F4D479,A8E48B211A2CBBD7,5131263AAD216723,A74A3CD08EB9D657,94CCCEC627051751,8AEC29D5ED9BAC8F,D91CA1B70E4975DA,4F6B143E576E44C6,7CBCDEC03F185E8A,00000001F452B4EA,9A2D257F7835A1CC,28D2C52DA84A548B,F08E1FA4517770C4,275D0ABE416A23B3,0AEE852AB49C2FEF,8D6EC46A9761D080,3CCBB07068279BD0,B72E4D8267D4EE17,152344EFE99EB34E,000000025BACE524,3B1E629EABE5E5F4,268FA7CE27017069,293B604D74D73969,F2A8816CE092EA58,001A21FCC333C22A,DBE4921B3356ED0E,AD92EBBF2CC5CABF,205EF8E891BE6DFA,23E26DC3B662A351,00000000B8031603,D9C12442449A3AB9,9B1F2CA683C8A23C,23E8E03BB4E8F3C5,52F980CCE027257F,4941A87DCDD4080E,91B94EDF43709964,1E30CE8B050DE2B7,572F64EC92469466,C8F84F0C3CC9F203,00000001033CE526,5BA3C2F8F05CBFCE,A751F7FC3D8FA18B,5F039C1AD4B468C5,32C86229EFA9606B,EB3830F5B1B9D5C9,CB79C5B56067532E,F8BA1F8381D1332A,EA822EBEAC6B0266,042E32D099BD1B8A,000000023D72293E,31FC7FC67CC151AA,51786C4610F0AC03,42CD3AB23AE90AD7,602BFAB14EDAD38F,604E2174A60B03F2,56C817570401D6E6,C6084F35F856A4B0,B923A39E41438809,81028A0A9E850392,000000001CAF0D1B,5281E0D20E29394C,091EDEA67E5344A3,EB18E7C6D9CC4542,0F48C0185EE1854F,C0CE320F8702FEA2,58955FCCB15AA945,169360D13FF1CACC,7FC7C1893779AFBB,43F3C3D048A732DD,000000010A07D129,BD24A9681458C11F,CFA027BF1B7E555D,6FEA744D1B2EAB36,AFFCADAB85D48E7E,45E7D55FC156EC21,5E915E5844F4E416,4C7208032AA31EA6,E8000F43E856209A,9011371092BB882B,000000025C51C285,0381123175F02716,676A81326B2F11C3,1D12DBA5D9DAD119,36C0D71660A273BD,6E3705D04BC99E69,12FAAF8707A4F9CB,27DE859CBD6155A8,0CEF96FC5C757C1F,5BC973D15810E660,00000002613A0B83,003F596D89438835,EEE56D2B85FC987F,5B40419947FACB57,9C2FA6781E90EB4C,85B5E32870D00AB6,B6D7C01BB564DB41,03128E146A9C33C0,0F599CA6133B0C09,D0F1742BB72C18B2,000000007BAFC6C2,07FC068B3A52BA2D,5DFEEFC356D242F9,881DEA868BF38DE1,1053393F83579285,55B7425E1008E16C,21B6D1B14099F273,F3130CD647038838,4E138304C7DA07B0,6B70569AAAEAEE18,000000008E95373B,ECE500D4BA68103A,00A5D9D4A30B86F8,9C8ECA8B963B1E71,9CA1CB0B5BFAF139,7EC2B880F5F6A481,54930BE4B776F20F,7245549410027A32,1C4BF53F7B1A6788,836005FC61BE03A5,0000000255AF4C1D,33521EA4FA84A71B,DFF66FACB9A15847,D6AFE5E4E70619AE,5593FC855C5180A9,CAB7AD9E62BEEC72,37DA92CCCB297CD5,95F70B0F4D5BAD4E,3F88A3D18B096C49,D2317EC213858B9E,000000001BA5A9C9,46D4A9252AEA6A16,50E62F2BC0F1EB74,9097B9A9E46E9F3D,4DC07867AE89C25E,1F3629722AEA3C12,CEFF8A84555049DA,5D20B9B0A950D0FA,02B5A0BC0D149A92,54DCA6A30E8D042F,000000016C741133,C10A8A2939269667,515BF987EC8AF438,3D16C44E5AD3FA41,425F2C069EFAB672,BD36B0D35E938632,3C7972F324568A99,17DE714F4043D9DC,AD8DFA1B2AF57C6C,E87E3D123BE25BF8,0000000112108B77,B24C54810CC5173B,F25EC5C221075285,2AEFC2323092CE66,779A871CEB67718E,0F7AB51F57621F75,A15CBA30D0728D10,76D76D995AC4A446,DD44BE2B1D5AD4B5,2BBAF5E1D999ED05,00000002759CE63B,80A2CCB3EF198B89,B344EAD5CCFDE125,49720C09A485B8E3,4D4DEF3E0CDAACDD,58D17314E5AB1771,C728DBEA50061057,E70014FF2CAB9B5B,60ABCF8EF0BF2072,1F8D46A06E877AC8,00000000A5A3DC16,E3F235A4ED5D1475,0845F21E1A463623,DBB95E4238141701,0A23A64F04941A6E,7C9200CE14B2E653,DF685760173EC3DA,68527A0FB9F93815,61DFB65A07600C61,87DA6C7FD7217D75,00000001AD919C86,CD3CE12F524214D7,A90DF5E34ECA9481,B24234E8FEFFA7CE,3A8CB443919FC356,D69C4AED94C29F38,E2DE6141768C1762,2154135EAE36B357,84694660D55B9DD1,F4230DADE4D8659D,000000005AFA728B,7FC89A6803AE29DD,0284449DAB472ACE,7970E546B979ABB5,951367842CEE0844,59EF285CE5710B7F,37A7FE3214911E00,212C2B8CAC2B4C3C,585EEEBA3807849F,4363F6631CDFE08A,00000001BA7D8854,6D7FF9CD555FF3FC,B44126665BBA29EB,94267086D055A5B1,CC6D98768C53C376,90DA6C67EB1C03B1,CFB227E7027FDF59,C0FFC36C2C9929EA,27EE1664E4B7A1AB,3018F44513110A82,000000016847B819,367CD1D7B0CFC38A,C689305C0FE078DA,C4E1795414E08C5C,665424D6E3A91C9F,9C79855D42FEB06C,BFDD287BDE98896C,A76879992E90676A,CE20F212F4759327,39C2DDA4EC3EC72D,00000001E4434A25,1DAD7E8624815F81,38876C9923FCE461,74A88835FF8D893A,C0BF89397DC62386,8176C68F4FA00D75,51B38A56E3DB85B3,F22ED1F9F1F6CCEA,26BA77BB2793C306,FB66C06FDAF45EE4,00000002497BFB65,49E8C44AFCA5A1A5,E8C44EA7B1FDDFCC,9623E32227D52730,F9E096778DF25B2E,269C3E8E9E54F751,8154BD105C5302D9,65E2B4D411A49DD0,BD34BF538D314154,855916CF781DEC9E,00000001664B381F,8C0D7859C076A6E3,F670A116483359E5,55CD931D2E11B3EA,499EA532AF474DD6,28179FA882112CCF,28F207CF02FE5885,5E2DBFC750ED4F57,82019AB672BDE17B,779FD6721A7E3E97,000000003A8101D9,79306CC1238FF3E4,FB22F9717D131EB3,0CCB917F011B9EA9,C3C5EC41025572BD,B53A8F46FC0F5A3E,89E4AD02FFD12A35,6F3A51B8411973E4,2C814CA2515C3889,D3AE6F71D88BF21A,0000000020BBBCBA,22117A8A2DE2FF79,068E341F192D1E8E,CCDE785D5E009AA4,81A7490C2C9941ED,19DBB1392EE6B1A8,63E7A325AA16D7CB,DABB2B3052F71796,4F5044EA8DC90A27,CD5F7508D6306883,000000023722DBD1,A4920322377A9797,C698DE1F502D274F,3827AFCDFDF7D007,BB09805A4A2E7BE1,F8A092467BE1951F,C9D602DA3C8F5709,07B83506DED58197,0476B3B64D6CB016,E6E7FCB6467BC9D6,00000001BC9EE806,AF2C487453767E99,F4B451D9C1023495,04CE074E0CFBAB3B,C42E8CD534C99D0F,29F3048CD6E063FE,D6A972C92384B4C5,C71337E0E15DEB56,5E1C0A233E7B13BA,7485686EE0F77315,000000004CAF6414,3B201CE41C1E5146,3B526BCCE77F9211,491AD73C3842C020,6AB6A911A7D810E8,3CCDE8E41B9A0868,4ADB7F0F5031D049,0899281B608BB8C4,E6191A34A85D53E0,B0DF58328B7CAFE7,00000001CF1A2F5F,61CFA6767CBA059F,212BB5B2F38CC30A,AAABC4B449074114,DFCAEAB15190B0EE,0FB62C80D38F1FF9,631BAE9EB6557107,E5747EC60B5BA6F8,21587C3CA8C013BB,C05987F29A64D3E3,00000001F55AE24D,34756905E917EF0B,CFD509EB36B5A6EA,F9C695941139E408,29B706282A95F444,6CA28EC1E8E19B32,9D96D9F9A4B27347,5BE124606073D4F4,4CFAA04157B56968,CE1FC443BA5F9CE1,00000001BA501B01,B6B9EE066AFC4F15,50547E28FA65845C,AD2072D63DA85532,11BB2209A499185F,8D56E96346EFA800,AB2C77BA80E4BDCB,2C6EA35839E1CCE7,08C498CA39C59AF4,4B7E76F36F0BFB9A,00000001ABF408C3,38C9641A188FF971,5D83BA4C5F9B9B34,5558475E4898869E,8C0A406DC29FB432,15986BEA706837B7,0D3E031ACB5EE417,ECAB990196C134BD,E9CC80A11E3A15D4,0D0FA42047D2BCB9,000000007B924027,8AEB1F4A43268E20,FBB7D530A973092E,05DD93AC91B94576,48ABD8566E5C7781,86A8AD48D6750CE3,4D08F6AAE0FA5C72,52D6B9E71B6B9239,9FFE653AF6FD1A60,09A6BAA4B07531A8,00000001A3744D1B,8ABE68690EA02437,C67C202602EA2F09,E6462B22B73E9ED9,6EFDAE9D366E72F4,BC8D7ACD94494321,BC7034F813C3BE93,556DCFCF9798BE5B,6884D6B6F8ECDF0C,E78E2419CAC41D2F,000000022DC58C7D,955C700901DCAAB2,0D803A6721A1ACDC,53A4342C81412FAC,D747BF417FB64FA8,EAD8944BD9DC92C1,483237B57988ECD2,E9AA38B2C99E02D6,EE0AA717B8F337FA,0AB2DBB4A3812BC4,00000001FB1409D8,7DF8C64075077E38,47D5A7340535B959,EE5FC6717E2DA5C0,B680436F503483F6,5CA92D0D8924E050,A4E6BED13ADBE0C2,9943AFCAD4B32457,9084DDF8D830DD9F,6EF06E6963319805,000000003E5C5E0B,5F417E73675C495C,6E1E90BEF899D763,F9C025A81099A172,54C3CA34B69B5144,1DFADA16A7DA9A30,6A0DF993F98EF5DC,85A14BA796EF73E8,1DFB18C6076BE468,D22E69D09243FA43,0000000223D3B152,7E68BA277AFADE21,9844C9358F67AF90,7B0A523F4D285346,4180AC63FF400DB1,DEFD7A846812CF78,4BD44A1FF6F81A1A,5D1D17286A7EA0DB,8FD52A573DC5379A,A7B105E82ECCCD40,00000001B0F82D39,CA424E040D063D3A,F49C0CD4888426BE,318798C31E7365DF,4676CD693650B601,5411B817F661FBF6,58FE5898375E6C40,F41C8B0224ECD617,6873F54E72B146BB,8C661771AC8AD909,00000001BDFE1079,024643D14C8C603E,75F59324E0D31D24,3377E43FAFD7BC67,6C704BF47A710840,1A838C6CFF4806FE,86E28A5B30DE032A,1CCC1A30545E0468,A61875DAD0DCA45F,6888C5CD8365F3E9,000000018C7553B0,148CF812983E8C3C,E65ECA5E187C15C2,9613B8AC5084456C,540EFB758B567EBA,F86DB844CDB40C7A,B854C6F41AE983F0,07F87154C950E29B,B75696766F765CBB,CA8039764470C94C,000000018B7030B4,043B2C407E137E51,27015EC12535D90D,8114A5E04A69D705,FCD68E654CD0C52B,815C1528D016952B,544994F6591CD1BF,963C9853BFD642E5,1B2FF8B8B779D0C5,88A953414E62DC00,0000000034F90B11,7B25A48BCF1C0F94,D374F977F1C5771E,64EBE56BA4839286,0E727F848E17680A,6A8348645A28C6EF,074219C0E8C97636,F24779857DA80F17,9509DFBF2248B0EA,F6CB4D3C708D0B71,0000000265D06ED0,DC09EA89B9300ECA,9DC513FE0823B3B6,5BAE13E506C7EE50,23D100801EE805E3,9E7AD53BEC5E5B2B,E989D50FD3281AAC,10EDDAD987550209,12908C1F5DD9FF71,BD63B45C4E7A85AF,00000001E09908CA,1E0FE003FE88FEC3,F06ADD2BB6924E31,3C9180CEF51A9D1E,A4EC8115A97E3CA8,818BBC1B8FD9C76A,5735DEFC7C3DAA9D,F2F242FAA698720F,0120CD66A860169E,583CDE06F42B35FE,000000019FB9DB81,6D6A52B8D954713B,7163325DA4EBDF11,5F47B2BF6C5999E8,1E323713AB20068B,C5B89B9E46B4B198,12BF5F459EA4CEBB,71299115B0A5E71F,5C4EB76F9E8BD4CD,DB803CFF46744EFF,00000001BB969B05,F5D0D42BA672C997,C9620B6872C493C7,43BA3D155390586A,0C41EC25A137BD25,BC53AC4418116C93,ED3AA79D7E827083,A33C1CADFF8D2291,1276B25E7B6D0992,7384CD4CB4636B99,0000000118CE55BF,A076FEB6CD00FDBA,843F9C3D34EA176C,2C99966452B14224,6802259ACAF442FB,861E00400FB4DCB2,6B7BEEDACE6BC833,A0C2DD09967332A5,CCE241DA0C6BA318,01A9CFA27638FE75,0000000241627C07,4BC5311DA6BFE339,CD22B9AF4C329E3C,45695A0B2A842AB8,1E5AEA252841ACFF,F718865F3EDE9C7D,A87FC8C178A5F977,0A5C7EE47B1DA552,4BB6BD54DCFE48C0,C89E7EEF43379ADF,000000010BF4AF93,3FB24A8D1E7CCF1D,187C0B593AE6E64B,9BA1E46A66FCBF4F,328D2CE0064CD9A3,4A9663482AB1EA51,C5524A42B2BEBDF9,AD661F189CF7809D,531FA253D9BE1087,6583BA7FE19D73C2,000000026A50455D,925A693A77B9A2CC,5AD237724CE4EC69,812C6C6D188BB9DF,B23DE288368D1902,E41CADBD384FC93E,0A2F47DB7DA5DE9C,61DB0266E4A9642B,74E16D15DE1C38D4,B30DE3F9ED3CB628,0000000062CD58E3,BB6905AFFE2E70DB,A088518ABD1600C9,D1759F492D47818F,333143060CB26BC6,D04EB1703B86B17D,090F449DC59BA828,4FA5A28DAFEF7C62,9DAB5D8972BB091B,8E77DC142F9D2FD2,0000000072F737A8,BC1EDD7582E6C037,7D959E4DC16C3E27,1916986627F150F1,020E06B7B946C699,F308530AA5C04A77,D8F5CD0911F95C48,19898DCEBDBD23FD,DE1601434CDF7BD7,7F427309AD1EEEBB,00000001A02D5B14,BB1CA6D89B8A3D6B,BAEC824A107B61E0,6002C5F511B378E8,F9BC9AF172E84875,38CA3662A3D0079D,97EA0B75C3476B92,C32A7E692501E56B,F4A64861D6E5447B,68555D0B242829A7,00000001EBE2C309,1AEE9BBA572CF0DA,76FFCDCEEC122DA4,60AFD0E201F4E91E,A4B3729EBA9BB828,984297BC84173C09,D5EC07659B786752,1352D08555D8DD2A,03135A30A72404C5,68ED94344A3E93E8,000000002D58C2DA,243BC4D8938BF230,7B05C7DCFB2425DB,33B4E55C5802ED38,A2699A3EBC8E82BE,60980053609A7AEA,64F435A2A33D82D0,97933EA16043AC05,EF3FAE110FCDC71D,E127673F39E50D43,00000000DA11405F,0947A1AC085DC9CC,603F4803D95B6938,A5CB6B2EBF8317BE,FB20DAA66096E573,024FC20A3E04C896,5F8C16D7EAF08F20,F02B108F496F327F,42204662A36C1420,CE34FA02F81CE39E,000000010CBFDCBD,FA5F3B2F5D84322F,77A1BC48DCD0DD33,348D0E238F3C1AE2,7D5D1B015A932404,6ECCCB30185F1E9D,9842BE1F9D0EC6E0,A82BC6E1B5CFE424,254C2A195E946FCA,B2328C213D8EC4DE,00000000EFE2AE17,D599080D0796B04B,6AA0E2CC1A5A78F1,67C02259662E08B6,38D17E0768790C05,8CE02AFD4C8FF6A3,D26BF86FDB4D92DF,5F32E9077F441170,F06A7E71CAEEAF37,FC7D57ABB9D169DE,00000001BCD5317D,D821138A73E1E6EE,E1251C89CF49351F,174641189C4AFC7B,167C655B3AFAC86A,8F8F9B62A7EA524B,71EDE7E711D69A82,90C65E8A61EC99B3,183D543B10001067,202C2990F3B33992,00000000E1547311,BB59443AB862AF15,4A0668550D02719E,9ED9B57A4C7DFBFE,5198B41C24623C9B,416B21E0F97A217B,F25DF1F87FD3C70A,E458F475A1B1B76F,B0F5D90BFC8D4F7F,1E70C9C748880B80,000000015E10FCC3,FD89B6411CEF6AD2,71E7BCE6DA0DC355,34AD58287B0CF55E,B92EF0624FA61E2B,7B3FF2705E43F722,344A63BAB3A79639,E29688AD937A439E,F416F1A763B4E5EA,4BF4AB898CA4E6EC,000000023F30A963,D9B59645BA956A33,4239B8603ABCA1D4,B6D8ABF42893A029,20F8DBA0E3CAB09A,801D231BB35773EA,0E6649C49FE14DEF,0293F4EA5FE29AE0,C382F3B9574726D3,E86A72A166F3A1F8,000000016AE1F3EB,8E0C2146DFEA9A01,12B5871F96304B62,49E61697A32E91CE,F1AF3EBBA1CF87B1,FFA775B979D5AB86,44BD2A26348A8FFE,81B48AA9CBAE4E0F,299CFE5C275489FA,0B0595FB65C08EDD,00000001148AE08D,5A18B3DCAD17AE16,75985FB5F1A44226,5347C07D0BBC62B7,6F151DDD57706232,32992C3C317B921E,F6A71AD2DCFDD157,8B36DCB6E08F94C9,680E189DD7CE70A2,3BA0F1173B9A5891,000000022DC97F8C,90969EEAFC4466E9,B3D282B2995A1F4D,56CE986D7D588CBE,D9F2366DD841E7DA,7F10B0090EC66243,D2A13EFD797C1A1C,D4C53326D6733EF7,82612CCD84ABA940,A8D66C81D7C6FBCF,000000008C21D1F8,3EAEA3275A23A61E,867D89E00DA81584,050EB044AE6106AB,D8B1F58376BF1837,727241B5E7936F6E,F74C034CE3204F4E,737EDA555BF37916,44D68638AB5F3A6D,40732421FF182A40,00000000569853BC,02AAA15B8A431BEB,CAF154CC1EF01095,6EE97559147145B3,10BF9A6855455B76,A4F73B71B2287F1A,69A554A2F59B99CA,D7A7FB58E7125C77,C1A1EE7E80CAFB96,BE5C4E8EE51710F7,0000000053AC7D17,CF791587F00BF90C,7C7CA8152139EE2D,DA47E087B82A93C4,FD90CEBE0CEDEA85,78D38F998C42FFCC,08300CCDEA647D2F,D6CA949F02744EAD,9F40EDE5EB0F5B27,C6351618F4D6E6DB,000000004A688F74,DB1A7854C58EE4A2,6920D310726446BB,32673DF69A2ED8CF,79B67CE8DC39D802,AFC52820D02D2800,728DCEE0FE4A739C,EA61ADAB083667B8,FDDADC80442848B0,86B2EFFF456B1326,0000000073879D74,5CF1D59E336AEB23,2031369BDA773797,E8D91458E349001D,0A1BFEBE21B1AB3F,B02C0F9FA59855FD,7A5AE4AAF49E8220,FCF2987C013885C4,0981827AC973410E,4A0443182B522638,00000001833384DA,AA6408861AA99B66,7BB9271D0444E521,3CAA53A425596C5F,D61312C53C55A57A,42CD3676D31835C3,F2912B4372B7086A,528373FC802ACDA3,E3DD90519A090B8E,D8E3F0F469431B0D,00000000C8B3605C,3BA010BFD6003CD2,F48FD64D630CC5BF,B2C9625B80508506,54DD3BCB66EF5B6B,406C6FB1B11C5746,ADEF8BC89711B82A,CA55E3F4B77313DB,597E7823B21FA48A,1B91ADCB3D7465CC,000000016B9E4FBF,B738084222556622,1735E2473464EBC9,1A061C9DE30BBA14,AC2B275135B3BEF6,21611AD2A5F83042,9D37D4249E4F44B7,134DA21F1BFC903A,00B24982DBB02DCB,3B122647E45B9E6B,00000001875EF343,582D9E0FA0403A48,9CA56EF741F3580A,18929C71556CE533,31EA9AAF621165A8,5BA8D63CC2C9DE1C,A7DD0A36AA06B5C1,0CF0B324F042A95C,58EDF593DF02BF21,7FCC16814AF0BEBD,0000000061693871,A2DAEC6A4EE85543,A5AE4286B4C5984F,D73B8C0DE87E4A50,DBBCFF57C1C83EF3,C22872CA93BB9CB1,A17CF97A330AAD3C,1CFB14E70808355D,8E54544CFAAD05DB,0FFF6059C0AF9FA8,00000001CE15A153,1ED1BD397181F853,5CE70EB6F36480BD,FAF23E5B79FEF8A2,AE58FEF676BD1AB7,A3CB1A921AB387B6,616F799DA47D9380,8E90856DEE3096E3,CB54C4EE941A3C3D,C0294F7A0F0AC290,00000001040C15E3,0F97665398A75155,76D4F96B6FEA6304,1D56C609B43323A4,AFEB318EE3BA421A,B254D5EAB54DAB30,FAF07F23532D63FE,C94335E6AC461786,0AD6C0BE243F9ED2,A6F5502B98AB4BAB,000000019A50F7C5,6EF988932B470739,E5A9C946C1C5D1FD,37695842E98F9CB7,F668C8D2452DC7D5,DF9ACC4ADB5B1C50,42B5032A4C8EC63F,466E78E0192CEA1B,9B0DAAE21AACB9F1,A594A280B14A80D3,00000000F7E03AD5,C3E5D69D3482DA00,2EF4022B11F5572B,1B7A85611612FF18,CCD9C9BCCFC7EBD0,4B2DC71B573B68D9,9733416FD9201D5A,A3D98CC8C81180A0,0243D83D3597255E,7599026DD7BD5007,000000003DFBCB0B,B76C85A289350D34,9EB24F22F4569E05,40C82897F5E36315,3BB1F9F2CC069003,7CAF86F358AFCF7D,965378208556C1CD,89495706345D9E89,E7A6DB260267215F,AA9922AEF58311EF,00000001452F65AB,29A1D8FD5401A1E0,C4DF4A518A57CEDB,BAD793AF1FED34D1,F163FADC31EC20D2,0344F299D7A680D2,DB6B184AC20ABB57,9E7053BF6A1C7092,F09DF757CB076BE5,26A66A18A068C54C,00000000EDCAF462,32053D0DAF273419,9F86AF3060C227D8,0F80E1537E5DE95D,B051BE8EDA70A9F3,D0D13017EFDF1C1A,2E98CF89D846A325,8221C681AD8D6BDC,A0A097CC3D5AB5AC,B0DA7C2C3202B037,000000024E80AD67,3480A4559800A546,067E6B500777B13B,465938A25207D455,051FC0F280AEFC42,0C662C1E01C21FFD,F6ED1CC24FD1A34E,3579C7F5DE9D3986,64B11503D88D4FEB,F45F1B1FB64B968E,00000001B1E0590F,E18A9E846668B3DD,DB3A089CC7C35DDB,846E44FF2875270E,C44B2911DCDBFDEB,E56D10BD09C73626,C062522192EA6DBD,8C84E66E8241DA4F,D344687DED9DAC83,5F84987C829D3A21,00000000107BA350,FD97E8D1D04E0437,8F98BCB6825B762F,A56D01EB3F39BF34,E4A016745781A57D,87FA2396E132E809,26CD6A68C58578D9,E1D791098877B943,B1BAE448357DF250,C32A7AF65C745C33,00000000570A1232,91755CF2292E7D28,7ECACBC233052B11,3FFC9AE5236261E0,0E1ED6CE42416E81,11C44C8C5A959182,8C5C0C60E3696E60,9F2CFF6E8987B897,FA1C5C532DC3CF83,EE9CC195B5B30DA9,00000001AD10F79A,06FC329D8C03A4DD,D8B98EB5AEA6CECA,B6FBD8BB458B89FB,DE578CC0BCD09E8F,80AA7274BD9EA19C,9525F1FCF30A8CD4,14279B8757AFE4BF,26FEDF8F37DE33D9,AE46D1F47ECB1D60,00000001956CBACB,BB705850402A6C5B,7637E82F3F312E02,46FA023AEA2972E5,0A6E429DE5F7D6DC,3BEF410254FD3F2A,1F20F4D51B015876,24D9F6C5DE9FCC11,8CD0A95C87625659,126D33FBA8F73A36,000000003B063936,843D31C4F3C7115A,107255D44A7384F3,88984101972DF176,E0B5818F125A446E,7254B32877792337,35A393F6DFA9BC0E,4896B4B351745A3A,95530B4C72812B21,653B981ED2C37372,000000020F9B25DB,87F2E050DD8F9706,5A8A43ECB2B0CB9A,3F14F22743720373,690FF7B9D4C10E56,75E761A0217A6E97,7D0B9DEA46F3D937,A8039EF206E316DB,1B572A39900DB891,F9AE1A03F7E4C854,0000000064A11806,A22CA4FE48685ECC,8D266D92C622E622,29C0C6E63F8B4E22,6310EEF7BB220B40,AE4F08F09C68C2DA,E004149F024CC40E,59F905C2845B6E25,0330D7DEACEDCDEF,257D95DA0D59C475,00000001E1747341,FCCE2C9FCDDA96E4,934B699BA98A3628,345A79DBD30C783F,6C3F6CE843084F7F,6D4A751559009F4E,CB19004984215DEC,53FF494A6C78CEBA,F6B52E897EDD5523,1DCF010961A27AA9,00000000C79F4B2A,B08207EDE3AF37BE,3E8BA588B7640209,643FD01A87183B31,CB240E80A811D6EE,B40048860C358A51,7C9792F9DA26E8D6,D22A5D108038B684,77DCFC60728F7C6A,80CB4483630D045D,00000000FDBC4604,EEB78384D3AC7F75,C2F345B1DE0825C9,3C8D6A85A7D75553,8533582AADF940CB,5983D8589CEB4D36,2B6B3EF9F51BCF81,03126B07EAF10E9E,2D006E6BACBA183A,55B6820FB1B4CF6B,00000001DEC30769,E029E1D0FB15D493,71A7451F0917BE47,F79138FE6EF9C675,E1A2567735DF7927,71C53C37DA37DB27,3C77D1DDE378F62D,60095D66C57BD378,04622AE9302DF74E,1DF1C7975866752F,00000001D9C7B414,E6F8583DF5E1F6F1,5336150F268A6BA6,3F36A80BE8DD4E7D,9A63FC0E9B081ACC,9F97F7AE4A0021D0,327BEC4D28AC14CE,553DF3C98FEFF608,4316DDE528E1ECD4,7878518DA852D0B7,0000000173C5A338,5BB196F6807C9A61,8695A6E108FAB604,E083C090F9BDCD85,28FECF6958FB0DE0,79433FCE7DA6E6B4,FC1E5DD465DD1984,B4E2109CDFDDB7B8,15A4B24CD5FF5510,804EB43AF62DBFAF,00000000034739AA,375A9C4724AF3979,1F5DF45AA951C157,9936055EFFD9FA70,829014FFA52C5D34,382DDB68B7604466,1EDA0576D1C67CBC,1B6DE70F8F909F50,34726E560F7757DC,9530FF5D54F39F71,00000000DE5622B0,6310BE5C383A2DBF,1C2084144344C4E9,7F2D49EFCCF519D3,4432FBF96E5284B3,8DAA41DA794E6788,6704F221BBA7AD8E,7ECFD8B7A71139D4,6EFE7A3A8495BF68,BD008E6FE6D493F8,00000001C7F02684,AAA6CDA6EB18500E,A71DE144D00E1B75,87E42BB4F1709CAE,EF0523BDBF901712,5F8B8FF1E9E87327,FFAFE277386D706C,C1226789512B386F,C2EEE29F2A769E75,E05738C5E47DE75B,00000001B550FC13,9B9984B74EDEA2BC,751DD732FD345407,A3F9756D1A064067,53B26FCB2401B193,D8ADD98C197F2D82,B87A48CF8BFBF0A7,1372B6CFB936171D,76E84EB3FAD6A93D,D3B2C60E73F43210,00000001C7BA0973,623EFA90DC51E6C1,E04B7FC1348580FC,CA2E302C23AFDEEE,AFC812E7542DD447,7C2ED505139E0FB8,643B6078FA886FDC,198C99B568F3913C,A9B94C11E5F2DF89,C8342B8B60A0957C,000000011791F245,B0F6467E451671A3,7736E1CC68F3BA64,F340085863512E98,D7A09BBBC7435292,4AA4006C835D0C69,04B37EE70B6EAD72,916689B45EE80D57,9CAA60A90335E2D3,04633D5CDA9E7FC2,00000001F13E64EA,6F85601A71AC6BC9,2FD09F88A5C4A66D,453ACE8830CF560B,E82766177EA62D1E,5794E6B79D7D0A4A,AEE8E46876C49508,D0A340F53DC57A57,3A676272B0AD52A6,26C4857E58D56864,000000018A99EB5D,F94AD6A57F7A264C,C35A9A9E87A67A47,6B3953CC86BD130D,E734F6ACC6CC9A59,D41A0521ACC81600,67BFDE4F5036B0CF,372CE58F1711105A,0CCE49A7E4118AFF,DFE2DDAA4B61BC1A,00000001FC023E40,FE53BDDA6C030993,8226B0A0CEC7E197,17D0DBAC1FC42BA1,8916F24DB9D5CFCE,4A0808042541E003,018E491152FF1198,5A8C156463C4047E,A5D943C158BCD49D,4E38CDDB25CD2E28,0000000120F4D93D,4CB8D15BC856AAE6,79F4768CB41B4CFE,E3B8943122BBF137,07712616027BF28E,86D8954816DE81A1,244DD1847DD40123,0C46D61969E00E0E,10CE626000765AFA,871D5752C144FF7E,00000000ACAA229A,3116B5AFB12FB232,FE4388AE3C6EF517,FAF50ECB3479661A,B183B1C64E294B2D,F932E9FFD6CEE4AB,E445F6F1548E5B7C,D3E845FF61A1B7C6,0565BBF39975B995,1AA456DF19B8E2DE,000000007206C0E0,BD2D075A104BABEE,2AF0069A862CA760,DE82F3D7883AF35F,F85FCA5E461C3B5B,E9A193021A5A7600,BACD323B40609AB1,90B360D0CAEC62D6,982DB074B7D604B5,61897DCB975E6844,00000000E7098ECB,F893D461CDC4E2CD,6BDAC24A5117B27A,10BEF827F3B33400,9AB5E7D71AF5BC48,1CB2C261833AB153,1C62FD028373C5BF,3FD7B302453F15D7,872C38B748C0F16B,4D0F69F56CAB3EBD,000000025431548C,A0C6581534390D8F,68817F6E2EC45208,859734722F74F36A,3C83BED433A34EF2,ABAA557D63AC5166,75EA27C7BFB155EC,F1DD37D1512CC2C9,3152272E4D0EDDCE,2E85210CB3FF8107,000000022BBD840F,9B32EE3A70DD033D,3335F9AA59E4DB6A,5DFFE660FF75D60E,FB1E8C8F9BAD203D,386B1A8DDCB94874,5B52DF8E9B09DAF3,3D76A3293E932357,4CD33E8440BB04B8,7DFCB6121C10DFC9,000000025E1B4A34,FEACD057DCD1575E,725FEB23D91AFB4E,89FBA1EED66F9CAF,EAA76100E32FABAE,CE68F58C8CFF8035,32F3D84DCACD1036,CFF1429E7D43C850,F9403D39614D1F45,92C621BAD082FFA3,00000000563085B0,32DD8500D9DEF697,6E2FCC97ABD7D3F8,4C38110752565170,C962324525BC32B8,D3C29E36B5CF5785,5A34DF25BC14BF3A,0D3688B8E09B1AD8,C677AC1A49FB52F6,23390A69A405FCC2,00000001BE5A9264,A9E1DD36E1458B10,26145F370D644D57,56EDAC1AECD7F7F1,C28A6ED84708B445,BB537BC4593A3BC9,AD86C9D2652C8ED9,7A783FEBEB2E3BFE,77C1BB4A15400059,1AB6E9BA73797C0A,0000000229B8C433,B589D2C01ECC63D2,0D514C1598BE8A1B,5B0F1EBAD42A2128,318ABE52966A3AFF,5E96762C78066449,7CC7955A5B662218,0984E78619A5EF83,276BB9E53F7AF5CA,12C4B6630CBC78F1,000000000076A9CB,EF4BBFE565C8FB6A,A904B920F9EB32A3,E3AABEB88D863CA3,78BC4CC8119052AF,494EF6BA1C1A9F5D,6A7BBC1507E5B22D,FC9BD67046B89C5F,00E2C7C5CE9B0255,76781075BEED9F0E,00000001B5C8A9EF,21CBCE43A1DB1AE9,C866104115081A67,5399E743023240EC,6C0FF0BD891D17A6,4C36AB6E0F9EA97F,46A38C3371EC97B2,6060F5B323159EB2,C7C88FBC151D08DD,0531DB33481ACA01,000000005352F03F,876EB25855371451,E79195C71AEB58E0,611A8E3CD3A4D3C1,40E11CEC5F22D3AF,31F02E039F7C955A,33A6EB51ACC198D3,7AFBBD4AE858E877,8694C3B9F64E67BC,AF709D7FF9A23AD1,000000014E104660,E1C8D1212C0CD2E4,C7A08974130E2704,D6385224EFDADA1F,6B5E5B167E0E4E33,8FA3F0882F105B76,C43CFCF985D15A9B,EB233CEBC8212A4D,19B4D6DEC71F9D4C,33A10081175C118B,000000004F599F10,E7D2C32F27F4E322,3310E6224FC6BEC0,1DDAE1FB0535D3E6,AA72B8F4CBAD7E89,D2667D1E37083063,3EF3DA575BA6F82A,23C81982511391C8,9E4890E7C08D1B4C,FB9112E38412BBC1,00000001E796B6E0,1C6DEFA215DC4D59,E56CADE5961AAAB0,78197A8AFB2438B6,828BDAD98DCA6567,8B7E77B82FCE236F,9FD580106C9AECF4,F9BEBCEC4C8E1F31,230A2DA125A40213,9F4E1F8519B647AC,0000000250778EFC,AFB5421AE5E29A8E,241F3D3AA4FA079F,26D764A71215ABC5,2A71217FE8A04836,AD06C561295EAEB9,C70E68A27D55D517,784C8E3BE5CC95F3,DE3417BCCC058D10,49F67E263AA03693,00000000ECB6B2B3,8D5566E4C8A01875,67322E4103075BF7,FE6AE91B41677D2F,8B6058C63A3394AB,004486FA18014234,65675A83DD12DB18,45CD23E6DA2C6A8E,633B69EB0D6B4591,0AFA4964B9ADB92D,00000002637B30F2,CEA7C08077B1A3C0,CAFB5BE733C5AF07,64970B24C1D15BFA,DD51EB1A574CC8AD,78250FA8B759535A,57118B847C3CC05E,AB984326D4584E2A,986396B9CFC261B9,A82A75D74C38DAED,00000000FE49D549,43B85935FCBDD175,D8C02020E84E920B,FAEFE41EFA72A312,D85F3E6239F01D40,3091D761B8B7D326,B805469DADBB314D,048A8231B26806AC,9D55CBEF2FAF44A4,B91E2E86167A1118,000000008F140F98,61F70C9E8FE29760,2976F181653E01B7,B0F9BE15287C8250,82BB31DB1C5F2B9B,268089E51E929164,C94DAD938FB9B969,7C95B5424F7D8C13,286988E7BEADF705,7396FB7D3998042B,000000026429A4EA,47F8303BC887F971,28153B84C2F06F1F,4847D4EB54BC0EF1,2EB785F11B06C65A,7D04E604A5384605,CBA52D3D8AAB1B6A,A0B402166097B97C,8F70FBF6AC585425,2B367DDD0D381ABB,0000000274C8B5ED,F8614E5A7B065CD7,51937520A82AEAFC,D42A9CA0D3293E56,A71E148EA888330D,3CE941CC634BEF28,CF618257F24B3B18,B52F8BEEB6355856,9EB6ED8733C89C41,3236D4A15045AC7D,000000014F95EE23,625964F5E13FA67D,112BE6A5F866C398,2D4C2F711A95DF8F,E7A2FBCB3F29AC73,35D2267101C486F0,F6BD444D566A59B3,3C0AB7AF46D69930,2DFBCEFC0C8E8F0B,C6C0BC821103B5B2,0000000040092859,CE642131069AA96F,7AD6F00629B0281A,DA7A66415E7D2371,E9D4A95921732136,AE8357B08E0163E5,73C4194174CCD517,C71825C30127B4B0,9671020AAB91D180,9B8BA4F8832E36BC,000000006A600F0F,3C8236BF15401A3D,252532D1F39B9C23,DCCDF69A17FA3F1B,4945A1CE0CF327BA,97865FF627D44249,E788814AFE1564C8,19D95A733242DA8A,3D843EFBA0B3B4D7,87200FC610D4B910,000000017BC51026,2132C866DAC7DC8A,24DEDE83E6A214F9,2FE95804255BA619,467000F8722DE489,6C3090D396C911AF,186135E4495C0103,2D7F9FD6AF145D95,55CAAABA77092EAE,775159DD80870569,0000000040CA4775,F69C9EE68DE4B357,DA2897D9B5E15EE4,237AB92893290AD4,1B631C9A65D19962,DACF5315E1A231CF,48FFFC41E30E6779,6BA582C82E69B593,6C9F2A1394C50D18,4D18DA31099D38EB,00000000CAB07BDA,E22B5119BA1ECB4A,CA5C5F395AEFE22D,E79DFC06016F0A37,21CBC13031415E76,C058A9925727F130,5593EF8DD05ADFEC,B1110FB213CD3951,F221AB9E64E31BC6,1D31747ADE93F032,000000015DB0E295,7B0CC2C9596BDA5C,226793DB6916D199,862A6EB3A9D2A784,77FE985305C1E1E7,5A835575ACBFDDCC,487096164D8D1B4A,3790ED038BDFD649,E125FFC2EDC97301,BAC2C326ED6DCFF6,000000000239DA9C,B49CD42F7E7488FE,F8685C9AD33D6761,C1FA817F780AC7E0,9EE730F90BD2E43B,70D4C39C54A4C819,B7E8824F9001F251,3BBDF02BE86724C5,5E23E0F6DB864D13,0D23D9EB8158ADEB,0000000254D72A23,753B419D1AC0E9D5,E83E705A308EB02F,43D1D2E7E2DE2226,8E736B53A4B62871,16B56D45A3018307,86D6A6F47D36F08B,5CA8FB36247DEDD2,715D4BEEB3ECC616,F67CFB643B269CB8,0000000254C94BCF,C68747A62ED10B86,1607DEFB5A3DA98F,9794A831DED0036C,6ADB49E76D26EC68,BB8A2028C473E544,8BB949CC21CDE74F,56F96FA78E4D3434,95D4277FD03588DC,6444F51009E7C178,0000000129BD0711,57E939629879E81D,CDFCFC005E1700A7,32A62C09136A3474,EC06381FA6159543,F1316707D324AE37,2749E11C5C6A47A4,ECFAC7FC2B0F1700,16D8FC9545EFDBFB,4FFFEBA07FC5C5EA,000000005BF06DD6,3D423973612AC4BD,DF330A43061F356D,B414BFBAAF7FCFB2,68E57195C673B79D,09BFFC7351056D57,E66AF3E7770EDAE3,BFE5BF6B92F26D3E,2776AD4AB1316F14,96C03C98961B8B3A,00000000CD011358,789705A070CCA895,6EF365E931ED43A6,D04A32B82C7D5353,858495CE8A7E3058,251EE13A1600DF3D,4699CC77C52295D8,1EE445D13D54336F,DD68277153AD2406,0CA704F9F42057D4,000000025733ADF5,C1033E24077815D0,9B0CC9BCB505C9A7,7AEBD7E3D458A08C,9EBAB0305718C191,E6748657F3D2EB92,F1304E89B47DA201,0B93DF2FDEBEA957,10EA916E86FDC7B9,2F7E1A049248ABBC,0000000186A50E30,ADBF25160EC527E0,1C1A0D2A0A1075EA,0C44F576E3D41771,B37C742BC72591AC,85F910261E972F84,56B9837904A04165,207269AE98B40DBC,2B45BBF0303AD719,B83D2C3D7E0B26AE,0000000235A46B53,FA136B07518653B6,FBF9A5F5435F0E77,A2C5F3342CDDBFDE,5550EE74BE11DC24,F21E7142F916AF17,CF543E9F8126D206,D9A7FB0638853A5E,2748A406A3974B11,99B5468D295FE3DD,00000001E2780572,92684CDA47318FFD,3DF3502C13635B0E,0400BE81C3BD0F67,8F808672BF0AE017,5CA78E6C67FAB833,9387F138E1E58777,CD4B72DA5A2264EC,13FEB2FF879C82CA,CB8894345D1567C1,000000024F83B84D,05600DEA7FE673F3,46D8C73E22A803DB,1D8061D4E153E846,AFCEF9482D8B4534,8282CE2CB02929ED,92BB33C0C39B1E9A,AC3C78B8FBC27C68,90FF6D4D06A3E650,6EB852240EBBB37F,000000010AB6276F,5A0C1E78358FFD07,2682D48AF469FEAC,27C03529842FAB7C,3D1CC0DC4A8B34DD,ED9D7EC6972F970D,102F7953141CC84F,2C7950817A3F3020,49E80BD79473630D,40E3AAD42B6F0551,0000000173A2782C,F32D5FC1E448661D,208E20489039D4AA,1F9ADF42DA94D1E5,3743368C47BF6C44,1E5F8539BDFFFE28,01497D4430D0F898,C10AE8B5E4781A49,9207C400953A2A00,9BA083C8BF95827F,00000001A6F59D47,8F6F3E119649AC77,C237568BC1DD1426,2354FDA76F96E849,BC4F32C677BBD286,B0A5EA239F7D3289,58C30034FF12602D,9C2DC94C0CBFD113,58FF96434F823630,0DC0CF4D626B50E5,00000001871397B1,E801A64A6F9D10DC,D9EC933CEB8AED2E,48E50EAE41DB0DEA,EA20894880CDCB71,B78239C157491AB3,BC4472D49DFDE8AF,423DCEE6CD81D190,C8BB8818816D3A65,D68A83AE7E93661F,000000001B169426,9AC0C78808A2015D,433511432A692F85,1AADB34B058F1E72,A63462F7EA0C94FD,DD75D99203053A4E,F6AC31BDDCEFC367,00FDE6C6B5283BB6,59209F2EABA96D2F,E14291F9873D78B3,0000000087C67092,68CB478E08ADA6CE,F34BFA3F2957A359,65C993567DDA8365,857323D9E2C99660,0E96C03CF3673251,1281DE28E2055E14,AC338A12048D9E73,602E93B678666DAE,B88B37B3F1F5372D,00000000A705A26F,8948859C5095CE95,E2ECF865A15E3B52,73C54FC2A0F17379,8DDC52A69C9D98F3,2A9809DF7C8203C6,2121F0AC312446A3,AEC30911DFFA27DD,B783E7CC1F6CFFA5,8D99DBEA51B09E27,00000000310C2855,76A522DDE2374305,620C4C3715D260C3,560FEB177D70F0A2,533A184FC4C8D9AA,6072FCF2C038E5C2,4857D05ED56F04D6,7CA6D5CD80B865F5,44624C6C11A35ABB,4518A9E2C2606D97,0000000040B012BF,F3718D78527CD3BC,FC43F18557AE7886,266CE06E47740DE3,FBA3AA4D25032CB5,A4F891CFE52EDA64,290EA00CFBA34EE9,FE51A6C5F44BB2DC,982A57653D39A525,373CC1E30A137F12,000000020F35318F,0163697578C47D4D,250FC9A54FA0FF5F,721DF737F9028046,3C1EC63B6B9A41DA,CDF6997DA6FD530B,7BC00EC7A0C8182C,E99C89DBA8245A19,847872DCEC3BF9D0,8B3B16611948F689,000000026621B3E6,9ADDD5D02812FD67,574EF8344E1B1271,ED0E0EFDD62396DC,BA0E600CF9ED9A37,2E0237BC06B24F17,3A06D00AB40A266F,2DA3C71B9AE5947E,0A4A524EBB34DFD4,D9E2F015F98BA521,000000003ED2ED3D,1CF93DA9C434F721,7ACFCC504D8A7420,EAA08B1CCF719C48,B2C5814DF47F34CA,E60E22DBC3690A83,4F2EEADBBC420B39,1EA1B2A28A2D0682,7217A78BC88C1D49,5FEC67FEF9CFB74A,00000000A2AEAF60,FAC2FA4B30B9133A,0699825E8B922916,6C0037E666369BC8,79D2291277107A34,7F58CAFD837670EF,ECF185D9BEE541C0,48E544AFE8DDC5E7,CF6FBB2DF1CAE696,D7827DC70036665C,00000001554A85C6,60C6F36CB3446100,8D3A76EB625AFCC2,65884E7D63AC424C,FB33B14EB2DA68D1,66B8B383061534CA,82AD4688223139A3,DC4B355F78000BBB,9AE3D477AEF98C60,EC395AE85C67AA6B,00000001BCDDCDA2,9C2CFD97E2C9D8CF,26F98DB58C519CC8,A6B6E67D9350C547,3CEA01C3045790AE,A06C2287809B598B,BBEB559FBB9959F6,71AC24749A77A51C,56E2C573AC445F89,5A5FF9E9B1E1D04E,00000001C5A82E2E,7AF33A8CC9903CC9,5F5CC79DCD815714,010B31313818A89D,CC39F4920A2041BB,A87C9380C0488EB0,E312373060F7BFAD,93B3E9140692D0D3,6DF6E41D3676D7EA,0E18B393F2DC3C17,0000000135D07EDA,C3489E72A4BB28C4,DB6223EB5160F025,E31FA560E94597DF,901A2E33223E7D51,4ED56A97B0E2CDC3,87F18550D040E671,18E812D7BA24D28B,90B17414E290EB04,8332E86659442813,000000013EB8EF9C,58A3D94F0FDAD0D7,557F75A18841E87F,BF856C7256317C24,575739CA9E583B22,AC4C3F0F51DFF47D,03A133B9B435AC7F,5BBFA92556D4FD1C,D3D2A781E2C343D2,02899D02942E93A7,000000015FA5804C,EDA281BCB33DC029,8CD1810D0DBB0A62,EF7BA8E391602C0E,AB82A87C73EF6BAA,764C0493645D14AE,3BE1FCBC4DA0003D,55EA2EEA24695FE3,EAD4FF86C7FAEA0C,7D78BCDF71062B56,00000000632F10A6,8746C12264645A31,F21FA9008FF66BB1,F506087DCF7FBC96,1C76E7D9702D6009,C8FC10A2875E53CF,64C0A0D277D52092,8B7E3719C89FC887,04320FE251D8B75B,F798BD3FFE8A6352,00000001ABA62711,8E4B0B500DCD8314,BE1E3F6357DA4F62,2839E264318ECC2A,4D5A1F70CC63EC4E,3247726F49FA74DB,5FB17DFF58470B7A,BA9021606CCE922B,E765122689D9E631,4AB9748C1C8248EE,000000020D72DC7E,11456980F9AFD605,9F194FF831DB15F7,934EA654E7143AC4,D331332F9000FCFA,22625D388E5859EB,15AB103E28845B57,60759C8C0752765E,F3B410C14B3115BE,560F20D696B685BD,000000011B2C7484,FDE3E6F9FF225F58,D5633A190719831A,24FC9A99329930B2,71EC0C28E4E85BDB,9C9D9A09CE38E04E,E3858FA8AE544DAF,403FD38AF5C1191A,D929458EE5F60E6B,3453F36490B93717,000000020BBE96AA,1BD4775321D582A5,2CC683201429F3E4,ED27F1152C24AE76,4F9A548DB857D5CD,D2F9E07C548A05A7,C9433B9B8CB89AF0,A664C5CED532EB6E,8EA829C61848B60A,BC52EF0634B2D04D,00000002367C6CD1,D6C4CCD94A639D1B,472AC1CF60121E87,C7F68869F598BB57,836A2E4BEF284DDF,EB0AAB0A6E7E4A37,76AF1C759F29274C,70F8B460A1D07746,A74A1C39CDDECCB7,30DC4D53D416809B,00000001A7947154,1DBA12A3A91D279E,39963B8636D14886,42948C8500BFC9C9,196850853B8F034A,AA813929D426237C,A2F16595C778E05E,A43C451EC8FB61F2,3FC3ED70EC9430EF,DFCD99FBA6813EBA,00000001C9DF3279,304BE51FD78B4447,ABDB9808129806D3,F6C29CF28E37DC21,1C4413AA05F42F97,14C9239821E83E75,210D20F3A0E1CED6,46FF53D135D0460B,9F6D3B81CEC943C5,6994C8F42D173B35,00000000A085EBB8,56D757E26792268C,EF59262E665B10DA,A20A735D1A19585D,DEBC6450A659DB3F,E3A81B48A29F3A6A,AABFC5E046752360,32E89C779A1ADFF6,86A23C002EFDB8ED,7C99C944C1E32720,000000007A6B61BF,E9C3D633DD66B12C,D4EED3E750EFD0F5,A233A6B6B02E9DAF,D7B5E03AC51773D9,A9CB8B13ADEFFE78,C33AE320C0E1F223,158AF8F0EC6E21CC,505A0297646AE077,D7F3972973E5B627,0000000155D8B1F6,FA2044A4170B140D,36FE8A03A192472B,59FDC7903AFEB815,6D2CD0BCEB45B5C3,AAF15964853B883F,834533A6A4BE1042,634538C06FE0086A,C1E85BE032577FB4,DD4903D6E320F75C,00000000F44E410E,D4D3645996A34EAD,92FB7D7055C8899A,39E20772E85266E2,631CA67378831E1B,ECF4CF6973034252,BE50F7C2DBDC9761,5494FCA4DB0298FE,661A49A4BB8CBB9C,0655BAD5C57CF6A1,0000000253067B6A,C244274FC8CA82DB,B87D3C9BBBE0C4CC,BC388D4535140817,519FBB4958A37442,28D66145B195A1E0,E8223A8B805E994E,32DC21805D62289F,35A0EA48AEA27D8A,FBACC22CE7A5533E,00000000B4487503,F09CC1BDC809713A,71F727B94C826543,F39C28942E286754,1AF9F62A6FD6C16F,8BDC76A04AEC4F5A,AAD5EC3B0AD58341,D189815F73DE0179,2505135F962BE90A,D780EFC37A90D42F,00000002142E6FB3,B989AEA0C7AF707C,09B77056B3DD037C,7A78E303419B52AF,C5616F8B9D180998,EA7110266364A961,1B04A986B494B48C,103CC891EBFEE2D9,89B11C46158E01A1,87B7621B3FFBCEF4,00000000A57B6955,B280BE50D89AFE1A,AADDF10937F7DEA4,DC17A6486EBC7C54,8B804F2D7BA419A6,C2E819A06467B8B8,84E4278BAEC29478,A41DA54B69A44963,9E45848BD1017CAB,E2E11923C3054E59,0000000230653D24,8946837AEC6AA5E3,981E99296611320D,13392AF4C9FED421,C0DD4EF3919060ED,EADC40D0232BEA8D,75E6CC50126E1E95,21F4614873218EA3,DBB143FAD8B9FC3D,D5FDD7FFE16A4394,00000001479F6917,6A02DA5B8B597E5E,366A5BA4CC40E512,638C5A60F88B6166,E5C785356BECD618,480CA685FEB36691,D87DA403E4EF9FEE,1EC4D0CB3A600ED6,B49E45E9CF09FC92,9217B09F77DD314B,00000001B18EF00B,D1E1FFD798FCE549,DBEB085BFB97BC17,1E06CD532700D3EF,36127EAF9A911D58,E349F5F423339D10,FFBFA3BFC934D6EB,B9216DCAB7B06E51,86FD7406D770129E,24AD5C9098A8AC2E,00000002680F08AE,81E829697EC6E8E6,52195D8DAED0540E,FEF1CFCEA0230BC6,E4F69881936D2CE5,38D5B1E2A00FF189,5720506E181E81C9,83FABEBE03408C79,52DE91D14D67854E,7F2069E5EFB66B08,0000000119731493,905199FEBDB20B19,2168AD9685C04812,C511016C440BD4E0,269BC2588C00AD64,4FC0D5FEB1AE49CF,500C7A6EAF2311ED,FAAD1C1CD7EFB252,D6C3235031E0EB92,3FED85CE61E951C1,000000012CE111C6,B759DE69908B30E8,25367204BC1034CE,286B1689016378A7,43CEB12EEA477F0F,9344FC17FD68F022,D99ED0F634DD7B6A,C894A91B73BCDF0A,35B636BF22B09232,3C0916E3E23280C1,000000027986F4AE,2DBABCC743B41A59,97E8E90BE7BAFC8D,C63EE923E305AAEE,57C01475C2B4C640,06C15D23B7044CF3,35C98ACAF55FFB20,5AD64E5CC1C8E9DD,0642E7F4E80865E2,1A18E72954312532,000000014A690703,9DC446207F045D63,B1E0F47065395264,AD17F66C523C6C86,A87EEB2162E33FDE,52D8D5F1B8649FD0,9E13FC3D30BAB4DF,862BBFD79086BBF1,1AA48A554A16F650,B6F18FB7A268B60A,000000014A262883,FF32107A5B0D2FA2,A268DBA6CEA2FCEE,4C28CD64131F2D28,7170626D36CC74D1,03824D7904B2D936,A579F6EB7881AC6F,9ACA16723C59BBF2,4861AAFF1065CF74,22C57C9801B2B4D6,000000014A91AE74,8C9D7F16F6E7522E,09AF229D3C1E6BE8,AC390748AF5D14E9,D87F95A716D7F725,A68FF2B232C774C6,60536D49AD0D7EC7,17A016DE9AC92F02,D3AC76F31E33864E,D1418AC8B17BB89E,000000002E7F3905,6021102BE37E25F5,2DB5A8853EF07536,9BFB2CDADC40A195,B8FC871DBCD51271,C4C1AEEB9F0A0E27,EF8C46D838B00310,EF7E6241E11307AE,9ADACE6CDB75DEE1,90B42981381CC317,000000011F858D3A,465975AC3A2122E0,20BF11364669FE68,52C86B0A11A241A1,5D6B5E7E1D49B043,297CC6E9C13EDA2F,D181B275C5CC3C1D,5E0F537F36AA4AF4,293BBB927FB9817E,B8D7878CE2BD6D0E,00000001A8A2F298,2939C544F626F750,EA9A7AAF0056AA77,B16586EAE63C3FE8,E8CD00DD85236CDE,A15544522C0247F3,5C6D9438C989A390,22F6B3C2EADFF77D,447CD59ABE3AFE66,2F6490A5210625C5,00000000C1113E0A,178B2B5A5BD32C48,86183328361F311D,4DC3FD2F51FB5C1C,EC27E95E7842E931,0DDDCD063C39E406,ACC6395B7258FE19,033275FDC6EAB4AF,BC1CF13953861EB8,CBA3085E46126737,00000001C2A9C1CB,7614147A3A8DC5D6,0D3796C207D3CAE8,9B0004EBF37D99FD,6F2E4E57FFE28A4D,53AF26BDBA6159C0,8878919F01CC2871,18A1BCBCBE65CDEC,807A1E36A18E0A63,80E1A9E96DFC1A8B,00000000866ECB6D,550162E2478D54FF,1C526566D3407D94,A897DDB4F1200A07,A1E957C4A65E5649,12328011CCE82AD3,DEDE6C3237101BF8,6E908355C5291A68,122A50FD21DED47F,80FF03CC066D304B,000000010405AFAC,019C518E44D6B3DA,6D6EF7941C25DDC0,D2E8B7BBF1ABE2EC,56D0C31B3E98E38F,925A77B79F6862CE,47C5E7AF65C95DE9,299926579B9179C8,1DA2CA480C0CFB06,1A1DA0BB9AA1EA17,00000000369A12BE,36F4647C62B78935,E85455EF86DDD367,B3A1C1708D80474E,0B830AF703BC34CC,F41D38081F0390F1,05C2893D39679CCF,B98EED252494BA05,344E8E914CB7A4FA,01E8350EC29BB84A,000000000D09B256,E79A9ADD630AB681,58441E8CA1BA6AAA,FC107AFC9BFFF728,8E90919E4DA8514B,7DDAC5BA0B7679D1,A13F18FBF996B3E7,0AFBAD8279CFF391,25A44CAD95598A70,1DC5A2FE54482986,0000000171037A7B,F89507E32F987813,1E02D8E4688AF697,9CFA2CD8644DDF6D,0356BBEE1191CCC3,140F8D8A88E52F8C,0C433E844070A2F4,9B75BF251CC38EF9,22D33A57DD9FC1D5,2065A7A8EF0D3F68,00000000A080311D,A10B60E73BFCE207,74C8E87E3C194A8C,70BEB3B7199D3239,CA52F3701C978C5D,C38B5964B95EA9C8,10EC69A1ABFE77B8,BDD4A068D7DB9966,5E7D41183EF36A48,3D601617FF6160C4,0000000276CA0BE6,13FAA10FCCF30DCD,62E541B8B284E868,B0BCE0EBFDEEAC12,B38E25B55648B45D,D23721D4C9910E42,4428E163446BDA25,371F586B86858652,143A2BE8A140FC5A,F221E7FEC1E7AAD4,00000000137F008F,03A1AF36B8BFDC3F,B3787DEB707F49E7,224E355C8045A5F9,41817CBEB0C93922,626C528E85F44780,AD53D50DE7DD9FE5,F8E45D77C6FD5107,9AD0D25D899EB6BC,0A46C89E77C8A67E,0000000061C6834A,8E448C4C95B6694F,F2BD9922BB61C2CA,3C8CE288B6C4A729,C64F323019B00D21,C5C590D8C1A755B8,1B8C14BB3B2C5111,ED8879AD27C39A9D,DA74A584140E831C,E62138025A047BC2,000000022CE2E7F2,C203DE97BF258AD8,AA7B2C19F8E7E227,738380DAEF9E9855,9FA936029B3B6A51,36316E865D431B5E,EF1BDD3AB75DF241,B2FD740021BD8B0E,76BF7FCC3F0BCB94,6CC2BB4907F0B6F8,00000000800811E6,DC189FA89B3E7172,FC170330CCA4A5F8,BE64663532D0C52E,2A17E22A4718311F,61F160FEEF5A5541,D90F6E185E6C2351,7F273D99AC05A5D8,F49BFC45F71029E5,58905049767953D6,000000019641A1B5,73528A4E59623614,CB8A273E1E5F45A7,FC29F5AA25B30260,F500F468E2A6F17E,F95DEAD57CBE5A15,C9E59BFFA6F1EDA7,FBAF6DC138022183,E95861F9A589BADD,AC2532CE3DBFBB0B,00000002337D7929,B0B8943305871D36,C5BB445A253B745B,91E42827E6BD21F2,8E4E4D10580A2FFA,9499A950BC843473,70B8C8C0C3972B24,DA896A9026B7818B,20646461C9E6A3F6,A5D45FD902CE2D21,0000000175FE3B98,BB3B88F9C9EE8659,5E769501DFE1D50A,C122ED4D24E0E089,B0890F68F4C97A00,1F7AAA05D29F2654,43F46FDED496D902,A156626FC859013A,B7CD033B98E2DE42,5DB45DF44CEA14B8,000000016D9767E6,7C6E3418A60F39A7,61CFBCA8D49F7982,53380078DE1164D6,D98C2AA823772009,7972340BEA9A4835,8FCCB0739F3119AD,A6EE03B3D6213A00,2EE1E89D625C28C6,1B02BCBFB0F304CF,00000000CF45C51F,AA217F3A778C0CFA,EF8F7B8CFD965D8E,F8409D5145EA5131,8076F609AC272EEA,7CADB238F84A0AC6,3946DDFB8C703670,CC8A10107F3501DD,F2EF5493B833C378,0462439DBC401153,000000021F386F7A,861ADC55C90A790C,BC6C9C64B3F0FFCF,EEB659C3200378A0,6189933C94E2E325,8C8132311367D594,6797AD9DF42F65F2,51B80DDB3101D25E,86FE0CCC07DDF6D7,6B904BE6263B1F22,0000000221802A58,BA069243C77722E0,0E8951AC2AED3AAB,044DB5D78805812E,FBBE43F7AE4D6572,FC860D83F47B0B5B,D3731828DDF31EB1,46C8C2E83DBA210A,B7BE9A3F16F5F943,BFF34F567C21D562,00000000665EBBE6,8889BAB1FF16697D,8992EFF9DBF9F43E,8491C7CFC819328B,D42866ED1C2EED8B,2C062DD05048AC8E,2D5C222F9AA9C35B,0A1F0915FC09041C,68C65E1994DFCD57,278E100F7C5C5FC2,0000000141C93D0C,F91D575BD467276F,BBC67AB2CDB5E227,AFE7FAB33F833A71,304C8D3CC4F9A02D,F89F5B91BB97B677,301DAF8F7F01E838,93263C003DFE01BB,0736A2003FE094DD,09FB7FA34D8E203A,000000017B13B852,08373BBFC10B9E7C,E70EA0E1489FD5E5,1E96EFB5189239F5,33F7201C5FD7DE80,31B61F8CD1E4BF14,A1DA31D0BAEFB64D,618D9BE752654CC3,9D614F349591A858,10A67B1AADB9165E,000000025452D06B,297D4BEBF5938666,61FCDBC98565AF14,D366009A193613A1,0A60515E54682A7D,EF128ED88FACFA8E,DB2AE3C7B3F5D5A5,11C572821780B198,640FE3251E3660B3,8E46793A6978E2E3,00000000D84AE771,ABC4A15A865DED32,4D7E5155A583D167,69F9D093FC0AE280,ADA6D4B4476E9930,A07A7290996B7324,1EE44182670BEEB6,067B96202D1A9478,EC4E2579BA22CDA0,30AC5FC39610E8D1,000000020EEC3544,6D4C353631A2617E,487FEFBCD93CE400,B7651255B8DE57CD,F1E6D66B74FE238C,6EFF72E6CD5B7D9A,AA1E5E58193ABD58,840B1EF2701CD850,D3AA51ADEB908D0E,974E244B898377DD,00000000019A126F,C4F2BC531A3704CB,AA2F7A14001141D4,6BD94F8BBE3C72D6,F79434E98BF22A5B,2574024BCC46A6C0,841B5FBC64BFBE91,56AA57351A5BDBDE,1A8C94D7622CCEC3,6355A9D672590DCE,00000000352ECA02,0A8BAEB99E4D1738,E948345BBADF655E,4AD359B5BD1054CF,B4E56029E3028067,B2D67968CC6773E0,F83849D92DAA76AF,BE589FF27DCE14D8,92AA27C8ADD52BC6,137442D73643FA0D,000000009DC38E9F,2B7311AD7F208F65,35CFF1035706AF3A,51137E16FFA33BEA,120D8DB4ED3262F8,EAA0732439D4F858,6EC52E1E1F8B0382,87CA453B192D7D7D,A04F93542E8C7539,339ED2C0CADB8B37,00000001B5DFF4BE,24E0EADCF15C88F5,BFDA3201FBC4689D,BF6015CB73743329,93E14F6C5B40C417,20AB6B0CEDCEF29F,31CDDB0CB8B868C3,B234A995F436834D,CE722AA49246B846,349E39DD7A403304,00000000A25CBACF,9F240C8C18CFFFEE,5D8AB7F602FC49FC,E6167814B7BAAF19,2D3633D85B5244C4,A97B99D0024D0663,844F0FD24A723B3B,5E50CC27CC3CC36A,2AC02D81D0E02B18,2C68AE193BB3D6D8,00000001BD286F9E,2834F3F9D57E1DB1,33A3E38AB76DA7A9,18EEBC356C04FC0B,5E85307DCC97C527,28CFE7F2F534EE1D,CEF9DAA47EFB4321,9E3C13ED3BF92C81,4794CDFE83416AB6,C604E1D2BB36FED0,000000017FFB83F7,FED7BD5ECAC19B16,616ABAFFC519957A,56C34911C85ECC19,A13903418DFB2817,DFBAF4C9B903B8DF,0ABA3B43840615F2,9F5D05BEE4F2B7B5,96BBC383AFDAA6AC,FD3D259C8EA72F2D,00000000C0776003,3CBB738217724E55,FF986098ADD18D97,0D23B7145FBF97C6,A4DB064703250273,8F0504BE65D297EF,424288F3611B6EA1,3CC962D0997B0B1D,B98F20BE31A44326,6CCB231552ECDCB2,000000020AFED5F8,1812024121A2E371,A940A1288C9CFA0D,36AB50BEFB669B15,D40F88B372840BB7,B2C0D1FA76E035CF,576F208B77ACC3D6,C46CB4EB4CC6A827,32D92CA4F3817C6D,7EC8B8756C4DBA80,000000027ACAE7A4,86751E54F3E44F4E,DAA16192906287BE,AE17B57F5A3E0765,9E6C76BB9484DD7E,CB2050BF77D342E2,B71056F96B9B65EC,89CDE6982BF0DCA0,8243E7EA207C0FEE,BF5B216CCD27D1E3,000000021C2A9481,CAC1E36E018A4CEE,56ECB8A8D0BEFA0A,7C73249533546D4B,61286034DFA08BEF,CE47EE5B90D547F9,6D8228DE48D720A3,9E6940C3458C3ECA,9DC13701798019D1,59BABDBDFC3EF640,00000002211355A5,4B0A1A948ADD1CEA,F990F1FB80A765A0,5084B507B10030F4,C72ACDA084339004,58114A0B74FF645C,9B061F0A02D627D0,BEB6B755255A72FF,972A6D7B205EF659,00078BEC33C20214,00000000C305EE8A,DEB9FB32A4C4596C,64315C5F4A66B72D,385D8ED01B917C78,1333F8B28BC5FFF8,0DC1B19AAFB76ABF,41FD976EB96C9068,9EE7C3CE9801AC2E,9B91049E2FA69050,BD8390775D4074B0,0000000244D8E2B9,44600530AD1E6A98,6CB1932739A0303A,FDE9AF1DAE7557FD,338994C87F22BCDD,4C26CC328532B4A7,2A41CEAF23E6D7D0,490360C382D7685E,DF977496BD15C766,0A6B89FF6CC018C0,0000000035543FAD,31E3DBB3A4F1B125,C1971AEDC82A46B2,0F1E58557353EDDB,6E1C32A0F476E8BA,8F93A64C9C18CCA2,C274F8CC48BE9A78,92B4D8615133812A,9A2928A22DEA4936,C5DE375ABF8E2941,0000000051260AE1,6C12CA8A053DDCCF,64D05314D36B21CA,F72D6DBAA9BEB22F,5DBE705BCE494DB1,8B5D84122943292A,15ADF352F2E1E1F4,983777516FF612B7,8F86B9A1AE4620E1,C1A99DDE69FEA5CF,00000000DC5E5CED,A1DD8BE698B37706,20644E5D5A490DA1,6BC2298B6FCEAAD9,DBFF3C511618FC8B,3B4D7CAFE451806E,DF265B29F763218C,377D88468A359E4B,9AEFE12D9CFE6642,C3ADECC148394514,0000000094610766,75AAAB231F6F9C17,B798D187A16B6B5D,FC4EF12572C1ED31,4D2D399BA61DF07D,8AE34B436808F59D,A79DF61027928780,FC0B005073149326,CFC06F92BD704A81,622421467F37A93A,0000000211853386,A24D00BEBA55A8CB,D1A559BD7CDE3399,7F10BD806EE61C27,4739E83309D32DFC,7A81435A82D0517A,D9580414ECBC2AB3,0018A44F63B93B36,FD8A5AA8A861D827,FD9E0BA9BD427D64,00000000C0939D03,A98DDCE720623C1D,7B6184344F171ACF,EDAD0BAFC0B036D4,D6DAB58D947FFF86,4F275764F1EAD61B,F20BDDDEB9264C5D,5862F60DC13562F2,032A3E8207B6D572,B80F032695AD4A17,000000019A8F86C1,2CFA88ACCE7C9C54,2C6A17747D56F131,EB3E2B98E7B5B3B2,14C8D1B822C7A52C,1D25E9770FDA4EC2,3B0D583422DDA317,FEE30D00469C38D6,5B00437CDAD534A0,47B5E07D74F9DBCD,00000001B560A42D,82025171AE942FF1,3C6A38C80D3166C1,F367B2E8E91FFFC6,46B05ED4D08C62EA,B279B45317DE5AED,02A380D03BDE2A41,990102F86BED078F,D345359A7EC91EDD,5B34DAAE871D99C8,0000000221A42936,C2F12175ACD1EB23,14CAE14181375A76,2935C5FB21CD1B2C,1028581C682757D7,FFDB988AF04D954F,BB7E94D14370680B,0E29E04B413D0CF2,6B662E7FE08EF942,6CF152BDC546D929,00000000DDB9521C,6D6D0553DF4A2CE6,C3EF72DAF694B5B8,299719C6821D3C58,8F26170C95948859,604AA38A8894F3C2,183DBB2DFD796718,D9AE34862BCBFE36,EDCAA0BE113E074C,0039A22F0A4983C6,0000000079B83B51,083A0056207E073F,6E52BFAECE5EF730,1D5D02DF19EBEA2D,8B9DF4FF0816B1A8,B09C0A25DFB41C77,4A369275A6DEC6E2,31DAFFC4AC4AD5CA,BE016FE2629DF61B,97ACCA129033936C,000000000AEEB2F4,03944CF282262897,6D7640D448B37A5C,EC76744484F37F3B,0939BD8DC6413FE4,66E9537C3AFA1F1C,11D761F1B66A81D9,4898DF35FFB0A17E,0AB00096730A461E,95FDA1107EB8BE65,000000019C0848D5,4B1F211C1DC1CA89,AAF6A18964F65FAE,88F3C1D75E074983,66BA81EF40C0B189,E06C403A455DBE65,062C3CA0EB05090D,F3DCE0E4273C49FE,E2FBBE3042C35F83,BCCB9C460BFA85FD,000000018FB00B87,A9BDA55F20CE5049,25CD27E0313CA47D,6B05105579A61DBC,243F2887C2D23A04,F8761A3B43563536,0B38F16A1365BA94,3F83DF2DDB404E4F,F51D25D948441FE5,0D33945EFE963E7F,000000026CB5F9A0,B1F2894BCA63D975,A2EA14E28D03477C,C36B90712943A098,582DCDCAADEAF5B0,FDBE2740DD2E134F,86CBB056A552FC87,276597701BFD576C,C067921172BE8BD9,D275989D5DD98A2C,000000016BE23A39,4B8280B87B658541,94FAC2B65ED46F5D,811633E26DD8893D,BF9CAC66928506E3,D60E9AFEB401C2C2,68FF90A83474BCA2,9068D13FE054726F,65958CA25766CAF4,B5B77AC757FC96A7,00000001C0B52B16,020B90285B56D3F4,388835872411B423,06251407E1E6A895,ED034943D85921B0,70F6A47CF7B3F6B6,B89239176A1A8FB5,1B60C314CDE0CA58,F6A23ECC17F28CA8,8780411B5CBB86CD,000000020831255D,F15255D2A2710B79,A602CC3B0CB3DFB9,0D33D635305DCF16,AF268527F27C8241,393DCD8D77E5AFD1,6206CDAC807D9A18,62E9997570939F3B,09C0D35EFBA39E95,32DCDEDE3D069D62,00000002234BEBFC,EC1DB026C745225F,40B09831F6E3DC3E,74C454FC70BD7DDD,1FA490FA060E4A69,F17D6A746DA91279,2323D6A02D85A096,C5F2CDFAA2DE61B6,00B9532B985D3488,86D7644B695245E3,000000025D327DBB,C191CB6751C0BF93,A54BB13190CEA781,71B71B34E1B020AE,DF7E00CF030D3DD4,2C5C677799E333ED,AC9532B52C53C614,F1EF9DB14CD2E81D,FF9A25A296F3293F,C05A7D9A6249EC99,00000001EBE2053A,846719383C31D73C,7196F094FF248067,1D26800CCF20892E,177D368F6AF5F78C,7F9A4D09F28D4307,6380DBC701A8BC84,A83556D5CD24C275,CAE0AA1EB385B06E,86B67D669FC06E6C,00000002712AB940,64BBFD78E07B48BD,B035535033CCB117,CD151303F1E99BDD,56F8F74478353B01,B0452BD9D9E9C909,5326DCA5F45FB3EB,481D0ADD40DD29A1,0163D47FDF7C75BA,8724E942CD8C3C72,0000000007E0A2A2,91E68A17E43C686D,B5FB3CFBAC32D259,591687920FFC489C,3AF158DB7817373E,2AF3C16217FE33C9,8E49529D844F7521,F1CB51F6A09A8DAD,19D5A9AF8E18A537,23D639D9FD0FD0DB,00000000E16DAD5A,6182209779E434C8,E8592C93BA0D5C73,D67EFA62BF5E5BC9,C121481D58E8A94D,939FF1E9A25D9CF0,218588B8A54E7131,D850659BBB354D29,7F618BB7B0AFE1DB,65F2656BD37EFEF0,00000000AF3066C6,83656D88410D0959,A1C6F876FD69BA50,5C0181138228BFC9,F0DDA78791943851,14EF8018717736DD,FB9F7226D3B589ED,E6A3BD66FB88EF53,2A83F2946EB6E082,5C2CF23889D3BA92,000000003D901988,8D7DB2190D51BE47,7079D33BBB974BA1,8F59C140697A407E,A2746835CC0A6412,314D35DEA0468D14,410A319EDBFE132C,F396C5019ADB18A2,2863226519AD73DD,D12959102C4CA84E,000000018D81CA8C,D87936DAFA750DEB,F8064C8F130D9497,EBE810D7330A1762,E2C7CEEFF5A11001,1A9AAA5CD1BCC5EF,52BB3A4797DC1561,7F31867A4AECD632,3A6AAA8A3F17DF60,184F5D63EC518758,0000000026028C5E,31C7E9F187DCA9A4,18F3D17A8A90FAB3,38C306E163048CA9,1730F9B9D431B1A6,01982E9D66BA45B0,6409B8C0D420A504,263E57A51A1E4AB1,F25682BB000B0CBB,9B08C7170F3B21B1,000000006D9FC099,6A37B210C6878601,32C9863DEA367A48,E7881689BA4AAEE1,4578D14676A6F47C,84B8C6BC3A663E06,B7E0D21A0FD0B243,2775076CAD8AEDBE,C7E5EEA17AEB439F,E38F35FDE1E0A4E3,00000001E4EB1FC2,E9C61B773502868E,DAF4160404F41B24,CF11FEE1218904FA,76F79AE7BD28064C,B550CA9C6249DC18,FC7825DF581CD215,3CFBB020635B38D8,F25CF82B6230A64A,B77016227141D8F2,000000006FCA36BF,A2BF7D68133CABA0,DCBB97314DA1E594,C765588466F11C78,61F6907E6661008C,9169BD18091196BE,EC97B2E253183B27,070189354C3D90D5,24567B2F92016C10,88368D69A69231FB,00000001881B561E,E1194DC8D4FFC2F3,DE371FA2905C4BD5,1D6C4C1B7F1F4CB7,BD97C1E00CDFA1BB,056176A73D074478,2E1ED7148B683453,BDED1E1E08F52AEC,0ED2DE7709CF1DFE,02D773AB4574AB87,00000000662E8F92,F59BB7665C0FB503,B391C7FF186EDD88,CBB4B6EB92159470,EBD1A6CD0661719F,3351BA8A56DB8A8D,8057A2FB1F1C095A,9EAF98204003F921,7471B3F61019984B,4188E43C1D09B2D5,0000000197AEDEB5,1D8A4E62EB5C07C8,B65EF286EFFF9148,F8D00CB8872513E1,C358069ED73D22F0,89E81FD4E5239470,E8A29499B13A9D00,2B1BF17B1DC3086F,4C5DF9E3E658B54D,DFCBAA7297AD95C2,0000000271640DA5,8E3E6123A316E8CF,2DA89570C7F54295,B44CB29F7EB4BD03,919DF9DB4FD78272,026F4E0C649A5273,B8BF32067D86CBD5,5B8D1C4323B3D2FA,11F26581E451D3EB,8688C79B37359A41,000000017AE14FAA,250E24A33906E561,77175B9DE542A0F0,626B62F08BB7D611,5F6D56161474C62B,B8ED15D5BE7296E8,49A253D1F594D047,E7D6E8E527286999,B082C6F4C80B81BE,D613B57D316670FE,000000018D712577,7F46CB63F349D216,A0EDF8261E1E705D,8C9B18A043051B21,C6F54B9A8C7AC921,F7F77CC7C921B000,3D7F16FF9896D39F,B21684C95356418E,8C0C9DBE96FB42FE,95DF2A8F44C94850,0000000275645AE0,41AE36DCD9D3CCC3,7AE40804F70FB980,064C56BD18F6DA81,7DEC51434572B95D,A37323F5C343301A,1BDD5CC3A4CFB87C,4C69A25148B94BDA,C30EE2242399B80E,545933AE43D27FAE,00000000FCC3888D,561B23EFA487C991,DFBC098B8DB289B1,FCA8016082BDE386,DC94A2AFDB74C7F1,701D288F77D4CB8A,A5B6528A16DC2AB1,48E5B68B14BF75A2,75443FC7C136267F,FA86F91ED432B621,00000000DCC99E45,78A7E88A184BCE68,ADE4A28084743364,185176958C36C166,B9027C0B115B864A,39048535CF531F98,7263E2B59215DFC5,E0D1BD8358424C05,16931CB99579ACAD,D0F2F05BF9548BE6,000000006F6E0BAE,2152CBA2A7913764,D923640EC0435A94,8AA4C78910A806A8,19687FBC0E21FE44,689D5DA94BF202C3,EC29AA5D64550B8A,EB67C2B3C533E38F,1A745C02553E1544,EA389AF021AFC8CD,0000000116AD52C1,4B96ED86871620E2,85084F36F63CED6E,71F9E4CD02FB5572,CCF7DF92283F9F71,ED4F8D2C260DF98D,976BD10EEDF87053,A1E3FE3CA035DAF0,FD8AFC3FD2AA4DC8,980218D8B5C28F03,00000001686CF5E2,BE904394AD220C48,141B9E9903AF2A20,15413B5B6314B361,891132E852B43546,5AF6FA46AA043539,4BE08269F7F6925B,95EC58EBB282EBAC,6E8931B5D6BD8DFD,E218904F59FA8659,000000007D3D76A6,4E4C7E8D5CB6664F,238DED3CF7774B01,428A87B7DCF8E5FF,008AF0DF8B9A3EB2,CCB16FACDB2F2AB4,4EAB801C0CE0AFB2,77688F8BACA3BA81,69A25E91255A4F57,355D32E5205130DF,000000010F49A4E9,159E032AC4117522,2D5DBE1C31B58EC0,AA33636651674DEC,1BCC7D97B4F59C85,74DABBB735BD7C18,AE5D568C135D51D6,FAC8EFF6AC280A0B,789A92B6FAE1AB4C,AEAAD127C10AAC39,00000002504F853F,DB5FFF6C04779F9D,0208DD5120C606C4,BA4B27CC2220C3A5,0FA0B75797AF916D,305C20A78A23797C,DDEE5FA2A5F49801,5BD92B5D6FECEDFA,8C752482FECE5DB9,00E526C817B82AE6,0000000164A9D12D,9824925A804E3B98,BE9D9461FD11CEDD,E3170FA065765CC0,8E2ECC1137682D32,89CBF7E4564AB7D1,7977F98EBB0D0BA8,929C57DD49660F70,3B7A945174D1B3F8,2042719B7F97AAA8,0000000040C3AB61,39F6A4759CDBD493,D4EA8E5D59AF751D,C8E19FDA738C13AA,1ECA40A602523573,A991FA43E1731C94,CEBA68ED026B2E2B,86F048D7EC01F5E2,CB6DCA12729DB712,CE5048A23EF52D38,00000001351BA5FE,ED1A1C24D56FFFD5,F8E4EC7203992F47,CF1AA7FA5C22EE12,A74B147BB644B191,A7B7CCE455E1E06F,4D71DC30309F516F,E5582356C0B604C3,07017E120C329BC2,CDAC2D9259D95722,000000027325CE41,849182ACB09C280B,C6D50C2039CB6360,85040041B03E7A00,D5F53234A3A6075D,04E15A9EC405590E,A70CCA78A6105931,CC8F8544EE2EB853,36CC88ED1326FCCA,7867760159D2411A,000000007B26D022,EEEEF048007BFB27,1F89694EC0D263FC,8B35C57C5DA385CE,4B30F63AD361AD86,1A302DBCA802206B,ED16062FF580214F,B02AA8A4FBB12079,7C462C6982C9B1CE,73E923AC043309AB,000000020B4AC095,7E2EB6D8A29DC55A,DD97778A134BBBE4,C5E68DBF213872A1,085431ACBA5666D9,5F362C04F216CAF6,2C0272B2D08D68DE,F1BAA5C2A4139B3D,7C7843A82AA998E5,CF8A7E1AC3A7E0E7,000000004ECF457B,F4C6E4ED93DB30AA,4CEFE87786429E69,7C305ACAE3A58FD6,79FDA96DFF09B5C6,CB70272194C79428,EBEA65C49853F617,4413DA11330626B4,CFF41FD5D0BC95C9,2E4C61F6252F7AE7,00000000652C2ED7,B41E41075EC4DE8E,F132927F18F9FA75,C78A834359FA495F,82D3F94D9BE9E987,F891DDFF2475A1FE,99178763D18A38C2,EBD2F0FFB61DDAC1,0AD2571C2914B883,DB84D2A9590E7DBC,00000001DC44A786,FF582D38BFEBC30B,0F01F5AA787F28AD,56B793B884AB45A4,8205A8332F75DF8A,BFB283DFCE1F0BBA,267C6A02F5011102,6965ACC72490CBDC,AFD75DF0FF85C747,82DBE64D8EF4E178,000000019F1877B5,D698E24B5D55E264,28CE2D9E1E367C71,0E2E49A730A9923B,D3CEB2A8F801CCBF,51B0B0D824842091,88F1E2FC5FAAB593,17A28A29FE12789F,B8A97C8542B545B3,48659B7A334A37B8,0000000142B6CE5D,2DFFBA80B561A896,1A1F735404BA6E21,BE887F96E86F52A1,064C044E4F64DC39,C3B66370B295FB16,BF820CF3A6DC105E,6CBBA065BCFE1E2B,8CB9C6DB06F3E138,F01F0A0A782EF706,000000018EB29F43,2D095480D0409BE3,4BD20CFA11BB064B,0F0F14EF4797D5CB,DE215C1F5C5D063A,BD83E402302FC18F,A483EAE4D8B57B8F,C3A64CEDF2E8B0DE,CAEA48D1B0D9A5C4,AEA191A9C56ED50A,00000000DB9D109F,47DEC9CB4E86D0A5,B2647E9EA43826D2,88F086EFC3BE97DA,95C3621FA1C40AAF,05CE5369800DCCB1,02BAF9DF2DDC7443,D04C291122F26732,4B84799BEA846A42,4A4612B1E24C0E80,00000001328C1EEF,2AFD63C4012F74F1,659BDBD43905F4DE,C78BA190E6873BD8,791E37D415019F1D,4E204B16914A4865,FB3FC33BA74754C7,4C4B448EA9B0D36B,E5F054DBB47F5663,0DAD784F980BA40F,00000000E63C855E,8003D8EE0B641056,553657CB4B3F4717,6BEE13D8BE5C32D2,CAB7721AD7C3FF84,E9ADEAB7EFBC33CC,FA5EAF25B9AD3BBC,33BA68AE63CFD366,4D902284821DB046,CF8990DDF2FEBEE5,000000002D06F5BA,E417EA86A46B04BE,7A2F03669B447D9B,4E3C7F1357BCD1D9,D5C18801BD61AFE1,F9CDC618776D2843,EBBBCA28462895CF,6800EEF062E46769,A6DDEE783682017E,821FFAFE4D8B4A34,0000000138B680CC,EAA6AB0F4E90CD52,727F4DBAF7A46223,69F3F1EF8144D255,036B5153346BEA03,4515BE84327535C2,7FDDC42CE243D198,4ECABEB0DACE3C44,23B060EA213365B3,04CE6998070B34DB,00000001679EC14D,70DD61C786E8ED54,E58AE8A13203DF83,18E55553C64F769E,8559605A0C89E673,34EF85D999E81DD3,3E42990F67353735,D7429F8235B90496,CB7EB33A14653A4A,AC7E4B3EFD9E5640,00000000CA7F7386,52557627F7C45BFC,F6608C45E2E9A1FB,A32E3E88E6D17ADB,0BBF270C32AA3F58,EB44D71F54861CAD,9ABE1584F473800C,3B209EA162338EFC,A93A866843B79BD8,354E23D9DE1BFF18,000000002BC7D4AE,8A535124B3BD1187,661B5E82228E2DAC,71A05756DFE4E25D,FA53E370C81FB5B3,82AF16D7814EDE2C,DE581145BFBFB34C,11640F789BD71D08,1F28CFA8A4AC5EE7,FAC8256FC72FE9C4,00000000BBD081A2,51D9D6FD8D2C0C6A,35754D70811C69C5,9DC70643FC6C3B2A,AB1E71D781C68769,6FAB9633EC4D9267,DE9B71E82CACF756,D443B52E0A2E820C,F33E5A14DD15F091,4BC8F6D4761433BF,00000001A78B22EC,DBC6A99811200B7B,5B66317F8C0EAAF7,1B4414694375A5BF,9491FE9035CEAC30,A790EE95A45E4A97,F18335CF85485C02,E2D58B2C3135C629,0596FC3F2B7E5B78,CC0206D046A55917,00000001679851D6,4B8EB1F049E91889,F283E891AE3CCFBB,0CC6C63CB65A3C17,662DA11A51D21A2E,DCF868F8844A554C,7B09EE590497B749,F5147857D3A68CA1,6814E7A7F245E53B,4509AD18A3E71C3E,000000013FE08939,BA463C2E15170FA0,1D5609C156F9118F,AA19D80D1CDFA111,AB45A2549907201E,8BDC0BB3748A18C6,BB55E573ACEB784E,0DA6FDE715C7F2FC,EEFD624CF5F48B02,7D2D167CBA13A2B4,00000000BBBB548E,2F6D96A3380FE4D9,3F47185D8826CFEC,BCAF4D46AE5A67FD,FFC9DF67EFCB10E8,91FD92A4E81D0FB1,FB21D6B8B6092E1D,B703877C4EC3D2EE,86DD27F3EDBBBA7E,4CAE00EEC298C500,0000000054510991,0692EAA64C7571D8,385C8FBFCA41D416,73ECAA9426927E94,7A5ED6C2BDED4472,2D14624C3E710FFA,C263D85023806717,14BC080DAAA92D74,C1F93579D8E36C4D,11654248A805F192,000000026A2E647F,661FE2259C75846B,2BD3CFF630C82C44,18D5FEE1E95F95BA,AE3CF3FA4263611C,7C156C21DF6BE423,A53CB0A4B713AD63,4B6EC164E3CF4B96,DD3BAF32DD08926A,A6119679AD3D4DD5,00000000857BB4F9,59B5F7454CDD2DE5,8B2AFB0F30A7055A,CFD1736187A30E5B,002BFC138917DDAE,5CB2FED5996082D5,CB97615CB87FFE09,6119401DFDDB507A,E41D6FEE2EE18BF3,C29F2CFE4EF26FDD,00000001AEBBA87B,9A1522B49F673086,41681154EBD87580,94513FB62103B52E,C08D61943FD89680,1D4A79E4F5532994,2498DC88482C40E1,7FB8E2297B77290F,0C4FB3C456D237C3,C3A2CDF7BE2877F5,00000000811E915F,EDC510FE81BA0513,F424CE0A814513F4,3AF7263A01A82FBC,71885E513D339DB4,A7C51D453E670E57,7666D5214C6494BA,ADE963B16180FD7F,E4262136D8F61D7D,27F2D5AA44920204,00000001966600C4,90BB9C0F06040E34,B59D837ED98C8E45,BB8C7349FCCCCAED,C192310CD06FE716,0CBC6997F80380D1,F99C46584E87A009,BB235C41C0022FB3,451B0FA5F9D01FE4,B72BBFA91A250FAD,00000002450B89AD,E9E3DD3E96F079FB,B4120D2B28CFA456,33C58F9F4960A637,1CC5332562F663A1,E1E865430885DB1B,4A94031A0A0493B5,6328DF8CC22C9636,053D67C63FFEF1C8,FFE3AF76790051E3,00000000E64090AE,93AE93A64A5B7C96,AFC33E5CC694EF46,3EF86C41926DC602,8399CBC2BFE7DCF0,0B2EF0CFDC540AE3,1892F0B73159C93C,67A9290D3D8AF980,3B9DB4A2A1B90378,080231C871EFA86B,000000005862730F,B1401F95573CF00B,5CF4B6F1C5A90C86,8B3A2809D978CF6C,1E69BB1F4B1855DC,918806574D19D0DC,911CB1ED298AD2D4,D15DB0112B90E64B,9745F2D2B65AAED0,A1F090E664A24C45,00000001F69E67A0,D741A764275959EE,C9F13F3C82C85E48,22D0EB291D048FCE,6B29ADFA1AB49638,8CF620F1536AC409,38C0CA14C3DBDB5E,D0C22ADBD2CC3A34,C90F61DEC7B7A003,29CE86215681DE2F,00000000930257D1,CF78B07A8656EDCF,E2DEDD5AE464282D,C8CFF66EAF9B5B03,A56F5F451F3B2C69,EBF688164420A885,BCD2F40721D46FEB,35DDA06EED9FE4F1,0990275C3E2465BE,5E6FF18E3D03E4ED,00000002541D621A,022C01550854D8D2,E4268BB9B0650418,3205F4EE8481B0FA,8C9123D4DD7E3991,0925C0AD69625A2A,B378B2BC60104348,1271D1632E6E5D10,A0609BC0234B4080,B076B3408CD36BF7,000000016ECC486D,8BC56578C59E4721,AAC254BF7C4093D9,5989C7BDB7A03A45,50A8E72F494CA0FB,AD44762581FFCC91,A7870583BF7376AF,05DCEF2821F19377,4C2719F384FD5A20,FB48982B772DC7F5,000000000F92657D,2EA9E50A1AFF227B,9AB02B71C4C64FF5,A167C29AEE3CDF14,4B2A7397B171F3A0,0DE06991720A368C,F74511356D393386,AAE990FDE7501E36,7BC0CD31133BE9AA,0EDFF9BBFA9FA347,000000012D4847AA,8CC8FDD676D38225,07F88C2C73F8E845,71E6E9A75114EA1C,80590CD6E7948251,21369ED6DD65FB77,7BE744D0614391CC,F0D58CD266223E76,49E834333EE365B2,1032F646AA77FC12,00000000F8A0F54D,45A4689D0AE686F3,5D056C62056165B7,164878602CB59CFD,531E7EF2B8CBC7B8,F32562019D29A482,9AC0B1E4C26F071C,7167FF422F1C1C8D,E82108BF4F33EB41,645629DF8637394C,0000000181DB0DF1,BD7C1463CC83188F,79B65ADAB8CF17F8,1898B0C7202F9FA9,35F107D10432F9C3,751F97331CFFDEC8,AD8C4A6E4F2C173C,BDC82D4892A7D83E,65618D2C01BE25A3,72B858E7802F3710,000000023EA2583D,7D944D6EBFF4C3B2,EC852EFF90D1ED67,9BE25E4EA1AD22CF,69BF6319E24CEF0A,41A9B38FA1547DFA,806138F65AE23F48,6DD0AFE629A22B31,A99AAF97A4C28919,290AE27D1BF779D4,0000000215CF197C,3E9AC4B7550F4157,27BF338075D99580,534C00E8CF3D5FF9,8A21D0804CE65875,53192B31E5FED4F5,6ECB4BC06C2250EA,9451A426C3AB7527,59B510EBB6C6E55B,C402DE4AAE9FBD7B,00000002035AA89A,75FAB9C448A1D2F3,17B259E3EF72B90D,0F7FFC707DF5AE5C,23E2284D1DBCC815,55E11B7429AE98B3,6F087FF0DE9166C1,3E0889AE3517464F,2DF6E22B2B7B9D00,45A8AA938A3461BA,00000002356288F8,63651C387720520F,D2F637C3183E8FD6,6041C70CDEA71AA8,6A8D7CECB361C2AF,22136C94B365A757,A51FE6371F117D42,66622DD2ED9649C1,549CFF5FD743B048,7601A977353D3145,000000004C8991EE,9A5A66B3167E5A12,95B7552477D654E0,8F39AB07776DD5EE,71593561AE18FB28,37FD46A42257890E,5BB1F45DBF93D7C7,CA642528695CA279,F2673CE82D0795E8,DD7F7EFFC850F01A,00000001DDCD3A59,D44E5511744DF2BA,0C652C599F380441,D6F9A640D9A9C854,2E947DDC9EDDAB34,E3D683C5673AA008,A398A4827FFC2434,EB3FA9BE24801695,3FC857D1D2649219,2EA4E45D65F22FF8,0000000162DB0736,7EF9165A4CAA8B80,7FF989914FF619AF,BA727326D0B98B80,4AEAE9EF36D3E8E9,5B3ECBD83C21C7FD,CA86617367490D76,5B0A77647C8340E5,C4047DD6B5310202,D75FE8BBD456CA3A,00000000F2B7A9ED,A31291B31EB1F5A1,083A8E8C8DA213A2,4F6B438524F2D5DD,A948E10891D4BF64,1D5DC06ACFBF1738,BBFF6C68B7DDCBDC,ED158FF78CE69A65,844A6F997241EC74,4C616A8D9AF77DC4,0000000128A10A65,A46969CDF10326F2,A007A843098CD58A,09F20D05C3CB44FE,A63F7E7BEDC6F1B6,FFBB603908C2F642,6E14AABDCF18B2B9,CD38F3D63619EB38,931A2F307E31AD86,8392D8A554EAF1A1,000000019EB4186A,A0DFEC31DBB11A3C,F533DDD04896432C,28D1CFE29677755E,24909FD02C0819EB,6D2C557DBBE72DC3,9491A62385B4A3B6,BC3F9A9E08F5FE19,82B22603E5C0F582,754AA4FF9331A3B7,000000013FC5F9D2,453AD7DC15AF36EE,746655838D4B401F,E6DEC4C3B57A4B77,CD0449D9CBDA184C,F7851948DC57501A,B0A903970A61DE20,54968C17607081BF,E9630541933354EE,5D56E012A8E89E12,00000000F271F3EF,5397F2C090387DB0,D743AB0747F257D1,ED2AC897806D4ED7,772C08ED8063088A,9CC3996261B298E6,1FB537FB4779AB9C,46FB200ECEF931F1,283ECC1418490383,B79A781D408C6679,000000010694B7D0,7EEA8F2C97B74E3B,70646586F673AD0E,E8398DB905832455,084F10C0F3708C86,8896EDA5EE796380,B0DB5685370EE491,2316DE38A3F76897,747678912F0B6D56,DECD19466C46D395,00000001EC59974A,AECE69EC2AA7C988,B2967702988F0E8E,6009702F4B3BB14E,379040BFCEAF5180,0F993B298DA528C2,6EAA5456A6EB4B71,02916A17C1D229F9,2DE84AE5BDB96B55,EDC0203B9547E566,00000000F159C7F5,7A2BC7061BE5FF0E,F243528335788E03,66110B7766821E48,068646DCAC4403E7,6E651DB67DD35A5B,E7C785386987E725,86BD22737E0745EE,301F56CD313F1641,8D71EF5F5182C502,000000013AB050E9,9DE2E6E116BC2229,EB7F4C7E97B4028A,90FA82A050EB894A,9E77C69EC2BD290A,A0B384AB52DE2963,D46D4BF356AE2C44,30C80EC4CF5091AD,87D59A1D29839EBE,A7F8F5E65F2CD2AE,000000003BBC171F,40B541260425871F,C984ED577CA26940,AD47F887574CD476,676CE81626238EAA,E54419EE05DD2511,52E9942FEF93943F,73A3A7F720C5736A,FF002999A6460BB6,4DB569547FC1CFF7,0000000178983DDE,3B142207177379E8,EA9E37C069C14B0C,4B25D4916353DA03,0AAC3B9D68D5A734,36A46F5A75C4082E,6D6ADE4D4AD9A75D,AA11319CA38520BA,385163EDA85639AB,58564C10E32DEE6A,00000000B87257F4,3103CF9F056AD52C,3AF80DE5BBAA8062,5517C8255D67F0AB,C0F130C3BBD2C17F,2E4DB123F27DFE21,31841A2C56D460E7,1CCC8D6CE829F804,F4E3927C3ADF50DB,1656D736F0ABBD28,00000002280F4B14,3BA577B1470B6A42,68E125BC24CEAB5E,C94F8D6689789A81,7164F95DD685E6FC,328E905AA7D116E6,0FF6E6F065E17294,176EC98D57725CA5,CB6A0A222ADD0026,A9A2A5ED329661F7,00000001B378ADDF,B91F1C7C158E3E2C,7F39A63C092115E6,DC97592DC0FE6B2B,EE7898F26F44C684,3DAA940A1B0EB4E6,57BE19B9DA241F64,C664E03F7AC4DE04,950727B074A5778B,8CB083A2F7BC355A,0000000017C31757,A62FBC70F71CD148,4F5544FA116F3D5E,C87E863E3B9026DB,40E0FF1608A2A775,58A522BA9FE1715F,E8EB2BE2A3471792,92AC0A3591CF0B47,34A63EECF8DC6C00,D7A454F523EF0B6D,00000001337B36AB,19D55116644B66F7,6E2E6C0C6E9722B9,5392E6B49D604EEB,FEBD7AB203A547EA,AA7F8101CAB7FF43,30C971C6734A6C2D,7476F092DAD19BF8,5F51D9F41F255BD8,9237CA794EE71CD2,00000001BA816D01,937F4330E364C6FF,503774F3C66CD71A,CE0C4524CBC92FC9,060A1688D498AA0C,C6E4FF1AE1EB2422,6EE8F015B414B84C,446060CE158585BA,B2D71CF645233D90,B7A7A5176ED3FB8A,00000001AEBCABF8,A4AFAEFB3C56FBB4,2F37F0F8740FE916,2E6BA1F31E4644BA,27A37A2D833638F2,E6B219EBFBCF9F6E,D9F280D4D3953C2D,D0D6182117E35B31,270C6ED5745FC4F3,CE308CA43314DF36,0000000269F7F256,DD1B4100822148C3,50AF529A57AF4758,55987D0699A6B571,444E061231B52676,4999BF43B8E19F0D,67A41AF386372929,BC7F39C3DADC6EAD,CD5B7F12C6DA1C30,CB5FAF1BBC4AF6B9,000000017208AE0F,B041D61E767B4E23,C860C58E10B2ECBE,A40DEA43F256A21E,99516236E650C4D5,23282E357AA4A7FC,71849BC4E7FB0534,4AD243FA366ADDDF,311E38C4C9D01053,2DAFDFB368F5CB82,00000001F1642476,C3C03E8AAFD67EAA,458E76B077A39E12,8EAE1BB831671B7C,5AAAB560044183D7,F252C36970EBED93,443FC5F0549B59AD,E4615A64C50641B1,CEF193AF2270737A,E5506004F63F6E81,0000000124A75B5F,2C0563665B85C8B4,098771389C23BF2B,4195EBE05E26FD93,EE810944689E2435,89D17656D6CF806E,7CF617A196D2ECBC,A63BE88A3231E255,5E27DBA17251C299,4822428DE5A44770,0000000177752B6A,CC48ABE6349E0F6B,5A1BF825B376D2C4,1E11722739079BD2,63E89C7DD68E95F4,F93D6AEDE55F88BD,3509316E47BE18AE,7296EA64ABE1A049,5248BBF9F57B2718,C3E32E3771BD3CDE,00000001E98F8D46,412BDDADF342A823,01904DACF12AD79E,F6A70236F7EC4CAE,8042FE872DDBFA5A,420FF329A6918B59,7C77E376B06C8F37,6F4F4F671DBF37DD,E0CAAD2C321E067F,2E338546CD92888E,00000001B3F737BA,DF09C09176762B2A,956CD9B958A0451C,229916AAE61C3AB7,3B69D0C5545CA6A2,92589A349A8F9916,BD36D57D8E4C2DC6,8800592CE33C12EB,E546D8D245366B6D,18AFB0B8BEEBF89F,00000000663DC9AA,F72588E820769F8D,96892154170C1BD6,C2A409AD0E816652,C77029AED5231F38,32A7C5B0DA69DE40,709C27D22B299676,709D6DD93A52085F,956E4618ED15E28F,13B0D0F5C5F3ECAF,000000024C1A3808,10C922437CED4294,A3EFB2F8AE040D62,B8C6ADCCC82AC71A,E057D666377D594B,8F0E535E5948497C,BDDCA8C0BA1B5712,B03A2C65717591F5,74D99F8830C8BB10,BCF9A6FEF54659BA,0000000157B4E761,22C5DCCF18547788,5949D8AF4C10B91A,2601CFCC3B8F8E31,15DB61A9C41B523C,4F1C8A9C65A5CB1C,B062024056DA8DA3,0302491E1655D017,83F882B4964F96EE,2727D69E81276E9B,0000000032698A69,D2CC6C27BEA8C39F,A04EFB701397592F,662922A9D163C3A7,7FA91ED566F7DFD5,821CFDBB51AD4554,03D2DB7162D2C95B,B826EE71A413AC92,5BE383A879289921,07BF0A54FDD1582D,00000001099DBB71,160EA352B5A19E5F,3FBBD60F0D65B1AA,9A423AF5E4F8DAC0,6F9EEBFB46430582,88786E4FCF7E5B2E,A6E0FD7773D28FF8,576E13E8720334ED,2B1DDD99A9D7CABB,EEB0136BFF5D27CE,000000011B09A786,EE96C369B02035AA,2026F5CB131D3296,DA868E09DF8BF905,251121DA9E202C6E,CF47ADD9B2271561,FDB9C7F1D056F7C9,AC7E568E74CAE1E8,21D4E5CACB83C589,A605CC6E1A843934,000000011FFDCDB2,42251774A2D9239C,6A4B8F3A44314023,0172ABEFF0F43776,B03411F29E40EDF0,B756D6441548E0E1,29F06930A7DB1D56,B2A1A39AB8581816,87B482C1B5CD453F,C00DB878B242E321,000000012E4D200B,3AD9B9EFA2FB68AF,E83C330AA2E771B8,DB1BDA05B53305D4,8609CE9EAEF12831,90923433D64C31E8,DC974DD90F6FD1C5,3F3C828CA2309553,243B34C3E3D9F956,9A49ED791CCDDE74,00000001265DA298,F36823310501118C,11DA037587EF5D82,A218178224ED1D0B,CFDD1A704431C091,98C354984DE7F4BE,85EFD4B2C09C4A05,865F0A83AC767976,902A5B26D4156842,1134F26FD72BB73F,0000000014D6D0B5,0237FDF5452AF489,9928AFB6D083CF30,472EB5877D888BD4,8C6302AE075DE066,42F5B9DADD9B4BF7,554ABBCDE33ACF19,ABBFED2D1F3E8394,D7BDFEC7A460F01D,69F35E439AB205DA,00000000468808E0,45F600C77EF58B4E,55077ADE64AE409B,0AB14F71296CCC9B,C51ED84A26A5B6C0,C86202398086E2A7,7974F02119EB53BC,3FA6796787A5B732,AAE3D90E709C7E98,ECDB962845DF64B7,0000000231A4769B,C58A5DE21107B97C,F09EBAB4E9FAA6A8,7062FF9E9AE58F5B,EC74BAEB4459C7C2,57C39DED7DFE2C42,440BE54541240BDA,62CA6C3E6EBFD25E,D7A8065686E67D4A,06A4A55E53307D8E,000000027677AEFE,115689E3815A146A,D64C6EE27E273F44,BFFD3B86B0F23C41,F3DAE075266A5A2A,98E0BBCC671F19F9,21F4EED472285BC3,C581BF886BF97EFA,7F5970704F635415,5BD103D7D19F3341,0000000251110F17,30DA5D39F4D3B0BA,BB63716A4680FC00,123EA92265143173,ACF5DF8E44EE3647,88BFF10FA01250E5,458F7441999D5CF8,73F704D3E8470CF4,78BEC42BF72FBFA3,8AAAE9157942ACCF,00000001B0C1436A,CECA9A96FD015983,A3B260CC8110BAAE,03D0BD30E7F4B3C2,5763345EB7E3FF4E,D65300BE6F5ED161,6A910BFB976685FE,95314AA28182C077,ACC9F800959DD8BF,6E9A168C46B65C94,0000000117CB2761,31E20C4ADDDA3F3A,140FAB0651BB82F0,603E295C45C2077B,7BD615BBFE133E22,E73B25BC93AE9DAC,DC125A2138557A38,055D1AFFA2A56CA6,99F0075543B07D16,5C8587B1E5A3954C,00000000E70CFF54,634C9059DB14954B,800574441A13CEE0,60F2739D935A1481,FE6AF2492367785C,A0A136EC49F81051,1E442EB73136959D,190EB9026B444E39,55D0883D34999372,7C53468BFBC21C96,0000000163A6AD77,692A557874352AE2,2173B764816805CC,B9CEF3B5379CC12B,BE97984A527F1BA4,132F96785F71B67E,A5F2A014849CBED0,B618D873E4418C93,6C7B2FFDA2A5B28C,62A4146B818CBEB0,0000000026DDB288,74DF3DD25531F031,7D69799BB7728AA9,C79E9BF2E612AA0F,EECA4BF2CD572E6A,7C8F495BC612DD09,358944A30AC7CE16,EB55C6FCF6AC710B,ED747BBE7B62E350,3AAC002B769524BC,00000001EBFF0EC0,DC76769D2002DDDB,2DB08E512FF71E6B,C0DE437E5BB22EBE,9906E444313821AE,3A38E752ACD71B5C,FB181E7AFEB69849,B3ACA10E8F52D65D,7A050C608A23642C,F0C93FCA0FBBC7B2,000000017792F69A,9C65A894C338ED80,0DD91DD9D57EABDB,DC69673C844AD865,D0AEA265D7495A22,4789616C1F661474,ADC054596489D9A5,56EFBC4DF633BEAD,9832426597E9950A,C938FC93B4436315,0000000015D96FA0,69F9E14745F318F0,1103651221F241BC,E3E40145911E7B87,A52FA0DB76E3C3FC,616B98979F5778FE,552041F64D28CCA0,5DD588F7CCD52250,EF56F1A282BDAE6C,162AA32EB5339B01,00000000AC4642D6,EAF0FF957B9FB38A,F16FB80F0E9A9DE9,D70EA15CDB31F775,4A75289CBD7F035F,1103665664AE2870,902055A354BF503B,FD6B0804EF4EE04D,8487CD7010D167AE,9FED6B9606EDF014,000000000778068E,65B8FE2AF1AC2A78,75338FC1D9724D11,ACBD7EF7CDBAF6CF,6E2C51981F39BFC9,C4092A0272902E59,F54A4A4D7BB8461E,5EC75FD7C927016F,BEFBC9E765CC994F,15F80606E799137B,000000012CFDE544,1215D0AF4F7AEC4A,8603FD51D14055FB,3E0A2F558C1300E1,2A3330ADC80B31AE,95301791DF60A559,3AC3C15DDEF66B58,2D290B8B10FECE41,F757E8D38B4D9007,FDB51DA0E2A2AA2E,0000000154B9E830,8B495FBB574FFCF2,B0717D4BB67A43D2,A6E16782746D34B4,CBB17D397A0DD204,FE073407AF79F62C,246C6204DC635D08,74B2583DE584B699,11161AD143DD930F,28DA42F751C41D6B,00000001BAB41F11,C0E07F9C684C6E3D,594D8167912816B4,2E7DD2429B203456,DF615736A16E7F1C,9B9634AE3F0F1BEA,D402031C7399B05F,D70B99ADA47AE1E0,72E40FF9DEF2C409,6F82B5A65EFB7155,000000026F67B8A6,FE3A7D2A10CBB1D7,3F01C4AAD4BDAE0E,C8F829BA4C4B811E,BF6649A218BD6183,7FA1D7FDBB39BDD4,F47449EA160707AC,2FD0D7D4A492887E,442DF75A0D716D0A,93E67EDA12116657,00000000375EBA0F,C745256E5DCA9CFC,76BA1875A5802193,596605FA16F8B017,BFF6FD3B39DADB4D,530619FF6D2DDBA9,BC2323494F2CEE34,D5794465540B2703,AB98E6BE09159FA1,49A69D909D171058,0000000082BF83AD,F8668846FA0BFF8E,459BF81E2A27EA8E,924CE25E378FEEEC,5F1F7FEC5D44B5EC,C07E3E60CF285617,91ABF1A486B47B43,2D1DBBD6EC326E13,110B71DD188E395D,31F1B00FA8203C94,000000016DC0BE79,B0849DED901ECAC0,AF56DEB72E5F553B,B73BD31FC6C55FF8,9B173B220A8E8632,9E2C08FD2454D75D,541E56988101233C,7310E8EB5FB8CA08,0CF03064C8B9B836,6E72E5EEB2B5C575,000000009A15D954,771851CE1EC0319A,7D83B3FE114E6433,ED2A64464CD9A556,04DA6A2CA8CD2DB3,C6B64C3075A73101,6F5546E5C25EF9E1,F3040817E1578930,EBA806F7E3A0B64D,C4FD934E3B5A94AA,00000001325493BE,8B9A18E88164D246,27D778D56280F430,4C6263F33116ACA8,642BD683A6DAA9AE,7376BCEDC97364B4,D08091B50E4CA571,05F2A9F67FF16689,717FC2F8273900C4,72DCACE3B524C93C,000000007E510331,2EBC53546FDD49E4,3539BCD17FB5AAE0,34CDA1B524F44FA8,771EF51B94E6703F,BAE346110A68CD11,D9BD1866E5D28AE7,5DA22ED4C68A482F,D93AF94D4B74AFF8,2AFB5E7B4E2D7ADF,000000023D910128,3114CF86B216BB4E,830DFD4559D82A8D,40AB25EE5BBFE8A6,058DF6F248C9FEB6,EF3E4A44F8CEE0AB,218266616F56C9EB,24D01593026E67BB,9BF3B23419F1DFF9,BBA800A3C7AEDD37,0000000267834EEA,FD5A4D502276F00E,A202895E5C3A2707,1FA82985047C0584,6DD54AF225860169,C4420978E55BAD57,16B0B1C5369FCB7C,45105E80122153ED,A115D2C99FEFCCAD,E0685A48808053CF,0000000076E5A5B1,6AF79ED7673E8378,A9B85643659ECC25,4BE986082F9E967D,AA0247986C4D448F,81A52AADFF2FAB97,22761FC197C9C712,5CFE6145EDE5F199,27E4EF548FC6A17B,82991AB3CE571A2B,0000000037346DFC,9D320DBB8B4F3A0B,C339B0159A5F89A7,9B66CB2DB0E7A4A0,3731C80F00652752,B3B407907BDD5DBD,39219C2DC84E1E57,E16E33DF5C9F484A,27480054F06B8A6C,0429533E6DA6F5C3,00000002260AC486,842CE2D425E64433,52F66136070B5725,8B0EA4B7C3755FFE,15E602A3D85E7AE5,CE2BAFA5C82E7AF3,D76EB45CE57DAC12,FE7BC04B63D990B0,267241BC36F8BBDE,277068E26E9BFFD2,0000000007C5C6CD,F0EA9748AE0B2814,ADCC33493907191E,4456A66C6A564F61,D5589A036E899E64,D3BF27820EC4C1F2,7D8F60FA5A25A546,CAB045160CE638C3,DEA863D3DD18B8CD,F8060DAF32E9785A,00000002743475A6,5EBC9C119D5D22AE,E7FB45DD3EFA9658,5EE4004D2D2EB68A,06F9B289CD06B3EB,B209CC60D4218C5E,DF640D50CC78248A,29FB476EF4931945,3717035E6F825934,DF596B30FC8E2C5C,00000002663EDA6E,CC2EB58A43D452AB,A877CB27D285C387,6155FF80CF6B9464,97C831A84EFBB601,3CBBF6A3CAA497BF,B569557A42C5E9BC,19163E03BC07449F,5E27BA63FD664A8A,B5B9A9A187A693FE,000000022F2074F2,0ACB11BE5FA71145,A33DCEDA7626ECA4,FDFA82B548EDBD72,2A0528968DA869A3,6E3281FD21FFA7B0,CF1A81A23486215E,4F5CF8ED3A83490B,EDBD6C29613D70D2,F93453DEFAB75351,000000002C8A9060,66897788FE5DE6ED,F59ED641F6A8ADF5,9AB4620243D6C779,4E4381218D338722,D10B859D269A9D62,BC80767D68AA832C,687826868E45CC07,81EAB55DC2F5C10E,0D9CC64AD49ECEAA,000000015840848C,E3D81D3E3A90D898,27471F298BEBCE6A,4FDB53DB956E7913,669B156F95A067B9,7BE960E60AB83E6B,AF4625176E1E269C,F80F04CB13A87D8E,FA2B8FF44F19350E,291852551CC0615F,0000000161A703A4,4DE75BC400DF741F,F4848DD9A43FCA6E,0E4CD4DB82C00C0B,31F607CB45FE141A,1A0F26301B078190,257990CE325E43AC,A7ADA1FF231E3E5A,20EC49109ECB3844,F603093BDE142D82,000000018D7BDB62,09458260990367FF,054F4DDC8E039620,5514D90AFC2830D8,C22068A3BB05F633,F7F36118A7458FDD,81E73EE56A695CB9,7E4A5B51B8241959,8974F3E3EB30339A,4443EA72619DF20E,000000012AF520BE,33BD0DAB219CA9A9,389F00DC04B877FB,FF792DA5853406CB,4AB99ECDDF44C41A,CEF55AFF13CB4F95,085E2F900AD0D61F,05B851DC325691AF,1AF19C004CF236E0,80C3B883BEA9CCED,000000022A76C772,9C5172BCACED16E8,B520A01BE4C05B4C,74924FAABE28E0FF,89385BDE652E85EA,58FDDBB57A882962,7A23DF2E1134EC9B,6A9A935763F14A94,56B4B3361A2CED05,7561392163FDCEB7,00000001CDA84C83,2EDC97314544FC51,02D3C49FE08D9086,F971030C5664E19B,0F02E879CBA929DB,44B0A7090473F985,F291784256511EBB,4393DA8D2152B00A,285471B2E01D5A51,ACFC89E6A7143EA9,00000000DA84132D,4C51F5615145AFD9,6B8868CFA3A5B710,7C65FBA59A7BC23D,CFC3D1A532E80297,B8BD54D2323C2905,14553E32B9007ECA,3AEF04D157AE619F,8C78FFC5EB692492,EA8F8E4887ADA686,0000000145D4D2CC,A7E5B01A285831A3,5FE478B26B9175C7,EF5F6D0B129FD045,CBF26851B7B4F833,6618ECCD8A7590C0,0B452DF2AEBC1855,1500A45C32996AA8,A72AF8527B1F9710,4F18DAD9FE44D6BE,00000001511BC732,A171FFA98FAEF906,39B43BDC21500ACB,D5656DCDBA21EA4F,448A5A128C9452FD,76EAEE8785CDA17B,9D64F3CCE32E973A,0CEAFBAB4F2152D3,C0F37CE250556445,83C43CF9BDB67B80,000000004E530504,3130D8C7DB587DD1,408E54CE206BDCAA,1F78791809DAACC2,FE52EFE071E19658,28D8E5463CF6C5A0,37E684D6EE169537,39455160B9DD34A1,1D74841EF82B7FBE,15FC74A39153E8C3,000000027BB0A38A,48C5F3A2BEC4C534,61C54742A92559A8,BF2F84CB1EC5ABCE,889B9D8D7FFCC7A7,DB67FD93658802F3,DF07B8F95693B727,75060487B93BA729,204A5FDAE2F2CB3A,4FBCD7A517A29DFA,000000019A937FCB,15A852C628883727,1F57B3F9A0DE5553,E360B538DB51A162,E772DD7642029D77,1FD8530DEE752A0D,38D37E1BF6E4C91F,7D41CD30A44C3135,E154E07A413739D5,99FF91B855D9CC0B,000000006D2AF316,C620D4F4B846E010,CD010974ADDB02E7,09061AFC06FACB91,5E7B0F4F082406B5,1622EDC31A6594A9,2E67C3C90C6ED5A9,9DF31673C036C76C,CCC5F44EBA520D9B,ABC3B3A0509A8053,00000001E3BD5AF4,497EFA566EB85A01,6263F682CDAB5B78,A118933EE75CA795,999270DEFA722839,D47897C1074A509D,9CFA18E5FB252F06,73D1F4D45CE328EE,B7AEFD4AE92D883C,03B8791180332DC1,00000001A623754E,BEC4AF00A598759A,46F9950C090BBA62,90FC477FB7610F80,6A6B24844A6E62F3,E773541EA8786E29,31CCBBE2DEB9CA94,50E9E05EA70A3624,CB32CE33B30F7BB6,F3F2709F7598A955,0000000188087D70,BCD7ED1AEC5E2760,0732B101904B1F4F,6392B4F49394DD2B,21A62BC6C478AEB3,D665473DF94F09A0,0F6FD3AA33C033F9,98E80ADFD1079523,CE2476D97ECC3984,9E74A69C943EE871,0000000026DB583A,79FCDF8811B44FDD,1C838CBE5DBDF3AE,4391F3A628B6D104,102EF4C64B6BF760,0B0FA0C5D167D954,1AA4907B1FB7BFC4,904382026FBF7750,6592C1620A245E3B,C830AA78AD7AA73A,000000010F251633,620DB3D2132706B2,45B57F08CE7AE0B0,7C04DD7F53781AE2,EAC4C19995286134,D4B71E695B1904C7,713748D8188CEF06,DF36137B2798E437,00FA9AD92E8FFA28,14C1EC96D67F178B,000000022B179A3E,F1F9A46555140AB7,70400C97BF4A11DA,FD91A9AEC10EFCCF,B1DE2E3935E6F7F8,241EC37D2EF9FC77,5637E30301F76F0B,5F80ECE39D31A2B1,0563F1A69E22BAD0,A27461DFB2F06609,000000006F39263D,71713C275B2AFB34,79349DFCB1A78BA8,E334DA7F26B3BAD2,4035714F759C78E5,A5AE1E531B225767,41BC585B98D6D254,21B5C371733127E3,D9AC71B2839ADD74,C865213FFA018F87,00000001BC863896,DBCE7AEAB1CE978A,A050E7AFEAD66270,D30BBF25777B2873,CE7361BE4350992D,97DD3E89539EC321,75F8FDEC368FB80D,ADA67ADA553846AA,EFD6504931FF85AC,E5E84EA3C413C62A,000000008F88D2CC,52A1054DFB7117D1,0CF239D19C0E4250,F9CF19A2BB2392DD,72DF8C1502D0CE5C,12F79320C06B14D2,BD6668AE2CE5E773,04FAE42575136756,DA936F6F140EDE25,9F872EC12491BE6E,000000009A8BF5F1,2D6B63AF60D2432D,B79A3B8965275DCF,F493B99C5B85AEBE,83F3FAAFA1687B36,5B9151BB3F62274D,41C445D946628A8F,C52C64DC85683F41,41BB91FF95E6B913,428728DCA89389E4,000000018AE4834D,113B926E7350654B,51AE1B74A297C617,3D3A6BB7F0B9F53E,0EA4FBD8BDCDC1B8,F3CBEF2730A99119,1F8771D429B8ACC2,35BE8229642CEA31,90851AE086F5A479,BF318325AF653FE4,000000011C929C87,FB41CFA483B8369F,1F3329FEC62CE7BA,3FA0C157B44BDFB4,2DC687367EAE37A7,28B98CB2991F1094,029F44CF011604C1,4D2C6D7D3EED20E2,4CD39E5B425F75E8,339075F6DD0D219A,000000000AF010F5,50C1FBCC398F7A46,F15294157F252F88,46E1687570A1BF25,8BCC4480D41C8581,991A00CB7242A48E,2A05FB470AC8484C,35D74081DD3FC625,0A6F624E34A5DDF8,97517F70BAEDF1D2,0000000133293651,672ED4C380B4A478,CBA1434C32A4EFA0,64B75D0B2539B47B,0946132CC848CC63,208F09E8E3D96D1A,AA29F29B8AB2652D,6A674DC0AA6CF713,1A54F048FA00DD49,D3A037E69E05BEBB,0000000247351E56,533B5AEDC1F34854,D7EC88C1D7F07D1E,7D2AD5AD137CBEF1,A73C0EC680B10982,F53C0899FCFDCA25,15C7E1FEFE1BAE7F,F98768E65536039B,2A8D2CB57352360D,D3FB79212551F32E,0000000121B871D5,1139072CED04937B,14B3C0FE63686DED,8FF77B87FEE989C4,C0DFE35B41B444AC,F6FB369DFFDB5B19,5FC571709787DF55,A6AC2AFFFC6EC263,0D56BDBEF0927201,5C604EE601150970,00000001D4BFA23E,583F0D5BE9E8B33D,5B926FA4D4FFF827,E7EAA4E37F368AD4,43674BD4A18D58E5,781FADAF92E1DD3D,028A16C41391874B,7BCC487E97BDDFED,8632AFF6D5C74B57,82344A6E6B10406F,00000001E17A3D53,AC4155C0D9059CD2,64A02E3A1434CCAC,93C66DC07AE46F48,64B18A038C9206BA,5F60EEBCDA6E0666,2D6F47F95F518E3E,2BAA88E018839011,01A086CFB9915F64,AFA3DC7DD6E6C35D,000000011AD7970F,A683DE84F5D026A9,28E2BBF9CDDE4593,2B4F590C06E1D7A7,ACEF050A81DFA61D,CAF927482E693568,24728185321BCFE5,2114B44B4C7D932D,6FBFF31667845DAC,769B28883720EAF3,0000000036808470,9DBFCE0AD6956695,C1BDA2BD8170C5E0,0FBA0185A2C6B31C,F8574ED9928C8E3E,E5BDB3398BEA41D7,B6BD1C8B507C8C47,17A64D8BE84F3768,9A8484FA11C8821A,505EB61AA0CC1A8F,0000000062F31BC0,1B2F494ED744F870,C51D661CF261C251,8D12F5E505C9CBB4,17F4C311135FD732,1BF531CB35B03E06,43309BECCD28AA15,B64C7CB323CDCC99,EBADB538D79BF5B7,951D8E5EB47D0E6C,000000017425D4FA,55F55D680DA2AA4B,BDD427488863E69B,212B72457BDDD805,0630AFB321656408,EE385B866A0B5286,FD7D9DED2903F4A2,26108B5022CC6E92,EB368BFADFBBACB6,B9A178D02F20E936,00000000B682348A,E905360F01DBC17A,535972BEEFFAC9DF,D7C5FC8F72551327,1CDDF632378F679C,202A8AC91059A606,F79DDD78CE70F5EE,A7127FF0163CD6AD,DAB314F3CF79E10E,6996DC1B3AF18C1E,000000017B389F94,614EBBE30417A7D2,707A83CD6EF2B87C,931A0AE517969197,0BBA7BCDC57AE652,4281F8BE6F01D6F9,57631CA4018E6DE1,0E29C421233E4574,3F21DF36836C14B9,00E675A262AC6F29,0000000103F9B90B,C63D6A643DE7DD90,52D2C417A0D81B94,D0EE844965EFB2A9,DFA6F8724AC3983C,41B857778C80B854,327C1AC751469AB2,947FA87864B1D9C2,1D213BDB38CB8DE5,57A859A1907023B3,000000012403CFE0,C18CC71F2CFFFEB7,670607175FC1E76D,DD00570ED486FA85,001F812EDAAF8140,95D3EFFA7F5A4D3D,E613C7B28C72C852,D5F2B95513B0CB08,B3519DD345C33F20,24524CB873105431,000000019EA2AD28,DD970C588106E498,29D121C1F1ADF9C1,92DCCE5B87F794F8,D85D63B08B117D87,FFCB120DB805F5B9,864EC07E315BAC86,3ACA942EB4D1CB43,F778DE86E9D1960D,36510A97E0C205AB,00000001D4725BD1,19FAC2C55C334B2D,1C69A40D8A8F60AF,A4FE263BDD08C5A8,7E5343156B01B7F6,C5A6F9881458AADF,ABC05980D6F6EFFD,E828E337F8342481,036FA93AFC73B8A1,E22F7280E7A4B345,00000001241FE760,D06C6EAF986B58AB,9AE66D1764FB3315,D23743E9B82E21DC,A021363B088848EC,881078D3B5758792,A63C9C7EC362A8A5,B3F12F916F76B190,54076866E9597304,C0C2378ACEC45A24,00000001D3A6D4B0,C3D352090D95B6AD,7209CDDD5E26E34F,4316A8FD2731F649,DB591F3BE90C1FCB,FA012AB1FAC7592D,59A048D7386B189D,1597EA8B01A2EF49,13402869CE84CF72,BE46C4284DFFB421,0000000165FBF9A3,D296FB0F31355331,544CC229ACA859BC,9ABF9103AE15CA1B,AB8F3F821724DCBB,680420FA55576C3A,A2B851763379E56B,FD693AB494EE0B9C,48B852C153AE99BC,932DF7B36DD18EF5,00000001FB994B14,66D6FCAA777EF164,9E1563B5ED0305C0,7A78373BEADD80DF,126CFCE86494D0F1,607DC62ABCF685F7,C90C296AA03BE816,DB0BF5B125DD41FA,9259141D5CD27E2E,FAF9066AABF87FEF,0000000229BA2922,942B9F587D51E6EE,BCBBA32018EFF856,C7D5EC84DABF5FDF,EC631673D66F7AC8,572DA5A3ED05D7A5,4305F43F32BA3A86,042DECD11BD8421D,61CC5B620FB41ED5,08DEF03793456F39,000000018CAB8456,47501C4EFE1B2C71,4777CC8B72607622,443DE5DC647F61D5,A972F9C68B76D1FB,A89DDE6501D0A2B1,7EA66C08314F71C4,D3F5BC4331C5F444,4B4537455A53F7C5,4620CE6EE41B445D,00000000119F1816,5A9FAC8D044F2B50,B8D6B3B21FA051C9,10F22AF1215984F3,10F93C808F23DFCB,40BC4061B462FDA1,5AED2D2C96428BA4,8A04E3EC04F4A93A,72FF270A683AA7DC,B30EAE0260EA39CD,000000000EF750C5,5E01C079E92024F6,196C84ADFAF63B36,40FCBD4B544D0D4C,1B3BD010E51E83CC,C48D923D12E708DF,590725458542B7E5,39DF02A0237A2EB6,845BDA2E37320DB1,FC09BCF019E80BE8,00000001C766BEFC,238881B37A39947D,53A078C805126AB4,395D8296E88ED71D,C3A4F3D39E8B5284,6BA6DB2B5560BEB4,CBF27D96ABADD74B,25FB9E42636C293D,D6E5C816353035D7,50B9289EFCDFD99F,00000001280977AE,464BC16B8AEAD654,57726F89406A53F1,94071047B981F324,94F851DFE86EE651,8BAC3041149B8298,A20A80DA8D3F23BE,E2C07D29DC1D1DBC,BCC4AD4161497D1C,CA2649D4A00930D8,00000000DD2D8936,1288CFE339DFF267,4549CF1B1AD981CC,855BE128E7A84BD1,192012566C41C41B,ED6A0DD4EC262D7C,F88C44995D429C58,DD16E02A02BDB303,1FB8A03A020B67F8,5997A3BDC6AFFD9F,00000000C62B6892,2E049F8E25065520,C01B6EDF18DF2D64,9776C342E527EAD3,8ED773631E4430C7,E4FEB3E97DD9977D,BBE40B9C87912672,F6512CDBE037D6FA,4172E2E5A87426DE,E4C2B219A5CCBD69,000000024D3B1899,0990029805F8217B,DED4AD2763A49617,49CE4F7CFD5D6515,B51168303765BF8B,7820B0BBBBBC9931,F3AD3E7AB081E3E4,AD83ED0F4EC307FF,E80FEA033FB3C08D,A045F583FF159B6F,0000000021C48158,42DD05F51F61A91F,F2C9906BE62A7A6A,A7BEEE0526E80F33,9AF44652F6F23B00,F55CB7EA40A8A507,B177B7953A792517,70F81F2BA2CCEB39,7126F9A57F993585,9251E3372C9C01BE,0000000117FBCED5,0D0A9BEA95BBA33E,DCAD17E9D6B6EC4B,C19124C923A3EED7,118570F4642C8400,F04549F565EB2375,C25003CF7C8C6443,2F6CB3C38E9EEAE4,E9E0D06FFA3AC5D4,B90229E4AA08296B,000000014882B0BB,22F20353EFE303C1,048C9F72F0B54D3C,DF08381F3E8DFCED,E93E99866443E8A3,40B4D78C6821EF7F,13C08D29A887E673,8C6BC948D2A82891,0ADA2167628491C7,B1E44F02D8B88A34,000000005724CB22,6FDE5CAF05F75CFB,44504331A4922959,303B69E6FE8DCA21,2533E67C83426A70,D0271C120961A5AB,ACED421C7AA93F4D,8116486377AD75C8,CECEB5C755CB9F78,58E7C20CE8751D21,000000018DE65D4C,E51B9C628F0F5448,32D8A0DF76BF83ED,8C043571ED24AE4F,6000A6D2203E62A5,3FA0B6F815B2C542,EB897042D3903790,09B7267DAD4CE363,18985F0F492BFE4B,4F4CEA13E2A01EE3,000000000C6F157F,520EC06A7AF1F795,B006BBED6053DD29,6BB582A0122DCCCA,70AD713AA01D94D4,9786925DA1D01AC8,084A8D49E299241B,365EA36E1F4E74AF,466C0046A06077C8,077DFD77F2C2FE08,00000001D383B258,D25AFE6FDD1A9EEE,51D274570B7B515C,4A62695A526A660F,99CF4277D9D7CEB5,3E70EABF7DB49691,BAC877FA12843559,B83F93CD399265B1,ACDFFA854A2BC282,0C0F8713DC631B73,000000022949F8E6,5E9C566BE48211BD,7A4116355F86E96E,E08E5930B7442169,0CF5889C8FB34420,42347CDDFE14B417,165AEF2563FB06AB,E40AFBFFB71AD4DB,4623BEE7D4A3693F,990BDE857B5F1BE5,000000021E850769,82AED4ED6491B09B,E8AE04C76D7C27BE,E4649006EEF8C2D5,C0A427913DB45F3E,A8E403055C74B205,DB96EA72F4AEFA4E,EB51A44E56F3FCD2,718E86DE631A94AD,8F76CEC8F1683479,00000002743528DF,2A753B0D6965BA8C,985DFF52B8E72EAD,420CC06A7CC7BE0A,1D9D990DD40B4F96,56ACAC8826581578,34A107E026D2CF91,D3374346156F580A,E6148B36C416D420,BEFD877478AC8CA3,00000002519263E8,C3C2DFE4A9A2E8FB,E26139DB0779604F,AAB90B703A1B31DD,D0F139F66C589693,4FBBA177BE767586,C613AE899E69D1BE,D3730D38193ECF0C,4723C2A705F9F35D,1D5795E8E86D37D9,0000000120E38175,1129184E5CDD1220,E8AAF7BD1122735D,E1BEDC62D6A7AF7D,E754A0ADF0575EDC,C94FA7618845E049,0322440314BF799B,013F1BCADE7BA503,F661E1A5857FDF99,C5C3F4239D0A480E,000000008F2A9D31,F3DFCE15BD3B96FE,D4FC91B3D4969E06,68DB1F06243DAAF0,051112593312519F,A365304EA37E57DE,C3641FF50EE1D286,E1CFF7619F34CC42,0E1E3D8114E71A35,6F93C4DEF71E52CB,00000000A7D4BA48,350706F5F8918471,A464CAF34F6C7FC4,2706F87ECFBCC6AC,70C7BF9FAF306BF0,C33B226E59A02135,606F6B993D7648AC,BB22087781BF2468,EC2BAB374CB25B7B,42AA8229BB900E60,0000000050A8E370,C025F0CABA48D4D2,DB68BCF8230D51B8,18DAD66DD978BA22,4659FF33C3E4D02E,2D6718DAA29E4043,7B57F4E1450B22F9,00D394D88208C5B9,008E758034A8B40F,617AED7BF5A0FDB7,0000000117CF4216,B05A6A686EF72533,E1B56576EE963FCC,4FD1280F188427DF,6BCB7780A3BCE929,A32E805C7D3C738E,1CAA55211D1B8E13,13E6EB1A9D365FB5,09D08A343998211C,7DB4DB92B8A49EC2,000000024406AA4E,717F26E6DCC2875C,F055527511BFFE98,8A33A40E4A6E6378,A1102CB45F177AB1,EDCBE809A80E3DEF,188313685F9528F5,ADEABDFDD4E5AFAC,30234281699D5E19,BE990CC4654BEED9,0000000061870DD4,BEA05BCC389C0876,856A4F59FF6D98CB,6B1F12F2011CAA02,ED9D4D75C7896B18,E563B13DB0117211,6A00AAF0ACC8E0F0,6AC88B4C4F31A39C,58F31C4784E6A6EA,7114A10E1C95310C,00000001D4FD4974,E7C169CB0E308514,AC4F48D4AE9AF2EA,2597BB62D62EF6C9,4B27D42E49D907C3,94A45EAA3E997A4D,64305C20BF49F199,36A8A05C145A70C6,8C41C8148A87CC64,166CFF3A0C40D599,0000000137DFED4B,1ADA5A5BFB00711C,6F2043D8D98E14FC,5F70E2F75C57C77A,4B52C765BA7341A6,D64B0D39BD9F7C22,E4A54EA3C84A3437,11301FFFE284456F,6B079689B4CA18D9,F07F71907380C7A9,00000001B0840B53,0BBDEA374127F8A9,7238591E78903DF7,99F58726C151F0E2,4F60F1EE0B0FE9B3,8A725FCA52CADE3F,E181A624A000DD6C,D9713DBDF23D937E,8088DCB0B2811AF7,196C13954841F3D6,000000002DC3CCA9,26EF4EB85524DBEB,EC789FDE1FC977F5,3AA9E9BFE75A6B56,A4EC2EB66F9AFC39,B6079B6CDB1D2076,7EC49374F36E2764,EAD414CDCA5FD55E,448B78662CCEF255,FC31644AF3A38D18,000000010B50A6E9,4E3DA9762E5489B1,DE5E223C99E23B34,2F787B5C6B7F8208,5B0B3131FFF1C1D1,7B5906D2BACE760E,833F4928075560C3,F36498F2CE6DA330,75E46D57FBAC594B,D5711A7B26B40CBE,000000001F1793A5,F89BB8A7041B7BA8,3BCED587F7811F20,ACD630B606338865,AD9D72788465D54D,FDE39EBFCCE8EC1A,374DFBC53FECE15E,3BAEE706297177A1,2F328133DE407960,0523350250EB8C81,00000000DA912192,6BA0D68D2AAB8881,A4D5B5551BB66674,55CE8F14F3FA104D,ED19C77C65C5EDE5,A6D9BE02C8E82338,807BD5822F422873,AB92FBED592A2417,A044902B839D4291,B186400E06AFD8A3,0000000067E02696,3DABDB159F667DE8,6135199724378B85,DFB70D8CB211E230,47F4F4F48BC3E238,9F82D6B28F123F64,5219475A44D8DBD8,D352C56AF3784E3E,A38F502C29F946F0,B44E18EEFE4942BB,00000001B4EB4BB2,1652329040892CC9,223F71A54885A30A,E9EBCF47D9257055,6C0DC701E67D733F,2CA23AF01DAC5020,D2509B86C7D6D565,DC63F9160D3D0FA6,B4E9B8006AD84F52,509738D86E466419,00000000480A3BCF,48109AE30F6E7470,E5A0DFDACA7C21A0,25FE4C39CC6A20CD,6974425685D331CC,108E796A56926185,4F743BB8CFD2B243,9D2145B8845181AF,416AD9D5102765B9,100EFB645069839E,00000000532EE4A3,E771C51DA7347CBC,AAC22AE764F3AAC3,DF28B88FE2138219,67539945026659F9,FD2C4291E496B702,7117802C5AFC1105,F02BA0EA7290E632,CF0AF8028328BA56,369E17E5A6B203A5,0000000077946020,654EDC39D64B7AA3,D195308710233084,BAE17BE41449B5D5,1E68C6C476F9D04B,28551D02E46BC7A9,3D536B8EF4B776C3,AD2454891739083E,991329F68AC2A85F,5FF2C1AA8EFDF694,00000000E1A3098D,085823D5D5A745F9,D0D3AFC671716BB6,76D1FC03E88AD733,48C423155BC90CA6,0CC94203AEA675E0,5B213ABA03326CDE,8EAB0765515013A6,1DD5368DFEC990A1,91C2B09314BB2666,000000014F0793D4,9C74B84BC33DA6C5,8CC718DEC77ED2DF,3C7BBFFD5D6A1CC4,652DB443C90C2644,3FE12C932C693BC5,10C77EADD8FCC6F8,9AA6A27E11C7BD0F,35A45DC4351C9CFC,7C8AA3C3EE4FDCA6,0000000228C4EA05,29BA1924C148F8D3,B08BE7908DB7A606,6DBD959817042F17,43E5CB438D18E924,3F8BE049105C1A0E,AA27BD80526EDA30,82845B9A47C002D1,C822999F9CA3EC6B,2C0C3DBE07FD91D3,00000001571C7A73,B09A3F9F7ACEAEF2,DB702BBC83374AF3,4AE9EC67385A3B42,FC36462FBE637B02,8A8868A929B38F69,BBBE61B2274F1D8C,61E17BF8E45E863B,7475A3A020210887,24CD44A0CC02C3B0,00000001C9ADDA3D,633516A05B150F09,96A6ABA880DC78BE,BDF82D62D2454BF5,774A7844C2FACB75,4FF63BD87B2F6B52,7D7DB2EAE98BA7C2,92B585B96AF0A0FC,47AC88E1F0B5ED26,778BCC546EFA722E,00000001FF4DB339,E46EF23856E9DD7F,2C0A8A4A1C55388E,663B700550470B5C,1CD47FEF5E21C9B6,A47FC4416130789F,50A7E11FFC6849D8,186FFDF9C04AD9FB,738AEAFEB4810E45,A9D1CEF15666CF5E,000000008DD1AAEB,8C98367C8B4808B7,72BDBD9A40E92308,11923247D961F3E2,0C34C0EF92012D6D,29C843F336EE0D20,BA05D59D703C0F20,C7E7EB8BAB8344A2,26BA7C9CDB0EF9D2,795DB9CED98DA08C,000000027009A92E,85050D64348AEFB2,F728835864FC2328,007A5297C5C20D5F,4240B5BC37F7C6BE,BBCE0EE42E29749C,79EE8CC5C00EA113,B38574A4ABE6756D,EEC506E7CC4FB921,952F89200CDED4E5,00000001DEBA83CD,20EE964F70ED9271,F7E2F47C8E5553A4,94564986EF0EAFC0,C154048F7809D619,96592780A71CD039,16B0D4776AF54658,DC516F00A0EF4451,2B128B9FDCC54C1B,8BD8BB2FF78BD3B6,00000000EDA129EB,CA7AAA5457009EE0,92816A9485A17AF6,54A504D6EE2C7A29,853F60A82B0EE3C7,9C4CE4CD53297F26,AF4A683798FC7ECA,9B8D9FCB223EEDF0,E14608E97FBF529E,6B65A176608A38BE,000000010FB0A76A,6892D1E0D8C3450E,4A373AD71DE234DF,E80B42DE6250E183,761F8226CF3678D7,256A5AA7DFAC0AD2,A99BB8EF75171C00,84AA14FDD4DED56A,EC78F182B6BE212C,81C0684E72AABC4C,000000011C409EC5,42A6CF18ADB31388,D3B2E4AD002B2193,C89A0A3DCB75EF3E,57ADC7C898438AE9,B273A6CE6E76D1DD,07CA4C9874CBBD56,42591F7FBA7060F8,ADAF15CC27F83645,9238AC89E0A4E681,00000001D38B9851,B82ACB2E7DDCB949,FDDEB33C1C336A28,5F04182AC18BF075,12EA899C006C32B4,53FEFE96556450E4,A13963A62125FE00,798AEC679433CE28,CEE245127E2CFF52,6648AF85ADBF5B15,0000000155CB1F64,70FC2BC3F0C9F7D3,EC23F3CA0ACF625B,E83FA7BAA2113282,74994D3D22396AD0,07A3642E97FE75DC,247F9075CB7F4B52,79906E7E82F2CAE4,87E94CC34F4E83A4,50C21C2741B4E439,000000024A62C071,1238CC427D0FA4A5,67FDEE092D1379D8,C30A7EC0F0D559EE,116A683BE251BEB0,80FF84B374B0B4B7,E0995B448BB835B5,9574D836D9919B17,09C39EC0604878D7,0C209720AE16C3BE,0000000036AB5047,A3B8767F403795D1,20BBE5C51BE279C7,BC4B3BE3B8944730,7C2CB193F196AA0E,ED1B553B4CA21C16,36FBA2BB84C456C2,762D20F8AE10C204,DA422D41ECFF2F9C,B229E34B56369DC4,0000000057B36E67,4BB9241EA7474EA1,37F6B24E1749D0B4,E510E09846100E81,E1090CE9713A229B,46C6DE74B3FF0128,ADE6D2E94FB3B23D,50C197E254135BC4,FFE23F25B79FAFC8,19A4186005E7E51D,000000024A4F44FC,5DE5101F16E500CF,E08F1D49B23DFCA2,178E6749FDE4488C,4F9465F6536D11C2,8768F9D4B182FA3F,14D8A7ED9D48AA86,DD03065F771D18F3,F046015B9D917B33,988EBC842CDC7FB6,000000013799207B,4DC02B5B5BA535D5,B77DF2C89A4CF49F,7E382E26783A5B4B,793EE7E635E67E7B,7DDBE61D541114FE,EB6AE79A36818B39,43B0D1C6C94796B5,C2E0C286A16E8E82,880C6578816E0457,00000000187FB609,482593BA11EA9056,C730B9FBE8C0BDAB,0D4C16365C95B35A,A2AB058F5DBADA9F,459F37E0F1C0D875,33A9B6DF9AFF033C,E2A8FC282C36F48D,A3EDAA5B3C0CFCF5,0369800F227B2023,00000000122A7459,FFBEA327288F07B3,6D5F9A4A298FFB61,03328CB70801E212,411879BAF6DF78AC,CAED0B6524063114,8484AF00D08B7988,7B1DCE2E257B41C8,0E8B3F2EC8C9C310,43482F1931FDFC50,000000010F1F478E,5BE074521B43A693,0A0B28FD79004BFD,B4CF24F456B21816,6B0074F49C429788,4E5FEA937E4AF22F,ECA398C22A78C98E,FFF23783DF508C87,0000574E058E9AAE,12B116F0CD075480,0000000086D9978B,F857A4FEF5A7FD87,B49173A598866AF7,9636CB958DE44162,A0D58E94102A054E,B8DDE4A0E2FE06DC,60D2A0E571230189,65F6058BA6A1AAED,2986A3E92AA64B5C,C111336A85E08B4C,00000001AE4E15D2,97E898AD268BCD2E,E69644AF5FA2EE54,ACB186203FB5ED0E,2339C8C11484091C,9F7DEBCCFBF94694,113FCB4162ED2F58,AFA7731B5932EAF7,51AAC6BC4BDE9918,79AD7EA1B0F60A4D,00000000B7A3A6F3,7660D7E0D8A0E173,3F70E929BB39F686,9F8B08EE097EEFD8,6C65FCEFCC403143,935AD4655FC9F129,A899F6B9CF9216D5,1FD8EF52B8324156,78C84F688F2B65E5,A98E9C45ED872C78,000000006629CAF4,E057B20AD21FABEA,002EF52633295AFF,5928A4E856304547,0DCBD63DE5B0AD1A,745B259DE27DD2C4,90062FF30A6C0A43,7C53EC9C6C30EFD5,856A207670656C9B,7C948FF2F213CCE6,00000000E2B9DF39,269B7B137B16CC63,7CAB84AD584A10FD,8C3E6882945B4548,6E19715A364389B1,7AF5837F3681297D,26012142DF95F9C0,E6F9CB36CB888A39,DACFB932269D504D,281FFF9B1A44990D,00000000A57F3A8F,FC54B59C4CB61A46,DC45DA3D5C7B9A12,379B1C8D867FBB7B,B697D28FA2D092C3,1D2A6A838D5E3530,51CF30288B113189,E654875034BD8A7E,9F5C72454FD19BAA,F3191826F6F2700C,00000000DF8D107E,E257456FA54DA129,B93C9CAF2D6237A4,272FA75A21A2810C,83360E816E88D159,A594C1FC48C2F1F9,8EA9CF11B79F2343,6AA0A3352ECC9F8B,AA623806B6AA75A0,811A610B06C1FEC1,0000000044019125,6C8CE11898C6FFE8,27D9FDD74AB9EB7E,F301C7B2BF515598,5D3D2E0F657D37EA,70511D1FAA762885,7963EEF8AAD8A082,7180512CFAC071A0,CAE895FE8184A347,BFF9EDBF3732EAE3,0000000008F40967,C7EE38F135BA2A5D,715AFF1FEC926A36,FE490CE85B82749E,212ED79C8E35EC16,953BDDF79FC485D4,6EBEDD28712BEAE1,54D59911D54A80F3,0743BEC1A68CFDB5,B8DEF14F627B1DA3,000000006A20ADE6,8D5C9AB68145D348,9168BC684F597364,5C152A03469506A5,450F05585C83F4E3,0F1B34EC70725C5F,DF5D9FB81FD2E50E,E871DA2AA069AF96,63D0593B1979C57D,DDCFF8517DA173FD,0000000190594365,79BF629712B6B68E,C2FB23771A77EF8B,677BE6D552E6CB0F,FA1923C6FBAEFD29,31B8ED44EE9C8FB1,A625543204417FE4,1901D026AE304FAC,84AFFAF0FE88E113,FD1798D9CCE4F8C8,000000008D061872,DAB14F07FEEC74B1,1F4FE8B4569152FE,6AA8D6F73C815F52,E2026059AF521E07,DF7040C6D2F86B2A,8DA8F9F54BCDCA5E,8ECEAE66B75ED241,7C838DCC2403BEFD,C8C99F10CDBEFF95,00000001CF619765,E1F22CD1520C406A,3A9A2644615B50C5,793EB7DBA9E3FA03,68E414B1B7D5102A,AAD977A8594E1AA6,251DF30B8EB794AC,96EC3604C79F52AC,30E5BE5E31831749,5C2B9A1DD5674A02,00000001449EBB11,D705E5D107F35B59,2197D4F72A4335EE,BE23C305B3341C52,C0E426CCCE96E20D,0818C254C180FCCC,86CF8BD092801517,D05953BF90E153C4,8B0E8DD64227B694,14B04E14B078F007,00000000FAAD4DCB,30BE31C48D5FE7FD,AC54A8FE0663378D,D151C953FBFA18E2,58BB179B9DA34F22,F389E29D45A7F842,D73754EDB26749EA,43623622548B3FCB,8DF5424265DC99B1,69DCD0E63794805C,0000000114DB73E3,72ADC059CAB3AAD8,4F3C4759290A87C3,A9E0ACF0363A1A66,F184D47AA69941F4,20B84E67CA3F51D1,BD7572A16B3E5593,FAE7568A0EE44179,6739346EA8D49F32,14E4B866BA706D60,00000001D589383B,ADF860F48D1E2705,86B41DE90F0A976C,BCFE624A6BE2FB1E,8255D661A7E40390,8EC3997FECA00889,60E42CEC0BD90F46,E9EF668F88332200,57AE558819CFBB17,EAC5ED69A6309AE4,000000023E38C4CF,C1B151CAB2C1A848,93A9771CA5F87BF5,B24FD025378AC045,70B9CF1A750F8EC6,0918289298AD1330,F11BDFBFF997B45C,DD19E1675CA77DB8,FC74397336E1EF8A,C30F84C89D4D31EA,0000000178DABD2E,3B334F8207125C95,5B69996F3FAE2D5A,088D6D1718258982,123376D72AF43A30,B4484FD0027020CA,74BFEE4FF4ACBE17,F34DF31EDBFD74DC,81E8E76DD424D5A7,DBC06E9D9A0347B3,00000001F125D0FD,725994B3C23DCFCC,41F6D171350803F4,C361CC634F878592,0B97A8F6314CA3E4,0943951629B0C52B,7C277E9F89BF807C,8BB980C514C34CA1,FD777C2B38B6681C,8BFC0208DE6EC8E9,00000000C523A8A7,7471CEDF30625988,BA404C3DB39DC937,F8D289103E03E440,51F2C7C9E5BFD5D1,CFCE9063A9C5F49A,1A113217158EEA3A,E3712484EC1582CC,7040C6DB72B43CAC,91D260205305F5FD,000000015B6775D3,CF596D3A5B0B8345,357B45A4200F357C,DD1F9CF99217FD05,55F78C0BFE1774BE,E0288B18A52D26AB,6C7C4BB14FFCE23D,0A5BA5AAF31C6393,D96651946D344DE8,3EE157FB9E8B8A94,00000000A89028C7,BECB46D77C0AAE08,5E8304C1F5E6CE38,AB6719D6D8CAF7DA,D69D4F25906778E3,45A8D604B63FF9A7,9AE308690244E1E7,B65ECDCD8A92AD67,5354C7449B42745C,50634360F84F8E10,000000026A2CDB93,4F9C81F2D3608E8D,745325BD6A538D28,D10430C3BC33BE84,B63E0F91F429609D,6EDFE38DD254A432,A3F13533E7EF8343,DF0A1CA1EB62F3F7,0BDDB65ED3F454B3,15CCA2400DA4F808,000000001418A772,0CC513D21F058473,0EC524BCE2CF9F2E,2F357272B1289FCD,651D1AD7FA47EA10,7F75082F45C30B7C,3AE0EE85EE8F7813,1CE3BCB47BA89C38,7F8A8CC0645329C3,EF59076CB0B6AE3E,00000001CD4D2DE2,911DB818F99C8B49,0800067408A75C7C,4020529945E4E420,801382E8F157F32D,3BDBCEE76FA49D4C,8AF35D75973DC698,1462C10644565A70,9F86F292039D859E,911A1A2DB4BBD1F5,000000019A30CD3C,14FE4DBEDAD4BD62,E08A478DFF0AE4C1,90776C83052D42A2,18489182D71C6E37,EE0B167FC813BB71,E7B77D74C26587B6,FB2A415E5F0BC629,EB8A36F880EA8125,4B0EA2C8342C5C09,00000000908D888E,C2ABEEDDCA33B1E5,85C3B981D1B04D33,E690AD1207E4EE68,24C68CBB6F8A33CD,33BCF1FC06484EC4,BD51936C55FA9A36,97E5F51736F1324C,269397869C797AAA,424EAC4690830EA1,0000000052A15BD5,C0E59A102C683FC5,3957A4C6BD162480,9FB8FD9436150DF8,46B81FF8C5A3FE04,75B402D8C7706738,03321CDBD64128E9,274A1D4BCC146282,131BD5AE71E2DA1D,4D7F7F5C91887AFD,00000000AFA0EC6B,DCCE5F1630F5D786,7B3393A59424B3C2,D89E1F6932B36038,D401A9AED5F7F84F,FC3E695968D9CCAC,0C1179E3DC737A9B,7B2222C96AFD86A9,D68C1293EA178229,C22C40B1A749011D,0000000279E00EC7,37798AA575457CC2,9C47B43EB35861D6,1C7A55E539A568A9,2AA9A7E56DDE3526,7A2BBA5595962272,456094EB9283A259,58B8403CBDF0CAD5,1F6127FC1C0822FC,A6BCACEBD6472F6D,00000000CE79633D,BC714405F4AC64E6,292D7C67A61AF3A2,875D8AF57EEC4DAE,65039923C7639416,1860733F2BCC472D,F7B35A838468A5A6,24FE8B901421B8F1,58B91E51DA18924C,9E445B71E224D2F6,00000001D2C723DD,AB6A2733F8A681A4,1C8CBCE8D747621E,D648650C001A4358,57CBEA1E96B5D2D2,D410DCBFB412DF59,B63BB33273312CD5,24F99DA3EFA70F7F,F45A5EA60A13DB48,18EFA6B729D60687,0000000203B37BCE,DF3B5DD8F0C6BA7B,5925DE5AC6058D9C,0E0566BA71B0E441,F4FFE39CC1A0A108,27B917F8CF5C58B9,B2A73F6F4CCB0AE1,4F806E25BC821734,54A1CD1CB7560FA1,C79FFD65570CBD4E,0000000219B4CD04,779692681A83DD26,AC7C57111C012FBA,FD7ED6FEA8BFEAED,7FF465919EE6DA2D,3B876DE8F79BBD0C,095271E94041A64D,8A5B0B7AF3109783,37AD0697E25348F6,FD65EF72CF920E1B,000000019CD2F207,B4C3F1F67CF5330C,19D1721A4A6E1AC2,E989BBE59DF3619E,A2214B4138794D41,2F2D4B316479D728,089794719D4283D6,18C9602D8F2E5F02,6D03F5D937810342,CDF7D81D7DF824F3,000000018461B168,C52C91119DD9A138,6BC47C5A365050A8,6E90C8D856CD8646,0CFC0412A34FED2F,073FF0F2FEC0E459,14B6B5228B8AA78B,7077160F70809390,789FAFD81908DCDD,48DACCA9569B8188,00000000A67F42A0,209B88B0660A3849,4CB17F56D993353C,7612EE2B5F7883D8,7DB076EC42F96231,4693AC0774EB48E9,EBE1141233A6311C,C0DD37802A73D984,0C238650C4BE9DD0,FDD6AE9126240F2E,00000002224D135B,64912EBE03F5DF78,01099FA5972F25D1,D6C77BD7D61B1B3E,BB6B70D59514DC55,44E502456EAF48FB,38841114F3F95CAF,BBC1121C32894212,8D5ACAAA07AFEB28,007FAE0C12E00302,00000000F46B1BA2,568C4AA488AE0324,221D610DD2DA8A61,79B55DEB25BEA826,30D2ACCF01D4C6E7,EF7349B242A517B5,705501DF1C6D4D84,021F8AD20F64544C,15328A6E84C35157,BA88241B8D10C283,00000001F3169062,88EBA118D2E3F1CF,9A71F1822D167980,B0E03487D9921F59,907D03B4B827B191,C9121EE4DDEC84D7,FAD372B0C6A91924,A36893710DCEB812,29128146C1B04218,974913408B76DB64,00000001BFBE3DC4,F4C14B9D076545C1,3D27280C5F6CD18B,0A2DB0BD6B858F34,64771349F91D47ED,8F1866F5BA88EEF5,7124A8D061DF9182,D308EFA2FF004477,35AC886EE1B0615A,5CED1624AA6AE0E9,00000000D87AF856,B890F64DE7F44CDD,75BF007F08E4F885,C38A9C55016F3032,4EDC111F8AE24AFE,C21D8CAA5F016EF0,38E9FB99F3113ABD,1AC46669B33D8BB0,F29E878BCD1BC94D,3FA87A666E5CBB19,00000001828E5C71,780FA1B76871C79C,281CBB88ADA8671B,CA124E1C8C609E76,7D3AEFDAD0E209CA,EF9ECA86A449ADF1,C171F350C465C55D,D6682B07C7FBB77E,84D907EBA510C85E,A6A1AFA739722CC1,00000000F876C873,B44E09CC96CAF3E7,06142FF9B2269B85,36C10050A0C32BC6,CE11FB3E699942C3,7239A9C774582F6A,AECF5DD63694A9D3,FB717A35D8163582,F6AD99434BE4A321,4E0FF8C1837FBBE5,00000000E2333174,9441EB432B74F758,E93BD2438AA39B22,65E57357185C7FEF,CE27379C4E976FB5,3BEF6324C520AC16,0918F6517E735DF7,438B49885D0BE06B,E95BE7725EB43ADE,CDAFF788D9195956,00000000A0C554BE,AA590E7D33926660,32B57FE1960A1B3B,98B2B1B25EF73BE3,461D8A14F906DDC3,FC7B75ADD8ACF202,338A592F46B4ABF4,2F4FDDE8CC48B7C6,AA21C21DD3CD660F,6B6D3CF7220DCDED,00000000E75F321E,C1AE9D611B0B604E,E996B8BD127D0999,6B4E31D4259FB851,C0F1D62409B24D45,9EE1C30A0C1183D0,8614D41813580B8E,114A6F18BB8E8B67,3FC96ADC43D7AD7B,0AC8F0AF6067CEF5,0000000031FD9B5E,E3AA6C31BAE9D7B0,8C89AD55D64E8F9E,7D43777DFAE0DA57,CD85294D049D91D2,EF040213A751F438,2A57481F21E81B50,8B0BD7FA69BC89B4,1D0F2240FC120C7F,2369B9CC0C8A1456,000000000E729570,DFA4FF2347DE1114,BCDAA0A4B0986400,14B31CE2E86F4D4F,864D0ED381D43BB4,4964F4CDFF66B282,2B086FB3FDA98589,AAD8E37460B1CF43,06ADCBEEDC176A68,55A9AEE6A1F01C6E,0000000249071D3B,6F8E08337F8043BE,EFAD2B29297ED5E7,9D6953717D24A5B9,5124F755DBF459E8,F36557E5B2FFD08A,554FAC76773E304E,54B4781AC502F6DE,A4F749257E011DCB,A3A7E396DCD6CAA0,000000022EC987B1,9D542BFFACC986E2,CD0AA54261436126,CF0B5C8725A2AED2,0EF8EBD889E953BB,C60DEABD0F4B6E3A,A7BE4244C2E700ED,9E832611FFF0FE41,529CAC5B47EBE228,E2B2325AE70AB561,000000009EDDBE5F,C54923E22A7EB713,03AEE3EC3C84740F,38FD553C5F132DE5,A61F8F984F1D54BF,DAAF715C5000558B,39F6AAA3CD0196D3,260A702542E1B950,B07BF32F38FBA702,9E5DD6CE10AFA87B,00000001C56A2BAA,ED7D580AFE32FC99,BE51A65DD9A3D752,AD55A8950C7EEA1B,1CDE2023FB363EA9,6248512CAB9DC12E,B07A22DACF0443F8,2A0BFC4987150CDA,B87992C5409CF7C1,E0FCF5E41BA799DB,00000001F821E717,F599ACB668D4CDE5,B10FCC69B5F2E591,0C74BD3734734D7E,D2C332DAFA82B430,0531E6B4F2EDFE0B,3B4DE523E93CB1D5,C5CAD119DDC4D8BF,BE06380F2D09BE99,061D37FE48405E55,000000007304D141,4952C3FCD1ED0450,9DFE30B29E19FC9D,69538EA0E11F8727,3414E0814C473A68,49F0784245BAA066,55293F6F827E05DE,81E3DC6D4E46DE04,BE072FABDD9836A4,57C0A7D0006F2E82,00000001C6B90B56,7192D4EAB19638DF,530E0E7C102100F9,A21BC2DE1E146F47,891971BC102219DF,77988CE8F6AF7524,85228C8568E3BE6F,D56E9E965FBEADE8,359C280E321B1541,15E2E77B8E923CBE,0000000249EE225E,4D1A44E40FA224A2,55B7E88FC569F3EB,FF175E06DDACEF32,4FA340E3B9CE8169,A8373C0580C6B54C,ABB32FCB3C233CEE,52F751FFCFA5B889,F11A0DA36EBED97A,3C0F7B2A1E2D571E,0000000051DB6624,0D8A458334C38E5B,E52D65387F3FBF79,EE19991E5793EB04,7B65FCE7ABA5FE6F,11573F51FEE1C576,F02E376143C5F2F6,A6FB0C37022BC806,F01ED24B693699BA,0FF827CFE63808CF,00000001D04E3ADC,F6DCD897C4F24FE2,A66FCDA9B4A41501,774E5EA58B94209B,4306E18943A4FA14,D1185CB22D62D529,F8789523959E5EB9,00308D0B681516F7,51405949154317D6,DF8692ADE912B271,0000000132B69D2C,9005AC501D1AC92F,5B35883714A22A1C,0993B61E37C30453,AC179CB1506A47BF,A940DF9E971EB5D4,56DBAACA2FFCCC25,A36FE54B062AB20D,58CFE0D2697FE88E,6EE2EBAB5DB5D752,000000013476A3AD,A984AECEA1B5E327,36FAB658A93BA213,EE78A89EB3E1EC8C,220B875A22C3AB0A,23EFEB648EBBDBCE,D8381EB2B68F2B03,60C15D9CE84A8D30,407249CDAE6BC90C,58076FE2F11557D5,000000014633B444,490C319DE585E205,829B55768F8AA53F,7A67851ED09B6480,6EB89EC47E6D2506,02186DE4A6DD3D18,B8D2CC738332AEA7,0EA5423266B79D88,9E7B4AA647B49397,17C43ED217178B2C,00000000D85132E8,AB91049E597F7B42,D81373CB247FFC23,C55AAC5D5E228DDA,DCA9DC8160ECE5A3,ECEF3DB812650F98,123E1876898EB4F1,D93FE6087809F0CC,4A5AB244C4568F5E,E547B6994C646CFB,000000016CAB4C7B,1912425942A9CA6F,DF7259099C459EF1,CB4AFD5AB504CB1F,7AB201C4DA5F16DE,3CEA9B4E63B107D4,26E78B9D739CD156,535DE72D13C11D8D,B8267D222CEF8B1C,AD3BCC666956ABAF,0000000218869A0D,E375E0B29911CEAF,F7B744AB03A0BFE2,76ABCD22CD317B07,D96DE2D50EEC5B3D,07D2C776B3D10095,C42210D656B01CC3,FFC25CB5F70E7635,9A1068875A01C540,F8167C6777A85F55,0000000033B8A122,2355245F980C487F,C05DFF0420B60E57,73839269B37B5CDB,2423F317D3BEB872,7ED47BF1F48686E0,51A5BBEBC7C4CF3E,E7DA7D16803B83A5,5DD0DF76DA9EF5F7,448AC9C8D27255C4,0000000026585ECF,98111288D898EC3A,2410CE8C0D8A8EDE,11FD022069F00D51,7704FE464527A744,482728092195531C,C9E8910409EA3D59,F8600C9E50EAE1AA,3D41DC2DF28C95B3,50988D6EA115ADB2,00000000D6E5E547,618223C287A72362,EBC3DB66CC7BC09A,3022F15F1AFCF1FB,2B16A1CD89A925A1,1A745EBCFBA77B34,42EF810B4DF10005,3173D60E3596D90D,89A06A76E4629137,D1ECD0B2CE7BB191,0000000109E59D92,0C302AD7279AA142,4EE292A3C2FB8C48,444F5F53C17EDFE3,F8C225EA9664F368,697D7733C15A6081,9201021CF70DC6BE,D1D9D427AA663EB8,36AC246D7A685DF5,FBCC9137C987F816,00000000117F0568,1D30F529C08239EB,5AF1FABFEB1DF987,3F4AF61DB28A4E90,330819B4BB49B075,7729CDB835A4F186,E6BECF5DBB9E7448,FBAF82B70A413FD0,A9A23B496C0E2C06,3FBEF80B5D825A4B,00000000D3656C75,D283612F3F52EC82,4A8B751AEA4BB07D,80F900C1370AF9DD,5FC18FABC398E13B,2DC1C2B2288202EA,054C59DDC4387C46,9519B9C85CD30189,FCE90B2DC1CCFD54,43ADDA28AF9ED921,00000000E24EF65B,EEAF9F830818FF79,377ABAFC1AF26242,9C5010E6317E491C,D49D1F2086B5BE9B,4F42C08670636991,32ED6267C839CC5D,92D456043F6077FF,0587A175143D6667,87D10935D03ED101,000000006DC470BD,844AAC1284E902EE,6FAAD86A0CA9BEA9,73539533B2CAC0BC,40A5F50E9295EC12,A8873D790ADD61F5,80F5F8A243C7EE5D,F1632869E8D407B7,07F8C705C746FAA0,1D9CDC79BB0C9DCD,00000002412AF1F7,4B4145C448C40B98,E3AE647BE86AC7C6,C189C815587EF761,F7EEB84B59DBBD9C,E468ED9CF2B1D6A3,1EEA418EF5EB6426,F6E2E5309E774E72,25A6C62F78E07092,F1779FDFB7756F02,000000026BBE3E16,2A94AE8EE182AB1B,26AB0BDE1290DE30,38D2E10BDDE8D065,1CD9857B0762BC14,0FA2F6C6A400AD09,806B4363742F181E,029B926CC303C7D0,97C28102FF30EE66,F5145A80A05F4449,000000026A6B39CB,C04F773282CDEE83,EDC695CCDFF43BA1,75B2AEED164F9D07,CE893C3CC9E2CC7E,B18C865A0BE44DB2,6B71EB917096BD6F,2431B3A34EA9D150,30AE2D3AFAB7B047,246882ABF79ED302,00000001431B7A1B,D48987FCFD4A3F11,EB707E88FA9E0E94,89A56540E5506FF2,796A8FBD538219DE,49E15078475ACC0E,51278633534DF8BC,645720C38AFA1250,FE212270C6491945,B925FCC4D29A8600,000000002F1E1299,FB9474F08FBB234E,09A5BC83C264A8D6,1D74474493C77A3B,F88DC8A53F128D80,97406C7AF34CA6FE,7625487DFA6A8163,9F11AE3BBF33D5A8,8DDAD02BA36F99D4,374AE39F2593A59F,000000026523DF50,894EF9A1B3E06A5C,077D6215A8290EA2,6752AB271A1F4E8A,EA7CECED840B0FA3,40741F2B6CCABFD5,97956B504B38036C,2A177063B36B1B2F,87D60CF49B000436,1CEF4CED25FCA522,000000026D6E458E,0204D720FE78CC61,4F904E01062E68D7,3A8B45FAA3E49BCF,0F463263350581AD,B7FB132C3FD06DAD,8F672614B0EB0F67,F3EB8B798CCBC882,7B71073EC006FDE0,F3EAA6A7088536F0,0000000228EF734A,614F8E107D66EA62,C4DE690C5247F376,5F4676ECFE22D2B8,FDFBAE0E1B82B29B,29A65E55AE3C5D6A,AC461DD5E96BDFF1,A2AA70EA3E583CF0,9CB9470610AB982B,B3D1A6B4C84C3E5C,00000001C152023B,2A76DB32B11BF6D8,6A899CA7A25D2761,71A4DD587423E760,7F017BF5E465098B,D7D07B2B3F061307,82DCC19BD147C538,D2010FF5CC8A07D2,17705174D49093FF,3F04310148446156,000000023C032363,536F7629CA0302AE,A13F4E31D1670A98,57AA98BAAEA86894,92E47523C137F999,0E8E99AC876CC266,B6A45FBB4AA0EB4E,85B3413372322018,80BE19BB68A3C8F2,F0B2AABA08181B1D,000000019B81FDAB,ED1F256F58F63FC6,59E47C7060F6548F,4ED6D59920E6C742,EF039A00CE9768A6,9E0C69A699F2AD8B,E4F4599EAA2516E6,86E95262A4C06662,17ECDFBAB322ED46,9B6F92F1D20FF8E1,00000001547E4478,451C27BB031798EF,FAFB907F25BF6F73,B19A0C68FBC6345A,0587B1B44D0E2FBB,F05DF3237DCC7A08,0536059E7459A035,BBEB1C19E4E3C268,7A5695CBCCE40D19,1AE7ED2E8CE1F10E,00000001EF787E5D,D0976F6AE11A6E1F,CF1D4127E0920698,6B97935112B7E4CE,9D8A56A38F0F5865,5BAFBB2833D9BE1D,B57769249965614E,328646721B665825,531A96075C175369,CF0468F5AEF05363,00000001D9B606A6,84451C85D499BBBD,6556EE43F6E25BBA,234D3980E4A23EF2,00F84151B9F9B7A1,9D2D71DFDB35A2F6,67F828BC7A0EF068,F988B74166896812,915454238F8DF91A,B09FC1BC49B3813F,00000000AC1B6541,C02B6C2B5DB2B5BD,333122121F450EBA,8935F36E43330D0A,F072DFC0B55F573B,2CD61036266FFB32,E73CCE1D7D315017,7A63BF79A381BC6E,8886AEC9ADE7E0C3,1B2E9A1E18077546,00000002037A0366,B563690B12830D87,21AEC11DCDDFCB46,B0418A8BAA7CBA79,7BA68977F5CFBB49,851C9F448F3075FD,C23DFC21E37D1D7F,9927C170F1D05F5C,04B1BA350A8F1982,F849261926755969,000000012ED4BF77,8A47E986A1B5C2C6,AEE2D9E7C3DE676B,34A83D8058DF2955,254AA533A5AD30C7,29C2472DDDDF7DD6,EA224A422F73B69A,B4E30F5E9F915A54,F4DA27387CAA9C88,E08AC83250BFD3FE,00000000FCC8250C,0D09A4F6D5629BE6,83F75395BBA9D0CE,1150036A752C1310,D894504125062995,652C2D90FB0EAFC0,9C1111AB2B5F3EB7,FFF7FB748D3E9903,E3B199E90FB59962,428E6FCED06735EC,0000000035EFBDD3,C8605FF85546DFD6,F2EB084CD67B6181,FDD37A8F920FC0F4,B41E8D751CD7ACE8,76A1FC06C7DE8136,47A0E4F0700E56E7,5D7544099CEC7CD0,2227424E2D9E25B0,5C0E4C7D4E56DA79,0000000051AA1A77,EC607ACCEF578511,49D9BB0888C8BA87,10C2FA96298EFC0E,EC217F684A4DC158,4782F941E1A23DA4,6EF2387E94845E78,011EC6F04C32D444,E08CDA29F51B1E92,3B2A68DFAE2F7D39,00000000F15AFC8E,A9ABFD5B4762ADDE,D8AA6DEB74053586,215A6ABBF14429F5,C1F0CCD37A3933A7,12EC206C6FFEFF16,61C3FA2CE8FC286E,58505A4706621309,A2DE722BB036C13F,BE900FE7410DFAFF,0000000084E9B48D,BB20F52680671B8B,A2C0A9673DBF0593,5816E63B3C17EACF,3C6D4FBFD158109D,0CA9851AC8EA4252,CA1323E49E423271,E563DFB2ED74BF2A,56B635EFE12D99EC,D51E32A87D1CEE58,00000000313E8E6E,6A8FC3B87A5C2C16,A9332425DA720424,169A7D163349EA48,9C9F6A6F47BDD647,9633401DEE00CDC6,0D46F3A7926BEF88,479FBE193D74C5D0,391A81B3111A559C,0B79F23B840BE85E,00000000F2923FBB,17CF9A5286C2AD52,5A5A7F9B44CFCE81,A7D675F7AFB9C6DE,08E35364CBAE8D28,A7DCE7FC9A029FC1,42C6D64FB9A51183,75188118B3A87668,67B86D5E0A1C09A4,C37771D5676D4792,0000000243385C8E,A1C0ADC05E2F940F,81430CA6E30BECFA,0162AD2954F25115,C775184FCD6ABE32,CBE59710E85996D1,2DC48512EE5ABC89,CBA8BB376CF1A8FC,6EE8334C3CA0F080,219488BFF0ABD0CA,00000001613DDBE3,A31D3BEA3C4CF58A,D24213361CFA35CB,557C055D2F30CA62,A8FC9C17B9DAA59D,D4AB7FE8AEAE912F,728EF4D91ADDF778,D2E272A91CD0BD53,CE4884CC1718B13B,CD397CF700916BE8,000000000B039322,AEA5EC470AA7C849,6793A6BDB85F1556,3BD7EF4E30851375,CAD04CC4FB1E2D41,E244BA5343DF1F68,B9C3FF58383D5993,BD06138951ECBD69,C181775E9CC45BED,5DF468D3006486A2,000000007E3D79C9,5BD7740C8A7AB8ED,1F8751609A6A7C43,F4A2FEC73CF662AC,F15D0D732F6710DD,E707E8358234C0CD,64DA72398F54404A,060E72CC530D1BE3,017CE4D650E2E31B,E51CD6A7E6AFB96C,000000001FA8C3A3,EC27AFEAEADD416F,FADA39E54D4C3D94,581F4668D43C1347,573B86169842F77D,57B1F6C6DC391831,E7F1BDCA15B856E9,95414955665A2490,8B3EDE71E925F4E6,8C033A9BA46D1BC1,0000000038AB81D7,2890C6BD090FFDC7,F1F9D48EF7A4B31F,4198CD7169EE1C84,455FBB939B9343AC,71DDF561735DE0CF,F250D97455D5D27E,346B3EB5BD7AE051,D4C5D2AC2ED38F0B,C069EE2F26287DEB,00000000D94AD772,12F92894BA1FEE39,C2EA6F27F2018AC6,A32E86C1D2B533A8,CAEB8343A9558414,7C011E5B625A266E,FAB6847EF538A034,CF9FCCCD70FC7910,70A520DCCBD61F17,197C84246033F9EE,000000019D3E99DB,B1D7545728B2313F,069F8BA1C1F16340,EA737510907EDCA8,4B9F337EA0849783,ED4B04DF9C203391,E483CFA4D50A4CC3,B90A580162D474FD,8B4683FFFFBC83B2,1F5956DFF412BA33,00000002380A96D7,9D8C3AF0E890E461,CF1E14A4CEC7430E,4AE02FD41EBC29B8,6597AC68617B178B,1F8AD6EDB4D7EDC7,9BA902D461753036,4BA23C56A2F6DCB9,83D01FA0BA6AEDA7,C1A028A36B7773CC,00000000E8018186,BB311FE8E6F4EE20,1DE725FD16EC186A,688075C2D17D9915,9FF570B46879F5D4,83DE8325D12A8704,655804EC71B8ABE2,99B558A7154F7DAE,AA59E9B46E2939BC,30144E47ABAB1F36,000000002FE1281B,9EE90499B6BAE995,1970E0CAE63653B1,410F14552A4FEB8C,18956E97277C76B0,306A01B61613C113,041D13170C594A29,2E73B549C74E94E6,D71DEF1A55EE156E,FE7D5FD18550930A,000000015839BAAC,FF15624943A09E61,1473D19548863F3C,99B6BCC2F77656CD,AED014AA435C4964,AF836FBA41D50D0A,E7046E75A6EB3542,C555C0B866A1A27B,9953AC21DB854C40,CB927758D6FD9080,0000000073E02531,62CA330D72FE2A1B,E1E695F5A592F301,8567B3E4424569B9,CC104225C7FD8304,43ADEE6D20294C54,9F8F5B051053A5FC,01D5D22BE0715306,FBF826BFF761B8A0,F1F5C846B7CC3C82,00000000F359F7A7,05166806C355E00A,72FDEAD3634EC506,0BA95263A74016A8,2331FE1E933CBCC8,979FB1AB5B8C94D0,CFBD6425F9513313,7FA35C8488FDC29C,98328B59EC34E08F,0569835C369149B5,000000007FE1C2AD,60E305F5AE3FFE27,13EE5FE085A7C681,09E20543E5871C32,917EEE23800DF6F3,D67E845FA368E471,E01CFF357AE2876B,F5ACF47B98B7C1C3,54223277B1C4AC56,27D8A1A532612253,0000000029CD3FC1,C2246146BD73181B,478BDA136EA58296,C91CBEF2AF1195C2,4ADD7D420C875B73,DFA7DA7E06873D4A,7BA5A10C512093EE,64E90A3051616EA8,3E4B653F237F59D1,CECD64E4B80268CC,00000001D22BB7BF,DB256EC5973D72EF,241240D7B1E571C5,286113F56EBFFCD4,294ED38DF4D984AA,BD90D03EC10AF0A2,3BD741E22E91ECB3,75B569C4526319FD,0F033C7DB26E4723,274659172DD2F524,000000016EEB24D3,59D9651A6A46AD03,969D9412C7227183,A40E2F4DFB9901AF,3A03CAB1CF343D6E,C133D4D413F4D1F4,0298C793318B119F,37BA633EBFB7461D,9EF497CCAB980A90,F7DFE307CE45C29E,000000008B2C95E8,3E1B2037F75F13FE,EF3F3D3A2CF8ED5D,2445C58EBED04868,77984C84EDA8236E,BD9FDF0277B5D96C,87576EF51F19C318,033B0E222D785854,615E9F5250B0FFAB,434E996D527BA57F,000000007DC2AB7C,F94DFB47420277BB,9C299E61EE676DB7,73E4CB00ACFF472F,FCB552000EC6BB38,189F844C838B4F03,EA00C9D933F8FF43,CA27F33A0D9EF4E8,5DD8C09AF00F66D3,D67365D907CD426D,00000001AD6BC977,E19811553BF57727,957EC428072DE179,236FA903027385F2,16AA45769A1854C2,DD1B4C74FFE92095,DABF0A25622835A5,65996CFB8AA3EC78,88AEE541DB056957,D3E6DFABA2E66136,000000018FFE03F4,8C212E0DEABCB69C,B88D2A030CA2FA56,138CE674DAA12099,FD27BBC83C1BFECD,149CDCB8D1308D9A,78DF8B5044827387,C77EE655428E202E,40099C7E9929A694,A3F4FD209C8329F4,000000012F890278,4EE99348C6764D34,81F830604511DF2C,6C6E53F1CDBDDC7E,3269D3588AEB358A,D648E7892F4D5151,EBD79AEBE291236F,1A1F4FAED20BD8AE,315E2B2AF9B7AA20,294CD51E3BE6454D,000000005ED60311,3D78A2525F99EBA4,34FBD7B1BCA6E0F8,8E4A6461D7149285,BC1153627C01E460,1EE6C64666D6F01B,B1B61749FEB9642D,3A3AEE3C1CC502B5,2FE4B70BF77194DB,2E67DCC84823002C,000000004EAE5B06,094D99FC566FCC7B,CAD4FDD0D431420C,3B3E5DA25E93309D,6634643B9899B080,67529B258687A17F,BD3F5A79E227D1ED,62D47450ED46598C,9C813653D6A71C38,560057ECB31A2C8A,00000000A824B676,A59988957E55EE53,B120B8FEABD6606F,B01E9631EB38E9DC,14D6D85155DD03A1,CB3B0E1A423341E2,CA3577EAC0A61818,F93D3B9863D71AA6,C154F8C6FB2F1728,1DDFA0A30E5EB8EF,000000001A7F10C0,BA1DF4F658148B65,A0ECADD612F64952,9F2EF803449C2BBE,B7E2427C491F1A95,6F63BD387A2EA5C1,AAB626D068190974,0183DADB5257052D,4A0CD7FE94DE680F,CED6261CFF02179A,00000002147C5A50,03A3393D859EF37D,BF2DE77EC3DEB493,64D6B28A4F5F51DE,1D3775FF29AE568E,9415D8493DEF8F80,D3E1AC5F3B7427F1,5863EA5B04C9E818,2229776BB27E5A65,71E8121FF8A50693,0000000271F7D367,9AC8D081F83AC709,8F590200887C625E,A7E2F9ACA6C0D93C,986CFCDCD13A56B6,FA65E9F124B596B5,63A7C40CD73D5C87,D04408B38FEB03D0,F630EB8340454CDE,19859B972A7068CA,00000002393D0DA1,F5DE1A4F93B63B1A,F004F1029AB4A792,D2625AB033477003,67528410AEE9EE2B,A1BCD3A7073B58EE,72FC90896D1FAB5A,42D2A56492FF1279,A8F93F010402CFC1,289C256A0BCB68EA,0000000139679370,ED434C005AAAD40B,72241197C9517101,FD886BF322CA0E2A,563D4BCCE0130A6E,882A8A96B3437AE5,985586262F9319F3,9BF29C2EB3006446,946D2D487FB35F32,69E3DF4F0485DC75,00000000130FC56E,9972B2D5D86088F7,A4DE2EF753B998FA,D8172F39B2B329F6,54E7BC4F30320AE4,0ED516A404DE5B71,09E4296CEBAEC628,C2A8B8C7EAF76C16,1CCFEDB532386FBD,973EC8F9036C5607,000000016954FF38,0959676AD0BF53C8,9270B798A22F1FF6,DA1383DE9D925552,0DFA05E99E2FCA90,3A7C03A76EB16F6D,2AC6315DA350F506,94AF1DD871F78299,9396D835817F65C9,4A32302B92510628,000000000337B2A4,67108E4C93CB076D,1129167C71B855FA,12362F402E4DC5FC,D2F97618D2DEC87F,0817A449E32999EB,E0226B02F773B93D,253483B52C27A696,1144D028ABC260AD,BD90A72D70264159,00000001CC9D4BFD,89A55BAE9B799E7A,5E89B72C7F13E5B3,E911E89045B63547,16EDACF2A470E053,FD3ACB4333E08AA8,660EEEA3B980C466,CC9E061415ADD1E2,C1F2C0CE29C65AB4,897079B3F10200B2,000000005596B200,D02C792435B1F5D2,E4E43E094AD29020,0E22EE862E5BB136,AB8BA09B05B1DD99,C1F0F85E4946DD7C,F98194797CADEC29,142192309996FCBD,421C9D363A2AE049,ADDEA6676E5658F8,000000000B4FE8F2,1D52544E0CC11517,E642158655422122,EC9A0D1564D5C135,C233DD29963F4FB5,1FC052D8874DCBE9,C2B8DB30A8F7A8E4,6F774FBF9CCC7F2D,FA61C5F9DF75A4D9,D66EE4D889CC6306,00000002208C956A,0C06F29C79790046,F936B771ABD62922,56D867C0C63CF92C,8BEA280652182C64,255E15EF6438A8E5,63BE261950E2B5A5,8E537F37521A6C3D,495E8C8C4FD47029,7EAB465B65647C6A,000000008643C33A,DA1BD1EFC5B7F8F3,65B80855BABADC4D,CBFA3F8DAA415941,E797C4167AF258F6,846A14D6DD503E1C,414650767B95D1C8,F93DDAA6D5816DEB,9640AB0C8BC5548F,1A2B05218242C5E3,00000001AFBBA121,4FFF511DEAA15EC5,42FD4C07A7E45EE7,74D6319D39F2EE99,AB71D645350D0DFB,AEC37E5B35531431,FBF23557054C075B,7576F2466078A62A,B4D5BFFC009B4F7A,1C154F09F62AE628,000000009E40E0CE,D26CD9DCE0E02D00,4559680D15877B66,4624F798972D438E,B99228BA6F92D2DF,55D696090C1128C0,3E74931E75677CDB,9D7A7495BD400012,6CFBE615C49CE14C,8EB8B690AE903293,00000001A16A175C,55059265B63C08E5,DA043979ED70866A,E9456D70ECD004F6,713358CBD7549924,8946DBAB1AF6FFF9,BF83D1F869746012,504F47C38641E47B,D94CD843CD209CEC,5EC167DB4D5EDF45,00000000ECC28442,8121ACD2E2695B3C,3B9B976E863AF87F,FC1FBDAA9855BC20,2CFC8C8D78956ACC,D9EDFA5D80692127,5853864B69EA6DAC,AA3D6248F5D026F2,E0C3E830CB063AE1,6E078001F50FBDA4,000000022A881170,F31FEB7BF096641A,C771FFC293EF0EEA,B88BCBE2BF1AEC24,AE4BE9B93BC31901,36D9293958506187,0EBFEE4CB9B6D197,0F177F21225B2298,F315B268DB11C152,61DFBAC0AE60A3A5,000000013D5B5336,746A11AB36C3DF51,C844EEE4F9CAEE0F,D988B12BDF401F3E,EADA3EE83F1AD292,2ACAD2EC447CE27F,9C581E70986E9E8B,69A536643839332B,0D28A1A29ABE6DF5,96AED5BA6EB69010,00000000B4723AEF,B2879F1BD0250E99,03D9E36820AD9F79,D20BBB1A99FDE53C,35598DEBAEF3824B,1CCA2F853C32D976,0B099238E309AC51,FA628A2E92AE5A51,E3A59B1451180098,D9C217A93C97C26C,000000017CA2E9E5,62750E5C48F18736,B051BB5EE6A67B67,8D877A3306D7D7FC,59CE3EF603FD06D1,F7EDA224B5045748,F1A29A767E607C88,65019DBC2DEEDE80,680B6E0A328E536F,6E78E316187E9A40,000000016209FB26,784743669EDEDA82,2F81E9AEC6CDFA34,9CB703A039D72C5E,82CEA23BCC8BB1E5,F29962A32E17BDF9,20E2C2A0350139A7,341BBC3893B5ED0E,B679929D1FDFC642,9860CF5CD958C3B9,00000001F4C7D6FD,9F43418FFC261DD5,1D6FEFA1902DA6EF,27F7B2FBE42CDA55,334B0C65CE12A440,70CE23A0AE645E36,352D6A83EAB6071D,43476150DD00312A,586B38CCE4B79F28,83072CA7F768698E,00000001F45B9370,AA800CF5F8971CE4,0A1E235CE5AA483C,DEB353E1BA67A451,7984E1CA7B6832E5,2AE239E130AF1DDD,3EAD5078B22AA693,231EEE7FB7426B29,09FDC97C5931BF05,9990BD4DFA7A1E87,000000013768AA29,393C84DC466AF7F7,F0EE218B3EFFA38F,2098B24EBBE9A80B,56BE41F9EE7D85F3,4085836265985040,A135A7671E6B0014,21FA0A9EB5B4F9AC,951998C814837B54,6118112642E34C2F,000000010BF0ADBD,16C31C44FDFC2C12,8D0A737FA4F05DA2,533796EA870678E4,6340EF7015816781,C3AD2E43C74D2C88,05304E878F699F13,4134DD7E61A36450,CE803DB709F40812,9B9B59310C71F6D0,000000013948BF83,78950525C79FEB66,5CF776660E6B0B6C,FD53BEF5B668C9D5,E2B6E9AD8B4DB53F,7A291A7A148BB42F,DBF4718E24E60D46,D1F70980297EE192,F84F9D8295B0155E,F436DBE23708DE61,0000000212ECEFB9,0E87046BF390B4E0,68D2D64BEAFF7460,D15CDEA065A864D8,8904058034464518,6DA65BC056BC766A,34052BAEACEA35AC,C95D0E7F1263A3C3,17965220BBCAC990,72B8EF9CB77ACCAA,00000001284EA538,2FF684BAE2927F0E,15DBAAC7682951F1,F8993A0B57E87A62,5F2062D041F9F9CD,231177E2B6260B59,18666A7364ADBEE2,B9756E494034008E,12CADD151E29FC0E,A5B744B34D6AEB5A,00000002371E9ED9,060A1D8CB6EF987C,5FD5609E212E874C,948A53CF399CDA71,3E75DAD0AECA5B55,22FC6838C66A00E9,C9809CA21F29F656,57D6CA9911250042,7F421CCEA0DAEFBE,CF2B5E377F4C31DD,00000000588E5539,0A8934FE1FC3411A,DAEF3104D4E63313,6CF77310C8B9F5C5,942B4DF4B97FA4BE,21A42110970670CB,4DA0926898B03964,3339DE725E07F3FF,1B01036C5770790A,E56A92F1E9AD0083,0000000244696FB3,4A4EE7DDE24DD621,D42005D1015D64B1,DAB6785B7CE218AA,B98ECD49202D39CF,D1BC056F51779672,D5AACD8B389EA687,D9D1B7857B707B4E,20CAF7662B455E3B,B70789900E45A16F,00000000E780F671,0232E4454B0886C9,156403A46872EA4E,2AF3DA2635AC7B26,168A8AFAA8C6C5D7,4037A6DB13BDAB85,0BBAE272AD71128A,F9885051A7F403AD,05E64C17AE48DC92,6BC56EA2407337CB,00000002038E432B,8508A81A144EC27E,355B82919ED97819,FCA1A48E3B0709B7,AA7140708EA50160,E3E4FEAEF1784B84,DF55DBDBDFB61E42,57AF2A710AE065A8,139AB3C00051F336,6B2FC4191156035C,0000000046065533,78C765870A392C8B,5DD385778DFB20BA,7F4E07D27EBF4B4D,4224278A064E63F1,54C7FF36CC8875C6,CD46D56AEBC88A77,9532D5D0E5D8332B,FA5B73453937E058,B2320F053C939488,000000004B034B32,AB4556E44E0D16A2,F5341E8AA7260D93,A9A0F5FE0E15DCB5,0D218B9222EE1C08,2FBE97CC3F7645BC,647C0A5EE0F08CAF,A482CE17A17EDE5C,73738DE155336A87,682E566352C1BA48,00000001A5714D17,3B8C0F411CC45D09,914323CCEA28EC62,8D6708E103E94978,51F494920BC0A7D7,0DF4F1886ED5AA42,F260C07639ACA7B2,54A04AFA995DB790,3F076C18C0D64018,564F2552EAEC1F1F,00000001422D12B6,EB377AA5C25D3177,59148C673D84E478,6E5990A0B8B5F10A,1BAE2C7C78171AAE,BCD155589664BBE1,1DE665652DF23496,87DC2307DDFB3335,B3558DDFF8C230B6,0360DA71E9285C67,00000000AC533867,FA529FEA6FA4D9B9,7763451B338D0BA3,FED69E610C3DFE18,43CD61375F7F2A6C,BF7694E9DCED0203,CF863C8A5705254F,5F0DC180DAD21C46,400DC2022538B75D,E639E1C7B3C362EF,00000000733CE32C,65E0F7C7BB3A0892,E903615E375CFB58,46B2F03FC7AA45BC,182A78732CDE0A6E,B146EF662F5ACD25,54BA4866534E73B8,B3EE8F7355EA4BCB,6010DF4B976B60AF,FFA998E78FD561EA,00000000BBEB08DB,E4B9405F9BA6A2CD,379C0E13F5BE35FE,F02F518F8E9263F8,620C79FE49F08A4F,E95F312E41BCE3D3,DE30A9892A5B718D,DCE7BE6D895D1C7E,8FD0972DAB307F2F,743C96118768770D,0000000245B33365,3EA36059D28B2CA3,490072A94FD9058C,341DC26BF1E94995,EC59226FA742C4C6,6B9E73E6209C6BAD,5C2E6BE76309D372,C2E10AA717DA57B4,24F080F0E1869325,0319E525609F3B68,00000000C4D0D0D8,776DC722FB5E887E,8C02FDB5A18143EE,C6A5B86DEB8BB8A7,DB0B10F0CF1C21CD,3854E17A0BD57B5C,5C016F5688BAB0E5,A386888A3DC2BBF3,7E19F06BD1506FD8,98E1C4DBB13D3070,00000000232EBD27,1DD6E3F250A0ECF0,C8FD5894CF7E108B,972E68C10B1A162E,0D9D4971E853C0FD,0EDF3969C203BF32,7846AC126B7FDB74,A3A07B7FB6394978,F7031BEDEBD386F2,061A347BFD0066EF,00000002488C0011,216F44BB54665AD3,AE8D70C9C6AE50F0,F0DE54F47A577396,74E10AB2430400ED,16CBB1570A7691D9,BAA5217588731FB4,85ECD4EB595B4D7B,F3788C9B574CCB88,515E6A7F3C420CD5,00000001C7533E18,E12B10EBAE4A9246,5194A9990A9E51D2,749B0B30A24069E2,978C3D364012FC50,9FD42EF014800142,C820DCC2957132EA,D1D738EBBE62593B,D6745AC31D6E29A5,676568CFE3862B40,000000025A43B89D,E574646D151719E7,5FE1CECE9EE9BB3F,4B9423B91DCD06B0,8179D220E5D7F498,8296C68FE238322A,7ABA443D5F7F6D62,6F1FA578528BD9F0,2D47D85E6B72F475,F221CA81D6EA79DC,000000002A475612,5555D5B56C2657B4,17AF192DC97A9C14,A86D0E22680595DE,59961166292D097D,37CC66824D694305,9B247DA95B6EB478,2927E16150616DDC,9D1FC14FCED2F65A,3348BD71CE922E62,0000000212260F8D,49BEB338F1AB6BA4,D1643B9CC731BCB1,4ADF47A77CAF1D2A,E500D1132AB7AE85,65B6B11FD57661A8,26DCCDDBC856502E,C429E877555D9C72,D44C29D7ED6112FD,F979D07FDF6A9BB8,00000000A4D7CCDE,11E0BE30B341C31C,E9BA682577D143C5,FD7B166567C1C044,52F95EA66C6B5ECE,DBD6D4184C88F574,B29193BA1D5CFB52,0EEE7A717CF2B2D6,CFE9CBDAA8CD1950,0C28FB6C7B768666,00000000ED0CB6E8,B3F1B7DC4CA206BE,165AE42BB004ADE4,44F88998F2E6E7DB,FFE95D6E20F1BC10,72C178D56E661C92,B9786D969D1CF63C,00A351828F589AA2,B2CE77EB1A50A5CE,6FC17BC410C44C0C,0000000001F28C1E,31A64ABC8FE7D1DE,4724D39D051FCD01,103B7592588EBB53,65A0F75A612E6B9D,5C83BD16A449D52B,889A990683E98B6A,E4AB2C244DB11795,D4F371E78FF7097A,7C31F8FEA42C071B,000000021F6D9E8D,D2F7C759419B316B,A7AB34BCACFEF68A,D709E4DE37847528,2E388AD3F98DAFD8,6B2B18D7B8762A03,D0D1F1282DBEC159,600185E4995B3696,C3FCB2E12C8E99B9,50E66AE823D9E701,000000004CD8BC7B,620224A2F2B31036,20BF7F9CF651DE1B,4450FB3648817C8A,5D9B315DA4E2EB30,8C91337FC1EA6EF6,56CEEA969AF7CD79,839D46BF5D513B3C,D5E584ACC0C7F026,D7A1C61FCC1699FA,00000000CFBDA8B8,3DA7AFE14A5A63E6,897ED531DEFC030F,57D7AACA401D4B15,1A089047BA8C3AFF,8399B8DC48658B0C,01A9D55228430FB6,875EBD7897F66B2B,1701A1C1EA84CC31,1869DB7F6DED70C4,000000008F1F8175,6E38DE6F90F34F33,8299C47AF49E8911,3BA83FF88C8E5335,C149C1E8E0DE5F5A,26CC14BDC0248310,4A5F5FD5B303DF19,33FCF914D06489E0,4B6D12F1250F7EC3,FDB1B85E5DC4C623,00000000AA4CA1B5,EF66E878CF4A7E81,BEC1064B8A891855,56B56AC2D5D08AE0,1947046399D2CACC,D470841286888C32,C3F6A7424EE0324B,61A103508BFD93F1,59E55B02B95C1246,636F788600304A84,00000002634F2F47,32527949D6B096F7,BD34BEEDFF366E33,163863D8A8EAE65C,7798FEAC282A9FFC,E0B42E46AED1E1F7,534B671FE70BBBFE,2F8231FA737B2BDF,579E389348AC9F21,A81CED34A31C8E4F,0000000104413F27,EB56E1C615BC1EB8,B9575E2A9BB960FB,34020EB7DD497939,505D519225184498,B953BE1855E85EEC,9C5617E8D5BA5D50,1AD2BE46355F4B73,7FDE3B62BC0432E1,20EDF657E1AA2405,000000004FABAC0F,D068E4B973AF5591,D06A90E2640495F7,684DB2CEEE7605FC,DFA72E602E0CB451,B1BC07CAF50381FD,7B4620633FB027FC,BCE650E834AF9914,E34094B8131175BB,1064E06941F8923A,00000000616B1974,5AC11B469ED0C041,CB90ABF7791E4433,9F898E71EE2BC473,B8E93F4F36040BAA,316255D3BC08CE2B,CA22D9FD84057B15,FBDEE19379EE75E8,1D1A813B950FA14C,A28C94587F447286,000000008093D35F,64B7A5A5DC1F2CF6,CAE14D9879B89F6A,1B79E973E30CE98E,F96C7C82B35CE715,C9D95AF1F28DDA4C,13260EC55DE31663,1763BB18430A8E6E,D6C4B82495DABA85,AD63E7192B3DE2C9,000000009CFBF022,F1AA4815E30A718B,4675BE5658395997,1AADEB7AF4B2F525,59A9A0726673F146,5EDA551305326337,3CD4F273C2033A1B,CE9E19AA9EC30F05,F6FC87BC9817B47A,55860AEBCFCEF0CD,000000015CA26A2E,C71A5D35337ECFAA,00F30CF93BF7920A,E769BB891F7EB708,493D21B127BDA637,9F130DB362246043,FE83F6A409C2CC6E,7A7E92C7B5BB4F4F,C95F4170D0145C0A,5A5639C00F6EBBD9,00000002385AF3FF,F71E1B6C06CDC9AC,878A8217E976F0F7,1D7EF7DA8966011F,9EF19975CEB2BAF6,1D2374952B7AB4B9,CA0E60C93A2F4AE2,2DFD19FE6DF57ABC,114D2478939E6661,40AA09257FA1C8B6,00000001AC1ED4FB,CDDDF4E68304670D,299305E500355C1A,565E7A6BF2644700,AE3FA86F062DBD79,EB7482A616F4C435,80161712D58D20A5,FEA63FBBD8E49B0B,17031F856C087F18,08F61FD43DC4A53D,000000000F67C147,492BB7E7156CF2E6,4631C3BFA08854FD,D901C88BBD0AA40F,C6AA398E8C620F4D,A983D78F72611D18,5EB7DF10D1C7D0CE,E8B1362B154A1325,582C024285765147,82AD917F18BD30E4,00000001DC5473D8,85F26F808F7447B0,B1E7A85C09448E02,ED550ED71282EDF9,F77440ADD7783ACF,8748435373F6E939,5BB4E408BF1EC975,5201677A657E55BC,B6A961FDC5A046C6,665569439EF65F2F,00000000C567F73F,A34729ABE13AE73A,23819C45F84ECB53,14D44900ECA8ECC2,48690BBDAC733FE5,3503C7B006BF8A2C,6F4B5EF610E339C4,F683587215C68075,2FB4E7203AF16C45,3F201705A15C8BE3,0000000006B054AB,83F4A36411EB3A85,3566626EA252B8B2,B44821F8FEE61891,145F659BAAA42601,AE5ACCA74527BF1B,C953440DDAE24255,48984FC839C301B7,B8A48453B1E90038,706018A057C4985E,000000019D600713,53E9CC2E6E10A6E6,1E23887E4464BB05,39B1501D04E3C004,D65497DF37CF8228,851802F7547FEF30,FD42CF795713A74A,7A92B445F5892700,81E406F1C50B2045,7B38242C66AF9532,0000000053FB54DF,117514FA84EA3E45,091B433029A92BE1,3359751A56720F8B,D339D66D7AA686D3,17785617C0A09EA4,5AA13806EA6884EC,C1DB47277A7D2D70,04D053704E7879C4,41CE971BB902E14D,0000000252BCEAB9,7E16DE79BDA17D0C,44E6CABF1FADABFB,90EF8FB96814A589,DD97337456D19457,998622923C8CE382,C4425CC27B713B78,2BAA4A977CA9DBED,10DE2C5C75EC9596,8BE2C2E7F39AD82B,000000021CA7495B,BFA6D46BBF854EED,A0EBDED330F3C8D7,93E05F9CC758C605,22022D034A956BFF,92750C99BBC1EB77,B426820C670FC8D8,33A18E051245DD4B,C03CA410BA63DEF3,9C5CBF99322B6A9C,00000001DFA9AF86,352FEABA860F4CF2,4C3B4CF80AD12B91,5A72A7B0213A827C,2C698F7DE7FC4FFE,264BCF3B941A0EFA,7B39BD633667183A,85C01BB2E30E5021,785460F79D5C6C79,71B4084A2E89C8B9,000000002BA00EB2,F93DD8A31039A918,3AE9F6528F29A1D2,0F11C61E10255B89,6B9048151F4F4148,D42522C7F21A2276,A1C8818F71B0D4A0,1BC095AA9DDC913B,E698C316F5A9A27D,BB52587A803CE235,00000001F8F41DA2,C5C90D211DE8708C,A10FE91940E7846F,3BB7173ACDF602E1,6455E7FEE75BF866,C79D35F26A093EA8,90AE277D6B951E50,51D096DED8092E9B,FF693AEAB4BB39C5,4618CD4B2C898BE7,000000007F304551,2E1BA454E3FCBF05,8BB5E9E132C9C287,748A3955D04ED4BF,D2C28422A68FA364,A37672E703BBA908,446CDB9E140B32A3,5EB3B8590540DD57,2694CA6C3940B015,23FEE58F7A47953A,00000001E7296BF2,774B3376FDCDAE21,5C0CEB59810E4EAC,2DC34D1F563DA3C0,455452E5E3D1FDAB,61D7E5FF599CC8AF,69E57B67C961E5B5,AE9415FB17DEC549,F1B91C9257FCC0BE,17B62C39518676B9,000000015B8A8630,C9A72D002FDC9D71,7A433207463F70D4,964219228E782AC6,C553C1C76C7132D2,205C47C7E13F0003,19492EB0B29016A8,F975FF14E3C36145,DD9F58BD973101C2,CF4130F16980C3E8,000000020B6D18A4,ED92273C95B9C847,751AE2387AE5BC41,0FA20DCC929B33B7,04B3E56945B416BB,EEFC8F3EB23FA6AA,7AC52898898C091F,4D739021698F9838,44660C2C1D51F64C,82D99DBC35176975,0000000042655FC6,B6FD2E4CFE367717,C90805E4D9338C3C,EF1DD133C83CA2BB,F42E9761C25DAB66,3B4AE052C81560CF,A9ACD9A74C175766,00630345ED7D4B11,77FA182F23B94A43,5EE97B431FF140E3,00000001D26C86C6,0B507CCE10E7EB4A,F0A7C86CF98511B5,22DF08E83FA90111,4FCA7F7404245A55,62BFCAE24876DA35,0545733066431F70,8AFE6A747684B221,B4B9B6BDB05AD71E,79EA8A61F04094B9,0000000099EB6B15,10844984C0D0CDE8,D5880A3AD76CE675,985C920D0B765523,DB161E149B5A99A9,D5A6E58FB0135267,2D49AF5D55119B7E,B4ACE548C234D2F2,C9B24C30EA91E570,14618EA645F791E2,0000000000316D75,A2CDF7E362084DB9,6F267FCE40207727,B2DFF29B1E8F64B8,316677FD2895C2E4,6A551719A95A102E,8A94BF8DC91C1459,8C042E05C15F759A,69569593364DCE23,3617D527D978EF60,00000001295A4C1A,168C09FBC61BB50D,7A5585B45F5A70DA,3AEDCEE617E56567,8A6B43256DED2120,F50CB481B575C3D9,3DFD1F32F8B7076D,45871670E1C25283,8589D6D5A47A5498,68875FC21FF59A3A,000000000DDBBBE2,EB44305F6A84AFF1,E0D9E1E76C29440E,39D08025E12FF47C,D13CD898485699B1,31700287BF9D9525,158108FE0845CD2A,7FBA3DC58E569789,AF112D3A48052D1C,36A3AD37C3AEF069,0000000052DCA4E5,86A57FF16C485BEC,6B3C85DBEF023819,48DF3ED5A4C570FA,33651C1CFC8E4038,7C2A1FA2533DE79E,8361B488E1909490,0DAD8B1F16D9A55C,23A2617F01AF8F83,58F9DEF36102D834,00000000C342085E,EAB93CC939267BAA,B24609AB44F585DC,36E9723F950BCC25,581821C66B6F870C,8B84F2DAC20D723E,DF04F2C6BB611F48,21E4795A3D57A165,AB2195CB0C7E1931,D654FD477B07BD29,000000022BB9C7DB,680BF80DE0082199,A805E35265AF7430,634AF8EC886BDAAD,FC110433B839A3AC,0261FFB76DE9376F,1119C457FC762E2E,F68D222FD2DB3E76,D3485497085E5129,62866BBD8E7D0FFE,00000000FD4920DB,30ABA68513589D17,C3EF0B80EB0AE495,6977CA01376BBE18,00CDDBD455A9BAC4,24282CD3D7271FAD,458FE1D35FB4ACA1,A30D5C3F8AC20C89,F90436389C7BEC24,CA6BBB62AA3B6B21,0000000174B1F905,1A5450773026C81B,763E178857CCFDEB,4E43FC9A0891DB41,3F108D09C38C290C,65D7A962B517C4A6,A843CE9354AF6996,662440E00D56A1DC,81D76F4A5795DF75,6FAF7652C3263E4F,00000001079DA93E,DE55F3774434849C,DB1E493F780130DE,64F745223E925A18,A6A6097F89DBF544,A7828E3E152B826B,9A2CF8C03061277C,94075C6DB0D6AF61,DCEDD7FF5AA13989,363AD492130BB30F,00000001C2CD6EE1,87F6810F8607ADDB,3DAC03CC09AAB982,B3B95D761853D73F,7BA8B3EED34484FC,B269D211192A70BA,14E1B30FC59B8680,E1B7561572098D37,B1534A541657AB76,E6DA3112CF4F7939,00000001CC21A26D,C806344B6DBCBC9B,68FEAC5CBE7F4CB1,98B0D481495726C9,42B9C595BA53D034,C06A50BC41B90546,FDA94C22C15CED14,CAC01FB4B638601F,062F26C2AFF756E2,D6D6CA63179EF2E4,000000009BC67744,68D8E9D43611BB64,A9AD53D9509DCB1A,238A9BCAF03EA388,8FB2E846CADB43F7,009D0DFC268BBD76,61BBA9DCC5318AE5,5AC11ECD35211925,EF15E697323F13F1,E5AD2A9ECE8239CE,00000000411F48A5,4939641A7A830094,F714CFAA3290ECEF,78CB553AECD8E841,4FFD8D9E111E2591,CE80FDB4E1A104CF,B99E7EF8C458AB6D,850126423DFD9028,FB565392B73E4E80,F9D71FFF187DAE40,00000002611BF096,331D4DFD09BA16D8,9BE2180F5A4FFCD3,409D18F4D87EAFB7,7F9D92C94C5E2453,0FDB3CE2DD0338CF,C7878380E6897E4F,FAA0BE01CCCFBB0A,CFC3C0391E15CD9A,5505531030F04745,0000000147ADA184,E29577A1A6BAFE18,E49C230BEF3484E4,DCDA1B59C9047C81,DBC9524154EC362E,EDCA72F0F47445DC,9E4ED49CED3FE7CD,E8F84A819661E590,80250F6F345CBCA9,B23E7EBA29B2764E,00000002009E78FE,FC113DA53334C2C4,C6AEB6965A8AB279,CE14E4BDE031C340,6DEF845712948A19,6A05CADE86458883,0B5E077CB8AF972D,5EA7D3618C4F03FB,2DEE2FD2086B8E1F,E6593925AB2D10FF,00000001990FAB67,CFD11E6015396CFB,5D2FF14069F50A43,3ACD4F936FD92C20,1B7CCE082AB8603B,FBBDAFE0A44A3003,329C03C78EBCE436,62FD028254A1C8B4,05EB237734E49B93,563F28BFF1056127,00000000A639AFE0,8BFF4152F0A2D3A2,3181E7BEC6397B38,ABF83E783A7CEB22,2D8D18C0A5CA4E3B,D0864BF73F1C02F3,4CA441EC2BAFEB18,B549A91F37005168,BC8B2C41767CC6AE,EE53771FD9190E2B,000000021563989B,663DF2A31263837B,3F80D4E5446E26EA,6B07ECA00426D40E,3096FD00E6C53E3C,E8A188E0C1ED129C,4F46DDA0F873CF64,7C822C7C31F85F55,2C9E31E74531D344,88A1F0F3DACCCD86,00000002229D714D,6D0B9FE717921151,478FD3A73722CA87,B8E01F5310B0664D,B3E84F20B3AAB884,C2B082B9A3775172,D45F51C3802E0044,345DABEEE0FB3BA5,A8CB41081FB1A507,E4CCF6B098C417D1,000000014112F101,95EDA8B242F0F835,7B6CE4813AB56552,C39CEFADEE1C8084,B3B4ABE79983FF9C,29D6A81C28895F48,B09C2804C8E3B7D3,D1D8611F55513234,2854B85B89DA67AC,40F3632C02CBCE16,00000001AD70E0D0,3349758FB3E1AEDA,1FFABDA526B54758,61DA0DF312E8DC5F,4A8BC94994AE7852,EA5CB500C713085D,0A06742211921B3D,3DECC7F9BE8409CA,84A4484F8CFE5AD9,F96EB310CE5E6969,0000000180BB389F,86D8F041B5F9EAF2,322EED48449A30B4,00BF4953BBB58D47,DBD5B96F38B5E9FC,D5570B207E6FB649,3FD251A3BC189BED,14FF8E92ECCA9D88,28AB175384601B18,EC9E28FBCE8F03B4,000000005BF87AE6,F92BFF57B3C9DF91,E7568C20E2AC7AC0,97BDDDDEAFB6F855,C5EFA1E53B78AD44,F8DFFE2D8E0FB84E,4C721EB9A01DE750,12F22B63CDB8C0D7,A2FE857315A9681D,3CA1D1BCE2CDDFA4,00000001E58F1A19,CC2BFCA98348D8AD,15D0C354D976BD86,6383D1C3649E63F6,9462CC30560B9A6B,6A8399E1E492C73E,1E30D04BBD277960,91BC01F949A47859,BBDFBC8DEFEADB59,046FEF46FAE8916B,00000000366AFDC9,B9FAE34C3AD28B85,FB44344E4A326940,F34BC0900EE5CD7B,D3B2842F9D760550,A82DFDB2FCE785F5,BDE60A097BDF0CA8,A1AEC79BD80ECDE7,AFF706138DB5F95A,D7BB1670479A7608,00000000AD2A3015,1946EA181DD3A305,F5803287D3482D09,58CA0A926FA959A7,55AAD96F0D7E1DC9,4478138AC369DEE5,173F07D4AFE6FB28,D2E7FCA319939B49,D80FBE1BDFFE307D,BCFF3E4A4E01E97D,00000000580CEC48,824FD81497C6B960,8BA75D31FE4CBCFE,179A7403C7BA0D9F,A5495C848BBE350E,EB3A106935C17C7F,D5C5A244E26D7AC7,4CFDB6200586A8CA,FEF35BBCA7FD628E,EC6F6B5DB40CBAED,0000000237B3952F,327855B4E06E32B1,0396DB9C3E8BD1F5,2BC687B38775D5A1,A2C3B23CF0525C4B,F533A9462EF50DA1,7E19862534068678,ABF900E994B3DA92,9D6A1942C1397877,E190EC7B5D31CBE8,000000026AB55920,A38720716DD0EF25,018D1F8406D5A570,7052A88463D73809,9576650D2DAC84F6,F57536EF12AE1C67,6CC6E3836C1E0A2D,B87ED97098E51C59,39577AA948A796FE,AE8D8112D6388898,000000024CAA176B,551B3A334FA82EA6,E17E65D14EF1FCFD,BB30D4496607BBDC,C8DA3A831D08D3BC,570D5EFF1A346480,DCBD44AE6107C71C,19FEAB63083E78C3,1F9551787FD5598C,112862253B77DAF3,00000002762143A7,4BF9AB01F5857463,0F45B6EF4698F227,DC695DECB058BB9D,6FCD023FC9CB82F2,8D1F75D1EEA4BF6D,60010A3AC762A4A8,2928F87B82B79D80,9B87804745BE66A7,91F9C85751ED6E41,00000000D8A6B755,F5CEE84FD55D2DE5,BD073D3F16D7AE60,29AB9DA9CACC9775,7C2C6CB15448DBA2,C47FB2EBC476A67C,E6919EDBE0D1ED00,24D4AD9D3AA1EED2,EFBB825CBA136C43,FB7ACF8B9BA5FD47,00000001C60BAFCC,A6E9DF719A9374A2,AEB48A4C16ADE447,6B26D178156C9B93,6DE7F643D2929A36,B6DFAB328844FFD0,9A7F06EEC4A3954D,B76894443D56A1D9,940C62BBC78E1A14,847843CE264DF1B1,000000024AB11EA5,C173A52A301A3B41,0D3A377FFD6E3F25,B51B910925A467F1,5DD17A9A14E39500,18B1FC33BDEE0DD2,ECB5A674205A8F01,2936D7F4DF673855,C441065EA1AF5541,23C03C044FD2DDAD,000000015D4BB9AF,EE4F6928AF3973D5,4AEC4EDF77CE08E2,B0A0E1E1FF5D5C29,81BFBC291F2FD9A1,7974B013E8B7B676,1ED3EDEB2C64902E,DBF8923570F2A6E8,7AB704EDA763EE86,091005237D146FB9,00000000349F05EE,2641004BC671E24F,B4B72265CAA40543,113986EAEFED5571,A632554FFB6E432C,150C3462FF9BEC4B,8EBB84431530A0EC,46E60D8E57B0E367,E7C12D67B8435A8B,CC1308303FABFBFE,000000003631FAA7,F6C5446628B741B3,BDCAA498D97395D6,FC7C2CA8C9AD836B,71ED5D906DB179B2,1F0606E3F8936C25,C9CC212B5ECA667D,D8D284D72052E7E8,1AAB755FAD2EA396,A692C58ECD8F0BE0,00000000003D6A4F,A8B9FC9BDD9EB6E0,FBF94AC8665DD885,583B9C296154404D,52F6D1085DE2C396,0DBF0FB0001599E6,FEF6999018F2160F,82191580E2F1A3A2,52D851F5B32BC3FE,5AAE2BF7A2B8EB98,00000000C29A2C30,13B3F26E3A60EF0C,831C60780EE8ACFE,785C55B068468CDB,54A0B2E9B8B92655,F60AD18DCF773E78,DB2C66E8612E34E3,57C0317F5C7E9CFB,5AF408289D327FDA,14883B66A6F68C15,0000000090602E9A,F9FA6502682E6698,5C8566C6D87CDE79,85CE03519E33159C,9E618E2440503F1D,431C037772657E6C,DACE31DFCC9823BF,76904B1BD7C01AA1,16F2F4043BE98586,745D596304E0A804,000000005157C02E,7C637CBCD4D6A4A1,1AE6CCC1AFE4C7C7,657135290EAA3407,2D02606DB766B642,F81373E53F9A224A,F7968861C513482C,3261425971B276E2,01D3029FE36A91F5,24C76EC5926B9FAF,000000022AA73890,6A230145948175CD,B88086FE1E7741D1,EA0320180AD84A7B,B6245558C4841517,2EE80FC3B184BB2E,26D86C030BDE9573,F2B8F0A7BF6E26B1,029A81FDCD1869E7,143C7D25379B8C2F,000000021FE1669B,27255FF3E7FE9CEC,F5722ECCE65AD047,73B41529C2CC68A5,261F0E663B01E43F,2E275CF83E2C9970,0562A2E1DDA42369,7343229C68DC87C3,81FBF77DB9ED99B9,0B598F22B599AFBE,000000019EDE5D70,A648CAA49B9CFD46,8982433DD89A20E1,9CD37545E420E330,4C19022392BAEE26,536675C5D99B1597,DD0582089DEB8AC9,11CF8C91B1E4A72E,3BE2EC97BC8A9A5A,824000A09DDE23DC,00000001FD35707A,EEB76F62AF75D634,CA8B208048005C2B,9D7C6B484D25C177,C24E9C664AAC72B0,39090390B142C58B,7A2D5DA83DA6E6DC,7CAABDA8704CFB26,CE05EF833B446853,15D14B0EF399E40F,000000009C599A5B,47094B02EE9F2DCA,213DD1E1AE756C84,436643622DA2A81F,354ACDBE5F0ADE93,0FD9B7845C2EAEF7,59487E69E69A2674,49DB248E07CCC59F,647333D14C162184,5EC689315E156019,000000012979A995,F324F16B45E081D2,B67A69A6D5F6595E,4A7F9DCAE99603F1,981769B7F2D20D2A,737BACFD7240FF98,261AF1D9F59EE70B,A6437602B8EBD093,7AAED59BEB348519,16C1F486C07F008A,0000000109752DA8,FBAD0E9F4DD74394,7A42551F1679B709,A78237F2337ACBF4,F1EA0F2D08C9592D,9741BEBF4B433396,714CE09105AFBB38,47F2EBBBC1AA641F,ECCA6C81AD01114A,D4370BE51C12A685,000000006D923754,8C7A8BB8A8C0E651,205AC3F548B607F0,D83A9DF6DA726FB6,F8FFD0A94014E56F,7AAD3CB1081AC2A5,978629F0B673391C,3212C9719702495E,5CBB27DAE60B81F0,85E26A13FD583022,00000000866F9C96,CB1AC67DFFE82B74,2915F65966EA617B,3AB0EA969B6F425F,37EE952728183361,FC92D310FB7D2EC0,C33A8277E97D3DFA,5434BBECCD763286,6538513387115DF4,D978FCF2201C79CD,00000001FF7B217A,9061A083337EA854,C98F3E991EB9B587,EE32DC88BF44317A,70A758B6091FA51B,5C10CB3889B1741B,50A462D88183327F,CF47737946136024,067F975D4E85D420,3E487E1C591DCA1F,00000000757ED096,45C4F966F5D872CE,8A9E05302554746E,B737B96559789EA4,B887A88DDEED0CA5,AF9164BDD6E6EA95,CAAAF4D144767920,A70F2CC926B76EF6,310F1235277ADECD,FD81B0CEF0B59CCD,000000015BE45547,A64536D76894818C,019B30F6DCBED28D,F92AAE5F592908FD,F605BB6FD4071CC3,F053B84EACE49D8C,C4ED8AE58611AA74,B2ACA9A9C2F8F108,1AE84C3ADEEB953D,71D72FBC1821FF74,000000019957BE84,EBFD7D3B98E76D71,D702474B2276C232,8C491B93CF91C957,3B0BB73940E49460,07746EE77A86AEF4,47D0AD2316407235,9A3743DBDA25525E,AF070498E4E1A9F6,0B582537760895F0,00000000D4257A81,6AA6A1B8BCF398F5,B27D2D52A6735889,5CE7B35F2E8D6C35,C3C74EE973851468,AE3CA578FDCFCA25,767A434D03071200,6FEAD3CAC7030F8A,0A7567DA4E3E3BB5,CE7A9C15D54A5342,000000007EA824B5,1D0C61F372BEE847,A7F0BCFBEC09FAD5,A95B57424F3108FC,A550246A6B5B21F7,C66394485928BA01,81014A6C9C4549A7,0BADB24F2ED243B8,7481A6EE82490F3D,4FAC02B325C2AF77,00000001401B8DF6,C1DB403BC006A36C,CB991916427D7EFE,A6BD00C5970D5FBF,957F0BD1EF7A6FA3,62D3EAFD8272332D,C56E4B3D8082D368,01763D3C5ABDECBE,EB8DBFAA815B5BAD,5E605709522B2227,000000002264194A,69EEA08884547DF7,A6883D58E1023787,1FC3D1CE70692D4C,D9F43B8C82340BA6,F548D3984A761BE9,4F5B2A24A57468CA,13DE9C529F5B6646,CCF56EB56B854DAD,E4275E45BBE870D6,00000001337E1BC4,78A497659AA89B13,CE6D45DE55DE3312,CCBCF3295D0FF669,A1679E1EBDD24C7D,7B63998CC0DD45D0,09BBAF3EDC8789BA,5025C6C1F9289112,65F940246994CD2F,ADC0AD77C624BA6D,00000000126841E4,C9BB5352440162DD,E7BBF9510237A160,763192A0A04C6990,2954E97CE2B87EC3,283F2FAA04B98932,F8575BE9889604DB,88E3F4D48745B7FE,CF9F44ABA77DC7AF,EAE0A0B2814EF317,000000024123FEC4,EC7F28B8741B2D46,8F1A54180F08E25B,C5F597A5A6EF20AC,6408E264E636AC97,0D97B5514816781A,354D16DE0374385F,BD0610710595D2B8,7FCBC481149F21DE,2BF2464FAB1823AC,00000000EF7FD4F0,10BEA64E6F67C92E,2BBF7422CD62A8F6,63F07DFF8E5313F7,A3558B35CD9829A4,70756FE58A98EF44,F32E860E380CFD28,62DE02108321C6AE,43D36885D444CEAE,ADDA843F38FCE92F,00000000217C4056,29F45C4056AF4720,016D1E8B82465E80,59BA13577450B468,AF1CFE12DAB14B67,099F6C884709E946,BA96414B8041529E,D7BC771D4C37B9F4,D339876891977A68,12CC3C018051FC27,000000023507574B,6CE1C1992BE87711,D7EF984AC793D521,46E758A01AEA5584,33FD1BA3F9F01235,AA890BE0FAEE8D20,053610977096C045,09A6D9A0DBFA4A7E,21D19BF065253FAD,672113B4CE46BE17,000000018C06329A,265694C92B91977F,B5351E3079CE9B87,5E2F97B985B7D07E,DE2E48BA45E8A902,E220501A8EFAEB14,4FBA8268CC41B18B,AD5D22583DF984D3,12EBF41F5BB05965,84C5F0C37F752DA9,000000027A6D6EB1,D2C33A1D2E64E199,5EDE6A73380343AD,AFC1601FC6BF4DFD,46A43557B9CD1590,5192EB5B5C880111,5B38B1163C4A8084,01ECEB2D64DBE9BD,AEC42F8DD084F451,C8F9D368B36DC30A,00000000B72284FF,1A1A07263FB00D8C,16FBE21443B775BB,4C48C951F42F5BF3,2E789D06B8BAEF9A,0E1A64E447976FA0,D089CE275EDCBCA0,DF678B760907AFC9,C05CD0AD57930211,293F4F1C8427BBBC,000000003E5B6A31,B6542651FBCF5BA2,03325DE05B9AA175,24AF0770E089F275,B71EB4A91FFB5D45,608FF4585659A3BB,8274BF5571EE9CEA,2C75D645463F7702,ADA08DD4BA82C611,1C62DAD0F9D13CD8,000000019F624239,F0287CF7D8D57CE1,67C8E9FA54388300,80C2162D4F2E9F50,A05A6F27ADB07624,ABB5C7B02A6DF662,D998102665652864,245EB048690B60C7,1F638E1CFF69951B,65EFB4E63C0BCFB7,0000000167CD647A,7464B8E48CEEDFC5,12DF1C62BF7A7B67,969FCBFF163DBFC3,34236DB2F59D6CD7,13915F4C8CD9333C,02786540D2F51A46,F5DF54145C4F044B,4A7B253378AF6F63,7D251B4C5600D04E,0000000277BF0EB3,1F59E9425EFCCF8C,BD0AF3381CF4C328,13B851ACAC3AC36A,970EC43720E11F6A,39688F1402576912,D38B1DA2F8D72FB2,CED46E5E1081F283,63274D90749707D1,A543789A75FA9344,00000000D467BE85,2A854CF71E006FD6,CE22F73138762128,22110695E474A095,2677A7B7275ECA27,E7180842664C52B2,4B2963FB5FCFAA20,E0A22044838435C2,D743086FAFD4722E,18CF6F8190EF3553,0000000054D32F55,79B381CBBE9F0A5D,21C3C629AE51B887,4CDA7B67DD2D93A1,0D22B2057DF1EBA4,A4EF0CD4616E525D,1A043644846C177A,A2689CFAB02F16BE,325B61F1F5CE8583,496767A9AEE769CE,0000000165078C93,C4220C91086944B2,419EFE10333E15BC,339ACDB3B31BF85B,C3A35A74B100773B,0D84C21A6E5C0E5B,4C3830A404387714,EC383A403D2D9B79,44F329848CFA03DC,846144B6D136A24D,000000022C21851C,CEF25B6A0EA17242,B818E255EC2EF30A,C81EC6A95227DC89,1CA5C8095DA4A1E4,A55CB3DFE3374F42,32ED8CEB846A7B4C,47F916DD3A92BF40,84DC3E368F7D7127,3EC33ED31AE12575,00000001849AB528,9677EB6F59DA4771,78FB4D66A6DBA567,93E22920CD9BDBB2,2E4131E5A28FAE5A,B42F1506842A8BC9,0C2DB9DD290D4378,E91555807AB20F6D,33855900CAA5D3A6,135C1F53F0E543EA,00000001A7A3B2BE,55DA370DB1BD21A8,AB061BE513BC5C98,BCB6DA918111D510,018E6D960D7B16C2,73ED87756603BB21,F3ADA0378D760974,94B3CA0A98687086,0F85DAAE9DA0BEDC,29BAF7EDC53BBB5F,000000007F886CD0,AC307E2E2E1C1D3A,581174A8BCFEF34E,ABDD85A25B40A4B4,2D6F1488BDEDBF81,2D50EDE03144B748,184075C2DBB141B8,4AB5ACD9B7C0241C,8491C8845106E526,FDB89108296BD3AD,00000001AD1BB345,548E9E3AC05EB5E4,E8665E87E234FFD1,DD554E5B50521CE7,F274C0AE87491E5D,AAFF1D10C5243E54,7ADE4F5BFCCF213E,68DDED48D30BCF0A,B00CFC862A16C078,4A90561FD8B71468,00000000C9ED11CA,CB5E6C40966B6715,579853E022294D66,CAC6011809F2F865,B0BFBCE4FC3F1FF3,5619209B149FB42C,65D33156BB7A9C2B,84485066E58C96E8,603824D7742A76CF,F0B93D1C721C381F,00000001BF4FAB49,29F89132530C205F,AA738255426D191B,2446A035EBCB1662,35AE655F17D18F4A,5CC0D5480BF38D40,C60A9B7C9AE93555,3647B353E9DEB815,9676E66BA4C09337,53F8A3875DC0929B,00000001A2C04CD1,F52F78D020821EB7,E31FBA69A316372C,B18930BDB8D27EE9,26FCCE676CF4F8FB,D34E6302923F52F6,D60F8EF829B1DC26,C99C61F619CE545A,67A8E634237BF1B9,ACA686C2BB143877,0000000109332BCD,27EBEF165A25854A,F63977E4106E5402,F416635B454DE2B3,A4F27EEEDF251B77,34DF60F74E6A9600,69254E66A37C5BC5,27FDD789EC52696D,7506984051A166D6,86273D5159DD44B2,00000000591B91F5,D950A730576AD865,B0CCBFEC74EF20DC,F710752A240A4FF4,AFA696349298FC75,915A69E5B388F4D3,412279F2316C505D,7DC8A0E668CF541A,E3FD1918C53EC584,7263F2D64E97EB09,0000000051AD155C,003EBACC7F999530,E5A073B744402387,05C09C46491748A7,C2CF1386250B25DB,5D544A9D0F2AA8ED,F8BE4586FD4D63A7,64D2B92464820834,509AC935974A92F9,5F484E5216CAB574,00000001665EDDB8,0D8056C92AF34870,000F63478497C9AC,48E2F7F0E1382FD7,259B778413F9389E,8814607B24545D69,FB91276CFE66A81F,7F83CDD0682D86E7,6BCCD84557AECCEA,6E6528F2A421A1B3,00000001BCEC9816,03AC4E69466719D5,9F3F51AEEDE9EC4B,5DEEE290E97D3EDA,9B2989B42DFF4AFB,8043D95329CEF6C0,3816CBEC4FA2E13D,E27C0A813E42054B,E596EBE8870E8389,8B835EDDE58B0E30,0000000185F41499,D835642A7DEEDE41,2DCBFB97C0B01EED,96A5A9633ACD5B9C,E02A3D0A8764F492,B46E820EEE233859,DC9E8280497CD7B8,5AD0DB68DEDDA76D,FB27E1A086A868DF,DE7FAD83A802855A,00000001A45ACA56,9F46C43321B2EF6B,BB7C1E228D45FEA7,AB5BA73C36728BE7,C298F4F0E49DBBDA,3A87442891DB0384,53FE61E49A6ABAB8,74318BCAC2B37861,53EB9AE35805611C,667385782ED3371B,00000001F43817F0,AB85DFB5930B6A83,30D2CAC9228AE205,B6802048F82CD753,B493F50F78CF16D4,1DE27F80626EC94E,96C0635D816FEDE4,00D6EC1A8F2C3C57,B5396EBCF85E2A23,A36A1C2DE48DD581,000000018D0C0F1D,7A654552FD48068B,FD649AFF63D64772,5EBD397F62C4CB2A,70F9908190B8D361,423FB16D29D5C2C7,0A7F43B6B66B3111,18F7526F931EB53C,4E8A5A1E01F854AC,5C5510157578A6CC,00000000FDD48B4F,5B66210AD9044279,A70A8F475AE62B6C,A39712573D3342C9,AEFAFB48A6F9AEB4,B7387E9585B95138,F85137827B95D1C8,E617C68DBA0CDFE4,31AAD6CA7C455A03,37E699186E2784C9,00000000DE50EF08,B1BA55C4E1DE39AF,5060ACC3820FDF3D,2E6C7692D7C7437A,9C44ABE4B2D4DBD3,0F86BE916F1CB4A5,96972C802DC9E456,FCDBD0330403C8BB,BA54078C7064FBB9,56F403343D8B65B6,000000001E9900D2,AA7DF8454B8045C7,155E48BA3706083B,3040E3988FC2462F,0B12CCB2E354CC02,21BA225963DB9FEB,3C147AA9B98DAD3F,5B18D11BA9A58FAE,56179BFF9FFB5672,65530756334CEC92,0000000087E99FE3,21BE822325726999,246C92A7369F1CCC,D6C99FF7EA5FA77B,D992D1DF36D7A8B5,3FF996C8E0755148,0299A91A7D5D6F18,6E7EEE194B303B50,2947985D9A03AAE9,541137F92C760D45,0000000166B7DE98,439827440EB56F07,48A185FD66234781,EE7F4900B36C561E,EFD5D45D282B4F21,FED789745BC385E5,E3074A5AFF701D53,2344074A2D71FF75,C16146886CBA9F3F,76D57A3B8B3C4B0D,0000000198E36A8E,076F42DFEA00AFEC,1388FCDD0F27C3D3,10015F4D715D9100,910FAC32CCF3F5EA,17D34714F3EBCEB1,1CFBA39EE7E05146,E0560AFFB0017A95,FD6D1C80B6AD32BC,02DA2B395EBEF57D,0000000011DC96D7,CCE1E6DA4D46C911,F01272B18FFADBB8,ED5A82795BE3AA8E,DE1FD26DAA1F09CB,6F8F4F1A9E2CE905,5AA4CF4DC8369EE6,11E2FB66C154423E,FDF2FE877C00F36F,62EBA8F07F45E12E,000000021AE77731,00C3E7BAA7710600,40F5804B90FB2413,290E11D868028932,705AE3E1E8D28BC9,E56B3E4E35D82B73,48756C7EE52444B4,9D4CE33309448984,E3A042BCBCCEB3DB,F41C7F9B6351B9EF,000000017A4CA444,E2220CA29F831D2F,5ECF350432016D1B,577D883AADC951C2,4471589D5FBE8328,B67CACB66EFC9B6E,4D1C8077970FC8D6,C688097B93432140,9E808D2534F2AEDD,BB178008B9AF1B51,000000016C251372,0736375F53D0B274,39D871EAD0371659,37ECF9DDD7C0A895,05E9FB1F80108EDE,93C1493013A823BF,84DD9C4E7BCAE298,64973CFC30975FFE,C39735F844686EB8,4DCBF28601D08639,00000000CDDC5391,B6BF8B8EB874C195,98AA3159FFF31E9D,03679FBA85057ADD,AD7E9DEE7DF83DD9,C4212166D86D851D,23A7DF49EF9CCF2A,F5B2DA6E008C6F9A,A8A4E82A328AD558,4B862149130F2523,00000001D0167265,CB2C06D58F9222DD,21127165A25EF53D,40F75A52413C8CA7,0925ADE0B9A4211B,A6A12BF96AF51E2A,6DD4996FB5E4E8A4,2F05FB7A22929674,E63011F03959BCF6,F0B347BDE5384622,000000021F93CE8B,3108BA1E8023CDA9,0013E4973E339AC4,AAA7731B2728466C,09E7D7FCC518A459,05F8DF0BD720C637,88DDE62A0544D9C4,B68BFE2EAA406457,1DC289DC43A5C65A,47BFEF6E05BD069B,0000000122283E0D,4483EFB925B92CDD,B7312F3E1E275A59,94AC93616D8182EF,06909E6A22E8634E,ADB9E1473E6D2E7D,1F7FE224611DDAB9,82EA0E845AA7800D,F82B200A3CF594EC,301CF7935E0C52FA,00000000060A4A82,0A06493B8B7A11C2,B6E71C93CDFC82E2,119C6CFEFD2ABA65,97EB9E141860A654,394709B3C9262688,CBAE0441CF5E3F52,7691248A377F5F9F,516745C3D1ACACEC,C081E12243AF649A,0000000000D18578,3CF1FD03A111577D,5917B8624998FE36,97859AA964474351,E6A3942D9B1FB9A2,E92C4AC28F6DD182,6079F6BD1CBCE0B3,BE18281421C72130,AA95187B89C1275B,A3295AB380CD5061,000000012FD492B4,C5159B8EC577A6B8,8439F75B84E48BC8,414F1EDB7390155B,CF8514609910EB21,7F776D59499C30FF,B179C13AACEE5C86,8686ABB81BBDDF39,2A2457EA33ED60B3,4DA28D21BF44E074,000000019236E930,24E29A25440824D9,3AA3B6B28B2E445A,CDF123327C1FA615,F242C254C6320333,9C63D2596B73CCB3,E52B69DE39875379,9E0E663A92ED96D3,D2C9311C6E4052AC,DFEE3E4F17417918,000000009BC0B281,243C4BCDA0C40401,00086B6C17DDF5E6,A7089F1600E4D16A,B4D222138B4F83DB,CEEDA23CA4C4A498,2D010EDBB692ED0D,669FC39663623C7C,7C96E5F6EB9D7143,EBDC7B162C178FB9,00000000FECED76C,196CEBDABEF94D04,F32109913A662B6A,99EF737DF3861487,97053F0C680B5068,598AE6117CC22E41,291153A9BC708E1F,0676E095ABCA30C4,F786B138572C5A11,D1E4D6A45A726B93,00000000C48F3CBF,45372B78F294C837,1BBA395AA75E17E0,6DEC39E8A1055376,B9DFEA65C69F9621,243C11A055FBFF6E,D218A62CFFBB3B17,1311CECD9D900A8A,7D31666EEE7653C7,FBF9C31D5062CCF4,00000000C8DBA9CA,8C40F2D66490768A,94B9F113E7EE545D,DC770CA12AF98082,017107634E02B2EA,D3C6A51C4641622F,512845DE3EF32731,450D9FD608BD10A8,9D7774BE6692A1B4,D732AE32506314B7,0000000126770A48,0BFB3D5BAE751AB2,DD86DC0D21DFBFFD,9364F803FA97DC2B,0EAF2548EA0178CD,D8B3B998756E3F6D,3AFFA5FE6D1C0CD4,38661A658D06C754,331E1015DAF73DF6,5BED468AF8FA5B02,00000001448006BE,0489AC0DEAFD500F,E9AA4836BBB94F3E,1E190FD9365DAA2E,47365C396A6320AB,841083EB596379D6,88A08E4D6C1AA81C,527F2027AE106C19,CDF2BADFB8100B66,E9B9D50B5C8D44EE,000000023E8D2DA3,7000FAA1A91C7295,48B8FFABCA3A5AEF,4F8C88BAAC94A45C,A45691655201F038,AD5419FBD4AB2C8D,18F497EA39ADE9A7,0745A9894A506538,1A896F0DC3C1D05B,E48EC9DE6998D8E3,00000001253ACDC4,87C8FEC776231600,C004E048C8499BA8,4B7100F36C2DFBBB,785353E23AFE2E3D,2840EE282410BD0B,FA650237A5C46503,6897FDB667E21678,566271953DC1B4F4,F2198D718AA50B94,000000004FAE5324,F132619638184B42,687F74B6F0253DC2,038EA4CE4BFB8F95,45B56A3142B2EFD1,A1014257EE554855,9965D5EC8EAFCE55,1CE4669095ACE6DE,092B7456E0D609BE,9A7871D68A77152E,000000017F45D883,E7B8B56E442765E7,7A06C7FA4A2FAD03,12ADDB528AA43D69,A22957C601B2B3CE,71C898194C41088D,059F203A85F13816,D30573B75F0064F9,7C6BED59DEE7C716,C97DAC01FAF78DF8,0000000110129D39,2D0E6EF003AF3D86,D1436AB5C618470D,6B00C6089519CAA5,8FE294A8651C1DED,2433DD362902392A,61634A5D7504CC16,C0C822CEADCD1FD9,3F6548B99CD91B46,356AAED604193906,000000017B77CAA6,CE1F5F17C059C0E2,6A9220B7176C51DB,05DE76D2049412FF,D0A89EE9B41EF5C7,F88CD1B99B58EEC5,064CFA2EBEA0A0A4,26D22EE5DA823828,255BDA958C280367,83ACA3C21E689437,00000001CC900EEA,8FB9DDC3C7F4DC17,FF4AAA44165D2FAF,A46988DD4EB1EAC3,43A09867D92D81E9,528283A5F425BCA1,7DA2E4CA46668A9E,5B199E1EA7AE9DB0,45DF708950C2E29A,41BF4DB28AC1DB36,000000002EB08035,C9F47F8231C50279,8EF3A5D0EC2416C1,3C37AC76384F1FF8,C5856E8379C29F24,C44537237FC60D5A,FE61B3800F3BA70D,3CFF4807F173F8DC,C9C9A917D30E0604,F872EBA19609EC94,000000011AB08FD7,C5D22ADF870C47CC,2F62782AFD40CCB4,622727213054C304,0815BE53CBF552EE,09232E8D73CB66F3,1D61DAB073541760,21B37A5879D6343E,FA2711970BA9DB06,F758F9D209F3334C,00000000551C693F,60B16B7AA58B1B03,93B34E32A05DFFEE,5328C976DF0600AD,F007D448DD322200,0C1B275DBBD000E6,ECA5A892C995DD87,1DD28F6EB7FB0845,63C70B28F442B06D,64C9BF7A85288D43,00000000ED2A200F,BE9F81800C3143F6,1BC8AC472448D081,46D42CEA3413CFCB,D5D01FD98045FD36,001E9936C2A82C90,ACEC3FE7D6689787,0FE99A4A3ABF7C2B,37B8B5B5503EED1E,C219A530B7D96FD2,000000005D832F22,0686D1BE4E407D4A,50C463E6BC0C415A,08E9F96E065C1916,BF715CEE2EB8C74F,D1E594B98EAA618B,D6252EBA2FF67D6F,DDE22E51081E3F5F,C87983CF3DCE98C7,9750A5681714DF84,000000012675AB4F,945592CC36208B52,7AE4A2F010719ACF,B8BF5586F12FAC4D,139BA5A8D62178EB,6D0711C2BE4D43A3,7CEA52DEEE8CD808,0020A6CFBE5476CD,28725317E0F93CC7,B5283F691F557D58,0000000071A46551,5FBF258EDDA92947,AF5207740FAF85CE,2D8CEFB00DCAB047,F8B57B3745077B71,9B7256DE4B932729,5C6D54B11C9D16D5,93197AB9FB49D8D4,A5BE5B5FEFEE4D1A,71B21010DB7481B9,000000003DF4BE0F,081F8C2771C186C1,5DFC10E760FFC440,9CD6F8D3F111BCF5,6242AAFB37A8385D,8D0E1DEEC93040B4,344DF0E8A90CCD8B,2963F7438798E6D0,C20D4A1C8307BC8D,AA38DE450803A9DD,000000006F682D95,C3D1D4F20ABF4100,97336409CA4F0375,2A9632D77407CD13,D4C2C4114C81C6CB,0BF23A0837736FC1,5F6974B49184BC64,584938B2FC3AAF0A,66A663EDB4B813F8,D6A6BD900331769E,0000000143920160,622C53FC5B0F5214,67B9B7BC79C029FA,FC8C61DF75107497,48F26F57F608B343,A30393FF2FE07F8E,1CEC7EED651DC75B,A1E9BEB2E0025993,8CDC08B86B89D54C,0292794A9B77B75D,00000001A82345F8,D091826803A375B3,FC9CD19616F35E4A,5CC7F6974AFFF362,008584A6BB037FD4,5B3455CD480D8D0A,2468C9F1075C44F7,0E0C487B3464FFB4,DE412E53A135F6E7,605125FA348BF76E,000000014CC0F067,8B76044AD474BADF,42DA29F03873376E,1155C3BC0060AFEB,D335BC1EF44D621C,EB452E6FAA164195,6A9001F7033A8E96,E1B420691899E010,A9E9665CCE14AFB9,2AA783A815FD042F,00000000F3C4FFA5,989BDE1C6BE0DA2A,2BE8DA1ACE157F84,67448BA99287DA54,E7B88BB00C408370,3012A8056DB04FF0,FB13F89020F914F1,6D9614B9A441A1CA,CBF0CC2C16653305,4DA2F99C71E7A55E,0000000157971121,F284B260303756DF,44806C6068D9E29B,ABA6FBA2B960C1A8,34C8D1EB17B6C9A8,6E9127CA63E4BED1,A7692A928B60A681,1965A5312A686A03,24710489BAE5C548,38F73E05C9DF2B7E,00000001C9BDF624,13BD1ADB91F565EB,C3CCE398CA8D2D3E,06E31F1D291A193E,3AB3F0AE4D95CB4B,A1DE2BF690779D05,2E13FE99D363520E,DB6600958D72CBC3,98428396D687E7BC,1B4DF070E01E20AD,000000016F5C790B,0D301E361E78F4DF,E1AD90BD1AD9E8F0,F3C40ACFDBE4849F,FA8E9E9930DFC6E5,B0EF93524E8509D1,EFE88C1D93607404,F1C59343B82C03C5,A9C7A71118B0094D,A7D84E02EE989200,000000015C6AA05F,AB4AFFC8EA4BECCA,E60D160B541C91A4,B3E086248F54218F,B7F347A9C44C880D,E57B4613BF2DD4D6,3BE7DED45992E3DC,B3D13A8FCABA4042,727031DD99EF3C0C,6ACF4E0F3E429281,0000000265381804,34725BF75DABC81A,69674F7C407836CE,FB9180DD433AEFA2,965BF7FD2599E56C,361E1795F1B02137,FF3979327C724D24,FCD79F9598F51324,8D912CC8A5F31CF4,603CCE375618FA76,00000001A38AC8AC,2F2EB7EACDED3B81,9A0CCBA7633F6B6F,7AD28BE8C625E9DC,EDE5E060D65ED5D1,CE15BE23F4E66705,C1B503DA30CFD059,EB85709FF91C2277,AB655770ACE76EB1,8FD5BFC389067A59,00000001DE7F84EF,5B7601EEC8B63E11,71FC2ACDFEAB1D4A,102118FF7F77B07A,FDCF9005EB685C59,70993C8177049F3D,79A14732C41B9A2F,D5116C74026C7C95,D88175DC99191177,B1E2AE0842F29FF4,000000012BB3ED9D,FFAF42F9DDC0E9D5,183132E742E53106,962B597E459AE107,1B39D1F976374ECF,25CD7E3E6B045377,546B8F99D4D865E9,83697AB57D3994C2,844BB527A158B19B,FB41D458A571F725,00000000617509B3,F96B7D7EC2ADA739,9F40863C81530368,225C4755DE38E445,28F1D0B89B067921,0F13414893A4A72B,84B5569501258D47,82DB72D68C2DF190,2139F61E4587827E,A44AC7F9F2C0CCFB,00000001056D4B8D,259E3C1984641E51,5F05BB7C9EA09CB2,F98865E31FC1B6C9,BBAF105C212E131F,BD431268C5F08449,02C9B07213AD7E2A,045E98A6D29C8776,85E2AB4E548364F2,2DA96AF65A4F8F31,0000000121FB3510,021CABF578F2073A,3872325BDF1C7A90,619D14062B3BC743,805E10AE9E74792A,1A565ABDD1CCEBE6,EB720B6D5FDA561A,7A4F465AD9CBB651,AF7B94EEE16FD04A,B2599B8F6AD3EB68,0000000101396E6A,4F82C1D207F9D19B,86B3851028096C6B,0B284975B0490EAA,DEC008567FBFA21D,D21D33B3D652BEAA,F405B94DB7B7ED9D,3CFFE2914B82E89E,F5A78FCE2A224675,100596B5ADD3D697,000000008B6DBCEA,9E088BAF745F524D,05FFEC8D4109EBDF,1E5EE343E7D83FC7,A040887443A4D58E,665DFB8AB756436F,3FAE9640391F6B33,0D6B8CEEECE07824,822386AE588D954E,2EC91CC74E8CF344,00000001C67E572B,EA8C1C9E98AA1D07,816290A408B67D84,80A8C4B4FAF7C0A4,AEE5046525AD346D,9ECCAE7FF2520AE6,364C6A9EBBC46B01,B89DDA301FCDBAF0,7C49D68BDD3FD9B8,ED205BCCC28FB634,00000000CBAD0083,C1F23772E7DE2BB3,FC4046E778356B34,C68BD3279292B201,BF864681398B592D,0ED7B85B0A177258,62B10B1C357C164D,FA5DC877CA36C266,9A1DECB5B1CB88E2,A66C21AF1BC4AE7E,0000000055927056,0E6010E743F874D9,BC786F66EEC85EF1,04F9111BDEE1EBB9,1507CEB6DE9AE101,683CFF7169445E25,7E223F299DD4F803,16BD851F270F8FD8,B7FA9919C3A41689,DCF1DEFF7457AFDD,0000000150DB31DF,85A9741E2C0CA977,4DD210889C901065,D50DD4BDAE6303E3,20910EA2A45510F0,A22E0A6DD0A0A5CD,AB5BE9959DBAF901,9F54571FD04B678B,23861E8FFC4BE950,CEE4ED112F6FE076,00000001666D432C,2F45471C47992F26,4D8E74A00BFD2343,1FFB744A754A57F6,9450EAB5DFD2EDFA,B1886A69D6F2523D,5E229B00645FB7A8,1C40085604A2FE91,01833065822B1DE1,3F8F32909E5696E6,00000000BA03C790,FD60448825C9C6DF,79C887BD345F1865,3D63BE67097A6ECF,58EA67EAD20714A8,6380A0A1092F4A6F,1578EAD2693DCA1B,37143445AD858113,7F11E32500D5359B,D2B740B33F8A26E1,00000001DF2C3022,D6CAF7D52733FEC0,50088BF0E3BC713F,EAC56ADF2C84AB15,5B0F24067783CC17,03BBEC5661EF6766,D9BBDA1560173CE0,9DB13398ABCC5ED8,24496C9AFF18E67A,E0A3605B1FF07E3D,00000000D6D90584,945BF270242B1B6B,F0E91AEB9D976E30,910A445DA0A98AC4,326F6B3B2F5CF1E8,CD8F189436A1B817,FD93EE0EC7707F4C,34DACE6AA6050400,1D93D433A18C8EDD,657348849536024B,00000001181253CD,D34637A858DA225A,5A5E8567B403BDFE,D27446FA01324725,FADF6838BD15E389,EE78108DC0BC233E,08A534871CF40BEF,94241FF1695D11CE,C7A05150C27866CD,40655B47324CF6B2,000000000201C1A7,0F4C4817FAE76ED9,EB1360F6D8DC034A,47888623DC98EEC4,F1993DAFAFABC0A4,D636CFC4DC9AF447,AB0B80C20EA282E2,8CC16E52167A7CC5,0F1D62CE1EAC7C32,7668AEE125A81560,0000000192AEEBB4,54F941FEAC20DD50,7EDC0A2A7AA1F4FB,93E797E080C067FF,82D3A19C48BB6717,95EBD1ED54795D02,2C0191E2458A17D3,2CE6B64CAE02E08B,B99EFC60F606D0A3,876BCC823EA9B5A2,000000000285702E,7E23DF314816A87D,8FFD11B218EBAA97,9CBBEDAC0F7FBEEF,690B477A8481FDE3,7B65F4695702B840,3B2B14749F218D8F,CC26D5C2891497B2,2D6891A353C3D5BD,FCBEE6DC02241E4D,00000001572C1CA9,BA247EBF24144FC3,274E81752052E9E8,26474C02456A11E7,377F301A173BDFEC,CE3B6BDBA4E4BF84,6696B4399822BC03,AA94174CE39A60FB,28F81AE6E2C514D0,126DE53B1EF8351D,000000013AAB5C74,314915850F89C73E,938A295F9EAEB5D0,DAD402FFE94EB1E3,F1C0EF7F5ACCFC83,77B0F02523A6A2FE,39E98DF03E6D44D8,5EFA728FD4F4E56E,62ED8569FFCB218D,D67682DFAE05F034,000000011AEC9394,8FC53B54E06E4624,03C0C8774381151A,73328233CD4058A9,1B35B823E325C8B5,90EB029B40D42F92,34F9CA4A9503E8EC,67ACA333E48BE404,8A6BEEDFE26C2A28,87FC642F69E0415F,00000000965B66BD,EE72B04556A93D4E,0C9D7132F47B8BDA,B03257BEF4CB448A,9EA605A9719E9524,28BA1F8E22B363FF,5C957CE43EB27F82,33DA46C1B9B0E729,4F5578C56ABC9AFA,36BA8D972B7D1604,00000000EDBD488A,B085B872FBEE5E58,C259097606E91D13,219A8EE868C8F8F3,22141A5CFA1BF39C,DF701E78B28A4FFF,3A201D22989163EE,5FE00DD4A0B0D1AF,47BDE5A775635E66,CD3054036EAE01DD,0000000220B89816,5D9AB8F9EF006F3E,BBAC20A5F3A13F85,7486DC6C1420297B,989CAF9511491034,69FC0B76B6EBD248,997555548CB5A3E7,0FB20BB92F137917,DDEBEBC3DF856D86,349643B034629AA4,000000004EA48773,320AAD176ECD56B0,169130CB6047D63C,4493BB7E1770EFD3,1B3CE52071D14F7A,0C5B82747907361F,CCA783078E38770F,418B407882E686CC,2C750CBDBEB56D63,983C750732BECAAE,000000024A01205F,3EC46265D00A7BC0,94C6DEDB95CC45CF,8241F412F0F2FA44,23CF4469D4F14464,FCB86FA8E2D247C2,8A1E1B50B40B3FA9,4F84587034F75E9E,50A0843D09D1BE26,988F7AE44D97BFD4,000000009D5356CC,67156B57520A3130,EC79580BD073EA33,459585FD812D7E71,7DEDF9C3AF73471B,3059EA181CCDD1DE,3D10B04763D7F022,C71B1936D91EE9C4,3528120890288D67,53727ACD71927468,000000007E37CCD5,ED4A5C139E4A6D08,91C72223A2AEAACC,2F24EB281408CB87,C191748327724FA7,5D187EB4AD644B2D,EAE6C7E3276C809C,D4EA762A6C47DC5A,1C67F8B2CDECF612,CD60BFF7C869003B,00000001679B9E46,4CDDA55732F539E4,41099F280F1F90D0,D8E4F1389AB75585,B3D6113FDEF87180,16078013C35F4D99,233400325B79C8D1,4593A7A14E2DEB93,B77A91A9363EA747,993957B6EE1D14EF,00000001B453F416,2C75F1E3C39B752A,BCEFF9DE221705E5,1079767F354E0BB1,B9B6E0152C88DD2C,2BFE7DE4571A791A,98D181E04CFD0D80,8849461665BC2E9A,6AEE095E0B9A630B,A7D489C16EC28D11,00000000F2D35E9D,06A32E9B05B1DB0C,B04119563444F97D,CDFFDFB2F9FBF853,26925139C29AE59E,9BC19B89915CDAEE,D71F1B56B1E366B1,E7367F90EF37AB7A,45DB33965C914BE6,E4EA29365C432322,00000002455D472D,0F92504F2C1539DD,23EB214BC495CA06,1FC32221EE3FC3C8,8047F1EBAD9E884F,7047A7CCFB4C2156,0D660E2749444DD4,C0440CCBA0E3F4F3,5618AF363974FFB6,4CB3B6A014FC17A2,00000000F09FC4D3,EF7D0E8EA6CE17C6,906583A8FAD03000,B8C1FD0CEDD85364,36B5DFC84243565C,B6A201450FE3171D,34A3B50BCDBFD3C0,CBB64AA051BB6081,38438AC17FC0C179,1CC8EE449CEDC554,0000000035A596BB,83C3233AEB1FF18F,BF9F4A92177CBE75,D7AD4BE8F85B955C,746D7CA6591E626C,EE5F6A8ABB54492B,DFDCC549896BFE96,BBD7430BB1A77E7D,ACF316449E32187E,61269A0B7E410840,000000017A6A5464,579F57293ADB7508,FF4D9F446D8DC4B3,5AFED4FCD6F5F021,65954FE40FF467A4,D3A1FC8C2D96CE24,FC8827648F86A682,86DBB4AE10DE3EE3,AE59D0D18713FCC4,54CFF31FA24A1718,0000000161819081,F2A3D9E86C60453F,84859BAA5C575E41,551D260AFE47A473,A21D4BA1115AE2F1,D313C15A197C54F4,A725B34DB40A2C82,1BEC13F25B485BCB,205DCA4A9F3C0093,8D6E1FECC7FE4AE9,00000001C9D39BE2,7B601D95A4EAD6E9,35119EAC881B25A7,764698A6482DE778,C0AAD9266113D391,FA55B80120BFA4C8,B1A09D5299817BDA,01C5EFE6A4DA1B58,03F6F4FB5711FCBB,CF9375E4F4F29E6E,0000000056DE8D9B,7EDD15AE1109ED05,A52A753E4E3BF2F9,CFD377F516C0152A,6DEF0432AC54E2D0,012C15BCD26846C7,59208E7331B25D69,485E6B09B395E959,9BD70E926F386BB4,8AFA5165DEA65ADF,00000000C9609130,1A9B85AFA46E725B,EB8A1384322CBB42,1C4A8F6D4EF19887,72B75E8CC2932B95,31398C7E90C49158,AEBC0D88C0E7C35A,50E43965A474162F,A98A75F48C6C44EE,93D50F2684178C30,00000000D815211A,58ECA4A4B60FCF11,A7EB94EC0A17B008,78A14A09D6962562,1A83C91362F79A34,2ED843EC7D7784A6,5A6104F8615DD2B9,8EA2DCAFBB6979B7,5590A7C641034F8A,A86032FF9994E27A,00000001B23C39E0,2EAFCFFE3B3E5A28,B8AAD8C4DEA008BD,177FE7EC728D14E7,E0751D510FC927C3,3DE75E9EAF1B551F,5E8CB3E634686C91,BAA630165C1FA998,BF54074560260F58,F1BED90C14097AFA,00000001D4B6E30B,9F69BA9DC15D9CB4,C3429D9D4BD1072F,2A96925FAA44572A,BBC8799FAE651A00,321C3532ACFB44CC,C2FC4879B1F1F2DC,237F28F0B85129E9,FB9A0DF365BD0B23,71C95B384876ECCE,0000000149B39E8D,57FC7E3B8D41D192,81A61A79481A2DDE,F7C6DE5ADAE3D2A0,5F553BB0CCA383E7,74D7DFF72ACF090C,16673CC19F5AF092,E7A1C2711F331ADD,FD3B43ACE9B70F17,F4121EDB69E44CDF,000000024E180ABF,1D84A4C844D634CB,F32131D5745F8C71,B8B0949661B60BC7,347C4C78488B4EC2,0898D349D427998B,1E8A2D57F3C47A84,549F97634CD8D3E6,7D947F822235ECE3,1E3A0141E51097FD,0000000065585574,D428758C06AF792A,5B453037A498ACE1,9E1237EAA4653717,346410D305CFF311,922AF9D191D4265C,733A183F9B133ACE,E26AD69CD7F4A8BF,B7BC17DCEAE5B21B,103D0E8FFDDD5E38,00000000FD59402E,D20C4F10E18C6CDE,57715549809C6687,AFEA8C5205B7A11E,6D6DBFC330AE0590,7B90CCBF26245797,93168A58D7195CAE,0220B84D21FFB39B,B942811368E2777E,EF0F7B4D3CC7F70C,000000023375B2E3,3BC844EB9FDE989F,C679DDEBDA560C12,29901F83FBEF5DE6,2EA51065874E004C,F03C6E5A7F1A9D0F,43CF9A2A9DDC1BDB,B5A0083722AF5EC2,B006CE26C11D0F3D,7604A4730FEC131B,00000001F80763CD,92086801DDE24214,3AEA0F9C9620D1A8,B0000780C35EC10F,A28F1D399AF729D9,5D3D9277C04217F9,A99ACEE4F4A35560,75ADD752D51DD763,23A74A57F7D17C22,9DE67788CC70CDA3,000000002847290D,D68DAB07CE681FCD,7DD0AA7205C74D58,53D127C31E633323,43ADC5057E3606D1,C1FA38F3852DFA4D,FC079B2B3A36D0DD,EC28116BCD156062,E3E5BD501475F15B,A172A0DEE79F8807,0000000127345AEA,D8F4E0D568776A19,DD32955EBCAC35BF,74D9D453CA8ADB14,38FF26DF14EB6957,CB3E42B88394ABC1,DC275F4A05CA4AAA,ABA70D539D19642D,4A98AA9F7CA7565D,7005C04FA40472EF,000000004D054474,44628742525519D3,5CB9DB74061B3469,AB802E284009EEB1,248240B68B25D4A7,04708CEF6178C480,96D5EBEE9F8B052C,558E7FB559000E40,3C5DA9CBDF636E37,DD318CEBBD9ED7FD,00000001A7C4D4AE,BD4457E633A496D3,19FED2756BADDF6E,BDEC334E4738A72D,CC19DC3F1B082ADC,4E0ACA30D50E3978,EAE5504BF85F924F,FDFA9007229AFC52,59359D008D0E42F2,645503EC401BC298,00000000B990CA9D,B48B82702B0699F6,641F619305C890EE,8696B55D2504E20F,DAEF73C1C0C8310A,9B62572370F3FBBE,731529676C4FF6F3,FE5C54DE2146AEB5,847C7126099FCC95,7A1E5D13FB028002,000000001984C1A3,DADA7118B941E472,8FCF759D6D5AB8E5,79F99D69FC59FBE9,78668136F07AC1B1,853FC54388695696,DD15A7E24A19A286,110DE2A1666B107D,7A32F74A916E5C9C,B79A795179DC7FCF,00000001E1D996BC,CF4715DBAAD37BF1,0C6F513F7192065F,E56DCD0F35AB321E,7CE8C5240EF13169,A759FAD771779A4F,DF9469776025FA0E,A4CF5DDECA7F8375,FD67EAFC3B7829F6,2FFEBCE5B9C356E6,000000005B9383A3,DAC80EF1C1149593,9C4F262D7F30F3C3,E21E373D17141D8E,79B02DF845C71062,FD12F2CFC62D387A,CC1CE781E26901C2,A6502B7411E1F4E2,6FD50AF0E51D4A17,779529BC34CD1BEE,000000026B93AB19,EC720E4731F2D519,7D01E676F92A6934,55D3FCC3560F5638,10C571136D50EC2E,D22A4A2FC71FF60B,12B44AAA1D1AD5AA,734166839AEDA4C7,3B16FB3224B16BE6,5813C0897CC4AC63,00000001ADDA8F33,9C1737CF35624A2D,AC9F85A72F43FFD9,8A0285E0BCD1A0C7,EDBDAA5C883F00A3,9E3B123A5D483326,E13691F8E446EC5A,53C00AC51145EA7B,6E704251DBCFC5E1,15AAD77B2B6E6CC0,00000000140442D6,C44606912F0EDB19,2162C4549A7D4E1E,BF0EB457EC06C3C9,4E6A172881CD2D56,28BE8C5BBF8D61EB,02ED0CC3CAD8EA79,930970F9BC21B511,ED8BFD00E3062376,FB92F0F1424B31C1,00000000FB678C62,C52F2C68DFF83070,53D3DD06D8982B2E,FEC4CFF332DC295C,8A2ACC519E0D1A83,303262981C656222,3622516960EF40A2,0B5FE74BA6C4145B,5619674B3F8F1399,AD854A23541CF548,0000000080F3D9FE,4CAB4182ED5B0DB6,FE4AB7567A182E71,1A3F43CBA6BAF753,41472F92F269EA81,0D00B3FA81372F1F,5586C6B9ABC19002,98DD18C58A3D3FA5,292AAB8155BC8DDF,CA0EF9B05C4C43E5,0000000256D93928,004F34E0D8718569,273CC7488B14BAD1,529E5301D61ECA41,41D94C5911636DA4,91377DB73C597571,2BFDB501CBD72A09,4645B13D12A3F2EC,A6D5A0C20F7E8394,DF7CC31A4495EF3E,000000020F498153,C2D56A412CD840C5,9AF0957F4EEDED9A,C0F85DEBFA34FF9F,19B63077FD256159,E1817CFDFFB90FB3,92B6F96A0C93B73D,F11A1B8614AF743C,C7CCCCA42E02DC7C,EEBD45ED6558E21E,000000009007E071,93FC7B54B4BF0697,05288D5327551320,46211F41F2E41376,A4297E0080862FF2,3F0CBD0FF854DF02,B5420C46F5708494,25F125EA1E9243EB,F40AB19C85015435,5E54892870E5EACF,00000001C0EF6128,799C8D3F234E3122,FA93A8179F5DFB62,BFC8634C11983B11,4E32B28321D21058,8F7CB0624C9C3440,FFB9E98AED2A758D,DB5C19CDB6789A41,327CFF006867DB52,9116AD6101755865,0000000137264E57,742B86721A2751C1,2FD5EE273423DA73,4FF76FA1F99F4279,45184553F8CB6D13,239964272FDFED89,A3F2E0AD5E82E67E,34FDA6E31AAC5CC8,1AAF5265CA12D9C8,895B026D04BE8EFE,0000000107712B69,4AEA256C6DAAD139,02F14FFD368F4907,0D1F9ECDA8848CA9,57641816BC5C1BCF,BE0FC177846F5AD7,F6A89512F8F841D8,C99AF66BA4413A54,4DB730877C31CCD3,19A76AF29CD22A64,000000008AC3EE69,A0C374A7EE012817,3B791E67FD7526B9,BD7D7449AEAF478F,DC83D22A7C43C8D9,A778E73327C740A8,618288A44FFAD9AA,77F2F0BAD8F5FB57,A1D88A3B8F0853B3,DDB1EEDAFB2E207A,00000000DD3C6A25,5255FB410E3909E8,0A3B111D8170FEFA,87740BA535B6FA47,1F76899ADA6AC0C5,0CE55EB1EE2B8B0C,D8DB243D5277CA86,BE553FBAD15AF388,E210D1DCBA6A5BD2,64026C5693530F28,000000023A69A045,06F101632EBA20F5,E858F8852BDE3D19,889E755EB2F5B7A1,F79A5B2675D4CBB1,E2A4D572EC7564BB,13E51A5BD23774E2,AECE882C20B65448,215A134FBAE8716C,EB4C950836B2B916,00000001DE5604D3,E5DD72C4F19CE911,3C8A83B76CE4AB80,810B85F94922A9E9,444029E2D538B82B,483628CC75F5F3D6,E647BE7614B8F629,92F5560B990E742C,931F554DF36F8F26,E693DA65248C4812,000000025DA8E8D2,5A890B5730D34387,45849E383E6A5D4C,22E043B717D0F640,36ADA7B5E6AD2821,DEFD48D5CCB83654,EF3F5DB57B7F063E,244471F25F5FC329,62DA4434EE2B70C6,F13E71412B45FB04,000000023671F213,85D8B64ADCDD3765,DBFFCE488AB0CA0B,04F25ADCFB298D7E,0FD408C2A1800B29,630BF451AA767DBA,F81D3D0F197D00C1,3B10EC0ED79C4F17,B07AAD3FC7B49411,0F44AA89AEA3179E,00000001DB12D4F6,7CFF6452A90E8CEB,22E43B9C0FE304EB,D0DA96B770073A13,AFAF39C0DF85AA89,3E1B17F24373509C,2349E560AA422850,0D311611807C2DF2,0578070356F8E251,E998B3B3E2811ED6,00000001FC3A4CC9,AAFD1822EAD0B441,57E2BA0F363E7085,F99D14F229F0298D,91C83EA7C228CFFD,90F7DF6CE3AFD450,37E962082489C3C3,6C5B02A686E179FA,449027815E1B1F43,B852821B0F9CD38D,0000000151E446AF,06EE077D7EA7C38A,AD6A2A85D9FE1331,2D25E72F655F763E,D0C454E1097DAF5C,599980C55A296348,457FC5886E65BD2B,F02B3DA372F34054,554E4CFAE1F25B90,7B6B6CED06CF1FAF,00000000328F55DC,E60C936D0C40E743,7DDDE5F98D912CF6,A8CED6DE0E33134D,105AD1F95F532E05,73B1CDB77604155E,812EA045CA583950,A554FEBFC17FD984,68C0B7AF55E04D15,A5BF34F395E1A1D6,000000015B32343C,A26E6944D6F68A16,5761C702FE2B9077,D75450F493A7D199,222E4AD9B1103580,B12A9397C2558530,B179EDF9B1DA7225,5C9DE9295A6FE051,A9D6F2E47D4A8FBA,7CFA489F897206B0,0000000043BD95D2,D051298E24C98A4C,B9634C2502D01D9C,DAC703874F565432,5362083568F0D19E,CEAD54A13F8C93E2,5E6BA9E9BFD707F4,559B0E1960FEAAD1,2D67A1E8EC872760,54A1DB1F668DD8B1,00000001E1947653,3EC1A4CEBC3FFD95,EE434D6BADA8AA8F,4AE9FB9286D4A48E,7F6991C6E1587F87,B4A5F959E14DD694,BB4A34AEEA56CD76,33A0FABE14CC2DB2,35BEC4318E9EF55B,49BFA2B59ECA72C9,000000000CF7F0F1,4C3A8F2BD2097676,903FE2193EA68FD1,7DBE722B39265385,4AEBE87DCB7E119F,AF6F51CEB3B6969D,5D1DF88E84F7DD50,47BC218DBE5ACE5A,15656907DC97D97C,968451941353ED30,00000001642DF3EF,985CCA0E56054C86,232F97188D6A6569,05911D900977E48C,DD626BD6E40D9524,FDA8FCE05481BF77,D6AAE51DEABAEA97,B691DED5CBF5A32C,DCC31446D9E3B685,E4020289C8C49D27,0000000211EA2FD1,974CD43B9DEC1515,D644C41F6AC35E21,C1C2DC98D0677E02,5F1CC73A03DCEC64,EE6EEDD2495398B9,7F57710107F7DD63,BEAEE768F75A6EC7,29BC7D9A77BD79C6,3D507B0BC6FC0DEE,0000000051145541,6C0A9DC44D25AEAC,1E1ADA944FBDC16E,F906C365C1DF0F1E,69B29EF739DF3572,4C1B886359CB60F5,050A846171FC985D,09932E0D727BFC76,81783A9294C913B2,87459E16E39FCACA,00000001473A96E1,E5401C493A97DDF5,D5B242ACD9DB4793,A350D4527FA93E7B,9928B807723F5E81,A52A060D832A8A06,51A6149D290825DD,9DF49A17176EC89F,AB2B562996A92AAA,AD182273459F8EC5,00000001C8387BBD,0710B951A8A32C5E,A5413A963025DDDE,70935D63339C84AD,1522EEC70ED2FBBA,6C6CA06F651841BD,EC40F0A43B6C196B,11F7DAF00E7F2C13,6FB651A128998089,CE46562359735ED2,000000001D8705CA,B9C6DC1D0D3505C3,C710AF2D2B5095D4,E01175D9580E445A,269EBB201901AB31,BFD628D1EDEF148C,C0D96DA5C01DC734,4191CF1B4346B66D,F9E4AC1C244F987F,BD40E6184E9B01EC,00000001520E8621,95AAB42FCA83C317,C17AC79D65D1ED9A,B42344F83028A0D0,E602BE92D818B9BE,7782EB49F77A6CBD,4204710C225FEC1F,28CFF772840457D2,3AA477E4B17CDA06,3428D6C8F8EA42AC,0000000205FE05E9,31512A5C70691AAA,6E5D573BB6CE42BE,AC2C7297ABCAE599,D8F6E87A4D0C32BF,DD42092A3C53A675,BF4396DFB534C29D,6FF7F082DC3EB7FD,C308747AE7119CF4,0AA47FC60EB53654,0000000242D04468,A65879F54729E4FB,6CE4B972FCB40B29,B2BD08A63EAF8627,158650381A5A8078,D8BBD23EAAEDBC69,A5ACB186D38DB124,7C6E5F63A163766D,D1DC014C70E5574F,EE831D07AADDA498,000000014B1F3F3B,B624C1CE4DFFEF14,F3484B79B9F95F31,B67224B20BC9E299,A7A8559E309D29E1,D609BEED53C3F9E8,FF03872C88C3F2E5,085C20CC6ADCE8F1,765825F32BDF00F3,E5096BFA4B495AB8,00000001DE51C3C8,D9AE630AA9E7C172,903661E120F8FA8A,760958ECA46D9704,43DC69E992AEC8DB,D84B79AC5396FB5A,03BB47520191E1BF,543FDD213E4CD063,44B6A2F86C79CA1A,F6538C3AC8EF5A3E,000000018A4E4391,EC99D79A450135AE,44CE2F3354F18100,F836AF701CB94BA5,3E4084AD3B869C30,3873F22D98575E7E,9577A154C339B3B8,BF460864FC0F1B23,BB7335B144F30494,2D2D5050FB60A720,000000003BFA9004,B48DC7EA46B35BD0,29CB7594EADD1BEA,43478B7F0B00765A,DF9C5F70FEEE9BD3,5A6DEE13AD7FCF68,1A4B128B2E001B0A,F813ACB3E69AA218,F7748CC3E17C321C,4B39DBEDF1DE9D5E,000000020A8EC43C,4C3CF73DDC6BFAEE,7A1FE6FC43F77B98,99576AA40BF6C3C1,B81B8614763AD508,AD8D5379B0993EB7,961585713AE38B83,90BFF476C748E47B,E8952A5A71F788C2,42BE0367DC044C61,000000015BA2A549,1292CA6ACDC5073D,0EACA815FF47587C,5FDC3E742078DE4C,F251AEAB3681500D,11071E9158340184,FD1A889CDD42F325,A29F2A56D03BCB1E,5C978E5213F0D077,F7ABE361A4A2B232,00000001BF4243E3,A5FA01B13788FF88,3C928BF82C0840A5,85E924D86E53DF97,668AD4180BCE36D5,42CE8E298BF608BF,482A41639A4240F9,4A3CD01ADE8791CF,58A954F6ADF6B7A5,8BFFEF8F29B67531,00000000CEFEB556,C640A1A29A138588,D07822498CB6C87F,4875B2DA855F0225,8151E677C48EAC2A,6FED459D9908B9A5,7E0A6F011D4B359B,31CD957313A938AE,46EDC7A049EC28B3,0BCB95694F3DBAA3,00000001D1130F29,DC7C20B72EBA16D4,14ACC085AA38BB9D,7D83A6EB391FE963,61B38567904DBCE9,A391419C27E206CE,113624DEEAFCE784,F966F1895FE24606,525EC27A68FF17F1,C4A9BF4BCD05299C,0000000074532135,BDD616B184338D67,B48A0B875427C3DB,7871B64A87F4DBED,0215DC98F9E0821C,C15A1992CFD1B91A,A39797AC0B2EE8EF,571ED24EC9724616,E0DC1F39021BA3C7,7A569A724FCFCA3B,000000012E12285B,6E163F2E82C11864,D9075F3948BD0F8A,D0ED6477D3C891EF,5961C3269C68CA77,BDA3BD7A457732F7,4FA1971FE10A714A,2789808A85DDCBC9,397C43461F1908F9,CF2B2B92B23D5931,00000001A3C46274,47F8822E3BAB2394,483CA296F82D980D,72C3A8BF8179AE6E,9D7C6E9CD305E5B8,025C79F586665CFB,ABCDACC605DD1CE1,43F00BD651542F6D,ED07300FB541369C,8BA661281B32F108,000000012C1ED16D,72729ABD202AB378,1B1FF6844E371AB2,07745D13E5E17FE7,994C3AADE98C4067,9A07FA5B92E9022B,CC8AE4A59DFE11E3,40C0EA99813F10DD,10C031CEDE29C155,3DF77F459D60BBD7,0000000144D425D0,EEF70EB2C00E4851,F4005A3BFE3089B8,4EBF538D2132D740,5FB62838E8683E7E,0945386BCE6A3D57,FE82BF0A3186133A,8D50174FEFE7E8BF,CB3AB424C1373109,12AA6D0EF51C873C,000000006C8DF919,D928FE9593A04A95,197CC8B3074343B2,1734197684F06056,B0810B97458CD59D,3348F942ECD3194D,CF16E9B32D30A8AB,24000A3A3F06CDD4,EC4D729BCB80881B,ABE0EF175252AF8D,0000000270270DDB,27DD8086AB52173B,B94ECB3BD64A9C2C,861D7AC2D9D06B6E,0EAE561706DA877C,057C679CF5F7C8C8,67B0CC4F6357B451,0BBAF03767D430AC,3DCFDD566265C759,D7C66410323061C3,00000001775CEF7D,782E1C2A669343E3,048B6EA9E0E9A71A,855C726FC58F0A62,5BADBCBBC31F8043,F013E94197223B8E,C59CE042368BDD27,CA02B2CD15DC7CEE,CCB137D29B27408B,6610EDDC84497003,00000001BFAFCE28,ADE50B95A4E89A57,8A3D00A08895CDF3,C55518AC6EEA4F29,FAC6A3EFEF9F395F,9A0E2E5C042B28E6,0E1C95EC1F622FFF,4B8BF684F234CA12,D03638A0BD9CF8AC,83F8EF20D7789255,000000024B7F73C0,DDE6D87266D5A6FA,983BAF93576710CD,9D9CC89084C319D1,77DD9F34D3D02BF1,A8837D35A3A4E39C,D9DA8687210C4ADA,4E1370610B2A1F43,70BE9D14E34B638B,C60582D1FCE8F08A,000000025C1E5275,FD61869795C1878C,12B7499BEB98BE06,1B9992CD2211590C,4E8AE93990FD5153,4195FBA6B81B605F,9DC80344870DCACD,56C53A77A567BBF0,1751CEE629D8F6C7,EDEAA9677F610C06,000000006000AB45,AE9DEE14B64EF310,2814B8C48108B8D1,BC0F55132BED3FC6,4DC53ED3D8AA29A5,FEE2D8C640AC2C9D,957F4AE1DD307184,3F1718DF2A7B0042,72C960173A73BD1C,B4807CDF7645C2C2,000000013E4C4FB2,91811A9B9A9E74CF,6C7972B6C429835A,487B84CA9F05B243,CE5A9900FD5B489E,E63C6F251E00527F,B7E7CA4543C7FE77,495DABEC9B21E46D,6A0ABE7EAAE32BAE,E1B18ADDCD1B3624,00000001F8049B91,A9856C286E890E67,B66F0A67BCAB61C4,D600AB5B6AB4047D,183690FAFBDA8F71,ABB2F28AD52E03AA,5EBDBF6DD3285864,F1FA5865606CC5DD,5AC29DE4FD63B52A,919A2E76642767A3,00000000705F9254,11B96C6E6863ED25,21F2E5115630F2AB,03096ABE237ADDB5,4F11FBE5085876E3,C431741B7BAF6E95,5B118E5BDBD65290,B62E66BA5D5FB27D,ADDC5E134C53DDE7,76A27992B16A6B20,0000000212045564,BE7D2DE673462DE5,C9D064DA21B7E9BA,31E33FB1113751A8,ED50C2D7456C3692,8E46AF3550E235F6,A3817EF55BB99BDC,537831AA5F8E30AC,63A768F8DCF63031,DD14B41929C71A13,00000001FB3BF2F4,40154A252E13276B,C7B456E2E6F57163,7B231B5D50FDE0F2,580EBE7714AD807D,86F14C4D0593AF7C,47FCA7796078B71A,DC7297A7119482D2,CFD5F1C8504817CA,1C09A1376142674D,0000000041D44D74,90ECFB2F85CF97F0,E0B4550E0B0135A5,964FEC67A38B68C0,74EE08CCA8103CBD,4B93CE03DAF3914D,A5483C2E7045A60E,8A77567DDE598930,6D6D5C38CE3C2597,A8ADAF5792AA7CD9,000000005B37A180,1BC1BA7DFA029B08,D99516FDA72E0B4E,F7FB2F2DFBEC87EF,7502C8A1391717BE,1E329E5F86A5A45F,7B8F5A37F7AD3455,B6EF544BD8C3E58A,1C7395343D1D3D96,05E31FBBCC32382F,0000000108A2ABCE,29834EA825282A41,75604679A9DA1DAE,9A59824DFE664183,62453EA637F6DEF4,38BE84A9E226377D,F8A4C91D49188C9F,94F66E14D705E1B0,C04E84DB92E3F43A,ABBCEC03875E75DF,000000022EADD2F6,0505D2A55125D0F4,09ECFBA5CBF28341,E8EA51DF154DDD25,80629CC9153A8A74,E9F6D67862AE3575,56796DA06D5BDA07,FC700AFBA7F904F0,35F4AB2C6863B278,8B9ECC771939B46C,00000000366B2621,1357C24D9F96C3BE,F8329B91DBC31244,A8B042413B19ADF5,A6BE715B742AB8C2,0C302B7E3EF65734,BB405D89A3339842,6CCD99B2B66E5F6F,A9FC0B781E14646F,59FD0AA5103FB68E,000000015A5CAF73,E91B6164E75055FC,36B3EFA1BA863EB1,272F6CBAECF00E71,80483BA957BE07C2,05C06859A2270125,EAE76F1713FDA160,D6E64D91E3F28835,E2D1413786648BF6,1FA5493F90CAAE87,000000026AC0E7B1,0671BF4C09908470,48D07BC23DDD630D,CB8067A0546D24B3,CE1139E1F948D2BD,EC99270F2BB595A1,BA01D8B80F3BC6F7,DD2406ED086EDA71,8B8C8082C1476E68,A323DFA37AF575A0,000000024F3D0A39,2FC8AC90403DD107,A1E0E89862F84D8F,8A51336BFB2488FB,416B99924FF334E6,CBCB3E54DCC43356,265FA236B5724850,B23698FAB387F458,0CDC7C1D7C3047A2,C6ACC5D21037435D,000000021EE506EC,7A1A223788B82EBE,852ECF1C937601D1,BDD2E9AE7DCB7F01,17A15C61385D0077,ED9CE79B74A63600,F7DAA27AE5EC0DC3,D50E325A83EF89E8,BB873CD26BAC1913,52F60EB82AEDFCF2,0000000173D84A9B,2DE632F8C0737DAA,920F7DDDE823A11E,C4E78721CD248CA2,BE8FE905EC408282,20CDDF700B1E3DE3,20C40C86178D5502,5941E579D511E557,FC4EA17CEB351A4B,9B9A89E74BA6CB20,00000001212D2032,5A733510B6F913FD,BEB6213761071C72,87E07497364F91C8,47307035550574B9,E4CEC188BEC58C6A,E7D91CDF5D628A33,89D3DD7ECAE6F9BF,CA40B5C27A31A976,1265A08A4F34E64E,0000000067C09B26,1496A4A12B818BBF,94C47C42E2F0677E,F845CD8015D8DA8D,CC57308B6F92AD4C,8E35B6BB77F4BFD6,E555B6626360BC55,6F33E92C4DE46234,23B353531573F20B,45087AC1D967C133,00000000018C39E6,7DA49BDFDA17F1FA,468753094205D9C2,9DBBD2386A35157E,81C0FE94DCF65BC7,BA066ADFCD99DE16,F2208E0AB9FE94BD,7DBBA34D5A8D2158,A5DE18E6CDAA1F2C,A81EC6CFEF59284C,00000000ED6E4108,A4BFD3EE89C7B92F,E8AD965BD354B10A,5ED2297E7C442567,ACCEBB9DD937522D,782B27689EF62910,195E78404775B33D,85A3FB896C1119A8,2DCD02AB36A3E49F,464972C63EEED6D3,0000000246E835E8,723350124269F77E,082C8C66A9D4CC02,6B10722A40C39F3F,413E3A6D8A0D2F7B,5CFB2EF68626236D,FB80FA2B697DAC32,D5AEF4AC4BFDC577,70BD71757D860871,5EB2BFFCBA308F64,00000001A1D0915E,F65EE9056BA25A73,2ECDF4AFEF53BA13,9FB702527F655DF5,0EEB110E04191BE4,B9B75A5182AEB191,BE4809AD7675A44B,65BE659E13606613,0D54CFD55BC2AFB1,D83090CE28567BAF,00000001B4450715,8063DE74CE009B60,CDA87FD0E52F3AB7,A200EE9E3707CB68,1133D90906FF0446,748991E8062DB518,AA76A6862769BCC1,89264C0D58F0936C,A8A62B2DC11D5AE5,38EDE9BEEB18711D,0000000235E22F78,E5E6469C5C3742A7,10490219791A96B3,3D5A33A79AD36B72,EA4F670C094F190D,28BBE6F74818A1A1,24F1643A9FC9FBD5,E691186BEEB1F123,1839EC720B172A58,2B2DAF3A5C9071E9,0000000166652A45,A9FDDEB19948C3DD,3EB7F617464E48DE,D013F32A777BA582,2FB06A53B0634D7C,E287FD00EC1C2B42,F6B4672E35EF9D94,F619CE2120B83E20,38A16FBA98C747BC,82478C279F9A5B71,00000001BA020052,EF3EE1F4FAB7EFA7,2BF61A11C44FE0FA,493C1A2C5E959BAC,E3C0F14FAE23929C,24558BE4BBE02EB8,75795ACCD7EA1C33,B9CDA1458C8CF84F,500503608ECE67A3,4F2443815CBB06A3,00000002686C8263,DD9C2080FF21AD06,0C8798B03C12D1FE,70EC4BCD18F6FDB3,06DB77F89E1F6261,73C2E1EEC40A5162,A46281C79ADFA37C,17EE006694AC1C42,314A4BE04C3450F1,F95D0D6A47ACAC8C,0000000002B0A7FF,94FA18904405C87D,E5B7C7D8AD9B3AF7,F1A25128582207F7,1BA4C19AF4C49F82,2D14FA07517D733A,E6DC551BEB6AD5F2,E6A2E3DF29B1AA4B,6A548F0298ED69E1,2376CFF02EE80A50,000000021F280579,3D29B12A887EBB1C,EE5E87A0F42E6711,FF56489AB31DCCF0,336698DC86D317CF,F913DD842E9F7782,FBD876027BD82ECB,F01A41AD2BDF026C,1819DEAC0B2C77A6,65A383EAB3DC5879,000000003CF0D30C,A99AD378AEECB502,36BACE40E9EF7CE7,68154323A28D281D,DAD1C7D72514FDAB,CCB61CFE891E390B,9F8071853BAE6424,605168C4014F8CEE,EB34FBB2431254CE,33BB2AE6C27F400E,00000000BDBDFAF1,C40609049BD31686,D5E1506DD956A894,E7F33221F8434421,6413395A040D16D6,6D38AE8BA19C6B37,210C1A5DD493ADD2,D561EB472BB84942,C9D86979BC4BEC77,E8996357AB563107,00000000136C433A,E9D9A1046E420A58,F1926578BB893D2A,E57D01AEB7281108,510690C8B4CBBB2E,D5234D8F76ABDC9C,D85CF1FC88F86297,B6E17DEEA2EFF18C,C3F93A9E76BC0247,C644535C5B9F73AC,0000000233D44A7D,61564CB656F3957F,5F90077E9E02E0A7,FD93F08ECBBDEE56,DC49CCECB0B30814,3B404BEE53719B35,28527E7561C46BD2,661D099B7D995483,1E2F7B10D09B2E7F,40302BBEF7C159BC,000000010093038E,E1EFF3C2AEB2D8F8,ABAEF6D98BB5919A,D143B612E25D3A25,75260D9DD45548CD,193E591B31B1A69A,B4D2E749AE6E3FFC,3C12E9086BDE0803,BA813F6F1137247D,F0055FBAD3A48D6D,00000000C699C799,7B9FC16070FFAD31,B57CA6C43414DC56,8AF62DD27FA16AD5,5C656DAC759AF4D3,BB0B63D94373CF8E,367C3CD62E72FEF0,0A1972CA4E77A26F,948F791DA0124F3F,0496EE5D5A34DCA0,00000001E02E86A8,1592751391F9F3EF,11E1F72AD46FE9F1,D716C818C20A882A,233A4FA70E72EA13,325BF5426D58C062,4AF7172D866C91A2,5C82718CB91B338D,2EA6DC37783EC9A4,9F246BE538C68BB5,00000002039F6A7B,564675C5C743A538,7135354BE3CB1582,6C1061383EED48FC,38D3956672BB5F47,454F43A0B32BC427,203C34E4410EFF5D,098D541231ADAF53,F66F3CC54C89F071,0A3C1A61E2DCDAB4,00000001295C0258,B2357CF390C9D84C,A495464B268DE4A6,07C17F088BC29193,A118E155D96735C7,16CD311008B78AF6,55F4740AEE15D308,5D53354EB5828CC3,EFEA11480C8B995B,E8FE1A09876215D8,00000000A16F9B10,CB4238AB26200FD8,AEFA4692B855C442,1C934250110C596A,4E401D2A0E3D0894,0044163AAE3AE406,AF82314701814E6D,424CA8BBD87397CF,3729A06CC5411C11,EE5623CD1F709EAD,0000000046BAF03D,E3309956710E69D6,5A022E55AC017881,5449A9E19FF5C452,58D1457BE0517FE8,49CAEBBCA15C6777,C43E2F2BB264AD3D,32FC3BBCDB6B8B0D,372C1F04463C8219,2C134D94C97E8D8A,00000001F8B1A7A5,1B94F6CEDDDDD8F2,6B1ECC4DC3FB3823,E9A9999B7359409D,C4288C8A8379B126,ED169DB2834E6885,9CD581FCA32E3092,53FCA16BF83D5CA0,77D5D70877599F1C,492E165E59B92C7A,000000027933F8E5,4E24270A8712B475,9E12F75C9FADED28,4BF9D25B08FB070A,4395DA575FDFDE1E,D745C7E0F3559771,B5B42FCF82A433B4,D7E053A12E9D2B17,7586E22D79C1EE6C,B2B93DEA28BAC04A,00000000620CB487,2D204B8998F32C72,C9160970F2DF7CC0,0746AE389F71E7BD,8BB0A5BEA3351B36,BC35F3CB20AAC230,5CB0EF9A37971321,590BFCDA01642AFF,7543C7E943C0F600,9DF0D3C1F2BC218D,0000000090DC9B01,78D73369BF27EBBA,A559C5F3389769DC,8F0C04516C6365AE,0FA9BC9D64A2F58E,F4401F50A64F1FED,31A1DE60929A74D3,3C39CA5DE96DBA07,0B85E6B2710372BE,22226A448B2D321C,00000000D42ED7F9,2E115D11FAE74D84,1E1FFEE3153C1219,7CCB52DACF9F65DC,E675FEB57299B14D,9EBD9C26AD91AA73,E13561EE1063B695,ECD43D8451ABA3E6,C80732082DCF0747,CB2BFBE669A243E8,00000001B0A0E873,837ADF0002BA536D,EC9376DFF41938C0,C3951D7AF2F51D1E,9F60842CE6933271,ABCB5BE76FB71C90,F5D4A888BC558AC7,30643A547E587052,E279149FD03E5412,F16968A3397573FB,00000001CF16256D,1A1F1AD96DB3D2E4,13ECD62E2E03B38E,8251C8BAD01C7093,75E5A78E9E98B3F0,69A79F62533EB5CB,FAD8AA5AA9468AD0,6EAE0405268736FF,CECB657A0547F7C5,392E4C699B53B4B5,0000000027ED9E48,CC1BCE77BE718541,72E63DECAA0ACA2F,097CC8F165E78402,A6B4C1C65477D6FF,3070D1BBF3E31A21,83F42437121AE7CF,2B610AC8AF809A99,2F9306DDAD977B26,EF321755BA3C431B,0000000111F7BF15,8B2D24B6DD29E709,8961D8D8FB38F6E4,85B4A78D5F6923BD,619B9376E1F42049,CDB665931E37436C,76309EC9C70C6A2B,48BD27F87C6D2958,61FFD3993D76B0C7,BE93F577847E3271,00000001AE06608D,D6D6170BF8906959,178C6CDF06C8D7C4,BF0633609D0ADBF3,03B1E62C8D94535B,10DBCA7B21D02938,25BF39CBD292D183,55B7942F90A79870,C77666D6FC80D6A2,C9F7C30D827E1609,000000010E47F740,96E0DBC386B1EE85,21B7A0C49E1F5EAF,07DCCB230CB4A57E,F1E0D1D5959E5F49,FF9B02DFEC949B67,0C3A42AF36E8A81A,912D78A7DA3A4089,900ED3F2FD136DB9,9EB38B8526595158,00000000875D2DE5,7DB42BF0A67FF1D4,7AA89B972D47D4E4,78122EFF95E1E37F,411985A56020E27E,F457F36B24CBDB93,8670FB2A2EC417B6,4AB89FE5CA6E531F,12B78F16880F907F,A0EBC4348AA5EB59,00000000E445BC2E,39D8D0421AC91C3E,81041868B597884C,E6E68E14D860D711,92865C4361914E65,ECFF0C52CBDB34E9,0E99BA484A268717,0815ABD6271F8DB2,A3CA3664D3A947F7,B8A290A559C961AD,00000002468F831D,69F885E91D129C7A,AF9E01B4C6E85D52,4780B1A3092E438A,4A2F262FFBE5DA35,902872CDE63E9E53,4E95F50ABCEDF535,1A11AC0BC8F2867B,99655696349341E5,7F9BC381FB8F49F8,000000018CEE07D5,9147D6545E26DA52,7ED95EBBFA9AB95C,81F151A40ED55030,8097615861A631DA,63518B8A99108C3C,4111FFFB875730E2,BE0A162AE2B22FAB,D5E3BC0750E218DC,7C46B610A581DBE9,00000001474416A7,D5C251EB0D29D38E,F3166B9B86F0D074,AE6C802EB5F110DB,F85BD2B2A797F22B,B084277647AFBA66,BD1B1FE56D3D5D92,17879A726005C3C7,61663D7E8E9D74C8,E9BDA6C4376F5E5E,00000001FFF18398,896A8FE5419B5DB7,FA63D84C92494127,338E6A50FC4D230F,922EC4D464E1B4CF,89F1644641DE2001,C85B9B07A35678EE,2B1BB4D9B464CB83,880D5BAFD62DBFDC,0852858CC69CE3BF,0000000024D7A239,E814D93688BAD21E,02458910B4CF3FEA,5C3B535C09712A1B,60582375F2AE0ECF,026F96056AD42BC3,3D202771F3746060,77AB5A2624DC0CD7,F9C2BB18FDA8BA74,DA92FED88EF4CEBC,00000002564DBB62,8A268D73B5003E91,1B79D38C0A46EE17,AD89808AC90FCA12,13E56596B9C9EC07,B15241062C1BAA53,2DAAC4164B9FE117,41E166E869E997C0,623ECFFFF1B14722,5187B73214DBD412,00000000A981CB20,56D485DE27DCF3D0,42D342196D6AF277,D7A3CED1BD98D9A9,15239CEFC626DE41,56693CEF092A324E,7986FF61572107F5,BECBEB07260477E0,28FC1A8B7E3C98E6,67F5617D749C1B3D,00000000F1B22A62,C65D267DAA0D645E,AB646B581BEDC785,E1C3BC132ABAC1D7,F0A425AF58E565F6,2EAC4738E725E922,41B89D0C8CD142A7,456112F4DB551D7D,2287104092DBC183,6209782873BB66E4,000000013CB693C7,D6E3CA3BE9222953,4853FB3C5CD2FA51,5B4F6F6C602CDAC5,BA041C413C9A363E,E4C4572D2C3FE814,F704442E2DC1C7FE,495A0BF493A15977,5E5FA5B2701276BA,F8C22AD9073AD107,0000000025C2C420,BC43566D81B4BDE5,B906A3E7D181ED3B,CF5DF9D789C4D282,26789EAA1FE2A74F,6F0ABA2F45B214D4,102FF544DCDEEA98,093331F1F7E19084,C8A1953F68C88AB9,206D58DF9556CCD2,0000000097B086F3,2D9C273BE5F76F34,F8E4AF0EB6B61E8D,D6D6187D1F496928,1035091CF609DF72,98F218232C490EB5,9A694FFE827D2872,70C4F6D9E2CDD1E5,BD2131B799847BB8,E04A0EE5DEBBFC95,000000003D8DDA81,3434B44F00B2DEDA,814F8185F9788891,54A496156B7699FA,BBA9115A89A4AB44,0B65B3B02DEDB21C,E5FFEBB43AC0D8D1,F553B64D253A8693,555F9F06A83A1888,462BC0825F443DE1,000000001964AE4D,573F7AAF0E4D69C7,527F25C2F35212D6,375204A29124C687,3AD3748E5050597A,E0DD717DAF8C8552,1AC3DB4A52D1C6AA,B438EBF4E47A863F,97AD7D0B1A506C09,0CE5CB273CBA2D38,0000000236412345,89E77818DB03F258,606ABEFF94463946,13B690532AA8537E,409CAF560ED883A0,A93BA41FED5CF85D,F10984F1F6D39494,F09678B0F9FA27AB,EF3B960279A8D669,311AB954A02AD118,0000000005D6E494,B41D9BA37E913DBC,8BD71B52BDFD7AC5,83155B324E5B89C4,F801B998908FEAE9,7DB6CD7F1900E310,53D59A5D23AE1269,035EE02CC2A14CC8,2FE1980879EE6A59,E64CEF1A586A6F3E,0000000149764FFB,B700096261AABF5A,084C9F047F1E7C19,2B55C58404072511,D1523145E4EE8F7D,8B185613D21968FA,B0FDB65A64A33928,A905DEF8349BAFE3,9D95C3FA79D3C948,2A1697F3DA4AE66E,000000009AB3CC8A,F754AEE980A45A80,E4D2A417EE7A3652,9D6D0606150AF081,690DD6D4CEDE9F18,AF32DB1EE37E3877,AB51705586A6C9C9,74C5B4F4A2671472,4481E733B1654DEA,2C27D4DBB25D0607,0000000172CA2EDF,ED7BE63D5B142A00,A450856D99286D4B,A2EF4D622A5D23AA,41E65AEFEFF8597F,3C3613578CDFD34F,B535C9ABFCF6E5A7,9C1540A3035870BB,3F1F3548FCCBE19C,3F451063FD3E8809,000000020C649BA6,82A0A2FCF8350800,83A2950FF06A3C4F,C1CFB2AB9AD139AE,9EA9C17BE85CDECF,9A24363D8BCFA7B0,3D297AC418278B0D,C1434D2555622C75,BB07C648AEE8F8C0,6FBF7DA44A0D3C5A,0000000115A8005C,74D6824EFF840BB8,31CACEEA4FB2A9B8,E54902EC13C82898,E06701103E963937,ACA08006F97A885E,8C92212165C44227,60703086E2F8B6C1,4A60B1FDFB1D84DE,A06A649BF89DA575,00000000AF9751BB,E25DAC8FF958A860,48E013C6E2BE1CCC,FDAF5BD2D85D6856,8864E631471B05D2,F70D4BC43802FC94,38C51969EDAF2487,A6A92A030FD24E55,73927B22CEBCBF18,2D75E8EB27AC2855,0000000145395C8F,046A2B2672D464F1,CDAD02BF7EE7F4B5,BEF6F20C3CA8FB7E,0F121E451008E83D,2D09DBF733B70A2F,BA237EC13D5825A8,52DE66826F97A603,A9355C6D56A6137F,E6AE4D7EC140D572,00000002653D25FB,CFD9A2935C006003,24C973DE06F41941,81860111F69996C3,3F2DFE479A4B8D86,8BBA4A72BC3D2B29,DFEC6ABCBC4D015E,FAE2E8064851D12E,BD2BDBA717267F85,4F563BCD6DDE8772,000000004041189B,821A6232116A115B,524154EAA96E94D1,72CAB6835A4B02F3,1FF149511010871A,CD31ACF26ED7A610,C70F8D9FA7959935,5889C2F7BFD87481,2B05A0AC6C9FA843,5CE6CE7BA757D53E,00000000A5907465,4229B72A8A25BF0F,519A5BF938C79ABF,20C7BE0DB480B36C,B0ED33430439E034,5B5AFCEB396070D6,DCBE1F9BB67D7BFC,60CB0C4A241F30F9,BEAD100F913C41AE,BB0556A933322BD1,00000002254786B3,8039613321C11F98,94BDE6877A640E4C,F6C21DE66F17BBCE,468AD2E021899969,32B217D82C17061F,5F4DE6B995C84E58,607FA65A1A1699B8,27BA938EF2EC437A,E572E237179058DF,00000002301509E2,916F8DB4BFF4FF63,5B3AC3E438873F18,4B72CF3C5B83F981,C105EEAD6DFC275F,F258A02CA8F9995E,C2F37161754FD2BA,EA730D8E2E9F85FB,C256EBF737C471F7,AC1B38DB056D2584,00000002106BDF04,E317C0A17A934349,86581CC7F01CD505,52E5E2BDED996B1A,39D4F7229B414C75,7D5A2D1561243194,D80ACBAC821A3759,96202D7149DC18F2,9C7BEE70C83A6697,17C81999F4290E48,00000000692D563C,8C2AB30D5E51F0D1,3276E96CD4F760BC,E0216A0B1076F137,F47EE3B2F7DE2A44,32186E094FB52FBC,5306D78C9A86FA86,F4766BC6BA7EB9C7,B555C7861144747B,E0A03B46FDAF1C78,0000000215EB7EA7,C30A3485F7F13623,089ACAB3E3BA2897,3E56BDA293D2A1A8,5699934145216328,730564070FEFF05B,75A555DC6CE581AB,645F180237962F5F,A3D54A470105CA30,A774571A45536D41,000000015B07248A,676D013112E59BF1,3888E0ECC1CCEA90,16BCFB2BB9A7EEBD,331B1DF3FFC82073,075E330C2245BAC0,2827A0ECD69CCCCC,C662CBE4DBE67CDC,26D8501224F3B908,0AB084298D62C560,000000021F442DB1,6FC25EBFA1F2F731,45F7F945C372DE03,9E91D1A1427D0B55,BFF55EE827DC832A,3F2DDF8E0A01C13A,28B7B4537AA0152D,C5C7E696EBF72FD4,63DBE56A0AAFA0F1,72567D5377451C9C,00000001E9B7A08D,635AAEBF83AB09D4,CB8C381ED87E54E8,D4870FC511F1EBB8,4C23EFBB21FEE838,83B636734CC83D2D,F5AFED9E5621963C,2A06C8EC3634BD0E,A567D03C25A5EC3A,AD8617AF2FB10FA2,00000001BD8FF15A,28FDF835015AADD9,BB5D710738FB86A9,5886FCEC8F1BE631,66877153F68DA27F,ADD2E52194830F59,67282FBA1050FFB0,B19C1BAA96AA15A1,86F803838217447C,27BA9EA2D068C886,000000016C302979,D3CBEB2AAA5A0A85,BF97D3D535CFBE2F,32228BD5CF8A53CF,18CC4606B349E4F2,3C245EDC1145DFA4,5BF5475DC0088D35,ED6526179726A50D,8D508B4AED152A04,B0D94B35D35FEC52,00000000CA26BD19,CA22A81313DC531C,FA73F6994D1214EF,7C19324571DB1BA6,39BB393A8A83F38D,C98A7510246D8519,E057D14ADE71D2AD,E026827C23D9A8F6,2EC16E3EC9074D2E,0242398612C8C8AF,00000000EA501750,CDF4C41BCF301260,B115DA26B6BABF9B,B868ADF01070A383,1A7D8F6048D6D68E,F7C5B6DA78BA0936,5E3FBAC513D6BDAA,E80CF5F1E73AA412,14944FDE6D3E6F6E,3D1C93840F047C77,00000000964767BD,5BD65D4F65E7A88A,CBC9B81C6313AB5E,6829A2F20B1B52CA,DAEF3A3A3ED191A7,39C71D66C550FB59,4D71FACF5B28F560,D29D690BADFA1807,69522C46EC5F1851,B3623048666FFEC2,00000001D89E277C,51EC32A739ABB4AF,D2F44EF548246436,A7D584DA4BD950D2,55B55B53C13FF2D4,7C9955EE78988FA4,802FC00FB1B07FB2,322C7C19BB295882,F14B78F3FE4B35E2,9F339CCB7C2D05D5,00000002454988EC,64D30E17C169FACE,C45C2BC05C1724D9,7BBBE8CAE40A849B,281D89975826F0BD,757839ECFF2C172E,263568C41186B8FA,D4A131AECE5AF273,7A58FC00FB463C92,16945C8F1D8027EB,000000023F543B77,643128CC8CFE62D7,3089C985A801C179,464E65B7E8B4F0F9,645DDABCC14DE6F3,4540916A032DDF94,09A820AB19C1F00D,8BE21A7D1F6605F5,EA5AC3D53E252DE9,0AC396E8A5961BFE,00000001C4C35613,146286486A7DE019,32A0677F223137F7,2625C815CB2400A0,E5E6AE2DFDD757C6,5C812459D16C38DD,07C21B3D75A629C4,ED9A45058FF819CF,8EADCA593C818E3A,29055ABA51632EFD,000000003A186C04,C7983200ABDF6627,C90BAC4966F82CD0,193BC553A2094E74,B1FD9CDCFB29E085,830798D7F52A5802,F5D887AE3A68C1D5,D47A7F8CC0818CB5,D2FCD93B1C877907,F954305F72D8B688,00000001E7B509B4,919CD6AE333F3356,C7F000A5DF37D291,C01BEDE7836E53EE,47905ABDF39845BD,E398CA4816ADD2B4,12EFDAC262A048E6,E192B9F251A3A163,BE5FD03EE5E3A2AE,F0FB301250E28363,0000000087768529,85C0413F5B3F19DE,66D3E8423CDF6178,5CFDB9A335588EE4,1E55E159F603A2DC,3ED460C72F393CF2,3F7BDF177302976B,103E2AA7ED168FE5,2D1BB50E91A4528E,516CCB9CE1E14ADF,0000000076F3FDEC,56F8072990D232C5,2F600686142A584C,BE61C611B929B9E4,2644600D09C28D39,19CFF0EACA830AAE,D7C1DD0A78A24D9A,7D32C4BE8F13CC29,021ECF86ECA28B5E,B3E846DAA13BDCF4,0000000107888871,886AD1DC96B0F1F8,35019A034AD77914,A6E2DC9FF8126E7D,CCB7E1527297F29A,BFE35B686D4DC50C,F0C49D1F170C545F,60D74DFCF485E3EB,B4CF36BB4C911C30,0F3BCE5AD91B4A15,000000002C5CC9E2,001AA6B5C5AE068F,543595AB7890EC9B,E6CD08338FDD4265,38E583896E075E1A,AF92A6FE7FE80634,5509BA074AACF403,6BD8CEC3DAA70584,73E2949CCD5FB53A,0317C49EAEC21FD4,000000007914CAB5,04CFD7DCC0D45539,2E7365090B7EA4FA,984F67749517AED9,61F60A9D265292BD,D3D1857BEB7715C6,605FA8484AF36E98,88B28E61BB8C7C24,3D30FC5F1D5A75AC,F754638A2A200002,0000000238AF33D7,258515E514C989CA,BD642A764DBD87EC,EBC4B51B9809B5E0,F791ABDA70944551,BC1BF87F4ECE3B7A,D1B132B3DCCBA78E,1DDCAC159014BBAB,24D9F973B746D367,AF4176E42269FDAB,00000001F4E18A01,923A40A2A1C210A4,056C867D34614B1E,E128BB4247F7F48F,B4C151B516C194B5,7485BA30F5B75968,A51E42E79887A440,08CAA8CC916DCD52,F1A1720EC4BA13A3,27189741ED2A25D5,000000013306048A,F47B4B1ADD126E91,AF0242CC263AD56C,C0BE1F9EC9F235D1,5866857EBFAC14DF,0C10B88644243BA3,9E8819FBDC67D829,80521317AFEBD897,DA0141A6DC238D5D,2DF21C75510686C6,00000000ECB0A568,D32EF3675F078DD3,ED5B74E325239D55,57B8CACFF92C1003,BEDCBF11FC13F108,BD9A9A83F0C58AF6,B0CE15A3770C9A9E,FD2B777616ABB2DC,75AFC1FC102E8B6D,F41D2A1918438C59,00000001C43FD370,7031CDD6F8CCDB44,6020F4FC8E6C22F2,63653404F31F295A,29C7E77266EDE134,CC08E427AD4332E3,F755BF06C58D9FE1,995BB17091656141,82335C522D5D5B25,FA0124DF5F246975,00000001B204CA31,8C9CF854C2BB0009,693B13582598ACCD,35377A2DD71C9130,98C2E39A38CC27DA,03D5F95FFBE6CE19,0D9E84579A242ECC,82DA802CE49DAD7E,CEFBBCB86AC27A6E,5E58EB984806D00C,0000000174B60824,8934326E268105C2,85E75A4C4157B39D,CB9F403EFEBDEF25,F2123A43BC7CA2E9,7B23E3BDD19FA347,A452FED5B59611C6,F5ACD01045A3B399,20A11DCEA8B439D4,36EA8692583CC51F,0000000266F89006,762EF6C60E54D042,B65CB8F6E59A42F1,FD63D8CDD22FD332,143DCA6BCB240951,A3F27F4751914914,4DC75B6512BE1AF7,FEF56106DEC77CB7,433A6AFE03C89704,6FD68A1A6BE0BCC7,0000000002BE0C73,B22569E0FE7351AB,B16220221122EAB4,211ED220A53B4B10,923BCEBF5D6DFFA9,994658C45C3B73A7,AC35132844760E85,FAA8E84FD65EA218,1ECB82F4F71F3771,3C25E45DF73D8296,000000007343867C,96911486CEEE8CCA,B5883606A798ED60,5282D390ED1660AD,A3B7047084018154,7DFBB07DA9EB6B19,8EEB6D7C679729E1,E392B1F48B5D1A9C,B9F47774B6CEB02C,018BA942B20C3031,00000001657FD2CA,E226CE137D4BB8C5,5E24293FE8438840,A12011B8C3D20D8C,AE6A84A111F06754,24EB3DA7D2AE8576,93891F745DCA8D02,F6D6BC0164F4A858,D074FF80B73F7CF9,A2F9A7D81798F820,000000005D29A7EE,19A9572A9A75E16B,A5601A953AEEBB8C,0406FCF393D4F711,500F28AD0CCD7A56,F45AC75485715723,F6220E4340BAC0E3,146C72774D1ACB83,B37ED94AD547D904,94B9431BCF76B4A2,000000017F156899,2A951BCC637A77CF,A84D22821E5501F9,BC22E6156DFD9BA4,B633CAD86F9CF832,B1EB363AC3F6B55D,0E2C39D696154995,005094924B3E9955,24782C553101C36D,E59F198BD004F47B,000000012DF773B7,7822A0E069CD4D57,B87EEB45F08016A1,49B4C5165BBFEB08,69DE38E587D8D72B,6FF9C4E46CEAA342,E7A2C3725147696C,ECA9E05E44AA0A25,85F0F29E06B0FDD3,2427318B6B4CA32A,000000000049FD71,D95BD4BD3A6F8777,097950569EB17428,47288A29CF6D583E,6A79331D25C673CB,D7DAC2E035BADBFF,76A578A5D4090A8C,5917A15C3B07C497,F40D23BCD6CA2C86,95C0113D0A8F6753,0000000148433BB2,F64AE2A5377082E5,AE9605B23E237C01,424B6021C46F1EBB,BBF0CD0FB3DE71C5,F62EB5F04A512FB3,D395259F521757EF,AC23621CA31AA6AC,09D4C466F49BA206,89696AC5E8992DD2,0000000110F85B57,3A7CD9B89E8F021E,DF9A70E9564687C8,4119BB04FADC1A9D,60C8A74EABE8F34C,C842F25E12BF8FD8,BDABE11CFFBFE976,E1FFD5D0C9631FD7,CDC33659403D5EE5,20DD3207F8AD065A,00000000D3152A17,2B657D5C1813405C,C67D072FEBD863FF,81C8E80BE43F2CCE,F60F2C53DF3F9D93,C9762F7698E78C7C,CBF5169952C0F12A,ED2CCD42A5E61E28,DBC7DF593E8270BC,3AB1E84B27E651C7,0000000218553A6B,DF8F04F7A54636E6,D6EBAFF8A36965A0,2378CFC2F9F26776,2F0CF507DAD50F3B,36B06FF272418A9C,2F4B545D99A7BE90,9E707AA70FE0E530,B3AAAB8F8A4BA68C,1287CE163917BE20,000000025C4A9A12,ECEDA9E2510F4D53,D35631F07722FFD0,E693602D5C049904,BF20B8C76357E92E,846B072F22D51559,277A6BD8D97FB8A0,5666D4635DBA3DE7,D3230AA99676B991,D503AC5592790449,00000000AC2E379F,5A3EB836D36DEB99,05CBF4D6C8AE7C17,F82B2DDCB07EEBDB,4C390FEA6BC13836,057B281E0AA6C5C6,A441CEA83090F26E,3A5A751E56697ACF,87BC64F973EA5328,F5E1CB5F215F5B96,000000019710E174,9FB291677C768ECB,E28AF561BBC15481,462B5EA1B022C772,9B8110F740AD4DCE,A274647880099ADF,4FE273F87870CF8E,8D55F29A29D769A4,C891BBD7B50A91EF,2A7FBCC4F48C1FDF,000000024828DCBA,0FA713E4CF342F09,2BD0288CA7BD89E8,C4D8449FED824AF7,D387579BCA7C3EE9,759784D706A95D9B,E681A3D10DEF7858,F89E2573DAE108AD,B61A8A95DB33638D,0375FC40C1DB81C0,00000000F3C3B654,310C5C7799A1E17C,B60C1F32113777F0,74EC285D797ADF67,F5500CE1E3FE53F6,BF1D5423592198BF,066CEB56A9B8F9F8,FD95C099BE298479,F4C40E02AED59A7E,758213CECE8917F8,00000002272FB0D1,FB24EFD149A16799,4311210FA4968884,4670C6F779C0E501,B347707A0A0B1CDC,5F78DAF3B4BCA303,428E14ED38DCBF14,5C5EE8A3F11D00B8,E5EC0BEF1CA059F7,34B7E3F69D9CA31C,00000000CCE05436,E7E8C68EB083592F,55A71005143D35CE,2988CBE720563F84,7802B8EE474B195B,4278069AF09F52AA,C980C7DBFC19258F,E6D13D492D5061AA,86E349FD90A7F71E,598EB03345522441,0000000079ECE2A7,3B7671CD5D85042B,4DEE70081128F53B,8BF7BC4A496D671E,06594930ECAFA38F,8AE1B9ADF54EE892,DED3111AAA748C3B,C05E6AA504AACFD6,A87159808E858F5F,E6CA16D450AE5AD4,0000000137DF1B29,571765E138ABB961,850E529318EC6759,5013B8B4AA9A4D68,C9520E8ABAD9CFB8,37D07CD4F0244143,A6990FE825D641D0,BD0A03BD13F11759,B331D6D477CD0800,EBE4BB5E7DAA43EE,00000000D58FABC4,9CA8317BFE022CBA,AD1AF4415CC182CD,B47342B4A23F78A0,87D750457A4A566D,2856EE8FB60E3E72,2EDC1BF7A62C0160,356FD525D243A814,9560722AC301FF5A,DE725E1E3F621F98,000000026E8CCB5F,9C0783D49891284D,E487ED69164A8B5C,77CA431EC4790808,873F8A56AA910B32,CA6A7253A72EFD5B,A015638C94BAF1E0,A7DCACAB63E0593D,D683901C36C9A322,970F2ACB004B56B2,0000000087EA4DE3,DAEBC59D0791AB04,AD44126730E4CC84,8813C75B893B3C34,A30B4E5FA85380C7,6FD26FB896EF1D38,341E53B1A834C68F,32CC1E6A36615EF0,878B339C9AE9CC37,9AD84BA04988694D,000000001D28DB92,EB63FADA2ECCB583,71C41AC817A34364,F14375C59B696878,5C39FEC533D532F7,26971A7209ACF817,EC5BDC7D716A370A,511124D1C50480DE,97D10E4E64325AB6,453C5C35DB111E8C,000000002101BD48,A1B3C67B05E79EFF,4A54A11B9ECB83E2,8D294B61F1F71EFC,249B56CB86B1CE06,19F765BD8E328B09,724D1BD411421225,54790A1A885CB8B0,B9CE90D0F6595C79,F49651A73B64A16F,00000002416B2FD0,815D31FDF697B5DC,B368260B2E1762F1,F45DA2E7832F5F72,985743B40833C5F8,DCEF0F8C496DD610,56213A8DD7AB1515,2453EC3FDB3E3972,80B808900036497A,0EB755A0D9F9D072,000000006B811B14,61DFD07643ECDABA,547FCEFDB23262A2,33B818EC814F3ACB,947699081B04F877,D98F5A015B13E7C4,281CE95A602BC7C1,110B2BCAC6D1F384,3725E15CE554BEEF,9AA1004D7D923923,0000000062561357,F9F825EEE399769E,4DFC3C203CF8AC54,2760CB3493BC563E,3EDE2D99431887C9,13FD94A9DF5CBCC4,DBDE10E17CBEEFA8,BD6C5E2201B627B2,8262BF4DF0C07932,C6F9A0693FAFFE6D,000000012B543BA3,AA184C198E9F19C0,C7EC1B95E19C1DC8,CDF4F3E528A5162A,A231921278526BB2,4896422501F9CAAC,3FB86E83EA82DA7F,1796A7BA3DD1DB79,4678E4902A918456,4CF6E768C932A73D,000000025E2F1B41,EA8CA0962AE1EEC9,2F0DCCB9AF8F349E,37748240243E6920,8DF53A88711332BA,C7229C64F2472A69,877AC9463B669817,2BF1F21530BE54C9,EE44EC8B7C5528FF,786EB1F6FC7126D3,000000003FD21C5E,547BF051BB4768F0,8A32480AD0AB0268,69599166752A1ACE,F5C5915AC3EC43D2,959CA8C79A694190,65F5704A78F21B4F,CF5A5A007749DE00,60A79494AE883EDF,CD245DB8EF37BF0E,00000000C1BE2A42,DBCB825CAD6A4820,4D70723B3AC473EF,6AE6350106921009,F6BB2589678AEE01,89EB49C69E673B17,344354B1F46B1D2D,0DCA3FC818C9BB90,90F62C286997E41C,00BF4BE87440F6F5,000000000A894948,BAEA4E4EEB8FAF3F,B2B3D6A3855847AC,3C676E9987F417D8,AE8D4B55BC7AC1BC,E3E8E2D2BD3A4C38,A8A51E819A1AD0C2,9D1CABCE856335C0,89657914299B498F,79FD8452545976BF,000000013B5FDBC1,A6E7DAFEF923959B,CC4226A49CAAC049,83F33B65C9AA7784,4C9413ED23C89395,624C83BF333F682F,2B023623E150C518,6B29AA79DCF5CAAA,22B1EDFD8BF019B3,A7008D980C1725C7,0000000190E4A828,C999F93D350BB4D6,73C9BA888218A67D,E28368F552509317,73EED718330B1616,969780D4EF3E7063,F4F1790B4665FC9E,9563DA4B00445F6D,D724EECEED3B2711,7E95FF7530E208A5,00000000DABCA5E0,D5794AAA9DAA7BD5,1ADEB16DE274C639,7419D2228DB81AFC,924EF230D850EEDE,E3BCFDAF25F8A8C5,7B6B969803F9C922,89D19A4E1D1B1A05,142C502A61FFE396,3E1813E4510E5CF1,0000000082449706,D0FE34167685199A,D4B92442B83DA443,8BA61002DFC7527B,A6B715ADDC0B33EA,CAE9BE500EB31568,04DA7ABAA7328BCE,338F1CB15C82944C,D7A92D5390FEBFFE,A7B5D168E4E88C5E,00000001FFB9CB10,B49A23A5FAEFC552,AF4BED92A61AC574,E48FFE707CC85C17,3B4F669D6396E5F1,13F6CC5CA9F14B2C,8EB7E9675B097C9F,2302417693FED594,F64B37649F2E85BA,431F508406AB4565,000000001CCC7B63,DA20F8992A588EB9,8814439864D237C6,D04CC6F562F2D8FF,7D0D75D0A371BD44,030A5A0C98CB47CF,C7ED6E659C31EEDB,2DA79DFC3B8043CB,E3331D64AF287ABF,F2B8022B9E78E8ED,0000000023882A44,FF777BF0056C0717,0FF5C09A56504743,68449A5D64C38C0D,72F29F328BAE4C22,75B5391FAACC5683,58B67B6BB1CC6A41,B6597B99A54F8F8F,B6300F3A021695C6,10B63D4552DCF839,000000025E79B22E,FB67264E7D2A29CD,79F8A017C93C866C,199645F589978554,F2773C59F20694E1,6AE266DC7CB0F495,00A1069E5EEACB13,C0763525FCC9E449,5FB947AA2C84C97A,EAA803AE2BC77769,0000000001741131,51B70B517D189E14,02F5E8C5ED261326,AC50875FAF1F1EBB,CF7421915EBDE4EA,705A8E7B88C5BB1B,E67E62901F81E707,F7C057A9A5A2D35D,A60056418C6AAE56,AAEDA97CB1AF9941,000000015DB38A92,6248B5399F497041,88257DC071456F62,E5E831489D3D537A,BCC31BA90F5055FA,1F27BADBA706252B,7B8BA6F5748315E1,E835D2D5C72B9918,1A7EA0FBD21C6411,E66AE2B2C26E4A79,00000000568BD8BA,08903E49130B79EB,48A67E80FA98CE8E,3A204AA5CF95A4ED,4BFADD93AC889F6C,B18962EF403706A3,280FFD05F1B0F45D,A8606B7DCA1DABF5,6DE66173ABB8ADFD,C1EE14C9DF072E19,000000014779E486,CBF7385498ED2A39,CE906EFAA07D33E3,E5A66A2E259617F7,FC9627D845AA4A43,F3EAD463FF6FA6FD,0581091B797DBB97,3AB2FE8E8EC9CAF4,6A8F0FEA1477674A,83AF4221948D72A5,000000021F346034,76DFD15191886AE9,12E029FB5FE915CB,69C1C6289121261F,8AA36BA74566FE72,CE9F28FCB87851CE,AE0E7E12E3B503A3,744DCA978AEC83F4,D6E4AC15FC74C086,AD6787E67263C844,00000001D17E2238,96C844C8E941CA2B,F539C5FC1CB31493,6BE222FD17D3EACC,D2AA9819FE76BAFA,36716F70071929D0,BA07E17DA6339623,2DBB2C59E943A191,17AFB7BCB77FC5B4,99393B320A8100CD,00000000F8F4456F,037C3F3AA27ECC63,B9AB2332494605ED,776C76980977129D,FF2B422EA24FAF2E,D5DAC06072803B26,882A4C6D45C9AE4C,881886406429CC22,D7FA6C2095E3B03C,E53515375302AC14,000000004D3AB76D,A087F3B53DC375CC,6473E633037F5B93,3F4FACAAD4AEB79A,2F530A974D0AACBC,4671FC2A2C0FDBAB,1F9A90A10521C143,3A4A7D71D0CFEA52,90CE298A44D4D267,E77D551F7C3FE68B,000000000C4BCE00,1B94477F8471F8B8,DBE655519F97A7F0,0C89734AF6E5EC9C,7558C6B56DA57107,37AE2A30FE25B264,C1B229D4429C47CB,106A0C24A94980FB,17E97E0E66D4476D,8EC30892DD42CA88,000000022A934698,2F77F76686179590,E7B09AE58D2B6319,6932563422501DD0,3AC4D7F355BB7D4F,43FBB7096ACC98B5,9943A47188B026DC,808AAA4E8EF188C1,46EB8B7BBF0C76AA,E1827C9C875780A4,000000004A2C6A6C,B5B608AAE82044C1,C85C4F09C2AD83D1,38150C78A4F8E85F,6250AD5D294C6ADF,3481016396A2A701,61A0B80D2515CD51,A51EDA929317EF47,918231108D4546DF,E75CE669883CA357,000000014B0ED526,464CA1842801BCD3,9D5951D0947B478A,D97337E856109E8A,E24F9144800CB2C1,B98016AC7C5DE06C,561901317BF31F70,E5E349BE4910F8FC,90B6CB33CDB7B6B2,DEC508A2C5D40D52,00000000A803D786,FBBA944892F0B241,5CD0861C0167A2B3,04417D1800FCC565,767ACBB2D9597E36,8832731AFF27F6E1,5994F0B9078B361F,C7FEF0D4BB07B0CB,E40CD5544C9168B7,2D061482B45A0CF7,000000008FCC91C2,78F3DCF316C07DFF,DCD5EBD904CE656A,D02DEA72EA6E0157,1CA61E6EC219EC95,A7BC46E4CEC0D4CD,214ECE0EEB11D2CC,E5086E6BF527CD47,15C283DED4DE131E,20ED9FBE555AEC78,000000007CAAB941,8F420949BDD28088,86BFD431D153B46B,EAB60753014A6A3F,BD03439B0D4C13CB,F11B219824B62B8B,DADA1DBD4C2AD021,3B0AD1A29B54BEB2,4685B8C12A6BC712,686F0F193BF701B2,000000003A7A6350,560E9BD82F81C62E,42C7FC07A2BC916E,481CBB7541AECD20,137DBDF2E9435D71,A10ECBFB52D853C8,C7E4026003971ECE,63848F89490226C2,65ECC7E469FA2520,E81858F05D75EE26,00000001A8825377,3A6CAB1638AF92EC,B752CBF82B847067,894BAA8695D71B13,3ACE271FE8AE9FF0,BB264AC6D6ED068D,37307E0CDF901C9E,873BE70DCA948D6E,0FB913D2BE987E64,150D401F14769596,00000000ACF4CC04,E26EB61CF716341D,FDE3BF82F3A6F4E2,C5874F17C1F9D44B,FA7610434BEBB68F,6AF7F71444FFC03C,1CBE3E8B7F2507E5,51174741222EC202,FE7A7E5F3692A95C,9829E8BBEDE24D90,0000000274EF73A3,FF64612BC38360D2,46E160417692AC04,4B4F9632F65EEAFC,14838BBE8B7CDF31,7A2C6053326057A7,6C74B6CB24010079,2BEA0913307027E2,58D64F06A5E1F3FA,523DFBF1F93D0E62,00000000CCB1EBC5,380B6C6B3014B51C,98E99B43DC15D56A,8BA8082C45D77F03,0C8E3C01819F8AFB,1CBD05811959232C,AF95CB2514D7C9A7,2C70BD8515F2DBA3,8A8F69970857E7F0,FE07D75B78B4F728,000000004E3B3EA9,2DD18AE2C1D75DF9,DEA6299141176CEC,59CDB4EE60C470EE,8D19503F4CDA2A2B,66CAAE90E3A5336A,BDD19EA1CD15BC34,606170DB0C3B40A8,8F7252A262A36DD2,F30280799B9243C0,00000002385035B0,D19FD4B553172D6F,B2CE88B977DFBFD7,A02FC1A1CE44E576,AC40738B2E50BB9D,88597DB324295FDD,4B2EB12301A5CB4C,F03AB83ED1A4F0C8,E4EE56B1138A5E10,E0910328B17E731F,000000023FA9FB22,14CD4AA977B84EF8,293CA73974A8A073,968636937EC638DE,15CDF9504F1CEE50,B4F0BF3E642CD2E3,DC0701A679AABB24,8C9A69CB679F5C29,5178C66148BD2098,C93CD7A6618F81AC,0000000002D5D258,1725D26064786D87,F3AA52D50B7AD1F0,4FAB2783C8922D63,E604AC8E3C2A2886,487E81C9BBAA3E58,81337AA61CD456AB,DBA8F9E3201D17A8,3AA886F7EC662493,A052FD168C99925E,0000000069FCCD10,D7C022B0B166392C,13C362E1430B6188,814259CD7FF4D43C,EBABAEA09DF5A1A9,9D155EFCFDEACD0D,802CE733C343F3BA,45DB24D948C8D18E,8615FF09883F0C14,2B49DD81E7E2A3B9,0000000086D023B7,CE0AB6468D5E7CB2,6C192CDE58F9540B,98BA021635C39444,FDD877CAC900540F,96A998758AB1036D,4848D38DCE5925C2,D7DD39617AB00B70,1EE8F4FB1956474A,764C724BA4634EE0,0000000169943440,6E97CD0B0B937924,B13C3D1F2CC3D539,BFA8A85F6B5DA9DF,130C03F592C9AF87,91843D355BC9D03F,C1D2B2E42C24D265,CF455D90AD523CC3,30D10E5E452C10E3,D2B6D04A130F243C,00000000EB1C47F9,FB9169BCBE8CB36B,190C6CFD7D46453B,1D16F26F4C63836D,FA0CAFF1FE1BB141,4BDE05C2CE03F48A,2402F15CEA55E09E,BCD6232BCB8046B3,187AC273339C8C12,A3E8611AF0C3AB9A,000000015B6C55CF,0279F369482F2B59,B0CA58344E32158C,0FB245717E95E722,1DEDAA2360F2DC3D,D839B6D53F553C4F,470211194AF5CC8D,E47A091C91364BB1,64728ADB7AEBAC66,D17F98C9F3E8009D,000000005F8346A6,D3BB31AFA1D0577F,16DA1BF275FFBD37,806BD82A2E900CE5,45087A0BD3C93219,981FD58B90704D84,831FD4DD5C7FD009,EA0D050827C14A2C,5A8DD8738A923D7F,CF0506F6BDDD097D,00000001E95D793D,56E9A89A75374368,D1137C45F4717BD1,D2287A1ABAE0FDF8,A6B1EFB451B6391A,4B69CE8CAE5208A3,C61646CB97E8649E,B6624480B72624C4,ACE3BFBBE2BD6D5A,EBAEADAEA751F976,00000001F7F6F6C9,944FF527672C60F1,B19B2F5B6EDA5D97,60B3B73162749A52,A3E4BD8C72AF4C47,19518F034AAFB610,704538FD196ED217,A14A579A2E6A5359,BF2A636E51200393,40EE442C57126647,00000000707A6954,48EA8E45E70D9EC2,DA085C22C762E593,BD7ED084EB4AC9BD,3A73487F306D1451,462440D99D4468AB,CDA6D15BFCC6CC0C,4B5251E796234478,81DCDA054EB5C92D,E03BA1755980DA16,00000001825E494D,218417286A9D81C5,30B0C720FAAD320A,282F8D90378B8EEE,CFE24486FE0AE8FE,5119DB59DE30533E,ABD0F12E210DC34A,4930238810203238,A63B683C41E741CA,6E38909B21D804BC,0000000188ACD980,551AF74EC41ACF9B,D1B147BA9EDE3390,927219A7714F6B08,C196703C94120AD9,7A99F2EBA5936256,EDEFDCB6863F2712,0DB3B2149462990B,E0515484EB27BEC2,89F8EF09AB9D2ABF,000000015FBB9496,93150EE42FC7427E,2FC39730A68CBCF8,D1F9BE2C33D5B269,36D7ED7F274F5ACE,E85AEA0DBA4B528F,18E8FBAB3C76B1FF,E66E536052F10F65,54446E66803BCE5D,E2CD8320B31F3D90,000000000ACE5074,6B09A858A74F419C,0BE39D416F4E38C6,1C5168D38B7EAAD5,A18CC612C301F9AD,DB00704498DB848C,54E176614C2568ED,F65C4845116D0D94,16D02759DEB443C3,8D34482C1BA86E78,0000000002D5F5E3,02A43AF1D1F537A5,54A9E63D1F6FED2C,53600AEDA1FF5996,628B819489270B1E,C2564D9081418284,30FC17ED1ABFDAE2,22E8DEA07264D14A,F16455E957D867AD,2B58D2A81A533B4B,0000000257CB1C3B,6DDA5F4C2EC6A6B5,42F3DEAD5B928098,96536CDE1E275F42,F2C4D0DA04C4384C,A7C1B8923EBC1E92,8B4974F4B7B62A39,629835C3E918C035,A8584B3677798C85,5ABBD0A618442E17,000000013D5305FB,7FA3268AAD792780,EDE1A3127D28D52B,9E4E22C4D004A0EC,0E8A70ECDB531382,6A0B2B9B37610B9E,2C087B2B92A24C3F,C797C96358957FCE,B40710B0B9563748,AE853BF726CD7F2D,00000000D6839098,1CBBB3C60C9029A6,5AE621708D67B76B,5C4C24E4EC5DB3BA,81C0E4A4E2080F49,C06CD08E4B38E5FE,6311DB444AB18930,1EB614EAD8A27E32,FE4C76C5658F21DB,EDEADA6B828541C0,000000003FB26D8D,790237EB7F3D9082,0A15179447134962,BF1447F1890E94FE,91D53455B8B1C9DF,D56956F208A3901F,9B2ECE2DA375708F,D1C5D1365CB7A08F,4B9AA51B85BBECE1,91877C59D79F16B3,000000003D00173A,CDA8D0524ED0B1F8,241A9EB7F85E7E59,E063EAD9D48BAA67,E11AAA7274A6DC04,9FDCCB3986F915E7,F5D6C59D96478245,291EE7E9F516FB54,9EA9E1BAFA61C8A4,72C059898225B80C,00000000504EF98F,F060658448C2CB81,0AAEAC70D781C32D,F84833ACCC89076D,296635DAC17D0AA2,9F7CED8BB0949F9F,63A37B1EC0D36EFC,1FCB55C3520DE66B,BC3B635CF0B8A9BE,207F96D1987821D2,0000000123F15EEE,BAB48344C501C15B,4E2B73F2A97945F0,B659CD438E626B69,75A93F11211AA64E,645CBE3B477EEAC2,567DBDA8E8418AF3,AD1BD57C98335D51,84126F9D38F16D0B,800F65E0B1BBE1F4,00000000DAC8BEBD,72C6F07AE3D55BFC,927ADE60713FB820,D6F6B6323148E886,5A01AA99374878EC,9F3B28A2277C2AD0,D65E5814240E59BA,30220891B438B26F,557AB72900B8A954,81569B581A77C07F,000000013B13F1F0,C250E869118335A1,C7CE5212BF1AAEE3,282AAB5E685162E9,A9251A02AB0800D5,3F376DE5093742EE,660E64EFD102F421,E7192E995C0A85D9,0F842F38D3C46337,92468DCA1F1A2E7F,00000000B5D7710A,F5D788EA46F19171,0D18766A0B7C3F1C,5650B874F39CDAFB,D40865A5E9B3B1A3,A1591CC41ADBE9EC,5F42B626857F6425,389C5C82C4B58225,B6302F85ECFC77E9,F7E9F91D496DC6B1,000000003BCFA3F3,617CD4E6FE22C7D2,B691EE1E4A104A38,EC210BF0A6ABB4E8,8F09474597C95AE7,D7C90186FAD910C2,6FA6442F1DA27645,C90490360967A357,36BE5B4680E7CEA3,38C189AE0D14EC9F,00000001B17286F2,5230AA5F47A3BCC8,897FC059ABC2A318,51F7CBA2841B0B41,C5D72B65402BC2E0,AA5DA323E8756B40,3F38D85A9866BDE4,BCDC28CCE7ED4AE9,3905FA192B342C6D,51ECF94F4F95CBA8,000000009333D2BF,8CF01F95F2D0B0DF,A32A247D5A00A58F,A043A3E4F34059AF,A2387089F5E8FBBD,78128692DE26B1E6,17514EF912AD4C29,607D3FBB23E8D5FB,5C815CCD38049045,74B239B821EEA0BA,000000021EBB516D,CAFACEFF91A62F1D,91D3B1F9BFAF2FB3,1B74D69FE2016816,EB39FCED99DD244A,8B14BD89B26F1D16,609CD9FADCA83F5D,6AFF45B070F175F4,3E3342DF91AEBFCA,FAD27E1352B6C316,00000001251227F0,6D73E95E1B053F79,AA694F249825E482,2834264739227C27,41BF9CC1967D1612,23696C9ACA6F3D51,8E3E60756731D72C,990B0EE7E793CAE5,7E7969957E92E6AC,8D44A274EE3AB610,000000024E1C3518,B87C111FCCE946DF,05211EFB9F0708B1,C9C18EE494EF68AF,142024797F9BDD5F,4021830B605495FD,77057161F6193C42,56146295F649637A,32C9A194A49EBCEB,C7FAA09490450AFF,000000025F7EE560,445FF004F0BF8913,EECB1C10CBB2DF65,BD0A7C3B9087512E,B0F5407C266D67D8,1F8DEA3918801DDF,F82CAA2D78BDE754,026003DE44B609CA,B11061851EDF4517,92996488204A5A5B,00000001576C5483,55ED4A8A52C25C5E,DD6E0B994BD0E464,4389C8E3D7105E28,F2E6476B2E5997A5,D72A9AF70603DB87,4ECE856161321CD4,E2E813313D61EF17,71089693CF47B6C1,785757628EAFDE91,0000000243427C5B,B10F1CAE6FF00E40,382AC95112479CC3,6B8404909E9EEDBD,2364EFDCD6D4ECFB,32AFBC58DABEDC06,A68A37E00130E3D0,4A0D5A8B92E1CE5C,460D1DBCF2A46B7A,7E12C8D59DEC298D,00000001F42FFE67,CE3684A4501C44A3,8AAF700397499EE2,881A16A3BECA7893,FCE9409D3A1D0B80,16AB48B8DE348BE9,B0205CFB4CFCCA44,B947C958903204A7,0DBBCE85117AF8BB,526EF7E17A9E7ABB,00000000BD9579D0,F60421433B9BD3BC,C80CDE94970B4F0B,070B1E9658CAAA28,07DDFF44CDE2EC95,CA1290ECBA626AD3,F0FB78911351BB68,598481BD40A9BA0B,1B9FBB1F42CFBAE2,534F8AD2E9382B29,00000000FC37C596,5D609E8E0504EB01,760F836747D8B975,8BC2B26918407B61,E1BBB48AE3517076,1C779723573BF293,2E4AF4BD5D0F08F1,EDC0A4A353C52E32,92449F3EDB6CEC8F,014024292C28BC95,00000002738FF760,33CE155E355EB0CB,50D1C8F329DD5452,BB5ED2D1401456BC,FEB8EC8BA41B0454,25F6B6FD94599082,8AFC0F2D556BCAC3,925F26557B1BE1FD,45E3C47853C30481,71DBFDCEEAFD697E,000000009FEA4685,5565FBCC47E632AF,91AE1E7CC7DD0625,4E182CAEB1C06898,8E111D59BB7C4AB8,C2BCE76F608257A3,FD9B1B42D63CCE38,9BC4C4B5114C3BE8,12697E2FDBA6FF73,891BB1D04E2180CA,000000007A41C666,1FAB612356C330CD,A8344B3E18A9DC3C,5DB7837E47794392,E6D22188A3381D29,1BCAE6A201DBE842,3D5782454E510AB5,665F6936CE50255E,5BC773519F515FD9,1CB453C8CEBEACE9,0000000220E8DCE4,4F8509F4AAE07281,D420090EAB5BBA35,B52C0B622A004D87,6295EDF1B6CE5FA6,7F22EFE9B9EA135E,1674F05AD79D1E9A,A9360DEC5DF1D072,27A279D20C181A05,555000FE3EC198B3,000000011615C723,53D0A1FD2C2316FE,3F4403B9CF880980,F2A90645BA859309,92D4F551507A9B09,1F8E84F6CB843579,1B1AA7F00CE6AB9F,A6CD5C80123162DB,5E0323F1BFBEC00D,AA0138C9CD9F327A,00000001F09B7058,F1A742D68F8CA4AC,02A7BB11E8BF5A1E,31C93FDD6D19CD21,899BD26F56FB6011,5A65474821C9B313,809B595E63DCB162,2A67755F4E739342,7B0FDCEB1643EC2C,17F32ADBAD8D3125,00000000CD2A2128,C835F1F878054D23,096F45245BEECE24,C34F9780AF83C84D,7B28A7BC66A9D74F,B63873DB4FE61749,CFBE8F76E8516385,75BA5056EB38B143,1E76AE18827D4451,3CD63CC975089702,00000000F63ACE6D,F5FCEB67BF5AFCD1,F2C5B4688BCE7550,C91B868DA366FCF4,8E6C595499436E33,AA59FE2A07FE654A,9EBDC17AFCAA9B26,03F28C6416661C63,697DC8BBCC3B7032,C0CD79EE3204A3D6,000000008135F583,AE5A293AE539DFD6,4E0DC1629D68F5D9,2B1958088E707197,9708C96EC1E64493,FF8E21C61E546EDF,FFA2F9C9CFBB0ABC,92B9525C7E43E0AE,AFBD859027973C31,06D1FE203F87473E,00000000724EF99B,07A39BDE935300D5,CBEAE2F6736768D2,CB925384DCAB0C42,276C4A276043FF6E,2770A90F56E1EEA9,CABDF4D5E7FE23B5,B476C31C34228D84,43E9B1025300017E,D859FA9FBED9B5E4,000000014263A1F7,85C1B571D754C5DC,3E59958897ADDB8B,BD5FE7EC62AD67A7,C783E23374A31132,EBBD1834101E1A84,9E862FD698CA6687,936407853926AEE0,7E290BD7BA0D1006,E2E8742602305C68,00000001076A24F3,96C3F44B7CB6F5FB,B1B00046C2E0EAF5,6F3AB89E44CB2A6A,2CCABC73396B132B,728468E7471622F8,AF1493E956390E66,C55E3AA9FAD887FC,733F4886E02E12DC,1A10092B12F3CEAA,00000001EF6BC74F,DDAE54F4E19AABAC,E3843BCF3C788E1A,BB8919B0F4C23BAE,277FFC00ECFC9133,FFA999FAF43B9239,BF3578D749A6903B,F1AFC26DADA63257,89D6DD850049D442,ABF87190BA1E3916,00000000E6BD80BD,B6E77979DD5BDE54,EBB59E8154B24395,213DC4428CC2552B,6088B5684239C97E,6ADE14F35F33FF2B,399DAF848C0BB7BE,75AA88B89F564182,1732D396B303EB0C,EC50C70A93822B8D,0000000239566B58,C9D79CE1718C854E,A1D22DC0BD548597,4912B8CFD2AFE5CB,2891FCF758277C0C,173B2DE8147C3B1F,7F80896254C1C089,638CD4FEA2227EC8,877729C2ED576391,AFD22B54D6152822,00000002633910D2,86D50B194FEB2532,D57BDEA739699B01,6389105F153C8BAE,2DCBB30096C5BC4F,6C6C0E98D472BD14,278ED3B10BFF117B,E1BC810F87A799C7,DC8DFD000A7179D5,E529E7D93ACA1A0D,00000001DF676C70,54BDCCA2763868B7,47C9FC87BB909C3E,EF3758A200860E2A,E20423450F1F578B,854561A3EC172BDA,76CF42AB34430091,7D7946947CCE4AA0,E95B9A1AD3D4AE31,6E046EA710F50E0F,0000000249660AFC,A1599B7247D8E3E1,E4D965145424A76E,5A41D8A962C517DC,BC828201DB4C6A1C,0B6742F2EB617224,65AC84E61CF9342C,40D27FB1992AFFE2,914A3FFB48BF8216,AB88F564711CEC10,000000025A824CD8,8259290F1EDD2295,4366A802E280DEFC,CD95D20CF37701B0,776845A725017A24,F7236CE35A3B451A,B49B2A34D4EFA900,4B991BBA3772260A,52373D1E3B6B8F0F,530F005E06E67181,00000000B727DD70,E98570E3B0CF1C7E,D3BA320CD55823A5,809E06EEC849BF02,E44200B79C6F2F3B,82C1150203FDE3DD,FA668D83E0A1392E,743B42EFE4CDD97C,A5D28B13850F6294,DF1D3ECD2ED5072A,00000001E2A2A37A,599C735595FAC7DD,55D2768914F1F1E2,AC5BACC3012A5636,7F9E2EB1206CFA6C,3D6643BC57622FF6,D14C9361F0694F16,740CD8DE7A7A0836,22D1F2D41FC7D711,025C7684685C0537,00000001C0CD17A5,60FB565AD73EF087,9957264D8E378601,23050D4BD282091F,21C42574CDBE8979,3D2A877E095596B8,2D0C83317C706231,4722C4AE7ECC3B3E,2BA39FD2BC1C84B4,D7DF7E5A20E9E1C1,00000001125FF085,20564A720A8DA446,2BE9C122F10CEB8B,F838BDC172596669,E25AEE455BA8CB2B,A029A93BF9543A37,F7966D70A941F3C3,A1DCC83F5657539C,3A9EEABE8682B29F,F027E80865E9F1AF,0000000115CAA60A,52847B38D278BADD,1599DFCCF0422E70,65541DDCC9C4DCE2,A1DAEA892E328F2A,C6E578CAAD0EE21D,DF12F814721891CC,7D3F965D3463CD37,41920113EC3D1A88,5463A744AEF75545,00000000C7AA6BD4,AB3037E43FB63EF0,814D160477BA0BDF,4C693E3D4CB3959B,4081C989836952B5,CF8E3EBFD93E022C,AC46E4463A921573,0778C68216270EA8,57B4175CB83ECABA,B34F009EB997A5AA,0000000186BFFDB5,D2B6F873C1DE516B,17424453F693B97F,2509B9EBBE5E3B3A,E1FAA3300D2BD41E,0FC1F06D69D5F762,02A9E54B7D080DA2,82CF5E0B973937EE,CD2EA8A7B5317455,1A96C3A8938ECBB4,00000000FD0966EE,8CAAD23905498FCB,BC0DCCF478870643,B5248C19B45064DD,94A56C670B48836C,47D2D593911A872B,503EB6487167CBCF,C9CFFA7380295629,55BDFC456A0AFFDF,50061EC02E04B3F3,00000001E40AF7D0,C50EF26927627DE8,37DED417B2EF11F9,8D4D3B19248D0D2A,C2A500FCDFFF2D60,4A28FD78FC3480C0,1F4C30FF7FB6EE22,BB3F9D2FC6957907,CD5D1ADF83907CD2,381A6F8F5FE77712,0000000040278086,063325D89BF9D9B1,92501E9ACC3A6C27,D618673514966A23,BF5E2FC1D0F1549A,F190AED5ABD166EF,A289E064A8F51DAC,5755DAF045EA7294,74A3F460492DD8E3,877FB5CCAE4DDDA4,000000019FB78655,08CBF99590EF9BC9,4EDA7476D6A201B8,6971F2F0F5BE1B3D,611BB1A31DD7E588,C4E21E9E05D37704,9A59B4A98F5D6F31,F3E68CF75BFB4663,3741413E86840F4D,7BD78F7BA4653BF6,000000009198D41C,46FEA33949AA3F16,3AA0AD51C80B1C50,EBFEDE549812D068,43F73A92AC35F189,67DDAD874E82D4C2,23A61E95FBD53126,D221E3434B13E5A7,5A8E56F1EF5DC6E7,6149C2005B75994F,000000019226F5F3,F9721A439B6F57DC,3411CD4E9961F28D,923B22064C4EBE77,9DFE08C8AE4862F6,230B422E9822F19E,0F9E231E4CC06269,6491F5E4EB2F5705,D9C374C46ED0D065,C29D7AF16075CE16,0000000033005BE6,FF194CAAF9039694,0913F5B5BDE1D7F3,57125F130850A0A4,951FFB43226BAFB0,EAD7E6CB5BC556BD,E94432B475BA705F,000BA147C4C4562C,5BC42F1F0544895F,8F8A5B3008DF089C,000000019FC61307,828A3D86EB6FF002,B49936658AC6CF69,7955F97071DA586D,4BE09C235AC29408,612CF843E5DCFF66,54D685A2D1FE619E,FA78E801187EF3B1,ED0DBC3A979C368E,C803995BB164D6E3,00000001C24CF95B,243966787EA04258,D8247D9537E0A4AC,19A51B75525F6B6B,F65019F19E0DF39D,20AAB04795A29B89,F8DD490591F8E3FB,E684FBC6832415F9,CF2966708848D843,2E45CCEA7D8A363A,000000008CD5369A,759AEDD9746ED0BC,434F104434F06D34,1D9742BB0AAFABDB,05D1213CD660E0FD,BC5513EF7D2818EC,AAFE0D3EF7992A54,374D8487A3740537,210BC302BEC909AF,9C5DEE6383AA902D,000000024F7B50BF,793109D0A42F101B,49FB9B0B93E421AC,7CC4A2680459C5CE,2F5E3B8423D8253E,2C1563A4E0381680,1C05509B5D8AFE5E,5D11F61E65C1198A,1072DBCA79662856,F9D808DF993B7095,00000000B8FF8163,D476B06EF37B4A95,BFC27A6986AB59CC,5C0831294A13F5CF,4410D8C7348F4F58,156F822A2A3C769E,A539CB8217E7D212,D2A22CBCA51A20D6,6BD198D3DB6A162F,00432048F5296EFD,00000000B4FAAD14,E7C45E2AD8C8DBC0,9BDF9AD3A4892ABB,299B8F2809179F22,B7F032FF5C37A5AC,7DC9B00AF93395F8,70DE2A42B70A5A71,5CB8ACE37EB226E5,BE96426DB1486DE4,1BAAF1F5CBD8CD09,000000026EA8C6F7,D5F2019FE0DE0280,9199F432B532041B,FB2AFEF87948BB4B,F3317F64AED3D26C,30ECB9A0FF67E6F3,A0700AEDA3E8A467,14FCCA4085A8B3C1,10F73D39D1DBA992,8FA54A1868343B3F,000000016DC3A7CD,B857A299BB2ABD40,FA2EFDEFC5076578,761CF4019E65A980,EF7913DD24C107F3,9CB1390BEE7E1707,D2C2095CC8F976ED,603D2ACE17DA3B19,AB7F4946B5347B9D,E3E9F633E5900263,000000024538B1E8,FE6E99A6BB9D2C1A,C75F8BD1F57D819B,4C7D69F1DB0F7368,9B03585DC2D3CA97,EBE99607E55FB110,8B34E800BA40664B,288EB9FFA1564D4D,004577130AA197AB,EFBB36D2594E5FD0,0000000002C38890,89DAFA8AEEFA5796,25EB91BBC3DFA70C,320F7E5C86D50154,E7B33297BAD9237A,311BA47451FCDF14,E01D216A1778B94E,7E96C3BDF82AC928,61F136E94742D387,BAB5545455457760,00000000DE077DE4,88E95E245BC60314,F09AA1972BF47C6B,21ADF6AFB5E80C82,19F4FBB4A90A73CC,B4E4D637056232C5,B379B525DC9C8F29,43D7DC8E142399EE,149B189F1F522F5C,D67BBAE7420AFD03,0000000004F8F7A4,F52546309097E99E,39BA03EA5B811B56,3AC30A1EE90442BC,53500AD9BDE9E744,58CDFB2336C760C7,0BA89A37E05063E6,0E49ADEACE893931,ADA2C78650772DA1,1947198A2EEA4CEE,0000000094A9BB62,6B124F00F2D3582F,0EE56861E5EC41EE,733A4F6EC1E91916,3B111A2C6B85DD57,C06AEC4BD675EB0F,2C8D78DBBB8D4675,149B1BD9F0ECAA2B,ABAC2F4353720807,6E5B8F30BC2D8F10,000000019824BA1B,28B0EFC99148C94A,BBB52D795741BD3E,7C9A387FD1B73C3C,3DE0EC6385EA899F,D6CB48E2F879EC66,889A91222BF306B5,4FC51D4C0B91B75F,98DCF346A767F1EC,803E93766E733D7B,0000000004F174F2,16842DBEBF140C70,4B130576350FA4E6,12091DB1BF9DCBD9,36495EF0E57997EA,6FB78F99EBF0F89E,8DFB5AD197CE1D38,C5A8E66950F090B4,5CA870447D77679C,5F5B0F3C67CABCA6,00000000C2ACF322,1BC2D9E57BBBD7B7,A68150447E060698,22803E6AAE8F21BD,6448BA8583308C46,12ACCBC4DF32917F,AC4867E294795133,AFC9A7C8C4F3CF5E,B3A6A1FD3D7A91E0,B1BB4866D06B84B3,000000023189E9AF,F73378E05A3E90FD,362DF21070E4C526,5BD5A04CA55F5114,9B18D88125EBC3EC,8EEFE5E679B927E0,00102418F66F49D7,D053EB8188361C73,283D6892E122BC7A,B16EDD43EA2D6D08,000000011B78919B,6AD19931F24A3820,9FFE734CA957EBAF,5EE6D6ECC3DD2B60,6251896877AB4DEB,466ABD11DED38BA1,55AD4ECFBAE3E341,8B7DB9851E48CFA5,A7ACBD4CB38160B9,8464F6DBB0D620AE,0000000205C4AA56,8F2A3C6C0AF231A4,222764CCC6C064B4,4399BCB6E0FFFFC2,73BD9646D8E0C4AA,980C7A3C382C3388,E78F76E5DB4A63CA,C41E0BB47662B00F,F137CA544B68C8A1,0B8A295BABCA616B,00000000668F3C02,42DD176A132A708A,E55D288B01CD1592,34D1B96460C0EB17,870D47C8BE5AB606,C4A5FF609EB59B17,DC64703EDCB3171B,BFEFB4AA9D2A46FD,85F55FBBB2CC7C7A,081DDA8CE21E5BCB,00000000196AB4D1,7103157437CAFDEA,1E545AE187A914E4,AA3963D3A8784FC8,650BA2BF19961183,EB3AE595994200A6,4CF9F5CDEDE7B7C0,973038D19E88976A,2A22C4FDBCBDA31E,F2357F444F180E90,000000004CB50D36,BD190E7FACE99405,5793619991DE05CB,DE4F1FBFC80ABE2D,17845ECF29FFEC85,616444B07C9C8398,BE86D3975E23F5EF,819E1EC01854753F,8EE12CFC8A47F663,E699FB467D096CA3,00000000DE9DE036,D882553AEE325D7D,FFBEE650D50A5215,86443E5A7A76E9F0,8772D199E9EE320D,6CD4DE211715CEB0,353C9B7F8CE238A8,F38CB19593144F47,F665EC6CD1038322,D981823834E8620E,000000026473C89D,2C906E00B20EA5D3,DA8DE9AC63B2290D,851C3AE4167078A8,6181956D55EAAC45,CF0E84452E5884F5,79FE2ACCE8558746,314F5933EF876BA7,4FB7836FFBCABF0A,559F7C7EB9887412,000000004C7ADDD7,4D516C69EC9A1994,AD7F29D51C430C13,7EE47F79CECE9DBF,53C2DB427C78D8BC,E79BF93E2A270717,A82B984C5442FC36,2B725712DC75F309,D7B58672A3FD2C34,ACCC37E8A0E878C6,0000000165A0A0C4,163701CCA2387A1D,7BE059CD34985C77,F618DBCE55F474CA,80603CFC26C0FECE,A1F13A7CC6F725A0,77577C6B790488ED,5FA69FC7D014E864,0E4EA0382C37504F,A148C1B062A5E928,00000000C50E845C,BE7E418A161B09A7,685EF1DF0916E4BB,B0B43E21CDBA4DE2,9DF857F56E0EF0AF,6ACD902C2CEF0CC9,CBE160FE9C54C13A,D75D573710293C4E,BC01273A8CDF8026,409D296828846E83,000000021922744A,94B932086264A5C3,0C84D1703D5569DA,8E134B5B00C11311,F9299BB96CA89DAB,B1335D529AA0D0C8,A68BE222F897188B,D4465BB582464174,C84F7D7A76B5ED18,544C030216BC51A9,00000001CB984825,F6CE965B439A63AA,337D05B217729E06,DF936BC4A427C1B4,667ADD4F5622DF62,54D5F40F85E9CB77,7B8898D87ECA12C6,FEB1822889F40510,C6F23B4D0A856021,2FC528BC6B3BF88E,000000026A4184BA,0E0DEAD06FF87AF9,32567C814400C198,67ED757330E75096,F1E9E8E657624C27,3308CD9825993F3F,88ED92A59980D16D,5AC93E9A906F7181,BFDC73EC54E67F3D,48EAB3F5C624A6CC,000000022F92F5C3,5D2CA304E70C8611,5278826D04CD406B,2BEABDA460DD801E,7C22B64E5EE1EBDE,FA422AA15B3A44CB,87A1D0AD0DFF61D2,8F128FBEAD1D1FE4,5614462EF30B02AC,FC96CDBE32253C3B,00000001C692091D,37843490B489F8EB,48253E09C095F872,D7F6DDF99F992397,7134D83DDB89EA7A,DF5B351963E9BAD5,F7B2DA8ECC71A70C,0DB7AEFB132E4946,5894D6D3D7A738D4,68DF674BFF46DF43,00000001F7852A9D,66C5871FC2740A9F,23D32CA15BAE4E50,48F92E1FD4B7C25E,A7A3B0F9742D0728,B06B3DF8216CE55F,73AED5B82F3FC0D7,20702E89B93C1B44,3BEF3F752CEAA7FD,F5B54775D64DC3E2,00000001D13B8088,32FF62D52795A87A,B6056A235647D920,2A4D9D6CAF47F9D2,546125CB708A0940,4A076FA2160C9852,4908570D70254569,942AC3C841886905,B60F92F2CD26053B,DEB806C09DE781B6,000000000632CC9F,C14EA317DCC058B3,F12BE6C09AE56933,2A9B3EF22752942A,01D5EDEFCC469E92,7C947145DE2B1DAB,92731C74800EF924,A7728C1415276273,252F45C337CE66C6,5326196D4A4432B2,00000001EB5A370C,57B9E7581AF1698F,DE9DF22EAF370F67,68623464F19D596E,D05FCE0416F4FF29,C2C8A8104553286E,ABFDF5D0959FE068,DC6B81DBC9F10128,0CD3D48278338371,7E163856D5151C22,00000002484D8649,677E56E989C4E34D,99BA683695045D34,41187AD2C6A8CA10,B18F4423368B7289,A55015ED0D9A6ED9,FC650ACBB3778AA9,A180DBC547D63A7D,37E9E183C61184BB,F8EEF7BDA9DA7142,000000007F94902F,85F0270596CE8C54,C38F5C20AFDF3648,05857DF87D84EC25,E600451ADAB0C11A,3C589406C0915992,6F0C6155D30D02AF,8FDD7522A1EAA020,CFCD602CF7C7181F,931EFD8D8C2FA51E,00000000D539F6DA,5232E83F50C87BD8,8ACE3C042DF1EB3C,4C6DF92B298FB7CC,337004C76080C3FF,1402377372BC487F,72A7DB53BD959E4D,1C930EE205CA0530,C807B958672384D8,FD1DA40A650BF5B1,000000000998B522,4F822BE064C211DB,DAD990621D8B9294,F4B41A8B0354F29D,BB6BF2DE9DEBDD7A,6E5415BB4570FF43,308FFA5774FD0E41,B1DF06D6AED2D420,D505FD372B9E81FC,AFFDF4D60F262A9C,0000000057469E9E,8004A74C5711C3E0,879D5F8BBFDCEC0E,74A96438E7486811,B84973F6D25CE569,68AAA443F3BA9A70,E04E07BA73164F8C,C4FB07291B4D8962,4AAB652BFDB4E624,C548590A217E092B,000000009641AE52,7C1BEF66A9238BBA,63953CBACC95ED95,7901A63222234365,09A5A2C5BC1A0EF6,096D6D76F0842CB0,32B24020AA8C297B,11E6ED2738BB8548,B78C5EFCE3EB475F,5474396FD8B21A97,000000015237FE8D,72F4F535A23038CE,D393DA7288464FFE,B74A63E97D244DA4,83D089EDB9C7DCAC,FF12BBCE03B7458E,BE6CD8EF04E203FC,3AE559D478756539,5AA7C25BCF7FD143,499946F38968AF28,00000000E893BEC1,3E175E5F8FF9F517,4498C1A3C9880D49,43977C857426A37F,998773F66BA41372,0F4767814947A5C2,501669C08DCFC2B6,3F2F18CB5AE52B38,A6F9E6F0D1C498B4,F4F7CC704C6900C8,000000017247BA1A,ECB59839E9381710,130B20FB455E064F,068067069AFE21FA,71AF8116073D7080,E2417157781BE674,5D539446AD62CFAA,33C2EDF66A0438C4,90E03D85E53862BB,B72CDE647A96C4C2,00000001ECF1D3C3,74A199AC2E090022,5A44B09B1382D19B,2BB9A23BEB1E0175,AD47E30B4B63BD50,A304CC2CFA526101,BD4FCCC50A033809,AE59FE0D7A3718A4,CC3A490C48902FF4,DC7D473BC7BB9709,00000002138F7587,28587B1190CA8D27,6B825B8F9FEC7B65,9D0D7EEDFD607448,253F5FF13BE85A95,E4524B80A75B899C,BB4C32A6ABF2EBA5,0FC446B45E09E8CA,064866938DC63FDF,2ACDEC7C96A92D35,000000018D295152,7981F6528A0A3180,4D30A56127379ACF,3BEC27FC98E69933,67A94527123A45F4,4605B7E10C269B68,B91878107781012E,564D76719A13BEF3,2CDA7029382E00FF,DDBD18FD19314016,00000001E84EEBEC,9DF6E6F5E95A992F,5EDAC78111BCD791,39F99B4D7A136710,17212C8C4C612B8A,C9A750273DFB59A3,C7478BFC94C3F8A5,8B1769F71AA005DD,E2ED136AF96C171F,B7EBD0AEB3B50721,000000014678AA3A,1650B7C88880190D,AD43E9A4AC60BB9B,F73DA2D744DB5511,0C039DED4D50B616,E6F4A3B83047A330,28D9E8D4DF703A24,8472DAD5D54B2B14,06C3900CB074BC6C,31142E80040C5ABF,00000001864CD33A,7213E135A58AA7C8,1CB541E6A9ADEE9D,8DCDEF5F13008823,9E28F2801F48D42F,C9CBECB576450F7D,1AD00EC6170E2C97,3F0600878489E330,51BABF5A2A4476BD,89116AB3E0AE1543,00000000A49EE5BF,EE0A5446858A4724,FD18123DC3C06D1B,92CFC38129395B97,8F8EB736BAEB46EF,499791C509040BBA,202EB5284883FC2F,70A77DFAA5D02EE5,ED3E15CFC4D041D4,E3618A72CB63F9A7,0000000069C58391,24C3A4902C3B8812,8EF3C161237A7A30,864EA3DD10FBB3F4,9E2417767DCE7EE3,BCF8D655DB1B84AB,795456A0B3D773FB,0190F9BBE057786C,5B0248EE59670243,9F47FD58DC993268,00000001269681FD,6F468E1AD55958E3,D3C9B25A2907CE90,6C0990538ED2C755,57B3FEA16233B060,0CDFE132427C92D6,A56C5ED7DF338E33,DD215D0B973BE068,6606EBA9FD178518,A6907C6683E8E6BB,00000000D6F54C17,8CDE79F82FF12C8D,6A6B4D1302904D5E,2D15A0C1F4C5838F,0CA6F615E5DE95D5,FCD04161C961BD40,90670E646F3E201D,99C603F42081B3DC,4A6325FE3CBDCEC9,4B62A4EC560D135D,00000000A09EBF32,38BEC2FA9BD37DB4,D0ABC94AD416C739,E2E6576E365A70FD,494AA5D188130A4B,9706E58E0E169EBC,D395868D4A1CF04E,042953FD228AED0D,8C10825A8C426496,332AB3DAE46458C4,0000000048D26C37,46579C11D5A096B8,5F45B8DFF26EE870,17C29CA46B266164,0D881ED99966E419,B36DC194BEC52EE0,27EDD26552606D63,28812EBCD67C0E39,8BCF62A64CF618FF,8E678B303278137B,000000001B7A1F61,3820BB09D6396FAE,1366A5270D0E9D5D,C049C98311FA8050,3B950B8A0A2A2F47,40C54C48011913F6,8611E3E9CBE20322,D50FAD091C394195,29E2F015695E217C,7947C61ECA622A4C,00000001CBB2585B,5E60FD3A6B690945,9F23229681DD6F41,8424E34459029AB9,5D9C7D4583908529,BF43B89BF9645483,F44B90B2C3BD16BF,47F6AEE0BC18FEB9,8A8F17E2D6406B9C,9F1162F60C1F2F38,000000016A553AE2,3F9B3682E89DCFD7,1C2D6E4AA4E74111,116DEEFE02F9FEAF,E512A1D58BE73E86,4D8D931E439BF261,49E92EB1C78416CC,8D0DB0D10C41C34F,C8A07F8CAB3CEDBE,9DD41231A9E2A7DB,000000016C46E7FD,539C6F15036E19A2,854671540C88DDDE,4A3B26F0E61188F3,4ACE3A4A69CC90A2,F791D930A4197AEF,4CED7FB0CDC05595,E36A7E3BA1F2A15E,9438A27B89016809,961FC51389BEE60C,00000000C2995255,2D0BF80B36EF6454,9169613E98DCF189,A6D2392F10C59161,727D575AF7248CAE,B523F327757472DE,A4990DD09E5DF668,9966CA960E046C14,E85B35369F6BE921,82BC389E7F923FED,000000017940E48C,847F44B20AB1A22A,C772E508D04891D3,25954C748FAE423F,AF6E07598D820856,64864A72631C59CF,5CAFDD4A92442E49,48C1C50C54C5A795,6828A884AF7AC360,1BB84810F5554BCA,00000001653DB5E3,AC601DFB64E7193E,D33E78DB22AF949A,CF1D5A30D825EDC6,F293D2A99EDDF6C0,A1B1274D1B7D4C76,FB6044860F9C3FBC,9B78124D54C81722,26CAE905150D6D10,6BE38EA4B6444BA5,00000000E040FEBC,3C26D9085149808A,B6C6D59292E682E6,1CDC50CFB0F19CCC,61F6F44CF8AF2D09,302FA0CD35433FDF,CE98E2AF3FC1DE91,A242A2E1E39EE9FB,EA22E9A0E7F10205,98BFECEF8F8A3FEA,0000000110E6F07E,16FB9DE9FED06DD1,D13B9F768705A763,4CD5B0DCA8BEF359,4123EC7C01BEA2B6,0FA8A90934A4C30B,2BA62EF6FC56C6E7,80FEBAFBB0D34289,557FAE085A0A2581,ADB6F9AFDBD32E88,00000001D60494AD,FABF9AE580E0F7A9,3E7B0420297FD574,B540900F4994B012,56FFC77B5CB0A58F,8EB5342CCC7ED747,694EE189BCD3DA6F,C2C63441356FB118,1A3F09F2F196E1B9,AEBEA83382071144,00000001793C49E5,F79E00C6980775CB,53150C9B8B7ADB39,713CC2EBB25629EF,21E8A8C1AD54AA10,01C2D52E00249697,7F26FE77EBD8C764,828D37002AADB327,C67DAA4B13E64984,6B2D08D8226E1177,000000006549E871,7D60AFDE8F9E8DE1,750A7CF0A7658298,9B87CE09E1F28A46,8017DC1680F1360E,2F63E86C8259A691,BD8310470BC6C8F9,275B331B04B50F49,E06A7F7221E15360,676F7FF7F59AC664,000000025D88359E,3DB5B4C6C82A9473,35BBA18E29937379,D89DE1561F9EBDD5,D0D9D534112DEA57,976A773D3D0D5C14,C4B053112751C867,27B170C5C7050EF5,40651BD73636C60E,C5BB619583BF4E75,000000009BE61560,988E7AAFE18E8359,4DEE72FCCF8D16D2,5E8A25D9EB0335AF,DEDD54C31FE3034C,B95CC3D8266376F4,BA7D7368E074BA36,4FE0CC577FADE12E,CBC3A34206D24E30,AD48B1413DC85161,00000000F9D8B345,9084D54799FA4FD4,AB48BC92CB879CF1,0C0B5659CA7DBC55,A819951845FFB57C,9332D8E4826F52B6,23F20E42B84BDB5D,886AC3285A280DEE,43F07296BAC5339B,5D71BD5809BBE7CD,000000006CAB0837,6EB9B80D759B0FCE,39D5D9AD145DE6A6,265BAFE7212F11C6,97078AE5307EF2A7,6862C13B7A504104,A20DE880A434AA32,FCB7EDA742901C8E,5BA5650386BF29BD,67834F432E685C60,000000007ECD36B4,EDBEC7891077FE2B,3675584BDCF480F6,96CDB606830D98F7,57166257E17EFD50,0D5226E852A300F9,9876596507D45C07,DC67BCACFE48A59E,B2543AC6BAA3C66B,2551E77248B22021,00000002109B09C2,0C5C4B7837C68D84,557AD4E31A739D25,43C09820002BFAE6,0E3B45B2E1DB689D,1700A47A6AF3C807,58FBED8DC891AA4D,A7814D3D4173C136,B462C7394FB814E4,104BB840866D6408,00000000A0E04462,E7AAFACBABC543C1,9489801FBCCB978A,A15725C7DFD4D6EE,9F7D3976F548D780,0F0C958A0F27C195,D9790CD48EC02236,88BAB6F65C75AC2F,E841663FCC0572E5,A1BC533CB7EE959A,0000000104D74462,1FB9284BF5D4E13B,98DD752B5E854CB7,BBFA2653FB61FDC2,BF8B544225DE53B6,001673EF9DD91211,F6E36173A979532D,9995D5C832ADE852,827B90F02D952EA2,3CB88992976B5B56,000000023A2D2BB0,F42AEACDB288CE95,458242770606C46B,5798D10115EAFF1A,2A481CCB724A3252,FABB0A668A83471B,AA9946591BA889EF,3D62BB701AA0776A,2FDC6C71DA94AE8A,4D5DF8630E2E224F,00000000EF69BD42,F526EBCF88129880,8FEF6954AA266EA6,A5221C2228D4281D,4018049F8029F5D1,133628487761EB27,C82C94DDDDFAC911,E7E431B273157527,F83B6C8B324FEEA8,015CD141C2BB15E8,000000004CAF955A,3C0BC6FEC0E5C126,C445C7376011C87F,3C8791BD4AADD1D8,A5EFFBFBFE1324BF,4B40AB2EF5F469A3,622B2DA7AA5F4164,273A45B52F42E07A,EAF3A223653EDC2E,4B454C398079FF82,00000000EEF96660,C37F65F3D5E48C0B,18A0E8ED1D7FF2B0,AA22FF56650F764A,44DBB6278D25BAF9,792C88D01360B618,5347BE2956B08957,C7F5831CD5323740,533F871F795E3E9D,C7A45D36957E8270,00000001BED1E2B4,7B35B449D2B40BE7,2800EEAC3573F676,72964E0981D4D097,37F680CED546A00D,6A210A488C7393E9,DB5F8D11B1261E67,BC90E142BDE72A3F,97BE5428BD1EF0D9,8C562928EB1E1E43,0000000010FD09A5,43C81CF1518D97DF,7EA6D12E1D7632F2,0ADBC7DCCA630D7F,58A7674198CD5FB1,61E4251CBBA4D9A9,26BEB131A2C0F170,126DE768003C154B,9B6F173328EAE683,DFFD836A2820ABC0,000000012D938AF7,7831F43287B75359,F24EEE5B025AC8DE,E38E89A00D7D9141,0F0EA80A73FCC3DB,D4FBD8D2053E83A6,532497CC64243D79,165EEAAB71D5D1CF,3D895D9959F81029,C27D10A6CCB42E1C,0000000105AA485C,260AEB47ECB093A7,9F94A10F1C5E6227,962E0616C44C3170,029A86C8A0169DE5,ED360D1A8D6056D4,343D6053B5D3FB13,5711ED4046472C60,49C7D68FA883A415,43C953C31B262EF0,00000000B0E1B6FE,84DD82DAFF58DA13,E2573CB7E14D05F6,278FD46E6FD011B3,983C8A8F0E83EA84,B10494C5C94EAD1A,48E905806C7C1B6D,A67CCB25954EBAC0,8ECCE89281E68152,0C6E67E1F6F2F1DD,00000000131E9BAF,3E8F77337897B812,BEDAC04D6B936D5A,9692134C0A06E08D,F805143E37025363,CDFF49CEA278DF66,E25F7372E9DCCD20,3CFFB81EC63D5251,2789FA7633F32406,63421A2FABA43845,00000000552F6EA1,CC9221ECC59E2479,E383A9698B64D4AD,C6F094E478DF6E50,BAFB549265140503,8B74D83A0F91C808,4B9054BF85013EB8,2C319454E52EC1BD,2BE21C719C7909DD,908F3A5514A7FF30,00000001A5C79E7B,9B7F87AFF527C93A,32CD2A821C1384BE,F8BF0527DA59CE33,6F98719832DF9D71,5BA3132C3E248146,C337AAC168001F39,02C46DEE2CC34E47,2B45E729C79B6B46,5E659F907B177A53,0000000088AB7EF9,6E0EA159BDEA4EF9,577E31ED452626C3,227557D121820125,163F67D182778656,F56859FD4DFBC4CE,711E7BEFC8A1A71D,2E24D09F1346AF60,2ABCBCA75F9B27CA,7F673038B1521433,00000001BA7743E2,B364495E6E0F74F6,A405A2BF9261ADA8,957BD29D77A8D2D8,8E6BEA5F091A7CDD,A4000BB074FDD68D,04749E44572A7BB2,395D77AD71D90862,FEE26073851F46E8,0E693EE488B1C9FA,00000001B2CD6927,12A2780189086B50,5A9466DA65BCE80C,E735BD77BB961685,8EE1E326EA1F16B4,BAF7405EAFD09A0D,20E99DB8C5ACFD18,49234F237B3F7A16,89A5D4A4175F9545,58E56232EF768BCC,000000025AB6CC2A,B8081F99A62ABCED,501F504D4E30FCEE,7EEAAEB6280D4291,D85B5EC1ACC24D1E,4113A94D1D75AA40,2089955BAC934CE3,8584044DE955647A,D459B33C7C030720,544E90C23CDE87CB,00000000E59B0EC7,767CDF8D6669B50F,BD40C5E068CEBFC9,3BB60C30AFCAEACC,51C9C04A195B1A20,98435153A8AF6859,30CD9D70970F310D,D9E4061BE9DB05E0,0CF433DFF99B2635,DBF5EDD4DFDF479D,000000009016D072,D9576F534C8E7E6F,1D664542189BB136,A729B944EC90660C,5FDACB8C7E3EC528,F4B6598E3FC0821D,81271ED86C006FAC,F89E998F22856573,2C9520B0CB9599FF,5A7DD049C6A8CAC8,00000000536E3BB9,306E1A4F019A2D64,63F4EF5AB0C2CC67,1CE86B7524999699,E2203DC1D989E34C,97403CAEEFB7811A,B8206EF8CAB4B36B,F32728FB8141710C,DD95B5269F2A545C,832DAF5F958DA7EC,00000000C5407647,0AD464880807F84A,F66A10CA28585F8F,FD01143C61955587,D03D27CACEE4AA41,129736878E8D9E04,B03D6136C1888775,FBF8439543AB8D95,A14944ACCA8CC21E,A755FA7C0B3B7E74,000000004A24588A,5CCA248D9DD44594,0FDD52A4F03999BF,4E7E4CE561FF1ED3,CA2D4D9B8EC3829F,7CDEF47F7B5EB6CF,65111B65036ED8BB,80718C2772FDEB91,9AB528EF6BA306F5,F7748DC75D232A96,000000011B2414F7,4926F889E0B2B0B8,29DC14F05E46EAFF,1E53032586DE33B9,031C2B1996AF7AE2,C74E5382FCE4DBB0,710426EA0A23D959,1A0F24701A663AC9,7887E8D0F58AB63F,940A232E9D8BB566,0000000010B9BCD6,3021E7CBE1E29329,834727E1C2ED79B9,759247C196B4B168,EB285B74D33C6E82,F8966078065F3E95,3D7F64BD3D891D17,A4AA3A1A7A3FE1D2,E62E2D1F1CDE3A61,8648B523AC6FE711,00000001DA1E865C,B49B1E434D116FE2,5A25D461207EC99B,DDE1D85227A0E271,73A742162553442E,F2934B290A5CA58E,914AD8EFD6F195B1,11063199BDEDF5EA,0628650D487B2D48,72D74AB66BAF7997,0000000165755264,ABD8F2DF96B5B912,29D8DFCA7D2EB134,BC3AA108C5B3CEDD,3E10541AF56EE16E,BA3BB1F8912B0994,7A27A5DAB582E963,0796C201198CC53C,3EEAACDC377AAD5A,48A504E71D7EDD36,0000000001729BEF,ABA67E6920B7FB53,4A723C7C68A9C9D0,C1A33B018B2C9523,61A72F602499C438,A82B7446DF70B31F,2AFA5D7C6861E9AB,270D291AF44773C5,AC6F68CE910A60F5,E9F6FDB3E3623614,00000001F06C6C55,8B9DCE10D44BBC8F,C3279B543BE5FC1F,0096A7E927C53EA4,8864C641DDE1B7E9,87B2C9EDA1B93232,60D538B7DF09D561,23A428F1F4C1F91A,FF2D5F7CE96FBD79,C2E0799DD4DC42DC,000000007095B19D,275D6B8E17158ABF,77EEDB963BD635EA,688DB22E852927EC,3580757D2C1DBD38,B6ACB32A7C9A2DBA,3ED7678E047B9019,CC26B415EC7A822D,4A3C7D35BFE29D39,40329FBD738F1BD0,000000025B6A2507,88AB1D8349F385D0,47B9051E2B927CBE,19AF2451B0157C25,E10BDA3FF1F28114,83FB1875691B2374,11663E794B8EF83F,9ADBD57C6A1CE9B4,08D77E1CDCA85434,65A909A398D32AA4,0000000266FC0577,275CBF3B40272F5B,0409FBD8CB186016,AEB7D4F44123DE03,792E632632B7B37F,2B6E407E40AE636E,3892ACC5A0909AF4,EADBC0A3B3C5011C,F0996E7ABBB361C9,29D07BC3D14C2D52,00000001CBD4E8AC,4985EE53FBE46F70,91FA758B890488E1,D38E416E4E442038,C21F9AC96C879E3F,8C5C3EDC0CB0FABD,D214FD400830B069,3D7CA8BF94758D9D,DE70AAEB2357D6EE,F27F16D707FDD6B5,000000019AC2AEE3,A67C45A720FB9939,449EE787954C8FF8,68CA189F6DBEF7C9,A351AC27374EA182,6E86B22DAFDD813B,B9D6432E0B81BF12,3BC9C2FFF7FC958F,A51AB3AD70227D7E,99B6B5AC3758B01C,0000000164FFACB9,3D496E1AE0FE901A,BCE4B1ABA554A27E,B59BC92DEB7D423B,E24BF7F482E517C8,1785575805B7A604,1292AC799BF2251E,68D4A43E35D94587,5578C70874CDCEE2,0B36F027CCA9EBB5,00000000E905605F,613DA726D0A61117,46A06F1787BEE469,C8744F5EE98DA99C,3F1D56DA50A7BFDF,3B1FF9ADDD273128,C9827FAFEEF31A88,DA05BF4D607BA4A5,521F24BD676BE6C5,76F5F3A46800C960,00000000EA4F5849,7B646D0FF7F19F3A,D8D49FEEB8721BA6,E2A72D1C9EA047D2,6E3229287DDD67AC,AF7080591D1D28A2,428B3AD823E73D53,5CDB172D5129BC7D,213DD8346ADD550F,4D94F3E33ACA24A6,000000009D54CA06,FB83090ADD0F244E,F3808EB7E50B60D9,2975D6E2865DAB0B,694C71659FE634D1,D588269983310CC2,7F785076286BC9C1,C9BEFF5CF99BE9E5,B06113715D468D83,115139771C66AEE4,00000001304132F2,7CCD62A9F575A471,889C72B474A6CC1A,C0E24D702296025F,C4346132D2114FAB,2E37515D2EDBF8D0,FDF6E0D1AEFBC9F7,A91D923750613590,2D044E0B69EA6735,820F04761165ED7E,00000002289F9712,8802C3BCCFAEF665,1EB58A3AE40B0C68,BC6A35C09F868C8D,7F4D557CD05F953C,2DD7A77EFBAEEB30,ABC6A0EAA3E7C526,FC8792069979D83C,A291BB4999A4F3DE,2C0038577C25D031,0000000184F5C3A6,A261FCB4330FB958,164F2A8BF11573DA,AD23D427CC289ACB,E87AAD91C97B4DBD,4AA7B65A827E02A9,B3D690BE09C0703E,5B5196771422EBF7,77CAB751769842A5,1BA8093856E41F5A,000000004629A80C,88AB72006EC36CC6,A8F4864CA0F0840D,9F466444293BCD84,83FBAB78A6A458AD,D135C8308CD4E2EA,7B68DF3BAFFB1AA7,5E17D1DD7D2FBAB6,62BB9095954A513F,602EC392B58AD771,00000000ED898C28,3B9BE546C2B16685,69354ABE59F6200A,7BA877E0FEA1F284,95ADE1935AA43995,CC2EDF182658E365,5A5A3C227023BB2A,DE61740CDBFB778A,18F6C79C99444777,1740E0CE6B32A9AE,0000000165CB4180,CBABE41EC5653654,488F46F9F97E6033,24729A313F0285D4,B53D9E33C5E46CF8,632E61FE11E30DDD,CA8FFADBA92A57A0,556FF53E495EAE6C,93C00364777D2A85,13ACEC2582FD418C,0000000167DB1460,0CB8FB197058A896,7161A397AC488261,2DF85B8562B57F30,4D245AE09DD261DD,A705C9F041F5028B,1125746ABC7D28A1,A24AFC0D52CBAD67,50E840E38553A9DE,F3DAEE5AE8A7FD65,00000001566DE404,475FCC48C0B0B46A,6061D2A9E1073A48,1C6F8B48A37D284A,298DD6B7BA1D10EA,365E7CC059DC5038,5EA034A7833DE8F6,C030D82C9B752BEE,26FEC268C59F1B94,BE96342AC35D9B77,00000001DD121764,BF01F6FC72500EE0,75BC04DB238174EA,C4F0FC6EB4DF729D,49598711BC8C5987,F9CCEE0101533689,9176D92AE17DE610,8D9B147DE73DF7B9,A96A136F4409187D,4B0FEC8680943D61,000000024510EEBB,6E7161C8E44E0A51,949B2EE627081DE2,FF5670D750ED221C,E83A26EF056E0CBB,0F1F5C88B5688C8C,2E03DF41CD8FF532,F3751F3521B0F53F,FF5D0634F20E55AC,DE791817A2866581,00000002043C989E,8EB82FBBD0E08A25,99E3055CAC7B0D60,CE08011070789894,790BCCB91B2E8541,64CB4D7CF1AD681B,FD0CAE5CEFA3CC21,36D1A6F1FF7F5519,F473198AF52C2962,772EAB8BFE549A1D,0000000074DDDB86,9703D032E4820FE1,B371BB7F023A4EA8,49F88C0708B1C07B,D8DC383822DECB3B,C07DAB22B24F2A6D,7824B9932865C9D8,4538DA40F8D6812C,82CCD47BA2F921A7,A169952446D67057,000000007AFBC99E,4101F92D6489516F,345A670B69A07168,FD090D5CAA1381E7,0DA80610A7DF86D9,A95E17F473B1A259,2AC34D3CE5A10BA9,3B1A38CFD3C07E07,54DC915CAA197872,D3A87EA9C3DC7431,00000001F95FEC2B,7394BD6A20403D69,6650DF23651BAD26,F3C9E25177FF26A9,72E2A1D15E303EFF,C6562E92DC3ADA22,09D6DC1D6B0723CB,C02C5B795B4C2CE5,CE671C60A2A72F42,1C49F1B624CED687,00000000B4508885,7EB618BE4DAFAAEA,AAA5AC7704722C2A,0819AC981E98DEF9,BE0FC93542DC3B2F,A9378888CC7529F4,5BEA2B416C764911,D8ABAB61AC72DA96,1FD00516FC0E57DA,77555F699F3857E9,00000001F6F2E602,B3F1C029E33AFD3B,757F4C7F74B8633A,21AF9364D003A9C8,6AA1DF293DE11C44,684BE62035492812,49AD67C62793608B,AC03498FB7FF4AA1,BCB815D70E851E5E,7A523D28F7ABED42,00000002282ED008,57EFAB6E45DEE586,B6A4F0005B0DBEDD,38ECDF3B1E5082EB,21D8F08B4D33B04F,1B7D6C7BCE7550C8,E539661421061F8E,06DC027A3305D426,A271E8CD01DCCF08,EB6611F36F58F259,0000000210C6B1AE,E41817A615C80763,1040CCB4C9E8433E,C9C80BC26326FE52,AB57C994B284A2C9,98637D930D82ED58,8DAECA5AFC7892C2,F4BF4A4F30D18A7D,E29DF26AC7563C38,A86F1529D201645C,00000001D32ECEDE,D9CD0DAA7AD02B2B,8A3C6C070C3751DC,85CD209EC4575680,C84B9DDB27D063E7,55C54D86CA49F21C,884003396D9CDE9A,D0FAF4E70E533FA2,926137B2395EEFBA,01E0DB30DAC9DD2F,000000014534567B,D53C49CBABE5F368,20C828A8055F1E4B,10F7D76374CB244A,6E6D26687DE9D5B0,DB14E204288B6D8D,5D1C4864B1D219E5,2E2105E89E702809,6A81A2CCCAEEE225,B864680F5760EF70,000000014402541C,E4A91B1574B18A94,92529A2372AE60D4,54223283077EE483,A556E01A3C1351E2,830999928B83D6C4,3B9FD24A861ED6B3,85A2B849B7F0CF17,B5044F6D19754FBB,928317C2F4E6573C,00000000734061CC,7EB21EB119933603,B2D24F467EFCF82D,41FC91C50C5023FE,576F37486CD53F90,8C82B95E35F27E0E,F4200F0142940999,014BC899B06175EC,598163E34E5E74BC,2BDFC9CB5C48A3BE,0000000228BDA8A5,28250254A4159CD8,3E493276BEE5556E,6F1F9EF19AEC5347,28D60B951D632A96,41E42D2295010191,3502FAA1C97CC8BF,904EE7C7F8EDE34A,8D7D15513C441B42,982B4A610EDEA6B6,00000001B78CCCA1,87166980B42D39E8,39138B033FE33E63,B3658B19D628CA53,F2D0A0C08B806D03,025C343DFE3C2E90,684CBF107DD15D77,DEA4F16B98D8CA7C,00D1C08A28C2179F,F306BAED2F6B9730,000000025C447192,25AE6DADF1D4A9A1,FBF8E732AEF8DE5D,7763021F83A0EF74,0FBA0341321166D6,5F44A9E7F0A597BB,DF6A33A85FD2A2F7,48248802A805EEA5,FA91B765CEEE0286,097108F75AF56A1D,000000013DD46680,D92C750107A81D16,B03583A854C47E9F,701699637BD85293,730D2D5D5C9A9BA3,F3AC09634B67B8C0,A7EA3AA62E337C0D,050F22A5816FC787,8FC92F14A1DC5582,C5C62BF6BBFEAACA,00000000B4C8A7E5,3173489AB7434306,705C58BAFD7680CF,8FE68AB8F97AC161,DA52292C90DD4D62,7F79DE19ABBBA7F4,02631DFD7E62F3B9,93AD5A0C46FDD269,11C54C636D69CB03,709EF35E864BBB19,00000001C579F6F5,0C705770B9CBA58E,9FD12E5FB2A4C0F9,7361877A449550ED,21D2F88E65EE90C4,AB212FEDB56ADADA,008A7C7912D39265,0125CE80BA0DEADC,E81F3BF1CE1B356C,3610BE29ACF5109B,000000018B249FCB,14047E6780EEE7E7,55BCF4415D1C8CA4,929353ADC1F508AF,55B8FD802532F6AC,58FB3F4C150CA594,8C08A8DE09327BF8,87AB99B38FD058C1,F7122183965C7A6A,36195DF6F431B7CE,000000015605D240,22356F579823DF00,EE5502A13FB120A6,42556C37E0CD4F9F,891FC776818CE8F2,C53AAF6CD357140B,D816138FD2519D4E,9FC9DF40937DC9F8,538E7C611EDFFAFE,01BFC1293B5A7982,000000008F753FFB,89A3A4AD16CF1948,04C96B958A172E21,293F10A97B5007FF,9066BF56784AD5CC,BB9EF2D945EBD546,816C76031E1FA4CF,4C149F031CE7FD45,EFD2EA540014672C,EAD07B77FD9FF0F9,00000001D75795BA,CED4E49F98926ADF,D8321D55EBEB719C,6328DBACC862A097,E63B9F1D037A1298,DEEACC6F31270BEA,890E906C938519F1,BFCF5EA327AE4513,A0BF09CB6A0105EC,C119D1BE3EBD8924,0000000083806884,F183A31121A57BB3,F78F57457B9B8173,D5672D9F9DECAEEB,DB0E56789E8C4D94,BB8B7402DF462C4E,2E04FDE14FECCE37,02A2A49E89E7185B,608E06CC14C77FF3,39E193CE1B251C5D,00000001CF955E08,E793C6E28AF58257,736E5D5213824889,7A0788D67FFC8073,1CDA91A0FDF3D5FE,76F29F54BB11064A,7D47B74A30D0FD48,68A892E92ED60544,615F8CB9942D3330,46F22100EDC89414,0000000057833EEA,A1B33B10FB394638,D6CC83DD7FC5DB02,322939345D6F0A9B,444AD131211D4CEF,04C2CE015CCFB76B,F815C4E0583D6CD4,7AD07AEA12411918,0968982537A0DD36,58B19D5B6D274077,0000000164F8CA0A,8C958112DA12A46A,C28FB87948175F57,2332551307684D06,3BBFC4CCA98CD8D7,542B27445EF46230,5B30DC886CD5CCDC,2FC547FD235C8B26,225657B1ABF19C64,6A3B07EC633308AA,000000007B65D9C1,E5BC1C8C5C002ABA,717F85F69A716509,E184FC9DDA313E76,F55CD21FB9554114,2AE4B1FFDAEAD2F6,91E6278A0670C7FF,661C2D1EC7F23C46,B071F84223B33603,89158BC02A03F3A5,00000000551BC4FB,FD4BD65724280F66,BD0389EBFBE6E1E5,8001526AC470EAC1,FAAC69C021F3F8CB,89C7D5B6D25FF030,89C09AA899EBE2CA,B4AB06F4F3AAD077,87A4E9AD35FC0D39,E4A851BCBFB08B0D,000000014B8CE7B8,0423839E27182F01,B13AEA55D33E4A60,31A008290D451282,978CCE09F71076A4,7ECE6B8B087C7ABF,D0067F45A6E9184C,11D0277CF612A4A0,3714257609567E99,7155BDD064E518A8,00000000AB7B8931,A17627E9E2510106,DEEF584D213BC4E4,B4E7F859F7C5FF10,04B0F91BDB7BA5DB,AACE18B53929807C,D142063CC8A76B02,89A8DBF862A3CF62,26E3A7BAE9510907,D31F3CEF95F8A99F,00000001B1D95AB8,540058AB11F46949,AD62B3BD9AEE3E52,D1F050273E2AFBDE,4286CD5866EEA09C,D1E38C11196ABF30,11EA5D7663DBA94B,41896DC74F3D7D1E,F49606A137C7816C,D34615AC28F7F3CD,00000002306B4848,E5789D495BD68782,DCB3A32E1749F701,89057FDF7FEB35AD,62180CA583C5D0F4,15C5111F3EC431BD,E5673417819B9407,1134BB516478C155,2597A560DCEA94BF,438C7AE9FDECF508,00000000D08FA6DF,CCF28895E813EFFD,03ADFA302384B3ED,E8D132A779FF1976,E0EE8E52D309FFAE,B2DF1B4A9485F8D6,0AE7F3F20A180F31,979420C74D775ABC,34C1C53CCC12CBD6,C93CF688948C5AEA,000000026ABB3BBE,65E5912C0FBB9100,8364D895CDB99CF1,03E9835DFE672178,87D99ECFA039B6D9,05F0E57323B964D8,2988EBCA3736D91E,C3B34F7CED96FF44,2383E987AEA1C620,68E3752AC9338652,00000001849D39EC,7F16A8EBC72AE2DD,33FEA25D153BEFA9,E5BEC58042414232,728525EA3650970A,CB3520C391A56CD3,EB09F0086A5DEE92,A56280DCC9924184,E3B74B834D7DAED4,721607E945BDDE22,00000001D05DF059,29DACE6C1F9A5507,A0986A1915EEFBDC,390AAE0863826252,50B0B58C87DD9CE3,3D1CDDB164747790,71158325E3042B2B,0538E2E59F3BAEC1,B4C82ED173E0882D,B6EB02601A0C4A35,0000000052FF2982,511E275DF99FE158,EC5F7EE32AEEE329,9F99D4EAB24B85A1,2C51315D294812B8,39F2FA31D971468A,2737F871899C0A42,FBA0E4F97048973C,E4A3354ACD71416D,2B3EC13DB49ED0C2,000000011DFE2463,1489354E29ACA71B,64554C8B2C3CAC0D,1BA609EA22B9E3F8,B711CC3B2CAFA2CA,2E6F8BA999F38D10,9B8FEE73FFF58972,56A8C99684027E8D,D691477B6B1C1DF5,1052DA5CD4AED6A7,00000000074FFE6D,7D999437539F3477,689870747A5314A2,F9017B544B93EC97,CFDEAAADCDE56BB3,BE8ECFD76AEFD73F,F37287304C76A31D,F05DA109A1ED4ADD,551CAC69CF3E97B9,CF84A01B7E42A498,0000000063401D83,887880B1F906C67F,DF28F0FB1958831F,45E21E53B082A247,B3304072FE32C9D8,E11B3E42A020F11A,27DE7621088936DC,E94F10F8AB5130C4,7A0A893F9C05DFA4,96E2442C2A51328C,00000001105C0243,AC283553FC86E1C3,3E115058AF6ADFBD,08D6BFB55852E0B5,965EDEDE89E07B77,691F94271196DE4E,A75047B77F3F9DE5,20DF2343E029C0F5,110CF1F45EA6C529,A0F217AAD7F4C003,0000000156DDDA00,E24B04100951947B,AF28027375A27A81,9E38C62575C604FF,4F810EC37F5C0D57,AE4F6739E7F9EC55,A725E3C2154D9591,343BD28446597D47,100A94A1D7A101A8,6207B9EE7FB863B0,00000001EB990C0A,A39FC4571BADCFB3,E634A0AB43AC5F65,CCD779033A40A9F8,900D03201B38CF3A,FD10B9E70E79E543,3BE8037FF23E14E9,6CADB23584427922,80B08E5607D2D9A7,FB6F0AE3390F8076,000000009293B944,A011760421220DEA,AC6EB9665EA3A901,9DE6E340BF837563,32987E5F48F01448,1182BC823098F092,7EC0E13214CD5175,08C68C30C8ADB2AB,27EDE1A525C42C91,1465FA1213A3E39A,00000001A3E6CF01,25F305823D651B93,8EB7013F4B28B789,AE4A4A887F53E04A,BF5EE4E91873689D,93E403489D00A42F,EB1C4AEC0D66A894,8DC10F1B2CE53995,FF7EE318AA38C132,CBE83FE765DC2BCF,00000000F35556EB,9AA0BC760D2784D3,1697982249ABF9F5,EE5AA0E2EF313F60,9008BDBDE6AC5E4B,54C698963FDA3FC5,FCF4F87AE99D617B,07EBC9FB1A8DC317,F2800E46FE3C92C4,177A76443F1EB15F,0000000071771A52,07D38F05F3021954,BA90E8FBD6DCA6AE,6B867A0D0DF28EDC,F8796BB055382117,C5F5C632C1CFF221,103DA6C85E60B860,47A5F0724E0F8EF5,8B097CD00092B608,0A5FE84CE38629A8,000000019599F9EC,33BA0FE43278D781,A5BC94F6EDCDA3A5,7B73E3CF06A82CCC,A11F6586064052D2,2D6035D8AF7D1935,98BB4071862AF6A2,F3DB762405DC7BA7,238BAF11078A3B42,1A4BC64D1183CF26,0000000045254AAA,CFC35A1BA1B4BEBB,914D0D03C199EC59,21BE4E3413A2F0A5,C850770C101FBB9E,2A8EDE5160C6FCCD,E5FB0541CF0E8D45,43E4C6A53D8CFA03,87276DDF6CE6E5DE,6DBAC12853027E49,00000000BBB8162E,0D8D16A50FFB9988,4A966B78491A0D72,BEB2570AD5CB6528,74F9099640AAD08B,CC31B868D167FF20,F14C362C8C430621,F12540913A29ABE3,A902A7E38C04E3AB,B0F7609CED056B0A,00000000E03E8758,D6163DA51142EC84,8C3AE153B58FC1C7,C053E8FCC869E9C8,1FF2E2508CBB7AC6,84DB4E0C31F51201,E17C3DA65596303B,1770F7A548B7A390,B5385CE99A734E8C,4BFBFA4592A2000F,000000004431BDD9,AA7610EBDB4CB2DB,DE732F29A927AB21,2B4EC5C103C216D1,685C79532F25D79B,EAD2DBF2F6D9FF09,99738A16C81A4D01,68E9FB013E9716FA,F928032E38BC91EF,7AFC4CC2662103F3,0000000195EF9060,64574DB00C1BD0DE,7A114088FBCD0260,90FD95DB84AE375F,09F1BD595804EFAC,7C0E9682A44A4CF3,9BCB3C1660C8E858,3B4564FF01CB5871,ADBF1BD25F6C4E5F,09EC6A9B5285ED0F,000000001A4C2201,B22531E5095B7D6F,4997D0FC2FCDC4DC,23D3D6035055049A,F831593D77B8AF25,6F54AFC4129DC6FB,2183DC897E5AFA44,9DA2257F3B1F90F3,4814EC271312BE26,79C5EE1EBD6D4D0A,00000000F13F3D03,9C5647451368AE9F,EDFD32DBBECE3325,EAE60C608EB97A4D,95FEDC899B893489,A43B2069003B3B3E,7828E047901F68C3,546C137BA14D1B9F,A53B5C8213E9BA21,C572DE64A1FE2B22,0000000054A27101,4D0C6CBBFC39D259,FB0A326BD71616C9,7CAEF7AC0E8B119E,7EA3CA3873D97392,F9A12A3F832C4128,6D921F26705F596B,1CED6A6684ACBC48,736FF33FF106E9C9,A66B52393A828B03,0000000109F80D9E,5904C1299BB59792,FB628E7D61784F93,0E76AFFB2C8ECB13,0A25C9537BC527D1,7A267C591C73CD7D,6E279443C74CAA72,3CB847899D95895C,E2D894C49370CEE5,534C406ACC74D04B,00000001BE3A2B37,D9717D8447D79070,E7C9A0D111F44EF0,8EC6449F9D29EECC,590A32D684E43DAB,3FD2DB3D7A1CA08C,2E36DBA5288B7488,30805B96AB2DAB6E,9CF9AF3326E6AE5B,BEB6845FF87A6ED0,000000001E7C793B,5518CD555637AE67,6207424806EFDB0C,17130609D550270A,CF04E0152595998C,22E5FB467B00EE24,3AC121FD285128DB,072DDF08F657DC31,019DFDA4CE9E6DEA,5F349E6832FFC918,000000022305D864,636A73AC2FBCB9C9,6AEC8BB4E03CB3D2,472F487344E86265,2B1D660992AF9FF4,2B19A9AF4B0AECCB,7AB2FF78599757CF,C9A59CADBCAB9E75,5BDEE54523A31AAC,42DB8E3B0D4FECB9,0000000136811BB2,20C1BFD4EA52DF71,0F4D108F5BF5FDF5,C4EF83208C1A36C8,3839DFA2789C29C9,9CEA0A8A9FD9BC09,A4D2689309C9E2B5,657BD0A621EB3ACF,061AD14D0B5B0A9D,0FB65927EBE0E90B,00000001A4AB4992,DB7A82740F2B5B36,060C57F6B9662C80,C609360F4E9A97C0,A8B71B5E37F413C6,5E46C372BAD07B20,5E90CFF40B498DDD,84FFB0D3D49B0EA6,AF17769AD7238815,F5145EAC884120B6,00000000DE0462B9,D140BED5943B188A,D5408EEE6E9406B3,7F2AAEA688A4B2AC,27075A44BEB20431,BB9BC132BDF07B43,F919407AAC08BBE0,064D2548F2A0A0FC,53C1D401E2C86EFB,148E68B566E1D284,000000022915DFCD,79F90922C1861911,F00AA50E55F19E95,AD10285D746F51D2,966A28EF1ACDC266,32A49CD876377477,614721FDD60E7DA5,E9226A15590DF1F5,D9AF27930747DFF0,2D2441288DE75F78,000000002A901830,76C67CADBCF9180F,BCD6B08EE68D9040,F9A53EA8024976E6,9F18924CF344AFB9,ABBCCA385D57C435,B66F9B4B45BF08C4,5237EEA01ABE1898,5B5A86676B9E7B40,0FB6D6ADC69E607D,000000006D6753A5,7D6A54D414E2A079,B97163E10808A5DD,B326B7F981211D6A,79E91E21DF8FBB36,078DC733C5063AD2,8E5E959002EB6344,2938B4537B36DCD1,1399177FEE47354D,8E8B05EAED3098B2,00000001EE1F58B7,AA4F3CD3571CCD4B,8027D73E4F5601D1,7CCE9A03B388D658,77AFE4DA489BB199,6DFEEB3EFC73C767,A453101B9D13C9F4,FCFAE3CCCABA255F,5FB562A9ACC64DD5,050F6DFD611D4A0F,00000000B5A77902,503AB5E618D6A33F,B30659E90F333CF9,6F9F39A545727E60,89A2E18A3EAE4548,B354A7C22F66B170,3D80AE613B6A4428,12D98F4DEF5BB036,893EA0151278CB80,E195A4FD1D516978,000000000EEF4046,A42850ECD4676D3F,DB67F5008A9C66C4,AD24680D042D842B,EB476C5578BF15C0,9A8D87A766272820,4811F9050FB0A2F9,225400D12D6D0633,8C81679987A27A14,AF34B6DDD49494A5,00000000D4F48F9C,78D8EE628E1D0781,93FAD86B10B03730,2B86BF010B2B4E58,9FE817F359757A82,ED474F00EB747293,C90ACD37B187ED5C,CB0DC0B61885D3C3,59515BEB8775C0DE,F3774A24BDE52538,000000021AD8308E,74252F2E8D942F2F,BEFDC44274DD6230,4074459438372045,2570EDD0DCB355B5,5F9B915374A94036,1CD5F3F593026EEF,9E38E58201E8B3B7,98193312EDCBC420,B9D3A90717F9949B,0000000047651BA0,A5BD806B9D899643,647F94C218087288,32BE3150D808922E,0A45CC5138B87D17,0A3D6EA2633D820A,2BF4D070E3427B7B,96E5EDB3DF29B605,4F5E19A9EA294213,F166743C1FBF0A77,000000001F550105,D52E8BC72AD405EE,EEE71140D9246955,0435B6DC239BC273,8B127D10C87ED339,B6895A7CDCF0C25D,4C47015063309790,C02B69F256FB71C1,2E27F109895BF6EC,F0EE9060EF98782C,00000001592CD865,EC12454829C30E92,EBD921C2D3D30B6D,0DAEF1560E4792F8,6007E43D518A94DB,BBBC3D62FF9FF956,64553EC2FDA0E094,8FCA5CA31B31198C,3D2A788A4A22CC0B,EFFE9C64B5F17E32,0000000165ACBAA6,99AD0B8488D427C9,687671313CB07610,6C8042908D907C41,6E602F5F556B8F2E,2FF44BCE2274644D,8C994A5F38C601A6,E8C9E9307EB9088E,A8FBE3CE4D5D617D,4C800BF0E7A05028,0000000215220E03,56B84172EE23C99D,F845CAFC3E31A5ED,385412F94A0CB66B,7500B7D741BAD8CE,70C0D8ECF0C6C049,D4C8A5EEFE2DA13C,7964699A49175605,C253B62915DD0556,1467A315E117EB39,0000000087C22FDC,08CFDCA63F414DA1,CE539C159FC7E9B4,D4426BB0ADF64D0E,7E2426422FEE145A,4B6B9976917777C9,6BDADB4577B3BBCD,68DC602B4788F24B,7B55B9A2324B5867,ED0B692E812AD73D,000000019CDCD934,6078B938C320642C,2BEFA5BCEFE8B8D0,145539576CE240A5,FB86ED9720168534,FBA3A42FC3B755FD,11952B09B16FC2FD,A238802B097593BC,6E04E8E3777DC194,B92DAC8A77B79B07,00000000C30CA665,67AF404E936271BD,2733568A145098E3,E3E2D56040B2CE0A,6AA5183B6926C0A3,B7E23B1CB75C02E4,BCEBD990EC0F6507,CDA28589374072EC,A3BBF509C77F6D5E,697A8EB3F1270546,00000000544EB789,516FA6150AABA53D,30DBA2CEB1FD6C96,83A60108A10C3544,66C5566B32A4049C,60F4B3E7B0FE4FA8,5F57F77A25B3D3DF,DCD3EF1ECF6C3991,8712AF5F46ABC314,B70EF2F4BCA6A98E,00000000AEAE2498,43E4F69E16D9D1B9,3E3C7D067D22E2B9,996331D083CEA8A6,63137B93E5DEFC7E,0F2F0045C2FD280A,0F9379B99D8B4EE0,BA8EBF4B7B9BE4E5,A740B7911609145A,1B91F3E59319D6BD,000000019C3A8EF0,91E76E9396C049F0,6866981B276C12AB,BD863AE8CF916168,81518814A59F0DDB,9B13D8543EEE3D96,3EF1818FB338B464,C417CB60CEEEBAAE,5FEA8EACC7D4070F,24D06DBB16D4FD6B,00000001B651D24F,5009B93A2C23246E,B080C0CCA10CA021,F3B596AF8A9849E7,694DE738E0FE6AF2,2CDE5AF2B46A1A7F,3340B8E621FD8017,9774DEDECD3AE3CB,F704975D56132A6A,EE032F4DE67DD0A5,000000002CD408DB,21F99859F37E5FF4,8D2DCA5022CE25EF,D550BFF86AA48E7F,928AD8DEC2325A81,1E1D936D45E95310,953F78CCD211DE05,E0A977B48CDC4942,1CCDC2E685389D4F,2D5F0053247850D4,000000025320517B,C57CF39E2E44EAC8,AA2C222D59B58563,7AA339FCAFB4E65F,23B6ADC1B35F3CDB,2ECF06B0103A4BC0,8CCC80B33AE26BF4,E91FACEFD1D12CC3,6588CD9FAD7F36D4,B16A46A3AD08FD94,0000000254093CAD,07BC77C65834759C,60C020D9C1009076,D8FE70AA14D8969F,796253A67BF2C286,194AE951F6D5A9CC,E3F0FC9E703DFDB2,A179483F795D65DA,98A03AA1A90611D3,6C67B1DD736A287C,00000001930CDCB9,B1A58622E85878FA,492552FE93A0628B,375D8B89553914EF,C678BA186678ADC7,05309484181EA542,154957F79118E597,907F0111330511CE,55DBD0C0F41E7EFB,72458FDB21135596,00000001AAC347E6,97649D2CBC19BA0A,3C8ADC7E664FEDEE,5E4D789E5EBA76D6,1BBCDF78E65E59DC,5D366D9C558A4099,41D738D78302279E,8564F964F4FAE07E,3C89277609339FB7,924A6634EDF79A8D,00000001F2113AC2,08B47DD1AE9ED4C7,475E7EFE38A5A75E,8310F15D24A44C91,136AF714A9D08026,C06EBDB1BBCFD8ED,0CCB537FF1CD7C97,CBC01E3E2DC0BF22,53D5208FAD076076,2799A9ECE8E3252A,000000014A9894BD,D964BA48903293F6,3E11D374BF34065D,7BD26FC66A799415,38907CD2FD4A4635,1DB81E4A69842745,F3CF8BED0BA18E97,FB1A1EFE1A064A09,E7EA1671AB6A434D,F22284B016791BDE,000000000CB81C41,2A745176015A9E35,F9C6AA403ABF3838,DC3AAA0F819AED15,8A4E0D22340978D1,7869379B6D0171AC,FD74913B79291599,0077E45E3D259990,9E8665C724712BAA,12171D58AE7D2111,00000001CDF231DC,F77AFD68796268A7,F0452CEC7D872CBA,6215C481633C5347,163AC4CBC22F1FED,5542605479070B58,9E26EB987DD2A2BF,1F49657637FBF483,0F0190246896E8C8,DA4212C548EEFD6B,000000017C4A066F,862434B5F15C05A5,5E44CC7F2C50728F,96C1774A1DCE7545,99A3B52D2A2A8089,343A0033CB7B83FA,94077D938DD37A12,13515F4426F1A77A,CD897536C6D97152,A33A697983D33667,000000004D954C93,98B0641FA9CA4FED,F05BAD8FF7961C68,64CD17CDF86466A2,A60EE7DD8D89F90F,AAD4E73B80C9D645,3D01EF11415D1E85,F63998F907DD45D2,FB82CD877675F5D4,191728634ABCCF73,00000001986A0DF8,4E75EDFFD411324E,28FE36B79FE3DD1E,FEFB8009C9F4BB33,BF9442F03DAD5253,F075DF53549C6514,29C07BB4492B35FC,A0572F0AD866B4A8,B234804917186BA5,BBDA6A47B1824278,00000001D62C45FC,7377B1AB1D3D25E1,C1B9A07E536CE163,588CEEC40E9744D5,E85E471AE8ED5F26,65915C40DFF2D332,0A8FB01FCAEBDF2F,3EFCF44052E8E65B,35928DC481762C24,B3E99E0C90439666,0000000025854C76,D63AB3F75134F3E8,9CC4D8EB3E802C54,82FBFAA5D61DF95D,54A6E1F3D5A2AD93,7592AB057E84EAB5,CE4CCF9C96765E6C,C62D3EEBF39F5E96,ED6A9237C79E5F9A,7A5E3F1215564156,00000001AB074AFD,6B947575870030F0,62003AACD60FA1C7,42033AC482D35427,69D59209A959BBD6,20D0D4EF4BF11A06,36B5B4F0D9AA95E2,BB8DC096EFBD0A05,9530004EA1E64766,99B72B751D5B7AAC,00000000B39E5A05,E87BBEF246B087FE,EB7F3729453F4CA7,05C387F065A3B9D3,8778426F48E00811,1D1EAC61C906F5F5,BD270367B8AB06E9,EF68993ED09E1E68,ADEE35B4723CA496,F000F8058EE9EEEE,00000000C8D5FA2A,57B360FCFE088D15,9FA06B380745C1CA,C75955B3300752B3,71F3E10544E8E5C4,EED37C4086C0ACBD,8DD61352E42852AC,75B4724AAA7C2A01,0D3FEDE0473BE7EC,8ECC4BC9F35B7346,00000000AED5E334,1685FD77752EA45B,CA956B69F0FE7133,CFE8442D845B00DA,D97F453E9127C527,66DC16BA3A625701,EC169083F8287DCB,18E85DF28F1E93E1,6DC34A891CC47139,6AC57EFB4145FEC2,00000001DB3026A4,777197439B6581BD,DFE8F840EA5177AE,45E4C6B86BD5607D,7120B841E64B326E,735F863FC71DA6FE,07451785081E9DA3,7548B445B99BE3B0,7A85881FA02DA89E,2E4569D6948C99CD,00000002434BA471,9A5D0EF1AB3DA80B,D0E4DC55B73848D3,DB270221B9E9A342,42FEC8EBC146D26B,816F5095B9D91F61,06007AB042E3A8B8,0FE03864A85BD325,0ACE3AD2F96F99BD,C3E9988EA8DEE99D,000000004A9CCADC,857539CF2D220344,5CCDA95D4D3DD7A3,A636D90F37DFED8B,F71B7D56C5A175E0,7DDCCDD1AAFB2949,4DE5C065FB6320EA,41C4283A78AB2A76,7A813156DBBF46B2,93ACBE054EEFE49D,00000001D6CEE5F4,0DDA26178C932A61,BF2EE08A2B3444C7,0455AC7BEEC31A77,B50467D1D6C9F0F0,9C168DF6132A1613,19196B7AEDE00323,E01C68057043EC50,F96E670799769CFC,F5B3B55D4C675C9C,0000000160A5A9F3,EA86CAFB4A3FBE18,B980854171671552,483EA8D2F9C5752A,2A5168E5885513C2,8BEBBB131C48E666,4A44DF3E9A9AD283,7F733F4AB61A872A,60544111E9F6A1DE,39941DEE703C8C82,000000016C3520F1,1659B036601847D4,B2657C6F0CBB8BFD,280E733057ED48E4,63979BF5D316850F,C0AC68F1899FF5C0,7C0A3B5D0FDB5C99,DC16F4B8DE0A6361,6F8B7930D53E4AE9,1AA9C07319AB8098,00000002271C562D,49845112334A85CB,6E7381752B8F0248,C88B513C6792F168,18E4E69C8FB22614,5A32E78DD064DAF3,5A93E354BB9AC010,9B8CC20C31B94729,A99ED1FB025E049C,C3A66B0A24501FE0,00000000D7624B69,B189384AAD129039,BD4DBBC03E7E4BD1,A8B8B48E39998EEB,D5CC61B00808D0FD,C06DAC5089133B54,5D7D769D4E210C48,B4B07A85F1DF79C0,267BFDC8BDAA5503,DB1E1CCA52B72B56,0000000105BA3403,1BC8C758B1383BD4,ECCF2DAC274B569D,5FC2560F115ED43E,DED1C55D3955F428,D9BF23F34BAF363B,5A737A0ED5C76FC7,B01C49F57BFAD064,6F022E56A0C853CC,B577A6EF2FC5C008,00000001E5771090,676FEBFE2611EA08,88C0B6E60E4E6740,060C98EA148E8B60,4C31E025B87F6BE1,58D6EEAFF02B152D,6DE7469B10448A11,2512C264095DA510,8695E9754F1B7DE5,55109A5AC001A680,0000000214010052,7250C70EB9F9EB9F,366BA1D218CD5507,7115271D604F876B,1B1F7A4E5CBCBF97,FC0E5C36D71DB65B,2CB8EFE0935DEC1A,7A4358EAA02FB27E,88F6129FA7DAAB7C,14D2D0F47AF3B108,000000001FDD7C89,728A6F9311445B5B,EF164296B4C3944C,97308AFBA0F517F4,14E48762D499B063,BDF527ED3C59DCF7,6AFFA14131BCA419,58F3F5C5B67321E3,997087F1F6305DA1,5FE8882EEE5E4E85,00000001EA07000D,A81F4264B8C431F2,16CB8FDDB8F9A18C,8FAAAE1A3F9BF5D9,DE374BA29035E2A9,3077567F9F167689,896F823042203A77,4AF0A802E8F95D4E,59305A5E999CA36E,BC75198275A00472,00000000C36AFE0F,4572C10335365ADB,CBE4E99D6987F05F,7523B4C5714E087B,D1EADD71462B9C75,BB64749FC15E99B0,35C79373055B61B9,F3C99169B7D882B6,A6B606F4BF29FE93,31353099093AC276,0000000158BE19CB,B00DA81535E65A63,4DE17395F0AF246E,AD83B30064CD9C30,349D950A95DCD5B5,369E30A222BB4C46,91F4FEC17C055847,04710868FA10818D,595BA07D9ED97AF2,60EF220F8F691483,00000000F41D1999,9910CFAAC0AC0706,0AA4CE99302B1C12,8AAFB68D00F36D3E,FF8ECE74E9792E3E,17D83878227144EB,FA1B87D494BA0586,E6416226C48385A9,1D16FF71AE3D1D51,AA08EB9D9A83D6ED,000000027336107E,3CA97877DD568078,29976C768848237C,A19302D3E99DE276,1BF778EEE112F732,DCF266D5C3D497A1,FE5B277AB075725C,B71399471B70A24D,BEB257EA2C3996E5,6D4BD886282062B1,00000001E4937588,0453D4810465D337,1D44D3D67BB884AC,A63D1374A8B82012,0AC3B1D1C187CE24,9FC4269E220D2378,FD88D6F0F884D779,44C8CF04CEBC685B,7F63E149DD47F4AB,79417578F8A58704,000000027532C69C,DB56A03431A10543,F056A2363358FD8D,0EC58EA64B8182E4,569A8E56063E6637,B4CB1BCFA1AAFEAF,41340625F5494975,2BFEE9BF5D6DAC5B,658949C5635677AC,557838D9C8D824A0,000000018DD91000,8DDD5CFC7D3A8743,766D50F7DA847402,51D3BEBFC1F1E6D0,1280E12584059588,48C06002DA8CC1DB,2DFDDE77294EDFBF,B44724D5CA203FCA,194E2C3317D2AF77,9FCD8CED7F4BFDE0,0000000067944468,910FB500F86AA0D4,1542852032052453,81F9E4B7C11948EF,F1518786222C9E39,012560A6BD70A4EE,E5C67149E238E793,5231009DDF3146A9,A24D94F2DD0D9E63,F7ABED99538961FD,00000000F0076F14,3E09C4CA7356358C,9EA0C6A0116A920A,28602CE919BC21E3,A929E2DC06795F09,4F73ABC4181C6D92,CC5876A3822A197B,EC113EF39EDDF516,EB193C865066AE63,11581249B7F05C82,000000023DB5AA4E,124A684F065F625F,7C9BA69F007BA5CC,EB92A19EB3021892,BA82CE17F06FA5FB,D33AC2939C743B28,9BA1670E31078B51,6AE1FE746CFB7AEC,29E82A84D1A465E4,29060BECAC65DEA5,0000000191D82E81,67133CFA3EF01A21,B6A336726EDA4118,7D80CDEB591C5269,BD238E18892041E3,3F75C4271DB0854C,DF0AF4E9291325D1,C47736FFFE9101F7,466CABD92371FD65,5BA2146E9DB03837,000000010C7212D9,4BA5D5C0A63367BB,64F80563258AF88F,73BCFA58E4EDD1E5,0F3D3CCE820222F6,C706F21FD7985756,B1B911A65D1EB74D,34DD06CA8B253618,E6BCEE173F8FFA70,91073DBF212CB146,0000000023F90379,96B4495C96F4DEC2,092EBA297BC0F787,10D75792321F57D0,A1F673F35CC8EB5F,921D906B70C94DA0,4A6EE23D81F7EB49,4D68B8DF26ABF53B,EEAD3D5A2DED784A,F57FAB695489C7BB,000000021C085EA8,2ABDF46803289D86,A8E72F1955626F28,8967BECDBEDE0E5B,054F4123B14424C2,67B40F2F26CFC379,783A424C1358742A,794EEA83253D09F4,DE8302B2BF4A924E,D7D0A44C09582AAF,0000000195357955,F1B537C34F23E186,5AB4E75F7EE81C1B,F285AD9D3530497F,BBFFF88FC4D1ABD9,C0BC11A7B4AAFB56,B1379325374BE744,0F80F4180B9557FC,63D937AE7AC500F3,F48B3CB6357073EA,00000000A6F48D79,8EB0A07C76A6A1D9,D06696CC3F840A74,C36F043A1FC613EF,294755B1DD46A498,630E0D9EC01A0FAE,85CE3B6B6EF829D4,A141674500825B8B,604C43992FDC65D5,9F26B41E7D34A4D3,000000011A24A613,85FA6D33B4F9BFC1,284908208A3BA3F8,377A5B81DBF44539,5EAB34C9EF85BAB4,38416BDD7BC72CF3,B9B4A7CAEDB9DEC0,7836D3AD26F071D7,6C3BBEC4372D6D99,C3542B200E843C3B,00000001B81B57A8,7094BCC73C1652B5,ABC5945E09E5B0F4,ECFDFAF3A0047070,25E80EE39B96D147,0B979F374ECE6C56,5A2DBF0AB35F1918,625A2FB2D2A3DF3E,61B40F4D559E16E9,415B4D6A3C929A06,0000000218D258AA,E07C530656B8D819,27E162805EB6466C,7E0B487C8D2C24FE,78D8BCE2E6C0193F,BAC689CF78B07822,6A7554334A90F132,96A9F3D1B66EAF98,42BBD147886E2C85,3AF4EC7431870CA8,00000000A529DC5B,368F4FE69ABD7456,B12027B85931956C,0F6214FCCA8E989B,80BE0E4F1B4A6FDE,EEEB23FF494EED45,1EB422855BF674D7,99CFBEFBF74A6798,8C145E5E80ED884A,F1B34826373E7D93,00000000BC3987F3,96713784AA2830DD,4CBD9B3B672F50F6,5A8E686465D277B8,87494A453AB6D370,2DD3E5835276FF83,CC29A317F1B580AA,2B32A81259E10A62,468A12E92FF0AA4F,76719B1EF7E95797,00000001C6577AA3,3867A4EF616A85C9,5220ED31BDAE9DE1,954CF67F6A63D9E5,A5296089BC416604,0C491E06F7D227A0,401B12665F2951E0,F122D7520A8F4620,2A061D50F42C671B,0613182E20EDB938,00000001599FDFC3,84626E5276AF5310,B6C4257F81141FD8,63D8E14233A04EA3,5BF1FD616E0CE889,81DAE7B4C0923CE7,DF1BB83A7AD6C512,6FF73356F15E48C1,F1F6848069FB1DC8,4F186B2AA4E0F352,00000001AE9C9A09,05125F0B53449028,15E39F5B1D740F28,3100DA7CA5CCAE6D,949DC5AECC991450,1A9448B61E407B07,A33BF19F429F48EF,E1659E5B4CC5837B,097D6E04F7AC640B,9BDCDA3FEAB5C08B,00000000C86DA1B8,EF6504D05C86EFAC,4FA4A676813301F8,EC46ED611A74D0C0,951640C7ED0094FF,D9BCC8D9FBEF1EFD,9320A2FFFC9C04C3,24D40B5D598D1939,31DAB1686547F538,EDCBD62CD326D25A,00000000DD64BA85,E9862C5119DFF1E7,AF97AD5F0E7A1907,D7DD50183125095E,3F44DA450F117011,F94CD0EB56CFD9AF,ABCD01589BFABD2D,27731BE9F852637F,5956994FFFBDAE2D,A414C03BDEC2AAC6,000000011B0B8360,F2F8F5B499E64AC6,832A15C6069B2B91,F797DFB661EE87D1,00A11AF1AEF484AD,EDA42010A021C449,F93DB64723686963,6751CB2FA70875BC,43132B1C80B67AC3,9B4B243FA666F7D0,00000000323E62B9,A0F896E0A8F5F891,D0D6227C27250BE5,EEFEF5AC5190D9EE,5F1D1955E37E17A4,C68B9B133134C106,583846BFEF02F022,F9A36AFBBDCD3ED8,AB4EDA2E9E71CD61,AFC6D01EE592C9D1,00000001BA188040,6BD954CA55EEABE4,86271714EB2B5502,66E0BE067A1F6866,EFF51D69878AA021,AAB2AA55B7712426,EB7F46FB7530FB2E,A9F9C43216E77869,0CEFACFBB6EAF1CF,11B07D2D08796D90,000000008556071F,203FD5606B2CFEFE,F939E8B78A9CC23F,10CB04495DC18B50,7246DD7563D4469E,59E864683C1FEA56,89DC24C39A5802C6,0DAE1BE135815439,4159163E3C1E30CA,13130C6B64E83C8F,00000001CAF4737B,BE637E8791DF8BE2,DDAD13B5407410D4,460F51C020DD96D6,F0CD28EB1E23973C,40B5DDEDA66F7559,118857E99A78BE63,0E350EB857FCB18A,F16C8B58ECDEF4A9,ED99D9277BEF6393,00000001A4C91547,BE637E8791DF8BE2,DDAD13B5407410D4,460F51C020DD96D6,F0CD28EB1E23973C,40B5DDEDA66F7559,118857E99A78BE63,0E350EB857FCB18A,F16C8B58ECDEF4A9,ED99D9277BEF6393,00000001A4C91547,203FD5606B2CFEFE,F939E8B78A9CC23F,10CB04495DC18B50,7246DD7563D4469E,59E864683C1FEA56,89DC24C39A5802C6,0DAE1BE135815439,4159163E3C1E30CA,13130C6B64E83C8F,00000001CAF4737B,6BD954CA55EEABE4,86271714EB2B5502,66E0BE067A1F6866,EFF51D69878AA021,AAB2AA55B7712426,EB7F46FB7530FB2E,A9F9C43216E77869,0CEFACFBB6EAF1CF,11B07D2D08796D90,000000008556071F,A0F896E0A8F5F891,D0D6227C27250BE5,EEFEF5AC5190D9EE,5F1D1955E37E17A4,C68B9B133134C106,583846BFEF02F022,F9A36AFBBDCD3ED8,AB4EDA2E9E71CD61,AFC6D01EE592C9D1,00000001BA188040,F2F8F5B499E64AC6,832A15C6069B2B91,F797DFB661EE87D1,00A11AF1AEF484AD,EDA42010A021C449,F93DB64723686963,6751CB2FA70875BC,43132B1C80B67AC3,9B4B243FA666F7D0,00000000323E62B9,E9862C5119DFF1E7,AF97AD5F0E7A1907,D7DD50183125095E,3F44DA450F117011,F94CD0EB56CFD9AF,ABCD01589BFABD2D,27731BE9F852637F,5956994FFFBDAE2D,A414C03BDEC2AAC6,000000011B0B8360,EF6504D05C86EFAC,4FA4A676813301F8,EC46ED611A74D0C0,951640C7ED0094FF,D9BCC8D9FBEF1EFD,9320A2FFFC9C04C3,24D40B5D598D1939,31DAB1686547F538,EDCBD62CD326D25A,00000000DD64BA85,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,00000000670CC8E6,0000000000000000,0000000000000000,0000000000000000,9A34000000000000,4D99C2BD28717A3F,0A4A1839A323D41C,D2B62215D06AD1E2,1369026E862CAF3D,000000010894E964,1679D3AEE6200E18,506852A0F185E6F8,2822AFE7CEDAF6A1,C0BB25BAF0EE8FEE,74B52F14A9302650,05AB4C900E5FF300,7374A35B0C3D962C,58FF19AA110676FD,DD7B508673252DC6,0000000160EB2407,EF6504D05C86EFAC,4FA4A676813301F8,EC46ED611A74D0C0,951640C7ED0094FF,D9BCC8D9FBEF1EFD,9320A2FFFC9C04C3,24D40B5D598D1939,31DAB1686547F538,EDCBD62CD326D25A,00000000DD64BA85,5F07691F570A076E,2F29DD83D8DAF41A,11010A53AE6F2611,A0E2E6AA1C81E85B,A77664ECCECB3EF9,59400728BB57C00B,A144544946C2BAD3,0706D8CB725257C8,D1C940A36C550EBB,00000000C1DE2727,F2F8F5B499E64AC6,832A15C6069B2B91,F797DFB661EE87D1,00A11AF1AEF484AD,EDA42010A021C449,F93DB64723686963,6751CB2FA70875BC,43132B1C80B67AC3,9B4B243FA666F7D0,00000000323E62B9,DFC02A9F94D30101,06C6174875633DC0,EF34FBB6A23E74AF,8DB9228A9C2BB961,14199B97C3E015A9,279C29251002AD68,8D39A363CF0EA572,70FC9CBBD4A5F460,6E7D0456ECFF9BFD,00000000B10233ED,6BD954CA55EEABE4,86271714EB2B5502,66E0BE067A1F6866,EFF51D69878AA021,AAB2AA55B7712426,EB7F46FB7530FB2E,A9F9C43216E77869,0CEFACFBB6EAF1CF,11B07D2D08796D90,000000008556071F,419C81786E20741D,2252EC4ABF8BEF2B,B9F0AE3FDF226929,0F32D714E1DC68C3,2D4C221259908AA6,9FEFF5FF0FE1F1CB,8CB2B08CAC934821,C0E927A123E53081,93F6379AD5F874F8,00000000D72D9220,BE637E8791DF8BE2,DDAD13B5407410D4,460F51C020DD96D6,F0CD28EB1E23973C,40B5DDEDA66F7559,118857E99A78BE63,0E350EB857FCB18A,F16C8B58ECDEF4A9,ED99D9277BEF6393,00000001A4C91547,9426AB35AA11541B,79D8E8EB14D4AAFD,991F41F985E09799,100AE29678755FDE,C34F55AA488EDBD9,C5F906ED3529B4FF,F0EDFB12EDA88141,A56605FE59D9335A,6FDF9395496E6AFC,00000001F6A0A049,203FD5606B2CFEFE,F939E8B78A9CC23F,10CB04495DC18B50,7246DD7563D4469E,59E864683C1FEA56,89DC24C39A5802C6,0DAE1BE135815439,4159163E3C1E30CA,13130C6B64E83C8F,00000001CAF4737B,0D070A4B6619B539,7CD5EA39F964D46E,086820499E11782E,FF5EE50E510B7B52,805DDFEF5FDE3BB6,B83A97A186F246CA,3395F4155D8783EE,6F4287DD900DAA67,E644EC82AB80E0BC,0000000249B844AE,A0F896E0A8F5F891,D0D6227C27250BE5,EEFEF5AC5190D9EE,5F1D1955E37E17A4,C68B9B133134C106,583846BFEF02F022,F9A36AFBBDCD3ED8,AB4EDA2E9E71CD61,AFC6D01EE592C9D1,00000001BA188040,109AFB2FA3791053,B05B59897ECCFE07,13B9129EE58B2F3F,6AE9BF3812FF6B00,944537260410E102,1E57AAE8ADBEAB6A,7613B3E7AB02E072,807B0191AB7C2FF2,93C43A957EC10632,000000019E91ECE2,E9862C5119DFF1E7,AF97AD5F0E7A1907,D7DD50183125095E,3F44DA450F117011,F94CD0EB56CFD9AF,ABCD01589BFABD2D,27731BE9F852637F,5956994FFFBDAE2D,A414C03BDEC2AAC6,000000011B0B8360,FFFFFFFF98F33719,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,D3CDFFFFFFFFFFFF,63DE8B2B81E935EE,909DA70B616C258F,DF9F90E440595348,6E270E53CBBB294E,000000017361BE04,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000 -ph3_T = EFE0B1246E1B15D8,CE5E59D2C6A938B7,9421DA239FF6D260,96F33702CD2DAAC5,045CC46BDE3A5FCE,E855F2AEFA620E36,96D60B35087BA313,587DEC7923493D74,E9FDFA81772DFB58,00000001A4BC61E5,0FCE11250E1823AA,7DE75D693DB489FA,DB547584F4D310CE,DEDA13FBB2D3E2C4,73E82F442A99394B,F41360FBC0F94A94,0D5D12F662BDB097,FE4093C5B907F763,5F5BCA5AD0110C1F,000000009612E327,86FD022EC9F94DBD,5343F05AB1097F09,A3125120920E316E,4D2C9F0629D2DC17,767954328D9D6A46,D8B5FC2F6A5748EF,603DABBFFB73D6F0,01A9B4211D79384A,89704DFD1BA13165,000000022F662552,7F75B2FBE4552BA8,D8BBCA8D0697B755,AB964F06BC50D80B,68656927DA935A51,DB2C7A908DEE21C5,54207A7E2064E50B,548C5E27C54C5BAD,30663353362BFF6E,B229CA37822C2336,00000001F1C65245,6AAA0FFDA5BBBCD7,618EBEE72EA4F88B,FB440030DEC39C4C,156362DCA5EFC0E4,C7B9A7AA365C9745,F0CFDB90838A770A,DE36F85314F5540B,6934C51A2512C49B,90F6E835EEF6A55B,0000000236073F7B,D61111C3019E6B9D,71995AFD6009DDA0,998D49598316D2E6,130E2EE2B4BDBE1D,235974B164108C76,F3C53A408E0FE7EC,B59255A6AD3B36DE,6D61681687E31845,F813C38433A7C7CD,00000002377A56C5,E9D68FB4864F476C,B73DADF725508865,B34B60AD7B5BF9FF,C9E642EA8FE13116,5FA481C91A5B6698,5D2B63305833C75A,C74579F19E78EBE4,C58D31F9ED86CA9D,B0696DE0B73C8891,000000007617FDF4,802E0B51FB6B186E,F8F6B70C9A398EB6,597A0959EBA4B53C,7B830DF4C24E2ED8,066B76D85642AA97,B003463AA38532E7,9AA87FF5006105AD,8D092F92733BD14D,4FD1ED446DF801D1,000000002ADA2E43,2352C7F5AF84E69D,014AEF2842031743,5C05FAC0CC876757,B8769C806EA6E20D,6EEC48E698AE64FA,F4B7B352C35612B0,D0CBC9DE5AEEA58E,B6FD9411C0784F87,15A85CC228A7D03B,00000000E40F365E,EB75CFE28431D5E7,A5D634681EF68AF0,F22746B4BA4E42CF,545C96BA2069B50C,5F2EB55ED4CAF6D2,844DA1C7A89E93F9,CC7898A710274475,354A048276409157,167920483AC16CEA,00000001811ED046,9C3ABCC6E68E705B,E34DF217202355E5,107569E54CB351EC,1925215A7CDC64E8,F96FEB136EA58363,1370BA7C0A9B0989,9BBAB20692F31A5F,F2C57EAAC7BBDD17,45D63B1D687EE446,000000002DFCCAD3,FCC1F2BC081F84B8,00B0631C98B1C51C,396E1D3A3322B175,1B2BDFCE9C2303E0,6D81852F855146D0,5CCB40C9522BBC56,454B4035A269E9D2,21081A95A6296B71,21A10AACF9574325,000000001C36A00A,73BCF7EFE36E9207,5906A4F704D3630E,427C426D7D84BCBE,1184EEAC60A368EC,9AB2BAAA38AF05BB,F8D210A9D02EE04F,B850A422E4834D64,68336583BABF0131,0A8AA1FE153DC6AF,000000024CD8115F,94BB71F0DA02B0CE,7D055AB794B75E38,DFD876C4DD403D18,C15712997E7D36C6,4A1AD99ED1E83D9B,B33BB91E43784CCC,C802292D0AD68926,48E972B2ADDCF657,573DED5A51F69BBD,000000012EF39CDC,7206A16ACF028ED9,75F903438FC844C1,40F5F4D472A0AFCA,F9BD4FA7924BE49A,51081EDF59D780BB,9ADFBDBD0837D98A,47CAA05ABC98E2EB,86799F7A022D8FBD,7E07FEB593E35542,00000001EF3B1212,E38A0306AF13B214,8AA0ADDD6977AC15,BE55B1F99F93BA50,EE1C9D36512B8B96,E9FEBEC1E48D730B,7EDADBD9F466E6CE,F5C21935AC12E135,5074543ADD0B48F2,E2FC51409687AB83,00000000DA2848F5,D58BE275ABA921A0,253A619C05AF312F,4BBC5C7DA24E4128,9501240F9BDAD1B7,CA14B0D23480D387,B3DE9FFBA6AEB736,473386736CF86606,92EB0B81FC674853,34FECF52DE6B40EC,00000000803D786F,8FDB621E6BE55588,A9583254021E0437,807352FFE89037B8,7F212D4E7789D170,C254AF485B369469,6843BD9750ED6A69,781C1C13A76717E2,72501AC3225F591F,D15447E859830ABA,0000000272F02DA6,D75ACAB0E0186235,9E03194519000128,CCB68D2B09807776,012C528F07F57922,1C968F8C79F188AF,3CF5D459B51D5334,79C445C479277C36,04E4F2C9A5662DDE,80BFD5FFDF2D8739,00000000B7E1B432,66E69AB48B168BE1,4D14AC49DE2124DE,7CF689514DC14115,1457520A30F5E1C2,471251A605CF44B6,6ED1FB06EB71B001,B2E6E11C867856DE,C47B1AC7BAB20E16,488074D655E28E46,00000001C05B6443,84B87E8A05A91B40,B8FED3A9167E8667,8AC620666A78DE55,65B90DA63045158B,18BB62C862C36755,E8A0C97416FCD448,77504BA92CCB0D6D,6EBC2F6C6AFCEC2E,5CC7D24DCC67A365,0000000069A610D5,EAF11B6AC0A05972,59DFB58B494F40B8,DE2EBD4F7EBB6817,73423090E2221DC5,BC61FBBF34996194,313F36343A94CA01,F022CB0DE06DF3B2,0013ADA8AAB93A7C,D29F434A616B53F4,0000000275C2A309,17F6ED15E7EBA15F,04B5E365E24C6D45,B384F482F7E60084,C22E5513C923C902,A65BBA8935170485,10016C207EDA2E33,32B1294C484E9BC8,8A5AAE4285858DF5,34ECFF8E3BE421EB,00000000D3A282C4,10B5CFC56AB8F4EC,D6A5CC925ED60961,2E4C5CEDB6AE037D,7AB85146E3AC9FF1,559D6D5EC6EDF91F,6B9E6F216F70530A,5308947A204335C5,EC084C5E5211D3CE,CA992290752334A1,00000001BA2526EF,EE2AFF6029EF934D,39E3FB207F461056,ADEB0F1174DD8AFF,989DA97CB54EDAA5,0914C7B1E8AA1916,851D974682DFE3AE,69988E4DB1528B62,BADD2489D9FC9AB1,0E420E7FCAC4DF9F,0000000121E3CB48,7517545FDE166EE1,8D70FFF9A4881D6D,A84984DA240111D4,27FF89F3B7068D57,177C32DB1E5114E6,BF4277883CDB255A,D750941BBB9D680A,DDE4A87FAEB647E3,B196258879219747,00000000FAD0457D,67B9A79E2430C948,8F095169B96B5C06,A1B07CA1EC62D59F,7638EEC9E7AA8FFE,348BAAD37C9200B9,69ED890BABD8DE3A,8289E9586ED8EC11,0A0F7EE5AB7FF6FA,F05E917463C9B91F,000000007A5ABC80,F9D9FCDF30654AC6,21A4C726569867D2,1D248F7AD425534F,2F10CE1F6259E5E0,A90011969B483C4C,305711F1CCA45525,3B94AA8ADBFF1A33,2ACDB095FC45DB7F,741D952AF1C131E9,00000001FE40A0DE,2A8AA854B8AF090A,129EFE25553E2630,1F1CC518797CAC9C,11C183A8C7FC9E2A,9563A61667FCD4E3,3F123153FCFCE578,0039654A29C009F7,A547B92A42CCCAE3,65CFB170222507F0,0000000194F7C3B6,46F35E614C4EB2D0,ED29CF542BC4E99F,8CE866D1B1658641,C30DB4F013CE2F01,70AA9D64C3A9916A,C3894CB6FE1B5B91,760B0E73143C38C3,24C3F697E18089EF,99D8C3D18C193DD2,00000000878D08B2,B1C63F36C81BB1A9,70878EE896EB4A37,A4B8FADFB699853B,E22F9D6D44A955B9,D6AD72B071E673FD,8B5107EEC7BBA491,266B9CDC80FDBA8B,00A1F10BAA320D2E,994A1880886E8427,00000000F518BC17,F2B71E8943C2DCAD,273A02A8403E301D,ECD2DC1E74275299,6B79A1BDA5F774CF,C281D20643FC1656,02AB0BC1331E89BC,CC01EDB9866C9C09,55F2D2B510863A5A,757152CD322C61B0,0000000119A91729,D57B1ECCA71CD23D,5B96C23FCF7A3A9C,45800CA08E9AA8E6,D3634BD5FDA6EA65,9F904B321AC2078A,6D5120E5A436D8AA,7AB1E73EB0746164,2BCC352CAA3A6CB9,4DA57D6874146EAE,00000002362FA4F1,C97D8E622733A394,B963E47EBCE31C28,12CEF75053D221B9,0B6F5DC197E6A5A3,47213360F3CAA3B7,68546BA1D40384E9,E75B7CE7E964CB4F,5EEAFC7F711004E7,3926E46791AE294A,0000000253B957F0,EB4C532854C36A06,1A7A2049E01C7E51,237A49BF0AC79115,CA0DA7D38D4BEAC5,6BA2356774525B69,64B4B420F1421D1E,64D0F64510D57EA7,8039418050A32344,F8C44A365E9E480A,00000000DA50A062,0993A26DCBBCCDF6,B0DBD78B0AEA0B31,DCA045B9BB30198A,E9299CA622E98417,DA3C096AC7F12643,2AC94A59A74C2D1F,3EB1199C45E5A016,A4CB1DAA308D9317,A512C2429FF24295,000000001476641B,88F052E21CA08D4E,7217FCEDC7C20D28,D403EE44DC5A4225,E0DEACC7F1188552,72742D023B17FD63,97838D2742BB7E01,7585DC743FB9BAC9,43A11F9D4F3DA417,350C9DCDE65BF531,00000000E1619261,542BCEAA8FC1A594,E455296733922F3A,41F013E6734FC983,FFF04973A381135B,90FBF2CDF57D327E,628AA05AE2274FDE,99B1E9B63D71A1FA,AF80F80C89492A17,07FB63584F9AEE41,00000001681D2317,81A21A22D11331DA,FD7D8CC13CF05475,67FCC0F44CC24885,CCAA2F11D4A1D237,CF5EF9D3248ED223,15068FDF5CA75C12,8C722D91C3ADA447,844C54CF32EC1B2F,BC43B2140F468E29,000000024223D367,A4B2E1794E7D6023,315FEDE8D426D088,774E931CBCBC5763,12BF23FE7D0BF9CC,848B8C2C7C239256,B300E6BFF4F4DB88,4A85B74D0740CFD1,2B0F60A235B4FD07,B0190EED22E06FEA,000000025CCE33BC,4F70ACBF430D9B32,12A2890BDA8D7184,D7981F7ADE7CBEAD,F53FAEC0CCF9A764,E39FF3596943240D,3181B0D9D46B3870,E5BA36AB8398E9F4,946CC4768EE9795B,EA9ACE0FC547E12E,0000000173D9628A,ADB8A6472C30D518,2ED9C804B4B792B4,9A5706F8A2F16382,EF7BA77AB9221AD6,5FA6821124EA556A,309E8B976600C301,3E78FC12659F4350,FE257F8CF55708E1,4C3011DAEF455AB2,00000000D289D79B,7425BE4240AF8358,A5905F79944FD7F2,108201C33AB71091,360A06253E10E36D,AA79B81308599790,3E06080C58DA120B,9C5F4028E723CC7B,B094747933295DEF,B88A3E1F607025F9,00000000B761759A,BFA73BC6F177891F,7EF3C19472EC6C52,F53DB043799C5B41,E35C0B0DBA06AD2E,EC78970E5FB81252,FBB7D66513954599,3D04D43E4FEEDA66,262D9AFC2953B3A2,F620C848046523BB,00000002049EBEA7,2F492720FD243A45,A716D86567F1F7C2,2815A6A3B212BC7A,39103130D812B421,2CCAB2200EFD077E,17CDFD0C10CB16D0,E34DEA11BE43F0F5,34C2EA9BB5E23C90,F22DB81A06780A49,00000000FC749414,D57CD95B738DE45C,606DCBCF8F39D772,63D27839E9694B28,4F7705484693C471,7E58D9131886C80E,BB997B7D974BB499,AD7257A45D134D2D,2F1D57CB2F9FAC7F,90AD82DE05E5F627,0000000055D4DEC4,4E864A8EE9CE456C,3AE884EC7DD360DA,561BDA0988F74793,27DFB5950210D860,A92DDC3B0C1FAC4E,74DC2E55CC33B3DD,7BE4266456AB00D2,8C8DD76F7C92BB91,F60E3D2B52A9C0D5,00000000B714236C,1EC4943266B16E6C,B6D15E301D4C07A3,23FB59AD479B1A8F,F3325B35B585D14E,1CF93B7D032C81DE,362276EDD989122D,820749C63BEA0638,83777B3351F25665,4F6E534AD57F115D,00000000297C0394,6EEF489C0BF4BDF4,BA01A715B2FB335A,C36ED72FCD4A6696,6C665A7D72801028,DF7C3B7FF2876129,98EE479D574BC118,1DF83E4A471A4429,7A08FDF1B225FEC1,7755E5DF3FB1800F,0000000124D1834E,25F012D3BF517D1B,1A10062B0E7998E0,2BF58D2A0766454D,0C4A6AAE5C52265C,D73F544C307F2387,221CDB5476772FA9,9184514D9494708C,8BA8BE5CECAC14A7,034032A3931B6C2A,00000000C33707FA,B9F617FAAC729FBD,9D1881022E4F1039,C8B0F65D5EDAFC10,AEF656770253641B,83A8AF1824F8F619,C484F05AD2530181,0159F6532083A18C,43797AFD7D0C51BA,779D7CD06042BAB4,000000002E9FDE38,2AD1E8104D5A90EC,98F00C2E62C345FB,DF44AB4D5226990D,11AAB9CE23D157C4,68C06C63276DE000,A21BEBA0BD62AED0,A4525FACC458AEB5,81E9FD928D6084BA,055184D1E918EB7A,000000018C1D0110,BE6BFC0AC3030A89,98B364BC2E6BEB06,0FE5067652F4A9CE,AD288D0D185758E6,AD91367CEA1EF47A,538E874401098FC5,0EFCCB6A4F508396,200780DEF859A112,DD872E63D2EEAEB0,0000000233DB039A,EDBD26B1D038C358,0F80BEFCF7A21FDB,0C7EC288BFCF5D57,DBCF0447BB46913A,A42041C04D7CEFD9,B3E3757E30945093,2EBE6FC10C5752D6,2FD1AED1DE35FD3A,DAED7A3A63EA63EA,00000001C5FC3C64,34888C220C094332,4DC8B56AB981D66D,AF11C9D4114EA3AE,2C6F6287B37255A4,A1122E7196CDEACE,176A0AD49DE79AF6,4DEA47A5C56DCA21,42D7D93BFAD7145E,3FAE7F31B3DE7C91,00000001B733745C,4B2AF843457A71FB,8A97155A65B16C3A,319042F1D77192B2,16EB159F12EB6491,D32C2B57843DEB4E,53F564E541BCD2F4,1F0D7E70AD688165,93DF083341B16D70,EC8DACA72325418B,000000015D59BDF3,435AA0BAD7C2AD7E,0F831B95343887A3,E14DB4288F895F2C,15FCD84867F96F45,06901B9A9C552AD6,3703B7CA6D482592,51C20FBE32A75EBC,7204A4A2DAF2C18C,5E2C9FB17CEA1B84,000000010EB43ECB,AECE6FB38326FDFC,97E0F36E1A5129BA,A9FD8192AD5E3726,FB4F18FDBF5762FE,0E17E30DF389A511,CA7B917844D419CB,CCBBD3443FF753C3,853999BB895690F4,A2D4B57F94EC9239,00000001E1924C76,CBCD4E20F9789993,F40CAC6AC5EDB6FF,0C1E8A735DE71D7B,6EE2DDB74D615561,971A47160E2BBBCB,B0C3ECE225C6087D,52B6462342DA6182,F3E432DBCB6927F5,A7BB8653B8B792E4,000000002FCC6B73,6631D125272D1F71,34CE189473F811D1,29DC837889A9CC75,AC8201A4AB9D963D,3CBED9C7C71D7768,66D7A105D2893DDF,E2D38EFF5F956991,3E5BD671DB5E8DB2,A736CC660E731333,00000001240CFAA5,962F61D294385D08,896415BFC7A8A192,A7417353D8D539D3,FB9B2191D6854F06,043372C3A938E2AB,C918662EDFC2FDCD,818D3736FEFB219B,DC976E9A736FB38D,7BCC1FB0B069DA04,000000017641F77C,15F2283E8C6D49E3,02B11AD9EBA330ED,2D50B73E4DC9B5EB,4277CA894DB1A102,9566E5F29C016686,D2CCE7B7AFBD93B8,6B22E8A32F0FBB9B,78899963900701E6,A545D07C7628F821,00000001A943F7E7,0C5B5CB4D58A182F,961D00B7FD35652E,03B2A70D25235CB0,D6204508EE8D6308,83C9DB0733F7CDD6,2D7B219D2A6A32FC,7315418A958A3C7A,807C9C0183880972,EADEB7C60B80B07E,0000000118B5105E,B8B4D0B7F750884C,3CDB30C6DCFF0AC8,9E87A171B0E0F2F6,D4AB7AFC3B209675,694CDDF124A82894,D3EDC09B1BAD4473,5EFEF301BE1E54DA,C2037622AC45E37E,4DA00E1130A5A877,0000000102D2509E,A7476038853DA738,EB251381B5B563E1,BC4BDBE7EB099443,4C6A469115FD515B,7D9BEA3910BC90C5,AE71C965E675E420,092C9EEFF9464870,EC60745E31BF75DF,F50C2626BDDF6C96,000000016730F994,9538AD0F33689FCC,6F5BC4EC069C5A25,5D5E1A3751B750DF,49848B4E617BE43D,22019A4BEDADE2E6,08AC4D1EDA18B2B6,36495D8A2D20D009,01E3E528DD61E82C,2855512DD7D9E7A8,000000027B1141FC,573DE98607E7830C,4D4C838DD1E6DE7C,D8B52BAE0D00CC9A,7CA345C0858C4363,3F0CFFA6B04D276E,F5299B088C194F07,62B54A52FD6D910A,CEC8CBF44C7E5464,14FCEE94EC479470,000000019DCEA040,A7009B1E3D0ED509,1156212D404B0DE9,8AF3988A386A2E59,20B1448FA9443C79,02B12B8193BEECA8,FEA32883F599528E,56ED441B7A316B7C,FEA181ABF06489C5,DEE837903BDEF03C,00000001B5F9222B,0242B176A499CE5E,FF8D6FA858ABC896,076B422BCFE615A4,F816C8CBF545E458,C85568ADE1EB6E25,EED6E3C208ED6EC2,4444E8875904B715,001E45EEEAE940AF,3B675675E75C8D05,0000000213800A6E,9185B154A09B726F,BCBDF98170F9F43B,516C3A60902E1C27,5C509A2BED1A7A28,0BF1B5BEFC1CAD22,3F25F643B5B6EAF7,06CF841464ADE486,C5D7EFF82043B236,3D67183A6FE988C2,000000002840E4F5,50F819F34E5330C3,5717CC43A8F128CB,FDB4194F69D2FA21,13D2863624271E55,2808DD11061BEA99,B7AAEC4437B52792,5CD9B32A1103611E,7213C21FEEDAD3E8,23BCE330C5C86E33,00000000E5DF445B,08D06907C2CD6C8E,FFDC2F937AC23BDA,62A81CB9A75510FA,A9C5A036F8DF0B5C,93E3E77AD0B5E867,6CDE301C1A27DF33,C9E4BBB4E6FD6841,03AC53A186081B19,09EC8B6D747FF063,00000000240B308A,68639A8B0A57F25E,6F89BBEECBE758BC,49B685B70CB5249A,FB691A68CD07C806,EF300C381C481384,97370138078994F4,080F65480E402460,861E9360574AE12E,DF38F9A1F779B163,000000004364109D,21528186264A6577,ECBF835078FF8203,538E25ABCB8C2CD9,6C9DAF711A9A4BED,D858395AA016093A,8A957EDF78127C04,A1946C7CA4CB4C3D,FD9D54B3FDA33AE2,3F203AEF60A38E35,000000010B622FBD,3FBF8A58C9B97EFB,D8CA40BE288C46FB,343B40C4A29FEE23,11EDE34D4DC36F78,31074C30C4FF0982,7B4C5E2903A3B833,33E34F3C9A8A1BB0,EAD820CFB7051D10,70852930C3051C4B,00000001404E8BB6,1B864139FFAC7166,DECD79A49CB6A6CD,9DABED6D8BCAE288,80A12B32A844649F,3D29D81A8FA13AEE,0DE82DC73490E58D,DA839DDB1C4A7C85,7909B2F002C8C3D8,EB52DFDA62099F8E,00000001FEA73C7A,F52BAF95DF2219B5,7C7C59FA385AA733,0EBA6AA1676D4BC2,EFEBF516F5136B8F,7B6796FCB73BB939,99001717BA63045E,7FA7F0F3720C6C9F,70184A8DA9EDF031,A79668B44CABC96A,0000000233BD345A,FD2DD8A22D1A86CB,EF0AF31898EC94A7,AD9887309EE1A9B7,A840ADCDD3B8DA16,E6879E4560225CD4,E94344CABB796563,89C0C4AF9BADD266,8BDCCB9C32AE1CC0,CC93CD00258D78C0,00000000325C0396,D36DC370E234C22E,89C81DB0FE71860B,80566BEAA8310089,46D4DE079FAFA7B2,D60522AC916C5D16,A4B97FC62ED1D947,8568EE195AF66A5E,5CA2493726E8D537,6E0EF8ACDE517491,000000022C60FD8E,9FE40DC98EFB8DB3,CBFC5AAA3BF63B6D,9D8FEB72E1697251,7D10744CAED505B4,E38CEACE4BD6EAFC,AD138DA42C10506B,B42C28564BFEF884,2249E524859414F0,FFAAB38363982569,000000023B4B8318,435EFCEDA2CFD1B6,0C39544C9C68368C,535FAD0A9D960276,244546E8A38DFFEC,4538D6B4E6167DF9,9587D1AF4DB697B7,877A709E801373AD,C80610A4D751602F,C070ED3444782E77,000000011640EA36,07C8CBCD8A723DA6,4FAC55512848A679,04D1721D6B4CBA17,DF377ED5459F9771,F6ACC05B9A77DF04,368365C92807FEF5,F2619CE5C9B6E79A,4D16970F09295276,E38477A74D43E13E,00000000E8957327,C9708C548F9E3662,DF1D90B695A12DD9,AB1EB7312CE15748,6CBEAEF6BD39437B,8571FE51E6FE1DF9,0DF572432940CD57,A3A8F942281EFC32,86D0F5FBA8FE5325,72A6E84AC09BD73D,0000000226EED66A,9C8AE1AB213AFC94,6D6CA5131B3F9257,5ACC49320B2C6B71,36AA765AF8DBAA66,D4DEBABD6A248F0A,0DBA2661B9FB1F9C,81862FF9E22FFC91,F08932D227B4695F,8D398E3DECE00220,00000000A1200C01,7C8C44B4689CB166,288E410478ABE7F6,8F6BDCE6DE518018,9F9FC26A4110E080,518E24786055E893,14E1FEF37A6BA0CE,F47AF792E25F2933,AD707A6B92D65BC5,D95B81EBC4220A52,00000001B814BFFF,BCA6CA5A7216DEA9,FF2501CCB1753547,3AC0BFC5215F8BEB,A8A98BBC7E11215F,ACC4A0E343BC7841,AA840FF8681C8565,19DFBF37B0082596,82B3609E16C41566,967738F7E786ABBD,00000001C92D5887,C012A0367C84DEC8,650DA26A9F272363,9611F4B865B1EC8F,51E5022B472E58CE,30BDD0FCB0A7A9F3,F7B34C2A0A1EC2FB,34EAA10003445ED1,B98CD5E1C9511C4F,8B52B43FD3A7BC1A,00000000011D8FCC,2C5DFAED49361356,1A561F97BE3B5289,78DA2E4321FD9602,0E9F9FBA857AAFCD,E2253B8E12F022F0,5F67A074A1C3591C,AFB66DCCAB785100,D6BC20C6FE315C4C,0BAFABA7342CA3EF,000000012D443A02,A0E117089BEEEE9A,9A9EE9C23B7962BE,908C5D423F0C9D89,D3FA8F34A83C3E81,D57E667A03B803C3,E7E45F88BC3A8B89,7E4073A869772B27,D6F16392DBB9D5C7,70C1135AB96E2F83,000000016FA9867C,DCD8930402F83317,A0EEC414CED9BFAA,82929DEC298B4F0C,4689796B3012DDE3,1758D53FB4046EC4,A7A3BEF4DAB0BF9B,AEE83AE3A62396D8,EB09D65082AA5044,531DFF9983355B91,0000000258966A7A,72E327BEFE95FB5F,8EFA8EC728215222,573A98E78EAEBED2,11174F41F88BBE11,67AF9B0BA5C42188,FD71042B9B2F6416,158575DEE2168E78,F0CC0DAD3BDBFE4A,AF8048787B7BEDB8,0000000042BE4928,44F40905B5771C89,E77668E525123213,C250F8B769F13FD2,53C57AD96E44EC16,47F9B3F536E3046B,436C78FCDED94CD1,210AF0478BCA004B,4A118251D969B9B6,EF7E580935C32C9C,0000000040F1414F,2BD46758018CDF82,37E6B6C6EDEEC17A,7DE66FB1CF345AF9,3BB3695BB89AA2EB,D9FE3671766000F7,1B4B513BB2A889E4,2063AEA1406DA46D,386A0824A7301B2C,45D598319703574F,00000001182C8EDA,4DEEB320F4A8817A,299F7136BBE42ACA,36F13373F20C7E20,6923553FADE05847,B485C23B053F4FB1,F2E31CE264292517,DB671F32433B10F5,205F7AB9B851E22B,B5FF2AF796B5DD97,00000000E13689C9,0C876A1D6FC82B85,4505242FE0CB3C3F,035F3C5B7E08C158,99BD51A4B7543E0D,182111B1666D2F58,CBC80908D2A3DEC9,13356A5AE97B9D4B,802424B9C5FF672A,E568F00F4E9B3AED,0000000142F3D6AC,50BD416471573145,5A14ABCE917911DE,2DAED79B7BE4E313,7317CCA4ACB94BCC,51AA238BB5D1A9CC,A2A2296AE0596490,96703A53BA7770A4,4A8B72DDD35BFCF8,C1C9A99F73C08F89,00000002631A4A09,DC618E490137408B,E420E341E41A1B77,8951E76E03118171,322C8E6ED1E27A44,5D4CC3449ABEB728,4EE41BF9AF9714F3,35BD14538A25581A,3343F3990B8AD8DA,9CB40D013204DB4F,00000001C4576ABF,E1BE2E224EC8EF3E,588C3E638DF4BA0F,F39B5BEEBE1CC81D,40B5C09567DD9D59,5D28FB7ECB32F864,B8941E6A68B5C12B,CD5BD250E8B2BA64,55F07E4AEC3C56E1,A2CE25186B3126E3,000000003C8B1044,8CE8E9DB93D80C7F,9450ADB518F6259E,175DC127649E3A19,09EF45572FFA2E54,40F4C24C50692DCE,64455616D3842C75,FAB57254EEB5AA74,E372ECA0DAC17B89,DC19AB13608DF69F,000000018B8D6270,D8AE94C5B4DDB361,9ACDA6EEA310421C,5769C62DE2BC1D96,6D3D2F52CCA293F6,229565B15D81145C,83DA6A056A31E592,35FE27BDA7214500,E3A51C56506B931E,D46DA897A7C5D307,000000019D39E9EE,5A87FB706D0D5F8D,426EFDB1DED0CFFE,889B446EF373C3A3,9AD3035E774E3476,BBC32FEAC51F0C11,7133656C4099E1DB,07DE7BDA140DBC69,56FA2C9D5C0FA9EE,AB79D51584B574E8,00000001BD32672E,B89238280E8A2254,CCD03CC96EA4EDF8,200776AB9BE6F460,DC5E5EAF323331CD,8D2C76A4797F49E7,07C390DED9C6CB66,0B16A2C3A6BF64A4,665B296CF8375041,52D92A6F2C438FA4,000000023D488659,15F0EB5622EE6333,7B62267503D0F7C0,3DC8F03D75B1D514,44E856D632976A0F,2068BA4B770F950C,78D4DA73FDC24BBE,0BCB074E1DB87D76,23ECF5FB7635893D,DB333C88E9064FA9,00000000EA16FD46,72E60EA789458EF4,43CB80086B44C90F,B9A7FBC27EC6DF7A,3C2A6F2331CDF1B2,5D9907F33747481B,992072FA9FE9F913,28B0D481ED5664CE,C885749BD9C666F3,56B8475E07AB06CD,0000000058A2A3A2,B52E3FB04827B349,523EA2A2A463FFEE,3FA9BE66341D2A79,03C183938C8EF949,04DA6D97DF27ABC1,1E79ED30A19D2A6F,E5636C83BAC87704,BACB6CB470AE1756,7A378D0AF796AA8E,00000002002E33AE,40C29B96959E5BFD,608BAE14CE9E28CC,B133CA89E4EA905B,6056BBC7FD188EE1,7D8AD8855B2A5ABC,867CB0C40BF5AB19,99BC3E56FEE43846,67D78A54921C07A0,6D676A661D831AB0,00000000C90F36E0,7ECD9C543463EA61,7954C058324B5FA1,B7F8BA200F5E48B4,B5A44A7E257DE4D3,AFF1CF4278163CCC,21AD357B784B7407,0D4109151D113EFB,F06B09B869A167C3,4E81C45333AEF8A0,0000000075C8A07E,9AF5F34DC2CCC7FA,E9B3CD998B7CA16D,572FE1C7D102B29B,10545CADD140A638,DEBF867203F0DD32,E614DA9B91F1F5E9,CFEB34ECCEC07619,26F261BE5BB967CE,9B0C1EE468BD1800,000000018A0F22CE,833E7C933C29265D,45C3677E1FF5F784,2BE185430051233E,CCCA53973DB397F2,D911EE7BF197507F,740D72A5134475A8,C532BE46DD124F61,74D9D97DBF56985A,39B559F4DC45A3D1,00000001A0F7338E,9E589E0E3A059405,9A1DCC3DB98B6BD2,D2FB4C662BD700F1,0D4B1083BA14E7DA,8FFDAA3378C4AD56,7C7FDB080D1E73AF,1DEE8500C9F93947,C35D4E939C5C9BA2,25477E3634BB3D92,000000013D90CDC5,652A5D788595D9ED,9ABE49264C6AA929,4665FC0D51DFC94D,1C246B143C19760F,3C621CE35190A128,AD015763F0905886,D0FDCA41B8181BC8,D26CF49C4B461049,1829C3193E915A1B,000000013E9462E2,BD72AA17C6CEE8D3,E50CC04DD5DC1664,4A9354E44D7582C7,101015D733D6E138,A2F0EA76CFB11113,CC1BB2DABEB0713B,24C29983E4F22ADB,896B23FA8F973C54,1AB49C748A5B4183,0000000126E64C3D,E9B5587B568855BD,710F023C2500C696,F21881B02ED1AF2E,92E0D767745FE964,AE9A1F7C73F9F12B,F163DE920ADEC061,2B242FB23FF96037,F6C6558B619A110F,98645F7118467B55,00000000BA364F9A,5D09BDB96E77F365,FB63B5E8D81FDA10,C3F876D3245D9360,89290B616600E098,0FF0400272A39B88,E310596181FD70F7,67EA5872C4AB5FDB,CB6895BF3C69BBB5,82AC5CB40901B523,000000025617EA06,F123F76E35D7FF07,C195D6A5791DE718,DEB324ECF9E19821,546FF959F1CE3D29,4A9859FC9E0826E9,2C1160855C20E776,AD994EBCB2BDF6F4,EFF844F5D19AFCC4,4F8F167C2F12B8D8,000000010B23AB06,51BD985001504FB0,7327EA2E3AC9B069,A9578511162DAA35,6435117F295B56FC,A9B5E7E4EBED4878,AD080B12333E989D,4F4351805F2BF363,0F44DC29440886FB,7676FEEF676DC265,0000000242E968E3,EBBE36DC9BDE919E,32D07A3DD3A736C1,894DD78E5EEA66BE,12A7EFD1159B2873,B7DBC02835AD5242,425E128CA7BFC6B5,CA979B6687BD39F5,F129D6BA75DA77B5,A33CAC7B2C07E1E4,000000000BCA9321,B8FDBF2EC2C0ADE6,3B19D8175E34F040,3FBC7BD4AAD25707,B6E2742890B82ED4,B03D6A4E6FAB88E0,1F64A545E0D1A461,A7C3C12B081893B5,68948C261907164A,F2B4AF0EF36CB075,00000001615A6ED4,AF0FA1EB354C192E,BA7F64FAA78C6B9F,D32794994A808F46,515A311E30CC2367,E6D0445550072AD8,248682FFDB8D82C0,8BAAF7AADFBA8760,D20A1C8F0DE64180,D95E543724DDDD7E,000000008121FC17,5D5E74E70959A678,45A5C6DAFDA3C205,B3F61D09B95899F8,840B0B87BFB730D1,E7E59DD038D2FD22,931740EDDDF88290,20D4C484B59E0159,8D3EBDAB48224F1C,1B90FB19A4423260,0000000036EC4E8F,7FD0BB3CEBB49D0C,EBDDAB78EB5C88C3,DCC18BA1EF1F5DE1,8587819747790BD1,23441FB04A9335D8,0ACD62B4FE86EDA8,D94F2439447B5FE4,A45FD813358B0344,5C1D6C1F13769737,0000000266766763,B90964DDA48BD6F3,302525C05497BEB0,4955B99CDC81322A,90624CC2596C5A9A,D44DD0BF27996D79,819AF5DCC397B0CA,1460D50D24355542,2184D2743F5E5DB3,2E1818A2BCB2D2B2,000000013843C43B,98248E602D04D2BC,AB5AF32F5293AA6C,4550EFB0064905F0,8016BB9E89AF799B,EE6543E1096659F0,C266129169B69268,B9EA52353ADEDF0C,8BF0C8EE507A9219,F3E556D49C36BBA4,0000000205B85030,8960FFF9474B56F3,18F6EE112418D65C,9D53AFB1FFCEDCEB,7AE72BF8A6045E6B,B301B750839D7064,85CAF09B5FAE19AE,C94D860203E93C16,9D72D6E5A536D238,420D500F271E1670,0000000260C3E811,AA877324B183B4D3,E66B9F26E5A55C70,D01121306C9F6550,73ABEDE0C6CE58AF,6C458023E417A4B6,A5ABA8D8304D2088,8E1C54C34B729C3C,13EED28040FE84CF,B5662F6D09E70013,000000005E958A08,BCF3257A6EA30ED0,49F01C2B035BC651,49BDCC576C584FA0,7346D68BE611AAE2,97C04D40B1667149,525C8A66A3A16601,DCC676F802924620,6CE05DB3B947DD8E,2EF2D56590ED9A12,00000000E874E5B2,15FD96CDFE0C1CE1,194F81A254A64072,006EF906B32B6F4A,0D4AC5F85F3F94C7,7D4C51CB2F50552F,9FDE5444E05C6989,5E98FC863ADABC87,D5AE65D64FC3E520,20C5B7ED7AF9CA0B,00000001F4DAF305,A06A5800D03F425D,9CB98FCC737639C6,991B0FC9EAB3ABC5,4D98DA7D61AD8173,E4149096C88B1819,82521692C5CB1C0D,BE9CDC0AC03DA6D2,7F0180DB6E1FF827,A7C7487C16F5EC93,0000000153D77E56,CF45B55C51CBF071,B69B3C240A10428A,B25CC5C0ABDCFF0F,9FF4E5359AFC7A28,4CFE96119E12EC4D,CD979D78143B3CC2,804F23BAC09CB835,37761C900DFE7BA3,BDB821590F13BBCA,00000002262821FF,1ACFD08EEFA05CAF,6E7E61C83601FC11,47243BF3AFF480F8,F4FF70DA2E1EE8AC,751D06F93DC49B97,FFA1FCD128D0C286,8E5FD9849A8A3411,62CF44E6DC58D736,A2042E90CBEA9E94,00000001946435F4,9D020B788D078A67,E9A388DA0C741CB8,07FE18F7CAF4F7A3,08E099430C7C1E23,31768B48D040E46A,1F4A8A656C4AD2D2,DB8974B7A0E2EEC5,D913CB8F8488ABC8,60E8A0FC71726280,000000000EA7869E,B000FACF020AB63B,388851299DACD05F,C6D9029AEAB420A5,4C0A9879D05CD3B9,985E3AC1098846A5,51EA2C2FEDEC9976,B819121843FEEC46,FB47344771C3CC41,BA0E1A842E47A471,00000000542EAA2F,51D845328E66ACD9,6FE3162D123C855C,203544E6D3812B16,B6426DA6B66A17BA,97827BD224472CD6,D3C64AF8B5CD8416,A9A8E0035B0B9E06,09F36280D52735B4,06EDB534A9CE429D,000000014E843624,D2D6CB71CD4D70B2,AA2C490F59F413AB,EAE155D43A0CD97D,A1D97775F0D8B693,9206918F7808B83B,7E4C8A234BA47E94,BE95DC314CE71C4D,D0F3B38BD7DEDEC6,A0CBB76757C43A3F,0000000154F0CB89,07758A0798B0C04F,CFB01DD5F372E4E4,7D9FEC1F10966A93,A9510B13A3B8C138,9E3D26C188741013,9DA0859500E00846,A5698F0C66D67E7B,390EC9DA84A6E522,9146D88A7A00579A,000000000B0E3812,16A850BFD2CE449A,3D447772293B219D,EE770BFA5C987F90,D040B68916C691F0,CB5E952263A9A4FA,3E1D6030B4340A6A,51947BD3608C3A2F,0A3F1FCE9A146144,E77314DAF7D82CC2,000000003FDF70C0,44978F898E409C58,E3E5C6065CF72B50,2D91910D6910B82A,DA6B4A17833EA383,0A8E26AA247B6279,AAA4834CB62FFD75,92B6EB5499DCAC6A,C37A24ECD3ABC72F,59AB5FEEC7D5D7A9,00000001AFF55721,7E3ED0582CDAB656,8AB4BD8624160CBE,FECC9790A45DD98B,C035449B3E452405,34FD4A143B174605,3034125558EEA0C6,3D07BF54604D0F9C,39C7847A5D09565E,4508514DE6084E8D,00000000E465E69C,420A905E4EE3548E,43DB4197DB9C95A6,EB61F7CF0EF51173,31FF570CE4F9D1D8,ED409D93CE57AB6C,B01A15719B0BB118,13E2418C82D7B2B5,253FD468FAECA042,86946A71EB190C5D,00000000B7F0098A,B27995D0A13E66B7,021B2C966E6C63CE,2C588DAA9B9B2EAE,4B3E5A53F42016BC,12C9A1DD1E66E421,A74A20C8A944A40C,35063F975CB25305,271B59F71A15E24A,E54C461D052CDBBD,000000019F9E72DF,DA2D27E8B1D01706,2449690685A6877E,E7608C5A53198611,80568544AF486258,86092966E8A64A7E,A67323E8976DCC0C,4B7BB8E5FCBFC9CD,40859749F375E20A,71559B1FE063FFA4,0000000062EA9F16,6F48C1107C42C291,6EEF7660AC594D94,D3D8CE589F53AA0F,C1B155770F27D24E,7F068A7B04462513,471DF30F7474E8A7,8B88AB9709CA1C8D,4FA5A2633265A9B2,8F0372CE69857A09,000000000798EEC8,549BDD9E84F3660E,212B928D8CA1EC28,56EC5DDB55AB6835,E8F23981AF4CDE14,7FD0CB4DCE0C271A,594749901E29BF6A,0DAD27091388AF57,67193642D0D63597,9B7B7C28335E217F,000000006A018F1A,FC71FE32DF5700D9,3F20CBBABD538B2A,B00A74A440B79EF1,A2F8001171E4974D,A16877E756E63D48,36CD1766FBE6959E,800A0ECEEA327959,8179781547BA3AD5,A310887358489D53,0000000275F2C2D2,AABBDE8FF49A8617,2E06889519F4650C,AB026F31B9B22D50,DF01FC4906964767,A769A86907672703,CD14035EC7B87D64,12254072EE240C26,1E5CB1EF9380076E,9E5D6D51D22438E8,000000015B295A4F,791971CC16EB2697,7D956E5B655A26D5,BF9D66ABBB08BAB0,779580003A7B8B75,7DD7614DABC9C6D3,93E11B2286ACA6F3,D3F4583AC8E09FA9,31D76428D4B4989F,75E0DED7F3092D1C,0000000028D04233,DD817BFB30A6AE07,E8DD7E11640765E2,0AD4443CCBE6230D,B0A1D64FB4CE1EA1,ED8F27B149F710CC,0DAD673383496A3F,1779E6566A0BE87C,58A918A2080B5543,E979B8BB5C68CD6F,00000001AE052C79,98AF005CBA492E94,E22E407B0679612B,F54292FCD5E61647,834A197FBBBB6CB5,C3ABDC68F4FD8492,D047D34601B4DC4A,4275C07F531149FC,5B8F31F3B79BBBBB,7781A55448A27765,000000026238736A,BD68B50B31730EAB,115CAAC9158272F6,94B6D2AA5C7415AA,13106D1DAE274414,7AD87B6371C26E58,DAC97A84FAB25EFD,C2286A1223A1E11A,CD7D73CEFAAA8203,F81812B3CB0FAEEE,000000009F7F7C76,0B43686FAE6C7FE7,D3FA193B70D78F3E,DAEB36E29329186B,A982CBA50F0BF523,A1999606F30454A1,F84D5C717EDE8B9C,B437761717F45E8B,C4BE2035AC7A460E,4F14D933D2620556,000000005CB4E81C,0BFD56629934161B,971982812B134997,1EA5BBBC52314E73,A08B661D52ED5E36,2F4389F3FF86A0C5,1DE247BF1F74E7D3,E04A3C2A689F8663,D289B3BA14DD2ED4,202283B8B9ED4A68,000000009DE2B328,27CF803ADE99E27F,492B456E87D71C87,054488D46A9F82AF,18C2474005DB29D3,957F1AC6BA6959C1,8B7D4CAB43321184,D268B73EF12FDD3A,4C727F15E6F7E98D,1E7B75AFE315F544,000000008129D3D2,63622C98C0FDBA75,AA323700052B3ECA,D140BDCFE935C8FC,489082437BB2A281,8235088F73EFFA63,0F4C867A4589820D,8C42A213D462AB86,00D74B7CF438E5F9,D7D580647ADCFE21,00000001AE47FDDF,DDACAEF137505F74,524B9DAC61B256EC,F51249248B28B131,2F90DD5F1FBCE9A0,97FDEA2A5DE14166,114B588821FD415A,5D90E7A71AE2FAE9,CF2E2BB26C9E7BA2,A3D1A30B5B81871E,0000000072A90726,FCD1EC81EBCE52C5,86D94D50F4871757,5AF592BBC3C67172,2F70E6648855538E,1B84E80A7BAAAA01,D6B76EDEAC7CD576,B879F99E38E7A353,14AC2395208A9A67,200B359EBEAE3A2F,00000001578B2D4A,751822B468F82A4D,3BCC76E2F6F7AA8B,C9515E9CBD1EA8B0,159E445743C0E89D,2EFD912972115E99,2D41A342B585BDAD,09E17C9427D38E5E,78CE3B407912C7F0,749454804A6FD6AB,00000000271B2D60,F112507A17C53016,D858607C69D9E90C,11C4930629F0A999,DB2B699EE2800150,037C80B05FB3AE76,19C15B60B421D6BD,3ED102F38199F95C,D1594857846AE283,566D241DC4697D0D,0000000017F16BA9,032CC353B81165DF,DFC56BEBBDF8A0B9,FB617C57B0089546,918BC7F69FFE8405,A972D47AC8276BD1,8F93593E8B652472,6BD748D15D971FFB,AAA49186498475B2,095A30C496CBB3A9,000000014D25319D,85AC3C32DAA2693F,39A05957625B86A2,84C7323A51E3EAF4,0292FDBA67DEAB07,3E30C7AFEBB74182,BC8919C70CDCB569,38A2017E7769102F,2F195DA9DF4AE8E0,2918714EE38F68FF,0000000258E33903,631899A19BFB4EB5,0FA1B7842F56C994,A958E80E5EE3684D,EC93CC5CFF57BA4E,000097F11B81F281,F5F907E58FBCDDC7,1255D7E5511BA4A8,2A434A9BDFD97F8F,D78160E480C62329,0000000163FC6B6D,786D6786FEFA42B1,14212492EBB28002,FCD3FF95B4813254,0EA8542C98A1F012,F0BF9CC3829D0016,EC8050444DC242D2,F524F92A30421183,C95A89969392C5DE,B1A414B265E3EB99,00000002762F5233,18D80BF52717FEE0,96A49202E64E0DBE,45031B7F781367FC,4E675800AD3BA229,EAA50A16397BEABD,021648F74E8F4623,EADD24C197F6DDDB,497490687D6FCAAB,656F3F9B53CA16E7,0000000088C4845D,840604A1F60696FF,BED8F74DCE73A1E3,60C4D7017BF84356,0596C65F4A3021B8,172429E75D3D5D51,36229954EFB1A48C,7432EEA6438E3C85,B88B3E0D26F08693,18C463F67647576B,0000000201AC9840,A52696DACFDFDED4,6C730C9D29E92A43,85786764B9F9FEE8,3CCEAF5AAA0CE1A8,84B2DA63B3677671,91B2E35EA3707BD0,8E05D02751565A83,5166ACE0CCB9C303,8FB844DF1E80F951,000000011ABCA70A,4D429B3750F39984,089BFEE466FF76D3,8299BD4FB9A990C7,0034FBE033D43C31,73D14B8B40CB6811,E65486671CA7AEF6,417772550BFC6F0F,0A162B2464899EF0,83A4AA7AC437B3C0,00000001798D06DE,45A4FB56E5553831,41DD71680F9D7CB8,D33F35E6C83530F1,824763741EEAB404,1CF21601AD3BD47C,DE35422900110A3E,8FE5C2623CED3D18,C765AE28C5162999,4F683D93D96DC333,00000001F803AC8A,49A0E3D001ED6E27,714C642C3FB8DBF7,C15173ED4721408D,243DAEBBD0504665,8BE9D79FB98FBACC,82DC5B4BB4D6F91C,EE721B2184EA5A5F,F0F2CC6F6BFF49E3,A607FF81658E7D67,000000013D117134,124C034170AFD806,C1F33CE854AF0ABA,F3CAB14B80E84B3A,CFB201D369A714F0,49A8ACB331125C42,0648BBAC923F321C,28AFFBA3A04D654B,06223C8F7801F619,38CF5FDE23241378,0000000031ADBE41,E748A317D4AE5A19,81930072346C1514,DDDFC400B474B10F,362D79D55960F42C,5EA75D8ACAE42CBE,2E9F5B9DD528682A,A2AEDA40063DFB0C,03B76270C9E9312F,73AE54E335986675,00000001F2BC899D,23DE504A36646C48,63F860D8A983DE70,AB2F2E4AA8E7617D,05FC8F28D1A452BB,E919F25BEE9C4552,CF45FE02F6291EC2,5267E4537284A26C,03B7E782EB97C235,29796CA57E08904D,00000001C6533F16,7BE29509117CD3D9,DF5416F2BBB62012,9206B6FD05E6B183,BB3BCEB837D2A83D,91E9E68BA1FADFE2,FFEF608593C38D2E,277A0E8D09661AB6,38FB834A10DF3FF4,12A84D2AA44685A2,00000001B714BAD7,DE076BE99C32795C,F71D649998CD18D6,9C97096FDF72C64E,E4A553B7FADE42A5,7FDB318CF2D5FA1D,3A2E09A0ADFEB549,D0C483943957A601,456708CD98EB4338,861BE77EE0898F6A,00000000D3E4FD56,D8CB85934CA002B9,161D76F2BA6E5CDD,40C1F8F70B667F6C,80F3F87D4225BB71,0C3F3918F2F8F297,F1F59DF2DAB2B2CF,B83D0FD20DCF0558,ADEEED09B52A2AB1,97AD37078D260F3B,0000000211A6985E,B8B11838261D2259,6647C27B84CCFE35,D1F8E8763D4E10DF,A36F76804DE18E28,B94C8D79298FF4F0,9E9465A7066DF259,AA72AAFE61B5D3A5,371CC542A526EAAC,BDD30EE54C46D19F,0000000064076D3B,AA11B46F1A903262,BE21E1A6AD1C731E,2DC6B160F2F2746E,C3C1FFEB8BCC80B8,539040CAC59A812A,F424150ACBBD7176,6FB7ADEBCC1E3399,DED3917B36998D1D,ACFF96DD1BE6FD02,00000001EBED164C,576836EB3FA643FF,A74B1A9D1394C48A,A53A02E4D1E04C62,A809DE4F96900D8E,F4420636470FAA7D,F6EBF52D91D34CA5,3EC6E7C1567E6AF6,A92D61D3AC8680DF,E15216BA026A8AF7,000000025C002D14,2E889D5F34C87A2F,8115A08CA726CB07,B1A74FAB4DD9D4FF,ED9FEA77A27EF3AB,AE205737C7DE9BBB,BEB4F7C9D01D00DE,B3725A9424D67956,225A48C0ECFF109C,36608AA598D6E0F4,000000000202C571,3796AE1AE024BAA9,20A2C3D2EE4B3CD2,BA716E878D1F2127,78AA5ABAE8F9F096,9E14D4F24C8B1720,3FE85BE7F74A1EFC,0971994607397105,C60C08CC7566C764,9540784144467B36,00000000E9A2F200,011307985664D422,22B5506934FCF013,1462952DC309BFB5,02D0F3F1F5150144,B1C27F686BFCE9F5,5C628A0EC4BCB007,6D30CD8D75F60FC6,9A316A236BCAEC5E,002543BFF8374E8C,00000001DAEA4659,A590BF2FEE1FA314,119217D642BAE7DE,873B3B9C86C91370,94ED39E6080A7B46,95BD2C3288FC80AB,38FCAC87CBE53461,805CE4AD6574369C,3F04B0BE7E0EF85F,1563395B80190477,0000000053B521F0,48F8CB84AA5FCF2B,2EA05579034E8D8D,9DB55037746231E7,064433464EAD834B,A676966C9B292A8E,CFC285D40944E56B,7C6F15457095AB4C,1B0A068AE12E70FD,05DDCE0970912ADA,000000026862806D,A8A337E22F650B69,03F05BB1D9F16EF3,C3580BF6A73B5438,56B8AA6364BE665B,45A763B9F2BB2EBB,70550E88AAF47B54,1113ED504DB68A39,EFD64C0EBB203C85,72C5746C6D50C967,00000001D04526F8,173AE3A3E4D29A14,4FC08531B14894C2,2BB6943D41B77E4C,C60B7947357A1059,FEE13EE61E8C8270,2DDF3FC21523A5D5,5B2C80D52762534A,0C05659C05D75112,01707B5E8D50B112,00000000AED4D157,129912DC5725DD7F,D79024DFF1DC5D86,914AFFA9E03619DF,9D45298A8962466D,DCE21C177443A7C7,BBE999192FF6A1FD,3B8AD78DB84889A3,BA4BD52BEFA2C336,93BEC0796FC5292E,0000000151D8EA97,938B7C3282611D13,7D7ECC23CDE6A3F3,9348EEC84B646AB3,5467E1B5718FA132,4198A39BEE18B7A7,85C4600D76B961F9,AA9B95C1BE557CAE,3460072FD4FB6075,2057FEB0EC4E7463,00000000D0D12CA3,5E33DE64346A1A3F,698D840698B23FB8,8B3227701265BC75,375F529E7430429D,F33630379AE4BF5E,615CE847616E5223,343ED5E9C6515DBD,93999F4E4B2BCE39,52CB6534D1C061DA,00000001664DEC66,833F983738BB6978,65BBD8734273AA2B,BCF2607465189440,687783712C2459DB,43C71F14A1E7678E,9FDF27F8809D6DFC,1F0D66FFE610782B,BC61AE3F47CC6F1B,4323B4785E3CF0D6,000000016A744617,87D86D94C2BAA4CD,DBDB4DF123C74BCB,F45D5266823DC2E3,0CCB019B1CEDBCBF,D3B88364813CFA4D,E6395C8105955B7D,18159CF86CF9EC6D,A28C6E8D1D313DD2,F56084A93B15FF2C,00000001D514BF4A,8409791162D361BA,487D768C7AC1E482,1F554C58F94048CE,F5634804B5438FC0,8D05BA83C5849B34,45815BB9B6004CC3,672C1047DE6911BA,C4CC5D5479909E73,5EF1A717D9116BA5,00000000111265B9,ADAE2F578A2E2AD3,FF771FA03003142E,609CD73411423D15,6D4BE9157F610B49,81C75B8E7860EC75,E3E7F9698EC9EECB,A220BD04AEC40441,EEDA26AAEAC06C23,0A85120DDFC7DFA4,00000002725FCF2A,F7BB455930446A32,C6AD03D12B1146CF,760DC0B7195B5BF8,2CA415689FC8EAB7,AAF566EFA5DC6CD1,07FCE2DAE48CD742,14659C4A5E65D491,AD62FA52CB1FC3A0,52930AD687010DC9,00000000FCD2F0C6,C6E9FC0A2CFBEC98,54316D9569638DD6,62A9D3D7FDC7D8BC,696E3AA2649ACCD8,E7C4B964722E6B2D,76FF89F3039CA59F,871231730BBF1F65,8F7805B492E760F3,83C35BF6E608BAE1,000000018F632AB3,0A0DAE0D78BF0C7A,A3B6F7073F6285E8,D28DF218D83FE230,2A324434CB3C871F,DFCCCA27A2C69EE7,C615B8087F45DC84,37F01462934036A1,3E38777D4BBF7ABE,FE545C5ECF605868,0000000167EC865B,C7E4E616FC2BA697,A956BDA04FAF8951,6DD4DE21593B83C7,71DCA1B872AD3CB7,E544AC9DDD5DB05B,728E0C70E62B9E52,46B737E74BD4EF44,A8108385C01C6C25,CB1240AF86E3F514,000000017E05EF0F,381534615470A497,BD73E08E287A8E19,0B227424C0E272D0,97F69A550D60DF9C,477B480280F2E737,A07BD8742AFAAF33,405E5F29A48FE89C,A80D6F41C0CFC5B3,A8AA14FF7E02998D,000000023DF77E02,8E7927E43F709BB4,E4043D1E47C74DDE,3DC59C1ABA14F25D,832BE9A9C8F8E0B8,7529DF0998437FBB,EEF302CC3E50AD6F,E79E4CC778FF3445,FBF1106E7041C71E,E74653467A294DEF,0000000238D50294,20C4593A560E8236,3AB055D2E8886334,1773C82DD4265E59,AA413906E727B221,B3CD8183DF469162,E562CB5BC990B5ED,6130E72E24EF7106,05F0DA0CAD7F6DDB,2CE4B7E0A1130D7D,0000000056EB5995,7334C271034165BA,00F646F9D2EFA601,55D4884AE5C3B9C3,74FFAB233FB08D53,B3778A1EB5E8905A,40A60ABA4E0D96A5,6078491644B21BDC,47277DCEAEA2660F,61028CE2944CD62C,000000000EDAA969,45DDC60D6BDE1BDA,D9733926845F3B88,8F7494B93855CC93,8434D63F9627BA4D,5D8DED792882349D,7B2A0ACDA0A832F5,CCA6B30BC2274E85,835E80B080B32F9E,F76050D2258BF391,00000001451B545A,4651059AAED184FE,2D9FFF707C26AFAD,4A586A5D9BC45C66,18D0FA779633165B,CD7EBF1A071BE0D6,F8B72C4CC28E17E4,A30CCEA53DA831A1,8019D31DE9D3FC98,BFD6D65BBCE228C0,000000021BF013A3,C6C81A10149219B7,F3E995A229B77205,6B28BD7F602E94EB,A7F2DD2B47198D91,0D1480449F10D4FF,B251EE7214F409D9,DFBD10FADE771891,604387729C478765,9CC4CAC457E17581,000000009AA90FEC,B3E3FA6871DFEB21,151D1B4372090D62,227F94584751BC7F,B0B43F9BF1B5DC91,20F3E696E686241A,6666AE12E86D606E,B2171C97FAE57825,F3BC60C8D009EED1,936EAD1582C89639,00000000CAC88729,4F29FC9DE80D7D34,83517BE2E1C9B8B7,1E3289FC1DC8917E,7172D23958171EFB,715D8F3F574D204F,8A98EB19114C5DE1,E1852F739080F907,46F76728189D31CB,F8512FC5BBCA4226,00000001F2193AD2,CB77589C07FDF562,35FE2BD7DD5EA1EC,D2F95E779194BEA6,9276FE38626D5644,B1366339391CD1D9,645A7D1C72786222,F74E7BAAD4032CC1,CEB842E7C7C197B2,E4D7AACDC35336BB,00000001C5549EAC,35F237CC3BA012E6,744128B1150AAD8B,2D09B909A587E514,C6B593705E2A7605,9016F196DEA81347,BEC6CD8FB29D899E,445DAD66F228CD58,6ECF82B5E99E0E4A,07C2A42DDEB367D3,000000004FAC54A9,E0F4A94EC0C2C1F3,EEB440DA8429A264,2B616CE698E27B7A,26067B106C92A9F2,CE2CED1CC7F99EBA,9A5DF4713EC0B55C,4C13476E3FD5DEDE,4365D44592BD7274,2BA788F59E28F022,000000008E120F71,25E3F3764243294B,86E2CB5071A8F5D3,82712B4C28CF7CE2,B5AA311832FA0BEF,7AFB972F189BFBC8,139315D438A2B420,DDB28B7084B66808,018749DB1BBE5CD8,FA585027763C8766,00000001C0B718D2,AC5E867672085909,59FF2C5331313A71,F7B47E8ECC19BEF1,E3C8845476AD70D5,BC64CE8FE1E5818E,0A5562CD09734C76,9A3E327B92F649F8,4AF716C17C9F4897,AD2040A7E7CC8270,000000011843025E,7A4FA666F979630F,D2E431B21395DC6C,07860B3415EE8841,C18F554EEB8EB3D9,86B6DCCED42D7A12,AB0A9AF6C88ECA6D,B036FB6CA77EB4C8,8286B6B0E6367F5A,6F1C32C8531108AB,00000002745B090D,D4D8916931CE0593,2790A8F83C942018,3BFEBCD021B811FF,C6F2B709BE2980E9,16142E40F9B26807,8A3F1AD280880880,00714AC49E58954B,FA46A782782FF632,6E36D79ABD37D517,00000000D2FCB6F0,721605FA03780833,ED891A0662CE3C4A,A8C1806134FE5C08,36C1B6DE77F1F6DA,F0810BF9D0CAEE58,08839A8B4C050C0D,FAB48673A3743B85,FA44443D4C7B03F5,810D3B7C9516CE9A,000000022A9E5AF0,BC0E073718C66411,30280C6F57D63F97,4098B2E6B155265E,D095CB9E1C984A12,1C6380878586A556,EDCA47194540544C,854BBF97CE24406E,0A366E2F8FBA9752,7053D5E17083787B,00000001710E1CA1,7EE02AD56FD1CF6D,1C0234F5B5E024AC,04B632A062ABCB3E,D8FE75BB44B2B0BC,4F1E1269EF0E2785,DF3A5ADDD74C9A4B,FECDF2D3DDBA6D29,79A41C792D6F7584,6F6AAABE2988D39F,000000017C5B3F79,CBCB5A92C9ECC589,4F6058B17EDC4D1F,D54A66407418E3AF,AE7CDAE0A6807F50,F6BE9A4764DFF04C,C92BCAAB9DD82B17,94C19A2D2EB6A382,A3065E1380981E08,8D95B3951017A09C,00000000B0024219,9E10BBE1509BE0B1,85C0CD40F9ADE643,6F7E57F05FEAF3D2,522DAA04889A0F28,A24D083466B12B22,AF52C5C71DB4B6CE,758B3CD8D9F5466B,7B91FD7C4059F32C,DFF4C57D213B9420,0000000012D46C6E,638488511EECF114,559BD08E3514DDCA,C07FBD7A4B251FC0,B127D8CA2D07E564,2D716C25DB95F879,1318E23ABA64A633,6C8C2E161797527B,23A685A21EBB7225,EA42D988C2DFC2FE,00000000C7B1C7F9,5B818BDE2070E5B7,E1C3B0B8161C561A,6C8FF21A25038EAB,ED235211B5115CCA,9AB8A18939FD28F6,D9234D1F379AA1DF,DDE52807CCB386CD,1A8EFF0535FECF76,2DE3A10FABCAF1D6,000000015E047AF6,99CEBFAD916D8FF8,2834365231A8730A,1E089D16F54CF30B,AFF4BE345BE493C9,ECA379289B652C0A,69F9390F0112448C,E5ABE39923BE6D50,A95841ED708C7FE9,B5F159B28490E0DE,0000000109D426A0,D3654D53549D00D1,4551DE933B2CD706,2FCC31F0018B8C26,4C2122EA5F465D1B,9279D02CFE6CACB4,8532253A95756FE7,9990031A86F47B3E,FD0B326DC32B4B62,9525602DA3C18CD8,000000019BB9FFB3,0B2616CABA52BF01,201AE6B5477DFA36,F7A99F770C1C8773,6CE7D624B90FDE78,508637D17335757D,50D0072D1C63BBE0,0F3EC08A62A84977,171C7BAB1E517662,B2FF64EB3CF20BC2,00000001F2ACA614,1F1B9F5DE126E2E6,6D218D6C0CFFC91D,A98A9232207A6E01,C42FCEA462DC93F8,242D1A2DA2109AB1,A2C264E8298A7AB9,E22A589D112DB326,7748FCC2CA13CE7B,5C209A176274C247,0000000243B3FC50,E661B794DD6DCCBC,FF78E0D9EA47EC7F,3C7DD37176F065DC,1468726AA7793777,C7F0843541B95822,1EA9A8E3EBAD11A0,7A8E7C57C7B9FF16,E5642C6A51E58D82,963F8C01B8DB7A82,00000001F1DF152B,C10CDAC14BFFD71D,57C652915B2DD4AA,4F84A53B7BD1138C,F66B544060ADA373,CCBB6468C6B7A983,2CCB4F16AB827F08,2F5CC99267FE155D,8E282B78B140C849,20446096E2621EA7,000000020D77EF40,51B17E514A123D96,A203684F92511712,9B40BA5CD3D4E77B,FA58D7674A6A0465,7A7A1FCAC272AFA2,15E2E5375CF8E27C,9582986806931F73,2E75BECA7B63DB27,D0C1DCAAD3980EBC,000000012842DC2B,2FEBB684ABE60A4D,743D4DB3008B9499,647AE8B5927EC5C1,5CCC3F60B14BC37C,90077D57CD7F8DB2,48E6FE7FCF960CBB,DBB922FEC548A991,08527706220D3E6D,314FB49891108CA5,0000000073AD1A33,B083E84E45A32B67,451B916A35B20000,68A57C30A04B9B7A,582E50B55EC6ABC2,47E2EC1BC1F17E09,CCBC31D8AAC0EE12,87AB0ED53F9EF12C,7F293A53CB630E8D,1DD7EC633EBFD557,00000000A5B330B8,57FE624EEB926845,AE49D76B534C88CA,6F00261EA82F1FAA,6DB3F7934B001290,D0807AA10EBB5FA5,125E0E4759857B7B,B58401601EBD62AB,A63206E6DD031060,2E97B6BA9153A568,00000000FFF24D9B,FAE2FD53EAD9B12F,29F46643049A9F5A,82BD2C480F065406,8E0372A0EC2CEE1E,70CDB71CC204A7EF,2278BD5531BE9BBB,B74F6541C8DF27E1,CEC39367A3325194,ABA63DFA4B9CC384,000000016A4EC24C,2588507EBBF83162,80BE18BB2827AEB4,594ED8244FBB4F81,727C25F35FA28435,E586257CFF8B791F,5CE3195968A0A6B3,57FFB279EFC778A2,6A0191363B88CD99,16DE1DE5C82FEE55,00000001E3B7E6DC,E25543158BB6DC97,9646411CEAD2CB9B,29E29DE9D2CA72AB,34E25B57EFFB6AB6,0A98816CDDE09D29,F2679833E4A2F05F,B8BC6DC44BC7C68B,43CC92EDF6933F2B,B92B0A0699D66124,000000002D45C53D,654162C74C6D90A3,47B2F6E163F15D69,1F00A76997BD1776,399ED8D7650DDB6B,1A39AA67A6201ED8,4559FBEAE165F467,40B1202384011DD2,1193BF655DF223CA,6D7CC7B95E5AB6DE,000000023CA6CD29,E229217979FF653E,49651AA62B57223D,09E345F71134D95D,29D96A8A05001382,FF299AB1BCB60460,65575D80F7C02977,50E9E027C632F132,BA80DE252F090CA8,20DAEB4D14905D9A,00000002161739ED,D123AF3601197432,8AA6A601780C9DF2,D499F8E7790AA03F,D09E2211C502E6CD,E9D3DA8FCDDC79A3,A8B8F99FB409EFF6,D5B39CCCD47BFDA8,59DE9EF3D8DD7784,4D28CA1441F1723E,0000000273AB3D18,DAEECB35D2B02CB9,B4A0C7B973EABA02,3A0DB50D51FFBBD3,788EAFA9F5710005,311B6E06B990F701,C34C4726E113FE90,C75FFBFD43587162,F859D118CCC5D2CF,A486368040749334,000000019EC8DD9F,7E8863FB51FB1519,D87930B571347BFB,EBC76B8C19EA5513,14DA5DBF9DFB7053,4CFE16EF39B3E8A5,63B7F56E0BEF3568,D689DF65DFA75AA3,26DB13A64BB62058,0B030A142E6C0867,000000026C0D2EFA,2845C8F4C62889E9,39AEAB0EBB9ED805,3A7B6D3B2FD94475,8BE56AF69A310BBC,74F357356EC801A4,157AAEC8131301ED,5BD4A534BE76F0F8,5B60641C993BD21F,79C96F2B43B1C3C9,000000013BAFB9EC,875BD89B8533EA87,CBC9FBE2F3AA292E,753F9306963951EA,FAE4C21866AD03B7,A07DB75FAD11801D,CB0D6BF066F006B7,76A9E567CCAFF1FB,50F27E9A61470CBD,379EA766E1765AC4,0000000185AC3C37,E1F1B70C51C588B1,EC8F6891AB648669,D7584108151B13B7,C07681F3C94F803C,AEAE8540D749FF6E,1CE81AA77AC352D1,3F0D07DC1B7BA657,7DAE37585C2463F8,2F6264E6E0410C78,00000000D63C9DD5,4B6C2AB19BAE66A3,3F6D86B52528B591,5D3E482D4023F483,48B63EDE78C71897,09F7903662C9ECF6,E8A0ED425AE62BAE,AEC24BE6B5E428EB,B84DFF81628B13CA,505B7DE529C5208E,00000000C5707A7E,8314FFAC5C19A52D,2DF633E103CD9C7B,AA8ECA96D0FA8C64,A6FF11DB063E4EE6,DE62258F0756524B,DC3E39B7BC3DFAB1,8563DF2ADAEEB447,ADD0393F91359F6E,ADF83109FF776B7B,00000001D2EDB0AF,14BDD834043F0E1E,E653B6CC803E2FF6,C88ADAB19B7A7EF5,A3C9E260C07C6D0A,50AEA3C2429A02B6,04B138E71DB31C96,3B29DB3C97FAB886,9BB004101AB8F5C8,40D96695791F19EE,00000000D60022DA,7BA710BCC61D5E10,A0B5DB53895E7D0C,6EB80F1FD65514BC,F124F60495037605,F345539A4B12B006,07DCB7BC2A3D3832,1589B55B4B599DC5,74DFF4536B3B6BFC,2F7D94B79BAA3340,0000000064B01176,AF3D953FB5AE467D,C193F6334B8D0B21,7E0182B7576E71EA,1A415B94200BB6AF,E4C129A1D9D9EAC1,05D4A789297E7FAE,049700F701539A52,9DD1C01E146837EA,E5571F41B880BDEB,000000008217BE1D,90A23E7A2ECC27EC,CB46E821EAFBDFE3,A3A418E22A698007,A0875E285BAD4BDB,5AFA3F20BF33F0DB,2BA40BACBAE3EEC8,18EBF3AE56A8AAED,DCD1C4F919334461,C25F34108567E5BE,00000001D20B2AEA,0AD9F0E64EF776D7,0B3F902A2FDAF7D3,D60376DDDBE06F47,70AB5941B9FB1257,F4291C29F6172FE9,133C88E429C27FE6,E20A1BF2DA1FC41F,308F065156D13503,58C7C5A5AEB60D37,0000000128AAC3BC,9B7647B69B9E1689,6BD7BBA84BF121D3,D10C6EB3C737E658,DCF99E70C5306E36,03F24BBE573BDD55,E08C754DA34987BC,C1659F9F8D2C5FDA,DF9C4AEF59621F69,458714220393DE2E,00000000E6DAC154,92D3E76B81D62760,001397970C1E999C,E8192648397600B0,7E9704BB46A37A6A,B94E3F8768F282A5,B156DEAF49452E54,BFE2923C1E6C5D6B,CD2FDE937C79D70A,B8149FFCB2B3C4E8,00000002769ABC4E,70F068CF823B78F9,E48B8AFA97CBF6BB,10A092E9CE6C58E2,F9264CE67F608A11,2869B9141BCF81AC,E762F2C68938BE29,2134D096E991EBCF,1C3B7CD0ABBEDC11,021802BA399320D1,000000026BF8E741,875A8B59520F133E,ADBC5F1CB4CBD8A4,E3D675EA9DF9EAE7,821C176A5040511F,082A15F378A8AF12,7CAC37D4AA5B8570,BE8EE24F1886A1AE,7E1E1F7FA7CDFA7A,54CA794DD8364794,000000012B7D9EA1,207F34CF71366E1C,FD8139E1C2A2F407,1A9BBC76B3011409,CF84CD2EBC75EF08,EF88824D231CE15D,55B53A43F421C272,C4634C3D00171279,F0E170D8E1ABC027,DB1C0171BB13CCAB,00000000EDB159C6,1A52F7D9C903C7ED,77E5520B8C98604F,D91A9F7CA2CCCC67,E1EBA52165A7906D,6FF9452858A54C7F,5D10A2245F21116E,BBDAED156BF01286,5D81943F4783EDC0,1759C3DAB9D066C5,000000007B759732,C1CB1672BC0A5F6F,4B5E9BD6D5902D19,79999418D250C748,E559909E7B8A93A6,707CB61CEE014889,1EEEC3E1EE166C3E,D65FF51FD1D6ED4A,1CA2F710AAB2D2AA,712DA79A58495D1B,00000001BB48650D,3B843AEDD08B5766,1282917D11A43E6C,4C2AE39E6F3BB660,D6909E57BF6298CA,709DA095B6012003,45EBDB99F6F2C102,96293E9F3C37B230,38A3C3F6DA68E611,469C1AA91088EF67,00000001E9CCC49E,741DDC7BF9D64B11,4A50CBD106B0524D,E5EBF673902C8ED1,58468651BE4FDF4C,29D5B3D92FAE978E,68F42C9B1A664F3F,C124902FE5DEFCB1,6F0A8676C0230FC5,CBFB01598543DC7E,000000027B30B10E,8E67416E27E933EB,CA83FF806A825B77,EB2FF4053CD5484D,98E3828B81008320,F7B0CA2150FA0859,78D01EDFB43B8CD3,7A532F59CC39B03D,07D07C7CF6D2DD20,7D711F1EAED41AA9,00000000AAA4A769,B5899CF6EEDA71C7,E0461DF37867E62F,61B8D2E4FB04877B,387ED3346A9B1FD3,0C3911133EBA6526,CD34E2FC12DE7286,7CC93878028E3BCB,F36B5C066924E7A9,8B8DE667625EFF5D,000000012818919A,E5A4874F2BBE9A94,3C744ABD4A55C72F,E74476ED6C5A9CB9,DFF022C04F136220,B875F087E86E4685,9BA6F9A583B4B101,D5C25CD219D7E436,ECB31C9E17194734,E08413EBF8A38CB4,000000016A08F353,D07EF7041358C195,831C1354030EEFF7,564B1B777F0AC292,1565D9F83BF666FB,B80641C4B1509DBD,1C0331352E8AC29F,005142B97CE41F19,2B958C3870D1CAA1,2AED8E5527584D3A,00000000326B83A1,622580B60101A1FD,F44C93102CFC73DC,C66683561DE63383,54D09120CE18444D,D0DBC0D7AA66FFDB,0A1077030D03D767,84E8718416BF7977,114573312E51981C,45D81AF7C6F5B988,000000014C4ADCFB,D12E5DCD177834C2,B554849AB3FFAF8D,F23FB64B08F38677,367F9D618BF74F93,9592C82CC4391C3E,1B4A411A2E677B86,03706EFE559B2265,4F6B1203EA76C882,D8CC61CC715B3D3C,000000004A6AC977,F98D1CAFE7081C68,235312DE2A85BBAB,49AC772F6DED6AEB,CDF1E5044B4C5D19,CC614ABC88E45679,21A4A0E40B9BDC6E,72A1B64307E9F6AA,B581825F0876DE0F,8950B2033A9E4BE7,000000010604EC77,DA6F652D6B01FAFC,8483B89EBF538EFE,610C5E4F18C9E851,658EB3BC6F6830B4,4EE9415DD3555C7F,A0EBD3262BAB2237,2DA09AA7591F7233,E6A9E2EC2E468635,969A11B7DA1A24FA,00000000E9F90606,A3A851772A388FA0,6FAE2A8CBB7D0325,F79B6E24542F3255,BAD461121C0D3EBA,0E38A7497B975C1A,C989BD24F3312AF0,7ED1563FA441854E,D1007111CFF08691,B0ADD31585F87B12,000000009E85A6F1,8D39DB9806C46CE4,530AAC21174714BA,555389E9048C83C7,8358E1222371EB0F,1F2D4C6A9FF6103F,1731699673BB7F54,93BFAA356560B242,B785A9DC368F0641,DAF6D75B8A2CC2EE,0000000143157482,002B52B113AEE285,B106292319DD8F13,914783964916028A,247E424EB1B0221C,A22699FAFFF38615,7B23889C6A545239,579EE0966E8C6066,B4571D2B878B84F1,65C14361666FB615,00000000CF48FBC3,35DB929C1A0342EE,C609BB8A01078ED8,59C8A75C18A2E264,F2572962C4B5228B,C5E6B4231FED1023,80FB2E782B79D71A,8E47E3C21A218317,D1ED9845D2E0E87B,3DCA5DE318BFE927,000000012ABC791B,441AF256B46CC035,D65DF7288341D33D,429E27C72FCEF2DE,0578FAA344280523,99BBD7B7A712E7B5,AAFD9D8EA43661D0,B23711BAB2E55C6E,6762D5C9F67C117E,1E1D7DC29A6D0CD8,000000024EAD681A,28B82C8DBEBC68A1,E3CEF565E34E1CE4,EF78C20126A7F8E9,F49F4BFF50FA9AB3,C7312F560CB001D1,D0B0AEF4B9454C87,BDE16416FD6CAA7B,B8345526E3F697B0,C79161A882B6F034,000000022B40593E,E5FBA73D9257FF3A,62AB80AC3FA21E11,6F83B808DD149784,A1CD42AC86EB1C35,3E5ECA386FA33B1B,5B9A37EB0175E7C5,F90BA3A7249E0AEB,348669D20E56F94D,9B63569338EDA5EA,00000000C0DAF815,43CEA49A7F6E3099,ABC331DC9B8D0141,D4B2CB8CBEE54047,47F4BFA4EE6FB095,02D121E3BC68667A,E2F5DF47763C056D,F05277654DE7BB21,F91F631B1573D95A,D924D81EC8430106,000000006E77FD1D,398EAC5A762ED976,3C879202341553DE,2667CD85D7275AF0,D9E172CE05CC4910,6EC0CDD4A2285CA4,080A09626BBA98FF,1E17029E96397637,4EC2197DF84C40BC,F4F9D44ACF1FD209,000000012B2A3407,AF0BC1C6CA579948,BD10F0C6749DE05E,83EF557F85A46C2A,9E034A1F1A29CB1F,0CFB4EB2823B08DE,881AEEF3B4E3B81F,E8B6579F60A158B7,011FAD23FB3A8D76,B51D86A4E5D4FA3F,000000022EDFCFA1,3DAA1CAE4BC725C1,104BEFD6D64D6094,F2FC7CA6923C8888,A69F9F0519618C4B,8A2D8C701EB6CB5A,0E2CAC2896718FD3,5EBDB22E09B65F7F,55F9D9323807E19F,0DF7AE3C7C887550,00000000815AF726,7C31348315E9F58D,8DDB54DDFAD40BC7,93FE2E342F9490A2,7645238BD5BD3B1A,18235F710B2959FD,04E2C17408394041,8D1EE9E6046C3BAA,45B33534EA340677,DF3EF37EED19A2C3,0000000279F1A1EA,2212A3EA0D8BF977,3503E17D16F10AD3,EFA6D7163807E2B8,80BC544422F479E3,D01D779240C62829,0D1019D52515C48A,70E7C77FA8315EF2,225EAD3164EE8516,D5337F98C7FAED7F,0000000272A0F008,B486EA51EB14976A,42632C76BAE7BF37,78A5DBDF41FAE42B,0F3F9D6CF6C31C64,BE865262165D6DA0,83FB7DCAA317D3AA,E1BBA7047E642569,C2E3B854989319DC,6A3A4672C76C055A,000000025A5522A2,06FABE79CFEEF77E,CA5522FFF9EF9F08,BAE8592399F36FD4,09E678E6D0F10B6B,15422A9CD661048C,9A5367D9D66BDBCC,FF6BA0B0298D03FE,2AD82190B7CEE50E,5B0320B5B578B18D,00000001A733646D,E8A84AB9A443EE95,6A0F845E9C65B7AA,2BAE4278C63A9323,25C3872225DA9438,9300B5C2AF58571A,1A3C507AECEA3487,98E1A661E88B3AA0,AA69FD4613BC88CC,0D1AC3E12D1AF4F3,0000000093C78CD6,ACE9673951489A39,69E3DF59623A0EEF,6697A2A0769AA6F6,90D29393ECCAECD9,25C1D69ABEFBDA99,5CA4BDCED41BC5E3,A69FCBA1FAF49DD8,9757A05CB37DCA7C,9F150A879F9C13EF,000000005CE82DFC,531589BF50D24954,19D2DB2441510426,D26677F22E7FD15C,CA0AD5A5E2166880,8567E1063213615A,2C34327F356ED7ED,A243E19F6471934A,A67E590EEAC4C8E7,734A0AA334A2A7CD,000000022B34B152,598DAA29AFED4D8B,CA4C6305029398B8,7C7C8A6722CCA82A,43DBC242217C5BC5,5287F9BF13588A0A,B01C88D3CADB296C,6A1CA754800A3466,1F0D5A88FA4566E0,0CF86EC9F403793A,0000000179A6F054,E8EFBD8E1B8E42EB,CDF4F18BEA2AC363,928B8AFDB5D73648,D2BE8F46EBAC6D39,B8BFF27415DA67DE,8443627A92086900,39706D8D91D21CE3,FADFB356A14C0A87,2F59A1D20C958982,000000004D20A4EE,49954469B5AF8D1C,D1B07FF14FF0B035,ED7FB70187A4D04F,E7CAEB607639F1A8,B480E3CB018001F7,33B136B450DFC2F8,A2DFB65B2F80679B,A0CCE82F56D215FC,8A115D33C8911860,00000001A07BE40F,2AB1DC5F1733C374,5CD4B1CBC8D307C7,62AA37255554F9B4,E87D2E8FD68557CC,F7BE0D07FF987F54,2F3A5DD7F07458CD,54F21A1A7430DDA3,6FD8A428EE534141,B2F52A9277CEDBE6,0000000058E65DB6,2EFEEF0A8AFF1AA9,3289497815BB41BD,723FD4EC5520D80B,83E3AFBC7FA18DC2,2CE7818E98C56F73,8F776F50F86A8AF9,CE8C1011A142E232,705F342485DEEC55,3FA064296BA26E28,0000000174241E15,E80CCED26431AE5E,46C0DAB7110B4FBE,D348E17FDEAB7363,899B369D88D1D572,92CF75D112092BA2,5D69930DCE8C3E12,121127C294D367B5,2A6931B28CCA4CA2,FB5B2A7C9CF906D5,00000001DE0D7A8F,C19DF6372CA8DDC5,ED382528DE5A766B,1925B595BBCCC2C7,32B59213B80D6BDC,01C2908508159409,C40364286D4348AC,3A269535BC66135E,BF2EA9DF8491273C,EBD3CAB2C74057A7,00000002376564D2,CACB87666F315089,18E17987BBF4250D,4D557079A79E3D30,C3EE7732E0C88EAA,5180BDC60EA0BA54,214F7266173E1547,0FEFF2FEC2AEC3CA,CBE92D8BD8399CCA,F0D2C0624C4CF9D8,000000022034E87D,DEACECFBE9EBBFC0,F56E6E277EC39979,2DFE96ECF08B6659,180D290926FB45FD,DE4C506FF31C97F4,32B2DF5E58D8D623,1340845CFC8D717D,DC695546E34CAFB5,C60BEE6310EA1BC8,000000016C4B4F3A,296C8C003E599B6B,C8B7B227D6A614FC,DF3AE80B0EAAA3BD,60ED3874FF0220C5,CF8933A986CEA4B7,B7B06D11302A0811,D9DAF06B32F58810,FB06145E73C28722,B94906FB17C952BF,0000000119B2D71F,DC061C518293F10F,A14CAB15F79E20CA,FCD077DE28E25C0E,3A15EB727A9571C3,6C37A355F58AF07F,734DEABCCDA2C70A,4A63FBA38F3411FD,E62B305CB30A4298,E39FE08C46BD726D,000000022A3FBB52,AE2F76CF783F21F0,14628614257B6293,5F266CD53A763338,B8DBE7185CC8AA3A,6DC091A77F8C2B76,17E097CA17D02561,A09D183CE7A4F15F,339A551CDCDFE0AB,FD9D642B27E7BB3F,000000010843D086,7F831B04DC819A01,335E54AD888B84D7,0B0BD75D39D59D03,76503E3479B1A62E,0621450B23483C4A,CF4AE93D9473C0AB,942DE2F3719FFDD4,463215E8AA0C43C7,85D6008C2CB76059,00000001FF84BBD6,F0BBEF43EA8A1645,E502833A40269047,9FBAE1A10FF70B5A,B34D28323B3DC49D,54BC26175BAF34D6,D61A90A1C5E58A13,195D825CC6510534,EAB9D2B25BE4DE4A,D32A207EEED6B835,000000019A8B28C9,28269AD4BD18A973,99A2F5740643F611,EB7539219CE5E95B,C00C8592F4D5359C,5874908EE738FE60,3656590B07ABDEBB,2DCD1CA99C5FD79C,720B85E131F8F3E7,9AD8432FB9BA833C,00000001C8C4C7D8,141949B1049BDFF5,2C4FE2AB3DA05F60,6C1EFDF642FAC9F6,6127FD059C97A4DD,AB82ECC0C88A87A7,F3A44B1F344A4A44,16E2139041201531,5E9F41273742BB9A,F21972F3162B87A7,000000002B7654FE,0422B435BBA57972,9F288C3AFEA2765F,9CEC174077410485,3887062C4CD0F486,A86181F7B9FF0514,90512088C1B20CD6,AB57634D8F7D5B96,1B8B9D18ED461F8C,3D2A6B925F238A71,000000002A229D9B,39742C67650EBD3E,E780E7058B5D226D,227F8E8CE3CF920F,B659145C92C2070C,935A6AA4A45D47D0,8929F714C109D369,B80CDA172DB0B8D6,EB23E7B652AB59BE,642A6B6853A52B1D,00000000E1E3268C,3F1C9A2D7AEDFDF7,2BB6A8CB9D6205EF,FBBDE2F4CDC34E32,FB6D0E77F983E447,8AE09617F5F8C55E,04E9897A59DAC99B,EF59BA252A94CD7D,31C1358D7B05B973,C0C0EB9A6D049603,00000000593C6F62,8D0533021111899B,49D6BB365EE53481,786E300751F1681B,5CAD36B6E18648FE,7F1FC9E1C7611E80,BD0F52D719E3CC37,43C9EE3D7558D7B1,404CF36C236C3083,F2C1BC370F3764B6,00000000E9E50B3A,03E96C9E2B2D9BD1,A66CBC60DA6BD904,3E20B5BBA594246C,D61647E14BF12E58,F8D090483584D60F,E917103E61501992,BEAFC61F4C1E1230,83424AA1F5223D9F,E8608E3B56268E5A,00000001E4C3221E,EB852F64376A0689,16F779B1D2DBE388,B87D0E329057A7CB,CDD4024C3A6AF6B4,2FDFE6FB039FC7DA,7F7E00F58D77E268,ECA41FFF2F05DF99,DE906CCEB63818CF,5E5726FFE77CBAAA,00000000E6E37189,8368EA2F402E9BB2,B6CD87F47CA286D2,220DF639083011F2,92B4DD2BC57CE716,C318F5B704B9E9AB,D700DA176489FAFF,DDDF83CD46D249C4,57617BA2C2C589D1,7CB9E89F40B407B8,0000000018D85ED4,F58145F09BC552A3,ED08EDE5766C5B60,D76087A9364BB90A,3229142C73F513FC,13032061C73957A0,E8BD8D7FB8B99A63,6CE76EBC49D17599,6FB0734BA4BC43AB,F356A0C837F8CB33,00000000CD48013A,79FBA8239A656E38,2E00098D002AFA3F,D9410214B08DEB69,B21D4DF44053B1BE,15B7C1A9AC9FB97C,1485B51F3708FCDE,A1CD5186D6E77A27,FEF971DC0E8664B6,48FEA79B20EED90D,00000000880E329D,DF76DA746C707995,68F9532AA9B35343,0B3A393620FFD813,9C85EBAFFEC1D276,BB263843B359B6E7,49CA13525E968666,2F46031DAE592DC4,E2BDE0C25D4D88D8,CC84BB306534AADF,000000001E54D330,0EEA85A571318427,935F2D295A91666D,45AFBA6BDE5678E8,6AA8ACEAEF6F8EB8,D0E79A9458667899,B76D4425DBBB4BF4,4910A7099779E193,2026544E40F5DE6A,53E8B6385FD3CF50,00000001E1BA9701,2AAE5B52064C30ED,8F174F06A12CFB45,D0D24B1FDC8E866C,D5EC855203CF1F76,AABD59A0D8E0FEAF,AD4981CC7D3EE58A,1FD1E3012E66EF98,D5E2A58005A6974E,6E8DEC2DAC6C46AD,00000000D010664F,F44A5E2C6CE64C7D,5B0F6D678F51F8E8,D0F1B551F05629F2,3EE4FB4E1975BFD2,D7F84EA660BAFD10,D3B8A0C9C51B5883,235B26364BB231FA,52BF05752B52A44A,9EE02B5B98F416F3,00000000891EDBC5,9A1A5A083E6C4B6A,F4FF9EFA5BCA0872,79ADCD84F50D2E24,9CD0354B1B797181,8A6D0F5B22563533,B37F14EEC8919C58,8AD52AD2E47991D7,445CDB82EEBA59F2,2BFDC5BD2A2F78BB,0000000049460684,9013C1A9FC3A5A18,221A4B74536845EB,1D62FB51C7FD1B3A,874B1CB16CAA993E,B88BBE5A9C15A230,F5D982873CBF2B76,0624DFE59916E303,1E68CA947C7FAC07,62F11CABAC84FE82,00000000BA9DCE5A,918950DF3B9CCEA4,4C740AB818D481D3,24DB5C93037D8EED,4141E7CF01256F92,D501622B8F926FDD,E7C78D954285DDC7,4C72A41009AEA27F,72C219E8E89D2EB2,E25F9A9A4F9CEAE9,000000007DEDA2AC,15845B98BCF2B197,4F73945D190C5774,2126D862D81FD903,3042A1BA4C8494D7,E7516E6F77FDED6B,0E5BF44BB5AC6466,C95FF4C9B11D57C6,E0EB58DC7B948CA9,422C4B0B856B082E,00000001C0B53776,098D2C615ECAD8AA,46A10CD7F8F196AC,BAEF942DA7187E42,388C2373102E908A,FEB0F865A973BA17,20256A2946EE2FDF,0845F6FE6111D3A8,050528AAC5DB776D,489FF2E76C85CA10,0000000242350B96,D5D2EE11EB46FBC8,252CC9D84F256466,441BD443D7FC447A,2EC23DF5F97928FC,FE5881F933F6586C,B642566BFECB554C,9BE17F163F19881E,E01471FD10CB93D4,D5D42F1D8D41C391,000000005C1A7669,18450D29AF651E85,C46E39CC2F04EBFB,7D74A9BB52ADCD14,8DB79BC5DFDDB384,27CBC02566E0A797,90457F85669D893B,F7E948CFB888E104,683CC7C5E0780B5C,7E21EF6F096C0BF9,00000002258C6E7A,47E59D029628DDC8,CA3CB3AC3365F79A,4EFBF9D78193E6F0,FDA3D488CA46A85B,A49D9C190A90AEB9,297796BA19B9C613,FF281297DDADC4F7,EED0A9BF500D3786,949F874FFC1F0BF8,00000000F4749955,CAFD42A08BE7A2AA,B540099E8EA7549C,8E93A791FFC7BE7D,E29441A345C443DC,0AF502476A82ED70,ED74AB225B16AE6F,62ECD6AF4C4886A2,AA37A9AA86C8B806,270279183718ABE8,0000000119D5DE1D,EA8BFC6FC75E265B,3C22B64472144594,FE9F388354F20C04,05CD82A3E21E47A6,1BA144C093A818CB,C6DB54790BFB58C3,FBECAE1E72FBDEF3,62A90DC14E407E84,286E1CBF555D8FCD,00000001FE9684B1,1C35F3C9CC774FDB,A05C854AA1E25E93,5E30A37BEF10D73D,3133CA47678C0DB0,5B3A06464D13EC5F,450889C261FD46BE,6A7F5FD440553D15,DF3083295439CFD7,1776F8CFA85D01C6,00000000E9CD9EFB,48A6A36E4B356489,E72EE5ECEF03D7A7,8A299546CA0DF4DE,F23C5C99D410023E,3FDAC6617C698C0C,55779992F6A0073A,B1B350BD87EA4584,E39F5D417736A13E,1249F87E74B8754C,000000019C9D0086,24DB6615F2106B81,4E7A1F1A5DF29600,2853D53A3AC52380,1B1A23EE5DD49FAF,FCFA6DCE1F422E83,2AAD62D17A5D6F7E,3497E876BFFCD46B,A83C04A6A7A407EB,27C8E05FE4DD603C,000000009A5C3E7B,0BD332048712B1CB,D07CDC9770CF2E51,80D7A8B217841020,E34017E9ECEF49E9,B3980E72F4150529,D78633B14C552785,47AEB4AFE498FD27,205D3581E405F94C,2C9A23C7F49B4BEE,00000000B8206164,8A3DF55E0C216237,EBEB33AA2F0756AA,2204F186A046EF14,44930A5927FF71B0,74AFFC9544358E19,C5703AFBB4F5B657,EB0849BF557BDCF4,D4F58DB21E976952,B6D879A890F94DF6,000000012DB18FE4,4E5DF886BCD0F0AA,6C9027E9F13277A2,B7640DDD4D6B89B0,D431BBC616B13C5D,41CAF7C1153B26F7,467717773B7C8940,1DA6F04DD032C511,89A1C1EEC768CD89,EB10C557588C5454,0000000162A1A037,218FDBC71BE0DF7F,875B9CD8F7A1BF5C,4B5BDA7ABE689D20,2704E536EB0F901F,78E2436312435438,561FE92A94BB2BD4,DEA967F6B4AF21E1,3A74818427BCED71,B0DB9714F210BA92,00000000C775B1EC,1707C6406B11EDFF,2D6DEC3E14225834,7529AA6BED1642FD,0C69A581548B34E4,51A2BD7796869677,B386E9260F7005E8,9BCE24F0E77A283B,B3D159098EC1867F,9C808B024D7AD458,000000003858DD74,38E871220E2F5799,A4D75B9245A6F5EF,BEC34C4F0EA83E14,3E0382FDB67FEE1C,3308D2E46523299B,E82FC390F2CE00DE,2A5D7A6191C61C98,AFB6E38D69B6C54E,D537F854401782FE,000000004E5BCD53,6546BE4150197950,CB652AD397667F4D,8BE8E0144CDFB079,3739EACF00F1E1E6,44B6BECF8F911B7F,8406B530213DA824,5E05CDFD4AD6C0DA,7CAD3ADC0E8C1984,F6A9AEBD1906AEED,0000000024C55EAA,39C4898B6CC055C2,31FA2AACF34FD1F4,F0032B6572712F71,E46D74D19A25A9E0,914850CFCAF20364,4E2041147465438A,962A89FE686123CF,101B7417641F9B5C,13798541C67FA294,000000019B40674C,C5BD03E3466B9992,B217D3D97F8B144A,6707A8BBF60E5A65,18486D032D29BB3A,8B6454B33573B249,E3F78F0D7DC92120,41CD9BB09006A1D5,BF8664AB0BF88C47,05A2A237CD7F1CFB,0000000226D91CED,5DC9BD87FE8C609A,114BCBD935BC5366,D4C8C145C87C5916,A1CC098EBD588E29,3FD5F2D43EB3BCCC,ED46224B28B78796,686EE62DEB032584,5FBDD47BC5434D4B,A93CD4179747CC0B,0000000273A9961B,3BBA53CD0F2A61B7,8FCEAF063C850B84,EDC746C44F844CCA,D33900E6CB451EEE,0E237F71EE1F83AC,499727B5ED8A1485,8B0936B39660AE91,29DC3C4FDBE97D8D,2E9F9970FD773FBD,00000000363E7992,6E0003FBFF09F784,204FC092B42B6F2D,A66B76E1102DC996,CC883CA6E588CB4F,11831505A841CEDB,6C0249373BEBA189,9C89A3E571371D44,7756A931D31DCB53,3B35EBA0113FB5A9,00000002184007C8,8B64D5BEAC9BB2DE,E217D6FB0437E103,0C54F88CA4C60C89,BC7AD583852AA555,1036D0D7B646CD01,FFBF8CB180DE1A7B,ACA0A1D3A1E0C615,0E2D8094BE398E44,1A996EA61E0EDA08,00000000443C570B,D7546698FF5F9AF2,1848413213ECBE29,A88953761F1BEDE1,DCF6D0CE96E83A7D,C3FA7D35FA018666,1BAE6EEB48B3B335,4DDC79A3E5274393,87D71DCFDB168E85,370FC802D39E7D4F,0000000146F0F311,D02CD5AD51A28D2A,5247019A32AAB6D3,F16789EED854F4E2,8EA68722A8FAED77,1560362B1C9E1F66,E234A430FB24FB55,7C973BB6D2BA9841,B3C19A8C7CFD42AB,D08BA8828E55EDDC,000000003C51FA88,A4E69AE2A8508512,5FFE9A9551E37211,5B460E4EABA6A773,357F93DBF041ED7F,FB652350FE40E17D,84F865261A359E3D,91C741F5E82427E6,243AB8A52AF53E4E,C1BBF77762EA15C1,00000001470D35E6,C025742DE4B070FD,A49C2B573AD3414F,C8F18DEDAE37EEA9,2C1143CDE877643E,C8FAF4FF8FA7E8EF,142CE1DDDC6206CE,53E8EE306003A347,1B9C2C3965135C30,FEB6EEA72AE25E3E,0000000008814C34,03455A726DF0CDBD,B7BD45977F109A7A,2795B498C04B1359,2195B037EEBE30B2,1D701534A3A1746F,BB33DCFCD8304D60,44CA00971DE9B07E,6531ED06DA05BAB9,A16CF2EF09D5F780,00000000F1E384F5,E610C678FD4175C3,0C943B72C224F1E7,EC44400A05E05B95,84C50C824E78DC23,7712DB5F030330E0,A974893CB9E7C1AD,68D3004C66BE9AA5,4E8034AE3E5D9F64,85DFCC188F2DCCD3,00000000C4E4ECC3,3E7EF60866053EB4,71FEE66EA6B08545,549E969C16B7735D,221B580E984D35A2,EAC1D2B7CE8F67A9,8A150F0D6F4AD804,234D6FDE3B9B1889,15BE2B7EA34F92F8,A80B084E1C543BC2,00000000174075E8,D88443B73B277F09,5AE330CD2FE40C1A,9CA5D73A24711930,81A0A71FE2331272,A89B4C9B11D4668E,99759B0C89FFE09B,2E9AB74742561361,203EA5056F356023,7641330333FC979A,000000014F713A3A,8FC6E8A707C589F6,628DD942EB717191,7B41B2897AF0805B,92770DE7627AE0ED,CF95FF516377B55D,B1F99F55C014984F,8A3F32076B8174CC,FE7382B87EE4F34A,23AEA4216DA017F2,0000000003D4E58F,06C6F9F7E4D3AFA8,BF5C6D61B73242CB,6180ABED170EA841,BC331C6F9E9A0270,7532EDE6DC5D9503,CCE6912D1252030B,F16026592E5073B3,2FD8972785654FCB,B69AEE1903FEF071,0000000095F2A557,B4D9F8FF35F9973E,71E87DF776265E7B,D944F219C7920E94,9CCA8DCB0FE21987,06C2F1BE7CCFFFC9,A788E1569A27074B,81E190289B52FE1F,9EDBE45F922CF833,79016CF5A19DB5AD,000000020E93D777,EAC14A2750EF798F,5053EF39C43AF2EF,C0FD303E5EBFE2CC,B130C351D22F8F4C,AEC4C6135E1A2AB3,231BDE26DBD8C35D,E973BA00DC0CE5CA,A71C799FCAE6615E,B915BDAF803A97D7,0000000104174D1D,D9375F527BB6937B,06A5C4AD21AF4F5F,F4F2C252A77A6F6B,DAA968255668531E,E12DBF1F7050BDFF,D218E6F89A579028,24F6EF65A62468E4,7F98DE2C38FC27F5,E8F40C34038E3BAA,000000006D6A84D6,A39218E22BDCD510,765D56D6E10F040F,5EB49809EB08728F,5295823908B7BE79,CDE257363116A3E7,FAD17A1890577EC6,8C68C3238261999C,5C2DCDB340FAC527,4D7041C54056FF34,000000016F61E7BC,2BD380DB118C1DA3,44972B578EB438C2,E50E9015DA0306F4,6C35387A4A731D55,6C438AD2E77D5AD0,8AA5B8E941BE35CD,79363E5DC9A8EA72,99692226A6D0416D,E19733E29AB42B05,000000007BAFDEA4,8D18B2D6C3DA1B8D,0BE5450171C30507,0460165EA3B2DD13,24827903EC677572,6DD0FE8190E593D0,7BF3C2E51FE3AE61,BD52C732C4C8E8E8,185002C72943161B,2497D3ED5AC9005D,0000000190FE2F4A,24FDD5C01A186199,C4C409809A2CD8A3,CB7A1D0B0833216F,61EDF022159E6FF1,B192D0B261C49B0B,4FCE56B0FC2815FC,633EE7238D47B167,A06224312A2F0C5E,9D32448777599892,00000001925F4F15,397123A507E052F5,F345BAB6725A7BDB,A328BF2521C12596,CF8C136972C0646F,B5BBC97B353C6B8F,BECBDF4CBF1C1BD5,46D1AFF525C1BC29,934BDBF96F20625B,4A2821E6B21FDB75,000000024D9125A4,F4B0C9B10D39AFBF,B0FB42BF4E6C7392,0069A6FAB2D9D002,735199D786AE7689,86CCA3489CEEC16D,CEC28697B457450D,1799D138B98BB2E6,A9022321AFCAB53C,4543D73F6AEA06FB,000000004582DDC1,3BF37F4F7322ECA8,CE1F5D5233989E1F,F3221B5D87E64536,812048A5D45FF22E,58AEF1B0908ECD29,56E989B4A853FEEA,4B6C07FEEAEFB0DB,D0E17E86043D5D39,7E480DB6C7B9EFBD,000000026FBBB096,D9EAC69879BE3C87,CD9A4A30098AEC31,C600CA29DEAAA1CC,17B699BC25DD3877,2969E2AE676882B5,4E721FD4E1DC9195,5726CCDCE37BDB8B,0008AE044347B8A1,F1B67E5706A7BBF5,000000027A277923,326566B762405F71,A371AAC29A57AFCD,A7CD463B09B9E34C,8CC3DE43D788FFB0,AC0D24E9950B4939,6D39E2A6A9E66ACC,ED83725F9502003A,BCBE9A63667386D8,7D0342B340BFED64,000000007143C2ED,E11BEC67CD57680F,B2289ADF13ECD485,FF2263FBE69BE5A1,6A082D0413B7378D,F3371199A276EDD9,4C9E92E9C0AB40A1,3816BC8799E27C02,CDFD8654A21FAD1D,B8381DE2DF11A2EC,000000024FCCAED2,EB406BD5717DD60B,1BF9694BFDE5B900,778B0C3DC34D4A2F,4D34D5D2D698B7BE,9D6EECF82B418B68,A1F5E3D029207C74,CFFDD995BD4167F9,CB64981553792F3B,971A6424EE7B6AB0,000000027B95AFED,A9D2DDB45F4A7C83,7A553194D3A73220,9186BF4895EDB222,BA324987777C056A,E086BE930C9818F2,1C02F5ADA6C801BD,2A74B2D724D2C9B7,5563F67FDD997E8F,92A3BE70307DB5DA,000000026F9CA481,B5A87B43C75C8B0C,5B7FB3954C89ECA1,0ACDC5AC22667504,0D683075433EF273,B057714D0610CE73,A7A08B6821C0463F,A6E09344E12BD3FC,61E1D00209E3BB3B,A63F723B2C847869,000000001E48DA71,1500D2A2D3EA73F1,EA9454E6827370C0,86BF4D682B3AFE8D,5C77776391C15FEE,99F7300F5DA097E4,59941DB015D83CC1,C77D95A84B15D56C,51F14EE7497A9992,B1113F9CD4728FAF,0000000277B33E58,CC349E6C9BB3DB26,BC9A5B45E3EFCB87,38B1258771F20C21,47B6EED9EF443DA2,E16366550F7763B3,2B38B1AB884EBD32,077F3E875E71CFA7,FB7DA5FA6F5F06C3,3B334ACBE93A2D0F,00000000FC653E3F,7A634FF7EC04BA8D,C16340DF9EE2CFD4,43723B31BA70C0B1,F6BF191A1E9DFF52,E8C1031E8C3CB42D,7EE6D4856F94382C,0750F55201D58721,C4E7C127E0B88839,97B8DFF6ADFBE39A,000000008AFFF85B,60B4CB866ABB7900,4259F739A7782EBB,E4199E1AE95FB2C0,5B13620B8B4C3DE6,1509B00F7881104E,B79C7BFF879A994C,981036C7ABB4B906,B11FA5473F3CB970,8401C3911AD6AB95,000000016143258F,EB3193F162EA78B1,34DBE6F3171708A6,B36ACDF64258099E,3C959C0F28D6194F,112463A28965C19C,8D8AA68FA725EF97,8E175347E0764AF7,200FFF6A36C34E88,BC17F79FB1BDB256,000000007F70A126,B529A1B7C46D75C1,0EC34F5287493C9D,5F954DBA020AC194,F73C5322D802B489,5E940F8AAE8E58EE,BB0F037574C96738,E1C975E5B81EA3A2,9F71D43350B71BF5,4A6284605E85E82A,000000007EAF453C,39B661062AF94811,FF1B3EA160FC5A3D,06FF51351E447640,00DC17D9B130163F,BC47DBBD111C7447,FA020E8560C1AB54,FC7A55EEC4768218,50186CE513FC155F,53BF7B0BECF2A2FE,000000001C4D5163,401EEA6751739F1D,97E4FDEF58CB7674,6BCE56190946F4F4,1684FDBE4FEFB504,110538E667EDD3B3,1373319F24D9DBBE,AFF03C157215B1D7,B95A599959CA22DC,AF0138194E351D28,00000001DBB1AB9B,DC929587B602F8F7,457C3EE89E86843D,3136613F3746A48B,D5AEF1ABE5DDF1E6,6C39C3CD688B16EF,9F018918C5FAA6CD,261BD251ADC72B8C,DCFC7E244C7D4DAB,88BD8B91A2538A3E,00000000CEB5C134,0E7DE7BD135F980D,4E9CBEA8E52CDC8F,108820698499C2C4,B99D797CDD6211BE,BDCA24DFF47D813E,B37C17D341C30EF1,F913EA353274613A,07C106AD24590063,7DBBC10AF6C24313,0000000119AF5F5F,54D0AD7E8B71DCBC,A147D0DA6AF66456,EB2F6D6BEA686BD4,3F70547C1A28B712,627215C788C9DCC8,13641F4B6CA7059D,9DC7295315B00B0F,9AE21A6CE0226FD9,3CF68C50E4782B88,00000000B1800777,131FC89ECE63ED61,2CA2ACB04A83D5D7,9A5A1E8B39A34851,1B02157BDE4794F4,97EF97C421214D90,75C0BD044DCB28D5,94F308CD0608FC78,7FF3B9C6E0938FB9,535A3351629E7CA8,00000001775C7981,5E7F80E37331197C,AED69AFE372BEA17,C845AA905F115E7E,BF5988FA21306189,71A69271F1CBA1F3,FF0CCBE29369867B,4EE2175DD445A8B2,C29C62708915AC75,33BD8C9BF31BE90A,0000000233E3E889,EE69CD6B3479BD7C,07ECFFC6AD480ACB,99433C77F75A4DBD,2581DC6886D04FC7,6AE36B15F8AB3A23,4305B5DF5C2A30EC,88DF365AFCB3731D,C5140488BD3BE390,1708D17E5A76D6C9,00000000E17CADF3,48F6674B385C278D,C8116A8EE37C1685,A33C6F3ACAE77746,632F119E09B4353C,8E5DD57CDE6D9F76,47938B2090172A1F,B4FEB88593A46458,3B67D297B7E43A14,CBA6833FFD05C5C7,0000000234A94ECE,47DD3411E3F5A84F,E0FC2F8EA1A1FD9D,6CF25A4740DC9242,D4764C8619B1C2AD,4CC94E5EFA8AEBD7,BD50A71AA417C5E7,F6B331F354C1DF8B,C3D8C697B76A0CCB,F71BCA63B260FB12,00000000A9BE9CBA,CC49727FED6208AB,27A85C6D65AF3ACD,75BDF2168A7A7EFF,388EFC65175CE6D8,B972C0F23200C7B8,7B1DA698855779FA,8C8A2DA196F4583B,7C9DD9BD799E9A06,BAF89C1F35C2793A,000000016E78B5BA,F924E7234E639820,BA4E796028878D03,A51E03E0FC0BE26D,48B7D67B49C43492,B5E9F9F7516ECF8A,FA99BABAF4BEA1C4,112E8960A0A39170,E34F2216143D88C3,03977245CFAFB0D9,0000000262FFED70,895B3CF4A1397F11,A931AB0663D559AF,4558EB363206149B,040E192BC63E9AC9,B6556F5CADD73866,1C1C2B376A369D2C,E8B7BE750944FCEE,06DA8029A6BABE38,AF3ED4829D8AB3A9,00000001B2182BD6,13BF20BF5CFBCE81,81CD610EB34DC9B0,915B8AA0E9F54495,1B263214B63457D9,5170CDE698868DEA,2AE24AA0743142A5,52F0B18D1092A305,E6F426612ACDB770,3C57353F028F6C2C,00000000F6BA9484,278CAD2F12F1FA0D,F092EF958F3461B4,EA14EA96B96EA600,14A3D85030342B25,26779F2D819105D9,759560CDE198E48E,D63F22388E08D58F,9A5DFED0717D5536,86C11361E7F08729,00000001E3B8941E,6816E8D359179596,C0BF1F0D86A1D449,D1620DD347B5A9FF,FC2C27FDE4BEF69B,2AA3FD7CE3604573,46FBDEA970628402,66130C2C709A0370,614112E18249A4A0,A989A520ADB045CD,00000001C14E816F,D81DD6CCCE5D5C3C,127525DBF752284D,3AF166D6713D268D,F57A3DA5981FA20F,4E388A21670DFA62,A0FD69A7F470A5E6,CD34226747230AED,C32A1AAF783AB0FF,E3C867BE9B2383AB,0000000086AC62C2,9B15498BAEB4144F,4435D01ED735F2E2,3C0D4578B9383697,BB25559F8BBEC5E2,638421386FD65FC1,15ED37A8D999DD42,9BE16C60A20CA891,E681A569DFFC5F7A,45D5C84265E7BEC9,00000001BC12DC79,F55ED144CBC4E145,CAF91FD0016A028C,4A04D6E6CD02FADA,08B0730469B8FAA0,69D59D5AA17C54EF,82ABC31F4F6A0271,C700F0F5EDBA93BB,1BA6C646D79173CA,8B4378CC0478BA86,00000002205136CC,989A178898FE7485,813431ACF4D012A0,2B311602BD93FF91,3F578DB6F2A47AA6,1E6DFF063A32FDF8,7C134709851F779F,E03A8F15E8BB0BCE,A34C5F01127D4543,A82358DF3C01E0CA,000000015500A12C,1F1AAEE430CA3889,6704B794B25E1ED4,B1A0A47A6799C920,180706E2813794CE,11B6CF81DBDF4E3C,69FBE51886616664,31AF8C947D3D612A,BCB756078C1B3452,DA4AFD61B0BB5206,000000008CA68C78,5284399174991878,661A7CAE6FCA558D,F12B170636D22B53,3D1DE820C580EAA5,C7E65E3F6E68903B,F714C6BA8DB0D888,4ABBB90F020E110A,5987855E2080BB96,87027484C1E4F060,00000001DD3FA361,4049A3D91F02727F,8F9A53BEEAEB3544,30AA412A4B87DAE1,ADB080388A417155,7EE6978E029C1067,FB1994BE0152FC47,3E930DA6AAB7F03F,768B7314F4210F2B,D56F7252BE0A90EA,00000001A8105B84,69329731ABB7669E,EF87FD4556FADE2F,A5C658A0622C91DE,05936519F5EF1919,8E004D8CBB68ECB3,C09F5FFE928B3D8B,54BA1B3CA6678A38,B1FF4F82346B1A92,E90D9EA8ECBD498D,00000000EEAC8559,E6BB408D9AD8B37E,29C282E9A1CBD0AF,231BD3E083C427C5,F6E0B8A02121FFEC,0392521FCE55EE69,1EB346C542DF8794,B826EF905C37CDD7,1C9B823A92A25A78,2DF1A15642B23614,000000002A551C2D,24D1BE73CFA72E5C,90B57C988A6954E7,EB66904A4AAF068C,4F9AFF6EF1BF9F47,1BBA906CF48C3DFE,5A4BDDE122493859,B0ABC4668A7F2091,7C80930B7F73A270,9F5C76DEAA989966,00000001F6E9E5BD,FCCB75B0202EF271,C975DA82972D53CB,7F18DAA6703FAA42,805A4A387A1B3BE0,70A5F8A43ED0B1B6,5A97ADC63A941FEB,3D4B8727C8DC4196,4C536F6DA19CF4F4,2FF8196040BD5009,000000021332A8CE,79B651D08A3D6355,DCA573DC4AE0C500,D45D5F749D7BF7AC,374925965006A697,7BADE1A7FE855920,5574FA70B13E05B1,2E086407B2C8F7A4,10909EA2A121FF9F,250BC26290E0D175,00000000513A579B,AC6F1ADF812E8E19,AF14C09E1F543CC3,2931AD81EFCBA176,5122976F7057AC8A,476078E0F5B01CED,E280BAC5682496B4,AA6FDBAA9736CB0E,3BC2ECB39F587492,FE06D7CC88E7432C,000000007CFBE6B2,8F039C1984FE6DAB,4F919C8403FEAB92,3D54960C44027F62,9C20171A3B73AC24,7BD8C4123DBC0F59,E22D2D6302D3D2D4,B6737796A4F1482C,625D659C2B13C1D2,DC0004DB72453D0F,000000019D22CC97,EEF3F4DDBA11FB25,271DE62061D09879,A7CD6BBB14F931D6,F9F6384CF0E978FC,3E82456A9A031317,65769AFD36A3D912,BCC5225E903D3DB6,2786B7BAD1D3271C,A76AB17F8C142765,00000000D40CA3AA,99E5E61B9F47E69E,F677686133514E9A,083A68DC9BA712CB,FFF8F5290F0755A4,65529BC033BB49DC,317C5C80B29588A9,BEFE13FAFB41E59F,B9342EACD4C60C19,F6B96B911EF24BFC,000000007D3EE75B,DFE9984A57F882A4,02DF66507EA8174F,A5AF7932E6F5C222,AF23632DC9ABD5BD,243B9B75E8CA1F15,63F12EE32F9924BD,C6584F4CE9AC8D4C,3E5E4312BBA4D19F,6EEC431D47A2A9C5,0000000024BE5519,06C73635B6057CA5,D1B0E9C7E7974019,D20043E89FB156E0,8F19CD1486C4F723,5A680439A9B7D081,2F64D24EA6D85699,3F7BAF80E70C7610,2FB5500F1C1D57CB,7753041689D987DF,000000016D3DB305,A635091DE857424E,9B777B662913C7A4,1D92555C5206EB01,7AF52D4F4B3A4A84,5B3F84BB58FF18D4,2CD35D86496EAC57,A3CF8379248E4A81,9ED2B0DDE184114A,92701C322758303A,0000000159D133AC,8C3A8BAA45B45467,BC43364304373C04,6BE24018B2011E07,68EECF80A224AB84,72D48606965D9E00,FB2A94BB3ADB07F0,C391DCE467CE80F8,7EBC48B79E0710F1,073087DE2F44324F,00000001E2559C41,DD99B290E32CEEA8,A84E915BB3A1A57E,AB1956AA792432B7,45353602894BFA1D,F478B3DEDD596E56,59ECF64D89901030,B3837D67EA0F4CDE,EF535803E2E1CA80,DBD99487930564C8,000000001A052B65,C7AB5CAAAC732CCC,F99424830826E025,71B2EE5A09A01491,DC352C0CAAF94CEC,A4B70D311CB7F8B1,90CD16032F6A704A,957ABD023377FDC2,C13D72886977277B,AA774A7C56648E5E,00000000695F4F9F,9DB673251FC4C894,48C96B9E1C8CAF8E,9D1D347178D94E9E,EE8157741CBA93CA,1DDF30DDA7DCB74F,833E812CC4870E11,71BAB3FD809FD6E3,B1ACB8E71EACF559,BC61A92129D4E083,00000000C4B2DFD5,2B943A11337A6817,95BF6FAE546B376C,D1B5561355D7AA5E,075C497C2A7C2946,CE764EA9288B88D3,8D100A6269358464,773D60E824828425,A2EEAA9F4CA31A6F,6A49BB732EAD0B9F,00000000630D2FD9,6A5CB597C20D2114,0CAA03C7022E1DF5,65AE3E15E5C73DA8,D7D791ECE92ED411,2309A994689D4239,F7434D70C3DF6E7B,50DC9BF0AD65462F,05EF4EB55D8BE45A,DCADBBE7878297E6,00000001DE8E499F,B84F6E4A75519735,423C1AE77BA2BB75,8973B163ECC3031E,AD49190A4DF0DF63,C57356DC5701C09E,AB3F53FD1260D244,80C5E208E3D790A6,3A1FEF7DB33AF5A0,54A3F01567B905BD,000000014F37A3BE,1A46F9454AF48A70,755FDF54B718A6E3,8E446E79128D5C06,74E1783806239D82,BF2E6E51FC16B86E,F831BF132DB05371,804B4F26C5E2E9AE,C73ADAA3AAB72C8C,975512899C9B11E5,000000012238AAA8,75575E1BB717AE7C,9666D483E63A232E,C4129E21184C8DF1,A1B52A81CBD7CA61,209C1385E56DB1E6,DBE2297DF79E081D,50E29CE1C70050A6,E50DEE1CB47C464E,7E6D07D00A31C92C,00000000E546DFDE,62CB00DAB44BDF0C,2A0DF2F6A68E0D4D,482852A78B4D998B,65AF4BBBCB1942C8,78236FEAAF74F661,8830FFF466FF71D7,F770C0892B3B5AAC,FD50A9588C431B4D,546059F526EC0CC7,00000001AAA648AD,9D5F8596E83CBE3D,165BB9A89BFBA3F9,5F3A83F9031A84EB,509A2C6655AEEDD7,BD29D578A81767EC,95BB66843C07667A,B5EF131C965F62FF,E171929A611B7095,F6719E926E84282B,0000000082193A9F,BE0E45CB5B5F572B,37E1BAFED2EA6FF7,B65870CC15ECE116,11619007F9103B37,1179796437CC0951,F89379EF247E1A16,12D748810BB92BF2,0DEF015AFDFCC8CB,267B03DAA3AD95CB,000000022228493C,1ACF9392643BFC72,32091FF508B14B95,0FFF56DC691F7B7E,F0AC1E8657FBD238,4F59EA48C25CF34A,C4D074FD31C95A58,4C7D4226A0FB0683,634BD4E354A1B527,575A90CBD568A036,000000024CE41E89,7B8DBB40F4E2267E,D5C0E5D4907D909F,FA458D29F578B2B0,0C1F2FC3BC9C3FB4,FD86C5F052548DB2,EAA35291A2E8EF86,82D35942697DAFB9,1C7A8FA8812165F6,A17D0B1D73E3CB7F,00000001842E5050,A1C224228B789174,2A1E690D958D7E11,D6DCD1103AE8A42A,A989C94DBEF186EB,3567EC2DA4F05FCD,D8037BBBE9095EDE,037454E716515A5A,76C32A655F5C0988,6F386151C960492F,0000000257804AA7,58A0D6263EEA1DA4,AC1AD97B45BF5E47,C00546CB2F823363,DE749D2E67378054,3471ED99E21F6D38,FC99DE95F44164FE,9EFA3A78749D90E1,26AD008DB1155AA4,EF31AD663CE933FC,00000000D08DBA41,A48FEAEF72098E88,0FCE28B8C016622F,D371DEF336CF59B7,BF7170E91E827755,780F8CD2550CF83E,11CF467C476A9A65,C5398251F25F0DA4,C199CD452520DE4C,D51F67F363714A33,0000000177C90A40,3BC04637976AC34D,36988618A4176D7F,9E653DC5401593E3,478042C71B9D8FD5,C132EEC8EE405380,54D4A58F15466A01,C5591F9E14845E68,F33EC82B350D6F0D,7D57E09185E9ED0C,000000004860E0B8,8AAF65AD3056AA5A,9DD72BEE857E4DD6,53F21D66A5AE5FBD,693D70055EC093FE,FEFAFAC6B04A2C96,EBB14BF063774910,A73DB548660BC211,047DAB197F409821,ED30D194FE01297A,00000001191D7713,F9A83270870C4355,A6FE88466C58D50C,214CCF3A7569B1FC,372E0DEC702A9757,039B2ECEDB040067,A0043D3DB5BFB245,0337C9651214BF7C,7CC7DE26B08772B0,03E5D66487F01DB9,00000000F6D7EC4E,11F4F1A5A5CB0BC3,AFDBBD574B5473D0,784A672C78019D36,1BE8ABF5EBE85262,BF83FBB3DE88BC48,D13718B9C6F5C5DB,264E751778F61D42,F81FBC7CDA27479C,0327A99754BE63D6,00000001E124A1CC,840F30E8868FC7F3,3BFDEF79BBB1B278,300CC45FD1138E71,84E5AD947C7C0861,3FA0C5AECCFCA24E,BDDF60C0129CCF5D,EA090BEDA82F4776,C0B0192596D20E2D,8860080FA5C7C88E,00000002119C7320,36E9F31C0DD5B258,B4E7581AE87FFC2E,361B7681C1D4610E,EAEB86997851C99B,5939201BFF4735F5,F4858F9824189D36,683BC523CFD507AE,56012ABE4BDEFDEA,DAAAE1B45F0DD399,000000015643F1B8,5E4B9DB34EA4B7C2,E543E4135ABBD779,7958770150B62C7A,64F3F0D1450088B6,E3C930F7325AFF7E,994494BF1939C9D6,FC5020CA75906DDC,E6F6A51495021260,B6D0B50C7124FD2E,000000009851F9C4,144092E2C4BCBFAF,FB1A5F5E09880034,5CE43A218AD1170E,2C26405355CEBBC2,EB917F5F25A569F6,711B6F6B46BB8F87,30FBFF3DCB562C72,25E86339AF12B6E2,2C749BDF38B29446,00000001F1B1D232,85BFBAE407619D38,9CA17EEBD8E45156,73C2656923755C9B,6F9F343F2570B9AA,76B728E502B9AE39,65D54DCB38EF046D,EDB0DE9CF7EDB31D,CD9AEF787CB9711A,AF51D95820DE7C6D,0000000136BC9A3F,E40FFB816D786DD4,9B8B4E21A3FB449B,54FBFF1CFA27BE63,7012582E3785F660,54A096FC2839465D,02A74F871F44DE49,B86695088818E3F3,3F42729D475F9A39,331195E9F5930294,0000000069307CCA,7BE629021348F8EE,E12035D653651459,7B65326C03C088B7,360A36013E2AA12D,538D0B62CB2A539F,0B627CDB2C72A651,70BA544054B64D0A,55910CF450FB95D2,44C62B09A0555281,00000001EE367080,B56508B1712EFE42,FB28C06FD5FFF264,CF523735F00E7891,F7146BC96F3A6A94,5A04B4967C10DFC1,3EA109DF6890C871,5AF23CB8D517868A,9441CCA146D9A22E,0E6480DC0B0B1174,0000000089E87765,A82632BF1BE3121D,0A7B48C573AB2941,2F88095FDD613E60,9466EA062440F75D,7102EFB0F7354C29,612408D5309189E3,A7E7A1BF7EC0AF41,7D83BE0D54407D23,37FD868F519DCE20,000000015016AC9E,65947F50E1FD274B,A2B95D0BCC8A8233,486B4144E10DF044,5250C6791DCF6F43,F962B02F9A14EF86,91E4805FEACC0A8B,7BD6F990D5F92C9D,F2A749747650DE7F,8CFB6456575C49C8,00000001ADEF43F6,8EB9FD3CAD9BC432,98B948D827BDDD5E,3DC3B997CB86DB7B,B33B6505BB33A60E,27928C0B64B41420,BFD681E0A7F096C9,777671880CE9BC4F,A3C640C55C69B3F5,BE7F38CE4D3EEE19,000000014B7C7E2B,22F089E0941DEFCB,4FA3EBC821DEFAD8,1E3B1AA9DA201E25,7D2478CEC2FAAAC5,A257B277356787C9,CC505FEA75AF2744,17C718EE6CF41E7B,3A8FAABCD0876B14,597ABDFC3566470A,0000000062DB963C,E444988FD1DCF77A,71B272CD60CBB1C3,6594D7B6603B1411,46E63897D31A6B4E,AA8403D4B7E6F4B5,82DDA1CFDA78EA6C,35BDED05453BFC4B,012481F2F4F94759,724AA2BF0A106EDF,000000023FFD7700,519A049ED8AA2B57,06C0809CFD86936C,C6D42FF1C468900E,9F9B1B57C932EA79,34FBFA8E343248DA,50DF85636DBF930B,C43703963F4C8798,C869C82F48022F06,AAB053795AEFBDEF,000000006DD4FF40,426B5A03732A16F5,FA2EBDDB665F56FF,2C724EA1FAF99B88,FD9CBDF427E0A381,E2FF26FBF5466561,3D3EF114055A1EBA,C902A04A2AE0B451,1160CB553FF08335,4159FE6ED823AAF8,0000000218940D29,6B4D957678A75327,1EBD937CA5C925B4,0D30750F7BE2BF24,A685A517F04601DE,C910798052698F3C,8DFD68CE00CB99F8,F5D1C602EAC57949,90862F035E5E7BE0,BE02C002B8167523,000000006889FCD4,4D8C127A41FA6514,74E39AFE20D3EC71,2CAFEBB972EBC818,A8611814DFA17F34,FE9437D0D03F9E03,BC3A1CC3877772ED,E6E85B3BFC11CBEB,C73953561BEDDBA1,7EBF3D3C47A5C32F,000000006692D48E,C539946D4DD63E44,57DEFB3E2FD1E89B,49CC21E624879536,CB3828EA75E7099F,08C7C9A1454EBDD3,8F7FF551154F1B34,4C80A9364C4D3ED5,44799ADB6F345395,E7C874C3F38E2574,00000000D5A3C027,AB3BFBDC4BC94320,8ED1286826F779AA,6C8CFE5E1CA307ED,46A41CEE6F971D2B,76A594F3206F7143,064345996489E7C6,E8B54961F6783804,3116B093A5955D44,74A418B5F2AECD67,000000008ACDC75E,5FE0512502629AB3,146CEA6DF082B3EF,8C9A1EDA5ED34F62,02BECC02BAAFAAE7,14CD3EA627A3FB85,8874C403A191CCF3,0E31D856CD91B77D,57435CC1C48DDB2D,19DEF7FDCB009DD3,000000024E73690C,174055789FAD875B,5A82BE8DDE3950A7,A411C49485F65ADF,64B09478C9FDDBBF,8CCB13A53BFB9573,CD7F235C0FDEA7CF,9E2F5E24A04753B1,FF2E58BDF8FD4CB4,213571F99BB00E9F,00000000DBA58BB1,C82F32CF8814FB28,1BE8E9DC4949B4CB,EF41C81C03632580,AA0B3695C6436E91,442FB36CC59BB94C,6E207FCC84AF0D0F,91FA6E2203134F99,3C800A39735FAFD2,F7533EF8A7EB6178,000000006089E9CC,749AABA0165789B6,ED7EC8AE057EFBC1,B3032607F28C6AB8,A52F57E1B4CDD3A7,5C3E74F65C1798ED,43F252877B5573C9,F58F24676BA01E84,106D8C9BBC9F935D,DB89315103480C4B,000000010A01C172,95A36D60F4687FB4,02794B93AAC2AAE2,4A82DE1C2D61370B,FBA9113BD22EE25B,1C530F8E2A0E747B,823EB96E42F72D8D,33F2606A9F0C9C51,FCC0EDD3EFA9E03A,85BB1EE8C3089717,0000000260BB5CD4,2A8EF33C53E98D35,5D8C995BD7F792F9,3D39F1B8694735E8,5272F9E4ACE155CF,D15EF6F5628D162E,AA4C9903414617EB,F5A393EAE613AE3D,5EC2A4AE0740A336,DBF1E8989D2C1A71,000000025C0A25EE,2BF8966A1578FAD2,1CFC17FF8EAB2A3D,0EB704205480D6B6,0019F6C9ED1A7231,4EAF59710BC66540,791F24CC673CC87F,C312FF43A224BF87,B85E9BA1ECD3CDFD,802973ECBF0DEF0E,0000000130E03C1B,C242706CDEE8A9D1,801F4944218A38BA,B57C660852E68988,FDFA0EE095CFE9AB,C29C981CE88F4767,49F616656BB65B0F,FC25C4692629C260,67068A22E232524A,0A026A0A745FEE16,000000027194E2A6,FA875FD7B582E040,166B0139F2642D9E,204502E2E942780A,3D014927535D872A,3507F2FC2681DF11,C1955B1239CCE4A3,C5168FDD6CC060D6,C2C7065BB22F29E8,15EB93E9E3CE5339,00000001227B3B1D,2406699BCB9F1B52,0862951898739C39,5271C5CF5A831159,F6F7F3073648D95D,8AD6DD55F9EAE437,DFBD78BDF5888DB1,1FEC0E41C43E504B,766B3CCD9BA6FAAC,2837021FB1A633BA,00000000BA4901C8,F95A580EC6F84D73,20461485A7A7F8C0,00EAF110EEF8360E,05D79A4C6737F565,89D7474A10E9D606,F7E0BF7B74F8325C,24185FC090F2A213,C27B9EFB3DEB8F4B,7D1B370C41AD67D5,0000000044BEE9C9,2BA0EB56B81E239A,52E08CCAA3325EE6,24FC36DE10643B1F,2437BD647211B562,954FFB9BA45C713B,AA79E779044DDCE6,FBA915F14CE68810,68C3D45C0C17FE20,0AACFCF111791E1E,0000000202C2175B,F8964B96AC9A2C6F,0DB748ECCB1ED1BF,7F200C5D054B8EDF,2200DE560DECD538,E500BAF70186413A,05E52799FF8E741B,AD4D837057B852D5,636890316B6280B7,63EE2DD0C19894AD,000000017D153D71,11E9A1ECF7CF4553,412F0969228E9DA3,C1BC1003B09FE389,FD187F0D2EB66C20,EF511F27477FE771,B496D4EABE47409B,7FBE29F0121CBD95,011421C02552E827,FF3DD81E97E27401,00000001C50EFF06,52390F53C24DFD07,C3CE1094A9DE4183,F619446F153E3295,343A360FD101E18C,EEAB95FBFDD4A412,9B44A631A06D78D4,A7FA8B5837D59851,A69A28AAD49875BF,F235981C8FD152E8,000000020A113993,FCE32E3A228D61EC,EC76D755365AFA2F,4271FA745E4D4171,AB6D1FB4115493A7,B7D781438122AFC9,24F2CB45AEF9FB94,E55715A1494074C2,69DAACCB016D11DB,797527428C30AA35,00000001BE151510,FA3144E681C5F27B,3D03F6561A4D7E01,36FBD5DEF3CD5F13,42C89F936598C4F2,6CFB10A81825C822,115501ABEC5EF29A,0A140CD792E74888,2561644ED18DC9D2,1502548666A0F71E,00000000C284B583,65E0DCE1E3976C66,4FFC64A70C1C20A5,380F691C0034D002,19D271687D6816B0,FB565C035CEE0063,E33F53DC215E0969,002157D4DF1F9457,B853E316C91B50B4,5226D3A118E91E2C,000000004B9E824C,05100D6FB6BE6CB6,13D2A456074275F4,74BE734B8FBB08D1,4781CFBE4C5F589E,6582D0AEEC2F089E,338F9A704B824986,90FA531DB7B24E02,D9F50B5DCEB0633A,D0804DD547DB9DDD,00000001FCCDEE31,292E477C8BC40668,38BC75AE29339730,94655EFA8D57AC9D,ED08AEB09867F086,E23285CC4DF336E3,E096457692F4EC24,8EFE356C6369308B,E0CB7DD4CD9E5D48,B98393313B2F871A,0000000005F9D76D,404536189CC41A06,6CAFA1ED2FFEDB4A,032ADE543AD14A30,DCC2020366D5A65E,F4D282C4B73A0A7F,1E05F121B3D9B044,BD52556236C33B16,AEA223E6A96719A7,633F7B59CF128875,00000000D8B17E74,758C17AD26A80B4C,BBBEC7C6C78CCB52,64F0977092020D44,D76DF7F30A1655CA,2052EAFD16FE0023,D7BCBF94BB977994,919215618F877C9A,FBA968881CD2C752,D95791082E8F2700,00000001C8BF1328,55636D76EE00D059,0C75A0AE71EEE970,DB348C6CE690A848,F1BDE0558397A593,D4B83C0A866E0D6A,E224E2E7D7C91782,B7BDD54744E81982,6E8344D8726BBE91,821A60B97F685F4C,000000006DFF638D,D950FDCCD81E68B4,CE25C33424D5F8E8,37B2E748F2DA79A6,B659BDADB19284FD,3C41B6BE80DCEC08,A908AFE36DED941A,C3472BC97BBAD9A1,853CD069F2F05A79,EA65395CDB33C5D2,0000000016306B76,EA00BE7C978DA807,281CBD6BB0FB4BC3,6D55A0D8FD1500EC,B58387D42708BD0F,ABFBC9B988893F4D,804761F0F571182B,14B1B0D2EE3515F8,20258699A5E79C86,AEAF219AFA0EA83F,00000000EB129F55,3E2915BDD59A2697,C213D6B425F9629B,791729B0879E24C9,935AD378E506A6DB,FD70F904F738D4E6,CEF4C110C92814D8,DC522E856195EA27,6DE74F12BFC98829,8EDCABF084141F96,00000000D7E55E8D,3031021B0E7C0B03,E89128AF0A7A47D2,8FF59DB9E7AC5FB9,75432E5AA8C1388B,90674593552AFB8C,DC17A3EF951C0915,FFBE9240D18DC160,613375F23D657949,0EEF87FE9BA5186A,00000000587C052B,F31B67D16E34BB6C,4C85BEC0C57AFD95,15D8386D78725D09,B53E3F8ABD7849B5,29ED3E883FB2AB10,5D9947A067B30974,C2CE81F090749F35,20CED00A7592F5F6,69F1088EC3036FC3,0000000025749BA4,8AE584B5AF5A389B,CA4C9093326EFC13,8147A588CBAAFF37,D6A64919A467543F,D2D5AD873A78AFD4,C5B1E223BB3624E8,98D6C7792EFECD62,B946904692AB6E8F,3F9D73DD7B514C2B,000000010D4439C1,6D08EF8E105D6B0B,CDDC14F7787A14A1,EC5ACA252B3CD5F9,C3110DA3C184CAB9,5AC74CF113FB344A,C5E1E3CA98870CBF,76B826FDB621B4B6,F0AD1A6D1D4221D2,9888D2B14CB8582F,000000027657615B,978FE6A9D87BE6FC,891D36C0C293B599,14DE9792DF8AA15D,33EB95D4DDC3E8E8,944B4BD68B99CBF8,00EE3807AB7EAF4E,73A3FCA7448E8C61,DD3A45737D3BAE82,C4030A3FED00DA3A,000000022573686A,9A602610D47255AC,03A177D7B3195127,7032D8FF9F417975,24B1E35766A5219B,6D2A8B47D639FC68,075D235BDC57F0AA,6AC1C40053D0A965,5DB1A6D24BB699B3,F8FAC8B513214A44,00000000F9F2B06B,27E8C68C4A328A69,7077F88E6688EB7D,CE198564D0A8A442,F70EA547DD6E5AC8,00DB4FAAD11BB99A,D701EB3BF0AEE5D3,091A0F18AB06131B,34B099FCF3CC091D,F371962900F2A302,00000000C9B031ED,918C155FE92D8E86,84ABA9B60E69898D,F0FE685070FC9ED8,CC512B247B739898,6431583BDDE5CAB9,6126DFDF9F50C192,66F3CAEB92808381,4AF757817DDB754B,CA9775D981A26281,0000000150DD0CCF,D8EE602E0A894BA3,78CAAA7AB5202D60,ACE70051DF15D10F,27A644DE1D1C4583,D29399FBC4A35A36,5D01B759139A4304,ACD5AF744D550372,D39BA1644A73E0F4,54B5AA43562B4453,00000001A940C83C,E027230CCABE8649,AFD971667ECDF435,210C707393A0549E,9A309C4D247570B1,850B85D536EA61FB,FF02EA6CAA71D4AC,5FC7B54CC979DD06,6C96DF2CEF20359A,7AFFF8FD04460755,000000007DE80DF2,E1242FE0F189F815,7719C873CFF63F23,94877D72622DB332,F13B2043A6338141,9EFED6CEAD68ABE0,5C1B23EBE2B060B1,843461F58114E3D6,1B0F31F2FF6B668C,ED9B07637FC39026,0000000096C33003,3B718A8B37CD514B,8DF786F63D4D6610,C11DF472EC8816AC,A716018CCBBA0DA7,0C4141DB950A1F0D,2760E4639AC74DD4,6035D57F18EDC433,D2D9C42773ADAAA9,0CF8877415865260,000000010B40A2FE,F0FB276FD70913B7,A6D53CD310817896,5F3040C29737C22F,E2D15B5C9531CC99,A1477CE02449C8A0,5784D1EAC2759628,822EF6EAFC162A0D,C2970BB042760CC3,8A7A21911FD6D008,00000000A2DAD2EC,4D5BA89A0B1EC06A,6B3F811D50249B36,0BD9F0D8956F3E6E,93A9C2B340B61F78,B240EB625DEC768C,97DA52F8B25F318D,84EC74CEDF1AFBCB,9C9EC671660E9F74,014F8C4FB532FD0D,00000001C0DB30B0,356EC24AB1AD2DEC,5400D86B984D32D2,A2711E4FA0B950E6,AE0D04EF0191007E,A56AB44C42068B55,9DD47FD370BCB6E9,4C5F1FF9A79A0E79,8A08134AD6D38FAC,7E1E2A0E5CF49799,0000000036A6838B,4EBF42C01B54AE5F,13A526427AB32070,5576006FC674FFC0,5B23FCD252A282F1,9D76777B52DFFE49,EFF60CD70C9E3D6A,E907C70616471074,703B7290741F7AF7,B31D1E1CDBDFF8CF,000000005495D313,ADA11748FD6CBA17,13F7257CCB987D05,D54F479420370AFC,D174CB5FBB5FDD50,0F4017DEB5156275,D914B165CFE40D8B,FCA2FCBEFEC9E1E6,BBB666F1855C3F7D,AE536BBF7D204ED7,00000000195ADA4F,EF49B129E8EA953F,627AB04145D9F5B5,7254C19689AFDB2F,2CC0A1C87A290260,0E9F4DDB4DAECBCB,625D3D3852596363,F18B1C83A33C11E9,80D449DDE6AF428B,CAFBC2623A897ABA,00000001171F7078,7B0EF620F9C406F7,25F16DBFE2FD5CD7,3966C5051BA0CC4D,00E57ED73139AFCA,B8EA2AE2DDAFA4ED,326C1CA56A530CD5,05D4166186CFD19C,C4B160A6B300548D,7BCDEA4E1D254917,00000000E74A2610,0FD235C51BEA72F8,EE89104D6BE814E1,88AC52533C8935ED,08F8A040F53B77B5,472A44EF8023804D,BE002157E42E2118,6818B1C9953448DF,D6285B60D736DE12,DE33EBD07387CF0D,00000000B717BF77,8D47446437D9818F,028AD8680E797627,D2EE5811D18AA37A,B0E52D6E492A5F41,E6A2F14EB96B4102,AB249A23FEFE6F70,5461A5FED73270EA,84883B171E6FBCB5,7AED7C46404F3088,0000000236979FF7,ED3F7975A6FB21F1,B05BB1F6369A0B49,939203AE6F3C8577,261A98F9FB95D4AA,7D0FA198C523DF0A,79D794E235687772,07629AC90964E24A,143E6B24AD485C8A,F72732AE1F5AAAA8,0000000196B4F480,D8668C56A735CCE7,B778235ED9EDCCF5,4B94C6F32523AC35,100B9CE04B5CF64B,EB7AC18506C8CE5D,15D3D1AD618BE3D7,D9A26AFBD200DFB2,74CE5A4786CB2377,CB34FCD9D92C4BB5,00000000BC8C74E1,83A02BE7221491BF,20442331E8CB5167,44B64047475D1DEF,AFFD7C7DCFDC01C2,7444A77DC305EB4A,CFFE74740959D2DD,27898A9F5C28FFCF,56C1037999A7C4AB,BBC88DDC610346C0,00000001722813C3,550148555007A6AC,3A02DB33697D72FA,F583F41B3760D924,081C4C04A573E41C,69B18B5F92374EE6,AB7A01758A92109D,C40C5C065A95F9A8,64C199306BA11343,745AB75BBEBCE152,000000018E66588D,3D21D8DD472EAD52,25C3A65D15BBB197,49BCC9E0C4C3B610,B4A36FD79B377F39,AF0E6B4355B94BC3,EFA6F23A8570216A,B5802E7B34841C0D,C025AAD8CCA4A43B,B2ECF52FCF5D1DBA,0000000163CEB12E,2AA80ACBAEB9F5AF,B93DC2DDAA402A9D,E33E9381F212CBB3,6D4D48EAE2338AD3,2E8C9573622BE858,F56D79A46C9C9E30,EBA5EE3BD3FC08BF,0E585D99646AF6A3,B0D718DD5C380A3A,00000001ED4390C2,B92BBF63F1FD85CF,9DC1420AFE490539,3D9AA9037B1A5F91,9E43C77174480EC5,DC38E94417BB2D54,AC0026FEF7E76B54,B953D12AA489CC8A,4B185EF73ED87CF4,DEA64289C1008B73,0000000117D08DD0,1EECACA4C12F74F5,1063509B6B63CB7A,0A608151041D23BB,4513597ACD9E106D,42A29C62358AC3AF,02CDD946804E6643,F71F2AEAC8510D5A,173A58D091C2FA0F,56D19F6A8273FECD,0000000066962572,512D555FC5575CF1,3C5EAD90462D5FA4,321AC69E7127C986,13AA3C9E2C721A5B,E22D8AA5D15B4048,208BD8B12486212E,D655C07AEBEF2961,B24B30CAD39D0650,CA32A046FEC6B310,00000001399839DA,1D86F8C925E316E1,BD12D0C2255A3373,E7A9001D08DA0B3C,C40C7C1D1DF12AFB,A2AF1B4227FFBD6C,0A7222CECC91B877,7023737E082FDF19,53B86A64B8C02F33,F24C81C7C1CFA313,0000000254FE3B82,CF98E1DCCDBE9ECF,DA9E4DD6AB4E7A27,65EF78E889BE3C18,8F2909CB9A3A5864,05C31AB3E018DB20,5CF1692BA932F571,402D8D7E419B5EA5,790BE7D0B3343BEB,CC21596879D96346,000000026F0F1DCA,0D880F8525FD04B1,CB05B5AC2634703B,C7CF69C881EBC59E,BB68E89B9DF1A9BC,31E54B5A2CC1FBBB,C7D1F0B941F66989,D2F4BF5D14FA6C47,4EFE65223A3AA9DA,212C850A10D822D1,00000000104F5AE9,8E8E9E7C7A6DB8C8,17E35E797A052E8B,F81D3E70C6324652,3AE6F354069ECC50,06D3FB18C194B08C,27AB0FD1A84FAFC3,F671D839D8B92E21,C6D5B28C698E2B09,C7F06BAB408B5DF7,000000000A851E4A,69A807E3F1D4BB1A,B1D5607B146D44C8,BDD909CBACE38F72,F02CB1BF4D5DF128,78004B34F7B69D02,2564D2589A33081E,DA041A986DE15850,822A7B905C2782F6,B82ED41513FCD176,00000002138FA986,C9BDAE28FA19E1AB,BF4746F30E2280BE,C4471F7C1CC09A46,90B6725E006669EA,7B8737C8DC73E93D,9EE0F92E105180B3,243CCC55A17E10CD,124812053557BF90,D39663345F35E16B,000000010D35400A,2E6C5AF78E6103BB,A2C4CCB1674F13CF,1F94A2DDB8CF5977,4F629F9EA0E6B595,1463D9EEDC10EA83,A64307BCD39C9B87,4C99129D67937534,A77FDD173EA01C31,B6376B115E4B198E,00000001EB92EB61,EF361E332292DCEB,FB0D41F6DC03A0E2,C0DCD774F5C981E4,FED4254D3D6DF6C5,2E7F7DD1CE92DF57,0BD3AE68F9891C25,270659A9CBC2AD88,AEEF8603E1897D41,F00E4EEF9BFD43FA,000000007D480064,B69EB8149CCA659C,708D6847E115170C,C2F8B2373FA1DB86,628237009FCD704E,81EC7FEA4391E571,B86844D799875D31,675A96E93BEC11B7,457489CCA127B47F,F084799CAE2C5049,000000026B78392E,9BD9A9E3E86D35AF,40DAC3AE78D10198,94E604868E98E6F0,BBE2FE7B65FC9E1F,A5D9ABF6815A2ED5,F04AD6B49966B0CE,76EC56FC5B02EAD5,5D8EFEB4C2DF392E,9CA377841B5373AD,00000001711563EF,AD4BF801139E54D6,E03E8C0AA1267B1C,B26BECD915257C3D,1C47669ACE8C9BBF,3476938D07506067,480008BEA664077D,DD4FBE1D681B9790,43123A2D06FE4B57,913B878959DD9E58,00000001BD2AC44A,868928F4C1B97E90,0A6089E77BB55F11,066B0A75C723A757,E2A1EB3904C5D6EA,07510CA29AD77232,5788ACF46C22A9A7,B4EB88AB14E084C2,BFCF777CAD787683,0362D07441F8AE64,00000000236E430B,E1491B868A2F535B,677BBFA8BF471F36,5518CE554DF605BA,DF9CCA82382CB48F,B291F60575CEC7B7,A6494789CA9CF549,4953CDD1F633E590,CD9D6E5644C49BB1,0D036E1B68E4C3E6,00000001F44F9E16,4F6BCF962D121219,942E7021E773AD5E,BF596FD583B8E028,932316321B781A8E,7637F427CB31FAD4,7DCBB751D8F6074A,BE3DA3BE996D4274,906F96021A2A8A7D,51842E10A7425DA0,0000000169574D0B,6A282837E75A3BCC,80423B25652880B2,BD63F6E4F06B9EB8,B8350C683BF6AB1D,D6222E0B5F079CE0,2C81FD46590F0DB8,4DE535B8395AD98C,51E5975F9AF5EFF0,AEFA9CB38F36CDDA,00000000CDC4FAA3,2D630A8686CB0410,3C6E233F2A870333,8F25E3C5E5BC26DF,C041F6AAA17CB784,80EB53228DC490AF,F1BCDE543ED18688,A31C50908203E9D2,D74D5CB2487573CB,B7179E14D6C34154,00000001AEA5718A,8332F571E44ECE24,B5C597FF6E54EB87,1C2E0729FF143D76,966D2064CE8DF38A,0C865EB66CE03CA0,48A6E090BBA53F33,DF5027338DAFB84C,034CE95BEBFD30C7,5FB1D45E11B1AAEB,000000009B2CFD6E,00885C12D4653A55,9E36FDC5244DC517,C610A629A7B65DBB,48D57B510B327902,7D8CE0BF80B94A2B,98D2CEA252FAD2FE,AD57753CDF4A3C26,9E89606AA8FFFCEB,2A09BC12D0BFBB18,00000001B9D9DDBA,ECF95074BAD0836F,679ECCEBA6763162,4154D5DF4339F9FB,464CE6234A7F3A45,E45FCF70E3FC363F,0A4C8295576B4239,FDC44574E1A48504,7EB5E31A9314E883,BC7FFE67C8338AF9,00000000CD630C8D,783176302AA2A61A,77AC48C5EF262D4B,495CB3FAB257265D,DEFB35E7782D9ADB,523B26C6C37C6816,4301027E16673248,4B3F7328ECA3F818,C700BB7B72A2669A,CB8CCD1F4F38F874,0000000051B72939,DB287222EDEE8AB0,2B92AD11CC650731,147DA785B0FEFCF3,5FFF45DADA0EB169,E6F7366214642E33,DE27B7C63674BC52,50B5968FEE6F894B,62B1C3FE61C864FD,EFBCF60C80B32BC6,000000018AF629E4,47BE9204768F45AE,058CBAC52F613617,BA4EFAEC35B1236F,E709284080DC3D8E,7154D1BCD7BD1F4F,63767BD46EB2A499,A8DBA241D7D57B86,973AB178B1637422,8B27218F78037ED9,000000012F3FB8F8,01C2006A3AB4B46A,901A2ED29B764EED,50AC53C1352DA9F3,8EED95A9C45A10A1,7011D885408887EA,EBCE5BF407324674,8D1255A227F62303,FB73A49A695B6E5D,2036E8836DE23A94,00000000993414BA,66BE32F3D28EEDDF,DDDBA2570115179D,151FD18FC3094034,21573AC26AEF8693,3E44AAEA2F58E411,C1208EA1503BE1AE,F13165D908CD2ABE,CE8943DC7C7ACE42,09566F92EADA226D,00000001F501B134,8FC78A7BFE7E7D2D,CDAA781401744A34,7C2B850E5A545A89,E5AC6B66127353C5,99108BB5D111B696,89A7676B80F40832,9618152696E9F245,D77AD19F6868F1A6,97120933DA5C0225,0000000129701DAF,884472F09B4D72D7,9CA43EDAA44C5D9B,3AABED20717CE330,B3D9A803CD1A0283,789E6DDC2ACD46BD,31E8F65132BA7A14,57B363E4715E4DBC,3A133AF2DC4374DD,7FCC119290782789,0000000247681763,236E6868B155CF72,63EE1A96E49C6C7B,BB576D15C777FAC0,CA32E9F31E421143,162F23ED7AC24DB9,783679977A49BA8F,5CD317917C77AE21,B4AF58CE2A8AC0E2,5006C01A9FD02177,00000001F7835754,F772A4BDDDCE525F,EA0E00094A8ACC36,A950E6586D0A1526,90889950C4C7C35D,4E3323197C9EBDC0,69D4750862A17EE2,22B66BBF5D0C9937,CAA4F4D20863E35E,D19A634E0F8A9DB2,00000000D55889E5,00B8241103226D64,0E335425E3A906FF,E8D9C2B410EBC1A5,7A36BFA2E6EA7513,58530E50409BDBC1,62238E3513DA2682,ED8697A55AA6FDEA,6FBCA6E5B1D36E0E,47B1327F79FDDCDA,00000001DA3FF4CA,A83214FB722F7B3B,C91ABA99BB0FB230,0E9F4BE267834E76,4DB66770AC774030,E279F011DB02B443,2D7B03EC4C1E5C2C,67A35C2F0016AB3B,59DA3A81E1D81EEB,1B60708E222ACD73,000000015C2B3EF5,8216593F72DD974D,D2695BAFB224DEFD,086F09CE019E80CF,5997293A2FFE2A32,A82CD4188612A003,AC848B978050611F,BCE270E384B85707,43ECDCCED75AEEF8,627341B7DCACCCA9,000000015E3A4380,4259F1A64CC8F418,DD7A6614E94B9D8F,8283C43ED4A1353B,FE4D35D02AF8732E,4625317CE4EC9D8C,5B12D40E33076351,37577EC3F466FD86,879C5B3290039C8D,5A6043BDBADDB99D,00000002568001BD,6AB8FB3FDB1E855F,7AA71169C6A2B83E,CD5B27C5E6025912,7C01FF5A0E0C1CA0,C22C201F6482FFED,6E79314A142A06F2,16A405CF129A4856,2463CF586ADA5D54,FAFABCDF528A957E,00000001B8892467,C1DA3690E9CE77D6,723C57B496336E4D,E9A1235A8A7F88E8,18A93F0CCA760A67,8826E973957DA40F,ECBA6605DDA5D9DD,3E6F4FDE078DDA4D,2CF1AD4BB050DEE0,7B9425532C21611D,000000012D253044,DD7A377A0BC03FB9,1083256FF950F5AB,30244CA9E56BC3EB,13BA2861E42D413F,7A2D110DFC5977A4,1B70F6FEE3213428,3150903ADA3CD8C6,1FEC7F9375D1F9C0,170D5C9B0D0CFEBE,00000000DE7C066B,502F2BDDEB5EDBBE,31A11D7A6F4FD8E4,37E9FEE69C4BB059,05579D31092683FA,700A128449891B3E,6CD2BF1CD27ADE64,1E59798ACC194B18,B09E321D7218A8B2,FF67F970379DC5CE,000000027044C288,0B7AB9FE89971430,443AED30657D6040,B833163B0F1802B8,72F3EC4EC863DF54,08919F59C5914A9D,8815962FC52CD526,85509A0F79779BAD,B11B0AEC3409549E,51E29CBD27784F28,000000003C7754FD,241D7386F95B5C61,01406C54AE069086,006A9B09D4B6B1A7,683BA404D52F60C9,C510400E607B3304,B3349736C78639FB,7C4B05D6682808D6,F4427D9DA73D2D9F,967DD0C2BDEC84CD,00000000D5A447C0,4FE6F363BF45493F,3113441DDBAD2D69,C250D6020203EB27,C80AB01FB7B1421F,3F9BE6C88EECE7BE,B199B5416F7809FB,D635BFFA70AF0C65,49D88402EB5E1829,2D17B13DF09BA648,000000004577B6CB,3B6C9CB1D3CD0235,8211E615771AF82F,AF7E438FCB0942EE,420313F632978343,5A65EF80D2A3F879,F2B073665FBC3A10,492B316C79162926,8469A83B89CB5651,78286FF9B5A9F48C,000000016AC9AB49,0092F4EE7D0FAA1C,CE0136A2624A3BF2,BA04BACF53FF910C,D8029C37E49B542B,1D7C26DB9AAB3461,CFF5154CFF326866,6F87D57145A69D95,7FB823EF48B6BEBC,C8086608FAE41795,0000000099FAB5D0,67F2BB37782569CA,326F2755734C0045,4139573C36759D67,E3393752F1B83199,1C4DD983533BC4A6,E30E54C6C5F7664D,EDB5EFCD05FD24C7,A796823FDFBC9122,560865B1E4C70855,000000004C571EEF,AE7265F95C3FE55D,9916EFA8FF83F4B6,1F59CD047C647FF5,49B2CE9AB8D1E7A2,392325A5F0605470,66C89BE524B0D3ED,03A6B287F49475A6,1EF0F5BDFDCC976B,5BAD96BFC4DB30BD,000000024B8231B9,2D8FA725148E56FF,7B1A18D2E0B7340D,72CC592B09D1AD0D,527DFFC0760E93C7,0B972ECDA9539C83,D71D0F7937237422,B9345C593C915EBB,0A066A887056402E,B3897B7FF9CEDDBE,00000000E7C56174,770FE95EAC4DA7DE,3AF22732C119E231,852F7D65A2A30454,E73D5483B50332C8,8EDB1A1352547BD2,4EC6B187295F0DCB,E4EDCDFFA8D2AB1A,35B2D13585578D5B,B42C587BAC669AF4,000000006EFEF954,9DD72306634BBB3E,4D6DD1B4F946E6EA,5A3708735FC07378,C2C8522DD0DF8448,F51D8E06B3A0690F,8AE07A4D28144FA8,B88370E36DEF90C5,50F610726145FDBC,C2ECD41A8E36E155,00000002403E4ADA,E5FB5A29855EFC1B,A0364FD7DE6E9DBC,7FD349FE22EF06C0,3781BB75DC216BF0,109CB390DFF9C08D,9225E044B8A5710A,79BCBAA7B80D4982,B25A962DF8E31272,38C9DCAA9D8A2EFF,00000000CD940706,06A0FF127E9CEE45,A63AC51844E4C2C3,FF6B109ECDD6D416,2196064EF6D757D1,832E66544409AC76,17F6972C47CF2BEE,181C49E30FA6C874,6A8256267C15FC60,CC82E3F6BA51D270,000000021B0DB971,4E0FD8B507765EF1,AD375F335C617350,0138F385827462CC,080AEB29C84F1C27,F49070B67D3C82B3,AA7078C1C401495F,40B6643F84D0CEC7,1C0EFFD9A4254065,C5C7426011AE19A1,0000000158A69629,EC9B362304A5C7D2,54419FBFAB46FC5D,2998B7C2F7CD804F,9565BE489CD4158B,E02050F54E2A218B,54A13477A445CE70,8A9365687046B591,C108E11963E2EEDD,BFC8E4B1904FA6E7,000000016F77ED9C,1449CFC256C8F741,57CC2BB488F18EDE,CAD80FB61A0D788C,C5C2BE13E9609BF2,0906E39028519B6B,B03E06280A04C332,93E6D40F40E57178,8301C58ADA179E59,2DA101F5DB636A9A,00000000D9399914,B57FD474FD506147,EEF7B06F9592F74D,C80EB0475EBC2AC3,1ABB5A7B72DA0BED,80A8D2133D01B83E,49A5CB7BEDF04D98,E98591CA35A2196D,FFC0CABD7CF19FBB,9CB2A7C885D2543B,00000000C442F753,058DF4D2D9298647,981BF44D38A8FCCA,6D70F2CD6E8F9D81,456C06B770D0DDF2,2144A6C6C934573F,C483F659910C0AA3,4060D7BDA4515909,E78EC350ED4FCF0B,E1999BE0F3AEA13F,0000000044E5F953,30063E13238B71B8,2B96FF05465297DD,D830D621A05925B9,9C00D65CC58BF5EB,F09FB0B7250B5826,CE983E43AEC03D53,8EC7460DFDA3E02F,9E2E30FA0DF9FA8F,1D2FE537CCA158D9,00000000C21DAFA3,C628C02EB3862E24,6F00A5E5E686B548,71A49290B6016722,E09C1D4DDDBC54AF,106C1A83F7F04BE2,D3E7CF8896EABE54,C524C9BF298A73AF,97A27441ED717B6A,CA807EDA45FAE65C,00000000CB0517DF,65A792987A308A73,7CAF4952750CE43B,EB15411E1CD97F31,648EBCBCDA2CAA4D,9ABF805604914246,94BA15F8ABAF5BD2,68FAA2723F278A7B,B1FE3FC02620D707,93BF4524CA7BA333,0000000274A6F66A,1B88F5F5F93209D2,30B70A7461249F98,5CE2673C2B70BE50,AAA7A0211EDF41F6,369C7FA23F57F219,91A6268CDAAA34B9,634E63EE8143D392,EA3D9FC630F5E373,96FD8F468CA3AAF4,000000020E6E2876,1BF20413C6670EB1,842FE9F593B08351,61DD5D53670108BD,C5678D7B825A2636,1F8B98A808A16A3F,891384FFEBE118BD,BC6C137B00E51E76,E5F06BCCB8E95F74,2CAE667D8F67AD8B,000000008A3A67CE,EFF5ECEAACFBE384,3431F9118973CA08,7CE7335AAFA3ECC1,547302DD3BA3FCE1,F251FCB8E49A2A01,5BAE46DD415C6188,64A3EB6FD2F63EC2,1F50B756F158CAF3,45FF49F36248B496,000000003A7255D7,653B21C206F84124,5AFB44DA36E7B6A4,41718530BB6D521D,16D1D3E63F32F376,95220EC34C3B00FB,5E0B91A045F6B5DE,26AA514B84C71968,095A08E72A90674B,C199EBCB0E870358,00000001A5424523,9F0BEA5D26C2E796,10E8C5470E7F676B,1D8A1F763AA2921F,0467A9D7AFB902C2,A6C5B24CCDEC1F6E,92D530637E8F463C,537D5CE3C1DE14C0,DB7C215208EC512E,2B7891AD2AA97B19,000000003E9228D8,482C81F1579F3964,82386083ED427435,BEB276B7236D6451,AE7636278FF7DBEE,7F87DB9F7B4E0074,91C593FF0913FF33,4F45CCE9A95BD2FD,97DEA3AAFF63D7C0,E30C88629AE71DA2,000000014F2B2B29,7F4733F74B6B7989,2D96BF0542D9BD37,224009CE169D6630,2E16050E68E6493E,2C9ABA9315B199C6,C60AEE61156951C4,BBAAE00CCE90EE06,89E2C40A9D2F5676,736C18F4F24D5050,00000000DC3707F4,8FAC448263D8C24E,22BEACF8CB44E5FC,D612DD2F3843733F,BDE888D5E87E7925,DCA5DA6DB7A89C01,BEEB5EE97372B277,CB17BE9E8DA14462,A014238E3E391FCF,FD35D3CAB843A7D4,00000001751FB61A,24B8BE30E7C36CFA,668A9A7DD4477498,97E4941AB8A07557,CEEE8C02DE96CA08,A71B5B2CE10F9D2B,6A3AFB92A93770F2,006E932277873CA4,00085D1FB21DAC3A,3D32D674EF8C19F9,00000002500991A9,0E7ADF886AB4AF8F,1F7014B3FE5B215B,B30CC8DFFBBDD944,8D6AAADE0012B94B,98F8363DD28CD402,3F090E39D989B7A1,93979EFDB09003D6,6888D6C334B81F21,7D44ADB83803C94B,000000017C870EC9,9B93824BA050CD67,991F62777BA6A52F,B817F4E52DDADEE3,891D079E26DED17E,EA387ADEBE95C58E,89D431319C351780,2C4E94F3B58677F4,C475071A39CA4085,30A7571DE6374F84,0000000184DD232E,02E428DC5D58BCD8,9D72DCC07BF172D9,2628102BA519A788,C3096E9276EDACFD,DADE777932574E70,7B54ED691794463A,01DBC5B5B1A68E6E,F27A7B5800ACC01A,88D16891F037D7D8,0000000104F0621E,C150FB1B89E38428,3D2114460DF1013D,A3DCF896121E7279,554D8C9F484CF0DA,133635BCFC1953FF,B8B7F747DBAEF9D9,DD812CBDCD1D39AB,FC6672309A952474,D6CD508BB0F33D07,000000004926107F,71B0C9E75757D154,CF35A3960564B44A,1F791BCDF25D93BA,F3FDA98C79924EA0,69F0C51D74A10FF7,D4F8816A82D17436,CBC0FF64BFEC92D9,626FAABA5F2702E7,FF2763086601AD56,000000014012FB93,191610CD3E8B63DE,93D5FF48B2146EAB,CF6B04838D92BBA3,24FB519A5E9ACE93,FD6E95BC513E4C25,DC3DECDDA2FFE356,FCC2F15D6F1521CB,DE3BA614998496E4,04DECA91335B5F59,00000001AFFF5ACD,BD4203FE5A9E8A5D,B1D74A53ACB545F3,597C79539628A624,F7A56214D58307C4,BA7C9057DC0C0093,F8AF1700F7589AFC,F057BC3E6324E028,7473BBDBA425B3F4,2757DA859CBF4A4D,00000000239C0647,8C5771867C02FC75,7928628D90B05D47,164AA8BD1C851FDE,8DAB60EC50212C22,FB92A45F3AF0EB37,41150683FF463BC3,46B66FF6A7DCD79D,A7F65E487306E372,CD978F4E5A6723EB,000000018B5C7234,E27E91F913485142,EB67988A59786C40,BCB7991C51ED5B6C,F26A06B3B1B96AD7,687B54D0D58BAC09,1E611172886B7C07,B8535716B734F031,5506F02CEB26FA0B,4FCB9E44D8268024,000000004AB1A7CE,45CAAB7B607F8FC5,4159A38FB916F48A,64DE10CE2472909F,B2A5FD42FF7B78BB,EF2D8FCBC56ADCE2,F5F90EFD7E10B36D,60405C3D8E2126FF,F43C8DC6AF350A9D,63483C2AD18F71E3,00000001D328B8F6,B68E29C70C66D885,A7EB109362004798,38993AD013379011,5BB835D45C1BBE3C,E4E19EAEB85B4010,92E3E7FBD5777CF3,0D860C51AC117E3A,D208BFD314C604C9,FACFF06F9318657F,00000000D4CBDC75,02EF9C37B005BF35,2DBF8F2FBF7CFB0B,6A93E0EFD994996B,C9CB66AC09157D46,44CE44ABA60FD164,DA8831419565729C,8845C1EA2E9EED91,37C97209BF2A300E,CAF91CBE8287A748,000000026E676EC3,38BAC6F19F22066C,7DE3543DE752648E,6FEB05FAF543EC51,EA4F676036613A6C,66E2E2329C192A76,E3314F445ACEBD0F,709333141926FF9F,A9B13EAFC16DFD34,FFFD48036BA10045,00000000F0CE030F,BCA9AD3B54AE574B,70059C602F7664B4,41813AF8F6DED159,2BB2BB5C0DC39789,4FCE1BC2140EBA9F,C0CC7645C056D0D1,9E4CF8271C7ADA4B,2E71D2B949C02261,36C05D2EC86EC713,000000016D921FD0,DCC11FA46005C36F,037583FA484068A5,5701B522FED4625C,21496602AF6E5900,2F9A04F5B3D25180,6207A23608B00567,B7F5162AE1261BB8,9342BE9956F4731B,AAD31D942ABD8E89,00000000A7997C47,9F4F11973DE70667,A8E455F143B22F4E,E7794264450ADD52,8461F8F4F143F898,57BEDB6C7D2B8F3E,C2FE43FB75ED428F,AED70E98F7E7582A,0C50E1D37998A9B5,462579F2D3A650ED,00000001694BB82F,DE0869F3CAE3BC97,E40A39D28E2BA6AC,31D019C9C262B7FC,63E27DBF44086144,3932921CD4661633,D7199E91D90993E6,112F7B36DE0FFB97,FE8E32E79B2020BF,3AB0381F7A490A9A,000000008784CAB0,DB4ED97ECA341A63,86A8946FE64D5FB5,B73DC2A1417EDA79,66A3B80923119EA9,65F2DD8BF115658C,632376C0153D5623,3F3FDDB37106D093,8AAAC543A45E6C89,9831507C58B70AEE,000000001EE23067,B7ADB3519CC07272,110EAF498CEE8CF3,FAA8719D5B82313F,2E76789BFC60DE88,9C21F82141818128,046DEE27AAD4BC37,F1B9AAE3E9E8188D,2C3579949EE99232,A6E0D5A0C71FA759,0000000277D7B365,A09BE7CF5FCD1C8C,4D1A20A55424F23D,F247E1201DC6DCE0,95C8D6FF2D1CAE73,0BF1290CA2233422,99F6EBE7986A2313,AC1F38CA825060DE,FD6766D51000695C,39672264531A5126,00000000D08C2D9E,35A87A9C5B49AB86,4A73EC733ACDD042,91993CBE38729E02,C1ADA0D631B47007,04DE97BA25C615CE,83E9CCC6B3E00325,AD1C155FC5633243,B282C810C2C8EE4C,EB92F879B21565D8,000000020AFC2EE4,6DF35DC710176523,D617C4352AEE33FC,8F3737102022D07A,28C4159EC7452AF7,3130B66603A55986,4F56B9D38AD7B195,18DCAA15D6BEA6E9,827E90DF044A58EF,F532E53593B4E31D,00000002286A15BF,3870412FA0E47741,3ACD251040846C95,72E15D56CBB1D300,1C8CB401A990508F,F721D4F4B27D1887,0402DA99C2742392,24C8B4BB503C83BB,21685E9C9DD5B0BB,DC34F54AE52DEBD5,000000004F99ED28,7983D01AD672746A,12A13D5E950F26F6,6611507838D1A704,B536AC8C92EC0F05,32F8C0AC4EDAC754,A8D3E6F5F77117F2,E1D5BBAC0AC2CCD4,60BFBDB7E5AA5EEA,1251CB9C054AFC35,00000000DC244A5C,6B39E2ABC3B8FD1C,1C02D5136DC766D4,6DF52BD10A635370,47F09828A577311B,10AF7752BEB1D623,4A9F1F059961D0C9,26F32A59A8F9CFD6,90CAE776130328BE,37317BEFDC6AE24E,00000002239ADE25,38C8B83C304F5000,8F92D78B918C4952,E5FA0855E2515ADE,FD4B16F6AAB2DEB8,BAA7D274163CA472,DDCFF1335164B3A4,F5BA528962B05884,1D04F50E92D60E28,3EB19FEE4DA4E3E8,00000001BD73C033,D0709B3CB5DACC88,2AAF2174D9E3D95A,526262CD9601BA12,2AC9590A0736092F,11FD250372C4122E,D5339738AFB67804,2DF7092416C2B555,52B2E19A0C06635B,81E1ED14C633D751,00000000D4956C14,FE20C08324BC7258,3DC0763EAD690752,C572732BCF08FF8B,FF0420D87A56D4CD,0263EDCC00D468B0,658766E934D33F82,CCED3851AFAD7838,EF4FB3BED0FE5720,6D3BE1995B9A14F5,00000001D6E9B52C,931479DEABF61C0D,B993F6A09999DAFC,CE9EC11C549E1FCA,2E801D287087A61E,FC990018DD8B7E77,DE1305A12C4FBC67,3DA2A2352A434396,6855BE99FF9F55EB,EB07C819AF966DA4,000000007A500207,CBC69DB0B849FF87,19691F952EF823ED,97341A0258E044D4,BC9C9C93DE786D87,AA5977D1BCF72370,27DBD30CB37006E7,0C6FBF6658A241A8,86EADA2774214324,97ACA6D1BD4D4BB1,000000018A2A9E42,0049C21686114CC7,7F3A05B05642288F,67AC2AD8951AAB30,2BD28DFC9CB6CCF4,3931B3FAF2C4A690,B11D9939426560F3,22212A5BE2BFAC23,E926A6F5C28170B1,892A8B6730FF0FED,0000000258495FB7,9AAAA1A44A502EB4,0CE3A8818DE7F81A,50941845D9812F13,9CC631F846B07682,28345153E92A9EC1,DB7CEA49EE214E7F,B565C60D0F7044DF,C0B2DE5FEB17F018,4F4972D25C2E59BD,00000002625E15BE,F091884B6C1472F6,12E28DD0877562C2,C4D65EB2B16A98D8,65C1238020A10A00,E100823F768D4259,DC295EF01D6F02EC,424F48AC10863DEB,2F1778C934DA22E9,D5E04EECA9644890,00000001C62B9ECC,240A26F04B486E91,AF5AECA4187FA330,F656E2F46F39328A,2F2ACD655EF5752F,AD4981A92D1DE444,243388D7ED7BD316,D0B11B83FB42FA1D,6D5B970CDA0E2A07,6F952E9259803B15,000000003B0F3C0D,E78A98D76DC267A3,37BCB795B7D4BF5C,2FC38C2C21DFAA65,9D13D4F8D5A7B4B8,B27AA13E88E8CBE1,E617F51F07596CAD,5F3BFCFCC57AA5E9,9187A8F98F5D8D65,0E5536ABFDFDD822,000000010BAAA613,74E9F2B752B9D57A,7C88514533637A4D,DB1316844541D1C2,344D13D8414CF1F0,B77AEDDDC0E7CA51,9469B08C4A0AD9E9,5F2586827B94CDEF,FF9F81C455CAFC83,F0167DE658989848,000000003155A46B,3672E2BDEC28D318,F5B84613BC7B8C3C,2EA31E7BE039CAE1,B25ABD1AE8284D0C,14EA725BBD6E91F2,42F7168F7AAF1DD1,0C9B4AA90FD165E4,526DFCB2F62D6A28,5069AA9B00017E65,0000000250B9533D,C7A638D386A9DBF1,2A0D9F139874B540,BA5180FF7F1839B0,3B95CCBCB12861CD,8AD5915B3D027BA8,5195B91F6DAB6B5E,443641AAA6EB2477,2364B9EC37D34B8D,6CCA4EC22E4CBC53,000000013A88AA0B,4C1CC7585A52307A,904B55EBD1982157,2B74046E48FE9D75,20A0EEF9A41BC591,61D2166ECFDB2F93,26885BF95A355492,E90DD553345AD606,3FC39CEC9D39F2F9,B72E430715B78D7C,00000001020CEA6C,4E1B8BD40F376A07,FC9BA034C72E055D,FA0BEE06D957C388,CD21499B38EADEFA,CBE18D38E1C9EF4D,D6F2F224098DDD3A,147EDB37D6A52C66,ED6961E9048E6073,9F03DE4A00924033,00000000918772B8,B0C37A1E4F672791,33927B2DC18EC845,DEC163A1C28F1A2A,1C89D46D1777C3E1,4993F42FD265B94F,3D5E9975C4457A05,F81A3CFAF161CE19,50BF8DE3730D24E7,DA719F0050210810,0000000236BA7653,B01F59E4535C12E3,CBB66950281C0D13,DB2D213BF93117DF,5C704D5E6FE9358E,988767C910B03B8C,8203A0871135C046,40819ADD9CF00FEE,CF7F28D96C16B3F6,F8CE010DB72A6E47,00000001465B7817,7ACF324C0803DEE5,AB5E955AB63B5FFF,EBCC482942E98AA8,0314CFEA7A499A78,9595075377DEA456,776CAE0A3786BD0B,3BAE5C2FCF996D91,7794AE45EA050152,8106AC6E50FDFF83,0000000044648E34,7A3A1D5C57F7942B,EB985FED410EF779,D874BBF3F0BB6216,FE2F642A4A74F707,088D2897987A170A,F593008373A865BE,C4D3ED6A89593B45,C7D8AE68D716DCEA,2933064D42CD9D06,0000000246FC0E32,D6ABA46F280ED805,8567BAE66C7897DD,A3CBA7E4180873C5,1BB8ABA0A71FF778,437286FB3D46E66E,8050FBA289B2BAEB,DF63BABEA3930A40,B6CCA7E91BE12844,6118E58FB8BB076E,00000001E4FA4BB7,D3912302AE3E258D,0B34D7B4AAE621C6,48371146936CC364,5C132D32A7584B33,E774F3A1DCE585C1,B0DFBF3ABD6B5988,0F8F949B9C23AAFC,2294807989DFF099,CA9A4B604D142817,000000006DF6683D,ED0A81273301C699,27560C7AFF1C10D4,1F374428EF098E41,9B3BF8122387A152,F0A3A6FE73673E47,A8FCAEF323041F7E,5DA5364270156958,A8227034C75BFC17,F4C8DAAF87ACAD8B,0000000195CF97C9,AAA36EC56CE54184,E0E35454F83CF833,C72D40AA008D7125,1E54327406DC3D1A,10B9C6FB6CF3E684,CEB64B3B67582EBA,92D1F86E834822E4,ED1EB9DC01DAE218,6463E7EB4A7AA8CD,00000000FF947804,9B3C49102C4C00E9,6F6C8A7DA4C5EA99,75D0FE596D65E8D1,28BD9D9B6FB596D7,4C27471593396549,AB039FA6ECE5A03C,92C960073ADB6BB8,46BB9B237BFCF1EF,54D5766B35A004C9,0000000115F041BB,C8CF955AFB0FBC15,8A71B696C6C9008A,222D5ABF07344779,CEE8820FC14936DC,81E36B4E89779EEE,02D9A279C0EE02FD,E2B02F4C74CC30A0,92DEF4B3302DF67E,B8B7BEFAB7107DE2,000000019C8D7E1C,214166BE170B9894,948DA0BDB5C24752,ECD1F9E8EEA1AFB7,CBE65803B748C169,91A0E4722E77D862,F32BC680FB33AF06,A8DDD595D810D214,B6CA6FDBE506FF52,7D4A6C57D80E7255,0000000015D41943,3EF61F6F4F46070E,3D36AC8A41E44CC4,A63B601E4CE8BDEB,95BBDCFE3C261874,3230294B33E7C01B,D9D82B80B0AD8187,8D7A82109F84AE14,4F122E804F106D0F,F582553E2FC1A83E,00000000D65FFA12,89EDEE0326D69BED,7EC476A93BF42682,8C7ED58CF1165CB9,B371878A3E030550,063FA3A05D2ACF5E,F85A3DA2EC006576,82B67C1A48292E1F,65B7732654A8153D,9E8E1AEC48CC6AAF,00000001F2B22090,8918836859A5D64F,B23E33BDDD0B001C,EC6BC15DC4BDB926,105FF0DE88B85CD9,A2665C951851C8E9,AA1A12864B79918C,E47306F68D6C9FAA,D0AC19385538FC50,1933A6A40813A320,00000001A2F8B234,A5B646BC8DB13A3F,78BD53848E0E7AC9,9C711B6A9521CB8E,FA5C81F3F3776D97,0F71FEDF9489B3EC,DAEFD5B4B846FD34,6F3751208B91BB7E,937B354D9F025D1F,8A0E9CAA808C73CA,0000000177408807,7010F35E052DC0D4,D00EA2D55A4D050B,FA611C9CDC5C000F,AD619C7C9C3729FF,82F5657FA94388F1,4788C7364220617E,BA753EAF3CF24401,738023A2E6B4354A,012AB909DBF9FE3D,00000001F2470748,EB18AA7804CEEC91,9D074E05FB442381,50AA606A2616C6EC,DA0B4056FE266FD5,B7341E97711F8CD3,E921B6E9830773F9,BD1AA1EF327B278F,06E8D666E346E9BD,8DEA2585731EDF5F,000000015BADC7A2,37E9D80A2422E466,B212486FD9476B65,185C7989CE23A96D,AC6B3FBA418B6173,5EE928B14F2E3C4C,F261E94D8A32AACD,124805D7192C50CA,8F820B4E98C5BE8C,0E369628F14B2F2D,000000005FCD550D,DB332868FF42CD28,B9B77510F06527C1,3872B63E41FEA838,3F41489D65622E4E,224D2DB916E21358,AE12732D78551758,C6B148960E2EA47B,7415E19CF3273B96,A7B0948E48E81A74,00000001E4AE7CE5,23F13C3D2B5DB7C5,58AF31316D84109B,FB4AFD1D97AB41B6,5E539D19F8E2032B,803047CF9E0F2B87,933A1C567DB69DAC,A939438C4C6E7DD3,8C114DE7F3A2C51B,B8113CE15AA784FA,00000000076C01AA,FCB0F6644FD70075,22A1D247139677C0,099D02A533F18F44,911EFBA9FB9CA5A7,D08E67E894E91008,508B3DA78FDD28C3,99B80EDFC28BFF8F,A45097F3A618E693,7F9249E4194D1508,000000001790CB25,4AB7340709BD1FC1,CAE86312BBA47DDE,7D02BD1D83E45790,DD473E265FE6E745,54F3DC1812FE9F2A,BA510A2816081198,E6600A317DA10A0A,18BE13FCDA63B154,9B296AEDE64BF4E1,0000000231A4D400,5E53076ABDF25377,9389965B02B19EBD,0051C927236907CE,BE6481A881556829,26399FEA0060FE37,87A702F67EA5280C,CD275A240E7CA195,34C25CD7EA96B7E6,FE22094641F12230,0000000212B27B16,CC32E46DC7002A31,7ACCEB7F144582B7,B1770FF771D3F340,4C81E90440CADEC4,E53ED40D76DED3BF,EBEE76C163E1F9E0,8A9C618E4567E2B2,B0738CD5A3C8890A,5AB4EE09D8A1CC28,00000001DA724B27,994313C5AE6D9BD7,67503C203B13FAA0,7845F0EB98B70D6D,ED694750961DE2BC,7735D1FE26C90F5C,E01376B2FF1D1E09,9835ED433E64E635,FE96F5D0D336B082,7E697D994499B114,00000000923F2E6D,B1EFB2CBF1FF5EE4,1F480E95667C9A0C,D5E7B081F69C9FFB,C15B888879CC6886,35CD1DDAB648D1CD,A9897EE26CBCF174,D02B52B94DCDF046,57D540B313258201,FC62A8E57A1D1B68,000000013C37C322,005D114C6A419CB5,AE7942BA35BFE816,2621267BCED97DB9,59A83D70C73D6A2C,D4339E2467052E6B,F20B153147A66603,48B4A1AB200D765F,6034275FEEFFF1A7,B4673B7BF1DAF646,0000000033BF02EE,1FC5ACDA07DEA6CC,461878C2C6F83F68,5C62C036723901C7,3A7EAD2EE1727CB8,05771B4EF441242C,3BFA86EF23810669,F88318BA07AFC5C2,E01F1DE042270B8F,ABC669CEE775D0B6,00000001EA240A7A,CDEF761F5EA5D3C8,FF57332F55593EFC,FAA18C59438F7D6C,FB1D41AB1F1936E6,204BFE609526A3EE,FB823A2A8C2FF147,AD38F244E01C64A4,1EB461B2B9DE8176,90EA0778945F4D1E,0000000133CF205C,32486712689EF2EE,E7B713C5EB614F7D,A540B0C2E45E6D46,3EEB7BB6DC64F64B,B66D5F653F165411,CBCDB44B2B37CC09,6EFAF7AACED74D7D,D754D137294CDB48,FFA1BD907CEEBAD1,0000000103D9D08A,5F5DB128439E1DD6,223E1B5159BD3630,B6467C18AC3DFD21,F500F2DEC9466386,A7E0DE9ECF5D6E70,74F08748D119F392,BF3B52E87378B0D2,15D4B6139F6EA63D,3E79B5DFF59DECA1,00000001B976A8AA,E6A8D99495504F36,854C0DBA7658225C,52261647D6F41935,06FBE834BEFB571D,4C396CF3129AF5E3,C4D52985A1E99D47,47DE02C1573E4B8B,B7B40FCB14FCEA9D,D31194D2BE155D71,00000000C468A2A1,5C4B317F971F4B16,CF3E6DE72324A885,3FC5CDB20BB5F248,64BFC4641B95A932,F2D204B6D119E67E,098C241E7270392D,13A5B4FAC705DE50,9F645B771A9ADC0C,97BF498FCEEF8191,0000000211FD92F9,7BED9B030EB536B4,5F41A693F3440CF1,AD872A13DF47B239,657C49A5B1DF891B,9FDDB73CDE1A85AC,38730A36DE370C9B,F0C697190EC6799D,E4E70764F4C7EE84,6BAFBBADF6D00190,00000001733B321F,5040D14F30911A9D,C279AA467483A604,25F507CF8FE55614,EF728F5996F12618,1B500EA49ACA3E8F,818B147989F63BC9,CF23DE7757BFA303,F05AAF3975D5DF80,964FB03A15EB7DE2,00000001C0ADD46A,238496F1F21B315C,DCFE5B391BB192DE,97F6E4BC110D2B32,EC96B3F227ADBCB6,3C6C15F8597675B4,7E4BD245F9DF2C26,503AF27A4E2852D4,7036A18A8B32AE03,19054C3897DD86E8,0000000170864378,A7D1895E7C2E2982,E03B2A9908257DD1,87E930DDCBB2C14D,D7A9F0816EFE6F3C,FCC18A16F3A67FA7,CD2128CDECA95BE2,DBB060902685729C,22B0F351B6C850A3,1521A480FC41DC7F,00000000450A0858,D74D07C850B8C433,5B34C705E5A9093B,A3DE573E6AF66B56,D23DF6C918642B44,1668AA2B00E2BD94,2A178228646498F2,D995AC1858AB4143,289E2B502CD25334,3C4F122497E93047,000000013A624404,32C93CF4EA4C39A9,76859B1BDEE686A5,15CB01781826A42E,63E72E4726059231,2912ADF2F871AB1B,017B81C7C173BF00,253D642E39700ADF,8EECEFDAC201D4BB,229575F76E27A6C7,00000001119A37A1,529595128BA1CF65,4AB3863B475E1F36,612C6A8AD36EA2F8,6B45AC0981E224F9,C4FBF355C7F8F7A2,D11F1C8E4FE33777,0DBF8B1E0434D216,0C6448E27525DE1E,216ACD2C738796E3,000000012B452DDE,2EE95A6A154BCCC3,BD1896D2540D4301,7E299DD8E5080471,4889B62E95B058E6,782F2BFE716A51CD,EDA7D760442205C0,7B5F070C578E17E0,E6E6783F716A95EA,E0C899BD52BA6AAC,000000003953B920,36706800D83CB0AF,8A37129C4579C19D,F410DA4ACFF4413D,17E6274AB6056120,D4CAC8903FCB180C,3EBF5BE4642CF009,202A816785DC2240,34F2557FA2266D20,0D553CF1559BB4F6,0000000258FF3A81,8EFA9CEDAD386064,726442E1E038C9DE,B30C2278E479F430,383929A4E914B705,CB240F759582006F,CE8C010E0DDAD477,F71CDBD1E2214FC4,5EB5CD623B9E4BCD,EE4D4BD752E44B86,00000001B62C7A93,7DDC3FEAC59DAC1F,15ECEF9504E1DC65,27C9CF72253DABF2,2080A440259D2C9B,F190A89D3084C020,4DB7D471D850F695,FB401EFD5876C1F8,798A22B09FF3405B,338BAC8A218013F7,0000000137DE2368,23B3DEF9E618755B,EA4AFACE79EC2F20,37865617CC5350EE,05B237F192292276,966F7504AA3C40C8,93F4DBC5747FC9FF,93491464CD5680FA,EE67AEB8BAA5875B,8BCF614F100D7968,00000001C89264E2,F46A371ABD9549A3,0989BDA9A14563F9,1DF53BC7D367E356,E14B06E5EF9B33FD,9B6BD75724807534,28EE154DAB5AA44D,9E7287E5B539D736,7163F2D85A0DAE67,A36CDFC29C9CBD10,00000001AA05F375,D65BF4464FEB05DB,2CC589748E3F5D81,342E8AE0C3517CAB,0A4A5D5F7F791A19,C6D7597E3FC4AAA9,4083171B2D3EBCB5,6ACF27B10FCB3A0C,FAD825DE9C340368,911CD316465ECBAB,000000018FEE8535,26125ED14E365500,9B141766ADE68DFF,33F6FB062CCE8064,70761B3620D71760,07A319DB1D9620FA,5270F5976CCB026F,EE9BA7F0A59C9AFA,819CC12E3CA2665C,96572AE733024D27,00000000855E56E9,643FED710F8D8A1C,C5FADC272F51A4AE,04DCDD4F5457553F,0A784402A1B0DBB5,6DE62659C79E0B6B,D8FAFD8807DEA467,AA32ED1FCD6ABB26,5F696451887872B4,9C1F36247EB5ED98,000000007A972730,6164816A4790FABC,25BC9C7CE907D166,8161D9C37E463E96,4EE01B3F137F5FF2,913296E08EDF9845,E4DF2F76664A59EB,C90BFF5DF4800157,BC1F64F8BCC39854,D98C3B53D8204E9B,00000000C7DEE790,AB687BA634620FFC,4F0E0B9093B5AD08,54E2B168A7DE8EA4,09D4AC482C60734D,30E307261E8B9DEC,174E7485D37BD952,54FD4F895B65DF9D,6AA734EE5A0A397C,AFC9096DF692948E,000000020CD4A626,4D86E2BC5779586D,E8C52F3C261C7903,447F25308A9A1CE9,7C6E4D5F9AEB2C3F,92E9C27E4ADE1B8F,69C6CD47209BAB96,E9A924E2B4ADC59F,5FD839A4D608229F,373ECB16A36C1E86,000000006A20FF1D,5884E4C4B44F5C6F,D6737F70BE560004,151EB0A0D1715A55,9F4186A2D53DBA21,14604D8D6296BB33,138496EC0C10BE94,B8808861156CB003,9EF25418320EFC13,DBB9F22EAA7B40D2,0000000069399492,61DB33F316C36A55,CAF89E5BE5E1DF06,666C9F7D2F93365F,F177FE49CE4ECE05,AF002A21D0BFB656,2BD67F219A437992,16CCE3F79466C65E,ED49FBDF7D019316,8D51E674F35B163E,00000000A48E36A2,9A70569CC6B67AAC,5C2F9E5B76211B10,162A4D2254400089,C9F702C7749B7C91,7D90C76A0799CD72,E27F904ABFE20D9C,F310D8AB9D89AE8B,9B3F7D10A42EB44E,23DBAF3C3953A555,000000014D0C9902,F2C9A05816E0EFE2,C942B713CEB75932,5B69FFB9CC235F15,60B1FCA612B1DF92,AD0F5E71EC8697E3,98B2A3227341B5C5,53C50ECC7083E9AA,B4C02F69A695A762,1F221CAB96790979,000000001E2B061A,F46739BA3707D317,B0C6624987D71FFE,1FCABBF7A33F495B,43848D919CDC7BB9,DCDCAEC88B8AD451,8318A7F5DB868554,EF022BC9922B74D8,EDF837E9A6B2F4B5,192537F756E8969F,000000021CBF33BC,B1C5E94D5F9B6D81,1A2B60212108962C,BDC4A1F8A485369C,9223B014B7D8C6D1,705977287020F6CE,8E2E78A7BEC866D0,046B48B04B5FDF82,D88E3351F7A188A7,614BE39368EBB0D0,00000001D694AEF7,93D65EA66EB6A9EB,96CEA2E0B9C9691C,17AF7E2B6687A60B,DAE0C837439C02BC,A2B23E2F9430E674,91F1C09C62FC8867,1C83568AAB3E50BD,A139DD6546B54F95,A7E68EA363322B4E,000000014B2648DA,7B8A527D1E6282E4,D54F2DDB6596177C,FAEABF69E7529C89,E81D3EBB8B5F9F7C,A26509C9B0033666,D538DF82DC6DABD4,87E3C3724BE93B62,93DA29F2A3529D02,A761199D876D4347,0000000095AAE7EF,1EC9E36996658E70,13A280CA28D6EEA6,552E59783EDF8369,6A22A456B8899D89,E3BE9AE302B1AF5D,454F1CF66219D1FE,E36FBA4DEAA92480,17F26E0DFECB30D4,90D62FDB1D4F083F,00000001EBA39AB8,45D51F4A5A00DC93,34D3E1D309C28E4C,36B47985C5BC664F,DA158F2C67C4BD4E,6145EE8FDAA1689D,FF6B5DCAAAEEA331,C8B6BF5E8D316AFD,111DE1E66FEB33FB,D5412125FBD90694,0000000230AC3A74,1F63071E781E8AC9,24C1CD8297E7BEB4,A59BEDEB86BC68B7,A28E2F3BDF48B3E5,5B3BC64B41BE627E,A75C2770F6942324,3624CA1EAB9F39F0,D36FC5DDB299BBE8,F8E5B5ED6C2E1A14,00000000A6D2F7E7,56E20F6E1AC4A56C,FD67B5C57B0161A0,0608850D7518B73E,488A70ECCC78137F,708C28B844E2B6EE,17663080B0CCBD82,D022CB350195C44A,58EE45E8166D0890,C5FB90A10D1F00A0,00000001D824A3F3,D6E9725240C52994,80AF9649E4B7F787,1DA0DD7FE5B4EC06,998407101680468A,0544886BCE4B6B6A,E1E7B3E34EC95DF5,B6C34436562C752E,D011926AEF98B849,EAB7D0C4E4BA6FE9,00000001BCE947C7,F26B33DCCC899CB2,9CC4B6D4888C3556,6ACB24C6D2D0BB63,0BB3EAFE794E42BE,D06C815DFE3B83B7,67096AE04CFF8FDD,53CE9A7BA1F9E0B0,7772C46037350442,59AC83580B3CD96F,00000002735D5F57,EBE58AE26E38A59C,1788F34CD80B1DEF,CB2C4CA16CB4A114,4060B26D66E621A3,E7C61F6909016791,74759E587F127C6D,C27905E1575CB191,C06E0B5DF1B7BAC2,CA61ADF46D96FC66,0000000160A87872,9BEA336EB4A6F568,08AD49EF8489D1E3,9DF0A25AB40053C0,2B8BB971F6727564,453074435487A1E7,B5743CE4A5FDE299,576A40F776E8499A,81D78EF2B16F552C,BB9852548E00B97C,0000000073D8CB11,C94D8C2784C1F7A0,0B3C5F5E8C92F64C,0E9BD27982F28679,5C1097AA1F5C04A5,2B037D817622A00E,8E1BA65B7B6269A3,A8A158467429D36B,CEF6B5689005FF4E,D1DD610DAF41BC8D,00000001F7C697F7,ED2ED8EFE0CE9CEB,DF9F668FFFE89E26,78952B3B398AE742,F259300DE5426FF3,BFFBD7B41D9655D0,204EA0DCF6292659,145FF13F651547EF,DDBE3C65D7C470CC,32766E4FEB2F827D,00000002443C1DEA,FDB4A9E3EA4E1315,57A09D0A1E006439,67D99DEBD54B765B,FEB465198E333B7E,BB7E6A0962641660,2230A5F5AC2EE6B4,679A46B09D6729B4,3E65DD7FED570146,63AE975056AD5951,000000022D7E5A7E,737E56EB28199B47,378CD7EF3B83E549,45640B9A99EB4AE8,E20963CB2A5C9ABB,FC8767383669B8FF,BF554C069AEB587D,6A7A053D06635606,9B156634E84BD3FA,BFCB0BBA8E967EDC,0000000223BECA52,7785F105016F9EB8,1E6A61BAE1C725DC,4331D2562BA7E292,CCAE852D6645EB02,17CDD6BF99A41805,94B84425A13CFDAB,074612B7DADDA494,CA5E4D1EF2874763,63DBE042D6B4AF7F,000000019A2A5F05,D1E3CEED8E08E3E1,6FE411FA86BF1C6D,28991E85CBBB9FC1,424A7D661D302AE4,2F2EEEF13F6C372A,697958B9A8B202CF,A8F1C64EB1D68FF5,5490D4E2E663162F,A792C437948D1994,000000021C51FD7C,E303169FD9286525,EB69C5BF7ACCF273,76B56E8AB1B00F6C,C43A5FB1833BCDC8,37F62AF4A923E1F5,4804A0FCB0BF8FF0,9546482796A87205,C49108CF35681C4D,EF75D1FDA8521DBC,0000000139009CE3,DCAAE67F1D03B7D8,94E5C4BFB9E3934E,0258707C2A6CF949,FDCCCF036E8A759A,8AB1AD7E7847F893,D36CA7158C8DC9C9,D1C8A385D244854E,176BC05A9AB8D8BB,C90FAC27F53CC2D5,0000000128725015,B7CDC30C61878F11,995C694D7319A055,31AE3AFC03BBB3C2,809916557BC5F72A,D68FCDF6C5B0FD5B,21B57E30A89ADA82,197FC9E255FF9D1F,1F93080DF4B264CE,0E829D7D7BB0F218,00000000FA7214EA,A763631F66AB0975,86AAFDFAA90CA6F7,858E72856F837D51,E2105E474E181B8E,32A47F58F90B2673,61CCD8A29C3C79D6,F0DBECFAEAF413E5,6A47DC9BF4A9E472,77194A01CA7FB4F8,0000000056D84EA1,22321DFCDD3462C5,6BBA5EB9E11505A0,9EFC4784AC21A089,484F81DA7B6C58D4,937077056F1BADCF,31EF5506FACF6B3F,C7CC1C2683F6E42A,3D22B647764FA20D,67354676F9EEBA75,00000001A58240F2,DCF355A99A5AB06C,A3006BEFFFB22D53,1C0A1C497E50C4EF,78D6F029B09C4E9E,0553096B0B0A18BC,82E3A8033354FB6F,16296ABD8BEC764D,1BE7CB3E45E23D54,C5094328103865F1,0000000187BBB504,6AAF954C2EF25F4F,BEBE9AEA82E2EFB0,2C9FD6B8EDF1A0FD,DA084673D4177560,05DCEEC3C691305D,7B40DDA18AEF4124,4B3E5A4ACCF81B46,494E20E7871D4BC2,6A21EF514CAAC87F,00000000DFAB62B1,505A2E949D548A9D,BB8E8C74684F3CFA,F8964EEFB9642F66,95E511B9C0A5D051,A4E4546B88D5E928,E1512C9A5A16FFA6,C68350E8A41E951D,1267703D3BA4A93C,43867289AAFCD1E8,0000000220E30225,01F62B804D810E01,33343E4DF78EF236,37848607A9D10290,B784B4D5436D4604,12941121A35923F8,C5803364120D816A,A6D55B72C6E3AA77,2B10AD9C81FE311D,F93DEFEC082E7823,00000000FFB9209A,351F9AACDDF731B9,A611E5EDD7B2252F,E289974276F47D1D,5BFA6428EE1E74E8,C6387C774A88C76A,78A1F267BD252E83,C35D14705CD232F7,F7AE37767BCE2C62,0E735D594FEDDA75,000000019212C234,6A7DB83EAAA0B120,7DFDED7E3CAE84FE,CEDF7EEF86EE2D88,5EB74D5A3A27C63D,5266D21F9CA2E923,3FEB69D663D02937,08C2EC250FF8D16C,D3975A42CCF620C8,D01BAE3E97D8CDA8,000000021376E063,AA6408F6D8DA9ED5,07F458B6AA5BBC49,B08EF5B7A29EE357,5B8990C1ADAC5758,08B5A683F9927A66,385EC8863A915258,120A4D855118AE47,DA99F4AFE3D59DB7,22CC2C8724D71410,0000000248B04255,749C5D490AE3B588,527701B8007BE2F1,F05A792FDFDAB94B,A47AC1B9CEF24BA5,54A3532AE2A668F6,A4FB95F4FFA4B274,E4570AD2794B8102,47B33F8672CFCEFA,C318516A33367BA6,000000024FC326D3,FF746C3C4D7415B9,E4D3F51A919E0BCC,01226E160FA169EB,4EEBF8088CCB2BAC,29DB3F4BF3A7E86C,53E26685988E05E5,1E5F628D8BFFF916,F41FBB47EB4AA983,1CB9E95BC46802B5,000000000F392FA0,A050E44AE789ED29,FE81D8D28146D8D5,3D25CADA88A16943,6BC0C03D0B9BAF47,4797E174C5A7562C,637D003D9B455799,1C8117D6A808817C,D25FFE3683C2E541,AFA01D90F1ACC031,00000001A128F23D,9925C2DFC1E8A955,579D743E3095CC23,D1FDE6418834731B,7163F52FE4207941,002FDB5086AD130B,5F914181B678A475,607E5366173C3164,7A474065572B476C,775CD5FC81354EC9,0000000166C18043,CF7800841C6A82F2,C210342F2B6C5F19,FB09819945B33458,02E8F3E590EE7E45,A4E89992EAD3D1AD,5A3141ABA76B5764,04D949363127A083,1C007B6B02B53CD9,DCEC648C8B56D19C,000000017A5F6C6A,338667C3BB149C27,7E1E2D38D0311DA2,E5E27EF0DE70809C,6613F2429F1233F7,6A232EC938957AD6,6B817F36B3BC7053,4CD2901BD15E178F,9AE04A1267B6A0C6,BFDC8923992A9467,00000000A9C23E87,AD0BB64BE8B8BEFE,76EF886BB8DF52AA,DDF77ECE8FF315C3,03606123CB23397B,93B38A55F4B9E833,53AA44563CDCB271,224849686BF248E1,49EEE92ACEFE8A6C,2A07D7BD594B0035,00000000159DE1A8,52D2A0D5CE3CE1AE,03A57FB6983984BD,BDDE878ADD901CAE,6876D87CD0EF1CF1,7945B6A2E2DF6B9D,B8139BBF26EC7EC2,85E6F8EB36E4FB08,B9BB8026E703355F,EA5A10DD0190226D,0000000244FDE6D0,88FB63A44875422F,1272D3D6988E1443,35A8AE7F6A1B3A9F,C27B3F6FB9AC1319,4C1BFA148418AFE5,9F02A5308F04E6CB,D11CF568E3F52A15,999647DFF2849128,4ABFF04F1B765862,000000011FDA7F40,221B113407D3AF42,A4CFB2B57F67A22E,0AA5677B8AB72309,36CA5CFDC89FFD07,20F8D6E13067D23E,590EAB8DE5461E36,C67D30EDAEEB0D55,BA9BB891800E2D8B,F14B9979BDD27F34,0000000214BCA4B0,0A54893C1A3B0444,7428CAEB1428149A,0F306153948E756B,5750121E44AF9D73,9F32906ABCA64BF5,44257FC51C66F9D4,B367E034F4F2DF65,57EDEA1FE5DD27A3,12F66AC8901EF34A,0000000111C823B3,4BF2A0083A130BAA,146FC6586F674597,67A6D1A7AA958811,A8911EC53F599F81,8F52958ECEDC4587,4675994247F91D10,409D67DF64DF1439,3185BB13218D6168,85A93B1B4D164739,000000024C453FE2,F3201E40A9DFA32C,4C32E1933BC40F59,56270F8EECB217B4,798F743C26308906,2740A8658A9E9252,D5431A7F099A8883,D0F434C05E1AAB29,78BCD98A7F1F7C3B,C8B533B10847DF2F,000000011D204014,616C43A4BF402BC0,2124EC791351E97C,AB0ADADF4A4C0673,77223606DD61A533,99C3FA9418C9A962,5E49732656B109FB,AC54B16630881910,A2CB284C56E25491,DBD32BFF6EB68027,00000000B24D1552,8666D8F7F45F0BB9,2074B94C381DCB0F,1E059A860239E833,959AC9C473AD8B1A,281E61F0A7DDD8C5,6B9D96C40FB40FF0,D46F307CC02A0F7C,2A7BD0F251ED91CC,1B81EB907FC4CF3A,00000000969522EB,8F768502A37FF640,D0434785E787B079,5D7C3C8EC7C5809C,BCDB55037D055248,8ADE19374550403E,0502E514A521F5C7,6C5A855E6C6EA900,A689889E77FDCA29,D6DCA7D00BED31F5,00000001FDDEF826,1456CCCB9CEA4BA8,F4750D7DDDE7E055,88E183363B10BE99,7A5B62E1BA338E1A,90DA36DAAD9A73E3,2D4EF4011101A4AE,7809931EB14EC819,6D07D518BD010AFA,3654F0E59CFD89D2,0000000140C6AB9E,9DABEF10546BE654,368882D223A1D7C9,E4C620EC4928796B,76D14C9BB26A735E,EE3BEF5022333C8A,5B4D8F9E5B8221D6,97337F17AA01697E,677108BD9D542872,89DD102915760C12,00000001136A8884,A0FD06E8B8B5AC2B,05BD685B60F67443,0335B659C6FCF950,871AB437D27B5EE1,79F7048343D415D6,5CB9A99441790CED,9893D35B8475D44A,CA1B3FCF5A3E218E,BBFBE09B455B7CC6,000000022249CB94,CF8CD97BD4A3D621,95F900BA348188F3,674F13A008F8BC37,7DD49D417C868A3C,FFD81EC64544111F,0B1C1F3CA2B684CF,3FC306C018DAFF33,E0A44984DC33A818,B15B931A3C4621F1,0000000221A4E930,735821A626EBAE77,3658523974888D70,B7D74EC5AC4E7186,29DF8CF1796D622B,0F45E543472CD25F,0C1469A8576F872A,8344405283BEC206,DED0BE205F1B6137,F149DAAB848D4CAE,00000000B52B28F0,E12C5C27D97F240A,E1DC7A2FD07E8EDD,E09EB599B6D64598,870967DBC83778DF,8FE21DA8E4B48191,93D6C5180290F427,05B7842FE7353FAA,178F437FFE7BADC2,CB9EA87E5363E1B3,000000005724ED30,B633251489023691,F7B61EB2406EC5F0,91F8E39823A83315,5A97819817F04A46,B49667FE9DEFD2DF,3C13F800E6405273,72AFEADEC3E91F65,71D9B510B8AA873D,FDB4AEDA6190A07F,000000002F943627,CE1A679A16D9032F,C2D612E4F860CE47,35A97BE3483A749E,C91007821B54BEDA,19F81D19A628BB77,CE4B57FFEC0C87B5,4FAA124E6AB08720,FE716FCC01A6FFF8,51CD9DB17EF9103D,000000019C4A9C54,EE59490DABF01464,2B03AE4EDB80167F,D0D1EAC6FD443DA6,90BC4FCFDA3D54DD,6D74477C876708AD,71998D8F3F7888AB,E7AF4A6B4862BE57,E66EFD80904EE010,13D8E4406BC0A165,0000000191FD6EBD,59CE4B1072CDE79E,6CE309D2A7C48F9F,9CECBEA8B6769C29,E160A21A45074A31,1810A019ED34906F,EDFE4F1BB65552A5,3285BDBDCA9AD864,925D1623B773064C,D6457A331437E1F9,00000000F35F251C,DE6F4AA8AA92C7F4,756449E1614EC084,C5A41B1708C02950,66CA544B2C70C79D,343CB6336BE8F73F,E0043D9E8D21C205,206EB78EDD70A09E,061BDDADC51AC1EC,C72F465B34130A0C,000000017D3A72D7,A80FFC86AA74D938,45CBD452F88891C6,122020489B0C4E6A,29CE0EF1B6569EB3,F1E73F12DB79AC77,2AE43C8C29C8A99B,1725130160BD348A,F3984507279068A4,2D00468CE4E90BEB,000000009F5385EE,D13E9A200C001944,2A310C0E1DBB9C9F,06A3021280FB0CA6,E37882C653849FAA,BE195E1689ABFFAC,D10C78F4FE6BDFD5,72328424F0A478F3,7064BFC9A139B4C5,59629FB5E0258A7E,000000011F510455,E03C0E7C464F2402,09F89CFC827DB93E,59D251ECEFCFC202,69E7072A5C15CC4F,8F5AC008600F35D5,4B055B315A52C3A3,85C99DEC15C9C9FF,874663BE54E58152,EFB030505180C135,000000022648D054,8E4F062567252EBB,0D348F9E065C9C32,1DCBAE381438D3DE,0EE11AB20E63B562,A662B1EF465CAE9B,530E21CB52C796CE,AD3FBEEC8C5E9059,C0138A6261060137,598164BEF08553C1,00000000DFB4432A,A6984F9F76DBC646,BD56AA3A5609D3F0,D42F3742D6A4D926,ABE6847F2CEEBED0,E8B08317C004B7FC,457F5B42F556F9CD,4E22E51451FB841D,103B33141F9253CA,0AF77C02AB0A7334,00000001D74D96AC,0DCF90675B47F128,A95D531B5064870E,7BEBC372C21BBD4B,B84D28FC8D6C7A11,4CFFF1D15B6CABFA,D3DAD0D2690DBAE1,23702EC78865640D,A96D7BD38023F80F,E9CB647ADA3767AC,00000001A201D106,6C260C1C670D7DE0,23002B24AB5C3E2B,782BFD65FCEF3D52,53A4D555887C638C,FF4923AE3DD57EFB,F120D0E2BBD349C0,DD57FA606CADD763,E1E06588FA641A3D,004154A2F5AAC27E,0000000184C6F366,E6A3D01EE30B54AA,E9B5B3EA26A82FAF,A04BE460886C3EBE,FB80A6C826C94C3D,B1FD0B0A0F3C1187,BD30CA8AF255E5FB,9B2F65DB9E546AD5,BF95D12BA5F45717,3FC13BF1CC6659CA,00000001C7DB53E3,0809DD430859960F,81B827D12AC4A5C8,A0254D697C35CE5E,7AED4D7A3FBDC1E8,0C0F9AD8187BED4E,58AE9681015C9D97,ED110981DDD18E25,C93F91BBC08EA4AE,594810D6B01159D5,000000024D987917,926EF5B21A091241,B02D33CC1183B883,3F0EDDC5F2556DBC,C13BAE76E6D057BD,11A82AF6A5AA3084,A26F037D4FA8708F,E8BDB2FF2E505C66,916BF0B029370239,966A43FDF3698E5B,0000000097A8CB4D,66F8A967E6726022,20720E158A9C2368,337DCB7D922B0B65,51CA7E4C60E660D2,03B62DEF3C3EFE2E,F1B753DF65F4BBB7,84DCBCBF5F1E2E2A,BE5459F472A87E37,6B441597E6011ABA,00000000EF52DBA9,4076007F68463369,78F13F40D0EB77C1,6D1F0C2E39E92917,54BEC25E28E572F5,14B2B375839429B1,1DAFD44F8698622D,D8E739633E3BF348,D48CC96C11F67920,D22FEF6F6FD69FF1,0000000065C8789F,15F806646BA9A842,1748963527F077CE,681BC0C4491E7F50,710DC8284EA13C34,B65B23762F02BDFA,FAD2FCD01D5BBEC1,46817069686113DA,18AA2AEB2060E624,E744B933114311E7,0000000172577325,FD1625BCF32B2EAD,A7BE9BE579A37D70,5D1A714F33BEE43E,AC3E784214232108,27C01E225FC68A3A,2751D4FEB56F4CCB,FF1A33E88F58912D,4207AF45B78F99CE,58B1B66038C5AADC,000000018013C8D4,A68E0422B95BEAF9,7A9E4E87B561443B,973CA58834B328A9,DC7B96A435EF68C4,63D501EAE237D86F,2CF9000498CD2D70,69D64EAB46D6B7D8,4673A4A732835223,5329E69C83C77491,000000012EC24B05,243D5654F963AB3C,20AB186E923EC5FA,006A6D805E19FDDB,08DDB0028ECBA56A,4EF7ECC22703BF7F,369F71B500BB115F,6962CD61A7D39ABE,8F38EFB9AE663A1C,2B6EFBA25D7A5F52,00000000E8CD0730,4D799A942689E363,6819CDB77323FE62,4614D844A08FFDF4,A45B4BC9A891256A,A293A59C6FE9698F,324DC43A4BCC593A,8DE9E6144E94D5B5,0240E257D9BD878D,630E2A7DF7622990,00000000F2504B04,88CAAF76E0AA1B03,E6FC9769B8D67EBF,A53F40A833B65856,6CC9B21AB7FCDC75,FB6D4D2F4908C580,43C71D03BD42185C,21F65E05A69EE1D6,A2E6EF8C7E8DC184,EA8536A3CAB55109,00000000C832557E,C88D31170D54846C,1355B12DE92A6247,835AE6429E0C2031,FE469AFAFE04E165,F12C46B4CFFFD10A,1C5A473F97897274,B1BF03B42C7ECE9C,724EB27A45A8FF33,FCECCD42F3FA323C,00000001CD14CA65,FDA1C1D99FBB63F4,93342E044BD67F99,6D8DA8CAC2968335,4675EC1691AE7600,6C3F490008CA876B,6420B07370B2B49B,38B9645BFBE8407D,529F88EE3AB66D9E,87870BA12A17EDBF,00000001D42A24C8,BB1B48DB83F71089,2135026AA0FEAC13,A289F58E49B8C583,08F60D6C6B519653,F55CEAEE0861E2D7,0336E71EBFDCEEB1,B796312BE2A9B9AE,5434156D38FDE8AE,0A9ED20EAAAE7B98,000000003ACA96EF,8BA5D86EBD191210,FBCC07436FCBD5FE,43410C99CF186EE7,7F70C5812E2B65FA,B402A27DA408A5F2,BFA5B2024E28BF1B,3C81EED6FDAB6C62,509BA05B16E3EF08,47484B13A260B58E,000000018D90CA66,67C44A4FF0996070,A50ED82E3211934A,B2080F19D20D44EA,A431170C935A64C7,2B8CD12F1B2BF960,98B1C0BFB3400513,1CEEBA13AF67E783,B3734602937DD6A0,A3746D9EA6369C72,000000011FA10BB0,BAB52EA309DDCA30,32584CFE743525A8,E60D3E8536E4C20C,0A40402C0CB1200E,23BAC2891EEB4A2C,4FDBACA685C76D19,31205A9BC03D5738,1BAD997EB3F19BB6,46DE665235F14477,000000003A86109C,5DC2E1906F095E1C,57C885A736E39604,F0EEE778551AA972,FDDC984F391D9382,8959F3BB96EF762B,8C9CF82E33504FB2,4F055E8AF55363B1,4CF83FE4DC4E2323,97B78814F703BF76,0000000093F9CA58,A34867695C4AD030,45817892906F0313,155731DAEE4234B7,282ED4C211097ABC,F521F7EDAFD5A551,CEB9C987F1BF88FD,2087679A3B0EE52B,9A1F5F7F785617F5,65629B5855BFB6EE,0000000054691BA1,BA1387C08B75AA7D,24119EBF589FB223,08389519CCE03441,F4D13D7DD3C07D92,10AA90B2D9804FD8,58231A93D533E7F3,0EE15C21CBD1BECD,267022476653F578,BEFB9EBA2D2B8CC0,000000014176F2F4,3480BF1BB3F64157,F21CA102C997537D,80C9194B82139BC9,947F5257ED4D857C,2337C519FA9A4C8E,3FDAE5A2AD7C8BFB,73E703B81472CBA1,022CCB325A63AA93,391EB8264DB7580E,00000000099A1377,8E6EFD0ACC775AA9,CB66667133CA247E,89A4DE507E2FD6C0,08D76C46A4B7B715,B21E97C98FAA7C66,E73FC4501C6209DB,06C8ED34E3E38C0A,ECFB7C8A48EF267D,56BC25CD311C719A,000000024853CA78,1C94C74DB46993B0,2A7DE142287C21E5,516A26E88BE870E9,18A4CBFB2BFB0872,86542002869C8B4F,2B3B40C4FE9EA35A,C66548F14CEBD033,71901C6C9693B566,6D0B7418D42FA356,000000003DC9BD2F,15ADB6CF678F21A4,61D9BB2BE13AEA6B,1124E2228FCDBB44,50FAA02271F8F7C8,ADD7FEEAEAF8BDFC,FAFBDE1F83EFF00B,A0CC4D8E10E7F175,C78035886E52C01A,ED2F87BDC2BEB5B0,0000000144DF5A2D,12890B0E90721867,DF0313BFA330A527,739F44BF5B3F6EDC,294BA6FBF033AE4F,F2C496E534D693C6,60A37BDA2AA35726,10F009476E2352D7,9C4C449AD6F3F59A,FB2B2FC08107B3C3,00000000C8C3AA97,60D961C76613631A,17DEEEF71606C5FE,CEE42B41D0EBDA5B,569F67F8CF96396A,276F1D23AE78DC82,326FCACDFCCE2817,A02115C2BD591B8E,5DDDBF1675812FA6,B426E9267909112C,0000000048BB6958,B7C980CC0A34AD28,31430F0BC0E18A7C,A820342C18F3F3E8,BD6A8439EB11424F,EE754E3E969921FA,93686A375496F84B,4180D12D658D695E,3BE7FE0B23972964,37FF0A86EF6A41A4,00000000E367D92B,462FE752E7742ED1,010BBC38DF0A27BA,5EA7E872D3DEEC7E,4EFBCF9AF7E59C13,91F3F0D0118E07FD,16C50D693AD25B57,17844280A0C2E5E5,B9F34C6CDDCBD961,0B5FB33FF54EF25A,0000000160B7747D,3A67DB8E151C81AD,97D95B0EFF087570,CC64245AD1F2152C,CDE1916D09568CB2,65C1D38B9F077879,34E08664E0D26C38,9A931DD58CA60386,4CCDD86E6FE1C9C5,FF41D1AE2CB25BB5,0000000035E8DA82,DC405D17440CCC6C,A7229FF36D299D31,2CF11A8A268DB0B0,14870083EE60B725,2421842009AB05BF,D9C39080ABF750D3,AA662B99E288C8B5,CD357CBFFAE74A1E,B8B07816DBCEB155,0000000091BF2710,98E71DF990BA0D2E,F6413731C57E3DE1,85F44B1CFE96633E,33F7D44C81BC48EC,189B83930ABC0019,6EF9C549E390681C,3D5096797A300291,58AEC41AC23191FD,3B606046B1DB0C54,000000006913C2AA,D35F5517D5BAEBF9,041601F8D6E15CB6,F731771F294678F4,AF322ED2B5430D72,80470153F4C78467,71AB395CEF251FAE,469BDCADE4764BCC,D4E289BD2EFED2F5,B96B3991FE99D8E5,000000017099EDA7,2D603565A87A934C,D537C96BAD07F68A,119102B9954FF86B,3BE0B5525D6F4FCB,048483840600682B,378925B8A80F9D28,64DBEF5E2F3DDCE4,14BA986B95BAFA14,D8BD4985540E8950,000000013A90410B,9958ED85BC3D6AFF,E2B0045C8DC63F5A,E372BD57CEFF862B,0758DC66A48E2ECA,3A3614A35950690F,3FB30BDCB06150A1,C53BDCC7B1DECCE4,BC2CDA4A258F1311,3EE52487001314DC,00000000240854AB,F11FFAEFC2C5754E,B05753F87D104E0A,7838ADB85D872F7E,500A234793627667,36D5C0DBE87BE6D1,E9F313454C0CCBB5,9DA2099DFF3D950E,3C56922781C32ED6,0E2CFE45D30EC0A7,0000000044963CB4,CBCA4E66F0A40FF9,704017A58468F3C5,47B64FD6D51107C7,ED32E5633C979CDB,B097A1545DBBC3EE,A90E0E59372DAE78,31168F382B1C4DC3,29A9F831CB09C007,8F13231B6BB947B6,000000000E7AB088,53654213B67215EB,D1F7270345EB3FC0,99B9292D12E1F0E9,C2A702C8A84E587D,C03DF6E88A63D50F,3A1AF4FB8C0060AF,371EF5637CB5F25B,CA0AD3C7DEF6D8FA,F49400116A5348BB,0000000056251B73,7F7AC6C098C85CDC,73E7C8902F6BC1A4,2EBDD5EDE265904C,4038B846BFEFAC27,974A871C849721B3,9DE3256AE589B484,165A62E285D8AA13,D20062FE7E49BC89,B0DE250A0A4B23BF,00000000B845FE09,4936E5B4C8E231E4,F3C15A4F209AD4C3,DC299DEDB1C4D97C,8F0087D3CE3E5EB0,74367D28594B268E,1318FF9BC8B89D1F,2BD9505A283C2801,BD7D93B1B31B120E,D08FCF4DFFAF0C2D,000000003FD6AED5,4ACC6F09801D67C5,3A4F2167DF1563D3,5C45F6E80DB37C11,E4806E723CC226C5,794980BE19406F9A,ABFF39E4D477F514,4B67CB1504E6FCD8,ACFC6945D68FC0A2,B88180F2B4996182,00000000234135CC,848C0A18F775DA07,25A59E1A0647860C,0F9D94BD1C9EC7F3,E0820940780117DA,D111137F193C40C8,1F77D5DB35276956,CD48B2638D58840F,04D6E9A3D9BA0C1B,9C5555D3400EBC82,0000000278423361,1BB147C3DBD1D2C1,2A08D211441BE939,623212CF7441B5C7,701EE93B9620E66A,F938C0C7A5BA4FEA,E699C9AFACE4AD64,C80EE87E3991AE2A,EC31350CDD2FA1D2,37F52366020CD9C5,00000001F3385BBF,2A497B0CC913FB45,B676F5119BACCDCB,F3692890CD07326F,75096F5AE014DC6C,223E38F5DDF7DD03,16345C88141521CD,105268DBEA926E84,032E9BDFFECEEFFE,AB1783CA3D3FF91F,000000010672154B,95B759B4AE1052C2,516E7B1519E9573F,73034AD32CED5DD0,F3DE665F38CB23BF,B0000322F5B98481,B0ACAFA65C9B138D,A26E2E7B1AE79E25,2394E5794F989E7E,2F034123B4CDA1D6,000000014FD19229,BDFB00328B8C687E,C4571C233BC1972D,8E19A30809743ECB,E06D7E11E5C2CF7C,EB88A0532B09FF58,E863A8B9428414D3,9224A44FD7D13F24,1611A5A74B5D731A,CB421AEABCFCE6F6,000000002A07AE17,F44D492FC31E007A,9FE0D353D3C53F6D,B12728D87CB0AA98,2BD133B3EBB43001,C489082C42E172F2,D8C0CD64D380A148,A0788E6E025A33D2,865F00D2E88498E9,2413B5DA2A19722D,00000001CCB4D625,2D494B476295F036,3EE995ED9004C49A,7DE8A8F581CE6BD4,8F70B7DA92056BCD,0C8CFFEC01C0256C,C51DC5C6D4F6881B,E30B17AFDAF5B342,C5CBDF933E23130D,7E81AA1CEA17257F,00000000339846C7,977D72267CEA5FF2,41A7894E63C7414E,7B2B6666DF132175,86CA6CB27BD12C50,D84AF2E27F6B28D8,69CF4CE27FF9A072,600ECE9B7036815E,12B72622CE3216B5,313D7D7331F26854,000000019F9C0D70,862F65396A514F34,4840743A8E5F65EA,AA84F73D803AAE18,02BCE5B46F0A902D,2AAE320CCFCB96A7,749EB9D84C5C828A,1BB2FD5FAF8367D3,E2CC277CFBF55DEC,5B6E3067A44F5616,00000000EDEA4E13,018E5EFC1A8EA103,0432A22864BE0C5B,85016A0FCFFE2759,A5642DDEFAF43CCD,4C542B6E55CB18D9,E357698E59345988,771E53095C3F975E,AAF6AAB5C2BF9BCA,54F2933B5F4DCE40,0000000179D06510,F00C3F6EDAF263AC,591E98FD3438B732,B956B2E4B5DF80E9,1C4AB8247CA83CB5,A1489A08B775D771,9F2B2DFAF8D248C4,BE290C1D1DC985AD,EFBBADF877215B7E,901EF491BDBD638D,000000002C63E967,9899896189B1A291,F0E6383ADB5A0F82,626217BFBF7DDB99,D36164BC77AF2C6E,27F8140ADC7D2E19,ADF650C005BC3CE7,ED54CAE1CABD6953,50E148D77525D3C4,B5326D39C0DD538B,000000001A6BEBBE,255369342A536561,88FDEF43B3D9D049,FFBC361A2ED35D2A,3EFA94109E281315,7E8036B259241989,6CA5B50F006AA0B2,59E466B6D94AD0D4,4B906F685DBE7662,BBBFD606A91EC50F,000000003D39CA94,986F7A4445DB5B8B,E7E01FA030DC74F8,E1ADC184AE57F695,09BCA0938107E433,3642CA3CC8B3B7A9,54C806FDAC577ADF,70E6BA60AEBC00F9,BE6631D4FFBA0831,6686630A5F0CA1C2,000000013497B778,B9CB9F5B2B790526,21191833DC6F757D,BB3846E13C7E0EA9,4B7B45511A8FC691,81699C0C7585BA9F,1B3496FC2EE81674,AF17FCC6D202E843,25C2CF154C98CC61,36E6E628D01A41D3,00000000248F0454,9DDA89E4E84C9D97,E6A68C77B6CF5267,5A5483268112204D,FA61B8A192A18228,E023DD2264B2A6F0,C73FCE4539C2AD48,247BF4938785A93E,F9D4C24B3E5032BA,D91542A7A488C1E5,000000004D774D46,746CCC498D08917D,2C59D8A567E504A2,213D288C3E518E68,3D2FCFD5A2A4AECD,20DA39DA9BAFDD8B,0C44FD6AE5213EE8,68EA47810EB0E734,4B6DEBA4C7F537A9,14586631977F2FD1,0000000279BDF7FC,85B9D67BF4D8CB99,5EF4859E3695F5AF,36F3779ADA770284,CFA37ADB3D1F554C,D5369C5ECC6C7697,262D3287F42F4249,7D8B768727222DB7,2DB447BE244EB583,4340874FBAE5444F,00000000B3946DF8,D1EEE6D20D00115D,CE2A1DA00882EDC1,E71D7865B790379D,9A24B9CD31C8251F,8C71955F90833CC2,4DC27A8C815D34CC,6A2560365AB95975,AD33E9900E533F70,B90AF5802E25DA1C,00000001E6482D1F,2540BE9855234C76,62B46316B75B711E,676DE7BC361CDADB,3D4D4E484C4F018F,8D777D942F6A2E35,8F506EB1A501D91D,5EC36981BD826092,E74758036F301D81,2CE8053F5547869A,000000006C62DFE5,70FF4F476A31E4D3,ADD42E274D832AD5,2C50FF5D804E19CB,24D21CCB27D9D122,D3CCD6D25DD09F6D,B7E78C1B11E5674C,1BD983823CBBA267,4C85148456C721FA,5C0026631373A649,0000000019E2AB34,A6DACB7309A4057C,41DF48A6E3537E57,1C52B96DDD10A616,2E2B22C396B6DBAA,367B9C73F0FD79CD,3B95CF6FEE965E3F,33AFEA02D36194C3,2479936E1E57EFD3,5A695FED11258A02,00000000C131F7D7,90DFC9E0B72E3EAF,B4C176F61AFE0524,3969280B7192F785,A4576AF580E4322B,B2F12583B3681869,1C13CCBDD4F2D264,AA0D2016D800A1DC,73B2399FAD4219DE,1E0F88C1E420698F,000000008660D8F2,1C25D8CFF4A9DC4E,0DDBE202C6B841DB,B23BF4EEE5446E3D,AE52E8BCE6AE6484,6BE8B5F180D2F79F,1932F29FBA38A566,DD6D9C6F0A1C52D1,7924FAD567A5AE89,4EA4E84B4DED6A85,000000009BECDC2C,82CE1157704A0090,14A13491656F2620,7046DB437D8DFC7C,7035E7680B39BC9C,374EE3248BC79777,8761824E17939EB6,D939733AC92A6702,E2DBA1D2F3C99D4C,0BE6592AE78AE39C,0000000154244624,7739F29723B9AF48,3F3C0E39D5746A7B,834635AACB27085E,097E076333566DD2,2E4EEF93E314FDDD,9CDE843EFE5830BB,0AA2C3A46EFE7FF5,138512C9EF10DB45,7DEF82DA76B59EDF,00000000295AFFED,C7899495F6393C8D,FE7B809AB25DEF4E,5E4046A8CDE9D9D4,B73F539083AA4913,FD046A5CC8251902,A5DC7FAE116C0AC8,8E1EFDA2CB3D8B2E,199AE604FE8A7DB5,AF42863022ADBE24,0000000206E375F5,4D81249CF7F85601,83B0476734362D83,98B901DA60FB62E9,7B9AEB7D345E93D4,E09DC5E49B1993A1,9FA940F0686AEEB7,F35A5278B1A5CF00,160765F08F96481D,93AB3BDBB357F626,00000001D4AEEB8B,3B5A532C0EE10F55,F02F313A0338E724,1F94176AD5C466BD,1BE5DE8D14BAE512,7821ED2A7034DC4F,90C622A4CF87581F,B30C5BB8B9330A38,9D55F7B2FF538373,B1F1C279E35FE795,000000023A56F249,0F35C92F4D9007ED,F3700F652878716E,C12541A4D7A423B6,2910B5DDDE0EB187,48E503CB54660F07,0CCEB44C69F88707,C2B78C8CEF2BA1EE,933C05FF75F00837,03C797274FECF718,000000020F0B47B6,F66EDB1156205C0D,966CAA560887679C,A31DAF3C3DF8BC4D,9F5E3A7F0F01D53C,2D713C2085329A73,DE96F5AE364A30B4,0475E4D219371C33,4D53278030FAE7B8,B05239F990A38323,000000000F23158F,402A560E85613ACE,686E0A095CCC86A0,6290B1ADFBA9DDDE,EFFCF433B69C0610,C485CF4FA46B3806,48E07B7CFD04BEA1,3764AB669F12C56C,C89E507BFAB079B0,C712B7CA16AEF6E7,0000000172AC7865,A7573ADB7090340E,5D6D67238F880792,F677388A67A5B4C0,95932B69A64BFA03,98F2C4C0C7B99BDC,9703FABFC5E45FCD,6BCDD457A3967E91,8506CCA09D1B704F,F70E0FE5F6CF0F61,000000007EAFE731,0C726D038D061230,B77BEC1C0478B18C,3AB490FC9B2A84D5,90A2E25B6D666FB1,C4A8C96F66F46FFF,2757EDAB5D2822E2,7015FF7CB251EB82,2FC030DD3F24C9C2,0B2462DD10DAE3A5,0000000256FAF63B,C236A7E3252C43A5,E7CCA650D5B24D6E,A9CDD57A63791F74,8F3DABADEA3F4BA9,E0D83DC6FE5BCFBD,8AF0FE263CBE328B,4FCA57592788224F,F70FCBBF02170553,4F971E12BAF52B23,00000000A216214B,2B288F630361D064,0CC2022864ED292F,410B23B9C0B12FC7,84814CF25155D75C,FA0FBDC4646749F8,60160B182E6C7224,F2A91FAFD37E37AA,A1925882B22DE6CD,A4DE71AF2654658C,0000000055B61D9A,98CF8CEB668F0DE9,9D16642AEB3D909A,3FDCF3D93279D3C8,691BAFC06285EB11,4755DFC33481A55D,5527E63E7C0120AC,1C5625397D80223D,EF8CFBF2C513A7DA,E18F05454E2BBBB6,00000000FE5BEB97,F90A174F618A6B9E,E975E69C7C72EE8D,B963F01998A9C004,FE6E9F11E2E6FADF,75CF3D037C85B6CB,629C5C7E8F99ECDF,F43C3216CF065CDF,5C508F3FF0D91518,67B7AF1CD1D2F990,00000002124A7231,F377D154F404873B,C1F6DD0A76DCEFE2,BF949BE4B218699E,8435057F0C7B5706,0872C8F455E31673,674EC6E465FA59C2,4404F2FFFD308B81,02DDA01D1DC028EF,1260E03D450DF455,0000000021240A55,5472070EFC715203,7D738DCF665B36C2,EC3143ED93B5895F,361062AC583D4459,1660B2B0087BE466,D372E82E14605117,A96FD4E14BDBF0C9,F04CA13D1F5E1744,D20CF6ECB12D522F,00000001E95A1EA1,5FE4FF3FFF795952,F01955F72FD5E701,28BFB67BF6D496A5,9FDE8DBA419EA179,599B2F163C9C9076,9A581F7EE338A735,78587D58055094AB,5DC07D0D55A9AF90,5D7748EEC6852B41,00000000182A1357,638904E0E1CF37CE,16EFF7AF68FB82B3,66A88236B51E98C0,36DE76BEB85F203C,569D5CC76ED768C4,7AF25E0B46E8B450,D6A218B6EB4E7AC9,7326147C58A26EC1,8E5DC9DE131435D9,00000000014B31A9,DAC0E8380908B63A,5990441893A7D6EE,8B8A23EFC15700E0,013329C5C400555A,07EEB5023AB0454D,2E41C60C2DBF72E8,5913C8D6331948E7,984E09B1C57A29BE,9A1A751C2C060F19,0000000217801A5E,94D318ABBCBDD8F9,A5648A0C3726119C,CB5FA299B431662F,8799E4E5D1B27FBE,EA8EB37A61D372B8,86BB3A252F63D01E,9A1C5CC9ACF33DD6,DD05ECBCD5A07B24,4415D39643085ED1,00000000D34C8394,B1554ADC15C9174B,6EDB4971FD54A538,C6BE1165E7387A8C,8CCD8B4B78A1CDD0,D8EF5AECA5F22348,A3B0A233DD1BA741,7211BCD8D5DEA775,05700AE08DA0B36A,6A577624347DE8DD,00000000EB8CD759,915629B1CED0D7EB,0589B08E8DACD490,9DD43C4CEAF12E5D,E2B3CB04CCAB8323,9C95104D3B9C6B3D,601E469C6C371C6F,4E8FA24911103586,D197F90B905A7394,50C7D63FDC48E60A,000000014E8B933B,03A583396F419095,CB3476342223CA87,BDEE3C6F663EB236,5EF32C0B85222A82,4FF97C8A9AFFEA20,E12F0677CB2BCAE7,7460EF183065A789,6C13C11CF5A42318,AF693F093C173544,000000024DB96804,DE0B001083646DDF,602BCEAB67B5288C,88677A418335DECF,10A39FB35FE84273,59DC4CAFE82FE933,5F5C59D871F74543,C6FDD5DCCA300AD2,8F53939F040DEB50,7CF2644C7D2C2CC3,00000001EF440AE5,9817769C3F517CDB,4438C532E8230AF8,1DCD3292A67AA03A,584EA2137B4054A5,FC0F2EB73A94B348,4352188333A4E9DA,2BC5B13A95932E79,68FB878BB2EA0253,A3CF7E7E20FA9501,0000000095416F7D,F017EBA6CD97D319,82AD602D1065683B,B9815739E084CF81,E0159AFF99BA9628,577432647D910A1C,DA31BA06C9569C72,9D682929B3D9507E,44968B01C23771BB,A1C5F66636AA7D20,000000005AD43B0E,3053E3653CCCB02F,2002D3154310BBB1,22956936B540CE4C,609EFFA320E5C806,441B0B55D7605CE2,EC7888478D798191,D9FFCDAE797E30F5,519871BD1A448AB3,F64000964D74AC11,00000000B0FE683F,B4581570BC445B36,3EE96F7737919FAA,78FCA28959C695AB,EF4AE57E1E04651A,D6DE27FCC4B4B5E2,03D2F6F57B24AD04,CB02368E4E975533,28BBA7B524EACE7F,29D79C7815E75940,000000007718EE74,76258F7AC012BE29,FF5F500010DF2C72,78A64EF49BA3C64A,B16899E998F0B102,44A55F2026A05894,1AA13DA4D44AAAB5,D4E3A700DD4E0671,0D7D4F77EBBB6C0E,DDBE7610537BE080,00000000AF3F8A37,E7045D7EA83ED2CC,D21F5F62CC099D86,E72C2749FB3796AE,7790AC17EDDB5BA6,A3A0701F73EE12F1,7E9A849B7367C880,B33073BD05938147,AF34ACB5F0CB9666,E86FCA38E7E63AEF,000000011CE99CF2,FEBC0F546BD5A840,20FF8B7FCDC347AF,489561553DA6A52C,6222D7D71F11D56A,11CE25FAD8902F37,AF35AB3257933F31,DF55AA1541AF1BF3,47C5A39C7D77EA40,75CC2108FC31F983,0000000253BC6250,D4A3162B76BFD0B7,F2F90A8A53B10158,2E9306CE349304E7,0914929D53998FFC,EDCF4DBB2AC90F95,7893C6A1216E4B98,F30A55EC3D15B9DF,4609D60E7520FCCE,0052E9E7BB73B262,00000000DF225A45,B2607796686D8D8A,A1DB40182196A3A5,C3355C05E39D6350,855664DCC57B0098,2641892D11A547FC,97C7A291DD312272,618E2A2A1F4C218D,218E10D29D3C268E,BFDAAE240AB39D88,0000000111F386E5,EA7B28CD23E0B0AC,896E053ED41872E9,DD9A29EF60611A30,E27FB01FBE8040D2,2ABF29173628F6BD,F44650EA6B52D803,D7BDC76E1AF60EA3,F7F10CF24CF950B1,BA78C1D3C56A426C,0000000006C5CB70,1185D626E75EE159,E78F782DA9A9A7BB,C4DE9F34437C6D86,EB621E83101AE0FE,7A289DCDA8F5E67F,F727F7C8C07AC311,B6B54E6E41BFC127,D92EFF7175B461E4,8ADD03A25EB0DF99,00000000E416C2B8,9570A536B6637F3D,CFF01F2340A3E16B,CC521BECB248850B,71202EDCDD2067B9,6AE53A5D52B4A061,7F387B63126C72C4,A094B34B2611F4FD,AB153B4FAD36AD44,799182B1B31D6B2E,0000000083DEBA50,E7E88B3FAA277C45,8E39287234E09E6A,1F0103C3CCC874D2,01C115CE8F9E53B2,51E6005B5ABFD630,80DB47BE65F98358,7EF4FB0BCB2BF038,72CD7AF4F72BB1B7,4900C4DF3F2A9428,0000000075F6A073,B7E1F5A03C525CE9,59EA89D70533AF23,53505928C24D5052,35B0642B45DD8286,01634D2AFDF4EC90,A04100EF438C795E,E571828DC4A2676F,4068C7D807E9E577,973CBC66D5C34313,000000015EB54B7F,B4805F9B540AB78E,AA28CD8EC1E780D2,B55702D54CEE9D61,561C67C79DBF2C35,95BA1070DAA6F66D,1141BB72209ABEA6,357729DBE87A1758,E4EEB640329B04E1,E0E92774C142BFAE,00000001AD638468,12381A0BB7883685,ACBD8A6DA4A8A18D,0A58F2B639E0BDBA,AE39C515E09A89A3,E38907F4D7605413,FEDBB90DB11B3D18,8B8F46B5AA642673,4D15D27E13DA4EBB,622D4304B86DFCD9,000000025D3E8FA3,CE4BE816ABA61D64,B6A1D42AE27C9E69,1DA1014A5A6575AE,A603F18D19B3AF90,44D3689B35B98A0E,3943644583304D0D,126916A786325E2B,2CD15CA524FC36E9,2DB117B22479F379,00000000A1484386,B1089848464D1CAA,4421C6C272E024B6,035C0C69ECD92BE5,9529D8A6C8A2CF83,4ED6B1D7412ECDC8,DBF1FAA4DD2F8C25,F0A50130473CB7FA,5C215CAACCA479E9,A4D3D05DDD899BE3,0000000224BD978D,B04EA22AC680EDDD,6ADB9E1E99660D63,12AA1797377BEC6E,CF388139A80BD5A4,A492A83581BFDE6F,6EC39FE67EE2671D,6A32D3E6431463F9,D934B2E18876A206,4EB5C19296CFAB18,0000000054002835,EB94289D22394E1B,3D37FA538E07D8E8,6E74E9269E73A998,8321335C55F59BA7,5F30362E251208DF,041CC1C2DEBC28EE,97E82056C7BFDFA0,3D12E196C54D493A,F5939DF25E0D464D,000000006E6D2783,4301BAF299686923,314BCAF148823BB5,A3BD5FD9302C7109,4147BB1B96E91C2E,C7E028DB6FAADB1D,250AB75B407AABFC,BD36A1E958B70D3B,B0B92F2433265DFF,56D7B0269399C53C,0000000157F06B51,583918278C284FB4,13D594F71B85F2C5,A7E56306C069610E,8754573E8AC1A527,8CE94258BCA8A51F,1EDD3242DD0EB58C,859AB7AF714D79ED,3981A3D843977950,276EA7A519E588B1,000000015662D682,EAFCCDD2DD016695,CC340582D7A188DA,E65FD6D7E68DE8F7,83D09E1292F1DC10,3FB47F1B5483A53F,E02BEC4B583D386A,D0F75DC61AFB38CA,08BD2B6ED7550B45,3E02693CF0D21FF5,00000000A5929503,ECFD84B427B16C09,79E6072CD3220D74,8FA5A1FB002D9A5F,2EFCDBB7444F7D1B,553363D498F014AF,7C83C6286F7E2B8D,3D95BF6765F33770,BBCEFC077299FA1A,3992DB7CCF90EE50,00000002579E7D94,82244114049DB4B1,643689F9AB553ED3,2A49348F7717EB3E,5C1FCF2B75425064,17AFC3FD2C5B0278,33D77BBCA435A5A5,DDFD4EDCAD6B5A85,A9118D4F9CB48DCD,D33BA4318269B30C,0000000190BB5ECF,A7D417E44AAC3935,D3E48411E20B0ECD,254D4DD980BF7E54,9EEDC5923B191F09,1C6DFE3B76228CEA,F4AF1D2D4F0F239D,468A7900D018FBC4,A01B9D5C38D10612,9C32ED1D3CA04B6C,000000024906EE22,566AB5C6A9248A02,CC8EF03AD46C9940,3330D6FDF9D38841,F3B087B907F60293,D62F75A8AD645A44,5563F0E2E66B0AC9,5A66BF8712466A56,F0FAD0698EED7440,CFEE864AD9232148,0000000010F0AFD5,3A0116D6C655E9D9,B01297BFB7870AF1,320917861F3DF956,927A89130D72E22B,BBD1EBD7D275CBC1,0F1AB8CF2E3AC86A,1629D3C2CFCB8580,2C2C669E971E7D01,F76037783A907B82,0000000170653C62,BBA2BB6B82A2F98D,F143E4E5E444CFE2,DE6692DCEE8627F9,99592E427DC05EA3,E3889C116BC63E46,7D91D6DF8BB79400,C4AB954689E931BF,474125DFB7027F79,3A97C45C9C703713,00000001A879F4C8,31BEC3E0D9AFAE6E,2FC6E36ECFCD891B,D030A5A5725163DD,7C2EAEF98FB8D5E2,2B340FA54D9D98B0,3D5CA68FD5DCBB9D,FF3AE4217196605C,19E3C87F6916616C,E9F2E8E420B7D0AF,00000001A97C60CF,CFCF105E0AFB4015,9BD6C4553830AD9C,15AFC6FFC758CD77,1935D126082D85FE,86AF197C7C0FE6E5,42B56CE896BFE1F7,2198A706D9B1308C,1050E64061B14B6D,6A9AB2FD7EE7B80D,00000000E0015D73,3EEBC2F31AE910D1,658A6C6C232B5EB0,6D848587CE4443D9,5E7CBB27933717B0,DF88C542724A4198,7EEB13E3822C9BB5,133C21903AD01BD6,CCBA22DBD72FD03A,D87E065A4E41B3B0,00000001F6A69F2D,2BFE531927E95346,546756E651346710,2E96E3E80414D28F,2D2B45EA3B283AA6,A8547A78C6737B35,F4F4C36611688376,6BDD71D9E0CC2252,3DB63870D006F185,6D27913D594CB777,000000011E8B8454,25DE6C37A0A03449,47C9116DA81007C5,96597AB54A2C4B85,378B31A6FF4CD8CC,B1417B47A61F706A,6D35C37B1DD54E92,775B63C98DB484F4,4FA80BA8532702EB,B2A0CA2CBB1E159F,0000000014DAA19E,A369B8E76C7E9B11,DB1EEC8DD0881B1A,CC6519979CCCB52A,416A99DB016196E0,0301F874DD49CF78,56654B8E854F33AA,A02C1CAC0BF70D00,7D2771C0CED5CFEB,FDEF5C7FED61E267,0000000013E41628,438C73A77B35F2D7,D472852FBC11C9A4,B0D471942E02E6CF,1282E33D2F12FA54,7545AA73288D6127,A2D07A12D8D2AB03,88C94C0AFB6DB0B0,BE3AE028035D4682,B3DBC487ED0DA89C,00000000914328FF,DF2CA6AA3B69134B,46612199B7DAC3B8,7E3AC5A2F98B9D44,2A798F2BB219C90A,1D86212DB2187A9C,12701A8F269AA5DF,2AA954505A175CBB,BEF4FD02F8F4A172,E922E1F84D14F45C,00000001323A8708,E7D162F044622F79,0506E51F3FDB594A,8445C717AAC5DB25,7138C7F3D15A8271,84ECD2966D59ED5F,81772F08D056A48D,204E4899459EF3D1,4BA0CB99B4D9D545,CF0925DBF788BBBB,0000000203FED31D,7E03F4CB3CF8C5F5,6DDAEC02617B6CCD,67E95A1BCA07CDC3,0E774638BF4DDBF7,0F242F5CEB837A57,427B9CA61EBFCAFF,A7FADBC04C43821F,DD03B8BFC6A74EA5,1D95492B0D29CAC7,00000002571EBB58,4C331A744D935A59,2D000DB245919E2F,98FF2FEBBC76CF0D,916CE39CBC506147,9555BFB897D08109,DBD86E1696251161,7E81B59898507EB0,3C0C5D007587FEDB,893B4B5AE385ADE6,000000003D7B5D01,6CA7BC2EB3990EE7,BC99C0A09CDB4293,DDBC34A06116D86C,B3C3B26F4F8E33DC,FF681A6F1CBBE13E,1AF5E483728E3E44,7AEC98D774AA5739,CCC689D9A7807C38,19D77B68CD8CFA9F,0000000011720A5C,FD755EBFA95D4375,671F01E048963C3A,D369FAB949FEA3E7,638BAE53C0BCEC9E,E66C5B928EC0A13B,892E78E0808E013E,942252F9FA37F84C,035FE98EA7C81D77,BAEC50B935BF4720,000000018B04055C,08C71049F194E0A2,5806241698370920,A670E670D5BDF22B,8A3AD1F192282C0F,498D9FCCC6942E15,3AD935C04A6D20BB,CD189F788F638C1E,350322449943341F,2183AFF88A47C988,0000000003B0BC85,EDB72552BB3E24B3,0A1C3EEB3D2FD7BB,D67E55DAC759C0E3,453A2BCBA45BA09C,20B27483AADF9BD7,559716587CAC3199,C414CA90737ABBF8,C36FA3B377EB4E1E,A0C72CBFFD330449,000000008E2AD071,55D3198A5F09C1EB,0B7AAD3DCE26B510,633C2442A844CD03,9D9ED77C25D0BEB9,6947F9A805ED4211,853D0911DD3232BB,BA2FD4DDAC249066,CA179C6F3A23394F,B8E758B78EF7C035,00000001D0BC6675,489D70A4E82A35E7,F66BF14B4D25FD4B,F3D9DEAF4A3D595E,25FBEFFA41D8EBB3,1B843767E82D855F,27BF2C47B8DB4E2B,550C7AF12A5DAA4C,FBD2711C5BE6DBB5,6CED4CB618ED97E2,000000026B392280,2DC501BEC24A2291,5075B112EB3D7459,1A2B7EEBA5E3AC2C,920DCB372175DFCE,5E5B057620382BE5,E65B344AF7D4A745,F9997C3CFAB91187,5959D8D5108B285D,3CE67584F6237B76,00000001305E77E7,B20EB6CEC00FD965,EBEA628753BD9DD2,7C62112DFDE33306,B013E8B34028A58F,41F0C88E65A2A35D,06857EFEFB9E9BDE,AC34C5E6769212FB,1664219399C7333F,E1B25CBB6EB27A3D,000000011446FCDE,BD4B4EF33D522558,70302950B966929A,E672A215A57FB424,19E5765BD338F682,ABAC846CD501B25D,91984B519B8E0788,35DDCABBBB40E630,EC4E8945CEE47407,2C5E31C896BDDD32,00000000469CA450,C71F663F11E588FD,D60DA9D6C3C75FFE,40C39940805647F1,A75D3DB0EBA861FC,7CD3CAF06FEDE6AB,E16AC51FDD5A878C,4C41AEEC4F2580C7,85D965CCB4E60923,84307D85F25746FC,000000007EC704CC,0FCC04CD298C8A92,5B765EF88438BD87,27C7914A6DAAE383,3FD26F9C7848F6F2,5221E5943F6A4F60,94087014DBF0A35C,0B3EDACA0EDAD9AA,52E21539C1135527,E54E508317495889,00000001C66180BD,C052A4639FB00591,40FA45D7660546DD,7BF8451788EF7B5A,3EA477A856772372,15B9ADA0689AE347,F753D7BBA2C6F4AB,1ABD9A42682B1D94,29ECCAEA55915021,1044DC6DD9E1EB6C,000000006FEA61E1,55999E3CE7D8E5F6,6820FAF8D776148D,C792FC272090E7A4,05C47957B810779D,9A354EC7ECA035B5,B2684A0119ED14B5,7536A19242F17BC9,B86A71CD45C74ACE,54CD931DB9EBC970,000000022A73507F,7B76470CE20C4D5B,C6F0A1C5F536C564,E42CCF4D45F66690,F5533871E447D3F5,60CECAD0BFC5A152,BE5844B6BFF89FAD,F4214D94AACF7086,0D391E9C5BD4519E,227718C56E5167DF,00000001E915B8DD,B36137380FD626CF,965B717E9BB6B71F,8060F4739EEBABBC,FF8BB75D23510F3F,FBBC6803DF81B614,B6C3033D60C521C2,ADA7A8CE45998C33,4A939E74E849F640,259AB2A0EEAD00F8,0000000028823E31,B06B8E6354083595,B55B85643F2E8D98,3B917BD90819855E,508F803E730154F6,9FACB208ED595CF2,5BC15C7361219B25,EF1789AEC3AC4769,2B3AE2CE96928B2D,67C35A8B41AB7229,00000000D9F74B0A,EBF6B214714B3A3C,DDF756078DB6809C,AF0B1E40B9ADC627,0B6DE4A9B05EFEA5,CB3BF7DC00BB5624,A69618CC72AF49C3,1B3A9274C8E3DD24,D529B5E4E326FE0B,45F77F6FE735AE48,0000000165B1D8C6,703E9C96AEF853BA,2F84B3A0A783B3F2,3D9A6E2CE7135DAE,DF47831D9CFA8AD8,B3B5DEDA2E92E395,39EBE6CF50E21262,A4829947CAAF3402,725550257C4313CE,0FF5A322E4E397AE,0000000164B7168E,F18B5837129F8FC1,C33AF65B2A4DC8D1,B77F0A0DA50F0BFF,9014F2B6D3521422,9C9ED9D01261AF48,A495AD4E95FAFA8D,17891901610BA6BF,A9AE44E5076A3132,4B27769FF9E48633,0000000222AC1A92,61F423747EF3B456,BA091AEDA0606A2C,A4C15AF335BFCA86,F4F957B0DD67BA59,528058749E552890,FDE542F3AFFD252D,D70D1D0A17496BEF,F4934A4F70F735EA,083368ADBA2C58E3,000000020A26F5D5,EB4C6FD4B2813A4D,15D99506824F72BC,6AD42340A490FB90,3BDEA876366E1D58,F93F00F70F5BA695,6B7BE75165E72978,7FDBC60272F3CB96,86E92E617E3A4A84,CC07295FC11F4CD3,0000000233172430,62187E35643A20F2,E5C782A7591D8B2C,36EF89F64A6073B9,B859EDCC8CFE0684,407F4173AA70D160,7AD50637D09BCA3D,E78004D1B4A83A93,23B9D489FE2F534B,4261886EFAD903FD,00000001AFD4359D,7E2C95597FB28FB6,8EF31E42B5CA1483,F078B20DBAE8334F,8BE80E1E11DA1BD6,D1C18C4E6A45ECF8,4D71350761FD0C16,6CE69FDE27EAB33A,11EF5E236C302349,4FBFE23C1ACEA345,00000000344BA264,28A29D92D1645827,2FD0183E45D2F2D8,2ABD0A0A9180C4A0,1ADE5F20F679B66E,A7963D45EBFADAE2,B54DF3DE465AE01B,AF09EC75533AA522,F93595F833B23E13,966C8D03FF661B7A,000000014DD35B74,E19BF615B593FB89,3C9085FF2898CC47,8B9F881240CD658B,DC56B9648F676FCB,34BAF9BAE39C0699,83B4632EF96BC46A,73C1EBD612BF1F17,7EB137DAF67D8922,FDE5D1A551DC3443,0000000153EE21EE,3C2A9551B257C3AE,B9A760F6D90E60F2,A048B375F75C4942,8B2E086E86EE1BCD,53E9C294958C2805,0CF7F32253E681F7,9CBE3B5E9C995F30,02D0760F250F6E35,24A4E78259DF1875,000000006487EA06,917C094B0D728B2B,A27BC7A6F645950D,E28E434B494E1968,97DDF498662370FE,9DF9CB3EF128A421,7E7550DA717C24AF,506B31F5B8447FA5,FE8842C0FBE4A03E,F14B7A69BD8DD3C9,0000000028E7F851,04BC8FB94CFA2F8B,8F5285EE6F7560F9,B31D5FBEAFB9550C,F5E082930900375E,539708E86E867197,8003F1CEDC178C08,91B6A36BA1FF26F0,249C25CC2D981BB6,22FF5C586FF9F441,000000007EADAED6,260CA93C5DC7483F,A9920E24B2CDF599,739E075261D565E5,8DE23E4D25793789,69A649F4089F3E82,42BBA5C142F02251,5FAB58AA637890A7,7A24ACF190CEF1F4,3B82D398C0064F0E,000000006896FA79,882B4C31873A5874,01F4104B3B8E2D91,F573F32A4F8AEF5C,331D0949978268D8,9E140CC8D4250796,3057C39AE137720A,02917E21ECC53B18,03E2BFE46BA7AE4B,C96132C492BA59A2,00000000FAF9338C,A9720831D7A41134,AEA7D012440E0B4A,F279C91D2AE4D098,49DBAA29E3574C48,03BD2566A071C84F,2A364876448F141B,71A72DECEE0FA417,92AF749BAA6F5DAC,CB880EEDF4B4751D,0000000202D4C2C4,CA54D690685B1C4C,04A34E23493BA7EE,93B837B9371620E7,A1E1CC163DB56EB1,C24B34D68B104A9C,36AC1BE32B3DBAFF,821458ED0CDB689E,68BEBD54CA310827,09B23A5799FD0DC9,00000000116ED021,7667B428E4D60686,F1EAE71C50FE1B06,08A40921DBDA36E3,8F4A910167A27741,CB51867668D182C8,784880EB792FE03C,B9FBD72EDDAA2A4D,DD803BB8ABF68D7D,FC9AECBF07DDC97C,00000000CC6E763E,14863E4418952A91,D4A45C7DCC37FE4D,4D7755DDFFE23446,1A7A637FF25027DB,FF6D1EBCEA6E1810,092B49BAD2E86C3F,835EB98E29B7FA59,CB574258DE36ABF0,413EA0B7BA567117,000000007F6C3B0E,4BE6C3283CE6AC4D,A94627B950A45AE2,179103608B47CD10,08AC83055B51EA41,55D914429C3F20B1,98B453A620CD5E5E,1247A265143A2B51,B9594636E6B6D16B,83E13A92B92A2837,0000000251532386,30022CC8386DE959,B344E65CAFCB014A,463AA6359F272141,B73A31C350995C32,FD02026A5F29F6CE,7AD1BA0212876046,F4C5BA1EEC14FB32,01D5F6E54C04678D,72E26D1F8E95C162,00000000A9E8EF93,C22600BCAD15218D,6E2D53702642AB44,D7CDD79530F3DF26,6BAD84C6CB885847,158608A71877EB2B,E03EA154B4AFB9FD,A2F95FAAF82FCFA4,674A67BA1214305B,CB70BB9B9957FA31,00000002447FD556,C5660A4F1482579B,F499374FFF9A537B,BAB1A90DCF5395F7,8DFFDEE4713F1DC8,3906516D2FE7118C,F58AB0E5780C3E9E,53831843280BD8DE,E9C752A347E05DF3,9763B840906276B7,0000000260780437,E3AB10460805863E,3933D1B6BBAF6FD1,6BEDE1DDE4F10716,795D2AA6A1C24053,11C4E0D391A03098,FB209927FF28238C,FE646C0D56753394,D782E1A1124DA571,D380CEF1BC59BC35,00000001649BC38B,AEF1A473E8D6AF71,2D54D91C49D35401,37EA470706EA3481,FC19E9C787BB0EE6,4D50D907700B8688,2CC9A143C9DA9328,57BF198FB36C353E,9925A1A3273D70F7,C0686C90612E2FC0,0000000085A15794,DB890BC9BF5CE000,B818B37B67F1D272,5BC0782350684135,84B3AC52F60C8F8E,426AECE8A14F1C8D,4E2A4DD14336D96D,16E513D6297B9398,AE1D6292D84921DB,D59D1E768E5757DF,00000001B817754D,8D4BE12E13FF8B81,6BC66651F1D2EDA2,4D78D0AAEFE102A1,FF7D8E4851DD817B,F93CFBA274F81A41,96CCCD33E121CE6D,9994BA9005E572DC,933CC18D1DF5A965,F4B33FF77303FCC9,000000005C55922D,12ED65195491EDCD,E6C65F1A0F8B6620,87B8DA977DB36445,7F2F6042217009FF,F45DF6E2AE957A02,64B299032BC08258,08384FDD53FFA1AB,DE8DBC90F49C0368,C21AAA1BB44E5735,00000001633C2C65,DE973A1FF192640A,147B39E9CA6F3CD7,C29AA822C5198AC2,503C9EA82A4CF322,CECDD0DE9EDCCF6D,843B9B0622B04460,DD92FD0620EE5641,FF4D54694DCF47A5,DADCF01DE7090247,00000000B5022DD0,AC15A721B294FCBB,BBEFCA5AD3A31D0F,9B7BC6730787C547,3896EBD3D8FC32A8,FDA59812102A0E9D,C0DD08282D5C71ED,DD25D818E7670648,B067CA579D6A996C,FD61393E3CE4141F,000000017692C936,1AE452C23E775AC3,8526498975B0FD31,38192130747BE899,C740AC38D44C203C,A78590B6F6735AD9,4225D9C1E9CF1669,6B26C3B150BDDCAA,659BFD9D237257FA,FA4E314378CE9030,000000020E4A2306,5810663D5230F785,F2A31AC6798C8FB1,C2F18F105D9914BB,FAEDB4CA7E4E149A,6C716C8C60552D96,54E77DF574DDE267,36C79120B311F5E9,1FFBC25AA4F072D8,F44FDDC5C2E4A1A5,00000000F607AE42,E4FD017B3E501212,E310AF14DA3ED629,DC98610A524D4CDA,E34D986CA5D87CB0,404CF682CBF6AC01,3920FFCE4749BA89,2ACCD290562C19E7,48B8390434481257,EDAC4D7BDDE481E5,0000000110ADF003,5CA51198BA7666D4,C0D4B2316A2D62AB,B52A28108CD961C4,3C15F8377FA35902,DEF5FE964B954C31,B046A4CD868BACD3,78E74446662E401D,9447C95FE2DF4EC5,8A26D7D81E9F7213,000000024A9FAECF,E03389F1E56F4366,D82F6F817779FDC7,D3C6FEA644711395,F2DA0BD6EB846371,7EB32AB1881CF6E1,732C073EAD0E8FBE,ECECBACE3AE8BF97,C196BE8DC5FCCF81,E7D6BEE3B407E117,00000001F692F304,8665AB82587A7ADD,5A0BA83197A44ACD,5D6C282DDD8EA0B1,948BD0CBC2C8DC90,E6BD07BC6A263EC3,E121A9AFBFCEEE34,22FF5864FB4B295F,B4F76ABA7F88761B,D74428F8756835B1,000000000D80E75B,D5E0D62595446708,E79143959CD9E9FB,7A5034C74D6E8740,21EAA0AB82C7EC6C,956C9B022898B1EE,CC963D03237DE2D3,74788C867D40CE4B,4C824F99B8D5B505,E83F2EAA7781994F,00000001D4415D63,02F0F338C8823AFD,5EC8D6C78C7B14EE,5875EE456FE58AB5,D6BD05FD6A836419,446C18F054326983,9D0E0794F4E354D8,C9FB846F147AF568,70B6CB6096E394D9,3E1372A0CBB9F486,0000000234B7D08B,ACB774431BCCFFDB,56DCA85162ECFB34,298C438821F64E29,C5AD051D0D3E5B9B,D116025CE352691C,50DCC4D8D69B6D69,E6702E781FCEF5D7,629D1B291559734F,3A899AEF0A05665A,00000001CB5E853F,B0DBFC877157A07F,3A68CD4E2A687810,176F0517510FDEB3,9C03BB7781E1261B,DDA1679E185B7994,FEAFE202B839BB8D,537536DFE459AC7B,6E4BBCEEA53C25F7,0FD1CFF53AEC89FF,000000020DA5A59C,5AE6BC2226528515,539257872CF2857A,6581287807275024,476AD8A3A4CF51ED,64BE558997AC332A,52843CC74DBCA055,A17B0CFB22151E46,80682935D1F1CD62,20941DA5963459CB,000000024423B7DC,1990D092CCAE75B0,FAC3D82CB7B1FC5A,793493E20138F38C,897E9E4323205333,B8E0E27D51FEDFD0,8369769D2339FD3E,C57D945B0340B497,F0790F281809B3BE,0FEAB403A5996181,000000017DFCE782,86EE254AF2499AFC,E62798E1CEB95B2F,EA0AC48CFA7857CE,E48C2BBDE1F00037,5339009C3F856DFA,74F46160B12A6586,6DB20612F73099D2,A6E3E327F7D3B5ED,6E1AB997B29FEE90,00000000DF7AF311,29F4BA2518AED87C,6BB9C7674EB29844,2B785741AB10664D,C7147D686A470589,6EFA7F672C6B45F9,9D7D60CF05B703E7,D73839951C9DF2B5,C4AABD7F5A057618,E6F9A5B0F8EDDEA9,0000000211932ACC,F9C9011508E611BA,0C6F32A864583CEF,3BE9C0FD5618C132,2D6875C2A781D29E,8718E6F86EAC5774,C14C90450E0A01D1,ED0102BF31018E70,785FADC6399D66BD,250C469C7E2036A8,00000000028E23A0,87EDB3E205B0D6B3,03D5FDB6E78B6694,10F9BE0474D655DA,58748501771B5F95,CB4ABD9998C27CE8,78687132356DE757,30AC4B96FB267999,AC5F3289868FD24E,FC10BB3812EA8850,0000000028AE189C,61251C683776B241,513CE338C24816FF,FEAECB382A5D684E,3BA7CEE70091A627,18E98FB290F6FB4A,9FC768F5038F3F1C,FFC7B445D38E9C1B,0A8DE68602CF1BAB,93B859B88F025B92,000000002483CBC7,5FDEC77383428DB1,6FD78722DC161B62,405435C809E2F473,CB39EE234DF179AA,37D959226614BE38,0FAC811E924D944B,3F6E2185F595BF4D,A186D900F26A861D,8B03C83A4A41DBC0,00000001223DAFD3,A5597B9D90195B1F,01A2AB2A2DB02375,78BF455DCF15E507,A1717663ECC79662,BE5583D1E270C03B,59DF7DF3F428883E,D27793AE3A3A8C95,A7E23285DDB9BE21,9FDD924702E2C0E1,00000000C7311626,8A9EA6A244ECFC88,514BBC1989CF49FD,B3F83A3C4D1FD447,B29660FF079572AF,E4C4789257489943,092A164354CA92EE,EA2A61237A20A5CA,3709230D22B3F389,EC037DD9065EB657,00000000E959AA58,482F4F6EBEE8B494,C6865CA41785ADCB,24ACAD02DD4EE34F,DA6D8424A6D5CCAD,48D5C6E4F594DF67,6E50AF0EA22C5353,37D87548042064CA,BFD303AB5819F950,3FD504A9BFA40FEC,00000002571C38BF,C7CC3078AB94BA08,7E205ECB3741E285,0D618D319B73E9DA,89C31F9155AAF0F5,45B344B5388620AF,0DFF5050248D923B,5DAB751F68CDA680,6F6FAC7276304794,077E22C52577A8A3,0000000262823AAC,DD622BE0BA1618DB,38AA7624D56A7CD6,9C9381E134F640BE,E6D0832CD957194D,A8A9B70667C5B08C,1AC7E7EEA26D1D1A,5ABBD82DC98B6FA3,2D7D0CD4602DF74A,D5C451A3E50418CC,00000002388E6EEE,E245E046D682C8D3,C77516AF1F505CE9,4638B065EF758F00,E04C553141B062F9,E96C3AF18FAAD483,5013892BD4E51AF3,587AC4D05CD876DB,8B87624EEAD66E40,51CC69AE77DDBF74,0000000218B1C415,1DFBF97A00DCB673,3A5A99C0E373A9A9,B61FA49D0326AEED,10CB67CF9EF837FB,3D1425986AF6D03A,0E43BF134C561C6A,33160AEE71345B18,18A44BAAEB29D168,9AD9690A8457E782,00000001D71F57C5,677FCD84230306D0,39606CBCC4080673,456D8002C627C987,F585A948A5058559,02180628972ED1C8,9F1DE96ED839381E,CA1E5D052DB4E504,D4D3C65E8AD1A738,A711A74B2A545625,000000005F3953E1,502EFBF996C13FA6,81A5C07BE8B225EA,5581413C06C2FF27,9769D90DBF3FDA92,65924558ABF42D02,0AB027FED8A7D232,0213A12E2E0FF1EC,3C9D5B6ECC24E8E8,8F0CDEAEF8B3E51A,00000000A11FBD7A,A30186E7944FF426,4F379E977E877D20,6500F99C0706F259,78FDA65FED3A6D2C,03E055607B1BF4CE,92CE769464258793,E2590B1FF870D2FF,46C9087632AA048E,13BCB385A88F80F2,000000009E966588,A3031CD83C62CD2B,1282D2879BBBEBAE,DEC95DA146AFCFE2,AD143641971AD4FA,DC9C429F51D68231,21D1B8233FDC8BA2,B6B1F7C02C08CF36,9A6FA3082CEF125A,712D3D229CEA247F,000000002FA9919C,357884BF4BF096DB,E1FAC83C13A272B7,A73BC4828AEB98FE,97AE5EDCF55E6287,BB6E056358EC2962,5A5081F0BFD1ED7E,F0A9CCEBAFE04E5B,4B05C23085C0064E,54A9D2D2782B821C,00000001DCCBC0F1,8EC1EBE05627B965,78B03A2830CDA1DF,5596113A0195CD81,3C82A8DF2CAAE30D,588B6CE442044641,AA4E8E06F97945F5,C50C1082B49771C5,8774C138BCBFCA61,57E7B1421D8985F7,00000001A5BA8DE0,B8FF3D5BAD2C1BC9,A484ACB0D6578849,E813D8CF2A272B8E,FADC568EA52B346A,C94403DF88849367,045F0B7ECD571A14,AD3899293C46E827,B9553A3F2D1CC256,A853C8DB0F7B70EB,000000000EF587FB,43567B4C22A31F2B,A26C5CCCF8DC73A1,4F377B190228E1A6,E6E453C93A5DDF7E,AD9A6C964428395E,6912C6BD381A444F,16A24F31E3589783,AE9F271508CDA9A8,3E65CD23DA315873,00000000888EA896,E55CA374E633E92E,312B90ED099D68A7,84F6BA4CC28E7355,4520F17938171BB0,47855D0552A22548,38E62630894EB25F,8400914CBC44C252,57EF1CAE148563CE,61F6D0B8A339758E,000000026BC4D215,E7CD67A6EF5E7F9E,238C560A1828D8EA,92ED693E44825B7D,36776982E725F21E,68CF8EE1CA3AD724,DDF894D706A5C0FF,7A943B54A5574696,D89F4741D54A79DA,7E624513753D406B,0000000258FCED54,2EE9FC875E3115FC,6FBCC3C0770FC529,DBEEFF726B44716E,86D61BDC7CBCAE84,FBDC88B6F934F900,5161AB4FF7D323EE,668729331088F005,07F050B85EF0CA86,C2B03FFAADEA9142,000000020683E26C,F998F16D97D293A8,34823FCCC8815C91,AB7E26C89337885C,2F6E5FD3B740E6AE,9252DD0D09BD38D2,9374FB2834C8BA90,03083BD53082A806,7A496ED94FCCE228,77F88B895D9BB635,00000000508CF918,F39DEE86D3B0013C,B49F45D11C536356,B0EE9A0D4EA0445F,D75C8E9D37364072,2ACFDB7C27580A2E,657F9257ED3B0B37,373464B8B14A8648,AF1FD1CBF826FABD,27CA23A77B1C8A7E,000000000C562CFE,EA10CFB32DD7D261,83378D0869EFEFDB,F9DF28D3C4555C95,83F664C07575ED23,27B1A3ED0B75C8C0,A215D861CB3CE160,E0036640DCBC1193,D4C01F7D9D7A5A71,68E18E0428734788,00000000671BB0CB,BF9204FAF3952B0C,1F5EE8EC2C77B25D,4299286725F96D16,01C60FBA65C0D24C,7466E7D9EF88C661,3A49F4F0642B39FA,50D08E35B7A2E2EE,196360BE912BFFD1,0E99606B22E2DF68,00000002733150B5,EDF9EE79A90011EA,9202BC739DF63128,EDA47F24A9B80B83,7E7C06EC536D2F28,E17DB4D462C05758,8F7A04BDC65ED224,F7E09034AED09540,19F2893620AEEDCD,7F6CA1913E0EBC0C,00000000980C3DF4,DDC98616C06DDE53,305D1BD73EA0C02E,75FB946D02539CF5,539080D7691F5AF9,F192740772C46292,27EDCA79AA960355,7087A827E6EE6B65,12B01125EDDD06BB,79C62A6D23AA5A47,0000000236B4C7E0,8B8B9DFADD8E8F06,6D809F63E4EB90F1,A0DA51F3F73A7AAB,364761BD4316D9B2,FA0F8DF9A80A1F9B,59FB0E8786C8F767,66909DE0E8909889,60BA3B401A51F0C4,2B5A7031A6AF6D64,00000001E3C4702B,398FA2C6E8FD1229,CCC7F0A53EB832E0,EFDDA3CE82AF7294,EFB423E36AFAB30E,23DC9F7006831BF3,7CEE5FA98DC7B283,6AF586366CEE456A,EC946EC52EE19D54,A79B7F00DF7E05DE,000000011E73876C,E1E8D8E01BF8D5C5,A3F21F836539B35D,882FDE7C666FE4FD,1FDA39EC656F2EDC,298250EA4146D87A,701B9EC8BF5DCF45,8AF20F0DF5230665,8131E91A13E9910D,4516226C5253937F,000000017B148925,DDFB6702ED96CDFB,B68F78C1809CF946,BEAA5E92DDA40AA2,4DA235CDBE92BA68,3B684A95C253A533,0FF8FAA4205BCC3A,5DFF9C9BFB04A26B,DACD1BBEE314E08C,177E4DA3D1F428BE,0000000094891F6A,F3D0B5F6C63D0C23,5AE0DD7D97C56C9E,26E59D7AA7508113,07BC49A0C393D699,08E7CA1576CCF179,24FBBC66F1778D96,E93BBD343207633E,68C740370FEF4F69,E3A76E5E4D9290D8,0000000086E5D959,EAAF6EF6F7A5C694,0AC3567830EAB0FF,496304304CBFACF1,310B2558BB1C1740,D53FA7123633715D,69F087A07ABFEE61,2912062F24E9D423,B4B896BFF585D1EF,36D5E9E5CF45A7CA,0000000163DE2281,885832F7C4093856,EBD8A66C90CF8F42,B9E460E509142D5F,83564C3DC0F69E82,9B00F657702677BC,2E830F9F207B0C41,801E1A09A857F2EE,26DBA6EB579510FF,FFF003E72D530DDC,00000001059CCDA7,0E87D67136CF758C,132ED2F477E919B0,EB417C954C2AB523,D270B2BF7AE3A5B4,9AE03360717724D7,14876A179417A04C,33357197DADB8977,0A841320B9BA1EA2,4E56FBCE1A446B99,0000000271AE1E2F,C29E8465FCCDC3CA,5C03A7D291BAA0D4,B6A7AC6DD74B2FD5,98478761F6464D79,1BF64921B73891A9,8876DDA4DC19AE52,3852FE097E2E4A50,336CE3231A7B499B,87B94B11DC16F879,000000016FD2C175,A2B9395D0D4471A3,49DFA6ABA7E8F1E4,1C0DAEB0F6E60A65,83205E1158EA41C1,006ADD536FEC646E,1B19D2605739807D,D8184729FD55108F,48AAC1C3CC7E36D7,387B0E62E26B0D58,00000000C518BD77,383449F51C45E48B,7B5308AEC5E3CEAE,7EC6E2C209335ADF,FD1001963E764DE3,950785B6B6BEF754,59E0EE307561727F,520619FF7740793E,9892FAD8487746F9,DED3CE4F79091E84,00000000BFBB4928,CEC573AE84577EA6,0BDA4076D7AF264D,231D648107730B4B,DE7D0F38125D46BD,EB4BAA89E4430B9B,F3643CEFFFDDE962,A06382FB73663B17,5FB8496BBD8BDDF7,68979AC84771FF8F,00000001ED2AB640,EEC48989F3ECE10E,0C9AC8DC650DBDE8,CDCF6A2898B4FA69,76E3BFCF6B02DFA0,E534011AEC616399,7191E3FFF9BC9660,D9B392D444E41B5C,218A0177F1B7B9B3,F35723674AC6432D,000000014643C080,6CAF7511A9933170,4FF9D71B46158BD7,F1AE32FC8C3C3367,F94D967C33D1565D,10D4BBA08F9FB2A6,A74ED1D5EBFB3BFF,139E3D9BC57B0506,A969632D635B856A,BA2F9C5168F87687,000000003E3B8423,1CF9A1A425B2639F,8F41C3021796116B,D50825AB27F4A96D,42988A0C2AD5B58D,F38DFE699DA0D6DA,891D404E0D3D233F,85355DAD72D47666,B54DEBE194739A3F,03CD49B63C4DCB17,0000000193D9B808,B09BCCD844AAF1B0,794073F8A99053C8,9DE6953521D6E585,43D60A7CC7B18E63,32DED720AAAD25E8,B5D9EF37119C7FD9,DDF2EBF1C1D4F53D,A7B68A3A70DB63B2,BB0C0BAC522195C9,000000026BFB0B93,E994E1BE3B2058B0,087C350F93C6CA26,08A4F7252F63F90F,A17F7E435EBEE641,9BB1CFB8C5FA0340,BFE98DA511D79121,AB09A97F4ADBDA94,0718C27374A975F7,6651832B8B6D2C7D,000000011BB16A45,43B287C819A3DA63,B039CA10697DFA40,DEE65BA8B5085E5D,948DD5AC03E6E1BF,03E045D2964CE833,93A3BE947985FDEF,3D6F68B7D06B3023,F66DC2BF5D7408BF,1F32115C6555986C,0000000166ED9260,6BEEFE8C833D8B0E,57F5C34297152C0A,C48C491AF08CDFEF,206DA94C0370608D,4EAA7E641E9FFD70,A13BF84DC21FB088,7A4CF7A2837C2868,48E94459D15BEEC3,E366ACD1C2340D2C,000000011D525557,4AB95DE05373F97E,8BDE6739297ACF99,F5DBBDFE502DA920,5AB55DEFA0E5FED8,D61E0405118105CC,A98E4B242F0CA8A4,8AA8A25C9248DAA1,EBABFB8074FAEB0F,6A2B2735DD60EC90,00000000C498F313,1FA18BEB8679C8D5,FF7D196312F05198,3401E5A88F84D7A0,A00FB8A4783B18A5,B5281CB52D5900D9,C1609DE6316DEEB1,7C955A1503A70994,96C49D61D6299716,696B81087C615030,00000000625BE06F,DF166CAB608AD3DB,5E9B89887134CC76,E3EB626CEF779642,A9D8FDEB3908392F,BAC27FDC738F6A6B,D07E3345FA6FD6D9,5DB11D80795BE953,ECF7E0FD11A337A8,EF537C4C5209A129,0000000155004D58,A164AD7106443C2A,4DCD7AF1116B73BD,6DD5899046558CD9,54BE9E557060DB58,EA0DFABC4FA2607F,FC4174F54EEA8282,0844FA6A299C738D,92E225A3DA7952FC,545382E11D539B4C,000000009C216B0D,61F0CBE7C91E356C,027645279B702F14,F32CC43C91353D42,0A13DD81E5CC2A6B,3EDCBA4F72C35A4C,A8F53C99B4C0BA6D,C622F293A8120CB9,CBA545F7E244D0AF,A1788FC1DEE7B253,0000000164787DBA,7C5BEA236F6EC2C3,DB18EDE01D4AD972,3A9B3197A1D59982,AF7D221FE5240DC6,A4DB19042CA03E31,A4062E4FE5EE91B0,BA95C149CE97BF17,DC9BD3A09CDD527F,2454A323198DCE1B,000000002A9CA361,AA0FFB8932237ABE,DAA54AECCA60B28E,A490E022147D975C,04CC812067663EAC,595E76FC582237DD,F69CF3E4A48DD105,565DFEA07D78D380,7DC7E805A7A22627,4313F6F0A5E13F83,000000020EC2F171,9E130C34155F6371,55AE351E3C05F9E1,5D1077C8522DF1DC,50E358AA322DE35F,CACD99CBF3C5E049,819A9D3B7DF722C1,6DFA327DD38F1E51,377EF3F10B6C4F86,66B10FAA8315F4D2,0000000104192584,6E04124EB458BDB4,003B91FD1D3A9ABB,76DCF9F881FA6838,717504FC593841FC,026063107042E4FD,39A0D9809DF681B2,A6A982E7F1E1669A,F5CE0E8A3D95B98E,AFAEB0F1AC72126A,00000001CCEC3C02,5F904FCCAFC629AB,C92FC02A0C95D4ED,8DA456FED216F54E,EFE2C3DBD2E182E2,AB6D18ECDDE60A95,670CEF45D5F9524C,A548606F1D2D41AA,A6EF4CF9F06049F7,A580283616B26723,0000000013A8BA03,8B2C87D19B1A955B,88FF59193DB46112,1698315C7168050E,63C0C8DC1054FA94,D7CE0EB6C4C76F23,AABDA684B9E61469,893EA9E48F095299,C05B3A776EE8F534,0D727C10FB8FCF95,00000001B7CF601E,BD4D1B31DED57D33,823256E05C3F5247,C5528DB4C1E78E2C,B1546383E26FD5CE,B2B8AEB76536DC02,C7CA81EC72F37D7C,EA25DB03FD4839C3,54A7D2568A70A11F,34E6086040DACF23,00000001C79FEBAD,8F4F553CBFB92174,0672B45D5CF22ADE,22697D81670B5DAD,FF89CF863C90F433,36D8E66381873FFE,5E4DA4C45A2F622A,360EF7820170C134,C713347341C0E306,C07B7BA2F27205E9,00000001F4A0CA05,2EF7D911F8BF0F8A,C7665AFC267A9AD0,EE5793F96DC762E3,D705C5E8136B253B,0733D59D437DA019,D5D444292EA651B3,DE23EAC4359014B1,CB4C82BD2C3BD046,078132A97E2392FB,00000001EBD51BC3,CC60F8004AE3D60E,CC682C0168C86F37,ADE04FFF03504FFA,F15992C072812B97,3BD35FE46DB4F969,144C3955617691B8,79D55B8F8D5E2060,1A96FA8B1E920638,3592BFACC5E2B764,0000000072069703,A27A6665AF4BD4D1,2B43D30274E2C070,89864AD2AC4E530B,E20A1FB47EEC0628,96937706280C156C,75DD80D6DCF37092,C4F36D8748012F28,37895FE0800AC21E,875BB4AD01C27446,000000011AE6AE0E,6F9390A4A1F72772,A8A24B0CEDD77E9D,0A3B0200BDDF1A76,5478FADEA21EE163,4C6408BF618E9E35,CF6E4D41EA0A246B,CE2B6349A36A0E93,CAD4BAE02716B563,7F5BC74336FD7C50,0000000041B3CB66,72C80A20481946E0,D0DFB477F386A632,6822A27207AE954C,71239A07F75C67E6,FF71170191D4493B,68475FA477247920,30305665C67355FC,00A7326D178C4BEC,B26A61F0342B6818,00000001E906DA7E,5FD8B203502CDD5E,F36C896B6FD43EE7,F2CC5E5A12D5A7C1,C1D97262164E0BBC,C06D6D65F766BC5A,D382EB5DAD89F71F,69C07E7F08464AF0,9F02B3D4705CF940,255027AA968C02CD,000000008860D440,362B41F488619357,63C041CB03EA2BD5,F1B19930629F4709,772B3C397D369F9F,C1F1F85EC7AA659D,9AE7F99ABFDAFB1F,33C58421FAA59251,6D487694A5C5249B,AB0C4FB49094EC9A,0000000252E66283,52DB0EAE9968B7E7,1C82F09022F754EE,33AF624C00BADEFA,C8F875256D54B304,BF7698D1232A4393,A578DC585803C23E,E2172201430EC309,3B5A46C765F763CF,D6997853512BDF11,000000014FFF28CD,880012DBC6C597DB,A69F9446F033300B,768053970EEF77F1,1E25AF3F51E7081F,4B872AD2520F7317,3BEAD342780FD964,2FC1797C789BAD6F,37F42F027588B72C,EDC15F381B392347,000000026154F212,C6082C58A6D3ED3B,5D147EBDCBE40B0D,C31EC82E3AC5770A,4B093889AEE009D3,8891958A8D55A64F,EAB5F60E5FE2E343,C089BFEC8E83FB80,B4C2E62CF77CEC42,4E63735536EC333D,0000000041CED785,5B839EC89CFD9865,9C6D3DADCBA34A39,476B53AA24C3844C,5068F3C9C455CAF5,B6FE584E47EFB2ED,2B0FFE91F3918F11,0F773C87A7A8B176,3570EA7A4767A148,1AEB42EE1E1C052E,00000001A2744F94,370038E1F92F77E6,4ABFF3E8D6B18926,D8029AB0CFF699C2,045128ED6D5BA4B3,56EABAC84E3F585F,67356DCE1972CCEC,6091F34F806E835D,EA9FD37E90EFF3C2,77624DAA350680FF,000000025789BFAA,3094B8590CEFDF0A,576CC9E907D5DF7C,7839EE99535F7227,ECED76039DD28018,3505EDBA7055C613,D190342315C08AE7,1A6D84CA49235A5B,7E16218B57B19968,821B78C8C806143A,00000002571A1193,206AA057A27D3DB2,CCD53F9DC973DEEF,72EBADC36EA21B92,20AEA158B1E027C2,BAAC221EB91AE303,56553C72418ADEC6,06A37ABEAF04CFD6,55D4A3A9C02EB08A,A4D8AC764DD0630F,000000021B131B08,252A2E46BBD2FE7A,71798157904A767F,95C91FA1B9F8B352,B8963918B7753630,BFEA2C32CFCF165A,CC9127B83E070E63,9BAFB98E121A6F74,B456ACC8FC2C7959,21CFC10D4E14E709,0000000213A75406,ACA8B18BBE87A86C,B4DB4373E8EA2A46,1294A11942D78E62,079E5318480A2976,4791899B7AB4E2A4,DC1A0C433B10CEFD,E0C1D93742E93BF5,39213468B6BB341B,F8776A9998465DF4,0000000130889E7E,14FA1F40110C7597,50A60539B264F6A3,DE2E26DFE20515FF,C9F9BC6FE81D6BEA,C0AD3B10138870D2,68E8DF0005067FB8,41BED0643F966E0B,15FD52102B68E023,EAB42A68575880A0,000000004FE5DC44,0FA617159FEC0A9E,4C3291B83046532B,CE293F104550CC9F,D25A1EFEE46248BE,DE3F642559574C57,4FCBFF2DA5E238B7,F5E55CAB8119882B,E29150ADB8BA21C4,85124CA84625E9CE,00000001B22677D0,CCF3245CAF88D583,187EABDE218648B4,5318B9C2060AEC5E,5B50F9014D972700,5F4104DEEB63881D,2B72EDD1014A265E,5BC080A7B761678B,9475FA7D27A9E842,C0AFFC98E633B898,00000000314BABA5,C835F45C02674977,A353ABEC47F66A9C,DCD2CB88864C2391,FC318BCEBAC6FDD9,215D30A20425656F,02899AC77EDA44F5,59486BD16C41A0A5,70DFBC40F9567F5C,2D02D96D4CE135EC,000000013DCA7244,AD229BEE18DD380D,79DA791794F53867,0ECD956E9B0A04AC,0923F1C813F05DB5,372B0178EA7C543B,4CF28D21F03BDBED,5B7E77176BED30D7,FCF880EEFA4E6230,C25240027BF1E862,000000016055E913,4A72094FD7B2FD9C,0EAABB3020A80675,B05031AFA84B0501,90763F560F01E9A7,0C045C3B8EBA9C5A,5D26BA922B84B790,2891E3D455C0FA73,3F9A277491577A82,48F1747A9DA61554,00000000D8E60538,C5EEFF17B1CA0310,81CC7F19DA0C5E1F,21CF2964B35BB8F5,11A401CEC5317909,0DA1F5072B73A059,49FEF5C431BD963A,444BC5E5124FDE32,1AF0EDE11ED4BE8F,8D8C7381020064EB,00000001F4D32CF1,CF9CC603727E3B1F,9867336AD39FA099,A4D1D98B422203E9,88090B36EACCC430,A7F8F69A0901CB3C,FF6A08E24B8B721D,2D1C073C933362BA,FEA58990A20E933C,0EC6D4B23A88B6FE,00000000237FE87B,ECC818FC95E02C1D,5E0D7B8B491D7049,E895F741D55FDDA2,ED5A77DD5B7E7DBA,412C50056B7774A8,B7FDA2ECAC5E98E0,DE23DA5AC7B2A862,71C3907EF50C8064,3A2398D176CC6C01,00000000738C7983,30B1FAB96EF3BA4C,FFAB75521B5387C0,D8ACC26DA6FED1AF,244125DCF9423354,B161AF1197695107,D0DA70FD35C8C173,D123DF47C4A4053A,CBE0D886D950B72A,7CF40DF9F1532004,00000002758C64C1,6459213C0FD19CBF,1AEE37BD53EDA059,37805BA269D28CF2,F3C41E9BB5CFDCE9,76323871CAD9F01E,68D7A584AAA1A70D,C924E7C25C8DD7B2,3349D9757D52F925,86617FD2FA56149F,0000000276CE68A1,5CD81A790330A8FE,13676D00B4417F4E,EF77154C24D6D89F,2C1599653761B6FD,7606B2B6FACB6016,ACF3929EB01638DC,426E387C38988B6E,E478132180C64065,5012674EFC6942D8,00000001895BC9EA,7CC4582204FCD035,CE0A6EEA2DF34010,ED5689036F70D67A,E05C33650EA91EE6,99E98EFACEDC5F6E,DAB8530A57A1B7EA,0D5823DF7323567F,C4D7E669FDDC1F1E,A90DEF5CD5AEB92A,00000000F10A6AE4,0E1D16DE763DADFC,4A8DC3500A3D6510,BAD19C6E5EE84507,C307EA9C9F767FBA,D10314CF1B3133D6,FDB2167D225F4D20,E16AB95C76E3EACD,ADFCE8EA7D42A70D,E50DA39150073ECC,000000008FA72A40,A35BFB5A23996923,9D05B6AE664F692F,074AD40B75E9BF0F,BA043C46730B9D7B,813D5CF4543676C5,D9D763DA3962B3FB,813191989C20C5F6,1D1C561E8612ED7A,221B7EE43BF1C3AC,000000012BB08DDA,5AC9CE8D88FB75C4,943F0A089BF33377,9D9C857ED30ADF52,D5CB7DA12FC7F9F6,EE27323D393B9700,618FE4860BB34DCB,37358A6C353D8A0C,E634FABE578495F6,320644544CFB6828,000000014E5EF53F,2026ACC5EE0F3849,AD0CC73FD08907A0,11AB3475CA40FB7F,E0A6F7C5C28F3B17,E52ACD32738BD229,08817B78392B9A10,9FC7BDA6A727AE4E,B6866AEB3985110B,03B91C108EF11FD3,00000000E6E6FF13,542301620F95D112,9037D533CB38B384,989FDEF6BE6FDA5F,4B57BEF34DACCB73,CEA5B198D3EE6194,BA45B8EB56DFAD55,405E14C6080DE8F6,9CE688F35BE57DCE,B7129A638FA8B640,00000002725B7B1F,C08EBFBEE1721139,C33CD604BA48BA59,FC3096F8796A788C,A32B9692B924B52D,1D009476E44D837B,ABCA63EB0414465D,5328CC14603E9F3B,4A2155559D59E075,923905D74BFBE19D,000000019E97B0A7,47CC9264E6BB9FE4,7A1940B70A31480F,8B6B94C51481966D,0765C2697CAF008E,6D145D8DEAD7AC6C,D0B68592F0474C5D,A3D78600866536AC,A18D90953283A111,F9939CAEED65233B,000000007202E755,7EE495DC83DDD2BB,662097AE8685FA92,3CE37856E82737E3,A74D4CF3487DA9E8,1D344CFA0037852C,06FFCA08FE707ADE,1CC0FFFE7063FAF8,AB94846B39F8EFFA,05305AF0B49A06E9,000000016836582B,572E3AC9BC405496,6EA205FCB221F8EA,B81BB2442F30C904,0D4A43DA6114104F,EFB0CEDFFD952648,46FDFB9798AF0299,A83CA7DB05156BAB,9FE3878358DE695A,34D28CD923DAAC87,000000016E719783,599A58E282FE5763,0FDE2F8285F8FA94,DE6FDE12A0B2EAB8,817036F5F8EC2A5F,9E67459744B14660,E5B1E1F412E0BF77,EEB8AD26E469F724,13CB93A82D7A8682,FDD62F3513D1F4A6,000000005E078BE1,99E42008BF04DF80,395599BF4AB07703,12991528B621244F,EEF94FA3496CE305,1501F1914509DBDF,C9F3FD34E0516E35,16D7A94B153DE04E,88FEEF1D4FD242BA,C20C6F8203015316,00000001F67DB1E5,23BA0AB8AF1F6A4B,6448330CB3736213,B64DA3512B604C8D,6BFCD301AF40A895,D33D16871C4B8208,4B365F70DB08559D,9B9E1D37DB31D176,28F3C4D7CF998DFB,DD836E279BB2A40F,000000019C921566,89E08BF770BECE00,CDE8D682C94006DC,294F9D5249BADA79,3E413CEC71029EE6,4D30F34A2F0EC94C,12D6033C847CA65A,3DD12EA6F56F2E61,B776CD8F2A046A01,4E1E6EBD89346C41,000000009F036085,7A6D32C5C7E4BFBA,1BDD501300B95471,095BBA3F6E658243,EF806A9DFB969D24,BE08845A51B3AA0C,18FCAC9FE2EDDAB7,395E6F3287F26020,A435166EC184E91D,98553CF834C82939,00000002021635BE,4C869C51E7B0C6D2,27A5C4C1849626C1,D8782A05D6BF3326,A65E617122469E78,2AC1B8AC545E8615,022A3FE20936D94B,5084B17777FCFC70,6116B66756B20461,7E4ED58B93B49DB1,0000000125FF360A,CFF92CAA46BF19B6,0132AC6721E98D04,037BD23FB7565009,DD850CA051C06B70,D1F99DED3EB8DF79,7AE93A4950499D26,DD3B585287754F08,F383A744E54A75E4,375BD2C681157856,00000000A5545BAE,EB518D0CDB1AE21D,7DCC400E108AC6D4,D87A640789EEED2B,4BCE5CEC56DEEFB1,99416A940D1BFACC,26E1DB71806B45F5,30B480A5ED4D005B,F48FF3DA1381C9EC,7ABC6D54E4516291,00000000BD7DB2C7,78B47BFFBBFF8A07,B457B22153FFD493,1934CAEDDCEDD5D8,DBA6AD97604A92AD,11432BEEE1FCD4D8,98832FA2BADEECB4,8F8C3302C2CD1AAB,EEAD223535F8995F,9EDB394EFA221C10,00000000D2B2DC42,5D8C3F94D49DF827,0DE4A466DBD3D7F4,A4DE5EF926AFEDF2,848AEB989878141C,FD21AF8E1B82729A,F9AA82751E5C6940,8DAAF5850B78C9F4,C92A1F4C1203F05F,1231509F01049091,000000012C57F656,C6E4B8DFD8A34FFA,9A6FF1D7708ABC11,E1FC0A9FBFE3FEA4,05E371317B67A04B,5E8BCA8422CF42A6,936B1E225002A681,44C8087A7E5C8BD9,AAD569335CA6714A,CFC8D8ED105BD8D2,00000000B605DE5E,EF1F222F60305152,F4F85C40A4962C70,B31600A396C6D748,78A136265E556DE0,16525FF96DC7E356,BC2277BCCB42A023,E0260439050D48D8,7F42A40DF1C9CC63,9DC0BC771E75CCF1,00000000F587BA63,2C55D52D5593060B,CEC9320B99FADEEF,FE80D9F8E7C7C661,1C61C0BDF72B0258,491A3D13116B4EDD,9D34ABFDC895EA94,7799CF9E0BB2DACC,4A37C11094BFD7DD,079908E368873D8B,0000000126ABB0CF,0F281E892DCAAE88,540D4939EDB28439,F0B18F94A453063A,C34F792B01CD087D,4449DCD74288DABF,3EE09AE1494EF721,0342A0DE84F20840,E2D03BA98B8E8725,2C83B4D70A7130D7,00000001BB74C403,9131B7F61E98287D,6453F2EF4AA09B0B,A141CD8242977DD2,ED02D8358799558E,2584A23B6BE1B58A,E17C1C270717D4EF,AB8185EC7155F63E,479CBE630274B1CA,4F48662AC0B8D61D,00000002142BBA5E,EBFC8273D3D5C11D,838B6E517A4CBF8E,143A768577E3D79B,1F315B08BD954D05,35C57FF6F73F3A36,EDE4EEACABAA0D6F,71BAF2E822C4D958,0CA63993F1436F4B,CCDEA169F9B4EECD,00000002396999EB,8165BB886C7FDC2E,D849DE010F1BEAFB,935DFFC2268F78F3,256A66B29EA8623E,4F026F71F4543BE3,FCF510B34E62BF29,87B093F0E6BD8E8D,4C007775BA9446FF,FF84961F3D9954A8,0000000194C55938,A84EECEC3DD9B038,AD2047D1E55B60C8,5C3FDAF2E3E16D8A,29C7784A79197E24,361AA294BB51D535,B7C790A319EA9E0F,6171E0328E614675,7203472C5C4B72B7,8ABA2720C6708135,00000001A548D9AA,DE6440E0B960BE2B,8DBEA76D77DD6F3C,D58306BCC4E22F0A,DB53D09183D5C553,EBDD18DAF07E38FB,44515BC27966E9A3,15C5A6F47C98F8D3,D35A1C2FC9AF4A28,9CB5F1EAA4CC2302,00000001F6D5BFB6,A8DCA414F769620F,218EA47C6602DCFC,9967188B73FC118A,694324F9B2432517,EA5B13CAF30127EF,768692217756D2D6,9E83E0CB4FB11B40,C11A4D352EF468EA,31925DD68F81FA2B,00000000865EB8E4,14508D1F289E4CE7,DBEAEDA69114C174,B7B67CE473223FA0,F5925DEDF8E287F1,5AE05C31877419C9,51029C7112262B92,CEF78DD5D36A96F9,A6801614BFE24B84,5399581456575315,000000016F85E271,DC0AA52ECF2B4A19,8D1BF66BC07AB4CA,F3602F2B7FED2A19,61DFE764A8741711,6E689E024A89F3D1,2CC90C1B4275BD72,DC2FF6EDD6A34E7C,B6A00CC7A817BE24,530293D148798D8B,00000000A506E88E,14D405DE3264DE8B,7BD2E5A23DA1439E,9C97B48DD3C8F902,D5C469E02580ABDA,59EA3C3DD1BEC017,5041D8356DEC53BD,469C1D249E80A376,D50392C2D5C7A61D,AA6B2DB9870B4E59,00000000B05C8CB7,6C02466DBD51EA9E,1104C22EE7C4FAD2,8E9B6F19146AD22C,47DFD5B1A1B60771,7D10D19E280D4C70,D4C2F46E1313967E,B734D411125A03C9,BA30B578A4855FFE,0CCDBAA6936783E0,0000000117C4E93F,06571C51F023B35D,3296BEED40264DEC,BAB6B092D6954A1F,484EEB35D70C03E8,DD270080AE0C9390,6A091A64E647D9F2,31218B00BAB0C923,AB8A7AC1D05FA413,F0DBE7F70D2FF326,0000000117671B59,8A71FB6189153376,2BADE700578204B1,37E0D7FC2B5ABD41,1BFAC91F4592D8E7,1165AA15FDB29EB2,7B9EB61477064B03,DBCCAFCA3E6D4901,62595601236E7F28,41931917639DF4F3,000000010A3126F4,FC33E033E9EB85DF,864F7B9AF48A828E,DAD10C92DF5B5EE4,61D8CD878508CF85,BDF9DA6CB4124FA5,38AE574E5B120479,99951A1439BCB279,21C463948C3E8C69,F09AA28FDECDE03A,0000000186171210,4556B87DED2CDC2E,78CFA7DD27A93C60,5C1D24AC471057CC,DF0F6240C44E9414,9FF37DCA7481D492,44682761F88E57C8,4A1272B7E4FACEE2,2014838A8364A360,F467A85FFED331C1,000000000C7A6E7C,FE08509F0433A51B,CE93C697B78F9906,08FCAC230DD0E3C3,5412BE228741CB8A,7D6E35A512BBCFE5,9E1DBB2F805497BA,F2AC87089856C42C,D6CD140A153C5C30,7D40B0BFA41C1ADA,000000023B1C0144,11C9EA230F65C205,493E2B2C72611950,FC669231941370B2,F0392CC82CFC52C7,87F70368DA66A829,83E1A74592F41C90,BE81DC409D742273,719EF45B91AEA389,9373B47A1B1C6F03,000000021D4781BF,D0E068AFF8C3AF23,E3FAC0143AD34BED,DDBEA63C9063B815,AE2568FE4A1437DF,8CE7D8BEB7A6D8B8,B80F3840EA148A80,8597F30D760AFE27,6780803919F8213E,DBBE4E97DE09DBC3,000000010EA6DE65,E88296B920F52F37,32A3E74D5A1807C5,44979D123FA4547E,0883D5657D0807F1,408BBEE3A8669A9B,1582ECC91BDBB69E,A4FCAB82BFFA525B,E4ED8A85E3A4F64D,AA0D7D5C4E1CBBEC,00000001219FBE86,E4DE4885AB4BC7B0,38FFED3F0DAA7644,54A4A35F171B9073,AAF19BDD513908B1,55EAB92CD29FFA03,3A163AAB656A0C98,674F714AFEF43547,733E6DD1468F8AAE,4AD359C78A9F18BA,000000014546D280,6B9E88F22F5D4875,FFEBFB22940B75EB,BCCDE29377EF84BE,A259086489F26054,2747423E2B8D1154,130363C1C3263927,249AB2DEB65FA5F1,572618E87C63E0BF,8908FF6764E8C973,000000011D124AB7,F1FAF85EC9060EBB,53DFC26D66F25D52,60A161A15A442A79,22C0148532B8A29E,0F69C0C6932AE0E1,00FFD4C53AAA8269,3A5BC6BFE0C058C9,8C0A5CB7AA74696B,4330D63A61796F72,000000006484316A,59CA3ECECB907227,C876459F81F95F3C,962FDAA1099B3262,73F7A0FB6541446A,C7396B256DD3A493,71207D38E5223D7E,FEEC463F979FA7A9,A15A3B878EE751B4,716EC23BF782A2A2,0000000082399DF2,946AF928C2404387,BF1E85E8AF4F4996,041CAF03D7710723,E21E9E0FF28B0FCC,0D2BBCFFAB11E95F,B5B13A9DF05029C2,56B9746F4F6EC233,569EE3C0E54FB347,2A380A4049CFEB89,00000001D36FBC07,9522D72CF9B75036,5223AF4F191A8166,7165202F7E606445,A75683128080279A,A51DC475BD9787C9,FC948693294E7D94,F94CE2F42F3E93AC,B044F106D357D738,BAE06542618C8FDD,0000000047BAD4F6,D66406E6D17CCB28,3E23308419F7D74A,91ECA4C829756197,54751DAC9F917596,419D457E9500C8E8,EE70E4263C849E5D,D2C9ECA414D9558B,7522847B7D47600D,E26CC8BBF35D14D8,0000000084100415,63C227FBA5EFB04B,A1B30C27CC3318CA,58A15A2069627BE1,A8139917EF2C37C3,C91237E496FA3C15,753E03E0438BFC9B,A741DB5978FB99CB,E82D156F351C75D2,48C2C48FB3F1420C,00000001C50F9C34,1AB812ED410DDBDD,9A11F5154BFA7F48,E9C2AB51D0BF56AC,A8CD4EF4EE61A2C9,55EADF45D3F04375,9E04223E1D29935B,886A22DEFBADA8BC,20016824524F2599,E339F619509046FC,0000000019EFDE4E,0C179C81E4CBF8C8,37A53CE3B8412767,34304324F58F4F51,A7A2DD8B8FAC8680,6F34EE5200CB7B7E,89A887ACF19DECBD,676AE0E9CD1AD98F,D0B423ED5258E1D9,EA984824D0AC1F15,00000001A0CE0A69,60BEC82C8C073244,CB260A8083615951,AF84E4755B4F2E8B,189A71E8F97C94E9,F3155012975DBC80,B2002328014172DC,1ED95F9235F6542D,6AD32B27ECC4FB03,335C5BE9FDF575A7,000000022826DA7B,39E33A25E61293E4,92D39BB46311E8E5,672A7B1181820FC6,35DA638FE6C5AFD6,41ED2D5D5397E754,67CDCA47657CB1F9,82C0CF401B45F5B9,260530A961DC5697,BE0E1EA0563A299C,00000002290B0C7E,C233962431F31C9B,074023BB486FB68F,E83302C0ED1D2281,613278663EAD95EE,297B3893E9A7B831,23BED21E0F5ECEAA,C054BAE5AB1F71A6,C93B81BB6675E5F3,65B8DF5A5769EF02,00000000F547F029,AD0C605B46CC3B9B,64CF0C015C8BAC00,3A644C30A12C407A,BE0A47E8C8C5A244,76035D1C2C97D2C2,742D7B37D77CC48D,2B0B04143A3341E2,5A0D11354B77B855,EBE54CB0158CC2B2,00000000B3F5C282,47339C26598B6128,48497AB0A2BD9674,2ED4EB7B08C6D077,D08159DED7F62066,D589B1499BBDB07A,3247460AAD45D558,069B8DBC1B82C6F8,31D2CD8EA278FC51,F0EF347999213D9E,000000018C331AAA,0EA4A66681D58D35,F22BDBCEDC7473C5,D17259ADE5568D48,9223BEB1AEB3293A,AA01F3F42F4EF655,C0A8CB413DC7F373,DF8C5C8D92CDB67E,802DF6C3926F6D5D,0A54BA5838971AB2,000000022A53F844,12EC42149DEE4C56,702D6CB578B7DFA9,23B66A9B01D21E5E,75492E84EF9EF2A8,37B723AA7722723E,524E8ABAC3EFBF2A,636AA82E542240DD,9250BDD2C0733326,F887A3563DA2DEC9,0000000055FC6D18,31183AD5E5CB3426,9237E8B5802F26E6,04D1262F28CF920F,5D22F25E13BDB85D,3A411EEDEABDD499,ADB70CC4BBB1D436,B40D4AB2F0E9C006,41D73DEA9DE1384D,7A845E9E1D83F941,000000015D5EBFA5,900D875D760B02C2,9B024DCA41455FB7,2B125FB5FFFE8DB9,50DA35D1F479A281,B82DBE35CA862799,7C5794F0C3F1AC52,36EFF48D36E1614C,25D0BF4513EC2936,C9E44EECD0A24EFA,0000000183ACD311,A98E8760C4B8BA8F,81247FF52310BC3C,AC3CCBE01D194CF0,7213D6730EDA2D4E,72E3BAA228ED2E41,04A7E29A90DF41D1,4F99BBB2E23EC1B6,DC78CC04A60B4339,0525AA1E39915948,00000001E4C8D448,871567C6AC07EABE,B6DD2FEFC0F804A8,28B0EB2C2ECD34B5,0FB8BD876AACC797,B9299DF4D162BFD5,8A4854E3BAA39563,B4579FB21A423DDB,5FF45B55639501AA,67D11187C976A10D,00000001CC095293,12E182753A4ED0AA,CD3D1C1096D6F324,0C8D97477D926112,F6E186E4475F5E88,4D44BBD2B0949571,038F38632CBDAD0C,364703DDED2FEE20,C3BD6D7A33585C55,69D0324D69B50A48,00000001AAD68869,E0C47F5B4DF959A7,EE235FB45A0526E5,5326BA144934FE60,E124C6BDFBD2217B,9484BDAD72773B7A,B1FA0FF7B0B65768,3E43B20F787582BC,EF6164A6D6B49A1B,55782B8A0AE3E3D2,0000000180123C78,74C8D12FA7176FD6,F0C86BAEA2BCD729,2433C6F2322C22AA,8E99BF1730775116,C5F9CA23DAECEB31,754FB1014624FA6F,53B7FD4CC1FD99D7,C8F9A63614221CC8,CA6453B5DCECA03B,000000007883DC24,D8B2F30B7599E25D,D66BBA76173CFC13,FDF1AAA7F6B0A710,301D3E4780D50E43,87508B942748812E,8D13D60D6983C0EE,24048FEFDB27DB63,94A71B9A2267C9DB,E7664437C732E9FD,00000001B3986E0E,BAE448AC87EEAF4B,597B52116C3F101B,CFFBCB41719ACA2E,C821006C50295245,764B6C26298BCE73,F05D27C22A0961F4,86752F76994F7EAC,CC3A43DB4908AD2D,B47086124B7546F1,000000013588FD61,F632BBDB9F370DD8,14C939EFD558EBCC,AFBF2B692490ADF8,59100B6F7DDD02B9,AAAB84E605774160,EB8A0C384B72954E,A2DD21A282773A63,3368827129C46656,7C02F3D619843E65,00000000AA28B793,50D936DD05CAAAFC,F5224A6CDAC86F12,40473E1F41767DB2,436FEDE5F501D46F,269F03B10D1D6A37,BE02B4942BA4D96F,8D02DC2A2872D089,9F0BAF20DD6418F7,9003931439CDDD36,00000000D2DABF98,73A2FD97E7B263FF,D890FEC685319DA0,EB5CD5C64C507285,F31650AB2F4C36AF,1076B93B649A27BB,6818B7769F45A851,313B1F669794EF3B,9A5EEAA1AAA953FC,0581B670D3FC0308,000000000E3DBD61,EC73FF1AEA0338BF,5E04DDC94E655613,CD235FDD0D8C0A34,EA6772076CEA8F49,4D492FA49BEF4775,1C01EAA59351DE1E,6658D128B5A1B340,0CCEC081AD2947BA,41A244D08EEF682E,000000017BACD86D,EE4D6BE08CCB8D30,ACBC1090ADBB02F0,7F9D0FC7CA98CD75,086A07C2F12AFA80,4ADB2D3F49164D7C,194CE4CCC45E3B85,3957AE6FDACC82A2,C7D75BE9D99498A5,3E26382E6A8565AE,00000002746ABA42,8669886B759E3D13,4F7330A3F9C054FE,B8C6373EA3759FCD,9E4A159A97421240,D377CCCBD21CF237,F0A204B79BF5E1AE,6ABEC02C1E6FF094,E2D05DA7F828DC1B,8569913D59F53AC2,000000000794532E,D083B05D3C6C671C,4DE070C610637AE1,25C81D8C62E6D7E3,E26766839C3F2650,965D02C653250822,43D19527334C05E0,2DB1F0C2EBF09484,43AFC8A8C60393C0,D60380E3FE0251C9,00000000671A981B,EBD934AB057EB225,23BF15A0FEB5CBB0,17DEBA07DCB1A201,CEA40805D8B9F477,E7EF98096656968D,543E4A4B5D394642,19540BCED76EB225,ED92B4794C60A9FA,13FDFE3317A9C35A,00000001F79C2486,E320B9BFE59966E9,EABB18CD10428F1E,A9693BADFD496603,16C41B4BB94894FA,5D6F380479089AE0,2AE053B4245E0B8D,7E2F1F946488B605,6D6C673532DE005A,02D91352052D2CC2,000000017F681BE2,8F16BDAC45B9F0D2,89AD70C72A70BD87,51EA6CD8AC5EDA70,C20E7D44C56658B9,499436AF28953E64,495942973BB14DA1,08940617024737B4,55437CA06E6CB7B9,24576E88D11CB610,0000000026809C13,E83A845A302E36DF,056560B1E8B9D644,A45F7F315F74B354,C5DA36F6E9B97570,93F801DBD37C9EC4,887C215768A2C5F6,C63E59AC47505530,92303B215386E625,B210A5AE1EE7C79B,00000001D5E31B30,372B15553A19F308,EC89B95557E61943,40352B1AAEC44C0B,03FF83427839CE09,6767519DD3D3CF15,6CF8CD4AADBF92DD,5D2DE66397243A83,C7F1409B5750BA4C,C43A5F01F5FB24EA,00000000426641E3,E0D1085A88EA9C45,1269EF392AA7A140,D2D572A3A6CEB92F,76A08B8FEFEC969E,7B1BA9265CDB57C2,C87CE8BDA0EC1EC4,34E03B1FBFCD16B4,0806454F4390D31D,A9B6CAFDD7446079,000000004DD4A16F,04928B7609F0C530,BCF5C853E20EE947,3DB1C92FE7662BBE,C8C3AB2384D7B876,DFA7BE2F342A7457,D3EA13EBC45A8ECA,CFB36036A90012A5,B6A45319985A015E,0537EC3A57624844,000000019BB3D292,F530FBBF7A3729C8,CF8C486CF9BA6572,92C1691173D2A008,36884B565112C297,2648B0D9E06122F5,ADFD843BBBE5A9E2,76D95665F17881F6,653B448BDD84DF36,AC851C1BB0D11810,00000001727041EC,58D23BCE8769E717,9E61C27072C91B3C,20BCFB9710626AB0,1A89E1D95F9F4D21,039F4ADED064C101,55ADE550C136C2B8,5E9282AC60E0AF1F,6A15CD01C8D8BBA6,7FFA64659ED861AB,000000018B7049FA,3BBF20071CF59F5E,251B42C0610AD5E5,35496922172052A8,EF67CBFF141A248B,BD1C2889AF81C9DF,0239BF02DA5EC4D8,71B0EEC628971049,E87E541FD42FB095,055135D803DCFC49,000000019F509E42,22A2D37F4BFFA09D,F85878DA730038E8,A4670CA9D6B9CA22,17BDA9D9FA141476,A54AA76C47C93F23,CE525EE974BE9DDA,15869929CFB384CF,638F631A58B47288,A3AEE2EAC435CCFC,00000001AF4848C6,73A044264D5BF93D,97E1139BE8741A6F,4C832A0939CFC2B7,3E2CD7CCDAD75132,5D4DC522F0430CF0,93EE96A00F60458E,BD2C0F5BB106EE01,4B46BF081783F156,DFF526E39C9BBE4C,00000002526036DD,3003D2629AB67A75,49A95472637D2149,A40D79602DBBAE6A,B20BB7393CAF6699,25B0184890BF334E,B23653E909BF47FF,BA11FBB5E8422392,EFC7D74C6B9FB982,AD068ABAB79DAB3E,00000001E3C3E5A9,352621A414C8BA45,DEB93376F5932B33,E47E5FA91DE1F521,8C261FB2B087C418,2EB107C9436A563C,1D31A9A6B27ABB89,77FF4DE4B36E88E5,3B2ABB00C0628421,C20249A93E67612D,0000000167428653,3482D56272081308,175D75C0252E3804,6FC3615E2D68FE56,EF065BA1D9993C01,E3F8A2F525F6C31B,B31D3FC58E94DAB2,8B44CF9F2F7120E5,74280F74148CA170,011F2226DEA26A54,0000000066EBF69C,560BFA2F0F056D6D,056AABFAAF42083B,855F28A45BC2A372,718E11C5B067BB1E,689EC51AE0611CC1,B65A7FE821678B47,84FA756D8026D3FB,10BD3F4EA8D6DA25,2616542A6D7F0C24,00000000089A952E,DD6CDA10B33F6B3D,509DD164299FC640,B518CCC30AF1C755,D7FD010C71E8DB4A,50A62C6E4E442D7C,022507B026F4BEC2,97F5F6F6A90E69FC,4F2A26BF3D7D61ED,6763772F07666F52,000000015DC0A7A2,7D8FDB9B22B3D058,9B8206E56F97BCF6,FA8A1315F25B2260,EA0B114816C0AFF7,277FFB9EE8FF3DF1,20A903B09FFB299E,CBAE7D71F6A0F6D8,735638E20984FA05,FB4EEA9B9F2357FC,0000000005A70B54,A1FD8F072533E9C6,F8701C82671BA125,7A65A24D85C7E2FF,500B5CF9D5EBA07F,D07DECAD3F0A73A8,3BC831CE42D7E003,AD389E01BD0E94EC,79584CE5502A41C0,23F193FD320FC0BB,00000000FBA6F0EA,5C9C65FFA2FE44DA,82363A87E972C5BD,C2FF2851ADF03D4B,311DD7D98AE6FFA0,C4084198BDC48803,0CBD2DBE27DCD2A9,5CD4ACF5F4979B32,E8FC53E51195B79F,1C3F1A35EF1ADD93,000000006567FE9C,1FE73F4698876F36,6E32876CC1D48984,1BB95D80F166918C,2614B1294E0F3BED,36D86650F700B1CC,7EE154BC798D05A4,178805A29B97E425,FAD98CE21C42A2DA,9236ED24709FBC01,00000001441FEF57,D8C584F2A72BF1BE,19B7DDCEBFF065CD,FF855450AC6CAC96,5436969E6D50605B,76E7BA59311771F0,C3B8E7540169A10E,51B1CE83A76A6C22,E806AB8B7489681E,B493DCC4A9CBED18,000000019C114439,1ADBFD2FDA9EE325,EB5BD9C29C430172,BA8BAF28961A0E12,92F6E10CFF25C80A,F56DB367B7148A01,637CE08537AFE7B8,2FEB8E537E348670,63733B572D36ADC0,6B4F7DBE648AA1CF,000000011222321D,2CE545E02CB2292C,C73B2D627C509B31,89855235A29CDC67,48517153AA4E6C08,9BBE61A8BAB6EBAC,C6C599EBE199A76D,CC0EAD8AD5A57190,1C9EFF71A2DB2364,5740FE4F33F7617F,000000008F4A6795,B667D416DEF0D3FA,1414FAB9492CFBFD,08E9E61379A29787,0A9F4B6EBBD77DD6,3A3400027F76E1CA,F742DEED30B424D4,24E19101BBD5D870,4E4A4771E287F22A,C25BFDE12015EA43,00000001E13D352F,C15C765BD335BF05,D8B930AF2504D510,BF7831AD110FEECB,C0A4C1B4309BA644,11C3A0207782714B,85637663A34308BD,04C2550221D923AD,2FAF061A21800137,07F22056DFE9AFC3,000000001D3A20FE,75082981A3F731BA,C8F98D5AD56B7C8A,CE1BE68A2F2F15AD,341A439D0DFFCEE5,8161A6301ADF0291,1F8AA0C4EDA91E3A,6E75EF8A12D815AB,82FC9B4570042F2C,BFD4A2553AB5F3E6,0000000267E40BF3,B37FB459C517DD62,F718F54FB40294AA,878456FF6117FC43,C3C552B9FAD4462C,A5AA9995EABD00D5,339F616F159748FE,5D3B7E137DDB5410,70B0B13FE147132C,2DE4CA0A5F51B517,00000001B3BB408F,732A3ABDD61AE732,9348990A76BD3F40,573C305885271101,E18947A8AD00CDF2,4DB33F03D0396792,879B16166B1DE1D4,9C4550498F33BBC2,0688447815A891E9,2A0EE302641D06E5,000000020792DB95,2828D0061D91CB2F,BA09C76389F635EA,9714ABABB4BB1334,76293B6766841BD6,FBE26EF889659DAB,3ED8BB7EE9B77516,1434EE31C8E02CD9,5CD0A6B91CD9887C,5AFD84682A92AE0F,000000026F213302,3862CEA1FAA51C9A,353C6DAEAA7746F3,012025697E9D0994,9BE3C7CA109DB3CA,2914FC22C5F85437,BE2368181B7C34DE,D19EC04FC38FF449,6534B8FE36593A88,0BE31F6F49923D42,0000000116FD0E59,14DCC93D87075053,67898A04044B771B,C6FC6B8494231F6C,0740D4171251F0D6,72CCC96918FE8401,3D19104452C00E3B,C5DEE056B279462B,29C76E7B51E08311,4F7BB8F118738D70,0000000124FE4132,ECC09015C9830EDE,49B440B6C2A70771,CDDEFD246415C4A1,CA4F6E3F983C839E,17BF579275B18FD0,9F94C826B1C705C7,DE504CF640024517,ED65B543D3D7AF78,FC675830BCC766A1,000000016E9B1C56,572BF31A781448E0,7944605D2BB66337,E7455E3AAC44FBDE,EE435FCC9A736E4E,E15CFDE98B052991,05CDDB01275CF7D4,326DF7E1305084C3,41E697FDFA73F90C,AD5C9FD3E596B295,000000001332713E,54FAB63696E87480,23C141BDECD011D7,66A670B0033E682A,369EE22BB4D81BCC,84892299FCF4D52C,0B3E8CDC2344C1AC,A24A7C7E5DD8A699,9282C37950394C68,DB014AD88057AD03,0000000011621BB7,A27FA46B3593B25F,0D1DAF7497DE3154,2AB6F6F6BCB4F645,CEC8AD6C83367D08,F778CDF2EE054DA3,064DB7A96ED1AD04,6663DC5967826FE4,B9C70496D8E4E1BA,D7C04921CB55E1B3,00000001B2129DCE,E843223970987E26,05209156D99C872E,A29C59ADFA572328,F28F4E1ABC262E70,B5D5C2EADBEAF9FE,A16B1CD52B805695,D1111B612FF9CAE2,28B03DB2725EDE18,B730954D2F8D05AA,00000001A9B3123F,9846CB896A549115,7F23D2AEC3651C08,C9E99D7B90D939C8,228A55A93926FD31,A56DF8458EE8DA88,684B350618C8D23F,7894A5F1CFDB3C2B,507CFC29C7C36A51,3C556819C864193A,0000000124149842,B41A76D799E54829,025BDCA7130BE6D0,87F1F4AE6C69B5A5,28A3FAB8932C3324,B4932ECFABBB2AFD,A6A4465F880452D2,674FE91755818589,5BD78CDA5CCB960D,C78316D8C56A62B9,00000001CAD2B9D2,C7D16F765D73F809,CE527C5C5FCB359A,52CAD1060F4F9DBC,77A1C7B282C2E74A,D2ED820C684141C0,89448FE2A1834EB3,581B0968C0498356,528AE013EDE6954B,854C4EE52758AD07,000000011261EC37,F8715DB6888AF705,03324FF4D305B828,49E98E5291FE9DCD,E56D001ADA4C067A,A78A0C91DB88D952,F20D1EC189DD76E5,47F0CD83B49494CE,67590B0D00AA7CD9,AA55F63A78E7B9EB,000000004E2BE885,A1D8E93DFD78D66A,1E1CFE08BE17E5DB,F1713CC4D1BF3322,161B4543C93AB61D,973FB271A8914727,EA376AF4ACCF64BF,F7069EA156608D58,C8C1AA1DA1AC79C5,7861585903681AE5,00000000C81C00B6,487646A519FDF846,8CAE704F7A5E2590,F2DABBD48A736BFC,A027066BD3B684AD,143BCEB406EF92C9,1C7688AE670DAAAB,1C16E2D2D730BE46,D41C183A9FFAB7EC,64CAB57F409ED64D,0000000176282D90,37DFA00DFC0981BE,0B50CB08907E3E90,AEC91BCBEB673B56,DDECB6C3D79D26A6,711D7CACDB151D93,FA42C48B62964FAD,79AD6709517416D3,AED7B0823D88F633,EC1C2149A9BF3D1E,000000007503DA49,58060733E85FF12E,08B27B0578015EEB,B5ACBE6D35EF27EF,0616B196E4D601AB,34827D6C4D1E60FF,B1B53D7971D9EC9E,4E291F092882E3A6,BC6B4100659904D6,C1BA8B61DF7B2D44,0000000058E3E5E9,123D9846997CBF2E,B6E75C6E3E64E9E2,711B52484DBDC681,326AD9DD817F3709,2F70018A09CFEAE9,A2F41AE8302DCE37,9918F805FFE97C7A,E7B0883D177A25B1,4108645F45F6344F,00000000D013CE7F,F0DEC27E9458F4DE,A5ED3984B7EB9E60,298E16ACFDE105A4,196509EF6F53F0DB,15D2ADC0A99256F7,4A7EF9986BDF5EE7,A1B19B411BCB67CE,E3B633D1D9B8E883,48FC7BC97258B41A,00000000C658CD53,475C5598F1FAB511,66B6641A193491B9,F39A2D543D549165,A4E2A8A791A56E62,B6F89B0B0EC51A9A,F28222E548E6E068,2D6DB9624D2BFFA5,8564B94D7D9B31A0,64F65BF5D6B0CA0C,0000000117954B9D,EF03D0DF3DFD0D8D,736DFF3ABCD731BC,358EF631FECB5660,DDCD415093DDE633,342D3A0ECA48F1B1,A210C5AF1D176D70,5DA6A4B176D0859A,F27CFDC185B0C976,B2215BE63BB1F305,00000000BEDB140D,8356D5B542AEF987,2655B781D7820E30,910CE11259333ABD,011F9DF48CA14710,9ACC09B75B201762,DABC8937AE23453A,89725FA98658C6AE,160CDCACEF3DF59F,930CE596A3ABC075,00000002087B40EF,2F294F1BC43EBBF2,C6B00271BD44D4DC,B43C5F976B6A2041,4F6EB187D3507D9E,C9D27D65AA28AE07,84907BF775E0EB96,0CDA501A086D5CB4,2DF9867AE27418AE,C307877F03098C27,0000000018BF3C77,FE5F9FD4278808A0,1F4952D87FF883DA,4B151320F366B39E,2E22C05CE7B37992,84DFB31053EEE2C0,8159F43E32444D28,9B3F50141D033EA0,9603C407E46B4F40,07C9FDDC18D42A1B,000000002BCA59C3,DB8C94D93D1DBECC,66881212C8A7ACB7,4E67E0681AC4BE30,C5E8D0EA32632771,CBF833064388C12C,F098D3B7D4730656,52E14D8CC12B7CAA,33A2AF9E85E2151C,FB75436E3150A3D5,0000000212349C48,089B58EA0C7CF100,8CA32C57AA54B8AA,8CD2ECD07BF913AE,303E8C229F630F77,6605D3E2CDFEE2DC,DC03FC051FB2AF9B,D65A1E2BBA34F511,990D69D0686E3EE6,810A64E36AFBD940,000000008DD2909B,F68B06A817B747D3,A20518A6D99B327D,704B8B5D5A069F6C,D2BE5F54797BBE30,EB26FE6C222C7239,EDFED0F5FAFEBDAE,F4FE1DCD0E972430,DED9EA55CEE6EF47,9D535F70CCA5C578,00000001BD37538E,129B344DA0760818,8C807249B96BFE74,6D6A62230177835C,573BAEE6B3C75A27,980AF2ED85BD21B1,634EF73759FB36B0,180C6FA2846B36C9,81B3A9F9BE609D95,6F6D99C69D8A517E,0000000040696A3D,D7B5F680E9678366,7074582E77B72550,03C99AC42E319B5E,1B2EB4AA0C076021,938F42F13393471C,B160D26BE8451CCF,284822F346252F66,2BF06BC811C169DC,3F4D93D9AC1B4C23,00000000825A21CF,0C855CB511AE723A,82E25D516F159161,663CC0ECAF6347A2,E98006EAFCEEBB66,A082EABD246E28B4,F7C46B96F3FD809B,0C76D5AE1F8039AD,BDF00FDD8C60111F,83E72C893390931E,00000000845B6EC9,4B5496A383721437,1A332B4C14EA7837,1253EB0C86CF7804,D474478CC13FB99D,29DC7CD22BD74A79,C8DC2F1853116783,589CB7A6426217EE,AF44DDA05767F407,4D55CFB4CE55516E,00000001E6B63724,8E2357ECDEE119D1,64E4F4E496A28450,46A8476B29858476,0405477EB07722FA,B4AA9386A92834F6,B48CC43A9623096D,661880A1DF85802B,F385A01F1198E5CA,73B54C0330D1F23C,00000000FBF011A2,D928C82A843FB145,9697E9E9AF560EF9,B291CBDFDE78AEA2,C0C7CC8F4FCEC986,05E4AE55C0068F41,822EE27CF3B3B474,679CD37251E1D082,CA3A18258DBFB185,A6D7D78892FF4B93,0000000101613E08,52D92331F3270187,087970DCA85E8FC7,D5EDC46B6B3F60F5,D3FF0E7EF3575353,7BC99C1BD8A32BCE,4BDE4433278945F5,E9D538E076DB7FA0,33EEDB8C65401C90,8ECEE9CDE91E4959,00000000A4704759,4C512A748993EE56,77E9B643ADCB791C,A5D3F496182B0B4F,3D6A34A9BA438F44,8C61AE314DB8CDFE,15B01ECDE4A1DEF2,4AD9293DBEDC805B,5E6589F265A3DA87,D532D85BDDB5291D,0000000079AB10FD,5DC935E4D9A53179,E4F2A6740C0C61D5,1F31132B7356F2AE,5A0D38E9D61381BA,99E397A637DE2949,C4C68224830A2A61,8C282E65C9C27392,3A1F82204FCDD71B,7275053E2F7FABC5,000000026213E41C,2466487E67EB8319,261258B9A59B6B37,DF0FE7D1A969653C,6CC9F88B8A44C75F,41C5F32CCE74C085,637D8206701749FA,1B61B19AD3B2F8ED,7DF1E6EDB6AE0A42,D7E96AD035EC6F99,00000001A894F905,2DE961265F014D9E,518F746464E67915,BA8144CFC5CB7442,AEFD70DC72D0B37E,4E783AA7CDAF6145,9979567926C779E4,7AFF2487150B2B87,C5E44194A294FA3D,0CFDE2FFE2E50D30,0000000064C932DB,1F1AE3EF2EDDC210,4F7120C2CF17F66B,798737415123A248,EC3664E3C833658A,2F205AE890A74E6B,E12FFE7D424B201E,82E987BFE64B6E79,F8FC484D6FB97719,51BA342B650F7131,000000020C0982B5,DED868D7C678B5AA,37BEF0926CB8785C,3D340DBB78A3AB11,1540486A932FFECB,3DEAE08989C14C02,75D0A147B9172284,C06F7DF0FF2272C1,BE15529B82B3956A,84DF6216A3E7F670,00000001B8EE3B1F,3D8C5825A9E44573,63201FCD70C5C9DC,DC81FD30F49461FC,39C5EC0BB7BE403E,ADA98C31537302E9,A1F91042793D3FA6,38387D55ECF1C762,7152FC855CA271E2,69DC1E90D0CDF22F,00000002135BDFE4,E6EAE166589F6EA2,82CCB345B1EF3FCB,D8DD0877A16D9E1C,E3CDD92A75E652FD,EFA5096D395F76EE,4C03A4498D11CCCD,0282BA3B9C6610BB,D2937BA9FC883F06,CC68A7E3163E661A,00000001E304B5ED,B2BF906760F9F0D0,6FFD0F7D52538743,5E93FF1F75B43E16,FCA8C1D294175B90,550298708B17B491,6DC613D664F3C45A,7FC362ABAE6027DB,B3CBE8C2BF43C230,4DEB14FAFC33D51F,000000007B42003A,5CA35E3E1C2B4CA1,C0CF5D7400B37329,0C0A96564054CFBD,876B4B33DCCC6E51,AE4EB8920036A7AC,A9EB4C082A4FECE6,B3266EB05FCCEB55,6E3EE64B61001182,5BDDE21F3BD1290D,00000000CD773B47,B7044181EE854063,36DC27FA9FC877F2,999BE754538673AE,671CDAE230ABF44D,8871E6088E3B3147,6480DF57AAE891EB,1E47A92308F12661,D6E43EC93BF84F26,EE7265F922236684,000000006C52CEC8,2B06D85B9B33DDE8,D06EF5122CF8DDA1,61355876740991B1,FFE26C8395745979,E5959F122751AA9F,EFE291F04DEAC188,7024947BD8AB5E23,01BE9AA93241EBDB,DD51816EE68C4796,00000000B6F408D8,B7FFA139C5AAB074,7DE88D3954BA64D1,25463BDCFF03870E,3555D1A66F0969C5,8598D3FE7580E7FD,38C61803EF932B68,76179196293A29E0,597CD5C4A00B2E45,DC70A70613F3FD1F,0000000018B699CE,6941CAC0692E61C0,830D1181BEE1EACF,E72616A9BA21989A,C141F0F3D48CED54,0A9F9D85E40AAB38,A6F5D4A8A267BD39,29657CD8A10812B6,CF44FF3036E55AC5,88BAE75814454AD1,00000000473F4EB6,8BBA0A601B6DFB73,C21DD19228E21593,7B7696BBC1D80BFF,38BD8327FE26521D,4CB6D1CFE435D7C6,0807B0AC915B23FB,9235EDA97A0C60CC,01EB501CDCD3E75F,9711B1442B415906,000000023E9B8162,F4FC41EF248FA7E7,84E5F6398FCE8B09,7B40320A5F798134,EFF17F03ADCC2777,1CB2DF52B0CC2C01,D48B25FD8CA38219,06842831019C588C,2E924DCEDDB2D7B2,18371F140D56D026,00000000C6867068,20E1A7B1F2DEC88D,6B77F66933E8EFFD,DC645577973B5A34,92C168399DB7FB01,7E62C7490206D172,262C6A21944152BD,CE8100D7D71E3CBF,BDFD5619EB2FDF0E,87CB2D4793678EAB,0000000189DC4285,D25CB768641705A5,B4274A92217E5F21,9D2F1227B0A7D2B9,3A846D283AB32576,1F53617987067D9E,53A495B9A1A0EEBE,5A885AC4A293D7A5,34639C4D8FFCA73F,D46CD4B4CBBD14EC,00000001D9E64BDF,32AD2939D79D03B3,138F153FCAD57087,54584A44EA766495,6DD6221E7E98A2F6,5916F92BBD7AC13D,E20957DF9135E6C9,02D871BC548E956A,69CC08BAD9813A68,C1333040061DAC2C,00000001E6959AC9,19BD53E7B08C13FA,9FF566888FB81505,61376FB2F01602FF,0E65D0B489A39EFB,DF66659F88B03298,09C5CE49A6756D2B,03D48B7EC837BA82,D012AE69277C6821,60A28F8ED0B2E4F8,0000000107CBFC8D,487EF5406259DBA9,B31B20DCC06513D1,A04BBB5E5F499687,7BB69DDD4B96AC38,204346565E8F1C4C,F908990140DDE462,E94345E48B5E9EE5,B44EEB11F8EEBCC3,B89684A7C1579ED8,00000002570146CC,45889F6667B3B123,E1E3AD04EAF3AA80,22BC40CE68CC0EB1,A67D2B3AE250045E,AB947679F50AB1A9,78FDE1DE111E3EB6,13419A7EF2A15AFB,E2E9924CFBD55929,519FBB5D63E7A721,0000000026CDFF7C,A443EC67FD8751AB,2C9C354D88AA0C5A,66C38F3308B9B9E3,52B33CEBA6B88D88,D6CDD4B438983AED,28E91331D087E230,160075F9C9A34525,EAE9EB8C58E81D3D,DF45761E2B7E4B7A,000000026BF92C84,321AB5C9A517F586,538A8750E7BAEBE0,9C78530D99BD69F5,43AD1B769294F21F,4446D4338A4A7D85,8A89C5C4FF086B67,FC400A7E47B43FC6,E42C73868E95CF0B,08BC651A1AC509FE,00000001B0105D49,A0E6B1CDC491ADA3,76321F291C6028D2,65D68EC97FBEB62F,F6A33D1D73860EA0,A5C8DF11C3057EFB,CD25D03E45D1B052,8BCBB8D72DAFB69A,131AE5CB406EF7B7,4ECEC14EC805639E,0000000195CF00FA,A0578BCD971C4930,9A3F0137EE00BA84,58E1E7089277B2A3,1A261B11227B0521,12D37D146F62B435,7BF2332097468B9E,2551DF570441B1E8,07FD85ABE16EAEDF,815DF1FCFDA023FC,0000000237F657E9,71936F914EF12122,2BDB483767CE004D,B063DAAC9A0247C8,ED89F4B9C61B132C,19282D90BB5F7380,8DA4EE9090B00D44,8B895AFF3B8EC2FC,26D644B7F720C989,76D19AD964EC27F1,000000007F430D08,E9E8B798DB93E7C1,FC2E0C5EC202E39E,BE47DD55A52D41A6,4F11A00FD37C2916,238D7ADF8A37D87A,2DCB500DDB88B8A7,367AB5B1F342B8FD,2F7C11990852ADA4,7539DE50731A5770,00000002535B3399,6EA1F8EE9F7A5BD3,4D68BF9D66DCAE68,71BB162B7680EEE0,F0E26DB40DE31010,DB5FDC236916671C,F3E82FAF403F660B,67CDBE35DF27A0AA,DFB8C111E1FB2774,59E46115F23502D7,0000000170F9C758,CEA49D555716A161,0811CDF802E87229,C383B62CA4DCC502,A72927610267518A,24800D9A0DD19982,4356AFEB832354C8,267AC914B4FF9643,581A381566AAFB94,D4057D37ABD9FA72,00000000DEE06660,B7102A281E57777B,235C49695F92D6A3,DCFECF6C537CBD48,887D25DDED7FAA71,BAB36F56B065EACA,09E00B65BE30DC9D,C78CC4879E1C97B6,EADA9E46564F79ED,72B31BF6943DDC61,000000004925B13C,8F90B06C2AF6997B,6EC9F7D76684BE5C,6F8606FF2931C738,095ABC7F8B87F802,D8E84BFE7114C5CD,EDD0C44E8DFC4498,936AACB19AE84984,3D5ADB494356170B,F3D3B2B5018C7EFC,00000001A73B9D42,C88C0AC4483B2434,D4F9EEA19471C81F,01D53827AFA02466,0EA8D5B574E5BFDB,94713CECF644243E,D932B9C681F5B932,D7E7970B50D78984,65243128B8B1A616,308B004B41199FCA,00000000CD9405F1,9CCF58D66A7CE6F7,A007E12A8B4F1F7D,278CC71CC4F4BB0A,889DB7E73DB82F43,F7ACBB2C0AE90582,DFBD347697797E59,E8ADEAA3B0124620,BD08F0AC00F09005,E80971CC94C33863,00000000808D411D,50EF95900F90F86D,1F68AEB1408B9230,4F626D6031C52722,2DEC6EE9D8C8130E,71A0DEEBE9840CE9,4B405D4E76315B34,3B97E99D94123F59,21327F79DF016447,34C9C3D560B190A9,0000000034AAF473,C5DF27C166707B96,750651F7A2722F50,E7D29666B73D65A9,35BDDF08B38D8092,62C98F4BF7766A2A,AF22BB276FCA9B58,B6A5BBE4914BFAC6,87D93E124964D246,3D00B53C12D2B1B5,00000000096C3D0E,0C14A5DE26737F8A,3018BEACF1BCBFB9,67AF69593BD6EA46,714E22D4FCD40E08,8BCCA5E36C930CE5,DB2183AEC5F0B4B1,A6489E08F525B1BF,EBA3D9B6CF84759D,F98378343D51E385,000000003F8E37D5,673DC5AA69B64187,27A94EBA94FE9474,1759D547EFCB50E0,AF5BDB60D5087B38,E99F8D67B3D2DC17,471C859764F2FD25,79703C108747ECB7,D12035797DE7E520,AD7FDCD254FD678B,0000000102B742C7,A5250F09F5F65081,6F0B14CD9B93BDEB,EC40E6221A8A8B67,6B7A1EE938865042,CD3EA4218AFB8E89,DB69563FCE62A6FD,57F35C79823C4360,B7CA79D9C5240632,85EEE486F2921D50,000000008C669F06,727A291D87421666,8B967487EA00212B,D87A09CED71761AC,7BDFB0FC9F91288D,F282BBC8B1DA4372,A8D475825CC89616,DB70AC2B55DA2CED,273F9CF1C501AB64,92E3EBF6200CC137,00000000E9A8356E,408F86A33010B6AD,526C87059E115217,BC6C1CCC65F53327,591DDBB6F3982AB6,3FD2100E3CFA08CE,63E3197626A0099C,F0FC7C5D0B847112,A1D1189935B02EC0,FA249337544C3406,000000010514A2CA,75BF7A009FD4BBA6,6F2E5F6222E9BC55,DCD2B0874386377A,E240466147776EA6,77018634F5031FDE,8C9E8255A0566BDD,A05B416C731D170E,75BDFEDDF229473D,5B53AA5F8145C010,00000001E6CA5FD9,126C96472F613937,F4DC70D16989C2DB,BA621FFE1D494940,47CF648CE442880D,498261BAE3A55A5A,41DDDFAE566877F6,E1B8A09A34E4012C,CCF941044AF7A675,8273D5B6C67F8017,00000000E5DF9CE2,C82A1FB26E539D19,2D419A56C85F9B86,B63D09AE1A2E58F7,46597C580E9067A1,F9404C4ED9FAF769,32E19616E9773016,D4E5F2B520A6815E,D7EBFD1FB729FBD6,D9306D9ADBBEC9C0,0000000090CD15CE,5A59248217B3F6D0,980D9BE8E9BBDEC2,FC0EC6AEF627E52C,618728087C71FCA0,64D2D801B76C0D68,242FC635A6BA0E77,E5D7C596F4186903,575E5CA37DA64D57,60247F739C83F095,000000026A848CC7,A10416B83D772C2A,E1D256E9FF21254C,9DD9795FF644C455,F38CB7EB19972E02,33AC3795B8ADF027,F3B03F101C37B78D,9DD097D51495E3D1,3AC62F40B287BB0A,B6B4D3FEE17AA602,0000000181BA5458,D4F701E3D22E6BD6,266C391EC7057283,62C99B956F61EE5A,D39912FF20C1496D,A6E5D69ECE9A56BB,7B2704F0890874F5,77CA46B5B539CB97,FF9D01B1C758EE58,49A8B9CC57C84974,000000009F87ECE5,73F2AF97073B428C,3BE50DC43917FF6D,258C0D8345353D2B,8726398773742D1E,8A7C3FB3158FAF72,06AFE96214E1B76F,2E17E1B91C5D5E2C,E65CD738AE0638B5,71F7FF865345954D,0000000071ADACB4,D715CB1059919207,803EB04DCF2053FE,13CD860BEC6256A0,C5A493E98E398F25,1794535510752190,8AE8A8E357EB95A4,3903BE90F96CBFDA,BFFB4FC84742C87E,B2A6CE42D6C51DEE,000000024415D71E,3AAE140750E2BCAF,97257C5BB29E3B77,1B8B20E8F8783254,73926C00E378AA8A,128E73F7A17DEE6A,B0F04B5C1C54593D,9525984A53650DF9,C2911133ABF00C3C,904B21BD9D319468,000000023E3F2BD2,45A49D605FCE3FE6,FB7A1C36BE9C146D,844197FD959E293D,524D1A1F61AFC8E5,AC7792918487AFF2,ABE041B889B83D41,36DAFFB1E905A8A7,9C9C2A6F6B3ADCF8,44770A36AB797A5E,00000000362A5495,ECAB8E7FA80880FB,3825AE388DB751E9,287A5F78DB4C852D,7E9B66C39FF4CC40,6A7DA62D44DDBC10,E59CF4D7972BC10F,AAA1E5E6C8E8F06F,0D6418B69D9EF3F5,27005F23F83CE173,0000000157E88C47,8D67722B46A2A015,8041974C53251F01,E3D37C209C9640B5,6F7380DE761077F1,87F5B718CAB1DB91,30DE1902B0F15046,5B75FD8F65FBC421,6589BE92BE8FD1E9,C8F584A9C489F635,000000018D624DE3,922A9888A41ED24B,F015D5373BAAE9A7,F590A98BF501D5DA,72BF68F4810322B1,57EBADF42474894E,EECC489215B04C92,5DD2562F6D77D390,A73DD007BC15CA4E,62BF8E57EAB54C8A,000000026D8E573F,DA5347727B8D20C1,934B90064EF03E99,BCE80830C8BBE880,1A2210324259F7B5,4082480A33B38BDE,4892E32EA3FBBE47,96D698FCD34A604B,C1D9B8F38B6DF73D,61A075CE5B446E6C,00000000E0CE8078,A621831A8D447AD1,0B2DAF2FDC6B99F8,CB4A857582D6EB65,7BA9A4B1FE8A2E5C,5334D8D44EC31DF9,02BBA3CF5DD47F74,98B614411A34481D,ADB99AEADD016E8E,B319B140E21E158B,00000001EF7975F9,16A2A2598F7F6BDE,BD61F97A960ADC2F,49A2FD1C501748EC,361DB2CC28B01C29,DC33B43FE0CE0DB0,6F61FA081089C8DF,223CE6B4ED08A9AD,6565B2703E786EB2,65CCDD59B9807345,0000000264D25F5C,F1686AAE8225006D,D18F4FF7715A3FD2,5737205E56EA0A49,D7A30A5B3C4DD47B,3E93C168A23F505E,59C53531724BBDE0,5136D48AE93F85B3,A9DE596BE0F7C808,FA327484BC7537D6,00000000E6EFEEB5,CAC04D8D0319DF37,2724738634EB95F4,63427ED628CB44EC,95C289070BC6895F,54DDBD46BF497943,C70D3DC80F689023,044D2EFFDA65F0DA,DC16694D5D2FC4E1,B562035E8E940998,00000001CF4E143E,624BFE09154FC148,606D32D2ADE227A3,38F5DF21DB9BA910,C30B5EC389F181EA,7EE85B42C13A7826,83B7F08532B05949,5A207FCEAD34E5A5,5AE8AC7C26870BEC,37AA2D666D16856C,00000000CB4A7C22,4AE08C4EDA72FBC8,9E876B2BB45A2516,5485E19DAC062055,D99BDEA4C6CD7109,0F68EAF874B4D447,63ECA5F163C99173,18C6A938647C02B5,7B47F3F53A9506A3,C1606BEF0763E15C,000000004E183198,E4028ACCBBA4D6FD,4B01737E222BA213,EA97421D6DDC51A2,75F646671D49CFE0,0A2D2AA1F4BDE5B6,35F3E39817DA810F,946057366AA47178,2F229725509F5508,D29F8CE460DEE13C,000000020FE0AB0C,BD59043876869A6D,5D16879AB26265F9,78AE5F37917A5831,2A46D34BB2179D78,98BF89F46C38A722,13B5907C0BEE7467,592EEF41CEE59CB1,C691F35507081F2B,660E2C13CA24689B,00000000B275E320,EBDFE12C19F80D8F,C99457D2B1F1A53A,307ED8A3D9F0ACA9,BBBDFE18EFCACE2C,F1C62B3B660EBFEC,136B40BFF28B849D,787B8BBDC9DC7BFB,E2DCE3E634255BE9,6BAEC579A30AAC16,00000000B38C6F95,AB5BC70A73A5A6E4,34289C7F88A70B8E,4F26343B2C0855EC,9E1BD67A88BA4069,E5C72B090FACF5D2,54A40ADA3267821F,C54A49FE1B9A91B0,266D373DC0115541,5B6CD7CCA64C866A,00000001DAC728E9,8D2E619A32D4CDA5,F1EF8B511F0634BD,BF9B7C7BD0FED853,841E7E339FE9BC80,FAEC6E9C20E5B525,30821D8FAAF6BC26,452EC595EF94575F,B396254D24CE606B,002CD39E5361F80F,0000000255FB0A40,0DD94BC0E2540374,56312ABE2D3B3FE3,0954DA965AD76366,13A060F317DFCA94,5772D98288E5F08A,B1F6E75BC98C817A,30D02C22DB8708DC,9AAE131446082E50,1301717A8BD7C41E,000000023F4AD8B9,986DA6683A8ADB0A,0A908A762924D091,ADA7232D43B8B294,9779C9B34DC119F2,0B5D698F65CB718F,FB8069EBF0CC594D,42C0E8922E174346,165EB3584C0A9417,3EE9B75D6DD6F2EC,0000000191B3D08A,E57D9544E6F10158,A834406DE0C472AB,E0E1AFC793D5F639,A4CE7B9C5DBD7977,6C8A604788435121,7AB77467EDE61DCB,16DB8F7E2216FAC7,0D8D427BE59F38B6,52A08D27559D8E8A,0000000072F4C30F,B6DB251F69461377,947570416B2F9774,5D5D5F48CB0AD160,78384751E2C49F49,1127EED9637FEDA4,CA2F1C968D10108B,9AB2B9D2C4BD97B2,7426C754FFF93091,89338F0D51F244ED,00000002619D4BAC,4378A43C9B24087C,29A06DA77FE3EE55,B51F4832F797553B,933AE0486EAD453D,8E92CE041589A78E,AF60E72D14A843A7,120BFBC96FDD4BE8,5D8F4F6A3AC6089C,DA87712D5099F8D0,000000014B234843,8ADF3D1590DA755F,23DB2ACA1173F0EB,2B38FD5E1B50A8C4,76924317EE0C4A85,E8E0D3DF501811DD,C5A025BE027F9F59,BC579F019D03EC8F,2E2FA94A33DC4850,33B9A1FF63006990,000000016A42CADA,8626D343653A47AA,2A10D9BF8C3C84D1,9601CCD4982D1E13,DBAC2749053BEE53,D2AFB26130BF78D3,6B7A2E301B9B245E,D1E8969D12EA8F86,5F05737D938E37FE,7F83793101D0E233,00000002487C6618,47BC976592D9EAD1,A58A4491E0F77F77,62FC6DF428FB97A3,B8EB1F292937CB2D,E57AF0C3DEC43C0B,2F9CAD3AE022BE91,5F8AA8A9BA79F01F,C754D9862422D911,8D1E60375640EF5A,000000020AC170B1,D378D517F21A603A,73B09F33FBB4754F,E867BF8CF0830664,D34651D81E46620D,ED689BF2D28075D3,398D4E2751FA39EA,776D179F8E0FCA53,D0FDF75DB4761F5E,0405DCA9B60676FD,00000001E645C41E,DF8108CB75CA4112,58979CF411F4A664,BDE2E08929F4AB65,58807DEA94F8CC02,EAB9FF52CEDFE024,B4C7560E44531EE5,D2DAAE974B749859,DCCEA26975D9B8DC,0962274119EFC0CE,000000008B89BCDA,C430B84C97A3AB8C,9EDA5E7EDD7DE780,5CAD15FB305B7D67,BBD7C874A07007A0,AC0968332791ABAF,5CEE7640C671AF96,6E7ECEAF016AE0AC,BAB4BC81E7ECF357,5231D0456AE423AE,00000001C1A03CD3,DE2292AE95CBBD32,13AC084B3E0F4882,A3427C75539E673D,F629FF3D0799DF92,CC377483D5CD2ABD,2B717B247CFA9C13,2E8111D8052D33B0,19E1815022A6AE6A,9CE00D94D0F1095C,0000000220F2914F,463D663A4E3290C6,AAC0043385593565,5560ED96EBFFA836,1F1139583B0D7414,CF99C0C0DEF01639,F0B037407D92F97D,884D5720080EB7C2,89C0BF6E40CC30D3,18CB8E422DA62DAE,000000004329C27B,D870FD0DA02EF1ED,0A30933CB9FC68D7,372EAB68C855B54F,77B265119EF7729B,32E0990B9845CA4C,33F46C58186348BF,EB6CCE9B2A73E463,5E074C94B6CEB25F,AD21FC56B64E5B7C,00000001EBD19DE0,027A0E497CDBC318,B59E6AE10D9F2ADC,437531946117B8C2,2C4757D26E182982,B24A74B029D1D5FA,EE452AC42EBBB1DB,BB99BD6E1F53AF81,3683FC88614447A0,FC9793B7F6D2658C,00000001EB466343,A111B74B99C47405,CDB54FF989BC5FFD,938E500FC405740A,D87F3EB8793358E5,19BB6D3497174CDC,A805E85EA2B67A0E,3442E5BE8526E7E2,C87834A3AC01B676,4C64D88D36FEC85F,00000001F8C1C1E8,A5609D9464B7CEF3,4BE7F663B8BD4504,249CF769FF69E194,A90AA9C657D3169F,6274CD0C8A12053B,681CD62EEE07FB36,7C19FE1A660A1619,442C71D7CA47054D,6DA584EFFC4F273A,000000021D68AD68,D984058CAF8E3349,89A01428D46277ED,136E54AF8488D9FF,E361014313B7BEBA,89A87BFDEB5B0CD0,6679CDF4D171A904,9FF4AE1D153E33F9,C10EFDD28FC92DE4,E1F3CD94C9B933E9,00000001190452F3,EB30567E8CB52317,C9E3ADCF927CA548,24B02A877456037F,53A63D4A19862A9D,D90D5D1EB0E36D69,05699DF9A65F057D,3F37A926F1DA985A,AE083BDE022DE611,F488D3ADBACA06E6,000000016ED78459,03E75DDBCB4A0422,0645052AB484CC85,02ADCD6D9F885D82,C7582DD7848D6253,FCB5DA312A91E7F1,9465F570A544AE37,56E38D717742A42C,80CA2B7C567B05DC,1041E49649997278,0000000088AD1FF4,A660BD293CC03777,9AA763135732B884,3406F5DB7FF0426F,FC531AF03EAAAD87,8956EA7AED0E63DB,F8B0565EA03D370C,E964A938C76A8EA5,5C42DB997E0975B7,309D4012734D60E4,00000000E67D8DB4,E7C71DECED737383,E0F32CF3C95330ED,B2D778F0F61F3407,4194C2784147F393,6B9E187D6DC28C9B,3A9118BC76DA745F,3A21A7C1D36D0A09,788786B60B32F053,6080FE3B0EC75D4A,00000001BA85287E,D495AB837D5DF55A,3A02359E40C2C5CC,58A3CB92E900CC73,E6B845C558C5E1C8,F7F3839C29CC0FC4,933BBBA40D056B57,92AA2BC415E516D3,57D18D992AE6E4A5,A69E93C6391321B1,0000000253F560D9,639D678E85CD3475,C558A630D8F1FC44,515944F07A7C4EDF,24D62572F0C07EA7,39234C01D47BD934,66007A1810B8C375,3539D4DC24872F08,FE389A4331678D1C,D4EBA07B2ABEF631,0000000215069469,977978ABB8BB8C96,BE9E77D6EBC8740D,6E2A48F8352E9A73,1E47806C723EFCB0,B15D04F287CFCA9C,E72786FD787216D4,5EA69FA1BF8698C2,0DCBD996F831D69A,29B3302E6739B4DF,00000000B247FBCD,C02A40014E757E19,36F7B9D284D504E0,0DCF8075ADEFB504,50E917C022B83475,7EF3C44F71C37F8B,16A48A72BB839BBB,B1BE3EE9D4AEC766,506D074EF3AC4A90,3826B25AED69E9E6,00000001964F07D6,C2CD14FEB98F2CF8,13F268578DC83410,067D7C4C80DD02B1,B56A6BDE5B572E48,D5E89D01A15D6405,4F99A607A314FE05,B6EAFAC4383066DE,C8CEA83713110C67,0E468623E8264413,00000001EC9D9AFC,99E7FA5253209D81,ACD5B2444D8823DE,50C000DF9CFA1621,C6345D5B62857F33,80BC612D5D8442D8,D56212B5348A1487,EED3883E341947CC,A1C1425B576F41F1,247607A372DDEA6D,000000014FE0A25F,F67F8A523D4367C9,73DF7C041E13D438,9621BC7B7B3CA85F,A30B922B87E880F1,BE48AD00DD0639E5,D4ED70597CAFF7D2,4B886096E38CB928,7B405A16DD1A0A49,6960CD72E611F311,00000000690AB57E,CD42CAD902D99149,E39B5B64E037C9E8,B95637F5E75C06BE,4145B2D1CF96C0D7,5C6EFDE7D37CC7D8,657A7A531598AB2A,54190188F2B6D5A5,E00E4E677552E0F9,D45115E7B4FA0EF4,000000026FE35620,6DA98D990A9FF2FE,FE34B76761FDDBCE,EC36B6DCCB659704,057AC4E8C9C134C4,4A30C8CC8C3FCCC8,95B308B585DC0BFA,74F100B5C867CF87,A44EAED75BF05BC4,0914BAE2AC00F059,0000000192D9E4D4,2715A183965EBF7D,A070A0407C28827E,4AE78FAF8FE3FE96,6A5BACF1D5F02334,AF6ACA7EB5CC941A,42FCBA6B7C587360,1E540110F40F3BAF,2D881011E3B2FB7E,461A43C3837E402E,0000000137EA514F,3695F33951C14504,B0CB8BB670A38160,0F77B6BC269878E9,CD76294807E18249,322FDD23F590DF0A,8C54C8F16F8D3601,D2A088940D205F2A,820CA11B0F526CA5,1153092032D56D8E,00000002061E61F1,33AD900C3AF537EA,7D9B68DFD0298A1E,084C1BB2A8482C6C,8911A37DDADDB391,21902A092B3D8B52,87B2082670FF1CFD,AE885E474A3C615E,D94B2B4EC0BFE433,CF73A6A6FD8885EF,00000001435CAB1A,8DA8186F31CCB35C,E3278DD94BE8D378,6CACF9187F60024D,CD7DDE12459F52E9,B8231575092D2088,84C454672578CE7D,25736D691D8D5AFE,8BC79848F9F65767,3B71C0972AF9DF92,0000000079C0E52A,68987EEC5B110F5F,D1A5ED71E3E329C4,FC2265C5C0188E9F,3E4FC714690A1355,A5F7F9DFDCE758D2,7427EEFC4A74D493,821D5FA4D0B9114F,FFA64D55AB9523E3,C11A958463F4AA53,000000010FB0AF1F,06CC0DBA7F8A1D1C,14982A1312197F8D,C3AE3F2638FCEAA6,428A8E551DF80B27,D3C912638A6A4B78,8B7E61A7AD431A0A,3B859D0EF178FBAF,3263EB60AE2C556E,1CBD74DBE4313D08,0000000264264D3B,4A0848FEB46F5525,774E2C45B37FA2E0,D1B5FC7D2CCE214B,1AF7DF84B1087ACD,E9E9EB8ADCB055D2,C1C992323C2F67F1,8119B262255632F5,DA6319DA982EE296,37E736E2EB282A48,00000000FCA4A550,0B158181181AF9A5,AB453956397F5B16,EB4364A2955CEF00,8EFCC9329A862990,408B7EDB921E5FC9,63753ECBCB06A2E8,280C1EE09EC7721F,3CA7BE732FFB6367,B6333B5293E77CD0,000000007B757B0B,EF0749F6AE47FD66,0FF10710BDEAE9B2,F8B9C0A0F1D68FB7,A2309B38D2F98451,D4C90EDCB0419144,DDA4C65E4AADF723,05C5A68BD1DC3264,CC340531A9DFBC2B,29EECEFB1BD3D2B7,00000001A70C3B68,F70C3015134374D4,CB9687DD90207477,3DDEB88F510CEC5F,009CB1A6696EEA26,8716B587C23DEDD5,2C0E8F78E75DD3A4,E287F5CC0A607CA1,2391F30FD683EC37,57ADD940C3B03B56,000000006F9E2CED,F95280D717E9859B,64DC0F68A02D698A,3BA4963116F94006,5CC0BF988A5B90C3,9567E54DD20466CE,EDF794FB0434A7EF,396612087A552896,053D8BA07D82719F,481AF9622367C2CE,0000000051A9B071,E813939FC65872F5,480BEAF669AE5CB9,CF899FD775773456,E1784A3AEA4FA6AE,A8B2C94687FD6F08,E94A37C3093FC955,12C14FD40831D525,F443730F0617AEC1,C16C69C59F9F3F9B,0000000147EEA812,31F592CED49B9C27,250CBC1CC4A0AB5D,437E92AC008AB730,D8F51E6761BEB6AA,62188B6F75AC297B,99AB79D3EB417462,F4A579B59EBC8C7B,28A4C8E774E1A2B2,5728DBB3F1B89074,00000001AB1E2826,6D8F18C93EF7393E,BCA50B82EEC3A085,D5A445F67D708A1B,057E2F340F5B7423,5210F5ABF8D21A4F,BEF974A855F44582,D7EE7F0F2ECB3CD6,14315B6FC54DC2C5,564F51561AD3E98B,00000000BDD3832F,0D62C68565EAED84,0EF075C4E2104DC2,13CF96F59C6F549B,8EDC38B60E532919,F3F340AE057AB43E,B7D96518D180063D,3AB133B391F91F5E,0AAAA4E2AB1E1CBC,92EAD4FDECACED37,0000000092A3B9EA,9399DB6C07E6CA86,A28C4EE0BD4351BD,8A433BA100AD45E6,5D81E98B9AF71E0A,1F17B4D64ED23414,99380D895A06A891,9F89E8A11E233C11,E3DA21E91F2C71FA,6B152DA7D3695BE5,00000001083CCBCB,E0686C503EE079A2,7A3756FB335A5387,973CD526E47921AB,C3033959F152CB3D,3F61C11406717FDE,7BD88040365FA1DB,04AF9AF28FF834E9,4DECE00788CAC407,CF1831AFEC92D78F,000000002D732122,5BFE2FDB1B6412A1,BC5BBF55AC0C523D,A874236346EA7942,7FE5A5FF21BD54F6,11528BD5A29ADFEF,35E6015D95CDFDF3,B36AEDAC6AE8E613,4CC7E30F92314B58,D71A3E155AA95846,000000021CACBB50,6475A964AA5FED86,BAEF8AE877E426F1,0BFF6DE915D52AED,35ABA0B0C2EB4AC2,671B67F180C279DA,ED50CCC2AC609FCC,B4A7DE849E0BE87E,6CB03A5C64550920,C42851CA311058F3,000000008EDE5AE4,40E33530FB6ABE3B,72F04D8AC7ECAFFD,311A7B6387468DBE,294B42E38E10D28A,A1EDF5BEA2FE1B25,083DB5B1DA75FF4C,BA24939EA9D95B83,702A4C1D65916E66,D5855EDCE268F20F,000000012184827D,C16B478A10513558,1125F9F08B8C1F68,A252E07302941A70,1396938F260232F6,0054798F71B4FB0C,7F43C5C6D1E43F73,21AC041E72B824D4,1803A6E354ACD044,740DC1D007091001,000000020E7CF453,5636BF7D78D1E499,9371A0E7B6F8CAA3,66FFA8ABFCA3EB24,11E40DFF28C81136,A9BF42D374F2935B,A6324258ED790EC4,460881325766B7C5,F69C26267FD59AD5,8F1FD43C65E0ED68,00000001A86E15AF,FFA8F5E799BC9BFA,FD1BBAB90D5AAF67,D12BD70FF1B086FE,031EDD24CF33ADA3,2F093FAFAF367025,8A5C7E1EB27AAAF7,946664C352DC5C6D,32A291D20CE58ECA,90BB4DCE9C7956AF,00000001A7DDE425,E3A268A511E90CA6,FD7F8E5EC956B8E5,E753B02A3872CE80,E4B8DCD115B8A7AF,22707FBBE3663E11,F5555E185ECD3083,158742F446445E74,463C212277CF9F30,6C24110221ECF7C9,000000008A36C6AC,D6D8A1CAF2A3E6ED,3365A9C1C57E2666,43B3BF55336107F8,6F33FB2877BD9C17,CE79FA5F1A16056C,2709D5AF7EFEFB0C,40BCFC1949E7F965,B50E0C26674A8098,D29B36B957D157CF,0000000276D199BD,77580F5BC1A76CB2,E91AC3F7F262D2ED,DAF6BB2A68E8567D,70B57DB6363D7790,E7E928B2BF22584F,582E65F7C6215ECB,5428E211157691F7,0BC6A3BC123CCCF9,8651BFCB9D1825E1,0000000254A3ED50,777F3620554A0042,9F3C97A5295B17F8,F91C1B343C439AE4,6F3A965299C2AB42,E0378BD563784EBA,ABFC393A2CC00CB9,C51A02D2BEA0B1E1,522356C3B9F64364,47645EDABC1D7FDE,0000000236DA5B87,123B34C921DF677F,3E84EE9543B566E6,03A9AE4A729ABC3C,EDAEA309866AE38E,F4DA8D2B83E3495C,A5CF67C7DBC1AFB1,93537F206973DC2A,577C2566F1BF58F3,BEEEFC8EA1709513,000000023D70735D,69EDBD91DD4290F0,A1FF3E30DB198AE0,0BFF9FB511578F5A,65D07ECDA5AB725D,967DFA5953B43024,EBB4BFCDE877D024,7E74FF12BD6987F0,3A1FFAEA856C0DD1,2DFBC39C16712153,000000010B7CC3DC,D3AD7B865C124BD2,5D5DD92C39186DB0,347E9C5080706817,FFF2EF618387B9D8,7065937BC9C31264,ED7E6FACEFB9B6EB,629D9CC7E61C242A,1F160335CF1F089B,A02B47068B5A6E41,0000000169A8AFA0,F9E0AB9C16AACDB3,32C41837878B0988,D8EBF8D0CB3E6454,FB6188D230B636AB,BCFB08808B44600B,5CBA9126D61D3E19,D9585DD63CB072BF,C11EE010D76EBA3E,FB3E7784D92D350E,000000007E1D16F6,436EC53605F6196A,8537E64EBE09B0B7,9D6181133D618D6C,816FE77353262358,98A6013C213D6C49,F168E05B6BB92C13,8F14A819D7AA6B87,E5A857E45D0683D3,249274C6EFF25743,0000000216A9B3E7,DA4444D80D3C87E8,7ECDE67E4ED7824C,879323C91B584170,A33056881C36D621,88709BE1DA9DDE23,859FBD8FB6D7A2AB,3B8AFDDFF427315F,ECA1604803305F02,AE6E9A086C0FEEEC,00000001A17C6DD6,AEF015CD7B96F6F7,90E629A0064B4C76,553AF48AC5A91815,B23F173FC5C6C721,597B925D59178274,8B4ECEC81088CA3D,1C457F38A6814E85,61A7BE3746C2CCE7,92E88882CB364FEF,000000008D35C8FE,20438A396A01EFBA,6F6CDE14B88AA13E,51B7BFD686744A48,36ABAD0C72D73F2A,488E862920F4BDB1,86BC48495BA55C21,FA3E0FC67C3CA8A8,A35BD562A2C6D2D5,1B99C5C321471390,00000002541956C0,D6322CD0580E6EB4,DACDA8B27A0756CC,D2EFF96061435B3E,EAE2AA7428E8F339,D04ED159B83C86C7,63E726F8BCDEA264,A3BA2324D9F458EC,457F02EB0A6E88C3,7ED1E8A04A3F15DF,00000002066FFB3B,7113BE1BE3FBDA16,EB51A9ABD8FEC9C8,4D9E00554A726C75,C3A419AA0CD4A9F4,4BEDFE9257503B6A,33097DA6BC9B06DE,0374EF9EAE6F28A4,A2B193F227B88B10,C15FCDD1237D3303,000000001DF4D553,162F7301D88461F6,0EF8E766CFB85094,6F52E6EB1724E4E6,C5DD10FEDE0F0AC0,8FBCBB34AEBB8EDC,010DD79A60AD0F64,F1CEA60C09A3C395,86FC4B2547371DFC,B9FD773601DFD873,00000001780627DD,4C3758A48AE65E80,8AD6BF7BABA2CE80,AEEFE0AD989F5AB5,8EA18380EEBFE0D1,FA0FF63CE7934BC8,9F50AF05AC5B0674,CFD57EC9B8B22E23,B724F8362E11ECFA,C60D1595B23A2313,000000011FF99454,9FDEF5C0B0BB562B,C02BAB260CFBF6F4,76DE28F5D52790D7,FEC5D4906BC836A9,6093F1B4213A6291,C901154A8D722C88,C4B09760E1626222,A62F4E6817134E71,FD140C4F9B73E8E5,00000001BACFEAE5,5D8A6FC429A8D1B3,29271F9A5424D169,5411BF74B6D9C53D,64EF0123BC7F0EB0,68D9A5DC52C1397E,571068D43A94A36C,A92619B7573082B2,3396E91D4E8A07D4,BA33A8D744CE3B04,00000001A277F952,4AD9CEDFC6FAA211,FCB1144EE1119210,1946AAAF2FBED6D6,7EF79223110A5F4E,9922B175A0AD3CD5,38F5FFE76809F5D6,5B32245BDF6D411D,9409EA81A45C789B,05D298BDCE0A5FCC,00000000CF8DC03D,080EB4CABFED964E,2207E93F07E8970D,CB6DF798AA4BE338,789C6B3B3C5C8DD8,A44386ACE9979D3A,903DB2EF933E117D,E18CA1FB7EE59AB9,D3FE1C3D7AF27C5D,2498A82EB73FCE2D,00000000386F9218,E5317A1CAE61CCA7,D98E03B4FC1A382B,1318013FF5EC6C32,51AE2030AAFD362D,DCE6427466C82F3F,4DF13A03ADC8263A,D5CC1E0935C18F4C,7423DA711212CF99,6D9533D87D8DAF40,000000004192B78D,4EE039E89FC26DD9,648D935D58D6399F,6B4F9A40C0B2F0C4,A4C134604FF78162,81C58D381263E526,A7695474E12D0D9C,C123380627E63E8F,DAD463D0272AA84E,D546705752D96F82,000000007ADEC833,E73D723D7D49202E,1F0B2EFC9A735323,185C7E117416E78B,DB904E1C379D2296,1B8D017C0D6493F9,14E81715D5803104,F5B6A16BD6B27C3D,70F73C37770547E3,86C09885F37852E7,00000000283874B6,148BB217255A8A0C,C8B10C6C46D7D8B7,13266FBAF4A66BAB,9E522CD7E8F82E57,68934DA363BA85F8,E6CBFCD7B60B1621,D69099F4C9F2E449,C0D24D762940047B,EA56388B1A6C9CAE,00000000819DBB24,ECD1AE7DD43D0F34,E044AC22F67BD3AD,6EA7482C06E957BA,BA47E605B2CB61EA,760037CA8425BC80,366DD718061ED781,DCB44CE1115E2F43,99269EC50EB03A7A,3BCE728481FEB448,00000002112DE017,2C7B44E38217EBDE,8F11CDE138C886A9,5D4CC8DAD54C4DFC,D5713B3AD112CB80,C74E158147F82D6A,A7F82D57F2DF1166,B44012C420000C81,40B57170A73FD827,92A0107A8670810A,000000008D4DBB98,F702A7C7CB79496B,DFB92382C540AC84,C8151655C10821E0,1FB86937B3543AAD,6C1FCE5F2B8858E3,8D60E554FE1CCEFD,F19B992818CA8E37,B6E2C6DF2334C1DF,FB075EE76AD27661,00000001F363BE3B,3E866490DC9FB2E5,179B50648DEA4EE8,3E183099DBD6DB12,47A814B248DE1A7E,16FDF2EA9D540572,BFA10BA2F1C6F6E6,BD6BE78F91327EDB,D77FFDE8E30E03C5,78D289EB5FEE8090,00000001259693D8,CC422D94F2977AE9,AA6DC80FE183CC4B,CF2AC8B48FDCF252,F253E4E2F3B30FDF,1DAC3681A47DF33D,0CD8AC85AB040453,F37AB8EA1FA1BA49,EE83562B3B75E59F,78684C1C962EC1D0,0000000179D294AE,35688F8602419B20,59AF499FA9D421FF,2723DCC6A22D44F9,A5D743590968DAC2,098B12A290F52F46,7B96783997C8A377,D1269DA8FFF6A507,2A88CB4DBA5104B1,D46DA0801D699919,00000000BA6C4725,09BD3B62395A84BD,FAC4FC0F7A14099C,D8A4DFB00CBDFDDF,2F5882FA3888BCD4,035CCD96C9533B5F,913C39A5F47CF441,1CBDF0349C91CAE3,F196AB1E3C6FEE71,EB2077815F41899B,000000020C509914,4B090288B7607AE2,5C581AD9F1938FEB,F7E5291EEC33F408,889749764C12F04F,C1E7DFC43D6A413A,41B760283740E219,88CA05E1A4B70D9B,1AA68B9E22EA35A3,8011524B50A86324,0000000118727E87,BD562910BAE5FA4F,4B4D6FF12A1ED5A6,59BB103183F121EE,CA6C0AB8C8B79516,B5A80EAAEFAB891C,9D6BAB2A1CDBF24E,2FBA762AFB2C032A,63B637301AFA42C7,08AB6D8837774BFF,0000000014D90D7B,0FC3CE8CF4DBFBF6,A704FBD2A717A6A8,8D60CC52C1C8E8CA,49246B23CA597F74,E212FCEC68217DFC,4B30B4BD70F7FA3C,6232FCFD1876B87A,943F8CF45FD45DB4,CB8B27F23CD55A4F,00000001E0F638A8,1095A60724CD5110,65DF9F5809F82F31,F8B0DC608A4102A2,D9E5DA09443F7FC9,6270B1A553E91888,0807FEC241BD2AE8,C8062CCAFF54DDA2,DE4784C70587091C,89959A559C0F19AC,000000005D1089BE,902F800E180798C1,A81C844508280F81,927ADAD5601B28CC,411D1C2296D99AF8,9A13F9ED78999C9C,D38D96551856DBFE,2A584BC023E018FB,50D5C6760E5EA6C6,4F27267EFD4A807F,000000002F54CD46,C274B99634D8A0A3,72A3C74CE5762902,D239B76250DD976B,F954CF84AC18B8BF,BFED11DB8861EDE5,D8D53E0DBF7C6DFE,1FCBFF97FE475B70,92ABE5001B0F4F46,E56E09F454C33AF5,00000001CEBBFA90,E86C6399D4D114BE,45BFB848CE888B2F,17D48178643E7586,0CE7E6A92813B5B5,46C98E7C6D4AAD3C,E3C1A8AC6BA22888,A5025E419C0AE9FA,F9BE4D1E767EB2D2,A4FC8666E88461FD,000000005FE7214F,35FA70A5C231E0B3,469B7025743E7639,49D4BF2C4EEB357D,AEEDBD59A86E8940,27414E3DAECF6729,1DB9E6261193D400,928C2A524A9B2549,04AEEA46EBBB39A5,071419C5CED4B2FB,00000000B8C7A989,C0B7F0B44DEF0A01,2D7011BF2DAE1D08,67C01E90C4BCEA29,9B5484A2535D12FC,14225E77A0BD6734,0AD0C8AF0CB6DC19,11305EAE3B82FDA5,315F40AE4817BA85,8301BFC45BB943AB,0000000029B0FCE5,2877C9DDC44CAE56,2FBD434FE5F7E2B6,0F2CAFDC2DACFD98,DC49749A67BEBCC8,1A08287D00B68DCC,CA690E0CF7C98D6A,9449CBBBF9FC75F0,3C7AD3E71EE9F58C,3A15DCB751FC9025,000000019A362986,82CA4E6ECEB79A58,E0B871BB57F17E13,4769A21E084089E3,5C12B7BA5823F670,65BACA97A2AF2110,25EA1888ADE1050C,E9A6A73D2D060317,6A371E0BC5E7E5B5,FF8F4545EAC40945,00000000FC12A249,5454AA387723A2BE,38B1BB7B546E72E3,9685979A8B3F9F6F,97AD5E60492107ED,62E4FBC43505D8AA,93F1EE261A0B8BA2,184828798BE0B5F2,7047885D7820B8EB,E2FEE6A0DCCEF7BB,000000014965A8B0,37F11A78944948B1,899CD0B3BD671C70,CCF6BD27B068E075,1A90F137B129B583,7376EEAC81593BDD,4AC3946FEB066943,B542E531168A76AB,F8A25672D6535820,1042FE32B78016F4,00000001D32684EE,1163347F69B2D5F9,A49964E1646A3E76,B9453527AF4D28EC,7019355C72A5CA2C,829DBA330ADB94AF,6839DB946D1115F7,DAB1C15DDCCECD6A,0D44CEA758E1DD89,538D5A67D84B05FA,000000017516A4AE,CAAF29360E9A5701,EA7757B584B8753B,A7F0E6CB5410688F,DFDAC76B2FFCD760,7833F6937C8D72FD,54A1AA01045AEC0F,2DEBB610FD92079B,CEB1FCFE019A0529,EC857C1859DEB6C2,0000000155494636,71C0B2E6894EB5D4,68F7271835C2D3D8,7D8781E37BE60475,B27F2D198D1CA19E,8C2C6F707342A6FF,6E21A3FFA4274A19,61D0CB119A2CC732,D8D65E2D17FA8E9A,444B30F3E98E3CDB,000000004C14FB24,7FD621F5D2E70128,197FC3AEEFD33149,3CB609B7CBF11BE3,5F80B07455A915A8,1383BB02F180F634,4EEC651DA931D216,15926496A1E2F997,0D4AE9E657B3EE4F,A68C84BD528C0BE7,000000018B173214,5F3292A447258E24,3B926886150811A4,9186A215127FB9B7,BC153ECC47E052F1,06881EC4EBCD7D0F,B3B48F6E4044445F,DE93FA421DA1AD5A,53090D0BCDA6B7F2,4F766C08FA109585,00000001FDC9769E,D33AEF0ED2A557F9,0DAB77955397F17C,F2778BA68D6CEB9C,69FC75A5CFA97247,2938558A8ED9E098,E4A081AEFA645EDD,B347E3FEBE2640CF,E1C3B06E699223F6,8F613CD6447FF634,0000000015FE3289,2363317AE79D0C47,0CFF835C9F253FF8,2CC96ACA9F62D3D8,AEF5112F8A437846,8517D6666859678F,7DF254A75BD30254,83076C1711597FF2,CB029A6E88C92207,E9A970C05A866594,00000001F7A63D14,8CD6A931E97C3456,DC1764146A08AF29,C7685ECB81D28C6C,1AF887757771DC59,F7EF069239FDD6BC,F707A114AAA12631,9C078F75A9B54EBA,DED8D97DED48FCB1,679843B3EF48C3FF,00000001B964C660,DDB486763F06F320,4634772BBB143A9C,4DE685EE96C167BE,4661C2D724BD56C1,0BA63412DBC825EC,723828B91E465418,953D4F1DCCEE64EA,392CBB903E735005,2D019B3529F344FF,00000001BBFF0F4F,30BF54DE29569F0E,975CE2AEBC66E171,A9D3C292C7EE6A42,45066FEA0B53A031,0CA5CBDE72799B70,9D9DA7B773A4AF9D,0C3644C512FB11D4,0A3582D9965F6EF4,DDDC290E7A6B9212,0000000172A5B9A3,0821F0140E1705C0,11E0A4AD1C3F6F7F,012C2613E2B87D44,34B259AB88BCEF3A,1AE07C891B7EF01F,D7DB8E80C98263CC,90D69B01967F1F1B,2FC8F40049FD6456,042E22CC9359E722,0000000043455035,EBA847C188CCD36A,AC622772976619DF,B8341BA2CAFBD2EF,DBEA543CB3C4B1B9,3303F7798853DA51,27B2C820BCFF8C1D,E8BD773986ED9B69,F0B2DD206D16E51B,C64ACD2174195435,000000007CF3CC91,6FBFD9A172D5E78E,30CC34E989167A59,3A65E8E14C0CD5EA,0822F01C2E60A208,05C1C73A9ADB237D,783621918012CF44,B6F4902BBBA7112D,628866C03C33CF4C,563FDBA0DBB8D1A5,000000018A8F0BB9,DF272FFDF7E7FC4F,B159EDC59C7B8B8A,CDAE951090816F8A,1B1EDB6010EA7ABC,68E90969A8C79438,49EC64C41386E662,E015849C5BA3E307,6D7581CCFAE88851,83CCCB06286B59F3,00000000926CE5AC,BEE252D98E3249A5,908EBB709B019BF6,8BD04DA514196F79,A11F3C9C70C57D90,C5757E9A1BFA3158,F33CB1FED10DB901,7D5A2FC86723BAFD,3A0DA0AF1A118CF5,7AC5D0481AB852F5,00000000CA943EC5,675B7AF962EC05D2,62473D2F70D6C9F0,CB9E05443E339C29,2129DA8AFAAC1D55,67896A0F74797A1B,F0AFEE8D40623F47,8AA7436FAB9640D5,0309F79131404576,16DFBECFE42FE52E,00000000BFD6A13F,55D4DA4A61778360,91B93A1AD4A54D3E,E9363E5AAA914C28,B50D8A93C9498413,BC1B999B3394FD2C,3CA6D99F828BE538,395685CCF002C1FC,961EA8BDA5CA5678,BB0BA0E88D762CFB,0000000099DDD956,B08C2663F76EB9C7,2BCF63D1DDD1F17C,E917FAA78EF918AC,8EEF6BD28BFAC18D,7DE4C31C0FFEDA16,B84D0FD3075315FA,FF47B5385E700F00,9EE433CDAC56E51A,FC24F37F27C83BEB,000000004AAD114E,E9B7A52E31C1F3AE,71573C4FF0A76A26,57D0ED77434E5CBF,839EDDE47DC4610F,AB694C56154462D8,11F44C3A66ABA18B,03FB58A5F24C80CA,F364A634DC7ED0E3,370E0A8FBE743138,00000001C975EB05,E3FCF14BAF3B1A47,362703A38AD4C210,77C93452E32E8923,26CDAD538513A132,38D14266C37BD7D8,B10C2D4EEDF3D99C,C5A145B30C8EAA78,16BCAA2B707D5063,50E7F0E9B432002F,0000000016FB52C2,EE5F52AFDB1523D2,36FA88DB296D86FC,1672A60EC0DFBB1A,1033DED90E6FB262,789065686AD1566F,40C28454500B5A26,9C064A84AD5E6BE3,9200254BB9F2812A,38F203CCD36ADB3E,000000015781A7D2,C4C2AB01EAAB9700,B84010F257BF3CE8,CA9DD630CAD705C6,77325E1AC04971ED,5E4BEDFB26BF19BE,86F4242ED2F07DE7,6DDCDED7F662EBEB,5C6C6A8E6B53E474,CF98A6D646D4AAB8,000000013AEF5564,51B21F584F5DBCD8,3C8B8A75317E6B7B,DE16F1F92CA7B3A5,012318ABBC6D6449,6008A9FCCB6AA3AE,00085D926F95CC51,E2A6720294D87582,EDFF9B1C43E250DF,6B925D090E47749D,00000000FCC0010E,979FEDE760C14BD2,99BAF6F8E7EB6C45,F44B01AAA482D903,A16216CDED7BE627,411A33EE5195322B,C5AC1548A02F5AB1,327EDB4FA69ACA07,F86981024A3CA940,1880878B369AD4F7,000000008F21D122,29B71B1F70A3C80E,60E9248865695529,138EA6B1EE9EEC4C,4A302A2EEA385392,7E95694398C0860D,01B6B1E5C0BA383C,17FEC4A0ACD3BC32,48D2DD74B8E631C4,90B2ECC50A95DB10,00000000E35DCAD4,3433A16F1C7CCE3F,2A56EBC7A99B35A0,41D9B318B5E4F0E8,4FD7E6375C7C9B65,27573761A9BBD6D6,B8D6A88416DCCDB3,2B0FC88A302E7813,60D3BE7C6CF7825C,88A01595C44A74CB,00000002444009DE,0FE30F921B9AF4E5,594873CA86EEDB18,F4CED20919508257,C266CB2E39F17BB9,22E4895B0FFACC41,0714790B82CA2CD7,C610CA38B950F7DC,71F29B53B563D028,0B6BEFF7D683F570,0000000128AB96BC,6212298A98C9473A,543CBA01F49CC064,391D6C395783651F,CCE8E2E19D9272D5,93422B72E8C2A528,5E44BBB49C58859B,30727D38FC0F8BF8,737FBF11BEF780B5,0CA1BB1A94938FCA,0000000135F4D059,52E77CB5C7B9972A,1B289DFD7BC1C99D,958045E8C6095D7C,D42E417B4D0EC364,2C4D0A845FE1028C,2B65E13CAADCD0CF,5889AD67B7FF17B9,F90102EB4770B48C,F9C0C840E9CCF318,000000011C501390,262C242BBD3ADF03,08A18AC7AF362924,5836D21084F10D36,835502DA41D70A50,6F46EE673EE7D25A,C8B7D2CB4425613A,E0162A5CBA451924,881BACAB5882E411,3A302C5F68BB77F9,000000007FD87FD0,75AD6F9C236E2F03,3197C7280269B830,C6F8A876AD13E858,A27E9A4388F28450,E4F0BA8F6D4CEB9E,E9A03364729A9DB0,A23E8ABF11FECE99,57B7F78F8BF9D834,367A63AF6BDFDCAD,000000021FD34797,1F95F740E647EFF9,923F3F710E493714,AC3E51D842846883,DF0E16E0DB2FB8FE,4623CBD9B6FB97E3,A4C389D09D1173EF,F570F10C796AAF7E,41BFEB631BA43D6F,EE0736AFEA475A7D,0000000122FB3DFF,33526EA9B09D4AF6,AFD042C75CFAE878,4AA657CAF12FA298,DF26DCB813D3E437,7BE98CB6A66F3FA7,CB341E15FE0BDAC4,63BCB23C77C4011F,B8416F876A16CE3D,725D71C24366063A,000000009CE65898,2134A26340844DBE,8EBC8EB2FD5E99CD,99D16A746EF9F945,51D61761103FE055,9D8171AA18BA47A5,CD19285C220EFD0A,22AD713C2379DF66,F4FD8885D0CCBCEA,B871B10DC7A30690,000000019DDE1358,39EB2DEDC22A0FE1,BEC7071A6FF42BE1,C8F452458532C395,031CC10386D2B205,B08A26B8BE11E93F,3149EFA42C9C817D,775A0682F3C44714,6291AE8308BEA5E9,D59DC3442404AA79,000000020C828731,879C990A387FB32E,AE65C06A5872CC03,57B7C898833B2D58,DCC3DB595183D534,36455BF1C1A3E77D,F4A0B2DF2B88AC5F,934666C40F91624F,33556CCCA30EAD3E,AAED9BC159B74950,0000000249BFE0C7,04930792345A4D10,CD9A64B5D6BB4A08,6EE04B3CC77D6A7F,9CB1AB41757F21B9,8988A63FEEF6C498,2919B3F88C078BA7,5FA732D8E4157AB3,B333357E21F71CBE,40A9D4C68B71C0DA,00000001093CF271,5227AA829DFD6EF0,C055A518D0DC4D8A,7481F649B1535602,2106903D0E525D3B,6CABC5F1DBB94C44,95426B7C1552F32D,C411EB396FCDBE1D,3EFE4FCFDBCB2BE2,67DE64A99F9B854F,000000023A7CD137,D503A1ADD9BBE846,56BFBE73E1C79B6D,6545C516B68047DD,43CEA33296BF0788,F8A81B4742FCB8E8,302230EE8FF8D25B,68FC57E2BAE2B36E,F5CDF3B3CDFE7D1D,9E6868DD51EC4D27,00000001937E1283,EF81154AD419BD92,AA7C9FD744BDC27D,75151F05ACF949E3,1E59694005343E56,F35C18022226B6ED,D2C054FE3EE91406,BAB5DB38C90EF885,A08AA75FA78FA524,6A6C0E1CD110A1B2,0000000029BEA51C,3819F6F77040D064,0510D469010C5EF4,14A5B13CFB8ADA4C,E8660E1AA918CADC,E608BFDC51056E8C,B528BB46F8FDDE72,7B8577321F09E4E6,A6896E180B266485,7044BC400C02C48E,0000000009A9F456,5547744040316A21,3147E6C78C675713,4BFA12E96360153B,DAFFC5673517F2C7,642BE96318167100,0BD52D63F10C3331,F3903A11F51E00A7,7F7D1924D17CAFCD,DDC5FA6A2D3DC4AE,0000000203B450B5,5D86D1206AA396B7,6944111EC44FE894,A30E65512D120BFC,B13E65F1EE342406,8D3B1D1EE670F437,1364B816A2540C71,7552C9A0B9FBD51C,908E0172BFF212DA,912053457FF066D4,000000011E39DF1B,0F6A68B941EF5867,E878D0F41F672F9B,3496F3C6BD8A5565,1177D923A511EE2E,CAD72C26B371681E,804A7D08581E2B10,E6F463F0EBA1D8A2,1852BBED6821DF72,8D21D1F251896039,00000001C3F0D8F5,FC9BBA32AD547787,A9388064DDE7EDEB,3D090C1D8356AF7B,63AED41335A8B5C4,206F17097FA216D5,5A5F3C3AF5CF014D,1949909182AC8C62,81B02D80174D7CD0,1BE487C21DD4C35E,000000000554B555,1557A14F9368D13D,F5FBA60310C20773,AB286E57F9E3B29A,308518F4218C1EF5,8587A08DB99B00E1,6F8D533F21B12051,B3F1AC4574137EA6,82E817C08D1791E7,5395175D8FB18D3F,00000000A9D62CE8,4239683AA4F41392,217EED40787E5245,96CCFBE3BD30E3B8,71BF79315C899291,222BD7D08962FE80,AAB78F7542CE4EEB,E283E2C26174BD25,54669EE079232BB0,EBA70BA031EA7FA0,000000026A501757,1C6448858886833C,F14979708F021572,3060CFD58945793B,3E7F1242A680B0B5,968C1C9949498BED,9ACE085F9EF74FD3,8B4C72F7C953C6BB,C25C0423E2E8DB92,38B75166B8771DA6,00000000E89AC5B8,F6190A9C1B684E74,90BAFAFDA3AF583A,5EE0214CEA506247,F1A62828904C2AE0,88D628DF9E492BDA,A9B8D8D851FB9AE5,BEF4FE74A4618B70,3A862460CF07FC54,780A6C213BC320FB,000000023BE75A6A,6C35872D65DF98BB,F16CB3771B6BE2C3,2F57117CE72CE3B3,649BB0718F4D995F,57CE5F63F88EB1C3,93918FB833D97864,B874CD4B852028EC,171EB4788ECD58D4,085537FF8FBEE28B,0000000111C068DB,DF3CC872D523E59A,EE4C8B8167AF00C9,38B25D20FE9AC4E7,AE41E9C3F3104E9B,1C9C4016F21A3B90,4EB321BB2E76C848,B599202EDF307E7B,5D7CD8449D0F383A,07F8FE11BD4094B9,000000027B122D69,CF07A09D0F70C54F,D0A4568010F575FD,F15EA14FD3AF7237,CC8FCF407B08E328,E4FA80B74AA57995,0F2D611A54631461,8365E3995C6421A9,219876DEE5069094,BA65DB6C9B340D1A,00000001F8EAED0C,5A4B92DBB1B4B278,689BB4A63B1A5D63,8EFD646A96E440F8,8FF1A558E7156CD5,461595C7CF504C27,FC8B4C79ED6F8070,BE9C81FF48D0075F,02A7F915514705A7,00AFF239EFE2B998,000000016C2F9DD0,BE1DEEA6EC39B7A3,A61BFD2BEF8052EA,31A88CF6DAFDE75A,B760F1ADD3985333,48DD9D0A9DE899A3,4E67179562476E5C,1365CAF0D26172C4,DBFA4FDC9A238A5A,C469680217EA154A,0000000006617C4E,39E6B94E08A17363,916593232A75D554,D6A7CA11770D7736,E183610B5F6DCE86,01CE25B92AA03796,758E9DA7BF4AEFE3,7AAA65F900661107,97F2BAE8C9213D0D,14DDFA2AC2CFDC7B,0000000027BBF7CE,6487B6DCE6D171A4,FB823A93975A828C,5B6AE73BDA93CAEB,6F8428F56370B7C3,5B96CDB2A0B996F6,30A1ACA80371046D,96C7A4351731CCF3,82B89983C24E476A,1FB28BC05169BAEE,0000000040F60A3C,CF7A9BD525BE4E40,33CF07B20498D48C,CE09CF397844F5F8,A0A0D4BDCCA6B277,229FF2B196E00018,5F692059EEA58227,7BD02F4231CDF482,761AE566A251DD91,4214F00522F47DC5,000000003C12D6EA,B89EA455F87FD5E3,42FBF7FB7393D840,A019BB0F1808BD3C,AAC9CBF4D72E27E4,D6341085D216AA2B,B7B016F84F75E742,CCE550E3B2B92383,81CD2590F36C4F38,9AC4D9901A36301F,0000000204AE52E3,4922F1655FA57847,210B06BF58A67C90,F299E828A2DA6E16,8B5085221D47CB28,BD75ECC4B5B402C0,649978A2C9D79727,6A5EDE1C0CC43D19,90A1307ED7CF6C5F,E9C4994008F75652,00000000B814CC33,5C1FF6821F331C20,46E94D9E1EBEE1E8,DA7D6282AEDC7A8D,10929600315D4671,C3ECBDC5BEB22538,0EC09750816D8036,7E7B4DC345EF0902,F9758F1BA09A284A,07D89C5C979B1771,00000002463A4DC9,7090877F9854D885,31084946A829C556,6273A79F45C28EB7,D7086169C9BC5016,440E09D9BADCFAF7,339B49DB210FF5EB,E0495EC1F7FDCA08,E67F29B1E9BD0A07,D1978781C694AC5E,000000013AC50DD8,C560E4065E90AA53,FAD02BE288ACCB2E,F940B407BDF1EA48,20918CCB13208255,26B5FE30AAEB5DA2,F5AF830ACFDE6C29,0D2EAD8013BA79D8,6A1E63F31FD7E397,D526F6C062CF5A78,000000007E5D9C67,E37604009CA32E26,C02B9B3FEAD16808,76A1BC4FF65FCC94,4BE4B800E040B6F6,3552A2B3EFEE89B6,41D822BA46C78B20,8E81D1AA901641C0,A641EB9DC6FDE9BC,4BC3078B7BD4B277,00000000D5640902,37C202013E404643,BAB52DD5E4F3E8C2,F112A70EAD977346,4B0DAFA6AB93FA8D,944A9148B1DB4950,302E3A118E146C96,F49E59FD5BD04DAC,2CE3152E7774CB26,F53EA204DCA25876,0000000174D5B4D0,C826DF58F492733C,F245FE342F24A252,9F25158B510DE4FC,2AA6B88D55E291C1,AA2177C3A7F0D5B2,3F32EDAC6B0D8AD2,248B54FB1D1961D7,1F5EBF993F4EBDDF,43DBF5C0607E0EB9,0000000257FC6482,E511BEBEAA7D3865,F1DCD4061215EECB,32ACA3701F3CF70D,A975FD59701A8F60,9B58536B38FB1A5E,0DB35B07B5C9ADC0,47B014A4114E7534,D1587C2A7621E058,9CA234BFC699440C,000000016FA3E0C6,56F559CE632DF355,26D3F45D5905133C,965AB499266E7EEB,D90472F397F8399C,145FBB0CF2D593D2,0EFF82599176BC6D,30D514410D5FEF22,97FA567A5A6177B2,772AD59EA65547B7,00000001F416D202,1DBE01DC8F3AB1B7,8C3AE2DA30CB895B,D22785E1E012F59F,FA82AD24AB0830B4,1112275FF59A3A8E,B5D2684C8A3B9699,AC31346A94D4D9C2,90657BFAE6FF2D41,A2CC6B923EFD554D,00000000A4BED5FD,C65A5C1BB74FF963,249571E0EA22794A,CF53E28C51B6211A,08FB18566AC5387E,FB19F96FDA568AF9,4DDB668BE351EF26,2457E45A6C6BDBCD,62C8348E355F5829,FBB863051739F28B,00000000CF85470B,F2E0000D46338351,BD0D5BD539B776CB,254410486181B47C,167C45AF7FE16AD0,7A2CE07FD4A4503B,3208339676144E58,7C1481FD34277EC2,BC673AC7BE5DC631,83D47C9F71D7342A,00000002372F93E7,3716FF7C8E998761,0B06DAEB5E20FE8C,8F997BD0E6B55442,8F2183C3171016EF,190789E9B8DF3E60,8813BA74332E7FC4,9613DA582CFB276D,63CCD48063EC7AD9,F87F3B6CF1A55823,00000000A30D5B7E,30D52186FFDF16ED,C536BCCFB31C819E,AA2593C451939B95,1AF419ACBBD2DCF6,D4498E1DEDC301BC,B80D17695D0EA461,57E7EF0D3C1B668C,E3098D920847EF29,9B5947DAA8E2BD6F,00000000418A1E2A,2D8F7C8F03855AD0,7CDB80F5389E9A24,6EA0B17ACD6FDF81,571246898255430F,B8292359540B4FE0,30A01152D39648CE,350E84A9B5C2513E,200F37CFAE8F5DE7,6A51FC6C46588BF8,0000000063C82EB4,7C5B346BE4665C81,134982140E3E9051,A0CD5411E45E1399,E264BB0F5A0FA777,01AC9E2FD5A2BD44,9AB9BFC5E4F6958F,16DD6B5EE09C0388,E4CFB5368B542DA6,68614FD689AD3A0E,0000000112A7B495,7C4C34F40FC111BE,CE682FD29226EBBC,85C365AB824BCB61,1D5895BF19AE0611,9353B29D85C49EC1,3AC9A26DD8132671,E2B413BFF8E648ED,A5599C9174D3D5FB,7DED62C2C8B5456B,0000000014D865ED,853F7F132C14CAD7,A8C09F756E92A137,5EC923465F9B34BC,87789BB414651B25,C83CBF0F32B4CD8A,39740D240E839879,1F7DD4C1A7A3EB5D,AEB19848D8268106,7274EAA057DADFBD,000000010F9FC811,6ECC70CBDE81874D,39813012CAAB451B,A06854EAD62AD1EE,3694D7E848860C53,2088E6E298B40F35,DF12F3198F236FE9,4DB836A96AEDBE94,327B8FBB8C00DA44,0BB12A05153B4DDA,0000000179E6B750,2918E9AC3DF4FDC1,1935DBDC11DAA6C7,E87F1B2EB0A44EC4,354D54F242EFFB1C,4081FE0D4DDDEFAB,A0B94FAC32252393,8D999620E35A081B,2FA06DEE0E5EF036,6AB76BE48C9D4C21,000000014D4492A1,9712A255018A5FC0,D24ACD1D6ABFD090,25ADFFD4DD6596F2,67B5BF0813BBE8DA,F84D6809C79612F7,965F91405DABCE54,114D6C340FBFD33D,7CA7FEEBB023E5C6,FED5ABC4F28026E7,000000019115C797,580FDD3BFB83E933,917C5FA6C4C1477B,8C34F1EA30A2CCD4,724490382611173B,AF2E73CA8DE4438A,B375C99573372956,4DEB6CFC74A22395,6FC713D9DBECFE6F,21FABACC37346618,0000000189133D37,4A03FF19271F65BB,DF9962868B61FB38,071EE51ABCCBEE3A,2A0F995F0C8245D4,15F827C425AAE403,4D703CC492261B94,73509F22789F138B,BAF40CCD8B4706F5,CA9159E5B1B250E6,000000001603B620,7EC18AB851FDF5E6,38D7516E88AD2575,6009D233D30C9B67,EC48A6B1AAC75507,58244884B99B818E,C29D763B16D41B92,62F6AD24EE37E29E,C1F587A52C9A594F,96D748B55592B288,00000000AAB191FE,9873B19434E887C3,BCF450FA7AFA0FD3,DDAB08E991CB1EE1,1CBDDBBC1E517DEB,450110F007F1C734,7C2D7F1D34AFFAF3,4EF604A608DD3CB5,B22C94B3D543FB47,99CC50F4F84E68D6,000000025C69457D,362D8644434CA77D,15736D0D4ED9E2A1,4C5B87F0B7587713,60D3C8A7B76BCFBD,49985EF2485E77DF,71BA0B19BBDD0B6E,935632F68CBBA821,1086C6DD5F133F16,249260852B8285B9,00000000F8EAD7FF,B568A1D647B7012F,86057A9D673A111F,6A37822075A21DDE,7AE551E1329D7BC0,AB3687C599AC3922,A1169E36D2886A96,097A3E67DB930813,F38C1BFA7AFE61B5,FA93A01D50794A19,000000008993A74E,11EACCE21CE94CCB,0860E82AF47D4FE3,3A553B24772CDB76,2D13A8B37D884DF7,F1AABEFF4CBE80DF,DD76983F34D0C6FF,E87308F0519CD82A,CD5087C6EA97B4ED,3C567B6D3DBC8AD8,0000000161573ED4,76472CADD9783DAC,DEE65A070909AD58,48616D922751A844,63CBA91FF9A2AE96,95A61BA1EA0B07DE,233B455493273749,00086460EE7FB213,359352C14324A483,52D2AAAE71B565C6,000000022E519332,5A667CEB2B8223F7,6DD9CEFA3B7FB7AF,EBC44771C902C927,8B7E59DD5B85E609,E1362D7FAA4571E0,A3896B9FB2954F0E,34542A0D037AC0E4,3A7B3BF12EB5493D,7C416C1FF23398E3,00000000DA9EF558,A06154AB3940FD95,076AC974CA9A7D66,D3C2613C9D5EDFE3,F639E94F46C7B9EC,88516BE7187380DC,124AA397F77590FC,C665EBEEF9F542D5,B14BDADB5D5522C3,C9C66468BA109A19,00000001AD1C3AA2,2B421888F48556D5,ADF4D6D1B9E22C4F,EB17853895E01B4D,4993C10E47537C92,23D1C322C19DD9EC,E194B57DC47C6919,086986630FC6DBC0,23C6FC8EBB159295,79DC63F5BCF0A7BE,000000008F826890,497F94E0BD2A1D16,9ED526FBAA1B327A,A6AEE4518FCA6970,45B84C578E73CCFB,D41B0309C9D1624A,A493DDAC00A261B8,1137D4E4C2CECE64,2445BB3FC35F8986,C0CEA328C3547B1D,0000000096DF58E9,2BAECFEC7BD4087D,EA37C9001001CBC1,793DE8C521CEF762,13CC0C137181F948,7A2E01A95A682705,C80C77BEACA69927,6634D7730AD75A6B,1BED4BDD6B10C461,74B3AF2591B983DC,0000000054237359,A79897527EE1ACE9,1AF668F17DE2A029,37B5A010C79FA075,B9503AF36C17E0D0,7CB9885D23A96F9F,F5290DE673B39155,A7507B258F951CBB,D09CAD79EED318C6,CD863C44FBF558EE,0000000120C20250,AEEB0AF10D400E4D,F15C5ED8EFBF2097,A3AC59665A7B9951,2F66655B6F875CC5,8C55B22670C1A4F1,1BDEB49A8B553779,CAAC76B4D00690DC,0871C69B9597AAA5,C0871BB6740FB536,00000001D87796C0,50973B597F30C5EB,2F6547D351E1583B,B6283EA0C0129EB8,C2392FFCE194CCFB,FCE44CF803D5D5AD,BE5AFC5E74E91655,F0DE6569E2D696CD,396126B42250329D,458185814A885B44,00000001887337BC,B462645ED26B44C3,012FFF887FBEC7B3,1911ADD52BF6418D,BF1C290CEAFF123F,D2C0C4AF2CFD0799,E3F84AB60841F1A3,8C0F6AF9B3422BA2,8A3933B8514C30B3,F5653184607104EC,0000000018B1BBE8,946C44AA94F80CD7,2FEEA22FB54F8CA6,273BE6B68C780A57,5BE70309386369C4,16296C2F679DBA75,33176D2E539736DC,6898A6E19DF83F3B,17B4099D860E115E,8B8847E6AA2C6D04,00000001A95D4F1C,7CEF5A01211C31BF,24FA854138D21E6F,AD539116B1207108,363AE682378D28BA,ECB742B8420848D8,5EBD4DF69EE85944,31CA3A9DA6216D94,445326C2E0802D28,11DC553428C15C4E,000000012D5DE691,DF73D1381ACDE1F5,6AE872530821EB31,2CC355D279436E57,5C3B92B830F12A6D,287A1929290434C6,1BD8124F0E6A03F7,37D1AD02DC9D01EF,C098D7C6065A3C0F,20BA3E1CECDDF3D7,000000005E70E73D,7540811F1757032F,B017C73BA984C3C8,37B48AEAE82AB26C,36A47531A8FD6D94,9246207961622E58,3BB61D50B3F6BAE7,BF05F8167EA5EF93,FF9F6E6B32D3BA6F,E39B8D9875400A35,00000001C1E6E414,A895D525831436F4,5D7949C54B000FD9,7E463A8E0A15C549,A7E96A4E6B31A12A,36BF442F7DACC812,A10317098563A0E3,6D3E473FE9CBB3FC,9E75EC24B9B90D8F,E1C94ADD404024F7,00000001364F17A8,15224C53A9274C4F,D0E0302C3C987E82,EE80ADB499E22232,74B9F1A994652152,E4FC8F02B7BF6D07,71981B2A20F2FC75,371F7CFEAEF37B8F,8141FEBE5D25DC93,4DBC8C8D55D25282,00000001BD30F949,724049D57AA4A3BD,05EC8B9070700573,B73583131C32BDA5,B230442CA738E321,78052F35650737AA,23C10AC874FC19AD,6FBBA251C3C9E5F2,FF49E8339DD4E5C7,67DA3A5AF04F527F,000000015654F9C6,97362CD540C4A5A6,B356F78DED954013,559595E39107BAF7,37C3B1A6DE029B95,7D119C3723E950BD,90AF2EF799E2FE0F,E08C2048E1D8EC72,97127764A7AD570A,36B9BA99A0C00B8B,00000000B68CCC36,B02C787CB80E5C7F,3BF8B73FA665B46A,F783A5F819D17ECB,A9F80CAD9AE223F7,1F52F9E60891ACE2,08B709E4719C5CEA,EAAEA4613ABA030C,CFB17EBBABE6D54C,5D70C771EEABC1A1,0000000050E40A9A,F9A3F83B0CF8D2E8,7B4F1ADD29068FC1,9FE2ACA4E6F791BA,AB13A55E400CB047,DAC8D5512A702AA5,AB8BBC740D1D085E,D7C66DAEAF4A3FC9,ED121236FCC496C1,761E992D49527A24,000000006AD9A1F5,A4B973016F191326,4EB90EB164188438,CED77BF7F65817BA,29457CCC22A7A349,3A47718688A54A6F,2C379678A4AB287B,5CF90703C521DC43,CC7D292DE6C4CDCA,186E5B7E23D1C5D9,000000019B9AEC69,0E73630AB3213F16,47B925559230E230,A6A72ECF9DBF7C1E,E3E4ABA63D7A7ED1,B4969094E2D3271E,E2258EF0D15FD4F1,C0935740C9D6C820,17A20A1AC785F41B,065936E15B5E3DA1,0000000033292E7F,DFFD43946DF516CC,B3B07299083050AE,77166645937F8D32,CF203F3A5B129429,A3653E3CB7DEA5E1,5ACBDEE0AB92F3CF,FBF07198207E43EF,8A1411550AD98168,E2C343A378C662A9,0000000092BEF390,F2359514858E5485,E130C209F02CA0AF,E8509C5E8668FE72,FD77AA9E55C12153,47ADE91A95A7F2FF,03F4E0BED9FB14EE,662C43ED35A1C624,06C576E9E70613E2,59152E61AB26D3B0,000000014D51D609,3F5546DB4C18286D,5CE02BD4B5E463E1,8E28DB994DCFCB4E,22A83C42CC8CC4B6,11845B7464712759,8C3E328FDE6D857B,217E4215FB56EA6B,CE02C91C2A978C8E,B991E0C878B80656,000000026544AC18,85983B1D6B686ED9,15FA7F02611C47A1,DA8306A04C7E45D3,4325C9E01B18FD9F,CF50BD6C110AE6E2,45440E4B1BDEA0CA,4CDFC2E3FF21F67E,96297A8C8F6E48A7,5927BF4A944D5A12,000000005ACE3A9A,E3760FF303F22AE8,AC78C68989480305,A174E8F2C4C311A3,9D62DA1D5F610D38,B9276CADAC6DFDF7,1A1A41281D4A8CAC,443DA6200BA22D4D,05304FB94D14E948,3E8041BA1698316C,00000001A818BD85,004961C292C8DF00,98937945C2DF195C,B908654F31136613,12B12F61CAF05494,DD9227AD40050B0D,A8772EE71ADA46D7,E76FBBE1DCF62153,04A8E164B470B449,5D6573DF415EE274,000000013EE0169F,1E04282AEB38B300,339645E134D1AF99,A21618D4691B225C,7AE4F9CA9F02337A,AB43F1118B00D0C3,A3E80C13C585D459,573FE042D2CCB9E5,62872742C2A86CE7,9CFD6F3526375B2A,0000000215FAE6AF,4ADA58C0383EE925,7BB971C2FF58B250,99390CFF487D7A5F,D3D44933B751AC66,7E88A87277364DAC,7441300E46EC7907,8ECC023F2CEE62EC,A26526FF2F381EDC,9696B56D7B1483DF,00000002553753E9,1F517C61CB28470F,63C0692C952F9AEB,F07137A2AE5DD72E,B042B45A48D71516,C42B64ED0A0BCF0A,6B8EAC53DBE21A50,3EE39FF1DD729102,2BE07DCA0916CD31,8BD7C3CE96F56F66,0000000030BF1482,DE1EC12CF74C147A,5E83FCABD630EB3C,365DD668A953DA77,DD68BFCA1A3E490A,23928AFF85213678,57680F3048E926F8,BBC9FE35A287B69F,AC00A6D41CE53980,438AEF789C947D9C,00000001534CF441,B6F51179C5FF9CEE,D4963A3CB47A20CC,0AAF6A1C630E1CDA,720B5AB16AC4283D,7E4F25FE460DBED1,13F1F5A4953D9BB9,B3AD0541A7E4E5C5,EA3F39066DD34284,A7CA18223842CF5A,0000000091190D66,243C79EB17374B2A,63412465FB49552E,83752364565BA9D6,7FE84945240EF780,059CF4CD7F9B18E7,27887BFD8E68E6EC,5883987348579F36,2031433CFB539017,BC2B35641A596B02,00000000D7236994,6A2780B0D97BC2E3,D5747E678AF8A2BF,F5E1217887B807BC,11B0CB15588918BD,9F04D9A9FCB3B73E,57CEFB56569263FC,461B0F9C5B5D7A8A,DE43A248F61B7EAF,AD82BD55C3AC0683,00000001B7C51D1C,25F244244BCFE9BC,A4DC79AFAE7F2910,583A52CF5A6E4557,3C4FA90F3C3B9A1A,7010112C557480FA,F0708251D41E89A6,BAF0C64552E09F57,49AB3D5E9D0807D8,B158CC17B4109EDE,00000000D20EE9FE,CFD904711EABD358,3C0D277ACEE7842D,3BD9B9CA90234CD0,A2724B8D87D79B14,6CFBB588F0C45CAE,1791B49389FA35C5,3A7AA40652F44411,600D687DB6EE0553,9894F7C9D0F89124,000000009353A83F,BC0C64C2819CB23B,54F9782106CE88BC,4EA75A1C21E5D48B,41007B38065D87FB,1C3E0F821DE9B524,8A49F2F38C79F7C7,02C77F25375D8E00,7A39367A285ED274,2F2C5C6318C44F12,00000000402A97BF,A7D2B50061359C03,4027C09C9BE4659F,9CA4E93BE9C2D13F,5A13323F6B611B75,8F4E9720367854C9,9EA40456A022EF14,24A87049F5DDCDA9,F5F0DD74E9970965,138B03E9B45A9201,000000025DDF7B0D,1963D01F9F7433AA,DE799DB20CA84897,A1C2C78C1FC71460,AABE2660390909FE,F80C2601E030541E,24D9D8DD7EC37E37,EC3D47AAAB6ACA67,56E9DCE3B1581494,9B550898819D40B5,000000009CFDDD75,B4DEA5FD0DFE6CAD,F850D058A37D2EF1,636EEA0D70AA0592,3CBAE61B3AFAC017,EB00C68EBE91E207,3087045798F75031,158EB16A6C033ADD,36FF561F9BD8B80E,45BC7F6D1AF66FD7,0000000040DD7A62,81E4895F7A0C06AC,C7BCEE9591221BD9,024C8E094068979B,7BE5655C8EAF88BE,5A0C737EBECE39DF,649D28C39ECE6CFD,C0BF9178DAB921DF,71D9766F04AB88FE,3F3D48EE555479F7,0000000251F97C96,7EEB8EEF4900FD90,4F1C4374769DEF40,25F9C1D669F4E0A4,9F5C755B20164716,BFF12B958B74662D,E5635DFA08EA1325,1044725DDD6311EC,6228C0C1D81CE879,08F034B32252C178,00000000F157F7A5,BF48462C64E1E717,426B257C123313BF,D44F11E32FDFEAED,80FC21280F5C8C6C,D9213774D91EA9F2,B6BC2C4970E4803A,B6FB6CFE339D3C89,43EC3732342382C2,F21988A938300F7F,00000000C9708F7B,FD11ACB95F1A353A,019EECF2ADC361B2,919617808230AD02,B686FB92D77D2DBE,DF7FF767F7232CEC,12270C46AB1FB4A2,50C9B0B9EA5C9FE6,E67EFF68ACAAE67A,1E6DFD85181A8924,000000017C4ADCA2,31DA4A3CD6B44CB5,D60E245C48A421C4,1BF6E2EEE97B96F0,23429551FCEE412D,3C55E32BEDA437D0,18C01AF279E5DF41,04F60C607AAE3E28,D3C8946DB3A3046D,7AA2064383668225,00000001516D1ED6,C1CDC01D71A5C8BB,7BBF2CB00AA432DB,75F2FC23F091B15A,10F6B2091A04B79B,4D51787ED1CE52AA,8B5CCCA119B5DC21,E291424914D5EC42,2154C1ECA5C99D54,3DB0B4E7E3A1B86D,0000000174208ECD,96F555900DD52EC2,F8413696B422C19A,CB139D2A9DFE7C19,6EE74685CE699DD1,AF73F4B1E6096879,9C1E0010F8730F59,58B624E9C97F15D4,D0B2B7A8D0FE433D,1C0FBA285C272090,0000000248AC61AE,E6A7CAB617590467,BD7219A467002C96,121AD06C9F5C1E07,3FFC8FEA02AF0243,F7BA1636DCD80901,D11309F94BB25A59,4CBCE4302D26B3CE,23B90C30B7A30CA2,098172A5B5615534,00000001B1166E02,3FA4BEF48BCBEBDE,BFB3938A545EB990,A1F773B30E13D111,8FFC70EE355A7D73,A452DF41B8A6CA44,6A6B96B6344337F4,F636F1FAA8D1B3AF,170BAE9FD7FC6D40,3618BFC28D41A406,0000000164468007,1DEFDF3BD95EEEC9,028AC0A5F88BB338,D60F5CFBB8D37A7F,2762DB25CCA4F84A,514400D703309BCA,9AF9D4C5B0D68BE4,9BD7F93775B13251,319DD2FC71BAE89F,344AF9F728270E4A,0000000028D5443B,DB0B49D41128CAA0,1720FC4EF32CA69A,AED5FF27ADF64175,C84364EE33C9891C,CEC7A4EC02E1FE3B,0F85C6A5D3E9EF97,FDBD60A7581A72A0,48DD7C09DDB6E7B7,CA3AA3C8A95E1BEF,00000000973CB172,61B45E0B00FC6B87,1236B22C16E9C062,2F884377AD8719F7,2E2298372A5EEAA8,6B3F1288A561AF60,3495BC7F089C6931,F5D12BD9EA3F924C,6B3218B01F846528,B0183BD5839D67F1,00000000BF52D7DF,012BE9ED14A254C0,09DC7F332A84FFC0,2151FFF9507C8F46,62C8F5449219207A,57E25A542DE65039,EF21E025EABBBD79,F9F7E1B90142546E,C30143B5DE884CD4,31E03024F6EAF652,0000000049CBAD6E,74E8E8935C318C14,A2DBC887C117C09E,1563640A717CA7CA,352D925E2EA45C71,9332BDDF9B598C8A,5054B132C19EC4D9,3DD59D8A34F5DB12,CDBA34115C1E9701,8F535AB78A46EF33,0000000231A81B81,6C22B31EA5CFA62B,CD52E7F7509673DC,99DA4A4A395B501A,EF0678F293B09E1C,073420274AB9A442,FD2F89EBA34241BF,4FFC600C40F3BAF3,07603FD3D471F59E,71B59B453D3498EE,0000000034806525,4FFDD073298B1916,29F3CE50A74C90D9,49D75A69860D16D9,F10CE4FCDFF043FC,E15E29C20E87DC43,DA9348690A3CFFBB,98206160A84657EF,B90BD5FBF67E51F1,E40DF795C9026C8C,000000017D18623C,72807721D899DC6B,D4F078B9F3450EF3,DAA653B2E7CD0943,3D7E2F2C6785BDE2,4A236A205D2E1627,31079ED73639BF72,BA59754C3D6F585E,0A5A1B174511BC04,8759CFC507AE0B5D,000000021748EED3,DC6479DA2648FCBD,CE21B846275FB210,EFD70DD033EADC47,E4ADE943E5C02C3D,A46F13FC031BF645,DA57862A9ED16C85,0DC2CAD2F2D83E44,17E0B076DD5F2106,39D3C87D0F24C8AA,000000009B510DE1,0955B6F29E8C194A,64F5FCB400B2047A,ADD5780B7FCD1C7B,5D64A9AC1EC7F19F,B02BC3A415D5DA49,737F2294BC52AD1A,2D0498BE9126C718,748A7048D0D04204,D319C5B6FC0DBE31,00000001AE2D1575,F86834AA0E05D14E,98C66A36F5535778,838A4125555E3CD7,68FDC0C0BAE88D39,FCAEB70DEA8A645B,736963889214DD7F,0385F4A941B5C5FF,2E7E2158C62DBC27,C51547D0805307B1,0000000134A6D768,52D9538070FDFDAA,825D278DF40F5EDF,C8B267C5296539BF,46D1CA0432C83A3F,043B6AF04205DF69,7450041135819D58,946BAD35B93B5226,88E40BEF82049CC5,C6E4FBA91C1E3E68,0000000228FA1B34,9C77AAC15F145963,52586419508165CF,BB98F5FD1912CFF9,0721C196B6E70756,D65C8DA183F22AFF,5EC937408FEE5632,90F8FC3B30D940B9,3C1955474B3CCEC8,6E2E895C2988593E,000000008939B42B,F9D53E8AFB76C683,FEF06E1DB293D7EA,7576F191A7854DC1,2DAF3AFB2FB43C01,D2EBE54219C1F973,7279CF17DA144B3C,C95ED9E7C193D039,667EEDFF5BB14B00,EB30329257814627,00000001BBC3D4EE,8814D9F7DFBBC82A,C2CB0BBE1D246A88,9E82F817E905BEBB,C6E0310ECA2D23B9,963E29BB28096A92,2C6AA731BEC9DEE9,B5565F5B44466E96,DDD5394EDD07EA2D,53FE43DE481B6143,000000013071DCD2,2FF083DE8E826A03,E4C34EF8107DADE5,097CF287704642A0,355655FE67666B5F,6E00A737078FDE16,5739EECD7DE306E3,E88970E868FF6A86,E32E3FC6E5A70F87,7FE1BFCF282AFF48,00000001F496690B,F4FCBA9BE0896FEF,6B3BDE4C201B1607,A6C0061D0DF3DB6E,1B26B0946DCE5333,DB0E84872FC03445,0390D64FEB06615D,D13855127C2A422B,BDB84A0BAE0805F1,40D5459E2427CA2E,00000001129C49A4,937572C6DF592DC9,43B0960B0A2DC959,5953DC9C04676931,51D94EB5B2DD56AC,D5A2800D76893C37,BC91E02BABE3DFE5,E7C20AE57F9573B4,BF275BD666CD2553,FB99A6B6A0664B02,0000000227CC370F,BCDDCC66BDCCF98A,A19FFB10D1562C1D,8512F03B940CF37A,177088BAA63B0785,1713ACECA30204FC,6E49A8E65B3857B3,4C8CB3D1B5A32A27,DDECA0AA2061D542,B87CF82B3B47ABC4,000000024B08400B,3EC6D8299716054F,97DB0E4C9ED6F115,D4D8BC0E39C5BB01,B8BD5FD734AF2E2C,E16155974CEE9646,34C46065D48230B5,73923972AC2E40FE,A8E10473008D35CE,FDB51F3333FBD106,000000004E9CBF30,473A021577C340FE,8E8A150640337286,4358A52F95C37FDF,2B1DC31EB3ACFDD7,4A10D5F84C7E5A0B,8B719B448F09D0BC,8CA8E1A180588602,BA8DA59A3B990746,6774F0DDF0E2FD51,000000005FED4B53,6A40E24E1ED50A9E,6FC17650774C105D,EB9DC5DAA5A7C667,AB9D448BBB3750F5,FA225E4317FDE0E5,352BCCAE69EC2DAD,7D1CF2B4C9BEF333,54937DAD74246052,70C3AB9A1D240182,000000019EDB739B,F572800677A7CE76,DC08C5AD6FDA3F23,0D05B60B39C26360,B6AA3670902FF55E,332CF647268A0F40,E568E1001CED09F5,B109077D993DB2D5,57969F9D8994BC87,0B29BFACDF494A06,00000001FFECDE22,E1C29A5533E5EA9A,84BB158A4F97E083,16808C717AFFC4E1,A5FF67312C99DF59,FFA5EBCCDD736B04,0172C91A8AE31F02,D36DD3978EF3E377,1D16B8F2DDEFA73F,3F91D7E9CA3E8C55,0000000176B808EE,A5E700DBCF4AD3F2,7B72461C041E1355,A488A0EC6E16A3D1,535F4D51F2D274DD,91DD301F517BDE6E,EFF888305D4FB20D,421863148A27CD50,DC0A7C552A51EA8E,E9F266122A7AAE2D,000000011A0CA8B9,0982109CB9ACEEAA,D32EC1D675CF12C1,922568789077CCA7,C5697177FAED35AA,C49FAEEA3010B74D,47977D69D2FE3261,B3ED220AA182CC00,D57033D5B0FDDE63,D3E276A313C0A9E8,00000000A908D296,6EF0DAFA3FD500C8,F5358726D2F82D85,7D5B690A5C904302,9423E4F2B82FB98F,8831428AA9CAE1DD,A5B535A13BA277BE,A7A6C1728C1EE20E,BB3E4A54C8FFD6B9,63AEA2B17ADF1541,00000001B848B1DB,20D5FD0B318A081C,A13A0E0071D3D63B,617B7F89736D448B,455213777617233E,D5D24B509A07A7FC,9FCFD1028A1FDFBE,C1F000E02C8868EF,09A5BCE2DDE53506,B4682B911D1C0E9E,000000012E66C04C,CF18FE4E71C2AC90,54F1BC9A2AD30CC7,B18E88DD70495FD6,4B7F2C8ED4AEA355,1CEB34AD604F91A9,2D0413367BA8B477,C909291D61080F72,0F72C14C66713754,7B4E416B0FE29CDC,000000008E8A5AAA,D5EBE47D3602F9C0,3F3746221BDB0257,51A638EADB8D597A,6D58BCA215209851,9CF2A664C70255F6,838A151A832F74A2,8867B81A1E9CB503,475CAD793208D5EA,0A45494A66A0D2C5,00000001B63C6694,1B18385D5940D783,3863220552590A82,3D6232D0CF4371E0,802C8E0169A1832A,7E0F887FB27AA972,6151FF48D2ED07CB,EB35480DD5E3A1E2,E2C0FFADF40AB456,C37DBC178206CCFD,000000020B4A81A7,554D409AC7F1B1AF,1DE9DEFAD55BEC9D,7EAE4E9AB052E3D1,3C8ADA7A8040F7AB,20B852F599C57081,E6844DBAA844ED18,6B2FE15C1A7BCAD1,4C7AE6E323CECF31,14A67304F64B6742,000000007B838C39,A07AC85306BAF5F4,E31EFC25138FE8D1,1FCEE278952F79D7,4586630819BB1C60,6694EC65AD0DA24C,2348902E0DB2F68D,4759987D721E4F94,7DA90033C69296C4,ECE2EF8ECEE44B3E,000000018712565B,C79AD326332EFC0E,3C860CBD6881B1B3,53B59D7F4F539E2B,DEDD1010456BB89C,768AA53FBF8CFF14,D32BBAB03F31D3C1,FB9FCBD4FB10EBC7,67F5583E203B3CCF,EC1126A58028889F,000000015B29D068,356A15651691B05E,832A6C76AC41AD1F,C2250A2E5BCB50D3,8B2FB61D67DEBFE9,F8C1758B59EB19B4,082B797A180FA9E4,60825BBB0116D0B5,5E0EE5B92ABEC129,CCCFED93B13BC579,000000007E0EC274,DB046C293AEA271B,835BE4DABA06EA43,C25701F2F68A03F2,EFBEF4154F5E2259,BB3C1AF9D3672EFF,D557B307D603E2CD,0A97C97300A3CCFD,6D65A4B3497B8ED5,AE3C98DD89B43AB7,000000021B7A1E21,DA0AC45F67F9B2D0,61AF48BEF802BD19,4F2016171CB1069F,3CA32CF426D5B105,3834BFC4BF2124C2,F9C3130905623FA3,D7E1A0522D848417,07BBECA5B410CA23,8034FE8E387621C8,000000026178A0F7,B90565A9EE1BAF4D,CADAB3B81D35E5AE,B38E4526194A12BB,AACB88D19D39FB77,01C0A49A339B0470,C5335AE92E401BD8,5BFA0BC0B87CEDE7,2D29A5EBC8EA721F,A90465C77FCB4218,00000001C37F8929,3FE6E19A2A99FB15,F50184C45B061844,6598A910127CFE94,AA869E3AE7A1979F,B55BC75F09B90968,0A4DB11153B5620D,7B3A2A84723E4DD9,36DB51066BE3CB6C,BAE5F831A1D20503,000000015A6407CF,FD2FA85335214AD2,D6732075F9EA32DB,8D27717FF14962F8,362AB12136EC3E4B,1AC4ECF3BD09A270,A7D4381812300D59,BCABE5BC1617E447,933ABABDCE468CD9,25F90843F0901B95,000000018A6F1C9F,941E9C80C87AB02D,2FD35FF87C99C57D,3C17917FE7157817,9E649EA5A33DB9C3,8B376754CE3B278D,9A437036AD32EAF6,E21C97AEDFDD507F,F2812BBDB2743DA7,DE6FAF9215F87127,00000000E6B4792C,1FBB8D0575E528FA,8C1771E502CEDD12,DBF8830DD5CAC0B3,97C456D0F7861FCB,1F7B682EEBE8E94E,0569413E3BC4204E,8338445D86F2142B,415F44858DA172E2,6E22A1BDB4D24F44,00000000A60F8739,ECF2C66B06EDC2EF,3C0382BD7B2412C7,E7625C30CD0EC847,62C8C34C44F9D886,C8480EEC67B2CC55,848511B8C2821316,D9879358DF19D954,53B02D15A5C5727D,17EC8843D67A751F,00000000A9449D40,E5352F169E11CF62,E9DD27FEEE300F85,38E2E011347A4AE7,6FE47907D0B13423,B5AD738DB384461E,C6A1F316C393B8E2,8899AE82B492F28D,745433BA706C6040,FDFCED953C61D76E,000000002F440B3C,E02A8AD5978FE189,95A607617ACD191F,4F4906B0580CD6C7,04BBA52EA756EB58,BB8491F0FB83B785,EAAC49C304432D7A,CB19C9E58B1393AC,A8BCBFFC5E427E7E,72969F53F813F0DB,0000000095FCEE14,150E515FDCA7CFC2,CAEBA4EEA3A01F06,B7252FC44AA0D2E4,A9810C2BE280795C,3E0CE076E85CDF73,15E7AA713F4125E5,76975D8E9489767D,C42A874659DFAD36,5FDE3A4986CD98E4,000000025392EEDE,F64A87F7B47ABCF8,B79FDE75C44F7826,9E70B42083D7A832,85197E42D64E6ECE,A055FAC2938929C6,B50FA6E1EE8CCC77,B8306B8FF2FD937A,4837EE9B766287C2,D4D1B298DFD29667,000000025B6DCD71,84631EA25745AF7B,CA94C008396445C1,1D8547B4ED963E7F,C7518A3581853508,DBEB06F012C170C6,C5AA3D74064B9862,4DCDE2B1FBF2D43F,A6D9CD66177A4BE7,061DC31979EA9948,00000001963ED61F,4105B546D2C72480,1B3F74D465D2676E,3B9F04EA1F45ACBB,7552DCBFE8FF2B1F,0B866A41969681EC,BA57AB6F40E4E2B3,5CF871BE9A5D0DD7,1A4402E48EAC5981,65DFC3A4E0E83CCF,00000000695D72D3,617037871D2142D4,307AD127900F25EE,C35BA40D39FB6621,AEE79B91DF6C7828,FA694CD0ADFFC5A2,48CFD2A11015B7B0,A2A663ECB9AC7DBD,29A3E936889554B9,81BAF76085287EA6,00000000510FD7B6,6FF85FB69607C73C,4C01005413B189AC,0DB5771FE990D779,679F832EECA8A383,3B36E4D394D9895F,ACB483268D69C4E2,D01306C3B961BB55,6234F3275E1BB37E,5F1464750F703E58,000000018DFF9A2E,9CD90EE4ACB60169,8A1EC1280F5C13A0,5874F2DE5A6FBBD0,44A7469F316C0475,7909029D86BC3E66,B35899B1C9E245BE,D278C5E20443AB1C,F2D794969C0FE8F1,71EA5FC4E69A43FC,00000001EC87C61F,BBB52C69126628F9,6BDA3A1D686AA6A0,5B1C35B69E1CC8AA,123CC213E1B957C0,F941B92F33C93440,C67D44C4A51B5DE4,69E3A656A7A2525A,CDEBC28CD39A0778,4F399B1C596AC243,00000001B52621E2,788206EECBB9910C,242EDB7FD5E0EE53,7499657583946FB5,760341828B0AE0EC,066135A13E3E6E36,7BBF2B971992054D,C83BFDE586A36774,C3541CCAC6788421,55908758BE42AD2C,0000000191BD24E2,827C2C20D45418C0,32DA758D2662E7C2,6A8F37182D6BCBF4,A30E1269FA7E45EF,850C89E069D83F00,708DCCAA9DD42B3C,D5381C6E2E7AD4E4,8CF71BBEF7E9F2AD,1E86B476B650AA21,000000003FB3B2D9,1414FB59FA53550D,957897BC85A43623,224FEEAA789263EE,DF4984DD999F9553,E54E1F036D2B29CD,25578A3B5000103B,99F2AE7A8C71F32F,D8930EF43FF352A8,22EA9511E164FC4C,000000004A75CDCF,6BE6C670C544CA6B,2A61F34DB83D3441,09F4EF5DD65EB809,9A8427450CE2168D,80AA0F54C280EEB0,CCFBC9ECD131D97C,FBB54569B880A6E2,6FCCD3E253828E73,C52223E2224E3449,00000000743EC58F,BA69252DB3760A24,1BE63FE146F85648,C3684E4B3268AF94,F9770942C7A4BBF8,56C3ED27F32F6C20,35406881E46FD53B,2E8E024A90285C71,D08937C3BECB963B,3A58B89FB9C9702D,000000001CF29CF7,E92EC1C9FDB76BAD,B917D25CF07D962B,52943D6667C5AC1B,00F32C5C4D4B1533,4C42A37AD86455E0,ECB79935456E11C4,B7456255776B4B9B,0A4BD9EF28CB8083,25B41186D869CF91,000000017F1B4A85,BF97725559A36FDB,9ACE73E22CA1F0BA,AEB2FD0C60C0F4E2,83C4279989545290,344A7B929D3C7CC8,BF1F8078FC9A7A23,9C953D5DC3B956A2,6DCC7A5D3F44C3DC,07EBB89EA7A5D29F,00000001A51E68AF,B984FCD28FCA3476,4EEA5E79A80CA2CE,549FA4B1C759CFA1,1AC4E5EA5DFC5BF4,BC9E86CB5DC87390,14D8CEE37E74E328,278DFAC5C8AAC784,F9468C4FB7E8037C,DED39DD735E66EDF,0000000052C14940,7C4F82CB17179220,1228925389C50F4C,AF86B881B7219E21,FEAE99625B19B697,2CB81B8CC40D9278,40F63AFABF0B4964,36FB8C658EF0598F,E10B28F299056023,63B8968301FFCB71,00000001D787896B,136C28F24580F6B1,D4CDC8C3ED2232CA,B6A3657D33FE66DD,A6360BBAFE8E5A3D,C1B743DC7E11CEF7,403637F600DD1EC3,C9F86F9E846E2FA6,C3B5E7AA692A46DA,18D31DAF80CB80C3,000000026EE55097,CF5429DBCB2AB83B,DC489B3CFBBB5D4F,A9DE2BA503C8722E,0D81E21AD3CC6A62,5F189F98FF2CBB3E,E0BD9EE414511FE0,F1B26BB9D9F31D9E,338AE9E6FD3C83CD,27105679F47C38E4,000000001F852991,90AB0396ADC2001C,4FEBD33E0F53B28B,19B90399E44CCA8B,1698AD1FE449D468,72EF4EE1C4FA615A,EE52172150145D36,BE11738B731735AC,406253F19C5B8556,44E7E787DF738B23,000000027739AD25,467C663A0DD96386,C69A25836D36F651,7F9447CC0E95504B,6689C0D1A9ADF314,FEAAF01DC6B341D4,90BDA2C04CE5FBF8,AF0B04FD5C62FB29,E815720D85A14ACC,614F017CDDFDBADD,0000000099C8E49D,EF74773BC9755A17,193C0E73866B538D,197A8C5667872BAF,27E9A48ECB98E9F9,8CDB9A153EC51084,4B48DCA557E08BEA,93D4BB6E1A822CA8,A1595580F277E342,F1440116FDAF7FED,00000001AC334070,26083CF7DB3976C3,27489C2950E004D0,60E18DA49121CAD6,07D52095FC270DA6,594982085D22DE3F,C5103FC8F10E54B6,FD6DFA48FA55CDD5,EA97E68AA8CDF0CD,B2889373FF7B1CF4,00000001F727A5BB,AB034231E8BE8CAD,6CF94757EB33FF3C,728A67E1359A04F0,16955DC895C017EB,853226A8732F39AD,7F740344EE01D1EA,BC61A6FD0DA0644C,BD7C38F5ED238A68,F3BC7F8A71CF6053,000000019CCCE7C9,F231A8B787626EE1,2FEE8087A23AA739,E2CC49E6F3A57A94,B94A13941EC5C369,BF301A2D54D0AF96,1B4C17C51BFF6D5E,A64AB9C38B8E1517,23098DDB7BF1B82C,0B3008A2E506885E,000000021580113E,D06A1367D8252EEA,140E3D9EFC9310EB,F3BF85A88A3E10E4,350FA423486C8938,6EA19BD4EA338715,514DA43AFC34414E,B1C45910EAFDA6A5,1EB206EA5E7D260D,B869CCBDEE9B6E13,0000000142C06E67,38C6FEF0362B68B5,AA6E3AAA60BC3A9A,5C7E887355AC5755,507706E629B11542,DEB9EC7BEF8C52DF,FA90019B15FCDE5B,A50AA3F7F820BC11,F57A97722D4F518A,7738371E22DA5EE4,00000001A6DD4560,38097C15CDD57F1E,C9580EF2FC1DFD33,18D75C0D13051426,182B90CA121BABD3,571F0B04CED5247D,6F15F5F309C18861,F333E54C2DBD5C2D,34E5FD1B505DEDDE,AC6B92CADE9F5208,00000001FBE83AE3,EBA3C21A7BF99F40,266DEA196716F3B0,C4AC9CA8200E2CD3,7F48BC3A6D3BBEF9,20809AFF69E075FF,C351202006B4D9C3,8932651DC5D22EA0,057D8FBD81D9ABDA,C2F02346D036391C,00000001D43860C3,FF1BCBB1CCA4656D,AE520B958BF5CB0E,60102F100C8F1412,0539FF6441F566CD,8908CA20378C8306,EA5FA88EEA79F7B3,A0FD46F9823FA3D5,CBBD83F30AD17CF0,73977D82243D25F4,000000008A3ECF6C,1CE6D24E7B2E6F1C,8A7C7139A5AEBA29,D539523B55514BD3,D8252AFFF2DC2911,592A41077E3DD4F7,A69BEC085CE8742F,1F6BB0692994CEFB,6E3CA56BC404485A,45929630AE192B0A,000000016D17A382,AE5F7130B5380107,AF23AC1E242BB89F,5DDB83699918F166,734DB0011928DA42,CBBB2C2C1824B539,B94622A3A0E11E7E,5F120C1A6B774C88,C915010441AD0792,041637D60B08F496,00000001A6E62731,40355A135D1BB8EF,2DC3FC1F6EB43CF4,42E7D2E956BA302A,5C95B5F46030A0B3,39A5BFB8941B6A8B,72A2AA864F3488BD,30D9B7AFB3AC6634,36B7829578CB013B,D934BA1CA03D3CDB,0000000206CB4F20,234DDB9A76D485B2,B8E8F17ADCF91DBE,5F525308CCB55E63,8F006CB42AAC2DA6,9C3A1B278A597683,7787A5655F2570B4,414955794F1519B3,7D640B02FBF20047,D399702FBD939F5F,00000000FF4312EA,A9AA8013634DED19,3F18C82F6806A626,7BB075BDC2FBEED9,D29791E225839DB1,8921636AC298DA9D,251C30976F6449C8,FFF5DE58929C36C5,52B10E03CC7A3003,758B5992CB483BB7,00000001C9FD2939,D6C4B26CB394D549,CCF36D1A6B6DD4F7,FF4910F4324DB0F8,DDB39010BF9F57F0,C956F9062DF39C8D,3B03604FF4D9A4A1,1966A786A4200C55,1575F76682A4BBAC,409F80D6402A9E37,0000000262D3AAB8,8D938A27E4CC1261,54C53BC936812937,A96D5C22E33EF961,A7031A1D6F5ED722,DA5E7819C1C69141,95B7C3EF142716AE,D5DA4312477D6B5F,E2A0E8D3B4515C65,A35078E5AFAA642A,000000009BAE6E0D,1E18C8FA194D5FB4,977A4ACDDFDDF51E,DACF4A479E536205,59B8A280B51E26FE,2E5CE0354FDDD0A0,C2D2FFACD5248F01,3EC14C625703F82A,B382F35D8DAB5A43,CCC5A79428D495B6,00000000E25E3F73,835D58ABDFEAF3A1,0DAD0D15DCBAFAC2,13B3DC0E8FC0ECCA,CA9785B621769670,70AF28378860C775,A100831FC9BE2EF5,E32281F0678D19DE,9C048954770C6E51,412A3B98DC6DB452,0000000023024006,3C4A5F7FDEB21C3E,73E624517ED4DF52,F8909EBFE9138211,5CC37E0829132B86,853CFE53FBB701A1,D2185CB45A7E58DD,55D809CA02D06E03,9A30CA3E89C984A7,3225287B66CEC6D3,00000000AE336D56,209F4D8EB790D40B,E1EBBF5E5B8CF887,79DEFF03BDE90303,705514AC0E240F45,1C198A8A5608CAAB,A6A9EBCDE2B43512,7C7F97A17F1447AA,847352AB5EF87D13,D963C2653E0D7B3A,000000006B9FEB26,81B9225959C3B540,EA2A328C7F833F11,E1F16AC5C1C00CFC,BF9E3AEAB17202DA,36E5C06B577EBD88,148275970FF8DD4D,8C6ABFEDC4EAF31C,5E83AF16EAB43677,7AE2BBA911C1902D,0000000133592EDC,F0BC87A75B0E3AAF,2AF8C9208B987FC7,86C5CB3BA46D0CF6,3DCFC4580193E513,96CFB0180D97CC36,98B7AD39A6EE9DF8,D15C1BD95A6004ED,7C4B0758979DBF70,4126FF74BC337976,0000000013E62E48,674A901CFD5A91F3,FC9E9B4E21029A0A,74EB8C1939F55E8C,1160888CCABDFE7E,DE6CF0A7B2822514,464E8D3439E42B64,EE105EB075F72A95,91A1B92AF03A136B,CCA4FCA1F89F0DDB,000000024E18C0BC,D106DF3173908463,96DA1BA9DCD0A276,91A3AC93F9F5D2BB,E3A92464D772BC9A,99067C5450235324,5BF47944468A6822,4D6849466B901E74,6C7D85C52089A994,3E994BCCCB23A00F,0000000086A2E657,1AE18BBDA4781C26,18594D2CBB03DA66,75C90347AC3EEF27,14CACE6D44CCC261,86AB043B935D382B,A1A4535BB69ED110,E48814E15FB72CA3,9AF2EA6E5CEED10D,CEBEC2FFE6CC72A2,000000027B2356AD,329C561B293A2FE5,DF5CBCF851711A37,0D6D62486779AC84,F77AB6E896E5775C,800FDAB799F05030,48FB567E94D63742,4D86EDD6202DA682,B977426DA8A6D236,4D3284706CA6D48C,00000000818B2770,FF95E74D31370725,A6837615D2624E93,517A218A46648398,F83EF4FEC49C1A43,609C2402C9CC1164,2003DF9685AC32F3,6F02694C34170174,9281C7CD91BD73FC,B1A2E59B055C3E3D,00000000E68ED009,F882C5294668AA28,67F5CCBB8681042D,60828CBDE600B837,2BC99DDF0B9FD566,DB555E24A49DAD97,EE4878BA434C9D41,8D389062813CC310,DEAC575C2413D97D,DCF061BF7778993A,0000000007E68191,EF4991C5060E5EEC,F78367E881764DDD,93220D1305AA4A54,A3332AE0A23CA9D9,4F07A1114EC601CC,20AB10C14CF6D9F3,21686F9A6574A4F2,909CA17478B0E1A3,AE015BB15B6AAFA2,00000000FFCA1CA2,028B9C6FA7AEFC3F,269CE8B984D1C2BB,0E0CC22EA1D77E0A,69B10CB9845C0B95,BE8EFFA0CA8A296C,108B2D8FF31361EB,7C85E29E9DDEFF1F,466549F6AB7E98F5,ABC2BA8301119A8D,00000000E5351AE9,B60B108E5F6E337F,5E2867ABAB422E46,E2512EFF2C332D69,612A228C83593928,3BEBBF314507D3FA,6853C58018AC76B7,0602C25CFBA985BA,4B73FCB7C2034B78,4AA97038F62412DB,00000002666113A0,89AB5D16002CA605,2B6D75E1C44D646F,8F1982C5A6791F61,AC1EA8457E76E188,A42BD5852684D25A,45A29C8888D7EFE1,37CDA92BAA8E0AAB,E501539F31962FFD,9C1D2C1922179327,0000000256CD40C8,A7108EA03FC47CFA,686B68AD8419166F,DDE51ABD13CC5753,FE110EB93EA367E0,720EA6B7C5903265,A2A2C739249579DF,B8C6D7E27AAEAACB,DD049A45424439A5,5CC9DA515D585AA0,000000025F5FD9AC,02660872AB477C18,2597A26754B544F2,8DA188E38E09C05B,D705013989F57666,51B6CB93C06075A2,88A9C622F29E10BA,4746FF3CB7675C7F,47883A93C4F9CB94,6D351507898B4C76,0000000115164B40,AB95338D582453E7,ED828FCB9FBF5FB2,2217F0CC228B4B74,2A6D8355342B5100,9E47E3DEDFA06739,71CA656B46BBF9B3,1774BE9C180E4781,551BAEC02E5BC0F7,C941EA28E5A06D92,00000002583AC854,BAAA0D1A284FCA6F,84DB2D750B0629D7,2451B9BB8D3513FE,73B5F36F49E10CD7,1829E08DE8C72B21,840A51EDDAF9B172,0B40C8F1A3E1B7F8,38E027D2A57F04A8,F16A1C846BCFE4AD,00000000D7F3FC50,77C636D6C891F8AC,6F1DDA949A0491E4,7C3F38494B8A0B83,D303A43A607147E2,E6C7ED213DE0E0B2,7A335487EF700D1A,2C73283F546E1CE8,323618F2F269A259,6E5BB89C827AC751,000000025B1E910D,3C2174996B28FCF3,D80B5BF2C453110D,25E0CF8188FEBD9B,56BC570B5C92AEE4,CB56A35D8DDDD4D4,C5893B5AF89D9F48,DD1E181DA7D3A6F3,59F4020859254D10,D5DF6339E5B9AB65,0000000153B4FE64,DE7BE6D4F4060AC2,960ED9E78FDE56BF,5994C960CD018D2A,C7BD7027E070E352,A45EA16306E67EBB,BA9E977BBC653677,9A18BA4CE3B5FEF8,3AF6820B4E0A4DB2,9A2EBD1E90259D37,0000000052CF44CB,52B37529240707CE,25F995100D641033,6F8C4545EC8FBF1F,6BC8E2B1108CCD5B,53E11D39611C5925,49394DFDACB93D19,B792AE9800AE38CA,BE9F9DC868EB81CE,95AD2E9241F8C755,000000004F0B1D6F,8CE5C717B783DA15,A147F7B67A76E2C4,0AF84C4A1D37B1A4,18342B9E3B220841,F1AEFA0681B2DDD7,806667F33E934747,52DABE8CA3C6FC64,5A7A5CA72799CB09,AFB8E896B34EDEC6,0000000059BDD269,93757CE7DED6E353,DB99E4B5CC217C4A,14D0A13B81F7E955,3710DC8B93767FD3,FE215B832169A1B0,A8D4B100CB2BE51A,D8822EBFD11E9136,909CA3DF9AED3C69,C919DD823B68398E,0000000211A83A3C,D2A28AEA5891415C,DAFE5FDE29107EE6,3A5288A84A5FEE34,D9D04545391CA9FC,878915ACC30357D9,14FEFE0F77AFCFD5,F7A7FFDB6F2380F6,025AA54C8E601A16,0677594E51A8649D,000000008E5E3C89,0207F3528C8895D7,1D20762E75C2188A,32DEC2B3A9A13BEA,73B21C8978757F2D,0ED8B163D536D55E,776FB3E31718A735,353C65B30522634B,8AE76471B6F572FD,052AB3250D22828D,0000000096A94B5A,663F604CBF28BDB1,6684162A6BC93640,BB9D44CA69ABA1AA,FFDC95CBD2C04CD0,C68CA042DB5F1519,4A1FF8E3840B410A,E79347CA1923E0D6,C53689529C006FDF,699313ED98BE11C3,0000000262163319,C26DC6A07B301084,ED32E6D0746420FB,6CC3C43CAEB07407,ED1143C0ADD3502B,C40A687569637196,B07CF2032771DCB6,4EC0278D6A9DC588,729E3B6E2CCCF5EB,E0D69FD70D8E4B4D,00000001380A2F03,BB85B88DD727BC89,FABE3F94C0C7BBD9,2BA93AA9F8D10753,9045A614B355FB92,9B5F6CA304310C24,20CB6189C632CD68,7461EC583EA6CBA1,FB09C4AD16184D3D,C88FD21D377E9E40,0000000232D983D9,BC511A126DF8ECF4,44EC75D449106A39,095CFF95C33EF728,41673B8E00C96A8C,01008937EE5F4A61,379EFAF24C18DEC2,385C0CC2167ACFCD,7B584C10E8194F9A,C8DB42E6BB5A34FB,00000001C2240248,06FCF1CDBC4CE0DE,227CA6044D9D448E,AF541E1518DA3CD9,3B5D17B82838F1ED,348B44D94A5ADF0F,78D8CC43E7B696FB,242E71DA22E60EEA,46BA3DE7C2462387,F842C3DFA3C38ED8,00000001388A1C12,10D4294391911D98,F9A3A43C1810F165,0E5BFE5857A190EB,8A8370D56AA09629,18DDC2D1EC25C867,392D2D155CD6B337,2A534F502B6A3A5D,A2C03E572A992FA5,2536502689888027,00000001F0B44B2D,DF4847A7B723C6C3,F57EBAAC3CC74C18,F0C50B25312EBC92,FC769FF1460EFA6F,B216BC1B32FFB7E0,DDCBF7AFA070A4C8,F10C435BF48CF457,9E7D9A24DFB3883A,E53AB12ADDC97CF0,0000000150386841,9D7FC4D0DC4FC5D5,C7670B345EF95B5A,FE5E9A1466B379B1,F3D4E53BFA18541C,844B042F7DC57DE3,A62DDE85DE4B942D,43A716851B1CC18A,25FB0E9F5FB267A1,C663428C954D191A,0000000171E2B061,158F182C364C7707,0F29EEF92C999BFB,C280184A4A37F648,9F084BF7117093F3,1F6CC426E1AF4A1A,65AACF4B2B5003F3,4D7BB056D3BD2E32,EA97A35CEB98E3DE,68B5BB28DEB4EE54,000000004A9E17E2,2348CDE5C6170F55,4169745B2B7B065F,BBF0BADE38CBA961,355D1D0E6845D101,2D221312152F1B4D,8D18ED93432FB0B0,8BE381A20659ABB0,34059802E03E6ACA,77D5C79D900752F8,00000000F26AEBD7,BDCCC5640E35E052,FE491230B78C145F,E07D79CEF1C08B4E,57ED8608327D8441,6F303925827766E6,2935943DC6D0BD4A,1924B90374666255,F9835FDDEEF9B6A0,F0A2BC0DBAD1F992,000000000CFC643A,B4E852E7AF6F7735,1BDECA127BDBED80,3822E189FA417BBC,1117EA3CC65E072C,02FD2F688CDB827B,F8D77677BC61635F,B472A83DA0C6A930,FB259262818B28B9,7590016038FC422E,000000014060D251,51C1917EE725D179,B11CD192A788B5BB,17C0D0F0A6923E6E,012C03E94BF23FBB,2BC3D64E5F23FB27,C7B34D1665B611B0,D4E77BBB9A3BA0F0,170B60DFB3F630BC,3E0704EBA1B69AB5,00000000B0B12A19,24D5857E9F5C4283,9A31A9D44BC178D9,8481E9B16172689C,FB53EA1BD98121F5,578F04CD7D8E87E2,1AF9CD2A21B12B1A,69F77B9742C3D3FD,384906DB5C567B02,BA1548BB3AB06145,000000024744D36F,5980E364BAEE4613,7D538BADAA70EE1C,E2E84346529E101A,458846B067CA3A0D,A7B753EC2CF34DC5,3B8467B5D95243B9,42BFE280C6AFE054,608AE48681907FDD,E4B3B971B32B28A0,0000000265A851FF,5F257E96D08431A0,F2813344E56732AA,4974DC10407D0EF5,134EB79CB5F722EB,C2F51A8D8F8FCBA7,D2997D4CA79DB6DE,3930AE758EBC0A10,86923491D03AF0C1,3A0A8EEC99C5F853,000000003039BB5E,B969E61FD1D7928B,67720FD746DD8B8F,7A02E14B8A55704F,23ACC3A9303F6D82,F1487AEA31BFF3F2,3E0001C3EDD284BF,5AE86996D087422E,0B55F806C7A3A050,22C2D54647830B7C,00000001FAC3BC01,0B28C7425C97A6AE,B39CE5DEB05E145E,5B7C701F0CEA869C,2B0AEC4A7FABCA7A,DB1E28A11CE2262D,09B167FC861001CB,F3D69BD5E9C06EF5,46AEAB768BD5B8B2,6F42F6676C278469,0000000006474BD5,2029EE8349724B7F,D9B031893CC30FB8,F0FF91B38FEB5C0B,340D4B71D9CF8E08,DE0A638A790A1ED8,91C7FA3DE4DBAA9F,34B41B7A9D680773,48C32155E181DB03,54C4E48D44084368,000000026AA13132,A9071FE5079E58D5,769A18A1CC33D4A7,8F5FA0EC92294CE1,60A046CC2412852B,A95FC8EC0E22734F,A6DEDA4A569E43DE,C21A7CFB27E178CA,85F25FC31E87E037,F170DD0909DE3F4B,000000015CC10379,EF7F939B8B0B3413,7354BCB743DAC0B9,0DE74FDACA28CA21,6A3AFB38DA2E22D6,71C7F6FB65639DB6,CD0FE2347ADA2D24,A673AD0C6224DBA3,D76D46FBBDA87BD4,01A49D803EFEF35C,00000000BB7D4D0D,B77918E70B084273,79FEB139DD112078,1B84632B5FAE29C5,A4EAD7AA4792204D,00139642AA2AAA85,98A1143566ADDD80,2FB30AE3882D2AD1,4A22CB072273CA61,48EBB2E22E0578D8,000000026CDEAAE9,EAA9FE64B2E03E72,5A0E10DBEDA48FE0,4D5FCAC8968BDB4B,0C48E0752515D216,03B43EF69BBEFF8B,1FEA2DE70AA36B17,78611EC43A8152B3,FE29A21C2DFD6B32,A91633BF623EE73C,00000001BF81F635,ADD86F23BC230EE3,BD4FE130E852FFE0,6ABF56832245715D,98400C69B3680491,81735D07150680A7,7C30CD130E915F7D,4AC1E1587DC2B3AE,32F6E3C8D7E40ABB,81B3AE11620F296E,00000000FDDB22CE,3743DE94F61BFBD4,778D9DFB693B91FD,8F44AF07FF2A73AE,DBFE247CF9C388B0,4824BCEB9E91CA12,5095DB7C2F80470A,EDC101720ADD008E,361DA2F68839E7B8,08F453CBD398C99C,00000000DACD3BAB,1485DAE1484D3D30,C8A38233501553D0,93F469BFFDD14C71,C6D8D7AB426E57A9,F4DB886A829CFE89,EA75E842EAFA8DD5,A3FD23F3E0A8DC83,960482B90736D44D,4278DBFF38C33E97,00000000311A7246,33B9909198DB61E4,E3A8ADDCBDEEF610,205901D05EE59551,659B78FAE35A5DBF,D1928F9812747319,38A539816D0DBA2E,266992B75684DCC8,136B5BA1D202B7AB,590D7E47F41DE2A3,000000020FF0FE33,40AE5F9610C3C393,3CFFB2B14C59CDE8,E7AEE2797D13965A,B1D3EBD83AFD3D55,7BFB2A1E5CA47389,C86A0625269EAA81,40387281EDF8005C,A4C35EF8FEA16750,B128B1C2F8C1079F,000000017A2F882E,CC6FD7D63F5ACAA6,480D73319D822D54,E9E2B3F6DDABEC1D,D4F202EB754BBAB0,14B1A93D9F1185FA,6BB71CE8019F706B,5C4E7AD66041EC5A,ABDFE3EDE372C6C5,B2117F03B40E669F,0000000217C7912B,A9601E9C60EC22FC,18965E4420B53AE7,D0E2E438B1070C81,BC5E5B8F4BF51BC6,8A2C1C8929A7AC44,966A8825C28F3E3E,01862C26C5C99345,45E291FFDB952BA0,BA59C1F31C4240D7,0000000191E2CB67,DCB6AEA4B23F9A85,4358F167374D87A7,B21A07EC02BF04F4,0F8F69031EC8C886,490C2DDF42E62136,9BEC9BB3B88E87C9,666432E4F8865A58,BBAE27FD6A102C19,5F1B84E02381D984,0000000006605A99,16D112E8373BCBE9,A7AC57E35D396664,612172D95BF2CC15,9E534A9C2B6D1535,E094A7A499484073,C89D9378A3B59F9A,7B621684C1A193E0,D1B5C3159CAFC73D,6713A9EE2B4BDF45,00000001B39D7175,8EFC773DF4059127,8DEB9F6555EC014A,8B76077C8DCAA2B1,661719D2EA65759F,467964E4C711E8B2,5B4A0D37457C26C6,CB9EEF412C10EB00,78D6FFFBBA35E797,7B4B31CF5293CCA5,0000000075318CE3,3F914587A8C88535,89E3F31B949B0369,1D95C98552A7E396,4B23D0F65D2A4740,357A37EE958F290F,86F16AAB705F14CA,EB88F83D1FFF6B74,426BEEA8DA8E24FF,626C4E26895549BC,000000019599F5DA,1768DF183B245AFD,FDE9D3BED06AFFD2,1043AB9C1F5DD462,1355DDAA03397398,D0383764ED4DF748,50FC1C7937174C68,1504537A8F45A61C,153C1B09718073F3,8FAA00EC0D3FEBAD,00000001EDC7CF66,BBBD80D2750CC561,8FD98A8F42D7CA66,67A7D2F36FD2DA3C,9CFC2952996DECA8,99CDE4E877B9B98C,74D73AA42DDE89BA,6C31C0708F9F99A7,55B4C17740C861ED,3808C333F12074E9,000000003756968C,D50D88DAFDC8F6E3,DCF5E316FF2276F3,7ED8E11FD000B840,CDB3C3EB5523BB4D,EFF2CA47E29E4C81,B64B09FC65CBD087,D9FD3ABED1CFC112,043FB6FB813BF82A,92A299A4C9173CE2,00000000CFA428B9,F196A4DF53E18D23,007BC2B0B4C46A37,8A0817C788E810CE,2AB39442E52F252E,9C46142DDA723D8F,A6AD3117C97C92E6,CAE63F6C3E75951B,7F64038BEAFC5D6D,309C952D75A4E8B9,000000018BF08991,0C68F94D9DA15FD0,531DDD65D9896827,F178EABEAF81DFDB,F01E5961AE14C971,938124810F0FED77,2520F77F83098EBD,8E0DC1D483F49BDA,1A657E1AB610EAEA,158075F708F2DC40,000000026A351BEB,11836D1B313D07B3,C6AE57B0FC1D6E41,7647DAA7A8E625F9,54B64CCDE3EC34A3,CB07A5D8465E37AE,52CCB1B46F478DE1,5F8D9945EEB93463,90E441ACA1E17C3A,082C9190E73F3827,000000023D70930E,06F9CB306DE38906,B9F25D6CD242A0E5,CD8186831105F384,F1D684C918EBB105,587DC9B74B56B338,6115B655275026F3,6BE07658322F4332,FAF5FEE6C530FA7A,A9B9F98394226346,000000001A1DAC4E,3349EC03C566F1DE,DC469E1B53D8277C,B179DD6ED09090B8,8DB81DBD773B1F29,AE4FDE8BBD1C0841,FBFD6F679F7B60A1,17D01DE339BA2EFB,2298D253AA70558D,36931B9A0922A304,000000010C4224F4,2C29673A9BC4690E,7CC4F3C961C4C3C0,13BEE7A7785AB19F,BD2A6FBF0CD33858,155D37C1D30D36C3,F36DE591A10C405D,AF997B83C99C2F9E,ED0325D714FEB23D,7C314570F91A31FC,000000025AADA0A4,D724EDF695901EA9,5FED8A766514C4D6,EDD44BE089660DE6,1655F552D195B01B,EADC33DC94098F4B,D8442041C8FD799E,5DA8044450405701,AB6FDCC6DB16B91C,779A8176B43ECFA3,000000015D612894,115A6C418081F633,E80BB6531C818BC7,1067F0C949AFC530,66FB4C2213211C8C,7FB86EAC80F5F1DF,0DBC1953214315F4,01C6051C4F2CB97B,4E1214C1F604B465,0BE99EFEF1D3E623,0000000075DFA21C,D322DFC66D510780,032D43EBD03B2A0B,1445CD123678C803,182E25F758BACFD5,1AB69D053ADA1007,1C3BD0C9CB3E7D38,7738856C281E8311,C94B94B890A53A77,BCFEAD9A1E668A2F,0000000271B22DEE,486C6AB9A9821B7D,DD588591CFCD57CD,F666EEFD7F90835F,2FB0D2E6F6F4FD38,B62C925DEC2D110D,889F9B518A87A251,872BEFCCCAF5674A,6843951C34F2D257,DF142E06EB8BEC08,000000007FE52785,9FC7D4299BD3DB55,B99132AC2238F035,40437FAAE3CE2CD2,F39C714DC9CC1EC1,E39750266775EC8E,801AF260D33D342E,F72CC4051C1AA7FF,B590E290DFA24D72,2762632594CD332B,00000001A9DF1E8A,D2F43F6A49ED3E2F,B7034BD1A1723122,AAC8A6949EF54C5A,446A63782183558A,39906C4C895DB68E,B9027A6570C47104,2B3675CBCA0959BA,6BF97502141FB5BB,1E7A863557B5E7FD,000000014AD2057B,122D26B54F54CA1F,2F2C64B91D537638,2A8E3E1A00B57CC0,1724558E0918C0E9,5E9D87236188FAE0,543564D032EAF340,F855B09E0F0198F2,9202EF483EAC2C97,9C9F75D413B7A3C6,00000000FAD6F4DC,3603F3F5242A4E47,BA2FC86B416AF99D,4D8F6AE45191C0A0,FA82CBA3A126EA97,12F5264066CC4BBA,C8D4D0AA0B396F47,15057174744213B9,039FA42E1336D0F5,B4549493D6A9F749,000000020333A69F,9684C358399C9F96,DC6E743E2116A528,44A0A018E5D02595,CFF3D9A4CA0F0D8A,A27D7B0B24F4EB3A,4A6C3111951A4479,FA364CBBD6D7AA0B,0015AFE651B3A352,7381F7036666557E,00000000F3939B95,25907FF8EB4154AC,BDD1C67310751348,B7E6D7678B3F01FA,4048354F8983182A,CC07278376963A31,B0292A94B7D3550B,7D12D51E5C71816E,753BFDD93E9BFE5F,070F70F5E42370D7,00000001C90E201A,B6FF58459D09C271,4A0A6CC11CD24CA7,266BE022EDFB75C3,F68C9995D32F25D4,C7088C3068B77286,2C2203A1C035CE73,F3ED6C64E4D1A960,6A266CE1E147AECE,144F5E21A8BBCDC4,00000001B937118E,DB5CDB5E9BD69948,596FB984B60A3D9B,3AD540CC7BDB228F,8C790AB9EC945382,5F08019084C3C00C,9C32AA016E3C5C30,29882B216BADE88C,7573E09724136456,A1FC8AB1172CB63B,0000000198DC0409,A69EE0F525EF88F6,7A40D89B047EBF18,FCB2B41ACEF294E7,160408312003BED5,4B519D4A5C6EE5F1,B2B8AB1EE089F1CC,6CA92803A262D8CB,04A11B9639C51727,8D84B7C654EBC40A,000000003E7E25B8,BF0BF8B1DECD68F9,20AD52A7593C50DD,6927136A9EC3D9D4,07D89D7B66725F9D,18FB56AA2372719C,2D1048311BE54126,C9669DBB707BDE61,B364F57B57376B50,325318CF49EA027C,00000000A22772F5,B9998A81EA9DBFA1,7C090BC40AD1300D,07FD7C0CF88B2ED1,5121CB0655FF2344,2C56FE2B667CD805,9261D8C6A8815D41,C5D101C44FA9A8B3,C3C95C212A970530,DB9606183B6FD0CA,0000000153108BDC,76A56A22087D8959,D82E2A6DFE283499,F36E0064FFB16AAB,79F38D29ACD818FE,9A48A5B4CE48B7E4,135F447973DA2474,C9F8A9E9969306A9,BCA3E1E2A27424F0,6140FA38B995F443,0000000082F28A80,36D4847222B87484,C45BD883DDB3AF8F,3ABC387AECAF5DC0,AF24A842DB9BE46B,E21C6AF08883240C,6256E827120D912A,67CFF204DB7AEE3A,BB3A4E984F156D44,4A2F92D525D646E3,00000000AF8B709E,970D3A4F3612862F,91E0005285F70F0B,E5D65EB95E2DDFBB,FDFF9646C9BAA4D0,3DF38B89C44B7554,E186503F472D2F9B,AA21BAE98BBEAEB1,B3791B91CD25F65F,EB300C4E30544BC5,0000000221339D22,70654EB38FEEC6ED,05A5EDBA66D71223,129C175531F5AB03,138FE9D497FF57EF,30F8529EE1930C95,2B6053C435F4387F,1656A3CB5AEA1B06,49D68D6B56FA5E6D,D4BC5ECD6E11217A,00000002477959F7,555A989B08AF1CD0,69A9D0E2CE07CE66,4F790B756ADCB097,EE75029E10A6DAFB,1EFFAA4002891B3D,227B0B1BA269E25F,3D96CF4EC8EFD1B4,DF942E7BCC370AAE,C9DED0809424FBAF,000000019C84FFE8,8B42CFF009A9D17A,DA652433A5C26E16,930FE6C4CCBC031A,7EFD9A01D5BC4FDB,9D3A41400A027E9B,7EFC5B4F3E4B02A1,FD909E54FA9B46D5,1B95CDB903415FCB,B819FB32663D965A,0000000072D4EC11,0140348A58599749,EA459F72B97F2EBE,7C49EB10EDA60EE1,3D3A1EF78328A4AD,7E88F3120CD724C6,72638403E3BCC74B,34824D7E5CB56532,8E9988640D263FC8,7FEFF9C674601721,00000001031E7497,C5313B88DFC9CD53,8CEE6DDF0797B52D,1CE3DB4A1EE11A0F,8A5AA2C58E29204C,89BBD489C4BCA900,3B403C7A0942AB6C,CF862E0F6A13F0E4,9B87FF090007DB63,B8D5393A735B1F4A,00000000D65D2AF2,2D73753636FA79F5,7A5C408E938CEC3D,6DDE5EF38A825E60,09375AB379DC6774,131B2316CD4830F9,B55ABEE05CB06FE3,6F5B6EFE75DBE88E,440E6AD58DF03B57,0584EAA4FFD6E5B2,00000000BF035327,45F1532681D6C166,8FB73F873DF92D13,F549F27110B0C9C9,98418E8B5CD7C8D5,CC1221CE5D315336,A8006252EFFC5A7E,BDF1E75828A40B8C,1E6BBF6A7A430E34,7946F463E1FC836D,000000009D02136C,7F62F400DC2A9D3A,0962A321985B9C37,79DE7D2A81AD7DD7,B77C9801FD0D780D,33C58E6D05845F0D,EFB734101544B150,4B14E6BD3CDB2F18,5DC50382B21972B7,B53D847447B3A737,0000000095A0AF3F,34CBE31424A38DDE,5D1B6B5E0BD94EE6,C70511DB778315B3,049B7853B78C84F6,1F657707A5804911,DD71652338A91881,C45F32E90555A164,765A77E36A0ADB14,7701F728B0580380,000000027BF2F8A9,F19594C4CFEA4722,011C7F4F6BBC36E6,2EC5F1E0999A2858,7B9379FB7E0C70C4,AED29C74E74B806B,E1F242645F7BDB9A,4016B6B631FBE1DD,1F727D18298E62A6,0E49DD0CE15995E7,0000000264FB1669,F37F2A02191C9F85,E4F64329EE20AC16,892C9797F3BAA392,B196FC38E3E42843,3E2E3011F443CF62,46B871517ED46391,499DA2ED3A9CA636,610D070E0ED45F6B,7397668F471EB9D0,0000000047345D18,2AC73B450F81EDCD,E28359AB4BEC37B1,950B98E0F0AD1FED,2F1368C92CBAEC71,130BD591A8EB0670,20313D6FD65C1F46,95490C3F64618942,E22EC89C9F380E01,407D33C7BCEDB8AE,00000000A748FE13,23C63E44D3C67456,C041DFF7AC12B7D9,8B7CF235A29F5FD6,B4FA3F1F73DA68FB,6D869C6166E05F6C,E573496FA481AD43,0D6D1B0C83010D30,2412781687293D14,B393732469B796CB,00000001F30F0130,CDFD731B4B960906,2F1FC33E11124787,001E57D86A8F903D,760F0B2CD7382E25,CCB66C454A282EAE,B8050433391EEA2B,EF4162997407B2CE,2324C83E07A72EAF,72FD6E15D7A9F92B,00000000046EF284,A3C0B3101E41A848,EB94AB6A6FEC3C54,8544A97F9A02C5B7,C6FB87218FC4C0BA,B80039D006CA4BB8,EE1D30FEFB700947,614C7C8E36BBBA9D,6FB1AE08781FA72C,7F1351836E1CA12B,00000000560EC85F,A2881B7892DECB55,9673599F267118B8,53677A8084F73D43,048D53E0C097B01C,576974C1ACA855FB,EDD5797FB6B4EB5B,3D4DE049C67B8DB3,F3245B47AB2958E8,0CA4247FEBD6D68F,00000000402BDC71,DDF2D092C3F8029E,E51563CA13630A67,ED016046C968DE79,C86284E1B101F073,72D11D89F1E5D848,0D69C7FC451C863E,3197898DC1708E28,D6D70F97B0D18564,153E12F61F99CE86,000000002636F833,E191D6CC5C6EAE9E,698FDBFBAE38AB63,8B9182AB3A45B665,B7C024CEF05E1354,060E6E4F9E8CF99F,14068447B9E8447F,C6694C71A02F122C,7B5C715531D2FB6B,6319C304A777C120,0000000058EA0C23,1835ACDC0852DD27,F28493F7D010E6F1,2012518C8259AA8B,8A776F1299A6B513,48FE2663BA2CFF85,F50A5E8BF0FFEEA2,F2011438711E9F2F,EBC90E3B0FCCA8E7,80062F05DD83E1AC,0000000204803748,39E12C6012C4414A,676BDB2CC6D3E93C,FCA8918CBF161CE6,571519B00DEF2341,4A60651C9C04CD4E,3DD76D0E35D55351,D605BE802B582F2C,C9A6830247822906,E82B40A763B9E324,00000001752BBEC6,CB52939FB4CD1F39,8855F2279B3D62AA,1AB1311E100E886A,3B7D4DC3B9960B26,9F41B27126D1454A,A5EECD227E24ACEB,04217FFDF1F3AD9D,2AEB73C606656187,417E568F73F693B2,000000018F3C1E4D,94E49FDFB36AF887,4AB9CE603639C367,CB2B229AB7ADB2C4,106D5A9527CC43CB,250A0C4BB3D5D06A,517C262F35B384BC,743AE0BEDF5DDCAC,50A04B546C37816C,B6AB374D5F38B950,0000000228BFDC02,F094BDEA6B8DD1A5,4F4E4D39F331462C,938A08FC58153F5A,8CF5BCF9ABADDD8B,41C72999BF8DED53,BBBB221CC7D4A5B4,6345BFBAAE39F4A7,AD901516CD63C75B,15D84CB8EB5B13E2,0000000166CCBADF,915E9178378BF0EE,87DA42EF730F1C29,8201A34843924DBC,B3222EEE34949241,CDFB6884E5716D4E,4CF4E46E5E6A819E,C118460897A1E244,AC7AB5AFA2995BC7,078F456AF1003F4B,00000001B4A8341F,216FC83D0E3A7447,B7F0CC7A94684D2B,42FA80FD55A40C7A,8960448D33FD8EC9,FAA6270BCE4F5874,BC5E2220AF5E2B4F,9A2A51C03F8C8B22,A4FD45C2188F9A84,1D680F935A592CA4,00000000D718A3B1,A785CD5567BC7E9F,97D111B05121440A,4C7A6760B3D3A0F1,E013B756FBF1F4C2,62EC8D43F14C2946,815F3F8AA58A2375,731A3C05FCED2C2E,F80C93BC88AC0363,EAF38EF88E0C7717,00000001E1D0E3F7,9E19866CE51C0B0B,6C9941CD7808ECB1,A64198B02B420B9C,E646A3508C9C1DFD,1F3B15579510F3E3,F28FCA23C7D1BE4B,AD1478E018D60F64,48DD5A8F33ABA020,E8CCC7A3F2515B7D,00000000C09F15E8,373ACABF9C0C62D4,92057E3F84DC9AA4,E0D05780718885BC,A4C265746088A411,00189B93EC116787,58DE35FE1FB93419,A24770573768FA1D,7186B66BE375772C,7FB0236F85F732E6,000000027A94B1A0,4375B93832E97F2F,155C9FCB7588AD35,F3ECDE88E92D068C,025940E08B9A7B57,1508BA5A9D8EE205,B8A4B6CECBF073A8,4F31ADF1DF761471,16226771628BFD76,13BD7C612CC682A8,00000002690AF836,D09510D3C80D86AC,65C2F71144140792,F5A149D477FCB82D,3C95EC450387F6AA,353F5B4A4B9C440E,4F804EC3598180B1,0784AE631E117EDC,F4435338C1392718,435A80B0F91F0585,000000014F2B19D4,7D460B334CE74C19,9640A08A630A9FD4,C1074EADC0705C28,827880949F8C0DC0,F9471A99B5E4EB3D,24633C8005570601,0AD49219B6F86A09,E8297C3EA1AD9BF0,334C7B1752CB797B,00000000D3A14823,47932CBAA87B2F7D,A8744634064EA37E,79EA8798340EC516,1F9ECFA58272B855,13091DA01D240748,14FC3EC7965756FB,35A7F83899367A48,DECF56FA98787221,DD01EB492FF91B94,000000004D40BE22,33CA3689CED1FAD1,4C1D3A64AFC5A304,FBBCBC59BEF4A94F,5C0246F623376B2F,3C794D1A32131769,A473A862931124EE,CC44AB3BDE965DC7,FB7ED7A91E86C32E,3F9B612A1C17E781,00000001651C4FF6,F9B23E5D74D823DD,8861C8BA817C5642,3B4C4A3326E2A714,D5155DBBB68C4813,55CA7B3D7E4EE55F,D27811D9F4C1A7B0,C7024B9A58A8BE99,00F1043E6DD8057F,2544636200096401,000000015DE3C241,9B6C858A66826481,46109B952C0A5734,4543B0AB41EB6DAE,D535DFAE4E6721A2,DD3380FEA2026116,30EA6F67A305E1DF,9970A903D62445DC,D61F07409C4D2E46,FFF0B0724352D595,00000000F50C830D,6E4828CE2A97F684,C995B068672AFEFB,DDF347DC06954800,510661A0FFE60CE9,C58A20AD2ED06A78,210D401A51872189,8D949837BE6C32F8,05BA8E1DF00F1BB7,B9C9782920DF6839,00000000C8B5C5B5,743D1314FD146CE3,6D0C467BC5D5FFDB,D2B1B3A3FAECEF1E,85FE6D45067D8D4B,589A751A5750FCD8,1B8A39F85199703A,1B3E18FC3E86D6BD,05282348D2E1641B,F1539C35DB2B0160,00000001F7FFC578,34BD2931860DF1D8,2C89100574A4FDA4,CB604BE7E5A04AB3,255E54688E3172CB,26787CD4F7520C00,9F40E728D7A1DFBD,B8262C3F3E4C239F,8776E2321D205FF5,BF8DC43D8D958BF2,000000014EF7FF30,0BB47C17E21D322C,FB670A02035407EB,279F68E308AC2A5E,B74C2A39C630AEA4,0005288C1604C4B8,117A4B487D6FA30B,9BB5F3208ACF4C91,645EA2AE22B5B200,7565C0562540F2BB,0000000242749A44,CE35E8F489347A4C,91478C981870DAEB,2431D05E8E864832,77A1008F8953E9FF,5D223A60B454214C,C8CBC5DD2DC03555,1435BC71F6C6A786,10AD9B94B512E7F0,38315F7F70AE5F45,0000000076C87DD5,F0204D8CD5ECE0FC,B7055B6BD3A532D9,2B3E8CF63816E942,2850FECF416ADE9A,D6860D2FD21AFBF8,802D67331C0D3F79,034B211AF31593F0,979849E31A2E4D1C,F73FAA2BA9132FB6,00000001FCA582D3,ED92A76BC3803EB8,09F8B1291F80E4FB,8B741B09A22CE590,AEBB7034DA7ACB50,D1ED5736F792CAD9,A0D34B098D22E36D,A353C628178456D8,AB94D78C237D6CCC,9DF464F2C4574C7C,0000000161BEE508,95F390A3D16929E8,2FD0A62B3DA004AA,AB766728868D8041,C73F0A2DF15D99A4,22EB3FFFF3819E44,0E45D16EC76D3AC3,6455A0FC9198B1CB,1E491EF19E28F7AA,0F50FA6D59C44870,000000017D7B0967,7D9A4AE625B4E814,66C749259E8389D5,BDE32B0CB64A3630,B23E12C0151DBEC7,C05A282D4BF84051,C696E3B9A3B0762C,F5F43B286EC4B649,89AF11073812A547,F0FFCBD3FAEC4259,00000001B7232BCB,34D1E37A4F150358,DBA081437BA9EE46,A0C71092A8CA1B6F,AC4D315A2B987558,6275E22CA62B86DD,F1741E1697FA8BB2,8716C72751E05793,C2FF9DE075991CED,FD0A8A28553972B5,000000013106D210,6AFDAD526D4E2EAB,97481DEBB653D286,52FAE8E895BF9095,2E051D34E6B21023,970D7718CB0389E4,77B1841A58910A8E,67FB31D4F8530DD5,12E2B0827790B6D1,1D1D321593F01684,000000023C6BF933,40D634BC1780E690,84E57078C05306BC,822F4F3B58092CB2,3BBCAA03993D9C09,E44DA31EB6242B2B,D54003A34173503E,BF7B6615FF810A8C,46105857A7D3B7D8,84337C54EFB1DC72,00000000238A28CE,1406047FF22ABD31,3CC3A9431AEC7945,12B82A735C929226,7C8FD7F0C2114873,4E63197DA4B8AD94,59764B57E3487AC4,19B7CD71E581F392,74ACE7D9C912FA79,0E34A9E502A431DC,000000019C7BC784,FFFFFFFFCC799B8C,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,A0E7FFFFFFFFFFFF,8AAB6C8A1621F30E,95C2B32832FE0F9D,C8FAA1EF288EBC39,77DB8F8B0ED180ED,00000001F7AC32B6,A746D1C4492361CE,C1D7F06F5A7E7425,740CFF53DB571965,D1ED1B8FFF4F7079,BDE6CACEDFF66F16,BB3BFA4D62A50B2F,FB76D038C4953FF0,E298590E2E80958E,631185E85CB1C339,00000001B9190568,8B5F94BA19AD1E9E,2EFD55228FE7563F,8213F46AE90229FE,68410F06438AF8C6,4D3B0FC717C8BD6B,37C4A1E2D5D63B01,0F27ADF326789157,70C682F94A69AA23,BDC13343461E1498,00000000F3502EA3,1A53C6227D529954,B461E08899702302,D76BE04035AFEB11,A77A7A350B85005F,F8989E402669C834,86FE397DEE86D313,52B581D78CD934F8,73BBE39B5B3AF4F9,E8F04683029ACDDB,000000003E980542,2FC196FB4A689826,DE4EE327584BBA85,19F53EC2154A76E1,7E7CEEF786006905,2E589CD4B7D2180B,8F19C06A6F5A429C,7A604F19DC8B5C3B,19370DD8FEDDD9F6,8494D627B95B9041,0000000055E35249,FCB5848442B63827,CDB26D834F28D38A,7507A10C8F2A4894,DCFEBB93E6CC0339,D183566B9C331F6B,56A444000709E904,DA66999D39E6DADD,0D28226487819B19,6353B9EC7310AE4B,0000000173B6337D,F5CF5C4731826933,63231358FC89FB79,81D7E5337E8590A0,B2C2888D0824D90F,607E4AE5B52D64E2,3920906A3BAEB55F,B63BC49139006ACF,413A23B9B07DEE8F,027B8AE16EE06749,0000000182727FF1,48DD21B49FA6F63C,3A3E392029DE8C31,F282DF24D0A9EB7D,8CDFBE5786EC4BFB,99E1AB5854A63451,2755FC90CC0E966F,3DCE0EE9307892AA,02382ED51AF24552,317207966D56B667,00000000682B2C9B,042B365B47F5ECD6,4D939A922906C53B,AD220A26BF3CEC5E,2062D6F6F86472C1,0578CA4417E03F4F,D148E955BB387DD8,96CE6A4E8B3B12D5,68B47962E4A44B38,967AB702D57B8EA7,00000000B8D331B8,1F5CBE773A4BC46C,78B1249107100A10,67424AAB13A69D5D,371A6FA55126E151,74CB1CD6433EA98D,D807852C5F62AE18,8F1E09B620BDAF51,9AE73BF76E6A84DC,65C3057353A8ED37,00000000EAF66733 diff --git a/core/src/main/resources/org/bouncycastle/pqc/legacy/crypto/sike/p751.properties b/core/src/main/resources/org/bouncycastle/pqc/legacy/crypto/sike/p751.properties deleted file mode 100644 index 1ff1e03825..0000000000 --- a/core/src/main/resources/org/bouncycastle/pqc/legacy/crypto/sike/p751.properties +++ /dev/null @@ -1,66 +0,0 @@ -ph2_path = 0,0,1,2,3,3,4,4,5,6,6,7,8,9,9,9,10,11,12,13,13,13,14,14,15,16,17,18,19,19,19,19,20,21,22,22,23,24,25,26,27,27,28,28,28,28,28,29,30,31,32,33,34,34,35,36,37,38,39,40,40,40,40,41,42,42,42,42,42,42,43,44,45,46,47,48,49,50,51,52,52,53,54,55,56,57,58,59,59,59,59,59,59,59 -ph3_path = 0,0,1,2,3,3,4,4,5,6,6,7,8,9,9,9,10,11,12,13,13,13,13,14,15,16,17,18,19,19,19,19,19,20,21,22,23,24,25,26,27,28,28,28,28,28,28,28,29,30,31,32,33,34,35,36,37,38,39,40,41,41,41,41,41,41,41,41,41,41,42,43,44,45,46,47,48,49,50,51,52 - - - -A_gen = 2584350E0C33C304,51E9C29E234DC61E,C6E65A7BF90ACC05,B1333E2E19B3A930,A4F7CA2F7F66909F,E01E9E6F6704BF9E,E2345D48C0219D6D,70F37AD9933FC182,7B9D4D5870CFACA3,3B8DAF20190D460D,0B02D6FF9AAFA0C7,000015A435D19526,E85E3F2B4EDDAF22,4824EDCA0A253CB2,65C70852876C50A0,0917389F0D88B919,93FBE011EFA068E5,72703759A4651388,A266A6AEE1213EE0,C496ABC50E388B6E,564CB9FE0EBD72B5,88B483157D3BADC8,0326D337A76B5317,0000440F6F4F2D5A,CDD55D2646A1DE32,AA056CDD8B80E53E,AA87189B3A885C53,9F6D9809057564A1,C59794A13E1D38B8,97F8ED39F3FA7DE5,FC0CAF68C8B95129,393F28B240A42FFE,CD99B2F9792DEF96,F1036825CBF416B9,877B835F0533F2AE,00000CDFFE238E18,AC4EF1B17010B136,EC411E1B5AD8A667,7737372EDB66A1AF,43593ECED672CF87,1E418547C7B8A975,8CC78DCB18BD469A,6C9FB93FD2EF8496,8A4AC42666AB8545,8A973B8387C15F1D,C1657503D4BB4ADA,22F49E4311D7BBF0,00001299B8FDA94C,C04B8957D3A4748F,F3FB80F19063629F,595434555D4EBE94,8E1FEF11BFD1E0DA,E31E3377248C0BB4,9A05DEFF75EA51BA,398686FBB343398A,20331307B470DA54,964FA62AD10005C5,9EA5CC4D64E5D9EE,C84675CF9B96060F,00001DECCB78CFAC,6B20FF684759DDC2,D50EB91730DEAFBF,AA5CA048E2DAF488,E29708E28654FC18,542928AD1F445359,A311B83D79E73FF6,850B7F5926826B22,2D46731863BDB99D,467A80CD8320B69D,C046B12F05BFD513,35D9B2FF794BDB40,0000633276495B85 - -B_gen = 110F4508C6634CCB,31910BC05E296F4C,ED17AB0D6C029EA6,9C863AB6172B9974,5C15236CDB216F99,DC025064818EC7D7,C2180F387487EBF0,946B1D0F025CBC3B,5AE34395A520CB46,B52034F98A879F2C,3D2FAE10A22AB7C7,0000174CD090DA3D,C3C6A839776171F2,5883AFB529C8E50A,0DE1622BBD192925,064CCE86B1826A21,441AF1ABE9F6568E,3F29EEC0BC6F962D,A7845A0127159975,109DCD6D92B0C3F2,462438CD0100EE2E,FB7869F2B1DF80EB,563B0C55F0EEDC53,00001958C37D4721,110F4508C6634CCB,31910BC05E296F4C,ED17AB0D6C029EA6,9C863AB6172B9974,5C15236CDB216F99,DC025064818EC7D7,C2180F387487EBF0,946B1D0F025CBC3B,5AE34395A520CB46,B52034F98A879F2C,3D2FAE10A22AB7C7,0000174CD090DA3D,3C3957C6889E8E0D,A77C504AD6371AF5,F21E9DD442E6D6DA,F9B331794E7D95DE,BBE50E541609A971,AF86113F439069D2,3C683C8422E2DF33,C9F7CDAC81470884,C22A5F9AD5EAFA48,89EA4B11AAD2D65C,B7D78449A6CC0012,0000568D11C4AFFA,31BB0964DFBDC34F,FDC65CF4959AB106,A3071E4B8B04D8FF,9B68CFCE270DE486,2339E590896E0095,FC753508AD83E33E,73A274E4A6908387,88D1B207BBE8E2DC,0A6D0583233DC71F,CF7F2ECC609DE5BE,B8AF0669FBD1CF01,00001F3EF25DD512,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000 - -XQB3 = 96DCB5BD39AA8288,81E7BA9AA19C1C53,7021384077E4FEB6,A1490C7A753E8E74,A31871E13D80831C,7E653AD5931BC82E,8A0C230821766ECA,1CE14E07EB29B669,F985F42F404E45EF,044AF699D9546F9B,8A8C976EE869BE6B,00000EC5AA84C390,F16AEFC3FA025CCB,205E4E1559261A6E,FA6EEE97610CA4AA,04B29DB4DF10E7D9,083BC8A148E0FBB2,1065373142BD8B81,D7C4A7221ED3E403,1071E13BCEB89A2A,54A18AEA86CD9D51,39BF04224B598D62,D4B89FF2AA465908,00005A0F792EB1A3 - -A_basis_zero = 2584350E0C38565F,51E9C29E234DC61E,C6E65A7BF90ACC05,B1333E2E19B3A930,A4F7CA2F7F66909F,F78E9E6F6704BF9E,A8972A8BE4E1FD91,694D0F3DFDE63EAC,048A2455F29C6089,4F74628F6069C173,1EDF6B38ED1A5433,00000074AA0969CE,E85E3F2B4EDDAF22,4824EDCA0A253CB2,65C70852876C50A0,0917389F0D88B919,93FBE011EFA068E5,72703759A4651388,A266A6AEE1213EE0,C496ABC50E388B6E,564CB9FE0EBD72B5,88B483157D3BADC8,0326D337A76B5317,0000440F6F4F2D5A,CF298A24AB4EECC8,426BE362D17B58E1,DEC9E4AB0C0813E4,BB213D92B1A23DEC,73F9337EBF1AFB1E,22A428421E3F369D,4C504FBA8D4C1F41,97C03C026B64E556,94524150E5242247,08F397D005B7D0F3,2EEEFB40C2D1D40F,000049FFA7880CC0,C735AE6A6D9AB879,4431FCF02097BF97,CD6C8982E0B17062,D38791B330DBF671,BBE57BF59A8D9150,58F968F33F45A7D8,903068B77EC83B26,7DADADD772211F21,2A8DEA498D8A12BB,0AE73B6AE3E7657F,11695A4A18565FCD,0000303FE0D52CDB,CDD55D2646A6718C,AA056CDD8B80E53E,AA87189B3A885C53,9F6D9809057564A1,C59794A13E1D38B8,9E18ED39F3FA7DE5,A65C1331377229F6,0C2E5830BF42799F,5ED5225ED1E68BF3,8A4CD0997002E967,A96AA837EF598281,00006796479D59DC,AC4EF1B17010B136,EC411E1B5AD8A667,7737372EDB66A1AF,43593ECED672CF87,1E418547C7B8A975,8CC78DCB18BD469A,6C9FB93FD2EF8496,8A4AC42666AB8545,8A973B8387C15F1D,C1657503D4BB4ADA,22F49E4311D7BBF0,00001299B8FDA94C,0D976D6B7056D9BE,269169101B22C490,485B7EFC9E5BBC09,0D0B55BEABD8EF10,985F36CD657501DD,19FD14B27B195F17,F0F7E577A00E0E42,1A179D4A080F58D2,97603A54D8CFB3E5,96E69A6743A68CE1,F04C8D027EB4B382,00000A8E741B2F5C,BBF34629BA51923B,94250E3ECE841C7C,56CD785FA63E19F9,126F4144FC6B39F4,4BB54DEE559E01E3,03195B2E094E0D92,01F40204597E534A,7F9B8D473586B966,38281C1E6F54E744,215C5889B91D5D63,9CEA26343AD2B060,000022374E0C0255 - -B_basis_zero = F1A8C9ED7B96C4AB,299429DA5178486E,EF4926F20CD5C2F4,683B2E2858B4716A,DDA2FBCC3CAC3EEB,EC055F9F3A600460,D5A5A17A58C3848B,4652D836F42EAED5,2F2E71ED78B3A3B3,A771C057180ADD1D,C780A5D2D835F512,0000114EA3B55AC1,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,2E1EB8ED8C1C8C94,06CFE456B25DBE01,1EB54C3E8010F57A,4B222D95FC81619D,F99EBD204D501496,0C18348F9B629361,C29E9A16BEDE6F96,3B39F30163DAD41D,807D3D1ECF2AC04E,E088443F222A4988,61B49A7524F1EA12,000041BF31133104,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0E57361284693B54,D66BD625AE87B791,10B6D90DF32A3D0B,97C4D1D7A74B8E95,225D0433C353C114,02AAA060C59FFB9F,0E46F50AF134F41D,9442C2E31FC91DA1,D920267A5E3844C3,DDF0F4AD44A77A2A,4691EACCBF84E753,00005E97318C9C5A,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,2E1EB8ED8C1C8C94,06CFE456B25DBE01,1EB54C3E8010F57A,4B222D95FC81619D,F99EBD204D501496,0C18348F9B629361,C29E9A16BEDE6F96,3B39F30163DAD41D,807D3D1ECF2AC04E,E088443F222A4988,61B49A7524F1EA12,000041BF31133104 - -B_gen_3_tors = 7BB7A4A07B0788DC,DC36A3F6607B21B0,4750E18EE74CF2F0,464E319D0B7AB806,C25AA44C04F758FF,392E8521A46E0A68,FC4E76B63EFF37DF,1F3566D892E67DD8,F8D2EB0F73295E65,457B13EBC470BCCB,FDA1CC9EFEF5BE33,00005DBF3D92CC02,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0E7E952E9A260914,92C98EDCD6E01424,8F2B207221D33C50,AEF2728CA22F318E,5FD0E29877DC3D43,1BDC7B7367E4E124,FF5BC4186BDDCAE7,D20A34710EE8B44B,2E0866A5B9467EBD,876EFC05B732A6AD,9D39159E24822ABB,0000658F31DC0D6E,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,84485B5F84F87723,23C95C099F84DE4F,B8AF1E7118B30D0F,B9B1CE62F48547F9,3DA55BB3FB08A700,B5817ADE5B91F597,E79E1FCF0AF940C9,BB60344181114E9D,0F7BAD5863C28A11,3FE7A11898419A7C,1070C40098C51E33,0000122697AF2B19,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0E7E952E9A260914,92C98EDCD6E01424,8F2B207221D33C50,AEF2728CA22F318E,5FD0E29877DC3D43,1BDC7B7367E4E124,FF5BC4186BDDCAE7,D20A34710EE8B44B,2E0866A5B9467EBD,876EFC05B732A6AD,9D39159E24822ABB,0000658F31DC0D6E,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,6491DDA56B18F762,B50239F87A977F80,D061934416F37D7C,D79D328C01810FEC,4F4BB58557C706AF,EFE0C6963007AABB,20EA47B4FDE821A5,DE5144774B84AE51,262E82E15B85FF1B,7A0820D88294BDEE,A36653F0DFF6FE6E,0000239BB2213058,A8C40A6A4ACECF3A,E988877E7DF4D938,C2353D8E5C2F0BAB,C4758A5B1437A358,C5CEE9FD3A3B088D,086B2876D6520F51,D31476314E3DAD08,517E8096137AFBC9,E52ADD7D2B85BB6C,43A92AC98B1E5F2B,4F32E4103B80C703,000068BCEB2391D2,573BF595B53130C5,16777881820B26C7,3DCAC271A3D0F454,3B8A75A4EBC85CA7,3A311602C5C4F772,E644D78929ADF0AE,10D82053FBBACBA0,89171A84007CD0AD,2323BAEAAB662D0A,41B98A3AD193F81C,BEDFAC8F5C3A1563,00000728EA1E6549,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,9B6E225A94E7089D,4AFDC6078568807F,2F9E6CBBE90C8283,2862CD73FE7EF013,B0B44A7AA838F950,FECF3969CFF85544,C3024ED04C105702,FC4456A2C8731E25,E22015867B65E95A,0B5A942BDA1D9959,6AAC3CAEB7C3DDF8,00004C4A2320C6C3,A8C40A6A4ACECF3A,E988877E7DF4D938,C2353D8E5C2F0BAB,C4758A5B1437A358,C5CEE9FD3A3B088D,086B2876D6520F51,D31476314E3DAD08,517E8096137AFBC9,E52ADD7D2B85BB6C,43A92AC98B1E5F2B,4F32E4103B80C703,000068BCEB2391D2,A8C40A6A4ACECF3A,E988877E7DF4D938,C2353D8E5C2F0BAB,C4758A5B1437A358,C5CEE9FD3A3B088D,086B2876D6520F51,D31476314E3DAD08,517E8096137AFBC9,E52ADD7D2B85BB6C,43A92AC98B1E5F2B,4F32E4103B80C703,000068BCEB2391D2 - -g_R_S_im = CB6E5ADE9CD78AF1,40F3DD4D50CE0E29,38109C203BF27F5B,50A4863D3A9F473A,518C38F09EC0418E,C2429D6AC98DE417,1A2DC3684817A3CB,F7E83EC334E40005,C560B1CA4C837125,CECA2F86BEB1A124,563DDE23E947A71E,000034BDF9FF47AA - -Montgomery_R2 = 233046449DAD4058,DB010161A696452A,5E36941472E3FD8E,F40BFE2082A2E706,4932CCA8904F8751 ,1F735F1F1EE7FC81,A24F4D80C1048E18,B56C383CCDB607C5,441DD47B735F9C90,5673ED2C6A6AC82A,06C905261132294B,000041AD830F1F35 -Montgomery_one = 00000000000249ad,0000000000000000,0000000000000000,0000000000000000,0000000000000000,8310000000000000,5527b1e4375c6c66,697797bf3f4f24d0,c89db7b2ac5c4e2e,4ca4b439d2076956,10f7926c7512c7e9,00002d5b24bce5e2 - -Montgomery_RB1 = 1A55482318541298,070A6370DFA12A03,CB1658E0E3823A40,B3B7384EB5DEF3F9,CBCA952F7006EA33,00569EF8EC94864C - -Montgomery_RB2 = 48062A91D3AB563D,6CE572751303C2F5,5D1319F3F160EC9D,E35554E8C2D5623A,CA29300232BC79A5,8AAD843D646D78C5 - -threeinv = 555555555556188F,5555555555555555,5555555555555555,5555555555555555,5555555555555555,8105555555555555,1C6290A167C97977,CDD287EA6A6FB6F0,42DF3D3B8EC96F64,198C3C1346027872,B0528624270642A3,00000F1E61944CA0 - -u_entang = 0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,000000000004935a,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0620000000000000,aa4f63c86eb8d8cd,d2ef2f7e7e9e49a0,913b6f6558b89c5c,99496873a40ed2ad,21ef24d8ea258fd2,00005ab64979cbc4 - -u0_entang = 00000000000249ad,0000000000000000,0000000000000000,0000000000000000,0000000000000000,8310000000000000,5527b1e4375c6c66,697797bf3f4f24d0,c89db7b2ac5c4e2e,4ca4b439d2076956,10f7926c7512c7e9,00002d5b24bce5e2,00000000000249ad,0000000000000000,0000000000000000,0000000000000000,0000000000000000,8310000000000000,5527b1e4375c6c66,697797bf3f4f24d0,c89db7b2ac5c4e2e,4ca4b439d2076956,10f7926c7512c7e9,00002d5b24bce5e2 - - -table_r_qr = 00000000000249AD,0000000000000000,0000000000000000,0000000000000000,0000000000000000,8310000000000000,5527B1E4375C6C66,697797BF3F4F24D0,C89DB7B2AC5C4E2E,4CA4B439D2076956,10F7926C7512C7E9,00002D5B24BCE5E2,00000000000926B5,0000000000000000,0000000000000000,0000000000000000,0000000000000000,1D90000000000000,70B2310B937938F1,CB48C3E2E944C6CA,1A284662DA855042,AD301BE2EB6B4E13,35CBB9123C90433E,00004586BDB1A06C,00000000000DBA10,0000000000000000,0000000000000000,0000000000000000,0000000000000000,3500000000000000,3714FE4EB8399915,C3A2584753EB43F4,A3151D605C520428,C116CF5232C7C978,49A84D4B8EFAF6AA,0000305731E97514,00000000001003BD,0000000000000000,0000000000000000,0000000000000000,0000000000000000,B810000000000000,8C3CB032EF96057B,2D19F006933A68C4,6BB2D51308AE5257,0DBB838C04CF32CF,5A9FDFB8040DBE94,00005DB256A65AF6,0000000000124D6B,0000000000000000,0000000000000000,0000000000000000,0000000000000000,4C70000000000000,FD77CB91DCF9F939,BBFBECABBE91C11D,2C01F45DDE1EB80E,D4FD82C17A2444DE,5D84E184E165AA16,00001B27A62149BC,0000000000149718,0000000000000000,0000000000000000,0000000000000000,0000000000000000,CF80000000000000,529F7D761456659F,2573846AFDE0E5EE,F49FAC108A7B063D,21A236FB4C2BAE34,6E7C73F156787200,00004882CADE2F9E,0000000000192A73,0000000000000000,0000000000000000,0000000000000000,0000000000000000,E6F0000000000000,19024AB93916C5C3,1DCD18CF68876318,7D8C830E0C47BA23,3588EA6A9388299A,8259082AA8E3256C,000033533F160446,00000000001DBDCE,0000000000000000,0000000000000000,0000000000000000,0000000000000000,FE60000000000000,DF6517FC5DD725E7,1626AD33D32DE041,06795A0B8E146E09,496F9DD9DAE4A500,96359C63FB4DD8D8,00001E23B34DD8EE,0000000000249AD6,0000000000000000,0000000000000000,0000000000000000,0000000000000000,98E0000000000000,FAEF9723B9F3F272,77F7D9577D23823B,5803E8BBBC3D701D,A9FB0582F44889BC,BB09C309C2CB542D,0000364F4C429378,0000000000292E31,0000000000000000,0000000000000000,0000000000000000,0000000000000000,B050000000000000,C1526466DEB45296,70516DBBE7C9FF65,E0F0BFB93E0A2403,BDE1B8F23BA50521,CEE6574315360799,0000211FC07A6820,00000000002B77DE,0000000000000000,0000000000000000,0000000000000000,0000000000000000,3360000000000000,167A164B1610BEFD,D9C9057B27192436,A98E776BEA667231,0A866D2C0DAC6E78,DFDDE9AF8A48CF83,00004E7AE5374E02,00000000002DC18C,0000000000000000,0000000000000000,0000000000000000,0000000000000000,C7C0000000000000,87B531AA0374B2BA,68AB022052707C8F,69DD96B6BFD6D7E9,D1C86C6183018087,E2C2EB7C67A0BB05,00000BF034B23CC8,0000000000300B39,0000000000000000,0000000000000000,0000000000000000,0000000000000000,4AD0000000000000,DCDCE38E3AD11F21,D22299DF91BFA15F,327B4E696C332617,1E6D209B5508E9DE,F3BA7DE8DCB382EF,0000394B596F22AA,00000000003254E6,0000000000000000,0000000000000000,0000000000000000,0000000000000000,CDE0000000000000,32049572722D8B87,3B9A319ED10EC630,FB19061C188F7446,6B11D4D527105334,04B2105551C64AD8,000066A67E2C088D,0000000000349E94,0000000000000000,0000000000000000,0000000000000000,0000000000000000,6240000000000000,A33FB0D15F917F45,CA7C2E43FC661E89,BB682566EDFFD9FD,3253D40A9C656543,079712222F1E365B,0000241BCDA6F753,00000000003B7B9C,0000000000000000,0000000000000000,0000000000000000,0000000000000000,FCC0000000000000,BECA2FF8BBAE4BCF,2C4D5A67A65BC083,0CF2B4171C28DC12,92DF3BB3B5C94A00,2C6B38C7F69BB1B0,00003C47669BB1DD,00000000003DC549,0000000000000000,0000000000000000,0000000000000000,0000000000000000,7FD0000000000000,13F1E1DCF30AB836,95C4F226E5AAE554,D5906BC9C8852A40,DF83EFED87D0B356,3D62CB346BAE7999,000069A28B5897BF - -table_r_qnr = 000000000004935A,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0620000000000000,AA4F63C86EB8D8CD,D2EF2F7E7E9E49A0,913B6F6558B89C5C,99496873A40ED2AD,21EF24D8EA258FD2,00005AB64979CBC4,000000000006DD08,0000000000000000,0000000000000000,0000000000000000,0000000000000000,9A80000000000000,1B8A7F275C1CCC8A,61D12C23A9F5A1FA,518A8EB02E290214,608B67A91963E4BC,24D426A5C77D7B55,0000182B98F4BA8A,00000000000B7063,0000000000000000,0000000000000000,0000000000000000,0000000000000000,B1F0000000000000,E1ED4C6A80DD2CAE,5A2AC088149C1F23,DA7765ADAFF5B5FA,74721B1860C06021,38B0BADF19E82EC1,000002FC0D2C8F32,000000000016E0C6,0000000000000000,0000000000000000,0000000000000000,0000000000000000,63E0000000000000,C3DA98D501BA595D,B455811029383E47,B4EECB5B5FEB6BF4,E8E43630C180C043,716175BE33D05D82,000005F81A591E64,00000000001B7420,0000000000000000,0000000000000000,0000000000000000,0000000000000000,6A00000000000000,6E29FC9D7073322A,8744B08EA7D687E8,462A3AC0B8A40851,822D9EA4658F92F1,93509A971DF5ED55,000060AE63D2EA28,000000000020077B,0000000000000000,0000000000000000,0000000000000000,0000000000000000,8170000000000000,348CC9E09533924E,7F9E44F3127D0512,CF1711BE3A70BC37,96145213ACEC0E56,A72D2ED07060A0C1,00004B7ED80ABED0,0000000000225129,0000000000000000,0000000000000000,0000000000000000,0000000000000000,15D0000000000000,A5C7E53F8297860C,0E8041983DD45D6B,8F6631090FE121EF,5D56514922412065,AA12309D4DB88C44,000008F42785AD96,000000000026E483,0000000000000000,0000000000000000,0000000000000000,0000000000000000,1BF0000000000000,50174907F1505ED9,E16F7116BC72A70C,20A1A06E6899BE4B,F69FB9BCC64FF313,CC01557637DE1C16,000063AA70FF795A,000000000036E841,0000000000000000,0000000000000000,0000000000000000,0000000000000000,E550000000000000,F86762B596EDEBAB,33F3C6033BB54359,8405DD199A5C282C,7EF888446E6CCE9A,188EA48EA430FE44,00005176F263DD35,00000000003931EF,0000000000000000,0000000000000000,0000000000000000,0000000000000000,79B0000000000000,69A27E148451DF69,C2D5C2A8670C9BB3,4454FC646FCC8DE3,463A8779E3C1E0A9,1B73A65B8188E9C7,00000EEC41DECBFB,0000000000400EF7,0000000000000000,0000000000000000,0000000000000000,0000000000000000,1430000000000000,852CFD3BE06EABF4,24A6EECC11023DAD,95DF8B149DF58FF8,A6C5EF22FD25C565,4047CD014906651C,00002717DAD38685,00000000004258A4,0000000000000000,0000000000000000,0000000000000000,0000000000000000,9740000000000000,DA54AF2017CB185A,8E1E868B5051627D,5E7D42C74A51DE26,F36AA35CCF2D2EBC,513F5F6DBE192D05,00005472FF906C67,000000000044A252,0000000000000000,0000000000000000,0000000000000000,0000000000000000,2BA0000000000000,4B8FCA7F052F0C18,1D0083307BA8BAD7,1ECC62121FC243DE,BAACA292448240CB,5424613A9B711888,000011E84F0B5B2D,000000000046EBFF,0000000000000000,0000000000000000,0000000000000000,0000000000000000,AEB0000000000000,A0B77C633C8B787E,86781AEFBAF7DFA7,E76A19C4CC1E920C,075156CC1689AA21,651BF3A71083E072,00003F4373C8410F,00000000004935AC,0000000000000000,0000000000000000,0000000000000000,0000000000000000,31C0000000000000,F5DF2E4773E7E4E5,EFEFB2AEFA470477,B007D177787AE03A,53F60B05E8911378,761386138596A85B,00006C9E988526F1,00000000004DC907,0000000000000000,0000000000000000,0000000000000000,0000000000000000,4930000000000000,BC41FB8A98A84509,E849471364ED81A1,38F4A874FA479420,67DCBE752FED8EDE,89F01A4CD8015BC7,0000576F0CBCFB99,0000000000525C62,0000000000000000,0000000000000000,0000000000000000,0000000000000000,60A0000000000000,82A4C8CDBD68A52D,E0A2DB77CF93FECB,C1E17F727C144806,7BC371E4774A0A43,9DCCAE862A6C0F33,0000423F80F4D041 - -table_v_qr = CCCCCCCCCCCD41EF,CCCCCCCCCCCCCCCC,CCCCCCCCCCCCCCCC,CCCCCCCCCCCCCCCC,CCCCCCCCCCCCCCCC,467CCCCCCCCCCCCC,05CCF962F575DF8B,3953C2CA47D95926,C50BC81A120A6C9F,DE486C73B57C04C7,3C38F0BBEDB4E68A,000035D48FD9C405,6666666666657C21,6666666666666666,6666666666666666,6666666666666666,6666666666666666,61B6666666666666,D852A3BF5F0CB992,67EE158584451A2A,7E370833B2D70F38,C8D1DC1CF1BA4DB8,95A0AF27BC510F50,0000043CB58E6F11,B891DB891DB8926D,DB891DB891DB891D,1DB891DB891DB891,91DB891DB891DB89,891DB891DB891DB8,B7A1DB891DB891DB,7667EA3E359A528F,920F68111BC2395B,73153DF2CE971E2C,16EDA0D863AC7DA5,BF837289A3FC18BF,00005ADF5C37BA11,EDC48EDC48EDB246,8EDC48EDC48EDC48,48EDC48EDC48EDC4,C48EDC48EDC48EDC,DC48EDC48EDC48ED,49A48EDC48EDC48E,590A01C2CFF1EF31,F144BE828EE398A4,7553BC320111D67F,AE524764F48D28A2,7D745F00E9774A86,0000016C21BBD6A1,5E40E05A0E84063C,1F4D776F0A51A9CB,CB5E40E05A0E8406,061F4D776F0A51A9,A9CB5E40E05A0E84,72C61F4D776F0A51,618B216FB9C76A1E,E22409F266B16463,894A7D245553FD6B,4E89F364CCE00FA7,77A8C743F3083EC9,0000188BE18D4AC5,7DC0E6ABEADE3F10,323668C519083ECD,CD7DC0E6ABEADE47,47323668C519083E,3ECD7DC0E6ABEADE,A347323668C51908,CFA800E85F71B1FE,0F36E5745D988B7A,E7F654456F1F4116,3F5EDBEC2C210D61,39B0FEDD215C1DCA,00001705E4626A37,791C39AD37694088,40791C39AD376940,6940791C39AD3769,376940791C39AD37,AD376940791C39AD,6C2D376940791C39,4A463885B9946D81,736B37A93397FE42,3874F55B29BB4D54,5F7A8A5F8D7543C5,228CCBA8F76BD619,00005096624D7492,A331EBB0C9B54BA9,51A331EBB0C9B551,B551A331EBB0C9B5,C9B551A331EBB0C9,B0C9B551A331EBB0,C980C9B551A331EB,C7BC1BC679178B4E,7072B575C98A5F98,B10657E6A1B9DEA2,71773BA18E92437A,AD4025945D8B2AB8,00002F2C83A4E8D6,732233773223377C,3773223377322337,2337732233773223,3223377322337732,7732233773223377,C637322337732233,2695C5C06B69B3F6,02330B3C47A0D9F3,1FF319B45BEC27C0,A128906C609EE6B9,736A7518122E449F,00001FCE86244E63,6EE64466EE6441DB,466EE64466EE6446,64466EE64466EE64,EE64466EE64466EE,66EE64466EE64466,63D6EE64466EE644,A64EE10DFC0F7507,7E19CCA11263939B,39CF2CD41A04B92C,B2FBF371165340D9,53745B07D6DF8B00,000044F4C0618554,70E5437D550C15E9,514AB52CDC183AC2,A4D63DFA7AA6594A,046DAD39BC3F3F19,82FD5B4A38522B72,AD58A5AA7E8D2ECF,523BAAB70A135BE2,45782546050175F7,B24F33FAA2472B55,EBA7A14C1F8593CD,20600FBAB2D24E65,0000133D309F7EC7,8EEB4AB02E5A2272,8EB9599CB8AAD0F4,B06CC77E62BB7EF8,32986176DFFA11C5,1BAC3B085C0081D9,69272A1BEAA860AF,E41E6EBFB6ED0D08,F255608B042DB67E,1279C6C0D0C40109,76B7BA4E30FA03B6,0D3DDD4F6F5A7EB7,0000106A8E48CD0F,D5120148FEAF2C06,255365F9DAA4C4B8,CC272EFC74777061,D9E68887C98D5C50,0383B3424E91729B,E0B5120148FEAF2C,1BE4FA2B9F7CFD78,DA98A1C587680DD9,ACC09E7217DDD41D,BAB5E239D699C58C,41FD047089438309,00000858395E2C66,94FAC8FF3E686241,B72999CF503E0946,02F59559E717C42A,0412EFA3785EBB9F,AD808B51BA81A8AC,4BE4FAC8FF3E6864,8C1AAEA7B9495845,94D196357B071596,4FBF87DA63CFBC99,666394A603DFBB5D,AA328976810C7C69,00006AA898DF5E6A,40E70907368FAAA3,2531EC3903CE9F2C,F8AB9BFACF708D95,D2DE3A9B1838859A,4E47B12D7C682948,281BDC83C4953F02,DE0EF99ABED7AFEA,B81783A3E8034AE6,3E73219AAC32B265,A6F25C569E80F4D3,6961E44D2E61E550,000054AF9D7748CE,4EF61479F650B3CA,E4161CB8F931D792,AD6C0EDA1D651114,96969F3A055F9963,A55811F1BE797DD9,BB36DA0672F2CEF4,BCD0F6F9FFB265C5,868F4BABA3739212,DA96099F90F8EC8D,F6B719FF6C14091F,EF5131B07D9BA208,000015F75A78FB86,B5CA528D6B5CA529,CA528D6B5CA528D6,528D6B5CA528D6B5,8D6B5CA528D6B5CA,6B5CA528D6B5CA52,B27528D6B5CA528D,D7C00A95FC590145,4E4610B31250410D,92EB9C10C371F0FC,71D124AD03784C6D,FBA87309E1A6D857,00002DF3B0F268CD,6B5AE52946B5AD2D,5AE52946B5AE5294,E52946B5AE52946B,2946B5AE52946B5A,46B5AE52946B5AE5,D0BE52946B5AE529,5BEAE3E345C8E7D7,9D2D7059D4BB6A4E,018F7C0F408EA159,4E11D89176651539,48671FC6C152F99C,0000530CE08D1028,CE57AA6B0A6E427F,9B8F883433A0EB6A,BD90869A824E3109,D1840719519276EA,F601CD0A72F12455,8904C6A15653D646,072DB02908565884,71294DC40DC2EB13,361608701CEA745E,1279CC6C51A4F800,DD923715582E9EDE,00006578E5CC44C5,B218A10D98E7AC3C,3CAF3BDD50AC19A5,2A2B48E62A13DFAE,A9CE07E98542FDD0,4B70FD8D0D9C06C5,6829379D7BC99C61,57C3D248CC251489,9F1367A307C698E9,2CC0B2B8746361EF,9A6A53D6400CB8EA,7888C0894B30195B,000029E026757F97,B7B49E77DD01B05A,C7FCDE689EA7A30E,3B83E48534D253E7,E1F4F28B24C70D5F,0C226AF798CDAE97,29592FFABA44E0BF,451BFFACF7902A0B,EF0C4136DB713262,7F066B8D7CD90C93,193C99BB6A2BD9E4,DCCEB7DD7547E7EE,00001BC6242C97DB,E49911F2B13CA178,F8D4BCF08B36207D,2605805106CF5C4D,BB2BF392469C496A,C6EE51B30BE997A4,3636AEDEA9BE252F,5962BFE5CE1E434D,80A1219F24FBAA71,9727D3F901B9FA59,9C7DB47FBDB8D837,260B21A1EA96DA92,000058C7EC9D75A5,11372FCC7943203A,5C4549B345DE13E1,B35E08AA984D8EEB,9AD22A4F3D9CF45D,84408FBE68108C13,D6F34279BA1D5079,FD86BCE1D485CE9C,7547DCC9E6A72B9A,082BAC6E5640D1B8,A0AA9060525B5FA0,9DF6B6008023369A,000064534002FC0F,338AA1050E3B47F2,A779AFC5AA01E0AA,7A24EAE40DA1607F,2F3BC85F75845B2F,B63ECCFACC4A42BC,B970439A64648442,FC7FE81D54BCBFAD,8F070C333697311A,C3F49A6F3F169CEA,05D4853A9EA5F7ED,D518DE0B200B8454,0000527415AF5FE1,29D6C703462657AD,DC60DB370D32F7B9,7ECF292BC2C418DD,37B10E0D29478FC0,2DFAFEF9EA3B8E16,E9716B45FA8908A4,6CB32B342A6375FF,FD73F31AB04928C5,B397940272F73C0C,5B001264620355C2,5803F26169F9945B,00005C5620099D9B,DA0656B84FE5EB1E,BA4CBC548666840D,1A44273AF862539E,1FFD96A7C772BACB,953D86F6FED07774,7BBC68E6D3E03A59,A78131504FEA94B4,5FF580356C9EF9E7,DF4576DB17102D3C,CA73668DEBAABC08,C73232385D81A0CB,000014DC1275B692,E1C98F3C564A49CD,76847854DFFF1979,6DD3A9A2B019D474,FEB9A85944A3C836,4C554E80A25DEBB9,C247DBF7209CBA59,E606E4DA4D403E68,5AABAE35231E6C78,1E08F32D70B4CF5A,8EDD7B4A0D3949FA,A549CBAE571FABD6,0000345B562BB1C2,3DDA63D9B718EF13,DB18FF110367AB22,B7A690D61E54A79F,D1FB6E7474B2F230,5D6F299A0CDCA8B4,BDB8418CAF5F5E57,87950067C9C186CF,F190BC388A72A53B,213C2BED23C24CA9,D23020B606F4B8B5,E7CFBF2E0DE63E1D,0000085488821CA3,2E87222F0886018B,2006A348352327DC,019561FC0617F066,0390FD49917EAD64,C8962E05BE5C859E,9098F7D823688E17,A367361FE7730947,4C6AE2F141441363,6012B07C3CA41E86,B27005C079FEB1B6,825B9BFC26C91F27,00003F1183F8513F,B584B99EC62D9D35,A4912F9464B54407,74A10C6ED11079EF,42C935F4B27768B1,0355CC43459FC8F5,083FB4BDA9E4C1B5,362D54FAF7050831,ED24CAC0D587AF78,520C08B595DEF623,9C385DB3FD4B1742,12B09C148B913905,00004C96EA957BF4,CCB2CE7886EF239D,47C704F6F492B661,63CDC17F473B3143,E43575F9DEDACC50,ED36745A83436E23,B43E3A2A47D36381,6FE523A476BF9F48,082B1F402B3BD2A0,DBE6E728B539ADAE,A37C34807A76FF4E,538EE747772483FB,00000DB5A5E658A6,EFAD9377610BEA32,ECEDC7C4592CCB7E,E95A17CFCF63D4AC,C5A8F05F0C78F770,386981FAC3E25272,DD7CD0B4AB9A79D3,D9455DDAD31D0592,994588049EBE35C8,07820458445B7DF6,160C1A4D5730403C,D554560F2A51E183,000027B420420DC7,ED6F9F18F5F91D9B,D0140983A4C9F4FA,4B28E37741FCEC6E,58485D7E32AF47F7,BFCAD3B8EF182455,AA683462489724D5,4F7F01FFFD1C1E61,DB4F6A13AEBB1ACA,40272AE951D7AD1B,430F04D3C2402C98,67C05BFAD21BAAF1,000053D2C0CD2C47,BA47E3D71B355EF5,EDE1D03F79CAC2E3,F12082CA2D8570E2,33DB874355B82195,AED62CBE488111EF,8FF5A83E933036A1,5FC5432547B62106,3675123E1B5D6362,187E4E847EDF9ACC,92E55D9773F0AB6E,2FB79EE22F3B6FA7,000059F9721DDC1B - -table_v_qnr = E85E85E85E85F161,5E85E85E85E85E85,85E85E85E85E85E8,E85E85E85E85E85E,5E85E85E85E85E85,65385E85E85E85E8,85F916A5F6E08638,2609C462575E3A01,D55BC460BFFDB5F7,394FD56C08877041,90A4C64E64B48269,0000155B182E978E,BD0BD0BD0BD074F6,0BD0BD0BD0BD0BD0,D0BD0BD0BD0BD0BD,BD0BD0BD0BD0BD0B,0BD0BD0BD0BD0BD0,B39D0BD0BD0BD0BD,981077DADCECBF8E,84DD13216CFDC8E1,65BF0DC9ADEA2134,4046BEA875292C81,96FEEECC09D1A583,000034F2E90F31C3,94DFB461AC813046,794DFB461AC812E7,E794DFB461AC812E,2E794DFB461AC812,12E794DFB461AC81,3D0E794DFB461AC8,70595ED790F5300A,8AC21DF01D745314,960E4F84DA8D1645,5B7E64183952E46B,F22C180908C76B1F,00004768EB30E5C6,88455121DEEA9B08,788455121DEEABB7,B788455121DEEABB,BB788455121DEEAB,ABB788455121DEEA,E53B788455121DEE,C8CE631746684732,7D5D2A56DD6FBE22,D6AD8D86B52354AE,D1BD7280508807CF,A1C516D87EBCCC99,0000396575A76D53,D62298ECA7759C89,4D62298ECA7759C4,C4D62298ECA7759C,9C4D62298ECA7759,59C4D62298ECA775,796C4D62298ECA77,AE6DBC543FEF825C,EC1F7E95B33ED029,CA719FAF0D52EACA,F0376BE32D0BF058,F65BA4732A06CB30,0000253E29FDA895,2D3E21C74B076D2D,E2D3E21C74B0778E,8E2D3E21C74B0778,78E2D3E21C74B077,778E2D3E21C74B07,2288E2D3E21C74B0,114736656CB88D28,65C8937E512FEBC1,0306EEB4AB789442,F0BAF2EB5B82DA71,D1557C1ADE14F33F,0000281EF5D67B92,55A7CC22BD034BC5,CF664D2B55543DB8,AD0509637903BB29,CC764B6DB31CC125,A38DE755C3A64634,C5DBC1418728812C,54CDBEA5DAAB0EBF,784DA3FDEE94F653,ACD92FABB346E2C0,309E575438F3301C,DE6DA98747E3BC84,00000078998A0688,14E884DC556CCE17,F813B625562FC7FD,D410AA497515C755,4395124C11891A90,392344FF261926C0,5B0104CE685B1520,A32FA4F27454F2D6,DDED7CB7AF975B5C,FEA15A43C78AC218,89AE7B37DEB4C0E0,48661EEF6DCF9520,000011ADE16CDC2E,D2261143E5B763C9,7BAF0692270E1A07,3E5B763C797E0B76,2270E1A07D226114,C797E0B767BAF069,8FA2261143E5B763,6F563606E110ED58,CD1C300154910AA4,B61EDFD60C5C6096,12CADF965191532E,A045CA5ADE8C8CA6,00002CDC07A09F1D,952C939D91AFBD6C,DB189B941022B733,D91AFBF752331AB4,41022B733952C939,752331AB4DB189B9,91552C939D91AFBF,06376CA8518BA8EA,4C144651E91CACE2,E0E13E3F7AF8AC34,4C7E7CDE3D51F816,11E5E216628DA39F,00003C9C0D30F762,0C605DAAC2686111,653B01B6DAB28C3B,C50A3A32DE5449A4,B6EBC1C42E96427E,8FEFFAE8A88084D9,58EA39884624C641,9EC005ED22C5BC45,1633B0FBD77D6D9D,A57C267B6FBA36DB,F94465FAC0B899A2,34A4BE281ED17637,000055D1BDD26591,0C709286502B5CCB,FDA560011E994595,4856E21B8EEF3C44,E6FF4B98A9EA2DE2,9887CBBDFB34929F,7E47E75497B06B9B,E723E79ABA5D9470,02C05C07824B8E6E,5E4E45149E3C5445,2452AE29E3055EA4,EF90DE3635F81ED5,00002811146405A3,9807214A3A1C1CF3,7A0E708928E1F773,6B79A82BEC4DCC5F,E98AFBE2931E7695,F1BFAF7F0D6FE513,729355B40CC74834,7355193ADF5FC317,AABE07A1788CB696,22D720814DB72B6B,37DF09E734DE45BA,FD056FDA4F240CBA,000068ABBB7B5C8E,C3777B85DA951B35,729E2EE622CB06CE,142662CA9F3EC02B,79B13BB964738D59,0D0D82AA614F52FF,2073598189B312EF,187D2FB5FF497E99,55FEA80CEF2A4B0E,6B197F79D5FAF833,254447C18292F844,60F938B568EE1543,0000071826A2ADCA,9C02260C68B4DBCD,0EAD5B56BFB777BE,3BC3BE5177278FD6,DAB6622B90CD39DE,90CC3EC6ACA6DDD0,6E158FF767CE5D2C,A8B669D3FF7489EA,AF133837592C7ADA,FBF80D62062EC026,C3512D9A00005FBB,B759F49E11D399A6,00002B5BC9341B5D,C32617FB97A7BA46,DC97C62323C3A3A3,100C4C10F8AD3EB2,303659A310A3583D,12DA436E2F3F2E72,4D50F367A011A161,8328C3F9F44A3084,F982C9DA22658656,5EB7238A18DD90A7,B9156E1D1B343898,57243EC083BFEF2F,000003DE52126EF4,BBD06880C51C680B,7A81A7C7078464C3,FDECD7041B4ECF3E,2C5C3D04ED2F2A03,5D174A6A4E7F7DB4,1B52D2539D1EA2E8,A5CC20018839AB95,67625D02AE4CF980,186074DCBD384821,9E5E42872A3C7A83,545832703A5A56B9,000027681CF8D9FB,D629BC89002BCCEA,B88D005E2C3A8F32,56386D851D5B66D8,60ED69D4ABC2EE09,1731219EC24A5538,966D87BCF622EA5D,62A6B07E4C8B3CEF,6EA16F4B509B81A3,7A97D35B5CDE162D,E25FB4ACF2AF1E4F,C48E64140BD3474E,000021FDD6C8FB82,9288477180A6C951,B2D2DE965A033D61,3BA1694AB827311A,70A5B57FC1C70CDC,BFD11385625A2E5B,2DDDAFB04A38853F,F21823FF1B225FDC,5F007A2E1641AEB8,C3E5684AC220ECAA,78179AF27DD10F63,96DC98F67C36644F,000007D6D89BB770,829327C9D19D0226,D65D25DC7C2E4992,D5DBE128D0A23BA2,F6DFC62FD21334A4,651EAEB5C3A9A583,180C253598055EB9,3F73FA2EEF9168FA,4318BBEE307725D0,54DD26A9FC5450F7,76ABA5758680DBA0,353ED351A6A5F735,00002FF3A6573DE4,B9993936AA2301F8,7B319EACE5E9B127,012E616BD697BA4E,811B1F35F96913B0,474DB18B6AB00C82,C1FFF493FE2C0901,796424D7A11AEDE9,61076638D85C4C48,64774660A3BE93D0,43FA3F433B9D067D,47A0B426F92F7600,00000A280AE8D170,3581912DE993F071,70141CFFC8A2ECAF,C3EB4B7D9EAADF4D,39E0D5685C6769F8,44208A1289B360A9,1495F58B3248D82B,CBC66BB98CDA2E99,CC3F8763F217FA81,495812161E7D7E11,255FA1A2A5D70135,240F5A6F7EAE5BA4,00004C1F4DD638F5,5B9845DD9A79003D,EF65F03C8F56ECBD,30F64FF52B455D62,D45579863FAD5D92,C798CD9C72EB564D,DD15C4F63ED0D645,9F35EC5BCF419520,2759D2CB3306DFB3,6A4CEE0C84723002,62AE428E1405808C,A93787CE06A12315,00004885205A0A7F,3184F5FF10FC6AF3,143B921A36E08BDC,4DA6A729B2406BF7,E6678BF19EEF357A,96091214F1C2F4A2,9F07E61747E02986,48FA86D281046604,FF69050DD5E29481,F97F744AB920445E,16B828177FE35D68,2A44107C12A0C668,000065CD488721CA,4E5420F1827B439D,F487A4ED360B1C4D,C55EFC7F8D8112D0,ED67A91DBC5910C6,9E9A78EFA44FC34F,D40F65D4211D8623,5C21F3F0FE48DBC9,09CEA4A83954032F,068A443A160CCF02,BA2D35302646DABE,B27CC0AAD03BA372,00002E3F49905A08,40785DE28D4C9530,A6405C1C01E10071,3C209F250C73B2C8,BF22E6EBADC20A64,D1DDAB04AF2AB602,A33C04772868D58C,98DA3CE309D547DA,4DD504F6F173D486,283B355D938C1316,99001A20441BA13A,E8C99EC8D3BB4B46,000006F688BD1C61,459A64577F98DD28,3FD6890B60AA7022,32B84AB229B33D20,7CA6E1524F6EBF03,4F0242DD469A4D8B,53EAA4C1EBC77C19,62C19F1C435AC30D,F230AE4E1F1BF94B,CF7E083E29C16D7E,CA42C2833B78234E,D01EFFD11DB566A8,0000224E1F2FFD2E,6EDAA71406539762,B74F189440621EB1,345F3262EC4F13E0,23185407A289E9FD,D105FEB3ED85CEC2,11F70813D04E49FC,D99654FECB39AB46,734ECF9475139205,54E95C9BD579AED5,E044D2C9270C1251,E60CAFCEA4BB3508,0000552B57BCA931,D91B6C9B924D91B6,9B924D91B6C9B924,91B6C9B924D91B6C,B924D91B6C9B924D,1B6C9B924D91B6C9,312D91B6C9B924D9,17D193651E9DCA60,8DF224D4272EC01E,CBD2BC92A7A778F6,A59CF2B6356CD90E,9C712EB8F35468FD,00005C2C61931F7C,249B236D93724969,6D937249B236D937,49B236D937249B23,D937249B236D9372,9B236D937249B236,7D4249B236D93724,6F78BF6586101FB3,DEBA77A01FF372B9,2809BF0C10D132CA,15E12E137474B550,32E144163D1A7A6C,00000083BCB784FD,0A014E250439995F,45FC65F1FFF85333,6BCB9B2F717EC6B4,E17F29C4A3AAB256,84007F11103DBAF3,8F00A6A9F3A093F6,9726358A43891D51,0897A6562E06B392,9C43741CF4F314B9,F134466DE6EFE2AB,F564982D2C7FD077,00001314C36F69C9,A43641B1D7CEDC7D,F0874E7045509B0D,792E7B86FF0D73E7,7B8EC819E2656382,DB846DE5527F9573,CBAED11FBDC7B5A7,9CF8B6F734116414,AB4016ED22D2B78C,901482B46AAC884D,6F313D2D60B58E49,8226CE453AFF56F5,0000541B0694E059,E39251FB5F896DD7,861156ADC66BF25B,D3B6E410C9EB77F6,0149A5B2E22C5FF6,39BF19B234BC83FE,6FC6DDCDE9500C15,33D635192E7CA410,F40BB7C04811EFE5,B95BDBAD0678F5E3,FFEE8DDD2907E2DA,71BB095C5885E70A,00003006B1C7034E,D681EED8B087DAC7,90726086FB0A1D9F,643AD6038FE15FF2,F6524CCDFEB45CE0,511BD3AA0B479432,FDAA3B25B585A917,16C0CA87EB477009,5DCAD9871ABB0038,5BA46393DEEC08B5,9AC8A0B793849197,A8F7FEDA5FA4EA5A,00003A742CC9DEB9 - - -v_3_torsion = D89D89D89D8A493E,9D89D89D89D89D89,89D89D89D89D89D8,D89D89D89D89D89D,9D89D89D89D89D89,8B389D89D89D89D8,B4C6B9529F01D8C3,1399AE2626262260,DE85321D9D8185DF,8451DC3FDF91784A,FAEFD5E487381389,00006319EE6373CB,3B13B13B13B1248D,13B13B13B13B13B1,B13B13B13B13B13B,3B13B13B13B13B13,13B13B13B13B13B1,7A4B13B13B13B13B,A30792A3BBCAECC7,8E3262972F905537,6EC1E1420B7BAD51,3369C4F4190692FF,9D6D588BD01A282C,0000028F2E2C80A9,673D45AA630B09FB,5673D45AA630AE95,95673D45AA630AE9,E95673D45AA630AE,AE95673D45AA630A,D4595673D45AA630,06D7B45385F91ACC,7FDE0F3B044702EF,F1BFC4766FC2E18A,D67138B8790E3167,9EF75C6F0552A406,00002C5A25459904,F6C4681424EE5801,AF6C4681424EE5FA,FAF6C4681424EE5F,5FAF6C4681424EE5,E5FAF6C4681424EE,7FAFAF6C4681424E,71E7F021FC96E1CF,BD317223E4665091,04D1B06EED834E4E,F423F47B02EEF4B8,0A418B4D55C23C88,0000094F95559E31,BC8EA75EFC1DB814,DC562840F895B742,EA75EFC1DA922F50,62840F895B742BC8,5EFC1DA922F50DC5,1B3895B742BC8EA7,0EF4E35288013377,7034C1EDC7954F9D,404E07FFDCD9C4B4,6C0D3C3112E9FC8B,E93593735AD57C40,00005E74FB7D527D,5C835ABF61CF41ED,DF2950278C2E9C12,35ABF61CF458FB68,950278C2E9C125C8,BF61CF458FB68DF2,7E9C2E9C125C835A,CA8064284EDAE000,B011CE81CE7860C5,F2D3F4033A9B8AE2,2FF7880A1DE06DD0,7182DD9DC3FCB499,00000A4A77D973AB,8AE21EF6EA938B09,37966C6ED5186501,69DCB18F74253FB3,3188241B31A56443,09156C7D752C811D,9CFAE79AFE751DE1,8BF44341193A82F9,34DAFBE7EE16D274,0272F0852BA272D8,A0F247E8810D0FE5,48E124BE4CC4D188,00004FDE2C9A5389,44369DCB18F7403C,11D3188241B31A56,DE109156C7D752C8,993912AE79AFE751,34E708BDAC04CC86,8C7E4CE5A9BBC962,F269836E4C98DDD3,045188E7965A38A0,DAB83EB832EB62A0,CCEFE1931E93559A,775966B73B29F6D5,000045DBC312B900,0B71EE1F7F5C9327,8A5569830CE94076,12961C17A5932157,DD79C7E8EBB6086B,2BEF8AB644F43951,37277CB68D98CE33,DE633F0A815B7506,61740E19C3F2EFA4,61B1E49FB5E4EABE,A015247782FF386E,E25E2C7B9F068D08,00005A5611C2C7A3,D213F53791E68D00,2EDE2F635D1EFA2E,DA72EC5F8871204D,DAEBFEACFFF3E491,5F948C8E72BBF1CF,4A440214B6EE743F,D224FC96C70931D9,EA00C3F488138831,9D46231784C01FDC,B12AA781AEC3B474,E312A59BD123CE5A,00001FED35710EB4,72F7284A69378371,03D4A5A89547E058,B12975E3DAE2E152,599E71CBADA705F9,4ACD0B0B6F42CE9A,E5285A0245577966,6C038D909BB02FA1,124374A6F770AF89,99103DFE37CA79AF,147E8A248FDBCAAE,EB9B0A578010CFB9,000037F0B3678B6F,5D470CF2D274DD99,C8516258CB0C2B2B,B43C53B94E11D2A6,5ABE2DE626199F2D,029D6C7C473EDC98,E0376A892583E1DC,C0CAA571F277C6A0,D4F6AD7F88406328,C9A2779B2F2431FD,D7757D28491C9C9C,3710D688A0ED993D,00004ADB9FE768DE,81F1C30C09FD33FC,DBF51DCE3A9149C9,E9CF78A0524C35B8,C02099DC646FDE01,B0594156B5517D78,CDF2CD6BD4510E26,A62E43C6D4ABA685,06282F81A9AB8658,D6D76B986C3AFC2D,82003479185AC489,68A227ED5A5D8D62,00004CB44C725522,248D49A3572E2D8B,D7958CBA82F9C02A,8CAA9BD2ECD45A98,D568F26B9E3F23BE,6C2D5F812C90C433,F1565E72D2FCBB81,27E816D21960503D,C557356BF112F986,4C0F35DCE29E0B8B,B5D66BBE22866AEA,A93F73DFFDAB2E0A,0000615CF5C957D3,516EE2A1BE021E2A,F602D6E151658AD7,26B24FB3189298B0,0D965FAF4CE85C95,EFEF3DB9B3A4B775,D851DD3FA8E08D31,2DA32E186C78CE68,143617DD482EE422,667237E94436FC75,1AC3465D96DCFDBB,56D74ABF63E8D5D3,00005D7C60C0D2E4,A30146117F0077FD,9BE366E0CADBC188,EF64080B2EACAD26,0A8FD83BF0D513C6,877CB3DDB56170B2,B35C3C73A225B6FC,BF79CBB465569B88,498384E224080C8B,B2F0B94988649443,B3DCD435A017EB4F,E9941938991157FB,000021C1C22E5E5B,0D40E007BD838CEA,A6EFBD2F6C46FEC8,DC1072B787D7CD36,7204C616DD691C29,F3C600AA941422BD,B810967F5BD8F3A2,53CCFBAE4D3DD147,CC071945DE01CFF7,6DD53CCD52E214A3,B2C2FB56192E2E38,D2B99B61C093CFD5,000051BE0034F0EA,8107763EA961F872,74B86F2CE50392D0,DB4527F030D9F82D,EC3F66A797FB122F,F4DE67CF2F609807,EFC422F586A5B1F2,B765C11D7152D2E1,B0A5BFC4FD2AC62B,589DF808D4BB351A,1165BA9E7035FA93,E9B487C366AEC785,0000586D2918F33C,6E3302C6FE0C0C01,DFAC66DC6CEDA28C,DED64C5EF280083F,8B39B4C197F785CD,11B93A8C64FD9206,9AC84CC06813FCFF,CF85682DC9D9B864,C23496D96970C301,5194BE86F6E26D90,4DB579722DE163E0,66DAEB4660E533AE,000015B525F2A541,7C758374FFD93EC3,2C7354CAF23E0942,BD93A801DBC916D7,47E4D764786D5DAC,0712497FC82C0471,87311F4B3AF3FE32,EFAEC8155C91650E,E2169C5AD02053FE,C96489E29375ADEB,5E7D1381050F03CE,B88C1A56DDD05F31,000006070D9E2F41,9ED7073D4D892D5E,7A8ACF5D59CC31D7,149DB0BEB6B3A2E1,C059D51CC46D3357,EE43544B33B041DD,5CC5EB8BC024538F,4B759EA5B9EAB631,A335C8BC0AEEAFBC,B03F67E326524765,2C790108FA72A4B0,789B5DA805C4192F,000064DEC5C9AB82,36DAB776C6A6E1AD,70788D740F12BB16,0678109B1BC9AEB8,6CC747669CD9ABEF,CBF25E90DDFDB9BA,9186ABE61B8B423E,29E06834AA38279D,45176543D221EEC1,761F084D3249B19E,B968904364D0E464,5DB85DA70B052289,0000521E2DDB50A5,395783F790D29774,112CEC9A5FB0FD8E,2286B13D7C636B50,3BB1C1FAABC848AE,CEBD9A801EAB03DC,D0D0F3042DC47BD3,BA7CC91C76FBFC6F,7E4B81D9BC252CC4,791DA3C97B45B52E,76E4B2A8663A7CDB,B18F9D7CDF16DE77,00006738B89E9A90,C5C400C8DEF67ACF,7DB5C96374C369C2,4DE65F1497C0251B,3D6A0B0AA5A7DC1D,CFF42CDA41FF0694,13585BF9A20DF747,29F5EA2387657EA2,85F982D144BC9D02,70BA26172B51F920,7CDC5B7AD3069E68,DA452B30229CE4DE,00005308C36EA06B,AC4F402D28A1B7D9,1F9692D5D204DA19,7B09C49F36556C65,74E03DD0CC93BAA4,2857AF2E2C697F78,B5B97969D9A74314,9B0B4C1B8B9C5804,012FE23955636F0E,B8E8FEC4456834F9,F6E7C5B893C1F2AC,05A45A12C0CF9B64,00004242B7D98CD1,895BC47E5E99FE58,00CFD306BF78ED7A,43394EBA61FCD38C,83E94C74E7C77585,9E944616E2627346,9BA6856CF3432676,2185C6AFF5533077,67F7CB233436A703,52D795D168AD54FF,BB7BF59763DC0670,79561A9B5335EFFB,00006F8E14E2EA1D,52170E4682673A4B,0AD4577028668C00,105830C4E5B35043,0E44B518DCE2097C,1DC57628AFA086C9,7017D10868A9652D,F52DAC7D308B4DED,E5F8D6B44798B8A4,860E5513916A8B0B,0EF1A2AE69403037,FD7E1676F8DB8D34,00001DA40260AF34,438DF92CAED981E9,E0EC927187AF9BD2,02C47A2EB752165A,10A814019E74674B,0AD43DCF5C2393FE,9EF40A6C20918C14,827A35EE6A2A622C,C5367CAADECCABBA,DEC9E5F60CC017A0,89393E2776CC5F44,7AD261CF40C946E0,000069EC298FC2C5,E370D28A643127FE,6484E527E4F15551,3F59642BD5A34627,85A03E71ECC4BDC1,7B2E731CBACBC6B9,70F5FDBD8FDA90B6,24E12F3C9683795B,35FAA7C6879A3C7C,FF53C1E88A24C6E7,E5DD61BDDC562FD5,E68B1C39660B3261,00006259E2A86D74,2982F0136CCDEF7A,8848824CB25EDE31,7BF8BC5D9CE7B4CD,5A3A0205A555D497,9240434A161CAB24,FDB3CBB75FE9869F,C97131D9A60D18C9,9DB915412B8CB0B8,5B7E4834AD58F24F,DF6E9178CA871824,F1259454624AC092,00001327C8999EB4,666280546751F204,3124828432952042,628126D710FA6B0A,1D3B96F1B28EB258,A3E698E6B79C0621,5CFD4588D9A09890,43A7B8C256D49EBA,E2F94301C0032B74,8953956AC6CA7C77,7F8015DC765F106C,82E4DDDD36ED8083,0000133AE4EA2F71,DBF063D1F1AF17B9,CEC32E934E871629,E2671C831AFAA693,960B975DBBED5813,203E4A33C527B48A,423CD368EF5C02DB,361633B23B9CEB74,5F11CA4E0B5ECBDD,AD9328EC4662A397,EA2509539AEEDDBA,15BB2346F14D8146,000002F2B9A05EEE,795D912BDEF015D7,65E6C0F35599987E,8BE785422F397093,CD93F70F07BAA7DB,F1A8945586B3C277,26353E447C9BF58B,4CD879A487B985CA,9E680A1F08FF3F3F,EA67CD5F51356E12,501DDEE09936B7D1,559A868F99683C3A,000023FA0B67D681,EDDAB05F06B5A605,C6E7FE44E0E20ACE,DA2D7FCAF5C0C0EB,7507BC508BE5F429,7516F14BC559D8F0,55DB0692A07CC717,12F7611288A3B08B,34ED3DD86C14B639,2BCFE7EA6234CAAA,A20E37F49CD7B313,ED785E90CA869C5F,0000524FB4A9B68D,B24323DEA264A910,FBB77EB1969BA34D,06DFE6BD2DF0E62D,4BA1D9212AAC1737,6604456CC168CE0D,1F045C2902E70B1A,C30F3CF005747BBB,D0808A1E60231D09,616E5202B8B68AB9,91279DE1E1F59C61,17039A54DE74E351,0000483F7B722965,CA63AE6778B0F84E,3920204D38EBDF19,FB1FE6BAD523F1EC,8B34EDE136AC2733,7409325BA76B71BB,987FACF98158EF9B,3EBAB81D7CC6988B,518A2D688F371575,C77B4766A9D72BCA,AF7343FE6E77A7C4,54516072DE9FE449,000052E493B8BEDC,95B9273E98BEE101,6CF2C2CC7C2F0D29,EFE3B76E594AA11B,3DDEDCDD1FE42241,F7E15F986E39CC89,3CF9E152B6FD333B,E7F2CF0844AD69DD,B792DFF3C762D02E,3888F4A332FD9030,8A4CC0E4C437575A,833E2BA7BAF41403,0000135FE5EBD4BB,657D9769E52DAD91,84951CC10B514173,7678CDEC0CC5511B,D4E7DB99FC763848,C6ADD473DF8087CE,842DE2D06829FA76,D086DB2A4651BE48,D0399255E5DAD344,6B2EAEB21B8BB524,F6DE9148F0694AEF,5A85093194755805,00002570D86C9FCF,D665CD614A703CBD,7251A4FFE04E2B30,8AD6A13EAA0B07BC,2AB5112D91260BE2,F31D78441E75FDE5,981D1D465A8768E6,7AD08CCEE352CCDD,31C6C60ACD409AC7,DFC10AD642C330AA,16DA3C495AE40C44,89AB4B294D700C6D,000013081265A555,B649623190FAD2EC,9E0A9F4A626C11FD,EF8A6A8092D66371,EB9370EA38CC1EED,74BF8D8667FFF12C,F931EE21E90FE5CA,5E180EC10EC59AE0,BA6729A7EF221E52,AEAB0D0AC6ED85F9,2401EAF62859B015,D309B49CD60C1B34,00002CBA9B452CC8 - - - -T_tate3 = 27DD15B8A940103C,698445579C6FC8AF,EF0662EE3F8DA506,93D4F81B06781F60,C74371742E7C108A,03101E9FA3DF1F2D,F5326D30834BAB52,CC65719BBE7A0F07,DDE26695C63C52A9,5EF3096F1CC1375B,C294077DF435C984,0000082F3986076B,3473C9FA7E5404DB,4F95A1FB1D629EA5,712BEDC72A682C10,1DD108940590DB2D,88BFC71946DE8BEF,E41ADDF572557D71,7552B158479D3FFF,99E1BB53518B911B,AA15601D2EA66BDF,3BB21CBAC6C72B06,5AFDB90E6F37C129,00000AD8B9D22E50,1D03B8B14750F050,1545B963A3FBD292,ABF9110C1B06DEDE,3FDFF9C8BD2736B6,98C7049844B874A5,AE5AB4D180ACDFF2,B2B03879747E80D1,466061A914E71020,EF39255AB2765772,F44DAF12BF260DAA,63A33411506608DD,000035F8D0942C29,4C41EF1D22E3730F,68090B20EA18192E,935C391908CFEB88,907417F890C3D4A7,062730A7D330A3A4,A7E28590A7B8CC24,F119C30CAEEE2222,9F57B7D3E735D202,E96A09A47460C945,CDE908B9508F202F,2A5610F61338D28C,000062D46F8CD535,F506C72790301F65,81BDE514D427C37D,73EB4DE892519A96,36AFF40874618466,5D53626AF47DD1DF,8C694A59134848A6,087DECA426BB0D72,5B9B923DE58AC167,06B73AE4AAF31F30,2202F66A5F525580,CD5448A1EA96723B,00006EB824809EF0,C195DE8689A2FD6C,A109A88AE0397829,9A0215273010AC45,AEE291C7219346BA,BA84BFF92BA1FA28,8E97DEA0B08DBD63,582399FC4165E40E,B33116A920516714,18BBC373DBA7F1D8,0CDB31D989C06D0C,F9C8FBCC8D34E576,00006C6114FAA9A4,48C137EE4E478CAB,44E62599FAAF4E06,F05611486EBB7304,0501FF325BA0B6ED,611F4852609A1831,6C6AF3F43FBAAC0E,CDD201ADF7CCF097,A7407BF8B95DCBC3,1D2C7DCDECF6EF56,189A58984ABD279A,CF741A50B523FF00,0000470A2BBBBEB6,1CDAE85F214D6C32,749F9F77D1BF2C46,D9945F9BAD81FC58,0AAD1FD641B6DF6B,BF3AECABB7688DF7,C7F088F8A1AE546E,7ECC318544EEAE08,1EC797D23BC3BDF3,0B78BA5063DADD7E,472A6CB0E73F8649,F1EFDE3F8C775A21,00003D3C79A41BA3,654890F70F254EE2,46FCF3F802DC1863,BC2ACA8732057A49,4793578578918662,13F9D2A8055FC5B6,95134A341F47A377,B02678E2FFC3F9A7,B15EEDA559408FD3,DF5928147B9874AD,05AF25AFCA56C562,5AAF5F2A26F70AD2,00002999090B0934,24AFE67E904D1E7B,70A4296D4480E374,7D47CEBFCE196041,DBC6EB8FD8C2AD30,A2715D74F3DE2FEF,65E9AE1945DA8895,A304C3917064E243,68EDE55B09294838,EC2B4DEC447F24FD,7B8D6910FF878D1C,7ED7122B09453E64,00004C1E3D9693BB,0B6F7D6D95CBB4A5,F77208B181FAA21B,837E9B2C63489521,5C3B23B45DDC65A2,40E8385F8AA6531D,D4979ED3226C8D19,5CE67536708B4C93,7FD383B8B5A7AD28,7CA14C29E46E05CC,47C5AA8788B93085,5E1AD8ACE0854B42,00004D9D3D953582,B7B6435234F3E181,E0D2D28F51DB59A9,01247DCA8EC56E66,35DED45949912A31,C1864744A027371B,5808F8ADB370D498,5F67E3655A0AC3D2,CB39B4CFD962C12F,9BEC506F8F1D0B12,E7175121352F092A,5490EF8254BD37C6,00004B8A61AF6106,AC349D1FF4D13AF1,106F79E101351FF3,877CAA38D78128A6,6B9A534E6A0F9DFE,C2A783F3AE8594C9,BD4CC798AE2F6E58,2EE9F13CAA22059C,A457F0F9FBAB66C8,79657BEC936CA9E6,8D5BA16E8C374059,AFAC28183088CA3A,000069A201357D0D,ED04AC1653CA8AF8,A80878C3C3A2EC1D,D1EA429583D566AF,9271AE45BAF46187,1DE359199DA053A2,08D86898DC3A9978,1CFF69D03680A86C,A2C1C9F40713AD4E,63FF6C657242F3C5,40D3A82B83777930,6A516DC1B80F7710,0000378A446595C2,C8C8AE7E5672FAEF,80A2BA4299C33A15,853896A3C8583D3B,6EC191226EA30988,47E271D3D9C1170F,9511548DA4C7B80C,84B50C649C598D1D,A2369DE7C229779D,856EB3DB68C61F41,4A6C91708809DA6F,0970E45E9AFAE435,0000208F25F4E4CB,47DB16A45D143655,9EAFFAC87CCC30A6,A161771EC1CB1744,5F37A551302E97AF,B339508C6DA1022D,CA7D139BDEB79F5D,11030EFD06466CDB,948B13D5806C8D94,D95D27B24AF17C40,83FDF65F891DC33A,E441CA7ACBD588D7,0000269BC8FC9DD2,FE228564FDF4EF1C,8C949CFEA47F9942,77A75FE6BE359434,FA22B6F8523DE1F1,420B7C9B2B0A0DDE,B9D6D9C4E1D20A20,C3C341C47A8635D2,F9A76E97B05E321B,54FB524CCA4FDE38,03BE8E5DB94358FB,20ED2FDFC8CBAF60,00000DABCE633FB4,0EA9C32970A9B8B5,35681AFA2347A2E2,9C4FC5C401B191DC,828FA2ADED7A2ED2,A6103BCA059925B4,64945E98A706218E,72DD13BF9BB6EE98,81DDED0E81E39B57,7B407F083BA79458,8AE8B5D83EE8C976,260887045E98D20B,000067878FC0F05E,E25C55A99945618F,6A2AD616786FC92B,2A73072F3B4A43A9,F1C4FFCFA82A00E2,576E1E868C3889EB,E655C9AEAE0D7A3A,55CFF76DB1B5DBA8,3E7F1679B83FBC2C,152AE6198CA610DC,C14EF0497313D1D2,AE9BA246913C7355,000000E7DFAFFD70,9674F55496D1DFB3,7004C6D79B3A8497,FEB3FC07FAAAA026,B34968F053876B2B,62DE0C3FFFF1BC77,8629B80CFB5D3143,1498A8BAC617E694,6B543C3E2C98415D,CA9E36A9BF66112D,2D0D7C15DC485C7A,01A3112A026AAD4E,0000000398BFE09B,DBB77D7DA7DF767A,D594D4FD412F95B0,A9F5D84FF021EBE8,3D78BE5CA9727EFC,85076F15E9824C73,0A05598C1A3E8D5F,B66FF100E28DE4C2,E27187F3CE2AF4EA,556EB1F8DF44EE32,3A21C08AAD6169FC,E6F76B7A13B795DD,00001BBB94C87EE3,ECDAB5BA1B165D15,CAB602B7DDE22388,B41892CF77242694,BB672311D503EF7B,128037FD702B97D4,DAB844A0A56E9E52,67ABDC0A3DB2FBC2,4732C6D17373D3E3,5D6EA883C4DA2E1E,AD180ED09AD8FB52,00B8C5079048AA54,00000E7E87AB8651,E781228F72419840,C51481F3C47F0B6A,4CDFDF0B613C4430,13EA7A47D47FD86F,0A024404100BFFD8,E9B9499124064C9E,AB2C978DB8186B0D,6B6AD7225ED4C3F3,154ECC643AC67650,9E05A829E4BF69E1,26082BB007CF1FB1,00006828C0A86A4C,A6FED9510B44DBE9,9D79F771023F2DC6,AE4F73C196CDFFBB,379046A26A342B1D,44F023F3E05C312B,A5DE3DB75A486BC1,86371784CC327395,F0CAF621E8628D7B,368586F1A0000799,DE3A07F4189C0502,61B02BA6D5BF3122,000010BFF23BDEB8,108F3B472021BE40,1E49DE9A1F923FA2,4D96A0CA68577C45,CD21F175B51728A7,FD4A6C7ABE6C7CF5,3ED910342333DA1D,FA3F9F2BA6FA9961,F04D53C757A812D8,882259D99EEA6A2C,1AD6DA224488D129,97EF740F2F363E84,00005B1966DD6A7D,51E705069745FC39,0B429CBBC240A5E0,7679D8A54342E4DE,CCD9735E7D1EBC40,F5752B7EE77A0B96,34200925F94B08AA,C04179248D460521,B177558B4DE874BC,E2BDF0C8CDA3F8C4,E1AE298BDE14FD29,26A5CA92D54F6CA4,0000465E248B55F8,31B080E7EB34890B,31CCA1CE1739D121,05661164553059B9,4B24F8A4513FD5C0,09CEDB115184851B,FB9057FD023780AC,53659C87BCFC792E,F1735FA5D84107EA,EDD0939D039B895B,BCD986B10959C24B,065B8A6216D766B6,000059D271F1F3E0,44F0EC3E7638DE1A,02229F924A225D87,E1C4D666AB03B3C1,F3536E905225E713,AB1E518C76F83EE5,42CC4EDFEE87836E,0C93D564BA08A0AF,3F4CF5FAB51402E0,32E1E1C9CAA401B6,676BAC25532E52FE,B5CF21461D8D9606,000045E91FAF0A47,9A3AC9AD9F7C1CC5,712A4C4972B7C390,97C03710D699B327,B3511859B86792F2,30E57ED4D56DB9A3,7409C2FAD6C6BADB,A68815034078CBD3,8A720CF2CD76E299,2E767FDF19304119,5288A132F92B58A4,06868C450FC4E617,00001C1F50B6626A,61D7E096FAF42D0C,7173C4705C2C8F70,46445ECAF92FFE9E,46A59FB28C73F425,A8A256F277A34A10,3D8902E9926ED1B8,B8483F00FF66F692,62ACF1C702E2EC48,3E866FF1DDEA00B0,2D5BA09717C16760,481330C9EB1DC919,000064A96DD23D19,E20D12337BD6262F,A86D7867739EDCCE,88738AB044672A48,6B650370409A7BEF,923BAD3C19E6C486,99049310961B7320,7FA5B1713A2BCDB1,71BDA2BCC16F4A6E,3B52F1BB148C7D51,8BCA5A27C4EB9332,B3437D42D8E0DB8A,00002CC770FDC06F,F5C02D73A67DCE0E,9754CA34616F3CA0,82CC50A4AE5BAB3F,28CA8D6FCC2E1B63,49F2FEF4C84FE094,FB59B1765C516261,018C0D3F7A843DA5,3DC3BCD58C772AEF,CF5787992D5066FE,3903C8E0E7B17517,4F389F3DD4657AC5,00003CBDBEBE273C,D6452B47780A8B61,F0842387FCE72006,96F46DB5B0F205C4,C6EB91D4EDD382D8,9D955A856D74968D,75BC012434A2AF22,736554B9938E69F2,DE87BC5966C70658,6E6365C422B08B98,DDD7C6B4A51B9E7E,8D6F049C92900789,00006AF1F5D9ED01,A9F7E52C8F97F54A,7BE47A364797D000,CEE7C89A8E56581D,21BEBAA683A87574,EA4AEC27E7CB8A1A,5ECAB1C77B73E3C8,45AC83BFE0BE8892,9368445533E80174,EF8B5CF5D6E6AB06,368063EF435E822B,307C2A29D93B5434,00006E0A36F1D8C4,B0C1EA4226F7AFF1,B36A5957917C147A,BB36381F915588BC,C7A6555A00606F1C,B9F48320E52D8C24,A904DA5EC1FF1C49,2D1ADE347E7D0D4F,5BF07317AFDE89E4,D52E41CF72535C7C,969DAACC82071782,DA18749AD453D78C,00003C40F4434B63,5A87373022C07C76,D70EBA4C7F0CE835,6421DB008363309B,EAA9179B8E5E347E,49DAC65EC07BA4C0,457C69E4FA7759CE,C811E475BD58F179,1B5C29FBEBCCB089,35C302AD4C73E855,F8AC078C560B0E33,E2F4FA21C9D89D39,0000020EA31CD9CA,536A8C53756D2181,78F714DC5AA82067,B36F33A5D560E9C6,0DF22DC02943B376,95D515D8573C34F4,D32D6801FA7465C2,7C463CB5F639D4CB,403AC004BEA1A6EA,80318F2379611FF3,B53376398ACEAA4D,D1F7CFED792973F6,00000401CD1D9281,CC82C08D4C969935,7713803E4A9AD336,4BED71141D4CB57E,1EF2F63610CA5127,D56575EB942AA077,06B587B499F25461,904CD556189DADF6,E77856361977B4DD,32D7A8B71F1FA582,6A3B5AF9F5177726,F42D02E5BCA04B1A,00001DD1755EDEC9,4AE42FCC0D68E95F,6967E8A36119C2B2,B167694F2EC6E540,FF34AB65504960D2,5F32C95ABF60EE30,9BAB8B55A146F593,7E89F7AC99E85A86,0632BFE6685DFC78,12BCA4D5FD01430C,A8670558DDA1F3EC,84898979DF7DA337,00001978CFAC115F,FA3B8499FBDCDB2C,0D092614F6CF328E,C89416BA1DE0EB96,7D779CAFB478CD3E,7763C8AAEE7C110E,5E746F12A28AC6A2,3B73264F4AA46FEF,655F5FB8FDA5BE1B,0BF0395F31719D0D,0534BA7933F7FC96,15C92EB7701F2C30,000019F9839086EE,20A9CCDC45459BB4,ACCF927B42469831,FF5106F2A51BFC77,F52580EE497821FE,35C6EDAEEF8DC248,88DB23B289FEC6B1,FB4B433CC3FCEA5A,34EC62369F558039,F47C44684BA6722A,1B39FEB1A35B91F4,CEF76C0FD7866CA2,000022D23C42AAED,9BB8C7D5B528384B,890615FCA69DDD65,637149FDE7CCB759,72626427D04D1911,88803DA75D138B73,BCBBB899C7CDED80,9B5DC28D8942225B,4D4145495D5B8E2B,CE61BEE1CF9BF2AC,75F13C3B271E3B7B,FF126C76C54EA7E4,0000439462E68BB9,E3FFA526D8CF269C,4AC44219FDBCD6E7,70B49A34533407B8,8BC9F7112429D6A7,29C7BE01670C0F81,98376FB19CBB244E,7DF4A8AB6912A718,2BFD48B586DEE586,00DEEB3AF99429B6,80E980A4812140D5,6897660BBB700731,0000650510B9E688,C80660EF52CAE02E,D86A90151105A2C6,4EBDC721417E5357,05CA6E635F007DC1,AF9569221733B81D,05C7D98AE90C6229,ECBEA83CC3422E7D,53385D011FB238F8,999560236E869E4D,1034660F55CE3BC8,A4DF123929121661,00006D2F1FF67619,664340DA7249BEBD,06B92432B6C0E45B,7EC6114B45414118,574CCD91DAC3CEF9,786A0B1FF4BED68A,F1217992827810C5,46AA89E5F5A0B9D1,6003ED6D1689AF8A,51EC3769987FEA0A,56122DEBB3DA3DE0,A4F36119E0D0DCC7,0000073987285FDC,74B8B69CE9FA8B46,EA68CF44E062E4DD,947BE05F04EBEE61,092D96B303A90E39,211760C1D663F618,2BAC9AE4E33FCEDD,49987787D28A8DC5,4B882D585EF03EE3,7189DB701C262DED,B8CE7BCEF712F654,C3D292942C141082,0000021AEC7830FB,BE95E3BF25F5D9EC,D238E17876A66384,DDED6BD6DC72576F,B92EE5AF2842B9D8,62C070852A8321B4,6AF21B3830529268,3E01A0C9288D9199,5F2DC63865072D3D,93716301E7DB2324,CA6EBE14F552C910,1EB312AC3AE59327,000004DFD743D12A,183DFE83D3151A82,9718436DD690E93A,88FF70F8CDCA68DC,869F1D95E348733B,BDEB4DA8A69DDB15,2F48A377662FDA44,96E896E5C43B4C8B,36B3BC71DF184454,ACF1749CA738C77C,A3107C8C661B9F30,6580C3986F3ABF2C,000033BEC3A78D7D,A3F70C9EA38215A4,F423E142B5D131E3,1C3AC5C2D8128270,10E961D8457AF65F,713D79A91036765A,BFF97E7BA0DC589F,02220759FD2A5C41,D7628E9B80F96453,76BB761D30D30120,DE3E794454EB3AAA,BFCB128BED25D312,0000607F097B4848,42118779C4080AF3,A14C210C7D3550AA,EF66F11195B2804D,A93BA2B29617367B,2B4D65B49486E7BA,7195E01FBD42734F,2993DE67CDB24B21,74D99633C1FEED41,DE3CAFD36BAE1111,9D342F6455A328C7,E282C00708557A97,00002970677FD37B,D5CD1FBB97196E62,B94185B9A483C347,DDB24972FB0F93E7,F1965316D85003D1,83F71CBD7D7EDEE2,5FED73FCA694189E,B550992BB72EB766,F09B2BA32F4975E6,627F9C939E9A4A33,1C9652AB50A29438,8D89E65B19617819,000051901CFD11E2,570FE8E806C5D75F,C56C3ACCDA1735A4,D1BDD589DBB9BB6B,68098AAD5BF1E3EE,2BC345C878F746D2,66E8DD8982220FFD,23C28884381BC103,02D37ABCB376CCB7,65AECE3461979155,190CFF92062B3B1D,5F4B13319EAAAE60,0000195AF1CCAD69,E0DA66F763D07A4E,96D7373287625255,1CF17EA2785978CB,E5F532774108EB5C,2F8B9DB04327347E,9F0B02E351BBE5C5,C2C2304C1EE109B6,9FD32662641CEBF7,63E6A540C74DB02D,B83B20625CDC3B90,40C4C66EDDFF17FE,0000414451EB48FC,BDEF7F980612238B,C9C4FB84EED9313E,359891B334E3B308,9572D41BF3351251,0C8BC3B5D9723E4A,71954027CAF7CBBF,F3B6807162BD9BD2,FC925D0DB8A1C980,550A47D8FDD4D8FA,1FFBE442D308C965,ECB59FDCF7418CAD,00003941F53BDB40,A5E40DD01BFE0DC3,03A76E5E07788D24,CBF23E2D9B6E01DB,BAAB14446121591F,D56C0268588D69CC,6BC01239593FD93B,99FE1218DECCC29E,E153988EF185214D,322AAF9F7653491C,95C6FC7B8B55828D,791690C9C33C9C58,00003EB45FB2FD12,DE9537621B0EEDB3,6CB912188CE09B8F,81915BEFF81299BC,425A2A237639D6C9,A76C16B9F27DDBD5,62DE972ABDFC8713,FF437699D04BFD61,97431818231EA85E,13E7228B44B44288,1775E7A12BFFB1F9,7C0ACB02F0048792,000047BC0AE17683,3A31CB3BA8C45CC0,5E10F017550B9132,AB5602135DDDA6FB,7F7E45CDBF4C8841,D299072BA36838CE,ABC7B380E0BDFF4B,3DDEF95FE7BF59CC,6E4F213EE8BD1D5A,B3DAAB3F1B4ECDDA,FDB9126BAFA50AC0,CE448D82E9BB5336,0000003ECE6D3446,88D74ECEA659DE2E,F8D08D34393D6E34,EC6716138E42062E,BC41D0E65431A58F,531E6D101B1BB261,4035AE0D861F51E0,07C16F16B7656AFB,93D04A8C78F20502,B2E57A0EDB5C24F3,F278978D87C44691,1AAD400817445770,000018A265174621,A3254734B3DB2A8E,6F453F00AA4FDFC1,518610626EC1C311,E46069C020AC089B,138A58E55280F554,10AB9E13EFD78F3E,966DFD0A458AC197,DDDC748F338BF023,26475CE604EEAB85,B28E68C2F5B98AE5,4B42B42B97017545,00002F2CA02175F5,3B0A439E7FB60491,3E4361D7C508A2F4,A33132EEE9DFC3DC,F774FF837E182C23,351DC2F2CE373D5B,3E560156A343E379,5F03D4D327179103,05CED4D25134F47C,47C333C63F32C9B8,DE6C1DF13869FCCB,FE4A4AF75B2DC57A,0000532134F80632,FB5784890A597D36,CE35577ECCE95F7A,33CB5BC7160E6E03,B0FD41A49AE3E69A,370D28E89D09FB14,35FE747AFD13E15F,4CF1D4EE4C1621AC,68D48672709EAAC1,8B9A34E32306D04B,337064414AC813D7,D3FC1445DC6A2B48,000045EE94E82D6B,2703BD82433C1FED,B54AB56713A228DB,A0F56244A9CF230F,A5C1E1D5F30091B5,904C95210C309F50,1A22F46F4E7A224A,26832F2C69A588EC,B44ECFA45E66F2DB,BFE8D971D5D99CF9,88C3A6FF8345F545,B1D67AA4C13FE32A,000034B4EE06418C,AE679E7199F2D329,6ABB142CE2BEB55D,E815B159C068D787,303B0D969F5787CE,BF1A7FD02440E491,9B6A71D233155B8C,14E16432BCEF35E8,0570EE385340A2A7,0843371EBA1BBEF6,0E6B521DD9BBCC54,A014F279E33D18BA,0000293D768ACDE4,25F090E346B40721,9201EE5128A42061,8985C3F1BD37DD32,F23DA8E7961FE168,7ED32BBCE3126998,C77788A81BF36450,EF9646DF1863B75E,1EA0733655F346F7,0F58AEB119FFC94B,CB6AD64B537C2376,5133800A96EDD656,00000970AA5B1E42,783D687487F0874B,32F705D5903B02AE,A75D4DB36E14EDE2,3DD7DBD871965FD4,BCE2E3C22E5F7288,9039A7A295E37244,D82CA4BCA83AAF94,A41EAE830248F980,38A879A04E090B3C,8612B8C668F767D5,B0F7F563E8A700DC,00001C3ABD62C7AF,75306274827EEB0D,8BA9A5C1320CA218,E69B22ADE837AD85,7472C1004539B96A,95D56FB636F43D70,D6FFC29B5A7CD8A9,527909F3AFA67D69,DFDD1B7B550A063D,64941D6092267B0A,6D643435C2E6049F,A5E650E70454C87A,0000409BFE9BB591,E3C55405C0AFC72F,81E8E52612F04B0E,E409F33A01CACEF2,5191BAC71E832D0D,DD1A56B8C25303AC,F1EA09E6CCC9E4EA,B981D3C8F29EE220,FD4B858B44585F79,28AE86E225C6AB3A,9DCAF23A9371CDD4,F2F2F507AA0E1040,00000991969A6F50,C4846E4740C9708A,82494E891C759FA6,E1E03BCA222C9CA5,B9E40BBD128C151E,3C2D2322FF1AD530,54393F1E4E8DC98B,94B86381CDBC1743,DD85AB4E890E9F3C,46C3C6E56DA1CFD8,0D8F91CF3A31BCEC,DBCC02BCAED6D9C7,0000111238590510,9329C6938CDCB4E0,E0C06E6FB3769DC3,CC179B477B46962A,1489E3312F84211F,5572DE377A014EC7,1E0AED2711A84226,8564A2D5E242F131,161B71700DA0CD6F,EF46BB0789FA224D,BEF13F766BE0F7D6,512A175C0D0D2545,00004176B399E536,0C052CDE540BCB4E,B59E4E25423A9B84,ECB1C4DA94A04BA5,0621F391F3190115,840ADF88444CD2A3,B7B7C57D18936436,614436F4036B1841,A8C8575D083224C0,6CBAE1703D8CA89D,0C6079C47CE720A9,7E93A50B9280A5D2,000032F9A2DCF976,B633BBF555A633FF,B858799E40AF2E0A,E4114D286E488D0F,91C8C248A90EF6B3,236A6017FEEC23B4,789954D3610DBE2E,FDC9AB0B33E3EC4D,6F2F939D5BD44AD2,FC39303F9F4A489F,14B50ABEA66964EE,569FDC7AA47E9E1F,00003EE48CC51DF1,2D6C02D8BC68C767,4A7D2101A13E002C,10D4F79F88FFF249,19D25ABC7E750514,6618F4077B966B67,0AB32E07A38B86BF,C0477EA8781AC19F,B9F9F9E414D4FFB3,F7A8CB739C6B5943,F50FFC58E7EA2C58,47C94C6F50CBF743,00006AF57A517295,A0F1F20FFB996799,BD5764A9A2A2FC02,4E59B976DF07B2FD,26D61E1258B5593F,AB5E28D62C727408,F447EEF7139A67CD,5572223886945809,192AE45863841D4A,0331C3D1E3234486,70D913527211B46A,322E6E50040B8651,000035A3F62DD66B,CA4725CB7C151D90,5DBDF6F8CEC475EF,0E0C3482AB7D8207,94C833C562450194,3E6133692AACB5E3,FABE8F3EA83E07CF,1F03A975627CAEC3,FD3508E14DF68C21,6FDC072B69B77653,227B6B7C40C89238,C7C4C1A12505FE35,000003487713B550,51AA5C853AC36102,827DC9F6F78E8D96,2E49831EC295FDEB,FF768BD703E4104C,5026AEFD12C3F064,08D262D25D4B8314,890CB613760C9C07,C4ECB5EE5CC95302,06CE1D4B8433AF8C,E0D713FC1AF58C6F,CE10D7E7E0B4E9DD,0000399C184F8A44,57A2FE34CA3A0BAF,D33EAE20B1CF9FB1,5E0E9EEC4FF7C042,F505FEBCB1F7B7C7,39CD1A53C12FF8AD,2C2B76B2DAB50515,BF9A4840E0FA356B,A56875C70C3682C1,A6D5B53B1625D64D,AE87ADAA800AEF0C,D980B3F3FC0F427A,000022853CDB365D,D7CA92D5D963C14B,A9E014A5EDFA243C,18764B08EB94A0C9,008DBD4DDFFCC7AD,B7048C28576A89D6,EE4AF5E4D12BD7E7,434AE852ED649E54,8A88FA5E7B6694E4,F1EB472A9270EB63,BCE5ADE2C9B8643D,347FCC438ACCFD4F,00005850C9463439,6AA55D1BEA907CD1,47D414AF9661CDC0,BEBD6685C143D326,2E14D47D59D06658,9C127655EC0CA5FF,515AB266E93EA66A,21075B9F491A28B1,61E52566BF4BC904,CA7DFC20CAE06EB0,6CF6327791E266CF,C5BFBA0C0AB826AD,0000236514363B20,3ECA8107A4C43AF3,50E358975D8E099C,7EC015F6EBA069D8,C329FFE09B61D20E,0CB428E552DA93B4,CCDFC8BE9D81121F,10AAED01CC44EE6F,734EAF09913884B6,2F5F84328C17F074,A4BA48DDF8E98488,31DBF78FEB2EF726,00006D6EE496C778,17397CB0BAC7A52C,F289CD9D8A53BBC3,DC4A061BDE7CBDEC,FCE3E3E222A6D994,8A01D48D30F96987,E707EEA92DFEBE14,DAA19AD9D79BA17E,3742C38AC25242DC,8ED711DCD3A6467B,90C0F7E3E0477081,E4E8DC95DBEBEA47,00004A3E6236F408,838982293FCF93B9,811215D1986F9DFF,7BD3C49C2B1BC3CC,27D95E7794F84A3C,FFCCBFC17930A88D,E006C9484B29B493,5B41410BE3B58F0E,95B405771B843C94,D13D12EBBC1DF120,6B07883B6053A8E0,42E9AA7311177B49,000054CF70F6DAB9,B388C790035B06B6,30D3F7C2C89F45B1,C5DF29F5FC21954D,C03C48D0B6C009F9,ABF13086D179B74D,6427D335B9F5AD04,D243C77A4507F1B5,6AE7FE58E8043923,A2CEA794CB74A27E,C549CB58BD40430E,B82141947A5AFB40,00002399268DC609,8E8EE96A8CC16158,C444A18202E4B4EA,6D50B1E4CE3C5C06,10C4A7D5E8C49CD5,09CE20AF500A52FE,440E5BF4CBCD57DE,9F7D3FCDA6870332,D6D386EE0D0E06E5,00F27AC63342E57B,38A2188B4BEE8C78,27C0A2A2ADB0200A,00001DD3522E84BE,F8FBB4E348C09CC4,6A87A2EB79F575C5,ECAE6A0180A78768,F5B13E158BA09982,E51005ADBA0465D9,CF9140ED5ED70201,9F521987DB0CCC6D,D98F11FE47739033,A4042BA3F0DCC769,3AA0130169642A5F,42E590297A2BF3BF,0000377223FAA640,E7CD6A7AD62F109A,1ED4080EA0638B61,0BACC3A51258FEC3,5E4D648795E8EDE7,91E51635DA54FCDB,395FC3B6C99EE7CB,105510D3CB79E7A5,961548328AA7F208,66319E778CFC6877,077223986DB0C16B,5BC47120824187F0,0000270A12FC9549,ED65418A6CE77289,9EFA71D8B3E2D27F,F4F3B14AAA9E1F4D,0408D06F899B203E,254CB3B656353304,5ED3994CFBC7ED97,93E6594A80023D50,127B453B64C0C38E,C3A48B83BCE8B81D,9C75E543E0B1D46A,834277C021A6653D,00000DC2F49B49D3,FA514CB3CA805748,89210D3DDBA2325E,3641C9A4199FA0E6,2A754674C9EF5236,B024495903B9B511,9CA36C5222EE9B5D,E62797B277B899E4,AA82873247F2CA3B,A4A4CD1D98530621,C50470C961EFAC74,A010EF63AC1057E4,00003EAAA16A9646,334C5E9441195128,67E3C7D0286906E4,040E2C6688AA3028,1C68A7E7491E6702,3FDCE49E529F99D2,73E793BCFC2C9FE6,E13D275052752B31,F9CC6CFC9E8C6283,B43568C44C9B7C4C,22FE92EB99B2A69B,149CEDB4F97FA329,00002D3ADC7918EB,7FCE3F10FB4E2C81,8B09DAF61C7369CD,51C4B75203F51A01,DFA3A529E5F3AFB0,B915274DB1960F8D,099F601961216ECB,2D710BB181C534E2,5D8A024371BCE1E3,42E0F76C1A5930FE,C9ABB506DE7EBB2F,7DE960EDD0F36314,00002778DBB00656,F8E8007A8226FECE,18CEF99466357C44,4183FC1C72031ED1,0401E46EF63D2563,90B2C69D1ECF8219,1E51B3BC706BAFF5,A6BD6BE73DCFCBD0,15C025C42716F6D4,94235EA8C9A6AFCB,59DFF341125B1162,75FC91D8405C6F7F,000018F718EDA089,361B79504155E080,68776E17FEF8C44C,CD41DD6587FF2C20,D2B8652F5343446C,526F93E5A039831D,F8821B94D8F573FF,0B7704C919B0FE32,EFD6CEC4E6966760,C1A5A733E8481120,A620849A8E622B6D,3E262CE6527930FF,00002A8626BBA28F,37A85DEC98AC8B24,088045316EF33AD0,EAFA1975415D54C9,6C37B4189B3C0F00,8E4FBD2DD1DDD56A,B531735C5E4A26BD,CE9D4649DE2E8DAF,5EA3C16E12900A4C,2522603B8E560A75,4828D935DC551977,D8939C19819C0739,00003548E957B41B,4355D442A39D3C86,46C15F37CA2A4F66,07EB445B090E3DBB,DEFCC75E0F007583,7D39382B7DCD8E7E,427307570EB67297,7AA95D6E987316AE,E09F3ED1DB5DE146,FBC23AF76476810C,E09911BA70F6FC14,FBEF0232E29BE7C2,000058E83F2F57F3,1E940137B7917B55,605BA68F35D5F46C,F822EFB991C62D04,C39240607636EA89,02F1202EAB790A48,FF7D9C72566F6E79,136E0FC773869BEF,45EA0646DE3CBC0A,C498778EE46E9340,5F71C21FA3F85575,7C1B3FE4AE2F2FE7,00004492419501F1,B9E1090E110E46F8,1F00EE9FBED47CE9,17B6440BBA617238,FBA2BF9AF63B132E,84374042E8A23A27,FE998B15D445A2D7,DA13D8DA2CD1853C,B4E927FCEFEDBC8C,EAF5DCD6F1867B7C,5DCCDA1992FF39F5,8D4600103E873931,000024C7FA78336D,3214DB2E2F17C6E9,0A04B097C6587DC9,DC4F9586E39AF767,668A1088EF0DC1E1,C2B7D73D892CD071,575E700304494494,65FB8D51EE01614E,BEE2E2154C16A290,408A3E4996A9BCD4,39FDB8240A9EEBE7,8E23FC91A4F0DF93,000008A2D0764270,716A815E45245770,73F2BCB614B2C4C2,6C11C87617083A58,6E3E355746B61C75,6790FA59F7655EDF,4E82355EE268DCDE,A9089CF9ED76B98D,196BD75F53D6641D,E40406261BB8728F,50DBA3DD881F3945,549428C2A81F773F,0000513E971FE715,1718BD171254B7C1,28621DF56FD09E25,8027417515435044,49E1FC8F67257EBA,EA096FEC642D9B1B,B56292AA523C5FFB,16610585F1263D77,7DE1ACCD2CC1CCF2,6742D0D3475550A4,A234B7CA80EEAFF4,9EC8EA1327B99CC6,0000232D1DE53281,C93637D2E9CF9235,3C8A841E88B9BA92,4151C93FC4F35467,98C92BCC76D08754,C6D9C0294EB47D4B,11B2B5C84C4AB38C,094E3FA317FEB9C4,37110EE3A8DAE1A9,623D1B5D682637BA,FAF965F34782A601,D4EE6D9F3030DBEE,0000394AC1A52282,334F76362086F167,1A5BEA3703513718,1419911723698675,9735A68C1540C3CA,E1A541AAA2379673,71856D05A6F6B972,7B7406DCC27CB844,A85A06297DEA7B9B,F1CDDA75505D5AF2,820DC4F7E6E9B180,3C17F73D864DE32B,0000309634BDCACC,ACE13898F4FC7ECD,18694C5AC523EF89,F9B865A76B274DF9,225D380E2883ABEB,DB547536F0ECB580,D806EEB13D9B3CD3,903B70B1635BF48D,7EA5E4F7A81681E9,E13AAF96595C4A0E,4F301635F323FB4A,84F0858E8BB3A638,000000545CD920E3,608A1C1AFB0057C0,454736FB5AF10B3F,41A240F9FDBE2BE4,71FA89EB0A098CFE,37C2878559074844,1A40DDDF451C2799,1D39CF05F69FC5E9,4633672C15F8CEFA,92B4A20CF2B0B322,2DB1D9B46AFA37B5,AA25DE997EBF3322,00005C292DCF70AE,BAEC55812F38D41C,FDD7468BF885BE17,B356ED774E7C4248,C23B5090C185C6D0,50169F90BEA29BE9,891F30143DDC8E19,1C544B6710E1D25E,69E77168620489A3,A68ADE5F5F3FB0E5,C6CEBE9EBCC0FE36,65452F45F353DA9D,00000D4FA6A2EC8F,1E2AA2B7CD506ABC,2E0063A5091842BB,E1BF55764AD35FE4,929DDFC3188EB7D0,D60D0290930B0B50,B641B23A4D146EC7,78AEB544DC0826FB,5B69F518A0A74763,8613C9A9C2E194C9,9A28C14B5A10E928,48B2C2C8ACDAEAFB,0000031593A66755,1092B4D8AF170B02,45F8016E31D57FA2,36B5EC302802DD56,37F9C7BD4E172F4D,5A7E63959FAF04BA,456D03540C899C4D,317A09482841C26F,CC0047DA68CF307A,0ED3A923F6A0AF89,D61DC576B8CFF4B7,FE099A08B5F58BEC,00003FC4287D0674,7EC0C9BE8B942905,2612D7DC98A8A310,7C283D98C0E99ADD,6B1E4BBED7B344DE,CEE33DC296490AE6,1BECF6A1B49BE42C,B61E22949C809F58,20C0C1CCD1402742,3F4BA426975DA66E,FEE7F313FE90A270,56BEA9D99AA688AF,00002B84C851158A,0A07F8C086647D3A,510A4FAEE74F55E3,97E3D1061216FCDE,807C19501471F18C,4200A2AE18554C09,87E9131049CDE349,3818000573B65D94,DEB20373DCF397DD,D28A82D994F31608,AD9D851C180FF321,6145A315DF4E103F,000029762CD23A60,7FA67726054BFEF2,0330B50CE19C908C,7B4C6D674283EA11,470967943480BF67,F71C88C628FE133E,4FCA51C09FC0DC95,DC67C7343B3C422F,F82F67EA3A24A565,B13E770BF8861200,3D2483F28665D4DD,FE58167552530EB6,00000A5D1D1B518C,D19F18F7E20B80A3,9D0F260C79043C17,41C3361351681610,4FE277DB3EC8584C,67F6C6B4DE95EF1B,DA968FB9F59AEAE8,C9E253538E687579,6BFF125A1FBF4A04,EBF35E332C9834E6,E50D1F0C4DD229CF,1FFFFF036807C62F,0000011F1F5810FC,38E400A0CBF0BE72,F568FF84285AC267,13F298CEC32E0E1B,EAB3BEB5CCEFA8D0,5E643BD612CCE6B6,FA3FD6BE1307874A,37BA6239445CB6C2,12365E663F202929,B2020BB7D1977B88,73B936101483CE7C,E7F3E41B96D98216,0000325C5EF0BA81,1F70A51921AB5FA6,66FD4149B7E9C1FB,5830E80BA84E6DF8,2206A8EDD1BFFDC8,2B31A6CF03B61ECA,22FF837C9A0AB90D,64F2D82E1AEED9E7,8B89F1CE2ABD43CD,141383428843DDD7,DD356FACFF4B4485,611232BBD958E061,00000EF9DFB8EF25,F282AD0F30E04680,852D5468278DA344,1D1725EDF560DC7B,04BF6CB7D970E49C,E7BC9B93654420F1,B74D3F09A4A3CD57,FBB7B36446A6B188,FC1E33BB7B87930F,D18ACA032DB7D075,8551A1DBF2D081EA,AA2FE1C16255F93E,0000130403389BCA,D243B6FE0B070D86,A4A4B68A4C585C60,E40364B56005D6BA,8CF30E1584B8D13A,A3D183B3CD461BF4,C60DA7B2477664B8,9B2EFCBF63D61E15,D0D0F0F2A1B34C53,77F851C53D9A1602,D378AF41AA7AE8FF,E70EA5F75D3515A5,0000499BE42D1F68,1B6BB5C873FA0251,CDDD511B5F6A709E,9199C7C86D380353,1B51F7EFEAA8624B,3A53A3D09B69ED9E,AA05B3D097015229,43F70DA7F9ED3DF8,0A6C66AD580CC012,16E2BD07EA86D99A,A66367A7213869F6,F9716A392E3DF8FF,000013997619DE82,D5C845B6971ECCED,A9BF55019F1DB288,65CBB3E30135C1BE,291282195A6E01FB,FD7B63148BCB6C86,7697152DB4CED2B3,ECB518BB34F9594A,61FC22681E935435,95D15822A7B8AF94,36DB05A7CED21CBE,2D46F6BAFB82234B,000007CF07EF43E0,A68C4221717012DA,0F29B60FC810A316,83D218678D681DC7,F23BD97E0677C384,56889524891B0222,ADCB552D42FCF8AD,9700A4D39507CB6D,63B575FEF33FCA55,E7857B36631B2C75,E6B85EF15BCB1671,0362167E9565E127,00006F84A2FFE28A,A160849E02E814B3,E73121A347AA414A,C89EE523B9E99C91,0DBF77CD0F92181F,5824AC529D0CFF81,9D391BAEE5DD21A2,7A97650A4F01D74C,4D19918161AEBE31,ABBD3993587FA6C5,5DA24A021B0A174B,7CBB81F8096AF0A6,0000629ECAC05128,58F94DCC7B95E6DF,5CDA907B757FD6E9,9456E39798B9C5B9,F084BF1971EDFBF1,41774379436B24B7,868391791D37B54C,BD3A207F173912E3,FC9F318B52C15CDD,F772C9A97CFED43B,37F12D7FD0E2B466,614FC751F186A22A,0000619BB175D13F,C3BCBE23C6116163,E8AF774AD3E45464,5555A0616165A509,B380D4993315FBBB,297367962E01645F,FE6531BC9E98D0AD,8180C7EFF89C30CF,ED6E04411A06783B,306711E98C1EBB96,EAC7A207835D5C59,28BC4DB5BE7E29D8,000057F09EDBAB55,29089D981623EE69,48412AB132BF410F,8D9EC7D5D4DFE622,D4060F43225E2D7D,127067B45D675EA6,C76A7670A9E751A1,150855DCF5B6CA50,3261846AB99E0C42,E3D170AC0C7AC829,6937DFEDC83D1C40,18CB38FAA11A1FC7,000000C701D3602B,A8AF8AFDCF6CDBCE,399561509315C92D,1E283AF936799876,8DBC2B7AB04CB094,6AC932D32EABE0F5,55A27725787B3861,25161B867D4BC6DC,44EDACD1A8AC6CFB,C30CD93E8FB3CCDD,3679D34166AE85F8,E62B1A5EE057D60A,000026FB6F8D2359,3FA2CB5D77A0E72C,445815594385B12D,05DAD93387C0864E,C5D41640616E89D8,E911824FDB8322BA,9DDB662CC1D3360B,D84C8CFBFCEC959A,F8580B19AC59F1AF,14C42C665CBEE133,949B8F9C4EA22429,71F2FFC9DBB772D2,00005764D4AFB1B6,33A9DB039313C015,0A76380F179BB2AB,226C39526E0CF185,987BDF8F0DB8EBF0,78D1C286117C5A34,7544682EF593D663,835DF4866BFE56BF,813E409D450E3E23,F0FF0EBB590370A7,FEBAF3E94123B74B,6CB3FFEA4FC991B3,00002C4AD2324AC8,5175F41502ED2A46,ED277EA61E3621CF,CCEF635A7D359CC8,F2F5EF49D750FC55,A5423CBF71AD0798,82E26D38656CB096,2B6881279C7C4A23,F0E98903A5BEE3DA,26E9FCBA942C5E20,CEE1CC9C9BEF1E93,1FBF5ACADB07B82B,00000122E64AB6BA,8A00557B0B50B7C2,D159D2460C7C25F3,081C2A7D109DF984,445CA1769D27351A,754205CE55AAE4AD,2012C451ADC5C156,9BE27D723B9893AD,5CA0B6C2643FF3EE,5B2B6C43747D0597,DD5D1B0A8F87744C,35630159893B121D,00000AB07B5A05D2,C0021276017FFFC1,9B79581BC8059E8E,218497F02DD6A168,2E99628FBFC284D8,214D7BD10A13ABBE,CFABF90A40B8F2C7,98EA97DEA3295D11,78FFCF816EF501D1,E78D786658546463,E16B9496E31FEAC8,12A9365BB9797D01,000045CBAD7FEDD8,EFEF914F68CE1DFE,5A762AEADE79C0AD,36A548FD6B3B1836,05CFFD018AE014F2,B850A5771D91ECD1,E1A6EA2CF6DF2D06,76F4620619D66116,796BF514436CC770,4F6C2ECF34511441,837A45D3D3CE40D3,ED78C0CEFA272DA4,000019972B4E4E00,536ABFAE9C242D0B,7946C95C42EDC3FE,7C8BBF6D9DDB6CD2,B96E750BF78625DC,76B291C71D7883E8,F7B549D52C065627,6313D3A72E4112BB,F5C60449F8D5C81C,B38C4DE58C57B6D7,9770FA282635CB6C,F02F415E23CFBC38,000035AAD07CEF28,BB2D632A098314B2,1C6C01F846D61702,619DED8B4CC1943E,60B90ADFBB513AB9,FAA134DA03624144,F6803623AB339F44,C76788D74CE0B317,31D99BDBC1E401FE,24423AC78233A431,E2A43AF5DB223550,C29084B4574A1283,00004C27AF8792DC,CABE72B23AD60B8A,B4044B32B2DA3092,94D58DAE363C3FB3,3594D7121FEFB40A,138E838E95248074,323C02E615F62BD4,4455CA840E038185,2A73A7725C5BF461,D0AF40AAE37A9E15,DF9974DF49C0FEE7,4BC01B1EB217C5B8,0000303CCB0279F9,084DEFCE7B846582,3ABDF4A8C7308F78,08CA1D34BA7403EB,4F0D864B6339574F,023C785E16432935,F191060476177C78,5C74354F65F97D57,CF5A02BEAA24B2C7,086948A68C45C069,9D4069B95304FB32,A22A0B62E45513DF,000035E5318FBEA9,BD88240B8213A918,05F5B626DEADE463,34B4B2A50C5FB790,3E3103A9AFC069FF,1EC25D59E53A8BD4,55FB7D1323A862B8,FE796D83F1348DB0,A669526DAF3B2AA8,A822079826C0696D,FBA17877FE33CE35,43FD70B4CEAF42F1,00002C3043C03A6E,B2814C92F543792C,4B9798D79A0FF218,61D7A263264AB84B,3E5D20758E67F166,5945E17B55D447C6,BEE14CF9D3D34C51,F70693E679AD0209,489A38125C51B233,5FBAEE2B56809EF5,5079B872DF154426,2BA61220130CB28C,0000172E41614960,B38D9C5CD23D6ECC,1BBC4C7D84406806,62500B829028E1D8,9DACD0E9FF4D3F8A,CCA71183F6E31E43,E27EF7BD3095285B,73AB122DC86797B9,05E642EEEEA501B1,97BEA6F8945202B1,C0BE0701107543B0,5DA3FA667C70F129,000006DA4107D050,7F87D8E00181849F,87B7AB02F5D4A154,5289B82DF9E418A7,EE89214A30AA5C0C,C17DEF1234E768DA,4790CDFD006CF38F,6A67E5910DAE943E,641FB492B351D6BF,43896EB222382FB4,388BC0403D9995CA,F93F4C8E4D95BC25,00006CDD2126DE6C,C9E5E1FE2126B864,10934604A681B551,927ABA1C2CF0CD53,EEC5E497AF40D5F4,6BDF15ED0B7A02A6,9641E635AC4B4A34,257911D0748879BA,9A02A250155AA5A0,5D5549528A932DD4,62AB16E4C4C3C33B,B5B21E3B1F408125,000009149E93DC4E,495309E7CF753BC0,5AF220832B8737BE,5501EAF481A679A7,493420A427712D83,6345FFE2D6FD8A66,02732B8851CED580,0C94E0D05C5393CE,4D9443925AA4E2F4,0C36442201CB29F3,C794E51D058699F1,AE3A4210A95FED7A,00002EE4223C4800,E19CEE0C46EAA76E,535774E02FFC7AF2,DF85A826E93CFA6C,481FAB447C751C64,5AEFB1D0467120AA,A81EEA25B6DE116F,D1BC6E2A022AC2F9,8B42ED5C78F18ECD,73BF3CE619390C44,EDBF1E09DA23FD00,49868FCB741E8FB3,000026A23CE591FA,7E5B7D10AC0710AC,A47FCF347D99078F,434724D991694986,D8F2F51B2C2BD4A1,F763B3E2D72A3EDD,C747831D177DB7BD,16A042CAF3CB8BCE,1948B5522F3E6AA6,D4876DC2CD9BE043,BE3BD8AB31F3B253,DE486BFB1DBD403C,00004B221214EA0E,7C4C8AF466F59788,9B8A338F71A0E13F,FDA78204DE985885,65621F77DFCB92B9,4A846961BF1BE8A8,52045169CCAC9FFA,874149B7F006A456,1B396A581CC5DD5A,BC980DCA9F8F95CE,7286AAF568244496,86E0F318BFA01C26,000017FC7741A235,543DC4FD04A22444,3EB0435921E8CC2F,48E9BA2AEBF5BEE5,84655C321CF2E215,C87C39E5F5B8578D,57638A9306CEA1AE,7A0578963EB60FF7,826F53FE44C46FB4,7D78E1BE88D19D7A,4D22DC6D22C1AC28,78A11E9DE35925A1,00003E566BCBD9CC,9E56E0B0C003DA67,7E572A99445D130B,9B8B39B6EF231768,79EE4BD212BE8ACF,73684D75561F8D2D,166838E09D91F01D,BC3D895D5C04D556,880917EF6274EEE3,DED47F011A62E8C1,5FE8F24CC61D87FF,8F25492A41F219D2,000019EC483F0B11,10E3B15C373F7799,56756E21930CBCC9,7E83B2A98DFFEE2C,EA0336C8F16CE3D2,D3E5DBE68BD602D6,D3A9F845C66A3C32,05B54DE8501259D4,238EDDBF19D8730B,104374873120BE34,513E0D142E3B155C,961287F93FF32756,0000427AAC761411,853B2D802925E10C,0591961C63E998B8,B46DCBA3B3051D82,87A6E4175EFA5472,0A876EE8F3102198,4EF3433365159454,A6FDFA09FC077D6E,6B68B47182CAE86A,D7C3CA1CF395102D,F1031510F817BC09,3D25160B69C9644B,00000FB76582EF61,4EAD37DBECF9555D,41069D68E06998AE,CBEF521EF9B5EA3F,5731F0D042C34C89,2BF308588C7ADEA3,1517A5C6264CAF12,C0C068A694E64B0B,06BD3F411512E7F5,AD5659D4045EA2E6,42BF13CA6CA4929E,A9E38D9CFB26DBCF,00001943A57CFE70,DEF0D0DDCB028400,7019B7FA0DBC938A,211F16174AE84BC4,3190F7B9D1AA10BD,CBE32B146B9E0B18,9123D72DAEA46E56,DCC1EE656905F1FB,6F994A1268336C6E,611AB3EA6543BF0A,CD206411F4B59620,30CACDF539D50EDF,00000B9547705525,A1A7FAE15D682B4C,E08CF90664C9DDD9,918D1B85912E361E,B42538D5CD21E4E8,31105EFAA0701EEB,C966137F50CBD4B2,97797D22B8886E08,CF30FDFD08C4DC4B,5778935DCFC6B378,563B3B1031DB0E99,B8DD33F4CF80071F,00000D934FA068A8,A4CD0048D7D812A6,CF076D3732D2E4B3,2EEABB63116C6475,CB1006A9ACE5F339,F1E492B8FA26EBF1,8DA2C2A9AB003540,0A0D6780EBAB15F3,14AA315D5145ECBA,0B9FED5487A67663,644C39430A41F5FD,D4F01989FAAD7D1C,0000417DE65BD72F,24D2ED1FA02B8897,B318B64CA36A3C87,41BF967CA8A8714C,7FEE5F7DC22B266B,363A8902AF9BBA7C,BE66D622609E12DF,75FCB024F43F06A1,DE612077C86F8F86,0F8406DABB7BBFD7,A11C657790C5FE7B,AD9CA5AE7D852B35,0000615F00FA35D7,5FE346656DB4D5D7,E17F938B939B787C,4FCBB6BA9A370A3A,C1E4A47F44BF1E6A,EF8B56915B55D906,A536674E44883E0C,C1D5CD73BEFD146A,E43DDFCC744A3E29,65B1296E4AE2B7B9,8588582801EE51DE,352D438D0BAE4B42,00001324CB496885,94BC3877DDF328A8,F5688AA0480F6AEC,2632A62FF1998E21,F20E18EA54FED0AC,223A02BE9C655A8C,D48CDB0742C864A4,C6AD4C81877A889F,6E818F6919F66BBF,131F9D0AA87D801B,363AD581341F49F9,F1F12F4F907D6D8F,00004D60FCC7257A,9C26A67EA722F099,2263A0B414EEDF0D,E1E08BDC05E5F5DB,79DCADB0D5B93839,CFA4041A2BC19FF2,656DD0EC6246755D,266BE20E15AD9A58,623D28758F8935F9,84D83AD00675FD90,5D0C3ECA11B14E00,ED0AE112AEC9DE65,00006570756D658C,5E7B9E7BDBD07598,F83E31EA6BB97A9A,52B1EF1B29C84D5A,723100F0AF822533,FB2F1F84C32C076C,DF6C290181567316,38031F748529FE68,DEF2DCBC5871DB29,457BBA58D4E8B5DC,479388A619FD98F4,FB331B13F54C2F17,0000593AC5A392F3,08FFB06E6F72AC1D,860D3242EBE7028F,4803AA7C78E7EC9D,6560182EFD5D3A3F,E1824E414E190B48,C1A304D0E6031B77,514EFF50B06930A6,5A763D1D17C86243,7A703F1DFB3152B8,9DF2A55DA15CDE99,81020459989FA81A,00004F9ADB430D27,50DD9F5BE0D73B06,07BEB2EEA1B57E9F,CFF7FDD15CFCE374,F7A8B3513A64188A,DD9C25C5363CC1AD,639A54264EF27B9C,C36C9201685D0ECE,DD4D9F0814BE89B9,651E2DD3AC6CA510,96F541FFF3711F7D,B52D69986FE190C6,00000AD4536D675A,DCE32F684CC54814,D8FE05C3C17B2A1C,60EED972D9C65D21,E9F493C1F853C561,CC4345231C903B9D,D28A0555F764F032,15F76D0752F89FFF,A2CDAF1290D00EB5,370EE5181F7F568C,5BA99D1D33DF8AE2,9312F557003F851C,00006B9DC9CD4A47,B25B3F04EA2F7478,8E49ED1D1C602339,451647E11505E6B4,4BC8743FDD45E87B,A7D9F98202D50751,6834622EB4486E13,EC91C61A24BDF8CB,6FB3C7D5946EBE14,E8BDD9E63EF998C9,3F33379AD515FFCE,685F5B213DFF584F,0000377C24E6E232,FA082E618378739B,F3F8D7ACE708838A,479534B8FAEA11A8,9090F1713B91D0AE,0249CD2EDB47C051,2D48D8A809FCDD04,F0FA9E05BFE1368A,D36692BFE85A748C,76737E4345B17655,36852CDDA81E6233,4DF46E5A86031CE7,000045EE2BC6C0A0,0F0DC2BB514AAF55,8FEA4543514D4EFE,7F91860B51D8323A,DC8F84218BC6538C,2E17E57FF5583D97,7674337E5ED07334,BB94FC6EB833F7CF,22368A4CEA518B67,E8BCF1A998220DCA,8F8A0E944D16E6B3,F0D3AB087E63164A,00005B308FB6710F,DDCB525A662994FE,0033D8BE26F8D58D,E5737729FE8D5651,B1F1100BAA51B15C,3E085763095A9979,D82A893BEB6AE30B,92033D3E88B15F55,589AE105A4BBB515,485E35B997BFC6F7,EC28DFC645EF9C35,EA9E9895545CBCE5,000010C20620DBD5,4670C1E392B669DB,6CCA88DD5943839B,A902A341552E457B,D0E13A87BB8E96BD,79AA37D373ED317A,5135D6655FA2812E,E2085EB76A60542B,711966944B5776B0,FF9F9168C91842D4,9C011C8922DD3388,482B42AB2BDADF9A,00000C6692F61A62,71CB7D795A17E3E8,2F63823391D34123,F593D2EFB2097B30,4048A4C31124DAC3,8EDDBD58E1767B40,7CC6EA4F61675E4B,A503B3C64F58D0C4,93926CA92E3F8A30,F6550F77BABC147D,699B19E4C444721D,BF43F37A015A3B19,0000329407F15954,430B6E4D2C9785EF,D769602EBE46FD99,1B3313E5968918CA,FBCEA00EBC3F3851,3300A669D3C758CB,6D75858D5304A5F2,C363B4D5C6AC547D,C08FDCF38440594D,A27FB8D632A8928A,8EDDCDB0978D515E,B9151CC21DBE7200,0000418D91DFE0F4,7F432008EF27E2E8,0D62FF7B761E10E3,6B4619154DF440CC,99E975AF82BF19C6,F980278DCC669F0A,7B635A38A3DCC455,EA69B5B25AF785DF,1214F555CF96CD80,74396F6624341E80,5C89223DA4F9C641,6A6186FF11787995,00005A18604C394D,229036918A63D781,C10AA8E90BC38B37,BF48468505A2C244,590331E5641E8277,48910F2963EF4D97,6CE843659D456625,137F641FF88F2AEB,3487B5F6B6A1E9F7,11B5C1D6BC9554AE,D17CD2AACFD826A5,6D00D6D1C6EB12A9,000023FBFA567D2F,4C0D4653402DA1D2,D4D884F843A63715,A580B1E0270EC47D,28D0E02C50E69264,51CC186012107925,78A2C8F67F28F260,00074A662A50DA30,AC3BF8E9894E0409,C80B837A19CB4C5D,577D2AECDE8FC683,E5681F01CB739B3E,0000067C60525399,255263FFA5D0B91E,A0E83B50D9A45B21,965F7BAA1449B97F,195670C7AB811BF0,6FBC34C3669F99DF,894AA3D0C683A94B,14C44B9A009BA969,FE94AAD98AFABA6E,22D3722035CB3DA9,F038C24FE9F4413A,F236ABF14A962E88,000000B33279D7FA,243740419B9F7B20,84C10264A9525CA1,346B10AA1A90152B,4C6E7A748D02EF2E,CCECCFF36BD1EBA2,6F3C98C5A8071E9B,F481DABC22F486C3,070024732179F5A7,5BFFFA1D67A78A9B,F62CC8881F421088,77F9013D47011A4A,0000065D571B9524,89AA22DD3C7E16E5,888C6F2186E9530A,27E875F48D83752F,BF814E832C2D8658,A5084A439F741E89,5F7A015AE7858A36,5E50DECFA4897A3B,D6AD43626D3D185F,90056405B0C511F7,139F9E3F69D56781,738C7FD835CF06BE,000044C46B4456F2,004A05451C92AA7B,3EAF88CFB14AAC09,D2FC1114543698E3,AA6610B4A85758DC,B3407FA364E119A4,5A4871300DA27BBE,EAC49676F0F7CA7B,67AD211D348BCFB4,297F278FA8AF1152,B4C658DDC574EE7E,C4AA0A08514F04ED,000001841B259ECF,5599362C22B721D0,C765ED0BAE83F151,277F0D8110D9D9EF,EB8726B5D94751D7,7C644CF7D4C89535,898CBB2BB185A299,067ADC85303F8F24,D44C2C9802BB7135,A0095DDEF749FCC6,51A7E1F60B80F635,FF0A8DF788B236D1,00004694B40CF036,F1D855F008BFEB0F,8659DAD97FF9E238,DEBE6176A0C78C2D,9CB6C6892996294B,633F6CB6940A0B7B,FBCFD92403299FB4,3830A4689AFE2ED1,B8D4DC29E62CA30E,84EBBE6FEAE987B3,6925653D4D7C603D,23498F872A733736,00003398A73532B4,193E555FE8BA564C,6C1BEE6C512E0473,2156FBE10070C2A8,6887389764F90642,34D4ABB9C4971E5C,CF929C0B00457614,CE3A1CFDC0D2E5E0,BF2F32C9DB49993C,D3837D24D6282451,F405EA712B1E832C,AAE6EA1C619FA5EF,000029D89EB0F7DB,E94372EB2F7B59C2,41D3FB6CCDC1F1C5,CF9AE938AEB4BC15,EA115E61AE35426E,6BE0F104338D3A31,105F7A6FC2053D74,E6D25D1F2A8B4877,9413DAF3A3BFDBCF,EA41217030497C2B,E4C26DC0A8E4733D,A07966955392E1D2,000014B36F910633,8538DA1D6673344C,C7D5D2493247C480,50B3E7D3E349F017,3480664A55860FFD,C84F47969A05C938,F5CE56BD8B77B5EF,A6BB4B5EA16640A9,7F885B701FA478A4,9CDED673A3DB14C2,6192B0A7080F772E,39BB14556A4CBB34,00004D0B454729CD,28F637BD784D7654,BD1471761FA688EB,0C525C3A7F7BB0ED,42A2FB44101608BA,2092F32EA2EB03ED,6A9236A5F1F6C6C6,18FF53B6E48646C6,0F67D178E0D46B83,20D1CB91E383DF43,0F0694D6BD539F8D,0E82A3674211D2ED,000001D53E3ED46A,A48252C53D40178D,0EBAB5E0E3509462,D1E92D9493D41214,3D2D740D9F0C8283,56E2B38475079E67,CED868C98CF4DA55,EBAE02B9F0C06BBC,59BB828F8BC1361A,0455735B8984E876,92A547E38F07C35E,7B8FEC0F334DBB83,0000268F30CEF211,4B24AF4BD8F11A09,C570C350A1F73CE3,A95937B39E1F3A91,7EA10D605A48DB10,D39B9E5721750E70,56381A6BB2A505B9,348894F5164AFD16,41574E2EB9787B5C,755CDEB182A6761B,93C84807192579D7,BEA3E91B1A39F5FC,000058B91E783FE7,DFC2BA79CC66E65B,EADB6E0A8F163BFF,73FEB3EE239433D4,51B84BECDB43773E,DAB678E2C1EEC61C,2D04476BF0B72098,7E40F227F47F3DE3,1DCE95C29E3BD721,D74AEC24A75B89DC,819A39CA67A0A0DD,8F83B1ECFA19418A,000045BF34695376,DC43DD21D3000950,002A35DE0FDD339B,2677A66EA313975C,020F80DDD62CB08B,BD2C248539820DA9,158BC0B4EFBD5965,E81BFBE9CFB8218A,1B1C108F627A76FF,8892643B79E28386,4A416F181436EAB2,2F4CF85B88A816C0,000069FF8F465447,ABB4094152C83DDB,D7477054DD47CD7F,F41DADAE75312DAC,995EB87121F48897,B547ADE45BA816AC,8D64B626D00C556B,08D214DC0B2E248D,436A5A801C827FA8,1E033134F3A84B5F,EB353D11FAA78D0B,CE0494556A777699,0000358056EF8487,2D410E3F2F5E95B6,F1067F1FB7C34438,A9F60F271339D098,4FD1B716FA9859C9,F10C74BBB7A1AB36,CECB65A1AEC53324,176B9C2E268D4AD7,F5D03B334A52C372,FCDB01789C378A69,89EA1B1B330CC31F,39644A4C4D47D55E,000023C0D03F582F,805571A9D78D1779,7206B243BF7AEBAB,A9B33C3472915C50,AECCF989609B99CC,724925487D8CF33B,548FD7E44CC7E0A0,2E2A292478DBFE86,215F0F81CCB3C45F,4C893162D5987F17,4A3EF9F06753CD79,D1AA688780D9A306,00002EDB88B2F282,E38EAEB50770BBCD,BE4FB43FDFA00A9C,ECC2A7AC51E80B7C,A94FD8635E84388C,8AEAB14755FF2178,77BC99E1CD482103,DC96D9AA0032BA3F,24B253A847BAF7BF,C3BF02830990CF48,8D6B14AC2C1EB91F,78BCA2A01CB093BE,00003E60B5A2A04D,A56B552E1DECEC1E,B6E86E38E4010945,303C17D4C61BA33C,29933C4092114A97,5814B6DCEBD00AB9,E3115AB39DA7F29E,5A994A644A97EA6B,810A5F57DEA818FD,D0511B74AD265C50,D4EF5BEB2F8808EB,FB332BB13A2AEF5A,00002516C3592C80,2651E583381524B4,A8446D9838E32718,D791759BC53D2A76,B957E722F8F866C4,D2A7EB534DCFD771,504FE46A4C1A2938,1BEB5F162A980550,A677DFD8BF051A5C,1700F95B09034E55,AE5FD7E967E55C00,A6CAF088F1EE3671,00004482B090DD4D,4BAEF8B6E40971E1,9C824B5F2E456CD9,F197892FDE1D7879,21726F3512377FF4,4DB1A77FBB63ADB2,6E8D3F8A06867991,29AEDD78B7A52F03,1A380EE384A03777,C6C99FE32C19F395,55E42D1F07949BDC,E872B80117833595,00002AD50619C773,D33DD724D505F3B0,9FF4291297446679,F0D83CFB5333BB4E,28DC2F56AE33E3C8,8255CA770885477B,04D8518853180F30,EB31B5D529E83D70,8779C9788DB83213,C5499187FAC978B9,3AE8F7CD67121437,506C2446D37793F4,000035D15260FED9,3897C42428D4E025,94A30AE91587885A,0C07D3B03AB7D2C6,850C7B8326943861,40D1E4B97FF8C17B,5B7069176C5EEFD0,3B4E14F41D4B1597,0BDFE3608EFE017E,0EB11AECD00821C3,BF99B1ADD96F8ADF,67C84C1B33FA4900,000065871959A96B,6EED057A13BA2589,8820A0A3AC21E6F7,17498B679D42C768,0647B6B4B6B76C06,977EB9E49B27B0D6,C06FB0959BD8E273,58D0EA84C6FCAAD0,269AEB5145D30FB0,38B5587790AA05C5,7236BF473431B12C,94D003777C88BE95,0000328D6E816B0D,632B45FD673538B8,3F365E9C08DF72A7,71DD4E57312028C7,A87C76910E69F0FB,C5C843BA53955FC2,7E6F41241C748902,B70804F33CCB189A,2C5E1B1C77ACD93E,E1627F384C16FE55,11D576993592A1F4,17D32F63E1424F10,00006D4EA76FBB0B,8EAD9F981450CEBB,51F2D425F691A46F,215B641B0C0793A6,CDF0C9C431AB78D4,1DC803EFB0BB9099,F965AB15FEEC1D55,62FB4A365FEB7FFD,955EF910E238678D,1623173704E61D58,5AF11AA478D6A4AD,EF9DAF24586F1EF1,00006BD0CE39DAD1,7ABB977244FFBFE5,A3279FC043027601,3A16E4FF4EBE6BED,B011FF4429A14F42,1267A6F12360145D,B30A7786FDD38AB2,C0DF035BCB7DFAFD,2EBC02FE4C61D9F7,053323E0D76A5228,894CB7EAFB8A288D,F0FA578D4CE77506,00003E3D9FDF6113,B15923D1B595C83E,9DFFA03C1EC6B0F7,F4C5AE58E979A5CF,E2382A0BFA00FD1B,E077C23C215B3F67,4AEFB30B4DBDCB05,A6B56A9073A45005,438470CBC431ADFA,A4000645D67485AF,B0C358B17AB64DE3,C34451546EEB3E2A,000064023787A179,E07628B2B143BC9F,2604686186D8644B,58E1F52697707C65,925A430E7A9CE177,B0B09B1A75F2F00D,973C87A99E29FEC9,445B5C4EE84BE744,55BAB88F11F6AA80,D6E4D768CEA544BD,842DE3C06C7883B9,2D5F8B6868CDA6B6,00001C1D5BA2177C,C72564782AFDFAA9,11B949E4E323CE2F,424CDA6989B4CFDD,F63E4967CF7A1CD5,C39148D217E7B1E5,A4821C6253EF032F,CB7170483B0F2F18,339E124787AA3A11,63402EA49788C7F5,EB70E0731F581516,063EE79A2FCA402A,000034277633FAC6,C74C334AF46E38BD,ED7971B9E9EECC07,7D3CD784C62666D0,5EA222F0C33CF88E,BDAE1A3DD2CCD8F9,3DD46C8A5B6A2783,8E868BFD3953AC8E,59EE455B056529F9,BB6135AEB18D8AAE,706AFF64EABA592B,7BC51DF103A03E3D,000018AC9181057A,D8074B0475405D8F,B0E36EF8CFBCF78D,73A3636231E05526,039AAAA15E04D46B,A00EF3404BF2E6FE,034697D38049E0AE,EFFB23E918BF18E5,C422FF0ACD04A2EA,3F2FA105D517E147,89594323C2EBA5D1,B5C96B582E3F4B0A,00005945808D71FD,189A8D08CFD54819,349C2D6E0C8A8418,2E40380B61BFFA6D,B59E292499C60461,25ED57C8E9A81A6E,0D7CED7A1F093023,79EF096C9BD2060D,498A2159C9BEA19E,8FACB89C2500A3BB,8F34BF57FAB7EA1E,C049749A2D7B641D,00004AF6BDDBCA12,DE35BCBDBE5337AC,B965FED582767C76,D87A8517BA2569F5,404F7DAEF02E5543,F4C24769C0C0E68D,EDFA2ADB304BEE11,0D1825AE0E4A0C33,A8857CBA3159BD6A,61A0057A28BDDBE7,F04A7C5200876A0C,9C559EFB628016C4,00002C18E72BD976,FE83096F69ABE87E,ADC956F9654AA1BD,FAA07902DA1E9020,7D73BC6DF66537E6,6144AC9570487129,FB6629E7D3EA9733,57CFB8E8A75F4DFE,A808EBB5EBCE8429,F0391AB222AA4A2F,D718C7D2E1EEAAFE,1C597FA9CDE3518E,00002C850369EA00,465AA3B0FC83F11E,094B914E4DA292B8,0104D8D5F13CCE11,D44C634AA27DE875,B00994D3B72741B2,CC22303976065906,A0B1CB1EBEAB74D7,79AAA6FDC6DD9910,760F59C30CA77C24,D1ED1DE4B435AB26,A51BD5D0881FB678,00004D0324BA4BF7,8AD6BE6B12FC45F2,F8574F5ED97654F9,1CEE64FCB8CA1CC4,8EAE5F232F0B9595,1141F536230CFE79,8EE6E7307A4D74F8,54474735ABA9E1EC,B3AB9FF706386588,2EEAB65415ACBEC5,BA726C2D07787A5B,799935F370F2C4A4,0000121D78672C6E,1824543FE0EFA328,77620DAE87BD3172,E95A4D36ECCC4A1E,D7F429E2F9A9F510,F7AB47E9D2EF8503,8FEE87DFC87D22B8,185228F0C3899358,74FD0D92BF15095A,9E778DB7EEF260FB,BDF9C2FD37B48335,BD4A9A7DE46A6269,00002D306917BFA0,ED83E0AF300A5B7F,5FA3D9EE26AFE86E,694F28535A7EA543,765EFAEC647DB37C,8C78120FFFB5FD3A,FCD19ECC39D32745,82D49839777F3D2A,12FCC096402E6CE5,FDDD747643FA9645,264F751AF19CFA3C,4393F41EBC6D2BCD,0000649B9752CB53,825794D60EADDC87,57D928FFCAD20A89,FC69A3BB227453E8,658C3108DF578E57,EC6A6DF95D68464E,03E76976C9C602FF,26FB8B73544FC3AB,F8B3167B6645FA65,E6EFDA3FD9BA02F5,FCAB83790D39374C,311596B1F7D5B065,000024CF43879803,95EE9EEECC9182C1,0D30885D1653DB0B,68A8EA7385FB3F63,BF05AF802176929E,E0AF59B2E4FB0811,D46C1B8AA9DAC906,797608D2C17CC6B0,CAC29CD05B498468,0D8172A7DC4B5244,B959AD8C98C478EE,BC0C8581BD20A218,000062EC67C69677,92CA8E9382C791EF,E1A76612BB4C55DC,9E9285CF1CAC1719,A5B5D2DA351BB409,E0EF490CFBD59E5B,8E9416C70C0C868E,6E92C606B84F4960,94A00ABD9197C4FE,2333EADDADC9EBBE,F775C3459121E4CD,0E602FB88AA5A8E3,000034B3F6D52B32,26299E0541252438,5BD84B266C5C63A3,7B740BDF9A3F2290,EF8BAF7ECF0C6808,99E7C2274BC81DF7,30C07004ED189906,A666057C4B543978,E3B65EAACEB8C350,71BAC3550F02E3E9,8C0412E00AC3B785,C62FA64676234F07,0000665613E1C6CA,8F21579F79D9E312,B0560BB7EB004A57,99A77643DC172A8A,B371406F598A7F3F,62042D38DFA9F1DD,02B1732E2AE44ED4,05399E1CDC7DFFDE,8CE884878A743A2D,F553CFF972DF8692,CF27F6E2F649658C,14724AB1C60322EE,0000334CF191E6FA,D2898454B904ABD1,E129FEC9998D3A8C,014F472EF48DE1EA,74D683B4CC89A196,F15CCFA55A6156BB,D0092FA171918966,253BB23629EBC5D4,8F157FAFCDE75D0B,5062312081AB0858,F0C0D6B25E4105B6,D34CCB1790800014,00005913E2917A59,36F69DB994288722,4AA87CAEF510E70B,5E9CA92EB5E8CAFE,39D0B2547590CB47,D52DFE3F250170A1,B2855E26385105E8,D2A93B80C3E5F16B,3B909D4DAE51C6A4,13072303657C43A2,2E5E811B9F96A64F,D3BC4F9105D08E5A,0000222199F49F81,172866293DFAED81,38FB02BF9FF55576,FBB077480BD110F6,36AB74420D60056C,E7B0F2BECCFA7823,19C74DF6DEE372A3,DC5D7E4AEB366940,F774FDEF1B9342BA,619C3C662C2F546F,2EB3087771D22B82,E9D78B9824228B2B,000035A8B9762766,37993F99C3F03AE3,E377ED828EA1E447,55DABFD5C7BC79D1,50D33DD83F1B0D66,9E5D6CC8E1EC9BEA,BFD06B10C30C6B1E,D7967A1006E9E0EA,F4EDB40EADEE93B5,7666ADBFA5CB924D,4D6FF54A0DE67C0A,61589D7666454F3C,00005B83BC893E5F,62563A922C09DC4B,7765E66DE8656FC6,6ABA9318F0430A4B,E382837B80EA4863,31C90D158BAC991A,B4ACC87DDBDECBBD,0454B2E97038905B,7C9707B1122A5294,C74B65469058850F,00323A16FCC7C283,C94E52444A7708F8,00003751C65F2E2C,5538A26462513BB7,56E1B94BD33D3315,25F84942331C041A,F55C9C62BE2802B9,D226E4D2E084D367,7A17D3F840201A61,257FFBCC45009D84,299662C8C1840235,89530D8C44D44694,80D0BC2105EC398E,6B77D99655CAD705,000006D0410A20E6,0BF0D528D82DC90B,E9AC2A4DAA045C80,6A2678BE7B28AE41,90B5E6C5DDCE0318,4EF21FA3231AD9D4,96C46057F61B6DF8,9975393ECB0D19DA,C10FEB6B22DA7EE4,866CFAF509B8ECB0,85A283C6AFA70A6C,F8BC582723B958AF,000045F5B45EAFEE,69E3ABCE403828F2,4287B619B91661BD,FD39ED47E32CB5D0,E53B6C47D773F6F1,B2FCCF14D5935EC3,2B4CE00A910F0794,5D89C50872C7B766,61E6675DCAF2A978,D8A32B13FF1DDE89,A17EF235CF72BF8C,B82081839FDC4426,00002BA7F5910611,FF96B97F255219A0,7C8E70AD6A49EC0E,D3A53B61B375DA95,9EEE8F8247011606,9E0BF7EB19E80FD5,7656E51C675E6BE0,A54362F2C191D3E0,CE89823C82396367,39BBEF2599DAE188,FE77E5F075F796BB,A5FA2C5F79E6A84E,000048051A20DB62,2C15A89FC5F8D436,46E60912A6EF80F6,6635AA99890379A0,3758E458E450B8DF,B3F01760105B091F,77623ECC08B6673B,4D2CA9F7019B392F,4EBDECD91A81E006,69AB1A68D3A8450C,F97C2EEC61596112,D30FA8A86B89A5F8,00002F15C75101B2,7AD50230B181D886,FAB5BBF915847676,4014ABF115146BA9,F8D99DA5DE2DC1D7,DA2FCF22EFB8455D,D3EA1FB2284432A9,50FD225B46748888,D0ACC67982AD460B,1AD1F959F6800A2B,A1490081B7798A3B,B1E7A49900F37FBA,0000164733F0C299,F25A004B4F8C58D0,84DBB94F28EB143E,A808676FED208DB0,4D43947DB9EA512B,008BE7F79B5C76BE,FBB2990256D5FD83,F9EC37DE6448DE70,712E322365AD3635,98074A8B31443EBE,AA79AC17A403AAF1,0E4971EBDA1B7FC2,000016240D0D8112,F8F62FE146E46DF9,A17255A3D50821E0,66A9DE103E5F284B,A0A66CA97AFA27B3,98B4EEFE9B593275,F5DF6D7273EFF565,525FDF027658BF14,C9C29E5CAE756B67,DCE4976768B97A90,4245BF9CFDA67981,1E760D631E20B572,00005FDAA83D862B,EB00EC7C52FB6AB8,2D4997B6BB5961C8,41D51409390C598E,BB6498999045C8F2,211175FFDB1ED179,810993C35C573405,63D828F49F24E228,A2A4A469D3224ABB,8C12E437ADF8E633,944B72843D3B3A81,9C3C1AF122B51A5A,00002A8F9DEFA8B2,8EFA9D8ADA1FF757,0D44742151FBFD26,FF2CD4445491C5BB,A7C6BE731C53AED3,4C9FF8942E9243A0,CF0AECC4B5627ED7,24FC1DA5FD8F7993,4DD81029CECF3845,3BE57978684947DF,E9E604E8CFE41B96,A454254FFFB7B829,000067EB45262FCA,CD3EE2C24C910C62,A780A3485CCCDD88,4D0B0E16650BCC08,B52B9A70AB4B2C3B,DBB50AD28FE8D676,1215CF3E467B3864,F15783B1B9832616,0A9B8AB5E7866494,B9F25FF7332F6893,56D75F1C229E52D9,5D24149D80FF04F3,00000CF1954895D4,4E2813586F8271F4,62E00CC11139D6DA,F4450F00468598E5,126425AF71814514,CEE67C3D4101CBEC,51519525BD9766D3,BA56C996D48C522C,F941DD289E57FBC6,32207F7356BD7D3F,59A3A22613EF7C48,64DC68CDD9FC7C61,00000A33148CD74B,D4A4520D024AC049,7A23F745064CA1D7,1B3A5F6EBFB3FCDB,F8C792374F130EBA,AA2AC4563A498612,82E360F54A3529A2,B9234CE376ED443B,8220CBE364AF3D95,0AC73F2EEE61BE4F,4AB23DE82F81814B,7A00D2EF56D92EF4,00005197F67016A6,27072CD0E7C9B3D4,C1D588FD50ACEB93,9FBDACDAC9EE69C1,8BD362B9656D565D,5CEF0FFE1C9F2471,C3694C851695BE3E,0556A6B7A5A4162E,AD43ADFF82431CAD,8C00F0364E05A9A2,98F21EE46EFA741E,EF0670CFC538FBA4,00002565135B34F8,972C43B3754773E2,0D199E332CB471A0,F816AA80DB8081D2,C443FC21BB05FCDC,5FAE6103B239C346,BBE693A4BD3A2AB3,438F9C06F3D17763,C799385669E02146,4CC47837A8D239C3,7CA4165939DA17B8,3BDDC69EE6F6B2D5,000039BD1D8D95E7,2E8304423808802E,7A5153B7DD99F81D,3EDA47F7D0A78081,508FB18383A86E02,ADB07CD91F5501C4,E88D39D2571C89B1,ECEBA1AEBA110998,D6504B7EFEAB7624,4989C98E5BF8734D,445EA69373BAF3E0,011EBB94C3503FE2,000034AF452ECCBB,0030810C4C4D5092,5ED5271A085F486C,2CA9A3C6B99669E5,7685D0172069FDE1,8C0741FB74ABF05B,C442E31D2CB4D838,E9A77C35E596BAFC,07920109BC1940AC,ACC5A384923F6F18,83B6F466331C1FBE,ECFB36F6ABB4D7F2,000062ADD12F02E6,856091211428BA59,C95611FB1DB3D7DA,B2E8CA1F5F3E8AE7,6A8C707B12D744C8,1036A97113B78F6E,DDBF004A2EBD28CC,45C40B6E0BA9D8C9,34383C5BF62E11F1,63E514395A124373,C9B1898C7A8130E3,265C5FACC6D2BB7A,000034247FEC0EED,13AD2292A38CD7C1,4B5C87213CFFA770,E08D577A869C514C,B39BD06C1A57277F,471A976B153B9129,C1289BA1D6226E47,DA388F1700C52F79,7F4CD8E62002E152,94F003BE0E9B58A1,C3DE09DF4B1FAD5D,05576840B66B926F,00005BB78406B4F5,5FF5EEF8D64DDB96,F588F6F602543A0E,3E392A4B4CAACBCA,0D71D909C3E98B65,FC3D42F1254814C8,C6A08D76FD8A0F3D,FEB270E3F24EC8ED,250C6ACEE22F689A,A592E0792361F60B,DBC992E72363DCB0,211A43D16BD67571,000018033E9277DE,131720EEABBAABB6,FB4F9059CC228C1B,D52422922CCB207F,56503E268525995B,6BE2ACC8FC515B3E,0B46316FA6AC5B5A,16ACCB598CCDE064,681B71AA20C855A4,A1B8DA3372F43D21,E946FA1A203A98D3,495374176C77988C,000033CF2A467805,27961B7CDDBF31AE,4943115936794192,3F8324FBBDAF84A0,9618C4EF13E9A6D6,0FC9549A5CE25EDD,D854043A989813C1,E847698126F6BE06,5E9A6DF91FC9D232,3275A3FE1995ACEE,626CBBCE3EBB99AD,7850876BD3062EA4,00005EB3B3A9B5F6,F8BEDBD94131C3D7,F5A6EB4114AA850E,1C0C205FF3A79B10,00130BDA6882CFA7,D1E82E6EFB0318E8,C1532899C69D787C,E87AFF8398519C40,77D9B034E213BA35,5601B8FF4518E4A8,DB31BC289D40BEBC,CCD5929D42374E93,0000420D76ADB609,4B6A3E2ED555532B,1EEAAA1D2FBB8B9A,3F4E2ABB87512FA1,B4BF918F3922C87E,C19242BC87717CC2,57EDD8851827695D,E1DFC953B39591EE,B62AD213EB061954,132B359CA9DFB117,7493490B87731C37,6391AEBFD2BFB72D,0000435CB9374A8B,DF09F03548B44B40,B324A34DB2AD0308,AFE9DFB5059BEE46,DF3EFC510B831CBF,D54574A167B98E07,1AD484807B33D36D,5590EACA886F82C9,1BA44EB95480C8E3,7DA517079000122C,9BE9111DE1DD83DC,E9B3D60B83DA0F6F,00005B2C648AA137,DEA914E51B2D0932,EA432E0E7D184E7B,462338D3E139B294,9F0976E292D88830,558D839AF509618A,7CA10F3C49C678E3,3A58606FE3E52FA7,15216053191EE121,DBA70433B189867B,2EF412F454E3188A,03EA066EC9858482,000052FFB1C68AB3,1DA37D6122CFCE08,76D86E99CDE2AD1A,7ECF76BA7E5FA3FF,D51338AAC6083ADF,CEECCD5B503BFEC3,9FA7CA7312EB3E28,FED48703B8D678F1,32A5F4B40CE0E2C6,048589F1111EA5E2,F7715BCD7BAB8E1A,AA9A383740548549,000036F5B845A102,B9E5F511F5CEBE8E,0197877F5B3E0B1C,1B97BFB558BDF155,7B000434B529C862,93FDDFFEA9C4BD7C,987380DFEE02465E,0901C68840FF8ABA,EEB3E1F996B3A638,FA86472608951F3B,C3A55A51E1058FFC,AAB3839E91171DBD,00006DCC659A6A24,A50FECAFEC629C4E,F31DCC3E50840F35,93C02CA7967476F8,3D433D6106A67D27,AE4B48E4689FCB20,E9025B3C29A8CCE3,08B3D96B4F3B7DBD,17E5E7E27E517166,881603C1DCD246C4,EEFDE8705E4EB0E8,2F61127267753D4B,00001976CFEA7A49,1265BFA37FE2CDAF,5208586A0515ADD8,71680B7AA86940B4,1B7508A83F38E4B4,5B56263350942CA3,534BEAE7E3F49242,8FF0F02C33611FFE,2CD605437F1A82CB,56E4C1DE1283BA01,9186088CCEEF430C,1E4D194E5C6F4050,000042C5C843917D,AC43355D0D388C95,C8290CBC2DB21849,5942DC8D3D3D78EC,0ED7EAA5B374664B,1955ED6199A78A02,CAA3535AC8B10890,09320C5B858C8DCF,7D1F70FE81E5140A,4EBD126E80F447A5,D33B1357DFDCBFCE,C3215020A70C3263,000054A38A39209B,FE1C3D21244BE405,C0D943DB7BEDD962,1537DA4B2A354D1C,EC83E3D51BD99F6D,B459796C874EBCD6,5111883D25B7FA1E,6B10FCAE6242DE4B,74E56F342F32C1EB,E17DDC59E982192D,62D707DDD3250EB9,693A1F21E6030D49,00003BB5A3295780,7F3FC5961CB1BF49,760137E8347FB28A,6AAC7605E3EE97AE,5A46C9D6A69748BA,648CD340914E54D5,23CF8286739B4748,B1BC19E9BD95FA9A,F4F65B4A7277B3E4,E19124FD12B76466,DC9A1F8F3B042F70,94A6C21F6DF04B80,00005EEC4592BC07,F1AC1C9BEC099335,A4C9BD5545959CFD,425DEA7360651109,D4C880EF63822A9E,09E0B12201DAB1E0,6342EBD4BF1CDCCD,004915FD210873EB,D1EA239B8E32384C,CF2719D545A79C94,00E312B107407DE0,4670973EC0B179B3,00001E7C1C80266E,3D99E1294D801C08,B7A2484681731D64,4A3854620F75AC09,3B52343CE71BE121,F58D4E19C8218B88,C45F3D9814F0EFF4,5DD6A437CDBE446E,F213A5F9156EBA7E,7A669884972BBAE2,7FFD1672A8095007,6AEAE8310E6A3347,00006CB80F28EAD3,1D52AD19E7E549F6,F4E0A47A06CDE70F,A7DF2639BD92AF69,FEE0EEF3763EC7C6,3875D69ECF49A8B7,AA9DF211862BF51D,4BAE6F73E8D8EF72,EC7860D135B5B55F,500DC9E552E7BEE6,F24E084BFE39DE16,36B9E9EEDE05967F,00002F891B152CDF,C2B5DF6F29E2ECEE,64DA642DD54F2A7E,C7C47000691BA89D,E43DE88CDF09959D,B6E86B37ED352EDD,465400BAC74516C4,80F2A9B7B3D649EE,762368784CFC5B2E,D3817EAE39AF189B,2FFC611535285D22,7138E114F2926FD1,00003DF4D97FFC24,3820F506F6E59E04,81459AA1CB5620F6,F262E356C35E7211,3346C25AA418AE62,6F522E5BBF58F477,831EA33F66760119,194FE07A20B0C55A,B3F563813AB6B5B7,5A1E257C9F6E3C9E,80FE3B59CAD6BDB9,F7070A982987C723,00003B9FF010727D,9E7B379486C5F5BD,DF095E4AAD39721D,CFAEDF4252C68C9E,DCD5461548C325C5,B02EF9FE7B963A17,50D2D39CD89B7CB7,B75E54CA3C26BED7,F7740F5D043AB2ED,9D672B6704A1A66F,53BE3AF54AF74329,EEEBD9255EBE1BEC,00001BC0C609EF13,3FF7EDBBD0810FF4,35F3E0E30427766A,456F181E6C806EFB,CCCA4B3F514C2DC7,432B09AB9FB7C63F,8362EF0450058042,E46E9B8A071C5A4E,208A1CF9737E7AE0,D1128FAEBD213428,988229EB666AC332,5C860454A83336A4,000041F83B6BEC14,C9AF4A71C452E888,8A2DFE2BEA315F17,42E381E729D4B78D,28E7047C1E796770,D61092BA028BBE26,1E4DAA170FAC2B9F,274882F95597EACA,F67B1E723068BA0F,88964B2652E53BFB,387C07C4BD0F37B6,49835678CB41D1F3,00006C6868232752,25BB9FFD28CBEB41,8735C15C1BBE3C61,2FD690AAF70439AD,841867A0F0AB85A7,154973AA1393EF0B,1ACFB9D6A95A23A4,39363A8E3E2D08BE,AEF1E0FBE1ECD5F2,8E5DB8BEF6E4BB2C,E2EC4D0D16D143F6,5DE1231EB0F517A7,000021E52B41AE65,7A530F6893599917,758C3DB6594CDDEF,2261B929F603F39D,D434C92E92E8FEEE,78724542936A4F41,80C94ED551268F14,FD769E120CDAFD82,13F2CF0143411F13,1471AE21D00D1F98,6420CD42C7B5842B,0AD26FAF424C65E5,00001D4C932CCB22,66DB058F5B591EF6,AF83392BAEC3AD69,74AD9A23C4E64648,45949249773CC24E,91582E1397C2C705,9923E8325581C305,1AE39E58DFC91953,4A6333045F8C2174,87ECD374E83068CA,835D39717B36C90D,D1F61844400CA4C1,000045E5E3EB5707,BA11AF23E76F9C8E,8849EF88B72306A1,8D296E37D5D52DF0,1880473267C7B8E4,0DA4C90079DF2968,83471263A49BA618,31B3642E1F7959FF,C02EC04FEB0A9C4E,763CCBEE72B40E94,41E90172C8903AA2,CE643AE525998842,0000565E3A401C31,CD254870721D339C,AA7CAA0F15283CC6,60E93CCD91B86712,FF169C373ACB311A,9243DE6A4579E974,41EB95B498781796,EF996BCF6EF677B7,E653B9147BB7EBB6,A094F7A022731399,AA67755F46BF4D5D,7F2D78311CF6F955,0000358B6D8A4450,9DE61A90ED45F72B,B30100F1678671A6,D8ECB370D8D50BFD,F03386A414D9AC71,4ADCD96812BBAB9A,C1667A8FCC6DB5B9,172068D02DB0C9E1,233D6043EE9055F4,36FE78FED336AB0E,7DA25261B835EB75,D9A66A9EC23C2073,00002A3A31A9782E,A511398EBBDD9BD1,ECFC7DE32621B8E2,C7A7629E4DF8BD16,E5E88029302AE41C,E580D2A603DCE2E5,BD84D66A50FC1888,5A532E40826B520D,2AB86EEFD8980C99,5556B42AD90F2437,3C7E0673D9F9FEAE,D8477B56CA2F28FD,0000505A5D8D90C6,4BE2FC9D275D7453,0C0ECF7EA1151254,00BFF73798E60052,6AF745523485F294,7FBC96ECFE5BC8CB,B8CD1C2DB06838FD,48819B2D1538701E,4425AE0DA2323A5D,0C91F9CEC9DF9376,6D811A9F682854C5,7C80A72861ADA99B,0000010C23F50161,B77BD538160B02CF,F015530EE8BE172B,1E35EDC73AB08F49,C2CFCE906E28CCDA,B7C3952B4EE5F34F,49A386F71D75FE66,929EC90AFACF59C1,C46DFFA7288D283F,5575949A8F3E2CCD,70B67EDD1B123943,11A48128773B7C2F,00004B220F91B77B,7D594E6CB08BDBFA,654FE5C7E7554E36,75D6CDDE0BB2E0A1,3A78D08E838F01C1,60507ECFF3212358,3BE650D862B5ABFD,70FCC84B95C93707,2003AE42DAFEC977,281DDC44A33ACB7B,C430579AFD29DD4F,618D534FB0457245,000008F2327D7C99,17B9351238CDA554,77FA8672D3BD0791,1CED32DFF3992E73,4CE3CB5573337BC6,E30831FD268C4C8E,88FF0256CA45E6A4,ED70A3041962756E,1C35F5D0D9A1C194,597B31314D1D82EA,8C6234AF30A0CDCE,1E1FF8FB2CC41999,00002FD29581BFD9,121AFD232CA097F5,FE800C1741D67DDA,BB6C49003B75ADA1,AD3C54B49DDDF46E,24D891A7DED20BF0,DCF736C453F114F4,0D43E1FA2164E676,B7FEE777E0A26A05,E5C7A6B0D81E7D24,E77C329FB72C3389,90DACCE1B57EFE9F,000051D1DC43B786,3E05BE4CA90AB188,2F325B9BF1CAEB44,7AD3CF4F0EC6289A,B02D31FCF507B065,4F26CF0EF7C1FB78,43CB3CE26A07DFD0,74E5A0154E74008C,D6FFD26290A44795,5CA81059C297AE62,7B3EADF4477587BC,9A17C894C5D5E342,00004105C67401ED,FB562464B0D42464,FE754DA1BBD8C53A,09F19453763123DB,AD3010AF00E0F03E,E35106D4C67D5FD5,5FF468C5FCE981A7,12F6EE72789F5BC3,C105E164535299E2,DFFAD89DC2939485,772DEB28A3A811C1,7AC5579A4D41721B,000008C3BC3214D0,9842AFC867CBE3AE,B494A7ECD0C20997,C31C5274DB450B68,85EE60CACDA155CD,ECFA4B66990BDC1E,309BFD0B6055A6BC,83C37AD592BD51D5,CF6475EE76821D4A,D109C14BB14100EF,1098DCD59CBD0D0E,10576CEC5D678439,0000106587E74133,BF87D3F11597BF97,51E5BA0EE09358C5,E496C7B1DD330115,9C792D374E4DD8BF,1CE59564F8E4CA46,225474A33D3AE358,51BB67550ECF284A,913C05370BDB414C,C8350FE6B5E1706B,44F606E05CAD766D,BB47ABBF2C2020AD,0000527BF85CDD13,5243352CABADDD96,7C143914362E88A7,1329F0A364EF3CCF,C60BD07823046ADD,04D0B57D268BE3CD,20EF290F2EE3DA97,06F3F30763B1E1CF,A52AFB3DDB24B3AE,BBCD291E1E789EE0,8BEFE2C6B3814FA3,671A3E93F2683DA8,000030EBD35E72FA,2CB91646F8D4654D,9738084CB1E30D4C,72AD5C3512D07523,23E54587CD14E401,9DAF82E6BBE39471,3FE3B005D4C84BF9,47B2F14D61852471,7AA5071A1D640E6C,9B01AE4A6F231F65,7D444D2E548AAA5D,4131195EBF025DD1,000038B9F980F09F,2A461C4975744122,2B851C8EF946C6C7,217C6A3ADC5DEE57,DF362638A83DEA09,6B97014BCAD7051E,677DFC53738ABBBB,99A7FD221D03D666,EAF219B1CDE90494,DDE05D1317770C53,26354F05E4C965C5,E7BE89C393B31B09,000053E5A8465D84,F51BDB98F0D15822,4443EBFF6AAE3A96,76E6CB9F25C4F767,E92639ACED7C9DBD,7E7AA8C265EE4745,159771107CBF50B9,792D4F8C1DAA0C76,7E7367E45B9593CB,A8D05713F5CE702A,73C2F92B4B5BC027,193421D25DA712BD,00002B52D04AA278,F1BC0FFA8EAAA512,E9796114D7ECE644,04173F1592AC6F5C,D5CA83CD1FAC896A,3553AA2AB6409812,47DC1645F8BC6E33,7B172B49168C66C4,C4A360FE203E1E81,A7F973F47C2E1E47,8D4538D01D385B0F,2B17E867761D6CAE,000045D59C5BA75C,C63B03F49054FD12,1DDA0AD6D20D8C19,993B10ED75EE32A4,F02FE2F12123DB8F,18FD3CF5545D2E79,0DAC6123F383834B,B28C944B0234BEAF,38A96A771A8EBEF9,05C0D6ED0D643576,2D5E57067F0686F7,AD13B974FB8865D6,00001DC4386D4040,4B1D2B753147120D,4C4148B8FF791C37,390F0A3DBA774100,65B8768E8042C4E8,533F8B028C3020F4,12791ED6C9EC812E,19111EF96D4392E2,4ACB838BC4439CB0,AEF3E368191AB187,9AB89AAAB2ADEBD3,BF1304E7D087D8DA,00002D5D1EF4B893,882789D2A35A7A9E,4422C5FEF2EBA4E3,5C63A17EBE3431C3,4F585B247122A096,AF9928351D1A9C34,6A6A24ECB379F348,C6138F7B6CBA211E,7B493427634FE7CF,A46B986FE333AF90,AF1A7C165A9E71EE,148A528F492AF37E,000067E4C54A296A,2E2A7A2684B0D921,F4E6FEA1C4B9194F,7CB604CED984460F,5AAF31C9D3A02E24,F1CBDFB4EC785FCF,6FB22DF14E21CD25,D8E5A533A81EB87F,6904D59D25B70A8D,BEC63CAB00212C07,38D96D250ADAFF5D,4C48E296DEE21F6B,000018406C57BBE8,2929F0D329C0FFA0,1548E63EB77F50DD,E8F70601C64A8001,4021F22E48769625,E21D1F22A1DB7D5F,A8D578D03FCD85F7,CBC86FD4E24942B8,6BC7548F8C527F47,953B867C53146261,88FF7C5A62BDCC65,232DC854E6D2DFD7,0000139EA8B2DF76,70B033E62B877354,374A05EB5EE763E0,4E3F31C2C7CEDF56,B672BBC8ACFF3323,D5A443E0E52C81B6,25D9B4E73D4EAF3E,5FD9087FF6E17EA5,7081E2403447D3E8,AD26B9EF1E645943,347FBEE19CDCF8CB,D0E6104F851DCFD0,0000516B2DB8B994,7E0E415F44310475,D9253C0FF63F00EC,95C62D8F82C514A0,E26C8DBE6017FF0E,89BA42918BFB1A92,78E381D442F2C501,76E85B2D8BC33545,73EF150BA30F2169,A2656B7044F0782E,3BA50470DF0D030D,EAE731FA27A92F92,000058F56E60C952,FB67D8B56D6B2FD2,9D12468FA1472E8C,A398925B39B88425,045F16D43B153F2D,EB2A3A8A141D0EA1,50A0C8240D2D79A1,CBAEE67908F422C9,1B65BC0F3CF2F7F0,CCC7F8CA79DD48FB,81A1D8C188EB5BA6,485BFBDC8ECDC59C,00000B954F57F95D,1CF98EB1986EC771,2E4EBED80C85CB3D,893031903E71372A,080B658B4CF0E337,0B597218B3E8EE2C,B657301BA6EA4072,1C00EC2E158A175A,D4284C845C653464,86307AA4A9F9AB92,3BCAF0CBD4A2AAA6,158D9B15645B22D9,0000662D89DBD82D,D4001AAB4E69DF17,15E99D34DFF1A68B,6B3A19883E896454,16261A86F9D75BF2,1270F4368A118BB2,663DBD301E974642,67DBEDB610864589,AD087A32F32E602E,9A366119BE72D124,7956BCC6FCC75D1E,CD18DDE14A424590,0000309343F2C8D8,92D97BB6FD96E574,DE0AF973BDEFCAD1,5AA8E9BB4CE94C41,8A39F44BB6A99533,64DAA154613F1E2C,7DBD58FEBF2181D2,307AC4885544373A,054DA06C410BA164,98E35434E8C42541,0CE7D4A39FBC0D5D,4D3E901BCB40F844,000039C829B7F75C,D28750C7D080EDA0,BDD8A8F09E854830,7741FA85BDF78F67,57B2EC7EC4BEED99,0CDDEA2D7AEC435C,26FE43F61CD715FF,D8F94669B4F4A587,18BACAC37AF9D3A9,AF9DF13713C08E20,D6B3563F35FE6F4F,801B4CFB47BF2CA4,000014DC6C08F018,891B9940A59CB5D0,96063D4F1BE40A12,8F179B48B3266E75,9CF3A9EE8C11B2C4,0AA2BFF7CA08D929,C08A4F297ABFB392,5A2CF2E0A6CD76E6,1D2519A064E70876,E48B18DE15DDCCA3,6D86392C05DC7804,CB49854CD37AEE5E,00000BC2D24DB421,B56E8E02C7B39B74,1D5B4D66999F481D,3F79A2E5CACCBE5C,AA52306DD36FF76F,CBDC3E9D2E99DDF0,93D4307FBBF1503A,2E4AD75C6B89B48B,225C95B5A66DCD30,6246A4E1C7BEFFA5,2EB915C319F89BF7,DD429C5E6FDE0E06,000043FCAB438773,5FFDDFD096A2AD24,9F438412D289FEE4,394F7D7AEBA6B0F6,60AFB6EDCBC0DC5E,9B9960DCD38CD4D5,86616332989956FE,9E91BF9B9F13FAB6,FE05A847A71D63FB,24804EAC58AC0268,F9C221988890789A,6AD152A2B0BD3789,00003B47BC446429,1F86341B315F9B4D,6B806FE32D75B0C4,F2B05109E00D71B6,9F6921F962D2D53D,331328A6A95FFDBB,9846ECF9BE9F382C,FC82AD83E1573C3B,F3A420A58912628D,8672EEFDC48D56CE,5D40E3900A7E2BC2,EB735994D8BEEF18,00004A31F48FC5A7,68A5069D497F1157,C379ADFDD2C1A3E6,A00B16BE32E5B37E,7F38738F7E5F2D08,F1D678907B45457E,8AA532F86816D247,D63BBEA1CD68818F,2EDCDF6CFC2A0AE7,697F05A99B2F92FB,C1D6AFA61C09B578,B4606904BB91BE13,0000502F0649DFD2,B6F44D597B225A46,CC20094E2CC6B023,7ABB07B0765EBAB0,82A691F226E40AB7,3781969628F7D9A7,F1B95CD02A87C21D,FBF05D2B4E4B649D,82702BDA06E40473,82A0AEDAB778FCC4,12426ACDCCCA4E54,D4D53307589F4D7A,00004F6B0BF91AE1,43A75A8736FDC0BB,BDF8AA6A1769E5D5,603939A3D59FF932,B72858162504A34B,19B11E096729D28A,8AEA27441265FBA2,7932F1539920949B,E3982E2D0974AB89,62F497B0BEC9426A,0214A38ACC8B2B30,96F1EA9A604E12A4,00005C4D8441248E,AB89CC508E99E515,B131A5D4D0A80DA9,9FD68CA31524E1D7,5A19CC4946DBFF41,34B44B6E6E0B959A,6543DA1C39612FF7,21D96D33A52C8B9B,B529A12D037B21CE,4B52B7B1390DE207,B49EFF14C679CF05,6C921ADCD53F3451,00001B690046BDC4,3A01B86DD712BB06,D7C8AE59E32C631E,F3FC845700AD7A61,530ECA869997CE4C,07B55B5E31546617,F555F6397110910E,AF2569CCE56657D8,C13A4FC0DBE014DC,05C0CD77041F997A,498FD66AC3BC4D82,20EAF4445639EA9F,0000535CE7655ABC,A5F34EC00D0CBA89,6A21680E52F9015D,9581513E259B799B,7C8C1226F11F7A46,02D96A28C1A5D121,6896BBAD9BF7DADE,F6383282B8B61CAE,7B885E586AF9AF37,A4D9E6F6461F2965,753F795BE1574ED6,27852032D7A8DB86,000032A8F596E031,991AB789B14FA6A4,CE8885B15E267FCE,80BE3242BD9490CB,DECB5067BABB214B,99DAA3050D400387,C6601855815172C1,28EF4EC63ECF8CE3,C3C9299E708B6CD2,C6EC9B623F706DFD,C0442D6C01C640D4,749E3D6170EE70DC,000039D90EF82B11,B378F6F7581ABAFD,57F3113C24B15111,0CB7269C0E3E2E08,92F6BD2B0B4DEF7E,9448999F71CA412C,3E9BCCB8C20390A4,1CB501050734F3E1,F7D733CC7C27529E,1F0D0D1DA76E3372,77337D57F2036727,300231F4FDD5A6F3,00002F08FA686926,09A24793EC752386,7114483E913F54CA,A6E555357F06F603,D78351054708528F,3EB51E212EB04FDE,C37F6B68B20FF9A2,FF91147667578525,D19E6CF1AB12CB64,690BC515347B5206,AABCB14DE7FCF37A,0E67DE17DB3ABDA2,000007FEFADA2F64,5FFDB9F60FB46458,D50AE62924EBDEA8,445C608FC5604BDA,366099B7F5A911D4,521AB77E5ACF85FF,6A22F50FBE4AFAB0,24AB423214B12239,FACF8E9488210D1B,EE93EA61FE38C788,80DB4C1E6FB0130D,A6B6813A635C2B9D,00004C2166717210,0C81D488953C0C86,8727A26D07867C53,796358C5FF9294FD,980ACCFC243E4173,C0B2B5CE7679C0EB,F518B6920E1B6071,8D9FE6D22CAE1A8C,0650738675AC96B7,B255E71DAF0D7A1E,B1317E851AB382D7,92059BDD0595B9C6,000025D49FA94F03,F87B0990A5239363,928675FAE8ECAE0A,8DA35F1C01C54B3C,466A0A429B198A77,CD205F64F613E615,C94D440C8AEAAA8F,D0E33BE296552139,0EFAADA9B6D0DE49,72BDD509FD4222D2,B2461F57D0F28F81,81617C9237B61DFD,000032B0C30449AE,05AF7E78BD9507A4,46F8DC9B003D9FDB,8D4DC125F3E4FA56,883B885CD238C219,60F43D402ABFDDC9,16881224520B1198,CFE97CE3F64B375C,982A68AC7FB6A0D5,7C43AB38B5481128,0E98CEF32AD86D0F,0798C3596BE0B118,000040CD3A53CF65,F9B3051C78CBECBE,F274360E4A484AC4,6B296C117EBD4B25,96011C0E5D54BF81,F24C1BB10AFB45CA,7587795B9DFCB240,E7D7B0091E062621,07919B95D4643686,B332A6A9B83B16DA,33DA2991F0562508,2290D71F5FE4F54B,00004033F83A6DBD,3EF57AA71F843049,7C44A37B4713A86D,AE064F0ABE315316,83489236CFD8643B,D7444A9F4A7A9C0D,4F4A8A0B127B4B32,446646444BA4D73D,9790DBCE400E8903,2C191E7D2C09D17D,F54F038705F6999B,604C81427369C48C,000049D64663A875,6631E932B719F887,2D7E6896413FF8FA,1789FBBB8D4FCFB6,8A34FD706B03E1F9,FDA4563E7045BB4A,48E5F52547965960,1FD7BBA1E9491980,BC14C37DBD2FBAFF,FC7A3B29AA0D0A2A,9499381C2EE8B51D,44F1380ABAC7FDE7,00001E884F5EC897,58D21596AA231BD3,15F0E61DF58950B0,F2068001D47DA33A,DBA639A7C4027A16,B8EA828D89EE3851,8BA99F8CF7C42E5B,A34EADD2C230695F,B3ED9B42BF259EBE,F9F4E58468EF1771,6F8A8B67EF6B4CF2,7943CEE760EA48A3,00004B8FD14B6709,19B9DC37DCB17701,D2200F9BBB89370F,AC5522F8297A3AC8,D354302475914BCC,B5639913BADE308C,9857E1C4C1882955,47708DE10FB4AB2A,14B9412320CAD103,7097186DEAD87751,C31C1D017B05EF58,6AE6136AEB393476,000001371CD26BBC,F6736D0B346CE5B7,59BE0696F6FC8351,916820112D6BB7A1,511AEDC44E93BE8C,E32478751179BAD0,85328DEC5781CB85,D39956D26324ED2B,9FFD0B1467622574,B2CD6607D5547ECC,ECBCF0EE715C8B82,6F7A8BF9CB8F89DD,00002902A35944A0,26DBBC623D2C03FE,B590CE4905638145,C65F821DBF04BBBC,EEC62DE07ACE51B4,7A17D5839F85C872,19448B86CC3405BB,E43E1313981E6D75,515C995AEA8CCBEF,EEF8911CD80D6195,54FAF63518766D9D,91BE7B114F3B2C2F,00002D3DF4691568,3957591303C7E0B6,3BB5B867283EC82F,47FB301535704B03,5F51551B398F57A0,D665AE9C43020C1B,5C4AEFB4836B6ED4,9A053C44A37D9320,87E08E86D150AAE5,B40D4DCB2B30A7BB,4C1FD8854C0C09C9,63BA5454F25327A0,00002B126DD96D46,EE628C664DFA739D,610DE8C75F65AB18,CCABC610424EFF08,8A22FC54CAFC98EF,090C32AA2020A240,B2A112AD8D573637,D4ACBE1F999B9A29,EC257EE28245DD55,403E707EA34608CE,77927003A59C798A,734C2FF6D85226DD,00000147321A3F20,10FCE284B735312F,C9F43EB277264424,B0E6DA96B027428F,25CF8805208E5CA0,E6012F1F7F7FE11A,E32A347812AE5EA6,7FF93709451A3C50,D76DA1A49B98D975,162D7738C17A97E4,7FA9D6C3910CC000,574C6095B785842B,00000B4838C36B57,ADD78275EA67722D,C56DCCB7F00AEA75,8D4A83821B618FBB,3EEB178F2B67538F,10C957EC1825EEE7,13F772FD6070DB2A,CB7B77A53886C5DD,B0C836298232E47E,2E28E4C8FFCD1D96,01B9D2C9EC998B49,7E6E10E8374B169D,000021FFC517D0FB,2B0A5ADE4AA73596,6A0AB9EAC647B652,ECD55BC5F7EC1F19,06CBB0800A6FBAA5,0F125CD9F7421006,2BC061583427DA50,54514507D045D8DE,55A528FC5698B041,EE82C6B3C0A51657,08702A5604B844D8,387E44FEB03BEDEA,0000495F5D6E08F3,F51AC87A0DBAD055,F48A14A8B39C8ED6,8502658FF353A7C1,6D94D025813024BF,2BB9C29CAD049E8F,649E0201BDC5FC7A,A95E0464B22478B2,0EEC76880F8D17FB,C0302AAA89F08F8C,D8789649ABBAA590,6793BA04A0B9EDBE,00001C0A7732985E,B378073A17673D13,CED75D64BADCDD26,DC6D06CB1E4B8473,79E5E61BF590368B,59C8D7038FC1C335,2066E9F118716617,900332E4E0536243,941487ED510B87D7,94AA88F4C3B6C696,44243F5D1ED2A058,AB83098FC9F0EC6F,000023F307FA3BC6,F7A3FCBB74944D0F,F00140EF2FD39B7D,4E21DE00A3B93E60,DB6462166C3F662A,B0B714B228FD690F,0EE9A4DC97F10362,59590513592822DD,29C52ABA6F43C2A2,AE887F9896E3D16D,BCE30B5DEFB75F16,4E0501E027502A06,00004312AE339CA1,527519EFA36517E3,91407BE3BEA255AB,2E5A07D310D2F59D,B8EDDF0A9A61B92D,498BC9610D20B511,F6D55D9D41BED830,6BA1975CC4D1908B,54E3E0521AFA41BD,4DD0575D23D6EAAD,B5C2F074CE0F7848,5A7271C6748D00DC,00000CE23A40B074,8B84D69E4280DD3F,B59ED02F76C7B5B3,B2AAF6BCD0050DE6,A7E320893BC4081E,5FA87FCC4C7388D4,5E84B14098E7BABF,3011168553B06453,020050B1569F5E6C,6AEBEF8431FF6DE4,3104D25F24358643,16B610FFB1D83A8F,000003C558B5EEEB,26D44D832C11B410,785C7E90C3290D8B,BE54A021131E3A43,A8284C91AC1FBD70,EFB20DB3B1644163,272664D90F66C3A6,896427D066AA1392,6FF64FA15091BFFF,5CC0D24C64BB1BBC,D18DAB503F233963,AEF25EFC7C0298F7,0000625837DF9F62,D10AA07675B5772D,6B460719B0489409,9278A46D9E402D58,FECCF7A79E75FBE1,FA0A5D7F9FDE7A8A,BFD0D51F85E2ECB8,B5A2A95167F23A0A,AB2690AB0523BEA1,BAA408971CAF7CA6,2B20B4CB2625E356,1CC463952811892D,000002A0AB3CBAB1,71E712CB27A08194,3FFF4A43CDC50638,90F82F9B44B6211D,5FE19A15734EF5F6,657C12713D5CA79E,EDBA87DEA36A35FF,4547595B7EE4C244,4DDC42EF6CE3F7F8,04FC9CA1FC81F27D,98458AAC9175D35B,775D835062A994BA,00002581A638C3D9,9206237FF172F6E7,8AEE0212BE6E20BD,CC0E32BBAE1801A6,327DAB6485BB2060,915E4AFFBEA47B0E,040F2F02A3EAFCD9,43D88669F02AFFE1,BFEAF0DF2CF41576,C48DA89BBBB27DC1,7D2945CDC9DCE719,6735926E05FF87EE,00003534C4540D9E,FA7023460B1B22D6,1DD96A50E6A34647,41DC3BFD4B5A23A1,74D6CBA12858D069,41805050724AC8A8,53EB63321EE78052,39CB915C7EAD9F39,9F2F1B7993E666CE,C81A5E32D4DB3BD8,30C93E9A1A2F3994,9865C9AD11C7C73D,000004A799F4E98A,CC9A6C6639124496,61C535047CE2D272,033500E3FE928963,7231219CA8E2F4FF,4927F30EA350EED4,D62843CCDBEB9875,070B6D895EBE1EB5,16AED77EDC414A6F,0910A66ADEB6B61C,C683CE0BB328036E,11CA547311B272A4,00002429504F0EDD,616F60D7C28A1EDE,D6C71F6C1F7049B5,EF9D9A32B682C959,FF22CD4E39EFFB19,220931286A87096E,06479E62C0E77D0D,A4FF39011EE2A03C,9F4C60BFB02869C2,48D66379905DA1F9,F33BC0BBBF67F901,408A3E1EE11249FC,000012231FB40398,74583276CDB13A77,A0719395D0DD135C,F1B3CF5FD915413C,56F33021191E3752,61F37F37151631A0,FDDD276C36940030,7621998FF400B43B,292FD475B9FECD0A,95C3A905E7D1FF81,AE6952F862D7000F,CA8A2100E567A995,000018220E82D273,06791160C96FB091,EC08715869681666,77081894B8EA27D4,BCD50471E7128B35,BC0C7597900E2266,796A1C4CCC83A7CD,ADC7C7C268CCFF0A,8B02464E9B5502DF,E6BD41D341D9FE9C,76344F888538A096,49E3E2CAC4C091A4,00001C4E36C6964A,A13BE371D9557F0C,BE0DDA9DCF53F80F,CB2615289794880D,45D3A0D625BC5F18,0516187DC5EA80F8,B68C54FFD287035B,DB1DEBD8DC7FBC8F,69239CB9F76687E1,A0F5FC51C2EFF995,217AF56E3EDEC3F0,EC4D30693E128D94,00004216340ABA19,43DF3E14171B7AE6,A37BB85FA7A4B886,90CFCED82CB1A1A2,8045FD0B3B047C20,64AAF3F035328F55,C6F4F1F601B4400B,CBF788C2757A3F77,57E425C2C624FCED,31112D2784208927,294093F5F588B756,F7DDC951D9FEB0D0,00004874670F2F74,1C365ADF22A15CF3,BA3AC3A9D7ED0D2C,991397FD0B726F2C,A566DCE7B4A575D8,96413584DA242686,B7CACCF06CDC5DF1,27F7941F119A5283,87872C0334F7B954,24321AEC20AD6710,40EB4BA999DAB8BB,18D6D065568263FB,00002B7AC56D871D,1B8E882DBA63EF27,707A4D0F7B7D53FE,36E6680E7E0FC189,826970D4B28F8B70,14DAA9B97F348EA9,C8903092958B36C8,E599C19F84736693,66903E91820AC687,9F01E68370FE4F6E,25C6D2B98FA5F36E,8E62531D8A3900F2,00002AC7483B24F2,91465ED9E3CBDCA6,59D0F629A8C5650F,CBB3C465F3D1875B,E995054A38604D99,D952C1ACF0781C29,1776A4B71856DBC7,879BC08660D2B4B4,E2A0F7EA977DBA51,6B7F028145989F2B,034B72F50C7E8D6D,426564A064859654,00003C33B437BD29,D344EE8DBD2B4CC9,F1ACBFF718E8357B,B04988033F77360F,CF5315D779381F80,A5D380BF925F9A4F,C8E992D2F2F3292D,11802A99102A4440,CF5E9118F71BED71,4473714C1A1F8B9F,C1EDB45D92D22DDE,98029F4FA2A61D6D,000001072B127275,C9B7DABC86EADF10,2E785DB31A68531E,8D28CAF5105AA4A3,B7E39BC7BDCE3C02,D78753FF84E4A6EE,40A4C638EDD3C658,0FA16CEE2F46B6D2,FD1AB124986A99AE,A9F23A721BE10D0E,2BA6B67DAEE9ED7F,D66A8CDE42484E8A,00002F589BCFCD98,3DB0B2036BBD2223,BCE5E0F07E3FE58C,02EB2DA5769073B7,9F681C9A990593E8,326259D269132E46,962077CE66E88233,CC132E8F4799C321,3EA75EDD9B95DA5B,30781B7DC9D44C40,6EC69E95D983E93A,B40ABCED0A0D0F4D,00005BA5BB6E0A06,C709E15857E7130B,A8FCA1F784ADFB7B,498DB15FC93010CE,CFDC46081B144084,BB98834EB98DA279,3D24FB891EECA63D,8B3FA9731CCE2FA6,9FF9B0670C4ECFFB,C66591B0C19B9BE5,601391AE75F98CD8,52F9576945BB271C,00000146B9184194,7CEA328C187A86A4,FCCF4135E00B6D4D,7EE72723A2AA8AE9,AD84145A5D0B45D7,FCED1CC4AB3916FD,3DC5F751AC49E640,75EB2EEA1BBF2763,C7622ED7EB0F0B92,B39EC6650CF1A631,4F088D6152C983B7,9736BFE4F96901B4,00005A2AB8247766,31E29864FEF6AE09,B33738C658256092,CD1FB04539240AEF,9E9FC7DEC40B7E7A,513D29870F078555,29B9BF0D314B5FEE,63A0CA26B35CB589,FF8E21FAC551F04C,AD253E3011119006,3253BB86B2760041,6636318C761DE6F9,0000080D36168AB8,B7DF6665FB756762,14791E5A9FC029D4,B9AD2FCDDE8CB979,5BDF720A58414FAE,9E840FCF3E98A673,5C37F31659707117,EE8F2772D331DDB3,B0D49F6DE304CFD8,E57D3BC2EA5C256A,6D8EB0DE1C9DEF90,4E52B3256EE0231C,00005315B639B44B,8AF8087B7B9BBF9F,E80F40FF91900E84,2713C5EE44D69E91,F0342D4D935A7E6E,935B9F39DDA73400,B183D3E404D1F498,C4D2DF75E55047F5,511E40C34657085F,23E2905DE6F080B3,9908A36FC658202A,B0A662490E5DD5BC,000022DF7805F61C,50FCDBB41D61CAFD,21960538F2E28330,2E0A31B78D64E0A5,52D5517BCC5D991D,46B95442D31679CA,928908D166DF33DF,C58BE85C7292D668,7550EB80B1839B51,62B6794C8E6ABD11,E10447882EB22D93,A5C3E71801F2EF31,000059EBAFEBCBF4,45B83BDB8549C57A,E8220A2C36676225,70F2F1BB4F166EC5,ADD482ABC17A9626,92931CAC859AE10B,977046635E58AEA5,040825AED6C6E1AE,634EE0204D59BC4A,16D8EDEF20E64867,6CBF85F10C902B57,002F3120DC166278,00001107729893AD,E0E32781C6C51BE3,64BF173BA96F3895,668754E495A38C8E,AFE0F6C78671C381,42453CC084A23EC0,9BC48570B291004A,F4039C988B666644,6F78555BE29C4A24,25093E7CB5C0F012,DBB87450172DE182,5A2BFB9763E423A8,0000478ABE8264F3,1D17824107473956,07B405DB346E6DB6,92465043490A6AE1,63BFF0A5C2AF9248,5E35016E5EC1DCF5,11489BD829A5EE87,2EC3E1D84FA4EBBC,9D9F39FC274EDEF0,D950C56EC87C8199,4F72C20F4827273B,E140D9EFCD0B9BCE,00006B6B14C427B6,15A8A6C348B882EC,E33C5C7F895196DE,E3BC9E74B934BD3E,7111400D25A0F603,854F5ABE66678B67,2D86F0E3499AAB72,5264EF5DADAF275F,66999D371C3356A8,9A31DF2BED8E0630,64E8D738C4F8EF55,FC318375AC2E4A0B,000009E1EBE936F8,0039CBD74059B4D8,310C545AC8011776,BE975F6AFD4A28B9,B8B827A64DC724F6,3742B1D8E112AC0E,1423BF3169A07E8B,7C90E50B7274F81B,BDE4CF8576CF5EA1,C626CFEED5519D9B,A0E5C19826A7388F,D411BD5507FDB531,00000ACF1C341FCA,94A55888DF13017B,721F150EC5751AC5,473763DEEF48A305,4152B9F51079D6CE,DA6C20EC50C8C085,B5317A12C63F099E,45AE4BDB4D8EF7E6,5FB64C76BC63DD40,EBB48DC8C71AD393,4248A9CCEEC4A864,15BD4FEB21DB9E54,000036F63F49B7EA,B1F6207E971C47AD,5F81D28F21EF3158,0E6A4375E011B775,6DF7FD6E5C4218C9,8FE192FE7396C480,9D6936641B1291B5,FBE2B22CB1B310C7,9645E14114E93C26,066E31851F0DBBC1,554D97BBDAB48C23,0D1151B20701CF2B,0000355284C4C516,C705C77CAB1FC7E7,57D3BB65F5A14BB2,267BD2EEAB7BDE6A,FF69272926E5C1B7,8B5BDFDE5F7C8E04,82B3A0C1EFE0EF05,2A75E89E323B5BEF,43CA2530AD13E2BE,CBB70932B40F6A38,B366A3D384B12B03,1D27C12772161450,000043FDEF19BC99,652BA45825923A36,1D7F6DBAE53C2A5E,39C78D91548F098C,3239E4BEC89DBAF3,C2C08F2E78430805,AD69B7E586C73343,BF8441F56E11E91E,B9F78EC11E373EE9,A6B7F819D647063F,C40B7D88A48F7AF4,A6FCE170FA534ABD,0000463B7BC5DF08,DE39595D2EE84930,60972952B011D825,19BDA50801514D18,725B11DC8B60F643,37E91D3C89CD27D8,0FDDCAC990556921,496AC27933517C71,81B5CEDB9EABE349,D6BBC91196E628B9,A67211B597D8B27F,017FC7CFBB8459F2,000051AC687ACC99,58A38B922E60BEF2,51878C142CA7A3B9,1BFB203477A6CBA5,8A2D2B7F6C531000,A14EF7F7F80A4517,B6B1030434419310,89A4E97A44A9F4FE,730CF87AF8F2535D,7F49638CECDA792C,7449F5817E31BB85,7031E0B3C65ED3E0,000003D4CD2180B6,9BCAF764BCC29D1D,82A447BE60BD0FE4,0867C63C058BA0D1,08D03EF3F3829D7F,625DC4A38C85366C,4B308C53227D56AA,E248BDE4CB898055,B81FE0D969F9E7AD,0E1247F52B14BEE8,C574DD1A81E78642,3D2F42ABC9C0C8F6,0000616FB69C4ABA,96BCD3F6EFF06C25,C689C79C41562BAA,5638474E888221C4,3293F4D8670F69A1,483429ED84D76FBC,EB457A592BB72348,4A9CA959F9B02D5F,587E0CF53A191975,687CCB717ACB451F,40C2C2282489B145,517A2A9A6B8A9B3C,0000606F24B962DD,D3DD2705EE6A03EC,755CB73A50E924FD,7FA162E23145D7EE,E1DEC53F23798ECF,EF075AB86ED250CD,15AC6F75788C7EC6,991D95CE62C570CF,9B2D24F24D1F07A2,9FC8A27CCD61F716,B46D9969D89D4AAF,2C3EA2804E29AE0D,00003ACB7F87B708,BE6E5AC2BD51D7C5,E03D79C517BD8424,A4F005BB871C4B4C,E096771860938E7F,958825F247661F14,101F232F47F4D82D,7C3B5BE17128E05B,70F15EF5EBC53CDB,E6918A03236AED8F,04946DEFE263D5AC,295D86619FC104B6,000045A2CA84537B,A533B7BE5D964C74,577C511B4E36EC15,4F647CEAD3128B26,0796018BFD842A17,94EC1F08094FA71F,D86057AAA197DA9D,D121565EB7B57F02,7B4F6AE72B1AB1B9,04F5831F2C1C7798,B56B24993E3936B0,70F0C239B5AA6271,0000277076765306,76F1ECE8AD140F73,D5EFA3CF66178923,F7D453981B4D9F96,D910D3C214C6814D,8BF9C355FD30C85E,EA111CCC96A0F27A,E54266318D2CC38E,C54E6C34E0FDAC02,EF2AEC763640E647,8D847177FAC3CE47,EBCB9FBE761DFC18,000007E2F8963694,8B6261BD0B1A9C40,D3289138F5043A0A,715D1E2BD589A262,AB19DB68F992093E,AB28B537CE035EC5,042FEAC904765619,32F97AA3ACA1AE36,EF50C1BAC09880A3,174410DE55EE3055,1BB96F5BDF8B3310,D52CACB85042CB36,000011ACA19869D3,F858CBE1E42D63CE,93B45A7A2B472B55,E34EACD1871BF5A7,5FFDCF2F2997122D,2E1AE3EF3C13767D,3027DC6ABCDFF7C1,E20BA6855D5778EF,3912F7167DB718FD,F747830A4DEA8D25,D3F1F9A61039DE80,7A1C25C4606C2EA6,000004AABA2815C5,6728DF7C40584615,07A732BA27C7B14B,A5ABB6CCF4FCF15B,A266ED35298F9708,F35B81B6D843AC6D,0281425993D7A490,A3D43F69A1223A8C,E1DB4BA473E14153,A2773175E8B196E2,2A13C30FFD284EBA,97CA4AA8F639DC76,0000635F4BC80502,F8BF32505DC93EE6,4E611494262053D4,D811A88997B1B7D7,51D84483DC4363B4,A878CE943174713C,C7D8F1FD0E0E43F8,B23AD6F8D900464F,155617322D6D9626,E446C8B49D24F388,EC349923299131FB,23528A8C08C039DE,00000C14EE712151,9610A785BA208052,9105B4BA58C33CE3,D9D0CD11C31922C9,2783292FCCFF8BBE,6E2342F781223FAD,DDD5E013B6AD7F25,E09F6B6D52DDBE27,CADE4827FAE9BCF7,C230BB237C7A247D,7D8A9FEF20ECDAB1,75297D1E480AFE6A,0000337666FC7CD3,47828996EB6B71E2,7E8603C8894FAABD,25F5D0062993FC25,14B4BA53196B0698,990DCE11DCCC9BF5,67355487AFC0D2EE,09A3FA0F2E148139,13C1A2A6AF134D5D,307C7DEDF60B4977,7AC1CAACD6602D61,0C816D3AE3D1CEAD,000056BA55BD9066,5AF06EDD41D8A041,1B7211CDC31C9DAF,461463FF719086F9,84797BADF5E9EA4A,745694398FA1BD39,317F811CCAF0F299,FB8F9D3B21A4FCF8,052696CC965C690E,1CE6006D6C4E4C9E,8CCBC0A0F6135299,F314F8F7E0D15C47,00003309DAF22D78,5F8AC58FA4C95B15,9B6D1A3D3FC8C526,A29A77629B3E648D,FC403DDE12C51180,D97A694F3FB126A4,D91B2450CC6474FC,194F2BB46EEB2B06,1C8CCE5AC8BB9FFD,CC4AA17E9A1974C8,BF92332FFBF817E6,0B1C4CCB0F20982E,000023DB6F4D952B,9AB19D1BD9C4192A,45B67B45E5B905A7,2EFFD59C48FC28DA,C9F2A864D1F2AAC6,32EE09157BA66269,9D7F85D90960D6F6,B7B53BED0D41522B,57CBDEC741B6D878,E91D8F866937A2DF,5A42550468123E14,A46612B1AEB8EB1B,0000015F61B0ADB5,E9179380D5B3B07F,9B12F076A76629FB,F59A254621A9DD1A,7BA327BDA3707DB7,6C3FDB3AF114E442,B749AC4D79B9CD67,D83A11C169AE71BB,93742888F587D915,B07A67C1ECA8F66A,9E3FD62E466406C8,E83D576012180D99,00005063AE0351D8,AFD499C52B38FFF7,C5C9F8D457DB93F3,7EEDFE61E974B186,F0ADE8727FB0FE33,8A41003365A56575,F722E300EBC38DC8,449281230E4C1959,1E2F38E0C13D7560,8A8FB08DD12FF70D,3AF90221BD7F7C3E,83E9227E39703134,00002EC1BE91EB0D,C28B3846C7D3229F,AA6DBF17C2B9C230,ECB6EE7557055400,7B8E4AAE71B422EA,18B4CB793A660C7D,B7EECAE4579D16B2,FC14E2305CAB311A,57DFFFC24566257A,1C7BE92F6DED4159,51A0DB4CE358BE57,57CA62D07A2DE3CE,00000C22D454DCB2,5FB3DA0B5DD7AD68,E8AF2CFA9D5A701A,612F80433A4D2D2C,9E7A48E14B9198AA,E2F636BE898548DE,0942E2E451833468,DDE9B2A82A540207,4EC86DB6D31EB905,576A085C3DB95F2D,3BB564E926C4F52D,05CAAE87A3BE47B4,000066C0CC9E7984,6E7F4B70D430D7AD,F8D1D45E9F4A47E9,E9B5926F15AEA322,E33E9798FC8E83CC,8FEA8155B162A9A1,06D83D71A6CEE53D,878D740F35052F65,0E1B7B6B60F4F966,DAD403361EBF1315,E75A136A3452E3C9,C67F5B803133F23A,00004D0EDA95F36F,755B75008156B11B,2DEAB14C28BD4FF8,5259F174C173747A,C24559B0C4A06F97,000A758101D84ACA,595E9062BCEF64DC,669BB10C1BBBD03A,C167906A72C82D85,DACA7E21C5889955,A6A382D75D535DF6,6801224E5F5D7366,00002D1F991E7BFF,9655D5BE2820AE9A,B50845E488B99C12,1015F19C2B667F24,71609E35882758C4,BD0AA3B799C28826,5315C6D2CE855E3F,F9BE5D1C1A582596,EDFA7AA3E85E4F79,EC9C8E81FADBA87A,D32467C260DA9227,900FC38799ED3932,000066745268000B,703A21005CD4CE97,195BC8A607626CCF,A44274E4AC0A0245,39EDDA9A244CC486,C4DE05540F7A136E,9972D19AB7398A45,4806A6C1BDF02688,DA1E1441EEE63994,E3B1267D7AB69D71,3E8416BBA2866D41,8A1A999C910B1A0D,00002028FC9E060F,5B71F384E16FE31E,59E8F4D0CC1783E3,8B7D39565C7747F6,92B562E4F4EF77A4,CF690958B87C5B5C,9A9D856DAC9E2ADE,4014BFF7B6C1C4D6,1F30964C60BA5725,6A4F90002744383B,84E8BD81DB29CB6A,E8F62923DF97E1EF,0000185C8C823B9A,3BC8918118BDAE20,EEC347655F026A04,12F5BB753EB9E14E,057B4B7040DB193B,A4AC26CDDBA4774A,944A81B16646D17A,B96F7FD4E2E957EC,B9DC1A3B3BD7B925,9FDB2D86DDD009F8,C5EB71E61274BB09,C29AD1DED21F4C60,0000095B2C224968,F06408944C1FF30C,A6E4E10680C6164D,14BEBF3539F465D3,79EAC780912A3033,DDCB3AF08798FC4D,5F2EB3650F1064AD,1B4A118D1961F590,D4359573C94BF249,BF4A86AC6FC61C5A,12BD546A7D7AF03E,85C3350D975D2941,000030D3122CAEEB,134B70319F764AEC,924D7D7052B4497E,5D3087E82A3DC9E9,FB4384B3E9AC07A3,09B5C65539C9579A,EA6B75BDE8AEF925,AE604F58495DFD61,3417852AFE4976A2,99E58BAF5970DDCC,592FD4E8A9158F8E,F2BAB0CB54AF14A8,000061B9C9D79539,2780A9893A28EBA6,FE5EF57B75D6C5CF,DBA3CAA5E10318DD,79F6DACE1EEF98C8,B505D4BB4AA12021,B5383BA8A650C6EA,82BC1A6B6958A375,5074C5143B726373,B82B6E79D3701537,FFF8396AE783A933,0669D4B0D4EC9086,000011B8C0AD8492,85F066F5A1BFA063,340141D546F386A8,394A498732552E91,CB3845E768180736,DD21A008BBAFFCB4,453D530215A956FB,EFF8E1F773274291,CC90D94A0C2BFF05,39A96E41E24481DD,9C27248D3FBD9773,5EECAE3EAF5947DD,000015CD67C90DB5,B8F2D4FB8F5BAD56,42F88A7F1F8BCF37,251D5CBE3394030D,98DE7F2AC2F1ED87,40A3BB29DFBFA3CA,51AB302F93FDA9B1,2620785BA3696F43,0FEB02D652DDA05B,B9004BD0FFFB8B5D,0F4716B9D62B0C8D,A8CAD58536A9806F,00005BE65C93C96C,4882695F0EB97778,8414D89F329344A3,CE69DEED92B604D4,631889525D345344,B4BA77C30B285E0C,4C7A13F079C6A1FC,78F47BBB70DE8AF3,0CF93D55FDA5BCE4,0542B07CCE15C0A8,D7E0A409786E0883,CBD88F0B61BB7235,000006881D8A9F8E,D14E3A73A98060AD,648BE9F1047C5BF0,EBDBA379B8DB9412,04DA05E8F654E36C,4E83814E5DA0F4C7,7C7312B7CBBF526B,DFD06238B5C59824,2D747B0EBD74990F,11022A06539C2061,D1F90BEFECCEF068,9D8A8AD0C7D55DDC,0000666545983E74,742CA1A62481853B,FFC45D05D302E51B,AF51650CC6FBE20F,7BD22E002674F7D8,AC9A0F4782EF1632,984E1260FD529130,5C0808F5813FB16B,95DC0B40E40FD972,85C8F52914854501,89EB64270962ADF3,DA71BAD07272AADC,000010496BBB005E,F7A7438978CE0666,9501FD401795E265,8613F31511D49750,C7D4E450A3783842,4A8043D61CF9D8A6,7061AAAFE015F2C5,4800C46813BFFE71,C0F3B7DA96B45B46,9E71D7E4597F386F,B4F95B4F4696CDD7,B76A3DBCF6891DC9,00003E8183CAB011,D92D9A3D4CF5B4C6,BE6002DCA097B746,40F6E608F712EDB0,8A72014C18B516B5,DEEC1FAD7879FA2E,F71FFD6F698BA88F,31A0FC88FF5D540F,81DA5EE92A29E452,4513651AF65F9E7F,814405BD047163CB,5CA14BEBFB5A6D6D,00006C4DF29892FD,72580B7C5AD7B08C,ED4BBB7B6017AD70,49D654604594227F,584F8ECB6ED41092,DD7C3C1CD254F265,5D781375BBFD783D,CB3BDB746653F25A,D46C76AFA1A81770,6FF0D79245EDFAEE,6A26FBAAFA3108E1,5DCB45658DFFC262,00005901FBC4A8EA,4ACB4420D1331E42,AB7914EBB374CFEF,22ED09398D0855CB,F0F1BD136691F83B,23D7B595B9B7B8DC,A0D133C7ED6BBFB3,B335EE2C683D6D05,0ED2326C1F84BEFE,C7F55789CDEC880B,2759B2EAE71DAF84,C97160EA31F76F97,00006B48F0917190,EB44C89BD1615D3C,81BE7F8BDC5EAD3F,95BCA60F56BC26A4,BC769EA70079C718,B62F4A6F433090C5,CB07FCCBC52ADEC6,C8C3176AE27EE995,CF61F3AF334F3EC8,C2971069D467A02F,1B06155170AE45F1,4BC9CC04AB2B31A9,00002695DFC939AD,F0D877046AF6AB56,59B67BDD02D0EAC9,B3A90877F4A9E505,3474E6A63518A6AC,12396FAC379B9A2E,DD325E9DBA528A55,F8057B113EAF9FFF,831B469DC363F90A,80B9C3F645F02CC8,C8A56DB3958BB2BB,73BA87F0D72C56C2,00006E394EA73A82,3EECE01216AE8715,C6A94F1784FA73C4,77BFF9426BAC64C4,9AE7BED25CE14A2D,0F98D72DE7E2A066,9DDA842B983AB8D9,D88BB34949FA5A0C,835DE2CAF7D11236,E88AE11C9E0EF6E7,C49BB4C9FB566953,FCB1019C4B7AFB25,000041C6B7259B4C,94BB965D4A1A4761,568521B0F8718113,CF06EBDAB7460B0D,F6556DC9E7EC637D,0310DBF67DCB9FEE,55B4CCC819F47186,AE207283C8311543,BCAD302D40D382EC,75A449C5AF222914,301BFDB6A4D29CDD,AA9562B1BD56ADBB,00005E88DD0439A0,9774BA5E69E28F0A,8A0BF8EC5B3EC662,984FA717E17E3247,F6C76CCF305BEC95,250EBBFDE610E08A,427193F63B23BE26,B0DE90F3D3639FE3,8B4EAB709611EC9E,0BCE4781FA7C2F9F,87BCFF45886DD912,CF7549B1A5EBBFB7,00003FA00D254E28,39B520CD13457CEE,785C10AD15D4072B,1FB96DB90B32EDB3,3E3AE16FD6B26BE4,995045F84D6380D9,8A925FB3C68B81DE,7836AE8E8862F9F5,01B30705CC20AA6B,055E690E38A097BE,8BE225C1F1C03459,FC550843C0A36CDF,0000026897B6B14D,1715AE36A631CFB8,A06BA303AC46BCFD,3D607B80D412B768,EBD28100DBC20C79,7E2B382938935D8F,06125832311D5864,8ED6959BE618FC61,434121C8D093EF2E,3018B8C5D8708268,E5D9DA772EDFA5FC,49780F58D7F7901A,000042008FECE4D3,9326345C4D1247CD,CB8A041F78E2BB06,406FAD67223D1795,B13FBE0D44146A90,7F64D8794119D028,5DAECF426844325B,E66E82D2617C3F1E,91C6C9DE6886AD5F,4257AF4ACB9C99E4,C47BAAF5A64F78A1,B2AF0E0842F0586B,000018CEEEF8E995,FF28C28902BD6BEE,F40C9D0A4069D364,E6B0FC57E51CC354,9812EB69D19F352E,4BC28FB08BE603CF,AB35618FF2FBC728,48C53E646E04F795,2BBB2575953FB011,BCE192EF372FC328,BD8281F26FF25BB4,579F040829ED66BD,000017D94B945BF7,0E7E8315FE15862E,E916E4A92E6A4555,60E7DDFBD589DB45,514F4744A3865CC8,31E68138EB0BFF7E,9A714A82A2E4C53C,287A3488AB51CABE,F97A3A9C4B506567,C6FB82C59C3A6ACA,2270CAAF676192EF,DF84DE6ED58A85CE,000002C450E395CD,9ECAC8A4020A01B0,2A0139036B1A4D1F,02A9CD2A5A2E1DA4,BFC59E060B128733,143158C6804BCE1B,336A676FA7FB9AF6,4AB23A87F90FB213,F8F572076E43BD74,086CB4CFDB811761,B63A944B2C28E1E8,E9629495B17608DB,00001C8C0D86BC54,E85279E7E7C4D4B3,8A13AFC76678299D,F326067DA50C8C10,137DE709BE4850A7,C53A0704609D98D9,ED685054437CADB5,07C3C0EC128C95D4,31A22DA2EC38F533,D7130F3A898AFDCD,250BFAD52FFD7DA3,E1301CE52AA243A6,000069D563484482,8059D7330777B68F,475F17AA58D71F09,6275D25B764BCE0C,B2FB9C04280A4C43,53D10CB52E6A2E0A,5A2346076A141CBD,93DF8DCDF61DE0D3,8532F52669ECFAC4,7A0336486D17117C,66BE900C6278FB4E,0AFCCBEFC7C284EF,00000AAB5D7E0FCD,2F16F8622D16672E,EEE5BBD331C51245,751A226FABDCF80A,107770F3AA882ABD,EB73B12223708B5B,ED3D4AC318FD1D33,09FCEEBA10684338,E6B74BD95DDEF2DF,001CE60C2A38890E,08FC43BAA1D94772,3BF03C696EE9BC33,000054E6F1B460C7,6322B5246669910F,57BDDB076458A555,551D9839D88A774B,C58B958BF23ADF10,97C9EC990864C435,BD5F139EFFE60E19,1F16A7D777612EA8,EE4A60BC626FE0E3,9CFEAF6D0A96AF5A,DA3D298CB6A3856E,DF3E41B45BFA1FB9,00004704F2F14B95,E8B53897B8D90C8C,701D79F480115D99,6D94DE80D174A5A9,1788C5CB0BDB265B,BE1D5BC875A32B15,73E495AF421DA74C,207CAA26AF4CA7EA,C420C73F7B8E1734,27894EC93B9019F9,9481FBBB10DA3EAC,51DFC35D3A3D56E8,00002C6359794927,CDA1970F7C93B5C8,B45AA8C1E60F6850,3255B91FE430F098,F7B826D3F04C914A,0E43221712E73A70,B1B6B5D02F6B73C2,A01C05E4434F0ADF,66B7896EEC01895A,D0FC48DD01E2C14A,F86E2727151B56A7,20D20C413C452DEC,000043892273DDB3,7D1C93121DB82F7A,239B20AEC6ABDCA9,ED4FBB7CCB603570,73B5892F3A6B24F4,D390BF0C519F44B6,74A91882CA3501F0,242AD307CF2440F0,5C83CE4A8370069A,316EEA9DAA33381E,AEEE5636F2C3136F,48EDE10ED9400F9E,00001CE988406C56,C3244204E76DC457,F4AD2B38CCA0B456,0D91FC69D8C79C64,0C07814E8DAE420E,2736C30D9F0AEE99,954BA55CA86CBDA5,A7FAE91FD19D90C8,F808A9F234E7A7A1,15EE00274D2E5E29,C5FDA94D6A8413A1,6C0A9706FD8DF6DA,000031029CF4CBFE,258276E992281E18,488FF92CD77C543A,CBC30BEDFCD405B6,58ECCF6A94635C53,80D842A436DC1412,9CDC2C37F70118D1,E92469F449C5D049,96BA570FF6040558,E693CAEFD54BD6EA,9E3607C6D81708A3,D5C38178BFD7EAB4,000052C97E6D027A,9B58553B8E259E4A,5EEB7658D1D406FC,1DCF9F45C9CEE7B1,CC35346009789921,8D0A130EF48F0B18,A28ABFA70A24A2F9,D906404D72E01F94,09F2D3EFD18D9FEF,1B2B1341DEE25B34,6BB5A33162EC20ED,C0F8CBBF275456C6,00006E027459A60A,9C8E0F208F1382CD,21F404A76639ADE3,50429A5C75F2D424,55CD618F2BA96424,A514614F67679248,C35BB0F46B83634E,FCE199DED61CAA7F,E5A95D952D37DE42,5273C4471CA7DD97,4191DDE3B4C2DA89,D89DD1948A3A702F,00003B148A13399F,C4265FDEC7EA7295,DDEF32F75DFF12C2,AA70AD288DD7E304,9FBA8AAF0F07A77B,3CBA412A2B0D3769,D3153117BDB3E8BC,02DC9006564DA1F1,666E399982067DDA,F0C1E7A804A2EE63,7B4CA158E416657F,A7FC49B473912C3C,000048862B2E6EE5,CBBB3790A6B98393,18784DBD70A032C2,D5D7F3D682AAB4B7,1AF00BDC0A9E803F,8047A9C7CD82FA97,CC89242A6E2C1F6F,F64C1ACF260F2AA9,BECD5B0AD0803707,2AB9C68A88704468,56C92D3EDCC8A2ED,246BA18968EEEA4D,00004BF0CB19D87C,36ED57E9F141FB0B,1FB286EE5293ACC0,FA887C19620845FC,FE94E4437499307B,9402DCBA23C9A816,6BB4DF7398205A3F,A7EB505089E21B45,B75A28B4BF069AA4,4AC56B55EF9B5DAC,C58F343D5202D876,0626F8475CC02904,00003F0575C47254,B51205418765C853,E653BAF7D1E9E374,62233F3F8238853A,BCC3A0DE18914766,B0838D6CD637B52E,3C9517B6063A13C2,B3008E4C7C023208,FC8FE22C4CED981C,2AA1E3E380EF692F,2CA1909D19DAA407,AE6D6C547BF30B45,000024C53B1C7B46,CC92DFD30310FC5C,1E59452CD0FD7967,8615BC042AD19574,3E4AA2B1F3CD2E61,5E7F478990071430,8B5AC09BED81A6DE,53EE034304385C35,A221EEB56C00B32B,17E1465E5524CB54,B0C54EAC0C3D918B,0BAFA4A4CB24CA93,000043E99D554C44,E3DA774EED994B17,BA5AAB35B13065FB,3F557E5820D4CCE6,08CDFC36D504F874,42599A3DBFA369CF,C851F50650891DBA,888B8ADDCC99B281,C0C4C91F3B2711D8,47C42B22AD319CA5,CD46F46F8AB40163,69B730E40AFA04A6,000032781F90C521,269839DC7D93339C,FA1C91AE87C2435C,4C862967F7D03502,56B1B06DE05DB173,81A6730FF9523F38,F68613712AAC3A7E,9DA2445F5DC75F83,305B776454CED789,0C9A59E62729B28C,A1DC08D46FE825A7,FC3B141BC08F3EEF,0000459322CACD08,9A80FBDEE1EDAC24,B45AA93E2A043EF3,6E30F7F0B725F8CA,44EDD7DBF72E0EE6,8161FFE513294B74,D5A947990CA55A9A,A65A766F80E7B4D7,BD68031C3A31B8D9,F024D7A91B2C7DBA,E4AF88B3EECCE137,384F66EECD7C24D9,00001347B2F2EEFA,FF5A5D8EFB466972,FCD94A2A8484DAF2,75F81C3D5484D73B,002871C716D4FAF1,76E3FD0F6569BF71,DC4B5408676B0033,4E6D66DB7705BECA,5654202244F0B233,E4FDD7F0888A9418,4BA265D5ACE68994,FCB2C85EC38ED3ED,0000598BA80FF7C5,B9BF5184EF1B9F94,22EBFBD8FDF1A9F2,E7934E02ECFBA458,2A03F61D66E91A8C,6BB87DC78759C52D,836D0167E1DBF9F9,6E7269124DD47E31,05DF65A7B164919F,C1513501485FE095,365E7E4927F242B0,FB0D7F05EC923D43,00000E68D78A5D84,4E48FA67BAD6797E,4F2511F99D192D00,C33C4C674347D903,773AC52C6E9B9945,B6CF76A4D654D419,3FB2468282EEC017,E26EA5A52967A6B3,5C7035783632CFFD,B819D06E082B21A9,31EA081C9E7BE7DD,08865831EBE09EE2,00000315C91281D3,D3CD9B8C58F4774C,DEE408FD5A80733E,11D973487C56C4DB,8504F2E4D4516F32,DC785066DECD7F89,CB020FF7DFC9499F,D7BB540363647364,C603DF335219EC8A,F11AA731BEFCEA6E,17F149E4019400F8,0E9C6D62556449B4,00004D204BA3DF7E,D472769014091830,0D41AC2061655B4F,7E45CB998F4B73B7,170F9CF640250522,F5CDF79F2860E092,E83FC6069802D8B7,E17ADC493227123C,2DCE5E41F36D94CC,768E72D79C95AEA6,BF811A1741E360B8,263B4D6BD9526471,000022479AE9D0E1,773E4AE01A3D6079,D24C1EE2AB0C3EC5,CE1EDD6DAB1716CB,FF65A0BA987F0C08,C893E261E14274B6,EEF9AA4B3AAA6801,9CC81BE4E25C63A9,E8067A16709237F8,FC7F2BF552D48039,389F26AFAC96A823,301C461895ACA579,00001606FB8855AD,C365BC156BBBEF88,531E9A84D0D19741,1EE4FEFAA37A6C7B,6886248488EE8CC9,23EC7C42CF2522AC,943CC3FE2ECB7ED1,B4D2C3D6719D923B,0536CB7DF51117F8,9375457064FB00C6,0590C9D0F196E207,8D989808C50A680E,00005047595073A8,677CBEC5FF2E56A1,A47189147221959A,C9B361AED8C7191B,298A0B2FFE2B02D1,DF3E7E1184CE0EBD,613E736A900EB26A,C6325014BA9678A0,0054D4ABC2860BFC,78F8C0160881AD3F,A0237E6AE9119549,35E4D8EB393174F4,00002BD941FBCD23,AB0F6AF5E3072B27,6C4D341B3AD9F059,3B8964BCF7031996,1FCAE0ED2F55AB64,2EC0AA15F8957DE0,D27FC87BD878CEF6,19BE6F649BD7FC23,BBAAB49AB84FF412,4822E515B6A0DAB8,3177010AAE4467C8,7243076180471CBE,000019931D5E1A97,98E44ACA398D8AC8,2BA03736CC15D2AE,6BCEBCD61F9031F0,2502CB8D47C751C7,BD7424E197C54E55,A58521527001B36C,74D928818FDA6A13,36E5041EE1D4CA56,6029040493AE6153,40CF2D999D431DF8,B15EA92CF81D584F,000053B0B79FA57F,5690A408C9903390,4029935BE6AEA3A3,0CC9A4DBCF9025BB,8EAA5784EE65F438,D7D351CB3303645D,99D159A27654A560,09A53A86A9A6981A,53B2A90975CF80E0,D665B18FCCC0E62D,B47B432DAB99B6BB,A075DA867EB386FD,00004DEE71AE2875,7E11272AC5A05E95,5AE2F1EBEA3F2E65,7977BDDAB0BE4A2B,42BBF6D55C9368C6,5D1CD1B14846FD64,69C325C23562DA0C,3DF2979B23301114,EEED6B8F1836242C,3F18FE7315264456,61A8F1ED2E72A366,ECC9086101FB6727,000067CCD65D0034,3870C380676913A5,D404C3C66E0FE68C,9F6EE6756582409C,7FB54C25857A6D8C,865094E476BA4E1F,AC4813B343D98483,BA969E28AF64A46E,FFA8DAAEBDC420DB,966E00E6D48F337C,391AE78393C21ECD,3A6AFF3EDEB1B541,00004D62D056AF64,D562BDDB554F4CE9,B5981AE615B2950C,58FE16C54F2BD10D,6F45BB7E84050734,5AAC33B9EB303876,5534F07AC8B46974,08C96DA0BBBE66E0,C026B11F0BB523D5,1FBAE0DCBA14D01D,3DCEBEA033BF8544,56EF0CC2C40ADF6A,000012D141D7655B,13A4D89DB1086EB7,466F5D597A1F3374,5CA6C4B39F108272,0F2CE11C0369F6FE,16463F4807B2CCDA,F0B31AAB7C983D9A,1E66B98FA5D0EF23,B7B287FD808D5DA2,B14DB0427A0CD2BC,678B48A9721D6182,260BB94302CF6A70,00000277F48FFBA2,07A22DE40481BB4C,8F0447288780D514,D6E57754C068E65C,C423E33AF744A63D,C7DFEB025AB5D58D,F96A370CA6D28938,3DB82C5AFA6D416D,26518C2FB41CCB4E,2380501D858DCE73,F5B6C06DBCB998C5,F1334D5CB9083D9B,000012A019D0274A,013F44C9ED8E1192,6998943067435A27,CED813C5675AA503,4B5F1D4837A01E51,4D3CB92C9EBF47BB,0449BF355EF1AFC1,D2150CC0F4DD964A,E60D1E4A62B6CAC4,DA5AED64602656CD,BFF66B6943A49D8D,511B038F7C6F435D,00004C75EA760D6C,D9E3349A2F8F41BD,9F3B8FC47F111169,2088E6FAD9962C70,DFEBF4D08BE94921,AA58D08D032EBBB9,BEC7CFFAF18907E2,1F4F2FB860B38B25,6FB8D04A267B5C97,9CCDF4077724E3D7,EB7DD4F44E68D538,E48C2051F27AFDE0,00004E10DD7C878D,B004E0FC1624A6A0,38D72F64C2DC3D11,FCEDD06914B733E2,1C9E25A5F5A9AC24,9F61E7CE10329D82,5716ECB1AB1FFCD9,746A8F3415CF3F14,465749EF2A383FF2,4769251EFD6E0269,46A6DE19D4A3444D,56D225FFFCABC14C,000061C80B9A4AD5,E66C0E6B7B89F281,19A0AE81000CB776,0DA97BC66E53B47F,197D5BEB55BDE555,D39F45F6DFFD314E,908C9E47612CDB9D,241CC868793391DE,D50DA995C66B610D,EBE0C885C8907BC6,28151CEB94F14477,CB496B25228C6917,0000177CCC66E33B,143F194FA9699D0A,DEF11F9016A32572,E6F5A096617C2B49,1EF4C6F72A5DC419,FFD505B781A16373,97301086FA270021,AE10714D0F7E63C9,C56EC54611756C80,933099264A5CBC1C,E30E23C90BC2709C,4A7B9D3D6D052F22,00002443ED6B6D2F,833B1B3291D23899,A2FE8A3C2D68674C,FCF0CD7A147C40C5,074715A76E47AEFE,B67220B1F760A1A6,64547F4BF8B63556,00E42BA88867EFBC,EDC0254D9DA0B807,45D35D9BA9F1EA7B,2CD976C4DAF784AC,50422715D9144C34,000028F063CE061F,D6A4CE80F5A850DE,5A6A0C6045F0BBE7,36B98A220D8C91FD,4D86F7E3B167192F,2F849E91EDB7F95C,215655F1A8EEF1D9,369FC8D289DEDB75,C52327D6EB3E0DE2,C8CB8753E531656A,DDF67B0BDC9BDF99,E38DB166EEC7C3A7,000040D4F7615399,81F51BD453C85FBE,33613AA35DD80BEA,D1D8185CBD598010,8E77BEA3824FBD9F,D0A8560CA42AB35D,E109B24E684DD7AB,23D2089C11138BE2,E48A54D6AF682C63,23C63F704E484DE5,A0ED3B865A029BE7,499D8A9C41F5D335,00000DBDD22E5D0A,084D554C89AEA7CC,34E1121DFB5DE760,DDED97E23CF5F930,02D4E78986820728,45297D089FAFB41C,84766D900B49D574,AE10AE45B882BDE9,F2A8B789810DB817,81D6758231628299,99EB761EE746AE7D,F7EE63B092E31239,0000512F485645B2,E4A31A33370E6A76,E118F02356C6C4B7,F56189EDFD865680,DF8EB7C4281C3D04,93A31048AC4D51BC,9A6923E98A2076CF,DF0D8A31811A5F95,6855B8245330BE07,6C9C54E22FE207D1,F21B1BECCB8CC775,629E8436CBF360B2,0000145373896829,5610CCD632CFF129,00C6D8BD1F7BAB6A,6B1B1C837C8AE5C1,E046450A5EAA94CC,68CABCEB445D5B3D,AE31BE0D43783C6C,C0B4C3DB2DBC2BF9,87FA693FF745EB0B,EE7EFAB062BD8DC5,648C2C29C91EBD3E,48EEFD1ADCAB23DC,000011BB72BD9CAF,ADB280319F85DAEE,741C6FF724DC98B5,B73064117F5296C8,9D763CEE379327AA,26996C7D678A389E,5743665A3382BFD0,9269B2549C4067CF,B915095B1CC30D46,1F1049E374D0E2C1,DDFEC955D043FC5A,14BBC6A4F59A350D,00001EE2AF9AC72C,AA3E580DAF3A5F53,A7B80D9551389387,E65EB938E7C2DE41,9C7DCF67417F70FE,8BB254A31A8749BA,1EE04DB97A036A16,C6E60FF6E34416C6,E509EA6E662DAC62,AC33B8DDC0221973,02872D2CD69CBB99,546321AF7CDD20E7,0000329E660443D5,7E975610B7402868,B8F1906A1890003B,87E563B471731691,20FC77DD0E43A9D7,D776FC48A0C9792E,0351C9C5441838B8,D163C62E188AFCCD,A7A8E4897740528D,E61D17D364C104D1,2774128158B3E669,91D9759057C4E0EA,00002AB33A7CAF75,083DAECF3A1A02BB,1DFA78E277B7249C,31EC7912AEEDA49C,C52A1CEC0FE51354,BBB26B6B49B6CE55,CD98A643E3311C22,0DB4F10C37D564B5,F1B65296337558BC,11D510A5BA347408,955924365C4FAC81,79002D5A68A8927A,00000010820C5922,9D73623B7765856A,688718C428973541,E5142F70349888C9,AF8C5EBE3BD96285,E1C67A6C2716CB80,2BEC639259622C4F,EAB415EE260F6E31,0D8AA3B46C5C39E6,884DB089B8D7355C,256828668C97CBC1,060466DA0092C995,00002FCD835A8ED8,25E8629FC44645A1,29347D0514386506,C5BC58161596AD1A,94215F9FE02D6B7D,732D6961B9EF3BCC,80FED19FE3AC53A1,FC2C1D1D0D97AA0D,3B87B78E7A695D6B,C3D8020584CB23B5,919D4A17D11B05BA,4D7CBBEEC500FC30,00005DFCB6B63AFD,513ECE5459E4C2B4,611DF54F8515B69F,814AA9970EDA7B9E,90F3C9FB46CF6A4C,6EE6172E625AF935,BA36109C78BE3191,F1CC508A61B18E21,84BB4C70D570D0D3,E3459F0A0E9CBD5B,950F695B56B0D49E,46F56931F4143053,00000C223A76F99C,112487C0D235EF1D,238AEEFE08455564,93E69ABF14DF349E,90DE98DAB7BB77D5,CC986377F66DDA45,649EC65324CDD0DA,4B1A7F874C6F189F,D77031978C7A8DC0,5CF057E6E5E4DFED,E0EB4000B35329E7,3970EEF8B94E063B,000011738CD90125,A448CBF7E255F6B6,E29FC7AC90A7B5BB,17A30103B8C26A88,872A52CBAB946FBE,BD7DD4C3DCB140B6,67482432E84AFFB6,1F5AD8576E9DF49B,06FCA807B05E7153,B2B1F655A3A450F4,5AF1F735AFDE3059,EBB053B3679739AF,00004DC465DE6792,9D8E87D0EF2588F9,A2D0D50AA6C4DB1A,9533E770B5704B55,545D8722BE8B473C,652350AB8B5C8465,99FE7F0D420694CC,CD1A532CD0523779,F663E3602F40DAE1,D3B650EAD0B88161,044A93B1BC9FFF73,67504C066A73F822,0000224D58711791,7FD64035DE36B2AA,393646CC65FC1E45,A74468EC1FABF8CA,16D05FD424BD73C4,7BFBB3729EF3D6F2,8E13B579206B2293,7D14EF99C01146B4,969805B8BC7BA6B4,5FE314421C3D8069,D063F03D32321A4A,28E1A2AB1D636FEC,0000576D8D669932,84F1CA74E730A08B,011CE2352CDB3A3A,208A1B6CCA597077,6D2C0E38F1423EF8,D9354BABB73892C7,1B3E1523E9A0E39F,FD52D40269A063E6,AB86E2B510442C5A,E1F75F78F09EB244,6295BCBC56C1EEC4,7B71E0C0EE987CA0,000030854E74A37D,22AAB0C35608EE34,7EE7F740FAFD0ACB,A89C917F39528284,BF89076994C4FB46,F614A946C3DCD1E7,B993D0F2CAA8B17C,DFF9CD9B15DF5C09,8ABE54750CBA0F71,8928988CC9207AED,02F529450322BC94,402060EEBC1212B7,0000088689EF4C93,B40C843244F35885,541B40A7542062D3,C78F6CD8408DEAE9,FAA8A2833BA29B36,55EEFDBB5AFCA21B,66798FEC1B485157,018302B4E18EAA9E,3331D1BBAAAE32C1,C433574AD41AFFA3,DD4969D768C77830,D95B1C59898DF4CF,000009E5B2BCA110,B839E875F671133C,D6635663254421A4,12171BD4D8F80ED6,6B88F1056D7BE3AF,C7531CC8B5C3E82D,DA38C4E103D9DE98,EB8205FDF66F9499,8DCCA6F1203BAF4A,9866F55CA08B610A,87F1B54C2B3468A2,0178A32B3A77DC27,000060B9379CF849,372FD1CC333596C9,701AB79F6F5A8743,8A2F1DB035E2D6FD,15508BC6E9703534,3F2DAE7AFFAF5898,200FB7123BF36732,8924DED99CAD543F,CD428381A4102462,088B8DD9A5613DEC,32BF08AEA2E7CF92,1B5D3D0312C210B6,0000059A0B3A46E9,8F5F4E6DD25DFE8D,750366EF1A3C3335,67A176B3E0FD3FDE,67BB8DB6A49A38DA,CF740FBABB9C3257,70DC85CFF4C22E0C,E9CBDF7D297F20A1,65D6ED9B50C60E9C,6DE55BDF6A24F8DE,5F3017BFDF0ACB19,AFB2B82700E58D2A,00005099D98E3417,4CB86D520F369A5F,28EFE7D6E4E90DD5,E500065F44822F1C,522A5C133079ED58,898813A894DD682A,D32EC17871E8D0EC,85DC9E8FE499AB2A,5F012654F35DF1F2,F6DAB64221C227DC,B9F0B7DAA46FBD57,AFB3A32F0200DAC8,00004ED4A8818F74,E66CD8FD0FC88BC7,FAA13BDDE6357FF2,27F8DC8EE5801105,7EAF2688D7F939CA,BB69EA13BE3CFA93,DEC9069A22431DD9,17EE5BCC3EFBB6BF,0B52E37A87BAF1EB,896F1AFDDC17C49A,633AC3D43F9C55A9,B9467EA29F7CFAD8,000011446349954B,24780C278F1F9C38,4E1C92D16AEF6A27,00625E6381114169,A4021A78B24FE863,072147C78AD0C8E0,AE7A8A160892618D,0159BC4D341AA3CC,8F3F48957C301E90,1773DC6CA3DBD273,4C0F58CF4125F082,D67A091D15B4E85D,00001F22AFF973DE,6D59483AE520DF02,D2178B1F2D25145D,4AAE39B4E2E40CAE,EE04EAC125FB2F71,E5546BE8974650B0,A635C4B7F898D90C,5C367E0E425F0CF0,55428C31A90C9C25,5FEBD1A383343130,3A27CD2F568013D5,93FE208DD2B268F5,00003753D2A11A6E,AAB6E74C445DF02E,5954CCAE40F69A9D,E3BE90C1522F47BA,D8E298BE7D78F4FC,545794C87F9AE258,27A2155962C14A17,992FB081D9B625CD,2826704CD71A9240,6F102E26473CBADB,2B308DD6BEB12BB8,CC507E301C0F2E5D,000023AD661B4B07,72AB257D9268F87F,7F8C79967E243E2B,A7285AF5898008DB,ACDF7A5EC7E12705,329C47A0B7EA6D94,D69A228741A27B7B,B964A81FB03530A9,343338130F7FBA46,3C068CD16F7A2966,E1E0D0C2043A49C9,CDF8AA068F8E9640,00006FADEF4EADA3,B18CBBC3F539040D,6D199A1196A420D2,DDF46087BA6CF214,13DB7A990595608F,E51F437D71CF4AD4,AC7C861A3279D0F7,273A02AB610118F2,869E8648244BC8FC,D9156DBBF56D3A50,04374709692253A7,FF257092741BD036,00005E417B3542F0,E7681D9D9F4D4686,C96F3E692E3C1C07,BE69C6641638580E,2E641301DA617728,A3AA48BC2BB3C570,765A71A709CFD86A,22313A6DBA9E18CB,EA9E9CF57F6D8B9A,D37BBD61E9D30E3E,24E5FDDC2C5EFF72,4FBCB633AE3675D1,00003BE8C45CBE23,41F4B4474365B778,74E99893EF8D1AFC,FEC122AB170420DA,6710C3FFAF73C50A,81E866484FA11B36,EE3E2B34D54A9377,DDB53756A3DF8636,847E993F75216488,6761CC80C4225CA9,7704662331100528,B8A8B73D03663B64,0000369CF9ABDA91,2B7E41CB14A07387,AABA08F99D0A5445,6681002E6F613ABD,083EC55374707264,DA72D6CC985F7683,E1952C2FEF094B32,A1ED43CCDD00CFDC,318DE46F6090EA6D,909F3DC4B704FA92,9A63D715A3F5365D,ACD5029AA2CEC09B,00001425F1DE536B,CE12A42F50921810,E987A76C37006FD1,2282B388895DCFF9,F26D12CA7E51BBF4,215CBE1D706D47BE,EBCC69C2C7AB565B,CEEEF3FBCB8CC4EF,70E00CC0739E2C1B,E7418425230874B8,B5E83CBC93ADB926,0DE72C5810C71568,00006BF72E316A3D,426775E9B6C8177C,750D2B8825FDC483,658155D19E7F42B2,AC807067D94EA0A6,932507AEAAD4728C,0B481341955F70F3,DB6C83D93A95B850,F2197E9A028C19EB,9C59992109B5E3C4,50FBE08285FB453F,AD46A1AA340747F3,000008371459D6E1,89600C52C0F2DC5C,1874270C9FE3FD12,464CAE23311DB974,332D91802E2D670B,78C875D486F24E05,2368D657A5D4CC91,7797BDB2CC19F8CD,7590E4964E946323,96C61E5CBB9A9049,5E7E944F7869659F,8D5F2D006B08C813,00004B4ED03C79BE,08884281FE01A31E,16B6788F31E16480,3AE2374DFF89F546,55757D71841B6947,7A577CD097D25B3A,7F3DDDD9BB04E601,4D28A620CE4F7151,0C599BAA4B96FEA9,9A5363AC32E8B051,C48C8CA36394F0A3,3355240EC5B0ECB1,0000433582C5A563,EB139D9F29169057,446EF2165E079BAC,A59145FB78B0011F,01B7EFA3E1B4D76A,944053D3C41FEA1E,46BFA00CC2AEE417,A6E06138774206D6,8022956C212BC2E9,B73E9116ED84AE70,0CAC0C7CCA4B2AEA,1ED39EC7AC069ECE,00001C1C50B5A65B,DFEEF105E35F72C3,A8CABDC7B8C24D41,175659FD7812D118,0786B1179690B980,AD7133475E14A1F5,3F3D917684207593,CB08EE72D9C5F8AB,BDD0AD1E7872CC43,26336F46C0E20521,E81848CF83EB36AE,FEC1FE298A544807,000050FF7D8082B7,BBF68EE7A499B266,70F1C604CC691031,70D28033AF93624F,17E8F6C8B514E620,2D8D12ABD5A097F1,00AB01F9F9AD1BB5,DB642884DE0283FE,854346EF1635E2ED,23242E3AF8D3A4FC,6C511F9CF4A73E28,250CEA992B6F34DD,00003A1D9B93F7FC,5B084CEC5962394C,B5B8877BE2F67767,6E92358C85DB9B47,F8DAB16B6E433198,1904DEEEE18B572D,0502D129EF3BEFF7,78F3DA1EA535CB99,ED0A0EF21545AB93,481AF8A89E012188,23E15454A294C70E,81983DC40C0686AB,00006250761D4744,C29E7C3D661D92E0,96FE7F52B43E862C,E81E5EE2999D1D7D,BF953E62F20583D7,9AEDAA420D3C2B58,8788FBD03943B3E2,E323E3F6F9FBAF8F,B796E3A14BBA54FD,4C7D8BDF50638EB5,9A01D593BEADB278,584637B5558446CF,0000210669DEFD4F,B589907676994247,6183F76044952383,51729AEBAC528899,0944AF7CF68AF8D7,FFBA183FE2A518FD,A4629444969D7143,752111A116DEDEB3,74F10CEB0ACA8CD2,7E134FB045A604E1,30B85CF993C5BEA8,80ECB898B33D2083,000050ADEC28A056,BCE39CEF8894C649,4AD3CB5264F4B9DB,6694D18E4835EC23,77B0E5FF94FAA0F4,9D2472F4634581C6,9091A21F6194E8FF,36F9AF912A688AFF,54F7095E912DC214,6A9E6F34A27A19F1,D040DC2B0FB4F5FF,A594B166D1E5735D,000054EF5B626C01,059BF716E7203184,BFA2F1407C684731,C511410FD47EB374,EC4580288BF8CD65,6A52AA3F2C249A7A,6567A602B394B8DD,AEDE880D0D6BB005,75DAC82F6F23ADAA,5B93B62707EAB9C5,CDFBA7AF4493BF71,4C4E090E180AB533,00006124B0F1AB65,FD41830E7420CF75,6D9CCDE27B66B990,81BA7CA1B3D7B765,977C56F2BABB4962,55E0BFD04612531B,0B5EE75CDD0F9BA6,24B9F98EB783AF80,18EE6FAA3F283B93,7E014C378F12200D,FE83228A11F788C4,BB7BB00BF56C59C1,000012C616C4BB6E,C97003FD9A4B230E,50470B64FC8882E9,859451657C1A1B3B,34EB72E9C48216F9,F1B7E95915A12CFF,BBB1FAFDAC310547,35DC1D9EC8647746,119B76981A099E95,F4D436CF93D1220A,D47A44C9BCA2E43B,E8D448B045151C80,000059DD1809F0F0,C65907AE4C8A369B,28B7FA352BE4417E,8CCBC4A59A3FFBF7,25E259250ED51857,30BCB63BD9E3E7BC,82E908E29F2644B6,35FD842D8791400A,9F6C166056C1772E,D1FF0CBC2F0C2F62,A1A90A3488EBD59B,C9AC7D69FE1E24FA,0000180787A34AEF,873CB2905BBB316B,0B3CC1F9E0969659,510880F70316E0BF,6A38FF7A06A880A6,FCCDEE32DBE98CF9,E9266714A47C6D4F,CBDE82D77B5DFD2D,62E7852CE8D82B26,22DAE6C2B2C433F5,3ED978676D87BC8C,562254043574B3BC,00001C6F7B63D6A1,47953D3041650241,E5C40D80C829C76D,2CA328F19573D10F,94D1D942DB6255B7,244F30C926915BB5,1A3D50DD633EB64D,B5F92B85BAACCB1D,AEE10A5BB2A70F93,5030214C60F21CBE,A1D85F5CA3EF6BE6,C9F4CC0113AC1D5D,00000B7A499F3C1D,B2E7176C022FA08E,8A0B2564800A176C,BD1F46BF7F4FB104,BC53CFF8DBF19875,7E112735A11D885B,277FF3A8268FABD4,D93CC2BCCFB0060C,5570AE12559E9B96,EE2E9DB96901439D,1B811D9CB821BFC3,68516FF05A925D7D,00000892DB52E3E7,2B483E20E0D8D4BC,36591B9296408D8E,EAFC438436B1CEA9,DAA8928E2C285024,397F2580F3D0C377,A7F55DDDC6BCC8E1,337E8EB8FB1152EF,7C7A04F41A16CD76,F30BE8F6DF8818EA,9BCD2038AC456545,9044D1B71463F76B,00003FB901E81FF4,A34C489107939972,93872F1C94B7A5CE,4FEFF424BB0EDAB3,CA6362E274152C7D,B563A3F7EFB44A66,F268B8C03BB15EDD,A6451BBD93FC4E31,F0AC305E4F12693B,0057BD7A83686DDE,B72E7D495789FCAE,2933388CCECD7659,00002279740BE432,303E33E76C8F536F,C9CA480FD972B562,EEE44AA5715E7C38,4E63A2F77D55406F,70A6D72024F9EAF5,D95AEE1AC1E990A9,A0533E56CA68DA59,0758DB62701C4C9C,2033FE6D811A3F9A,39DC585F2E5745A5,E91694C4611C32F3,0000374E24E0B5C8,20572D6D7E94FCA1,FDE51F0E73FD17C6,03248CE69DC29224,278B7A51CEB70700,C4CF85E7DFA28A54,A34F181C9ECBEB90,E4075960168F8050,863C9D5239198921,461292220A7398E3,3670CAE350C071ED,8793FAA033A17715,0000187BBCC0E266,AE879A094EDDB919,A79E0AC1646924DC,AF49BC9BDEF05D7C,C71036A7ED9F7A17,1203ABE70CB912BC,6B07477EDD66EDF7,3174A6CE307E278C,B5C0A1C621C46CC4,61580AFA24F9617D,F2926789B2A34898,E45DF6ACD43E7413,000064C8B3781194,2B37E86E5855984D,9693CD1BA8B2CEA6,1A481AFBF41598D6,574166AB2D070CA5,7AD487BA831B8BD1,58180AFF7903C11F,CB20E46128FA939A,F500EDEFC6646922,25C7C110A7F29A96,F178F4DBD41EE803,0159EFA7EA8700CC,00004542C9D630AE,C8AED865505AD549,F0B0A799A375BF88,804E71DC8F4C6D72,AE0385A35506F07B,F3841621178F2380,67695C1DB0428D9C,E93FA1CAA015EF08,52F489F36CAE51A7,6643E907CA452D52,89EE8BEEB480B1F9,CE2D7FC4242B46DD,0000528AAB0060D9,CC605D6F8E7B5185,C0310722AE822844,2D9A7F5BBE62AF5D,E224573493D70B0B,AE988ED7A9B79E53,B2DF406DC4430E0D,955887D49F2FD9E1,931EF81790637527,174CC87269E44164,8B8CF3AEB7E0A58F,26310124B07B36B9,000034A22A1E9BA7,11266667981B0AD9,CFFEDDB5C3E7CEA2,6847E0E6A25E0C1A,0CB7794EDFB071E7,8F9F303249C10D3B,9E9F6DC89AF0C715,2AAAB3A5D6CFF0E4,6948A3F5EADB67B3,5ACFD9CD7CC7E187,1E08A3BE18132A51,9DC2000A052B2702,000004F73C3DC504,9F6093605151D66C,C8B566BBAD286AED,B6A2212162DDEF90,C9F2A62A9DE797B0,70F5D94D137310EB,111E0F61FE5CA5A8,A2B8C93CD24EE669,4CB4CE7416F2152D,FE8EC34E2EF067A4,18B06333D35653B9,005F1B2DC89B5C92,000042C09D8E3065,13BEA01635FB6DC1,86EA3F0DAE41BFFF,9043EFF0551F4195,79F8246CA36FDD4D,5006CB938629979D,155C43F98870ECB8,3B1C318CF0E1DB23,1C8BDEEB76FD5FAE,32283EE7B6397E05,85079A10B8F9B1B9,CB4990EAE128BF2B,00001F47AEF677BC,0A026F0F8DD0869A,A6D994CE5D11014B,2C36FD2C146D52BE,062B2608039C1037,4AF0C2CB4E30C422,B9E13D02AA899873,12AE6159BBEF621A,E41A42D5B5F476F5,F96577C1428CB1D1,EE61C2821727C8FC,825024D349C626AC,000048D78B0780C5,282989D0CFF892B6,FC6A60D3849F341E,60E7124AFCDEB85B,25F1F16262488D25,146DB29D3368E749,685D4A4094CA38CD,1C158052B7BA9D0E,8F5282E856FA04CE,2BD4C755FD32D1D7,823CB694F7905C73,7D3A49C0964EFA7A,00004B090623F16A,D199EE947977285D,1AD7AB3D5C89EAC0,7AF3F3B9BE19A56E,DEAEE5BC4F81F644,244D1A5D3B3A34DE,364BC714BB7E38AE,069115AD1CED1D5D,A816B9CB555AC789,D09282D7A5379FFB,A4064B8285309B3F,6B5BC81ACCDACB73,00000FBD79386916,D5B69FA9A95AB355,F949CF9FA89D1562,1589D6A578B7DF3A,459DA6D456036699,C54B9BB753FCA4B2,042673A7FC1C12FC,0A1E9FE67B900C61,B027F066BD830DAE,5F7DEFB6702BFCBC,6ED5169C8AB9273A,E0CFC3DBBF8A941B,000049A46316DB1B,7E4E5D4309AA6AA1,5258CCBFB70C330C,05536521827A2205,8D080D5F4D4E28B9,5028CAD37433DF54,91DF079DC2B3E163,6C77CA77ABC0E608,D6A59278824813AB,32D379BAED981E66,4D9696EE03E228B2,BAC647767ECE43FD,000034FF4477BB71,7575807E97153F8D,CFE64AF03B532375,469F6E7D0C90F15C,57329722AFEA3E9D,2A787E2B9B9A617F,D556BAE63461A0AB,B180ABF1F30656DB,BD01EF02D8A3128C,DD50C10834A86A6D,E405C7DF8DC6AF5A,FBD743243326544D,000065D8EA969DA2,9174B39D3732DDD7,BF2AF13AF6D1F76B,252624A03EB9B06F,3B5B426880B735AB,D7EB70EDA7044446,B60828323AAD4C71,BEAFE823FBB291EF,3BD957192A80AE5D,F9FCD005D74CDF1C,88668BB548E5B28D,937D094A4E0F4B70,00001739D7C63084,8F98B32FDDAFC045,059F27A8236DED19,AB33122E8DF61D5A,445BC05CC2487BD7,8ED2C90C7CEA9DFE,A3B4B8C58CD02043,507F7EBE1CBD400D,6E12A6FB33E0195C,F4ACE17D71E26053,559A5923F77E4CE1,7B2106CB9FDB3032,0000337527C4084E,6F3C870A2BA24B73,20796616F8AA191C,BEE8F32D7BB86896,BA0AF4CEE782B258,523832FCE291CDE7,A65BC078331AB311,BA7E22787B379C9B,F289457F424D566C,C18A3C10985DBF20,2CE59673E5F46570,E3FAEDEFEF30089F,0000162893945BD6,4C137C5B44D1E0CF,846ACA786F5C8BB4,28DF691FAEC69A7E,F9F482ADC27ABBCE,801BBAECE4E1BF19,3B5F8D005F45FF7D,5A35707E5C5CAA67,9D30CD8683C08D13,D7999DAE3D35ACD6,BCB869816622D89B,46933F44F3978629,00004212186DFB34,FA6A886B21F2A64C,4EF2D0ED06E6F6BE,093196AF3DB0EA6C,EAE3D7E40360704C,E49CC92BAD5358A3,5109D2D1BC770B36,CE68D991B3244295,D738C4F914263656,DDE2249FD085CA8F,FD4AA6049703CC12,3BC74BCB2D33438A,000048D8196162B6,E3BC2B6A4A3BE612,4A5CB7542FFE7BCC,3C4CADE1D8B876C2,AEAA2069BAB8337D,57B8E52846D86523,B286817E54CF1553,24D9B92BD2DE5251,7173D49D5FB063EC,5D349DC4EED0B496,D528E3DC7B905916,9632586DABCA3BED,0000476CFFF4F32D,6472169A3F53C4EE,30B5AA1ADC709546,1A81F105986649F5,391ED91E7730C0D5,66DB1D8789B9D690,B78C24582119731B,B999EF8736BA6526,6192092AAC6E9546,8CF48CB407BD5CB6,26597311AE81231D,5BCC024E44DE68A6,000017444B9FE556,B35F2DB5EF795D38,95D07BDEDDC81E99,5184D72FDED5ED25,B42E6DED2DA6C322,292D197AA71A88C5,721A055928D834A1,9098814D275F3365,8E77CAE6B0B32F98,B0A0E8260CB8FEB7,6E6A7387D8B9FFD4,BF427EDB4B21C836,000021103A0E327F,50CD225CF9795BA5,D61203EC54267B28,EBAD1DCDF58BDFC3,856FB55B8595D8C0,5EC85F873EF6C05D,393D7F96A418F5B2,7027F5A792802E24,2E8FDF704595E1F0,DFBA9BB93B2A3AC2,96BF8129521FB3F2,C97D90706C440A67,000003A0DB6C3373,48551938C77F767B,00955D0AD4E05403,86F4FA96BEB5F110,C8899215CEB03376,5916E11CB072ED34,872D0413123A54EF,3F42327595896BFA,D052FF7914A75E9E,CF0D305E0611BFBF,6940F0590B88B937,81936AE5BA159903,00001A317ABDA7A4,F7D9BED550428DB3,7D41D5ED63762579,0F66759CA59BCD6A,79F4888575C75780,329A5A42A3D55FB4,3CCB1737EB1DD9FB,62B05E828F6DA7F4,F32AB294F54E829E,C1C5C325AC5D14C9,D90FC9CC7C4D1094,BE79097186007C0A,00005497B0FEF930,A960623B2DB9D04D,C522B17050C07C7B,DC8B798F2A3B2929,42F1059CB4D486DD,862933A809CA018B,5633D434864CD89A,DF96A7EF7C711349,7F779AE43C8AAC90,FC22BD25463D3793,B05143E829F268F6,98AAC69D3FC89319,000023C0BA91A073,B5580FB0216D807C,06842E20F7B5C8B8,083562FE0C87402D,5A231AD44159ACF4,B4C72217E7E4737F,9B788B439BEB5CE7,D274CBFBAB400232,0751F2E316F83B8A,939EBDF70D3279B1,5E0A139289C9E6EA,A9FBFF6548B98D39,000042D89A8E570C,FB6C4F190B9ADFBE,11630DFF1FFFB069,35909D8751E3A405,4AFB291BF79B611E,3C967D71CAC96467,18A5663A2C11C0B3,1F330EED43548B81,67F02B435EC523A9,9C39E1C103CC5C65,DD10D5C43724D3E4,7FC0C45DD1EA46A4,000008D02CC324D7,6D8F91DA1596BB0D,C2A9F287D7E5A62F,2AB717C39716C91C,77EEF832188873EF,66D956E5DEC3323C,87A8AC03E82AE05A,76F78866F1C2D8BE,3063994F5E89A7BA,CA1F82EA2B459F01,4CB32B846B6A77EC,A49E528479355175,000028E2C4767CB7,1C34371AD0CDFDF8,B21F09D2236F93C0,1D830A51F1B0599E,69B7C2043D22BCD6,C4E846F9DA3718CB,87AA77DC3B1026FB,81726F581B47112B,EEDA74B30325CE10,6F3155E8B5C29F20,A0ECFA70B74EE02D,10B842F59FB79CC8,000015EFD42F389E,96A3DB1883F0E74E,0F9A4157BBEB115A,C868A01BF3E7FCDD,AC6B6D14C5702D9D,AD125F301FBBE687,16D6FE2A44D1048F,F1D6325F94D271FD,75A6DFC15125CED1,631738BCDCAEA5F7,2D73B288304D2363,2D280AD0DD6F9F67,00004E8C51B1FC7A,B80F5A812F6724D8,B377F9A0C549F425,57681D8A595E4452,3EBA2CD2D8BA3343,E339268F44113A24,4F6562548175A766,031D5B945873A38F,8ACEE13D21F77C15,1EFFE7B92D066D4F,101ABA3E9DA1C4F3,657C8113D100C8B7,00001EF133D1DC4A,89FCC2FDB8734DD2,8DB86BA44AB6903B,62098F4ADE648E76,AFDB235F1DE11493,834CB271D8B22F94,315B921744F1B142,9B5610288524DB83,7917CB45CD79D475,07C14FAE8E8FEBFA,26F9F04C9F58F7B9,CD244608FCBA64E6,00000EC19D9AA001,F7C0806FF7144DC8,08F94B7BE2EFD984,CE458F04975225DD,99DFB34FEAC2F807,227DD314AA459F88,0C2D0765C49CA476,E9EC27F4EEE96248,20B7FA9544B5DB12,D60F3A33B46B5F43,67A7B7EB51E8DACA,D4C456388E9D985F,00006538E4847E31,D66CBCFFC2298382,083B4E11D41A0467,FF7AE7A8A80F3136,9A4D9E188137664C,5987210638D45065,2B431ECAD634CF8E,65EE774FAD719E3A,8A88E45AC466CD8C,CD45F4E3CA89F8ED,120956D243EBAAE3,C24AD72713E36024,00002285254B9181,89720899AAB66AB2,8CE55A465234F1A4,F0CC9FD903C34809,24AA098E800C8670,FB0CE1C5A423E404,C279E9667ADA0CE6,F33ECFD7122C0642,59ED9E6F0F73E733,62D89B3992BBA273,F185AAE69AECF9E5,EEA3CFC7C64100D7,000024997D49E334,025BDDCBD4B3C8D4,4467D39E2F76B26E,5E60C8A5178B6915,C6958263924ABB2F,89A3D82D235C31DA,ECA19F747F8E7930,C335EFA14BFA3321,601AF45AA280FB6A,EF8BBAE640CB4C5C,A958EC33CC6DF0B2,9E1B3ABED346CE7F,00006F1CDBC0A7C8,1489B2F1138E9E51,3651AFEB7441CF5B,7171A486A7E455D9,929D5925DC2EC62B,64B44545F2987EC9,A4CAA3F69183C6D6,F3D73409361990B4,418840BA7E3C9E6E,C5D92D4CF702EC45,A6558618770E1020,28FADCC503FA2771,00000137D362DB47,2B343D6D3A8A432B,26D4E87AE988B0BE,B320B0C7F476F84E,682739F3E1A39CB6,13CFB99535A39259,7C16E480F8E06C9B,391A0D26AC29AB8D,4EC807DDF27D88DF,15A6C53F1C8857FF,079E8197023FD350,9F583B155D6911B0,00001E61D4899E5A,72CF3D06113676EB,94D9FA43A5C93FDF,7FFDD38F61602FEE,878BDCD3BF0E53D0,920971020E0419AB,00D79AE906EBDF89,78F62879078D7568,28A96EE9021C459D,53E7AAAD7D42A281,320374FB35ED109A,65EA96094AA27837,00000B08532CE4D8,82896EB36A62264D,4F6184E61EEA1928,59B80E6C0CE43177,137AB2A1C17A3E98,75EE360FDBC08D13,56943C6B6F2B75F1,81089028AC067E30,B35DCA5B210022D4,446D0C01C79AE210,9CA8848577A30C48,86CA4864E7C7413B,00001D235771E63E,3367982ECAE1D7B0,6415BC206AA3409C,28A91A9221616A6F,31A610FE43E125B9,75947E2EBA8BC323,C3F48F7C99379B24,A24D7001642DCA12,18FB5536BFFE23EF,164589F5E14B3137,9C4D0E15F88FB18B,E934A7DACE85F944,0000371A90B424CE,A2C7103C83591BDF,C25965474A547B73,06ECA778E6760B18,C08D4A6A449CFF1C,C4BE6FB5BB7B786F,C89090E425F9D6C0,DEFF390E60AE8B88,A272354F2C454725,0F98F63027E3A757,F2AFF77793530DC8,11407F262C3EAF4F,000020F63F65917E,59A8238D7F8B6AFC,B43121BC8BEAEBA6,FE30965E27BC2356,BDC24AC277554217,DDB70D3213CC12FC,7032C936F0501E7B,1AE7C34F2877BCA5,E8BCFF1E9B1D46D9,8AE009FB9E307179,B4E0EE1B8B53A09B,ADE47160B404FF66,00000117276ECD87,BC2600D9A3D2674C,FB21F317DAD674A5,CDC9A7AC770019FC,69B004B42A591F09,AA363FD199065C57,5B4EE78E872FD1E7,7D2BEB4151C66EB2,56AF8AF728334BB1,AD94180C2C13B4B6,82A65282C4A2408E,6A57849DD846E461,000062845C57F2D7,D1AFEFE8C4B86C76,3DBA4ECE7E79921C,607653A69A61B230,704976DFC7014B5E,0BD3FACE46B175C8,8CD32276F5EA832D,C5666B64259D0473,ABB260328A74CAF1,781F1379698F5623,1E4C1A5A4067AC70,6F4BAA47B1FE8BCF,0000611F67CF9939,288C0FACC453EAE2,2042F8F21008C41C,F529213558C022E8,440AB278B1BECBDC,F560D258C2F6F30C,879974148D692593,050DFE55BEB2B626,4D637D0BF58BFF8A,A8C635D0DDB19E23,AD09C460BD3C0E89,404A3D83BD7D7352,0000641005C2957C,83564BE569A69576,9BCC9F9FB1D590FB,92DCBF8CA9DB0C45,2A43E9F2C1BFC58F,300E624936F31A90,D7ED9D77BAD6BD5C,206515A33257B6A6,0356A76320C7DBA4,F04735614286B1A9,E93F5762361B8A42,B19C4D94851F8ACB,000008A404961FF3,6F783235BB59E7D0,AF32C426B7324ABF,789EAD0C42892714,3A68254B5470F3B7,D1C20A939D6A5E18,729BC4C3C71D4CC5,2D09A50E4EFC222A,18A835CBA71D2B13,20418D49D63CD75C,3281F0B201811AC3,1566D21640FE350E,00004F87A5169464,11CD9A645CC26C50,7C03295C9BC6C939,3A52BCCF097045BB,B2537D7CBA0A07A2,64C3121A06EFB42B,790C7F2A06F84B63,5DD956195D155875,9E412CBE5089F6B3,30A4954984BC1ED5,B77D033F40AE3381,C30AEB60571DAE9E,00006942D0A9903F,635BE8B639B84CFF,2F4F7AD90784786C,6F48576F99382A2C,744659F160B6CA43,260DF40F9361376E,01ED0E2BEC3E2F18,7E30B87B9034A61C,48DDD30AB0AB9279,66036BCA628110C7,E3D68EE4D7AAE6E4,779CACD2F15AC478,00005A0FE57E8359,CDCD5B59AC4EDD03,5526EF6C91CB2D16,44953F971642DF65,9DC8548AA7C051CA,73D2933B0F77138E,FD2F3B6C3783D194,F7405C2E85DA1A3A,32F04DF6F000250D,8E919D0A560DD1A2,BB7718A5A72BBD94,BC723EA04560FA2B,00004F2327828A9B,D722FBC9D64EA79D,AB3A0A08D2F12487,231439347D50F72E,D66C2B982FE02406,7B0F654DD0B032FB,B344879BBFFD72FA,9489BD36786E599B,6D2546372970A68F,551CAFB1411A6BD3,4D9C60B2E76D9BAE,558BFF7B200E1FBC,0000439F35451941,C866EDF411C9F64C,14D649DEE17256ED,992FC85EA278EFA6,FA7B82ED8264A74B,413079D13017E1E0,AD376F01B83CC8AE,4F98D014C2EEAC7D,76384E6C6E1A7F24,239FA7613CC9D63E,340A629DAD3D5B42,CA67AE0FA23C15AD,0000531DDB83138A,112D979ED19529E3,26578045DA562F85,C8AD1849C3A0ED93,D756651E7A955979,3FBEF976F125ABD3,AE0E1EA45E9AEAB8,E02BF5260B6F7844,20FD6826B4D4895B,2CEC17041BCE93FD,54B594D13F24CB04,C134F993025A4E07,00004E657F16F53F,166A411DF847AB70,B6FE9B00C134D950,A571CA5417BC070B,921DA09261035923,476C499CDF7504B4,53F2DF363821D02A,D0533E94D89E55EC,E4BE3CDE345B4BD9,4A55BE4C9903E365,C8DF59B4E860131E,76CCC24A822AD019,00001F4DE7241493,8830E05D74B787B7,289387BA1B7AEDB7,55FB9FFEF44099E9,5B05997A9F08CDA1,54A8BDC0D641071C,37C15C3C0D0144D8,8EFAF8C54AF2348D,940C054BA4B986BE,557D6B999C638249,B11823818002B40B,4011168DA2E135B1,000055ED8C560F59,CECD505889638AF6,B29326B82B9ACEE9,1B83EF1A71A16706,AC85E916FA43DD80,B845B61AF56E19D3,685E56312DE02F9E,CF931C26B6F12F1E,EDDE86684580EAAE,5100DEDAAC65F18A,8AD163C53543207E,10B3DB8D6BD6CBA8,00003495222D3C45,3B4212CC73C5A551,A224C9DA59B5F4CA,6FCBB08106234F30,1E074E5EE0F9F263,F704A7ACA04CEA98,DF6C1A105444BAB8,0FBB44DA7F8B7984,C0D3046AB90DF99A,BE780BC2212E9710,BE8305E6471327ED,26E0E9EE7DE2BA9B,00006AFC455A1D7D,57377B80B12DE156,6F80EFA29F79FD9C,D81CAF215E723E74,773A19C80C3D55FF,2DE51ED9F5D8D5CD,63A713680B191FB6,D39008BBF0DBED7A,4FCACA9E941EF199,267A24E9897B9201,7AE908492EE65918,9602000BE442FC83,0000025C075EE978,13D5737792FA9194,418E7DE7F6F21298,AE87F8409D915E80,F4F10C43F87E915C,0B12B5D269C0226F,A7826785839BA598,7BC1B43521159E3F,807F47BE37BF103D,383C4862B4340D5F,3715181C4C97DC7E,C32711C82CDA13E4,00002A332D49ADC8,B432185F22E96DCB,452A4A1C49989152,E1A3BC72832A3BF7,BAC5CE1B645AD60F,C39DE1505D070550,B63DC04D97AAC3BE,DA49C2C61C606471,2AC615612622B417,F55E002C659C8D63,5672B762746E461B,A2E2CD64A17C07A1,000003DC88260E47,7EDB6B67B2509B7A,AF2A26BC4C0C080A,1C877FA9EC9998B8,E8AEECA1F3CC9DC3,257B7E39C46DE8E9,B2C80332C88D7399,EABCF8ABE4ED7BB4,2BBDE4762E1521D0,5CA8AB6892C59929,4E402903E01E32FF,FAEEBDB3C3B2869A,000035121E06C42D,517002BBFCA0FEA8,CC76D61F017A7F14,0E92CE01C3E4BB76,DDCDB8BF482E2BF4,8BD52EF09EA5569C,1E8A6204037C908E,1D1FE540AD604A5A,8EDFF8445C93703E,AE92CDB95644D45B,4BF5DDA0DAE005D4,6B2C9BAD1E751336,00002F56C8FE4402,E773325DFE509B21,B48A33DAE87FB077,5A553D6A4A281906,81CC050978EDC6FB,DBD5A0980BF78FDB,84EA1A5AB0F1A0E2,0F5368FEBEA01C44,CDB2069A235A945A,2F2DB9BCFFE10510,C5D8CC10392C6740,F8FF3DC3F00BC880,000041853FC17FD5,9673FCD2DAE28410,1B3AE266B3FD773D,C7A7B5209109B01A,453B3E5AE8F7536B,F2C9A5898A65ACFD,5712C93A7E536F18,7A448402D480033E,F89F0628E11501E2,61B53958D6E1094F,AA59107733FF6F5A,792BE1B2F6836C94,000037657030AA50,E9FB96DAAB396664,F3D4885D57B03419,3B223B74851C6CD9,9AFD2F2270F9EE87,D4DD40D7582B1A07,A2FB02DE5731A682,F97617DF1A97361A,EC317C8BB70440F3,7314EFC56C5319A8,CBB05F406481A214,65ABA228BB93D06C,00002BA770FDED25,162A80E4EB92576E,3E93A5D0633722B5,D6C566EA78D6ED08,EC45386F617B2D77,EDCE5920A4B7FC97,32BEF58C93ACEDF6,23F4CE2568E095C0,ED71070B661C6C88,BCBBE3093AB13429,2DCEF7D64388137A,DD9C920F6A0D56C2,0000513C82E7276F,6DFEFF7ABACF15B2,4629C12B24B76993,E750DD25BCD5AD3E,A67730D0FC323157,FE1E8FFAB9E2BCA4,79CDD8DB56FD51C3,AA5AB8DF134E212D,FACDFB0B21723D78,F2746B6680D7217E,885B36D34FD43637,5EE1365CD3BC4104,00000F9DAC75A13D,3F6BBF5FF7186BFF,A4762C9921DFDD76,20314BDC83BFF6FC,9EE1E24EE034C5DB,D423393DE12C913F,271DCCDA30E4CFF9,A457C92B0BD3E66A,92828E21AF233C80,D918EDC8A5A821DE,7355E4D93C0A2D73,4D38FF54AC08D0F8,00002657A3E4C1E7,FC48381D0A28B303,1DF67129F51E9F7F,516051F109503C1C,233D8D0D6FB36B66,DF9A59EF5E3A13D5,1B5027E67729E499,E9419B9D2B039978,E2836FF8F4FC7E13,E78CE87118D14F54,D611A3B35DB27720,45015281059A2427,0000203C1BBB8D47,577AA2914B1A459F,ED92FCBC92B9FD90,2E5CA2A04C5670E1,22BE179B9A9A8060,139AD4CCE8770A86,EB10BE9FBE16C007,26EB554FEACC7B71,015BCAD52DD35067,0B93D87803423F2C,4949B6BEA6A336C1,789B9397C6A6A300,0000347153B33947,83AAA3033191CDD8,EA126447B845DD96,453CB72F94E9465C,2BF559FAF2D6ED13,14FF5680AE2F4CB5,8FE18A8F43CFE178,5EAEC5F3B66EE3F1,E75FCDAC2AC46B5F,7E3A87FCCFC6A58E,AC4B7FA88271B97F,7D250751DA723A5B,00000656BB503355,4448B2CBCB33EC57,E205FD125CB83754,4A7E8056149A9D45,3F327F4E6A063D5A,E12516BCEC103F7A,A9BB0E68E15B4EAE,95EC76432103A155,52BDADC99139628B,3F283BC214ABFACD,72CEE720AAD68D8C,A9B23E5B899F341F,00006A5DA4537B0D,DDC3564C89AA8641,4604AC3797650DC3,5AA0D8D63420AEAE,DAB690303374E185,A8855819E0A252F8,FA3E872758231319,6905F7425E159A41,B339C561AAE807AF,97239B39EC481851,52894F129C6C7D16,51D8662E326E94D1,00002CC88EC459C2,66AE1A9E85E22738,A62C91D5016288C5,A4C11D5E24A0BB75,2AA797858EADC14A,AE454DC189DBDA73,87A55B47BCCA2380,53C56B4794934E47,D7A0285B1D1F35F3,4EF1B42ACF7EFB42,12C74C1BB074D52E,63ABBAE80D22D3C5,0000137E435873D0,88BD2F921821EC35,4208049555322195,F4BFF7CCA3827D83,2EBC8AEDDB64CC96,6AE1FCCC1D279C51,D24E60D8EF018840,4D81A3E0818B9A06,DDD6352DC25BAE25,8A5669B4CA5C93D7,1B018BAFD1F76465,E70100717D4B9CB9,00001683B1628B93,4A6CD0F95C5A2EC1,CCB958CCE4534521,12B592ACE9D18F8C,0914351F0E4C398C,D7314994F11F0662,697DA0C963061FE1,6AE9CFB2D7817DD2,F3B0BE4358947EEC,DAA43ADFD88CD6AA,5EB935D30776487A,922C210D86168BDB,000059A020B96923,8FCC38119B73F420,FF40AEB0DD53FE80,A89A3BAE31A73349,C8FE6B5E9C8BFD4C,2A71F69DAE30AF8C,B9306D33958FE3D0,39628C0CBB1E2E10,115F6B8507AF9A5C,20BCE837D898869A,96433DCBE3CC10D0,6ECDD0E2A209EAA9,00001F40F1165702,4594341EA494B64E,8F49BAC44DC55CFF,2A71C4BC6E66218D,A17E3E7D54A3754B,22B6AC56B91C8388,0B5155BF016EF724,A69AA7EB3F8A49CF,875072B663E26F0F,03FB4FEFF8D39B7B,259E996A7F7A1622,9FAD5A2B6E714F5A,0000565A62C5757C,54A82015AA19AA1F,B75659B6186F52AD,FE2FFDB04F4731E5,F8D5CAD70185B227,B675675203AF866E,82C17F5BA573B283,51D2645B84FE2748,B8CEAE7184F247DC,FFF81BCA237647B1,66575C09A76F13F2,0C91DA0F4145809D,00002B9334B34077,13262511E0B9ACFD,F56A04FF0E7E503B,396D99A112DE1DE3,9FDF1EA8C4545BC7,27BB17DD890D2704,9DEE42BFB5CBE6F3,21ED0E1A4A5C7427,97F07B47704E9CF8,DCCD9A157FCC51A7,C5347ED33228DCD3,9918CD862B0AEF96,000004CCD8A12957,9B51255DCE63FCBF,58E524F031B679A9,E1F6C40C171EB5D2,093010774B7C04F5,ACC058442BBDFCC1,1587491DE225A2BF,4BA0F00458822A2C,4A0E39194456D6D2,9E8933A6F7202ADA,2F89CE29C0FA4BED,6A0B0B9E921B989B,0000234C6458067E,6C83323799E3C979,710F1CD7469931D1,C77690B65E6B8DE8,E20ECDE76D01EB80,CDA8BA7F3ECDD1CD,92155A11B138D670,147E48D936C55E7E,96C785C4F6FA2BD5,407A5D6557976A30,E82CC70F810200A0,944CE0A254B340A3,0000038B3F02EBF4,ED8213DB43A3764C,6A42A6601FD9B02C,2D8DCCA9283010F8,56EFC9AF137D1AB0,54DA3B1AE8FCB2B1,4197ED4A35A99082,F42BC5AC8CD27B02,2339716350D241E8,FBCEDE7F57074E41,2662D505C55616D9,22AF8E07849B0F60,00002A13C46A3000,52AB8FAD2F8F5EC1,89F75C715BB30F68,F6042E548C12B896,29428281BA2E13EE,5EBDB1A7012BC7D6,02B619133F59A18A,B70F8580E50C40E2,D23F4C1F8BDD0BC1,C999C4D17D06DA78,032BF2C074366E95,842916594D2D263E,00006B2C874770E1,DCD7C56D0E7910C0,5F8C36F1155501C6,2F064EEDA9C801C6,A1C0EA11FF0ACC87,CAA99B29A4C2859B,317D0D7049A16164,627FB2CB8A097698,E4A2B1D32264EE1B,F4482ECBAEBC0768,DC385B1B7CA7872A,02436CDDBCCA1CB4,0000575187F545DF,3FFC77C89733687B,B4EC910FD2772572,C3D0C7D444DFC72D,FB441259FB1EFE7B,ADEFBE1E402924C8,EACEBE67E96173AC,4B038C3DD4F3C7B9,D4FB2D11774F4FE9,76A336AF9A8A1608,78BE3F6FFDD0E07E,4C54EFB61B5CE267,00002FDC8665BC10,F733D2F98A6AD1F3,6E9EFC96D77B6CED,6640100C3842841A,725F924FF510541E,A3DE6C3DDC997923,002072F2E0685BB7,EB9FAFA803C24A6B,4EF4138C0C5DF501,18D7B6C28C9FF436,2BC3A1A750629120,87875097D01B521E,0000571FB0E04D93,BD031E562365282C,5A3E2A7D0740C7CD,73EBA38C08C00163,A72307A6CEF357AC,4664D33B8475A5D6,C991BAC7E8512AD6,9BF0D5ED34548D64,E4FF04D855597718,A8E7AD839424B5FD,B787BF08B0E61695,77279A29292618CD,00006486F397457B,19078C61C5E936B3,0518C2E047F1A6BD,970103AAC010EE98,FD6717B873D87492,F2BAE4B756CB86AF,30B51D4DED4B0CBB,6B7FD7145027828C,85F1496F7C4CB33C,54E613150AE4F799,902CD15E46C43B2F,99D4854B4C0428AF,0000656C4F479C1A,14C9781127602448,6DBA83C7F4AB5AAE,52690A47E94D9BCA,7441445380C1ED72,F165E531006164A3,8737009F45180A20,1543980A85FBB4C8,B652037AE6760438,F1B59BDA875DBCDE,EA0D99DD50BF173F,F7F438DB6E64811F,00005BDC2CEAA7C2,69B13F7B4CBED691,8697D6B61F7B6CE5,1EA240F09F112963,DF1281853D1236FE,180647865B984B2A,0DCC26F660B96823,0F2141A911FCA052,7EF607CD846AC2C2,C251791A5F020848,C1BCDD8614FD13F2,E0807B6C396C5A0F,0000635157CE6298,F352EE3B7D03A7D9,17D507B0DCCF9635,A3FAB2B3DDA5C46F,79344532D290DAC8,0CA70A4B3E75BACD,E86A62018AF01A71,19ED751B00E588B5,43D6CCB2E3982885,9D1D300223EC50FC,22F9EA8450D7C110,013E544C8D17667B,000064A6043470F6,7E5E9EB93507AAE1,A2C1E0F17A66A1A6,8FEC61ECE7CB34CD,E7B5F2BCB01B6BA7,D62965565D61CED5,85627F8E26E59216,8AE802DC511F4252,FA493E17C3F27067,E4B9104443E3BDF2,A286BEE570469069,EDA5A6478F0F714D,000014D680BD6A77,FFF5AEC30BC3E317,C48D2E38E8CDBA9E,058A651BC4BAE3C7,9403F56A4756A906,3EF020A5DB9238ED,EB8EA46F7E18619B,75ED82C4C1F88D18,9A5252D66874495F,35F6A941B534D2E6,53A471E20FF8EAA5,8545FA1117DB9D1D,000024D3F5463296,0583FA9908683184,9230425E3D95DA95,17C7BF94955EFD3A,D9609A654060E765,FD0D4DE08F1E30A1,5092B50623929B33,2D9532F95D4E21DF,4A14E427D4032FD3,9189BB2706066208,5358148C39666FAF,D3A25FA920C66993,00006DCFA163EA9B,8F41CB6CC299FCA8,EAD9FD377356477D,DDEBC155BE1F35AF,6ABCD1A49C1BA3B6,2FD59C97C685F23F,64C87AD54917CE1A,B2A1F3382B9E165F,242F7E8798AFA2D5,B03DF51EDF9A43E1,1986DE1EFE7B99AB,97DE40C419EE7CE9,00003940800F54B3,9DA26775A74A3A21,675E97B60E5178BA,B383373302F6D47C,4CF79B17F55F6460,6C11360E257D9221,36FBDEB1139899A2,7C2F844052EA694C,5D6D4D4E4F27980C,AED8489CCEC132F1,B25C2BF8BA006517,97CF16FDBF893447,0000178716A6EB1C,17342CB374974A8C,B9B1820AE4C095EE,BF50122A3760B268,512AE4DAE55036ED,E91C06D94E6F88B4,C6DF07544B629E2D,AC2E8CBFA21E4849,27FE375B6FA1F280,AAF6F74A0BDE6CBB,3E1BE97585E5FB28,81DD28175D951FB0,000067C3B1943E98,9B0FCD44BBA58FF9,A8EDCFD02655AEC7,E4B387AF90D6C95F,ABDEE1EF169E61AE,B457858FDC8FB220,76EE6B1B8D3BADC8,F0D5042DF1AB48E7,038FDF7143B39FF1,438A9C1894197262,D4B1CD2A97F703A1,CC01A628E72477BC,0000053644A64CE7,6D8774F1198DDE1D,031D8BA515544583,70DDCB6AB7CC2FE4,6BB93C4EAF8F8F2F,4DB7F95301ED309C,2BD85D9D6E4B097A,49AA28C1AE100042,DC0BE27EA15F5257,F6A959DE2FBD5801,BCF248354A277CDD,EBA490FDAD1CFA15,0000207F4F51D06F,EB70859C3CE12386,1C9E856116E0BD7D,C0CC45EE80EB9919,F69EF65B00720DFF,992F40E3BD95D8D2,67A7B8BBE082EBBF,467C945FC3CA18AA,90C93D9CE2FF300E,8B59CA2234A940E3,51E1315574B9BA10,65A684ED78661066,00002399FE7B6F73,726BE78ABFAF9F71,BC0BF22C02E50DB9,85F593A84CB696DE,9819A4DC85A71435,37ACEEE3BDFC35FB,49D1AC978348C13E,37789F2EBFC1513C,3033D2F87285D35A,8F50115CAAA1E38A,01F6751E0FE9C71E,9AECF7A178C0D93E,0000139683D78680,BFC26F745CC61ECC,A4C15DD36ABFEBB6,2E8DAC79F28CED98,6633C884CA2B99B8,69E7A6FCCECB132B,DC1EE00233C29A46,BBCB9B54B21BD2DF,F51108B46DD23CCC,86E8C6758F2C030F,D7DD4AA3109DA788,B53653843536730E,00005F13C840E182,7AD3B1332838187B,7DF8D5513AB36765,CC6D67A751CD33E7,9CAF37EC0D5DB9E6,ED6E21165EB8FD23,CB3CFD34C9797DE5,DE6D6F1DE382E484,A5225FD5B6862EE3,AF0FD46E7E369541,DCE3C83A366CEDD6,5E6D7138DDFBBD1B,00000A52C1DE7A14,0C550D96687FC8D2,37057C906A085388,CB6C4CAF7E062E31,A221889AED82B8D4,EE48883F0B7BC99A,C5C98C88E8D90F11,AB3BE0382AD55D3E,D5199C7A361E2754,0508881C12F3426C,56D2583E8C9307CC,DF270C34CDA22DCC,000044C5435C1D84,98C04B5B9859856E,AA3AB625387A53F0,4FD5420605D9C32D,C7BBD0EB6DC38EB1,8873A5957BA2D413,F7E16BB00369F565,FCA9BAAD31C9068D,C188331FB9035A3A,DE1DFF8E34B2F606,E4B9046506B1F8DF,209D6D1D7EB140A2,00002B13736615BC,5FDA6119848C2CCC,CB1B2DED3E73A05E,A9BE44F5C024B6E9,39957C5CFDDEB605,9A4F14454EAF0C37,736778B914790BCC,625ECC58B7BE41C6,7EDFF3C800D824A4,B61A574E27C7672D,EE77A24E1B9A311D,0461BF5FB08CE1CC,00003356F8A98D1D,177CA692C4782FBA,8516237040A2DE83,D3EF1903E3A1407A,7A69373E27DAA1E4,CB0D83066642E422,4A8C3BB9CB7606AD,C9FEE0CC34BB71A9,ED7B70D526F7A121,D0BF1EEA84DC09A8,7CA06D622F964EED,6005AF17AB883743,00001020F479E91D,1AE157E250C57249,B7D47ECEB2647C1A,560AD735A48C9F28,1B6CABF53512A3FA,9635A1B6CE63B24A,109C0C48D8DF8ABA,A3D0463B096016F7,E15F11D9C4649E69,52C07218193FF37C,C65256C684713246,56996C455F19B93B,00002F5446DE547C,C37A7B59F73E60C9,08450B6661381943,5C7E90C8647D10D8,564CE184439F8A42,D66730DB0784F8EB,28D2AA56AFE574CE,12A7E4A12940CF5D,AE49CC1EE79A0DB2,541D61D79AD7D2EA,E8F70F34C4144B80,A38E7924496E3C1E,00006D9DE8B53DC8,D29672E9A45817F8,FF7BE2C6874399B2,F45C49DE65B24238,5B983DE5DCE8F5A5,17786D0ADF74FD18,93745328AAA2AF70,17880311E78E2721,2DFAEA9ADE584B09,5D6D1C00AB036B7E,CD5175F0969CFFF4,70CFC8A2D3121843,00001630D09F5880,37EB68164A9809C4,7C3703A46D8D5F5C,910D071976EC1031,4C3ED1491BFA2EF4,BFA4FE9F669574E4,F475AD5435340B0E,D9D7AFCB8728C858,4A97C934246AD5F1,608973BBC0A7BA14,EED0B29FEA5F4168,610D05B1F1DF0194,00003E1F7630B960,733A2C29D2FB7D54,2F87284B9726A00A,41A7D44ECE78CD1E,D18110F8F5EBF286,DB3E770719761B93,9F1FDC0C8B6F0471,4C4773FFB22A51CA,E3B4DBB5CD3F090A,E1D5B7AC74E9E51F,E435FC0B67C7DEF6,8823FFBE1CAAF276,00003986A10B419C,6B3A9FC32F379F7C,7FD89A0B2AA0DA58,D27D02306BA89530,D00760D5053F32AB,5FE07D45C4F26561,44F360803E6A2B18,3FF74B91DB7027AB,7A15E245BAB0C050,5EBC80CE9C200E7E,E644C677B592C5DC,D85B5F86DA0CC2E8,00002BDB4B0A559C,D561DF1F147D97C3,F231D5A01660D850,21714C05BA0EF738,95A3352DFE89D33C,DBBB8B7331FEE2B1,3E3DF42903740993,2FD5A2CA97731AD6,887109A37F9035D1,2533264E3E6C4B1C,AA95CA4488C55498,D441ABF05BC6B3AF,000032B078A2BA67,184E14342B327405,A695B4AA2420179F,92641EC305C51A4D,0A05702DBB61750F,2C7586D97C4ECEB1,C5FFA2C3634D398F,E5194A44FA57AE29,977FFFF4E8A3E086,86FFA08CBEB806CB,DD4821CF3F086C76,AED2A92218039F8D,00001546A3C559EA,E0EA9189DFF510B5,5C2A133E54DCDAF5,545290AF5BDFEE52,6DF1787CF4CA2156,16BF65E13C769E3C,DFF4C89517D131EA,AFFFB6431A0AA6EA,82E26E7426A5CB75,DDEA4C3FF1650250,147C91B584115C01,0F27320ADBC8FF48,00003D7D0F550A63,6A249500B7AA7E45,01ECC5951C043196,CAE6B524C27D7519,50FE480161156C67,54D055C7BF222767,343EFCBDAD7F4DD0,E61AFFA31F560C67,40B5E460A17D099E,1CB97990516A4A82,86D367ACFDFB4642,A6233198019911D6,00001DFD44F8AE12,A7BC8C68F08A5915,D9309BC6977E2B56,995D42263AAF4137,5D680257CAA9AA00,806ECE60DAD60CDD,5625650ACEE753A6,846EBC268498E398,3559677ADE114837,D8878191913A61FA,6348CDB79D8F4344,D2E43D1B854D3D9B,000057D4FF1EA915,EF905CC6D44DEBF4,250B5820FF16B29A,EAA79F8B8A65AEC8,37F76E8C09BF20EC,22346ADD72DADE1D,914438411D7BF892,87F6F7396F12702E,2A6A2FFA426C0FB2,F687CA2F706DB37E,E079CD5EF34521C3,2CEECEB5FE396985,00004614088407FD,EE2C06FD47BFD1D3,64D2BEB67A90BA20,BCFC76C86E4B77D1,03899A6DC503A2CC,770C325B26F4B9A8,0EBAA37CF96C38CA,2C5F87DDD08DBCE7,E7D981699641C8E6,472CD9FAE5EDE147,AACC847B1657B0B6,FB388CD4505835E1,00000EBDDBE49DD4,FCC3D5823E86CDBA,D18134A3ADAD3288,429D897A2F08EFAD,1ECC903A142A6241,59C33F09D93C5A30,D94D8658175936A1,5187796316BCB731,5FBA81B9745C0ED4,163D2109A6564C33,AEEB5764A764647C,D8A4BE3082AB538C,0000485D9241FEC3,27F412412F0AEF4F,6B4316A0EFD61A36,6E9B583F79917775,F18E7F8A3A6619CF,754EE52164A5076F,B05FCA1AFCCB62A2,462F37D0B93B308E,33A9743BC6B05641,3CAA025E54F13661,934D3B3D78BCD221,EDF07ED001A19828,000001CA32891F33,FDB242E2FC0793A4,631FB2C99E62B6AA,EEF65C9E3DA37D26,2F60D813FCEBB03D,2D8F5754321A0B6F,6A2174C9BF13843D,B5366E950CD1B8D8,A95B4399F77A95BB,55D47E593790F52D,B576BCEE668D2F63,CF193E66DB4F58CC,00000C6C4851449E,A9EC2F3CC22E1DEF,6BE227406BA7968C,33E0888B3FE82C2C,BAC28F574F72C446,6FDB8409EEC1B4AB,FB7D2677D7523BE4,C80633C3AEF48D1C,724710C496EE9AC0,61FEA3E168202870,B98C77E2D77DA528,1D7B9A114C1FA032,00001DDC69717848,A034823746B415BD,F8BB498DF6BE4EFB,5BB8B7ED2F91C8EE,E5D9950CCC7571BA,1A13D2A1C6D1E025,EE215B07E6729EBB,FB537A30BE1812FB,173D500F206ACDD0,8F28DB887AA0274C,83ED28267A813980,066F0D4705EB9907,00004B73BB75F9CB,4B7DCE69951B6755,55DC0F98931EC72B,947BCF60D2909B84,7EC80A8ED67D439D,D814156F4CC51049,7DB7CF879571C7E8,69F1DEBF91D21A01,9E49003CF65DC08D,4640CFD8489F44B5,B1633F4E479FB3E3,FF31FC571D3A4583,0000571A140CEF19,0058E918BE3D9720,C81972000D9D5838,334CCC750C2AE3C6,C249F7D3A386EBEC,6910F4D6892C6CFF,D52B447B6BF3B0A8,8716F7A22B0D4DF0,DF100CC3DF16DED0,F77D7EB817A6EF01,7F6A80F63CABFBDE,C3BA1BCFA95AD893,00005959B7718293,E5D73DED326DBC3D,FA9160C737E99833,232F1BF31F22EED3,8592E458073948A4,63625092D09626C5,5BC02D2820517508,0ED016AAB169D248,A35716AE51AD19DA,7BE8D50B3C936E11,800E70E2848AAA74,7C244A7E21FE6DFB,00006F9340839927,9E70BA27EF248D56,E261CECCEA2CC2C7,DC6162EF0A6D33DF,090B5A433029343F,5C0B7334C9941D90,7B6A4225FBC0F484,51367EBF17322634,72491047D7C634A9,9FE90D752BAD9881,1C8FA46EB0F26EDF,B161CAADBFFE0E47,00000681019F50C8,56F845F56CB201D8,B41B25CFD17CD67D,CF9ED47858ECAB87,9667C5E27FFA53C6,B54D4F00549B9C55,1173B042BDA6AF83,C8808414C7046603,02A743E23E5DD644,92C847AA20309CFD,11E2D2427EAAA2BF,2779EA95E3EA8CAC,0000641C32AC1D4F,F9593D9C4F61624B,8A1BD9C39C627BC8,AD8304CF99C56D0D,30D7FCD97DBA017A,BED8EE8C4022DDEC,47D38D7193A39C58,839F27AFCCD60057,7ECB2F9235748797,95C725C89EDCD3A6,34837D78A9D1996B,7365C9A39CBF1F13,00001DAAEB425C90,7CBCA21C95B87B9A,2B4AFBA271A52A7A,1E74077DED5EF958,B0ECF25F4A59D55F,018C9709285FEBB1,D9CDB239B8A1C376,A4534B2F83875A73,B41997BD0B4E199E,6F834319E6773EA3,F1FA7EF8DF50FFF3,9AA65E2CC3E46AFD,00001E7FA62F7D56,BD9A3AEE7F431290,4507BC93AF4104D8,4B4075D9CA614C59,D807DAA746EFFEFA,8FC5403EA003D91F,DBBAA3DB30877B2A,7926831046F35D89,8B10171E4A9F8AF5,911FD04C8A8DE1EA,1F66F3BCF7D4E971,B5FABF1FE08402F5,0000200CA20B708C,36D8B83B8336433F,2FBCCD40D5E9A845,32456B8962D6858C,AA37DACB346E5F38,5EBC213C6CBF0A5F,E5BD7B7488863982,6C68D0FF36065F34,8ED2D32B527ECF92,98BD2513A5485747,3B1A68B6CE879755,322AF432472BDBE7,00003CCD6B66B12C,2753B1D1F2F829A8,19775D6935E470F8,4736F472B24D1693,6B9CBFAA9944B135,29AE80211EAE7027,72ED7B33436B8D4A,E46B02DD3B3268F2,B77E3E71DF567C5D,251E9102A0562651,8D00C0247E936B69,C4C4A7FF444B4E9F,000049664A1473DC,952DF2D6E192D4C9,D159CCD95AD814A0,3F4D6E38A8E92AED,595F6FD5AA3367DD,AD29CC70A4C8C095,2EF2F94EDDA88F74,0579FB0DD1CE004C,57B06271273EC846,0FDF3127C764FEC8,5EE50071319FF979,1161805748174C51,0000289CB25A1A27,6386E6290149C908,00CD9E30319EDAD9,477064B5E1880923,970D82AD9D017165,143D667B2896FE9D,B632FD9E829EEB0D,DC4AECC03DFAD3CD,37533CD319EAEE0E,5AB873ECFA8D8882,613FE35746B9681E,3E0DAD0B6FADCE9B,0000223A04EE55CF,0AAB5F821F7FFEAB,8C74FC4113C29F2F,2AEEA3EABA777CA5,9DEC36CA01F7F221,117DD0B06871CAB7,3A38F849D8589B0B,C5BE8F4795587600,22858065CAE5969F,634BDC4FDAEC2535,D5E3D9E5FE5CCE3B,833EAAA9E37ABAE3,0000672DD67856B4,4CA52C77E4375AA3,5D07D10AE7641824,EC3A1FE26FEC4FEA,9C7FE6C376391594,CE0A5BC32A167AFE,9E64EA3914BB8779,3AC4C0486297BD3C,F21D992A9D61D60C,B8694E0D5BB1A73D,F34AA8E4B169AB75,F971F21281E12E84,0000320740ED6F2E,4908048FC68DF7DA,448FD8B8F87AEE41,4CA685DDF00F3598,D458CF1177EFA0C6,E92E5A0BF7B2B4C1,98D43BA0F1FA078C,A87546B2D1870C77,45C3FC99B083E500,6CA4A4F554681E10,DB4F3A85F826C3B3,264BD740391AD6EF,00001984A934CFF6,C98190A528F7362F,ACA447D7FBAC2ED3,8AF0D3DC6A563BF8,A768D40F197CA93B,6C067FB248633A74,918E68867EA23344,E45CD10C67A7B9FF,220EFF8BF8A7B22E,45A28F0D839AC016,9CED5D157809CBD4,E671DBD2A39CB803,00005ADE3E00CD23,5C7BCA15DB557B1A,441E3C8ABEB5AF2F,962F4A593EB9A334,637E62EF819EE905,C208B023587085E4,D48990CCA21B4F59,E323E638BD7F9F66,49FBA3A4FD4F6275,76BCEEB7ADC00803,BA5C1490CCA7D1F7,240F4E803F8101F6,00006597D8B3FFE5,32C7396C993F38F8,1BDE0A9297C57981,9CAC400F443209D2,EA0EA08B5534005C,F6D13AA65AAC2429,44A1D29826ADB6FC,36547038D109B221,C857CF2B8170866F,678DF2E4D01ED831,3DDC4988A7D864AB,2175A7F2D16B03B5,00006CD9A19EED06,0C8CF795C611592B,BA50B395D435DC22,220C733B7303D6E4,276EDB1E5FE79A8D,445CDBFF8AB1B3F8,6503240272537950,CE2E028A58EA46BE,D297220D278998C0,47CF32CF98E95FC4,3A5FAC73809BEDBA,E04207288E6E3CF5,00000CAA532A17DA,FFA910BF9E642BA1,52A81FF02731A6EF,54EB343523E9E0CD,EB48E623F3D9AC15,F835545ACA882911,DCC3F57C3F66CCF0,082780CF81B4E2BA,9C6A44533AA82D11,CA6E92923D09CFA0,D0765AEF95568141,7D6086C40F680EBB,00002FABB40B5655,C96C3080E1F5496B,9B6D7D15500B42A7,2D153D92C692398C,2545EA0FADE95D4F,55519BAB40A212BF,9290507BF10CFB53,4F51A1451D78FDDF,2D386316FE311E69,869A434352160A49,33971813CBEEF697,D2960093D2E661D9,00003177B2E9141D,DA1B375273BD1077,CE297B5C52BEC64A,B2DC8A51EFCAAF41,EC6903F53C5C6E60,5F351914BF35DA4A,BBA7E01BDE0B803C,3F5D285D8F710736,55E3C9E414110E8B,749232906A8430F0,4B15E0107BD08390,64A1BF772A5C077F,00003F8B9F9B816A,4A60A5EA5BC929CB,664A7002B5F0C3BE,B4DEB90AD320F9E2,436F7B930F46AEDC,5B43F8909F838B86,BBB9228A4DDEE492,31D25BF1CDB249E5,FB362AB9F725DE48,D65C2E15F071CAA5,68E842594BCFF5DF,10FABF94956D8A65,00004DB75AF5FF6E,90F81FB0B32E3207,0FF4EABF397669F0,65F5873008A12EED,FD5830D3D406830C,AF30E24A785A4147,55BB386E37FCE523,5F5A5B6A2442D38F,14BAD3FDB67FFA90,EA57DE8F12EE8DF7,6705347032F4A825,3912220BD6D9F97E,000055B3F5CC3123,60BC5CF1CD180F38,72053441296CD08D,24302FCBFAFF8FA5,EE59362D47587EF8,5912F32870753E76,F08310EEFC868609,DC2BD4BA433D7DD9,24D032D0C571456A,B42F1F0DBC0C5B1D,C8CFFE4C6FE5202E,5D4643696575A1DF,0000389B0F74513C,6CA3CE0BC2341819,59EAE5A26BFE53AC,D497F70601C0E927,BBC39ACC288A29EE,7BD0251E16201DB6,E5A46FA12F55BCBA,68E9641D58D85D49,492345C597C65DDD,A131A94AE3D7A054,1FCF2EDCE8B6F4A9,5C18AF77B8FDEB3A,00000F9B22A7E909,8CA8E948F2A7F471,BA49CA162412578A,390B88D8BCD006F3,F2CFA8F82B6F4011,CD3336AE5BE36B40,50863328FB47601F,63AD619C878ABC3D,2786D1E8871DF8E0,E9C1FF7D01FDB1B0,726B47227E2BE4EE,00E9C4763F16D4E5,000029B12A73D3AD,9898C8AFC8126DF4,3C56444A67D24544,483E85392F2799B8,6A18DD6FD7BBF2C6,BE74930E1241FEDE,D1028EAACAD1405B,F59CA8BAC740D582,1CB9658BBE3AE92A,881CDA4D1F6A558B,08D4F85CA5B9A857,426536A8F29E2D8E,0000436891C0E405,A7E06DAD08D30D31,8EB779E5627B1A05,D6EC74E0ADA32D7C,0AA14BFCEEEA278F,A30BC39F2D3E728E,843F5BFB9A9F2F3B,C9E3BD2CA14D5CE6,499710D38D0F10C4,6F7BEAFBBDD1A50A,2A3EDFFD35C421E5,1F66D74B8681ED91,0000008FEA7296BF,99DC5E4681F7957F,0F212592AB3FEE67,1F0D7B632E40064D,BD218146878BFE78,FA1D700D8319BEFD,38EC18C3D013EB78,4378081203B1C328,A59AB085F11FCE88,71459A11AABC41DF,0B1689CE177997AD,B483A01628BA3D49,00001DA9B0BFE62A,AAA62EC3130A0103,6D81A3132767FD2A,0BB39B1ABCD1B4CB,830235876B3E422D,822669158C593E48,31F76415CAF47E4A,655F147341943F41,BD1E5316CB51A68C,7EB08829AEBDC8EE,E9C000109813E5FA,DBFD9C9BBD705F4E,00001CDD4D1163B9,8C27C479749C1102,C4F7A51ED2828854,93D925BFDAB796AA,2030D09DDC5E9D84,12F3BE8BB827BD77,CAE9190A178AD20F,C7277CA64E11E56A,EA88ED67E06A662D,433EE757947045B1,0C4A9B4A48884F6B,4AA285046E3091A4,0000578FFF560473,18FA03E8B5A40A65,1EF3DBE341FE2B11,1F0A3A1C92CF457F,D3291511823FAA3F,969367C262AA8197,380F1A316AD45506,121C03E713C4B2E0,E7B92DABD4A594FC,5C67F8BAE9E3FD89,47C8CC5662D51753,7267A7C1225B55D2,0000516544D43D83,38C426B7CB1BD840,BC503AFFA1FA8774,9C3670B097F53137,866F528771EB0C65,A352AC05B8D25F08,3A7D787556814E16,4ADD3494B55F795F,44C32C5EC1ECD2C1,218F8B48D759DE02,A3F6D6B6140EAF5C,671BEA6A67F238E2,00004EECB46B8A82,2FE02F65F962E662,79B9EB2F0056F206,FDF21502CED8E937,22188CC2EB6A767F,901485187AFC22DE,42AACB7230A8EF68,AED205D762555DFB,820C464E313A5FEA,BF92D7D1F198C9EB,3000D40104B004EA,35DCE9E6D88FB7C3,0000230F7B999AD1,31C158A379C0C553,A9B02875EDA964D8,2A0E8463BF0CB7F0,6B388571E8C930AB,3AC97BAC426FB0B7,76B692137D5D77B3,C7524020B277740E,9C426025424CD6FD,8FBD9CDE2643BEFA,C73EB2240C1C3521,FC0BC51AE8DE6801,0000389B3264C706,F0B0FEBA5F4CF45C,16A7DAFCF49C5042,8669392FD2884E5D,BB126EA9BDA02898,8682D78BCC2C4346,F8BE74692DA0CD00,CD0BC9E3CF3EBFD4,88180525A3EDC229,C660D863C29578D8,6640049CA76B2BDD,ED8E7C79FA60D96E,00000D69E5221078,8C4D356DA5BBA434,9D11BFA6E3685B0F,240EDEA26B0DABEB,88B34CDF89637CF1,B6AD44C833D80C7D,02A7894034621E73,B344992CEE262158,12E0ECC85F4E685E,849CD3F81186CE02,79BF15432438B62E,1CF3AB41587E1E4A,00005982603622BC,D504ADFDA8F62A5D,52DF8725AA896310,E7DF461DB377814E,C568E7A91B763CCC,952D88FC8DD983A2,5ABAC6EFBA641317,9DE7EE95503DBC9E,3AAA73DD9B13132D,D6B251DCA85E6A44,8F49ED4F301E3173,D4FB050CC0797384,000021E8342AB632,CFE696A21A54D142,4208C52A4A8DE0DE,72BE35BB831C5BE4,CD99347C8D4855EC,0E879095A5235FA2,C01796F9088D3751,282C4CE990890277,E6233E3D9E3EDE88,ADA01B1751F30659,92663FC1A1B0ABA9,B6D35794DC7E267C,000043A4960B7B69,2A8DBC0B0DB135B1,CEEC34085324BD5E,3F274639D4743FBF,009C81E852C47856,F9BB8DEE73C7E21F,7959AE8CFBA3B092,38C091C3475887D4,463439B2BCDE0A69,59C0664780E636E6,48B35C3B1E16FE83,47FBF7EF2F883175,000013D4278DE94A,9D8C442FC5483808,4DFA4294F39A1D21,63264085E90917B5,66DC856AFEA429BE,2F3C50D68A19FF1C,F6D8C91E241F7A08,0AEC152E1EC83CEC,25D725D706682DEE,7CED9597C8014777,B9D5FED872C017AC,1DD6DF33728046AA,00002A9494395DA3,A4A3F7BF4687B30D,136DD3E95423EE8D,C9B9FB4567C0EE1E,7EE80445A01493B2,01865A7E0D5F8859,B6787EBFD039BBEF,11E7847F14694AF4,520FC51F7DABB1CF,DEC7DDEBFF667A6A,E15F6B9229CFA986,B8DDC3FC0549E6F3,0000119C6BB8AA52,D97E2AE820B24F74,CE4893EED3A2A960,8BC1F86C1F514501,F9C55280235B8A73,8EA9B2831F67CCC7,7696EDAFAC0B9BEF,D7FA72E069D6E39A,AB40FA0ED4288531,D53C30460DDF9E8C,E20B4F5E5EB43D28,61267E3B916E3D1C,00004FB9DBB072A0,BA98274BDD98F045,57C0830F4B4A4770,1CDE403011F0F514,C57522E24690905E,0AB26DF767D114BD,09E8C8F20058A369,4117131CABE64C7F,8E04C71E16E43308,4C43D9737488913A,B93C43A8F99C248F,CAB9BA29823DF990,000022DE74FF6324,9CDB1D4E374E3D23,76990B305DAA49E6,D58FE32042048768,68BF0657C6A46CF6,9F5D162A5D9E9D70,BF39DDC528B94BF7,BB086A0C3F91F247,FBA07D1D20EFB1DD,8E9CD8B6DEB776B6,9A560FE510AB8173,E22F94E9F7F21D9D,000059E87FF50D0A,312A98A25B604D2C,ED1A36B0DD8D087B,C9E7D579E8983E76,4F38756BF2F38D0B,F5720F0C4A5A98D8,0C1098C2C53FD208,7E005F90E20A8786,92E27396DECD2BE4,4B63E2E21247055B,81CF5952D9C5DD62,703DADF7E3A69957,0000080AD4F07A15,63F119CD0BDC1AA3,0F51C11D9D575B8C,221231A913ED3A93,F905F4944FD43591,9EEEC39DAF098A1B,AD155D1AF5A29B59,3AC04E31237D3F89,4E05B9CAA28C6A47,F3975D26E26B7040,05D7CDE764DBB862,1F037321A2E2CA23,000016F21082FD7F,8568CE2BD20AE9F6,A03F1CC7B729205B,E63E5FDB886F9B23,1EB9DEDA15E4A6FF,321CBEA1D5ECAB35,096147EF973AA366,89E0A5AF3BB936C1,12A49BE296FBCE8F,80776BF3E4973C66,DCB11C478738DC43,AB00B8BACB1CCE2A,00001EE37807EA48,15F3FD0DC1601DCD,90D9DB6B6A924706,B36E628A3877C453,63FD18CFC0570BF7,4BDDC0BDBE44C0ED,B2EEA5D4B8D1A5EE,1E1EC8A5F1988D8F,E60EC877B78E6A8D,50C83EC7B5CDC621,74C80C05F3CBC37B,CD9B42F58174246F,0000569BCACD5E64,5360A2EE800FFC42,4D3CB9443A05CC96,F800AD939061DB62,CC90B4B1C71AF5DB,9889688E34C7D419,20DA0B58A31FDCAF,231841A32E092101,97E71311E4E18183,531B397E8629000B,20C393BC552D7057,D73D175A72F0FD2D,000058981AC52289,BE54F6D4A61133E8,E2F2F7785CC85A94,D8DF0F2F87ED6B84,39937799E2843957,A25672697890089D,F5502B7A5A639A45,06FE84892FA3953F,6D423C2A3B615D20,C93D19546BEC7CEE,E5C1DCE285CA952B,246D156C4853F87A,00000D43DB4A151B,5AA7FDA742A89DE3,A303F92FC5ED1C95,90A25214D9B52D95,54A8B0A3584EA112,78212855B3B2DB5A,77517CB8618E39DA,8DA93D0A919F7056,D16A04C90C2F39E3,EF6DDAB58260E824,42A15223B1399E5C,737FA46AEB27EDE3,000001E0462BB866,BDF77CBDB99B07DC,E2CDC9A28740E0E6,66F624CA56844B65,4C86908D5FBE0950,0444C56898BE0232,C64A314F7F135104,D117D19DD757669F,298CAC777212B5C7,ACD3EA212142FEB7,793F2D4C04695475,B78C71542ECBA1A3,00004F6A030E59CF,FA472831A51E55BE,7188E5EFC43DCA5C,447699091301290D,C8EE6D148E74CE97,51F9CFE0A4BDE0BB,1B459062B32B9D49,318BF760B80FA334,B04DF3D27E0803F2,85FDC1B3AA94080C,30240471A21C5286,90BAF0E1C2F42220,00000ADF26F26930,B554CDF022C28D5D,EC8262417A3EB0F9,932993D93C7F70CE,37D27F0873003401,922C2296163AB94D,E7020801CA18B093,D54632B8BDFEFB12,9230466E3DF6FD6E,235A6C5193BD8D37,193AD8BE9186AE3A,13C37364D98CB50F,0000357F74303036,0215EE5ECD6B4AAB,D50B6CA940601848,F15D040200FDFE2D,325A9EB003C20CC0,1FB5B74997F3CED4,3D0B04ABA89ED4C3,2014B4476D15DD82,4E66BEE98919F30F,6C4BAEBA8597F867,A24B49517666ADC7,AE9A716BB1FD5B70,000022090215DF20,A8FBDB092F1E5F7B,7FCD31083FF980AC,5F267C801050B022,C3D07102C20196F5,BF47831E74EC5443,401C661DD04DAAC1,10F998214B3A816F,639CB28246188D01,6BF87D578C18A0F2,FA3061EA4D436617,2D82FBE3732C34E9,00001AF40FD31B7A,645AFA7C5DEFCE7F,1CAE408BDDD856E2,486C1AA2F9245E5F,DFAB65C951D1DF6B,79882396242051C6,923FA5E3391EEF8D,DA21461EFDD69DBB,1CCA92F4ACEA2A01,6629EE926E30FA80,EF263F6DAE114F5D,1E681BE5E2C27E54,00006820E2A7C0E3,FCFCDCC1FD230C44,09568E3064824DF0,516E64D7A738E4B0,2905DEAF17094A5C,123382CAB2288457,DA30D0EFE4BB97C5,D9F9142CE0EFE2AB,5E3693F0647151AD,A2C12D7B2BC3946E,1A1E36F955FA3C62,2DB1727B188CBAD0,00003C77296628B6,7650A03643F931CC,07A297B3ED433F51,E07538ED0099F3D4,0E639FB488E4A8AA,8BC2E04677CC73CC,F8CB181127366E99,8F0FAC8F712BCB51,95065120E0FE53C3,E95B0EBF129CA796,48C26154BE09633C,38C98EEC22DAC3B9,000022BB7DCA5AA7,89D191F7A6E1561C,78AB0D357626700C,C446415BD0DC26D9,54AA2358310A7134,33220E78506955BE,8DFCD16B34265983,5BBF885B1C1941AA,9AE5A85CDA13EE84,271F504FD8BE6690,37373F519B0A7AA4,73D299CDA4737CB1,00003369454B76E6,AB977046E1D25A86,A4B2F44EDD934AC4,C1D92EEAB9A2CDEF,897BB9E475458BA5,E18494168E340631,A7ABDE8307A45699,B9D8B3029CD16806,7E0ECAD968225E29,2DE7D326E470C490,9F8DC9D7E055020E,6D1B409E8ACF0B08,00005EBCDD515212,78D59030865C59FD,58911FAA01C42AFE,0FFCDC43B1273A40,A4AE78906F403C44,EA3C1227C1CE7309,2DB73AF20CE4D741,E5B5BD56ACA12C76,E251B8FBE19719B4,7FAB7A99E0A3F7FF,C8CEAF3E0314C4F0,F52C274466292351,0000373D475D7B4F,A494B973AFBCA3BE,D607F07157B3F887,4DF152655762E7DC,DA8152A305F7CF31,C66EA0E3F2762E13,103747C0F774F522,53A238344F356E12,43CFF744571B5C13,AD7787C92D803135,DE53A537426CEA27,756F25AE5CC3C52A,00002CCE4019F15F,DE74F67166092D0B,628CD4B230854BCA,ADBC5E1201434F23,5023B0BC3D08946A,CED649A516CA28CC,335B9CBCF90FB358,24A61D301B0B9385,149E35D1CF049BB1,3FC0BBA10A300E18,2F525190265C3B7D,EBD21B00333AFCB9,00000D004FB935F6,57792CD8B8B006E9,1589777B45A4FBDF,001F5367A2C547C3,C1F539CA824F8EE6,F6029E1664DB17BB,578A2ED08C1958BF,FB4B72045D77A543,50D6EA8FD8C4238A,A09FC64E13230CD7,3A1354BA13476E4B,35D7700FC35C6992,000049940D590AFE,03A5E362D922E9D1,24D5C49FC498536D,FE2771EE99F74C06,00299F0479C9E931,4778164500790E3A,5625FD97F0AF8993,55F6CBFDBBFF1464,93B8F1FFD7EC6C99,A8825A43538685C9,9F35E3EE67C1B836,313F0643E0DB9432,00002D363FE2DFC9,6D510899E6F493E6,DB27470D8E2A6808,BE6FB79A0250A90B,B8E53ABD752FBBC9,115BC7694CC4FF61,3D4C109D56A0D077,914F9A287C958F14,5C281A2273E2B5DA,28F390D78F2A918A,44C9560346CD0D26,95DFCB46DC4EAE09,0000486377F90E3B,8D127D30A9215515,69A3F2514B3EEFC7,3A465B443EFA3913,ABF17F186D8BEA1C,C2BD976AC413FC2D,75CF1D90C8A27B7A,58C5CBD465242B94,5AC3CEF0A873BA8A,5736FE7BADEC475D,8C02FAC7ADC47F4B,4B4202754AC04A90,0000185506632615,676E83AE2EF94022,6897FA0A12DEB498,6574E6BC06B80E0F,E72512001E5A3A81,7E73B071A14F21AE,A6087A058C42FAF4,2060D5DF3BCD612E,68AF45AF8698F4EA,36FBFE011C5A7077,AC835232B37B0B98,68E38A3C51D83C29,00006F786702671C,8BDB40885A6ED006,938AACC3CEC39FA1,A5553B53F8DACFC8,0B0292EC0A3A514A,FA6D7C09FEFF4E9D,F3345F7BB64FB333,C09725712E204408,0860B879681DE66A,E938C39E18E8EB77,93F1EB4B0DD51839,767032332E80D3F0,000059C0FB7738AC,2DF525FF8124403D,3EB5A0FC513C8032,6E8D92EAF8ACCFDA,55215CACD9B144A5,0292144B757F6F20,185302184DA26ECD,D16E7A0D8C58D34C,CA262D0D8069BE24,1FFE09B63351EA6D,FA2E2F6BCA97492B,E10133E35C8DD061,00005A72691FE3D6,1C367ED83805470D,AE2E636F73C44FC7,63D98D3F02EE748E,E7575E6419357E5E,B435E395EEF1A53C,5488F475D2906142,96445FF97E37B1AD,41AF44BF6EC48E8A,7815F245E9066B49,3BF9D080C0E164BD,C3B129594E9054FF,00001259B1EB6DD4,E309A43678DF5BF0,7F5E0F098ACA2DC4,CF12AC9FF1BF8BF8,DCE8B1438F4C5D75,596C4430E30404B9,DEA9EB9E697C1F93,3F60CCCFA7796E72,FB1A5A32AEAB3036,6CF0914E377DFFC5,9BA589FC4FAB601B,B941B4F819D47936,000009DF6341CA81,0DD04C087A7ED5FA,58BE0A497572BB22,2DADD5A264C78652,E9EA2034B120BB03,A88995B1E59B80A8,94E663F23C265E8C,653282E11DC327A7,4D9AB755B018B17E,FFB29CF9C5F98D4D,13F6511750D23CC1,0A6CA4333712951C,00005BA7FF1F04DE,F07ED98C9ADF2C43,52A4A93854080E30,F015DD29C956C40F,7F2A949DA2AE1BAC,78621FC09972CA83,418DAA6305A5B9E3,414CA013BBF91437,A80DF33183E5AEB5,75545EB017ECF653,9106DB99A21E1979,1C0934FB7535DEC2,00003C11513D471F,7050C920E8CCB472,65369249EBB97C53,C1256347F853A7AF,A6356F4FC1E18C01,D480EB9C3A63597F,64516279FAA7513C,B08176C4973A58E6,097C77C3FC6D40C2,B7C6A0D352CCF1C5,BD6B3CA9761CA602,F963D0E62BEB5499,00004E072F423714,AFC114EDF8E9CA6B,154981287426B844,EEDEA99983FDEBF7,94B4652B5206C6BD,DA7F96C5BDFE29C8,AF8B174A7E92176A,4118B5787C53432D,F15572805EDB420A,FF72951901AE98DF,9E658844B28D1335,A306E4EE4EC4DCFC,00004FACD89D0874,C4889738DA91C9C3,CA57FDDC14793CA0,6A13AA1475C574F2,D9D7A19FE8D1B069,008D0B833E0FDA98,818733F779391D94,229263AC69894F26,D49FF212BCCCA8B0,862B0DE269C46CA1,6C3F51DB74ED8A5C,3D36E67927AC552F,000051C880B8BA10,650F43C0E20B6AE7,B1800ECF697A7FDB,5AA83B28C51FD9EB,49067A7147FBEA55,BE9FD6885AAEEBB4,C1513A867A1AB34B,A80F117408C770C9,63AB7C8B3E8DF96B,93749CE815FF4EC9,A95B7AB8B5B794D2,165527B42C9D1399,00004577AEECB587,6DEF7BC0098D3A13,ED55F5A3FE0F30D5,26C6B1E5AEE585F9,8F01E938CF226BA2,0AFCEF47DED8D307,1E91918F20ACECAE,BBE5F6A41928CAF0,E12FAB3EE64E9696,5970F0C3E4E5B3DE,D498D676750D5E1F,99DCC3F4DD62A805,00004F0E8FE0039E,B9D3F94DB4E3F3CE,7C0FF9CD9B705D1C,5F8C53AB84079B0C,3F7BF948C055421B,3DA4399CE6F7EE80,0AAC1260FF3E9ABC,B6F1EA40A7EE94C4,849D7296C76CEFC1,61294CCA224627AB,78B6C9BF9E17C5E3,7A738FD9B83AD80D,000044FBDF8BEB65,E5966F8873C83A4D,B826C1B5505E7B70,E7ECB34A78BA73C7,AD6926102D40EB31,DC3019F947BC9F05,A536C83AE4B064A0,44979B8A7E6EDFCC,C09AF8951490DB1C,51E5ADDE23F381CA,402D8CD57A4C6D8E,64030B91ED9BAFB3,000057FC6F7A1A77,6670B01247B55263,1E11408CBF41694A,1DD63F7A33E61975,FAF13ED731646AF9,084D4E234A26093E,D57964ABB5B91145,03EAC7DFD5F3A785,6C29D28230C6111F,3D79187DC3623D25,BB6E4F8772CE2B71,C36662C3F2EFC98C,00001625044648A2,7734AE684AAF5F90,B93284EA95030A6B,DBBA36805FF53BBD,8241540E98242B0A,BEE55CC929AA9CFE,84BB3119A85D2346,F662DCDF4664AB16,FF686EAE39ACFD5A,3C307DDFDCA0597B,2D59B12BC34F252A,E4E453B25656754E,000003C908CDC34D,BD80F1B37375F5FF,C27C5092039E4CA6,C0F971796FC8B339,212CA6E18814B5A0,1D561823496CAFA3,9834E81D053D67A2,EBCB04B9162E15A1,F32AD51A843D2C7A,8333883EB005C55B,7488F1E4187083FC,98C76ECA44FA2F8C,00002CDC5369148C,0D3C828192A8AA47,C208A4DBE890CC07,B79E89F2C48D69B4,0E828BD332CAB908,F83F93FF9690CA1A,37C3AE10D8B69184,25DD711B5CC882BB,603050321BFA7F62,CBAB607743EBDCCB,97E602B59CDCC929,7F8D256A3893FC41,00005DD8350846BB,C760356D4CDFC549,7561C3A656590894,84B156F8992F7D61,BB6BBD4EEFCB139C,6D9E9DA387719162,8226F7D1878EE2A9,D73D0CBA0124003C,691DA45BA7D4FF6D,9A51E408652A5FCD,0BB0041618C7CA10,BFAA10805A954778,0000071626E8CF55,21682DF5390B83EE,D8134EBDAD2658B4,D7CBCC09EA974568,F4C512366C28F000,6BDABC22F3417C3F,C02B611B869FF292,F7E084DD516BF9B5,F7B8878D135C5178,BB8C9DD23EF1D80B,EC1ADC7932ED8A33,192037B9C842AB33,00001ED703E0727C,820077BDF9DB07C4,9512405FC804D5C7,D197B6DD333BFADC,86F53C9C1C9569E2,61084A3B032C5084,24A4E4760F20FB09,4B8EC6F78B722366,3FE6BC6C7DEF04E2,78B8237700B4D9DF,01F643D193155D05,F18C5D8D49049D8A,000004B4A96FC757,EEC961318EE59463,9975C24466C246BC,E4FEACDBD7836CB1,ACA57543C07CD6AA,F0582B6FCC8886A8,F582FAB913529176,4B5FD74F97291BB7,6B5664421A834DEE,6BA0DDADADA4BC34,B0C3E67573723BD2,34C99AA28CCD7731,00000CEB507C0DF4,EF95406C044F0EE5,5B1C7F3CE60BEB19,1127C1BA8D8AA94F,2DA78E62D4B6FE49,579312E53337AA38,C394B92950C45B4D,956E7F78AC5376D6,BA24424156158ECC,95790F8FBF6B8072,AB73931E88CF8DF9,B50C41456C52AB5B,00006327C32414B5,02A343AEE0513F46,67CBC708268E733F,69DF8E614D0D4236,AE7477FC14608211,143817981A05938F,DDF3AF658B6819E4,5C38EC0678C89499,CC706B36021023DB,D5B092A1D275059B,7CBDAFF723D7E413,877FD36C028B95C5,000017D2E612E40D,7533B257A03823C5,D0E9862473BCF552,289B6087BDA8DFA4,7DC948D3D7B57281,B255962FDB1E99E0,19F65D730B1B086D,31E3A728972C72C0,DE88DEEF4451A0FF,2FD2DFDBCB6A1CD1,02C0CF3A1A628EDF,42AA5445BE533F2E,00001C6D4562A49D,7DC82C224E68B866,B00DD4006B456417,53352F8561ED2DE4,20F1555F08B503AA,DB196872C520A99E,8223CFFA8BFB587B,D910831DAC9FB2E7,C52A035240042F81,DD3298307FB2B993,F31E8BBF3C732176,8B2447BCF2B8BB55,0000525FDC003D97,507870E564571B5D,FAABF0C3E96AC4F5,61150E1EE2055B1F,706C9E59B2F67CC0,41DC47C873059EE6,0DC661486787AB64,7BA3154AC6CD96FB,1A2E29343E062641,8A3733B58C54B9CB,7A8F83E664B100A1,60952A4A01EB1BF5,00006AD7AB7A98B9,D2867D46505B89F9,8C984840E27E2653,024BD268E74E0898,22CC0EE69898CDCD,3FB7FB4ECDAD46E5,AED893B37D7B345C,0A86E20DCB2ACF10,7A171E75C36022E8,32D25DA3431618BD,ADDE40078B51AD73,9AD7CAC52B0D8493,00006C15B1D01073,7B68738FBC5DCC60,86A53E2A1A282508,279BFEFF5C6751C4,E57AF5FF372F39EE,97B053B235B85F93,E735134B3E70BB6B,B684F75AC54EE8E8,3FB4D5570D3D4861,5BBDB8AA21A4FCAB,A7A0FA911DBA922A,AC84161B7B336951,00001243EBEF7CC3,10C1A88DB3F5D8E9,E7FFA20300C8772C,AF3A98E35E72BDF9,A7A8CBFFFFF4AE49,1FFE499BEF3D8086,5AD36E9EADFB0329,E6005FE2B0FDEE7A,A0CA4F8B42281E0A,169844E48A91D500,24757986312130AF,3FD6A0C6AC890791,000016118D6D796A,D9693E04864DA5D6,FCEDEBB387B6EA2C,9D717420093756A3,906C22DB344E840B,61DEE2B44EE90874,B56A075A81912391,CAE1D8CA4376B162,1BCAB31A69AED456,1C94B9142BA20BC1,6455CEAE1B6C762B,ABC80CCBCC2BDA17,000039D3683D25E4,ABFEF556769412CD,C766FF03091BE118,F8C311E36A619660,D9572B23E8741F32,BE9ACE9F2F758EF9,10FC16DB06018EC3,1A2B9E00C86A38BC,7D70FC2F07ADE78C,EDC01BD81C24F135,11CEE7913DA7E5E5,F2509E7A910B084D,000042D3DEB03A8D,46A6315B12731019,EF86FAE44097B617,66F2F3E13B0009CE,63281B3E39AE6990,9801A795FCCCBFEF,D878AB1BD68EF0B0,6351DA3B691292A3,15C9A76343234EE8,CFE44D4743F2D238,FBDC5B70A0DF4B7E,81C273F44E292EF7,000015BCAC5B5B32,0F7AC713D79FB84C,CE4FA7E56EAC3017,33D79BE8551305A4,8874F89504E3FDA6,61F66CECF90B244C,B6071CF29A17272D,D72070167485782D,99C439DF82A16C31,E0B2204E8CC46783,6906DD0777BE5E20,F078AC51360A9992,00003A5E3462F047,7DEA37219DABF4A3,B53872BC9C2F005A,A600A1494C3C1D69,5639563158F563BF,683DFCFA64037A6B,BEFF4677155ED1BF,75F4E78C97B03E4A,1D2803823296ED1D,FE0C07E6F6A0A73D,CB5C916448FFD921,C2A0CCF3CB7B0B95,0000259636D477DF,E0287695E868C61D,DEDD1819D5150798,60E9CDAE35678359,C53663C6A4F67C25,34EAB02F94464953,0ABCE0BF1A20EE43,F5773F9095DC1B9B,0647747E413D3398,3F05DDCFCD7B013D,BDEBA0638BCB1216,A0C9806822711FAC,00003A8B74DBD2B3,E2076E303FBD0651,4A7802C140513EC3,C9D832A066D582A9,4700E843A6D9C66B,605E798D65F0CA56,C95A6194FE0BFAD1,A4DCA1D21300E34E,6C5286F7A9CD1D2B,6CBFABE0639CDD65,16538AA197497FD1,35B5E04352DC98BE,0000185B83AE0C79,2CD1E2335C15121B,D52B031D536161C8,EF1CC8D79081CC71,56CF08F34C4AC040,E9419B42302EBF1B,2A97E5979DAF2868,1CD7DE7231CD56B1,7E8B8D8F2A3E39A3,0AE55B062587CCDF,C5957D2F6226E885,A25CC5E52D6E1B13,00003D16A28A15AD,B05A83C3647EF466,5C4638B6ABFA6F5E,E7FBB2C4125A2DE1,3C9FA705F8253A1A,316CB66528444E26,24759B21858E240C,04502518B2EA9ED3,E4BD5FCD4F2E495A,349E9A65D52EA524,136829C5C87A7ED6,74B7D661D82CAA6B,000066B0E4C8F396,34FBCA072588EFC5,1FE0AA181037403C,4BB5BCC3EC772409,F26D1CDB8631E290,7C5AB644C54549FA,5AB6FC3A28EDC846,5D4ED6A2F57922CF,8AA5E845D0EF3EEC,3C1B79601154EED3,9D12C0BAAE18E527,9D38A92E710385AB,00005866646928EF,4DFFC758FC2F8F3D,D1AEA642E01259EB,2A5761B4C86C498C,C1455D72464B33AB,ABE604E355A76B32,55F73D51D5490195,78C7776A2EAB4343,2D15773869A22640,EB3D62D9CF625A57,9107439ECFBCA7E1,5C11A0CDAE29BE47,00005905446D7921,0A49222F9BC798F6,920096F71C8B626F,E0474F6DCB60766B,6A6C9855E7AE71B2,6E268D0C7B647C3B,CE83C6354F680E3D,F7D33A1C56DC1426,08BD0D6AE9D40692,C0EDE66258A8D772,DAF8D3794E257D07,3C098EDCBE928856,0000639C579CC35D,FE9BD223B05F7013,FB38C1E32EF3144C,CB92F282A8D086BD,C807618B456920D9,66BC2000CC6FF438,8D20194D7E9178E1,57207D8E1B51D213,D09D6AD1C5897220,408DEE7647D7516D,55DAD2E6ACBEB766,189434D109F9DD26,0000659FB445F1A1,8F6DFFF14F59CF75,3B60C0AC1C4A71FE,CEA1B38F7A6A3D36,EBCC0A84FBBBD3EF,67E1297C060EBC82,733AC4E0BD9E9FF4,2DDCAE460804A45F,5E20562C836C8269,F99DCFCAD3BC4FB6,9FB5B5CE5305E849,102D5C5A856CC507,00003A3F45997F7B,260E6D7705A7D13B,C57617CCD560D7A4,9B0A8EE5B0006D75,08D9514A47FE275D,8A90ED2DB9F47D40,1E8D9EAF7FC61153,C6F81A0AA845C5EC,C1BA6A9C1E4BB79D,02B20765AC03FF28,83E23C3DACAEFE07,9B3B2377192C9411,000008A11D10FB96,B150DDAD7995F802,A7CE55BC74E138A2,E86C252667E8964C,F97E909F6E4EA62A,40FDAB5A660B02CD,AA3D14DB55EA53B8,B7411FEB89F15B23,53FB81EDC05A0D6A,6D1E999C6CDCF589,B099AFD4EC481CD4,D421559706FC458B,00001BAA81996926,87323E3090CECB94,9BDEEA0DF79C3297,4CF7BA9C5B947E42,B91FADB7679E9654,2385AFD067F3909C,E897E66D6D5AE4B8,EA1465293E1F70A3,020B4AE7632E200F,77AC365A864DCC4B,FCFC0AF4A6D4A5C4,89667AA894E942B9,00004882631B8BB2,00E1DC9DADFE34FC,5CB50DB0E5FD67A3,2F2B80D82795FA24,48AE1077E0C70F9F,8983681282D47D5C,1C232AFAB9EB8F0F,EF39D1DC73AF932D,165AA037818517E4,FAF681683231DFF1,35A1947AB140C48C,8108C4EB661648FE,000006C9B4B717E8,DAC1BA4821802F1A,522C88D47FD48F35,3EBDA1FC771A8DA0,853DE29BF44C0B38,845C292C8C0EA729,78E240EDB5C44261,CDF50F6E06E0F192,9A20625186E42194,616555D22CBB9F7A,B7D682EAE77B0E4B,BDB6C6CD388FCD5E,000026D6437F6B3D,279FA8F8E8165BDD,25EA870C2C30D037,15B8128F59FDB25A,18BB0053F8937698,82E0A50C5AE1B47D,DAF9D533F0CD4C1E,631A9E0DADEAA7E9,F76613EB9FE5EC78,25DD3086930BACF7,200947491BBC9E3B,AD3226ECDB705D55,000017DC0499AEE4,387F4BE6C7C56D1B,3251F99B5BF3D327,8EACABA6E87C613D,5F28FB76EAD45F56,C606826FC530537C,A035BE94CCA617F5,12FDFD20B68B3B85,E6645B79D9AD8162,39F6690E9B93207E,81797F7D07276AAE,90CFBDAC4E6A754F,000047307484DEF4,FCC22C490FB4EA48,2C9BEABD88D64449,E98F3ED29BCDEF76,7F819AA787CE732B,13BCAAA56D6FF3DB,53BC74B7476F0320,BD76E39398030134,336EC2985DF7220E,D8438533B29F911F,C3727227D36BA4C3,811041068A604B02,00001FFE787B6226,BDDD5CFC400912BB,C56A155460CBCC3B,4359C07BFF38A840,F075DF4082359D7B,5B65091242B47A43,B6DAE6AFEA18F879,4B86934E821F790A,9655C02C017F021C,FD542DFDE10BA867,12EBD1C865C59B06,2F3E352DF43BED87,00006BF24AC6E96E,F4639B2605FAA3E6,2C270DC9A01B0367,39FE00658B71DC06,88305B3522952817,3CF4833EA81AD1D8,4B9CDE78E93659BE,698ABA432498EF77,DC457AF4534A370F,B9C300966E01E5CB,898CE8690CBD8909,50BCC634E4AD8625,00003F1755C47BF8,4B82E8AD89E6641A,21BD8AB4895521E7,B9C4D32DA7FD9075,70691D1211EA1580,E4D600EF88326D8F,CD98BD1ABAB1895F,CDD47DFDA8727815,513F4A18B035EC71,0B925C39AED99747,A3441E7317D6DBA3,6C254A62A920D0D1,00000C71E9BDB2D1,9BF5B0FB5EC42224,A3686D019A02A32C,0FEF3888FCCCD96B,2633DACF0B36D824,E7D047AE7FFE57F1,4B21C4E3258BDCA1,187E599176EFA63E,110A810FCE4293E3,9EB639AA6DEE06D4,BC434E85EBB602E5,8B09A4303E280EB7,0000408B5A55CA7D,1078FF2319F250CC,86124135E4875983,4774C81B6F607699,C0E00AC1919F0A59,01C9D65155BFEAB2,8D0390F569A5655E,B1C9D10547CE2766,9A9B12001933AF1E,40D7640FC9C78714,AA82D808975745A9,2B8AA2E4C8426952,00004C45E00B39E3,622689ADD070A957,E1DB7F5A57E312C0,24BE8F34C82B0677,ADEDED3AA76E1872,930B0048DCF42818,97C99E1716CCD330,6B7E106D4E089E8A,57D0EDDE5E9451C7,5D9454D116D3957B,A8089B45372DD862,1F06210AC1949D11,00004FD52FF77067,CA1C29A873BFBE0C,A0156B38E052C74B,00592DD3FBCC0E21,94FDEFCF520A8D0F,0AB1509DE8F443E3,9E9D0B49540696B3,38855C271E8F49EE,167C357E75A0756E,A5C0EBA67DC859B2,1FFAEC10B06F7237,8FEC37CC5234ACD5,0000291D8BF7E3AC,D33C39A21D5241C4,8205A09F2A302A39,B4C62845BC56A798,45E9CC0BC957FFC8,F8059494176FFAF3,F0BD4AE334C6F027,2F29F277BEBB1740,3E1A18E089184C09,ADE4E068448D3AA0,46FFCD9BFB81EE5E,F7A777DFF7B50D4A,0000143271B13D09,C7D9F96F46B15CEE,99B06B41C5FE0345,140A89319CCF34D8,7F167C499399C311,3F4EC0E245B1E2D8,C84948DE57C44886,8A0F1CA65EEEAF5D,9C87FDBB649E0D4D,0340A360AA50FB11,343794B0618DF4D3,479177F8BBC8B6D0,000068959D01B344,800BE1C461AEFCEB,FE65F6256365A5A3,F5D3B2D7AEC4DA56,28E557DDED5137E3,009322FDBD639AB6,8DA8B1DF84051A5D,74F8C361D79CC80D,79D993E2D937B27F,5E76B99E06FA6D8A,E7BF995E1A7E2297,B170AAC0D5A663F6,000021BC10F3E236,14FF02E218667CD0,46779A5C945561C1,33CD4D922E4DB2EB,88E8AEB383002FF5,D9B5E370E4D2E06B,5486328BF13D4275,3D68970D6B737E79,D4F38A225B6A50D6,781B16E75403DFF6,D52236408655AF21,63F2233DB731742B,00004742B82BDD3B,2FC6EADFDE33485A,C55A566A3112524A,022539019B56A106,F6CA0E3A2E9A0F13,C1067C8092D8E2B6,63B30F4268FD3A7A,7576C1DF9A82CE50,E33AC068F9CB33B7,DED1990BF0082287,DCC0863AEFA52672,733EA7B429D3CE7C,000041F41DB79D7E,C8D5D588F1BA77D0,60ACB4720BBA42BF,C88C415D6E38523C,9939A005C6F5F71C,E18FEADBABD9763B,AD0BA66AA9FD2BB5,5B5D7C992DA3949D,AC7C52E3C841D845,5178D3EEADE6DBFD,A87020755A5762E4,4A7E851F9A7C2B2C,000033FF8180E771,81D9AC043FE15A6A,022D5CDFEE0FBDE4,93166F5F1335BAE6,5CC5258B613351A7,4B59D0D3F6E96C4A,43741C611449F739,3CCC98A5CAA789A0,7DB96DB78E8E6A78,383EC501B66BA903,CEB5F0438A4647F9,D673215CD29E657D,00001D944BDCEAC3,8EB1FEEF97736818,68473F0252D88A4F,ACEE6698934D8C02,22F15BB910A11A52,B0C7573F9A6EBC5C,617EC764A46337AD,0A57AB4C2DB7460F,FC336D7E04E0CC4E,029EBE472BD03045,E7CDEC1786829C48,D4B10CA536F1626A,00006AA94E4A8504,DC1801D58BA9063D,83E5BE256A9F3582,23C9759BDE636412,FBD9D3DA6BD25A25,C68F76FFE7117111,190BB80F58134D6B,7B0D4265083E4373,288A9BB15C87D94D,DB17FF6A629396FC,86C715D67AD79E93,42A4533B92758047,00004F44FC9D06F7,E2C290FFD189753F,246036CB696709A8,97BAFA65A0FD3DE7,5787979A1E5F2090,A95BC67C690692D8,884C0AE4F0E2FF7C,94E36FE59BB5DBA9,3743AE861151F3A4,70D061F5FFAE2B00,F52246AD3A35BF11,BF7886E124E56BF5,0000433625F2DFD4,117E35D438A9E619,76192291C5FE1F4A,A0670A6BE783612B,98639B2ACABD8638,33F3B79588FAB2E9,F9BB9DE24DA0EE2C,6D60BBC7446E7808,05A871E0FACC73BB,8EACB5DD2228C83A,076DDFEAF29553C3,12664F612820A396,000056320C9C42AD,16FE6EC1A3F33F32,38595A909872DA7B,AD5DFFB2EA78C8A7,FF2904A8240AD5AB,CC8F20EE9865388B,458DA7881011E2FB,3B95AEFD871C19C0,CA261AE75D98FF86,84B9F6D489FB4202,766F722FA27BAAB8,7CBB0F410F463980,00006F01A07905AE,3B8D9444C0AD38CE,F70879D4521AEF98,77661CF08C972447,FF866C0870E77C3F,2F2B9B95EA9FBEEE,2B7414E3FEAE7BD7,58B68D4CF01DF7D6,007EA61D227EA99F,3034469CF7165636,1D87A09CE9D0A70B,854D1A246FF49ECD,0000108171CF71C6,90B081B280BCED81,3463B263E83A593D,FFA7D333BA192BA5,FF2D0C2A1DDD6BAE,BF018EF2230C8E33,5D3085D9BBD26B8D,034908699DEA742B,00307D6D8B5FBA9F,B58BFB984F88CEE6,59E77582F5D42111,DBB473BD579373F6,0000698F1A559F6E,F024C0DBBCF04401,B5A7FCF4DE9946A1,1023486099578DC5,F94CCF63E8A616F9,18953EDD88382292,B4C843F6AF0309B9,E62A7C0192DD7DEB,A39E004988F785DF,AC56F0C7AE84B672,FB4A2C0A8CFE2BDE,85257029ED723CBE,00003A1647787506,75C2CA63DA336C26,83261CDA36E87E09,01CAAA8AA4AA7402,DEB3B1A273BC1F20,AB805EA4DA475111,890E5817947091A0,CCFB00BFBF7FC424,68F0DE89E8050C29,3F05244594F48713,65194A41D681DE6A,9102D0C198CD0704,00005F3DE29FAFA5,8AA28BCA279E2F49,AE0775200E22B9B6,C7869F857529B0E7,97B9917579F2D804,954588797205CC0A,D09E227BFCF4D778,30C1487E54DFEA48,32EC339FB2BE948E,1E887DD5585D4102,C0424E9720CF0D9F,B899E8DB5A86346D,000014FEEC892F44,15ADCCDD60ED0DF9,1AA0200BF213CC01,991747B8CC196453,3BA6F8F97F2EA434,7C84BA5D2DD9DB94,B9E31A408A318569,8680E8A22DB56F83,32111D639E8A2049,55BAD0164A2DDCE7,485DD21B0A920D39,87979758FBB75869,00000D7FF5B554FE,65F6281ABDBB387A,9C07BE245A26D240,2A830DB500B44FB4,D91CA04B55847EB5,FF95A9F7076036D3,D74F9ED7B4694B9D,E210EB25F5D9EFFD,B088E1FDF5590349,BCDFF1583AC86635,C3A2A1A588CAD8D3,3EE4E6F6437944B7,00000AE6F96E03F1,0D1712A4A424D7E4,D85014378B326347,363A6AD3C58A148E,3DC34A8647F98755,341BF53D1A674037,959C11ECC91227D3,82674F0E0CCE31A6,5594C88CAA899BA0,79ABCE17220B51C3,DB5CC8FFF1D4F640,47DB108050154120,00000C744A91A5B4,F009A63513BD3A77,767ABB252913B019,DF7459F312A5B781,0F4EF828AFC4F84B,54226B12EFB4EED3,54F011F8E4B1ADA1,A387552217A55052,BA99F6308C65EA91,93160CB66C6BF04A,AE585A7FA9C12138,5ED60259A9D3F7F9,000004394E323E8E,AB3FADF36E369793,B4A4E25C1E955B5A,5FB2B0D08A3120BE,411736FFD26DD12E,2B60E93B1CCDB251,25B48C3F211DB1EA,D025E3DE9705D983,03EEE5E8E34B3AE1,1FA3D4EF5490B961,7AB303C84B7978A7,E1482EF832B22AE2,00005ED2D2ED4B7A,4802A83930AC75C8,AC4583C418F7754C,9F636682D372458C,035822CB335B8EEC,2F82D34A05559331,8D7A6E84A589C7DF,BDA24727B6CEF0B3,A12306085B2AAC73,60E2BA20E9FD54DF,4020A230ACD02571,5719461ED74948EA,00002E56170D2C5B,FABC303955A65C1C,961D77ADBF9E5309,4043066F3B7A8035,4BF765E2C5C6053C,3285FEA9EC7C3554,88F1AED9560095DB,572487360FD12F58,C88641FAAC8AADBF,99A8AA7CC8DF5C08,926F2C17559FADEA,454AFD8BA413C546,00006C4489E53A50,23E3D933F8F6C5D6,6B7DED0A8F724556,E33E86079E8C25E3,1B9A3B1DFE495F18,EC2265D498998DA3,AB2DD535E22B4BA4,8C1FCD070ED016D1,AA4097AE4CEC7E44,F8428F44EF6CD268,944BE6B8EDE373F1,A4BB58C555A8F887,00004B8E6BCF28E8,8C1A13DE989379FD,9CB2A3408586F8D7,A2E3AF5135C9A149,3FA44407F074DD89,37DE80682B2FCA57,764D6C34971650AC,8AE0A97A99D02E7A,F08CBF80BE01C0F1,314F0C427EF6D02C,D6431E54C0318A87,0A1F7BDF4B822E0D,00000F590CFA284D,8E60D592327E1B57,3150B4EB50B80D35,E830426527BE0C04,DB563411690EC292,2405D558E19F9046,217A4D3D4247F17C,85E6F3787701E8A9,1994EFB7F1761291,272693BE5B058EFC,FCD5B910ED76D3A8,FE0DCEE18D823215,000010B2B38EDF26,08B3EB8151A212EE,F84D60644109388F,07BB858D19B1CAB0,10E3B92BEEE4E641,12B51187FDCA047F,6BFA046A77A36E85,FBE3BCE15F5C0727,450C3F0D9CF06CFF,7EEF0EC728557AB1,6819DEF1A0F21921,56D02569D4B8ADE4,00004011E5183009,34E07A2EA5F5CF9A,6A7A60E933AA7B38,9B615CA018E5B2DA,EB257660C94FC6A0,508BD9E266902458,0C4C5CD7CB4F400E,3F7F14ACDBDC22FE,6B406C6A11280A60,4AF4F1CC8C72C41C,AD36524628575E39,D23BC7B4ADD3DD04,0000158AC55F4D93,56290EAFE6EA3C0C,9B8BD1F264AEA9CE,C831BF432F36FACA,C9A8A02B8A141633,B9AF9784CBAE4846,60752C2ED15AC229,75530A4EE671A66C,0A004B1BF848B591,85F9B4BF401A0862,59CFA583B3DA48F1,04C6351AF8F42B91,000022D6FD3E65A1,7481461D2CCDE3E2,1C8FDDD9801F7F4E,1175B407963E4782,769733C1B49C44BF,6D194441ABD180B3,CC299D15701D6217,11DC5E2433A0747C,187DEDE0B0E28629,CC2244FDAD8A0C69,362FBCBBA3BE2B1C,84FBA4B8455A81D2,0000565370A17C6E,DE36549FBC03D166,7DD452F61D1DA730,F5FD86CC229563E3,76DA57C8421E69B2,6E2353C96905A636,DD22D0F5E15B9DBB,E4D995FED7EEB0CF,359F09360C8E6965,EDF5FB1CCF584A83,76FB1847256B7C9A,E03524EFB05528EB,000065AD93DBD067,BFCDEDA85DE774DB,17879B5255F33F92,3A41D0EC83461F97,605BA76D1690CD54,1202B1D3BE3B1E01,DE86DC8C357D88AC,26448480FF5A03F9,E9BF31A17787E9D6,489F8E12EC0206D6,8BDEFCDD950DEE8B,0DB3569E3BB2F2AE,00005C8D98E1EE5F,4DEA9AECA4187361,C2B8EB2D92D48B00,F20054AB2AACDA7F,B1D261AA9ACC5E22,190D1D4FA8A6C6B6,663CCCD7C0360376,13C9D9FE05D5A4E3,AB0AAEEF21555070,49BCE15F81C9CBDB,BA4D4D8E6930F75D,30BDBCEA82341CE8,00002F0DBCDE5E3E,C534CBAC095AC42F,935D0E643B017D80,BD669F1647F5DED9,E321B4441F90A4C2,C8EEAC9EDBF8B128,D859EB276D55884E,E938A6FD227ED52B,5CDC0B22B2F6CAF2,10C74B408B1ECC6C,872403540A9EBF06,EB7E7D6A80547A60,0000328F49FC172B,D8967BD69958B3DA,BC420E18FB471DC9,075D575A6A48A233,4E2E503364C134C5,04BC39097EB85D8E,17342ABC907DCC07,6D6D61A4F90BA105,BF3024603D8F62DA,17CE1B7AF22061C9,11495868FF9F6D52,02989FE947879B2D,0000455E1E62D6B4,95A42057B5FAC073,93774BB36042229F,72A5F525FA16F90C,4E2120BBFDF6C9FA,A5417FA36BC11329,139973CFBB62F9CB,17AC0CB83605041F,A169752AD9916414,C297286F265A99BD,C6BA70AF4E838FD9,5660535AAF87C3E0,00006F6056E6ADA6,A635B92FD1A8D759,C92F3B6F67F10EC0,74C4464569151905,315589131FD0E895,418F0DAF0B6AA8C2,9FB989FEFE468B12,58E80406D10EB0BE,EE95808BE7CFED1E,83C5DA30306C0C86,E957C5F639F6DC72,296E5FE4512E17A9,00003E368462E4F4,D8A161FF6F34FD1D,2ED17579FC994862,F8FDF396F34484A6,7411A92BC6D1CB63,5C6F1C0109280DDE,F1EBC9F6051F74B8,6BC2C5FC833BC5F5,7B9C31C9348338AB,796EC1FE904294F4,3F7FD306101D3AAB,962AF0452580E6BD,00002099559130BC,3AE6CAA07EF66CAC,4FD0C2F6107802D0,B64E30E5C0D1E97C,AF85AF0F813203C2,8C7D47BFA7786BC9,2487377C554A1A05,E2E96762EE69C3DA,F6221499D47EC4FF,637E198D62736E5A,1F98CDE964141D24,2C01CEC06B7C98DC,00002DEA184C7DFB,05DF125D8C48D94B,8676122E7945258A,71D3A31DBEFD3580,5D8051E0556A3228,24F3F0E22D681E1A,0AA884569EF458E2,7A8C27E6A63B4B63,03A9FCC4BEE1522D,91CF05983EF1C617,75673103A44B2AD7,86879675C254BA38,000013802B76DBF4,36D6B6825CCF8B54,52E9CF27AAF00FBD,84A262C2F00AFB6B,55FBDFA5B5C19CF3,69B3505AFAC14E2A,0C8A566136AC9529,D940C85D3786B3AF,8CDF3DE06AC33DD6,01B1A2037B0D3A35,FCC825419E850358,3EAB9ADDA8A42437,0000530D2BA2C1CE,75AF2EC3A8129B3D,E57F602AD0EE0DD3,3FA25442F571094A,2B6A9E580269729F,A003C689DAD95390,60A150452A9BC7ED,459F5C61E1355E0D,260C4C234CD1A34C,180B8C158A866F63,78EDFD491E65C13A,2AC740134A3A4CF0,00004495C974389C,F9D1373BBA1BD2EA,133C7D44336F0BE9,7E3E4005F4203855,150880648172DFB2,1C4F5CFCED9313EF,2E36884A324C6D10,FB89ADDD6622D8BC,BC5E897F3C7AB19A,9635998336FAEA5C,81949EAEFF090D99,C1380B95E1E5CB42,00003E0B620DA000,2F514794408291B1,0509D5D7F4A3CDFA,D040FF9B1A9151D4,D94F7C21624FBAC3,0E78C6B6F4F29EC5,673C5AA165602E4C,169D91FE6D898916,4D6643C7853B36DA,829C5552780AADD0,67B460D298A33344,F04668AD3EEB5C91,00005F70EFD0360A,39A7C5F753DA96E2,21348CB65549DF45,1FBBA154F4FD7D02,DC7EEC7E3D8F8770,027D65C09398AB54,3F354FFC0D57D06B,B82ADBDFE8C23A6C,5036BAEEEEB3662E,A10741B0F813F6CF,C5E22DF2622F004C,335CD0A3CD748FDC,0000672285AA5FA8,6380FDB145C6C33D,A9BE38FC187221CC,E8E237F4D7F6F1FB,77AAB4F81B6D0988,51A120497B7F3517,EC1280D373120BE2,C83D1BE84E8AFD80,EAA7F5F8A18BAAE9,35C7A7AFBD65BAFC,A01070E1D0F39915,1F6842AE9977DDCA,00006E068568A9D1,41469FD5A53834B9,B36797E5840C3E8B,A767BAE67F7780E6,A5FBDE2EAA0B2919,4177D2077B17020A,1ABAFED52A884CFC,C7632E22FD7C101D,36D363BBCB7BCC57,4D5339F35B6FBF0F,56E2F1C6F6AA920C,A37AE4D0C49A6691,000047370635D83C,6F88B3A93ADF7F13,72B83E51DED1E130,C1E9AB4BA256B916,04D06C5BD574E1AF,3F7176DD0C9FB9E0,67E6A22AB800FA58,075B9AC8F06AE704,EE182328B080A4C8,0458B8D15CDC5E3E,96B2C03117F70A50,B91BEDD7B1DE3602,00003D6923CAE91D,873193304D79906D,CE8283AAE0B6B503,447F257BB39C9CF7,D1590E88A83C1627,CCFFC2EC6AE09279,B40966167C4C6283,1925D2BA3CF01912,D2DF8A8E64050C82,99F7ED64816CC163,5DDD0DD67CD40D65,AF708E104F50C68F,00000D6930827FDA,F673504D5401D735,17B0E966AF388DF0,FC5F361C54484FA9,B76DF5377E794088,7BFC24C7931B521D,18A3C96A4B272898,7B07C200A4AF5ADE,6D1396B667697F07,500269A1CF513641,C1632F51F9F0453E,3FA393D886FF68F6,000000F7F00E6DB8,427B42D2C4C180C5,0CEE3A7E0A36BE21,EEEA74679A3C369D,8AE71BAD197F89BC,DC7931D29A21D0B1,D83D7B0832A0C445,D72BE5EC306042B7,52B4D2B98249E916,ECE90A7D703E0CF0,2FD4FF04969A4961,C0D0234013C06552,00003C123EED76B8,909197AD386D34F6,0241A21E083D7D28,4129FE18E4AB5F91,0FD6D0D29E6EB975,6EC0E797CA7E6578,9D1EBE21D1F898FB,08DC5C0A364DDC10,4B41E95C707DC8F3,B289F41AF4F3CFD2,1E66DF73CADED6C9,54CBF3AD8347063B,000060DB0E5B769F,612D58CCC74EF61F,5D829C38C471152F,11E706FB30D7972B,433D728358595740,4E2F52090E071B80,DEBC05576EDC84E6,CB18217CD17B3146,9E3835DFE7CF3FA2,5E585F101DA0932B,E2E49D12E330EFE2,4FD8B3ADB394183F,00002E28085BD67A,126037B7DC82BE8F,E73AEBA6D05C2DAE,CCC5A2DD4D9488BD,E5731E5B2F0D3413,1283FC3EEF6B2B94,FB2836B1B5E50AC8,0127E432C9DE0727,05CD8C10C76325FF,9C5F543D0C7595E9,00B02E2EE7073710,F390E434F6B17E83,0000573C02E9DEF6,F8154D656402D3D8,C71631B6A746181C,E2BB5C757478892D,093630DA7487CD7C,B27CD1AFC507C3CA,57A2B6A919605E45,21531C348523CBB6,BFFC2E97FB05EDA4,31459F30639C46F5,3356F55CE6CC3574,B797DA9F1BDB58E8,000013689D6DC4C0,4B0A429B1C1A568A,060AC16CF68895B0,5C7543649C45021B,0F3DD7EE100C363F,C28E230FAF4B0127,38912A5FDE8A61A6,B45963950C59ECFF,9977CFE5B9AB3A78,83BB94E201A5CD55,E8D383987FF61126,566FEF7709646A59,00001243B48CD565,21BD976FBBD60BA3,7AC51DF2170786A1,1AB35477AD3E58B4,C659266419AAC985,7D2DC17C6C301931,9F633990C4428E35,42D97EA7E499420E,DE2BB6CF2422C7A8,B6F27A2E9C7FC81D,F3CFA882E19C1B4C,091D251984ECFC76,000034B9FE41ACE4,E578433BB6902F66,C84983D0F08BA6BF,39CBCE584645D26B,E9E4FD8FC7F047C1,4436ADA5EE5FD4CA,9F2C5BAE71B9C128,F083516928DD9360,7DBFA48C7ACC50CA,42341490DDF1AE18,B2CDDF3C7F1AAEB5,84DFB6A7414AFE64,00006207A3916C38,B51ADB4D014A9469,E36BBB9EEF075C09,F944AACDF9D9B622,40B7E3D65B235EFD,8E3E1F2773D44B9A,27D58227DEF4FC31,461012C50829E78C,D35036A90EB6C40C,9C538CE1BA5ED460,C40C258B0D4FAF3C,49AB8F63248B7196,00002A5A37197D21,6267BC92E7FCD5A5,81B3D36FDDEB79C1,FC0DAF662B1487CA,7395E814C81DF4E5,0D58C9E38554CE2C,A546752332D72EF0,C2EF25F13D7E20EE,798EB10D1071FDF6,5C2A854EBE255D9C,AEA526E916B366CF,500B45106E619815,00004A3DF5956154,FC09099ED6E8D7EE,B355142F68FFDE4C,5C91970742FB1C7E,B92A339F3EA745F5,61303AD494B62D32,29F53F470498734F,56226183518B65E3,60898E7A66816893,43E7EFE68E856B0C,D9AB377037BA251C,D10E1B901828C7B8,000035910A94BC95,CAF3843B9987F88D,000AEB88532B22A5,0E3BA8976818606A,371D727808990735,F747178AC57BC8FC,F061AB89A6CC8BD2,DC963BDF3AD83360,AB42C51F3BFEF26B,C1820D9CE8B0284A,713944357511ADCF,B1AF1C21D7725125,0000337406DAB8E9,22FDB7950EC8747A,FFC2D818ACC3B21E,56C5B40BE0A5C407,CC214822CF982D14,E2EC88F92505B7C7,03243C28D30DA8E9,8ADE7F20EEB4A19D,F0CBB8FAAD0D222F,43F6C8ACFB3F6C04,A03D9DA23E6119AF,090F5D174D1621C0,0000518854DC79FA,308AE429A6C06E14,92387178C33AB945,88DF08591D2D51FC,FAFC2E213BBA7078,70C9251E67AC1CEC,A0D9BDE03BBC2FB9,AA2EAF074256758D,EADB73BD9D1F6405,533A7FA297F36CDC,2575B77CD3E7A7E9,DC09273F778C4FFB,00006270AF45EA33,9120582CD414ADDC,478E357CC794F645,7F2AE55A4507915F,F9E9C2ADAE94FC90,2EE9F8902F830D17,6520FE2C9F2F042C,B9B113956EB48146,85A7F6D592DD53CC,23B1F26878344E90,B019EC8EB74AED11,2DBFB10ADFC5684D,00000E54D427CD2B,DF6EFA85414E1838,D54135C9C617B672,193E08B49C52C04D,823C8A533FAB8D28,0A2143988D62C459,06A1D9A084246530,61F3387CBD91B1D1,F56012E6C47D2513,7954567F37A73265,5FF5672F9FD97C61,33E8E77F669742DA,0000409403E13816,FCA3FB4D3AC03080,C4B7DAD73D481EF4,324EC7D97AB8B010,E488AECDE96F7884,9324FCE0F39DF11F,61E0F1CB70F536E8,D74EB77E7F438B5D,01AFA03743899D1C,AFB94F1EC5587C72,B8C5F9EC7E10E9BF,E0E8B531981FF93D,00003C19F7FEA52F,1AE7A656F531768E,C2F16F844136B0AB,FD45DB52E98BE056,B7640D1A6A923F09,96124873CE617DE4,0CC8999CC30479C5,DCEB69508450B666,4A2938C37060932C,6E4E8E1CAEA4BF02,4EF9180C9C1310A6,ED1D4A7F8BDDEB13,00002026174437DB,EE37DD300FC2522F,D98071DF317FAC14,733E6B902B82824B,80B2CDF7A4316CED,C8A2CE8C100D4C0B,936039FD36EA4300,A62BB8F39A3A36F9,B650C320AB8B0488,3D8D5640A3F672CA,036686ED85DFAB4F,784C5E5773166718,0000143C67EB64E0,681985EE578B17F2,F0E3618F4DA1E586,1F0001D78E6B2B2C,D3484B039A81451D,BDA357C764E4CD7B,3C8863F578FB6043,1231FD118789158E,51AA3BFAC201252A,C0A976B869A810C0,65C8D259BC0D68A1,6D9568ED37010776,0000072ED0ED5904,72B28B6F7E1BF9CC,CB55F76821A29C5A,420663C36D2A4183,87F65E0FCB0FB277,E0A46B77C92CC322,020D710DC48FE226,DB8DFB5EB550FC0A,C75AE39381CEDD79,0773CFCAE9E08996,EBFDA8876AC21445,FDE60CF4EDB47B83,00004E4DB3E799D3,4E81F891FD63D911,A741137221E50933,A722487253D288FF,54ACB1F0842E6768,BF2ADBEBB2F8AF42,90149E59B076AACF,CCC630AA26502591,6A41917F7C2342B5,F33BB7BDF72FF0AD,18D448811594A90F,3BF8427C2319E2C3,000021C1E6B20C7C,2A73B08D5F2E610B,4C9BEEB4DC7BE9DF,554178A87027EFA5,561B70F9B5C96348,A19F39AA70166894,3E80CDDA2D77AB2C,B2FA4A238846C3C1,6F7D2F4096D7E544,124C3F1FAEA802A6,D6894FC8597C95A6,6BF2CE04B31950AF,0000276E067CD7BB,76001E8DFF24E46B,FE22F9C7EB5104B8,AEC4664C5EEABD1D,74172D25FF93A576,9F5C781CE2150732,0F2409258E7AFE9A,D032364E8B5B49CF,2E4D11C903C0C631,BD61E89BD7E07630,CB7CAED727ACBD0C,DBD4746D238B7BC7,00006DB9ADBB5BA1,8560B657E2986A8B,6C962A4C03D297F4,C9B23CD27CE43BAA,DA37BE1F694D694D,38CAF2D89329C183,B0C9703657BA8601,3B2A39C62ECE28EA,4BD6325EC4240C0F,E7A01481D1A1E7E4,4F72E2338CB95F74,8326416EF48FD45A,00006790C8B676F2,A66A3D5E57A6AC7D,E6E83277ECCA6DB0,E697155F8C4F5304,D387B798E84BEDAB,B91171E830F3FACB,A89B397471D31393,3C4B4F0A763F911D,BBF2FC77F28BDE35,81BE3F4C9EACB4D8,8D6073580CA5135D,C90FADE6D128FB9D,00005C000A38C272,4CA7FFF260FE205E,C50AF479A3A099E9,8207B2E0266C32BC,45D4C61C95AAFBE0,19D15394C13E1FCB,E50A60B303B0A983,10A7127FAE04CCDC,1C40402B39E0E0DD,EB0549688BBDD3AE,99E8E8FDC9F6B0F8,35367C284E2577B2,000041A90ACC0F4B,B07CD877943AAF48,AFC184E76A1E2006,B8FD4C987CF96C64,F7C71F4B4008C49E,9261931BFEF57FC9,496A0C13BE528690,60EBEC34BE5BB11E,9A6663300E92C1C3,70B902CA85B228B2,83BB42ED07BD3815,29497DB7566F983A,000007DB50B3B71B,B6BE5DD7CDA70A69,5D4EB5F2B50CC12B,BDC3528931DA50D8,05F3A56F1708C5E6,2A2D6E3ADA5DBB6F,7F61DA4999B94611,041E6C5DFC9481FE,CB929DB1E0BE0951,5140E09213D96954,E831A0CD959065AC,5E907211733F48A4,00005925B28C95BC,816D46F0B1B3ED9A,6C204B7924BCD4DC,C00990E8C968BB89,1B7B77AAC2506EF1,EF2ACDDB3350B8FA,92388F8110098EBE,2A7348C224A4393A,2A1FFB53A6079AA5,37C2C090E36AEF96,BA82DDFF5D789BD8,61A97BBC187C8A1D,0000398217BFC501,8B3F4D693ABF96F2,6D1C76D00D4A4652,91D9C86E1F21650B,1D92901DF064C416,862244CE926DA464,3A02E9215D854159,B0FB48E8A3510446,60B7EA6AFFCDF85F,564A14F309CD30B4,E08BDA8CE7B8FB9E,95BECED29282B5D6,00002D804BC3B29F,5D2D8F35999A5FF9,ABEDD4AE6CF958F5,A6AB3A758480D00F,0540B7C85A7E2ABC,F7B99C045B8B8DAB,FF9FD874BC68263B,C83920ACC3D4201B,0F2095CB648DA8D9,379F653765B9E593,7EB4D52B956F4795,3CF88CFE73855C90,000010C035B09789,13F830620D0836CD,F087CD72CBAEE365,167F8F3F1268955F,53523247401D36D8,4B193A512926A9C5,B6BD0BFA49964EE5,2B7CE66F7294A5AB,1F3B08EB054E1C64,16460D1BE0FDA33D,45C514073BCBDFC9,635C53E788BB23AB,00002A2BABC619FA,978971D016BF81A7,0497D5D23158E566,99E0C697933B76B5,E594475422DE7437,05A7CC5B30766AC3,F703D3EAB5440E80,B06DFB180F46C12D,16F2C2CD96146067,38001E3EA83C6077,F67EFEA84F005F4C,917A3AD9EA14CB74,000066D2197BE1A9,B6A37CD271C02679,B7BFAAE497BC6850,E01D31F616331310,31F06940130C1052,3BAABCB79FD30FF5,8678C8C578C04CD3,536D9C4CEB4B80A6,15617ABDA8F183D8,4920F8483670459F,E7317D4A3E041D82,4CE77E0A2B20105C,000049F93270D3B1,D28F0A5902CA05A1,0191105B288BB4F8,F2B93AE6FA04809B,609AD6399BA42E74,6BE0D0497E4E39ED,F247692D49C7A982,68161CBB6E2452A8,12209355CE37657B,7A5585D3FD88ABB3,AA1BE16D2943702F,69957E2AD87F4819,000027FC1F0E2191,491D236A8F5BB37D,506CB049DA1697D2,464175A6BDEF259F,0F7CB4A777CF7863,7B0F39E42902F94C,1FD4A7947C0DE4BC,B95A0CB1178B9145,A35A0AF03A7933E6,015D678017FDF488,AC11AD98CCE8BF41,389D04566394F8A6,00003471395687FA,8E8DD9B5C4DB3FD6,C25062BA8D4884D9,57071324FE91AA35,8268357BC07DC570,748BB1DCB57B59C4,A96E5E52BC86FE69,10EA00FEC6FF3BD9,A9FE09D74017ACDA,99AFC920F5A8F587,A8332AB08742F760,A0A9168F618AD348,000044F44AACEF83,85384927283DC843,81875C6939164773,1F3F1C7884F4C559,801C964702D8A001,542170DE44F2A3DE,A9BBF129B9E0554F,DBDB1916ABD22BF5,CE5189D9685A1C95,0D07754954FAD3AA,37AE4A3EC96532E8,7C5AB51F7F772F4E,0000267F26FDCC78,BE11333043247B4F,DBBF099D0961DCDA,F94BA2DD39EC1DC6,40960D66AD14EEB4,4D5B3AE46976F699,4A0D6762F670B2E3,92D7A0F76573FE20,FB1091701B815269,73BFDB786ED9E64E,40639E1A124BEA5A,C262F6A4D9E9F5E4,0000573D871ECEAD,7899DB38CE366B87,E6AE9C2E2F67AFFB,8690EF6E4262401A,617EFD24FF616930,0CCA272A0C5033E3,3D2FA38EEA5A15CD,7DFC22D7AA3FD782,B6AF328458F74ABB,0114678ED8DA30DF,501492E42CEA3EDA,DB039D1B7F6B3499,00004AFEF935807B,2695707C44405820,FCC9E56F7264A955,C30AEBEEB270FB58,AFC6C355B9167BAA,44EF259B8C52168F,1EC05FD5F59F2799,80B75CF897F5700B,556E4C6F33FA1D06,C3C25939790D3966,0D8F75157FBF8CFC,A65E4B3796649B65,000065C9BD61AFBF,5D9D808E5AD9FB58,43DA83E4C09D6BCF,21B321A210EB78AE,D0C60748CC4F03CF,884874B2458EDB36,0010B2333C34E65B,039F1CA38E430BD9,3A320258B368EEA0,4400142C3F6843CE,3085115CE72F700A,56AB6B0F57209A40,00003ACDB7B21B42,3FB693A8D2EBC354,389EA9FE4DCEBE51,41D81D4E544AED29,AC5892285C989321,C9E5A8B40B696A6A,295C575F49C63A55,7FC5544C130A6190,4D98199A9837944C,DCC01A62F4A947D1,AB1F9B42C2E2BD42,4486D8F036235E54,00006EC579A06D6B,7E751DB16E472A5A,50FE31F9720804CA,A9E89B72372BD886,D30AC56AF74C2E58,D291A09F3A99FE12,EE8EA6930E681AAD,801EA6F1417C22F6,2B1FC0BBC3B08715,066030C0E85194A6,613D3C1663709283,5576BB5515AFA4AE,0000585F2F17FA02,E288511C93FA0028,1B0B601E0DE00997,AAB612ACD0EAE0A6,3F2803E6BFD86943,6CE11281D052D07C,9133CFDE6F3743A2,3012769897E2D6BB,05E727614E5E5202,48CE3FCB210899C5,34E84D9240CA2386,2E2FDD3FEB48E80D,0000366D3B394A68,04DE7E498F1880EF,36384191819F9190,02121B3F2956734D,BE67B4A81CAB8B02,C965C5D7911ADEC6,561FDFCDDA640D7B,A49AD4DBAEEAFFBB,B7672747C0B503BD,3C2CF502AF2A2A89,E3651DCB472E2DD7,7D1FD03B3FB0E6B3,00003BD51392E49A,3735B35C3F8CD852,EE30EAF45CCBFA22,DEAAB55E92F43669,96E5F9145DF0DE6E,498864E94ACDAC04,A7C07BB46418387B,6490203C795DB8C2,DB527561C5840456,5EAF17169C984067,EB1984A93D96C64D,312CDBDB8D14A4E4,00004AC0DA1C4DBF,38AFE675B2F305B7,1D99AEB7C46575FA,5868876339C3D8D9,003AE36739E95DBC,F504B3A023D4DE40,EB8C73ECC037C1D6,D9679F92C617303F,F6189F36D8F2FAA5,347B4E256B79D25D,8A806C9E8E800BC8,4DCD2DFA02B81D62,000036139336EF88,673A51DCB4D8208E,83023F11D3F12482,0DE002C16FE2FB70,8B63F14AC6190309,D9A4C4474D62ED84,9F3FA6AEA83A38D5,133B9B30F2C48172,DB3E72FCBB2791AF,F352FBABA7BCDB15,DBF190923AD66D7C,4433186D924067B8,00006731D2490E78,0BB32A7861833741,D2D3277755B8921B,DDF20AF6FACEEDF5,3B841C0E7012456C,9A3FD824FFD95518,1701D0FAC96B0CA2,1EAB56DB4135E099,AEA4BB0A57DD5292,BB9DB170AC28FE6C,4AFFF07297E7CAFC,C33CE73481261BBB,00003142AFC99413,57822E3EAAAA8928,D36AA4166F6CE1B8,316114BCAF856B0D,EBAE88B4F4451605,13D277789FE8996F,C01523583CD6C0F8,351F90FB7F7E10B1,0CDC9791029C7AB8,17FCB1F00FAF4D11,FF3F120B175F0E85,1D1A6A4C5C63D5A1,00002AE926674A15,515584D2342DFBEB,5C1C017316C4AF74,CB30B3BD0A0C8665,9AA81BE2E0E4E429,7AAAFDB990309782,9696122A4AD0CA53,E5A0A3C8CF2C1FF7,661B8EE683A75CDF,82D4C448B121FA86,B2272DF310DF561F,B6283456D177EBB6,00004C98246B705D,9971B15BD13EB2D5,62CC94BE79F6E9FE,2AE5F6353A14F4F2,05EE12BC7E9C236B,0BBD565B1BE683D9,74E94257CE0105C3,9E7ACF8F621B626A,A5AE8467CA308835,A0AE7006B513DC5D,208A5F2C71D7B575,1EF0BAEB19138C66,0000415485D2E3B2,D15EDFE877C08005,A27F90C0BEA209A1,FF58846647265EAF,392795CDCC055348,FF78DDD86B5DC541,619626466E6C0478,959BE17671123EDA,C9C63667BB2FE7E2,968EB8FA3C2D31A0,16C65E055BFABDA4,79E9CED3DFD688B8,000003DADBF3355B,2D70F2D2A1976939,7786858A86852A32,2C1B9A38D72F1E20,6C7D79D261F3A485,576CE52B74BEBACA,A2855263F127DE84,0CFDA8D73700A19A,C5704F8AB30BFD7F,DD76DC624260E02C,F7A1629617C13CDF,494715C54A1525B0,000022E8F507EDFB,98D695213298E09B,5D7324CE8554C1B6,19D4E65DFC50931B,5ACBD11B54688E8B,6BC7327B922BCC2E,4DF40D5BDCEA1954,F1DF7323CB3EF0EB,F78FE01800D75FE7,9BE654F079C65E91,4D8E47E188F678D4,C303A8909CF71CD9,00003EA07BCC8CD4,AE9265DAAC2A543E,0C2C7C98BCA34A30,EAB73DC6A562A817,EF75ED6361BD10BF,40F997A06C66142D,A7E614EAF73C447A,07EB598FA672B46D,8AC444135B21908C,FB4DD5F1D77A5844,A726414080E9380B,6EEB93BB0524082D,000014C79DE4B02C,27528DD804B81BA2,C9408B862EB2BB89,73A4E2E1695CE5DF,6C270DFD693DDAE7,80A8EDC52B14F092,077A84918A7E2DCB,76A6995FD4370B6C,96455CE708E57359,36B4BEF9A22B292C,BFC096A07566CA82,2F51A73F8C049617,000014E082EA228E,4B41BAFE45CA7FF6,E185949653C82374,E2999DAB23BCB2A4,D30705D6840924E9,20520F653AA783D5,5BBF9784F3CB3141,B99C4D95DABDD366,04C4183235567591,E9B60DA36113B8FC,014561C0C78D3A6D,D633E16FA3823A28,000034BD06F103BF,4450F8E1EB223487,124F58AA9FED6C2B,AC72B8A74C9DC4B3,1589086DC3F7249C,371CD014F7D56F1D,BE4A80E81F620AC6,A03ADCA410225212,53E32DE30C5472F8,70E55E059F802497,A398E50413AF33D8,66109FD247AB3443,0000507F33ACAC5D,3C089121530FF09C,B1EE103783FDFB9C,34178787989964F9,EB9FB448EA26F50A,BF26A6BE41BEDFFA,084DBC37E3FA5326,782434B21A0B68D9,67A473A5D1AF822E,09B487E8FB29C903,49ED5A9E0AEC3F0F,BFCA4CEEA73F64D9,0000186A64D5B909,B6D6D5A589319878,62C8BE8EC8234329,4634C8B5AE4C419F,4F6FA991042D0F70,4E5603AE1EFBC96F,0CC092C7D5CF5593,D9B596C8C220C3D2,6D17D3338BB41916,3BC6ED232FF62DE7,E9AE9EBCBCD5F3B3,F91413EA25ECC19D,0000362BF8452966,76ED037E189816A2,085CFE5B44EE2271,D5AC4BAA91A58455,5412FEA8E12CD960,E44B15E3D5D1A690,C17CC778DD0F6C32,32579696551C6B94,5C9264CD81D431B8,6FA341F911DFF66B,D6F8CC0330465926,C404DE78FFE8DA22,0000247CD0D49185,B290A30EC5815CD2,6882DC04C46DE18F,F86B512B7BDD45EA,162EE5EF42312733,B18AADD23DD1A492,3E57A7C1C77AA605,7541504E92F55EC9,D3A95828A726A2C6,5F6191DA6EAC46FC,E4B012586200018F,4428831A9872BC97,00005FFB907C508E,22D57267513D985C,8D7F7057719760D7,D1B0B414DC150D5C,ED57147B9E02C584,04F07E42A99DDE56,CC3283D2739857BC,19035E9168C86F51,7AF6673B8597EF9E,8CDDDE6EB36C9B29,4387A0567A347E54,35BFE51D2AA894C9,000058F2C626A972,AABB3AD1B54DED6E,90FDBF97FAA5EFF5,B1665FA7DC260907,1CFC149E56BB6FA1,1317D361E3B82110,C92F94E82A6E799E,290E2CFC151589B2,CD468158134EE82A,9557133D564B84E5,390648F5E837BB7C,57B480A75D2F8A19,0000115D0FA7FB15,5054CA9C93E84F24,9A96F3DDC8C3779F,B85804A095B4E4BC,91B3897091A7827D,28A84B3666336D24,BF11A21CBB26294E,ABB36329E21FB758,B94BA7317661E90A,F502758FC9566725,04D79BBD68112137,0D39469F859AAD7C,00006D99B74F70A2,D29C31343A523690,6208C18376CD57D5,D88C3249BCC33099,0B448C364DC649C6,92EFF83E268E252F,785E3D7C9C62D482,A0CB3F2A10BF48F5,6614D43F3812CFE5,F3D5609B5B80B775,30BC07FE31215B3D,EA71E4A8D799F091,000062FD7CB51CF5,ADB77FE82A3F3720,96AB7CBECD552954,767D6A01E17D457E,40AD418EF40C9E84,B651129C86F2BBA2,C29CD9E60412C1D4,3A7241B3AB4DA244,A606BAFE0DA9CF6F,85C8FAA580BB0619,6461324A4AFC0B5B,C0D499434B4766AA,00006FC99F89F7CC,AD3994142ECE27E2,1C51852A13E0F8BF,9954A1FF3FCD40B6,880C9CCA670E70C0,2B1173FA69171427,7021D33C11BC7D5C,3FAE4B6391D778FC,6A6684EC327C3825,2726D9A870BD81E4,EB5A6FC1233F8676,EC4BA10FCE42F4A8,00001A4946CFA44A,03DFF95BCE7AADD3,3D0AA39F8D8130D1,3C8933AD4803FC25,6B001DFCD939A14E,1E868B4DD80BEFF8,66ACD62A212AA1FD,C0DC0D32F44CAAE7,EF027E22FD176898,2536765F9CDF5475,CB8958B4A840DAC3,1898FF45F10B765C,00000AA2908B8D0A,7BC4546FD4423429,E48ACBCBB220C6A1,4AD83E5D9FDE8BA0,51E035C6E3FA7ECB,A902F880ADEEAAB0,4DB00F06CDDE01DC,E33E3E9B69496CF6,6E90481F3DA521EB,CC06C36FBBEA8367,D2DC0FB8022D290A,E73B7E57E2EBD5B9,00004E79407DCA2B,1173DE8E65D5D8E6,E21C945BC2140488,CD780583E5A32E96,C257BAD47657E851,FC6178C6D6F7F811,EFF29D71DF3B76FF,511291F6543CBA6E,C8F14CE3172D4513,EE7DEB3BDF4179C4,35645858787FA13B,F8D6F96C5C7CE050,00005F7CE8038D18,D43C9C1DB0BBBAAF,4F2882CC8DB6ACAC,2BCD859E418AD517,02E09C15F40834D0,D9B0A12328747FC1,E13A520D247F89E4,8BE71ACDD471D4B7,FA72F79900D5979F,30FA2CB71BF7297E,28AC973B77598104,246054F6961726B9,00004A6E87FFA004,6CA5C0EE7023008C,21F82B9F3990B243,18DB73A77C214D99,8795B162C6E4760E,653F04DC012081E1,48A69BF1EA984CCB,620C8BAC8BE04AF1,A496040B5CFF1882,C026003E1EECBD31,5A2498371EB1DA0F,CCE89A69F650C659,0000571E250FC1AD,D7BB697271AB50D7,07C961F4D7465DCC,5C9444F1C84EE403,8A922A0D25114586,499C7AB62EE013F6,6FB80A9F3904D2B5,94BBC4618CCDF150,FF70766507E83630,E664D461E333BC33,E0BE911F5E0C90EF,0FC90915C36A80E0,000038ECFBBC46EC,49812D38006D0F06,9D65E48761A7B5FF,A98D40ABE7A6FDDC,CFD1C44A60D0ABCE,B6885186D1F17BD6,BC9D6B2A0C8260AB,0EAB476CEAE2DD82,673E00C70E04E26C,E0EFC56F12D70554,BA2FC3B910A031D5,9E0C9E9FD2C5019C,00006A27E62F68FC,4D3C8A9C168ABDA1,3F3DED9EB7687E03,0384A3683B93E80A,6EA039B42AD18D1D,53EB4AF44B9FEB41,8E5EFA3B3A611D45,C2CCC21AEB22DA61,0939C7AB524C2B37,B982A5DA707D3CC4,B6F7D6305A346987,E766B2D3B0DDBB28,00000EBE40377879,76308560F226A5E7,CF90341B5E0E12B7,BC231FE73E0610A7,F301D1BEC99100C8,3332E990F65ACD10,E9D3577A0C43E942,D16F553864824A04,BB45BA7BBA2E4984,AB76889BA7222BD4,F5A790822D77A812,591BEB5353CA4851,000038EECC6BD868,B9E6055204B0CF53,E64DA173B94250B4,9074614282EF1E38,845029FC0FE8EE88,9C057FFAC1CBBD4E,9A04C71E979B059A,683A960624078209,357817E8FE9E204C,589429481FFFD151,CB078E7022D86C29,D673377FE0FE52B1,000051CFDC702DB6,06724EC3835D69F3,D9FB74A8A9BD05CE,8DE87E5BFF7BA2CA,A1B1298B69F17170,0EAF561EAF7D0A59,753A0EDA97EBDC7C,CD3E0385473F5891,B1319A897D20B2F2,3E4D957BDED7DF65,200252BC34E0C428,E3A740E45B7EDEEA,00001328D91FDF23,4A00896205E42A78,2E7AB069FA3E5528,DF192F18F462EB92,989D9ACEF268CA82,17CB812BCBB6944B,49C96DFA655491A1,7AF0BE3A74C71ED8,6953C688359A389C,4FF14E318E1F427E,C8A5123644AC095D,F9F0B2C8A1EDAD07,00001EDB5A9BC325,245AA7D8F7CB58A1,C20B6D1A5D2A6B88,27ACE48106911AC1,9EE4101E0A5EFBB8,BA55E40AEECD543D,3668149F25DD6158,0B84EE938ACC3FD6,56D5C40903C35D90,C1740A5D8E7F9637,F2C61A86CF31BB6A,D7AB9B9ADC8B5562,000046FC2C4F4040,C84B233DAADFD510,1007E3CF0486859D,9D8633A4DC15A239,E86B16B27A980A74,BD5F0F793542E0FC,910ADF4A239DFD24,E8BA880308EB97F7,9AEF2CB42EA251C1,A63881F704D7B23C,FA7B98CC15ED57FB,6EB3FA054D0D2731,00005617F8578017,A04E2E1061CDFB5F,4F947CC1DA146CD8,36790FDBA33F4020,FCEE3A2732B92927,70A2BE840CA75BBE,8446E8D33F23FB1D,281A2FE12AAC62B5,75EE7F2E45A79022,55BE7BC56F02C659,3949FA6E8605EE54,FA49F348E45DCCC4,000038EA4ADAF6A8,2DD0BB5440167787,CDEB2F75EC6056B5,7E900BC3843191E3,AEA9718F71352C02,508A62BA304663FC,2E0A783826AFEDB1,3158C32EA8DDE50F,DC5E48AC42EF8CAD,51094EE4B3728FE7,6AD5EE92EB5F523A,59B21A5206671804,000003425E5BEF1B,51C0731F6F4A2417,70DD9548FAC9A3E0,E307568154573BFA,1D58F46C4342B574,5E190B296C2CF3D6,1128EA396401624E,4032E3F5D358149A,4116FCBEDA7646B1,17A545115DE24A87,AC838F01FA198507,BBEB23A3F186AEEE,000030650ED5EFB0,DF9F25995FC05266,5E73DB8E870EE67A,95B603ACD9B7F0E1,AF3051A003501422,CC2B8F5F8367B383,9A7235E9BBB74998,79391BE145DE249A,B3597B593D3D37F8,414CA6CCD4551F1A,D291168D13E7CA0F,B4785D166F1B15A9,0000645ADC590D65,1FD263B450FD45CE,F29464636A1B98E8,C5BAA32E90A111AD,0660563E2EEB0BBB,B6F3C068E659ECCD,24A1A319B1CD8B24,4A70FECC767A6E90,59D65C69B98FAACD,E14438A77CD407A7,CF591B4CCFE05710,EAD303089B3C5CD4,000014B2366677EC,83D3AB6CB419DCD4,D0B2C9392418C805,5A71D431AF3A8312,4118E9E5093EEEC3,35E84F9BBC5C66CC,56DF69F7EE6BE715,0BF48CE3D13C4C81,8B402CFB7C211D3F,39D7DBDCF28E3025,EEA194E4C3AB60EA,4214BE195EF08E87,00005F26EE93982F,6889D1993E9203C0,F3745F3F3C196469,465080CD3D5A8A5F,ACB9E6E48C709106,2814CEB61961FE68,49EE0FE4901B1B69,86CAB4FDC28261E9,069750FD18D3A32A,6DC55030D800BDAC,F591E62DD2AC28BA,9FB33324446DCE29,000057172C31A969,923C7CC190F1F81F,6B4E5F8099B3603C,4D70F1739556E1D9,5DD37662FFB77514,02CD03F99F54998A,639983B35A73E4F1,55CCB6D6CAAB7BB4,A1DA7841CCD38093,393D26D4D1DB6614,AC7129B826C32BC3,34561590A841E519,000005451308B65C,D8C3F993FC8E5F8A,377816C607AF1FB0,DB5AAA017F4D69A2,2A147AAE0E9996D5,0F215CBE1DD23650,74FEEBC67A271B6B,6D52E94BDAB3877A,A6D6A9E4AF984A48,F2FA486CADDFC1C6,54A64C91E5BFBA6C,92A6796922F88D07,000036B2281D4FD4,D32D80EB97603917,11B2B7E842E2BD9D,5E3FA38663B79F88,DFA96D009D17741E,61BA116DE6822F31,A51B79E3234D889B,34EF4C615C36BF4B,B77CDA1030F441B4,6F0F8098F26DA0A9,13A6E5EF73CD7C70,7C6BD4DDB47E0851,0000340F390BCC32,95848B5433325941,9B74F16FA02F8C2F,DD598C9686B1AC72,54E7820977FD2474,38D6D778453C7B70,503183787D18E6E3,D838A32F51F12723,C558B9713C5AB368,A4945E120C027B8C,177648FA94C739EB,871166E80192CABD,00000D79DF5150C7,A7BAFBFB3008779C,CD61DC0C71FE58D4,C213CE8A8AD634A0,8E043AECD36D0B2F,BD741400F8CC3BF3,72CF186B72B29BD1,797EAD9116254E6A,BD9F00B34750FC2F,CCECB9D691026588,3D236B8313FC4D40,015DB1D10862EB9A,00005721E90F3731,DE727DED3231BBDD,2939BFAE03974171,C68F3BC62E59557A,1D8CB21B610406A2,482B149D5B2CCB6E,519438A007A2AE2C,14C78AD31D47CF43,A99CCDD87B96C362,7A2A698448B74AC5,A261B84B9E47797F,3C56BFE7ED6C4676,00000BD4E362D2B7,44E951F91D6F4063,7BDDC8E9D663C6AC,91EA65F85F599336,B61CCE2E5827C681,BBCBBD9560D59429,276DAE8F73C4B3E0,B3D322512E1E61BC,11B6299802279A71,96FF8EF969961151,3C83769C7D7ADA7F,F4485B621104FAC3,00006FB217A7D9D4,95B2942E42FA0360,636262FB56E79993,4CE7DA8A9CCF30D6,AFB5CB1C05E4FA59,73D382443FDCE427,0E331ED08AD5B59A,97DC8115739FA18B,2E5F6CFD4AF75EDC,15F993605E78252A,F17008F4EB3DF480,11975C682CEFE1BA,000065CF1F4B789E,D7F0CC5DE7A8D383,A3FAF9EA800E0CD6,ABEE2810573E5FA9,77EEB5508BBD559B,DC794F3E2F80936D,28A7802EBD84EEBF,053D091CEB215C8A,66E9313CFC3689DC,3E9A85047329D4BE,B48ADACB298F2BB2,624B67907623BC22,00006EAC1DB65908,13C73C03C2FA537E,9AE9A114814BE3A6,EC2243DB6D18BEF6,EA37E79AF2879E94,569021C9529B2D1F,B1369EBEA2E223FC,101F1730C1E80823,321F07B65B959583,8401398784B20650,1797CF197C504A63,A121B626B5D16597,00003FDFAD8A47F5,C80BC6378451631E,68CE6E66BA5BE122,82B78C59749B7E00,D3166167E4B8C3CB,1E0A1A7CAE64D6A8,3BF99A8EFCAA0F55,E5F4EAE0AD99E62A,6080E799036FB286,157A4E2979B5030E,16C4B2F2EE5FD826,0642C0AD1A970272,0000435A4AEB8C4A,5058F7FF47B9CEC2,6D936B05629AE35A,91BB934C330E6634,E1F17C33C53834CB,8CBBA08333B2037E,70E06F295F1413CD,1AC93F21330373EC,ABEA991D1B16775D,5A41AF626335D553,792ED086E660D95E,D76D98629E783E90,000037C3EBF9D121,EA654BBBCEA5A62A,EDC0B30940DBF8D4,50BA0D5862D43971,8D15B6A47603ACFA,F090FC3A06FB5FB2,95FDC44FB08FCBF2,B2A04C0F88EBC637,90FE828834652611,BB14826D5E390A66,CA78041A15F41E33,3E58B81EA179DAD9,00000748FA9ABE92,15A0692B88E8AEDF,91E8FDB40136D18B,2DA082DA2712D2A8,0569A56C7451AB41,557438A00306834C,05965CA8BED8277D,66DFB71E20309A57,F7EB167DD68AD6BB,DBD700EA24AE754B,893D5747B9EF7E08,61A2B23E6EBDECB9,00003C36292F5950,BB6AAB5A13ED6A7E,E9DD3AF025992F61,1542A8F3595A14D0,0DF42DA99A529F18,153A676DDFC206EE,749DBCC6BC5F72A0,C4DAEF6E93AD8481,0A7C8EABB5A14F1D,D2C4C0C0FA5EA077,7F5AAED1EDB611BA,586482317465813D,00000C6B29972FC5,4A8DA226757A512F,33F01D246FD62610,874B717CB3EADF85,58063E6AD1686DC2,F248FD4362F0384A,F743A0C42CB7E57D,8B184A6E4D56D1F1,12973218516B3CAC,5673CC224873E693,7B6F481BC2775344,F27B37BEBA515B52,0000478858FA6DCE,35D98A0459BA75B4,D44417FFA7A501A2,00E01C599C9D16B8,4B6A64F153F9335B,560D58233D5F0375,A7B964FD8AB6D9BD,BEBA94405F3B5048,A39C3F37D69C3513,634973226F1C6F64,82F5C977F4318C13,F6D4BB7417CEC4CD,000051F5BC27A1FB,CF60C27DC4943A3E,9FFEECF755111E7B,0E251EF4665DC2DA,33A502B8A56B2194,48BD51D434391F20,CA44FE30C3B92260,FC6674DE7254A515,54F10B9307029F3E,77998925011B380A,2A6C2C5E6BD4F39F,068BEC9572BE1671,00001491FDBC4AAA,0591BB1F1B0D68A3,94205E4C540BA40F,48FF974FF74D8BF8,BBF6ECEFBA80444A,6213A79D3C17B003,56ED19C0DA3E4A31,29AB5CD9E3AE9382,C7B70417B03CD37B,456A61985079180C,517E4A6422FA3148,400D3563B6570573,00005AF61FCA814C,275E5ACC05D5BCB7,B44A490E08E5EF80,B886C1C0C8A5B24E,1D4F265DB1E0C32B,B86C6C26E29EB427,BEA4C45B585CBBC0,0084B37D21DA52EF,5158417BEE691673,E9F0B57FB561342E,5D6C714A1F84BBF5,F839EF607FBE4EB0,00004436FAD0E72B,1AFE3AF740F45E0B,1EABFFD21FD2E388,EA83BF5CD6AE13E0,A32416DDF4A3127A,E0B483F8F2A43AA4,EE6759E58B8649AA,316E18AB95EEF59C,C0C4704DAF5722EB,21D4CA528BE8707D,1656E312D390B556,DECB8648DF13D77A,000004B0657A459F,933ADF34D19308FC,A26CAE8FEAB9653C,521F1D0D78AB0262,6B7F261E33B2715B,498ABCAE0A7D9DAD,9C68EDEFF550EBF1,4B1C29B0F7A41EB6,F6794153986839C3,A807690E952B8951,720B111AC66B5DD3,575948ACBA8EDBB0,000026A1BC076364,D17053A22EC79232,AED2A84BE9F2890F,5EDF478C599C7D8C,B457C58FF83565B5,6A888B5B5903E142,4F15CAAD5F5F3D07,628111F2753C7E7A,AA9B0F8BB079E046,9EDE8A46961D3666,8A91CBDF4E51D706,1ACD2363503140B3,000015A43FC1DE39,746F6B773EB0F483,F1549402BAFB0FF2,97FC77EEEFB89E5D,5EA15F0318B0C2CE,491943E740ED1FCF,513F7EFB716F291D,BB355B47ACB171DA,65E055934CDBBFD6,ADDDDADEAED677C2,D4E8575607439B79,F6EA598367AC629D,00003D2C6835ADDE,0941E11BC5117A7D,D6EFA72095FA7399,9ABAD75850692BAB,E7B174B66007C5CE,1C6F110E8A7D8756,8B0F889C5508A406,A2C11F24C58A6BD5,9636C7779BA17C3A,6F4B9DA516B46A14,48D4AE842081B09D,64DBDA4D39D00EE9,000054036A75F7FD,925381B7AF65BC29,78BCCA1AAB7FC852,9E51FFFF08CD2BFE,2F5FC1C0016B8AA1,6464A4745A4E846B,8F24F7B9522D5A77,67764401996B8446,3F6374AA75F035D0,2916066ABCD73F8F,F2ACB413986D5A6C,D53CF89028F77AE9,00000DB90008E7E1,0DD3D062B3EF53FA,EA72CABF9F4D34C9,CCC57019261A561B,121FA89735111F76,2F501944CF43F72D,02D20F0C05636696,CEA95250D61FAF3A,2F1A2467DCF6A34C,986FFBA7AB1B4DE7,B71D37610AA18B3D,CDBC6290030124CD,00003F38D9D4C92C,B65D92D95272819B,667CCDB8CBEF56ED,69974E5E2CCF19C5,5E07DAB339D89AA8,888C6458D7CD2604,5E5407094A284F15,D3C1E47A3D1DC8F0,F8B3C3D5D8227787,8F6CA3E065E8C53E,FC2875D4B237C483,85073284AB954C81,000028626E50EF6D,15D70DC7ED00E2A0,A765F9C6A2F4508D,F659AB099E65279B,C95A76F04B4F9FB7,F04FD9DDDB737D05,335F750B6671724C,AF633BED04052248,8FCDB005D10C2508,6ECEE743E19FCE99,9C7B08C3C64BC6E9,992B3456F71BF53D,00001704966B160A,EA38BFE67DF16981,79AF43B1E3571375,F469C21C91D0A371,3C99C6B233FEFDBD,F71B1B8F4B8049FD,90E029CE98A9D41C,488C4BAEDD49159A,534BCBCCBDE093F0,88E1472EB4F16FD9,39097E84037FDD40,52B8179F4CBB1D70,00000BA6824A560D,02DE078819638954,860AEDD08EAD1A1E,D8F52D3BE4DFB69F,11F18B5E6095083B,70CE5ACF77313FA2,53FC9FDABBA3A182,F9AD362E7A49F70F,E99EE94689F869EC,A406B1DF540F2455,0C1BB963606DDFA7,D3D46A4ADCE23C23,000051305BE60175,0E7CB962AE4F2AE7,CAB3CF59793BD9A3,0B6D9BACDA651B97,FC06EB0B0CC6286D,AA9651503E062589,A46D74484808F97C,83DFE5439F43A881,A97DB8BD3BBD90FC,1BEDA0B8F9CCFB28,C4D28836AF24C16F,DCB9EED154C64134,000041A18D3522D7,13F533A0F9B17057,1C9A3428A961E0F5,6EE7BE14C5083DCD,8A02B03CD6F8A5F4,F20034DE8EB1AA0B,AE0173C9F46E12D0,649A2E11E9754666,12CE6A1AC9809BF4,6B8CEF7DBE70D2D3,FF6B1A4ABF90CC11,34D17058126EE1FC,000009976B16BE54,75BD079F0AE8C7E1,755E9451393DFC2E,6D09F4A27F135C8E,AFE138DA71570A0B,3021481007538487,01BE7602FDB11C6C,FC9657E2C11A1EB6,853DFD55EFB78FD8,7AE7F8BD15F6A41B,B8195770DEF7C99C,5F2385C50E370799,0000638C6B5CB5D3,6EAF879555109434,26E346DD6BC2AAEB,20ED5AC65CF39A7C,BC1B07B28EF854F1,D77773C01E6815CA,A2D05CA3E5C2E5B0,4283279C90332682,8AD5B644FE10C0AC,CF57590FA629EDE6,DF565729E5247663,54EC2582D05279BB,0000582B2622ECAF,8BD90CB35A2C9778,83E37C7442D9A28A,7A7F057FF3C11495,BD8C0BBCADBEBB69,90D809C1A944E0D3,7A9EC0B373FDB122,25CFABE9F14C2F95,FDAE477B7BA50840,5C91047034A0D73F,561B4A87C73DBB1F,5A81AC351966967B,00001D1627F72404,F28B6264A9C46378,D83A88EEBC72800E,4EB5175ADFD4A5CB,ACFA7E95E7D05920,BD8DBD5322EF7794,23D67FF4A2C6A915,CF726E70ED8A27E9,1BB44DFF3547AD7F,EDF33A3A510672C0,CE0C8355762FCD33,11CEB6A9688897AF,00001D9C3CE670A4,7ED58208DDBCC5A6,7C948B7170A2E062,E63A831E39120D5D,7972D9ECAB1374FD,9420A239371640C2,95927709C1E85649,3BCDBE7E94F6897B,60F0C3FA53E7976A,E569DB1D7E003FF6,51F3191D24878064,E2723182465C2442,00004B133A69BFCE,D6E25F9C2AFD7DFD,578370A26CD9368C,E2DA8A5F9583FD10,E8C23F93C55FEB19,506D9723AED3EC68,9200C3AF6DE23A3B,4E61F27CC884B63E,6CFE19C872B6F3B7,68AF9AC832531A4B,95D2C8F391EC6A25,C0D56B2423CF2222,0000207E57A2B9D2,86B9164E013D9805,ABD9AC71B065E630,5B365362A36632DB,86B7880DABD1B9A4,77313590DA287491,C1B991E4857810DB,EB9010787B9CC7E6,FF0FCED1CB9A5F28,33FE94B6962C118E,D5214D12C8C98732,9CC67BAC9D02BF3F,000053E5707C2838,12FC1B8C1BD29CE9,0815F99E5BFB9FDC,176A34CC09254200,720BCB7322A8F531,47458C81EA4BE6B4,79C421104CC3A77B,89C708F2EF3B73A5,6D306AB48DDB7A17,D78C854F998D622A,576777C84DCD93D0,86D9BC168DEE1552,00002857EAAD0154,771A7F4F8609DAF4,96A6B01EDB55EFC9,33554D5C3993F042,B6CB8F3CCEE45FA7,C56218463DAA8724,9490A6204A5B5DF7,7468583144DFC126,6173692CC89324EF,DDEE0435C80BF997,ADDE0700C94BEAC8,3379D0D94B4C2C70,00003B4FA27FF434,C09F5013398247F4,4287CDAE63E0CCBE,382DC175D22A7DF1,16E32395A924DD2E,773054CC4C0B1357,E19B6C4DE020E738,5F68D21D55E39DC8,9DCEDF151E0D1BA4,3BB8ECB1EE1A3F7A,5B3C5AFB22E63807,E464011A26A91116,00000209DF2CCB06,A89D363AEEBC9011,0E41DA2333496C31,4BE9058735C07F29,3EC4BB4F7FEEE378,A6A29DB36A84FE2C,97331A188EBAA487,1EDA43EC6E46FB41,4407E67071529611,2422FD346628D8B4,30EC190E01689251,14D03B2805210BB6,00006A822AEA38E7,BF8A60305E36C5D9,73E602C31F173AEB,960A4F9F7566E5F1,B4D56A51AF5AE369,41653C45547EBF12,23C361EC3461A4A8,758DACE85804A238,56B4C57BACC350D3,77CD7263D9C72227,69CC249F99AC6E8F,22AD2E2A0A282D3B,0000066F796A8A5B,AE7928690CB820DE,EBED1F0B2BBEDA1D,C964198451E6BBB3,B478155B498BB4C1,FB09300766DD45A4,694D1D1577B263C7,97F12D41EEADEE7B,6C8E273ED194C840,6929F102130F78AC,D143AEE33F013CEB,128FAD30D4E8EECE,00001E423A48F820,79573D73D2039556,F0FA245DE3E871F7,C30885AA89CD64AC,7BFFCFE93B393AFF,5625506F3DC33F5F,7470CF79CFABBAFE,2C7D772407640284,78C378182976A06B,9ED2CE70299E6BC2,EED26CFF21581D83,AC6A280BDF236068,000003B549FF8F03,1BFCA69EFE08083A,D6DECC6AFE00C6D5,5EE55A653E2266DF,DB8E0E48A406F422,F95C84F792899874,6B2BDEEBEF924AF9,42DF83B02D09969F,B1B16D90D009AC67,EEA20BA7974DD242,3784DC9F62213B30,1801B21FA049DC59,00001258CB69C81F,2A00C7A8867F1E90,3563898522295578,DF973C7AA761FF00,C19E36745CECB295,D17E2F1B8DEE4729,3254296624C1B2B2,5B679DD9D3235718,0DCBB8D72D9DF2B5,384CC15723077F83,C1B7748A6FF4160E,06C75894F3FAA8FE,0000149A61BCBE50,092F4EDC768C48A4,2448401DE16EEE04,36ACDAFA8920CD48,0EE669C610777311,858A2F34F3298DAE,1E24536D69992380,196A4EFE017862DE,D3EC6435AEC1A8CB,573E5B1DDAF80D07,3DEB22DEDFB1DA97,2FBA1936833021C0,000000812821002C,4F870891F8F3CD5A,870F7D5EBFCB6217,148D3BC5ECB22161,AD6687F2DADEC598,2E8236E29769EDD1,4936BBAAB7FFD963,E0F48C5BDBCDC61A,07E73B16CC940A94,2D1C1FFCD4C712F5,11982889BDFD915C,795175172AC4568E,00006E4687F2377C,75D166B4A06E8DCA,3887C951626CD958,83AE2A69BC4BE3BA,089EB924DB7F61D0,4036BF1ADEB3976C,505E114109A68AC2,33FAA9B87EAC1CFB,92B254465D239536,7E844190B82E0B75,3BCA3B25B7E79F30,8D4E66DC157CCEBF,00001A9A2AD76BC7,ACAD75AFDD66346E,1F2A9D922D979D00,AFC359E532D41EA6,37D4DFAC0BAFB75A,590119B7439395BD,7C48FD33F5D7C30A,E4118AC9A2663224,4B5137A42305114D,45D1AE51B7E4AB4C,B4E63EB8126AAA23,E31AB56CB91D75BB,000067DD4C916B21,23BD7901EABB5FF1,F62626235D152AFB,D74B411DC2925A3E,4A03F11EB7089B21,E41F765114E966E6,155C48E5EA84CB5E,E566E224A9134122,B56B10C6E4083053,33A50D16B6765D49,8E7388DB0CE3ABBB,ECFDCBAD26E61C83,000023025FB55035,2D89D87E4540129B,0EEB4C802C1330A8,7CB04985BE993540,1AE4C6DD853B64EB,041BFB8D8151630C,76F13E4349703E59,A3268F7E2752227F,E78F2F24DD0A0C56,59D63E31639B6131,6A1FE95A39530925,77A7CA46568C067C,000000F967F574F8,20187DA308EBEB1B,19DA789B5DAB5002,5E214526602F757A,8E42F1A83FD0CDB3,FD1F9FBFDD21BAEC,5855B49AAB6DAD01,29DBFBFF451F054A,8550F812FE7E5B55,BC5A7E452D7804FF,9FEC45986E5F4330,30AF2D8131170D1E,0000687D236F286F,6D4A330E4CC914E2,A563751A986766E3,D5A4151DAFB3902E,ABE06A560A588EC5,02AE36B2307E475E,95494D0F108F4426,71B5DD6AD885CECB,E06EC934FF3BE188,7296924F64274E8A,94C64F9E8793BCA2,90FE4474DBC17E4A,00002761C76CF064,477EA90AEEF7A718,FF4ABE38B222B265,93599006A53BD85D,52087DFF4B6B0A1B,AB95FF4CA2804219,1C3A867DAD506870,4C5EBDA868524F67,DD4C090005C77146,A860C720E19BAB78,96817D67960D7DD4,10A234FFB2F4855D,000028624ECC795A,FE5D0D5D3053D764,53511AF4ABD76E2D,94F9F4ABF557A855,0EA4FA0191F9CE06,0EA6465282E5E4D7,AA594F6BED38EE4F,82124F6334182EB7,1CFC9DDE4A0A8DA6,9EC849FD51883B08,9E110E0304B11743,8EAB654E0E268081,0000356FD11E4F4A,EB42F9270709251A,B82A6C1343865861,4AAAB65AD0D7C6AE,1269F4E621131096,DE73E21669FAB401,0B44786A1BC00802,AB98C6D812528C76,6FC16F662B6482D2,9C0F053493C196D9,0042D094EA15C3A9,40332F951D574A93,00005933F4668DF0,C08F44DD611E860E,D658580ADDB92165,86557BD45B7AADE7,E6EEFE15F6048262,16F24FDE27B3CD65,FA12F363643D7AA0,037469D2E4950DBA,57A04D2256BCDA6D,133187669F5E9976,C1CA07A854403878,6FBD50A2CA5F0408,00003FD66E09E8C1,F27E48DF7204FC9F,2A9587CF1F887D7D,4F7CD0D2D16246C0,BF6B04C6D918FCDC,B1FB8D003186B896,3C150CA180F9B593,215AC0DBC770652A,5BC8A2FEB61B8683,9841A953C7681514,F6A37BA57394BF23,C63665CE851DBBA4,00002F5ABBC12743,6110D45A537B408F,855D46129F42327E,B6A2EF5E437634C9,5DD16CB2D836250D,7E501091712B19F9,FC9453C6E2E79AEC,74D2CB3CFC11776A,106BD78D95AB5BA3,78A08915848CEB67,69DF324A4A1837C0,E18EE432A20CD990,000022C75898084A,B6D17E620249390B,1F1123D39C8CB9A9,3F026F8A0098362E,4979A95E63BC0B2F,3ED7A91A54C58368,D1CF683986FA4BF3,C3A9C6D981FC712E,D9D8555C03DBB175,4F4A51B6E44F8543,7C4A98B979DC4E70,0A2804BE2A954525,00005DD3CBBD32D9,0916B86984B70205,90006C85986DE12B,AD4A45DB82FDD7DD,F2DDFE6E288B8F6C,20A987699260FFCB,37056DF17C9A803C,1436926ED92CA556,BA1CB41C6C29023A,B7000110D49046E2,3AAA7E7256B2AE91,ABB8449EF1164DF0,0000212CFAC5E216,EFCAB0648AA08FCC,8382597C28CCFBC8,FA1612E6E1F8217D,73952CA062C196BD,D505D7AEB2751516,21385C7A5C6799F0,DCABB7673374A227,6D96CCB3AFEA931A,157A5725CAC5E61D,42F0981CDB11B87C,33956ED5E368C5B8,0000141C74B531B1,2BCB5C138B194A8E,A108F33F9B531481,4103CB4F952ED8EE,8A6D404FB1B9B173,F7F26503A947E205,A5F615909BDA2725,73A73A0506B24F93,C1511E9A41C2D924,9FDBACA354612940,1BF14F98390A258F,5961E338CD9DFE5A,000034442479E269,BDF7317B244556AB,3C46879D93258145,12B497831FC41B6B,F40BC4122501E447,FD44A6884F7BA599,7A1BEA34369688A0,99F33172D38AA045,011FE5AE29DFC9DD,3A257A0E9C547E36,5D0D31A45FEF97FE,E69BABFFD2BBF95F,0000146D299F99B3,E773C82AF3481781,A0821BE4CC7E2E45,B32D690B88029E6D,ACE5BF21818BA699,21FABB4688A2DA6F,9BFC91AA85859289,9DAF3EE4DD65D7BB,C72C82735F284980,F34C26931608490B,64C3CB77249F20B5,8B2CED2A93D99E83,0000620B0315A052,BB901E598B587AC9,683A511B800AD580,D3A24CC24C0EBB5B,E4F9C7944A9025C4,74356C5AE2BE3538,CD8E8254A7CD4D96,DEC44165E0AB2D0F,0B833586625F3611,A2A7805B4E98566A,A3579D146CFF44F8,E14F91EC38758AA7,00000438EE8EAB2B,E2DD48CEE30F8D6D,2BEA07C7E6794A94,863EFB62118B3788,B909CD1157B025D2,5C09505070A46E11,5370B644A0D68FD6,F4AD8F6A45411C17,0E8DC44354E5FCF7,DA793A9905A68EB9,BE8B085DF5486F24,03C441FE519B8825,00005E07E33F292C,309C88592E4DE00A,3AE822064ABF9547,74EEBCBF0CCC56AB,847A27C3E8BB7C1B,82855F3ABFCE86C5,999B92225A2A93E5,9FCF335609C42C6D,AA4CE6AFC1E21182,076B7F417F5A1C45,1E2B52B4E5EA7E5F,28B6F23214EEE7CB,0000214855BFC6AF,2AEED9417066D5A5,9116E407D82DCB47,36C3D00BAC203328,308D0C267CB24540,4145CB17F7918B2F,5AAB4DC2ECB756F7,409F86358671A7AC,EF770B52809EA961,36FD0CEBD644ACFD,9A5B835E7CAD668D,452F26E53EA122CE,00003A173BEC954E,01241AC4A94F43FA,CAE6CC2920198022,B341E2E31D160DAD,189723EBE912903A,B0662E1AF46DE857,35D57E61B78CFBA5,86AE6C2E079D8756,41D6B6E219BC18C0,E79388BB78847DB0,33557F6BF13D2C69,27D7EC8DCE2D3748,00003ED9AFED6AA7,4FAE323B3CED6B88,EAA5A6F0C6FD63A3,45C3A3F9B3A99886,7834504CA4D5F67E,15FAC8DF4E28EF25,C120B8DCBB3AB56F,7E7EE6D9EA961806,3E53C66C64761F3A,FF7BA373BCA11BFE,ED641CD1A5F391DC,4FCD5CF716C094FF,000005F051761C40,FF1C5A37285912F2,DED750D2D2A4D43F,9AB7868A4556278B,AF4AE1FE4DB8F8D4,31F42CD28C686DAB,4A41E83A2E0999B3,5283389FB099C2E1,AFE72410D9279CD8,8951C60895F1CB6B,2D060D3F3FFFBBCF,BA299E4A7C52D999,00004F45EAF704E6,F8DBA68108861934,16CAEAA683FC021C,C8123461C59BCBA1,6B025DB8FBBDCB27,E4F5674314FE0F5E,3D0BE851C3126E23,A78337641C095AD0,B54FFCB5A7D21A1D,3E3734C8387DC8F6,376942EAED34DC92,F9A980DDFCCF7810,000012F604989E58,B07F1C329569F588,19AF2D321F37E78A,8B8C7215B55E8F45,604F1B0E92B6D97E,F3F36BC44ECA71A6,97E61A39F95E8C1C,9EF51A32D488B48A,C0FADA493A31235E,0AE4CCA1DC253A34,4E4D17A48D037BCA,189F213B2432EC28,00006BBD815A4C30,32B6D8822CBD2589,89875A9835CF8D63,8AA0DA94577C03BA,E0E10E2A6D5E6776,0A5519A249FB2211,98F3EC9E034D015C,877265A066F28642,09A52B7869EC7887,08642DD6BA4BAABD,331E50E8838EF615,904CFD7E32430A66,0000362FAD0E351F,DA50FCF4E5F9EECF,DB6109D60D7B8DA4,5AF6427ECD7538AA,CC90FEF5812E51CB,5E491B1745A3EC9F,2E69D61729FF7442,5C4A7DB306F83B38,3F4E8D82AF5A5C31,7FBCEF9380A1035E,AB6B29A448A5CD36,7A070582A686A9A4,00000B091914D7F8,E3A512FCF86BC5D1,29CF37D2C34884F8,D2E5D87BC1220C63,175B470245E301CC,C658722E926D364C,8166278E2144D4EC,8AC17C50C1B1B2CD,89AF8E7ED0CF36BB,21FAA92139346E42,7A11D2AE1902C12B,56F51FEB839A9F4F,00003EBE4F94E157,D031BA53EAF6E629,A2EF167083398119,F41CA1A8C57E93B3,E0A84686F9B8E933,40E17640AD5492C2,E1069F2D7E3BB3E0,8EDA42B1B9CE9156,B76AE6D0533000B4,475D0B3CDA6B6F19,A0F479318392608F,740D97A0DF3F8311,000044B3E69747D0,6FB46D834CD5CA4E,A6D80007B33711EB,826E674CFB0C3FA9,2B8842EC24FDC809,6B2CE5514E42692E,37FA298274D2FD5B,DC640290D8A42305,5D6D05828CC12FC4,EB9FD423D752FBCD,ACD5698BE4A7B579,2D1F9C06AC6AF74C,00002E1BFC662B5D,03DCF3242B1A38C1,8272FAC7A8773BFB,0A3074840B1EE9EB,D4F684883737FE54,7C0576D9A69391F5,BC5A36A436FC6F23,A86E4009AD53A000,98B52BD673471AE8,79C5E797C8C7BF40,1541F4088B68DA9C,C88CB7DB1FB7C628,00003E26032453A5,65B4FA2AA8BC65B1,32740032B815675C,E5E0DD4CC8EF6902,EEF0B70D2ED024CF,E084877E358CFCD3,3880243D3CEFF8B9,F586ED2CB8B3B285,D7F7160C0A0CD5A7,9BFF0DB0E16B38CE,557C1916E412D9F3,7429BB96C603E691,000010DF883CDABF,43A5A02E6CCE47B9,3A6EBFA09D208694,FF7F9FC61807341B,992286C984F9304A,61D6C9C5BA2A8B63,BE560112791A5398,A9B1B0E157DCEC0D,1A422E73AD010FA2,BEC9EAD2B8EA4EF2,C0D926286841AFBA,F770126EFBE7E01E,000039B702E36238,DB5F9CF12CD9CCDE,EB816761935A6C88,7A6EC25D89F554EA,D07A8AABDB6B7FD9,D1DD0B40DC3BA750,89CB37BE69A70BCD,F0190C28E2B6AFCD,A4C3656F461FB71C,0F07579C921388B8,838DA950187A838B,9A20CAF4A1ADFC69,00005F9C9E744835,6A3223DAFEA14762,BC6BE40814C21FE9,820907034D4D1902,C1395FFDE3C409EF,8501557696B40E76,46BDE9BAA08B0A8A,A430C1563ED52A8D,E6FC2DE025466286,BA3AF5116B261D52,72D9C33F869D355E,740E26EEA6E1F3E5,00001222DF6B715D,F645C79609A10D45,17184C0BE15717CF,7183417494D6564A,AAECB7FEDB8CC46D,91864C141D18B285,D5DB393ADE0AD9AE,06AC74664F2E1FD2,80161178F9120614,8862239D1EB3CC17,358A8F9F29A9073C,D5B496282A936751,00000073F8848B74,D738A7E910F0167E,3054E0AE8D77F9AD,B25FD5324CDA4F74,01840AAC08ADBC24,CE09D2010568B003,16B134B6AC11B8B9,FB124CE1D93065AE,CA5909BDE3774061,A5840FC5CB0BE030,C0B89BA9AA930968,03B4D5999F81D86F,00004CD013AF43EF,82FE6CDC98C85461,08CD2258A2DE46C0,7A35CA1830252E0C,7DAA6A29DF3CFEBB,1504B3DCCA30C3A0,0D4EF30A3F8F3631,449C3B72E2C81F7A,010AB2932B676980,A834F051888B02EB,28E3ABAB5A0846F1,226691DA38EC97AC,0000302DEF3F6217,C88161715E6B2613,E5F0CE919496928B,4CDFF30F87FDDFDD,5E1319FF27848719,9FCA95106AFFAAB9,691BA99D2AC2F707,6C61ABA4F9A2E282,BF3EF35A445153FA,AFB3DADC0AE1ABF6,DD0B6BBE562219ED,40AA2E0107715236,000008D8E5D50D84,D7D0B557CE4AF0C4,81E6460BF794E850,4886DD1ECA6EECE0,0B2AEAEBD107D545,9907A9E13CC6FFD6,5CD443D3263BF307,72075C2140A32305,4BC1A2CD03668CCD,B020ED84FC8E10AE,B0671976A65AB8C9,7198DDA1C7DE272E,00000ACFE49AA183,2407C495974E7B9C,3C92E43313586B50,DF750D4BAE6858D4,6C192F99EFA54DAF,C211A3C7317678BF,86AAE43F19A76856,C678F22ED22D6FCD,29D52F640F9549D1,863762BC7E35D463,8970BDE0F6010D91,8EABADB3E02EE878,00003AA35D7C2E9C,14D6F3967383946E,4EACD19D3C39CC08,A76693746E81E1B6,EF2081535211853D,87B3C874A811F1AB,8570C72045B4858B,82925E4A400AAF14,E0B0B77CDB207DAD,BFE1367D6E9E01C9,413B3885C85E61E8,1A61D4B85488EA80,00006A31D9016D5E,29F3DC48C407BF23,02A8DD1494028D84,AAE33FA60BD71D8A,3C14DE0140845E2E,88B97AD803F417CF,02C5A4FDA0B2221B,23C23E77225543D1,CB28286AB96AC986,D11D6E54DEB312D8,5A7121ADBE672018,9E129F98ED1392DA,000069320DD87984,BEA56C301316A7DA,C478C436EE09CDAF,2E470E08CC2C8A11,BEC8DCE4833FB2FC,CF65940433AB5453,C95158B1DB39F790,63DEF3E2B4B25762,CCE1BF3BC7336CCF,CCFAF3C303F533CC,7505040404192EE5,D907271E97E40C30,00004E4C51BED65A,06358A94082C9473,46A4D6A0DFCE60E1,9738261A082891BB,E85F50C2054751DA,30308479D102F57E,EEC16EA65969A1D0,74F5BFFD6B6C136C,75DCC0DE21E4F58B,496DFF2C9376C120,2CE656A9C8C6D6BB,4133A3010B929031,00000CE036944016,2725DE30080E8679,62C6A584037BAB07,385E49DAAC0997EF,E0E8B0E6D36413E3,352C6390D84823BF,C77E056C414A18D9,C5CF6BA147842B9F,DC2D019FFA233C23,0C709DAAB7071411,C8FF5239486A4E4C,E7D6E4554315A671,00005E9F952F844C,5976E13413105BDA,0A8F267A1D315CA6,968D07030968E659,E74C1F9478758768,AECE6F2F2A739F89,08631A1CEB9D3DE2,5D9E4927CF9F77F7,10D538879368BC92,99DD8BD9824F497D,F805F4AB5988618E,3CCF0A922E9CEF0D,0000499F65CE74DE,DF721AAD426675D0,AB6FDDAA6DA2E7C4,D0F09F024843C8F2,7A718E59ECD305F5,E0236F8A21D20FA9,78FD2BB48D904889,BC96CEB39C572CE1,C7739F800A377748,32DE1AEF783F3DF6,93326383333433DE,88586905BECC4E26,000069789CAC639A,088A39BBB66EED3B,6D9FC277A02E179E,9958C33768F596CC,D6CB670D964F8727,CA939136914927A2,EC079C99F81F79BF,B228ECAF6C92B634,E7A63D3D408B8270,4126A7AFED1E6F5D,65FDC71AE4075085,CEFCA9D8719A42F6,0000637C9CD52489,9845576DD48DD2CB,ED48590BB8F57E4C,4B9F6BA135B0AD48,A641F6C55E073006,40CBE9FAF11D94FD,B15280635E448F66,4F39AB5EB336ED2F,C1E06B649F0B78CD,EB4DADF0D4189E53,83A9DBD9651A19CC,E53403BB67E41269,00003AA6A7551FFB,C1171959816347DB,AAC1345EABB1BE32,4D708230D4788CCF,D6B494B551C07BBC,3375B782C13FBF77,A9F2A2F82C0E526C,04E404FCAB13FC8D,4AC49237592C2E88,4034DEBF124181CA,A588721FC543D124,5D7CD3C16A6EFF30,0000003C9FF1EB65,8FFFB26FD66DB3BC,0E76E96A35A4FDDC,B7317CC91766F150,DB687790FFD07423,A7359DCB9B77FCD9,CDAD1FC5567FFBF5,FE419CBF00025506,36D41154AF597317,70729BEF46C08706,E422D9E7C66F05A1,C69A4AE39BDAC7EA,000049108E477230,D0CC451640C36407,3D5225101E8FBE6F,456C886C9E52C0DD,D1C9C053A4A9C10A,05E670409311D101,F3A42BCE6D7DC06B,83CDCBB3E6DD1822,19216F126E9F1FF1,B9A461FCD8EA4CEF,69E5DB7308FC7D0B,46BD1F9330E911D4,000000146BCCC290,F2F915EFF43A914E,5E4530B8AD5AF76D,DB625237FEDD787F,6767883051EEFC67,1E23D3C350B65614,F35BEBF9527969D9,005AC5944DF63D84,529BA22E4D4A7192,7013137290D225A5,1ADA027CF7AF4373,5EA65145FC558DC6,000004A4B175A118,3A8BA5357F9F1911,54A9E575A813EF3A,FC3AC3433D36F3CC,A25D5443BF844759,01F8B6167145F06B,AEB20DC3195D35C1,8116D7C0D28751F8,0BFA03DB45130916,CF3AAA2A099F5755,5AD012B73431F6FD,866B210D9C8C8455,00005A36E6895ADF,F7F11F7BF32561A1,871761014ECD9B89,96A4A07EBB7AD1C4,EE342034A79691EA,EFE6BEB9281CA918,25F9914F77082EFA,23F57B39B54397F6,268A0B031E0AF9F0,8C4009485D5FDCD3,B9357D8D38DB2C0C,7F2B4A7C57AB074F,00001DC1BFE5F4A1,713F6AEB298770D4,89E6024A97B54BF1,DCF719DC3021413B,DBCDDDFA995B20E7,8CB842A63B583B66,BDF509822B73A751,A5D607E256955578,E876977604E7E30A,077EF735F6B9E139,F8BF348A9570DAC8,1EB0F85A3A79727B,000053493CD4FB06,21C7BB77A0724353,AAE6E0FE61F30027,91E0CD16243AAF76,76D79EE89C587023,84982CEC4DA45910,A39BB240D59A722E,0E2C11A6A49D3A0E,9C3BF63E9C3288B7,FA07114A74E4BA10,099A8718409C5695,231FE0E0CEEA9D5E,00004DA5F1F1338E,C837D87A48068D0E,4AC61A6E660D1C86,F8FE25831EC15A3E,62400C7C3A5C0C7C,5621DA5CD36077A6,50E4D3370192BEC4,0503ABF67D71B3BB,C18B9C85B5BF7EED,55270AA62E6ACBCB,0FC415E2CFB31234,125D71965099B5DB,000032B069A010FA,C184F8CAED1F0C63,8C7FBA74CDA0BE45,12FF8C8331BD305C,493D75903BB014DB,6B24FF5741C27D26,6F4C2E29A137A278,D0FB0141BB432C39,2726C9A51ABBCD70,C6B66467F6479766,9821BD12DECA723A,C91B1430294EBF34,000005C23C01919F,2FE0AC37B1E23926,DED94496A687ADB6,B0CC5DE98A76860C,2DAC6362D458CFF7,EC68BF4A6DC08A75,0D7682B5BA07A44A,4A571B494DB576BE,A06B219ACD680C34,F8EBA4BFD74C0ECA,5B43F1B32114E1E3,2A6003520D30C005,00000D3725493DC0,D0F6418E63F8374C,1811A7F82F15AF87,955A48835878489E,64CEB678433CD05C,8AACA78A39FDD91B,75FDFA0C269B6C12,D7690C1E018BCBB8,006B91EAC2AE448A,0F970EA4EEE25177,85AD280CB4A7270B,0BB5B7D14E7135FE,0000240EB1F758C8,174DFF28395CDD2B,B8B28705B42EA62A,CFF1D69A7D266EA5,04F52F095341E017,95F6CBB62C0F9C6C,52137470653B5898,4965BD9D5E4B9CA6,68D3646E4D50AF17,B949FB6F872E5D5B,F83CAD0F559DD92D,8E1EFCD8469E9716,000038A339415F6D,2D37074EEF60F38D,FDBAC6E28FEF74A5,12F665546C4C125F,53868FF4BF377BA0,06B814849DB69FF7,9CE0B95C721AE36A,A651129EE70EC040,A6410F861D97F7D2,E91847AA0ADE5324,8E4B8921B2A024E7,52BD59BA57BCF7D5,00002C0B5B324D57,45AE048B5086ED81,7C1A1A60F19B6E28,9E476A7E85645D47,63C58B999AE75A33,53085205D8011B42,E5EA1C5E3DC95CA6,31F16D5976B11187,5D02194566B8BE6C,3E968F684D0387BF,37A2F17FFA28255A,0C2E468C0BA8054A,0000306DE5823468,A34F57E181DE8458,B5471A52C8AD724C,73FBF09360450998,CB9F3DA70343CB8E,49389B1FB8765153,B48BEC3E02C2E2CD,D5EB49F0B3105D1F,47A6B585649F0DD3,225333572D79D73B,A492F71D84FDCD1A,0F33600769EFF247,00002FF247865D6D,61142128FA02B438,50E215C13C7C933C,8D3DBC4C3E96F215,298AEB63D24FAF2D,A4DA9E9D5AFC5BEA,DC34724422CA8140,A23FFE23251C0A40,5D70A2C2660F6B50,D2B47611DC094AE1,0CED19B0E34B141E,024A716C7AC23ABE,00005AAC9AEE07EC,6A8CCBE26D903A1C,6C28E989FE5D7F54,71A32E5013AC51CA,5F8297FDA0423CFC,74834C19C0F74BC9,31FEBCA0F392DEE1,5A0371032B8738BA,99017FA5997AAD2D,DDD64B7132865493,1979BB86CE830562,7FDAF156944B895E,0000087B44B24B94,08A9E590C28398AE,DC6599B9EE626947,9EC9E8CD62E07BB8,DD2A94E0053E2FE2,63A2757CC75F556A,D90AE0D161141C6F,494D38C062F7F429,B311F4354072B187,873DFB21121FFF25,970012949F560992,6294095B8CCEFB8A,00001357B7C8999D,0357F0D685F67B85,957D275A72B0D4B6,232711E3B5082D61,673925CE31217890,C5D335FCDA2BE031,96DA3F2934F0306F,FFDE4C0AD51D08E3,2B0EB57A2D3411A7,29043AF9929E3398,C2AFA900F045B161,D6C842B865AC722C,000051D138CFEA42,B7B80971CA597766,602DBCC3E37E7945,8A04220B37227E74,11338FE0C0081048,77F5118F45DA1C14,6E9EF5551347B0EE,2AC4DB9E11E754EA,5FE90019D5821B7F,BE52259712667CC0,475308CCA9A9916A,AD808479957A6D51,00002FFEF3A44B45,515E9F5A27BA4177,3854E49AE32AF377,1997CFBD2DC61304,1B925A38000BCEAA,BB09E534E91FBB40,21615CDB0CAE2DC7,B0C9D7EE7562E59C,9DDB1240B473D31D,69AA8F012DB7C456,06BA5E3692BBA71B,2CDA3EB5D8155BD4,00003E4436B2147C,97E11E5F308B60C5,84647117B61FF85B,81361753BECAE807,8B8EF29F9E5100BE,7B00E19507297926,41F713E0385D507A,17367DD74583CD8B,DB9647F6C86B89B4,09C7039CB655242C,04C52AD6E6DA32D8,5F18ACFB93A3AD01,000044D38531EA75,FE5ACECCD78DA10A,911D427C3151C8F8,5EFD74071970257B,F5E7EA590563704A,05213AC77D4A4B4B,14761F207533008E,E84EACA7BEF109F0,FDA7157A8B9045CB,02F0E2D338312F6C,57B4AADA02A2C9A6,4850623FAA243D96,00006C8472DA469E,2ED8BF40603F3922,08CD5C33588BE9ED,F737A93B4F252597,129E8039DE7B7CDB,D21412B571438B37,E8ED3767DDADC85B,F117E3BB6E9A0650,A2EB2AFC414E369B,96EF33A909C96542,7DD83F44A6266BE6,DBDF4E41442CB5D8,000012E8C32D85B4,0EA7794D2F677118,23EC18B957F66ECD,F9259AFF607755C5,26E1B484CFA5F7A8,1087910614FDF3AB,5F8AAE54F22A619F,4901524EC86CD1FF,F320A696877A25AD,DC1BC5403C1F56BA,598BA555FE16FCC3,A1F92B241CDF2136,000011C9017DA516,0DCD83C53C69DA8B,70FED3418A6658F5,1B7DE5D9DCB2F876,E6F90CDBEFAE7505,AB19B6F0637AA65E,2D0310D99845CEFE,02C38FFDB1D4DCE9,CA26CB69210DC72B,0A7A9C8CFBA96247,5347F224F362BE5B,6649C3F445F0AA2A,00005E94C2C2C978,C5A98875A7D22939,EB204CDA3E6DF322,03224BD52AC68284,C814AECBE4EF3E1C,0C073ACD60F94BC7,6E6112DE4187FBDA,201A0624E6277CF9,D073CB298F49C8B4,762C3D17C686A422,9FD8788BC19511EC,3A3CB927135D85F5,00003836BFD899B4,7B35D9A5706CC112,81FDC37E1EEE62D2,7F72DD6DF3A94BC7,062207F86C23E8A4,E1D952EE07635683,4D7B4DC7E1C424A9,593940E91DB6A2FB,EEA708B65FCCD688,089B5F343B0D529C,78B147170CB43167,1EAD713DA7826B0E,00005CFF0D8C1B5F,8E2DE359F9BC387E,A9384401CB5DC0E8,EF7F334BFDF68C18,EFD552075AD227A5,68DEC089C9E6769B,D971C2F4057ADCCD,AADD08B2418DBD33,56A0307705550306,C7E3EF355E3AAB72,D7D70E9F36FEC21B,B6C44BC475206501,00002F49ED84E8D5,2A41B37B57A199F8,386E9191193E9E77,2676CD9FB4092FEC,4925BC0E7D2C26BB,0EB16E7515724CF8,A40A16036584E146,9CF67EA4A4C2B5B7,9D27678A003A696A,253864D3427AE75E,0388A719F066296F,E682F6DD247EE74B,0000548730554736,76451FAA41BCE5DF,47C31A40CF77D6BF,1DF6554E4F9D6C1F,5CE67E83DF6302FA,8935730D8D2B27ED,1DE1190FC4C40E23,6B82023655BBE3B2,C79696B0BE10B13B,F51A6A0A888DE3DE,EEE8A601867C40E5,E67C83FD1C797027,000031FF9FAEC071,7A62B1D876892EF5,36E37CA1AB104577,C8BAC25E48170949,B6EFEF34775B29D9,39FF01B467B354B4,B960F20A7761503E,803F7AA19154A721,DEA53ED759951A0C,3C9DEDBA75857120,58402101C77AD35F,7855D299DF242F9D,000043F182FD92E5,293426F68199F0D2,20D5406D3E29C697,3A88465C8ADCF8D3,800322EC22755308,4D82ACFC7F037373,E895FEDBDBF1436B,4E416F682402E415,6C05AB251A91B71D,507ECCAFE95EB084,7D653F854566EE03,9BB953AA4461EB94,00005CFE6A11E53B,0C7F3ADB05947311,6E55831FC4557637,8699FDC4457D3A03,B03840AB2B7AE6C0,8A2CC60F45705816,139A538D822F6314,C16B50214088791E,37C8086D55447ABD,B91CF3BBFE235D43,8E4360BDCB927B5C,20F4F13F10B00158,00006DC615923742,539FB1A27A421DCA,910E8854862EB22D,DD6B29FA618D589D,EF3F2EB2A4E5CB5A,B30B67705A5E4CAB,E6E4C909F3A24E12,5F208C628C6D1F08,C37C4D4D87A857B2,C920CC4F44BE9A4B,338FA9D446D322F2,AD053D8149C28505,0000546669ED1AFC,8EEAFF2A4A576ACF,83D0B0174F10181D,1915E21C0BB91522,853B46C9F7769305,13AD6F77C0BB7CE8,0383757F8CF0DAC2,4C419E62BF2E9054,95A3B2BCEA0D063C,DA3833115236A944,9AFDA9C881C8C68F,B6D374F3ED6510E4,000024F7851909F7,278DA917045CBE5A,9520ACC4297372AC,A14A89DA1150F6CB,EF52162CFF489110,29412C4CA270DA6B,B34FF4719CEE4EEB,4DE1A71BFE1484A3,FDC861E8241DF41F,A2C82547861868AB,95275DEFC8169D25,76EF0403E532EAB9,000023A5FB187B0F,7D93B7185E218619,877373E5527AE8F4,3BC11F3BEF3DC197,23C86C1435B2F915,5D5D6AA2878D8EE6,5C6D93861DA9CE2B,F06E2C3A63F9D54B,51DD9A70AA2D697A,F06AA9900700E49D,C552428FC3B43199,AD39990EBCA98F00,000041399551E0CB,B26E4A8B1C649BB8,91CACDCB96A60FA0,F557BB9BB9BE03E7,58FE6FC947EB325D,70865DE56597D756,89E1916F4D1CD000,808A94B4FCE35ECE,D9E17D9FE4887A4C,8A4203D1B6F2E2BF,69828B37F5F935AE,3345BBD92BB1752D,000039986F17A3B0,0591DF756BFDEB3C,0CD73B2317A61DBC,C52175DB7AB1211B,DA2A9002E3CD9CA7,3F4C197A520EFC30,98E1CF93C0048D93,073A336427D52BAA,87C2A6C0E177C9D8,3B8EFD19EE3F34E5,76F44C73C0E2904C,23DDE0AE6DC2F0DC,0000139FA9EA12DF,709608DCDFD23628,88722D8488C19149,BF62A02EF0EB447D,6B4F072484B6F1D1,6A582CD3CDC57296,29B7DAA7E2732ABA,10299E4DEFC68B85,DAF405BF6817EAF6,779F7914F41BD634,4B562E4927C87108,C5FC164CDD2118D8,00005EB72D325CF8,B8BBB7577620B323,8E64132348DE1F4E,B1B717A0835B01F3,CEFA7427C6426A8A,B8389A8F705B2E28,CA2D72F8B6042563,CAC9C3F727BDA03B,9D86E86A95838E6C,856439772A5F5D6A,F532B493CB603E57,8D1A9424188383F0,000035FB99CF94E5,6163E0C6D39AB564,13873B15B9388188,26D8C631FFE0B7BB,026AD81B0FA9802F,D7C9632C60008A8C,C0309AE0E2429813,30A5D5BD89432A95,514A8314E9ABBEE3,488FF37C6BD34A49,B43A9876696139C5,D34660DBE9B28FA9,00006233DA108E83,DE1745B7451E9998,CB2B5D9857FF3B23,ACB19CA35E48468A,F7669C0872309537,D5A26573F59B1435,954B176C6773B58E,F01E49C18517D16B,F9EEA12C270F5FFE,8ADA0034FBCE5A3B,9190FD64F77E4560,5A265FAE441EBC27,00000145D562501C,6CF3C24F7BFE30B2,1F8C66ACE29E5DC0,06954D0213E663B4,1CB09626B85CCB76,40EE13A2CE0421EE,551AFA6694AAE73E,73327664AD79CBE4,89B601152D1C0EA7,CF6D92BE293C1BD9,A47BF421C62E49AF,4075C1FA4360861B,00002215261ACDB4,DAF39BDDB0C066E9,F03DC850DFB4147A,877BA3B34EBBE168,142AF5DC2270EF0C,F78054797282CBCF,9F23A142C7B93F46,7F52B2407C5D2C80,D61473C79A43F1CE,267726EC3A3F30DC,D06EFC22C768237B,7D8CF53446ABE78E,00005B629FAC51FD,A1452A4EF7FC31F4,1A6C26EA5885FFB4,48850F7A3B043D52,16EC39A983C96748,6B1D7BD2A3B4CB2A,98CE0F0437B14232,DB15C9393F7F1276,2032DF59F5AC0095,9C267A4A93F20B07,91B08E5BF49F3781,3F4E3747981BDE2A,0000207267A162BF,4E2B102F9D7B616C,7C2E4F397096D5EA,3F79938E212A2C02,717D8B41AAA13F98,767F977781FBA5C8,611DE6C438AAF3A8,00D566B042122905,4D96AE0BA70E5F20,2BD24FE4E387DF6F,BF7E74F4C52BE11A,D8E9B06C771CF13B,00003E9BCC372917,8376EABC4A000ED6,0C94A69A6EB3CCAC,C0305B7018195E55,10C3DC04565D780C,E11000DE2F21C056,53FB26198AB0EAEB,2F79050135E67544,C2163727DEC06472,AA532EB67350C2AC,8D9805DDA0C04B82,D43546531F97FD66,000056528F236D35,9D8B7422B7BF5156,C32EEA62CCD91210,80EDAD8B2BC125FD,75C2D16EB59DFB67,81F3421BBD22E660,62E16C44B43ADA69,4BA4231E59D854A3,EC36C2482C85A6C9,3136D72D79BF4C94,EAEE16EA79675E68,31B791FDD87EBBC0,00003FA344D0B077,7C4A57F6FA1971B0,00F5CCFC1E0A7005,277A2E4E5DA3C54D,B9E51B2AF0028B78,BC2835DE0EC2CA55,B06767C8E2E022FC,9143F2EC30564710,4B98F4EA17D28D9F,D62DC36751C0BB46,5CE7F1B322DA2F1A,BC205CFB1F8EC09A,0000208920AA630B,C00BFA1471701ED7,7AA6C17076EDDCBF,A93E67FE975408B4,2DEA2A8AE55D23A2,D8E5B02DF2AE085F,24E6A465593EC6C9,AD30F5230B268346,06E1E46E221115D8,6D449BCA3EF9403D,9E97940353C64118,C9B913B11BCC0A3F,00004D6E31791982,17AFC6B34798DCBF,DDEA57798CF05C17,5301BB3BF08B0549,FE7A0C6FD7C246F5,2F2CB59CE85F452A,A04C52884BE856BE,46BEE58AA7105649,C6244B8A211DD115,322DB634B3F7E8F7,D9F8245EED46FA71,9CDCF6677372A72B,000018A662C13644,1AB84BF7C492C676,349823F69F4B28EF,033B8F0D59B738B2,61586F55C6C451BA,A0BFBB67B2DA6FDA,4A4DE4BDAF560968,0CA14F5CB8F9496B,480B1D32D94C5EF9,C8ED35B1B2F009CD,881516E922604810,0F6CE11F8C674719,00004219554A9D10,84A3484336D74738,A493A7A18F377406,41EBDA6E6F71E7F4,44DBB1F0EDA964B9,6B0F7139F68E1C6E,8F267AB4011DE72C,0DF2316DF53524E2,7466C93801DAC736,09D285D41F9471E2,A7EAE3F5EDFC5841,46666AE1F3746011,00006992338F54E6,8CFD6813B236E4AB,0072816355FCC52B,E1CAD8360550925E,B28D6A0A589BFB6D,AEEADC390DFB7A47,373D2CF77BC6DB55,560897D9E0FFB9DF,C5F0FC75009056AB,F579C2011D194517,E253277E56973B7F,F2C2EC652BD5BC15,0000690BF812B5D6,4DEB2D25A98B2F9C,C9B081FBF2D6BB64,532AE5637DC379C3,6C7779BE0C45A1CB,EC54237DCF5EE728,F883360DB0E83280,4C122EADAF59418B,556528A5B254B0E7,79F89365F529EDE7,3BBC5914F3CAD861,38F3651A1CBD5F2D,00001A86D3CEE9DA,89C81A3A302695B9,B64C5A2C76E99D32,37951AD96EB3AD1A,6915C0740C8DF1CA,11537C3108112D7C,74B1BA91CDD1A61B,779043BBBEC204E4,E20CEEAFDA345557,369FC8354D40F741,9AE3814154B2111D,445BC0EFBD895C26,0000378B5A7CC1BC,09A4E05E74EC87AF,D2E23FB72FCEBD9E,CE4DCA7412422236,CA94708EDC329219,CB38680685F4FB4A,DCBBABA0726A3B9B,AD9FAD66756CF321,A1D6F990A1AABEAE,E6D5CC726CD534E9,B8F8F294102FD69A,388C835FCF7C426F,000046C7E5427622,BEDEECDA55EF4B1C,FEEC2F0EE67905ED,E4B288C6A075AE47,05862AF91F22E50F,A07817BE181C733F,F2788A6E568FCA9B,52A1A26B14EA0741,B524DF84B8EDBEA0,BA6DEB7F16BC17E4,FF5DF0885356C5D3,4A80F3E319049046,0000610A656E5E29,D58B2A9630A33410,48932DC0C8186EEF,44BE848C569E8F1A,D343920D328A5717,4C832C7A3EFC7C5B,CE73F864F94483AB,D5048CC356224F9B,2BF75CEEE25A310C,52E0728C0BA9004E,D60A72DCABE7AB82,619F89F176E8A703,00006EC1A73D2F3C,E1E3276678DED4A3,4E5FF1BFA8D7B3CC,7225684665428FFC,BFBB82E47CC2EADF,2FE0AD026DD0258F,9B3F283B544084EB,E48399A26BBC421B,2566BC40EB879434,00117040D686A1F9,A70ABA927D5E69FB,6026C842775848D7,0000435E41EF79F3,D73E87348FB2AF93,4CF9B68AB9E8DC3E,D1C2FCDFD5D73533,3FDDB3397F516745,29A0802970F9626D,D21AA482E99BC881,14E66507B3C1672E,6B3A1858F12D1B72,4CC5D170B2629CC5,D77F418A1AD76BC2,D69C5752CBB02D3A,00001B63D370AF5E,9A06CBDEAEC2680F,A4A83AB5AAD205EA,316E10E8F76ECF19,9CDB73169C7659E3,E1C5FD6B414CDAA8,C07048FFA385F604,13C8F8A5D4B3F0EC,A6D01016B48526AD,12DA4472E79CB65B,31C87E646D997B7B,499DB74ED31FE585,0000173DC8B2E309,872A20CFA87FF572,A12E4A783187F1F0,6E44B5B4B6446A1C,BFC648DC30D997DC,98BFACFAFBDB7B1D,E77785F76BD79955,A86A990E690CCB84,96EF505189EF1743,991E4E934C5FEE06,BCAE24A533E9AAA3,8A4D3287F2B77776,00001C0E96EED203,FB55A2E109695269,68FFDF765409E6C6,AC0EC3EAB8BECB37,652B974D73C8AB8E,FF8E03DFD4F1450C,4314C367314DEAE9,8BAAEBF6ACAE2E01,D8B0D9EDC2790769,319588D793D28D2B,F3B6DDDD2909A939,5D79C91DE00D412F,00001C777CA4B943,146EE289C820179B,5653F62DC3600F84,4A77BD92FFE292B2,2488C6257CADB8AD,874DF11200B0091A,CCF060088C82D2AD,4D7E2D09F414E151,34C524581247BD89,948BD094284BA84C,4E4B74B4030040C8,72E0ED1B9CDCEAFC,00004F5937FB2FBA,01896AC6DB1BEF20,6EA10B0013502096,6D62CCF645DA8CCD,740BDB2CDCE2DFEB,5D6A38BE7226A400,DBD308C72A7880DE,DBA59E9F64352DA8,575754883EA78FCB,F82563FAE75B8ED3,606A85ECB13C8478,0A5F50401D4AFE42,000068AC5EEEA091,C9155D299D5A1E0F,55B35FE319227490,CDC6C84C6701C782,FC09F8C9045B6DA4,2CC9304EB655C5FB,BC8B2B1C609AB70E,2F47741C8F095A8E,7C96047F0D5B787B,B336A9BE1487B469,E959AEE280C39FB4,4BA3A8E88D17C163,00003674B8F85443,171999689F4D5B47,59B4976AC12A5FD1,0FDDBB7E32561C05,5D35FF11583DC939,8C1A4E744F9053E8,476984F406D60415,B3CFFB93CEBF3F21,43EC019C6D45963A,DCF365730EC46CEF,28750A8366039AFE,C3D12B1E2980DA0F,00001FFD1D1CB861,58B73A40F7486C6C,90D87C89DC7013B3,C0A2BD3584A1495E,1AE5C7F744C714FF,52D3C53DC3854420,7A7E850DB8AA094F,2EC935B835231744,2B68234753947AE4,C1EB044B8DE9C90A,6CDC44FB7F02E30D,D3BACC7A69A5BBC8,000012E7205339AF,2DFF1E14B91A224E,5939C161B1ADFC21,30DDA640190B35DE,F29FE1987CC58A03,4CCB1EDA7141DFEC,EB3DAF238F96A98E,ACC132CF56410C97,68B9B83EC659798D,B02654DABBC2D314,AAAD5DEBDAEF7A34,6A79D0B3FFBBDC9F,0000369750E2C12C,B84E1DA14DE3AB39,D2A6E8B10C5F7384,006EA6681AA3044D,C4C5DA544683D63F,F7DF9D28B0953529,DA0EC714E21E63E4,B3703BB6AB67F797,4754A872642C07AD,728B2051F65A4A5D,F33711D6EFD78874,E58F16028A7C7FF2,00001FE0195094DE,947CF13B18D91AA9,B7D852A5F306C8A4,E5727510CB76A20D,8A59FEF2DA5079D0,6FB2D69EC71CD0D6,482D551662FC8507,836324667320164E,33F9D15102E30264,5036AB0322AED704,0ED891A7057D93ED,F4E4BD934D3C553B,00006CF00CE873F3,BCD7FD42EBB28432,E950A75B100C6CBE,E3165347C1768E2F,1E3C6937CCAD1874,B45C5AF2D88AA2C6,3311AF1EE5A89DA9,0392273C8DF1464A,409AE323411DB458,54B4C0E2A00821EE,60F7310CAF626D16,74E26A69E5C5794C,000015A6FB1F8FFF,D5FB4B81892E5B25,D7E52C8A2AEC7A6D,C203F6EC187DCBC2,5A929E976906CD98,D8EA8A2097DE3577,79787771687A313C,1C5E922B61DCFC6E,873C601386588330,CBD02737D6706B27,7E457CFFE07EE9EC,AF6B26833068A093,0000329E99EDB740,AB8E18D010B94A67,2BC1F2F4EE69D922,5564F54C3423761B,C9F7F93F5FCF8240,3E3D15F22EE34C6D,39BAF3B8EE036402,909135F965413C1B,0F8F330EF62E1B3A,E0301B730E577523,9C06A4DDC87C6400,A61FDFFBF88D98D5,00000272A479C495,A6EC7C2A13E4459A,805630C5906DB1E4,2F183F6A1D849FC1,065A9677D316FA8E,D51EE1222FEE6A07,D955B8B66046A156,6A42B66ED644D998,DA2B226A93C0D248,2CC2853E3E27B5E8,5530622ADCC1CC7A,52386477778E7221,000045907AE82CA6,8FA66FE88AAEC818,A7E17B393B78A594,50C146EC3D2CC682,BB8DC8EDD047E8FA,B995592DC28B697F,5FBFD37518EA7EA8,6FF0C7FD0BA8C9C3,1DA889F968EB5474,023F4C5FDA8EFD02,B67DF477A5AD0732,ECE7CCA11AA03D93,00005846BDBC50AF,40F5EE88F8B602B8,8CC828806495FB0A,2FB92952A319EA0A,54C6D177233F3C87,E33C7B1C5E65356B,2CA82491A0C6EB34,DCE71871560894C6,8F8F5899DA9BBA90,15D815BFFB4D01F6,7C4213548BA992AF,E8F0EF802401C26C,00001DF755FD2A3C,A454ED2F20030610,CF6635F8177E976B,75FF37AB54ACA863,31A5CD47DF7BC3FF,7F1B491D5F2E28D4,E7A1400A924B0420,FBA30C9FF07D06A5,96A29793C2B745B9,9442AFA4173358BC,9C064B2F115E71C4,74CD38376E3A8584,000053BD862695D2,525011FF7053D1BD,2A4215E20D78ECE2,D7E6A741F337FE1A,38A73930F4A8C77D,7BF75A38E09FBBEA,BCDF84AF6DF68EAC,CDA8C17A58F2B855,5B5F29F0E54DD10A,83AC0BFBADB02DBD,A45631C701E90255,BF836EA8D059C32F,00000DEAFB8314F3,DAA48F41E0DEFC28,419D650C795B98C3,1EF57541F4A1B879,8843A20BA2EEB787,1B68B615AC0890BF,AF690739F536C001,7482803A6607BEA6,EE3E14D994DEC5FC,1E9BECD7ECDF4B5F,E855BF3DF9779665,4A6EFBFAF61BAA9C,000040CFAB0B12D2,5B1D29B0714A4E2D,FD08FC47178C9763,7FB7C5E99D8CECEA,0C7CBAAF6726CBEB,8B46A262F821C290,9B96A3F4373079FD,C840EF9B6DFAABDB,BD4C1890E2FE3643,B3ACEAF0D63B34E8,5ABEEC74A6B8AF3F,3C546E599AA46F36,000055F99F2D997D,49BD0358B747B8FF,CB31212DDA4AEDD8,A046295532FD4AA3,FAB8AF7493F3F673,186FB1ED05FA2660,2F9D6E65331DE2CC,EA14082B49CFC293,ACE2811D335ED0C6,13E483E18CD0C324,38303F928A4C02B4,107ED447C0976D0A,000039B78671D331,615433B06F8C2B2C,7AA972EAF0D953FD,45EEB32A37719A27,680AE8CC059E4031,789D1CF5BCF54670,FBBABA41DFA5FD21,D0B3E2B4A52699FF,A7D36CC74B6CF069,06279DA6908C332B,1493BA827DC63B36,1D28C8316E1CC305,0000449DE4C707D2,59419B51AA388B22,14892D4512E5B7C4,EA85F9A7B0814FC6,C409E29D3C4732DA,F5F4C8BD9BDEBE01,FA7F3758365A27F9,2262071E4CC23D82,83BCA5E0A20D58C3,B4D8CD0C6B5D09C3,CE0EC1C45AF1DF7A,3B2C4EB61A7E5C89,00006BA3BCDE8F71,783F99067F5AD090,DEB3320268FBA65D,BAC8BCE03F6E10EB,736D375F2CA8A454,6CBE5C37DBF52AF3,E1A0193755325B16,77498C4BDC7FEE7E,D80C4E7A3115D784,13380B310D70BBD6,85299FA27602DEEB,EAAF8298CE21AF83,00005CDAE7DA9021,3030E0C764107AAE,FE5775948D686DEC,C2E966422B1BE9F4,C588917DB16BFD9C,D259C056C7EBFB20,F45CBAE18F6FCD1C,FCDD262A7607FD47,F157E555F01FF812,74ADC08C5B8C928B,EAF67DE364BA982C,C8903D6689A95E9B,00000DAC8604E51C,E2F344376BED1025,6DDFD6CDF9730324,D91F400DDB5BDC84,30D07AD0A726E624,AF3FA69F3C4A07F6,DF7F080552E4CA3A,AEE540E977DD0EBE,E1AE1B2A6DEF4C78,3C8629B5609A9520,13DED6F4F08E63FA,7B3ECEB374445DA3,000007707798EC3B,13B90123199052A5,C228A3D33EBCD58C,866156A250C82C09,4D22E2B98D6B1077,4A7CDE5FD9B09910,E46DCD8D5C96AC29,4C9678745A879976,E7DD5CA2B57B17E7,F1CFFF3369622F46,39DDECB7B437A292,921115A2FAA4D4CE,00006E996FABE222,205B1A584EA05DD8,9E79FF52C0F36D4F,224112305642D4F7,AD94AF18B3F2B5D7,931C9BA436E2574E,BDEF56CAD118BA43,53CC8AD226FE43B6,2C54639D76E71391,148E6B994303D897,47005F890EAD1D9E,B7043F539301B20C,00000A9709F7D7AD,79912C8F49140A07,7FACAB5EE6E7D348,E97D2BFB35E54DCE,3FAA49F458C58B47,7237D405EC2A0849,A5100ADDC7AA3FF5,4E74EC4B560F7417,6FBAC95E774CEF4F,1126A123C5A2E9D7,B761499ED46981E3,08D189AEC01968F1,000060F0C8EEC576,9437B2E80F93563A,EAA10FAF5D9DD9C9,586270C66CC35B72,F599B0DA89911B58,1B13551AC0B0D0AA,F73527C2E21D00BF,8428D10FD6FA962A,39431D2CC5FA11D4,3F83CB2E1323635E,0A3C18720DBB9A64,29A197776E24FD3B,000033A49EA3F69C,8F53CF66CD63BC01,E6EC1E8A0C6AA347,B5365EEF6DD7E57B,F0461DA73CC494A2,084DCE77A0A2C2A5,8B3E0A0028671E3E,1FCEEFB0BF726172,C684236B66EB6A03,0435FB02249D07AB,C8630974AD0A32EA,B09AC90D1A15AA56,0000528862025C64,043BC26EF609539E,7ED824456C2D99AF,25777954F123722F,55A74069AD373831,5EFF1BC949FACD4D,5962BF92EB06D77D,DBD38AD77FE469C0,41E1EF8837C8121F,2B89BF8554260F3B,AC9D71A365432AA0,3790FB9364DFF961,000035281297B25B,045142E3D11196AC,4982060637152462,F46B959334FAFA31,350F5BA347D29F24,35D846AC81F9A1CB,37EE5DEB670B5808,B6515F9A82904494,02B24E88E6A660B9,A76CE7CFCECBC8A5,A4F632E998A55D0C,5F49A6DFF6E807BA,0000255B349EC329,6AE388C72DA972A4,592B26221F3811CB,D29D43EA9AFB18B7,3F9B88AB5E7E482D,1E49BBCE46991A17,05BF12E974FD986E,0C6DD9ABF59827DF,45B4D863945C557A,DB87AD29655D730D,6B88B201A7FA26B6,39F88408E9A1DB21,00004224954EBA90,DBEB0483C826CCBB,7D889CF9D87DA076,C0F5672A656F98FB,2834A9827D52282D,77DE2CD364CB574C,3344E5A9A8E3F409,C7B83138A0D1123E,E4D67A37C48AC8B3,7247AA02CDD6EE75,B2525822AC67AAB4,18CB002A219BDD83,00002686904AE507,46579F86BD59B113,1D4F0472E5096744,8D489484C95B000C,08788B238B114EFD,9695AA39CC58DC2B,DCA16233D7BCDCFA,693102322F64852A,19F841E39380A3F5,ECDAAB820A163E58,F26151B73FFEF485,276DEDC2D829F3F5,00001C53FFFEF817,330CC3CBE12B79AC,2C55BAC9D6D3403C,BDF87169978EBC21,856752D3559B41E7,EFB2C425119FEB8B,EAA09E173CAE094A,664CC8031328F07E,3B8A9CE5077E91BD,7C6F70A6794EFF7F,4A32E829EB42A9E7,E7CC750BF7ED80E4,00002F63C0592769,194B7CF48DAE2C03,9FAE1B3741F06F14,F406410B33682BE4,4316D434028E26AF,F0E21E6C918D2078,933968EDA292CC50,44986CE020A490FC,2D071A4BA3B07AF6,E2DDAD341520D245,534E10167BA055B6,C2F919723ED564BC,00005F1997CEE41E,B1DE0E2AD126E6D4,6F913380CEF98015,D202C54D225119A9,A4951C1CB3DFF2E2,14EC8F0A44671648,23DB7D9FE4BC0FE0,F42E0F56912C4D1E,03B53193942342B1,95064843BCF54D8D,A5E1D9A6751B89F9,7AA3B49B80201934,00005C0C7FD80162,9063DD7A7413399E,026B85B7EEB6CD50,2D9AA240DE84CFD0,962BBC54A553A127,C1C2AF9D82F9E322,75086EEDE8C45FCE,B6A40AF9FD8D7BC3,66EC34796838056F,BF92706F780AE414,EBB9DD5EA2AEEA76,0ED8F9311B530F13,000015C0EFD09FFC,398F7A2F4D9929C8,5C1A250DDEF4D2D4,EC165B5D5EB4070B,F3A225F8DFF2135E,020F2C6631D19C52,DACD1A7D00A3E2FA,68376A47F492ED9F,16628EBD3549DDE1,0533EDAA771D7CD5,3B4307C0A050B576,32599109E0FA7E43,000059C37F474201,AC7E825EF5D4D86E,17E351116108DA9B,631424C0EBEB27A0,82C8B2EAAA6131EF,FE6B14927314ACA3,9E97981239CCF8B9,7AE7F89672CB7009,E72C29FAF1730472,90005F2308EE319C,F25133EA4A802AD6,ECF3BC1C8BB7499A,000010E8E07D0333,E7EB8CEB1CE4A564,7B83F1BF0A157AD3,DAAD784CBDA6BC57,F917C90939F2F156,00DEED015C8053BC,B06DF92A2338850D,1BBBD69A513D06FA,26B25406A5009F2B,BC96A9D2E4F2EC30,96175A394F52ACEB,264134D1A5EF59FE,000030CF2BBDA116,909A89BDC0F9DE35,E49FEEC2BD254847,A059744FBCBD0F96,88A712A4619F36BF,4FC7C3ED06281848,0BEFF00853CEFB68,07B757160F903BD2,4B2004090392FBF4,E37CC43B4328CFE3,C83A76F7683C9752,37A97CC34CF0B5D8,00004C324FDC7B4E,7D2E4A1FF98809B9,95D34E5A6967327A,8E58AEAB3BC49E5B,B986C93BA68377A1,2E1E550A2E269B3D,74A73121937F7A0E,F42E0A76FE766AB0,7C4D98FA20C58113,097C64CBA273005B,6DBC3464592557FD,51C9375650F3F91E,00001004A2FA9E2A,DBFDD284BF173868,5ABAA803CA4B508B,8B4E01EC27601533,22A7C0D867C188F8,8B973BE5A9DA1EB7,2B20E8B5805AB5AB,202CF56609D16A6A,BB6C94D2B89E3761,BD0C2DCBC69C9A72,E4852977F14E9EC4,3DD3A663626C1F7A,00002624E762F5FA,4877CDD3F1A73581,A07846CEA60C0A31,4411B13D7062FDBC,F37F268B482E5364,8D45ABC2BD815426,342405BA716DB08A,27CD92CF2BC3C784,EE80F57AADC0DA04,7E7AEED3F57E82B1,5B6B5F324B049A9C,8F6DE7E19A02B750,000055366B9FF145,8799078876BDDD38,72D09EA810271451,BEEC6FEF1743709D,69754BA66BF7EDDB,61A0C32F687BFF55,DC85AE3836457C10,186DC209C7C21020,46D2643FACA2F3D4,F94D535004B184D7,733DAA749A133812,889E5710060F4FFF,000061E8C9E9B2F4,8544D4ED01A64933,AC5CF68F7C54B01E,829D04718D781237,0D544B9741A57B97,C06BEE422E1FF1D5,0F2BF0AC59707820,118A193082348585,9B8470F5AD1925C5,0E9AF87E9154A41A,3255C0409ED3AE41,9D9286C20C58B6E4,00001B36DA22D6B9,99B1D880A4A03FFB,3EF8B8BEEC445636,EACA8C9C5356500A,50778AA48DCC1116,842764C82C59E675,ADABDF264CF341D0,4BC27DA6822E0AD8,7C740CF1B2084D95,967BD67CF9BF4B4E,3B0E9B2EA90146A4,686152C5EA5DFEEC,000036001AAEF62F,88E3AA69359B7F71,F61E62067F2AE53E,9431EF010C7D704B,390EA2EA8CC9EBCB,A7041BB36E99E179,4E18ADAC14962817,7098029E6D37CC9D,ADF01E765214AC67,D62514D6600A9DFC,2C2C4A40C496F6D1,69ECCD2D8B512500,00001D013192EE1C,2F116B1888597EA3,4D86D34F481A4C4B,A83E96FC475C5EC7,B8918FB72CA16A7F,C23F6F9D07EC4C50,AC70E8B865EB7672,15072C8B66FC743F,FA1C4FE8C72F3512,5A2F51D64FDE0CEA,A30BC773F0E344BC,423282FAEA512479,00006FA0544889AD,A386A6A7529E6B59,FEB61AE9A4832624,3193F67ABE7FEA92,8724458D4463333E,0768A65514D55674,1A55D01107D69AD4,5E6A2BA5A19AF132,8561D40D4BAB0C17,C4CCBC97E7AA395E,6B81CBE45CD23DFB,EACF1E1B247669A6,00000A6D040B6179,B0423EBE6461C452,EBFF40C81256C2F3,806696A0994DFC7C,46E215C8D8A20F54,A033998913755E32,3C8472D6BC655862,1293F75A5A38F3C0,F2FEFE8AC39F8D21,947F028DD1D7A6B4,24E18E2FBEFC0CC8,711B507322C923EA,000044DBDA6ECA21,71A133AB29498F2E,E1111329BF8402AA,02FFBD7D7DA6F881,2CED2B2E220D58E6,D1DF8B6FCADC8067,CF95B555667C6EA4,3B01DC62CBA30F7A,35C7F7E9829F9EA5,56F1752546F3542F,C1AA9314CEA1C15E,60D01C65E3CCE1D0,000058CB6EFCC3E5,E70AC8DE3E006BD3,0ED5D4B9AE9BA127,07EC6F6CB64EA672,000CCA35ACC257B7,40C9A07A26B3D63D,A61C5D43A840B379,49DA33FFA12F569C,2C1BD0A972BE7F74,8FA408466152B6F1,90AB9C37F7D31982,8728D479BD5AB1A1,0000494AB9597122,0F688490DDB38F44,8D5EDE25353D99CA,5659ACA8CE30EE94,DEC8A99DDD15C7CE,24857840853EBB71,77A9AE6BD2171E24,393C21DBE9E50DB2,9C131854B2FC96FA,66413322341EB284,2EC02FE5350CF32D,611BDCDA70EFDE7D,00003E67A1DE37E5,EE91C4ED6EC16ECB,DEE398E8FE99B491,A8AC6D40C14C4AB1,89AD1B136ABB523E,DC30B0402C4B7A87,7606A3E2DBF81044,BF4B5A3042A1842D,E98E10793D514F41,87ACB412DE58E2C5,BC73516ED421DC21,178C7725BA1B118B,000023B7920689FE,39E148F6A78F41B9,5AFC840FC854AC8D,1DB0C87BCF8BC71D,620452678F952B6B,F456E78F0C0710BD,2F61F3C688FC3ABD,0306B4436A7EC95E,70998F21A2E06266,AD881FFD12743344,49922E20C936AD53,5EB7C1238C033B83,00002E0E42EBAD37,78FCCA452F4BFE6A,90BECCB7154C112C,5D4960B4980C4BBA,55F840150B9EBBE1,AD2DA4FC3DB2919C,DFDB9A399091D39D,EA2261F2B1EA44EC,8406BB819070D924,54028C0850F49D9C,51DC04DD5A9E2E6E,139E8E5992F900F8,00002DE8CD9B5CF6,B5398C46BA0D16A2,1645A85C72834695,06766EB375BD21A0,97F3CD2A868851D4,5D6A7EF9DD62008B,17A2F749630B147C,AEF1E8FAB9B52DB6,A181B895D8FF8F76,465ADEE4312B3D7E,8C88E362D3C6B515,35C46436ED0AAB83,0000119D8F0CEC8F,C8458E4BDB6DBBD6,625FF3EAF0D75492,43F9671EA832CA6A,9D91FAE79C855E5A,A98018A8989A546B,84B389FBC8B0EA5C,77911CA0BBF54C26,4E38A2339CFCC947,71945E0D297D169F,56900323CEBCD41F,8230C3F476702CFD,000027CADD77D17C,4D86F93A1AB3D712,76912A405D3EAA88,BA6E2901C3E3A5C9,3B5A27140DFF7C5B,5384FCA427D476BC,42FCAC42302B3858,035774698D64E521,D5BD777573B77CC0,153F1DD3C2E5E036,99FDF10E4024DDE3,C4B25459255D2F83,0000297108C0F6A9,17E7B11BBCB1F0D0,9EF066B5F8F2CFEE,9303E20695D60D61,DDF4F805DA2C473C,4E805DDA588C36A6,C836D3DA00E551AB,8804143880DDEC19,0742E440D9279FA0,50A73882FCFF64B1,94F171328BEF7C27,D9B5BC3D79024362,0000049D9BCA7BA9,F57BD020A88F907B,A3868975AACC53D0,6DC78F1DBF0686C7,2EB647687A3B24EE,BCEFB1AC0B79E69D,66542958641F26E6,DEC15CC6F215DE53,64E7653CF38FA7BC,A81B126D593BF573,670D7EC3DDEC01E5,97FFB81801219156,00005B3A798B7372,47E5D7D389CF0A56,90662BBF4D846DD1,4081AD00FB8475A1,81C662D7175553F7,0F3DE703FA2DABB0,59731FF96D76216C,FE7338FD879403C8,199AB5FFB3BD1333,73ECF3871DB718C6,58923DFA9375E81A,D34FA5B495C28509,00004974FD6A495A,C11DFEB87EC0B61B,453AD6373196B5B3,EF24B4B2DB48DD7F,84DEFB1F1B424239,DECA14804D494456,896498CC80264AE0,C8DFF98717B9AF5F,FC6A847DD0DEA108,8D00E48542CA62FB,3FCDE340C3A2F362,8731950A49A8508E,0000633BDAC96549,ABE5DAA3680A68B1,107DD4A06BC6DC93,A8B052B8CE5C1B3C,6E5C4E6FC8A6494A,FC226E6305A64A75,0044DC457292708D,5D4F3C4DD90A6647,75D4E8F0B2A637A6,9BF5B3A632D70247,F7340769B5D7E0DA,2EC074F8A94D9133,000015ED39F0A7A0,5D4F1284DA767FD2,F1FED25E94BF7B24,2C4E64FB16102CC2,A981B9E918975124,9950DAE15934184F,3E6CF2BE56B3F93C,F6349E4D746141BB,F78B8A50B39C07BA,E429780D9CAFB893,69C4A22E72906762,63F385D5AB037F57,0000089DB9DDEB6F,858F7929C78508DC,34A0951D465C4201,27AFEC29A6B2AFC4,D0BB41AB9B690F27,9DA0DFB2D10A581F,D17D042AF97C951D,3C7E6EEB1050A489,C9C2EE4EDEAC8063,EC6862EF032F3BEA,40199BEFA59050C0,1C23D8ED195FB3CB,0000289752200927,6F3F9D4606C1A777,9D44EE286957891D,10C44F48D45F9DEE,0F83D0A23BF3F71E,780D51ED855F7411,9937F2381B9BEBC0,4E5FB2425D51F04C,68F8B78CB0C992FE,917F66454935DDEF,61F8CA99D461960E,01E06D1D9A4FAB8D,000030302EF449CB,2C1A280A25480017,18F84D217A4DBFA5,10675F3710453705,D5F572752280F039,B8F5C52B42A665A9,D5D4A849F4F79F68,432D691DDCFF8507,5D38FA47649A6601,F3616C0276349207,0426AE99BBA1BACE,39BBFF81EFBA7778,0000152D09F3D8DD,0DB77E992789DABD,2DD16D781A5B0D30,69B5CB99E605E351,554ABAA7C93640BE,61A2B090C74DA52C,D7A339D34B5B80E8,C4D20A97FDDE1EC0,6BAF4BB3EB6AA5FA,4B7047BCCB60A91D,018C5B3A9EE7E616,64038465C49C433F,00002A103215843F,866416024688BD90,000103C6318D08A0,7C85B44FE5F96261,C3C6E2FE36491636,ABB2484337290482,4367AC4D4480D73F,86D945EEAFA1C857,EDDF44A7CEC7890E,0C5FE9EFF45AEC3F,BBC6526311550146,6A6EE3A82C3F56B6,00006137C0B544FC,15B28382D817996F,72FE3648F1847233,94A9E08DCB3C3189,5480C84A12A171F7,F9A2478CD70C190E,22B9D054875F766F,690D237261E6CFB5,E287E322B4F22B4B,7614283EEEE0B7DE,3187543D6C7D69DD,AF8D16B8D76DBA16,00006E487CDB5280,3BB563186603F51D,0996355949700FCC,43AF37CC1B2199AA,740C4000C1C99E87,32F866C78253E101,04E104CAEF6F2F57,C1E87D425A04D276,5C655DF6B429FBEE,E9C9972451AA4B1B,20AC0FBB77FB83CA,3ABB3708DC40911E,000037B05A734213,DB3E783D030CBBA0,28F9D4C9A16A805F,4E113BDBFA2F64FE,B27C1E0BEB4D8618,72838094A9C9787E,367AA1769E656AF4,8F528A306C614F99,3B266F6A977DB1CD,E3998A43AC96E045,54BE7B51CBED73C6,A82DD87F58BBB97D,000034F62CCBB982,5CB58E9E589E59D1,4BFC9AAAC190287C,238B193443E1A49F,E00108887FC7F160,4B837F8DEBD77298,4DA133155D0A20FE,760F383A5744EDCC,F309C8C71D041918,F6FC6F81EA41036C,41A5F2C6B67500B3,64ACC08472ABCD82,00006CAF6F119152,5EFBEE4DCD0D8CE4,34379673B7AEDC17,E6F1F7696C2DC946,E3F7FDEB1B2D63C1,4EB92AA5DCA5D6AA,BE0FC5D15849A72B,D8D96F51025CF6C4,F7206CAF194F1D28,A7F0B3127514B678,157038EF8A0BD505,74CB32FF17C87ADE,000027B6A98AB43D,B7D197B390635C0B,5C5395FC640FA1E3,1F3510250FE26AF9,A7A9BC6951D1AB92,934F304469CB4695,7126250DBC092DBB,82AD338D93067460,F3D4CCBCD9A0D637,83A01C8079322DE5,82F8DDB542DCEAE7,E80B620D953290B5,000060D232F31AA2,E861A6CEC0872F50,78D1B878AE3E0BE5,3C9F2E21DF72C3D2,CFC1F154FC69B073,18490AE8A7481627,EDE3FED7331C471B,C3B3F0B3BB9284E6,65C5CAB466D5389F,A22B959DECA06767,E9A1FBE8D0C1BAA5,0A8DEBEB862DFC6B,00006673590614D8,DC96C88E6F4F9A3C,8D390081A06C3103,77C2FAEA96CF1EE5,246E8FCDD91B576C,0588AA778430E3C4,41BFE4D5847C59CB,EC016380838B547E,BA6118FE8BE297C9,BAD0B6EEC4878DE4,6C5530983D83D820,6306F37DF101D014,00001D71A4390EBD,ED50BA7967522BC0,4A32FB9D3F3960EA,93B20316BE10E5A5,EF78539D6EB5CA97,B816B1C1B3CD49D9,3A2AD245FAEB827F,07969B72314DB779,D4218D46EC5A5834,8DB055059B15ED28,B827B672C9320CAD,EA0DBE482C10A7F3,000012CE1314FCB5,A2FB5AD833AE92D5,CB453F05C511DEF3,5C530ECEDD1160F1,24AF7223F08B22AD,63922D8CC06ECDA1,B83E435709A2E67A,D7C630E7C584E19C,BC32508E6DB9F348,5774DD27658755DE,CCE216491460CC68,D1AC03F231D1BF98,00002C1AF6A3DF55,78BE7D93837C325C,0AD96467243FBF53,F69595B28E5AF159,BFED561E3D486C86,607B7034F94A01D9,F0C4DFF0E469F839,B7AE6E1AF2B9BB5A,61ACA0F5A6B6E4C7,E16855799F8E9F87,1C09354556149305,CF34F9C0B0E1334C,000056E100DD967F,3BF8722310B0AC58,77A4409D2DF9C43E,7AB02191C916EAD1,8762B2A643CEF460,C1AE80F2B1890E93,DAC73CFEF8F67742,7EEB20FB39C313FE,ECF7BD8ADD22A9DD,49005C0B3CBE9B62,F79FE71FDFCBF096,79016D603B2CF338,0000695D519449A8,C5FFF77892DF291C,40F847DA54594D4F,57BC52EAEEE7D9AD,7882FFA139788D53,83746B829E704309,C74AC7D6E997ECB3,3B50982B69C673F5,1E50A9B6095B691D,1C7549B0A95A52FA,FB6E6567385ECFB6,C7E884B1732B0F4A,0000382EE04A75C3,631683DEB4A71D79,21E071EE3EEB8E6C,655FBC1628C1D61F,6790696A0598C58B,CC4F469E6D7FEF7F,2970E52CF24F4220,BDD9184971C9E910,FF552ACF0DDA75C6,2593CE5D37A37463,F473D9A079B86501,C27EF6EF2F671E07,00000D5A08D1FCA4,8BD24FD7729EE79B,0F1E45346DC0437F,15352A36AC88BDFE,4CF288650FCB98FD,988C93096F1E665E,ED93702F56163F9C,58988F076D7A1FB8,F8A23175B05B219E,E6AF86D5855EA4BA,B2F4AE2ACBFAEB6C,E9DDA77CDA48F313,00001A060955678D,96D898DA7E275460,B2A4474540A7A950,18ADAC67C3E649B7,EF53D47865AB19B4,DE1496D3EBFFE7B7,E7E6815F72DF9186,4A6588FB9A4B2092,E481C87E05BE0AEC,C87E0AE0F6676F8A,8D4F660CA92AF2B9,2E16C11BD00AC446,0000095E860E08DA,A7894A0F97D338AA,A91AAE963C0D34D5,E38CD97B29B48394,8818C0998B702145,D9109235EF5774D9,044125DA8EF20ACA,9921944AA1B23EC0,79720125068E7C22,8946453641CBCDA7,A19BB2E4AF10E534,95E5FF5267480709,0000415384EAFDE9,B0D5A79D7DDE954B,CC5834FD470148FA,AE247762A3E18F03,C12B3340D49C6570,C976CD39BA478ED4,88F45995970B2742,1C79D3E405BB8E9C,CCE7657239CCA6A8,97D5C5451A5F7E20,75DED29CE1B55CA2,2DBE02DC27D38100,000069211C9B5A71,BB710C29AFA269BE,D223A2E5CB0B129E,1735A7EC19B9E1F2,D03B158E6E2B0E74,10B22EA002D01EE3,0B4981C7ED8558B1,77F5071D24184523,9793148436A68CA2,0B5CB038153AB1BF,123AD7AD1B8DE6F3,F2BACEA25C6A8D8E,00004A1D6FB2CF42,97AFDC5BB84BE699,19611FF19E4D9483,0F44199ADB757FDE,5FEEEF09C032F18E,971C4CAD5AE26DF9,5CB6D385369A64D9,7567661451557F6C,F475183F3E4C7E10,CA4758AADE427C25,859DE34C4A7D1684,A02442598BCDCB16,000009DC7205A7CA,50F664B929ED15A0,A3812D7F219E6534,46BEF1E10E96BEE9,17F6CC0F52E1D328,01D9C619D6C259BC,E83F5F0078805CF4,2635FD0E24A5FBC6,16A6AA8DF381E317,64C11D67133C4DD4,AA33FD044B09FE1F,497AE9A4B973C840,00004FBEFAF37874,E234850574D76256,15B7FE1D497C1BEA,4F19E92184E955F3,22C02A315AAAB365,91F21BDFD445B5AC,31E3DFA5CDC2BD0E,E975BA2AD80AD98A,BD460ADC421CA68B,397E5E6A3DB738F8,B8DC4435DD24CC14,D05AFE53AA080765,000062FC9E9AAD77,AAB69C569C84A632,1A59B916C7346673,03D70DBB3B1FCB25,9D737DA4935D5EF9,1B3A6367F1E4214B,EF5DDC26D2406B06,6560A052B60B9B8B,F7E6478B377D8C24,A77698C344508D17,BEC15394A925BEFF,0D1F5A55088FD0DE,00004A9D5130D4A8,80C23F89FAC242A7,8D9A3AA9F2D8EC57,78812A3BD8411391,0F1940B114E4BEC7,3E17EC36438A3AE4,78D84F88C9513358,E48581DB31C927C1,2376EEE7E3F10AC1,6453D743F8DD3F9F,6B57E085E690D301,BE8B527488417BCB,00001E94C16E75B8,A3D5785EA64530E7,281D231C5C7D9737,493108D91825C481,51A56A366DB066A9,D87BB574B5623B29,AE5068E9E997B08B,41F80F38935F93A0,7E655E808BA10290,FF96F17D91A5892D,36F44C1A90F699F8,78B35EE0F24DA540,000029B668B01E5A,D14CCBA32C5B5A0F,A718DBCEE0A1E8C3,647C5528304C2D9A,894DF2E9DECE902B,49FCD1EDB27B499E,73D3B69F8EF5716F,F1DB36C881CAE287,0044534E8736DD5D,F62E260C84B9EF51,9A31528E80C6CEC0,156BA2E3700CDC26,000032E2C6BC86E8,0422037422A84830,0221684887AD6628,228B5277F54FF1CA,D8B2DB39C684D36C,5D47117A1F0DE036,4914D9F2D7FCB030,A810EB2C0AF82B15,5588E815C71ACD75,692E8114474A25E9,D8FC909F939ABD42,3AD35EBA9B45108E,00002BCA80A1DFA1,63E4BC5327FE2DC5,DD41B4F2E3F26535,811CA4D4DE2E25E8,28C4C1C05BC8FC1F,9E23B2CD46D42E37,09DA3DCA6E80B21A,33F099D311FE1F61,5CD2FFACA8AF7F3B,E2C75CAC815792F7,660F94B8C24E8954,338A7712AEF88083,00003C3057001515,3C59B5F160471FE2,BEF1838FA51D9FE8,40B0B4768F301269,6F3CC8F5873BC2EC,5BA4BF4F34BF7E45,01192BFDC48A76E6,C5152D36B0549781,80A1DC0D19A90915,D0EDC366BBEE74B1,50204AF3C847D95F,A34F3AD0492DAC64,0000090B57C76303,AB80B01240621164,A8C95168E4D1A357,1138B21E293CBD6D,72233703685A8D59,BC05C4663BE96D28,07B3346995292A13,AF61767C1F3C59BA,F7C04C6CFB108A03,5B21F45F63181D38,BB91F6F89A7678F0,1A958D1734BFBA3E,0000644AD8818CD9,4537545B1EA1E920,2D22BE28EBAC3218,9B60537E74E94734,01A646B4B3F97330,3548DB6937D18E05,E2D29F28FDAA3A36,0EE47B255397932D,66C0917A69AC35EB,FF784989890A38A7,9FFB72F77125AD4E,B0D7F6DA839FF617,00002DF9D220A8DD,C210C4F633CE9022,B4963F069BF55373,3CBD5B0C6BD0E097,ACD776A6B61F117D,3AB62DCCACF23AFF,925E65B51EC7CBD2,D40A33C172E02786,538EB559EAFB2983,91D91593F5440E10,AD348897ABBDC054,D983CF6DE96EA45D,00001F98AC0E83B5,FDEBE95D0C77C139,AE6B9F07C11864B0,A6DC52F2E46F3284,999CD3CE41547919,B73D963F3846542D,58F8D9454211FEDA,768F87E955B87F41,F519850333F1AE06,2392995A57976BC3,E47083131D5A8C49,A81D53BB9D41AA1D,00006B7CF363E9E7,EEE0A3DB7F8C6793,251F6B85A43C584D,3957E8637DC5192E,7789C5272E1E0410,1F3E46A90DE30F62,E0CB19592CC9534A,7CB2CC9E433EFC68,C69092A45898E073,DBCE9A1A9729B9E6,B65DD0B2C76D26AF,866581FC364A5440,00004181229275F5,D7C1B484D7ECE069,F2392FC08F095805,21D3D25B755922AF,3F45D3EA4FB9DC12,7DD49C243C08711D,5583BE6E8AD21A02,2620FC00C073F540,AC4836692012F5D1,5D57D65542BAC56E,2DF88723A6EDF586,44171938F1D0BB72,0000679838A5C179,CAC90B35FBD0202B,8D59A50D43A24671,D73DB609DC48BB12,CE9940BF205A74D5,933025C3810067FB,EC041C57AA7E3F27,B1569E70E795CD62,D672A322B32EAB39,6ED9F379C660855D,84B58C2BAD79984F,510EEC7CC35B11C9,000062DEE8DF06E7,E7E2E3C95F333D31,9C7E312C0F75A49A,913E51787509BD05,2893266D82C06EE8,EC5831E5EE81FB42,4467807CC2876258,CB76E6968DB74E50,CC985FEF97F395D2,643A74BD387A5EBE,679EF7DCD2E0DF76,B43952BD82D8A14B,00006C77B9D70B3E,106F1AF263D07153,6CFCE9D9B5462D8E,28AC7DBBA8E7EF44,4BCE2B3070C3EEA8,4B3A9FF40AAC73DB,F6129EC7952481D0,1545984912517503,6F85710B317F4FB3,A23D9DC9932D706D,CC493F7B3A96696C,364A54B998824541,0000409E99691AC5,FE5382AC588722EB,5FB62ABD80D45AB0,D238F77C259FB641,5437BDF23A0C530E,F9B3D86E6D733B2C,56C3F5FF657972B7,FA76393CDBC70516,3628832B2A372F84,D27DBA5727F2DD96,1E48F2DD59E9A25D,FDD2BF87E059CB99,0000380A33D68F0F,ABCAC8EAAD330003,6C3F9FD15974853E,8190D9C71F5EBE8B,D92EFBBB6B95B6C2,03E355D17F8FDF4F,F36B387C348EC3FE,14CAD5CD139A1641,AA2675BD5EE14A9B,7B39E1866A265BC0,D75F8EA17E92C2C3,74CCB9A45279F21C,00000D9E88D06D91,8995771DA8F293E2,5A630DE3E0FFE3FB,F6C523CED66DC85F,F3DEBD4037A19D8A,0EDFB04D313BEF58,DD34D6D2299AE4B2,D79E5907DEC9876D,5F67BE4FE69CD731,DDADBA814C7A0CE3,1BDC0B8998A4D4D0,EA83945C1722D3DB,0000395EC5E9205B,A238B3DF05E08AEE,3E8827D6C5D2ED4B,97B589954CFC2321,EDD6316FF52CB789,9F0BC2651DA12263,52EFEE606C335744,9F1A0CFB5775CF0E,E0A213349AED2833,CDA4B715FBD2AD28,CF674F55077DA828,B78CC25B568FB001,000046357A6538B8,83C0F49BB73E5985,68E10EAFC6AD5167,7C37296F8ED190AD,0CEFDD817280822B,FEB9038DE9283394,8F316BA2A22A0AEB,A11C52843044ECD3,640D18EE3127524E,B208E55A0B9540F8,218E57A2CB225DC7,2A043934074D169F,0000695740768810,5E9C02FCC197AA08,6AF03D8DD41E072B,5320953463AA9D06,2AA5F6F8823A04E5,FBB06D0C3D3DDCC1,D36F11321A7E2831,FDA087D02016C1B1,B84E97BF466EDF1E,662BCA04B3CD3D19,4D9D03927D63D61C,891734F4074A02D5,00000630CA1E58E4,C2212A9147068BD6,31274E725C6C4D36,7DC4D46136B9C22B,4C2D3F6B27DC8429,4475FFB37FF30DE9,B3C5DAF71923E6A2,5C3D0AD63F67A90F,32197989EED3B794,1D059934DE3A15FA,FB85F5137E42137B,19D15173FE67B233,00003518588D67B4,865C9333749A8996,FD9DD64567440EAC,9C7716591FE4F733,BB48E650D56140A8,4786564028A592EB,C4ED4B902649A7EC,8FFD84476209983E,56A61C03FBA202B0,F78552085BB423FE,A2E84AB8F307F96F,CA5A29CAE9C77AF4,00001FC8E72E1C7F,4ECE1ADDECD5A404,5487356DEBCF792B,26FE83F9961C9678,1DA15AF19EF0ECAD,BA58C889D7A00F4D,761F86A0E240D8A8,0444BBF131BCD658,951DED9063120F6B,1B17B3AE6EA80E33,97129AB8ABC97664,93560D1F9D26F297,00005164A74703DA,956F289ABEEB35B9,BDEDC942DD992F02,44F4C781E3F6D67F,3BC5B357FB3D5BC7,9187F549BD2D10E3,1924E6E0F3338216,39C72BE1A4C33F3A,1949268A7BEA87C6,366F161EC02F9CF5,57586AD307106D3F,D058FD5D71858672,00001D0CF1BAA483,5806F1B20303E7B0,BCA80A2649EB8D62,3126EE268DE48B47,6F06F9540DF13C71,358E15F4AEF906A3,0A41D1461F097A25,24A94AD9A81D2CBB,B911FDC0011016DD,806C5FB47CDE5C8E,AB7523AAC3B1FA4D,9A84D65E60D964BA,0000538C879B68BD,B4B9A32F6A5B3F36,F22904715EB2FFDB,EFFD08D97CFAD4E3,260FF243AE19F504,7E13D35C9CECE4C8,ACEF09288AA031FE,8F4A1EC67EFEEDD4,BD24AE3D6F3EE3DF,F427D76A5C19BE06,A3C4E8B5E00806BF,5EFC307BB284C875,0000633E5C0BB0D7,9D891E2B3EDA7354,4F005C943A5001D2,AFFBD1D8C4B439E1,CB6E679ECCC8DCB9,750F5B7542CCDD97,9C0AD25DFD193C92,2CE89DE0F10F0406,BBC7543EB6216EE9,CD7E5CE8B5A9693E,248D56063DD3163C,5A5CA5BE8BB52E74,00005A3EA18F76CB,12D0CED912A87731,D839B0A192D3D253,1260F9F97A535503,3D3D2025278ACA93,7A3917DB93479CAF,853A44CE847598B8,B66D6A63AF928507,029E82B00AF1D381,54AAEC3D5FEBB793,641D13F08B5CEECD,1783FA11F872A7A4,000064C0B280E800,3BF727975499AC1B,DB5FBCF4683CA126,893706B6D7FFEB81,2902667940712D49,CDBFA36B70C706F6,749CA3E1BCB10F45,AA112045695A6605,1389B3F53F05B14D,48BCD14EE697977C,8734FD1A1DC58FD4,117D4A9BC6859CDE,00006E965C92917A,86A0ECF97347A16B,FD418C40A62B152D,6FFB6246E1787EA1,E3E6BFAD7EF9B6A1,9F9E7DA871824896,16A2118AB41540BC,7D3950EC27DF6F34,D995606ADD142F2C,53DEB87D62D86A86,8CF72C0C994C0543,E4CD1DA15F208C81,0000332856CE962D,3C8E5E0059156616,DEE76E3BC8049625,344279A3F665033A,4C8B249E796ABF3A,818AB158757BDEEF,1812BC9867603FFF,1E27419A3E6CE6E8,D2C9E22EFB94DCB5,E5D7671C26568BE7,92EC2B889FA4CBC6,168233C046617AB6,000025FB2CB03F30,DCC21991BBF2D4B8,F7759FF583E3A12A,80F28A45AC84B695,283E47CF8937313A,AEF01BF7C2BFBA49,A7B4E220CE1C5462,F4AAF4357D79757D,64B97261C0C33101,58462D02EE663B1F,D0E43AE658876762,B491178979F515DC,00004CDF6E2A8936,DA7E7332B63BACA4,C08C7754E6654FE3,F99BAEAAA1757703,7056B7D43B5E5790,BF26E3FD2B7BB525,4E99997A1EE9BD80,EC166DDBF106831A,601F23FEB488634B,610D7F7A11D095E2,B5D061AE26794BDB,C98B836EF20F1223,000054E6D6B9AA14,744EDEF4799CCC68,2C64BDF6D06DD1D0,2F0B93C8CB3AC02F,41BD1AD38ED5C360,EF80F47EEDADB639,980BA33634134CE0,624B66332712CE29,A8F51A74FCEC984F,21C9EF7992462D2E,B7CBD40C9C0D862A,80AF89F50751F7D2,000007D06E2B79BF,A76F0D5705D3017A,C9DF532C8794E73C,BF61F713717062A5,6431788444817EEC,0B0F21CCA89C1629,71FEB227AFF04376,23672EAA70AF0806,776C63A05A6B16F7,75901272DCF5D2F7,C7F188CCF5E2A593,C1E7E2A65AB18888,00002D108ADC5971,817139172FD14647,3B4FB9A19D3C23B7,9AE85FA009034F5D,F3F673302B240439,C086EEF617167707,A8F5ABED8944E89D,429A0780180C9663,4E8A01C7B825D22C,43D9E591DA50C114,581E861A9309E03E,49B99AE78560EB20,00000D25F3EBDAAE,AB738747ABBA2649,91D0B012C9651982,AE41D380A1EE7101,1B5F438101C1AB46,F4478D194B25F3A9,3ECB76CC40CE4AA6,F4C7075F56B0299C,778C91BB91B25EEB,41CF1E8537EF4F4F,09FA23F4842A5927,652227B2306FC403,00000F924D15D099,B641288F3A36928C,2DBA6001985DA1B9,3BDBED29128AB928,3A5065FA7DC3DF82,C5166B2C2DC52292,0EC8B1223FF87B01,150E6D6D43B412A1,963FA684DC932FCE,2A4EFB840F02A62C,3784E65BF7F834DB,11510180D99A0BD8,00000CBC6CAAE744,3F286F390FEC2247,B70002A38D292A59,1745D3534D4B972A,7EF8A711CCE09EAC,9C883B6B2D184E65,E102B87C2163F701,E9455D9DB1F88324,1BD8FF8D90B5F61A,217EA78E4FF2E9B1,507B11C4D8806425,DD5C3F209BA883A7,00006B5A4A9D5157,93B2BD50ADC61198,A0109262F6C893CB,C2D62B161538C9BB,5332BBF0A5442EE6,3C7A520D9DDC3072,05BCC4CD53FB8D2C,8CF95B30258B29C4,0BDCD8BE2BFD0412,5278F2FC11F866C4,E60705F9D9F6DBF2,16604E1829DDCFBA,000043A74CC7DB63,164FEC4BFFE48EA1,D320C657ACCF1432,DC4821C282F0B82E,3D7E115A7F7E9D37,FFBD4EAE08585B56,7DCFFEB3D2E4CD0E,84D5E0FE8204745B,A58C62A22C40EB2C,D74FE2F1199873A6,519C7B3CBFBC7D13,528A5DF6E0510DAA,0000313B372DFDB5,9FE40AE1EB1625BA,E0EFDCAF27FDD907,8794D0D3FC1F69CE,9CCD76EA5326CF4E,9D3D803E855F059D,5AE6C3CE928FBF58,6504A50F2514F445,216C8AD64C2A693F,0FC8BC39C0B796F9,C11FEB434CEFA8D7,8C5091C93A34FC8A,000015E8BF39C1B6,D0014A0E3103BEDF,0D0336243B1ED513,0C72EF7DB35B4B0F,339320353900484B,1C2428A657E5943B,1CD87814932A563C,5165B78431CB171B,D1202BC2786E3262,5456FA6C6F19C939,A465BFEFBCA8A312,AF52E2E3E2FFEF1E,0000413BE61DE2BD,34B98E0601D22D67,CE037432C47BC924,2FA39252E007E8AB,15A0A672BE7CAC00,307A69D8F46CF505,B526DDD658F743DD,4E81474132E2C525,B5925C4686E0E287,49B65F78432E41E7,AEEC63C1A63E1E53,0F0D5F12EEDEBE5F,0000076DEA4AE2CE,57653920F039212F,35DF60417C1C17EA,E30DFE952537DF99,1E809EF3B6E064DF,314AA7315C153783,964B05FAD7057BD7,B02E94FA225205F2,5193BA7E869A03CD,32280E2030F8F9E2,C607DB633EF980DD,365582F7596496BD,00002518A03F24AA,3D1C747759FED074,EDC68F5F9C239869,B345ED837072FEC5,5C819D5159F7FB9B,E85D277532CECABA,2B6A56A2602EDD0E,4993D59283F808E4,D28D2219115D90FC,3E9DD0B1772B317B,3C9B38774F9C87E9,D44535A954FB3F2E,00003B666353F6AA,C5F9B9325ED8C334,9BBC7490A0E008D6,BF2023A4615892FF,8C5B00DD95DC6BA0,396D953EDD7B04D9,AC419E43844363A3,CFC95BA4738D904C,5800AE1B5DB80B2F,9124C47986E3337D,5E7B7889D282B0AC,F137535DAA8B6654,000027BF626D94FC,421E76AB5041C4C0,FD586565885C7D68,1FD6BCB10C253646,5911EC9B681B0501,51EB595310DE84CF,A66D1236D781952C,8219268FDE5E9F2D,4D995ED7F0D1C77A,BB9C75D684E2056A,7DE9E3A4198CEFB2,14B303DDCB682CB5,00003C385B0E8DE2,EB89969A9E88198D,01C327BFEE31C966,044FDBAED5677E92,DE2CC39413C60A11,3036C18CE6BED468,636BC88BD69F068F,AA29BEB7ED1D8B93,862D6D106924C52A,4FE95BDF4A5F75C7,08009221D4BA1E9B,14ED5B955D6C9178,0000514405FBAFAF,BC94E55B71B8DFA5,4E2F64E6DB89CEFC,616F9E8FDA89BB33,6F4B7810367E452E,1AF14B9283E1FB37,CECEBD80258FBDE4,B67CAE70DDDE392A,26175E47426CD6C7,F8C863E73F3428F3,8E527B0998AB284B,166A3A7B8C1725C7,00004D6633E09CD5,C569B101544DC5C1,1A2EFD3EF67712CA,8305F861FF5A8EFC,008B61F34E227E81,581F1327239DF301,9AF154898F0AAEA5,EC2963961C27E387,F66F10A72F718208,97418F2E7D83F8EC,84CB2FCD15BDBCB3,8A5F0BA32B2B38AB,0000430EB6330EC9,A06C3E08391BE9A4,C618A8647FCFA887,CBF3BA8B7BEF1574,2EB270FE59390054,FDBBF28BB0CA9688,478D676C98DFBB2B,CF37556512E17EF8,CE017E332AC60A95,2AC1F60F2F2E940A,F5FABBFD04FF7E69,6661E2A5E0D0E0E2,000041D34996C2B8,78366466EDBAB0BD,CFC0FEEA4FA38566,F45E8E34DCE76959,42435B5EE622E00C,E55F3765830CC272,578E0F5B55BEB7E8,6693E67AE0ED1D40,9C13B8DA735AA49A,977A370F7A8AC9A1,62804BD116345086,928CE2B5777D317C,00004711B1897D69,E515E903CE9A82A3,DFC62862FEE9868F,5C60120234B58F3A,96269373BA4FEE14,C20CBC65CAAC7150,608238B3EB3D85C8,018BEC50B4202404,9F76BFCD3F9D0D87,DFCE3455E6CAF54F,34B50C1B3164DEF6,712184161713B66E,0000648D6C08EB83,7390BE7F6728EA64,50C65FE5F8A71967,EC7395374D878DE5,092ACABC018A439B,C389370A5569D5D3,93370D3B1CA92C2F,295049534D2391E7,D4CAEE0C469E047D,EEDB2F741FFBCFA4,78BD99944B3DA916,79228A19148BDA6A,00003501C962DF52,D35CABF1023C7A8B,1600CEB9281B9A91,F7E8E02385C49660,45DB58C507A8B034,E16A6DB9CDED602C,08713AB116F8D306,3343E70E4E03A4EB,86BF281BE6983FBF,DBC9F7B9B2F46666,565AF31B36A598F7,ED9FA12863EC16D4,00004310A580A8DE,8D56BEE72B7F03FC,070C4742DF11D568,FBBE50255EE6DEE4,2A33C5F5B5AF9C67,90E2C88CBCBE581C,8E9BD5269CA4A889,9F7D5C134A10E3DF,D1A3598A6893FA0F,C26E8299EC204E64,7B928DD8F697965E,5DC851F8C9AE2F08,00005C6B829F4424,26FABB9A81F9F1B3,6B546E711EBBADB6,0BAA1F135A1CDF98,944FA17E8446C16C,831093A3C3FFD01F,87893970A75CE305,1196A1700F28E777,37A772CD70E589BA,912F526B92134150,1C829BE5A138861F,27C7DC7E0EB1A2FF,0000247ADA8B1DEA,9936400C50282F10,7E6B6995EF744117,69B7B102DE4DB2BF,D61FE17DF9CFF8BD,7955AF77B3115BF2,F9BF2D80A44150E6,EC6E943E4C4EBE05,0FA8E8FC9B803133,9F79BDAE2ADECED8,845791C61DE898D8,E5C72F9AC2DB2D40,000022941A915D73,D4A8042B9FB414EE,1B3D394BFA2A8850,F1F69F7DD214432A,CB2DC73A1689BDA7,FB579544C81DB3B9,51457D8235B8CB56,033B6E6B8DE5E319,2FFB97AD7929A0DB,F82A9022F8C09273,452635715FA4AE55,F4601477F3C9E473,00001F8561E8092D,88F42676DFB6550C,0CF78ED441C28523,ED948FB828605972,F73277638F23503D,7AD67E8CE061C0D1,1F42EC42A66AD7C2,79BA9706CCA3A347,C6642639DF62F600,21691CF589032784,D72471794ED9C72A,5AC7CF3DAA21813D,00003618B5621C4D,C903364DA988FC49,ADFE708168634F80,EB4F70614DD725ED,117A2B527CC7484D,4F4C58892A5442F6,9533AE0BE2F1AA96,1852BA46ACD3CF2C,587D80DAE208B942,9E189B55CCC29CF7,0DFEE89148C93712,8081A60BFE8A7371,00006C8DA5F5B4B9,51053B235A6A36E6,A09589E461444DEC,817DE5A509A59CE3,13D8E181860A26A3,497BE3B26462EE2F,F9AFACAE7A64AA7F,1456FF09CC244F2D,A4EC00A63BC7059E,753A520064C43D5B,4010E9A16ED3B8CB,6B5912FB10D33BEE,000015210BCC9142,1CDD39534C6CB8D1,C29B7012E00B69A8,E0789A62A51960DC,46429CD37D9BA430,4CF03DF15FF1FE19,E3C72E2221A1FBCA,2B585554D434C830,189FFE5465F16CD8,28055D42EB635722,32C685B7D5A74318,F8DE553661861784,00006D37C324F300,1B47986AD255125E,0FBE88BE7849E13C,B3A8E7940060757E,CE30F33E57897D5D,9737AAB47141A007,369127702E436BEE,152E7730BD2CAF19,70F803A73D5EECFF,FC269C3E93B2BE75,0DAD1B9F511B87AD,2D315F22900F7F63,00004F7271CAA307,D65E15FE0F85DD19,217403B22A9EBE4B,55993D828B39FE17,DD362CB1F5FACFEA,B2AA26D7CCCF6317,DD7E8E8789361156,66B10A2B0E2753A1,C07451D80C06265A,1C4FEB6A80D2B2E9,BAB0645ACF7E8052,1403A6FF704BA6D2,0000357BAC013E4F,88A1B2539CF701D8,8E39DDB54AA5B0B2,23634940B5662BFA,2E9D8E7BE95C3BCD,CCCC0F620A9A3715,B4B9D807FBEE96AE,91A7B1CF9AC6F9FA,7CC4E419E6305DAA,ADAAA0A4D160686C,A79A2BC0D45F66FC,415E20CC713C3BF4,0000279D146BF8B1,770BB4CC1F3FE8D2,77681F58EEA22327,006500E90CE158C1,D2A39EDF11A430AA,9816D31CE489DD1D,38D4CEFA04C8FB80,DF2C10C83BEAC013,6DB18C6DF24784E4,75E4828C3DE77783,6C7DB9D520CED4FA,7F1700F475D7D0B4,00002EEE9DBF4D7A,53A8C43ACC45D00E,1AD5410354491865,0D44B1A536C151BB,8DA8A553C45F8E0B,2D8B91CCD3701E5C,9EDB4916FF693041,469137934E76D1B4,2635C98A29F97377,873C986E9574115B,4647F0CC93B97C24,E68CEBBFC9F5DCC8,00002A965A216F98,E8E98DD03B958E71,585B7CC087DB70F8,84C99C07BF6BCAF3,878028FFB3983536,30D2ED43894DB393,23D3C011ABAE1431,E0CF67F66AE71BE9,2CFD35FBD7A778F2,66876E87430A08E2,7D29607D052E8107,791060450FD2DF38,00003FEECBF01887,E1D9AB5A130D95E6,FC5DF949DA1311DD,F3FB6385B221C002,63B93E14E8789AF6,91FA50CA2CDC9C33,030330252E4BEB81,6603EB9B7B2FA7EC,BD1A3160B9F038B9,1C552513507EC872,EB055617C4C1F1F2,04EA5526E84AC75F,0000202AA2ABAB5C,A807BD18B98F1691,E2D310E56B56A0BF,B4927E7F99905835,DB5EA3A959885336,D3D5BF0B9E893E17,665103E47252E9C2,091EE0021000A598,621E3273943927D8,7DC9EC5B47134421,0BCCC77B670725AA,D82ED9ADF56C1209,000062BDAEA0950C,3EBA9B3A7B4D92A7,46DBED5D934545CC,AAB77867B2CF2AD1,9EE06D5C44F9A914,4ABCFEDF4892A02F,3A89799F7194A166,80D040EB6D380CA1,172FB9F01B7A2FFA,44E0F659220591E5,A790B331423CA320,E10B1F005B4B0763,0000465B91A6DD98,15EEFD3793F0591C,E4233D0126073A46,1F39ECEBB38F622A,19428C195CD1F1F5,FD28439EC1DA3419,7F8453F06DFCA89B,4446E995BC3FE1FD,AC01E3916455A4B7,79D5D2A38DBC0250,580412B6FEC06610,100EF528C6CE749E,000002342B338256,FC9BBD268F949F2A,0C4DA7FD77A19A37,F71C453A2AC3B083,276551356B5B4F48,B18C8D78C5BAA02E,219C14285B234B5C,32ADD459F1AD17FC,9BA14FBB66964E4E,D5C7FB7F32CF60C0,8305B47ECAB12033,9F43CCCB3CB12EE2,00001553F417BC26,2BBFD36CD055A592,CB7B838EFD150B56,38D2B3E11CF7BF58,7ADDDBCB435CBC05,FEB338CD330DDDC1,298212451A2181E5,655DE387D49C781E,1D7F92FB82BD2516,05CAD334E0F77389,D36BD66547E6CFD9,D919EE04E190C0A7,000059C8FFDC677C,6BE13A07EF83E161,3D27C9C1B0D2F37F,3537C02076DCB24D,68A8E1C6ADE33212,1E87796454D0DEC9,7E028164556AD79B,C2CCBE9CA8EB24AC,8B3E2CCEEE9BAB9C,15413BB0E53FC85D,173AA88FEC506F1C,4ABFE7E981DA5F93,00003A19E0F07DC3,52AA84A74E5E0AB9,5828B2DC2F7374AF,8991EE4338CC3A96,0FC5F886C1017F58,B351B058054AED7D,1B68E2AD1154F00F,A5B84C870FA8C1E0,36C856DCBD5DF3A8,12CA4C2BD4C73AFD,469099D47B6178F6,C987B4FAB2ECA787,000009DA2233A8C0,1DAA5604E393155D,D1BA58B76C233ADA,B76C4BE3DD45335A,219DDCC5842653E4,B510A0710B481A63,C481113B5BBB56BD,0035D397389369FF,7A6E44ACA99DCD44,BF7492DB9E23906F,CF3259D844637EF8,55B0FAA9C6E970B3,000035C0A9A5FBAF,E8B4F5C2D56D319E,A94F0D4CC1896DD0,038C14846C1221CD,4FEA1682D8EFEA78,FCDDE0ED2F1E9B30,1093C6504334D070,C6E95A89EF859B61,1EE1C445AC0FB653,ABD662D3D3412AC1,F0FB188CE590D863,C0A1F626D31E6A29,00001E5B7CE2D3E6,CF967C5A6950BFE2,DB60BA65F01FD736,2291C4A6A7C0FAAD,621289977977E6E6,C5E5D9784677735F,B235146EF93B5FD2,A3822F78375A50D8,E323BDC75F658B2D,F65EB7A58D55D71D,BE0F6EDA1D1984BA,21D8AAD7C42F1BCB,00005E86FBE623ED,C081558A37AB770B,784EDFF5FA80F78F,11698A865940A5D6,9A778A58A6E1A1BB,FEDBE48F873CD1A7,04595D7E7C95D4B4,9B6ECE41CB15C235,0E3417B82579A9A2,404070071FCEA11A,6DC7B49E9430E628,E9974AC706590BAF,00000E582AA8EC83,47F0F60D6E0F69C3,140E01639A22EFB9,BDAD89AC23DFD040,88ADB7823F0AC538,7D3337443D0539AB,BDBB56E5D4E8C73B,11BFC27BE9CA401F,BC916B4D4F2EF634,2186B7702B87AB7B,E7B4802CE72D4406,2CDB8A61624532B4,000029D6CA19E8B0,5CB0F3AC83B2CA56,8DEE060623DF1829,41EDD3D9AECD593B,1800C0FD125AE514,0C9F5AB52FD53F52,185A1CDA4CE82F26,6C252DA3CA4EF626,9D146200B81CB076,5C47206DCAED9003,0579B75DFD9F0870,6A5F63F545E7F2B7,0000039EE7FD6892,02E90E00B983B70C,F7B91B0AE239CCC5,E98E29FD5AB9EDA1,ECBC8FD7EE42D011,7A9AD0DD306A7959,109D24E64586D589,48EF251316F8AD01,74989D8D8B942AF6,710F3EC3D455413B,F938098EB403803D,920A4F23F16C430F,00003CD0DAF3F16A,29A4DB6E85ED48E3,5562D0F11760E870,D0CD88FD9BDC1143,343114F27391F85E,7F74606BFCCC8E3D,15652F204E0C94EB,69208BEEB4759671,A99E881710D6462C,6B3B02B1596FD6D8,E1A65C0D7396CE57,A9ABDBC141DE47BF,00004D983FC733EF,BDB3E82D4487BE6B,CB06A55CD0F4D222,526978080FF852FF,85DB71FECE6CC953,9FDC85FC5D05AD13,73845140E4D7DE8A,8668B8560C9C041A,A6E368161D694DAD,9FB71D75F407070F,49860001230461F7,B292C2C63C30A276,000053A0B0FFFC19,309145C3271DA55D,720D17F3446E041C,4744E96B0C8C96B6,358D03E4216793F8,01335F5A9C1D925D,38BC14AE0412675F,C915FF82758C150E,F3DA2BE68C6ADD55,A782F061291A74E2,695C1E95D318DEF4,E57E119090CE48E0,00005D386E3CBA83,5E8D534A293921FD,DD6B3724FAB8A6CE,F495CADD991D2FDD,E6C020792660695E,B7B833BCE7B13B47,B30386634C4A0081,AF4B4CE42F933C2A,EC629F29984903BA,20F92370BDC5E29E,32F0E5B4A4A1E10A,C472E23987651E0B,00003D5C9AAD33D6,3B175FC290A4D2D7,6520A3700E6EB651,A1AE25BAE5CB7159,E918F4026C5B5BDA,4233579D4A21C8CC,648CE9C2DA4536D4,6355DB0280FC6207,D04DA3E058FD5BFF,B264B786D639228C,1863CBDFDDF65A2E,E2C26AE296802A33,000021F0154A772B,BD56B0AF9223EF0D,BCECBFBBFBAE5CFC,C40E2B580759E90A,6D22E8DC5F68DF34,D43F7EBA5DE01DC2,DFB2D8A2517CD8BA,C90FD9890CDB5A5F,994A54BFF7C5FD2E,0D6CB5C32427B6AC,722A8E8766E75C38,99FD530DBDB77A48,0000016906D4A6E5,41C725D84487E43D,B982D66EE1C2CD78,219189D2402A1881,6CC1F54EF1EBFE2B,16D49FC32E5E4B45,43498A73D1993656,1D091D7B2634585E,702EECFA009C1FD0,A6AFFC1B1A51A88F,001968154452E406,CEA2A721CE820B1A,0000473D5CD8771C,C6E4E588A0CA83AF,6BCA2736A2AFB895,24428FCD6CD43A7F,5D9C67FF06F11617,F10F35E7C727AD5D,9022022298F44FE2,E9A3B55AD81D8116,2CCC7FCA77F89714,EFBFFCB715101638,916C2C22857276ED,05A5097BE49031A5,000025E28115B134,A861EB395D466898,225FC027F3D3A5F4,83BD880002F7A28A,55DFEA53E3F7E521,EB84620F1C9F1F81,E697CDB051D04EF5,80122B9D0DE1F97E,9C40F2B4F2B8DE18,F095B127DA960C14,6C92476D13F59D87,5007975FDF1CBE08,00003476406B48F6,CF14C6AE50F5F69B,4B415114D28111B0,3039FE9223F5D1F8,585B2C0C34CD2075,E819055B03EDE175,010FF601DDF53716,28936B6482AC739F,D17EE4F9EE33915B,7DAE0B1B83A4447E,DFA8C00C40764A26,C947421EE748CB4F,000066C88EFB2706,172A761A1CF6404F,EFD01445B0B61B06,A048E5EA203A6284,98BF89C5190BC146,15BA8458E62D7E6D,7D3910D0586C764D,8EF3E9E3D16E530C,A4495C582F563CE1,454805EFF139F1D7,81150DCCCB4A6E5E,009E8F7FFF3A81BC,0000029F596BA0A2,0A94D746097258FE,E1FE5E1224148633,75BA07E5C7B2A4B4,85D60C8D2BB36E00,029C086505686930,2F111A0F51FB5EE2,CF90CA4440F61EC5,0337986788A76753,299097F5E6C9B0FB,ECCED075B737B217,C8F284612D62AB11,00005738175CFAED,54F26490ACC903F4,6D2EEA6138E900B6,48A82396BCAB755A,8528F8B55476BE56,1CCFC1F0E4F18D80,36FC35CB16BBC412,0139CBE9408774E6,221DE45938DDF032,B01147ED5843F23C,D4381A242242EE0E,0E90322D506F7BE3,0000378EF2E5D568,FE58197C5E36AF6C,5E54E2D4DA1BAC52,8C9BAB717CABAB54,29C0F935E05A173C,BDA14ED3416D9AE3,1646CF933905D058,A4FC90E1B15DFA57,8D595EAA6914F193,73C5A658FC786E61,0CD8A78D64C220E2,14FDCB1A66135964,000058B57844EA9C,7880AFAD358B0916,B15BCC3731D06427,8638223501E6490B,10481A413D8F8AA5,52F6645D35059390,EDDB3FA673C83AFC,276656C7340EE1C8,84D93D98DE5ECF9B,4793C1288225DF3B,13B1B23291984142,B1DDEB657C907B43,00003DAF4BD6FA08,B74B2B9BCF87B066,57891D3B92CFB64C,87BA48BAF7594A8D,DB65DE7B1B7A9559,6217819F58C0CAE0,5E4CF5F113EA04DF,AB7144FF07B866CE,30F7FA6C70369705,1EE4C6AEFE3B104F,33ECF86E870B803D,76FA360C01B989B8,0000638996E18FE3,19DFCF92EE15A302,F2884BF15389A4E5,15A1C1C813A6498D,F68357D37F0CE50B,408210DF9DC8BEA2,FAEE933F25EB319B,D3B6CEE972A94479,4D39C4A68FE974B7,5D2DA110CDCDA9B5,D1B8F2C4A1F2CF10,D560144D2B14E085,00006B96C945074B,4182E92CC450A546,AFFA8E4529F706EF,C0EB84E55603EC87,07AA8C11821A0EE5,279B75E22D2013DD,A0DB6DD6B40E6C78,8BA2B2202F8B9D19,D7F4FE88AF9C7A6A,42B846E37A224A8A,92C1BAFD75B84262,ED5E2987D287D77E,0000297F28C8091E,CCC239C6DE4584E4,E5D4FC9EB8189116,7E45C09DEA51804B,12DC1AF1F7D04014,6C45A7F6B2882234,00F2AE9DE8EDB53B,D6BC2416343F0F6C,6705DAFE0D9E621F,7DB1299D07700A8A,C47C2200F6ED21CA,23C930076D65BB50,000006E9BD5A463C,FA0301E70D28289D,3A41F07C59E7A44A,46FDF4A9154DDF9F,6763F85360EDAF62,EBB64CC03015E184,AFEAE2070DBF4CB1,445808068E2A6EB0,CEA30C64B0899A7E,BC61BA150537DE89,04687BB4FCDF9533,EFC14AC057F936FC,00003A97CC00A3AB,311D6E54BC7E5431,D894209D019A2368,8F3AC76D696C9B3A,EC7DA310BCEEA60F,E90F0C81AAEDCEDC,FF7FE09C1CC90E13,ACF6BDCA83AC3ABB,777592370FA24696,27CDBF6256BC6B6C,48F78A208DC01100,9B186FF917809096,00005C012BEB1265,E4A0323037D6ECAB,4B84B64473CA039E,7674A961F04DBE1F,02F6DD480DD02D4D,F1710CBEDA6EF3B0,36047CED4B4179B9,C40A89E3E509A4DE,D886BDAD4F3A6B8C,F3459BD939CEE116,7BB9D973954F2E08,F2B4A81FE5678039,00006ACE30E112F9,BE230120FA0CA1FA,34DCBE8A61BD2877,303CB3C7B59B5935,82507CE77DC8D156,49988FAED9767351,BBD4EB3E09C2B4EA,28928489ED42F9BF,7EDAEE6B29AECD08,3AF1DCD83FF9C5D1,502F67B382243874,8D2E46F7EABCD875,0000307750AFAACC,E02E77FAF15C1109,4EABE56E59675AAA,C08BB9CE2D4FE214,5B70CC829B55B10E,3B43F000BC4DF446,EBFACE539D2E7894,662EE7444D8A5CD0,01BFC5DAEC4F4700,554DF092BD694A2A,157C255920A464EC,62307699B08B46A7,0000548B61EF4D75,0397C63675F8A418,3188E6FD69353AFA,9F095813F31560AC,9B042D1FB81AB10B,DDBFFCB2FD94E28C,62AF2C9BA7FA4110,D407053C8129207C,5B178201B58B9958,26DD8350424A1EEA,CCC9F46406FD153A,EFFCA1413E83E9E4,0000027B238BC445,B787FA42ACB41A26,62FD067D03159949,D5DE3ADE2868BA16,62A02EE050D80BD2,CA649D33754513F2,F980E6321B0B0B13,E27AA18CBEDAE76D,B9307750A1DBC11F,762601676588BACD,E7003A285ACC086B,03EC30BF46A53519,00002532A94B22B4,31EF712775A1B7A8,FCEA0A29747AAE54,F415F4242ACE51C5,058C4F7ADB4056C8,45AC4AEAB4422D70,E54C2BEC4E8A723F,8B5936C0A4F2062F,617FAA12BBD5A570,5BFE0D881FFA177A,EA9C2675E24E91B1,6FF261D47633F6A5,000028902F4081CE,876F3C0C8E522B5B,C40CFD0D65D8A593,4A8DA461A4E78ADF,FA0EFDA8A2F75B8C,7CFFB28900D8074C,DB263154E85C1E12,5C3B6EA30F3DFC10,E79E3155C6DF3453,E033A3E9EB785CB6,5FC7773E1C3A51C5,7E9D7CC7A5B16A3A,00000E54C1EE8193,958E8292E22377F0,896CED15A2AA76B2,371FF85703C9F356,FD08FF88086C0915,EC39F9B794BB0AF4,E576FF362565AC7F,55C818D92888FE51,EF1ADC5CF5936602,9915C6E3040D490B,4E97A00273A16AA6,AEDB73FF6D4FA962,000022430AFEA823,FC39AB5813F3DEAC,E8393A38404375B3,241FA0839E79C8B2,9F6A65D1D0F575F4,F9C0DDAE3EEEE3AA,2BCE7BE0FC2D5F35,FCDC959D6687DC28,25B386A647841831,B263DFD70A0C0A23,B2AB397CBED69AAC,9A4BDE1F24A4E403,00000B8160DDD15C,7891E93BA158DA5D,195B172485040991,76D9B53D761E0883,C9D86D2CC56F206C,F6C3BB82C44B60DC,2DA0821C7B7AC4A8,811C8E93E6CC39D1,25B94C3F253F51FA,3BBF64638839ECA8,68C05F52E130732B,4FAE3F9955AB718B,0000628FF85701C2,E4E2B2409BEB21E9,B74C89523B112A07,4C66931F946F5990,BD4DF3F72DD64BBF,58925E3159702327,BF2AB2DA26C534BF,0C5EE2C1FD79EADB,A2B594CAA8DD45C6,0D32121B268C8951,D5283E161E6B3701,599C97D85B4FA21E,00003770CE713E24,291FCFBD83B76CC6,BC2B50E27D9B6ED3,97B5AE2E5870E778,F4BB091C753E2F54,0874C97E488A3BFD,E4246CE503088106,E21D1E72A7883E80,34A05AE97F204D7D,3D0F7F98486B6741,317655D2744B2390,13AFD6ACF0B62F5D,0000170CBDC51D90,9D2F39D502BA220E,806C6AEAEA53E0B0,9537D85AEC1558DD,AF40F9F9E2421D8A,68F33EB258C6F46D,7E237679EC2F10D2,9F3A704353EB6F1B,D795F19C031329F8,860289B46146784E,63D65CF58C68EF71,6A479B46583B1825,00006B8E55BE0410,5584B2126BE8BC44,ACC7855977BD1873,30447659F0820A78,A110E72E7DD82C6D,E8D4F01F41FF8F94,E86D0976B1B13720,F5DE0F7C9E11EE88,79B06253F24AC4EE,BA74FFBDCAAB3FC5,308BD3F338030057,1C6A7CA43131765C,0000133747EF55FC,4FB5B82067726A75,4002D2C289481B79,A98B8287A1335873,EE74F0DD76F0D207,F4BC45587F2C86F1,5E9000B9638543F4,E4991637E3994E28,73DB0929A727CEF8,5AA177C602FEE762,F83C1765F4A0D92C,41F50B7F7F761369,0000399700D36C5C,DCF0FB33312B2497,B329C75245A24707,3C35E0846606BF59,AAA26FBBC85E1A40,CF1EBBE340E60C33,8F397F34B71CDA92,0D6A0FAB957C650C,813DEF21F18F3091,41EB0F4ADF900249,282DC84BDB93D87D,ECA230364A142441,000006BAF5B69A15,C37A116CE0E7F4BB,10E60E80A6190AF7,334E4068613C457B,0B012825B444EDA9,0A0DCCB3B755F2DF,9ED3191915F1A6F1,EAFED5FD5FB4C95D,1C96984E4A59A0A2,0B78E12D17667CBF,DCE85CDF90F9C483,8CA2DF5989866FCB,0000375E87229B42,2055F74C4141F3EB,0B2176ABC78AA204,98E797073B2B9E24,3D27274FCE297C4D,2725BA6869A15707,48BE22A641ED6DBD,1CC4ECB9375C251B,208E2F4A962ACAD4,D2D73EC638D7831F,34F493A43B0291BF,F89B59BB079B2197,000009B8DBE83980,B4E80F6780424CB6,59057513704FB973,F91A539876D21E8E,5A98610D0EE67673,B8CBAB22B3504F8C,214F40205EB592B7,D48702244E316941,626AD791C23B0D2C,8EA57C6F5B3485B4,4A434D3715CA2FD2,87DAFAFB59A0184E,00004D3358C2D91E,291D5E28599D5C78,AB5326AEFAD82528,A895827F339D0D7E,881ED3BD5E275483,887D35B8F7FA1F06,0AD35CDE713BF659,77261CC789FB152D,C8058FFFD6D72C00,1976885A45D77A1C,28B0192092D51171,D78B973DF7E9EABD,0000296FA18EA0D1,3C8462A2463EAD2E,1490AED33EEC150D,AF85200D1DC2FE6F,4E811EB5ADB699D9,DE7FC1D474E6C32F,33211E4ACE3B80D0,1A2C54ADC877F92B,35BE67C46086DC79,CCBC003792A4523A,AE9013BA7197E325,125D625D39B5F716,0000395F7AD6A029,407343B8758ACC6C,B2E9032D51007C1A,A2482C1724DDAC78,384CB115AFC12734,4AA6857011AAD0C0,A1BADE5F71274028,2561E9D14C5BF644,D3D5FCC572AC9797,6C1E0F96197C13DA,D1A125ECE698B15C,94AB389DC3D7BAA8,000054E305375446,C684CD1F41064DA5,7FE9A3CB6A868D35,40BE5F6A75866C77,9A97D9EB95D3404F,E01569332C6BCB28,8A609C616134BE0E,518615A31D250360,19F3A774F9BF3653,96466A450B1792BC,D82F102153CC1730,9A37CB8CA97A6B35,0000324E87D7D635,22D8E43A026393E2,A9E87C453ACD696B,0FC436618ECCD448,41673DD4E81E48BE,DA349C43B4120E3A,33DDF90CB1F14659,C4B4ACC45784B9BA,8885B6B63CC37BC7,01FF53ADB0F2E0C3,9326CD2EF1788FD1,8FA99CE860CDCEAA,00004C9A3415D37D,A1C7876297EAA2A5,D99B2C7B6882E383,27E286CB0F59BD66,03931C2157C7C4DA,27C28D149EFFAC2D,457C15A20FAEF56D,8E838445A989979F,D692CE35AAE92F8B,246BB5A388B75AAA,CF7E057D5D18FD9B,598BB76E15C39B35,000015F64AA22B88,C57CAA9B647E85D3,288E84BE885C7494,E35375F7B05212A2,44FF6F9F1EB671FF,5806024BB8CF88A2,A1C78BA6157F30E8,90A4B9E9A045C5ED,CBBCA18859FF23F6,7D551382EB23A869,7B8B924EAE3FF5A2,AFCBE7FAEBDA10BB,00006AF1F6796C2B,DAF31BE469424B4E,F49F6CF36335FB71,4D8C6970CCE71AF7,C67E405E62F95E6F,C8FCCBFFC90B4357,8E994C6C0D64F8EF,CAD29FC88B22BB21,915C5159C2F00DC5,24708CD30B6756C9,3CE2C1221F0FBB15,784AF295DE96007B,000001A10059FACA,96E4CE76FE8D1082,E4CEA7272B328DD2,3760094FC7260D75,82581A72F69CE324,80DD30CF17D422A8,94A08DC3A134A82B,EC6370C69221BB38,C7024671B11BFA7F,2490667DF357EEDA,5D454042A8E0FAAA,6E2DAF79E56603D2,00001DB0DB371F20,F3775B5D6A36CBB1,BC801B308A0F819E,C85C0C68B9EBF48B,B4DFB64B05E82F7B,08275586C61B923C,919E677C3679F9CD,8671B59D9826ED5B,952F2ADA56A1B91F,FD5B092A30F95449,A3F9DB2A089BEA34,AD2E1E05EC21188C,000008A877CAE972,44D62582BA124216,B8A98FFD9F315B4D,3CAF04FCA39A025C,470F0F1EDB495973,8028289FE1985555,913EEA8633F5F61B,C445488A3F2FA3E3,63341DB97325D86D,DFCCFC8C3CED2215,3EF543F8798046ED,8A0004933C3E93E3,00002E601DA79929,26F5AAC6FF686F89,26E363821B6051D2,8A6E9D636735D472,39EEA9C74F2DBDA9,F5757A4FF395C6D7,C2589F74CBF79F81,A8DB1F3CFFA6DC75,AC19AA253B196E05,67B571C35C24B0E0,7F4E9794EEF51BB2,C61506241E88B25F,000026286756122A,37729EA889745A54,65E097EBDFA2E99A,656A57A647FBAB9C,D2A093FDEDEDB592,654D682696F7209C,F17A884453D0740C,F6BC468A91DB0F25,8FF03383CED4EA35,B57E1FF7C5E0CF83,A0687DCC46EB62EF,30CC42596C29250F,000061E344A28975,27109FE3E31AFD5C,DB754729C5D1F283,B3EA85CD217349A2,49595E4AB4B88F37,C4BAAFCB45D91635,E2F77C847A03F1E9,78C0653C24148C8D,3A8F0C341CC95C80,1E8FE0149A2BB44C,B94DC2005E169C9D,4BFC833124419F53,00002CF0C1627EB8,2BC7A05C0FA7B793,B2A7966364A899C4,0EF52CDADFA0B959,D3F15752824D38D6,5E37591336CFE679,CDBCDF46A7080AC5,ADA063128907E707,E4984381A6B68964,210B17A32C1E1FE2,C88328A6334DE06C,C1E9AEC61D1A7714,00006DB73311DB29,5E98C9C9DEEEEB12,B0904BB81390063E,296789070B9B3AD9,0D80C1D92E7645EE,54B405C1B4DCAD36,04FD895140A41B3B,F1953DED1F62920A,876FF8797791E1A6,58B553835D2A6BB8,B170268D3C05A900,8744E9C63B2EA59C,000022BA83791EDF,D3F5A548C4C196EF,807640966A31FF25,0D921584206CE10A,7ACEA30B5CEC62D3,6274D33D879E44CF,2A1F06B3056CA271,477E6E8556E1E420,AE964B17F34C9CF5,21179CA1CEC502FF,0BC403EED5CEDED2,972E25CA6EEFAFCA,00002CD4DFE2D96B,F15CFED4764E1826,46D527A4A2F5C9BA,D9B6ABEC2FD1E38C,987E32A2F5835DD0,80E4D712CD12CD21,D4DD4EB82A532891,64C9806E06D3FF7C,6089E84833669AAE,0B83A444C5E94926,9C67FC7B08E09B7A,31BAFC405565F5F9,00002EC6E3E40722,82226CE3038248DC,37786E7EB198F1F3,3577CBF8779E5F55,C490E9ECCB243F86,0A90A4EEA9EC3171,0AED5A1861274745,637BFBD69F3B1400,32502FD635E06B2E,1086F18D6AA5EBE4,DFC4ABBE1002A9D8,447EBD7A958D8202,00002B819DDEC198,F9065C38C89CCDB4,2AA7B0E883EF2BA1,1E3F37EACF8FC429,685BD6B3355EE1E8,0CE73F1852F15C6C,C30C7E53396EB2A5,A7CC73CAE6C9F590,050F36BF535D66DD,EA44192B877B9656,62B744A23301598F,5A2F66D062D717EC,00004E14339616F4,55ACB6331AB0D632,01752FAA7EF75753,F8FED41822B0AAAF,6F6A45FD86064B50,892865C98E8359AC,05D0CA69279EBAD5,8D171C0FE1C15761,35C93C84517AD164,AEF645B52321EF96,D032957A0BFC5416,54CF3BBF286C0D82,0000473A68C6F0C0,616604C165F5C0C3,CEC2842FBBE13342,5A04260D5895267E,49976BECEB95794D,EA635FD82F241AFC,201A84E9A27D2FFE,F6236560A255BBFB,68A08E785524DAFB,5BF60D6944BE38C8,F0DCC49AA8165D21,065BE5855E5CC148,00003C16096447BC,E65C87CD943068BB,2EE0E28531D621B7,6524CB0A4E830219,F3F35D026F932681,0126A80A7C8DC30C,E569E5D58F2B0B0C,108F47B9B8F9952F,7E25C1005E3B16A9,985F000E8F7D1360,68119D6AE9894AF4,D000FC166E4EEA31,0000331D81E8F591,A4E33C64CDF9951C,B2181551FB507648,1D5FB9138A691849,77234061816335CE,871CD8F4D9B2F5D9,E452DB1D4A35BD01,47FF179422F2DF7B,872CAFE1D127F40B,A17CFA8E88323298,E484E141226718F9,BA2E24B94650E42F,00003EE395963864,62945BFDA48CEAF5,3982854A2A491D58,04614A0C3DABF9F3,FC09B10DACFF5C99,BE5515F461512BF1,986C552EE3B1D8DF,5FF406306736829A,C82ED9443215F8DC,46CF27E7E539A312,4E4767C56C175113,61FC19A2849D95D1,00000AA672FF5FD8,D705F95F1FA65102,EDAB6C811A268DAC,C137B022630F315A,23311050F7BC17AA,86B8DDAD2A8DDCA5,CD8A7B7D8C81E0D3,55ADF22362F76AD3,15FF08D8FE808090,C9D3094A0CDBB380,AF6A01E702AD83F7,B0E8F8B77323D98A,0000492B508B0DCF,FCDCEECEFE600650,A3FBF574ED66AE01,3D20562243ECBD4C,E3E0600E0977C94A,249E98E64BF3856C,387ED6C21A926A38,9F77694A0FA34AA3,2E8FB6E8CE801561,6DE92C3A0F6C275E,6D74F4AF3798EFEA,80669A6AA14E2FFC,000000ACF6E4A83A,1F8C5952A33CE3C4,A55CC4218E9E598C,5141E01DAC6B3F6C,63850AAF817A4B6B,DFDEBDD9FB799461,2A276F6576B5D258,8750700F274A33D6,3942838C4C48F4DC,569692752152C09B,A618271A9AE11B30,3691102277975649,00000F60293E851C,4F8261CF4F932189,2F51F06B8EEFE929,9EA19A176C468069,38DE79CB7B2D2E2F,2D5ABA06E232A273,40470D932268BB4B,B450C40D344B9D2E,71B3967F058BEAA4,D6149B09C31426E5,C190453CE03B9EAE,A785666E87DA0836,00004ACA287523A6,F077A840EEEE06D9,C316C9F35CE13A4C,79CA688DC22DBE69,98F644118F7AB548,E31B9CEA76632CD5,21AC77C740B2FCD8,A76A33BBB723D86E,761F56B07FFE102A,32E1A967A748D192,546110E83F38F560,DBED14A1AE666344,00002DBAF9245B4A,F0FED0648E50D6A2,110061B0B1A87C73,D5444DE646B70DE8,D3E54C5A2C3D23D9,4ED146FF73370B51,0993AF2B5AC5D114,F8E6750BA913485E,A4F9E52ED1F379CA,DFF69D163087F033,19298D0301030AFC,4D467A171090E36D,00005AEA0EA22145,FC3F4AC63B631C88,355E56884ADBE2B2,7F71507DEC273D3A,925B9B764DDC831A,AE1E589A91E3C9B3,4FE1627CD2C553C0,8E0306A554532740,083C0ACAE8BC82A9,1D75089605CE5ACE,029327B1E6ACEE33,D7BADF5FCC3A5D72,0000571259A3618C,FF9CF76C38272B60,D9B5C12E9B2218A3,1501708B229AE248,0F9B3D6EB5698107,D02D29F11BD495AC,6C01C29FA6474F75,27068AD0CCA913B0,0E65A33ADE259EC6,FC51538A12FF7BA4,CF5AD11135E37183,FA84470609E84B96,00002642AAC7B8AF,6DD526EE39DAFD5A,B12F6BE32B439DCE,8BA47DF0AE821848,6C35CED381C6D42C,31BAC0DEFDE5705D,DFF98BD3C7C7ED3C,B631CE6279D0A018,F3741CB21D0368D9,FE4079541BF59EDC,D7AFF75128080579,FE6F23100BBBFBC1,00002FC95B9F9D38,B47EADFAA20A029D,1FAAF9A10DCE438F,21011097DAB7BEF9,ACBCA9D32105D175,FA61843DDACC97C4,CA131D9CB4076300,C6527F97778FE364,758A3D43FC2218A7,3887BFA5A77F0132,2CB6DBFCCA8CD407,2D25BC49356A6B01,00002F3B7EE74BB5,4B2EE3E0837CC622,2C13A713682B5459,D7F35736FCC78D24,230DAEC8EEC03892,082F7F8FFFFEC5E2,0B158057D207F386,7F1584B9063597A5,FC330B68C2BFC937,C18A6E881700F2FF,A75C0DE5F66EF9C1,F9C1633B1114D5A0,00002C523C63D4AA,0763D5EBCA751082,8B0DA1232BB01EB0,090BA53DFCFC83A1,0AD34533A9421C3B,41026138C64409AC,C32DD4717B3B69D9,7EA69A08D1287C95,7A41B093628CD330,49B01299469D7458,030247D382FCBE2C,8C1B3264754FBBC4,000028BD9C7A0FD0,7E11EAEB1EEFA353,1B890FE9671D9064,847AA322A2F010EB,F4522FCAF1828564,2F46E83D7EC3810D,FDA762EC14D7D8B5,24A29B9629A941B1,9AAAC4EF9D789B56,1D8010DCA1999EAE,A0EF205E53226284,6FFF53DBA9504816,00003132816F8833,023ECBA2EACE543E,196881394D851CCF,EDFFD312B72E0C69,04C2C2751CCA6A72,09E79260BE5DE2A2,7256CE214E54A9D1,2B1203D01322AEC8,A227D54241B6F6EC,BBCEC10FF4AFF226,A069783B4D7FE7BF,EA6D80B515DFF321,000010282CBE15DB,749A8551804BE07F,851C708AA21B1412,28BF0CB0FE03D651,015BD092F278B82B,CFE5FC2BAA48D1FC,FA4CEE60B289AE9D,D204D125F23FAAD2,66B247608D7B1E3F,58A1BE842A9636EC,528793501A6C08AB,DC81EEEE409132C6,0000610B890C3448,356F409158754EB7,AD909A4A679DFF01,0BBD144F0BA2FF33,39D75265C2549D06,C93C709B70A13E5D,45506E1C1FC7D5E9,E1D6DDF9CE391036,AE79A331E52A2F71,D48AEE4246617370,3BBBB56E881DE42C,41B29D17AE17EA21,000042EB98C60752,93C92FE24FC5A89E,C250597304A567DC,0AD6C60F00DB0951,CDF80811EA8CF0BF,0B93FF8F7E6261AC,599AD8BD40CEDC22,8C4768E40913B88D,46D59D90187B08CC,BD99B021098D909B,3E69530D2CC75FAC,66DB8E0EEAD8FAD6,00003F0770BAD482,9C0454EF9C26B147,9ED791419CDE3841,9805D6B3A52F7842,4556FD5984B85036,0A993C0F96C83D15,8A17ABE914791EDB,A1EE217115396FD4,125EF6C811CEF652,BF834B4BA9852D25,8C5471A358DF4F05,5FD16BF370D5BCFB,0000609972C6651A,76756CECB9460C9A,885F91E5E61E0F4C,A0522FB7A4C7E94F,479D60F2DF2083C1,EB1C21E8B12ECC2A,60ED9764E1724172,0E9DB64013302DD8,571159A667D3985C,FB60BC3923F0300B,7BE0BC692D1A56F0,65D9535C561449A8,00002986E74955BA,93BE5B4242B84AA3,6A226BBCBD8C623E,6A96B751044AB6CE,B139B44D566E74C4,91E2A2CC946D1343,21CE430B6896B135,9499D60AFA2821AA,DE7FD408FAE0841E,E70433BB8C5F180E,7CC7BED9B730AFE4,8DE1FF1DD8136839,0000458691F707B1,C8F47AAFB65F62CA,BF57DE99E7AB7AD7,918CBD9CD2692C49,1D9CFFBB0492F16D,D89B563918383160,F53980FE21DDA22E,EB305F4320D16103,86113DCA995E46F0,8B745374F1663929,B57038AC1A11DE13,BE0F4352FEF1D2F2,00003E646B2C949E,86F4284EDF4A64CA,5A909DD4E9702A5F,92E950DEBF5B0DC7,9CA4D941CD497C2A,9B8C08096EB453CD,89AEC7CF983CB266,5CCC71C1402C6373,B6E5599B0C8C8CC6,2306659A5BAFB942,C057DA9C1C6C755A,F857B1DAE5AD1B93,00006BEC169CC538,F32F4C847B1CCE18,A7890BA45854AD9B,1F96656DFA6633D7,8B3907A6E18EAA3D,047EFAB45D523D8F,3FEDB5C9A2750C26,44DE24417574D540,83C79ED7E8033C7B,4BAB2400DB6FC746,288549BC8F606CDC,1DF09043A9DFF116,00004C0ECF4604E3,58C3BE6C20EFE60C,2090DB5426D1FCBB,23ECB4C9C5E5DBCF,F32D1D186957B2C0,AAB2095FC726F254,DEE3CE8368B9366B,4E5FCAC0813601FE,DA1736B26B3AC321,E811FBC1DC61A998,9B170A7658C624E6,B9EC5DD46FCCC180,00004CD1969DB2E3,5FD562F9F6B1D9FC,2BF0308113674766,466139CE2528EC96,CEB73BFED5F7219F,388F1BC02A768E0E,7CEFA5F79F0FD64B,27917B25D1A96B71,0088CD1D33D2AB8E,13A4E7FDBCA4FA09,6B2DBDE7652C9F87,D40DAFCE4EC2A4A2,00002AA4DCDF9850,5ECB49B9A95F810E,B839A84BDCF60FE9,7DF56CF6CF26E48C,53459F517F99C598,8EBF002501215BE4,B09FC80853F7248E,60A829B161F41BB5,28571273D6DB9DB2,37DA384A02654450,E821D3A486D47E16,04EB8C77E23D62FE,0000649843813B2A,3CA53B149E04CB14,9A9BFA1B026AE402,F80F4D73A762DAEB,0DC00FA06949A8FF,E2A71BA23CACA37A,516879F5A1897DEC,F1740759090CB314,C909FDB23B15A7AA,154D8ACE0411A08D,A96797576CCD4373,2C3F2D3655EA81F3,00006B5A9E6663A7,89F9CBE66707C624,CA57FA7DCFB3B035,2237BDC198689B95,987BBB66F29BF5E1,984AD06D16D10738,0B232E1DCA664ABD,A38EFF021E441350,8CB53820E6D6A72A,96208D4B7FD0150C,4D3D4978B37A2D40,23F17991C1B68A67,0000502DD9FCC671,8BC7C9FDB7BEBB7F,FF9D95B8AA25D2C0,15763ABAF81F5CDF,23904C838CC99D4B,2CF3FEC2F736BAB4,6340A102BAFBCD7C,1C7FB782599ADC7E,4FA1018C4EF4F8CF,FAB38A160576B819,FDC0EA95EC137F97,5854752D3A204DE8,000055D6D1896432,B8D588B6C27D4117,861AB7A4092A55A1,C91E2742A0042F00,EC8270CF7A6D0880,B7FF0DE3820CF965,19C4EF819FCA7DBB,5B923C4C25A250EE,3D99C4F242FFB2DC,B3B55F875D732A7B,9F84B32EF49F760A,B8E181FDA32A2908,000025BB64833307,47BC1CB17A7E1286,74FBD33505E42365,A39D9C2F7487E837,7556481E5DDCF980,3A4BF584062BD4C0,2F6301C6733771EE,61E925FBECBA2A78,FE966DDA1CA049CE,B1622CE60780D83D,B02F59841B8D082D,7B39442623DAED96,00005C126026B032,11FE85506D177538,85503ABC349B7BC6,E504C7E450E0CF9A,013C4A5BA29AEFDC,0CA3B7C0FF6D9D68,766964B2975B8070,F48675F1DA3B5E34,54FEB4F4C5240F0B,D7584E8AB12EDDB1,03FF8EDF8F77696C,FEECC7FD5957E927,00001357BF3224BC,D979F2541F5E8077,7BD799B8BC0D354F,C14464D5B431D912,27AA02C4833C0476,F57DAD262C3F6627,EF9C156EF0F2537D,2214C4F664275D51,D63012DAAA0BA107,C8D9616476CF9BDE,A33CED58934AD3D9,DD5396EF74B67EE2,000049DB875DE0D0,B9A90B41AF668B56,2B1F170C81A3C27E,D7B0E0601DFB0F41,366CA5A6055E155A,E2FFF54343CC92A1,A105DBDA56331CC6,6B089DE63B6C4591,89BA2BC0FAB1D110,A7782F39C24DC6DE,DEAF2E71945DA8EC,73D09FAFD018C2B0,00006CBD4C86B631,D58CD980AA00A26B,E1414AB6F953821C,61510AF10C3EDC05,BCB42443EAF34C48,30014D06C9355408,391E47ABAEED5389,2B235637BFF6F1F9,DADE47FBB41861F1,E626BDB79C2E2210,A8C94937BB335285,D98351DC76E94521,00002D2E9099BF6D,8643407249B65670,898F6AAB67F70247,BA5A7F3B1154A5AD,4D438A7ADEECEE85,10D27DDBA60FC99C,968B6BCF0586F795,17DCFA6D12FA3333,1A35A538D24AD8EA,326014D6174386E0,8BD10FBF36D1FC9E,070849F79ECE8B0B,0000521A7012E017,6308EC5FDA53377E,B5325059A4B35061,9B8868A84388CA47,559761D1E38B1850,86FF3328C75CE984,D7B3F686078A6922,16D674578889A2FF,78AB02F47C7A2373,EEF0CAFC6100B1CA,5B7341FBF3D3ED25,5308DC8F0EA2F70A,000012560F3A785F,0C28419F05A90829,1FD6EDE2EED0206C,7065596419480087,8CA6654151157099,753ADD8BB536DB98,804EC277BEDD897C,284E014556B328E1,251F261FBCA917F4,532DB1265D53C08F,162F8C19CEF43CF9,F30E8543D20E5517,0000136E1F50957B,CEEAFC40A1CC067B,E5B0776F5E1B2DCF,3D9EBC530472AD0C,0B4BB6AA28A9B5FB,A4EAB85332A8D434,91C2FF72FE2BDF06,F9659888B00E7278,18E1DB2C574B9FD3,EF1B9E85024C3D61,680749BF8BCD286B,C53F3963F7189D2F,000036551FEF0733,0D45D96A06AAD3DC,C466473A6A2FE813,CCE2B6847176D4E9,FFDC27EB9F963324,974DAFEBF27BAB65,D46FA308926FE3A5,56C3C7DB9113CACC,AD0868E34DDA101F,DDB353D6E710A8FD,7AF9095466FD60C7,61DC363543C49A7E,000000F272DEBDEB,45725C034567F920,826A9BA2049E03BE,FF3D36FC4268308A,D33121BB5263C916,577A9E2E02FAB661,EAF0D96A9C524623,B48677FC3826BEA0,6E1410A6A3C25A8D,3ACF57EF694F8832,29B329CFB07E98EF,68E189B34C572CC3,00005C21CEF2C25A,E0CEDF6FEBA18B24,D52BB2E82296C374,B76EF8D1CB247469,5A276D47B8EF1260,AFAAC113AEF39768,611E71C0E075DAED,76B1AB88937AF7D2,EB7AD41910F54061,553B26B121FED0AC,CEF8B4B94CE33046,11BDF023DFB87DE4,000001E70DAD998B,A8928504B86957DB,015C32737306CCC3,F618511B7DEBB6B0,57008B7852ABEC22,1B4A26BA44978A9B,3A88122CC11F1C97,23F7448185944821,36DF4AE39687EB20,449CE89F487C1D16,59C5ED81EFAB94BF,888BBDB6D7955789,00001CF36905750B,5A446633334D2B9F,87245277C095FABD,EC96E0C2350696D4,93D755A33E2F8CB3,FE11EC6671E80641,435A950E9427EEDC,BA1DB12D1A1D0834,0213240879321B2A,F9689108B8BE8942,3483DC8972EC3072,6AB6FB7CE889DFFA,000029FB13B6C706,CA9925FE34CC8177,5313B81E196AC3A8,EE10C087908D10D1,1857F81E0C17341F,7E4BDC7840C59035,73EAEBB8B474BDE2,EFC930C2C513D1A2,36DE04D7A618FC93,2759F4200DE9D61A,967DB7C6F59EA031,02996DC2F05186A1,000006B8F9B481A5,173626E8E016B451,195A9A1FF5458F5E,D79861561419BEB8,A1807B10EFA1E76A,1FA8FE3FF4099FDB,864AD0EB1F4E5969,2F42EDDA3AE88659,2920A49DAC7137EB,8DF64920993DA0EC,977C04B2FB1A4B74,4B46DAEEC939D6FC,00006F3DC20A495D,8AE5F1B909C53EF0,A694D0805C58CA5E,2E0B599E4AAAAE13,119C2FE5F8BE1DA3,7B7839552CCA35B2,D8ECD6D3A28E6106,4F2A2EBB6D2C1AA9,BAA117C26C2A46FA,C7D80523B831BE2E,44090F48235A177B,4660F8547DA6D136,0000564DA1E86C02,711A2121534B45D2,A9B3798B0FEA9DAE,E24832C1E967FFF0,8025BD1EC62944B0,577C9D3241DAB723,B4C9D456D4600DDA,A27326933645826A,C2281BA36F0CA197,2B02F64658CA5ABE,6A9B84E1CFF8C728,B9AEB42A1467B3CB,0000286ECB3CB23D,C9184CD579BEC11D,6412C8198B4933E4,4C5E1CED535494D8,C65421C183719DF0,A392158B6DCE6A60,E45E0458BB6B8B9D,2F418BE54850E307,7D5FD837D48D644A,779447BBC9F8164F,DF16268F8E607392,92E2D7919E7F3E5B,00006E7B11998403,02BABF0F98781938,704B428CED44D74B,8FD6878E2A6BC8BF,A10053079A97EEA6,46E3D30EAC8C2C96,C038D0F199ABB4A4,85E22FA3DFA0C1F4,D50929F62D4467BE,CDA63AEBC5B83C61,034F21A71F0EB3DA,13742292BF734761,00004113DC47CE47,4A19A4220E929E38,E083B2DE897F7607,9831A3801543B7C8,23F9769A98225E83,FCD72245A7AD2A28,6F2C3EB409B53558,4E7E06A216D074FD,EB35D471FEDB575A,0F82CA5CE22A8CFF,092B348C0B6BA6EE,1A7E4E1B28F10CA6,0000660EA07407EC,555034F329BB5492,93FE5BD1BF1FA6E6,C94EBB520BC62BA0,70BFE2F3679668CF,9BD7C75D6AD49225,813DEC8E1100D5AB,A7DA6DB2FA472A86,A4DDA0677634D77C,0C2AF2673C7C07B3,CCB8368E4F65C934,803A511A39F843C1,000007884079823B,87CF5A69DC51D2B5,B90FFF1ACFEBA2DA,78712F709A03513D,4B796476E1B5B63F,4C588BE9FBE9DB1F,F587D451B1091E49,06DF50C2C6998FAB,D41A03FB74CC234C,7A031DBC17AA5AFC,19A659D1411A48B5,02975702E73B80D1,00001321D2D76167,C78CD309B55F9B28,78ADB98AAE9EAB20,5ECEAB85D1253596,48BBBBF6B4AB3EE6,31573226CECC0D75,D191F8216C3C585B,1AD767DB4AA86A52,7FB30E61853E7AF2,B93E435E561B5908,9FFD7DF8746868C3,EC7C8D15B3EDC55F,000050AC4FCC2DB7,DE24B02C01C2DF3A,66C836827C57FCAB,A718A24636E16D4D,3F1FF5C6F3193704,5B9B362439EE6B02,5ACAF750CE7D85DE,8D27C775725D254C,3A55942B93DACF8C,1E08E8D1B2A3ADFA,AF4792D648FAEE0C,42E453EB880FBDAE,0000131036884459,852C56DE08AFAD7B,9FA1478E10721A66,D172E928A3D11201,D0B13D083F28A3E3,434D1755E5E68337,B4B7CA36D7C7DAAD,F2F90CF930920F8C,8EB41037A6DE67B4,AAC41C3ACDD018C1,6EC26A5EFE73C8B3,905F5DC4FE2D3159,000002A18E9D926B,056AC9D2AB8AB820,30C3364614C34A6F,5735FB19AE7AA7AE,EA47043B2CD72EAF,8FC59A6828805C60,657CC3FCCA0B64BD,7CF1947D46C27062,BC07DDD43ED219CD,320B097604588F12,84D40AA5BE4A9AA6,14BF1403726D1477,00003D31F1414E57,970EDFEF2C43E696,B1A88DDEBD0C85D0,1179EBA5DBD84592,615F240906355480,862D948BE81A9007,A59D0E33101D6919,1B97AF38D44F2D56,06939E4EDC54A7F2,6C1A3713D5A2D86B,0A5DD24CFE65215E,C6A169585AB3F3B4,00005D4CF9768E1B,54B5A6210665218C,422CC7C64F6E37AA,8CCA251782790218,1CB2CD7123B23AA7,24D35E1C628DC1AF,807139266AB6A562,DEBD3F2BB8948348,9A17B8B3EA0B97F8,51C3C9A3C7925DDB,301AB472FEE8E755,7E831AB8DC9E1FA3,000022191EE3FE31,7FF5E5F3507A7964,3FE05C1E0A61041B,1F8A13717F16C7E5,4EEBB44F5296F8AF,BA7BE5FEDC7BC460,83C1F01C984FE101,D705174ACB0D618E,CAFD23CD94AF32B6,DA267E913FEF75A6,2C7C71FF27EFC59B,B8E61A1649E8EDBD,00005A95E092DCFD,FC9D324253AF5A5D,E932F0F96805DAAB,C6267BCE3B4AEEFF,F5916E2D356D09FF,D41D02D4A1ADAAEB,CBA624D686D797A0,6060B7BD98D92F08,82779348891B1733,6D38AF82255E663E,3F3BF2E6E26AF87F,62A6EDF5B043B52A,00002B3A0B5882C8,49361D2F40992F78,C30D5D03552AAB0E,CF5FF8638872829D,F27E72D50812A588,37A6A5057788C552,C5AE25EF06486BF7,94FC608E188A6291,76E8F33BC34F932F,A56DD94B496C820B,42D1814180B9B038,2DC2C74B489330DD,00006AEB9B3C5400,25DA1023F2C48104,0265872B6DCFE2A6,6074805B8CD53258,9A4744CB22B8636E,721FA933A2063B28,0F25A813F783FB17,6B5703E42294F036,2A8007AE37D79417,99F3CE0E49475907,01808403944739FA,BCF4AB9C8C928D84,000062C60544EDD5,5602647255BFDE10,A0D65E6DD214C65D,5CCE14294A8B7B3B,6D3CE114E07A764E,6D80168A21EEA03C,FFE0F5254384669B,36032E375A233B28,21AEFBB79F8CB0FB,D8CCBBA26852E830,503ED3923675CA9E,CA9963F417E66FB2,000025461C97A584,55C4C63614FD2ADB,E3FF25EA39C572FB,C6A7A424E33214DC,7B71CC613E7750D3,93988262C7F65500,03252744E413E358,A127C391EC5C8B8D,BB0642A02CE58F72,1F30F19B5FDF97F7,4B6FFD16307EE871,09D12C20D3037DE5,000001D5BCA8D984,84D7876884EF7014,D474BC2FDDF65144,C010F0E5893034B7,512DB1534EAA06E7,ABF4B636FCCAAE7B,8EBB9A41C1309375,324C22D8300E6F92,773428422C386E1D,6E9D4DF82C65CBBE,9F3F319607B85C58,DE938B340E8CEF0C,000046596FE20972,077B32C2DF7C3C1B,6FDEB5FF721C5AA7,559F70A1D4B422D7,BBB54DD829BF4A02,8816E8BE6955795C,26815DF5330D9453,3124055783261791,30B781341C854F91,5FAA9C3671957A3A,84361638C712A943,008A5B59501A126B,0000040CC4D56413,D5AF37E8A39EE3FD,1624A57A4F23ABB0,7B60C953601A0E36,53CE6131FF541EC9,C1A508F1880C1CC4,0658BE650612736D,E3BD3093079274C9,446E598A0139D3A9,2976D28830CCBE37,4F161317DD454336,EFEFEC8731075E27,0000141FDD3230C2,F8764C53D3421705,6C7C011658EF7D16,82F95CE90D44A070,C18281804B5D576E,620C10D0733838C5,DBA9B925CCD9AB75,AC07704C8746C57A,E458C93288F378E2,CC1FC2C2DE90613C,567F0A8AF39A6B6A,3F0DEE9E3254F372,00004DBA5BDE7200,B5F754FA4CAA3D05,8EEB4795DA94E7F1,D8C8347052D74E97,08820AFB6AFC3ED6,30B2C87388C75A04,0C53C2E7365B2E92,0E1E6DA425C27426,1BDA11409052EADB,EE793C81C41EC6A5,766F3B56B6497A45,8C4AC0AE5AFC0F81,0000411639BA7196,14D710986CADB4FE,7A1687C0A52BEFE0,CAE73D113CEB4594,C3259210EE500CD0,CFBC3E0D064B5AB4,EE8BBCAA93F8A378,EF2FFC680D23C97D,C67D5CDE14067974,B9D9F6103677B8DD,586605196E44FFD9,FFD9E5C51A903B6D,0000077B4E83DBE2,FFC57EDC24F0B010,9AC69F5D24EBDC79,E4DDF993CB8255B4,3C411B83E8359F70,115E141E486DF430,E1A04BC006DFBA54,A418F19FC71A77A1,BFD2FC5B5A855A59,463D6CD264A8F8D9,940E77A319F8B834,6F6C9F7619218B72,000060D4B36BB157,9D12D5EFA493794B,D19BCA87CB5598AB,C7093ECE3801A3E1,5BFB5A4088DAB581,07E800195CBE8456,14905DC6BDEFD2F9,E55AD8F7EED2B20A,0555D7D6B597FDE7,E84F61B683EC4330,08AA07ACA6505F0E,4E08F3349B7CBABA,000060534156428C,3D09CCE635DCE9B6,49DC03217E042D48,24440782FAB86E46,555CEB99EDFC661C,A6E75D4291E49E84,6773A4B14890D683,398A520DB6DFF7EB,437233D3B41F5656,FBC666F50936FA67,4FDF44FCEBBDDADB,F507E3A23BFCDB5E,00002FDC06EE43CF,55D7E2D6FC9FD544,FD7061EC28F48CCA,D9A2ED395134083D,3544887BFCB99001,637F05654FC3A7A3,FF748791F1B2D13C,E8ADC7F5CB65E788,6ABC6B828F43B94E,526801445ECB0989,4B536A24636FA215,E1C5782F224C9D19,00006A0C9CA28ECD,C310BE4B648E6007,EC0A45034F4EBB08,01FC4AC4A4CC8F4A,C21981E11270DD59,2F38DC8F747FCB64,519682B115151307,3BFCEAE3339573E1,E220EC93E6654647,6096EE8132DB0652,9F2D6F791AEC69B5,E3C246E429F6E7C5,0000440195946F2D,39C710CEC6A9A697,AE2A8248E6A96603,89DC8751BB87AD59,69594717F588D730,B1676A4FE6359901,5B458B60706C4F8E,E30F6D6AC1430FAF,0716CD773F0E3BE0,4D5504838FD61D05,2F17D6546EBB81E1,4EEBD1D6645F6F6C,00001A98BB8810D8,FAF84DD265BFCF47,2994E377DAD4E8ED,3A002F0D0A1866A0,2995F03FCAF9DBF0,41A38DE91D61F658,DCC6D75D6B55BEE0,86C9405F1A96EFB2,3034B72904386C0B,B0A6B51563ABAC62,990C6E7FB69880FA,BD760D13300FF5E3,0000122CC60DDC9A,56E8A60558E199B6,274948419BBBF650,8C1F74719A898ED4,607978458D264C38,C947FE83D89557C5,39152089B89B40EC,B20E8171081D128A,51FEFEEF8000BC08,E8CD09BA9B329784,7885B3E983D9EDDC,FA5CED75B525F0BC,000020C90E71CC8D,BF1DBEFACE905B5C,AAF8E22B65B3C1AF,05ABE5066A7A0080,4918B53D45C71A12,2A0B82E18F9FA131,DBEB35BE2BE653D5,501811FF6C6CE486,AB038B187A1BF7CB,85ADD4B0FB003B9C,0026610FF3EDA2FD,ADC131B9B96CB638,00005FF7CBCD82F6,A872907E10C48950,FD3CD1E53B8BEE4D,B9782EFE81B7D169,0106C8B08F55CD6B,AC8AFD00A4BF95F2,00BAA05D060A5446,C30829C3B40B8F7D,970104C092394F62,59EDC1BE4011336D,84A1A72482A2D3A2,5B49C9C509C083DD,0000207FEFB3893A,473A2E91E160E3A7,569E9C68D53A22C0,58699AE6E8AEEA5E,49195CBD673B727D,46B994FB372EA416,2D6B25B8D039E01D,675B03BEE62E325B,AA74C1B5DDF48A61,0562621BEDE69A3E,E0330EC256D773F5,417F4C28FBA46F57,000004099C579D87,B32E0041134A34F0,3370A43D85D059C1,52EF725DE7A5E9D2,5BE40C0E283F8515,E2AA999A0AEE122F,1F08BCB36AD80CB6,1268729561AB734D,9FA6D96317077000,9F50AD897B9E0920,849CF72ABCC93B5E,2D2AB79102F8DA25,00003BB804BA4E11,EBD8AF2ABDF0B2CB,28B9EEC89B69215E,813647CE1D8D931E,D6B11907CD6C37E5,7DA2297D2D4B528B,2B9C3CFA6B638921,A21CD5B24A6DDA41,AC5DC5661635DA5B,33360CB7820837CB,92F86D1AABDC5CB4,4B1C48B68D2E90AD,0000297BDE937B92,5592B04EA0F4DCD1,CAE00288CC5C79AF,EF28822A7FE1300E,49804F824D14B71A,2E477E78C3D6910B,A22BCE94F6551602,60A9820856FBF693,7E42733A6F6618A9,29406576E06A6DF9,2CBF4465F9439B6C,E37B541FAB689300,00005D616B5F1649,82AFD7F2ACEF3318,ECA7A6EF2B1F55A6,3E7571E9CDDF810C,27BF287819E444C2,3E9B3848807FC0BC,E8CFD9EBD6009415,159667488F81E676,5041FE39046FC7B3,82DC2577E5C91F4C,4198FA83F6796F58,2AC5A4F96E5FCE24,00003CE66C899C43,1C9F6A5718262FF0,75E02A7A0A7E8B33,9BB4233B518F13BE,99CFB686A44F94EC,8AA07F104A7AFBFC,1E13D49D1B0DDC7E,EA371165C5328D48,EC5C0CB7FD9A3579,21D9030F216BF8AA,BC9BD83626BF8EBB,644C9F03387ED80D,00003D5B98F6B919,AD873DD76971F844,148EFE7DA6353006,565798EC192823E0,9D669126755B4F09,8446536EDF0EAED6,2A9BD249A44097BE,B1C62F93F3A314E1,C893597285E6FDD7,24065586B095F5C9,1BD57515721D32E4,59CD981D14024E73,00005AC153EB18A2,EF4807553309D43E,97442BCFA652CA0B,0591E9AFB714626F,0F0F3529150D265A,E1193266710B8FD8,D68DCC81638F18AF,137D13D195E681A5,F28D9270C9810A7B,7EAD684D345A7B02,4001EDD6F14A4924,E2E53FC05F7A9C29,000016567231518E,4A9E9037F98AF45E,A65FFA9888CE9458,6F4162FA5A1B8306,E150308D8C319661,2921D73E3A8C2002,C40A192BD44C7618,CD4F2E2DDAA764F7,CFC68584BBB3F358,4DB2A104FD8839E7,C2F226ECBBC1FD40,5243EAD493E93AE0,00003B777BBE4D73,DD27B65148F58B21,099CE55CFAE7BD55,41C27D52B8DD1B04,D605F6A781D905A7,FC8427F430961DC0,F28A560DBCA10016,08BE20C0F0AB9A17,91C6975B9C8E13FE,EEEB1BE1CE213D7D,81682DE0B068DE83,74F8772F011ADF8C,00003C832A035C75,5C46243F2505F67C,BE8E2558543ACDD9,01819A7C1A984144,A7AF17A10D68C153,AFD8E0168E603A4A,67EE073C47F3E727,BCAC6F31E6A18C5F,E6A3D1EADDCF785B,9384CF80965085F5,F0B5DA198A9022F3,2EDCACA691C05E6E,00002CA9FE826708,B87C1B0CAD255101,E403B3BD778C2AE8,8202C15FF7121651,9DFEFAE27853AEE7,808E1B258BC1BB28,4574F026DA7C21CD,637491F38E090941,071519947250FA1D,E7ABC8AB4229EB1E,861D099B45513766,E6C7852EA7745969,00002C67D7E28815,E594A044472E24D6,8EA82E65887346C2,6580EE2CD94C2759,D51ACA3DD30329D2,CC2F8A6377BBA702,A135FC550A145E20,D9FCFB2FD152D5DC,BAFD5EC5D2E68C48,8294929F99552F90,F62D08DD945A7C0F,8DB4C7CDCD164F35,0000271550F58E9B,72DE58B51ED072AC,916444EDA54D70D8,0337CABB249A2D78,3EF5C8E3A95898AD,BB86C8FFBB410F1B,E35066B5FD75AF82,EDE93498E0AEA548,649AD826C683EDAF,8B863FBB760DD697,009E9BF2112C93F1,C1F9A5D9A3C6A744,000049072A18B861,21D4645EC2479699,98E50C29BA3BFF08,FEDCFD89C45CB3D0,72622C801771915C,12F906626AC5F963,CB0523C3EA33B6AF,88861D2DC63B38BC,BD8C32B332CEE45E,C778D05DC9BE3502,17507D845ED2A340,DE16DC52FBB15FC4,000041155D6C7FE0,C48514EDC6A1DB39,75FDA2BC43BA3AF1,B69DFCD14002FB88,BF06B1DE5B9B5BA4,FEA60A69D7EFC099,AF900413A8196390,BCE92944AB61FD9B,2A7AE6FAA73A0401,3C55C81A8E9B3DDB,36B6DB77F7FC0B53,38BA8EDC06925BB2,000008FF1A28B409,E7B6EAD96D22C10D,C023ED73C9F17531,882CDAF7006E2CF2,AAC7917E8C0BEFCC,1B58887427AEC615,2C5688CC702ABF38,558FF8322E7C4FC3,C1B78E732B8CFCA8,B980C6939B6A645A,291F2D3214D6B5E6,F3433BCE1682F401,00005167C5D46E82,538D960CF5692731,7D429FFA46F16921,4B6BDEFE408ABF4F,8A40B431585CBB16,5D5E212DA0D27521,9E20450523E93FF0,FD2853410F769E14,3465805DD153DF6A,86B63EC6DF75B976,9CD9D6BC2B705E6E,DA9AF6207873B0B2,000002CDDF260F89,A6D91EED026C59AD,0C991BBC99292FF6,30602CA7CFA46BFD,BD1D5D8D8DEAB6D4,37FFF673774F5043,5530C32732D10C72,2BA4CC06F348C855,4E37F63D39A347ED,35CE6FE190234E18,5F67EE7929273252,43901A1F9205540D,00000FCC4249E0F2,AD8C2816A5543E4A,F866DFF2B44C08AF,6CBCED1351585705,9FF95050A6F9767F,482A222772C3614E,9A0B41583E16DBBF,41ABC0FB4F7F7656,F037BCD40D1DE9FE,8C7D24E106EC5482,6EA87BF9D6CBEA03,C0686582F37F606B,00003C77AD8A76CB,FD243F6D77815D12,BAC5D551A15B3BBE,33D1313AD315B317,F2AB507E47305EA3,0E75F065D5A6EDC6,243554E664E66330,85D19215A81972B3,F5D41CAE76255AD1,D5DB6C54CCC93376,4D0EBF032182CDE0,870E0A5857B790E8,0000296654761D15,AC803BCC634B0BF3,900831CCCBD9988D,33FF3001884BDCE2,A8B96C556F2CABCE,80C4CA0A3A8AF393,3D921F229120EB0A,52C1A3C49A8957A1,7F3B5DFF658BACE7,451BC28C6E0C867C,3DBA60A7FD58A5A1,E756D3273E07FD02,000069F9567C54D7,D495D8FC5839BF37,9A785D9FC13B8EAE,1DA50AC60F0D1254,B1CB49C1D73A6A51,4F2B7809A6C4A1E5,659D48652B33FADC,80CD6D2820478944,FD926CBFE82B90FF,95A1D0A77CD72C5E,C7D3667659B83E41,D343852972887C37,00006C5B9322CA29,3C06B9FD1EB59EB0,8C564E07BFA9DDD0,BEB9EFA42F10B0DC,1AEA14E3E2E72309,72523D009332E87D,42951E0B2F9BDDFC,112BF989D65F8A51,2421443DF7B4D8AB,9EBCA97A8F2A9791,A3DEBD29B9329962,7046B0DF5D35650C,00006EB5DAA5B102,F6C5C005BEA71D9D,DE5D1178508F89CA,28287223D20DEBD4,7FD4A49738B33552,5E736A0F4C79F74F,9D13FDBDF827B939,1A58CB00918525EF,B91963EE3EC1E364,3A85101A1E624E3A,97268A9459FF7105,3450C9EB02B50ECE,00004EC30888784D,4D592F8247769FA7,D17CBA765F287921,9446269E8D71CAD2,2E4677954CF006C7,7C4FB4BA5FEC0F87,BC35924F67C4959E,933BB6614A569C91,27D696D000EE646F,28E458D5821312CB,6EB36AF7A660C39F,B2278225246637DF,00003E1CBB0D6DA4,0C879BFB23DE4EFE,CB595BE837459E02,7A4BE19C0640FBB5,A31B2D25D1887EC4,BF43B4F8E2C560FA,3410900F232FAEB1,5424E0472FC29A9D,D8086249385C355B,7BE33589DC03FD95,7A2E2BC6453DF00F,20A139DFBD02D0D9,00003FFBF7D81C34,3671CF959D17BDD2,617495F4A2827043,AE6FBE6125C74794,18285ABDC0AC2FE7,90F8E6CAC9196102,4AA0F8EB6B643842,41B40701F42189D6,40C469044E0A6A32,7867859157B3C889,641694A79C2AED15,0B1EC1A94DD1559B,00005383AF7F3A84,C8D14F7DE9415F67,C4A1F316F3D2CFCB,839C06181F43748B,49B7B5997E0EAE31,542F103F7220FFE5,30288AEA1E3BB12C,9D600C7DC228CD58,626C146D30C32715,BE92D57BCFEEB7CC,D67CEF2432C59411,ED1998F0C906BBD9,000038B52C02F086,87C903A66963CE20,C2A87DD243FC033B,52AC0C317BB34595,75C0FD2B9B02B533,8D4264F2C28DD80C,14980EFDFA973051,B0F522402E01CC80,733211B7A1C8CD56,FDF83A9C38AFD944,A22ACB4AEABE37C5,347CFE3DDC849B1C,000009D6299327E7,FE0EAEE30D1AC6C3,8DA0C89E619C0B24,955933012F1D54AF,1CF562B46275815A,AB998BA36B829A66,81A93C1F2263A5FB,888320AA5244EA57,5616B1B352CD8D74,6F4B9D7CE3286A42,5AA8A439C008D381,92E92F9035C2A33A,0000005E63ADA7A3,0BB02362E62A4EBB,CEA27DC681271FDA,B5D778DE27497277,0A0122BA7A1D2226,B56F84EACA6C3CC9,C4D7EE543A4DDB09,066968323B3AD791,E2ACECAB4626FFE1,962AE4D6DDDC18D8,54E1999E854791B5,630BAB553B46BF2A,00000271EE333D10,7BB7A4A07B0788DC,DC36A3F6607B21B0,4750E18EE74CF2F0,464E319D0B7AB806,C25AA44C04F758FF,392E8521A46E0A68,FC4E76B63EFF37DF,1F3566D892E67DD8,F8D2EB0F73295E65,457B13EBC470BCCB,FDA1CC9EFEF5BE33,00005DBF3D92CC02,0E7E952E9A260914,92C98EDCD6E01424,8F2B207221D33C50,AEF2728CA22F318E,5FD0E29877DC3D43,1BDC7B7367E4E124,FF5BC4186BDDCAE7,D20A34710EE8B44B,2E0866A5B9467EBD,876EFC05B732A6AD,9D39159E24822ABB,0000658F31DC0D6E,73E75CE4A532CE4E,8A9CFA6FD7C7D8D7,5C32241579AB4D31,C3B150BD8F701620,3490B85EA3AECEC0,95A369A8DFFA3A5D,4FD3E2058B184D09,EA9B75C9C036EB14,4E0764498F8C479C,B292905A05D75662,31CAFF3E38483EA8,00005D55ADDEE14F,7BB7A4A07B0788DC,DC36A3F6607B21B0,4750E18EE74CF2F0,464E319D0B7AB806,C25AA44C04F758FF,392E8521A46E0A68,FC4E76B63EFF37DF,1F3566D892E67DD8,F8D2EB0F73295E65,457B13EBC470BCCB,FDA1CC9EFEF5BE33,00005DBF3D92CC02 - -T_tate2_firststep_P = D25C46609D011910,135AF5A98C28ADCB,1FBBAA32F245FF2F,AFD791F380D906A5,A7A53C388793D95A,FBD17414C81EC903,EB07E1336AF105F8,AC3EA4E2E4FE53F6,B6256871166682DF,53E7689F74C06845,23F839F6531DDBCC,000006BC870E1A52,0BD5F83502C76EB7,4EC78E2DD52CAB67,F9BDA9CCE6539EBA,B97FD14D7E4109C1,F486C305000BC492,138E2273FD8FA40B,22A1D7254ABCCD27,9040445BBBAC4D22,C5F6A6E6E30F03DC,DCD17AA07985BD11,4DA3C9A422AC99FC,00003BB8A508D510,D40A45531EB0EDC2,C2299904BAE9675D,1FC9934035AE1105,0A657E853BA42593,9AEA7A9998765F91,C971E696D54D7F4D,F0BBEFBC42CA0BFC,0A1B703139AFBBA4,1449BEEDD33383E2,D56E2ADA01E1CE44,123F51487ABD92C1,000002AEC11AF4E3,A705DECD67BB154E,3671355CABABE5F6,92D2CA2173DF3764,9287F2C3C3ACC70D,22553D769BF6FA4C,1A02C98F8E9FF24C,A1F4FF3CB5A2879A,786B1F479BB26317,6C788B0D7262433E,5C08F513D0B359E6,0DF77EE49CF2DDDB,00002BE7A0285CE3 - -T_tate2_P = 5CBA3D258C4DB901,C93BEDE745B295DE,BACDF727F64CA987,83ECDF3588EB0EEF,0CD2BAC5AB77E0E4,1D56430F8D7803B2,EA6FD88513503E97,92589961E52EBA47,915B0E001AEFB2F2,85FE3AD27CF8A2C7,A2A5879C170ABF08,00006756AABEF4A2,6958EE2BDB497F9B,0DB206E7ACB9FCE8,67969F38A0162224,22C73FE0E1C96671,2A145539A0E9EDFC,DDDE81220226093F,05AEF2EF0589015C,B2D79977770478D4,92E804AE163BC6A2,607A5C228D62FBAA,9EA104FCAA562E01,00000AC521235AF0,1DFA0D28D1939568,0BF57BE62BC3BDA6,A044A0DB9CB3D35A,1A05ADF0635ED21B,0D194D18A476E296,1FC7E5835179FF39,0E69F2A9DE5CE4A0,1361BEA4591991EF,08CE96F83FC3CEC3,22381B2E2D28978D,D709B6C6CD68C642,00006518ECE8D749,8E8E1E64DDFDF364,7A7D339CB2539473,601E8F3CE5CA7C4E,D94528B30DC5C326,8A428DB8B5F6A148,AE14E31B05C912CF,EA3E94DE2C6163FA,AACB9CCC709F9492,2F6F88D6C13D722B,1F0517DCCFB44B27,E000AA61246E6DBD,00003D98D655AEBC,511E94EB02FEFED3,E7D839A4F7ABD9EC,E505B5461C5D8D99,83540DFA28217FFC,E647DC67A73BED9B,CC433B88615C8DF1,B0F928600AD8DAD9,7062211A58F6C440,6D55864BD21E37BB,97F47967D7A0A780,F83294597DDAF9F0,000060C4D23B7EAD,80059A4DD85AA23B,7C5B5A29CC77FA47,DAA8AF0AF6697D0B,FFF54D8372626502,C745F543DC3C19AC,F76B389DF4A1DB76,0A8CE3A39463C476,28A8939ECA08C223,F51F040970CBEA9C,FE97C69A195B7F09,1E1D163A38DBEA2E,000056DD83D2C142,21BC23E97B1C7B97,A0997FD85A8F9B45,6A727E0402B0DDC4,E874CC2199F9882E,C78E3C135436E8A5,AA7D317588E787E6,9A42E70C91B21B1C,E9FC183C27F7E021,31D3AF2F13D804D9,8C05C0395551A380,74B3B5BBB15EF970,00004779B71B0005,157F0DA1088D3B9E,9DB2C0ADF97DC9F5,6A98D257AFB571EF,32E96D0346445618,6CB8469D7B62E2EF,CC0491868B121142,67F88CB845DC74AB,B8778DE9D7C7432A,148171F3A97AD64E,917718DCBB09E79E,96E83D4A274E6FB0,000020182B229ADE,5FA5C292FC75CCB9,37DA3EE82B12DEA0,F6C8A8FE3DCE6BA1,CBD544A976C5741F,014EBC6847C58126,BCBCAD6E1B25AEDF,80CB31C6F315851C,4D92B6C1C9E51A19,7341B0B9927CFD37,F858A9A191EEA266,A8A6A4F2ADEE9940,000059D251005B93,97F8276F285F23D0,74BFEBA2BFF06B30,0ECB37C5724D93B7,B428830038FA655F,621BDC14CF2EBCA7,2AC5988F5C03570B,EC63CE172DE253DC,AB853C36B89FB08B,6AE0B9362B60555D,821B834612261F22,FFD9892A3BB0D1DE,000020FF757CDD24,B3CC96053606DB8E,BB6F66FD1811D1B9,3DDCFF4CBA448531,15F921BEF2FE0EE0,EBE20A463D1B918C,81898EFFD5E2CBA7,6365264C10FE4400,CFF74664FA761D97,B601B512F2DC0DA4,965C72D8A1EBF74E,B4A225CD1421351A,00004D0C08F4CFB2,3D6820D24ADF83AB,7E22241B437094E4,2835524C8809AD2F,5CB80B3D13478B06,5E9C772CEB8FDB75,0FBBE0407E9C7BCF,9FB164E6E97798CF,EF2BDA583BDD09EA,945822D3F7FA6B6B,22C72B0E217BACD2,B19C22156612DDBF,00004646BA37E3D9,1528926005935DF8,47177C66840F357E,360EF7FC3B79C99B,558F3B2C453BE8C3,7893E58AA524D581,40759484EC40CBE5,8C077635B826CE30,8CD6B8338E439E3E,E54AFE880266770D,F14FBE1CAF5E102B,2E633C12D04E905C,00005C31AE074815,18E7E91AF372066C,2FC235FF6A7B0D9F,A588D6FC403871FC,44F9248FA75082A9,D6012014658D0AEA,559D683C9C5369C8,62761914883D677C,89DA613889806CC2,203455F3EB39BD1C,7523EA22C34CCA50,100211A596651283,0000227DA670A0EE,AA211663BF26A0DA,D68340FA36F1782F,1F8096ABFA533427,E422F82A58B813EF,7349F71DEC318042,B88A9B54193F5162,652EF038E4A7753F,25899E70AEAD37A4,1AFFA684C58BBD42,96C251CBF0FF147D,CE368E97691D3B2F,000068575308EA86,2E889154842FBBD7,C3D444D331CC5830,7A11F55998B74F6B,923AB01B0A568215,465F390DC2EAB449,1B16D976D7C3F527,F8635AC7BA92EA77,76C2994383401758,48E84B960E5C431E,915627D09C705E21,7DA30EDCF64C0526,00004ACF5D342AF2,0E2CE2864B31F854,B334DFB6EFDEA11A,8E8D235C6F622A0B,696C058ADBE58A51,DFF7A7F1C8042792,DE0158CBC432F386,694E5764877BF8AE,B8C0AF407FAD626F,E0174B31F9DBDC2F,37604D38476031C6,13638B9011F63BA8,00002789E3D82D8A,E847C382CAE8E73A,3F71405F0C894063,D48AA86DD161AB69,D866A387D95E2402,5F65D9E290549A0E,DFEEAD352A939C9B,2FEB2E81E748FADC,27E10E8AB865B35B,D72F7F009385ED20,D203BF970FD947FF,6047B015BAD7BC20,00004F739EA1278A,FDD2EE96DE27FBD9,B55C39FAC37DD274,D6C6AFA29ACCB9BD,207B9B4CD82C8300,F6A8C029CFFD5BE3,3926C29655BD2E5E,9FB1884F9FCE6721,A504F780822946AC,4DF965791CA48528,64F66606FAEB46AA,72B0E9549D782D46,00004E241838E0D4,E5AFFD63A5A01D7A,DFACB8D01FAE4C86,86F5FC9C11AF1E34,83DFF2415FFA6638,03D30E56FBDF2409,AAF6B44C8ADA2FA2,1D2D9917EA040D74,3EDA7ECC9152F949,01594F595C725C60,32F77925526F70BF,A6D31E12DF98F937,00000FD6568BB39E,E7E10782E0939000,51CC1CEC8B970616,5E4DAFFE99AAABAD,028B8274220EB051,4EC720E0B1157EF6,2EC0FA75F0E9B7E0,15F2AC3FBDC86011,FA0473CF7E13401C,04FA72110D8E7C0B,95E24A3613327DF0,E5E621B5A6A3C58F,00002DF1B098DBDC,A3895071D8A40F47,223A862093A028B0,6706AF2B0277DBEA,2785CFE85513F89B,2F2A1DF3FEA5A0E9,ED7019D13CA2FEB7,9AAED87445D0EE0F,1C08981A646AB5D1,E5BF74DFCE52CB8A,6DC18BA62068335C,5C6C2774F382BD6B,000060C113164B4F,E8A3BDCFC1B1211B,1EF2D18FE3EF92C2,F4B209A1B55B997C,E61F94D43AA5B5A1,F5792FA187BEA099,BE5779F1878B6D86,B9B53B36F23F8519,536239ADD745A207,46BFFD688C7785FD,10DDC2DE07F59822,A933C8145C093A47,00003BBA4D8DA213,7D9AE9767A12C6D1,D0C72701AFDFD84C,82FD4C3AC7A57466,D5E90F19BFBB48B0,5C9D0A35AE541D9A,38860009532762E5,7809641F3A07C1BF,189D2BD8D3AAA854,306E41668A35AD75,61FFC0F572231E49,4E4055AAD90A1B6A,00003432BCE941BC,4CF2FAFE5435C1E1,A1C6B2319150C0FC,1B156DA8A019B27D,9CF84674521A0605,F1AB517F13BCA3BB,010F1D76570F449A,CA9CDBEF134CC872,4B1D481D7F9E4BAA,E6CCD3380ECA732F,FA5D0CF663BBB182,51A4556EB5356C77,00001BBEFB926A0F,02D60A1FF932D563,E30A677AF09DA717,CE46A75A0C997B55,E32E77BDC80520C4,33D446BA879DA878,D1EBEFD3868D23DA,2C5325C8B57E4A74,762651C02C4804B9,D107802DA5F9C096,D7D7D855202ABF06,E0DB99C066F47426,000065CDEBD7B009,832AC3AD8DC6CD68,BA29CBBD0464CA09,468A993209994C0D,D4F5E0C12A47B9E7,D94F9FFC9B7D72A9,2E4E3370D80CE2E8,B78E9F94771787D3,CE1D7D416A8B02E7,CE1E8E808501E697,7F6976CF60C41BF1,A6D13EE55001B1DD,00000FF3D189024E,02A038EFB6524390,A91B92F129350589,6D9652A0FD20EE32,02FDD5B9CB673F28,BED536807A7BB51C,7F3CA6737577A4AD,F9A4834D559973B6,EE1E54D8DE63CD6C,228AB67D384A117E,303E38F3678579CA,A35FC4539C009EA4,00004DC489310E29,F54B16115A969658,B5EED2582C55B776,292E95F3FE25D951,F3EE707A7DE0FD70,A4C7C57F13D6F285,02F35D8E73C42A63,0D7ED3A9C4B6F6A0,4391CE88B005976D,5470E01FE61AD8C7,3F6B312FDBC6A2BD,B614ECB48784A9FC,00000219F0C24C58,080F7A8BC66EA5ED,099A4996F19CF23F,634E892A0FBCA564,70E0F734BB9DC55A,E540BDC568041922,52CA58080DF9FE46,6A4FDC548C380C67,A0B7F54A08612419,42CA4E5B04627BA4,95E82F45A4B3A07C,CB69A1B827441646,0000062E9A37AE93,8BF3F8CE2159D735,2A2F10F5FE0764E4,74E33C9EAE8164BC,E9964C5C578CF675,739648B3BF9A5516,2EB28FE4C5A8A9B7,C544882008B0954D,2B645703CFB3F4A4,8B7D7CC7A96BED8F,A836D7F8519FF12B,DCD83DF734BB00E5,00003522B042BFB2,1AEB3929627FB774,02C943ADA0996AFB,60AFF98AE7CD526C,6226BF64CA64F717,8AA151F57582F546,6A26D73BE76E48F0,411F85A23C13051C,9938464F96262C80,0B203B869951070D,BB7E94B8B4CDB5BF,21AA8C2CF15C4BC5,0000166C41FD4896,BE6119B114DF7800,B89918A851AF141D,2908FC0ECF1C68DD,44D0649947CBEB2C,0F6A8D53D74C7E8E,583CD18B906AF16E,4739A05CD0877213,3BEFC67DF16EEA55,14B47F2E28079D5A,E86CAFC132EAEE1D,07AD2DCC5893DBCF,00000EB054F6E35F,14C4D81E47993159,6EF5A4D78FCF6718,CE27020FF4FD513E,60440CB6A5120988,4E7728C4DA1603D6,88EE6B817800F286,45903C2945EC4C86,A8EA0F5F9321F4E9,4C0043CA8F016E17,A28F83135B194482,EE8C871CB3364291,00002B180ECB1584,2053F02CEA651A06,C7BECF674E947C66,FFD638A35D757DA7,E6271C319C1371AE,38FDFE0A8C6E921D,65DAE7059782ED5B,85E86618764F68B7,F4C4D2294CCC2D3E,5104B360F302C231,557CDC90E7A17C75,BBDC3B0AFD71F151,000002B9652E409A,DD429BA06F75A5B7,722BC7DA609AEC4B,27AE1B6692CB08DE,460B1EBF4FF76939,FA570BFFF9A27895,AD12503F7568D9A6,46969ABF8AC3A78D,1FED6E47BB4E3A1B,403E32854BA1FA7B,D4A6A0AB0B0A181A,07806AA7123F43CA,0000597F5D7BC9B8,4C554FD58C1C2C7F,8DF98378847C13DE,3A8B3D223CC796B0,2DEF2DEF83AD72A9,83C7AC1C78DC243B,6904B9772743A207,E2F7AC6DD8063326,7AA6BEB0E91BFF00,FFF091EA0436F977,781DF8B85120E82E,FC718537BDC20CF1,00003C8EB54237EB,DBD71C3E67BBABE0,0BB5903AF46B32F4,9BE06881516F89EF,5C8255DB2E0365AC,14DE328DEE5F97C6,F09603305C2A6783,E79DE224A3F146EF,0F9B59C03D602807,5D1416D1F9903DE9,ADF43164B0DD9154,37EDAB1B2E891C44,0000575E8EFB048C,EE96379456F70059,CEAD852D514DE605,23873D325FFBF560,0A27269AA9A632F2,07964617F2D20553,A650EEADAA36DBA8,B618643A1F9C3C30,A28135B0D959AFFD,2EDC009B285C04D7,B12FC164914EAA11,A5D24149D8EF2B0F,00001996AB074829,3161C08619A1577A,1A3A2A0C20EE5558,E5F8D470F7D49297,D7264D5F0759B673,4464C94A8669F7EB,FAE0B47BD57D82E3,535D3BF088FEA065,AEFF59A13D661C7B,2F8895EEBEDA87EE,910DEA5541A5B152,529599AF81FCDD2A,0000032211BBE628,AF6D30F4DB5094A4,8626E137EE6C882D,A37EC05261134713,3505DA260DC131F7,B18797933B4A9CDB,C7C873283272C79C,4201F1C0C59385F8,A4C506851428A303,33C895DAA0D15199,4A019275D4D25407,6490AA86B10F90D5,00006A9FD7784C2D,4B970829EBDBF90F,356CE91A9AFF2AC3,7BD3E7A2DBCDE8F9,06B44EDCFCF3496D,FEEB0153AFDEB9E4,6D815EA3C6946A25,F0764CDFD8F4D7A8,14F0276BC00E0FC6,7F1E5B532E052D9E,5F82B5FA519CB6CA,1DCAA5778BD700DB,000020E74562B070,805D085F8DD17589,41521E7BF0402693,7DE22A7BB742F164,E014CDDAAF1485EC,1D5BDF63FA3A05D5,EFFEEA8F264627C9,71C8039F63853F9D,54687EF1E181CFA9,43F7CA34A9410C35,02D90FCEDA7CB008,3DB8011F867BF9D5,00000C8E5970F973,A43DFE268EC39C2F,BC4C68C5D71C0ABA,57996CC12FAF4885,E663E934FE8C5D74,826C19AD8F9A782A,96E4CD46F53A0054,FD6E4E666C461A75,6E2648018C565DE9,70316109001B72B1,CC49465368017E96,3B784DA737CA5F4D,00000CC43E195D53,F09C5063CB39F5C5,C56B2A961D80A1AC,84296F771D943F6A,C5BB2F48A3A08CD3,99234C5EBC9D4FD3,0353D329C0042046,96B41E761083CF88,CB2266C6FB2ED33F,3542606F50DB97E8,1DB5C70BBEEA857A,C434E0DD85B12378,00002041ADCAEC0E,77A20CA7CDACE952,2689BF152AA3C9CF,511A725F558D7AEB,AA1B91A6B9B73675,A672FAAB26196AD0,3B87B140A328FE0C,7D7DAD8FC421D633,9FDBB11245C8393D,D892C5C25F6FE345,86F87F2614EDCED9,866B2797E9FF9771,0000200E97CC845C,EC0905D774D7E474,3A90720A3213BB58,296DA9172578E6C1,C91EFFEBBD4EBC19,3778C00343A0669C,6183393EC9449AD4,6C3D452533F8BB68,4B91DC4F1D058E2A,0574455763C564D5,BE6B90727F6E755E,7EC6F46186477449,000050BCFDDE53E3,1C2C983901A79B74,2B34B840C773726A,E7520C1AE22CCEFF,6B401F073D32552C,1668C28E7D4F8F97,2BA08BEE9ABC3263,27305B33B4B82D11,E5770A0A38D358F0,BE4D3BFF20B71861,0C920FEA9840717B,B501BFBFBEB5EDCA,0000041593359C7E,EB6EDA47BB73A070,AB0F7288C418E4A9,3180BEE4C7A6F652,B739C5404824085D,E0513F9150785AE8,1D6B2758706A2324,5D635E0525A0EE67,1C534B78268B0543,37DB26138EE41C26,A16C15634DC4A3DC,E93D220650F558BF,00000C2E409ABABB,BD8C2027C5898F26,07D5ABEAED7F2680,E2A1B6DD8E1525E4,3ADF479944814082,AB0566BDF2E4A7E3,63D46185174CD3B3,B76C168B50B78B5A,60DCAE98041519D0,B8480BDDD34EB0FC,98C9CB5832CD4556,C25263539DB04611,0000368256534C61,930F75A9B94BBD10,0934BC5A8224BF39,61585E6B71C8EAEC,59092053415BB4BA,2BCA857630ADC08C,A5947C6A450743E5,101E776B3AAAF9CA,3A2FFC94B9AE6486,7598C6A595B6CD6E,C72BE1871860C56C,0F9AA3523874BD27,0000406F93FC5D68,886F6375DCAC6E78,F54C331C88E5F44A,A33708BBD2CA43C2,03F5ACF6CB0E5D2A,125036CCD6D4F331,73953DE205142686,56AB904F4EE880CB,C8B76BF57BC8633D,3159FAAF78EA527E,14845744A9EDB397,094DEA8325BA4365,0000283344BF9B4A,E9328ED251D588E2,825D5677FFA9F3EA,D55A3D5C98778D7D,C6EA99B96EB39568,96893CE8E4A6F92A,0DE84208F79C2FEC,80B2E92814A5939A,0D39C0186726127F,B2AEFFA4982B6EA8,29EAB1BE2D80B363,6C1412374B391DC9,0000286E7839A4CD,ADCCE2017D720796,3CF37BE76221E2E9,80F87D4A9BEF4067,5A058367E7BD91ED,936D61CAC2E5B2D4,3A9DCEC29A5FFDD7,A9F32A8BA3722180,95C4E1EC3A198B9B,F105B9E9DFF17FED,4780EACD543A689D,0AD078F5E20A4771,000045A1A209B09B,EA465AC848046C57,E82D863B6685C930,66819E1722817E1D,5996538AC3585182,947EABBD92383007,4AC6AABACC88ED9A,DD1AFE66E409E04C,8AE5F008BD7D6E40,7B3B2190807DBB5F,00F040F5FC8E7898,67F1ADA5EEFB3A87,0000630F0B0E4C0F,7CE6455E97471D8B,DCA36E5BC85F9198,63ECF6C582A23173,F313939E9C5464FC,32CF090C3A1F7347,658A2CAEEC8F4786,E3BF1B69704A0A7E,95F02DE4C987E2C2,E935751B838B885C,BDDCCD5D0F2804C4,1AA2D7FA15DFC1D7,00005458C3949345,7668017E4D6FB4F5,D9B331B6C48B7C09,5442351AC2F4C3B2,3E6CDF879BABC260,D46B3534A3D1CA0D,5AF2E99AD05094E3,FDC9D95552195146,FBC344D6939EF44F,1371A9A0505BCE0A,9EEF6BFD92D3E0C8,D4D54EA496E665A7,00006B9490CE1A90,4F905260A741BA6F,9AC93C3D4678B1D4,BB8855CC9E6F4347,5CAD8B47DBDA0E90,53FC3648398DC1E3,FB0F5C87FC83DAB2,5D021A32E9C389EA,39C903EF7B4962B1,79CB848B33634DF5,D19D8F267627D337,587757D0CC0701F0,000034FA45148BD8,96B3BE6AC25F3AC1,4A2F43CDA7E59B42,F5D492D082AEB6AE,0628F0E13ECBFB10,E063690550C98C83,C61A82B471EA4449,88AF7315C201705D,6A4D2FF7EE764C99,2CD8128A82F57D78,4BA4DC86EFD9D3E9,C9BDF40619CCBA93,0000365D850572F8,8F9920A2DCDE53EF,8CD8E9E67E6A4475,8EF6E3228258199E,BEA42B76C6586902,7B9AB9EB0EDA3449,6E0B28F89964DC76,A36242EE24B172EE,F62783DBC7FAC34E,23D8E7E7F919F34D,03A4D1221E72E403,B577934837E2B9AA,000037EF891C55D3,BD7A6A2E3045D4A3,CAB0B437FCE6BB9D,61593202E9BC968E,6989A822D9131DA5,F4E77C8D5057126E,E5A10AA1F8179CA6,1A3ABACE5FB89562,B062435BA114B812,1AC6A38FAFBBEFB8,A1F63C538ED17030,B3793074CA60CA11,000027BDD1CEC86A,6C42153B112E18F6,98423880D5908E5A,76B044C6246DDCD4,591D4D0F85DD0EBC,FDB45EA8CFE19C36,518F28D7C9C315DF,418EB1A467EF4009,A0B739ECB5AA5346,A8FFD5C836707319,123F03F579F67578,2D3A070FBCF2460B,00005D8F69CF174E,529BEF42410219B8,9C8A6125235AAF33,0033A961E3851434,E744168A8F394B30,65E7ACEE4E07F3AD,890D5CB5C975C0F3,74AAEE25BEB49A8A,351F366EB7F6B48A,ACD5A69BF88083BB,E9447E86EC71D3C2,D0CC6314933B3CAC,00000FAC778B957B,53205AE23678B875,F9AE05DC7FDA3718,7640056F0EB91C72,75045CA349B2C91E,9E55D1D3654E8CAF,CEC6B7BEF71BDAAF,58415465C1CF5333,0CFE3460BA9B1B35,8C6614E0B8D9B9A9,5C79A4AD1955E90F,A9D59AD3736FF199,00001B9C1E56CAF8,A38ADABC93E3C796,A700037F9F828634,205AE675D30950E6,0A83AB9EAC4C9641,877706DBB805A290,CA36DD24C12CE93A,AA0ACA37C493EFB8,7ED6A2138EC1D093,2EA9F2560A227ABF,6AA1D7251B15C966,BDD980B80C9FB1A0,000019989EF740F1,A33E013FC257961E,963A6DC3FEFE3DEF,A99C862DF4C89EBA,06ED179C5FBD63FC,5A42E89DD972CEC0,2A62DD3BF291BCE0,B14F11A3716B466E,56C7DB1F96ED6953,F2859B577ECC7B32,6DD5FD275D5CE140,C213B863396F8DA3,00004B887983949F,4220FBFC21617350,52DEDEA2514052A1,61DB2385A250190B,168CF0BC44160702,3421E370CCD1A997,7DB25937FBB26AE6,DDFAFFCFCC939C7D,6E2A44CC9FFA1C6B,F5E8D006F150728C,2489DA100AABF767,4F7DBA9D75BB2053,000009F97C0D3904,424097E246E67352,01BB12A4E6862533,FAE8A0770BA659D3,523FE5A8D376CA95,1697E8885347A78D,8C798CCB7B350621,F406020637C11EBF,6AD83F55F776AE60,F96806DD282D8A9E,926ADA1BAE6BF6A3,8604793896D92172,0000396C5B03A57F,AC97C4B97F7A20D7,2B4BA3DE0332F057,DE29AEB200C5002D,C032DB4396088C68,C136025FE94DE863,5455999FA02D032B,DC479FD377CDE714,06627BFA2089BF1A,1E495F3AAB5D855A,1DA6BA68EF86E00F,5ADB6C4F15E033D8,000035E621A9D5CF,CB007785A9DDA68E,65620FA72D99486A,CFF0A50EF03EB87D,5302D34D70DE0116,E52F109344B61138,0DA64CB86480B9CE,33A72B3F319691AB,A6C93687C8CDE3AE,08AF9FF57EC1C078,179DBC8CCE9DEA5C,C0FD023C31D5F5B4,00006C1371EF6F24,F6B71BDF24A18147,E6E48B0CDADAD3F2,896DC21A2FF48526,190C4FA334475582,0798973452B54AFE,D8427A4F33962C6B,DA0AD844B4F8C0EC,ED2A69BE432C67B1,9A023024C0D0F03C,6A8AB53B882D4E2D,75578A63C2F012CE,00005C22C5D6DD36,008E0156EB8B319C,1E9270960505C4A0,F1D2A77460A21333,7EB4CA80A56DD431,CA7C30B9539D13C1,BB3F76C81A8B3474,DFDC218D225C8696,0AFE60B422F9DFCC,FBC60ED064FC3FDD,34CE177EDB3A1C3F,326B05A44979B46B,000047478A74E209,E1D556AF8D591809,348A226860A85202,A62BABD3363ACF93,3CAB3B5428F48314,AC396D7A26C72B60,7516C66FF2F6CB13,C759AE830900B4B4,3B051FCCE8A45EC9,2CE62B3B47D25063,D55CA270DECD18E8,42C29B7FCB23EE4A,000010352FC4AE37,280002DE40DFF70A,734A5EDA67293219,82784507DAB3EB17,3C098B309B2D9AC7,DA945EDD8840902D,EFC197D6ADD40B91,1D4C9F0246352476,A6ECBF6E0569F229,C479E210C07E77C9,20A9A5C2BAD6CA98,063C8D81DA132671,00000C185859EE2A,3B3E9189A5F265B9,3481FD815DA44FD6,94EB4DF085E1B3AE,AC04299E7EF1E6F8,24E77ACCE6751CFF,AA278E08EBBB6541,3DD9BCAA3C9C33E6,FAC22B23435DD337,F570CFB50D5A1F47,385404F3A8C9BA51,A94FDDB18AFF2D9F,000012A81AA82CC5,E480DEDEB2547FFA,D39C6B84DB08980A,F115C7ED2077D571,45D8D05698943D2F,F3338988A9EA30B7,07704311A82584B1,5309C2DCE4C543F8,2037EB7DD3DD7F7A,D9767D68E8B7EC75,1A8A8C36AE561EFD,F4F03EF6B741C942,00005878F9DB185B,DE76CEEDACA86D55,46B8EFC944A3D0D7,07B8A37A59E29836,37F8EB7B2FE20B5A,5797AA06A2F00015,644957FF5C8523AA,230EAF1B3BC1E1E2,35A7A1442E8A1A07,93CA2EF626691921,D1820F40B90BACAC,AC54A3D28C5D4E6E,00001D5FA816DAA6,0FCB318A8F46F31C,774A928216140A05,501EF8A38A330C20,57CF5D8F50D03602,61DDA199DB7D9825,7A4516163C7C5106,99B04C3DA1D198EE,2ABE499FE834E418,8781B12CB4975B8E,52683E5887C4CE45,86516E4F42939466,0000517E32E2B762,76086B2F73F975B4,5FEF3048FEABA106,ACB512CCAC1B5EFA,240E4A3402878C72,3DA950549D20ABCB,ACFBD804C4DDD796,6FAC411709FA6672,307C5DD098F897A1,C4C40A887A603AE1,0BD7A66FE7A07FE1,AD04A975F05FB7E0,0000262359A6AB8C,8BF4AF5FE600FCFD,05D3B6EBA0E0B1C2,6D4A8E907A63471A,8415FB1F75E485A7,6F78FB977D0966E0,285DF289B02259D5,56941716BF255EC4,1143097C0E3A3C48,5A5F46342C3264E4,1AADE617A632DF2D,6EAE295CE51CA85E,00002DC767C7D8EF,3825B380B2515A12,3EA1D28153098F9F,F9D417F6A3EC985F,DFB327EEBFE29730,36652B712937F42E,C0F97A1D5B1B5390,3685AA590319305F,A92FC0503DB169A2,D3F51C3839C7BAE0,15CD05F0C65B2164,46C1385752430267,000038A4FB9D77FF,043A92D412E11A43,8A2A13F5EA19C06C,C11F71CE3984FD64,357E2658DC9E4BBB,B4480B92CF0573FC,09DD7F6727FD9106,B121B325B3AF0550,7633054FB50E03FD,86AEA26136000CEC,8323091939181B03,34D4F211C4145E80,000066C461B55309,57828D71127D0D23,807680D3B0505DB8,38374C5A09905AC4,0FA3536E2ABD74FA,2189C8EE935A9A28,82B9C7A2AB5CD761,6C8F2EB08105EA8C,007B98CCD31371AA,AAF229D787513927,250BF78790C9D7CE,579A7101FC758D2B,00002B6D0C90D18B,D3AF3F6617547B6C,9B7202C8B384D964,5B2A96687E935838,BC908FD8CF1C60A2,FD34DE962F89A54B,EE95827DAD033A11,6D6A90127A3344D6,76D11498DA880725,8EA76AFD842B8BFB,FB7C77E1F6326C6A,8067F2BC04B1704F,0000005B6E40CA1D,2DAF18CB610CC92F,4F2680FE8DB2CC34,DA0FF7171D838A23,3641D11B6FAEC879,F24F57F521647C2A,4422BD9BDAB6C50E,C067337E33CD3669,9339E1F02D84734F,4080555A8D896D20,536DA9A3B01A828C,551B78A9BD32B6A4,00005008F04B898F,514569D428D53146,4F7BC8BD8ECEC3EC,592FE71FC33838D3,6FABC42C4D347154,5B178750772573AE,1054274E6090252B,13E50D412552AE06,C6B9F879B08AAF7A,553549B49335EBFF,5E3401C37585ED62,C4C74CB6BA594574,000069353DBE6E91,42A940DAE16E48DE,1CB00B614D66C312,38B37FAA40C6EB20,4B28CA3DE137E88A,6B273020304E9620,06E97470E09E81C5,AFFB94A4F0CFDF02,CA1EFFF42D586F26,AA585C737CD5403B,A3A526C411FFF3A3,C85E567169EC89BA,000054DFBAB8DFEA,E099DEB7BA12219E,5F8C1D04082784E6,CE482EAA52DEAA75,98719BB142FE811E,153EEF5FE22F8F20,38D51FD849D3B74E,5C86B6278A640EA2,C69CB97BCC886A75,5D0521D92A68B24F,D56A1724BBA1E55F,7ADFC3D86BE6BD8D,000013CBED09263E,662874B8D567050B,D6C72FC6BFC88FE6,B6796B2556E3C09A,9E62F957D2A94442,A5B18146725B4DA9,7550892077A73C8A,9CE4BEB642A151A1,7ADF2B216A074931,8E571EB025EAC614,A833A64D7A82281C,A84CA7AE7C03B699,00004463BECDC557,D001AC5AA055505B,D9884DB394070371,965F97C62F9AE48D,3E9A78447425AE5A,EBDBC7DB7981B58B,74AA226F7CA7D687,D2B42A91A06DB253,B1EB825A12F2423B,1901B982F67FD6E9,EE472C5F0564939B,CE75EBBF993C3C34,000037C18E9EA72C,7F9F705CF86854A0,4E4ECFBD5C74C153,57855EF61E2C30C1,5BBCD9AC285E6D21,61B47A4253B87135,E932F09DB46E29AF,2A4C6F4AE221ADE1,A641418801C63BC6,AA577C370D0D5C00,71309470736B2F32,420AF455EFC83A1C,000026555DC09CCF,E21D173073FA79BD,6328EF1ECB9B681C,140DEE2193621172,03BADC223F747B4A,59202AFD8D87CC8A,C26165ADC83A327F,018C6A1B3AF41B2B,F36D02A5C4E6A491,DFFC61700F590882,4A4B7D86A3896677,0D05011695525AB3,0000329F01C2F596,2C3814E4D8906B9C,D113138240855395,CC4FEB87BE21AD31,1E8BF4FD9312A452,4A5A6CABA9FAE3AB,EE38F52365FB09FF,C7AB38188642FFC7,D8463D3A9C6AF751,C4508FDED5BA4C58,AEFC2C0C1E9757B5,2F22D5BCE3D2895B,000017E2F84E6853,FF04A21E1E9291AE,0EB63A3B5BE28856,1844DB3829507D96,2422C50872F71BB6,026DA6A73D1F66EF,3A0EC4EEFEB63FAF,ECAF0B472E18F13C,364EA8C151D685E9,8838FE273290CA38,ADE5D6455F7BD338,62F2FEE6C0F7F83C,0000439C728F79FF,6FDFBAA3591872AF,DD860E1FED953C9B,4D8527948E81B3C0,30A79B3C072AEB46,776B5A8707CC1E37,6DFD2BE374C61EE4,2717DF3E28DBC162,6FC3C5B9E07442E0,683085F0BBD8FB21,27471185731E4E22,1824C6DFE3ECEE10,000002C4478CBB5D,5BA394F5A58F0755,FAE1D3A3A9A56A79,C7F9DCFBA5708D56,8DFC508A5F9F97E7,60B399CFAA4E844E,57FCDD45FE3BBAA2,57B34838EBA8DA5C,5B6B1A98E31F0D3D,1EB1C74C64E96D11,93BDF1450F6E42E9,27B5786355987EE3,00002E570ED66BEB,EC82FBD8F8FB9D93,358E85C15294D6A4,91619294AFD542BD,2BCAC3EFC2F83C81,45D909610F0868D6,422C9E8579B5D1FE,48DB8BF745D723EC,0C833B0C8264069A,688BFD9B4DDCFEB5,687F4675A2285119,026F5CAB865F1FD1,00005B3C4EAAFD98,0488F06B9B9975C8,0A18EABD96504F50,9D7DD9799C1AAC39,03299BB495A59218,750873D842E1A7D6,ECD72469B8E1A640,B491119286F46FE1,29C95289699A61C2,CE54CBBEFC93D598,8AC997C2677F069E,CB7D7D4F3256BDED,00000C0C3B47390D,7F55C9D9695695B6,991962683ECED16A,36018C3122073A0B,E0996D71917A358A,CDA418F4A0D8D501,634A19ED93C21EFB,9BF92DD2CADA0BDC,B4B761F01C508D0F,B63445A47178E23B,00488ECB392F29E5,141AFF39C44C17E3,0000682BAA616571,66FB6D66CAC1ED26,FA28930283884D1E,8630DAD963F75919,FC6B067ADB5EF2B7,3F568134FC37D795,C8F12BF9892BEF6B,60A51F044C696F47,2F6D84F702F8E910,E5AC758503265B5F,962711D981E6615B,491BE7013CE4DEF0,000005DBD8CA78C5,A99D8F4551608300,62C72F96E1AA03D9,A3F7AF730E3BB36A,78F723621BE3C1A8,525520E748B3879B,04C9715CFFB9CDCE,A6CBBEB13997289C,96A961FE1DEC6E13,F9D0BBDF779041F2,0182FB10BE5201BD,6592E96486D74664,00003AB9E1F1891E,39111DE917CACA0D,B2F2610204057996,27B449EF40098E1D,0357528DF749D44A,61F7C0BEC6108C77,786E8879B72713CD,071AF2C367E4A48A,80D5E02C28234889,CD49C0AB30FAAC33,267ADEE2E12E3FBD,A6D159E3F78392B6,00002D4177E8D093,5CE2933C52EE6855,BF0C74D95329949C,3F4DDCC1441FEB6B,0A8FB3EADDDDAD2B,BE26F7EEBAEEACF9,2C88BA59C4D27102,8F6F47591CBD5C61,470019BA1BEFF3C5,2AAE055B9CFB80B8,60B90A20F7952DBF,8A2093FFA01ABC83,00001A11F8B0DD7D,E904DA2989EF0DE4,6C9DBC5E4918B872,EC4FB5E1D3145A4D,6280732D0F0377ED,3C8FB322727903B5,2FA109FDD42CCC9B,DB6294E07CE2C967,61F905D53A6348E4,55E34862E546DE6E,401E04283867BA04,BF1E881B916DA152,00004F3C9DA4AF56,8F2BFFF5685EB04A,8F7CA1E529A0C93F,04DB7EEC54DBD252,18683CA6FA931E82,F0F9C9F21B79523B,1F0FE7A03F9113D0,947B09E7798CE0E5,0D4C20E4718B7BB6,841D5D6E52D8C416,0231625975A6F5BB,1EF7F7059F87FC21,000013BC50E29C9F,322C188C053BD436,85C2A437C3B2C56B,8B34C21EE1DC798F,53FAFE39E7EF8C50,4E29513A5F5DF387,04E77A0E4430C76B,5169CDFBB0B8EC5E,622DD52CB3E6DB4F,B98CA1BF9AB6284F,8476D477A5D651B5,41389CB73FC8BCF2,00001EDC9C5BEEEC,680C64CB5B3747DC,C825D8AA7E711984,4CF8E7E4B282D0DF,DA9347F6FF86DB19,6E3087545F63D686,ACA364A1692C62F8,3DBD443A2954E667,4E5D21EAC3A05CCC,5EBFAED5B222A341,E83A0DFFCD15D44D,6E3AD1A6D47C5BC9,00000ABA9EDD7637,C8E6378958272AC7,F4C4903D8A4DA29C,15EC96DA6423E82B,4E727CF9ECC8FE42,42438A4E3280E8BB,ED12CA5D1E1F8428,6DD6DBB91B7D5770,992028798B76C6A8,BD894D6611403323,D96EE41C99F61897,176E172B50E7D081,00006875D3391F20,B71565E8EACA2DC2,649F0D02E614DB5A,91C37CA67428B028,53BBB8FDC29B3ED8,578CC46D60C076E7,CCFB6ECEBB875A7F,015C9C4BB2564A40,A3C4BAC208D327F8,77AB61DEDE78662F,5823082C3FA0BA61,5172B55EE5395668,0000167443497745,1330463E3D8BC9CC,04E2F2F5DEF75939,962721A26E197FC4,87363047F6A6E8FE,37F9DB0F440D033F,0E08298F429AAF47,B35C490A105EF8F6,4C0651B1085B4541,8C44497C556D8B39,37F2179E690D2EA7,16CBA8B48A133583,000064E2E3C4E5A2,5B51446058FD336B,855CE28E3CBF6CCA,BE92894782E61A3C,515D2661D5B95227,ED2C66A6E2873BCF,0BA3ACDC90741625,59F54EB73D48CD44,4B85B8F55919B3D7,E12CF378110164B6,B3CFA67FFECCE03A,C95458D6019F03BA,000022A2CA123CC6,038E4CE7198406A9,C76810C0196D481B,BFD57EF3FBC19FC2,0B9559876CA85005,7D9AA99C2A5C3B96,C6F76412185A077A,870FA5EC14B7DEC3,26C11C1EDF60A780,6822384FA8DE2BC4,A48527D175542BE3,1A2C5C014D4EE45E,00006E895DAB2EEA,C7B538FA931A02B1,DE133AB98B9C45C7,673DA138FAB47560,8995222F6FDF6FE7,48B7E0B8671FBA63,E5F27ED597A39558,7335E4FA8460F570,ACD1ECFCA40108F5,5F8EEDEAF702A865,615582756C2EB566,6CF576A8972740D7,000055DC39328668,C3EE45FFDDA0A37A,5364EBC61A4D758F,091306A1177BFDB4,D973DDCAC24C51B1,8A3AC96AEF228C99,69E83BC8ED6EA814,E1D86033A7C6026B,20FA1AE5601ED339,E1023E55D43EBCE2,7882114A1DA7C12E,4010677A16656472,0000010DA53BF663,D5094A4042B4C582,E1F3CBABE0D7F193,2A2F840CC1E4DF6C,4EBFDFEAA63A52DD,DD23485CA2C773B0,ACEC760CCEB0A2C3,32C04120074934BF,859E31BB817A3AB6,B294213C4367687F,347F5B8086EEF4D3,821AF04F53D5A159,000032B1F1B506BE,C2CB6BE808FD773F,1FDA058905597FEC,7256B920FC3A7433,9F8D475D8145589C,F29BDAF3FFC37B8D,07E6F850C1AD486A,788A00446FFD6E9A,9DAAFD78484479C9,A1698F2A422B3144,FE3766F025F3492F,90FB42F49777087C,000068FD37799253,41D78B9BDDC66003,48C155A5560B2705,3B2EF4624A9B92B1,E590343933DA7D30,FA239740EA004C3D,56B5AB2FF58A3C5F,CA43DB047C02B491,03D3D725350F864E,13DF1A79E0D41911,CE51FBB7CDF0E093,ACA4DFEF0211038A,00006F21172E293A,EC81E4D71BF70040,6255A1120E4A80A1,C0DBF84EEE3F5984,C5BA6D3CA8AF0C98,406DE0DDA47E6729,FBA342FA96E292CB,B2A06B39D0B55FC0,0ABA19E1BCCA085D,AFB5F3C735C5BEAE,12F38828357BF2D4,D71E7F1F8C77BA9E,0000694072AC3D35,E541C2032F1ED1EA,239CD206B7FA0C26,161102BE1096C88A,2512C5636A7BB3C7,A92B1E77FCEDD2D3,6DBB4DC72BEBCCAD,1525D18B80F19D28,83353A3D6F6FC02E,949D056EFF868B99,C3C3E3CFC51EB882,F14619EE5CF7A1F2,000061E78FAC5740,EDFD678028561963,96C9F6DD6CD5AAC6,9056124E26FC992F,9E3DB61F6C9589A9,CA519CC418ADCE14,3CFB56A49FF2C23D,4FD7EC6269D3C157,BB9F26CA8872C029,046DC319F1DAD383,1DA104CED84D360C,0774E3960ED94F00,00006293FD69F0BF,481394D2498E8FCB,57BD93D3119EDEB2,0275B851F5061E47,5674F96F96D5C544,D50BE9C9E93E0B18,E3F7CCFAEA640544,55335C4FB0578521,A824843C82E88AC3,ADAA41408053CC86,534C4C11B2CE3A10,763D43DF05F3D73A,00000F9A47BA975A,955B08AFE4F5E53E,55B7AAE4B300B01A,5433B71AAE3A56E3,4D9D5C22207435AE,4521356AF68A58C5,231A6B74FE606CE8,E9C17998C87983B8,8F91668A4824142E,1DCDA2D08355211D,831498B534BD8D80,57D162952A2F5E61,00003DDF55113F3F,EE235673AA174856,8740DE0BA9B184D4,ED73CC229B44FAAB,97F0A255535865D8,2BA72F15B08E9DB8,3E2B240823177D52,192C8F2C02EA4F0A,11238CB0CD6E7CDF,A721B3DBF7ADCB4D,7C367507003BDB05,080A9BABEAC289D2,0000029976C90B96,98828112E6A71EC4,7C0B0E79FFCF0739,98FA466D84F5DA00,F1B8AD3D7C90931E,FC3F8054096720A8,A6AA6B507F11C89C,133519C3C9BB79F7,128721CED851A3E8,29F4198CC3C0F0EE,91913583640C8752,5D3EFE90AD90F376,000055BDB3A40B91,97940DE735650222,019643932C46708E,CBC4B60A830495AC,E2539815171ECEC3,C1A4596C41061DE4,3745708DB9A863F8,DD7D5386043EF389,F6C47F9670C40535,330D4FF12DBAC83E,B181B29F0D5AF9FA,2EE2F1150F0A1002,0000004CCC051CDD,287FFFB813FB2928,4382A57CBAA10FF9,03DB4E6FBDDF4F27,04D545C9777B396B,B76552DC44A6AF67,955ABF0E1DADC6B8,D2FB52281073CEF2,1DFA667A3DD3EA5F,C9AE662CF894F7CB,92927C543736B5F9,B59C50890F698E1C,0000433B7BC082F0,C0F876C13A177FF8,CE047DB9AC5612D7,2DC89C387F297ED9,5737DBBFA3AF103F,CE05CF98B4C22A54,97664FC56C980FD6,76603C7E8CCACFFA,0EDA6BCBFCAF1CDD,C0DA2DC2B2A0DE8D,23B2952A0C6FE4AD,DA5BAA348D79F6F3,000065B5D5EAF03B,1D3ED498EE57593C,9B354AD32E78F858,386A7DD0AF185EA7,5956674FE04081AD,82CECF06550D5C72,1FC91805CDDC3EF8,4DE36BBCD1776D7B,E503C05FA4C08A00,C855F1122C3E6148,941014CBB0A3093B,B038071A675A076C,0000413E80A299B0,A762785F71C9EAE2,5D0A3696374AE20E,3496C4AA7730D9DB,E8B33E0DB040CF96,A45139917E8C6018,A680B9067B32EF21,FABC65B2425C7786,4300C1D154C3239F,ABBF264E3EFBBEFA,326D6007EEB0764D,BBB490E1A75A6FF4,00000C99CAE0AFA8,DFAC94DA33E0B15B,DAD5347F39655610,3CFD462FE8E3AC0C,CCE270E8E7FFFDD7,0BC404584A2CC134,1462B8171F5FE1DA,DC3A34558B71A748,D35E8B187FA76392,4F44C13A9CE087EC,C156EFFF60588245,058D0633BAC895F9,00005A30B14CAA93,42EFD6CAB80F9FCF,60D73F77CCD37F3B,65B8768342F7C568,217F54D3CB39E81B,601694FE457C9EC0,C6E0B023D7DAEF51,F9D6E00DD6089ADE,9B861D4C0FDF99ED,5B630C6F2681B305,BBB367C3D11F6A65,606C6161D9C67E61,00006B75515E1DBB,00E05153C1E128E4,B0AD90F1A098A3D6,B963390C79BAA20D,46055703D4FD250A,E4EBF890DB5562ED,B1AF43960D68108F,F2EEC087D8EF91CC,BB17C5BF219CE210,6D174F8C27AB6261,28D91F66D1E3F064,1F8C583D5B4E7AB1,000068CDD7716725,5CF97F80AEBD68C8,AFAA4C053A8A9FA5,20326DB0D0B966C8,771F6BF924524E3A,7AC501587EA82834,A36B2FCA18633077,9477063FF0B57F1B,5D5029845DE859DC,ADBF596FE9659535,C36D784338A4422E,3FB541797FA7D0C2,000017E2FA0A530C,BD34674CAB472766,3A5E1EB7924D70CB,DB20A0C406BA6357,F8036C46A5EF7119,8E9D61A4C90104EE,9F1D56B554E5006A,63A76908517D78C4,881725B0C7B2E2E0,D3B50BB87AA84BF9,9DB198F0CA7B73E5,28000D4FED3D1DD3,00002E300AF8102C,871A22A9DBAA9086,9959011D381E2BA3,19ACB3489CFA4895,B4C0FDA296542B22,0BBDCDAD66D4EACE,6E7642F8ADE5AAB0,806255F47B450B45,E3E5D6B91F19E4D6,E521E50F34CCC2C0,CD2A732EC1F61540,D8C0DEF182D73775,00001D4A1D8E1A6A,0C02BF82948DB0AA,A71C10A15B04D5CD,2096926DA0681B67,50264AFB2553BCC1,5D8929537580BEEF,8AD7A8912E9A2764,C7864D4102093754,8540CA1D9840B032,5D2131D9FFA9247E,AA07A3B457FDE990,1974AAE10F959324,00005A10F69BF61F,50895C6C04760EC1,7BBFC9C43B315AE2,AA15B31B142F9B2C,19DC67B7B72B7471,6C2398091D2C8C28,9927044D29512C22,CC9CED654967ED12,90BE3930FFCD7C95,BD0ACD016E638093,F55AFB34E0DAE9BF,EAD663F422C2D190,00001EB113F244AD,E53F84793E89E3F4,71AE0449FD5FAF46,523FF73B17F68E8B,FAEAC48271ED41F1,9F6973A1589B25D3,BADF9432C27C4D0B,0E037DC67AC90481,66CC5D56E4F07205,66FD564ADC387CD1,D00EF2CB62DF2652,6EC5C2AF76A44015,00000FD7F017A40F,35997323020C3F91,5A074C9C39DF943E,AF906C9F9EB9B27A,762E914CD6EEB576,54B87FEA39E595F3,DFEBF3688ECF2AF4,D54DBCD9DA696B96,DB33D2F5608C72D5,25C4CE9988FB568C,99FC9B1249B3C9B0,07B4B1A6F20F061C,00003C17EE05D2EB,22494185F28409F7,4A5E7763E946391C,07DE3C552BCDDA24,99E732F469A23049,7E05C29985042243,1FF4494CECB070DD,DAECE808D9A45CDE,9D860413AB983893,826B747F5F4357E5,CCBD462570D0F1BC,A5BC59F08928621E,00002B258AB5C9F7,8C571B0BE3F1FB52,F256B555DD6DC680,24855FFF169BA305,E34355876F593AF8,44DAC999DD712B10,16A6BBB5023289DF,1B430642550A89BF,D6EF91B6F3EBC24F,EA2E811D9E789B97,059B3F7C69B7F2AC,766F2D7B47A93EEB,00006F072D95F112,73F1DD3EF80984FB,B27384A35DB728B3,A971CF8616BE188F,45A65A8C83D7CDF0,78745C1B9B2FF453,371D7DE18A6A5A06,98393DEDA31BBA3C,42F6762E9C74F4B5,D3B7AD5FE27BE49D,B51DA06B82DE900C,764D9E2BA473294C,000032829F97A844,4A405EBE710B370F,7977954631B6AA79,300FE8B4F98667BE,3E1038987941E1E5,0841D1F51B35911A,0BCC285E4311B138,8F273CB62B7467D7,E9CE520311531C67,2BD44BE6551E99DA,44FC827A4EA4FD9C,9F3B3F5DB08C034E,000065BE72E59521,FC7E9205807F0C36,2F544B97DA921A93,841093A462214ECB,43195F795D9779FA,502C62A36282BC4A,AFDFF522547011B8,75519D9C45D724F6,B17419FFABD417BC,D271002005B4295C,50A92D4FA34B7BE9,CF22366B583BC5D0,0000548ECEE2B9B6,F8F4F7BCC1B237B5,832460CA9B157361,D769998D60CF37EF,00995782001CC6AA,236568D8E693D9B8,167A2D6F168CA092,A8A488ED7A54F8C7,9393D744933F534D,24C9D9F788AB27AA,D2E9225A1D011861,3FC6445BF2134E79,00000349002F96AC,1F3F6E8632A2142D,C9B28EC68E54F7FC,3E408073F2111450,84500D3E47844078,9C58D47F7A132DF9,8586E10C24924721,C9A5628AEEAE2419,1D11F1B15F3DCADB,0A0D0D31E0F8B1C6,B5BA4A36391B3885,25C9D39C26932088,000012B06A84EBD5,83EEB68D1395CA47,DDD6B2D8415021A8,910DB9F122EE1BC6,988725B44C0E60FF,1F9389C78406E6AE,1CB2B8AD97DB840B,97F53D31473A5638,D67C764FE9F0BA37,8364CCCF9CEB890D,03A5A719C98798EE,C22E95D3F59EAC48,000035764882CEFF,A8E2DF7FF3D21FFB,7B6A5B913D4696CF,2B7274FF3D156AA5,DAB9679EB0663B9A,5AEF9CB3EF87FB7C,B7E0CFB6E2377223,91652FBDB05955FA,258BB312EC4135EB,B36ED2369F5CEB14,CB4D962AE697D4AD,C167FD9228C1FCC2,00006E0C2697FDEB,E6E4A34CFE4407E8,250DB1883B629672,E9CA0508CD7F854A,2B66FEAA70C5D17E,A72BC1217B981E54,214C03838A7632C7,EC5B33333CE6B20E,B3B3276EA1C24D55,618007117BAAE4AB,E73E754E07ED31BB,CD72421877F23793,00001019D234B571,FC1FDCBBE2540FE8,DCE0EDBBB88161B3,337606B29456E45F,BC66186590B205BE,C152A6EED5C70293,ABEF840A7C61D36D,18C2DABDB0D3B72A,74B29D32D44E9CD4,C644AB2F788D08AE,AA957B9C93DFA126,1EAE8EB6FE34CBF2,00005DAFF81A057F,7A019C4AA2AB6513,35F04390ADA40EF9,31F4EF9CAF8D06FE,8583A21313F47E1C,7A1ED4182502FC9A,BC7C7699C8318F6D,EC6C1DC555324062,3A4F4378E04D7770,A5FBBED484355F86,03334E50C3281092,33F804DB98FA5530,000068E83184C727,7F5F112280B4FB43,69480B83583C10B8,84100A326888BBFE,70D4D41CD3C9DF55,92618DAA84670BEA,EB2B0BC439D80136,88B60FE77D7CC732,490304BE2A264A8D,2B7506A83684F6E2,170193CF16EFA27A,E815896A38383C60,0000230F99A69D7B,6D239CB581925CBD,9481F2A4C4610338,621D6F384466625C,23C5D3C731A433A2,A2DB5E8B7B245197,947932B532227945,0C93EF9377AB3AFC,F28F2F5771DA8FD3,054C34E301A3B976,F098E7E0B3574F1E,B4563EEEEAFB8BA6,00005C5B0DAF64DF,0E22CE6865C53471,E197CC8442B8F050,8EE908EAC9E84561,1A3795A4C39E0068,CB19ECAFC91F10CB,DA32A800BB5149F8,1EBC243CC076E375,AA53DF65BB909DC4,9C8AE38063EF4C7B,AFEE2A2F5DDA01D5,88E75D146BC294EC,00005C7D604B4AFA,C4E27431F7178772,D7749B5BA06AAC58,60C22E465BCABABA,313A5073787DCCAB,99885090D71BEA7C,E35CB174790E5710,55846F78F9E7C80C,13EE6D4764051FC4,1420F70A105A1F10,42F8628B83D8F74D,5B0F2A992BBE6073,000040407A1A426D,A1676F063131A7CF,84FDB7E67D63996F,EDD0EE1CC07251B0,B9A919F323E74662,373029332F9E098F,815A90FA60D256FA,CCF6D72DB7616B6E,2321732BED56CB69,D384D9D99599A326,F25508EF3A77BE4C,71AF004B7682EEF6,00004C015480D966,99EE107E149FF75D,D402DCF374D3C73B,D447D6F98BB26F4D,1C455F35712A653B,E4ADB22741E51D6D,6719721F698F652E,B9814CD4F8308BEF,2E4A5EBFD3EEE4EC,88FC586FD32DD5E2,59770CC5C9237EEE,AFD3D990B2CE1D3B,00001EF4C86B99EF,44F3710888523C64,8876CA0B61D5078A,02E49BA8869DC1D4,E4CF966CDF605937,3EDC04765F819FCD,C67EC9D1D7D5DB76,0FBA75DAD11F432B,131F211243548118,DE5C6BFC934C172B,D5432F75626E255B,58B4516043F6ABD1,0000666506F2CAAC,4137610085FAA455,8B9DB74254EF5016,A4DEB4613254C78D,5D32DF4A28E95F4C,78107EED502687C3,904FF129F76A0C42,DDB8C414FFDD7AB0,C07C4B8EC618528C,976F20134585E0B6,D3D84C86A5C58C73,500BD8A16D7B45E2,000007BF6838477A,20D3D8B689F849A0,CDB3E3D537E55282,35BB62A14D1C1AC7,08646E8AD2FC18E7,772A531C973CE32A,46C143DBDFA78907,5EE8A14F3D570925,FC8DFF8DAB212AF1,098A349C13EF3003,4AC5C4F05607A080,D31615EDFA804E62,00005B044E2DA871,006F5A556AE3E4FC,07971FCB6E91B544,3E5AC9E29BFA882C,449BF9B907B70504,3113899BDB864E80,B4D8E527DD32FC8A,639DFEEEB12F8EC0,86D210EA9DB4759D,7E55305C3A8797DE,F5F520AD215C4716,67816EB63F2944C8,00000520D89C0CBA,DE2E895A865A36D4,F784CC9C96125D59,CB40994C64E264DF,69A58760E7F81DFC,FC43A4DF1103BCA3,ADFE6D1C12227E65,A7D881A6E8D25D35,3062D6DD8806B657,82E2802744D47DA8,7F37A5F09971A740,9E8EB138E6134962,00004E7F9CC10918,87055A1C8132DD44,366B2694A71D592D,EE98874FB065FEB8,AB0F16E6B52352E7,A876B3EDBF4A510E,FD7D43B3729087A1,15815C9F92165BB9,E9506F78842D5F8F,9991484D9334AEE1,82DFDF8C9535DA40,C5701F725A8FC01F,0000297DB9CE7904,E648A858D8337814,37F3E5501D62A853,0C0D2D11B766B8CC,02B6CB6458A15DA5,DB4F0BA38FC0C65E,8E55AE9992A52A74,1671EC65238B27B3,35F9FB85FE3A2288,B359F307AF13FA57,A8E3DCAA3AF77074,460E39B250A71AF9,00001B555BF8AA0F,870B7E221EDF1572,3D5317124E248EF2,4A6FE00BEB4DDA39,B985A13C665F25D6,6E7A76459F2ECF76,CE1B9E3CF4015C1F,70D4D996398523B1,FB8A8FF3D1D95CC1,FAD6D12FBBDFC562,76816A07B3B5651C,55DB399A4539049A,000006C7FEF5D4FD,653E74A6D05F089F,D46D5C9CA353C74E,5037538E7258D685,B2D64E1C42FA6BC3,F9D1CE14B7E56D93,79AEAB2D81668E84,06B7290BCCB056BB,7279FD6A373856C1,9993BF499E8B98C6,EA99205C245FB437,2995AA12F1EE0607,0000612928BFC0DA,4FD9CEB4B56E29D1,A51574E1945FF101,5D93786DE4D0E7D8,61565C68B249CEAF,1F8142AF5073F87E,76A12B7401F233EF,39C6B061499411E1,8E36F48D97263E04,1E5CD4A9F6975EA5,C1E3504CCBC6F533,4E844D82AD89908D,00001CC800AADADE,722D2BFE3340C483,6B732EA53B59C3FB,7346A10232C9FA76,AF32D55ECA3394FF,EB845D7F8CAB4DF2,97D4BC879F8FE695,DE6BBC654936FBB9,997760DA149D63A0,7049C5D814CB54B9,0F0005D10F5B6C0D,1749548D29F86957,00005702CC54D3F4,B8686836AF364E19,D73B036C0F0989CD,889E13F7ECD6FDDE,5F993C16B118CEAA,32649DAA60285899,56D83C718F05A060,90F1839D8199D54D,60CB0351D3911375,135AB31D505268CD,6B53FAA6D6FC9934,904384B58E3FD241,0000344E705A29EE,2FDDECAE8308C506,14E6AB3D6C6FEE39,D232C592ED0DE918,AB57B202846A0E77,C17D131999370791,76A6EB078650A73E,30E7E65ED8361E61,1F277439A68B83C8,328565CAF70046B7,C8AC6BB2ACBCAD2E,8F44B295B9D68AE1,00004E859E097B8D,CE6C44462456369C,035B10015AB73BA2,36B0586EF970E066,E147685CB2DB5BC3,359E56A605D29E4C,9371476AE445F1E5,611F2EFB526D33E1,9005B05BD632DACB,DA862E612B11CAD1,47BF5ECF7BEB2271,2C828427998538C4,0000529D058B5881,FA7350D2004B4E9F,A1B5E70B5B2DA027,DC3387D7D3A64744,2A0BF2CA8FFC7F35,441715BB2C158ABF,3AE80C7960630C89,A7B7CC689B1ED965,45D43D7D36B16AEF,7577F5C54135AE08,837C962A02E1A236,90D977D9B17AD65B,000011F0D6486C2E,D1147B125D3CD108,ED2C70AB81BEAA2B,3393CB31810F3964,0C91C9C3AA01D609,2EDED050ED1E81A8,67C4BDD7640E2A2E,6633CC83A93EC4D4,FE3E623D302E5071,316E3A945313F0C7,A7B9D567921C8F9B,39A77011BB4D3F28,00006BC7052D65BB,86976F2E2FEB4FE7,4ECC5A39118B1203,66E9B6AA252F0F33,B67D8BAC66C2A8EC,570E79F1DCCE84DB,1B4B742FE96725D4,306438939FE38CC4,22E29B1D876E9CDD,01351BFA57242790,A50621640C925923,28D46FAF63294A36,00004CAD3E322933,C187F65B7477F64F,4049D707F402A2CE,2F6EA8398D4E657D,EDA3F1FFCF281E2A,CB48958CEA8B5A7A,3199E902C0C53B07,312ED4771A4A1A51,28C0D2AC9BC23085,6B3D7BC5BD55EF46,84A3294B75EE4B57,F62E754CE6684A92,00001E25663885CD,627A8E6ADD4D3F80,929664AE617ACC27,6B56547B0FE8A11F,D30DCCE9D578E671,9D129FB9D64850ED,2995B6D75BA611AB,19743712EFDBC907,C786223FADF2C77B,8AE90A74620E84C1,6F76D5588FC7A52E,20A03675C1426EC1,00004FC659236CCD,1F88B2DEF253904B,A6C31FCDB80A8CE2,521693E8629C27BF,0D640986CA1684E0,3250AFA4971BB2EA,549433C4D8C4FC58,6B1B7BDE050E77E4,18A8A73D97C7B9B1,CAA66A5CDA8A2304,3FE9F534376A6A8E,166403DB1C227070,0000551A0EA5856E,10E966844D0393A6,96D1082667670C36,CEB7CF91ADF49B9F,474B9BC9AD11AF50,F12FACD95E2C53CC,8098FC4F95BCF115,9E4ADB726E19DA42,5357349E4B57EDBC,952A214997A4C3C6,D1B8510BF47AF6A4,075F9018D2C482C4,000009940E0778E8,B9849637EF066580,C79A3FB17E9F2133,64C004F51E9C2FE4,CA44F08FA9DB4EE7,FAF0B4EB78D1D16F,D7CBE341F00854AB,0F17D9233C7ABC3F,BCC9F1B469AFBE47,523A9AE90E60F182,E407E7201879159E,C147177E7ED72019,0000675298054CCF,BFA2006BCB3F45EC,F4C9BE22696B36C2,D894B060029D862E,1C76149DC2063B9C,9DC75809F11E8278,B9DC772D2166FA61,DDE3B595D6BF6943,1A5464F31763FDDC,9F9440FECAC992F6,0D5BB9ADD9F9711D,DDA117D6E40BF0A2,00005217D685F0A5,367EF8082180B4E6,C9047F8928728042,3FA1B4CDAE0ABE44,C235F0875A45D8B0,21359226E8AD8872,1739E5AF7339DD0A,FDC2B88E18757CB1,CE9C13FF6DDED1BE,319F77884B0641A9,E682F90CB560CC7F,C20CDED246E9F630,00004589A35BA472,618EB7B67FDE6F51,33028CA49B50F58D,E858ED5510A5B5C1,5C1A2D9D79620CC2,80917999452824A1,BFCFD0C0D46A3743,2018363457FBA8EE,51C58F335062E8EF,12C68C1C36D8A7CC,2080DBB278D33819,6D9018222B69DCFE,00005BF7327FAB0C,183D507883C26C9D,22B2CF27F807DFEA,CAD22D24D0CA9723,04D6A18C36A205C9,87EA2207382766EF,E119FCC4FEE89F7B,0FA0FE46F5C88CA1,1EB786CBED330A54,B9570AB3847DC729,D46D1A190D68077D,3E4246CBCA1C5A50,00006097E6D8C3CF,16DBC7D20F59C791,D41632D3BE759D97,37D60A0F4150C149,D5CEA8DAA7D96DC6,BD9AF786164CDD82,1439DBB1167B5095,0C40F23C3887710E,1EE2F72BB26E3314,B172BC480FF07294,DBE3E3071FDEDCED,1F4E2293E71E5567,0000601DCB28C076,A1AA8CBAA6BB5B9B,DE67E1C34B24ADAF,4004EAD3D7D40669,B2AB48719B9D3996,EE478C3D74E74DB2,81E1ABE45D24422A,57A8018396CCA6F5,4AB920885AF048C7,708A1A7A6EF0B729,36E8EFC3E1F8BCB5,EF4BE895A61E97BA,0000587752DF88A3,889A7F95AE27F6D9,B44554037D885BE9,1506B1FBCFCF8A64,4FC5D8210291525B,64670F4D851F83AF,729612E3A5370273,55521BEC3CE5BBAD,798C3CF566BB68AD,038C94F355EA1DDF,14D01C58EA3F724B,564F6BCE9B13F96C,00001F60BC3D7A3B,9B71432F4919681E,72DA7088CCA736E9,CAE3A3CB8582A016,6AD51CC948630F93,9175B733516108FA,0B9CF502E35FC45E,16FE547B5D287ED0,CA1CB302596FECDA,AA22E77007E12097,841180199D6ABEDE,AFA33ACB7B949E28,000021E9545DC5BE,E485ABA6049689F3,F6C323D4A8C9FFE6,7654433D6FA84261,4C6E5A45C4A6A043,816498A8AFE1F192,64FF1C8E24B07E04,042D9C27CCF0840E,5EA9980E1DC8366D,A4D1C344C2A8111C,02694F0074D6BB35,499A6129BFE549A2,00003B18E67F3B61,E45C88A438795083,F4B48355DA654A3E,CCF4667BE98E7EB7,B0AA6079885ACFD4,36D85BE04DDEB451,D1B9AA2DA148D7E0,992F46174CF33B1A,36D126335A029493,E613A361461CEC5F,1219B2A4194D6478,F71A9E4B1929B20F,0000437F8F97F07E,826D7903D12678EC,9392E29878746204,D0B94885DAB04244,5A7689812EEB2DCE,2D2797E1E75A1E92,2300154435CBEA31,DA362ACC2E35CE30,F1B1D08ABB84CE9D,8B76A04D7962F93D,4B3E141C619ACF03,F83B7846839D99BA,000030A758A69025,C6FBC4636E579369,C0D12DF3A2BB59AC,6436DA1A3BD68B84,2182D355A8F0185D,2474FF95276206EB,0B1E1CDB960724D9,BFEF5937DF551119,29A1BF06956386A9,2BD3409D4A3AA5A5,4779BFF73CF2AC28,DFE118F73C0D0596,0000476E4B957A9D,F565970759DC0E70,466D40FCA4427052,A5EE0E71D0EA0524,9F477D349F630D8A,75CBC3A7EAE07755,E87BAD07CAD85307,284B951AE2B77094,DD1ADD90C023F6F6,219B385E4A6B7047,E71DBE0BB3DF7216,482F84ABD0AB3034,000044D8F7554D92,6E4844B179378119,A3A9D9834B2D6F4F,9E21043BF99F492E,FF7EBA32D48EA22A,EC1366AD44D3076A,91AF396A8A6691F8,F4C126C9E9593A01,E90487A7B4429B5D,1D821F6EBD8DB16B,2D0B0BB7218BE336,0985E9CFFA0E2E31,000067D57D782963,62AD5C2BFB60F8C8,1D9953129F14125E,A3C2712CCC8B8166,80C5AA44DD304037,30412192B87A6616,B8BDD7C64A98D376,58EBB549735BFFDF,BA160F47B7588A3E,40765E303CF18536,FA651B09F9EFE51E,0154ABB83B563F0D,00003148321F0ED7,E9A31B1838D4549A,C60A792BB422DFA7,EADF7E59324F24F9,F5EF1A39F12F22A7,135467FCA584959B,0E6235B8FAA7BBAB,5ECDE2050D8080BE,E127E470F9C37E6B,F2ADC88FF4E1B5EC,C5CB551670E175E9,13E205B801C1AE20,000048ACE411AFE0,E1FDDA666A1AD566,094EB2ADD5135D1A,37D7A0DEC4955BC8,015326BD8D94B8E0,EE545D3CBB4FEB33,996DE2CB1F0DDA93,CD75AAE58D6C4B0A,3E811D2228503A59,5030BCB530FFF482,5455DE3811C8F9C3,2A39313835187919,00002FA4C782C411,C76A9863F38BB4F5,E7287575AD6283BB,8B6CA3A1E82F2EFC,1DFB9D65720B6CDD,986AC04972BE4CCA,74C369A1A8CF095C,3FB10EE29FC8EDB2,7591918DB6EAA7B1,4F9BD7CF71B80CF3,F7FC35BE377B76B0,F3C4AEB5D4EAAA6C,000049453F3E1EF5,388D8738850208E2,E9D245C96D57B65E,E53231A5A0557DD9,72780B7EDD1BA95F,1B64ADD717B53975,257F97C883DBA5FE,CF506F5D3B2469F1,07ADBEA416A82CF1,3F59B81DB8259A43,3CE108AB063BD530,577E60E96524D221,000069CAF3E115FB,80024843786BC45C,24914B732F0AA94E,24CB9652014DC6D7,FEBE0A18A98E3FAE,B097D8D2DE7E3A7E,155883E6F900681B,095B53681F0E1AB0,BE2173804DC5F290,1BE70DFBD4AAEF4D,9E1210A45293AD68,C417CBE9EA6BA0B1,00005E8F2B834E9D,FC6705E5A7DD41D3,977C5CBA53285195,ACDEB86620E41CF3,701520FFF42E7321,ACE96BAC8C70D61A,4292F2E4571B53D5,4D6A67C313E2F7E9,CD27A573799E3C98,19ABDF5A79323B48,A448A097BCE77C2E,3897E3966F350B9C,000048E74DE5CD74,5CCF93D1644DC7CB,1AC378D2054DAF18,E132D22959638C0D,40BAC30FFD520309,54D8C1B4958ECB31,3CC6CEADBF2D150F,8E498515605F47D0,A309E2EAA6CA2D5E,25E0F0403AD9EBFD,6B244EABEF6997A6,59C096611B669ABC,00000CE54C56F345,57335B8BAECD6682,7EF769D25D05CEAA,98A96135DE579E96,571A91B9C207D645,02CAB163C5004C6E,2DC6FBFD3D46B9B8,4A2CD4C4B40B880D,6D2E56277BA4A478,D173AA3D7E76E332,DE30F97AA1FD8581,A045260AF2518B4C,000036654311DFF5,F7A56F6E6C84DBE9,5381B059D6798409,E1B55918A7CCD242,862A0658309C0A6A,FD8E4A47EEE8C621,6F89FB83A25E7647,B98DCDA08ECE3100,1A17D5973D208825,E65CED7322BD1D72,E8F29CE0AEAFD9AE,891838BCDF64839E,00002D24C4944D46,A0618AEE7EE17CAB,3F91E301C524F9D3,8C34F885B11D1A81,C2FCC7F714694ADA,70474BF7E36647C8,2B4D833F8715E7D0,012720B131AA80D3,889849DF3A337F72,FD50B313921DA52E,C4033AF162308BFB,0999140ADEDD09AB,00004236BC1CE727,F469D31B0E2C4BC7,A5911488545945DF,A52C30A3E556FEFF,2F968A838C735383,973D27D9E9B8D7AB,3C810A46CC6A4DEE,39508EF6E5CCFC33,93D3DD2D2EA8A5CD,8771F7C4D31F2C51,36502FD21C7BF35B,B48B1A8BDD6BD694,00006E1507802565,F03843FAF3607DDD,85C4F8FE3CFE0E54,DF0052B75CD73A00,833C7B4DD707464A,7E5E0DED5CBD2BD4,AA10A29985AABF7D,24B2F6A38B84FCC5,024DADCE6BA545B0,B7A82F8D60C739CD,7BEF0AD85C3C10B0,40182192E5039C65,000014EA2E11A0A6,8E6450E0C6866A28,8B015F791E7DDF61,8E7AA0BF850C05F0,11CE2090B3D5445F,ED5CD9E99B470EA6,6FDCAAA3CC31413E,F559A66E6CF9E81F,198BA92FA2BB393E,A229C28B720C39D3,CF874871C031E44E,DAAF30062A2B16C8,00004788CF58BD70,E32685E7A2244A0C,E1683A209A64BFE1,6C28461AA5F9DC56,CFD9EB0684F15F8A,FE2FC61A365A0E4D,76E53F99AE6F40CC,FE79B2BFB3A0D68F,CB7B4C12A4FF26A0,B15C80E4499985B2,7CB8DA96F13D0CD5,BD9EEA5B633590DC,0000449B29040B5E,4D94C327BB492327,5BE9E5DDD62318B7,7AF58811897B2600,D64E76D15823CEC8,B73CFFDF2D95A814,CF760E38DFFB9E20,44AC37EBF33BD2B0,F83E6521ADC5F085,6935FF1B13F31D4B,578B7E92D9011E37,EA0DE1E37B42A4C3,00001D99C576909C,99723D096FCF05D7,DE7CFE5BC89209C1,F9E7ACFE3F81FF9F,0C1F4687F59D5567,1FA50E4730B7B8A3,E192246165222C6C,1A812AA38D451395,257E39D0850856F3,993253FC497499F1,62B9363AEEBB60EF,EFD4147BE3E97B55,00006F058E13F6D6,C72FAA54C89C4551,DF1D4935E9B66504,189041DE9E1FAF32,03AAB6958566F582,1658478B7C6E4B73,9548305B085C9990,0FB55ED9171998CB,14FB76FFACD529BF,B75389E1272BA8E1,753D95A913CE3C87,B6B5661A59B860EC,0000625D2AC6ABDD,B46F121F6E04DF7C,2D5ED7D036244DEF,7B9896A9E3533C52,808792529B819B5C,37D896D16FE8598D,EDB2E299EFA35AB7,1DF83C16BB3EC0C0,C71FC61B6756383F,791A23359A83BDB2,E9053BE763913E9B,D08B7DA6EE2FC73A,00005BA99B347A0D,3147E933DC5FA4C2,A23949D9253B6B23,5E9C8FA19625A8EF,63C7237761771039,6D1B9DB9DF029E2A,A4C1739E37EFFDB9,D31E77ACE25FF618,446881AF5AFC9854,57EEAC3E8C17D5AA,C8FA13AC4D9CC24C,76B876E22D10EE10,000022CA45835656,A0C06EC31D5432E4,7401964CA3CE851F,C99374AF47C9B3B7,EB9112E614544C8B,F0D01CA22B985F8B,786DF47971C71686,D5B347AA3C0BFA0A,9AB9D34675B7F1A6,431175188D906C8D,70B35CD3E462F29C,10096E42DB81F972,0000079944D8F9AF,16605595A1011F85,A2507FB59A766C3B,7DDE7423747271BC,186319FD2C90E013,C05F0A0CEABA3742,FA183410A6894181,DA486977921C0C12,DAC5A759446AFBD3,DCA232A74F479A1A,8CEEB6784D1258B3,2950893294682F43,00005EE84018DC4A,2D10555735206449,1E66C55358E3ADC3,67528F82B03E2BA9,84FE2C464368788E,DF27E8A20263AD77,41BD9082A42974CE,CDC2D10ED107637D,A57E5154A3CA08CE,E88101EB015D469A,FAEE61472EF0B9B1,7593D6FB56CD56D8,00000D3FE67DFDBE,94AD828A6E9A016F,F6B91A5108412AD8,A8A88C7B5916A75F,B6E182F9ADE203FE,37DE2409DFDA74C6,C036FA78BF2AD40F,81C87A0D20C334A0,528A19D8A604AA3E,9CA476B8963A812C,18F59DF594CE9001,08EC4E72A1663144,00006D5EDEDA6FAE,46F200E0246F3FD0,DEB9A4ACB8AB7F13,04A377C5DAB9DCD5,377722C84B5EF269,E10E27182C1099C7,AC318DC37596B3E8,785F9E4A092CE7CE,99584781C46F6529,6D6C3AF53EEA29C3,1FE2169F4A7EBCD3,9749ACC0782C9F52,00006BCE55E477B9,12553BE5375D5DB9,688BCEE81EDA1C6F,DCB099FD5DF47B55,A073F341874EFEEC,08CA3EB93132DD05,E61D69889057F83C,996C57E1FDD86671,09FA0EFBCD1CF541,103431A9EC17D096,0E1D1279992FA444,275D05AEE2E0B5C6,00004D96DCF9D71E,0528FA3F68D1D608,0F670EE609772A7E,167AA21106E75583,25AD3FBB8FE0B8F6,0E20961E17ECF7AC,C4D12A29D3D18F34,674AA31E084A60B9,30A3F84F8F6D49FB,6925565B1CC29CB3,E192421109086AB2,CB800731C42E2572,00004E33BAE6BBE7,5BF3E9D567C74EBB,AA81D0032983EE62,EBF73BAEC2C8E94C,BA32F73697B90C78,E9502FCF3592EA1E,B94E6DD8223DAB52,458C6EC7D50A3EA9,1AF54D7D4C8E7C25,349B4D3FF2B414D8,CEFA603F5EA69D6A,AAD52ABAD48946C9,00002190C210F91D,A5691750BF239027,1A37B192FD45ED3E,94BC7EEB5DAD9C74,DF9DF488227F63BA,EDEE50841613E638,A75084915942A8E4,305434805ADCE5E6,342691B14E992488,F763070A5A43C387,1BDE96E50DD1908F,1CE80B63232525BD,00004B69FEDE7A5B,109CFB8A345F51BF,7AEF2567593637F9,008814BF64C37146,5CD8BFE4D9DD9E5D,40624402F9E3F845,E7F77EA7F0BC7678,C7B39B3B166C5435,D0ED56A5D6C7D720,B0D98A0EAC72E9DE,CFB890CACFD0F3F5,E8363EBD50687EEF,00002C7DB134DF27,FC23A65960CE1542,F3A2B11F452D4B4E,2E1E8B71CDF054FC,99445C307DEE8F38,D8D63C016402490C,C34909310A123510,B4E241ECAB20569C,7E33F9C0ED332D1E,D1DE5AE4EBCB8D31,5FDB43391734F936,915BF194FC12C04A,00003F5D56F77B88,E5BB4E08B91800AE,C043C6AF53D0B478,1110CA9FB5CED449,F6992061AD5F5993,93011DDC81C86B4A,1E417209705B7B4F,A5D4A5833CAF1AE2,4C7FC8403E13FC2C,A900BD3BBF6C81C5,AABE830A037E3841,8DBAFCA0F48BECAD,00006E8BDDD541B0,20AE865DA336A99F,87071656ECD684F2,96DD4A4FFC3556E1,571E2360B90C89D8,394B8B2D7D0A3526,22069651C7CB4F01,13F0051567B5C89C,7F193043BDC34DAF,18440DEA31172EC8,4DD945BFF679AE29,217524D864A216C3,00000BB95260EF08,A4CE65742B325304,16095DA491A3533D,0F8287781DDEB212,A9E8C22534CE82C3,46B81A3500E7523A,D36DD3086EA30D86,E084EFA27A9FF872,4828A080B98FD4B1,E5D706F3D44D15BB,08B10D08CE3F102C,B3EC23FAAD62171D,000046939E2D9C9C,681A61C513BEFF9F,BD7C022B128EBBB4,0AF6A6B99A442022,680FBFE8A9166420,0E498AEECAD87C5F,32B78B40F93817F1,EEABFDFBEC67DA8D,285740440B17E037,7BBEE212D7375E30,6E790CE25744449F,1956432ACB685A8F,0000528780530AA6,9B7FE2B557A17EB4,6E1E2E8A2C63B712,B73F25E43D852D22,30BDFAB411114593,22B05D2DE9629E65,07169BCD378C60FB,7FDF33893F0E9202,73C68839254987F1,D66D9409DECAC78F,49DBBF9A1FA7D8C6,6B664CB8F31F41BD,000028C082800BC9,3F4E18FCE5D43D92,D87DF45521BCB036,2E36AC05D57E8414,B0DE0118B51ED28F,69569D2DAA87AC7B,E822AD2D96817C8C,7E846A4E60B9C8B5,0890B906C43B26D5,EFFFDFC38CE7BCED,9E2B13FB46722E09,2779709F09082B41,00001D1848C0DAA9,F6A3629EB5BE238A,89F2AEEEEB56B0F7,D135C7ACE458E9FB,607703C4E1FCC1AA,322E4EF5FF726F1F,64571111D23A88DF,391FC4A448B02B35,218A77DC850DEAC6,24C821855B5F2AA1,CCE158334E8B5C16,F56A12038F7586D8,00006F734202800B,13454C7F22FC7F48,8A4645549FB38B26,1FAEAB25C55A5707,DE97240EE52B45D6,CA8E015A1CE99E08,014CA1E3F942C41E,20BB689BD2C2734E,EE2B4E097662D5B1,7F2E3838593F7785,432AC5B16494E42A,BA84983045379ED8,00002CB22AD18FAD,5135278DB9684382,0B1802980968AB42,9B2E0CF205D233D3,D350E1C00A4F0255,CD0C2706BCC651A7,AF43103C7EA6482E,ED79F0D98CFB1D42,CABB8E9E4B57F2D5,D5688BE3CD27DD2F,78C6FEC48031E449,3667158C5A1F8A25,0000499E92951984,5635CC0F335F1825,E5AD34252E886CE4,7F49B7DEDDF36B96,30808BE25E9A0034,D92855A1339862E1,9EEA63395066EF68,953CD51EC2CF85A5,E4D532B94C1A5F0C,C22E20B6D3DB81D5,BD14AF77BDEA8DB1,D880ED26EA3AC2D6,000049939DA51604,93514E77EC8EACC6,B13415F8C6ACA8F9,31B4849529BC8168,71FABB85D0501031,0011E07060F9C4C8,77E29C12DA9F5768,D64813789B4B5DC3,41A3125F4F7A2353,6F0174A67B1B1140,BF3442EBADC59318,2639612DEE0B5C98,00004E51A4DD169A,4B6206BDF9938F02,95939C66BB4AA091,D9E1DBE1D2263C35,835CC136A1982D49,3A37DDD4449DCA81,C5204F7819AF3F65,28AF9516FB96EA7E,45DB72D48E4B2AE8,5D7E73398862E7B1,3CBFC34CAEEE0657,A6B3279F642D3CF3,00003586BB8F4051,7C7BC7CFE65830E4,A7C23A57F4339F57,E09C94364053FB86,05F24CECDDFEEEB5,BE482DA45FC867B6,89920D01564E77D7,1EEE87514C00BDA7,2631B113BF9F09F8,B3F0B5BDF8E96FB6,F998AA628C0C2F1E,B593DF5BB76C0354,000065E168215E9B,22526054AAA9FBE1,2E91FEBDEBBD90C1,4307BDB3173F2F10,7712E7CF4836F81B,07611FED82DB3724,EE0CA0C77272ED5D,CC359B0EBE95B7A5,148635DE83B73BE3,34F689D40AE69AD7,A626B58E531776F2,66C9D2FE65B6F10F,00001C028CEEBBBA,9F15D9F0D7D5DCF2,F0559BD2143E3D56,F1E6DA2D81C123E5,8972E0D21830A70A,BFE9B55BD54D1E37,558E1F6C13E84109,7268C6E6340B6908,5C98A6A28B56C2FC,DB0EC95892D1FCCD,1A1ACF8C186F8078,8E07963C3CF5DF4D,00006BAC287DBB3B,4CB8336A1C3656D5,5DE82FA5FCCB83F5,286C8B1461FF3862,1810F177EE0EE007,F6110125B8CFEE0D,E8D8734ECC60B146,4167E9FA928A1D3A,B971BE78149F1BF3,D94CC5977EE713D9,D8FEF1AC21444693,07BC2319FD5AAF0B,0000085068E86F22,1683EB7947B71244,AB09981CC0FEB0EE,D03CFE1F8275A71C,07095A6B29A63A83,D6C79AB939D3D199,B133515BA0BBEBAE,A9B6FC986FAF4202,361D18D6940A6727,658617376FFC73EC,2CCD41CC81710EDD,96D9E5398118D954,000056CBB326ABF5,8F62336ED4CCF82D,93F194237FF75BFD,139C9BEDAB7866AF,F31EA626D65077F9,6DD7700E495B19D4,083D89A63768B151,F900C46A88750838,364ED2EB1F146821,74D4669031265AB9,1F8A7E2F6F7BD694,F90A1C4353228353,0000065A643380A7,DE303F1122C3E060,B26BA6DF641A6248,706FD6DAD8C8CE15,40DB1646EF58FC17,0F8BA447E475A826,98EAEE998DA1530C,45231B60EE3E3934,ACDA35538D11A74D,C66ACBE3A8A44B2F,54E29FC9853649B1,BF7E596B0D5055BB,00001EA2C7027553,9D8170D9B123A2AE,2F83761B86F0D30E,BCA49AEB11C1999C,B16F6889B785843F,53EA498392129F3D,B824147AD31DA8A9,C979B107ECCD463F,2A649D0B726CDDCB,E748CA28EA560FC8,177DFB9E34872776,34B89B7F7AAFF577,000047ECCE9A8D95,41F7A30ABD8CDD1B,49AAF75B0AE9B382,EDE691C5C9B16E24,6AE10094C78EECBA,4E6D11D15741D4A1,CFEA8C80777787F2,E98A9541E9744CAE,17742D7DA29ADFAE,E88A9F131548B6E5,FF2B1E1EBAD2D1FC,FE936FCFEC3B21B2,000023E626197028,B951BABD628387B7,5A0EA41C07626379,91DE98C87E39637A,8EAE13C8099782F3,46A1678B7613794C,510BE4AE32644CDF,3C70F532418256EC,F2DAE45000DAE1BD,D651CDC96EBA6985,998451A7C9746979,DC1F29DBF220A15A,00006D3C1E6BD63F,6F9E90882DA57A3C,CBAF3C94DA3B7511,0B2A9CB9E5E3F8EA,A54D0ADD5E9659D2,96C28D167CCEB121,408459F11B7234ED,FAB2B47BC4DE2FAB,BD1B1093AE1BD1D1,8AA8FE7395652421,E285DB03FF1E96AB,39A8DD350A1913F8,0000660E1A4CAF3D,C667DF54A043F566,817E88E3FBCF391D,10C407EA6ACD4AB6,3804B3944718C90D,F3DB1C501D531D35,FA562BD126A70EE5,59C26414A7D2D878,EBD6649A5B563F23,73970EFDA9C1F221,88806634093B0078,1B884FD7DDA6B21A,00006C0A6065518A,2468DE1C96BADC49,9A9CB3752F2DA675,2199517AE17EDFA4,E89B750B41637C1F,4820BD686E3597F9,72C10C28C2A0C509,A7A7EF29B78759DE,407573E091310234,9A757658323F5AEA,7AFA6CF8A7206E89,07A9E6771418791C,000030C478B148E1,FBF8667C2E0DAC87,CC981EACB39D1175,094120C02CEF4877,765AF62488FDAF3B,F27C29343B643B3C,8AD13FF0D3357830,CB430D6974EBA289,B17A59A250BB6222,B1E6130882DB9506,D1E5D30A183110DB,70A6D005E3A94F1C,0000079F95E655E6,0225F3CF43A23EF8,9658A94F7B1F3F7C,8F08AD6AE9087A64,306CDAE39D997CF7,83CB39154F8DA8F2,845322BA7B1E09A9,BF3FC9853D6D1DE0,EA845B92B99265EF,A67CA582A0330ECF,721F6818EDE9C175,953E90A283C00F93,000061CBBDC62E5C,D2EA396B5F70D3C3,A45852B1EA0606BE,F4C2459F09C847AD,0C7FC2D905B2A9A4,F60591A21D377B70,F7EB075D80B4248F,9C1B0C17E5278BD4,17DFE85F52ADCCB9,3DDF4296DFF78D94,C0B74BAD8480A148,138005788815C57E,000023D1BB4BC2E5,D0B5213B1B76583B,3152877D0CB20E10,962187D20156D077,8CE663589F8DC814,DB84C9AA6FCDDEB2,66680F65095F010F,F4405D640F11B478,3AC36E39A91A4048,D937B87608A4849F,005AC28EA20D39C4,0D4CB9C6E010A81C,000053449FBC3AFC,28D24E019D25B94A,53A2EE1EFC8E74F1,ADFE7E10BAE99EDA,A47AF24A70770295,63B01C832F7B74D4,55ED6CE98F1B742E,306F9F342460B598,5FD6FB1AFE5AC124,B3EE5D8CE2EF2044,F7832141B15CCB7F,D46D2FF765BA7C7A,00006AF71ACB9DE0,DC661A229BBFE7F4,87B28C09A0A9C544,1FD12659ED51176D,610B1C7A16F2C424,D9644C7B89D51230,4F0FE3C183A6142A,C8DAF4E8CEB5EE80,ECACFF2C4945997E,775147B9D9689316,7F8B7F8FAE57AC5E,1A924DEC83828804,00004D7AD0E0FB67,9A6F6DFE40FF2A85,11FFEC0CD78A8EB7,774EC8297BAAA5DD,EE6C5FCD1AD293DA,464F0CE7CADBEF51,F66CB4000956506B,7F5C21613857E85D,786D84E72AB2A8A1,95DB81365784FF54,BABA4D0D2AE40C66,A905039DF9934C39,00001E7728243045,75CB3E2D6E2C4B62,D2A6BD230D795337,2C6184A4373D24D2,026A5EA3C37FF127,3DC4C237E6D64B48,6F9841E76DC499EA,5314156F6BFAA571,50A0EE7B0B352AD8,9418E56408444A9E,532BC2A5796B78EC,6DC3D7548463E4AE,000055A06CE4BE76,507740DD92938588,6CF6C6D1B63D3599,ED71478BC5E03F7A,9D8E6A10585DCFE4,B187EEE3118EDFA4,897D50A22B7A4F39,7E5C1BFCA764AD7B,2CA2C2DA62FEF264,6FEC3F7453A8BBCE,43C6B2717A2EF06F,1F2FFD7CAB46C26D,00004C3E3AF20E32,E9657DA68D389B58,9F90054069AFF626,2EE844698FEECD2C,F3BA8888F213F9BA,FDC48F8FE530C0BE,E5B11F834959309A,8578B27F741B57EE,D65853C510E03668,32D06B6016A962D2,A77A59578E0C2DCA,8942F650A5FFC1F3,0000462F829CFB0E,80A3506A7DBBA343,3960E98E63528CC8,CF21AEAFE6883CF0,0981BA72BAE4556D,137A2BE009884A87,411330CB53B73DFE,B4F094924322E571,AE31CBE7858B9632,521DFC0066AC4303,1E34BE2438417DB2,C5ABEE937A09B28B,000049325647F425,9A6117CB32F4F843,C2860879CEEE07B8,F65C3431A60A05B5,053484135CEA2CC6,5CA69929F8F997B0,CD4513F60838F220,7FD710D5021ADEA2,AF9E079EF21274BF,4E33449DA013491E,B9D734D7164FC6A4,5BE3AAC558893BE9,00001A378BFF8F48,4B94085C331CC289,BFD31190444C29F5,0F025FAA0C33A22B,7492268E2A6ED602,DB19ABD98560D1C3,5B1ED52E54898935,355591C570CBC2BC,236E5071FEE0FB72,9A3AF2CD642F8B5F,906EA5FD484563AC,F0C657EAD7E8467D,000036BD1B6BD768,620451E69452E32E,0E60CC2F0BB97B63,C9693F14515D56FE,38C5BADA61B0C709,CA81238F2790E38A,1853979833F380A0,26CB86A8DB1CECB6,00E0077522A93A93,88D7C1D044913CA7,EB58B9919FBB663E,8DEA81AF81240EC7,00004D3289CCFB9D,5E839FA031D7FB0C,14778C77BC4E8A2C,8D57E24CE2B08998,759CEF8E8EA7FE24,F4308DBCCCA6E35C,E012FBA28B862D5C,5C515BF8D4833588,67D18D3FD2A3F688,D1D10B589E5221F9,8A93B9307ACF0CD1,277AF332962C8357,000045D5D5C30EEA,D21B06D90B2E0D24,9C397A8D035A777A,8D70D998EEC5CCC9,FBA5B0FF4FCF5EF1,889B82E33A1C3E92,21EE9B1BB78DC566,F832A08E9FC91679,17D32485C1458099,6CF04FBBB13CC041,5604C945377B015A,4817B91BB11917B2,00003497A996C717,2921085135205F19,12C2059AC3EEE87A,A96A82B24BB94C89,0B42E2C392213FF7,AB09FF260F6B897B,47E7693853628F3D,378BF8B8897215EF,483F8B8461FB0ACF,B1A400D3729DD7CA,75EEF48DF78766AD,0B0A09FE6800B20D,00001E6224C3F6E0,22A2CC145BE824E8,7C4633BD970ED99D,1150EE18DE12127E,6BEAA8C2DAC97DA0,695C8A94A792BFF1,E47E288C915B713C,EBC5E720AA5AB674,FC416521359F3B0F,ACC504ECBAFF9C3E,F78ADF08E623CC2E,D4EF93F5455F5486,000065EB9CBEF7C8,9B98728CE5F2BE8E,CA0A29F17BE305F2,BFB86AE91B81A3E0,2A22BDBF4CB9C5A7,2C917B1D9497BBEE,508353BD754AA252,84FFC69DB3929CD9,07DFDCC9710D69B0,FE7FA64B175B1FFD,05890307EE25C879,C1025495FA898690,00003A8AB013D88F,013AE39305A06A4A,F56A377DB6E58226,0CB631E636831736,B39FCC7FB7818D74,73E5566BBDB88630,A117AC4E057A969C,2D1B9240D69FB7B3,B4B3369D57AEB6FD,C2D9F075D4A0E325,EB1994394FBFDAF1,0EF344249D097E7E,000020D33ADB083E,8F5772D93F4E550E,1190522BFD8BE1D4,A628406D898F4F13,CC02153B386E2C17,A54C121F9909A6AF,9744CC14057C55E9,A5C2E330BFFF65BF,7059318DB17DB8D2,A5A9F7C454DAD357,692E1D2ED2807FF5,CB2B80A8EFF897CC,00006D5D941BB528,060160EC114EAEEA,5534870570D98088,CBE4CF772EC02675,F0000A69E0357F0E,55314BFA4E330C5B,1BC8BE3013E125E8,6E67805FB310D460,972BA3171D35A153,A7A414CB9905EA48,568BA1BE977F68A7,03459FC4AD4D9975,000053DA8AD445E1,08D093CBAFA0651C,A88F51AAA2E71643,80DE4AC3EA4328F5,61D876F7E0EFF48B,C9BC87D5DCFD7B4A,0666D254F57BC1EC,D2020FFD4442741E,D8ED37A713F930EE,105B4E16B08A8592,FA3D3DBB98230925,23BE51E89726ECED,000022C918C67B01,0A48A6AC341B381C,C96E366BC890D51C,8BD403EAE568EA4C,5D4AE185C33D5A2E,CE30589F3871872B,FCB0FC48C7F52E0E,06FD45C1B22D8260,C541DC18C35AE378,633110EB29EA216F,14C05851A423B849,B8B3685D75E6CD18,000037EA7661D871,966A34FB45867960,FF39043E0417B89C,7B1782A94C4AE8AF,30A55A9F85DE4F21,8E419E07D75952F5,5108F9E0905F9A2A,7E6C41BE2F286264,200405D894523922,0E268DF9BF00F643,99C20E72C3724B8B,0F6D4094756EB896,00000DA216C74FF3,FF85533DF5B18804,5372B3AD18C107EE,025E40C2BA2A6CB6,1845E1677F1760A3,A08A8F8CA602CF1A,01B0199DD016DA36,D29B8950F08B3399,49FF2DEB94309008,E84EC3178A005DBD,12CE02D2F12B82D5,19BD26774426DABE,0000561C80346435,4E422FE03B4B715E,11A8AECD5DA2C129,5AF291F4EC7F4CFF,017D7305B30860E6,1C8A70DA0306F6C4,6101AA8407D48770,68D94B497B13CCC5,9B0C4544AD2D84EE,16C591AE6C80F0B4,70A56C18AE03B0B9,EAFE88F5CC169A5F,00001A6B1AEE77E0,CC1A4BA6F24234BF,AF5EC59BBDAFBD45,47B3AE83F98F022D,9C1790F24047534A,95942CBEEAF358EE,F0598456FD6EB0B4,A6AB08819C1EA32C,378585D61B3F8CC0,4B10F43115CBD9F9,8FF167438E3E5783,5FD6E2E7102CFFDC,00004A4C44971B0E,9E37B1B9C308F65C,F2E10D89BDE15D54,B22F6AD556005A32,793E7CB49DD2186B,8A6773A9C1BEEF2F,A01A1D03D610C410,260EC9199081D14D,EE35F8546673AC13,6E7321F24C594C92,A3E5C56AFC13083A,6DA9FC1BE0FF395A,00002D7E301EA922,AF862E67B9373B81,49B5A5C90968FF04,C7852FF0289FC375,1443562B148392B2,4F0A28E336FECE33,FECA33DBA486B4DC,4BE1844DFF0920AC,0799190FEE959726,65416F534132F3D3,B6DF101C3ED8411C,CBAF6149B5DC9BF2,000000FF23F15F7C,6C29E16C7969E08D,1CBB0200832C4D9E,E1AD51C2B36233F9,403949AE35920EF2,242503792CEDD343,F9402FA0D7F28D88,73B98E23B7977B1F,E11159DB3D0F0983,E74094883E00C0AD,6BC6C07F2381508E,19122ED24434468E,00005A6DBA591188,D6ABA74C0F3672E5,C0BCC84016602921,2630B8C17E776EE5,8C56F30D06D09DA0,DE71ADE0C1A80AA7,EBE6ED0C590F58F4,633911EEF712A20B,641B06BC83BCAAFC,161E16686A2DABAA,28561C33ED72B93B,B53067AA83C8DA92,00006E789899A979,0C617254C5937FCB,D15475AB86FA8202,B85557025F734016,D209712DC51980E6,3B1CE6319F863657,9EA3B37F9F8DB63C,CEF58A37E2B71F67,53B1FE848F737B9C,FDC491D6B4F1A142,6D8B3EFF8AB72A8B,3A1EC11EFE0BF1F6,0000159E7CB4676C,CF972F2F7F35B153,861BC41BB5C0CCE4,471A7EC00C175249,0230D3D08CDC293B,F6072B239D4752EF,21323E3D0F18A3A9,C90765324089556F,E34022B8676185EF,03B7CD564B39232A,323B4D59BC579CD7,8132E2769D50FE10,00001678603A978B,BE811C6E0DA09967,13ABD8F227DA4E11,5063E95B9826955F,5A6CB117BAA15E2F,52FC0A9ABB208483,F89D0AFE7D6E9288,774720E6EDC63E28,DEEBD7B6C892F8CF,04E3C5EC279454ED,FB17B683A2A65141,FDD31EE266FB10FD,00002160EA24A151,BCE5EDD2870B624C,34469AC02F1620F5,EB88E228D488F387,0C575C1BA868F10E,DB7F41EFFC04A172,02C8D3E301733036,38E040602CF704B0,9CB34F1F10BCDCC5,C9EC766DCDEC82A9,C454D5EE3B8409CC,EA69C43B61162038,000026D78E11177D,A1534BACE373A74F,63FD6E475790E194,8E08CC6ABE692DAB,304E335CC397E6D8,77D717EFAF5F71C3,1B800385EF02B968,140626462D78E56D,DD22B026F9151049,519909C4F501D806,052067E1A2093BD4,E73FFBA2E51C96E0,000048E7ABE91812,198AB77832644476,473A693D6F4ADEAC,772CA0336371F1EA,326A9F3CD573E6B1,BDDCD844095149AF,FE504D606B708F7E,85A77BF3F0DD47A7,C0405916F1C43092,168AE5204EDF95FC,BA0E604A8D99F0B8,7503F04D65D0F3F3,00004FA9E7D72B4D,806A0891EAF4A208,A33A7328A6DBA9C1,0ED64FAC375CAA3E,8C23C6C78AAA95BD,D8C45C636168B223,4BBF89173A70406C,D500F049470D3869,82349261334618E0,73206A68F63BD59E,8664E0A42E199319,7A6ED7963ABA0EC4,00006670879CFDEC,029A88CD4FBF152C,045E71B7D4ACE6F0,A2F15283B55F58E3,A739FEECE34A6E33,89602FE2604ECB56,797C1B9028E4013C,A40B3ADA649D34ED,8A6C51A3C19784A7,F66F758AF77B8A1B,7F5EB20C6C6D3460,F21849F67EBB0CA7,000069B7E78734B2,A25A62D6F5E51580,7F9ED68483AEEB5C,2AE141D19CD43653,3B092FE4957CD445,FFBF0B3CF2317A5A,F238A16FCEE24E97,1EE88CBE98F30666,0BA53C1F7D0427E6,AD2E7E5255C06B8A,69C979894E257EE3,CE409D267A4EDD50,00002A9D9131C747,051B5C313AF869B2,A36660C989F6F6B6,CB8328FC99633D51,7FC61A8624A77D09,64209CC0CCB6E16B,37B1B477A6998BD8,73399E5682349E1B,1CF6A7FD80EB7117,3BD9E81E368E7AF1,ACCDE2984001AF13,FB5A7EE6178C409F,00004C5EC3714EAC,32AD7003349F9764,EEF3774C81BC3327,99C944BC6A186473,7F75CA2771394483,E198ED5BA38FE62A,ACC201EC695D74CF,2FE6C501E58D1E4A,E918DD309132AD02,664D68FC3347045C,CFE41ADE725907D3,EAB73A1D8EAB9435,0000063896B2C698,560A137A148DAC18,180681B2212F9FA2,4C680B32ED82C4C7,ED8A0A1ABEE3C4F0,2B6214DEA7D9AD34,DBD90EC418AC3A21,23AB5F507BD5AC97,013AF55F72253AB7,4850B74F5338459A,3D5258A34586D21B,427FE07D04E3C951,00004E19270AD6B3,422AAA181324C0B9,D71C0BD3518647C5,FA716E818F2CA599,29D8373346318FD3,B50DBDD449E20D00,E62061BA5C51BC3E,02F0FD22B119AAB3,CA2A622612C3DAEB,969C58FBD18D681B,AA25F05026F8D2A1,88565F4659612AC4,00003DEEF7BDB359,7A2D050882DC3C26,AE82FA22D7FAFACB,B1F80F4B24DD0101,B1D1D35931328A5A,D62BC31697B8BBD1,E0A4D93FE7021160,B7896CC0F864040E,375CAA7EEEC0423E,910E6982B39D658F,EB85774712AFA6E9,1C5F8C4F4EA69FE8,00005AF298386624,736C97D8F09ED40F,C91FB81F10D6311F,77BCF2B240269CA6,E82341EBA2AFEE7D,4A90A197CAC48912,8464DD0AF554B996,7EE423C75F3EB5B7,1B9052E7A072FB5C,52853530E1B44CAE,81E0584418E56D22,15946FF5F172AA05,0000591C26C96C02,A0E2B8325AC7F7D8,19A354A7D628F1B4,4077CFB80CD43C61,D2AF57F74DEE6DF0,83B8E01E7830E4E4,D6E727BE3C65AEF0,1392FF7792417D3B,64B321929EFCDF42,412EB9C304F37BA4,AE7E96BED1118DB8,F8A5E7124429ABB4,00003DE424F6D7C1,273D0FC00E2D68A9,0EAA14122595CF0F,121963B787A181A8,BF4CEE9FC3341F8E,CA185B05E7E4F0A4,36A28B54645DD896,2551DDBDE9808B93,65C975A7C58E41A3,701CA63D62A44256,3492ED23139E1432,99D18EF98858C1FF,00006F55DFEA4DC4,365AB956A0840FA7,BA27AE4209D2759F,E644B3C124076FED,2543DCA1FBEE10AF,D5CC3BFB27E03EF2,C02A6AF4AC4AC340,21A2E5049D8D5921,422D1333B26B976D,1E8E68269B495475,CB471810A57E8D0F,193AF7E4FCD521E8,000039BF4504E293,CD9C7C41C9340FA1,C831B091B9478FE5,5E56F6D398B7A6A3,8B644D3BE39A9F54,68CE663880B416E7,6933C3752AF47B1B,5CF1CAA43B79FEB5,D2A5B484A7DCB256,2B86EC0357EC5F59,D156286C247527F2,57A998C58B8BBCA9,00003C31040DE1E2,3D0D174BECAAE5B2,31209AEB988E9346,D40DF9C485BFCCAF,4F596CAF31D474DD,40C8C1B1AEBEB69C,F642F4E724C9827C,FFE713D48ADA12BA,6835F15AFE1DE7DC,06743A59086AAB58,F9037B9274478339,D842000D6BFBBEC1,00001E8EA824D4D7,DFBD772FD75EEA78,159375595AB32C66,3538F310183695AD,D290534A4D433B6A,07F6395A9E440A76,E3D0E259D9448861,FC5579A1E55AA901,0B89538AAC920DAC,3A80BAF34841B7FD,064F17B4AD5CA913,1001A3A3116F9D97,00006031E32D1502,3C44EEE4579A01C8,25266A5C9334DF1F,B3D91DC39029C97D,F58C433374F32689,71B4BBABA5BC149E,2859372961AAF52E,C9B4DD4E9B3D463E,9CF70450C07FF3F7,387A6863DE0924CC,B852BDDE246904DA,5A21E744A0C7BE1B,00004B0C8037E1A3,3533FD222A51D2FD,485BB96FEC892EFF,DD8A65A7C063381D,B52B74244659D6CC,57BC772782B49277,53507365A62142D1,5F888C7EF70FAAD7,4EED65F6CED381FA,9F43B275448022AF,C8D2A7D640091018,FCCD05E116F0A6AA,00001EC0E2D162B7,3328380869DE7A34,5544324ACB8B75ED,58A1ADFFCCCC8A13,7B4599530625A7CD,E8471A707F3113E0,33C853E8D1500A33,D9FC418EE2CF4001,84AECF4AE2964E9E,27E8733222B62018,064C41392AAAD467,408E66BD255BBC85,00000330806F52DF,394921654CDE3D65,A3F51B196372584D,7D46E8A47288B0C6,5314694D2C7244F5,537491C632B282D0,99BDA6899A8C3724,256B0E3F9C0EF2C4,3048DA38B5A4AC12,8636D9EC2C0EF2FA,C0624DAECE31ED8E,2905F5075EF4DD40,00003A0694557848,5DE15EE2305D2E0C,386CD7642D1E47D7,F6647C058949083C,86F197B578B0B07B,F3A79F4B04975D58,1984ED6932A54C9F,B9CB41609740D6C1,C605D7B30101BFE4,7531F76B68D909E7,D46F8514682C31E5,9378021DD4EF1845,000059AA96F1488E,7EFDF97DD620F16B,3B5F9224A1E6FF1A,2246B56AE3DFABA1,E1DAB704DA7F1D09,3F4F68208250FD00,4A5B185252D08D71,E20D7D70C7C4694D,F299A9712FC24678,DA71DBFFBDDC810E,4E209C92A6B48E69,99E55598B409AE65,0000680951AECF35,8B5410526443FFB5,09FCD16448FFDEE4,8ED3BDD6215B4A29,B86AABD3B4718591,1488809B15DD6A15,208F71933131B63C,E493E0E39E7DAC53,42AE1B183AACD5EB,33BCD3646BE27C69,A539425CDF5E4BF3,56FE556DB9F3D062,00001493ABAFDBA2,DE19AADC53B196CD,560A0D3441C26292,6D25750DDAA216D0,FACFEA5D883E0080,1A48646B114072F4,ECBB1F2F1F5CE03B,DD33D5E0727C38DA,36975A32A3392523,F5F7A209EB3239A1,F66178FC41D778C4,BA66570916CEF7C5,000029DC1BAAC201,5C9FD74FF24C258E,91D3E7639A797A24,ACAF76944E739F0E,4F30033C349378AF,C5DC4D2421AB0F05,9208C6449F36E702,F264D793091F568F,5E602C7A02E0CBAC,9046AD2D23DB2B53,F8B6650E147A197B,8C9472A367956C3F,000034F8D1A683C2,E04CBF2D5D108D90,BD15CE422507E212,3086440EBA90489A,715D052C028F1AFA,D086572FA06EEFBC,8078DDDE7547DAE3,CF9E1BE0B080F0FF,28004084F6D8245E,ED2B477D884E7A9F,5439A69EA5B6A824,1522884B6B6EAF6B,00000AB9BF95C562,5A1EAEB006ED98A5,B300DE2BF29E661C,7F0DA53BC8AD86FE,CCB985805C608DDC,1B00D3A773BD19B9,013A4EA392028C7E,7EF84C682B4AD5A8,88E9C7EABDE296BB,BCB743676C56282C,1CC8FC1166730E0B,C7CF4CB499046FC3,00000FA5795D1B67,C9C7C7B9AB9D1AC0,A3529494F18A83B7,EAEE374F2E0BACCA,F3913637992EA9E0,282178E7E32BA8F7,DE0837D82BE8638C,2ACD29296C1C7262,797230A473DC04A6,6616ED6869F6D6EA,84B4868F28A5D85D,D1879CD7AE5998B4,00005725D2C62617,D98BF78584FD5C08,A13AB6ABB0EB976D,2138D848F505325E,E5F8C68B334DD7A9,B453285A8A10DBE0,B42E37B9671A5BAD,2F612846399D51E4,53521C41282C09F1,7787C8722D48E9F8,D153470F0520FFC5,39EAA52DB9E45B4E,0000017E20434011,DC2299DB7FBEF76F,1A74927281B3F6D2,092A1091AD77B38E,96E305223A43BB75,A5A36F9743F523DC,2D18E5ED49423B95,7B3B0753C9021565,416FFFBBFB057F0D,60E7A52501E7FE44,E7B1AA14ED60E711,456670038546F660,00001D624272610A,351E24F6EF958901,30C58D48611D5103,F4FDAD76E439F77F,04323BA08C9C0551,476DC2423DF79354,07BDA32AC826C95C,8CEAA4763D8C8CE2,DE1FA3CCA94D0356,01D1537329F9324D,6E06E780C4488BF8,D698846973B5D29C,000029B95C0F9C3D,09C5E984B695AF63,9A1DB0B35376F924,31EC783D2A15659E,258B39B99DD02159,7B28387E424548CF,8D7C046DFECE182D,323A44E96FD85A9A,604A54A0C1E1FFA7,6253E7EC959FA343,13AB3FCF6FECEC7E,06B1C0656B3801E0,00001B1760F1253C,A3A7DA63C350FE96,A5E9B8AD5448B44D,E80AC063B4655E5C,D56627264C636D68,BB64C148BAB3FFF2,1ACF075F32EAA2D5,51C07443D9631B93,B1D67C17DC12B7DB,E8B90BDA2097F4DC,7F2A715241917389,E883467C17976570,000008ABB551B005,D1A064EC317D5CBA,3726FD2105065CDC,1117996C1A6F0A08,EB3AEC89B8064B3A,BED1A3DCC0A2624E,314E66A36A2E1F11,E9F1A23175783F9D,ED793D905B74B5E8,61D76834BADF86C6,B4D8EECC6AECAB7C,AB7C3665DE835185,00002961003C34FF,96AD8D2FB26CF864,79C3C1E6E7CA73FE,73C6984F462F392F,6B63CC4A8C927316,EFB350C4E626E01E,6537FA702196D37C,DCE21536916C24D7,3F5D360F5F260868,9C75112F87AC9368,9E68C44D2868CE32,F0DAF7B9B556CF6B,000027AF2BCD5E85,FBA92D94108B08ED,D1815D4D633FD9F9,CB8167B71BCC70BF,73D12B27223417D3,7B86325812AA3B63,36A10B3498AE89B6,A040F2612BBD5056,32B6DA163BB62275,F5CCD2FDB9A9CA36,B9E6FE31D963AC25,043450A21102F046,00005D16363C93E1,86961C6A80E6468F,A3C0DCC5A1FC9326,A74544C1C6250200,495DD1568E85FB18,5338743B2044345F,700638CD918263C3,B6A410D4111BC0B8,F6A1F4F48678F11F,4E41F13327666551,6EAEB3E7AFE50636,AF90462AB5644C8D,00002843140A3DD2,1AC8AEF5E3024674,53E48D4CD5F66DCE,69CC3A2AEE28B990,E78C815ABE1A8360,4052223B5D363C3F,254D915BEBF9C3EA,409F5113755EF688,967247F890164F07,E5CDD929E717307F,E8C321FE9F9D40DD,EAFADEB91FAF684D,000055B0AF2F1AF4,6D8CC6B5178FF7E2,C519DFD1188856C9,9447CB327E93CCF1,D2B8305B4896E1DD,08AEB227DBCB757E,52CAF90A7D80E29E,BC783DB92BF436DD,D3263F9B87E33D66,6071A8914A02D0CF,CD38EE2E5A8384D9,76B2B1F1A419FE58,00004C5440C5458E,2DB0A132CF409B9D,5D86E2F6E8D529F8,08296D99254EB3BF,8550B39FE8F03CB6,8B23BB2B821E3350,FA0D23DB6EAF63B3,AD711BD20AC39DCA,E421C55982DE2FE6,A137517836BB5D4C,A3B0A136267E16EF,80587FB769DAAFB0,00005C5E4B8FEFE2,4CB5F6A1A16C8CE2,0A42568802086CA3,93B9E0AAD70E23D1,4ED6D4AB5DDBDA82,4E28109781A32741,09136DB201B713A6,DDD012267D0BC7D4,53DEB41006B5BD25,A5FB20E69AAA5AB7,C769B56C79B032D9,01020E08B5F277E2,0000447775D75E8C,56916944682AB051,2D8E731A27480575,ED41B6530CA25987,486B25FB59B0F966,5C95390222C49E2B,3F73B994E2E24716,8FF25CD5324CAD3F,0879A45168E7762D,5575FB3FF3903D2B,BD7F7CB02F1AACDF,371F75181B45A9D2,00004984D2C48BB3,78A7222045300180,157C3CAB10AC3297,A61B5AB513811C23,171D67001F79A374,EE860A88CD33CEEF,A830BEC9564EA045,20C12BCBC898E60F,08B4DB2C4EB757DB,2129CB2CDAE06DC1,3D1FEB8B187F1423,7E43F3F7CF9170F0,00004928F05371E3,61F0D33A28DD9407,0824D06A32F77E51,1CBE619BBE439000,4DC775F5715F646B,CC1B811AA3B83BB1,A734068E2CA97D48,2AF974B6B69E5C3D,3A2A7A8CDC1B44C2,8FEF1129F824404B,2AA1EB44367525BA,43CDC3D773FD8013,00002823BD2E977F,38CAB29DDB4C8B82,D1ABADB8383461B5,13FDF16B4AAF52CF,6302CF84F81481FB,8A6CD7E007AA5252,8EB94330CC5D8186,C95BA29D87ADFB63,F8708A7E7F80E86F,AF8A4C59CE0A1153,82002A5937D3D47B,E89EAA49FA03AED4,000067917CE8EEE0,21EC4266AA544BEB,2E626C10A659F83B,314C50220BB0AB30,3D7AF4921CCDAB86,D112FF30192048FC,ED01C152F03D48DB,DE020DCF8A5C00B1,F072B1D729889CD9,8A54280F6018BA1E,061D132F68891709,6D8F4F1C2B21F287,000066AB89B3135D,3EADF2E475F2F006,9794D57561286B68,14C6CD1A464ED1FB,031A873EF7E3F371,3F1893275949F69C,3C48943C180A07B9,43E0B9A6A41F3375,C0D4DA51C47DE770,94511F2DD81157C6,5A3DD0BAE783A42A,630461F96BC0DAAF,0000567DFC3AC40D,B8153283B7ADA009,8AC778FA1F34197F,B323A42E3D7D1037,001387A4E95A3773,92D49A4BF9F267CD,619BF9F3B853D429,B5F9678593F7F236,FA08698F79D31CAC,9BA3BC08D78A497C,0347EFEA91C28ABA,CF74B19542E5586C,000035A5316E229D,8E2EBC0F931C1B87,68FD84D10214BB8A,C48800779263C735,1BA3E1DB147D0904,6B1B186A597825E9,A6A89296577E09F1,675C600C56135759,A935B9C885219B47,B4C30FBCEC5D1341,67499ED2A4652DD5,650604361664D6AA,0000593B9B8D7D70,D159CC8BB14B733A,23E8E336AF7B15E5,DAF269F09C662C26,DCCDEDDF37A16B03,8A07D2FAB7744C90,06B38773102465F5,6EB8E13CF136F903,4E42AE3CD0E07F07,D642151E2FEE2DEF,CE6D3153717D1F9E,28B76C13584D26D3,0000496C5B61C8F3,6E1BFF587FF212E8,F08527469748C13B,6927120B722CF7E7,4AC152994116B5F3,FABB0E84CFE7BFA6,81B4192BAC189FA1,D24E6589F6D75BC6,D933391FA615D852,D97EFB8B53109B64,E1E25B372489ADB4,54075EE37E365128,00000E8C65E0AD53,3807A1D4E377853A,4C898D3368D7AA76,9CB187FAEF4C61D7,86460DCB07358B6E,B68EA3E155677DF3,7EA4F49FE236662E,30234A4CF5408CBB,2B29FAE8E2175E16,6DF2AF9AADA5886F,8D9C32B972A6D5FF,D161DB2242F1AEE1,00003B79231D46BE,714BE85456ED6EEB,737821E23A5ED5E6,B9DE14E5FDC901DE,EFE26D1DDB471BC2,17D4B8D2D6CB90F5,4235C0D59CC51F04,8ED39A300FA340B1,DE8DF24E7AA79E2C,0BEDD827DB86A219,5CD5E74D81547AA7,39B7A7D868A746EB,000012E0F9970DF6,42C5511A52A4A0D9,31794CAC3697BF15,874777AE0C677202,26000ADF13CD28A3,FF5C0AD6E4D60DEC,6CF6A3C5DE63BB32,81505DD6E47AA53E,0ABC5895C91A93AD,28069764EF4E7EB1,22777FE23B85B4A3,33917141CE7A6125,000016A25A7CDA9A,BA07E0630B6E8876,2691031A01226F26,E13670DBB76FB65D,3ED5BEA68E68F77B,20674D030A214799,2DEB7DE449C2F298,2CFF1A7816C89263,C76197CB80B5F4BA,2952B1B213364A51,B6369C9B13D2B2FB,DCA60A9A46D49842,00004A3E679CD2E3,0614DF06B1DA388F,8C6BD98B1A3AEA0C,FEB4FC62CD3ED8F9,87D19157335E9FA8,AD9B910A14F9FAC8,A4B3115ED826DCBD,83A11681C7A6C9B2,F5B340D57A42E9A8,12275DE10C930CCE,35CC3B755CCD31A5,5B2080674254DBA5,00002A81EAF9D7D7,7705F93E1804A6EE,0E799EFC8BC857D1,315AE910DA3A0A7F,286DDE0A9F5D8FD3,03888C57F23FD134,60AAE6914036D725,5CAAE2E57C6FC11F,F85FD6B7CEA2BB88,52107FE199B76842,CCAF582F130AC0B2,3857D6BF5820D261,000004D97F34633F,5439E91C58445B50,6C536D309584A201,8D36BA2A0C20711F,B944179903DEAACC,C72290EE1AF118CE,685301A465BA7BEB,E5716432DDE417DD,5F8605348440D4F0,4C6B4DAD292AFE84,1B4F78A3F21BED27,08AD1EB43F8EA16B,000047995D1F84C5,861F35457D86354C,53940E53ED1C368A,52FC6D5B00E96D4A,ABB5EB36AAD62CD8,DD850160AA0F9BC8,93623E2201C0D1DF,047FFF6CEE6671E0,646A1A06C42F3DC3,6DDDC11AF936D7A2,C2F1B61F2696740A,F4F68C9C981A7F39,00003A73D3155122,0C50EB3969C9B3F1,EBF8934541F14A4B,1A01A8ED12ED2452,1195941C8E66EB6F,CDBFCDC3D94522F0,1F950DB9EB01DC02,22DCABEF440E5296,DF3E36A4ECE93997,F44AB9F29ED45693,DA14EF7D718E4B4B,323B0F660EADD5E4,0000369B96F856BE,2C2E6F69AB3E674B,55A9A2C975093AC3,AFB765B68D7B0F5C,B37BDC38D58E7278,0A16021446820612,8A876485C87CEDA7,BD5D04F259A391CC,1A59AC99A477FB50,77CC760EE0A5CE98,9888407D9BF61087,0C372B3CDFA3BB42,000015D1D5E510E1,04C55B69C3B79898,B0EF6CB57C1FD017,693449C8D2A4E87D,9BE92363F6BE95E6,66D59E4D4A2C2723,1DB236C127A35923,8A889F8C27ECDA59,256FCDCAF82C81FA,330B13C393D85F1B,DA9848F17A71CB80,84119CCEDFD95C77,0000007CFA74FA9B,0AA04EA99BD879E4,73B7E2700C3C8855,19E2F4791C837465,52998D1F42DD7FBD,04578FA80D800D16,E8E69F0F7ABC8FE0,2F2F435A0BCC94D7,C588B79DED0A71A1,19F031D79575FF9E,85D0E1E977E18EBF,E17C556B649C1F4D,0000450B05201E50,C1DD896376B809D0,12FC8BCCF814A213,C6AC14556D7854C9,D79C20F453E75C80,464CF55FB81187FF,AD36D8BEAA97675D,6844046EB4B4D5A4,FDD803DE32571511,58F341A9E738BC7B,03D9DB74B4194148,D4C335213C17544D,000061C6DB72797F,7CDC7CA678A8FCA5,3788A198B8B0A951,F396BD58138FA6AA,A7F192F9E704B33D,D70AF5C489BFE4F4,12E7D2A712D639C4,829F3DE8B834A601,49BBD92CD9EF57D4,0BFB494EAD82B28A,6AAE6311BC3D351D,F1ED56467ECC2D0E,000012F3ADDE01D4,846E6974ACBA1697,B3B6A8369D17D1F7,11DAE1E9417B1E6A,F4721F27AC001885,F437EC8676DB489B,36FB8F9A0EEF2682,326F4CB31E90E0AC,DDBAA699243C060C,59A5D858B1473443,A972A978B8614B32,38DC73D849231939,00006E77149E15AD,03F89A9B1F695C83,B4E7458B41A0A971,60717922CCC9EA51,FF2D091049711B9B,69F8892CE2CC7758,8CA49B08D972032B,516C04E9B774DDE9,066B67448F8DFF20,A418B649CB1C96DA,64BD6880A8BFD163,FA648B0262C4E3D1,00006531C826897D,57FE494E5C9DE819,6E2F19A048780D6E,7D12C80238ED95E0,08652D55C8B03B81,3EB3C15C7F29D1A5,80D9D2CA50A75DAD,2AA4BC497744C255,3903E8365981106C,CA379AF8AA3F2202,2D68E27DD247A357,3EFE52A9DE046AD9,000040585EC74B58,F9682666C3A9051E,ABCE182B3B9799CD,A62CC17CAA7DEC3F,4A6ACC7CA4C8ED7B,875FFE8DF5888247,1BDFDDD1B945DDAA,D23A7C76EB4C2615,FB1BBF928DD359D9,185D437FF11DA857,80372F3DFF21BA18,5BF903AE1E0E9837,00001EF57BFB99E9,130C4F11AD26574D,0AC752627738917E,A3EB405B6F973689,3615C4CCA742992C,4C90571B49E8E692,CDB71D4E6BF7D0E3,D3B1EBFF6821AED7,5AD504A78BCDF959,E642AB8876C00C73,42062CD2CE696A1F,94CADD24D349CA2F,000031DF046ACEDA,366ECB6C9F54229B,44DFAC74F133A222,E8C9F61CDD7896DB,905F4296F177FFEC,52E5BE09336F0BE0,1883ED5A4FBB89C4,777E7D0F66048E2F,61E28C40677907C1,548216738B9E0CA0,08E19E89226CF3E6,9838D64F2F668BFD,000062CBDAEEBCED,1BC641A976F7F4F1,257538206DF77727,DE623BA8825EB50F,668DAB79392A0583,CF2B70D09B9A0547,AEAE5B12D23EFCCF,5868CC35B9FF7496,5395B8F90BC64863,19A3DDFFFC7AB749,3CC36AB13686D5CD,6AF215FFC27396FD,00006A551BD1EB50,32886F7AEAB8D5BB,E1E0B64F7C7E6736,DD39552045E07230,BC5ED19D6BCC014A,41C9D135A38C4F54,021909C64A6927E6,15BBEDCB8E6CB4BA,81BB3FCDB67ED160,352B708B892AEAB3,9C2B62C8BCC37810,99E15DA949971BDC,000041526B9057DA,2E596E1526C3CE25,4CF966FF7F96E036,776680409A5ACCD2,2DFADF45A6094A46,CFF63EC5E64ADACE,D8EA65E3EAE75D67,D4B2B11E71A02AF8,5CC7C6ACF76A0760,E56C76B65CC7300C,0D9415D3855F200A,58B36C9A262E3ABB,00001B30B51B2587,2BEB1C0B01590E12,592B8D4FC94F9EDD,CFE96260B7D3B265,F01799427B5F2A5D,69B129A3C70EF3D3,9741F2D8DE77A86B,77E908DEBAB7A5BF,B9C23602A717C3B7,61B61439B3FC4506,111BDD95084C154E,5CC18EF353CBC0E7,00006E468192F7B8,9096C874240B2E89,FE1C02FBB4BED67A,16494CDFEF57A2D0,4B0B1A19B460A5C9,19D59EC4159F8569,A2E4A3A042B9B893,1D4EDE4C2D60415E,81DBADFA32980EC2,2F0CE121017BFFDD,A144665FDEA9B433,09AF2DF93F0B415C,000017F4FC42C301,51A5C9CBC5C123AB,A69CC2C6BE929BDD,DCB24C15A2EA5760,4A5E4E1A0C5E5B87,D0B872AE41919AE1,A8CBED749582885A,02A958F21ABB7A00,C732497BC91CB6F6,2FBA0AD4653BB900,4D7D9F6250028160,8B83F97E0993A7FE,00004F0518C804F9,C10A79954C125D28,8AD0914808D08FF8,0EE1D6D45DBB7937,F8B6037EA29D98D7,2AF3F7C83CD4880A,895A5FD4F4D8BEC1,168330D8CA133777,5CC30327B4609085,5E029FDE889EFE0B,D4EC96F268F52D27,EE052AF9E37B42B6,00003DD450235438,E61FFBF7231CAE8A,327E7C3D9497283C,8E7E300FD95A3764,4348415F25AB7F62,926654192DC1FF24,A636547DED8FD062,30A129FA7C6317C3,A0FF18026F268AEF,587BB9F7FD5576C5,6B9F07C30BAFD7CD,888BF810B2DED141,00004A2705E4A41B,1E9B51CACAC1B83A,C3E84FF3F3957D18,085881060CC1F286,EEB60BBF6B02E173,5A758C59B67611D2,31465AB312E47575,630A2BAF75BD89E1,7F70D74CA38003B6,31DB8CB665B30923,D4B402644806DD84,220253BC753A8015,00005C32128E899B,029E848FDF208C8A,80E216ECAA7FFA74,7EA109BFD79CBE58,D438DD60DC55B194,76DCE40364F46E90,65EDEB4FF3EA7E85,495577D6DAD0C569,286FA78AA414483C,D6FF94651DF5E895,59066D283E750CBA,CE6706548277C9A7,00002065ED227416,BAC121983BC35787,0BEF480C73E707C9,D089B9B4BC43BC7D,78B6BF6BBF95E9A4,68817F4EDE1A2285,3D44962DA209577E,1C034489DADD34FA,F9EAE2CFB20B9BC8,90D58EDCCA6207DF,A610FECB2BE0B970,03F44B8E39FEA61F,0000257AD22D2DE6,E3302E162BD72093,2BFD8D17A5A56A98,F57B1CB66EFBA096,D95CF9BAF15DAE64,A52C2E77A7B96258,1C93F3FA31157707,EB7C8C839B0BC072,F3AD0F2E01253F33,61FD43D17C496C61,242DAB8452FA9B5F,C9982D91AC8129F2,0000083D49FCBAF6,EC0BFAE572294D5D,96E6EF52F41B2728,282476401A1E36F9,F299B425378E4368,2CD3519BE7F99F5B,792DF02222CF1DD9,CD5F754E05C5A4CD,CBF5FEF3B0C5EF0D,D73F60C8AB3E32FB,D59A671E50424C7D,FFD42B38A2A68856,00002B2C08C75A31,1403F84C2DF27338,A8AAAC3129336C3E,F25996BF38F40545,9937AA0A677AC8EF,90DD3BC28003AC9C,7D105749C115BFF7,94BE1B61D6BCF55E,D876F1AF3671293F,E5986D329BF4ED7B,BAA4A2F6B35E6BE7,E81FD8AF7AC77169,00005FC51F288A04,D4DA6F3ADD9A0FB7,7EAF2B4C64F913A3,DAE7E0D9296599F3,51A6F41BA6CE88A1,50B9797BE467491D,8E853DFFDC11B6AA,2370F076A2C3F2FE,038E6C86EB7D6808,FEBB03A02B934769,8D4987C7E46CCDC9,E1D48C29580F14A8,0000116BB977CD47,3F882D5867815D54,07B84265D83A71F6,C30A380B490F8358,0B50F9B0C7F9CF94,984A2C1DA9F89D8E,1BDD569EC0EFF04A,53FF4641201FFC16,0698E13A43B5D12E,610084E533FC586C,D747FB7CD0E93242,0B06EC5C54FB5669,000053E51358209B,CE31F4D980F72153,3AC7D08640346833,64FA8D77C4AC0F29,66B3A46373BAFEA4,C062EF29F0B4DBBC,7587A09D5DFE01A1,9935ECA9FCF404A4,24BC1320913DB1E3,B0D642525EF004E3,67D68C81889820F5,CDC506D0654D9585,0000161C0136A65F,D1A876157AB21FBF,3B2515366F8655EE,EEE067C87DE0CAFF,7572082B03953BB8,12B7FC00B0693D35,36D4862D3E94CEBE,3BDDF065DCFD72E9,71A2D19718FC4C43,64050F155B7B92D2,0BCF411DCA6F84EB,B5204EB3DCD114B0,000053F7432B343E,84F044EE01141490,B80E0DFE05A893D6,BA32C8D0B8C62E72,564E2AFB786FD0A5,16A900E167B366E1,730C8E2FA02D08C0,7C2D63EBEE245BA2,6EB1F01397CD9F78,F67A503DC26FEDD6,598690366A758AE1,7FDBDE4A7CB1B1DE,00002507B4531E7B,009A342FBB452940,DF998FB5D6E691E2,5BC3D875120E8695,A6BFB6EACEB535A2,18F365A817D8901E,7F64FFE42AAE8C5E,CAD7E55955689848,3E8BCF9A4788E77F,3D7A37BDE8553A72,53CCD801CE1BAD37,F4532D43157D6EA4,0000533678B814D0,6638745F7704B375,5EA5C3AD70D165C4,A8596B9B828D4BA3,402E0AA96599CE7F,C32430E83127571F,747D1230B021E83F,0DC778DBB6B37686,C5FCAF87922408F2,0DE091DF469E036A,A37513B63717B3D0,C48C2F02D573D96C,00006FD90D8FA708,512090151AD4D649,4702BB2CDC716418,8151D0F12AE637E7,BD2F04777F24A352,38D4092FA454D78B,D37C426EB0CBD697,9EA93DA58677E687,AE50FCFEB838F45F,B50E64E91D7143E4,497C3C9BF598E756,7A9AE50905A10198,00004D2D26E91ACD,886334CDBCC37F1E,1481437A06802F52,76FC30E63DF25E4E,2BB18F8FE4FEAF71,430DDEAA53F5BA97,8C61732CD0B448FA,5E729F7E15815E2C,02C78A6D346D467B,481A7F9884E38159,C7C4ED8DB64FB0A5,D3CAAFA905CC3A51,000053EC6B54B5C2,1AEF2FE0ACF98250,C34C627E7C473C03,470F3CE5904DBDE1,111CE595E77066D8,0C13418109B06777,0E10733403649648,0B7C804C514DCD3C,6A57E5033C85BAAD,FFED05EBACD590FE,C8E66DB202027D20,C891449AEDBB3E54,00001E4DFFFAAA5F,72BC086A8E54F3EC,D2E6C209F07C81EF,58E7BED14E4B0E99,38F9613DD18E7C5B,2269431227839EFE,2088D3032FE9F97F,12AE3ED260FF58DA,6E07CCD09A3C4379,35DC7326F9745BA2,BF0AE91013FC2C50,1DC7DC84FAF4F6FF,00003368F4CBD9EC,D5F74E412ACAC5B9,2665D07CA56E548B,87A51F73D6364375,8BC01F5A0D879482,EE8E4584562FD974,53EE787FF257A00F,C7EDAB583203034D,4444614BA6336D74,09900D16F0356063,E576AFB38842B195,91A39D9AFAD144EA,00004E3D0D68BD21,AE0C03503CC8AB27,8E9B1A9F63DF783A,F5EDD8F01AD692BC,D582C29219EADEE5,76D69951BF755AAD,656988B926C10916,63E5ED11C3A22A71,3A6207D61D27541C,CDCFD1CCC5A74F5F,CAEE7524E65EF550,45966948598465AA,0000329960D9C47D,6C9056E2F89B2273,600EC4D4BCE7B0DD,93E3189A733A2F26,9D28D2D55C85364D,C44C08C5721C8666,DD00F7F5CD422F73,B5BB92A6A4D26655,8150364075960EA1,98D0BC6778A48813,CCC89F05A04EF933,3EF430CAA484B895,00005AEFC6F16499,FEE5042DE3D08449,0329E670262DC1BC,53F3148A7EE89ADF,58272EC80041CBAC,9EC63C064D652D55,823C5E5850968AF8,E259E1109683EC55,99F258A13C74081A,F9DF38830E3F5224,72B0C3B8DB3CE79C,F4B632848776E433,000040ADB43945DA,953C21D4DF725806,8CFE9F1BBC9A3CF5,F0BF187218D89019,ACFDF073EDB04DBE,064827A4DC0634CC,B99103680576056A,2F832C3E3F468CD8,B16A7F83AF9C2D8A,5337FB5A62A3B56E,53E16B8A0A3DCE96,EF8A7EB4D6385870,00003AA8F9982F6C,BEE19EF509B18C7C,0594A328C18E4D11,CB6B162020024614,D54FC6A577416F69,3B0ECA8693B64799,929B0B379BD42470,9C8646385C0571CC,FC9427CE1C9FF2A0,CC9DAA040F6FFFA1,9B7DC21DCD6F6499,542878345D43A41D,0000432DD823A2AB,F1AAA93E4E798284,37F9EB49C6CCB491,6F797A2DF8C07ADB,9E96353D56FD3AE6,FC81201CEA3531C6,490EA96435B8C8BA,1ECB326A6B351402,0FDA750A7148E87A,6D6E0E7B95405CAC,2C64ECA6069F4324,2F477A3248716394,0000077B58DCBA6A,14225D3B8D3A336A,B0C9C3AD2B1F8C68,32B1567ACD3766CE,00F0C90CCEE87607,A723997D6C766BF2,4410A0031BD20752,A836F9547C8C77D2,3C83E4C60A30F9FE,D41E9929746EB5BF,A6E76811C3BA9BD6,A5DCB98BC9EF848B,00001EB4AF36450A,3407C881898392A8,AEBC0646ED30AB64,38A2EB961CDB84CB,5011A529B3422798,F782BBF5347E4042,EE8A7D00F19EA0C5,667D0AD89422C278,793DCEDE8400FD71,0DE89012EA3E2EE9,FD85551AA5CEC663,6855949BECCBB335,000033B80347FACC,AACB9B5739007F82,AE472EB7CA8352DF,81635E939C2BA160,E31F84C87C21CE38,5DB9C8C25A6E4AA3,1F3D67CD89937218,99F4876E16DAEC40,F522DA326C68B630,9F9EEB89A9D54E97,8818A187FA8E1EC7,4E2A87EA4A9A8BFD,000053755250368B,784A14B9BE9370EC,64982A6983158E32,8C022560DC03A0BA,BFF70FDE9CA8A27E,B554B883E7E81E02,B4DCEADE622A2BBF,D80A69BA11B9E16C,9981088AFB410E5B,C4EABCB3D3106212,226AEBF6A0164F49,8F7E7A501CB328B1,000058716D5F9141,90D61371EC2DB328,B30BF78AE117B1B7,5E47609E068772D5,ECEDC1759056891D,61331DF28B300B12,22D5A4352E00F780,38D360A46358CDE8,ADF04DDC0887F4C4,544A126C392692A4,FE063D63190D4B9C,8850A2B502272A6D,0000101C9012A012,0767035A297995BD,735296767B3F6839,531428D84AD1B8CF,15DE068049EC138A,E252EC6A59B5360A,F39FD3977F828D30,57C09DCA80549853,B21AD4E1F64C764E,AD50C22C94D01D4B,6A08B7DE6441B29E,0DEF52E773D8B2C7,000067B28CE45112,CDF70E01C82614AD,1ED57ECCBAB21F4B,93F80DC4F6DE658F,CA53D9D87D311976,7E79E2687B48AE2F,4146586FE9ED56D4,48F1838FBD539E09,F5B0E311AEA1C734,BCD9A0179550147D,FC8D88229735F4BF,123124278CD9C599,00000F19A05AD5A1,C8D200C5F0263729,C3821AC67426A524,EC69BA4B6185E78B,27529720743A82CE,766AC89960F91755,E72676AC9C695634,64AD37F5455075FA,552FD467B605C0C2,2E45C78644EF4057,D37301508CADF7F2,3C918AFCCD5DA039,00006D624C0B3151,C181FDADB9D9C06D,BE310E1764677E8E,E26479E7DDA4565D,AD9F81BAFBFA8B0C,28D9B12D152807B8,DB91C8AC3BC1F99E,E6CA4805B54FE893,2B950E0ACDBC1320,C8AC9237324E07CD,97CBFF472737DC7B,4B924F1123F41DD6,00004B959ACAD164,6B684FDA4E66234E,8106C14B0AE083DD,266ED6D93C59888A,08284C681706DFE2,AFCF08248B2AE372,F56248B0BFB60C93,29505B85146B2F24,A142BD8ABECFBFCC,01C4146D12854941,A3D3F8AF561A4B90,7E606F8B96D783DC,0000629FF295F22E,F6EF6BAC96E51AA9,E5F95FF5EAD51038,DAFCAC069F9C227E,06860B606EC6A325,E05CE0B1AE4F38B4,1200DD8E6AF7B72D,17BEA9218DF6CB88,F8B8DF401EDAB13F,FAA48B8041F6659F,F4481895E055F801,3F14FE83872F4868,00006A4DA724BDB5,78FBE5AD167F327F,5CEC514D73F7C0FF,00C6D24D68476EE0,D4679ACC7E34319F,9CB73623C0F38047,06F88E122D9F6E87,A68F38F19B465CBB,540B0D426E2222DE,A1EC44A074939FCB,FC151336019742E8,9019A2EE5BAC24ED,000029277E689F28,416D81376B6E6669,9EC69175C0EDE297,53588B90A3E1934B,71706419E761FD44,450119CB3FF8A228,DF1F794DC865E030,36D1126F25BA59B7,211CE3CE542BCC7A,0DF6980D7D8CC0A8,74BB85EC68BA04D1,9A76536D89CD3B7E,00004962A26BA4E5,5F795A5BBF2A1D7A,9164CFBC3886125C,792A720DF9C398A6,623E077C21AB3A14,53A69DA164739DC8,4BBA18471159B84F,BD50EC5DC45A2F4B,F8CB46494854E3D3,685E74D3348F9408,BF6BC4AFBCF2D028,2FE164A53F8FD38F,000017290FFB0EF1,87E7220F865C24F3,65A73E0A1289F7B1,ED97BD829A6209A6,F302B1336826BB64,3323C2805C916840,AD17E5569D8C9C55,41F4FE2D92D3D122,F8E94B64175F8774,C15EBB88628B7029,0037786449F5DA9F,D8740085BC14A21B,000003A9EFE6F2D3,52426ECC9BCBB84C,4C7FB833DEA6783D,CF52EACDBECC2BD9,C0DBFC589FC6DF8E,038339E250B6D988,7F0681D55D6B6815,A8BEFD457984E325,A837494E2DF3402B,D38A97C294CF398D,FB4B5EEEC75BF9DD,C7A0E9DC6023879C,00004AD3303B1F0F,82B78BEE7B062DAD,31B0A31169C72478,EBE448FE69E733A4,90CB41D96E310F4B,8DC6E2D061C2C90C,51E4845996EC4BB3,048FB17DBC0C22F3,0194293EE74C384B,C578CA29F3E982D0,76283ECCD3C72BAC,0FAE6409B5828E37,000066EF5579E592,318952611DBF59C8,17D613092FFA8A53,6A34653306F13B8E,0B7F3EDB895ADCB1,167310040A3A4A87,B631537D3B49B346,F96E90661668630A,EC191EB0B84485E8,E91F3EFC0AEC0C12,5113526F7429C388,3FBBAB5901CEE04B,00002A90A847C042,13D4F1A740D0A3C6,2DB2C8CA276C109E,2DE9186F1A0A5C37,55E9BE3F898099AA,1221A56970B4943F,72A26A0C19979189,F8EDBE1E07565E30,26F014FE0EFBE702,838FA5973D01EBD9,54C1FC46116814CA,45822A667B6D9E13,00002503F8E8A429,8F962057B131B49F,57AB2B88ADCF92D1,6A11325415483551,70AE5231F9C572BF,27A733DA818965FE,9DA2D4A7D0290D77,3FD3BA8071B01A1D,4F05EA1D24578EB2,BB75DC0B41D96F35,F00E970B6F20C6F1,4436600ACABE2A60,00001F0C32256D17,8C93D5CD72E8319E,2707E8BD1C37D741,F1B581C8B38D4B31,E8252F8E09643D75,D413DBFF3A2F7F55,B39F332B98ADC979,0FC64E8F3EEB0094,0A6B62E8A2C5B09A,859906A387BB6A6E,3DFF29F438C4BB0E,2C0C6D78B9A8DC44,0000045EB7E587F1,A00C51CCD076F1C9,97252E28C9849440,576DAEEB7E06B1D9,2AEAFEF3BDB30D35,760AFC756757A043,EC740C324E4E809E,FD7E662C553819EC,C321EB91CC7FEE1E,A1F2C76B6C264CCB,267107A7F00DE332,F75B9699E4E1C524,000011DFD4066104,D9F40FC7E4C88775,6851CF67CD56A9F7,4B253221CF3F20DE,8D9F2B7B4E02A0D6,28E56D6787FCDFEF,D8934ACBF18759A5,5FFA6112963CB265,A6271CBE0CEFC7AC,C1D9A67091D2BEAE,FB9263487B50C730,EE6C072D8B5B7106,00003E81DDC287F6,09494047CB535598,D57B843C251F29B6,2C06796ED36690EF,FFB6343266613D56,50FD749EE0BDB846,BC96734F0913D145,99D6246DEB3EE96F,B7B8A294B429D429,4141859C881B62D4,6590964890C10B29,0C846E118FCC94EC,00002763D5927E8B,CD6FA386BF99463E,B023FFE62290DE64,AD72078D8E29A1A5,A39FADA243DD5A2B,2814D37B987270F1,BC1167FB2679248E,65D95A9BFDE3F51B,FE15E801667BFCB2,35E7DD2F346855D7,39E83070D9599E9E,39F1EB73F27E6F24,000003BE5471D595,E5AC041B14B4E091,0F1AA7EB6B57743E,B07C8676FA9ABEE2,43E01E5F54DFC675,3703371073CDA6D3,B8A57F70AA72D54E,B0E4383E6A0A41A2,D06C91BF4FA7AE67,34CDE2E95D22F028,270A005699BBDE78,6DE003F7D1CC92E9,000037DA75FC444A,4656465EC4DC4A1C,B3FCD1FFE5A9CFFC,DD70DF14E7F602D4,5B9C12E79B07000F,C477CB5E1F4A2893,AC8BCA5E1A7CC066,9683967097283165,485435A980B5C391,0C747BAD867D37B0,553F424207F84A68,81A028796E021134,000038CAB09AEE3F,1BDF006EDE79C508,F8FA6A27373DF22E,CAC62CF2AF294149,84FFDA82910C1A31,EA704E3D918BEF63,8C6A1CFCF5F4DCD9,15C865FE897B368D,B0422ABE61D6F0D9,05662DC0411DEC78,393D587CF214DCB5,810E66C33FBAC034,00000C156CBCC1A9,6DE13653096F69B0,D1BF5B3880CD02B3,FD63CE00D1E3E911,14E742D32240D631,EF2A6628A20D2897,12566C51CC30BABB,9D4799206BB1D0F2,4E7CFD0223EBF8F0,D3F8CDA3FBB0F666,6EDB2D8F8C4E9BD3,698221D4EFF2A153,00006BE516B818EF,2C5CC49271B7CE65,1062E842F8530F2C,64A0C1048BDED0CB,9D27C2F3BE9E86EC,C00FBD2E3A6119D7,A1E0E81D901F9E88,E761E31680FAAD2F,5E6B2F79194628C4,66AE7C6D349C3276,77971E08F1AA6A02,28CEE1B78B00F4C9,00002A81788F7D60,05E2AB9AB2493CB0,FB0A52FADE15FFAB,3FB5F1B276E22213,0C42A35259B6D3B1,FA592590DEB4911F,3EFE19A91F3F4543,8F5658020EA8F279,F74C0C13A954E208,85E8C07E53A3B897,AA6E9F1B30D36B74,432166B2BC09D2C4,00005F555B6D5654,DB7E4B38D6D49843,65A456344722A149,30A015AE353825A8,D30DD9EF3FCC56E2,83CC0107519ED766,6665A0163AF35DE7,E7A498D8C84B93EA,54271EE4C5BD344F,E34B8322D634F605,B9EBF902C717BBE2,CBF2EDEF68CF25BD,00004654B15400E8,B8C88D93199D5486,FF85679D1FB94490,DB7590315C9362C4,B5D986807B1B47DC,74D2303D876B7426,DC3956B8521DD193,FE044EEFE0A5B30C,1DCDBF9C06662C05,0D6FF864002B80EB,73ED059DBCD06061,C58BE983A4360A4E,00005CBEFCFF5CD2,FEFE432149714281,6C3EF20757889965,0FD210BDD14A43B5,BD964E46CDB03224,00B2A88187C7EDAF,F4615296792769F4,438CDF88A28CD67F,B73C9F42C9BC7C11,C9B20E87AB2C6445,D690EDA8B7325274,D8CD0329801D998C,00000974ACDBC20E,656DD8AFFEE6E295,68DF10C0BBC86B91,BF9F8CEC621B1046,29FBDEF778E7FBCA,5F744B207A2F3058,BD4C04C462284A07,81EC8E0C8B1438ED,2E3BCA99EAAF51D4,CF4DA7DBD16F6D2A,906F7D35027EF81C,BDD54B23481626F1,00005CB505C31187,1DF3F033355FC38B,F75A7F4EAD436133,AB27D343573BD07B,B0BEF81E1BC7BDE7,C099BB131CEAD1F0,E3654D6AEDF6B047,AF272C578B670413,A42C72209FD82E69,AAD12D0B3C7B112C,3B3F83A6250992D5,86E35B613E4641EA,00000458D941027D,1B931F7B59260F04,1CFEC5F46DFCFD2D,A5AA9B7D5064EACC,8B4CF44607101724,A005F54DA4BFFF8A,C062BDB94EF69999,99990F87A8F8EA54,E3D90169368A89EA,DEFA93ECDC2AD3D7,991C86335601E83E,7C63CC28EBB92BA8,000029CFEFB67D71,7E69E08E24D24DA6,F29237DD9C349BBB,F141889746460661,762A6FF0B9D0848F,004E24947C83F398,3A2667F34CDABE43,ADD77EE1DAEEB802,9485B5558327A935,64D1817FE71F758D,2B8F7BE0E5BD18BB,4DCDB99E7C36EBFB,0000449340B52E27,9B41F811262F1E97,C9809B4AC5409EEF,73AC02A856E89DF1,E6601F8422DD110C,D4327130C95188AC,5715EBAC93F0E623,2325900D4AB3202F,E0B706482B933759,9F6325B0A4AD573E,400843097CF9F0DA,B62C044453874238,0000031475CAA5C6,A49BAD815F3CF8CA,6C1ABDFC287947BC,025F1C841410F720,AF8E2396CC176E77,56B242CFC3FAB14A,6497A86464E73CA4,1742E7AD686EFAAF,7FC9AED27ECCCF63,BD58E198B410CAAC,33E8FD9F87434723,D3CC19D4A01EF4A1,00005A9FA948A545,B32B1E622AA553BE,9CE2554ECC53A620,AE5176400A47EB2A,1C323EB7095CE8B1,BD64493714CBDA4F,876888ABBEBE49DF,5BED01FE6BEED0A2,4943CE4C0A58ECBE,427226E9FC85A5E4,CD9F4D8826591AF8,856FDB44D8794AC2,00002F3856D349C0,FE587246369B309E,924FD59BAB28B298,811B8587DBBF7850,3A4EB4B912BF4E02,C29040DE185197BC,65C6C3D339D35BF8,8FD8DE2F174D65B2,41C65BA5EC1BDB4A,4F6A4D5D9EB89639,315E3A0C6022D652,90740CE63BCD7655,00003BCC043F7FC8,38CB7BCE9A9BEC84,6EE025F99E8DDBDD,41E38FF2C7AC88C8,C388945CF18000B1,48D2BE6A1B5884C9,4D8C9413B49C4627,C4249F1F45D94129,5528B28B00460D3F,473FE9EA2F969C62,6F2074A51CF55489,A32CE038864273A8,000025384ABEC592,DCAB19F8B1647986,862C64F1A5555624,E625F68596D88B02,7519FF7F11CC5F2F,02253F133079716D,6AF24CD9F057D207,8C6687F18A2F26F4,91BB159853AA4136,6C69EF4DFAA7CAD1,F9AE3B0321FBCA52,14AB8D876909D23C,000057D1863E3960,DA7FD04CCD5BA82B,A7A5B9E0DBD8F0B8,99A70B685040B84C,8FEB05E6508316FF,FE9CB2A7813CF93A,B99548638D49994D,5DDC4B69C829CF04,21B6454083219A91,8C4B410B1B59E8E8,51F7ADC1F9549CBD,D5E4E8D30301A0C6,000024B62640A04F,667B5F3A1E6A4D82,B5D833C182079CBF,BFC0567C4E88C406,8965390A13BBAF9B,9982A58812C41CDC,F3E20057114B6748,1D02A558B8D6FB9A,B4103584AD326801,46F7EA4CC1908CC5,29A4503E5394D91E,08A5EACE001B8A2D,0000281E121C5A76,6BA7A62AD17441D5,B14999C68DD0E54D,17404F4EF7BD4D80,1F8C0CE9154B3F42,D126EDF3AA677B4D,ED9E867BFD4816D5,773D1ACAE1CBD3CD,67F70C5E0327CF6D,7D3CF31BD01E6091,5EF21CBD55E2F443,22A8EB9DDC4962A6,00004663F40097C2,2A4CD0A24CDABB28,24F56436ACE1F1CF,AB991AA808AA0DB7,D148B0EE4559FAC2,F6AF44D97B8FA72A,48985A6A4D65662F,4862A7FBD6D4A35B,C133BB2C2967DE56,DA51421DC603B389,A5715DD1CCC247C6,F237EF36E648BB05,00006C6FA3ABCB06,5221B477E1E1941C,C8E3E5E8F880E6D2,3E144B8524354C51,172C1D045D3F94CA,41F86ACF5FEA302F,E3A93F05E936A49C,F376A5528A0EEF07,C0C097FDD10F05DB,E66AD277F774D399,D6D2566D96ABEF7B,4D53B510E973D25E,0000362D9BB034E3,7B313288FED89BE7,9533DF0615CB1BC2,BFEEA11166F20378,513675E284B4CC05,16289BCE228CE5E9,7DA3055A848A61D6,DD61EA9E9FB14402,9238A6A2C345757C,86D6515E04E79EA9,0ECD5D0EB10E077F,4A5085814F72657D,00006A5F29E99E22,B598E4FCBC89F689,26F741262ECE3CB7,2AFFB38F80200B3F,8D39E71BFEC95E79,DD093120F114A420,AA4F62FF47C08D0C,946A871D4BE84849,6137CEE88583506A,7EF0C1D77F4247C1,C8A09E3A2E2F4482,011C7FC1B24653A0,00005276EF49534A,C0C67E77D66F67B5,401A5EE8490C4D5B,7AD6B3D63F5FBC39,F5FB60D35D5045EF,6AA9E11B7BBD5316,CBEE1C462C1D8431,71C497A2F11C63A3,07098B1749340CAD,976C9BA76CE76C3F,BD1148244055D9E4,8955C0DC28D80B06,000029C41C6D835A,245B51089DDFAFB4,094B20E533005AC6,267E9CB924CD5E26,E061E0A262A367CA,B87C5C6F531BFF28,928ACFE2DA7EF02C,36B37EB96F5A9710,114945BDB4E3D650,1D9E6BB8C42E00B1,96B63F610B92C28A,18D99CB06D169DDB,00006A487D47C2D4,D84E28C8E6E77188,CAC714AAC04A38EC,04CD6E6D2FC47F96,1EC65E84813FA5FB,4085FB47BAB3D0AF,D4B061C9F8051301,73FA26D34E89E251,5D452715B5C38560,2B66343D56B21ED3,188CE5DBDECE1339,A8C15C0966F776C1,0000430AC3084ACE,FF63D7C4349D28AB,63A513ECD82BDB70,FD4531981DD978D4,BD88219209D2E220,DC44DE964E811271,490E17AB28FB0603,90260A7731C0937E,6E9E178FFBADCA3B,83C64009E2442A29,1C1305BE770A6622,B4F314707B43B8C6,0000441529374704,525EF8844FEAFDCE,B3553CD59405AE15,A2D9FE94FFC1CD13,3A843ED5596ADDDD,6C5CCA4757863AD9,ED1BCC4261A113E1,C224286F9034BD93,1B78A863B16AD29C,AE57DDC312C836F6,9987F485941D3D33,19A3EF66DE63E3DB,00002BF8C49B9047,C1CD77B99367590A,B74FA4A06147B712,ADB1B49E3DD7058A,E6345A4228261C2F,962D019FB569AE3A,A4B774106EE44643,F1AD6034F2490BE3,16333FCAE9A2B32C,D37ED8B707CBF33C,E6B9BB090F2A990A,CBBE2474C781CBD8,00000105167BF209,CE0895245AF8D350,8BE08F33E735614F,A99587B8C28E0619,F53D7926B999E598,F9B38D3D2151137B,F005AFE4734AECA7,A18DABF39A28C3A0,AC6E087C5D28655E,7C39E184BC1B07B7,A78C1AF63F3091D6,883D4247964C7C14,000052F8B000E8F1,77BBC1D31DE55EA6,6679B0E4CF88D811,7431C16877EC9B49,D3C3B58BDA5DA2D5,C6672232BC66044B,4238DC93F60C75E3,610E0AFC629B981B,4A6C201B3469E859,A9CF65BC861C582C,F8F16F96BFC3E33E,E0CE3DDBE37618F3,00000B7E7B7B7EA9,84B0EED307382148,9412A938A2C0F8DB,BA84A524521449D3,3DEFF1B45CCFC5A5,52C2F7EF2036137D,5C074AD9AF76482C,1F59A6BE39909431,F6F266459CE95E18,D72B7165D29F4295,7712EF2A9C14ADDE,3EBEBA34C064EC59,0000239CAAB0B6C1,F5FE0395D8EE01B4,C4F3D4BA943F46D9,88FDFF4BC44C93BA,051378150E8A07F5,2214403ACC2B0A0C,EBBA9880F1E58625,ECE0AC8C0F26F0FA,CA29E2FAEFBE61D2,F042002985066D0C,B5F87DC5346BA5F6,AE6FABCE41F94901,000007B684330D98,4488EB17F741369D,FD9B16E8FC4C5654,9B1D7BBB73189B3E,AD0831BBBF15DA8D,8921BB278F152EB4,46E56FCA3765857F,A785718B712385E8,AE6E3405B1873688,ABB1348B0F6F8765,8AD13141BF73CEFE,BEA0EB4F1F295A71,000054D3E2169F1D,CD669A406FCCCACE,19AF05B8207727FC,DE197DE483CD9935,874381D10A6FC528,22A921B4DA92D353,D00B6B6C38E1FCF7,0149F8FBF3DF9932,2BCCE573426F6F2A,80F976691C102799,12391E83D27F0514,73185F10708493C3,000052ED36B79DB4,C0D6B548AB1FBBE2,3E70BA8C514FE8D6,E90B42BC255C080F,FF7B0870B914AFBB,90DF6B2765E435AC,3B7CFB7160885B08,3DEA997E15A015FF,C5B1498CC8FC293B,25EBC3E3262D7C1D,26324D1BF08CD863,06AF629C8C2426F0,00004A1FE14645E5,927159B327DBEDAB,62C5C477769F930C,47A07673BAD148E2,3EB09FF7A885B768,2A017AE11313314B,F312750E1CE0DA5C,2145AF0BEBD3FA22,981EA0C3E78B6180,7D82699874E07F64,63C2DB1AF5465E60,D62AA3C72CA61A82,0000171FE47A27D1,6D4E6461E13ACE69,7C82B930DDDC7DD9,78F7F19C02426180,F9363620A7B97A7E,53A1926D0DC5481D,59AEFBD5971E661A,EBBE24A239987402,3F98E910D6FCD324,0DB0CD92709F3B4D,3975BB55ACB516CD,75F693C70C7DF9B6,0000627AA24A639F,6B5C014B4CD6C599,F1FFBB2CFE12F01D,CA88E81C8AFACAAC,B52DC729AABA8862,57EB99590DB85949,A1585E0ADD5E1197,9F927A6BBEBD8EBA,D06EE87661A2E6B1,7CFF8B09D8E1859F,E66A83DF909D5157,46ADBF056944A76F,0000108EA887330A,B607AA653621A5C4,44524D1773AB4C72,355BF47A00011D4B,4691796E344AF387,E8E6953F5C06F636,90513D7FB15B9F3B,E638592CA33CE5FC,EAE254194F2C37C7,52F866798D5CBBBD,858E95DC7F6C4042,7EB069059D03BFC2,000022CA25A99F32,24E9A72003ACDCB0,DE9830D19727CE83,F20F09F3FC3A9F51,A33E9586E68EA2BE,57431F53744227BE,7E6B938760875650,FB437A22219A9DC7,E34AFE0CA1FE362A,970B412014909791,77F73E873EA32B96,9229AF601C804498,000020A1B44E3729,8315532D752B8F80,8A34AD1EF7107731,2182932A35B1DAD8,04B04A645802B5AA,A38BC558283EB2FC,B51877C4CCB34242,7F5FFB577B7B2BF1,49D674EF7F25216B,1C57FB24B7B88892,CEFF50C39981ECCC,B9AD63CEEA5F2FEB,000050E9A1401E58,F0E0A95C3B1B3C30,2DC925F94253A131,22C6B9AE13B1571A,CC4895AAB62E40EC,4B4584C3270BE17B,6E86A216A2409164,01513EA96DF01F20,9D3A2C0E5561492A,65FD2C75E6E76BDD,936833030110190B,B62247A7857748CB,0000028E13F95EC4,E6D5CE340BC24117,D212370AD5F8AFB9,877EC5D8A4B8FF25,E5A222665CCC62FA,990A6B5F981AFD82,396E1BAE74556A90,D91A42C1A23D8254,DE0048813EB44773,F9AA5D90ADF954C2,7DF49C6533A68545,803948BD8096BE76,000019B81D268D7C,40C0D6BB002669FB,CE501E08BC7439DE,9B457918A9E4E219,6807070997712D09,89B1A080C0BA288B,F8566B2B620C1A44,83A3ECF7EC401DE9,C6E14DF91432CF12,6C3E556156785F80,3F37EDBD0A3BDA5F,B500F10B6A5BEBA0,00003F16497CCAD7,91D69CB200CEBB91,98DBC23ECBCAC13D,14EF205F9D9E791B,60C3121007D77076,686D057D0B1EAAA0,2C0A6AF8F4104DD6,75A0D01ACDEA089E,23967142C86DCD41,43E6156242300202,E5EF9D2DE245BA60,D135E723F1FA8929,0000489ED2B57CE6,4BF26EC8890980EE,C00C93B8F776D0C1,8ED3B89DD040F379,46BF2CE8876BE037,4950B66967C44B28,D20110FCEE3D5E30,924BAACE6B1E8D43,30164333EFBBE4DB,A877480CD976DFB1,7DCAE11913420787,317362054E861F42,000032D8F85349B2,5EABAB8D818A18F0,9F840B651EE7A91E,0A3B96E8F75302FA,28C89556CBB98458,E15461DD52A76358,A442231D000CF374,90758F3A7AF12D10,CEA991894B186A15,D2631D671BA5649A,5E4DD6D56CFA8DB7,568DB9BA6175FFE2,00006EBC53944E31,D08600FC2867997A,946AF6BC34683D3B,E41044E4CD33A884,723B7EC762E08AEE,356D8847646CCAF0,B3E5039E17AC2588,6174510EC7CFD92A,AACA7F6E7DFDB69E,E1ECF3DCC093FF20,C4A54BF02EE67C8C,1235B92C6985065E,00003D2FD4DD2A82,678EA22B3B924199,7AEB0A5684192A1B,99DDED4AD933EBF9,C585A9CE660033D3,51DCC6EDFC3B3475,2C6164EE6D208E4B,BAD29DF3442E5D8F,71C31C21B4FD15B9,28449F72F12C4C58,5A7A4E8911212F9D,1EE53B06E3736D16,00000D30F47C0FBB,A241E2E999882476,395C0BF0A38F189D,95B9A52892C69FE7,B063A68ADA05A1FB,ED18295BD5588AA3,2651E07B9B5A490A,FE76ABBB90F564BD,DD4CEA99EC5A7C45,08B92800AEB02B0A,8C71BA4574C4A534,BDED467142957A10,00006EC8EECFA2AA,46C3E89210104E66,1886ABA2C9CA64BC,2EA2849EDEA3D205,4302B266839F438C,8A12D7F8BD0807A4,C34094485AB98CAA,8F3ECBBA8985A974,8C1AABE1CD076770,CB05257E531F83CE,D69D7D662F53307C,39FCE58EBE499AEB,000006B8CC0C0BD4,B22432611648BE56,A020AF81786B4E0A,906DF62098471477,4295975E76A2C465,6EAFC3701CF4AD34,2020D83D76CDCB45,D7D99363E787E108,46EFB6F3E0F2E411,8AA2B4F655B77CE1,11751E4A59047A42,B936861DDEF25C76,00003D404D93A8AE,ECC4691A0AE34AE2,11C32E47EF27D3B4,45A38CB902791ED6,536BC60F45F8C600,0CA5F571E0BA5A60,41F3FE3AE0039685,C4523471C99830F8,85C6A3A7517C0895,AE529019D8C45B69,87BFE4A67E61FBFA,48B97970E1448598,0000172AE952AC0B,A0C077A954A64483,3AA810876B8CC582,979C93349A1550F7,D843EA991A19A88C,14C8C9ABFE2ACCA0,097D817B347C396A,D247CE67B54A119D,D3C194DE396BD208,9AC4DD3B7BBD66DB,BC4AE61B1D4FBBF5,AFC2E83B75BFD54D,0000672CC7C35E4A,33E0AC7A39500DED,93CAB51793C88775,E62526C6D3093075,299F016E613E0CFB,3E7D0F9150FD1BA8,6A7D93E6A37DA3DB,B0BD2C318F4A73C0,DC25853A9EF92268,40ACB52FDC3BADDD,650D1B34A01F3087,D01D3EA7E46A9147,00004B92D9FB082F,23E0E24BE5939909,6396375D5E610780,A57EC98F24167959,AD7ECFC0F941A0D2,A5D7D1A3B815D61D,DFD0DC01A972F70A,15FE42303BD101CF,DC863CCFB28E312C,2C9B97DFA1C9E952,43E22868D4B27F62,C17A8527EF8703E8,000066B5AFF5E753,C5C3B2236241FAB2,26B42F962BE63084,CEA4D3B92DF508E2,7B8E8FEFF40582CD,9CA5241D7DE02240,1DB2F24EAB5D719B,1F231D6E66A570E7,2CCA882EB2ACD0C7,84114F30F9063A63,F78E351DF28B6E83,8BA55D789C53B041,00006BABE34D5CC6,14F1451597937F25,BC0CFDE05991E777,C41546D7E26F6148,529F40D71BD163CD,99349E6CAB1B033A,F8662E80F11517CD,BB7A3A9FE5E90494,1306B7175A829E09,4FC1379DED9E6FE3,65685A622AD45F9C,38FE389E2095FE17,00002D6E115C46A0,E16B109810287F66,96815A27A0487EF3,56F4B860650DC64E,E6F0690FDB1CAE64,C65B9350FF3D0292,EA527982DEED141B,33B92621C8ED41F2,56710A08BE8CD72A,7C01BD9715C8D17C,3C85C7E1D5C4A91A,BF070E1CAC453352,00001CC6AFDBA574,59D5362DAABB2711,6316ACAA30527A6D,F00EA507AF397172,2F526BC0A7EE2074,FCDC3E5FD4E4EB5A,E644B20F1F796D36,86C347E333CCFE9D,EB54B53F32969592,C311ACA2FFAC7EF5,77F86D3C9F52F292,AD52D66CF612F25E,0000162BBC063C89,52251A2D74E7FE85,58B71AB598F10589,318A04FA8C8505AB,D7F92C81660D2B6F,DD3E349B32CF2C94,BC4F373450FB4A53,DBFFDC7C9ABE998C,B08B2B135D3B10C5,F7603F3E01B93238,7A2329114ABC8F0F,D26C4B7828D11263,00006E4038CA8B23,748D93B5269FB0DD,840E05687B61A9E7,201F578406A1095E,14E6C6944BBCF238,B6057DF4B6C656C2,CB45AAA6D72DA710,32DEE68D972F81A6,A1B98905736437E7,038AF248A5529AD1,03259B5E36E0EC97,E122FD2B9A04D630,0000197F37593EAD,04CE1832BAC2D64C,D7F09FA00E149F3F,82A85E0007ADE4C0,EF44AC38284B72C6,A6DC6BE3515C75E9,EF10AD7E60AE0A40,A10EB56CC01CFE69,A48D48667403A14E,0EE6D876262C11D1,D327606943BD612B,3FE33B973125D813,00001B8C05C7E89C,F2FB734ABEE8E86C,C27CC6756D5C0C4A,E271D69A43F6D5C0,B2A6F227C50C98C1,797852F196B1E8F7,0DC418D4692D46F6,F13E92978B5FC44B,531B403CECF7C717,CFC09DA93F2C32F8,EA36699B477CDDB4,03E077B768F72E51,00003007D7A74623,644F377930727884,A590A2D007D1486F,45938222F133551E,E7B8A03ED47A28C5,D4C3CB4DE564835C,20BE8E85D3F80EEE,9F131555BD967697,9C3EAFBEED4676E2,2AD579FD50E9B1FA,44FD13A02D8D9441,E5CDED662420E09B,000007D9BA1C1663,00EB15EEAE32D815,085E84965DB93181,4B4C5788B1674A99,D73672B8EF6DD0C7,FA10D30F63778583,E06DEB351148B2AB,774A7841D373E8E5,A47815397953D993,BAB718EEE2D1D537,C5D10360A9F827DE,0DD2C5F12EBD0668,00000BE682FB865F,DE12E9E94617DB2A,816C3E5124471CB3,CE1CD1C0F01EC62D,DBDC3B4A25EE9A39,3958511F510F781C,4B78A72EB3541378,AFF207F198F7D492,7F7BE9CFFAE8E3CF,4E6B3DD8BBF20DD2,63A8B7D8F05AAADD,53734097B77D1604,000015CF1EA9E8CF,2BD372A4841861CB,D0F404A3F0FEDC23,318505E0180B4430,057AABFEA219F760,D23199B501DE28CE,9769D412F60BE24B,62891F0658B109B7,D4A21620F2351B33,10D2E50F09F187EF,9CB9D09B4F3E3179,7F54DC1DEC456B4D,00005D7FFCC7A0C1,50515D4DC074771C,07FDBBFCF76E8A94,36E9121103E571D1,4D8BF742EF50303E,2A4F186F5B9AB58B,99FAB9B5A0D3D552,D57CC1DA6F4DA1F1,8C065B1C59E014BF,5434ED33F2B46B42,17E5063D2DE3C014,A9ABF45C3D7C6FAB,000057B4A8EC691F,9C0694EA3EECB0D2,1B9A2DF30AF89F89,27B34019EA576432,8C50662FF337EEE9,CDF6FB6D1B06F6D8,581FD97CDF8C018D,4CE448631D617506,3A9272EEFAB145F0,5E22C206B9F60914,590813B0AE627004,93C2A83EFE391E2D,00006EEFD66E8673,CFCC1AA3BE42FCDB,4026448B88A61492,9564F1DB6EF74D73,04722647EDF13824,9D54A3A20F1E4C11,298EF72F5668B149,EACB76EDE96A9097,948307D89463C82E,1B64A2770D4EF2DA,9B8C6ED87C17182F,843E6B78C200B111,00002C6AC78340B6,D8078B7C9475D113,C1ACF17F7F5C567A,D3C71E9AA94C8ADA,60DA9D0AC89259DA,03C4BEF50BFD0905,C9BB9268ED3E0F64,37D7E4B14FBD48B0,B3C96C996E728478,C6E02C0BBC5A0DD5,2C6FD29187FB4B65,271AED8AD2B4B773,0000164B5B99C1A8,4B6CAF441F2CD56F,EF9221D3815F4288,A2F09BCC119BF249,756D73E20919AF95,1A30513365969258,C707FB7AD93F7327,3250C670EC69F3C3,79BF1E7E1B4358BA,C33D20BFBD6883A3,4575111382228D8B,EA4BD3B29549A73E,0000368DB3773156,B198E0A15068941F,5FCB4DD26F7D0E20,A4D15223F9A46E51,DD7AA553F6244604,1E64F445ED7382E0,7225F9C56B02AE2A,F9EB3011A7D7103A,4B0198F6971993C4,128AF0AA4D0087DA,0EA3B1014853476D,141BC2D6835C2440,000047BC304B1119,077149D26F0EFC38,2C047AF3209D9820,3E940D185AEC1A96,E5B16052A0DBEBFB,CD87E89D0F7C5EDC,ADBDF618FEF4F4CA,D2E4A3EF1B2C616C,EEC02C4AA147AAE8,72D153D42B757AC6,518AB03A35CF1153,CB03AAD2A954BF40,00001ED4E0B000B8,581EF110686C1B72,EC2404F508352414,D10CF38E501098CD,F7C70174971940BE,09D5A9669A2E27F6,D899AFFF7423ED68,1C7B82B7980B71AD,A7095E6AC290CAEB,FCFF8F29F394712F,16401329DDC3AA51,1116FBE80E57E5A0,00006CF10744BE6B,0FDFE7E6D875EAB9,08617FA63D3D62B1,AB7EB3DEB2030A60,2DBB65417BC8A604,8668DA25499FF4D3,37EBA0D05095A2F2,3A588ABF0615C230,3734386FD97093CC,D41217035391D67F,646EE3C2BB610036,6497485A74B0E913,00004980D8E60FDF,45CB3AAD80F37B4B,1F6C0697AC0232A0,7709463AA9789DFE,BEBDCEAC22AF0641,AA966E45EDD567CA,E46E566279EECB5F,0E085577EDDD6F9C,E02AEE73C99E9CCC,3E6703F1A095345D,F42A2C03AA57D4E6,79AF6ACEE0296692,000046C66915398D,A2EE0B500D293133,7B349D68F1B23551,22D5A9F784E5F4EF,4F2B88A3DC566717,AEDB116C9BB6EA08,FF046D4BF07C3DFD,45064348209EB8AA,DD89F7E3A28DCD10,90B3070B2C885E1E,9F817CAA12ACAD0E,C1ADD868AD2206FE,00004C3D18414B1B,7FBF11339C610FF1,9C8E7AAB513D4434,71DC655558688BDE,41BFDEF624889393,8B0C8587CAD759DE,2DC4A6874B5BF96B,F2DBA1D7788D277C,34CBF630F9C99987,20ACBFCBCBF84835,AD9196E284DB9836,3B2A3E45A7A374A1,00006AFA0347B3DB,AFDB6CF6770D535E,CACB7E07D4D89B1E,3289C5546E30BA00,B6BD6A14EA6695FA,7FDCB00DD3404699,6581DB5BF5E8DAE1,EB8434A73BDCAB92,1DCAE6FCAB7D1310,F416FA7EB1EE7285,60656DB51CE55F8A,71F382F8F0043604,00006F106DA72D44,9A71B670D65DFCB1,10958F42B106FFF0,4B6542397E19C58B,DB1BB0F586819DF8,4DAE8D8DED112A3B,5421899C475957F1,30FDA6A0BE8A0288,45EBF798AF002AEB,91FA1C6422FC1847,4801332658E69D0A,D88EEFC74FFCD8EE,000059C2CD2E9944,395263570DBD5627,EF53A9757703DF4C,FB6006920C04156C,9B791DC0463D7133,209C0401592B8BB2,472A2BEF2C3F00E9,A83C184A2E4B5405,5B53D6A28D3C430E,02717A2B8455D767,049C45913A5EE4A1,49FBE73F72DEEEF4,000022F1FC5AC06F,FEE4E375194556B0,8C0029CCB6FE7779,FFDB61A20F236A1D,661C1103B1092331,0070798D404546EB,2AFBDC1E170AE851,4A8A307E9DC9AEB2,5795DE1F281A9C34,805B852CADA17372,1B41671363F98DE4,00FB74D9CC6A5F38,00003731332CDFCD,938CBFDCBA327464,4F17B29A37543F28,D3B0F93E6AF36859,CCAEB8793EFBD04A,6C81AFABBCE950A7,680009DF56E8ECE1,3A534A264860742F,5E89ED27FED48E04,0AF3EA57D1CE9C09,379CD7850053FE1A,ADF828177EC47013,000069359C48FFA7,A9C3A0E9AB9FD900,AAACD7935979626C,85EBBD9A886CDB7F,5BD0C0ABD0A88EB4,3FFBBF96EF941809,504FEE135CC9B98C,FB759E7C71153E45,7F96DC581E966831,755AB8231673ACE5,9A60146052AC77EC,28951C008F6A05A6,000003FB9BFC6348,B24C617CE7FFD23B,D656C66D0FA8BE88,959B5F8B9D57EDE9,D1AB1DB9CD667C11,94F7FBC75E2EA1DB,6040442C09F1A086,3E0F5CB8C0E74CDA,205B10331DB04D75,69E309938B820B49,5F4D38A8FA897E1F,38203DD813EF7666,00003F25FB756117,CD3FFC0412454005,464AAFFDB68A0723,210B437B2B9CD68F,FC7217096E03646F,7E8D08A5BE60D9BA,1F10BD57C15A4294,4D9684E31921FB57,5B2BEE4D8361171A,EA007A4E35CE0223,A656233E93A426C6,E0254C1C02DBD656,000046E4124303C5,83D2FE8A052EA090,067F8A2A645ABDBD,AE6114185C1DA29C,98E62B23E2E9B312,6FAAFAD1506EBE3C,557DA85CF10F1394,C0B3CC6F924463F7,D2FC36BC15DD8539,7957E830C9B883D4,D1F150B6E163EA10,A4C70D4A79A66651,000018B708FAF8DE,3CB4FA4FA4366D3A,230DC0C78073AE15,35906BB42F21058D,0827530C985F42FD,070A7A8D24A68964,FF8D88D0B7288F02,FA4B22F9EE1E3639,A0CA07B0F0407A8B,A47E5D94727FF6A2,2C661C3657AB8FA6,B027B023DCBCB0F8,0000625F60022E0C,980FFF865C2CB629,D29263BF54C770DF,C4C5E468EC240644,E38E2666C26A2123,98119195934FE155,378A856B0DF0A76C,0AC2AA7042AD62FF,614399A51ACC42F2,A1B0F1734B7BF947,8D693D638CC37C5A,DD5B030AA92E7FC2,000045E1D516CCC0,B3E8E78D48178503,779EE6336645F217,E8F99B19CA8FA4AE,AA24C5B95EEB86D7,A06454BC663EAD33,1EBFA3ED92B54E92,89CC20FE3A8B8089,7747005EB626B9BF,7B42150761FCF99C,4FA71C44DD3AAA93,B87922D1649FD3D2,000053AE65CF0693,50D2FCCD66415CD7,E14CE9A8CF620524,C190491640DE1977,4E52CA10FB0D818C,2F4AB7098CE097C0,29C23B9112E890CD,DEDD4739F5A2FBF9,E35AF5D5BF025B41,AECEBCC3748C3E1F,446B45D47771A574,3E776FF6742F8DE6,000010BF646A594B,65BE283BF0DFA9EF,C3AA41475BFB127D,AAC4C12790DEE76C,6372EC25B52A5CCF,37A3DF86ED0745C0,1DC4E4740BE6DADF,788BA4D76D3ECB72,B58E38FD4C339BF5,1897CD4D23C93E62,819D0791C2BA9FD7,15FD5F22E54300E9,000064B30AD6F440,CFEE6A65B6466E77,A302CF81E5020E5C,F9C78E04A724A77E,87361FE025EDB86D,5AA921B6CFFB7AFB,360BCC98FA585F47,96D14C8C2CBB2EA4,48D0816EAEEC32E4,7F6E4DEE387CD03A,C1F24784DFA6FD38,08ABC413BACB5CE4,000009C3D77D9336,89BEFC2D06363C40,D6541972C5145E88,54C03E7CE4E362A2,1D51D68805B46D26,F1A49901A5744170,5AA0F0DD369F2C0F,A1547827BE903F39,A557949E2C12E851,739DA66FF49135B7,40A6B07FE9F52EB1,6F4EFCAA3F45A38D,0000292D96633AFC,D135CA90540099B0,78AF6A022ACD48A0,34C076EBBD0F305E,BE9FD3C2F2A27147,E9F1F186DEC9D54C,7A12A97C7390FB48,352BB58F7BBF2C03,4B5FB1C708680DB6,925D8276037466C0,2AE6F7D15B464295,BC6C6B1F0CFA2555,00001751CFE5A5F2,12B6052CD5F08282,2BA72693FF4D6176,1E8229E0D8D0C030,641FFFCC05B429E0,F4FF83DA680A21FD,1D27D4863061FC11,91EAA59D43B1E657,012160B5146C230C,07DA92B2797BE361,C00698B1CA46CA04,E97D2C1CCAA9C90C,00004F8372827ED4,8CC4C664F491CE86,2D3BFE74571E788C,85A2F05ADDAB1EA9,C17EAD72747BD4FB,6183F9A529D20382,EC2C988244991136,0D532C939A1CC430,BF6206611B03C244,6D0DAF987C3963E1,A17631E9585B9920,94491F176857C7DB,00001B9478AF1F64,6F05FDFD3D1623E1,C80CDB811B379378,AE8A5F407658B796,30B9C0A2A527F752,2D18A8B9ECF77CCA,EA11D01E6C6E5AF6,4951C9E4D3813806,9CF7DC95FCE447E2,BB82AD2FAEF0404B,69DC05214A3B4239,8A92F0CBABD57149,00001CBD7077D8DB,B5C1928CBCB7C805,01EF6A0B12BF5258,CC531D36CD306232,59532A6946C5D6D4,AFAA47DD9605CFCB,E36A7244A4EC7D97,F5B54ED19B2BBE98,58177DD05E0C8A63,4295C7F08CA10D67,23F5EE968C585B7B,E3E9C5DF2E928F71,0000647EFFE0659F,D8794C51FDCB54A1,11CD818EF02CDBC2,35D385B2984C91F9,6721D95C7A808EE7,F454C19883607F06,BCCF9496A700276F,B14779C1B81CE1F8,9D64243102552EFE,49ED4809B3CE9D33,5525D6070DBFEF49,E6CEBDAEA20B9DD0,00003F8AECB4D905,394DBABFE2C0B692,D61D4839F58BAC71,B60831E9558A34B2,226C08368F62D925,6313BF844D6FA6EC,6D471AF38EB30F5E,DBA7FA2D0C2D0143,6FDE2AF139717777,C9E218D28828E5AD,92338D33025C09AD,E6F117215647F12B,00002B7FCF4D6732,A55EDC9440732E9A,E7E309B34AF0FB50,876ECC47D912642C,9D123B81DD3C33C3,E02E1999CE822031,0F938E291000C27B,C6E42816B7171033,5A14CC946909E520,14EB3D5B1BB33F53,1F61E396D8517C28,13DE166C43563665,000015E51040CDB2,41B525E741B6E965,96EAC79ED515A25E,36294C28BCA1203C,A598741532DE8F23,7B6829B103024CA2,581C01C7318579F7,05880AAE6E3D4318,2BF27C6D4CA44C19,77D3A52A289D76F3,5DE21D582D664BF8,9440ECC2D8DD4703,000036AA7AB7B73B,DCC077B7B34D31C8,576446E156ECF07F,B12BCD6C757F0F53,D09A69F7C347ED1E,D1432A5694F098AE,B79BFB2A5380CE87,CB50936DA2F829B3,50D1EE2A3AD7A2CF,F306F7D20CCDEF60,735D315C7DB0032D,86F9479A6EC71F48,000000C407BCE7D0,22AD52A481B9B223,9C24AAF2A40147A3,FB26E401C8434FC2,B07FC5048790D2EC,25B8442785A9BEAE,E600A85A1478A231,CF1210FCD5F550DA,98F269FFE8C5C355,3A9604A83875CF0D,504C881EFF956278,346B1D0CC2F36CFE,00006F3A2BB05CD8,40BD271AE720CF66,B9EB4181FF187BC9,D36FC9D776E17DCC,8DCCA7E787C67A95,73899BD263B3070E,8E12FB79F9665841,B0E50001230AE690,537C99E90978E398,2C6F6F395A541051,926DE0838E0BF69D,745B672548960896,00001C11A67A821E,A134407C76809FA2,44FD78845EAF71E8,C785634016CA3623,691D5DBD74A9A363,30646566970870A3,C7F7C8171ACC87EB,8ED8486A2C890A80,12A37A458D9626F0,DB0AB6414965D724,E53C035A68BE7DD0,6FFCC2C9A0919414,00003B889FDECE4D,D545F8177848BEC1,6132F553B62BE692,2BBC52F2AED086C5,16D21BD5570DFBD5,7E92684D93380A93,1F8038D0A7E013D3,84CEE312A8652830,D4E2700D2A85D680,B10297C33F9B86B5,960A1324850FA234,61B2A8CE3CA3382F,000036A181956E67,D9244D8BB80F883E,B51EB0000ABDF5D6,4F9813E4DB310665,F616F3E49B3EB45D,7D20E9E0753CAD84,B0544B66C05F5C7D,CEDFDC4F97829EB2,E03CEB33046CF5CF,BB320AE5909BACDF,0874DC7AACEDF9E8,7655074227E64EA9,00006CF8AE8928B1,7AA9BBDE588817BD,63696990AC65FA33,184D08ECAFBA1B08,9B96A5C5B6E40CC5,25EAF3BB32F0AC89,CD548D279944BB0A,CE3D95541AC19091,BEEF3A18E8407ED7,52B8ED0A99BB5CB1,AC3DEF44AB6F1055,689BE5D9CF2B6A22,000050D5B78E5B8A,ECC333FCF8AE5188,23C26D1B01E292C7,36E71218CF0164CA,EFE503024FE58395,7EBF65016CCD1E72,85AED883C53D016F,FE7061806CAFBAF1,405DEE439B09B08C,6D7560F82B66E22F,B2804634C58F646C,CD18BEAF9DF8B3E9,00006D0EC61DC3F9,4163C5944F0F9A7E,3A0055DE44A8460A,966F108751639ECE,DF4D00E490F7D54C,A8F21076B200ACCA,6DA8F232AAF21623,27D1A1A352A91E3D,E7D6D56C6FCCA194,A36393A9B318DD6E,4EDAC9A0860C80EC,26BEFA9AAD53665D,000065E1B507A5E7,C78B190BF30B5AD0,6A641ED702C6F3F3,6D11A68D5E3B1A08,41727DCE94618959,6433F0F2FC055C58,A770EB44C44B9DC7,091BF6232DA4F7AE,E8892012D31F35C5,56D03C99A99DB182,036FB3A49DB87732,4D08A374F20F333D,000066384B489071,1CFDB8E0E8FDADD1,89B2CD455065017D,8F73632E68F02E92,4E080E0DF0C3BA19,6FBBF9932DC8109C,2142DFBF31760DD2,12EEE0D984A14590,061DD54AEEDA9FBD,6D4D3DEC7C2111A5,48DF3E193E357C1E,BEACBA8DCBF127C9,0000066E77F7D108,B4614AAF0E76AE66,84CF52BDB4AB9807,3C7278E62537DA4B,D5C2AF5BB6CC4E55,8E12D8185D12339E,716FF6CD7754D2FA,E5C67418ED5E465E,71485978C22F5C8F,ED65E94734417266,0F87EB744AF5B355,165441A9558F6507,000041F1C8EF9BA6,A30DA88E2F05F8A9,29F9C1AFD3A6E260,3DB8FBA2CE40E2B9,1F9AB6C4F8C3EFDA,0ADAFCECD84EE2BF,25FF952291E31709,6CD3AD7CBE652243,8CE0E0EF62BADDB8,A3550132AB76A2E6,EB13E2D9A2FDA673,5B297351130F325D,000048B30F10FDAB,9DE6744DF744A8F1,A66E626FDBEA8921,D79C07359E31D85D,4A9E5139B2CEADE5,9860F39027D57686,F9A87B0F3C8571E2,275E8A9F2B84809A,2A14C30B3E6920F4,BB08A188F9973C60,75B57251695BF64E,A02D85579032BA1F,000051A2BE1BCD87,989A954A33383B2A,D76203DFAD94B654,3FA33F9A9269AB57,837A1441B9A4D228,BDCB671EBDB4D71E,9F6F719CB39E77EE,921F31E3CEEF7C29,8907F8AC8277BD0C,2805E57BF005B237,1E802061E91FA275,2617C71F2883A3F6,000051401BB4413A,F34544CC336FE41F,FCE2D19D3427DADA,CD0A776CE8A3B15E,DD98CEAB285120DD,D9C65F3976A8C0FF,D9D1E9F2DE3EC1C7,1A1A2135687FE6B9,0BDACBF26FCDF178,6EEE5BC78CDCE93C,EF42912567DAD0BA,F07F4ADF49055B7F,000051477D5F99FF,44E8AC1E5A62C61F,5DC3C6E137449EC1,6062D69CFBA9F017,8BE3DA76F0EAA000,256B1ABA5B33FE60,2C99E5D594C53F23,7A644E0062822606,578C016ABFC97514,5CB72F69FF3B3BA8,1E8F73732E202B98,9B615A56BBAA7608,000022FCFF8458C3,587161CDBAD0243E,64A89B27B5A9A3D4,E0A5296DC4FF5AE0,EC4C77E85013C8C0,D6812652F676C157,13D195357A11C5EF,7A43FF9B7FD1ACE8,EAAD25706A673623,5545B07B38522E0F,32DC17FFF552DC0A,316AF1882D002527,000055B294578CBE,CB263223B5AA849D,D4B625F7DF68676E,87BCCA0CDE4841BA,B3E763DF0C908D77,A69BE5803DBFD592,D3F535BF5CAC24EC,BA34A50F2EF5E858,2D468524F8E4A357,735CD7D60C21681D,848810B8C92E2C49,6EA17A308837FB7C,000068E37BC6F250,D17DFDD063AC17D1,756CB25AE0F2E8F4,6C3140A159C21A4B,A5BCDA3201E8679C,0F05C7481680DF28,D5C3C81631181F05,0D7319B5E6C18E2C,054C877D70064E18,31A069F06FF86286,259E898CC2500F0A,77C01A7AC21B6087,000009432B01F6A0,4FE01531684B20C9,1E1D7075711F1D1C,9AEBD9623218FBF3,DEC2AF0EC75E8CC4,92B12E3DE4BFC2D9,103B11922B15FCAF,9F2C3D28A458FA23,8D5568D062F38CE9,E185DFB63621F0EB,05477B6877C3939F,7945CEB76F27701E,00006D4F1097029E,A7C581E520875DD1,723AEB1419F1FA3C,A91E801365C64C0E,137638B2058899D2,119347FFE9A48498,21C10A4E63B2932D,83298BC04D2495E3,B8B75F997BD26DC1,2396E98784BC7CC8,4CE01E846A0CD02B,ACB458CA563B24A3,00001AD28D151488,38C14DB9811ED202,A22997B372AE8A87,0BCFBEA362628B63,E80EABBA9E1B4784,D67D750EA4DCD5C3,92DFB05D6A5687D3,0B5CDA057E660E2C,E63EB27E765E6587,2B0D951ABFE34E41,178A7186936C32F9,8A0418A8D0CEE8C7,00000A0ABAEA2821,C060D795E56B149B,E55301C8F4BFAC69,DCC00955B9392628,D72B3D1EE40A9800,BADAB13AD5AA6EB7,0BBD81F7CE8546EA,F1B104441741E9AA,095E2036B345B4EB,DCB7283BC729A465,B6547959168D7B31,BF4F185FC1D7F678,000062137E8ABD05,5E400E0DA7D00D9F,2B4D0F1F07DACBC3,1F64D1613954878D,5768A7BD62B6B50E,E1A1E96FAB7B340F,B0D82144614BDDD3,5DE20FB2C3EB28BE,3A0C0D439A5C5EDF,2A609837E343E0C4,05B107D1FC7C1B62,C76ABC7B9C70D2EF,00005D6E97B12685,F49F88CBF04E3936,C5B0C055F9EADBF0,E84D35B3EC6A621A,C0DDDFD4680CC8CE,879CAF8126CF77E9,4A7730CF7EDE331C,00A3975AC8526DB2,2C2A40A92CAEEB48,8D367298AF4AFC0D,CEF912750E747A94,7898708D25580D71,00000C25D4BE5F19,946D85740AD81AF9,0CA84C99BE641C68,0B944CC17AEE75BC,704EEE5C46B99BC4,748CB5BC4A8ABC16,6ADC465030362561,512864A2879AD5A8,2A802EF51402FFC6,82A7F234948D52CA,C519D359983CF2E2,FDC79E0DE5ABA97F,00000CE1584A24D5,CB235CE26CBF989F,135D026ACBAA147D,C3D4BDC9C8D14D33,B3A16D740D0BE90E,D3C4ACA29E1063F3,F666DA4B80576031,9A30D53AAD9008FF,63DD7960B7385383,9A4EBAA6C74BFBEC,0197947C1B917706,BA25234174A49855,00003303660D3D6B,0AD2E81A2AB9A459,D939FA85EE610577,8EED4B707FAA9C27,835230D08ED10041,ECF2D00E10732B96,3BEC722C9CA04DC6,819B396789CDC818,C8736114C0995418,899F901E4A2EB1A0,DDBAA4BF9A49D312,2B89E331A612AC79,0000189541AAC10D,49BE7904FDB87BBD,3EFAD81248342F3C,0F1692B10AF78AC2,F1A974ACA660F10B,31BAE356CDA960F4,2A5DC2A528FDB980,A4638A7EA0E69E8A,6EABE9B7D612AF37,813806A64D0864A5,B06DE30928AA2B71,60EEB00F16423DBE,00004B38CD9A8A09,FF9C667DA4B69AC8,CB982838AEF957D1,ADA03450CB86C2F5,8803852E0EDF961F,EBD2669C8084AFCD,C0AA595054887F04,8F6C731E79F96131,6E5E652FC600EBB5,B564198819931FE9,0A5EF0CBDFD1E3A6,4F2B81FB865F0CF8,000038ADE118993B,CA48D097303DA415,35AB0A1569B7D3E0,8A7B42E1D21BEB55,986623E3D1FF8D7C,7F24E87273747262,F62E2B72DA5323EF,DF1F991B03B0492C,736786A989CD2609,26604C2450F71B14,D47DFBCDA4812F27,6D166ABDBE92D7E3,00005AB1264AA0E1,BC08A0B54C053A0E,983D1F9072590213,6321C5895A640E28,BBD85DEA43353F6B,C44399E4C477F43E,3B898D04F741C0ED,04B85FAED7689603,FA74BF42D855F844,F74842EED0334811,883F660688AE2F04,D73FCAF66F9B33E5,00005390F2732E2C,A34B3EA9BD65AF8D,770C5046A92642BB,5D966974E4163814,D43F0EB37D5DB3F7,626420255E1D0D76,DAF3B05BA752D7CF,9971FB4DB0B0DFF5,2749AD9A868112F1,DC7523A746BE8F35,7C344E2322BC01A4,5C2AE321E4517CB4,0000527042308CF8,56519A57AD1EF6F5,81179EACCB129849,61177406176EE774,FB0D4252E2219769,D2C996111DF462A5,90F8C296B4FF50AF,8F59F38765EBA376,F00C3F71B0145BD8,DCD73733FEB82DC2,FBD2CD4CA441E8D2,CBFE6643E80D89CF,00004E520F8AE3C9,16DDB45D479EF3A8,85D8F65EEDB170B1,1C307EC48362CD02,7AF6FAD0901D98B8,5E44671FBE36893C,570FEBB881869D82,DE8C8BBC82DADD13,E46DBBAD4237DA76,05B765F2EEFBEE4A,4A34A188D657FFEA,A5FEBD94B4BABAA7,00000411D79878E1,7F8E8CC7123F14C4,FA13937DA0A0C0FC,77AE4FBC3F4D69FD,EC324CB150832E1F,37272E52141EE1E8,132317F2908E35C1,F92EE1FAFCAF2F78,4907BE175F3609B5,3822A84E59436275,DAF31FD4287293EF,58AB50195AA13A2E,00003C9CEFE428F9,7BE2A366DDA5FFCD,6EFFEFA82CDE5346,4DDDF2A83D8C3A30,A9F944D8FB237DF7,575BFE5952A6141E,12C8CCDA127BB37A,8A922BFADED21782,5ABE61A997886FF7,9492570C63C062C7,0DCFADBAC6A617CF,DE1B539CC6CE2103,00006434D67D3E81,E324D3A9441E94EF,96AC80E6D24524C0,1D8CFEC98A9F4401,48FC83179B6BD9B7,B516B440EDA9F99E,F9AA414FF7D0EDC6,69CADC69D5F6E4DD,9EA8508345CD802C,DADF3F8E79521D31,255E013F968F694D,546AEFA5A426FAFF,000041049C29ED7C,48A6E0026590F243,30180FA7F02E9B91,922D6282ED5A65E2,549D36EBCF3F7BE1,C423F2E9BF8DD75D,78CA2AF75F9B3F42,9E617BC80596EDBF,7879CB0AD8DD2B57,2CB89729E58EF883,BC8146F69048F5A1,8F5D9FFD9539B990,00005C981A3CA095,45C5824983E97F9F,D1E85CAF1B31A89E,C2F733D162C2C7AB,3ED58EF8082E2323,1A3A3FDDB54EDA50,A46245C25F04A96E,6A2E98525A073742,2175CE03896077D3,7A71C5B64CD0FA93,6B803ADCC65D048A,E57ED71A6401247F,000068A2FE3FCEF9,EA96F540293E3342,C06EFB884AC4508D,886D31A3AF81E305,B8252B03A72405B0,8B026E400084B098,49132463808C2C31,DC89DAC6FD5C8D2F,9762752F3ACD1D15,3A8D2809F791D214,8EBFA158734A49FD,42C437F92F5CCD76,00006EE3942FD25B,B388F37109A11382,2E2D4AB6D7334CA7,ABC4A481125927A3,411C4F69214CA1A9,D92FB354357F317C,55939EA767E19DFA,2475A62D4ED2A519,DBDE01A713380480,5F1014E075294BF4,ED25241887102853,899B5F2CC9DAFBEB,00004F52BF41E544,8E69BAE6575DF2B8,9F762A6FC1BD0E20,DD7682E0BD272A5D,2F242F8CAB4E6B99,8046348FB236EAA6,963249CD23AD54A5,BEBAAED3A3353A93,3907CFDF455EB3EE,A942D82E35CE189D,7E136C025A3C8165,84A2305B88E8668E,00003CBDEE33D5D0,F853127C3B2024BF,A3C4A22DA77A459A,8C357DD5D88DC91C,8656BAE5B2E5B03F,A2009764B7803893,CBFBA456AD5F1FB0,7E4C7A77CE93F589,724797BA163E186C,E5A7E8261C955680,DCC97A4F21D61EC9,26DB4B12D407B295,0000033888677C03,4D11369057D77963,84B20270FD8D1049,EB49C327C00A9DFF,3381F0FBBCE64546,C98F2D51D551384F,EEEC3C43078CB7F5,96506423AA4C0366,112DA2C0E896AD5E,F39DCFB81906187D,5A8D7C0857CA80E9,34E81E79DAD17D48,00005A7AD78E44A9,4C86BB6420C53A93,108D35C1A499D79B,C11508592C07B2B8,7265B91FA69F9514,3F56A73493E35CFC,D9B8A8112F2FA639,423255178DA1795D,ECC113A12E64800D,69D40CE244C627F5,8ACF9B8A1F21737F,073603AAEA7BB919,00000AE78CC0A8CD,3814086A2826555F,F1484F5517F1CADD,6380B8E0FD64886B,477CDF6E8215FE11,B19FF4D48475FD77,5B0403A43696A182,9BD6AC038B5DF9E5,BBF4F2C45ECB1835,6DEC6638D35AA62A,F4A10DB71FCB2C9A,B55825F813B7F416,00003C61F0E43468,7F07885EED96129A,655A5562816A3BC3,E39908B0ECF97245,A06BFA049383DAEF,BC69EA0475E25A50,2FC24E242C6BAC74,98B2B0C6BE478375,8022A81D5A67D7E8,9D235E6ACB417DE1,29448FFB3FE013BA,8D56F98A18803881,00003F351712FBFE,8524BD2618D3736C,E4464D7F911788DA,13222F8791CE95D8,4FD4ED33D1083F27,B1C36B5C7FDD5A45,FDE5CB6903120510,DA82E59199077F3B,C183F1C570CBF911,4763321B4A2C7797,0E11320ABE17C315,10003CFF50A67523,00000A3247B2BED0,A2971DB3E502FD96,ACC857C548103C5A,127B6B26EB4F832F,8C25120F74392113,AFDB2A2888D7B20A,59BEA4291AE321FC,1B266C1AF43E134A,A1A915668E724C33,B15D867BC7D61E7C,D8AC3FDC94047582,5C03C6BE90D8B998,000021B1DB79D68D,F27694B696669DDF,CEF32C60A6CD90A5,397D9102E95FF77E,05DFBEB9D0A6B0B5,6EDACA1E00EFB60C,2E6FAAAC35DF5BFE,A09EC1A9FBF9D289,8D1770F863D99882,1443CE271F35FE5E,7A58AD3C6928B9F4,C4E046AF1F475EDC,00004480BB1D04AE,1B91EB8353A122D5,50C6A6BA42DF8B08,F3B8C97D0F8E4A84,2140A7C7D5E71D35,E405FE1F6A184D2F,11FA65F1BA7A40D2,285A36FEFA54B7E7,FA1795691BEE13FB,649E1864ED3C8771,31F20B01A543C586,6BDC2719FB198317,00006EC0CF7209A7,88A2AA8C78333152,B949F42D0ED124E9,3F85A65563D670AE,7180A98883BA43AC,04F4708A58869433,93BF4CCE3C0F14E8,190947A5173C7ADD,B052A57D247789E1,1F825DA4C85E4A66,40CF0F4035BEFE8A,A2693E95C598F4F4,0000207BDC96BF70,93A2BCB7E4A14F2A,FFE1A12D75D8A78F,5EFA6F0346B0AEB4,A4CE99902804EA04,F57FE1CC3817A1B7,2127AA91406B60E7,82F5EA7146EE42B7,5DEF1BA9BFD1CDC1,1C2BE79C170CB43B,DB550F9205444C3A,E0E8F361503ED233,00001613CE5F0D4D,ABDE61734BBAE93B,AA681F12FF0B724E,952FDC005653A1DE,92912BD8D9961AE7,D90D67A1759AB24D,BDB0B181B4F8E7A2,EE6654002C89CFF7,F56F46813291785A,52EF987D4F1C3F3D,58E570932CF55CFA,C3CB2FE6ED7F48D0,0000634C11B870DF,E162E3906FD8D602,9257A34BD8DE9B6A,76A87F204118013C,9B9DD56838F1A340,3C04454A2D960BC0,BD33A9246E168C71,29336C7FE93775EB,A427EF0F110DDE74,85FFDEF87C0EEC6D,92EA743BA7148CCE,851E411FF4DE799B,000010420C193BBB,9A753B91CCD9AFA8,DC2939D506DBAD65,9646B1DE25253DE7,FD25DB384E2434D2,484C43B13C1FF9F8,751DE2916D5449A4,CEE78C237F8DF836,037A62EEF2D823AB,CB9C106ABF9DA47C,325E4E2D3734E3F8,6598032DA73FA7D6,000022BC0FAC7092,7D3F4413F59FE889,9649FB66F267EA0A,BD3CDDC8B1E7F750,0B055E859F7B13FF,FD25024DFB24B307,E12218C377DDDC90,CA26433A4728DACD,562368B9C34EC345,D7B4B7C5FB76E9B9,8ABF19FD990236E9,A73E24347D819FFB,000012B3A0393B7E,5BCBFCED55CE9969,DBC22322BE2C481D,20C7A1FEAD767559,BBE1E7379EB9DB71,9AC095EC74F192DC,6E4CDFBFA9226478,5838F7CD67DDAA7F,FB54F6DBCFD6187B,1F5EC0EDD741C63D,A055D46B85B096CC,79B7D635E11340F1,000038A215EF48C4,871511D7701CCD5B,71F0F38AF44511A1,5F6859D6173563BA,F26D4B728114E321,3140F5A99835A3F3,786AE04C732D1506,12557BF1201F9AD2,A837306CBF582B31,6160A9F7EA15365E,FED1673BB4F17E11,D8F92FCD3C39E569,000065E88949CC13,B547CB8B42B010C7,C9FC450196491E38,76876778BD9AA8D2,72E3AA57E5CEB3D0,DB285B5A44704A2E,4C09D10BE665A4D5,B93A77D4138A6F0E,F984B957355B8A62,0DAA66DEE383F5BF,BBBCD0391B7B805F,19DD6C033FA3A675,000004D5BB772138,DE67E06126A12721,083E6ACE2BB77D5F,FED353FC53BD3965,46ABD85F77C3A8D2,49F7EAA029FC1C30,FF36532F6FFB3F5C,E834314AF7AB6479,002E0AF1488B5F28,00FB7634D1E76AF4,8255EB91C4350998,9967E2ED480DF68F,00004218EAF2C818,8962AA27E68B7F0E,602894D83ED5E432,CC2F636DA1841339,910E1A0E7D8CDC71,ACBDC02F76CFE3BB,CE149FCCD0F33DC3,1F079B5D87DBBE04,59948951947E592A,4C63BBD78892237C,3D6584D1FEAE8795,96FC3BA0447A171D,0000379E20A8887A,66F706ED04F229CE,436046BFF9FE6CE8,C8E162ED73C2ECD2,C0983C1249B85FEA,0583A7F5BE977A36,F3D18A463A8FFDC1,1414E93A74904C93,F1E59BE8364F1877,9C45D362D974E6C8,7AD33DE71491EE13,34012423D34445B2,000026AB054D354B,BAAC0D62A987D957,4691856C87FBE54E,7C4604265DF0B902,8C5B234711568AB7,631FCC48D25FCBCD,503770EA795C6459,A058AD10D3DF016F,72F972E8EF524471,3C4E879198B5C4B3,E78B328FD7146A73,C7324803DD403270,000051DFB015FA9C,57550EFF6D5C749C,3487E30522D20E40,841C4078ECA95D8E,05431076FD65DAF3,1FDF8343CBDBABAC,05682ED1DF1BC054,A22DF6765A5FB904,4EA36023FCC50F59,5F283F7F0EF2B621,B8A7F41B296FAC68,F4A2E6F61D1527B1,00002134181CA436,8744DE128B1C0918,668057A305773FF4,AB158AF75A6A067A,E26E58385E0A9F04,C366809A41D4144F,962DF8EB270DB01D,01CF77013F1369C7,46A08970EF6BAD39,5065B2C0FB94ACB4,E44C4FBB473B7394,C5DC64DF873C3C18,000012334EF0A96D,C453E384354B4F59,A67790C233F6666C,09D0D302CFC96C9D,1405C52E10B019B2,F6F7608CEF67C3F3,C7AD9472E4E373F5,96792B239AFBC127,D003A412A23B06E4,131603E1D09CB3A0,9A2B1CD681851AA2,286EBAFB7D95E14C,00004E9C1DD9AD3A,7F6203A089A01BA7,6917EE5355A63B4D,F4A772EBE77A0CC0,A7DE26D8A42A8CB6,FB69F77FE51B73F8,77BB6B5BAEAD121A,AE29892489E2D9A6,07C7B1C2B6E9DBEB,676013F9CCE587AC,EC8AE3D4FD73B987,99E50C24C5142CEA,00003F38CFC4505C,B41DA8244D8872A4,36B1DB661CB4D2C9,92FF02B3E5D0ED2C,1AD7221C0F6AEC54,8909B22655434B78,366BAC4E3421FED4,C084F55D0F165B2C,9177B07B58DE68B6,4826B1A29D3FA16F,7D3D083543E0F337,E5B44B3A7C6BD606,0000121218996F5A,8E353279F7E9A608,1A3A4A657382C5D0,AED17277CDF714F7,B15037ACF43809B1,14863ED9CE9D7377,5811C8242EC77A06,49E1C584D8112DD9,F496BF719D3A58E2,DD5FFB604F1D8EED,2EB66A4453C3E874,E9692CAF562797F6,00002FCC26AA0000,9BFAECC28935ECF0,61BCB062373F34A7,4605BC2B41A00BBC,C4C7ED19E19FD897,A41C54405AD41B7E,D403EF1B90128D1E,FD2B3A61FEDD3AB5,6345BAE9E2A0F810,FCB152B0A72AEA3A,73D5437B03254643,CDB8DD6A909BD82C,00006CB9C7084278,951A0992ED790DE5,86496544E9B19C67,5BBABA38D55B45A0,82D0CF5D750F37F8,74303D8034F6AFD8,0F9DFC2472B4F475,C15498B855AFD61A,C2733324A0370285,899C8DBF314F9D06,FC2D6B9EA6B56A99,306CC433C16ED0A2,000006ACB456DFAC,99C42901800259A0,28CE47A0206461C5,ED444B78DDCA539E,0E9235053B84AE6B,CF9593669C435390,D9EB4ACF3D7D6A36,21D817B99C55BE61,69E03F95423F3BD8,DF0C7A968944E2A5,F36903C1CBAA7FA3,59BB88D7FDA8EFC0,0000467D1C6D2A2E,078BB64A6E332148,49702ECB49D9A636,FBDA17EEC2AC7C37,C0B8C4D8712AA86F,C98C1E46E2E152D0,6C8273E986752EE5,25BED35E41F31AF0,CE5027D315026F39,B5F7AA59F2B7677B,72CBF42D3E8F4747,2B2F13FDE8506A90,00005144A03236B9,91D2A7B98AA794EC,B790F3F097844270,3BA758748D7021E4,E0503980A608D191,7E35A17D8B9662B1,8026F715D4C1077C,3C8508966EF66D56,6C76A48642A32435,C1C9ADF557A4D73E,36E7CA134204168D,483433D8D1B05D3E,000048DC57BD7042,5F524480B267897A,1EFE35D5B39EA7A6,302DF596E7020706,C50B7956B06623B8,5142AEB952233EFA,9C59399279A2F83C,CBF519A74E59E0BA,6D2219EEDE4B6859,EDB28953D3889AF4,20A771D349C8B981,2DE9B0425DD5D72E,00001DFC8023D0B6,9EC8015354F14157,724CDB9266C9B7FE,EFAD6B113EC64681,6D894CE3CE87DA9C,7E0B3ADE4DE98CF0,C68B6DC056DF4CC1,FDC02B4E58D9EB28,F46C19CBE0FD7C98,AB5F62CEAB37374A,65152B1113071C88,AA36C70EF1C5E28C,00005D51146B4F2D,7B5990D9F6E5717F,0650E64ACEDF20A7,280920F16558BF88,1968174642F33542,C71BF8EAC426E3E3,863C0E520FF918FD,DFF0410A98E3FA5D,1621ADF164531B14,BA5D14411282B228,0C1BC6C0A6F124F8,57FF99D57827540B,000034BF3AA4F222,F4B3C06629A69C63,33B0C1313331F0B6,543C8332973B5DB1,D619E382D397B88F,5226D8255E3B65D5,9156D06C754C077D,B10B047B78EFF057,B81DE7ED43EACD72,4C3B4A2E97B3031B,1B6498035411C8E2,1CD349F7A869307D,00003029E1BEB027,3A5FF8B1435E7CE8,4BC27290EBDAA3F1,905896348E5864FF,D6967080C6DC8862,2F757D46AF51272E,69E35C31BE018E42,D444D9AC6DEF662E,14978DEDB109A50D,D8C67ED8B51B8BDB,E166D268D874C31B,6882E87C1B56E570,0000368D47B815C7,3E0D67A46B06AE57,44BD15F32690CF58,630EC548830083DB,DAB1324999BC2BE8,130D5F2862B0A5B5,98D136E63FDF95E8,5D529B71EBC136FE,3F2F08E2D3CED33D,6437170438152EFF,B92FF98AE0699773,A09F59EE3E1F48CF,00003770801476B6,8BEB371C60B366D9,8932088F26C58475,F1354ED9D864A77E,4521A8189CC8ED5C,9EB93F42C93348F8,5395D1FEDDF4142D,F95F296A3C646FC9,EAB4DF6C2B65740A,32CD8807ED4B652C,D4EC0FB2A12952DD,B270A56C0830DF70,00001CC13C012CC2,51EA496CBA7CB94B,A555751131BC10EF,B4C1C30127BB28E3,85421D1D145DAD2A,D77ADBFB0675D1F3,1A7BF3DC29F3CF70,6273E443FD9B3D10,3CADEC40B3F531F0,32F9E70DBD182869,53690A35C177BF4E,98CA2B9B3C64ADAB,00003FF69BD64CC3,690E9021142155AE,6F299B74FC2D6FE5,D010E9C8F2F9C1AE,416EE258EB161A4D,D8F94313348BB7CC,36B0CE9C5D15170D,AF154F3B51B13366,27687394228542DE,676694E7150B3F33,CEEB0FEE7909A9AF,F38BA90C13D7CE9E,00002F0B78FA7B92,146368A9244352D6,D225B4ABE2E181E1,16FAC8D71813BA3E,3617664B74FEC49E,71A824F0E9C4B97C,FCF9A93A85040E38,1A7B3A6BB71BB04A,500352F6E79143F2,4543B4ACF1458F9C,12EF4238E863D50E,61A595A9528F0D04,00005AD21B2EDC0E,4F6BE4B1449C7779,AA75A579A6814BB8,B037F2A854FACD9D,E7813DEE6BBCBE64,EDF502E228A4D4A6,16D0DA0C01DCECBC,62B14595BE851DDE,C8D9708690FF3A9C,28ACFA7A73CBB35D,DF27D486469EECBD,CFF5200C20B07B58,000061667302CFA9,BD9A615B3BF3E4F2,39A0F95E2B458E84,FD8249140FA49B70,9E192B4A5A239506,3C460EBAE59E5A07,646FAA52CF8E0CAE,2DE1E08AF76DF649,79E3C0442EE80429,F47992E0814B0A47,F60C52017FE6AC51,D298532B07C8AB9A,000047015DE647DA,9ADBACB76D87E418,B8DC7A0B175CA89B,C9264C03BC5CD9AB,84367FF518EB9CC5,3FF8139E8495AC51,B4FA1E17F45068F8,74EB7180E61FC2F3,EDB88DFD65CA4B5D,618A5AA3669260CA,A61ABE98A08C0376,6B81605BE839E52E,00005A69125EC5FF,9F5BC85FA0001E0D,2607F9EDF4C7F0F3,00F24BD5C49ABF6A,B7053097129B3DF2,3BAC8671622F17F2,5F46C2BAF1258C84,30F905A0E466A8CD,3ECFCD843A30EFB2,AB024E3C6ACCF521,307610D12753DA7D,5A3DCF35E384ABB0,00001BF37AD71F90,AEE79DC410DA6D7D,4ACCEB8D519A2373,9CE213DAA8DBF370,6EB97E5015406C00,65A5B199C2DD5DB3,CE40492015D0BF78,6841EF24B108D0FD,31D0479A393B69BD,D4F8CCA8B5130CAE,319F6A8B3FFFCF17,EF87180C4CBDE3EA,000004284B8AAA95,CCCC8AE70F611706,B7318A2D408571B1,4720BB64D0851D8C,EDB7EC00402EC203,7997B469F184F7EE,536899F1B0E062AE,0060C7D702BCBFB7,7ED69416031F6B06,A27A97C5CA268983,F92C1F86363D3F81,7E38D42C64C30D24,0000292A43C0F87E,25FE60756CBB165C,EA670446592C4052,ACA89B99ACAA3B68,F7F648AE0EF3FF70,034F4A2A0458431E,59D8E7738D1A0221,DD856EF01194E2E4,A76B975EADBE445C,C472A9EB545446AF,21ADD6A841265D11,7EB050FBB04E005D,0000201DCA9D5E6A,B9BD0605F0A1B66A,9821461695FE9CF0,8EC09F6A29C22736,CA89A1EFFB6929F6,BB7856A019C2445B,CA5BA1815D3FDC98,0F928841FCB579AD,288A09E9ABE91C9D,1B742BC8AA803897,A313E3CA795A4F5B,07CD6C559A9EB9D4,0000646D0735996C,FE9DE6DC7F0F8F45,04D2D6148A7A4D19,DCAD33FD6603ABF4,4360A281D95CFED2,BE9B7A1E5E5DAC38,3F1F253FD4556050,426D6807EFD9732C,F979841BDD866BDC,159552B8D747BF72,8F8B26612C22BD4B,B741A120A1AA0142,00000A00DE41D1DC,C212793385CD2D44,85676306414BD602,AA7870D625F8FF18,FA74DFA7EED25A6D,7251A13961395E85,C736181104B362B5,3BDD977497D6311A,EDA6912C9C3DA210,DD1FD471371438B5,081C023A248809CA,8D5B7E23E0943137,000055A998350A03,051FF7166C83E6D3,1C8DFBA897A6C167,3209DF69475B54D0,81ED9BD2945DD346,51715DE6A1A0FAFD,ECEC047C817F1AD8,D64D9FEDEE21E1CA,916DA6EDCAE136F4,54D63109BB85769F,691D2D6D2116B362,E5368A127E62C318,000012A64FC0C678,E996DFF08CF4812A,39D121871CA603F2,12CA60B3FBF3DB64,CCA127A5FE15EF21,9346692364877D93,8AFB21AD69836112,748E4D4C5B7C5629,341F4B8B144F7D58,CF8E9E345F1AAA5A,3A615582CE7CC9F1,B15BC5AB4A65AF48,0000094E1D154D44,53DB0C9C1623B0E6,5DFC5DD74EF2ADC4,F77C109830FEE57E,1EF58EEB1ABD41E0,26FC6AD855CC76D3,DD9941205CDDEA68,3536C18089041610,841C2B5DB24592A7,592079B390DFC620,6FD0EB47688572AF,50914D4B499E191D,000011321DE183DF,6C425A4B9ACCB62A,E06DC05616B0D501,0CFC7A9849A4F1E2,70BCA71F62D4B59E,EE3684B1F1E1A8C4,D4B1AE24194FF93B,00B0C80D4565FD96,72EC7D89C09421DD,A01189F26A8398E8,A4BE1720FEE10D67,A6E6713B70E6D929,000058D3D52932E3,4A1F278C357CA84A,12D1D6996FD75B0D,D18E820B4F61027C,DB773E17BC27B7E3,596D6F361BB14E16,0C4BF83D9C35FFFE,296E76257E6B7720,F5DEF243B5797178,33FB97D695715E3E,50ADD4DEEB4E36F2,2430B95E4203E497,000062FC2CB45500,1A7B58AF53054E4A,93413CE96AF4E5B7,08BBBBDBCE802689,2176389BD0467720,844F72C3EA055EE6,5F2A1B6540AED18E,844FD2753FFCEC0D,872775A123F6C7C1,EE2A493F6CFCBF6A,4C3396531E0F6913,87C091F435C68C88,00003CE8A252FE4C,D050E977685D30B0,4D5ACA294914EA65,2EC8917591E1F542,CB41FE34AC1F4459,A51A3ED00CA9D20F,7BD7223218C21011,DD7A3C5648F73C88,3B9E685AA0ACF533,38C325C4AA7BCD67,22BDED7792AC9D3A,84BD0740151FD574,0000507172F70979,E747E516F193B476,1924A67A956A5C66,6139CEA9B24C57A9,C592A2D6CC73EA1B,F4EC330EE4920DAA,248780453DF8C467,D8F9CABE8A318FEF,DFA4B110708E6903,6774B861A33FDF14,154E9559C3AF21F9,47B1CA4EC5AB9836,000062929B1AD32A,C471253EA1B43552,68901E5F1FC5250A,A597C9D685952BA7,100A5B9435695A37,69FE85FD56918623,DA5CEA046B66E2EA,A35C61CBB8E67065,B4D044C20C436F50,3180EECACB633852,7184A1F6C25E33B7,C66E87D57DFF1381,000044D833CC7158,6183E6A531863F80,75845548098462DA,1E15CFAF9FFA99C4,5F64CBE400FEC61B,BB8D90641DA56F9B,CB536B64C97920E1,086A2630C0BEFD87,13FF99C9EBCF637C,FFF6B6757CD6AEA8,5CF2AE501AE47597,12C532252A9BB3ED,0000188729FC98BE,DA1C76293CF43FE5,6C899BC605253170,DA1955468EBA7BD7,88E6DC3DB23BCACD,BE7C6EA12B2BA73F,163978B1E0636675,B9D2340FDE343BC4,E9CF4F78DA367F35,8E9F2B622D3C907A,3AF12C2884E66AEE,66807BC88BEED5BA,0000355E7590A442,FA78D087876E9906,9729C9CC875BE0A4,ED08F9B5C40B36B8,C7E4BF7D7853F18C,FCF073828588E2F0,0916D71F857ED1EC,34ABFEF58D5AC316,D5A4458C10C29DD8,50D31699AA71B500,EFA13DC51814EF4B,C155F1B8C3E9E920,00004E54E3823A78,A67C9ED66538E357,C193186345AFE9FD,746DDE81F61CF9B3,D6EE3561AC221F5E,8E7C8598CBCF4D45,4AFA074DBD377A7C,6974B4861E3A3F57,182E9AE860280444,C919F383CB47BF5D,78AA975862B83EB4,DB59923F37CE6341,00001935A51CD5C7,D094871CC582964A,EDC443AE19484745,9F46DF1A2DF52F78,D0372E7D503C3117,A581C78A9EC80EC3,811C99EE15A9DDB5,5A2E50E45440B544,78A04504977B5B67,9E1DFBC2172179D5,C6172CA4A9A287B8,D9659825744573C6,000052364B8EDBD5,BFC31321168A796A,30402AE6387BDA4E,5BA5840CBAF79A45,DB109AC51732C04A,1A94330B03BA86D9,69DCC720FF2993D4,A6F92E71CCF79C35,0DF75647778CCA35,E1E54D586C645308,9319096B2888CCB6,FAE24879F9B14565,00005C06B75C0FB1,64756E05158B99B4,A69942B06329747F,0FDF367481AAFC43,EE39E6849B415C4A,CE90B329508C6D73,F6DBE78A970A5E63,40F188B2F6FD3B1E,6BBE0344BE8376D5,671001CA5975B67A,8C55398DE38E6142,3FAAE8537D0B801E,0000648506CEDC13,539DE3B4300271E9,71F691AB12CBC15F,356ED53E2BC16519,0948E8DB0AC1B276,4D5129D3EEE40D7C,DF38FC40579E79BE,BBD4365C7023483B,A8F3414523A10BBB,C98F7DAFB7F22CA2,AD52B62FCC7C2878,A0FB66CDD70E2DF4,00005F3130D96AA5,AB34CA52BD8B52AC,D1C259BB767E75AE,803C89C538029B98,1B4EF3B6ADC7A2C8,E85775C1C535F567,7CFFE6D721F148D1,BD6CF7B72F171231,EA01D061C6091F96,7EA2B38608BA0CB3,EA1EB3D817A5A14F,93D352A091736BA4,00000F3D860B9306,8983676CC20DEFB9,481941BB7EECA2D5,F5344CA9488ECAD5,B76F3CD2DF641D81,44BE1DA6B03C6091,B7D0254926706BDC,BB9D5741FFDC0B58,7BB96C7867C05691,9E0E9095CE13B470,E936419ED724D0A1,4C83EE46FBC294D8,0000463171297AF5,258C5DEB2239118D,32036933F921456E,AE67630E939BFCCA,A78012094E0617EA,76A5A48D9B79BE82,CE61FE56C8A9A582,B7C30E9AC45A00B9,390D5ADB54E68504,FCCECFC3E3471FD5,F1080FD73F65BC58,C735BC01AAEC991C,000057FCA4A231B2,834F4ADF6D2F137F,48A7AA0ED27393B8,371839F87EB45474,B126E140A831E63C,5117445648B4C936,5CC775F8326AC6DD,BA3B0B516A71A811,D7A7801AD70AD84E,6BCB9A9AD631CA8F,2D81E7F0BDC4ADFE,54E1F23C243084E3,00002F94F7BB7BF9,3895EF14D531A6A2,F925DF80ED9CAE05,FEB7DF012F44BB4C,FA157616490E3657,555D0DE9506AB7C0,5FDFE8E799A0D228,62F7DE6B7E244EBE,DA0FE59570378AE8,3AE465D45BA7E079,EA3B16B5064628FF,B8A9AADEB710DA15,00006C13E81720CE,937925E357C50FA7,BD48E358929326C6,89054167B3C4D717,72FA54B5F06E628E,D61CB8DCDF95E5C2,C715825F2B904F39,0EB096BD3376372A,7E84FE9489CD8F26,19539AB7CFDC2836,04FCBDD7F4AC2866,70FA2740EA5F4FF7,000032E7CD437AE0,1CCDE73F09EC3D87,BA6E1C48CB73D34C,4A98A9A6999119C3,BB3B8E69023CB1A8,898BF53B59F9C2F5,3F5360A246B49215,EA8D2328EA843240,85A95A3DC6A3DA32,9FB55CBF2FA06123,3A737B1D19520B73,DE7B6C48463AEED7,00004915B716AE36,AA52995362475218,2761071DD8425489,D39F0824E4386931,DCB5723E73D51B59,0C2B7DC76A2A8CE3,5E5087E3D56E7C7C,A2FDE8D63EA69456,6D2F2DDEB710A45B,FE915E2603356015,1DE2BC16A28780BB,37D8D8BD40874914,0000381D0FC312AB,A4811E321C6FF98E,528A570A1A8697A2,898F749B3CA70861,9FFDCFA3A70711EE,C6FCE484EDB303B4,127AECBB968EA840,2283A32C607F2AFA,09F80A9A41A91F06,E144E1E14FF6A0DE,143FCC3318455E0F,DE12BE4EC2BC6A53,000042E9E671E1E2,E64C690B4BD10226,51778261F75C64A7,8239940B869E9522,8F19200BCF1908A7,35535259D35F0583,071FA56BA2DD919A,62AB9B0BBE3111E6,ED12FDB4D626D2E8,390E260D16CD340E,18BDE79190F6E19C,B9709824672B3683,000063C5956B6089,13456E17EA115CF4,587A3A68A9F12B87,25D42D340203C115,A8875807615DF057,F13DF1854DDD4268,C5790EAEEAED3EE3,E1E0E3A9E20B4ADF,80C0F1A98727F2F0,81D0CB0A6C64DDD5,49CAD4413B044204,D5EB6C3A3E3BEC2E,000016C667327126,968A5E60917D5801,DD647ECD9A199160,1F490FDED57E4882,EEC35D7117889037,DBD17B95D711AEDA,00F38C2742A70C4A,D213FB99A789D21B,4CC9860074E217A8,9E0C07A36359F019,6ED358A5FB596349,B66F6239055960FA,00002B76BFF46C11,27D1996B1A5F4C67,C8B29C52D16608AD,46015D9AC8E5723A,B033EB9EF52DC6EB,61F1A868D8DC5981,E021A00594AF733E,689FCDD5AE2AE362,5946C1C5E08F0C87,EE057DB10D996AEE,F05E388B29459699,D51617E0286CD296,00005C7AEC665A14,4899C76645F9EE27,21AA7E89FFFAD872,DF9DDBF6106AFD9F,473A6278AC430B28,8B83F4809C52194A,FE701C9A60D59B29,4955C3EAF9434EBA,F095D51C1E99889B,87A86B7D7447AA6C,E6F38F25F63030F8,BA12A9DD36BDEE53,0000520EFCC3D607,0B675D1A5F1D9C08,84CECCA413251513,94F626BA16BC1F4E,E826CFFE49E20988,60F44EE99DC83224,36501AABFF58CFF4,D61C63AE4871CF72,B58476733C741889,B03386CD31B220A0,598BEFBCBA93E6D9,0389062473300F45,000045CDC778D12C,E2EA52CD793508B1,DBB6EBE7CA92DDCC,A0FAC1BE4CCCA9D4,1D54D917EDB37C68,04C948613BDBC280,56C406D2B6851937,20F03A2CB54266EE,08A752BECA6F49E8,DB4BCC5D5C54A650,2845FF82A0594D07,C958D4CCA9245A0E,00001DF045B35C88,E6ED56423C841270,DA1C3562C0FEB21D,046CFF07E4A8E02C,D2620F84CBD07527,71FB52D2297B63EB,7C266C26D5D35901,279FC366794C8B62,AA849B5B35D2481C,90EA55E5771DF1D5,35D4225B49EC3737,0501AB5DF8BCBB8A,00004835BE3E7AC3,0FA7EB1128094852,1122EF22812F6C4E,1750BDB3BCFBCD12,82B876042755E3B9,C90FE9C79C1E8E48,ADFC82B1C329CDE5,8BC63D7B8B7089EA,0A8658D0C13E3770,FC67350F3D18C924,17CA8D389F5434C2,E8DD8BAA4CBC4C0F,000054DF2DC1C970,BC68131F061AA50C,629880D5B68DD0B1,FA148FBC4DF86821,5444F4BD60E63807,F8C3DDD8CBDFBBF5,5861DDFC94CB77C2,CF64D14AB871E504,98767556F978BACF,17503C5E0ADFFEAF,7644545E9642FA3C,E8FCA06477B2C711,0000522310254AE6,CA682216FD9C8B86,16FD3B82388D30C3,742BDEF89CD5B189,04D189AEFC25C2DD,987782566F2A9CD4,C48152C70DA3A636,2DA0555A0CBBF294,35B18E6389194DB0,93E6CD63CC83F695,CADD01DF64F63EC0,446BA7B2272E27CC,00006BC32DE4A6EC,A7DC722E0CBC148D,31AB44EE484E6475,53ED418B5BDB024B,98048B28E101CC65,997C189523FDEC41,595CF83D7EFD645C,3B72D29323AB81A0,172BAEC6DA0EDEE1,D40E3B8E3B8CAAE5,162E4482E1C335FD,52061708EDB8DE4C,00001F4CD2876077,D90FC63827236CAB,2C67393D1A230D97,9060F6B1D947A6A5,B33FC881AED7C375,1235118091A6C1C2,C76BBE761B0B031D,A484F26106F047B5,561DAE794F31DD18,55F7387F7E2FC72A,2C5647C1BC11C936,7E69246DBD527AC0,000023CFA525DF70,9B320E107133A436,76CDA4B7EC53C96F,7D336DD3513363F5,3695B349ABE1B66A,20E14449D6B9FFFE,A358C85C9D0BAF5D,3D1A8BCA26EB9D62,B63F27445014D8FD,EA11A1723296D5BE,B17FC31A1D7D2599,51F1DAD19FC73EEA,00005EFFA0697380,31117386DF88341A,91040B71C01BB84C,696DDC546BF29543,37DA6B13B39EE31B,02A5F99D57CDA47B,46E98A76217D18CA,224651059F927CFB,2D36E8FB4EB283FD,2329DA34C67D19F0,01453B21373C549E,F7D539B54B32768E,0000369641CBE8A6,A4BBA7F2C6A8FB4E,18CD4E2E38B20889,09C9A562F8343E50,377396E19DFACD81,6739C8C54A6ACB4A,B99082858FFCF4EC,B308FF328421A872,4D39FDDE1421F5E1,E00896DA1837CE60,4614BB3C8F7215FF,FF640CC3738F1E61,000012917C0CC506,B61F01368A2AFE15,E61135900A280BFD,F68308F679348788,974E44D47FFCB0C6,4BE4B968974ADBD8,F47560051A1B4A94,49B7463BB9BADCB4,3BACE9EFFFF8A3B1,995070C3D201DBD1,04D7408548407759,8F4BE95CE7D5AF79,00002973182A0A58,997A7E63F22EE657,5E768900307EAC9A,7F03A5511706C7A7,BECCF6484505834E,8F3B746C57A29A4D,F1BFC4699AB7C931,3AA0F54B62C252B2,9432B653B4AF0C4D,2607701D505BB12D,5BB62102C3BB197D,096CDF35B583E240,00006423E3C940E8,DE854C0DEA4D3F36,B68B02FA73BDDB83,17FB1DD778137369,6A8BAFD00EEEF8E7,2C53AF3F70BA1492,A7AC0AA91364953E,45E08CD93AC84077,B29DC3388D07EC9D,D53C60EADD657BF5,8CCFD028B54A8102,8FC39970317533B4,000051965531DB0E,70AF8D006877D928,EC22F6E35DF72ACE,697DD8E424266303,7D9AC85F8F1A36BC,1ECC00032ED2C74D,3E93E9C5DA186933,FEE4A168D7750431,4CB8E26089DA8621,AC4773ED15B50449,437FC8DD6A65AE67,F0617A982B0A7433,000026E421EC2563,5E48EA0E9288C227,C594293723C10F2B,92066D68A862C5AC,F93E2894FA620AC8,A5201904F94F1BEF,E55741D7DE5A9B76,D278C4091DD71390,82125D7E6BA7210A,0A5FAA5D1FD51793,9B9338F09EDAD37D,F04529217829A6AE,0000277678ABBA29,EDA1D73E810EF1A9,651F78004DB7AC16,96CBB75E30E91AED,EABA6F84A5DE1E0E,6799A8777938106E,CB2FFC41F3839CA2,9F96D61123B11EB4,930EFEE12AAC91B9,FB0ABE9448E3C817,30400030DAA86886,E7C3BCB7B3B5BF3C,0000002E88937670,076ACF1DADF3133B,E195A1252FED6CE6,8668971F0D45E484,A2B6D25999136FAB,0086AA60BBD30704,FFA8A0E8C2EC6732,E53A0BA0C27573EE,6FF27F9F70352B47,312644E9FBE39DC2,8209A141FF2FD746,C1CB8FBAA8F056CD,0000562BBEB356B6,523CC36FAA1D4770,ECA092625B301142,9663E4063F174E07,17A28FD4533E5DFA,C7862113EDE800FD,2BCC90971021CEF2,ABBED3266F9C60BD,6DC82DAB8C2DA78C,DCE95D586D23A85F,CC3B3BE8596107BC,AB1ACAC5B31221A9,000024DD85565F7C,E69E4BC7A3107677,2BBE932A38AA6251,D06888BA99343DE8,999BA558C97C838B,C3C045D4C6C14568,F51C43BE72B88F59,A0647CD7BFC0A8B2,2D43D67D0AF03997,D8A0950FDD8350A8,A08DF9866C37BD37,CD94AD675F443E1A,0000108554CE67CA,F68BC234D4A63D75,421F32472154CD1B,B37BB99CBF736015,086FD94DE54B4E06,7CBE586C63329CDE,891D56E955CD763F,75AC0B9732EB5F33,29339952F5955DE9,B848AC2B4F04481B,D4CBA721527E0100,D9960B852A547720,000024524164D100,84F00D9B33A04925,5AE381C1327AA70A,4A042F8E25C6FD0A,A76D7B7A87481938,B48B86F968430960,0F72C1A44C95415F,AD50EBF554528545,ED3C8A14104CEC2B,EB2CBE25CFA61584,CC36A20F0C24C426,68A474F662106460,000034C67B719358,5B561A5C1EAEF66A,6E53324AB5942456,7330B38D4D192602,9126484989D8AD24,5E2AA0929B1432BD,0F07EC0B96633708,2B5067BCA10E0CB3,203781B81C9FF98A,EEAC1F129824662A,B04BB95489B4B365,8AAF00C836B949AC,0000085FDAAC7E0B,0585D41CEFE7FF62,00E450988F7BDF3D,65FEA8C7EB53C52C,9EB9CB2B47AD38CF,BC639B047A4226F4,AA414C5C71B16EAC,410788C31120B920,A7DDA3807689F389,527A6E6E0DBF50DA,55AE962FA9B161FE,7649761157A38301,000019F985D6BAEC,D7A2229521D82DB1,A0673DB47E348310,5062F4047A2FE7A4,B89E77F447D93712,D995E59ED3ECFFD3,4449CC054086B044,DC178ABEF10E9CA7,DD5E7CB4894170C5,55A6042D1DAD3E39,9E9BCCF51022F6E9,0A8A7E6B832E831F,000055D53543BD12,968A274A8582EFFC,FA1BED014CF381D5,AC7176E7DD1E7007,4A612B0C02CFBEC5,AAB2DEB33446AF08,CBBA1E0ABB7DD446,790D519535141773,2926BC2ED207EF4C,441159F4E1FCEBBD,94EAE47A90AE519E,E1DEEBA9B5F8DDAD,00006ABABB37F9EE,BBD845382EDC9B48,01F96FE38E50C513,6E63F1CCC64CB5A2,FEE0B9E64B771EC8,B525286BF8D55B69,FEF5336010A11DDF,8982DB5F1383C859,4EE42B8911B9E3CF,D9C538E98D3CD054,2057CE3A8F1CA047,306D800D1EA62620,00000C0FEC3122C1,612E130A0C551F68,2E81A18F1F222C78,69694E220E9274BD,57138992BF719FB1,68B91A34C1B56E2D,748595044EDE9C4A,67B789EA59EE82FB,AC1CE5C3F17660DC,E029508BC35C23C8,D79D54D52C44A11C,1885FAF0B08A8CCB,000052ABC24F9B86,C279C1E52D0B250F,2496480C0527AAEA,023C17B90DC29741,0FF3B3984FC13B2D,53CC929AC78E5EEA,91E2D1EF8D183540,5875671C9A5099A4,982C99FACBE9E825,F9A0698A789D095C,9CFB921A033A5F15,CB1E51EC844FA863,000004A8B96BA7D2,C50C1446F028D829,B2C6817FD520DA79,5FC8F9994D0853A5,352A938FF930DFB3,88972C47DC9FCCC2,2898A7BC7E0C5216,0AA07D36B6E163EA,8595DAB174B78CA0,DF472C842FB5EBFD,A07A678A0C200F1C,BA5AABBE37219FCB,00006878F1A1CAD4,70DAF8BB736FB8EC,2305DCA4B0936AEC,9293307E4871113C,283087981398FA21,BF9F9CE335D4F3EB,A5B2399712D46B64,C067FB556CB03CEF,3E3DF1793CE6816C,28F1550C533B32BA,FF447E248F18F833,36C0121DF6F69484,00001618D2956211,A2A8D8D968F05D10,B3D17CE8757E4AA9,26947521972CB681,AF1473359104A2F0,C088257F0771F477,B67D935BA9F91665,261A8A155A15F39E,809AE0944C793E28,D6F48C90C923602E,E8C49DD860AD6B6F,DB0D76DE07B41F3F,00006630A552D94C,DDB0A000974EBAD4,645CB1E9AC1C858F,2B92C3C6D5917D85,260B8C063E03A1AB,27073439DE26E902,12879CDC976DD748,13F91356B163085F,098E15B4FABBFA6F,899E0BABDBDB00FA,5DC51B07DEE7185D,2C13BA9B51169AE8,00004224C912CFEF,B18C0093175D69EA,DBA144B6C659192B,914118254D2177AC,4D15C9FCB79D0E23,42E47D7C011D87B6,43E3B0C66755F505,A112791B5B829BC9,20FC08569EE93DC2,0BFA73B465C288E1,891F3E118D5B71B9,CF64B6723222532F,0000048EF8A8CB11,5896A30F9755B4DE,C24BB10D28506EB4,1B49DE0076FA977C,C4425F76B342C93C,6BD7FAA31A70B263,4F4988D10C2F7C3C,52147C0D3B87D59B,621CD29B671040CE,07D2054627382D8B,167186B709B98276,D4C56A9CD7D2191E,0000408D5BEF6016,94ECCF8640A42883,D5EC08C1DC2DAD21,C1734C35B562C638,B8E7BC255D6460EB,9D6A02978AC5BBE6,ECC03AF72A87ED42,D96A8991BF1CCF8C,A71480DFFE206CDA,8AED42C32055857A,5435E4969C14CD82,5D816F43D9BDFE0B,000068E4F5773B00,2BEC3D01F2C06296,61A92C3CFE342CFC,50926C7027FD1B88,ADF58EA6BD270BDE,1EA51BEF99E8F7C4,7692E515614A3CBD,F208E423F2DBAFB4,F315971407784E7F,FAD132DEFDCC8C22,83EB85E79B6BD91C,75D03E58821E02B8,000004884704BCFF,C1F646664D9F221F,20B76659A04AD8D6,C13D4496C8D78859,DABA5DEC8D14566B,5C764109CAC1A90E,318FC71A9BEB4CF2,945806037969195D,318DE2CBB26B9D69,F5DC31B580262450,3B7D8019A2B58328,3D7573A547D8DFF6,00004ADDB4E55CB3,DAEC97D6E95EBFEB,FFB28863BAB085F9,E50C01E51AF796FB,8786B161322287AA,3B10D8F603844DF1,0E873C8DB1D70F99,02CDD60FF5D6A87D,424EB16560185216,EAD5214C95415796,B56C9FEB72A21DBF,32E0B347EA19E052,0000534C6350A1E6,43353CCF6EA07EA3,CF5D27504F13C038,95AEA22E3AA373CE,B50C921DD1A53114,AFF9277B9EC30D44,E1566B9D6DFC4CAB,586737BFC143E507,F6930BB38FAB0C08,5797D4F58A6F0D0C,CDA93B733285ACAF,72873D474194AF61,000046BEB20E6F75,5E87435071CE9830,460D5CD7AE415319,523B1343C244A438,1D4D6EF00D7277A3,B751B3F46CE20E98,3C648C0978735F43,0FB2371C695D6C9D,7C52282B25836DFD,4363A639A885F0C2,F89EB5EF9B014A85,04C4B2610C1FA57C,00003BF5EEDEA0B9,2FDE892475C3A5FB,3E51DBEA1EAE5415,95BBC2398EDED751,ED7A0282B6857978,B60EA9E21630C4A7,A3437D3205B1F5B0,AB0402CA3776E58C,79720B031663EC40,209D8D3CFF6857A7,4A367DDC563B9D7F,7099B0230F4D1E10,000009C66F32096E,8732FF9AE66BAC68,7EF2265CBEDE0966,7E721AA659413FD0,041DF8F9C2A9C275,E83F21ECE77DD480,7D53A1D0B513C043,A417D6CCC8CFD469,6635B812A1D41DFF,01307E3FB5315788,3A3F8D8765AF721D,ABDC5BDBA0E7A5C9,00005A6B16157F6F,BAC33DBEE58C1AB0,488AC8BD807C102A,9E9D42DE3189E10C,14DAB7414BA6EA50,AFFA2C80E451984F,907A3B3C69A4D9EF,884AA273193E57E3,5A837D2F6055745A,12ABFCD6A0E64126,25B90502D8F37286,BEB58FDF3EEA8BA1,000052A4F25DA3CB,886B513CFBFF7248,54033D0AC3AE733B,7F072331BE57F0EC,97B591DEF9AA469B,C9C1A698FA93D888,E5E40D8CCDD487F8,808FA9FABA36D223,5630283D708881FB,F2DA52C59663CA74,625FEA14A9B69157,7E5CD0B910C038C7,0000321D1D570349,5CCB247105D88DDC,451532371BFB4E9F,D4E9963190B5EB19,C10314056211BB9A,37E29EE276B45ADF,C28BD66296E0AF83,388F8F97E86AD659,E4AF0BE891206F42,B30BC055612A4312,AB1626099E99172F,3BDF1009DADF6C88,0000093ECD357141,15DC5AEC752E109C,28130DBE97161C41,CFFAAED47EB1B9C4,C19AB1E28E868102,D414A389814C269A,06C705C7F4803B90,5D4BE94CBEEB2688,5F42A6EB76031A46,DB2E5FD3A4C3D25B,A844C979ADA3C955,29E2E0ACAACCF2DD,00004BE1DAEAA61C,F89D3B5E26144C9D,D9F075F8B539E7BB,3FDDC9C28DCDDF39,F1539E7512A3BBA6,AEA7694733B31D34,CB43A2C0DBDE5D75,1B320CA4F8069B39,7EAEEF4A75608F9D,BD69D8D72D26E738,49F642F175598D99,2C3C7FC6D30BDC4A,000027292974D190,F92E3909A7F5E4E8,E1D1590D9E02FBF8,3C49BF19568595FB,1A7582EB3F8F6869,0399E3E2FE1A2CE1,03329662F7DCE463,998A9996DA3D9363,73ED9577A3E4E704,AB03B0A8C6BD497C,87B9D6C94F11F3B8,22749ED966589BF1,0000051798C61EAC,354D63DFB228EE19,87157A3AA52C6768,EF35AD67019ACB6A,CA39DBD4CE37B53A,656A2D3DC9C98370,4B18D6E27B1202F9,1DAADC9455168947,05986653A6D6EE2B,AAC0D47D41567AA5,090EFFEB15A95C23,1EB366AF9ACFCEA9,0000368AC2F0CE61,10A22EBC405C7D71,AEF280D51549F855,24D755A3A6590CEA,128538D3D66B3496,3258DD00D922864A,886DD7B004D12E8A,5D892173B4E79494,82F57F61CB38B6E6,763D6BF73222C8E7,1828995B4F5DC022,53B895ABEEE37935,00004CDC97A053B3,CE06C488CD1A2955,7E595FD86D8863C7,6396146025593D3D,BC4796B645DECA04,CD0B7FAD2B181A92,88D67B2D2F4A432A,BE943E45FAA500D7,554F3FBEDC943624,992952060EC194B4,111B70B7C206ADA1,05C6DC6C33BCC929,00006E342B1F4BDA,003B6032D9B0F4EB,A0E2F7A86F018522,8A6F4CF2586C514B,3F6E35597763955F,DDA5376927342751,482926D8AE39D89B,607B8EBE8FC441D1,79F95F4FB19EBE26,6E938E9EA21E4B12,15A527780486CA3B,688527B0DE702B51,000064A96E83AD36,628FEF9E3B889824,35D02F776498C341,7A61802F306D0574,A667F85923769E6E,313DF60970D4535D,A1341BB9FD935841,D5F8524424C80877,BDF89FE4DADE4CD0,64631E6CA92411C6,B3CB323DB7BFC608,2C856D0014DD3F63,0000571C0605F8CC,680848B1F55E28A4,BDD937746541FEA5,C478CD60C01384E0,D080B2B496962DB6,5EF3282219235002,668A472CCD724319,0EE003D447200611,E00E9E41789E75F3,4C2EF5E823D61F29,456082AA3A76C458,194C2F098D3FCD89,000053B89B40C07B,DC434CF247428A40,47F5534C7C443C04,75160B90E84EFCEF,AF5572FBE5882CE4,42593DCFBF9BE991,7F65869D7ACBD212,C64619F1B82600C2,48D2CC1D90F6C981,B02641DBCB0E389F,EA421D7B10D818D6,C3C8961C08A91505,00003F263FA49ECD,2B1477D6F244A84D,5D71C99F6557425F,0F1951F838964193,9EEC3C9A220F9843,9EF172505C62146B,4CD3AC8C3ADC226F,5CF276CFA18BCFFB,FE2763019C3A1228,945051428D6FAD40,A3C688033668DB59,AAF64AA2C1E3B2FD,00005BE50E926DEB,32FDE817964C9B49,A41CC1E373FF2AE0,D3B3CB0A67D8D414,52F537A52F311683,956028D82D4B1787,5E44A00B309DA3A0,E7E35BFA654A0F2A,395ABB9609B2D29A,5A3D99A9646F4448,AC95D11AB747CD12,76A4D809EDD81F19,000039CBECBA5C0F,83269BA4CB8140DC,8B29A9B2C4B1EC5B,CDA027E4AFAF1726,2A06D7FF734F4973,6229D198736C2691,8387E702BBA3AA8B,C87CD4B3775DAD09,8587A76EB56E0E6D,333C03A5482DC1D7,1423CDFD8699C984,CAB37C1CE2A28C5D,00006B85B00D272B,B704B5B0B4432870,F6E150F2306E782A,64646F0761206536,BF83CF6051CF9AAB,72FAAE25C1CF393B,45D2419C7C8DCEEB,77141B87A6CC34F9,CEDE2E2CED09DD80,C84275C205C72904,C6A8738268037CB5,42870B9A7F4A5F6D,000015207628F75C,23F07E8C0A89979E,FA78A2E44629B36F,139730DBB58E7F25,EB34469870AF9253,0F95A18769C0A19D,4F501EB4E10451D9,1316914616408742,DBF86B49650D9AA9,C8D6DC3D51446869,04B39A83293DEC85,D1971DFA49201143,000007EA1024DD96,8D936A77C469ECEF,5F16FEE56911DEF0,B56848949E135EEC,5B0E5BBACD13987C,2DA899449ADCB598,7C0990C1373425FC,79EF38D85E8327B9,162071B7E2D4A60B,1ABD6B8D7464BAA0,0F848C6574C9E721,0B050C3EDF4249B6,000026DC42320497,21F84D3E472C2241,D5D02FEB1AD8023E,3E8A08F0EAD6A8D6,A7D228AF011D80AC,D41CFD0FA6A8CDA2,354ED0A0845AACDC,BB8336405ABE235A,BC29B1EA8714E14F,9651E95270C5AE25,4B6C8F69FCF01458,C667F94A78F3105C,00003F6A4F0F260E,8CD79E02603333E2,7981CA8B24A87A65,01D64180C31598C0,CD4ED79221934F34,20BE60279E427830,B671F5FC77FAD3B5,2A30822EDDE484CB,0E20656D91571FF7,A05DB0AE7B9AAA1A,A4F461267AE258DC,ADB7F8E67282DB7A,00001FE912C7B0F3,9AF27EE7C76AF4D8,BF8DFFF385B64CD8,EF6304BDB26233AE,1A3B1BE8A20F619D,D8FD6286C608BAE9,D4EE20D5A825DDC6,95AB7DBE2512631C,D4856149A0AB27AB,9A8E30552045D151,49F6BC4EF884E1B2,430EF2D712DC342C,00002311147E2D1E,4157C3BEB2F2582D,909985044F470A4B,465E29EA605B2100,468578593383F87C,75F5302F3285A431,7F9249B3A8FB4905,A8811B231A8786DF,A3B7A14E1CFCDCE9,B11E8AC82608B610,BEBB6E92BB3D10FA,022A9D2C8D734639,00001125175C926B,83D8B7B7893DAD08,B89A0ED758890753,6C1FCD0F30EB24F0,F1E4F1BFADAE942D,7734DE0BFF588473,FA3CF0386C21AF01,E04822960E0474BC,FB6F67A404709884,2F0FC4CE98F6114F,D4D230ABDA64B18D,93A9CC156B02E953,00002801C3964C24,325631B542304E15,550569E9F641FB76,D8724945FC4E9990,1571E9AE81E65B16,124F119D96047BA4,AFA975110DBF738B,92682A7F183CF4BD,B7ACB69F21273C6B,DE9D1A96362A641A,751E25EEBFAB1B2F,94708C65FCDF2001,00005DE7DF3BCDCB,2237FCC463644F2B,6423DD01D0C6B5F9,9FC72DD02A84C64B,C7046D203D4055E3,915EDDA75590FDAB,CD8B4A3A90F49A7D,F0AABE014E0D1A8B,B4D776F57254840C,DE665754D23F324A,6116CFA830A205C8,468305EC3022AD08,0000651DBC64E0E0,0338310EE3F5E979,4F4622CEA3084C37,BBE8488659674518,D1B4E5C869D5C4B3,6425241ECFA2B256,DEC7EF109FE77689,ADC75A38964B926B,B14FA08756BA079D,9E3A304AFFD61635,C693E3C57FBA46E2,96A12E3009EE4BEB,000041830F5A1942,15D38FB116F493B3,4116CA12018429B0,A0FA5D2C8EB30B23,6F2C8AA3C84F2F81,0520039A23F9C935,2D1AAD479DB4B691,C2A45C48E9283DED,75B7101361D6A690,1B77A6BCDADF4EBC,1F1497B7A3397EA0,CFBDBAF619A461EB,00001F3918DC9E7C,C47FE549AE82D12E,FD8C5048FD12F065,6505DA00248A2BF0,5A7EC0CD0D0C1422,CF7402CD592AD52C,FA197C5B99A304F6,A792324E2E520E10,F9E9FDD8B84DCAAE,7F5F4BCF427E7F9B,DF34D6AE56E8136B,A33D3E9A2808371C,0000517E33EB08E6,55C78C234D730364,E28B20E399343006,DF26092897992D9D,07BE132EBBC00051,F5486FE18681D699,7AE94220BA301E9A,2A0BE865B58AA098,1BEC61C1D321AA1F,0004581C3D234501,7EDCFE2176486381,CEED7D4CE37B68A1,000006F3DF85977F,754CF07AE978568A,F30CE39DD5FFA63F,798D253E7D925038,038B89FFEBD61795,EA3598F2357AE9D0,DBC2BB483796E852,6720FE7B522DBB46,1A67F4BFE917FC0C,000D3142913043E0,F1D8C46244052515,07F3EA5DCA047DCF,000042D1D8A3405E,0F3BFD1D3981370C,A0498042F6738352,6AA49D2D7BED33B0,62B9CBFE6493BA90,857A3FFFC5B8BED7,5AE3B3AF1C313145,AEF98024B6D55FC9,4D10578747D35D98,1B4FC53A8F95B43B,5139E21D1969C110,F6A26124FD8EFFDA,000037296646C291,EFD44B7DB882B09D,5AB884F4EF5CE96F,358C59AF9B672E43,842F08740CE9C0E6,AF9442C82E0133FA,E0AF7DC790DEE656,72F5F7C86A9F1AEC,66ACDDD246BED8B0,39AFFDCE17CC2A27,5CF406AC9D48C3BD,38370AD95BF93F8E,000031302D41ED86,266B6FC531DEB7B4,26B998DD9C74033D,AC03298331A51DCD,6CD92E6D5B943C77,41F6C1AEDC4D08AE,B28A9691252B7E28,F7CCED1723434668,4DE1DAB706D39776,3A9FFAE99E7AEF4C,3C5E5D705E0736B7,44825696576B97ED,00006C5C151F79FB,5F4083CEA82DBF76,11AB509D3E2DE337,D126672643818E17,6B3B1FC933B1DE74,7FA750C813990525,C2316B7978972CBC,042B7ED603AC00E4,AD28FD14791E9B46,5B6BC087A2457C8E,BDFFE7640B5B5C46,06DC171C6E0DAAF4,000001BEE98AD42C,68A5AD9D763F6BEF,3E2F9A33F181FA9B,8DADD0A74681D576,AC38CFEB075AE153,2B4CEA89DDF93BC7,FEABF3DA1D171961,CE2A54DDCE2F79AF,3A5642C7FB275527,8709EE801FCEED0D,CAD64974779A2075,56A9628BF80C9E5D,000052890A732FD0,05C551D72BAD1B54,56BF3CB84960204B,9BE665CD296B4ADE,764B2CC61C55096D,B23887EBF0F622D8,5DE7852544A0E260,18F05C0DC4277236,720647A7B310DF32,06F3B3598634DF8D,5836DB4D4D18D4D0,9E95762C61A66B57,000029E3C3DE20F9,4491B5FFAFCB5598,15A756612BF41F6E,96F512AB97D1FE2F,CABB1DD56EE3B0F7,B28BE7AD059411F1,ED265592BFFA862F,719E4E6DF184FCF2,C55AB086761F7C0A,29F1B2826084B56D,76EF5098D6A03FC7,A1F42CB0062DB521,00005AD0E0DCD85D,020612078900E07C,DB6DEA6E91FB54BA,FC9E8A88DB383838,33FE5720041AC8BE,693815AAD578D378,5EC06BF1DBB20CE6,87B853C999A4C070,73DAFF063D1B771C,CE244C725150DBD9,7559C0CF369886FF,C5BBC7EDC829366D,00002D2BCED87A10,D6E83D68DE36A938,7651F324C8C836D9,13BD8DCAEA2D0854,CBEA8B8C6E0BB9EF,FA9D9F81AB1C8A4C,59F62D5F8FA7C4BB,58C8FDB01CB65624,ABDFEDFEAFF0A0E8,31D64C69123A8F9F,AC438284102397D7,C9DE3676A706C0A8,00006F77CD2697D2,94F34B3FEF253505,E74C1CC7F5A5BC7F,CA94A16297BD9B53,29DB8CAABC3DF69F,B7CA0D6314720784,5E95B2507B0C34E6,22ADAEC65DB1DB5B,CB87BBB5F92F2105,E13A822F4CAF075D,76562852CD4B5445,97D64CBECE3AE0E0,00000436E6B9AC89,5443C4E0E90F6101,9B30689E75BAF468,35D35BC5D1D356C3,399A1EA53B722666,B916C5B7F8CBCF82,03E2F7EBE8D83767,B19B304864F81F4A,E8CAA9CA693CC9B1,2367F564CF2BC42F,092E415195420415,5D8109611F67B3AD,00001FED827902F5,968F085CEB866A4A,B3C33257660C75E6,898699D9B6F4365B,AAB3D7E9AE5550D2,211DDDFEA51768CD,05F2448CC71A16E2,1D825D003B37D346,733A57C2E7D4B20D,2FFD8BB71C6AC096,8949999D5E90EEBB,AC64CD4167D2FF72,00001A081068C8EE,43AA31D25F0BBA15,4865EFEECD2FCDF4,B847ADC0D4EA89D1,E27A40F51403A7AC,BB0E640FE67CD410,C1939F89297614F6,709FB7FE3BBC1D52,55BF84E32CA93D82,22C0B1A67C311006,204C7B90E8C3B6A9,5659C7CAA504CEEE,000068310425B9BA,03F1533BE95726B2,21B63FADAC027DC9,5580853382416A21,769230B78654B193,56EE18BD9BBF09B5,5359B2117B833BF6,0E1169AC9E630523,F71034B604AD97F8,0F14359117602884,017796DE79193C64,7F8D9724FAB81E7C,00006DEE664AB5D9,625D99CFCF554E57,9D3DE1BC0B53EF12,CC02CAA6EF52FB25,8765F37F8C5BCED1,807748DA1F26EF78,18C6BDC3EB33B919,91456574B3B72095,73B58CB050AF5E12,CA3D05E5C625C659,CA808E8CC66C600D,800ECD10818BFE3A,00002F136586DEBA,67788AE3CD26177E,6964B7BA70C1344C,20001E445E61598D,CEB8542F321007B0,F7F2C21D5A6AC6A8,F4A544E1789F2610,71C00EBC5133858F,EBFB7CFECFE6DDF5,41E97DC2103B7242,E749C2AB4D227D0F,066E61B648511610,0000334322D42A4B,EA917838BD09DF08,8A7650CAFCC94383,0F219CBB9D23348A,716E4180EA365757,A808456D9DFE0115,EC704A8E668652AF,8606D4E6DD9CC840,D57E39638335133E,D4662E10FB2BD887,7659F3E9C14744B4,07DD3BD735B7A4F0,00001333F708E939,1A1A8D7AB7DB388C,3B6C171AE3BD415D,01973AFAACAD8D22,A0B51EDC659A08BE,8BC4EA9BA4A1FAC2,5B9CDF254AE552E1,04ED56C4A847D4B6,C06DD7B45C285615,A80436DF561CAC60,07A95DB248C5EBE2,1F2C073D379D0A92,00000D423E85110F,0D587BEE80354721,3CBCBDFBBA6A6622,ACAD430A0D70D016,6339118DBD0D3760,E0CDB4A97F4CEC82,8AB5D26B58850134,A726F2749C3E53D2,FD34185367310EC6,E9519222BB002612,1791458C1A58F805,DD1B27FB93470917,00005107031E3612,55C6395DDC52DB7D,B2B436A0E6D86F60,70B9C5539E756CDF,D86FD0C8B3E2FFEA,2039E7EF92FBFB54,3C3B322DDB0FCE46,85C7DC88C9105B4C,52999884E2A1B8F4,3D425C75CED1C92D,720CAE3015089EEB,9EE05809BC3597BE,000008BAD857978F,59807810338A29F7,FFF5D8115E2339F8,10B2ED15E38E3370,2DD62FD1CBB65749,1C731A5C8C8EFD1C,9B4DC66CE3B347A2,9B8781F48516B2D1,E61A9EA4DC5D6FA7,1D66097E49374F7E,63CE18D68666D2D3,14B02E6242E6AFCC,00006D746629656B,7BFED6129C9332C8,A525F5F39B955747,34687FB98622E58A,CFAE53F146D95F58,26895BAABB23B089,A1D043EEFC1698DE,94570270869DE165,42EA2B4A6040D8B9,A053CD25E59715E6,93EF545991EA06FD,458EF509D8CEF2AE,0000526F347654E0,540E13C1C7EB1A58,7600AB21AC7828BD,D7BA92457FE6DE26,5AEC8B096D526D84,E6737C2A121870B4,61565F2A8424B9D5,0E2095BEA9881ACC,EEDB55AFBBEBBA11,487D727F4FC6BA9A,8BD7E62F6A6FD625,43C8F883F3A07771,00002AD771F80A7D,34F2F679329F685B,2AEF75A66BC44466,F1CCCA8542EBA38A,D8FF85F66886828E,1E59DAD9039D163A,0DC73038BB5DE124,D18B45E263742FA9,E865D85992098529,B437C8233AB1547A,0AE5D36307768E43,5449AA2FD313C1E3,0000266D30281360,CFF6A88BD591376D,9503348D2FAF14A8,5A0AEFC1A9982A3E,25C2774473FDEE8C,E9CCC3810B5B3E7A,BAA8E8AC578243E5,DFF791E8FBF5B16F,04AB4C59E7ADE8DA,6BE9C4D3F6862114,8567435336F7F128,10662880FC30845C,000033E9DCB68E3E,C1179A07111F0A6C,A9062C438CEFBBB5,2E3AE689C8A57DD9,8406A4ED07915D66,C721023C2153797F,162AF6743370C3DE,E5F2CC9524C44978,BDC3CE4DF3E0A4AE,8FECBA46B53CE727,8FBC815F9545CF3D,EB5BDE410532BF12,0000015B74728724,D5293CB83C16434D,9FC944B53446E733,A6184FB33C96AE19,A255CDEBD428E907,22C41DF50994559D,299B037860B60CE5,613D59EBE2BA5B2D,E3B34AA610D26183,352610A847E5676B,70B32CCBECD19848,6553ED24F917CD8A,000013B0C8C3C4ED,7098F44B27479382,09135E4EAB152AC5,E396285D99E641A4,F068AB16987DD523,47B96E5F9C4637CD,F0AF3A1E1F9AEBBE,2230775B9A77A23F,5D1802892322A784,D897FFF0CC40B9CB,E8BA1A6E47E99FA4,3F3DCEAE1C337504,000058AFA85AC14F,030E10489F144E9F,7CA62C02B057A4ED,1C001E58967A3CE2,ADD5389A1A99AA35,3566D0F99E66AA64,113AA3F2C2DBDFF5,FC821BB99D04669B,989DBC467C7AFB51,E3122F6CCA056ADC,9455CCEC658EA4F1,FFD30E2D26A3E357,00002D0B0119A5B3,E0BD037815BF2A98,B53B0DA2C7B00B88,AE66B3E6BD6AF05F,1E88A4AE2AC1B1C1,B7AF1E1CA9A31F2F,596AD5E99ADEE09F,1788F6E6BCADC104,9BF36567855A77F4,9635CB6FB42CB52B,EACEB52E9ED6F6ED,4CCC491D85CDAA60,00003AC1D7FAF847,2BA334B7540ACB9A,7FE8E23556082B2C,09626A5115AADB8C,98769615AF5E730F,AC8FF4A98AA2D018,3BF48552B6F91AB4,0537DF036F15DD8C,7A3F5101CFC8A776,FC74DD1B1BAE546B,D4E3C9BEEA432FB8,E2D4080E7596027C,0000303903CE92F1,0F9860D80529E141,822A389F15145BEE,40F79976745DF288,9E1675F783CE849B,FE02B1CCC97A1D6B,7CDD02B756DA611C,BB857C87D1491B9D,EB34A8DAAACC52DD,77DEA3755CCDF373,43D4F2FCF1A24454,6B0A37FCA26AFA62,00004E8FC4DF484C,FECF7031EB86EF91,A3497B864531E2BE,8DCC81B731092F7D,87AA694E68E6E9E0,C1A1976ADD70D2B4,2DF9C2D74186CF69,D04E26112B7E8430,8081927711F2B81D,2E4757C7423F15AB,AC5FF3C40EC824C1,612F770F1D993779,00004BE640AE3F7F,4FAEC079FEA2FD40,5CB8C5C43A1E624D,521B571FFF1C09EA,7CF857918CD0CFCA,B308B0F466B49A2F,4B6F567B3D562B38,1DE5D7C1D98A27F7,C07F078EEE1B2B80,C14CC93CF873A62E,C1DB87C44DF45F4C,CED7B17049895556,000060140BB4982B,C839D2F26857E4C4,772E6B8C5E120E28,92B65A5F13A56B51,F8988394E53AD564,A9534485CA9FAF7B,0A2F8D93222D7F00,C0AAFB8F0581E30A,858DD116900F00BB,2C2167429D8C6B5A,F7BF071082254958,90C5E0810252BFFB,0000027CC30EBB38,9A90D2F681EDBF04,ADE8CB95C15EAA8B,8B3AFEE238A890AF,53663DACBE6A3502,541E994D52722F3E,24BAF5B4F71C68CF,FF70BB31C60FD4EB,5D68197A619B974B,17A99C39D632D529,33AD79F2393D10AE,E367A24D617312E9,00003E5E423558D0,5F37E1350E306034,50A72B21A2DAA541,67A4E1D2D9A7239D,767E8F8BC4613828,22F4C7263AD6432D,F9E643BA440D0606,C8352F5A1D7ADA39,E20D24EE0E347CD6,10235B9CBC6D048B,DC2DFE575EF7EEB0,BD2CF0D065059810,00003C97573E6FBD,F493C70F8FCBFBFB,FE231E90672ADA6B,B3684F8073BDE026,C8A5845799F52531,DF4A3136946253A4,D87208B6C69F7D2B,5911F08962D8F963,B8C8554B07633C0B,2D34B5431DF8A021,22BD7777FF27E3CB,04F9C6046F4346B9,000041E943B6B2D1,28AB1701DD09968B,4D324373B7434B34,6F829BB2AD4FD42B,86B16CC5F4E33B8D,E31423C2E2704BE2,71765C102E3BA87B,D8091D44F3BB8A9C,8124789BAB30941F,3C131D4845D6487E,BE08372633F28BF5,E3D8E816377D9B8A,000022A5523B5D5F,FE84A365265033B5,487D085CEA777B10,3912FC450E94B4B8,99B0DDAB31920247,1F8D41237F85E074,FEFF9B57D7DD1493,B0066FDC62286092,010C5DB37CB16C69,BC1A1C8FAABF0E05,120FC38595BF9247,3FF812A735B86F67,0000370A68EDB824,28EB6C0E9B0F60E0,0095AF5BEA2274EE,88971ED63DB67E8B,76D5851ECFE64FD5,CFE1CE7E0B0830FA,CAB228DC00C99513,46537C38815E921C,BEED00F575987AB9,0687DBB949BC8744,0E57ED5FE9559972,ED3B6C874B7B261E,0000104148392A9B,3393D16F9F115CDC,A7964DEECDE22BB7,7BC86D9BA1B39E54,16270D224A58928E,5ABE11596F19946D,94BDC3EE20F00543,1D6D0CA55BE38655,E42FBECFDB5487B5,C55665C6C44AFC8C,3340822E25E0CC65,576EE275417B896D,00004DF4C9F40513,4613A6EFB8D4B982,74755DE37CA95800,6DFC28D8478FCDA5,895DE28942D3B45B,06D612F0C0DD3407,081BA16A5DFFDD3F,97FA30BFF1B326B2,9A13A8CDA9047B3C,CC19CEC0EF33012F,65C0023AE1FC41C5,268C6631AE718C55,0000276A82DAE3CD,971F7490DE261239,AE6F36D407853574,5A971E8701532228,D3351DE3AEDEE201,AA7495A9072DF6EA,0D29DC59D284AF55,DEF4396AD639E0D5,5E44583EA15A477E,B5D381840B1154A9,6307FDF7734BBC1A,9BA5F7AB7966B8F1,000004122783F7CF,4BA2F89FEB20DC3B,C065E01E1763C324,4FE0493E4DE10356,85F61CEFD00A7619,893FD811ADE09C58,CBBBF5B4C17F4403,BC82A51C0501E69F,1B0DA742274A0447,67116401D8FD940A,9B49032B7F77D32D,BD6F4A85131722D9,000006983FC770E8,95B4DF6F97812873,6EF6885CDFD5624D,12F30234957E742C,5A1EB474AC6FB72B,C7A5B217C5829096,49085C68B76E5623,729078D04158189E,FEACFFEB01EB754C,469655460D4FDD3E,D0662D975E478105,B2C00732AFE0B16F,00002BC42AF0E6BA,60B23BF88923D453,00757AB59034131B,5B3B39C54D346683,10F5DC56DBEE790D,AEB4A4295BCCF8CB,7173E36032F3F1D8,E3F8D1B64237ACD2,7F3BE6AA95C5E248,F9FDC870B7D2D2EA,409FBBC589F0D9E3,1E263C980889ABDC,00000690D5DE46E4,672E5647DEE25DB5,77AB7972C024DF26,3A2413145A3B9DB0,5FF9A4F99E9D9EE0,6267057DE902503E,2919891BFB5FB0A7,E82F83485529878F,2FFE6E99594FF589,ABB1C78228CC889F,C6B371A1782EF5E0,AF9F2D6EFE820880,000043F5091C3AF7,B800732A2060A10B,4A346A5EFB4650E6,07A4C334F8F9412C,383DFF25F77BB044,6BA060D8E4CC0998,ADC3BE3BEE889851,A020CDED05E592DC,2E93C0A109D6DDB2,7B51FA62EDD294BB,17B963E0C36B554F,B86122D4D3734257,0000363B2F1D75AA,CA63B4E69549C286,BF8BD055BDF9CD38,92C2CB7956DB152D,A9D850F98E6A1788,9DE82909C10BED36,4D155DCCD3DF4122,08ABC61728507337,5C406B0907E13489,97F6BFAF760C7643,72A6B8514612165E,B41AB8258A8813C7,000025731B91F488,5E33EB98F03BB5D9,B8C2494724F5C0A2,54D9EFFD8D415004,2A4E71C9532C654B,A1334E553754F9C9,34B4B2ECB3F52D56,CBCDC9B2C0BA7665,8E429A1A44EFDC25,FD71C7B695944B28,51E6AB2915E9E401,430EE0B36DEA9EEA,00003FD881146AF4,E3AEE210A6324986,744D38A58295C71F,C973C00392816890,B5FE22BB7EAD240F,690CD92264971774,A2D10CC482EA994E,270AC9D53151EFEE,EBB37AD83417C6EC,7FDE340722E4C38B,F8CB16D218071279,74992757DAE928F4,000001AB77B0E258,C8BBFF0C6B8E30FA,CB112DD151491F84,75C4FA1CD02B1C98,4057CA06D9072534,CE3CB0C0C3943CF8,6287D3AB58D11D0D,AD3F9CD72FA40973,47B11FE141B96089,78397D3E767D9A2E,901F9A9DC48DBD2E,A3CDCA671F8E5872,0000432B9FF16ED2,4206946924861B72,35C3C6F30FD297F4,B477A3661F13E0F5,427A07EAD820109C,D8880447180B4E52,60DB0F6BD15564A2,48B41DB46A0C4325,6A46F2B11F5771ED,EEAA3C9D11E98D8F,7411C2B2269AAEBB,8CE591A8DB23A6B2,00000411CC2F1BD5,F7425117C09AD79C,2CE080F1B43D8002,E5F90C1CECA03391,0688DA37AA82951A,E67ACEF13DDF5A2E,8BE5DBCAC15F3B8A,71508E106F3A4C23,BA6C16AD6FAA044C,59FE78FAEB277E2C,CC7B69B3FE266DEE,094C93F34716B265,000028E965180696,81AA131371A094FF,71A19BB361714E40,48B866FD144D3EF6,DD56B38BE3246FC0,A065F029F2A03373,13C227D28BA72C67,04E15AAF7553D965,9E0FB3E14A0F78A0,DB735E41FBD97A13,C4D634F28A810057,2AE14A692E6A516A,00000CC6696011FA,AD7C7215BE088C93,118A131BB5BB5973,6C2ED32BBECE220E,DF40035E465A00D3,D034114DF4EAEF69,77C287CC7B6B9B37,56B3F797F88A464A,A02B524FD9523745,72410DCF7ACD335C,2B945F6C6D480C15,D2F19DCB39F8F16D,0000642F8C692C2E,504C6580F5B5FBEC,E4DC3BF0C2E5A670,DA2A05DB6185AE4F,C8A48D48B16E3C4D,FD50D2E7C3D7A9CE,B43C59EBA2BDA02F,ABE29A75992856DE,BCB3E0E5E6326074,166EC493EC3DBD26,F6CE10D0A60FBCFE,AC068780D0D8427B,00000B37A1E81181,91432334CAB194D6,13F3001B11C9EE9A,DB1ABB3D9E648608,1B250F5DDF45289D,4A7E4314DE6D664F,10D193E8087E0797,89E042B2B0CC9A77,82C76C76B2180C68,4C1622A8DE769048,6ACD30A18795DDC8,DB079E5043D6E2FF,00001C5F8ECAD812,95F6C7A740BB8FD6,FA878EC9E89BF6E2,23250647A4B92F37,EDD7BB78DF0A06E8,BC2A1E0FE876FD9C,88C9F98CABCB9EDC,ADE97FF79BC7893F,3DDBFBAF0F1D5F7A,D1F91488BF04F562,804471182D69F91E,B124D51F96E7E50D,000051B98E29295C,441D3024596225F2,012393D3F2542A25,9006B0CE99F0D7DF,C654D159ED7F0DFF,6A7B028E5AEF671B,46E334CFAE337ADA,45B5EC9D988B5BAE,468846FC3AEB2811,0A9D7D6EC91979BF,8BE516C634E0BD5E,6864A8B26FE34CCF,0000619886ABA633,EFD5D8AB4978882E,103F5E5BD366E172,C3F143D23CDD71B2,751DB92524191287,D93FB160D5F7C9B4,CD30569AA3F26A82,3D554EFE48B77915,6E526856B3CE1D9A,87F636C813D38B8E,E5D3335BDA12E634,BA3376C2A2F9D473,00004D193B5D5C3F,2BE7B51A12324E6D,F9B2AC770A0099BD,E55B6FB01876BA55,AD7CB955BC719FAA,9A19ADBFF2863B15,2D8D67092EA6C064,37A36F39A33ACB7D,C762EE40E996C3DC,D314489FC398FB3C,A587D091C8B2F568,8E9568E3B849C60A,00003F2AD912D57F,9671BA66B98BC7FE,3767C07C41387556,E09337F85494F1B0,B587B736C0D0C813,EB22DE74D40E39AA,C6327BCC3357E6A6,81AFEB29A3BD7BAC,307A96A2E3B6EE3B,C949927AB4925ABB,046731041CAE29B4,392FD468170F8D80,0000192EC847FB0A,7272AA5BFDD53C47,DE3CE2DB3BA38710,97F1B83E5D2E1564,68EF778991E3611A,A22A5B673F7FFB7D,C3E7AFB9531CEE4C,69478BD94C619920,F5FCEDF86242FB36,5A50E731F4267F03,FE5CD18D6AFFAF1A,C7FC0753E477568C,0000643C190D7BCC,0C619F2A81E05957,0AAD0CB13DADB00F,DECC6C4657AB1781,92DDA1191455EA46,72106556D4631508,4C97529A654911F3,C6DFC1BF0166648A,ADE6CB6354559A31,F725C47E9D6F4152,515938E6EAA6C0A0,8A3EBC644D82D04B,000024730C1E331C,7E3178D9BF257319,C806DDACB2D7512C,A283A41264985A89,FB129B395CFEBB39,96D2AEEF4A2EAAA2,F8232E1D26B5C1D7,D4E0EE6985DF1307,EEADFE181A2090C3,14A99B60A7DACF0A,5251D437FA67A5FA,CE3F995B278EC2DF,00002B6CD52F9123,F42F8A254890F970,E61D86B87AE0FEA5,7A052FC6E8AEA502,376E4136E1E04FEB,B424A265AC24CE46,415E3C11FFFF82E1,3691F69720D1222A,CE910286A88225B4,9A53CBD5CA620B5E,37C167203BDA3939,476280015CAFBCCB,000022DCCE5AC5D5,B88EFA92663C7B51,CA234E89A461FF02,A4F10AE6DB2C96AE,785F202AC49A9C0E,184E011306719B41,D2ED20681563AD70,A0DEA78F7C3BBDC1,F3CACEB3B21B3F27,8A9DDD81599567EA,4BEEF906358284E9,750734AA4CBB57DF,00005582DD093BFD,9593761019C4E974,E55CC91625A6B05C,F4A401022C66AF4C,3FE868BD246F4221,A4BD8EFEFEE51CA2,032DADF636BD9A5D,8B3C7A684FE96CFD,4D2B48A06A56A316,0BE3AF5270C415AB,2807568048CFC7FD,4F37787CBECADF04,000006DB0AFBF4A3,F47561ACD297F426,CB8C8E2E11E0632B,48A2ACDBF2B64F75,5800DB972589C018,96E23BB21A91AB3F,9BA0049939D54AC5,B346B13957ADF0FC,BE302EDBE83D8226,5E2F7FDDB50AC0D3,7985CE5F300C978A,430E088FE3F76F78,000006945C314E69,B23C3E1AB89A15FC,73DEB4947C10E1B2,A86D118A757988A4,7621042D7C79EDDC,CA84B789EA8D3FD5,14A46EE795D15A8B,2A2DB128AE128A33,6B3B75FDF3691179,B78C766132C26FA9,A922729282138A47,7754A9523F1B3A6D,00004F69BCF1ABB5,08DE62D5689F64D8,0D6DF0D927FE5E11,C6EB3169B9F4AE18,87EE8D4C0DE1772E,AFA6E024062434E8,E8CC5258DF2F222F,C11A1F392CFB5DC3,40E18EFDEF8111A6,28C07D414653EFFA,1029F037C5C64857,6B5E22D5D733431F,000009B06D05599C,0786FF5A1C7D768A,E47921F0B7BAC0FA,AFABEC0F10E94166,FC703E0B1B47B43A,F76BCC539DB7D332,A8CC04CBE877D3C3,5E75FC8DEA35BA49,C0603ECCCD98950A,3FFD29761F47C366,A14AE81331CA8574,2AC4B8D7192F207A,000035B6CFD850A2,420F58C9BDB3BFB8,63B39FE94E5D93F0,7DA29A5EC712C600,DDC270F6DE9123D8,FB235A164195F759,9B3746C4CE5BF387,16872EEB75AFC719,D7DDE1444F731862,9C2E67793206BABE,5ABB1B5F071607F2,3911B30DA2CA109F,00006911133502E8,A441EC17B1DB7D07,120C6EBD7AE1F046,FC6B5F4B4A0D6EC1,8A70400A2C599370,F699D880670E436E,17F403F2AAB87AEF,B8FE26D0B8319DD8,EB0FEBF75AD2B08F,BDA6EF0CEB1A0DA6,8C4BBC0C5647849B,5A207CE53D09BE37,00004F35ACF2D51B,F98426F775818AFA,B7E2FB75726E57E7,A316AA703763773B,C890D76B9F39D11D,592AB844A6B06685,496FDC535042553B,A249D5B563A4E160,DA554E12EC461799,F806F958795EC6D9,3C39C6193C69178D,D04CBE26797AA8DB,0000526958F7BB0B,162EE51D33319497,EB6B07CC2BFAEE6E,93E84D9C949B4FD5,4FEF956041AE215F,165219ED08F5E7A6,9CECF6D2E521DA8D,DD2440AB4CE3B6EE,4632C69CB54968FB,62F63213AB7B6803,6CA19D84B4EAC7C9,E5C5292CDB789155,00000F35E40F8A41,AAFF25DDE2752A7D,C3FD09740863971D,8256044E3542BB3C,6D850731D269DB76,D3FC002D550C786A,8F1F544547500F59,F25C5BC21F49A5FB,C5089F1476ACBAD3,CBD8912D68DC21D9,3E4C8F72BCCF1861,281CB3970AEF176A,0000098392F5F25B,2B032003E12CFED9,9DF75F60FD67AE9C,43474EA69C615F23,8FB27F0660DC90FA,E113757D645BEAB0,AB6BE13F43653E7D,58EAB5D5A7406518,D123CC7884DFC03F,F3A349C5D9DAA7A6,A99FB244E2985466,BF0A7BCD1751B0D5,0000430D43A7AE3B,AB3D37FAFDD04A23,E3D31BF9475316D3,F937ABD11E6DFFAA,9D78BAE82DC69B16,4DB9A98E5A3C29EF,3BF0CA835F386EDF,E8A6FC9471C2F815,0A0807E8A35BBDAC,7DBBE2B8AFB0B1AA,A0720332A296FB9C,24BBDB9B7C7881DC,0000339716872051,42A00377C5DFB0D8,4E4627EEBF500307,548E6DD3D2D350FD,6835BB9C5321CFF7,29A253DAAFD45BA7,758121A31AE82746,C572D23514443664,CFCFEF50C3548C53,FAC535472CFDA72E,A9A4021DBB9FB0DC,DFFF674C2B7E1952,0000164BEC23A976,5E916E65516CF3D7,D3D3E076D93E31A0,C0FB2E09ACEFC1CB,29670618CFFA5E60,30C3BE65ADA927BD,79D51B6E35975B72,862918C63C343109,DE6878B4B92417C4,7C6B7DAD5B0EFF10,E6075B7E38991154,B12E3CC3DB14EEFB,000038D57A597570,8E01C3FFB0BF3029,5A02B88E7C8C3D1A,96EEBBE3945F434E,7F4BB68515C839AF,B58D0DDF9C33D21B,0E5DFAE7ABCA8A25,3ACB3F4120DDB6F6,93E1D4FC50C237A0,7CA0D3304AF882D4,4C5DAFE8F1C1843D,04961DA5E733F5B7,00000A6ED7D11EE4,2DCC9B692E0F8BB4,F852FE78B8DB0EC8,F21F6093254CA0CF,184CBC26C632CC6C,7608C72296756257,2D46515A8AA439F3,F476CD4CEDCD7573,BB162A4B41D83BB4,44AB8622760E25B4,CD0452B2D27BF86C,3508FF72A62147D7,0000388785FE99CF,48BEE9CE80E5E445,6E65F46A13C42DF6,BCA31E631D6BFFB0,14147B232C19B01A,14ADA3E6F43982A5,B9DAAD489DE31BC5,78C415B045D86A2B,9B3629ED0F1A6183,04420919999086B4,949AA07B0FBA4F4B,B9BB79C7E0B568D4,0000177EAA06451D,74BE4D72B0A5085E,B1CADB8AACC6D2A6,36E1C0D12CB91F93,580B47DD67F37C43,C97CD3B1215A6A13,2CE3B9BEEE01D702,AA4D8D29A2192361,E5FB2097FA91C494,37771DA82958193A,A7BEBD5E69CA581E,65589A3199231114,000004DB2F7997F8,6C20AAFB1CF29A16,110A692345C286B0,0CA59124E45ECEB0,99EA5FB1D6AC45CE,61AC19F25E6C05CF,525B7689A2466860,812E45237BA687C0,D1A20198D3EA4A71,B04978656E2A6FD8,F69487463A69551D,F4CFE1E37FD9A095,00000BFA1346512F,A0416950EF0513F7,942954F8CE785DDA,6CA1F15B12172F78,09EE14E61B0D52DA,5346D5655167B136,20AF2A0CC4CA2324,9D51EA8ACCBAD693,86C5ECCD57FA4453,1F59DF8C94731AE5,FCC71E6D750DE886,1068FA2CA8C6F91F,00002B5A5EE85C68,B2A076A932AF2783,B5A7E78B04425D65,DE51072AE6115EA9,B35D777AB363B870,FEB1AD18D3F1EF7E,423DAD72E71FED57,7C8580BC754E2D35,BF66910CBC6095F4,97BC225F1B00DCE2,E6B5C0BBCE7BF9F1,3F7EA9BA6C73324B,00006D43CD207809,7946EB9F4062F9AB,E9C15559C8D7BEBD,793A468AB80211B5,55F05AF8222D907D,268B6E7D76387662,33BC7ED013A36939,473EF964B81B2548,76D7FD5202CDF634,FB8EC19E942D4AAD,813DE4431DE15A72,75B371AE2D0700BE,00002ECACF5E5F82,036D4BA09AAA391B,DE848C711D9326C8,246693DE8BA774A7,BD96B0220F96139D,F6CABD12FBDEAE81,F44435B627330DB2,B7F12553BF24C51E,FE34821D834E6C64,177BD6FA61052E84,C256767A0C415515,3E25C4493678B162,000069C1565EB931,8A18EDC29CFD9BD4,982106908C5E9ED0,5C7377F301B107F9,04F0300050661FFF,3A68AE405766D1A0,BCA6557EF998F3A0,3F251F23B9B6BCED,FB50A336C4018AD8,675B3AC8ADF50A1E,D6FCF9DA14725005,D59C9FF32C3DD77E,00002C3FAA960E47,FC2BA56DCC75E73B,13B422F2C898344A,FA5E1EC24E3BA640,6E18A29905253583,14D1AB254FCDF92C,05FEE7981BFCCFA8,3D559F7AA6B03D8D,DF040540E5A8D7F0,B17C8A0AE6BD246D,3C548E2EFD3FBD9C,83011A7FB906506E,00002659FFEDBA30,8E144114093E41D7,8C26FF9D35D172F2,5E77D7E77AF70A40,262D3915668C224C,F7764758830AD25A,03F04CF5052BEBA5,134CEA07C2BFBF36,71B8B6DD3AF177F1,0C8237EF536ECCBE,634C4799281958B6,909191CA8BA7D5FF,00001D2160063247,F289139D97F2CA55,C468723D047DE380,C5F553AFBF098D41,40AE045FFD53EF6C,B97C9AF89ED3BADB,43E94D723E5D6CF0,42F6F2570B169BBC,FC60F1EB320F95A7,8C05E595D032362D,0EB1A5693BFDE82B,F27C790F57F0EE52,000031AA5C7206AF,3C552497B10E0234,5F197DE104AC1F0D,7B49E43C591B9A38,18595DCF723445A3,AFBB416389C36758,2790FBCCC6670D9C,2E44243FF101BD48,2BA4C542556A7F75,0323889686358EBC,D81EFD01D941D5C1,2C98FAB0E7ABDE24,0000349C7DF25D32,761A19D94E8F5324,202E3A0C0C8BA9BB,99A49B9EA564BD32,89A7A28E6CF10309,C5BA93FA2C0219C8,F8B84C7E71DA31C0,F4809D3222230AC4,150D7D48B7191C2A,71F69B81A8BFF0BE,E9D18AB32744E22E,2137AA40E5E80621,0000215C2D17973C,417B9112972BE095,041C64C40FBADE58,A834D152BA35E547,845E1121C3073D48,183DBCCC4B0BAD44,DC6DFCF28A7FC784,3E0A7966061F645E,670FE11F49E477CC,FD6CD04AEB02FA64,096207938B86BC59,641A9D81DE6CE858,00002ED32476943E,B8B0AB2B2F56BE7F,49BEF5FBC2932BC2,6F23ABFA841E7CD6,2F91A5C73B11916C,198D8F1D48B9D132,19E693A57B491B6A,2B491197283CC4FD,D9E5737F4869536D,C5979D17C3FCF8D4,82F438C3F376B05B,E10D0BAFE7CE1219,00002FB2E1D39E92,1165B07C6321C403,23157EFC1C2D6B4E,55C4AAD84A2B61F9,D22B0F3F97757B21,279E844ED1A98A42,9B517921046E7076,AC700B00FC098126,727351759624A1A5,51088F2FA0799FBB,AF430207A167194A,105949B44609D9A6,000050AB2310B20E,89A1F6BA3BBBADD8,58F89782B19466CE,DD04DB92B65E9F62,8DE28C712ECF20C8,242D5AEBDB8458D0,4CD5400E4A31B439,D12B0B241230DDF2,BC0209F225D10EA1,A9D78B304D0DDFFA,B87CB44AAB2456D5,409B3943584EED60,00006E15698DAFC8,79D02D3DF77145C1,85CCC781C1FD54B1,4B49BF5BC97BD7F0,8291D0D88815EEB3,8C14C12E83602E2F,7E4197CCFE79C339,F3181CD21F4C4AC3,941348AD2DA641F0,E72B77C7D169F473,1E57DC046F9123ED,70F0075DF04279B8,00006B81D99C4099,B28AD173465EAB84,4E40EE5D3C550D0A,64F67954651EAFB6,E0859EA4D5275F13,05478347622F80FB,3D264C71BE80DA59,983C73D9603723B5,1CA95D69B5E7D9D7,FC160D9901EC099D,14E28621EA1DC508,BAF3BDD2D565BB0E,000013047C35F5CA,88E4119D72D68434,34B708BF9538138B,A657AD07FA99058E,71334F6D891F94B9,FFFD472F8B61B3A2,51D33AD04C8B488C,4F40117A33415D70,89D5CE458F72A399,A6B89083A97714CF,98F96F88157CDED2,6AEBBB7D961E7F48,00000EF8584A1C54,695CE348F3064F0A,DE25879CB5A3D32B,6186944B8D7B526A,1EEA22D3DBD8D99A,EAE4F44C7206E13D,F7A60B8C2B9661D6,F5FC5CC113EF318D,B26A630490403761,96E8DE4258F3B38F,10CC74FA0D7BC0A7,7EA5BDA9E9789162,00004AEE588B6A70,B42DFBF9D1F05202,55F74AB75B98AEE3,0E1B88C784DB2F47,762E4591BAD12D54,DB2CF5EBDAE94921,1B813D00751A38C1,951D9D583ECD9166,F847D85BF0E67B5E,900E05281BECA9FA,F7E3F0AFDF908359,DD3FF1E203A8CA01,000037CEEDF087EE,DBA042D08E188FEB,8C6D033CC5F048E3,F3DE811CE9DF7468,1BEEA53C865BAE9F,75E072DC4060EEBB,2A7E378C249A42FD,CBE7BAD20F924DDC,F6C8A935A3B3DE2A,1A893AA820CC07D2,23AB207D3929262C,6A3B23E41E16D493,0000438626BED98E,0A1FBED14AEEE319,5FEDA50EB1DD3238,508435B45CFF9FDD,6A5A932A93E3BFE3,6FADDB37CE2204E4,ADB72B746DD484A7,DBFBC461C020F240,9B27976682E9646F,EE4A920F9ACB8653,DA7BD6E98A754EF5,656612859FD621C4,000045CFF091E62B,A017FB55E56F91BE,E8267E9DE7194BE6,9A8D6B7B3662A1C8,5CE1799813361E24,F8DEE1B59A1E5D67,3DE0182633D64699,3063BB03FBBC4E44,ED85DC72C5D3ADEF,607C1C4B3649C46C,FDC18076E59C4684,8CEE3C7F68426ED0,00003834AF75B69F,BEF95FFC9EC57FA0,064D0B44A7B6526F,FC2F34DD9003347F,B2F2F9D3EFF06484,48F6B71629FAC8E7,AADE1917AA960028,18826BFE8306F5FA,33511A75738FD882,CB55971207B9ECD4,CDC67893100CE78B,9F0CB5B102FB7762,00000E97B29A2780,83E999A57C952BA2,2F371F2FB9E29E27,170618FB142E6D3B,CACEFFA7F0CF81B3,E7F9AFC364C9EA59,037CA687583DD133,F3991C279E058CEA,7F160F97C6B9A3C6,5598C00E2E1C9E2C,321C940BC26BC44C,21F2072C5154A68A,000017189FDEEB59,AD26805F6F03869A,D5A159B09D63F651,3558C4B950DDA7E2,9D8C4BB260B10779,82624BD4C2FB10A8,A3FB4D1EBE50E75A,9C64DAEC0450C6E8,7BF0CD71546A3058,802F19319FC54E9F,49C4E2FF06991646,F71B3961F5F42678,00000062898B9CDC,0EC22B07E84CDA07,D72B2998D0EDC70D,C0041F456118884E,EC913D95D404CD77,1AA91410FCA3C62D,F7FE07233D216100,C9F2D4057B5F4B30,FE6A07ACC15D591C,3C83E0CF38E8BC37,36203050F08CC806,A4ED2DAC6DD21680,00004323A87306DE,26486B003EC6F2C6,31572065665A6F6C,C2EC3B7725E510E6,E39FC683726775FB,3DA09B379E75372A,7148E0C98DC4E1EC,5C7DE83D54E61E62,4171AB77F4E3597A,6F8A06A37BF1ED31,7B762F95604DDD0E,702EB43B21E74C05,00002C9CC7E1D9BF,85583E6E44915298,478E1F58E876C4E7,5BC955A9C8C4589A,0CE592B1822BEBDB,EDF4B9F340525929,6298D7725BD2F9BF,1C0C5104A2FB1617,1404A70A05D0F268,E8EDF40E3958C62C,E2240857FFCB2872,795BCEDE66E09A1E,000000D9E126F408,02965AD433733F79,7A8BE3A5C719D954,D5F27C4D541C72E1,CD32CB35B68FEEE3,9856DF5BC56F2E1B,A1082D185E6890C1,C8C2D004ADE5CC4B,6017C58732450603,53EAD4F591147D98,5D5638F257B9A54A,8EA1D9189A62CB1A,000042144003AADA,884B4D0CC1FE1546,A41C94036E366F91,87506C2F28CE4C0F,2449A910B4E08B7F,D9815D2A8FBD205E,2F8D5DDF7FA4E380,8B92697998E8B88B,B3B68723F3AC27A3,780EA7D3C53CAB07,18F79CB28D20A3B8,0BF4AC50E5B7DA37,00000BB4F101D9EC,97B89C7A1664CA1B,797475AC23DC2CAC,8D7DB92486E3593A,68B69CE9184119EC,06B9DCC3C64EB60F,7AD0EA052A896432,0A357B7287EFEF91,84D87593C4F4BA33,DA8AF81ECDC0F22C,1015B282142AB09A,2D583AFDF1E46EE0,0000545BD283E91B,595042F6F4918DD1,782D01225B37E935,19294086878F7E0D,CAD752EB467CB1BC,2A0A89D2264D736C,9360D0323439C273,97CF1120E411516F,63024B9D4E0F41A0,50BFEB3BF2819AC4,BC327CE998CE38D0,96F2E6F098616CA5,00003C48973BCD0C,2EE09118541926C3,92302979E8C640DC,BA072E0208EF76D3,F1AC1A1857CEDDEB,26E9DECC83D06D91,989384E5F3D43913,7A6B70BEFEAE5618,C41EA0E05183E974,D59B010714806AEE,FD8AC101237542E5,F4E26D6233A19CBE,00004F4676D1C8D2,90928ACA8DA5E1F6,EBB2FE46EF47D8F1,67A4F0B863F658E6,DC61F7299753A76B,03997318114D1DCF,5BD7E9357E8E7078,DFA519016356D038,DA88048A35AE8AA9,8BA782C5EB9DEC5A,24E843911146C3F0,3624FECDCC0328E2,000065536693781B,90D8AA82B46CDF65,3DCAE555897F07A3,7BF1F1DFFAF7888C,ED23F3A55E5B2C21,36F592C1CCD5A4FD,2B45F0C99828D56E,73F4B01762854ABB,F9351640ADEB6553,484F96583385A577,8B374F6C8898CB5F,743C9CEF1C2529A9,00006C13503B4D39,A0BD17954B9696FD,AB6DB962F945B6D9,198F93FBCC9A9ACE,8D07D69D36F3940A,C559ADD77C85AB30,EDA84231E77E40C9,F3F2FA75C2B24F90,DD940DA882BE5631,BC1E1C80D0A013B7,40E8D80CBB4C036B,778725E7B1789192,000048626F70BE26,F9600F3B4709B3BC,71D40E13B4AD492B,5F63164FADD4231E,B51CD98DB97E2EA9,1E74335275F38AAC,A1FD70A41CDBFF11,862F90067441B72F,E7194105445C6C30,8F9EB0223009601F,4ADAA1FFC19BA4A0,DEB478CAD2379217,0000344EB51F23F1,9375C1B8D75E6E59,CCCF9A86F6DDAC1C,4E1078366B578BBD,7EC686697CF94FCF,1E8A4591A8CC8BF5,2A7ABFE318BD1DF9,1F0817D4322CD1F6,C13ADB888A52359C,A1A85933D2A8A2BD,C6AB19AD927E4F69,5A8AFDD68C31694F,00006554E6B0E5FA,D7620A2C0B5C3F52,4D3525CD94AFEEDB,FB1D74D974BB1959,82ADBA480D531CDB,2E261AB777DE5FB0,52BBB7B7E8807941,C473E594F37A8774,E40E0EC1BBF62708,CAB0F23D85462E95,112DA0012E1C6455,1715E114029B0D89,00003D63FD2FF73E,15030BF661B46BD4,D6E9373BD1599438,3B436C43B1B8D737,7039ED8AE5FA0526,ABF23D841C058B6F,F1DF959F3FC569AF,3934F0182ABC2CF2,08B58E17F457848E,57FB755F4F30D457,82E71D57918C5407,FA9FB9A1AC19FCC6,0000329476970944,A8D67A895E2A3867,AF96215FEF245E28,900DC275D92C71E2,FA4AF750B683AEFC,0215976442078B98,A8A38FD72CC20E7C,2DEDCA1F672A57A8,0152A8F65B6AEAD6,714096149B836D03,95BBA18D1C4A8224,CED85F16631CA836,000009F3417381DA,7C12369A60229C02,F2F7E5ABDC98D538,1487357AF922A860,B8AE0D3E4FE1AEA3,1652765FA1FB91C2,773A60A276E4C6C4,3620293C7320BB9A,2D848C00CA7C6806,076B0B00D07448E5,1124B10FF11DC9B2,9C5F6FB13674408E,00006E43152A9D53,1FEBB25EC6ED09BA,8DBCD5B15077DBC9,281FBA843FC163DC,EC2223AC39EF584D,5F4DA36E8A2A5F33,959826F9BFB6AE0F,647449DB19DE830F,5E6A04CFB10BD9E2,6435A0A1DA0B47CB,A00163245CD3CE00,1433C3DF30A15BFC,000010C786030046,D82CBE736C3AF040,36BD2D01C4FCB25A,77D5CB0DDA3785CC,E8537164D91CB862,14040C7728881516,7A89186FBA6E58B4,9B02471FBDA78B7F,6ABC997111930D93,2B6710158CC3D592,D85332C202B6AB44,5ED7B7E7914A0D7D,00006C9DA4454AE2,0CE48984A6EFDF2D,0669D6AA31DFF660,1CC874F071DDCB6E,02A307EA9327C6C2,A889FFAEA1DDE97C,3134A93713DA8328,8F0577B707E4F6B2,CBA06A01A5019AA7,8BC669A7323C32A3,EE77A5ADC1960680,7828D3129B7E4FD9,00000BED3FBA4341,57B80D541F950B34,5201BF0B3122FDE9,AB29B0BE9BA94A28,00CEB8F7D80B25F4,DF5E935D24309937,0BF1E02FA033143E,1DF5D4583FC7AA85,BBBB06CEA8755B99,8C76585653BB3A05,035FF6E5100D0AE3,184479C91B4A165D,00002C2382CD05BB,113926816BB0B18E,CA9DD781E513D90A,E3A919B926182F5D,F381CE2A9F37A770,EEEEEBDDDDA39C1B,A0CD8F07371DB5DE,13CAFB146B424FAE,3306402C5EDBFF02,CC2F0323EC66D82F,6335DE0BFE0A3499,7189BE5887B66AAF,000012C9D0A188E3,A04DC45992C1FA02,F8B3B69A10BFBF0B,73E8184D8B692496,EA9C4A52CD1F9E65,521D40663DE66DC7,17062BA3DD065750,6CE63D0A0CBE2199,020F7D7B7C994B92,06E5D61549388707,F413D646B32FCAA1,1739A95C8CB94CE3,00002550C24A9877,06ECD022DAD80ED7,56DEE74DA8094D27,0E5431AB604269B5,BFEA3106593C8E93,9F1D7C63FEAD5189,888D0CF6E498B005,8CFEC646688D120A,EAD61AC11DC839E4,B49799A87F4F24C9,6E38B9F8995D9F01,CE69D3B5F33CD93F,000015228E4C44FC,8AF768E3705ED153,5FE551771AC9AF22,EC094047272AA3B1,39CB04E928E5A05D,EACC752247D12B87,0FA58BDE05F1F79D,FD00BE734001DD46,3F1AD76447BEC9B8,67623AD6093FB7AD,8AD62F50570A9EBC,EC18890DD49F72F5,00003014A87C9BC8,AED4DDF3ACCC0009,0E3D159E5C5BD3E4,B96883BFF4F4CE10,00175E848198B62F,16EE702BB20BA25A,014D8A0D203CAFD5,7ADFF68CC75312FB,7C84AEE1C5EA3C50,2A2994DFBEB6B2FC,B94ECC763FC86CD2,82D4D4B545BF86C2,00006963C8E005AC,215D7003730BAED7,07E1CC1D11484F76,D020D04F6D24366D,05F98A983073B31E,B547879336BC128D,0FEAFE4277C91E48,AF44B085B394B2A6,D4D260F345227540,E373A2EA145783FA,FBFA1BCAB42EAC9B,985ACD99C7009B17,00001948FD704856,BB16F3347C05D462,C5C8940E0345F921,F41E0DA149E85F8D,69AF0FE3E7286D47,592D98E39D8897E3,BFEB1F214E48A553,94D2D6B29CC6E3B6,8C42BDF964FC3411,BA82C05BAFFC65F9,23B7F68069D48476,A3548B7E94C52117,000013E2E4C6FDBE,6EEA6FD0E0B728DD,214BC71601C4A976,1F085168B30FA7C6,7FB39CB1B00822FA,F64D00BD7E2A4196,F7C92869BEBD72EF,6AE1F40BE98B3621,2CC4345C010E1D2B,849D0B6403B4C363,88C8C0F666C3CA58,537218B7101D3FE0,000004F224567381,BB8462F7DC9C5F6A,633190B87F1C1ACE,408E519A0D6BF6A7,9F6CB426038BD3F3,2BA38A9A05F7101C,D1550BB9A8B39669,8A55EBB2ACF7DC6A,B963F2DA583AB0B5,5735D16A2D8D2A16,50C81543A29F343F,1142414B39CE5AEB,00000DB4455186E0,C1149EC096E8EEF1,3D6A8140674AA197,6CD79098C4631510,899131FA619E04DF,38BA8F257E490E00,645ADB6AF2AC98A5,FF4F8A57FD4440F3,4C46DC6CE7C158AE,3CD051DE362599B7,FEBE06707E64B6E0,E8EE52F3FB8B483B,00006A4851BB9BC4,E67D682FDE4F207B,53C1D1C4AB201845,EA052F1E3C878DDB,1ED9CDB29105AF46,48D2E289850BAD02,A944F775D196606C,A74CABF381F8EC30,2918E46ED5A1DD4E,1C23967C25A4121A,A476160F382F286C,AFD25332118C2B9A,00004C0458B3D9A4,FB6D9CB99F4204C9,854948B6D26EEACA,7694C188346CCB70,26EE9C1EDFE401BC,4A10B0A1D9705645,1EDCA8E43E696349,34992E9507B931EE,88B7D24AD7B38132,B5CD38FB74C55BC7,E607A9F40719DE96,33A73278FFE67291,000044C6714E58A3,A46BA9AE635EDF24,634367B24627721B,F82580AB6DAAA462,FEB4B29168E73919,87FF34B6612A018F,193AC69CF3CFC352,6D643A07F2F07933,C68EC66FF33F3C5B,CADBA33C22A6B1D5,B488EA40C8168D91,8514A6A3ACF0BA88,00004BC7608E1CB0,7869C26F8AFB6B7B,6FD23F5A494CB61D,C49E7D0F5E0B6361,EB19AF32D9028AAE,DAC9C0E399C59F41,3D6FF6FE5D96E84A,66B983232553CBED,7389084D7040F9E7,29B88B92270D9217,3C32EB2707F5FAEE,69FA88E593A7BF26,0000355993F41736,1C6BEA92B033F0DD,1119250F3AB35AAE,194BAC3BCF00E7EC,4479C4114CED7881,F1B3594ACD0BF39A,57F408B805F9BD1B,37980EECB1BE4C0D,0300AC9DA098496C,939586DEE189BD54,F093EB014D089AE2,FF8755711D71CD62,00005D883D25B0BA,5875E7E0C97CD0BE,B49D46D3AE21D3AC,622FAA5CDF004FFF,841FEFA9BDF40D95,AF46A864E700C8FA,4451B465FAB79D63,231D89B2B8E77C6D,D98E196EAF99093C,1B966D602327E42E,6F5CBCB52A3B87BF,902D1F3A39DBA9E8,00004B5B0990FAFE,77DC56DEF5EEAF2F,1CE66B351F5A1CAF,EEEC0B128AFB929B,99BCC74B8A6B2A9C,111FD07CE3138D48,C3F44BE09D9E20A5,9F6622D36C9232F4,E34304ED4FD551EC,FD2F5180D6A7E096,CC9075EF463AE012,08BF8CEA60B35696,00004A3880D43852,92E8859F80BBD589,7CEB237A6004F40D,EE1CCD2EAF45E9C6,C88F06FB06236DFF,482196894D0A9207,1A547CD1FB47FE65,F163A16F8A250707,56321BE7366404FD,2E6470C7C7D96DCD,D8BD01F6A884E4AC,EAEAC941603A6FE2,000017B4F1EADE71,28EF15895E321833,A17F23AA21521419,295402049DCF8B68,9769EC1D0AFFECB1,CBB9F920C37036B4,1994932DD3C3010E,E123B7F587991B30,A636AF74AB2735AD,44B6AB18C65FDA7D,AF218A1B80172CCC,6739BB06BF6ECA59,00001AA133B5C6AE,B54CF2E1D0FDF11B,A9B1F66031DC93AB,05BFE8007E6B2A12,7736325FE89608AB,A5BD3E55ABCF5A47,AF403771E570077F,3C58366F697C9084,DEE4E14B7ABEE704,FA2BB6A790BF5B8A,101927914086F405,212C5492744FB46E,00001CCF4CF50E3F,799916E44EEB9222,AF2D9577C91D2DFE,DEF5D2EC04FC0E52,D3ABE20F97551D47,0501DAEEA69A3FFD,734327A95CC621A4,3F240925C7AC27A1,471CEC1925CECFAB,A43E8FCFC202ECF2,AFC39C215A7B6CF9,9C07F64E247D30CA,000009A222770231,C6D5BBEF7AEC0FB0,CB4E41075F1F1195,EB3D523A42035495,B73ADB9D5F45BAC3,F879DB6181D623F8,606FB143E6E09267,DEC12E49DB1DB90E,04B78708A87A931B,283FACC32A2124B7,8989CD064ABF2CE4,27FD692DAB974AD0,0000225214167CBB,5414908558AFD1B0,2672A225C81CA1CE,C976136DD48FABDF,47213C8F0EAB953E,5B06B61E288D6306,5CC4386C636CA679,51C085605530FFB3,6903BA3587CDD969,96F10BFE5061A8AC,E39AFBA8BD7664D8,306116615BB59096,000067EEAEB4505B,A3DB7D96BC090DF4,4945B63DC6072FED,BB05FDFF788B28AD,D3944646463E00C6,8470DB66F901A180,477AFE10F8DFB3B0,19D24B8BE3673AEA,14AD0322F8F133F4,929C9F14ABB6DA37,2C83453CB7D02080,2D7ABDC84E456F2E,0000281E3E437A5B,3A12FFFB2834636B,E10D0030E4732B9F,325D9D17DF7F7C85,5874E34B5F50B34A,68D68FBAB85492AA,9FAD69EF6DAB0620,79A4A7A90F5E68C2,5732DBAE0EDBC3E4,E8B94EBDE3E7AB5F,749F4772C7702122,3B0CF1174C97D4F6,0000360B432786A8,2E3218A16F5804F7,D8B7EF0364F616DB,8973B47B5FCB0391,F0F12C75B9A4969A,2A1A345BCBAEB3BF,E38E381813DB34A9,841E8F2C2D0C1836,A114D0FB0984D80D,F2F974F1E42F5BE6,2A47697A14B36F57,D140DF98D80A0A8E,00003A6D4F576221,6A487645FFE3EAFD,BF7B615E6C3E5371,A9DBDAE65E2EE3AE,FC50CAC65CBE8932,3498E746E562F652,D52EDFE9E2CEB026,EA1436DA273D3A9E,6656544AA30D0D7E,88E3AA729C85721D,3684AEA259C84F7F,13EC925FD6D57019,00004E203C735339,57B3FD110FF973B1,46C4BA0D785AA0B5,D4D7D7476707E9F8,DCEBE2010C500199,E0F28450FCF11278,3A3D313CC39BA367,8FAF80A933091989,B274F4A7638221E6,E97FB0B2C38D2984,5E282F472F6F2344,94D38B66571ECBA1,00001AF57E52A3C1,1BF1E164FFA757AF,F43D3D161FB67AED,48B13F3A33BC7FFE,70B88C424FFD941C,721D5BDA566DD2C0,4B8E4DEB5C70FEAD,49909E9C1DC4FB0E,5498AC90323A7E04,ED703458B41FB376,D31F79FE165CFF20,BE366954CD30E5AE,000067782A1E3356,807C553899216CF0,13896675C6D72EC6,CDA5F7AF7164F516,D87ED3DE8D5C63B0,2CD8FFC8F2558EEA,EC751546A83E3005,10824DEBA04E911E,CD9FCB86A85EF8C9,8AA32C28E16A58AE,206DCC6157DC1A77,FC8AB7AA474F85C2,00006CE89C83C893,1B4C655CABC58A55,2CE601ED70B64B05,312F060B919E3336,83A7011CD8FB8EA6,4CC6F8B637552B52,E71F25164C7AEC5A,B660A533B7F53CA1,EC20512D602FB17E,5B88C232CEADCD11,611CDD5924D9031E,C3E5AEE4B968439C,00002C9926E02C11,0B40C38073F6B828,D5F29CC62D4F513F,C9753DAF536AC7B1,883389481B21102A,D037C118D1BD4468,9713410029CADC4F,28894F69FB945421,F0F4FB88FFA6D9FD,EF50C038B6258DCD,11E21A89E0259C72,41E56DF7AF47845D,00004499F085DEF3,715469AD33BD2297,4FFDEF9AB9942817,2AB61A8B9943D2D9,A350DA6F390621D4,4A8ACA45D8C4D64F,6F88263A0C68499A,135BECAC8B53868D,14E587AB6CBE24E2,9A220F7706F7F68A,64B2B05716739083,BAB95009C2BC73E8,000035B0BDAC90E8,EC090C5A6D50D0DC,1EF9154647EA53CD,9F0D1DA5025FD4F2,20BC59CCD1837B3C,02A1E1BBEEB6727C,EA59AF39C4ED4407,ED398800D51C270E,4C1D12C7DA850780,FAD329F77CAF58ED,7CA71F5E95941AAF,D89E16A33C063D92,0000526A878BBE12,CCD457C2E694FBB6,85DE58B1BEB0C130,BDCF27A91BF89043,FE15C1604B9F68FC,B6383283B338FACF,9FCC9422A574BF5F,335AFB74148C561D,22A12E85D3689C9E,4663A89402A7500F,51099C5DBA8C9590,AFD958CF789D23B5,00001BE554BF6385,142E6A8A4BEB7AD2,3A9018C94D4CA18F,27635EA79C87C367,E2DB0D649C21D83A,3258E4B014472484,C0C5BE00007F1475,0ECA9A08614C6C59,CA8FC5E23D422E93,69C40142CDC46595,6D64F24E19D6908F,988CC92B380932C8,000007067BFD2BDA,727CE6F0C0D02433,7E637B78A21BE4EE,51040B6B73FCBD7A,E53582B02A4B88D3,F825DF582774DDC3,1063AE7755D68B0A,649CC227CCB00A80,6A79581DF0A12943,3D28E9E8F1CAEDE9,B878F5A25C03C105,1E232525FDAC03E9,000010DC24535F8E,D325FB60450781A9,9C29B1869C0DA15E,23FAB09C7238FD5B,62EB2C0DF8C3E549,8B74A28717247D1C,6B5FCAF0F1D3B26F,43AABEE3DB675F7F,7074BC2B01F70718,579DF420AE2130A9,31878DB9C58B1862,B9C2FE787CB039B9,00006551822ECD7C,EF8219DEAFC41298,23C96C3A41CD40D1,37AF532A4A4BBA1A,15F0E7BC90F63E9D,7EED2D6957A9FE70,D71A115F675689FE,256C5AC6D076A858,62608CF344FA3CF4,FAE55F1922891C4D,64C0A8CA1F6C941F,A62DF6AF027F6842,00002203E202E4BC,60365178B344563E,FFDD7A93665F2B0E,934178FE71B98374,CB776626D4029192,FD79681F65A2794A,53751EDD21C0937B,3AFB812552AC0632,0732925CBFFA7C48,9D4DD2D888E1AF6F,E1326EC8B3423AAD,38C328E5A12D114E,000016C330E31A08,2D73D9C84595E761,57B1D77FC7AFAB86,259F3F91C2F5FA27,090D590FD7AD35DF,BB362B1B226677EF,A4228EC31EE5DFDB,43D99268009BDB04,425CED503236141D,B4B40C57EDEB58CF,A9739905472EC009,175C22B8BA7EE40C,000055584FA78DE7,49CAFFB30468DE0B,CDB026653D66998E,2FADBD800C9E5283,A2C772D72B52E836,0B867EF9F2DB9FE0,4AEF7AE7856EDA0D,17CBB572A46A0A9F,DC99FDD99085736E,790DC9CEB4E7905A,5CF7B9AC5E771E5E,C64997550E0A586F,0000139F1D6A50AB,E3C40F0C92E2249C,20AEEB14ED019F79,F0FD6F26C76ECB8C,5F10DC9183700EAD,F8353E61E3BB7FED,1CAB08B16F77CFEE,40C09EFDC28DD136,53D0D638E869CD77,B551C314CA701A4A,31945035EC8599C2,38E87062AA7B44B8,000050A8092060C3,72429ED87BC2BE5C,4ACEE768F1A96141,1B987F59B06EDE6F,4678D43B081D0AE0,44F7CA49F1D12742,2A41E778428FE0AC,746827ED8719634A,834E9B3F918DCF4B,2D369ED813240B82,26DBB90543E7D766,D6D4296E9F1804BE,00003F46CA97669E,4ECF3D5F8C718589,3336FE7628337E50,56B1F0AE027A40AF,F0274895C36B9CC6,56399A69EAF2B4C6,ED06B94742F1DEE1,941853C0ACD7E968,9BDEEBF6DB9B622D,3EAAFDB02D52F510,7717308E20814375,39C30A5ABFF8541B,000017A9E1766AA7,FD44E5048789EFC6,C28BBD1CAD8DCE07,C771186247CE9ACD,135C73E7B687A12D,350C0246FD59E33C,A53A9691D9A7EA0F,6B5194FF0E043E92,7346EDC591EED598,7F86A7CAF30778D4,F1C1F028D1615C44,BAD55AE187E5EB0A,000027B280AA3CBB,004F3C85B2088674,1DFD4E920BFBD104,6ECA8D3B042B7D10,12B4A09B67E782C2,CCB75DA96DBB4CC9,61899AE99D0932A4,652BFAA14F4E4E59,2A23EC4279A7C2E5,73159AEFF5A75CF1,AD0618FCB32B18D0,04DDF44986CA21B4,0000147A279DDE3F,91A264B3E529B1EC,969F69E1A1985ACA,D925160601B10B61,7D56E6EF4B7EA3F6,2C81732B0C4F73B6,7AE531EF3218F893,737D1C7298EB1FA6,F950B6BC1C9B6764,610775015FF27D5F,0BD4653B67A94A94,3219A34DC7D003DD,0000425ECCA79708,D94A4B06FFE695A4,63780B7EFECD1146,988DE248F5265277,B54C13765C002151,E02FB845D657C279,291EE7E1CF029750,F08FC46D4EB80D93,EF0BA7B907516521,7C6CEB541AEB4E10,2EEED2AE152952C3,DE8D6C976FE81841,000037F519519464,15D75C20B6C35F9C,BC2EF8DCE6FA46A5,25FC1F0434A4099A,1DE4331B3A8E38DF,638E57ABB08D425E,60FADC95DFEA8711,342E9592B15D119E,1CF6EB8E542B9812,BA1BF19E73895F0B,5353430744AF8614,DD52DF99882EB95C,00005490BB38718E,EE93B3A70CD3A298,DEAFBCB80E448098,799655F72D1D565C,260CA71FD7FFAFC1,A8485DE5CE2C0E44,90485D14B38FE72B,78EF5A2A8C7A9D30,FEDE0E0E6CCC4746,ECCE81383F0C9EC2,FBF75C24FF3D814E,B97A62B56ED6F440,0000422FCB4F1133,94BBB8B7B200D99E,B59B32A1761A950B,35E7E8410C8A7EDB,D6F1B0BF160767D5,9B1CB74F777C1F91,4CD0F8861FA5E484,2AFD2C5621A4E55A,83CCA4098D4D8E04,5F06207D0519D047,1A1185CAB1979D1B,30F3BB2D71551447,00005750FD6246E6,2445F435600EAD05,6CF55EB288B56C4F,FDB8A596481A9E2C,A586DDC9441EE14C,5D142BDC85A4D0D7,9AC61911E408D62E,9652F7BDA5538B82,C33D7067AF299316,C477D2314AA80A8D,710F5954B96FCD1F,41F10B09054EE9A8,00001DC7CBD3753C,C315CEC6905E31F6,B7DF04721D359F23,522E10FEAF682D24,6933A1D7D61EF7D5,BE4B46EE28B0C66B,FB2612087B750E9D,CD0CB4A60379DED7,724F07150C7588D8,9D2469B82688FE58,0F69E5D40FFB4E2E,78B6100F002F3D02,00001583B7D49AC9,A5ED5D0DB0400057,BCAC2A5BC9C255FC,C8F835F07F2DD248,A67C54CA3F784C94,60745F2C2392EDDA,872415B6B77DA9D7,4FC8555EAE0C956E,A0E68DEAC483A74D,48A5225E0079A345,790A8E18DD0E6320,9681E02A62DD5A4B,000019AD8B366954,87F020207938577E,4397453EE6E4A658,B18149A74DA07700,AFACFCA7EF5B4180,6FF5B3D3F0E8B746,796BA35F42F4A44E,187E7FF6D4AA4A6A,861500058E6FD543,AF9D6EA9507B8DC2,DDFF6B817FED32F2,7DB59B1DEFF1A5B0,0000125679CDD063,7739843EEB09E3DF,4E0152D32A90A30B,6E6FE6CC9E9455F3,C22D9D37A03150FD,09783282474CECC4,FBA8DB94E7A1D54C,8C55FE4DB469D1A7,F1934AA5D9C223B7,39252A96C1DCF3BB,D06698A2BCB1563B,0DFF051D88479DCD,00000599D58EA618,51E25BFBA5316E67,C450A72181AF0263,4BF2E3B71B09E34E,C14BEFB3E043FABB,4FF6DEA8A77014DB,28314B33A20C8CC3,894E75565E265F15,3B6A548DA831E749,E8812849752380C8,C77FDA9AC312DB35,1BA9A85D7CD30C8A,00005EDC39C8818B,B0756E5B34F34434,47B5A94590E340FE,73E10B9145BB6548,31BC7ACF42652E69,CBB889EAB4631AAA,62DCF3F43F36F316,837AE2FEC6F4C11E,BCB7143504471E57,4B4AA9C35F2F1A05,3505B5BB990D7553,3A4EE2C750EF2DF1,000062F11CF5626A,BA526502ADF91062,81F4D9B7618F5112,226319CB4FE82AE3,0C8A6DEF79EF90B9,4B2A9AE204EF7D24,E69C6CC618EF79D5,654CF31ADE7D6FEA,41480037CD8FC8A2,8D61296132BA9393,386CF92F059EA51A,FE0EACA1E6175D98,0000627FD7875650,3A89BEA1EFDDEBEF,DA52A11635510BAA,6E29B0EDDF4A991D,9BAD2A0B522AC012,77161F56A8FD99ED,4F408D4E00E754DD,0A6CEB4FA3253E25,5B16D6A7CA06387C,A49F510955F97CBE,1D040A2D5FC24557,758B8ECB46CEC482,000008F6F27B238C,4AED021893859617,64DC29A2DECE7B3A,D1C4A17E3791712E,463A08428FC47171,2234B1299720A6DA,CF5217993D67BEF6,4F27A9FD553953BD,3582861D527BE94D,C19F8AD13AC49707,10639A5CFB8901F4,A0C3BB950C26BFAF,000030973A9EC9D7,0C2B01294187B98F,FFBB0F28B14C7724,C8AF3007615B4706,2E7FD4797FD2839B,8DE8DC0EC186686F,EB5446BE44B3F5B7,E0CC2E1AC2BF329A,D835F98A9A5BE690,1AF707A78992B45E,66F088E8B466A008,8E274456E52C90E1,00003E7F24C38D5C,53CA6D7DAE6D1B24,CF67DBB35F8DBFC9,04418729531BF90B,099D39203C90E5D1,F79F91C2D07B788F,572CC54AB3F977E2,12A34B6EF68F4193,D0E63E5B32060E55,0E1FD8399484D320,C034FE269FC529DA,784FAFB3BBAD1330,00004555ABC36069,59BB01A74AC3B8A2,D4D1D3B76A0F7589,F5E80A8D9DC83AAB,B99687AE73AF412F,DCD3BCEB077BDDE2,0BD2790CB0BC1AD7,502DEBB7C7E9AFFE,DC40680D99A3BDA2,3A344330E84510D4,BB64CB5210B1D9A4,46E8B2B1D044095A,00006797C7765A16,A86731C2A170F753,B3751A20A2F63CCB,84626FC9C2D33F0B,3C6CDF198A81BBB3,BA1660BAB9516209,52C830C31CCA1E70,A24DCD78B404212C,6F1A8E5FD0B60DB4,7C1C7430EE123660,343675FC3FE7C9B8,83BECB8A40C5E76F,00006909FC41FDC1,C6DF8953985CF176,DE69D1917F9C9B2D,0E9D22DD431C3972,8255EB4C71E1EAC7,85B5DBDC7993B7E2,69F5E79E1BBDA7A1,349AF367003E3BFE,4F78092DF06AF1D3,D82C19953662E60F,0AF911C99CD10EBA,CFE6992E5B2D3505,000042225D3E6F38,1B76A347472B5611,1E4D7E054BD62910,8BDFF7341441FBB0,47FBC7B429661F43,769D2FAC1D26CBD2,FB367E07E2DA9E9F,F39537B62F434252,1DCD24E1D8C824F8,8816E27F19A85BC8,BE981C4614EEEC25,31A718456201C038,00005B4BB7F623D7,481AC29D0D09B718,CA2A172B842EBB6D,5728D59FABE8DB5F,A847392F3777DC45,55534D63D7B31A91,AC89591B733F7F89,6BE3FE686FC7D46E,4C2C7D048FA73ED4,1F8B2F44FC481901,6E834A7B50DC395F,C7A1A352718D94D6,0000516F95EEE89F,9126C8CAEEB04845,FBB8F7B3C18B27FC,1F2783016C6B03BC,CEFDA0000FB4B62D,633C2AA8A287B8DC,533F7E8BBE33E96A,0575BA412B9C8414,88BEB31AB52405A9,598B008B20313BA2,48112655D01B225B,80DC06FDC17CF336,00001D665735BAB7,AB2B02F209C84908,8E14825E966262A8,673B869FD5732057,7A38D058A045A6EA,01A9016CEF25DDDA,A364661D90E028EF,833BA44CE53738C1,F5EFB6087E87E8AB,A2D69C78220023D1,CED68908C28BCF19,3430BE14E4BE7221,000036E9747FA991,B964BA40D7D157D0,F16582DE45AAB3BA,366A583996E5CC48,3CBFE9E5E4919F50,FA2DC5E404327C36,083641033BE243EE,48809E3C7AD36703,D4E066FAC7046832,3CCF1B27156D8345,BCF17274BC3E3510,E35D53C0A20B5FB4,000057BA62503766,A5471DA6C990D692,6954343B668D0737,02F2B632D5ABC7D4,7DA3158439A68DF6,070BBE9C91172BA1,04BD36541FDF2A4C,6A38857692539BD1,16783957C10318D7,56AA27EFF111F9FC,7286E601555CF001,8597243BD50541FA,00002E526BB84F0F,BC195B2DFA696E3D,DF4C392D3222DA6C,0666C527419A85BC,F5B18F7E4536BBCE,5F6D6D8D3060785B,279B8FF7B02ACE0D,1F90C800F3A0F178,E925D4807B21FEA9,BE536A4EB3E45D4E,17516C7E5095155B,2A3703A810861606,000045835EDE23FA,B4BDFE3A45593871,4E1949B462A14815,B473CAABD4E35AD1,B90AA3C1A6105402,4423705369D98232,45D73EFADA1D8882,FE25AA923DDD11B3,CA48F216AC5D8573,71C0D8F8D73BC162,E63FFC83B93892D8,86E3777504947215,00001B4DB4846771,8E1C687861A9C748,28B44C4E876DAD38,400AE6BF9A4840E3,F9DE77A98E63449C,AEBC7B3E5C129004,F855323CFD18122E,FD1FFEF9157A53ED,8B7D58437DA42F89,497083245E48FBE5,92256A9DEC41ADD6,DE3270C7CAE538B1,000001DB0176A742,0364B4910B992166,A247666C898D9366,4EEBA2170F0D0099,5BA6369D2581A1C6,61E81B91C4021E58,A053B6246C50497E,0DBD9692C9E74FB6,BFD5A55990E9D51C,37388D4CE494BBBB,AD7580ACC503AB51,F103F427B133F108,000008F0A805A25A,515A5DFED288C32A,8D061EEE8635224A,4B9F5283D985F51B,F530C1852807380A,D431CAAF84AA41F0,4F4AA6D5139270F8,19749273206E0962,17E4DF007DF55C86,823F2395B47A652E,52CCCEEE0698E251,5240A14C5C523827,0000373FC5447F46,00ADBDDCCC1884F0,D4E029EA61085890,E3AD3E07542D9FAE,03B2D2DB263C3D92,7583478A8E0BD839,C0AFD32556BC69EC,90BD3635995B1097,DF9A61DCD281B410,443EC41476539410,8B75292732067CCF,A4A313077FAD29B9,00002B4208E4BE32,7633D03EE55CB3C0,79C86A1403DB4727,1CA520D9D2A48B3A,D1F45C7483152A75,20A5749FE161E20A,E5D7D59E61FAB35C,EA3D7C4BA7D5CE47,5501955C3C7EC7DA,930E767F3D5FBBB0,1E41AC7C1D98E2FA,6EA971046C4C7297,00006FDAE7C0D9F3,5F187BAF56BF0C20,0E7D02D2B7AD0BB7,A4CA2CBC907231E7,3DC6140B3280CFB3,9AD3968A7AC647D6,1F80745DB1BF6409,EA10B85C2CAE17C0,F11F648DB36D86BB,D00FA9DFD70AD6F9,BC9AC22F1F461783,0CBE61F2DF4CE89A,00002D3052846BC0,D9F4F9F69676E83C,E193BE72DBB74F41,D97889310A3110A6,D0F100528DD50BDB,BCDA7C19CC5E5992,76E136A6670F4585,375A5D4059176DDF,42227A63267E6C34,97BC9FD69CE4C134,CE9212A3988EA601,1B00C443DAB936A3,00006825BAAD060D,DBAFE761892E2D9B,AA50A21F76791B12,21DB4D983CA31A89,51665248E150A2AE,93AEF35CA901F699,51824A9120479FC0,C405321AE30194A6,ED0C51881EFEFF17,556BB3BEF71C0803,46A9602D58DDE0AE,A38A8E4793C94E72,00000B0984375394,56AC6EC3D8B8E9C8,19A39B426FB11BB5,E066F40564CCE3BC,EDF623124E43AE68,C263B30CC46D30CA,DB5D8E6BD42CA5DE,64C138F87CBB329F,199C3EE86B1275E1,0CF4E950901A01A1,5590D155315FD9D2,139B25CA54EFAECC,000014495BB65A89,95A856F03C4B1B47,366A7BAB255FBE0B,101823967A35824B,028D2AEC8D033C3D,DE9A227A16908BDB,DD2088512F16EBF6,5E5257772E3DAAA0,AFF5D6EEBCA23CF3,0A06B171CC5797BF,2E601E532D8A8417,A963026A7B3813D0,00003EB02FF69580,A797EBA1584DF804,AA48C6FCA67609E3,B4A2DD4C24BC2BC3,300C267ACD365409,71E68AB5064B122A,CF22FDB99DD41E51,83AEC3789908D511,2961C0E4873EB473,C4FF0B2EAA943BED,F35ED414FE40A142,A12C958AF3901F66,00006773164931EE,40B78BCC758266AE,6B3C60C59AE33846,062B37D3AAD3CD1E,BD6E95559D1E6F49,15D68443B5F1B29E,DCE8D48DAFC1B467,F8E4584C2C38A041,F15D0DCD3DA04D86,6CAEF2F8E51B876D,85E3F6574AABC0FE,002ECBFBC1086CFB,000004E7D5BDBCE7,0F7F2D5D37CB6BCD,FF8DD7D9DDF6E13C,4586D41DDFFA921F,408856E59A48FCFE,E5BBAB4D4CB680A8,A83221B3BE42C6CD,D3124511934C0FC5,2C71C2B179BF32A1,1FF45CB9AB6BA5CC,254241A2066810B6,2E40DE02FC0CDEAA,000029989BB4320A,BFA282A5E69A4234,8DEC8285B8A7A606,7F920B30811C9733,B9B46CA34DECC76A,0D1C7C96665979A3,20F04C85DD6781FE,550F327E9D137DA7,6166BC5EEC5C0DD5,01053A0C234E4B66,5999E6E8C59E2A07,AD0DF9FEBC170453,00004342648EBC65,A17A01E0763B7D05,1C03AB1A07B06A94,F18A5EA515AE19B2,42C2C98A4AC14DFD,E5481694417BBFE3,9FD2BF9FBC188F8E,D47ECEAFED371989,05177E408167814A,20951EBD60C83CDD,996D9057EEBACF67,A905A5E6B2FC10B7,000007BF232A7B5B,AD3D3DF8637F9723,B6A035C1C427B187,4DFB281B611C52A9,2160F04247AAC55D,145BB0E8018894C7,289A8105C246CF69,240DF176C9D6202E,177687981F2ED7D5,AF4EDA419CB1DC1C,98F8CC6F6E46F5E3,4CB4365AE35C98E5,0000359158F060CE,ED3355D9CA5F0EA4,ECE2A0601D239AE0,870765C86BD656E8,FD568736E707A764,C71F5EAC848435C5,BAA102A09FD8290A,DD676E8F93ACECC7,DB52084DBD59A40C,6793CE06CC5F55A6,239902BEBDCF5758,2A220C163D82CF91,00000056FB0CFC47,3A9EA4915C2909FB,0FE02D9082675F1A,537D29775A3CBAE7,D083ED6364E96758,D4492E2D41FDB2AC,A4FEEA4BFC6280AD,E3136EA94A0BBDDE,C299B1BB251ED19A,EFA29D41E53F9F31,902BB97502B14E42,61D7625E40296C05,000019638FFAE02E,0D954BA12184FC71,9FF855FE4DC00D39,18F32DBAB86EB9B0,1C4C8FF0F4359FE6,0DCF41D6B4B5F7FA,735015063307FCBF,B8EC34FE3DE0FB4C,20C308387553DC49,5FCDD7FD73C45A58,4671C385A45A76CB,874EC359CBED78CD,000000FB54CB2619,4659CC08B86882DB,7ACBDFBEFCE083F7,93F0F2A383F41D18,E16727213DF42F91,BA40E172CD499A19,100D38F503B10D8F,CB0FEC7BDED74606,DBA01EE2CF200210,3236DBB2D94E8EA1,4910379991B6A48A,18C46CE8BA8DDA53,00006F488AEE4E77,9001C2A9864F441A,34693B33CA036070,A454B94B2F90CCB1,0EFB5268B6B4B7A5,CA1277D96E0F9D5B,F960BC63C4D19B0B,835A403D57532317,5C732A9212F38E3B,9BFA68C0E4452793,138B84E24A7EF983,9150D9F84BC31B8F,00004090E87813A6,016C7588F867A6E8,016460D20DC898EB,A2D98213ECAC2E45,573D8043443CE1E2,B0A2B8680B7B49AF,691A24B1060CF01E,2E5BFEC77143B9BD,0BEBF8811A70D8A5,317A6792AA5B2CD8,78AF54520D749045,76547F001E35CA99,00002EB7E3FA024E,CAFC3E9CF3AE9356,CED11BDE0F8CA398,0E6D5EF71D705BED,347FE0689A104CDC,F6EFE2D9BBD35A09,D3A9CFD840A95E77,3DF00133587866F8,006B99E89E1157F1,FD762B372962A726,2B422E99C79AEF42,114C539C5212441C,0000310BA9FB885B,E2A7BC0FA62A58D7,F1A2F6EDE3CC4ACA,116CCCFD2B5954C0,37D37CFBF28DBCA1,F2573DFD38B45EB7,77C4BBBD274D9E5A,35A7F21AC1064E59,3C809D6AE1BEAA1B,FBB163D604614359,51447E7845BCC460,CFF6F5DF2541F678,0000421D9D53B653,123FD2160C21A2F1,2950B1CE234E5F2C,316BCD54A2560AB8,B65B0C0EA3AD549E,7D3085EC755A945F,0ACF4ED56405D1F6,042F98F74F9208FD,68DB0424C83D53C5,96B3FFF49ED44585,775DEF186D99C7AC,25C7DE72FD7E9250,000003F75F2B3119,CEB6D53625A1D92F,DDF08D247FA4756C,59EEA90E6D3CD2B8,4F2C0A7E5625DE3C,BBB24396633328C7,EE98E36BD6CA2C68,7950C15E349B7A02,D18FF9417EA02439,2B1EC4822D755DA8,500FC38F1740C649,FA7A096B34DA5DBF,0000287C24F5CC6D,B24C3D1F08FF24A2,093CE12A7F7D7C38,D9CD4321F7BB7828,6072CD00640D615A,E1B70EF46B5DB2FA,E80172EDF4C28A77,B2F6B9CA8D549CB6,E2D49A4BAE1039EC,9EFF94B2795D6612,DC0B065688A64543,CC8C34A14ACA2072,000005215430286A,6020983DDABE43F7,A5E486EB33650F0B,38A2739A759C5001,41150ED591E05A5A,856E71426BC14756,4635BB0EA0FF9641,CAFA824B0483D009,DD876EB084AD517E,7A1CDD3491A58F22,5304967AA12C9A44,A4479DAFE3D551DC,0000555E31ADD319,8B1E2299106FE12A,B45076E3394E7649,92266DDABB08CDD1,768E0FED2B12FD56,8C5EEF5D0A927B4D,FE045FB84C8CD327,2E98A42D9B89D9CF,F38C6E0E7E500429,4177B556F36692C3,59D4FBA659A5C7D6,2309EC0B708FD2E2,00001A5864FDE105,E1E9B312464D39B0,59B64FD1CD2C05E3,F1087BF8C1DD071C,5564EFD79D124BA4,6BA9980205202904,764BE16294D25C62,A872F55E121DBB11,460DF9C96570BFE9,635BA86CE62E9C11,C164CDB65F3455BF,671901684954225B,00001D16180FE698,DD3DE7A8FFE409D1,FF34A1A8BE967D2B,15F7198028F00E81,5B0CFDD32D433D32,0FB856AE6D08BEB6,2C196A49462AF167,12F4B41A4AAA1224,707DF889BC5DCE34,8F4A442945FC26CA,2AE84F329E696B53,F6830ACBCF2CC085,000033A1DB7DF8FC,6B220BB7769DECCC,305543A4E76CC1E9,B98B097D3335739F,0A26A19153017089,9C350286E774319A,F087F08B12653722,8DAE70A3E2D229D1,A6FE6A1BD3A10132,178B727C559FA5E4,C83213F428940428,C84E39E194043273,0000452C12EA3136,6418957DBD7636CB,111C874C8CEE2538,65101AB159157154,D8AE2CA86313F352,C2958FF66BE6A402,A0AAD504E33EDCF3,57EB502D4C628502,D7A221896FC25124,3C6F026E3EAC140E,0B061E10A1F768FA,EB548ED184113B7D,00005617C2458056,E341744F732D15E4,C5AD9AF5500247A6,0DCB02FC0CA3433C,8F06A7EF19BC3E2F,8DFCB7441FEE64CE,A27C5A064947A4EE,AD7048718A86EC1C,DC9F699A867F2BD1,27ABA3DEED089859,4E9C7DBABB305F0E,16BC934758371A43,00004FAC2A6FD2EB,84D46910B67B95C0,B6BE7049BD9B9433,25F488710C22363D,B54B4FECBF30CD37,CF52CB40639A660E,7FB19A9EFDDF4E44,4CF104CA2BC1A0F2,BB18AFCD858D251A,E6FD703519123C6A,5B11EA16496CD95A,1F1FA54B3F07E615,0000376433CEEE06,A14F413E8C0A4DEE,3AC364E600ADE23A,E3AE6CA2FD11803D,E6FB1912ACF9D942,C32769AAB498F6CF,FE2B829D95E6515B,76EDF6246F4BB94C,B25F5C239F3EC767,C7FEC45735460F98,A11FD003B6AD6C56,670922D79FB9B3BE,000045B2471B6733,8D634D00AE828A27,F2A187DDE67D1E5E,D78B872851FA2B43,6B1789A31294B251,C99AB04463276186,05BBEAB78E8B8070,164BFC0FBF4FDFCA,2ECA40F81BF13F67,3C26FB62952840CB,80060BC4FB6C0F5F,568D7AB4BBA7B29D,000040FB13F251CB,397CDEFEED2E0382,F20F480DABA0EB08,5D97CE6AF52B2BAA,EFD0F033782F1C8E,5AFB61C6DB59DFE3,3C5F217C90CC3BA2,2B28F3D7D6A32794,CE8B67CFD8BDFFEC,45EC6E0BCF1AEB84,9AC48E65FCDBCEB1,86F7B308BA51BC09,00005D84FF6E5654,DD72B006D9D453B6,8DDAA4C61455AEEA,AD8CE48809026D77,325254D810F6C133,2F1AB385CC4A8BE8,F2A94F5D6C5CB13B,9B64F91B1557C6CE,7318BB100777EBB1,5DC96C209BEE3153,4D541D7CB48E6618,6D0A10A3DC130BDC,00005AC7923F1E17,5504675730EDF1BA,BE3D1D998F3DE93E,FE5BD953D2CC3093,5A6A65B4EF895F4C,4AA1B39AD1259E29,26F240492B77DC9C,ED1E54EABBF5872F,8D340B54AA4F3CDB,BC044290B60D4321,05099CF1385EA34B,C2EACDCB286C0237,00000B001A177453,1DCB6288F21F65F3,B5291FA6C93BF6C5,07FD5B5FD77B1244,358C596E828F9DC1,1B38172264668C6E,74E1AA88064291B7,D59DE106C2474530,58AEC386C936AC71,2F1A81937823D243,59EBF87868361764,DD9EF5F204B2CE0D,0000247AFADB4088,F302B3FE43586ECD,9DA97FDFDC8453F3,4215C2408E03F93B,3C3D719342167017,BBC9A07D766120B6,A95193AA8FF2C30A,4B6B7F6CB32FC029,B83C7061C227A556,26353381DEAC4368,71CB82EBDE4C3852,B6CF82D50D545C72,0000433BEBFDE1F7,E97D98EE71D27E28,C9D86E1369D14F55,0139D81C5E0D299E,3356D1B1C23765D8,661ED722DF4801DA,3C6D7E574E26A811,E884E03877CE6338,5E59E6E2CC491EB0,68F2A86E45605BD3,9698DA62850F8484,447716FD136B7ED3,0000004077F851E7,2686AA0BDFDB2DF7,9CECEB942B90D122,E8B24EC03A2621A2,D2EBF4DC303F11A2,A2B47402C8B566AA,F1D042A66B720F4B,971DF1D64B4B1D83,1563BEEBB7B8A89F,4451E9AB19C277E9,90060DB8E141A75A,F211C09C6E34B83F,000016C02AFAFB2A,B6C237F7A996EFE0,337898FA152CE0AA,1461B95E042A5F94,9DEAB912ADED3C89,D09749697CDC3FFA,36936082D4E5BCB6,991B32BFE4CAE4A7,88394DA1B2E3F12C,01B47CF45ACDAC6B,F846F65EC82DC77F,B7C2B82DA13BD048,00006FC7AE35E302,2BAF04BB938F8638,E2B4010219590435,026C738A60F0E3A1,E47AC1608C137C29,1265F7381973CB3A,C39C4F22D784FCED,C67EC3BBA2CC1D29,C071486FF79176BD,6B6990649FCD4140,7B9D377213EE34CF,F06C35FCC9A0D3BD,00005F7FBD2FFB95,6C3B8504CEF2BEFF,19DB986F12F798F2,09F8CE53613C1209,A6DDEFBD79F5E04C,28DEAAF317E6A68D,AF7A34731D81EA03,B328B9494E6AAAE8,5E6B8525CBB8CF14,264632FBBB9D618D,C564EC7F458F1CF4,960A73BB220502A8,000032913DB9D127,26E4B36673919DA5,91E5EF31DF6FAEE4,A14B9128D2CC4AD3,8C88F003D291F308,215B1DB158D75A89,7899BD2525BBC61C,A6B796F32327937B,5A6A41D4628619EE,002C0A7FCD708A7B,E07FB3C1B12865E5,77D467F11AA1DE68,000056D7D61A165A,9DD522E1675701E7,FE08721BA5CCE8C5,5899093FD0FF2CD9,B7519812B6C0720C,AD69758D585212D0,99BD98F83EFE8ABB,ABF2B6A9CCC1D875,6F8E7162022EF1EB,C2E6EEFBA39CB60D,8D8CC7806A374F66,B7D7D4DCE0A9DF09,00006BB0C64BB8C9,1D23109298CFCCCD,8B390BB759A0A595,CB0714297452888B,DB50D44EC5D93E86,F110B6B697D7AFED,FC591692292F892A,AB1AB71B33254191,DAE8909DB849DC09,C0AFECF175371132,C57C61CE11C7DA75,312D24C0F7C4AE64,00001208A7154D95,A3A6EE90196C8A91,53F12E393B597E38,39A235FCFE9A4BCB,B0AAF420226F3C0C,B77AA9C98E3C713C,B7A50916C3806DE3,F9E7D08CC57C67F8,FD32562D5048D991,DA6EF19F8016BA95,5ABF6872FC845B0D,0D7B95DA1FEDD6B2,00004017C9E5F58E,997D7D674A6D4D93,6275B0262E1B4F10,1EC0EA40296D2606,CBCAE11EF00BD3EB,B18A200BC054F69D,B11EE1955C894B52,B7EC1F63EF03447B,43BB66C4F8C530E2,7E9471B5E8C9BE4C,DFAFBBCE98640B79,45CDD09A1A2DABE6,00003C240C0D7E72,913B2843CF62755B,662C53F04939816D,F7A0BD670FA92AE9,910231AAFDB28B43,E39E25618152F8A2,B0E3A70A0E7E1F55,743E34F64F73A3DA,64DCF1356D26EB7C,F4352C7E9B6182F8,95C3B178C9936F5E,B796D1D504C8ED14,0000613683C0EF4D,2D93B0A3E7E23EBF,6FF943DDFD4F94C2,0CD665EA17A56DCD,72033891EA0E9771,9C5D63CC1834A5DA,CB6CB66EABC6B0DC,A48A2C6588BE0D00,77ACD1D216B08F55,B1389306FD3E4708,9083B6EB78D23C9E,F4EC6BFD2DA817A7,000007F9438DDB07,A75B2F4A9A32F0EF,3DFD7B68C2D0C444,9E1780CB35EFF5FB,7E4360166001D85C,EB708046DF6B9356,4F561D6CE5B9417C,6755DDA073930B32,627CF60AE5D05EC2,2AF231E9F567D562,6E976A89D4E73F5C,8C30A3B1230C0021,00005A70B5B35A16,13942187A12B11C7,C1AEC8670C8A5015,ABA35AD059C75767,053D2F83620EDBBD,8100D77F57F5E6AD,299E31D883499683,4D1A265F7CD4C300,39B36D19F99A5AFC,ED43011EA1C6E8CE,D6E1582472795B12,FD6569541C5E6659,000010A1769DA60A,BD9F08FBD7D9A299,BCCF6079D9CC18FF,B50F07A391B23642,97BAE95280C855AC,FDD8D3416E64E0FE,15E9EA90C2178C27,E44948A6A406069C,754982CEA788B1BC,CBCD5074B61193B3,FF48C98A06FBEB13,0F60B932F5A63489,000039A3CBC07359,1E6879B3435AFAAC,19412324F2A558F3,167BDE27A295844D,28C4193EF2D1639D,DF8462C7249E8660,25CB4076B2DFA482,20194CF1456D02EC,B36C55DE43DC9206,0025BF56FB5FDEC9,A84C0F9938622D7B,E2B4FCA926B5C3E7,00004D66F69D5B23,C2AB0CE26F91E6A2,770C67EA77543251,465EC0BCF8260AB7,AC23F41A5CBC515B,2FAA8CA78EF2E28F,E1F333AAC970EF1E,33EBE9ECF8960EE1,D402108609E498FB,370C2C34AFFBFF32,2343CEBA7E51FEA9,54A4CAA737AB1041,000038AC546C9BFE,F7E91D9D0172ECA1,66B0A2F6B7B50ADD,E3879B454844F5CA,48968894E4D78AB9,75C6BBF955280FAC,ED534251753C524A,CB493E8E2AFB1846,277F21551D88DC47,1133F4A9458931AD,326F87361CDA2B5A,3A72D7648997BA0D,00004B0A0B1F9BCD,2E489D1F58C060B7,8AB40A75A66FE6F9,7C1301B6BF5BEC5F,722BB397969657F9,EDA3A74D4798719E,D30DF6A272D62953,75226BCAF4BFFB09,B863035C55691B2C,38812E449FA9C07A,A98BC052004D0541,1AFBD7015658BA2F,0000664EDCBC8921,1A4542251FC41337,ECFC860C542F5E16,821206D454AF6260,2DCD8274952A44FA,C99AFBDB2C45ACC0,33CCA934946A615F,40708C4201D19DC5,F646B2CE5BC7C0EE,D25A28172550F914,605857E9BC62AB83,B8DBB2AA562F662E,0000526EAACFED95,9F84B51EB02C664B,CB22535249CF295B,00772F3F44BE61D0,DFA29ECC73EE7202,DB439E1BE3564774,3866CF238A23FC98,3B64539521B5A83C,F1052C45569CF3AE,1BF86B9A81946525,50DF1B7B9963CC3E,534250C18AFD73E7,00004A6AA1EA5FA6,AF463FF35D06AF2D,8FA9D469D80F7890,57EE667FD8AFBD73,D813EEEC00251133,60116053A412F53B,A6C60DAB6B369300,12C83EB79266CB1F,1B55A857BCCE716D,9BC48A3625144FFE,94905874FDBE2CFC,6D0B2F2194A00994,000029194460BFBA,7F537D4B3C05E1B8,DE7B039637D4CB30,89E218C6018A2D7C,A98197216F2B96F2,0FF10D38CEA2FE38,954C55EC80293AC3,F90B5D87B182EF6C,ABC0DD34459FA117,174C1269EF2240D1,2BE2DD5158EDBAA3,32FB23B9711919FC,00004DEEDD66DED8,2382EBD5351BC2F5,846605DD289AA61B,90C31B2A15A3C4C8,A6E0E7169C00704B,4A66BA6FECFEB654,9D6E436945BF2BB4,9047D06248E1AC7E,7FAA2F730C5DC677,E3363F527A328BF2,44E17935D696575C,1FE7B13D73FEE04B,00006B0D582C83E7,969F0D69E1431340,9CACAFB18FBA6B6E,A74D02490E5C632A,2B2353555C4D3846,89F63433D9CFF739,7CB4F475566B59E7,4C03366AD048D090,07C3DBC8D302C113,0DEDB92E314B3BD5,4BB8FD021DFAC937,DE88D0ECB2C4DAA6,00001F1BBB495856,0A756234052631B2,B5892F5B78721A26,15A9ECD050575A15,985CA58823AD1112,30DFEB7F30831B6A,CCDB5183DE0AA70C,C8E5F5FA45EB9BF7,E2F690FD5323DC38,C74B5804A98F4DF3,C5E5468F09027854,AC3BE081818EE2E8,00002B7AB6AB8452,4D188012FBE60126,B6AAAE53FB705E52,7DD02A6420D8D0EB,7C141F7C1838C359,4DF342428A3DCA4A,5728186734B90D1A,82C5969639598EEA,ACBF7377023508F2,6E99D578EBD13CEA,B0A5501F614ECC19,E6F40919B8B9E965,00000FE1DF191B73,65F94E5236DD4B3F,F314B4EB8FD34A08,1E6ABF6B83072C7D,2BF9BB9581231F73,F28F19219F7D626C,B0862595670B4BDE,20EFFDA20FB03875,71A634E70267B897,C7B71246131EECD2,37C5767F08E497A0,08FFCEC921D8ACF3,00002D8BB48A7438,4F71B47E1012999C,EEAB1F02EF3C6ACD,4BBA20872DA6ECC9,4C996FCBE28C6386,1AE71EA7935F6385,DCD2DA22486DFFC2,4FAE739BCDB1EC98,869E48AD40B37B90,3C5E46CE7598E179,59F0314626AA788D,3633CDE837EABB4F,00004798F031EAF5,99E042ABF534A034,CE82D857222736D1,21B647825E620165,DA6923877AB21730,A090DB84752BD51E,0158E79561E38104,EAC44B93ADB16DA6,F17F1F768C5CB395,E0D7D7D45F29399E,07C4AE7EA4303507,B46268CDCCF37CF5,0000135EDC624438,9806BD6117ABF3EF,342E932A0AEEBD4D,002B188A2B2A12BC,5E760FECC1AE7E1C,1F27B2D8ACF04200,879BAD7A2E884F72,6E5B9098F8144796,EFE4862272B76885,FB355F9B626A383A,993B5B18A6EE8334,71012176C0A78E2E,00001BCFBEF81D02,2C48770945B4408E,3FBD3B5BDA36CCDC,87351377FD412410,E1CBCB50F12FADD3,1838947144317569,A5610B34EC3C55DF,71BFC222C5FCE948,975C713F6533AD35,472BFCC8D66C554C,1F26C26B914835B8,5437E82650B2C851,00005A00EE83D1B4,3CFB88ACDEFD14E1,21D006F89C5A2D25,F2D496BBB5FDB3AD,84E71D344036BF8B,313E579BDDA168E7,BD866B470C53E0C8,F2306C7AA463BBF6,51A15752DB33948C,17ABAC9DAB115EC5,28CDC84A6710EFFD,7B0B4CF41CECE4DA,000008541A181C18,AD68CDA7AA4C51DC,45523C9B6E9C0B1E,BF017A32E1AD1795,13ECEA7B184EF4E8,BA2F196400131A11,B53AD15D7805B3F1,CE1DABD54A6B348B,A7AC263C4DE4F92B,28B620C3AF7477EC,8B0D0C82E9ACFFA0,5B7E2A1E80DDC6FA,000017A1A8F892DD,085D22DEDD41A9C8,66FC44FA60106224,7749CD75C478B4D0,CA4CB19A0283E34C,4D8498ED004ABB89,A67B3B992009106C,946AC337AA25820E,CB3FD79E3C78A2C4,9EBB59E34AB0CB7D,A9C94EB1A87A8B35,94D6C49930065A5A,000058BDC9B838F8,6A1CA8EED5C96EDF,D9DBC7AD6CCE58D8,59768BE17B054DF9,20647B36D6EEA36B,74B1D8227E81A1AC,C198475FAEFC9C71,9F0D6984674DBAC7,5E19783E5448F260,221D354CAD423F68,2357B73BD39DFF77,9306514D3EEBFC36,000047B7A4E81103,1C3491CC85106E1B,3A3779565FB24137,FFB129A7629FB72A,908E335B31D9E86F,446E53E5ED391F0A,E9A2B105199BC053,4D2C6FF45B3CCBF7,726DC535F44967E4,26DEF20DD5CD330D,9155FFF3EF87064F,6FE6FB5E8218139F,0000299936007865,1AF30FE9DD80779D,8A1D45D83436FAB7,CF55966B571F28D9,4795F3EA283B44D6,4864995CECA85E55,53762FE77FF967DB,30DB7AD97A831999,C4673966FC664537,BB75570C63223675,28EA11B6231FBF92,4788F89ED0DB6A2B,0000549A4B71A1E9,F8C5D1DF9716B000,593D6545037152F7,BFF58CD47159E93D,AE743AAC7E8A0110,8336140418682B42,D5302749E08A52A2,FC9D6B4BE2975F22,87F6B4A262DB49A9,BE08A4C3418DCE20,5EB83418BD48DF07,FBD29C000F8A7A6B,0000686EDB63CE3D,382C5974552E8182,714C5BC45FBE902C,6ACD15D271C4603A,6D65A564573AC422,A421748D06C88BE0,5FA74A395E55B63C,6764D513AD61ACE1,B2FD71425B3A37DC,0777FEF44C086866,A7BE0711A3B988B1,66EF699CFE80B870,0000328B15FA0BC7,7D0FBE2AF06CC890,9AB370CA89D409BD,9CF1AF34388C683B,36FEA84203A4BB7B,EBF0D3EB85AA8110,92327D1D79658B05,DA3A0469EF10F511,FB0EA3478A0DE328,35853603104CDF22,4BB180440B4FCF8B,BAAA40F9DCA973F8,0000493F26423948,5EFD7B6D1CD4CE41,9572661C5A796265,BC3747FB28AB4367,65EDAA95AE27239D,1B6310D6E53AC109,3F5BCE3FF91F709D,CC6D1163D562B2DC,E28977D6FDB3B51D,C6DF57130CE11F5F,A4730639BE8A166D,13A576D63B06A8EF,00004062804327A1,AD6FF42A660744EC,D0B3EF7EEE4A0507,8DD4EB5548562D37,4EFD9A251431F4A6,131B59FBD9830D74,B59B8919C751D459,5A696F7283E18A04,C593A0CDF310DDE7,9BDABF5A9AFFB6D1,36FB75B1AC2B4633,8FD7FF8998144713,000009ECB5E6A615,A580A9749F99EA4B,365F9DAE2E7D08E0,DD814C5C723CA61C,A760B51AEA4035A1,941B8A954371C106,AEE9B1178A0638FA,475CA3DBA96F6E9D,5D2DF088E194C80C,38113CDB816376B2,59694C869567763D,372E129933330E75,0000205EE3B563EB,69DDDED55E4569EE,F8E5716DD8B4A2C3,4694FCE32C916C6B,8659CEABA9EE9D41,D3B3E1E5F89F36F7,C3595C87E4A91568,CEDFB6E0A771D7D7,8318759D5EC38071,9F77C2F747256944,D6B2D60538307182,1B442650083A46CD,0000481C25034DDA,09F1652E6E75C96E,2DD6197DF696AC52,AFF3308B21A574AC,F57DFAAA123DE915,FAE11979C0D8AC7F,0A05C0C7ED94847C,543990457C0F31E3,B2A621744D7B94CF,8DBD9FF4142F97AB,65FFF93BAF2FE3D8,30BC9B6DFD10D1D6,0000542FEB3391FD,FD5E3225CED58D80,F87A459EDE18C126,F9F87BF38FD9CD9B,A669B245415F7FF0,E2196D8314DE4F68,C55FCE3C6AEF8E19,B844A43977734ABA,C7202F627031AD3D,2B651A1E4118F9B5,3ABEABD13D273D6F,5108D15BC9C0A82F,0000525BA3C44326,3290ACC74A3D3C26,CD0B3EB60F9EC4C4,0D8F3F5D375012AE,5440A4DC3F1A6C03,8DE2A8B91C505FA6,5DBDDB2A9265C952,9FE00F2D8E49C91B,957EBC7ED55A52F3,FCD14788E06A2933,ADA687499447C841,327095C6CEE6E4A9,000032EE3FC209BE,7CC2E359870DC203,A08D7FB158C32946,A3FB809E28B24091,03F0670EFF1BCFAC,9960FFF20CD09BC3,E10CDE688F008714,9743CFE932D63D1E,13F307D6D33950F4,409C8E272428C050,AAA6CA0DAA1A370C,7142BBFED155569B,00006360402DF372,E6E7C548377F30A8,5A424A60C141FEC3,0C5E3B85E3840AB7,A2AA8FE6D64AB53B,62D7544A4692E08C,A44E24F79880A51F,4558B8071ADEB6CA,761EC160CC232453,72BF64F24181F196,91CBF29E54EC1AFF,C1AE82DA1AC3C841,0000195ACEC5808F,1AEBCB3AEF7F5573,3599F9212D2262C5,2D440A4628957102,9DB1C9BEFF976F5F,D4195C7FB12659FF,BE084EA21E325495,D2143BB7AE4D1338,5F42A9FE2DB8E1D1,E9D27575F0C0FE29,BEFE0E8DD81CF11A,7BC5803F94ABD7A2,0000384EDE4975D4,CFD2993D6FC29E3B,1734BC9625AE5B5B,4ED5B19F2B59535A,16AD9D5D77A7DF9D,5D5F22C63BB9940A,5446D1FAE082FF15,D824AE4B3EAD8D6E,0A1E4FA9A10BA30F,8D8DA47DBF5BA542,14656128594D7BDA,FF25C8EAECF08FC8,00000F9A16C36540,DF689E6A4F3080EB,2AF316E58A19DB80,492CAD73039EF525,053B9CE5265998EF,13CBFA3D52C00E27,697FD813EBC135D2,9F36663DECF784FB,427F46FB200B0463,F9143487B7FFA2FC,46A7E9C9CE3B5F55,3D614758677104BC,00005BA281961436,C4515D47F2585589,2CF47A605C53019A,1E0D83689B4FB8DB,44C12D031C673F74,B5D6FDDB1FD329B2,8431DE405E244825,963FF4090A7B4E1A,B7F11DFF1BCD9E75,36598081E3DE8769,9099978C4C492B6E,128F82D7B1DB63A9,00000D84CCB7DEE4,8CCA413187E4A6BD,305657F040D5F441,73283EBB660C8C8D,5B910C1D0D199F94,42347C6AC09C7A4A,6D5A4AC8767DAA34,691FE3835D24FDE7,CAD6C3CE4A18FF1C,1B6441B29DEBB31E,4450CFF1800FB2A5,251524BF61EC173C,000053DC26CF541E,3D98466F28C849DE,47FB3FE2B7F6858B,DFC59503FA8F0C2F,9BF7D53A0ED7A148,FCFED17BBB309DEE,251161E965C8F373,1B4172A4E4E4645C,49ABE8210C0EBBFC,59E22299150D8817,3098E78EA04D58FC,3010258C38D55965,0000311DBF2EBE8E,60FCEB4448FC7BDB,EAB0B58B192CA83F,A77FD6A141A356C8,B171754904E44F37,ED2A1394E30948B7,A4067D126AD6BF8D,5A124C35B07025CE,B2DEB8453F3BBF64,DF05B392418C4905,D82BA0F2D0A4F60B,C1AA9D2D0B50A8A2,000066D989F5C981,D60DC0EC9F628808,9B5F5A848110FC11,2A3ED67713001799,4347DB4256F73A0C,630DC4E1B485C7B1,6106F7D7F9DCAD87,DB5BB846EB8973CE,4A471074391585DF,50D94570B6A62B97,1683BFDBD7DF19B9,A854196C92456CE6,00003A5E09D1910C,4A34428CCD2FAD2B,450C267DE2BC3EDA,CB284F16FA8C101E,78FD0588CA47987A,55F54AD1482B5E95,9203002029C2AB04,188357B64CBBB764,FCE912B6720792CF,4F486CF27B6F12C4,8409632212FB7BCC,4B00F96091D9EB57,00004B099789FB41,EDB4D6707EBD2685,BCDDFC47E6C6F60C,C73D5EE5F23B6DE9,DD698A9B2A4EDCE5,ED14FD8AC63823D4,F4F02CDD7DDFE6F2,96F79DC8EA865D92,0A04C12A44DD2754,5C64D2C0B96E990A,AD3CB76ACD236D3F,29D6C0A1052001CA,000057FB2EBB51D0,643565DC81025F8D,CEF703953DDED780,7E4AD99DFF830B0D,24758EEB3600B45C,FBC5E4D48B8021BE,100D5C1B634D37BA,FCC1BACE904939B3,4F4801AC99FE5A20,C4CE7AFE5DA9C3BD,00FAA09EBCB6D698,C6C87847A9F70A2F,00004675850FDD9E,040E02F222B3511B,E23F45CA415514D2,33689BA4E0115EF6,EEDBE012DDA0795D,656D174ED052CB63,8980BB7BE202AA06,7CC94C02C656E816,B2CA1D8169BD3E96,BB447AE598736F78,11B2590B1054DF07,8451C34BDAC5FBBF,000039D4225EB957,E5A8EBBD48B1FC50,F0EA74BCD950E4F0,BAA1F7759C89058F,145B08591660743C,118A11764AF55FE2,B2997558825DB9F7,FCD3BAD3C2056C4D,CE2CEF88FCFABEA1,7C25F2E925070D33,764A2B21F55E51EF,FD640713163DFAC3,00005752144DAC99,7AE384453AFBC321,D109998D28068943,49111E501B70119F,D185648467763907,1AED656299EE79C2,08430312D5839745,9D4836F614D37F8A,C9AA9DE683A41DF7,078CB34DF5F5DE93,2490BB54E9F1A6C4,4797572048D58EA9,000009A469555A7D,14B0065D709B206C,F73CD255CE7BFD66,314A96BD6D0A831F,179B1454EA929A01,401DAB63027EDB5D,3D80F422A891B519,1F3E47454A6995A0,98C1FAB64906613D,499C739F1AA48742,8747C8507A685373,B0258578F5EB8EAE,000019539AE06DCD,8F12C3F4C49CFB0B,7E0E47E3C68A63C4,A92CF6F664DF850C,3153ADBA530F7617,FC4640634FA98E35,0E5EA740F21F419A,6037C99EF5D44238,C620D08B1C7C64D6,97535917CEDD9605,30222304748611AF,0D7E28D792F1E8F4,00000C40973F92F9,E7D6882C4CC40628,FF9AA0D75507FC68,24CB46E3EDB2624A,526B7F3E264079FF,1B538B11CB60541C,4057EC220B00CB7E,F55D37F16288D209,50089867C853D704,FE311ABF987B9A9B,694DB6853226F9E4,705CEC4ED9F490F6,0000074E85DAF686,B8B78FC2F2747CAF,133BB4FEC0FE1C8E,FC8E658081F4BA7F,700A63A7A9F0D320,764947CFB2678E43,0397B37A46923315,D2DA1C1557FE7F5F,08D41D88BD4902CA,8BD5E3A001608B21,CB1982442B2A74B6,B8197A746BBECE81,00000BA019D744C6,A9E18D29DF69F956,EFA5E73A879998DE,3CBCEB050231C256,7C1053FFA8F754FB,308BAE6C910207EC,29C9CD634FC157D7,990A7CBA5C811990,3EF08B7D9266DBAD,4B59F5FC1DFD8807,A8268F8F9C8B2244,2FF7F5A3AAB3EF8D,00000AF584FC7155,E9C3EE0AFE72C3C0,609DC8254A04A0EA,E615E00D978E185A,1EDDB3B1EC22EBE3,EE51BF14168C8066,14BED2F50FAD96FD,E92D261D8528686A,B9B88229D5083F9B,11F8491737A5B1B6,BD4D2284D8F2DDD6,76E7076D6CB317B6,000010D2FB4E97AC,A97F2DD05D824CAD,795C429A4AC723DE,C4E2153BCCE8F075,67656E7519C70949,340CF98F6428AD6F,0F05ED662CD81F73,6B7B0690666B7433,28314EC999930C39,603D8BF33168B87B,3AB878C3FB6ADD90,91A6F29F1186930D,0000297A4305FBEF,E5402F61EE56C20D,CB55EE5128DB8948,F5CF353441F75FE7,8966BC8BBD6E6766,D75339572742A157,89A0234A4DE6C735,5165A679C4E7E88A,4F869C234BFD1CB1,8E632CF31AB2B675,579B3BBDC8010A9A,6666AD72D53450BC,00002275186ACA63,51F4F45DA91702E9,01B314EE578CAF5E,BAF1E4CEA325A7BF,0BDCB84DBE0E6A2F,93A8BB1F01A68888,E0D8EEBDBC5CDB2C,7725032F2E74017A,20E1A25D752BDE66,5C7016763E3AD6F6,A5C26DBFDF668AC6,597BEB255F4C8F0A,0000058736984C26,17D6E4D7739FCF17,F49A689D247317CD,4FD8598007481A72,E66F7FE81E633246,124A4FD639C45EB6,406B6621FFBA5A18,F36DB8E6B8251315,CBD4AD4EEDE32B98,1C120FE21C3EDAF3,C94C0367EB4CE770,CE002D8550E0CB58,00003E536939A8F3,D3E3BF5E0EBABF9E,665A737214D1220E,4F613B78D783864D,ACDED7E51016454F,82FA9FFE4C055CF9,DA1F123A45487A20,9D0ABFC800C13D3C,AD090F650EDD363E,BE1AD1A15C0E485E,75E864391E158302,D8B2B87D57B26502,000021D8CE733832,CCE9B67C6CE35D3D,552524ED2FCF927D,61206E1F7E8A8912,A1DC078F607C3D88,EEEDD007219672F5,566F962A1E3DAC7D,87C9423B3806E5B0,F57C23D6394D1283,09E05A941CA7168E,91CB27CCFCEFAEC4,F6048D58BA7F17DD,00006904A4481C7E,6563E5B6A79DE4CB,0F4004B8A5737317,DB417C14EB7D470E,A08F89A039FF54C6,3B897E4842C699BF,95880749A787D1FC,01BEDE0F4C64E876,3C0F5D0F01E55B7F,2021967C06BA1A48,A09D5E15903FD31D,271B0DA6D5323376,00004744F0D8F836,F59F3CF8E3CF0905,33E3CD86965AFAF7,6863FC4021A5CDFE,BD7A89ABD09E53DE,D560B086CE03AEB1,805F90CC1C3D77B9,9F8D7BDDB80FFC3E,3A2798ABDE979135,EBD9C0F735F07EEA,90FB558B35C5F482,7D8FD3BAC6E97FCA,000036BA668454E0,13DA8622A90CCEB3,BFD941DB9F812A40,537810CA50C3D5A8,09B8E6F83804C505,001D841CF2FD7347,FC3FA238C5FB321A,BE9505C154838103,57AE7EDAB80EC89F,1DF90488C52B032D,5014A77076C1FB48,0A170B14F9AC1BB4,00005229E6D30B7E,4D32BFC0FB419A34,6B436254596131A4,31C8F2FA79E61A7D,09522C1BDFA31E3C,D184D94B031DA0EA,DCB7E48AA9518652,9F4FBFE1C61A81F6,562BE40B267AC4DC,8EADEB472BAF0B58,8FB183DA4EAD1249,0238D8989499782B,00001EC1931EF083,89D6D0468342D232,944C20D3B4E56999,9C0F0133823E70CA,CB33545F4C75640F,47E0EAF49DEF4C39,CF96A06B75A5CC69,BFB6FD5299EE7A10,0A50380067A449D0,AF4AD0887CD06F64,5834126BF0F26F61,B5C3451727362269,00003332DB9BCC97,563CCE101804170B,59D935E595BDEE33,54C9A0DB805D7B61,E83CD41DDFEBE1EF,AC2E94ECEFD84D04,42DFE80B79FCD560,18AA509F57226D1E,9A2D07167AF4FD1A,33EAA4965BDDF9D9,21AAA829DB398F96,E137F5C0F0F43179,000022DF4A7767FA,B5E75F8C20A2592C,2834989C3BE837E5,4F28C134C988C83F,D5ACEE663E3CDB5C,61291BE21B5E29FD,AF63DB965C0282BC,237221EDC68BF954,C7B4A3AEA0A2120F,EE8DCC0482CB45EA,D6807B6BAFFBEA10,CBA5FA7DA28A67C6,00000217EA611AB1,3902FDE65619B8D7,6DC8F4C0504AD64E,F9BFF576114D6C5C,3C49A35E13C36B39,BAA51D60E7B67734,A21ED388B55AC1B3,9CEDAE4111D59E69,2A801BD105C9F7B8,E2504E7E6F019183,F64DDD420DEFDE01,8CC3C2C756662A97,00005F41C5C05349,8D5B4BABF771EF36,CE4B23C8695A3ADA,BDB13363FEB528C7,353361C709E4D874,8E51144D402AD769,F6496C9A4BDA8E53,3D323EC2F0C0DD36,895F1DDC3591DEC7,8CA191204B8F2A99,30826E8E4A11EFDB,081E66C92FB1C08F,000013CC6D45CCD4,077E7D08195FFE91,AF99B28B39F19603,FBC097040059ADC0,D89721773DF92772,B97E2B7F4AD239F0,4C414D7C5CF8AF0A,019E736551839407,2645D547140E8E1C,612041BE644B3205,FA737F66A7F07B77,D5B11E5A4EB18342,000016BED2449CEE,BC0C79DC630B6C59,DAFE922E88D1FA03,2E880295183F6256,765B9CC6378CBECF,E25832BBE5BCF5F1,5BB5370FE6006FF1,590389DA90A5E112,A2057ACEFEEF68BE,F7E0B620A0CA2117,4D8A66432C848FC8,B99AE34D5405281C,000045EB42DB87D7,48F771CF0FC515E8,BBFDD5C5245680BD,D2E251496EC65152,F58244E625BC8C64,7F301254E02DBE65,AC3EF428C666743E,28B3A0ED2BBF82CE,500B4313FADCCCC7,5BBD3A234C6A9B17,73E8E2A27984FCBA,48F5CFD26C394EA4,00001A0C9A8457F8,33348353F4A2BD24,0EC5EFC25B54B326,7FC668D9F0B852C9,81D39FE1DB2257D9,8E62ACD6420A5C2B,B8A752C0C4C02A4E,3D5E6531ED443FAC,D145276C817DF6A3,639FE44E0D136E63,EAF1F3EBA4F770A6,443A6EAFC41A76CA,000052FA30E5C6B2,07DB5A3E6A3692CB,A5544AAF90611E1C,049CD04A086567A2,A9460985B3E4EE0F,173807480EF9539C,490BFB6250C15569,FA04928179B47DEC,E7539ED3E90F158D,1FFF9BF0E7A196FE,C7A484B1A71BCB3F,BD9FC93FEA0B2706,000036310D7139DF,C3CA204A4B94DBDF,0247BE92FBDEA311,DC0F0E058A7DF232,A53FF227CB669A58,D461ED920FD0F6CF,EA8EF1B6C4C60944,C2FAA503DE6DE379,BD3D85414FAFCA2C,547D88301AB2A6F4,4897DEEBAC29A8EE,C60CC189E53C8CC0,00006E2860B7707E,654E9846AFC25E9A,4A6C432422955BFF,D479E57E806F9B0F,1EACD5D1A40DC6F0,70FD51940A72BB3D,2B499D5DA9816A74,63ED68212A582278,9D4B642D67609ECF,ABF524D84CE99BC8,63AE535EB130B68E,65E0253DC3A85458,00006D47B642A56E,C148AA51E055872D,8E324779D168CB32,0891E7AAFBD89EB9,C3E1643D34637450,5B5273147B55B0A9,62634F4A463054BF,B69903B5848C2A2B,9F6835277A93746F,D4A57101565060CC,5094121E7DA475F0,A2B17E38720483E9,00006633D1D9E422,2C3AFD6A626BFF3B,EBB37E2E90DCC6E3,00290A635C48DFC0,DF782D3BE2215C59,D9A7581D83897148,5CD75ECFAC32FD4B,FC0FF366696F1A4C,A338F112E6DB6B0A,41C619904A1E03D8,D11741151EC068FF,203F87AF5A6D83F5,000054D4D78EF693,DAA80E5946D290FB,DE9C468FBFE9C640,4F559021BD23FB51,24D5600AD58D0C25,1DF90AE480489E42,FF6251166692978C,E0EA3360C57F5709,DE8B69EDB05B1B93,FC70ECF9E211EE21,EE02D7938525232F,E622144C11C3D092,00003B0932F76379,9BDF866D1147823B,104D74DA09064739,5B94D16FD75726B9,6C343944F80E8E19,758E60EDCF612E30,837DE24F34AB3C31,680BF134F7C6164E,89BC2F951349F1B2,CC438F34E9B0C6F0,236730025E17A5E8,669FA5603276CA90,000014B3BFD5492A,F87760364D3E22B6,CF83C285E6752BB4,DC87C4B39FBBE9B1,2ED1CED5E33E0243,434C81D3A3D8A287,B98369664933A519,77E6490F5A9E83DE,B37D59DED37F4567,E0089A234E212CED,D6F66911726BFA14,F3521D0AACE36C1C,00005E11BCA91494,B5A5B96B4D50BEAF,30F8583B1D425025,69E0DFE39938F0BC,CCA27FBCECF0CED3,C1AD89123AFCFCE6,9C78C6AC544F0BC1,5E24F1B8AC9ECFAF,A6105380F684EA70,6AEF590A84354364,777EA6DDD519D373,80A976D133253645,00000A980C30AC03,E713DA860A6C9175,1CA7DAC141BD05A9,91FAA9E95898D639,856B4E2957E91474,31A857939E84D300,C95ABB1C66751A15,EC6433F7D3077F2A,B80846FD1E347D0D,452A57EEA40938F9,80F5200815EBC71B,B7352EA0187C2767,00005B2179724725,A42B14F2CCFD7353,938429792DAEEB1F,18A1E4FE05346B24,2949888B18A67FC4,129F39451EAD6158,F1FB8B67684516A4,F46838270512AB54,29A1238626856648,0F52E093367AD6A9,9145DCC843E9805F,502F51925D667B5A,000016027E348AC3,56029B7F24B6F996,DCA93CF3C9A7E23B,4E795C2EACC539E6,2E91272018C5A9A0,479DCCECA9CE310C,27FFCEB3D6416015,037F093951665FB7,78099BCB0491C2EE,7084E73DAD3355A0,1FEE7C5F8D8FA80A,86B5AAB7985B1FD7,00000BCEBBC9887F,DD11D8BA0FAB4584,A3DA540DB2F5FB2F,5D4988539F0364A7,528549CA1DE048EF,3D648E69CFF07D2A,8487D6E1488ADD58,B54169B637A312B3,94225BB6AEEBCF7D,4C961390BCD60B1D,C2DC536C217687C4,71AA70BEB74D187D,00001F2ADCB69D0A,9C60DF292D2E5157,ECBEBCB3739F9DD2,059CA5D70108E0AA,C0AE2AF3789C9F62,2CBE6751F8D1C691,110EEDFD39BD6251,2C423AA000993DF0,3E8D828BC06F7E6F,E777C5E5E6E43B4B,481DC24EAE2A9EE7,3BEE29138D9D73B6,0000596C658E18BD,316BE2C2CE7E5524,F58F3C67FD0C1659,F464D82AB7CA2932,8DAA582BD122075E,CB32C9DC801CD1BB,CF27C633BD6FE0DC,6645AC35A0DB1E3A,8E138D15B7ACB273,568590D47F583116,6856DA094446B253,785456311CD10602,0000383A7B486122,2563EB719E1FADD4,8C93D422C4046EB3,8AD7C054874A9810,D839B76D51609649,D51D6BC971D47E51,38D1A1E875EF67C6,103D21F8275E1146,D819B41373F9D3A5,BC77BFDEBD61CFE9,274E8926C5501C4E,7A733C0C4C54B41A,00003F4F73084CFA,ABAE8ED5F82B0680,A8B95E8FFC14C455,E8DF83AF192B0E60,443E3E9D6EFF0AC7,C2968B0B05185376,A0318260D0FFB041,B301D40052AF3974,CBFC8C9902395B70,CB73A3F056D236F2,8A9B5A07952AEBCD,2E69A9F30C7BF42F,00001C5605D5F420,4C878FFAAA9ECCE6,1B2C694DE4260D9E,05A0A4CB41EB8EEC,3ACF6C2F63464FF6,42567F0B56F4028D,DE50491DC2F9AB7E,F9E51488C2415BF7,3BE1E4A6A29B1604,FB89A33E46458437,5E1AD924C5C5C591,52F7C4ED87467A0E,0000241D0FA8D867,A318D35E61FF1D2A,A86374B5DB18E65B,24665617C93A0302,F352BFDAC6E91976,2CE390C4CE72C94D,C15F676EC7A4833B,E0F48CB3A408C094,F687729CFFEDFAD7,D41EFB97AC9AEF62,F335022BBDC16504,B256E9C6792619E6,00003D4FE8E415E3,E1A5835DDF9BD2B5,83820FF55CD6CC91,2E277EF4CEBE3F0A,0606AF9094C7573E,FDA337D6F286F9E2,A09B73C3F6C801E8,4ED6373886C9C69C,3D2267728F1DFDFD,814B1AFC84F2DED9,523221864838CEB8,6F6A67284AA5690B,0000203678E31369,0CD990FD29CBBA6A,10DD70E58E4FC1D8,5A0A484E2ED4A97A,EB065FA9EFAEC597,7C4F975D6DF62DF1,9C3D997DEEFC8F09,0452F29259FADD5D,5AB97EF4DE91ABFD,AB0417105EB48F1B,052032E8055EB77E,CB3F9A8EE503D31B,0000500B9DF19724,FB4DA608FA4DE382,879387A075F9D038,9B150061FD42877D,A08509EFCFE0DACE,3C33F9569CB4F440,B1BA9DC0B468EE8A,9BF6D57D6532E38F,59DF991D3DE05E54,790CAFA3A42A78A4,74E04FFF8C3252C2,CE62447A8CE813AB,00006A572522F7D8,6F57D302B4F0A306,11D83460D4B6AE1F,5D5B2546A4811604,C0A3BC5D1DD684CF,C2A4853DA4E968A8,635972C32C5EB4C0,ABE746E322DB98FF,B01C003EAF944159,A62BB9039E2E2453,8F28ACFAC37B1519,43CA6505F0B6B680,000006A5B2FB8BEE,CF98FC8D4DB72D6D,FA299B2F12FE18AE,D8F9DAEF5DF603A4,196C1C9C9A42C16C,D9D68A67337AD105,9F379FB4FFA867B8,25F2C87A7DC7683F,8D38E25CFCD9AFF9,CA6BA1D4CC87BCD5,20EA88AA2927E1F5,3192D1AC8823BBB1,00000335934C06E7,1E4E694750482E74,27C44FBE959777A5,8A69286337CFB532,27238BD5D5A13CFC,602CC397F8A8251D,11A53FEEAB36DF92,EE86995C513FF3EB,657145D5EE3E3DE3,F33D20F962FF22C0,FBBA16ECF96E7D41,16078163ABFBDF5E,00005526B87B3C75,0FCFC86F34C10EA8,7ADC161B7D5659AD,AA54DD47DCEC68BC,2C49A54AD9B73D2D,E2E8D7EB9F2B403B,D0011EE5601CD1A1,32DB9B2D6DB5229B,7900FAC1002F6DAC,96501A73567958F3,58467DFFAF695E49,8811FBBA0981F699,00000C1814051FD1,4682E304660321B6,8BC18F35407668E1,EC7B89D2AD766860,DE8E78EAAD8F0CD3,AA2DDF58A68525B8,D7876BE71D4953E3,FF0C9CF0FD1784D9,C054DD85CC3046F9,0A0BC58FF88C362B,9C2635FD37EF9DD1,D377F026FDBD298F,000034E60BCA8254,D729F0553670CC26,EE22A18F707CDF19,2AA8AF841FFE1718,759CA8CE49B347B4,300D603C33A03DD7,D00AB13C8EEF33D1,2D3A4F5A38A9A997,D07FF6342CC4563F,CF6CF28222E1DD4F,44C70D3FEE8A7DCB,D6E124C173310D67,00000544493FB8B7,40A7D1856D22BAE5,0053341FDF697712,9E1128EB9EA7B8B1,13004D0E16A3A565,1499C27283C54280,5DF74E52AC1DB078,554D75601666CFBD,698DA097DE804F8F,9784260784D05F8C,EFE442475ADEF241,D94EF62C70168327,000058C7D121B012,1A4E0B9F6922EFE8,E54AC9015212B9E6,7C97681644C79CC5,21300E9B8F3B4ACC,B1EEE821CCA17C39,E9F099FC2AB08647,00B04A4AFA72BC2C,FC48417CFC744D26,EF926794B84487DB,81D73CF0C3484945,A5E493E5107203F2,00005F92ED8F1572,1CF833FB81C0FC38,AC122EBFA52C4E53,1E0E736DF937C190,699828C377295402,E71AECEB3186B26A,329FDE3DAF6FD136,1563F5261CBD7D09,94FDFD0CF55A46DE,E4ED5DE048F893B0,58783687578ADCB4,0952CB79A971023F,00005B5EA7F7EC29,CFE36EB77874D6DD,0DFE43FC1B9D4BA9,B1EE80E707C5D4EA,56165D8241BBB013,4B860EFC4F18E7AD,4096EFDD36F94068,9C23E696579C1F90,D683932679F8E4E8,79C46F4AE2E2D0BE,E58BDAF4120C6177,0B9F500CA9112B9B,00000614694BECDC,DC994CF4EFDEEE59,334DFCC3C1CC2D1C,E1340F14E89870FC,A0E70242C96BCE66,4CF45D6C903CE261,ADE78B9DC499EC01,B3863176DBF79FD8,7FDA014645EFDE2D,0AD923CB6697676F,7AB36F49A4258290,640FC6876A6DD6A2,0000242A7A5219A1,B4C76DFCB65CB814,B1266C9E547E737E,3B2D99CEE4586821,E45A28BC0EBB7F1C,67FFC7FB4E7CE8A8,5FB0BCEBD1B893C1,A35754C6924F30FF,AADB6EE4DE6752EA,FBC046FB01C8C624,A473CE053FEAF8A7,E01AF15964BAD891,000005AC94533E01,E89956A2B0687473,109943DAF24F463E,41BCF3D13CC8F751,123C0F6988CC8C8A,F30DDE340AD57366,694FBF7ADB6A5D13,BED99691C28D64F5,B046B0D2B23BA509,B4B723608EFA8228,854CF7198876EADC,6F58DF21B276D1E3,000019944039B184,05DFDC8B7D9F81AA,BDD48CB4EA61721E,05606459606ED1A6,2359DDF6DF32D627,3D7F20E561CD1969,56C78828E1311797,FBDEE1F03527A740,132DCBB1DD39604E,40FF93F18AF74653,823539DBEFF623F6,4F7CBF2E3B9E8975,00002B81B37B4A8C,15AF84BABBF928BC,5E37FF797E9203F8,5E3E7E57993F6830,6582EEB3BC579A5E,72CE778A049C485D,86E48F405E8A5BF5,DD13B0CE992E7D76,9E215E87CB442693,9FEFA65326C2E387,F5B7396C04134EBB,4510C822D1A09F33,00006E15D9E3A500,A01ADC1C0EC799C0,B45A5334E7FFD166,86E9E4A86E04F95E,A1C792C9707E830D,4CA3DBA6E41A6361,F03E01E8AD5EDC18,AE700AB654CDE377,BB59E289496B277C,C819ADA4D08393C1,575384FC5579A298,27E4FE587CDDC0AF,00004EF63D2A12CB,9B65683423EC1582,C79906D016DD5316,5FCE805ACC216D3F,36995684490D2DDA,A972DB53D88BEBAF,F6552140F29EDE4D,D1417284701A24EF,257DED2988B56A3B,413826B173DFA38C,422473C6F652151A,8108904E9AAE89EE,00002DBDFB3858B8,36F5DC3F953669EE,8B64F0AEEF395B96,6E503110176BFF74,775CE16CFB177855,EBA50FB703A8A3E4,271EA63B2192F558,B29F156B65C0584A,FF2AD136205FFD0B,F966C93FEEA58DE2,0839850AFC45BDAF,8987EA1044736087,0000628C4B13D9B8,2A57B49142F35374,FB276F837F997D93,17F2D22DE2B7D391,43B9BA09DE22286F,434D35F807E8345D,031E6667C401C250,B5D5C6069DE43F8C,D660251FADFC0196,31CF9A7EC8E4266F,A249ACD67DF6BA1E,4EB8AEE9D87AD511,00000FE63AB18ACD,12D14205D2F9D943,044CD80A0C20B4B5,0EF605D4B365F5F6,3F2D12CE69365073,FA3D3A9A8BBDFC91,825551B27ED6071C,83FE0947718D85A0,1854946BAA2BDBFE,9407222329D73623,51D7392B9AD0E843,ED4646AEF1940EE8,00001A44A00C61AD,2AFD75A913EAAF32,2918FBA06F88C9AB,A4AC4DC7CB526F05,2D19E9391A607300,07A79E2B34091B54,1D4809DCB42F1792,63AF4826F85D0739,4FB1AF7134E78875,DBDA90D7F4168B95,2A4AA9AC804021F1,10BE206D2B037075,0000099FF25CA24B,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,51EAB6E6A2886C69,78EA0BF5D8EB2B3C,8DA896F199890C2B,6B8CEBCC75237144,6FD6E59F9A9B7A3E,9D051EDFDAF36367,64D34667DA122A73,56AA4F7AD9E72FF8,782B768DAE2A0A38,09D47C529A5AE770,1A5048049D1FA98E,0000111FFD261D4F - - -T_tate2_firststep_Q = AC2B2D74F888733E,DA9B5D82CAA27D78,F8656EBC40D57F4C,5E1CD5BDBF041897,1A30C6A718D110C8,42ADEF0DC70D6806,3BFA8FF5013BB159,5E5A1D50DBB0E0C1,3BCE4C7EDB3B6E6A,A2C0219900C16A99,18C7D034FA944E4C,00006715FAF4D0DA,D5592BABBCC2584E,0E0547C84CD5E0C1,FBE528CB2D17B51B,2168CC83A03036BC,46149EA13591E9E3,FF230F71ABE6A6E0,D4A9A33BEEBB78FA,63627D7CDDA2D559,601FCFC408949785,CDE4532F5618BCF6,BC83162A741E1D9B,00006F443172FD95,F15CCA64ECAF5A88,952ED60EBC735272,2C5E9BA5561DAE61,948952AD32E5CA87,31D2F32D2C887D6C,580EF5FDC2D40B61,DB49D392D81A2D21,8B011B5F9336CBDE,3B4C85B0A54AB1E1,71544DD7454B3E41,C6D6334162EDD2AC,0000224A7B1CCFCB,38E59BA0C402905B,662836C27434DBA5,CF76292E8B52FE60,C8DB8AAFAFB4CE6D,2FEA96B083869ADA,60347DA847067588,BC88696946B32293,17B2DF2CBFD97F3C,9B56940153EFAA92,B10099C181CFD23D,D3DD0D847F870C47,000021D326FF0152 - - - - -T_tate2_Q = 41FEAA3F231C32B5,97F8BC8686891429,56686BC64B25B1FF,2CC4DECC8CA1D20E,6AD16AF6F21BD80F,38CBFDB8AC2567EE,59A5A6E1701EE606,7A6492F0D852FE48,26EE6C4CC625968F,76632520C7F63518,7855AF0F7D287025,0000245A1BD67EFB,35C31F2D08EF9B83,B0D74D62EDBBA7F7,3C45BCC1AA3C6485,CA936D3A1B4CAA12,CF0DD083AA764971,798D508D343AC629,5FDBC47651C5B462,73D37E0F79F94264,8C40D219DA4C1F87,8E9AAC7FE49A4C49,C63AB2AE378C3902,0000359FE5848718,228B45E4774FB918,50E5D9D6958BC5B9,F8FB73BC851DB391,3E55CF2C83D672E6,B08ABFD29A6D6581,E35C7DA6A08D1581,F31632D4022C4140,B1AD8EA4ACA36529,0F8D4B59A749825C,534D0CE6433A7537,6A2A7D60DCF9A2E8,000005FE0AEEE043,1896832C8E469E4D,201684DF9A73CD95,5B8BD5CCFA47E7DB,B9C637B9DDB78EA9,B6FA06910C4576EA,DD0FBB74B0F51F6C,2B6D944304F25530,22DBF0CDC51CEBD2,2673ABADD331CB06,AE697CEA61882AE3,C08F5C7C8AA9090B,000034C2708E230D,1F25DF4484B6AFA3,20C3A3554A4F1176,99046B5E2CAAA455,EF6AC79E0DEA76D4,2CC0030FCFF889F9,610CEE38BB3C5C39,58B64535FEF64886,FB9373E0AEDF3891,AD3671028CF3C62F,089400131E9B5D09,E1F72DFB029507BE,0000154A16B9337B,1C58A2F1CAD3D47A,ED548D4CAC22437A,D150700AE4CCC30A,F56FFFBD67CA41CC,7D70EAE58BCDB818,898FD54A626B32C2,A18C38AD14E0CE6B,DBFEF4576BC271AB,106F1C06124BD417,18B8621A7EFB024D,E82DFBF24FD09313,00006081C5A62381,2497081E98D74D97,984E40412694B161,93BB72B5CCB1484D,C195C4D32240423A,382B0072EE919E37,7C0D8D479807ED4C,1CA0EF95CF5F73F2,C043B16F43924A1C,5396BE7C87D6D702,33A11E4D031187E6,8EF0EA15468B2701,000047A070A25281,2F32839488886B3F,1E9BA6C63C254349,29CCE943F08B0D8C,24DC7F4B41545FFC,C4C473382393C68F,81D55D0FE82C03A5,BFE4997900BDC79C,4D034AFB23682136,075165D4B11A833A,861F70D5074E9D3A,F86DE258AAE06315,00005311F6256DC6,4322ED2B2AFC377B,D974042DDE883E8B,84C4ADE79F910F21,D549934B815C93C2,B839AA00ABA5945A,DB2D3FF6A7ECFA41,BCD67E395C628955,DD98F7CB5D609AB7,B1F16EAA780195BA,03DE4B0DAEF9F92C,A132760C88C7BE41,000028C895111871,7DE89EB39CC23B63,106C387265B69E3A,8CF3A280D95F3FEC,A76317D104A9C84D,7BFDD754FE07719C,3CCC0F6D3528D7A0,727ED0306A5F5A99,04E5CFC0EF64086A,C8451E351AC0055B,D0D6C802E9F24B7B,C9D65D953611F4BC,000048A2C9D6A652,85B3C8A3C07680C6,2FEEBEDFDA6DC4FB,C7DD0B54000B53BD,286BD398D8CD97DA,DD7EF32341078D3D,FACA5DB4EAC9710C,4642104FC79F8508,7FEE5C63D6E8CBC6,139B51F90DF11EE8,2D83CEF979808974,05AE055D8AE5CCF9,00000750D6D9B980,F05FB27861EA2DC3,6F9A9263C676A000,85586BF4B1C51750,EA114FE37A3622FF,F29F02D34A019A69,6531978C8492037B,838572E6E1E84CF6,392E2C5CC41FADF5,CDCA4395E2BD4B78,6F21CC1CCC3325C2,C87AB58B148F8A7E,000032999B8FC8AF,18C5CB26C85C36AA,CEBE765747D8ABA0,DE857021D0BC3BC0,FAEFC794723E74A4,9FAE9057F8A57AB4,7C23DBB3F9216329,2A7A9C1C428D7B5D,15DE406E0B2B09B9,BE2BB184084C491E,EAC5809D3E474A72,0BC6D37913710131,00004AF8CB65AA4D,EB257B1EBDAC13F8,8FF771C60F3D1473,27B57486C49D823E,E9D9CDB05EF83ED7,0E79FFA6C4484A7E,D06FDC98B0AEF475,D89C600530F0111D,FFD5E4982A100391,00BB8AFCB5B3E7A1,24D2B05FFA34F225,6BFC87BC84941B00,000062DE743A18BD,3D40CBD27640A6F7,A542619129C8921C,DA9CEB9BF4AF292D,F46A0865877321B5,78FB29FD75A4A866,5A56206E332EE69C,E3BFF679508EBFCB,8BE80DA15C5A18BA,FA3A21459D776E46,F8373D1FAE8D7BF6,2742C2D81C344BE9,000012733B2921D6,F7BBF940DB253223,F508512B81BAA047,3604A37B3C0F7250,01A5AAC257B46434,E9A7DCD97783105D,5F3CAB56484A3AE9,C055AEC63AA95FF0,EC3FBA19501A99B7,9E7AF8E1B398D603,ED1DC8A4EE361FF3,40EB0D43C0A44B13,000036CDFCF866A9,4D8FFA39D021E487,05D887C92C3C8F31,9F4CF9D71F276CB2,D5873F38ACD5AE9A,0B62F548F2AC02EC,7670AAAADF81358E,32BC40445BD82BB1,C52BCCB897E5763B,DC03C8C56CCBE91F,0B25F75795534CCB,1FC17783F20DF749,0000370729149250,8E3307D0FF3B094D,BEC6858D31CB842C,18A8720CF8A3E3C2,8FE64B235E6004D9,8202926B7E4117B3,328207E18BD03EF6,3DACEBBB2A6E30A1,CB7DE4EAC4425ACA,4D51959B5449E6EA,DB3ED00AE5E84D0D,7D7313A2D1497577,000029CF10A332B6,F69CB74F4B2312A7,FE2141EC83DB9093,C737A8013581358C,EA1B48DD7839A2B9,E6C3BA0539731E55,4FE8934AFCB2DBA2,D43C9C3F683EB974,DC4B387E3B881758,ACDE8CF447B4667A,E3C6D891BE3F6F8A,02F4F1B2FED420A5,00004AF4A04F7EDA,4CDDB1050FF54A9D,F52C072234A751BC,7EF2C3B0D4F0FB9C,26E3E48F3F75B53F,FC93F7EFD3101B26,3F777590510AED37,37EE1A1732F029A3,AC2703036C959234,B1613D5B238EEFC0,14BEF779A3272D96,FFA5D9936C6F57AF,000048145DDE5D84,7930B4D3AFF7623C,F579D82ACA0EB325,7CAE78FCEF56CD16,D54874E796A5AF24,FF0928F57C5BD203,1ADCC7CFA1C533A3,BA14EA874674D3D4,65CD865C41EC0246,D564F88596889248,7B65445DF0291D00,4FFDE34C11FBD732,0000202E78EB43E1,E55BE122B67AFE2D,E45AE41FD3CC1390,BC667DFA66539555,D85470081E324755,678E52FB7559B94D,4B83A7C24B6A3824,03DF099DF7025B8D,85043A9B1F72F6DE,F9AD22B317560A91,691AD1A859A290EC,6EC3B345674A072E,00006DB6E9866087,3B6774ED233ED497,7DFDBFF0B8C33FBD,01A6FF897BD3AF7F,F6C8663010B605BB,AF82A409B891C427,93647FA1C36D6BCC,297153BFDE90B93A,A008B10A0D0502C1,A317DAEEFB021D41,7B3467F72423A93F,4724FAE9816E19E0,00000E4B0D1E692D,3F3AD94B8CFC8908,AE39264BADAC6B3E,034DDF5849F69666,15B26B312BF7D825,A98481F96E75CF29,63A564E31003DB6C,169D2009CE8F6D2F,6A1DFABF806A9D0B,EF529AD1F1B16F94,CFA27EB2F415DF7C,12A28DCAD099F7EB,00003F1D04D6B540,D5EF67D17501920E,EC581EE34206DE9D,C0A40DF96BAE4C15,AB5797EC29219B32,E37FF347DC996140,7845D81C58B1F068,32CBCCB7D206AB07,47AE6786EACDF058,E307D29DCE92BA2A,14E895B8F9F6AD8E,BCA43646758320B0,00001524A09074BF,777774041B0CE1F8,EE4E9A95DF96B2FA,AB79D65A4251114C,9B8D054F5487E829,746354637DF490E7,74623B2D676D29BE,C56CB27124264B7A,AB78F4A7BBE5D610,C97AA31A9488372C,D1065224267A0F6A,5AF06E5CF449B916,00000F50AE676A6E,50E62E54B2E87301,BF0A643FA8B4DDDE,7CFCF55BE5416988,3F52CD98FD999820,8A521DA6C3E6E21C,54FFDD969802C059,5780676B3BEDCB0F,4D0E5EB6CD677A43,9D9A3AF09C5E8DB4,C03376BE331D0876,CBDCF7C3C349A0D8,000049A3DC9874AD,A05EAAB8C9BDE361,BBACD4C2509610B8,1BD0354BA8EE1C41,B63DE836D1CF448D,2C3D81D0D6001430,08EE5F1599B51142,3AFC5F93A2094C5A,AD9F00F33C7BCC36,CC53DECF2C70C0E1,75A6BE224961CB24,A5FFD47CE0201406,0000260334B0E8AC,947BE05B275FF3BC,BEF35F81BDE60736,6BB16108963EB92B,260CDC5CFE9FCA2D,B64D81EE29F0422E,E9A96B78E03D317E,DBBFF8525B0B9D08,489961EDE56D5F05,8486CFB4FAD913E5,201AB18D2E9C35F1,AB4C544E4189EBFC,000052F60D390FF5,CF7F647818703378,CA8D6E5CC199509C,06508F68F7BDCBE0,C868FFF8C3FBB311,61DFCBAA7C9965AF,4763D41CBF6A65D6,FF9EA78F40574CFF,1B0981E2E182B85D,8F39686AB54CAD5F,8F79D205DCA1C13D,F491AC44B180924B,000068215502D936,AD41F9E45A7AE4C2,52FB46556B4C4239,05B393866A3DC800,F6FB9729D903C714,525846399056D232,7C04FFB8CEEA4336,8A7AE6EDACC8D150,567436CAE3D48C37,2019114B0928DA77,D8087C1798C68A66,0AED0EEE7E4A67A6,00000A8BA7BFFAB2,12E49DFD3495F0DF,97C7690271F02A94,89BEE6C3145D0CE9,3DA863DC8C497AED,A09902C19E2D5EC8,D5877B4B793BE359,682CF667DEAEB22C,7C71EF563762AB50,F25C27EA0A72AD0B,166B2BB7ABAABE90,1E6F57A164F6485D,0000376F983A1111,4D713026D898E1FE,A80B1B9E52AD4565,D08097D212BD8533,5C4CC160EF4A1EE5,1B3FB4D6C031BD9B,E727AB389C0BE2A4,52E057D21775A2BA,408A5A31061074CA,256192F282DC2F64,29AA8B5DE742221C,1785490F4F4A27EA,00004DFD6EBFF14B,C1FF64E6AD802C0B,68CF36453DAAE4DF,387ADFB2F5305825,80731715ED3D5891,22AD8F352BB7391F,75505D7556AF5DAF,B3809032AFAE94E9,2920EB485F566FC9,F3533032C7109CE1,A42C31AD0C38DEE7,A7D0B1B4011BB483,000056597954D087,37DF8020E63601A9,61FF8EFD4CCB7FCC,E05E27C19AE72C7A,A0AFC6B2C7788BFB,D44F084AA4DC1F2C,B0013C8613446BA6,BC57E796306F0791,1FBB4FB326418CCF,4C31005C8AD3016A,6433506F86D56B8E,7661AA230C749889,00003A9AD6628533,7D5F07406B78DC66,D0C1A2C72EBA5032,F991E71EB5C9313C,F9236EA7575E0B42,88B52B8041839A28,36FC6A483E43B526,F4E7AC46096E0C1E,D7FAC39B0B63695E,810F75D31A3616A0,C1EE6CFED4A37636,2EFEE4561AE7A50F,00006750799873B7,609599110A5F3D67,3BD789C721897187,50D3EF6A13105673,9E5E02B09FEECC22,2704C3833EF70F47,9C99277154B8E684,E0FF03EB99F94612,77F9FE62CC9613E5,B12C320176A87E77,5E191289C4ABFC53,B060F409121F1699,0000062D6408A987,39BB70FF237110F5,E90E3B03EF738F74,8907FEB153DFD12C,0988CAF0B4DD52F6,9C1D16A181A4A4D8,FD4B966FBA7520CA,4C77C87DFD898E7F,AD25306D911111D8,79A07CB257064DBB,751322A905EA0DF9,B81071DB113BF999,000016B29A8AC59A,2FCBDC23682572D1,59894B9332AF87E3,A7F8A5D3C6B1538D,EC4BF918405E20CE,B34D6419CF8DFDE2,803DEB7DFC02DC32,BA3C7D057AF27DA0,2BEB5CAF9C9747E7,319F85023D7B10B8,9648E2061A2108DC,F6276BE3FA8BC7DC,0000473C8BA0459B,99C76C144C052E8D,334DC40BBB3996AD,BEAFD2D89C78248A,FE7EB7CD75CEFA17,A0D2442A24979501,93A8E9DA87B24482,4CFC19DF3EC6B24C,00BBD8494110F430,A6065FBC65A2A388,2583F9E9F247E9E8,1A2128710E3E9B16,000060D254FFB63D,730F66F21A098041,7F4F2CC18EFF73F8,2A2D35794612F0D6,724694BC44ED8711,DB530CF8665161CB,F3A006C94F83E678,AD90914CAEBF9796,B15A239C918AFFB8,49427633FBBCBF63,711B5F96040BD253,37A1C953F9D7137F,00002188556CDE16,08FCDE842080679D,D3877D6C2685608D,6BE61D03B3F48CA6,1F37793795C4E650,15124FC270F4AF96,41B633C95079BC76,D5CA2B016409CC30,73FD19233C73317B,E4411E1ED45A149B,D7749C5A8EE2FD9F,314C9ACAD5320B61,00002AB2E2215470,F36EBB47B7861A88,BB3313F7A7FE6FEB,2F27EC12360FA186,F7D1291D514D318A,DFBBFAC6A8FD3E73,65EEE25B8427BB93,2FD17C0B15225C01,B6EC8DAED74E16E0,06ED66093DD30CAC,5BAB3C3A4DF800EC,BC5A03BFAB4649BE,000058D00EBBADFC,E5A25CC7AFFAB1D4,82C816E66D240844,4567BD238DDE75EB,A370C3B0B55F0C71,41E95B23C2939B2A,E8129C1114E34E1D,82383A73268BE039,7D96962B268E6941,25136EF0A10510EB,115B3D33A314C469,659AD741379808F3,000013023B64B685,71A4FE30390BAFAD,F469ADA3E7FB60B5,7A5BADE079EFDBB3,40ADE33A227F5E2F,B4466F80B57158C3,EF5B2F405B813C71,86229D930CAD17AB,CADEE515B3545220,5473534FA8333158,024AECD08B2AACF8,BB2D876EFF3EEF64,00000490F98FBDA7,65D540EDC018A1D3,52BBF1B531AD2B9B,2EBCBE11E5744F3A,37D9B7E64E682E38,9E92A2C536AC0EBF,0A5A6DF5D1FF8334,0D21DD495B3FC989,97823A0012ED51FD,94F534D36C7BA7BB,81BC5974B4BD0930,420522485E5E8D6E,00006D10E9DA9096,04DD9885989E3555,4520647EC130F7F8,5C790D8E55CA670E,424C692F290B0883,74708AFB4C5EDDDD,B371EE0711014861,0A8080B3E3366E7C,27BBEF2118984377,7C4D53B1CAD15045,6974D828C537E5BE,9FF4841E9291B468,00004C0B62648602,94344AF9DE5A9A33,A0C1830664E18467,7B7095510207CC2E,0714237A33E4A6DB,C53EB5FF437CC2A6,37D44775096BB135,4228F8E93CE53608,00844F999A9D0E5C,4185F3551E05B310,C0F02D9C8EFEB93F,6776D836E1FD4EDD,00005CD8BD9864AD,683E09E6EB3514C1,802C1C9A976F5102,8B97D106DB5A63D9,69C944E2207D9447,CABD0048D82F911C,31CFB7383E246D8A,AFB12122568DCB32,60F1BE72C3432808,F6AA5565FB7EE41E,723AE274D0783C5A,20C3264ECA7F7A8F,00000FDA6E250483,7926BC7359E2D53C,2C91832128532A50,05F8C4BE7E69BE72,A775F68B82CAFB4B,ABCAB4709BB9BF5B,335BA6B59DB1A49D,14999292D3FDFE38,B3FDA1ECE53F8617,7251C7A6A0597FCC,6FD72530BEEB6F57,0460E64333E6E573,000013992ECB4A5D,F5926A00810B9785,791CA612B5B72186,53BD438829A731C1,0B5D59EBC6568DD6,FA9A560430677154,6A7C601BD6AE2853,08A077566DD3410D,C1B10FFD7823E162,47B63B0C292AFA0E,C8E3DEBB5750ECAB,78EFDCD13F880CAC,000011DD1C2B474D,454B7D0480004219,5A3EF9383FA81AAD,D72564A33F1684E5,E8B48A5A8711C893,DE2829583D87485A,F5B7090B68C8AC28,F20AC28287E650B3,775686F80945E7BC,58DE3C5048174E9E,9D8A16CD9FEE2472,44E393A332146A28,00003664D9A8B3A6,0464D6A9D3F65DE4,C1E2B1F8138C9F66,A2CC5A559AC0E4AC,C4AB2D8A2E967C1B,F0B2773E0CD12213,0B439CE81F6F64A3,18B866A38D2ADBBB,3F512AF67CA9ACF5,BCA79E2332FDC56B,AA982CE4F1BE8D09,F3FDCA875648377A,00000E48F759B405,8C2132DF998BA133,72AFBAD0F3F3F6D5,A71A676940B315AA,565D1E6EEB4D8D0C,5AE48639CEA8195E,E202511F025D6A16,9CF8575E2311B5C0,BE736B10E9225E1F,1DCEC0B46A6EC45E,887A3AA32BEA8071,D022953E61EA4ACF,00003AC3CC9355E6,E4B4FA1499425B74,927A5100C8F0E638,B830FFB7DB41E9B9,380F40E0E413D841,9EE079D9150DC8DB,C926B2B9224C3045,5B0E6B61A883DB07,58DE413B7FF18EAC,9EB44040EC6A221C,E33A6AC444568463,3F3D872EB80C9E54,00004C7FEA0C3C5C,A66B12DBE3DD4668,80E9F718074C658B,7370282B19577868,FC978D3E77860E7D,D73F70168724425B,CA3099A7BCD5629B,5126C674D29E6399,D5DF2D459096AEF3,17690CCD8EEE1A78,32927158E7BC29C7,421BD620743A606C,00005D1846A70F0F,33F99145EBA98085,D87B0305F35763FC,C4F4D08762FFB962,8021B224A284D22F,FD4C2AC0071A95ED,0A05072CF30397DF,3FB7716417F6A489,0BF06DA5FD309160,0D971AFC8C41956D,D39ABD13B08C86B2,FA53A3456433CC2D,00000D74FAD0F977,81C492FEF224CDEB,487972102B68900E,A6960606722DF71D,D7479A64EDF4B88C,0CCCF6112C1690AC,17CE2655AF226A1E,935737FC11446DFB,FFDA1779B973A749,7DAF5D74E96AEB73,04F339D70AC5E732,5D15E8DC666D2D91,000068E7E87B66DD,14B207C4CE90A4E2,513229F3B8DB34C0,B130D1225F888AC1,BE6FA0C8563C7031,E683858E64FBAB29,A1BE06BB3ABB9AEF,3957E9C368B65094,004656EBFA164B69,516CDB0CA13A1CE9,44E614B90E36EC50,FA756DAF8EEFF656,00000105A9572556,8A7FA41A894CF6DD,E099F32D308D8F38,3966C9A55DA7167C,B70A1A439058E1E2,EDD476F6023C07F8,01C011D796FBDB01,93A559D85C849136,132EE336EE08EE7F,DB301C9D5717067D,6BC39A5DC5D236F9,F0068EA38B550F58,00006EF86DECB5C3,664E06C79367A8E6,E79D2DB253CFDB2B,E3C5FA1FD411FD73,105EB6D5FB0F4F86,115FED122871934F,1FFDF6EB5A6663D6,1CC5704056C3B488,81CB597D8B9AD7D4,C09C59EE4B39607F,BEFA878887A270EC,5DF846EA5BC4B6C4,000003B684C6D5D7,5F961AE3EC9A8542,0F0EF5DBE5255997,F2AE8A14BF6CF4BE,C0937FDA37EE2665,4486CCB02A0500D8,D4F78112BDC9F7A6,2A5BC12F0EB49DB5,B860125F2BAD2665,6944E63EAC357D21,3D29665A28F0FC61,609CA34E3FA99E68,000039958816228C,291A9FD19D704C93,B32D74E6740ADA5F,EEF54DFCA60DF6B8,F365E8B57121F484,5745F594DFD1A3E5,3B8F66B29A157F99,70DDB5EDF1E1F386,4C45F54EF254F1B9,8A95553B0D018A20,0E8C693AFA4D9BAE,17E6A88C21A294BF,00004BD0AEADA6DC,C5CA22063BBDF98E,0ADF526D169E1212,75462201B9F592B1,F42C6A51ACF650A7,38305A0D37698AA5,9B366261A6833DEE,309747513B705CA8,3C077BB585EDE947,84A69FEE3309DB3F,6AD3C5A97E239911,3CFFC658F5698988,000035D7CA9C1270,2F050E4E14520D88,13DF82C85C97B72A,C3B9CDFCEB667006,1F31DAFEFF3A4CAE,A2B36CF62E5A3182,9C3447A98C435D49,404044D506EE4AF5,9A48515DC7A1AA6D,61FCD11ADF5BF5B7,959A5BC0A935BD28,4434EF78CA4554D9,000043DF0755672F,ED0D36D7A88B67B5,5C41CF2E64B4DF43,0B2FD080239AC250,713F93CA9BB21748,44B8F79D92914B04,AF6252A67C1841C2,066472E532FCC079,33656514F7F141E4,F9367EC0CA53A7EA,C79B3511B18F2C8A,0A3712CD7F964B04,00000DE0BE9E2014,1EE5F3851ADD4BFB,AB016A4C2E4CC7CB,7279A26C789D3D02,4931277F21C77C5B,F7B0D25915BFE3F6,9E1A4F5920085F2E,90394ABD909ED5CC,6077CC61BA71F2F8,5D93664FA74643D0,0DBF9CEB5BFFA845,1DA1F969FE020955,00006B1F6A573EF8,5AF28F2CE2E027E8,7D088C3DC07A8434,65E17CBC8A97C104,79F20183D0C1126B,1D2C305C2659F31C,EF44AC0553C48094,76DA2D8FE972D0EA,A2BBF41CCBE25FEB,7391A8D3D674670A,2FA5B2EC79B5D77F,8E5CCD1E08C15688,00003FB1BB5C18F8,49F6991F5B2A180A,64D884D94816FFD6,57F8FFFE392EB79A,ECFE294B2582985B,3E85442081E1C6BD,E7D67A7AA9E8CC41,BC1F4F05F4DF4AA3,ABD7B8628D05E06A,1EEB1F37D611229F,39BE7A84DEDCEEAE,DFCE580F2E25C3B8,00003602D1320639,651B31593DB510F9,55E0ED4E37A0B6CB,9CAE3BF52D139480,1D534D5CD1A32673,91E33F64C6ED9C03,08C65D34D304A4D6,6A84D421D1200C23,75E27A39BE9ED5C0,11C56C0EC6CF36A2,13F4C2202518C606,4F051213F9702722,000012591ABA3844,1974C1CFFD5336E4,4AE94E322A36C4C2,1A9A7D061C779A51,B87C391AC9A2015E,C40A263B2595A98D,75B7525DEF4D9B87,1AD040CC6FF8674A,1AD3BE2D86D49B6E,C534E9CBEA886496,3CDEC14902495AEF,9B87CDF7AA774798,00004143DA0A331E,4189E1DA755B8933,2FFA33E07C566AAB,481F12B6D8479996,85D6FB680145DEEF,81DD45DC14BCD5AF,A50BF76285D05934,CC62A3022A2D5ADA,513D4245E170C8B2,F6A895B145BF7056,403EEA7BE6BBAA37,49301CDC1BA30D7B,0000633889984053,02AEEE0069FE4570,FDF13FB76C0A815F,A50A0470D1F6C56B,30CC06CBEF9AA555,04656CCCC9E12E84,96F2C7F619A20F3A,135D9F181C2A9087,EB91979402EB3117,9EFF9CC51D1C89EB,2EF638C100E4B084,480B7F4DAD524854,00000FE67BBFA7ED,A83D1E5D71A47320,A44F514559E60C9B,ABD2D4784A9793D3,86A563EE3635E7F0,8AE0B7478CA3D925,81F82267AB353DE2,D16E5F6E5AD11987,B45047EECF39339F,17B30898E712E3C6,410C971EAA224BAC,FD9A440CFC99606B,00005B0CE8EA9851,78D16427E0779459,D7A4C4F092115B56,C1B469F373DDE97A,4C6D8D96FC1C214B,FAE77B8D9ADF9E51,99F20D3CB589E00B,234C86BB31A9AB9A,18EE13CFECC205FD,5F34D314A3B056B3,04BF311CFE4FE778,498FE04064490997,00005EF3B3F8D9A0,B1C5C8DFDFD14D06,0BA019F769D4C916,25D8192A7959A3EE,0C8A40E3E303C0C3,74068F581FADE821,0A31807F63DCE343,4C26FBA48AFED91A,FA2F90F89AB5D739,590EE17EA5AA1924,E2CCCBB58EDA8D23,4DF4512050505C87,0000482F8CDAFDAF,FD5C068F8D08841D,D40C2C944F381D13,BB9E18758E539ED8,5F216B3308080496,3ECACA4103B14A95,2796FD17DBA23380,2CFE1A7CC905131C,566D463708F18982,A9113E75E004D4E8,E982E688AC33AA43,654CD1A6E611A56E,000030334D32143B,063DE844F970B65E,2E265565881159E1,511CEF8B0524BB49,BF9B402B07B29454,30843E2C498CC634,782040D376750AEC,19E99C6DB820ACE0,4A826AAC705CE3CA,58E16EA71117E4C3,43ECFE85BC83978A,64DE5F55C6FC0994,00003B31C9DB4EAC,E5D2302CF479EC31,4806747FAF5DCAE1,A99CF095ADFA9E0C,F0DC92A8BF044293,655947A0DBF317DF,5E80E5191E379855,DE7DF05CA8359FE5,E20D0AB7EC510BE1,3B01D2CD66DC3A7D,50F183B1A05B53AC,E8EF33C0278746E3,0000133E665F06FD,D613DED5022E4C1D,06B2D3E5C36737EB,354EADBC07EC60C7,5720B2AA1FCB579C,45B7CD9DFA950F49,71952076C285941B,1C1932E75D3EF756,88665573D43940CF,EE16B13B70EA84AE,04206D313D4A1241,BB6FB37A1F967C4C,000065F21DD417EA,B93E0B9EA1A64ECF,C909E3B5197E7AA4,78DB53780B6F322A,E81C7108807B5343,8912C464B124904A,DFA3502DF58057E9,F010592714EFD571,BB89C3B27DF8FD4C,059377E7742EE6FA,1F852CEB8C493D00,E8F4CA6E3272D6E9,00003E461F6CBF0C,C69587B26C278E7E,1AF7CB8C459E0F80,3F521FE012BEBF8D,0C0CC4E0B5870A33,FEC49CEDBB053935,A4ACB85E71160E19,C662D531B69C9BE5,B595F7D84F939BD0,E14F5C21AD0EC8E2,5EB270A171F38DA2,4FCF641B620D75F0,0000625631EC0A34,67A27B65340916BF,2D35A04255B7AB9F,0A1AB6C8B2084BB1,2932C0E9EFC3640E,B74E37CCF0155FE2,47E6877546E4A10C,43B2367FE26D8141,F8B2A7DDB45DDF69,F586788C1C162C3F,3BBC70D9DBCA3FB5,5E26CA956AEA06B1,00006DC9AE954C9E,F386FDA87A061A15,D06B5EB1F2B2A80D,2F4BBC103577FD9D,F72F54E8EC9A80D0,213AAA6FCA4EC688,BA6995C5D8C6E97E,42759FC8CBD61775,DAA6878103B51AA3,F410DCFA738BA24D,FC0DE1B8E88C4AF5,6338479D1D1D5F97,000031BE4B90918A,2DF09C4A5D419EAC,061B9A332C3BA401,971E95552D7B1954,7A96E5EEF93B398A,15695E1392784958,3659D655475CAC09,645ED03E0EDB53C7,4B0BE3884DB3FED4,3B80A0FECFAAA1A5,51AF27B2E2B51653,3ED898B04C8AECA3,00000EF13CEF1BFB,BA303AE12B9F04A6,7A6122ECE572C929,835DF9658F9636B2,BA068DA6135B7B4F,CF19A8591027D4EB,5A3D384B4F6053B8,5291D06AC9DD34FA,975613C231113660,901093738F7A1D0B,024441C262293DA0,98206885230D4917,00001223A78B6765,479125AA594B3AAC,CC3905923D8A113A,E48C74537E165F12,CCEB076A3FC6D06D,CB7CAC41578D30B7,0B7A934453A3EDA4,7F707303FB9175C4,B2905F5BD7EE06E3,3A3DF5EC8FA4D69B,38B602B9C626435A,7E73F26DA3D304AF,00003D94CF5CD697,5687620B6676C160,2DE8E4F270898DE3,7ACAFF0EFD554C0F,73ED8FB50364107C,929188B715DB705E,6BA85429ACCFD4B5,308C33E5E70392B3,7E6E6DF21FA6D2B0,679C522BE906F746,28327B191DDEF33B,C8299810A6281C4D,00000B4DF4E6130F,F6717E8E356E2A06,B3C35F052EBC94CA,EADFF3FD06816DBF,A9A221B81C4CF445,BA016C0D085ABA8B,4E0FF5142F1D9ACA,1433431BBF5A76A0,AE95CCB9FA809B07,4E3543D4D04F3E89,57D53A4389579672,AA557A3F6F38B6AF,000043A2C601C09B,7A1B8DD9FDC5147A,887ACBE78C2FF62F,D5C17D9623ED8650,8166A2F626A03864,68CE162ADF410E1F,4316F2B37D8AD2B0,1CA513DD6E29337D,571A48076D38DBA4,D2D6FF5726D9CEF6,559EAA41A391AE5B,D544C3E123EB6DAB,00004F752A366272,F7FA1610D9A24FDE,53D6099A888B5118,C5E2B2C51DF1B07D,56ABF6C122A645A2,241E92B82A7DC020,4BC8A23E81D3C331,54418BE3B5D27038,41777D03363A87CD,5AF3DA087443C71C,2CCE7446AEB230C5,4E7CE76796FF9453,00000633F6E3A821,BF7B870B666DC04E,9546A0C5D4CB6CCD,2468F342EB4C4B68,569E7A0FC5FE0975,A73205266DDD3511,52E9B28A0BA97A23,CE0BE7D4EAAB030D,1941D920A35AED0A,AFA551A3E98D8301,C4D81AD03149523B,D03DE713E82EEABF,00005510D528FE3C,A614C69D8C8CF053,DD5F0891A2116748,C411E629C4337CD0,D943EC6310C585A2,E4775630372CAD6D,22FD721C6046245E,9A56D151ED4BD93F,AA4FFF400EDF5025,762374693274733B,41B0EA3F62BD81EE,DF53F185EF6A00C8,000044B022398740,7D82181A28F66378,3761143898D00F24,34FFE8CD5550AAB1,CC450906D4EEF821,0B06A3475DC44017,8AFCB5AD606926C1,6266CE80383771E9,FE7841D333CA28B6,90CC7B82258F2B25,5848697266EF3360,C8F6F9153F2589BC,0000672A30FF2845,3934212879D79B3B,70E2A7EC6627F7B0,B94CFBC3F410FBDA,FC1BCE0DDBA735EF,933E35C47A35F914,61CEF481957045C2,90A2D86B4FA402F8,6C2E0B85E2B9EFD6,8E3C4BA505779B5B,4B256534B00F75B9,31399A39F52CAB6A,00004E66CB29F130,9CF78E0D4F90A954,C5DF084A8B26D071,70B956E60F7DB558,C59F0986ADF26447,010629BBE71BEC13,2AFFD141DBBB24C7,A3F2709BE2BD7669,E786653FB197B313,703ADF1BFA33E53C,89E9718B882D1C65,C19DC20E95CA24E5,000019BF668ACEF5,597C3A8BECFDE94C,ABAAE22AB7A0EC58,2A049C653DA2211D,ACA2D1AF447FBC4C,A50A55B0789EEC3D,D39A9D9A1F9EDECB,586763B58FF142E0,6DF04BB8E40B4C87,6A1F942FB7E22D33,D53DD76D6A1CED84,78873E8E0DEE9426,000048203E131608,755FF0DAF60AA68B,4D4BD31AEAD5CBBA,8AA4EEAC314366CD,05F793E18234BCB2,75FB508B558F5A38,0442CD32C732BA4C,33000FAF3DD066E1,37DC36BDF71EFDB7,1091B8C86362A601,FB6A48AD538B0EBE,8801D9E476098443,000011DC7747C1DC,4FCD4B8B4DED5EA1,C9C03AA54A58DABC,D723D00A37C9AED7,65F27212A0298315,B91400ED42DCACF8,A834DDEFE7400E34,775DEBAD82373409,341821C5E9DEDC7C,A4C0B593F37BFED2,3B1BF739F6ABA54C,9376B78A17A27C48,0000666FD1F83CB2,F49B2B576F5D63F0,186F468FB8151454,64A9079E6EAF076D,77EC18A7B87EA755,E5B9F5BF0F2D3F57,C538E469304AD593,76B93DFFDC600D9B,BAAA59378B7E8AB9,4C7F47AF1F8C7A55,3B4C15A4AC05AF7D,326E18A11908451A,000031880F10F58F,F8091B48F100D35A,164B646D1430C289,6F1DAAFD517905AE,E0B5CF65391426DA,20382906C5427915,7A31386D6D247E79,40A546BA669791DB,4BD5E36E905EA5B2,314863E127427701,EAC62DA742F4F743,519D86BC7B9F987B,00003287E594557C,35853432B698C65B,6DF23240AD5B4E68,B1F301401FED0EEB,A0C0E749A87E6046,EBD0F79A58F39D68,20D2863B5F3E5423,1E1A720A51CCC981,4D5AC6F2F607DE5C,67E9256C86566701,35B40D6ACBF38688,B719E8E8764B2724,00003F86D62346E0,34AAF502D1A9E77C,445B83A1BBC8BEA8,2AD0171E35B1ECA4,C259A19AFE15043C,6B631CF467A00498,B2B03BA3DFC3E2BC,FABED3373775EC99,EE2419E998342B77,217A4A59C439AC03,B3B05ACE646D6221,B6E2AD4902A88173,000007A3931FEBC6,622104D2C3E59FD4,CC61BEAE4F9C9A75,F184214BB771013E,E87F4D02D7371C54,AD583E5E9BE1A36E,06D507870602B8B6,46ADA4E7B0EF1AA6,4EB85169C7390108,2D22BC14E1E6E997,C8B87807DEC4F67E,453741EFBD107F68,000060DAE2316517,22B7B5606ACE9D3C,CCB68257AF32408F,522F4E8FC8ECBFF3,FE3BA3EA07710C7E,2C39AAD2B7C1ACE8,4373A44605676763,179D32AA64E786B4,D2BD4D92955D9E66,E4B75FA2F481B023,5EC4CE116776C081,1FCA0F9A9AAA6375,0000195D04376AD6,5D2E3F10E75B1324,FB937675D2A21C6C,4142274776509836,CE5273859476DDDD,83647388C07A74DA,692C4FED2F6D97AD,F9F05E96630CCA05,76D476C4E7F43C0A,A0FF2584FABEB614,5CCE75FC94699927,E7FDD6B8813F65CB,000015F008195B18,1DBCC45AD343F6A2,C002FECFA18A4B71,1CA33EEAB0A1E074,9A3409E9FB6DDAB7,017E0D615418A67F,56072C19895413CB,509AF683AB730741,898FE1B6D25FF491,C1874388FD2BD136,2DF5AF037ED64E33,67BB6BEA61252860,00000FFFEA3E5FA5,B7F1407C45EA8569,976328C44629F65F,1F14878FE6BDCD9B,A5F5CDBBC5819B54,6949C6C036213486,7CB58662E3E3AA6E,26E8E32510762995,6F21BBA2AABD9F06,C6F0BEF18D9FC828,C77CD0E90EDC1307,0B167C17A638E794,000033578E1D2B64,0F438EBE1965284E,8637338619EC997D,B07E01AF5F939214,F21D2A1B8133F21C,00803010C2485ED4,AE28EAE4ED42B8ED,C4B6246642F7F556,F85919F21B650DB2,495D64C3C08C17FE,5D292B5615699428,FE143932C7DEEDB0,00001A64F4778CC1,D6693DABCCE15D6D,94A59897E30EFBAB,89CED6B4CDCFEF9F,5182D05EFE488D25,F2D14C75618059F0,3AD162225A75830C,9F49D185FD144239,8221D10E33B4A9AF,6C4926DC3EAA4D80,4B9E4160FB4F6B21,A170A48DE30A9368,00002052731725A2,EEBAA47747E2DC52,B39CCF2BAE8450F5,B5098553F7F06EFD,3BB5463E310F2100,8E077797C3582B75,1839C2C412361167,406A2772A5866EE3,8CCA2C6A0E5D23C4,4B65057D9C10EB5A,C1D5644772B32731,6D25C760555B2E6C,00000F8F579BDFB7,1B3703174E36A394,4A99AC81271D784E,B6C6AC73191B5A7B,67F2E53F7C094E9B,FD603CB64C10D475,E8CD9B171110B528,5E97D99E3F21D97C,DA7C7D011A1B14B0,80AFC9ABFE430B1F,A62F38875AACD550,5C6D4BADAF7A064E,00000A4C635EB4CB,2DCA7BEA3843CA58,01AE2144016704CD,308B923E19DDB52B,AA6587EB5ABC571B,48ADA308130DAAB6,D891F7024EA5B7D8,FD80F9FC676D0AED,8A5E9A9B44184117,D95E9E537C25E90F,262B59A133C2C1A4,127CEF335B20B13A,00004B4250013F6F,ABC8E9B838F6E569,B27028BEA0F69239,FE640E8AEED81C7A,017DEAFCE79A65C0,B0DFC0F7D722B10A,D0AFFD90F0C17347,45CD13321AC095CE,5E3CF861C6BB4580,717BC6831E334E1F,677FE1A7C346F20D,476DFFA433E17CC4,000006FE037E7462,666B79F32BD9321E,02A69E5E8A12EF67,FCFB61D335FFD378,03355B9EB9AE86B6,5286E07E1B607206,CA6F7A09B0F20260,5FA128B6DBFB6142,7D0345E3BDB55808,9D4FE6700B7DB9B3,ACC8B6864C7D0A34,BF9A3C57345F983B,00000F2EF9C02983,B4E6B2394B3877A8,990D11F26AD34CF0,E1E80BA1437C8CAC,442C8EC830217772,D87494EEC95B6042,A4C552E03950D8CA,ADB38E60A5BAB872,08666F2FCAAADBD2,780DF340B784EBB9,ED16F1371557D799,44F53EA2DCFC91AF,000003089E06F3B9,DF7BF36ADD94A762,E135218299C6A19A,BCC34E942102F235,AA67373CDDC8CD35,1BB3D68AB38AFD6A,5D7A84B9D17C066C,62154D61C7D12665,B7380ED7A6C14254,ECA8A2804348160A,340C66E4C52549F0,18D23AE206F70B67,00003D382FF98676,A13BD3E18B1F2327,E69D441EB9CB6561,6266491E09271566,A8E2CA3CFF37FF85,B2F0983DBEDD2167,ADCF6DB131ED4605,CD3B9B04F49A1984,9D66DF6103C2BF10,5FAD438D23E01ED2,AA4F76B98D112700,4289A069B828C47A,00003BF5DA0A8C9B,00AE7DF24286C42D,C1845C1CEF9F340D,DBC1032D0C353026,5A55FE2132E2D6ED,F9E5DF3C1C028580,22A68CB2FEC282AA,5BC4CCF3BC4A6B53,9CDEBFA3477F1843,F279D3D028FD855F,F74494565B6BF86D,AD5F4E97D1EFEEB5,000037CAD5823A49,9E845EAC1B5C5358,5CEC16229C41A5FF,AA031AEB23CE9ED8,92F91C260C2FC85F,65C078AD5F5E6B0C,E330F53A2EB28A67,53F066B871A20D47,CABE0C1DF886E5CF,ADE7B2FB21067E2E,B60BB689296426A2,BFB2BAB8645FA091,000019021C793823,A15419F0D36BC853,8941F251A760DBB2,2C9A65F91A3268F8,3571A4992D55A7FF,F763B542177F1884,8DA9068FB5B554F2,0626AF61BAE14697,99639E214E6F8E7A,AC5E6EC1DBB38E4E,7F35BF5732435633,079E550FE333D130,000005272E78152F,09D14F96580F707C,C5A2019E56D87FF1,E768A8DCDFFEEA3C,2A7A64ACE49B57E1,4373438B76C8BCC4,87C4A30D34A2BB7B,558AAA7843B435A8,A6AD200CDA1C1DAE,0ABD3F0F13061E27,FA25DEF80ACA3588,62A40B012BA13776,00003BBCAF733E65,675DB693D684B1AF,EAF252E185316A12,7910DF94909E5B13,429803A8DED46FFE,454D597ADF62F4D9,6C26B44FCD9F17F6,E021F228EAF95C57,4881B535FB59940A,254307BE9F2AA176,69B85E32F0F24121,A5E2CED81632E63F,00003F99139A1EC5,3444D1A6B4099CB6,3D5F404B487996BA,6023D7D2958CD968,C3EDA0C8B609DD08,05F66725C52DCEC0,3A91926881956964,1B091FB70E529BD3,1524E82C76CC3CE4,E4D1534CB2B831F1,2D11EBEE30D9AF83,B827973E68E3C187,0000454FC92A04C9,ED5711DEAA044EAC,B97911A4649D088A,851B17123FC11CA2,262DB71807B80131,3312DF97464BCA23,4A8473A0B4D858E6,C21073E95AA29535,9455EE4D2E7CF1FC,457FB0359E0E6522,D5D10E17D51D61ED,CCE5591809EB3515,00003DC806C3DF56,B9CFBFCED8E60A77,7B9A5DC805AB0248,F4CCF9E41F5F4461,55E76F4882BEF149,F1EC1A602B2FB6A9,B814A1D8B85257A2,9C5D9085BB9EF681,54F8C2855EDFFAE3,A91F5C317AED4DB2,1E723D5972F8F6B5,8AE25CC8086D6520,00004C8DF112D5E6,C6CAA597D25B315B,23AB1D6CB132C96A,5AC33A36A13ADA41,7337F24A4870230E,5897F52FD63E967C,BD55DEB0C4AF9F17,D3A247AE99E78FDA,11B991265F753D92,DF31B3003E59BF20,42FFD84E49F2F58D,06FD2FC0B20B7FE0,0000285C6FA6693F,E629D4ADB4945C77,EAEC0D3FC9C1BD84,CE5718727AE44E9D,E8D2D82591B3AADA,A669B81D6179CA23,97F91AECD984E70E,DF42A60F3BCDC867,05EB02CC0797F2B8,6F4142DEF1B760F0,70A272E386A2F26A,A7E886709BA38498,0000306DC04FCAFE,F1D5AC6F09C8EA4E,C0B1C7F251AFDD7C,93761CE1745DBA5C,AA27EF4C7A6CBEFD,61F94850C2C490AD,32D55908673D061B,532CAEDA152F60EE,2F70EEAECF3CFB46,66300A4951986F59,906732FFE2B89D87,0D20E2EEB20C42AC,00000B033C43326A,623FC7C40F5D35B4,2D6B1E55EB2316F3,7AD3A88F414A4091,A61CC91772636369,B518BE3270A84D38,9A5A0CFE2015C683,3A2AE7E719E9A4BA,42764CDDE5178957,AFE5473A83D48990,894F0D8BD9E6D8DA,C3FC061C8DBDCA17,00004543D8AE6698,25DB3B14E629844F,09FB78943D4CC740,45FE51BBFFDAA88F,7348160B51B2D390,AC54DC866DC9C268,7B88B0960BA79BB7,73606D6D1EEE6907,D0C286E9B58B8CAC,F6B386CB3D35D668,9F382E1DC3D8B43A,1FB9E33A3E5F9B2A,00005796E6932A13,3B7EBFF316F547CF,4ABF6D41605D7FFB,2687B188845CC6A3,90FA1CEEB33DA532,885E2E4D34B4577B,65EBB835CA02233D,2C0CE9CB5EA947A5,38C8FB3374C9AD9A,01882F7347952469,FCEAFFA74B59D253,71E1CF4FA4A6EEC8,0000188802814F25,A0C2C814ADE4D91E,A7A5DBB027B96B31,214A4B9E823746C3,8888BCB73B2527DC,A2F2B092F8CB11B0,89F0A7653E5ACEBF,8BC11D1801E981BA,22CC4EF5A3D50ACC,294B27DCFA91CCC1,33D3793E7ABC05C0,F6E6CD6DBA1FAF07,00004B98357AA8F4,251DBB30CE806B1E,913BAD004058074F,34402F8807E58E7E,5FC79786318CDC77,61A3070B831D7811,482CDBF3D1AB2629,B811A33A9CCF7228,6F5B118090B259DE,2558B3297E007384,BA53BACAFCD6031A,2D2E11DA11843849,00005671832C38B6,526AA7EA73D9701F,EAA459D850C96788,EA5BF35FDADB84A0,FB499531687A23A2,CF1DAC9B72EC7F18,89743E9D05E485B1,3B3A5495E28FDA6F,D8F2B63074410F7A,2E371418BD32E8AC,C57C661BA1D4967C,77F5FCD457B53A89,0000052D8A1DF53E,AD74F3545870F615,85BFFA53FEDC63A7,68C21E3D7F7AFCFB,4E4396E2EB99CA54,614F48E64DD5AB46,6F87469CB04A164F,AEB3C7868A7021E8,F386AE18795E7CA6,61C6AE0F1A02A3EA,8648AC56DBB0DF16,48A51A644A32E738,00005B3326B3BA15,DFA6679BD7FC4EDF,A72561101D14A7D9,3AB57C28377D673E,3707F43766E584DB,93B17CB6310E5DDE,BCD2AA95365FBE8B,679B7D0C02A1BB9F,572D9A17483D9D1E,CBD6CFA5C4CDD1AC,DDB23D63812F60ED,8CC10A1DC56EB62A,00002C340A45BD35,4D3A80E24E89B6B1,CF19A4E19383F0F2,40188B13B36197DF,A87CDE9D083E326D,25C412E32866262F,F2D5AEBBE0E99F57,AC459256F367B6F8,AC12441211A2638A,976C380F271F9722,0499EB580602DE2E,841FFA48296E16C6,00000FADC2701C09,35A120BE13BB4C11,F3D6C1F924010A58,772155E01CA67183,14B637B57CCBC012,3E408A44A643A2B4,3FEB159D52127588,F9AC9189E16A4742,C4C75C314C0B530B,3FE04DAD3D58BDF3,3CF7C6DE108BE574,D28C6C2B3A203622,00005044FCC0539A,C5EA59100DD5EC4E,E709E79393E6F349,6D95A950549CA063,8C822BE1220E7A44,B1F4B4CF36E0E910,9F677F46FB750C2D,7EC9C22280385064,A192397DD29730F8,B9DB2B6EE170C571,DD47C21BF4C7904A,22FCD27063F5EF8C,00002D624B2002C0,90F1466717F4D222,9B6E77B32CB84B3A,2584F91008BE265C,A6A184C47BAA27ED,E972FA11517A77B6,56638B6E2CC9BEC9,76BE98C7D0395E46,2FADC463402F0FA7,F121CF28296EF9B6,0E93009B480EFB1E,FDF4AF5FDE7346F3,00004AEEB285B8FF,7ED54E50F258DA81,3BAA66A1E177E704,F8F42D125389D478,14C40E3565C380ED,72560A4E6EA5FC18,3DD5A3F8ED6F42A8,28B0BFB268C991CA,BCA719F004014527,98BAF5C27D9CE09F,1548CA3D83806D84,9F43E1876FB03400,00000FA9B5BC35E3,049EC1B3DEAFBABF,9D773A9E7DAA3E6C,7F687F3C2E277E0B,5DFB7CFDBEF9508D,25E7CAAAC4C4FC4F,7D4DBEBC055D1A6E,7ABC74FB6D618A79,1BA8E871972CE279,7D08404E76F005BE,2A799CD37D0D7497,4A5EF33C6C77E59D,000038DE8D8D813C,49166DA9CD8B71C0,C79C96F35B1582A5,FF202DE4F14C7BEF,FCBD2FEBDFE8334C,B409822307906AA7,A39F871F18090881,F1DB3F586EEE076D,4CD5F0DB78C05D15,61FAD7CB84B54F83,AF8EAD2FCC3A356E,9016E7E362DCA734,000051D2567D0CDC,B7F50E5A5E0B406C,6FB22BE8CA68E941,2FE78899EC68153A,C2952CA8BF7BDE8C,9AB36AECD51211E8,4AC09EAD1B1361B4,A07008BBEA0DBCAB,49756BFDE439414D,604D4B75EBF3D3FF,DA94C3CB8EC3E9EB,E51623EDC6904A71,0000693D25931553,ACB29B4BBC96D7AB,0C01DFF617A56A9C,B300A0DA3D623235,AF0866AB9129D93F,A389941C649A54F4,69E153BA301C3910,F1D4DB31E902283D,1A0373796175DA4F,3AC0575800B661C5,40AD099A5F4BF208,9D997A3CE34395B5,00004B68FB961CD4,84D04303C97403D2,B0EA5C8DEF55FC68,D237F434C37C2F7A,4063F6B43DE7A05C,2F1E4FF15E945B5C,6F57E11DCDD809B7,5E4EE22C616DFE97,080ED6F4A993E31E,A72C046B6F530DF6,D3AB08F8A58567E9,D61D8B51B5A0BB69,0000251CC43D8DDE,ADA5D1B22D6E58C5,7A373E94D0855B75,BDAC2FAE54B27E57,593555028749E0D3,AC1EF8B5CB03ECC3,DBBF6B0DE9BA20DF,9EB14961EA468539,3D0333657CD8ACFC,40412B2A4B5D142C,0A5F3FD68910B709,BA4ED620C5EF32D2,000053826520D7BF,1941C7E3EA2299E2,36F3B3BBD92708ED,F2BA350DF40D57F1,A4A40A4521A69EF6,1675D750CAD23197,E6D4AA94402C77CE,7C919D103613470A,4051B52B8580B95C,4F4F7669057202E9,9CFE1D0B3BA7AF58,E9B8CAAD2CF4A35B,00003CCEDC8CA4E7,4BF08DCD0E07B000,C31119FEE083FF6F,F6E5069C2535EBF3,6E99E25F72FCE97C,EF47E7CEA942D648,10E449B0D9E3B126,4A5ECC88FDA2EC23,9DADB7ACE6BCE4B9,72CF1574CEAAA6CE,C757706B320E04FE,D3E2532684DB673B,0000456CEC02E913,9DA9EF9A08A9F45C,09DD2F75105150BF,14574CBA104B4AD8,BA16B8116E9EF3EF,5344EBCB004C928B,6E661018B8073DF8,534FE7DE8E373028,A655D7CE7A06F256,CC1FD68250D5FB63,AD1653D431C812B0,F7256469823AF8E6,00001BB14A6EC0EF,DA2C8BBB5EA3363B,C3489D08D0F83A41,D0DED0725843CD7D,24354B56D6C88832,E7DF49FC43BC19EE,8DAE32B129ADC02B,2E8637129F704C7B,6DEF6DF8649D644E,2840195151E639FA,D7C8EFCE06865016,63401D67869B2096,0000587E8739471D,FDE548982E3F48DB,7D384A642FBF7D47,E10272EE50B19A81,97C0BE0D095618C8,B0C81013E8A7DEC1,B4E46C628533586D,646D0820D3C836BC,F0D0B03C35F61B02,CEEC9DA4577EC628,E3CCFD9FA9D969F5,5C1EE02698A9B8DE,00006AF903B74AD6,9C145DF53885B683,76419C2C31488AB7,7A71297E24CA807E,6C842B7C3B79C8CF,CA3BE614CAFEB8B0,BA80989AAE3291EA,585B64F197B8A44D,BA8B02C52576683E,08D6CCEA5606173A,7A9993506965B485,216484290EB092FE,0000338729A7B2B3,E40C6D452A9AB1BF,531787A812182AF7,211FF437412610C4,E8FF132EA009490D,870A5D38A72BF944,E2DF1BE41D0EE36C,D654AEA025305A61,AF936F8142766BE4,F10CAC7AB6326E03,0F6EE1F19C58BD5F,7C83C942C8911B0A,0000598B3D2CB42A,E6F107877648AE3F,B9ADDF6DB48E898E,50AE3C7ECA187F98,A206900F908E475B,20973BBC8423091D,D9C0CCDBF536C379,6807F43E58230B39,01B8DA5B8F9B7783,8EF388E102345C2F,2200AF61EAD9EA45,79BBA0D29188AB47,0000406A4E001A97,E2C7F5DF19F2A00D,C6F96078EAD43607,8782923662CDF6E4,63C29AA976C39E6B,E974565276D59E47,B5ED716ABDD9EE17,B6A84CC045907AA4,CBC06C8826FA346E,D3285224E3621A51,717203649C0E962F,945F50429363303E,0000604651F4FE7F,2B301135A0B5FD64,2EAB21E72FD247D3,6B569BD7C04D67E9,E43872EC33AE3C4F,78CF283C3CD1798B,0E0C77ABB9BA99C8,75D62C11036A1264,BDF9A5C99BA53B1E,D034FCEF3DA4210A,400A16708A23120E,0C3D4136D3D70F0C,000022048278AAE7,49AE0A28EC988CB4,6211FFB91F4E92F9,1F764E0FB68BE22F,30B5AF1105BC0EC6,D338BC2C87CE3666,7D69408478514E87,C2E7760AC0F8CB38,D79A5559D8392AA7,796CD181CAFAEF23,9BE045F2B6860CD4,CC3E0E34AFB96B04,000042AB6B68DFAA,64FDEEAB0045ADD2,8A9623FF15706840,955F59610A3DA2D1,EA806BF416FFDB87,8C9C3F9032B022D9,8D7EFB88C5707507,92E2ACFE972D6078,CF5E585D4C0A2050,A87B0DDDAAD1AC30,7B5924E5F8EFA3BD,EDD77EDB45937E24,0000160081F9153E,F9A3D8E541DF78C7,EC70E66ACB771496,70FBB86E994F3EAD,8993DE93CE00C7A2,BF5F39D6A304B5CF,941102EBEF77514E,F85C81EF32E8493F,A0B0D2A7361AC885,94A7CD0F19AE81BE,5C9CE6C907D1E85B,0261A9887BA73314,00002C6AB694AD84,CC55AE3917BE7A73,F76D79A587740223,0651A5149FB47372,CB128801599E0332,F3317333A2ADA67D,3A08E18EE4B5265D,B3F1005E190974B1,CBA709EB54BCBC5E,3405D81ADCD22EA6,DAE1AFA60EF66188,DF8E63134511C836,00005F81F483879B,C56E5633CACF12C2,EA69E34F8058B253,55333AB738523D4F,44A28321D859CCA4,C4741E48BB59FF39,3327CD9FFB261ED8,D2B95751F81D9D8B,F4DD16458EED3693,A63CF733D5B7B389,EDFCF4130D5D1506,471BF4E5FC9F1295,00005843E8930C68,F44BF19873F90A0B,C71B7F6C6DF12E94,1379B61B36FB2810,444DEF8F04FCB979,E45E9A433E8B521C,6255F9E0D7B0D77B,82445A6AAF7BE7E2,CAB5DC2866EF3EAE,562336E117F2527A,56CE4D9C49C71C44,2EF0BA18BC5B293D,00004A141CF17A3E,945A64A963A76EA9,A90DA9422E78E140,9A7E9DD4B5B09EB5,E27178DDD4347D0E,A9339BD6311802E7,3D28947F12B3AE02,4476D8D452EF27DC,3274978B5A12768A,E6F2B009145BB869,0203993F1549C13A,E6C4C8E16D5F2886,00000EDCEE49F658,9B66044FE02FC64F,F6B61734BF44BFEF,9A76936ADAF5A86C,52C9707CE8F3F0B2,228A4631C3FEFB84,0F4A4A34CE6C5014,7304A17BD9AF08C1,84BC84D6742475CA,BD3338776D372A3C,543E8CAE36242340,BA189CF1A368C08F,000059C178AD4422,2992C73FB7455EF2,8708D88228883E82,96B86E2F6CC618DA,76061C5BCAA42928,6AEB35D677E0CA37,3F922EB6CAFE9108,7FFF9991040E4E35,B0415FC059399B39,6BA793E4FF1EA16C,F09B6E2FA9FB18BE,4857BE39690CC559,000052C6AED21C91,5954076288FCF52B,4A16E463126FF1FB,9669044B95567C86,320D144DC703AF3C,546B7F1DE099E2C2,3A9CDAA9D165ECD3,D073E6431957972D,2A353BB41BA6C32B,E8D206C44CF1CDBB,6DD6528975E1427F,FF2097CEE14C7DBC,00005CD777F09D09,B5334245F8D630D0,14443280A700CB82,669C23E505DA076F,63492A318B49DCD9,F83496241E141A20,199119ED1BE0EE5B,A215F61B29FA09C2,6D0B74D4718763FC,F1606A2818F195A4,4394575FD1B2060A,A41EFD448A00F19F,000007171F28458F,A48B35DC967CCE0B,EC721A8E0434ED3A,C394ABB4407417BC,1B77CABED655F35A,47DB04B1659C23E8,53C0D0F448E4093B,6ECE70F42DFBA570,4F0F65D0198A778D,23BBE640B24D30F1,EB1977CE11BDA0CE,F0237E34BBA98D24,00006F128A89E156,8693ED2358492C9E,086E7ADA7CD6C747,9A7F6AFC197DF52F,764FB8308CF590AD,654A5ACEC3B8E497,2B24CF58B6ACFFD0,C19F8625EFBCDF7E,5268754B1BEF3348,023B5D9C5E88C40A,4B40836BADEE8E3E,DBC92ABA14EEB5A6,00003F3657BCA9CB,51D55BE908C0FC20,68EB810C0FEC769A,822669571F93C810,B0DD1795BF9DE8C1,BE531844CBA15E7F,3507606E71A0B964,D7BCC0C1AE64B4DA,937DC9923F961DF0,ADC746319109F998,355FCF917B41D5D7,070858BA6DEB65D4,00003777CF71C5F8,51EC928D8495330F,C8AFD96F1B90F9A6,896682D27D7F0603,6158C76108F328B3,F4BB77FEC2A2A4CD,FE369AD7CCA49019,ADCB8D295A6295EB,7ECE67FBD1727DCB,19D85A6F7C406F1D,400C52156780BCC1,DC2BBD45C788E7CF,0000115D0108FE3D,2977244E97B23350,E09392BAFD2A78A9,2349FF5FEC0E4A44,1B809B7F18E40D78,7FA3F90DF9A8A08B,7BC7DED045A50511,F1714B294A1AC8B5,6C7002D6F0E2D2D3,EE2A3F6D2493F3DE,15C320CEF4EE4811,D88A9C6053B68983,0000016F0A7B0CBE,0A72A42FB464ACE2,72F3C5B2C2C3E985,3BF96FCDEF5BAC5C,A28A32775791104E,56E398FED35F667E,B2B1C78D20512197,AD7D22373BE35B7F,3E86A50099A8F2ED,E88448169CD28D39,A86C50419050A442,D182297A2379E313,00001449E3711059,287D1EB32E024275,FC589F64282EE229,CED5D1F4C5962776,C6EF3235644624BE,A8DD51FAC3E0AF4D,8F1DAB3E110258BE,8DA83242EA24D6A2,0C0A33FD53930C5B,F2661D2BEF46EEC4,DCD6CB8E49BE81DC,960237E89350E97B,000036C43574DDB1,D8C2E75C1FAC671E,9C14EA8EBE1FD33D,64E4A852C12061CF,7F04D0CF532DE1D7,2F3EB43B4B6BEC42,F72C1BD0F3620E23,B3264D35654604E6,3C6FC0665705059F,13D9233F4304CB98,C2C42F54CBCB0880,B44A36E578E884AF,000025DB35DDD8B7,9DC1C12BC2038AE9,DAE7B42E6C3F9BD2,997ADB902C54695B,86A6BD45A5B24127,F10790CB73A9BFFE,77EE51848F497A1A,0BA1BEC63BA993E6,4A91CD84A9055D1D,092035729B1B8B35,1F29F5DBC1DA191C,3BF483DCD9D6108A,00003A305F2F670D,E8B53D22015E8888,488824594D4FA28D,B8D2477CA5E9870B,A37115A5D5784ADB,9FAA23E2EC729290,CAA2CC374C950792,52788296FF00EBE9,D44E0CCF2EEE4286,36A454BA9D036AFA,84C250A7A6A9A8F5,D1CCA96A4E3CFA63,00003170E01EE824,0A8F1C80150D8C08,203A408AC4887CA7,F0A4CEA91081DC5E,13A6E1FCE7B83E69,D1197DE1338E3DD7,89120245C010410D,D4FA4E77C1ACD244,2EF39DAE70F803E3,0FD3134D0B71192D,CA7CCD09CB5782F7,2F8ACD7CB4C3E930,000059C4714B36EC,A1322EF0ADEFFB1D,58B475B17EC4BC7D,0E13016825C6A5A0,3289A6773796D3E1,917189B6113F1501,BE62FF0D941D89BD,AA298EE582685D58,3B7A063F6B30CC77,82F73A6D9A2955B5,73181387737387FD,C16E37BAE068273C,0000142D0B911D3E,510187E0379CB417,758708A247A1FCEA,A64C6E25B28040F6,44CA2C38324F6311,051236C8DDD93A24,3B8C97ED6CF9E968,3D5BEAF516EF27DD,9610734BE81B3266,8345A10C337C93E9,E12B595307C2C421,2192C35B2A0B23C6,0000456E59571C96,46333F3E14445B66,A3B0AA56C937EC76,9039EB70CDC454A8,2A64675F41CBCADE,F17FC8B6F394E1C3,ED65ACA756BA3E2D,69CD15E5D0A7ADA9,A349E384BEBE0B37,75ABBDFA05DD233F,1226DF0C3A58F1F4,B91A8281C8EA2C60,000033B9583CEE88,513C831571004D32,B67CB682E0BB4D54,BBE6BCF22788C1E5,A0C0D54151C6A503,DBD0373F91729A36,351355ADEB7EF85D,0F149AF93BDEDE26,D3B5917ABD7E73E5,9AC9BA65101BB0E3,A11CEAC811E10733,D3319B3CC09FA1B7,0000027B041C0549,6DF4636CED40BF75,E8ED0002EC4179B3,885F20C98B64D813,BCE600F598372330,C98744C4552540FB,D03307B73F583A74,FDB1626B795AA6AB,FD86E80C3052AA4C,1EB3249A282B7548,3BC44E7C1703E7CF,E16659D43C6C3F21,00005247079B5A83,C7E08D1AAE1FE2A4,9A1F2E2A9F48EC86,D4FDFD77DBBDF6E3,E64DA65F10E95336,C7EB127CEF0E5B2E,3F78A9F569C33DBB,AC44F53029A025F7,1A7EF3B1DBDD092B,56E0A1FDA733B0A7,F4D434E8629FAFFC,9BFBBE621A594C9E,00000A187B50C2FB,C15E477263D841D0,C1C9148C6F1589EB,C08EB7AB0F550685,FC58166722BBCE74,5D78846BE399B2CB,1905F6C94685992C,07517B8C917A93BF,D97459CE44B53A59,C734367E17A7FEAC,54966CC5C9C32724,8A90D464EA0FE698,000059FF88A3A3E0,9F773D2E7591FA76,53B11ACEEB5491B5,C567E40F5B4DD637,9B92D9B914727834,72623F8A496E179B,02056C056C5BC284,1EF1704447F8614B,93E941BD3690670F,E8A92D6BBFC88C36,43E761C93D74B128,58B1A85DFBCA698C,00002D9E230A1CB9,7922506667EAA201,E8B85C7AE7B23B6E,60B00B0D4BD674D8,A0D7FB2B0EC23627,1E3075B4A070A992,067F0E853AA27321,47DFC0D14ACE6A7F,C638A1C6F6368030,84D7AE1473FCBD9D,60031981C97DA150,C40E901473C37D60,00004960128EFE97,422D030F3E9C3A79,4FE0CECED8598531,9EB6044477426191,A8AB70AABA11E567,4410A85AD2B20C1F,B2BB4AF2E1BDDDDC,95E0D6D7B891D366,F9248AE5D7CCC7CC,71025FDE4FE563A1,B6C8EC194DA129A2,7CDC049752ACB74D,0000302E09660579,EED5B5388174BA7E,DCCCB9330342767A,C4C7BAE09F3717EB,29A3640B957D668C,7F874C803A00623F,86AFE148820F80D2,FDE14E05571CF987,1608142CD713331B,6E87FEF49EB8AF82,0D5A9ED897B74C2F,F8BB71FEE061228F,00005F13E1CD120C,35772C4A3AC3CD0F,337A2BFC0DB6E403,AC8F8DF1FAE0AA33,D1B9F9677AD43E7A,1526A6B6892A8A73,E4755D74234FDA77,158B04DADC5361A1,EADA81D31644F9B7,F5AE1EA680A923FD,B166D8FB8AD15265,0EC8BF906A857565,00006CF3D067F5E0,B3B3B2DBFF154B95,513EDB8C10D8BB82,1C87612ABF17C0AE,CD8DB5F4D0399371,DD6BB11183F0CA90,1D970E3106BCEDF9,0FC1118D4CECF39A,16B980DB0260766E,281D8D6608BD2720,F1DCE44E6B64FADE,CEE38FCE4203080F,0000651EE494296A,B7F29A9D1108356F,BF85C6FC9CCEDE4D,160369B1C9B8AE05,31AD14E432AA6599,495FDE14463B846A,DA89D2D25F32A8BC,86EBB91EED16690C,31C1E4345D5F80AF,873ADDE7045526FB,8991AF4BF02CB59A,688E73F5BE856F4A,00003C750E5D717E,13499614B83610BE,6A4D90BA40FC9E30,5A3F14A563790D78,D8D2CBC2B03FA24F,64B7C23A2D2C7E5F,0E259ED380579295,59BE927D7F9A653D,943DE49F397155BC,3BF0375F1F670EF7,E749AC5897298E23,369CDCECC6816FAB,000010113B2EA50B,FF2C7EB36488DB1C,401E26CD8A892FB9,569CAB5F815B8F0E,E444A7489E0EF73F,1E97A53C67FC24C1,9A0FDB096F021F0E,F97EDEFAF6A548F8,3620A7439808BBB0,A0A820FA0DF11F24,55928E241B1E2C38,9030A0361913A83B,00005068D72330F7,3054F1A9CB2FE6B1,07C1353B82D1BA55,F4C49CB2E86B618E,C797627F0DC1A277,AE45720FC198C045,622E043659A278D7,EA5D23A15AFD0EB9,F8B3F8F59C9FB5F4,8FDC7ACD5B85391D,F01275EC378E3CD6,9388E86A75DC3E51,000052AE519D054F,79FF9B8FD5AE9E8A,828497B5B4224D2F,7D57A4726072F9CC,D1860EB854A7E70A,BFC6C39AE3EFD9DF,332EE98FEE3632FC,310E3BFDEA09A847,606BE16900C32AD0,D8A93E62CB2CF510,20F12F6405EE78EC,457C804F6F1116DB,0000053426306A7C,8A7278F3CF538AE1,0CE9B1FEC967C616,3375E38DBC1B04D0,49DADFA9AF5BD413,51F909F676EEE6F2,FBA28126BE8B3ED7,5D4A0173A79A732B,79FCB4582F3E69C8,E22E5B103BD0FD54,BE5A3DC1B40D5CCE,C02F741E758BFE09,00006EDCDA7D4F9B,1C32D07D38926669,6593FAF7FF70CB9D,4BD53C3689A635BA,D198C05F4F035C99,6FA06D6DD8F11647,5F40161C1FF5F5EE,13D99506567A64CB,149195BCC00110B1,C83258479DB9B230,50B2EC6C7B1899D4,D5670C264AACD3C5,000024DB43778FD3,1A947F88921D83D2,4718C3BD88CDBA06,890EBD7BD40E05D9,400E986A646908B0,C816117B66E670B4,6FEDDB4C683EBA73,2E89C27C741C95B8,4D7B6EE0DC394C37,10570DFD4A04C281,C55F4A809794B1C8,43A289EA03D68ED0,00001F28BC27F548,4EC5CADDEC270D87,4516172305A7E495,F29C5EC3739827A4,B07298D013D60893,24A69A390445CE5C,B6E78B16EB29F7EC,B28A0921960CE289,DCE38ECE2A31C03E,50BAF5B312F1B21F,873855F5FA111D78,58714EBA73FC153D,0000371424B272C3,E60E4CF81D4B55D3,9515CAA5C52102AA,014D9DE73FF19E47,4490D9DF4CE4E3E0,4DE2B962F0A4EA43,98A0B2BEFFC541DD,A26F15E62D969841,65B9140255EF03EC,A3857596EBE142D9,0E3BA6C02A86FBD2,388209FA99C66D1E,00001E9818AB6468,76756E8197198AAB,D3E48B4197FBCADD,E3D49603C2C465BC,A9BE4792E4A69328,D1FD8434E8881A6A,E9414EEFD0544423,7C0E5694E22F19EE,018DF616C7720A6E,96134E078816AAD1,CA5F057F42A517B4,E054CDA6B4C324F5,00005610E46DDE74,77A9D6EF98979E9B,CF569D5B06B3A86F,3CEA37858D78F782,A5ECD931FA9F33E6,BAA80D16BCD77CAF,1F3AA6A00DA992C9,64CFB60547A6440E,E8FD8D606AFE9D51,BC5782DFF75DFEF8,42E405393A81BF2B,3540C454BD677CB0,0000282CE72C0289,204938EBEEA4AAB0,8D0AA9FB63A1D015,D58D389D56176286,18FC3AA85ED3DB1F,B4D7441818AF5D3F,C134CD8B8BA76AB9,4D049E5D56DEE72F,9059613C21DA2443,25184C03406ECF5E,AA63E7E60FE961E6,2E5CEE3F4DBF18B2,00005FC63B9DD2C1,BAF99D551B383D16,C489B6713E5080A3,0C00148D8C925356,2C7DE9B8BA38A835,E922E18AF039F5C1,D716042B3EAB52ED,8680A4AADD955DAE,35AF8F3228517684,35BFFC3B48CEF2A4,5FDB93367243D525,B7DBB353D35B45D9,0000190B5387E87C,D77E7DE3FD1BDEE6,0D49A1AA7952346B,5DD9944BA28B73E2,633A59276617D792,F7F74270739678B6,9FEA1EE72864B13F,197491793B604C9B,C9CBEA428067E0F7,F5870E1F82C43FE3,8D9C7AA567395624,B28AAFC2BEA904DF,000000EFA15EB378,7C7BA6A97B41C9DA,2B70D7443E3ED637,91DC966369673712,F3D17CD5CED0003F,2739AF8F4CD43440,83F1FA92DFB15EC7,097860D375F0190B,E0D431EBDD5779A1,787DFEEECD18F0A0,4B08F0A67F7FACF8,117B92E67A2A9093,00002C1408C35F2D,ADFCBDA06BB3F68F,D91718E836AC5AAB,16F9A8AACF7E4DDD,4C64E573A9EE7164,1165C4A6CFDA970C,4A3BFA847080E4A5,EF63D9B964E9DEC6,A34B396A8546FB84,22789ECFA21A015D,784EC8BEBAD090CB,0DDB5AF57D224CA5,0000516A780D15F0,539DCF8BBA10B08F,26C94FD37B2F2ED5,1C4E2FE77D341B8C,3C85C35211D63215,81FD4A55CBE2B25F,93D878AEBE56382F,C1021B4E6F801467,36C28EE33CA56048,91FF4115F0B84395,EBA8BBF69CC39A23,C1E4642ECF9DF50A,00005397349C784C,D473F657076B7834,03A6C12417A4AF0F,5998B4395E113562,CE997A2EE47F2BFB,7B2BD7FFD57B32CC,730ECEE07C4E9F47,AAD87515767F50E6,3F13EB9C5E9E6DC5,4C75DDAF26810BEC,21091B2D89B257CE,AE9DF5B1CEB4A71A,0000375057DF769A,3F16CFAA856399CE,B08F50EE559753CC,FDE6B38857884C15,1BDF66E2567431D1,B94A643D75B22928,B752F2F28642D0CC,02DD07C5A980F8C1,F89A1FBC89968992,B951C81393418E6A,51E7CB4E69B16930,FDD6B47BBB1F253B,00000533E8215B2C,18FA5BDBCC708B65,16BF975547511F7A,0BD33255C7AD8196,547C876E661EC911,8F09732893C83D1B,70F8BEC5126CFE9E,F37BF521F95A2380,3E1CFFE7DD9ADF0E,0ACE013923F0CFC9,675E792FF0C58366,0819660F57CB8489,000005EB5D33C92F,7CC0EF3AE3B056E0,27AE42CC05F0AF77,333309E007079765,2153F1885850C159,FAE853968E86CD9D,1C7E2A2B6A1C2B95,8782CE515DC334B0,91E2E341A95FDDA2,1579AB8B878B7B19,A7A8D065FF9DD9C4,AEDF6CE9612D9B0E,00005AF1279E5B9F,D580E9B6B1B9EBCA,247C103F24EE480A,39BF9EDDF7FBBDE7,B6472E0C1822264C,71679684987277CD,D9AD205B93638D80,AA13CE6D9738793F,6CAA9D19E4C25F5F,165450E8F58336DE,489F19F9558CD395,E69FB9CAEB437B5B,0000125AD8ED223D,0705C584BFEBE38E,33B613499DCCF62A,14551971EB75162E,7298F2774483E468,1F135CF1A321F70F,41494A0F64553E82,3A4CE6CADEB508FB,35A9319C99F3559D,4BBAECBA5DB0C9D3,D36E394595B6DE3C,EFFBCDD6F29C226E,000059F4B3631E89,C3FF6E1A32078929,32E63E949C2B7842,BF9352B5040ED9E6,FA08301FA6EB8326,D6821FB1D5C90897,B81D323B64100879,102B0BDA96C10505,448602F78B57F5C3,12D8FBBB37056E23,61FC07D95F18FB9A,C84BAF6EF84FAB5D,00004160C9D40EE3,90A8D68532271FB6,C0F1353C19B7AF31,9F2890999479029A,E888DD1E07BD8DD7,A120A23171EF9C14,392B606E557D6855,1D3BD72074E39658,ABBA30C0F8EF982D,CDBFD3CA062B4CC9,E28B1274E63E4B2F,0C43FA21820760AB,000050A328604418,E589B1E686FE6CF0,07DDC50D8CBD5280,66205AFC545F095E,BDE3943117471E2F,5DAB1C935AF7741E,502B53E871D9105A,0676C73C05EB509D,189D104CD06A3FDE,B76F7505671095C4,B0106F9B0C28FD14,D21D5D460CF02A99,00004F7DD876A71D,AC7D129832C6D249,4D5B62E453625BDB,F9EBE8F1BC0E33B2,DF801EC48AA44A89,A9EE6BAA572A949C,6D49B3CEAF0445D4,C65801D3DFB17EB8,B22BB2C871E5B70A,1AB7EE6DB4CFF83C,AB74A70698162CB9,4581B3908604D9C8,00000D95822BFE95,BDA3C71BE7E88C57,0A7D218800262FF3,39CB2C95D27D8D0F,95A5BCDB863DC062,EF8503DAB5535BC2,21FFE60054013DBB,57F0FFE9F4BF60CA,3974CA866251B4E1,59A02F8879DA47E0,38C732B349B19569,7D8AF95B174BC969,00004522D9E7F431,17163F0B0A25DF8B,F47F9A4FA104695A,3CB8EF090B1F395F,189034D5AB8F4A72,A16B51CB640B1A99,8BFA5EE5F19C7142,15810222E143BE0E,39CE28B1A0144AA5,F8DE550998BC5738,D5EE477B005B6A3F,AFBD3BF0FCC046FD,000068E9FAE4CE4C,70D6067CD402CEC3,BC8895C155038839,007E41223712E4B0,653CE3712A3E8163,408F21FDDA559482,4C13C20895B4C14E,0DBC1D6D66F35D05,3CD02738CD66064F,8B91A6A711BA8F1D,A1399564CDA15902,277F0ACD1D89D8F8,000022AC8F26E363,71440A9129786802,15FD32D6A9228A17,15328E6A8B629B76,4ABFDB9321161C9A,7C65349F810494B4,A797F7313A360E4D,95B6F8A338FB9D56,921CDCF4F96B1653,AE20AA82E7301643,A44A2079DC29E660,0E627116D742409C,00005C6D995712BA,2FF7FF8F507E7CAB,A5C836D56C910249,992B680E262EA14C,E3DCCC9C769E943F,4E90624A443C0570,E06C83D9FB8526C7,595A15EB06764193,2FC1E6E688DDC609,4697DAD06D9E71E9,B9F32B38D4CF293C,459948D7F6ECC4BD,000006A62A3B434F,3B44257A164C049C,14CC2DFE0061D3DE,9B6C1B182FE63125,161C5F51CC4E5765,F888E0747904C404,1307B160355D8570,35A5A9ADE1029552,6640F4279B5D594F,CA0F27ED2DBCC2F0,87D85310F4DBB702,3C488D5CD56515C6,00005D2A357C1EB1,101F25D1B49A4948,CB80F9A30D53D781,F19AA2D8E4FF0B00,0E3525901B0D770E,CB5E6B20B1D5085D,F2ADD9A76C64B72B,9F286B59A78E9805,587025422C6A3E0B,C04662C8ADA3FB8E,F718E5277834DC87,14110330A1B49A8B,00002A286B6BFDB0,78000967BD877AAB,C3A64E6F2533A0B3,3C1F3E26E9315EF0,930A417A2D48C43C,F8F817C1AE8C3BA2,0DFF76DFF781A0F2,BB641D8A1423EB7A,C79D5ECB183CC7FA,EE0FA18B2A4486CE,11DAD369D6E097DB,B9B9A4FBD6EF95CA,00006B3B54526D9D,84B8B3BE9E051F13,690927FAB4D49B47,ED70970E4CD138B1,B1C0AD8CE566BD91,2324DEA47F9099D4,EF013EBFE2EE3D2F,8E88F944575AE6D0,1ACB614341524E42,D7B5848320A2524B,6C8FF5FD78FFF6B8,705ADCC2A23A2307,000069F0BE8F05EA,8BF5CB31C61E73FF,2CA53155A286455C,14213F23F9FEDCEF,22FE9F569AEE4C2A,25013F7D0E7AC42B,9B8DB2AEB2AE7413,676419D8CEFDE3F3,29628923210D1E3A,7FBD7365FF858156,11004E18AC50F9EE,2038AFE39660A30B,000036CA647F6D93,5DF67AF1B5950277,B251D9F4ADFFF57E,2ADEB89331AF7B2E,AB3238B084C5024F,E072AC018EFA1679,A1EA3BE9FEE81688,D2EA567A8A1A878B,68ABEB68481FC65B,62E789A4655C4150,68F06876EA4F109B,27E44BC33213E741,000004A146A3D006,0BEB195C383B293A,7D0D55C835E3E9E4,ED303E977FAF0D38,01FB53EBA6D989D1,915C92F447377E23,635BE328324B7952,7EE2D3CD730655D2,6159393AC12A2191,A336D3E35B06BE7F,5D2F9223816E60AF,95E8AFA7A3402074,0000396AA30FE321,7489B9DB672160AE,F24A22BD4B66AF39,1C3B208E57833133,E9D35800716B0681,A707E1221B833948,3EB2178BE3771AA2,F7559583FB1672DD,13B6B598C423DBD7,DD96D45AEC18706C,969BCAE2D53BEA82,FAD36A5E3EB94B51,000014C35DEC2A17,0B1E75172666B6C7,84948DA6EAB10569,B5984920E874A98F,49D45C95A842C8CE,4957318264B6D1DC,761C59170BEDFE44,C1497CF361E6A91F,8C38C3B21DC279E1,E76435A3D28A08A8,ED3FD2D9AFE63D03,6D693DAC1259FE0E,0000499A583FC2A1,0806520680F1605A,4D16AD3D96392DEC,3B5B00798A07B1C7,EF54521056F58B99,2C695B9DB0B84CBF,71012A307454074D,74FE5B92E22773D6,5CD4C25963B959C5,F2DCE86C88CA3143,8796C8E5ABDD0E01,7841A10FA0F312FE,00000E4B29E52FB7,41AF79272EEC7219,A270D802BEA60788,CBC7D577484913B2,667EC86F3C92E987,63378379A616C864,6D72B46DE60C4517,A454CB1E16EF4354,4AFC455092CCC4FD,4FC635E05F621CB7,0235B0E1B0C99132,DE2DDA5BCCF31772,0000591CA4832336,5D811B866997591A,2FBAC389038878F4,BC0072A531FE6D0D,44F6AD37F0A8BC9A,35342E009EFF5AAD,936296F6A8F1114E,E6641FD3E681F304,1EEF1777CFFEE8F0,FBC66C49841E7E51,B564B959580FFA22,F83AE2453F62209B,000022882A3F12B8,B3F44617F35A1407,4E20D37E285E6188,89A7C6DC3CF7A2CD,1A938685EDB54587,9BBDFB8A5140C46E,6B3C1D092605BB62,29FD35AC2D9040E4,BA4CBDCF3452E944,1712D026439193C2,BEE4369DFD18306A,160ED5D328EF9458,00001BD65F872B82,3FC76DCC39E59377,B454070E5FFDC8AB,B7ACBE5EF495CA60,AB1CD88F0B8377AA,4E3AE2D92DD2B791,E795770F8AE35F89,270BC590DA0044DB,F86F036AA0980E8C,0684673EEBCADAC0,5C2B70A1F237B464,B27FDA1BBE0405B2,000025A7663B34AA,FA79FB14CD8E4320,8FBFF950EBB11BBE,AEED2CCF4816F674,B71171C4B05E2B51,28F1322E357B64AA,77527FE998D0BBBD,B8674ABAB42F064B,27F7446C5B63783E,F3147A95EE5AD5ED,7EE0B87CB351DDAB,E5426E99C51A0A60,000067D0FD08E0B6,FC57CD68265C00EA,75A3D0555EE1A603,9C62A695B965F1B9,0E812AEDE48F1E38,A1B7FF7A933ED41E,29AAB36B4422F272,8288A6E67B2F8A67,10FFDAFEF0B6555F,FE7CFD84D58C2FF1,77AD85D356A05B55,5EB902AA072BAD32,0000638A873ACC63,7858866A35BD3251,D96592AC40C9B86C,E00AFE45AE6DC173,A1E221854C90DC5C,813F33835000F24B,FA6D732EADB19F3B,1AD76C736D261DCE,14450A57D7975139,4DA2ADB7ECC63370,55E063100103F1B2,8CA8A379A2E51D8E,000032997EE85BA4,F869BD6FB9F763E9,A515FCD269B95887,5A76A29FB3FDCABF,DAB7E4841A4B16F2,BA5A77FEC6BCA314,CD5B7ADDAFBC4C1E,73C728075C63B755,3C72C9EBDDD8E57B,8C6596BDCB648985,91A0B6409192042B,C5996637A3631FC1,000068F4A48905FC,53ABE69D36298075,EFF4708A860C499F,3A4750BB396710F0,8A341B1F83D5092F,0A16D6DB42B23CAD,8F88BD3EE5B85CAB,21CB85E6A9C77E40,BE836BFEA75AA7CF,392EA7F56405BD3D,E9553FA1A583EB36,9E5A3614537A3CC5,0000449E7E8B7353,16ACB32200609AA1,2C02F91E732C1A69,9D1FB3C8375E3198,2AEB0337CE3C9861,2E7D1ECED328D7B6,F9F1C18E68657F64,032B3B4B3777EE23,135FAC38A9C05701,6525618A42FE8C29,071442C01E672B65,2AB5ACD6ABD4EFFF,0000129E3D1DDD2A,C292EFCD18068064,6B866ABBC3711192,02C10A714CA1D8A3,7467002B18C22BFA,F8C22873AE3589D3,9A651DCAB7D5685E,9D53E5F3CAB34082,98DC6BCC67D943DE,7956ACC3B1F2C6AB,660DBDA2FB78D88F,23B501F69D4771F6,000009E2FEE62D8D,631CF0EF056B7342,5A21366BE274F8D8,07D8B832F0A80AFB,1AA32558506380EB,C49E94A2A0E46FF8,60F406E36F7F86DB,EA9A0CCA74FDA8E5,9F5381C67B5AB844,B296A82789B71710,72893FF78D5C5A99,746EB187D671CE57,00006F699A9DC4DD,9EDF984E6CDB7AF7,A5B70DBB06F0A3A7,95FDE30449033F88,F5BE13CBE3304C75,F5F6CD7AB035302E,1E8BCD4AEF34F2C8,5A2A0DE80054E96E,EE516F0A799A07E2,64AA0A7D544899E1,0603ED303BEBCBD0,DB60B08E44331F2C,000044471051B3CC,FE6E081103852068,49B28CE4AB068106,BE9F673A3BCF9E53,BD55E83EEFB03B77,F5FE52B9341CE77B,B9A0133ECDD6B524,2C7674673DF710DF,01EAD136528FCD86,7AC72F022A479E48,278C9FA4E8DB105D,D1E5F0E4E560BEEC,000061698E42627F,E14292471DEB3E48,BBF401CF86E8D11B,1175F3387EF73517,091A645F6B01E467,1F5CC464DF85C4D3,9C60E63F1F7A4945,19B23654D34231FC,E58769B56A09110D,ADF2F6B0B8AE040E,50E74522DE8ED940,EB5039C0E4BA6C4D,000002A6B7129F61,D9318AE388B2C332,9B72BCCF4D36EA45,71B6E7ED25B5B0C2,80DCDB26FFDA03D5,90AA5CE8ACEA26A3,E11D4BAF162D39A7,4D0C5E1F796EE967,CD69C1C9AF8374D1,9D993D4B87519EAF,A3C50F5B3D31E1C6,5E276533A1B18D22,00006265F1B21179,9D18B0814F475707,01B3E14F241532A2,906C443CDAC95CBE,D120E8DD41E43944,B28F4A119574AFFD,A312B7BBD91F73ED,F3C581D8F4F3F862,FC2C19C66D9B2E71,80F66F4DEA7DEDBF,03F2B9A24BBDD2B2,8D71DCA51392F845,00001B8222A4030E,58D548144ECAB776,59184779D731F4B1,9D5A3FC1E0B31F9A,4946D8C43524CF2C,50930FC6EBE8254D,D61FE3DDCA6B3DFC,4484A3E143AAC690,D2BB998D14CBF2BC,FCE2450B95FC9082,E47C5CD793343DB9,9E1EEF30DD0A5BE8,00001883A3B6EAB5,E683CD4DC18A8532,38E233BAF6BA0AB9,EE1D471224768840,30B150EA7E9F07E2,D6E7520687D71B04,BA7EDD4E3A25586A,D8C5D71048DE6780,46971DB20061B382,C6CB662EB143B8B5,A9DFFDDEE3D332F7,909865868DC5D762,000051234FAD4B2B,E3143F81154EE4C9,488E5B2284F159F5,33CA2DEA64579DED,11D1B155C04FB7CD,F562D028B979E01D,F3F87ECE884DA0F9,7EF39C74C7237E26,ED6FDAB198A5E532,49B7E311A73F28C3,DA9283AA6A837ECC,52E6C4FD0F0C8E4A,0000425FF76EAE7A,375D5EC36EBF1E90,F393AF815CBF8DBF,96C80335AB610C14,153618D785CDCCFC,EF0D39FD7B68BB66,F0A0603C5C93C81D,E453FE4D20C5541B,042771E2EF8DC025,8AA424A06C5DF8C1,F71B27B4754A2371,D3965C75C868DF0A,0000495B6EC4A981,947DAB556E2E7EA9,53F824AE389F23A6,0606F784498C84DB,D10B4B00AC1A80CE,D39351C80AD33236,7D1B41511184B768,04C872835B7DDA2F,3168205897A2B738,302DB972DAA96CB4,F0A9C9B189A57093,EEF8BD505376550E,000056756811B75C,982566D5D3C18B07,0961DADB4EE39A29,D38E173A25D466B9,78EF41CB0EB09C44,96AA4D3A2D989F4D,D3590DDCF0228EE6,8C3C615C773F2DCC,3EB46412063A547E,AC8E54D217BF38C0,B7EE759353EB3802,6E3A0ECC98F01B1D,0000612B81C2E6AD,EB7A48FF7B30691C,7410B3092F0DD175,4FF37999E821883F,8B5914AFBAC994DD,3DDD04B1667DB5FD,2E845E2897DCAED7,95B411E63404DE87,DC6C36CF4CCBB8FF,0218C80A90881621,64CED07BD30E7E5F,52AD7F00CE00D9AC,0000385594742458,9D3B531BB05C78C7,5350C60C8FDEF0DC,A4FB7AE7A17A4DD8,9BC845B16A4C00F9,65B36E10426E04CD,110B3D769E0F4155,331A9FC780C9F467,EA7B136C536CB529,6C93629FBA58ADB2,A8C0139EC0D48C35,45D75241499C8F25,00006E1030214568,E59F81AE98D4A2EB,A9B5F93612E008F4,5DA3BC06491BD121,7815D7DF0EA4E7A9,6DC8A4F8FCEFB8AB,EDA5E434644BA153,E8C0B2D0125E451D,5E7E33D2534817FA,5DD9D2F49A7E902E,45DEDFA6D7642760,52E12C69CBEB930F,000048E93608203D,7EDAF0A04899A155,EA4351D1E9D84284,F51965A24EFAEDB6,792935F9B7C5D4E9,8071A44FF46F9C4C,20B44AF6EC38331E,E020675BBA39FABE,266C8CEFB407519A,5B0F1941137F53AF,6EA4CE61592C2EFE,1350E6516661DCA2,00002EE9C2E53A94,DB2F33F44D44BF18,AF77A4BF8392F28F,0B393F9D626106FE,00B3048E1BA7EDC3,D172C8F938EB6ED1,F71D1AF30AFCB90D,23C88108E19D58D7,A872252A5E204359,E48B7B34C3EB5976,925D656B3D687F7F,B04486D1125C84BE,0000105214396599,D3D71FB974269A8F,7B72D515CF159163,F2106AA700549551,448DAF2D04CAAF7C,DBFE25AE181E0AB2,41FFE93AFA7810C0,580139CC3DFCD227,FB921F9EB0330884,CBB36C3A41A03A6E,505B781921B396D2,E4AEE0166CC0C993,0000420E652D6C4D,EBCF505A8D9EAA07,F91D8E748A02FE04,CAB15FA791604AA7,F6D1DDD614E35A3E,F2C812C94D1778A8,824165A0F5943CA2,0C215AED3D2CF5E9,BDAD80B07793A666,623E7321312DD4D7,23826E3A88E077BE,36D1B8AE0F79AC14,00001068F666D2DD,A17094F0B6AB4A45,94B90564C817E48F,5AC02DF97CBD0DBC,3B7DF92E43CF2EAA,A5399D1B840594F0,CD53BC41BC479513,C062C3134CA93A1F,153E1B1789C59938,5969C30470DFE733,627D6D8F71321046,21C15AC40793C679,000035301B852E23,E3D7EACF3ED3BF0D,BFAD322F47CB82BA,DC0F69E18D473D7C,65B036A6E0D5D411,AD1243631A242E09,15C1976602D6BAD3,A4407044B6D13DED,9098D13D167CC524,60A53C97D277E411,531AE5599554D7B9,0613791A20158AD3,00000B782AC3768A,8FBA46FE6A24E95D,0D7CA81419ABB310,6ED4D58ED5653E36,D5ABF1D96D3BD323,6E9A2223E862A51D,2D4B778AB9056B90,AA3733150D8AC4D6,67CE23ACD5AAA5ED,1C0949DAE3FA297A,B2E95504A7AEBCF3,1159FA1F40A1F041,00001C7D4188AC0F,0E22FEFBC8EEEECA,48B2B8FB01EC8CBF,235BF6B8C170C360,63BF7A734E84209B,55276EDAD7511730,A13B67F461CEBEEF,AF9E84BD1BCE573F,48FE119AD70F8C80,67E3160804EADDE9,1CE3A23071C3977C,7B6156D93F2EA100,00006B0906F3DF1C,070098279AFD64F9,424C003BE4FA8ACF,D924C4117F97036F,FC72FFE6FB3F2393,1A7169BA70BDC67A,9D6800512BDD2EE7,4B9D9A2E0E896940,81611189CDA6127F,148C157BBFB2DD70,395EF18F37F8CB6A,FBC502A2F4B3753E,000066BB3CFD4704,89AA93680DF0C331,304B741794476B88,AA93B88B5D3ECDD1,6279271D9528C082,D14594AA054BA1B9,2F8D81E521A79EE5,D3A4718698EFD4AF,7E5F13FF2ED85538,360D5FDD020CFCA3,D8D3A42C12E53ED1,4F18923768338EE5,000025179BA9DA97,02949197721BCF6F,6632CB9DB6DBB1B0,54CA6E62679B6E48,7E57270E0DBC852E,F649B15C13050ACF,37A633CAC001BAF5,984C31CE9A34FDE3,DBDBE16540FD69B5,1F5BB7CFEA0B6EB9,F502AAF4AD3AD8AD,55FC0357F1A37816,000022C0968FC89C,BC783974730EF635,2BB38A0A0EB497ED,C2773F24D96B3177,1795B6905D0D854B,E5968714E1249AF1,C8A148126EBA887C,C806458F675FE934,CC0FDEC5FAF990A4,388CB7A14AAED8C3,B12C5B8E5A63814E,1A8B937A4223C6EC,000025C23FE97C52,9CAE4EBBD6DEEDD1,AEA557473A6839B4,07433F217AC7EA6C,920B03ACE7FEF391,EADC7C2719B92648,C6775E0AF5AC1A3E,84824A9C40776433,415894DF9ECBB879,D77B3E485F8AFC36,4A6345ED258953EA,169D8EEC66325EEC,00005C3703455DA0,A53F666C0A9E668F,7BB31ED97F0CE55F,369D2947B9C335EC,9913DB980B7B85DC,1A8785079FCAB17A,F1FC0AAADE460E95,0A0EE1BBD933B68B,7489D9EE06BE9A22,DD94D40EEEC81266,E4467917432EBD6E,088B75E06CA2F145,00005F57B080D63F,75770B5E319C0AEC,266EF3297D92899A,D436A40609185BF8,240ECA01906BDC85,47E39A3195EBCFEA,42B68C5D01C0DB40,68E2AD64D819F06B,5344435399E8C048,0C396B8004D9FCDE,1057164FAA913DEA,9AE62B5F7FD70BED,00000B7C179C7462,BF9C91F68D2EA2D7,3E5ABE6F3181F94B,A4F9B573A8BD0C22,CEDF1A60A753A09B,9647240F42DD2671,F28C432D87363E04,292594C1D39A465D,524CE6C5086EC652,7030E21A1ABD0C2C,9DB165B2A1BA95D5,4A6BDADE39FAC53E,00004922B23A64CB,0CD0DAACAFC1BDAF,CC8BAF7E77BDEC92,3866292964670B4B,9907B6A084907E7F,2205F2A933AC7995,B8C3AB9993D1EAED,07A5951762EE6A14,C14BEE0E0BCD0E78,C7DB0CD2D20E809C,6F19C8CA82673336,816558AD116E62A5,00005BB34FD8B15B,FB3E5091A94D75BB,5615567DD1803179,65431F8790BDCBFB,D13B6F72BD2F9373,9203E725BC80F58E,009F90864729D851,C09E9EE4A3E8DA88,CE9BC094FF2EA1F5,D4C54B8A5434B70C,6D818FF2AF059473,60576EB86382FB84,0000135E207DE7F9,02E1D24462A67619,EE9D57E4CE5930FF,B1BBA312A58254BB,A3BA19ED6A2FBAC0,D9B33B4BB8612CC4,D00D35911A7658B6,AE53BCA77485D0F3,10BDD5C9E61183F2,B66FF84AD72E794D,CA2B80A834568402,31E0C1E4751C27F7,000042540D9F06B8,BD34717262B48F43,CA0FD0D292F0FF4A,A19B0D108A3B2FF2,1678D4460D7114C1,394C737AF04D215C,5080A6EAB3D5548D,A4328A6B91DEAFF6,643E52A9AD8BE7ED,DC6D1B725FEA108B,B870D6162A13590A,B6C39E5B3B665E47,0000038464502326,67F7E284C731B679,DDF9DB270790C86E,8F8C9844100F1E6E,D71B424B2E1357CD,54F06F9DAE962CDC,EA0E82A69700D90D,5CC2572E79F89E51,6AF6F68B1C72695B,3B9276758D664066,3024EEE8E7AADFD8,4B42C47CCD01B77D,00001CF9B5FF2F4F,2AE329C2FF07AC36,A87F301D24470302,C2995B8E50B6DAD7,730BE06B15A9F51E,1F920481752D44A8,0E7F534F19F777C7,53F4A847EC85D253,621F4864C548BEA1,56EFD35FC9034581,C4B8D66C6E6D86A5,DA74C075313ABB87,000067B6597212F5,6C17FE33F004890A,00BEFC2E276E3AF6,089CB248C5ADAF40,5C94AB2BCAB47C92,2EB7C59A14F4B180,327C51709F1AAC0B,6DDD2D6241E89D57,E12FDE8F789AB2A4,87B71C0DD475C022,B90901B0FF7CC92B,353823A321FA646D,000040195C18F331,CFB69DFE712F96AC,81D36E868F16039E,8A8934A4F2401CD9,9581F1176F0BE73A,E90E7B5C52435F85,23F01CD2EF98B3C1,FDF10AA912455BEE,4756DAA4E04F9730,2132898002E82B50,0EC647A6D10943FC,1BB7BAA5F457FC6E,00005F01A842F59C,61A4D48C34D08C1C,B8DBFEA9EFA70BBF,DDD926A15ECFF57B,498C29FB5EF74A79,5017021FA1094C61,3BB471F3097C1C51,07FA5AA62C11EEF1,5ED87AF67AF91262,4EB0083CB072432B,6E31E7B821D62751,5980ABD4C7F52B92,0000628D71172AC8,F7A9CB07118249A7,F3267CC7BEA96512,57C4B796DDFE07E2,998CD1364AFC88D1,D24361FC9FFB0694,D1D5A3D0486496E5,E5E9F5104027B757,60BDAF7F068D1A07,EC559FDEA65C4ECD,39D9E36B4FBFBA0F,613C611FEA41CE02,000019F801F01B6E,812E26F964221E83,36ED2A968C3E835D,7B4FD87C63BEC349,074B78013C5CF26B,F5AA61B23BEEA319,0A8295030FBE1ECB,86A5D0E16D8B7C0A,D5AC4BFB29398A18,ACB3D04382AC3387,6A05B77CD0B17F26,84D0C8BC28959BC3,000048DEB964C82A,3BFFEAF4A4E90D59,85A03E51C5CDA223,102A836E7B6D9FCA,220DA6AF0339678C,FFC761DF97FDCCC6,2FDBDCF176BB31C6,FAAD7F81E431BCE8,6D7F7D05FD4697EC,34139C963FA7597C,F85479AD0D173198,57983B1F3B57DFD9,000068ADA77B086C,289F2979840A678F,90D641A02147994A,7C7D5953B2D35C9E,E29E1CA5AD4A86B4,50B836DA235531C3,B17408603AA10EDC,BA68E2A9C5810DF5,B93D25FFBCB8B02F,F2CDBB84ABB078B7,8108117EC80DAD72,BF2C074D8E39B458,000021BF81578D79,B70BE3E92E9851E3,48D8C10280FA4F53,0ED83AD6099534D6,242E110BE20838CE,6D15A1F7289D7230,B11F89AAC4F30484,E1ED8E6E85D09429,904CABBCC307698D,B36FCE7745AAA236,F5B168614CDB1542,D793F50DD525E87A,00000803F281DE4C,9CF2AE0D1CE42480,AAE91BA7A6FC09E1,95638038355B2D41,A6783196A86E2A2E,4708D38C62D47D2D,50C0C603709A8011,BB6B70BED45D4934,DDF6EC296A7FA5FF,89D3D8AD76632241,5C762F6AD3EA8C11,423FE1B2C88B9924,0000670598F34986,E41A648395810548,238839E9148DB4E1,6F210A714642D027,738BA9869515EC12,A7DA18D6CF2CB940,EB3E4C358E6B4142,9AFDE84CED1A4CA3,BDAF2A56D15A48FC,FD8C2DF2A816B591,0BDA4CD4AD018D92,09656BA903D03431,0000568F447BE855,B20B41008A734906,A9FDFAB2451A5BB0,7CAF8E09ACB07E04,7F84F8556C219317,60BFEF8911D1CE5C,7AA416F08A0B2276,0CFEB297EDEBA893,60BA1920F5BE6C21,0588420A456BCB0D,B70114002C40D298,03098DE3FAA091C4,00005C24B8945E9A,882DFFE0794D69C6,C4537B4D7EB547EA,2CF6233CE6458B28,6AB3ACAA9DA4DF81,6B13A56EC723A082,71DA6B8E450931E1,0B0E961E6B31FFC7,B897C39D6CFFB47D,09C46EE6BE5F9ADD,6B69696F9C963AAA,976B12EA23964772,000017C0E221009C,7739A7CE1FC6B7A0,19B043601EACA884,16406DEF72C96810,B06396CC11E49CA7,44B9CF60B39887B9,8FD05565842CE39E,349520267B3333A5,7AE6B558B6B7D263,79472162753153B1,DDAE37AB787FA025,27E4BFDE5C9CFBCC,0000407326EA944A,84FF1E0894CEF303,D7AA7E47348E0A4C,3BDB8F6C2D373A31,1348A94BD7AD1BE7,1105D99F78104EE7,40F9D84C01130688,500C49429A664DC5,7603E6B335341103,0FE79BC0DED601BE,BDF7568494F2421D,8A393E058BCC1727,0000382579FCEE70,14EB68CE3C130309,1174C34782DEB4C3,9B72BCCF2CED6AEC,ACDDBB069D52B00B,6DE2572F11470AAA,40648DC01AFC976C,49462D3AE4BE57CC,10B8060823F6CA78,4FC0D80612D97CA1,186902F98B3DB6A9,430711F04F3EBF2B,00000A353BB09FC3,B894D894B5AF85FD,3FBBDB9C412B675F,B42E2B86276099CE,7B9DDDE2B89BEE8C,F679EF2C1222ABB4,FA602EE1A79599A5,D8AD6B18BE17ACCF,DD91B3B719514AFE,E7FB2B70293B2143,44685E473974533E,8E1C3108CB2B6D80,00001796C33673F9,10761B39B48FA892,F9262EA62E1C43D9,BB64493BCDA297D4,B9EE037C0966CCBF,59DBE3A4B55133DC,28D21F1279E12FFF,17930634A50C7EF0,CCFBAE06B1B3EAF7,F6A031F9193A1F44,28AFF0A9EA6EAEB2,B8D99A7E37E3A1AA,00002F42C7B55D68,B5F95B22EC2F357A,275C6A777008374C,8EDE4773468873E1,BB0225689442089F,D42FC46D75EF7DC6,F4EDB4D22653BC71,AB488B9F92B60D80,11501A4C5466F31C,DDDB3B755A43B04B,0B488BBB798E928A,814C94E22FE72544,00004E9189340E18,B32354EED92EE5AE,0B3DEF97DE189021,0EBA8B5E68971607,FB75AD35D4D9FD50,90D17AF1CC3C537C,E6B7418FE8B2E444,7B27ACDC7C75CA1A,C3155ABC4F40A33C,4BDCD6B11AD6E6AA,0C14CC81242E2056,4DB1463A38630683,000046B092DDD0FC,E6299E94CFDF2CA0,6D5405B71D5D5745,961D1972BCE6E17C,E437B05584B78CB1,4D86B18BAC0DDAF4,56E500CB560D423A,30FAF5D7B90BE520,514AC849E276256F,75D973C1B028A786,0A7BA09EB95699A8,6E12F80745DD2234,0000458C1E000612,27F1891BED668907,020A14401B466539,68D46B681053D33B,B642DA947AEC35E4,B931695D1D008EEF,51138CD8EEDE13AA,54C3280ECBD06A2E,BA5E7FDE91EECCEF,6CDF413BB09D3FFE,AFC5B80F8A383FC3,E42513058ADF97E4,0000539B3B52414D,BD424541179A7A43,61D55D3218E45287,637A08BC2DA093A3,92ABA002C0ADD6A1,864C807EA0EE09C9,1B50C7C627D14CCB,86F7F8F27C59601F,E868F156C3B49C86,8BB03DBF564696AC,83F5E5F9C05F0371,87590A5C01969EA3,0000363257C838AF,31E7D1E51B921441,CEFEC2704B47DCAC,2BD94B2AFD1F3F0C,B92D71B48B014D5F,C4604AB4367A05FD,4FDE1BBFAA71BCA5,73974E88F9662356,34B26D0C2615116B,E2EF600628DE0D05,A601E1571DBD4756,CE3D593A53E10FD9,00006A812592C53E,8B95FBBDDEBB472A,CC8BD5E7E26F5F85,0A81038BF4F429F2,755037ADD4777704,647E5CED51E5B5DE,8724715C52B81B61,61B7704368BC3C58,A8E5B2A751BD2DAE,F72C225F12D26B1C,D05442663DFC2DF3,43822D46B87DE597,000037D3D9F72D1A,D88BBE8627758ADD,F010D93BD6FF1B30,F59D3F3549F780ED,AAD74B6BE6F94CF0,3BD08ECCA72F0D90,F11C4011C1185C64,D6A21A03CE6B06E1,C0FCFDE4359B6766,E6F26BC7D4C04578,C9C1A06280AF1492,DD69143F8865BA60,00006E84CE8CAFA5,A6CAF83C7F7274D5,B0DB4B9A0FB0BBAA,61A6A285AEEBF972,5CFCFE09863F3234,BA9FC16EE4D1711C,704E760FF48F5CEA,A2DE5656455684D2,C4B4EF40EF2879F5,3CD955D7A4FBA8DB,7AC9DDF8925B222E,F46A6ABB3D003B70,0000582ADE3209BA,51EBA4898436FF1F,43BF843B074D512B,BA2E2FCA88FF7B1C,C358E15948B42509,0003226CB9EA9E70,21D140CF9ECFD7FC,658F1B84AFDC4948,28A76D249556F649,4CC7DC3EF2FAA541,8B985454E7519A60,251304B00003298A,0000639E0273F2FB,6EF2509F651684C1,65D3ADB80789F247,9F4C2394E5B3AA06,14D1D83B7D22B061,1B311F70E755EFE7,A38A198FC9B20135,8171D23172F34000,0CD3EF5648D477C1,4BE167511BC6C7FD,E433C8BC06574600,922CBFC09D402577,00000365792EA09D,3B20C62CAC8F6A69,093B647895F5D153,0D9F3F7E9CFBDCD8,60610040F80BA3C0,772BE9B2374795C2,8CFAE22FAA0E4507,37E16BC62231A8FA,35661B72AD00EC47,7D9A8F87EDC58095,AF677FA1E1262994,D5BA2C456246D72C,000041F7CE129EB9,2D6020D8401FCCA0,4A47A4DF62077696,4A53B205CAAB653C,104F82D15FB7321F,B81F2F59C4F1D5FA,9538B51BC04741D2,3968AA75247B906E,3FDF7AE3ECF22536,CEB6F59C2E3FC1A6,6D4A681C4C50701C,803AA76566F947A8,000049259DA8F3C9,A881D3C202954A8F,05363E9D2E35B44E,816D20E55F8EF219,02AC2F31405D170D,C45275FA072257DC,9DF90AF96CE30915,3D73BFD73C656CA4,F13D26E44DEC83C6,ED4D2D5E523376B0,EBB200E0C815E244,3EE2AD81FF253FF3,00002482BB57C48A,E0DCB7622DC87606,28DECDBE87A77C3F,2F8AA9F03FD3C04A,B0839A16C11E59BC,BE278ECBE2AB7227,ACA537AEEE1B1D90,3B00C6A55272FE01,91C0B08E82286945,5774E1944FA4942A,51AF60807525B6B1,F3560AA33C899C4F,00006574B9C5965A,D95907CB57861C69,A3B79321A89D0BED,B7600C032CD5043B,CB41D4FF0847843C,B7CD518BA4A69DA9,5BCB184E677902B2,F48D5743FF765D21,DB7980EB2356D907,3B23EDC70845AA72,602DD7E8CDAE9DD9,AA1AC5E574AB925A,00006E30430C9D3F,14ABCE70FFFBC334,3E8E7B267252DFA9,AD7254CF265C666A,FB84345540C8B3BA,627E58277B8579FD,CEACF78F769EE8F2,CE3C877DAA203E3F,F9D8DFC5BF15B3C7,EC3AD38CC2063483,355F62F8BA120C5C,917D0DF4F0FF3317,00000817A4C24569,83CB289FAD4B3855,46EC1659AB2F2F65,1741226B89D72185,E772B88C7836441F,C11A5D58B78718F8,E7FC75B6462CB9CD,8E0E450DA41F55F8,5654DE4E0E04A4FC,10E0837C83E80616,2A0E8730C1DEC4D1,2422CE0A7FAD5B06,00004FFA0266CA8B,FAD2B48A201AAB0B,945FDEBCB928D016,37565F591B45710F,F977D173ED282007,137F6C2EACF2B478,4A254EFC3875DB9A,97838C3EDF82F570,EDC03C1768B97147,644635DDD4CCFC2E,38B057E11D9635DC,D8AD38B4EB807B64,00005274CCB735EA,F926006BD6160256,8EFFBC6F3A808BC9,F7829E9181E5B377,D12AE2D3492E341D,E2194B7F33441CE2,24AE58C0EFF30E49,A0DEB829641DA937,EE6610929F62F5BC,21EB1310A783D6F8,4C4F6C25D4847227,1452347D7FC521BC,000036B495920A67,B96486E895E47DC8,B8F69056A0F9E024,791D2F26A8C07E24,338F3DA5DE31E458,E6876CF298F043DA,CC933EC9B7F253FB,B73E23A9586F3C92,7A77421AA7E81882,893E167B971119C9,63FA5A6CCE11B92F,9839F4B5D65BB641,0000282955D7C817,99C610CD4DEDD455,144BFE8FD2FB8654,2D63AD1D7DEEABC7,55D83BBAA19BDF31,BD1B0C279455638B,6D929F5A6100811E,8969D7BCFE81B3B4,62A342A779AD2C86,B09958AB744D7C5B,43FAE660CB43126F,BC38FCF7E9C96B11,000042EE74FDCFD9,EDB5F8A4551AC140,3339D03ED2B4787E,AFAE0BBF1D66902E,E47626F485454813,4B4B5507B6B86C40,6CEE4728E28EE7A2,A5F0231E14547AF9,6794711357C3ED69,B174945197834C9A,76ED55C597A840A9,3D44521C6E7AA54C,00004667C5C49D38,32D16EC252CB80F4,DD2BB936F1F0E4F3,E745C7F8B3CA5F78,1D6511ECEA67B446,33D7D269A4D7ECE3,5C946DAC959A6AB7,8E9E49511AFF2A61,74C5820B4814209B,D54FBEC1021E91D9,C031C47A9E2F4420,13CA0B5E3DD179D0,00002AEA8CA92FA3,D270699BBADD8B0D,4ECA73B5CA57CB7D,DBD3790023FD4E00,371D2E0575D19FE5,07C75F7135627650,3612C6A51DA1A4F7,DD24E177C8C1DC45,33F4AE133BC53DFD,A677551719414604,F0092C6EE8326A6F,53E57A1C82AC65EE,000008DEDE1C43F7,7DE946D5F8CB71EA,06A96473AAFED725,2DF8D27911750A4E,E7935D177AC41287,53B819287D83BFC5,3A0BB0790199095E,73CEC133B5EA85BC,2FB6FCA00377901A,8A234D0D2A72AF95,3B2EA66AB673ABC9,E62BF23BB5B6978A,0000180608B5CB41,F802A2ADAEE8C387,77CDD0170A070E51,E048E9D6EEC0A004,F0D0DA05FA6C6F25,F96AF0F2968598F5,4EE5DBBFCFE07229,E378CFDC7103CACC,8AF7456E68F95F7B,9D007625468DF2E3,8C36288134E64CBA,8ABFB1DCDE134B90,00001E995E79BF6D,C8B8D3BAFAB85010,BB53DDD7BAE3AD2E,D254EEBE9829663A,2CC3BA479371477A,A2CB63897BA6204B,69E197E17440F530,0870442C2E82EC66,E6AAA4339A03DEA7,707A1827F542DF45,B3B44F01570FB4C8,C57C18AB3EE1A8CD,0000537D4E043EA1,33CD9238C3A0021E,D66B4AD1F933E6CF,4AB5D9515892D13C,2C25CCEBE82B8AE7,BF20CE7C29902B3F,3787D99407588214,A7A2B5DBA687D79C,6BC8F6F561D0754D,3D324593D82A23B4,A9B0101132CE473A,3639E5E252020B17,00005E2529C64174,3F5819D15F233167,572AA2C23D8FA829,FCF7545104295238,042E37E9CAC1C1B1,CBDEB90B7AAC682B,BCB3FBC7C2C02A36,3383E1CEDE96C3D0,464589BE3DAD88D3,F4DEFA495C4EB676,3B9D6F7B0FD1A02A,2F42C21E5CC1604B,00006130AE9AA78D,C95148D3A72D3950,E05CBB0719DF5372,CF99CFE813C08EFE,58097A974B691C0A,21D2EC4A5DA23887,B20782DE616F00B3,D6C2B88793AAC54B,C84AC01F44415587,3034F15A69591FB4,6CF1967F4EE45AAA,11AA4871EA42D02B,00006FBED4C457B0,B35888898E996A4E,E8DE779F411EF1D6,1242F46CD3827754,FF740E661D4BB742,00A639CE9644BEC3,76A27FA458A5A89F,268E621EE473F68E,A03B9E3DECBDC828,573D17D235C8A2F5,CF657A1DDDAED03C,58B2EE45F28EED1F,00004C78C3E3A57A,FC5DEB134385262A,137321A3AE8B8B79,9BFAFAE14605B507,E35090D1450D0AAB,54CF2226A2C8BF51,6EEB90F679705EFD,531E950809B812B7,2F2128D053CC4871,8EB07A17AEF0EF42,454DBA1A5DF7380A,3F649A40D62BCAC7,000025BD7D034E8A,571C4F646808EC22,E58583CB930610F6,B43EEC04C9B79FF2,C32271EC0BA411A8,A61AADE5632DEC99,A2CC269310C9E1D9,EBD5D02D76621487,E2EC3D26C678EC3E,7C7FC68B7A4A135B,EC6472CD66C533C8,2FB33F561A5CEB08,00003038BAE28DAE,13B22FA5D925E132,48001D2EC5F9AF25,33025885AA1879B7,A2FB62D474F5E4B8,A92FF4FD12A7C149,95958192AC617027,7281762E21DDA971,30018CEDB85FEF25,84C59107CF6B5550,611B87E5724FA75D,C2232B8E8AF028FE,00006870F8E4B651,0156BF6899FC3D67,DB58540D53FC70D4,EF44A696E2CFC280,757FD1A92AA49145,63371818CA37A2DA,ACBA04C96E819EC5,8C6E9D056339CF93,6965DEB0E339C812,84EA305AA37B49FB,9F0A19B80810DF74,0361634FBEB02639,000023BD0607C756,A54EA6C84C272351,955ED56DE990B4F7,333C40A1FEDDF906,DE442A0832E1A904,C3A86F2F3678D2B0,7117DE86120B7627,78FF93079299D007,672035B2F368140E,2BFED0871984D469,3B73AAF8ED2949A0,7F5902CA3C897907,0000380754365AE4,D5D9B0E3301529F9,BFB24A3CF68968B0,CE032F6457035118,F81DAE5251A98F33,427E6FB487AD263F,2DB4B95CD3935600,B7C8AC6FD6A99F1A,B78D2205E7807E4F,D0526C68A7818CC2,593C15F6EFCB8AA4,E60A039B492B0A3B,000019A7008D98B1,1E0D9CE0EB35A148,5D95460DEAE0D98C,4CD665DA47C18590,D6EAE59372E6ACE4,4E2BD8662376B935,1B74B8BC2EF992E2,01B57677584E29AE,900A06A655CBC598,E708D9E29A544B63,889C74ECBE7A3C95,DC6FE413127C8BEF,000006EB24E0062F,0DA26B25A3826263,F0306AFBBA6BB17A,72DC3FA1B31F6E06,F9C96E3EEE70EB53,ED9C435943706693,EEF2D60D41AED1A9,EE5CC6446C755C6F,99106973AAC74BDE,AC96EDA748EEF2F8,8868F91756B02B3B,FB1EA1349DD97102,00003A6F7271062A,93A62DD53D19FBBE,DE910A3F31F0288C,41D76D49E59435E2,A3FD74535B9BAC5A,3D117B4961065FEF,268D0C42BB6F3E15,9B53B0809C968D8F,B2080A2C8422E024,C493E2A1ECF74617,BD87B18CE0904CFC,558AD31DD875CDEB,0000107974261DD6,FC22B3F8DCB99AD2,6C07E95D898A34DF,C4D054E0CBF1F7B8,01C8C051F085B4F7,D3D2B67EBF90DCAA,BA26CFCD2E4CE4D0,C5D37F2646854CB6,2D63F34DEC2AF2CF,50A232CD79734EC1,1927E85A178FC0B6,F98013D5E56BEC74,00004421FA3860A9,E379E34F0F36034F,F3C995A98F64FA92,C4B56BD0C97FAEC4,C178CF30CE5CB07E,023B8A4D0752CF2E,14BF2E23EBA979A9,2FD37CF17E99F115,F99B15019EF1D154,61A1FED8344F3222,87D442A6E25AF8C4,ACC809C518A49EE8,000069DBADE8DCE8,AC7F0D2D46F4ACDB,41A8BAB06D7A90B8,3756354BEC30FB71,4DFDE4166F204310,6FC4F393551EA596,13C86305671E3AB2,0CC64363F2053DF6,755CC7D634EE8FD1,38E1268BD7CB07AB,BF3409F5DC27071C,5FBBD3808950ACD0,00004C6D14558A52,0A915BF50759403C,FD8967FEDB555410,D211AE98F441ACFA,6E982B7F038D1BB7,A2A2D112912FDE09,699AD521F8201B02,E8AF26F832AE6A7E,3129F11619963969,EBC588C268A35BFE,137895C079D51E45,5C64B683CEEE5D27,00005417EFE08A12,C885108EE36DA684,63C9EEFE28D78741,40E9EECC872DEEF4,B9966F74B72D5E6E,9FA9F78702A8C12D,BA42FE786E730569,34262A1C619DE9B4,074170837E879730,FCD05D6BDCE5100F,99F2762A3911E63A,7593F9D5F9DF611B,000069456EA10FD7,65D8082BE8A6DDE0,8D6FDA5FF215D66F,8D879B24FC6EE762,8C6D78787AD494E0,16283798E33EC40B,05408D4693F7584A,763B54A4DEFB6D7D,A7C5497EC8588A8B,977EF403AAFE4A5F,C98E3E1267DA9E38,283A579E169E7EAE,0000418994B44110,A5A98C12E269390C,35886E9A7267025E,B2BE7FFE7A42501B,6F733E92F6F2836D,8D854ABB08C2FB94,2F9142AEFE740586,E3AFC1870382A508,9140C262D0A3FC74,E5135734CE9745BA,1C0D52C52A5E4736,C8784010094C4348,000018B62B10486C,C34FFBF56FECEC96,69714B21546EF360,06B35CA92AD48E27,00E360E286092569,7AE88B016A854FE2,09306069BFDB82BC,9F6E34A4B5E8B656,F179BB29C0B4552B,EBDC3ABA812570C7,F35B7BAE0FD45503,4264DAC440129B71,0000412396FF5E78,72C3BCC7FFAAABA5,BF4B5067610BA54A,E052CD610763097A,00A9E40238A97009,F8CAD0FB262D63D3,E8CB766B8457C361,481802B2B0B4EE02,122165AC5A076D1A,AF0905782BE9899D,CE07C954999C03D7,D95DDB35D4B1E46B,00003369494C749E,EC914749E0A69182,D93947C5FDF07680,E446AB46BCC5278A,743D463C505D7B11,9BBED06D538C0285,86EAFEC81358CBDA,55FC1C8FD8174BB8,5E052C38007A86E5,44758A8E0E59CE81,5C06BD1E0D53D9D8,1959DBBD80279839,000013F1EDDF540F,134D7B4041475963,961418CE77707BFA,DE64CF449FF7F2EC,E787399876BCFAE4,5556F9F3E8CB7B92,746231113F0F8EB3,F73EAFB5D9898735,4344F4207D042083,8D0860922A701F0B,A20A6F0A95D96967,8F6B7F4415B02B7D,00001CFFBE2E59F1,63B9B042DF8967AB,D8374F10FE7874DA,975C881231753D91,43A6A4058B5D7817,22611DA425F383B3,5071491B4FD04D90,ABA0F6C1FB9DF0C8,742D9E5842DFAE81,94A6E8F9F35ECCE4,EBC1A5C2D209BEFA,1775763DEB21A594,0000186FAE5EC4CA,DA7E37D219B766F6,2286B70FE596E57F,BF9AC727AE9892FC,1CF84663D4B1A2CB,6171E93B4E234C33,1CCFE49508C4FC04,8D26EC830181E917,2C0B42CD74FD9511,20580032D5710F79,CAC4A22070B12145,DE0E05EB75F2736D,000051617E5262CB,787DA59574F72EB9,A2316D49CF70CBF9,6BC3C8C389A8AC3B,38BCE9756E6E46FE,3421C609AD35AE67,DEF3B58653CE516E,D3FE64022DACD2A7,E251D1A4E52DDBDF,26D966F1A526269A,84930EC56826CF74,D3A34FDF70629F4A,0000462A701C6F09,82C52AF7F30787DD,65A2FAF7D2E31C2C,B3157D8FA7D66C1C,6CEE3CE6DD59E341,9289C1D9960169C2,1BB9D5C4F5125FD9,E0E2698AE112A9E8,C53CF33C03A5914E,D3A6121BEB8640C8,0E89987503537340,A3D76F3E5156BBE9,00001C31A5FDD9D6,0BF87D71021756C6,9095560328D965A5,A207B4F08DD35D61,ADD275B6D36035A3,E3F75707C1F489F4,41D2E426419F7085,3AF643EC4726BD2D,16E55E5809CCD12A,C2F72BFDABAD2797,388FED4BB57BD28D,C8F45459C42AC29E,00001A85CA7691F3,49C102587BF9E105,C7CD60A51029DB9F,4BF5FBEFBB17E465,3B63D832970F265F,169D63362612BB09,DEDD0536BAE36B69,7CC662F197797624,8BE00B677E3FEF46,C114F748F6E4E4E2,D47C5D9A52A53EC4,3186D1787D9C76D9,00003E7ADFCC0C8C,EFC2137B0B99BA1D,11E82C9FA5C7F5A9,7600D3924056DECB,50FB442A5BFA7848,59B170D24DCFCDA4,AAA6F523EDC5EFDD,52CD20CACE47C1E9,2573BFA50BE1AC69,30F0D64522F75F5C,1EBAE38A9D112896,191B642698774711,00002B473B3ED783,A24BA842654D56FF,2379678785AA1291,C120742CF1AE9A58,25339FDCA994C734,A0046995816559F9,E645E8CA47209500,FD25405E47D07BD8,7D6DA28E2DEB75F1,2B4480EF2D486CC0,2F8C98E77622A942,E140933ED1594A5C,000020603A5BB484,50D081101305492E,2F043B127AFE178A,42BFC92D955F9ECB,DC21A7A0E23649AE,0ABF7E92A830489E,A361B97D76607818,F91EF83AA1294E0A,B8B8F5352E2D4BC5,B7AD5A8B7F09D20F,CE9B0F8BC584E5C0,DA1263B7E4E6CC78,000063AF5B39BBE9,C1A7BEB24E3E6D5A,CBFC528790F46F49,FDD318B4B6459CB4,AD7A5B3E81091008,FA24102D5653ADD3,D020CA924FE80A26,6554421C7C5A91E4,947F0D01B08DBD6D,DCFCF19D77C32255,09B39C8676C88E7F,1DFA7120DAF47EFB,00000646DCE85EAD,F29C58FF45922112,7C0B050EB3813E2D,DDA259387960AA6B,DF257E8F5279419C,7988BD53C4FBD0C9,1D7DBA822E3DE6E4,BB06252ABCA8E740,B13B6F2A6539541E,708389FAF27F4560,1C631D0CE632A029,123C7A57B07D0809,000021628FEF25E7,092D4C488078CF21,30F9CFE3D175C46B,15358A0C76EE43B3,1AB44E69A9039712,67876149A0806045,B0A2C566F678E06D,986B07F5C0F0DF9D,E23E7CDE916965CA,C1D68EAF122FD51C,CE8BC8F67E4E80E4,0E176B7365ED768F,00005A4694BFAC9F,833DEF87D20F2EB1,39BC8785C70DF66C,222781417D728E31,54B2CC71E9D42AE7,628A51B368BB8E34,55CAE9BA68377935,FA8183510070D8F4,ACFCAD53E3A42941,E1066CE1B6124101,F9A8523E2B690DA8,76C8F0D7595E6E90,00002E6E73457D41,81EFF51E302CD81C,67EB55D87F18E2AF,3782444C2145B4C9,4783D9B1CD6530CB,D50EFF6F21231C80,F4EF1AA61C3652FB,0415CDA015D0BE81,B4A742CA67C5D28B,9438ACCEC51C7097,F25473DDBF53AD27,8E2676AD0894B88D,000056FAA20783B3,29DBA9471C84B54F,DACD9974648C42E3,EA8B451A15AE712E,F01AFBFFBF9F7375,40C961278C95C6D0,0733EAE8AD308D2C,4F838DBDA28D11B6,DA9324D30EC9E9D7,E540DEADFFACEC98,05448CB1549E8A3D,BF6F1D34CAC113BF,000054C712EBC89E,438884E618D70803,F1566103F3B55FD6,14852D790C2B6300,B0991A1407DF23A3,97C3020D9AEBE353,B0B913AE38FC86CD,27CB99C0FAD795CD,AF11CD8B57340AC7,4C6941ED4F90ABE0,85EC0CFCFCA0A2CA,9F625ECCEA10B762,0000541536A11585,BF3106CDAC5C9491,4E17ABA0B4E16D80,14E6B541E9BE799A,1DB30B764F56A507,BDE3A5B8BC20B284,D0F52C065221C7B0,D07D478DC1A7E496,0B8623E106BC5B28,4663BB5E91AD0506,FA878813641E7898,B86D40C4976C103B,00004E30D9D0A8B4,E162A28F1C29A574,366ADF7110365570,81241ED22CEEE215,70713A644085B162,822C53C6EDF0E91A,7B886537E33F37E1,3B2D1393D8BDAB06,EDBDADE32E6D3F03,1B3218F8BAF48547,D515C9A835ADF827,5825DC4945AFE78F,00004EB6A19B88D3,7C61581BE4E250B4,CB1E2BA3E18E6BFC,D941A95EC969682A,1EB6F8014FD56E96,93F99F0A85F4335A,FD687A3670A8EE0D,D5D22AC6D61AB56D,7460C77CE8ED8EE7,7166CD94028F9073,5712E1B602FCEB9A,923ABF4D631E53FA,00004D04365AA5AA,E2EE0A44079F3DB6,054EA4CCB672517C,4250C41795022095,2ED5E54583F570CD,9E907DF26D6C6C56,60278DC458DF0235,4FA6AD45C21149B5,C73ADC83FE0ECDED,AE2C7E9445CD656B,3023C574B1C1CD18,CA2DE0C91CDCA775,00001E8BE56E0A4F,4FB94BE9D7B46AF9,DF78F2A8988710F2,CC4986F0675F4C51,586B9F2E336C15DC,A9A88C3441AE7990,FC446D28A12C5256,00893790114E80CD,A94699BECF02BCF4,1B34BA2E2123D55A,26E688A70A5E2F00,2F587C7BCC3FB374,00000F4C73233E24,62C24448DCC71AF6,CA5312D096D50E0C,9EC18FD9A4162EAA,D872FB7E51712854,B374E8DD4D9E81A3,FB1AD0BA47087686,123A334DBF6AF49A,BE244F1BD1F99E85,1320AE11DD27D7EB,6908F12F31BB4089,FBC71A6E2E971CA2,0000628A658DD501,D24D2D101F8263C9,8A7857A0286318C5,AA6F56A3BFB41491,BA17976C5DA47029,6D008A849EF0D29A,D26572F31AC2E918,1A6BE25DAC89AAFF,9E696AA5FF43884A,BAADE86D76E4D139,E529A373BBD2F1D1,173DE56601D9D80D,00004720FD8E0683,275FC2452FAD07D6,36D2105BA2016DC7,DDE4BF611A55EEF1,EEDCE33C35CDC3F9,22B87CBC89CFF999,47587724491CD3ED,685265705B2416F3,7A04F922DA8E607C,B43599950A8EC958,D11EF637DA1ED5CF,781D9D3E6E6CC838,00002B0ABD00FFB1,F5B71B71F7B352C0,76E1DEEC8476B0DA,3BF9F92A1A14CA54,1EA9688D50FE873D,F444E9430CA46FFF,77271FF7FB6778AF,DAC2A4C0E5F5F4D7,3F96FF69630F8377,DAC1A49A368D2D11,D7046C9B06B759D1,BCF303677A804378,00000606AF5BDC5A,683399F50A201BC1,829E4BCCBBD08660,25C9A6B53124EAFE,A366982923AB14C6,3BB84D9B71ADC79C,775045E7A6239F92,2D65F68DC371AFB2,A0DF339FE0750F1B,647CE1A209C49159,BFA80A26E017D2C1,B39E60A375886DB3,00003236FF00BC94,203784AAB72B4368,A687CB31160FD76B,C13F88DD31E97D5C,B5A48B275E6BE65E,96F99BB1660F2BB4,38F3A061AA27D10D,8834838F34C0AA71,FF43B03DB71B9CCC,7A0FB1DCBAFF291E,0E06BD802188F313,0ECAFC2947C76D5B,000066C98DD30C08,AFF476775CC467A2,98CF8F8B9AEDA4A5,83FE5D0448121CE8,C433CD7BF9523C8C,D2EBB2859BDF71BD,76B3FEA6045EF275,5258DC7FE2B7CA54,5A7FD89D4E64AE0B,2C3024F67996347E,B97074B9379264A5,6A36170FA5D32B8F,00002EEF9826176C,70C3A08869158B20,968D2730DC32585F,4DC7748DDDB33185,468FDB687E86C6DC,E2ACD03427251E4F,9200A5880A6D426D,949451422DE62142,4189D7D703C3E3E8,CF8E1A91266CE1A4,680A7DADC922A85E,9014E5734BD288AC,000015F32AD90706,3B00C5CF3C6FE956,55E94DA0AFC01260,0E3B7F33511AA8AA,55093544D9BE4673,B4BEF7195C730DE2,6AA919BC64053492,8FF26667B78FD3CA,EAA9EFA787F200CE,AF3A0B60FCB6784E,668A2F5DFB2EE22C,97C9ECB28E7B8F22,00001C263F1C6F1D,704F99FED6D529A8,FA0046CE42FE1D40,D8F73F5CF0A1119E,FA3EB66A08E4CD7C,6AB50B5D0FDD644A,FF8FA9EAC506D196,783E6D719E21C45A,F294657F02B4E85E,9D62F0059D867326,F420879B39922B6E,8F65C644AFD106AB,0000481F4CEDDB20,672D3F80863C01ED,5E5D319B05DAD5C5,B8A85D33B6B86AD3,4EADB64C9B6E7A1A,42B0E6C03171700C,0A6B01C7414C7D3C,96BD9D0A9C09A64D,31564F429C1CA96E,FA2561E503A863D4,03A40F91E829CE0D,F9AD0FE35F7D85DB,0000547F900FC0FE,7236016F58972196,5A0D9107A5ED8708,B687834D90CBD220,B8189ABE7779DB35,1FFE46D5F27DEC47,A5EE04C778C60BBF,ECA5A0A92974444B,07829387DF1D76B2,652C858F44E83E99,FAFB9F993B1A84C8,EB34C47924EF133C,000060CEF352961D,4501AF389FC8DDC7,D35AA7CB6CAEFD79,74A184A6C3AC0611,802BA3E8478B7D11,B6865035C88246C9,59EA3EBFCFE17964,20B491457652EAD1,41068C6DA10B0474,4EE44073638A5774,DBF0286ADAE74339,1F0FE2523F7D66E0,0000372088C67233,0DEE0FD37A48C887,59F4253896107659,38508609398B0B43,E6D8A07EE2399752,7DFF7C26DBA41D1D,9B97B96C8BCD5062,6ED1B07E3678A7A5,A7FB97413CB09AAC,30911644AFBE66B2,EF922DD9EE2BF113,F95FB2B8091F7F53,00000A5017E85A9A,93FE27BEEAB12506,DABE4D0E9BEBAFC1,28C30976D9D39B25,276F263BEB8E0CF1,730BF6AE4C9F5050,8A8B15571FB9692E,955214977993BF61,F37A7339880AF55C,A1555E6027E3B7A1,763CFED3F4312DA7,DCE8AB30661E70F1,000008DCD2F8C8CA,AAF98A3D5850CBC4,CE3C0D24C51CF07D,C617A3AA82B4BB2D,E19B79AE0036E960,9797B16C61B9BA71,241BFECFA6C70BED,99E62378E09E83F3,D3F09DE83529EAD0,52AF31F7B986F5E7,2BABC08A2BEE8EB7,712558F75BD2CFCF,000004B6B6AAE615,8FC352E897332EA0,8339C1B9662A48CF,FEDB1BA236804A2A,6E284E978A4B3DAA,F8BFCE1FC68715D1,502B573A5AF25E4F,CEF395AC2889CCE7,7E5E5EF8B28C5C9D,0C76DDC9B89A3144,5E9E829680CAADB2,9997A36BE5F0819C,00005AC0523E6ACB,436855D8B6D180D0,AF8B3821727FC5D3,D807122ADAD66237,492B06F8165F3FFB,7522540FC9DAC620,FF96FD3EEEDB50B0,3FDCE3A4D7B66880,1710652BCCAEAEBD,D203072265AFEA13,3AC98D2EBF6C1410,AC56B3DBBBD0D247,00002DFBDD8BAE64,583FC2F2A7D124C2,FCE257491485D382,BDD3CEA84C8D3F2E,64ACB4B59BFFCBCB,2F86B6CC031400B7,B5A901AD0C1D7DFA,29D2B616F4D2583D,951F1982C60AAB5C,6EF2D8243961BCA7,D43F6D8F8C020969,70E07AECBE16EC9E,00001D01283E3C7E,1E549139C9DB54E2,0D1424A096B74E26,525E449AE284C901,30CCC2BC2E50D71A,AAB6B289E6B9DB17,F3BA1C80DE40C043,05B79264728829B2,ECB9ECF7D2098D3D,8A0803CA72A9A619,79D0AB6365DE01FB,F52FEA66768138E4,000040A1F346DAD4,713F1F8D5455CD5B,36BBE02809A4E7E6,C76E604251713FC5,E6936145593921B9,C6E1A8EFB6BFDA09,52C4D3B7044793BF,931EB521A9912056,E9238A71E1DB45A5,2D7139C6502C942D,2E0D205664630468,6720286566AE5F08,00000DB4948D0158,00A32E21A43D2CBC,627DEF9D9C203ACB,98D3185090DF2183,E04C362BA47B348E,DDA5F5080B80255F,DE736D79CF0F1843,4E965A4248853055,69FF9983CCA85275,0A061EFAD2B3446F,B23C923D865224D8,354CDF3A57AEDECE,00003C785847BC70,90385416B01AEA48,DFFE3D554DDEA4DA,A780667E05486C90,CB078589825246C9,978CD9FD291F99B2,2244D7A14756CE1E,20D6F73BE501C9B3,9D8E35ECCAD0D919,72A47BDB73378B00,466FCBD4C8564D5A,A38910F5ECA3BAEE,0000277EB9DC1C2D,5E25E669FDA6B728,7DBB7EB476A0F726,E15962CF83DFB975,FA58C375F75AC8F7,63B8EFEA9AFE234A,EAC49F98AE0D6C45,1A65E301468BA378,1EF398AF66E2B34B,4927BA123A8E45D3,5C7C8A1A7E25D002,A59BB31EA09BE172,000018C2E3DBF8D7,873837CBD6DCE0AC,7B5811F14E81EFE3,4B52A3F205DA400E,20E5D293F88FD3A2,169C604185735CA6,CA820AF4DDEC0A6F,D38879D69404E802,E0BEE812BEC87FE1,87565FE864608771,26474EB058746B62,0309F3A24B124C9D,0000150C74822011,81B5DE654B2CF027,7581537EB9B7F373,7748E5AD76CCB131,9793AAD2493EBE06,681EEA79200F14F4,B31A9657D981CC60,6C3EFC847C6B1C84,78E15C90B7500E78,765A3EC6EA45F14E,C6474059122BE4E4,A86BCDB5A53C4411,000015CF77FB4FA5,40F85AD5E3B76AF1,7AB777F1BE1A9E80,03DCC9DB7922301D,A3777C740A6CA930,2E05A596D494820C,5AB442E10C23BE71,C60786D22000AF9A,A06FEAB09C8124E9,3EF23C4ABC6F4AE8,0BDA5ED6D281828C,8DD9EA9718223A4B,000018D1D9DAEAA2,24CC1DE3BC5FA190,FBBCBEA2A21701EB,F981B7E5C9C41614,CC6C87EE869CF81C,19808F8940BE707E,26E2DB2A0AF50D45,B367E9BAA91B6F70,6224069A958195CC,F01772C7E68B5698,FC181F19879362AA,EBA39141D8BFE496,00005DC8721CA010,0B03CDDE4E92BA39,2A5E085F823A492F,115EB4A610225F2B,6EDF1E786AF2DCF3,22FBA2F8187DB0DA,37A4A6AA1C7F6E3B,529F854F7C0E33C7,A091A58C8F54957E,7FF0F2EEE318C31A,59A9C6DB626F8458,E83902BDC1841624,00001665EFA7E43C,A79B51CC0FF8DC5B,33BBC14A9D505315,8705BD05BEF8F76F,05A01E3701AA1AEF,687216CE1B4D4F5E,E6F56D2B7B5E1F94,804B53B4EC77DE89,2A2ADFFDAAEC82E1,87366ED4F8F1B0FB,822F3A1AA307EA95,167B37B766B19841,000004EE6D77ED6F,B4E79B2C7118E0B7,092AF4E4A556EB62,899F72D3AB84E2A6,D027ABF5D91A7F0B,FEBFFD4664436702,B8AC11B6DC3860AD,C374D9ACEB3FB2AA,D60C87E2D6820484,A735586B770205B0,8970639AB5773880,515CA28C7D74C119,0000091BE9D9EF06,2DD3EA6F71F662D0,4E08197F14342A0F,F61F7E0D22FB6805,0DA273CEB1CC03C7,B803A52B569A08F0,EB53EC4A44237D70,5515E3BDBD5B1486,61D12EA2ECE74072,92D4FB34653492FE,8A4EA9194FBC4B16,CEBC9E26D7BEA693,00005B744983A2E9,E0C7F89BAC9CCC54,925F08B406C20C2E,11264B100AFB9387,95CA7146016E7413,61AC9B06B3FEEED3,3EB36EFD235623EF,FB658D53B7A37EE7,EC675BAEC68D1757,4F7BAC4A91142118,6F21E81D1C951544,36B2F6589688CBF7,00003C09FFB2A1EF,8E0CE13D65460960,132DF80092209111,7BA420AF4171D806,5A99B01CAF6761FE,0D81A08BCC23FEDD,038BEF4CF5CCC2A0,7ADC6782B461CC8E,6FA8B7067A9DA4E0,10517CD5AF5F8DA4,55E7DB2E608D697D,72DF1EE52B833F18,000038856FA8607A,F7B396E138B2BF8A,A27D8CD57EBE7707,47251527E0526802,F428DF3C092F5924,037F8AE4F4213B5B,0CCD2973FAA5FE96,C2CDC57502C73C35,033E497D6065B5FB,F2A2B0EBF88D9A03,2227D986EDDFFD2F,DE83C9FFB0E94444,00005E1FB4D992D7,178B1BDDDED9B017,FC54783737780B6D,05F2D243CAD7DDE5,DEF8645D377C57F2,E187689EDDD36F61,00A1EC2B20AA6872,4FD8226F64A5242F,E252E535EDE7C614,290C106B09E61188,A43C771827B7B6BF,60A47ADB319EC5D0,00003046875DC4B8,5483B5F8A29816A6,E2D5E2001AE0348C,710822BAA2E918AD,1B594E850B8282BD,A48DD30727D26E13,F81C7061ED966A31,83E0C92D108A375A,C86941A2BB444002,48A31D7A04A84D79,AE49DAE0A64EE1DD,4072750007DF17F6,00006020C67EABA4,9485AB2F6AB1E611,F28F12BD64DCE521,FDCCCE9488CF5FA4,B557BA8763D624D0,BFC69F34FDDD2160,BDCB69A51628B108,6623A545D18F732D,04CCFA5F43659E03,6DCCB6E00E8A2902,6009474BBF200CD8,5A4EFB9C181F77A8,0000046D9B927CC2,9E1BA76756A12139,3A2AF57626909400,845F2D541745111F,F7A972D4D4436C87,115A8A70FE286E0B,D959D6C3F43C68AC,B7604D056B759A34,647499B12E580FDC,DC3EE51E75913F34,7E0988D7CDE04E3A,E47754B2696BE6B4,00004FD53401F0C5,C9B5442107B4748E,A5277D5761B76E81,B72BB20DF0DB31BF,7513A64001C4ED45,D13331711E311DA4,D39D4FFA27D50829,BFC5B71DB13ACF4C,FE7A6C08A3D15359,FCE413D709D86A3A,0C806ABE00054AEC,329ADB466E40F306,00005B44CA24AA83,1E0B710450394AA7,9814E3DFC92FB44C,3C344932A1F1C1D4,B7A3EBA25AC86BDA,9E24E202A46EE4E3,A7E16ADB8143F75A,44E3E803C9E60745,1AE90A28AAE38CC3,3F0DBA14645B8C5B,D2E7226EA9E26FC7,D5AF9BD67FCBB208,00006EAE4E3B7FDB,B686C6E47BC4355E,078ACD56442ACBD3,40EEAFAD743D260C,2C7ACF1E7502C4A7,FF2C91203746F225,C364801E3F125878,4737757D4CD3D64C,64B34F9BE373EAFE,2F7F536656414F5F,201A750D191A3108,E4B0D61A4BE49982,00004227A2B849EE,1B51353A513A905D,28B75332E7106C03,5ED644CD081DD1F1,B832A45F4FE116EF,06CF21048524246B,D298FA50192C2E05,523E0A7251E9CEDC,099DB15DDC8CB550,CF98790FB0186486,DBF307FC313FAF79,1CCCA3FC17B8045C,000066924DEBE622,80BC92E09AC85DBD,716373C62020E672,9FCB3524A45BECD4,47B4BCC5805FB509,64ED5B220B979C69,D4B618519EF143B5,4E63F9CF31819BBA,5F49C23E2249E4DA,F63671586CA257AB,1D6A41064D2CD8DC,BB91A4AED54A261C,00006E2A07A699C7,B2F7DEBDC34C77C4,ADE69119F37155FD,9A05DF91F1957868,7B92B34085514C05,0C19F292398D8985,CBD4F86A7A32F9A6,4E9E9D41F35E5D0E,A7B79466B481A0BE,5C4FB47E2C082AFD,EFE864F05AB00646,633E63D4C9E60045,00003E819083675D,39794FE2C58753F0,1619A45E4B181BE4,A4AD504CF0DA91F5,8299E305B895CC36,DBF6330C7C2006C5,8263E047FD6BD470,ECFED56EA564C6CF,5EB6312D71E90135,8CEC8DAD4D020328,B04C806C4B5F38D8,658926BB0D31B336,000045314E16B022,3C7ECD3EF1D91171,B52B0625AFE8056F,648F7B001408020B,82FA1AAA3EE9506D,E169E9FCB99E4031,7216F70BB089CED6,2347B2A4E66818D1,45078C0726CCAC51,85F1E69FA5F93B6A,6F12F9A6FA683D5C,E3D715A3B6E873FC,00000C970BFF5934,A37109899FC2A527,765C2809ECFDA9E0,BB946ECFDA1F78ED,298695735FC3F045,438416D4B69B7509,1572AF2796EEAA17,1100039850ADCAC7,FDE9FE890D2C0A04,2F4EC26EBAF92AE3,2BA585AEA1367E25,7DEA965C741C8570,00004F02C537C380,8004342FBED3F4FC,5577E9159C96FF07,B9E2A34B7899B016,F374B897A6A1CDC6,ABCDC8B687865246,D3777F37D2D84747,F1AC2868DB789324,C221B41083F5EE23,A23B0A170D7B3237,AD7820349512E135,F291AF3DE0B72A03,000060C1EF614070,050FF13FB249322B,42CC11F809D66966,9429432B6F3259DF,0822AB5ADE581895,8F6D8B6DDFDC91C2,F8C868D8BA5D50A1,7EB9823389628DFB,8A2AAD5A73D46896,80114FA80C003061,6D986DFBDFB568B5,8904912867F02943,00006F126D0C29D2,BC8289ED2B72D2FD,D8CF628CFB1B1BD0,66E568C252929296,42488E5036AF9CF9,41EF4577C387F7C1,2AD647BFB53BF403,3178CA3AA4D7BDEA,5B8644D1D19D74A9,1C335F5377BC939F,29D8457F88805E18,7B03C2E4B4AA8BC4,00006C3F49809770,5C71D282CADB92FA,94C3184A09FF2A99,F2833AD7B233BEB4,D27C51E4D80764FF,07454813FBCE5A23,DFA52D8BCCABAFC9,5DB613968D6FD9CE,F84BAFC2A4138C39,5AD5087A3AD5AB09,E2980F11854618AB,F55E531A666C3841,00002DB7F898EEAB,CF19754DAD49C04D,687E8D38C3A33A85,16F9531C81E30CAA,D79905DAE6E51A93,47F27DB37384C160,24B6015D2B044F08,0B2DDBA5894D6681,CBD181A6C3A4E450,A4FE0D54179E60BA,0ECC3F8571E37BE6,EDDA88E5C1E2C8D6,000007A881A16517,F3E539E10716D608,5E29AD2C2B42BFC6,A9632B693423F50C,B0618FEF0D6A92B0,765693BF97AE3FEE,173B9CA58A5E3D81,5C19C97C923405A5,12D62DFAA46706E2,C7558D0B5DE08FDA,46030362C8EF21E9,E9809502B707C384,000065ABBBE31309,A5CD63CEFD2E2069,B3A0EE61971919BB,E5548D9D56D7F318,16EA8AE8A0DE35EA,A92F988C4B5A2E40,6A2CD9B11670E694,680C81A1A874E7AA,7AEC996069DD6821,1D6AB84B453E2346,CEE7B8A21086071C,A23E59DF2152615D,00005315EC6DDEF8,AD9D2E22908E4B4E,B7C5F9B3C44C8BF0,3D0FDFE0BD5CAEA2,BAB715DDEFF428A7,E7F68E17F937578A,3E28EBFC407C72F3,D8E097FDAF2B32DF,94D11AF2CA54A2C4,46F33CE0A1592F31,C4F4F46995D011AB,0EF42684EC90D099,000053735B9BB7B6,741900A3D739DB56,57D130F58D443F1F,0D9585F329E6059B,EA487B1B08EEE667,1D4B5D15BBCEE5C3,DB7AA5BBD51E4307,7C3A2AC64618C914,5AEBE219A4E936E5,D854B8215AC62308,19E911D6180E91DC,1D4CD1EBF0720EB2,000055F6646B5BDD,41A95853FB019BEC,323D8E41F2AECED6,DB6BC28A9138C656,0ABF047D10BD6F31,F9195E4833A05F0E,01CC7ECB0C1209F9,5B79658019D08D00,CD25954A7571466F,D7E1341FA527FE65,F4CD95E4ABB8E797,50555CE470F7556C,000013DA0F48DE9C,9EE12F11DA9FDD52,4E17708C910EFE1C,7CA000CDCDCFF69B,77FD9CB7862B6F8F,D40E0472111E7876,E2E1071EED30BE95,AFE0265FC01CDC5C,05A71DBC19AB8E33,165A67C2C64EE684,3FC0F6A321B88196,E1C5F86AAE4CDB5E,00004092779529D9,E5BEB72E3AFE412F,E9C788623BDDC4A0,6D4E578A4CFB2EC3,36235FBB508400C4,AE649EDADD9A374A,AB8E840186D928C9,90EB0CCE6435ECD8,45A68F2FE5117B21,3A7AEA7226EB2AF5,F819929F379D274D,F7FC3ED3DC532E17,0000199E741B1552,9E3F15CC397A82D3,1C5E35BB51EE1DB3,3497B4A193EEE405,06B4A7906C7B6A28,533E8B6CA4AD8AAB,3E67164A19121092,26BA6F4661AE3EE0,64AAC3B6EDC5E2E3,C1182DF372A29010,65478CB6FC93A224,0710247C42C880CA,000067E13F550BD7,3CEA2277962C931D,7D06C145DFBBCB02,1382326FE815B896,07F7CC7D8D1D24DC,C89B9BDC1E8B836A,218FD35B7E293B3D,35E46EAAD54D51B6,9701331EE4C0FFB2,DB40BEA01C8C2AE8,029007E4DBE6380E,4E71BBF1C24A8B8B,00000014595F4922,1E73D826DACBE061,CFD965ADF8463C7B,0FCE9D8F7A7EE13E,CFB5F54B74991A41,B4A2AE141AF3C1CE,EF8DF533D06DA69C,A61927CDE98347A2,27C60216BD7BE6BC,8A896B02A1A8F117,6AF30282E9CD2DD6,3849C97200BDECBC,00004E7F32647DA1,A4289BA013077054,DA72E4561340C2AE,BC434EF5E80E0024,B892B8DC7355FE05,896C8EE595790F50,DB6A46126C1F2CCF,DA30C1ABB39CFA38,3577C8C4F9DE4FEE,8DA507D0E77C44E1,8ED26B463908567B,2BD28157B3073DD8,000005E6AFC926A0,FB7F2CA5DC9F77AD,F2752FC70AC73FA7,BCAEA18F9001CF9A,C51006C571ECE797,870A4CCCEFA5246B,ED728D1B4E28A51C,1EB0184132562994,3B5BDE9A8B4D998A,ABCCE1CB074593C3,D2F7087CDA7EBC73,273ACC7B4D9EDFE0,000038E04BD743F1,B3F34235E86A4D73,47CF55E20D74C5DF,F1A1B68D66ADF6C8,1D2458433E466F9B,19EDBD2C8EA2D2E4,AAA23EE195747D9A,D40A47D5E85C037E,10219E3FA176317E,102FEAF39696009F,60712B3D0A70CCCD,E6FD354F496A6600,000035FFC6B7AEF9,ADD20203614EE989,A76BA86481617742,D300B9EB9586AEA8,82151C4374333606,4EB29B5F3A68BEF4,37218E5950F865FA,33894F369F9292DB,11FC90EA829E51D2,AA38F79368829311,D5C31F5A927FE8F9,0E849E889927E15C,00006877223F8A30,FBF1998BF687B12D,F137A3D903C58EDB,C76921598D32D225,0CB972EC194C0FF9,1387D4350C1BF167,81B0160AF7FCD221,6FD927BD03A792E3,80AC759816E029C3,F58D119D8ACC57BC,C0F4CA9728A9CB8B,3A456938BE15B28E,000004FB9AA9F184,50896DAB0B5D6A7E,DE58FAC40955FBB2,F6E3C4ECA3D14727,7155568DDE1CBD23,E54F4732EB4DAF3E,98DEADFE38EF39A8,D39150094C2B7660,E0DA6E9264CBB45C,0997DB471D2DB40C,2A303793F6C4D004,CF5D654247931AEC,00002BB399C3288F,6D5ABE9825B90803,F7452BDF267B2646,998C8DB3F18CA7F9,280B17B8D8EF3773,215DB7BE871C75B7,51F2EE7C8BAC5729,C1A983D9EC1C65BB,D709F18301E30CC4,7DE75758D6961713,E1D6052BFB616D30,6A028EFB9A3715A2,00005522DB0BE7E4,A4A9D2A756FE97FE,4667384CA4806BF6,ABC8B8420CA39B16,C6B50941D2D9C6E1,769928DC8160DF42,FA48ABF97E905FAF,363C3D1C95578319,57AA896C040BFC21,155DF5B3920E574B,548130DC4E10EC77,B5D81E7C4E0E3B38,00004AE116D2226D,C5E0F292FE03A092,594221B7B3EE14B1,C85FE1D9E1148597,697EB36A5A7702BC,00F5A0E493C2446E,5E71A12CA3841735,303B88313F3D7365,1B4EB5880E3AE105,D1E135E5AF3983E2,00AC18F99BE79C8C,E0734B4E188E61F0,000014183738C337,387C0945ECC98441,279035A974B4CCA1,227BAED2E38AF908,DBB1DBE7FB51FA27,FBA63BE051492049,6B889C9F9B8DACD7,521C852AE6DC1E18,2FD861A958E074FD,EB1F5EEADCD25C46,7E1C44223579601D,69C41A8060873BF9,000055490B9D7563,E7DB0D6D929D455F,341A8630393504AF,487E28370830833A,ABEE61FC517C51DA,8B56BA1C9358C531,860D2DE657302393,130F827750978C9A,6E9A2E772481EBDD,6506D04A8E543A0C,66E080A42F5C255D,A13D0450491CB7E6,00005267D1F36AEE,4CD15B3470F5F4CE,6C6ADBDC1D761BBC,441332B563B79ACB,D8338F883C0D9AB9,E1AB08C67C1F1EF8,434661E4F53694A1,4A3C1761C3DB51A6,5807CDE35AE60F8E,517B8AAF32E696BA,0A78ABBDBA5E0B5F,F4F826D5AB7136D8,00006E719E128210,84AA4A81EC1A2448,92E373000120C364,32B0ACB7A0651D78,342038E592446035,31306EA29027CCE7,E035D1FABB7C4816,E91F44322D898A05,42F33AAD6DD9CD6B,36DABC0054F0F582,0D458B6757026F8B,2384D516F2321951,000066CF98A4B19C,00411F3CF62E4A09,E4CA8F4D6D2C5EDE,CF4440BD5D313342,A4E75FD4C3614AFF,FA37EABC5D52235E,933D3127957BA124,6B599A3896EAA1B3,FAE71183F02E54D3,7E6902A3FB2F58C5,D1C3A3A8012CA665,40AEF22742AA63EF,000007C9967F4088,C5850F335B617613,9335914164315968,DAB9BB0967989D7F,8F8CDAC5D47E5F7B,6407F9BE68D5CCE9,FD72D9C16AFF31C2,AA2ECCF24B63690A,0648F0F0ED432DE9,EF08A921085059AA,7CE574E5A52CE116,873A4817BDED9D29,0000514831DC9E37,EECBFC9EB2B0A4D6,C916292656CB0508,2F9FBCDF4FB8DD67,9321A5557D5E59D1,A7C3BC488FAD31BB,BB44FEDA6411F8EA,7461D1DFC5545B19,89E735F3F7534773,C858E0221F81FAD5,4CFD1B0091512A06,9188E054C29F9FB6,0000654E350801EF,F35354D24E8D4D05,DA9FCAD7D648C7E8,570D7113E3B9246F,07B2364EDCA78227,FDD25B0EAC52149A,E843AAFFD8D52E8E,7161DA6513E6DFDC,6F3D8C08418AC814,A2731203E0D08870,6B6C7D4BA0845D16,2373831A13D5848D,000020A5197AD4AD,0BCF97BF526059E0,603D3DA59F8CC1FD,A2B6C3A8B31DE70C,AAD653311E277F0E,705E543E1A11E4FD,B9678C8A461FA094,FAB4576CB559925F,C42FBB13729B13AB,78EA4C68B4B9EC9B,71CA8F1C2F348DA5,6A28B10D096EC0B7,00002E5F9795F63E,3463F2A559926B70,DC0E3AC1560F4DB4,2A65C2F4A6A086AA,F68DF9DB38456990,DA84ECF6DD39A4A2,919A7C052B669513,28185B9D602D2ECC,593577A630EEC187,AC7811B3CD237176,460109F6DDDA751A,C488FF0285B7FA2A,000048B7A892AE5C,E6A4FFACBA59844A,BBE3EE5A179F6037,AE0334B0631F9BFB,6BBE392A6117B84F,4C45BA098A413951,5CC0D3B5814CEA79,E51B8D8BF5DC36AE,70F9BC3BFF76C5C0,9CCCED68F8B35755,DC6B3ED8994F23AC,2DFF41BB8861312C,0000258650A95A03,A670361BFC144830,B315F7991AC84145,313A2C8B265428F5,DB4DE6999120FF08,308CEC7C2C0FC69B,045F5372FD162FEB,087B529E531C00F0,3C934B42FF30AB89,DCF60991822C1758,CC791154458F1282,10EBABF56AD06CB3,0000152BAA319C8E,CFBEC572B63C4244,9B0C2A696596A039,DCB6FD1D4A56216E,B50BE9DDF6289AE9,E7C2B23705E4A5AC,CFF8936164E74C52,8EFBB2C3FBA76C9F,9598B4D9402615A3,18776C33F6B9B5E7,5E7CC650322CDFC5,335C321BA13FB474,000047A0475A4620,289451C323490668,4ED414EDD812F10C,EB79E402D46332E9,0DC2204F4EA513F7,9444AEC18B772CC9,35EA884FE826E5BC,7258D441DFEE8474,35887D3BF55144E7,CC892B2D217EFEFD,B25B3950CDA16175,524C13657FEFDB95,0000074FE5AB487A,8EE644109AA23143,9CB46949B49742EA,FB6787911EC3DD33,CB0FF0F4C7522444,B8F6F048B767E7D4,AE03DB9360B8D616,873F4134B8C09ACA,EB25AFE893B9472C,77E60DAADA48D0D5,E071D71041995CD7,FBC284A4D6488313,000038B839D5414D,A6F9E9DCC6E3C171,E3BB8DDE1E9C5692,4208482254B92BFE,045DD73F58B92767,B6DCE836A174ACB0,3C910A3BF65C1732,CBEDC77308BFFD2A,EA382FB291DB64A3,77C5A66BF0EBBBEB,510AC236E05E77B9,04513CC74E04E0DE,0000126538E0A1C0,B44CC504510E87A9,6CBCA50D1AC21829,1E15497592C3B0BE,4CB8E9725579CB59,5D0359A90411FE31,653AA2CEA7A8AA98,DA7FB366C873BFA9,1B95330563F427EF,BDA0C8338CB56415,FFD54091413EF4AB,8B289DBD68DDE274,0000295E6F35C66A,3CAC57EF09D06E7E,00CC6DA4032192A8,16E51DB01B5AAF01,7D1BEB970AA917CA,715055D3FBC812A8,67BA70B600314E64,C144AB30F0086818,CDB32D9EA00F04DF,DD7C537C3D7047AE,CA4FEBBAF103CD4E,62D7F2AACC4B8EF3,00005A96E58F0518,EAF2F6B9F6D6AB2A,8E54031983F630E0,A432587231B1AFF1,78F9BDC8B942223F,7849F57AD69BBB09,730A92CB86B2DF63,FC76B3E5F8BCCBBC,CE4EF5CD74C2C12E,DDC087520933FC89,4844CB545019E77F,984693FD8CFBB698,000012E24D3BD8E7,B84F20CE2A1A78E9,7E9D0639C1ABBB5E,CC6512CDFD1503A7,799FF1E08B0D4474,208F6C5007C3E5E9,D2F74BA1425860E3,C20B66FBADCF2A5A,F76E8F44D6526851,FE097DC8D090B689,D5E8CAC3385A1CBB,A8EF981BA2CBCB87,00000F50D430F265,197829E295ED6028,96D9247BC4D8FA23,5EDA2432782063E1,50651BE325BD99AE,F88960A6F623D7D1,834C875D8E74C9D9,33F0A5B85B342108,F45C6824A3236742,A5B1AC0FADEE9B26,A7DD43E3A77DB9D0,EBA2B07367BBD364,00004FA090E5CF7D,8B23571E24E7861F,8E5AEB6BBD904F37,142077CBE0FD5A11,073E007A3BE1E3F4,34F8060376E07006,A2168548965EA56A,082722E5F5FDED51,AF5C961F6E2F0CA9,2B1F8C856313D18C,795AF76F8EDFA900,31B5F696F575A7FA,000005060DC39A8B,ABA28347EF92570B,D996436EC6CFA5F1,0F2236AF0AD9603D,39B3CBEEE0C4BDF1,BFCEA91F6D38E79E,156F101BDD73A101,B8624DA11824F631,6D9FDBCC7A04EE6F,2DB9BE14BC5F7BAC,6E09EA07BFFDFE6E,67B25C376DA96A17,00003A9BA38CD13B,4E8D1386F7BD6375,7601D4ACD25AB318,2E51FA1FA136F5F2,458A9DC3762023CB,05781E6A31A431C3,906B78C00BEF8F1C,35FDC567E65B9E42,341051521CEEE6D5,FA9693E69ADFC095,9BB0E790FB2F42B2,3E07C21AECBFBBE4,00002AE37CA5A0EC,10BFDF6722208EA9,7ED6C9B04B17F23F,C0DA051E80720756,2368C7A917D32FC1,FE5DE903C48CA209,A60219F303FF66E1,6DBE5FFD95AF87C7,4D6088243A97BA04,313DA956E882C616,ED0434CC8F8B3A7E,399F1273E03F3D39,000026DD7DD2D8AA,D877EDCDE97BD49D,44B0822FD8624C30,F772354634395C44,A100BABF72D7CE09,315BC804AA67EFDE,1090FE80A966F5F7,54C288C3ED42CFE3,E040E6D8597564F3,589F7C92AA320844,E762F8B9C44902AB,67A52C78A8E46CBE,000001FCC7CEAA77,3C42E1E730A702CB,A86D871102ADC9A0,8679F3C40005D00E,99DE6470E088CF08,50AD0BA9CDFC5D10,955C4D2D5DF79D20,7A2F5448467426FF,7D82E0C46E924B6A,18590C3DA1680FB0,E97BD667BCE98ED1,EC6B369DAE30EEB9,00002332AB2EB808,472B2A151C9E7A77,E2851A2543A30516,F13F09772DDF4663,605369A8C273E106,995BC0721AD5E1F2,898EC1D970865408,CD9BCC56E138C6A5,02B84E09610ABCB3,84A8144F7D05F03E,B0DBF2D281ACF3AD,D7467C22F2DF6C14,00001F738D275067,A702E9C735CF79D3,E5C5E1574C7D8B6E,F597A9698E1AB9E4,A65C46FEB867FF76,8DA695B76B1684BF,2CFA7656DA390F34,B08E1C189C24C546,68361CD53469086D,C460213EF1FD0446,8395FE975ADA8364,58483BF8219A37FC,0000005B7E47CE3A,FBB3606E861CA042,7B1DBDEB6A760C53,C9D57814B3CAE849,F647C8213975B64B,3E52F396DD0D1840,E7034BD3876767F7,EAB642DDF293E029,991C5D2BAD8D5BD3,4FDE39A2BF18AB11,B91EEA8D71B60CED,D4CBEC4F058C59B5,000027C8B1031F9F,1642D62AA3B48FAF,E19C374C7492C1B1,C0419FB7259BC4D2,1FD6CE74395C79A9,1FB78A26F151CC86,2F4D12D3E0B616D5,A8EC6BFCD96BDB32,BD4D60F077D5943C,D0C95F628EA6A480,B8F796EB1A989C7F,5F73A1DDDE9C5249,000028B4645BE787,BFEB6E5D7E33AD99,6BDCA04172E26CF8,A38E20EE24770E85,DC5E6D6865638939,2E9A09668D7A5388,68D93D4F77D4613B,0D795CEF010EA5F1,90B58889D4729CBC,6E5ECADA43560C76,B7DBB822DFA30244,D29A692F71C0EF2F,00004B416785ADFF,6032EA4124F5E272,E898CED548123B62,8B8B50B2EB16EAA1,F7682A6288B8A5AF,2C438EE33A127048,250BC992B7BD792D,119C63FE62DB6912,F951DD40C446F3B4,9A8CCDCD10D3762E,A8A531C195F9F62A,A6903454EF4143D0,00003E91C4A344C5,F8CED853D540EE3C,58280B3858D6CAC0,34DD61CB4632F37C,19BB2E4B10BF2EF8,32B32092FE716F89,F79F985288873F2E,F37D66E0007CCA7C,2C4602CE84F7C7B9,13AB3A85B1B64F72,301FF7088EAA0649,4A4BFA94D2256717,00004A3B13D5E5BE,8B70484C7E6F8600,84C259D2C6725A57,ADC1473802CA922E,E3BC74D40CEF851E,FDADF1D158DAD6DA,0D3B11B2250A3695,1F3B19882138CF6B,4E4008E0E1CD5C13,83470B00DDFA1907,7B55221AB8EFA178,8212CD8076B3E4D9,00001163B8FC2B98,15EF61ABF4FC313D,911BB91BA856E957,25DCF3A2962472E7,67824159CA1443B4,68BE64BBE9C1B392,6062F0BB5E38D8F6,4594F5E9B72918CC,194B68A25F97F4A7,B7D9580017CB2922,A0789A47E05AAA78,18C4732D537EB6AA,00003B420B025654,6678692FC5ED7079,39F736C5107FE5B7,B1E17412E299002C,92E7E3B97BEE9462,925A1436E28EF3D1,98242E31F4F04F59,6A07B8FF126E350A,F7BB16F9F758E2B4,A77FF1AECBF79789,99831886E57ACDBA,121CBEE74FD2051B,00003083AF26D360,1586CF6F061F9A8E,81BD939D65C9CFEC,79F8B73F863E28BF,BF089D494F2F5795,2AF740986D1331B5,27BF46D436E28FF2,63F3D33D3282674D,7E8CCB3DD0400C5F,09D83564B8461894,1C8728FA04B460DA,EB2F34F2F7369E4D,00000C017A11BC4D,7E5DBDF634BDC275,F6BB9CE32D763BD7,CA1A15BBED528FBE,0CBB87D1ED0F5B8D,4618A5E05CDB555F,E1B14673104C52DE,584533B11E131697,E4CF16D127DEDD31,20B8B3FF062D408F,97ADB50A92563816,73114D506752707C,0000099EFC526592,17A2AADF5AE5630A,AB7A39F4BF36FA23,F6DDC54743FB9C8A,331208DB4106206C,DE91779389D7AF8A,5730B264030D210F,58F0C3647940DEF9,7F37DCA4C6DD369A,558A3C89743E9FBD,34B495DE8862BCFE,64EA6D61F4A50693,00004497163406BD,5E3E780329279555,B357DF284464F257,DB5DE62B6FFBBE56,1E16D7E44F456D00,C35EA7B312148343,D1DB72A406F017CC,293325824F3B680B,84E4C5C3B6EB6563,FC4E067E9BB22842,6BFA718378CD4D40,F86B13E70BEF82F3,00004ECDCB75E9A5,FB706D0EDAB0D08B,B16E1FFB4D8A7F74,EE0FE9AD12DE9144,833D484421C0C570,3DE4B81C887B9818,4F7FBC5C02AF25DE,1AF13E31ADB47E8C,E35B3C45E5A83E1C,A21F11EF0843A1C5,2F8612FD0D5D0AB6,5BAD4AE55BD4AEE6,0000400C16A2969E,E24C4BCCA8398F71,54B58109DD81B1FA,56D225898689D009,E1F7EF5721B697AA,84D0C7BC707FE093,537C2E520B7F333E,A120E759DB4C4454,1A2F5685798F8506,9B4A525B24FD7EF1,16A44EF623EA3468,7DE826E48F4E6B43,000037E076AA118A,F7EEA3F43ADEA0DE,FFC1BAC859EBE937,173A0289B948CB7D,BF38FB0ADB8FE860,9A71C4B7D7BB6C8D,0315501EA77F8AB6,6EBE40DF0E01D78C,898828F3BC4F2144,20FAF12DB47FC921,46563773BF8DB43B,627CD4024F3AC448,000024F025AE2A26,685CF20B401F7513,AE14DBEF792D5155,34DDFAA33E6224DC,EAE7826FB05A9D00,0D67BBE575EAC0D7,F0B7E75948FC567F,F0FD58316B21BB8A,C988136D191A6298,1E745B0FE3031C02,872BDD3F0F642746,AA3EDE154441049B,00002C7E1C82C11B,547DFD8DE983CA26,BBEB8D07B3DFD2CD,C1AB30F8BFA06353,3EEC0A131622B075,B47F4F049C1A1B74,6C78FC9CF010E18C,69E122800A00DBCC,BE7AF4C199F46B0F,227FCD7B91F33FA3,8AA2EA0F552AEE0D,99617FED3831A279,000045971202061C,6086379375793760,2D0AF24AE145DB6D,6CC1273C4CD5961D,AA0F4995C7BA549D,95ABB0E80983952E,E7F18E9D6BE76773,B8C5AC9A54F29465,7268D1FAC7FBEABA,06A3D06701B2B37B,2A381F189DA863C3,3C134C77949630E4,000036775DFA5435,72539E2E6A87F97B,136535BC3B53A44C,AC97BAF92495E438,0FB617A05A956E7F,7421B2D17554A29D,1882C65628A633A8,D057C529671E3512,40E45722592A1B83,A46814B07FD831F0,4E7BB3DAC6600F91,B04BA183C3D2BC45,0000263E16E23D00,BF82B59E81550519,3D70227B6D17A5AF,E7E6BF61DB322FAC,3CA1A1D5B430583F,4F79CF4C97543B90,0733322B2D6E950C,8AA88265EB3399E5,6FD748DCC1274B4C,E288E0F6302B23D7,9D6E97515699A997,894232EF5A3EBE5B,0000003C2B725394,A8479D7F33C2B499,29790500F286B568,B68041B7F9F9AB3C,52104AE79117C01E,AAD3425A308C394A,2CC0181F9273133B,A75268243AD8CA93,F75026F284D86C29,3B3D6652CC5BDF68,7E1F4B44984E9A6A,62C08F1ACCF2FFA5,000024EE07E51822,29F0235BF25EB126,FC395F8CD1E75D68,4D90B0F0630D79B8,57006E73A199187C,6C92EA3B0DD6DA44,F60EF5427B667BC5,831308F6658917B2,485080DB6D119D32,72B5968247B7E50B,490D70F1735942B3,A11CD26356C03363,000030EF274A37DC,7ED7FEEBAB76090E,F5B198A2ADAB9A12,50608CDE9417842C,21811ABB32B6538C,7B8876F39BA43B93,7867B18DFCDABE42,ABA3FAA2C2F0DB9B,D86D45EFC3E1CB66,8E3696A8B7D952A7,F01C6E57A5163C5B,F930F410A02934DD,00006F30E61C2EF6,8CC4332E3CFB33BE,30160A6AC2C875C0,0D2F89DFBC0E93F4,86A1B3368B088955,4D9FAE99ABAB1DD4,25349C6044C2E134,0453EC0D0DF93D72,B9F2C9C1FF17F864,CD286B71B88FF2D1,BF0A917F32D41FF2,59B4CAF00E165174,000028CDAB2A3F68,6F11246422FDA854,E6BFAB557CB22E41,D01589A01E931685,3431FEAD4B8C172C,EC2DDC859253117A,93EDCF822CC4271D,4E768A226F63D1FE,083CD71E7E9C20BE,E320344295A873A2,499D6635F60BDB12,A0D68CEF7AEA8D8C,00004016D1CACDFD,87738488EEF67918,50D9B35B2A164D67,815BBBA5CD94941A,959E7C6BF9679A98,DEF3317382F81366,96AE205731B2C0A3,B6985F77A65AC01C,934D6D999470BDA4,9B703343AD5EF747,FECB2BF4C2B17BE1,5C7BD3970ACF9B3E,00000E1A7A1B4046,4F5B0F79B17DFE4D,B6444A3F1BAD6724,7F3BDF69EFA3AC85,A7583BE9D59F65B2,C7194CC6DB3DC39D,73DF5187D27A4854,98184EC76231833C,258BB22A834618D2,5EE7347393604336,F5CF60E3F0B19914,6DB07F9C622DF8FC,00004E6D951C4140,E3AD937626C5DF5E,C6282E7AA793FB89,87E9730FC7E78F41,BC4D3DA96CB68ED3,D2FE8E10582A0E43,F6051BFB520AAA3C,0D9D2E43745C8C19,A06D30BB646CCFB3,88588C7E71CE2F6F,B0FFCDB50F0D3DF0,DC876A7E9C9C6AB5,000064C675CB9FF9,2EFA414D25402A9C,C8A04CD45E3EF1A1,817B0BB9661C8E90,FEB7DE0927E12117,708A29932E23E5D9,FC2E5BF83E8D3FFC,904CEBEB70775D6B,F97326B6A689B279,ECBD22712944D576,387AB888B499D909,54CADCD996010188,00004EC5000ADADE,9E7C1763EDC06321,C4CAD4C48609D0F2,83C1ED03AFC38217,90865CBED2EEB4E5,599CDDC717DACBEF,8B49D21AAD5173A6,D3EB9E13F832D8DC,8B6BB01AFB4ED64C,F0BCFB482E58FA54,AE8EC64323B9E5DE,A879ECE0FC7C2ED1,00001EEAF84B2831,CBB9CD5E5EF3F04D,169243B89E64BE6B,5D35FCDD2FF05C46,A6BA810C6381B89D,A0674BD3A6253F87,E0B5B3B695EE0192,61E7EA2DE014A143,8CF325D5365C3379,73F3DF5478BA58E2,C92D616891A038A0,CF4620B51DE7E05A,000037A2D49549E5,4612418F9038A577,AAC27C3CE18F0E7F,C4F81A12568E52C1,C9EF2BBEA55C3C0D,9F4AF286B657A275,BCDAAA2D36FE1E19,B0DAF5491BC5ADC0,D54E78AD7057E384,5671EE766B5B8C2D,E5AEF23C94BD31C4,F4D571955C4D99FA,0000131B575175D6,D5EFFBE82B7D850F,5960DCE6991133CC,1445C790F9A66B20,651BD319C40CEF59,28441943A54A4789,288C5C5753C641DE,D7531AAE7E5135D0,6A10862AA3617EB1,82189260E0652E5B,5CF91AEA513C6D8F,28712D0C95E6CEA1,000024C7B7141D96,30C5D2FF95175DF3,C10905A22EC57052,4C154B259A4D4BCE,C92DEE9C7F217BA8,46338678AF193817,93CC090482E0F108,B28C5E53EEA7FB02,BFA802FCDB419F92,31F3913A8F8D967E,47D19BFFC8A3F361,FD19EECF9BA735F9,0000565D0D02D39F,C01106BF6BE1FE69,6C1760A06B4EBF1C,89F35F78CD14722B,F46DCD55F1F3A0B4,132A1393120A2C9C,1A9C78F348833DB6,548CCF1337940413,281D3808F6A47AAA,36BADC2A76DA769A,1CF70E140B3C44B6,1354B49B1B2AE182,00000D2615EE8D4D,F18D4AF5733274FB,D43E2C402DD8C40D,AF40967E6A8F5851,2643EB5D3655129A,1547CA0865DC5D23,954F5F03A37A9650,5CF554FE06213EC8,4AC549FDBAF05A1C,81A51993885C383F,ED26C8440D7E84FA,FA5E2BECCDEE2328,00004DDCFE6B0137,0D40B3FF4352E488,EB11E94F493E5857,84E2F49941F08F63,8F6D70BD8F64DE7E,8FBF6DC9B166E627,0ED8FFAF14A76798,B6B2A29557CD59BB,A05245FE341DBD8B,AA22749ECDC4545A,444395FA1446D555,F5290A1D1748EF08,000011DB63519A06,EB7ECB570818A01D,A344C34904791ECC,3CAFCB2CD04199C3,9C41F277BD4022BD,A088AE3F30ECC5A2,8FEF79C2E457AB3E,9AF6085CC8D509D8,67FE86B1737FB396,E5878ED3735BA0E9,2B0936AFE26DAF6F,15931CF19C27E89D,000055A95ACC9221,BD997C3942178C3B,F562D350073A227F,5EEA7862DFC69759,A517A896A9B5ED6E,8E61164D047F3E21,C03E57ED11C5E707,25A832B6E7857646,FC0329DBEB3F4989,59FC79BD8D8A260E,0B9B53E0AF6CAA0E,8AF5179D2A703078,00003AE15B0B2DF8,90D3BFDDD891D55B,EF04BF2FCE063306,0F5E34AC8CD04F47,255C08721E83DDBF,9CC62ED85FF58B3C,FC4BF35A334DFA02,5D080A5497D3C8DD,DFE7370EC9772157,C8D912B6AC175107,0D12C2FCD48A4DAF,475894E8D7E759C7,00006627EE36A2DE,3A9A166E8C96C842,D6D2614589ABD165,F1509DADFE4764B5,89B663E51A97C260,FF9D2E3312D82CE3,28530DFC848DB3F6,BC578BE3596E2FBA,8B19A2A4899D29F6,FCCA9FA613656CBE,E3AA4F548B4DAE63,CA98860A4A84CCD0,00004419188C0C58,A5E10CA37333554D,FE9A8F5CD372D90C,938E9A054A6AC042,393D166B051D03BE,A3BAE05BFDBD95AF,8429383EC7EDD427,372C394ED6017E74,2FC8A235C5818224,C2ACFFBB6EE9C346,A64BC8413F8C5A52,E44622577861CB55,0000375BF3F1AD07,19713F146A09990B,96130FA73BB69B02,384850D9674C7C36,E770CAF2D3244C45,2BA3EE1F70B26927,A56B4E26C509E9A9,BC8EC216C62A67B9,BA67C59EB3642BBB,ABB43A99982AD390,7C415AAF339D4461,3A7585D6E615E5B3,0000303B225D2508,D5B0907C4B5F593E,51F732B6D577D6C6,951DCC41C1FC6C91,235DABEC6782BEEC,DE6D3585F971927C,CB636DB38BEFD9A0,1ECCAFD8D170A543,DA5052E44822DA91,5E22288B7CC02C68,59D0EF1A0FEA5D9A,6D277D1A5274D07B,00001F46B73FBB3F,18049F252D9884A1,DD8DCFBE7A866600,7CD310581E502AD3,19D93BF6C8AAA3D7,E0F55F4EDBC05BED,774D5340D3E09CE1,10FF8ED0262A0DC2,48408FB46C599FFB,6C5DD2259E5A4230,3420617F320C4F68,74044F1DC8AA5A98,000046773C375AF7,2535F6776EE036AC,B0299D63C0243368,56C7D0C2873A514A,A5C4A32B9CB34243,7DCBC121CA959C85,3502B519EE32656E,818274616FC355CC,BD40C16B295070BF,058C762986E34445,9B2F56CF4632EDFB,7A93201407C0261B,000021EE44EC115B,E72399B0B4B95A6F,2D53AD915202B59A,7BFA12FA0BEFC017,BA50C3100BE88851,4326BE0B9B301250,EA41382B2EDD3666,E1F8ED58AC31DA91,CE3E78979D296A73,69ACC61A277D36A5,97A10AE4BF12C8D4,8006A9E95480FF87,0000669C5AD61284,5E79F600ACA4893F,7D93914E957AD35E,F5B27EE35A6508B8,5AD83B307032B265,A8CBAE460E686898,72CC53319C1D823C,923A2BED06824BD9,3C447F28127C5748,8FA97773013F261B,ACC42366553E134A,7346AE812E05073A,000031D288131227,19D0C4B297CE5F5B,B8F70170BE168571,770436761452419E,6190CF462A07D4C5,728776AC33ADD605,BBBFE13E0257DA8F,8D263602F4B5F0E7,EB55A5EFF1B59C28,C7036AEA90C224E6,6B5DBE3CA5417ADC,6B3C9A0A7CB01F1A,000016283E654F1F,BD7C0B127E373852,FDBA13E647C97F98,077EAC3AF6BB5421,44AD2B476408F732,A1C875CE3270BD0D,0E8D40AAA3479146,380CA40277B7109A,13C3693CB12E9265,839C35DC0C9D6D62,668C25D12591B546,55CF174E9D59951A,00006197357FEA85,10822D5039569908,E4349914C4FFC623,0CFCDDC9E343EFFC,B9147471C0C86893,EC202E784BD6B876,F5F980C9D12022F1,BC2593D44FB910A9,FA4B226D74CF6BD9,5280A5E7DD447CC1,C5B1C731D5DB249D,4E621C5F351C82B9,000019ACA706990C,B0DE3E2A59C76DB4,51CD494583D6E31E,D977500D63C1D33A,12ABE8E7F3AFAE96,7F7AE5689EED9BF1,A6F3664E346024D6,9D16812169168AB5,F1CF7D47AF2EB37C,B431A9AF7961EC02,70716DF1CB69A074,91FDBA07C085ECDD,00002834C94AEB2E,758519EFF46FAABA,A7D7AA212D10B819,48917BAAB8D9D974,06E02B87F06BF790,2F322D116B545C9F,93936171037D77DB,685298766A230901,6907620CFBDE45D0,B59BAF0454E09B0A,3B7E549E5F1FF521,AC408D7B8EEBAF02,000060C40870E69A,629F886479C8211B,852A260401E39192,7473B26EC1BEBEC1,1F3B3104DB02DF65,78474C311C43BCD0,3A2A4EC9DD25E366,94CB3C5B372041A4,216F925683AE74C7,C24878DEA4AD0B62,D1749F2E51EF704E,D05C704BDBABE34C,000064538E610782,C54CEEA4A4B1C845,95F8FF70288F6626,19E658BF7A4395A4,B3C4C2EBB071A800,83AAAA0C0A0E0E9E,91D9AA3A8E626C2F,50ED9E9D1B9A714F,E4360E1531A2AE4E,B5611987D8389188,E7C707082D4EBDB5,D8459DD69DDA91E1,00005BF0E63457E3,A9A062E4BB5A4DA7,B59E7D7F81CCEE5F,C8C6704B2B68036A,638D856F306B233D,9B4797D30B2FB70C,AE38726D7ACEDA8A,F345F5BB4CC592D5,AF9C3A63178AD86C,02CCE2274B03B1C4,9D3F4544C5503249,6AF4A92BF49648BF,000017D5908145C0,EAE09FD049C28AFB,91E9B97E20539E80,C3FE6C429A5D0972,8EF86C37147EE41A,402B3B4189523467,C6CE4C62F4394E5B,8FE08F75101931EA,40A2C58282C68ECD,2E2DD207B36E6390,6F1FF3822387AC5B,452238CC341FA2FC,000035B9A7C9D90D,FB77A00F63811A72,19574B6D057734DC,C15E7D8D789DD59A,2390DE001465B3D0,9D00E6DC4AF09F7A,DBBA8F06ADB64C42,4904D18F72905D03,A7F0C4DFD99CB4E4,9743BA0B6898CDCA,61A8E6CE1DF5A21E,3D6922E7201AB2BE,00003ACDB6935C84,9B136810F1F5A3F1,6EFF90FF6916C9AE,C9F4A4D8FBFC3066,631D55C9D2FCB88E,310D8A055EDC134A,2D6E355035077315,F00E32201661DE02,2A7F031F4DE36356,ABFEAF5057EDC9AF,F3BBE4C78D7FEEA5,0A0D7975820BDA07,000050F6A40C98E7,E3FE3D1E8F4CAB39,7189CD76E2429216,3C9F04279AEAA03E,8779D6D82273E4A6,6FBE451FA69BCD65,CA1271F48B55B4A1,9DC6A788EF04D4AF,686AB60C1863A443,62B0ECBA75275D79,6FC4F38E5C6F10EE,2A8D8F316F484379,00002564739017D0,C830739DB094F8CB,E6A58A1EB7B02B2D,DB2B6F215A4513D1,BEBF0B31F4AB3682,2967FD042B418F11,B9B56FACCA110A6F,0C236BC13CB02D40,C18D52A5EC5A6361,EE43DB9356915594,D6A1D7D2D2044652,D592472926064AA3,000022210A3A2B19,2393CE7CCB43BBDF,047A1ACEEEF3173A,77DBBE7CBB36DA11,AAFA075481740EF8,1E381447293F2DDC,DE32B24D0B1BBA96,0B70C66CED7A6C3E,2212B23A19142B06,9C15743F7731F165,8EE732BEC8E2C53E,08967F162DB69A44,00001E3005721D44,34AEF3BD75B9295F,AAA6D79E3BE135C6,AD371ABF8CF5A517,D67974F47C328756,6C36DE089B882CD3,184928865515FFAB,F9C77C528E32A16C,541DBF1D98038413,7C760987E81E5064,66AA857DA44D7923,A071A2B6AF6AD644,00003835590BBC42,2A31C7021E25D296,7BA11231CB947579,1DBA0100646A2D88,A3DDED837E9D180C,D262B22F3A0FCC6A,6239BEDAE14F2835,414AFFDDCBE8A03F,FA5DAF0AFA25B0CC,B3A500D5129CAA83,9C12E4A6BBB8E714,0BE192395584E3BC,0000111287DFF286,B48C8D696A64B5F5,09A3840774D2AD9D,C32B2FAB8625412A,C5A1E13EFA4934A6,5F0A96D55DC84DB9,21BB5B38A440D29A,98C9328CFB2BEF02,A1D9CA3088DC4E75,99DEDDED0D089BB8,7FAA1650E773B868,8F1A5486CB054BF9,0000297E560EAEA1,9BBE58254123D131,ACFC0A1179797326,2067FF5BCC4ABFA2,A2FA3389E7AB9DD7,DCAFD0975EA3A800,5BA94A8531887E11,87FCB3739F8451A8,6CDA4F79628663AD,14C5A59BCCAB33DB,B87BF992E1285392,F0AE257D00134050,00000DB374415234,946BA3AB63458ADF,470D5089BD8096A4,8C6779E50A6C2D2D,065D73CFEEDAF76A,87104701CB63DAD7,FF00C9EA313909FF,7C389B40259D2D85,E851BBCB18363471,E7A74C5E69A5C708,2E485BCAB3508CE0,060862B02D81482C,000006DCED04012E,F86F281379F9E0E1,9E0C5ABAB994BF44,3B6C62E5BA1C8CF7,DE7EA6493B7A0089,F39E14FFEF4512D6,50B17AF485324376,12325EB52114E9C4,E60DCF58C9AA842A,98B9F53B2283F97C,34E8E06202F43C55,315B799A3D3D7713,00002DD5246BCD25,62D92B4D62975D27,FC6CDF2C30480383,7991512F438CA8A9,F1D0C9D8EEB22B77,E40E44DE4CA284C4,E6CE1EC3A3BC9A7D,24CC4A332E69C8C4,7BDDA920321E7A03,5DA9C36FFF285F20,5A6402AAF9FADB32,2B09CC640650FBE6,00001ECA55E30177,00F73B8E1862DB4D,76B437C83E3C8125,5D3312FFAE3200CD,353BC3026AE08C09,F10BB65553BA0710,2C0A6AEEEA3AF564,C09299570E695397,9C51BFCA2FA75D82,49848654622A85BF,9C128614AE85288A,97825A1D97845328,00006B7E572F9E5A,2C7CDD39806A7198,B94A90CF2AD66026,3991F67D11444E18,337EF1CB3D0893C5,1BDDC5BD06FAF7FA,11374A53F45FE034,CC27AFE71E1A65E1,96EF2E80904F85AB,5555B6FA9875A508,529EAC40981F46AD,69494D06594AE6A0,00000D20F373BA76,BC2AC1A114D1886C,ECEDBA5FB92064DB,9660C0B9467137BF,55D16CCEB40E4471,62D309C00B413E71,60D25A5C665C9B21,762C4C92FD62DA1C,E950E8ED0B6BF805,9B46F978EDDF4D16,4794DEC50FB5912D,C5A9879F2018D976,000001B47358A6A2,ED6CF023415D0D9D,70943C666F9B6666,4BBF8E45F959A93E,2F783A1A362CAE48,A704B8EFFC3F0F12,881CA18CAE54A725,FC4247466EEB6086,B16853C454C9EF5A,E9EF41C599D5D079,C12B298859539F5A,2CD00808FD247465,000012DE15D618AA,E67603F1DCB613DB,C539AC42ACA1DA3B,FC2040B32B1B092E,FDFEF2B76F3CE7B9,FF07A1A42B36C3EA,6760D7DFA790709D,D884B0CDAD1FAFA8,310F78BB14446F5E,A093D7914422E69D,7CD51B637C2E154A,A798F7FD01706D87,00001EA9FFE785E9,9261FCD1C2EB3FC1,CABCA98ABBD0855C,1163741DA01CCB28,8EFC30DCE3873737,1A44E0DC41A5DF9E,F912462078F10291,1A9AA6BA0FF33DA1,F19A68767202509C,3AEAA51D92BBE244,2C774C095D3BD1BC,C3CE7B91E497B8E7,00005D47832962B8,3F1A31184D79C9E9,804747D85D174C9B,91FBCC2ABEE3E5D1,61E10D0AF280C06B,77BE9412053A8498,3ACF57292E5FEE2D,1B7BC85A07C5C3A9,8491BA5239752809,F1631DC113028825,6B1C1E9365ADCCD1,490F68EB5540ABB3,00004D870C52D0AF,01AA1930D16B2983,3E572DB692413611,0A7F4F63C9CC4934,D524EFAFA9C5D394,1FFA0A46005DF825,62838260FAC44CBC,33FD49C77842488D,B22695A2CBAB83B9,F57FCBE7E07DB22F,34288B094F603510,8AA18D3D0D18EC66,00006BB770FC49C2,FD40AB54D4E5DFEE,BA476C8FB4F9B37B,0D471FC6B1D04863,A9A327595D4E5FBB,3B1382E9472E7A8A,DA7DAB2A2CFF09B5,220F7CF9D6E71E07,995B32E8DC0026BA,8A4E7066F6D17A1B,A2AFA7EB3C101A81,F873BB6BF2F98E6C,00005AF69C349E9B,1D930D4812227EF5,8E9E8342632EEA3C,53DD0B7FDB52EFDB,2E42DCC218B14E89,3D6388DAB4C3688B,FF80F0AD3FD1A56D,31A48B3CF5E28960,D15917FAA30D1853,D78F489F568159A9,13B1384836CA0CFD,2576BC43F9C2879D,0000565930767CF0,3E45C68B0E8FBAC0,F9DB4E32012F5CB3,CFA205721A25456C,47A7770BF33E0028,F24AAA87AFC3F03A,E66CAA2FF41A1161,6C19707869DBFC56,AAF19858FF2BABB3,C9282DCE2A78000D,C5087DFC1CB5481A,B678CE3A0A26E3AC,00006839847B1EF5,814854579718B2B9,565E8A0FC3A98F20,B22102C0274FC7DE,E08EA88D6FBC897A,74F49ECFEC8A4F1B,8597A465BEC47A15,7A4D3489F9A1BD36,D21F42F6CD4205BC,07BD29CE5EE63C63,027C2C471EB2DF23,2AA08A495C69C6AE,00005C5793251F95,F32FDEBED6942399,8D7945872D3E3E2C,7D00ADFB3AAE532B,3C44EE6F8232C073,081D7F1D96A91E88,CA0166500A7363E8,68479F4F5E2C3C2E,2AC46CDB50C0A915,55791F8998D3FAF8,980838DA482889B9,67AAE5A151922566,00001AB030F20918,C0812EB31CCD7F76,CACB044C271AD894,6914B4AEE5D59B36,B596D377FE737EC5,A585DDCD8D474660,B0DC225CC278DB19,468806B4D74A7D1D,D94932532DC2BDA8,C1E72F4861360C71,C3BA1D1B5BF129A2,8446F9EC36AEF7F2,0000621FCD8BD258,E2FD9A4FF8499830,8F7E29CAF3250E65,D09EF7B73B48F307,0439927E8AE7970A,83C7D78CD70E9166,F8C54272787B066C,9A8F449F161B680C,F983C6F255FA3691,752D31E95AF94ABF,8C2AB5EC381345BA,C24010E50C95C190,00001927C639F6D9,DABFC0A295CED4B8,28AF73DC2C6166C5,843F602CB44CC986,44342ACCA132FDF7,BC91E37CC005F32A,B872D8861F7F573C,3BA84391DB24C039,76F9A02439825989,AE531A55CA0E2D63,C0BA650803778662,D735AEBAD65D15D7,00002830E30F1ED0,84500DEE34D56A07,DB1CDB1E0C2BB9BE,E55D7F89F16028F6,8E96492477B95C1F,560AEBBF784C951E,D7D7F7F7722046D9,CE91A7BEFA78BEAC,2D8997E0F2BA3136,238C676E2961706E,BFDBB0DF2FB8B7ED,3FE5553BF9D275F8,00004C5073CEA3CE,8A28C5047DACF6A4,98588497CF3CC8EC,66814759A43B0DC3,AFA7482461B2895D,FF94FE31B3F46E21,B0A36EC3F908A4C2,2AAA1772D38862E9,FF8E671A4478D7E7,F94090D61B297D82,D7082D7E505835E1,6E1CE25E88976E14,000067C6C7B0422B,27C9E287C9A4AC13,F27D5D87B77DFE23,BB03D0474D0D36C3,3799AF0E849B8479,92E34E26B85688A3,213AE029A080E48F,4DC99946CEBBA1B6,6014FA42B7701018,40930A87E4481395,B4F288B5E67648F8,EF1943E9C271D599,00004DA2C3928F9A,98D4751293FB6725,8A8CCB5104F4CD63,B6079A89BAD99992,30F623F6CA6DF3B5,AB6BDC8BB413D63A,71B68068DD3CCD24,A6161F84BB06CE5F,479D8A69352964F4,44980AD8FE225892,4B3F59E409A53D27,D863E3E40EE68DD1,000030B47968902A,36B84A5B34B77E08,42A760B370F0FDAA,EAD35D8C2634FC1E,69D2ED138BA02F2E,0691E3FC29AEE9B6,A9DABD2CFE1817A7,93B6C0AE5EF74883,D5378FD7441E48B3,949A3A5740110558,BBB3758223D4FF4F,97E4C0CB0E5363E4,0000378F0BFDA2FB,147A9438C04F6AC5,2E11A76F6B6D142F,DF6B6AB439681386,CBC5BD9B840FB3EA,99175F963F5AC8CD,BBBA4744C38BE0BC,FF731A51D86CB138,8B1549C7DC7CF617,2CFE8F43C9F26FCD,59817856C680198B,7FB408443EE917F3,000043CBC0C9F918,03450D4DBE62513B,706264EEBE21FB89,F40D09B0750F03FC,2D25BC0E174C3496,52FD3B4C20754CD4,BDCFBE6CCA3D76B4,E678F5D1CFB82B31,1DEF9729A90BE669,408E7CA1BDFAE496,7DB87FCDFE3F5E9A,7AB4BD2100BC197C,00001DAF5D5BBC08,CEA893B621A54362,23DF233BB4AE56D0,C659B3FB77C15963,ECF4B39836AD04DE,F275D5E9C96D00C8,9A603F725E814D83,D3AF496E1480443F,A31BFCD24B8D0453,B7341BB8C6B7C635,2F160D576223D033,094B2FBEC6AF9830,000046F9EABECC92,8BCD9F42506EF97B,FE51DEE45EC63578,26299C8CF84E03B4,CC467E9B998E10F0,85A220696CBF581D,09B3DC631734F2C2,DCE646609EB74D95,2540059B5F7EC23F,11E5B18C258E510D,9C2F52C213D56283,EE1012BF0205C604,00002C7D5E4EEA05,A3D5BAE573C9921B,6BB5EE43E64AEA09,568C939E9F65DDF1,65BEC64B1A3E34C6,83D929F6E51B62FB,A8ACBC1134671C58,F658E4958FA2A057,E52E0762897A8484,B59B07744EE8639A,DAF80F3572A422B6,2A901F02F5F6DD12,00002A8D06299218,3FA34F764E30A0F0,26883CCA4A3C77DB,1F73FFC0474640E6,BE88F2A3244EB7B8,5FF7E756B5812FB7,E99BD29F3EC07776,695494FABB5F90AF,5B44E461365BF905,A6FD942AC8F2B8A6,B3CD44DD9CBB900A,6E0BABEAA7C3EDFF,000045A36A5B51F6,1236231DFE042839,8110EAA6C077C032,9AF612773D74780D,5541AEABDD046BBB,68F2E60F66D7FEEB,3BD0667E51487DC3,A1AB1F19BD9E1B02,62A2407C506255C1,E594B52909DA63F9,093EF8D61ED001EB,1F3CBA140FD4AC6C,000018442BB90FAF,9D482EC9151B9346,6085BF57FF20B77A,810CD319B90279D1,2399C854D62B3E08,3360888943CA0101,69FACC7E43213C81,E2355ABEC7EE8BC6,F4716C1B17EE5B07,AD6A6AD20F8F46C4,8B8F3E2E0C6723AB,6352287DE489B98A,000064DA26CBE686,926240DC99CB31F6,8D84D1889CDAD19C,F4BBBA0D6ACA3D35,69A8B11D42E2990A,7B0AFD362762EACD,DE0A123DF7CE03E2,FA3DEC1DAFB6B1CF,FE4D3BD4D272B5DF,264912A2B19071D5,7FB3A89AC79F2834,F6310E20F8FDC2DE,0000464F6A714FED,20BD93D2B230E4FD,D15E73550BBA18CC,FF78EF242D7B52AD,F9B5751A1602FFC3,A277155952230D0E,6E6412960C395DBE,4C590A08E3122B58,77489318770C2517,C8BCA8149FED0B6A,19A211DB452A12A3,75D8F5645EAAB398,00000FC791F556B8,81E08DDEE928725C,41644B9280D18F4B,40AAF68884EC6807,3ED4744BAB832B37,51CCA26AD022E51D,1F74981CECDEC57E,82418F9231940F38,49D56674674E4CB5,021FED5D3DC4F54F,7F4B43D65DFCABE8,2497CB640BBFC9A5,0000393742549898,32E3C284730296C2,67BF4BBDBF8DD919,F8AC1C1F323C48F7,ACDBAD07F1BEC3E4,5A4223CFCFFD483B,1DE193B45F7AF091,E63BEA6D0CF6DC7E,99A3CBC973ABC954,1372DE745C19986E,2EA5B6B84599506D,A5788BA81BACA164,0000586C1D38EEB1,1ED3D85872040D25,EFA021D990C9C903,5E8869224047642D,891402C179EB7D75,7FC3FE8C537F3160,76CF56536F97A899,9E2759E5702DFBC7,FB8E24E5A00CE24E,FFCD36F5450509BB,571F0F31D07D598E,D542DACD51603745,0000583F5580E9A1,B5D513696DDECC34,F7BFC2BF59BD6909,8CA0EA3E865747DE,264E1F74CD478D7B,A755F2AF6D5477AE,FC71975E4A03D73A,3D6B45F104C6B41F,943DAEF088F75F05,714185D22FA17AFF,228C1D931168BCF9,61548A807F281F76,00000CCC080C6A83,B8715855E98AC21A,6C4915CF89B3FAE2,62BF625BD4A94E84,80949E5F5EA7884E,EFCC50C31A8AA60A,AE01C9E2F280C436,1BBC8BF7DB8A96EB,5822CE5E054C01B1,A0ECC81BDA282420,A673B1184617BFC3,913785D33D449348,00006F8749F727A4,AB108DC4EA7FFD6C,A014B4DCBB9CF4C5,AF5177091C6C8435,E3CFFE5DB4CC5814,B506AD0852515181,5E6143B9195B8904,852636E9B0AF9000,C9FFB48482DB194C,4FFE200DE979D369,AD8D513C94B990FD,703CC79C9046761F,000019121AE9C053,75A25D1AFD50231B,B33652890E867194,FFA5E08B4BAC90D9,11A317984DC4B3DF,9F6E2C9AEA238CFD,6556F8CE3BDD943B,2AF03E5CF12D7E47,73BE02B783CAD90A,B303F490C036D04F,E18BE41E355782B2,E7F845D7344B88EE,00006CB32451C5A7,FB598F22BD077BFE,D287B778F853123E,17A82ED8EBF7B7A8,A2B20F0E873F2114,42E48BBD3E27648C,6A0F1069D84A9753,EED13F9675F12861,B9559DB06D852261,1944D5A6F40EDCB4,2FA2879A648144C2,406445EB61400284,000007E5D3191C14,EFE08C04BAA444D0,2AE2BBC09A91BFB9,18ADCBA2814D7D8B,C07B1DE2052F712D,414E4B5FE61EB1F5,A14B4D6C564E3CBF,E3474ACFA5B897AE,F33656BD18CF9C08,29D1346BEAC06D7F,35925EC2C041A014,BD1D49349B575A40,00006AA5D26126C3,8006FE4604ECAA38,7CCFA16ABC844EB7,99152B3B07002088,2CCE8A98F92C4FF4,6BEF2EDE79BD28BB,F0CB58C22B434F7C,1BC78683CD953220,E958B9E42D0555DD,84113C9C1178C6E1,2446D0EE409F76BB,11233A861F098707,00003CB916A6B5B0,D0053CCE031D46DF,A6C8F84B5ABA6CB0,2B5998DF9EEEB751,CDD879A6A333D65A,2C67801BA138AEE8,8676EDCF638B1B3B,F2CD394B947D800F,3AB45A3C43966770,92F03746FD872432,EE1A89BA923C4D13,0989A9C6F815C23D,0000607ADF8A1361,02FA72A323F3ADD2,F073328CC33EAFA3,701D784A3DC0BBFE,B9AE26AAA4E8C3CF,FA272A966FD440A6,F5191B991D8AA971,84730B09EA656CD0,2D9E662BD698F146,849E526B7831EE08,318196F24058891D,09A5F3FB70CB9139,0000002BEBBF22B6,063F0148228F4982,C9882B835DAFEBC0,C359ED6A2CE7CAF1,1928FF8B52024629,1B9EDA7CE5C7D89F,839071607E80D580,A6F047C3A64F5E1F,75436784248DBFEF,2A15BC3D11560689,1BADF3D0DBEF6846,21A6623498990BF6,00004031F80E2D7B,B7EB9EE07A220F39,5ABF44A330B475FE,18CFB3DA83439218,F94E8223A5735643,811495492F51A6A1,D83ADB4A30B7EE30,34EA18ECE2A94F34,ED7265BB0FE1E439,9FDB3183533CC0BB,FA1C3785405F8441,FA58CA1C600052E1,0000310AE86C83D5,5F8AB2AAC09679BA,200FAE05C6AFFE24,CC30CFBC36A96E39,3B503EDB7F97E335,5118E884D8B1EB57,F3A9E969BD1A631F,BE2F28C769140E6A,A6A4AD357BC59D4A,E791AF55FD758368,524D245D02954EDC,C4505CF281B26B77,000020CF0C42396C,C7B7B1D44B07B312,D3210079A89CB2F3,9BAFBD6B37C45DBF,64411EA1EEECD600,7106FF4001DAD6E2,5334D0CBB5253742,A816BF2B31EFFAE6,5AD390F9A9C8C9A7,51E55F24C3F7BAC8,A4E6AA369812AF19,407B7739217C79F9,000033E221C523DB,C8AF8D5FD38DFD2E,D2B821381C459F8F,F65A73B3D279721F,D1E8E6DD2FF5AC38,4EF0B459984E7E31,772420600B8C3148,252F075899E141E0,2D69E63B614DEA77,DF86CAC3DB16648B,5D2ED8630A821CFF,7F670792E16BBB0E,00005680581AFFEF,FFB833C79F2A6BA2,B15D08F293528405,88D0CF009B6B4C49,762772DF6D3B21BE,24AD800D1AA005F9,F841DCB784F32C2F,DD3EB90E0087080B,CE2D0CC48BB6B242,08AEF45D1EB6A256,70D1C9940E512FE1,2D6CD8EE2FB6AC6A,0000671BDA1103AB,4A840876C5D91DC9,82F558B2B4FB6431,426DDCDDEC8316F3,F3141626AAE0D4EE,F34EB435E63623C1,8D389E8D64BEDB21,60D0123728450912,A71653F6368BD372,FC1311F675E9DD14,D28A6D68A54F0768,651090F761150A7C,00000B5D7F5C3C87,ABEBA07B27A5B54F,CBD05DEE459DF507,05D46EA516CD60ED,24E9F09BEEFB7400,6B2A2BAB89E135E1,6D2C23EBE86B5B06,F8D942A8C8EE2C69,11373FA599F1D87E,D70A0E61BB94009C,5C74475AA5AA33BA,21AA9CD2EA85DCB0,0000072DE6A1BD97,90F35E47988316A7,FB52131873105E1E,7AD8BDF6FD2D898A,EBED3A4B3022DE99,00A4183FE5339DA0,4022A79FFF25CFD5,B63F816FD72B2239,8E1182D6EB26BAD2,91B97AB3947DA01F,44CB3DC862547318,FA109B7DE8945475,000039D660C7F904,C89F448C5F6A794B,B9381E658B3F00E2,E63EE217406C3E83,320436469D1A7BEE,6A5AD4EFC406087A,1E645C50C5CCC4F8,54B616A9718FEE58,F22274C00501753C,F7084021DD9B9E67,DE04BEB1E6BBF932,64C8FA023C6E7395,00000F97CBD08A7F,C4ADA4F0AFAD8BCB,AC9843D6CF413426,FDF4938DBF01D1AE,7AB5E76C81FC33BE,EF207428D99F5D69,3FDDFF85DD408633,3FF84A028452C30C,812229502E176B71,7C910497CD2355A8,C988FA53AB051DC3,225A80A372864929,000024818F31FAB9,1EF50ED643C2E0E9,73AC85C85AB3D559,BB9036754C6F7756,3B5A09EA17FD3738,5EDA462FDBA92463,5B447AC38F552D82,A35465359C4D35EF,2FB709E2EFC01E3E,98D33A37DAE23B38,E9C09A148A1A1038,39E13A0ADF8F759F,000020BA7B5298F1,1A3417DAC043EEA4,508DD262554DD74C,C747A1767A039C5A,449410844D9F5B4C,0C9F2CF0CC975120,3DEA630A94FC8A88,2E3CD011A9135996,9DB0173DD192C8C9,C2F565669816CF12,AD7EF87AE5272236,E2E392C42F1026E9,000002BDCB59FCFC,A4CADDFAB6EF5B2D,1E77E9406F6171BA,3328FF726B8F329B,41908294B6C060B4,9F1F6D6429F62862,4B6CC45E88285C5E,7C2E435FC634122B,6F94850EC37FF482,5AC8B82354F04CFA,31DDBA589F8A4156,CBAE03BDEAE3AFE9,00003D2501AD9F68,0B299EBA3F89BA8B,DF59C15B6A41318C,50D2E52C104A7794,6A92BD268EDBE462,4DDDC94C420BEC1E,0FE18AF6A53C0A68,65D2FB2F9C03A128,E6538F407ED2E13B,03BF50A0C01B39D7,A471E95266AF383D,E13919D37F4F0318,00006391FBB159F8,C4CB8561600714FD,41D83A0DF53910D7,BE274654FBDBEBB5,E0A165302BBA66FA,3706874EEFA41FEC,A9A08B655F078A7D,7BA2FBED9ADE956C,25F8AAF2A5B9D3D0,C68764609835AA16,64D04CE89281F674,E1E37AF14668413D,0000527380B85BFF,F49698C176F7E1B1,50871F39AC31B290,B54DA367A148BA8C,53F3ACA25AE0D9CE,6C0139694D2D5342,8D03C193AE7A6376,FA53A2892155C268,D7DC46CA9945BF6D,1B0AC74C8C49C46B,04164C2E0DAA5BA4,541D81BD28FF95FF,000042C08691DC57,4FA519F1AF0629BF,AD849ADD56780016,5383762A410B3AF1,1971A52D9FD6E4E1,8BE5911E5B1E0590,844FB15320A855CB,8DB760DCC3B5B4CD,B07A04B264046EB1,C6FA51C6E621196A,0001CDC022897E7A,590C5F0E8AC3E78D,00000E416297CC18,DB1C47C693C0D892,8AD3DA75D4A1B596,D724D17FD83C4150,9DD91F1688D173E1,DE310578842A4CC8,BF359FDE21132DF4,EB6296E84B67FEEC,7DC60B498BDA0C51,A1F044807C3D6394,83BCB40C3832A0B7,38033F1B22C9B046,00002F300C4FFFB6,676F5E555D76EE57,67115410E8A6EBB5,76C71FB2CE3FD937,E7612726F5BCE396,1372F357B9B38892,066187AAC611C559,E656CC0BCF827064,9D5CA6933A8DE42E,483C166AE908984D,4512CFC44036EF21,6F74D062D9776771,000006C96AA336B6,5448AADED18A5215,30703AF89DB24F66,91413A5A282DC140,269E4831B7A54FFE,7A046B0F9DFEE1C6,FBF926E638913E9B,D5E54C57650A5029,B35CB49D41BC89D6,95A84D6F4EB672D2,D101A551F7DFF997,566D7857CF0A1C81,00005A8A7712857D,B1C02F8F9DCB2774,D29692DE6EF26D86,81BBEDBA98713B9B,C643E04CA72710BB,BB490565EDDD1BE0,9D2759F474E14A65,CD234D0D92ADD3AD,9C19F6929264086B,20BEF85D78B93AD0,C611915F1362EB76,01545436B94B3DDB,00003DCB48A49158,538227285E6BED5A,B022DA8FB5C2F020,BFB0FD9C6A979916,87585F034A09605B,305A754E63A5BF63,50D3F791A3204023,7BC5BC57BD226AAA,B9A9BF427C86C44A,9DE94CB5EADF7CD0,1CD4B28C897217BB,9820CF18C4C98063,0000057194F1D07B,00B560DF4DFFD333,0841A980AFB8476B,CAF926AC52991A4B,A88E9F83B1CDCC7B,DC7B018F95532C66,3879F05183C8CA14,275E5BC366743362,D8D4F370195FE2AB,A2F1F8273A2E45B4,E0A9B4CDAA114BDA,54B892120B365036,00001373B56FEB07,7442C91DBD97DB0C,852B94D689BD8DEF,106196734FD17E3A,41632BDFD503FE76,0F0F34F4E8C32849,BA6A7683B10C6266,ACB80BFD77F32214,DC394E9FC42D6456,CB677994CDAD2C32,DE97A0BEC0B0DBD6,0E073D932D5BE18D,00005FC728F57832,6A10B8B3A8DEEA9D,0748EE447C7B3D15,12589F79CB3C2E2F,8C92ED8F1A26B6BD,DFEE1AD98D0776F5,A2BC92D91F4935CB,5060CDB2CE31EA3B,B54176E374B4B427,0DACAA29ACCDE8C3,9976408FE5BF67B3,C39871B783834ABA,000057C7CBD079A9,6E6CFCE411005922,29C4716AED526304,685338E54076A2C1,738D9EE000782184,7F6F889F918B6B8F,D88FBE375998B650,B36336C97E9989B6,19C81200FEBE4CAE,FFC6583ABA7B476A,54531095A6E63877,B41122201723FD0B,0000477DFE20E6C5,171184D5973D828F,5560811AA215E52C,22D877A9DF5AE00C,22B76EF96309C967,444BA8BFC96544BF,0A889C6DB1B03FB5,C533B685C8AFA37E,5D32D5C83A92715B,07CB24C55BFB3895,101E4A2AD292C09E,3483EEF093F27354,000012FCC6CEFF23,C670D5B6BFCD0D06,96C8CCBFA9267481,03A1926222F690B1,CF081383F82D77E9,27461B49D49354F7,4C297CD9580E8AFA,E5AD25CEEA7C33B6,B183D691CEBF54CE,C3BB94D7D231DD75,9897E6F756A5BAA9,F21B114EABE6FD83,000032C5098EB6A5,1BA36E583CD343BF,3359A2E1C9272155,50854CBBB3D515E3,4D95CCD1C79EB986,D48E47EAE7A5801F,76BB2901940B90B4,814E35D85B546F21,4A60B7DE3EE7F8CC,8C7C582C8165CF57,15B74C4F1DEAAA1A,0555B80656002997,000011B98723BE74,E46ED8D7FA8679BC,277678EAF6BA78AF,AFDCBB6217F686B8,9CA7ADA3BC5D6C12,CA63AB18349878F6,A39DD866F4CB15EA,327B8F8E4B2895C1,FFC53E50F6CA6D67,BDC3865C939D3DB2,D514643AA29827E8,5C7F96C0AD6013F1,000048EE52E47CE8,E21699E756671A5D,4F57B62614EB53C4,8C3D1E0667800637,3B1EC43D843EBC3B,5ABF6445486AE151,EE91ABDC78F98430,16A8A73598B7B67D,DCD374BCF956C611,5EC35A86327692A9,A52E201B3FD9E228,71E6B1E13B79699A,000064383AED02F2,94522923C267DC1F,0411FCA0CE4094C8,7876DE10E7073237,939BCC6D89387BB4,DD7FAC80C4069FFA,AD7B978950D66053,947FE8464286EB23,A5FDF87650D3280E,EB8184271FFC2D2B,AD05EE84116629B9,D60244211D1CEB24,0000641E278ACCD9,60955CF4EAD0D918,F5D96B5A76A19EEF,610314482541EEEB,487A0CC7061A7A15,6CF97FE75B8746F0,D7A00BFBC4CBBA83,A72E1D378C8DD7BB,6D7A06CD73421952,7BCCC1B2DBB61FCB,5EDD047693CF38CD,BE375DE21337D665,00005C48B3F2DC8D,24B7767663B84553,00390F705DDBF163,9C797D236BA6D335,0C9A23F20DB6B7C3,B81FBB018CB16646,C5B0CF49B53215D0,E8F8D0643160B5B5,6FE6261DF70CE9A1,3EA7E685913413FF,8A40AA856CE8BB96,DB1EB9935E1AFFB3,00000334B803B04E,0B3831916B43E2DA,FAA17DEDD9D78FA8,E6B4D6D99E11D975,8E8AF4F21253A048,B12B92FD7164CB68,37439771C454320C,89EFDF9B6FEBA5B3,2A815A680F7F2914,A4222ED67D796CE4,75C3F325941E7462,2CBA7E36F6BE0E45,00003E0435C4E1C7,631C2A3E3A2FA102,759DE4EC513C7AC4,9125532FEBB8458F,6DC4162795958A91,4C6857DAC90A902B,10E96AF35243BE42,6B225F32FA0C479F,9A18042A16CD02A0,8280ACA73C5F26B9,1F385B8169C981D7,7CAA1573F97A451F,000018525C99FD0C,7B8526FCBFB78D2B,A4DC5695EA539DDE,D651A944E5597FC7,C9D5724404560C22,2E064F0E10E86F7B,90864D5C64A98A49,6D41D60A5D10BA11,2707527BC120F90B,527F5482FFFF9F58,284BA21C3CD76E1C,2D23BCCF8B59A8E0,00000B76BAC63540,5B8D6C18BD550088,0783898905D13FE0,AA8CECFB8A72F7C8,AC455D7E0C45DFE2,87902219281C7A0E,D972A4C43016A36E,7242448D75224165,671846A3910A021F,B527A4BFA8395B28,057569AC44AC25DD,74F8B9F2B0DA3485,000017E679B2D3F0,24133035D2129630,7A91AF0A6DA7F4C6,506280E01B941CA4,794A333B137609DD,0AB867DDB14D97EB,88A0F9175B0BA353,CDFDBC86DA289D26,1AC394419877C961,D2CEE48E454A0AB3,E859BF45F5A77D55,7378FC5CCFCA817A,000008ECDA2DB88A,83315A3555D29294,41B0EA3427E1A268,77DEAD6A96CB9E2C,61AE68B793349256,D228595188DDB085,2B1707D28F1FE4A2,8844AE6173F74097,179AC2154F97EE62,FA054ABC414394BE,EFC2647AB085F7D0,33DFC288D69B584A,00006E6AFBCFCB3E,A7AA2C650545A377,779FA8A1F50103B1,9CE1B8C86FC32B98,F766A8C47327AC64,E3211E8298C48E13,21B5DEBDF32168F6,7E86ED4361A62DB1,26585D9493B1BBE5,E21F7DFC9EF34F8E,ABE34676EEBB5DFC,920E9C10AD3717B9,0000329C64E1C6BC,68E2A239528719BA,B63EEA7E12E7B3A3,0129FAD624FF746D,0276845879B5686F,ED43F3992A616C3D,3DFDEB890E19130E,7F6082DF29FA5BE5,EBC16E8F11E6ECA2,3852C93C298C8BD4,8454ACC890B130CC,FBA0E11A85A026A6,00002631224CFBDA,7B7D325C090D1AA3,825BC42FBD0E6B07,E479359B39725439,EABD1441D5928B5C,D9C8E726A00D8650,C61CB94C7E90CA2F,28EA02FBFCF552ED,35B3E0BC66E17CC8,953E822636095576,FC2D9B6ADCCCE984,14288CDAEECF5541,00001E2D75344583,1F3831496A19D53E,A524F3621A516184,15B30A08B0CDB59D,F076990976491201,61F84DFD4C0C8367,A1522ABDADD00900,8EC673E9F436AD8D,D91C16FC6C78CB6C,BA75EC895A3EC513,5C58E4E057B954C1,CD78893E9FB06F17,00000776D5FEB2A0,F1561E0524DC5433,1FBF9C28C8C470CC,1655213D65692E9E,1920A14CA5E6A6AA,F15710E1309CC332,38E8A354463897C6,BC1055777C03A999,C29237325D48EF76,C1078AF8E897D4E0,369C2D250FA2B18B,E0C1AA21812A93D4,00006987A8899B4B,BED846B6B8A7503D,0E17F2BC35659982,4CEC0DF2E204334F,9FAEBEB8F14C5E7F,0F14BCB3BAC49A3E,4D7BB0CF9C676F36,7E3AD2E35676B727,7D4A1E323502CE76,376EC610461C1BF3,4319D0977FF8C057,9C40F4536FDD2D50,0000034CC38ABEF5,C03A092B92D63EC0,2D93F3BBA09F369C,D8B42BB62F4F1A58,8646A6199615DD9B,7F3083DBFB0C0007,4D343605CF4A6157,BFE2A9B53CE9DFD0,B006E3C435014338,C1969B61ED06BE32,B0C537FF48EAE3C3,3B7E52FC808178B6,0000345A0D7FADBD,1121F2A33C0CCDDA,C70A167D03DAC813,8CAC79A83EC0AAB3,CD04CEED66CB39F1,E0848C099097384D,A827398D31F47076,DED39AEFE975ED25,53A0DE5A49AEBE46,BAC3B4CC10F02CEF,2F5A1288E45216B6,CF72D75E12717498,000001E010A82FE4,F70F61FF46EA2A5D,4BF04037BA8F85DE,8EAAD05019AC1EF9,0B528475AA248A81,2122720928CB2A94,6E4D1676F93CC09F,DFFCCA06DB420015,A3B6CE439CFF3A79,8404A7E7496AB59D,779238BC3A1A8044,FEE5A64F55EC7346,0000446318955901,7BA1C8B2E1537B54,1328BDD6B6E1FC36,8B5A0D2B46338C55,0728CD8FB281707C,937B80F778C7839A,93FB8BF8E544F8AE,7A86655FDB156F08,B4E95A61F7CDE429,FFF80F60A731F977,95F1781E98B085BB,A4D62F1127574A38,000064C480422165,28628CA7076E846B,62216135B262FE19,CDBB2C0EBEC69FBA,80753AC9BD97753F,5ED7C1C13A8A7147,5DDBF5610C9C5DE1,988E1DE3FEE7BACE,160B628047453CC5,CE2D3389161A5B8F,53E11749AABF6121,0A782B228A6762B0,000066FCC5C60C21,653383CA0BCFFF96,F38D25AEE76FC6EB,BE318036073F754D,BB296E8AEEE865FF,78BE77328F5DD616,DCED9C8637FEF9B0,9EDE5C9998747744,60F40F02B145D73F,716AC28C36C5F671,DDB77A7D04C11D26,992D4865BF651A44,00005A9749778743,F8E1D5FE92B900B5,7C1F5584DEF91D9D,2798B2D528EA38CF,7E513CE803E3642B,9EBC0F59D8284EB7,58F1995E3ADFB144,6691DCA3662ED1ED,9C934606D4D93AE5,F334EE5CED5C2C30,66CAA0518089F66B,69213AC98D010F6E,00002CBA91F43EC4,C505B520FB80740C,917EBFAFC170475B,F21FB1772A5BF6D9,213D0560DBD49D16,31B22599E2021D33,7B0DEC2ADE00CD5F,8FDFF6E517564B61,656E860C3EBF0932,75CEBCD029058464,5A175B1B1DC3A28C,45FCC3746F8C4BF7,00004B1A1626F830,66E67ED6A3392996,8B568E7E1A1A5B99,75747900DCD22320,397357128ABB727A,EC2DBAD1D9D80CFB,CFF1B5C788D09317,B6EA03C9CDCF398C,133249A98E51C05E,412F69AE8CF7C20E,590A6153BA9880C2,24FF2C3BD9F23E19,00002D7BC20627A1,4EB32700E4D849F7,6DE336257C31DA90,D1494216A6A4F408,71AAB07269AAE7DC,3684CD8174B07927,662CDC9D0E0335CE,3ED5D216D73D7B6C,E33409A56ECDFA44,906E32DFF56E9C46,2B15DBF1CB3ACE3F,A27E2D17394347AE,0000250E374C7F89,37F816ACAFA5017E,D5B5FD6DFD9A8115,3B3D48681211023D,58767B3B96AD52B2,081FB26F8EAF7158,B3BE3AA5529EF908,78D1CB44995ED89C,4D17125A761FE6BA,5C013ED433E9F018,D9B2C8EEC7366E50,FCCF53A187044F54,000005149DB6871D,50E9F49C31162569,907B8426E3FCD1E3,4779063461846270,E9637968740C01B1,91369F000C5D8206,C2721BEE704547B6,DFFA90BA6C7D2A12,3FB140CCECC4D739,5D9048635E057B77,E3EB39CD6EF9093B,1E10B8F5BA4C9A69,000057ACE1093D75,18478B7EF00C8B48,027549BB4484CC03,EC808B18C07A0B82,E1589E2B4D9AB816,AD0C1B5F7BB61635,5AEAF68DCCBA27F7,B86693DA0348656D,1CFF1E4A15CF418F,B824071F09D9B482,B773788EA998E51E,43C60B416A4ACEF2,0000096DE0CCDD08,FD9CDEF3F892C70C,088D34759CCA569B,9FF8F54BF49D153D,B288BA0B9F016FE5,C9976386994296C9,29B2A4EE6AEF7AB0,60BE4B99E0CC44B6,D6484E6F93EB5EE8,9E346673BD05C14D,E8D0DF65CAE6B2BC,62F6A8090C386B1D,000032DA8D3815C5,ED31F4EA6F6FE6B3,C2C16D97F78C5151,722E242662DEB595,D634F093C9EB942F,12D72E3FA095C445,15D48EF9B2794069,62AE36349FA6ACD3,6501AB6F82F40DA9,E050FC6427BF2D26,284CD2259A2BBED4,B8F7266F847BA8D4,000056C7AFBF9EDC,89F47BBDE6F0A647,33940F01B5D5919E,D9C4C793B1957A9B,DC31FFA79BA2A887,F6B3BC8C3FC4E592,75F91B6777ED82E9,481EB6B1C5A772AA,4A89D3F191840952,8A8FAE5ECF3FD4EC,65EC506630E727A8,C686FE8202256A1C,00004575FB0AFB6C,F3A0AFE2840D240F,7250252240F48715,D036A18F5C9C046B,02804A893E1CCAD8,D5530D8662179324,5E28966EBE73E278,491A3C774CF9A035,AED0B46451F2FE8A,66A20316691AC923,11A95679AAD5B787,B4F2E04A587994C4,0000165D3B9A9A1A,321DED95E5C6BF1A,107C8741893F8E04,5D8FC41A86027E5D,B9CC54760A220962,7FFF48CC5E387070,80EAE7D11C262F37,E9E46833702029B0,1A3B7B97E29C12A2,0EC17BFD909070F6,58E4A0900DB29157,3C8B4CF26969F644,0000068E2B361392,4BBB478FF48D8954,028C730B4B71A3B6,66F760002391AA75,3B1407974A8F734E,6DC6C020434CA050,29EAA28E805A1281,71C32F38BC99CE9C,587588D27955A79E,B601E5B02146D471,B448CBE135FB7466,DE8CA303B40F7951,00006539518217D5,184A2955D7E594B8,14CF23566F85D92D,499025B421EE01A0,8D2B1A8C411E6CDE,C76BEDD6693E5D69,AB50CB259288579F,491C170328BD174A,655CCA47A75D09B8,21EE49203D43B7C9,C90702FA517E1C1B,35BDCD8AF177D8EC,000047969D3861CB,5AA1260B5D083375,38B136D03B1D7DEF,D4B75727965FABA0,EDBF6FAA64DF1078,74320B69FA9E3ABF,5A77192FDDAC4CF2,A802CCF01CEC3C39,30D04D73792E1A28,C5E9D108FD70BBD0,B52660225E529230,27B330D19CA70D9C,00006261EA69CDCB,C6165AD146953474,7E9FF0034496D243,095C2252FD739B24,A2A3565837665D5F,F38264E79138C07B,3645FD1B2720987A,EAA2115520660731,AF2F055E6708D0C2,71413C5CBA2D8497,77688EF56873D983,DD1F4AAF7C824745,0000323FF81DE167,51C20EDFD7E692AD,0C4A09232E8FF776,34D5000EF7670F9E,A68D4A7A68F4A90A,F3CB965C72417D88,E5F61D2FD3E49722,C5A33884EB76C01F,47C368C1283D4596,97B138F73D5F3A02,C1F2A891E02BA3B2,19D184ACFAB3302E,0000552FF7916200,02364D8B724B77E2,A5B3B48CC97B98A9,4BBBDD284F798A66,4A752155A35B54E3,4EA67C737B3F5C96,DA23E5429C5227D2,388FA3E7A77FB5C0,367AA0CF19A8C415,C58358C1590D50AC,4FA09D6720DDC455,B99EBF5824D5455B,00000DA6B7A25660,D3D0F6545EB923DB,B98758C916961F50,5E4DDA6185D56B43,EB8689086115985C,A5D0CC632DA144B2,FBB26DD30F3E3DB7,CA9F8075148C2ED7,FDD7974BC57B551F,C81C864221A9AF4E,B53B8877BE32818A,566744AAAB652919,0000484993A5A758,985A309EAFAF09A3,B50B3F785F3E7653,FEFE1C78BFB68C37,DDB4C91C05ABB697,D2DFF2DCFB700C14,131E8F0ED2770866,A457E155E8369950,9E788BC416F72F21,03E03EBB116E7BC6,78F721808118932C,2EA44BC60A06885E,00000E366972E595,80913A93EDE2D98C,D9131258F5D985BF,6D363C968E27DAD2,31E0EA93FC739650,260362C1DE0F7D22,EB3834A52178BC5B,39182DFA1BAEFB7F,D3529A6D8906A6F1,07A1FC4FC202D231,4A66477EBA5E2103,1E3641B0BA93D0E8,00001ABEBD068942,2F18F535AAF36DD4,AAF7B2E529B002F9,58900F827F7C0F81,6065BAB712965E43,5CE161B1AFDAB44F,7B2C1D052727F3AD,1089194F067CEC5E,EB7C061C20AE5288,5145D1AD18D2BA84,F5B0D3EE1AFD3D42,AA710AA779BE81C6,000053BCF99B8183,8AC3317928964840,1DF39845F46958C2,E7866D4D294810D6,A3AB33736AD4B2E9,74741C73F58B8DF2,5B1722D0D746100E,705B73C2F8375B90,780E92901406608E,D878C237028A2B1B,DE0D96AE4F8354A3,DFEDB56158B7CAC2,000042F5C7829464,C655F9FEACCF6587,B0178D0888759B5E,F770FACA00471FF2,7EA287A39FE8A0ED,1334DBEBB131572D,01AE41EA3CEBCBD5,6BA272457E527138,49F818A8313D2807,A0421E97F883EF38,AD3014876FEDD0EF,898B8BB436E3E068,000016BCCE049493,7CB47FAC0FF02982,050727A9089A8CD3,02EC920FC9851B28,2F42D90E27DCFEEE,C213A2C75B7970DD,DE0057C38D30CF7E,EB78C82BD3C7D2D4,2B43CD5239747CA4,9611F2DEA7873F48,80513A12EFE6B3EF,AF93FF704CA9F545,00005966BE3A8CA6,128F9028CC01CF21,AF9AF75B25985B49,F31ADA39DAA0C42E,0927ED9A7663D9C7,1D3BC60BD6E79D9C,77F884A81A9E246F,F3E1F67DE0191B0A,3E0CCA58E454BD78,F90103378D8667FA,DA0FE01ECEEA6241,291AD0CCC3E51B21,000065C5AE8C4FE7,2EED6282034F8FDD,DA3774AE1A817176,F3369A6344F66575,E43F8CB039D96B67,B71C9CC02930F3BC,058A45E7E217FA11,8882D9FA4E1B75E2,7EFF3DDCE777951E,2435910FD92412FF,D04270D7175863CA,27873586822997B3,000065A7B1F5BA4E,F92F57EEDBB60904,E3810CFBFBADF108,8D68210121FC78B1,1B8689CDA6BF6AE1,863C298A7FB21987,93F8A055151E99E2,BD8D33622D539F07,CD08AC8BC1AD77D0,686C816AA3BBD576,AC434248F11B5448,7E6A77D5904F1DE5,000012947DC916D4,06568B47F1E13618,25634570BD4838EE,7EFDA63EED496452,B9E53ACB5C7CF5CE,12A0955C3359EFCB,E24C410F62785EB5,82D380EDAA289B81,7470D5D2581A91B4,3DCE6A4DC1804BF9,D87FA33A5274E7B5,03530C34267CB636,000016B9C379D684,ACC515B16671B11E,1E0A310B1E93660D,C4AB9A72B83D1C4A,33B40C224DEF0F09,C4AF32D5480308D6,7EB89ACD561E79C3,2E9C1FC2262D2D39,7633D363A6281A95,130D1DA7A34E9AB9,E50432846E91EAF7,D745356E2B9B26A3,00005E77617E10C4,88ED6F4C45A5A1B0,913CC35FF338157D,3E683ADB7CB6CB30,7BC171106992EAF7,78C6D55FB278BE26,AF227F0E9CDD0463,557D9F4413959AE4,35FF09CF5C967791,EF819CBAA7848DBA,156A1FFA11B04CA5,FDDE589A4E37C95E,00000235043491EF,B732E01F83C58142,5569B856A7326EE5,530A673BE581CCEE,FB2C0D28B3A30872,634D930002EAF6E5,550EBB6FB369D58D,FF0240ABAD813B27,1DBAB3F48AAFCF29,EB1C50B916C504A4,B35D1B848B9FDE36,FC5DA3964F611833,000051A40A892F7A,1145E0A75F0F141F,506CDB0BB106F180,3928D3F10D0A8051,1B9868E14FB8406E,B69559F37C2914FF,3273D3A5585B4251,A9A43F7579E51606,7604A8FF1586D03D,5E0F74FD3F5B1F8B,DD485B6541F6E974,6E825FA54767D14D,00002BFBC81D0C15,CD3478391DB34201,2194B29F38707258,D5646E4AEC471A50,F56DD85EE3A0DDFC,5B42F8254E8693B9,F8CB468369E56EE7,19BA2BCE7949FBC5,347A55A61BC8794F,B4A0A0F5F413ED90,7B0C88F76A582085,7FC88F08F2E59F53,00000FE089AA1FDF,5C273DBC65C5D6B0,8539058E52EE9FA6,AD5969FA5C9EB48C,DCB59AA84A6B713B,1B27A68E66369014,7E831ABCB87CB192,6BB32D80322B79D1,03F98727B29BD35E,47ABE96E6F24E227,4AC509ABC682CE48,343977413AA69A94,000056249F817363,BA5EF6C9DDE763D6,61CD7183FB29E330,61C5C8D9BF0774ED,62332D6573ED95A6,8AB7E2973B1BE7B4,DC211C7674BE71F5,8D5B211D83720EF2,0D40A47F299FCD83,B19FB27E1626F687,C0987632E4540B69,E750F1C490697B58,000046D6283E95A2,F2A4805A14D9E369,AAAF35C172E0E56B,5290499A9A3F1BCE,AE2F56C228B524E1,FBDCF6D3FB7EFE55,A8F60AC4E1CBFF7F,63470E180913EC48,35527B7E7BA3B63B,C40BBE904EB38558,FEAD7E071F0CF436,50293C30079BC2D6,00002BB4E36D722A,87E9E1F6DF8032F3,D5B60BD53644143C,13A490405075D5C7,49569EDE4ADA5E32,B1BA1BBDD985AAC4,15EEF13E426E42D4,A98A67C490F53DE0,DB4BFD8B6624B5B0,D4A6556388BCFCE2,DAEC23B042C713CF,5045D2C2832A1C8F,0000321F09D9E944,73EA325BFA4D2F86,BACEA8E47A8AF4E7,61820596EFB046EC,8C09DD278D0019D0,2C766CEC90A12C99,5619FD8AD81AAB45,7527177180556342,9099BE1D1B4B4B37,AEF635CD4A838F64,7487BA848B145697,D7F1B886E8CCF179,0000467E4E4D4B3D,3197FAD53D8E7D5A,4BEBC59E5C80ABC4,C5BBC820E265A94B,5C8BA474388C3ECA,1B1BA8BD754C07B0,F87165A17702C78C,A18C31C48B068044,9E4EA3D1670A0143,37EAA29FDF2B4119,576420980F98BB86,8C3312204596E83B,00005E7A7EB471AA,DF139395BA67D2E7,DF3BA0B2A6290D4F,46A2587171B9497D,E80A053EE6087B21,A4EBC9C6533807EF,3FE1D88612DEB12A,2FAF3DA2F64CF01B,9493D78656834ECE,45C9B3A6175609A9,7690BB6CA79FA829,AB22CBBC32F726DB,0000027F7AE05A08,BA8A0BFD5A8A215D,EBB4EAE6313D833C,12B3E37875738C99,E2DDB4863C3389A5,0B54C805D665D29E,A854749B2AA91452,DD48D7BA93985DC1,917DC1A1F9C9A0C1,68706FC42D5BC8EC,01F259E185CF796A,B7726854BA459D6C,000005177CA8200A,C0EB983C3E7DD206,62D87163EC78EE2C,22CF3BCC176D50AD,6D984B3BF3DA1AB2,1B788822BE972D24,EC31C15786FA0070,3A0D811A740637F7,7681E670862A9B99,C1A5E9691283E654,3C57FC94B4C19AF4,6BC274FA6608D086,00006709605DACA6,74639B7C65DA8C5B,39667F252B40D5D1,1187C3D55581139B,044693FB16A60868,8912B4A1BE0E8B60,C5EFA15335C8C214,FDB49838411D2FAA,60B46C3C29D28646,7D4A589CA38AC046,0B3CD4F6AE09BD00,E9311AD30192B448,00001CFAA0597AE5,425E706426DA4854,C2B062B2C72C3EB3,B42A48F9F37822D6,BFF3BC18EBD8C01B,0AB78477EBC34142,9B65BC0E1506C793,9D3F07CB1202C892,3A2613B79AE43535,C6D99EA9C38D8A20,F1939566D67C3425,758D7932CCF3852F,000029DB452CE2D6,E5DF09DCC3520B55,3D315B91AC83FD37,D34FD9A57EF1CCE0,15D6D8F347B49EF6,993F4CE6E13EA383,5E7937D52364934E,6029960B4AE6C111,A6B0D53A9BE0A2C7,0E44797D76FCA890,21A17A266B5A082D,DB295558899A553B,000063D68EB1E612,8B8C0D9305302154,A31BD6B08FBD2647,A19F67D5A16B2996,9DEAB1BD1125162B,A6B4592C09CE3A3A,988A09CCAADD6AB3,562D05B5A294D6D2,F5AB014676B7AADE,0BA0261A7D6311EA,E4D97A5DA324CD92,AF8920C8F155FCD8,000020B4B3501CED,3AD93552E801D747,B2DB6FCF895715A5,45894C02BF2DF0DE,05ED16AC3AFDEB6A,A82B86CB32FB6C9C,AEFC903551375F49,A517505D0E79B74B,3E0896CA75397D2C,CBA02C92C05C2118,A499DD3CAC18AD48,D6186CD281AC5E86,00006F3627DC07D1,D68494DCDE0B7990,B08791C0A84ECF18,3099183E4AA8D814,355C6156ADF0F4E4,8ACE11620940F565,5F3627F2FEC76B7B,3ED6262A6C9DA758,27117AFFF050C5EA,F54E88EA07F6C1CB,26611887170C963F,AC0977F6AC7A49CE,000018B9FB41433C,56CB305BEBF61706,5CE44726AC7FCCAF,A8E7805128920985,158F194D104594C0,3770B66A34D63F9F,6B288C370F6F7417,808985927F009AA8,BBC6E2B0C668199F,76D0E1C5193C409F,D90F6B3E746F8545,5250F206A5EFD56B,000022F8B17239EC,EBBBC2547990E241,98C6D579E03F92E9,7CB9D005AA0C3C03,17C733EAFED162AD,151FB4F1CC2289E0,7733713BDFF9AB69,339E508C8AAA6CF0,47FDD4E68BAD03FF,B113C0BF45F0F966,3EFD67184C4EE401,5C22D73E4E2333BD,000015CFC773C233,0E61DEF803AC1892,792B276BA4357C5D,35731B6E879ACDF5,BD63A8034994C0A5,896016B1126A5E9A,D450A94B173CC0B5,85741B0A06852D3D,8255C9AAAEA6D4F5,70604842134E8990,23462B7ABDC718D5,08593E0E32F3B2C6,00005A24F01BDB32,B1F0A08E28A0420D,0F0544030237D5CC,C92D682B48A1C842,C026005BCB63AEFE,7D0FD1852EAD418A,7051025FE291FF25,58265B96C12DE7A3,57D4DD22F95FCDBF,0E59E75FA06EF481,58774FF0EA859080,A81762A7BBA8AB04,000028423BAD6D7B,834456D95318B5CE,2D742185EFFC203B,44D8D6E826BC6470,8E4CBDD8EDADBB76,68EF2283F6CC32CB,CA8556C3515047C9,E795DA4009453513,9A0D3224255D37A9,2859DE28FC70FBFF,17B1D3399D5E5E08,80B118176C439786,00004754B14E272E,456D7E3D48BF0C65,69A114A74775527E,6B83FB99276ECE40,4AD86A5A579B25E4,B0245730A4506ED4,E4BCB03F55469928,72980F6F4C2D4344,E7BEED6ADAC301EC,E0CDD9AA528879AF,EF7549B3CB85D759,ABD2974956FE14F4,00002FFA270A914D,1ADD9B53DBA34481,7349BD2E1EBB21D8,5E42F767FF989B19,CAB5A8C6154F4308,4797F287D4FC7F29,CA8E56B927E20102,6DE9CCD7E2EEF2BE,B96FA645C1DA5F9D,94C9724CEE1C0C8C,F1FBA45AEF71981E,0C807EE2F5D70644,00000467DCA41B94,9984842E08F81B6A,E91CB5AADD1BFBCA,8BC5AA332B2151F3,65F0A08377C36453,6C0B7009CEBD802B,54F4901DEA331679,7BEC4D7880E807F5,39A4673822752E6B,1831EC2209624340,9CD5057231790494,6391E83C55C7BAE9,00002E0871B619AA,F2ED50D9B7883F06,FD3C266EB2699BE6,B84C10FC9542F6BC,78166A0C1793ABF7,75A447A3A3F04ACF,859551B5A174F405,9BEA3D1EC7A46865,5EB02C55D01E3CD4,0F2FBA153C47FD19,F4142799F7F4914F,AB0A7818891628C3,00002964DE3132D1,8DDDA45D5928D080,C6CFDBD2F5F3F051,E4AAAC97B405B0D2,20590C29CB8A8F7B,62555AE88F97FE75,33B60FDF25D3B69F,557370D11F880F9E,AF7DD93714D33BED,CCB6DEAAB23F4DEC,0170BC77543507E0,A3DB4DEA264EC5DF,000000E86DB45C0D,FC4C5961CF40A08D,1FFF8FE2429A3360,43C1C295E5711C8F,3916AE7B7CDE031D,62F4DFBC10378434,758F36C27A85DF2E,0E4B875D21BDCC05,BE52DA6A5907A2A6,5660EB73DCA343C5,7DBB8310CE0589BB,B65AE630769C783C,00005A82C9EB7AB8,E88F3E5B692C649C,64BD79ACA1EA851E,2BC3F10051E2A6D3,CC7A34A38F8E1171,9CEA22C01ADF2742,5D8ABE570BF1D955,B5982ABC60740CEC,EC72DB4AAB56D86E,40AAFC0718D5EDBD,B0E14627CE48F1BC,74FD2B93B305D5B0,0000273FD6889FF9,6922DA20C4A61882,0773412C164A4978,B3E2BB3DB955B250,80393DF470C6E8B3,627B6C39F15E6F87,F2221A8740B3184D,9759499EB5C107D0,BC188078D2F70142,A068DD18B43EA902,FEFA1A76B493A9A2,D2C903DEBC0D14E4,00002FCC04B60CEE,551283BD10EF9C10,940D874FC08F881F,831F4E9A0B3B0284,2F3B6FA8B9EF33E7,E49991C1640B6F89,91908E23C93DA3C9,BD4D85F63E7CEA12,5C443642C22C8F36,F0DB75688DC48A35,853402072311AF23,114D80F0752D7B5E,000033EC88B66D06,975DB1ABD5EECDFC,1CB4C4A8C6332C7C,0C510CE5E0D02D46,EECD443634B1A4A6,D6C10E927EC4F9D6,D01ED2685D03CBD2,6B8E009300C57167,0EA48B08F72BD34D,4E5AA8CDB3A2F46F,F9AB249B5DE69A09,B3527B7E894778C6,00003BFDC3770D44,9C2AD240D651B21E,853F0B89000A7CEA,323C574032569734,3ABF5361F9C8D607,6D3AB2C86A43B942,9093CEB149DDA97A,11CE20329A8A5D44,45B9EE736F659846,25BB858A8C316812,0CC9F5B731CC2091,BCD59C29E16CCD35,000008D6D6E2C31F,D2FCA6E5708170A0,E8D0BB4AFBC7803D,403B501A2466AB9E,57A0FA604B555D11,7AB2417991BA3FCA,11008A35AF101BE9,1CC2FEA361D9CBDC,987845756DF14108,4CE995FD00E35B31,158887F6AFADD934,3840B9E2B552FB51,0000517624A45413,0C390F614264AC97,3301C8C1AFCC9768,E77EEF7B69475969,785093CBF04E3523,DCDEC68A1A776046,D412EB796A7B659E,B25A55CD409E5F5D,6CCAED4EBCDD1035,9C4E49EC35AA4F5B,FB97B9820B49AF5C,6236BF3F8D41A12C,00001943C717474E,F968E6CD87D60362,9F21BA7B2116C1EA,D38316991AF43249,16ABB0C25310EC4D,FBB496C77B83D102,DD63BC2B4976EA26,1FE6FDAC4DA8839F,6A85D3816A8A102C,60A9351E6E0AEBF2,A982E7813948CC63,45D68880BEBBF35B,00005210A6069CD8,4C76A3570779CC71,DA11C84D83C71D82,DB9F17EBBD2B7AAB,378266E5144B9BA2,FD38C50EC7BDDF85,F4FEDE87A08D07D1,A4EC49D49CFBF887,FBBF032C14E7CE71,C865CD8D0C825666,E61D4F9E52550F19,6FC4DD5B86500283,00006AE5537C3C90,024F293F3EF94982,3C6CF63ACF1947BF,16A529B219AF602D,D688C00D038C3FE2,DFDB5C5979A5D3E6,4ACA06F947B26162,F2B00A039F6B1BAD,1CD9F5DCA20A87E2,D9020DCAE021B8D0,390F001F510B80C1,E85DE1BE487013A9,00002C8E80651CB7,A383DECAB1D0AE53,8D5AB7B4D7E7D1C9,0F5CE8D6BC9239BC,3AF777BFD2D305BF,B924B7E70A4E2087,0A8C28D06DC1D23C,8324405C4BD391D2,31291E7A98D6AE50,155772163F0D71B5,2970202D176A8BDC,23E28C10179CC08C,00003365B0F3BF60,13F3889059D45CB3,E30D9CA1576C131B,570D43AA7566955C,60EF72BF7798A3E9,FF5F14DF701FE889,7F529A4A59727E04,3669383318CFFA4E,EAB717B175023565,AD4FCC97C9601CDA,51AE645FAE421359,C9F4E3E3096E6026,00005CF360553114,1B5199C74C597A50,552B914DCA449D08,0678512ABBA23837,A72366035211A928,72F388F4F89FC225,30325DB1570490D0,56282812C2F6E7D8,0E6F22BA4A9B73CD,86ED6D1722339973,1B29269F65330990,B14C2A26B7D2934B,00005CC88F69E06E,AF39FAD89125946C,C02AF2797BE52050,1581FF58A9AA433F,BA36F0C22157FB0E,AD103DAA2B5996EC,B821A6912CB9804D,FEBA0ACF10320E22,2209D702B0C30CE6,42EDF0311A8D5083,E88BDCC652E5C947,E203F734ECE0C1BC,00006BAFE4D92403,1229A2531F723F9F,922A03FCE2A70C10,F55063F015874852,4B7EC51D4C56F452,C2BE74A772794C1B,6DB5E985E518DD85,C1FBB5EE87F7B127,F62581E6B84DF0CC,091BCA618A30C7C9,519C22F9B42939BA,E9D2D22A23D53B56,000047028E56934D,5A70592A4AFEAD41,1578A71CDC842282,654F677BB4D15040,506377D771A98519,699A32BC2A1FD6B7,8503EBBAB3B43D50,938241AD6525E68E,7E0ED00FA82DBE1E,9383E77729108C71,47DFF1A7EA467124,3F1B919F66439AAE,0000678E896002A5,951D6B3A52D88C72,399334D5D61F512B,4FA773B4357D2AC2,D60AEEE030141078,0D62F56131869AC5,FA78770128AE6C76,BADA7F387F770986,00C68E23B54FE265,8081D9B1FD32B589,A19FF9C18517C440,F1FC84C82310C1B7,00002A712E8C78C7,973663E7444D2B8F,97936D39882D32CD,44F9552E3A656A95,4E6C4191D7719469,048939D0B989D95D,CF27A18C5D385250,0C2A1C06F8FE65CF,77EB1D4F0A10FEC3,62C602864BEC44CD,17F922BC9F152306,5DC04D1964452253,00002F8254BD37AF,EF38427363E699BD,3C25086E80CB1E5E,8E660EB3F99AFFD4,A9BB84ABFE2C91C8,2A05D5CF95463974,CF19998D8F857FAD,2940A52DBA4793A4,E6E101B646D2EF33,BEEDF4F05553CA30,B5EB8D4A1E4A2F57,7BA2AB20A8AE9B3B,00006EB4FFD4893E,424A296E20870DF0,E87080BD9997DE4C,AAF766DCCFFAF7EF,17FF85AE94520E01,F9DAC31BD9B2DFCB,284FC23A37A34158,A0E921272A4CE29C,FBE9EBD85672F4F8,7C08489D9AB99F89,534DDC03B433B154,98A2D7DE7B906A13,0000543B5975CA90,EBE7646923FDD6F9,297EF4BEEFFC006C,CE2845C2678C5F90,31F9EB7FE634E96C,71A4ADB103E4A869,0F248FC05CC7B4B5,8BBCE10D065912B3,152DDC91E172C575,34D20306FB4A80CB,9C020DE3A41DA26E,DBDB8D1707CA233C,00006679381E7697,F553B4205FD725CA,7799D5E76FE0B838,CA2881FF30E8D8D4,475D4C56F7644B59,D4788228CC013EF1,8B4BA43D8C436516,489D43E54A4F58ED,E907B6DFC045A260,97F1AC5BB82286FE,4099B3673B5D5DEF,354B3DA62B5BE37C,00005B3C8E1EEFCE,5626EE718771376E,DB28C82F9CEB725B,4BA3A66C37B03F3C,254D6E2D3A727067,8C45795763A76A96,61352F872C5C0FA5,B67F0F237DDA7D4A,0A595FE6AC94A77A,A99211BC0B38566B,D462B9066CBD0000,1EEB1A4BDD47F592,00000F098FE1F645,7BEC425A7EE5C471,1778F12C72C5A6D6,8F8FC4F2719B5FF1,56516AF593735EA1,85BF496427DEE999,6A17A5780F2F2660,B4371D9FA722BE6C,64AD78F9180D3F19,7C82A79D37D7D3AA,361CDB91197B953A,D8B59649013DD404,00002885B19095FC,693C331D5920E7DF,A5BCA28F09DF0B3E,7367B4C87492D247,C48E581EAD7B08C8,72FACCE29CD00494,5035BDC1C1DD7E5B,B7484CBEEBD6A8CA,28286B7955151176,F4790C2795A50C65,B49C0D33FAF95621,FC310504A7105AD0,00000551D318510C,8D5AEA1E9D2AB48F,3ED2DD798D3F743E,74009F461AB727C7,915EF06AF0D7E9EC,6B9B437761353AF0,3016F00F20D0D1E6,8AC638F37A29588D,5FBA64CC48C9F37E,F585366269844162,3D940AF44DDA1E3C,D3338CE6C3E921DD,00001925C6AB9CD1,A0EAF98F414F1ACE,AD9A739797777BC8,D10E5970AF03D211,4885CC6F4504A773,73FF3D34EDCB1622,509D454E17AABE90,CA164988627AA07B,8762EDE92B076908,AF9D1383FC627E2A,17E2DF66727C2FE3,B6F80B09E993E41A,00005F7F9D8127AD,65020BE03C53B4C8,32E5A9E3F0CB67D7,3F41A989EC669EC7,D61DE0F9621F17FE,1522940DCC5D3C13,EF62E31354316F10,D29ADE8FFB61B674,4B78DB240898FC1E,6DE5AE921D4204D9,73744A032ED64EE9,1D25B568F3ADD414,0000316CF1BD9187,95DA20728B10164F,BB107062B4F96FD2,845AC435C1EF2A3A,8C259E61B89D874C,8D95BFB846F1DED0,5E1479D3653A3F75,48B4FF7C99E17A83,82219D0470247188,6D3268AFFE3B2BE3,88DDB4E184A64E9B,2389D9E5A4370F58,00004D736EB8727D,A1E6A67F0F7ADCAA,C84A1F4382D4AABD,90AEC2933F797082,ED55EEFD496B87BE,D9A6F3ED1756929A,A7584832FA53660D,DDE9D0B9DB4CD6B8,E9EB0D9021835114,EF21B03BAE3F1664,56CE3A6DAFAA54E9,93764EBD80675846,00001AE882DEB101,EBD078228CD5C059,35DDB3164669CEFF,0507A3C15208DD47,A234939086EFCBB0,9F267817459A94BF,C2498C234AAE7354,00E721B68A7F0E7F,6679607389410E6D,5A1A0E844E53B8B3,7B69CB82795187A4,5586F3115829BED3,000042AA7515A19F,A18AC3CFB613EDA4,92997262F7CDEAA2,83570C79791F202A,8FE8E20D3FAA347F,1ABCB5393F58796A,81DC4D2C430515C4,C1FD4EAD8D724F32,61743BF1F3DDC796,6A1FBEE09161E605,1CCE5EF57E006177,6CA7B194F130636A,000052511CB295D3,AF24FD9D267D5536,DEDF01A8138EE2B4,13CF027EAA49D09D,B071EE5DF63D3FFB,C66AB6AB71C44E91,CD172F9947E4ED6E,1A04F19B9BAC8D8A,76384FDA7975313E,8AE301CDC3987CCE,2C192AC9D4DF0C61,4F023B4CA5D8919B,00000B99A33B75E3,13A974EB87EF7814,B59DA558F7A72137,0E3295B24C36A7B6,B70C6655A6C24660,EDE84C8C50A9B649,4D24A6DCB58A2EB6,AB9EC333156DED36,F40ABA52873FEF6F,2410F9B33D72CA25,096CC10346325329,D246A925E1C5381D,000038D0697B29FE,842C74CF0A2FCB7A,B72A29AA5062E4FF,6A9C6873D2F60A2C,70B2D68FEC03C892,1AF9580022AD0203,1A88CCDDD4729526,A9740C47B647B4B5,A52380588928490F,85040D6985C11151,503AFC1C3FA6742C,33E809DA7BF9F45C,00003B66D31397AE,89CA63231F90A7D5,D87073DF1D4062C1,CDDCC91A6D192E9B,E005AEA12EE8C1A8,C561BE5918C6C62A,0C21128BEC759CC4,C7638A31F396BABF,410E3A891757A6A4,99F43CC55FA1B393,EDBBFF71A6509212,73A212887B861A59,000067A12358A5D4,F95BB0DDC2D56C15,E0F87D90B683ECE9,950DCC476130C17E,090B0A356D19F45C,6A4ED0214C579E7E,89011A5644255CA8,56CA6A2720B9668A,CA376D0054C4889F,36DDEB6D6C7A76DF,74E5C3B487106AD5,F678E8E1CD4C163D,0000206E98261502,FE27B55849F01C25,66D4CABC02D79D33,BB521FB53EF18CE7,825E27D0582C532D,4DE41A2A252AD153,52F7F2A0A5E7FE0D,E37B003C01F6AA99,BE61CD0BE81E259F,B85AA17DF0F87D4C,A9B534301B0B76AC,CE2202A2B5ADE2C7,000010D20F0B48C9,872BB253AAA11D39,CFB6FA67E492FA00,4B9C298DA5B0A4F5,644D9194CFEAA695,75C1A33B251EE034,514A45B9905E3986,F5C9FC23D7232481,8A1D510FFC478CCB,F33C57DCCDD097BB,76B7DD290C714CEA,E1C8994249C8163D,00000087347313EB,694190FE9689C6BE,9E90DE41079AE100,6426291FDDB89A24,DDAEE27D7B2E4F09,B16D7EB2C043A742,429D79D9F6706389,9864E492B6F72B1D,E552ABE9D7138596,65B6418DC701175A,1683F2ADD235EA96,F4BBF862D91CA84E,000057902D94E14F,4A851FD6B808A525,B19402358F1F7944,0C9A23A938C875A2,BFB1EE8C2C0FF890,307A0ADE0FB2C7F2,FAF977A7E1B8D6AA,71D0B0CF9C3AC714,3952D4D57259AF48,8F2A735949E4A6E0,FA3EF863950C2F5A,541F99F409690B98,0000421AF82FB940,FBDDEB10886E3C57,CC9989109E220C44,9617E71B08DFCA2E,72963650DF5D5A43,91BB559FE06DC23C,DD78B51D20CD1B29,F34DBB303B31BE76,F75340C460E7D43A,C43FE433185BFC5E,C7B67DEFABB3F0A2,1CA8858F478AA6CD,000065EDB92B20E2,96E9C314BF7CCA10,A53BD18B32A9D371,D78FCC16549FA3F3,D69F995303F27468,A7E20ACDE711343E,57DFC266B2AEC61E,C724CC59EA17732C,69CAE78532E949C9,EFD9E6F5A808E64A,51668F4DFFC55CBB,FDA197F2725DCCEE,000037EE6DCAB77B,10FF8559583D279D,501A04FFCA39DB1E,9665E3335F12B6F5,71BD5FFE356AAC8E,8CF68204BEA917DE,7EFBBEBA2693B8D0,2B3A9A83B63F80D9,2753F61AE50911E7,E299CC1B3D181ED2,96842A0809945E1F,A52F82AFFB4B8AD2,00001E74EC943FA1,99F800429EC531C1,24E34E3DF7392ACB,D7548731940B4AA8,593FEE9AA217A207,F0BD3FBF175EDF33,8FC6503869032A5D,7BDFB7B23F7812D4,4E84761B8BE46F8E,88D848AD808ECB37,A1CE8751448C2C2D,C99730065159E890,000000B73563FF81,BB7C728BB8652F03,32D44E6B29166332,B928A15E0B9E8FF1,0C017407360DDE97,B1335E6F7EEB8896,B0B1A05F0DC7021F,81FF28894FACF6FF,CB60F8D2BF58AFFF,EBAC0EC072553504,F0ABF93DE6890E04,C22FBD84E985EEB6,00004FC0ABDB7FCD,96CE016FD3C6F845,A358B61E94EB8C4F,79A2A531BCFCDC69,7357D721F7A67860,6B27D3BA6A3FFFEE,B7635F8BD6A0708E,EAC0CEC6C47955A3,08601C6570F8A713,5ACC542E542F7A29,09CFD6137745380F,D6B33CDD13A3E585,00004E280054005D,49485B8A5D5F1DFA,F3034C438FD1FE65,3BA8ADC7C6413C2E,B9EF482BD8E150C4,ED51ED92895E5E35,9DA021536CF0C1BA,4B5B1174C2662D75,AE09E8F93D25AF91,7D65F5BD2670BF8C,314A7B949E1546C2,EC5F31E44C7D6505,00001A04E97B01B8,2ABD0C908F4EF1C5,B8EE9853E3E068C9,C129902D5215D446,6DCD21A113BDC2D6,80FE4EB3809A7B11,837A7554C8FD08B6,80B2CA7C033D29AB,BA2C8B25973502D2,35796DF8E95F002B,5D2B38DAB76832BD,9273C62F4B77D4CD,000030206D24126F,2F9675A39BB27266,569F234793CB375E,519EC40A7299AED3,90C703650493B938,7BB53F6DE292E8FF,03CDF5D43CBFA74A,485037B1DF898ED1,12F93BFD119AD4F2,BB880E10C3D942BF,ECEE706C6BBA1969,992EFAA04FBB1F8D,00004A3F9788D686,77FB2272BB125328,CEDEF16D18EEE058,985B7DA929F4B962,87E9ABC8985AAD52,9C24FDEEF052DB4B,26D86E6DF4E9209C,91162F4C4D6E4269,99BAD746E4680638,2F035E9ED01B08FF,3A2B03AE73D3EE86,A9F06B7E19A3ECA0,000054351802859E,FF87862DABADF9BD,D626069ECE79FD05,6360F254551B6BFE,7907F3938D67AAB1,15FB34B4A90FA60A,687BDA30AC18EB2A,46BB54AE14088D6E,C36BF6043656A12E,7A283BA716D32C9E,E33A5F2CC983632C,B4B5D1D99ADB2603,00000591804E09E4,7284B679F965E3C3,7C4E6E5030AE829B,2D7E1CAD17C6D445,1C8E40BB0FBC5DD6,888D7B28FDFF71B7,B3378D352097F3D6,CAD476239E85AE1E,E42E2C81599B8087,57FF5EBDE5176290,EE85BA200F2EDC9D,BDCA17EB2C767302,000002F8F6FCD217,B6252124D0738352,8C5621845B361557,634CEFDB3B84EAA3,FFE741A4A82331C5,386FD1D6DAD216C7,971496E877FFBF4B,2F0240B4095DFF42,CE928793CFF3A735,48A056F00C99D8F5,C6AADD93A34682AB,F5339AB69E4F774D,0000328D387D11D8,7A6F3153AA29BDCC,1A81E716679FACB5,11D14DCA1C3AEC89,5A70A98FE5B63FAA,92483BF80FC5F901,AF8091C3206A45D3,A2055CA473EB7452,69C59B75B8E8AB2F,3201628676AA4F86,2C97D0FCFC13A8AB,CAE34BFB0970C70E,00000583DA3D5269,2AA10BF62F90C5C0,5CF31ECB80677BE0,74D81F8E9EB2CF07,A06FA5A535D1EF39,0231C4EEFD8B8174,D551A2A2E17078D3,85D95EC8F70237C9,3D52870831BC88FC,6517F7803A91216C,70B61E8EF4A8DCF3,4E572327FB577C30,00003141BF6CB059,A81E7FE1D0885F53,64798E91CC1CE881,D58109075CCCE721,659ED914B543D733,313D63B039360E1C,2457E318423F50D1,D1EE5C8783EA4E7F,285AAC5E9D1C3BDA,3321A0297D9D31B5,DCCAFF71310F60E5,EE82C84CEF6988FC,000033F106D379AD,260F250D66CC09EC,0BA5450BBAFA3507,4753AAB79ED3491F,0A2AD762530D5F03,F702C7688573EF71,7852E7F8A3BB64DC,FC2DDDD20017193A,7AAF6D6A057C6220,B62A378E483AEB48,58647FE58D151E2C,5D5D39F5C846EFB9,00001DB1A5CC4FAA,BEBF164A9B02ED03,B92518DEF03E3994,33D22938027AEA02,7D0E655E2365505F,1ACC2BCF0E34B0F3,AFDF231A046D947F,CD3E4B3F5F29FA6D,20615ACD51792434,B5587F78E0EEDBC7,C3A8182B56D93310,1DD746C7F92C8157,00002CE5196E1D7D,29698A42942953F2,7382D852053DF010,5BB05C63AF523861,3245D1ED53A02A65,C8B13EACA3950A59,4D04962396E9CD02,D8A0F4E423414CD2,F71CF345E5511773,2910C72965D3ADCA,8762B3145E320357,A34A46A58127C1B8,0000123AF26A239C,4E845FC2B3D1441B,343D2CC3049ADDE0,68F0328DE347A8A8,DC8121BD82BF6C34,6EA55B5BC7D1D4B6,7970E086F974E5ED,1AFFB861201AEE0E,C04229E4AFEE2200,B8AF15C2DE3A96C4,87BADE2964E199C1,13DD324500347802,000029F3FB019CA0,E85EEE773B76A94D,27773B9CBF06DE60,6E3CA2D924F1E9B2,03DB748A5C2B4137,5B4CFBCF1664E07D,32CD3877322A4CE2,630B5474733593A0,D0318008755ACB99,F9929A3DB2E570F3,C4169668A9D074C0,C4489C136D2DF4DB,000062DDD028C2F3,9FD1935EE6310607,783C7D3AF99DF866,91809EAA1E1EDF32,453C49D732095A6B,67DE1313C6C6CB91,EE36B7BD787A03DD,FD889DAE546E072F,3555873D9071543C,1E2CB8149B3F0197,905A6E4D2D93386F,2CDEE944ABD00B2F,000001CCCF96E16E,153C340321D7B532,2758CCACA4E957E4,3FB6A4471947CF7E,C88CE1497F4EA1E6,1DD5636167635C75,420A55FBD43ED1F9,3731F892514739C4,8DB647A33804508F,6E441B68797D1320,D010DE127897EBDD,321570703D26B0AA,000059EE68E08F19,460DDD79C140075B,C1160892F665A0BC,F2B7538BA7F5042D,B364BD7DC217751E,3CF5E92918B06CE8,F82D5476D0086DFA,D54CE8AC6C340956,760CBBDC27BAE6BE,66BA5F3BD758A4EE,395E97994EF5DD28,9866BF3735E090AC,00001D62AF7DA609,45CF16651707DE87,FB713C077EA37C59,E531C051957A1738,5793CC0BB896544B,27B22C7968B507B4,744F95DF17FE0384,C1C56FF4267C5022,7AFE6E6BC2A3978A,CBF9FF0632B2CED8,E716CD03C63F4D36,B6A26ABCD054B51A,000023297C0518E9,7889B0E28D950F39,EE7B06A5D80E68F8,91D9BBEEB09F2D1D,7F84D090FB2BD3D9,87522B89091365B9,6483A352C77B92C2,FB054786D926BCC3,4C6CE3FCA3805470,A6E48B2139685FFB,5AD0801B5036C24D,1F11291C1759E801,000024F9D574DFCA,031219433F149B85,C359FEB92E6EE091,5DA24D38F382C4DB,927019CEF5F7E265,80134D0AFFDE9192,08F5B9C0FD857E9A,7665E530B68FE2D4,57B0C403DD036D6B,23D43E5FC52B07E9,943EADCF7A2F6071,4FF24311463FEFF9,000062E2659FBD08,C308C0C6EA73DF2E,B4549D3B9EEAA8CB,7D364EA9350E400A,85B3F2E01FFE60C3,5DF8B45614A58FF4,541F26C3D4E1480B,29C76F8A8CFBD76E,EAE5B6B9977704B1,66220AE44D1B55A8,34BBE64A46E740A1,770C1BB80F599ACB,00006511C0912E6E,D430C98218B9D19B,666802C9B74C11E7,B693FC81172F77E9,1D59CDE17503F98E,C8BE23492CD59F31,9D4D49FCAD06F358,EE93059FA8B9454E,88A57192B5B58281,194A60538118E00D,596F814C132E6978,59B1BC6C6A88FEDC,0000279E79FA2992,697A9B608BDB4E36,CF5DA2F49092BAF3,1934F8C7ED96BF44,BD25A4BC71B40F88,FDE717F2249B6319,FCA0A725DB2A79F2,33E6ABC6589A6D69,22B3B0C53ACD78E7,E2893637A4A42E98,DB2880D8F64EEAFE,C284C4CC7A5754F8,00006CAE5FFC184E,3E70F47EA264563B,18C29AE74E6C2154,6B297390D83AD7A6,F26B8004EE73DABD,A2552226ECE2A647,1CEB7916B485F3DA,D202F1154AC62842,5B990EA9F846B0C0,9CBC9E868B988ED4,C5E60889B025D0EF,C2D07E03A03214E9,000019A5AEE9B593,3DE42C52F6DC03E5,C37B64F5473A0259,D3D209F118183AE4,38FB635621784975,315C998CC64BB81D,A601FF58A9E67AEF,7D7027B7A2D286BE,DC8F8081D64EAF42,367A1FD0B629D779,40BFF99CC2328269,9F6CFEA2E85FA319,00002378F6DD31C9,951A154BD308788B,51776AD71A9C6607,46755AA56EE54123,C489C0C232C99CFA,1200671E89586834,FC053558DD51F5D1,EB6CEDF32812DD65,4132371EF6C9A280,8612C1E2A74BA2FB,6B062AC08A46E6E9,76478B39DD1CC38C,000069ABF477C221,16E299A4836C6559,98A926D03E8CD51F,EA690F659A81DDCF,7B3AB2908791A190,E203785F1C990385,F3313D9832DC4178,159F6F769419DAE6,0154A037584E0196,787125181232BF75,E33114D745589394,5E6EAB47FD4922A8,00000044C6F4B93C,E4C3C904BFE8844A,327760C9938E8579,5AC603F899B29108,4DA3E5F7E64E846D,684AEBDC19B684FC,D8A4A7C35388CA7D,A6F5692045922E31,C3A6D386C8180BC8,99439B7338B9843E,C12C318950DDC2A3,AFAECEA2A4F958F3,00001A63F05B8FE2,D99B6BC734654776,E29CE5ABC3DB4979,036ADBE9C2534A38,831C6BF28B3800F1,14E21B39553E55F4,DF46570C440FE9CB,A15A53BD8A6A6285,3416F0A9EDBD9A50,EDA855D89110362D,245367BACCB29362,3D952017DB837B04,00005F08301A5F31,FEEDD8D9AAFD9892,BC2FCB4A88E626B9,FB14BB880BF194C5,634782C75C94EDA8,020CAC2B522E36A3,C48B387D9339B4C8,168351A6825B2FB9,FA965F31857D6E18,9111915256CB1DB3,08B86886F0A50BD7,B30BC872F79D5DA9,00003ECFCD98ABB5,52BD605C093EA863,4F0E5C79FBCA166E,68511BE83629A42E,9A40E675D69220ED,7DE1D85313667056,9ECC81B2FE5BF6F7,2113CB3C2772963B,7B5478F4A3512C60,2D0A66F415843ECB,2DABBEB61E019B27,68B2E3098E915AC8,0000345B7B503D72,C5365B6F0A40CAF6,FB6F6C05D64ABC01,822C38E3181FED35,B11790E5DB0C6D5C,916D54E0FAC2A56B,25CBEBA4F20D77A6,5E12620D5067083F,D22AB8F0B712415C,15ACDF86801DF099,4AF47C5B6B242911,4DC6AC4E92CF2AD4,00000261943B59D1,941F4F7E850FAC2A,DE619B0715C5B0F4,334B133EA8F3C334,C78410EC1C1EC994,6184622473A79DF7,3FED3DFE2506FF71,411F06C8214F119E,6E2B2E4AA1160341,C8BB3843DCE765BD,D18FECC1761CB594,E246EC9FEF1DBD38,0000246DDD9456E8,20B05B4778F623C3,FBB4E143BA84533A,C76787508D9134DF,4AAE8B65585EB603,3C6BC7551909D9D8,FE90502E63AE5C54,E0C70373214D65BC,9595AF54053BB15F,FDA5297A7D03735C,561CB7EC6AAA092D,5B6ADAE992151790,0000490805C5EE46,C97DAC57A59DDCE8,E2257C978A86307F,C49F3B885964BBB4,A48728635B7DFFFA,F42EC76BBAEA5625,D14C8864456D88EC,898EBB34F2551B8B,B0B9E95EAEEAB8C2,62709F45A4EBD305,9DC7201E704BE41F,8CEB489153FE2FC6,00004F3383CACDA3,B072B7EAF019AE11,125D13A283135FC9,FE4A1CE3B158F979,7BE113A86803AD63,832690D918DDAE74,598D2FA15873513B,530DAB6364CF062A,551617AB4898C258,6944D132377E2CFC,2C1E4E2CAE9502C0,3E4F8F158C222DF8,0000258858D750E5,3F811EA93FD4B838,39619F3591AE9A6F,4F9B3BEF8FBE49F8,CF3C80AC779C4138,C821F1FDAFDC7688,F22E5CACCE2A0901,DDF4116CF091FFA1,E1B9394A0469A235,7E82B4CAD3F93B50,39692C33ACB8B840,B00E522A2C101EDD,0000552CA513955B,50B8BF201FB197EB,8288A498716562F9,87ABA76EBD7BD505,ED94D560C83E40D6,C52A47678991F04D,683CE7E1BD138675,34A3542C133FC445,BEFFABAD3FB9635D,BB29566A08AE06EC,8430559FDE8CA979,5E16C527D7B2A023,0000183113984B5F,BAF7917240A5E51A,9BFAC28E2F2CF88A,6077420E9AD3C3FF,D0CA28B48FB545D0,A856D152FEF4A227,C6CD74F2B01707BF,E7B82DDF97F5A7C0,7D48C6FDB2FE52E9,DFC59E9C9EDADD41,10FB42B89203135A,4E3179694F2A45CD,000038F6A8F8C7EF,AEFF9D503DCF0C8D,CAD19A9EBE6134A3,598EE1AF8D7DE8C3,39B49A5DD2BA8E4F,7E3324E9EFC7116A,F62535311E204981,97F2BFD5D7950831,6E588DAD5531F908,E1F0211A53916A7E,37BE5BA5DD4A4E35,B3069056F3B33AB9,00001059384BBD27,69F9A09B877FEF22,3CA220AB96E51A47,DF4A93A2BB81D638,2F94345E4CF1B736,81D6780CC18804A3,4A06CEADDB7B184E,7FAAAD424763FF84,3233C1DB5AAEFAE0,0FC4A0143471E1BD,BEA7A6937FC17AE3,342E05BD30F61A53,00004C7DF9BBD1FE,DDBBF48AEDF3FDF4,B1C5564DF6C7B1AC,A0D6C96E33506CA7,D7F409AC39FA7FF6,127DA7E1207B2634,D2425B79ED28BE06,9B50F64578EAA0A6,C3855D1C684DA640,F396A059B9D42F64,B6EB72A2BA5F40B8,E641FB4AD3ABFC34,00003CEFF511FC10,43166096618E91B5,A9D3117C74C5464A,14B127882FC46ADB,CC9F4AF5B1B3EBF7,CF149550D4B01165,40C2484D71C83106,7A30B0D9F7807465,489C0F624859D5F1,7EB2078A76F13720,43A2FE6740F155EC,8793AB76BC15D1AA,00006A6A84E68AC2,78DDE3AF62945E20,7EA9D4AE176127D4,7FBF5300A6A82E28,A9F0786C738D56B8,26B3367A44EF87B5,B45AA7E10FF644B1,F42E673F6F060D5D,DD8888A212649485,220BFC0235A7D8B9,1E3D74CC850506F0,497A59F0F2074DA0,00002A2BFA79E07F,A40DE18563D273AB,C51A752354905A08,2788B8FB5B52F7C6,4727776F51868E15,E490469A647E188D,483330D18D49355A,B3ECDE810305E6E7,A2662BAC979E8875,CAFF0CAF47E98D4F,050E093C46B9D331,1FE91227CDCFFA7A,00003AD1E50B17AF,8F69382370C0FA2C,883FA05CDA032444,2E5CE095C87629DA,508CDFDA2021C84E,FD22F881B258EC80,DCB08DE0E709CBCC,C80A0FB4A0FF30FF,AE499CD5DE112AE3,C792790331CD836C,25C57DBBD88EB242,054D8D7EBF639A8E,0000002BD242F831,71C62B41C30E26D2,7B6A3C516F33B61D,7D858707F68E5A27,B1993CB61F3BDAD1,A929E7BA55B212CB,1D17FDAE06A3955F,02C0AB0626ADAC38,A37A68BF36624ABA,1A8A21C18207762D,A065EF3E5B20C577,1D1C4EEBE8E8B4AF,00005BA147E11EFC,6C01DE0DA65E0FAD,9B0BC7A02E27D180,08723A90862D6AD6,0538CFC77602658E,09572FBA5C84A355,8463E069DF572B41,F944BB775CA6BF5C,0D6819B69F35C30B,9D0212B8B3EE93E7,4EC22ACFE49EC132,BC549C59BEF645BF,00003164DFF283F6,982F6E9BA2A0373C,3D780DD79802C85B,5F8EAFCC22455128,28322CBB84A62319,CA7DD7A5D4FC48F3,298C03F48AFCBE19,B5E2F62DB6FD7311,48EA174B2844DEEF,7F3E7A2F5CCA3DD3,B8BC7BEE82552C00,60840330E14FF9B4,000009E86B4E2E4B,624794FF19BF165B,8D5EF6889B85899B,B92A2433599740C3,386622BFBE6A1CD0,372FAE893ADCACA4,A96B51CC71221316,737D062F86CA272D,7C2E99F0B82FDC19,7A44DB3CEF12D8B4,44D79F19B1652EAB,B3E1A37A4940FD4D,00005278E3008A8F,E83E6DB641F03C0D,BD60C92EFAC67AC6,279D7B1E7B0AE3B9,AB247397F9960EC7,A36DDC25176FDBDD,E4015A368E1F097F,662F45D83DEB12BC,E4B31BBC0383D4C6,48DB7371381CD238,02EBC1CD90BBF884,230CD9337B2B466C,00001D8486E6F485,C7E52F29B577C0AE,D9B30888543A23E2,21B7146CE7B397F7,7623332153E51400,6C5B4D7556030971,A209D0FE60E6D76D,4A343BA93D2CD660,124515D82BB71C6A,0CB59ED269BB64AF,98912BCF94B32DDB,E1A3DCB17B7ADCAA,000056A08DCE392B,E970B66168D9D800,07E0A268235E7E93,C03630BE0E9D064E,F8FC6BB3BD8CE87F,59A77D4938B407F4,D5995E5F8A471C77,D8F53474E35CB3DB,DDA816875ECD58E3,397FAA24EF46F3AC,A4DD41A691125131,1EDFF1A7BD89E960,00000A9AC6A367A7,BA2C203D30A764C1,2015C47010FA49CE,34D130F98C30AC96,4AE3AC2D259BDF23,4941F1142F0537BF,D33820DC1ECE47FC,829D2C39F26F6BE0,CFD852F309E12C58,311AF6FF21AD1EE6,2154962D73D6D455,49FB71C4EBC89889,000043EBF77DAFC0,9568ABD0FF69FAC6,929CC51B16C44BCF,6B6ADDD5656CC429,B9937D3A5FAAA0CF,96BE3861B019D232,FAEB8A17A156DE06,F270816D451F0DD5,51FD803F200A342A,6818479C3E65B689,7BF5280524EBBF5E,5A1862490E0284DB,00002FC5BD3DE709,3F66A29A3E685DF9,537636658FBDBD87,5846E2BC914AEC44,51658A00D15D6CBF,101CA38B960685FE,D264B7226322D6F0,9EDC129E4E966A71,4C3D27A9E046CA5D,72EB1AFC14103657,E69414F061DE9DF2,50BD593CDDCD4F88,00000E996433F793,44B963152A129200,F40A3B7096AA8D05,A0FDC42DDD3F940C,A46CE5B1307AE3B3,C338D1752BF51411,9B2AB6739C707CCD,31C2A4D7D7E01946,14ACB58CAE027F15,25DF1BF301AE243D,F66CA7FD06E21F1B,D49FE38A474420B3,00001AEC4FF5F39C,8B08A38356337CCB,900DCEB6EB9AF2A5,34FC9E1CAF6E8019,CEE5BF5B830CAEF3,AA2F621F635851C7,29473ADDA80E2130,FB7B85B102A33723,FB47B9A855CAE9EC,4EBB4F08DF657AA3,2578FCB51A035CAF,51470BF101334FAD,000006E958F9E1CC,E0BC5C5D81D1A211,12CD290F748FC64C,41EBA3091A038E58,8D58C5A3AB80FCB9,3660317C23367CF5,3E7744B490EDC1B4,AA4066C1359C5113,458F9CE3E86F029E,4C6B3D540090B7DD,9094003BBC4A211C,EEA4E9D19ADBF621,0000030B0C930F5E,7E9B5595E3195ECC,96B2D755CB1D3406,1EFB7261A68BB170,082574F04DF24B1C,2675B4C4C9C396F1,EA60C9196092DE1C,2B83772EC9401D76,00FB81FE58589FB5,5D0884C95BE1F02D,499E9BCB24714696,B4A4ABAF396432D5,00002F1F50C7C82F,C94B9DF4BAD740B2,437FD0DE07050EB4,A0A9C7F4948BD6FB,B352B97EFCA100ED,193BB3C58A85CAF9,C169C36C7EEBADAF,CBD091057805EA3F,BB76E693D75B0CA7,CF7A3CD80E818A2E,45D1998B90F313D9,1B218B4381ED1FF9,00003E475E26BB91,84B609E6FF3B56E7,41C38F1A4DAAF08F,ABF0044E531FA2A5,8FE8D804B2419348,9BAF550FB9AF647F,41653EA736390E1C,C09920D3A2A7842C,8C9F43182D0931AB,EF252C7B36BA0968,136CA507023438D2,753893E91A1809B6,0000485434169661,0238553078DA1464,147981BC4995B4AF,CAF708B2A2F912B2,9E76B9D36F4FC0BC,82D35E23A4F44528,598F186E8E612A22,B081B9CFF922490B,D8BF72A5C1E473F6,CA73F24451EE6214,D52E4B0B5D54E1CF,66E5B24D4D6A06B7,0000075F04C7DAA1,7D1CB91C6D8D9C8B,04688912AA62C354,FA765F901A027B3C,024BFB2797186586,CF6C48FA40580329,2A3D7B71A708B39E,8555DB0A22F32FF2,7D5AB7BBF6ECC8D9,3C9443338478FFBB,ED6F1983A1E71A04,4C9911742327E2DD,00005975DC140680,848A50805E42250E,E3515D367B49B5CA,267E935EAFA7AFCB,11356E8A7955F501,CC3FB200B9D5126E,D528D503001F40B0,8B5CD6E2E94EB425,482FF62EB474D461,493E2425E524C0E7,110DFDF693BFA420,0274C30F3C4F1824,000059E6D41856F3,40FDF5DC6244CF8D,7D12C9385728704A,AFDBFA75709D19B6,D961CFA9599CE4ED,08E3EF9C0AEC6D89,99E85FA190916550,A4F1ADDB723F1E8C,C9A6A5C9167C2136,84A0CF08191932A8,4130A34F4012280F,BC08252C580C58CA,00005308528B47C6,B631D087BE80694D,B38197FC809CFAC3,8D4DA78E89D047C1,3793AF134F091419,E1D1AB22E48E0177,C8F61E25CE371BDF,136F311ED2D70D27,935064A784A71DEA,AF5DF16251131451,C8AE7C3F2A0DA8D4,F5CECDA828320004,00002CBF8E22F077,0F986DA3AE50145B,80C758E83912B46B,65A7FB7BFA2D4E2F,D3FD86CD3CDDF757,AB5711C49BF1E95E,8B0125351B8A57BF,DEC4504992962C7D,6B9FEE742C631725,95944B211EBAB447,34A62FA3C2A0309E,ADA1C2EDA80207A0,00006D24D715267D,B2814421D1857D80,D3A81447ED4E6A84,12AC00F28406516E,C4E99A0F96B6B924,19F01F028715CFE0,32BDC7D56E2D3CC9,B1E6513391CEA5D4,4B4369297A735E95,38EEA5114567FA53,BEE63F2DF03151E7,CAEB360A605926BC,00000E3714D309EF,8ED7FA691EBC02A8,A9DF0A7BA9213DF4,92EC316ADB845B86,A837F4175E020C8D,E766AC23F7089B9D,2F6066E8268053B5,99333BD32E44796B,64E9CDB8098E0471,3E3A9A0A16299A95,B9115E53D2923B93,26B46B2AC6268567,00000D7DF272409D,F4F3BAD138C83201,8972B9E31643CFCE,ECEA89426D4E3BE5,EA1E28FC8C56397C,5E7943E8F637BB07,A3BB002627F948B3,4DD1F1C66E37DE53,835349098F9F8B02,CB9CB0438D79B20F,194A97CFFA230FC2,0542A505D194B72B,00005D3E15B9C7DC,0A80CF4F1D45E4DD,780252AF9C0EE3D3,53652571D1995EBE,15FD90F000D599D3,71409910973BC69E,FE2D574EFCF44053,744B69059D9DEE01,2F1FB68F19381D18,D96ADD7B56E3952F,69CC861FA89E30DE,3C635C7F51FCB8F3,00005E6AF837D73E,4EA79CC8AB532376,FDDC779FAD56F1CC,FF521422A8033782,71BFDF0C90FEE0C1,7B74257B7D364EE7,0F5497FED8A3557D,33B72CF288E64458,C6B65C71EE3555E6,706D1E238C2B01A4,06ECA239DCF3B924,2CEBEDCFBA76198C,000025AEA85FE4C9,518DB4D776278DA9,0C2D35797EE04192,0688CEB1F5EBB263,9D1128B1BC8E85A9,7A099AD466330DB8,89237993D3D3A25D,36EBC62F29B897DD,BE5D5308C917161C,683A6457F6B8069D,FA1052D94A3C660F,8392E8E28BB47213,00006E8E4E3E3175,1C5F58C33B67CB33,3655DF929FD2BF94,D649CF8604DD49B9,DE45591B9A0DF1E1,F733AEBE26470D25,AAAD9518F3E05410,A1BB6DBE84FAF021,83785D8AC86879B3,5D1390B1F3BD1B02,5FF2C32D14EE126D,BFC85DE8B6721D90,00005CC500282A91,EC801A61F82F6261,CC8AD18B242DBD3A,F2E79D7C72AE4CAD,4319779F180BE2B1,E7EF0698F47C99EB,F07B58D7EF041784,A8A762DD77EFBBCB,18D0B263548C1D23,04AD407EFE8CFABF,41169C22D14C765E,0A2191C9AF02B1FC,00000349C5A87642,D3C56351A81DA59E,403E8F28A316830E,B71BBDEF696AD9D0,74E5F860881E3ACC,01E0F8C60506BF39,53B68437EB8B8EA9,A62B427592459DAF,28665406BB580704,1487102F18BCCCB0,BC2D30528A53B2BB,ED47D3AE5A8211D0,0000615EA07F117C,F59E406DC1BE9137,E4EA0692E66AFE61,2A205C3AF2BF919F,54B83CE9AA8D32CF,D3A111C0CD08D074,A590AC0EFE899337,7EDD17691DFE3FD2,1C367FB6FDC90AC1,368603A6926B8DDE,CCC74ECB888DF354,B75B3D05A5220E2C,0000133786E353AA,B1EB7D691596B3EC,58A9DB360BBAAE86,EAAD18525181C4CB,8564BBDA546106CC,263E50BE94AAD41A,3609E91F7F729104,50D64A414CF98F92,64BAB092096ED3D1,F754AF89B0845C18,8A38AAB74EA53704,E3E9F8C4F04DAB24,00000B7E3CE65104,ADF88F28F569AC87,3EFF4A80C22459D4,7210B3E56EDFD084,596EF19914E87FE6,87CDF5DB417F7EF7,5660F9DB0E5E1A6A,38ADF7347944707B,0462CDFF064A6747,ED00699BC82BA45A,53CADDAB4D94CA3E,B2F2CF8313078814,0000313BBC25BF7D,1D7D31CC87BB3BB5,A8A129AA13754DFA,D76D46184EB25825,7D71FBFDB88F792E,AC02E525B18B0BC8,7EA7364B84906C76,0CBB3E80F52F4C02,76F7808460E606A9,C576D4C7F6B72214,43F7DDB76AEC0BDB,F9B458F3577EACF5,0000036EA38EC616,1437610649D6BE10,475DE4973ACFF466,11437D61D330E7D0,14109275D3236691,DAFE049274995E3B,2A6F1AFADE09D251,011C4ED9F9540B5E,069BF9F8A7DD9B76,72E3B20E27623153,C1AF17932FC41733,CB4388CA7B25985B,000050D90F50163E,2E294BC0838A0253,DF7970C0126E84AC,79C695794696487D,AB19ABEC40A90823,58E5E370EE518418,A8847EBE748C514A,ECCC29216AA87CDC,CD81CA29DEACC048,2677DFF9A5FFC1A2,49929BEC3BDF413E,B5AC17E42780EDC9,000008A4D7C7C0D9,AB680AADBB090966,65A8CA9AF280DA91,41FB0B411A341FD2,E628A51DF05D8F5A,1257E6F190F79A59,A97915EF97902EBD,9D242D072A3BD20D,96E723133D9DE4BC,E86DD870C1D38564,3137709F5ED305DA,D5E193E9B7B2777E,0000342F72DC9FF3,09BE20157A61C694,95DBF8FBB612FC09,9D4F00612A125662,A120DD49FA4D44D9,14C77899C37084E3,6C48D2D460DCC201,5CBB23534C7C313C,5F7D6809DF83C6D9,330826EB97953704,70CABFE3D0B75B22,369E39BCC18DD9CD,00004388757EFC46,74E3D9FDC3199C68,EA5E350D238EFEFD,73C394488EB4C6D9,070C63DECB5CD0D4,85E75C270D87ECAE,484DB25FAD4609AF,1EC6614D58E23772,8A41A0BF34A1FFD3,4926E548C7A75BCE,7970929FBAC36360,62206DF0B148E8D6,0000293F099FE943,382A3B1EA2FC3EDC,3CB3DC57D2CFF429,7708090F494C234B,0EF4A5FC15FC7153,D038A83176331D14,E5A9D615ED59DACB,4D32D71C37DD6810,0809378D393B8C75,8DD983BF076005D9,11618A244BD3D5F4,38885901E4F0588E,0000283B728FF7E7,8C7B32925A2671BD,4D12A3B20156914D,FA40E061FB88E102,1AF081FA637F26ED,11BEEB6EC6486055,FC1CC1882B0A0752,2E00AE9F0ADB8B5E,B11F6BC28915E822,78004AC92E50B58F,7D47931F8505C335,DDF0BF01D1BE0920,00004DC1D3151692,FF230124FCBA677A,AA28EE1C363EBC3F,F7F771A43296C913,620F497194E79BC6,D7F65DF5EBCD6D8D,E3E342DF6362F121,47BA6DAAF62101A2,B614D9898868CF0A,47D859DA1DF2FD8C,21B88990B06526CF,5A7C97C01F25CC4B,000021DB7C0E8986,14A9C3D8D2D17AA9,7B204AA382BAA346,817AB948E42A38AA,A6FABB20AFD23929,A34E105057CCE154,C9AAFFC316B7151F,2DF299EFE77F25DA,F2A2F03E4063DB09,D31CA11B102F8E50,50E9007AE1555A94,57D25CCF104F1305,000037EF4A25BAE0,D1ED305892D63EC3,14FDC3D1D3C2ED34,D7501128312CC46A,34C780771BF4C289,9AF6CB386BFB9FC8,45A8D373B5AA63D7,A9029EB9D26C37A4,EF4BA33478B42BC8,65B25C51F552271D,A236203A552D69D3,F050AEB5A8AB6BF6,000009A94C9B9B9A,CD274B9A44C04536,A99051DC994E409D,EE1ACCB3058C8CD8,CCB467365BC10A5D,2989F2C10CD00B48,9358B57C9D1E273D,67E8D51B0A177550,1D579B5003490FFA,32842F7EE945925F,AE42E6F1BDFC787E,3CA2C3676F7C1942,0000555B4A4CE470,55F924F70A7DAE91,3F747DAE6C40CEF8,3D6FC9F1320F2513,D1749F9ED74E8399,1D6393A44BA2D6D0,E7BC3A7DC6D821CE,8E54216E2E7983F5,A19D8DAED1558F1C,0FB6C3C9B74B7DFB,BA970F28394FDB8D,85E035E9D59C7E4D,0000335AD3B7B7A4,CC1EAA16AA8292E6,52E76224314D3AD5,5E8B4221EA60CB44,13386CEDF9D9E268,E43F3BFE40384523,89F46DC738AB0AE1,34D722699E756DF6,6F243B9B4F5E5269,AA192AB964958A74,0A690BC446A834C4,268F094FF3B37533,00003F7AFB1F284F,24DDC9B2BE824951,368DEDB6FA017DD7,6C6267E74E7DFC4E,ABAECB92633B9C65,41FAD8D2A7E18878,4DE2AF8524770005,0B9C39478953686D,8ADC9867250DE872,5EC4A711E06A508A,E48B4EBBB8E26812,0C156E88036AA3AE,00004F2147AD5962,1564E4B9FC3EF7AB,FD7A2D0A43D7CE46,AE0807D6C6083192,9B1786697E9890EB,533F1BD941F9587F,0ED66D5830B72208,250E316662766E80,C2E6099FBF66C913,6D32139ED49ADEC4,0F34F0BC9C75BBDA,459B63C355DBD839,00005F2497D52E74,662139ACB91DAC0C,0A44ED16A491783B,8BFA668A08AB198A,7FF2E948A184BD16,7D37C94E4AD448C1,3CDDC42DDF1CBEDB,4ED04A58FFB66BD4,1EE6DDA273F2FC83,64B5D59BEBB80D39,5DEB42DAFC8E305E,016B7A7165D76126,000059356881CC94,71BDECD30B7BD495,E2233476CAC199D6,C5D0C7269F78ECA8,6E698E20ED4F3D79,39F1C1C05DBE76D8,B485990D1801D2B9,59AD62EB329E3D6E,6FD87EC9F887AAFE,DB1F0D2DD27DE18A,BE4D41837E47A171,843B8FDB44EE836A,000035B73B576A8F,10E9B67B701147C0,A552DEB6FCB59588,A478A52A21C83204,015C4B1B0798768F,EF8546AF7FDCD227,C485A427E2564CEF,9E33647D50E98B61,D4E533B4D54502EA,D2A45B5B213F68E8,39EF98B45FA5170A,5E6BB23C6E8EEF2D,000048E7C03AA050,5FD7F6B19E51E193,8764E230FB51EF40,D3135B5525BFE4DC,17992F7B4E64A9F1,0FA9EF96FBAEF49E,18CDE5DFEC3DF0AC,F3B7BCFD2D7576FB,41455DD80D51513A,040ADDB54B6F3356,A351B3835AD339AF,CBCCA3B61D1C2D40,000028ACED7D157D,6AA388B286FB16DE,758F5A9856E84BCB,618C11368E4304D8,72EF6F1D22B80D82,9C78F6C9E187E72E,786DD15DE65C2FCB,3F61D871AC1F4C56,893D61644C5C3770,2F702A14218FD601,04B6D8D3815E5C77,020F062E619C0508,0000033884B58711,FF11E7CE04ED19B3,B1F8878D561E5C32,EF9DF6C720F64BE6,59123A731DBCD140,A95BE86451E150BD,FF3EFBC5ED35816C,12FD973742B4AF76,95D1780643A78339,4954548CB6386437,40B891AA8526BDBF,E42ABC4F6364378E,0000604FCB69D942,78A662A5870A9F99,A672D6A631D8CF73,7848EAC4A15DCF2B,06C9A3991DA0D70C,248CC8B6E84FCD8C,FB8887ABC11F52FF,0955BDEB01020498,EF5414CE375E34D2,3AFE7D8FF9B23F46,A4404C809172F662,5B15702DB3804007,000068F86F70FC7C,3DCAB7871F4F45BA,A039AA6BCD8B62A1,F72834E3D5FBC7C9,7DFB1480C05BD112,B1700E87E3C4B35E,F09E879A31B896D9,7D9F2A96CF6D036B,1E6B72B7F682F36C,882AE1976DD764A3,129324B8C3E55A0D,FF6BAB601CC3CF30,00006A2854005DBD,BBAA64AFCC4B3072,6F4DA61361CDC1D2,CEF9B2A8C2247E19,4AF0AFDCA1FC716D,3E8D1AC27ED1FAB0,555C67E01FF45D86,67CE25AD762AA55A,A06DC9056BB4C1F8,CCA4877DA807963D,89F1E0C32B3D27DB,32EE1894B9DBA03B,000024935B314026,7023694BB4F82886,1BB5E891FC210632,E9108F824EF69FB5,F1265920F9E0C710,DFA40110CA451838,2F9F32B19058549A,E1E2C155A340C188,0B4D4F3EB0BF0C9E,A6D85F882ACA9674,604B6E32EAB346C0,2C57C35E74F32A59,0000606459895C41,DC1BEE297573D4EE,178679E723CFFAEB,F4AEDB96EAD30F0E,554E431F4B69AAAD,792C96F712ED8258,291B8E2D27EB9667,D533FC93D4726819,CDAF826190FF8103,7B1685C2E632BA87,99F1CD4F145F4AE2,955AA6931651A060,00003E4D01EBFA82,E31C4623939DD533,3E4D4E5B91F195AC,9E751DD5FFD79B59,F5A76C45B0BB2F3A,78228F93B1E86406,AD62D9451727C5D7,2678F4AEECD2CC24,610CFA6E9A4EAF36,0FB5CD93D8F1D977,CF482BAF96B4B354,04644BBD828796D4,00003AA684E501FA,94D213A5E6E6B323,D045636B75484556,E2AD53905BBBC019,8050AE1E7BD676A2,C05D768C1F508166,383FF7075E3B7467,178F034DAC6E763A,1A9AA12BDC7F5F3C,234C01EB5E9853EA,F2D7925B149B5B84,348D4F1F180D28A1,000037C5AA646D55,5D536A84E5FA9EB9,5767286F0EFD0780,BF1A0FE570B85513,3FB6EE556863EF58,99C1231A0F8304F9,3DBCCFFBC1B6DC86,DCD629518F57CA19,783AC8AEEBF69EFC,458B120F5B8031EC,97D5F22E76641DC0,AC2C01A5785F10D6,00000C8E739EB8FB,8FB02FAEEABDA421,38B6A990F335832A,7D7CC254CA66CD59,256D56B23F6AC14B,5E0B18F479A449E1,2AF51BA12A9B7E59,67C339FA9E4723E5,42A8F7FB816E2E34,6A301E9F80CA5EA5,1B7DF2B5A7DE86DE,E90E3784666B0F4E,000020203D8033B3,A3B7A91117367D47,A697D221C31C37F6,6065D4D26B7C0EDD,D8B593B0AAFE99F5,5BE6C2C1E6CEE477,5B385F62A7DD80DE,35EB4386F5A9B181,EF8E6C66A77FE998,BB7D712762B883E8,99F12917A6BF089C,BE493FB913E76E5A,00000EB070111331,86B3FD8F2A3F556F,E20A24AF9AF31288,280F8CDC01065E35,C414198025551EF8,3A8BCE608309A03A,54AB7F5EB02E4D9F,CD69AD9CA4D41F2A,7BCAF7F5C4A7E171,44F50A67835EABEE,399711A1EB4A815E,DE09E1D2B965E78F,000040A5B303528C,3051DC8E43317FB0,0C163449924E859C,49BBD8A383ED3ED3,E864876B612C40CC,5894C874D2B9768A,E43C8C8CE7D1231C,B1FCB1C53E80D0E1,78BF53D07254D7FA,0167CAC34BA35459,929516C3FBA30DCD,782F568A5614A48B,000034C9A472957F,1473C9FDD7747F9D,2A26D2F5EA36D5CE,2CA7E8C949DF638C,FB842138DCBA79B0,D14E0A783F147AC5,9F9335C29904819D,C8B9D16C34D3EB28,930CC0C0702EA8BF,78E4DD909F0CD0ED,25DB917CF9719F14,BA188135FE6378B6,00005920C7127B86,0B12812F3F54D804,42CDFC7AC4876EEC,8C3EEE14F79613BE,5BD9F3E4A61933DD,20F53EFCEFA7ED5E,38899E7B7C5519A6,16BF95FCD1F57E96,A1E5E09E2652C8F6,7A208B7571F0F872,FC8B338D52CD7F12,AB08D52B46A03BCF,000040B2D8523BF7,91217CC8AAB3E9C4,3C35629902FDE13B,133E3D9F7A96B07D,4A318B90A4A29851,7D3D7F1BD0EFE4C6,364F8FFCE9282FAC,2959724D33931064,B80A9DB55873D864,2746DADF327169D1,8E56ADAD693726F3,E828BA490C5D9945,000019DD8A30A653,42D57F7ED738AA39,FEAF9B2CD12D94B1,DC106A0DEBE4AF04,A8BB8F05AA22B75E,E56747EC9ED6B344,991E8BE44D2E0D59,0250389F8C27BEEC,920664803D4C0EC7,901711AA4C0750AA,44DF24E5968257D2,C40CD18C58C6702C,000051C9F05E913D,701C88C5FBBAB83C,3FB94CE92E0A753A,DD315C5C8FE20816,505D2C2604E4DBA2,69E47B60C7E2637B,11479C7A128EF74C,B2B45AF09F2C0093,A3ACA193D2F9AB60,8472D9907276D2EC,FDDB6AD1FDEE08F7,158322C0A1CFFA1F,00003FBD799C59E6,4CF683A741B5079A,7BECDB6EDA0E14A5,5B487F3585062A17,9DE49CA0875EE6D0,A925E4F46D599EB8,202E971D3A0C5A7C,CA6BC783D1A1481D,A5833AC3A25FE401,25FEED04F511E00F,5AD198FF9A941F07,2B1B0A50867D273C,00005F960EEF74BE,3914367515D10FC7,8CD9EB11E1C1F871,316161EA85872A02,9161B9F88562FA72,26CB69668BAC21EC,5DDDC4F88D4DEDA9,3B10CF12EFC3BEAA,407AA507D52697EE,B95508DC271E94F8,C97B95CCCA9FBC76,05D597D72C3AE3A7,0000675FFB4949F9,C3099DC8A1DFB1FC,28E8C8DFD744BD19,7DE9B3411532912F,02B1D1089FEF837A,E8C7158E16A26312,4D18EE876D0B9D56,0198FB7B663B9242,AA27497E6629CF15,4AFB3F18527C1109,4D48E970B8E2CC77,10FD49AE292133E6,000033A58EBE4D7F,5F7A9247DB247D4B,014DB02A9387A9D7,4DFE1B2814246238,77A5B111FD237C06,FCD6224F7F30C315,F43D1722C6562E69,37E26C8C89686BF3,F4302C1B7CD30AA1,CD3A03136F8C4829,3D076BFA30EEB01B,1E92EF8D17977B5B,000045602EF16827,DA325BFA7F89B7A9,735043B3760A63C6,3E9246220C4A6AE0,F6A6DC90966C09C4,E94E5BAD32554EF6,B91A18DAC4314535,5B6F1B19D2FCD324,6A5BBC2283BF7EB5,2AF3107EC07F4623,BF5944A9D3C8D37B,CF452A0EB438BB43,000057C81E925F05,4EDE3C9D52E51D3A,67FD0B6A449D631F,E7D229B5DA6C7C83,704F4A9C93C9DB24,8CC6E2533C849BB9,FB7E0A9C4523C4FA,5545B0C7093072C9,ADB45C731EB05E77,9CEE54B5CA465EC7,6A532B5A5F612FAF,8D11AB8D6FC7B143,0000021CFBE8DF5F,576BAB017D8864AD,EE5B68C007729864,0464226976482AD0,1B8F99DF4EB3F3D7,606007774E5F1445,CD331F2C37E3303F,1C68A1C1AABF462A,63A3E2E4449C9746,0704296252673DA3,6B0504924B3ABEE3,A3FC4C44C8931835,0000471E06E42DB1,2CE7A16C2A46A68A,E56F387F6EBCE729,506F663786AF53D3,D0F59B7CDF3C89AC,16512CF02662FEC9,89524428AD7C7EDB,8E8574236CC66957,DE88F40410B94090,C10AA4A6CA6E5C44,13B78AAF366438AD,820F3B77DF8F8E68,000023FAC561B78E,BA69257F007C2E25,CCC00EB17664C724,6ECF7FC34678611A,D005C98C82A87E49,F22E9545617F350B,2172AA3C3304F082,7209DE48307FB80F,01DA22CC15E5B9F8,2535C30215808463,6149E09AD9567F86,24E9E9089E7ADF60,00006809AEEA0824,51871E49861E61D2,B80BFA75E8874229,A7A071D197049C04,EC1C4BED4D81C828,5BB341867E5BCF9D,D511EC1B6E80DFDE,3957700E8527270A,37623DBA2DA147D7,AD24F946FCAB7CD9,8FA81C242148D424,6DE9E69058C878B5,00001783A07B03CD,AD4D1C25CA0AAEF0,DB4939C2F0926024,4CC9FA66EC67D563,A38E001E24588F9C,3318EDCE6CCC8570,13668BC69AE59304,3956C667EECC6149,BCE5D4FEF814F252,D7320BAFCFAC7E5D,3D37D28B40729B46,072444B95A69F5E5,00001A510C641641,3162DA5E03CFACFC,65C1D64992780E38,4E3A5A66203B3D3D,4114613AB757841A,BE1FB73CD9B78BC5,7B8C8B6FA92D6B79,EA83149BF95CAA89,E46EE7EF16279013,B0BEDEFC125C2D5E,1165B9EB1C154475,D3EDCA2C4D1D0877,00006A9101C7B9E2,0791930A1AF9D0B2,7BBEDF6A2DF4DC8D,F6559D65935EA7B2,9223BA0CEFCC79A7,40276EEEF9C56F21,3150E44BB74DAE6A,7495250A8FA49A2D,A135126E67977EE4,3C0DA2D6918A85A2,2E13C0F25DC82819,71EFB1E683AFBA50,000065E9BB6598CB,7F49D7C6465908F1,A9C7B595CCFE7AB9,0733D1083C28AE4E,76081FC6A952F8D9,1B98483D19FB3EFE,6536D7EBC6F7AC17,C1AADAC965D141CF,A93AE9B0A8550C10,8CEE01B7F8549A2F,5D56B5BF852FC5EF,F3E584FAB47529DE,000000E8EF8B6200,1A181651F3CD2D79,467FB97485A7FA03,9B9FDFF60B1E1BF9,8024B245F150447E,3A1C35C1F0B6378D,47722A46574877A9,64A5C0563D0C88D7,3E33AC8679D31D05,B09FEDF36F4F1CAC,74784848D638C0D4,5F264698330387C7,00000A0D1B2361FB,5893B290F4888693,18958F455864A8F3,E7093BF0DA579D0A,581595B27FD8237B,AFC0D103E65A5EF1,43BF96A33C5E713C,8C967D13B7370580,0853E23B14304A48,8DB4D28F868175DC,80EDB6FBF3C940F6,A2BCE41D7BA231FD,00001BB3CBB18A20,8AA6B40E945E1AD3,333ABCC89787DD42,86F8E2E1820E2A39,F711FE818348BF9A,181CD2E4DFCF2CFB,8DB85939B0C37AAE,F42E775B55F53697,EE5E5FA9CDF741FF,96AD526DE2A5D336,E01FA65A4C038363,9579C6FD7C93F54B,00004AF15D7B2D82,94682569455201AB,7CA141C29FACF975,55EFB63584CB4E73,D984B588A2CC48D8,D39B351A6BD5EFAF,1CA2932A17FD4E3E,CB5888BE9ACDB7E8,9E3DEDB803F10F11,500FF03DF21B0C7B,1AB7813B38E34942,8B828D8583D16CBC,00004CF101092DC3,8AB4C8FEF3B9A230,DDED4721C1DFA7A1,4BE5F2DD43211794,0203D892294B851D,2F614B77C43DBBCA,A24E2B180B367D1E,484A9BA0595574CE,77AF75D6163D3777,C07EAA8C2C1726BC,A9B2948CA57A44B7,6C521288BEBF3C9B,00004B98512E4F71,383B195FDF08A2CE,A8A9067EDEE9C673,6C990C86A2804353,20D0F94E702B071D,5F0899409B9E672F,2FF35AB72424AEF5,4B688011E357FFC8,F1D02A26E0347155,309574D96C9F8217,F2E4C0D32904CB8A,08A61449746549CB,0000118AC6C52368,CF60834DBBF1B184,2DD36F96FD26B9DC,FB90B4166DF986C4,40269E17D1E51271,7DE51005594C2495,66C75929D7251197,EF41F6B93222F01B,BCA7D5F816ED8C28,7EE70E3F03F60150,6AEE683F0C673818,BFD55741206FF5D0,0000528E3008A2A7,1B03D6D3E904479F,A6538FA6E947E8E1,1616E36F1AA27FC6,8A82FDC4A5D5A40F,A57E6B6A86CF503B,C6242E286A3A8BF6,73AE32D7B7FA3D30,4A2BDA7B230E5D85,0C64B1EC2C46C7EE,0DE7AB49E15C7CDD,E69F9DB09E89C937,000023F2E128184D,ECB01F0D67086EBD,E59F685BF2F2A1D3,2771CCB219DB415B,8E9ED31F0340DF31,7F9165A9E11412D5,27E968C81C8E69B8,16DC200400F08C00,EF3DEF9AB06D2A26,148A0FB8F42DABD9,F116E2BAE96162E1,501CEE10DFF62FCC,00003329090E0EFB,439530C26E952F6B,C753D914CEA93DE8,A311E4E5836DECD3,022116060123F404,3B36323C3F2C13CF,5858271754989174,2ABDFC4E9C9EC60A,4651DF37D024FD94,7E8F5882363EDC7F,01A6137D2D46EFC5,F9678AE5710EA302,0000045E2E03FD60,0DAF0D6F008C5D1E,0BCBA35E349ADB83,6045FC9BF33AC253,2A55028379869FBC,EC228CB671B11123,9F8D5C15A2D47445,8CC045BD62975307,60DA1647009FC8B9,44969767260F39F7,7771CC412459B45D,5BA76C9CEBC2B849,0000243D4E459591,5E078CD9BD91CA6F,6C980868D6D0F205,169EBEC4280767BC,1521AE11F466DEBD,E5895DA94E69BA20,8DB62AE329E63AB3,A3FEE62FA6C32248,4941724575FBF2BB,82A4363A04D380F1,A1A8DAF36AD922D3,9187E793843850A6,000046CFE0C2178A,B0E0AC3B8DD79C9D,BC3CFC8D60C8E171,A992BE105CC883C2,805D8BC670AA372F,0098EE22B9C81020,413E67A0C7E3ABAD,612BF6721FB71C69,8FB16D4EE1E17E0E,565A8573BDE9E916,FE5230171E0E7EA9,1164365AD5FB2119,0000269E61C35D03,EAB320D45D37DB6B,7B53399061318975,25A1118C8D0B7D43,88364839545F0870,1B323B92C9A7EFF3,83191383CB22793A,D290124C15B34265,9E43609074A7B3CD,90A02AA3FAB7E2BE,73A6C6D5D65591B9,5FE1CCC23DB23AFD,000044D0965E5402,D546374536E6389A,DD2FD4C2EEE16C2F,1BD069E6AEBD1816,FD8E5B5B9DB261DF,49A8587D5994792A,A85B9FBEA0E652A2,3FE675018ADC6A5A,742D94E5D435935F,7C8B41D67AB5F1BB,4F22CDDAFC9D8745,80545EDC8012707A,000054968AA29D0F,389180898A7674EB,6F1B9373158E872F,CB65BAB2827EB710,090EB8BFA4F3F0CC,B65AC324506026F4,F94198A91E8B2257,F605F3E6CE4F5606,19D12646F70C87AF,7981BF2134DC0038,25EE8F9FFAB7B847,6B6527FAD4485EA8,00001CAA0F9E6A16,3FFDC613C66F30E6,716BF9861408062A,A895B1CE8C147604,9059983635956D75,06102DC05367C89F,34B0CDFA76B37BE4,89C240321970E582,4A80F3285E3356FB,CC65D66D6A96973F,EC0B60B7117758D2,CADAF769492437FE,00000A78E2010B8E,51BF00AD1379E8D6,937B3CB4E00B5912,24904D68860747A7,56B549D4C103C7DA,BAC6A3F725698FCE,968D04E42E6C1453,6771575FB3CE7945,CAB593B275BC7322,EF9061428DFEF126,5B7857831F8E2C3B,7EA297E7D61D6D9E,00000C0A10FF6E43,63A900E04C8E1667,8A9611C626A0752A,FC2C52C91FAC0936,9BD556FFFD2F4F21,DDC88E9FCBB993B4,2AB6B1CFF4FC72DD,B8E38FBDECBF2C56,BDF356EA701D70BD,DB2C56D4CD8A32F8,52B429A27222DB31,AF9C9EFCD318F68C,000034E5EA39BA06,A053CA6ECBA2E111,FB84EC574467C030,9CE56EFEFFBE9353,F484DC55EF300A48,1C9B89CC292C1D63,1BE6E932B1EEBD76,EF3F90B525DF215A,89AB0FBE0551B4B2,87408A0FE34F5D9F,717C2E2403D7CB89,FDDB7050B196D147,000017B90ED39D3A,4C75BCA2A96D2822,0D9E7A9DFF4E8CD1,0295BC8E27DC9827,7DE45043CD7BC51E,7331E2EF73CF8689,0F97792D1BBCA144,4BEF2C2E6D1C7050,FF52C72DA70F177E,46DD930B0012D5A2,99DAD6BA242354F4,BBB75D97082C2015,00000F9BC251F5D3,A8B4E04306D7252F,890008088064561A,8346BF250ED6D16C,ED42AB36F16DAA50,9B426D7B13DAA26B,AF2117E7828EBB7B,F42A2A3A4D980BA6,9300692B874A12E0,7159638304C92702,EA1FC760247718F8,68928FBAE3E02A01,00003151C02C5D4B,D8034E241E5D6EAA,01D839215D7EC90E,34A21D6B15DBD311,5FEEC15989F6EE26,AE8AF94E25FBF6C9,94440878A4A1BC89,A0FEF995405DD99F,2A4000DFC8C94B0E,F91D9BBF39A57C6A,6C55836BFFFFCAD1,23685F6D71B5003A,000030BCED3D5ADC,1D652F62B049E1DF,0D15E0BCA7741D57,B7D84D23D16010DB,6581FE095109BD1F,8D82AA2916DD384E,87646B0CB04D74D9,AACEE6C4FA3BE937,A404D612C4AF7959,65FCDFB6D7B80507,97EF07D62FB09D75,1EC84993E0DF3015,000017C3B0B9C4E3,E4AE34F8BD7ABB37,552B400692D45029,37478108D6706E0C,AD13C48DCA6B44AF,17EECD4B323B3DDA,5B5BA6E104877815,0A321831919FBC04,B7F7434C1D2B333F,C7960F6E10862E2E,F138E4A40C12B437,89002CC09CE2F808,00004D476EE7EA25,1298C8FB732ACBB9,7F5B47D978895A04,E7F3932860800E0B,4206AFAAAB37C4EC,78398B5B4508B4FB,7EB968694E4BFC77,C7E527CB583FE080,987165EB0FC0901B,AA7A9F385EE44EC6,BCD80B89794669A5,EA7675CF128DAD8F,00005967FBA37882,31280118E4D6FD20,4C5E58D817E2BD67,61AAB9F128A71A70,828BAECEF1B43114,7D6F2366A3A732E7,DF1AD610CBE07669,2E0A007E99ADCBFC,CBFD0889DADF7231,1C2DB3444043229D,09B8BD3A70A3FDEA,2E564C680961EC67,0000364783CA1C0B,CBAF425B78D2A075,0144B8D1E228D69E,EB14A1EBACBB321F,6DDB366067AC8FF7,5034EDA9D0490016,16F1BDE6D7F61A20,213BEE515A5ECFC2,0146E6B5429BB104,9F7EFF7B67BC47E2,35DAD691B03A6A1E,7843ECE9E0EC4924,00006544AA335C5A,E69FAB6DB2E7CA16,419877254242642D,73072A299FD8F4B8,D1F1BDEA37ABD611,6D7C9BA725662CA7,43C78A45703CC147,A6FD674F7025D105,50F1BB344807512E,765025453F7B9DD2,839798F3417645F7,AC4F1F9B7CE25C6B,000057F0ADDB28FE,D029BADE36B717BE,59D7D38276484DF4,284B285927FD3E31,1FD4FD1DF7167453,AF84C5BFD768E65A,01918086C6D1672F,8470AEFBBAF9AB45,B4B0CAF857F99A4E,59FB2151CF6EC351,69FA3C7A07C100D3,7EE74CD7B04C3F99,0000308250BBD5E9,02FC4B5D0AED849C,6F314B43BA5301BB,9F8590005151D2E4,E7B77920671F39D6,83DC2F1047068F8C,E2AC5AF1CD54AA9A,08E26B0F47B07C97,DC40B4D0ADF27C1D,01D7169F248A7515,364833E2BE32BA45,29CC295EC15B6774,00001079F831F381,7CC741FC17FC5408,528CB8B9C3D0C8AC,1360E148485179F9,A808CB539B7C430E,140C52ACB8EC0F1B,7A4170B7B303AFCD,F93F482A0E0F1874,2DE50BE9C8434580,CBD35D02095751C6,1EE9DEC726F889A2,6D60E7E2A0C8F372,0000420360DD9A4B,EBF223A3B2C949C2,395AA9A1E6D33F88,02718CF689AAD1AD,E543E3836800D930,045F2E8D63CD8F1A,A4D6554B96BCA438,F525120C27876700,87163D6959AF1A26,0660845CA1A6ED30,8C7C81BADE7954E7,FE2D1FCDEB1BCB8C,00000A54B8C551C5,FDE75DEA1C274793,59D14E78EDDFB835,6309842E76D249E3,B7F6058C83D3E1C7,83CA9BF56385E6CB,6AACC200E791FB4C,3969E01AF573A853,E1C1336F41156E47,ACE897F9CCCFBE6C,8CDE035B1E6AD4E1,66F70DF27160B6CC,00003F40A3EC3072,BE64B98C8578B709,75DFBFADF367E67C,CCED3A5C40EB427D,B621652547904129,40CFA76FA21E6357,9F5782344EE8CE6F,268123E83CA3FDC5,886E18D6B7002CE1,C7B21E3674F4B41D,81C085E17D3F6AD6,BA53292A7ED8A97A,0000095DF2DBE19D,F557097A8C812C25,2C45A768BC66A936,446C5C81D84AD7EE,0A33BB4C29657BB9,28B1A2FEADF8323A,200C6643B145E1A4,60962635492E5E7D,92BD3C49D841E365,77DAB0CA193C2A6A,2915D009CA130456,6F57D4CE9BF10447,0000303C47ADC7AE,BFB8E866B2450285,C1E245A2F3B2DA7A,1D7042248B0C4B90,7550CD98A5B01C7C,74EE8E5567F56481,17432E5554B16418,8A293A403944C72C,66A8B806596DD155,E3D39A12F66C029F,1DB16E1227118453,7D570903DFC2F597,0000008F30DCD8BA,88AD03F3E5E0A2E8,359BB9C87130DECC,85C633331112BD5E,FB3478699A6376E7,F97BED5C0A131D2D,8118B550E2E5E6D4,24C0F9F1D0902E02,F103DAF7AD45536B,E63FEC887B8AF4EA,2686C81BC68BCCBD,BA3F8DC17BB40BF9,00002C452E75B6A0,4AADED21B17B6296,61B2B3E3897637FE,EF661EFA5BCE6033,0B067C2A62E8A63D,CB5A6CB84372CEB0,161546CF9E4EB891,BCDF448C9E9DB938,40A455A63F384D85,3E27CDE2573AEFC1,14FFCE25E87B2731,762876350B5400EB,000001EA261526CE,29DA0472217C7015,669BE627CA08C8DE,E286A64FB7C98065,4B621C6EFCC309CD,77D931B84648791D,AA4B0233E8B60142,61B12ABAECB3F58B,C82731651558A8EC,D41172360976CAAA,FD321752D25C8635,5F1E5C578799F924,00005B760B68A0B8,073E88B03635E42B,3F155D09694BD02F,7BB138BFC03918D2,89CD9F8C9C19B8CB,C8275EFF1075BD38,B3D4412176014DB8,5F2D453CF0BF3534,6338F6CD9F043333,217DB6AA1C8220E5,228B3C3B4555C74C,E4325A8A2F6C9720,00005A058EBA6D01,0B5F19C1BD047868,9A3F61107C57575E,F5DF702056BD8317,433ED5DF70DA79B7,1AEE7D6891A9DE62,372DA045B94CE0F9,C9F8EB66CDCAD30E,5282D22EDB92399E,2D9886AB2119E280,C41C4D5EA346485E,B03EE89A0613DB41,0000012B0FD342C2,3DC9AC556F57F2FE,0F9036EBE8C54EBD,7C9A8052062F0BD7,60810B8CCC642EDD,4D01FD0AFF457E9E,9A8234B7409D276B,DBA671D6668D6BE7,5CD71C5B57326622,A6CFC6A69C84578C,6691ABC231C40783,8B5A8EE0B0B14373,00005B1BA463C09A,60FD80F322126FB7,8DEBF6C1E93D3C35,2661673799A30FAC,C85EE2ED62D8FC84,90C4FD3A7B6E3C01,020D14022E05E612,65393EFC3AD6B6A9,DB907219FF297838,AB678A98BEC5F54A,2D3E1C40E31C2F48,EE6366CFA648BBE5,00004561F236A5D7,0FD048D127ED371C,192527CB3418B94C,1817B79AE546CBB5,6A67D7132FC17C90,6E9A4E73C03075D5,35CBDAB850FC8B4C,FC13EF726AC404EA,4ADC6CE82A8B7AF9,9DA664DEF6211489,1C88E139A3EC5F93,8EEB19C4544976E3,00005652AFD412E9,91AAA603FEFAF564,7F3E1C53DE268E52,2A55DBC5B4702A5E,68DE2BDDC1E3228D,CA96E19213B28660,83E31A21757AD0EB,5EE587C67E359087,01DD16CFDF57BF57,1FB3665678A5CCFA,BB62A1EB145D388F,200A1CD55073D932,000001B1E20522B4,CF00499286CDFF3A,52CA3D5AD5CF1569,514F85F2809EDC3C,3C9630C8831AD299,124D63E913867125,527EAB729635C3F5,91441E130C79FE46,86EBBC4935231090,54061DE4CB08A7B7,F26291458600EE55,0E6745BA2D1C1E88,00003B7757371B1B,8E8C1075D72986AE,D1BC7D83B4471D4F,922BC9FADFCEAA35,F81FD071EAF1C156,28FF8D272F1CE72A,50BC235116760AEA,143B00310174C3FF,28BB3F7E02C2A06C,49822244F820313E,E70F24A7339636AD,E7EF21CDC9D3E0B8,00001079180686CB,E18867327A5E41D0,86A6A31419F51563,79FC10E3EE70491F,6E6B04D662D38865,259F4132877128B8,A25D0FFDA5D7334B,CB45704C0FFF2E38,B3F136711F87388F,5E60EC32CE547F4E,CD34E1D3F953241F,3AB0195B86FDEAA7,000023B09EB21B37,209E7DB5DA7DB661,E197D6B780F6234A,F25DF3E8636EEAD9,E0028E623A464AE0,C6126F340B490762,A7494165BD03D792,6618F9BAC8D68AAC,68D5281B59BEA487,994D8DDFCFC9C4E5,8BDCC2B17CCCC25A,B10668999EB79999,0000466CD21B0330,964650AE304C3D39,DE80D6A3BC33D1FD,246FE6612379F3DD,0C2028B6CC592242,D87194FC6AF431EA,31163447004D5418,56BD946A668E46A6,3438EBF2B8DF177A,474651B1399F63D8,364350FC10726F74,0FCDF68DE2E2B2AC,00002DEFECAC70A2,9E9B8C86A24C9FE8,F2EF3C8F05115E98,7E13015FA4CDF8A9,57E1E6E818132EAC,A31DF522A03CA055,1DCDFD4B679DBF67,7A3BF06DA5FCF761,20E716090F07DDBC,A0D4571A9B9F7B4C,59F950790A2AD3B4,0E5603EE00EA6B15,000039693B982952,4DC33790F422AFA0,AF547C6D6E498F2F,38163DCC7181D743,9327086D773433CE,545501357D6BB752,163C06655240ABA2,CAA315A7493B583A,6840E067E9BE047B,5EA7A02B5A9F3FAA,9A49490D994E33CE,D03CBD9667AAA38C,00005CA646729534,41142928295CDC3B,C8864AA643AFF43C,4129193F2CF10FA3,DE1F1BBE9ACD5CC0,7D12B127DDA9920D,CC189425CB1A027B,68BE17F018520DCE,A573E0A78303EBDE,DFA921A41B4C1941,7EC8CA45635C59D2,1F0A36FABF193650,000026190F93B13F,02B83E966977C6EB,FFD44C3FE17D81DC,9236A5B6F44B160B,A991D74D1039B41C,E6CCD07CE3D7ED1D,862A2BEC135C0891,B2FC60007CEA85A6,2E34743AF81433A6,B0FAF195B7663C08,2421EC34F9CFBE02,F3018E31B2FD4B65,00006ACECCE7D858,FA7CD4ABCE02D373,8FCD4E1519E6276F,84C2FE07AFA1F1EF,6D28A892A3778D2D,890B26ED03AF60D6,DE6A84D971A13602,F4D65965CFE4218A,7FDD96F0D3995E73,D803B8455CF52CC5,B9D1E655566275F2,0D35CEE2BAD9BE4F,000005AAF982B24F,306E6ED5472419F1,DD8859F5964A43EE,28D6EA99F07FC9CF,E51BFD1B9BAE9203,88601696FBC6F234,A19679E61162D963,4408D2A9C22FD74B,6095F765E1A74124,DA4592832C62A71D,A46825C040421E38,81A6D52113F3F2FD,000034BBE2B6771C,8A4E73D212E7A1DC,0848B67938B22540,23D355DCFF3AE75A,33CAB358E1A09BD4,1F4B6987C2041EB4,F4DE74CAD769933E,49F28D8D81B58492,A8C96BA0183BE262,EAA23926B646D22A,9D59AC21175D2C40,29DD1077C8BB5E9E,000035981FA98640,78E62FB5333321B8,01F801796C26C806,04810D4182DDA7EE,89426979CF967514,361297B7B97E4908,E310E3F3AC968D9F,0BBAF6F6003983FB,1D892CF447E05CDE,98D981F4531680C7,9FD5E10B341EE8A5,13645705F9E6360B,000069E026B5D1A7,2E52A314DFEEAD53,34835EEBE657CB9A,3042E1C5D0F7BA39,D1AAD764C0980637,CEC227FD0C6F5E3E,2C16D1CA8EBB6DD7,6CB0A646670D5572,95B5853F0191AAE8,8E5E5428A3A9586B,564F63BBF775E1BA,E3BD39EC850D5834,000069342FBEDDD4,DD340A27B70C4B05,9F14692E4E4A3136,84BEF83D446DE5AE,3094F012ACA26715,B2D0D2F46FB3C45F,3276807F844450AF,50EA523BCEB76599,ABFFF522D153C063,0514416773565A84,F6E422DA17F50B29,BC817E3C3E3EC23C,000021F67734F8E7,C0F6DCD0CF07278B,C91032848A4786E0,FC2C0E5E0C2A7185,939A78A35D8CBDC2,A74A1A1DBFAEE71A,86C20FE7CE719B84,503D7A48A0B86183,4B103CA91FDC8B0F,B5706471F79C9AA4,F30C7875B6B4A7AA,60B7423F5B2CF90A,000058C4CCBF61B8,345687955B493E97,EBD6D279EF66036A,9A839E1D040984DE,F9C030CA6BDA70F4,07445E4BDFE174EF,7DAD28A54231C407,8AE1C121F34E963B,949F42F0782B9699,3793E302B8955EC9,39CDB10ED4C2132F,FCD06F6BF79B0272,000058320CBC96E1,9BB3F8F52803DCD8,ECD5FC9125A5ECF3,76D1724B7D57A9C0,CA309AB42F9C2719,43A796AA78ECC726,5510B52EFBEE000C,20DDF72B819B31AB,83A604A3EE05628A,29ADD3F7C5EB37D4,2554435FA7254030,F68EF3F7BCD26D19,00001F1C7339B59A,E33CCF49A6870E7B,666DBA8EF0AF89CA,7220030D1BE353F2,0D523E68786B841E,356A35C38802D9F9,7838519BE273B350,DD979C8D2D6B5641,A7FF84451C868FA2,9888C1D5024C29B4,E21DCA270DABC400,41643C77EE439649,0000270ECB2F9C64,8A4BED0E10373384,C4003611296A9D24,AE0781605C4710C4,9B454C1E33B5FBDB,802EC9FA051268E3,07964EAAE4B5C2B9,C3056E61FE37D7EC,AB2467D071312FD0,90761AB2D743CD1C,BDC5E04465CAD9E2,84B6915E1C2B2A3B,00001A04176CCC35,0B5D6C2840115C10,9DEB89156954F456,9675D6C52D46CB37,376D411ECB2200FB,4BD7EFC9533B84C3,633FB616AC78BEA0,E39AA0F85C7AEC33,7B4CE839864AEEFA,84C2CDA558E9A02B,C248E550F4717A5F,5AFBB5A11038C105,0000561973138E86,B697B668372643A7,F95D38DC6A52FD2A,9124F215D2C305BA,2F565050648FF73B,9A908C382D87DE95,3C88A5AE05EEC962,8AB893F91C361BD4,4E67251C4DB56411,BA3524F6C190CF97,77D4D58E97E3BEB9,6D1D8D505B6BA544,00005F9C286F829E,167A57D866930829,2AC531D2F131AA76,FDFA74D468B0315F,F856D6E089E66B91,0633BA4420259C18,CA1658BFF041ED99,6F939DD2858FB2BA,BB7E329877E5B0AF,14B7A28C91E7C426,BAFCFD6C28F81A2D,856B22985847A682,00006C6461312845,FFC76015991FB6F6,F8A452D688F95175,93DC14430D628892,93BEE6349FBF193A,444198B24921963A,07E1F69661D3C658,474F888BD9EB035E,233E5A9685796F86,E0B7F3EA0ED8976D,D0DCCF041FCAD644,A62C631A986C44D0,00005ED82032CF36,D7DE99B906E1F070,37FCB6C3127FAB3F,D71E4FD9800E66BA,BFC788D858897AD0,431969C3D9DF3216,5141AC67C136BB8A,F1F9B66442D72E12,41D726F2EA6C0B63,4FB75DAA0475F2F0,36479DCBC1086140,86A7C1CE20DBC628,0000134D217B570E,F33C1675E5D66C68,F6A9211D1EAE7F73,442F6CBB082A7546,9663050863A20E35,BA832464A4C94FC0,4562AD94D828EA51,F64DA4F4636A4BFC,EE85BC28117F63E4,62A8C948BBDFBC03,B053F7B82D0282E9,DDEECEE6F01E108D,00006E2605D983E2,035D54942FF98362,741FC6EE38058E07,1ABE6B370082CD2F,C9A7EB71069085CB,4E785B609A82CDA2,972FB523C73D5292,278BED86A6EF55FA,A4AB6F681290C653,912D754D263E862D,C7EC894306977212,78BB5B6CF60CDB5A,000004BF9F7B9F49,05D013F2D4132A32,871C30ECE118E3B2,C725459966BCE0A3,BF6C6EB9E2B6172E,06C102F5B52A09C9,2139765C66211042,B9309C61596D20F5,4D9C8763A3F65595,75291BD5C2C12A54,DF7DDFBA548D281B,C21E31F9AD7503B1,0000456DEA72992F,90FEE882DBB34FA7,6CFA560895D74D96,9C652047D837D8E8,2C05643A0F292C08,9F66A1F7BB0958DE,F4CA90B8C87C5E3D,EE9B2C634EA2077D,4CA4F01931766621,17E865A55C0EF58C,CB1649E521650644,1DE04FBE3A8E3047,000045D2F84AFCFC,008BEB1A69D2B613,7F436381F5B327F0,8790D979D7890873,F002026ACB7F5E9E,B67355231E8C77E9,5B359CA511B9576D,DFED7407464B2334,8003BFE0E7AB0673,5E0BCBFAC357787C,47908E38663EEA8C,45D627BAE2D584F6,000036EC780F402C,23AE05B815703408,E0D018F2A318BF47,7414D598EAAFB7AA,D0389B46E13F721C,7E886CE9FAB3709B,18ED55AC1FCB1F2A,4D34A16418201B21,8AB47F444FCF9C56,D04B3584D2E129B8,FC837E89351C8D89,53E4AE891018870C,00006A2891B57D2B,CDBCBC8C19935B5A,C163C4CA264A567E,314C60EB5D408321,E13E79CC43DA6855,F5BF570C28EDA478,02B6B43FFCBA847C,C22E2799573241A9,D3DBDD2B2A0844E8,4F0F2EC2D664B2C3,E6753C47A9C22A59,5402856C8BA1C233,00000AFC9E8351DC,F9E7F0074D18DC4F,87597B136DC89996,AA97770948A0F3BB,B8CD2279861BADFE,51E2C590C2622E47,DB27E7A8A1DE1C74,D255BB5550CBFF42,65F9F70C2E7D91CC,2131CC2ACBB07595,9ED244F053C423AE,E59F20163CB2B772,00000B1DEB2AEE96,2D7A68BB176EC187,518D4CC2AB819C23,25D201220A210286,519BD50AEA487A79,CAA50794DCF09CF3,B892A338C876B99B,529A2BAAEBDC0274,37DF4540C1A6A5D8,85CA6857EC8B573C,D0EF053B22EBD8DC,C18FA596371C8B3D,000013825AA0382C,28111AB3D3725ADB,628F278ED6258BE6,BDC05E534777984E,7E768F44B9222211,19AA80E796AFA4AE,916CD81ACDFA5624,15F45BEE8FBDFEA4,A4E6FD89D61E8EEC,7D6516EC99146810,DF8512CF905957B0,D85D94B158FFE97C,000046D23E263139,082BF2C772FD1711,F6E6BEA61D651A4E,D0F36FDC17CEC863,19E9D37D216BAC8B,E18C2585E81355F5,43812D0DC9F7D664,E47800DED322CDD2,5D70A433D29AF2A6,56F6E4DE6BAAD4C8,BA94019630F93A0F,8BBA63A7EB6218C3,00001D4F0B5E9FE0,F8E1BA352922D154,8A9D11171CEFD81E,5913CE50D8F03810,9842C2B973C376C0,93C7D2BBBC9498CF,2D80A2D8D2F5EA15,43A64CF4E007AEA6,6EF44A61F1E6E8C5,4A835E9F96407513,435C53F5E3D17313,1428BD39B04571E3,00004F2BF5D7E5B7,BFBEB5174EEE202F,AF4C3F7BD2733C96,FA62C1FF70401306,732741BF5110EE3D,4A86EDA691C6BF84,859256BB74DA4C6C,DD34B520122FD906,965D3D48569E7A9B,6999F0FBB24C898F,2B02F28886443222,15B21BB73C573E0A,00003389E8531602,E3D43A6E771EF0AE,9ADA1010F9960F32,7ABD7CF0E652DC67,84FAE9712663D64C,4190A52FD93388A6,DF5CCB466D579803,13FDDDFB80C160F6,9AEFBD451F7F2480,F4C67E2AF6C90E8F,E4A6EAFA452F0087,1D671F21045CED94,00002C2542A04468,0AF714655744E7C0,BF09E4E192F46FFD,BE4B439CFC1F5E0D,DC7F3E25A530AF11,65DA5DAF59062416,FF7468C48FC35862,CC9EB3AE68D4FE71,82402984C6D2C47D,3C6F2F6C1762B765,A6567959C5530A43,FB5844573A199514,000024D2AB3D4BC4,386927B998182BE6,9CCA0E2354E0C222,B633710F131C4064,68171AFB9EA02767,BD1A85402E575808,D684470BA061BE89,80A9B1EDC6FAC35C,7FEC47594D1C4456,E331C42B319C0653,D646FD665CEF0DAC,35C6F7E4791467B7,0000010B676AAB62,68A3FD0C8379A2C6,16155F04C0FB3900,E2E9B0BFAA2CD444,0F03F8CF53D6FBD2,D95C078C765FF4C2,529BEE072845E6F4,2BC5FE7677938232,54D20A6C234FA6B8,26FC3AC49B012FA3,1E7E7708EA853417,50D9E26647DDF9ED,000012E3E846796D,FE15FD776E15DF21,FA4054867E968EAE,7F1D11E8E517B2B1,8DCEFA40479DFF3D,04B88602AC1EA9A2,F24E72679B952449,51485AA34ECC6A70,04EAA6CB8D2130C9,CEAF6FFA5493CED3,BE0D8887380DACBD,3F21992D1F89B84C,000001BC377B2427,CDCC7BD1D4EDDE7D,235660CCC99871F4,F4543749F14788F8,8CB83D97B69A74DC,FAA1DAD807C88B16,3D68EF59C6ACD329,87855E7832E3DFAB,184CF4B5C2228975,160BF8989FB84FEE,935E3397C669CAE3,E9A7F2B4970683BA,00003174D2F7B511,6A48DB4C4C8454DD,E75A68AE8FB9948E,48D0AE970F10D20D,E1605B21C77AB71A,22CFDCFFC02A95C8,87120B9E7A82D8D4,181A2E70E642CB9F,F2BF400BED97EB33,A5AD639BAB08B908,1A88BA9055C463B1,9FAC5D79CB04EAF7,00004F7DBAB2FD58,81F92ED1B74CC4BF,B4165F0891DC5FF1,8AED1DFA3BFA7770,72507611F9C3AB26,B45C6C95E4A7A29D,E7E301F2F69A4233,B53EF31FEA305FF3,F87E11D2B4E50A8C,A48D0221F643015E,A49D225E20DC379B,EBBDE24EB341D41E,0000261E18EE4572,C3477D76AF61F08A,EA85B5AD0DC92665,AA2B09E43F499CDC,9BC6D275C3BF9D9C,C77474242BC18222,5FA3225491E98C4F,FB0DBEE3E7B23ADD,343F5ACD746C61C0,3B8FE8D5319199D7,B5C7437A085F93C6,9E1DB099C14ACADF,00006BC4F0CBA527,FACAF9D76A664A22,A97AFED0185820D4,40F3A6D51809604D,6849BDE75208442D,4E9793313A13D9EE,366E1604160C92E0,A784E2CAADA41DA4,BF83D98C596B17EA,E2D744CCBF2C9E9D,D484FE434B6D4DBE,56D6D96529091604,00000675A0F180C9,8A433F5661F81F60,4292F555F30E64D5,B4C1D4D88A2FE25B,30915FBF7C4C2E42,CEB03271386832B5,64FBB11A4546DA92,BAF631B7BCFFC05D,45687B2D0D3E5025,2ECE04C16F203C82,6245066291592A88,D886C19A63853909,000046C8F896163C,2BDAF48E891A4C91,66A61562DC37025B,0837DAD4A7965084,55565F32A85C369F,039C246AE4F08567,9830CE9C1D85DE12,A604E17193004F09,8948A2F8DE7E9D70,99B2DB0495E43B1E,797D8FAA1A3C2019,519E61EB771500BD,0000677E74FD47E5,F67D6BC438011E80,D68352F6B40E7A72,F7BAAC487E41F828,B6CA70E43A34C118,DFE5EE2C16B63050,993A0C211BD0C6B8,4021BA56E3712AF0,C3CAC1939DE1B813,E57148D96024A040,DED918E5872A36E4,6E47DF720E579DED,0000490950E5E453,641C7876BFCAECC4,BC017020AD278B6F,F7F9503D1AE13181,0ED584BD0EFEE6B9,B2F4B7A2BD28D43B,D958FB31FF9FB8A2,C1A6A41CDDAE5579,FDA63AB2D4A6067F,A11A8A29B404EDB3,E306AAD1DC85ED13,D4101E417EBA534B,0000626CB9F9FBE1,44A5DBA5D80D7EF9,862DC4141BC1BC4E,C52C1559D7A17A51,4E027CA54C1659E1,1B161326F4A46194,B30D2BEECA47797C,5CA3C18EB41C5738,A74DD5499C7757E2,B3EE7AD876A23E21,C8EF5456E29EF594,69BF83854D6242E6,00004CDE35F5EDF5,A83B69C70C6D2548,5F810C176B04F0D8,10973853307AA19E,8C3A94ADD9DBF546,D8F4227AC5286F45,2C72E4CF9CCFA9DB,B8AE4CD91EC8E88A,2B6450AC52DB65B3,058CDD9444999F1D,5FB83C313589E3CA,A0F34EA3442C150F,00001A66C244C950,A88E7A482CF77158,9A8752C3BBD7268D,5DF2309237EE0820,E3589F2EDFB0B5F0,3AA5A6732C694375,C82A8B77290D5859,78FA82E453604E5C,DEC5BEEC4D5D8BCC,0C35D084751F0FBD,2549A2620A43A02F,A1A55202D40133B4,00006941B7936A8D,853AB53960659057,5BBF380C70363DDB,A7E3CD91CEE69518,769DF6C6B910882F,B4DF7574B0830E07,13EB6CE81B405060,3BF971776993BE8C,EA0B89E22122BCB8,D1562D5FB0102DEF,0BAFBF2C41841394,D7E4813C03965CB6,0000416646EF2B93,C57F3B0116D2DA58,5FCAE631B2144E53,5C880B9270DA5AF6,AFDD6AA88D0809BF,69E462EBD6163822,A5F80C90CDC903CB,DCBF64FF64E914A1,4446C98F9B28FD31,43D34A4286EBEDF4,BE6E0362CD55D94D,7C1DCCE6314F593A,00006B36B61159F5,01119772B853F19D,031DA79F14D29FCB,F9DA9E1760CCF15B,230B1C6535A25330,A2B34277EBA15D08,EB5D5773690BC5F2,9C5487F7B153D2FB,E307FABB09F51CBF,5EC7F1D1439A4325,4BA39AC8E0536DDE,56737D0B9D1B878F,0000285510454848,DB890B674BED1361,104239F7D5E4FB62,377EFED34237AEDD,E00DBF726BC0D563,15B8A15D45248521,396ECB8C8754B3E2,3370C3A72718D1CB,5E28F33F8275C25A,DD4775D5A1C58912,3275A2DDAE16EDF1,A4445F2E8F5AB1F0,00001FC35C57037E,D3B8A9A33C76EA7F,D4D0ED69ECD3C08F,3E60F95CDFB1F739,B9E7DF674D7628BD,A32DE4ABB22FB64E,D518E6F3FBFD572B,72121C652E7CC05B,413D123B14AC6420,087F1E909BC1CD33,44ED12FA68635392,7DD4778600E36F17,00003B4E171EC415,3DC2FB53C65E6A52,2C6D032B6C9AF05C,C258E33EACA06505,7D9BA0DC22E531AF,24B0B87D3D55645C,E1DADA5F4865CFD5,94ED6D0B5961B52D,B3B61E7ADBD87573,525210A5DFFF8492,07E141C69A8EB4B3,4C3FB0D37447A34B,00006D925F58F1D8,A82E6C003F437038,EAABA32EEBD8B892,7C3F422EB5A29433,2964C70F12942B7A,63AB90A43D5B9383,4389B95113C39A07,44CB2F157D78A78E,CE51925885B1B53A,C829EF9DC8F9E166,F615FE2A0198C7F1,B1D1E1D7B40B2DA2,00005C6509E39F68,44ADD1225CDECDE6,DBC9141EAB330A48,BBE0A5AA7418E99D,A3EF6C97485CCA42,53D33212D472B469,0CF636A2CBFF56CA,45FAF365D5E597CB,808EA484DBCA1F9C,318FDF361E5DDA4F,4486A1EEE6EFC844,4264231D1230DE92,00005643E12F7BCB,8F79C7949E6108AB,F8361A1FB3436647,ECACD685FCFE6E38,FD593B233DAED3CF,307C7E65ED95FED4,F48C48FC2BD39F15,8952CD2CF8B8E212,E5240090971762BE,9DD68197C8F53CB6,CD04184284E416B9,B2A2D03E9A96AA7F,00003BF4140C68C1,2D708EADAA774B72,2E061246F4B50CA7,DECCCB46C42B7CBB,F7D61BC15CD030EB,BDD222DC06F2BD3F,E9E3ABB3823A66E0,3DF8FB8E07B45A98,2F7D0F8F24771268,532D83AC18F65FFE,7F4D94D0F69A55B9,717A6407F7C274B6,00001452336B5D87,BE954446226CE3D4,B10C0AB0BF807CA3,DFEF434F13EC4FE6,8211D09A85F604BC,823FB8010AAA5CC8,B953A862C8DC36B7,CBF7BE1C28803216,B6737CD1C851F70A,E04A3D805D4E862D,77089D43668BDA27,7FFEDC5ECDDB572F,00006EA4B0FE6CD5,BB415AA7517396C6,C0F55847D19031DB,7995D5B555A5EF30,A4C027ABD4F74807,6DCC873939B48337,1BFDA61751737D0E,1BE12BACD6D4589C,D33BDAA8378BBC46,A16E310470E7A940,067BC1AED8CF0160,D4A102AE6C59F3CC,0000658957EE0480,EA11DE7CDAD5D770,9B967321FA920BD3,2B106C508EA7C109,43D695651C193124,9FCBC541D622209F,BCC4C42F31B17F8D,15AB7075C019F7D5,530AAF428C9CF300,B1DAFB74FFDE20A1,48F15E63CD0345EB,D5E680A761F5AFC2,0000365FFE425CDF,67E9CF36075AFE2B,26CFF3DD1161607C,9903FC3A82547CA8,86580FD92816F2B8,DFFA3307BAD9E1B2,922A541D3587335D,E3DDB2AFD8E50A0B,B6A609B5D78854EC,EA5B414B5EEDD613,C9ED0149C4B6E2EC,29BEE31FF8FE589B,00005469450DE18A,108A179FDDC434DB,148D72D4F6F60DCB,0F9D50C8880A3E30,E98E3C15C3AF03DC,69BCABA7257389D3,A649967C8CFDDF6F,8DD36D686BA71F9D,BCE7A448AF3EC82E,CE63E5C42C375413,5863F6D9D0110E9E,84D1B9F0A0CA3258,000046E7C10D1C98,AC893128B0DDD240,2F8F0F948F50587B,E5FE0BEBC57B05F9,A1A97CA847127080,CA67FF91DA89F6AE,8B1C179C9D307B7F,484A1E65D25AAF81,C6E0E8B7D396034D,B624DB35E88C8BB5,B82B18E76429D94D,07C4814BDE080E6E,0000462C478493CD,FC24AFB0411D7C71,13AC468878C6DC9A,C39A13B11FED43A7,2D0FB186E67F94D0,C1F5DFC00CBC6AAF,65685AC0F33B72A2,4314BC745495D92A,C3017F5A04CB0D0B,CB9A3E8F5732C394,D0DA699D22F2338F,9083A1DFF5381B5B,0000453D0DDB2F93,E90A16D427C7F989,C69B70BE90E196E3,6BFEF10771445260,03E3BCF9EE0E1883,01505F173C0982B5,38FC4D30781C8EB0,EF8C53B25B913AF9,45B196FCA0B465D5,2ED56E66F19CE4F8,603ABBE6D766EF52,7F7CCAB444070BA3,00006E14812D70DD,4A7832BD96A0D79C,09FF2AA8FD9131DA,D1EFF16359E3C057,2AB1499B077D7F01,411A5494C4CF5170,34A230E0F1C78B6D,6394E60FD5C10ECF,C008AC5CFEBB69F5,AF8180139A021B9C,1A920B66F42053E4,4A5C28EF48F6D4E5,00002B23FD419AC5,0DCBA97D54A32298,FB4AF4A26A2DF2C7,B2132FA139D70CCC,4AB460DB7EE41314,296C712AAC0D40AB,CC5C409C26B901BA,613C47CAB203C688,BEC491E2B5CCC093,D741683E3426CB3F,ABA3E027C84AFEC4,A6E15511761A3F14,000051DC5A6EAD13,547FACD5517A1C77,7981D271E5E624C5,86A3D777C1A113B4,E33636E63DC51ADD,EF67883B8178BBCF,C4527D9E48D1ACF3,9D040F5234849DFE,F17053A33289CC50,E5C27BA7D935E458,F6FA64D8EFFB78C7,CE3423FD2BA69512,00001408CE766B35,3C463609BFC6E35F,DC904DADF194F7F0,5B846286300A8EF2,6DA44322948B91C6,48AEA631C187552C,0545B111775E7140,5D4A1DA3B722A5F1,F16CB87E143F1553,91B8B56A4B96BA5A,FC40575A78F4AEEE,8A6F0227F7606F0F,000019DAD69C2904,A54954664EF1BA09,A2269F34BB95ED13,402AB1145895A845,9E0FF96C11107F52,AE1AA00682B605CF,C6904ED307B9E02D,707F95B61A8CCC4B,3D1F7E6B2178979F,E8E3B10CEE8DDE53,95ADF2C33C8D18D6,1162B40149373B0F,000069D71F4593D0,6B35ABFD9143FD7D,C3F2E4C1FA1DE03F,178F8531CB2FF7EF,A0D5C3535DA56F7F,BC66C615C67036FD,BF29EF7F86B0C623,C1F79D3693C45EAA,C62388C0B58C2385,572CC6D737172364,8B980DD6B6E42570,E632C3D644A3A335,00002076D312B966,874CACE11A7A8A89,1661A019077551A1,B84C18DFEC452B87,AB24FC4C783480EF,F7D2B7589B4743DC,171E1EEF9921C497,449D60A8294D3979,D70FD167621958A2,5ABA1036ACA67385,620260EB3ADACF94,E1F356CDCCA95F0D,000011427FD523DD,8EA0A180B98C102B,3BCE63AB65CD76D8,5BD0BA1D893BED2C,D834F6C695CBDA1A,55B207515851EF27,F0713498BF90B6A5,2206AEC4B94EE4E6,9DB811C5C21055D9,32B60F9F952E9A90,CBBD801F6D66A0ED,27C80B1A2EC06B88,000041C510A44DDE,6671326CA0E33EB2,6B6720ECBD496D24,5BBD5C14B09A396A,171DB2F438E04BE1,80B7367F35E3898C,0F1FB266C7580CA8,F5C82CE3C519476D,19040FEE1F092833,ACD8211519181FA2,357A08743FA8CA36,506A8E01DEF060BD,00001D5AA0D44C61,CB40DD0EA8566553,0C0DD2820D30B1DE,52A32620EA482DB8,80D7A49542DFF826,665FA86BC08122E3,6354E70EA934D30E,8F3148678752A86A,A756C5324834DD71,85ED44A7B30805F8,9343E28C97F987F4,6D1D8B22D0DFB34A,000042121309AD31,64919CD7A87BFA3B,7246C170C77368BD,6AB437F2AE046288,7756003D27CAD7DC,5A992CAD6688356B,EDA3FBD63538A34C,572103861CB28A2C,A0EC34E3E6F59BB7,6054B9A125A91E5A,727204FC32C4A0F2,AE852BDAB298BD07,000056C01770AED1,0423326F596EAC00,B1991183191E5714,9805EC5CDBAE56B6,9B803C3F46642045,86BAC0181FBA5C56,62E3D0BF34DE4508,7994E68642405960,7CF706D9BA197FFF,DEE727ADC73E3145,5B2AA30B20F8034B,47E440010BB8458C,00005610C9124053,C955E63355567587,05A72DFB87B48D3C,4CB06B8B0198B171,D56C25369124BA21,8F1E38A06CC29FA8,BD71B825D8BFAB02,2D910C0043FE5C13,F5964B9A64BC3B69,569F9080C558AD7A,D69519A0522DB50F,43B5AA2F1213376F,0000227560B7B114,2457B4D7E1A63B6F,2FA373FEB5B8F5C2,E9532038C3FB706E,55474D54795E70E2,EEACE3D80D6AD8A3,CF80966F843B1F6B,5344D80DA35FCD04,0289127BE0179B8C,147358C6CF0E3081,A1E7FBA2F073BC1A,32F33A035CC782C9,0000492715D9F6F3,F03C55B625C15675,A8C54AE381EE2907,FB54D6B848AB4580,43D1480E6F6580A9,BE9B2063E97C2D26,946DA6958181BE76,24B11AE785C81B9E,479E0327B1D8A546,99706C4A5F6BD7CA,569A65D254119420,D2185BF455108DEA,00003BDB0274601D,83DB1EAF1CBF38A1,D6533DDA465A0309,586577410BE81A7A,B3796B467BF06AAB,10E38B7F2189AB30,7826498B74F9D8CD,2751C5C58350F034,22FD1FA204A97FF4,ADEBD815EBCC507A,F9E865FA6718054C,7A2441869A60C2C6,00002C772C885575,B57449B2362ED75D,3F6A5D8C9033CA07,529F86383C117ED3,FEFFB96C1AFDC1AA,6ACAD556DDB04295,84A9091BB577C7B3,DE473A71286BDF73,4AB30EA7ED867E57,C47E00BDF7B425A1,295A3072E100703F,FA78C4CFB12D401B,00003B17D78C0316,DFC208AB8FC9407F,B1F6A0F023B0EEAF,531057C3B03E5701,85AF605328AC615E,9227316D888B4EA9,7E0BB2B248BF72B9,66823AD9A8DF758B,21188340DBEDE95C,7F146DB0D7AC12F8,1066CD3875A90B42,A60BFA5B283A34B3,00000994F655D011,B278AD742C164FC7,112A62DCB2AB4259,85C661C3317DFF3D,93170A60E2850BA8,D852027CC47FCA9A,02BD4EAAF2DD0ED8,73874FB07EB9AF83,5865B7C8DE42BC38,E33B8265281CDB3F,25D80A4B2D660826,5E17DBB5A9CBD8DA,0000550A56CBF025,46B0EB47B03DB46B,B89B64BE4D09C877,D0D87D937F6D6384,04F72F3A3D77D7FE,337DAC361C84FE89,B5B88366B642DC5D,02A674EDF610C555,C7225A28381A37B0,3135D15D669C517F,005B57798510DB2F,6F592BD8043C198E,0000133DC729F261,43F4FEC69348809B,63C2E6DE5B0C82FD,17B1EE6888AE6BDF,F2E3196BF9F8FBFB,B01CC90E63976886,CEA0BD76E63B1B26,C04C02222C8A7BC9,5AC71DCC23886FC0,06B92E21A8096D2B,8553EF1EF36AEDF8,2B4AEBBB4028F106,000017676BC98491,0BE3E66F88F42208,48134B125558EB75,75857663679DDC28,A7976D7917967DBC,664C102C136FBA1A,9F9E905576F3F2A9,4D39FC80606E9468,601C00ED1E8F4FA5,DD4A7ED12F45F520,B8C2C17883A66AFA,490BF4E9B8DC492C,0000427CD201BCE1,675E11CBF9F59263,0115FFF19000ACD7,1BFCAE022BA542E0,D178D61E306AB7D6,FDBE6D2615833926,FCA6D72D56EB0FA1,C9311C496D3200B9,0DA4E5905C9C8F2D,04E1C96BCF577F5B,CFD481636F8B4CB1,5FE535FA52EFB7CB,000038FEE5EEF0F0,090D5A66C389F2EC,A9F2F072D9C59432,312A33D976EED97D,627082DDEDBB3DBF,05D0E9500CB1A052,39F194D419BDF730,2F8142A3712BE504,47B20A58E32790E8,77C58E36542DAE01,1097E0B53E25BA44,2495BE2856D51459,00006BB413B52CC2,98AB8F957BA99D7E,25441336C63BAFD7,A101B01C1947EAD4,3B82079797650BC5,B32A381D969C0069,0A9965971C0C3CF1,4B086CE1E541D8DF,FB57EF729176767C,8B2E1EB997AEBDF3,7A11DD95831DEA5D,7DF2A9FA1AD6FD20,000017B122BECD27,9612D89D62FB0753,99C99952B9939B26,9FF847CFF4001A50,9F6E76D4B52D1B48,C2831E7A8616702A,CD01BF6BD125C756,14B681D9C8AE30DF,3372753A194AD4E5,91CCDBDE81CE663C,EA5979325FED0CBA,1DD7FE0EFE9F3E8E,000000D831368FB4,150B9035CEB1877D,3487D24D636D97DE,6AF0509B7E64E8E9,53869E67F01D3EEC,429722B73669D88A,F0CD95E4EA6170D8,A2CF8A0810A8A395,0F518BF8BC141A87,8793B5A1D07970C4,121C4A87C2457BE9,AE5AE40989CF27D1,00000B7D62523268,194CF187EFDCDDF4,4EB55A91873A06BB,C6D3E0FFC86572E4,384CD9EE866F2B8A,0600EED7122FF148,835D8829E641A603,8EABDC4B0D73EEA7,8756ED7B28BB16D3,8885D96D9D33B25C,CCBE1DE1F95F86B6,90B18AAA91913977,00004846DDDF192C,865EB0044B3F8092,0DC5865C31ABBF32,5AE9D9705269B7D9,7649229CD1973C6C,ADFD7C8CE84D8460,B2F66525E5EAB7B4,2BB0BC5B01E22A45,4EE72382449A6BD7,EF39A4FF10AB5C1D,0F44237C897DFF7F,2E47474E5BDA6370,000065575F64F480,19ABDD54889995F7,8C0BC21EB1403A59,5AC857E8ADD10C7F,7720F16DEC8B17A3,26C921FDF779FEB9,B1145D69CB1FFCD6,D5401269BC67347A,8F22583BDAA8E1D2,33ABB3E532986B72,B2E363C4143BAC7E,0CEF32C63971EFE2,000016E85096AE08,CF29D4A416A193DC,3F0E5140ED67BEC6,854083465F20B9FF,1CA4BA30449CAF4B,0EF29A34EB897FE4,4696A564BB4D110A,D272717C5D24B578,378DABCCD6F82723,94FCE8C921FEAA5F,3B792D8DF03FE481,319FEF46B24223FD,000067EB2F3F9B1E,386AC646FEFA90F8,D8330A7DA792595D,7D2C2322C8EE0259,78C4884820C68987,72CC237FAC8AC9A2,BC128532C6AE2674,0FC8B435D6C6670F,6D7198483FD6BE62,FB15A3B4D4F76FDF,E343E0C3F4072920,0D45A3A65F942A66,0000380EDC480FF1,F6F816EDFABE320A,4C010003C7888408,448DB98D6FD15F35,81B76D5FF5D7AD3A,BBC36B50725DDD12,D655A0EB0B3B4C13,501C7B2302D5EC96,E2381259F447F1B3,A8F5E992451DE0D5,AE6BB6D2770E3CDC,6EB85796F39036C4,00005B3F274664A1,7F6AA1191F8073E4,06AD7137CC744531,FA5301E34252D95D,500C0707D0785E0A,49ED413B68A88F43,2E66503F57A96067,5A783608DCABB489,48BC4D60C8987195,130D7B2D63495D62,235F258284362727,85F83F66600C553A,00001837C790855E,50C0AA858AE9864C,9D9CADC6B2CA9DD5,FC9E51C3A599D3AF,ED69ED34EB51B952,FD6ED6ADA4BBB501,4C2348F5C985D957,F87B72DB8283253A,4C66F24371D44485,854A2BB4ADC7192D,6A715F4C3097FD1D,1925A8992A25F7AD,000036014A66CE80,60E4BACA7D5A2783,F1D90F6BE4E54D3E,7E0379EC3AB8ADF6,2C57F68D2BA2F550,0414D06ADCAFB4A1,82974751718A6047,F51E8907E23FB04B,D7A2D3E863606058,04DCD03E6D7D9458,C99CFDA1EBE2B0FE,824A096A6A1AD960,00006D865925F5C7,DF443A318948D99F,DDC098B2F7A01EE1,8E2893AB3AD08E18,56BFE189582C647D,D91C0AB112EBB58D,ED518C22822CCECE,A34F03AC7028FC91,9799B77ABF3DBC08,5DCE2A5D930BD35F,924008BC53FE02E7,9AF43A110ED4A1FE,00000AFC2B140B50,1962291591C179AA,B3D9D44639133CAE,0C8F7CED70145B21,A09F465D2B5EC707,84B6CAD1073BF730,E534E0C11CCE1CAB,DE2AA0C3BB0B469B,A36C3EF0A1334932,9F0F2A3CFCFEAE4A,605B7DC065385EDE,743109B2D49468E1,00004CEF47094858,8D1E128C06D0BBD1,CEBDB78993C0BB6F,CC1B6EA3526F507A,345AB81155BEEA14,CE05772FF421D7FF,1A1177D481AEE3EB,68C7C4496741DDB6,CD46D52E39E18AA9,C9C9E342F178A83B,3B7E68D2A6CDDC2C,CA3E6BA55D23823C,00002080BECA58A9,3615852A119C0C73,F0FD3336227A5453,E1E920BED9CAED5E,2C2AEAD27C2C1662,6EE2DA6E9353ADF5,5BBEEF6A5270A252,E7EF86DA8E7EF0DF,0F65F58D06E3BCFB,9A358D277CAEE442,A15020B48EAC1E79,52DE425B44F88786,00001A078812A8A5,61973DDC982CEEE5,5D41DC9C98A3AB96,6EF970A40725E1C0,83EDB582D522FA62,893368BB0710E7FF,F4AC6D2D58E23B4F,13D046F1EBF60A6A,954ADB68A3C3BA09,16A6B0B610D225D4,0B0D9A83261F8276,49D304F76ED99056,00005620D0E48210,166853650DC0FB5A,370E900ADB4DB52C,4BFDF8B830693277,E7D14029D33EE9B9,DB4ADB3EBF2A675E,73FD2D4C740E063B,5EA40ADB24308EA6,853DA4D463C28A02,8D9A8E02BAADC52A,C27B7F0EF0829B82,3682617C6C84D2C5,00001034545AE7D5,0874F595D433076B,FE71A343DA71CCE0,FD7C50FF35598651,C9B8D7C1B8DFB3A4,DDF5E4421FD28E76,D94ECFA5496DA7BB,BBC316207254CEF7,96AA8E489268B564,A36D552AAF8A735F,244C421ECF357115,9A18FD3D0E16B117,00003160965B15B7,30CBD4F6CEB76BCE,D59615C8FC87EEDE,ABBB157B6A45E243,1D858426F07557C8,6A7702529CDA6E4B,E62FDDC9BE58530E,CFA32F8A6DE365CF,D7E4B5949F44D0B7,5829379FD59A332D,CB081E48035AD3C3,9895CF7F99BDB096,000040ABD002006F,416E1E61E575A1B5,99FCA1169E81CB10,3205E0EFF81D6683,712F8764E398D3D6,1AAFB45A7A66273E,7A287EDF6D4A4CD8,E935A98AF9D2EA6E,A06C3E2EFCBD58C1,6EC24D695508A19D,364750726F5FA1EC,26A7405E01BBC32D,00002FEDE7A823A3,69334509DDD82A9D,2893D0DD1764A85A,E78B5327EB2EE12A,2CEBBB943E9DFE5D,2AFFB64670841D16,37B4E52F0593FD27,2AEBFC7EC919D64E,09E6EE78262AA330,5550071878F88B55,16EDB0AAFDE01A9C,ED0E7825F6D0BB3C,000000744005B5F6,5F388AAD1635425E,0DA273833E430EB2,F525F3B6D6745F52,7204B10B2F8ABB89,527A336C12081841,D22A5B071F1D4159,BB6D76D606384A26,501599BDFF893146,DCC3FEE6E23B9233,F0CA5BBE031F2037,A7CC86756F8A5691,00001DCFC1CC23E3,46558949FBD0F08F,0E0089D45B7F2B83,A928914E859F8F6E,EF0081403B720556,00881255C4E804E6,756C1A435E8F8C6C,00EF72D56519ACEB,9D7FFE033972E0D0,CA5889C16A5E1B81,673846C39749AAB4,F40DF11E0B1E21C4,00003FE41D035336,6BBD46937947265C,36860FD6C6E1EA35,A46A1BAF853EDE42,AEFEF387D1A77E3B,6C1909FD2A2C309B,0FF40B2874D5A0A6,CEAE79EE6EAE11CB,9FDD3D07992F0D0B,7FBACE2430E3465B,F753EC153E086265,B3D39006AF4A4C01,00005EEBE5C99523,E0BD57C44699903F,528F259B6E0EA2FB,3C372EA18BABD161,A153F261CD6C9285,2132344E1910B4B5,B336F721A2F031AE,EF137C85A6D73A5C,AB68B27EABC9BEED,36799FEDFC70987C,79313585031BAADD,C9B75FF0EFFF5E50,000018783EE446CB,4CEA379E3D6F3E47,DC0252E6B041DB7E,EB69B35AAA3BEDDB,8799E5BBE58A80F6,6C90A9C4D59A8038,71D35DDF57B153C1,991F1C41FBCA3375,4C75DDF3107B4782,2D715ACB1B85FBD6,B7855C3359729C4B,CC8B42779944A9B0,0000362637F0C598,59E1928258330845,779F211604C5034A,5171F28ED2C5420E,E1618B0861AA7439,278BD671D8DF7E74,161814C5B82DEBE2,2597409C3192D634,0DE76903FCF3AE77,2662BE07D3FCFA0E,BE38EC29AF769878,C11FBA8C822A9DB3,0000106D257A8870,EF68592BC6C6A50D,EBD56D7E8D34317D,53A50903812EB9EF,9A46B2D983ADE53E,EA022C3C5F16D5BC,0CEB749ED2D3A308,7808AA082A5F3BD4,22341E034876CA41,A1F8BF86A23AFF99,3DF62E0E40F0E042,726D9BCCCE330076,00004E05CDECB727,9AB8AD6392D45C11,7EE687C03DD469CB,68C0DCAE0CBF7490,5E364FE5AB82F3D1,DD9BD1BEC68DF1A7,74D0DEA078B2E74E,B0BDA1CA6CD538FC,2086AFFD9A13085E,35B83F10AE587863,8657617DDEC44DC3,02D5E75F2F80EB66,0000656D1D718C94,E2B284584662150F,43EDC0B4EBFD00A2,632DCA55564C2F96,1051AC3E5A3079D9,253D4DDD39DD992A,74108936F3B6872B,A162B16E95D86566,D124B0A16922FD25,C6BC277609B4CD95,2721B11785058F5C,8CA07E190581AB1B,00005598271A010C,B4D52F0B1A9A500C,003CF0EBC55280AF,F3DE1DF391DE60CD,46F6240B7C0D2758,92AB40370EBB46CA,86DDF5942A1F91FE,2287C2E5674D1C40,DA7A4A9141F910A7,36A674980166DCAA,441C711A3C84744B,344F6F1F8AC33B2D,0000080750698E61,1828440434FD6D34,CDDE722E8CB56AD9,3D05577990B65846,B41B9BC68825DD54,EF0687FBF5B91540,7B0197BF458355C2,079102BC7DDFABEE,026BB4F18C1BA2B4,CE0DBC1863F408DE,6A62CD35B8A850FA,A305AB0196C39650,00000330CE29EDED,BD55069F53AB9B2C,CA7FAEE05BCB75E9,59C80D22FEF9F5A5,FAE5934E536A10F1,4A63FEF218472DCF,89128AF337860669,544143C85E1CE826,6B81C66189E646C3,0AB5DB25652A0612,C28F6AD05175EFAC,6386F56362D5529B,00005B90DBC0D35B,6BC8B8503CB864AA,D57A855220B77E41,BCAEACE8698E24E0,E81DB133355FE5CA,2E482D9D6D1EB246,581C2E676F85FF09,E98FFF623A6507D8,884BB38DC8D88FA2,42FCAC223AADF707,5003119F7F947073,BBEAD06642583502,00006C8E7ACF50F0,554531CC6F04BA3C,49B8D24FBE20AF19,1BDCA782B68D438E,394D621E7314FE19,C0D37CF80650E696,6FB03042530FF5DD,89716F65630280ED,60D07B0779F0E305,A1C538AD8DC24CA7,EA39A1E3F48AE693,E240F497231DDB63,000035969BD99E80,0138D3C0BA71599B,67CBC4086B8FBE35,917B838DF7D38CFB,DFCB72700404AF98,3472B8F5FFBCE7F0,C208D858F7AEC690,6595ED7193EFCAB3,5E43A2A486231EB8,897031F44B74E357,D17C48AB9FBF99D5,9DCD7EE0F3FCAE32,000068294376C3C1,C58BF3295EAE9773,2B2337523A61BA75,B6B646C9C6C8DFF6,EB3A7D1F55D92867,F3A00DF5B661A5AC,08092E8F188A0810,5A6D0EB2928A4A45,3365E355926AD108,45E79D7843C41F76,B89B79EF1F5B2B41,1196429F6704EF2E,00002965F46FCE0B,8AD1FE382C774B05,7B52C33C86C3B24B,BB70B5258F360162,ADA7C3FAFA975B55,2D4761FEA142C32B,E4A8EAD18302AAD9,257B4FD277D454A0,1CF6F1CE3A0D1FB2,0ED9A6727FCB5777,E68F4B9AFC5BF049,9D4F3F206AB528CA,00001323D1EC995D,0E7DEEF313D2E44A,2200E73652EAF2D9,9717B60A4F63E509,D3F750B7B9FF4A85,34593794CB749936,DEFE840825B80E53,4AAF733A1850C6C9,0A574970B465C7DA,0CB8AD245402C92E,5D8482B525121262,D67E7D11D4C8955E,0000323E4D7047A7,BEFE9BAFB3996B20,E9A5E6EA0D1E833A,2714838A861EF7B5,D8114D8940A871F9,E0653C7A63971853,B355A62FE56B8753,A88C63D5B4BF2823,82B99AC564A5F321,E8D72A5314CC6967,566DD9C8DFF20748,AC318D0C492A40BE,000039BFA2D1D1C4,BC424DB60F0FAEDA,9DF3E7B4A7C0B61A,E6E63F411DBF72D0,99160BA8442A1A7B,D0098494B9100D9E,38AAB10910F2A9B7,D9B1617A16DA53DB,F484525EA448BA7A,CD51022E7771BA19,0CE15D2EA02B80E7,3FBB222144158998,000051E70A28CD9E,69A76E7B42688963,C584EA7C4E2EBB0D,CEED86A0106D1D00,17C0AF6653F02438,841A62A6D28D50E8,C80A6C2FB70778C7,66FDDD651F679059,B4CD1ADEFD25464F,2F549A758C64E4D4,FF959796F158E5DE,5E5D23DF2A3B20D6,000030530AC15334,7D9164ED3F513D5F,D7E7370890A80C1F,32345AA52CCD2BAD,D237083AF464F428,BC1C2D9476B07EC1,DF335D4986270DA8,9CC36315CEB4EB24,94F04B88189C2E62,EA173E9289BE5CC3,8ABF429DD2CBCE73,271F8587907751FA,000026BBEAD6D08F,FD42D9F8DFAF2B54,27E4B9E261EBD9BB,12E53F1A1788902D,614BF3AB893EF060,9284168A1F4C33BA,24B27D6CD1C82F80,A3506BDD8B226323,2C7D14731CC482AE,E27C2ABD813ADFAB,CDD799D88281A24F,57B25E547F30C74E,00005BF31EE7CC40,C72C063D2AAE5D93,E9437F48D532F889,B61CE08BC13CCF95,68B3BCE23B0A4474,9EFF4E662EDBC49A,3C66BF33897184AC,24E32F3C35C3AB9E,2FD449E12CFE5AA5,BC884D9DBF6CE7C7,AAFE16ECCAF72E6E,257E67D596CA8E85,000055F611CDC981,7056887E5883EABA,EA77C44A48F7D2AE,BFC783D6BB39575E,1C554FC0F325341E,E23EEE560F1B5112,05AC70D75BCC215C,74151B32FFBDD90A,B5372C5CA5CD10F3,D91C766FC61C3289,CD58BFB5D5CD11ED,EC5E0A60B4E32998,00006EC753D510D3,58B22947490B8887,4B10647E1F376725,471EDF1C9A4E284E,A726244CC3876322,72FD1A14B2CD6FD2,F9EF896D3DEE2725,9A28D904283ADE94,1AFEBB9539505717,1C0E04EA188A6589,89B27E66D3CA8E14,68B5408318DF6EAD,0000015F1376D91B,6B63F896DE29FC8B,F53306D24B39A502,D5687AEFD069C6DE,4550D0DA397F756A,82D063B3AE27AE45,878EABA0F39CD296,91461C5912F24CC9,EDCE4E214AD17E97,BE39C3E01CC36303,7093ACBAF7D5A4BB,F74FFD24B80E1716,00005F23A42DF1C9,A2F509ACA849FA9B,AE350A201C9CC29B,0C37C41E8CB32B00,3DE946804C2F5BA2,1E408D035D1F66DC,E9B2D09E91A5EBC5,0030ED4AEB468E23,E992D740E5A4DAD8,A4DA8E6EACFC1DF9,4717E55C565BD942,7E008535D2D324FE,000053479F387512,706324FC10980020,B323960F621EEFDC,A45A0C708DD07CE3,2BE4297B3C3599BD,B671A6B69F3AAF6E,0BEB5CF5180B1E19,7CFFACA60915754B,304BB79DD1E863AA,5EF1F5B6A85C4C6A,7FA5D5AD06AC0862,76751FDCA472F889,00003DFDAA509735,87D29CD1326B7E33,750AEEAC58103933,71DE8581358E63A5,ED90B578A58E60F7,2E56F945FB6D3987,FAAB25859CCEF21C,25D6CD62C8B2FD49,43F9B11C075BB3DB,0F8E8BFD74B64494,81BA570CD6F32C8E,9CA5E1062D425358,000000CFBE588C01,1B39C646FB91632D,FDC30365B1C4CF12,57BB56A60975D4B2,9DC66467CB466B8C,0FEF903A3871C4EC,E269852E52B546AA,609779856A33FD32,5C84AFFEAC71EE60,B96B46A956FBA3BB,060BCDBE69195EFC,7C0EED6A797FE3D7,00005808F582BBEC,C60103FF55334D85,986966A33D6517FF,84EAF8A60493A34C,FA9E8D8E03B9A1D0,654E25A495BEA1FC,4BCD540BFD46B575,5D2338DA4A2BBD5B,7AF5AC8694381272,3C8DDC5C7962CD35,88F4301650D79C4E,DA918DD29E46B90D,00003305DA26356D,A197F1B9D7577089,23389CABE1A02A64,CE0C1505D8D3A36E,3EF64D892396A6E2,7F04CD4A24F1381F,517D72779F1E975B,592506E5AFD115EA,CA60198D3538B967,F306D5876B2EBE70,D1E91248F4B0B2EA,2CBD02D7E3AD393A,00005EA6A48D927B,23349556C131FB73,1AA7552B421FF020,EE0EBB7C76DBE482,6A5127F710DE980B,B96FC57DDF912668,D89D31D50A99797A,484067673650D761,DE33896724DEF1F1,A5D31C6E0431D492,4835A3305DDB74A4,D0BB1E1070CB52D5,000021EAD8AE4F41,E086C97DF529E919,1C1C275E695F00ED,456E26CF17BCDD9B,204C75673CE8ABE8,77FF4D6235CD70E4,3F5230C0ED2FBC55,FDBF5A76046356A7,E8D3F42EC462B653,65FC5B72A26BFE01,58EE51C24D09340B,51296B33808A3F31,00003AC386DAB60C,AE43D55F7B0580BD,6BA5EE2ECB7A2ECB,AD8839E567BDC982,2F0B8998E0405E9E,75BF8BBAD2336080,95B794166AEAB45F,8D72D18874ACDB7C,71BE5C46E5E9A0AD,7441AFE4D0D5F48E,922468E87BCFDE94,0D3FFB3C46172436,00005F92280E6A37,F414D56B0EDC4747,64916AC4660261FC,9EBEB33906AD8953,EDBE52E0DA53D198,B62B69D7CBDE1144,68BC69F9383ED43A,72C618308BEB1FC1,89FF71486F43C437,7955B6B132A4DB30,BC2CA9E22893BE1A,CCF5F3154781007F,00004E046F5B8EEB,4659FB28151C8DE4,39A7FA767E6FA3C5,1F333A51A592861C,C24D9F7725CFBC89,5EDD8B4B0BFE8E08,1925C4979A2E9A19,7704E8814E14747B,1586A214C0E2520A,55A3297B1B6C93AB,CEDE2C89ED91492C,B3700269D73171A5,0000517B6BB3E04D,C2048946D8DDF9FD,136B7B77C757F782,ECC50261633088D9,B680BA279C8F1B07,B28548AB84F5D6F7,B5E6690E0B0D2958,E1C114A3020F3B42,8ADF56025A3C83C6,D9F2F147C6909FD5,5EC60774F45705CA,491F08403B362879,00004BCBF3C05E0E,886265A7E4CEBBB6,C2AE750591294A7A,2DCA149D7CAFD814,506102192C27BEEC,7F35EDBCB3B01615,E92AC980D416B428,B7EF9622FC844ED1,0259581F38AC3769,C108F44159EE5034,9A71A67221103434,8FE3849C196E878F,0000075626D6A7DC,1E0A16D78C626344,226AB76C19AE111D,21CBAD5C4FA21FBA,1526DA66F753BEC2,3E40CFBA1578A898,9A682A0058EC6166,E8A0433E1358EFA8,F240856F0B497F7F,CFAD5125225D3BFF,C691B4FB463DE7E6,90C2DEBF41DC6D5F,000011FCEAC513DE,BA5C6C2911F980BC,9C35A5DFD47773CD,ADB2548101BDF4E6,E54D9F6E60667FC3,435700CE7A378055,B5C9EE54DA5FF464,70A148C198BACDC0,2BE4444A6AA87B57,33B2EAFCD62AA4E2,2BD60156072C9955,4D909F98BA33B407,000040B14FFCB239,066519FEE56007A3,BF9E0087BBB7830E,F7747552E4010EC9,47AC410A15692AB5,1DCA01780E007C33,9C7C599F0E063BB6,B41A3DCC200CF2F7,888F63DC314609EC,FF7718AA36AF9B93,7DABBE90849B80B0,BC6F5AD58FBE9F47,00003EA591DE227F,0F87B3774C50FDDE,CC673CFE8F68D09E,1C20CCB31926F562,B5C1C7542B1A7ED4,15B5CEC813F1C297,C101D5B76AD0F30D,DC5ACB9F20A914C9,600E05863330862A,A22340AC35E9B70A,F8F425BCF901E6E2,790452E8484D4376,00006D539A740DA5,6237F4ED1ED274CC,7B992E6D1876B6D7,7912B44F1E12B6AA,8400003624A71447,01C1F41B6930631D,404A73C2A7ED8AE0,4A91BD587C4C2FC1,19BF0A548B1B76CF,C78006129BE1AAB2,EBE771AD7D7B353C,A9B37F23C5805620,000025214E5E7866,457BF00CF9C66311,E70F9C9D451F6CDE,9073C55282756066,8AC30E6D1956FE22,60C68FB2AB2CD96B,CB6F6B64BDEB70F2,245ABF0C5B475FFC,8DE20C6B0151F862,35ED831720063B28,70BC87CAAF983119,68C8FC39D67A971E,000002BD694ABDD9,5F36AF1C6F0E9A5B,D9EB532CA7C44C4C,BE00EF63820E3FE9,3228406BD0EE879E,65086D9937814A91,6D50C2B2BB985EC8,99121655EACC8D30,682874872952D9DF,9EF725300D0DD7C3,43C05F5486B1D386,A99DE4C6D79F3519,000063F8D92A7571,CB95C30FC3174D35,EB2D804ECC6FCD08,06F64D7C1DC92882,632F8C3CDA3D32E6,4B810F8D093F0DA2,73E4FE3AD967E64A,BAA3DC15787BE9E6,A3EE912C5EBBD4D7,DB27AB863331109B,FD2F7D2AF3DD92B8,2C1B1850368F487D,00004A22D98E9F68,24F87291E2A07F12,DA6A9231AAF6BD64,8CD2BCD6F3A7A617,55DCC041BB1C18D1,74E836F38891757D,06EF32A847FF5488,BCCC16A32572A83F,FC131A8BE7D5591D,5F01911C8F0BDC7D,E357CC673FC652F3,E5911670A82801BE,000046CE1687F71E,1514525367BCD0E5,2B22BAB04D11B869,A68B5BA67A2C0227,12928C65959A6E72,6D75FF5512A6FDE5,2A3F9D2021AEE65B,8D5AEDC8F8125590,C4D958DCDDF7DB06,E39351EA9592245E,1EE0ABCF0FD05085,7579DE7B721F8D3F,000004E2801128E4,17B0959467EC8E27,295DBAC9D48B1B26,114120B6CDEF3FE6,4D5C26171008794A,2353914B84B8B55D,A30DC896A6DD004D,F7606531B244E8B3,B8075F8DD844102D,08F0A1EBEC1E3801,4340C408EAE9DF0A,D73EBC3AE19A6404,0000506C451132E1,4055AC928B226585,3E08FD03DA5062CF,53D79EED1399D30E,B3D37032CC4D489E,B771F96700F79F9D,A11CE98855CD5AEF,5873EE54DEBD52E2,C62EC293E8BFD596,F71CD796793DEE39,F8B0C45C51C78C91,1CB88C7BD8767DA0,0000578543F8D455,C3E0C2B6BAB78CB7,B903667D4558326B,54E4AE2B85F23911,5649D99D06BB61FF,D09785C64F1B4029,8BB26D1292D78CAB,BCCA9514540915D7,76BE7E9FF4C3DE3F,72E4AD6F7BE0004B,00F2E439AE536E2E,BFC66F367F87E558,00004894C93B1B03,867BBFC0E08A6D07,3B5E68AD7EFA1083,17D461189A4B3FA9,B833EA51082E6C15,37A67B06B1465753,D8EF3548E2D08CE8,EBAE029CEEE344E3,5BD9E8AB7E4D077B,332CF5ACF9DD15C6,C34BE7AFAAA087D7,2D7698A34F912614,000034452A442EA5,84BC9927764FF643,2F3FF1E0A9458E3C,3C56A96BCC54530B,E052EEC6BEEB6EF4,1C5A198D9FEB8C8C,21EEFEC6B6392FC5,744365BC036E4C06,B1A87629DB585882,67025185091206E0,E2609BBF520CE6C0,3B3C52B3C164DE7B,00005B7196743997,9DD99D1609E1CEC3,EB58F112EA33D47F,57C51C69E8A419D2,8169F935EDF95AD6,B85B11F27B15D1D0,82DC90C4DB2E1257,9420312993366C99,910F774C19AC3494,53E0D099427A90EB,BE1D153B78FC793C,AD612FC1291631AA,000056DB79C9A67D,C646415B40C651B4,10C2384F19971F2F,65DBF9F71C0B3F2E,C7856509C94819D3,54A80DC50F93355A,ABE5293E42DA5556,02939A8601913CD3,EAE995FA8DF4A95D,97F2C96AD632F013,587DCA665B14D3FC,205BF123277E84AC,00005BAA0A8F34C0,D4DF793521E66053,DBFF6F5D95305442,73C399CE95AF8A1C,81FB12A972AC7321,6DAA1AF4CA30A820,0A4E6931E8150498,954969150AA962C4,6C9AA122565C9A66,7CB81205ADF37420,5AAA4E6E2849B52B,297B9337817F4C75,00005AE710F672FD,000000000006DD08,0000000000000000,0000000000000000,0000000000000000,0000000000000000,9A80000000000000,1B8A7F275C1CCC8A,61D12C23A9F5A1FA,518A8EB02E290214,608B67A91963E4BC,24D426A5C77D7B55,0000182B98F4BA8A,2AFD75A913ECF8DF,2918FBA06F88C9AB,A4AC4DC7CB526F05,2D19E9391A607300,07A79E2B34091B54,A05809DCB42F1792,B8D6FA0B2FB9739F,B92947307436AD45,A478488AA072D9C3,76EF5DE652478B48,21B5B2D9A016385E,000036FB1719882D,3728ED40E235CBB7,EB8E134CA64361D5,038E95CE4C097727,517C1D90F7A63229,3FFD4FE250E112DB,D19B655E70A2D616,4144CF18F5C1713C,634C0C1C04B3343D,A130EEA94CB71A24,E99FAA56357D2570,60EAD2DDB8B4022F,00003CC58DD89435,000000000004935A,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0620000000000000,AA4F63C86EB8D8CD,D2EF2F7E7E9E49A0,913B6F6558B89C5C,99496873A40ED2AD,21EF24D8EA258FD2,00005AB64979CBC4,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,2AFD75A913ECF8DF,2918FBA06F88C9AB,A4AC4DC7CB526F05,2D19E9391A607300,07A79E2B34091B54,A05809DCB42F1792,B8D6FA0B2FB9739F,B92947307436AD45,A478488AA072D9C3,76EF5DE652478B48,21B5B2D9A016385E,000036FB1719882D - - -ph2_T = 3156AAF9F437A3FC,36ADB2EFCCDC4BAA,5618FDD1B2675B29,7BA8B8749BAB61A9,66D494A30F7AC727,A5E1D5DBA320CE37,5B0FF9C6B93B3734,6D518D4F8AABBB36,F228F7553E4C4D71,67A8F419774A331B,45EEBD2B27D6B62C,00001B752993D57F,6FE4CC143684AEA5,FD55BE8433DA905E,31BC0BCB6E641755,2AFE733B9A86B029,91F740635E5D3E88,4F84211BFCBF0381,03A0AD6489F0F87D,0CEA95458DED6266,C40D3986226619E2,5A2521420D6B64B6,39C5955269D225F1,00001039A3BC03E5,E826363CF9124DB3,3952D58B1916BCB2,EEAEA21ED676496D,E0927DE124EA9B40,86761313D7C396F8,7DABA686AA776113,6A8F416AA5896C10,FB466E1C9471DFEC,849C50CCDDF761AC,9ADE9058FC402892,6DC8F418F8FB3025,000022A9055B9EC7,19C41A93A43C9F29,B3F3E8059F007ABD,573DC20273467DD0,E487CE81FE1CB6E3,BEF7627C2736D07E,B55101C5C73A1781,3E91878DDEE10DC5,57E9613142344FB9,8BDB15B2D4515043,4CB1D70C45484A76,747ED5C01262FA62,00005416484A457A,7DEB51751637A9EB,49A95525C11B33C8,AD16A8ACE107A7DA,CE797DDD5C4C459F,C0D901341C334556,370D2570227E7158,54568B5AC2E2C6BB,2472074D84F5AC34,647116E3734D402A,881C90D74347FEA7,25E96DE21812FC2D,000030B072E1FC5C,AE7C1E6B93616A84,C1C80068DF41DEB1,422CC5C095AE77B3,16C26C47141357B5,0E4F0146DB9EA8A2,0C8388463CC5653C,494C0877DCEAAD3C,FA2E1BA988DA8B6A,F96DBDD53B344E3A,52AF3C05A1A0DD72,BFCF60C8FF0F305A,000022B83242E90E,A8F9370AB1BE0CB0,C736863BF34ED56E,AE9D1830B3D36A9A,635151D1599A2290,5D6ED4D4942DA036,CEE349C0289F34B9,386633C515D09A6B,6D81056DE922E4E9,642EEBE7896348E3,7B64A764C32EBA84,1B2F7F945368566A,0000233E3F2925E8,86944FC647E71EE8,3BB41B1D4E95D2A6,5D7F1E4BE4254DBA,9D03A2C2F0341BA0,966344A3B6009509,286F9711AE1A21BC,9600D5119AC0D71E,C3CEACA8514865B0,A5754F75C5DE8A9F,D11B2E09ABB9C05D,E435788A97B4ED85,000035332CF89FA3,5F313195376DF9BE,E1E1903A50F33993,4B12A92CD58DAF94,36743C37C83D76E8,61D2561D6E925F49,8C9050176E9A7213,59664765D3B7B8E2,51A61FB876EBD570,5B5E6155DD962A25,51534DAA4BF46275,58491F364E6CD95B,00006C722DCA4CB8,36507BB00ECF816D,9BFABEF29375AE24,4C55AC5482A06431,90319426225DEB53,7BBD400F66496D7F,F30A3E587602C7C7,65F9208EEF75B6D6,78DD57DA8F31D6EE,E9C1ED64C33CB0D4,8C36CCC18B456D4F,BDBF76C579C18804,00006A36B6F51BEA,CF464AE43623FFEF,7ABF52D2D6F8FA97,A91E29BE12C20859,E7018289192DB88D,958DC15DBC4D8018,5E56420A26704B99,489C62436D3C4A68,A44BB355B74EDDD3,1D6F0C7A9ED85C9F,AF3AEC9BD0D882F8,098DDCAB39C258BB,00003DAA381E69A7,AE56AC68638E76CF,3CC3ED958E56554E,C6EE11FC549233FA,BA8F64A4ACDF4453,DCD6CD0CB7BDF9C7,EE8E3A385EB869A8,4456E902D1B5CC2B,FB08152925712CFF,0D4F87A63E3CF08C,588FFD3756A461AF,122F950A8AFAA96E,0000172B26BA631E,CC5B4643BA766652,69D8D65FF7A9C8A4,FC725F6A951F39AD,B47F0449605B300C,29BDD3BFBE13DD5F,1D656BA1B03ACDB9,17E32AF482AF1341,5DF2BF66966F61EF,63763F1465995E69,30523D59513DB2B9,83E3F56AFA670A86,00003A8372A3A472,D6BCF43D90C7869E,F2AF8F031716FD40,3A2417E94BD3BFAC,B7B7DE94832F2E22,ADB90F2F76FA9463,7A11BBDA0A9A0120,54FC4E67E69CE236,0D33A6C87D4A0D0C,6FFAFECF2048B1FE,F20A26C805BE0362,5DB08FB5836FF091,000047CCCF0CB47D,ADF3774BF4603F55,E747C9803E9944FE,D4D2F5E13FD6E301,A31665970AC0CE5D,25F837257DF1CD59,820CFD1E80556C53,63E0CDE93CBD204D,F53CEA7C49F93891,4C8FA79BB59F3AD1,7129E95A8917CA79,8CE522F843F4C827,000035B861EDE749,18E48929A9F0860E,C450BCED6FDB35A9,25D44CB40508BAC7,CAC7C5DF69C84CC4,B72AD69E327AD9F0,A4D1A4284B529F22,929D38B938C80CC3,786551BA8516A0B7,9A43113DD4C1826D,36C0BC09907E6AA9,DE6E9FF956310083,000032610209C324,0E429C82248A0091,7848899B1633222E,41B83099C3122318,DEE1E8FF6F9EC52B,2BCA8F8A3B3824AD,C4A5EFF3C976ABF0,22676C867E710534,5B859286AFE1712C,A6D11335BF75F1BB,55FB7484115C91A2,96F5680E42833B10,00004E68BA2B8A06,C243409D08D6A032,4C7FCC72A08A5D24,CB4937CBF7C07EF9,8A972A1F24852389,DA5AE6FE6ECFDAD1,A33C7845603C0F48,A80FD415BBB51B02,A2EA3370CA6F3B03,594BBA03E366DAB0,2DDC533A5FD1905B,E6890BA04E9D40C0,000001B72F0B1F18,CFD0D88AFF1F460F,30DB56126C05FD59,F150744367DF133F,FB165BA5E3A8F24C,CC47BE4190B5AEAE,8FF3887D8580B1C3,5DDAAEE0572D090C,D0C01FB0858B1CCB,72973573534BB0DA,87F6E3E4978B9E81,7FC01155B8A47224,0000406A1A7944EB,5FD511BA22BDECCC,96F0449E88FC854E,4903D25518FBF431,C26A3A428C97AE75,EF7A22549BC6A838,3EAF37C32CD3BC8F,3EC49C78A62ADB03,ADCE33BE5E63BD4B,373BD8C6594ADB08,FE8FEDD8FA8CA7CF,A7E6EF5AB2C3F5CF,000003A04603109B,307A7E59BD104FDC,69998FD7CF25F6ED,EC5E1C73D7C80191,A56D51ADC3DFAF37,2CDFFE6E1401A562,498146AA1DCA20D3,34128A76A11CFA8A,DB24BAF06300F3E7,99C0D436890EC45B,00B70FF9F2FC2EC9,C4560501AB43E7C9,000045C517446403,366238AA21102752,9CDFA446605CF1C0,0BBC9ACE69678752,6042D63B80DE67FF,0FBEBAD2C9F33A90,39C89A145DCB7F1A,183A9C5397345680,FBB10E4AD69D5CE5,AE8A0CB503EAB62C,D2A464743BA1FF42,34A72D5368873CB6,00006C6F847DDA6B,AB085F2415F6A7C3,3D47E1DC09767242,F5449D22CDD2A1CB,C6AF43847BA611EE,3A91C304C39009D6,5E7D17122BACEC7B,556C758DEF49A970,47FCC092FE9A5559,CA38DBA5656435C6,E1A2A7C5536ADC0A,71916BF492F6C500,00000087BC85ADB4,1A5379A4779C60CB,0FB206831B13EEE4,A4A03FEA5E2119D5,F99396927ED3C73F,5C5CC6D5AA627C8E,D02705E4BE47B9A5,B13DD7AF3D784A06,42880DD09708B65D,C035033CE4098D99,0ACDD21C34F7AAD5,108DBFED2328EC7C,0000160ACFD223EB,41F487AAC7905283,8E052BE94757C0A7,7672881985483D3F,DA7303E8383CA25C,2C455F166DCA8D96,E9B940A6CB3DD560,B80894A5A6AF6831,AECE689BB8C95AB0,4E75A1D928E90434,002579108274DAB3,9A866BDD9DB5B807,0000526486C31D85,57757DD2A56EFE66,4957F04BA99834D3,F207360A5C8218B8,3DF5D564213CF36B,DDA7BABD6CBA0179,EC3B29562CD0739C,B6A7032091CDEB25,04BAA27114D82271,C9C89A5CD99F65B4,7971794D1BB5E651,88C893B4A7F2D9CB,00000AC06A322820,89C51B8F5C4FC59F,9E935D935C5E1869,5C287DF644526150,DD991F4DCDF63FBE,C9997BCF00A42F4C,532997403D37DFEE,EFC3290E9083D0EC,59126A5C429CBDC2,102AE6FC968690BA,80A9514A7C5B6B13,145F8C19D84D6F48,000049289D18A93D,E981555244934FCC,55AAABC440860468,49FF38CD0AF613A7,D5A3686473CE4080,B2E9346AB4242D04,9D061268C4527A0E,5A49E6A22FF69AF2,18C3674F7B2B212F,FEC3EB4C095FFA65,ECFC88FD13EAD221,68133BC6B9F65C7B,0000460A9E9D3055,7F95DBFEFEA719A5,0D756425B557F4B5,D3C24CD30E4E8E88,46DA508AD346F51C,C66373A6728CF2C2,64EE9B5313E3D218,7F7A103D8D881E66,D0DDB39AFDB756D3,E7C99D7901037CB8,36BA51BD16238B22,0474AE556D91F108,00003DD0DFC4090F,C5A8095D1D7FAB87,7A3E96E85123D2BF,3F3CE6E88D03D053,D2495E9380E8E573,B38ECB55A8EDB271,5FF04F00F9F8C33D,9F086FD3C8673D4C,EF35708E4088F09F,229EFC2E00D8F9A8,C35F397DA085DB20,03AF8E717AC7426D,00002BBE4D0C8B9B,1E45CB9CF92493C5,3B7CF01ADE8DF0A0,D84EA49118FD1D16,FFA6CCF90FE20D77,137DD0E64E24B646,2E1A583BEBFB0F8C,9A484B8EC5EAF996,8100EAFF3B482D8F,8E49B0EFB38C5ED0,58D348BDB88E4B27,8F18729C656A800D,000007D8C8464D9A,ECE856458CAB9DFC,2805B02E06DA836A,36C7BCB3A60211D9,748DBB3FBB3DC06C,6C5B8E0E906D42E1,5E6EE9561FD2AF62,90CFB525B2DC99A3,3A871022E6C15EB9,0C5BCE38AD4D5DD7,699F8D70D012938F,58BFC20D6E08C66D,0000476D9E74B9E2,0E8F5BC42FCF0482,4E960B96A2FB7E57,126E6EBA52678526,C606262E3E95C24F,F1D44FB990D21EC4,372581ACD8EE6EE7,54BA726FC5E6B67B,E93860FF5BEE6392,A5863E9A56C8F20B,7DB7570A98BF5A1F,0D9BF463897AC9EB,00002C956DE2DFD8,887CD951B741C96B,8BAE0F61E4715578,814EB6211AF4F078,61DA613C93FDA091,0D1037F14B9F7E00,A516A6F2CA1E296F,58BD2C96DAE619D5,BE75CDE786B45B37,E0AC21E0464F3B60,476A20217CB4E0A3,8554048358308BFA,0000065D906C2E0F,906B75936DD1DC8D,EF3D377D84CEDAFA,96D10CECA8BA23B7,C7A9038571312860,206E61052A42E437,950DC5AF9FFAE0B8,80DB7D390F46599A,A81553077077BD88,473858249E334119,EE89746CF3240E62,FA7070D3E9EB6DCF,00004624277BAE8B,6FC8F74B2155CCD8,E875992459C152CC,FBF6AFF60992F7CE,035919D5037AAA15,FAFA786C3657F804,B76CDFDFA94E3CC2,FE1225838C15C6DC,B040BE732A4DB1CF,3D7317F2D9EBC2B3,E434BCE7EEB970D7,66DF256D33E07D4B,00002166E731990B,4611A4BE0D2EAEEB,EC35973BE0579F84,BDF5076CCC78626C,76DBDA20D0B987BE,CB891D0117670897,4FE33749B41B7F57,7294851BE3AF91AE,C3E9C34680780866,1F1EE1E637617312,96AC06419C6F8E87,95E38393A6FB776D,000042F499B53C28,A0788D34172DBA28,74579E89AC122CAA,5BDD385A4F964378,0607CF3A95ACDFAF,148EEBC6F7B8805B,761E857D0C1043D1,B2267C0F9F043EA7,632D971E4A5C1CF2,E31150D892F94D7B,7EFACBFD06FDBD73,25AAF06B0ADA9557,000013F356408924,044DFFB459A73D81,C09278F0D64A652D,C6DABE20A0D41BFE,BCB361ECFC0E9A2A,30465DDE3EBE1A5F,28BEABBC12059A8F,E7B63F25E0480F17,E24E79CA8CD3AA47,DE1F6B1264598599,A6689959FE5DE99E,06E6F53D2CED5DBF,00005A40173E285D,97D3F05F5B9E19CE,CBACD417FCE9394F,047D998FAC15FE15,3489CEBA2B70CBDB,8FA7801AE31CC1DE,1393E0922595870C,D2A90E0657C414BA,9B0B73D04322288C,E083958369E8367D,A7C41C6EA3F26A60,9C4E6186073C9B45,000050B8A85EF7AF,F956AFBDC68BA1E4,14CA8014C32A7219,DE7B144A85101B18,AB493F4A4B691DBC,F391FE318F4C7664,BE0F4249FB737C48,C13E048C20BAA62B,C33CE08B00B5F0F4,C91D9187524AC768,5155FBF37C378899,4BAD59991F438693,00000369997E519E,9F19C64F43F83046,AC547CB4028ADA7D,3A0FB881E3BF9A0B,69E13FBFC4C27CC5,E8002E9EAD69F876,859AC62D6F974136,6D6ED2695636B99F,47421AE08F4733E2,7D5132778182E3C7,F6F304865DF406AA,BF5DEE92EB9322A7,00003CA572226EDE,93938744F148CE65,D4D8DAA2B7CE5A21,1735A4DB617026B7,B14C1DA4177E2DB6,59A9B6815C9379F2,84CEE431F09C0B41,1D4C74AD18874E0E,8E6917FC728D92ED,1357203B17E07A26,BF8C0D42CE535FDB,A71A29FA38ED0F67,000038500FD66087,D97C30CACCDFF26B,1C03F45BA0592D4C,500B51DFC6631ABB,2020B2875235A87F,2D0BBD68AB5DB072,0B9CCCF06B765396,1BBEC907FF39B87B,58454E84E5092A27,F31BE0E64CA02DA0,01DCF8EADB298080,5D6024AC240DF89E,00001DD9C5C0DF23,04826443EBB99885,953CE31708D5A2FE,8DDFD76015BDE9A9,BDB62436414BC0EF,43EF7D6E322C7A5D,F7EE790AB3DE6E02,DC51A9A6916BC70B,C8691B8DD1CAE0EB,FBDDF6E290CE2DE4,D0DA13C1FF12EDDD,5FC764293E6B755E,00004A72F58BEC7F,6A7E3A35620B74C4,251EF1BCE431DECC,DF7932F93D70FA31,D83BEDC0CDA883A6,9862038E57846598,7AB63482E0E3FC37,42A1DB0801194799,EB55AEF53C45CD5A,54594CE05B8DE621,657BC126F2DB2E81,E34AE933FA4A6C31,00001C7B9251462B,89D0311450FD65AB,6CFAD5653355A6AA,0118E78161C60A76,B274558642FC1865,5C13BB4972DE37AF,DE6999B665703ED8,6F964B560F1C86D4,5F83617DE327C94D,671F8565C64D1A70,043B085A6E266BEC,745243318FA17B3E,000048BF05E50937,163722977BDEFFB9,1E43D965BEB0B196,08F282ECACF519CE,EBC8EA936D2C7EDB,2DEAEA28C565815F,D0BBD50A36DEBA1C,387BBB30A6B8CAEA,AD2066C52FBF066E,C37FF655D5FB608E,9AAB11D7E2C89A9D,207A7D694EE82D14,00004F4B22BBCABA,B80180E6A6D0AFF7,F579EC0E8EEA2ECF,2B49A416C4EA492B,D8F00770E1AFBA76,27AAB386E0BC2218,3C60A66C340E5999,DD246CCF0EA7C9AE,15C901AEFAA414BE,6419DD18743C517C,2B50D98CC1196687,31968ABDE671353A,00006D4F9F352DF3,212FD72B3DBABFA7,DCA10615BF344D28,4531146A36A37FFB,22BD8766F35E4647,1709A0D44CAE61B4,BC769F84204B6780,9DA26C8B4F0AB609,53334372F3B56CA8,E63E25C70A704514,F2DCE8DDC5EF4476,267040957FC52DA2,000005553BF08692,C09F4D6E820B8341,2ED44A8E031659E3,BC487416D15A42F0,58FF0F5F24561CB9,4C9E2C0523469C4D,5911D7917A0B7425,F2BF60AD99CB72DD,71AC810FB9D39318,458322440C433AAB,B830F376241EAC11,A486CE78E5B4CEA8,00005F573867626F,00300E9CA106982B,1F85298D5B937E67,BF552F798226A9B9,BB29723722057D7C,7E5728B604C75A24,F0D6D6BD0ADC1CEE,98E001B3EF0EAF46,3A9A26390E5B3AD2,F9CFB1D2CB2D3F01,A7AA9FE3CD93F0A7,D925798CA3028A1A,00006C0684890E09,C33EB4F60DECF16D,BED8AE3FC9AD10DD,312170C79D1096C4,8EC5A5EC573262B8,8DD721E46C3A654A,75D477B1A696ABA5,C5E965D0A7855278,745A6292257E8156,36A3723B6436F4C3,C7AFCDDF99DFA6D5,8B2E434788BD7045,00001103715F67FD,227203EDF28C2B2D,327208BDA21C9D59,C3F7901D9E6DD4E5,C28CC68D1F5E5CC3,2EDF190FE1BEEE94,62275600A39FF923,29FF806E797206CB,98154F44EF3E8617,ABB5BB9AF263C8F1,CCF2019EA61A9B16,DDE11E4AF5226139,00006C7A49BE40A2,294549F95A133B20,9D7B1DE43DA07ABE,51E546EF93BB2EE8,CCE1E31D4A4683AF,FC1B972EE39ABB54,8ACF1602B0CFA73D,0713E2ED8ABA0620,275B3DBA70129B33,83E0EACA9CA9894D,82A26D39A80013B5,F9E0D85052337DB7,00005F93A6B9EE20,527A28F5176493CC,E5DEAFD062C1F8BE,BED6C70A2C16C881,F5C0EBBE06B6BF4D,1998685D5D29203F,783D81BAF2965E5A,E57B3A4C473BB107,D81371361F51A527,56E9CF73CC057268,E4C9C608DC2DD986,65DEE790623AE616,00004ACB3340880A,5ACC2F7919D613D1,D01C702438AC4D50,F153B22FC2038755,8AA5E9D6FAEA589A,00073771FC3D3D74,5805D2382F4DEA63,562E0ABD72C41E1B,19785C2192D616A8,EFAA250225C34101,8175EEB870E7E3BC,16828CD6E69BBB09,00004A369C419D37,9726083AEE0FE425,60D04F28C2A79D7C,F99B849B48E3EA7E,D3651F2209F51622,BEA192969C1F129E,0D7027E05363EEF8,6CB730C6679A679D,264CFD06664187FD,28E36D4C9F634A40,99FB2BF9B35A08E0,428A1F10D281CE97,0000331C64C19880,EC90FCECCC433DFA,172F9B9ADB6A0EFB,F79A6B871A4EE3AD,0835DB9433A420AB,DA19FB9AFBB6283E,D86C77C962D5E12D,B3652C16EAD9F445,94D7552866585BC4,61913D870807626B,AB0FE3FA14F3A0CA,AAFA3C9A4E564395,000005BB41CA9754,430294D14AADB7DA,EBDF940F050F5E0A,D6F8D66F3B1CB5EC,E9E4547E8305C15E,08E2BB798313101A,33EC408A55EF20AF,52B867B1F28AE3F2,C7FF1472D98025B2,EBA0AC5033228C9D,1EF07AE892AF0DEA,DA001D5A76825384,00000F3F1EF96651,69206560D65750C9,7EC749947224D78C,24B92BE53408A381,637AA390EBD16C99,94A8BEB74BA00AAF,931C8408A29E93B4,A284084DF087ECD1,A2798C49D48D7255,95C2CEB7B1FA00C9,35A181C43EF6F8E4,ACAAD86F9A69FB26,00001073C225DA67,25230A9BE9803EC8,04091639C0296CC4,A397384239EC198B,161511675895337F,F6DE310C7434C1B2,854F8796F0C73378,E6A3653C22D2E9DB,4F581A3D305241ED,66292EFA1015A761,3182A143C8BA0366,8684786487BD4197,00002255868F12AA,DDEAA79F44257342,949985A19570EC27,6806F0522435443D,2F0C534110A0B3B4,54F623FE667A678E,ACF63B3A4C24FBC4,E9CCCCB1711B87EF,8D29572545FE4387,9318B31479EEE26C,419E36B861318932,ED09767B21D5B932,00003A2F5E3DF895,46893FF6E423D273,589E42A0D1FFE01A,5A551110DDF8927E,308E92FEE08332E9,FECA8F8C712179C6,23B0B1DAF4C07848,6E85BAEFAA309230,9EFDFEDD093947F7,2CF94A64B545670A,C4E77CB86E0BC5F5,54B62090C61B3AF4,000055CE229BB6BB,02C66D9E4C49F488,762053C7E9E5CEAF,9C9B4BFECB9D49B1,4291F4CF657CA19C,00D227DEC380EF8B,915C1ECBE1976DF4,110FA1B25B9309A7,1C5AC8DA7DBE9BBE,522CBCAAF60477B3,2BB3230542800D1B,36147BE510F37798,00006E69AA1D3CC8,9876D85442476448,C684B7B7A69AEA68,A87899A21EC5CD38,DE01C38FCB746A23,F3279B22EEAF6B57,374BE60518BEA847,5B996C525F44C9E2,110FADCAC5FAADE2,A50C59AECB5536E7,E4E3ACB287B1C841,23BB4A2C297B6551,0000642DF0E8FF6B,07C4ECB374CF6760,E823505391947583,5706E542C47499D7,8769AF5BF841BD7B,F410DCC09EAF9750,4558D38FE07BA2B6,13CE810FB0DBA0C2,6D069EA785D40E6D,9FC1B2925E4E0F23,5C90CA6E161AE64F,3C42258E6AC928F0,000014B535088E27,61F506325D390222,9B84FD2723E1D24D,E08A791ABB82FC4F,DAF1DD44F8116304,151DEF31B5F576E3,888767E1467A855A,9FE78D81FF258436,5FF8F2711BDC7065,F0EFC087FCB22D6A,BC85AE5DFFA79E2A,D3D488A8DC6B661D,000044840DE0BDCD,FAA022E6E07BAD31,35063B81D1F1F91C,BFA8C290D1BB61C4,44ADABC71000EF49,E2054A02DA8D06D0,D72FE7621B8D2A59,A4E1CCF20BFD3B55,B82ADC2A1DB7D63D,444136557102F263,B6D28BB000A27291,9A9A0496482EA42B,00004D5C4FEB943F,1FA08C76FF785448,595AFB0B26A34BE7,3C3062F7BEA85C8D,E8FF1214FDF44B5D,FBEBD624B9995042,6D73C8BB5F7F159F,50FF2B23E35D44FA,6C26B326E2AC7C50,8A8F2081CC0EA3FA,C462E1573C386500,727EB6A8EFA7D832,00001155952E0C75,25CAD0527702A25F,0C0A9C9127D79F55,45F63E5E9E1E3FE7,C3CC9E18E481AD54,81DE77D73BCAA6D2,B9F7B0894F53193C,868428DF6FE9AFEB,3C9F82A859F68185,2478FEEC825C5638,E620B05BB8944F53,1D0D19B435138F43,0000224A400EA11B,5D9789B2B3817CB5,2EA921268B7103CF,5C05D51C3A7F0BD8,FFB43A389FCF5F19,1AADC6C9EE1A70DB,BB75A1CB12D72C68,266DA6D313B9887E,918022297FA1CF25,616B4A36771F7BE7,54632491A2599EA3,9529D823311A7E1F,00003A3C680C10A2,D30C946D7F40B480,B8C994E2442E65B3,462CBEDA88EAA2F0,0F61406EE38808DE,9E31AC0920894202,1E27820BEE0E28E1,080F49F1F9BCDDC8,4929CC66BC477C0F,7632B06EDFEF2032,943386FC98729063,A868A1DB9ABA20CF,00003C14F2357692,6F381F67702CC6B1,9B998586906EA3A3,6CA920E63A65E369,7D94FB2CD1249DC0,D529CA2EDA05156D,73B84788432D1203,69C5976BD994DAF0,95BB88395A431F6F,4F881C3B1E76833D,39CE08E01DE58C88,406744A62B4F73F6,000036EE48127F92,6B3A79D7AC54472F,67B584DE8B857DB9,B9BA287ED810ADDA,E62EFB4C10A8F3FB,9E9234527E837567,2F8ED960C849CDE2,44C16545AAB24F3D,82E5376F2449B3CA,0E681CBDD6DF6D06,A26152758AE7E405,86885BDC485FDF0E,00000C5B88DB52D9,395B998074BF1722,DE535B0F15CBA2C2,302577CCEC4A906D,B21A9FEF3C316E74,48D78F2B71957C80,F555BE679C3198B4,5DA4A4047A8076BC,157273827D27D5DD,1918D51AFC0CD448,D587A5522701CF88,93748184EDE03DF8,00001EEE85008E82,3AC2A96A232A42E3,84A1523A25643337,D3712363CB1167FA,BD558BBC45CEF609,26CFE0341B77AD59,9FA336DB2BA6AC13,863BD9B9DF4ABD67,9808A0B350623493,AC06DE091D19AAC5,8936692252B09A6F,38AF01ED80EA2D57,0000159CCF914D44,DF61BAF185766A9D,EF113784C16BB631,6DA3A9267B6D14DC,F3301E49EE9DD176,19DC4B04FDACCAE2,48E1D418CEB3A198,E8CD13129A426A02,26FBD7965807FA7C,E3153D31BCFB232E,7109DD24E23ACEF4,1020FFB3D7311EA3,00002FAAF2114C52,D5C3A3962E692A4F,9FAE0D03586B8E25,0BE8D224E97B015F,C0C51D99B1FF8DED,EF69A2DD4DABAA7E,2455DB6162974EB6,50A29F54CE2449A3,6BACDEF85845338B,8973CBC6044DCCF5,034283CC9F0A983E,AC6BC2D958493488,00001E06CDE31B71,42C242A632692D18,2BA33952BB57E6A6,D8CB8BA148F69B4F,E9F9AD8F691A9BAD,7B360DC29BEC86DD,4C103190DCC57E83,FAE2AB419AFBF866,01D84851B1B3244B,39B2289441909D41,A2C5C7F29B1A6DC9,2EF251095A39ADEB,000039CB4FD50786,A4C3DDDB0E3098BB,3AB998D1956C5AE6,69FE689EEBC80215,CCB2F1749444AA51,0CDF8362DBF257D3,0E2E84FEADA91571,615030DA3659E301,AA97CCB72F13C27F,D6175F4CB32441DA,45133BBF7077EE0C,EB3A74175502F376,00000DE6ED3993A6,C553349102AFFDD8,1B1418EC224D3D21,4FBC16B5379D16A7,9DC7F55363598EDD,5E6B9F4AF82133B4,5511FED2947D53B1,A38133FF7806423B,D65D587BD7147D67,5DDCD042F1848ED1,3F11E41D858ADA92,37D7A1D067C8E433,00001CF6C2E7C567,68110C8B9949F47D,5CA152851108E22E,E62568659CB227AC,80D64E432DCC9623,34FCBA5E067E9E6D,444926482D68BFAB,CA11B9F6F2246DB3,A3578DD619103BE6,09BD45682488AEC6,FA97D941FF5BD08C,4828D1BA8DC45C85,00003F84D6554037,B56D29C55AB90DB1,246674874247360E,E2793653B48927E6,19CC3B6EC6EFB89E,3BD3573EA9686572,43BAA97BB41E6701,7C71CFBF7D3F7D7C,63D1A1C0753F74E0,21D9C69965A1AE35,B8320F44C7ED6684,79C7CAD94C8BE68B,00002104C100D4C0,6B5C42566B9DC9F0,4A7DFE8A71104957,7A73FB6663C57C26,18457805214ECE75,080D07BBE29E5AC2,7569187F2F7AF932,1A2137237ABB0418,A6A68E0A81653C09,D513A398DB146E8F,F3C24567BEEF71AF,1CE47DB350F49FB6,00000E3BAAECB67A,539CC5441EC2B631,674B2D60706E3B22,118597D884984435,0B4B722E3D9A8707,7CCFD6AF075BAED0,2E41301BBFA177E4,C075F39EAD8431DA,3A0ABD0B4A7BFAB5,BB835F84792F4844,E711EB4A9BA49970,8A6D4A80877E247D,00004BAA6832E01A,2D4CEE8D0FCDD572,82B45BCD89875830,60C4516656E29682,4DCA19EFF4B6530B,7EC1576182DA3E04,616B4605D472695A,696EA6A31FB363F0,1475E3234BB36BEC,10E02F68B53CC7FD,119160268066A5FF,3C8DF6E8540D9E1E,000066B19EAD78F7,1A3A284175539A63,1F81989BB766C096,D384965BB4B383B8,57304EF755E3691C,DB29B274765CB60E,7C572063F3CCCE1D,59A04F2960626C4B,8BFC86ED5572B206,C5A852039B6E088A,70794E18377C5263,0448D595E0AC5D9C,00003F90B6027B3E,52E94465F6CAEA55,44D4F859D0FAA8B4,A32C9B7A6F1D670C,56F5E4A58BF82669,F60834FC478BE3EC,874ED733B18EF781,C5C6F805D9115439,6F8AF9CB717BF3FC,44E37C7CF73F8806,C8A80D02AEB2BBB2,574BA3FD7E348DF8,0000479F9282316A,DCEC07EF18F5A448,44FAAE5614B148CA,2E8FE0A9A0BF0806,449D47CD9895F85A,E7268D64459BB4F6,583C35EA9D1591D7,1612A8BD646AF3A0,EE008B3AAF764F4D,E8D0ADCD32BF7A68,4A26E87B09C4B812,852F0D0FD5AA713E,00003504C1C49A48,F10AB9D871D437F0,5096D370A44116C0,7BC34322B59004DD,ABD3DF80B8185E87,95EFA678A443F1E4,2C4C04281449EDDD,FF54DB7B1B01AC95,FEA3D881D78A414A,01AE0173D1F9F5D5,004F928C75BCB475,8B95D056BC9F9A94,00004319D18F7AD5,7B1BC92FE701F673,E68FD0F9A6590B4F,EEC5A304BC69A1FC,3A21E96D47D0FC83,794FBF95968DEF12,D485C43A7F8B4E38,09F23C90A561A850,6D7DDA8F65F30551,DD68509F41B1C4EA,BEAAA88794DD4018,298C41176C2A6848,00005CB922423966,1DACF0D811A9E443,4C5C292397127F5B,5E32AA171C90014C,EDAF1112F556374A,B8D64F5B31152257,D2C0A3EE00976A67,F9F9385086ABC04B,74C767BD2A5F0207,C2D6322E499C26B5,CA5C239E2B98629A,5B496399551D56A1,000041938E7577AB,B960385AE4B18061,0D79C6256DDBAF60,77D207D84609AB61,E1930A3610553007,29D198BAAA65D941,75FF40CAAA7BA2EB,3B3048AFE4F56EBE,90D0B41915E4979C,88A27507E30FD7C9,8B43C01A36378CC8,E8B92A6F4593AA48,0000638801B55D8C,20F0EF014A7EFADE,EBF4CE99CA93D50F,0AED1688344E753C,ED23890D2C60B434,65F32CCB9E3997C6,FBA4B0024A24A4EF,9EFE5FC8E10665A2,D54BD7210574289B,7430141080AD6A36,CC9220DBEFDE1490,D6B1C5B25F74B580,000050C1E6ABC085,805C0C53925C228C,4394E49853604027,BBBA60B196A8C10E,A43894672F56C984,6611E5C2004B746B,F79AD8D95E8A8015,D161EC5F88DA48AB,4774368BD1DDDD23,8E460447EFAF0B43,2379342D4C273F00,DF073F1854ACA07B,00003ACAF6A9CB74,9446861ECEDEBC1C,BB6FFAF31563A539,8C651B1F8A897561,DF5EC1D3A95F8723,A6B4D1663D7A5B5C,9D4BE11736011068,BD83FDD3A08610EC,57B2B728D6974659,0CAF1123890D7ECA,BDDB7019DBFC8D8C,376CC49BFCAAA3F4,00003BD354F2314E,795ABC23F1ABCED9,20CF710B7F3FABBC,5A2427D668B228F4,A11E54C605EB7FD2,0662CD755A91B43C,3B3560FFD624F48C,FDF54FD5B6DFA37A,2A224160E02EC4F0,77F37F2FF6953BD7,7B04CB54454F20F7,C4987E0BC85BE8EB,000008FA449E5D5A,5993E0E8231C0117,07864EA89E00E2C3,3AC7BAE440DFEC60,192D86748E677063,41CDB6099D6B4102,E1F3DC57B0853110,CCAFDA6CD3D850C9,D039F75D07B487F3,1B7517128941F23C,A3F57C36999F7A41,25793529081D9A99,00002680DDAAC579,53D3B66C9C58C56D,CFF08BC2002D0423,0E98E8FF8C7B2AA6,EDA65D088013BC75,A2CE9103EFAEDEB3,F4A228102B2E1DCA,4214496BCD5CD6E9,0A6373EC682C6C00,3E23572CEEFCB642,1CC9CD9A1EEC0B10,839ED2CA9CB7712E,00006C1C5283DB74,6D9DAF56C557BDCC,D9E164B5855F6F85,66B7E4CBF6FDBF7F,D41B250E3D8BE0F6,BE121454A288EF40,D12335878D0B88D2,3A5A567644CED2ED,46F237D959F5A3DD,03422A66E3CF330B,E62E8F0C8334571D,749A3AD8A93C1C7B,0000481D16EF3A03,C3A91FE90F555780,803D049AB102AC3D,78F83C1B581DBED5,137D976E2AACA44B,9124B60743D20D6D,EE56F7EA8923D3F4,AD53D8A6C8AE354F,56C96FEA2995241A,2D8AE1EE5B2BDA56,CA69A77AE94DED2F,C43B18E1621385AF,00000DF2B2BA99DF,3E378DB228B07CE0,F260F2D23F2D2E55,E5C28FF0D1FB3692,6641324765971AE5,2A06E14C76422FA2,4D90006C710753A3,DB326BE271A23E36,DBFAE8F749964312,5863D2E804F35228,209E25DDFF5647DD,DEC606923F2CE1F7,00003F3F28FE4533,5476E6657972C58E,975C378C2E43DF9D,DAF31A94431378D8,B1A2742F32CA7041,C8DA83B8CF0AD3FF,4DDCB5234C945734,4743E895EF9C476A,776E4EF9233F54E3,00A2385E8E98A428,6E56B5F2966528AE,E3E9D87D385623F6,000039201CD22950,5D65682264786C96,28721E2A7BB030E3,8E9708F00E16EB4E,0276B4367B54F9F8,AE1D38394335BF5D,FB5FD7DDFAFA5EBC,18C034B34A3802C0,50A36F4142562E45,A2FA98C375843C7F,2C548569821B4000,A24BC682BB8780F6,00001BD4D0C598BF,2FBE57C3A54C8E87,4FD04D76F6CB6606,7AF2A88A8B4FD1FD,6DB49FB65642C6E6,46279DACFFC26FF0,62B60D6B03AB23AE,7CD65C8FF7BCD048,49C657235DB28DE2,582E9BC253C2E30A,330181DE80F18D5F,E0EECEAE32C91BAC,00003F498CC7FE49,25FFA7A177D8C8BF,CDEE4484226E4AD2,975DFE6920811FE2,CDF9EFDE8104D4F4,8A5C96D6743701D8,AC517D4FCFBFBBA7,4D825E22DFEF05AC,0B858CFC35D79C0F,76A2CBDEB183016C,4D43C81E6DE579CC,A26CB07595B59A22,00000E3D8FF52294,2C9DEB95F83C7ED8,A90CE5AE13775473,9E3E4AFCA35A2C0F,FA192EA5D4AFAEE7,A9783B8258F49B85,B8B914028991060E,8D269FE3703DC77A,3225B647F546AB80,66066F35F028DD4D,7E2E908C95DDCBF7,F6414B9E6748FBB8,000058BBC436C552,14ECD049AAB881A7,9BBB8F1DDC7B7E50,29A61DC0019E1BC4,EB28E861F95F78B9,6E57E7C31C1ED3CC,4E08EEA44A61A26D,4211E4F98172FC33,D499B38A3F2B1AB5,BF9C3C35DB08875B,92EB1F635BC89180,C8A79B87D52B8DAC,000065F13A16DEB6,14D742722B7A3439,A79E636E8F450037,2ED11164113C7CC5,CA137F5E5A17D082,408CD33AC0301058,46EC7DFF8FCAE800,8E1AA81193DD1F93,0523147BC2B6FB21,0603DEC484CDFD2F,E4439C9683463658,A84F9613E4C61008,00006526F6F7CD92,EDC4E71E448BE276,3F93998DF0178C3F,3AEFF75C3CF7489C,D41AA213FDB80797,4252BDD084AC5E0B,83CA020B27BCE1FD,F644DC71D9F7CFF0,0621F1C70141A80D,31A0A7EB1D4A17A7,FEDD269DBA32E67B,B7F542207C173BD0,000032AC105C18FE,CB73EE606A0BB146,CE8825B653BBFF06,2949D4BD67C2BD77,83EA49D49ECB6F87,8BEDE47A1853A681,7BA85A87F0D5A7D1,6D2180C9F677229C,3B84E78E54FBE5C2,BA539160446BD0CA,6B1C51740DFB4953,1B5C3E5CD3472014,0000560A1B14FAD5,53D2C03946B6477E,60DEA6B430391020,07B4A9EC01B04758,27513FCED5827FF1,1C6102C787EC83AD,ECF1C8614A53F1C9,33919D43E08FEAC1,5CCBEC3946B1A6A1,EB84A1A18207EC58,E15A62CC2E75151D,C446612A59B90039,000046FCCF34BB28,3F6359569BEB12FC,D14643834ABA01B3,53C8657957B37678,3A197E01A0F4105A,2DC24465F333E765,762792631459A6B4,E7B94163B3362F28,9FA7C3CADCF1C682,2D6CD9B0DA565FFA,90F9B7F364C5F0BA,5F61F2EF24E28C8F,00001DB4DFD55EB3,F8006C1B0120D17C,CE439B280837BBA1,B511655B821E33EF,994E837FA95CA0FE,0F390BE00A11B794,BE4C874BD9B3B238,E20650B501F73F49,7E5A7696BE3AA3ED,A7017BCD0C9E755D,E2918312EC17353D,C8C608ED2D2DF5FE,000049BBE98AD2E5,C6CEE18D534CD46A,369D32BE38BF3EB6,80FEAEC59F0D2EFF,1C6F7FBE97D05AFD,217DE218F9B07A52,FD0BE9D053A87D9D,37E0092BF51CCBFF,BE599E100F6E2517,F7E141E5D0E19F36,3D560A0485B85B56,9C9767FC0709055E,00000F7554882C65,8C3AE12F695ED458,4CFD5AB30ECD3CBD,DC7ADAB921F8E16C,915DB78EC8E6ED77,2CCC9CF0206C0478,43FB842320867AC5,62303CB5FF70713A,2E32F7F50ACB8212,8A559868A36557B7,9E86C6ADA013B40A,9A0B26163828D0DC,00002D85B8A64DEF,976F755D00254AF2,3E44A7FC1319570D,A65431D6912CBB69,A4D812962194032B,7E30D3A8AE82E77B,65780F55ABEECB3B,D6B7F7B71F19397C,27862C61F60DF4A8,FA6B2B85050EC741,A9E007064A2B0C2F,7613078B07C88DDB,000022D9DA65AC1D,725162062E3585E7,B799A96B63CB50A2,C599EB1513BB5759,D6D3DF36E5507749,E18414F457840E48,5E0A2C70B4708C48,AE55B050E8BB57E0,8426043A890C1A07,7B1D04FE7AB2EAB0,7FE73FFF54F969C4,5FCEF4EC7FE12AEF,000039653C73D51B,40DB6540F6966E2D,6F640C43D6945029,E29B58C9F750502F,88E18B0A59E46504,ACDB985214A23A07,58998061F3790F32,91D66E0315F60629,E4DDA633FA590986,C4BD67ECE30D1A63,9ED483751AED3122,B3699B01ECDAB997,000056A74E90A5A0,F2AF8D6C667F6FD0,321ABA5970FC8BB7,F494739D6521E719,BB7F15DEE4771C08,14C0D6270D480A2A,704B6DDC996DABEF,FC3B9310F4618A66,4537950BAE45DC28,ADB590BFDFC57723,790D8E0F2FEE4336,7359008B8C0A48E1,00001050057F4AD6,611B24231F0F6547,5ADEF9A1DCA51369,635EB077A34C4305,AE857F5DFFDB50A6,55FB70D8C16D36B2,39F6F3BB59CA4118,24EDFF9C587A6293,C3733936E8EC930A,5650022D369C9C05,C82AF861269F515B,CD620BCF4D44A0E1,000006E0F8A4CDB8,4D5771E77A7F36C7,F6C559BC6FBA19A7,B6205D0DC777E07D,0AC635A4588E4092,76902E4DF1B381BC,D95EFD43B07E3F5D,8473AB276709302F,265476D887530676,972AB7ED44C0A843,9395B4899A8B32C8,F2A6075C2ED73F3C,00000FC95D33D216,10F9B52A9A354196,7AF23C1D3683A72E,955D2665E32DAEF0,0BA3F35AAC988710,F22275A8B3678DEB,27EB94CC0B5AF8C6,170E6F3216C04DAB,789B505C386BBF0A,2525F1080AC1332A,B1163AC340243265,BD2EA45804E58C1D,00002FB0BCE8981F,E75D163D59E20A10,D45ED77AD4FED89E,FD69F9AE8A44C9F0,399C9D3A568C043E,22DA3494DF221908,7FB136727030B483,C7BE324D7C98796C,54105F388F5CCAF1,98A3EE70E12FA676,96375E85A143FFA4,3A22EF28DB54BB76,000014B1E6EF8489,7CB86A9BA0BE71CA,6F3147B24957A29C,435D61DBD6DC6AE5,7E3285C75B95447C,0EEA4DF813B15EA0,30E367FB01508360,FD342B825244B7B6,612D188E7596079C,6E2035B2A89F788C,16A52CD6879544B9,3E15691052E534A9,0000477623D5EF59,10BD832A7C5BB5C3,08C2E80BD7A93E84,DDFCA8BDE59CF8DF,814EBE5DFC41B35C,1E5D3B8092994261,980AB0B3935AB65B,9FF8DCC56B6E625D,C01FE6B770D68C1E,0AAC95B68DC97ADB,9340A257BCA127D5,18E271C587E183E3,00006AB27D62267E,E6C482276E89447E,DFBB0E6CC945053E,16083A06EA77A7B6,A65DE3F84E1FA6C3,2C16D508E20EE04D,8756EC9E454E7AFA,81D0B19B71F312C3,BA615F3D5E716D30,969C27D716456D12,9F97646989BB32AC,A93C643778DFB4F2,0000614C1EE987E9,024C4BCC5F1F4F60,B97D2B201772C2EA,E74C0D0FF1142414,27DBB7482AA30125,A0AFA0525C89A52B,52DBB1FCF009E467,54F54390364BA1C3,6CAAAA45C79D629C,1FC6A73E877FC7BE,608A3A844331D3AE,42C8C8B6441ABC27,00003390A4FD8457,F1D9390EEB4563DC,627C2847FFD0C6DF,0734610D8C84548A,27309249F47923C8,BA78F6EBAFF9E57A,554CFF1D68BA3C44,F530AFBDBDFC1C1E,8A43731611D0E2E1,F839F8CD673B451A,638183B958A3E4C2,5A33C88F790DCA18,000058F096EFF0CF,995DE5F8CD8955E9,07A6CC0E31AE64A5,6049360255C34840,3492E4B061E4F295,4C212B92A74E7B18,7DE16AD0A9EBA0D5,229FE52786A1E145,44C45E6425BA2199,1B394B016F1923EB,79E8130B08E9977F,F68BCAC44AD003B6,0000179BBA634293,5C42A4D655D3B526,8DF446BA001A4A83,3FD75E27AC1588A7,F12D0CCF8D39CB9D,56353DF874330AAA,939A3B3E16706941,F623AE28B403DF3F,E235A3907C36E9E6,497BFCFD3400FF3D,5E750DEF5A6595B4,18DF55BB15113477,00006DADB8A46A88,297C4AFB59510DCC,CF6D41E567D9177C,CDC46904D52F908F,D96FC41C346E158C,3A0CD7921DB49B0B,6572BD8EBF5BB524,D077C8DC321E8638,605B7479DB060254,8AEBD395D192E641,35C55FAB67952BEA,551D614285CA24F1,0000044751B9C4C0,874F94E1CA2CA4A2,183C838C19D38D01,CC39CB41CD682C4E,C262E9E61F558194,80F1BD1AE4E8A353,61B650A2FC8EC91E,26106FFF1362520B,1C15FC0825D451EB,592B470DCDFE3C97,E9B644FCA83D8C78,AD2D0E4CB47F91AE,00006F53550AA59C,75F352C2014154A9,8C3FED665E064D3F,A11DED34D6489E4C,0D9040DA91B2212A,4D4E312A05404A97,BC991DE26DA64DC6,F697C15CA92C82C2,B53EFCD0857D6575,F54816BEC584DDE0,A3E3D14BE7CC3637,34549B06C1F556A1,00004822715C009B,0AD1BEEF57A71169,F72D79B7ED9669C5,D941F7A2DC5CAFBB,07BA8707E558008B,4FF7620A44181E8F,B87A308BFF508663,9ED9B1C0E3BCFA1D,DC57B8601F45C46F,ADBCB56551741253,A40EAB49603AA17A,8151509B5636CA5F,000016C20DF9627B,8432C3B2D0FF2429,F1B8E44FAA0DAF1F,65F50151DF3B2C8E,6BB80030433E4B08,11FF5569276E3E8C,E75E1D99A7824C9A,96C048C2E9191407,5F5A9620B9CF877E,8718C3814B9A792C,E52A97F7F83D8F27,F65B8F93DE97D6F3,00003478A68D6FA8,26537CF7F8F4704D,59BF00AF734D0094,3A22163DD0FFF8C9,27C7B89C40D4C93A,689943DAD1364EE9,E23C047642C38E25,2ABA113253ACC57F,8250FDCB3E60A7F7,9ABB35CE069D73FD,FE618F42F932F25F,DB445D962915E6C9,00006C563C75A7DE,420CEDB0F26CEA37,31AFC486993DF8A8,E936FD4AD5E83DFA,21304B9DA5756006,1D9EF5D204B437DD,C26B9BE8E6921A2D,3C0DF9AAF127C9B7,13E8093A44CFD7E7,4AB3BD7DB387929B,BAE1BEB49EF861FD,0EB38E4A11831FCE,000024D71E2AF8B9,BAA6AE74E603F7A1,D6D25D60AF0A2E18,7FFFF2A63ACADC95,BE6564300B7CB201,E95BC7C3F73EA62B,FE26CF3ED7BFBCC4,245FB91E97751ACA,1601979B4A213D07,182981E624803D4D,B7C102BCF1AC54BD,0FC74093380273B2,000013AB407A3C96,2AF2FC92C6C0672E,3632724AEA36BB8F,98B984773186747D,1A9DC89EF7E7D3A5,DB529D20D909033E,D5966774D1E7B5B5,22AD8105C7359CC2,F5D61822D8FD93E1,3A65A86E7C4F397C,D03312DD92C9FB0A,4726179F0193ADE5,00005EF91EDD1FEF,CBD2024A0E0C722B,55ED5A6D557154F1,CE814D4BC43799D9,BAFAB59110D68521,5153675929606C80,343A36A0E62298F7,DC2ED6C15EBBC46B,59DC28286D0F4F2B,9D0BB6EF721320F7,6CAE747BDD074876,344191D4D1C9F13E,000049C5FA7C00DA,5709FE7211160828,04572F05C2E67C08,C6B0429DBCFCB1F1,72F455E896AA5DDB,F2C968950C422F34,77A35FDA15C3D300,925BCF28885C7C2E,949687A02E3D5D7E,7DDD292055A988D2,AD63CEE1B4F0BA82,C79850918E93A2F3,000005405C5E1645,38D3726D984F17F8,212EC46A10B1E220,DB5E237EC2170631,BABB5A7EC308C96F,32A865F2BED7CBD4,67DCA6C0E34CF84A,438E6E6D7B2068E1,E53D9DC184B1E29C,26068D5C30AE2B6F,E25ADA16007A75BC,B856FF318FFE8ECA,00002AF0FE5699C1,A486963DE809630A,5BD904FF3EC619A0,ABC24F21B060C5CA,7C4903066DE7BA72,7BF3663CE82C9CD6,F6E3BA76D0EF1113,171D6806B2362D94,3BE59C1BE8A71DE1,8BD8426DC4BA75D9,DA0196EBE9F7746E,5F1C47E7327E60A3,000017D8EF02621E,60A671BE9798F6E4,93F9012BB9C146AF,344F4395EA39B301,BC4CF0B194FAF139,285EF2E792B1961C,7A0A5D8DDB0514D6,F2BFFE1BCF9C7302,F3DBD0B8BB77695D,9F631FDE9C151BD2,9048027808D946F0,F1E552F49D62D614,000034446B8BF572,7CB51E3E3C0B3C7B,41B4054B70B1403E,339980A2247BF8F3,77E1ACA13080CFAF,D45484A2B1DCF272,013070721A869A0B,02464F91F43B3C16,3CF9C8DFE5C64D40,4BA6CD633CADFD6B,63A8385D6A6A8A96,3BEE7910C5AF750C,00002067FC9347F3,FB772B11A00AA0AC,32908587B27DA031,CAF9A5461745BF7C,7E3995103D35A917,647BD1D53032184B,02CE3CDA0817A164,5F53131C028693F6,8E68D4BC431AE790,3DCA90E6B378542F,82F94710793C772A,F87E65EB14A64B35,0000293D533B1FDF,2FCE9B54DBA3612C,7E435BFD85B96812,01C9862FA0661A25,81C0F373623AD24E,A8C1EB038DD622F8,88885539941BB398,DC1F8B65F40C8F8D,7093D0D2B7BAAE51,353C6C6DE9F5F6D0,623F91A701A82498,F6B5A59DDCB19131,00002340046DDC66,E37AD1B1769DF10B,4F1F21CD6428DE9C,60270CC144D4DB12,3BDC87BB77FA350E,7AA6C164D8554C02,3DBEE4AEAAD2139A,8B12E299C763EB9D,7B4FDFF4F9AF4A8B,AE3C29B833D47738,DF0C777D6993BE58,F774672E3454E7E5,0000232106DCDE41,CD7391D914487964,A5FE8D35BBF6BE52,0278A43195B7611B,5589BEEB77E9204A,148EA73483985C61,70EBCD41FEF69DFE,5884751A02968D98,0FFAAC2B7C670E86,263CA14D68CFE7ED,00FE5116DEDD7922,B0169472BD4BCAB8,000022405FF3D4D2,F146B1517B450C0B,B354FE587A0E52D8,05E0D82C766CEE7D,E8D14A0DF047D2D1,DEEBDFCA5A02B3ED,8803BD2ECC8C6997,8FDB7AF37FC119A8,AD39976D7E570BD7,CC676F5D0788C4F6,12D93EDC64EEE672,257561934F0D2D1F,00005B8584EDB29F,8478AA7BE0B0E768,0B790CC44AD33B34,21EEB36608541A8C,20EC0FB6484B91C8,84655E51655D0613,C2BCBB758BBE1FF1,93CD5A06FBA4603F,716111B038EC80DB,1BBDCEBEF137A734,83F0DE73E029E845,138765AF4D10DF99,00003E0B4551669F,7B5690A51456759A,48F8DB9EBA05C078,A4523F31852DADEF,18CC8D09A6265CF1,6C554166977C80B9,0BE7BF8085B1E0DE,4E00412EAF67A122,437D3027B6EAA942,CBF517C7E13F4725,D02DB13AF50D2F8C,1163699183718296,000007D97AE17A5E,17CFD57150A51D67,060683A86A461A3B,CB8333CEECBE558F,B46206C09728D589,21B2D0140166A008,9824BF61724ADEAB,E89C911DC1D52981,FAA3007F5141A0BC,5F886B7B0BC64581,AD9B25A9F5530361,4AC00CD0656CABB9,00003957B241FB8C,CA81FCD70591BA10,47DFD74567B6CA3E,0A208639548556CE,D09C7DC333A6CE17,79E4077855067A7B,879A867F0D8A4C0F,7C66E4ED04AD3475,B3AE166626C4057C,BFBEF2C97228F98E,16A0F024050023DF,5716B7F3BD9541CE,00003A840EE678E4,C7CB62C88980E428,009C9EBD1CF954D5,68B039F844E388CA,B314C8FB5A05E9C7,41C884E7BF22B2F8,15664E8BB506DFB5,281D0330D6A15FED,5B1622AD8917604F,B147B168290BE301,9EA9C87F79C49F8A,B46E69F418E017E7,00006868ABBA9FBD,DF4A085F918DA85F,95E9E7E9158CA9D3,D977DB180FDEF464,0E4262E1678870CF,BCC5FFB0B97D504A,97AE83B3D76551C1,B4BCA8E8973DCAB8,038F0392EB3961E1,1536CF3AABA53F97,D9F6EBA54B207D34,AC6F6A6B9FB78C8B,0000267D0595558F,0C06647DFC1F641C,156CBE84AC04EEE4,CAB561F276C08CC1,497B8616803F02C1,0D1221552E3419B4,BD858DA6D8C1508D,E993F8A7A01A4844,E504765E4AF770AB,D2038331FD855042,F2482C0DC438226F,7F6F1B4AE924754E,00002D71A881BA66,45BF4C302FDDE26F,AC92699BBC893A99,C0644772005355E3,E13C0E4F45B72B4B,898063CCF353D657,DF1F82AC7B52EB99,EDE9F3EABB31FF95,AAC01B3E24C826EF,B6B16BF82C452628,726AA3AB9F30459A,39778D6128CEBC92,00002E2F25814217,7EF3BE5DC6D74665,4C455F0929B20398,9CEF5E0EEBB49593,CA319E5174D2B4D1,F7B783E9A1FAB459,6FDB0DEE94A7F912,7BA3533F6ED72869,CAF8160007706AF8,E61F3EDA990EDFB1,089BB8A3D2245CE4,47B305BCEF554C1C,00005B0BDB4E529E,724C43C0DA0F5419,57FD3B245BEA4019,1A48059B386E66C0,4B76D2FC8474270B,4BFCA47404E19CB6,FDDD54F64C948A22,E9DE27536EF1BC05,C69AABFC2F75E8A3,9A7ACEEC1C8CA3BE,FA703FB973D8B04D,7DF01E656D3AFB0F,000046C673FDA626,1E4DEFE963A21A6E,6394B69413733201,6E9F69AFB3476448,4309958BEDA2CEEB,84CE3BD9E553CDC0,930508439811D6A3,7EBE3F47F4A6DDE6,8BFF65B47D573D1B,A85F9A6F8372DD8E,2E53E14264A6EBF2,7546FC605B4B5D44,000012A9D3FFC620,16FA2366A8E2E654,31731D8F5A4D4782,E9E352F7B62468D8,FE3B89EF86F6DBC4,81A419BE65B833A0,BC36C65FFF1D3F10,FE4EA35CE7E6941D,3763CAE283AE6E52,1452834B0B5142CA,3AFC5D311338ED49,3F3B2A2B9B01555D,0000359F374121A5,67829ABABCA53559,D377BBCEE7E09254,831953EFE7591A43,7CF0B92D9BE4CC02,19FBFBED293FB577,F053D34427263B63,26FD322EE010A2AE,DAC8FB3F9F6DF11D,30820503BC1FEE1F,9022814F4F7B4149,6FE8110FF22DDD39,000063BD1BF1963A,379DDA0597B477B1,0D222210034617F8,1921AC9FBBE80542,7FB9BD42017FEA3A,A67D0D217762A7A3,911209CA36914A73,DE4A3131FF272F43,DAB0000ED26FD142,E41DF702800EB71D,CC5AFA0F19AF621A,8DAA554951F6C7AA,0000220777968EFB,C2015C50626D093C,DE28B88E0A4F5188,1D43D0762395FA62,E338D9D637CAEB93,09F0E401C67A322B,DDD4EA048DEFA832,B04E19A102213FFB,827B4ABF6B3FB281,CA3D3DF5284E2DEE,12F2ED6A7C7CEA11,87292B83C0E36A51,00006DEE01789082,53307C5631ACB176,F40C0A5C4B412572,DCCD387EF2FD6940,53B8033547440C14,0E06697F64EC6E0A,583ED992D096FFF7,2345E90C5920D050,ED5D316A66FDED17,BB00D422E58B5640,CC0DE70417BB1142,F6DDC24F079DF97F,0000281CAC624730,E663A0C93778C728,0087D3B4DA13F26A,E208AD604EF8C223,EC58E5759BBB256D,0D879F1AA342DB14,8D73DC85DAC821BD,D8B11F602FFBA998,3AD77DC7B844944C,AF1B85458D899284,3014786F501DB2FA,61142C8C8F2DEA27,00002CB38A677EE1,089D361AE1880E3F,C0C7817AA8BACC46,D71335619C1A8930,61B2AEE5E72533E7,FDB0B41EDADBDE60,200DB7464B83E551,34BBB190B38296AE,E7A0D2C9B18B93A9,BA98AF319CB365E7,803BB6A7E56CE785,E07722D496AE2D51,000065DCC24D1146,4A828D74A2868471,A7196E2529820C3E,1B5B294A34212F6F,4B8764FFF7EE10F1,A6467F8AD2F80068,A6C54B438BD5CBB9,66F8B3EB518A0EC7,5FF99FFCEB5675AE,E2087DE2D9868394,E97944AD327A918F,E6974F00C9BAD102,000028F61D0E053E,EE0FF132C28F7B3C,3D4F65DFFD2966CB,D2BF631B767FF366,7A8DD41EF19A0588,A4CFFAFC8DEF9E00,21BE708DB0065695,21C13F81F9C356EE,76D7811CF38995EA,BBFC5F54EF1A1BDC,3A9A2C8E3BD5596E,2797E8E3F25E25A7,000023829139B588,17B1BD47EE7E8A05,03F860238214073C,E9EB802F0507C483,4D5CD8072E1F2A15,6954F25BBCD6C9BD,72446D97278F8BE6,82ED985A903BAC5E,CE19CF716701E212,50F58218E8069024,E73989B24ADE9723,D2455DBFD2B553A9,00001EF5CBCAEC49,7A1DF613713371EE,08CA491BAA881970,9C9F6B9682BD2ABF,A0A387EB3D1FACDA,5E46EA93F324ECC9,C12C6F0A46B02BA8,9E11265AF2C98438,45173232EDC064A9,E07BF3A57FB10135,770E4A8BF717E2A5,C389066E6FC293B4,00003F12801D520C,1CE9EAC5C3B31755,692833EBCCF32009,EEDBCAFBCFEC5870,DDA2FF2F5DD52278,F03417A48E779FAA,57B5B9131AD9515D,2CE14787B2883829,A1332FE3FC439DAC,33DE738F07CEC930,B0928537D86F8DCF,63742497F9E6A56C,0000592E54D4E4A5,F1192AD46C389104,8BD5F2472C79459E,1C4716B55ACE320B,7006C99EB8194128,A0DB80BDA8B0C74B,CD04160717BABB56,3C0A9E458382D6A9,4D1E3AF03071DE92,32E34CC26F874D1A,78ADCFA89AF4AB6F,44D14DEF3AB19FF4,00005686D8CAC88F,7F5897E31E254FC6,4C2444B1D1A00A58,1570E63BAD5320C2,3D77267179CD25D4,EFE2039BED97C963,6203B21F18F3042C,469393E75EF0CA58,257026D8B81F56E0,31D6328D784CBE47,9B0787E9BE3F2B59,E879911050D3E29E,000061D1830FE464,EC743FE734BE7498,47E95CBD3E6591EE,6AC0AD199C0FE5E2,6B67EDAF4ED22671,1BF40D1D7686EB1A,6746162C6E95CDEE,301CC2C035DA968C,CC113F63249E11FA,742D5A5A40FFEA53,1CABA30888261976,C442B518C41A66F4,00003A27BAF8C46B,4B749BDF1CD867DD,D0712EBA86A9CD5D,CB8EA73B3C36DB23,EC0A82D175E75F34,44DC4994762189EC,CB71210EB3D15C52,A2189773F41A9BC0,E2D783C063FC3D29,BDDBF504A26122AB,658515D72FAAAA12,AD1D762A57E2A14E,00006D864FC1DA06,44980F48DE8ED4A9,0F51E887F6ED3AB5,F6EAD246F21199AB,D7C9C3EBB6E566DA,2E747BC93801EF10,876751947681EF10,8536785B9EEE63FB,DE6FED5457817CF9,BDA20EFD9E7C1D02,5E31A08CAB69156A,785D1D5323D92EF6,00004FA4B83E7566,8EFA27519B42D51F,920C37C80FF72779,9644E25AC6F862BC,93F873D8F5B5ADD8,8B8DC74CA9335506,0CADE2DED22DE737,9902FE9AE485FD06,DD2ACA9EB775ACFE,D714978F04ED2CBE,3742C41EFC1DF50D,EFAD885A712A163F,00004A19050322F1,1D7673EDE315C8DA,3068A76D1FAC57D2,27E6C5FE8D548199,5DB5D74EC8EF5784,D6500061C768F722,557758B1DD69E353,11F595EFE130EDC3,4A960FAB375D23C0,0125F6F9AD348830,FAC8886DB512A177,C69D9FCC95AD3E95,00005B20587F3FE6,208591C0A24B4E73,773DF1DD1CBD165B,12C3A168ED64CE73,C412D546F92CFE83,1203B6E8EBC5AD4D,5DAA9CB0891ED400,EBC85154A7554C74,325152462BD3B2E6,65C681BC4887BA20,5E14B46432CCB9C0,329B981CB92DA5C2,00001DDF6258BF90,6C81497868433F92,E7E1CEFFA01DCC6E,F3C35CDA8A2E2A9B,50C477CD6C08ECD9,947EED3F19C67A42,A84F52893B792981,11034E26C88EEDFE,8FC6DDF16F3A8D1D,06315B258643447E,5C889EE76E77C4E1,08326A04CF9FCC5B,00004E0958F09233,FD788A58501D3AD0,F6F4B2641716783B,14417CE60994AC4D,BC24EBEF50134B7B,C7D10CD9A0BB4A89,5176CF95A6BADCB5,FC874606692202FA,9ECC164DD6B42CC7,5EFEE46F902F022B,AE7C760B8495C285,7BF53B44B45F5E2E,00006B459F86003C,75BDD7228B9583BE,816EACBC1A9AF527,DEEB11FBF23A4ACB,DA4A46379F08FC6C,445528731750B4DB,59AF067B3CB124F8,E6ACBB8FC71E68E9,1C33DA427307D8D8,F02A33BCAEAA20E5,9DA08E42E4ACFE71,04069CDFE6ACCF87,00006C82D5DD1B9D,26E718885130A7F2,2D9484896092AF3C,E76D737276DFDC1B,72A01BD190F583C9,8180D5C9379B6600,60BD1BF11C5902C9,4789256C9C45EA67,BCE8A54105329642,0BAF3309ECEA7AE3,FDEA338FCC9E6104,0AB7395F1535B941,00006685682F8FD0,494052A07F978440,74EBA97870755AD2,57665F8168CCE3BD,3DA2FDC52ED6642F,070D0FE86F2CD1C3,0DE6CCEBAF4C6958,165A00DF170E3F09,D9150930DDD9FFEE,12A3F875884881C0,826B89FE7026F59E,9C3678E81937CC2A,000062D57761A93D,41E77C4BE1FEC958,E241D4052AD4EB40,0B3CFB93C25B4E45,9D40CA2BB595DAAB,284219EF64AA203A,15B29E804ADDC02B,D0C2327A96C86460,D69D4C1842B9186E,88916B1DF011D111,E9E9892849550CFB,5B9F78DD921CF6DC,00004443C446B3D3,6EC74D6BDC5352B0,900B2B72F4C3DFB9,4A3A40048BA35201,0A6B1E7FCA1A0D3F,1F6FA6C818F9A8F9,A87645FF81C2235B,E71508ECB64C8CB9,36F8BFE58BA388BD,559756ACB66C86F1,ED7952AF9777997F,8C4892D145414119,000003C6D2E984A3,87F38FC9E5281451,D0E998C70243E705,ABB0E508B1F6AFD1,1DE6CBECF6AEA008,1DBDB2B96D14EF4C,560477CD7A062955,16E4B76543A04E4D,4F23BE07EA25821C,468A604B1FFFD4F0,618F5884A6546FA0,AF0076EDFB64FF58,00002F633D5465C1,8E77CD83C15B3D4F,44B773D79A95BA2D,B72F5C09ABB72D5E,28A0D87242DC72DC,65AAB92D9F39A9C9,8CFCFDD5FFBC7105,1B74780F9162E929,1D589AAD8D9F3880,DFCC1A0CF1039B3A,07B5690C0786B2EA,DFA64100906FB679,00003C00BFBC2C38,6D8ED5CF711B801F,D82DF89A0C76B853,199AFF7458BEA8CA,E1943555616596EA,E126059302F5F6A4,0DA02ED9E536A102,D75A311F68CE20D6,C32FF7C8CFC625A9,8850F7A29926B4D8,921CE835DFE2D3E3,768C76A18E46828A,0000088FDDDB0194,ADEAE0DF740CBA04,8C41BAF39BD0D599,847AD8C8936A30E6,B99D33B10A82141C,62C953E35FA0CAA0,B93AD5E2BD6DCC76,14C5849B5D26D030,DE1F97B527F932C6,9C0D7411CAA8B0EB,CD88B162FB84FD34,3B6D5DA1197C3648,000057292710EDC8,9A318E2BB1490572,91EB1108D891B1A4,94F129377E516474,511FBE2E51F20DDC,C4107F65344EAFB3,86D334703D7D6E72,63B7368C9638A4C7,5B3D995D05D13DC5,89737D1941AF3A0F,0A9DDDEB1EA2FFC6,4059DFFDE80DD475,000051B1AC08C82F,75A4708F171A15A9,B0002F1A54B53CDD,27F9BF0E7873956D,5847F0960C41483B,5BB81714E6125622,CE530F7CBAC9DA0C,3793DD3E51E3026B,82A5A19163FAF25E,A451F3B07FFD6D64,9C574D852FA5EB33,0A08F9856AAB508C,00005EC3F81CB474,51D3B73DCE3E8764,E6D5D3DE8692C244,3678806A4184AB45,84F2F11A109D6B21,613FAD0F44EE9B86,0AFBECBC850C41E5,2B2BD7793AE60128,B4D677DB3C3532AD,7F19F96DB4437236,49F7DCAC18D718B5,9C814E443CD4E7F0,00001786B4CBB1BA,CDE421490F010736,709FBCFFA79DEC2F,68986F43D168266B,37F84E3F3758C7B8,29B6093C9A8F65BC,75F9F62B324C4FA0,C298CFF19F4E337E,A39FF7F47E9D5EF5,5A05651688CC8107,188EDE73292CC641,9B228646D6DFB778,0000294D174C1CF9,2A5B78D3176D6F36,B1EAD16FF443C8C0,B8788D9D47B750EF,27E15B64796B021F,C4BA5BD9351AEDAE,AD8AE67207FA26CD,09176FB271D74375,AAC43F0E323384F4,6F9531BF7E858667,7A49C86406CEE600,B4AEFC82B68F0C66,0000658FA44B1493,B72F560E93E9526B,120DD4146B2936E2,C688B24032B223F6,2E2969013CFC74EB,66EB5A214934BE17,04044F0A323CBF46,7958618FC09858A6,9F840F5087919BEB,E22D81C10CDE4995,3A328A3E6C2510EB,ABCE996044DC717B,00004FA3E683ADF2,BBB27B1FE42C52D5,2823DBAD2CDB30ED,7F601CE461B8A05F,3AC843815144F35F,7CF7C26DC60E501E,73A51A10B0A4ADEC,6FC13F1E0F29919B,6CC3DDEBA5FC2CC8,AD870DC000DDE3AF,4BAA0FC96D29BCC7,70BF40B9DD662BEA,00003A5888936A5A,2368F969D1A4C919,F4F1BBF89F859134,D87A270F190A0437,1BD86E26992EFCC1,F7C8003061B69EFD,78873B0F15BAC739,21EDCF664FEBB57C,41B98BBF7B44A842,E011E0E0262BF5DF,F2CC325AB50B33BE,5AAD21D2EA760BDD,000022659C5D5A3C,46274F8F246F7A00,33E627768F36E7D2,308BE70262EEC601,B01FB083CB712DBC,3C80B86485F115D6,D58343B7752E3E8A,42198834284337E3,8287918E99CCE7C1,814CF6EC8FC98648,C33A793ED01CE1F9,479B08B05D0E7365,000010FF5F4BEC92,4C90D9A260C4001E,2FB59DD1DF263CD7,2C8CB14867CCF5E3,D0A95CB573A1B4FC,F78CF01BD7501B3A,109EC3366602C3F8,A1F8419F1F3767DC,BCB4ECB07FD2D040,C9463263017C733E,B19DC26B3B971D09,E522ACF3357FE12F,00000ECD77CC93C7,2D275D5C39B9F898,478EA2ED159610C5,A33E26A704243A7B,8692166F98EC16DD,0D1E7581E07B8AAE,E07646A83143A6BB,F13FF721A5CD756C,3AA9347DEEBA52D9,B3AFD74ED47E4A7D,48917B3DC26B4836,DEBD61E6F2A67001,00004032A23155CC,8AB2F0CCFCAA6451,E0E62ED9C3592EA0,CBBB22FFD341970E,F0DFD2E82067B719,568B4E6592867D91,E6737F02467EA362,FAF60434D05311C0,08A97FF5CC529F1C,8142D15ABE5F8AA2,5D04557C10753D64,FD6E79A94ADDFE51,000005279D57BBCA,EFE378A4C963CAA5,934E4FDBEE79AA77,5C2A578DEE81773D,28FBE4ED7B5455AC,F3CED062D55A843D,12410297C0E38913,1672A6373A0E3FB7,EF1FBA4DDC5187E2,D02A68732CE0EDB9,85DE5895E024448B,D8A1E5706BBEEB1F,00002F82F387DEE7,03B115CE2E01E6B2,0B9823A01C4FAFA9,B33E28A8415F2DD4,78F527AC05A2ACCC,3483E404F1EF6F0C,3CD37286612DD392,DD88D88DC0B328B2,C1EF4637456739BC,2012F42A0C130CC8,ABA05440C6A89B0B,6E156CD171F480D9,000022563F445106,429E7A72D2608E84,C7E4CDD7419FA891,FCD4984D254512A8,2DCB68458E74EA5D,36DE9DA3A9948B2F,E642BD5D60D6730D,E24D622CEF262C7C,6E7A5FC6461AEFFC,C967AA20A7148C97,35FCF23F3B2D574C,5814BF7E4DEBA6F1,000020B72045ECDE,A6B94BBACBC2EAF0,D8AE78122DECEC2D,89FE026555E90622,E1203A9279760BCE,7ECDC36783ED9C54,4A7F6F945DCE8F09,DDA3E66DD116D857,21D2FD3B1AF59C87,0F424E7AE40319BF,1CE8F9C512778A5A,C79F8D7833EDB964,000026B953C63033,5B21EB7C2EEF6D74,2246BE25D6FD8856,E285068FAE0AC45E,1BDC30FD226FEAAB,9B6290C84C9DA86C,C646A7B5574BCC31,E892E677235912FA,6FC4D949346D9F45,E3A2D11E0C923906,F74F28752D58672B,81A397D1347C6E67,0000570C91768D04,D2457D0DB897A526,6D581BACFFDB49C5,8293EAF79EA9A030,CEA1F56753610FFC,CC80B81360BCE690,1FED006BE81D0AF6,51A64879B42E298E,CA2D3DD6145DC165,20C549032C6A9435,D20BE7824017B003,9D457652BBF9EE25,0000542D2A96B782,3731A9F449E78746,FED3E5DE89045E3F,74D2FEDFE75B7497,8DAB8B21A43FF9BA,58C9B5673BADF38F,51CAEFACF6AD6CD7,BFC606806EB32295,2152FAE795877DF6,2D47C5A500F0F840,BA9B6D97569B6BED,9D5265B1D2A7C9EC,0000565E42021FBC,C2775243CA0D9067,8337FC0667C0C2EC,42619F311340BB22,25B14D489710051E,F20734989CBC4B76,432B8358F54481A2,5D863C15356CF354,1362C769E7846334,1EF16E99FFA303B8,28542FB4EB4D913D,1AB4A2B3AF5AFA53,0000151FB5988E9C,6BF3865212896E58,1A36C678E80DC6ED,131B79D2C7C09B5F,58ED8A8A22007B40,5E95D012B9989280,32C8ADB2056C8A94,2D59DAEE8DDD7911,7F699DF88CBAB0B6,97D5B805002DD92D,0B0ACC33072B2A3A,2DB3014507A23325,00001C6CE70810B1,7A902BF7C3E00758,FE8EE762C3A67771,B0721109F76DE393,F77C355BE7B9A31D,3416995B7B3EA060,273D299DF5430FFB,F554B6AA7AAB1E17,9FD2B5AF74854363,D34EA65DA2AC60E5,7FD4667BE6ED6499,C6BBC8777FC7923F,0000112EC6C58F12,7A9C8830B9E8C982,A1B3D72E13488CCD,B5D94D5EBE990DAD,237B5CF3932EB503,B735D34FD3399668,C85106E07B4CE8A7,271C6392F8D27A3F,B7CBC89ECC10924E,DEA62BA382FDEE0E,F1F69A5A33F2D726,7DBCA70570663566,000024B90472918B,609F6C46CD95996F,5A0E38D49FDC0EA4,AE807A2B79F3E15B,3DDB00B2089B39EF,7840BF8601C0FB94,640538988C9D1624,C7E1BDA48A35A37D,4143972798EF99C5,358528F87CCA4714,867C71864B35B88C,3FE9ACFF6B88B433,0000269FC5464A8F,B1B0F56D19505D43,465D96C76194E09A,876231949F06B0E3,0A80FCA448E4FA63,046ADF76127AEFE9,07835A0B535FA128,B31A09841CEA049F,D59D0E44623A057D,A2A0E52FCF64983C,429AE0B6C110B951,49C5FB3313EE08EB,000008F4D0FF9CD1,AEC6FD427451D008,48D6EBF93FFAD1A8,4CF6BA0E9ED45901,1599A73221A30E11,B835F22D46AA15E3,8F2530DF08FBCD5F,11646E17622DFC0F,743FAECFDFFB1BE7,57D82E3E0A38AAF0,E26715B28A0ACEDC,94118399FF80ABC6,000021FF9C50BA05,480CADB867E25CBF,27086D4152130A02,D689095EE9194273,45DF565EB21D6484,8C7E1975C05486C8,E4B9CAF87049126B,E006980EC0D49923,9EF8C2BEFC11248B,F20FAC8F5DC70E54,3EC108B438883A19,2C41525E3E66AF75,00001A1393F1DC92,123626B36A94B558,8EA4249BBD0F0B19,6BA1B93228D40C2F,947D02BB59953CF0,26AC814970E3A65A,7BCF032F0FC95D02,964CC60ADF7AD88D,4923C282A352155F,7BE69C8B5D44787E,467055C959293EB0,CDDE43D2294A5360,00005CEDB029D9E8,0DAD37A20634CC58,C8CEB25313F10398,E38D031BFE8C1903,79B279523527888A,5A087F47B8440C6E,FB607EB318B7CAF3,57021D3AD08CD092,00C36CA93851B85E,FE0EDF6569E70C0A,EE598CBB4E4EAEC7,433BEB4B77206DC2,0000224F10E4D906,2F13BDA8FD2ABC5F,EAAAA9400FDD8EBF,E554D6D92A63CD4D,E4776F93F8C2B22B,078CD31FDA00FC4E,3BABEB7BA2AE91A1,A6B478F53E1CEBD2,5DBD5BFD8117EBEE,5BE77814B262F7DE,47574A5434763045,45D9FCF684033357,00001A6EA19CDA92,F7717ADB21E14EE4,03996A325BD40622,D6403EA7BF233399,E60234C7B1E07522,F6802612476AAEDD,8F1F1E28471AD06D,799308BDA23E0A2D,74A993A094C2281C,5F2AE9DB9E0C60F0,AA80F58E47B2D6C4,C8D7BF5F92973ED4,00005BEBB30BFE2A,492B2384B2191457,A927DC221FAF1B7E,DF321E9CA8E3915B,472E77643AD06F69,216800DE4D2069EC,D7C8AED4A86F14EF,AA11A78EC976640C,E5B81E2606CB5DC4,2DF9C7151E965175,5DF4522C76C04242,2BE219D71B4D035A,00001C96325A26BD,0525CF794C2C9A2B,AE1734C43BE690C7,3C05F7907014C181,F8A07ED562687342,BA6376C60794D0D8,7788E4132A34F8AF,9B04FEFD4133E7A1,B566D1FADB14A593,558BF22774D983AA,56B3FD1F549E501A,BEB49CFFD459CF58,000050848F652062,E57721364D153A16,3397AACD968A45F4,1471C012DFDDA11C,7E6849D25A20C902,F4777A2A5E3C545E,8D41CACF469228DF,F686C3548618F07C,479DBE0E0195783C,0F3AA3E1C29CC5C7,6E80BA2FF6C5D841,4E0F1D18E525632C,000043EAFAE71D65,A6E6B5F9DF18B50D,12661ABF5E9F5E01,CF3DC4F2B76E88A3,93375B5C94BAE9FE,60E750F4BD1FBB97,A44E9147596C1405,C4CC3E0E36F2D90C,AC4BE0A9F147066A,382B2EEED3821A01,4306EC175C6B0FCB,FF548E4C38118200,00000BF7F43FAD65,F8B5B42DC180E13C,A97C52425D0311FD,29A4EED09BE16564,382A64E29E5674C9,2AAF76C2E477374D,33C92703A3F97786,474AA8C19A852E94,9E3EA7E85A347591,AA63EAE41FEB9C0D,CBE46019F5B64143,FAFEE16C203E98DF,0000601F79F61223,11C0C28B6CF462D1,B114DE043C119AE1,19D401CAEC920D07,CCC406D4DF18D85E,29B790D77DBA5B48,870CF5F8F89BA5BF,2A5A1DE33D1C9FC7,021AA298435E40D1,DFE17DEE5F081794,F964EAB48C8D81CC,59F48A44ADC908F2,000050F948425D99,F46C8F98892B6C48,B1F239D4FB6ECC19,DBEE5511467F6846,C64F0C61DB905806,4299C0BA4A06BC9E,83A55A45C838FA0E,1C3D6CD536B03E2D,A38A736A7ADF14BA,50D98234124930E1,DCCD3BEF9A4F505C,7615A5A60C1A5EB9,0000211CD70ECF25,7A557836D03F938D,09C6A42E9FC98352,38ED4DFF7B92C367,01056F7192310346,1A3041A756800DA7,840B39A06B1B80F7,55186BAA3D9BFDCA,27E5EF1625E59B39,B03190CD1272DA86,01BC163350B31415,6CCF72257FD48AD7,0000326564BDEAF4,A963AC9E142DEC4D,268777BB33607526,61C030B5575D9E6F,AA8D4E5955E0291B,72CCB65B7209E2BC,B7FFBB604120DBB4,4B58CEC1362F92DF,2458517A981711B6,B4496A50DCA8D06E,0787F44F9004680B,D52C85EEF6DC7827,00006CA2194CB312,E0ABE5BAA0561AFC,44F1F90BEEDADABA,371B4B75A65A3E3B,C3F4E290D5BF40B9,538218BB05268DCC,FE10E5EE024B3D62,D85C720D9B237948,A9D0AE04CB5AC3EF,FE7A301198D00736,1D164B76E495540D,4151C9D0CDB03F14,00000FA2CC0154BB,CEA5C395C1A2D267,6710EDE79C2F5CA0,2F435EDCBB0DF114,1936EFC74FE6F962,8AAB1E91B11A3D95,FE29D541DC17A11D,624FB5CEC0696F08,B9B8A2F20D71264F,D113BC1AA14BB6F7,B5E7B5E5ECE4EFB1,C778F665DE85DD0E,00005ACD16B0F725,46E59675393220DC,479E21C28ADD26B8,5A6CB51F8F3B980E,B7A5A8D1E80A27C9,A107C652A467DF52,9111938F23A48106,E2AFB47768C0D50C,B56A59674E0577E5,81F262AC5183DAB5,F0406E84BFF9AFD5,D1FBDA04C7A0FCD8,00003174BB26465C,BD38FCE86D89A3B3,C65A6B61F03BEA91,A41E3C1D7837E9B3,34E6CC36AFE9EE71,C81105D640493D59,29583E7CBED120B0,9B2C72DF75EF2B08,EEBB404DD73AD67E,BB1AAC7FA8CFF022,3376298F80EE7DD5,3DFF9E2AB5DA0279,00005D89C7111099,63DAA1C666D21852,62D0BC698D5EB8BC,0A1CBA2ACA5A7D23,3B81AAB7D66A7FC5,479A12EF4E96C893,E5C5C3E95DA1AB91,A04CE0FBCAB2FAF4,8EADD327CB417D77,938E45B72C2172BB,ECA58851D955629A,EA12E2591B7DA398,00004A690F998E26,B32D302B75780863,43407ECDE64B41B5,F05A44FD3A9F5959,A1CD83DF42792E12,7FCCC811E230EAFF,6D9FF0B6D077CBED,243E2CEE4AF15353,CBF44D38C66DE9EF,9F0D884D68D5C218,7C663FB6DD3B0D41,62D09DFDAD825462,0000474FCAEE71FF,3E6CA6953361E959,70C4F4C537DF8E93,2733CFE7A064205F,E6E7F100F622AB90,24FB8549FD59BDCD,C93288C9D7AD005D,387E2A06AD987647,A65EB283AC647E1F,A7938AA6DD0667AA,CE5A6C5547BADB97,BB8F435E42857732,00005C988AFCA852,20EA93DBFBA45A98,3440493357B35DE0,4567016DE02A9B82,5F0CBA8FEBCF3585,7DEF865E47094E12,FBA7066FD3C29235,4DED347898727B6C,58B7BA69A71F407C,3DAACE519C408000,A735C986B7B5E38D,10F758959E8E432A,000057AAA581662B,73456B2C802F6983,A55CA2C3F7207C57,350E7A5D6AF8C4DD,2F694EE648FDDC35,65345AB0B92E32A8,D3935243555BB5E2,A1B863C81A4BCFFB,628BF4D84A779024,601776F9972EBDEF,C7ED5055043030B1,B6A923E62A30E970,00000411E1F28064,F3D2FCE1119E0B23,54E2FF3021A4E5DF,6DAACA5F28549E95,3EB21AC972213F7C,05A8E311836A25E1,57AC788CF4899A80,BFC5DE003D3F6BC8,C909B33FDC0CB69F,C9FBE92FE6EF0DAC,4694FFA3527E3600,B50B37DCFC487068,000030CAB790EDA5,F4DA0E3B8D63C5B6,2FFB57E676D384CF,A5F48C142BBC6AC6,DD1391DA0C0E8E2C,79684E0580E2574D,DE4E8E099C0A72F6,52A306A4C303E55D,BFE73C799F98C763,B91E0E6FD9F9C34C,B72EEC74289DB461,C6AE9A7DE8FF62FA,000000BBE2BF4C93,94978043C8A8F0E3,687B2FE0275AF5FC,D4ED4B5BD084C938,825360BF71C8903E,971ABD08172BB8A3,D41276D17D92F5D7,E9123D9D0BD225DC,38D78E12B21A0A6C,5E0B21C839C2E956,F20A74D58B89250F,F18153096571F82A,00005147DC3654B8,079A4B05700D7FF7,C3B83803CED15108,523A414B99AEE405,65669FE3FC01189A,B356412F31A3CADF,4C2ED223181CA14B,7B97DEA50AFC56EA,D8FC9CA36EB7101A,CA6F1E821E468383,24793775AB12BD6C,0BE036C7E465F95B,00002B3C0E01A9BA,0B88E352BBBB8EDE,3B0A76844DE7E8FB,581435FA7C4F704B,6AD31B19A189B1D5,0D6EFEA9B1E64DEB,E9607A20079A8399,89BF8E1E8B64CBAC,9D0734843E519A37,1B678A6FC6B93CF0,DAD7A0895462C57A,59CAEA9640D11A20,000028764B7A1EAB,49BECDC0E7DA6D2F,4FDEAE506E78FD97,A7F143695A182146,A4E364F238EBA10F,DBB756F61890D3FD,461406EC0127C260,FE03656A8928D870,BE91E292E254A2E3,EB0926E880D9BEF3,742DB2BD9DD592AF,CFD47289CF7C7148,00004CA509C39093,813F278C8708583C,1E7378F70C97913D,246ED4AE016F4EB6,7B74020FB706579C,A8E003940322F72A,D54C33C721B18DAB,414BF01367F4B601,D901FFB406C70D6B,614E4F2C9A317506,231D7CA768F85668,D1B48AFE925A6861,00005A6C50F3A75E,CDF2D6F29D808CC0,2A33C121D4645130,6DBC8DABDDACD6D4,D057E55C936458A7,4A3BCE22DB3495D6,14B5BAB0F22148F6,01C52D71176EE61B,96E713EAABA40C9D,57EB7F83A47F5860,1F884B0A40283271,55B296B21501AE20,00000B33EE19B94B,22B4E360AC593192,A4541E0A25846BFC,96BE05D99C00237E,CC3C763CFE955B37,E14D45A479FF72D3,43FCDE35F68ABA3F,88743DA3388B3DFC,E8A9DEDA52638D22,FF1803426966E9CD,62A7561EFCFB2DF2,6ED94FAA2622D001,000032DAF5D74959,A5A040E490B3D42E,B1D2848616735F56,4958633102CF5F20,05DCDD1E6D375BD1,18F2BE1CE661A380,91697AA70C6334D8,75A6E35CB36E6C48,62AE5559EAC0D92A,425709AA13DFBF4C,60524BAF67B0042D,F645470894994CE0,0000523E3738206A,4966E6BF69AB2962,52CA1ED5D822A9B0,45484828F753B5BB,B25F3E599962BCD1,5986B6D6F65419F2,A78893D4601498E5,3687EE4C99A55725,6E15083DE59B46EB,E87410B5F3CBB496,C1AE1C9428100D14,928CADB8BFCAEC7D,00001C231D13A0C6,FFB83E5510ACC7E2,B23B9F02244C09CE,E8CBC77F65E51BCA,4728B6004F01B1BE,12351A4D6B5B1E47,649D88F3569DE59D,42A432F4E3F101A1,A60EAAE654A72E0F,8FEA521D281F6B12,592F2E4D4E981BAB,E38BB47B610DFD65,000023FF541780A3,0FF821BAA3C1E4A8,ACAB687D6DFB499C,34E0347942693360,070313E030EB9BA6,5312313D735B5A31,1B2F7214D378896D,6575AA14E8302F7F,E34637EC6CD15F2F,5FFFB92BFE29C660,3A0644541557144A,C01C514867062F87,000045FDBFAC2D03,41638D375DF96122,3C220BEC18E7BAB0,33C5CEAB0D7B9F84,D2485C7C90EFE5A7,F3A71AE83F991EFF,48D89628F1892B99,69047BE8E1C4F04A,3D21B304347E454A,4B9FAF03030F5C35,86A5F34A19B1F411,A634A4A5C1132BFE,00000C47DDB24F57,90ABBE7E8FF046BC,C471DE325D6362D1,05228760844B1B8B,485274B876528917,3659EBFA6BD1606F,69BE4C47441668DC,ED1600AE0C6DDEA9,7CA8B3A9084FADDE,828C912FC5E4B149,4E243D70BAD0D958,FCCE60558B3C3229,000030A6211E59D2,3E2858880A5A659B,3DC31406A7D3C33F,108B77FFE723F1C7,EFEEDB596308E0CF,7DCE182913610375,23A529E14A7060D3,928C1EE3C6EA80CB,D2C4902FC998ABB0,E189EC631BBD89F4,F5DD1D7E3A7FEC4E,F7EE6C069A18B017,0000188B465A4DBC,40D25C597FCBFF11,329F7395EFD98279,B9388AC9FBFC9592,C51045D0A608C983,BAB5E40D3EDECCAB,BC61BAAF7693C668,0E21C4670A2E5609,D41FDFC53356F426,10596607BF9768C4,8746FF90C129762C,C084E750D8528A70,00001376BAB69854,A5B44A30219926DD,28BB83078345E5EC,13D039E4091FA43A,FA3A3A2FC8058675,6BAE9E0A27075DB2,6D159234DFF313DC,A5528FF469F348CF,89E85B5762C210C3,2318F0A6F6A23A2A,0F484CE47DFCAE30,F8AA05E47C20FD97,00000BD90BCB9882,C181E29D906A6EFC,A51941EA77816B7F,78E1C78C2935BB2D,79FD494BE443787B,04CD0D333D1A4D8A,0BA9A53924992C71,F30AB8CDE59110FC,DF2C923BFBC42234,EB2285ABAE3AA8AE,B70A00BBCAA8DD04,CDC76018592974D2,00006575A6F01FCF,46863AB2643DCDD6,FFEA34D528BCFFDE,6B3ABA8DC2BAEA57,BC6F774547B330DD,A46C8E6F1D238D06,0612002C0E43670E,1D4202D01BB7BA06,AD2C192BBC8A4E79,7F61A9F03CDC232C,CC2B388AA9A1378F,A78E5CCEB53CA1FD,00006CD1766D3D4E,F54FFCBCF4A977D2,9D236BE16AEF6A6D,D2E938F634044F8C,C55641928EC5FC3A,C2FB73B4B1828122,709C651B1DD674EB,77AB48794A20AB48,A5DEEE2B3C924BB5,9097310E081375F9,CB5D0428CD49A78E,9602C808E954CD95,00004F9297BC8372,DDF21D90E060CBBB,0F1BF050AF78ED21,A3306EFE692317B3,1C3D1ED510D75738,9065125FA7EC2459,1A4E80A03A7AFAE8,5AE32BE99A5875C8,6DFEB25BBA9DEF6E,6037B5FECAB958C0,4C83841E7E2D1937,3686DD7FF65C72FE,0000196598F13D55,EC6A24C9D60EF349,113F248C20238449,80FD8D300A669756,439D7812DDF7BDAC,AFAA420AEF7B001F,5EBB1FFC29FA2232,6A9686A2DB9C4C13,FF079C9DD3077E3D,07E801F65443B426,8A03E9B7E904E345,601A07C49032D5DB,00001A4CD50A3C1E,F9C6CC92FB1005A4,72C885D440179496,5F628ABE98F6C8F8,4F1CD50B88275009,AB8BE827AEE341E4,E2FC0FC0FB6752E9,7F9DAC496B44AD7A,9D22C27D5D4CB16D,FCD720D553F30AD5,91F3653BD80EA2A7,CDCF800EBDDDA6F7,00006490415900A0,3510762B9480017B,C168792060FE2669,700BF8B63093E73F,B5E7642ED7E84AAA,E5033A9D02859C21,35F49BD9FAF431E6,1504065F24E67B1E,86367EAB37A544E3,CCCD16EB4A547DAA,46663DBFD9956377,3B3A9724D0379722,0000260F5956D074,2B7B28075749DFAC,40D25557F0BFA586,A128FA7492973DA8,5BF19FAF68F0A5C5,949647613C04ED74,B15130DABDA04334,65550A91A394F940,68023038147236EE,8BF7AAD3EDF2C3DA,195BB9B7541BE682,0D07F5F4DD342C1B,000039BF32403AB6,8D9B68F4455BFDB0,FD1A732A48404D4F,560B8517A1434893,0364741C4F493627,EF1A9832C43FDBE5,86A05973F0B3F4F2,C6EB972BCA06C8A1,2216FE09EEB24F8F,077B59D9E8676EA4,ABAF773FF9DD4BFE,912F3C5A3A5B260F,0000622379376769,E9348B67018FA52B,430A3FD58CC50321,BB63F92277650BCE,1D522EF1504A1E69,8C64B103D0530942,710BFFE5F995A413,212582B415BFE84E,1ADB758471FD8F44,6FB08C58D41B0959,270F8F164A5B4E55,4B7A1D4DCF940E38,00001F23A0A87687,8245E4FEEFBB805F,C9A35F1CA45760BC,AAD22BD1AB1106B0,C04465A13F2D002E,FD25603A66873E71,C3ACE59B54034CE2,CB0DADD993BC01FF,E69FA537D9190657,AEF851C823495729,CC4FEB891145FD24,31211FB6627F8271,00006078F269A7EC,6A52D47DD00FDB40,F570E4C7004F11C1,075B7E89340B14AE,623D8738B4E856FC,238D2589F729EBD8,254C9D52C6FB50A4,18F9DD70D61A1F70,026279FF30A3CFCB,53D417FA2BCDFAA2,84B72F27E1B81C39,A99FA089C77F106B,0000109537B3337E,B7EB563C76F44295,EF9738942B38EB2E,C4A04841B8DE0071,FAC89619ADA2A5B3,B981367CDDD543E7,B73F43B1D9887EA1,CF17984F41EBB48F,47175AF7668E2A4C,25139C6E971BCF2C,6B86F870D81E8B7B,85ABCA104736546C,00006DB0232D3372,A2D85BFED7549BD7,677DD2B6C9DB55D5,DF27DC50F0A15040,0167EC386BA82B30,42C637028FFCB4FF,94766C4B53FE77E2,39F47785D8EC9D87,7CB2359EBEB818DB,75E76ACE988B3679,0B93C5BBE4FB18E7,152962C0071A4425,000027BB180C78E4,2A38B77B28A1AB66,3451D85F401ACB28,FBC8E843D0EF45BE,6747FE0D28F7F0C7,70E16CEF4BAFB119,471367CFF8F68A4E,314C3E1960041531,F376222274E3DACC,FD7EA5374FBACF27,C9F45FC3BAB45BEB,94BC37923606F234,00005E73DC7605ED,6D088963D6E5BEC5,D7D04F27103B542A,18AEAE34E0E06B2B,0466D8B0083AEA80,6C6BCA1A79AD3FFC,F642875296205003,65C6237DE57BA45A,981277C7215F9219,FCF83D57D67DF145,00062970DD052E5C,CB479AA2A886C34D,000028000C1E72F0,317FF8834C162F0B,38BFBFF6911BC7A8,0D2032940255D6EE,D924DAEC98624B48,AA17502B4C9E053A,A9AAD4121A36AB5E,CB610F838AD6FA44,3F0FFEBF41915698,84E16B923059CA42,E928B83EF8421421,0989051DF32A6FD5,00006C2F4AEF0F4E,F5F6EFC236A60549,3AFDF9576CE451FA,48EF9C673BF7AE8A,B9D039A3728CDA1F,90BFC1B60D951037,BF3D6DF7D5D9F99F,96A523514E6F6334,DEE0D0098AAB1144,011C056D2DE74320,A453AF18A5896511,157B7EA29BCB0CF7,00001BF3032F4019,337F53EA88909433,66050D72F91DE88B,360526E413B1F305,D7AB9215D03B5C4E,103BC413B1D5D15F,21B8E5ADE67511E2,BF662403070908CD,11C41F1290CA846D,D8B4CE5202B80F42,A49AAF53BB2ECB53,AFFF76A01F5EFB8D,00003B73555DFD79,9A42883FF6EE0D15,0A6604B4D679D6ED,DC4768AD273A2369,880883063F60433E,A741C405F548863C,0DCBCCF376E66055,E74B3D178EEB195B,779DC48F10E1237F,2C362DDBC37A6FB4,D94380EB44E13BE9,C0EAE040A7F3CBAB,000004A3C8951F79,590C85C81AD8B213,E225DB70A4531C22,98464CDF1401F8DD,40357038BB23228B,E8A99B1DD313EC0A,AB095A4D477AFF44,16A6CB5AEFE4F7AF,18789CBEBB864846,BCDF2B28F5EC7B6A,17DBE271E06433A3,7CC2240E7C8CE810,000013228F88CA65,4E968654623B4109,4C7F0E4BEBA4539F,B6616E691D11FD26,0814583036D60702,E58B61D5BFD1CE27,9928341DD46B2941,C03C9C1B8AD83FE0,227322CDE782DE87,80D7B60CE7792A02,69F55A49096D5C3F,4D3C6C1989A701D3,0000397309995FAD,E74F2BFA4E785A17,818AFC7F2850724E,33752C3D42BC253B,27F72F7187DD76B2,8E3A2F3B0B163A6B,447EB03938CB7DF4,E947AEB46468AD4E,9BF170E01457DBE2,42987D7F3F38F7C4,DA52E8AA0A19FB24,9A4AD05E185DF397,000006AF43368BE1,61EADFEA4AD02300,4C83269F65DA23BF,6F67677D2224C338,5EFD2E8117F472F4,4F12F4ACC1E6C18F,410EB1F008792620,210D18CE6D91A83F,488F1D3B93D4CF73,2E0295A614D41422,7AA0A6357D3DF42D,BD0642E1D650277E,000000073D3F2B9A,3841892EAF391D22,E1CECEE31E7EEC6B,0200753E8EF12E51,154561ADD92CEE77,9F1E2BB23294ED0C,6EB1D8179F43FE23,375F4EFFB51DA098,AD8345D7E92987FD,676BE87615DD4758,39A94F3D2A9792E3,D0CDD2CA7A669901,000058C6C90E2AD8,7DD6C6FD00D0AAD9,2D3CB2756A2483AF,B0FB5F7305CB71D2,CFA7B54D49D728D1,BFE454A4148C0196,CA44B23C993DBE93,2B724BAE046FFA34,2EBA60521F114DF0,D91A86EC1CFC2DBE,8C5BC204124816A5,F9E87B8BA7E31FF8,00006AF466E5B168,ACE9E919D12521A1,660923F926B6C27D,E5CAFF3472534F11,D977950799A7349A,CD4695AD65CD0416,9AF8D30B92369057,972D52857F80445A,7539106BC0A83068,C503F7A30EFE4AFB,9584A6E6BB1FA58F,4431F38393129A99,00001FCE38A9B62C,0F89B226DFFEDB3E,81B4BA71994AD517,C3101CBE2BABC938,D38F9DE1E18C02F3,E85D5F6BC785C906,DB58288608EBE6A1,E00FF507BC08C959,4B9F8DA8289BCE68,74F40B15BF3F0B4B,6785575B1C3835A1,A745E72247C19F6F,00003BBA3C4BBAA7,6E82B4D21B6953A1,89D46B0E442242D1,C08680B9697E17F5,A12996B48BC0F416,E326C93B78C70E72,478F057D4707886E,6275C012F557AD33,317211F0F458E08C,A9AE5AEEC1014EAF,0C2A615D524B67C7,7B3B2EF6B859B66D,00003754A638A40D,C1D379CD8B8FEF87,E262B93D90A9B0A6,6E40FBF2C95A95FB,E323569186A7406D,9E58D1770EA2112C,185D49FE500C8EE9,969C221230971067,300044E98B9B3271,181145434EC8FEF5,38780BB7198CFAB5,9B4F3C397C58F319,00002CCA15C3E4BA,9CE1805D751B6400,A2D5FB91B6D48DAF,F57844CC948E107F,EE79A41FD64AEEAE,8FA873D2AE903B59,A58DCFC4F9A78181,8574572A22B1FB7E,8E420238E506A57C,1E82A321F43695B0,55C076AC5077CC68,6F643EEE9EC4067B,000056342C1242FF,446C7C8D355BE08E,BE47C061A0602568,FB8EF09469F54D6F,56AD28E43857177A,123B171480405BCF,6E12987DACB32B22,24EF25C08D41D609,39C774981993BEEF,6029D443F888CAE6,B5B145CEF9B89C65,965A183CFDFD7E48,00002BB037723B79,69C97B62665E8818,B5D8CF44BD30F912,1A9492675646500A,D9009D0C00027A09,6D9C5A2FA348F323,5CB8549A8B9693C3,C68EBF57988A325D,EA37959C2DA01EAB,F8A3201B09895A2D,B1A7113482A2B1FC,80748E6A1C326DF6,0000440AA11E2B61,5FA241698665510F,51151C3ADA506BFF,24C8977BD60E1844,86E9EDAF42776DDF,2EBCAFC80A90DD84,BEBD6C6C355DC42E,8DA61A66B03FEA29,23D835C5E69297E9,0BF15E638AB4F35B,7A6C7F3FFDE633F2,1AFB625E94FB785C,00003AF28B32E4C1,CB5DD8103BE714CC,9D6D105394C38745,25EFFC6A54F68621,8897CFE8735DE8B9,9B3D5846AC048A7C,E9832BD990C44C34,2D8D05000C411882,37ED4F922EC3EF38,25B2A744CFDAA28E,2829A0A208823E87,E4B3F20A6DE00E56,000004B549CD647D,FEEEDAAD5B27C97C,BE7EDC157F2E2D8E,1B56E0EF255E4474,D446A24D99870BC8,CB8826FDF698862E,CC2DFA1EBDD2600F,0A389FC3E3F3D215,36A6DAF79C37322E,92958ED677766CDD,933601AB8AAE9526,00F58D7B0377F979,000059D330D6D156,C84DAABD089DA703,F8603918CE8998F9,7C8349FF2D120F54,84C0158CE4E0A96B,A0ADC5BB3C9E0593,7B538B772A793687,86D0C80747881245,A7B6EFC045586A5D,608ED89E1C0E6CE0,651B350665F2FE1C,52D1E9DFE437D5CA,000048C70604B85E,E1F2EDE03B01A2E4,4AF964F55560B0DD,CE3E3604668C1E7E,BF07E40E7975F73E,0D1A5DDDF7362735,4EC4A6576CF182BA,3D47550F0864A0AE,4257919A63444502,199459FDF383BB83,31771DB4B807A5A7,DE0B185F56F4DC53,00000822B370C40D,A3D3997B020A0CC9,A440B8DA50B88957,02C2ECA3CD4CFE6D,2304DD7DEC16E1A8,EFB2D2AA31FE86E7,84086979EDA5C174,3F7320DC4E80B3EC,EC76D24F5D30173D,4E9717D93F643B3A,0E784BDEB42F99B5,252C63DB7A3703A4,0000341860C6EC8B,1C29CD49778E783D,5AE5202367D067CE,8D0F9B7A6DD7126A,89B7F9C84F43861A,218B192B0A0F6D08,C59C7165838C73E2,124DD83044515993,E3BB41AC8C121DE9,490E029B6ADB47F8,02BA5B07EF477978,CDBA39D84091C59A,000029DE404B2A12,A7496AC884C5C805,2EC35650E8C871C7,DE36F52D1770EA2D,5B8AFBFCDBDEDA4E,2FC78D3EDC0C55C7,378835C7F22709F7,FE7EB807D3E50E71,397380D0686F301A,CB7B0E2C08679723,884FEC1B315EFBA2,FF60F1B5DDD5B035,0000511796B5DC96,93E4E3A362DDE71D,2E6BEDE938672FB3,1C209C63413871D5,01A1535EA288A4E1,BE25B9F5F4872ED7,F8E4BC1EFA77C4DB,21D4C44E77CC3C38,44929B7868E351ED,C2DB927CF0E5EA77,74F25F24C30D2823,71B228FB6732EA5D,00006207DA8F5168,08A7786E847E3136,256664FE6DF9C9C3,2993F0B350A129C9,2D40A39B7B83F477,F5AA6F58F27668B0,D7137B6031E27C3A,11C562FA52D26290,E69D5EE6AD86339E,8867264CC8F041D1,B9BD12128DB37A81,F9C4FE8400345110,00005D6E31C670E8,371261A909EA76F6,610371D003E3B54C,CA9944F7F3E3924B,E66677D40FA9CED5,1F3C6859244A126F,89DC4F585FC215A7,036379CFAE63C7AD,290BA00AFFDD9172,CE342525E2E105E1,0A1C039EDD4B43C5,FBE87859ED6A3F90,00002114DDE29F13,15DE9741651934A2,8739306D97CFE40A,C37C270B360A42D6,6EB8D1B525EF9191,B7DF04C72619C743,72E92270C5CECCCB,4CF889FF3D803415,2C15342C1DD0E406,E4D608EB34889DDD,AEEF4F4F422FE14C,FA295F47633DEF13,00001C3182843B24,307C750805AA0CEA,FAE39A5CAEB7C0AC,DAA362D07C137821,C63410B141871139,4F8E459A856B111C,4B60FE6679B4D60E,2A36F59209B5D3D7,7911BA420A3F2A64,047356284E22F226,3A3E104EF2DCD4BF,24B237CFBE6A18F4,00003E0585D74B13,FC7A5AF45C593BC7,DCE86072E6F2CAEA,BEB22BB03DD8B683,604646F9292A23AB,94704784CA4B1996,D77B54562059BCB3,1A06E4B21D7DBEC7,95D29C2F91251D3F,5CB0D0FF00BFE330,79763C2EB20CB43F,4A3B32A74C8D9EF4,000003A0D535D966,5C72CC74E57AFDB5,825EC91342F70C30,6AA8A7FB805E21EF,DE701ABECD0F7110,DD43C0BBAE8F0C45,41D62B0D2FF083E6,24E8A9B62963BBB0,872786FA77895B42,625D9C3C73E7742D,BEF3AF82DB3AB056,54AAD70D87A53B69,0000034313E66152,8D0FD05F2B65CDB2,57816220B26D3002,B81144425EFD9161,B2BA248259A70CE2,0064FBAA61CFB8F7,52F8DB630D09E1DE,6446D325F9518AE3,86B86BC722047523,22FC3E12FE3C1805,3B7E2EEBC54256CD,51B284434EF34A71,000015B887E936B4,3EE32945BDE5E406,F7B465F3E60E4D68,4848F3FFB1D91A2E,2BE3216EFA5471E8,7830A8D37DF5A26B,CCC67C134EC3569D,57846F8724AF19A1,18CCA83FC41D6561,0F98A353495A269F,50BEC2309F86029B,3780FF7A5BF96942,00004D17650CCEDF,9D72B79F6E642744,0D45250FEE94AF6B,BE5D0C6853662823,A4EB9D864AD5BBFD,C96D7E91E2562A5A,8A6F1D0EF641CC62,8D881B6EF0969D58,9C0B572594255449,637C3DFA0A20AC1F,F03EC8B9F55AD91B,513D6E7F5F5331A8,000025DB79973097,61ABB4C7DB2F56F7,344ACC4A711DD216,4542FEEFBE8E98DC,5820F0BA5EB40BF9,395F64DDA6DBC96C,D226F21D4FC9724D,2CFA2CDAA9A2E42E,944610410F53D71C,0E07E5E8EE75FB54,39928082B31D4CC9,524EF5C254A96836,00006CA50F6EB50A,74A8063206757D21,8521A18DD7E8DBB3,1983EB90B7C12F10,991B0C0F9A100471,35173B5E214AB62D,6977D8C699BB5B52,157CE9C88F8FB6F6,9ACBD055F9CD7647,EBD2254E4FE6B87B,5145425E61608D5D,FCB0851626FED217,000042171535D336,CD3D8272736D7E57,06888CB834EE65F4,489B90BDDD103910,DC50F1F82540F46E,9C6B838A0637EFA7,A7544AE0CD1E811C,4886F17747C64623,49681B6A5DD99BD5,B51F8470A34A2069,0B9D5183F1982EFD,DDAC6FA199167B58,00005AC04FF6557D,BC71B962FD8E1786,F29E38E53B2BE371,47C21B0C94D9F4ED,334E830421FED989,52FAEFBB81BC8FD5,0B8E8033D49A0C89,B491EFC55E9E70B4,519297EDDBE0449D,C8E9F85B71490C33,BF221DF714562474,94328946A5A37504,00000FCC0C98BE22,E6985C648E294E58,EFCBB8AB13FE0DCB,71EA49169567AF5E,AB1F3A16C70F3C70,C672C668477061A2,BF9F947B7C9DEAFE,E73250F46B218700,887CD2530E65DFF7,593F92716ECF2F42,8E71C60A321B4477,1FF640650287FC0B,00004F2612BDB7AA,B29819747862C994,426E3D70273EB848,A7CC93C192F1AC95,F7E9BAB5C17F2B8B,58D0E7575729F6C5,95817731F900EE98,07D97ABB77A19ADF,9DE4BC3A93A0173E,8E2D394F51F53236,BB2F4E85BF10A71D,DDEF6822CC125570,00004B9D8B7782F1,5D080E80247BB14E,B0A7EDD0E213360A,30614D2F32DFAA97,F015C3FDE2ED8A53,54DAC72362005DE9,0080DEBF3258F26D,482DE95D919DF1A7,6723F8CBDC102570,A98E181BC3C902C5,18E35D6BF5B2F478,2173538E6BDE431F,00001345D3290B8B,2CA1746105C8342F,ECEA31988886DA8A,313FBACE379BDCF1,ADBCEF15FD5660BA,D371C10A17832BEC,DA07DF207C5E4596,AD9ADCED9E796EA6,94837080CBC27515,01C115B702F129C8,0F07CEC3EB5252EE,CD9A7884BCFEBEAA,00001FBF9B8891E9,F72C2738B36E5D78,5DEAAA31572867A9,82AC2BB607427B2B,307965E5E3C63E97,600EF8A60DE0AFCC,6797363F1A1D752E,BA56B7D35AFCB16D,EB51A6A3BD5CE6D5,5A98050127100441,CB6EB82349B12AC0,0523D38F4D9E7C5C,0000363CBAC3E3D6,68B4EA853D00E09A,150EFEC202F65942,81F3A7740B3C2C5E,750BE17B05448B7B,61ACCD6D7CAB77DD,6DB4FDF5928710D3,51D8D59CCA87EE1F,AB12D174EF4AE7CD,61DB374CE3498066,1D8B31E91383DC6A,596BE20C1F9BF04B,0000442A397BFBC3,CBF756BC67F567A2,EF629F04390A9DFB,7871791D7DDFB182,CCA0A17E697D402E,FC933424300DBA14,07E12FAB22C0389C,515376531D0EFEA8,8E6F9FEA7CA8BE65,7C62D601D7E4470E,56A9150CBFBC8D2E,3B91049F6CBE880F,00000B630919CB83,6D5C4F4A27499870,A6D26215CB65312E,312D0025380A3218,4883C90AE31D8856,D0D7FA59D997F433,9BEBDEC6A94D2C3F,8A9F4C962C2FD7FF,33104E12DBE79D90,D0C8F6E4A811940F,ECCACF01C9781ECD,BD03D07177EAAADC,00005824A0099439,D75CA4501D0863CC,CC2D3A9428631699,9F8BB8D1BCD2F444,12C6F15CE596F3B9,34B459DF5E1A38B5,EC7D0E22D30CD587,FC3460A444090012,C18EE3BB95C5CB2B,26CFEC842EB77DA7,5CC97B03FF753D65,9CFA56345E606150,00005B6EE100FDEC,CD512BDD816CB3EE,D42ADBBC41782A61,0DBA42B5947F61A0,9D1AC7B4D961EA3D,B1022308E2C36A5F,D2C7DA0D366789B8,850FF5DA0ACDB490,02B6659960CD0BC7,55433BCD87ED6D06,7DA533BD3A39194D,304A916D06B39D9E,00002B3AECE5514B,93DDD04717BD0ABD,8F53CD165DC56396,AB0BA009F16B1AE8,6DD327C33635B9FA,4E0518A645A1D9B3,9F8128E206E27C23,EB7B0451405F0D87,4925A41BF13B829A,467397B3FF3B490F,4C116B250E44A8A3,FE7BDD9924CF046D,000059BBB2C85982,F1686A78E55A6A62,39D96CEE732FA27C,888DDE85FB8091A4,BD68E937AD674D71,40B7807B1411FF35,68450DEAC491EF68,4CF5FD5A4B7CCB8E,E8ED3D9B56CD1D29,C7A551DF4CBE2BC1,7DC4B0CAD6D3909C,B82C8675F3CB461C,00006EC2E5493B79,950ECED89DC6D9C3,A9725F06C03F0F14,C86BBB896D94EA51,22273C3F4797ADEF,8CE85BA1A2110F70,A760A67BDC481AA4,67DEBD1B5133F818,84E809BCD2468E9B,08C23150124F5F29,272249187E2759FB,914BAC1F4ABFFB8B,000054B4FF2898FD,BD9223693CC537FB,AE7544643D6CE486,50E6A577C12EC4DC,EC5DD1CCF2F4FA85,FAD52F69D9E25F61,41CADB16CF2E10BD,3DB4EF589623B177,063375998C421513,2E589890DB910F0D,0250F08475C5D979,D858EC4E8CD2FF16,0000236B6A9D9669,7973A28724ECD104,6C5D1891D9D9E044,02338B137A3CF725,2CA6F1752330C0D4,2E3863183BE628B6,4EDBB9E1DDDE6D39,0F2D457731BC8340,C9280E76629AAB01,08BAFB5867A887D2,36F81B218796D2F6,4487F420806AA758,000016096AC161CA,19DDB4EB8B6D8F1F,57C227B09BB49F4E,81326A7531D85BF4,77BD92A735206BD8,8FAB71065AE7D699,30BACBFD67871962,31C1C06AAD89C627,37E8BACE79294459,7D69A4875CCF919C,9B80B3967BA69880,09C25A433997972C,00002B9241819066,8A307718035FCDAB,6A93BB2CF3C8190B,3A9D4B24C5AD4F10,FD7B2D128E38FEDE,904821FC224EFB07,90E749E766037915,35700E7753A11DC8,8D353C4DC4E39F73,3F874D11FF534E94,7C336C3164875ACD,35D1373521944C16,000026A6B7DF91B3,D599262E38DF3217,496A3E88B61C17FB,C415690331E5501B,E4A7EC5B005DACC1,44B34F6AD04FCB67,46234585869A8437,D58B080FBF1B22DB,3024627E7C759333,018D2B80018A2968,0AD7FDA50233A39B,2E97E199DF981F2D,0000177CC374CC55,03D5F8ACC1A5148D,1859D880F16575DA,3FD1D9B3164859CA,76CE2F8B435C8896,0917066D1AB25BEE,099713CA680BFC4E,DB967B3025C3CD8A,C2D2DED9FDEFC667,8AE4D1D78C83CEDC,1E4A82DB3528FCCB,9706DE56CA19D014,00000D45307ACAD6,FB894F6969F11ECD,003407F5423CEB01,4AFE7B47BC4EBE7F,A5C97B810EAB1237,6EED06828940C7FC,85C1D27494D3DC0C,8DFC47090DD5F364,434C6F4569E1FCDB,6D259607C69680DA,3AAAC639D205D714,6530B39318F78547,000045E1CF20EBDE,158B0E079C1A2907,D1B7CA3B1A5E0A2B,53AC2A16E89FE719,0A7E341E1D69F4FB,624D9D0197425DA6,28EEE3766E54B2F8,1773E7B6D8084DA5,B2DE2A702B04E37D,9BFA3472BFBC8C24,4642599FD327336D,1902CDD81B709AB1,00002903EF23C190,40B448C06472AB52,E8F7AF6E1479607D,E6823B7F55B7EE19,A7E51295222F106F,B28C4E58C626301D,D6590724A26AFF52,9B28D0BA21A6D9BA,603442AA3B681FAB,D3ECB1715D732C87,77FC26EBE7540998,899A3E7AC71E1987,000001645C5E2137,6C7A32C6A4D9C49E,1776F0717CD40346,B9EDE5F6A399238C,1612FB8073234A79,751AB394B13332EA,5773E0B6FC8AF885,5961393F264A79B0,BF80E5680138E97D,27C92EFBE041FC8F,66094B7CAFDBB14A,0D778D45A43C6CBA,00006E504A69F06C,3E27419B8974E987,D7BA25D23B7620FE,2E0BB9F72009E8FF,CC3AE2417F829999,47ED6BD5CA4ECB37,A062850E14F7E8AE,E2B357D07BA99BBF,F6DA0C892A99887D,13DE7CB8E1C8D0FB,3DD2C7482B1F1E8D,B5667721F98AAF0B,0000187B4382B2FA,04C32EA0B3586671,9B41D6E65DE654B6,B9D35E219CBFEEFE,FB36C00BCDDD327D,72AD569F58AA39C8,5F07D2F525D12053,BB38CB579F9E61D8,DDE80820371F17DD,D4401BE261E17638,C864E90F96402712,986C8D5F12AB1ACA,00000D0E5D6FCF9C,2559D63A3E7A5EF6,FC4FC7525E4709F4,9C32133E2F36687C,8A162B5AB567D11D,552198AABACF8D0E,C21E33F6E9E6A5C9,09863FD8C221D165,FD157CB6398ED68D,908A5C74BB669D3C,4ED45DD8BE1933DB,0D972F6A0810003B,0000059D5E1DB117,9B83EAD31BE7EBC7,61BA02A252C68084,100C425093B51B4D,31715434763A7BAD,AC2B2DEF50669393,D0C0CF229B6C2D38,38F74981E43E29C9,F4278B3AFC1B3EF4,C0C22FD77B4EAE14,A82E0E551EBDEA37,0A021B3A42507D8E,00006679AE88A726,15369052629FC638,1D1293181EFF49D6,8342F41E323F8054,842246F53B86A099,AA619D2C646D09CC,1C3A6ED439EF6F0F,A978F7B1FDCCB2D0,C17C0B450214C336,364E7C62D5F236C4,638D4CB1F314CC4B,84DD5C39DC9120AC,00005E12AA44096D,440919F4E1369BD9,4BAADB7BBF88CD58,75FE3253BB5790DA,4176E1A5114484D7,3293AFE6D02D39B3,621F7EC7889A4135,4253C26BB4E41916,6A0D4BF08F5FA56C,2FB098C0D02AE616,CD04648BB9BCFAA9,6EC4986545D8A291,0000247489690A20,C813B79150FB7DA6,4435E667D8D7FCBE,D080079867F78FD4,CBAB776A59798375,503F59186AE260B9,CA8340095B1A8EA6,47AEC70307ACF055,5EC9D4BD6169F81C,B98805E467175346,87540F57B3D8F958,132BA3DC9153893D,000037FA7BA0E6F3,EBE14618A297A30E,F911C28687852EF8,9D1F6705ED7A7BB3,2D9753D8432133D4,BD4028E600742C62,2520C32A2716A4F2,E421276FF84A941A,970D26BE6B2A5E14,4AF775949EE9B893,72698D1C0C74D538,B5FC12F6A780F9B2,00002D1195685872,6DB610FD1B82124A,E5645CE7166881FE,30A3C511738AE5B3,F1B700EA2A782C82,174C88A71970E658,0DE9FC71B8DF94A8,ADE1203201878221,079CBE4DB08E557D,6B4CB132E4405E72,AF7524BF10DD0CB3,66920163CF247B98,00001D5AFE1845D9,F9F0C9B1FBBABCDA,B784553DD4FA85CE,50D58C7C8C59A14A,BCD8181B7A7C3240,161515DA689801BC,DA7176F980A47BB0,93063A9DACC0F026,35809ED90D376408,6A2BDE10219F390E,FCBEBCF81871E7F9,3C5F79DF1A174586,000055621328946E,3F8A21FAA6EC83D9,1A1B714BD28034FF,2A9DF3955E60A7C3,6CB5AE637E5A3732,7DB4EF4101646A6B,CFBD73FE1347287D,B83F86DE8BA3F9FA,38A992434880225A,5F48FC022BD454B0,57A9498B9A42309C,8F57B339DEE87A23,000027AF38DF0D67,E5C997F225FDA891,95F6BDDE8FE7ECD9,00915419D50D699C,0C8BF5906481FDED,36A18769109F9A22,986C651A50FC63F9,58E5ACFE8707C426,BCF689F03FA59668,58C8F7C90F85E627,0CCF39587ECA7CF4,7560302279F328D3,000013EDD4865CB8,C4C4245589BC469B,A8BB87FBF57E69C3,86C86FC991D58EF6,355C023459A9EE86,FEA3CCA0652B5901,833A2F769FE61013,B09B6B9884DA57CB,EAEFF6C1102596CC,E7D43D3323BDCC68,3289797CE15B90E8,11DAF8D7988E77A9,000024BF07F4FC02,E069BA309888F00A,2D55D773B0466752,74D0BF684EBEA125,F5D7971FA3B76555,5D235395816DA91B,28BAF5492EBCF4D0,52DDF549E843262B,BEA02AD262B0D4F9,E0A227E7CBF5A042,5EA6D31A25023203,B484527A93FD1BEF,00002D13968A5255,8A793D24FFEC05CC,18EFFDB15D39C6B8,1C284EA68D139437,DE06672872348479,6B11C914AFB20610,ADA0CBFBDAD907A7,31E349CB073C16F4,F6887E503438D6F4,3C2854AC8ECB0451,AAAE834A52771F48,B351395F7045604E,00003FFC096EC86E,905D29426EADF2BA,E079BF547F49583A,59C11C27BCF2801F,E8DECF42271B28FF,B13FD1EB2FCC7222,92A13CCF78B54FFD,18F56AB8F74437A2,163968D7E8B7705F,F4FF5BEDAD39D56E,2DD27D1F3228F209,36D3E67965814108,00006CBA6F2E7B3A,832F35350611A8FC,53BDF4587EF38842,51AEB9F9AB0C44B5,7352021D114FEF27,11A0A0A2700C9A50,18CAE29F49326144,A18ACAE0CB9A534F,3DD23D90D4DA3795,7759CE579406E343,C6ECB5BEC844EF24,639E6A7BD5119159,000054D9BF39344C,ECCDFF0682230A49,E2F5C13975C23EF4,9ADA86AE1E7086F3,E09E4B0157AA8548,DF3ADC815EC51C3B,60CCAEF10C93BF2A,C9D0A1D6DD28808A,05F62459DD3E731B,3FBB111D5CB59B7A,DB449094C231053A,CEE0ADE45FE25C1D,00004FD0D2FED185,06363641596EB02C,0746147E0FA45DE7,59837039D6B8B035,711B9B84BCCF375B,085092D422EC29B7,346C01476F58D1D1,ACF1B2D1DC99B8EB,E78AE18F589841A1,33D70396A73A3C4E,A95BD07263585293,657B82F6DE381B53,0000007A6601C561,354A4F0DCD186533,3A07C5A12DF80A84,A55252F328A3D4EB,4EF0C1C1D056584E,A57EC5B08B29F600,B532F2D99F131C9A,187F56CD856D1DA9,B6F1C84F874FF9B7,649EBE94E355CC2A,ECFD3758C2786B13,3062A98EF6AD76A9,00001D93901A980C,835F0E9D26CE37F7,B249C65D176C0BBE,855C28FAFD72A54F,E0436D23DDA70AE4,CF07C5F3308221B0,5C325A8EF5766145,16EAEAC8D33871D0,E5293610AD596F28,CAFA95E1E381C66A,71A63BD8A6C1C79C,54D91692FD61F765,00004279F2749217,B8260FAA8207A178,7B8266D146241402,85C72A44C2151BCA,320D32BFF0546AED,3BCFE3B0A77CB8E5,22DAA56D35318F71,769905F11C4D00DB,8E3AF40831FFD56B,3C4E0141B95CA540,C5B5F5C6BD216464,813547930BF1E154,000015B8AB4F0C79,52E7BDFD00E8F568,6FCC4795E20DC841,5B04B78F7EFE0810,FA35DA74C614F97F,A3EF2AC51BE3C74C,93055E69354CEB93,24553D667D429E29,06FE9EDAC6B2B876,0DD66CEAA8444CCC,0B14B4B3D9C0DD10,EEC4A3DCE98D5ED0,0000016ABA1107A9,57573E1F5BB84405,6D8F65584A1BF18C,9B492783D43C7BB2,F30FDDD13E9B2E18,BE8646E79503326B,A957A9DBF4AA4494,C6975D09D6101707,47C25DAE417A628B,A24CB45CB903DC17,67ADFAF4960C5D75,FFE309668C509557,0000294C22CDFA63,AB673DB81F057720,3C0FF1D90A27D520,B3858B7A9B230223,54CC9066FF090334,4E1B4ECD29E6E12D,8BFAFC8A0133883D,004F4C9E53D36FC0,669C3F23D6D944B2,F18834F1C06CE505,57C4454D1A0E4A65,987390562130D879,000021887C4F74AC,987D3956B573E052,43217EC065F5211B,5207E26E4CD8653C,47614D18C223133C,20CEFBE3DC1740DD,87CFF67850BEA8A8,245D2A6802887100,CFC5D8894666D439,3EAADFC1F2367FDC,FEE67BF7DFA2BB51,615A782543022A35,000003CFE0B21FF4,66F01902D94D350D,7B90293E06C56687,252D3B92996664A0,EE2FC32ACCE4B23F,43A3D54AC2EB6D29,70092A2D07528ED0,25D18B1607319790,FFD8B7BF7700CFE3,4DA59526725D5B68,D207AC14A3F1E2D0,4587B83C6613E6F5,00000769681CE215,75242036A163A962,0A43BEEDBC6A1641,57411478665D4FD9,6654AB9EADD506C3,6885C82D0D6369FE,ECA4B20D2F243555,0515F4B0E71FEF10,FA68AEE234B48AEB,79EB82BF6B376D77,1900C5D8F5F0B29C,C8D9C746EDED30E2,0000411987527E2B,F47332A47D7ECA94,97E7DF58935E0220,9835281F7897D4FD,1DB0558565541B74,895690A51F9B98DC,66E22221CF50ED20,6F2D5B2F85D3B35B,E9DD75DB5866E5FD,7489829873B47F8D,7AD17D417D251ACA,82E3B5A4005C5349,0000022BD03D1646,0D5D935273F8F208,A036D3E5D7E1A079,C8B77669C9095E59,DE831077E41FA75E,DA8BA8494F92D713,7979B7FB18293EE7,2252F2E7A5A01421,51885D559FD2F9FA,B656CE5368B94A50,3F8E607085309A1E,EA753D01B3B79CC9,00005D488F327013,28739FF6E7830777,F9943C43FE15843E,C71F265862A069FC,FF968DFFB870E6E0,2CC00D3F6566CF18,C30C2B75BCB1878D,2D4BD017CFA294D2,D18CFD5C415479B5,41F3C81E491E34C3,91033B7B0C5E3D13,60327763E327F40C,00001AB76C98330B,BB493E352B5D4BCC,9CC8A8C5D23CF6CB,C322B14047AAD47B,F9A83538AAAC6C9A,E63231E1750AD429,DD7538C19495AC36,0012AA62C2C5048A,7CD38456AFA8FD39,623D17C6B3891BBA,BC60DB8DF5463DB5,C61163EE9852E9E7,00002C637758ADD8,D91874C68D09266C,06E3CB2D7CA58326,F47694C3C9DDB998,82663F2332DB6A17,52D4D8CE0465D638,77E0EF7941D8C493,12D256E7B1970097,94C18F37962DC4BF,0B606C419194DBD8,4C0598720C7B71A8,90958DD68D0A9CF3,000024FD1CCDD9F8,C9EFE7D25238AFB4,F3B39BE5A35231AD,D21727C0A4691B18,3153C1B1F9DBAE2F,256CEDE537098EEC,717DAD396835FBF3,4828A2AB6B823B7C,976452CF4CB3CBA6,2B4176C21F35F6B0,D43414BEFCE3DD14,752739285B2ECE1C,000054E90CF7AE24,FC0E593EEF077668,AD7C3BBFC27F07D8,1017DF7F88E67BEE,D224EF2C68709B3C,9C9502DEB6E9A20E,A539D0AB2F1EB839,162FCF5B695E7544,0DF46409DBC58D13,2FC991719C41D474,5D7A7995CE209967,9C03DD2B3720940B,00000D3E4F610360,1CE777A69EFA61B3,849E40C9B460ADB2,7B424B9FA081AADA,7D82498934EE5E89,A30EBB4AB088E9E4,2AEA54EC35C598C9,67F6BB540866ADC1,6A2576DE3E0753CE,BD875D9752685C77,03D24DDBEC2ADFC9,F4177E9C3E4F8978,0000370040FEDE8D,98EA487B9EF4EB62,88E91F9B7F8239BB,9626BF0DAC593B26,D6DD0B811BCB4A8D,5D421A34979B9015,C4A9ED5C0C401849,AB56CDE2BDA9CEBA,F391A28D104B8868,ACCC6F5402127BA3,D5D38495ADAFD022,62A35803B090E6FE,0000665F33D6D5CA,BE10627CF3C26FE5,18DA02D1BC073A07,2E8C9BC9DD2158E0,4864B2C2FCBBDE38,108F6073CF088284,BB362697FB5C81D2,13000061A0DE44D8,98CD554074485668,5E19B778ADC7AF83,5BB0A2B94335E0F2,E17EFC4EAFEE701A,00001710CB258A30,AD54082C970C1131,6D73BE1512ECC972,64192BC15DC3CBB3,F3D100CFAD728EA3,DAF9FE2AEC44623B,DDE5E129CEADFB8C,06471CF4125D3576,0261ABAD29D4DF4D,5547D259A99D9AF9,C1F8C67C67138C4A,BBD96EE0D75C6F71,00001A97F322AF3C,CB1421DF6F1D2DB8,506D4A322AF1B661,C8DEB60527B9219F,3D96BBCA38FC73BA,1F43D76A08B9454F,C05F1F966E655F59,AA51C39F4F9733FE,6C735D1DF548065B,2E789AAFF6833375,B365B02F2B06268D,AC3B25C9F940D216,0000171B683EDB2F,9E899954DE465AF1,54DC45E02FA63A63,C891405C91CE0CB0,E1789D84F38454C2,7292F29C3CD91BBC,88E3DC8A1B8EE80A,FC0F57823C8CAD39,6ED5BDF51956170A,D7AE1FEEEFDFF3F0,86CE1544B5F22A55,5388F0942E8001B3,000028757CF813EB,6A0092A0FD2B8F40,4559F54A3CE7CF7B,43153987A13D539E,4AA8689E8DD67F5A,5865867DCE6AC06D,5DABC9B7B44628C9,00BCF78D6321DF40,A47B5621812A80D5,608C0645237C9277,1FB8855CAD3D1B5F,FD5C19AF18648740,00006F5D7D650672,7F7BD6ABAC918CD4,E5CFC26D6BE311D0,46CDEFBDA4A0860C,E9FD312E156C13C8,BE8D9949E6E709A7,2816EE0BE7C3AC51,7AE1155C733FC5E0,605C97ADB7A8260A,0FC7198802C12933,D2061281FB449480,318BDAA5C88D3D12,000062E8E2D5798E,265C6D4F91215A34,86D01B8DBCCDA7FD,32CAB3D470E18C1E,820DE79102ABF04D,F66869B2F3EA1C6D,3EA18A3C36AE1DF4,C283D2C4F80C688D,CDF69BBC2E2622F3,4816691FFE552713,04B77DDCE2DC0786,6EEE702366D9DB48,00005E29787F5FB8,BFCF00C709C6D4F2,1ECF8724512977A0,852CB80636C6AEFC,AFF083064C94AAD5,53F88EC983059DE6,E44BE6BE6AD1DC25,B246B6F49EFB7BA6,A437AA0091B0D981,E989ADB8842634CD,AD662920F6D257B0,B380251A2D2D5E75,00003E1E0DC60688,26F4764CF0793A82,FD812A9278207166,959F2A8B295DB0BA,83D147D9BE1204EC,77F2B187E51AB904,8F199C77385720B9,CA39617F358B1A1A,24CDE380F9C715F7,6945CC3DCB7BC7CA,1DD3891D16100759,7B9783B537F3C44B,000044F0C8F1359D,BAC1016A8D095B93,8832950891BFAC83,709235FB2813AB5F,1FF6FF2E90C377FD,84B2234119337611,3A5CBBBA4AF4B00F,5A5E9BEBA1B2C98E,64E068FBBA2000E2,13B3CD243B44A77E,8F72C4AA48081932,BB7B9F232496D359,00001E8A08B205BB,7C78ACB67300809A,2D42C1563DEF9F15,BA74744D6F3E2C1B,24127D59C1ACAE92,B87C500D3920C601,C1CA6A21AE8D3E0B,D28F67C4BE5F7CEA,B34150DFC7CC750B,1A023511AAADB512,827BFE72AAF2F28B,DFA2E39DD148FF42,00002CA1A2173BE3,CD31D26EBEC754C2,2A355DD47B0D0B5D,533813EED01A9A68,E29024B4C120D545,3F49198E3F2218F4,C68A533B224C9DFA,D8FDAEA078F9179A,9F6B8E1E9103A445,953EB73CB405B5FE,6D3B551C369490B5,CA1F997571700725,00000A2F85770F0D,DD1AE5789695AC0D,CA4A50EF7ED28682,6031AF9393B1CD34,890DD60D4B722A22,D8DBEBCE97E9551C,B6F6AE375158D550,0E4D036AB0D53BAE,ECAAC4433B0B81B1,880F59CAD6B5E047,DAC32FB2BD14F467,5E4EADDF3C20ED38,00005058C2EBB9A5,9A684B647276F8D6,5D767E3227523B54,3688E3807EDB308D,B4BBDE9DF223E81D,AD8375CABCD53366,0B8CA2F5C51381C9,79EAD612CE08BA95,21BF86B10D2F9698,5A45398E3B8ED45E,889615892901BAD5,84D69361207742F3,00002B1C6DB9D017,7C299608CE4D9D08,8B6618E5E10AB484,18911A06A0F3053F,8FF8432321110504,CFF23C8433B97493,17E1F80E15DF534D,FF58DDE50CF4F054,CFBF02038BC7D698,DA3971A928406A92,009AD9D34EC28C14,11C622C802F4293C,000063C1856DB0E9,028E9DE4639FAC0F,C10028CBFD8B4D8C,6F740838E8589B6E,F66C5CCBC1E1C440,90DA5FD0C699070F,262AC39056E0BF45,679AC401D4334173,AC462BCC1BF59061,CB2ED359709FD0EE,41C9DC919FB39B90,A788F653C84E30A1,0000209C07630948,0B14FC7E2EF08FC5,86AD72DD3D0E25DF,8AF5D89AB5580F4E,F18AA28E1624C0FB,CDA03A18EDD265A1,EC705269EE4F8766,F1260BADC5741317,9303A131AB478981,885A218870F7C22F,A2C4A5DE4976F3C8,D1E5596B1A0C99CA,000044A5A7E0CF48,948C310857310471,60EED33BEE405C6E,76406B2A9030FD68,9BA52C09F2C6A0FF,3923889357EE3CF0,D25FD609609C5D63,610E3A354B06A911,69AC643D0E82A99D,38AF330295DB71A7,DE945EC03082D532,B3E5984E1DCD14F3,00000981462C1904,28CE39C690ABF2C0,C2EC1EF725D483EC,B48B08C7096AC299,9065404E50F31F79,D135AADADCEB4412,BEADC11A00FB574A,335354690FB6F983,BE57291C5FE0FC62,016A604FF64951B0,FCC905DAFCE5E369,6A981366726EBCEA,000011CB9DAFFDC2,31FCBB6439EBF667,79FAA5BA04587C91,9D1F4E2D2FF88673,CE6EBDF4CA4E46E1,AFBDCA16F6AE5911,D45DF934EEE94A69,B04FF0F33EC6D495,C18214588F376204,488831C8676EA671,ED918D9A33138618,FDAD969730565628,000041C88C9580B9,F8CBC4B94B6717F2,193809661EA7D653,C793659ABE82CCE6,32143E14B8FCB053,5F7545431BCE8C40,C0ACEF04303593D5,EBEF7AD527AD38C9,5065EB64E2BDD6E0,90D9B19E3267391F,105C853F4EF41837,B599CF6CF719E3BB,00004B287F661D7F,99FF0186A172B399,820CB7C6699B79BF,C7FF783BFF44D6E8,57269178890DB203,9FDD7A81E8E16D28,9ABC4FCE883D6F89,8252A98A6C3E953C,D51EBE68EE31A236,FD35099E0F6F5103,08203A8A46AF4071,91E97D94290561DF,0000619AEC05CD56,1ACAE5999016E4B1,5EFC0D61131EDF43,F65C123EADB888CD,0A086763D1B9B559,46446CA764404E6B,5EF1DA3C0587DBB8,13C1706D2F95B165,967264A7F808E7CD,98A0C161CB83B056,E26CDDD5EDB03F03,EF74EB3B36CDF243,00002650C1DD8A0B,08F48F1DF9F8C891,CD52E42C56C85710,7AB53002BA9A9D7C,02F03AEF2CE7EDD1,0B2D524153C69B98,B7FDBF19462C230D,5F152DAE37BE669A,4DC0248F23CCEC4C,3CAA5BB2715958CC,7644070B1D2166B3,6CEB5E916E33F783,00000FE3AF3B0DAF,F9D2E852312878FF,5B524AB498F32919,70CFD9EE03CA4DF5,583B8C675AFD4612,C5CB6CE408555AAE,084039FED4224415,0119CE5302C30C41,9902750DD6BD30DE,E794EC4CA8D467F5,C3A242315E60A26F,837303AE003D780E,00001F32B2545117,7B6529D7C4747E31,EE3CE6A04D4205DE,F1F34215914885B2,4685D054D1E6B919,B850994C723A0B48,2C3FAF99DB02540F,FD0B526F44BFC39A,97049EAC344C1747,41B8B750A7424360,718EB38B2F01B68C,145E44A6541388CF,00000B0963111ED2,7AF55532DF29C348,EB5C3AA0F357DC4B,C8080E9372F3EA2D,22900595DBCC16F4,10C401CA9EB4B31A,F3E6634958D766F6,853B53F91B6387F5,57651E2B89B8B20E,AE9F0968873153AA,96F2E9156A8B8DF7,0ED8CD4C1605E601,0000211526B126BF,CEB12DD8417A46C3,261C0D79DA059D97,6ECFDF2952D1860B,126CDD880769520F,A8D2F1C1523BCB23,DFA2991206633AEB,22B5F52A62EF08D0,556F3ED47A884181,09C5E343E3E28FE6,35A7C4F50611423E,FA73789BC23458CB,000056C7EFEEF384,F1B72ECFC698D9B0,AB89BD78AD356B58,3D11E9C02AE07B70,97F3EB4ADA4C06C6,9ED7E1FCB76A941C,DD91BA91D65C22ED,00B98CC4EBCA0817,97094E5C53025519,318154C0925F5F1C,38806821CB7DCB80,0AB7CC44BBE348CD,0000420A9B7C795C,1563155D6FEF7DDC,60FF485437A0EF41,80179A35BCA71A86,B4067256504238E4,C8D15754BC6E36F8,192541E5D8AB23A9,66E2E65BE1E62DF7,F3A583CEB0CDC073,1DF85506E647D163,87EC4B62A067024F,6BBA0ACBAA1B290C,000067B5190317E1,7EF903D24EB6FC3D,E68C5E3B52BE7F9F,2C69686409F1B3E6,33C2E8F1CA3AB42B,EA09E2B0F281B1AA,EB4D2508747B0095,4DB6626A66CDDD04,5EBDE7B661C609B7,59F2F5F8900467E3,D38933C10FEC0FDB,1E00C7BFEAEA16CF,000031622308C3E1,0E9B18495AF146EE,7A5C198D9F55F91F,003CA7CE8A642206,82B864C8BE2B941E,A566B9A92F01D2EE,D19BAB16617C6B32,7ACB1B7FE07E646C,E0FFD94D8CB67C0B,F0DF1735AD431A9F,81E44BA79DA0445A,77F32B4428F27FC3,00000A40644BA0C8,941A30613FFC8D46,B43CE402A9CD90B4,3E83110E06EEA64A,DB2CC42991D036B1,A21B1FEE76FAA26A,A3D07E96DE78D498,E184FF7DBDB6F134,4DE0B70D6562F940,CA0F75217723F8E9,701B24B893B2A851,5AEE81EDD5D33629,00000C4830DA2359,5ED27810940A4CB6,CCB97DA7DFD28AA0,B70C3935AB0F5F46,2D63C9C3610BEC3D,2203D09E2E5EBB41,DCD3CDD44711D768,98776387B55402E3,29F38F4F58AC7B97,CED3CD5CA7883333,4BED7613A7D93E2B,275ABD583F47965D,00006EA901A19A1C,91956FE33885881E,12D0B170DC1CE0AC,F7321C0DE2BA086A,97ECAE9BE8BBD9B3,D35ECA4D810A926C,5906475091647E63,E52768D0A06FBD5A,CD76CC270320BEAA,5FDAE231F9437C9C,9C65BF2DA585C31D,B48CC3D0BF45DA98,000056F59E12128F,21721C1F1EE2DAAD,DF2DB2A0C4EACA10,D9FBF8FB2C5704F9,7A313EFEA930D4BD,09D3086BBBC0FC6C,878F395F37B087AF,E0CACE240D597FE9,167FFFD30860053C,387BA234CFC6CAF6,A2BBF5859847C501,1436CCE2FE23DA76,000022A8BB4B2D5E,9442A326A568089E,9CC8E798B765EDC9,352BAF165004D28E,597810322C3F24CA,9A226863C002B9B9,B01B3B5F91248E57,4C02C8C54EDEEB9E,4FC159FCB30A1257,E5D8A96F0074F278,43770AFDABAE13DD,A2AF3CCDF02DEF62,0000572B025D0E1A,8B688DE8CA50435B,8250F283C4D3C041,658B89F5C52381AC,C8B0FD434C6084E0,720F9211DE7D4FE3,B8A74502BBCCEA1F,27813B29B16AE45D,B234EAD962C3C816,5A7EA671AEDB4FF5,E2FBFABE0166A2ED,A87AADFB7EECB8D2,000033D7C27130CA,BD4040CDF7283120,1591F635073AAC57,3A37C44431BF2546,39AD4C923F950707,5DF86C3E5F961DAA,090EB6A5AAA8BF5E,307BB68C5EECCCFC,A782EA33FDC83AFE,66D4996941D890AB,80580B23677B0E59,1F8713335ECC82EC,000052C609864223,77298B8788869A3A,AF4789385F04EFFB,F76063968E77356F,A3E3A973E52F3217,CA0DEBFB75D7B849,D5D0D21053C37B52,3697F7EDEBA23110,3C9F696B889A2AAA,D98483526A6ACFCD,E53A2304518467E4,6D456A1D56728D30,000066ACBC39866D,07D19568CAA8FDA7,27D1CB514BD44C75,439A57CE2DF3FDFC,AFC1A7113541C2C2,72EBD85EB60EC138,EC0D25F5E567292A,F66C42A750730CE7,483F7656D56A7C73,5122BCFBCC0BF971,7E3802AA23D4E8DF,D105C13B850D98E6,00002BE6D07373B9,2B488BD2876EF04A,7979EE3EBBAE498E,9A570919D48E5FCA,86E290D6A3EE1A38,433849A70620E544,B3EAF4D49372DE6E,40F62F0DA94E3F97,4B2E87CC0536DC07,9578ACE767DF5202,4F5EE063D5D2A190,9F201C818858204D,00001FC118A08907,F8A7D29D07CB65AD,FE3298CEE1B59B63,F28AC53359AEF9C6,59955932F5699F5A,F9A628C17649A096,A3CDCCB4628AA621,823026A17C7B2457,9B2BB733B4C4D9A9,188957830B94ECF1,33C53AC1B7BD6942,82FA3EF2E05B6A77,00003547668BBF77,880075582F81901D,C95A8626AB2AF7CD,1CDBE90CD298C9B8,4A45975C2BF4EAD1,EF21D0C5BF9EC297,192B56F9EA0FD3CF,0F0A8B275AE09B6A,30C2FC4AC97122AD,F6892C08F55C2320,50122BE82BB52B9D,C1AE42CAC5584D45,000049870F4BDF9C,F31F37D1B0A151A5,182FAE2367EA37BB,0CFB3FC220B2CA1D,CB4795A7A5073C91,9917BCFF7001EECD,25BAC91D8628A471,ADF0B036F4F8F3BB,A7E5A9F7FA8F8DB7,E6B42CD6AF2B38AF,0FECB60EEF7C0C92,05B3C5EA7625D082,00001030C0EFC628,CCBD28BAA23686C2,8D95A7535A48F51F,BE5A1CC59A4FFE02,AAD04F5E9714C2A7,6AC2A980457F1D5A,72A16B9FACDAFA30,4C3D2F93CAA5FB06,7C47074DFA9333E3,A7005AFF75D6FB57,EA5CE088DFACE2FE,9D028FB7B6578B1B,00004C49E4F25663,6B78D9574B1DD055,5A7182541AAEAEE8,BE091FF6190B0554,B127C3FD834D3CB7,9E8C9B2B8AEC6AE1,76D7CADCA63B8C32,71176097EE125027,C7046F786D043FDA,1B3094464CA042BF,4515D84A5D8ACDF4,8E59AE7FA80D77E3,00002FEC6A947750,F4F7BC53B51E8AD6,2B753C8FD568B890,1A0D072E8BDBFC9A,1677AE0F80287B2A,F8FC484B75E072C6,BF7E1BD524CEE41F,6F621D0FE36638F9,FAE139B3B41DE4E1,7B4F57CC167FF3C7,9132E604B536D1DF,3886EFA74877D5A5,000001941AA2B615,BC47A4946039FB02,93581270FE127BA4,02F5518A23255917,341AC7C10F8B0AD7,A2F661D621E6BEED,023B46D6E618B183,9D08DC3070E7084D,D74F1AD9CFD10B85,0B344F0867E60C3E,DB9B816DCF3EB073,8E1D7D4887E0ED2F,00003356DBE62E17,73BDFB190431589C,DF05E0168157D1FB,D5925EE16F58F89C,E0E9AC629C93919F,99B814FCD35E5DFA,7782B932941D1124,23704D24575C4992,F7B7ADDF588176F3,30EF159CDE9C9B59,80AD9778BE02E212,D6AD753D20BD0561,000062B4D9073E91,09EF1528BD8676BC,A8DD6942BE1BA7DD,06C4FD5357C08918,1744BE468D204209,EC9F9759080A16C9,0752715C279E9998,F595C558F865C4A5,51E73D209E8BCFFB,CE695EB036E9A0D5,426357A3E0D07639,B32E2643B9EF66C1,00006EA3D1918C30,4FA36AF37D662274,CC9192F5B5509F54,5F3E75D063EB88FE,DA222108462BDF90,8584ABACF7ED835E,D6CC92EE4F94AA0F,7FA8FEA298DEDAE5,2B11EDF67395E4FB,9BB4854A2691A2D5,150864F479065263,6A29ED541D1C16FE,000044AB32CA8F5A,C786024C0D4BAF16,792B93992B3E6DB2,053622A931FD257E,F129D8A1414421EB,ABADD0E8272914F5,2407160023DF01FB,E466538DB0AE659E,EB6187E8DB7C02CF,02602332B714FA29,CAF9520CF98F6D8E,DC16E49FDA10E4F0,00000CE728F7242C,D2F55C55088C5B82,4E35AEDC69645A35,9EE3813A7CA32BB4,522B91E3DB069690,38896237F33737EE,B3FC222083C9142F,BD7E64CF467F533B,CDA0C9FF85403DA6,BDD5199B9B8FBB20,FA9A034C732D370E,E579D023A6F57AE5,00004AFF6081E91D,88EC38DEEF62902F,C1CFABFF1FE95913,D5985A7ADC4F7B02,13EADBDFC6889E5E,927FE3F791B9D8EE,9C5022D99302927F,CDF3C7E39FFB64D5,5D277BF8F30709DA,FD684407C2FAE278,61DA8E2AF0CB877C,3B5FB68F26024ABB,000001F692562715,3CFF61552909401C,3D6291015D25029E,80B33BDD855D979A,DA8B0CC9634AFA20,7DD0936569784705,553D60E375513722,DD4BC56FFC346AE1,FA68918AA383DA42,A5926BC679881C2E,3F81C63F7A3E2598,0C453266B6CF55E1,000032F18215748C,31E81336DE17EBCF,2CA014628BCA7625,CFB57B0BA7972B31,5D9FC2010BE9C12F,6CF25ACA3377E583,4220F029F4B5C07D,4E3C173AFDD0741B,3F0B36E2C7F24429,D2A5BC8B05904391,399F449CD91267F3,8B248E9450804A52,00004CEFA40ED49F,F5F5FE94C1FA2C53,429789B268B81CC7,6DA4627FBD61F818,F201C112ADCA2617,2B65C9C27559AB25,B7E7A02755963F57,78322743424E967E,500F5CE543170680,D187B83CBC2FCCAE,55EC225EEFADDE0F,8C22C6A88A005718,00002CCAEA8A5104,3A78419A9B74A1B0,F3FB2F4AC602AC7E,32F529FF9A9D1CB5,FBD88F031777AE4B,97EEFA5ACD5EBED1,6F23E1C068F24A95,88C98CC598C0953A,88DC4C8C73FEDBD1,E36E8F18945313DF,11F4BF587A8B658A,5D2B83F1E126A73D,000019587CFD6C05,16A3DFC55F51C907,8EE0557E065080E1,C471479D407C5F03,D3959525970D0378,CDD1FBAC8C34B36D,249EBE8C46075DF0,C080F2FA3ABFDFB9,0127D9C6123C6BE5,EEDF845623A5EB81,3AAB7614F1310A12,4A69C5D98E550685,0000563741722A7F,8940E7C1BF6FF238,6EB03F5AB6783992,2692B2B52DC8793D,9FBAD0FD796E45F2,EBFF11E00818F465,65F94430408A5496,CF95BCEF7560A62D,A65638995C5FECFB,EA3329E5A529C524,95097BDF08BD6F59,6F9D63CC24512E14,00001D4D9C57A44B,7A0EE29A5482CA62,53B847F316C53A89,078791F6BF844232,469258CE0D1C4D54,DA525C5DDC773B08,1041D15731EE9780,E64C0911AB48357D,772FEBDBD0F987CE,394EA7C5161379C5,4EC34B42AD04BE45,AC3D4E113E713053,000018C8E87AC30E,35255F354D25E544,7E6DA10979F4DD1A,AB359BE3E91F62F7,F64172006CA15D80,71C7922E613EE0EF,8D04D56D130D8DB9,A9A4CC820C1C5514,9B29C50FC1CBEADC,266780FC7864CD0A,C6CB34859B91017C,2D6E689139CCEACE,00003D33F21B7638,5D9C2140F09B145C,4B780B08933ED294,8CB3AAB498A190F0,C561C4EE2546DB96,5BA94BEAE550D20E,4DD3013794B43EB8,04F478604D438713,ECF56A538F523E51,F4FE3F5DFE096AE7,3703B9D38322EDAA,070946C609BDE1BF,0000373DCCA34B07,96DE1E0F9669432C,A644D11B4BCC7C80,BA8631C80861D633,23177B231EFC4A24,B86D4285052C5D8E,2CF860E952EC1C9B,ED42A3AA8163C0BB,1DA8F1B0A2CD22B9,F9DF17C067B049AE,F331D4F2656E2BA3,883BB8A24B338B40,0000296C3DDC37FF,06E50090D8816026,BA35D7486557D58F,2BCC88E656390F75,643234CA0F80E856,C6B9619A12C6C675,FBA7E9F5F5813C97,04D63BF47F6F54ED,8666AB5387015478,B681F9994768527B,1DE645C9C3F81E00,DB9FF4ED28D6FA74,00004D12F1CD478E,F484FD1DC39D34CD,093469F337FD135E,C7F786A7980CEC02,49CFAEB3933ADD91,8EEBB3056E5E1B0B,A9BFEEC7C5B2920B,C95B55E4B827F166,5A7B60D8E648D5B4,C6567A7858251E91,065A7E9B95C742DB,E344A0A2CF6ECDE3,00000F3CABD89725,6A5219B46939BB66,1D30EBF08EAFB516,AC5EBBEFB1706A18,433049AC97135613,79F22FD4DD483D80,C1D839620A49F47B,37C25F2C7DE9B5CC,831A9452F199F9D4,4B5F346F31B7B26E,3E61E1F60762E68C,24AFF4BC47FE0577,00001E637B40279B,0FA82E52DB33036B,D50D4DC2AE83FCA2,850AF05A9D5751C1,313207C5EBA01509,678E15FA779FEFD4,00A1D1014B40CF4D,4FA00420E559D02A,7E2DF8BED43E30B0,AE952F241FDB8C44,0E3131FDD1A0CF1D,4A28458604B3CECD,000049468057686A,AFB22A34BFB2546A,317D762F51B73B8C,CEBB03D0AB8D9C58,0CE3F04D9476B8BC,8168E69699A3D362,ACC92F976E637298,A1F61FF38D99792A,89EEFF03149E2278,07F7FA08427E0EE7,BDD657EFE85AF170,14C766DB07CC4F3C,000024DF24AE7F3F,D2E04F56B3530328,5F1EFB4975EEC2D3,B764AFDBBC235314,8EB0298A8E7FB94E,F4A2BC1C91DBBC79,88CCE75AF6615CB5,DB6C64C6CF044BC5,8EF9C3D2C59B4241,9B4FBA97D18A3A80,12BC68F7742C1201,008787804E610F11,00004552832EB676,6865D2FEA17457D2,E9A3291C12392DAA,6317DAA317B23866,22CCDCF4574D4DFE,06209D136D78E026,EFF2223CE4CD97A7,DDF0DB3413B629D0,D97F20957F4EBFA3,75B8C6947C09C821,E14D76AEAFAFA9A1,D63A26FA9B470523,00004515CA02A58E,671BD069E7FF3080,3342772C71EAAFA0,6763AF15AAEF79B6,4EDC3EEE794CE00C,7CEAABE0FE8445D1,9380CEDB221F0B22,C3AA7660443E23C3,D9C5E97ADBD21B03,D97D3A997B112D9C,6AA22E926F96D827,D65F0C826C5A5A0B,000021EAB591A57A,49002F927D18CA43,26B252E0166062B5,56DBDD66BA213BDF,305404E1D93C89E0,F8292E436DC3B311,3C252A334BA7A2FF,5DE08D5348EF983D,8E1651A55BCEB200,6E966F36A209A00E,9E4EAF7763CE0E01,621A653E83FBCD68,00005F98B8225723,E02A0DE0C34DB788,7D4C9B4915419210,07F130D3BD5259DC,696DEBF2776D596D,C7123309DF270EE5,D2738C179DAEDB22,C4A507C9CBEEA7FB,6415CBBC110B7565,C1B315F1C5358DFC,B2A0AD27C9EE9850,C0485225E6AC3E3A,000033D222FFA363,E9C80EF4800066AA,41EA9E8992EB5F45,150CA8291CF27B7D,E333E644F7FE3D13,E2036AAAC87FD8E1,8460FAF9A7FFBE53,CC2ABCDE9D43B220,9341E4555DCBAE8A,3F38461E256722DD,1ED498FD57B85F42,5A10FCAE06B3FEE2,000046D537B352C3,E247537C6508C1EA,22353D48E4F68906,DBA52E53F8474CB7,BC8382C4DE784480,6162242483090AC6,D80A07C2CDADDB2B,869ADDE82E109C2F,B28B6D823E9D80AB,CF3AFA3EB1884E38,004F6E4A85799FE4,05746A020C3A3A22,000045E183B18853,769300712A75BB8F,CACEFCCB3119AEB0,2E75D4567288017A,CDDEF9674D448556,B0FF6CE34F1AC06B,7BDCD9898FBEC521,01FA32A65995E89A,291EFB8C863CB28D,C30EB751763613C8,A0AE2E6AE3206FDF,E19ECBEA146074B4,000050F912330212,EB2356A0151632EF,97D235885EECAC99,E38124F74FC7A315,1BE530588E345D5E,4CE6DF750A432895,0F5C8C4E2B48EB09,1C50EBA9044261C1,FF3B8ECDE71C9106,832F13516142B844,5E2EDEDA2E514B14,C2D4C65EC6288244,00003EB5167A9AD5,C50E4B6BB8B731AC,A3E9F636AADD629F,8E2E37600D52CFE6,2E405F3E0B172D8D,0E007A5F37E734F7,BDAAD97BB079247F,449244EAFD211207,E1A9277231283CF2,76743E32DDE82B50,D1F79DA1C2C5291B,7DAD552A3D99E3B1,0000660FF51B7FAA,44A638B258314363,FDDE975E28AB909C,7CC3E41E9A1199EF,0897AE1CD763D18D,F2B420590AFE599E,A8E18EC792C57284,6AFF83E2A49B4188,645DCE3DD72E89FC,6202C03420554408,BBBA2D2E46CC244F,9FED93444666EA72,00006DE68C7ADE09,3D9965D985732709,2A6B6079A8E8CA25,33874E57511F041F,AC5AB9C1D2CFA021,83E046DC91B01369,D2B7B57A86C5A702,C562C6B5DF498618,7DEB0E776B809B76,7B268E834DFCED50,D6D38008DACEF0FC,C78D513FDA145715,0000586145890697,8023A576933287EF,CEB145434BCAE1C2,7ED23B7546CEBD78,4D6E085FFF1FEDA3,D8992B1ACD83368C,F1B071F3FEF2FFA6,0718435E41F802D3,ED856439548BC310,708A0C1D18A3BA74,6BFDCBD74EA0C6C4,B1822958ACBAB690,00002E809D4EAE60,E590B087FE24E14E,1CBEBD2EB107E67F,18E701C7C84AD177,99567C426FDE656D,8D053FA8F8B75C44,D56F4E9931123FA4,E89BEA1A36E44E4B,1544FA7B968392B9,1E492F33CCFB41C2,005594E18411F569,6EBACCDC7E710D47,00000E1257EE063F,D03C7BD951FD14CD,6C1C45B17D8F95A5,E17F3205278EE2DC,83A5768ED195F425,7C9C37D346E8CBC9,0CDAC68FB483871B,22C78C5CEF4B5654,D4D8FD14DAE0B283,AACB58B93A36B24B,6FA360F4D05BB1ED,9779DE8D259B7A73,000035E9FADBBF3E,99E66086A0D7D3D4,ACCDB1719306C0C9,476BAFC700DAD5CF,A54D05AB50ACE624,472E0B42BA15B48D,696DCE3DCB41CA20,313FD9E7F36C1A3D,19DED091420AECDB,1338D68113095D1C,4213733AA78658BC,848300EAFE9B8440,0000230568D32C96,B31D575B231D88D2,3AB48BE6E71AC029,B1B99E5DF0C70421,4164BF77C12AEDD1,9920EC1CDFDA696C,610EBB23D4B1DCC6,5D2923623E3CEF3F,89C3E274C20B2096,A5D519D331EFCF0F,923EC6EFB1E7F16D,35A6F52847460562,00003A3E5ED54384,5E4868EE53762D18,7025B12200747D76,D716B57B3DF3C26C,0CBF665ED2601C15,D71601F64E875A1F,01E6E98FE1609184,1F604EBCA06B9DE2,E3B2D4871404C53C,3CC4BF7171F68E04,C1330846AFCEAD66,B4EB1025809E00EC,0000438415FCC22F,C5B48186A4D91964,BD10FC89618BD7E0,0E306055F6879388,4DCECE0E475D964B,79A13DF0EFE31B19,98668A23049FEF59,2DD6D826B65C59D3,9563288E7E29C2C2,485A5BEC3794A586,5FB59D7EF38E6867,60CEE65129DAE1C7,00003086F2C0C9CD,90A547F9FD71B606,E90B6B5ACF06CA88,E0F11381DAADDCE7,34E36617AD52063B,25F01EACBF0D8B63,201DF269BB646BC8,572775696CAB3813,76218006A8F9EE6E,899C9F6572545AE0,527CBA26E5E7591B,B9E149F96649DD72,00004A58FAF6941E,3F23CCFE9478EDF3,92D6D6450CCD2E3F,653CA641B0D4B32E,E9681DD5AAE9FFED,1E3B82C221913D09,0E0585F49A378894,42C56EFE93BF6EFD,F94F6BA03457A3C1,8E109D1C753E4B16,0B390566CF192ADE,1C4CF550109A3D10,00006B75CED4703B,E8B4B28C71574C22,FF9AF0A10362776D,6F874BB578C89585,F98C5E08F1040C25,B8BFAE6806F1D7C7,4B65B5ABEAB59A33,FD195A7E01ABDBE2,09C0950AF06C8E79,5E741EC4E6995A20,213F52AB3678C2F7,AE6E4F15A7C9D1FD,00006BAF5C76F3E3,A4EF459B4160AA68,4FB98E16A4F38176,89C3FB73A3FED0D8,4ED65130F43C8B2E,882D6A1116DF4CF1,03FACA5273B44A05,CC510AA1B7223AC2,4343B71CDA3F8F87,53CF44FE671CDC2F,69B32640A331524E,286A05E559C681D2,000043F0E64B7928,E6EBA4B23BE3E8CD,FEEC2FB115E3B1F3,0E595C3D1D3F5192,9551C14073023E3A,AF65964034D93D8E,CAB6E02EFC422ADC,79E0FA968EBE72FC,B887804316A76C8F,18736F205ECA7FE8,C1F8D49C7FEC2802,2C0012FC42150F2B,00002CF5B977F482,DEC07E3E073D4EA5,4E04E218783B8D3C,343D358E4C90E1A4,9D6C4C0C3210857E,26313598788A2E80,C2BDAF61A3D8510E,9EECB5ECE8F0901F,EA62D5411D5E216C,FA4D34AAC140D916,6B4F8D93053580FC,48880359368DDE5D,000047E6D1C18861,8A90B83130604E74,F43B8A476F87E449,C8CF112F5735C70D,52DABCA6491B81D9,2D40A0003BCF64DF,2AA2CDCF003279A8,778BA1D2ED901131,722865C4C9CA9287,1EA69FBBD4892A41,EA3F6CC6702C1221,65678214A9BEF9EF,00000215DC38B220,1103CD81128FCD93,781EF4A25C80E587,BCA95261D49EFC97,38E2042A6A0A45EF,66B01EA5B008A3E2,C12A1ECDBB4BCB1D,57C14A7C2011A3C9,FE2EFE6BC74DF271,C0C26071D284309A,95507A05CE88B9B6,D0D8F77DF70C72D8,00003B5DAD0D83BF,632D88F6EAB88A00,2506806248DE2EDE,D86700FC8DB53A63,99F79DA5C22C3064,CFDB8B11B2C08DF1,971B24B79E77D947,F4A834274DD35E96,0D024A18C48B5A9C,2A0B5C3A437B323D,38794E2AA3999E97,FA561EE77049D252,000012A1AEFCEE9D,A47C96CB076FE767,92790497F38F1D06,173396DC14A5F6E6,A9F1923E8317E6B8,00B8FAA534838156,FFC4B721300EBDB4,BB7505F39CE7B940,E9DF64DB5DDC483B,33F3CD238FF3FD63,8503035102B3141D,770318887F258C4F,00006F9D229B9B21,CAE7E3F36384A8C4,8B9BA77FD3EED999,D6A016A8A3F5B6C4,7C4996B6D7B0E0B5,236B604F1D84E879,95057BB002E16DA0,9495BA772AFF21C7,02E7485B59565B6A,3BF17B78163C6F89,1340284A31DB9B9E,81DA55506FBF3D51,00003736FFC3772E,5A0735FEC1D794BC,5548232D88A2597E,BD3FC6066D129206,2E94E0DF3233B3B2,A7E1C35AA8AEBA83,71A4CDA2FDAA143D,6D91EBC02BFA12B3,71C07E2A55D7DB0B,A7F1A3008AC3D9E7,F6F4A4615C3E1CAC,32ECAC408930C28E,00000430321AE23D,374ED4BC7654943F,AC201306EE41BF35,78DDFA1C1AAF587C,9D5C78D1FF9EAE37,9FBB4DD3D0ECB77D,6C65B0C79494F6E9,B698BED56BBBCF19,E95D7EBDFD1D1CBF,8C11C2B993D010D5,8C09A0EE4440B9F6,EB5D3016BB1C7635,00005F40DC8CF085,668B01CFF7AAAB12,C658EB698A7F4A27,EEF72191032FBA13,FB8CC7578B2791C9,E578F7602EC0946D,2C89EB7CE6471ACA,48F44C48546CAF42,1BF5A41814546FA4,D0BBC91A4AD8E2AB,C0E958EB3B6D0E36,D64934CC679C5F37,000026C2A6D07AC3,8138236260AF9108,DDBD4D220E7E929C,5EDD88643E4C976E,2E756352B3A292C1,DB443DC5C8977A70,F0F08D80A53F84C4,BA3ABCB080464273,554C06F12EBB4ECA,CD33D347FD527EAB,169E3F3DBFD6A7FE,D3044D06520017B4,000030C33FB8C5DE,2DD6BC3ECD966AD8,B6CA507276C2AF57,451D86C39A156DAE,EED33E0978D60C44,188C023B3DFE98B3,7A3B2729B406E91E,4548FBC55727CB26,D7A9F7CF271CD2B1,08B4337E9BFAB5A9,54031038AE66A6C6,A1D4DF0490739EBD,000052807636FE09,8D0116DF8776D348,7CA1CDA45B59A3D4,1C5DC697999BA02B,C30298F2C9E6B856,7D315D359C676B30,500606A39A83E30B,C63EF9320B1312B1,B5D60A593594BF51,EE746B764B6CFD37,E6E0E19FDD06D5D4,5511077883E8CC1B,000021354B5AE83A,958188068C081281,AE42695CC6E5B94E,F4E392DBA4086FBA,D13DE37BCA12AE47,0E4EA0657F600DBE,C83B69306C4402FA,179E0BCE6C9B1543,8F83FFC87074DE22,0CF10704969D49C9,F0AA502F7E99C128,7F1D5EE6CAE5F93D,000041C0A7C66045,742423D495744018,A65E0EF8EF39F108,620406D29C535038,C63DDABAB6224712,26740F63A5A86248,BB2328B75F23BC17,81294D6CE5D0D279,25EDC22E80EBB692,27AE1987E70E1251,8E04F9AE729859AA,77A2F955BB5E18B1,00003C5CBA71A689,A2D2EE3B3E5E3236,467284DE8412DE62,E026135D5B6F1210,EF0A5E83D686B05B,09BE7E6A4990FD4E,22732D3715E4B368,9198B5D78B0D9937,6CE5FAAF1CF4C99C,6B456B7B742F4325,B8F032B9D92E94A3,5931539B430B666E,000030D543E8CCF3,243629D1BD6B268B,0A1150CA7B8E5F12,331C2E1DE45FB7A3,9B9F2BFC7B545897,537C55C5B5F6B6BF,A520B130C504CDA4,8F3130866E740D3B,4CE743DF3BAA7AB9,42D0F8BB9D258729,4C58E0B91EAC4616,E8FD6020D2A75440,000068154377F1BE,06EC9E6ED6AB9666,B40C17196948B77A,CE9114BA411F5CE3,F17C279BB813269D,704E6913178A70E4,2001BA983C53D208,325C5E2546048C6A,24931C757490AA96,459BC526B1753E40,016FBE941BE0BAA7,C687D1E6AA9D0873,000008EA37C798AD,D0C13ECA3A56D8A0,9EE9998C4321487A,0B1AECFE54E11FFA,46FEE0096C91FB36,45F37A903DF23D30,A447277101C3F39B,30A25C5BE6D3C230,FAADB69CB1D0E2F1,0FC5C3C4182F7832,839D5BC5E0080574,89A645B85B489880,00001F384DAB30E4,DCC3D2CEB4E09F10,EA961D7C710318AB,F8021B73AD3AE485,AF809C5C3F1D3A84,CC48ADC2BBB9395F,2213693367C32681,659B9CDF6406BBCC,88DD31D10D3FA639,F47E300836607FF9,1A8294C572DC428F,3D2E1EF11B9E358E,00000D05DDD0D1CB,7ED32F8BE9756A42,70A2E0DAE4175EE4,8486B8DDBF9FC90D,2DF9AE0DC0442498,2AEFD89E3D60A17A,ECD15D9EE2A65A31,C004092F2538BE36,1B8A6068D30128B8,6C3FEE578FE52D7D,992E2A9A063CC5CB,A4F3EAA48324EB40,00002EB5FBFB470C,BF1670654A062E30,2CF8A21BFD0B3344,E2575C78988BA0EB,BAE5CC787FB05F60,AD7B4FBBB02B8283,1BF97CB8FF074B6C,FFB0B989441A70F4,89A607DE6AED14A8,D010058D87BB3A3C,8E8116075343FEE1,8D984E7D6DC80127,000001D79E1DC18C,7428286DED000F37,7D191DD33619C8D4,AD0304CBDC4F26B3,0DBBC021D2802DA0,6C45F45D68A173E6,A8E565BBE0CC8873,6473953CAE4E15F4,14C85B520165F783,29E247F6EAE745A8,4D59AE8E7A92DB9F,C789DB0C58C60A2C,00004D024CECED47,76FB0BFA58E0EEE2,A168FDFC53882F33,EF898ADB654CA76E,A59605573CC84CD3,7D1783D0756C6F42,00C7970078828C24,6DECC63D5B5E5CBA,DBBC59583D5AB912,68BC00F381D4CD65,E00164F8CD5944F0,2B07D6B6473CEAEC,00005C0C626CCB56,40C21A8F878276A8,AB03A186EF9D0A64,C3E2C2F4C66ED681,381B994C598F63A5,F5DE23E46F24BF10,D527DC93B1DD75E6,6FB0DF19B720FFDB,A4B8070D84FEF828,BBAFD654AB5F6E62,EA6DD74CC586C983,46EDE7DBEA59649D,000005447DAF48F5,F2CEAC222A164645,23C2E7239CC4C567,C253D03EF1E85E7F,BC3A9AA386E115FC,790C4A4F220AB73C,437AD81B668B985F,F1470DD13D3438B9,5132EDA5C4606E4B,87C4F34B38108385,A28B98744353A090,31524A273A1F7FD0,0000150A289A05D7,CCFA830C2E7F0C54,1AEB7DB1584FA46F,158D5445926AB743,B01286BC30D4381B,442D108E5FD6D4B7,BFAAA482241A0202,6B9ACBC8DF8A1A23,BA60B96E8553A462,96673D10A61A141F,DF874DB3033F6A63,CDA9F20D4B892C78,00004F82F7281B00,3077259A4D5AC3AD,BCF6AF42A038AABE,1046E4B0275D0D79,BFAFFAA02BFFBAE9,619601F4730B8D68,868C44B04E727288,7AB0D434D56BBDAA,86E97FB1F489E463,7DB40ED8CDBB3F53,4543E471316DE717,110021C5941C074A,000063AC42D2F827,2FD9EA6DBF28D307,038BA0D7E2F12B94,294698FCE33DD58F,F6E7E79908D98C13,512414B6B1000BAC,E8CCD56D3585BD89,A648ED08E756ED56,430E81A53081D2EB,19B848968CFEA650,F4877365D8645ABF,DF9FA2D0B95C542E,000036ADE99DE9F9,54157325AB797DC0,5C51263E904ADD46,AE24ECCD85AABA70,0F2A700F91B00311,0E32E6A3601A2AED,177FA2197A06D12B,26579ABC5BFA69F9,CC31B0F0739B3C27,83C7701421C60F77,43A1200011719628,2E71037B5ADB44EE,00005455184B42E6,8620E00096CDE119,E2F7D47619C87F5A,A74042E1642A935F,0802D0DAF576CA7E,059A7D45133B385C,2CFFCAAF0B50E207,7B99BDC7B52E93DB,9953CD0E6E71C8E6,2DC897B757614477,399FB38562F85A32,A9E9E8E4D0BDA54C,00004275AB8D3280,197CDE6AFD14FCE8,71C265F952452E94,FBECE2167BD7F928,0BB57AE4C9F0A23C,DDF17DF6422BF787,40E73E28D4C43CE1,875FB8D516785835,8FA4D22D64C11783,11846DDA2AF5CB19,F9BA99AC87F6F7D7,B024E80423DC5BFD,00004C68996D22EC,B59BA265DF37519D,6A90269B3492F0BA,CA4B3033755FF941,01C7CE181B6B7DDE,8EB62114FD9F6124,73489A744F5A78BA,562FD9BDB7A65EA9,BB118083C55A7D0B,830B4AE91F0F0CB6,8E98D57888D6B561,694CE5BDA71D7B05,00006D387949BC4B,372567195CA152CA,021E3D343483A677,EE855F509A41800F,362D70F6A6C50181,3B4C0BE072519A24,314AE7661B49FEF3,A1BF2EDF6C06041A,AA96906E760F9E87,69E64A8D84DA07CF,2A5C29C93A71B248,D81BE900DA545DF5,000015515159595D,D1F3080EBF506FEC,BB88D46370A41518,C677D8A640F97D6C,68FCD01CDF24AB95,7BAB6C97546F0905,68C0EB6DB1B865E5,8D4075077A9624E3,46C9BE6A197C0B98,5A2EC2CEB428CBCA,92FF32DAE0A1B701,D775B0D3EA8D5F61,00006483F971441E,010C96D22F0B1F54,7000D279D98E4168,2EA5098C0E5714D1,9E30448F10A05606,13D6D16AEFE031B3,D7172F12E5AEFE27,328F38D0D6DDC558,C6AB387630B1C5E3,41C06DB8BED408AD,3A90FDDED6F2F8AE,92AADFE102816A7C,00001FF2B3A9ECFF,389CA3C61ABC6DE8,1491ADF856DE2578,3991156B8CE0032B,A42A0DEA0389288D,96FC6DA27DB74AB1,8DB4080B2753312F,380C53246CCC15BC,7DE171D80257417A,401EA58A32A64441,4300A9C101E7F669,B756D2D7720D690B,00000E0EC89267F7,C53691CDDCE49202,04A6317118653241,02F7696256172421,54C6A5E1D6F13BD9,A306AA68F9779953,9EB0D0E62EDB199D,22817EFABE66D181,EE42B5ADBBF33C43,107F4F0EEFD53B4E,81A8B7722CDA581A,BE18E7430367792E,00002BA45D75A76C,69EC4857063E55D9,B48FB3BDE3801FAC,BB04BAFE3BB00955,36A0A9090F4550D3,E738800B149DA8BF,EE7DC251E384642F,BB5094799EE9C03F,014A51DBDE9462FD,23197C6EA657C38F,9276D0F497C223DF,1A2DB06F59EAC85C,0000316AB1AD08CA,5B1D717C285B2EF2,C96FECA9446A6A8D,FD8FE2CF93AC5398,74D85E0EF422B204,C525E66FC3F88B45,94E1A4D11FF79C30,6380F2D10D590286,614D821F6B9221F2,BBBADD0F40F326C1,84532919D19A8E75,CF6099DDCE80CF8A,00000ABF14BA415A,461A0FC7BDB7413C,55DE99837B89C52A,0617A6231CAF40D7,19BFC13DC146C60E,982DB8333C8872A5,668E7059B26EFC92,031601E3ED794286,C88546D31EBAF37C,B0121A779D203E64,F39E841E865D4BE8,0B9AD79E2A768139,00003AA6415AE101,635058ED88D975D3,3C86013BEB4EDC35,4FE54F145C22A8F6,61EB2EE29D0240A5,CDBC9A0B6AF663E0,40BDF3A07B731DC8,C36713F4394D2639,AD5F248C5E0DCC15,661158AD2297E6BA,8E57A112314E6C4E,8D189D7695AC93D0,000027F227E15AEE,3A3C024EBF468972,83D1CC4EE9B1D202,05047937A50451C5,A794E7DFF42FAABC,1A9F98A32CA4E2F0,0DB7CE6971DA662C,0802020B94D82A8D,4D4DB31F16B0829B,FD13FA9CE95D7D48,653522DF250BE33E,95596A7E1C9A860B,0000216C1A4C8F1D,10C9AE937EED3BB9,86F90669E5C33255,0F131C7BDF445D31,55DBAC4BD602D550,6F179FFC1F83883A,31A06ACC7C280C46,76F54E74F5D4E5EF,D49AED3882A528CF,1106138D5555AC74,13E2510D695348FB,F13712B32566C930,00004FF28061237E,A64207FD2C7B8FF1,62EDEA4327484B3C,FB8E0D1D9756CD9E,F194F0F47E71461C,704BBC17D1C0FB28,A6A601F2E87991E2,1CF1434196B14E2A,EF811D73C6B7C205,15A90960D3BC70F2,36ED85F16FBD5AAB,B3E38912A3B78334,00004AF7767212AB,031455246CBFD468,840580C4ABF151AF,EAF2FC30D29367FB,70579ED3597C9858,8E10841CF3977180,D8313DF058C31EAB,E76EE68ADBAD619F,32517E9F021E8B88,1F1F1864C1C39798,EC76B0C0961879F0,CA78817AC5DB2852,0000630CD64314FA,09A640001FDDB0F1,6B96030B161F21AA,5BF83714E43058D9,B32E3005A33EE59A,847B811D78F439E9,CB68E1ADE89ED8DE,7171BB71B1B5F4DA,57DBAF31C191E05B,5979ED9D1CA3E0DD,2760B9539D2F658F,B742F27472C2F084,00006F1A787A58E1,5E4C91FB02A94D0C,FE5520F409745209,8332D5B6028101F1,720149726349CF3D,B797738862A0FB1F,914B1ADCB37F961B,1CAC385FFA10ACF4,DE70FB75B902576F,3BB6AD090A182D90,FEAD733B6E06D236,EB463D4AF946C24A,000002028AC064A2,92E2A8B88C2F7C2E,FFCF3A19B711CF7A,307FAEA4A8E06038,B85F6C5E22A64B62,60B1E673F9B38C88,2F697E0F37BDEEAA,D7B5A450930500FC,0BD3B4371C3EACC3,EFC7BEB78E6462F4,8B5788B7DEBB7231,79E02153D0C9B928,000052A312463A7D,0D2E43B3918377F6,A4D826AC758F3834,1F1FC0D9672EBFE6,13E4EE582F8CEE4B,B49D6DBDAB4B8124,D313CF303DCE2AD4,A3723A50C9A32350,21987BDD58207699,DDF953A039C437E8,C06BB1F79D2DB6EF,B75661DAD650763A,00002FDF4CD0B5F4,B0F561F31B1389E1,8EC3BC3DD72E9E74,00D1C6F55249EECC,A4061DAB3670D6B8,16FA8EBB55AD6D19,703964404E958636,28C9E90A115EC68D,437EE67A66B64F37,4E3009D219DD4DE6,D4E4F0FCDC87C04A,E31D32AF1020D1EC,0000351E9B7EF321,2103E8103D55C7D2,CE29492769222231,12168CD577FB0D0F,9ED67FEF7CD44779,4CAF1BAFE96C3BD5,DEC728C72F4A28D2,DF50A6A895EFF325,5D29BB9EFE298FAC,59582A093A22FCF1,D39B90DC5DAB9E43,DDAEB27BCECC3C77,00000CECFF3B3522,B13D32A1A979AFA0,23C175CB0546C049,CFDE292F217D1896,C216827308F4BCAE,0879AE6DBED493E3,B764B8B74E860E02,132147FDBB1C688C,F6BB4BE8C328FCF9,D4EE7DB91EB343D2,4CE3EC2461B09FE9,B71A2A8B5C8E7D01,0000019EC0177E82,8DE8E0824713999E,1F201B53669D2080,074D17E0DE7D2040,6111EAAE6824D076,37A7AE734C74ECBA,2EEF755050D9AA8B,CC9D8CEC460EDDF7,412649C2E85700D6,753E929510CAE0AC,1BEAEB4905E2BB42,A7B49E990A80D0A8,000060B88FBA3F9F,7573357D3A330D93,AAF9D733DF2CBEF3,BAE570F6EBA8B4E3,CF8A7935832B47DA,3408517817446AB3,62DFBFB72F169E4F,B98DFC4A223C6285,EA481B911E2FA43C,E72D63C2977494B3,E42A84C741FB1AF4,7F028F5625D34A7C,0000567EB0AD6EF9,FF286C3AFDADB5B4,659275F170539932,842B238A23BF44B6,A5363B39834D8E27,11A7120A9BC04584,202D9B262B070C84,EF5A5D2EC83FD23D,41439F88E0F0DF30,0A9C1D4651BCB140,FC2F9EDB23F0C2B7,1D6E6BC6A8E9E5F7,00000B0D4EE477E3,B5937F3A01FE2D1A,3C941B7CBE215891,0414354E0554CC57,2FEF01A93AA03358,0611905923171094,84D93F8B18B573DB,17265E2CF9F86D97,BED303092C25BC86,C682B11089932B6A,5DF12F6B2A185162,37D0EBE5657F2C7E,000042272BBB6B57,362A1EBFE8F5A874,F636E21CA2278527,81DDDDE22516E087,C70A7297369B825D,14DC2658F4AF3FC7,7D2470F3352B1812,5B9DE9EB6FF0617A,379EA2617B123FBC,8EAC4D1B2D9A0F7F,90B2EA9D1EBE32D8,5DC16E1189CCA3F4,0000166A595DCE85,AE85F7E91EAE794E,E58FF351C9D254AD,741373BEA13D0B29,695716CEBEB5C02D,D408943556EDFA3C,3F0CD03A3023D7B9,05A046D9CFBC2A08,FE4DC9CCED748AEE,1A7E75782CA439BA,3B57610D9BABBCC8,11E769B0C5E7CD7F,0000050C3D654E80,3794E69184F62E1F,B1303D5E5396D5A7,17F1BA50F862A461,7615409F3E472D71,610A81BB66CF9F8C,37FA8AA3D1113289,1D1BBB45819D76E9,01C898B16B1B6374,14B35782F503943E,3586CA64D33A7B84,0E204001869E7AFE,000019443AEE6351,8798900797DB85D9,ACF2C01EFD516067,03DD4565FDFFAAA9,AD203081C1CF8AB8,C0A35AB02EB93F04,38E7325183E194EA,A71C2A44372A54E0,A36E48E01690ED63,D738CE9F0FAD25ED,E6C10C0E1510C367,120F56294A65FC4E,000035B60CD8396B,4395EF6135D01D89,5966382A002FEA9B,13409C840AE814BC,30B5B3F930D8BE60,0D6E3D5D75971208,657B1316602441D5,DEC83D09641520AE,11D3954D5638D76B,3F8CD323981AB7E5,5A188B61B94CC868,C7C8483AED287B0C,00005791CD257CE2,69D0798075C23B75,92BD143C4320B9C2,D12BBF7025E4B5C8,926072DEC2292FC1,EDD76393AB783B2B,E9D400C4034DDFF6,EF522C3835E059FA,7AB3436ABFD660D1,20CC9141AC6DF6F6,867AD6951150FA68,972B03ED0E61FBDF,00006AD0C4E49DF0,686EE9A9CC3F7A88,518DB8A29410777F,56926ACF686FD261,D50B9194E2D9474A,7C5A857C6012F3D8,854ED3685CB25952,D1253D5488FDE045,04A4BD2C45D0D32F,54005D4DC3B42D11,B5C11AF4FA719290,E8B1528DED5AB8B2,00000BE3BC854F34,E738CC398810AFC4,7973DFEAE425E507,9C7853DBC0F054C2,0F733136378BE92E,9684652F84D9DA83,1EBA25646E4A92E5,77398B40B01E102A,E48045CCAFBFCADC,1CB7B36A070E6CE4,59C03A89202C10BB,60794D3F08970494,00003EC31BCDB3B5,67823CAF352E0A0D,3B23FD4171C129B6,799BA3EC69109C9D,E4E29DC6AF389526,6D839491FAE413C6,B173DF09C2D0682D,8BB9B1D027ED85E8,1A3F1C28C1545A4F,305CBBD25005FFD8,1BF1F3059FCFA312,33DF6EA13BC1C0DB,000035856C764CBC,E77DF4564FCCDF63,C856B345C8AE8999,39B222CCD185A910,E8B17A0D2FBD7E93,029115A12160A2AE,C77C65E3A4F3B57E,A243A61FD411FD31,AEC2D49279C1E705,5D882C06AC366C82,66A4A3D4736958B6,D39F492C1147BF2A,000064CBC3C134A4,7F52179FE44369CA,5759B85D4442A23B,A2F24A293BD565F3,8822654C4832B9D9,89594B6F94047762,A62C6EF595ECC3B7,E689A37C679F796D,4ED6CA57B95143C5,19394BB9F3183053,20757ADB2B1994EB,F23093C2F942DB9B,00002AA64991764F,710E50578E5027DA,3DDEC22D8C493CF4,09C00845414D97F4,C42E2458E4C13AFC,8C51C8FB92464425,7695CA708B56F983,7908C7C88FAC32E8,DB9800D4B7FBE8B5,340639221188F2BB,A0FD0050E3D8CEB5,93A1C46503FC4224,000044AF55B78F92,C2C346C5A43908C9,97DA447F04957CE7,62C56BB605E41B0E,E3E1ADD6062A6016,3EBEE3F5184FE454,2A9E37776300123C,004C70300308FF5D,0F69E07778D8E5C1,FB442EA5BDDC96F2,349D02E3D47FFC66,060F01DD50F10F2F,00001384A204223A,2771F6321975DFA9,7A7F0CFDEF680EED,CA7F60033ACEA746,52830FF0FB0BDBCE,8027127DE087CA07,92E3F3D93D40D93B,5BDFE7861C31CAD2,A5423C7589DD3C70,162E58B7A38FA76F,9BFD37EE8BA8664A,EDD6DF1048BDACC5,0000178AC20A6A4B,D55C40DCC6CF837E,0BF5BA1D086284DD,9CEB7C4965BA2447,108210914DFD4D59,64999FC808DEB88D,487BD1021CBFF9F3,2190316D976F2D22,7733338B3BA37C02,884B7D618E48380E,E76DBDF03D131AEB,B2E7527DB113A0B0,0000045BEEAC30F3,F7028A2D2CBA2E1B,F7475833FEF571BF,1BB3F375F22EC3F5,59C39897E070BD02,432053C2ABFEAF1C,A2D4ECC61371A1DD,A0D62AF0DE83F459,EBE5FB4A7FEE37C6,811DCB49C332690D,C6632628FD48A6B5,867D6743A4F59215,00006C61D48792B5,3E3F57755EA19C73,65347E4C5213024F,595900F4DB79E432,661356D4FC78561F,C4467DC1826D0FFD,988DEAD21D8B4C39,BDDFA39A87E8CE8C,4AB6B6DCE8DCF09D,7E343774173488C1,C1256B14380B08AA,2DEB3CB3A1E8686A,00001E4C0EFC3D99,8B1F314ACBD69D95,CEEDD314FC54BDD2,3B4953210E37CB10,989BEC3472ECFB4B,CD25AFC51FB80819,E9129D28D8AB368A,CDF4D3A8252C544F,BB1D85D429FC552E,224AF896EEB596B1,384838730276DC27,D4C9CB5BFF160B46,00000090AD2A8BE4,E2950CC2429A4BBA,CCE47F0EAF4D20F9,281D0D4A83EBC5F7,6EE27F0A76BD219E,A7755995DBDEA0D8,700F1A2139F61A53,D95A76D800653ADD,A84D5BD48D09BA87,7102CE3FCC6D4D23,C17A1B7D61F8A8CB,2076654F96A2D5B0,00004C14104F7BD5,26A7AFDDA224EDC9,30F6CDE9792BA302,64F0471225B0590C,F4998171F435C79A,E3269E320B381F2B,6546FD09ABAD32C9,C378436E3F395B33,AB55CA979DF5DF21,B8AC9B9B2B6BD30D,A4954EA9552D005F,53220D054A4FF3C3,00005A0BEF137977,AB1C9403DEEE78C9,A9B19B41EBB1CA3C,2FDD2C10F3F98F5C,DF4E423C3ADE7336,891503EA3FBE9C2D,8E9C8153F903C11E,1A2B57C0345CCDA4,19BEA9CA9DE0D6A5,7A5E4C3781CDDA77,E597408F09CEE810,1D0814CF36F0B83A,000019A16D73E2A6,C632AEE94A09F472,847FE5DC3FCB6624,FE55C6A7C07BF832,96BA902C3127621E,3BD5FB12500B3B81,C8CB761FCFDCA919,E4CB47DED4E1E726,5D0E6D01BFCA38EF,BD325E9CC6674AC7,D4968F68EFED04B3,93F586A3A5488AE5,000063F0D1BD3B21,08B55F2F3A483254,C421ACC801F77FF2,5C32F7823FAD83BD,7EF013B7BAB05FF7,4465FC7739CD5F14,79E4A775A367518C,85E7AB1E5609DC77,8C91E53910FE897F,B3C22491E167B3D9,C591C88E5BB0B506,08DED3E361C8C7ED,00006E1D8BF10CB0,6A8784DE6275476A,BED7A8D2F6442820,479AA35E75CAF9DB,C1A6A121526FA902,AE1436C31A7ED2B5,468036945E1D6AB8,438F861C06C0970B,0A95D246800664BB,DAB4BF110B8AF474,F767A6B9883967A1,17704D5B31EBD219,00001B0C1A8D2104,6C7B4764A220F3A9,DC0F0AA1EF124958,0E4411D6A4F803B6,0D91D36389A4C8CD,9813BD47F0DAD78B,E308CB3B41D75F25,B95D27B8922F2844,ED02323019E24E98,8D3417EC4B5B89CE,B980319FD1FD5FD4,F678601B33ACC602,000060B185683014,7574F4500AE0D880,A62F8F4C3835237E,78F500E8CCA4D0C4,4AD9C0E36B149B6C,95E7821AAAFA32EC,CC7510AFDFFAA1C3,CBE0975C43B658F0,60D0809299AA2B49,718309CB60068550,8E931FE88E35ADBF,21FD3C6EE9EAADCB,0000683C8B2CDF07,3B9A39D897B2224E,EC1D6A85B06B3406,FF05738D5D520E8E,0D299C3BC8BCC5AE,2119009119E16B5B,26FB4F2BAD7985DC,070D25001AA0DDAA,1223F5F048AD4485,BCEE12790D5ABE37,8518455FF21BEB2A,468A1634D65F07F1,00005D7E24C7F0D1,7B8BAC30F5CF045B,84893BE811B630EC,8B1E598A3C0A1217,E8FA4701E16B7DB9,7D6F77A5B7999245,1820C3D0F8DA1F0E,46A194C243198676,D244C586065D1A90,91369F2AD8339D2B,731C69E32B07DB21,D5666E588E88BAA0,000052B6FC09D169,F150CEA98B9E343D,1DD0BC498BA6E578,98A2E5E1584E702D,997EF19A24F81703,1B75B3122B9972DB,F28978C821A161E6,248981D87D858BFF,65EFCDA36FD1F78C,02AC72C099BFBA9C,33F04F40857AD7BB,03E5AF12245D06C5,00000BB1E9AF27BA,3D7BE7B04521F19D,D435DFC99674D251,2F743E7FC5867D07,EF9F751877187753,B3ED38EC0BEE78BA,AD9354D2A779B106,F9EC524374E31B40,604F3B78C8F8C964,955F4AC04803133F,6501DCD8C4428B6B,2822FB4775D1A839,000069B94735629D,87C5B58ADD20D7E8,B3773C97C357A9FD,2177BE6E2E558B1E,486B07BCE35C9E09,A7CDFC58B080F195,3190E0122764F882,9D892344A1E8B81B,896FA4A3CC7873F1,C259CBE73C6BFCA9,4535181AB36C0606,1FD72B787C271C1C,000037C39BB010D7,F43A313267A86F7D,4E83BDE9FF8B620C,8A77750E8F3A5AD6,8210935578133F3B,4AC9A53E2986F303,88AAD78BA175BEA9,356C17ED8C10A5B7,9586E65095A6950A,7FC71BBB6265DE2D,0CBEC3A289C71E71,BFDE0E1C579CFFAF,00003BCBB957EAE9,E3942781420DEBF3,C3EB384081E8712B,A981A945A1D41492,5747C50DED15C1E6,D0F8B818A5D4AB73,E6EE566BB8D5AF5F,A5AFB645DDDA33C7,85BBB53060C12AD4,2F679015006FC36E,3FBACB197D406836,FF3D4A99AA73883B,00000796DD884F2E,4602F11CD879EB2F,87925C8151995B73,EAA0666BEB2B7481,5733D72BA78B1E71,61109EEC4FF902FB,8082EE4E4A0A6D37,64A42907CC27EA36,B96322FAC167FCBF,BA44FFDF4A707470,C2AAE3AE32A22367,05C3359637E88EB5,00000555D696C3AB,3A758AFB2C42DCD7,834BC264D1E9DAC1,1782CCB9BF38CF45,2122E7170660C339,F9C0A8905BBB90C9,A8CE423AF8DFF814,71AD34C52FC51E90,384DA37878A2A933,480F35D08B67DB2C,373B14349DD88900,A9D9D888EC767142,00002D84CA7C944A,3EE7C62B62088980,0BD65C59B3B34BF8,D3D5CDCF1B624025,8603072CCBC2C03B,2423C4E24976175A,57CEFD8E4A61E633,960E6511B4ACC946,B0CB00E7E7C5071E,93611ABFEA79CBF2,B86EEAAC4C43AED2,5DCBCD831C70516D,00006CAB85286258,EE0473671260DF2D,89976CD17D7DFB3A,160D7A62596599D8,1F96FEB5F1AE9DF5,8DA8A6D7E92C5138,338E46E40C121F6B,8674905D92D820F9,6B726F2FE75D3E83,A4CD83A289D0F806,60CCAD9E2BE4787D,8BC2A4783D75F34F,00000D170A542BE0,96CAD529B29DCAA4,78D3E7DFBBE7C26C,31BC535060CA263C,0ADA1177356196F8,97CDA6CEC23B2A84,604983F8FAC056C5,3A8C8633C89C7B5E,04A50A8E8513A53A,B7AC8501D5D51B3E,FBE2EECC387E9648,FCDDA19B1D6BCC58,00002038E88638B4,20223B50F70FD94C,4EE36A968836CA2F,C11037BD3CBBEAC1,E4A410763840FB31,A76784735F7D00F6,A0284D13ED4A342F,27343C6D57C22CC9,915D0C872E0F6654,BB03529F3D4689C6,A384F4A2583A32C4,BFFD8297BF4BC816,0000248A94BD4713,EC665353630195A3,BC59A3D196296708,D583D250FB84B08E,55D69CBDE6CB0560,9BE5ABC8241041E0,E04FF4BD7A10D443,512940C3A743D6EE,920C3C2457C7DE28,80B119D6EE840056,0852A29A89D74E55,66B82C17FE3F55B7,00006B90D2A4FB9A,FBD5DA1499C7A97A,FCB29D70C14555A3,E531064D7D420170,835E46B1EC3F5962,6DFFDFBD7D10A379,E98F57EAD2EFAE48,774D9CCD70EB0A2A,2E64DBDEFA753BE0,DBCA861D704DB3C2,3C78B71060BC8F30,A3ABFEB14F916241,000026EF9034938B,8D6A6872EE943500,084A0A5A36B61126,2D1980C82DECDA1C,B5FDBCF5ABD76D89,AB84A079AFD827B0,B5EBE21037EA1EA4,8E4F3D7E57A9E4C4,DB9257D44C624023,927C0B1A116910B1,EEBD2CE3724CC059,5F1C38A9F6608174,000043321FA78875,A4DEE5B6048C2F0D,2D246A6720A6462D,A1E8A8C9377776F8,92468B36C9272407,2C1A540C5EAD3773,FBAAED7B7B8C18A5,2F17FA4C8DA9E064,3C2172EDC1250439,0696ED88D63206F3,08312CE1656D0973,3DF1FD2ACB50B876,0000648898CD765D,2E51B1DC72F0202F,9ADC77371FF66453,FDAB625671BAB047,052B1CA4B057FBCA,A685AE12DEA20A8F,5237AC303BAB0B82,8C1DF2BECF1F4BC5,82E2968246DFB380,CFD3760E28DAF636,A554935F882FB49C,AA98C8BA03A8C2F2,000028527E45D439,B06C6E98AFCF00F2,67685D0C88CEA082,29EA8633DC90ED13,FB5DA271AA7D4D2F,83A68BE3538EE7B9,8C05AF752F4BAAA8,A11E612B9040976F,5A9DE72A72D2783C,6D4CE3F0AE1E9F57,1C6FAAC3FB2ADBC1,20BB29C2834D4537,0000265E538389FC,22CF16447B0FFBC5,8151474A9364851A,DC66789764760770,8FAC01073D995CD5,049E923A1604C4C6,0807D58ABECE4A75,F2B84AD6B719EBF6,5902E2C6591909CD,E87A55418BFE7F82,C14AFB38DDE3C3B1,371E03D180EC6B9D,00000F20A74B5ED7,C1E9FE385E269664,F167CF0ACCFECC88,DE60E98E1BFBD17D,048190CF0FF4BEF8,AB9A39C3AF901138,4C857CF0464934B0,A3B7BDB3A3A4C7DE,C97831905A6D8265,AA3A04835B5BCEDC,DDC8D8A52ACE8621,BDD0A686BB4A4809,00003CB71D4AA268,9BC70057FFD88A40,7FB0CC6D3595BE4B,A444C3F4291EC60B,C5ED2FEA34B5D6E8,2782D5FD07F1553C,2B22F7298EC10B51,38E38529393FDB23,D6976FDE2894F100,69824E1BB57AF544,7B7AC9A89615C3A7,15C4AA58B2CE7928,000007E89A702918,607EC708AD2B91FA,098BFC2C85337F9E,FB12C2CAF82FC675,F6FF83A2D9A94372,B22019435B929556,8DF57587B0B36E29,6F24E651C6CF40BD,B33A87BAF7F865A8,4CDDFB05CF388E39,8E85E62787690B9B,68CE6A6261118502,00002DE334A19372,C8821C7A24D49D20,9DE996DEB02AF85D,3A34DA7F3EBE63B6,EB9A52BD85451898,60C6A2431C92CF11,087AB3FD2937B161,B98EE435E9057732,D07B6DF99F2A0F84,B391D10D155E9B65,A08126239A8B5D27,4DC4A56E0A8385B5,00006EB348C23A95,FBF9F868993F86F5,7935C48F0F2F8C85,4737A771AF1FA1DF,E121F1B878CCB93C,55C4176E59E0F538,80B8F460994064EE,DCC82099A4328D29,5682A09F979E2060,F7CB7287FB5BE6E8,C666891AB44ADFC2,1A0BFDFB08E69AF1,0000354F12701B50,3A710BF7DF65C40A,884AAB79AF089582,50D8472928815F36,0627211EE3D5E2A9,EE6DE337970B1281,D7A83C555D8C3D7A,B402B023F3196734,C99AF9FD8391B28D,7BA6DDE9FAFB72F3,D338C3E20BED8DFE,0876962BE0E0C192,000043D0DE9619F2,0993731F8FC90E5A,D5E072D40A7E0ED2,030DEEC3A1CC51B9,9E7A66F14C26CDEF,8A080F40EBD664FE,6A2C07CD06137912,12A2514781F9C028,3037F6C7F3D806BF,A82C33E7CBA37D1C,C538600BB0DA6C3E,B7F31EE04B71C37E,000015F21D31711E,ECC68C0213EE7780,CDA7348B367F2AE1,A890C3339EC7DB02,0E94AA2816DCA539,8B6872FCFA51FCDD,413E1D5E96B1201B,51CC3482A174F7FE,47FDC58CA5D6D6BC,642724EC87FC11C7,F26BED92E24C69F2,55B9EE513523DD1D,000008293C9CB57D,14689E030307AB38,E7B765A3DC1811D2,49535A87AD9319BD,EE39EC6DE5C8833D,6336F843D7C6AECC,46F6626339EF4E0F,6A443B458682EAE1,0058C28D34581AC5,08CC210A94D8FD65,9B355DFDBDF258D1,6320983015A81C84,00004D791EAB234D,B5DE6D021B6A11B1,EE84E11217B38679,A6A930D363B8BB1D,5AD0D87A03EA2960,4AEAA36B5606E4C7,D0F47A0B5DC27958,5676420BC45EF2CF,C60D16AEE5460613,19771199D4ADC5CF,ED437D43BAD8493B,40E9108D30147F04,000064CFD7F21274,D2CD0A7D63C3145A,7EC2B0625E273B6C,DDCDE8BC6DC1DA7D,65BBA397DE116346,CFF5FF06763AE023,008ECD802DBBBB91,DB164245B9EA8B40,DCF2D634C05CED5E,1F73071AFA7DBDC3,72C5A539A5B5B9D0,B739A287004FCA94,00006D0A67398BBC,9BC1E6EFD45E17BE,57CF3798AC3C7BCC,2FF67B2C493F13ED,3E9BFACF29CB25B4,D99CB6D96B19593A,18A460C8DE39C6EB,255A7FCD151EA3A9,7015E5B574E3DC83,9D292A39E9228B37,CD396CC4976B9FEB,0EECC02FD0D82684,00000D2AAD23756F,93453DACAB7BC958,ACC8D603D1F32794,91C89BDB5C9BB62B,FCE213F14896910D,9BC9695BE9D70A06,0224BC119ED985B2,2A97CE341BC53C2A,E2EBFCE2B3BD5CAC,60DC7A3F4EFF7339,495CBEF2087B3B87,856BF0CBC683AEC1,00003237B7FCA1E4,5F70D36766C439B3,8EC1967B468387D5,C861E96F38A57B59,C633C5CB571F80B8,8B175725D1748FE7,9763C3199915AECE,891547F9F2FA2FAF,636E8398FBCA047F,D7D0E7A84143D3B3,CDB3EC3814B768D2,3B21A8E757F796A9,000025B9551D2389,BB469B5861073C96,6722360733A125FD,C02381892149182F,076F1975869CF616,5456F88E9DDA5EE4,18B19603BCE83A25,FADAFC25FF66B14F,5586AD11671EFBD7,35D656FE4ED779FC,38AAE096B9EFF952,7413E1EF1A207DF5,00002C9D374CED01,0AD31ECDC4972954,976B787435371EB3,EAB6C6D256D9586E,804CE1FDCE486D61,A530F33653C5DA06,8FA7BB1BAD34B709,0C394B148E74C8A3,BF390A01DBB0133F,0C14DCC8E4B4B775,5C864BA7D72F37EA,2516048D42536B69,000041BA8563D6C0,5D609EDAED633B9A,BF9B6A6B05592DEB,610ED89A598D51FA,883F653DEE898F14,E74E252FF264B158,CE8B1F20FDC6D942,ED1550FBD580691D,DDB96B3E2964DBA4,40E17F6C1D4F2D3B,20D3870E73F41FBC,16233A16A5C8E6D1,000029A13426FF18,A555CAEED7BD41EB,2B0C32242AC430CD,B0D3F885AC58C279,AB9F7C4022653E38,B2F57E0C7F087C2C,40363995E2B135AB,F78BF47AA4FCD3F3,838D1D0EA65D6A28,F072F61FB8FF9B5E,495A8D099ED4BDBB,407DD2B86418BDF3,0000528063E793D9,2E3854D9804E9088,60038A00E3E7A157,58EC8F18FE12E5EB,D3C070C7B4CBB813,6592605D139F704D,11207CE99560FFF8,B6650F80C3B3FD94,9965E2C75775E515,517F194CA1192C54,98F3C2FD523EA6F0,9F8819672E9A8197,00005570FC280E1C,B62487A82C289079,F9FBF1064C8E264D,8A67ADB6A41FE5A3,BCB45F01C33998D9,24513BAC31ECF5BA,E0E70594ED3B74F2,2A62C1B478F1CC1D,87EF4AE7CBF0BC8A,1FA62CA091BF979F,1331B8FCF16B0A2F,1039D4F91E08C8D2,0000238E8A945DDD,C49FAA7E64B782E2,80576B1E7D36D3CA,48F92016A7C6206E,36A3589813405F15,E8FB5B2251E6E224,9B3C754171B0EC91,589F06A6671A96A0,D68592408CCCF72F,01FCE5FDA8E0BA20,CADEF6B09D3358E6,885D070918BB2249,000002B99DCD289D,41FE265EC79435BE,C0635CAA30D6C942,E435FC3DEE6E7A97,2D489B63500FC375,6DDDCB7A36DE5098,81CEA013DB4A3EC6,4D4D81AF4752C069,115E946EEF1C6B14,B9B11C4B12E7AF58,12B8A32A230D61B9,E70CD36F47938E9A,000000E755B666E3,388270C7CFC2D9A5,D5DEA28826A10ED1,11B8425F9EE8B81D,253606EE73E8AB5B,675AE173463A722C,367FDAFB532DB10B,E0D388301095EE43,ED76D012116C34AD,1F301431CC99D450,94F5075A82C30832,E1FA9C20B9BFDF8E,00002CDDDFF187BE,DD7D6FFEC88797F5,BA529245C0F18887,35C20854E7B0227B,063FF685BB7D4037,9A014B1D59FC9CB5,0EF755D5337EA933,4F09E7A03A3E96D2,5124BFA3A7B34D4F,EB138A2788483D48,1836D2CCFC7759F3,60414AD68012FA61,00000F54B8370705,D05A91991B223F30,0C21FBA343453733,D3F4693251948953,324265DC1A2BA688,4942E92C12EA3489,7B841CA0D012E5B8,4D8BCBABD0A8F4AD,29843DA9DFA8B49B,68E5B3F881996F5F,4ED0DFB03968B72F,8EEBD6947CA9088D,00002D1D007E4A92,4A369AF40E647205,215924F2C8C49232,FE063DA885B10255,AD5D203D3C131E6D,09D9F2EB6D1ED704,B8DC81AAB533D4D2,8FD635CD9F5679EE,30A3C0A34FB6301F,B7E4F8C2CFAFB2D7,9C0A57D3DFE4500D,69230AC5D7EF6D64,00004346A85D33C7,128C8ADE0768D1CA,AF16AEBFFAB143D5,77BE158C6625169B,373D1F4198561408,C838577782767AE9,0DD8CC7938022913,3F4E2704518CBC37,6F369FCF923CC10C,921B432DD2ED06D7,AA29635C2D1906BA,C6F7C4D0D98194C4,0000273DC0199BE5,9CE021F16CC161D8,030DF406FFA0398A,C741991CDB6FFE79,DF980538656758B2,937F3AF0B2DCDAA5,64F1A6E91293BBDC,5CB39A0CE0742C3A,7B8DBCBD01338029,BDD4F52A6F1C05E7,ADCD13A112FE1AE9,ECBC787FD3CBD73E,000067B872A9EA96,61824C5F33B66C68,BE4893D9CB189D88,57805C69812461D8,D3179663AFFDAAAD,33D2283B83E1EC8B,75508A64D463E2CB,0CCF85F5A0278EB8,028EA0D340EDFE85,1DAB679C5C39356B,20151A837AADEB06,7FAC078669685A64,00003E169A7D7B76,31F8B178A18D61D7,1D7BE747C1935CCF,8FC9104C38A70516,E01C161F64C84B2A,37C9422109D17622,0A1C9F9C48B71994,D2B574D3C3C51C9A,A039DFECA9261786,5AB7CB4D2B57B021,4859750478D8EF5B,9B3F39CBAEC9824A,00000D85DAD87F15,CE3149CFAD47DF43,DA0B7FD60B77D2D3,6523B7521FB75DF9,C5A2112CAC1CE479,254B0C580B2BF812,38E66D67B8826C7B,06D1634CF6970268,8E1B26BADF451C56,8AAAA5EED083DB74,2B783BEC18FE782D,3D1B5D45DE05A6CD,00000EB904E2B26D,C71098AF8F7ACE8E,89E9F3762FE31EBE,F1E2A238D13321E6,4EFFD2CCE7614801,8EFA6BCABFDE9465,59A2978D6EAC037C,4F75A42063221A8F,3B1B78778E8C196A,D7055FD7A9A9FBAF,CD1B55B72971BB52,E4FF8BE902DC5421,000055BB33E58798,AC76514BACC97AAB,A6AE979008FF0C4C,F6E3BBC91032497E,75BD1DB8E52FBC4D,40CEC5390714BADB,D9442446E9360EAA,3AD5D3830ED4B85B,66F9FDC0B8C7007A,2F77AD7B4CAB487C,159D9FB6EE995442,A58F7270B4733D81,00006038FB64D31A,E17AF7CDBD60BDB5,1D5066258BD1D497,0B93973487BA7EC6,1E615AE97F4B802E,B113A13172B76196,FD1AA72AFBC5CEF4,7E5F8783F799E5E7,76C02D2DF729D0E6,7A046E54763B97E7,748B95EC90D92B19,2913C81A4B9CAEB1,000016A54FB5B3AF,E270BEC983DBFC72,825F86F109C12D24,476B8E0910BEE833,1305398D4C7730D8,838881AB4621D37C,63711D92B363284B,AFDD4DCFD2CABAD7,2E4BCB6E55EF2EFF,868F81246568120C,D8111615DF8F23B0,8C39D3908531A8B9,0000527001F81BF1,2D2D0141F5E64545,BC613669CAEA25BC,7532A5285A951984,A347B3EEF0D6E946,B38D21AA613E6DA2,7B8538F719535F56,3FF1118BF103AADD,6C0B24AEF067E834,C953A4C440B2905C,C745C0F0FE3F08FA,E3FA411D033598F1,0000403963306C7E,5291C322238DDFC0,6349D354EEEAA8DC,760ABC1104269CE6,7DEF75905D931E5F,AD469E7EDE65F312,FEF390860A9F5CB5,C93DB58FA1A674D3,9F02867882120A69,F35D3D8BAF6E81A5,FE35D806A4584FF5,458B80AE9646CAC6,00004C3ECDF1D3F6,7228367A29AC0447,9658145880CE6D46,7FDA7C9626589799,3F46136081A36CFB,49EB96BBA345B717,B402C3D6E3D217AB,5F644A9DE2DC4269,A891248E6CAD396E,37CC696FFE294453,ED987000AD580BF4,2DD5EC62A1C3783D,00001CACC468FFEC,6E421F05C958DD5D,8D53B3D0CB8541D7,9BB202FBA88ADE31,B0ECC94DCE4C426F,24875E5183F1F5CC,BAE79D5DBCC63249,090C46150CB8070E,D23115F81ADAD4BB,3BB77EBC7B76A414,4217FE38B4D82165,6C6F6EA0A64C2100,00005A542CB1E699,A13419C1701383CA,00CBC079F47A5CB0,C29CD272EEA7D6E0,ABB403358E2FDF78,A456AA5FBD5897FF,4E11809ABA6A92DE,8E44815E31529BC5,17738235D5FB574B,8F382D4ADFC96C95,735B12BD94662D42,BD6ADE0121B3E3D1,00002A9A91276377,79686579D10DFC56,7029C4231F4D10C0,9FBE20F1F1C022F5,80819A08538B0D05,C3E8254138714D7E,425A45D3BDCB3A56,F12F76E50170F1E7,0AB206FEC02E0B23,28966AFA8A9D58B1,DB988E9DAEFF0B8C,70D7A727C4932F2D,00005581337AE4CE,91A5E06CD85B5204,6EC0A6A396EA3482,86F6C26A53609ACE,F615BBBABD4F8EDE,08AB75029396AAAD,6C6B1B3761C3B539,2ECED4CEC111117E,46E616D95521416C,4671B9F208673F00,B0855396B0276D56,EE39E5B67DDC43EB,000035F7B23A5A19,5EE9EDC88F912C69,3D70FCB3AC708850,CD7547947C4B4991,A072B70545B86140,1132FB00D15C0D4C,0727AAD2D7A08ABF,9EB4F5D3009144B3,04483AAD311E6467,EFFBCDAB4A6FDA07,EC0CB1662B78CEBA,8FD92A0F21A5316A,000054D91DCE3574,6549BBB3EECD07E6,D833A98AA6544A69,B7554677332181EA,F2652DAFA30E8C53,4CAB824D86106774,254AB5C54235056E,04D4AB7A09E96F74,906EB44F04B9778D,4BC8EF8603068CD6,AF874264F7ECA4CE,24045EAEE90B9D38,00004D9A9B080909,948CC25B9540B8DA,345673ECAEF3A53A,031758B2F0DDFC57,C262AFB7B93A1AFB,BD2F3FD4D4D313E9,5CD7015663B7678D,15E5EF79162C2D28,1EE9EF47228A9DB5,369C9E23DBAC50CF,9F37EAA2301E2D9A,59E9EB2C7ACEA96A,0000695376AB9D37,E62E4F1D9BAC63FF,38FA56C67D8E4FED,7041137091E83A1A,27909F15F7C78838,9FC4DBD02E482434,59F5D0B8AD42DCF6,D38D71B25A53D98C,69A81950FA36F81C,AE21E6F68F75F2E8,5808A730970365C9,AA0E4E52D60EFFB5,000003AB2B930ADA,E7431CDADBEDA7E7,FB8BB7900D512C9A,158139467716C750,97F519D1ED3CACBE,A383CB0D36E6D5C4,851BD44B0F74C20C,CA259437C68E2462,8EEF9649D7936347,2C47D6662941272E,E32433E5A3C02966,9B5E4F313610FFFD,00003CD619975AF2,A0A1EE827DF62E12,1CEA1D5192ADB9D7,2EE0D37D6052479C,E4185E0E2829D52F,910C6AF44BBD3F9B,DAFEFCF859ABEF54,3A6A5B10FA57410C,14679601760071DC,BE088A989AF1CDE4,70CB7D51379135C9,EE63EEF62701BBDD,00005E7637B54722,99EA2DA555512B38,D8A303419488BF6E,732A1812F1D71167,1B70695DFF6A3EB8,62100B18EDDE3F42,062F318ECBFB800D,BA4FE35DE106C405,E59D4257ED36DA41,397A0D2B31F167F0,FF42400C01711D21,437CEA5D71B2E984,00004DA4B5D5179A,BA2D2FF722C5E483,4822BE4AA2617F1E,D77C86B64269870C,0141F00EB4370071,02CCA8D8C3C5CB2F,917C865F02603FF4,156AFE4DCF464719,778BD97434CA2D67,C6941C11E20B360C,523B3C5A99AA1653,AB3F38C3BABF4745,00002ADEEADC848A,CE09DCBA60420593,6CFF5C101E94B12F,95EA1CC322411CFA,E2E4953C64F06DAF,0DB4EE783FEF750B,70885FC758992848,F1071C400A653931,456E1778043F6295,313130C8ADCCDEB7,B72CD196B2832AE6,0D3E373100F26305,00000B36B2C90BD9,334966A8435A363D,DE48CAD781C7F2E9,CC2E4962D2CF6975,97746C5C72A74F61,E1B1DEAF5A1B0BC2,0F9CEBA1FC19DBF4,AC3528D2213FFF91,803FE05738EBB781,403DFE10D190F406,5ABE84E90BC0524E,DF211CA8F24DB84C,00002C1E434E5E92,33AABF881808E66D,F602424795B79CAA,7BCBE1A0A08A8102,78622C98653C2B32,6FCD60325ADF4DA5,A513D3CFB182C981,2FED635E8D58B978,E10A8263466F021E,772F186355B913D2,53A5218EFA4FB16C,17DDE2B9FC153929,000042B55A87BE98,A78FA71410D50B55,28218FF3A36A0E05,111D71CAE5BD5607,5B18BA79F4E9E233,D71190C6435E0F43,8BC8B32C13F2A57F,3091ADCC8B50D71C,671F91E7619FEC33,90D22E27933B9175,E29EFCC839A5DD9F,00C67CE4B5EE9B51,000058C8A12AB466,6E8C7289354EFFFD,3CC55ACD14029C6A,03F436F4A81BD8E8,3EA4A89F045B6E9A,98DE7CE49BB984FB,CF6BE32F2DC5FCBA,AE8DE18DD2747172,EDD997429B9A2666,5B545D2AF9B88E27,133EBD6DAB37399B,10870C6824D97A58,00002EECE9CA1AEE,726A333A134677C0,442196C98458E46C,612A1101D93A47AC,93EE3C31F2BB08B0,E27B9E1EA3D824E4,4296D2B62FB7672B,558CBF34E258F653,CFA92E90A4C61167,6717C2F2CC53F6ED,73BF44F348EF5CE2,92729096C8951C0A,000048BBFA4D3619,CEDF3CE39FBE6E33,62ADF03B536A7259,C5734733C8CB6A6B,7D2C0E6385354FF9,4ECB458B97A8E1C0,4C08EEB8E78B02DA,6CCF63BD683A8386,E5F416AC0B6BDAA0,3FA1A86C2D57A660,5B45A31F351F090A,9AD4116D2F5E95C4,0000512F7D187AB8,16D6DB75EF0A0864,710F688695C14295,799D5D7FD6BDA967,16E47C517ABBDE6F,0DACA475B22A2673,7450CC5668D516CA,51821188E3D1BCBF,333180ADB53FE6F5,4AE79AB5BF4BE401,DBBACCE26D13AF94,D54163185EC25BCA,00004AF9D37130C8,8E63B9316BECDD5F,AE17DDB0C9BA5ABA,5F3D1004637A7665,9C875227E27FC63F,581758E70297EFA2,FF88BF61E54864DF,986B14971F9C4583,8D9FC86F3BE92671,352B4E543B48222F,1C1150A0FBC7EB12,CF3922710806C9D5,00000AA0BBB44D02,4C68D7B8A5189037,27FA34ED3B04BF9B,77B54DFD7182B97A,B1EF16BE88187775,0B294E01656F3CDE,3E070C13A76E0848,ADDF4716638E677D,5214B4955B9EBF80,D34555EECBF6247F,BC09FEAD7FE07676,09F82223C1F29653,00002C790B0A75F6,3AD82C3E7C306F19,8E8DDFF093C19AE4,11876031C428850F,69A054991231A6A7,BD5AC23C36321D97,07114C913BBB7D8B,7000EABB5F0ECCDF,B34F47DD58C0C289,211FEFFD9560BD92,C3A89FCEBCE35E01,444F77E9354F4469,00000565274928A9,C5086D01135A7852,647E3DA43A619C8E,34B59CEE5B7804EB,090E6ADC6B61B09B,2401876B90B99BB1,EB7A5BE7544427FD,427CDE489D59ED60,4996AF030D6F7389,242679FCDC825350,30F9B5FEAE6C4C52,795E2F908BBB5504,000044F9728B9D79,595B5677BAEE97BC,1DCE07B32234A2A2,F8A3E8C036D26E88,5C971C9C5591BE85,C7B7A8784A28EDDC,F99CE5D063FDAB72,6A4D3EF910FEEC94,322BBACDF3999DCB,AC7E7D7A1B5DA8E8,4C62040F166AB1F0,343796EBEA36229F,000057DD9D2ADD2B,3546C5847A628B20,53E1B5C396A85AED,E519491877F58446,8677CD6970729BB2,6135C4EEEB65D2C0,981CC5908D8A8544,BFD79C91323334DE,0B21ACFAF370FFCC,30620934E6AE3CB5,69E0D5136BA0A1FB,E560DE2DC26C2DE4,00005C6A31865CAB,B4C412D1D262B21B,67B48FE2B3586CEC,53725DF8E38E7BF1,C8EA80A346522E73,B9741B3AD615E5A8,3038A9B00BA098E9,AF978B9AD0679CBF,E7F4D5C97A2C87EB,E49FDCD3EA52F0B5,47526450B3DE2E65,331207E99BB69605,000035FE3D884D9A,AE9FDFB556CAD3DE,2F550081827905DA,A270388AC8F52868,A2AA2C73056820AD,8935457212D4036E,97908048545B3879,B8513BEE87ADA82E,6DAD48AF613B8209,ED434AD26AD29EA9,3EE8ACF0324B514C,F525A3DFB11572BF,000020124D733F7E,CBE97D6C999B378E,2D3AEA4DFA9DD734,9E149B5E105EB327,6E4B1C0BC2438211,35D496AD0A7ABFD9,8BA33FF82F4B0226,3D2453F035754052,1A29152381E03957,CDD3AFBF8B317391,3C2BD15B7B034D54,835703AD7A2418BB,00000BD0579FC102,6211F6C8CA0C5929,EF912FD71D1CCA69,0120DC07F2766E8A,598D559228EF37E4,95C13C946C1CA7F1,F939E727FAF9974B,6877DF747C1D0096,44552A87299921EB,AB739BACE64D15ED,9C2A86D61E211CFD,C45789B90131DEC9,0000399ADF487251,248369F23817D096,ED30FA10D596D4D3,14E60BA05CD92286,BEF3A2BF2695E098,C25E0077D70813D6,5DFEDE5CC3B91CB8,5D26F1385990C8E3,AE5866B7C9BF03BF,6981F697A30B8023,CD4AC4A0FEB71F30,45E3C04E2F82806B,00001B12E665A348,87883022377910D7,0E969B0B3693EFF9,183C6EA69A42111C,F0B6940BEE090B08,B084AF5800849433,47BFDF46DC05D4D7,B64342425658A418,6E376044EEC9442F,04A0FF84C9A656A5,4ADD4DDAA496E4D7,1AF9C96CF83F7591,000023BEAEF0D337,1E963EB60923B42F,C098B3A037521B85,B6D90D712F7403EF,1AF76DFC7DE0F5C7,4F70D36F8D4719D5,150F7B679E33B076,27551AA13C3DDADF,5C0F658277CE44A1,4B9F765C2A115E7F,7B2B598390071EAC,FC7B8AEC8B11BA54,0000348E152E8075,1CFFDA2088FEF006,4A557C315A18AE28,FECCE30697B2647A,148B754D2C6EFABA,77806FB303DDEB6D,4D8C15C9BE8574B4,42DBBFDE6B00A964,6394B8F819B07C5D,2738998758D63ACA,F2FC558ABD5AE59B,1F6B1299B24D385E,00000F15CB5AD7EB,32A1E4D1E7FAB62F,A547E56EB408BC32,93C2D3A30979CCEA,E8E19FDC1118AF7C,B19FFF255F027542,58476E316F7EFFD6,8858B0C32162CF86,3E68EDE8C1C168E1,91E687880FB63851,DB6DFE9D41F3FB7B,D74135DED1401C26,000064F1EDF6603F,61360D2524054F3F,516E2994E6E26513,8415D3322DC70625,6DFEACEFEE0CB886,5291D660D6C8F1AF,54B174C3A22696B9,66DCFF772B97E758,62771380FC1BDE8F,2500BFA3D2662539,9FB8CEB5DDD43F0C,4C6BD9FE372E28C9,00004BF01030F0F6,34EE66A830D8309F,A21BC274CC03A897,1612A4A62A71151B,EBE76DADB7771C12,166128FD767F4CD1,675C69ADB626FDFD,C1051581DCF5AF1D,54017F03941117D8,426C0260B1035191,D03662B1B395336E,E3CB0649D93B28F8,00000015541DEE19,9F4964CF72315CD0,A5310660E8F50E11,EF80C0672AB510EC,3A122F80FFF42254,0FC1557292819546,79AB8CB74C004D4A,626C4C12203E74C8,A569CCB8852926B8,E591A197C6A6B15C,33C9CC6C3C960D8F,32FE18C8A51FD1A6,000000BE71B0ED8B,5A06F5114E58D5DD,B78CC4079E2DAFC7,D06B9D9FFB66DDAC,CE0F4E9B0F92AB1B,A6C485125386998E,6A37B78A678BA75F,0AE90D0F48B6D71B,6E0E9BEAC1F9256D,D59D162995213192,E55169898D50C0E1,A54DFFEF39C7EBAD,00000FCAA183611C,76533A910BDA11E5,AFB3FC57BCA01619,BA26978ED0C946CD,C6170729191F994B,0A3C14BA4FDC21A7,DC691C37ABAFF0BB,8A93AECEBFE7C646,D7500896474B6B76,C22BE0C0A9E57EA5,3A66149E42003EDA,03132167694F33BD,000010B8AF90B4DC,EC6BF2A8537AE138,BC992CF79E55C0CA,04E3FBD3DC1688C1,053BC1EC8586FA32,63C232E02D87EBBD,553B06E012CDD74D,73B944B994252EBF,EAA686FE63A037F8,722E19F0467AB286,B66EC7F46BB2F9D2,7157C5F016651764,00004FA142353BE5,C068522434659682,24EC44EF15166969,6D9E733438F50EF5,80800C61134E5372,5D0F9816C23C0604,C53F6C92891FB313,F5CACBF9BFC2118E,8F0B4CED412E1586,1D713A09E50AFF4F,C59A7E78BB8CBB35,1EA6A37B1884F3B5,00004006085D99ED,C415554607E4FD31,12A6C8C22DC5EEEF,6D51DF8F33864FAB,45C94DE5DD7412A5,207E12351E6567B9,D11A8CBF161746DB,0960D7EF9668A785,1D7C1697570397EC,EBD1C3D83D4B0478,FC0AB9270E118460,58CE376E54030DCE,00000D29A5CEFC72,EC49A5C98AEC2922,47EE0FEC01106D56,BFF38F9CEE8F84D5,95625A9DFF1B4DFF,3123332B4D4274A5,FD1985245FCB6831,1B48EA584577BA4D,F693A86577EECEA9,B5A8EF70FD70C173,5C91F0184B44B811,0B8D7BC70F2A8ED6,0000311BE59664E9,2C83565731B71096,42D49BAC7F1E7F74,4ACE00BB05055834,66CFC3F7119B27F7,2FFD70F9458460CB,713EED2AC810B8FB,46E1D06F6E72F2E0,7D7A7C13FA56A0D2,D670045D6166CF84,5D5A95253913CE10,8645E6E85B1CCA7F,0000552EF27B3DBE,05C60BFDD91DE268,D888B11B0435E6D3,1EBB3F20BB7A539C,30034F7F3057AFD2,6D460578E82AC6C6,C9A31F921A2DB070,E3B299B0D9F44837,37C256B8E2F070ED,806A736BEE4C1955,FEFC71B0A5D2C2AB,37D1DC72407764AF,00006D169B489998,BB50B464DD838233,04FDD04FE471C6FD,2558EFCDAFF94143,C083751EB795855B,DF3A5E44A1CE145A,EA8630FDE9029CB1,B43154BD5A521DFA,05ACBFBB625A1EBF,067D834DB19B9EBD,AD3574D29D25BA5A,1C4004C8CACCA8D1,000051F9B8574040,AF2CA64813323B9D,1F0453823B5CB4F5,5AA1B75BD4FB402B,A1E41043CC9E0FA4,553B9FD70D5CAC97,BB83EDD758764AC7,E193AA876C4C6B4E,5FFDBFB6764018C2,AC0D472E7F1163D1,6A4BB443EB1964F3,FE9E8864622A8898,00004A6764B0254F,ACB8950DEFCF523B,23018FAB80ABB913,06668616340E5CEF,4C88DD29D3350004,72FB8A67CA03AA98,8D4CD9E32173ACC1,A3062AA9D3B4DD27,16ABCDC5D075D9BE,6E6B51C72FB96DBB,8DE0B7BF1C215929,EEB53E5A25F3088A,00001061D3040E0F,C46FE748087BE745,A135B768EC879485,EE16B238D74D4D7E,FCA3C13EEE0CD7FB,90D73BC83C8BDF41,05919E3883D05086,9055E3E7DBC9DE0A,C28A4A57C4779945,8B1DFB3F06478076,DF58AB990EA990CC,1E36C5D964F38C90,00005B377F2DB85B,BA69A3EE5D65CBEB,2B6DDDABD099F332,5722F2AB493B141C,EECC20BEE4140AB0,8FA8F4E0E093F5CC,A92897D531B6BF62,20828207CC843F27,6387928F312115ED,F007634129C95DA4,FD2BE041A44FB3C4,6AFDC616C480C872,000064F4BA9008A5,5384D00E2512D352,66F0C3896AC853DC,7F8BFC6477C6C633,2C7E248535FA4287,65621F0ED1EB31CB,5B071DBD80870F0C,3A8B1D68CB0117F7,EDD33AC44E1433A6,A99ACB65EC4EEAC2,63DD96DD134D9EFD,2A495278B54911B2,00004FF1259C531E,1F3406FC65DD27CC,E9DB09D53E0E7784,94E83B9D6AF656DC,69E9DEF9E37B10E6,76EFF209771700A3,ED4C3E42BFEDB271,AC78EF172BA5F7C8,6D8089449F50036D,82E43CFE7CD87D27,62ECC87BB5FCC1AD,47ADA60BDA157827,0000437EA9905C63,582FB1E098220354,7F47DBC287A04092,5F974B65AF3B9321,E97C3696FE937665,AB2DCCC3637019DA,5370ABB73B2BE941,E661C36EE3A8311E,EA8D05F6E35B0AF4,42800093023680ED,8361C56C0AA59EB4,DBBB315BFA69E1F2,00004A9A921F2765,E66AD556FC795FAC,610BD88836E75159,BF45E691D590CF0A,34F618AEA78703AB,67ED11F0B29DC071,C2E4450DBBE65A38,A31FA8CF947CCCBC,BEC86EE5B9981212,E30BC44E1BB8DC1A,294CE1C748E42335,8BEFC04F3055D7BA,00001A4BE94E5AD4,DFC3EC4F2932198A,ADE2ADB10425AC4E,93FBB99E5823DED1,23F37341BC065509,5FC71160EDF4DECB,8D8D596D1ABE0F25,C4B864D7BDEE4F9E,0A6EBCA4B39503E2,332BCE1B20CB570F,CE7CFD58E5F68562,3AF9320E35851869,00005584A650778B,0DC19F7A3E9AF4EE,195E6DACE99337F8,71FC339A063A70F3,AE42F9473DF85354,35EBCCFDDE50A984,8357AE9FDCAAA319,B323273802CE127C,BF2C8E0D2C653F67,21CCB7CFB6FA1B5B,51D2D8DF05AAA4F5,02E67C79956B81F9,0000071F86CBD894,DFB71FDB029E2A7F,5FA554F6E8D72532,99085918C344A30B,A8318E1A94191C87,608B182BC66FC99D,0F918A02E409AD55,67D6BCE6E33D6CF7,07D305681B90E860,CD7C0E5658E72949,B21E629E07A62BD0,44915627BF074895,00001A9AF5682788,F4D58B7D1207FCA5,C056BA6BEC402132,D39E70EE7BDBC665,35EBEF9DC08CBE46,597CF0E624704CE7,3725D8B5332D21E2,6079A76F991927A5,56EB45BA1DE1D039,EC3F36927550AE49,558893889A606CAC,5AAE1B45FDEFD4EB,000014AC56173CD2,251A1DC4DF61ACF7,AD28C90CD85B7729,6F6F95B01E7A8663,DDE70187B9F6CEF0,8EC2717C1F22A4D9,A54DDCD0942463F0,6DEFF83889C443D9,A4512BA911D782FE,7A412DC00B604DCE,44D022024DCA1324,35977953C2EFCA50,00005D932A0EE25A,BCD8C03DD11729C4,C1FBFCA5729D8B74,A8FEBE2047A83BF2,7032A0114CC266F0,86A05A15A8B686DC,CB041CD081805A51,40DC62A8006B06E5,3877DC25B42D1EA7,ED11EB0A09D903F5,D8D59327AB6C921F,3FDDC04FCF4477DF,000060D7658776C4,6AF638189A2BE496,069D33DFA3AB1E43,85BF2867CAB0DD4C,D2C884C937115AE1,595D460FC6E33A6A,72EFF53A42E0170A,2BBEB25ECF5C6E07,573DC8720801D0AD,365B83EBD85458D9,68ED1EF5C335A85F,EA6ED70830B5ECCA,00003386B5CAA7D1,1058485CDA588FAA,110D352CBE712696,2166FD4B76057430,6A61E087E23CE7B5,72F445E92673C918,807B1EF1C5673170,32149D47677B1961,ADB1726AD868B7AB,D11A6554A6E487F0,710D47C037330961,4708C61EB0A9C337,000046C2EF8428EC,52CE88125DA6DE16,722F96636DE7F564,B16E3AD077C97B20,A2DC3FB20DEFA3CB,8FC603D25CF7552C,4E5556F0E9CA82A9,4E022A33B7E3E4F7,D24225F3FF18C0CA,B8326A3CC214D40E,9D0DEB01319801B2,8216B95031ACC692,00004412D506CEE0,5963058A13093F5D,5185DF72FDE9DA48,0332AD8B398B3B83,4DCD65B75A7D1932,31CCAE6B8572248E,9C908263A9D9ED5B,39842BC0DC2D8006,0A5E257BF56E538F,F249B0201BDEEF8F,F0CBB96C0776E67D,CFD63A0571BA8F9D,00001661E51353B1,00EF104BE9D6099B,2A1D866715176ED3,A52F1E8F62731C5D,BD805E2583F4FF70,B02868C9489D0096,39530030888BAF3F,B02D259DD4BF5D23,2D674A8F51067165,45C55802AFBA0D10,86BD713CBED62DA2,CCFB48B171AE5889,00005E8BA7751D80,EE9C345CA5CEE57C,B86C988923D31A9E,80C9E24558C9050B,5B6198542FB29465,29018822D7BBF6CF,84727DF60A2F39A5,07EB604BD09BE25E,20E66A510991740D,59711EC69EBE1266,9B2FC3EEF00E7126,2BF586E8C83F93B7,000054B0EB74B4EC,4D751E6849583DCA,2590A1F017204ACC,AD830181A8994F19,07904D38BCB9432D,88D222CC8A7985DE,C77E17042F79BAA8,3D102D4FDFFD1057,61A5E82B95F5648B,5605966261571705,A7051FFB64BF244A,1963F773314D900A,000021CCACE15EE8,6DD9491B672AFF91,96B961564FDA4987,EF2A639B8545FFC5,7F6F919BBEFE761E,7CDF3F56EC09BBEC,5BC66F25C6B63004,DD4C099E846CAF2F,36B218EDFAC51ED9,4BC287A981486E80,CC2479D3C355D060,573F966D6EEAF6B6,000023DDBD65A5B3,9B45C6E3F843D42C,DD93A573B1A6A368,409397B6C8995C6E,B204699C033BD18D,1194D99609F3BCAD,19399268701B9D62,FAB0C6C23C4B730E,87EEB446A6DE4C85,789DF923CF76AD1A,25A30149E683CA05,1A3BE9389AAAFCBA,00003FBD680C32A2,2A37FD2EE8E3309F,6E27C9948F4BC520,FA6F359CE17E5FC4,6106F4F189AD1464,EF0014416ED35F42,3118F77BE459AAFC,524DAEF5961598ED,AC32925CE9969D5B,9F74E559E2F5BAA1,43B851A20127DF92,E1900A010F13E744,00002AC5B1D8952A,6210922E5FB7C3C6,CB1048682A1322A2,DA7A5635842B7AF1,B992C560751947BC,8BD507F0CE5C8492,FDC3AFB3449219C5,83C4618DB4F2EA9C,ECE1354DE2DB28AF,7E373A301AF73123,97F0BAEA805D9491,40D1D0CC11015554,000021A282F1EF5D,743D6A08F3F6A59F,0226F559F199CB7B,F666450CDF313E1D,7A37B910FF3857A3,40A431A67731C79C,83699B2718E8EF77,1B8983505D1AE322,9820774B463FA6A0,AC1DF5E6EBD9248D,A49A80600F150885,CE80312D059581C3,00001704755B5C5E,37D2F9E1A882E2B3,0F75569F9D31789D,8FA3CC242B137052,9001C6FAF4BC64B9,D5971EA0EEAD654E,F1AA6142B0DF2D15,BE729DA10AFEDBFA,702F043DED490C72,87831F00233F64C2,2035FB4DF4D98C6B,4531D98EF010621C,000050A9B943916E,37EE2052DF4E09BC,DC6777DE90E4C70D,62301C1949C43832,E302B3E5C6702C7B,1E22981F181069B0,00B375021AE9BEF2,961BA14B56BFCE8E,B8C1A59CD1374B42,036F5D8A452ACB8D,D89C3133B81C5993,B5E9D02C4002B0CF,00004D8BFE53EA70,0FDF3DB740DBCB95,E9F8E392753E2D98,8FD74535480ACFD3,4E89D22FC3246D81,16B19FD71B17A1D3,3AFEDF06088613BA,716FDC762B9830EB,AD30A3893FFC40D4,38D586B5CC22F384,B9E6BF134B165C47,B02BB58B9568622A,00004EC37BFE75C4,41EF8D24D085953D,D71D4A7FA8A01335,BDE3B0E6DF4169BC,08CF5A8E0F826FB6,0AFE836FF14F66B0,CC128EDE252AE5B2,5895224BA9B84927,B8954EDB6EE06CCF,77EF70EB468CD565,B98D1E5DBA43C0DD,C6FE11B29E3E40AF,000046638E4FA64C,25F9F2EF4739CE21,48D3E0488195E8E2,9A8F623AC7B00E14,639A597668D39DB6,0E73DB67303B418C,ECB0775CB5310836,3D4B6FE7D68A38FE,074EDD6EC2B4C018,2C4BAA364DD1DE4B,A35855EEA305A1F6,B4A20B2E2602A994,00000320766EA9FD,07691F6CFF2B2CEB,CE1F725179CAA532,1334139B8266508E,A958100FCAEA3EE2,DF9B5B691C0D0396,5621C98CE05A3240,EC8A8DD052F58BF3,336E31EF8D3C0A91,1217EA936FE8F0E8,F99F22C6F037848F,0BD419BCBAA3EBB2,00000F75CD044C44,93E4E00EE17BFD35,8561D2ABAEFD00B1,B15FB0826FB805F1,B869C15D9BD78A15,ADBDF507F08FBD3A,3E23C165C4555F2A,2C361F473077F8D7,CF4C11CC824B5BAF,9EE7F8C334D4235E,7CCDE4E0F0151030,0FF17EFCDC55C68B,00003CAF45CD8F6C,BF98F5EC94AD251F,34F6204C9004A1C4,7D6704B5CBC2BA97,49D9EB4F3D922DB4,6BE1E4323767E326,BE52273AD234AAE6,BB9FE059F3EB7C29,B92D234E11F21D42,154DBD3F91D20257,101A4068484E2081,06E7F1D40015FFD6,00005F9D45563FA4,21DD7F52FCD2B1CA,A98361C4B8A793FF,E1A7C4533C8AB345,DABF554008D193F7,9E49E14ABB5547FC,BBD4E4CEA490B491,1EADF9305FB63690,CE3667E4E70C085F,802D3C5359E0268E,4582414A3C9C76EC,E5CEFFDA994BC9CB,0000268969CC3099,A35B2295AA9ECB6B,176F32CE626F10AB,1A346C07E25DAE13,16108F3A3B0AE118,FA486AAAEAE1C8D8,84EFA501D945233E,C4A47BA2DBC7D99B,2A76553C81382D5D,298AC7505FDC12F0,E164CF49B14A061C,7ABC99137BFDB29B,00000E8844E56348,F30765E5229546ED,22037CCDC0C6F76D,72D314865EE127DA,C33DEF450C91E3BA,F1A21178ADA71D1E,64E736A7F1C30953,4911A1D89BA3E7C4,880FE9491D7DC6B5,C13DE2A16BED01EA,82DB6649CAC4A637,C4AB076842B14A93,00006B357C030968,B0DD7D670E112F19,901EC57CD8A7305D,EB5C6A251B7D58FA,D19FE3F8279A1552,A701A1F7EECC225E,F1B3F87554FB86A4,E88083DB6B93E6DB,FEABE93AE4AE65BD,5D45736744CEE56D,D3823092118CFB57,A28D73F206D94171,00001CF9B7332334,DE103F1A2C247857,E40CCE6D05A9112B,A61ED3D04EB57075,C9B5501677F1B2E1,8DD6ABAA96381F6A,70CB7F35C71ADDDD,0002F2D7D609B2F0,B3078DC51C509452,20759C4537092F0D,6CC425B941F430F5,DEEDA49B7AA83EE3,0000054D5181358F,75079E1EBAD33C9B,82F35B2E1D7C812D,92D5D6AA85E64044,AE61F009FC0E4DA4,9930974D30B8CB50,19FBC0DD4A0004F9,8ACC568E599621D9,46F1F45633F40CC7,68B39BA9FB789137,C399756BEB742775,5D76F8F180A2BD38,0000245839A45A7A,42101B2847ABBD7A,32320630E43E913D,A45C8A3E721E472F,0DDB8EC223A531B7,9870A21B83C4C8D1,3579263F73DDF87D,A5B1EF3071C3BF06,4286DFDEAFA7B49C,6C3E17C3D8334133,171472BC3D2B1AE0,0A263BB0732FEC0C,0000482ACE46434E,899DB9A668EC7460,1A304654B6803614,DADF6E8F75E8F987,0CFE94A6DADCE060,326821CD36672C2C,A2EC782EFE279E22,DC44D8F364A737EC,D546FB0C4D5E0F63,E85BCF3564AFEEE2,0B5C1607C5B0E6C5,2A429B14F05AA9AF,00006D283640F17F,C1AD95AFC69EB338,ECC2E00C76CFF4EB,8D14EE337DD258CF,56C2C16DB507FBE9,DA19E0AF155DAC90,5AC8DF97E81A7EB0,97E9CA2A2E1FE547,78BD932920EAE690,A199A230B5B6515C,762A44345CF0898A,B560E124DB1DD87C,00001F9CAFCABB99,FDB761B9853C2AE5,A1E2AAB4F13BD715,9519D3255E4A2222,878F2AB6AE72EBA6,E3B01183581CFFDB,826C429DFDAFD72F,B2CFFFF67398022A,B63049D0F3CE6F50,047223D5446F0BB1,805996AEA70CAD32,D097EFC980956C8A,00004C71DFC72ECF,DE1F1AD3B8BBD3F9,C5779963CA00E4DB,5B8F501CC206AB00,D0852DC782ABCBEA,17F3E59A82EA49AD,30F5BFACA483F58F,21E805212047124B,1AFDCB96AD7923C4,AAD3D573E6F7BF54,D4DEABE9C571FCD2,CB69D0D2D36B41F8,000037318A8D8EB4,661CE9DEFAB599F7,90F7029A1438979E,37DFCB7F93EAE325,4905C9280C3A3421,97AC8418639B5B7A,82FB59ED3DC66C1A,79CE75C220C26E61,B323523E303A8602,650AE0ED98FE13CF,FA2098C09A7F074A,55761289D3CC74CF,00005756FDAA9DFD,E52A26BF0FAF9CAD,EC6C5124663CE32E,E39B0207AD629302,0D83EECA7ABE3672,9087C9CD5CB4B645,CD03578BE8E96A01,F7C5130CEC140141,4657740814248405,11D629DB9BC0BD59,496C0A7208D67656,6DD95C0B937B14DE,00003E1160D5DED9,B3620B6AED5CD18A,706CF693EA228F91,24A8CCC46E6D8BFF,9659A205452B0952,8CC0B1E7578ED4C0,D4831E5AFC2D1314,DA9031493EBE0120,5367E89DF14CE6B1,A2F49D07EA127670,87E8F4F0ACB2CA5E,7FBCBFA42C6E7D38,00006CEE4C02BE6A,D2DB46CCA80920A9,7C323FB29D9E72E5,08C83CDF26513940,486A2CDB1EE72B4F,4A1551087D82DBF4,FF01F514C149BED4,66E0409594BFC855,192ACCC905931BB8,6543194765B16DB7,309D6F73F4E23AC3,F0EC1539108CB4BC,0000494788C38895,A294F799F510FFE4,C88A71398C28861F,2CB1D3C85E3181E8,AB22BE8D76230EE2,A2ACB354F5AA7F90,18DA03CAB0F617FC,6505283796F6D822,E8E21D17029FA5B1,DAE08439F9691997,593D41C00AECF6EE,7199B83656C98D4C,00002FFE358E7D08,9E76882A15982523,E733C60660B3FDCE,49C12117F250437A,7365CE62B4469F46,BD0331BA8934A378,7DA243B149711AF0,6BC42E197B6C2FAA,1429F2DA6BC0DEFC,066BB0DF83E948BE,3AD14687407A8F74,B943DDDD04B13685,00000E2CBAB4379D,476D103E390C195E,8FF1A5E00630CCE3,18D1EF14C2CEA250,DDB1B4655946F132,CBC2177FF261C8C6,EF400ACFF3071A2B,9DF9A9A6F126EEE6,F1874651C5D3132C,D35B3C2F579267E7,D4EE3B1062A9063B,DB22B9DCFD8C15C5,000020472E916769,CDA249B5CE856A5F,8050AF016B339930,405744C2E7558A88,B8EEA88DE9E38125,2E55977068C3304A,EBD4115615AD6FD6,94D7EA92627CCEBB,6F6EA3AB2B83F6BE,09A9581E22685D69,C11B7B7512C92C32,3E88ADEA9BD30422,000028FB028BD69F,FBF137ED9AC95684,D976975D1035DB6B,B73C98FDD5D4C39F,5BE76E7315160F9D,64AC96AF7CCFB700,F0516129D3B53D56,A0355DA917A0BF7B,D09152051CE2C396,C4AD102F48F37C1B,18478D280989FCB1,3121FB1F7FDC64D6,0000093E3A9D796C,EEC26CD51B321CF2,14E4F20409697AC4,F3E13968126ACF6F,5EA7DB76960B5266,953BCB125CDF46D2,35F0CF2CF6570994,53BC061F2E4137B4,D392844D33840D94,8D4E80F11C7894F9,8C7EC3ADECBEB07E,EDD073D97034A53B,000052FF01EAF5AA,D11EEF4E7D89D479,6A0857B77575C3DF,203BF3FE58083047,11F4207BA8C6FD3D,409D419056F79023,BDB8329E5D504B17,5ECCE6FFC81340A1,5934271258A8A6E4,D18EA193D0B8F616,D94A07D97A64E22B,5AFFD155C3FDB851,000011678A5FDECC,9641F2ED1D649DB2,26CC851DABA6BAB3,EC8F7B5CD455C5BD,CFAE4F8FA4A75761,E5A7F4078AD92DA3,5DB6540077BEED5D,47BA7D8CB1196134,53EAFE1C20F4C31F,ECA0128F7EE68A51,2A8B1446574C64B9,8B06F42E82095590,00004A9CE9736D5B,2D71888B8D9C1BC6,A0567C8ACA769145,08C1FF3D7D4705E4,19DA1E2FB601C120,A4802E7E653C1C19,841EC33A743EE21B,BDB2C129F664C689,6FBE780A3CB61750,AC92B755D1F20D05,D87E4EF6BAB799A4,B37C938D00EA16DD,0000076B7C4EFB79,F7CAE912D2E410AA,AF58F46A8F0BA384,4CC9922FA9577BA6,0C609AD9D654FA8C,01926F1A523747ED,595F17F0C825E2CA,61EA22FD536B09E4,BDBEDF1E53B63E75,B8CA197A80F9B6AE,D57ED8000A15F31B,72B0E29C2E0E7D81,00000563F063BCB4,C0260526D543F037,F0FC81A633FFC744,9CD6E87D18229CE8,769ADE9F1D5BF2B4,B9FBB472DD647A2C,F13CCC91C3093928,89C0AA14CB420E93,6B23ABEEF01FDEEA,F4239EF8EDB974B7,BCD0F82C2483C6B6,29C5DBD99ED2F1E9,00005F61D4BCCEA0,6C87886B847F9920,4A131A2118D1BBC4,001827E8A8AC09DE,897E6AC2D053055F,B2A45CF3978A2AC7,C185178C2BE8B834,4FD43D2909935462,F8DD19FE5975264C,2B07834EDF032574,442A6F369DFED244,E0F1EC1180BC0CAB,00001A4BE5729877,780A986ECC823105,3859E939C00821DE,27D2F427FE77BC39,A28AE7D55FD25E45,3F273C0128A4E7F8,A5109C8F5F5F6025,7A82282D50223962,A3390564A1486BEC,BD7F0752A93B96AB,1C46BEA1C2EB66CC,A81CBB6F5B1B5B8A,000036960C69648F,3AD795264BF9E672,97E37FA07943D05D,AD1BB32687868487,92A73489A3D36C96,9125D3D47E8EF93F,E39DDBCB93CAF0D1,8AF40B0F928119CE,3AF709603A305356,A5156975A695E767,59B825908A94625A,B46BE20F7A4BEF37,000036F612BCE38F,EE15749CD64BC595,18E693E56B7DA29D,EEE09E3DAB8B69C8,DB541659DB8B4774,147E5A1692A47D35,DE98B8D59963B023,2AA16B1BD9217260,C8554FB02E8FB3FD,1C949C550D4CEA6A,6C0F1C5BCCB8DA81,9DDF2CFFF0DABE78,000038600AF0D8E2,3CA359A623D07A73,1810C4941F84ABCF,A403C3724929D56F,AADFBE930DA04065,CA07DD04F81033F5,263409959F96993C,BDFB9E8B171A1E5C,F70A2E353C56DC7B,8BF1B0E3A4FB3CAD,50535435207D7AB4,0BD9311F5F23BE13,00003E2C221A2A84,B37DC0724481BEE8,A133656DEB7A9704,FCEEE22C2542E548,96101A4DF802E3C3,C25E377DE1B6FC31,18C2B9E6204165A4,0DFF20450E47B1E9,61B9CABB7445B321,C1E965A4A0567828,3B49411068822341,3EA4B2F542555319,00003D5DD45FB9E8,153510DD468C5A98,0893AE95A208FA26,A581E2BF291209FA,1F4EB32FD6310AD1,E917A7621923910C,607A993663947511,57CD02C6006B17AF,2F1DD4B8A951791F,16DA447771F12499,6400503677A1D614,BFE99951111372AB,0000400DA08F5537,4CC0D1AB408B5B06,60AFFB5A4F3D93D9,85B1EC81BB16DA89,290B8E45C2DE70FE,DDD2E4AA975A9AA0,5FAAB75AE39EE70E,ECE832C2EA7C45B9,C8C522C51B5F58FD,E37D33145889B2AD,9E6C759EEF262DCF,3014A45D6DD08A95,000043FAF8A561DA,BA62E07EA9200217,51283B0050E312DA,AE77F71955FF4F2F,1B7682991F9C21EC,1ADD553CE7EF292F,293EDCB00B508E0F,2C87FF5E50925253,A4A22735793D5270,50D126ABCCC8EE39,6EB61B7246C746C8,D9D08C7B7E80A194,000040856D6FEFCF,56F2F70F9D4681FC,863BE83107173E7C,621DF061C31B0DBC,6A7B701D80F40121,3703DFC8479FB803,B1B8310629CC04FB,E947943D4C5B166B,16454A0A0FC7EAB7,4C739953CEE95457,14ED06963DEF6C1B,D039C3364D7F504D,0000269F161E4F52,E29F0FE0D9E7E620,0E1527FB33B9507B,DCCCF82D27581F54,2EDADFB03C40E9C1,FA4490133B117394,1DAF5DD033A6D024,F2F44EA1AF43B52D,7D9B394F91C9CAAD,4C60328A35B79F82,7ECCEB6823F55480,D80D1BC902D37428,0000320ECB333C1F,69018A2868B8E2C0,C94248BCA2F6B142,BFAE6CF79761E592,02DDBD2DFFB14C3D,B968C81511614DA6,5F8D5E92683A6F1C,07587138755F7A2B,C8A8F737B250AD63,E240E8A40EDE5310,778E7391245D6785,5819282175EFCE7F,00006994015BCDE7,D7BBEDC3F63BC9A6,1648F235134DB7F9,0BC3F1E8999D10F5,66B08A586BC8B700,2CF7B1D5555CA2A6,5A59B82D4C36A452,6BE3F408EB334090,0F7A395051502933,B96A0E13F8320481,35DD40DBE6E9C4B5,0DDB19E45E946547,0000233193F88B38,B0136E6F1D65C377,C633F1DF52095933,44B2A5EB9055B9D4,770AFE0FF83CA7F0,6E3348870E7DFCA6,E11956872D670E34,92FA6F4DDC163544,1C8AA74CE80E3949,A2F6D607F011DC2A,F21AFC4843095BB8,7AD0E2B632E12B27,00003A689C175D2D,441328D5D326C0E2,3DFCCDDA8B30A3EE,CFEB2036441F8A6D,EA7682E9838A3052,9CAE8BD6FB87A2E7,5927CD9ED2BBF16A,DB109CCE1C073A11,B4BE166802E890A5,E0A2E61AC7DD043C,15DB177481BF701E,9179FB303338D4D8,00004AB3923FA08D,9C166BF31BEDD1CF,85017553ACAA0855,FCAFFA535A753365,7481C2FFA4EDCEED,15B33AA78AD998D2,AE01C5DBE4C0889E,701777914717E8ED,DFE9AC274DFB4013,D6B7535561661F2E,53F73EC039A316FD,0CFEAD915BD519EF,000049357F1DFD0F,FBB1C22980F900AB,3933ADC74DD1B821,9B00B9253C6DBB4C,43E16C0951F1C521,88EA65AE2CADFEF7,8DAB4EF40FB5B6B1,E692A5E6C32C5977,5859212B7A792248,C0B069F3899E03F5,98B4989F7EDBD5EF,6B898356C3041509,00004933635FEEBC,75EDEC3E33C877A3,7F2E9AEBFB9D0797,90619874F0486CF7,19D34BDE6B7F342D,BA4502C170020FE5,BD495A6C317CEBD7,AAA448FD2B4DA4EE,B2A8E718B1917FC7,82D6DD4E2F6FE3F9,5FCD7C0F1A2F1320,2179AB1968F861F8,00006378F3EE61E1,69BCBC0CD6CA1BB3,DD472056CDD71257,29B574990C3B3382,C1C29B4BF5F13FD2,79149A68EB78AF0D,088D87BADB2D5BCE,C535C1C3076EB6A1,DEDD8F4A018C2F0D,F0F3009B9B2DE4F0,3E6770546666594D,498271FD3D723D07,000056B738BDA80A,BFDF14FA0F96FBDA,3A31502BF4784537,AF014CED1033F06D,8E7F1B30D7DD350E,1E94F38BB04086D6,2BC4262A397F5849,0F45DC3586B8909D,103A8E8210568096,E46EF9D7949A5308,A43A1630DE4D5A90,5BBBF80F1565F052,00006CB7AE07CF61,E1A022D5C72F391A,105273BB711E4C1E,647556C934529640,D804BA6DAA9B89CA,5A31C28091598F46,B485AB40E6DD015E,E909D45322E54271,5E5574DE8717639F,C6C6C74FA9023D83,DFD55E22EC673578,59B09B8A1C24D051,00002311A3F4BBC1,BFFB5AE4F3D4BAAE,D975C729BF3C1B76,09B78E3781BB49B8,4352183306E095EA,5B946BD956DA3F69,61388C7C4020CEB8,86BB9B0649045B03,3E09C813EA25409C,DE7F6742D613EE9C,245F03E8BD6B9883,962E80F940E64511,0000479A5EE7B90A,B809EF6931AAA312,A94939CBE65CE59A,783C179789013CA2,AA70B4AC19C7E6B6,1E8225D85BB848EE,5EDA2BFC55F39AB7,C0C76649C0E9B563,5B83BD813B7BD81B,0C0D362DD33144F9,B9DCCA5A4238AF77,3A5056344EF167CB,0000654E9050A723,9FDD1BA8B1189452,24AFC36F10E7BE6D,2D38F197E5F66E0B,20F0960F171C2F11,1450F8E698B54617,64C62905055D9C6D,3D46616833A1AA4A,C8EF6F2862F9623C,AA4F64345E973D93,EF38A485C13A7B5B,5DBE840C5E5ABD5A,00001E2C15E8F139,911D3D6BE95461D7,F82BAAAD038A1542,464D7F9BABB3D742,D244A68C802D9F9F,386E99CBC592F848,84722D97916435A8,BADB2D79F18F0966,FE4342736359A014,DB415E41F74553C8,ACFE6DA779B329B4,727C5522300652D7,0000159654C84BA8,583D836695A16224,6D0B76FA403698E9,188D6AA65E6BC11A,50B2C4D13439B78C,EBB87FCC5EA75A62,46CBD14EF6B2392E,9715B7994BECAB65,6D3DC79E6FE38C19,FE58B12F54EFA3E9,AAAACF0C985ACC59,42D33E478AAA8ED7,00002E084717F7D9,74B77B2505000F77,CE8F0E7681D38708,586A5BC1D1DAEDB3,BD4F7A7F5AAA1EDC,3E85B941BDA76B9E,18AEBDD4B236DB9B,A2E47D76D72B996B,7374EE8AFCB5C636,FFC1245C10A0D033,04B03D89DCCF75E6,9A9CE3FE6C425125,00002DACC04F4A2D,A928E313D86667D2,621B599070CA4DDC,F5A9908726AE5383,F11187775478F0C2,479393EC84FE1285,CDBA6F9D076B2FD1,9F572F41AD73907D,B801B42E8B5FACA6,7125420362EF9A1B,ED10E578FFF8E36E,2B8D92163E19C1A3,00000100D0885446,3BCF3E15A6310A42,CCCB271295D82C4E,D956AFE980BE1236,0C6E49DADF0831C1,7ECE55613599344C,AC0C33B9C43362DA,CF959050D10677B8,D2F6BBEE762D7609,77AD31D46D181765,8E17F4563E175CB6,E2130487288F157F,0000115287DE8638,1532F1D71EF063DB,A228872DC093AF7C,9F88FF5A00D93A34,2E0D965ADA858353,DB7762C573167365,2CC55236BB09A8DD,D899CA4FC7E1A0C2,8596898FEE5F7984,50DBD5DE413586CB,09742D6BCD64822D,9FB2A31F80B51360,00002C5B15A6C8ED,04973A862D862C04,00AD7D8F37FFBAE0,18396E542E7B9CE3,3EEDAA4ACC0F199A,03721EA512F91FB8,BDD04CC89279BA77,96FF6DBAF27037A8,2E1B8974431031A6,395E51B07342D97B,0E1F7B99120BED57,0AD4CA012F51389E,000042E8A6FBE698,5C86C80BBABE570A,AAD9053A4FB0C0EA,46060130B682CD3A,860DBDA663DE9985,FC6E975D66E39F4C,27A737CDD19F35D4,2673295C24CEF6C0,569F39286F7FCAA5,56AC5B7E02D5C7E8,659AAB34F7CF71A0,6C3F9095278CA976,00000E3EAD552572,E8FC6B5F990EA69B,5BDDC11C7CD29C0A,3FFB49944CA3D729,C5640D30793D9792,6C37CE6B1BA84F84,FC1835F5DC9E95D0,309706DF10E410E9,A3E1C94FA9B62B54,AF8AD22BCD1ED345,2D54D012D77321F9,80C3EC17EC8DD9B9,000050D0981C36F6,FF7891BC3E6E836C,DE1408C2F3D3F5FE,DBC197B5EECEDF5A,6A58AB8A5A46FF60,8F235A9B75C9025A,23182AC08A61835F,92F274E0B2E6F304,165DBE1D00B9B8C0,4BFD5F677FFD06D3,C46C8DFFA2AC4B5A,72965B2B41DBA383,000032143629034A,63857445D19B30D2,12FEACA304ADB0EA,16A2CE7A8D224462,902125DFF5B6F222,0D196770DCFA6777,3D5001C6394660A4,1D11238D8FBE5CC6,E1E4B1273D95D95F,8941FCB4C3F6117B,6199F3F209846D27,65062598479F39F1,0000261E52230753,E5DD7E921C14838E,8704A76DF2E4C38A,852B349E39CD33A2,564FDC1050F69315,1FF74CBD5D61D1EF,19F26CEEF0A33792,1B3F57BAE5768E8F,0F8966356FD25520,124FE71926672E74,8FD2B0FC11C29D5B,67072D18DA52CFE0,0000520A988CEB8B,72630AD948314860,DC16318ED6A6CB7B,030A4319822069E8,E91B75F5CAF6CE26,66B318505DAA4AAB,DD5A1002E80312DF,50B452EEC1051B21,F6FA3A54FC57B113,70D1256DB0C59E5D,C81C6DF2ACA4CC5F,805085C42321BB31,00000F2EAA7E743B,15E5CB523EA441B6,CF7ED30AA9147316,BFFEECEC2AC9EBD5,ABB4B9BDDE082BA3,142701F89818C20A,B82D7FD363264860,28F62C56D9414205,BF3757F1B602A892,4E9B22E77DEACE24,6DBBA1FAE940EEB8,810879CCAEA5A229,0000077F2590A027,5B71BA74158407CA,9F02D530B79F274B,FA12EC74CFC37340,FE80AB5FAEC7391C,A9051627B6079838,EF5718630727589C,285BB7D7F47A0C7F,1E4E50CE1206DB22,D9DE5E8B59191B9E,79EF0E12897D54F9,41D2D7CBC6A0C40A,00003D422D5E4704,62043D16B2F07570,57770B0AC3CA5E58,19F7204FBFC08750,7BA5EBADDD404AB4,B78C939B3AB46514,AAD858614FB2CF16,1D7283FB30FC5A19,9473F27D537C0227,DEA9AD00876B0E86,B1405CA56A629017,8FD018C639FB7BE5,000003F9BCFE8EFD,37109915E18887B1,A3EC5256C16B5002,59568EF56E045516,44006F354D32A84A,25833F55121A0319,3A63E1EE21B96ED6,663DE85119ADB6DE,6FA1C72DD3A3CFE6,8D6570C0430F2FE1,C7149939466A07DE,67AF84664921FF84,000019802534DBD0,9A0BBFEA834D8DCA,8B2A90E8D7CB08F9,DFF6E3578788FBFF,28D61E864430B812,DEB68CDD87F0ADD0,C4AC6A49D062C0A9,1447DAEC0F0F90F8,65B3C5A1616E1CBD,83441A34A2143BF8,784CAABA3E2135F6,E9C6F856552DE5C5,00002EA6621C25CB,8C6C0C50E2BB4EE8,784F997F574F9DFE,EF780D48C183EF9B,97BCB4E0073CC2D8,B699C3716F10FC6A,BFEAD42C8CD21DB2,91F2180FFA2B668F,D11D54BE13F2DDE1,63728593B0C26915,B17734F232A85319,650FEA76014E0088,000000FFBD8F6D95,077967B3F89627A3,1E5F6B7566A93221,5D0D1D5BBFF418A9,65932D03DF71D847,2BF1857E80E87ECB,31F63A072295BE81,6B744270FD9B9C65,97DF94BD46CD39F3,AADDFE703109846C,91B95B907D6E4459,2F8A695BD93AD08D,00006455520E927B,A3560AB17BCFA1AE,EEAE0DA318A53654,51AEAAF75EB9FF42,6CD7E0916D5E805B,41AAD6B5F4A80F27,449CEB18A5DD5CAB,FA075DC70F1F285A,A4A62FF6ADA3BC54,691EA4A3C2F714EA,8F5C226D21604984,E03C68E69FB3484D,000025B14D9D38FF,5256432173905A04,45DE9C4F32027A24,B46E4FC21D13ECD0,64FFEDB1441B1605,59F14FCA279A5D40,34B4A75BECD68002,0BF2EADC67D8CACE,48F51C46531FDC09,4DC8038EE555D3A2,CA7A162A7421AA7A,B7528E7512C11A3F,00004BB42F656DC3,0AF0443AE0A7FDFC,CA662AEDC714C4AB,30390899FC39366F,61D3DCA9B90A4956,FC687268FF53B8F7,D211534140AFDCB6,08789CF390C5A0CE,49338F23AF616E8F,E14E38DC5BBAC1B1,E6D2C489B4D62471,D3426037D5C25EB1,0000699B3F28FED9,7BC3C8AF05F1AC84,9776AD26A61A6FF3,A194489850282418,6C1B0741CD39B6BD,A15A7BDB2C012199,B3AD12D6DD05DB29,BD87AFD785E3BF13,E20ACF0C650E30DC,096B7A343EEF3C9D,4150378414298A7A,A0232115912B6699,0000387EDC101C4B,E77EC8AA73C83ED7,BE4F54E2C7B5CC4F,1F2018A1EEA1FC69,28CF9AE3BAE795B0,182EB3B44195CB6D,5199F35104F079CD,45833A0BC1A8644B,8D99CE035CF5792B,9332921C63E48666,6A4526363791C0FB,0EC6DD529984714D,00001BAF15F2A69D,69BA65B722C1A023,537E00601D858034,11B639F18363868D,9D9649189288B456,B48D93E2A86DD04E,FE7C4257B98C6E47,712BC3BEC080FAD1,464259E95D667A0D,0001EEB319A4A381,2F830D063A325078,D897008600EC2216,00004F42AA8BD1B9,6B7983DCD6344AB0,E5402A926AA4F36E,697804E6D99864C5,2539A4E6893796C8,4CDB1331458C1734,A7C94FC64233027E,264B6DE5D14E705C,225723230758573E,288A91568B552CD8,80DC58812A0BB118,414C95AC8E9A7CD3,00002B86127E620B,F16E6171BA685F92,51DE40CEB2DC920A,4E9B81B61D4EED5B,417501186F736C19,2B501E8B11A2239E,1480354A24737563,497BDC86865A2BAB,F6C506B92635164E,A2A907B82E770D0E,F4A4834A839DAA70,46381FA3A848BD55,00000D72EEEFDEC2,E74A395EA21798D3,3E2375C2B0AB77A8,222720D75A76A131,89C9BE5A5065A914,2E78ABF88FA41DFE,E813227D7E114214,4ADD1BD4FC078693,E0A98EC2DDD8521E,4271AD16AF0DC907,971984A5044DB1A7,B37DB91A630B0114,00003C526F058C35,6551DB1DA87F0EC3,1DED8E450407546C,3475DF8EB0C30F43,701F605F00CDD392,FF38744DF6CBD91A,F82C87478AC66F78,51230E4CCFB0CCB6,678660CB1A220731,BCC6A8A467F28616,5C64F189891A0E12,B632F95F0203A087,00000C4BFC94D771,30F8892CF7B63DCE,EB622ADEFF6E221C,2C6242465C3DCF80,85D05F5FAF8DB831,5ED4CF46E49CAA88,FC9BA5EB77B501BA,027FC6653DE94866,DEDBC34006B777A6,708A3ED59A0EA1EB,4ED761CA4253F4F9,A88316C66A0AA3C8,000008FFD8C0E91C,C0D499F0FE78D6DE,B799AB5DD9BADB87,F18AD126CB275CC8,209DF5F2666DBA73,0D629FBDC80FF751,4C1211447D4274BF,1A8B4514C06C28F8,FC41D0FE2BBCF0D3,6C4EFD60E76F54B3,9BB7C73A41B0C51E,ECD0BAA53EBAD716,0000381FF6184BB1,551985E0F146BA6D,BD0203B29259960F,D4DB945B2941FC08,2700701CA4C5875B,A5D624C678729813,E7A37917CA1FA781,E72E1289A268B6BE,19E8395B516DA5D1,1C687B5DFD3BD823,EF20A3042B3551AA,46A10CC5ED6407C1,00005FCD6B170163,EFA04C4828912EB7,46CFA476C9B828FF,0E9E0AA2F97DA36B,37B83E6AA6187B68,7E95DEED5CA7AA2E,D473C8FCE4588676,CB3F2E0561A09B2F,A19B15DBA6A95A28,907D8ACA2B8B0EB9,6F65E2A43A461C73,837103F9829BDA17,000009B42C307D26,AF7E282F7EF0EAE7,83822E5A9A621A30,25AF4059245D147A,0A1DBB66F3A5470F,5CC78A07805295AE,87124E90686A67BA,F7B9E4C94BC02DF3,DDECC6A61CD035DE,F7251BCB6C9F6677,E66CBDC9C2D3E458,FDF5E6C86AD5A3D5,00006A6CEFF0A8A1,D1DF4E0437469405,D45DB230648BB3BB,D126F9DB2B35DE61,E1E0898CD4369A39,4B694FEBB384C1BD,17BFBDE3DECAAC6B,F34FF6A33244209A,3507CEB1EB739B96,D7EB4AA56F223C95,D061EDABA64FD0AE,1CC70BB9182DB224,00001D8C9C4119F1,B4C7DBE21F53F85D,F202C836DB7809F3,E8133040F058C2A7,A15EAEB0B011C186,3765294FC19010CA,3877EED3F97C42EE,CB4813BBF6E6EC56,5FDAC2246B66111D,E441D6EB87763141,B8827DA853944C05,4B6F1EB1C35F4E74,000020D36F627E06,900E1E60507C95A5,930B4D1B1D0E3235,2037E34CEA890166,5B7FFDA8C7ECD8CA,2C44529AE52851E0,B4F0589FA3182BE6,5E258CB145F64B77,46FD641D923C2831,13043A07A880AD3F,18D992DA3D159A26,0E7066833D4CA327,00006C109ED7D4C1,5A5BD1D2CBE2A1BD,6CA7B6C3750609C8,10BEFA08B9478571,AFF76282AF83F37B,BAC07CB7A4D6C9C8,1D9821E68EC3EA1E,211ED262BA2A87AD,00A9E23B89AC9E43,79A5E3926C1C46AC,0F4779A4F9983B87,025ADBD01E72014A,00005FF1CB4B5505,F640F61D9BC8EE56,E6F280D33B903A25,1527F2AC2EC25DC0,1CE2733C799D51E9,888EAECE58E36980,790AE3ED7276FFE5,AD91C156C70FBAD5,35483FFA8D1DC313,22E854E0979CF5FE,88986D8CE3A01BB3,8F98D5C8FCC411D8,00005B610A4C22E1,14204B9FEEE0E0D0,4F0BDAD009B375D8,3BA3082BFDC9CC48,168CF8E96B5FDEB9,1113CFCB971D4B87,4EA9810434FCB40D,1FFCC23205459305,4391B0759D799B80,E88E31B3C0678266,BAD20DCE2129B664,3E197004769AF484,000004FB53589302,7D684A54FB0E1D47,00261929C7BB6A0D,ED41888979F583CE,4E370C0B097BA1F2,F3F27466A5B7B1D2,1937F7CE3BDBBE95,E981F126DF61A8B2,81F1F502006A121B,B48ADAF738C946A5,E695E4E27DBA6FEF,6E6D0DDF0AFF9188,00006AF77E8EA246,201EA3660A56CEF9,7D08C8AEE0396845,7C82A7008610D87E,2DDC0EEDF5F5729D,0CD7624113DE9653,1D3E45D54C851CC4,E107CA6B82FC76CA,851537FDBCA782BB,66673502E7985210,8FE73EA7F494C16D,03A51F861BDE556F,0000482C727A943D,1244D6CF9671DF9C,25CB52EEE528EE69,1B27B977B44F2F9A,2AEBAD68B83813AC,653EF4685F0C79E4,899E060578AD1B6D,041B60C9A72B0861,56C5EF9ED3DD3FE1,51EB08733BA90CEE,1645206EFAA5E892,F3DAF0CE5CC14055,00000DFB7CF57EAD,2E53149302A672E4,443993D0B1E0F8C3,159A0179608D5D23,5EF35A1917C679B4,0366A625009F4F71,C28497EB181571A6,2F4AEBDD6B3F0EF2,197A8CA349783911,BDD1BB8311D5B99B,CB3A2678FA38EB4A,BF73350E1BF8D384,00002AE23C772C3D,40851F5BD459E4D8,A9027149AD120B69,89B1B1453272469A,DA7C5F6109634E03,117F2B69B7DB3653,FD6ADF77957105D4,7D2D5801C08445C5,DDF70B89D237A625,FD708D39939BD807,28BB597706762EBD,17CD5AD44F1B78B2,00001B413E962715,A9FA7266807B987A,32132D851824B6C0,9EC657468B1937DE,2C86426700954BDE,CC235C8482CCBF00,469E3172E686B944,DB165B522B7655CE,BF1A9816887A16BB,12150E1E5B53FC5D,E0CD3B02DB7DB9F8,E59982123B822679,00002A5EF6DA7322,75074079EB70EFE4,BFD5876646494104,8BE86992DD2F8FE0,5E5BB51D16B4F62A,740850F4DCD83B5B,7F6F5882758BA714,1FECADB5FA3B8542,F27788C6EA6C9F8E,5342F7624B250FA1,56C674B6F8B743CD,DEA80CDAC9D6AFAC,000057BF540E079B,B2A1DD1D26CE5C46,B9C17D758678F750,1E09E7CD3C566D1E,B9ED98863DCA209E,03541ED0A7876380,9715B16D74E5AE64,83906FA2B7AA0C1C,E2F157E6F28C5638,9978B438B4032E9C,BBD20D5F23A7A0FD,D002421C7CA1166F,00001B1533DA71B9,5594335B9D2C7623,95DC76283F297177,A9DD4B0C7D487779,5EC16850C6292452,F06D543D667C9D23,2FF0F31E5D7CFA50,38350310D1F85CA7,37DF5A84B26950DD,C9D0EC4EC79A70FD,744EDF00D8796780,3EC4114923315FB0,000005BBF02B684E,439FCDC2205FB8AF,141C54FA50D414AC,2AF843AE1E2D64DC,116F300D8495B916,B228C954BFDEB941,3822B84B2EFC6A65,521A854975A08556,4641D0189E75E2F1,EE699E3598D61AC6,BEAAC910BD558261,E2E4850B643F2ECE,0000623B61BC052F,EDB27E386491110B,6B2B61D95B8D3185,73250B6B21D1658F,8E5637451997866E,CE5B49778350CA5D,A475E294A3C776E5,E6976D19A9C71515,30CD947562D79FCE,877249F91853738C,48787B8D9A18111D,46BED7C71CB5DA39,0000175240261948,2A21A603BEB36489,A106FFD2E17E8B5B,252F1B5E5091509D,8C8A6CD45DF7FD51,8C36C93397114B44,904A7100CEA650A6,533D031E8105AA54,9CEE455B1C9A54D7,EB834D2261F2E58D,CDCCFCF461A90F85,370EB2EEEB6AC6D9,00003A4D69C600DC,5C2A5027237D9A48,0E949F3D139498B2,9D263427B0BC4799,199670A3D2B64571,C282EA1481A917CC,FE2FDEC8A21034A2,C765F8B588CB4FB4,98D44D68B239C6F3,45DB669F6C434227,11FCC31224CD44CC,F2C3ED91A4BAB00D,000025650B47B461,C432ABE561378EA4,BC9E17ECDAEF2B69,9234B591846868C5,3A104E4CCB8326A3,3552F28409FB7010,C243D7430574293C,1DE5454FEBBBA33D,1ADE7BEC30CA921E,36931D462D3B6932,6D702D207EAE1359,DCAA0AAEF6C0EB05,00006110EC90608E,BEB08C34F1116294,AD2C296C5E596450,C2F353EA3628D48A,3A5FD26E21B3A07E,BB30A25902E3E9AE,986D232C64B6EA17,76953D0B2E96D7ED,9C8F2649CA0E9EDB,B18FEBD2F2C3920C,AF81B32643D2BEA6,FC58742C04236B19,0000321A66389DDE,4E188F94C177F7EC,F46935997CBBCBAC,E5AF695701CD0D64,A454096EA26C56C0,EF7242EC0AC60A29,8743DB42C7B429D5,9330ED08E5D3F02D,C59F133DBBF4BA56,15B93D2B0B5111B4,06EF13F8A646C833,5E54D6F89E0B7825,00001C7F91685FC4,B801A86D97CE6A8A,F0808F06F3DD9676,8E03727506C91AD5,258CB670A0BA146D,D66D9C0AA1DA16CD,4C8E8766B0522621,59E20C433288F55A,3554772390F68B82,ECF6ABFB7445C182,0BA8DBD75C6ECAD7,C1862754F26CFD14,00004D880C24D3B2,5A514A3CBEAE1ABB,4A278A99742EBEBF,FE0FAD02FFD85D4B,9742005DF21A9DBC,B185F80626AE3497,4F8A058C7566A70C,0AD50569BB2D7986,D34ACE91A2B41E88,97ABD455BA6061D0,B37032ADC4AEBE3D,7B37944CFB2F0003,00003F24C283BF62,D3B9DA556BE19DFA,4ED0C0A10FAC7A0F,CFF6D2D462A4CEDE,C9F3E02DEAB40849,77B324134971ED2D,A872EC9176A5A70B,C5F4FA897B993547,2E270357C4490DC4,2F411159D3D980C0,4C2ADC5803503019,DFE535DCD6FA1401,000032D9D07D563C,7473904818B14800,71CA07174E761E23,527C152CFDE6A715,1B0BE7AC84BEE181,8C7F7565294FC4F3,A7D5E2C92D448069,E79E4BAC2F669576,856E67399AD52D4F,D2A252AC9D8A345C,700DABE50A2AF17D,34FEC48C4C18CDF5,0000427EDC38898F,00289185AB7E3F11,A17304E6754EB393,90ADFA338A10FD08,037A1E8C07EC3FB7,50B39AF7CB4F9E03,9F8CF1A005042A8D,111273767C32D465,AA874A38B1375A47,36BB0C9DABF548A4,5E0BE80D49629081,B4BD79DC7F18E92C,000004922B5BD69E,D904FF2A0E56622C,75774EFF5F9FA2E4,8F769B971B1AB12F,D1A5445035C41421,E99E8ED8763B5E5D,CEB403F2F06A6BEA,4B03DE4CF71642EB,9C08596112AF71C9,552E69E701AFCD1E,3898898878C439C6,34963A3665DAA0E8,000047BCE0CEB2D4,A906198ACD0EC0BB,6F9408C1D64DC1B1,8EB13D806C8C9B2D,347BDC65D8BD23DD,B4B53C101485565C,411229466A67EEF7,2E3746815DB47BD4,71FEF2BEE8AE88E2,19C783C43780CB8C,56A81C064829A73E,D0BB192967FB01C6,0000020F4EE4F590,CFF55CE92E259E4D,2D4E42DD3361AA05,B730B98974F6E6E2,E00A738AD747FB47,D44F633E656576EF,E815C302AE0BD960,D40F512079B18823,A7B3E6FC79DE3CB1,D8F2214842B00DB2,0936B1C24FF30873,9E1F1D87C597A0EC,00005F0867C17214,F89FCB5DFB9DF3D4,A19827938A1809A2,54E4AC5C51451771,CDB338788C86EF01,A54CEF9090440EE7,2E02167D86125A78,089EB9DC20064948,E5C4819184FD4FD0,E1CDEA6F08CF6287,66B1FF5BCB686E10,AB78CD13C54EB141,00003EF88AD343EB,109A09C60E385380,845ABB8492B16CF4,2AB67FE9F08F026F,EB2662267BCB9473,BCA2A943B9E7136D,353A77C647D8F5F2,4E0D10A6336E6E7C,834CD06BF5516F49,7AC005E7128B1324,125E4C90E9D7EFE8,BB7922A8FF39A444,0000532C33F696A9,7A35406FBD43CA81,09AD80F1C8004E95,F64A206EB7B5AA02,B8AB82196B2594ED,2282FA8E30D969E1,67FCFE79CDB64E7B,17DB517F7E9201E9,FFCA0E637D244E7A,99FF55B7E0E12E9A,B963A38B6385172B,74E85BAA4226B301,00002E9AE6E067F2,EC532B7F24D5D819,F862FFF8A2A73259,C6A125C7589A61ED,2B6863264BDABB71,47BF75169BAD8202,268F89A20F08A7FE,C73B6CFDEACEF0A7,AF792415E731E515,C1415C098052E0D1,5ACB8EE12319D736,7B6162D0DFB97508,00005A28CB64529D,4B2C391D3124E557,A8831BA8DA6692AA,FB792C0983DF1F95,DC83254DB6D009E4,F19A91AB9C768F8B,AD236920829FF673,5935BD4B80BA8187,4200E7948B4C39F1,C121D528EA6A58ED,40A8FCB5CEBB0868,4BAB3D0D6B2245E9,0000167A53347582,A0B24E6AC309922B,30D4AA5456B0574D,302E88CE87A57162,FF673228947F2E94,00085E7DD49492F8,70456C7129FCFCD2,2ABB29921A6B27E9,4AB2CE1ED4B34518,48BFF612BF64A850,F04F4D3B34DB8B45,55F6A78CA0BDB2F0,0000546DD691DB53,3AC5845C5FBC1D36,1DDB8A01C57BB469,F4EB2DC76EDB3601,505EA293FE0F3F54,AD71BAE0987BA348,EBE6AF8DB923C266,188C8104CD041613,A8FA077EA2A185CD,D26AEA3610FEE7A4,C471EE6E704AC042,4C330403DAC6DB9E,000007B4165CC7A4,43A4C2AEE8EEBDA2,FDE8FF8900F8658C,D78AA6F912D910B0,2F7CE86B7B9DE3B9,7F8F3206F9832092,558CD242AB3617D9,3A1083ABD8B10D3A,77AA4D86F77F553B,E188B6D9D5762BCF,3DDF1CB09860D5D6,3D1AC7F83B3785F3,00005E149AA23CC4,73AD6C84353F3348,FB385F7246FB2BB3,F082BF05A28D66DB,DAB5CB0109E82E4A,D36DD7C410B65757,80A00334F764C412,D3A5CB3E690B8AC0,C99F4D434ECB635F,4071828FEC399A55,B344F0ACE44E1D65,A9E9158993D55D36,00001E7F3AEEAD3A,17858C1E9431D13A,F486883962B4AF64,8B8797154D1B4288,DD29C12E1BF613B5,314088BC483C637F,6EE9750D53F4C1B9,85D6629472574115,AB88A58CC9996DCF,FF0DAC374C94BC4E,C630CEF360ECC0E6,1D5D4F37732DCB89,000012DA9AF774E5,1A3A969512E80F14,660263D79186AE1F,3F0B0A0C14431978,673FBE3A600D81A8,C13094379959F4EB,8F4F85286DB44957,203479B68AE69D63,ED461266CCFE851B,130518A7B7C6B67F,543C4C4DB166852E,C7D779BD1DB5A36B,000048EF100E5AF9,6E861F7AAD88816F,EFDCD4FDC04EAB7D,1AC50F366762EE86,53077D757ECBC211,5A679A172BBD36FC,41E02AFD3EAF121E,DE61B0934A0C38AC,D53567142B27CD4E,4ED7603AC6ED7549,2E2E2042E576147E,1064AA2CCBC79DC2,00002316F38BFCD2,B4186B3D5890A987,143FA1FAD9C131C7,E29F7C6AE8CE79E2,ACC20959D5D99FF7,F4CC325F4AAED1EB,2E8BCD3402EA5006,3F8E4823E53C4A7B,07117B843F5A352F,21410A9E8FBF43F1,3C005FC71670B59B,812AD4C718BE60F2,00005BDB3B8C454D,CE7B7093EDE3B1F6,BC987D0788D15689,0B87AE2456955FF3,A0EFC66978A195B8,8E8D975DD4F4E314,91622333F70BCC1D,F43DBD65BCD15EE1,17080591D5DE76AC,0CF51CCA2E5D2252,385F26774B52525E,4225D27027FEAD6D,0000334A6D108EEF,1F6D7C15C0A36D6E,3B132660C2D20442,1EE426A748716539,B0787E235220FE8C,496AEAF3A67B874E,00D71B9A010204D3,A748FE052FF92220,687B347DB13B5D36,EE851875BB13DC6D,06CFD5498E666600,726108CEE4D18833,00001868434259E7,4708F8B485DD0DA4,A0AFF8527983236B,7F95A041CAC2E951,9867A97D32D1AA85,9DC4C83F17C4D8AA,F44FD2EE7AC2677F,80BC40647F6C88D4,1470E414C1E65CF7,15179C1D6DF8D1B9,2F3A4E7FDE4314F8,E418177B712DEDD6,000004781DD0808C,3099FD01F935F275,B8EC0646C0851894,952A365DEEECD041,218D122B7BF0F364,C1A4E68664E8C50D,288DE94D3B7F4A73,D12F07A08496085B,41C8E34EEEC0C4B8,1FD4EFB7E1EF208A,DBF3BBF4C153A16E,2FD707CE27093825,00002012FA545719,615D32D5475D1847,3844A9FDB29C0002,07D62EEA67164E15,EEA4541DEE34BC03,370C4A5A4A07F828,573FC912CA5F0AB7,659DCE4BD7386F11,0D0D76E35A5D5CE4,64B6D867A0804CC4,4230876A96CCC8C3,D65B5EE841E93D5F,000030BBC47EF2F2,61C5FA5E7C759314,6FAF42EF13A5B449,2B47781C9EB50998,F29A0075C71BCBF6,58047C1E1EAAFC45,CCA63668B1A83F4F,6B34834E5FC05B90,ED29ECBCC0E7F417,9F6BE6F703BA6FEE,880FF4F558EE705A,C1B6EE3A65BC3E8A,00006717605AF19B,E3ECD06DF17100B5,60BFDC6CA45C007B,5067A7691F9111D2,62CEC3D9D4C9C6F3,97D5EBF1B4CC775E,9D8332F7BBB45AC1,7A2FD6DD980507F3,A44DAE59474CE825,E8F86E5634A314FC,19042156EE568B38,27183F07C938C9C5,00000341769EDDB7,3224DD441CF941E5,AA419BC6B4FC1FC9,A9B3BD9D5471B4DA,4B5B7420E22C9F9A,F6BF07DCFE57C9FE,0846A9AEC8A66E14,6752125FA04F99AB,76A649E234C8BD1F,6FB4F35066500814,4CA6AF378C2EC476,7D48C594A8C82417,00001B8649467595,C8C81FA5793A4692,EC6689A635511C50,5F739161FEF5BAAD,3DA897BD96B0D8B3,C93F1A4BA166E5F1,FF421435C031CB62,FFBDD43794AF77D6,6DD6F4A5AEB926D2,9E54105FEB3262E2,3CE2D82D36205981,F2D5ED49885437CF,000042DA893094BE,3EBEA6F6639E87CC,C08347259B0CB58B,991B593B4BDCB820,8DEB9C448A410D22,6FD1EED614E954EA,CF3BDEE4011FE6DA,2837E6996D625C70,87506FAFF3B2DCD6,1A97F1D4E943A6B3,6230B18454A6CF9E,D824647211B3223E,00004C417DF16E79,5089E7CE4C64A264,320A43F291E2D7B6,BFED471EA45064AA,D234B11ED2B1F692,251ECB7A05274DFF,0062B620D93B0252,9A1EA8F20F77C96A,BA78047661FE69CA,469D712D6C804EC6,24CD388B9B3D4481,78503C7B7BD4664C,00004B2E49AC777D,D28D5582971EF513,E8DEB2E88AC0280C,BDC9D6B963A17671,CF8022549EE29117,374CEC04D78D26A1,4E30B1BED2445856,F187B899E8E4CD69,EB203ABA5186782E,D3A892CC03172F91,8506634AD20904A0,9AC4C51C7C29A8C6,00002CA3EB7FBE8C,331AC5C70400DD34,6BA2F57FAF9DC34C,0F1CBC3DB7935ACF,A94C099F170EBCAA,398F11125ED831B0,AC41453517BA45CF,CD96184F70E4D468,9FB63C4CFE58DCE2,A5AC44CC200243BC,7317222ADFEDB455,FE5F1BD34DFE339C,0000000F0CD65B0D,37F29795C75C5443,080EE506E9DA6E7E,CD5126376CE75DF5,9FC80CB7947A24EB,FDA833B449CD5973,6CD2FCB64882ED3F,C65BF353B895D248,85B971CBB50366F2,B1C48A5D52B129AD,232A7FAB4FF72137,FE2559946AF6A2CF,00004F0DCD2C75CD,54750DBB1ECFD481,334DCAB593B3727F,D5EC9AF4B4D2FAD7,1E8857E1475A78DD,18F77C256B7AD517,31FF481F25829136,F6313276B8E08E5E,FD4777D72EADC11B,42995B7BDB59D509,4902E663F502D5D9,FA951EBCBDBA62D4,00005EDEE12BE320,A91682E55B1C702E,F453732E16A2DE88,E2240FE2836E6C83,3C58E5FEDC4E657F,761F95D93B381325,A227028A7421D423,D3C16FBBCEEB2873,889C314CFC5A1E13,2814B32BE05046D8,4E4B8DEBCC32D546,98C54B8E8D69BB32,0000643863ACFB04,8FB567667B7338EB,B9F402B9606125D2,68A59255C2E1DB2F,F313EDA13102F113,C3D672151F04951F,88B0D879F6891BA7,7B0674BDF5206F9F,524264A045599881,D6344D76D698E5E9,CE995DEA443FB929,F58D26B93D36B47A,00000A6E00261DA0,1CE477D31B777F31,4734367689CC1E0C,93A5BDDE6D85FDF1,88F1B10386F22B22,F259357732F951EE,23190E722438258C,1C206D3D2E6B5664,130001D996C0347E,3218D58B8281D6DD,1403BDD159A2976B,A9A0A62FD0B9A0F7,00000EF19624A0EB,5A78CF48D8D737B2,25EFBA56B1F17FBB,B0A1B548FDB8D621,8E8DE11AC08C7EDE,2509F69E7495C284,7B66AFBFFB74A234,ED8476386EF1D9E9,A2669021EE332C1D,960DAE8CA35E29F8,F098C15A5C7D494F,0739EAAF066F1466,0000073D02CA2D86,46E9CF29A400724D,008EF390B0DFEF22,42A44C7BCA0062BD,34B364E0B3E2BF03,441CDA1A6D82843D,6E7CB33E92FB33EF,05A5E2074B6539B1,D3F21B54F1974E10,64FA37CC074DD860,75191C1B421CEC8E,806014360ED4E28E,000047E86A2B84DC,F764FEA5D7E7D1E5,4DE691C660935541,0D1A23F6AEE4EFD1,270ADF6C7EF66286,E3339EB68BCD8ED9,409921D97EEA5BC0,9485DF9465D0F356,EF0FFED5D95C5B65,EF71161B921C4B9F,7D9B694A35A52119,945445CF1F6749F0,0000003136EA13CB,18852EE073670DA3,2E58D9D5B1BCBB6F,3D51D62C5E3792DB,5F9B7F001AE3BDFA,BECAFAF3295EE821,2901DD595C27AEF1,43C3719B58A3707C,D1AFB6B926C1E64F,54CBBF6688500C6F,8D62B7D296943117,9F122F20C07A4A47,000027176907CD05,BEE9342597CE735E,12FA98A98644D710,FAE0223636EBF1C8,CBE365AFEBA847BD,8B25452F5DF4C94C,AB57D10C134AFEAC,2EE1AA7C702F2421,90E13124DFC43B80,4091799CE6080AB8,0D38D99886E6D433,20A56CA55B7E9ADE,0000518248771ECE,5B26C6999D505241,A2587FC127118FA2,CD3E59CA42D69EE0,6D334185BB06057A,A60384E3BA03F444,F3417D3C9DDCF970,796C1069DA7A7802,5DDD3D81DB556331,7952B3E3D3E23132,FD5D959A2B34B680,EAC4811B58D4ED96,00004FFDBCB20770,94C609C0A21CD7AB,80B84A2308ECACC6,9E34ED138178E4FA,5FDBAA8A04FE1A31,E0ADB21715C9F6B9,C5CECCAB1B08FC14,02634C1AA32E2E8D,ABABEC6A7B36F09D,BF710434025FB7FB,27C9850EBF34E244,D05FAFE3503BDDF4,0000605B0B1A7E01,FAD3294683E4C104,C834F879248BC56C,5C376E2B5BD76EF4,047ACDEA00ADF9DB,1D460C2D587DFF60,53ABE9CFB10FE1D6,BB17E342479C1C01,31246E00A3B30A7E,DA78EC0B10C12E52,8746146F489BDAE5,56855E768337CC0A,00003E0F0D80189F,506FCE42E88C3469,9A3714A52F3BBB32,254D4A14B6564ED8,A972BACC63B8EBC4,33DCBC492DA48B89,8531BF54848106FB,C4A769065D3B237D,512DA54018BDF264,E7155C16C495F7F8,27D21281C4F207E1,F80FC32B632FA72B,00002F867BBF1319,19ACABB018E3E455,9ED6265140B3BB47,A1AD5CA93DFF23C4,0817E0A18CD7D7E5,64DCA80DCC11442A,32F755C120D3DBC7,9264E8A0926B0EE0,A944F7BDB41D22B9,6E15746362BAE114,479104D0A9593D5F,1A6BEE3AD685D707,000008762DB301AA,064D89605E9B437C,D7C9780162A6D8D0,9B1031B38A060F65,A7F0F6700A4D8E0E,C14BBC0A9DCF8FD6,DABFD4CB862CDD7A,B52242CC9DDBB6EF,1991AEC675742016,3978CBEF5CC80BFB,7146D2BC5E2AC369,FD05897FC6BCDB24,00003A761B8DFE72,C59B60FBFC10C267,44CC3E451857959C,BDFC838FFDCAB1D7,11269A95960072B9,926572502F65DB95,4640BD803C69EA3C,D61E69B86D03950F,F9407AA785EB86FB,0B9AFCF4E6A9CD62,7458AB4C8607C91A,B7F6C6BA9004098D,000021B1DDE34B38,E35A8B3C4132C79F,95698C8B357005FA,1C37B64047CA2CCD,EC659CE8B1DF970A,134E1D2390004EF0,6016FC485F09A294,55608A3136C6E373,77208AD0B60B01BC,455D0B5638144440,37BD719DFB60E64C,93FFA8D3CAF7F278,00002FB893620DCB,B1BA8A3C07043C19,F244B7CD08D631DD,7823A51A4705C6A2,AA56E29E8607FA0C,59CCC8B3DBD5CD69,1F349CD270FA6CC6,5F4956C3E0589EFF,D00A32FBC42E945A,6FA78B2D3EC6300E,8082640F5F299710,2B6F292495B4E48C,0000159B52E60CD4,C7A3CFE8E35CC1A4,20CB1E309E2B7E21,4ACF76E9FEDFA4C8,CB2CE2FE2C19D378,5030C59F0E7F34FF,4EE8F6ED4DD316A0,2D72A9789C7208D2,86574C329CCAE298,A01F3DAB0A4FDEA4,A18D0788490CE9BA,D704013DD49E942A,000019443DD576BD,304C903910D08B92,DE55BBD208B9205E,8EC764C4CE8752A6,179EBEEFE888C6D1,4837CBB42A5DC620,07EAF389586BE01B,04EDA5420F338202,73911161F226AE0E,554330F303D09D31,E2EC0481D4BF4D51,558F1E95532B2959,000005CD98D3CC0D,A38F368ED7E92318,9D64849DBCB3099E,9A22CE185BE0F4BF,34B99D367495EB93,8106F6A34F1C5A5D,7B0A997055BB6847,CECA81CCACF6A869,D9E3F717F92CBFCD,A20AFC58BD9295DA,C558EE08CE9C5287,07EEC9633BC2DA42,0000652E938B7B0C,255F6551B5EEBC7F,43C560CEF5C5C74B,9BEAFDF5F298997D,9A96967FDB9D9F02,F921D4D7DD68DDAB,9B0AB47331AC06BE,B3E1860144971210,8575A88ACAA1089A,0E40E38C134E7E71,8C6F3C883792F846,843F906F7F6EF3F0,0000675017507C5B,8D61A52D2C80D5B9,BBDCEE6BC9EFAA2E,014D3380951AA83D,5749D293A296DB7F,4CEDCD749CB19AF7,330A6704E3F762C8,D9DF653C9B80D795,717DA278DC575455,B2500BE699A902D6,866A620118C27010,2497A4918CFE9122,00004EE6D2E4F92C,8FF0666B8201AD26,C739F91D96E84893,1CB086CD9114AD43,5567799C6115A122,E5902A448DAD98B1,15A4DE52B7EF4622,8062C1B68CC9E30C,C1BDCDB9477B816C,731BF9F7BC01F5FC,5DDBE1203CBFF563,5DA65B193EC677E5,00002BF33A04A936,994956C7F7DED59C,A35F887E64764B14,548E436B1538FDC4,993443C63193E2E2,5227FD8D4F2F740C,5C8018D2EF13B2D6,BA6A56A0C514DD00,AB22340534F181E7,0ECF40252AA65122,599A500B61A41BC8,079C6725539E16B2,0000485ED5EB7FF5,C2A1EF6F5334AE06,43AB626EACF9056E,CA0FFE20E103ACD3,0616F11D931B4C9C,AFA58601DFD7E2F3,657CD54282D3095E,0A68DA1EB5FCBFAE,572138B697AF0819,FEF268E88878651E,ED4BDA4C23CE74C4,949F1DB3B81BDCB2,000047D8324C8767,482652F16FE52043,032DF2E49F3691D5,501573A6BE93C0BA,0ED5268ABD95AD7B,7D75791E9AA3A01F,20C6E6D4441760C7,1BC9BE9EC958E61D,7438C2AD264A9C18,648140114BDEC7E0,989A72770FC899A5,4B6A4ADB169599B1,000044D0BAC2D575,AC36B17CD281E211,6D5BE7D8439D1FD3,50F14F502DAB15E1,2ED1CE38D89F5077,D19DDF7393611195,1D82C49A35D023B6,5286616CA595F59E,14E33E3775D750A2,C77C9F0CD6B52C9E,044974CAC62E34C5,20A664D8E8159E0A,000058BBDE2001EB,3464B01CEAEAFA5E,DE670752B10B454F,460920FB4AB39B61,C4AFB9677743F05B,148A8F990BFBEF0C,E508D978D2A23ADC,92E7AD3D5200833C,092811D9E715CDBD,CE5697F5B0DD52D3,CB0FA2A49612066F,63C8A46F6381FFC2,0000303F18D40268,8850C3FBE548B1DE,8978E3215D7B73A7,5FF4655CD89B01EC,9EBA0C45706E0DF0,30B61F49C89E6D00,66E29E6CA9FB9896,380CB5643DF65C46,21D397D881B8FD25,79B05DF9F50FA8B0,CB56E169729FDCAF,8F6B279E233DC622,00000885552DD8CC,545F1F1864B9E498,9C3D0E76964B4B78,9C902188DBC8943F,4EE992FACE50E8EA,1DFE05ECFF392470,F74502DA399FA5F9,C822EC17E2E81B5C,EA1F2B55C89FC9DE,6E4223C55AE63159,A1AF5D736644B757,E6620E95522CEB33,0000133497EFD82B,5C68C881E9976614,D4EF1B5AD822C1A7,21B6284BCD1F3505,7A652D6ED8A5E06D,B5A2762641779461,5ED6A98C5541BF2C,526B45445527357E,907E9B70873998AE,C03EDBB87298CD78,985334E48530015C,78C213006E81F259,000017AE4E3A23BA,C458A5F54D1649D5,271A03DDDE9A2115,C4CB664DD149D52A,54BF573363698A44,6981D99FD9053D53,A4E7566314E53DC7,90062386409F7B79,5A086F8CBE82852C,1E1E0407BFAF2BEF,FBD38CFC2F34C341,11405F5DB9D44249,000023660E487395,D0A861003D8CE66E,E68511FE934BB86E,DA1A4ED06B3142EC,7D73AB563B336416,3A62F53494DC32F5,4AD6099129198566,F44A48BFFC7F475B,4BBFF2BEBFCF4DB5,92202DC6BD78B23D,00E1D74D38A53034,E1F10BBD966F3794,00006154B64EFD5C,66AF67D4B11C1AA5,AF5DDDF13FF69169,6391BC58E70204E3,D2B75079A0FBE7B7,500FDA4F6F6D0903,A101E0F30C286006,85ED031482B8D3F5,6070823544605B59,399502C6889AF9AA,717F8FC6568D6ED6,D7C6CC14B026F542,000039E521BB3D7D,5593BBE3FA3ECC57,595E6A1AE459F61C,1DBEEC69AC9BD08B,F9A0563FB4E34C7F,D2D68BA177CAC15A,DBC15E655F7C138E,ECBBF0F71DAF0ED7,480FC0BD5BFDB15B,236CC1FB1D8F1780,F3893BB88FE5DDFD,C40089FF385DC7BA,00005DF8F51EDE90,FBEB3F99839AB887,F312B066D0FB75AF,0EB86E1F6DD201F3,1E0E7D6C0FD8836E,C75BC536F7582534,086A16BB29EDB7AE,F7CF10CAB345FFFC,9F65F39298251E8E,7A84E4CF9DBC24F5,8E893AFA41A21A62,75FE8CAB431D35C5,000029C92666A259,F73A574DA1E66AF9,32CE29E0B7F23D35,A0B368CAF37E0C18,57262E9440D55254,23A9506BA4CF8153,28694972494AD0E2,0BF3203EEC8D7966,3403C7AEBCA2692B,CE2F6AED719D827E,B3A28F5361FB4424,B739F936B7930EF0,000015A8A345996F,16964B0057123640,8EC42788737F9A89,4FB637EADBA27207,FF284065DEF5B1F8,E8591D0EE8B37C17,6E329A117B548BFD,AD6D85282C33D476,49E374DB6F29CBC7,F44843FC0133F43E,AB4526644BC27978,32D68574C62A7914,0000654D59806B56,79ABF498132F82B9,BC482D08A8BF5248,449B49EDC69237F3,B58802F3C7263E74,9BD648461D21BFC1,BBBB08D2BE825A85,1402557B8CF60AA0,90335387EFEC0BA2,8B2089AF672A4445,4F8DBE87CF195553,FA35DF80352EAAD0,000008481173C975,E477E2D3A15C4EBF,80259954D0167DC7,FB2D4493FD2921E8,B353450CA773DF20,8884062F887EB8D4,FD6D238E9D847BFD,9790941763298DED,F42ECC32FDE68536,4A3E88110A21EE73,55F666C63CB5DC14,EE38106662E17E54,00000B8BD3FAB7DB,BE6BB933E22E4D12,508EE99099A3B281,99AF9AF68732CBD9,BF67198CEB53C3E4,9E7BB50F0A13B69E,97C48C830A5EFBE8,6EAC95B0D760052F,D6EB3E0FD657A90E,0EB7D888165AF6AC,1B6A28B1FAD9BA54,E678CC96FFBB4F22,00005E8598CDCCBE,1399F05458DD40DA,15A7C72C72D24E40,CBDD7CCD9D6C8621,36D54AC8E24AABE2,0445B8F6312E70CD,9EFEC97D21A77F9A,621A01D16F98C5B7,78EEAAC7115220BE,735530430ED61B01,2E03B220170E5705,93C3A78228EA316E,0000360EAE0EF227,8BCD9AC6037C23B2,C1D826D3F691A1C5,76A47613131DF9CC,FF74753156B5D195,99B9EAC3F8F4757F,A4CA752AF0418B4C,1FC401DC31D13EE1,DFB1091F8154BE1F,0B5E18BDBFE4F625,5026F9DB17315214,E0BDFC830553A1AC,0000104AAD826260,3B5CA0AD9B31FCE3,ACB3413232BE8FB6,4042B62C889DA874,53C312A003B81BC3,9D5948F8EACCE5BA,C6C5AC569087B483,8E6AB2756B2C581D,27AA6484C825B60F,6F5237EE256FA130,79A5D4EB743DC2C7,B57A48C7BD4AC2FA,00004768360A4D42,65CCD93330421DE1,16E9C980FF83128A,490B85D4ECC5B8E0,1704DB57471391F9,F981A5F36734F156,9F1F82874672A448,D7766F0B7A5C9E25,E33EC0B27E712EE7,C360CA4C715002CE,38AD59870EA987A8,52CC1BA8DC5EFCEE,000033C7979BB9BC,536D598855FF73E6,B74D57777D67BCD1,5C929F20A8557C38,0FB959B98B7BB220,7298729BD9BF5F49,E6A234DE55BA3F54,F1D754F751D51F44,4954923197CBCC0A,DC61A2F334DB6D13,610FCB2C2415542D,B95C44E5FFCBDBA3,0000361AD1F594B6,715231A4FCFF246B,CD6C000283726878,7EF383A29240781B,EEF0DA7805797E5D,3F6D2AA1515C641D,4BDB81B41070741B,DC9E8A9B49D91EE8,284E0981743782DB,28AF7B9A7217747D,6B30071685D3E09E,31963B6756400E88,0000483ABD56812B,93F5E01F5DC6AC4F,4045DE821ED609DF,9709FB967501BCC0,2CB78ECC3D9039EB,90FDC2734E51C0A1,56B8BA6CC32E64A3,52C076F4493EDE8B,578DF51F3B337890,C4D3C7BA5AB25B06,925E4EEB316DB217,149E12D8445B886E,00000491FAF7CB3F,154F14DF10097525,32D3A709A951024A,F414F3A9DB261136,8BEE0ADCCC8772E0,176598BF509D7E6D,B2002C584BCB76C7,0CFA8B97C6D6CCA1,E9211485696C26DE,CC6CFAC23306D03A,176A2B4FB4D83494,7E7F683B0C3A8BCA,00000D52C9CC3263,19907024EB861CF6,3403026D24F4DCDE,E9837D7CA8D2BA14,090A196F60F2FFC1,145CE9DD3B1E9045,2A4B1A1F991FDA7F,5C4081E71676C745,94315FAA4E82D7CC,4E849D34DBBD2B55,ADC6D803384FDB73,9F4AD5E0ABCB367B,000012F6E3766660,1142371EBE9B6E0E,CF233F0278C2FDCB,9884FD6A3C288A72,A00DB3550864D4A6,D9A300E097DA63F4,C8971490C643D40D,134EE98D4A31BD20,F77D39E801DF88CB,3836E0ADE477AB36,3B2D7E50041F1AF1,3E36925B81E334BC,000016B69FA05848,8B699962E46C2516,842D745E5D476B86,1A38CDD3216577F3,67E76A637612AE58,EA57C5485CB196CE,519BC1E5323645D8,47C954297B705AD4,DA644C7456BDCB06,7DBDE1B4AA85014A,51F58C6163097428,D11B7AD027978AF2,000020A0B88125B1,3381E050D9BF59F8,B2C0C3D8C53F2BCC,2C67525F5B92070F,A04327B6FF4B6AC6,1E7E10F4E0D9571E,26F6EF28AC01ED6C,E36A6B9990DCD153,2826597B609F120A,57C91EE9D8FFA40C,C08C16640914D69E,316FEF6FEB1B33E8,000000052607B30C,16663B7BB7A08C2B,E8A4E2F874CAC141,C3B62E38B3B2612C,5D5B848F767A4B92,468CCC76B18B1F9C,56688F4C34131371,7D70B327721EC20B,06510132C9317922,8BC1F6F33CD14823,D1D5853397A1C8A0,9918D1CB6A5AD41B,0000490F29E4D4C4,7D2C70D2D821F8E2,5F85BDDD782F3B2C,450B8118AE89EBFB,44117D3A57CD1945,CE843ACA2597FF01,B4A2D27E2DD74452,80BD07B3947F2FAC,FCDEC3D9FFDA7CB2,D348734E8070BA94,E3A613178D6FF4A5,31A99F0A85D2A297,00004DF5CF5E625F,F7184F01FAC4D803,B671DEB13D4EBFD4,9D82DD9268A70A56,B1B37CDF3EFA291F,53B6B87E4AA2573A,F4CFAF8F760F81FB,CA85C047AEF71D94,E12D86C669702944,EC5DDC19893851A9,F2F6651454E7B29A,650ACE3DF4FD0AA9,000044814561214E,89A5EA204ACE1983,2BEAB9A5F15291CE,9ED8A48897BE2325,DEAA0035F57753A0,8A2819F2A1B9145B,2C572AC2BE99118E,AC59AB8AD3843F3F,A25A220C0A329FEE,BE57D711901B1A81,CBD5164F4F2C6021,5AA791A85540F49B,00006ED3AB0DCD8F,AF06AF10E955C86E,7539D0D6E5B24379,CBCA4DF84933D9EC,AAFB1A55FF8B9C20,65CDBA215DB21D30,6B3C568AEC6FB597,27EC5EDF3C43998D,64BED1FF9F1EF1D8,5BE339030FBFBE6F,E07CE9AB87DDC200,F6313290FE28F2B2,00002F2B4B5A35FE,EBF4A142C9E2EBB2,293D6EE128DC0887,743907E5B2447497,6C477EA1377F19BC,15F135864EBF71DA,D8E6B78C9001E02F,304EBA61EB614776,2B7BDAD493AECAA1,8CB4FEAA24571548,FB84944D78610E94,A775C4F41FE1EAD6,00003C29376ACC9D,7BA732CB1B542CA7,82ED49C0C9ABF850,24797BC5EFA63F57,DC49DA0F88E7E498,FEF6B429C3C6DD07,8A4E42CD9D6B1B62,2BE6F0CC65384AA7,ED54482195E752C4,69CBC3B066874FD0,B05410F77A717C10,7C3A3C415D05BB88,000056D54E35F7D5,B8293C5D1D24D05D,3478126347013187,C6B8E18527E92EC6,3AAC5BE12DF57B07,C7887D512FCBF471,AB9DD64E631819C5,F847259375A6A61A,C851750368BD2B8E,B74705601500A532,5FC398FE0620F258,64020ADBF85FC1AA,00002B9EAA7AE3CF,532EFCA47440EF39,7CB034668D565FEF,AE9455A79CD589C4,6A455BEB26DBF3F0,CB3CAE3D2DD699DD,77AEB5EA6A9009B5,C6D75551660D71A2,6513106DAA2B75F9,D15FCF6015C0637D,07DC5B9F0F3C3F9E,506CDD329AEC8625,000047624C044478,E78CAA6164F4D25B,AA0A9D90A18EC8B0,1A6AD059DEBD9F05,06046FC27DEB7DFC,F7DAF3E8BFA5327B,91D5EA2A0E21ECDB,1A59BA8BC98E5DFC,D3EE2A596440EA58,1C1D4E7DF483E281,A435858384D45423,2C8754597FE0554E,00004A4C94EFC0B0,4EDE1B3A76D9311D,7E65B4DC7A22EB6D,D7E76C29815AECF6,540AF9C62DDFEB84,BBF89639DF31D060,0214EFF5A0374D44,87A7BAB08BB9EB22,CD9FB030FBBF5A51,4544F041926F69A1,F5DD9CED697C75FB,6A4808EB63593B58,00005D445F4EC9EC,CA7ABEEB0A9A7C8E,8F0AAD7AE89C6590,8DEA6EEB71B59A5B,55ED8198D4FBE7F9,6A959FB10F8F1ACF,8F537B1000865253,DC57F77BFADF6AC0,F441456EEFAB1BEE,5C3E6C96C4B804B5,2A0BBDAA56BD0D61,3764F1F638B48636,00003157BC7657BA,532DFADA632A5EF4,87378D625AD85F1B,6F76CC51C5BBF208,1B28EFF62BDA03F6,6072232ACC44EAED,79CA38A938AE293C,66B3F02FBFDE77EE,C210C31C03B4BDAF,A045DFF141B9314D,85F5604482D064D1,29D0A9FA99CD5BF2,000029D2C99F0B9C,2E616D95C4F6A7C6,E07B898E4045F2D9,DAC3D2B401A1C840,DA0899FA8C34C79E,CA97C892CD9E6E8C,CB162763CD54F1E6,E09FE517331C8287,96522EC054E9F94C,9A76CDFC61710A04,46410E0BE2E9AF45,68E2D6BA13937A6D,000011BFF9304AB3,D956E72B3737C43A,A75A53F29CBCADC1,A7CEE7B64526DBA4,0FEA39A7F786331E,E3043F5FD6DB4C48,F78EF999D2294727,F8D91A8F47643072,01C5CD032FC3C396,0E1C33308A69508E,256414E4E81FB20A,07FA814601D09258,00003F0DFA4F7DE1,EF0401BA332EA21F,49E6826D600FEC7C,5E9CBC05591075C7,01434C4FEF135A8A,A5FC4F8C94760F83,FCD8AAE3BB47D93D,F07B872063FDA32C,943AC63C3B249165,6D4C162E950A56B0,4FD118E4C9F0EBD1,A21C21B331BA1209,000043AEEA965F94,17BFEC32F591BA0C,701A71C5AF74C883,58A29AA0602BD089,3A46B9668C04E641,774266C3DC345762,1198297820B9E50D,2AF9C98E683C98B6,09E6F73817805C9A,49EDC4D8C425F5BE,21A1AF230B871186,E80ED1AEDF3894C4,0000282D5A2E46DB,93CD1B647B8E028B,1AB4258EBA3EA274,8451BE682B8BDA40,9C14067B5E42ED0D,18A894E4CACCED86,4F33B92516E5EDB2,40FA95C52C7EBE51,14F84795201A467E,2CFA1C2E39EE8FC9,1D84FA8325879DE0,826829E2AF500948,0000213099442046,EF7DB563B0497EED,9221A39466A52398,444A33DEB1E7FBF4,838D570D7E54817A,30C56EBE0525C546,994A11385ACE5127,DEBDBB7EB1DEC374,B08101FCB2BD8673,65D816391F7BBC91,AB4B5FA76EDFAC68,BD77015FDF251D77,00006CC1EECF0937,818CCD917B984C99,6296CF9D1C4745D4,1A06ACFD40EF4475,F25FF5D3F6293BC5,D3BAA247F1093166,EB92FB31751B30B5,D4991B7787E158DB,9B5A29B5A4494609,CD3D8434F6DD1291,7E0A87F7EBA31368,D98F36F7166ACA07,00002FE6C9C64FE8,54824451858A7F38,5A452A782C2E2164,CB01250016BE669C,EF7BD3056881B9EA,625A8C9ABE13F48B,0AA83578155627FF,E05D5FE444AAF08A,ECA5E862CC001E27,FF76C2FA3FADA0F7,7D0953DB512693B5,5A1D38AF2574DDE4,000023656E1A694F,47F003E724CE0CA1,0D4D8AF031B1B3E5,3F0DAD887D65E76A,4E1DE0FED1C12BE5,E68A2214BFCDF551,28F0003DA714FF49,BFC3C4A059341343,D992062E4D5F35C3,F3340E0559B2A5A9,689D1AD05FC7E8C3,B5A5089E0E8841FC,000025AE5E5F185D,D6C5A83F749881C7,E0A02F13CFA89201,2952B2F154353A80,FE89FDF01E72B8BF,A67556721B14149E,56CE7F536AD89667,161BF81118F515D8,0FE0C911ABB49846,1C1FED929FB59A8C,8D469BECF802DFED,E687D2686FA7AFC0,000057305778F131,9C78E7683F9F866F,BCB5DE3AB43E20C1,7F2C38D4829C08E1,1CC2EA00949A791F,6A64335E27E75002,2C50A447C9E8592B,6779DDA5E3AE6F39,2A0604644CA1B37A,75E37010C50F1FCC,7EA309650F16FBE3,7EB0E70ABE635E76,00001023B98029BC,8E0308DFC2E0C820,B8E4937110C2B8BF,512BAFEB9E4913CD,831F43D6A8344E40,9498F11C0859A26A,6C5991DBCABF0E05,E0A57C25DD202C03,45631483200C5DAE,9E559BA569BBDB54,B3F4EB48A01B90CC,EE9336C77F6976E2,00000EBBD3DE835B,4079B60E61D4FEDC,04D8D80D50759E7D,C67906F6F045ECB4,FE4ACCDAE9A49520,9D48E0746944C4E5,B3BCC6F4579E152F,208FC77FF3F91F99,DF77822BA2371BE6,D35044EB1BB0333A,E959A3C88E85A7E7,04F4CB4108E282B6,0000640A21A59965,D5CBB0BF8CFFFC9A,FDFFF92A4C62FDD4,B2C1EA224C675114,D0AD9E1A0B5D4E67,7E11C207FFCABDD7,34EDA149DB7DAE03,37303E5B73FC0A3E,47A1B6273DF2DAAF,B60309991C97DFDA,8FA517F532B30A46,F5E82E3FAB882066,0000684AFE7E0E56,9DFAA4053CA07EB9,289D170A5735936B,F5CCCAAC880F31CB,631667A4198803DF,16A11CC7602E7FDC,9002560F8069E8F8,F14EBC33AE72D4A9,648593DBB39DF133,9EDA849726EEAACB,446AEBF84B887B9A,19D77954A2473309,0000498C5328C1D1,ADA4C75FA2F1819E,7D96A84A8E9873CA,074F78F1786E0CDF,AA24E96DD7B4606B,39B5E7455F1D2246,F2326E2564B6998C,BAC16EB87781FA77,A2A7C1AB51930F15,FFFA45CDF725A5FB,2B6FD6035CB8B711,674930BBFA54792B,00002A01E07BFDC4,F91F552668E689C1,40FB06BE49222C2F,F600A6752CBAA154,417F55E461CCE649,E8CB12E615A59AF4,202C3230F1073C81,4073C21363D513CE,ABD120C51FCC80E9,D25124795B0AD76B,8EB5C9D9FE271324,7801B61A1C169044,000022B3B900AA16,B6FFA0676E90C8A9,2724A0E2D40BB6D6,4A47B48F0BB5EB8C,1F48DC36203F4611,01FA7D1013AEB364,25EC8D75CED427E6,FB3EA26EFAA4BA4C,EEC642701F256EE2,FA26A14F61075554,B0D00DBDC23B9034,9CACC440C206A6C0,000003A1136E219D,A1A22209910D7520,C9C055D335BC3F28,E972B6DD4504804E,826F90D0F830781B,852EE72EC5791048,BFD24ACC8FCB852A,3AADC574024671FC,0D0FAD4FB6298B3E,D1D6871307F11109,B1AB6D3835D2BBA4,222F35EB82077987,000064CE58C1C66B,AF7F76C8B45D46EE,1AF174E6AAB4B9E9,8B606997EC95A8B9,11E30C37777FC122,D4C86B57CC16130C,EA3EBF1C95D53AF3,C2EE508DD39095E6,A73F0F63F68D93A8,3C99EE884907DEE9,67E33BD6DEA1B0F8,FA323C3390405F50,000022E59CA357E4,61BE607F32F88524,35B50D03E6EFEE3D,EAA9DFFB7CF2D145,988E2EFBFC631132,BA24B98DA66EB7EF,C65CAF8AE3CFFDA2,193AE0B2054C0C4F,041B39CFC70F8BB0,2FCD9DF589FE8C82,EDCA0BFE0D858C8B,BF80F01558E6FDDB,000048194113EBAB,14F5292C7F4E15C6,3112FA8C2DBD250F,872EB72CCF9456FA,1836A551CFDB1844,5E79EA8E31309DAA,CA25C59F1AD72043,CF7C62FC4B12746B,4C561AB1AEB006BD,BBCAD71747FFE94A,615B40712A035CE6,551B3C374C8FEF05,00002ED04CF5E072,79C8954C2EE17DD3,BD8A537778039B66,284633AF88B9EA98,082FFA5562F3679F,1392D6CBF8DE4E81,2DAEE64C113F927D,167039F6A88D0F4F,2AD7CBBF511AD0B2,858E168DC044CD24,E3D165A0ED4E5E2D,56EF3A9332735C0C,000010BD895F2D12,47F56E1565F8C065,9F667F6F94AA947A,EB34DCC14CAF542B,0A8499E46CB0B3EB,3C44E254A1E9874E,F3E0CF96605FEEAE,6EB787A0D3BCD288,276964B92ABB68AD,74F39FDDCAC1F986,D2C2C321EA84F0FF,BE9C5B432D998E5E,000027E93A6A5AE5,6E9586A86D445BC7,011C5154E599ACEC,27F5CA50C1765844,BFDFB4EFC13E1E62,9E9E6295B5125EDD,62853189427F19B1,1D1E20F04AD7BA4D,50E74F37C453CC5C,BE2EC9CE218EDC35,0257AB062BD71F27,1F3EBC4DA5A99673,000046167C5C8A01,7536C54AE340DE38,98E9E5EBB4FFCE09,48D8791061531AB6,206C8D2EF65B6571,BF380445C4F8FEC4,6F1234FA282DC2C3,E693F3FE0F937E04,532F29B8AB6514EF,78538ADEAB7F80F7,2385BB48C748E234,84E05AE764D56477,00006ACBC3F36456,05B9D967A46E25AE,08D141BA7C172FF7,6C047D353EAF6F5B,BC6A965876F18F2E,4DF40BA492C4FBC7,02AB7A00E12B7DBE,8214EE588FCF454C,8DE7ABFB00754DF0,2C66A284AF118811,A75FA40157D8CD60,2871A68378EDDB3A,000046A004437D2C,655C49BA23558EFB,CAE40A181F7BE3E8,D7B227660E9AA2BE,1C275D42F1807FAE,563E1C6AD769A91E,72256F56A8402523,1B8183628AE2B73C,3778D8F276BD0E4C,C55528261C6EC1D9,33D5A8750EA1558C,6540C90B809DB3ED,000060C4E4EBADC5,62144689B76A476C,4082C83E5E1391F6,27EB0288C78343C5,F831909E1C391DEF,B42B9045EC8F028E,DCD637AC801B12CD,B16BED7C3810E384,0CF72C030EAC1EE0,345E20F8D7B1C4A8,C9AD6457939C7A6B,3EDBD0938AC64B7F,0000261D7017EFA0,2F5ACF9BC8F36BDF,3D99197FA896A708,25377B751923162F,160BFDFC502100E5,9D23E431843525D4,3BC9E1853216CE49,0CF1F01BDDBEDE8B,9FF6CA9B0A6BCA3B,7FEE859937F9784A,7AF9B67AF4B8FE2B,D5FB3B515AF929D1,000064470BE2CA46,7A81550B2660682F,B1393D42A006012C,17FFED70BB102D7F,B6940339FCC35845,6C1CBD7204358B5F,D51FFDF45B293873,0A52A5054CA628B6,D4BDAFD03360214C,D95204A06F43FBE8,0D9BF4CA90AC9119,3512120773F498CC,00003D0C833F9BB0,0DBAC1A4C2FC477E,05AD25EF0910837E,3DF903977CC948D8,98817C8E5FB7712F,88115868F7FDB284,6F5586B3A1BA4DEA,FA5770B15558B655,347F90D76E87E6B1,E7353DE753DB4933,155F66A014D948B5,BD5E069C718D6AFD,00000E4EC81E954F,FD96A45E8FEBEA45,9BAB7CD5C70D07BA,1EE82DC28B071B77,C5074A0BEA30A76B,788DC32D328A0410,33E222131E064362,5C1DC015B16CE80A,48141310A5EACDAC,AF24BF200A94C927,7021065EB62B3B75,EAE335FAEA8F965B,0000411F95D6BDCE,3EB0968798CFA977,7456A0BC339CE82E,3864EE2A54C48884,A79F3E7878B0F050,9039CE365DC95B56,FF4956CF8BD0AD29,42A6AE89C1844757,149CDF447A86F8E9,D723A86ADAF812CC,1C0CFE4732C0C484,F3A9D7C7A10A7A0E,00006616E51CD650,97DDDCD7D72267FA,21AE63E396614662,0116437590D74B6B,594580627E4C5ACC,E36FD77BE944D820,194BBF6AF3DF219D,8602156597910C2F,94B3BAE8DDF97690,06D7155C67A1AB8F,F06D02957DD8AADD,7EFBED7DB0A34DEB,0000297F81183341,D131F525CCD5FBB2,901C654E3F3FC2CF,8A82394C8BE2DC6E,106F5305E32BE250,4A0C0D1BD9F156D9,300B288BF2B8AE51,A3CBA0F701446A16,EBCC07738E4D3E85,BCD72197C9BED26C,88AEDB22EC32E6E0,D2C72D4853EA547E,0000375CF6515BBF,37890F2813EA0D6A,0BB29D720BE11507,D4A8DFD909995DF5,EDA156A313A582DD,BF0CFC855958CF3F,B0C664AA76C8FB4A,DBA36E5BAE5407F6,40095D760C4A586D,E936635AF0FA8186,7E1D38CB2F85879E,73A801DB35FBE750,00006ACDD141419F,023B9D79EB71AA23,0C654E36A42D14DD,35D6EB17C79CCC67,66BA6CCEE199F315,5689D7A30E237FBA,2B6CF1B90E1CAE07,4F50D5A842BCC085,3633C1BE17CF72FD,5C10DD6D6C1B967E,B764F3897BDC1886,1C18FA189727C40B,00005DCF40B537AD,64D0105C37E73FF0,AB6EB98BD0D65497,02C9544A7FA392C5,2E1160448DC798D4,48C0A00480B7C22E,841EC361B7A970E6,4A7B20CA12E99297,4B57D09714CD5BB5,527BE06C32D25FE9,9C43D0D3ED88B560,38E4587BBD87472E,00003523879D5FA5,87A829397E7D2B70,BABBBB928C6AB8AB,7F91C6391E3640D6,11F23E323B5ABD86,7F37A05B5DC67A37,FF36FA158D069A80,7066740660299904,82B3EB9B4745C444,02B2E6DBE949E371,D4D715307111AABB,8BC23CD3B7E0B058,000048FF4BF8C252,2045BFC7372FEB77,EB5F1F2D01412163,95C067033FFA7669,71A5CCC2D08E4EF7,C5670E5A88EDA20C,1F5D29190FBF83AB,E8CC54F52C4997CB,484F0F762ADAE997,4FED498B73C949D3,B8BB1E941820F26A,DA250DE5F20D4ADE,00004C0A27B5BBCE,B3FBA00CC46272CC,71B38247DAA3966E,399A67C33EB2571D,0159AAE731894485,BCA55031F9566967,763FCD348B877602,8872190844B6FE0C,20BF3FD56899842F,D2A111AF25E48C0F,BEAF66479A093B96,7FC5D059711E0ECF,00000C5CC65095EC,736B4BD254453CD1,AD396D8C663AA80B,1E03203D359912CF,BA5EDD7179969530,3680C0CD7FCCEACB,FF6C72E36560F012,71B35CA0CE021FEB,57CC3DC0D1730971,B138666C3A0BD10A,610707AD7A6A58F8,2C2F9A28BF23759E,00006EF9B173E5FD,E93931001A2C59E5,79AAD9B9397FB12F,458FB9628083F27A,84E1782B9328AE62,93C3C81A612040C5,043851E2AAB6369E,46DE11ED3C41F805,89F6A77BF7EE33DB,B689E84D083E67D9,2B460E95D900734D,43E56B747E411E62,000050EC325F37AB,23B67C9992E7E61D,CA7B0A18DEF9277D,9590697C07646C76,03D5FFA3D066C40C,18D4158900D21837,92847E7F188478A1,4F44762C86C77E53,0EABD8259ABD5CDB,93B1207CE7216413,879B8A906625F266,D57E5734DADBB74E,00001BFCC07909E2,9041C4F74FF4167B,7A34E2C9D9FA463A,7E2A83D173B02C33,9446D9E718615AE2,CDD1B0FFBB9D66F0,613DD6DE9C4C18D5,A244E2E5BA40A973,1F5871B00201DDD9,CFF04F7C0BB5E27A,3C0994018809AA8E,0C04C3E8A54A9419,000067404B52D0D2,4270DEFB321AC5BE,11F1A3CEF574FBC3,82A7922D6AA177A7,9D019A366096A093,F30BD5126D03FD6C,465054E95EBD76E4,A0320F2653DACD22,098DE95EFA1602E2,52D87B7B4A318349,568D05FA26857F0B,7FA740801A60CA13,0000475EDC60749E,723A5D9643EFE275,0B1FC5882E2827E7,0A72EF22352FE5CE,F79E0FD0650557F8,9CFFDBE27DE56D1C,ED380EF5DF22C275,6BB479855F028999,37F3F39EBEA750C3,AFD3620C990DB6FC,D4B465BEFDC031A5,6F79A5AA2F682B71,000012139803797E,EB6E0D2F07DE4828,D1029D5C5056162C,EFEAA3DA53382D56,E9EE12992147BA0B,6EDE72D13621730C,27DC626B7411F55A,012734EA379B9CD5,CB63015C532050E1,F506C36B3E42CA87,5EB934F2835C3400,A133509BBDFE79EF,00000BFF01EAEE9B,5C24E9C70C800D76,62668CB7BC974571,A69151B7C5D3EFDC,F72508B2C54CAF25,3E5A7A295AE25E29,46757628A45C2B5C,4B7B6BBE755396A0,077243FBF4EA793C,00E5E28C906F9D95,B08408028AD0F0B7,25C5CA6E3D999392,000064E5ADE8D94E,718FAEFECB296CC2,CB3DF6AC399AA6B4,0A6338E48B4B3209,80C8EBC127550558,858F47878B0E063C,35774F9F0C7F9A57,69E8343BDC9643B0,32515C6DFF7E8B91,A1C2B096D359414D,8ADAFAE09DB80DF1,D4D3D7AE7E470DB0,00004728892A88D9,4DB74B70D1B522DE,03B7A270B279F571,3097714BBC190428,F9650EAF75CDAE39,1FFD7E7136BD2C6B,1E5186107C0F22CD,E154E52B3BA43A6C,A2C71B16C2295674,EEB5643BC03BA25D,FED366D5F564521F,C36320D9977942D6,00002F7D441DC0FD,5E523DC646417874,93DAE6331CD2444E,888E3FB999BEA9D3,6536A9F198038824,997FEE387AD3865C,B5CDD6873550AECC,4BD0B6E8492C3D08,B47E62781771D7C3,1F7ABA47A461BFF7,218C410BA1ACCE3F,7C60E25BC16AA662,00000F26BE890ABA,A93470C0B474D7D7,67399AF01F913266,A702844C3B0F2C66,A71706728FFDA4EA,2FB88C3C75C7066E,F76D48AB356AB931,A8496E7235A3050F,6C5F7CECF76340A0,D213704211DBBF10,03B78C5BCA6A2A40,E8B1151191792645,000017C08A4432AE,6EFD790817833491,04D56D1B1739259A,150894F03435DED7,74C9C7F68C129EE8,178000DA3808590D,EC95026B59B8682B,4ED8595ACF75BE2B,68C7A671DF91926A,BC90BDA641857165,6951BB7DE6368598,63E3A02F2CE09EBA,000031EC3AFD0B2A,359A3A0C8CAB2933,5316D692454064C2,5264E2DC9CBDD657,4F5D33B9DDC2F3AF,4C5FC4DC7CB2F0B8,E7193E22CCAB9821,4926F67FCCBC14BC,C61F4B91AFEBB4A1,32E17C403FF9CD34,15B7A6A75E6E9139,258651BAFEBEFA50,000023A57486FEB1,275D5EE75CB22D75,FF0FCEF4B1BBAAE2,CE39FDD2BC3B8E73,087ADB4C8DDFF965,2695D3ABA741DE57,FC5781162DC60127,05323F95BE4E7816,7E89ACB23E1E0E54,6003AA8399DF9BD3,42E188662874217A,C57A5E175EE59140,0000067C5A2DFE2B,687638137461C41F,6EEF41E578B6984E,0B2FA27B0F619B44,A059B62703C02DF5,9FAA24BB70C222F3,EA1D0657BBF92984,C0CDFB421ADE4EED,D15B6D2A2715A63E,4A8386378DA8456B,8BDF7E8C205665F8,D83383D120B12A4B,0000281D7A04071D,7EBF98DC33D5AA6B,0073B3915B80EC22,1B9885FA41D228F5,31675B031BD75766,269847BBCD25D767,9AE6AC6028D90799,AA671210EDB6EC86,C8D24F5411AE49F2,E9BA098BA2E435BC,3F352B0C8673BFE8,CCF277808CCA89B0,000062FA71F9F76D,5D6478BE2C081F9E,9DC7CAC6BE6CEB6F,1B814A365DFFB38B,6AE1A841E59BD2F7,71DE3DF88D5F4ABD,5A1290DABBC5326A,3EEB3E6BEDE19293,2CB66BABA8018C0A,2A86928AE26B86E9,02364040C6676846,A0777D88403718DF,000059744B6E6FA2,D322D971D254E9B5,422B2383F199D7A8,7F6750D07AAA4470,72C170FF3E147E93,2962EBB7FE420C15,9958B333506C0031,C951BFD73B7DCB47,C232DC693A71149C,1B5CDABFE38441C6,A3BFA9E8C2C40E36,3B2BC0DB78D97050,00006ACA80D1005B,0441EFD492EF3168,385A709A741B9BCA,1ECC739928F6185B,32D8F474C04CAFD7,5F2BE813DC9D4678,A89E3722A9DA3936,7CF0A06C2D2DD080,F8FBD70D3A9BCA54,A1BDCB443C32B530,D99D9538B9C4ABC8,1EFA7FDED9789184,00001A7129B6BB8E,8F0F26B7ED8343D3,026EDED3BAC55C8F,EF2F8D69E8C9EB0A,DDD693A56642EC4B,9B5B2CFC249970C5,CEBB7EA8C2B0854F,91CFB69B2DA35C4B,9C98973FBA6308F9,B88AC96B9C436C9B,6B00514D77383AA5,643F0CCF4B4E118A,00006B2258FF075C,1DDE2DED78770A07,EFCBDECB18B6F735,EC883DDB4E33F59F,254E426AE4B0F8C5,7FF7AC20ED19DF48,B9D91C0A068DDEDC,174A262DEFAC2C8F,EB01C21B9A16B4A4,95B41939D0E01569,C1AB6E951D03B17E,BBD686563F9C0BC5,00005E5990123409,BC25AF90179AA55A,E967E75874760465,B9541AB892CA932C,028E554C495582B7,55C13CA5C049923F,11AFD087FE1EE981,A6F75F83FA9D5170,E693998D46A1BD38,2FC220F30A281F44,0DFFC2D8C30A9ACD,11B70180D62C1AE5,00003DC263B2AF05,89CC88C2F436BACE,238262525494A8D7,6BF9D79DB0FC2FB8,CC62AFE8DDBE657D,85CD9F18135FE825,0BBDD7375EEF930E,AD5B038F514A579B,2081E192B30BDAA6,0764A5CFE9427EA7,182517015DCCC9DA,65767912C90841F8,000008D2E41979EB,6266A7D6D6AC0A4E,85E8B8E3A14B3D70,FC9656D38C3C621C,B005433133266052,A74F868F44365A28,92B286E85690543D,8533348CD0A4BE51,FDF25B01E6E7A740,5B5D8CAD2123823B,CA45829E28BA87C1,26F2D36C85919625,0000098F64B0F7C3,BF07CFEE1B75D986,D8511CFA6EAE6661,5C9664296345480C,7B9C130B7EB88024,A57CD9FA8DE072D7,A633BD49321D34FE,B98E6154F13A9564,78B9174C9C7D18F2,B32DCCA6C3F99CB3,7422BC4BC68DB60C,43C936BA0C7765DC,000015DCB5C690C7,DBE051FB227D592C,2766347D06858314,F6FC03B5BAB70886,548CC84133E1A272,9A4E629FF085BF36,B11AF1560EB23BCE,102530A01A4980E2,CB0CDCE921E665D3,EB858E2EB51E2862,E848A4A24763943F,C33BD6B6203ECA97,000015C8B9693595,B0F480C487703FAA,7B95806202C0520C,D019037E4B182A9B,B5D8855CDE101DDB,3A9F87BCB81CAAC6,F1CA7D1FCC58FC2F,F56EE034883F1ACD,6B2A57070C781F37,48E23238153945AA,D421AC31AA45C495,995C95A04FF15CF1,00005582BC47FAF3,E48A3E234C82E481,EC2F38274F344159,939485B7546D7F93,17614DE44222E0CA,905C186AA58187D9,D6D70A341F3A1C3E,6824CB36DFF1E077,455789FE9D4903CC,FA6C54E081DDC9F5,26E6EF00C822A2C1,4752846F0DF47F28,0000214BAB7946B6,07DC3CE96042BD5C,477A407F31BC6A40,79044F490CCD3A87,570FB1276F9A7683,D0611B496A115EF2,5698246E6CF84D21,DF8944DAC33D6267,55D08B917BF374C5,78D00B8C68B85574,01F14B03D31A988A,2FE89CF7B267D7DF,000024867FE91FEA,CE3249C220FAF28B,E03BCA224F4A463A,176E96070E2B3E86,3C7D5A77BA7F8CB5,2B03E2D87D8AA70C,FC82D16D7F65AA21,18D7F57DFF6B04FF,6D4D8BEDE16BB70D,FD72DEFB724229F6,6F7244A5BB5ACA33,BD8A9089F846B01D,00004BA1C206D740,428609318492FFBE,95129E3617E5520D,8D54D891B2E151E4,3C2F7F7D893135BD,001FA4A595502BF7,5F5AC100BBB9F469,7443B3A7AE6EA4F3,0A9BC6DBCD809357,9EB7690627F5F1E7,261DF457973B669F,2219D753469167D7,0000339F66930C51,E19F69AE7881C0FE,8FDC06834182D4AF,31F71A5D721A5341,2250A9C90AF462E7,2BBA1A109818EFC8,757BE65BEDA07C5F,4934D99C1C8A7380,92077F046AE6214B,476BC15BF19798E0,47E289E254C147CA,4D1B23ACB32190E8,000046C39EBEA0B4,1B7CB046609A5367,0C44C7B48C38114B,168E976BD7FBBC06,AF7948E7E4D26F2C,A48DD8F3C5457C70,2A9890F194744EE3,4991432B89E6E991,56E2187440FFB7A7,F605110C4CEFD291,938121CA5A23299B,AA8510230C690374,0000420C07E1A644,FE3749ED3D3F63FC,BF5F318F01F3B5E1,012636C15A51A653,BC60EB9375D7D0F2,F9C691C31522E7A1,6F019A4436F21DB6,72519B9FC1AFD1AB,4BBF55C87A3CA30C,36B49E4AA9ECE4B7,D0B099779B130F6A,9560A51BCAF210CA,000018BE09989DE7,9D78214F1D84CBBB,4B9640A629631794,2A80B181093991D4,BE8F01F17949B591,8378E7649D6F7074,9C50D9532EFA902B,F776535728B04D7E,46C231E427435620,7B47F253F5F88CDD,0C7C37E0260CCF53,8F3C3CD898375368,000027C6B9EA277B,12AAC1A10E1A9FE6,65573C4C2CD66A34,2FD047018548DA7C,145D534DBCA92002,206BBE0C6DD06507,C47BB419669A5C41,1EB7E3DF59AF412D,FFFE34FB04121591,D12C8E8BF3FF95A8,1790CDC1B17A94BB,354FD0C9E850D8B2,0000106B809ECB8C,0AAB13F468C4E63C,029E700042B34A1A,9B393B571EB93769,FED71B759C49D9BE,21B73BA7247175C5,B231686BFD22872B,F63CDC256D11EA90,85BAED3EBB77451E,7BF133D9E29FA633,BF66F78944C36AAC,EBE3EB8ED37F7275,0000328C80D8F921,6ECEC93E07515079,14DBF35536A82DF4,13C7A1049F4E297B,3B43B2AA2D7B3AA0,21604C0B347369C8,E78A93267FDD6DA3,6C877269983219AD,3A3847532AAA0252,2C781CAADB33213E,1A317FE4AF50F335,90CBA1291BE0D580,0000063EA0C44B6A,C3F3F25FBAC500F8,5A6A74BA6853F683,9F871CE95C4E5001,750192303A2D3A61,6CF8E463138727FF,AF431796A1139910,110F81E6AD554846,308230B659D0420D,8967215AE0B9AAA9,FB92E4E4B9FEC86D,FCCF67A45A349C38,000053D3249D0AAA,9F8D615D939B8483,27124235838E6D66,65448C1F0CE4CC7F,22FDF047ACA494D7,36F2CB654301CF60,526E7B6B27464154,A15B0DD51C1D4E8C,AD650DDA0AD2E2C8,98EEC7A8B623F045,8C2DD4722FCE5F48,5436F9A481915301,0000172F20FEC316,F11EA4C1FB4B6AA5,388C1BB61916AC98,60AE3E5BC9F99A91,A57BA1BACF6F221F,3A87486C4FF6F820,C44B94BF4C1FA986,164E4354AF32579E,BE0F64929952D229,8919EC37E8B56461,2B9B2457C77FFB5E,58373C078017E07F,00004DC02AAA1008,DC80D24005E2BB34,46441504F45BD0BA,9F4B732D0969EF21,5066AEE405A1F187,6900348747CD36F3,4F301A15510D7085,F3B1AA4E3680751F,ABFF4B0DA0D1DCF7,A6B10E04CD44A521,E323A85E426C927D,0C48E416CAE2F04A,0000410260677C0D,56DAAD9E754ACB2D,9706F3B015BB8951,C075B6A86B0880B4,EBB1058A81C74B18,FA70E87018462F6F,329FEB86D1A9BF07,590A1B387A16D2EF,10F7D915E844EA82,AAA3C7BB48FB7F51,0E5B7807B2B68DA8,DE9B5758D1B711F6,000019C9976D207F,FFE36737EFE0A7CE,F9152550CC9228E4,D7EE423D126A4279,C897EC0DC54E0B80,12756942CF2C2418,859390EB1BAD6A2E,ABAC2BC0AB7FD659,55D192438A4B8D20,90AF12F923A56147,3588E86314E7DE3A,0D104FBCD70514DD,0000500E7DC6623F,C6A11A2A495253AF,14DB7A0DB8EE7A0F,D2BD584EAE1859D5,145DE182398C065A,F79F2BEB42987047,64FB1E5CEE2903B9,19E3BF61AAA67111,B1023AC93FEC668F,09A4D9D275F04171,B9A92D14DDDCD846,A3918C8927060C9C,00004710406B838F,ADC47ACBB2C484C3,2C3EEA1F51AE4060,0DEDFEBBAE677384,3940784153175358,73BF0580FD188B24,3717E56A54773AFD,9365B0BBEE7198A1,7DD8170420DED895,C9D432BED6B3946C,344D51333A924CB7,02B20BDD09CBEFD0,0000593305763188,FB224FCB5A3F0C8F,CF98656DE146D4BD,65E75AEE102D21C3,B9193CC3663DD242,DBE35D361EFBAF86,EB42A516BE6BBCC8,C4541B25C1F7FFC6,A19DC9EAF30BBCB1,8132D4435E7A1CA1,3484F8C9DB135D20,B4CCFF55196D1114,000057E26C5DAE17,CC2246B370F91BE8,74C7A7C5A69FB812,A9F60860A3143D4A,E8342B1F9EF7F72F,C5BE88E2C4488527,4B817813F7C2D6A9,092E4F1FEB012715,A31727E5217B5733,1B6FCB6E54452BD1,C089FA89FFAF78EF,E5660A1678D391A4,00001AC4D5EB00DA,89C366C2230E8174,DE278E49662A5082,0BA767C657C9B1B9,CB22DFF405E321CB,EF77C3E23A8EF035,6331A7E5F6C12F2D,B3826EC59B663064,71EC47887A6ACF3B,CCE6A0090E361C8B,6D92E1AFB89C0933,CDBABBE72DAD89E2,00006472ECFA9A56,D9D9A92D7AA685E1,22EB62CF33011AB9,BC28FA0C9B0EE005,01B665C7A2E4F452,7BE7BD168F1285A2,B7F2822CBBE243BD,4903E22CBA84B250,777B65CD54A889A0,880477B3134A44F5,85759CA1504E0C39,4C20C5DB360FFEE1,00006A8225FDED26,C941880C50A685F1,018121AE24F9940B,77E74725E9052B57,69B40599C87A0C9F,6E85C83F1AFA1E06,92D0B32055F67454,D99BAE005DEDCF8B,361A0DD7C37942C6,652F33F2D0607084,C4B9FFC7DD87A7A8,68AA6044826FD5CC,00003A87AD0B5956,9335D7EA236C7F4C,06BC4B36BAFC9852,95576757AD0AD885,7AFAE114941481FD,4272627DB37EAB8A,68ABB38A1F9564AE,8420A8D10DCDEC2C,56F0EC5920639A86,F8A2D53F6AB765E2,1FD1ECBF9C8E0BFF,2BA1B2D3C35F4797,000012067A2C053D,C8A84CAF532D7FEE,50BB0B6788E4B788,8FBF7DCA0577B22D,641308F52E6EA173,120F8704A56CB74D,9052A61F9DA01ED7,C3C39023C108CCDA,3DE6F0154F6E6FB7,81438B538939C565,603EDCB326F6B44F,FF756061F6290419,000063D46824AAE7,B27B4434AE0C8C2A,2395CD99B2906C65,F00AF07F47325D39,458AB78E43C0BDDA,9434AC4B53DCD7D7,55CC0B77D18A65D1,FEB758E802E1A8FB,BAAC2B289ECC52E2,9CA9AA8BC2F5EA23,490A2883E1CA9902,DBD7F940C441C41C,0000645B2E994910,5887E2F40DDE3B15,7F80DE000962F2C7,A7DC3E44C9A5AF0D,35E2BD305456CCD3,67488431680FCDEA,9F225A95C44AEB8C,2C329C784AFE1A25,882433CB6D4FE089,ED13FC6BA8E161FD,1B47FB4D58530762,9EB52B4567D72ED6,00005FA08D53918D,B3B40F5779AF0C6E,3EE02C2D407CAF83,7D1D0CC5FD79534F,0386627C52D40EF8,EDECDF00C276ACC3,C56DDA6DD5E35B84,21927D20B0B6F0E1,F9035150E4316555,3409D014C3AE5E58,E1CABDEEB6C23968,9F74AEDF17C31B63,00004E47EA8ACB14,ED2C5DB98E7FFCBB,3F74A3C23D9BA398,4FB3C6DD7D7CA632,36ACCE128B8F1CC3,2847BD6902E474DA,210EC68410D0C13A,67475D909E0F12FD,45962C46081C735B,CE01E666D57D6C0A,587494C1A0C2B81E,5EADA92FD4B2B475,00001CBB3D8528FB,3F73098D973FBA08,A3C9F5E22F122FA6,3EEAEC234E1C74AA,B92CA912A3B3467A,BFA197E18245885C,C71FFBAB76118C2E,84A7B6FA619702FE,4C854BECFDE02DE4,DC6A0DBBC261370B,F01452D26E01AC3F,39D42A7B52E01BC5,0000518AC3A43BEA,2DDD495143B7ECC6,6B8585A0A82032C1,73ABD8EF8A06BD43,9579E618939895A4,8083FFBC97127BBC,181FA9101DFF7DD0,3ACB3A6C341B6DAE,EF84AAA734983134,00C730922ED7F969,58547FECF8DFA848,D444E0F99E7EFF9A,000020D77A7778C6,324C89C5FB4B82F7,3EA9C03F842C86CA,ABFC96715C2BA090,CB8BA66761C71308,F4A3E3455D6BAA96,18541EB6AB108281,EF66C6BA7116C93C,A67B4788B4A4C7F2,BCE9AB520369481A,AA6F695C7DF4A74D,6698C8CFDC9413DE,00001A0BF2B2385B,C5B4CB9CA950D5BB,22DE2FEC279C0A48,3824DCFD2AD179C9,389EBC7782E73E3F,B9CBA665E01E6F18,422D7A0BFE6892B5,52B168A0594C7884,E4F17C02C0C0DAE3,E47C14C883B33EE8,3DCAAF4129E45608,03C8403D94EE19AB,00000843BDF507BC,42F8B6FFCE6A70A7,CC61746EC679CE50,64B02D84CE499772,0AA98769216848D4,60CE23C2E35A3873,A2140AD0C779AA02,D3D0B7CEFCE12F42,077ADDDBD69EEAAD,1F8F11E81766ABE5,EF7AB14326B2A8C5,C9D8711B117EC5FE,0000003F49D9565E,5CD10F5BB5B73C46,81D40EF679A889C7,6A9A6A778396923D,B98C7C95F3CE3821,A80411A86C233471,5943EE833CB6D3A7,35E5828A365379E1,4613926B2996E5F7,580838E6A32B9E34,BA2DEAEC789AC5F4,EC32BC4D997DFB2C,00004609D26AC8AB,0938079CB61EA29C,BA3452B90D37BF81,CF496E48499B41E7,74854A3FA1460885,1188EBFE0B7559C5,F0346BD302B9106B,317290B8C6B03CCF,300F7042C3BE6EA6,7BF92047F3ED9874,2AD8F4D76CB95B62,BFA5CB1C387B3F1F,0000311C22205126,91847D1672E3C989,661BD82470724871,39C50BF19B63A1AD,A483AD60D8EEC58A,53AC725520DD25E5,082E8780665A15FA,BFFE66DED399A1B3,A8F8BC9B637A83E9,31AB4CF5EEDEE446,B8737CAE3297E12B,287FFE6788A1F8F0,000022541FB01FA2,196DE24D7DD6E602,E6FF247B01FF33BA,BE2BECC15648490C,4529F73D97556951,F8FC3655E7103F36,10FC3F7EEA3A3D7F,62B4E6E9996FFE86,A32D3A72C75F871A,84AC1135D6861339,60BA4DC9AFCF9BEB,017C1C1A57747205,00001ECA4D948C83,572B703AFBAE848D,3E1910293CAFA09C,DB155C1F15872A81,5C433AC700D59CF5,E68FDE5E36139DE8,508D846291F0F8C2,A6DD7C460E8631F4,73DB25A04D6BD11A,13CB9B3835B34EE7,C197410E586334C7,40380AAC745F1CDE,00002DBF61B46F2D,F5C6989B19F0BA41,63E3602C9CF28927,E51D541B4AF20E32,3E3EDA554D854AA0,98E492B8C0DEFE8E,3B1A9DC7240B2598,B3BB656EE2A99E2E,885ADF12262FDEF3,9F4AAC10D76514DB,9DF2087E6976E156,47F3253D73953499,000016B22DDAC488,7F9F447CF768C0C0,D19CCC5F8B8327F5,19C086DC30A25BDF,ECFA7B9B29B2B1E8,D73FE3920E24543E,4E877A6D1A728550,55CB437CA9808323,18661376F835834F,31AE6262FD9BC070,E82FA6DADD43E659,57FF5690A8D7CF1B,00000607E76131F1,E9B94BF5059CC064,7694D1C0D948E46D,90C3227089E6298D,7E1B566E2B353D84,E51BC4297A20E550,F7B0C54C3C0B48BA,B1ED08BC87964E6B,F0DB031CFD766001,CFFDBD6FE4742207,420BD363426A601F,131ECC6D9C71F9C4,000004F226AD2A3E,0D657454438968A8,281DE17195EED1C9,97F79CBEA8DB56AB,83CB9D9D6543C4A0,6FE3B44F09531928,DEAC051DC46B384B,9A3A57A24456CAC5,F5F34E4DD97DC1EE,2031E5FC181687F9,DE747B0DCEBAE802,8F25426B3346B365,000027A5DEBEDBD6,7657741C30B87CFD,0D4E5BBCBDE5C68F,E5644C1083FC880B,994D1DFB6FF37641,D47CA7B119B547E9,CFB6E934A94FEADA,5A87CE44275EE1E5,FD658D21AEA635A7,13DE0D46FD184A67,1488A27BABD7E45C,66C8282770353A02,000059F45A6DF4B8,4EBAAA3C4206727E,1ECBFDBC008D1256,EB203CF4417AF5D9,7EB0B00CAD9DD82A,DAF8D9C7ED1201ED,8A384B4F3B726A90,51F07CD261C51BEA,BF993F18542870EC,413C600A00642D9E,9BC44A300586C51E,D8F7E14D107799B9,0000491EEAF0FDD5,808A351E59B8B4A6,BBBD354A396D48B5,CDEA2F91A97BB7FD,72271F1D44D3084A,F4382BBF85B9B75E,7DDF0E0AE7E058EF,A3F2854C95D53AB4,31235990F779B212,385D32470B8A5D30,B3689E9225130D4C,42224DE4B6E7BDDF,0000633330BF9181,8CC3BA66D8B28161,97F49600E185BACD,791CFF474805899C,90B379608B28D464,FBF38C0E15D2826E,8301FCA1F49160AA,581C01BB1AB0B836,07352980E4FB979E,9527EDB63B6B2E62,828DC99B0A5613EC,CD1FF707BA53884B,00004872169607D0,4DD289FE42852813,0351BFD0515C31D3,43E75150B82E1139,33E964DF1E205604,2686B691C22D2802,E1A52BAF19786B26,0930D2B94B81C829,4FB26F08EB8B6AAF,026984475EC23094,2569D0C8346F48D5,43CEBFB9F794D091,00002439419EB28C,ACE8C692AB030F37,E3F07E5AD4EB42D1,1E9BCF0D5E899F33,6CFEF98FB94B4A42,E4A373FC156DBD63,4151D05DC80EE92E,CF2AB2F2EA97B32E,E83E933F9A2A00DB,FC282E3A2EF517BB,AFF4BB7F5C71A17B,82F31293BAAA7591,000038FE1082E88C,EFDCB68B0DBB5393,B4DBA2642C5C9083,8777AFCB5B33A7F2,D431A6711967E9A3,76073D423605C290,736BA6D4E2A9613A,80EFEF5AE9DB4F0B,19ADE524C59FF536,CA51F5DC520BD2A2,EF622D2C98D2F4AC,2A6DFC3738DA18F7,0000175E57B44626,07EDD46A12FFBC4D,D0487DED527965BB,B8A5A9A22F937CD8,1C9E699A7C19A0C5,111988FD811D7401,B7D01801665E2F00,E23BC95A9566488A,AC6F6B16CDF65070,4C9A116952AC1F31,69124B2C076907D2,F4AA1D23311E684B,00001345D10B38FA,F3D311DD83384763,02362E0B4ED475CB,46C4E157A00203C7,BA7ED0DAFCDB2821,64437454C793ECA3,1E3F3E7E95A01FED,1D9823FEE67A6CD7,98A6DE2A13849623,85E1D3215FF4559F,74DB444084F05910,8BCBB0C3B03AF324,000060AFA854C500,A0262C1AB0BC68B5,275A9BF90DA718CF,6762083D149FFD68,C956A1F90613964F,3BB1051E32E648E5,45D97F5414D9020E,345D8818D24131E9,C06238F2AF32228F,1A6AA31F31B8319E,C6979B9DA72BDA0D,B7A3FC74EB85A141,00005544E4667C28,3911587D097F2123,6B2EE8A8F9989577,2E2DE506E52D7136,960A1D5899A37913,B473AD61A983AB8C,7DE9A66E4D288B12,38C98EF44B5D6CEA,40BDBBB3E5892C07,EADA115C704C99A9,0FF5227FF92810EA,059299D088FF7409,00002CDD38B37EB8,9846AE5389C2B273,419E699A0DB469AC,C848C71DF5605B3E,2BD1D1C48927D819,C9FC082A99A9C149,F2C4579F6E914B74,E0F8452BAC80519E,5B352309A3776F26,F13B60DFC8905115,CF2410B4B7946701,C36DD7F8FAF3A74E,000053F8498FD0F7,DC9E4A4A32A01C8C,E3AE9702DCA80C61,2B2C8AF3DE778C66,52AF09D5F2FA0868,E6C93DCCFA135C59,3884DC98B48EC2DF,E91700AD64F16D3A,6AF1EEE8EF89D1B5,CD5ADF4F86D1FABB,1998DAAD1EDC0907,8605A730416FFA17,000043333C8C96C2,977933E55FD73C5E,BDA0D983E49D136D,848A3E1C1F04F3CF,4B3CE4BFE947CE53,C08B9A8F4E31D936,21535A8E13E2EDB7,848E827D5F6E721D,C8255D8EF78638D7,68A753FD8C91B75A,89927D73D8BC4726,4E9CCD8CC979919E,00000C777C022133,A36F2D522578005C,59F86AE3E67A9C36,F3A955A245520094,1D0BBBDC7091B196,3CAEF8DF51542397,2A1714227C7161E7,186F8F5E496BD85B,32DA901D28722C34,B653C83B130E0E02,977FD50B1F112216,74A58BB044234D83,000012DFA8812D64,792BD9E5682D01D2,B8593968B53330DF,F2952D27E9E20B7B,FC50D6F1C7688118,5C091094802F6BC3,F1BA7C3FFC25405A,98637B6ECE364E19,0B889CD822AEB21C,9DB0BD4FC8CD40EF,33051EAB7BB2ED23,F93304571BE7B1EB,000017EC73234D8D,2ADAD356ED234DF6,9429AFA333D06069,320C3440D0D9B6BA,5956BF51BE9FF319,7ACB32FEA0E49017,3EF75A9337FC94F2,A24AD4C7BF18B782,DCB2380B6EC012AB,D73F83151C64897F,CAB1120860B51B07,A29F42999647129F,00001748CC41998B,98F7ECFB7F1ED77D,6B15AF286933B8AC,0B065420A21CFD21,D5E7A1DA3B78B1FC,1AEB2AAD915DCBD9,BFDE840D39B5EFED,8BC783876DEF1201,9D0F3D1F92DAEF68,F7F8D1416BE74C1F,58F2D97002CE46C9,2CE0F7BB96ED81CE,0000573E1AE1B74B,54106B4EB7D03314,A93E6CE56C1751C8,8437BE0F9281EE4D,2171E33DED423173,9DCE014158158596,E54EE715109B5609,23A95C4F58B3EDD3,A9C25A6001FA0304,B9B998EC9C33C2B4,C8425C108278E90B,B51CC29369EA204D,00006FD828EAB8A8,C5E630447BBE4752,A0DA26CEFEFD5EE8,E0643FF442A7C2F5,36A940A9B6EE4FC7,3AE6FE348D9E4962,53B0B0B06BC7DAFA,AA52FC54324A7DE9,C5CB30A7FC08D8EB,3533A4133AAB31FC,EF6F5BCA39AC5DE5,B34FA02AC1A60102,00002C90C5416239,1E2F7BC7F44C84E0,A5487BF408A32688,7139A63EE2FBF301,C526BFA4E5BB488C,A62957F7C7E50FD2,CD289CB923F6EEDA,7B159BD342DB251C,C5DE1A892246F717,900E7250EF5643DA,3AF3DAC8DBC04192,DB6125A6C5687D38,00002BF3C7A9B280,160380272F287A19,BC9215254FD0A976,D6ECD02C7FC44E97,675484050F84CBFC,363647F6286F5F68,3F74D50DFDD86720,E3E578767ACFC658,2DE6449A6DA8ADCA,989F9026507359DF,2D1D339C04D8C376,D921E94F6037B0CD,00004A7DF9EEFF69,B233B6BFD9F9F782,B49505459BF10A39,2AB6D605C0F4BD2E,863E10211B2BCACF,D8F3363FA55B4ADF,912172B492DFA49A,68EF00D90C0AC3C8,0E2DBE473D9C21A0,435D2109316F42F8,7767CEB9EA51824B,F5A1A9711B1134D4,00003946E4B37BC1,688091591477B856,72A2DD65D9CA0AC5,FCD2F1BAB8307A16,1D7435B2F752217C,9CF4052BD08A27AC,938C2558FA43ACA5,560F037B24126B56,FA1A5F556AB53C0B,BD2591979F2B7D7A,0CFE2E590BC8ACA8,7B0B8FC825E7BFAB,00004BFD77B5663D,3199949C7E268918,884279BF3905737B,717A14539CBC7AA2,9F8415EA469688F1,84A9371EAFDB9D37,5015808977DE7C8D,821C3FBA6B8870DA,40F2C2A7240F6085,E87C48EA37EE01AB,0D9601C3D2C399DB,A24F17936620DFDD,0000327E619B9143,6A52642391098EC5,95B41224604F7A92,B05B55C9D81A3268,A3892F11681DFD5B,0FF10F45BBCF9ECC,E02F17CBBE5E61A3,A6A2E77302A4575B,D7C3CBC393005BBC,14289F63A866D6CD,375CAE7340C95F0D,AA8D8D0F13F45059,00005E0F731671D5,67F41903809E0E2B,F888CC5D1177C673,42F7B2608FD6C3B6,5B8824184C5A828D,95083C5D32ADA064,92B4F8D0C16F3CA8,6D078C4DCCAEA2EB,637EDF4596E8768D,5F96AC3E1AC565AF,59408530098EF6BE,1F82ECE1A4501421,00001F3296FC317F,BB3FF3C5C8E7E8B1,27A8BF163E739A05,6C5A7A23D983222B,D22173549529A674,2123F953CF8446D4,BCF06CE7153D1E99,45B3C9DF5D4A827A,5F3BC24BD6EDB092,58910F20D0201082,06AED77D31C76DA3,4DAB1FC1CA2309A2,000002923C68AA2D,EACFA5E3659A9FB7,DA12B8902398E9B5,FE45288C0229B1A5,B346E597DE1B7CDC,7A169458F9873EDC,81E7F1E9883B57F4,90F2B493950DAC09,9221ECC5ECDFE62D,C6C873190F239F4F,B4FFAEDF4DE818B3,265CC3D097141972,000060B07725A36D,CE8962280596643C,6559A96F012599CC,9CE91CA914E3908E,510FBF396B778F0F,CCB736608803E657,28E2EA48D4916CDF,856E48542956339B,B8E79B2972352A9E,E8B87B99E58916A9,50F44F5E3DE03961,9EDDA3670E880A91,0000129DE992A5E9,E6CDDEA46AC9EB85,9D06BBD3DED08FC5,D59260EE4E11F184,3E4ADF873BD90807,D6D37B2C8A4CF1FE,8F785AE8EF83EAED,064A29C417BE5740,4BF1AFA9E70B8D4C,A20EE7A174C4BFE2,6408565DA8D6A540,FA2795612AEB3B1F,000020DAD6285239,FBDA7E713E37BA5A,804BFF003A7E9F88,9E1E2E7E07123FAA,6B4DD6A214DE1074,A7255028741FE9B8,ADB311C94B814179,39BB2F4C74AAA0D8,EE4EA3DE52D71183,0E264AA4E4EAA6BA,265CDFE9C4EF62B2,0D9E663051A22823,00003DBFF1F27BEA,BC5BE0F43E9D4D5E,F9C160E198F2819F,88BF184137FD64DE,D1AFF2AC86F97D3C,D71BF3D3C1149C53,3E0B20E7DDDE8C01,C6C2C223792CB203,F6185679DAE01160,07ADBB5E7A46AF24,9BA6B23D0B18B18B,C1FF2F1FCEECBBDE,00004B55FBE35361,26A2F668B3FB3E55,42F47251E84BDB55,3E59D339A2C352BD,4195156D62EF060A,4D2BB205161EDB92,4365C78CE4CB8DEA,7E6039B2D36479E0,7ACC819D78B89B85,8A0DB43129020AC3,1ACC87FCD6C6173A,0B9D0555DBEECED0,000002428D60BAA2,80B2AA698B9EB9F7,D310FE91CEF67359,6727A9EBDC4468DA,2DE1E7F832C51BCA,6CCD2845D715DFF5,7CA118D7FAA77EB1,3692247853002A9B,095BDE79DBA8C961,DA68ADA777061964,C2B213B5CEA401F8,5011AEFE7D0D4C6B,00001D5F54030045,F691DA4EDC1CD32F,4185FA679364D276,E976A067526A4A12,BF77FF15B303E0BD,9D3AE671C4FF0152,BCBCEA6A913A3391,C3E5F4D0251E5B40,A9E73E524CCD7B65,596F29FEE4A638A2,5CD7259EBE6EC2BD,A2402549E1E7642B,00003C272833F8A4,F30118AE84707626,83F3306CA015805F,E91A1976B61130C1,C5FEEF790449399C,433FBF845D6F912D,CE0151CA3E52B43A,54906F7B1558D8FC,07BA0FAAAF0D9F4F,C9D5A16E4908382A,8094B1867E5A4C55,A4F546337BEC1C2F,0000172F1197BD3A,61B8A3717228E62E,90E648FB0C79FD78,8EF512EF5F8DFBDD,EEE3F24647FBF2F7,A5C9FF051ED6E211,571AE140A11295FB,0B0C01C927A88028,D5FCB1E5BBA04274,6F90075EAB2F81C4,82978D73B864EB04,742B9F39545F557B,000002080AA4DB1E,C839D87E214B2CE3,577762BDB2FA9D2D,BBB75654A769D0EA,8D38F6E1C854B2CC,B7FF44EF3524826D,3322C08D74D10073,A4C06F74B514C3D9,33E683C5B9691162,0BB660AE069F8653,BCEF3BB8DDFC5EC4,0301BA7FF3EC65DF,000018A643478117,8CA107E9BB2E39E5,C45323D3ED219ED1,23702290C63A677E,9C80F41B7A7B269E,C8B52BCF19135F77,D8C207D29021CE24,E49F336C2E708C1A,4DDE6969B1144A7E,6C492985D5F8F1A6,9881949F212B14D0,0210992CCFC039ED,00004987A65F5295,2DD99612F341C0D1,29662146FB4CD63C,8BFFDC7EDC63D3F4,E94F45C4782B6911,74AF73B8A875DCD9,2B459181361DF1C9,14980CD771FF83D9,CCC0321338DF7C48,EF1C8397EFB31DF6,6039A66807C46B16,EED1A4727A631BB3,0000474A81CD8C1D,2305D0052F655968,198ED7A808976AD6,60C331EB350E4A72,478657128689EAA4,E6B7667DC913447D,00F8B3B81BAD4B6C,C749F5E4BCBF6C02,D62DC0AB0AA1E627,AF20B0800C8C89B0,1197EC60D9CAE20B,7B80DC8A423C582C,000011997273C7BC,9AD591758E06C2F3,D0DB76E07179D484,7D685E40F4A6104B,8231AB810EE96531,E04A4A3FFAC54C44,7710A7D669C56863,A91C9F4E276D4751,A4A49C06F05D0C2C,2256C632EDD5EFD8,D07426B9284B8B7F,09C547B3EBA183FE,00005301D0362051,139052F370428D4E,4EED4866F9F5A154,45ABA2B24CFD4DF0,AEABAE4A3B1F6181,9A7EBC36A7D023F1,AF6D3D34621BA953,EA0F5487BFE3492C,07290100FA476773,E84FF9795C902A7A,39410ADFD3AA73BB,7A6F7D9B2130EE48,000044EE0E3F5785,434313092083F0FE,74DCDBEEF798555D,2DCBBCD0A10BE053,E2DFC88E3897D1F5,560DE036E60F363E,A729C668AAEA5B13,2797622868C7C424,5D4C174E7826CF6D,072EC44A52F21335,0EFC29CB0260FCAF,663C699FB3C2A704,0000323DC3746B0A,DE4CDF2455421C6F,99685F3FF88A40D8,5834DBC2678B0C71,A0139BEBBDD1797A,556E7445D5CD4AF1,D334A5846E09C6FF,20E77F7DA26A4D04,E76906F9FD22F810,8030DA546D3CB4AD,A87358B231D790F0,D633F539F09B6130,00004EEF8FA9EDB1,6C665C82E88359DB,5A3C6118000D0D86,2CCD7709069A2FA7,8ABB0B0EC808D03A,232F91A82B4964A1,F53D3F524E9090F3,89EF946C989D51AB,91613EA14EC862C6,F397241A0C15F89E,035DF32E6B3D5B54,5DFDA01382326B99,0000399F360A2249,DC0298F0C88832BA,421CFA423E7087DC,586F83F85A1D4242,ED962E2CE402AB57,607E9216D5936B9E,EAEE6EF64BF4A6E6,162D7E993F6C3030,EFD4770E40D66D66,D588557A96108C56,8B7E77F60D0C7DD1,CDD2154787470242,00005AEAA034F067,1773D0F9A9BD6FDA,9FCFE5FD973D217B,A7F20561A5C14242,69A40E786D9F5E96,01D3510E1B6EACBB,786DA7F36E86FF14,E3577C6ACF1B5E42,DDF638A34E76CC62,4A8001F00B06B56C,64CA572924B0BF6B,CC7EFBA1DF728D2E,00000726CEBEDA98,FEEB3D0F2D7BC833,658EE997D42F1AD8,76A6190E5C09C4D8,206932641B3FFDB9,26A9A738FDD4E549,BB573C3D7DDED1D1,27C2EC70FA04B7D4,9B176C43A6B12FEF,12917B7FCE34A2D1,C2559AC6D2368201,B90176A3C9EC5B62,000063A3DD9A3755,1D13595EB3DECF84,F136D91A5E983F0C,647BF681F52809EC,9FD40FA47E3336D0,E7E14A29929F776A,A1CE64E1097E2F14,8002C58E67BAF77F,FDB46D6058FC9C7B,184E9FDF756F9FE8,FCDAD871B367B18C,C374CBF5A06D5B41,0000512CA8841338,033B2E7163FFCCBE,7B80F3FA7E1AB5C2,8C2F4817D5C10391,AECCD7C20AC2231E,66CCE37DD1581441,793F6D0334488709,A6F2D37D82B6DF66,9F32561B77DD8E53,C8E2605AE0597D6F,B8EDAA5447807A8D,35D66C9AFBD7A70E,00001956EFDAC858,9BB6AF409CCDB20F,70D1583D3401AA3A,537A5D97DADDE99A,84DF9CB25681FB76,16747EA4E55018EA,8881B02BDC19E0D7,1F035BC454B6D722,693B8B681DA12479,153555898780C68F,F36E87E4FF26193E,CF1F5720A05FE74C,00005E67E374AA33,8FEB0DDE06FD39FA,0CF106B244251986,A318A51CB123D671,644FF5DA8EA96317,9457BB206E639C94,C227CC8303C1E994,441ACF17E7237EE6,131F40121ADA94D4,7A8DFC69733F8A1D,D24C9778764DD241,FEA6E5F1668B4E76,00006E7E13A38963,324456135F0FE5FE,0893BA5BE4083D37,4623F576524DB911,3A3351FB453D38F0,F3800950594DFAD4,254484BEEBC7F0DD,466AD67F720C727C,9B6F70DEDE6E68B3,38779A5BEC5B6DB5,DCFA97B9BB85FBDD,9D668D978C232E91,00004ADAD765A0DF,8FFA5CA64A12ABE0,2E5968D4284F19F8,A2E30928E0545EDB,6832B1CE259692AE,23ABAE2FBD3B8DD0,36AA30A695E4653E,11C390C5C0B3B4B9,AE6000EBA7E978B9,4445D1A567288BDF,0EAAD458BE341B5B,138D7AAA11538F6A,0000428CB6D17177,D7744D2DA1825769,B8FE8764ABA93909,5500327D9E0A49B9,8886D62CB4AFF389,E3D0BC95486E63EE,6FD08FBD21291E62,AFF7157853604BEB,19834F8E56F50329,955DC63560590384,50C4D964DCFE6965,5D71B52BD22D3550,000015748D254C30,3A492CBB3F2ACBB8,D77DC1A9010BF79C,CF0F6CF40D4C2192,9D3A6E095306D84F,3695EED188581B5B,3A0B56A219104DA9,AD5696BBAC05D88D,515A77B887C58085,0C42B1E0919137E0,9D59D45CF5B1DB94,515C66F0B1089C47,00003C0E862C9E75,4AEE2193485BD3FC,E801B164BDACEF5D,916E8A14D794E351,CCD0C911AAEFD49D,4126319E7A4C9068,E369E50842BB1366,9B29849AC173C056,7D01762F51E76451,62F63059F1494E30,3948144CF036C0ED,9BA457D6B4D755F5,000014BAD7EDDDD8,36A3072B401E8F49,7D5EED44431E7D8F,EE35FAFACEA004FA,6EBC049E31E6ED89,A87610B9D535B566,14A668587F5CC434,A67DCAE53A435816,756C0ADB3601B765,2353B342A9255153,9C6138B385D06140,7A69B765BF0C282C,0000164BC65AC661,89004199AE60D248,F161ACA66763577B,0E95407D3EF976ED,0F55D5B7E01499E9,C2B1EE373E7B4D26,BC726D87DA541138,5FFE6B4A952374C1,0D67C1A7A757290C,6268CE938445EC5A,3AEE226CA2C13B28,86393CB5D3BED363,00006E80B1F688FA,A76A6F83400F492A,2DD1DC34F059AD24,8461F82DE36C5789,4958493AAE55218D,FD0D77E11FF228AC,C0E40A17206BC04E,ED3AFC99812A2DFE,D85E1247FF9055DF,23C14D03EF5B6A05,858B1F7150C2F9B4,F6D3B16BD9A354B7,000005FE51145352,523A2F42573728D6,510ACDEB7BBA4BAA,88CD26E8C06CE5BB,535AAB8C81FC8501,ED1CF33D36183E33,5EE2D6053FE73FFF,FE8869712E72EFB4,C29453457114182E,63C8396E671EFB1B,29872C480060D6E1,9777770D30C4B4B9,0000070980F13C7E,15398D1C4E418924,4502B77EA1EA71D5,B5D5332D53C80C58,EF2F0E9A8E802530,122C03CE31EB70EC,4D3D8929C956D0EC,430A7E37DE13764D,B6131474CE828D50,C596EA54E48C10C0,8CA779D8192410B1,55B962AF9C0B65C2,0000654C8EC8A2A4,29C5558DB3712FBF,BB4D948BC9D262D9,2C397CBAA3B65126,14AEA2A6049A5347,990A526BE1BBE81F,4AB1891400ACF439,8D9F6635C36B5288,AD4050A04DB00DF1,A56DFEF347389768,9D0A19D20C962E2D,7E9DA46C1B018EFC,000008DDF201F479,B58C427CFE14288C,6C50A1813AE9E6F4,D4B7A58476E84B3C,CF91697EDBDE4CE1,1386D864AD8861F5,1AD47B4801065226,AAA4F2373B23DCE5,87D9CA015DFF7829,4C4709948D7F6E44,C2B36968C203DEAF,57973A7E711526E8,000000F39B7216A4,F92986F713202A0A,38436A5A0F7168AC,014CB9A407FC2CCB,F0DB7F7B12D688DB,043E301DBC1414D6,0186280C868BE242,912054115F9E90B7,529B7933EC2F5029,D67B95A7B1BA6C16,E91B7311696D46E1,C3626990C0C61FB2,00003119EC0617A9,4EC1160A5DFECA55,254A04AAF4AC0C39,BCE31DADB4B7066C,4B74A53731C6840F,9681D8C11439CEAA,C80EC726F01CA071,7950F9B92572359D,0155083985EF9875,13AB12B84A3162D5,F15D9B7782361C69,2B6B0FB8AFD80795,000007E16808D095,B352BBB6E6E196CF,73BA3A80B1E4A804,1B672765AE9C9997,982053583CB9324F,E3DCDFD8ECAC686D,5B2088648D824733,C89A7A72874561C3,9320C61389DBFE6A,C9FA289E0E2203AF,F5530AAFCB9AA229,F20EB79473EED83F,00002FC4DFF3E39E,182B1ED3908BA578,5EA6315D3B589DD2,9A63E24FFE7F2570,403DCC02D776B1FB,9532639FE525B2A2,16ED392100010C23,8B1697B86B126C7E,C958AB56BEA9A2D2,F09A0FA1E1D52C6B,743A79355600AF7C,046AF5E9373D9ABA,00004B740F94EC40,FC399928C50AEECB,7DCABEC390F40A0B,6300A7294217DA9E,EED215AF70341148,F330B1190BBA7A6C,7DBD48784FACF32B,6E060072324612D7,74BFDA43F34FD2EC,97C8C606A80C162B,820C6F58A3EBC545,1F577231430FCB54,000011EB0069DFAC,46C246679A9F734D,E7DF8B9D35056450,5D42B61D85DAB038,EEAE2722B857128C,B8A6CE2CB317A90A,BCA8FC2BABF7A73B,A7A6B09D962068DC,F6C1EE916C17213D,E4C6755C94B6A26F,DC4F8616B1EF1624,36726015B391DB9D,00002761694EE4E4,0901E4671A563146,AD9E4A2B3859956D,725A9F4D4B16D71A,CA81C869D2BED503,E96A8D623D584DFA,FCF1DB8626C62CFB,27BD3A54ADCD1B0D,26F48EB2D75EB54D,0F6E4A7016189041,91F59A7ED7C038C6,CF29644A3571E762,00004F9E56816D29,DF0FD253D3E1BF2F,E7575CF1A6CC3DD2,FAC897033DC67062,C1A92CD545ADBA1D,33C9664F097BA1E4,84ED4CA830C85511,2F6954879E85981A,F1281810E093F4EC,336A735B401CBBF3,12AB7AE2F046993C,56E3B5A9E9501446,00005C4579C6FEFC,9B085A078D889304,07B62DEA420153F2,9416BD3530AC7B44,03A393175FED9F25,CD02A9772792CB96,0A9AFDA6D8FD061B,AA4DB58B7B6EE0A5,618A3B137DDB7CDE,6908AC3C16064C3B,54B4DBA86DB5D47C,955D16A647013100,0000236044BB2B85,36F127D21D2F34A7,858AE0E8F07EAC87,ED71E60EA97D5EB8,A5A8BE382842A504,6762A8AF65A957D8,395ABD71BA712605,D04CDD7A7604112E,D9BDC82C22259532,45F669F3F4429C79,A8EBE9BC76035223,617DB4844E0419D2,0000526973A9E35E,3EB7F1ED62A9331E,059CA901958592A2,CD376E604F816A2D,ED0C5ADB90B17696,F1C1DBC844ECF828,FF65D9636DA5AF49,83A64B2A6E9B3FAF,D4D98220B3D5FB72,D3E37F98994DC5DF,085562B3457F964C,AAB628953D0D1796,000004C5B72E65FB,B474311FC4404101,03418542CB1892EE,A7AD9A3897756940,30003543410BD9FA,854105F687FB6581,457A4310BB5695DE,608C94BA10E643BB,79C71CC1324814CB,CDB417C509E57A60,BC9A5638543812F3,8DF9969934F306F7,0000451684B4539A,AF0ACD3C5C80275C,B6936204FCE83F0F,C4815D34DA10FE83,DE11DD904CC94D5F,B3576C89FE0AFF36,E23A9165DF8A3778,3E32F8B545DEB88B,D20B6675FBF7406A,DC22C6DE0CCB67FB,19ECC494C503F6D4,D82779927B9181C4,000040C6B93A4737,F838F1C325BAC233,FA1AE26C719C32EA,29BFA32760F031F7,8ABF2129C772EEF1,207F84AAE1DAE141,A1B397B2131446C6,CB662898EC024E54,DA9CDACF9641F133,BD323E23A5E82FE9,9AAE78754C47E976,E5E098C5BFF108E1,000050F9963E902B,3E24918760F749A4,344B4607048A76ED,DFA16C4606924021,949FA5DE08A91A70,B022F42AE7A86AC1,D39BECCB678F47FD,498AFE8DEC214F01,1A5F4604F57B555F,3F5DD58644650E91,6FCB9FFC657D9C91,CF2D489513F8C2D3,000042263E31FE5F,97F2B08AF93BCEAE,C20BDBC49EED4FD8,7458828091316C5B,99E0709C52FD2D42,F1A8802E5FEDEAAE,35C75EFC43ECD570,F116373E25F40D4A,A00F155F12BEBAC1,5943F8C83CB22073,2035BAE86E847BA3,4FBD0A58FD271E7F,00005181DFBE08DB,C46C9AB2BFFFFFAF,39C1E4508F43C6C8,15FFA4AF1C86674B,B7CAA751AD6A9284,2E9732290657882C,E81D283DF386FE52,B231849F7C0ECF7B,9BE3AFDBD1BCD9CE,237EBA337446D91C,D2591C55BAFF4154,628A769AAB62A394,0000062F6FAE7F41,DE79119C212F7931,80BDC98DCBCE2FBD,41E02F4F242D4537,05CBF2DF9F8B3556,2CC5B8F0BF8CB20E,DEC6A8D13C3294A0,E0EA3561AF85F31B,2542E26540141CEB,6A0FACD3A9C51F26,11687716A61ECBD3,858F82879F3643E9,00006F4B701EC8A6,4B68EC02F4F35BD9,1734921CCCE5E154,9DBB8345162F0567,A65F3D5C75B66749,07FB04FBD79613F3,0B27C2F9AE81F780,569C28DB50B94B6B,FB926C9ED715EA46,03B23BBF30269E2D,E744FEDAD792DE96,4B8D822D435D245B,00002FAC93C6B2E0,729F274AD748DE5D,91C0EF6CB06F1BD0,51496FF8AA506C0B,1C4BD80B62EDC6C2,07DE5EDE2574CB94,9BF369A650C04A64,3942E750A09D7888,E966B1B2DEC6E904,4CC00924FE7C2303,FC79D9386B2C8EAF,DBB91B11D1F5EAE0,00000B8E36AC9378,1F9DBA7D3C40B745,4C2CE1A380113060,FC7C3ABF3E1CBCE4,2A88D2F405CCC598,F7A7F127E20E7A64,175C89EC231D78F7,693EA7B87AB8B484,4B049D10201B9BEB,F102F25C0CEDA64B,770C7B59B362C6BF,ADA231B2ABD45F7E,0000576D8F6AEDCB,E9F550997F18F238,7F436C7A1F25B5B5,E6D258EC363B5798,1546FB01187618B2,51941A7E9838AA0F,1629665BAEF643B4,A8AD1327D04B5750,B0D789B025BC48ED,05498523EB87D463,2587615079AC83FE,6390BE38195F3176,00000159FD2F692D,4B11780113990B76,6429C9C017BAF0AB,4611DBEDCD4099B1,BBD2C88C11923295,EE12981F67612AD0,9BF765068F85DE5A,292D24BBCEF59D55,FBA5771D06DB3A41,1484B03789D85B87,06954F49D4BEE7E3,D5DCDC417BA98F21,00000DB059E7B200,42423895E2216AB4,7839E63DB8F8576F,B5E529D3E38A325B,543436DD2379F9F3,04E31BDDC96CB8B1,0BCB2D87130E71AA,610676AE73D04E68,A3209D611FCEBADD,0A43318714E6AAAD,B886CE1D9A6C3A3A,3983B05D1A6B0F91,00003F02D81D80AE,B8CDEC5940CDF5A6,2B5620471F0635D9,62C1BBA40E615B92,E0F4E87174DF0785,7C86C3D6382B8472,CE575B9711A380DB,9E6C9CC844F4DB1F,1C60DFAF4B8EFB16,89EA309B99FA4381,7992120A8C4D1F69,A683E88A9FEEF94D,00006804797414DE,52A7EB088653704E,ECF6ADD87B0E75A4,091E39156D9288BA,25F0B545D416E3C1,11011906FFFF7B00,7638D1EED0D9A513,CC229064F2CAEFD9,681B0EB2B7C5DB82,169E8B8D25015DF7,FE226CC292B02A49,D2FEAAAE583D76F9,000052BAB9D8131B,7F0DC0B5E7EFBFFB,B3A4936B54920975,C24C311597BF9B5A,4A41F8AAD2DDDE36,5BE0905C3DF1034F,FA43B5CF4582163F,967D15CC4DD43CEB,8E1E055B6FFA1D41,4E4F9607D2C08ABC,B349DD8F9DC12EF5,DD98DC787A0EB7EA,000058F55B1DBF8D,A7AE8E0565A3DFA5,AE12E3DE74B239C6,AC44E657D5E1A95C,63682846BB90EB37,224F1134AD15B153,EA623BBC1440F9EA,AA8D65B15E8F1DB1,30437CC27A2E8564,06DEB5868C4B22B1,93E0032DC1AAF2AB,6B714CFCE90FF464,0000257D815A1B13,EA989B80804DD5A8,80BE2FEB5FD5A24E,B058E38CE27FD310,164B78958086B95D,BF46D836E9E00E31,F9C3065D54D5F8EB,75DF8007BFD1A56D,9A7EE2992CBA19C6,F077B6FE88FCB0D8,6119E12738180422,F2D489F5659FC00C,00002ED241C4A00D,524701A930814412,DF776B753ED795B9,816EA798663ACCA0,9759126368F945F2,1EBCAE810F0BA238,A5077E1CBFD23449,04837FBE04532B6A,F5858B2BB5D98278,F57E52F81D8FC0AF,096EAB24EB7E379F,EE49F68C53C7AB2A,000031A4DB4510F1,DCA9829AE9A5C0F8,DF9ABD84F26F5FFC,3D643174A6367E65,093E4AA0F277A19B,742CBDD4C06C7F30,B2B6F003A7B0FD23,EA429DCE6E56786E,C1E599B9C1311CE0,087701614412D65B,0A69AD5390CA699D,E1FCE1C8452D9B52,000023C3C6E75E9F,A069289228BD93AD,A9ACA7C9374F6919,E212359A18F30447,6E3D5784AA569547,353D19B79BB1E756,295604B3BD0261C7,AE431A1A1FB0F868,BD4E3B9C8206EC85,43A045A2B55EAB08,BC709F5E27F52EC0,C713E765A0D8BAA9,0000465ED9C9BD4F,BD0E062F2700C530,0AB344083212FCBC,4EDD249445CB7206,D9A4F6DB4929453F,4D7E3D1C25F238A8,7C83082519FC0F9D,6AB93B867467047C,347A47DAC57A940B,C239A96C3202908C,BF7CDBDC7288A171,ABA1F560589B159F,00003B910A98CCFA,AC03A0F072171D72,17473C2CA7FBA8F4,17FBA3E914A7C02A,D7545846C9252D08,544A42D51B214995,D8B63DC061E716DE,0E9F0B23CDCDFD75,FC994AC25AC02F70,ECC5A945D6554794,AD2EC5F1C466E15F,D25BA4A81966EC6E,00006235044B5E85,B0A23FECD14BEC35,740BB1E5CDEF11CF,0B47D84551E91CD8,01365F8961D0A606,E96F4369BDEF14AB,749123CFCAACA6A2,D63351C47D14675D,4C85E8EDB4096541,2D879CECA8BA94DB,F639815BB53348F8,5F35F5CD8FE072B9,000059C586E6FB15,446275745B258733,BB11D55C0A529771,DFF6938E96CD0CF7,279B7B3B2D88CFF9,18B7D07C4F7491D1,7CA8E8D859085ED3,22B506AD43C087DE,5863940B194C17D7,8D3B66CE21A6DBD7,2FE3FAF330490FA7,1AE97C095D611F50,0000064ADBEF6EB1,1E4B716E88AD21EB,3BA557DDDAF765CF,2D2B241E73A1DDBA,1965F060969B79A6,9B53E4B16E1EA709,0C2555D3A34433C8,F0D2445E863B8D44,D58C39FACCCB89CD,DC6DEB8014ABE9C7,73317A82CD372CAF,C42E35398532C3C3,00002E487B90BCCE,62503B67968A15EA,F45C460A08ABA7BB,B9A0359295D32DA6,989D3C95A5BE4840,CEE183DFB2CCA1E8,B12BD7BAE406ADEF,7DEABCC69CF1B483,6447C9008D1BF2F1,8496AB8C65BD1DA8,753F0EE4CF122BC5,D2619C1F68E4A17B,000012D5744391C2,50C692916EDADA33,05D842DD068833F3,80869DF2AB7A23CE,D58103E2507B0284,C280361F62948A15,748D4C96165E6DFC,B12635FB38FBA870,C35A44570C1946FB,21B5EFF804C66056,C8DFF0378A169F16,C2BA8C54C761E38B,00004AC8856C5DBD,443BF4C957E8E19D,5B99AF64ED440DF5,E0952BA81776208C,1BFA640119B02F02,2E56CE226201E486,62DBEECE87D0AAD6,18A5A7362F153400,E6FECF0F92977141,B6AEBABA2D7305AA,FB5D774D7BEF3524,B25ECFC1F817A1CB,000017C6E4F2D7AD,D21F6B5923F45E66,0AD2454BF8268FF6,72A90D6F756A931F,6C73D2183787A31C,254752268E987273,BA7B05957C721F3C,0BF853DF03257298,CE9CBEE8FA7BD3D1,4E5E644175F32AD6,989F6F6CBD459E0D,2E9920309482D6A4,000038B81EC2FC4B,BFCA9CE6458BD3E0,2B0DD2B47E31ED0E,019BB2B5D1772F82,7AA9F2D0A51D19EA,904DE88EB9AB1589,B70684E2F1843824,B421BCE67748B97C,5274A7D5E2419099,C6216744C290D520,2929789C05A0CD36,38F4B66B58621576,00005024E6FF6256,8D1C8725937BADD8,2D6C3E421647AAF8,BD016F1B4F8A601D,B86E6DB31FF04297,397B964EBF65E88D,434AF568C73A8FC9,31B9FF934D1D356D,5D6118DD6236158D,A9A766C108076FAA,1FAA7967C75C94B0,7DF279501F33E337,0000409E1CA8887A,BAA2F644103D09A5,AEB1D7DC23161309,5AC5AD9AE65608B3,5A5D11C5A2471EBF,8681D226DE1CBDD2,A7F021D974B56B50,FD6AB63C73B442ED,0447EB5CC69583A4,AFD757918BB57CC9,E0048C2CF0DA8B16,3AE9732345350407,00002B32508A8F8E,DF7E8AE053C878F6,7E4EE53C91031704,4BCE950C474EA86F,BE4A20E72C1AD9B7,9CF7E115E1F08D2F,9A1AC01663688061,462E55F4B67DBF96,7DE13A9674101F8C,149C965B402B0847,8AE04027BA750A55,F031EE77D9045E54,00001652AFF6E6D2,FB3B5E3643DF1236,5DF25AFDF704D333,86641687F49B9B98,DFB0F177E5936E29,8D8B7409B38FEA3C,22DCD3CC7D2FF218,61464051F09C79B1,31ED44F6521EFED0,38D5620598DB8D03,F158DBC907640B9A,8AC1B97E1FE9EBCB,0000174826DF9390,75B31090B7562004,CF662D0D3C4F3012,B893EAC1FF52167E,816C4F266ACBCB9A,F3E4E8C65CCDCDFC,E6FF692D4C4BAF1B,8D39AC72096123A5,AAFA1217B595DCE5,E6BB46905A2A3225,3E93D861D21C958A,6B46FA8EE9FBBB5C,000041921749CACB,CE0AA4CF530AAF63,CF8417B7634E0359,BED02B97BFA6C1FA,5F4C8B71979BDE43,D9B011FB1ECEAF4A,C9264B698DDDDAC9,6007B0E12019203A,34D2F03B0219E332,4AA25FDF83B2CE12,F7955501EED98337,338ACD1E1459938B,00006ABAE807B73B,6A964840916DF954,3EC24BD56E98DBF2,8842044E34607666,FF07D94F984FBE2F,3C594C048A0EC81D,D40F1561FE810806,AC43B7A6A7E0135D,D2F9D916FCC79988,09FDEEF1FE2A1531,98E2093291C8443C,713FD7E8BAD81364,00002240A2425259,75E884661F12F125,7EA7B4374E4BA4B4,ECFAEE95D7C50A4F,9D42A1D2B056B388,8F58B6937BAA74DA,D998F3288CAC9B4F,FCF0D2D6F6EB3DF6,331276FF963C9075,B321F61CA5A54203,3EF6B3AF3976B6E7,DF01108257BAF75D,00001BCC3C973877,01D1E84450283E73,E171959883711B0D,8B0DB85AD6AC8CBB,501CB6C3653EA7BF,63C5646A3823F5F7,84E17D3A497D911F,CDAB7315B6AFB399,C2175B1CEC50F849,627242CAAD44D21A,CB278E7958D52E36,9456CDD1F1ACC886,0000370E09246A92,4BDB518067910E7F,6E6AC1A4AF72E462,37141CF9F9DC8D30,2F40BBFAC09E58B9,B8887A4794B59C60,2565157E908FADA4,16A3A37A48A030AD,6C2450625E6887FB,36B3E43FD57B3123,0DD23BE96FCAFC2A,BFF89BCD5CB31026,00006F8F95F3D749,D197FB563C9C8F11,9A39DC469DED1AA6,6A8040B671355D2A,3C8BE7FB29AEA45A,A84223C5A9362601,0C1C567CADF71588,9A86078AB5374BD0,54131B68C0D06D02,52731BE360BF6EE8,EA14B3C255244F6C,B7856920CCC4CA9B,00003091E21D4643,52D282A1CD41C036,0A1E0238191D74E7,79BF3F12DEAFC0FC,9A6C8F0098EB712C,9A65C5B2F2B23CB9,FEB388B6C70FE678,7D367DBE1E92530B,5181C86B59E812F5,FBF61C501E191427,2FC758D2E6D43939,377C756F65262CA6,0000577784FD4762,52C5E0B4CCF70650,7583445C075978DC,844623BEF617E51D,0B9456FE9A9A8896,20DE4D68C2CC8656,B3BCD508A888845D,F9549959174C1C09,2026D4C4333161C1,493ADDBF1CACC936,E029DEBBEE97AF25,4B06041AE8FB9B20,00004339723FF7EF,3CF7E62C702AAAE3,C470B0B18A0A4A9A,CEA7A803FEFBD825,D4F64793D6B05A01,F255418A13342C11,45895A3935B4E8E8,442513F5D2DF5404,C8E6EE4927108057,51876462455E12C9,0AA0198233EFB68F,EAB4123B18B03C0A,00005209EC1338AC,1BC08965AA82A0BE,E59B0DB81539B817,B882BF8705CFF28C,2263FA30C0CB6FAB,A3135C74DB58DA10,52B2CBE836FB6DF1,F110E4CAAE5D495F,EB75008A5CE8E7E4,4174801577AE9895,C3E22EE98091A252,98961052F5529E5F,000025AB64FB4F2B,83BB3A1E4AC171EE,703943B12C421745,FC41EB52242A0A27,8552478ED096B0DD,04B7D30FE3C686B9,70BC07DDF0943697,72C31AB5857A12FD,69035F4AC00FAC73,FFBF770A0EE4A7A7,B386814F1BE6A5A9,07104B13F656D54C,00000AB24F1D906B,588F3B2203F5FA31,CEE9AC943A877F3D,0A9DBE8C34DEABA6,9D4D4B619656FF1B,A921AAD9BFE10E56,CD1E72D2997EBAF4,49BA30BEFD3D904A,B679436848B95BF0,0B45068643B56319,48E0FD3552E9B561,2A19639D1818168A,00002137F72FBE3B,CAB3862BE4516E58,978D46E2C0BC5CBD,3B48BAD9AE33E583,23994F9408602DA1,E26C352BEF4C45BE,4AA90A094F195AF1,80964C82F164A75D,1A34FF277DBE2B0D,D888D478EA095562,F037DCBF19ED4FCA,DC5DDD07D6828826,00005806FC82986E,09A1475D06D7EBF3,9424CFDD7E474210,CE54639EDD5C91C2,D6099CB2C97CD34D,A42540EA92BA7047,1D4B931D44DDD32F,8213B8AD04F0553A,52834F5C7B20B103,F843DB3CB5F60F6E,4EA9F82D65E17166,0B5F733C7CA61CB3,000009F1054BD195,B55A9749B245BB8F,6B3B385C579DA703,1053F5A9CD0DEF1A,052776CC22A556FB,B27B0E96CF8D3CE5,F8BBB106CA859E02,F267EB47E9EE329B,96CC843AE5C58A7C,26D9E617FA89D233,D00458AFD0E4CF71,1FB09A6E83977AE2,00001CBA9797E78D,B7E1249D284767A6,B34F25431DE6A1B2,C49CA60E6251A5D9,C0445EA02CB82730,C846AE6BB07B5412,1A058518F428EE38,00A01CB263098DAB,ED65E01A1626B33F,97D458AC8BFE5E82,2180DCE396701801,35893D7726D43764,0000585831879435,BD3259E08BA1068C,9DCC652A393B14CF,2C531E90AED8A066,5DF3BB4FC02F06AD,829D69B669E6BD78,DD6F1C91AD4B6761,D9A5A4B8D85D0E2C,8784B5B468E649A2,1941072043936B0A,0AC157EEB1C4D6A1,00AEA63957A498B6,00003785268A1B3C,4B6A942D5DEE4AF8,333538182C405559,02F2E0B1B5B172C1,CCB51D4916D6ADD8,F2846A0781FC4B7C,3E3D8F991CFE7BC3,32CBC4662A1C98BA,97AD648FABC18E24,25DD197DCFD0C4B6,51C38CD48D0AC1C7,C2B36A4A53E60F7D,000039275F5B1E67,424E82341E725096,C7F7F265DA8BB8A5,E0C333D469734C42,E2241DFF80919354,475ED15C9D835A7B,564B29102FED98A5,21D6E433113522E5,3DE8DB8DF5AB46A4,6268002C597D63A9,213A79CC379BDDD5,1F81FAE729B2405F,00005B2F9D932732,E1800CCA48598774,6294FCD2E33B515A,5B4D6CDB2DCF0BE0,BE05CFB0A00722FD,8AE1C8C42F66CDF4,4DCCDBA2CFD2CEBB,721BA2515C72F233,52BE8850A6D7EC96,39F972A58BE24CAD,1190C8BAE14DC252,E7700C970286106F,000016FD14AAD822,9095FB18387C7B6E,F2EC4BF56E76B8B8,C2C9AA27BA238013,AC5218D880E7019F,2929A24F720A9596,F226EB35B11E7C60,039429DD3C8187BD,56BC86791668035C,F95BF5B6738FE25C,7C28058FDB4E1ADD,3C3BF293FA2E20ED,000031A039AE2163,579FC2B7826A2050,D71F8C43BB451824,B9F1DB02AA909AED,533A580013E6AD68,AD07620D6F9925D1,3DE6EAFBDA9D903B,9DAAF3B6583B0AD7,7DA309B1EFE33D0A,FE0ABAD353AD0476,82785C3010C74291,1EEA440AF96B39BA,00005BDC620EFC6D,9B732424F002B2D7,A9809AB34BECBA7D,991CD1D768348502,87D2ACFF0B36CB8D,CCD6F597409333B1,1D52003CC87656AB,DC317BBBBAD2AB13,AC91008A0ED0D3AC,6253A17F43A58956,D4D13BC97447C68C,85FDFCF19459C48F,0000128FBEBDE89B,0B14E5B9BCCC99F3,26DAC77234CEBFAA,9F56A5867402E9F3,9D1BE7E79F7B1B2B,83554E8042D8F00E,039F03AF4EDB549E,2DB1A12CB497D374,BD6603300726160A,690808D4C27E0560,0C3472F766B76FA4,E2AC6CB53FC78EBE,000020B6FC74700A,A1A1B61978D9CA88,0D76CF62BC868DA5,7F12EB36294FCB04,9638F52294C68562,27A7BCCF444B091E,608B1F4646D0178E,47793A995A24651D,3F8DD004C0F64DDE,3559C63ED89D66EC,BE37A6926450AE54,5D3AC1495BD870DD,00002DF2F13FAED0,A31C15F606F63252,93F92E2ABD5AB854,A085638BFC667402,EF30800A4C312722,8E9177E4B1736D9F,7554EF9A17EE5B5B,309DA145AA77D9A0,A768CA8FA07D7521,9AA6DD6A3DA5E583,EDF9D084454FB1C8,788E977F91D35BAC,0000534626C9459F,6017BB12D0B246DA,E34ED1821980F7D6,201DE82E4A3C2ADA,B03AEDB9C323E34F,C48A742811A9AF66,21E0D4818F537403,020B9490021A8CCE,E5A0A57FD6A6E38C,D09BE5079B2A9159,E15BD2409CB155F9,BFC197DED7F5CB39,00001BB7123D5F60,91F77101F934018F,E0DE944175C52F3D,E98B414BAC088CA8,DAA2806A20DE56B8,80A9CE59E7C88D6B,64D61895E8E82938,7062D2463974FF3F,BFA99B121FEB36B2,D312A50875D7D223,E1C3AFF321BD27CB,D7B9F68FE760993A,000031080B1BB604,48E0C9FE46547690,53C31C5313F548A1,D8B2B90A6D512FF3,D98EEEFA1362CC94,4AE137B53B209DA3,909E719D5DD9386B,A5BB52A1CCB32CE0,35FFCA31045AD22E,C6655C5607EAC90B,F61989ED3D055FED,92E02E09DC55A06D,0000237F54EEFD09,417954BEC48A5F96,0C99EA6EFE139F41,0BD48CAEE17446E5,E5B0D2F34CEEE1EE,682CDBA3C842B4E4,33C2B4019D4F0FF1,F53F67BC5E2AA878,EFD9E4BA608EC701,795CF51A359E8C16,D1FB3A37218F1A43,2EE08EBDD55298FC,0000320AB605CE56,C3D7917AC3C88BBD,A75382056CB721A5,CBD8AE641C6934F2,8FD41FD0E97A6B22,060C2AD86664EECD,078493D2FC5F2E9F,99A866FF8BEA74F6,0DF2A4DD8A1D252A,E59EC78BF98E30A9,C7548C68EF42143F,EE1BB9C32EC60C87,00000B82E892B5FD,58F6D9F55EF15315,F3310C12ABD9ED24,63809E5C036ECB12,1BE2C2E392860EC3,8DEFA5B22698FB81,274113960C36BBF1,275774E78B0749F5,543153E458A384B0,3DE4FDC7B2104ACA,33A9616B033156F6,54437AEA96E56A91,0000526BF3FE8D9B,C99CCACCA2CA1615,D57776D05A76CCC3,F6A7D9FA5AB513FA,420C7106B556A020,E610674A2A1E37C4,54737E74A107BB6E,7AFAB2C64F26A447,56B156278F21A1E1,1503C199EFF2511B,1DC795B0E98B8506,0003237F03A5220C,000021D0560963C8,E172194BCC21021A,E2355766BA087387,1B5CA9C54C76D167,91EA725E4EABB1DD,EE2A3479F2016F25,39847602EF1ACEF2,693ADDC419084269,84DAA0028729D23E,F9A066588045D2A6,BBBBF3136361D70F,33134577BAED51C6,00000EBD1405F2C0,AB01AF13B2C075EE,D470EA038E3E15AE,7890D17702734ECC,E75BB0AA596FF515,0BF7483ACDE5AE32,0CE18C336ABE4CFA,8FF47DBFD494D447,C0E2DA2223F6FE11,0E1D4AA1377191D4,859EE22A391694FA,57A2F2A16BB79BB7,000066BF9F5C6929,9955CFD6FF1941D0,C9E85343E35BAF92,2EC8B5450A01F20F,0805376011BEB494,D4A828A94434B4C5,0179948D06F0DED2,DE75FA47F415EC6E,2A6035DA97568335,204599B3D8284D99,9D3E995EFE954535,814D9D2CBA2E956B,00006D38D302D09E,862546163FE4C7D0,645B3B9D9AAD5322,802CC1016C6A7F43,8567AB4220ECE5AA,25A9B56368477DF4,79CD3257D754587B,C605641118786FE5,8EF6719CB552FB8D,74CE0B658D42EE84,E11100DFC4671180,C73F35683883B2A3,00000B57EF386F4B,E4128653D187EB9F,8553869D2BDF06FF,6FE74CDC7672EC17,EB45B8CD374FA07F,D1A11085C72E0C57,B60CE2829BA12154,FFBAF53AEB051998,CA16170692BCF040,6CDC2C5235A3486C,0F943E4231906F59,92522578541B9A1E,000068C717D068A5,26A9B911A4C705AD,8DB9E7AAF1FDE48D,AC8CD7DA39CCEE8E,C9690A9FB3574F0B,14873EE4D0CC4783,A9659CFAACB2CB2A,DBC381ACF95CC787,683DDE70984C4A13,11C136E7E650AEE9,5BBDC5EE08D2DBE8,741A7203E337486A,00006E82E88B93F2,A354EBC19D032022,C96CDAA77CDAA3A5,CD9BD0E93FAED74C,E0B57D5D09B1A22E,644E6F3DC402B99C,0659ED01561188D9,D64475B03F4546FC,6CE38820D5864932,185B0587D08CA903,031F81E58897F23F,A5BC7ADEB5B5EBDC,000044779C57F16E,452C646717CE6B52,3F37153D8D376415,C21715A86BAA3779,F5FBCD1DB38BBD7B,2153271A087F2299,61360AC087FDE47B,212101424D403F84,0D8A435DEAA97E68,9B7151B83A46CD44,D9362D71CCDF9FC6,332795F740F1CD99,0000475120E6362A,07FCF43E758677CE,43FEC7188B03052A,C6300A07B50C1C58,04BD0AB1591EC914,048149A34AF389A5,0AA53BE169E44E41,E7C106134BCC1C83,1CE7C54418FE0C4F,199C4E3C3FA4E82F,12DB3769F3A2C52E,12F609C5F033E633,00002388E0038C66,2937A6AA6AA96AED,C6CB812F2BBFF248,D65E8D6AFBC66819,58E47EEE0DE8E33B,9ED738DFC8011FFE,D38145D3C90773E7,A79D24CD38750806,7BF81400565BBA5C,FC78F73363D41431,EA6EDDA7BF83C24C,79FC8CDB93C8D8E9,00003F2011A1893A,075AF0429132C4F9,AF9C078B40954AD9,692A36D9AF3AB471,1A8A1617793650C7,4E026400492A0645,85704A28E29EC14D,73BC4AE75658E451,11D27633812A655F,A49A8AC448075F80,CABDFAB1A307A8E2,1A2AFDFDA23D9DAD,0000390EE91D9652,B367927A8A2E017F,76BD623B63991567,4622FA4F51320318,4B8696F2B9DDC845,B70E1871679D8BEF,1ED433C112AB08DE,39BF5C405EE56B4B,7121A1E0D1AD32C9,A41E63558B531ABC,D31381AED59A1CC5,160F5DE9EE535E9B,000036D51AC5870C,972571ACD9582F0D,F8993F81A6313BBE,6A40884EEA95854E,6F5E9CFB8793118F,91AB404F11B7B367,309318F0FEA5AF94,A7BA59046FDA53DA,2B8A305272C7DED3,48941F9BD0A46832,58849CD5F8D22163,A7232A8E1672950B,0000664BA08457E1,1393BE1756218DCC,57AA720160FEBF20,C20DC802816257ED,BD542232D884B361,1AADFEF4334B3EEF,E26CA4A7F1F9C179,91B02F703680044E,BBC3DEA304DAE5CB,482AA714524E3695,EE5AA0259190BE6F,CF0E2B9FC82CF6E4,000006A98289C9BA,E427448BCB051F9E,66572779367AA6BC,1E1BD352FC7DE3D0,F63CF17667DBD9C1,967C37F04B79072A,028CC404D994ED4E,EDE12183B925BD10,558E03F17494A96E,367B39B58E4F3C3E,984E2AE50074483A,E06DFC7CE9975371,000028EDBFE29721,F6756CE6F4F6FC48,E70421C1178F9A93,E2046285F950D1BD,ECFCC0E1D60B3C17,E7574F15E18489F2,D9B122CFAD96FA31,8016C577C4816D1E,B250F8C9CD805010,FC18D51E098FCB9E,3B589589391821DC,E87D04086F60D066,0000672E7AF5FCB2,229BAA83A0E4D7C0,1BE9E45BDF902B4A,2571DB8B2F7AC3CC,8B26C69350467BE6,AE8400B587E1F2CC,2EBF5E552F843753,44C9DA04E5B04F26,C64F7793616E0CD7,E404A5D32C220C06,A683F706800D9151,48BD30D41242FD83,000066928B9B2820,7F12814F4B350706,2EDA5874D4765CAB,E0B824C67431C155,96073CAC8F38A71E,09C817328345DF02,DDF7C02987360AE9,12FF36DCACD63A37,FFC7DB219FE58966,128AF715FA7FB990,C14B5D0DEB771E81,3D280F7BB23FD2DA,00002F7CF3190239,23C7DAFC85BAF422,C8D188F30FC739C9,138138615F95976D,7FA6E620137AAB28,81EB66D5EED41991,47365D2D616E7C80,8C8BE444E9A01401,70255B32DE25A1E2,84C21A114A4EB93E,048C72218BFBB4F3,5A9182C03ACD5A08,00001CC31465087C,D44A153F9D697513,85897DB1D37D3C28,A7EDBB8DF102423A,0F12F60768821223,470FB32D8D6074CC,C09A21554F278503,B3E016B18002BB58,22F212E8878FC6B9,CA48D7227D526899,8ACB6C483C1AE6AE,3D7C45E253977E7C,000036B157FB367A,34B4DDFB3696B5E4,879FA0C752E4DCF9,9CCF4B0150737075,5E53573CE68601EA,F8A4D899A2962E55,A03173AC79885887,6E24F9DB26DFC65F,26C1C773C5359500,DCC3D86A1BD3CBE6,B1E981B495A82F94,52A18D1994053F94,00002B7535851F42,7729421B750D6E52,FF4E36F8FFB70671,AE8C109677339A80,193C55FD5E174530,A6AE97FF0EE99509,C90F5D72DE08BEEB,30C2B8808ADC6A61,7CD0ECAB748A8E68,42638B6CC46BF805,FA11A4F8F769B27E,0D79800B401CA2C4,0000074498E72D82,30E822D30845C672,8F60C495CFC0D55E,58F92CEE22164232,B8CE0B63CFB4FABA,AA93D789E3713C78,19366AF268B2C8DD,DD34D69363ABC7ED,2217F09EFD110E53,FA132EEAC9DAC375,EA76AE1554773D49,A573F924F7D881CF,00001D805D98BA64,E801C377E9C929B7,615B408E29ADB8E0,92664EF5FCBE27FA,669DC47FEA86085A,D9B57A4E59E6E44F,3AE2D6DEC45047C7,082DAAB4D57A3ECC,88875B9373035DDF,DBF00C3DF7EB022E,3EB6247F2ADF242F,D72D356A9E7ACEB5,0000380159915F68,3C5078918A54A2F5,FD6FADEF967F2317,1482E76EB30E7016,97A5DD1E6C953E02,DFBDDE6D5BF5DDAF,6BB7EB5135BFBA35,BC8E3C9640B08FBE,9D6BFC0D7E10AC31,D4CF0122EA59E6B2,DFC9246F26B66E3C,D055F429BDA3FC50,000021D49CB77EC5,D07169E0DA44C6B8,C44E40475DA71B82,2D05798EFA0B11CB,D3E44B6C37AAD55E,71D462A6219E73B4,14963563B8D4C807,AFE5A7EE91006EF2,CE6532A73B6183D6,184CBD2C0D4292C9,994857091EC8E4BC,A7C68032049C9DD1,00003A5224207874,BE19D08A52F7C2D0,8D45B1CDFB9987B2,BCE897A3A1946FA9,32E050E521B9CE56,6EC9B7CEE1289ABE,94AAA2C38F07C5FC,647985D005EF4C94,C451C5A69E5E1E67,27774152F3262D99,89C693EFDA71C107,2CE305AD7C1CB98B,000011B1BEE8CD3E,806F333E8A8C7790,ACFDEF1362DCB2C8,65FF78A90BFA22C1,B7203990697CC5C7,34DD94E9E04EB4B4,2DC513D5A30CF57F,E8F331339729F372,A2065AB49A01F1B6,467CDCBEF81E3328,181EC93C102EAEA0,E89A1839FE0DBB37,0000343CF8243B21,7F7DDD925C224DBE,D59C7B73EF3DA114,EF77F074E8ABA16A,C1305E28D3CA9E80,1FFC0DC6AF78EE74,C61B06C3485DC4A0,33BC4BF7769500E8,D48ACB38729D8766,BC1D55D0AF60252D,F7255A4F75615C5D,AEA712EDD910C8CB,0000584C6807974C,BCC217C23050E92C,FAB50AB57A0F18CA,DDC294E9656DA082,1691EBBBCFC42A20,09B68B88ECE317F1,DDE36901C95B6C08,6F49F03F6F3A777E,72BE34A1B1A31C77,404EC6E3DB047A20,B3173361FE4F04DB,A2451F5142C7BF0F,00002D1CD8A5C04D,E476CA4B07F88173,1FD030DD79EFF493,3415E48C5B447F78,B908EDB9E4E75C72,58E31F3C675FC19B,B25496F77E0CFA37,C8167013F87AC162,11AE7B7F90722D6E,D3A7ABEF6A0C1B0F,E02748FBEA699DC5,1C3AC69E2B9210FE,000009A787088499,C1D9B6CD0A472026,2399B32FA4E38F1A,368AC2D728D83814,9C88E29BD7795425,C63C977A97606AF4,E37D713392960A9C,30719498C7441F5A,EF97B6B078E3EFF9,20DD3BCBF860351D,048A96649768C8C8,C08ABE4ECA059725,00004144BB930987,01FC229E9EECC448,C96ED20BD5EA2FE5,18862307D2DE9413,E01B5497B24F56AD,A674558743AA8460,487D35CF029B0048,AD154F99FCFA9517,C54322FCDF28B54B,5413B9E53DD5E76F,5FC39F4EF6222764,22898640149A38EA,00005D93C03EDD26,33638D1B9B766224,5EFC995838057305,685ED26601F0D489,6DFB98485655F790,89A6488D7CE8A57B,DF12716E7A09169B,BBDBE30904011A2F,AB61057B699DCE32,C06371BFD2262502,700EE2A03F878E55,2CFED74DEE65E7FE,00000BAEF546A81A,11BB4CEF67C066EE,4A7907CB14739FBF,7C64BC9CD8F804F7,56D250B0EA36BE18,22CDE01D6472438B,687A6E7205A904C8,5A9264B8F58C8EB4,14999F6FB6AA605E,B6541206AC5E2A4B,11E6F7D6072B3490,9E191BA7BC4F7BA9,00002AC9CF64EFE6,E1C4FE88350AB7C8,22EBCEF73DF2543D,DBFAC356D0971AC7,9492440E27B93645,192C72774A422A9D,775A8419DD160365,1D02A689E15A8B13,EDC208D9B80FF582,CB8A440C4D0DD014,EB0A64F0A971D9D4,5FAF667CC647570C,000024B5D9E1EB61,57AEC66E8B0E0B62,AA50A03ABE92FBE6,74039F5A05B25FF9,897207C10ED1C5CE,8F476A964BBA102D,6A855CE2B73D4277,074F3D7A08A4B156,70ED78177C5991F7,EB7B3D34BDE51596,FF04FC6BBD12479D,D3ECB2381ACBC7D6,000022B7A6063BDB,76BA63174127EAFC,27E00E1C9CDA66F3,A3CF9EDC9BE98A96,06441A5D269BF5E3,B37EA5DB36076E5E,62A857B9C35D8E68,FF35581E0C34873F,B210AA1FE4A627F4,FC65175FD03118EA,BBE2FB9352CAC658,C52702226CBD8834,00006608EB820948,6D6AF7C711077770,75BD93D70FC325A8,D97F2DCEA332A0A8,945D723855AC6444,8993F516ACC6660C,D83211816B130CF6,C97ADA48D33D7D86,47485F00E8AD8DC2,4E481B4A81DDFB23,6FC61B5AF668643A,697B5D1243E57D77,00002EC2E6582A04,960AA71882190379,9C96304E47085B4D,891C91163D0021E9,697166C0857EEA50,35CA6C6BCC83D78A,D3B72AC5CCB0BCBF,BD0C40291E59B2C2,545DCAD59CED40C7,BABEED63E1D3ACE8,900E07AC5597E70D,0DA06165E1C4F35D,00000AFED8FF31AC,C57C7DB9CF9C1074,AD6C2F5267241063,360722A36408DDCE,9C1A464957299D8E,2ED6EF89A6E110D3,3B045839A8DFBCC2,7D3B60723E0CE150,1C153A4AA2F38535,9281FD6A61576744,19FF3EE75417BD01,ABEDFAE75621ED99,00005AD1307E53A8,52E1EB3E7F74CAB3,09C74889E8B9D837,40DF9E8C2216644A,281D4E30485042F7,10C848D7E9D15CA9,2494369607DD352A,175BA8DC76AAAFF7,CE18DD53BF396FE2,0627A6C348CBB0F9,E864CFCD096F5499,14BD51CAC4DDF402,000041CB7CD87481,CD7DF9B80203E268,F32D74BFE85F58FF,C0721DAF44D3749B,C1B92DCE9D50A5DA,F8C146AD9E814E20,17BA34518E2C55F4,EB75C0D9DBEBC7A1,8780D4B0229AF04F,8F205DB3BF80D5CE,2E1748D83AA6C362,A1F0D35000A16A40,000005C4C4F69DDE,BD69BC99ACA43290,C6AC8590CE646A59,51F49B759EB8180D,1CC71414176B752D,C952EDAD1BE69A94,5E99D5DCDCE8060F,EFE03B6AE960CC80,082E011A35E33541,3C1DC3C053810246,61851102E5A27D3F,D450E7D55A8B62FC,0000554BEA2988DA,B454C72470550A7B,BFE249CB11CB4CEB,2D25F6826D4308A3,D9CB023C2385462E,ADB5278A0F23CD57,35CF1A2F3CCB1045,0280E91C375BBF6F,F869FF21DC83DD47,B05BE93157D13508,AA852BBF1FC19E6D,71353B49BDC8BA5F,00001080E0BA330A,593373073189B7D7,C90072C405EFE307,17FBCF35C5BD5D91,AB5EDF39B4F416BF,F1E1B184EF6D8162,859DCEBFFEB81B29,5594900427F801EB,1C03A3756FA679C6,51B9FE0003BEAB02,A6741E70FFC252D8,2B158CEA8B9CECEF,0000541B93241B71,2A8A0F789D48DC4B,7910918F6E25F2CB,26F343738D3E18A4,A5EAF82DCCA69A66,4CCD1BD7F97FE9D3,7502E2FC17A21559,D62C2D6FA90C22DA,9F7C39B54F043411,D05B5E3748302BAF,5BFD9F25632C3326,95442AE067859FDF,00003B8D087E2F97,1094E90579B2E792,0A5DA9887ACD3BB5,BDAC2F36916440B9,8EF87DE2B1E6ABB8,9D5566658C9236F5,EBFAB7DFB589A9BA,FFA9A74FB27EFBCE,6C2623DBAC1FFD11,D0BBC7EB531C9B40,8AEAF1A186793813,82635433F0B357F2,00005F3BD05343CC,BE6FDD51DEF3F5EB,248AA4B48875BE4E,C6DE1DE32C12D524,C28BC58B40B05E68,496F522F669EE335,508099E47B08007B,42945303B7FDCA47,3ECA3F95A8EC3C82,D30147017B18E033,831B14C8083A5805,207BB1BEA83D739F,00006D17CDC45F6D,F85711A17CE8CFC8,F03D4B03D3C0027B,393B7BBA1A8DFFE9,E74EBA73FBE92BDE,D345A6DD3E699FFF,08A70EEEF04F9F57,A0B8F7EDAB84A520,96C6A9E5DA1DD278,756E09F08D96927D,C652B5B5F2BC0C96,C63445D25FBEB503,00002E3F6B1F7354,59D57C9E6A9AF417,438714C9BA3BFE2E,828D7CC4E1C05360,7068A1CE7329C08C,81F9630C2699AB18,2421848C9DE7F9CB,AF9A2F64FD881543,7F162F3E8777C5C2,CA026D9AC85F8A6F,AA4C71C6352B5312,0524776A296B0612,000037F733B02184,8AA1A66671613CB6,1AA0536811F3D12F,9C26B2DE65CEC0D1,35A4C656A0AF4E58,9CE1D2E7BFE277AD,1C27E8160E6D4D6E,54FDD11DF57B5735,47E289EEEC3540DA,7E52E1DBBC4572AC,DD614ACC366415F8,578CA9720954CD4E,0000047F05231BE6,08C7D7901BEE4340,251859637D2A697F,1BA4628AAED7B412,B7EB6D3E0506A719,647AA4E49217F430,62FF0BCF4BED1DB6,666CD4D45BDEF25A,F98168E411290DC5,79D059F3746C86D2,563D9C73309F184E,A28BBC2C1BF13D87,000019A04EF00EC8,F42C881623E48266,C370E588FF55FC9B,727FBFD7048DC354,5ACD586CAFD6C07F,F9DEF259654B0140,4BC3BF9853C58117,30079AF6888EAE64,CF3B190ED81E17FF,A4F511F4A1803854,99F06DC13D5B6E6A,B60FAB1600F98E47,00004679771900C1,B27D757765072B4A,77A35731AE37E262,BE9C2D36AA66B39B,44337A25B04882AA,10129EA30CD135C8,1A9531B72876823F,54A314BFADB63557,DC6B1FF917A4F7E1,104CA84D0C3982B3,F1D4F99F254B016A,14348F916475B628,000057CC3A607E15,0A1DEB46DC906283,9E4734B7AAD9AD38,BD45C560C1AA23C6,EA8A172243D52710,E178D9EBC0CCBFC0,CEB9A8D3E9D79361,35F6A15A3CE41BE2,63B524AB6CA471E9,6F8C56FBAA25DB6F,E11FE2B7DF9E1FF2,CCE6DBCBB2D1B5F9,000003E2272DC1C9,C4F92E1453F8E577,47BB61DEC0D5930E,A957E34DAFC65F28,55C8EF5AE47FDDF2,0D08E5E08288BF9A,303326064BF92D1E,15DF75CADC2EAED3,2045C3B9828888C0,A241AF380709C5BF,0F1983C3BF0814E9,1A645ADC83E1DEA3,00004D4C0923B96F,D47E8AD7B9D52516,B669915F0B7C59A2,D61AB33008D049BF,8659D4DDD17FC512,322B384A01D4B148,85A83F8C8E4153DA,57D9E13AD29C2ED0,D1712263BAD74818,D3B09EE7BD98BBF7,5BB9434DF8C100A0,B4952C3C37897D08,00000124BA327587,AC36445BBD07D318,8E6D9CF702A6952A,26BC33CC42A2D9EE,4B42A006203A98C2,28C921F4CCBB73C4,39FA7A232BE6422E,602A71D052ACF7B2,18E484988F5866FA,3F5FC67439A1BCE6,06800F42AC7C5407,98CF7F9F0FF1387A,000049E3539F2499,CF98371A8D923393,EA603ABA93FAB4C6,435AED533D6780E7,E4D7392B12FBAB14,10BC425EEF2BC9EC,DC8D278F034DD393,67D3AD40139163AB,4A0A2B953C75EF1B,D353990FEDB77B55,A4D2437D2DDA2167,D853F89655B0BDAE,0000251A7B7BD793,19C6FAD500F5441C,4784F2AF96EA4466,DEB3EE01B2D3BAE7,2C222C6C339A3BB9,6AB2F44A1A19A077,CA8A156002638478,0C1B8D20C0CED75E,2515314DE4DDE23E,1F4F89E48921985B,71DAACE92EBA496C,4788A602AED310C7,0000330D8A801C02,118687663202A616,3A8E91A556D63EFA,8C34DFECF5710CCF,88505464016B959A,86F7A77A4DFD751C,8724BE34AE093FB1,AD0935945FB55A3D,590D727FFC293415,62FF52E347735D25,B8DDCABB2A5F7344,887DCF52FF452BB4,00005CDBCA1BF7E4,E2A9858AD4707D68,2FFA4060479DADA2,25C4ACC99BE32D33,4CEFF5D618B6D2BC,BCA8F0867CB6FFFB,DD8EF1FF2D92FCA1,51A60E3622A7CD1D,644727009B019D35,F4238B0C8DC80081,4E30507C1E9A0499,B9F36C608B8DFA33,00006AA403DFDBD3,1F98EE90304FC67E,4799DDE5C6C30522,89FAF8C14B8DB56A,560BD1932CDC62DB,2CB724F63ABFDFD1,C4BD4E3C91E994CA,F056F01B0B7EC075,8AA8688A38E08D39,4145C4847413C78D,201D8343F9DB73C8,833BBB0C0C1AA9E4,00004580F4F4CC94,6DEC92C50588A7F7,F81518B60DC43B2B,9F0752935D33176A,3236B94D0D320CC9,01A1C923254EB6EB,F6CB0104F543DB6E,51A505BE56F5BCA1,8EB0869EA9D06BFF,32D82F95E314737C,619FEE9EC85FD343,8E0269E0D6C57741,000037FAEB41C6E0,B5DD9B6C266437CD,C6C76A9C5DFCE0A0,DF3D5E21C6FA3787,5CBC86689126F8A4,EC76D88AB35E7889,29E21FE870855747,034344DBD5A9CEFE,5E119AA526B5B8D2,AB1D589FCD8011DE,5FF05B060F6F1490,65A0C8BBA5463046,0000024E5F279CCB,299BDF8EADC77AE4,A0EA39D8696A92B7,1ADD4D3191F4D8D6,5FE26F29A143405C,F758F63DCDA7F10E,296444EFCAF6932A,663749BAFB8FECD3,78FF7FFB642E9BC1,28C4FD23FA250C23,C4FAD4FA3184D1C8,82D666017A037C0F,000021CB4359B6BF,94986CFA4C1A5B91,1D73E3044B180243,2A660E4B9A17CA3C,CBB497E9441500A7,CA2B8414F1C04902,5A3BFD67051A4DE7,DFB92AAE628CF858,0D118955577B8C0B,83D34FA589C03FEE,647A1D02DF41A8EF,FD856757370E6DA9,000060C822CB6CDA,9023F83BE2D6AA56,29CA58050295338B,441259570B5A79B5,4817EDAE462F4B53,6432135A0C1D97AF,DFB4DFF98A20F30D,85BBCC84E9AA0036,9F2462B67CA9AEFB,133336B3FB92B5A6,C882E7ADD38615CE,68F1539011FFE523,0000045C53E2DF01,6F085E1BFF2B889A,D33CACDCDAB7FAAA,7CA36D7DF38A0929,6F7EABA62AF83C36,DAC11D4C5ED41940,537F9645453C794A,40049D77F4B582E9,B024231B9A3AA871,B43DDD96E123FCC8,A8EFF0D6A61314BF,AD40776F370B73C5,000003FB494BD003,93CE0A51788DDBE4,E2C1BFAA36D9EDE2,1AF040AE6DDBE7E2,265179DF29529416,C1E36D6F4FBAAA6C,9DFA4B5B31AD70CE,A59FC94250EF2441,596CCD7B39700115,D863F2FB2FA2D89A,756E1B98A7CEA9C6,AE7E9B11C8F40A7A,000019914602519B,E9BCFFBC2E92C8E5,836ED898C6D39CC4,78F13C546FB3E853,52FB6826C8A68C70,23657CC42A710DA5,771052A645242A27,D194572A4B2A16D1,09CD99CE68A10F67,E0714B7F33EA4BA1,582AA2CF48A7BB19,B264BD6CA19BA4DF,000016CD407FE35C,4165D43E119F77A1,954DF431E16B3624,58D11C5244C707F0,08A0E68616391284,E347A8F3A4043314,8788328A7D2D2DE5,AAAE6ED9714E338B,E6E0BC8C123ACC37,914D8873EDDDB189,39B7F741B90E13C0,1822CA3BD932CB9A,000033AB266CF76D,ECAA9D9705F7B16D,120D198CFE3FA1C9,40B456E146C55B9B,BF4D2F7A36C476DF,7F81E3E6980411BD,E9419B5F9F22E0C0,38596C1520A9C2E7,5EA1D8B575617969,0DE9DF15499EC94C,51BF8F087106054A,4AFDB6BF2E5F840C,0000414CA813B07A,D7E413FDA0ECD097,DCF3C5520E3E286E,7DDBD131CA54B27B,3FD2467B08FCC185,03481DD41BD368C8,7521424DD383F4D7,0418787A8F9E6840,AEF2A6899D22542B,9CA4B0E72C587089,20B9CD12B21674A3,1055A73392FD7045,000001ECEA9CDBD1,0133233416D33475,0DD2CD120BE16C7B,466EEE6C317266CC,97E001A87FE9C562,D0C51333BFCE6E8F,EDCD99459A5DA8B6,4E7047E6A02E61E5,E3E37268BBDCFF0E,DB35F4738D5D604E,701B48241DB17C50,B5445CC1D861BCA4,000037CA629682A4,9957DE90E7714D37,C855A6A39A2113C9,A4B9F8765F5485B5,D36C4EA2F4288298,B70DC8F787E4DE01,1C706A9668DEAB65,6BB2CD930191E9F2,88D570CCDDEF590A,16B408D1E0E08A79,1D6CC1683AEFA902,D00E78202E5889C6,0000477159162A56,C5B59B7549373690,CB43AF1472704DA6,A8C59D28A7B448E0,2432DE62316CB99E,DFD9348F85922AC3,3C07A64A593400C2,E01A5AD07C70D46D,CDCA3D7786F68DF5,506A8451206203D4,F9A3DE7E404670C0,8FD086396FD2735B,0000077FFD3E9524,31670173EBDFEC07,4C62F331905F0980,D97C24040E16A961,BAE73FFB3B4B69DC,DB5D4B8B654F5A4E,63402FB40EE5F0EA,E8CB4231B47C743F,7ED5BBC77E4BA490,5C3A725F4D9E1821,8E52296358C1C0A3,6602CA6A368061F6,000037BCA3F73A44,912BC97AAAE46019,177BDADBF6FA4E60,A36B2051A55D7B16,049206A1495A7AB0,AEA0B2F15602DF27,8216C5110143B4DC,CD98015443069F11,063CB69F9535805A,9CBFA904182C016D,4E64CEEA6C86D9EB,BAC1FD6FE1D2BD65,000030A4CB60042F,A2DE4113675DDBEF,34FFE67BFE18A8DD,0A6A3C88A676FE7C,27344531730837C3,FB81ABE9BDFA2535,85E91AC0E5EFFB90,2665D4D85AAA600E,BD1F466F4202EB36,F8CD5947D2D4F537,77B228CF92C16567,049CCA9F63821AC0,000035277F65E21A,11903F9555595C7B,60B0DBB093EA8231,6DB745BA6DEE6704,5BE67B093F52262A,F7C4BAA4A26E2EB7,0DBF16097D0054C0,B0CA6FB4CEAFB407,C70C35FE7C9128FE,400BCFC1BB6CBA84,78992833E4EC000B,34E69E7B26136818,000068FEEC194CFC,2A9951304BA3F864,BADF6327BB217120,652EF0241FCC013B,2E59E82E72C0FB2E,84D4B0EF6515FB4C,067437EE9279183F,E64335630D4F526B,206D081C607EF856,0B669963C7064AD4,968EED23737EFEFC,5125CF280DCAFD64,0000483F5E53E661,2F335CD13DDF0D00,E49890225A2CA38B,226EA826BEDA925C,5FA03142F82FCA66,300ADEA166394D25,D6BB584E264F8050,7624BBC50F885F05,8A16A346D4420D76,49C355DFD83DE974,4C8F151A4C40A60B,A0354C2F1C61E3A4,000042312A4EA948,5AD055EBCE50DE35,F241496CCDDC9DB9,64ACF10256B2EEB7,B068EA888D52D605,8D2216148981178F,71BFC2ABA97BFA01,D4E490FA54A618BD,750AE08F8F506A76,3C00A550709EB000,10B9AFDB1D365248,AD57D417173DA149,000060A32E98D581,945471C267141295,4D411C3DBD31EB54,6EDB572D3DF59327,AF6DF856FBF1B539,758F7EC851FA3AD1,1778AAB1F74FAA19,8B9A0F9C68AD8560,C0EFADF2386B824E,1C3862B63543C20A,C1A1A1194DDD9F0F,4554BF15480C1B22,000013D50C5F5FF8,02D5F6BBE2093652,C54B0415AB562D67,CB761EE6744C04C8,98B8374413C65376,19E1BAE75A6531AD,DF014BE8C68E57D8,6E5DFEA693FC0484,183A4A6864E6E3EF,EEECF2FC5E695C2C,5B0BB809B8B8875C,F0ADBD01112A8443,00000B996F032DE8,E6D71F05CFD5C060,AD06CBBE46419736,2322C042DD9C968F,699BEDDA11A2CABD,225BFF498A3293AA,285FBED38E5C468A,D32B56522356CCFB,328061C41E38A825,E9533EC544DE6343,B50701BB1FAEC2B9,CDAF512A2B803678,00001DE36DD003E0,81880A535707B81A,93C44233BFA8D494,9870A9F26F3391A4,506664982BBF6450,3D7E71FFC1EE21D1,5553B1DDE7EC3BE9,D55ECBF788E5B24D,865FACB06F97BAB5,00661DD4673AC819,94ADAF3E222E52DE,7FCA1AB9D6246CAD,00003C48D671EA7F,499E996CD8CB3A6C,5208449EB08BD3C3,AE243ECACD0B8FD1,9ACDA3CEE89AE42C,F191C1B35A710886,00AA20E6D390B628,1031EB0F74A7A55C,50157310179D8D23,92A1B9535014943B,FE5179D5A788929A,535A35E8A29EC202,00005DA743D036AC,9268230CAE051EA6,F4559C1B7DCC837D,BB9B46CDFB09E169,F05D234EFCA9DC72,BEBE128967613CC4,0BF47361A6C07FDF,0A9D96FE2C250B3B,79231056FE133ADC,B79BF2CA1D5D343B,305B7EC660C9A436,85DFABE38CBC5BEB,00003B01D4C286B7,B17C290397A7C323,73039BD271A19545,02722BC68F573C30,06F3011A793F1E62,02070B633E375C29,7D71EDD2DCBC2F4D,E8CDBA0D306BFADE,1F8A9BF2E03AA574,4B0F6074A8DF61C7,99DA0D8CEBBC0B2A,00EE267164DE09A2,0000373449D7C900,832A42975EC5039C,A0105EEAB5D0B524,93FB001938FB2DEC,EA714FAEA7E99DD7,CA9D5FB51338CF86,D59D828111A3F2FB,DD6C8FC8498BA5C5,25578AE9372E9660,4F259131C195497D,871475665CFE467E,93DC2FB47F7233AD,00002FA82DFEC4BA,AB44F7466FB2DA3F,3EF0D4BA1E303600,DE2A15E001F9880F,EFE101602AEE6873,F3E7E79B1436156B,ED1F6C1139AACE9F,C088D03EC10FF701,046729D13E7EDA7C,5FC69712D36A50E8,FA75F2016C457366,4DD1C55097B815B2,00005908EA540AA1,A2F3280981600FC5,26FC8C2ED95C6620,889916729C3E0E60,1FE8F133680DC8F1,F22503D77AD95E90,3A36BE928F7351D0,EEE4F41937CB0505,9605E39F5218C0FF,F40B3CA50C2F17A1,51939E9C6D3B409F,E43F9FF27348B2C6,00004D33D1803084,B47CAA1173042DC3,55669BD317FF2DCA,D577FC5D4E5B8E20,B7791AEA764900C7,E41523FC1BDED921,4B19A51B9572CD03,F8D8810470B51B20,6587400E59A8FA52,09C96BE29C40783D,28146C6255C56545,CBB91B06E7D18AAA,0000693FD68ED7D8,ABB54C6EA74817F2,28D981A04D0C4B1B,EDE6B3AE17428A8F,19EE4F6C027DBBF8,DCB5D92EDF8FD08C,543215776BC22509,B2F575ACE3C1B046,E7BBEB51F7DEF080,B51BB62BF9914A33,AA57E33A0C9E74A6,9B7692D3212FC8F1,00005784793343F5,09946AA5047862C4,B4A10EFB17ED917C,A00FC2E4777E759B,8ABE6BFE06BCE9A4,83D78E20DA6D289A,524DCF79F0096312,ACB33DC8FEFA9389,BA8A6E756EB22CAC,3B2E601ABC23646A,7A54A48540E12E07,5DC4AEA63146BF00,00002810EAB41889,DEC7E5AE4D0872E6,B7DFFE4A56E21084,AA14D7259392CA70,CAE8ABB80FB3DB15,C4E139F3A06A2443,4FC3961D0C4E8413,F659E11180877DFE,90A7B3C3E5BA6211,01B7643A0379BC69,F5BF350E84CE8806,0421B2E103A8FAE5,00006BBBD85352B6,A41D2970AA577FAB,BFA046E65E1A86D7,EB33B2B404DB6ADA,1A0CC55EA6D5D9EF,A448C793494E5E8E,AD8514385B0DF371,2B4660FBBD44D271,11A27E6BA036717D,DFD383F2C9096E1C,A0F78CFA3814AD58,5DD07EE1A8F29696,0000282D1F1D27F7,691D1E6E1AEE364A,DC2AD876D0B710FB,7C1B546FBA27F052,D5F645BB8E7C60FE,53E05CE6C17FE5E1,F6CF18A92174D763,655DC4E056F69F6F,7ED772FCA52B44A8,755105DF11DE059A,37066D9430482696,185D54734D7421F9,000026560395BDC7,72E32BDBC11535B4,5268DF865934AE57,E7354A6FF510DEC4,AF13E599A5758E06,9622EA10D23857D5,50D276EFEF7F3FF8,6ECA66091ABCFE40,0FC5DB4E55D61394,D1A2561D8E9FEDDB,6952BE34EE676E1D,EF1A3BFDBB2A98D2,000054B05F3B1331,C2C6D3B29B2DEB79,B7518B1FFDF382A8,9735338287BD930F,5E804AFEC678BA3D,E5D3594E3C90ABE9,F3DF10372F889E87,1D5E63F205B85FF2,3FD53B31E32CFBA7,32C0A5BA145B0BAA,171930E968051001,7A07C2FE97EE32C0,00003F6BA700BB64,31B72499259EC654,FFAD4E8516CAD19F,B4232787C4997F79,5BAD837F81B31276,39317CA98F9D18AF,186354A83ED1DD92,A4D95885F539121A,7CC6DF8E91F458F8,8ABAEF704B0E3305,4478471EB2FDEEE5,DF0C7E8EB2E15EAB,0000255C6459A876,89B5A0CCC61E696F,2CE112354FDA0FA1,F4E6A4A264A1EB21,E817284CB3BB317F,4A6EF3D577972B30,AA20AA15E0759F48,C133D272C3C4FB14,37C021D3EDC7D98D,24F4A43623AEE2DB,F4850A33BF6D3843,978E10AFEC3F8A04,000066E6FB256489,E87EA42EF3F45FD7,A30F6362CD7920AF,FBC9622749A303D6,9CC6A40EDC323DC0,9C60EAA5F4C13CFB,FC4F2D08DA7A8D1D,B13B7233A9009BEF,C9C5CE5FDC245A7B,02BE955C318D5B69,F06D49C5A9A40E02,2C560C18A9F2328B,0000375517F2E065,D6FC77C89B46DF0A,CCD1C8A9D13470BF,5BD733E15D90D0B9,41553DC82E41D7D3,72325233B1D543CF,36EFD339A5C86C4B,6BBBE792A3260382,253AA0247707EA1F,6BC955C35A0123AD,1DE562075B7D197A,CA7CFFB8904658D2,00006E1DEE6D766B,4B1835C848B3575D,49BD7AED61B8C9EB,534EFD493DE9E16C,4B7F64BC74EA11FB,381538B0956A19B4,8515A18DB4622672,25D0471AF47B667A,FBE8296B29877F06,E2779F7FC0085717,A3F7142B031EA24D,C9E45A9AEA943C49,00001BFE09AD92DE,313CFA4CDE0FF12D,3566BCDE741B89B2,4DA4E87135BA131F,334A6988D28C7FBC,59EF299C408F3DAE,B777A56DCEBCBF3D,B05660330986DE14,645AEEE79ECCE2B4,3D3AC8A41C7983A3,96FF58BD56B779C0,FCAECD78ED8B81BF,00006B4982C1D755,445C45159393D80E,CAF9D69CA2120344,3FF908DE0BB3A39B,CA7917C8A81EFD65,F9827AEC2E145458,480D7AC336665148,8314536E689A2F78,0D91C6F29CFA0756,8E4373765FA7CDDA,E0F56076675B70C5,AB758B08461B5765,0000486C4A77BE05,A3F9E874CBE8F5E9,FD20E30FA8ACD7E0,A7051610A903CE5E,9E054F25C66A7C0E,81AAD188BBB8E2AB,A85A45DE812EF271,F8CF046C92E860AF,FF10BE7D0A11C52D,9AE7210F4DE8B8E1,C21BF8D755A50733,5AF8A89F36966284,000047A266DF06CB,2F70E9D5422F2FBA,2C2863FC06CC05AA,AC14326E54F0E7CC,3E87EC23858363D5,3EC93F62B620E7D1,4AA34C84F72E5E89,A04DA8F7AAE464CD,1A515E99AB85D8E3,DA009BDFB4E1BC23,D21DB7F05ACEDC47,C1DE003EB90CAF5D,00001F6E0CAD4E2A,3125843A6617D2E4,EB1026C340577C9F,0E4CAAB2547F7A65,78D4D5EE838850B6,21186D81A1C62447,875CDB04FD5C6617,E0B3B7DCCB80D9F8,CBF47CB34EC8C28A,7DFD9CA9BAF2AFF7,72992DE624BCCB5F,BE69C246FE53ECBF,00004D82F8B7CF96,5FF67A80C7B7F546,B5202AED83F0AFAE,3277046E6901CFFC,5A594485E2B6FB7A,4F9C7EACD3568185,AB75CCF5DA85D3C8,E80A10458A16951B,BCA697E551754983,5926D6A7BB51DC4C,3D2183E1F81D2C39,E5179B7AF1D8AA8F,00004DD2C1BB811E,3F7D66700FC8FDF4,AB2DEC387C8C965B,D88415445A132EA4,6AF23E1431756EF0,0753EC7F33CCA29F,2DE23D144B89B412,77425320A8A0E4AB,B1D6D9F5B40B6DD5,1B360FE56307679A,D8EA864E3B7DCC17,38640DAA8CE9C6E2,000061FFAF655F4A,14D0067B739A0039,ADEC31D762082ADD,A8DE041C8AB6571B,57908DFA0753CC2B,DF3F2CF6EC6B1DDB,8EF655BD4CE26677,A9D71D2CE5ECAF34,EC0048D9113ACC69,F02A78DEBB628644,4B72AA2A69EC1874,8DFF80A7963A6BF1,000060D86993AEA6,010BAB983A1D0311,DC7C072A7036BC29,6BFC23A0611A56EA,70D87BAA9255A993,CD64B5E36C34F5E6,32A399D37C5BA1C6,7AE610CA4D0D4B8A,B4F172F4646D7C11,E234822DEFD65F3A,F6B4693817E54DDA,CC966F687B178C38,000063BF3690B178,0F14B00F46AEEC9F,58C1BF4B86C86BC9,9F2D80380637F7FB,F46B6C741B8865DF,2243F267FCD409C2,29CCE9E4F23C25D2,2FDA9F2E02EB998E,4C0947E322D9230B,9DF3CF4CBFAA8E8B,F1995946F52FD4B4,D5F08D4C2048FDD4,00001F9A9199CC44,9234006FE690A45B,06FC4CD70695165F,DF8DDB245DA94FDC,4A45BC055F5D6995,4A61E5BC08BE6C7A,C7B8D664087C0BAD,2DBCEDDDCF76F15D,5E629CBD625A4420,0664E5A2B0964117,1D052E40150681B2,1B133545D367CA46,00005E678D6A7AD8,D1AEF2A1C10AED3C,F580627CBECFF8C1,FA11EFEDBAD83F5E,8C2F5504D0DA47F1,91CF51FEA416F3C9,0DC3D5FC0B0F58BF,0D275D1B5DB8C4A7,9F4C08903BDE8815,0144C952437375A8,9E1B30016ADA7D7C,FC03FDF1F66B94B6,00004D2ACC16FECB,93D83C675641CE3E,210EFB0B087AE8B0,459DE41AE7D2EEA6,9DAA635DEA1D34D5,1A8FAE1472419C42,3D8BE7651706D324,6D5A01A7FF92E05A,79CEEC016F734A30,B5BC8E92B70D7BF9,EA8965C25E802934,B67123A2DE8A9CB1,00000E6A38CC8039,2800BC4FF85D7D5A,4A61AA6D7CFDBD40,4689CF539B82C568,B499B457406D0E8A,C26559F772BD9576,2AE36C61A8E66A07,BCFEF0D06E679E71,C240A6F0CDBCA6F4,703558A90001D9CF,1C13491571985ED7,509166B0DD8F1776,0000352FC598F256,D0DEABC55DE813B8,F83EDC6AD0694018,BD3196D12FF9ADA2,628245613279A7DD,B2FD737497D714C5,18F897AF8EFC02AB,8A785A1BDC0A13B3,C5B0E266235657C2,B855DF8ADF3EA7FB,806050817E094EF7,7EB2428018FF6197,000012430394CB69,3B6E7284118BDA6B,817034EF028C85BA,AE71492BE9A7B020,130FBF9064B75C04,F3322C6D0E0A4257,5D35E9854549D782,807AAF6BC0B8E346,A4A25D71FF15DDEB,17BCB55A1994A9E0,9C950EFDB74D86A1,11964E72AE5253DC,00005B3270259DAC,BA624C79A5D4DD17,88DD65A13FAA5BDE,8381FADE22895CF8,49A5D67D1B2669BE,D4A663E3FFD65132,670B640D0AEED8E6,077EE8C0E3FBF5C8,8535BB0CC8BDADED,B4ED9590B9867551,712138AEBF8E8FD9,07CEDCF98695D02A,000067532B66F204,F77F52D258AED579,9107D0A0877F03A2,271CAB09E04B0E49,D6D168646EF8FFCB,1432CF7BADC6EBF6,9E9AF5568A1BCBB9,0E882C807746BC83,FCE33354487A279E,720F46A54AF1455C,0116A9F5F595698B,3FE5A41673A31E7D,00000CB80605AF80,BF87F437BAE756F6,4C4D31DE4508CAA6,78F43740FB008C85,E0FA2B93E5DE9C5C,8B3E8AB0E5FA1F48,AA73A14E781AD6E6,6C3001B5E488C827,56E08A6AC76CB0B6,489FAD43EABA5BBC,6E74FCBA07A81396,4F8107ACCC29EE36,00000889CC0D017E,3F41221211582C78,749D452B82CB6A1C,E82852632C9E32EA,EF04B4D607A712ED,D642597B5CEE070C,5862638E08815584,456A63D5933186CC,A92B93689FFCB945,130FD772D079166A,6D9078BD95687171,A373F161A0D3518A,0000401A4221536F,1B0750F2F8E68A7B,031CC5701C503B3A,CDBADA7EAB4919CE,C6B1D5B97500B2E7,AF5B79CF34031E8E,FFFD721F102755D9,592A08DB81948B81,D0C8A0C3F2BD8C1B,34B29492A2265F2C,BFED6A85A97FF599,81FA088CDDB892AD,000051E824B4B8B2,7D7176B84FC0F0B9,E20BFD6F3BA62DFD,75FF997A3A5B5793,79569ECDAB73FDF9,39E27AD533A38A4E,C2C166D9D6021A41,71089F58F27FC622,7B0263FC3644566A,E064F13A6962643E,A6EA31075EEA6F48,32F3CF65C4826BEC,0000474B5DD287E1,902349AFCA8FCD0A,FA896417AC7E86CC,00B5F055AFC19B74,39B1069E50F18294,A5A0BD7A31B489F8,F9629C8593E086A5,5CE91C810C3170D6,46C239E5BEED1170,B4A3BC32BC9BB76A,4878C059BF2FD8CA,D4C3AD7912807BCF,00005244E1DF892C,BCBFCF74D0ABA336,07F071BA95675382,7546C4A4DCB3E0A2,A03B682B04E173D4,EDB35A878719C117,5B647FFF05BF60B8,6A8477EF4F8DAD35,B0455A313C9CA21B,0A8CB3F5F2CBB5A3,29F9491BBE92704C,216A0D3738BFBA95,00005A56EBE18471,E8FA79B1E4B8F3D8,52AC021837340EDB,B108114E7F9151A8,1F288CE775852929,CD3698774E42B57F,7105C90E4349F7C9,57A1905FB3C9C195,37BA52CA46DE875C,AF58E2827D3966AB,1306508A5FE49857,13BE9C14F009509D,000014EE3632613F,1AAB5C60463DCA7E,D630028A5DB4B968,EF93CDC6824C0DB3,775F22697F288962,20475D79CDD08EB7,D07E00D10D2959D9,A54F044AB91CB6C0,5346459F78FE28B1,36F6EEC550EC4979,CFEF5BE78036B9A9,1B938CE76FF25D9E,000019C0257E3BC8,55662BBAD747160A,3451FA2550ECC494,59A34C859F95A76C,4326B7698EE77C10,1E01EB579B27AD04,3920F2BDC1A3A2DB,4E2A44F6C2AC0BAE,FA5B6DDB609B5514,363018BD8A997E80,B34C727079F6ADE2,AC460048721D753E,00000FBD77B0CF40,F9630A1657A5E43C,6CE675FB9EE0AE8D,2F79C021A47339F5,5B91CB93328621AC,EE8C30F65FFFA152,CA969B29A2484DDC,95F15D1F023EB895,59FD58A2CB66633F,0EE34A22D6925C29,8543169A5C14824F,E071CD6CE9324CB2,0000363AE900D8A0,E41C8AC4D6EFA260,BD3D77527EF40DA3,DDF8121447432D89,EC15D22D552D787B,725FEA0167536705,DD26414C833E50CA,9A0040D382D1B687,526A92E6EF3FEF25,0D4A1BB26646EABC,1A5E433BF32EF469,F38C54FEC65020F8,0000295E64981808,3C607AED404E1D6E,508F7C85F72B8DEB,900835E313FF944B,ED72FFC03BC8F997,A23FD7283231A61F,2321376F7EC23CBD,697284847351644C,A41C1BF33CCA3793,FD460E2ED960D8A2,D92C1AE18B12F80F,6A6DB7650F2021AA,00004B50FD3D934A,CB8A7C0BD7773022,508906E81A47BFF8,13BC6DEB35445FCE,59AB1A33569D64DC,A1440B02130A11A5,3EF22CDE180DF2C3,6A2A36879340346A,E8ABE2C9E71EEB09,B4DB72BDB97717B1,FE8AA3FF76B326E6,230F5E7CC30D7511,000059BF964F6FA9,D7A0A525072D58D6,539DF9A98B0FE497,772C9F1D13D63DF6,B99A7508F7181AEF,3915558CD7012468,33B7BE251606559F,D2521D8EB4A707E9,95FEBABA65E999E2,9563C1C7140637EE,BEAE487873DBBD62,CA12E70346C0BC63,00006469B08F8040,64D59E72D5B69EF4,FC133BFF80A695D9,31449D5C4426CF85,CEB51706A3FFECCD,FB121CF8498118F1,FC1851F4AA52F575,C08C899116A68B3A,23DEB8D2AA46B1E5,9B0C3CC47F17B362,7E42161EF28FD015,565544AB5AC9F360,000040F6B883ACEF,12E12A9C6F47AC71,817B202FCD21359C,E99BBA91136BBB0F,4D2EAB4258C92A74,14BF402D019E7144,1A33FEA31B0E66B5,00C31415FCD0D4CA,F259E442E479CE03,AA65E14F4E26C744,840894940707730D,01277018C2F39007,000032725B3063FD,C58768BD8893A47F,8AE58D258EF40F60,3FE4F9F3D22E00D7,16DBD00340E1386A,8CB60F5C59C8F1B7,972ACFB34911D8CC,EF5FE052D83A7D7F,719675BECAB7BBB2,744FABA9DA3703CA,1F40897CF7381969,E2ABFD0179DD900E,00006CEDC302C138,09ADC2D5F9A3B2E7,3A9DEB793BB641F4,E5570B3B7E41FDC7,7D8B2C6AB6268915,0F196573B0840BFC,1C409DD6C8F4A24F,2B4BFD0589C330C5,4FF2B07121296137,B0DF2FE192B4F4DC,6467670256B373DA,A986BC58D973E101,00003FF425743C08,A5D4598C14439F27,53DE4B7C13424426,BB39B9466E874D17,84C99A68CF5A5E23,41B569DE80AA5A00,DED0EFEA79BBC0AC,CAC1BE744FB2111A,BE5106EE242CB1D8,5A545903A26A876F,609CF5FE461737AD,CB1321095E03D446,00001E4C950E0BFC,1DC240CE508E44D6,B75B006754FF8512,8D795F50ECB1FD25,6083BD915EE7BF1C,C1BD982AA8E9B1A5,9C4B569F5CEF4B60,C7BBA0DA17D37F08,CC39E23B456A1CD1,8A792C0B6089D9B5,CE4A8CBBD879703B,0DBD45B50B65B713,000031174706917B,0E2BC2341097B226,FE1C5DBA52738020,E01FFF33B452AD3E,07BE05727367FDA1,B1A7921C1D15364F,3332984F83DDFB99,C965F2754A2779EE,F6349018F9D20EC0,AFCF69F47DDCB860,1B54856C1A543F04,64AA9278E19EA96C,00003122C6F2EDB8,69F41D18B4973241,C1B54F011178F7AE,D7AE7B5BE20CCE22,3B324444455A6E35,07D311BEE5D9D11D,D7BF7664819480F2,76377DE070C60970,7E3D1DF2DFD38829,ED4B74ACB58ECEB4,32A285B012F23ED2,4F2173027057D46F,00001F8A66FABC59,0663E5FE6C6BFBD2,66D35E730A34805E,A6296BD0B3444992,52064D844A918590,23B9E39EDEBD5A76,7579D744A2271320,7974CB47D6FD93F6,8DECF1E3CBF80309,8A4268661BCCE161,54425F7524ED04D4,2CAE00827F0CC38D,0000515F29D1A1DF,7F42207C4697FF2F,3A92DFF2C02EF77F,587BD6A7F80BC4BF,77C989078F93D667,C5F164B0415E5DB0,454126C9028C1320,9D2AAC87047A6E07,B4740B82CBB4549F,B5A5458ED1B9EC4D,B755F826AA0E4AE2,4A5C34802AF21C0F,00001BCFB3B82A7D,3DBC2E9896634A6B,2FEEAE68F2914D8A,8838414E9B78D370,510547C307388DFB,19D618C13320801C,C1D93112FA8AC032,D3CDCD5EA497D7E1,EEDC6C046974BDFC,010B2E4300E6DFC5,87CECEF4C5F95CE9,29A14F72461AB269,00000243DC818EDE,DBAC455DE1145833,2D195977234A45A3,FAB83399211CE37E,A705E729E6B38CDA,D6EF7843BE489ADF,55131BA79B03F0E9,A13BDE6E88EA4A47,5BC90A6C5DBDA059,825737A0E4B5484D,957E49C26316568E,1DD6E631D65D0BF7,00005A303C66F42E,697D27241A7EF4E2,D1263C8456424D51,7AA393CBCCC1907D,F4D6C827EC145E9D,BC2638F288B3ACC8,BD6BCED782977599,63315B7D1EA27916,79B31BD62745E8BC,9FA073873C051BBC,BD2D6E35E6A0454A,24424CB8B686CE7E,0000562EC1CE5497,3B84495D9D2EE376,770C24365DB0103B,9511D665AEEA4ECE,7380B12F3A0EB17A,F81641FA3F08BB15,08A0EF12E796D034,63C0E4324FFD0987,989FE01720920D8A,AC570BE94EE6EA0E,D9D82CCCB189BCA4,074E99F1B1479944,000021B3C8ADC6D2,CEFE177D449F3381,D3FB5E72CBF44F7B,57697C52C1479B98,CEFED624D2872067,3CEFECBCB1D22E21,B71D384D1BF0671B,2A7A97FFD5BB9303,B2B1B19FDE30C399,6EBF2DE4A7F1FAF9,D3D7DC80123D9BFA,44A6BB95BF9185F1,000006AEAA5ED0F8,937B1087CF4045E4,212A5A58704DF78A,3E291A9867BF05FF,A6400C706346E1E4,3851DBA6FC9DBB8C,2547BBF477284A14,D7AB5995E35956D5,B0D7A78A4563737A,E270C7755E6E24D5,776A7AE1EFC450F1,8D1EDEAD131B9284,00006F817B1CB5A0,723D7C3E60504622,6BB37D58C8B94C3C,7E2636B34A24E056,F7F5E528511C8A5E,BFE464ED22B63708,5C9809E521217E72,F81803470DEE851E,936BE3F2A8144607,04EF22D057F9EE78,6135EF1DC3CF02C5,5105184B2B9DBD92,000021691BA3E81B,814478B6B765F4DF,4D0EF8BAEDD368EC,8E9433A34BA00E81,E2EFC478665884DB,843C3BE08EBC1417,3EC20CDE44FC485C,68E9BFC6C25280A7,FB2A4764F8AD8118,08AB59A84466F8D2,34482E26A302780C,CC431CE4E6ABF5EC,000043EB25D647C6,D7455D97299212E2,48CAD4BEA9FCB650,2D9FB1C7E604CB61,9EF4D5F9DD1B396E,DC40A656DB162668,E2DD44112BCCFA7F,281D43D3D6B0B872,C8A893EE2807C70E,DDEEB04ED7DCEF8A,B0366B808C26CA33,680992E60A3491D9,000023397D3EB006,04551A65469C414A,3B4AC1FC20CFD7B5,1391D49B551BE4F6,C7F5BBEA45303E4E,1B22E778211FE253,CBF493CCDE6EA79E,EFAB059AC996DC70,5639749107E25DF6,37100D95ACB48F98,88CCF867879E5651,19F9F858686F27A4,00006F226A326215,E43BDE3F714EC23F,1F044AF3684AEAE9,92F1EC0AFC5340C0,014E624C5A398B76,41C84C1A96EFEA3B,D9A739FF131B287A,9E7A82DFA22B351B,694EC5D56860C3FF,40B0F6CD88A0B559,0B0655074A111D5E,405318DDC9D945F0,00000D7A15226E8C,E8B0F4FF4591855E,8B98D3B107AF13AF,403B7A35361F4392,9D78D1093B9E9BA0,55C7CD3CA064E71A,1569EB9DEC2722CC,4D34E93225D9E4CF,FC08AAAB154D6BA4,DBEEA49163A049B4,4AD91BD1D7D8261B,D6C414AA17C14EC1,00001EEF60FDC18D,D0B1468D688CF7A7,EFA5494765BEE9D2,0283B463CB6462A2,98F89FA6435840B2,92DCA93F0B1DFC67,6CE74DC03FA3087B,D621AE071DCD3638,3AC8E294DC3E5CE3,06750955939712CA,F211AB2543B09A33,C4746FB8650BAB73,00006A496589861E,1DD276BEA31D9C51,FC61DF07FA9EB07B,4E2E5CD6B856DCC7,AEBBA8C82E04E58D,48F8793608E09654,9B9073E4E0597011,3FFF2071C948C105,726D70D189E01E40,E9898BA239512EA9,5D269AB548BF177C,CA34F7A309B2DA13,000024FBEC9557CA,5C1F9AB8AE8E866D,2E328A877E311C8D,5BBC15ACD8F747BF,39E7502BA22FCA04,807A003F3BDB3249,73DE9F2BEABD84B7,D2CE4AD5FDE4B520,8BBD19CBC9B8153B,FE7F073DC0C08E46,F9661127EBA821D4,19C5E835DE80DE67,000060D7A648D7C2,59C37A1259955128,3E7BCA69105DF701,4844B1D58785C739,9F89455BC7425A6A,B2BCACDAA8BAD97F,DF98EE8444923644,A47458A47A19B04A,B754DC2EFB084E45,1E4A72CE3FEC810F,373B4B2DD1E48438,444236C730DE2761,0000490289785978,65D254D591C90C41,F3BCC1DFACBC4657,A8E0D2D6462318C5,1EA5F32F3563AC4C,05DAA9285173158D,93BC88012DDFB8EF,E9139F4C1C585EA9,F24AFB15465A0D6D,1D38264204FA1BF7,BED7997DFF855B35,E9506254CA2B0BA6,0000660E7BFF194C,C188E64A96637033,1ABA4B6911B802CE,100C69C7F7928F1D,4BB5F7D74005794B,43E2D8C1F4CEC84C,7906587DB10A6823,410EB8DB548C60AD,B358CECE79089C9F,38BD6CCDA0A0A50E,DA87CBF8207C0CBC,017DBE133DC0F05A,00006030780894C9,37A13A65B61E769A,8664BBFBA9610E1B,E616B0BB40BDCD9A,4CE4E47FA1585E26,3F1358F3F743A383,05F0EF909F441E13,4723C9178D617609,F3B5FBED1A3EC63D,14556F922621A91D,B6C8890914C062F3,A152FEC493F6BECB,000013E4C4EB403A,35B4B1E5BA2B6CE8,9C3ACD0B69553DA0,5D2A23E32FC99728,A4BDC556933F9A72,BE088A856BBF30E4,EACBCE9D2DA31AE3,A3F934AF5E0D7763,63494E2421FEFBA5,18CC90D5F2040DAE,27FF032441BBCB7C,E039D2639BD8EEEC,0000527F04BF6F85,67734E0ACCB41D60,274F7E9A98D1420C,D5CACE96252DEBD6,DF6EDC171682FF8A,4A220C1309CF0DB0,8F9BB379D6E0370D,6A0BA1FCB7CE958A,F4DA57E7F3A55D29,F1E65C2B4357F6C9,1E547F75EBB4561C,63E81BC47E4DF48B,00004FA0DC286904,0D40A28ED9EA686B,83089847D6DA9556,64F9E2F77D26FB36,6F8F9708D42C6811,7F3F95538CD334D2,264D252C1B550F03,E17F261AD65D7F9E,B57F8A96EF092882,B89BCC9A1F0D9DD4,EB0A0088E06A5341,C7C115C2314EEBC3,0000251EA1CC686D,534B10A544BEC117,8393401CEC74C8E3,5778624B7010E079,5D7F8F570A527122,090D5D7EF89AAF22,402125C7448CB611,EA910922395B5E9F,E15450B2BE41D02B,1F335122DC187453,B2BC6D1E6CC31909,A271A9D53D6B763F,0000123F6065622F,E85D85CE2766DD08,77D9554ED2F88670,0F64AEF9D9E092A1,8A1E48BFBDC15A8F,28A1C7BF7D2EB9A4,9D53F2000E7B1DAB,0C208F9054024059,8B8EF4D66C22CDCD,F1FC2E390553C5A3,69FC5E668B902C92,D3E4DFC0E9BA157A,000066816492D38B,37AABBE361457D76,F888A28C77F1025C,A011B773345316EC,ACB1F0D85CAE6813,071CA1387FF24AD1,3E92C31C3412AE74,5725FE68EF177796,DAC65BFC95917AD9,E6D4E17175850642,94AC6F151B59904B,484232EC17703658,000069FBDAE7EE6E,363EDBA4D011DF40,C51790CA7F419257,44990E598513B12E,6C108910D86C2059,6D6F2CBFC75FED7C,ACCC8BADC0937148,64FD599A2F638C34,A3DAC0AD03809662,F664006ED01C886F,B2A7D1D2AFE67AFC,069093D624B057F8,000031EFF57B4BF4,3F813E58B3A6353E,1452637A68758129,2E4AD9EF7B454DD0,7C86D6930B444E9C,EB80A93699E60D58,25E5779815EA0A8B,44754242DCA76A29,50538619E87CB002,29C3FCD108569E2E,675569C6C31A54FA,8BC2C4D19EC34244,000058F5C354F13C,ABDEE55BB78B7BFD,E19F23EDDDAE224E,0AB8550B10738AC8,8CC98CAA5F28BD44,51E66011795D2749,E5BC32A706A53547,6CFCD8CC202BBF2E,37CEBC30B979B11A,D2C60BDE4CE7BF3C,58ABE71CA04F156A,F627BE824A27A8B2,000056B3601F4174,BCCD7D7C5B83F662,DB90A6F443F96D8E,BED72F2F0CB917D6,9974948415203999,69EA2461D54A9A72,943B9953033D5676,B69F12568D1BA857,EDACAA9B5A138632,5095B7E0555443A3,BC0A076AD3F03014,8A7DC2D3AD860E49,00003BE7BB3CB012,674FCE43BACE0DC1,EF722CF99F13D015,B9B9573B44706199,C1B65BACFD3C2DB8,3AE8A0FBB391A459,36CAEE8DA689740D,02E9B8828EFD517E,263D85A62BE5DFEC,86E58021F5BE2182,B79D3815C9BAEB16,32CC0CE39E602B8D,000046A0C455D7CD,57DDC34330512344,DFDC519AC119BBF1,8525C15EB142D269,DD6240AD447C3939,CC41CD19271D0AC9,C52F507F14E6C651,C0D5DD98044D7C96,DF790102ED843052,25FABC66864A5944,46963DFCEDC18D9E,DC3CFDAF5F530122,000043C78FFF8D37,5DE266AEFF2F02A0,7DBBEBC663CCCB36,A7627CF6206BE816,EA9A99A0BF9F7811,E88E5E69E2BC4681,2670E6938D302372,2DAAC12F79F9D101,38CF792087CF5E1B,D0A2CD0D56F1EE39,AF072DE1237FA60A,182070223BCB1302,0000374E0FBFA738,D2A391D75B193A0F,70FF9B4D7EDC99C1,7A119BF6A3099245,9BC179F79D7069FC,C8B5978127D109E4,3AFC267870F3E735,F2E392D14AC00C25,7B95CB9B88E4B15C,1AFE4DE70561670A,60D3793166815EF8,ED66F5FD68E4A6A0,00000804F9EDBA8A,D776A6DCCD82364E,BEBC16EA90964479,72F5FCA874B706FB,45A91EE1CF718AC2,3F8A7B8A8BBC68C0,A6E320B6BD395F7B,287AA59A1DE2501E,172911DFABD537D5,146964B9197C45EC,EFE77844E623434D,62AF7862EC2604B3,00005ADA095847CE,5BB9088152B1550B,3902FCE3E1D95780,B00FD188CFFA30FE,D1EDB630506177A9,EBE73D5121225450,FB3A1598AC622EA0,81D8AAFEAF0EA5D0,A6BE0461CD07CE12,01D745F25145E9B1,36AE25AF04929A0E,AB7553DCA210CF77,00004BAAA0802C52,8B2058DD58CD45B0,CE5DC9AD8E63348C,E39AA357C18BCB09,5A3C567317C128E4,24DCE0A3B93C81D1,321B3C56FFED8307,BC160038D7F95EE3,3CC957BE75452976,DDA40665DFBFDEB8,AECE80C404D1F2DA,6B94D78E8092FEAE,00005505B80B2AD5,8B709F1208F466A4,9F27191689DEC37A,EEBF820662756D3A,D6FD2B2E231546BF,96E589691FBB96A1,0F3EE23AF60EF5B4,8F4B353AC304297B,4F998C489F7004BE,F568B1846F001198,B5B961538A6664D8,8E832C5CB951A797,00004441B6BEF708,2FE70C0C1BDE573F,943CFC28BDF84E3D,7BA23D219FEF84A5,17266004D2A9A684,F4CDE3D0A2893F9C,AD47EC646C95780A,78D414711DA83F14,DE52E6C43B2F5675,FFAAAED3404C3D39,40A663CA804C1D3B,492EC62783782C7A,0000434E9EA6F6CD,78EB04FDB08277A8,A0EF2DD5E2683F21,6FF6120C9D9E9D57,7FDCA7307E7BB140,B0691C15A8073307,F66CF74A7AD80E0F,6D4EDD9CBC2CE9EA,F77D8B2B7C5D2799,1FCCC70B6A18871B,A5E7B9E4A8B0B3E4,C4EF381BF8A39365,0000317A02A2121A,1B1E90592092F13A,BC3E5C1D9D837F25,41694463E6FA6A9A,8AF7E7D8FCB1A36A,EA1F272087DA464E,5A2E299F77F4A002,8B7527A330C55582,DAECFDD15FA93321,05407B77BEDC5784,40391CE082C47056,4E69A35A6DD3ABC8,0000570ECAAAD61D,7F3C9C3AC43301ED,883BB1AEDB2BB96B,76AC41C19D405E3F,17869B6489101EF6,94060D1E3EF90037,37509AB76A882627,9532070F3E5577D0,D934D2FEE59BED45,4A6D6B98F377E4FD,B47B69AACB573F9F,FE3E9C78A5B41200,000057C990165CB7,BE47E5A7D8A98FB0,A7EC8CC99034FD53,64D7D6999D604D73,40C7F8E704CCAD19,8D01334B47DEA540,2E5016845D1D7532,E96B47F56E3DDDA2,72F172CC1D7990E0,AC354AE43560F733,A87840FBBF3B689A,E9D41A488FDCDC2A,000040F925170D34,64DFD1DB7E6E0E48,E56002580F82A3A9,EE94017313AA2560,F3C0E26B57720E63,2999393ACC49BDAF,E039F559EDEE0AD5,8BA5C6AB49BA3B93,D84C4BC293203C32,74356F22C235152F,C55AD9726F07EE76,81ABE04D85C5838A,00000FD6DDD6E24C,CEB706D513008F5F,80C8817CFB895F1F,9FFDCF545C71BEEA,98BC33F992FA6644,A5D2C93D85666514,58F312C443307187,A47CE77A51C2B417,891B4A9D21C95136,9B369743E8C3C95A,26662E1FD63399D0,7F725B20E9F59944,00000B2968529DA3,F073CAA5A1B0D215,76B81AB58D2904F8,A14E3112EA405918,50B6859A3D57C7B7,CBB1E9D6116EB400,F2A877255E2E8636,88FA5300F471C566,8454BCCBC996AB24,EAC0F3D3CB52E624,61E7F3D6B577E0BE,8FC562C4969A2357,00003C23CEDEFDAF,39CDEEE9E5E25E85,F17D96CADDA97E5E,6311F213C350F5D9,24198D536B07E328,812895AA029BEB3B,A71144ABB702478D,A9972FD337236ACE,9E4F00052F6A9469,62BA00C9CBA4EA9B,667560ED2EE02406,9970BE2E2347C7E7,0000682E47C97D8E,8661EB085C62B4AE,500605C9B5AE56CA,4502F502F4118BFC,9BC563B95AFD8F42,E54403BD69D2E855,9796A1224BACD5CD,BF719CBD4214FD34,4063A017F3F44E28,7BD01ED6EDCA4A1C,31133A016A4D519A,F045E39527C12575,00005A941D0E071B,DE9051228AB7AE55,3386C2B4BC498470,A9E99575A62F8879,5BC5E1FB0ED555E3,E0D62C051F2CD23F,646BCC2A51EDC25C,CE6E7E680D88066E,A79EFE3595AF5242,C17BE118411FD556,D9C704561305AAFB,18096828144377EF,00000229B10D3D74,79BD503CE80BC9A8,29BE02A4536A07A2,FB55C3B7F45F6064,16B4300A739967C1,4902592578A6E68F,1E8482E8C0B91E19,D72CDDEE6CBE0983,D26869D755681AE4,0488FE387B49757E,4C079BFD92ACCC79,FEAF95745E9166DA,000066329B97EF97,F0520A13FB16E745,804A3A2493A50070,319C7CB4DEA82AB0,A0D35BAFE61CEEB4,0385556AC5D215A1,CAE2271B99A4A327,B9D127CDC6A38E8F,06C4BAC9E5EB6A8E,42C529AFA26EA68D,A6F039F545E107C5,0210B89DC2091CF9,0000286EE91DE216,38D70B09C778DFE5,33B4C537D3027140,4C4EB8F30829BF4B,6607302184A9B5D7,05DC52FB74D61CEE,BEFBD783A413C401,AEEF9CBA2487BA88,32087A71C92079C5,6B78A88EE1AD17C4,54656A88ECE01193,5C520E9A984B1715,00006B6CE52A1C07,878B1AFB6CE28935,E9E75679799F141E,70B2185F4D0DC4B1,95B74BEA44F9D557,B35B185E107A0522,967AE53C46CDBB6A,795F0815F121B94E,58E1FF525D0F0697,01782ADB0617C1F3,9E9644FC1896A5CE,28926C6CD297EF77,000016F17A6E9AAF,05C6907D646BA084,6057668633E66B29,151AB1690F2B9D00,D3C3DCC3D4016F3B,E84C10399779DA6F,C568FD76E917E6AB,500973257C579B29,8459E212F3D24FCD,45B482061F398EEA,E7153403E6C03B58,EDB2F3E7756AF6D2,000002DD5C44CD5F,44C65F61BCB9ACA3,EB1441DDC0169BD1,96F200E5CDE41515,D5132305B6ADB449,90E9B23C9E3AD0D1,B17FFA264041A904,B1401E76A0A796EB,DD4D0BE8E418BE9A,1D612A27A510890D,C5C62A6918381582,1ADA54EEB9DB8027,000049A02A39851B,7A46BDD1C7CF732C,05EDDABC8DB24A1D,5157E1760DA33B71,E57DC391AC1677BE,9FC9025F595C18A8,E43A96A60674F485,F4E50FC979CC743D,AD72691C8A255F09,9CEF0C79A44ADA8C,AF2CC94BB3F1BA88,18F9F34E6385E303,0000087B58899B21,C2269144315C4DF1,5D685E5A6214D28E,F15A75B146E21ACD,31BE5E39964066E0,21BC7D9C4E6274DC,BDE54CADDE4DC747,D98C264E5E096E62,E90601A701EC5CCA,88628CF4E31DF5C5,D9B014C1C7094733,F2F7CF1D4E127980,00000432F8AC4655,9B57896A1FA25D73,FC7902BE816A09B8,DBD7401FE2497725,526763624FD1F494,43449DCD12FC908B,C1D08BED5EF05295,29857A1AE620F247,EA7C4C74375F3301,E57049385FCC1271,623F829443A5EA14,D0A7E1A7C6A45F8A,00003A87F22A7005,233E0FD7C441A686,EF272E2EECFCF9E0,18EAC5B57D902CBF,742252C228499A3D,03323EACFF710F74,B63C2DCFA5CEE2CA,D1A78787F7D83C2A,463A06F7C72A0D5D,F6F54F3792601D9A,D5E2C78B073BA5C2,67303819670A233C,00002652A645E7ED,79ABB173D3375A05,7AC541DF1256C6AE,55AA113CB2B68DC0,6D9498EA788C1012,C31528F62F8E7D9D,159FC8CB97D73DE9,41D84D0DAE0FDB57,B00538F83A683996,5C3EB4382E29C17F,A3F00118E46229BF,C7F0CDD2DE17C51E,00004C959B93E4EF,5B0A0F98814A79C4,9B160002477949EC,779EAA19B834D01B,1FA44AB42CD6079A,C68FA9779FEB5C01,1B882D5C2CD29215,2631FFC4CE2FDC24,0A2B0A709F196BF2,3A120B7226235637,629C40D3EEF618F2,EAFD5FB0C9B883E4,00003859C59A3258,5A54AF9E4085608B,8BE9CAB04D45A9A5,9C6A31DFFF7B8894,1DF7D1309B406099,4607FE6791991A42,13F5025073779E7A,3445A39DD2ADAB19,38353457990FC06C,318C2AE94144FD50,B723F1EE3FAAFD67,D3A3CA9CA430953C,00003A3F824E59A6,B60480A8DB65BA17,1AF6C879C4A54277,A4EFBA07A1FA1B59,2F4C1187926DC319,90CC39327591257C,FEFE9E3038CA3762,B9804014F1D7C7CF,19C1D57712DCE0EF,A6EE24797AAA92AE,47FB1980D322EB74,620E9FE540E2CF01,000030B11BBBB4CA,D95BAE851F9E36CE,7C883E50B15D134D,ED2A5B59AA19C17F,9A3B77F3EBDE9554,2C8B968017078E8C,C0D1C3ECECC9B6EE,A5F9B78DB7DE83C1,111368DC88AD9A0B,C10AC5A5029B193C,1E06BCF6BD591FB0,CBC3F6CB42B42734,000029663ED4358C,617F96A1E4677DA8,5D1B3354BEDA15AD,7B7E9821CF886F64,8C41F530C642F4CF,1FEB100B0753DDEF,86FCD3CA7D89F9EA,7154A5E9C1DEA246,966F4F35376E7292,483C4DBCB1A922D4,EEAF86E0F3564713,05F90274824848A5,00006B18773F133D,8FCB9455206064FF,CC9FEFC4122091D6,05186F1EF6F1CFAD,E5A6743B3A9F595A,7B44747B3247820A,C951F58755FF7E7B,C0BCC2AAC5D04637,12CE3BC7B51DEC82,E54468062981240F,DB877A5E29635D47,EEF9009D05683F52,00001FCAD9A05B21,CFE1A10A2C41F490,8A3CD7289ADDDBC8,51EFE70A4A04DBCC,BB2C707AE0450790,5157974AA4AA37EB,800FD24A436B89D5,EBDD76577F00FB3C,38297C531AA3A1BA,1D244D640EE70696,88C32262BC66E2D4,76CCAA13B410D552,00006FDE197C53E4,741BC080B5E3CB6D,022248A5E4B80BF5,1A7E5729F6EFADBF,5712EAF12243EB9E,8277915F82B95381,691F35C5D6C8C23F,C0735DD4B6606786,6B1E3FB648D01E01,6543399F2CCB67EA,575AFAA9CBD446D1,8DFB045A701AA86B,0000152E8C4DB62F,2179F76C4418CD9E,DD5CCF8000857A0F,058940184C3485C7,152735705AD0BF33,1A8620B0C82B87AC,022E2D14979D3CFB,38FE81175F8CA4F3,8ED79E5EA506057E,0365C7A8C256E08E,4FC27C6EFED13023,8D7A77C2AF0C7037,000016A14A944D70,02F3CBE430E1E889,C54C77BF580618C0,C43BBBF73E585628,09DD71B32F2F7916,BFB5BDA04614BDF3,1FAEAF5D7BECCBDE,4C71734C844C1CCA,600189959A2F54D6,00324C97D8B2849E,7BDA45E7DD1C90F3,AB671550C6333544,00003A6339694664,73DA07D46CB00A3E,09C77F701996FBFD,A0755B09F3502CA9,CFC15A8BFB4050BC,095C1F41ECEE8B6A,E6DEC4ACA272BFA7,E6910ECF768CB521,9C73680BBC2E8216,E351C851E0FB4B80,ED2F901C50BAD44E,55948220E332E528,00006E25336B8C46,7C22BA1F31B59E50,B206546A6A1FB668,AA1399CEC1D71F07,019336F50A6FE823,6855D01559180D5A,847ECDCE4311DDAD,26656166D172881B,6C7727ED64475AF8,98494967EA948671,9C639FEACE5C4601,2820DA3E3533DD93,00004FF4055F7DEC,1E010E34B304F7CC,25877D6686014E14,FD524A4D86401327,B79C91D34752C3DE,0E2128EBEC22DD54,D2E1EB48A12231E6,62B166513343BC3D,93541FEBFDDD9AEB,707A3449BD00FECF,32FAC3880EAF9E89,0743503505AA96EF,000055676A18B7A4,415B35C1D8E444B6,BB9EAE2AF4DC0289,B298B158E7FBD351,0C45341F883E2BA9,A1B5DCC2A4760D4D,E328FEB2F937439D,C5A7BB738F04EE99,1221751043D80F4F,A0D375C8E3489F53,F2D9CE022CC8835C,C170DF2E80FB347F,00005FBC66A64554,6ECD03F59BA6B368,D2E1D6B1108DEE4E,6FEF5451286D201F,93ADE17AB5B8A9E0,48AC92BEF8E3BD8D,2A91C84AAAF805BA,E8535C7E7056A190,8C7A92F32FFBB697,DA71B844E2B900C6,A7C02B140FDCF5BA,61DCCD8E10D91980,000032A6A412B9E9,1D40956C020B5371,9232F1CE938BFA7C,14DC4B3202612C7F,E714ECD0C6DCBBA6,52C0AC609DE6DE29,31AFC33C8CA3A545,A7C6F868C678F8C8,F3F545E8C561E20A,7C55B96D72E3D372,D21A10EE4E636AD3,91849441BA532CD7,00001CDA19CE578F,7FABAE8BA651B724,6B3B4E3EC74BC2E4,B44029E0FA6B44D2,CFE0519F5E14FD16,3C93323ED9115E40,88FB8B8D48BCB57F,EF74EC4D0C197B69,0BACADC73C1C0C5A,8D9AF70A221D69D7,3ADD8782C0C19509,55EC8DF154D4D41C,00005E6E17D23F19,6E18A205CB256757,1F0046CC17ED9EBD,E710AED3E9CE25FD,B411F823D5ACA11E,8B37185F29F01120,1D049ACEBC829E2B,DCCD3D5A4AB47592,020242B0F3B7F392,FF7910FE8BA9C423,EDFB42B5195CF330,B37B63A781451ECF,00000415E7B5DE08,45E06745907A123E,3670DAADCE69E108,F01CAC50EFC7223D,4A6FE4F0AD25FD3B,FE1F2327B07FD0CA,434D0329D2A6A501,3F977B1EC53089A6,F081E11A9BD9150A,3E08776487EA7CAD,BB65FABB662D6071,AC8A0004BED48E58,0000208FA293BBBA,F8524D76BD90375D,98FB8E753CAB636C,FA18FE2990D147CF,7BA340F8A4F090A7,CBD8BD68690E9286,7807F0F422C5BA18,AA8F4898917F8DA7,55FD4EF19E11DF0E,231A504DE68C2A6B,6E23CF14B3E2656B,F45B31E9F98BA308,0000462415CF6673,340270D1E4AC7A8C,4C4B076161F281FF,53D7113ACC39EAD5,C616A2E0307CBCC4,EEEDF641891948A9,2F517D7291E1A0B5,992067584767525B,E3CF0C2A898BCDD5,0346B5A3D760C3CC,9601C78E7B5FEAFB,F4FD75034B337FF7,000003D7CA6A68D9,9D3DD5542B9024D1,738CF24CE964F68D,16E53CC9743CD4FC,1B5C240DC43BA419,8271FC100FF0B300,1EBBCBA84C031A71,11EEB89683E5B38E,C2B89D3CF34A522B,00F0E74C1B5ED06B,4A530CFC8AA4CB3F,F6CEBFD8AE5BDA04,000060F4EF531A15,2A6B5D2AF2D9C454,D9F34CB6246F2919,B2F5102000E2A7FC,7F863DBE03A4278F,4E64713942805864,832FB7F1D4F4474B,A85907281C4F2291,53216D6996731F96,CD3773E8526E8C1D,117A9EEDF563F289,F71243F51999B280,000021AF15DB2926,BD2984F0B82C5F0A,3B0554EB2CE12DD6,A6E75D1979514D39,3EAD1A58DC214E68,5A16D21A8F111649,C76BA0D7E19D1697,A747A8BF93782F72,5949F0D794BD78DF,939F92EBDD2861AB,E9F02F822EAA6075,6D6E4B3E1E71B627,000061053DFCEAF2,DAE807F988FA03B1,3303378618FE18E1,12F60BA13CFD2341,93F2620697C0889E,678212DE006AFD14,5E462C5C644434C5,6E1DC3423ED3862B,076024EFD61CDC74,8B8640948C156446,41325920A7AED85B,A5D7922916C7ED62,00004786F0E082B5,21C8C55D185C0C7E,CFE346D9BD312430,040DB889992AF834,B78B888E55F0BEC0,62DFAB360ADFCF7C,337B1186ABDAC059,6C1974C147E9B91A,BAA9D43815970313,CBCA198C4FE30868,C7B1CE44485D8561,97BDC60DD10DA010,0000652B7980CA6A,5B41B02F48FAD0FB,A3D77A8490C10F17,CE9153746D41CF55,D6AB6225E68FAD3B,7955105EF6F0A6AD,34233B4497827B76,265EF8AC86A50E13,88A24E6C8671DCAE,1F62D634FD88177E,D4527E9999858D87,9D347EFFDB42F3F4,00006B6333D159A2,E10DAD4E5747ED2F,21DE37CCCA085E86,205B35627BC848C8,7B74E2DBE89080ED,5055876B63D01D7F,4B5D11A5A5C2357C,A1FDC77923E3B0A5,785D9A984F55FF86,6A03C7253E51E70E,04869FBC824FDE30,1F5B50E2043A9973,000030CA999437D3,EAC3020BACC578F8,301EEBF5E1A71422,D2D5DD4106A318C3,67C6614B2BC48A52,A8A01088539F5ECB,B257DB31C290EE3B,63C3C8DD2ADFCADF,0ABD8494A7EE8F18,A2C4C856FBA96816,D208F505B8D6441E,22C8AFDC6EBDE795,0000050B7DA52C5E,F3C05B6394393DE9,8C0D4A5CD71FA94A,CB786A6EA7BDA5FA,4E058314AE55FA39,A24F26243D1AAFD4,3F347E20FED1739D,F6693276286C36EF,C8A3CB70334196C2,666B2E920F12F45A,D0C93D340651585A,87CCB87D770FB255,00004B60564DA8DF,68C089618F69C51A,1D94EB37E1155ED0,B4C1B8F3BB8E0BED,E3B855829502D8A7,434C790143F8E294,D48D04CDB637AF34,6F48023B425F6DA2,AD7529C8C968E320,C77EA9E1C31A1439,E94BC1FB2FFEB55B,A7688C081097BC46,00002621DA52CC09,746018B4F27B18D4,DAD6B65D4BF0BA83,0CB8A83CAD4BAE19,72E59879D3AB46B1,B21F877917BE74EC,81D5A5FCC1DB7F21,39FF91F5515802BC,01303012830D06A9,07C284321CACD990,0A34609A36847CF4,AE70A2CE32A47CA2,00001B2FBD4E8CE5,CC3FB2A4C02C31CA,B95DA394FA52A2C2,864E5C40276FF5FA,E8FA1A51BD02DE06,838A84234738A545,198D26F48BAC9F44,FA19AA3E4E4A86E7,69F887CE4E056EB9,BEDE09F98AC3AC58,61B4520874A18AE1,D27AF6484A00C35A,000011C2FF9DC7DE,ADC2FF9EF786CDF5,4F5038271E1C607D,29E1C9C8A0B24383,2E0358C47B3156F0,A57D80A2044B7335,9D910795C942061A,725F2C7A471C65BB,0E39BA22B07120AE,C9737825148472D4,0011B5B66D1BFD3F,CAFC76D500F7ABD7,0000062915C591C2,5552BFE3A25195AC,769F9F42D142C002,F9306B251E7D7506,766C2A305D848A2C,C501620A58E7A384,CCCF18B06D6F42E4,F34DFED2D15FF777,61D8816BA0D10891,AA142A2DDC02D647,8CD70838D1BDB5E3,2962B416B592D648,00002881F91337E1,C0EFCD42B33747B9,E7110A1A157C50DD,83015889116F9CE7,5E62ED6F661A51E9,1564AD052FD146D6,E6B13FC58333B93B,BC107D7B0FCA8ADC,A537B0BAF34D8734,F86DDF1D5F616E54,CBA31E7E91F9D6B6,82D195C62F4EAB14,00003EC67BCD37D0,EE0D7EB8D58BDD5B,734ACE30CE586457,0678F44577270E38,33ED28FAE49ED0EB,CFCA78C14B64C4A2,25487FC91F99D3E5,C1A49493BC762C80,F825AC15D939E531,71086FA7E5261B4F,394B94C10493C61E,9292E3A1CC4CEE2A,000044F09AD3A65D,1A952C2DC86D5B6C,BD2C3A943A348540,6F1F9B1B9F7555B4,1C23D9A5E693EDEA,670E68B35D6ECF15,AE3E06DBB1DF7137,06F6C9CD4C7DE84B,919BD501966CC2CF,833AE7CB6309B03E,6CC1DBC0C080A9CA,035C7D3A893AC09F,000053B0347C4F78,2CDB1BB84CFC2D91,1CD631FDF8C36BC6,4C7B3F8AF6E9633C,114712990008F172,7771517751583519,75874D1FAA8B8BB1,B1A288B8CA793D54,3FBCF04444979BE2,42D4AD2E34CD7D40,4DD3C7A65D63FAD2,BCC543CA4BADEE73,000037887196FCD2,47CAE8701A739B64,0143F830002A97F8,30AFC9BA66B93129,45AE6D0479169DF7,3A6FEA311A1FCE6C,83C6CC53DFF9AF9B,ED717E2DA6D524FA,2A1A7E83B56AE84D,07A03912A8B54754,2DC467FC9C88C585,0E7F51FCE649849B,000008C446F9AA78,50ECC1140D07DDE4,38C0A905CE6081F1,55807D63809EE07E,781889847E615F58,0215FEB56C2D7DF5,A7E37D1AD5CFA9E8,9A7B8E4DB48860C6,BD22735ADDD8A853,FE7A6F1E5992D0D5,E18655AF228DFF54,734E39CA2BD52B7C,00004D0AC80EADAF,E2235BCEB22CAF11,115CFB5C9C4ABD65,6B6AA5B17ACB4BE4,B16DEA1AE7D7F73A,01DF45808F13D9A0,43C6041746C98D20,ECFCF1AA6D96E624,EFBDCA70C0341205,83DFB86B8867AFF8,5FA13408B19987EC,8781C06D2EDDB219,0000288F02346BF5,EFD6F55F4B043514,8CBA4B3C6CAC9F06,F920CBEDF739B646,630026EFA47FAFE1,1B5BC86AB6D54284,E17C6864FD43039B,BAE2968C0EC4B77A,98A0BAEDDDDFF5CA,D3869CF1C76A24BB,549E5C466E8AD007,74307D03FE64F4EE,00002A2B88678288,B80E763412EC92AF,00D4B48EB3D22E5E,02AD7FAFB4A564CE,D0B19B63F63B54E4,936EF00E9C79B237,03ABDC1B0C153064,7E73FB33EDA65D4A,0CD61579C2C418A8,F15B000A28386877,FC0C716CE022EC20,0551F9CA92394C75,00005B6708E2E0E2,251EBFD5C70F4AF5,66B13BCB5BA4AED8,FAC4C61913D51DF5,DCCD2F0B7350AD50,2E011A4F0FDB3670,05B131E75846C2C0,62DCED9ACCEB5666,2B27532BCA29D8EC,709885B800BACBC3,EF726CF8BA701D67,B3573FBF778EB530,000058BA7C6E6E06,16A57975600AA734,2B3015A1AD435B73,B60DF1B2740678B9,F6AEC3A71915936F,9CA96C03ED1167AA,38D514A59F44BF1E,DF8DB4D37A7DB067,1B8F713259FAB803,5572075B89C21BC1,35B75AD6136474A1,6D817E8ABDFC0B5A,000039F068416C2E,752DDC9381A8D173,FC925058827E6B71,C321D292CF57D6A2,F21FEF1FD16676CE,2BA612DBF08D7070,D8F7CE3185AA2BD7,E65C175276734CE6,86330066B52FE60D,F392C869F57286D9,386A5B01A93B3778,7BDD3DFEF37437B6,0000067CFDF3769F,10FD57367C1CD269,9EF31B153EC1C484,0C846AE546312E6F,E61046451A62B67F,B6A73E9E63B83C07,CAFCDA702AAF2576,7E8A986548FC0AD1,CE8178391B205FCC,6FBC7DB88B7A4EAC,556CF9302E0471D0,633FD8D0C817E4A4,0000562AB4FB88EF,7FCFA55CC5F54AC4,4732A6095E7FC837,A4FA7E7D7ED17870,D351ADD93E85FA99,D1DF01CB906E500E,887378597D6CA78A,E888A8282878CB4D,891A6141BCEE1902,1AC0369F6A36D841,85D099AFC5EEA287,96DAA5AD986620E9,00004E1A0F6CC77B,8AC8A027283E0E8D,4F60457420AAC213,BDB1CD89C7EC7109,D60698299E28413C,1767BE3F04371D2C,C0D946561D48D5D3,0CC31E459B4EDCB4,D76E505150F65F5C,A47F09E7B0D626CF,6636A846E51F374E,537097E9532A28AD,00002898A0A99891,946AA645AA4DE22E,9BF0339FD55C601C,290DFA13A7007C2A,487C91C5B0B0D7BD,EEA691B538E3C360,385973061794A46A,1685CBAF4927F6B5,6F7FC991E0B76871,0EAB06B08CF69965,8037B8529CD5991A,5A05791F37068BD0,00002AFDFA0ED119,19B2878547BBE49E,C998ED292D57C53C,09DCB67BFE85F9A4,ECE107D6585B9348,04C65FB116AE6D67,31916B4C9DE8BE0B,FE3F4315CD2F28CE,55C455B554C836CB,619FF72A1FEC15E7,6E4E60A2CC77363B,BA18D1A9015DD2CE,00006FDC50784A7C,7A879F187CA8A14D,6CDBE47AFE811A9B,2FD2E51FD41B3E9D,1AC585C557206B06,24ED77EBD4D2C70A,386A148154EE6B17,1769A0C2105E0F3C,2020C22DFDEE29B3,AC0C7FD95D26810F,83308DE3ADA49744,4F7315BBB5720480,0000489976558AAC,500B30CB836B774E,88B77717559D96F3,09D488DB0BDB2A54,5F5BCE01166223DF,03FF2D244DBFF21E,155838EB6BA9FD38,D7ECADC4670705E3,2F80A7279E95F490,7301B1D69BDD8C3F,7874EBA00C08E120,76A994A3844AAEA0,00002885BF2E45D7,C72B5B0A2997A18D,4F4209F37B0798A3,AFBBFF10D09B1CAC,B6B7FC74F0DF2CF8,9B633F051657FD04,4BE15ED0D4A5E4A8,2327CCD080D1C4C4,09D06AD3579FED33,CEF5B20EFBF84B8E,1E29625E8B0D60E7,6D9C569DB899E900,00000A119ED4B3B0,098A91AFC97F86F0,34815078E367EF0C,1C911854BD89BA1F,0B6FA1A7DC6E785C,DE901B4350F12E75,A37C328DCE195ACF,37D7CF48A4139444,C8F07269FF2CE8C8,1C64D755EEEE89F7,A7B43DF3F45218E5,25EF30D742F90F50,000049BE763D26A4,2B67AC595163B7C5,20FF8C308692253F,9834A985DE9180AF,211EFA5C34412434,D10DD11AFAA53319,A5454D976F9CDD49,1DCDE3BC336C58F1,864EB9832A616C5E,3900CAFF3CF80C2D,0E8D965DE9A93C2A,8E6210F3EB7C3E4E,00005A37996B6A0E,49D694D6ED300500,687EF19021893D02,A4A3EEA2C9EC422A,6A371BD7FA7307CD,63742580CA4A1071,F03BA22CCA7BD4DB,9BBF09B586CD89FC,9323D50FB692FE30,1647391E3AC4BD39,6D84BE65246AE040,1471E5F6D7BCD60F,000035955E57FB28,899C43926CB3C7F6,7E31588DF8112C54,CC8C56F64773A3CF,FC21D52B9203D4DD,3D223F62E6B95293,A310EBC5CAC2753A,952FBD58C90FC86D,033FCBC9CCCDD108,05C105E9B01A73CD,6D77B5237B14C1C4,6D9B5F675FD66767,00001D8C38D21DC8,B39E66EC947A09FA,51CF661BF64317D4,BBF1B8D864789701,43EA9D27FF19DD37,CD0B62B7F12F88C7,5F224870C62D75EA,E3B5C4359B32BCBF,FEB9B1A9BACFC460,79546B1BA584311D,910589BB0D5FCE3D,011598FA7105AAE7,0000406ACD718040,0B036BD6523F95CB,2F51D21CCF451089,D7E5220B44B9EA48,74A6A2605E1A50DE,51455D9BD9C0D206,D8E73091FA00EFDE,B347119C3EBB78B4,FB88B0652F61F975,93229C1DF7E98975,58B52AA34F03DF28,6FB3D7A6A35F31EC,000031A99941DDD1,D4F0604160622643,7C04219F501280F5,73A1BF17B6163C55,3C2A1922BFC30221,5E23D8E177002808,CEBDA3019B6644B6,0EE7CB8A63445711,CB9D44417FAB170B,C6E78B40F49A708C,0CB0640D19154D7B,E320848CC3AA25F5,000019F09C6EC1E8,F4029C59C5ED8D5D,50E73AA4751EAE92,76419031E7F39E4C,7836970094C40417,61D733F38F37684E,45EE18A09C7FA0A9,4BA83F284C58A0EF,18FB004432CCC20B,9E9C53CBF61690E2,60EDD9133F8E3696,018554ADD798AFB9,000016DCFBCAF978,0CE5B2A2A3F9944B,333A32F65A4AAF35,114E9DAAE1DAF215,4BE769FA3D61E2A9,70637F6AF3A1CAF1,7A71E447A4A4713F,DB044500A27660D8,B0FB5BBF55D666D4,01EDEF7E36303E94,704E7A35E0BC4050,1D284B72E7FC0435,000028F4EC75669F,8CE037853226ABAD,7F2D53DBBA66AA87,15DEADE616505EC8,8C9DE0D4F1000AB3,5C88EC7EE0340D57,B7FA4F10878296C0,A1ADA2D24B01A9D4,DC94BD575184D62E,D4BAA95144B63DF3,E968CB1CD771A168,D1559D4BCAD8DFB0,000033A1C237A6C6,7B477C21CFFABAC2,8C8F7DAD549090E1,4556F34B0A14A630,0ED8BB022DA17E17,9ECA0B7F7448498D,A7BD31409ADF60D7,5E79417992899108,905FD446630D6F71,5A46DA41ECE59B3B,A27690BB0EC2B14A,91CC887DA3BD01F4,00002AE3A7394753,9441F1C031E2A7B8,6591625644739248,E7F7DA92DA826E09,43C5F1278241DC77,B409769F2B53F146,41264D7E32D0017C,482A79A440A57D4F,00C465163EF60823,DA251FA6B8B07F33,C1320F0CAFDAFE00,8B62360FA4843986,00006C5112C373D9,2123B9BA766182A3,36CCAE37B5FCBDAA,CA6EE7320FA47FF7,BB89DEC595295550,738AA23500AAE142,3C644BC3283B5D7F,8FD54869348146FB,853E8B2323C4148A,3DCC56E9160C0044,F5582E122E4F3F53,EB538F272F9E908B,0000496569204AC0,C59CB60FB4AD6747,A138E058956D5A28,41AEB634096325A8,BB9522D9EC003E8F,0BD34077C2D56095,3450AD3DD1C507B4,7185DCB52DA91779,F2C6D190713A3CB3,EBDB15947EAA7B18,B13E28497F5E5DAF,6C680451EC99CDC8,000028529474FC57,5C24E025D43BC76D,0A4CA935026956B4,07AEF5B69C3F6248,08ADEDF507ADB0D6,4C84E79C5D86671D,CE192A98E511AD26,BB89CD386638DF8E,3E724F7DE7C03A29,78AEAD25EBB8CE56,3A0330C59DE7E71C,FFDC0CC7C2E76DD7,000030E932CE8608,6D95FECC2360B359,9A9B404787F29B63,D5EBE5C6391F5204,6657FEC7D21E93F1,4CAEC81B5812C013,9DA83E9724FCD01F,47F83B00700D881E,49F86012636719C9,575DF925823F38D3,153918864A450400,DA6543287074E261,000030ED9BDBB433,5BB574C18605A296,7C7FC92FF748104C,9A0762D8AC0FA21E,C0D569C609FD67C2,7C51B9A81A01CC38,3551F9A8B2C29E40,E78E32F2C3BFD1DD,45BD416495F2FD2E,1F2C9EB67C1C7EE0,DB14C31559935D18,164D70FF7918D8A6,00000F6C55567FC0,B101C5525583D197,874B2BDF730A466F,3F6813F87F2D678B,D181306B4B1CB181,B3322E7DE341B2A0,0F927D242CDDE4C8,7D88BD9716C2B034,008E192FD66DE910,1DAE69D28BE46F8F,4C59BE0194936220,552D87399AC1D653,0000621F5C594C61,8F03A9E8BE4D33FB,46FC912BB264AAF7,F46BE6A61B7EC39D,E457B186185962B7,9D7F1ACC7441D97F,828501D242BCE9D3,03BCEA6148F643D5,CCDBD7D94E64BA4E,BE6666FBD9AB1BE1,6CB626B5AD78F9EB,DE67666BA7D7DCDF,00005BAF88A97311,3927B43FB82A48CC,385743FA3A12AE89,93473332792319E8,8969C024EEEFC896,7B914BA93D48FE50,2CBB723456406D7E,D7502969AFE36BFF,1E8A68889A09B3EC,9356611A231064A1,1404140A38259A45,21949EF814A24DFD,000011B79B3DB909,43C485D568B331B9,54E9546A4800A783,DE2464833E4AAC5E,E531377DACDE941F,CCF4CE870F348F28,2D07BC370A2617E6,1C87F35B90EF8879,45968298CE825BE1,356F98B4841EAF74,9EA48ED8E729470A,8D1FE49B7773C1D2,00000A60A36A614D,90011D948FF333A5,0272B70738560D22,24AA321594A318CD,D40AD69231369B90,C95B483502892F05,35E582E81B9DA5F1,6B9597BDAF31C481,8EA8DE93C701DAB9,CE2D0CF5C9458A1E,C79CE81E68BC762A,8876E9A15D3941E4,00003A1799FA5E98,F746E49CFAD785BA,FFDA3E10BFD0324D,BA9C53A46F21EAC4,D491BC07928AA4AA,BDE3F0FF2E93637D,6F21D44B07E861EF,7A9818C6EB9B4AD2,B9EBB0151C6FFAA4,CEFF5DCA5BD8AC0F,4C37C8F57219935C,E7DDF1A78B06D3B9,00003644FF35F6D7,86A4CB0DCC0386C8,BB21FEB2CB89ADF8,802A4AC54D70EEA1,1F0C8C6A46755228,22DE7A444BDB5691,071B8B87C2541C21,37D3D22D93EB8E82,B123356E5CFF3226,C1D90B5BAF752ED0,5A0DFF9B18810CF6,F4A4F427545546A7,00004EA881787815,FCBB23C8168294A9,790EF18C14505B64,C39935F70EEC6771,012E0ED3B1BD8746,97EE7CBDCDE0014E,1BA1C0117C6EF357,893CAA32DB2DB7F1,328DDF85C884DB7D,4739E5D88F578EF0,CBD8255328DC38A5,D576B81DFD4A85BD,0000434033820651,4D17E91E3B2F9488,8DBBA0EA1A85E907,FB15DB50BD41A1A5,75D41FEF89ADB860,2C753A09C4AA531F,A49186A0D33BD6ED,A7288DEEC1B3C959,F8AB7F7607A5FC4E,6A2787376A32F0D5,EAD5C582F8228188,A50AAA5E0C4413DE,00003EADB13E84CB,CDEEA5CDC5F16EB4,CBB4205F393A779B,865D260BFFD149D3,55CE2D6B89540A04,97F92CBD4E6F8C78,565073C6384FB153,31EACB7C1ADDACD9,A203562513EBABEC,21098B7C3D1C8CE0,C9F815A1A88A71B5,8090EF479FA93829,0000319F076C0D86,F572659FBF7C863B,363B160E781BBC1C,7257E99006519F01,85926093F7A5F0D5,A9FAC58637F596FB,CDE0B405B0911F04,AB96B63CB992C922,963942C25BF649F2,13F0FC0E421AFAFE,506AA53B304EE3B4,D95BBA118C98560F,00001AE3D5DB59C0,1FD62C97DCCDADF5,56714D65A6033C61,EA0EA5EB44065B9D,63E1E66B1D115EDA,39C36FF6920946A7,3F46393666A88173,E4B3614B0A535461,BAEA6A2E3FCE21DB,C0E7786AD9F7ADB1,88A9F46C7F396AE7,78726FE0EE540260,00001054DBEEFC73,88B7B1FBF1D71E56,026F57F9D775CE4F,347553A9B45BD084,97013C52F8D6A35B,A384EBC2F40BC457,78BB66262F2C4738,87FA3F37EBBBB5AA,DCDB43B55BA68072,CB7A94CAB3E4C842,0AF158F8A37A79D1,BE87FA437B434BCE,0000617D7BAFC9B1,B9C5A91F8DA2C120,582A77A233DC1D8E,2633E9EC84D07C1A,4B6DA3E5F6EC4598,A7D0D29D08C1FCFE,EA609161FADFFBD0,AD105049FA4AF747,A411CFF769690F64,E38F8F992130DDE5,0BC547A375D882EE,53BC706F8B6EB2A6,000018ACA1FBAC18,0E232044D1327D55,DD83DB7927F24B12,DA8C90ADDD3F8117,80CC380CAE04711C,D9AA83C97DA4C506,5A4D8F07E72744CF,505EF7932B185DD2,C38C9A7003A3E8EF,D29E6ACFA39854D8,FED34F9B036733ED,A9E7F91CAC714737,000034E93748C125,281985C683948C10,A9831C56E6F1BFCF,01A75FE6ADDEDDBE,CC017EC72CF09FC7,B8C5B2FC7077CE2B,27CA64D71730EFB8,432207212158B7FF,A22451B86A6F3CE3,AB32D716E29DB99B,AA800E7E89E106B3,79C9A2EA146C380F,0000028430287D10,55068DA6EF287117,038FC4FF27E3EB8E,5A1B83D3E9839E0D,227C893AFD199971,5D8DC7EFF1038CD9,F7F5205FB8A84445,32F20A1448294543,A2EA7A1161ACB26D,100E90E1C833F1CC,186B0F7B0D3F95B2,6C0C33577CCFAE23,0000588945F6E8A4,F3FC86E8616A39E8,9C31ACE64022B763,142D30D26837672A,3ECAE5DB88ED14B3,F420C794FC6034E4,E03AEEBA46942CB3,E7417323EB8CE70B,4312016DFCDB633B,2658EBD52DCCFC30,4A3D3EFF0714C39C,CA707D7060EFAE75,00005B0ED5676150,48199CA916E4B309,61701F68FC67CB84,F29397D137B7C122,7E043FCF73870136,E4B3A67CE3DF5ADE,1870C55A1D145E48,0357944026883196,E37415FD8F0FD38A,0518237952A0A22F,E156CCE610344F17,52E88982E18B37A5,00002D64819E4701,8F47DED2AE9AE506,15C503DB2AD05858,9DB0E062679223BB,E47C6D37D1F75101,477FBDAB2E4BF961,C447F5596D1C46D9,83962E808BDB41FF,F09F8D22A1067309,B732073EDBDB10B3,D739928EC6979669,E566FD63188F72F1,0000205FCA364617,6E10AACAD408218B,178737B42ADFC5E9,C91CBC3DE80AAAFB,3C2E7FED546DE89F,B78B6B087F6B7AFA,944D5F4450D356B3,2AF3A0897AC8E205,3EE0DBF73BD6139A,E1F73B2B594AE7E2,13B882451F59B563,5E5DD4DE51727D3C,00005D74B7287BD1,AFF815CBE2866933,A43A258C4F9C4166,F48E92CA6B681C27,1A356C7AC6F71684,E1CC286A042C2A69,B602CC046C3E2B58,ACD0DC5BE1457C58,70C56E80C6A855EF,C58E3CC7EFDD95EC,767EF9CA6AEBD13A,2C6776DC418BED00,00002A7726CE7BB8,682B1B584EA446DE,9F81A1322D26558C,2A0077E2523C5710,501F44591C8ECCF2,E4C0D3D48C3F387B,51B72EEE03B89CFC,F588D042B7346ADB,9EF86BEEE48B1EB1,9F8466AEC43B4F1D,D842CDB63CD45632,04A797DA4BFAE2C9,00004770902468E6,C5598B52011996CC,0629D38ACD3CBE15,736615FC5429EB01,385B98660D7CE822,C027B30E17F92B4F,D8C1BB14325E95BD,4A14D53C001F51EE,9E76737B8E333AE5,C684296FEB0E354D,7D0F4211CE0ECB75,625A5CF4EC2FF923,000044DDD1803C1A,2852257B53E70106,50183162234B0068,51CFE39EDE524514,E33D557B852A9A16,C6B42156A2A85EB3,BC8411D00D88C874,337E3F539C6C066D,BDC9E4362B87152D,BAEA5AE4BD052B66,2FAA787BC67D9737,92CAE9B8826B6684,00001B8F0BBDFB5D,FAE3B84A3FE0BA4E,02D2AA239B66F930,46B7250C1CCB0538,0830886C2F36B8B7,771BE25BE2B26AFD,CAC87D39DFC6CD4E,A75CA13200D73AED,3B76415E436DD5D8,2FF5E0E54179E032,50042FD8DAB127D4,88EDC98180502C8D,00000ABB523D6AE7,31E31531544EF632,F30B0C840C8C871F,780C5926A92F2B3C,D3074A06049590E9,2AF2EC95D6B5F79C,E362E0BE5938D61E,2B7B86774C39B7E2,0B03FC75395F0851,5CEBF502EE511D08,7DAAA1BFED2C218C,01978C3AEECB1977,0000601911EA19E8,DF6AF2DA30338644,1CA46D4E0DD06B42,7AFE4995C893D4B5,9A34B9F5DFE597CF,006D9068180B5D9D,DCD6BE6AAEBCDBE9,B66438F5C333D091,7B66EFC15DCE994F,F6B75043E1035B71,234152C124FCAEB9,3E268FFF9A2308A4,000033B371E2BC1C,D56664B8B1E4574A,F667CD83EC14A251,6E44655BEB02C621,A80B25F696977DED,EE69A583778432AA,8AF7194352F22AD8,B40EB58943774494,0BC74A0DDFBED8DD,5638ED4585DB33BF,2B518C84031D0E13,56F1D2A5374D6C0E,00003873B51666F7,E9E8AF9621831016,52D56C59A4F5A155,86E48D4C2AD3828C,FC49A791FA4854E3,90475E279B04A214,AFD47961F337FA98,97A6E9C6EB043CF0,FAAC6E8ACFC76F1E,56EAF8627E0F7D52,F87A5C96F358BB66,72EC229A0AD1AB1D,00006CF266C25C36,412CC292310B722B,8071318DBE2B5CFE,2F6AAB28371E9A9F,2AF64008B73C54D9,F9DE49C27F9C0DEB,B9C1AD814A5B0566,E7A2BC8D96F0C77E,E3C5F26E7324BBDD,9BC5B8FCD778C1F8,D974A07E740C0007,717BC01760F3D9A5,00002019EDC1BA92,4DCA3B50388E0559,FAE384D32990D875,40E3A57393025DC9,D45F07643DE98C8A,8FFF53F8943844B6,D52AD9579C28B585,659B203F4B477768,B330E8F6D1009643,DA73A996FE44DA14,4D9117A401E123B1,DC7899528B71B286,00001A882CA55E85,395A11C8CE4ACDA6,7F7CC0E508F76CCB,E23AF39F94293F75,0F1BA73C95B293AA,F0AC1C38F69BB8C4,0C625CAD3112747D,27D6DBF48D332226,A2668206BF7D2063,6CE42674D759A8BE,66F79FD81D33014B,0565620686C135B7,00001F3ED2A0DA6D,3540A295BB04C1C8,B5B9C117E41DCD95,D6D4EC8E0D2B643E,F4B985B1B967E33F,7E16187532FDB92A,5395FD88D2F43A1B,4AC5671E868FC142,C85B14FA67F047CC,D8F593F74D9E43AC,039CD5C7829AB2FF,BB1737717DE92902,00000E3AAF8A1BBB,3540A295BB04C1C8,B5B9C117E41DCD95,D6D4EC8E0D2B643E,F4B985B1B967E33F,7E16187532FDB92A,5395FD88D2F43A1B,4AC5671E868FC142,C85B14FA67F047CC,D8F593F74D9E43AC,039CD5C7829AB2FF,BB1737717DE92902,00000E3AAF8A1BBB,395A11C8CE4ACDA6,7F7CC0E508F76CCB,E23AF39F94293F75,0F1BA73C95B293AA,F0AC1C38F69BB8C4,0C625CAD3112747D,27D6DBF48D332226,A2668206BF7D2063,6CE42674D759A8BE,66F79FD81D33014B,0565620686C135B7,00001F3ED2A0DA6D,4DCA3B50388E0559,FAE384D32990D875,40E3A57393025DC9,D45F07643DE98C8A,8FFF53F8943844B6,D52AD9579C28B585,659B203F4B477768,B330E8F6D1009643,DA73A996FE44DA14,4D9117A401E123B1,DC7899528B71B286,00001A882CA55E85,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,00000000000249AD,0000000000000000,0000000000000000,0000000000000000,0000000000000000,8310000000000000,5527B1E4375C6C66,697797BF3F4F24D0,C89DB7B2AC5C4E2E,4CA4B439D2076956,10F7926C7512C7E9,00002D5B24BCE5E2,C6A5EE3731B53259,80833F1AF7089334,1DC50C606BD6C08A,F0E458C36A4D6C55,0F53E3C70964473B,E24DA352CEED8B82,BC15BA90BCC55682,382F1913547AAC13,9B6A71F2FF923FB8,1E6B152C3F7F55FC,08AD2E9910F9A6AF,000050A702A11CAF,4DCA3B50388E0559,FAE384D32990D875,40E3A57393025DC9,D45F07643DE98C8A,8FFF53F8943844B6,D52AD9579C28B585,659B203F4B477768,B330E8F6D1009643,DA73A996FE44DA14,4D9117A401E123B1,DC7899528B71B286,00001A882CA55E85,CABF5D6A44FB3E37,4A463EE81BE2326A,292B1371F2D49BC1,0B467A4E46981CC0,81E9E78ACD0246D5,9B1A02772D0BC5E4,99272F66C368B766,123A861FAC0784AA,2F590470894DA4CA,81C5DF3CDA17A448,52FB592E19D1B364,000061AB25B7DB60,3540A295BB04C1C8,B5B9C117E41DCD95,D6D4EC8E0D2B643E,F4B985B1B967E33F,7E16187532FDB92A,5395FD88D2F43A1B,4AC5671E868FC142,C85B14FA67F047CC,D8F593F74D9E43AC,039CD5C7829AB2FF,BB1737717DE92902,00000E3AAF8A1BBB,B235C4AFC771FAA6,051C7B2CD66F278A,BF1C5A8C6CFDA236,2BA0F89BC2167375,7000AC076BC7BB49,198526A863D74A7A,7E517645FEB10140,2764B22342F73633,2DDAEED0D8A70E62,37D19D605AD13396,3199F74D0C4929E0,0000555DA89C9896,395A11C8CE4ACDA6,7F7CC0E508F76CCB,E23AF39F94293F75,0F1BA73C95B293AA,F0AC1C38F69BB8C4,0C625CAD3112747D,27D6DBF48D332226,A2668206BF7D2063,6CE42674D759A8BE,66F79FD81D33014B,0565620686C135B7,00001F3ED2A0DA6D,FFFFFFFFFFFDB652,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,6B9FFFFFFFFFFFFF,8EC4E4A1129C0C42,711E035AD4A8A7A6,3FB0E0B52A8F9A48,38BE00CA8AAAEDF1,FD1AFE3322A8147D,0000428AB0851139,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000 - -ph3_T1 = 61F2C46235355981,B14A772CB29B82A6,D42C0B8FC04184DF,FCA910510D39E137,7C362C336F08DC04,5AD83F13B81712F6,4F3DBBC2A96F63FA,0A57610E390A5607,14C5DAF1A1626E5C,9E44E107664A2F4E,8DAAED26BBFDB0E3,00002D6B4A339DF9,3E26404B0AF5D1CC,500F8B5016019FE4,783C57F59330D4AE,9A63B0E9FEC0B16A,60C2C9156C323CB1,7FDE85AB8348E8BE,0D948E42F685D4A6,0D2620E19066F726,E0F7B959E1E34CC4,DA22A41492CA4FB4,45FC1205CD9A9FF3,0000647A168C97DD,A3E1E0F284119083,54A1675AD5FCE7F0,0367178870AE5931,1DDF75E74BF11C01,D575FEF284B33B38,CE98D0BD1FFEC121,38F63CFB654FABE3,E6787C23FEE5167E,673649AFC7CD4016,E94DB8301F0C3EE7,673E019BECC49377,00000D2F6E941025,380DD270B4E38753,3887493104C70199,ACB249A68C2C8A2C,2AF58A3740A4DC72,EB9FDADA18EA7B81,DF2B51EB589F2BBB,2B5D7B01DA7B98F4,D29718C86EF95744,45BE21485F9B5841,359BA73A6AF7D10B,E9A780CED50BB85B,00005962C56E14AE,6D528C376AE2568A,F5E98924F27E28F2,83BBFCC7C51C11ED,0DF8E1157C0B2104,09EAC3B579A1FB0F,1D8A1308F31C3293,04F39128DBCCCF72,84757DC1D6865E0D,9077B3C839D63CAA,9885B3F80F35DEF5,5D2A7A7F119311D8,000005E9573EBA6E,EEB80519CE828003,5FAA4F091FFA4B3C,180F1C0D7A185086,4E39DB5A8788A014,92ECBDA3B525C47B,0ACBCA986C588FBA,B79A38862540BF6A,475048369F46FBCB,3DEA309CD1624773,F1C9CFC0B8AF783C,C976322CE2C8C02B,0000239CFFAD4B79,A433E0DD4C33DD9D,1DB3C40D971FBC98,7148DFCB642ADD87,A90DF39D90FEB5B1,C30D9D6BD4D03BDB,FC9B4AC25D560D3E,655F6EB70FE2464B,DFB7E778CC4C60E3,E19C560DC64269C9,C31206407A0FEBFE,080218BA788FB306,00001B23221F863B,8C3EEBB6C18E2751,6D8DA6F801331A10,203945342960FC09,C21DD47346BA5B4B,801E1D5637E8BFB3,30D207D58C2883C1,3F0FF731C15A5372,A8948F3D9D05CA82,5699F3E728A4995A,0978DCFFC7D1FCBE,B18D4EE97DB42F2F,000050F2EC7B0BAF,A78927CF314B8C94,CD8550A2160099E2,43A5069BD3B2FE47,61CF5B9C1CFFE0BD,F9075CB076B7BCFE,7E26934BE2ACD14A,8FD4EBC9B50A43FD,F9C0B9D603608F11,B8BAD7BAB7E7B8B4,C99B88E620745263,7AA683F3112BD1D6,00000007726CA73D,8027986681D32884,DC639598DE6C7D0B,1331F490E5D4111C,96DE70470A45E502,4FC409BF13B910ED,78BA2F3829ACD860,E8653E219B87EA16,8E98824746BD30D8,E04A044C5AC1E23E,894A19390A89078A,4C2E506BB1950536,00004B2B337B7465,6B2E15CA156FC79C,77188A6E2E7D8B91,6CD043B43052F252,E1BEC7AE9D6EDDB8,DDA346E92E996B4A,2295EA20B1340163,1B7E59C08B6A510B,0154984C4076E74C,4A41430F237B4005,A7AFA207DB760555,E1CA6D12AE3A29E7,00005DCDDFAC4320,07AED6895B0CE7BD,0E2592AE7447D965,492AEEC10F601D46,E59AEEE4A025E80C,B61660758F5660A3,E97E78C2288FADA3,09CB16533AF75E84,5A41C21412E81810,20C679A70AB34175,ED569B6A5612B192,56532D50825658C3,00002623A5E90691,30FD5A3045EACC1D,1FBDBC13BDA82DE5,3A3EC2934A322064,DBA996F38E453D23,A11BE6A70BEDD90E,45C19065005CB33A,4426AEED0619061E,76FA12F869ECC7CC,DA55C31FF849950A,1E0029A16B1228C4,CD59A6AD63FD8447,00005A55677BB501,FCF27604F4B08E92,62769B284268C25C,BA0CD67CD35E982A,B2194B734F471A50,9B500EBEDE8AF10A,863BE756685D164B,0877A32C1F62857F,40FB1CE4819CCEAB,D5EC1C7578B6541F,8D692C11E1253C2B,C5091ED42C8BF666,000007C6532A5A14,F42F6A14628B8F21,8EA82569519644B8,4F80AE531AE0EFD6,3FFC70361727D330,734D3549A86D3032,5EED94A9536AEDBD,5D2CA5FCCB6A5C99,2A70FFD43D8E2A2A,B6D672F5F67B5750,3422F460E4781E65,E3A8FB856ECAC907,00005CA66BCE5A32,150AC998C143A5F6,46102EB917878DD8,D2C9150AEFFE6D74,694DE55C6265A7AC,CE58ABD3FA7799F7,1A829B6BFC595EEC,F45A23838B981AF5,6D3017F6D0E11F2D,FB554B978A50ECF3,039348E2DAFA0776,303B29BCD086DF41,000043931162ACCD,B43A5B7EC264A484,CC91FD3A4AF8C866,A09A12C3A46CA8F6,886A77C6ABEA7A11,9A953AA6BD9A1871,CA47A5D6533BE74A,7FBE28A88A394C8F,DEBFDC4033F480A0,96826AFAB216C488,2F6CBF18A8723C12,3F637ABBBD64520D,0000202B45A4CBE0,BC28A0F4EFEF59BA,C5FCDD4CB236024D,A7F8FA7F004B2462,E45DF3A3A2317475,403B8B831862F2C7,B387AD1E0D9C4361,F88E048E2A030F39,6DD9A98FF681C183,A9A5644A4B061A4D,88A9191C14DCC723,0B441BD1A86F5191,00006D19455EDAF3,0D2C974E28703A95,175559ECB942C34C,7CD732A9A37F2676,F2FA7524199AE520,D16E612286D2EE3C,B755DB85BF9CF7D1,32AB8DE6D35C9B0C,9BC090F62B4CD17F,BA40606F3E7AA0D1,E203E9B3174F5F66,2F13B46444F735CD,0000653531FB68C9,DA48FD257901590C,534CFEF849AC6CD2,81635EECE6895A6B,7A5EEEA3B37CE63B,A3382AE6B52A52DD,7CA88A5FA81D0C99,0BFCA0451505AA86,BB38A5EB1964C3FE,698C82FD96357312,077F5C131F6E5F82,098ED1D2461C693E,00001DB8AC87CF5F,E6570173DDCBDDFD,4F5401BF473E8433,F95D519665F12BC0,9EE519F3F4E39C8D,BA1C60BBB24FADE0,F8C6F9E575CB937C,5840112F5A529F33,D4118A42AEA1B0ED,B67D3908E1419945,8CBB35343C590AF7,2CB9B99D9FC6950B,0000212A4B33D257,24011EE9F6E74861,37DB9AD9F53BFC99,4E1A0877A39771DF,5B89DA750C844A12,99674C0EB0BE3A85,D8E85B87645E10A6,2D4B4BF6CC5BB090,DF40EF7E5D94937B,F8108D6EDA17256B,7339FCFCF73F5495,74FD2B4410839642,000034E57C46D50B,BCEB409B401223CB,97803C03A2190A51,3BE6A9D77A4B823E,B7686663E7CA86C9,4C2E034714E5F721,64428B94E70B0D4B,C562BECF74BFFFCB,7B89522C69D71ADE,DD68D30FF08EE555,820F9F35E2B8FF3F,4FF92D89D2BD54B5,000068BE2983BA5F,722A6DEF84D2A077,3226ECD43774B9DF,905FD3C9B1D5D888,6AD3CE3D7053313C,4004EF0D83712C08,0601DCD6E2BBB8C7,782C7E9184C522AC,E9FEA5363B4720A8,EBB8649C8FF39264,1CFCFB9370084C1F,EB847AF675C0AF4A,000006EBB36983E1,81CF5DC5BE123C64,F75EFF5DC1850BDA,286AB6E7CD68399F,DAF45719B6E3CA5D,86F92B4297721168,3A5690E6F3BE9794,4A80C1CFBE34E306,CAD698244676F53D,367B4D2056B09EEA,A5CDDEF2EF51838E,FED1FFF910F75272,00000E0C28703833,7D9E374864DC1729,B76D13AD977F4351,F57C91CB9BF62AA1,02DD6FF89B9E016E,B38148BFBA93F989,B9CB8D05032D2BE1,9869628E1DD4C118,C41FD6606CF8E64E,B79ADF470C090C66,54B7D64AD46D23F2,6FE6671ABCDD4A43,000002A4C465FEA5,E1BFB4BA164A6C2E,1B4F30C541003DB5,D3D06ACBCDBB4F0D,8B52A39DEB38CDDB,76529B49EC389C49,F4F02339DE646D57,AFACC7600E29AF52,598D8F128E19C279,836FC4FF2D342237,ED001A2E81B54CB9,C0137AA63D9F3115,000055820DEF4910,7C861620B1B65A38,10F54A6CA7068BEC,CC93985E64587FB6,A521A9A4E36F5F29,B00780DFD671222E,060EA946E8115E62,9BF04AA54AB167BA,96D06D6CED86FBC5,EDF737BBC49F05FE,79151A1CF64F4F1F,B6FA508C99A7F949,000041AB9236E456,60AE886F08F4FF07,CBDF7E92141D8C2B,7AC749EF515D4998,CC60577E5BDC0062,784B8A2887A6BDA4,1E945061B1F3B7DE,D43EAB76E326A336,C9ED39FFB18ED8FE,DA2F47CBAFEBCE04,0813C95D376B4924,5FA89146E0E4381D,00002B61A1FA30FD,5A533EE1C61AD161,6E1310CD5678C227,C14DF41B1E77E5FA,457DE2A8AD0F6790,0642A4461C2563AD,43F1BA8364E54BFE,374FDD91091DAB70,32526EDF54DE1FC6,8461759438494423,7C441E3BD742BE03,F21DF043D0BB1980,0000102C9176C000,5364126AED2FFC77,4971C5995D1D0E29,76A0ACCDB0807E04,9F9F89C47C48CDFC,C105EA35891B69FC,1B2781DC3B5BC5F0,40360ADC5C1882E0,B646BA77530106EE,585057B3AF56CDA3,9ACDFC9DFC5B88EB,0560C67287C906D4,00002B86C538CD53,0422AF0AB0AD57D2,3B4616D0F09A2990,F38E2C087CCAE69E,7805607431DB5F7B,81225BA4752B2CB2,0A7822646E2CEDA7,CC44C80DE1C474A0,2AAF08907B8C8957,2B26729F721CFD39,2FBD094477E70928,5FA5035016F7BFA7,00006CA651AA3822,7C4B2B60EC103CE6,AA902DBAA18F7332,D260697CB15E37E7,6CF6D812C67A050D,7012D1A0755C1649,1A969CA0D56EBE16,0D53A83718B8C147,DB2FC2B3592F1AC6,837402EBD91302CF,8D5BB4A3FF69C499,A11D55491411B555,0000162AC625C40E,5F75A23A7B0AD0A8,49376ECA6A75F4F8,FC1D6DAB1588D196,9D15DEEF58D02717,7B095556F06A5638,E044086B041723EF,7962A6E38B068DCE,66E5989538D02570,2BC69D570684D629,C2F6448E43ACE035,2E98F2FFB6B175F5,000016C124A1F6AF,F18BFAC237E7C1A8,94C09903C78A70B2,ADE108A07D37FA69,336B9070375B13AF,67A9371CA74749AA,FA52F12264FD63B2,6E9635959DDEE6BE,FDAA3C8F0F685763,F85E27F68641A1D8,68278B963A13A62C,C3E44776180B42F4,000062998A3C6674,DB01D4CE1F5F4E84,16547E4ED09C7330,0794CD09A42C703C,E357BCA07769C3BB,D47B0EF8216394D3,DBBB9EC8430FB845,5B66D3028D607536,381745E4B1312F3F,60DDB98A3D461775,052E4EA9CC7A6B56,1C3AA1E6CADD6C9B,000008552100BCC2,84925452074F35FC,1247D6FD5C3F5192,C80DF14A9252A841,BEC886CABED8C93D,1FBDE3BDF6EBE850,58E33CF7C2E4650F,B0D442AC0956B303,4CA5B607BD558B79,5E0A3BF88798B019,2CFA34663CD95488,EA7E7149C92B0E9A,00003D539F503EFD,22AEE672E339FA6A,85B436881D3BB923,20EEBB6879805FA8,987064074F27B021,AC6A935F94EAF52C,92BA72301CE8621C,BE6A2425CC9F44DF,9A72D8BC8D1E7E9B,0144131BB1742493,543DADB20F4A5FF7,02DABBA43B780380,00002A8FE70E32B7,1B7535959D718B89,DC723BFA7483247C,85344AEB952A15AF,B65E23C730551126,5FD9AFD8C48C1CC7,B7870926C16850C7,054FB85DF45FAE70,C8C5636FC4E98989,5E7774D446431C6C,B7046972410A969E,4F50B1869162CB17,000004040890056C,FB88F8C29708BBC1,FA11F56B68008229,F92BCEDF0CF76B7B,359F4D040B333FAA,C2DC98452EE7EB85,622E677FC7E664E7,E3801B9D912E1347,22E20A3AD318AC68,85432DB58BA715D0,9D494C382EFE9899,F0E04417814B2F44,0000302A61F598F1,D9956DBB63AA2B37,BEDAFA3BD6BF590E,85BA5D43E4BA1075,8DF8183E0BC5C57F,80345080B9A0BCA8,3F9ADDE0E8CA6F4E,5CB131F848C10DB9,373B5AE7D43AC7D2,77B26E9FA5B171D0,B43D5BD5A832169F,682CF766AC58E1E6,00000EECA2A28F17,B0B9292636AE33E0,6974C604E4042BC8,270777C6D81A11D8,42AE6BDCBC225C85,3E921039F41A32F1,DA1B650B4167976E,D20F4B7194086AF0,0B207C8CCE588257,0F4313DB27F66242,AF21DE15D257FB50,7AA05A6F0E5630BC,00000DF34BD63986,A4A9912AAAC5A394,7D2FB8574D3E9F9F,D06B7FD2914C9469,C1410D6CA79B8C38,8518617AF34EB8B4,7A04FD979FCF207C,D090B56E437F93E3,FCD3B44D9C54D4A6,62E2E27F565C65FD,2FB42B46ED021294,1ED737E75604E4A2,0000614805BF0AE7,A0BC33559E6DCDEC,0B1155001569C215,8BF0553D9A78B15F,39116AB0B1C6C089,5C9E1956745B0729,8FF5DE369FBBDFE6,8977F3A6BF168888,A470DC48A46F8517,586C44714D74A519,DCEEA8F31104F5BA,C983C30052A82ADA,00004D4DDFF6C810,E77F53D5F28E3268,6D7A216CAEE34562,1B39012566722042,18634A0E9547DE98,933BAAA23B0CC671,2CA365F2380D0562,8853F9B40DFDFA04,CAED2A38F7EFF123,C97870A906BA7860,5EAA5D35C6B27060,DB90327659075F41,000016E3A40DC0E3,1396EA354DFC5EE4,09D884D055EC947F,B816E4C80B600DD1,C2448E2D8C3CC9FC,EB60EE36B63FD893,1EBA001E5E1998B0,F3C4AF865E579316,C927AF36B58B87E2,0EFD551C65E5018A,C4B830B6A0E8C7B5,C0F323684B7A8A84,00001BC0315377F6,9A606D88D4071B3E,35D46D0989B99936,3B8665BAAAB8ADED,1CC906428217C33D,A6A31F45A7C64BC9,B3B1DDE438572CE9,6248E0D4F4C7A514,CEF00716E0340C09,D6CEB1983F3182BE,80A7A48D63E52AB8,48BC17AA27A68E44,00005D0FB951157D,81A8BB912A0A224F,808DBDFA70132067,AA145D3CE27D650A,4CD42EA89298B4B9,396FF3784F0C8DD3,7636BEF8DC9612F0,C591DA4671CE0A68,72A3781FCF6E1025,AB86D7522FD02D88,5DC109E06C7C5D42,9EF44B56B8043197,00004A4F6A87EF7E,7A5C873F212B4FEF,96FD6A08A9AE26D9,941792C654DA47FE,FD33A50DFD9F02AE,0707896E8F91AF1B,A4D09A5CDD4EA241,797BE7A55A0AA284,A4E1204A1489ECEF,E6EE444D87E01BB6,C2DA0B39D7B2B6BE,544BAAC9775B0B40,0000625112A98F6A,5F4AEC37FE385C02,9EBB0444C85F49D5,7392FCE85B9D74D9,EC1FC6A7B0BB9EBB,264E4AB4CBD45A60,E4450B777009D710,D1C780715C8620BD,329A805924FCF53D,153BA1FEC2D4F782,68E76622FB5F1BE2,217E1855750D64B5,00005AC89DEA1D99,168E6718AE9E3B95,83F8F7C5E164F0A0,D15764F40DF08E1D,37287F7B58A2587F,D198D2BCC7F08608,C6162879B467EAC4,F0567C79C6BCA859,5AE4CCB55A91D93B,28B8B171546D3522,2562B2A5A48F3935,F2FB7D171385F896,00000DBC5EE9DA19,A52EFA9BFBF22BA9,325C6A889FD2CCD1,D38BDD3BC99608AB,176FA1F3E1A99CE8,133CD1AAA765CD74,31B0F80B478280C5,F664077B059D2AD7,E5C8C7A8CA9479F6,B91F52A67F6CE115,2E7AAE69EE4696C4,7527AA7D1322E4DE,00004E0B639B6E2A,7598E6AB9575E3EA,16583AA13BE3AC77,3F291FEBE72E30FB,CB62F630287E1136,72B0E6C9C62471EE,7A032F8E8A65F03C,9798F0C8C008B737,984FA33CFBF5B256,B50D5C9B7CFD6838,D9F9CC0AB1A1626B,FB97C09A556E231B,00005C63072A4D9F,FE0EAF1FC65CD316,7DF8BC1B4DC1AE4E,046F66CE33C31762,5E546C4180DEE836,4CA336E976936830,AF9B7D6C30E83568,5EA5286E734771EB,85F96F6D896F11F2,73A5AA4834A20E67,F32417FC4244EB17,25BD70AC8CE3D640,000047736C8ED2BF,D3B6CF8B6F085CA3,528D43C71F98B35E,C834B9AB9F8BC84D,A660F4B563B15433,F4BA0AFC05846408,CE1505D862BFCC26,D63826F7B50F8CD9,6D8A9C59893A234A,77455D091005BE5D,9BA67F5D5DA622FE,BB81A7940CAEFFC2,00005AE43A09CAB1,3C5EDA99EDD01413,473FC7577EADB7D9,9E6F1E2F67B0B230,D57AD72158039B6C,449937EDE066ABA8,666356B80138B78F,63B2399B5C1256FD,B6C54E38289BCE53,94A8D85C73943D06,9CA0A326FAE02D8C,ECF35D17214E1F53,0000196307612488,6B603DC0A319B18C,A8F5E24F6D030877,5E3F98D8874DFDF7,C925E5BAA414B9ED,9A49C0D616B5D968,5B68396FC4C03CD2,71AE9F37A39FB40F,36F3E296C976A9D8,D2502F03C9143F9B,5BD349F0C74B0F96,84B0C631B0EBD4E6,0000368D422DA9A4,FD7DEBD7E7C46B7A,A2F5853DB0A57102,71E10940E4E3287F,EE7BBA7DB5E5E278,5EBB31B109E7B425,ED2E405A63FF6EE8,E4B04D5F002A7F98,31FD61AE5E1B4F39,3EF4E116E2168A2B,35D952C3CECFCE5A,9A08A78F29CBB14B,00006F18F073885D,6A3974F5423E5E43,7483BCB551F92553,C2E4C277166AD21D,A7E435330784B22D,FD042D4935C2AE1C,43464C72E785410A,86D459E281355769,F1E8A6AA85785387,8145FFD13C9F189D,5118BD9BF1D3F5D8,C9A03581BBAEA8FD,000031E8586A2B49,0C69DCC1C79B88FA,ED2F6C54D45D47EE,9094016C79527B33,2B25B51EE3F4CC10,093C49EDBE2F54D8,F3301673E9D34BE6,CE77057FFDF1E224,09119979F9687F21,BC9744F95A3B084A,50B8F48954ED5DFC,D67FC1B7080E23E5,00005B7B06758CF4,D72AD7056C228D7D,AB419E65EBE4A542,52B597EE5FE38E82,F6C90FD6F81E3935,E48BD6064FDCA692,F2D9E6C07C82F215,F8385EA023288D74,C2A5888AD653709F,E2867AB42499AD6A,87B71EF3BC8F9315,28CD029AE4677E00,000040CDF65CE08E,CE67874FAC150827,907E6FC0B9CEA729,D03A8B94E31C08CE,17FD9E5B90B13551,AEC07B2F2689D2CE,7598B2A24E3B6AED,25589538481CE804,68D97B59EACA52BC,9142AE02A083F576,99F212C481B47A20,85A10CF79AB2F143,00001D676F637E10,52118B2A4985AA85,0C809187E40D514C,714794F67E781BBA,6AF2858AE687CFCB,02C3AD5A5FB10E9C,33D868D98095E332,CE8571AAB410080D,9263EEA96873488F,CA973857DC775D17,C91373C46FCBFC1C,B618F1DB6C151960,0000053E2F1212AA,12BAE986748ECE64,486CDA10F9965A8A,9A6EDFCB89936B0D,6FC012C15FEF1E0D,5B258D72F36C9F3F,55FAC06771FEB75F,9E3E9EBBA01B7EC2,81DE1EE37249557C,BF11507AB937E50E,CCBCC8EEED6263F0,42A83AF9921D87B5,00004082A6B5CD18,1C231C9FB49566C3,C948FBFAE1071CDA,C8B9C7AC04A966E4,B905A9064D7AAF78,1332ACACBE6281BF,24BF16977F46C025,178260C879EB3BEC,D3ED13ED89923DCA,536B33B94CD61B06,4F8DCC522619617E,D54F4535CAFB0B3F,000040A6C6970556,4CF2C9186AB60454,B9F767A98CD5A36B,4A8AA5BC72C4C18C,0CD0B4993C08CCC8,752A560BEC1C9AC0,F27CE2105594EBEC,C208F74BF516965C,8F50A6C85C281779,CCE7731850424562,F4866D0778D65628,D2EC6402D5B80E61,00002C2FD53464B3,BD3626C15E40C6BA,88AB031089F66CCD,CFB590569FBA537E,E2C31376C65FAA98,37FC6F210810714F,6B7D8CE2BA01A51A,F7A28AAB2B11BF24,E8F9CEE0DBB1B76D,52E9CABAB2E72FE8,47D1F6505EC3E5C9,29E4E5A9D73763FB,000024D9D4334CD3,2C413D61B46728B8,B9E8F72332D1FC7F,BA39C28200554BE7,A533025F0BD4B70B,17418A326210AC5D,652C848863120839,79B7E6390FFAC0B7,792DA51B3B3F4E3F,98DBE79EBD51C25E,9520168E55B1CE9E,4FEE74014257978D,00003D487C96BC9D,8BD11A24BE729E7E,E7060BC98E3754C3,25137F8F5F4FAA9C,D876BA798554BBE6,E1B1F79B9C7BB98F,6AF9D18C2C40845E,7319530CDE4DD361,60CEDC0720F997F5,3E05FAD979FA6F71,66DE5D94C179F723,22BA03FB3F80E866,00005E4BF388EC14,2D23BADE15022408,739BC18B3099F27F,BFC34E37397C74A3,255C15CE3CD7CA5C,3CAD5C4DB9FFF963,55C33185DF5EF423,CAD95D800947E396,5C36FEA4D3C2BEA6,15B021146E87577D,E6EBC02C9CCA9244,92C9FE3205FDAD82,000031B32D460DEC,AD47D76C7B34739A,5CFBF0A853C80939,DFFF6A4494EEF142,A742BCC3ED128A7D,21C6CDBCA7D3F7DE,27D91217126B9081,BAEA720F1FA298AB,C76C5A3B27CB72E4,CECE6EB38229DF9F,F902374A89727BA6,BFB414AA56B2DC37,000047A16A825733,59904832C93968F1,89744D52329AB24C,AB05C1AF8F535A4A,DDF262FC36B54439,715BD99E382871AD,B73E6F37FA9F5AE8,FAD7456701DFAF92,2EFCC06C013E1E36,D4937FC7B32B20F9,05F1774CDEA6A7B1,73E1F70DD8B748EB,00003F47442A4015,A29FC2AFC246C9CC,DEB3AE0FD31CF454,7CAECC6991270F96,D4230B970529356C,3913E3DE62079939,07ADA9D14AE6D564,3D64D0FEFBE706A4,5C2F733BBFFCFA9D,A815EE36E6EE4179,1A9771FD71090CB9,1EF25F822AE13AD8,000061C117CA58D5,5B3AA35F745CC8AD,75BC68C7CCED65ED,01E052EDCE060A2C,72365FF2106A66C2,0C8BB830FA424E5B,F558D038D439485E,029ECA9F6E7CC92A,352302D6D3896D81,CA607C00241C9C9B,C079171EC561C0A8,5AF663C62F12195E,0000303FFC7BE5A2,F4FC2E5927E2AA79,68C9C44F35BF7D1F,6617CDA6B200B47D,E6F29DADCE707963,D1A514E3C0E05DC8,690C1A8C7D731C0E,C8376AEB3D9632B1,05B30AB8EB13F55A,533331A856323BAF,4807F7F69AAE5E63,C946181F2FC3BB4C,0000564867CE9B01,A4BF10606112AEE4,FE28E4633A87614F,896308C93DCFF06B,FCF473398F292FA5,D4BA2F6DDC915D3C,4FA7F879B6A788A0,41ABF9D6D55FE7F0,76B6D2B28FD3371A,2E3325A67FEB56D5,2992A6AEC3E5978C,06211838D33532BE,0000196C7D81569D,0212C1E24E29A38D,7B90F2B3852309E5,64CF979FDCF97138,460FD1B676A26862,5BB94A760156FF68,91036D21CACB8B18,7958FB8608E856A0,FA1F7C112A4289FF,0E342508F0D8C184,40DC55836FD04EDE,B5EA8DBE89A6FE68,000058E56E56E33E,0A22E19C2B79E101,573A536CF563C207,687C68280EC55B08,315CBF84F4C5E821,7A036954AED11A77,90D38626B28506C1,B64599243C1C364A,2E3BB137D427C00C,3FC0A68F6FE85105,5DCF92F5556BC3AF,7500E3D5FE28736A,000054CCAB16D9AD,5F4B548C24BA41AC,4EA620A21D33AD83,20A57C65530476BD,33E51B659893652C,62E08696C7DB54C8,D5E363D045009221,4BD76A9D05126E0C,74FDA8FD1567C24E,FB897D1DED7B6C02,84A137C82C97A09E,FE790798B22E2CEA,0000169087A2B928,81850FE5165BB484,3FA5A38F05BD9176,924F682643C75E7D,9F92CD21E154C745,43B0AACEE146C919,E616D54B5AC6D3A2,70DF17764386602A,68C91FE666AA58FA,568845B4D9E9A8A2,5D544F0109DF1263,05C89F8C94594C55,00002E795EBF958F,06392B4B1784272E,3EC18A8CFEE40895,58F6A2DE4E4C6B7F,16CA061DD0D90CB3,4CE1A46E4B0811A9,34510EB5CFD2D846,143F5A70383301D6,89664DA18A374914,37242ACE4E4E57D6,65305EB7E2AB5953,70FEC62D097F5C8E,0000214EB96C2756,ADE97FC94F22B040,787F36C729242066,8939ADD3DAF96322,0DFC058034A2ACBC,12395EF2DFC6715A,BA40B3A1ABD8FCA6,AB08B2F88FEEA93E,32C396A3E7DB9109,9BADFDEFE6B176E7,BDC3D41DF358C18B,065152118B53B20C,00002CE2DF45720E,04FD2A7E4A73422C,E5117D2F38B2C335,29B888D0EEC26256,3E1641F1AF5D6924,847148552FE91E85,B55DE057155737F3,D9FA5BECEB70BE9E,810015570E9DB804,00F5D1B1B062A580,65715A8B59ED3348,A25581115F80E819,00005F86410CF057,7D0C055DF7E11000,780CEF18F2C1AA07,5F5F0914E8280030,83D152024980ADFF,44F3927785AF3650,EECE642BB60EF046,C18B75199563EA59,10AA79E90C9C5BBB,78A0A0114EC2B5B8,256CCB58E940B472,4DC9BD0A335ED63F,00001DB0CA249608,9C0773EAA8AB91B0,491D3E7E26CEC6DE,0BF410AA460199DF,49DEF5463FEE5367,C11F9CEF93F6AEC0,0EF406171101EADE,FD7E81120E5A6731,A7C73660F69C5754,87DD2B70CCD70A9E,32DFA1A66E84EDD0,8E08CAB0244F4654,0000590DAD701599,4E9A94FDDC47EB5A,B519D19E6FDFD7F7,ACFD936500C76A68,A601C6BDA40F157F,8944E8478629900A,B6025166E29E43BA,3FD1C0A96697CFFE,24353D83B7D794CE,EDB34650368485F9,7E7FA91789BFC839,227EBFD453374EC3,000023EDC8C0CF6F,7889A177E38F8FD4,E201B495CEBEB8A4,17D91721AB373875,5FFF28A3DE92749E,B2AFB3ACBB40AFED,5B9996D5B7497BA5,C356A2DD6FC6DE91,42A00DAA278037F0,1E049B6073660C10,840B5AC6FEBF0BA2,7256F64D26158093,000042802FB9A9A7,36D35BB7A197B14C,85725C33FC9D6003,B1FD083A2029195A,165988B95C6815FE,F8323A111CE00B03,BD4D15013FE4F6D5,14092AF5942D5404,BB6FE411C2375A12,44A3C71E4E0369D5,9291CB73D185A877,AC4641371AADC59B,0000290FC61F3A6B,2EB62DDBDC3D30DA,7DF0F90ABF8E072B,E239E1D8501A47A2,DA6D2EC78CB8CA62,E8258D897769761C,EB08FE079E05F315,25EEFF3F76CD9644,6D3D9080D0A356E3,171BB67015A874C7,4A2AE6FEA6D876AA,D14FBE0C368D89B2,0000308BD6F9C513,CFAC702E598927D6,C05BFF8F9B6728A8,B7FE943218C23481,23A981F5915CD3AB,7B4AF57EE2ABFA4F,8826C3B5A2B817A1,02FADCE08AC9AD3E,4933CCC0C31CB281,878008FDB05BC4A2,A949E87039853026,1B02B4F7986167AB,00004C9325FCC485,E34CCFB983A65638,C53A777988C7D420,4B2052F401CFA748,2832C0C1B215303B,A5BDD9EDB9BAD1E3,582D824CA49537AB,0B3F510D8A1F41F0,27F0030AC84BA396,EAD9C6E19BDC3657,9316169546298614,464CDBF04C4D91F5,00005CB907339E98,EF0415B34B9B5065,9F0B12129414873B,20B0A1C38454ABA7,7471A66838CD66D6,29CFFA080803B452,0854BA0F2D78DD1A,136F706DE4E9023F,8BB5ED67F6B7730C,00762CC346F6FEC9,8AC744954D2250E0,1AA35928EC642116,00003F85032380A9,2614EDE7340039A5,CD71DC9C389D9F6B,56A7549AC8FF4F0C,DC04C82E86D3101D,08B1F91BAE4C92CD,30F635ABE7B271BE,647B4190A22D58EE,DBAC83C210CEB61E,93FAFC57ECB249DD,CEE71C72C6130B37,221162E03AFBA506,0000470D509AC8F2,048089C7F9C63ACC,14DF7BC5507542E1,C8ED36EEBE190848,443BC172623D139F,97C404A02120B36E,8A7A7BF05D94661D,8B9B82F63395C879,758599274727F407,7E45B2C49A221237,BF5CD78974BEEEE0,F9FB19D8F08F375B,00000EC388F95E40,FFF1DE936FB855FD,B591577C63E8CE0C,4DBB4B2A763A8FE7,CC4B8CCAD959B6A3,00773074FB2E36E3,A125A573C6099993,D6ADFB177A000D7C,6D26BEE4061C6F3B,F7E1672E15EE239F,11E053D565777CD2,25F1AF3E12E34F47,000048D6528FB383,B8C577D96203D4C9,8CFFA4A233224CE7,B77C0315938B3C89,DF4F6A3477BA5862,AA085F1F68C5BC00,620B94955E4F4E25,811ED61AD7EF128C,1BB43B63A2DBBBDF,4E5CD1A29EC46BF4,76F2BF645A6C1D3F,2F316D293283CDE7,000002E368FFC9F1,5FBB0F1438770860,C09127DF2C697377,EAFA58AACE7D6A91,E277D89EEFD6FF43,ABF2349A3ED81A47,46484FFECD1AB5FA,E0AE06BBB52150DC,32A0C6BBC61B254A,25C3BB5DC19B4A9E,A6BFDE403F6F9DA4,FC3974CCF1456D6A,00003B9EF4E60299,0F7FD395CC447648,75F8A3753C953CED,6CFE2BAF996B69EC,43CD0B67A66EC662,2959222BDCD51B8F,17EDB3A9157B7404,C9AC900469C2ED1D,DEC616845496F699,C8122B2FF8E9E10C,09C87C33AAEF7408,15BDF271A4C27557,00005B22B9E15189,820C176E0FFED070,26E2172931D0744C,484425EFC4FED497,A82D23CD524461ED,A51075B6FF331BE0,A63F8C69750658F8,B95221DD1E0EA03D,6D9CE99410A10294,21D76C289EC5E847,E7BBD17E575206D4,1F03E185C78181A6,00000BFA419FF563,ABA3A2924366AED2,E89F443B50416E1F,81C2AE1E786C0A65,A0F15D8BB19AACE6,D77421B74E4BF91F,F1DC6553728BC29D,EB2248C7C6ECD85B,77BA9F1F90562274,71C56DF5AA687CE2,BC95138CB69AB830,2C32C88F84956256,0000528DB5C43360,68134E7BB5A4F5D4,AC3EECFCE288AB02,78704660E5C61B6F,6EA959907B3B6D9D,9703BC40AD7EF91E,F1F686F8ED01BA01,5ACC4721335891B4,3DB2BA43CA74CB1A,C03076E5B397C195,3593B287FD85E336,CEDD326E4826693B,000019A761960DDC,EC89931D120AC4CD,7DD859058528549D,31D7A80BD060D9E8,8EF8EF6BD982917A,45F37BDB99C80E68,B5E8B11006541987,A855A883F9F821BC,30C970E41ED3A213,01590D1CBB0FD355,3940BB8539305E16,8D5A6CC91B90A76D,00002B59A9533AE9,6ADD22DF51F78CC1,867BC90DF0E3BFD2,72CDF84A31F1A34F,DD0A3D99C89F2FD3,90F4A4FA605D0FD4,4B9CA937AEF35B1E,CB8262EC4E29FC9C,B62858CC706C48C0,676DBD73A44B825A,6BB5D535F965F866,E7964E9DBE4E702E,000055B763C025AF,01E36EE356301381,39B6AA483279161F,2F0A35D3AA41B2B5,79F4409DCE877373,2CDED19D054D4D30,EC9A97AB3EE5E8A8,44F5E12C5B877BFC,DE00DE3EA31AD6CF,B3D28D5FE7C064BC,8ED71458CCBB8596,A78C3FE8DBD30FD3,00004673EC68EDBA,C61C5F7DDF85DA52,F399180A773A71E1,C9CD8AE33A10DAEB,B842B38474A82C84,B9B7F9BF6505BFF8,F8A75137BE3227A1,9E77445887A72FDA,7C7963607B70255D,7F1CEC9554BD381F,38871B39505EBD0F,AEF155FC5E1386F7,0000460CE6C3E4E6,84A250B8CDD51915,047142B5858788D2,12EDDAF3495468F3,C0257E323AF49A0A,0806CC864997B447,AD5949AF544E110A,8A8B839E62500743,49FD16C331707794,03141E829BA33C73,2715303A7620BF2D,37329A775BD56EBD,000009671358D061,C91AC031A9B26853,D563828AC78F7E46,880BBEFAB051B7BB,C206A6F8A85F16C8,0D5E8CDA52627902,08EF40ED9C747E41,B4F65DFA45B18587,396528BF9588D0CC,4BEE7FF6A192D8E6,B1ED552787ABA632,D60396CDA415D370,00006337CFDDD1D2,D054E19AA6341276,1398C7156480636E,AE46D26CCCA7150E,E0744C28E974B99F,3096BCCBB853BCCD,C14541AE67A5F799,6BFD4B322BFEC701,C9798F017493B501,8B32115E59604B41,83E5068888A8A136,FF574C0AE710D1B5,000034A5B21D9F93,882ACECE07496416,20E38C7E00569B26,D1ED4FA62586D86E,AD24D81F6C766E8A,8BE2169FDF6F490E,E099AF826BBCF51E,EBA40B4B5C223C25,6D04138F0511342E,06CC6B3052A0BDFD,B781AC63F284B201,F9043F9B1EABE82E,0000440175A10054,C8175CE823640CD1,FF5D759522B3D16D,30F89031AF3F7F20,64A6E878EC670EBF,A754E49542B6B9A0,ECA8395BD15CD6D3,110BCB2E753A642A,3C8803870CD557D0,24A4FD5D53633519,D95259529AAFADA2,B0ABA6564925BBB0,000006BE41FC3074,055DB94998AD475D,3F53C425CA7A5C34,3C5C438FAA44F546,5F94A7207E968415,BEFEE702D0999E50,9BCF95956D35B20A,ADFE6435FE802233,D36BAAF2F52783CE,4D98298549B64D83,71A303C982221F1B,7A6B35E3F1411A0A,000060DCAC2B2292,12EC42A2527B1419,5B7DB8EA01CA63C7,6CBEBBC480210D76,A027F42F6596AC3E,7D066CC01919015A,E50ADD4F957EAFC9,F5D85F941E0BF137,CE89F7ACE2D022C7,5A38621B96A65430,512078AB3DF79532,BCB0C427E58EF6F5,00000061BAEB15FD,F1AEB477CB02A04C,29BE43C22F20FB9C,BCA2A758ABD7AE6A,2FD42EBF74AEBC33,A388B504C76CC900,F66A262D5BA3CF78,A8E77B93D7D07F8E,DB1B0CE99D4EF277,2846F5E4D46D851C,98541BBD2D88BE85,6E22358B64B1E6CF,00005F2F44910C21,BE4DA9955B12CE5D,DED98E4996593189,20919F3CD5B74CF9,166DFB2D50C0A0E3,2D1FA521FDA4DC45,01FDCD2ADA0E6B3F,7B316E7043A775A8,F54D285CFB552B61,C1BD1964B3CD113E,220C9E8982D23974,A4A629E4526DA1A6,0000581C96B1B9DE,D25E1232ED3BF696,6CFA4666762C0169,BA374D0D6C2205C6,C414AACD4DBBA495,C3A370E5CBB19201,C3BE0F7CFB7DA24F,CF32BAE81AB87C9F,40627C5394C56F66,F1B04DDCBBCAC07C,ECAEB4339BE27C8D,432456D9695D1BD4,000011D4EB88728F,E88992CAAF12E5E4,F2A48C3E6CF1811B,DC0E241F409754C5,EAAA4E7E9CBC09FE,4BE455DB45E5462C,C42AA2ECE6454A00,D45E73C7CAA9479D,89A65B1277CA6C7D,23D3903C2DEB8624,2C25935D07F24C90,77CB7F6DEFF4ECB1,0000649FA99FFA13,A233FAEB0474BFFB,9B4224E299E6C760,F7A1767A44D821A4,0F4ABB5E753CA40A,330134EA2693A5BF,BADC1D9F5A905020,8D9F1ED2FE2F028E,EE7BA1B8083DDFC0,BB25450011B5610E,B689A24957EBC4FB,A8BDC8FED91BCEB4,00006958D18FC6C8,F71AB8AF90D91A27,80B25EBD1A69FC30,FF8B8A9662B1BEDC,3BBB1A6789A71408,C605298682ED9CF0,72C415A9A32CA15B,1698A00D0B20EFD3,D43CFCBE52364282,0D0D8E113C0EE1F0,28C9898328DF6B45,E18354A58879789C,00002E0EE80FAC3F,6D8AE645E77E6B20,3AEC59CAE699BC29,9639E12E32B13B10,F7348CF6BCB89C82,897A838D3423522A,391D705B724334B6,3D29DA78D115DD89,F1A218CC122B0739,6D9C12E6F0317A92,5919DB13FA62926C,E487B437480D7D3F,00005896D2410CD5,521F14E6A38B34B1,8498CBFB84322EB7,A015433710FCFB47,4386ECCF647B03D3,B50CC2163A2AD4B5,A8C1FE5F027CC4B1,23BE34F15C69B880,6F1C8301DF934830,B01138C31C0D13E8,2E558D6858FF52C4,92BA9CB0D6EF3811,0000219366F6CDC4,6C13DBC0F6B7F175,22B0115ED201505B,D04237D0695D07B3,5ED76164FE31B671,AC64E87948C7AEA7,CAB514BAE5D5E1C5,60031F7D9F04045A,FE033BE785628FD9,8C136BACE9EEACB7,893046B58D5D6E04,6FB6F3894988EF9B,00004630884BD33A,1427F517D84254FC,04F44F768147DB27,8E5A2DC74C23AB3E,206729AB25F75FF8,E4B6FA0D870C2B32,C8060E30DAFDB37F,6F5F998A3B7CD2C9,239F3B07377B80E1,6DBA3F76741B079D,88F0991E64995F72,88B1AFA59CC7B532,0000083C4251AEA6,E1D3D027EB017D63,E3540C85A471222A,903036323BDDB4F2,72CA64EDDE2691DC,76E9541F10FEDDB7,015C8214C0A7CF60,032706AA038AFDDB,13B5B8E499D677E9,69E5A4C443066DD4,16FF23EE48F3A442,1D86829123AEC9FA,00000EBEABCBAFC1,321A05EAFFF79089,D525D50E51679737,52441D591406BD18,F7CE55C705855EBF,278FDEE3F24484D4,E1A1004CE88C9963,17E15E7CE6D60DE1,94FA986D97300B70,F9B05A6F90868044,57EEBF2F851301D4,A98776DE4842F6E3,0000500949DDA11F,1039B442CFAAAD98,1876C080EAD40569,82C7646314B1899C,0EEC5870A9CA7718,51B8DEC8AA78759D,B8532C6F457B4BB6,B60DA707DF6609EE,978E0730F5E071A4,EF37F45F8D2710B4,F9BFE8205D1ADA7E,93DC3CC4535DBCD9,000055893737E72B,6DC6719F20DB7DAC,7BC6A1C8113A83B5,9169AE31E0AC4F67,3CC59F2EB6ABB159,895AF3D8588FB273,BD6A2615B0434F77,F7C99220D4448E13,B447A3671582619F,FD41A27C9C3A4253,33AA1ADE49E41F60,8658D9B654DCB2C4,000012BEC12FCFE1,3E25FB9C025A015A,0D296C0008124C62,5B082453FC012D39,22D59A56242CD30B,F20162139E4625B0,26DA291323B6F362,630BD8BF3276354E,9796C3A74B7C856A,AE4A6D0C027A852B,F93C1541FAAACBF6,C569713144DE45F8,0000486722E30390,A9D8ED833A06547A,72BF556BF971D000,B6B9B51E5CB268CF,28F545F552BEBC8F,ED769ADA8FE6423F,9D09A6A389DCBF8A,A04C5E6A5A157063,EB0D765B1A47EE58,F8CB077EEF65220F,E78F63F624467FCE,1C90DC2A5506C7AD,00003CAC1CCD6F8E,CC2AD196BACF9C37,134522992E04E935,BA5EABBF7DF0C1EC,A5EE400CB203C2D7,C27CD162599AE96A,EAA8E06062A85D88,CB40CB46923B8928,AE97D661D9BAD613,DB79D9A32FB2CC7B,D0675484725A0D92,E3DEE039C4455513,00002CCE01A16E68,A84A35653DCF5B93,FA7FFA315503C24C,9BA771A93B3F66D3,30AC4F206E4F2A8B,108EB783042A0BD6,A60D5A06DAE6CD21,80558EF076E87BFF,96F66482F7EFD716,32BFB44963860AB7,FDCA1CADC88CB08A,B2C020C45D5B4386,00001E6D8DB059CB,985286D3F38ACBFD,CCB937386C5E8578,C4E6EC92A169C880,AF6110DBC14D743A,39735D85AEDEF510,A8DCA3A818E569EA,41C2243537BDF912,266D73843116DF91,A729D0DEE0FE967B,B50FF60E8C66AF7A,182BB2F1A3C9B2B4,000034EDB1614659,C4013390FD330D4C,542559B7A2BC8B38,C6375885138ED051,BF0548590A36E25C,D1103BCEA0465500,757DB82A06C87871,8E4BD9B01C756F3E,23DF74219FB11454,83B33B4E67FC9F3F,2223D0482604FAC8,A06BB17B9B963F95,000063D2A7EADA18,3B53284BFF8F8C23,A11774D0F830F4C5,BEBAFAA3B8B9958C,1F6B2AC92C8559BA,D4A871BBBE7738BB,3D2BA628BDAF73F2,43E7661CA673A3C9,CBF28699FB5FD640,979F11A5D41F7A34,A1A181852DB171FA,5021F6EC0F5DA35C,00005140A0F3AAFF,80C28D441D1B2A2D,43749EE078E487EE,DF261DCFEA7D89D5,184506BAEDCE233A,3930DBBB07AECAD2,CD04229D265FB223,29A0B65F6090FC48,4E54272E4D95C4FB,D592EFC5E9D75A11,43A6EA00961F0119,1EAE55ACCD831C73,00004C579EEC333C,C5AB38046FB54FC3,09021EB2E903B909,24FAF16C71566AAF,D76A2696E2D2662A,57FCB86F9BC2C2BD,406835B937598801,851D85DAA9E2B619,D0E3148C94D7EE8C,60809FE60F1D44A3,52727B7335E9F4D9,65E5F1CA614E6244,000025981CC5BF01,44D12B8F0D1C8EDD,477A0919CD66414F,BCB03BAA4D4D5272,B0926E8CB2C80B5A,7DBBDD1DF010019A,73E634D6DA9511D0,4020DA2E69795D85,D85B6AC215AE91D5,3F25CFD4AF2813BB,2534D70B48D2D5FE,016D135ADFC71E8C,00001EE02F9B8166,AB6692E78B59E2B1,C0CF9D72FCD01B20,5A7DB2F66E241B44,35D64EAE5509C1A3,6A787FF8D64D8AD8,6E4ECF5615D88F6C,7FB5230D6C15D871,77A1BC0DE3FF1BD5,258810313D75E848,9EDE2ADA2D45E00F,800B83AD006DA521,00001932DC3C4834,CAFD957CA2D402C2,A8DAA1143E6643A5,A118CCE3F937DCB8,1F03EA8999C87688,AA33320E928BB163,B3024798AF9616DC,B9CB152BA40A8897,CD2783AA405EC461,90238A8B4C8A6BAF,AFCF2434EC21E7F7,9E3F8B6501D7EC89,00002C831B68F56B,0198A7865FD05813,AEFFEEA258053605,9A75D127DF2391D8,9A51746C43FEA28B,FAE40F787996577D,DDCA95577B1C74CC,C5E229D49A0A6FA0,A2BE3D56144BFE95,BE7681A7BA612573,C3E8B06A2C0E9B97,BF44F950940E1655,000065BD653F9E22,2885BFD0603956A6,F14D47DFED2F812B,30042D5E9C1FCB5A,A10168DB72421B41,144655E4635386D1,FB258DA62258C879,BFC0F5F8F207496D,50E6EF0FC7609DF5,ABEF1EF969670724,628392F95C49426B,F30C9DDF8595E031,00002A6918487C84,7F25009C8360039F,FDEC35A4D8079E6A,1CEA6857794172C5,73852210FB516EB2,92823634D3F262D9,4C02CCB83B2FABB3,8028AA0BF0F885D6,805E07831441559B,59BA4882336AC312,B12A68DB71AE16E7,A2CDA749BF5FE520,00006E38F530511D,1D7A5DAFBB0196A5,E0D6B9B9FFC620BA,28F41D3B8E45F406,0C669C70E9607FFF,A5E5C420F4E4F647,FA8ABD0E0210C4F0,5BE5948EC6951FAE,9AB7304A937E9081,A3ABF18B305F10EA,3905E043F1D1A8F4,038360D382BADD35,000050CD2393AE1C,78EA73510B5F3E97,77785508A86747C1,7FBD62F626C7E281,25CFB2B01CCDAB35,8E75EDF0A6AFB7DD,3987CF08E8E4C24F,51C08A0357A89299,6352EAADD4BC8269,ED391EB6D318F500,F75C7B2C5728CC69,B31E38C66B9440C6,0000391D4B7A4DE1,6126744289372910,D7E1C8B39BC3B72C,254F560506F2A186,385888994CD5A6A8,246E25263BB728BA,F4E8BAF735810BE8,634D61C2E7E31FCC,61D62AC8524D8FFD,3047227EAE4C7ED1,9F54F37532683B7D,BC686E8E2333FBA5,00004A9004677C6B,2C8AD54243556E5D,F9483FAE5B1FC78A,E5AA727612FD3F06,8FA1319A5257FDD7,5BD61811643EA813,C7DFD3E6B37BB1C0,E838651E3BA0E07D,66D7B393B121FEE1,34DB323BAD9D8CFB,2ED6651E2F44FA94,E29D73BF99A315E2,000007181909FC21,734D7DD8C8017899,9D31DB1DC25842EE,E84E883CA38CD74E,369D6BE1ECDE9EED,AA14BED34828FBC4,D5BF7911B782D472,82BEC9619BC57B24,E8553E72D2F9ABF7,650E3A6127F3F004,2647721F5935A2F3,B6226C81CC6BAB18,000048A955EBD219,017287FB270B5415,D9789BEA28902292,1D60EA8F012FCB45,8FD4C33A5C1D70D8,6CD53A78011D149E,E52F9AADD0CA099E,A229BA870D2F1753,6C5F51241B8D5810,CBFBD183A2259A23,E6809C570C3FFF9B,74263E7C8E26FE3D,00001231D34854B9,B8EACA97478B2ABA,C2B2F6B3EC19F038,672EFBDB33C01E13,73C6795EAB31BEA2,49F4BB8B6555436B,EAFE693EAD0AF2FC,7B63DC93FAD4E090,31CAB196A3A6E329,724DF9FDB028FC69,AF566038A92843DE,F1A7D78F53CBBACC,00002CD063141870,44430B2FAA29C563,5B1106F3F137AE9D,24EACB13A8698314,27A862D1AF14E249,E590C1063BF07AD6,A149A6B2703AD3A2,415E2AF41C2A29C8,17B5506BC84493D3,549AF474C78B273A,79A016C14E8B2761,C5706DA5088B1933,00005A40169D9AC7,FD672C2C12170210,BC75DBB1EAD8425B,697B8C74E798F9D6,29D230369EC2A4AE,22E613AD64297754,2510A9ACCF54D9E4,DAE2BB6A460AEEAF,F41E2A1924CDA0D0,6E0199CB8606F5C2,E21C98F985D22B22,B335D923D35CCE2A,000048AC961F106A,EB53218362BAEC5B,FA49F2D4207A4DD9,CD5AFABD2DC8813F,35AF3D70888D87F9,53FAC172E7429F24,AF9E716AA8308C89,63EFE51E71C052CB,3501605B9E46DFA2,AAFCB2EA232BB730,53AA5FEBB187A76F,FE8C52824B7487EC,0000002F405B5538,E3CB04C0B421493E,F878553063069DD7,15B59BFF49B4BB90,3ACBB583C3C06BB1,ABB81A95D0FEDB91,344605E1E0273375,995D76F2803E8CB7,DD9A74A61D147714,752ECCB507F1E0FA,FDE647E5FE04F01A,0A7CF1F6060905F4,000068CFDDCA6849,666AEB000FAE5E01,41346C5265322415,A62C894EDFE082BC,DB4F810E6A3A6946,7DB04B8146EDB669,D5B445DB4B301F93,D07BA8AACE82C751,E223FE5E63EE302F,8082062F75B55D55,902CF89D5B5D629A,BB903C2C71EF9624,00006791AF5204BA,B768BFBE78F264AF,4429EFC9E700AA3C,121D52B619137711,C704EE45C0DBF2E3,8931C0A2C8F0C96F,AED988C216D075C0,96627C92B5FC3E6E,D3911959A6045140,73D3E5011BF467A8,022E081F577DD2AF,55B73DEA52320FC1,00003512EB75D89F,C85DB1F28DAB77C3,9753FDAD3FC30F67,E6F7ECA2D14ABDCA,D2F70D3D151042DB,7685C161218E9A5A,D975965523E22339,6D350930750B0DA6,77715FA213D009F1,4AADBE211BE6FE37,F284682D9C510CCB,16EB351FF3B10F77,000030032C57164F,D6563D717364F17F,A996C64DE920A9A7,3F348DE00AD06DFA,7464AE9D430631CB,5764BC1032F17A46,691D673A5A92B875,21135B7085D78263,8B48907B33F266AA,BD8F270988A3875C,D6D1657802C6A5A8,42C78E5E560C834A,0000374C93E40405,B4F94F09A6FD15C0,D8E9317619AD2E66,A81A350962F64913,3D93549AF70991A3,EF2E575F8848A69A,9C51E235FA28D437,920F5680420E8AF3,60798D583939CE1C,BC1B3475BB5BEE4A,70F5AF3243CAA1E8,792C7EF9D9F26589,00002C38BA0E6848,35B7E4C5B8F7DEBC,90A3A02A03824979,D20CA40FBC9DD846,ADE0F2544AE499A0,2BA3574946BBF93D,0EDA3443F2B07FA0,50137543A84C4243,211016162F69218C,CD2F3803412B3ABD,BB78236D8F691C9A,9A72C6532556D64F,00005DCA59D4FC3F,1CA659AD7BD93735,D96CC8DD172846B7,281930EA5F64FBEF,A7CC852C3C09D3E8,FEC12551EC4A4612,9A2046D4559054E5,D0AFA1229BE69781,085C07A4D6D91AF7,80A566B5F1595DA4,450863CCD67FBF44,E546752158157341,0000340C0522ED4C,003D3230DC2F548C,B173FD5146F156AA,5CB82A78E3EBBED4,D3C287D3AF5390DB,D8FCDBD9B163D3DF,8C76FBE395D80A5B,1A114D9BFEEC7FE5,2D7CE75E7F39A36A,A43629046D7576DB,5692D8AA2105FC62,279F0461BA937C1B,00003AD4527F8115,7654A0A8B5DC2D10,D153FA0031C522D5,F222853142376D48,1C47D6E77EA8AC7C,91A951C9D61E0C1F,6ECF9E59C5CADB2A,AF0AAACD3CCC9C21,74618EC171373A9B,CE3A5FE59274B35E,3C7A7A3935C27DB4,6735D8276179B1F4,0000207238C4A05E,051142CBB7986B2C,751631C602D282A7,D5F3CF575C9A6A3C,FB43D2C279A6C385,CEB98671B8317961,A9AEE73E8607D134,B31B556FDE175A39,48BBA727309D90AB,40D35E3613254D6A,23BB258BB1D1EE44,AB475A9BF5FD9933,000052D609454CC1,9EDD70167F5344A6,28B5752C2ADC0C8C,C7BF9E137C580D3D,D5F67382AFC983BF,356A44457EB93300,4092F6D9DBD13544,AB5F29F48083E07D,F691BC4C7A4C4983,36CE403B677EF687,3FA6C5FEC73A1641,BEA96461F191C671,000056B65824E74F,7BEB78E98E7EBB73,CCF900C31B4ECB77,54AD1F50B4417C51,DC0B30283343343C,80D7B79A285F8B4E,8FEC295FE783184E,019CC7F61B594A81,E7117BA092289445,C1D6BF38490FCDC7,B5E604897C326012,B17E3D1DDB212662,000040346EB071B1,93DC3F56455DDA01,FB05B5933D51E9A9,A44CB69A89FAEA20,233C4AB59BFA0A9A,741ACF55FC3EC662,C369001110569F57,E142FEAEB759CC82,BA1B5E1D9975D9A7,E71C9CC747BFB996,199BD1DDEF429889,92A3207E7E22B950,00002CB1EF56D806,80C8E84FCC706001,499AA177CA31D46A,24AB9524F1309A3F,69E9F4F471DB6FD6,565F49C4215172B0,10B962493C70DFCF,287D24A66B67E811,315ACDF63A89AFF7,DE6AA3A2FE0776B5,C32C887521DF3563,165CFA28500192B6,00005BDFFABDFB1D,FD8746B80215D587,21BD69493C8AD6C5,95450344C276CC69,C32C72980FD8E0AA,78CA7EDE2DB99A07,0ADA879B9142FD75,D31C68888BF68F7F,E3DBD1067557CCF2,33EA91CEAD7188D8,BD6AF0B4ADCCA3B8,C81FF4D967DDAE9D,000053DAD4B9B00D,CC0DEEDEC08D20DB,DF017C9EA871AC0C,E9D5E3AAE17137E8,E903757BD379ADF5,4CA60C70917A62DC,2D401515C8121436,DDE48E7E7944412A,5D504C2E63BE69A2,95C255FC2223555B,024CD0A81E4F24D8,4167AD0B107DEC01,000003434F0F95A6,E00C36662EBE2259,FCAB52942525DF1A,0A3CD2B37990362D,35EC32A5AF54A0D1,C0E4E58C164AED42,C360FDE6655A40AF,1F806A4533332C1D,21ADB73C58A42B03,B001203268EB57C4,B79C2C14F8A8F2F4,3778230545DB2E92,000037754454AEB6,83FA163CDA9358E9,256DF288BFD7DC16,DB259628C72410DC,43E3A45C10FF3675,F5A00FEFDE541AFA,3D002B2F8FA74A78,A58BFFBDA9BF3A7D,E008877AAA34394A,87CC15AF1926B12B,696987E0D8545968,87B38C23B3031394,00001EF68E06006E,A9831452576D47D6,E6CCD2E9166D6AE9,3D2DD5CD3E53884A,CC088C02CE34982D,23BFD3A55954AB47,A6649ADFD398278B,CE2B41103C2743C4,FEACA11077B2E67F,6F8E3D1FE433F645,434543A361F50362,C313900CAA189A94,000055591EE06262,1D9B8000F3F00475,4D808882508A6F02,57855622F40D0879,78A4FEC99298927C,472D6D9FC115ADD2,62DE7CC2BD39F325,CF886E145F91DBEC,06B26FE26B2112FE,11E60D7D526E8180,8E1B3411E014C1B2,4366CD786DC10C65,00004EAF2C58121A,E29FA8E8F4E2C2D0,4DD2365889E10E0B,C62CBF2B104F80E3,4E9723FAAB0341A3,217FA9C9FF4191C9,0C78D083FC6AF7D4,0C032D6AA4FCE259,7A653D3006B7E433,D0746AE2BF8EFA65,15ADD27E4BA7B792,0F3EDD5CA0E8CB8A,0000188FD4242CB0,8FE971FC03267BC2,513A2C121182D35E,42455B0B3DE06CF3,905FE2D6BEE139CF,C4FB0E1830B6A944,4AEF35C9AF33F550,B9553706C7A0B1D9,DAE2B76412BBE8B5,0DBF5F3F23297F76,05150823B6ECBA72,AB8957C1002C59D9,00005BBAC33BC455,EFBF50E634BA5897,63FAD1158EAB7507,5B589143BBFA1E4E,2F1A54C97D1643AC,4086D687B0BE9B2F,983EE6D9AB2C484D,B79C0AE064DE8C1A,4DBACB65CBCCA21E,0BB27D4F8B71C77D,7934FD3D43F8335C,E60184EB3BA4863E,000054487FA5F53F,24A1BAB340813C40,86881986C87F2843,72E76F26F0853390,AA60DCA27429CAAF,8CA9C4A9128CCEB3,4DC0552A41FAB95F,D55EBDC4537B2A1D,C41DFAAECB4A97F3,B015B659869720B6,B38A1C7EE11402FF,85546B5946A214DA,00004018DF6C4876,4E77E9EC8323DFD4,2BC4BD0663631B97,2C22A116C6A05EBD,BA406F0EB5881B75,F388193189428045,3C3FA0F3BAACFBA4,139193C324B305E5,13519B1C6953B265,56E81FDB5D33DE42,4BB078B66E91AAB2,7E5A7B0DD5431EBC,0000329A918DBE23,27945D9202F01DBB,A8293D8A8DA42371,91BADE26BA61B81F,5290F296D896FB33,EE0A6BBA31E306E5,7AFBF165EBA95450,988BB933851287FB,A79E0C516F88A211,264BC97CF937024C,289ED0E76E53A439,45B30D647E913BA5,00001A4FCA3B6E1D,AD3CE0550B78E486,FE800659F70E08F3,BF3F8F112B079F56,80D3535873CFA776,BC76B74118E434A9,A1B4F876AC3F4C0C,AB3C8AF9D7F83229,2EADA6A4A9EB9E05,8116470C56217CE5,46E6A238DDEA6A07,B888730380F1E921,00004A83D5B1D753,EFCED646A9D5391D,1079B1657F968E16,EC1DFF306A7078B4,C349094C529187B2,86778614F9D88A45,915FD1AA1417AA1E,07F9709293B8C89C,D6A52F6C8A8325C0,334A3AB4C4BB0F6C,F4A1221956F4C125,1744718375D665E4,00003EAEA15C8931,7C4BFB4AFDDC122F,8C9424F7ED367811,8F05F85C74B45596,7A69EDD3E71B4BCC,6E04020BA95BCC7C,1ED009B25E6A0809,C020FFB7001D4C5C,991EBBF9481B9622,D9782E9F668A8D35,07CA092E04617073,EB9A63FC9863FB1E,000061A07D8BDEBF,523352DC91CD09B8,91BD26DF2C4A5855,82BECCB647B82354,F035ABD599ADA9BF,FB206AB0F6CA5625,B3C17F226292C9A3,80702984C9B37FE8,56874C613829C69F,8599D5B4BDCBBCF5,9E758FEBCEAC4690,86ED743BF37A3C6B,00000F42BC725BED,6504F351EB2F2E40,901034786BF14AF4,A4940277B666AA5D,3A1E60C81A585992,8E056EFEC198EE64,94ED38B005EBD5F9,2E9825ADDD6B4A6E,392257699C20241F,379061EB444A9E20,BD65C3A964F086DA,512868AE2B1730FA,00002E3121A33D55,8D44452708804055,1A6FBA76B57C5DA1,22A29E18EA7D9803,DDF43B4C25918395,6B2FDE72924EBBBF,8EC4CD96F256BC45,45CDB802059A82A0,95F169EA9BDD6F5E,1A259CACFB516D0F,357726079577D955,132ECF69ADE4C117,0000572611C4913B,BEFA82CB7D1A2F55,56D51F31599F81C6,66ECD6BAFD0B3523,2B60ED25592FA9E0,5C2EAC804A37BE66,CA9EA4C9A3A4B6EE,490C3EAAFBC39F85,6ED31D42E5E2788E,F0CA142C31DF8D24,1DDF79AFFC0D2BD5,E4D94E4F8921F8ED,00004181151CBA5C,69760EE8430A41E2,178FFC0909F259D8,ACA9083F7DA4E07E,F6E94F4014557245,10F7FCDFC50958B5,841C39DF3D657FB1,901476C51BD028D1,78ABC4B4785D7840,22DFFFFAEE3F3442,13E85EF474CFB4F8,6E5CB595B1CC2243,000034E77DB7B80D,8913794733ABEA94,42F9577744285B5F,0FFB6BA46900E292,87E4882E781EFEC0,C6692E6B5AD8E28B,A8F19D38ADC784E1,F48A0295FCF2099F,A5307F5D79C43EFD,F41C73597D50ABDB,566C042D741EA268,46FD6D7DA72FAF0E,00003DE008246844,9A9EE4D64085C070,1AB8458ED5DCA0C6,0BCE6B44327B1F1E,2DA94C707B850757,F15F439279CB0B4C,B9542D353B421346,FB89C95366254401,C5A829BE95F4C140,AFF0D28B74227D0A,7F98CFE819D08F76,9DF9E3DAEBA03B2F,000029EC3B068092,F1CCD5685612FC06,EE45ADAD6768CDBF,164AE7C7ABA21B67,082379D8D203F0DF,87474358EC83FDEE,090570FB9B5930C9,4D57B6D0C954DB68,1A019E448E7EECD8,9E24D8F686D4078B,B15F27DB578A4D2A,C2EFA71071C59015,00004F4EF842376C,BE45DF6B5DAEBA63,766949F5ED0AE41A,E9A73BF2286C92C0,6A168FBCFB3E1675,C8B01F1297CAA2A2,39F9A3557E650532,4C853ED25BC28602,D1C61B48E0A2FF05,A0BB1C6F808F4E5D,2018FC36A347D412,0AFBEC9FA9B93EE4,000041CB612132D6,330B4F56BF0297A6,DA0D12836D9FAB36,A335AC45F3D5F614,39F0B5525DD1A655,8A67EBBF03C2026E,4BC975448F363DB9,BFEAA0281C2FD05C,95492BFB35F3F704,6F1D2AB4B0747045,D39E38A2E209E07B,272CC0EC78FDF4C2,00002ECE2734EA0C,A802FDFE563D3670,7599666133777C44,79CE295A1CA93D04,D4E3B07E4E4CB029,24C89338555DAD97,3C0DF50BA226FA4D,A1CAD698EAD31D74,2B66517157A906C3,3839CE68BFD8EB58,F56881E3C53AAB6B,27FDF970CC8BFEE1,000045AFFAB76E49,64E072EE77576514,FF032DB1B4EF15E6,55D103C05BEA0373,CB4F34482C0570B7,07780FB691CEA304,5C30B1C73EE2C0E0,2E4A53991A0071DC,972595C427BA2EDC,CF4530A3F199B066,AA14A5ABB9A67A8B,C4EAB946B17443A0,00001B15889F4CD3,E2AF5B48CE0241C2,945A4F744EABB01F,B7AAD3D3116C1FC0,859117DD6D38CBB1,1BDB13794E3A9345,EA51E39AC925F6A9,263E22E209446047,5F4090EE8584AEEF,A2BA2BAA12B91855,CB456CA115B26EB3,6055525EB18B243C,00004B1249C0A81F,CAB40173620C3543,F5A27265593B8B06,68E9B7363E638ADD,0488250083DE5B67,D14F60098D39108A,64486421B9147677,9D56F1AE8D14F3A5,34862DFF66D000CE,7088A3E0F445BE0A,C6C49A126ED5A9F0,B251E68A7867ACBD,00006D21AFE83416,51B225B2C1B47D68,F28922210EDE8B8C,B738A36472D621DB,8BA892733B828646,FD438076F151EBCE,12E872B25570CD3C,214E2C4B29A83465,1E6747D59A7D272C,2AE588B04A03E957,7DE1FB72ED7D64D9,29F8B0B73E26151C,0000221A7EFBB130,17D95F68E073C9CC,ED37646881F3D236,A6139F824E4F517C,972818CCD73A9B5B,0B0399D43DBB9541,0A5E1B667C8C96C7,FA3D4B24310A20D4,F6E810638D5C13DA,E759DB4A7AEA8223,51DF19A3AD4E2BD1,B295EED1ED0E9485,000020497B85D48C,F5FE4FEF9F544A56,A9CD2D61A980761A,F7F38BAC1AE851FE,28D6DD3D529B58B6,6D33D2F9B5205FFE,883D892F577F716E,DB6A4240322BA7DA,573E749B101C0681,B61242347DB57341,EA1D4E98C1EBFB65,E83D70F3A76A17E7,000038F5A425193B,A20FF2A271DDF05D,4106471CB624EF3D,0C88F07641EB989C,8AD5E909DF675D40,38A13185C23EABF1,6B9E60B7BFFEA72F,E44AA9BBBDC04E63,06090ABDD9A4D4AA,9F2D602B67AFBC1E,321BDF38B4A18DD0,AFC807BC8A8A3131,000005E9B23B3D56,45E4D0354A3A4DE4,675FE2858C9A2278,EB80E9F385B546CA,6C5F9CAD6A818AB5,8E663808885017D3,6832480B9437D9DF,5BEB4E0E33AA93E3,60941CACD7D34372,D3A1DD177344F104,7BB9C2E8A010ADF4,1AA27735D72E2B3E,00004B96B317ABF8,E29541B2B8CD22A5,1EF1BD67F1B6EBD4,124ADA89DE79B22C,7A3F86040ECB247C,5A02EA5A84D73065,549B0AA527C1BBE8,898144C30C321787,111C624DC929E41E,B1C6F25827B9FCB2,C240C778C2282661,E9ECFC3746FB4F02,00005FE42175BEB8,302E1AC00BEDE3F7,4E359356C57CCF2D,8AE9AB48D097CA71,8A6D364F582452AE,52A0D39FD1132FF3,D4E49EFFBDFDC257,155AAAE53478B550,914DA3F4F3446CE6,2A8FB64E887FBCA5,8C1765137974CD52,40D7C133070CDBBE,00004CE13C4E08BA,82149D5A8499D117,467970E23DAE518E,9367834FCE85F14F,5557CF6D518FB29D,6D15C3020E4C4AA9,70FB734CE718520C,2FF36245D2F128D7,733A0C072482B864,C6B1C82383619F4A,DE05FEA96A3F7F39,D9F7724FD50BD25B,00001AA40D4FBB6A,7FA4F694EC305EB9,CE0BA1674F16A3D3,761D4FFED0872593,76F939D88D0A31B9,3609EF183D7C70D5,B57F7DB5F5E8EA0F,1FC3D3C15B767F7B,B1ADA3954AE78C99,A61C3AE0F1851747,63C5CC1D8053F80E,77648A4AA9A01EE7,00000E9E7E2A04BB,2269C2A9EE7B05EF,1855DECAEF9679C0,9CDB9BC670BEA782,01038911D5E3EEEE,73A81735FA4077A2,6FABBF39F6F2E6CE,F108887E2039B3B8,C61CEDC40136E255,3DF7F4D9CC6E1D49,90CBEDA80E158C58,12F7F117106FA6F7,000044E39ECA596B,7C7A0AB6FC43248D,A1117D6E89A03525,9BD8604291ECF3BD,D2C4F4B07B213BC4,1084C1087F50BF08,63753870F7718C94,30E261DAF94F20D1,660D85FE8D536170,CA5D814897539952,0B81B1132D210F37,644F448E95C44714,00005F296773E080,AF31E3805AC44C22,D723A7CC88C5A03C,BD4DFCBDEA471A2B,18B763DA9E152A57,738FF17C2747628F,3AAFE1E02D889F59,155B93A11524F213,F7E24347AC05FE3F,CB4D0BD2F70CEBD5,9D78EAC02E40BD18,001C06978AAE9C3B,00002782DB02E616,99290868E087433A,81E419FFDC353575,0C94FDB839F4C393,A989F21B8CAD6F4B,E2A3B2733557DD0B,879F276F3DD0A63E,23F670E8EB485523,75BC9374F5B05618,9DD54CBF45E9F28E,D8B7F41F29358A91,9D4DEC7841B0F8DE,00001456CD77F50A,FD629520B496B181,E071498CE06DC440,A16D702B04603C22,420FE52C732693D6,3409101CF068E769,911B8E70529B5330,E06769D26AA04624,BB9BA53C555CE5E9,FE8AC9F2D48CFDD4,22B8CE9D616030AA,544E6AA208C7CA16,0000245CA6E99F29,BDBBCFA36F02A800,53209DB988B36F19,BF123299DD8D4FA3,2009B77D5319B359,5D7EEC7DF2EBD904,3B60F4770644F653,FFD2FED12A3B88EF,F0E52AFBA84BD65E,82C0DA35487770CD,B59588E9CA1B1D5E,02FDF443AE2420F4,00002F7A121B1DEA,6E50BE85E8FC8FA6,CC89B7B9C9740A2D,B8219905855C3ACC,22751D55E41041CA,15698EADED3998D7,7EC6C0D73C2C3F3E,15B6323DC50F14D2,3C3D372C5E556C3A,9037ABF18775F5EC,3F05482B786E62BD,A1429FE8A3A4AFF9,0000245F694D58AF,C22E345B7EAAE790,DF922071988592C6,4428190E98362571,DE8BAF2176BEE188,AB1C318C3E5F8699,6D8526833E90432E,589312813D04509B,7296D435742BA000,A1BAD32B04A6BE0B,39AEB473AE4DA4A3,43FE024C5B98D025,000039D925C5ED9E,19B8AE66D873E12D,C08D58FC550F9656,DF43456A8A919414,D9B5D1E2550B5484,0D4D96193C25E810,73A5F57CE5C2C48A,F68F4B3B46B32196,9E3B0CA3FB1BFFB5,8B09813229D78E23,1C87A7EB8802509A,47E38B541550CFA9,00000850E207FF88,B4065CD6A0506832,53943A83A82BEF8D,B277DF587F59ADEA,842A452ACE2BF598,5ACF276E96E652B4,92E4CB6653D76FD8,AF882D43667A8C44,48F00E54D3BEFAE6,44C9C325210C65E9,C5852E12A5A63D4C,F8F8CED1394169EE,000048039616D075,38F0DDB523DFE08D,D333C6B8239D9E6C,581F83084C13CE35,62395A89E962A97A,3066FD851E356FA4,8909A3BF9C8C5C1C,8473D93EED2DF7A7,9BFE29A1334C84F6,0BC27750BF030EC1,2484E642A95774B1,C1E66EE2CC758429,00006AEC5679A40E,FBC78AA130486354,479148B802944B90,29B00148BC4BE3A1,FD8C761B5932CF9D,273D5FB25AB4937F,3AF45F36322642A4,0482A2C1F3ACEB6C,7283DEA642327A02,2980FE62089BA3F2,EF8DA20998ED9F46,78AE3777A76E1E4E,00000EAFF2D429F2,48D26B719339AFA5,6B59CEDACB9AF693,B38B2FC468324ADF,E739373FFFA0E33A,4F7C82D44C5464B9,20455FDFA4E2F147,4B7B190917B39A3A,C55369FD2062006E,3957C1C3CEED3068,AA61363D1560C7D1,1B09C599CC6546CC,00001780865F911C,5D2E2A8B8F336DD5,968D5896BFFAB4FB,32328C413B88B153,8D43C4AF1CD01170,40B3DB470875F0D9,DF482B8799F06EB0,395172733BD32E43,37677F0E59A4053C,D989FAACF61AC1EA,5AFEAFBAB346B7A8,32BA7F939BF98184,000021849D184F14,660A481B667347FC,ACB793C32BEDD2A7,613B51F2974B44E5,6A876B744D0CFFAF,DBC7025192B15FF1,6C74ADEC8C5AC67A,F5B5DDEA6AFCB7E5,BE37E04F8FEA5153,9CA3F5133AE5A490,EC03F39C8480DC07,46407D104CB74ACD,0000581863C5D044,FB3B6D845F01A4FE,92454DA530C6E033,A7F4E769DC8C5425,C7F06478DFB6513F,35D3655687C6B013,BB783990AFDBF991,D3BB6B206B8F9AEA,775C6EF4B1C0F3B2,F5226B8349E0EF87,53A190C6E5C72401,D7DBB65E46D3415D,00006D8EA3BA6768,F816F25335D84318,D0A0BC56DA70FF90,5A3E2847408FB0CD,67CED12E4A6A082B,32A328187341DF96,ED485086ADD1A359,F17F2E1CE668EF1F,665186D24E0973DD,CCD4231A412BFB69,B264AC5ADEEEF37C,A394F1F7192171E2,000016B3AFF4EA95,2587311C0756E6B2,27F9DF3C25A0FA31,76C1CB57EB617430,3CB0820A921885B1,23A407D4C069E58A,1ABE0D557E335A61,24323CBA876E1740,6759CDE52C1EF5DB,5BA88C2FBAD80CE2,7D479B7FA872B95E,4D8A97BC89D53746,00004846170039FE,62E35891B9CBA76F,B8C5A8A365192591,4FF9E0C362039B9F,AAC7EDAA645B3E9B,AED8CADD13E5422B,8A64E4840F87D497,8969946EFDDCABF5,D10297C7327FACE0,F30265D865AFA844,021382BBA1BECCA2,6E74462CB217E606,00004658B460E2CC,1A3263D0ED1F65C6,0F4E68D17E6E9A56,F8327E34B7D34645,82425240CD6B1450,04526E4C23224994,22FBA5EFECE418D2,4E889CC87E2B3C86,F6A775FCCFE8AC8E,C43B81710EF89FCB,BADF4BBA78BA2E57,993CFEF15A519DF6,000037B39D3DD531,3D08C7FF0FF6EC1B,F2F67F05CDA5B931,E30EDCCCA6AE235E,A21FD84245EFD1BE,83826A8B41B00FD3,1A689A82B1D3F9DA,EADCACEC7D1E8A23,C0D13DA6ADE2D884,ACBFF74FD39EA1C1,6630D535DFD4961C,A6139CFED8E2A949,000033E747D29939,22219CF04EF38E93,BD3A6352F78D2BCD,663C1EDCFA7DF3AD,D53136C2A02E9FA7,5D5BDB199CEA60C7,D151871F820A14FB,417C7B07B1734D1C,D5C73CAB9E681641,249FC4D69C4B2B04,AEBC2D44173085DA,93D40824F9C91A6B,00002D6E0DE784B1,465011650B9F056F,6AE15A032CF24876,FD41B303D49E4D2A,911768147E3763C6,9B43E97C6DB40C90,B9FEF4F5A7E02973,C625FD55BFEE4B3A,E528701341074084,3E9B9896095E3599,01D612D949376C26,63CD622B5ABE9FAD,00006A9817F1FB43,33547F8D071B53AD,E3B9D77867B830C0,989DE3DD34F56CF7,E3E0FD0E0BA2C54D,3458B9D07C1FFBE7,AFF00524C475C83F,56A8C05381BA7063,A422D6026B6D29E3,0FE3976101F0D0B6,4D400E92D4FE4D5D,9C62C14FDEC56CFF,000033FF562A8CDD,3EA35A4853F24438,4502072BF3AE7C75,482089A8AE655E8B,0F46771DC820E0ED,F9BE381F0DC5C342,CBB6B580076875A5,32D9FBB2504E83A4,11F5A6DE1EBAFE67,2BC07D3B192FDEBF,02FEA13F78B044B0,2172112148A8194B,000059F8FB585230,6733243CF7555118,AB87D0D67A8DC27F,F6E95207CB5EBE89,934052A6F8610823,4A8D876F4CF3185B,A5F1712653906520,3970CB0CE8986D0D,4E304EAFDCDF0E84,5431BDCFB3CA280C,1EBA9D66D2574D5F,9A00E2ADD00F1EA0,00000A45467302EC,C70B8A6AC7B358B9,3B71DCD9C1A9D332,26C9F938C1E07B25,0B74F59265549CD4,2795A4F0D48444C2,09989DC27F035D9A,16CEC3EEEF47F80A,1F147FE8AECC3FBF,1D2026035328089D,C99FC14B5F977142,A6E20E1A31FBF615,000003DBA71C8237,6996E90D99EBC82B,C8F55FB3FBE5C9D4,CE1169EFFF37C3DB,E7DDB0BD621965F0,06B7E7C92644A7C9,5E671E14945AC116,AA3DAD3C4EBA75E1,66DE72EE6BE5F02E,B1066E4CD4EEDB45,58572169C61797CC,C1117982D4526016,00006BCB9260BD37,96A1E65513814F5E,65B809F217EF158D,383BFCF4ABDAFE47,A16A60A15A9ED407,CB79625F47A13FBF,1A2A83A4E1E58E1E,8443C2D44D915992,3D8C2FF83872F1DE,FECEC01CC3170063,56981E539FE1F647,89F8F587AD6DA876,0000181B04933A49,9D8B8A8F17556E29,ECC02A811C02D2BD,C43244D66D679276,384751766D25422C,94799419EEF1D758,FB5B3CB1FFBC700F,4C6CF6A2BC511A54,D9390F681441D93B,0CD7A1976E20CA5B,C49C70E30537C6B8,9676AA3B33FC037A,000067FD84CD5071,837E77D76E531706,8C2ED743A83FC1B0,7A9E69FBC921FA2C,96D319B983DC7EF7,FC57A4C76FB664DB,4BDBF14AC8AE5167,706FA43B5581D462,4FF0F285F96A0F5C,7203E554CF374EF6,807478FB393922D3,C8E21711D1F8C485,0000111EC94536DD,198515375D02DEE8,3EA533A10A16A5A4,11A07F466AF15916,E452BC8C63C5EBAE,2F1C1CC07C3BDEC1,26CD052C098560E9,CDE0C8EBE58F74E7,A86556CFDCC5349B,5321F5AD7C341A5B,B230D9EE3A8FD567,66619761B1092806,000060603DF4FB8C,D4D48AA928A778BA,3518FE569DC80284,71FF7530E9D1A1B2,CD440216F69FB0FE,36654E8544BF13A7,DBB4E787A0CDCB31,3F24E06C46163F3D,55571F90BCF13773,2242A46B2230ACCB,5426A8CAE1416EFD,46B83BA37343AF93,0000190C93E457D7,C624F25334C3E83E,E073D40B5A963B3D,DF186C30832FF279,84A4AF4E2D27306E,C6C49A3066DCB3D5,EA6BC7710CB07015,ABFA6E9A306DBCF6,81F45F9789DC506D,97FAAC97C72B18E7,9761BF18D8BF6D07,03DDF3092BFBCE91,00003AC225304A50,74E6A90124A96E8E,434354DCABE87255,41E68D0F10CDB257,CC2DAB7A3ED636BB,003F5BD77EEB5437,B9AFF3A2112A264B,EFC4B1D33C86F485,1AAE2774CF3CFFE9,C18CF4AB8940054E,DD34210931344FDD,2B50C672C8979AC6,0000400CE6DB74C4,577409B083BA6252,CE289893F4252C7B,3F9EB721B7D80030,EDE07AE1EA39DDD2,03DB6CFE6621F00B,94484DF6F39B17D7,12C9932F5D5A4F81,814DBD4CCCB81C45,CF8AD9431C4228D5,2DFCE70B6CB8DFD0,D327516EFDD17F1F,00005DADFBDFA56B,02ED579975F8C884,CDDFEEB7E5F57864,033EA7B3562C6F61,5192692229580D2C,A38F8015C46A8902,05DCE161FDCC3F11,A502E207B7EDDF50,9DE4C076A28BF0D3,C058B4F82F1C13FC,7CBC14BECF08690D,813E1D51BCD7C2EC,0000257A81E9ACB5,3FB7B3F303AE0EE1,17719BC15267966E,F263DF16202F03A4,C0A17CDD43F8DE7F,0273199E2828658B,0F2AF5981707FCCE,5CEFE4A10FD579F1,CFA14456A856E0F8,B639847A3D2708CD,1099A662BF09E608,29ACB424B6D7E361,00001F6F4A5EF1B9,E73DB3C155740A73,12678062FFDA6AB2,2CA66D7E14F2E50C,0E9B09442D522273,6F93AA06D2FDD05A,A7C8D51EA72A9C7E,D84D73EBBEE18DC3,414D28579155F028,4552D5AD63366310,870FF7DF58222E44,3565C05BDAE8F4B4,00002ED6CBFFA929,D05362B18A190260,7832349EA24D7C0C,F0C0183A2B93A9A4,393295668CB7310F,AD181366B3820F88,62F088A02C7C8135,884CB3E705D3A526,D17BE0473E246385,FB67CC5CC2EE6961,04FD693936016536,B73ACAD9B51B1C23,00004F92A24E25DF,9EEB996FFC34BB0B,3CB8BADBD007ED24,298CE495C50B7174,AE6B0259AAE4A9E3,53690FCD05A109F4,137E2F951B890D3B,57F6E03A66493729,678E42610C118D2C,18C84953F499357F,694D3A9633B4AD16,9DE7643E28498882,00006CA8234898DA,C2AF020079A2315E,0389F9F83D6343AB,0EC020E1A0328828,02807030C69FAA4E,5607A295B93BC11F,653FEBDB1FC2661C,B219BD049E8726B7,C9C9E89D7C305A76,D2B68B935234A11A,0EAAF13F8C57AC18,2993F44C3E4500F3,0000263C0949CD6B,71988E28BA0EFBF2,842189B73699B20A,CF6846692F04BADB,9AB02C208EAF8CB3,303231F9FBEE84B3,AACD8ECA94EE3ED8,6E96811EFE093C0C,04434795573F72F8,71A0FC6B1123B4EF,7AB764DDC5535DFC,B830527BD6EDA448,000023276F94B8DF,B6713B526ACD478F,CFCCF719FD36526A,318454A4FC8456F7,E96F04AFD208F36C,546EF3E5EE0D5832,AEC33C14D1E42382,1A327ED3DA3953C5,7D3412A5B940BC5A,93056A222397012C,D3BA56B9C3F596DA,6DE07B7B1C39DAF9,0000667F5295B128,3BCF8AF51FD504C5,CFD1A031C1E741A6,889B42210CE393E7,AC548F4E1971CCD5,10E085AEF62073E4,FB0A4CD2751D3D8F,F439F75C447D1D04,1E47412AE3FD2E61,F6BAFE8E846760C6,16E0E1C90C8791EF,2C65D507594C70E7,00003D40996C2843,3C7688156AEB2C2A,1C98AC3F202FE5EF,28B3F78DD56A780B,C3BF3613EBF36560,75BAEE276B16B654,DAA1F54B1CEE58CA,A2E4DE114191B4C3,ACF16C12732F3E50,E88C8A0CBF34D85B,63C40E703BFEED86,89DCCF75E40010F1,000020665B005E73,19029E91112E8CC1,B5AB0D810B8B2A5E,4D59D7150E91A21D,7F69C6A57AEDA63A,041A5E32986ECD23,E0EA4ABBAB3A8009,A2FC60FEE2A55495,7D78A4B039C53B61,577597D54F02F958,6261B143F435E72F,2563B7AEC77193A5,000017FC3F8E76A7,9029D384A9A487F1,EF10B27F93916F91,19463439B0C90450,ABB948CF0D639463,2FA7B73683B27F43,7B02F42B7537591A,AF04EA080983B4AC,7EEE736B63D331DD,F427C319F0B4CF82,7D8DE953303F8F89,20342A403C191E78,0000233058B03CAC,3DEBA2123AD2CC1A,72CFDE741F734BFC,65C5192F67FEA72F,4AB6E5CCB96A1E51,C954E4B42E366C38,50FA6973C08167BB,06EC2759B20C100C,EB20C93A218F0758,7F85F87224540658,D9B42663560A146F,67E71170C2EC0196,00000D3DEBF9765F,7973DBA41FF90963,B0CCE99CB79BBA47,684854B5FF9B1446,8FF9D274E8313C6F,E0DD4017B74786B6,95C17582F7020534,E6E917E4C3BC8808,40FDBFE217C7E50E,F18D3FC1F98BCF79,F0C2A6F2C75B638D,6449D0CBA53739E4,0000468B5DE40716,14B8D7B99FC76034,ABF1B29D44C179E1,84A5014F670EB13B,B3A62C6A234F7CF7,E387FB633E2881B3,3B4EEEEC3857FA97,CE31557C8953ABCF,30298B543EF52ECB,47F212D165C68343,9D424575EA3F9279,5376157EFF65D18B,00001DB330CDFC78,7170C17F2A899E55,C71D6410692ACA05,2C0037F5EC749D01,BC2A22D35CB2576F,A3420F2192DC9B35,09FD001DFF997F7C,D21323363EAA9EF1,3F2B9F2C45302F0B,944D468532906824,BA2CB12C945DCBE6,2BB7E4580210F63C,000062E7DC145088,69909EC99D9A24D0,262CA0AB253355D4,1E097BFFEF90FFBF,E73E7F6BD53C9AE6,C626A142CFBE7A78,5ACA1DC54B61E905,B97649D42EF6A221,2E75545E67CC2D96,16C75D8768303546,5FAA610B05771410,16BA8E998E8CE687,000028017C05B54C,14097A0F77FAED8B,2B3FAC8DA18F988D,D61EA587DD484D08,128FFEFB8A2BEEF8,D85F2C454EE005F4,9621B09288524288,DE8A353FE33CF5C0,3391532BE8404880,EAC934BBE6106D5F,663C974BBAFC3D4D,0698F2E7EE900FEA,00004406B5CE5C60,E34C08E75EA5FC59,5446C1530B0E2623,785BDF85F5898FCB,6A2F66403C5AC818,A026FCEFB2A3FD6D,7F8E5656F8DE78CE,05F665CB197BE24B,718ED162EB4DC695,AA16A89EABFFAC8F,B2FC388775035573,B69D9082DF996984,0000090D3087E44B,2DA0F22FDFD0E91A,BF5F0BE14C91A05B,A45D8B79C4FA4B60,93D2DBFD6D3FA442,C6CDF1427058F4D0,E96CC45B99E83E6F,2B4F34B8C00BFB3B,999AC27B1153C2AE,8AD942E77B70C28B,75C369B2715EFB04,B2231616E90B9567,00004B01D65544A6,C4166BF17F9FEFF4,DD1CE9D423B6BD3D,3A5B32C1A1082981,1D72F901DA1517CD,A73E0517B0B04BBC,7FBC20C00DF635F2,E7D812C7DBDFBFAF,7CE9CD42BC1EE4DC,BFEACE3BF7566C80,9913A60F71201582,94A164619D5148E8,00001C30BAB4834D,B7E7D17275511CAB,A990018E2A5FFE41,AAA866911154D663,608C409E2C1FEA4B,EDDD4FE2EF3ED21B,AF182FDB350F6E82,A2982DFBE55D1B10,EEC148DC4AFBDFB1,5F50F0BF7E6E1731,17C640164D064E1B,4146B32E8831F900,00006267F3D42FA7,6BDF52003DD9B06A,B4BDCD071C31B2B2,6729F6ECEC168360,CD00EC1A628726BE,AFC6978477E0648C,18A31A0CA015D03F,2847574D058E2BB2,6DFD8BE3E68B0BFA,DC31E859AFE1DD14,48923402437F3E64,AB1B31620AA732B1,000024F4B484A3B5,6889908EBA90DB5A,0A5F9ED77DE875AB,421CE8134A9893AB,574E90E86B1001C6,31B9C1DDD84EE60F,4B9BD2C28C040869,C3FEE3CD0F9B7047,07716A0EB0DE8E3F,C62E0FAA311C9255,811098928D5D185D,DA675712609A5756,000031C2996EBFF7,4F75CC437FEBC4B4,53AD015EB75DB671,C2AE147C9F51B911,CD60D4E5DEC812AF,2D130639209B38F4,59E4CAD9F4776026,49C46B5CB1763370,1B6C8317261343EF,C91DF1C27232D387,DB9279C2E6B3251C,3638918C6540F211,0000583DAB54F4FF,7362594B0A90C8F0,0AB40ECBE9185BC6,92FF74AFE8564FCF,73A7072190725AF0,60D27BE63AFB799F,7F6E13926FBE4BCC,D3359A304E2F81C9,2E33B8AF475E0701,DD58327639927A52,A4AB83FBC180A887,3D02D44C6FFF5909,00004CFB58C78293,CA97077C206F3723,CBD1870ADD2E5FB1,D5C4AF77EE2C44AD,C14155CB25FFB1CA,8D18FB34DCF4B727,A904F3BC6716FC81,876D30777B9D3AD1,1648179041499C40,2B4677D84BC74A96,425B6C88B45A0DA9,5C8B9278E662A17C,00005D2561E43BCF,B44369C0A0B89D57,17421A88FF463AE9,B5E05DAC6FECE9EA,75736E9FB46E9976,44D5FBDE85EBDB7F,6183FDDDB9D9BCF5,D4E2F04B5278961A,9B6EDFF75259CC3A,D9ACB17F9056A711,42C199A8061D89FE,8AC4A242B8999BF7,0000393F1DF38B09,B41DAB5E0DA0E40C,A03AAD6416916A93,04FA539F52732D9E,8ABCDD5B987C22D1,149ECF52E9537CD5,93301BFFABC96F90,AE23C3E20EA46E22,8A43DE2EA7C5D735,D3799CD4790AE746,2662BD9D0D1DDA50,D7B65A3C18619792,000040692EB6F41A,97F980249DE12E65,5690CDDFD8225CC3,1F04DD321F0FE052,11B93639B0E89F0E,4A6E5CE2955E6A55,0ED58D4075B9CA78,1C87F6488CFF6710,480593975F0C5C3B,AEE36B769E8B94CE,113D20F397438685,63BC8B8305F309D2,00004C61D7B5D345,F4FD820550D99A28,7E67548DAB8011FD,580241E76CA520ED,87F9C3EF3E16EF86,24BC57C36D896CCB,A2BD8850C4E906C3,102EBD4CB5FB54D2,B5A00002F995AA9C,646410F9819B853C,EA71096366273B71,D370D57608570B79,0000132C6F7302CC,64E010EE245B1312,3B42EC529E2197EE,ED9E897B11E42A85,FB47196E7B113433,C804459522E47A92,724C67C423E4CE0C,42FCB538D076DC99,A770578EB7B9C6FE,C3897E0D76D66E7F,B99BE5CCAAB17F07,8D3605050CDEBA23,00004B6E6C33DD60,3D36C727EA810BA0,EF6CD07B901E89F8,87A793143CCDE480,40717A45CF16D535,55744A85C7BEBF48,045F5935919D016F,B3D5F400BFEB1798,2C91536EF9E8474B,A3FE454D1B80C3CA,DF817C2545EEC75C,6319F63879EF212F,00006801CE8F48F3,E10A57DFA72A2E90,A34AE48586874660,C77A47B5064831D1,67E748F9227A1F0F,D1FDC7D643A8FAF8,0733932194380719,371599561AE92285,B7B56A5ABDBD2B9E,F2AA11CB780B5C3F,23D4800CCC46BCFC,467A9BAE9A1B0222,00000C432F4CE2A2,9435759A051C57FD,9689295B300E4F32,B92CB128ECFA12E0,14CDD6ABFEB696FC,98B98817CE671B9B,5EFE6C49855F200D,4179B3FCCFFD3FF6,2F4BDFCB0AEE4D97,2586A159B20E65EF,19DBE4395C669E55,798B534EEB54EA65,00006858D2E59C6F,20DE18A970E20D21,8CE52A81C57DEFC0,75A65F117669E1FF,E606CB2E3DFCC265,90087A82E8BD05D3,CC4AAD35703D0D55,03862081FE151410,C53AABC6DA1A1466,0839B44ACF7513FB,75F5C31707478C54,EEB325466A5EFA97,00004E0E43BA8379,9916DDDD9586B8C5,BCB5D8A1D1C0728E,4DCB000425FC75E2,FA0C3BF57EC19FF2,A28E6937C56C5620,360748B6219212ED,43BF361BA60D0D62,6380F065D5BEA452,F44906B430F67FD6,ABDC244BC778C235,A77BCC94DB36AA5E,00002D54F52EFDB6,6DAF95FE79981425,9EC740A53C875DBD,38EAB1A75F2B440C,32BD2C31EDDFEB57,36CA0FCA6E52A02A,978405B4AF99F03E,C6BECA3A55A0A0C7,7703920C5C53479B,1E99F26AA0F64370,6DAEFC519E84E5CB,A19553F97708D994,00003C5C729935F4,61F29C7FF3F23EBF,D6054F67F9A3E9A7,BFC872BC1B9B84D0,50A0849BC5A2DF26,4610163CCF887D55,4262421E03048946,A7F8DE80658EB180,4213DC04ABBD5E47,8341FE20FE47556B,17146A9F9C1F7739,4F08ABD9B979E276,000006F4D22F5FBD,7476017033831CD0,1B5BA6DD931150FE,A577FD898A776A53,460AEDEA524CE7B7,23FB01EC3B64D056,BD6A01BFC833C43B,0F6B17F931EFAE3F,3C1F56CCEC7D93B2,0C4667448E733671,ECD2DD080DC18D5C,A728C7AD5C197D57,00005839B57D661E,E6C33CAC7BC9952D,9EB06BA5F3DE051B,92BA454985DB7237,C97C79B0E3235BBE,EB5E15F08CF3417C,B65C24ECEC020B30,C34E3EA09B5407F1,90F0C105CBF8A833,BF0EEE65D6025626,57867A437435EE3B,83657A703C7F98A5,000038CE27F167D3,5AA64B532F03AF79,12D928A99498CB64,3F9A428BB6293D09,FE3F67E2883B7E98,8D22A062A3F8EED9,8EB8218EF82C8C7C,733B5E688392E10E,9B7286D91D9E5E5D,EB9640D6D301B571,DCCB56D00396F346,782834B58C3F2E09,00006022853528B9,AE268976B05736C1,0C0826F5FF44C9B6,853E110B3365AF01,8B0D7F2627FC35CE,AE2646DF30A92841,202410BC5A34A8A0,2858C864C63F9A6A,1FDA3C7F1EF2F4D4,FFD257C4FEAAF599,2AC005E64B6EEB2C,1C8F8040E6F8CB87,00000DE940C0631B,26AB298097632750,2DB7F0081280E67F,6884B9D8120FAFC6,E5BB84C40249F2E1,DEE2F8BABFA5F5E4,F6EB072203A784B6,6B01AEEB23EB8377,9354C9861B64F529,D3374F22DF1F55E4,DC411A3A1238C0AE,61920198DCA17756,000029647EA60588,98F67B689CB39DC6,CE0874DD7A85983F,31711DF637CC9D0A,BFC9FF868B574E3F,88C083F4498EF89D,4D18FF825ED406C3,BC685BE8A74CF512,DA1CDD196916FEAE,0C851A4EE98B69DC,DF10DF542A9D6685,9FBA9F81485C00BA,0000481E6ED2C26E,0627D2D8A7D7E876,AD098C885951FFF7,80D30D70776C9F92,EA43AB0D0FB03153,5B1E443318A8DE2B,C5D5CD96EE7E17A3,CDC07EAB0228DC28,0736067FD459CEDA,C4F25CF677F2163F,CB824297FBCF18CD,3C57EB33BB7E0500,00000D4BD6741006,4F72BB57C8E5B2D3,4EE5FF60D3448F17,714EDA36118F7685,D54C479D974F26A0,C5B83DBCB9EE2DA2,92271194DD39ED89,BFB5B7978CEED372,CFDAA66A6546F5D1,3C00556DABBE61C8,74865AAD1EC74551,62C377C7D0F4B965,00006D0A568950A7,BBA75EF44C1EE015,EE408CDBC5DB54ED,DA26BA2BF747293A,0459BCEFC83682C5,078B188DE890CA50,514D3FB0F012235C,A462330EC3C3521C,A9FEFB2CAC3B4D26,F2A8B908D60CE4FF,BCEA2E1AC7673BAC,58A59ACCD6C6BBB1,000067F7E3F1ADC4,1FDABDD7F8A61082,0CBA6404F8835E7D,5A77642CC09E305B,34F834D0EDD37732,9946A440FF23AA73,964681B78451B6B6,F3B83A5F51CC9F26,ECD0EB78803C1F78,54B630CC08000D28,039C4310C85FE203,1CBF09F1E286EB08,000047AC1BEC0185,4DF3CEEC878A5F13,7997DAEFA8996DF4,A9AE6E4A12EDA383,DF6A544820C226F4,7DFEC6213424DC86,E48C004123435D6A,52A12B437856D8F8,A00866B7614929AB,1C09F9EEB7415934,1E0F78154C21373D,3FD4C79CB11DEE01,00001177A0994BEC,578E554D2D91ABAF,3903079E4ACDCA78,70550F09F1F2B726,50DF0FCE726B9D41,EE9C420A8E9297E5,A85FBB28F9C0A7BC,A71C5E325E547BC9,7FCEB5B5F85DF441,601FE429229D90DC,22E7FE275CD7518E,7C7108F2953C7284,00002966BE38CCCD,641D7B5E5C25DC10,4EF1AC640CF86210,F69786EF34242F2B,18B7AEA2F13E995B,13692BEDD310962B,82E8A95FB5835E6B,C6055631695737CC,39E24033613A04B9,61EE64521ADE8D4A,669887F970007577,603401E9D12BC119,00005EFC0C039B7B,6890503ABB39884D,B61CF8A6FBA03F36,2D64845F23308537,5C9889FF821A5768,D7354D020B55E98E,3FA393388B9C1488,FA4DE5AC5F8AE0E0,3017DDAE121F5C51,6577004747748E83,D3AB123331C7DB85,24414E946968B7AC,00006A31FCBEC88C,2073DA773AF7155B,06720204834F38C8,8011B50C87E4F4FB,457A352720844F30,84C9C772CCE753BE,832AE0009B57A6E6,E0029DCEFCAD1EFC,24021ECC71033F08,EE740D2E9A90CC7C,B46FCFB98069E38E,E278FD75EFEE0D1A,0000024B4D99B8DA,1EBB4B851CDD0C19,4FC99F64FD4166F0,6B2A14543221E2A0,EF8320405157311E,DC75DEF30D642E55,DE5631263D951FC8,F359C2A3FE05665E,65FBB505F4939195,0D7F268CBB7F943F,0BF5CE11733AB9B4,DAE8F41DEFC3AFA1,000020D32B2B8201,B655B1B1CF612317,69C9D14BA703A4CC,FC56FC6976B02A76,7A059F37F3EC8B03,EACE607F38536469,70C5F3E0913A430A,73060AE9F439A75D,A3286DDF86E96EE1,2FCB0705A4FA18C8,90527F5C7EC7B0C4,0E1BBA30D54C1FEB,0000122C3BDFFD92,696C87804538402C,CB0CF548F8A2E609,32D418C431E03732,D79FFDB074226866,FAB0A6431AE1BA35,4B52CD162E6BDDB7,AB0819DCBDEF9F0C,1D737C1F6C8698C9,ABA012FBE6CA79E0,6C082699916A6008,E0E88344C5719F37,00004074FA9FA03D,6E4ABBDCB0BEBA3F,DFA645E0EE043032,43AAEA373EEFA8AC,28CB98CC4BEAFEB3,8A4C15695C2978DA,8A994E75F4103939,5E87413AB9194541,D912C8E9CA15521C,063FAC837B9D1D4D,8F0BCD059C5E2042,22F7E5034196C146,00006607811BE69D,DE6E6B20940F42CB,66C2A80628E228D3,F04F9DA12D8C90FA,289EA043772227A5,B6385491EB09A762,149D283DD0712226,E7193B62F39E5DF2,60005B296432D6DE,23E75DF728411FD4,F8C58CB99F276131,DDD46A733CDE8DFC,00002A7B666D7BC4,6FFF18976A026789,57576C9C241723C5,FD3D1698D2FA71CA,90B56DCE16C7B4FC,ED15CA4C10582D76,1BA8127C56CECF64,C7B888F09B4D8CA2,980D56F07EC13932,D873FFFB0A890B23,B37307063BF41478,E7BE5229F220D92F,000030CAA04CCEE5,46F82C534C073BF5,40976DE975612FB9,23CA2953267E4F70,537A4D7ABA0F49E5,F7D69FCBE5DBEE3A,704E73CFBA9DFEE3,CD6EB2A41436C819,8F26474CD4732254,12CCAA33983CC99D,1A69B9AC1FD15263,FF7B1963B2428CAE,0000405300117FEF,487F4AF5DB77F289,AAB763A91F4F4211,248D9FCDCD7307AA,23166B7674CAACFA,C1B6916CEDC1628B,6121C3EBCF5147AB,CDD4EE4BC6F8F012,5C7B909A9D5691D2,B9636DA65A44C7FA,921C747D9984E6C5,53E14EF0C5322526,0000548C667225C4,23BB737483BA851A,A8927D498DEEC186,E42F52D7DBD3ABE1,B142777D0C9BBC65,BCB6084895D6D40B,33F0BA6F455C0D87,B3E8FED9B7376193,86A161A86D807745,8F97114181717571,0ADB0DC3CA70017C,44DB5D688E6A4969,00004FD6E159E98D,311E9A4088295F57,4A7D204BC8B58531,18C76BDD407ECBDC,9BB5DAE68FA93B15,43A9D43343028DEB,1254E2F78913142E,C5624CF1EB324B67,26392BB7658E7E79,2A85260D4A64DE54,8AA19AD72441FCB2,94CDE4D6C6D9D3DA,000047E02CC29252,9A9DD61BCB727540,488F883A2657A3EA,164E7C0959C6C61C,063E33CDE807CB2C,5AEBE911111D18AC,AB5FB60A68450328,14C68BC36C947844,4C3091D4E0A8B3A8,771B0B8CBAB60D2C,E91461A44337D21D,15B12BD4833D8D50,000042F03BC6DEF0,9FC1295D3937018E,F96C6A7D0ECDD93F,E946248E765679EC,B4DE062A0766725A,C14D510CA1F74E89,A06DE2CC45DEA247,2AA82FDD45A6AAF4,26C0953BF3C42CF3,1870F07147A6D9FE,B3701A5599CEEDE8,4C5B9B61FF00F348,000055E904F4330D,B6B3E9967D8304F8,519569DA720545F3,41EB497EA523976E,5114DB58E4FF7B0B,4542DC81647C9A93,C4CC034D0AE204A7,FB98724CC6CE5D66,FE4E5100791D280B,520C4C032E4760E1,17FFDA44AC9E784E,E1E7C2FCFC8DA2F5,00001B185106A814,5DAB1AA6911F5B7B,0153EC171DA67B74,3B17630B1858C154,9D0A2DD55505689F,8BDEB0A17A836292,855F7F006C4042D2,808B050A35CCE689,556DFCE79D98B9AC,A8D5C54898673D4B,E1F4823A4A83F8F0,F94BCAAAE2C46D11,000044827E52E3E2,A03572103F0781DA,954B569C7426A47C,E0B176D790A499B4,5554829CC367E92B,4107DE07CB13C210,8E790F5A2C8A897C,726BA50852D691EF,BF7D771FB093EBF1,AD7BCA34B5101E98,4B16AE759F8D0F88,65A9D814D8B9329B,000038F18986BDF4,5318993549F26427,00240DBB4BB13658,F7D290FB9545C974,127C6E1622D5B6E0,DB877561C887EC1E,88E35D600AEC86AE,03CE5F5E0DDB7490,87C2F67EABC010AE,BAB1FE692561A14A,00D3BC0CED0ACAE0,6E015DF49B0C1A9F,00003AA4F2813057,3EED30E813BD4C64,5D25134C4A5FC798,A7F737FC475CAD04,1BA7BD03F0571674,BD9845B78DAECCFE,8B43D9526DB17BE9,F75042601E5E27FA,AE70C177D7D1F82B,D26635FC051DF191,A8518A51DCD9AD60,DB14269C7F240D65,0000492E66B6059E,5918B1F188544303,FFFFD7391E263996,C2B4C0AD075FAD5B,FFF697BC75A2E84F,EED74F7660ADA9D9,22E2E7B66770C8D9,B9DAB3CA869E51F7,353BB42FE85C4A7E,F5BDE94AF2C01AD5,9F3A9CA789192CB6,037027AD5F0B069C,00000DB4177AB0A0,F2BD5573E6425DE0,C95AA5AD6D54438B,D1B3214A6A53E21B,52911864684FBBCC,504795E06CF61869,BCEF968D8E54A660,8D7BF7DA4D49DDC5,2BF971CBAACD6231,24E0843C3EA26BF1,64BF7B2FE6B616A6,DCC751175EE7C249,0000140D613DD8BD,6642A8903F125963,59D4054795472D99,82A4F47A7EB88607,34D4809C7BD976F1,A158581C04254BA9,D132C6C6F9755B39,8626E051824D28A0,4B89EE9AA9B08DB8,459E17E292A3D4AB,BAB6C985A6DD12AA,85E25B69486C8BAC,0000245B5295F70D,607E5B8FA7AD7F08,56067F0C8DFF5120,6B6CD8D4EE6706AC,D17710C857FA133B,E8F8A85BD0ADCE4A,7790DA45EE8A4732,78BD540E00A1210C,C809214549543164,C635C92BDAB89C05,35003139D90223F9,A570DE131B982DE6,000039BE8FC9FA32,58967AA1556DD281,A7BD214DE70DF741,52BFBC5820946902,CAB21FA0080831EE,5E679893B06B68A7,7A980942FBAA979D,32172E25916DBA58,7D2C6AC35CE85FE6,6C93C1BE69F8B0CA,AE7E4D91A270D361,6B18BAC95C14E5B8,0000523AC3CD97E9,CF962266F9665F4F,16392AA404CD5A80,F9BDCF51B20550B0,A8710E642D11BA2A,BB910B0D6F5FCD91,ACB061A4702DDB04,30A27CB82FEC6330,7DA53A40683000DF,F5C7413AF011E831,50C7AF79F573CE54,CC97F782EE61B07B,00002F0A5FB60FDB,E864DC90A79FB9C6,DA4876B13CE9FA19,A8C170696D3D5EE1,808044F42F3D0B55,3909EC842626DE47,CDBAA4A6FB98E1EE,1EA279610DE72BB5,8D88D46E6F08C1D1,1BFCFE71C72FBE7C,0A80B62861DD14B3,AAC8F1C1D1A5C816,000017D3E19F11EC,5674CF62F018C10E,FE7E62767D6415EF,E8B6A06F5D791F1C,64DDE0A3E496E1C7,FD8057C0D5D8BB63,8DED40F3ABE2B0C8,4D8E905406198432,8C6A9D2FD9AC6F7A,60CEE7BA1BA9EDDB,BA04E287963A8A3E,A2FA55734D7D35C1,0000680BB6A20E4A,9B36FA9396284210,29AD29E8CD39F3F5,BA324B16975494F8,E004E1CAAC88242F,1DC78EE8B0D97ABC,2DF0B29E53CDCB55,89A05063A8B1BCE8,D754B49E5CF8F2B3,00881B022C76985A,F7DF1FCD61EE93F0,FFEF07C8998CD8C4,00002E3EC05632B2,CF66118C3A790733,1E0E3291C7B7610D,22C64ECFAF6145DF,079B0A3E07778693,CD887191FF3315EA,C4196F43ABF035B5,EE9143F70068E7CB,3D91E63D24827499,66A832B5C26DFB6E,79835C6DE30B4BC1,343D04EC7A651ACC,0000199F92775519,DE66EDFDF64EAD6F,4093CEC5E89CB237,3E6BEF973F70F6AF,8B7AC294515367BF,02CE78D71044B818,493B50C2187C67EB,7C4A1558DB9185B1,661105B1D2220E10,AB867FC0B2392706,B37BB20F22F2A9DF,0484C2B00A6CB98A,0000109CD6E0074C,C0550279BBC2F1B8,CC0A68E3D3CDC537,1CB6949AB952F166,8643D27B80A7CE62,C38A1D4716142481,52070D87D6173D72,FF16BC0F0EBB93F9,C8137E36BABB04B9,B14585C623CF6675,CF2A2EA5B6E18771,99CA7060ABB1EF89,0000574F2809174A,5B0004885C675839,14A1F082DA95D0E1,5E5538B18ABDEEF6,33EF12494F218EC8,7AE7457A756FC537,10D722CDAD0133A7,CB3463DB0944E527,66CFA867C11A67DE,80874772FDCDB2AC,4154D90B41B64783,A58D518A2C996F29,000028874D025A14,CE2FE71EC5D40BC3,EE25F517BD82683A,640CCAEB64294778,8B0B67D239CB0745,62FD1229C9488523,A639786BDF0D2C0B,93116C2470DBC629,0B9D92A4447D55BC,58FDCFCAAEAD5100,300772947673DB16,06D64B5FEB586292,00004A0DEB60A62B,F2883C15AA81B228,DA58D8EB561F2FFB,C3555D8E9ACBF61E,023CEBDAB1D94B0B,BAF33C24040D05E8,D72606670DFE7036,5572D93C8F684119,06BEF0BF71659FC7,C0C8DECF3E9E46A5,76C194C538025871,49D13C4E382050FB,00000534CC47D761,48733B9C08F07675,ED595028ED0BFEA3,4F02F46EEDEC6DB8,26BCBEDFB9F9F548,C92202A59C8C5F4A,5D084AEB36317200,568265246496D184,2B1AAC9A42E617F2,93973D030A32E4C0,672D146042DA9E94,100232FF13E0EF1E,000033DCDD716883,AFD1CCD89DF8625D,16D7718D44836B52,8678575A82BDAAFD,2C431D916534BB7A,8540F4347F561D97,77092FEE694945D2,D5E29D2622247C4A,C3378C2B1BDC7C41,7FFE86DA05300B7A,87562D43ADB85F37,ADA9B4BD0336D6CE,0000158ECF1C2784,863D1F666BCBD925,5A57F9CB63292F33,E9100892965026F6,083DD066A4DA8073,E9A28581E96238EB,50C8B50325E6FB8A,17E6E4E67975A759,FAD455ED9BA03D21,7C5A0C6E3A6CE42C,DD830E4B8C206E99,AAE29F4AB4373A88,000059152F9248B4,5FD5BF4AE967694F,A4E9CCB399D9F40B,B918255EDAF1C1F2,8182074D9ACF4E7D,9EFB9435EAC87A43,570F15768BDDCDF6,1EE59F19E676B812,F24F055981712604,71580F03650DAC6D,40B6911BE6473F2F,6E2B40BDDE3195B2,000008987802E7D3,606986B4DD2C756E,477C895758706A36,D4ED098BB4A392DA,D103E3B3982E0E73,23F3075B547708FE,705297784E1F0DBD,D2DD8FAEC29FC747,2D3A44F9155D2F60,216BF451D92C3343,62495547C453E27C,2278DB5B5430C283,0000320EF21DFFDF,EA0AFDACA0B56F88,0FBDF8FBBC3CEE30,7A01B7EF435F9F18,C00B66BF672F4546,C2F87343E3D82B72,169CD68BFF82E879,190B2B67A5C99A92,6E69F6811FAC8390,03E9161B94EBF8F3,76B82881D4B99F6C,0D894F3AE213B299,000024E44A2FFF77,7FD01CC571164837,C1E449706508FDCF,548CE908E4DD8351,C3021A7A20B12114,8A2D427BD38132A6,8FC0D4EDD6D14AE2,87D82FFE1C4B0E55,655797FAB88D053F,8A79BBCFA0E58A40,8FFCEE46D8C7EDD3,BA88D2DBAD208570,00002AB1C7EE65CA,A1B1523AE532B023,837733D243A9CBF4,F1DE3DF55E356329,9561397139B5738A,6F21C92C927A1C03,3A213686AD5AE439,4C78FB5089FBA8DB,17280A2DFDD72D17,13F73C7155B68C0C,C575D195AB4E8087,19CC2DFA07585EF2,0000387EF1E9CA4D,C21A45AAEF3C7537,C04130E88FB36A00,DF5964A07C8E098F,A2DCC040CB988F5F,6F8F302B6B3D3E7C,F3CC64EF3DE7C75E,6948FBC9B5182EAF,4F8EC098797448FB,B232A75F3808FC36,D1AF66E3BDCF3E5D,A25FF4122CB92CFB,000056B0EBBF4880,F05D0B52627EBD38,FDD75BE5DF2C04C1,A01394A4BFBD1CA6,D9ADD53FD8F48F35,6C6F4EB009831752,C539B0658E8A0BFD,C82BC4B8E1A57897,49B4E6C1150BC5C6,7B4F236AEFEBB109,71B5BA0858E4B76F,FC519CCEFB1875EE,0000612E84490EB1,F155E2C53D91C80C,71DD29950263C46F,440D124F3708AEF4,67ABA2A4D9E4FD3D,63EFA1E980CE943E,E1E9706C00376D6D,8F5EF0B4A36E3510,78B72F1603E0EB90,DFF75D81DE774B7A,332D1008250BB711,1543EA8F05D2F67B,00006ECDD926A954,BFA61ACB6DD448E9,391F61F5B032CE23,EA212A0BA84EEA6A,27F0594EA78049A0,D6AB0E253C2CD45A,AE1018FED23BBED6,3FBF40FDDA4C2F8C,F26F1ECE5BC110EF,78273F50EB69E281,0761C7A2E8077D05,9259E9EFD4229609,00003DADFF7110B6,B2CA9E2B70217E54,C979FB43618208AB,C4AB747A312C4D8B,F8B8FBC362AB2B50,A7E4721C65BE9E36,BBEF7CAF0BA52F86,1F04ABE7D0D0DD3C,B28B3C4D2242CC4C,81AEAD33B4344A5C,DB35E7DE36479DAD,5BC4D546059D4BBD,00002D2306EB22D3,066402DBB16B6234,9CF5E3738CC22495,C81A4579F839032D,E36F0EB530587816,6D1A3CFC0FEEF294,3F831DBC5C23361F,A03B509EA0C77BEC,6BFD27D076197419,1D0077BDCBA1E1DF,84A73E195F148C6C,3EBE063E73DC02AC,00006FD2501961F2,120ED11D66BFB459,8A0C8875B7070E45,D3BE1309D179E736,EB820B3CF1B6670B,66D83AF0549CDAA0,7A3465CD32E2F6CA,934E74E770E6FC08,BF1F767BA2BF866C,737880236153A4A5,9359A9E1AF56B3CC,8A8BA9181FEAE39D,000069455ABA559F,EECA30EC7FD116D5,DF3E769E43B7B38D,3D059629507DEB1B,961AB086A82963C9,946A61E87751F12C,5BD995928866C05E,945C39019B36F2FD,B459D24DEE2282EF,76D48D17ABAF60E4,6F2724722062E20C,59E5E409F1234FF4,000045AE3D929D3B,F6689E227295E8DB,A1303F3DCA10FC2B,0927DC209361B7A1,23364FA992E66911,1161EB4949294D5C,B6971E9E1908BC5A,02ADDF36CD545E0F,845CF404EA7A7B93,53BDAB28956F857C,E1B0C16FC3D2D743,5AB918CF2C8C3F92,00005BA937CBE2BD,A0E2EFABF44009DC,1B58E17EDB2F2892,5A2027D2BE090046,95E9E038C0E7609D,DCDD5841EF30541F,32287A8674A42D7A,0F3F8737B5D6F792,05E17A55593583C7,0840DFBF9416B4C3,9281F8FC324125EB,6335DEDC3D3A86EC,0000285FCE40B5E7,A0863E8FB38641DC,C227C449D8A465AA,AB35BAB04C9958F1,D92C36D7E1E3873F,360756C1F1707A27,755FEB9E8512C6DC,713D7ABFCF653012,9A2272725D8626C9,BC3A1619B644D99F,16E7BE10FF1F1123,5630004AFAC996A5,00001940FEE45797,7266CB4174E6E2C9,11A22C22A4D94291,BB85AFAE9FFB5A60,A5C4C75CDC68451B,674B66FB3AE05BE3,0E60E480EFD837A3,451B05F377A915A4,0A94B85A8E18FBFC,EA30BC009BE8F391,474B6EB768875153,53105300C8015C8A,000002275E41C91A,E6275346FC29E98A,0E7BE4E85C17EA49,97F3CE1BD17A33F4,C987C219DECAA253,ACBE6BC7CD1AE08B,2FAD4A0450EC87E9,F4800E0F7DC9EF33,2C1A711C1DD4690A,D98909AAE772DEFF,41C1BE06E8FF7E6F,5430C106E09B030E,00002915AF258752,9504DE3A6FC89A2E,01B48738E8C0ACE5,146ADD1F7A1B6FA1,BA02B8FC5980443B,6FA255857850FCA9,5E89BFF3A4A76444,33E9014AEF3FA611,B4A2E2B3E0369B5D,80E5B8821735F904,C3F98F4578243117,CF8EDB20233919C0,0000241477C342C7,BA78A65E4C144D63,853B78148EAE71C2,B187D45F69E77AFA,EB0A525D67060F06,B032D46854180141,4AE7943D381213F2,29C1780A7B407EF9,1EF713D9BF848647,F10343AAF09B158C,54D9655075E52A63,36ABCB594DAF8F1D,00005B01BD3CC1B8,D1BB269E3532D2FE,0D8D720C66B17CB0,4A29460B6342F0D0,5FEABE118F79AC5A,3DA2921EABA17843,39C15583124038D5,8701D3E87A06A15B,D1796101F7A1649B,EBF4EB283FEE4ABA,7AE69A918D188DED,A5BDC6921A9EC632,00004FF0401CAE16,A12C6F361A65E631,A5A931AED5E1BA3E,C6A6053769FC81AE,90452650BAC71940,B9A142E63C64B5DD,7F4472AFD62FE55F,ED7BD9D73AE1965B,31869E6742507FB4,06F983F5831B6FEA,B9674AD965DF7FA2,BBB0876546CF83DC,000002CF28D246B9,8157AFEA7AA8C815,96E03063B853E7EE,17E4012F8997F9E4,CD6D285AE1EA87AF,EB997D2FC7F501F7,E85B66B50790FB5D,6A596F9022A81FCB,0C81BD4BBBBE0CFC,A1B68E365D49D0AB,C20E209A1BF4F100,4EDB515D6C0CB114,00002048B57E0048,942FE7044629CC69,50443B651FA9054F,7CE02F769BE8977A,3882908C04B645E8,3842B83701CCCD93,A4DEE1233AF5836F,419C1EF8E8FA5DE3,CCF0FDA6A2C7CD7D,639D5419EEC5D017,254B6B000B6CC1B1,3EACEDFDB6BB1323,0000157BF6BCBE19,42D02C48AE467F5A,CFDEB240B98D8FCC,F1F2FA6F61FC70F1,290E116397DC02B6,8917B4F63E5FD1C7,6F7D360E50D7980A,1860E16853AE9CF6,FC8B93EA7395DA03,E91793E870D8F984,A0B0D9B74D6ACD9F,696EA4130395977C,00000E9F3D4E73D2,8BE7A05177EB4382,3BB07E093070F62A,91CC03C9477F8AAD,1C0A130FAA3509BE,9B526EA73EF0D481,8F68AA5B79CEB9B0,F8E37C98F07EABD9,7F36100DB07B2B12,4994FCCA21101928,409E40C442E68E12,8B93D1AAD92087C8,0000052A74D969ED,2D35D046FEFF583D,EA9907AF4F39ED24,B544F379BDB2CDA4,E8D1E23785CB9E0F,A84F73E2C649C7BC,A03886D80667245E,BFB95AE72EC1C870,D9214B3FF63A7650,6D20C5CB0255984C,1F65918D2F6873EE,10CC341B5952263A,00000A87B2FC7557,1D98AC5A73785E14,BFA311C983763BF4,0E9295E9313F8A0B,41614DA806D05B77,115F071FB8C9E144,C6562C6DB6E331E9,35D4B2FDE87025CF,67A81BC92099C78A,30C195B4D3DA9870,48842D4DB9EC5A50,42B45DDAB25E72F9,000041F11CD82FCB,95A91BD223A2BBD8,18A508761996A21B,752452635D074A5D,D5D90C2F32632DDB,9923D5120CFCBF2B,9813527681323948,753464EB201C4ECC,BD8A3F78DE171FCB,43BE539DB2BF4538,AB780A25D2F56E4A,9696E7121DD31BBE,00000DDA9C8A1C41,D2AB6C0FBA7FD595,CF196435C3890E36,F6BDA611E4001FA8,936C8EAFA1160BB9,064B3FE998E830CC,84F7E0D506AEB112,589862EBBA2C3326,E5C156F3996C4201,07186D2419A20D08,839DD949816F097A,5E08A35A964CDA79,00006BA4F2C5628D,ECE3BA6A61986E4D,37E70B8B8A2FD4C8,B2C36C664089C22D,B672D9B5C82F3487,286AB5FB00EC0855,0D72E995F7CA9FE5,82310493D18C5E13,471F51CE0297709D,8C158E7B6FD3860C,7C0748B62496F058,B47232898D32B70D,00006D6174717A3E,C9CCD8995ACD4301,C7D5B23EBB33B0C4,F5491F95AE19D171,A0667E42D014408B,9A08C42C0D548A5A,24DF9C9FEA1F9B3E,0E0F91059DAF9672,4A7F19ABC9A209EC,85C3C06A9288AEE3,0B2BFA71CCA0EB6D,1D6B4E1F0910CDD8,00006DEA8B44A0A0,C2673C908A15E8AC,96657F1DC352113E,3C1BF981788F1310,60DD90BC2C3BF1E9,2D480A6C0186A7C7,CD22D98348729042,7A16AC4FDC81A2EE,9D8A65BF0A4160CA,8B23A3A7A8441597,DBDD96683E8ACB11,F0F5DA7D2F67E955,000005258087F21C,72A44E120C098A25,141F6EE536682FC3,CC32D57201373A6B,472A64EE37E451A0,B2D1EC6D94DDE9D1,92DC3DA21E578237,E93E73AA63EDE43D,D99356C0A54D6348,7CF91F687650082D,DF0898F4B1E63071,A3F32ACA1013AF83,00006B645AD804BA,85E5FC22284F43B3,BC294F412F6DC930,B9CC0FE5694D8475,B9858F4752520F2B,4481A05E38D523D7,7CD24FB7A4DCF63F,45CBE59C28E1F0A9,BE2E4C5E1BD4B924,C5666176184E4482,82CD80666BCDE474,64580E6AD5D5F15C,000064AF53917E2B,3CA835CFD5A856E0,77F6DBECC5FCB1D9,34D15A5599B96DEB,36EE7350BEABDCB9,403642B588376378,4A29EEBDDDBFF0DA,8718EEA1C8BE1ED1,65930DEDA3CE6F91,412DC24629195F53,E8A938C1DC06611D,6064B507E644E9D9,00005CED3BA3FABF,CA129AB9D918237C,4F37D50D08B333D4,1B5888A2D0E92272,5FA0CE2245C476AC,06B29B3ECC64C08D,3B6722265930DB8C,138A559A6B74C1BB,4D19A35E912F5021,616678EAFD1FDDBC,F8F759ECDECF81A6,FCE486559D04D92D,000065C4F592E9E1,B8AEF87C21078F48,A35F43BBDE6930FE,95A1F154CB52FD82,D8B0E4D6317E3035,59950011EA3AD5B2,45672666C49515BB,43AC188A52C56D06,B43AF0B76D3BEC3D,C5F1C46527DAF90B,24FE9CC55C74BD64,727A8FCF1AA24702,00006136A2499AF1,D9DF14B10BD049ED,AF04FC4A82D9ECA1,B43C60E1F39914D2,B39B5D3DF6C1B92F,6219644CE85B2C46,490FA9D74A6E1A2F,6626AE8E2F0314F1,EBE9AA905E4C49A8,E9A92F37BC836927,8383487842467322,3A059E38019A49D4,00002C1BF1FD44D8,4D45B2777BD4E76D,98F773940789E269,38A350E48F986239,9C1CE30795D79E3C,675369351894E641,890E5D4423E7D23D,CD5CFAD4D1FFBD11,3EFF877E5AE656BA,2C1C5AD3B7609303,DCE00D1495EF9DBB,102F91B732A8942A,00005F30235DC76F,8C923AB0E792E42A,07F175CFC7B44182,06E84C39A0D29E52,CFFEB2C1A59D3990,B430610192DC9C1C,2E16497793E9392D,7CDEF52EA7869E6E,A873A55DD7BFEDE2,7DEC7CAFE82354B6,70C7176F47429298,539C23B07719D648,00001CF16EDC3557,6DAD99A632D98393,237B131EE6A56923,1E297640C9AE9DD2,89261B8FCEAFF6A6,DF5558DB3290982C,D981EF9B188515ED,B9A7BDDADF8A89F5,562A8580D2068B68,AD78BC412E2E4514,BDFBB72867E3DA0F,BA4964A1ADA3E9C1,000013989B2B21EE,000F0505803BE4F4,5E7F1CED0C1EDCB1,7E7144A49AD29C8A,D68DF976E8A4EB3F,0056BEA05FC5090C,A53FD4E2BE448E59,0C79A2EE9005E8F7,EDB5D511D9583FC6,D8F99E4CFABBA09F,A5F14B28C84904B4,16F9CA099545A5F1,00002DD06D24E146,D9C17BE29BD1AF0E,CDDE16D6BC1A051A,55B608B1FEB06DFE,6604362B42CD072A,0099800F7D3BCAE2,C464D13333569379,90AC888B2F914204,B908077B18BD8E78,D8287D42221CE11F,C79E5873A15F14A6,8D50C5A33BB3B316,00000C560174007B,25E0DD7E6985ECB9,9DF9339419226C7B,FDE11ACDA0455D90,B082CD8457BF9B3D,D69DD8863E81E897,CF0F42660D9FF4F8,6C55B9BE5D5AEEF4,3965BB9656654DBD,88ECCDD8E72326E3,D2C156B3F555A1D3,FE4B61776677B1DC,00006A31B7F9C1CD,3B213AE25685B0D0,BC141CEB49ADF0FF,5A5F8F10581E4CEB,D6182EC464F3A9B4,362CC7F30C3A6370,8A8FE825D2C17128,95000C92F2A47501,5F55395257E5D799,1A38F10A18BB78CB,DB4DDE62053E931A,C61B6660275B44A1,000046112DF7919D,95CCA5551A2074B7,CF1077CBCFB33477,AD593425355C1181,33D5928BA9C95F74,7C5DFAC87DD01A59,7DBC5D64FE45416E,423E807133D79134,7D08B98D83DFF6FE,C80342FB612F8B44,9BC7C9DB232DF776,558F897162BC4150,00005AA802799040,F6E09A20AF0A3F2C,BC408913ADBA4EB2,145366FA90F2F00C,C6531B522CDEEF1F,4393DFFE0A59DEA8,61E48FC3CC5E7BC3,91D7036F193C682B,159BB0DAA7710406,5666361D04772FFF,6BAE540C2D59AEA7,008DC8D4E3C44FEF,00003CC2A8DA9C02,1A1AF44DF21CBB42,F9876151E2B59440,0463633BC3BAFFCE,41EB2C1D8672DE56,FE517ECF9F27271E,EC72016E856DED86,223DAE84FC943CC9,D19ECE6CF320EC96,BF45C8391E143E8A,E2FE38BB7B5C41C9,B8E46846E458B7C9,00006F5CFC483383,477E0701CFE681CE,4E5D42646F9DB857,908ACCFBF0AB8B43,CC7F027F7460A906,B2C0DB3A783529B1,03E0DB3498A3E49E,859EDBF880DF3006,B70D0E5EE6550DA2,960B2BF3B87E5F0F,9864B3AE478AD807,AC53CAD7D8705A30,00003E61EFA33B8F,7C3E306BEE61EDA8,DDB4BA9DD9C610DC,8E1943693B87084E,74977B7D96AF5F3C,01BEFCFAF5E7A463,77FD2074A2EE7037,AC3B88887731223E,492FC62A2DCA11C9,485804C63A1D94D6,BBCB4C623D21737F,EE81F0C8B879B8E3,0000060FF2B130CD,5EBC5D2E01135D0A,2D588704E891EC2C,1EECE889D045D9FC,C7E39FA3C96DA411,09B4B41CE83CE2F6,B59ED0A4AD099F63,1542CB30012F814F,7B151B94B8AD432C,33B99FCD96C801B3,604EA3D4C9312C60,42F1CA25412FDA21,0000556B83348FF5,28F195F40570E2EB,A8ACF4A6A8A56229,7843F73C9E5B94C5,6AEE60FBBD46F431,3E495534B5B0873F,8609F8E97742D27B,75F7410561EFC679,F10F123FD8207EC5,76BE82FBD7F293C7,D524ECDA57778B5C,AE7CD1B888D03592,0000087D33D1F600,AA690706577410DE,A5D128A80EE7A94D,0DF53CC9C75A951E,78C8028BF4B9D967,DE8092BB34D0BF54,3637473F804E67B1,A39A04DF19C39E9E,96E4765B192969CF,F7B0EF7D589D2115,8C005B85FB1DCD5A,CF4FB3249023AEB8,00001F8D2C540B64,5F14BD2F0229D620,C34664F5CCA04E83,6BE3934C2D7436C4,901290ECB17042DC,3DE77A6FB1A1C469,1651BBD73047FCFC,F3F1D1011298BFA7,3F568F6AAE58DC3B,E2CFE0DBD43CDDC5,F61B50932E9B2B7F,8F76B30EFE4C1B4D,0000618A9947BD52,1D30DC8E070B8B6C,B078D89CD2DFC389,B79BB59843BFAD9C,46F895F25CFB575D,3EA91E501290FA14,B1ACF8EF567DEA9F,03488ECE50A3D9EA,D85A4F0DFEAC8956,725C07BD4A63E7E7,A31881F7CB9067F7,02F1F626374F48BD,000061D99FF0DB41,AC5A0A6B01727664,98E0C67CF366C6B3,5AD745EA24543B2F,81FAC941DBE14804,0ADB3DBDD3E4E3CC,005AD4E8B03A4CAB,C4F81C3BA6D26367,59667294E9D37F99,25DFF3E2329A0020,1ECDC6237A10D5D4,5A842173E529563C,00002901BBAC00E2,AA0732B0C9BAA39F,3B3CF333E54677BA,18DA7D79EA496142,7269FE35462BA014,712F2CAD1E6962CE,53AA73D59782C7A8,98B49A0D3237D48C,139D282E333AFAE4,A4549C86D0E2048A,5D7E06CFE627A7E1,2107676382366CD8,00001EA9598B4456,97B95399121B8670,99016A1D052D1A24,60F52856C28F9428,3032F76389FFC5B0,C4D5C8C88B89F1D0,8BA3583D953D19A5,A152E7852CD9888C,12CAA32F6E448AEE,92A97AD418E03363,B82F8706DC77856B,19679C1434466616,00005DAA5589F7F6,DEC139F0242794B0,9C1834FFC27BEDDF,5D53EE9C9FCC10C1,ACE575F22DF917E6,C35B34D1D2B8FAE4,3038FC343087610C,542E74FF93EAC864,D27B515488FC40B2,30469229B0A06CA7,10A711805A86416C,8FF51AF4B2817767,0000234C54FE25E9,2530FF402C71B04F,DCAC7139CCDD13A8,AEBD2210D204A287,E18CAC4EE5E5BD82,BD43C779E5DCE130,EA5425F0D1E6C56A,DBCFC0785DB122D7,F87F197FCB91A6C7,948BEE52F6E01504,95E76B2AD77BA642,A24E191BB674ECF8,000049117690FC9D,408F4CBB2BA87FF3,BE17F4A69676C4B9,7567408999629AE6,EFE1973497D06C19,50C73A8AFF16FBBE,3662EB997181B9E0,06EEFA3E59152D79,718305F3133FBED3,231B1EA7562599B5,59C0769A61F33851,2389200184EFC4D0,000051ED1E345EC2,824C4DB87FDB0E28,BE42426218655860,6CF4371E963C2310,45D6C8E6B93734A2,62A8DFE2CD440AA4,8ACD9E1AA7ECC362,928CF9CAC3A7DB19,875FECE08A0BC990,18C8F6AB43046F46,0CF3C3D724C017D1,240358789A249894,0000433D9D276FC5,D6FC2EB10684B090,5CA37129CFEAD0F7,897DF203C043EFE3,0E06E908EE5A1103,5B9BB9008909714B,E1DC320EB55E710B,9031C7533FA31CFC,C8A56FA4994B0CAC,CD1E7971389AE501,6B1E02BF9EE0A9B6,5531ACC0AC686353,000050E33C5955B1,E72E7D704981937F,44AC1111B87CCE60,FB9F52BB4FCDBBB7,F63E02C79B6B3F44,817AA5091C68C6CD,9BF9FC2C94438E00,D92819AF0AF44A25,46149CA8FB3AFA5A,19E0621B99496F9C,371D9F476FC5C194,F718D4A9DD3CF334,000007DB3F637CA0,20636485B11AE710,E01B864A041E6C37,739EE543A8C49036,69F049AA744B5036,03447F68DDE76C84,E1DDE5AC99726B89,7434AEB2C9F71217,996F440113DFE05C,61BA4992EDDDC07A,F3A0E29117A80AB1,41E799AB5151F0D0,000066E8D15724A4,9651C21E6A7692F9,3F221AC388D0C39F,702D99811847E95A,7A88B0106D18243F,A80978A28D7023B6,89CC818D5BA4F2E3,C6ECF8BBC6B59EA0,99D2B4614CA4AE18,5334B0A28EC39D85,F21E307BEAB8C509,3103D1AD405DFECA,0000375385FC6B2D,060F57AFDA2CC988,7190A9A54A37E291,4F57F53872AC7DDD,94D060AAEBCA02DE,56B36FC35AA32559,64FDA16DFF0E2025,4A462A253D39104F,1C0BD4BA8A2C8AB7,AB9C4AE5F3D0D2BB,A05CE937BD727D82,42D3183A1D845298,00005636984F36CF,9C9E2F452542F60A,A9301D9CB065CA52,1F46D8A5F4C10234,02387D6B8BDFA435,4FD0FE739BF05489,A477716D5356E13F,BD749995D0389D49,6E0653A1631824C1,FABBC21750CFCC0F,7585D7C76E9BA40E,3AFF329329956ACA,000040F8563F63FB,E11E32DE6847BF89,7A473563878FF91E,89DAEC94470F53DB,C5BE95A2AA5261D7,8E41CC9C2D6CA2F4,B4E06566CB410827,5759BDE4E8DF138F,19DD46A83211EA97,9163E534CAB63383,438B7DED12F4A4D9,AEA00AE09C68F9A3,0000134BC9766509,75712252DA57816D,AF30112965B6572B,A888FD2706E7A100,196D1AB6AE773D4F,53C861A75FC83055,170B5C056E19F954,2D975AD052B7533E,64488A750033B43C,5ECCB0749FCC881F,356D6514AAA52BCA,A0793A737E5D8FA4,00006F230A58B787,0530B2FAFD3ECAEE,AB9DDB5C6A198354,138A10904AF7A08A,5FEE45A8C9D061BD,92FA926EA00011EB,7C71F7141BAD1188,CB9F2503B62D09DD,E39E01E98CFFB140,AE5E73A6DC16CCFD,325410764A63E8E0,DC4A206F59DF3B4A,000031376B7E47E1,79E90F38CF5A57B1,E85BE23F000E31AF,670727FB016F187B,886C974FE2899EB6,12C7AED943D13306,BC6E39C3CD983D13,08D35222EE95B8DB,71E21A2F6E256D12,14844BE6158F7489,3341386FC3427CB4,45443E3129DF7B6E,000047E38D34BAAF,FF6A0535274C6949,EB89C5D70186A622,D1F8ED1AE2B3F235,8E75F01939669371,5D457142CABB1A70,C7E03E60980C3AD7,2369A55A39B59FE5,973B522FA5E72F49,BE224FE6135F8291,B3623086794CD8AA,756A1FFE74FCF0CF,0000099CB91080E9,8A514D903FA54657,A1C64CC06659BCB8,894589A2C657912F,8FC4A68C758656FC,DC4EECCA4CCE2152,F623C8B790EAA67C,7882C88F929B4ADD,B0C85CBFD797C3AF,4DFB4BE5FB8F6A7A,FD13A3EB0985CB07,9EAB85C76B2FEEC5,00000C2BD6E533AF,92BB9DC87B3FAEB2,3A649625EC5B172C,FBE1AB358A0D42DB,C9851EC966D813AE,70D6C5387ECA9714,C0FE594E9E8D46E9,F54C952AE5A4B012,1B651ED7AF5C48DE,7E07508368C55C6B,151E26175D3B545F,506E4AE7696ABC84,00001EBC4222C190,BE6C55DBC3324E58,4EE1C473987D6873,DD917609DDF34B51,17A5D077E32B0308,59CCA9E3DF9E7F83,277171088DBC2148,50772CEF8F0FCE28,27C65BB135C31A8D,5586574522CC1C8C,C7C657A84E587A08,C828F9C37BCAB62D,00004541070BD683,C3C54B4DB6E23BBB,74F95F56189D20CF,BB4F752769A28D70,7892447E8705B78C,0D80401038A9FA70,850DBB4CF8104658,50CABC1E94D898AC,F4793C816E7B8A9D,0EC1B6BC2B1232DB,80C3A9CBE2D0B35D,F8A42352EEB37F5C,00001FC6F95E9784,39ADD36856523AEB,7E21D322D1EF5C78,7787BD41B3321BA0,9F22983B59FB5858,BB6641B05B7626AE,C7B87A7552E0E935,C9051FFDAB7EFCA2,BA3997B6FBFBEC40,2D0351D05BBBFE54,EFACBA166B1A1015,5FD9031866096886,0000547434751E22,A7A13C798BF65C34,5B6E8C20E6CF9C22,A18C516237AA4C09,84E4736071AFD883,97079D066D3BC503,54506BD3BB965652,9EFD3D637449B976,1E9FF78507809AB7,C3B90274D6A7A039,FC3369AF28692D9B,5EB95A5241716FED,00003664B43172D3,FC069772C75B92E8,F707504FA03F406F,A8ECF48DE8460377,D4969C8BD00CCA04,4BF97F478AA54BC7,191C1E3415A67BE8,60819CC77D688861,AC43B4571768B1CE,BC69270A76396452,2D5011918D52F6CE,BD20C0C56084029D,000026A2DBB51B73,09E1D9B52210E5FC,70B1250CCC8DAE13,759898626253B7E4,497D94FD3B042BE3,A69F671B1A89B2FB,10E0C8425CC79FAD,D2D9B63ACCE06994,01FD8D286F57B1FB,E3E663E39E755A15,212D921CB3B1EFF1,A5782F132D029390,00002FDD1BA723A2,E359E0ACBF41F957,D40FB069C6F53505,87F06A5F30B989BF,74B6DD888CCCA4FB,A6C5E8306795C18E,A9610A2EE6B39165,B68621451D064128,38792074E48DC308,51B7C4A111554D25,A7A7D3AD10200D4B,F666CC1D83016003,000012C4172B0551,B4053450F2403BFF,87D1583BAA67290E,600031BD5F945B4F,2130EC2249D955E4,3F2326DD83CA1D9F,86DF015289B6705C,6BA5866D32A32BFD,0B04E5C48970DCDF,08DBE4F80D0784C3,AAB773F7AD6BC0EA,DD802796C3169911,000016620F657690,DB6A785345D3E3D8,0287E5A67911ABDF,8320D489B923A16D,CD35355C3E6CBB2F,36F1A5F0E3F5333E,1FF7663A1738F91A,867117B5157248F2,9D746B4E608230AA,14E3686293F6621B,3EC3728B3D29991E,F91284F821BD8D28,00001EFF7BB2A1F2,58D79DDAB21B501A,5795BC31681F6450,5B8F9297DB9A4E50,58B6DDF41BA9820E,64189672FC98A401,675629ED1B407A42,4DA276AAA241C116,1874950347957F75,1D584CE56CA3C184,AB833641D00EBA81,D1A8ACEDFF53E0E5,00001726A14F1160,0D79923FCEF46187,B0D87E581C587FA7,D507882F99298F96,380A7D7120332ADB,3E945A30A7C76E32,1D1F60B0413484AB,2E56237198BE3745,7ADDC65DC96F12CB,8119A99F208048BC,725606F0FC79E525,1069833FE35D7A17,000035FE973433D5,6FC38001C7D1F6E9,7AE3702AAF45288B,90F0386A0DDC024F,D20DB13EE77D669F,4846D5F79DD7C5C9,5090985E8DA28DDB,54808FFA7E22834F,C3096E9C13583882,5329266A6E603033,8BF53E43020C138B,B3607A09372E9B0A,0000304877928DE0,12D918AF32271B87,9976E9CD4A0DE952,766AA9C5E661BDA0,18DF9D3E67B1B8AC,98DEBF9FA30CF238,047E732EDDB34730,407A871B8D7DCC26,B69EF6DFA77B20E9,F4A2F47CD07ABBB3,7BCF3EAF667DE69C,8F85488281FBE5C6,0000207A48528169,B8883801CFCDB828,B8F73365A07670FE,E4B0CBD710832759,7A14EAB1194ED6D8,E1DC4314FF428413,B2FB2708554B48F7,595D1A87DAA08C9D,4550FB95A391FDE4,15578F1EB129755C,D5FAD01C95685415,079F447B3844EC49,00001067434D6DA8,86265DBA88F40350,95D1ADC59813EE33,288C8C46D5C13179,192E89C15C4A428A,AC2407A7BD773E94,617A9BA4B29D9B0C,8BB1D42A87456F24,9CF525C3FD6F9DEE,B21FA26CF62FEA28,C555629A8DD607E1,4B8455FACB5FF0B4,0000687B90174DAE,57645F6A05E4B042,5B5BCA8B911F974A,885266403984BE92,1E020812B3B57CEA,ADC59186F09ECF42,4D213CF6B5AE8A87,88BA67ACD6751D28,E611FF2CFF7C7767,71F0B3D04628AA98,20102BC33F60D6C3,F5792F9AA6CD7835,0000651ACF11C371,F971D52B75253D04,EA624E64BB4965B0,F44A975FA245B3FC,75A0F3A096F7312F,554608680A792A50,9A11EA63216368BA,8F2047DEE32F787B,B8CFC5E34DB3115A,A7DCD99979DAE483,72C482CF7DAB9BD6,91EFE4E4754F741A,00006E43FBA67401,89884FCBED733888,D927B4BE8E6B2188,3D4DE08B6E127AB6,7EEA35B9B93151B9,CAA7857C50F538DF,473DF0EC5B1363A3,B83DDC13B8B84974,41A874DFAA177C90,92385F3992553D80,E0F4FDEED8A98BF3,9A2393D66EB3452C,000022B5BA237943,79F87E73097ED103,8F02C4FBCA29C068,7845A86504266F43,6297786D3C3FB2A8,E4AC4F09DAF8AB57,8C9348C4FA6AAE05,9F3BEE487D35CDA2,C75C1480BC189743,C39B3CAE06667EED,9605B988F61701CB,F495C385B7B6B7FE,00006F1016781AA6,7F9C71EAF37710DF,92535BB796F02381,436E5240FEAA61DE,3BD86711BA6E605B,5A26823D569FB9C3,412C945C1349FB9A,38260092BEEDEF85,5966F3A61CE21E2A,24EF26075E4F0A0D,31A5505AF3F686AA,5ED4D467139EF23D,00005141238A5C98,201248FFAEA2EE44,8818A7CE1777A61E,5C2067ED65A486E6,383BD937B8BF3CD3,FFB737E1F6E48D8E,0B108660D4D3A3BA,23BF9D5426A0174F,31D332BC67D40885,A698BC5714ABC401,BF4A9A2A3FB75F53,09A418A642C6C4E6,00005325FC32F431,92C362BC137539A8,8B53D0316202FF96,09EAD097D363745B,1FF658FAD246C17F,8338C9F46B5EAB05,99F82B2A79D35983,77B783433DF05360,A1BA50A4D5B6272F,73BBE17C69BD2DDC,43E37DA8ABCA48C2,D7A56C2E2A3C3DA0,00000F5B477AF14F,01208E3C9B546792,7A194736CD45E371,227822251F2E7514,E551442364E921A3,EB6EC894A33DA9F5,400A0C3FB03F7F53,EFA9CC5A688B4443,3019745CB59BB304,65A03CF3E1779F24,50B59AA14EDEA2E0,0775B5BADF31AAB7,00002E3C536BFE04,7B7B5C142B5351C5,DD2016D06C046BF8,1509082A684FAFB1,03B12200644975A1,BBC9F771C2A9D5B8,7116D39AFFBEC01F,2232822B6BC0E308,000FEDAC6A13B47B,83E01CECF8B73B29,63F23A0AE2DAEFC3,21EB9DFC3E7DDCA9,00000F38974AC08C,2514D39CEBEB2EAF,B838496BD046DD68,4E40C8AD038B106A,4B1922D02EED8D9B,C989F254E3AC66A9,A6003A65B3564D03,BB4B8D5AC65F933B,9D624EE9A25347BF,5E293D5D3836CFF0,273D9D18A7266579,EC4F28A39C6383BA,00001CC1541A4EA3,AEC3698372A32F2A,1301F36A83FBACCD,D336200488FBE8C3,7E36B0924083F24C,5512B70F09759567,0921EAE1F6D718F8,EA290D286E057601,AD82ADBF660D5F93,5F9AF0BDA32AB722,2CC8B39EAA78ED1C,09A218E4C49FCBD4,00004DE218CBA6E9,99939B8F9BF49CF7,B5A5E2C796681627,019FBEC8E94C7EF6,CBB76AE00270326F,3294993EF5E6EEF0,28EE2A7DCEF5A3F4,C7B83AEBD01F407F,0124B46F40CF3F69,CC28C4991D2A57DD,FCF78F39A75397D0,C0D65297A86797BB,00006DD0CD860957,AC3D16BCBBCE37C3,AF43A019ADA0209B,06EACD690402E966,36C4848EA59F9BCC,D8481557F0DA6937,FB60D19582EAEA95,DB58B5318E7F2441,6872F586A80EDED8,931B8DBF2B019781,0DBDBDFFF5E9ACD8,98515238BFFB24CC,00002045137B6F15,5830E1417C389676,22E895FE1C5507C5,C97C8C304997CCC4,6F4C7270C7CDB4E0,21444500C176948B,21FF884C6D1733F7,3572B41425A5EF0B,8704591F7EF4E5F1,6C1118F215699A84,52482DC0E68BFF45,655D8B6114B2A424,00006CE2CB182A50,A85E1FF9F0C56D55,7222E1AF9A0DF2B4,8890161AE1630696,DAE1358F8AEAF0A7,F51D9FB3185FBCCA,17116FD3B84EC7A5,0C0FAF1C4FA67954,5F2F8E799AF6DF73,7C1CAAF1CC243ED3,763EDEE1F2C33C16,8F46FD584CFBC08F,000010314D631B71,D9B537D9F726D984,FFF85C4622FBB32A,4B45F09521FE17C2,A6C5563F3A320441,73E9CF1466011D96,9F0517756258405D,11C2FA9D56EC2B78,57913C23C4759094,9235AAE9C816CCE2,6CDFA6DBEBE377F3,CCDE594A79D5DFA4,000027D756019456,CB8B457C50ADB916,D1FB80F2F0CA49AD,A9C635CC9E24AA84,31B723C48C72029D,CD5D5B06623E309A,3D7A4685E888BA87,A152B9BB36D55E85,D0444BD0BC124076,A1A214884B41AD89,124A416D70EAFD82,4F73BE52A6A69E8B,0000319310BA52DB,96AE0BD73B2346FE,46E2BA47CD08AC03,507B199CF06A6B0A,C69CE62E707ADF70,BF7D8D06B203B695,ABFBFD05C4FB0E1B,C90D6EDF47D4F73B,A1CFC0E66378DB22,A43361621079513F,77CA7F173116B810,2814D587198BFEED,00004856856B501B,837AB90F710620AB,B595EDBE9889FA88,B4365D7257A9FA63,EF107507A0A3A828,5431B00172E31CA7,1B5D985FC19D6003,18D8D5DF30D777ED,D1C0328BCB241EEB,048EA3C783A91829,9A4439946B399C5B,8FAC57F4BF2D271E,00005264A66F30EA,091A62DA15528873,A9FBFFC5FC2F51B3,31DB977D3E0F07EE,AACE349F1F133ED9,98B66536D841FE18,52AC0129A6407366,280125D6D5F7CA6D,8FF2434B7564D09C,8ADA80C284732C18,611C1FE0FCCCC671,46BFCAB491E3DEB7,0000688E2BE4C3BD,529B7DBAA6A9FD08,5BB27F71E1CF0AEC,3E61EBD8F67AF41A,D181D45D5A00B827,03B831FFB332554E,1D918D8335811AAE,121E401BF21D365F,F7AAE7EF8BAD62EB,467E361306F6A6D6,DBE89831E66BE49C,25CA4688FC91C196,000016DE54C613D6,773DA4B7D35BE0DE,FCE729E090EFDCA5,33CC656F46FE4EEE,E307858766C3B72B,DF73C255BFD24DC4,2BDB24E664DE3839,05EFEEC6A51F6229,4BAF9A6297D4A9DC,2461E83E7C0D7703,6DF793C0E8044D1F,4B0E5AE96493A958,000001D126E44BCA,070F370095D0B8D5,A648A7D23223F408,0912A25DD22CA683,C9702087F291A16B,1B1F6798DAA2854D,FABF93CEDB004522,854C94F670459E4A,001C305F19804782,6E1480540FE3D725,00403C7B2030A357,93C01B4EBE3EEDFB,0000662B5322DACE,A5E81C43AEDCD3AF,BEA297D55F8516EC,C83632594985338A,9F271A9A87526ED9,19358A3A818FC0F3,79D80DB18780AF5B,0A243F16A4B582DD,A105A98EEDC37D7D,E074F95669606A43,16028DEBD8CA49FF,1094C24976853592,00003AAD3DCC864B,A7AEB9045A4A8F78,BB17287D2E92DEB5,D6734FA0AE1B348E,C4C17184C2A671BA,62E8BFBD20741EA0,65AC654A75D391E9,A580B7E5B6B203DE,B9C4E74D059B747A,D1701670D90B476B,D3DB70330FA23E37,197D6681FA60225C,00003BC3ADC49702,B80BF8EB7AE5583C,43E12B341DA1246A,89EADDCF32509D31,A831EAF11FDCD4DB,F44BC5BD8225B075,74544284DADEB68F,9F47233AA06D762C,435191307DB93B05,249C99FEDA8C8619,9F52DAF9C9D74255,F25ADE91A2BFA191,0000658E24967AC5,A4204229A876CEB0,2D34C2ED3F84B668,253F8676A0AFF47E,99446A267E8D38BD,6E8FFBDF1E94168F,D9A60FF37F4B8FE2,9874501BBEE59E83,0FC42B1FA1C68020,47F922CB463A1BED,8198DA7CECE0FA33,27ED48BC219ABBCB,00004E89F0235604,572CD3CD95CE5930,971BC10FCB9C1CD9,388358287F31F180,4F0AE9AC8B73DA97,1AA33886D939B4B4,481C36DDEF4420FD,4B095599FF265E08,0EE41832323040CE,01D9D1A029096263,8EA7868A8618F9E7,07ADE01C647B0D53,00001F66C908F8EC,671AF4FBE8D20FC5,106808B61E14FDD9,B091B75040ABEE51,995E606B54CEEA51,2B09FB1525494F4A,7E8045CB0E8813CC,710A8139EDCC54D8,596999F8DE00AB5D,EC96BBEF74E16734,E7FBE15AA694894E,7220BDCEF5247648,000030A587EE42AE,E2F5DC0694ACD417,DBE07C0650668B29,929C09A881DB1939,5B371B7B343A9A67,86E78A8A620ABE47,2A7C504CA09F3C9C,4FE91B9DC9687C8A,2439ABDB216629F9,0EFBB32290C41C8B,C5592A2F27A64C21,4F365E97184FC8AB,00004971E6DF8EDB,621C59FCD42587E9,7DB4729EC5A1F054,15F8DBB404EB096A,694631E249CA942B,A92896F8C446218A,239F4FBDDA40E2A1,102B3B7190D0480D,B5704C84216518A2,F8ACF814F3FEEB7F,E1DF686563900BDE,3274229101DDD79F,000021E5B1C725C7,EF9D99EB2FCC7C6F,3FCFF53BFCE8FC30,A3FEAE3C0016606E,DBDF516A7E10DE39,2DEA2852360FF046,6B819C8C690037E7,C50665E2BE97696C,1A796090C373AB17,89EFE34BFE088866,9E3C9B1C831D311C,24BE22CE1B0D96DA,00004F5BE3FD8AAF,F48AC2EB5BE2482F,867C88BA671194B7,4EC7A20F87649127,94E551429D1D99B0,A475AF22159E4F46,47F94F42C9D77280,427C0E598F8CEA03,EBC2D720D8BE4047,055AA115C721855E,8BE6429F96EB0276,77DFCFF46B11BB91,0000329B06D21816,A82568E5D80D31BA,90E72EBCAF9A2CA0,07561D038E665C08,301031519B35A065,398851438EF6B2D3,AEB0E668CAD91B3A,3F68DF16A5338C9C,9A072A74C2339DDF,9E7DC818062D7653,8A00D278B12AA020,DBA6411AC4D55F50,000050FBB70BB8FA,3183E6D66F8D3D37,0DDE3F60076D2701,F85EAE735F6F16A5,B4A04C7D29C8C6A7,FC91FECD9D888D81,ECBAD9FD92861633,F78A1A1E82B430CC,407037E151A0572F,C715B19F46A1C069,FDF8BD0FEE6D84DB,D114BD654315B12E,0000232CF636A870,8EEA87E7B6E6D337,3CB6C9BBABFA4387,F8DCFB6E0EF28B9F,4F1C4131D0762F8C,610429383385DE21,55D4CC5EAFEEA515,87945D448055A726,1C49BD57326BA3EC,74CF163FCEF0A815,2AA1FB6391DBF625,36F3685C007FB494,000016D0C7B606D2,3A397F5EAD33D15F,2BFC6340E3203C12,04BEF5B462053E42,ED01758818F986E3,14A3E17B5D70D957,94CC3DF1C9D8FEBD,97D19C2E3837D3B0,5B64C2A0ABBE93E7,6B1A6E245C0FD766,E384CACBF020B865,1F3D83A2CE7C072E,00000AD465803B21,BBDA749143146A16,5C325D365C8A8515,8363902649A14D81,10E9E109D871B153,95999121E9C9B783,7A8BB94F91FD6269,5401DB5EC897E3C2,0FB17C1F5E775F00,94F6F085009A07E4,14452AF38B84EF3E,0731AED953F941B9,00004DB0F7BA1F2C,787BA9577254F6C2,A5B0EBC1DBC1C963,9851D08C74858292,E0CF7228CE811906,A7FD3E0450818B4F,C01A5980418B385F,8618CA1C3FA1E9F5,7D6411390A38A844,8B0FEC7EA7687593,EDE07E6D45FF65C5,127BFD1A5A8F861A,00004C4DB41F24EC,F36AD2C8A1B471DA,F9E1F8BF1B0C3928,C754BAE3571CA976,A96F9573BBC84823,7B8CA764771A57CB,B38B1BC77FB7093C,8989291282146B6A,F5CF6F6C359B1F75,CC7A1AA92BD0A168,7A61892E1E6A294C,DE11892EEF733587,00000C5BE681EEBF,5BB99AD9263FB629,5694EFC6B9F77A4A,58436865C1CA85E7,B0B15ED59769439F,72DFD961790A8175,F4554B7282FFC916,3A2C6162945E4AB7,39B11362C277D64B,B0F408A804C5785A,435B7C3009FA554E,71FDABA8DF085149,00002F80B8EEFD77,F06ED9995CBC4B06,5B2FC3C8300EE0B7,4907AD0DAF3CC0C5,D78D7437D8AA8A2A,9195C8054E6922A6,D07AEE7991187B78,42392B6DA9CC1D33,2419886B910C94BD,41304ED6DD8CE9F6,7758C3DA5A4B73A1,C66135A2D3F60964,00002112DEF6DAAB,37AA8DDD19386A8B,AC887C3B51BC067C,6D2D487CB4F880A0,C83DAF1ED273ECF9,51C75604F7806E70,F042253158F3F68E,95DBF97FDD706FB0,5BF5BDFD59B6D183,4570FEA642492EBC,B8AEC2C680FC4170,056336F47F0C089C,00004D67C45E8BE3,4E2091D0F946BF5A,A4933C67A28440F2,4C1A073C0D11D800,7700438925BBA135,0BC97CB15B95BCD3,F013C0E13B5C6F0D,C36C111EE4ED7D74,5D6AE4627F879288,626A84497F0BFA67,F4275B3D769EF976,CFCE5BEC9E200407,0000395E022617D0,F3B2AC8577A73D8F,3C9F6E14757B6248,1F6073065C2BB035,5F32DFA758EFE5BC,B392230AF389412E,D6125433FE3604F0,D401AB451C4B72D0,E920EC9BE471893C,3145FA46242F921F,2953920E02D59E47,89A3E4A6EB1F8C13,00003FC388D08293,E44B881A2F1FB04A,190C1304A914928E,33F135FF1C3F5BD5,0C959C60520655C2,41C824862D5206B4,B6952492189EDD21,6088ACF8EE56B6C0,7618B9E124FB89FD,C724000ADF80E758,073D5F553614C84B,81D810A3FC36EAC7,0000593822F47CFD,44DC5F953ED05556,7AAB2FFE33714FEF,BB70AF9EA5E1EAC5,C3AFF2C320303739,A4E8028EF0021243,EBA7DB10902817C0,E013F5C4A5AC0636,5BA6BCFD8F647137,6B34598F74909212,3E7EED2B913CC98E,78CF536A0AC2FBBA,00000F22C5312B9C,02FF924758295C38,8B8600CDAD2CA02C,C14E1BA9B4E81B7C,24960C788F26CD99,C6D1EEAEBBEA9C74,69BDE306A32DE194,69207EA62F3B0393,4F807F8CAE0ACD37,D15AE1657CDCBD5A,7080B85A167D4ACE,19FF976EE19672F5,000043C540C05542,573FCD292F476D12,8E6810111AAB8CE5,D62737FC7A508205,2615670146CE13D6,00AFBFF080F6E7F0,4853A9F3F0CE38E0,A1106CC32E70516C,74D61FBD5B6D5A64,76F04DC21FEC21A6,A8BD48796B757A62,0CAAC848B90FC25A,00003A6AF8859A98,F104D54750FD303A,0109E35CE0549B0D,4927EBF4D8C1C9CD,C32D69EE70F08765,38098E5F843FD0F4,7D83E0C149E312EB,3BDAA10B275532D2,106812FA413E804D,12C4E503BCC76015,22C130CE6CDE74DC,DC30BEB902BD79D4,000045FEECB5BA8F,7415BD049D12C71F,050C06E012F81238,2B7177F59BE0AA7D,2767F3CA8E72C42B,5744A797E6D9AB9B,872A49D2E3FFD50C,9DD7F162D3EDA349,94465CC2849C2E31,F439B7DF23B4503E,C03E5E79960767F2,59655D75562AE847,00002A9C0D0EA78D,336EA4AD8540F6D4,5750606A940B335E,EBB3168505C6B83A,D6355F44FCD139B3,349B37458393DB54,679D3674BD564FED,E74AA5E9CFAC2FD0,40B192CAFF19A3E9,EF73936E5F592B5A,90653298786A7E7B,AFCBC2902618C971,000043BE04E6E369,A22911CBC2BC9A1A,A3DB63611D9375EF,B83BEAE2348B1424,7AF5E97BC6474D5D,FD60417AFB62FC7D,C333DC0F2665DFC6,3ECA83BEE5EA0AB1,891A37EDBAF60B3F,C6DAD3BD46DA8D05,B15162F0D75B69F8,C8F3BE4A974A37EE,000012D8A1FDED20,1B2ED31E41C0A269,08ADAFA7949269AA,46D86A766F2202DC,4DE0963F345F30AE,EC15EE8B1EF04B16,6337FBC510E49377,91EF42B37A56C3D0,748BCE168DA610F0,1938C279820BE012,9B0F47C08013ACFD,BDCDA66641C3F177,0000175E3E239C4C,AC1DA4521B751541,7AA49DC20B9F2E6F,1056CBEE6E8771C6,D24CC78DB7708D94,07BF7557221EC66E,F19F9E337B28AF87,12B1925222D4CD9E,3CE0898EE96E185F,5775C065F2ADE970,8E038A146E20C29A,AE088815CDD07277,00006F739C430D26,3B90B9080D968B71,3B9679A0E48C3819,7B15CEA73FEFE19A,8FCDFCA9349CFEBE,F90E5F3BF050F0F2,E82770F6047DA3CB,A63E082AFA5BA228,511A25A9AD0D7108,6D112472C0B851DE,E3B4E8D57313F2E6,3DEF9DE667FF279D,000011454593E746,1A1B83200A0CF6D6,4864410617AF4E3B,09A2EFED6734F0D2,0F740831BF2E961F,F94DCC4E68FE9CF7,D5CDA4209D06E286,DC5B1C82DFD12027,7F528180E989CF82,9EC350C1E265A60C,A685938806D2DB7D,5237550188C7A79B,0000584EA632C1F5,E342E2EF3EB7210A,893136DF90F13FFB,458B2E217322C78D,825085099B803F8A,9BB44288538036B7,D6E35858E095D999,0A0D6F6A77C31E4B,B08277C57EABC2BE,6DC28BAF2E346D49,E45B51E8CFB8BDD6,CACF2BFFB77F25FD,0000210573A6839F,BCBF8ABC0F5E3BB7,1A1950CB86F134F0,7F9E0A079C2D427B,BE150E9BC921A7F6,C4921EAFEDA55E7D,644FD531BB563A2F,35C06F6BEE8ACF0D,14A10B663A20EC75,C2F641C034C7BC16,248FBDA897D3A418,1E85F66FBB563F90,00004A214F09DB7B,1E5836BB314F0678,43F3175B4F116CD1,0048632F8C5B45EB,DCF7C3AED50675CA,0447AD5292FD9EDD,4A0D8EE2FD02086E,7B63ED6F071629E6,02B32BC22DAF8397,DA3F78E2BF5E8B2B,13967318DC3D9B00,2344D84282D29A07,00000A1BBC83010C,1495ED5E66CF80F4,39B51EABFBFDC9C5,2B7494311EEAD4F8,85BC4B78C89793B5,F2897CD36AB4D25C,E9290595BB63E526,D1A270B4E537D245,BD9B37CEE99D9F41,9DA9E6027AA6F383,7DE129573D75A6A5,9F55EEEB95A8396D,00006B90DD50B848,A615070C91830AE2,97E2FE43528FFE42,D1C000CE9B21E871,F08B8153C0D3E820,6506E1CB0AEBD7C1,C8744DD564A2EC16,33C07112EA5AEF62,EEEDFEFF1529D081,A19F2973BE3F57FB,C1FC73209009F8FD,A007EC9B9B4D1EC0,00003DD4254B0511,AFF5DC46A3930ABB,E41D29513FC8B995,67C05AF6475D2BFD,226BDCC0D5929858,61A2B869B307BA93,A702329F8C9EB86D,CAAE88E21189FEA2,B1319CCCE2C68473,06DEC794179A1853,6E06A2E5601A5173,5B450522BC03D215,00006470EA062EC3,FB641D1860A91400,4A219ABCCF81BEE5,B78F37C8E3D06BDC,CDA5B7A5EB2A598E,F18CC87369073ED6,64C3C9EFB52A9D8A,699DEF4E3A38CD62,3B043A4C520CC7F9,2C232277CB50A08C,D3833E4A76BA238C,2767581C64475CD9,00002FD989678DFC,6C4B8BC35B33291F,DFD441AA64FC6788,B1F930657EB99D1B,15676AFF6F1C705E,B70ADBB67F4C8D7E,8126263DBA998B75,290FE88880B28EED,FFA3457DD9F51BB0,F1A94B499AA0C686,D5A555D7D65E7EDA,2B7A7166971425CB,0000047252C03AD4,0FEF4996C77F6749,4E92F6E6A2FA44D3,ACE7691119653D9A,B279F2B1942C9276,26502CA228A45D63,84844B3E4DA5C76F,32F6F421DCB52A89,CBA965F95864CB7E,A0796CE6A845C2AB,20BB1AA2FA5D3A6B,5C3B62E212262A5B,00000DFF25B4C6A3,E564BFB29F7D60AD,97C0938804CEB6F3,73E3F3C172F69796,F075EE13BA0D8A5B,46E603CC1CC7022E,F393407D2CBA40DB,13C113FCF4541D00,32357A0D1EF9FD21,C9A24B02D8FF5755,41E7BB050A39C90F,E21B264CC6D508A0,0000212751A7E3D1,BBFE66A0E36C37C9,9AB3134418B1EE09,C46827E9288B10B3,03506A35D5D5F6EA,F42779807DD5A52C,11417B219088A756,9850D82E1045CE3A,3F1726AFC75017D9,52BF6AF6D4338D45,4C9AEBF3B70A2F6D,E0FA385D54C1FD9D,00002D7A0063E0C3,B6F51757A4722CD5,C99463D5D842479F,62B6D4268F2CF9E2,821E63F69D3D1780,A3085E461919932C,E2BFA898E2097F26,64475621B66B48B9,F0BEC4F1836538F6,E498097592C92790,6DE07BBADBD89FD5,A253A01E09DAEDB8,000046FB24C14420,C6A2A44FBB4F9D2B,04A87E053A995D1C,0DC977F11416321D,63A287B9ED02FE35,D345522D3A226E1E,69F72A1177580A66,D16DC1C4F64BE70C,AEC301DAE37EDDF1,89815B653EB5032A,84D7E53B97D302D8,D8B3E134CE6B8F7A,0000442B9761A88D,894BF0E7CF850955,A7B394E1A9C6CB19,9735C0DAF83FC592,AE522092C038A8E7,D55308316B2B150F,0D3E88083C6C32C4,C505C6BBC9BEC887,6D4C9B065309F13F,C05DCB2EA2655083,146F1DCAF7A551B9,C3100270247E62D9,0000080F806EE279,7EA4C1C172EE561A,C2C754523FCFF9D2,4579DDFB5F78678A,4617E80F297B985B,C36135EEA646B74D,B428AFD013AAE8DD,4CB323EB19BC47A0,A6C25DEB745526CE,86C211669C0A8DE7,558E0D5AE3A0F4C9,CDA844E9E3C9554E,0000103A7BDF604A,8D259C088C484DD2,D0B5653CF2D1D5A2,55CF327C2B7FBEE6,2CF563088E86402E,0E4D8AA62D94F52A,370E23FFC9035385,7EB6CBA3CA02E94C,EBC13616555E6180,69BBE00B0FE2C7F2,513443A1D8084DAC,D0017813661D3C2F,0000442BC9A647C6,A9C331F3E0A76FAD,C518CF964EBF17EE,BB480CE29A9AA61C,F3EB0E8CFA1338CD,EBD18233F950EBC6,01F8F347B4C1888E,99BEF0C9B7D9AAB1,34A96ED7895CB3F9,331C210D432C5558,E57647F8EC2FC54E,28E3E92DE9F2CF9C,0000424FDBAE9503,5EE47C05DDD26C7C,500442FB468C6D51,2CD76C41B1DCA02D,B2A55E1ED383BDF4,A269FB3EDD42D86C,F134361F9E809A7B,61CF2DDD91723FB0,EE2CE1FC7D2912AC,0057B3D7568605C7,9EE55F0E776F6944,FE72B6E4414CC0B3,0000487B3E48142D,9F7808137D6A9B8D,10EAE547C4B5D065,63804CAD1B406F68,4E05848BE6F0DF3F,81D460720D7D47F5,D5EF915904801D05,4737005626EBB406,368D8780DD9B2B8A,B81421509A6470E4,23DC21A826D7289B,D11EF961FF1DB794,0000636C6A3ED2F1,A610CF522B74CBE1,09F1A4BFDC247EBC,95781ACC5E334228,EADFD81BB5C6B3CE,A9D08E7C5C4ACFC7,3CA073455F3EF0E4,DACE28AC9AA6B754,79346B8E75EC858D,EB0753EA6B22F80C,F6BD4A39F23518BA,E1FBE39C6FE73590,00006C2A06D4971A,81A531231B0C7EF4,AE6924B5292528A6,03B2F21AA021E09E,2157B89404909FEE,DEC39B5946F5EDF5,8D2E70EC2FEFE10F,C207BD49534DD359,0763222163FB30D6,53F002798FEF0970,0ECEE08F43375EB9,A60BC7C28221BE58,000069B4D702E431,3E098CB650B0D39E,49E9981D1E739BB1,D6C5882B403F1954,35DAAF005BA319BB,5897759656B15D57,3A03E74EA7979FA7,1AF5BD6020C39324,A110A4F5B6BEEE34,934FFCD73AFAA0E4,8C833DF14430EFFE,EF7D06D607F8DE81,000010C1767C5CFB,8D72FC4FD34FAF22,DD2C08B61FBFD334,F73E7807316AF940,7B0CE89B6319CF07,E5B56972CC14393D,8B5A8E4171E5E880,D00A652F5577E7D9,333C41A14C8BC0E9,EA66CDF6ABDF3983,9C79BC3CEDFACED7,3DA1DDFFACE73A6C,000009DC92A7A906,69611D949A70DDC8,0A1BB2640333B17D,A222F19C8A2274E3,F3A7C430FE9E1F28,FABABE44E33D5870,C7A778F68902E41F,082A4FF04862B47B,B14A57950BC54166,7B2483026BABC68D,55344510D5CDAB6E,438B5BFDD85D3DC1,00004FA573BA77E0,0A8C540B29D94C4E,6EFEC270F9981598,36C31C073FFCCB2F,B2E4205B0C3DF148,E2D9D02B5B243E06,19A2EF23910FF885,2A057A23D4DFB66C,8850FA8A9071A19E,67D040065A247EA6,58150DCEBACE66C9,DE04B21D537ACA36,0000060E0EC6C3A0,859EA5A11CAAA025,5BBFEBDC0DEB2B5E,3349B7F4049880F4,BE9B16774660BE8F,62F5F4BED7BF0ED1,07FB5635D774C877,3E0BB1607771A49C,42A13ADE3DD856EA,C67299E386ED0B97,AA8B48C030AF07B8,1D3A8AA21C9B295C,00003E0411EFE000,395513B5C3762EB4,2FCDF7AF0768765E,E4E697709A805215,DF4BC2A0FF8BE1C6,E2B0B320DC45F0A4,3FFB2DFC72EC4608,A5B5C736EE4B88A7,9D41C6828E4FF58C,6F96F9F1FD7BC971,F3AC3FABD0182011,FA1B7C3A86C4392D,000051DB91B8333D,F5C044502CAA599E,E3D2D9BC57E333F6,FA710470650D0F47,BC5523BD2CEDD48D,7DD8902033B38880,0520B755CA985608,CDE02E5D3BB6B0D4,217752670BD50E92,260EC0F4EC6E34E9,D042775D57B38630,C5AF743058628184,0000619409F7AF86,D66C623B0B2B7003,518928AE5F28F438,984A9473E5B6CC88,C3B56C53121873C1,0BFFAD2BE09087B3,C62F98B1A6D41E2E,EDC9ED287DEAB42C,83A83792D5C1FA20,C414CAB3E5E44D31,73C7D52CDEA4CDE3,FF284CBFFE85808F,000022AB5D89DF16,B63E6BA11B35D4DA,E7973406069FC1E9,37142121558EEBD1,3FBCE0B20CE72C6F,79A018458642ABA3,1E455B46561F7020,E64627224EAAC28E,D573FB1DEDB0CD78,26EE2036142CC9C4,4FBC46F9B72D2F4E,A3FE4A559A1B7C13,0000419D5F263B25,C10D1E25779AE0CD,279955BA6A10FD1A,F680CA4340018A35,F7730D7AD7655507,683C6E2BD54B03B4,35BDD975BB58E65A,0820C4F1E823125E,8E901EDF2C779F00,FC7D9870F4B7EF46,932D266EEFCD6D5D,905DD45E04C85797,00001AB231D43162,6D4B542056F1433B,CE01226CAC91DE8E,74154AA2FF01E682,35677A7A7E0BB8FE,788844F663634BBC,BFCDE5D1BE6EB9F6,B3A57B7CD026B685,8DED90CF9DDCB385,BC476B3BAB11B998,1808950691E72451,268F383F1CA2CBD6,00001DFFD80D6628,01BEC14A8FD9B5FE,0A49CCD4A6E1187F,44ADF20C70B9BC00,2894FE6A28C56210,A051A4AAE72639D1,35F21F66465A2F1A,9E989165E985E54F,A48E33F71BD89B68,241AFE33002DC013,8F62FB0E6FA4631E,4E1B77967F803F01,000015734B0C3872,9CF8B1E6B0BE97FF,F642A3AB48E64EA3,01AEBA603050E437,567513881995F26F,3478D53F26BB7706,FB1B6401E96B29CD,4A0E35DA59256DB5,B2F09EDABE56F607,4EE886D55076DBE1,B60B71F23576B546,1C98CCB8CCAB25F1,0000137BDEE9235A,388113637C9AE658,72F041C41400B41D,8F9E230714987506,764FA03CDA24F468,129B6332DFAE2C5A,A0F12813F4658EEB,D2469EE08C5C41EC,3DB73BF62CD938DC,AEA48B506C68D9B6,9D3FE110443972A2,7E1484768203297A,000018C6ED49399B,482FF0C7DCCDD46D,AC9144102E911237,54A672A5E2E0A2FA,10F2F5DE71FD0033,C0984B978463217C,605A72D78E819CF4,5CF74290880251B8,D38B050CD99F59B1,37A2AC5B0AA14945,790FD8A34D6DC1C3,9D3854F98EE7DEA5,00000F27946E636F,337F259753CEA4FD,F426F24DDF8FC799,4C3CAC21B116110E,5BDB645721639CAC,048DB28FD788B7A8,E0CAF67E4EC52F21,CB38C6D953F1E55C,0A4F6FB44F323194,3D518E80F9F0C0FA,637CB1FFD402EB65,BA8D495E628115B2,000022A686B5B159,54BCC4F188124C9B,FEDDCA78F1867B51,0805DB4D799EC04C,D694D701F563DD34,A7DA5BEF6F2B89C3,7FD08F6297194556,B31AF3EB5960F767,0071C4CBF3C21BC0,B76F2F5185B77C8B,5B80A563564A806B,3978E9F9D6793F97,00005846A6E5B36E,38406554FA4B480A,E89AA2125D13B5B7,ADEB2DBDFCB20020,A91E1F301B6A9395,CF461354750550FC,F773A176AFC9566F,AF114CC0EEF9D62C,33C3DD8C303D52D9,2571545068EE9D5F,F59623C5FDE81EFE,0A2FC1957BFE590F,000017B29D8D29F8,66BE8D0A0467392D,6B10FFF3DB4FB5FE,FE315FA51BFB23EA,CE043876917BB8CC,F28889124E544902,D41D3746187AA1A6,47923664E406C439,DFE5B1587CE40A90,D4C21DB35413015A,8FE6F407CC82EF8C,F45B12C75EA8611B,000015066C88814A,6CF65F21499E772F,BABC08466EA324C1,0B7DD1C85422F8A7,948F95386E5B270E,62825C8418DC90A0,05D39E035D4C2215,FEA04A874259A7F6,68AF2A2151DC049A,3AE598535DC64677,2CFF61D20F1DC036,6763AA803E355C59,000068AC2F6295CF,3FD5737676DB2FAC,6A5FC2C25E84D20D,C8D6246647365649,D4EF429A439E0038,BE1ECCBE5FCA04EF,708FD3B21E1BDCF3,5505A17AD210AF75,7363DF63D713299C,34C76F4A3B22C326,96C6708926DC92B8,BA57D0AEB95D593B,00006BA9ED8E54C2,BB3FECB35DECCE37,C0768E6FB2CB2216,A9B696664AAC7186,C83469834038CE39,4F231DA298D0E1A9,28DC52D43F8523B9,90F76689F8796460,124A5EC7EB6285B5,173B64CB4549F1F7,616022D4EF0430B2,A3A5D2CA38EE6270,0000296A30DE8FAE,A1C8FACB6DCF1241,6CEA8827C1EE6948,22D6D6C882852FFE,8B6168DCF4409A7C,56CBB233A8DFE686,38D6137195333435,67491D44257D967E,EB502407D9927109,7018A56016068269,C85646B64C84C134,DFFBAB5CD751DC2A,00001B04504BD768,BB92C225A067F0AA,C0B30B03980245F2,AA4C305A5987A866,B5C0821E9235F73A,D80C5408ED4408DC,3F7BBF2C5C4653E8,7781079AFFE05131,EA80C698C726B633,A8E7D3637319BC54,B07ACC0A14B8CF54,6A763D73A9419F52,00006C57ADC5C5C9,10E328232D4FFFB6,1119BFD47BF5D5EC,8BB962F8938DDEC4,69BAF0ACA843FC0F,CC07CAB2B09A87C8,8D027D9BFC167028,2B37BEE44BDFD5AD,FF69CF79462FDA07,D4EC75BB4F312885,03D17F36CCCA4B2D,B2CBBD0774219891,00005609C9085CF1,3F412E9B87E9F083,2D57195BAAA6F671,5FA9F9CC70CC204D,F9FB6680C2EDCFAA,E7A8D377D9611E67,A3FA756286DACE06,AB7B2BB920990011,092B3550302B9427,58D9DF4B4290481D,412844385F2BEB5D,A42BE22E5FBF4BFF,000030823578D94E,0BA2F81249777BB2,99FBED250B71C956,40357541E6DECB9E,91EA2EE432BE0692,1E9BD3365C7714CC,F88B3DDEBEAF17A5,97CE148CDF7111EA,E0E2AC75526C974E,5CC5AE522F7EAC36,52010961C46F3983,CB11C1717301D27D,00006F2CC3A01ED9,05A06B33C61F9C36,DB4A0F429083BE1F,E26F6EA3F8B1D9B0,04FB970722992637,DEB25FCA7E0E2924,4439C299F2BEB076,F714C12488A81863,5F2DB83AE7393D68,790D54B37CFB7FBC,3BA60007509A1152,76AEEE936DF75646,0000155CD7E9EAE4,D1996C00D49611E2,919889D962128927,17E33C5350996128,97B9845892BB1B7F,2847585A738E83A1,0401F0E2AAA2FBB2,6174B4CFB8637585,95D3E09A5B91689D,39C40570A4744150,D49FD7590EABEE1B,521DB69B2E3A610E,000058BE32DB6DCE,6B8B57C30D27860F,2582B156F9C36CE5,A44DD7078924C658,B456C1D4CA9265AA,748456E27BC83B20,9FB392B800D49FA4,B2F4753C2182448D,581FFB77B2385DD0,6F521C9075446325,C668A59814E059A2,55E4B5A83A27E8EB,000069FA609918C0,6929CC00B21B47F1,60D77769D59AC7A6,2C5D0866B1F47212,2844719230F793A5,7ED367EEBA6EFE5D,5314FF66126F5728,972074FADB34FF3E,FE63B9842E8D2D00,2AE349815C05D0EF,5F55EBF9720CC267,A58879463CB3E67F,000056B15C30A00F,FEBA10A96C4D701B,2117A57835284C0C,DBA460C37FECC223,223ED26F8399E53B,D2A95FC65AE0F0E3,0C48D78FE1017427,E94D3DAE09D2DDC9,3D7F4CFC47DBF2BC,1C9B331984C12382,666FA7B6063D6735,BF9F018448D2D8DF,000030A4FB39ABFB,4C2426A9D02C08CE,B5C8410C10C44589,18A2C6F35703BBF1,741B5A66BAEC8759,AE12024EA8F4BB11,754ADA911CA585EC,D7205CCF163B34AA,8E336A4DBCA78357,8595DF0B0FE8A811,A35B0E4CBC0C62CB,1C1D3DF07CF218D5,000031CB7E6DCB2E,3E705351C0B475B0,B3D127E547D7D2B9,C2C1807C4C808801,8D24F41BC5CEF860,EAE7C55E91900A63,D2E4E4DD81DC5157,A1486045A596C65A,9A3D26200D30E700,31BF9EB5AA431028,FDCE16AA3DE63763,1254E6CB37E64CE4,00002385DCE12532,E85BA6328E7DD25E,416C9C9BA520E737,60932D4552922457,6275CFA0F45AFBA0,1C3AFE9D54270D91,D4885F60B07D143C,8D0619801A6E53F3,DA9AE3824CCA74E8,B186D532657E6EA6,163917D1C3B432CD,177048395A51BE1D,00003771FB8F80B6,7AEA76D3F76A0CB7,38194976FA6981B4,054C1D981CC2886B,2ED0012A47A77F9E,80753D5416995349,CEEEF0F296A540E2,7763E322D86E3076,031045FB8F5D2801,1376E1E99106482B,F9AA264CFE0FE724,5407046B4DDFF182,00000A1F5957EEDE,15A0402621A77728,3AE46A18BB3157D9,53170F8B640DC07F,273CF690D9BAE99C,4ACBEDCB351E6208,87AA467154C4E0DF,680DC1A47DDA1A7A,BA6DF8918A8797B9,9DD5F2E8CCFF937E,5727F22ED6B04B58,8ED9BDAD391DBAA4,00001E0E5A155DB6,5B7CA22D29C9A477,A26F76D61B4D78C7,70388E76253A63D7,2FD6A175A5A6C3DD,B9E3E8D844A37B7C,DDF4E497C41FAD91,F367E2DFF0B6FFEB,A7D83D1F2850570B,AD47CF4CF7251CD4,5BC809BB04742D70,55135D13B04A0E3D,000016776CA96009,8D711031C6147C69,17683B3F0364DFE9,5D912E2D62314D6B,2CE801424937FE04,06A8ADB7F22065BB,240E9D94E1158934,5E81070B81CEAA14,620820C589FDB7AC,76F01E5125EDDF67,F2C67390EE081D29,741E681ABC59E415,00005BD0E3A0B8D2,0DFD99682CE55600,41A6B6BF4496AEEF,E537D96F6AAF153F,E9B3263A1630B158,EBF51F4DE21A95B2,F85D8E0E4211A202,C0EBC5D0820E19A0,70E80A4C88597737,2985D7D5B713DF24,23EAC318D814185E,15CE2696874E2F3C,00002DF4A05D2268,F936DC40D6BC40E7,5F38D46EFE3B1FA0,7093666661DDAAFA,9B46D6B6BFF1FA1D,91ECF6E7A4655884,81EF4BA1F6F0D80E,DA6922F445B5C247,3272625D4BB6361B,9A0D7CB24F63668C,1E8D03C17B313342,3D6FF74153CB8D35,0000448D053D7626,AD3176E63EDD32E1,54E9ACB9F1E3FF59,D9A08E654D6E5209,D3F21779AF623272,FB564F9A9542BAA5,5E2828577208DCC1,913ABCF6F205F0BA,321F5D519BA3D7E3,C75F026287167B3F,0A4521ECC27DD5BA,C03050596374C2D6,00005C30B677E6B3,B02B7B61A0A0F6E3,75931F80E086ECFF,29361F400C0F4004,FDD53B2D62D0AF7F,FD08E948B1C369DA,0646A5777502A2F4,52310D04E9094C91,203E385856C1ACCC,16B16844A692D342,7203F56CCA07F036,77C58D54191B2B1A,00000A5F76DD36C7,80B79EBB91D62AEF,C8D4F5BEE76731FF,D63EF26E3183B420,3DCF629C09902219,5E4336B2828C7351,421C3C966753B62E,6A121E959707D37E,A32FB92B832C1FEC,559658016569D62D,47E9283478805861,0865B27CC4E64EF5,00000CCA9AE39715,2CEBD99B3AC7DDCC,C28F743D80E25F55,96F7531ABD5DEB1D,F2ACF8E73304990B,ED9E974389F868B0,5E11904FF89FBDA0,4E25F2989154E7BB,58760D19517E0E27,E80579E51853B1D3,D8D8CF83E9EE25D3,0CC9A523AF78159C,000040709322B0C8,71BE5369EC556CD7,E38DB8D0D7C6BB50,FEBA4EF928D528E3,F2B94C5375BF3F72,1F319086C4F2D7C2,3FB01D1626E0A2AB,2607E09389A318AC,A0836579019F4B46,5F514B1323AAA093,7518E7338D7F75C8,B584E216CD348596,00001F6C09EF5533,CEA0285FDFCD5F33,29CFA1D9DED71C30,1D7A81C25279A2C2,D70C5723A7ADD4C2,820172668BD0A62A,9A1D7BE3E2313FBA,755968FAE9F13F2D,31BB6C7EA36DE00C,DD5F09C6612134AC,416EBBAB8A71A3A4,F6397D83805D458D,0000360869E64B88,9656ED61D7003900,DB33832064C56781,39541EBEE35FB04C,0FAF2F287EF6071A,FC58685638EBBBA5,6583D2114592FF0B,A1C0141A70ADD686,39BA6FD02AE3C79E,9525C26CE0EB26EE,29CBEB906069B25A,DE571AE26FC764E6,0000450A1096706E,004AB2E15B862B37,222D01FC359607DA,726227DEA4839187,1F2536FD2BAD2B38,E4ACBEAB895597B4,E13D830CD45249DC,D858F53C0779F065,2E1D50B45E5A8D51,E9F9D4FE9970D692,2A88057441390502,8022650F13180DF1,00000DC7BEC6A903,9D0BA95F0A938E9A,7713F27CF3B52D90,E56E5AB34319AB1C,40D2F4B884F42743,24B79CD94DD46E0B,E11733EBA2BD5711,F33C2F6546033522,75B497195779C002,AA9F17BF4AA66D55,79C711A90C8CEF86,E6562645F9418366,00006EC8353198E1,FFA61A1E39E2CDB5,05D40DC25CA09AB7,7EBE5B79F4E8F9EB,E775D3C94DBEF0C2,26017E2BD143BA9D,EBEB8FD6470D358F,1007EA4DF2DCB94E,7870C6E1683DA3AB,98C7F01D704B248D,8D90AD4041377939,2AB7ADF233CCA2BE,000043B2A62EC660,510EDBBAC41FE1E7,64F3485CA2B5269A,D1EA3F19E7590377,59DCB8A741C40B10,D487AF373EBBFCCD,A885DABCB401C0D6,C4B3DAB003DAEC71,4C81AE87AFEF8DDB,2A526AD734D1426B,FFD5C9835CC47160,526D9F9EDF2F0024,000043E54E6F908E,B1A20E295B8CA53A,4C78CCF2574974B5,2B35A10AB6A19900,B9F8837CF2A3E305,BE7FFCECD1F4B5A2,5C63CCC25B0EB619,8148D7576EA0AC82,192BA963BCCC5EC1,1FC62E8502F33AFE,C4B62EDB4C005A57,A7F4826AE33D2545,00003328D8D54B4B,F124504E3D3A01D5,61EB0E49434FB058,0F0A305CFFDE4182,5FD82BAE88BD5E17,F57C001E4FB309C5,DE63278DAAED9177,F3C533832E358DAA,511362D150A9BA48,E525BD7367997221,D365C6241EC7AED4,B8B0BE1F5E6E2B3B,000000776F8380F0,C4C225E3A6C5FFF5,A053058E264B8A74,0A69AB9614B6A54F,A66981250DCD27A4,75A594434B531A2C,EDFE8C6FCF9DA0C3,1E9BE6D3FAFF491D,A26FB8ACFD1DA41A,1120E2900E5CE7BA,D7DFF3890AF1F8F6,874CE6796B5B09CD,000010A71BD355E8,06E97959C2D29492,78723C94209FAA56,DA4DC67D0AB6EE7B,6AA820F9558A6317,F9D5A5DE22741F09,70A15C4175FB9268,478AF77DEDC65C5B,6562E8187C1C6954,CF1FA32382BB552C,5EEA1822A99B2EAD,4E908695EEE41B26,0000254F3565F620,D90D2154DBD41CDD,F033B88AE4E5D838,7FC36E6CB90689DC,463E07074021B7DA,193165D026623A31,5C4D40DE32570636,CDB24E4E36487E56,AA5F24B652AA00D9,50D6A6FE83F5E0D9,AA6DD8241433B1B4,D4F44E651A53BDDC,000040363052F87B,A07B8195E80175E9,6D3DD91D1B0B5D3F,5CE17F2BAAD12382,8B810DFA6A2D0797,EEC81769BA708934,6C05CFFB1FC9DAC9,7C75DEC7577CD198,EE0AB60F9F17DA79,72A4E70B147FF061,B617505D634C9E46,5E7C3F33D482C1E0,00005DFB185253B8,CAE931E9A15E2329,C473842C60373196,985A148F8DFC6B48,BAC005CA55848633,DA069CA3C1854A8B,5915718BECC16E40,294EB85EF6807EFC,A96C0D4F4B8DA51D,CD6A6F2F5F9C81DF,F41E3917F2B599DC,079E576655A82A5F,000014178DE8526E,704B22F3E0528D26,4E47EB5C90A43A48,DA92521D60C9B716,C61ABE1F19747CCD,DC2CEA393404E8CA,60FBEB716B75C457,2F4D998FC2665F0B,01B8BDBFEFCFCA2A,3F3DB960CBF2623A,7D41233EAD028CCF,810696C717307BBA,000011DAF0CC9DD4,867CE83C348F5334,2EE0CF4B34C5846A,0ACFD13F8C9674C6,2097134126A21111,6796EDECBD0CE54C,4422EFD7ABC3C43B,7BEAAB511123CD1A,7AE7ED7D1F3BE280,3E72C24B4998B51B,F67C4EBB025B24BD,B4DDCE7ACDC97A11,000056E6B1DEEF99,439C7859DE551F3C,F6874F28728CABB7,EDFDC8FEE74CD17C,B85C37C5E92D36FD,657CFC688A09ACA6,C928DF9A36168CFC,28B3590AD2E0579E,3F84C27BD8323FAD,4BB19C889828EB51,FD8EA01A5845B76F,7DFB6512F4042CE8,000003D23E689436,B5AC0E313F3CD982,D93056AA6C247F1B,473DDC3FEBA307E5,73E27A3B20A5B727,0B47CC9C5EBF1CA0,FABB9D69E3E256CD,D071B80642238500,5E27421C6D1C6DFD,8F4A216AF6187858,60772AE66DE43B34,A83B97B205034F27,00004837A5F4B491,CAA6B5DB5975BDCB,3A7596A12B25A279,D54D50FE6D82FFC3,D9C43D53BBBD273D,7D5E7BE326E1D683,7FC432479D0FBEEC,0D16AE7D47F0E464,4BCA62FA79F4ADC1,3557D54DD46807FD,5AFB7E1A2F2DFFD0,DC668AF024655D5A,000052C89531A8D9,852B6CC3C7AD9286,A9A2624A1DFC3BD6,E759A9F107086271,640D6F5E87753828,ECAFB6ECCD6410CE,F57546202D6789ED,EA529268F8D8EC52,C927E3FB94D8E0D9,881F3800F09ED1A3,EADCA5FEB15895BE,D7021DBAAE0DAA06,00005D75C516C3C8,8669C5A778DDE1C0,0F6402639C50467F,9ABAD1B14B91FCAB,FEA948BFCA8D8AB4,6FCCB77FC57332C6,6E7F31093FA554C0,EA8A7748233E2F17,29B6DF4FD9F3EBAB,DEF0455D9CD95960,951A8C459D26E964,9DC2972F2E640852,00005753DCB79082,3A696D2D202B4D4E,DF2D25A1D5A89386,64F6ED787E4BBD6E,A735B524169EE295,F332E7C2DBEAEE58,6526E9CA25437680,7D5360A5E149C482,2D53BE5D3A0AE583,64AA8C28F46D36C3,4F748EE046D58604,35A45341E4759815,00003449D4543ACF,03324683F50CB44F,5F6C5717B4E0FC50,F5C902A8C9029B9C,1ACBC45EE1D1F5D3,9C60FAE7BD9CF96F,B54626F2AD3C4CCE,9DB05638702B191D,1AAECDFD77315759,90F638D99D54BDAA,ACA4ED510A84F2A9,4D07037C360BBD0E,0000455A80CE71C0,B74F2C254019402C,A79295256393F6E8,0BCE419A76BE8D27,E8625190ABB9B699,C4F7E8ACEA621125,E91A1427700BD0B9,4D9227979C10024C,300F167E5B0BDBAD,1B678B0C5FEF68EC,E9FAB268ECDAA2BA,F0B0D2B67369E9F7,0000437FE86830BA,A19B0C9D13CBC1E8,246D824F674D02B3,DBBDDDB6963E9279,5D79D40E815D78CD,B35A338C9D303FC3,E29514669D333498,424C60014FE55056,C529E2F76F8DA25B,30BA5B6EFDC3B17F,1FFB645B5A067B2D,FE3C9490282960DC,00000F4FF91E1E61,C64137176951AB9B,93F0C4F567CE7C01,0D3D61C43B1D13BA,FF5376021719451B,F6241F8225601990,704EC0BDD24B0B67,0CC6987CC84AAEC1,5A2436A236814256,53FF7B852ADDD724,72CEAF7D91D7DBEF,0FD74DB6D23E82D6,000023E03C125595,C950D60D220952DC,1C691CC3C4A36E44,40A0E4A39DADFAA7,5562CE09BE73EB4E,75C3C5A052C0F6DF,1F68EB1694636AC4,831B99D1E1D8743E,70F9AE52A1ED3594,C2BA452DF8633DDE,71F2A4645AC1E8CD,E88F5F3E23ED6C5D,000028053359DA27,C8D93433C1C43FEE,B1E5876DC801DB76,A90BBA6CA38DF383,134435BFBBA81661,90EFAAA7AD870060,A2A9BD30A592E00F,55C70DA48C91DA0F,388F96561AD9BFA6,95E5BDE427F8B8E0,186412D3D17DAED0,F532C9338D0841F4,000023D96F5DFA17,E3690D21286A3960,F98B8CA3AAEF188A,5675520B65027F6D,97101B2A4C13424A,3959B4958ED3615A,189234E7B93A88BA,08B41DE1C315411A,307D0B86A1A5D682,47C807F6579D5055,4B60E17938864751,3DA9E9B7EA425578,00006F407E446F03,77C08D5A88EB4E49,DB503F7876CAA696,213226EEF8119568,0BD122D91B485B6E,DA82F248FF88EC70,4B52D2112FB9C033,17987A21AD7B5561,0B366F2CECF67724,137768775FC84AD5,220D800DF4822A36,02109FC48FC54181,000053F534487A5D,B6BC08EFB93E7EB6,2723B0022C9B2623,8CD513AE2A6B87F4,1311C552C5E0C872,A818C3C9B02F7C09,D24426C3BFAA880F,5B955C11DA13D390,8A07760C19134BA5,7619D0DE0E436850,414801D7FB0A1ADC,B3B7B0F9638357BB,00006457014F9FD9,E00DF3F3E29C83D4,E3DD74BEBE71A0ED,CFC0F7425FDCB2AF,03396E99ECB4D979,0AA4B71E5E73C53A,6D8ED07E9339F832,55072028E76A46A2,E0E76E6F3915B578,65B87A4BAB71FC43,0FFD1ABF7AC25B0B,D4F53F2C34D9B0E8,00006D4E736C7B96,22BF053ADE813937,14EA626A40A10671,A9EDCBCBF37F4F25,095C520C01A7CC0B,8B20CC14507AC13B,2BD4ABB77DCC81B2,0F85B1068930AC57,D72D3B1AC772EB07,2C432D7E205FFCAA,7D59DA4F19ED11F4,881EC5C53FF58565,000053DD94E33049,20DBA642E53EB49C,4647253AF1982B11,0FE89B9A1EC8C42A,C2DA22332E659F3F,FACF7655E24FE77B,363220D7507C8BE7,E10BED971229E1F2,2B132E9C19A061FD,CC60ECAD2C75AC85,BDA239AE589A7B07,D60A47F1AFE5E48C,000028107559575D,CED47DAB5F13291D,FD3980816FDAB054,6D86764136F0B9B3,FAE3A3886B792BC2,5056DCA8DBE8CB39,5B049FA6B860B433,E95D2924B510463D,5D8336383B672D2D,6F34BA6CDB80344F,D361E60506D6DFBD,7034DFBBEADDCAA8,000056C5C8FFC160,E459ACB132FDE76A,24E14B2253B1E1D2,2129D582CB1F53BD,D16E767BD37D94EE,BE88DA31E3480649,CC258901A68D4E0D,14984947B7BC0124,88E6590E58D8417F,2B40B7155CC4C912,87C2FFD839D5670B,4A3819D30EF91BC0,0000637819EC4EFE,1C498F5C89DC35B1,EB190F49FB2C14E4,48F2F080409D11E9,462B8BC5D53C2475,F55979CD90669493,8C53D5D28E841475,085CEEB2BF1F1EFD,DBF26D0A48B8F826,379C0DDE4E26C449,960A0ECCD1A39982,782F1732194BEFC3,00002115CCC68B27,FEC22FDC0497A31E,F2DAC697998E9B19,FCD5D7367E9C201D,194341BFE12E89C1,75DE5036549695E1,14D41D64142FF517,BB65DD42F3D0E04F,43D743F5403777FD,A2FE62C8D3F1D4D3,BB2587578D496AF4,80CACFB402213C84,00004677341135CE,B0A7373111E2599C,224417A78F899ACB,AABCD3C233062C83,1508234EAC6BE739,34869212C0829C4D,D68CEE1FFA2E060D,8CEB23E5BA6E10B5,9ADB2EEF7E827026,72E849B304139C43,8DEFF8BD8F469587,C89D43C13042C6D7,00002985145AE232,0E2866D6F60A52D9,27533B50B5B6640B,B5780C2EB5A668A0,8BA6860FFAA76373,EF312FF51B1B5611,4A6BF612CE22E297,47C840026554B00C,B2F778B02B74C22B,6F87A7F916BE62FC,567955985E7D1555,628CF9DB04952C5F,00004CE249F09678,A95333579A410922,C4EB0967C03CC58B,6DB24E4452C93CD7,F73385F785E1A3EB,1551A1EA16465068,8FA173B6833D386C,A2C08922FA631636,2D2B0D8FE3F2C419,A1AE3E588F0D8AD8,5FDEF81ACFA219B6,5BB170AEE3B69D64,00003D2CCEC29D29,4B44CAE7343438F7,E4C5A1C996F2ED7E,7F506A313D40F8BA,516DF0EEC2CE7F76,37510F6BC74C7982,D6721A25679D8B72,E91521E61C6E1472,C2D73F385795A86A,7B168B2500EFF4DC,6DDAB6D476885929,9D0BCBEB86FD7E6F,000053D0EDF3EE09,443975DE81C3B0D3,ACF298D8F0361591,AE774AD101286514,12690950E818669C,5236E9EFD1415FF6,DDE8DC1C699AF847,61F0A211309A88CF,555BF388FA4AF183,D4C28E93DD776AFC,38EB01C34F142E4D,A75E357C4E8A80D6,000003FBFE71DEDD,AA572B3274B20F90,786D8FE4EB53BF7B,A7AFD9A1EF1F3527,23E2B95A826094FE,D36B6F97BEB548CB,359099D1E4F429AB,EB27239AAEDE0136,ED4C547F119F6962,B67E33D5030D50AC,F275138A2D80F0D0,6AECFE09F4E7624C,000012FBDE2E732F,27CCC5706B639171,372B8337AE194962,86805FEE5BCD62F5,E21280692B4A802A,53D1B1A0C2FAF6B2,F91A163004F9CA9B,56A0AE8178C43B7B,590EAF639A6A2D67,1B86309B50237A24,B5A718FC6E1BBD9C,9D6A0F44C3357BF9,000006B704991874,E44FAA204DDCD39D,13E5E2512E29B006,9D5813D192BD5152,4F4FA0D64709A2D0,49664EC990367882,5F415C799690FDD0,4083AFEED83D6574,B53C77652BD726FF,7D29C969BCA1FEAA,DA0A130AF30582CF,3D8C643E658A866C,00000ADE492604EB,A330D95D051AC009,105E757F67E631BD,8E99BCAFCFCB91DD,A1AE9964F26FFD23,9A305C328C21EF38,33DB35C8981B8F3C,2B43908AE8F3171A,D1AB3CE0C1A9FFB3,B467F39DFB2D522C,DE9453767ABB4FBD,433EA7B102FDC9BD,00006B246146D3A8,3EF4D50ECB83A28C,BE37D502D39EFE0A,CF58157DE905E327,636EB785CF84FE3C,AD25CC0448D87704,CED7250EE3E78FE5,A95364DB53F04F95,4840E60E09E00448,E251F1DEC7EE0325,9EB5AB3DFE0CB677,EF131902662AE208,00006AD9FF16CF29,C1FA97E864E07275,5DD187BD72A5B45E,2AA8009993AB6949,6F498115126A9E8E,76617AC9DEC24534,4520195AD582E38E,B6485D3A2888003A,323D463CB80F4FA3,EE4FAA5486805EFD,6EFBE3D43F16B602,00BE4460EE3AA402,00003B1D1AD3F173,276C7EF4AF59BB5D,B35F079E6FE11DB4,0562246B752F952E,00D309ACADB0E3BF,5BCA136F6D9C0A2C,4AAB809532C6C281,8C3AEE0BCACB6A6D,D8DEA54377FDE503,D2D68B76FF398A6E,1F6751E8CC9D37C5,92A41B6654E0166B,000035EDC43058A3,00732FD33FE7A3AB,69A2FD5630B058B7,F9CA3C1F702F8955,628E43171D8E0C5D,AECFB8CBA993F360,716716D45ECBDA4B,233952BCBA1B5021,0A7282D2988C24AC,8CF517F9641E023C,92DF4852E0EE37E5,1B06739CDA1AD833,00000579E17A92A6,AF26166D52FA8335,B25E32C7D531AB01,2007974898346592,8C99874F1C9237BF,F4C4F5423AC08CAA,5E91B13826DDF5FC,B919D22701CB7CA8,9EF4F0B0AD75ED98,5A478E807238ECC7,1542D4E292EA56D6,CBEE79F9EEE73EF9,00006218A751FF98,701C9646881B2E5B,E8893311BCB9D103,B099BAF303BE86C5,194402B39FBA18C7,0666503460209A2F,B90D0A56FEE6DC74,CB48B5391EDE9412,8E57D61C310EE197,2E0FE13DDAEEB104,7E34FAEF04D42D23,871F98B9CEF21296,000014A7F2312FBF,8AB2C5B065270659,E843FDDF81D815D3,76836BF77ECEC1A3,15C1BDC2D6C060E9,EED6E3A962297B30,CF846C1BA7CA9458,2FC7BD3A5E08EDBF,5AEA1CB9CC4F5C83,31ADFA10F99A10F9,AA4F4C7C3E7F9465,2DEF239647D5B439,00003F89848AC349,6963E386F06E1E4F,7D9A45500ABCFDDA,F7D01FD6A47CA079,79074D923386D7B7,010A52B4037A7F41,C7F89294D6F788D2,F7EA98A0D0193F63,D597ACCD68D2FFF8,472F0ACD22B2C464,50AF99B5894B5898,B28F08783EF6E815,00002CEC023DD99A,98B2D0D57154175A,C1F5540C7B37DC32,6EA345BC698E44AE,0B9DB15B8665D220,D3DDD2930D48A721,4E507E9E5B957656,C09930D0589853ED,1542A0CD101E94D9,04A20D9A7DB53D6C,BA57B7F941479D0F,FD5AAC18A10F48E9,000062CF301D94AE,5AFD10E06F41EB24,9DE06775EBF4AA52,8F2F8287099CE27A,72924387EC25D762,E3917EF7D00A4B3C,4A003B71903F9B20,38C4E5BA4563496C,34D719BD834E0E2D,1ED4E85714ADDD48,3C765DA03FD55B42,23B2168452A97C8E,00006D7224FC56A6,33B0DAAAD0925BA8,AEA98DE74CB8353D,65F36D0671570695,4135E09903A15A8C,0B9484F806B62CE8,9AA20F9933CE2E3D,B5B8F068ADC0B562,26FA55381FAE9FC0,1AD34EF7E25098C9,863603D72AA42B16,BB14FE9045F10EA2,000061593ED22F2B,0BD792EEA04A1E95,9C944E9EF6C53B93,E8A218464B85E258,8095189AA9B5C04B,2FDCF790D6AF44EB,3C019A3159FA3A6D,FC396B356B095924,456BA93A7D8B6BDD,E8E8B2F0C15780B1,3D2835D08594B5EA,9525E812791829D7,00000E34DF7215CF,F377498B0E607C87,472E3FFBBC6D6F31,42B217E725463BAA,E11CC82677B7D06B,B66F52A7934F977A,B05B84545EFBCEB0,BC0D8290979E067B,A695066C9055C751,6AAC063494E4B082,A56A1223C7BC6DB2,3F8C57749902F7A3,000065113E588B6E,4F9BF60F99364AD8,09C7D03907A4FEC4,C39D50E6ACF815AA,AF65F3761FC5389D,127B09B07172CE6E,CE29810534D3D958,638C4AFF15E5FC47,208C88968FBB5592,498EF2BBB3FD05B3,EF09E9E2BBD26171,B1902F6C9B245717,00006F504468ADD0,66DDAE3D34790799,475122DDB407BF42,D15F6154E61F870C,72A41CEB32D798D4,0074AEBE18C5ED04,A980DF118F08F4BC,0F40EF9CD0FCFB38,8AAF37E103BDE836,3BD60AA32F1BCBB1,B4BA6083855B2172,FD8F76F59C014A63,00006A692F062138,7D8FC784E48400C2,AFFED52CBDB75A42,34449B9F5A70EF8E,8FCD1D472DD31C21,47D24078BF32FD11,AF4829B5E2C8D8A2,F9A00B7571FAA118,702184B499A52089,44AF4D28F7A5DF64,F3D9F6FD2685A695,23E76F686A29C730,000005F40DA8B60F,2FA29342554AFDDA,26463A84B9F210A7,E5F3A3240C648DD5,ABCD78C2C35A187B,EF9022FEE214BEB3,6D20A0FCB7C70A49,F2DA8B2D72ADC788,E87C7B9BDBD983D2,A67B94513FBB76C6,901CAF019A59CD9C,6BC0E74043748776,000046AA8406CA4F,BEB07486827F5199,F680755B238D9F60,B44A4B5B804B666F,A571CDB3804DE6AE,879A5A30120C1F49,860AECF13BADDA9D,C71939778578F749,96945EB2161EEFD8,71CC0D8D792663AC,9B2786006EAB79EC,7163E506C3D03206,000002FCD9D1B43A,4C01AD6DBB6C5012,17C69FE3DA548BB6,33C2004BA6C7A1F0,462B96DDEE953B6D,26A76AD1F1B91216,6C555FE3FE8CB57F,478465AE2045DD25,8782FEC43FE86B11,F7E403B6C8D9BEB1,B01CC968D9FA2D5E,E8D7AD58982B9188,00004A8C274599FA,25F2FD5F9E7200A2,CC5463306666D78B,289EC92D952647B9,E96104CBF6AED6ED,E6C265AA44D6E273,65213D13E4E67705,7AD62F8A0B67B811,62406217CC866E3A,F29E06093199F64B,01923B0B2406C3A7,613887687F2B4BDB,00004656787249F0,3AC1DC15BAE66F33,2D82C035D687A131,0907044D6D97404B,48023027EB63E80E,A57399FD727748E6,AF03B132CA68BA50,861C516E4092B6D7,7D36F846BF6AC4B2,878937FF789E6ACF,39C9102E6C3B5DCF,754BAE189CDFFD36,000018F0A0654E7B,A5F21DEA79898D84,39C78C60CEFC3EF9,96E3F8D56EC27978,BDED8915D16DACA1,AE28BA5B6FAAC575,CEF5FCC7A724F659,D6AC3605F3CC4409,19025DFD5075F3B5,CB2D900927AF151C,EEFBAFEE47ABD8EC,8E5126A01F332D50,00004DBF136B4BE6,FCA6EEEA6C66D87A,733469D61C225C97,98DA262FE7C5B8FD,4CFB732E1BE3BC2E,9B49AF9283728714,CDFA47316A1AD225,F1F6918B0457CD36,CEBEE83932938EF8,B4508C6000653637,4E2F628C45B9B5A7,C25F18D42B56DA1D,000044F5CC81F74F,FBC285298A82D7F9,1DEBE774B26E0DCD,737B00BCDC263CCD,C27C7D0A6C10F2C1,1F292D7C45D54B02,4E94F77256779E15,DB51D05AD36DFFAB,C1C331B4CACFF0CD,2F588B25EF512921,02C36C954CEB3D76,794EF69929C6DB6C,00001121FAD16433,BDBA6940E9C388F6,0CA12C289C818DF9,1B7DEE16BF8FC4F2,CD6097C81AFA4967,8792FBE393DC180B,9CA500DFE628BF39,56739B58D9E749CF,8D127DCE674F900F,98672C7AEB830849,8106DA1B029625D2,60D7060D57C9C785,000023B55DE167E6,59670540B08E48DA,C906EB276A600558,56DED84154E74F0A,CC231FA39925F012,8344817DCE38024A,96AE7AC7564E18D5,60C242E7B22D7780,9DF0C8FB46E7A8CF,79C1A0B0C5AF5F8D,6CB41CF4E6FDEE36,8775966BA6D9761E,00003FC1D28C1822,452655B94E3FCEC3,376FA2C218D8E0C6,DF52761F5B67B5ED,455A6671B0CD312F,8A7CCC7C832ADFC3,4661534B829F7CF5,DBEC40556F5496EA,2E20702CCD35F892,1142BC6C11D2BA70,8B9F1741FDBE03E8,FD64206B5443ADA3,000032776A95BA1B,CC15234981EC2D2B,DEAE363F1C4EB46F,EFE3B1034F61B611,C41D9FFFF4DEBBD0,6B2AA8472AB152C3,19A52BFDF377DAE4,223DA5DDF95A8BD6,862849C2003C8DB4,4C4CC2B518A41119,D67D2B72176AF935,B773017A87A018B0,0000569FF4931AF7,56E3141890E1A2D9,A6B0511248F26991,0758E85072BD3B76,D1DCE4FFF03A8A71,63361AE9BB04BCEB,C4A58E34D4C98102,2FF74FC15AC68FD3,4BCD4EF37B5AC318,6CAD877527AAF114,D5CE6BDD4B6BFB37,C67C45169890220B,00005A2CFEF2EF72,24E5FB179D28343D,BB1E8466969A16FA,8B0C4F1DCEB80ADC,5837FF7A2D93B8C1,D89DE24CADD4126F,021469E59A24ABDF,28ED7503545E3DAD,A67D8FA12AEB51A3,7729E275582B4CBF,7995F3D41D26E4E2,31A270AEE1D017BE,000017761C25F5BC,D91FB45BA8B53F2A,E8E98803EA8CA344,6621E2843D2D7F8D,E2535A3C5D9F4638,F7AF588ED58E5BF5,7F459BAC28D58F3A,FF415E694F64CAFC,7C45F79068CB7217,2A85B42FC2121E33,17EBAB64EDDDC0E2,A4A4E47CF23CD089,000032853F941C5B,23805C1A4E59AEF6,771A9A92CA2DD558,675D52F432740151,3560EC3A9DBCC3CE,301DB1E5B4D2DCB8,528D4CB6AD2E281C,DC36E72CCACC7E7E,0AD51ABFC84CEA30,A51465674C0A2A83,3547D02DCEBB137C,E6BA26DC52F5342C,00006A65A28E9D89,46D051F78E02C602,E3F5E1CC6B61BF21,CBF6933E2504AA9B,B4AFB270D80636BD,9312E6D0013C6D93,5794860DB11FE84F,9944E8BE1D01FB74,7D324A63D9EF2D6D,D654FD0F485A6469,1B781FA1E3DA382C,D74A614ACE0D236F,000002117FCC2586,85FC5A122F6EAB3A,256436FD8DA71ECA,6066ED6894DBBB57,775649434D80CB61,84D4AD4C2139ADB9,BCE17CB8CCA91157,9ADA85D703019210,BED07D0F5DEE4745,6133D95AE1C564EA,C9C1B3D28277D56F,341162004F517F7A,000069ED7EA97307,AD0031909E1AE183,F82AD6D6632ED84C,8EC62C986FA85741,99D56E1665B2553A,3C31CC66193B0A9B,DFE1E98496301716,A64CF731A26F5B9F,36A4EA4ADAB61D9D,E9617A04B9215010,81DDD88C3FA06576,2DC7B1B227D4C17E,000028AD6E7628C5,E3AF0D3068493A98,E0372F5683F3EDAE,6AA4F23971651183,52860DA010B47E3D,AB3DBEE97AB8EDF1,747AB9BA780A0C7E,22D4105D31DEB8D2,3257DD7FB310A527,F9BB47B04A4844AD,E7D6960960F00EC8,7B069B59198C9654,000024041955325B,73BBD3B8ACB6C07A,B3BC399E1598D936,ADD2E0BEE27DC1CB,F1C0D193466147B1,70B315C26EFBAAC6,29EDF055B1EE7F1A,DBB89965AFB5B20C,865BE71051D2CB5F,92F0B458368B6B4A,D149080CA26F70A7,3CCAB79897B95CAD,00002DECF5080254,C7713145777D4BAC,DAE0415283F7F92E,660988E716A6E01E,0AAD4CD94EAAD2C0,50C32A2E5B1ADAB8,283328920CD8CA1C,E558FB227802A898,296055D63B6816C9,FA36F9F7792157AE,2E4971C94A4F4EEE,6A7C39E69CD29DD7,00002EDA4C4A36F1,6B9470B5C28061F1,4FE81C230109487B,60EAFDEBF56BCD91,F9F2C9BEBF63D13C,888CD3B674BF1F1D,DAD975D8826303C1,86DC486140A94FD5,B181F47B9B1DA5F5,17EE75B43D79F6A0,B72E7F67C2D8A87E,433CC7CBBF699F69,000019A7F78F07B8,CD9A4C8B7B928A56,2734AF9AE99AE7EC,121348287293AAB1,5E6ABE72243D1E87,CF595017C9A35D1C,E06506A83FF63EA5,C0F141930C7A1198,44EECE08AD87F2FB,4514B690E122B700,D3CCCB2F8EF438E0,D485E80B7125125A,00003CF095A6BE9C,3655533B7AAEDABE,FFEBD6C1207FA3DD,A110BB99C36CEB96,CE55A33E845B3498,7567C758552C84A1,4054DFC21267FB1D,6A1C8F8B2733BCC4,1D1EF4C2BEB18DB0,5A42830B73AAC370,1106E70935216110,E0F10B2A4B60018C,000048A03D7118CE,84421D4C89F2F631,6AC2ACC8579CBBFE,8DA55F79B1BC58EC,FC95C08A98242F25,8ABDE1785AA2AB7C,92FFEF8975D891CF,EC2D1723A3159EBB,357AC709AB1FCE4B,F9CC0263AF374D47,A2838A94DADED579,18A329D91FA18B8B,000043C8C0387C87,200A8DAE10493A46,CBAADCEDD656AF9D,8DD0E043D3D51496,5284A8145912E7A0,E130AE0A5728352A,1B78A7A987380DA7,5812CC349028351F,58588441B14B05D3,53FE85587E2CE909,F3644F8C415E1A31,244A7238142B8D65,0000229B0F976648,C0C0703903AC2B25,9B970E64B9570AF5,E046C157A20981B2,2BB29BC91582F7F7,B75A4EF6BFCF627A,AD8C4547CE687727,A767BC8E9FC88609,DA9B4371280AF233,A784BBB1A1D90620,70C2E7FEB321C895,5485CEEF55E77310,0000126F0323C9EB,E08C9F5833B3D2C2,D65130B6FA0DFC88,FC5B67C2EC29C33B,39A9F819C0915052,60ABDE4DC6B7CFE5,90F8C0E8014396F6,262C03D51C16037A,C5A5F09C1C332098,8E5C13A76D76722F,9AD2E194D5F4724B,FF28E4D591AB4D6F,00006C86C278EAF8,41F31B2C2A4E599D,0B598604DF24F5E3,D14951D8BD4557AF,7650030A5A4A9168,D3F49382FAC7F858,CEA0390CD829D140,3659FD4D1DB794D9,AF3E4BF801447C2A,BEA871C86620413B,A3E38CF39BBA887C,846B7A309E5A10D6,00005DB8DABAB4E6,5DA59B08112EFA76,E21E747EABBCF9AB,F17E3A0C6A526293,0898AD9515053737,EC2A7977AA631D7A,021F2A876F97E3F5,7B0F994E91EBE7E9,6356230722637622,4E6220DB9FCD9C2E,5BD4ED33910DA4C1,7382370BAE7A14D3,0000563D0C48BDBF,C081F6C6665E37CC,4A4786C95CF77E47,903150005DED2F96,C890E4136897349F,E2BC36AEDDECFD6E,EE2446481AE08BBC,23E7F31B29B49CA4,AA9883E88ADB92E7,257484D8062E0BFB,B5D0EB0ACC14DD0B,1771D056B3C94E1D,000031EC4CA18DE7,1FC256FA39657771,B794D38242F0BDB2,48E27254A554397D,E9B8B4FA472CE8C0,58F8EF194E77C63F,3477D894D34C82C2,CD5FFB87FE2F9196,00569E25AB585F37,AD818997004AB14A,B84F2D923D76A9DD,54FDFCCE7095844A,00001AC93439A841,F0885BEC81ED67D1,F535841CBE2B54B5,91F954C20A3C761F,101D2EAD64DCC8FE,1049F5C9717EFCCB,A1D9C0D4A5995B3A,980E316776C423DD,4AA188593E6C5E91,9B1A394CEBDA2082,9FD80F4BAE9CEB94,6851B79DE9DDD72B,000044D93D1F74CB,5807EA3993C95862,E1E154D2055583CA,BF80D80EAFFF1A4A,6E99AAC7922E3206,1AB24FB94B76B460,8DD4732CFC46C180,0C1AFC5557AD4F69,1521057A9CD38968,EE52661C5B81E150,1B5DDE20238007AE,FC57799D09DA753D,0000619DD1E2263B,AFB5F208554A4B1B,95B69089F4DE0B7A,207F45B4DC1100B9,85601ADE396DBF53,F468BA00D6A5B1D2,82FFCDF7E8111F01,7DA6861169C4CD8A,3EE6689D5414D3E4,B720D0307177E9D1,E5452AED1229475B,9DBB70FAF790D3DC,00000C1637E36D74,406ECFFCA4E6C389,B56745D1740232D4,C1C439474683F288,1803EADA07DC8C22,E5C8B2FD49837209,2105414D71A00438,6B87A1A7B66E7114,97B48C4FF3732C3D,C953836A5481153E,939959DE5BB8468A,AC01C02DA54A6A89,0000583EE9952F25,59FDA3F78171B17E,DB2A6652505C2DEF,497B42152B05BE05,9FD2749385C259AF,F3CC041CCE80F0FB,6FD9599F7A655131,DB1DB0F2CF310B03,5E3EF4F53232C428,0EAD7F549881E0A3,9B651D6F7E3756A4,0E46D7B2AF182230,000057D7A390C525,6C23F4581F0E3173,DCFF464CF10E32B3,956AE202BBABEF28,7224B99CB014F489,6CDF0EF6914684A4,36DC75CA6851971D,004BE5BDCAC34D95,EFB86A7F198139AF,CBD2EF67662CD80C,6609013721A779C7,5EF1093C36299226,00001A532CF9391A,B20E1E5C4BF29C33,2FC8C6F91F23CD06,533508C2F9A4BADC,0A530E17CF0378F2,778F37391AB1E264,DA84CEABF952A79E,275B9869E41A2DBD,FAE2DB7DC327F10E,3D63299823E2CA5F,A4CC3023B4B27F20,C37E163B2A98C6D8,000047A1695B58CE,D10DA943C3F6F077,D32F9DB1392ACCAC,B83D58B14C433AC5,E48EF3B0A75C90F1,6FEBE2F305A5B3C5,E417F4A3C67032E1,338958078FE69303,BB87304BC1ED557F,DBB745708AFDBE84,B4632E33D69F5C51,A283C12214B32C61,00002E533C15EE17,58907E6D7C4F909D,675772847EE5C35B,781AAEC37BD76714,EB7E32CA1AE23598,58ECE3B44B7577DF,5DDE5613D05C94EB,07C6DCCE0705EF9E,AC1281B2D0A07392,DF92C7386DF1011A,249E367F3CF6FF8A,B6F607405788A913,00002A167A1F9B21,BDADA447E4EC82F9,678E350726005F9C,80E9380F7E4695AE,7B8037585F32EC25,7C49FCE0E2C22077,B76094DAFBD8CB62,F671031C19385556,48D20D88E5A0A5E6,8D148F55BDF74EF8,3AE02C6C19643F71,8CA2A31E03452670,00000AEACB36EE73,754E939C3DB36896,66DF94D44B96AB51,0FB09830879CB17A,54096E222CB61F1A,3395155340ABCDCC,999FDF3ED16C08CD,0383FF22825B387B,2458EB581F2F53C1,48B8276268E042EA,F4D3C8151349FF91,CB566D6A050F25E8,00006E44616FA022,230520E7514ED4FD,806B39A0A6519F8B,1AC1AA24D8148923,396B168F1F447484,7204244F7DA19F8A,4EF36E1490A7039F,7185834271F12ACB,986D1D3E892B5DF8,6FFFB74A72BB284C,04689B008543CAEA,A75E20C637D8A3A0,00001639B9556454,F99BAE13B4C12842,5777E29833CFCB88,F2A3B8676AC010BA,2B48EC2BED99944B,A4DB41AE60F4BCF4,65C144563699398E,5247C665534C057F,16AB0E4342029625,9ED5750D7E5A7562,BB2FE2C80A354F3A,90FE4E65DE79BD41,000003852BA4CF6D,C2FE83EA2CB447CA,8F5610F4646EF28F,CF5405DB6CC689B8,1E5211D500CAB986,16633EAA2E16F33A,CE9ADD49B7D75D42,C26BE3AB846D240B,2AD492782FB64B31,4EF891A919EC3F46,86DF922EFBE3F715,36EC3496EAB569CA,0000314B40637CAC,6638657D53B27610,852086CB0CDDB4C1,D6867860DDB82EBB,C12DCB3B28A80396,85D92FA67F2314D6,4F45E8CE534ADC08,F85C1F35E2DA46A3,773C9B5A8E911860,BF83F658D3B2EAB0,339B95D64E6BA596,A108E0640F0D6892,00001466BDA0CFD6,53FD7D53D5B6BD50,B19571E8066BF852,5B8564EE357C33E6,A47D99E72C680855,2B08D58570F6957E,D32EA59E4010486F,5ABBB7228D665A4C,6FC5221365F00BCC,F94AF2B597FBB24B,2E7E29C593D06E8D,69B4B1BAFECB0119,00006D52CCD8BCCD,1188A6D1B40C5350,EC1561AE9603583B,C1B7EC45029F2586,2947E465B829AF19,FE7764498B769A1D,089FA64B8BCF54C0,C7FCFF67A8CB45E9,10D793BEC23ED51A,C8558D2DA2056EEA,18EF59CDECCD085F,2A165C70926B158A,00001E9DFB5A288D,936DECA8B7D0ECAB,53ADCD4A5175EFCC,7DB03198C34E30A4,4C41D4AF915BEF65,5A153A566E522093,2AEE2A2E81AC57A9,15A20EF84935C9A3,53F509A33DB9DC5C,48BB1561EB8EC1C9,7875A0B7979E14EB,350449586782293B,000050CFF5A152BF,DC7DAC275F25469E,21333EEDE102C53F,BBE3D6AB6CFD9F9D,ACC01784398F14FD,B319B9EF32CB4E79,17C5BEE29B2BB081,8949B0CDABD8B213,D067392FC15A1940,64856AF47EF37DBB,C8B54E40CEEC404C,F11E74959D1D09E3,00002B4FD38CD049,145A0EB51A1FA51C,A07E59B7AE0237D3,682C010CB777071A,9D779DB472648922,D4DDBBA260A67487,7B236EA26FBE2407,8C9B3D8768F887B7,E99E4266A7570C11,58C34E767E59E906,D26CBCE0C3AA98BC,B5499DAEAAD4F442,0000470C9AF28C59,E8BEE50E8B2F6346,49687BCE6D1F1379,F685939581B893D6,629822A0D29E81D2,9400B597F93D9A45,D2BB665F2412FFBE,26F70E3D3F1A4EF3,138C7378D2B2E020,4AFFA1D354E0744B,36AB09292F573D16,FD8A1221282A71A8,000063C39EFEE29C,CF60C19EAD36743F,4B5CD5571215E49F,77873B2D3DC5B126,9C53F986E8CFCEE3,F8B2970319B067D4,C0475FBF22F8A52D,8D063C794C552AA3,73D8531751595614,82E7F7DD61064B6F,67E7F64F5E0CE5E6,0AF6C1E107AE63A8,00003D4A96C6B187,33E7AA71B16BB935,9CDF62484A38D73A,58EF07287775F0DA,85483D82C947EAA4,7B7AF19890DAA801,7838EC910666284F,A754EE628767EC31,100649C294D68477,09049B926823F52F,DB839FF34509A313,9F183673765B8F0A,000047199446C7EE,9F43CF24415FC043,6D0A2059037EFD36,165C631DFEFA1698,E54E27A1A6B9B20B,9C0A9CC929999FF3,2EB98C02B9D9E035,045B8ECD64AD7318,A0D88D8D925B8F78,77A1848F04A9D34A,CC792F187ECE4695,F2AD2DC86D7F4A3E,000017EBDD86B9E5,E9A146C681CEC8C3,29E05614F83C2DD0,27AF391A6D39E436,6E9E27D979988ADB,C10BD5AE19E76831,318150931F1A169A,28D035C403EEB948,2BC4A5BCDBDCFD70,EE14AB245132DB90,2321E9ADF277B0B7,6CA576A91A189EC4,000065B9EAD024F3,A4209EF94E0D5EC2,24262CF7B5EF7911,478F9DBED8F6E850,3D37CA7BA322234C,A6C4221EBD31B89B,81176CE493C9E28C,DC4A9378FC7061B8,ADFA96BCD724F2FC,5AA87B2D88478846,52EB95CEA46B1BC4,9DA600E852C1AD58,00000C27A1F86B34,C9FCB151D307CF2A,26CAC176C3D23843,FE631FA8A9DFE159,576576070F73C422,6C22D1FCBF14CD43,ADD52F55B14E4F05,B52E845C6EFD364D,154A8CB1D29047BE,8AEFCF0AEE717524,E25B20CC32072CFF,2E080C6C41E97FE8,000053EA85D198F6,F9AA2555A287FB02,A6CCBB48D3D77D54,E46FEB654519EA13,0E1A331433CEE108,2C635FC684A3CD75,41743F276F500E24,10159FCEDA3C2C01,92147B31A3FE14CB,DA649CE683521198,2E7AE80BED2A4BAE,101BB45BAAD75049,000032C9C32274B4,7EE6E22A030D5E6C,041A9AF89D1A8D3D,DB4BA3E2030DE85F,013C4D30F0EEDCE9,029E2E47ED1E4EF0,6EF17D4A40D40297,B2B9021F963424A9,097D589B8C0BCF57,886B4BF1736F6B38,6AC3AFCB2E57ED22,8B3EF133E1D609AD,000041A7949F458F,D04066CD89025DED,79EE598FE1A824E5,067B2F25891B0680,CAE54AE5CE30AD28,6198BE1731EE23AD,CF91E9B7751D1FEA,CE1E7ACE6C621D2C,3907E514A4DC8F98,4D1AA2A1C1FCDBF9,560F79F4EA75350B,35654D8D2F387996,0000019D957C5E89,568312311A7CA212,AC7E574AC45B72D5,2731B74CC38792A0,CEA35CC99D9C97C0,A0228B222CC2401E,CB90EC2B028A7DFB,6C6D9C80F364D4CE,679205FC31513556,DBD71729052F74FC,793FAEFE5B64497A,4D3E42A8974E70DB,00005076A5A586CB,55E33A9B7E9DFC66,0007C949F59D4C6B,948BC362CA046029,BBAB8F6E76D94593,91C3E7645F5BC471,66780421CC3BEB97,024965D69E4D71CC,F405A89B8F736895,D0E429C3A36A988F,EDE549F73D0D21A6,163F425F707CEABE,00006996263C9E22,35391B01115E9FC4,906324B5A9D5DBDD,434B87B6F98300B7,45A8FEE5B7828199,CB1AE12CCCF613E1,7B129F4944911F72,2563DE0B1A7CF242,29503B28F39177C7,9A384EF2306E9A0D,412985446B8C65A4,1498AEAB3119863B,00005337A1D20B13,F8802ECE2DBFC103,ABB2825236B4B131,663B99A13AF93FAA,97B887418CD7B8B7,87E48BCA1123D75A,1BE84A5D0FD42333,A80822DD7D592971,4F7C2F2D567BB861,72CDDCD407D59190,849E550E7916C04D,ABBE6E60D0A1577C,000020A8AA5C84D9,552BCFDD64C4F4F9,1EB478301146BDDE,15A155BFE3320DD2,A6012D72BEC6409E,2CF11FF7E71A1EF3,E198B188E4CBB012,21B4CC80C702A85E,9BF22D65E4B5A7B8,8D097F4DF9CD18E0,891A26755F211AB6,ED2C48F85B2288DD,00004D7375C5510B,B624520AE6E96181,6F2A39CBE8099AF5,DEE2F992438E987D,765D5280321C4F82,6A177AD7621C3B33,6E7E506F1AE3D48D,79CE09258D08BC15,075C2F160837E82F,FFE314C8486796F8,A6586385FFB065CF,FD54BE024F10AA52,000043B9CA2C9E20,4BB935CE60CB9D18,85AEE533690B3CF7,FCE3208444E92296,F39C8367F813BE77,6A6BF0DF39F058DB,45F81630C1717A31,631BC43C8909B487,844D65814AC4EFB8,4B52B3F02E5C952A,D813B3A0F5C4EEA1,0E1977207687B326,00006C52145C5BE1,C311D169A2445C29,E964B64C5A32563D,8E8CE0BE8230347A,877B77D00811F769,1B61189283AEA596,7AC3D1F69B88CDE5,D2E4656DADAB186A,7263AE61EA77305E,5DFA07DFC8603478,EE0801AB83995C41,1DD75F293C9E77EA,00006005E504D65D,63EC1C85AD0D753E,8CC8DC64041BF4B8,3B11ED9CBF705FE9,696B109E52E592F2,1BEEF446158E93DE,155BA80E5CADEF75,FB611D1A9CBC58CE,B245FE67B5BD8460,6F64E46E4093E369,DE7DDFAE8B9ABD18,273DF149A2C13FD0,0000417FCAAFDA7F,A9C6AFBAC8B4D830,467EEEE06932CFF0,3A4634782E6302B9,F890020003E37F68,4D99D624F5F5725E,6A224055427FDEAD,637C297AB7A6BF7A,779E22AD20190F44,7538B0B323690437,2BF5EDC1AAF1A547,17E68083A36E5E06,00002F35168EABAC,C3CE1FC5DDA1773D,70A5EE48B74F4F59,FDE92DD9256DEC80,BBAC189979A13092,C2E35A76BFACB421,05EB9F165F9D5442,0B5C99608FB4DE16,B2811066946F5D1E,506239D7DBE0DAD2,5F05B9153878DC85,0BD5F494043EC887,0000117491F6B159,579F453C61DC24B9,37FF329278BB0955,4A368588E4A6BDC3,215AB36215762396,AD4952A9CDF476E8,FD0512C34D39097E,4FD1633BC0600037,7A5E44C2324D1A6A,4FBA0DDED0422CE3,C4C55FDD2A5AB294,E672D497ED9CCFFE,00001AB84DAD88CF,31366D349897D829,6CF64B7C89157719,5FD14CB2F027FE17,AEFE0CFF947D98EA,FF06D8D0320EE2EA,5E33F8FFEA13CEFA,B5A8FDE850532287,D7152D6CDFFF7EE9,A94CBBD50F1C592A,A5D397CDC033629C,0080AD46F88CAB96,00004F3053126E56,3E7EBDD5FDB8ACB5,40624B5217AC056C,2A0444B180AFEA1D,2042AD93B03CF593,E69F2CE689F66063,A458818A211DA9A2,680DA01933D86777,C689074EB7DCF741,A902A8CBA41D2625,21895CE22F915F7F,56A4A6C76665CC86,0000305F4C1A9D51,A4177332C06D93E9,140CB59C011E4C87,10A47CA6D5AC2D6A,F23277C54BF08D04,988F736EBA6148BA,783E8A583EFA3FEB,62ABFD92F1A213B6,461A3EDF1235174A,4F53FBD1F1B05B4B,2A355FC7CAC9799B,25C6C7820554994D,00006802AEE3E4F2,7F2A55CE6871F7C3,A054D4D1DC342984,79D5848DEF65F579,C12BF1316EC7EC6A,4AB35AA3D313C6C6,99A31018B2EB3DE0,34F8C52C7C6FC64D,2B4706C7A6027E50,06879B53D60B1F65,BD13181194FCEEF0,4C9BAAE7FC2DCB06,0000303341D92E26,F0A7F4AF7EFE5813,AA0F0FADD9060817,AE04EE595E316549,3E8ABDA8E5AF94B8,F2B2A45B1DA0C231,6B4EECF5BAA75BB3,F52429DF7AE2A73C,11DB5684CEB9D205,689E2DC8F0823A9E,52DE49B36BB17417,63A8FF22DBAD49B3,0000154E241926F9,38A8F936DDE34CCA,F4474D6AD6B9A14B,26D6203F0BF32680,4F96404CFA71659D,C1926A9F94B6B538,3CA2561A45EA4835,5007ABF23CF315CC,C6AE2F38FC189F74,E6F8F368D81B6FD4,70DA8CAD6A653DE1,ECF06AD749E1E86F,00006365FC4FDF8B,507B791632A2FFD4,BAF7AA3108838170,FBC8504981AA39B7,73C9ACA88528A6E6,ED6E80EA49F2D450,6523D7BC6662F7BE,91B2751F0F115333,090B98D3D49D32EA,E5B302E2A88C0247,1F703501CE99620A,399CC605172B2263,000009FBB9A72A93,2FD66AFDA60DF962,F54140F3BAB073E0,E8687B1FEF33EBAB,55DD67B42F6194C0,0FE0780F6C171442,5EA434A799030C6A,08BBCB5886EC3B1D,70DD7E1DDC17CA18,A7D7E89FC5F4D385,5ED9FAA17FE5BA78,20477B7984FE1C68,0000068A5E766C66,2B7D7BAB1436D3B6,BB9BB16D48DC9C70,377EF85CB8D95354,41EDA976F35FB266,357D42E0B886241B,8C775C36579E24D5,8904A3B24FF90B9F,E6ABF987ABB4C35A,F58C67A1D7698284,3DAC0A316700E468,CFB314E1D4DF1811,00000E9E26E45BCE,3255A22DC6E70C3B,5B87E85178019518,6FCF9A48A7E74133,3F5C64E3CB53A3DD,6F6B1A8D637EB60A,456D176F00DF64A4,6459949F0E4C1E26,7B3A7266169D61B9,BF72600620C5D9C9,A14E741E9818CE67,99BC698769E9FEB8,000041F17CFD452F,27D412DD977E6E01,8A6D9AB62A5D0ACF,7945CD3F4537E402,6F366AA661D14CE6,0AEF8FDB3EB32DA1,6BC0CD66727F86AD,EF9AC0E1C05E2AB6,5D3C943E39B149A1,D649CAC82816A29B,CDC1AB5ACF4C12B4,A5B5AB7977E55570,00001EA059097316,F41A948DCCCF8ED3,9B5C9D96F5C4F88C,BBDDB7F094236BBB,AE730FF3F5D3D899,C2DBB5982E0CB123,88031636F06531D5,25C1D185C7E32CDD,05696E9633951FBA,86CBE2314210D84D,DDCFD008584A4460,E483F77636A351F5,00004D871DBA3FC5,028B95A3FF98ED4F,4B49FEA67B60584C,FF7061E437AAB9AA,A192E5C3FC76B556,136778CB0ACD9AE0,4D7B814AC4C6BF03,B6A69CAD0393F17A,C642262BE88FADC1,618F6E087BD876DB,F10F8A6C11168B6B,6B69570C309735B3,0000294B74AFBB91,BA28868304C0460C,2BAA6B816AFE9B51,1BEB0F0454C61C3B,D620CE0DE5DAEA27,4B77862333C0A438,3A465271ACD80715,10EFCDA24AFB2DDC,B812893B965B799D,84A8E0617F4C7DAF,7DF54A56526954E9,C393304D7CD61419,00006EC5758B943C,B41DB7D0B2471843,C0BD46C370FE6639,B1D935D4A6723F74,938939619A2245F9,CCAD053F1294750B,BA28F5234359C559,6ED2DE180C22C56E,407E123EAC0CF1A4,3DEEF475711B2410,C6259B841A0648C8,4C9760AFA2392490,000037122E9BF86F,638A29F0908D2499,C7E574154E1F1838,769A9E3B89DEC88D,50926E8F0EF78CF4,69DFCE757A9692DE,AEA8878D6F4051CA,01E1A5D58DB6F25F,EC64E96DB9DC1A55,F60E6F9A86D56B34,C4CC17B9968FBF32,1CA54AB3AEE2A432,000007E4238091C0,F9012B171F0D95BC,9BB10022B7CC277F,4E14D1D37EB75111,FF9F62E70E42A808,F5E8F4F9BED4B04D,19B5DF1D2DE6B945,F9251F4D39C20534,598D273CD0DFACC7,3E02FE01B55E8517,FF6EC4CA25206BD0,B61791D85D2E1E38,00000936D2E72D46,2778C455B4E0A230,F60E2AFE46485507,9F37E11CFBABE00C,323E87D1C9593BBF,C4D8891F9DBCB44F,FBA868D0B987C3F9,C3014F2EEC893A66,1418B3D980F082DD,58DA080719DD8ACE,5A115864A3B37A12,51D7D32A7ED2DE40,00002F4E55B42B81,A367ED0BEFFAED5F,26B1AE1920850728,E40CE85A4E881B0A,3CD75A6D57FD0053,CDFCD4A4F51E8278,02DBC23DF53B026F,7637BC83A19E1812,C10B42A753D9F213,332BE1F892A9C6D1,70D10110D66AF95E,59036616CC554D6E,00006C2652F733DC,82D8E9F5C69499DC,5C3C326261C6F0B0,25CAE3413558D6AB,053F8F6268B6C6DB,09FF1E153A98F368,DB4251EF0ED8DEA3,9E2C93E9D7834165,2B3977F76024DFB1,97D5C9E4B4F70000,31685E4877DB1EDF,F7C77649807CA774,000038737260CDD8,F1CA5E2508767763,7BB48622DC81D255,64A558344A11C04E,EF417CF4D96B2F47,B8DF88718C3B871C,56504258CC91CBFF,BD5A583FA6B10296,ABD6848CBD137246,C3D9A9B4CD099D0B,10B1C306F9FB80A9,FAD66F813002DAD4,000066385584919E,1CC813AFCB25A5CB,A60C7CC6ECDB59B2,4650B28AB1A703BA,A83DF666ACE1E9AF,C33D542839AD71C0,5C6D560145D2BAAF,DBACC5364BBC8525,478F98E8BE3D5710,9E0015966B21C995,BFBE36C6AC6FE62E,779ED7F4B2A46173,00002250F9210A99,083B6888C5A255FF,1159CC9374DB92BB,D5A3E76E67D5FF1A,70D4A61468429421,2297F3B3DA531CA0,F48E44D4D261410C,2FE91246FE644696,F9368B5E62E0AB4E,C13DF8E914F68242,05EC3835521635DA,880C09FF11F1C28E,00000F8D780DDDB7,732E2C5CC7924A96,C2E4424F56240DB6,A57D63781AAE25FE,816DFE70506E5DAB,BF3B6B96145F40C6,AFACF2D9D59459D4,4563214EFFF6EB0D,EFDCEDB6035FE13A,8D66E78BA7308C66,BEC9360C7170A2E0,3B4B1AF8F82EFE38,00004B51B00ABD9F,F349DA3F63E03253,61C9E187E82FDBEB,376CCB6AD60A4F9B,BB8F904430D71C2A,F7B6A200F7B62E0D,07E73F71A6751B51,5E68A40C042E472D,34F8B4EF8DA2E0DA,B30C11986C3F99D9,DF5F69CEBCECE53A,439D96E99108490A,000032C9DD30C7A5,F9AC9A49F538A20C,E895AEC270F406E4,BAD5B05C6AA9CA64,F2AEDD29E338CF80,EC279EF03A57B9AF,20B17231DEA0072B,7F977E3417DC21CD,76883CB7EB75F9DB,9087383F794452DE,12E474F6E3179E19,2F2B9DD895336FC7,00005AE24C62F469,0385D1C7FDAD1BAC,EFBCB32F2B36FDCE,1607E2F6AEDBFFB0,A7DC6CCEF0C45A37,5F669AAE940EAF88,98F1972634CAAC14,2412E3EB402A47AF,F9AE5C555A499695,1789CC8CB3A324D2,D4BBBB86DC0F47A1,C74EA01E0699D0D2,00006C9D4DEA7D3C,F658C349D49C0355,7DF07A02DF0FD24D,84AD86B007389972,CD5726CCF1512252,337C2B9C43C77C1D,E016EEDD7AA6624E,DBA4D17E4C5FC6D2,96187EDCB613B35C,F72924A32C6DB7EE,261F8A935E4AB84D,BDA345F600BCC97D,00006F9FC73FEEB4,4912192E5C2A2C5A,D87FAA5EE3EC711B,C2DEF76B011F4EE8,797735AFE08349B1,3CB44D038D8B6859,4A30FEE8EAA73E10,FA3E1722B7A0EA84,456A9408B64AD66F,60E82637AECD7975,608E3946DC8A133B,640C677099355F40,000045CBBFCC796F,9BF02A8FCC7FF66E,97332CE9685E34CC,4EF23EF88E360429,3EA67ADFE648ED6D,88F587C3EF1B020A,3654DFCA53C5FC82,F7E176D9619D43D1,F34AEF778FCCCDD6,03EB04022527BE5C,8C9113A1DB4832FC,998198F1BC64DBA4,00000B101F9A6F92,58B5A5FD4235F294,53A2A32DCD38CB70,68C08BA79B46BE16,7A36549B2BF066FE,81C3E1DF99578410,AE70BB2396B94833,249C7F647E40F612,AED7924F50C5C4E9,CC1091D188BF74CA,648C2FD6E7AB95E5,010EBB413EC07997,00005F57DEA33253,83B53F112223DE5B,D9B2CF6A06240615,5BB50642428C7435,ABF814856A0215AF,FFFA0A53E950A0B1,CDB36B985C8DFF42,608AEF2F0CD28057,E405F2CE0E3B0E69,C5DEAF52FC9AB6AD,4119E15F78C46CE8,BE0CFC15C23C4463,000018A19CB595BB,ACD689DE3C0E9EFE,B26596E63DE22D9E,21C6D58AC42C709E,86E91153EECBD5AE,2E31D1539F27DF09,BCE3B58390D8E39F,96E654B887ED2E37,02EF3979FB43F006,8FC5C7E19E892003,3368A734DBED4F0E,DBFF174E21813675,000060AEF102826B,FE3978D3921840E9,ABBA56F87829FAD4,8FA5FD1BB04516F3,F180FBBDCD41A030,F8252C3522052ABA,227B4F0ED694A05D,6464D2FB50CCC3FF,2CAD44A0EF2D09CE,A2782F23970CE038,0856449A7BF271F8,A8EB5B40E0A391F7,00002141010EBF90,CDD359B26E83604D,102A5181D7F922A9,0232E711F78BE01B,AA49B67686D01258,C1311A89F1FBA17E,18EB50C7295960EF,050792383CF6230B,8B0AFEEB951E502E,3330AB63DDB58598,0164184856BC9581,A5E804111871D26C,0000037DC332D780,AB4CC6CC90708FA1,5799D0338A02E851,B8AA42053070CC84,E9677B5D9587A409,4B4F50CABC01468C,C6777046F2F02504,8D2F45B248C2C6A1,A596C800CAB52EF3,6A80B8FC0A9CFA4C,B4F63B6BE680DC82,04D5EB3A081DE850,0000163534CF0176,62BE1CFD6C4EEC64,7DB4FA549B19EB17,E8175FDC87B4BCAE,F53D94490220432C,CA245F0491008ECF,6A860C135C1974B2,F0F86B7A4B2FDF35,E768987C7D395638,D519945AAB14B96F,4864828037816C99,4388C77A1E36371C,00005FACE4DA7541,8E1DE691D33E8624,CBBBFE7E84FEB1DE,5294F3F3941EFE05,03C8ED32E1FCE38F,AC2254E5ECCB35AD,EFC22684C58414F2,12506CCC0208DE4E,AFDB7FBB0234B7B1,3ECC43B5879BF50C,17C0FAA04B2F7C48,7149B7C00BEF5D81,00005709FAE37492,F491ACA16AF169DB,53965E120DA57B60,1FEBA922611B466F,F258578C1417677D,88D89B18836B7C39,797852C98F149676,9DDE0648A372F650,A0184280C1E6A56E,E87F00A61D572AF8,1C59346C251D7A4C,869397E944D16A10,00005E3BD80FA3EF,CAB7E92AAB627ACD,91F648BF586F4CD1,87BC143177F54174,2C55BA1BB8CEE852,AF3F69EB71C12EC0,6B8BF0782479CE60,185B5A73249A6737,F9A632F378D11A7E,F1B8C5174F2C0678,F124C6F2C719D3D2,51126D3AF6607845,00002AA1E55F104D,DA7B4C392C382C11,3F284E7F3961283F,39C9D53CE7F93ED5,44A5F945DAEBFDC6,A3A470BB7ED82742,6E58E0AEC521FB7D,3BEA4EEF0DE92364,EE54D90BC1E7F699,CA11D5AE5B9FC0E8,7FC3A14B2CD33745,2451C26BE6A7EF89,00006EA3A76BDEED,C52676A08AAB048D,07881918C98F7272,6042EA0872619A28,012E4FAD6124CB10,FCD6D78E891422CC,891085B88366FFAA,ACDE87BB0D12B93D,5146AA99E08A29D6,2E4CDC5C273AC3CD,111C1F23A9F3AC9D,4AECF265B7A46C01,0000683BD34872D2,0581B079B7B6288B,27FC0A1627EEDB3E,A97B199F26909887,3C0A92437C4352EA,03E9EC73616B9E95,9812B063C81DB582,ED558A6587FAE74E,1947CB7639B3DD08,D2F44B6D9DAC0241,8CCB216C967ED5BC,DC42AA28CD25DD9B,00000B92A3A5A04A,7CADB0252BE32252,5B5CFBD372337AC2,083F558CCA16E09D,62C571C9B9C4B209,4BF0F8982185DA8B,946962BE5CAF5E74,8C6A1C64F3F891B2,5F82C57EC02A07F9,8B44637D421B4C9C,D6C16F81E98FFB4A,6C09A5EFFBC1D612,0000185972E064C0,B7EA16017EF0AE91,843FF58FC9C67D30,0B043EAD0509C616,A7BF5F19F4AA4F76,6E790ED64EBD9BCA,6798A6CA98FBD593,15C7EF91C93FEC81,7B1AA67E78D8B8F3,E01F501CB34EE6D6,568AB80546C0E6A4,1B47401B58D5085C,000067D443DDE209,5645E1915B78B94C,654BEE49541B164E,C0536C2BFEE92896,75CC6BF69E139921,401809D65DA26673,DF8CAB42932CCB85,80EC35EAB1469A06,1B9ACC1418F13112,4945231854DC879B,7844475CBDED8A17,6BADC9D89561EF21,00005CAB140F6BFB,974F72B78CFD24AE,8AF49A0D41C3D52E,44E0C39A70C858CB,C927E1AF72E3CB18,6EEFCDEF7AFF3A04,BB0F84D5CD48EDE9,F40B9F07F67F9194,3895082C572ACF86,C38A63DD565C6FCC,A13C0DB55E7C443B,8AF4DCA02B2BD352,00003E0B74E26E83,73C10E6917DDF996,25033198DCF376C8,76186869BB904982,F288EFEBCE248C97,DF730567C00D6FE5,498F370A12807163,B3C5A9D869BD0501,A80D70DCCBED24AA,1153422B0CCA50D6,3B726C74EC576DE5,6D5C9E6D0DFC3BE1,000067E502ADA241,3B08969565D4D9DE,56785B5B2D9076FB,118F57D8CD59A533,CDBAC8B0087961A5,53C18188807DA826,78B58C1FB467DE19,2EA422721EDD98C6,9E191713D333E895,5157D5C98A8399A3,AC7AE89EA5A41D56,F9809FBE151A2BD1,00003D6A67862722,CD4CD63D8ACAE719,4F50B8EE8232E97C,0ABC9B4A6CADDD36,7856CBA432C05C78,432A53189DD94A8D,42F3DA42933F3E46,E1C4FEAEFF39567D,B243A9C5B8E815A3,1BC13ECADB3C95D1,52EBEB1E984693DE,39D77C9CCFEA2C90,00006BE37759E6FA,482E03911F023D51,62ADDDF377C7EE1B,B73443B436982AF2,085C1256B7523A04,C6D5DABF3AAEBE5C,4ADF8227214C53BF,418D844A78F7A9ED,D524E737380C69EC,683099B228158C65,AB1C3B8A22169987,9ADC4424571F0341,00004930F0984329,9B5B72A98CDA90B9,5F0A1C711A4A95D8,ECF7D8C292A96A29,7BBAC59077F53697,F1F9A7DF3FB16907,26ADC1C5F685DD0A,A4CF78B1E23BC09C,BF15BD284A7D88BC,0761179288554CFB,F0A0790D094164EC,5465A61A2805E558,00006FB962B9CDD7,D8D5680FB6B2C9EC,8196A6EC13D53CD9,61E6CCBCC191165D,E3716AFBCF6132F9,46C1BA950471FC01,B2E4E28287867CC7,FA488D68A092B9C9,DEA04B5E7E4237CC,BE4B438219CFF592,57E5E3886156B3D0,727554688603AE8D,00003AC3B55DBF4F,1BCC001137023C60,57282E7AA3D1BAD1,CF56FB407D7206DE,122AFB4D1CA6731E,9EC3A2ED311E5A5C,19693F7DEB0A7442,B9AB210824DABEB5,0B174FF5E05C02C7,44A38B47FD7ADB41,A738C743AC787A0C,8107CC25B03A1D9C,0000249A07A116B8,69132248A98BF7AF,56FC71332FA26F18,7AF37F03AEA5E7FC,87B9F2F30A7F5842,5607176097237E74,54F974097562736F,1A122DE648EC3560,DC92917D66DD7189,F47C4540BC6003DE,0FCD13A380ED1927,5F804916FB23673C,00001A7AFB35FDAE,A846FAE15DA2BD67,8CB877044112654B,AE2397DC9903D514,4784781A27514DA9,0CDFEE1EFB113BA6,6C64528B1BAC875A,78740BFB0F9CB732,5266DDA65E7C33D1,717A99C389029E08,62E7F1332CCE4BC9,5BC66709294274BC,0000020AD3EFA7CF,6BE392D18F401095,A49F16C820CE4C37,18D8D210C19976B8,3CFAAB436177EC73,B9B7DC8C1705DAD6,89103CD5A28AA28C,3BBF8ECB413B3EDC,F1D6D736F9F917A7,B268238DC3863480,7E91BD99FFB32567,85628BED2810F54C,000043D9DE767F98,BDEBA7803A47FA68,1039F025DB10966B,E921FB79A08D26CF,6DD73C26108EBE26,2A90BAD5CB3A5DFB,AE23FF0C347DD2C6,1D93E8ACB32BC902,014FE6B8118CB55F,97B5969A14C7B016,EE047D3AB0EB338A,52E5A2000F6EF092,0000565414AEC8EB,A8AF1793B4407AC9,4E021089F9A4A8BE,EECBEA8BBEFF083D,51065CF41BABAED7,0EE1A58FD448B6D5,3897B140C4E255B6,7551F5FD92412205,91C69BE16B706A43,D8DE98289F467835,A67CFC28D604FED8,C1671FCCA647A44A,0000613B319C164D,4C30CCD67144560C,E3462226233B5812,7AC035B5FF0BD2CB,371AB15E5C1C8B80,0ACC09C04F2E4A60,0E2EABE4F181BDD2,45DED99D822D5A74,9D173338CBE842EC,3616246AD7A1A5B3,2B6C9DB4FF27A1A0,E698B824569409B9,00005225E000A8E4,1AB26155F34B1C44,C3D25CEE477BC4C8,5B14ECB528CA561C,627BDB8791AC3562,D75596E2B64478C8,996EB8068CEF6F26,2C8A65360E271F23,5F9F44705105E35D,D3DFCD8DF053253C,ADECDD1F30A46B46,428B71F33936C6B5,000069888DDC03A0,E4EA4BA192DFC522,61A2855AD703E3F2,BC943A3A2FB6627B,F23E866460F0BD6A,B92FA3AE6F9006DD,0707FE09A4C00521,14D8B85DE178DD2C,807BF705C8DBA408,F8913919A288AF33,1C9A26DECB26C590,01D263D4E51872A5,0000652008FB11D6,B7511DD39EC275E4,F339FA60A2015BBC,82D01ED0BFBB6B00,824D803E42E907E1,69C5C4BA0DE8AF9A,4D472FD8118655E2,D3D0ABC3BD627677,B155F21D0F18BDFA,0811476C15896776,AF31989AEF3D52B4,A022C2D106D0F9DE,0000513EF00C32E8,B7E4AF71CB827F07,140C837BECAAC460,F9C065078707593C,AC64C8AA59CA0D8A,147BC2A027AC0F72,D9A993DF2F4F6809,49CB9C7D8215D44C,609A7CB9FB3612B4,2F259DFBF0828105,C00EC5916D739021,7CE4BDBD72029192,0000610BC6C669D4,4099863769553B39,2F8E0E22C2C678FE,EC8805819FCAD8CD,83C469A8A91EFCCA,47B25AAC51B41C3E,DF9AEB8A0A02B2FB,D0F0CEF8EDF320A4,6ED23BE9F2A64652,D0125F724BC580AD,59A5EC0390086CFF,5276841B7FF35C28,00003FDD2CB3070D,1C01BF99ADA4FABD,F54C9731EEBD6CBF,CC1C2A3F2F4ABB76,6F8777E0CFED7542,3C9B03066283A281,1622683E53B07514,2B376911C6D38EF1,B0BFE7C76D50BA08,AA1F5E00688BD635,06DDF3824A4F0876,BEDCCD0798075885,00005CF4B85BA1BE,AF77D39393AF27B2,87F499C07FF6B2F2,0A6D1F3AA5332123,F1AF6297E05728DB,217A5104EA5BA4B5,5F9D4B96F08FEE54,AD0A06A08A554EBF,90F423D0EC033489,D9BC1EB727CB0731,6D4FDC3A62F3ACF5,F772A6B2E72BA1DE,000025E75910621C,E9CAE8D15CD29BF2,ECF3281350B3753C,F933B81B95924351,C236C4433288867B,F9145B284494716B,7592A5F8117575A2,4FA9507864973745,864550C5CD79C2AC,0A7305363E23AED0,111B747BB046A2A5,EDD178487AD5DF0E,0000662F4C229914,48648119D35EB63D,79A5772BB412D266,9DFB7262C1E407B4,6613D237EF71DF23,61AC90FEEAC61D37,E7AC8324D366BC31,16E14F7DC28656F4,FF20CFE76A271C43,88C59A643E4E0195,029172C5492044AB,DB6B676531AA663B,0000369545A1DDB5,5EEE1E77E1D108BC,8F87C9CC32532717,03A6CE8A3BB7F236,0CCAE1787798C12F,E0E7CE65B00B88EC,EF203F349AA82A45,EAE4A29C9CE7838F,4B3EE06589B7B318,62A8AEB96190F8A4,434255EE34B9C3DB,1C5B159001E3E196,000007A19A6E5036,545E770074E7F179,EAF6E2A2539BA1E6,34348F64C519C848,10FC13CE7162063E,7DACADC9DB3D4A31,0E1BF3297AEF7B1F,4F3EB2E2DFC7C8F3,4C453A87566CB6B0,CA4242CA3834BD4B,4E4BE5E685025AB6,9DD18C2AE393C470,00002794ED606971,CBBEAFCF0E7DE117,EC5E5DF0E466D9CC,E00BE6112D9E0237,4B9153D091707E67,BB43613C8A6E70F2,8084482822C11F9F,A0B77577341C3C08,535FC9F38147F65B,78641DA8F691F549,7783D68CBFF2116E,B9E439DE42D6515E,000047449FE432E8,F27102ECAA671E18,79A4A724A90246EB,2A3706BE03C4B10E,E99F164242003470,29B0A48DCE491863,E3BF578609F0CD14,A90C6198CCFC066C,E6ECA061A0415B32,404F64B63C180425,0C4FD2198D73C4B5,A4B1C9117FAC2815,000014B0C15F8C86,60FC0AF82059CC4F,195ABC426A9E6093,1F06AED42311310B,F6EC19125BD287A0,8587BFCA8E71B597,7233BA5EDD5D2828,B99495D71F035ED9,E905C09546DBD071,F994ED6253235E14,20AD2057CD6EF3A7,4DF5FD5C2399C4AE,000047A034199649,70DA216BB6203F6A,69C3B10E283A41F0,41B6BDBCA4204172,160786F1971A7134,7D22B56D110DFCDD,2C971980B59F4BF2,CC132F07E48060F9,98AA34C13A76D404,7CA36B247B32B176,356010A70D439A11,E705F042351667F7,000005FE4F9E55E0,350CE84C72E8E8F8,C3041F72E6D71BAA,80696B8E7331033D,34DE4B71F92EDEE4,E9B0C77932514501,6D2F10AD7CCAF322,5F235C93BBD5A820,AD6AABD5A0FCA4E1,8CEE55301358A73C,76F6DFDA6FBEED99,ABBA6680DB6967E1,00000A894A392045,4A0E6C73E0DF3138,70DD83CA16F5B8A1,3305AFDED55E2161,2CE033E9D6A15D2B,CF8490BD3FE40317,DBB20F8B77049505,D8208C3A1D255D31,84CD5F290861CF81,C21C4E6DE9C9200B,5A9660593975B591,FAC4278BA270FC52,00002EB3AFA62D8B,FDE29AB5436DE426,9A1B1D61B4294C3D,6CAC87EB91FC9318,378EC56F9DC636A7,6F8B93532DBCD321,D6238D76DB36C174,B0A9CEC0D0F8D7F6,BF4634E1BA75350E,6B6930324A2E9344,265726546BE8BEEC,79B3B0DD594DE8B7,0000167EE222FCF2,E4D32F1335A88D8A,9893565F35E107BB,0E035C9484BDD63C,AD339C727702D374,3CBF021D1B890EF2,61C13638D613F0E2,006481907EDB0265,B31CCB8069C4A62F,0039128D04B76AF7,92D8C0237BB59C7F,28678171CB0EDAC8,000055012AFF18AA,6833FD5521A9AD74,3FE4125C294AB463,3446286BDB70F0C2,3DB4C3EABDE967D3,4A96A34C85DD6F44,206B67070AA3A3B8,3B78F226ED37E5FD,F3F3AF887D58B894,140D186ED4BC7B9A,F7A8311ED7CCCB72,9C62734E6ECB9C63,000052F6E3B73968,574A009863B4FC3A,01E23481621CB34B,952583FB7AF18F8C,8BD0EB410A310410,A6D92BD68A024181,0CDC0462D8470C55,29A9445993BF3FED,9F7691ED41EAA27C,E2B35F878E0753E6,A10B03C7F8FF7378,168C040603289967,00001C4EC722D84D,ED95F8141699B72E,8C0299F2D8B30956,BE27B50A4D95192C,3C141ABF430D5F6E,7CC8E070F603D755,15902A3726D86C80,D32301E2E6F4CC29,D9989F0DF2D29EB3,603BAF56E1E4DA2B,F24296BA1FF689F0,16B674BDC78BA3E2,00006B83B1150EE8,0D0C144DF9F9AD51,5AD79C3802853F3C,C13667D5E6D4D511,009089402771CC2C,9B1A9A4E1F764E47,62E676C7E7594B61,29AEDF8829251531,9A8C6402E62D143F,37A374A6B8ABD77C,45BC4F48963B3308,A5E4627B6B07A51D,0000162BFFCBEE2A,163F86661E6365DD,E7533754FA7D2724,19A6194A3565E6B5,8AB998905095D016,B2B6D2D10C98EA61,69D179E3CD383324,78A21689193F9585,B9F09BECFBF2389C,1D38009C3952E79B,2162A30AC6CBB6D0,6FAF7C7444C0416E,0000324F7FBC2CF4,079DAFF1C2469E08,CB093C1B1A81C935,9D00C3902A76A8EA,92EACC64B3287368,38629BA874BD1B94,BE2F2C8B3D5DDC90,0F1A334A3BB696A5,01DBFD3F6D299D8D,D5FF03940468F1DF,E638B94414DBBD1F,13CD3F42046C2813,000054CBA873B4AB,9EB8D69C403DBAE7,25283B26F230223E,D842F47377682B76,28D4FFC47DDBAFBE,0F55F4E2E0CB0E43,F94B93B34AF61BA8,2C7BE395AB09D255,633D2E55610D6F84,634DC7502EA9D921,C54CBA98B5E3F49D,664ADB50EC5020FF,000001094F8FFC56,F24B99815CE7DC85,8220CF533C675275,80B5656453419B4B,523216C6FA913231,7A2FE2DF54549075,15818454CCE02462,DE30F87BC001E7EB,27F1D6A553FA4A0E,EF52C58D70B8F262,A2FD4938484A9E74,431E6B71510DC8BF,0000146EFAA8B06F,B7AEC3D1C530812D,C16EF2019E24D9F6,EE3DB4E277856275,7648581FA2601C05,C082F4F12B17E965,CD5DA8C67E1868C3,A2E2773BCA1C9879,D430E2A13AC36B34,8D57F60940DBFEB6,9FEBFD9B0C2C996B,0AB5B870B44EF5BC,00005E02CF680A84,3CEFECCF3A89E3E6,BB8237DA0EAC8DFC,9504469CD4762EF9,4CE43266C1A06F3E,EA37F3DAACE4407A,B1F642D7A7077266,6292BDB7AD2F166D,D2A00531D44D5127,4072EE584F0FD357,6958974DDDCA3254,C7CBEC94DBECC412,000061F7C06698E4,DD55E483BFEDC4F6,C94FDEFB48FB88EA,6491E49ADE323AAE,BA480AE0818C19A1,6C2DEF1B919CD8E3,F22F72263AB7049B,C6B2D987809F3528,74E2BAD05166E199,B1D7560929D57770,2F4225F86AD3E239,524468946ECC165F,000066F9CACB0695,0837F860B6CD0248,22469272105052CD,8EE984EF04CCCECE,86062E2D433898B8,917A564608CDDCD8,E5FD6527C3021182,B91701761908A121,61A11A70A8A808BE,9DC353306C9A0A66,E216FDD545087903,5B6A72D84BDD23F9,00001CC8AB6C3E2F,49FFCAFA9349BB64,A6DD45B028EAF01A,DB9C949FEF33C546,50E00A34C483012C,6D5DAAE76F3C46E2,C781767ACBFBF1D1,028244B2D1400266,B2A8530283FA5DA0,4B2DC755829BB6F1,0F22E3BAD02132CA,C5886BABF489AF8E,00001EF6BA045071,7DE868309AE2E436,1600AFE88727868B,67C5F0C899FF6DD4,313210691D1C0DB3,4FAC902C50512806,4EC8B6EDE4BE90DB,1988B0885C1D7547,81547FF26A227659,E76F2725E0BDF6A9,D2C4B0BF835904F6,E85BEF0CF2DE17A4,0000012760657FF7,4A46F8D8F029C7DE,4B5DB63DDE8542D7,E97D4BB3CB07CAC5,1A69BD5CDC26D827,BD4587077D3906BB,5693889F68C4121C,BF44D6E3161F3F1F,E210FF41AB5D089E,6130E98E93D7A274,7737CA8887D2B487,DC7CE06D81BA60E9,000010090FB99355,F1909C550E52BB5F,17239198769AED36,5D9767B8283488D7,91B6C60E78C74AAC,AE666ADC62C8E0D1,27309DE8CFDC67DD,0F2C4327D106D929,9759A512E1437327,8918F74751261350,F15A9603DF07A30B,2D0B4058F999FC55,0000070345CFB2ED,404A85BC5F859384,12EA508C3C53B58A,823DDF32FC9E234B,E3D462CC453C15F6,D068FEB0BE59061C,0FA01C1F495B9DF0,40491C9124EFBF86,97B8069432BEEE75,45B01F0AD12427AC,FD266DF28412DAC6,7ED636FD829BB33E,000041C8CCBE4723,BFFD3A9154079275,8203B7F3F49B0A0A,49AC0D3A17FC4C32,EA503B6FA6F067DC,813880BD8B6F5EBC,480A47BD8CE5CDD8,C9E3895EE7EF851D,B8B251088F55FB5B,719D8450B0D7F88D,66B51162A7C3F486,E1440BDABBACFC12,00000E0676101F90,7264358342DEA451,DD3905E4D2FC4A99,FB46E8230E245AF2,A05CFE428F9AB3FA,2D943CE1A29E8184,5049A0D9408D02F9,4431548E0A4C99FA,171B9049A7D3A2F6,2BA022E3ED0A09DB,3A15047C7335A371,2EC28F48A37DFF63,000044484171F929,8C52B3948493CC89,A770E343D03E2CEA,44E04F47CBEC306E,2E5E1DDB1C63B028,D830F492E5C15076,4B5D2AB22072A622,AC65D90D47F87642,94C6D123D9A513E5,EE36368450078663,11FB73ED63034835,6CA281C995E816E4,000064D4BA77D763,11402B37A45E2A51,89E0FD043EE877F7,C50A437369165831,875D45C55CC3D6E0,80541919C3150C48,17819BC89BAB68A6,60F3000093C8C3B1,E54CB7AECDA58889,CAFA972219020F0D,2A929961CDDCB81D,2EE9AED167263EF4,000031DB3E5B8C69,CC127D169513B4FB,E7412A9AEC23AEE4,7D51BDD7280E902E,98559C42F02D0183,FF802D2C28D2F47D,AA1653209868DC24,B962C5FFDC1EC7A1,ECD080D2CEDAA5B8,DC5ADE7B0AA774E1,C7E70E8E601C30FF,918D081D5FB6FE3A,000048795C6D101C,AEAC241C35C9430B,80B516F0902206E2,04EBCAB409FDF678,0F439D3BD2B636D4,D4975E3661318BA2,840D872D64F6288C,AD86D70D30385D63,25F6E066EA1CF4F0,FBD57BFE23487F9E,4322D626F848451C,02773FC06948CF46,00001B5A1B917DCE,5BA8F1164692989C,9F8345C9B4B90A24,9019CB8011B80D9E,A81AF79F9DC2CB42,D1CB0090363B6B77,8D4E6A952BC20B2F,DA87B10D47832F7F,766A77F9A4187DBA,30882BDD426D3F24,42C5F6EA8C63BE27,632BF7A2D1FC286E,000036B957CC61F0,CCE7E3F1009D0FFD,6CDD9030C39FABB4,A30BF47F180EBD76,ECA136E4C2D85908,A9345F79D6372A3B,219D47C8BD5A70A6,588BCBEDCAA77B84,85F64D1D54EBF859,BC287BDC8F3F02A5,FAFDA106F4248C56,ACF687862884879C,0000190C076C7070,53E74F70B8644717,BEB078DAE7711E1E,B9069E259B34A638,A318A7D020E73D0D,0D4D1CC7FA7E9EF9,6EE817F297E1B8DF,FEC759570B8AFB5D,4A3C35EBE0AA2E04,6A70F3F82A48C274,752B741372D22C39,47D1215355925358,00006F87AE0A0301,43A190CA75CE3923,34566A6A694A68A4,4F31FDBCB5893CEC,6416DDEA371E9653,83E5A2FEE0ACDEEF,936F196C2BB18B1B,0B52BDBE449A8558,BED885EE0A5E2FAB,96112EDBFD8E3CCD,6D875E0D41C7471D,8BB17D6B301CB580,0000572888176520,55A631F313705B8B,4155F42887E77A49,26F60F28E97878B5,5AC425B806500611,9BA0BB6779529839,47D3E724E1D2F08D,6A43124F507D3833,1039AC54293E710B,FF6BAA674376A9C0,808E01D2C67F32AE,E3C839F41BC1B845,000062020A64027C,D0BC0853E7DBB810,805774F124C3C1D6,8BFBA888F4F17D8E,2031E13A329B70D0,7DFE6C60100512CA,71C2139DF6F44A29,CFBEACF3F8707ABE,C9114DB505948E8D,561C78EF5CFBEAC4,A5AC4D6280AF8C6D,9A309ED6F6E25A96,0000035E248C9DAB,B7A5E4D7F18EADA5,D60DEB3EE883942E,6A447B75BDF80CF9,5780D90877B3476A,5750D757540F454E,81ACB7122F2EE39B,BA5C2CFAB6D0A205,E3F8311C0B583D24,20921086F5080461,8FDE7DC1EB0DD7C0,69DCFB537252083D,000038485E765CD0,C4B40C26AA05CBE0,8F05EA5E2E2F9928,6FD490577D23F149,BD907DF1711D2057,ECAE7F24E077B526,76DABD89D109F29C,6220F39510594B6C,B920A3D6E10491BD,DFAD3934208280F0,8D221A36E74C694C,0BD8343AB885BA88,00006D3CF961503C,8752A940F07874C2,5C7332D1111A0A10,525840FE1AF7C28B,7FFF8FC42FB6B1CA,947E3AAF50195279,711030B02BC2F083,52000997676CAF52,6761A11EDA591354,C92E6EB4FBFA819B,050F9DA312E488A8,340A8CC13124E3D5,00004E3239595CA9,06D92E42FB8D177E,69558510BC89904F,FFE82549CA23262B,50D8D2D8988DE457,3FF384B94D52F460,49BB780AFC043992,B09FFB6A6C790C9D,D7B23C70916F9500,8EE511B81BF78C9E,629468CE76BB196C,AF39BA3DA362C5B8,00003E19C2BA6251,FD77E85E45F98DD2,0875732AEC8CD831,2D1B51C57EF80C2E,B991F3727FFC626F,26420FE0252ED6BD,C3732A6FE620FB4D,688AF07711ED503C,1FB71FE3465CD6A0,0FCA4F29BECE2C6D,8F0B74C65A7B9B2A,6A82EF2343EB328A,000054A348A2F561,3BBB49A3025B1FDF,380CB680E1307AD1,16C2AF642EA9D373,F67C3E1FDB5A70E3,722ED19FB2754AF7,89F07E5D4FD3A5A2,3786389729B31661,BD86E2E6427D6D91,5A8514FFB902F610,6614186828F92C1F,5322403C765E2EC3,00003B84C8D91E24,01BACF384CAEB153,2A50DB82F72EBFA3,AF09816BE4827BE2,7385301696026F7B,3F2F0F1D95DE95F7,00684C895AE02856,5B0604BA306304B1,C92F78842BA1C402,D92C5F767557B1A3,57BBFC14BEA42552,DD0740E322C92A98,00005A00BA4B376E,D0595C5CAE6365DE,CAA3C00CD880DEED,E076BF596C304A71,FB6EE21987327A69,9D402EE23463239B,AA563E101969B5D1,5C4558364FD25BA7,39024247C2B92B91,45941682B42F7014,8EFDD5116C3E87DC,BECA7D63B3A3B835,00000E61119851D4,F9EE298CCB07C4FD,06DDE07A5B765D3D,809457CE9B215806,3212215038CB6364,4F0304068AC64EC8,D32881B40D41022C,150CB4B63239C875,7DC2EB03240F729B,AF9D17D6219D4930,E9C534B1C6BF87BD,8438533430D9742A,00003B496460BAF2,4154A07450848F80,6B020072DB659254,0F5353E4EF702FB7,A6AE85B8C522B8EB,F08204AF6D3E62D5,5E4BD31CF92C602C,27DC7231DC4C5ACA,3E85DA2E537D9A48,BCDA999BEEF1BF94,22B1C48E0AAEE75A,20805A7F3D8D0774,00001F8A45017E3C,FE3BFCDF32C015A7,EFAC173D75684FAF,058B2A507B4E057B,966DB6315B878F3B,D25B4C35F7CC14AB,0267F38E82696F6F,FA7EEFD769A3C5D1,BB5AB169D5EF040C,2B92119A973FD6A2,B0F6F953F677C499,51B22C7187C7689E,0000435E6716DADC,E0CB9504593722A6,4FFBE47150E3D725,904248E72024EE58,AF1652F5B6FEC55B,7CC830D1707EF58C,3C79804E522C2F7F,66853970FB92E763,C61ACCEB35C1D6F9,DB6ECDEF8AE601EF,B9DB7D02CEEAF7F7,88AD05E4383143FB,0000062A6F9453CB,F5D2D962BC2E42D4,F1C98C2AA0AB555A,72CABC67A7D71D24,831CE8DEFDFD3FF8,5449B2A82AB11C51,53ECD09EC0FA60F3,414CD2DA07CAFF6C,A895FE79EBDDA03E,337842E3B63BBD62,37384D34D7072453,81F69D70D40C7929,000060316A09CFF8,75C8BC8AAFEEBE76,5F315C5191755E77,25AA7A5AE487E0E3,5ADF22BE5F4AA949,9CC7F455EEF753BD,8683CF1FC9F99761,9D25804CA422BACC,F609D9BE999D111C,BEC4658A5A727281,69581D00F2027B6B,09461541FA82832A,00001503C76E6A77,E3BA39113D84BF2E,FE1161C9FCD78D23,2A3E51ADF67510EE,13C2F8EB1963A41F,4D90760A5ADD51BE,1F4EBBC591F52045,E5A4BEDC8B7A2B56,D2890AF64C95D8C2,E065145CF7563B88,2D15E72F4386B40E,A9C0E5A0DAE1D6D4,0000165DDD910685,62099FAF5B228D72,964FA601DDEED1A2,9C671DA5B89DC411,3E1A5ED806661525,B0F3C3C898610D03,F83C9AC077CBA83C,25C3949AC2AD5945,53FED56385FD5C26,8A491BD82627ED94,D840B2AA2E741FCB,B11C2BAFB4B5E732,00000E5CB9F6315D,A2FC62753E2E968A,CBB2A359C796185A,54931ED1ACBF3FC9,616F203F162EFFF9,E7AC313124167B83,D1C559C91CED92B6,065C9AF2F0518546,2D39C6A5CA0E7CFE,943B543FC5A22BBB,2D62190DFCC21D14,D36AEFB72A8825F6,000030B4BE635987,D5105546710F61B0,0770F399CC420E52,CB0A49DBFCD27396,69137A33A31E22B5,E85265FA8BDE429B,BB703DE2AE1D078D,DB88E0C87599BF12,780E5B8BBB669F32,6AF825A6E385AD75,E62325D250662D67,42BB61BCECBE88ED,0000447DB3EDFBFA,23CBA6F7DD7A0320,CB52060F012CE738,B90A7B0652CA95B1,EF07345596FF043C,341ED2674F0CE68C,430BE77A7CF89D6A,E3EE28ED8ED72D8B,A9A64B20463B758B,C2B8220ABA61AB5A,0CE49CA3DFCA6B57,30C192E55FF31398,00004A2DA9B2F32F,D99FE085129F339A,BEED7E437FE4B91F,198E08321E600FC3,CE7A330290DA8351,881EA7B207C30B0A,0554B74D3A780A4C,173D8B2EAC6614BB,47672F31877C1ED9,E4D034DB8AF97D26,FA95CBC26BE504D1,9B09B8FB9B77E2F7,0000595D75884F96,33B68BBA3F235CD9,C580B6B6DD06B092,76D4BF83E04F8BEF,7C59D74D5248C39D,71098BF7E71E0FDB,25D22FE9E6C62A22,BCBC88E536A4A8AB,0388DE2AF9B2A98A,229B495954264BCC,67D4D82B1DA60C3A,0C51485B84CD05E5,00000F648EE9E0C6,6E39E803052BEC21,3E049125D6E36D99,538077C48298AD02,2773E9B159F5BF85,059505CFAF35096A,3E1706D024917D58,886084BC58709B44,5D55F05B40190926,C7A43C9A96BFA482,DCBA7EB0CA34515B,114847E17A4DB25B,000008EC984BC9E0,AC7D42F602948B4C,0F0A3541B3504161,A3029533D5D7D24D,C19DD746AA4DCC8F,7BCFBAEAA3C1225B,249696EBF46CBB68,E7C5DB4583329C29,2E64975E14C4E9E7,4E1BC5363E37DC45,258030872414C0BE,D34EDE9301D7B8EA,000004979DF4FDDE,43698EE563250D2F,B78656EF6DC30732,941CD546BA4D0C19,B8221BEC4EF93B79,68907CF64FE9F4C6,C1744E0ED94BB79C,033E16AC58EF480A,6F009DDE3CD478D4,9B60E44189E577A7,3E6C87522F2F1FA5,BD06DDA9FDCDE5B9,000027FBDC4911DF,9079C28DC4C0466C,88A2F356F3D8998A,CE78B995D4D5FF00,B7B798D4EFF116ED,8A9A0AEC505FC30C,546D43E8EF2B2DB5,3F789A3AC189FE79,F1A2EB90B7BA0D0C,4D09447B73457E8B,09366CF477632083,40F2AAB4F09FFDC6,00005F845D5B673E,C8938DFDD797977A,02DA266EA8142CD7,B242C9B33C3DA1C1,5A98068AB3037F20,08202C3C7ED24769,887E6CB992E5DEF8,6B8C4AB0AF155320,8BE25CEC14E2985D,58E1826C1A64DEC7,2595C95ADC9A1902,0B7AB6B4790ED095,00006D8AA34C7762,83CCB4E6A54BE20F,7E263453799C0B7D,9A814678F24CEE31,BD4797B06D346233,4D9A70AB50C1CE15,BA1AFD31F14A6ECD,B3CE050CCB03B10E,45F2C62351F25E7C,50F93B26DA8D28CE,325D4106A56F4F3A,69B0E41FA130AF17,0000385A96D71C05,3CB9FC0A48E3EDE9,F1E96BE51E64C4E6,2D7F4D22B3E3A8AA,024A8D6E54255436,4015D43BF3ADDA6C,F2778CCA9769F67E,A4437014F97DF15A,FFE58E014984BEA7,61BCB5976E6A7544,1797BB88E0D69959,9D3404E886DB242F,000009015580F7A9,C51F6FB2D3225D44,8F33177A890D94EB,A3BC3781270FC21F,B92509EC25DF4AB2,7288570DE0E89272,66B1C2D91A67CCB5,10F5046AAF67BE46,9A15FA0FDD2A258D,FF339F487F95BFC4,92CCF9E7B523D86C,390EC3345709D373,00004BB4D25EA4C5,0D89E6B882D8889C,78C67A0AAEEBCA7E,615DBA91B041B620,E5A2A3C4FCC93F00,EBFD90DB3BF196AA,5ED8479D70119AF5,7D6FCD65BC6CDA66,992A918371D7D1B9,31B3B18B0F7B501C,BCEB5AD9838C258D,DE99067A55E1569F,0000509F099B6C91,1CA989E084602AB9,9F96DCD19E9EDE47,7488EA04A9B8B87D,E049354703F8B872,2D96C02FA44163F2,B396F0A09DFE005D,454436CC5BE7E9C0,FB8BF6CAB02BCEA6,0C5B7E8B6912FBAD,93F7134EF93A8216,493C9A7985C9E5B5,0000216E1ED79591,27826ED0FA0F433A,ADB6F3A0B4159327,6E77364365ED0458,826B42CA062F7262,75648B03624D1C98,9C29D286E9D31260,7E28FD7905288FC8,B3237C40D24BDBBF,D8A4A367312DAADB,70E5F5A0F87D5F13,3B434A5C63240C74,000037591AD7AABC,1A087782D35F4094,409413D6F760ECCC,1FFFC1EB5B2260BA,515386ADFB6EC7DE,EE65F7EA9EB05102,30DB44D6F9E416ED,D700699BE8E0FF83,F17FFDC224DC8FC7,99E48A171A4A6C0E,D6290BB2F92405DB,C62F67ACDAB20D0B,00004F791ECC09AA,A6E8D8A944FC5CD4,3B1ABA3EEF386282,33F8D6379789DF4F,A3DF89306958E071,C3D3568D72695B8D,2CCA0456D1F7732B,2499B435AFE5250B,8D23F49175C0ABA9,128F94DB71F4B8AB,4179DDAE44CEB809,D68E1F0D40D901CF,000044F323A5A9E7,86D6F886DC38CA5C,B719638682E1D30A,E37E1E1AF3F84FCE,3E4115567435A9E9,AE3A6BDE0689328E,44A8E9930E6EE768,C7F5653D74323110,793D7FCA724B138C,8FB726956969919C,288B72FE23A5F981,06106F76295D489F,000063112F858470,C69B39479B161D45,F5F0A63A5326F136,0FE9F86361EACD4F,99F891F19D0EB4C3,60F3AD122F95A1E2,82037003390BD39D,F51C1D1CE38BB621,86E96B98B7DA8333,DB459882948DC0F8,D24D7D99B4920FBC,947F3929D58B5917,00004C3C00885EA1,F7F54F3C18281D12,BFF10D23E1D79600,2A8F191A33BAFDA1,369473EE86EC39E8,F0E6F812D6B03510,B5111C1411B40CA1,9740507C33C67278,09728296787D8E75,63E6612BE572BAC3,05E037010024AE01,A9BA0142BEAB7800,0000582DB25F5A26,43F91D3274983F40,96723800433182E7,3E523F683BF6FC13,16C024D32DDBBEBF,C161E116A30E2152,29FBB4E1C8C0E193,A13FCFCF2DA037FD,4A1162C42B363D41,AA66C0BB8EC9F1B2,8EF1F3C9842631D5,F39D5097DCBFA76B,000047203B4ECAC7,DE6C3AF9B5A82E24,95F3E740808DA0B3,08BC11173D81B5BD,A815CA90B5CA4181,6DEF41446E9EF803,B22BC72533E2CFB6,8847324C03DE03F4,F1DFF7AE3EB998A2,205AAD52978F990A,366D17815FCFC6A4,1633E3FB6F4497D4,000035EFE5BD9782,617C470252D1AAA3,B68C5D511B7A83AA,06857C4B2D50AA19,A9D691652A06ADCD,01463E8676027B0E,8BAC2E119DCDBC7B,1DB6E68021782C79,617B51C5C68BBED4,A4039BDB5944685B,B6A757AB3D62311C,46D7490E2FFDF149,0000593BDB0D5364,2C8C8AA87DB5D09D,9385605C51564507,7F5C08BE71C9C140,6CC23ABF3183EEF8,1F977BFB884A48FD,9BBA31E6CFCBD87D,0AEF371B937AE0AD,402446E29C68E969,DA2A4D50261EA0F7,2821B58473D9D48F,62DFF698AB3C6D89,0000064800815204,81960D259AE7ED42,D39495E1A303DD1E,026CC614344059C9,37CD9B016D5CAE65,9B6B88789F19FC7C,1E12977FB29965FC,B236C7B1CB0C635F,2B4AAF156754BF3F,43EBE91026DD446C,A23799F7C2593171,41A9BDA42C36D7AA,00005A716E69390B,EA011917A1147E96,A1D4DB302BBC82CF,9C446D86DA514A51,BAC64C4EC480B6F1,22B32D1FDE12CABC,A0F2149AE281C101,FC190DDB8CF78DE4,E9820F2281EF2883,49D0747C02AC5EEE,CE0A0AEF32B2D5AF,7DA324746261642F,0000551E0273C92B,BD9E6F983B25A65A,517AF4646A968919,0E755D92D005BE03,E7106D42232B668C,262417B1D3E51F00,19535956B2E47DBD,06D5E7E09E81426D,752E8714261E030B,8B51CD82138984CE,F8625946F492066C,0821E2CEC4C9ACF8,0000075EEF5A2D90,86CEE5B094634355,064CCDFE602D433D,50CA0DC170425EB6,08C0C2BA3F7C2D8A,FA71C3685D4B64A3,6F925FA697328D7D,0657ACA787692DB4,5908F9F42193FBF6,506945D6D908A1D3,E8274B1F225879ED,4F7D8AA9577FB0B6,000060B1C373C937,DB4B081A5709A600,4BEF9C680C24548D,6884611151FF7989,6A3FB6017AACA212,D98AD5F933AF6F0E,D56DFAF73EACB9F7,EA07673B1B3B3E5E,EED8F24D8D13CDD4,921DD3A22E4CAE26,57C571469CAED30B,312CE11B64D5C275,000022D3CC14E30D,826B12D06F57D315,4DD8AF904CE64A11,D2540B7AC72AF9FB,8973AB44D3C56BD2,88CBAEB43401439E,DE51263417DF20CB,ED06DCD5BDDB04CF,C6B373C449B9B056,65CF21EEF2A05272,2BCF4C5702C850FA,A5CC5F1F2EC1CFFC,00000CCF40DD7EAA,8C9A3155E1E93662,D9100D1CBC382CDD,1178FAFFF6C7754C,1A73718FD791A0BF,3DF6F9664916CAC3,F3F084B1A09B1E95,22D36813E4F885C3,828C9FC021F36DF6,3A49ED42BC69A2BE,DFB946994EE242BB,333BBD531EB653A1,00001B2798C85FCD,888ECB498D112F58,EAF609724AA18261,9A0D66BA3F9672F7,C857D7A8BF9D974D,AAE5989A13F4D7D4,EBCCB78A7F9CEB27,E2B786C2750B0BB0,6704685426AA92B8,9DAC8CD6381B6025,D8BE417D07361596,2702B3126AE73760,00004DFA35CE7664,8DF4F1EBAE9D8E9A,BAB5A35C7D5A3D57,0A1BCE887D5289B9,5779F41C0CB21CF7,226CFECADF4D323C,AD0334BAFB757DE9,EA05EAAE09DC35BC,759D8FD3D560CD1F,D92228A43B276BB1,5198742ED08CDF2D,19942F2F84E7F79F,00001EC0951EF8B8,6C5B5D0146DE009C,ADC114946C87821A,67B4A6EBE3873CF6,F5FAA51E972FF78C,BA435963EB10DF46,9F459B900CB784A4,45FEB181AAF9F882,25EBA2167C681CF4,DEBA7A8E6CEAB6EB,9B4F6614D282B7BB,3E357873C7580AD8,00004E2ADF29AF11,D8C6721BDF0BE16F,1064200FCF6CB632,ABACAE1A118B93E6,18526DD08E577183,A5B85E3D25B46B2E,98A56FC119FCB337,3F41A554A23908CC,A6F70C313DDA0C32,DBE14EFFE2A3D31B,BBFA6EDEA81F79E2,89F3B80DD0379CAE,00001219C43CFC3E,92EE1EE04F48A58B,7FF04E1969FD0788,EDD3A67DB31CA618,8916702CBD2EA58C,6386FA610AF6AA16,4A5B9BDBB8E82B14,D45362BEFF338D6A,D4EB7723296D03AB,D092EDA0AAF0B701,2D967D50E95B045F,634C2F42792C6C5B,0000081E300E8A09,826454CAA3A09407,72034B310487460E,39AF1DEDF6600211,5E6E181D683A7493,C895A68DFEB2C612,D71736721A25237D,BFD71D2119A0BCAD,843821D7F79188EC,BBA8FB841087B191,629D500470851651,F75B7787D19FFFC0,00002BAE3F16217A,C59BFD5C8801DC9E,EE26BE5CDD9F1CD3,166C923D62C7849A,4934E989532ACA6A,F955C4F2885C13FE,2EAD02D9ECA78626,4E1C1D670C7BB958,D85F3378980EFE6F,2163E1AD79CB197A,8825F3AC9CDB815A,CA17EDA0681863E6,00005336F08F4C88,EAF164C8C548E1BE,3A4EA55FA701ED47,50B58B8CD649D906,D678BAE9E921657B,EB790E3559850389,E6B3B93EABBFE755,AC34F1B07FC18008,55807F24FD7D3BDB,ADFAE45D76043754,B683D46C966F3A66,95E96E09ADEE56F2,0000082E493681BD,1ED0A09EA5CA1BE9,524A7EF042540C8D,60A4E06F280542AB,09D08F6793A6E9E3,69EA6E6A74BF8F07,249F99313DF1D718,E8A430F3AF5A3EB9,FC6971F42A90CA55,45136E8B7B7539AF,5712B445523B248B,91AA56CF61A6F5B3,00004CDCFAB2536F,D75B3B9D41A922AD,C22629F944BDB5DC,3081561B71440535,BAFA9B03A02BFE9A,919CEDF92C577767,3E9AE807BA6F4B94,9DF2095B67780D31,880A43FC93E62620,8DA593EDDA823265,977D8A6CC53B04CD,EB89A4C59EFA6A2C,000051B980B09E22,45E2C3F08721673C,130EE2C4AD8253F8,7D43A58684830372,C325046C6AE7BA27,EF30077767BC0DB0,F0F8BC4748939866,1D84B8B1872D6917,1CC4EF899D36D131,612AD00F61A3FE9D,446025D92C71CF6C,9CFBDFB711B80A77,000015DBEF23B55E,47156EAB74E321A6,5025084B568E6E7A,4749B7053A991DAE,8F138628DC1D1193,3D0A427E7BD06E34,550B738354174FED,421E0BB2CC63CC47,FE6180A380087E57,5D09FF656206BECA,C090B8F98ABBF54C,E33D2C5362E1E4C6,00002B95DC993FCB,8407D2BAF88B5872,BBD3F1662C48966C,4B316F220CC1492E,8D6CB1160F8A411C,101AC1831678F50A,33B5A552917A42C6,8BA64D409BAAC6A9,D2E3599BF23FE3AD,B25D96B01E42C355,4ADA1F4CCD3E3CA1,1F1DAA92E5695C0D,00006B2DD1129A1C,92CC8A566BC48905,C06E9BEA7258D0BC,F448F83F7655E98A,813BBEBD5523B99E,955F705F87743B7C,664CCBA55331EA78,C54D71A70EFE08E3,F667761BD2BB146B,D835C5BF1E157978,BD3A3F0DB1A39ECB,A40B92E43BF20CB9,0000043C53B89FF9,4A405DFB9EDA4834,08DF828E839261C7,2E4CB42DEA5C7260,50FC9FCFD72A2145,FC44348AF994F8D7,8CA9F70884C1930D,20C219DD93290F44,D086BF6FDCC99C04,81C81D1A75D8828B,40FF6B100EA63F0C,E8A276CBF24D6B27,00006D8AA98F646C,C6BB2548475A5830,0240686A7B67EC08,D7E2C4A16550DAE5,790E841E745CD847,369CDA97F15300D9,2F5F6DF604403F23,3E6AC760F9B09732,C01EB55BDC1B020C,52F3F1E85F67F695,59BE1AB0487CE411,1DAC4A2A65D2177A,0000160FB4267E6F,E139051EC5D5CADA,7CC3FC6A796C80F0,BA99CB5B4DBEE0A3,D5C96C0AB3A7BAFC,23B67F0C99198DDD,BA910ED65009A39F,7F122245E96A0260,1BDB9D0F298EA95A,39CBCAA90B63251B,D72EB516A4C2BAC5,ECC7668335067AE3,0000581C25AD859F,788FD66657580541,1B7CB4E2D350B3B8,6E0F680948CBD410,8705F0BFF4BEA166,8358F349DD83C9CF,0EDE6B1F9598502D,FE596E39D7993752,3266A55EAA8A592C,4B492CA7A82E8BF6,7E390228C93267FC,D04F8C9E8F793BD9,00003F5AD8FC8833,460042096D52C2D2,163D738F16C8B144,63698CDCC5025339,FDDCBBE5EBB76CD1,783407FC17AC4A8D,75999CD55F9D74DC,D70474C617E9E0F4,90B2DFD9AE58511B,AE766367FA5AF928,D5D711EBCD1FF10E,2E434CC2B7D834B1,00004E7D0D9A9351,100C54933C20ADA2,A895A5569B6259CC,633EA57B27346063,A969B3899C5A7405,E5DE8208635B6236,85F37FFE9AF95875,99DCB6EC12C9D68B,CD1E1C5047D19484,9570F43AD7946DEC,3690DE7F0AF15A0C,9500D116AD1D639E,000024EC0EFAA689,AE0C137BEF410361,BD200155578B3C01,F6D3CDB0DDB5464C,2F70824EEA5ABCD7,C48EC74D98636161,960CE791D744B880,B6553C7C5C6D7020,58B7F762E794344E,EB758F735B37BEFE,C3B0927B0E98C790,42800C7D2D2980B7,000020D9EE8A3585,50A0E113B3C2216F,41BF8B836AA7B385,79104052AC2ABA13,5C276CB377F3B27A,704AA7AB4E44F96A,AE03E33DBD247E3D,76407DB5CD0D98BB,DE91B4CB12C18D26,5D55ECBC6EAEDA31,F0574B8CF3943AAF,B1B96F14296775C8,00000AAA12698F34,8EB7B9D84A5EE71E,8CD0A5B08B7B5BA0,8A8680B9A06E2D86,558922DC8D3F2AEA,0F29704B4811825A,D64F2FBD14313B21,D358B2656C88297F,124C2ED97C76D674,8487E320470439E4,FCA2CD1C70979EFE,012ECAC89483221D,0000112ED31B05EA,241D759C6930D842,1F12C4E846DDDD7F,A7E95D9245F166CF,7CBED1C2302211F2,29E2E767B25EAD8C,7D29E474B613F4F8,03C53CC0D59B23F1,8DC0B9F3EB761C4B,9961F25ABC2B144B,0D74C73C52C088FF,E5AF3ACCA7608CFF,000061BB4FA25F01,361B94D29CA08EE5,611100A5A0CD29DE,9CA510B4D90CB209,2BDF821D0761C372,C233EEF049961B3C,C2FDB6EB51806E36,830642A7269D37BF,3818B166445BFFF5,8629BD47851F9714,64EE8371A36EE04F,7A0885F6B6645858,000052A6F768CE6E,75017B90FD2C1160,FDE949A61445E7DD,1749BA4DCE5EF785,6EE6C1EA2F5CE54A,FF8471193D045039,792727CEC0BB30D0,6E3EED7FB7B5E0DB,FE05B98C5D6168FA,635F609B9E174F00,952AB27ECFE6334A,4759975E18796E15,000051E697BAD31E,B310F581DE4F98FD,CEDA30BAD8553DB1,201B7338E42193ED,16883049F1A4A051,77DE315D17836C04,07E757228F8F097D,B36087134D0ADE51,FB7399A7EE61E4B9,8F86E5EBA17CAFA6,EF5D72404C73B86E,E8292BC6319869E4,0000351639B35E7C,541184F9B03B21F8,912A511FCBFC7170,52CF8742BF9203E5,1742A34718B3B06F,F2BEF156CE2545C4,1BC6EFBA24F78DA5,635FE267FC8FFF57,9E66C441BCDA19AA,06CAE7EF4E34F367,C6456AA2BBED0B49,EF9DC5FBBB1F14E7,00003C0813C5A00F,36080BF106F35260,EE068882135B148D,6EFAE2D76E9E5386,40E2795FA7DF59F8,FD60D747F34FEBCE,0E2CF9B3FE650539,83F5F8831D927C98,D6C7F9CB301B67A7,BCE908533E513134,0F6FE9500F31E962,31BC433D46CF6AC3,0000024E9FD646D8,FF6C08098A4A829F,DC41CC0DEFC0A20C,56D9E12C76616142,3599D24FE0D63025,30C2B4EADDFB03C4,686422A160EEC064,D89690D160E92511,E03273F04EAA291E,9728C1944EB70D49,0930BCC217EFF9A4,182D50BD3259FE72,00000DA2289586E3,A5A5D2E3C552E6FE,3AF84D1438F3EB05,EB5EA1EF798BF24B,0FFE1A04382E72C1,EE76B0D5985FE18B,4D24A159351C1F5B,3053637B28445BD3,3507D1BF4F3E458F,EBFDA5406F396CB2,4548665F60597333,1CD05167E12F99A6,0000556F0634A2DD,0121265660F6BB0F,02B0C294EA1000F4,7104F4112F2BDC1A,12A026C19141CBCF,592ADF8EAEA6E9DA,62F09F3169E06AEE,A325ABF4E1148346,0449F14847EED46F,24DAC08D8EBC8425,EB5E501FA092774B,5820E29F0C7E95FD,00003861F25B215F,4A9454C58EECAE3A,B73A51F51C52B3CC,49B53011B8D9E9C9,3891CE15C4641487,25B5537C88D488A3,191B00F43D5133A3,6F9E13288B088277,570FB1FEDE5D9677,1F06F64E11A14D44,F92F331B2916B649,80D5AC09FE834245,00000B57C2CB30A1,3748E238EED11291,2E8643CE70CFA2AA,C4822E0EFDA52480,AB77B533BC7C401C,9804033B2692E0A0,1CE3D894E4BDBD2B,7F1AC260E78C5BAA,8802C111CF401CFA,558BE26DDB954BFC,B3E1ACD8FDF4AD0B,A0C326A89EA0F369,0000652BA7FA0089,273A671CF566D80E,269987AA6ACA9272,5CD3AA6C64D8AFAB,634A29F782E92C40,289011D3B364E727,8BCDA2D9C7AF5E1C,1C33ED7D65514108,068D74D67824641A,6E64675BC92F4C7A,53B0621FF68339E3,F67BC05FC264EF7E,00003A1B2020E028,373D417302CD0A35,530FA683F04440E1,D7A414F9AF78EC60,0D259DA77454B160,F5E4422EFBE9CB46,877A58B0AF5FD35F,4EEC7ACF64D6162C,CAE559BDED860560,D9E400691A01802D,2781080DD61D32AA,0603E7A8D2F2B78D,00000D265014EFF4,C1A4F6133E19B9B8,C225FD0D5DBBFE14,4707379581F04079,E86AE17A3908307D,0C302351E2CF02B3,0BC7D2B7AC11B03D,48C2529B684970F4,EA92902951FEFFF0,5485F981D1D691C2,F207229FB3CC563B,8A302A1B4A02EDC7,000050213ADDEF95,D17886011DF81E77,A10A77B2E30C9FE6,11A6FF275D03CF84,AD679F0576499A61,EBF676F9EF2F01E3,AEA7924F26DEAB72,DB8CF1C82338AC2E,FDC7D88F95ACC5A0,4A01127B9E4B88A6,8D9511B13152A813,5DED727C528D95A8,000042A9C8C80747,803FC5EBA54494C5,17EE996BC8131EC6,FBAC13D70C8A1962,57A1B3B1EB5CF27D,2D44BF8B04257433,E69D0444FF2B8B77,DDCDC0F6C2710D19,B6932F5EC3BEB3B0,41D5B676FFF8CB97,AB13B69DC198ECF9,7F47C1E3894767E9,000069ECAC912806,FEB1C05A9143462C,E2396442C9976451,4D9931675232ACD4,130D64DDA79A1C4B,EFE080E0DE149667,82593958ECAF2F29,A7E7DE96406F2DC6,7951C85A57C744BD,7757AA41A08D16A8,CB0B7452DE292C20,139DA03E07B85FF1,000065C66E519085,3FE702A8D43EB5AF,B70CD30310EE3C6D,34E1C3AE9518C685,105D5FDF1B8105D6,8807CF6B32B15DA6,B32C3B0CB03FC057,511F530BAD14527A,3956150AADD803B4,30BB763BF8D4CC3F,67DF4BD284C62E94,F4582D58D3F01322,000065E42C7AA867,B90B63B7764D34EC,FF4DA44D6CC258E3,8F3240CC44CA01C7,2192DD30F4753949,4BD13476B8D73868,FC6815486B0AD97C,2DBA5FEE0A531535,EE8EAE6799B81D5A,CBB2254B896398BD,9CA22876D5C04993,F7FA9CD221EB7719,0000026601B173E8,6D6DE489D004CF71,03330FFCDE4B20F4,4DEF3C20B4240A55,5FBF966933D15F45,C008C681E0B765B0,455CC02AE7505B57,5BC3809F4B8B3090,3A9B81B477326A17,7A23DBC916F8E974,AC80D6DC80109626,B053F78C1B0BBFC6,000051AE7FE990E2,E01A79D96417AA9A,ECB23367710DC404,A8FA467D8B14F7F5,B2AF6E13E657B143,99031E890CAC389B,6DD0EC4501E73095,9B3DE8EBDCFD2D0B,BEB3F6EDC5AF9352,402D564096F4195D,2E911D9D24A16216,3537A52C1BF41100,00001DE0E16E6E00,2CD1716F3AF89126,7BCABA00B0BFECB5,988445CF9170C062,4C04AC32C89EB56D,2CBE0BD3CE5FEED2,BF6DA803202B25C2,C57C4E0EB01791D5,25EBA79C8D7925D7,F3121FA0F6DBCF15,E8B50E9CAB14FB9A,4780CD5EB101D689,000039221AAC1960,6A994F6B4A350312,E3DF1B980322E23A,73BCF44C65113C4E,B4925A88E452D411,5D8FE96374E1A58C,90C7F8CA3BE93636,50FD0801CDDF6885,5A92395B021DE0BF,4C3DD06C1BBBD34C,94545AA417AC8EB0,630B67CDC6E4CE13,000009342AAD35EC,7E81234E150AAF2C,12D1E5E908DA457D,A43A81AEFB3977C6,D72F6E84B3887682,3FDD6EFA05D9CC6B,D058C893E1C347DC,643EDABC7C849B01,0710AAAD9B944DA0,F84C60CB57F01438,5B1769DEE7CAEF30,7236072AD264F97D,00003BF2DC38B27B,824019B8BA200EFB,C4F1CC7BB0BCE1DD,56C3492A6A15341D,BB6835C499B2A1AC,CCB8DE994CC9E395,C6D302073842A38D,9F32132063A95DAE,13A5C8DB114B7C75,C95C5BBEA46328EA,DE0B1025FADB9E64,0B66B44EBABE10AF,00003F9F9A1B55F3,3983AF95C4280876,7B8A987157C1B88E,5CEAA9CE8F6AE1EF,3EF3D7AC03BA1552,42625D4F3F7BC830,6A07DEF0A0ECB021,98D291B193AFAE35,F4B09F7823948BD2,ADAFFB13DAF7E490,75069ADDB8041AFF,5718143A9413F0BF,000039AC9A17EAD1,291FC65ECDE9257E,F16DE4177EC8B35D,F9C5AF69660A0717,95F92292B7F76EC0,9491A905A047E201,B0083027D4FC66F3,B2DD584BDBE2FAA7,9EEBBD2327494FBD,9F0EC6C81B6957A3,2FAD17F5B1B3A9E4,98387B3C8B31309C,00000CD2881EB857,E53551C5126450FB,CCF5070E28187573,1EB6B2CBB663D039,BB3B01F2973956C5,2B5DA04D00BFC047,9C5AF302A22DF6DF,5FFE81D2E3F0E0CD,3E295B5ECFB0EC2D,07CD8FB87206A262,54CBE519D185C3EB,550927302FBE55C1,000031FDF81845E8,AE774EEBED6EDC97,6DAB39DDF15ED7A1,EEB5A3B2E0FA0A05,62192D82CB3C4F34,C81C0FD8E01A90D1,83EE0C9D71C072B6,224F2B16A1801BD4,A07FC0D5AD26EE94,124A51194AEA5AC7,1C4CADA6AA1B6413,D76BBAD2247CA026,000029A5BA3667D9,EA9F6EC531ABFA2F,2D22D07A7E25602D,B24DCD591CDAE074,80BB765E78EE7D8D,53756C17652AB0E2,57BD71BA92219F90,079F1007E16BA15E,585770ECDC40CF3D,90785DE85B6F762A,BC909C22B888FC8D,88AB6EA7A8C5EFA8,000027FCF82595EF,E9AC29AD54EB37FF,CEED4C420175597E,AAAF328514851AF1,C24BEB7DA0EFE6C0,A43832A94D9058EA,6F2D5064D822B17F,8086A3DD494D1B85,5AA3E1BB8208B072,293BEA9060A01E80,CDC2EC2AAD7A61E1,7D851767AA43614A,000069DC6FE25F51,6D18E81842A649F0,5FDF9750472BADA2,4FA8254D86C9E071,5B68E8503181685C,1B3A4B1BE7F6BF93,AD00E81952CEB68F,EC8158F304D83424,7378280B81F043A8,4A4D476A79312D7C,B0C68C75EC825132,E172C3345B238EA8,0000406870AFC34B,E31233452B3B1071,3CA319DC44C4B74E,6407AE976378D43D,0E22F3D581295642,3DE1F02AECE48297,8E1FE3F0D10EB766,A6ACDE168FA2D009,B0DDFF6DD5AD73A5,8305CEC58E7E209A,7A0DE66F89713236,6E745B182D3EDA09,0000283F90726642,F01F7F6C70A3C236,AEE1566330AFF201,2E0E07B9B9568F74,174E05D099F95E93,EB566C9F1DC905BD,9F69F21CDE7FE7C0,D8BFFD0859AABDA7,7EC7E29DC726CA12,FEA87E303A712EFB,6EB29D2A46E87A62,46F28CF1019D7F35,0000003673FF5362,5CA72822D8681848,BA288DC6C1E727F5,23E8FD8CA60C5FEB,702803D0FFDD4340,233DECFB014E25D7,41985F944AF47BE0,231E02F85B19AD8E,93617CAC679E9CA0,D6FFA16C8E92E6DA,0462F1377B09F365,25F1DB32823DF78F,00000782ECA390E7,DE3C96FA9ED104C8,7EB09D5767143D77,9C85761FB01DE9E8,81E7D3148BF6036D,A83D156AFDFD34B6,B8AB28F69279BCBA,772336781A6B2544,2549A1A4980D86D5,1CB48D2118EF90E4,AD2941BAD71860F7,F9A0540EC81C5780,0000372A3A435980,3758926066E6A84B,9F6A6D5BB314A1D2,BDFB008C857AD970,81EDD17E9D02B844,60726CEA6803F32B,AE4B2DD8EA11770E,BDA23B274C95B815,4A57017956B6912E,BFCE004FA2D6AAA2,6B5C0FAEE63AC13C,F7EE5D3AB1A83DF5,000058B5EDC4184E,37FF72C8FB9C5E1F,3D2060294E75E5D8,D99205867284C6BF,C229332D002D1F4B,5A7727CE86298639,6F0237ED8B10F3BD,B2E693316C827692,F8E443F278B3A84C,5B23B1ACD39EA78A,64855B36B7F12CAE,23245CEDB4E50E42,00006E2D3C824661,EB70D35F91D02598,A0A520B7562EED58,8212BE68ED0EF424,8E901AC55C31F414,D816D6932C4C48A5,B6DE8ED9C57705E5,B0A66E4DCE752C7C,4FD5D2EEFBE82743,7D939674ED3BAD88,15B1F49B58B351BC,7CE3D75FD6FCC9CC,00003BB706470ED2,9371EFDE219528A4,53F4A63AB528DB1A,E823BB4869C60518,58CA2D890DFF714D,D185DE5AE4D79F9C,8477B44150380202,25B7E0F1BE296113,E8B00FAEC31BA4C8,05E00232B9059B3D,95641975677EBDD2,9D4318D9D5E7D7D6,0000469790CE6F2F,C8D5F3F954ECA024,9599D2FEB4DF4BE9,CA9EF141CFA9CEFC,EB78AFD2FA166879,A136430C0C2BDDD2,EB040DE749072C87,3F30FFDE0F08FBBB,B2399EDF9AEB3843,201DF9704A4314D4,CB9E5C66A5582F4A,647F3F7E8BB4773C,00002E6518ACD196,1866194DA24220BC,49C038A6B8825927,74F18F9C52A48F6E,EC2324EFC96168C4,6FA6EC20C6BD90CF,CA4F31D37A9EFE12,075C54536C0EFD63,23C139DD6762F684,E3096CF2F5C6EAAE,4D97BACFDF1F316C,19C0F5E4F7FBA2EB,00004F8A0DFB38DF,658E3C00DBDD4A3C,3B301FBDA4F036AF,1B48EAC5620DC403,6E9589B8601E108D,5681FD4AA6467742,E9945D49EB6A7C3E,D268EA7671DC6B32,2B36F70303C36D8C,49509B8D16F0AC51,57B39FCF1FD3D97F,804A65F463CC0ED7,0000531D0B3C7D82,3EE88774AAE341CD,9D6A954ADE7A4D75,EAAF4B4788527458,FAA84AD8E4A5925B,89963B08BF4F744A,D01A37F2EDE5F76A,B91106611D6DF03A,EF2B34CD0B14C9D4,C26CEB0971FC55E6,B3468C6B23F5917D,8CB14473AD20C6D1,0000134A577E2EE3,DF66A92DDB7D4E18,52DBB2601C0CC49C,C15CAF7034F34DFA,0FB5256D4CD6E37A,5A3CE6A5697D86CA,598A01E9B569952A,944B6D3BABD681BD,6F230D03F36969F8,5D3BFF3D0CC0E563,880E626E567C2281,AADD6486BEAA7E8A,00004B4B78EACCB6,A3E0918991112CEF,D4CA0999C392A0A2,1A17433D62A382C7,6CAFCE9845AD4BAA,DA33C9C331A2EEF6,EE66DE7B288029CF,8851D29F2DF0EEE5,B76352D7FDFF687B,1E31E2A38FE25980,D9D0E53D75EFE8FF,A522A1E2E0618CC4,000033574FE62044,7DF14ED4A3415693,307CCAF3B4733D30,B5DA1A32D2556F74,85DEF198219C6F1E,D893513098799A33,F956B916551A8145,8BAD5F229CAA1A2F,3F2474602FCB53D1,4358A310BC86ED79,52D66D7285C09779,C07B1C6C0D99893E,000005BCC5697938,B68F4B3326F3BBBA,FC81A49D156EE0CC,7EFC80BC8BC6950B,27607A2AFA47205D,9AF7A822694E1CD5,406796A770F0CDC7,DCAF43669AA86214,B860D007B963E7C8,971E528AAABDEE66,4EEBEAF01F36E1A4,18647068519FF602,000034D11FEC5394,14287E03010C5115,6A7FBDCD0EC33571,559FF4448FEAEE8B,D40044249B0B88A7,4A0096E67DED8340,6AFB695FDF0DA3F6,373810703F324EB5,7DF83E55C97A597A,DB6422BFCE92D4ED,D9F9320D4907600F,534E8FCB00C27B7C,00004EAE91AD4164,661069C8789E6429,4F6C8DB777E8A3F9,9E75E4322DC209F5,274C8DE59D49D52E,A63CF7FF59107A85,403F5114FBCD52EC,251DE94287266B63,4BF4F10257ECB256,10E922AE0536157F,5A60EA273BB1CED0,1CD4243F11CE9D90,000062FF53397C97,9AF8E7CB5C6B55C9,64AC4E16400270D5,B9C54BABA85FD7B4,28EA35CCC9226B1F,0E4ED9E6703B4DE3,4FEBEF02BBA881C7,5AB768F88745D501,A474FFDC831F15C8,4EF73B4A0E2BE466,6CD39BBDEB944D4B,C6B494DAC76CBD98,00003DDE8ADC658C,3BADF38FB8511327,D1E66A57E1785D30,5594615BF47D172E,F6415D4436FD5C99,84D444E887C8CE38,87CF8E03A62ACE8E,36ED9FC41F6F8E9D,26AECB5FB40C94D4,FDF9E2E4760C4026,F93F15D9228455DC,13E5670172EDF891,000065BD818031CA,5933295338993AC8,B9DCC4241DFBDAD4,73C4DDF0B076CB3E,03EDC216CBFF8BD0,0EABB3572F3353C3,775DE70AA2D22030,3B89E4A62B397A30,3A3CB06175885B46,A2E27A19A5DE1E53,17110DAFED0C9F1A,0CBCF6365ECF0EAC,000010B0F974F13C,C99D5F92B65EE2D3,53CD9742740237BE,FF1C5072298F123A,CFA71021FAD7D633,335C4F685FD9B617,4396AC59E7CA60DB,52EC7C6D07DCF549,20F5E246D2999639,246A73C172B0A76B,F76913DFE203ACFE,DFEA35C1A303105D,000035511E163E02,618CFBA940F04E0C,413CE3DBEBEAE72F,03D8D656E53CF897,D1084302E5FA1EF2,99DF15700423AE79,EEA9539EF7311362,CCA92237B3ADBD7A,D13CD43FE87F6E57,CE44C8FEF3979A65,1AA1EEE9928052EB,3A034D2604A537EC,00000732532FA709,C08748159EAD2BCA,F34319ABC229BBE8,3790F6DC3FF76B30,D6E5BA20C73BACAF,326B22A58DA4D7EA,4CD9BFFA8DD8D25C,A95C139F10569843,0D23FD934ADF2497,4BF8D8670BFF3926,8CF429869B59BAAC,F6344984288B3A59,00005F76F172E72C,92F478E5B870E249,24F2D72984C317F2,B0A637622F88AAF0,CCCED196A144E43D,4C2CCA385DEADBE1,E4B0FE33435EFD9A,D256B8DB1C1F3DB9,BF8935403856EB14,B31CDA1B009DF026,151156557B809782,029849646C2BACCF,00006B83504DBF26,C99DBBDAFF07A11E,2F2FF428F8BCA87C,C0B1B63ADB9C9441,128CDA6CE8E80105,9E1DB3BA80243952,27DA49F1ADA7A02A,9062BC2C2EE0070B,95175243EEA56C14,D2C4B841E9E4B763,E03D9EB3220EAC22,06A3EF11D589BF8E,00002B643993A3AE,10AB15A3C366C599,E81CF68D22691F7B,929BC91892580C3E,CA2A27703C76DDB1,91A660B885A6D5AD,21998AA0669CC11F,63DF20F7DA421806,07E4E418682C7845,F921EED50B435D5D,9F33432BEC1E5E9C,3817503EA58DA8FF,000037D2AF7A166D,915CACE911ACE9DB,CE3BF6D3F6DF6135,23DF4F4F996A3B81,FB27B8C95DFE7981,C9952B3616C6839C,79C374B47F82607C,9D5D36FA0672E270,AA454B8D446EBE96,12FE4FDC6193335F,837D79610D4328EF,10A299FE0496E961,000063B4FE498B1D,AA2FE85B6FA0D451,8EAE87DE96A9C360,89582E9A816A3723,8A02FF8FB7EC3221,500FFB4238EEB94B,3DBF86B1D84B2981,3D02F001C6EC848C,9CB7B3057215E92C,2DF9424F041157C4,D90206DDCAB3A138,763E5ADC1FCCF378,00002AAB24CC8CD8,942520A3563629F9,7E5ECBA355DA20CB,E403B4EF3EAFBF23,D41B03038D6ADD96,C76D380A122C6053,D1E2948F845BECBB,DAA96EDED58D2264,202183242BECED98,602167C28D755A24,4FDD7940A4E6157F,5BCEB7CD07568601,00002AC36C21AABE,D85432B2ECBB6C19,7EC16BB3F8B5AC4C,F4CD0A5D5371569C,B7A7AFB636F4DF4E,792C1F6A182E9146,860D16851D938D7A,F7B822FF43FB077D,67C3FD9EDB1BCC12,D4A401C592F29C38,A25DE7CF8CA20B6F,2ABA9D5833693F65,00000C6658051671,C7E72F5A182C4AE9,E7E4921B708B92A9,878503A96393FADA,A36B142E5A84935E,8D1B2D8B8E3251C6,0574294A7B31987C,BF01C88ED2F74527,A93868F51A816C9D,C4DB845DAE48148C,5304AD555EC5C02F,A6B1863BD5AC48BE,000011BDD4774E12,58BC8FCF61FF5833,17BB5891E6EA113E,6935287BD7A5B1E8,BA920D452CE064FA,615F3D859CBEB934,EE20803657CD1278,68D1AA8A2EC57096,2D00C5DEA64E798C,8741BBA31CBAEAB3,CF21263BE3763256,3A0D5613819117B6,000059113CC5E2D2,C308C8143062DFD1,E40220FD8A50E18D,015C73642846E6DB,EC1A685FE2B606B9,DEFB230BF45BF971,7BDDDC60C3CB0787,EB8C1A9E9C875883,985EF67ED46F39D4,B0322D0ED814FD5B,772101434B2F93F7,E8D75C6D232320EA,00000D67DA911761,4DADACC380F921CC,B21E5206542470DB,3E8ECBE88F803F54,F06AAA58B4BBBAFC,92163797C34178E0,7ECF313A46558187,F8DB2F66B9C869AF,8A5FBE2F8FCCC9AE,E670F5F4E7B7DAA9,D2CB6558CADA7BBC,EC0C866FBD8347E5,00006B0242AF1B4D,E702546055E0816D,1A9B89B63F65BC3A,D2BAACD6047D8DCF,40A0B10974FD2EE7,2201FA820FE2E53B,67F7D9450FABDBBC,15195D7D484DCE82,8695F62BF055E062,27E1A97353DD0632,421CD53556D40A84,8C1AADF7BE1D8934,0000290F6DD7ACAC,FEC3725F84FA14AD,D74BB9D5E0702EE8,947B5AF63C6786D3,B057C5F3EAEEE78F,145F6608255CD36B,C6C5D98899702024,D299E23F5E26DB97,FD564D247D0CEF11,8B25F3DB45AC4E6B,9D334ABDBCEA9EE4,AE589AB6492E74E6,00000B767BD349C5,7330583C60E594FD,08D1B5EE4F725EDD,A06CD6264E5816D4,0C4F74BF362A3331,995C17BE6F9A283B,3CD41541AC207D7D,31F4689A68DAD197,D89CC0623349FD2D,FEBCD2F0A4859418,5CD19AD06BDECD78,0C57AE0792F8D6E0,00005C7A8160FE1F,8742EDED07E3473F,09115AA46D8C8E63,3EF213E15B84B652,FC8FC3216C661386,5DBBA8A5B17ACA2D,2790D14B27229D3A,46AD3802BF111159,BE81A48883F59EB9,B35602F7F11A8B7C,9CBEE44175C2A760,F964B7CF17B96E71,00004F2A36962BFF,F6CD38202625ADEE,3ED218CE1FE11E41,2C90E48DAFD71113,55BDB4945254DD42,E8ED91DE365D09A4,41A2061BC5A60442,849B262E6DB8D8E5,F5AF3771DC338954,E14BF22522DD1905,FD2CDAAE11B52D74,380F42FB33571C1B,0000679201EE01BD,7051240D246ED296,3EA93E3929F397FA,C55650AA819CF555,62F35FF70C36FE4A,DADD142B426DCC0E,0D0C267B345949F2,B1B4C4D0210FD138,C4F4A876F4CA5C3A,D0A4B6C969C9DFBB,CC52D319490081BA,5C52CCE0518A50C2,00004284CB4356DA,D08E16895AAC7350,2DFD7D241108F661,8149DBE4CC3CDE14,B35A1E1C355006E6,9CBB9C5408318321,57309E3264639910,6267FD487C1E8CC1,8B554F7A6BF89AE1,0ACE449165512C47,5FB9E9A334A075F2,3E93F8AB70805E7B,00002370975B7D05,DDBC1F2DAC748369,5A3600B369F3B682,E24C7E2C7C9DFFFB,889424A04C78B406,8283274A9A6EBF72,D16114D7AFDE27D4,29E74F04A9ECC0B7,B71561E936638E8E,6A078787423A749C,E20901835C31DA74,B74F7CB194A74D84,00000364E7C006DE,D2B2D79821DCAA87,7E7CCE751B081AC4,9CD444106EAC65F4,4F9DA87AF493A3CB,A57C06657978960D,397356E14BD48D33,3FEF1D520B3B2370,9C5F1C8951410E50,516DDF919D9D3F00,2DF8609B68C0B81C,0285FC2AF7D7259A,0000192C8725319A,80A5322BBC56EB86,E51F54DDFD7A2DFD,548269063C212D9E,8227F2287C7B09BE,1D45CC34C9869CC7,7D4EF4B8574F4496,40791FEA826C0CDB,368DAE7A04D46273,C7BEDA9BEA99616E,4A309CD74C1BE6CA,55334A90F33DD162,00005736140B341F,A86A7F0D241DE7EB,5501AF8ACC5456D3,38EF345077DF5786,45EA609A0769F98C,AE0232A91E981F6E,8475EEDED28A8EC7,BD9C3F6E3C6CB13F,DBF5015837430931,26A2C3C4C7045297,30B7091D8DCF503E,63B619333A73422E,00005982FC1674AA,D04ABB164984E670,40A8197420AC6864,DE2B4944D1C25C5C,2D0D1A8DAB443B03,4D21BA6CE5847948,3F8EB6EFC08DC130,ED813A0CADE90861,DC432DEC77702386,D6BD59BA88965B16,58D3BD2CD2F552D1,DDE8FFC3BBC27EF6,00001C2731978D59,EAB32CC1442BDB5B,DC227858EB8570CB,8769055A2BF9F7D2,DBBCD26065E01904,D6B68DC15DFF0930,8528C46FE8DA91FF,9EC0F8253FC0B0AA,9A80BAA67D8EB759,E54C3B426E3A2362,69713D5CE04A88BF,D97486A19160B1EA,00001E0CFEFD18F1,8C8A43A105FEF72F,D1BE98F87432C351,870D7B3469695478,736137D3ADBAEA91,19861B0958550321,4A82FCB05AFA2A87,01A569B431BF7646,675AF733D3413CC3,64277F25CC4BB63F,947C0E1893F1D17F,D04D80C8045C6BB8,000020332A437A64,4B297BC0950197D9,FB5590438BAED6FF,5CE6F1BE5F6CFB14,A5D6CDBDFCDF9304,A54602AE9D046C9B,05334F48001780C0,63361CEE27C8CFAD,CF4AADA2990D85AD,DE3FB24ECB106C8D,BDB7F14A9759D8FA,1404ECE5EAE23770,00004E72FBF57848,68E2E10335E05431,9B432C3C865324F2,9D53B9A33861B9B6,80824C7A45EA6865,82B06A4772632D6E,C178BCC061843B36,B9399BE83AD37B88,A29D97E0392CD8EE,B81BFB6F505A4216,BFA380512768664A,F460BE495D47A682,0000001662202EC1,751A710B226FD12E,93BD08379C3756EE,FA5FF475DD3D5149,A22A30B09B0A1832,662C75DA2380C8C4,4943ADCC89F5D877,447D747A3A99260B,154F3E64017B8B29,AD2771D1C1DE492E,ABB9410DFE2DA7BF,F60BC20D966112BE,000046F3DF15DDC9,BB3A0DD42494A0FA,4606B7AA88D57E38,B931FA908959ACE4,4D7447F7675DF0A2,A38E798C857BBF18,AE7B80A8CC5FDCA5,95B912125302EC3C,9995120A73F765A5,7D6B59FFCF63056F,0FE704CCEBDAD30D,17F29B2579207CA4,00002F5DF5723F14,173C210B08036BB9,049F886EEAC87B06,461B9EA63AC86FC8,F895246CA62419DF,A243C130B362B7EC,D464EF357BD4686B,7585F5D970AA2024,AD32DC003897CC4F,A592ABC707690E2A,7551B96F91320EC3,BE8B0BE16192B904,00000DCC7A2A188C,6E18C1F10A5F324C,9CD7EBF1F9E4A40A,CB3C97D771CE319B,0732F90D31CA5DDC,B558E155DF486C1D,0D0A1ED341E1CAB6,E30273BBACFC6B3F,0C952BECB5D52520,4B2B9563D6AAFDD6,3AF4012A63E3DF30,E9BE3439804FA0BD,00001CC514F8E8D1,1D2DD4A88A7F9123,83245BC07BD847AA,F8C3DD95DA87C48A,FAC6A9A2098140C5,288EAD444977346A,2F4DC2F323302D44,E3883F4319971FF8,8B174BA50BE4F09F,72571D770693B12D,E82983F1667523C6,7670A60E5E61C5C7,00005050278245E5,4DFC2CF74DB57F7D,348B835941BF1563,8640A7B8FA2247A6,9CD388E44DDB4626,53D5D21948D76A3A,4EFE1F5A645D635A,60C4D9FA0FCAD3B7,A97A3C0DF3222A1C,A58A6B5E9656CC06,572908AD47FEF46E,5E16589B8E2D5A47,000019CED87B7949,B8BF40D319DA0692,2726143D348EA517,CAD409ADC33EDB31,85EDCB943C9FE1D0,8BF28E2C6C4F94D0,3F0AF0AD6EFC1B99,5BE08E9BF0FEA251,3D07B576CFD27A21,7D09349998394BCE,9D6D55BFAD7A19DA,93AFE2AF3E6F6103,00000E98722EEC75,1CFD5E64208F6EBD,74ADAF32D2C48225,50F41EB8D0E72D2F,78EA0BF9BD8F0624,98DADBE37992D400,84724E52B049CD6E,32EE9C76C619B335,215EDB954416915B,816F74364BC8322B,FF784EA8171AB95E,4AACC3F711E4E70E,00003749E332C28A,82DEDF7E900A15B7,29F3775CF10090CF,2CA2C04668840C44,0AE3C8A4F30A35D6,6C3FDF7BFA673396,29BD1FB02B256CC4,2E6192156A0D8131,17B6138B3FEC09B8,14F3FE15A7B4EC75,3ECEB401752C61B0,F4B5D17805875487,000050300D16C3AE,D79AC4115F842014,689F067CEB469B23,DD9EC791C063EBD1,B6683837361FF909,4A432C7AD760303E,7D84E3CAEEF719B8,6A02B3BD4CBC8B56,C133FD87AB78E733,78EE292D0C7BF89E,C415491051658637,1687CEB576981667,0000514EEDBB228E,BBED5F8959EA56FB,658B7CB4E1FC5AF7,90CBC16F29EA2144,2F7B550F52959319,FB5491020EFE39BB,4C82A068FA0C6157,7CE243E2FFA3ACB1,83C3BE890287533A,ABA1F9BDE6491488,F2D027682270897A,151F80A9BB99D58B,00002FF41EEE97A6,CEF03B6825E8DB1B,20533063BE42A7B3,AD53D95B64A5C27E,724FE3686F8B6150,6255904335F25DB3,65C940735AAE7E06,A2262F26007D1810,09F14BD224D292A1,5CFAA2C2FADE5224,0C116EB091DA402B,391697B24B2B69A1,00001E8FAC7C3AFB,4B1450F5E4F50A76,5C52363222E71A87,05D8C41A5968F5DD,3950142E8C43CF00,87C3C258E85D1C83,1086BBB697401996,A57A712CC96A6ECA,5EB080018CE52ABB,4A4594DBD974A9F2,B7CA50D8D975C9A3,B7A7BAAC0C5CAD68,00000E8EE7A5BB65,7E71A33AF8B0B063,96520B34DFED059C,B120A3C95640802F,9C3C88E83F86A7DA,E6D25036018B0A31,A9153081B1C473F2,804CF289541637E4,6B0CED19C7403403,ECE943CF9DC3C005,6D901BE703A170FE,F77C792E80C7AB94,00002A61C17BE9CC,EDF04F380EA36B1E,4077E0F5CE531007,69C2F0A9C42DD8A4,0374ADAEC0A823AD,3071C7B4FF165504,38190AAA30F38188,966438CA0D2772AC,4AF5C136575BCD4E,9492B1CC990D70B1,36855CC961E42D9E,C4A0F3C13F1E7FA8,000016AF373A56A2,B21669ECBD820DB6,27C9E620B89CD76F,D5009A3F2E52CEE6,80464E5AB0C5075C,AAE0D21ABBB3B6B2,7FD9EA9E03E60634,E2983DDE317B13C7,1D7BA09526C562E0,E7BDD7D101DD08CC,EFAAB027B04018B5,DD18F9E2216D36F2,00001C62FCD9C549,FD7EC88629166724,CD1F0898864E6DFD,610697CBDA19281F,937DFBC3A53FB87C,3DDB81AC7CDBC834,D2864F5D04B9CFAA,F3EC5AF4D6AB3920,1C18D163F592C1A1,839C987757851D90,A188620D2622F0A6,030B56509DF7461D,0000604A450B3760,AD4557D82EF3FBB4,87943D3684938E7C,E6505A1C3A324A21,9B0BBCBA565F3B8B,79146A34DCCD6EDB,382A97909A731D64,AB93BE781855E47B,89F5CEBE78945C33,226F6EEC4CB3ECAF,4BF348FA7EF09CC6,180CC2380813081F,00005EE6281EA303,8A14C9F5171176A2,06C6707D7D2A8888,146226E758942BD5,B05C8AD2633CCDE0,AED6906BD3A3A1A0,20F14929842F8FF8,0D57C0A325EF7DB0,9D631F1D0E56D20C,26D1F0DC6A3A71C1,3F1D4894735B860D,8BF59AA5A0473805,000022CC77007DF9,044BD970985BF5BC,C5192D7EEB5732A9,0A7D9E787B6022AD,2F087F37531B4752,2A7E583B698BD5C3,F207C7F82DBD00F1,B206D5F3BDE29F58,4CD0AD5DD35AC743,E6A116BCC2257C7B,42F46A7800EDC3CD,A7B7EF87294158D2,00005117DFE56DD8,90A71A3E2CD64315,DA30433C960DC475,3C35DAF6F3ACC533,3158569795C5F784,A3E44771A5CB174F,E6EC0333E4A53431,4B6D5740BB0D6191,B382D1B1CF8D88E5,DE7E069F847B3E23,E0A6BE26D4E1F417,585290649E15201C,00006CB5EE31D6FA,2CA7A065340E6EC2,3590BDAA03F21290,824A73DFA29E1319,A97186F7458DB0F5,7C5C41715D68E567,F8B8EE687E620AD4,AC49B37EF2C8D17D,6C3A06354DE84F45,62388E9A27531262,4682BA29FCFD7A9D,12AD9A5827B405AE,0000362FAF6A19FC,5CDCEE09B9BDFAE3,04C174FCA2B653D6,53E3EEBEB0747DC5,991D9D052C013ADC,3B9684CC03412D80,55CA432CFAED179E,09F244DD9FFBE10C,6DEE901941980B9F,259432302E8DE853,2D560D1D52F355BC,D972B23F548544E1,00004C53ADD7A01F,22E86564BD228BCF,E3BD8D9832178E94,4A3FE11DE2D28B22,500F982DF9C31816,C172C0C92EAEF835,5FFB98F02C692C45,FFE1D255433DF230,5D157F8644815456,9258E0D792A93384,910920D5604F0B0D,D84D748C258C8C35,0000353C633DFA46,87BEC856D195DCAD,9F9CD7C0BA6FF0FA,643E3EED2107195D,0E84737355E9B705,DA9DF2CA33C63D6B,455BCCACD55F671A,C40A9BC4086496F7,41D40EF9C8D5632F,3EC09F1302282F13,46DC03C8ECEE148D,68329264C327F4FF,000054A3863A49DB,F06C021F42DF4427,C9D193249C38F09A,FEE11CED4F8BE1CC,769C3DAA7E69FAB6,CFAB84455B37AF8A,A97527A617804275,8EB69898AA08CAFE,2895CDAD9357AF43,BD4195AB0B9C7F40,2D0269DC632B2109,B3A06A59DB3DAC2C,00004EF7A7852D75,CB32624807049B34,8C8D89E3DB51E9F3,4D0D5B5B80B5B067,FE1017BAF5B8FE25,D8E683BF22822C06,93349AC474014CDB,0F04ABB73FDF2890,7AF16AB8B11CF015,42E4F102D1E3F322,A8E0B62B7B347903,7BEA2E5715EA5509,00001C28DB11F907,A66457F9CBCB4A1A,28247D332307A73A,9436D432A0F71033,19CCA1B4560FD7C8,15E03FEF09CBC62E,F1D85865107EB1A8,A398C06FB0EBB80B,61933FC9D0B9955D,BF99A232AA7078CE,F4C42299781B7963,C9FE5C4212296E57,00002CE611276ECA,F9FF2B72BEF6C7C0,6CBA6C227E3743DC,10E48F9FA02FA621,584BC5CDD1D1F6A6,A51013C811496F47,9A54088B23FFD778,351C4B1E62A2B0F0,D1607C013224FBCF,2F70C0C60EF97D89,96256505E47910A2,F311DF313F483C18,0000327635D3DEE5,54E9966F86EE4888,FFC948DC9CCD62FE,D4FECCB3DB341771,B51046736A8AE55E,EB3232C0BDC08888,D6B574D1DD361E09,0EC3D702D6168628,BE36F7E979A85746,228D0053980F23A2,A41E0A993689D86C,CE5BD64DAF904078,000000C1A0F53A93,9EC7E6A32D39DA86,FE0B622ECFB995CF,FFAEFBD041AEF480,724B9568AB6086BA,0BDD17C16A48F110,6C9ACAF4B0094268,C6006B39A2061051,9496AD5ABC0F1892,C5A5BAFE161A0E4D,8CDE50EDDFFF3588,899B10F0B514ADF9,0000242D2B39BC88,84B65B5EDF13F1EA,F6F069F5F43F86D0,A8F5951C61389C52,EF3F92700B701ADC,DD1605ED34225561,A545FC8557E2BB13,04B8FFD632942507,FD10181CB2A3B604,57B438E71256798D,39B9775FAAF86E79,99FDA4B86128F485,000019D33138FFED,4CE5432DC0CB25D1,F71EA511CEDF737A,B634E9F26547F000,4197582278F9DDD0,49749ADF8E8B8406,5D2F16C52FCBCCA5,4C2F0FCB9DE788D9,851850593255BEA7,5F9FCE8E2A0A54D5,A2A4D7CE7619C95B,12145118A8F39BDF,000010282716373B,F9D938512CA6F594,BD90B24EA21816A6,10BCFE0D796DBBB7,F4D45061C39ABE44,D8DC46DF09C303CD,FC2C09360F7555A9,A6312CB89297A067,F351641C6DD0AC71,0629268744401682,B4A4698CBD44C42C,5F982C3606E0AF3F,0000654ADD890F33,D6565DDF36B8C791,230DE693548FD728,EBF8C9FA9F700073,A263C352E0A1A23C,E3993F2EF300F689,396057D372BDD068,896089FF91996FD5,94EDAF48F9A575A0,EDC667F08A6138F8,24C19B290F674805,4890E815C05051DF,00001CE8706B836E,84477FA4A6C6DB3B,AECB2C0F35638F8D,680A05E0A0106BB8,8389FF85F209AEF5,910CEBD157AEABFF,D3E3A7C49F9C4F4A,DDB815354E07E4C9,ECAF10D4B873C891,716F936DAE03A072,E5581BAA71543B2E,BA2A917D754E4E0D,000004051296BF16,1C78ED12A7F2E513,5DDAFF57BB3BF0AD,9367AD54AE6797B2,728AD5AEE8F70F45,14FB042A0B622F9D,77E0973B01BB2E7E,02CFC2745E15D892,ED5CBAF4B029C871,D99D7187F66C7BD1,10F5443C80193D00,BE99402D8CA209EB,00004D53F798B180,C9F193E92D2B25B0,30512966DB02D692,7FFE2582117DB8A6,7E838D4A140258A8,E559FAAA58AA6570,44AF5BB19124F13F,18F88BE8964B0839,DF148BB563F4CC14,BB377F6E4BE8721D,A7DDD1F52D674BAD,D0F7F7350610E0B6,00003B0198419604,5E2E4FA175FCD5CC,658AFC67321DCEF7,939478545054F562,F594F4B8C88282BD,46805CAE0E012064,F5EEF05468E2C7F4,9B153BDA37386772,7AC7733206AC78B2,A1AA8706A1F54510,658661622B994124,5F0E63F0BA8982C2,00001BCD3B9CA481,A391B770617C60C0,E0A7EE40088E2CD9,56340070C3CFFAD7,EF4D225603A40A12,7ADE488846A7A474,E59EC68D86429D1C,5A0CCE6446624634,FB54003460248964,9CC510E1DFADBA31,27F224E63C7B3E2C,FD6512AC2E46721F,00001690D00CD3B3,9C58CAD47D5BE487,AAECB7667D9C511C,94117A155CF8411B,0A5F5F07A558E858,734044233F6724F0,FA4B6656A24011F0,6A90FD5DD6EAB15D,71A2DAD6C3E57B5F,358FB14C46799FF8,AADD1761A37EDD14,3BEC0F0C6C22A3BA,000027812D156F1E,5E2701BE5CF01D8F,91BA9D77D2EEA078,7D54006454790EE4,61BDF4BAB275537E,6C14A9345A7004C9,0BD2576C07184C8E,BC6B7DC6102631E6,3318F85FDF70F7F3,112E6DBDE57014E4,03F94C2F8F905F70,A021410278E40568,00006C5B2FA69486,5551D504F4520563,E1BB800A9A991F63,F102B033808215F9,2D02798FECE68960,20630FE2A52143C3,3FE32D495EA1B664,AF62141D74176F39,26971450EEB97600,086CCFCCFBDC53DB,53235F2E855DFFA1,6B696B23E8E6EAB4,000027EA510E9A07,F216C6D1976D4AFB,0587185C770293D0,A1E440FCD27E1ECB,B7EF233C077222CD,103F0DF57069A1B1,5BB624B5D06AD0E3,27A8EB624048EA66,F5583B3538C3EC4D,CA8E6F1DE286B6B6,FC4E17DED2FD5C97,229DC67064F00DA6,0000528636A31566,D6FA6A5A57464AA6,8DDFEEF7A368CC92,919F5BCFD1CD930E,1CEFF524415FA867,D2141EB923EB25FD,4917EA99DD1F819D,251FA29ADE98D9A8,85583AE1ED9CE83E,7E8794F246AF0FA5,CF26C210D8836E04,BA8FE204075BED44,0000425C179C483D,9768E1E2CD176110,4B435FBFCD5C16C5,5420F6CCCE55DC22,E22F4846F44286D6,C10355B3BCC0F06E,7E7EB25C08BB21CC,5686DBAD7F6CD0D9,D040510468BC6237,E06F865EC40798D0,42E1EF3360239BA5,EE986969F7111C7A,00006EF26AFDD2B8,542CBD26372D6669,031988FEBE36DEBF,2DFD61304D489056,4CA6ED18EFDEE34E,5A880E5761F38657,34EA0F11C3274625,C6D735E4B3BB0567,3568BC439A19B26C,F0CAD9118FDDB209,58D2EAF011042C9C,89E614A8C421FB78,00004B89D29DE4EC,B02F7A0196E08232,23D7B2FD8350399B,CA662E9C5730E41E,5A53A681AD83852D,C8025C1CA0EAC3F0,21BA06B249204319,F09101CB5AC8D4E9,118157EB6D966EDD,5B7B48905A817B98,2D123C4DD18615C6,281F9E2E523AA7CB,0000356971A0B3CD,A06E69E774256190,FAA0648D18B21504,8FF61851B1AB77A5,9A2120AB375C8DAF,B718EF6AC80D0EAD,33F905EC6CBB634F,64E9B3ED94153CCA,2D51063EB3C44635,4BEBD9AE41A5DFD4,1E7E846C2962A423,1BCD3714EA225537,000003CF4DB23470,34D5D2608ACB1ACF,476805004E5520DA,577583E96DE2F54F,0C36E4A8C285E88C,551C2F3F7B46C349,D6C456F835DED359,1293B68F42CBD2AF,8365A28EAB2B200F,F25D50D81D204484,24D1FFA1E932C17D,732E4D90EB47188B,00004E7D1A0B5BC8,5EE42F96811DA7E3,66894C44DE462883,C0B6C201A6D2F95D,1FDE3EDD46092E5B,078C9E8434615019,5C4BC62AC0B9B984,9CD05A0AD6B1FA06,D10D62C039ECB18E,559D635B4B9B2714,BA07B03DDAAB2A5A,91452DA8BAF3DC52,000059C120862BD6,5EB223EE18AAADF1,477E5CEBBA4B90D3,0F07ABF0DE186559,9520371E9D7D90DD,5B96C7AF4C6B415A,5AF8D5498A997393,B0F42B81F1528D84,6525379229A686ED,F677C786ED428EF3,F8F416C653B718A9,D325E69759746F1F,0000659EC00B5B95,BF4A1D264D9E47DD,BB2966A9B99BED5F,395A65F2EBC844AD,1E0A90C201A78DE5,50EB1A8C0F03A050,F3DD6919A9FB2C19,5D3D3191AAC21FBC,F9A434E6378C64E5,B6D7EB8194B9F750,09660040C0B5DBA3,7DFC5F6ADBF7AB43,00000712210F02C8,83C4C79A70A9A699,81B146A5A34C48E5,50DC64B3CED2728B,5834E78349555E63,D78ACCD6E1E32E7D,85C98E6A7A3FDB35,D13C6B7DE8F73A22,DB8F259A156FD272,A40A5A4D23247059,9FDF824C413B37A8,3ED91E4A3C7D81D0,000027AB44818D6A,F125359D5CC33E4D,09B153F190268257,6720568EFA75D8B9,258D8268C4935822,BBB4547CD53BAFA2,054FF1D6DE995E45,F80CEBE401985889,F61F997E611FE3F9,723874564DA682D3,CD7FE9A6F973197A,EF0275AABE8AE022,00001DAC4FF9A2FB,CCE9841774FF5184,040D5FE8198CFF9F,F04FC0DBFCB41531,C2558E997FD06FA9,3473E8C5CFF419B3,A6E83DFDB81A5B65,564E29F8A594B6A9,04D1EBD7AF95E055,07799886AACF6510,6AA2333594A4ED99,D788BEB64E24254A,000016C929DED0EA,AF1B630D2F17B4F6,6A7E60172C80E3B2,70E9461C3DC6DEA4,8095ED8D3CE3F1C5,6410043FF38E08D8,E3633018884C5E33,E4DF097275A39318,77C9FC6EA787F72F,CACD61A55DC54F53,BB5D2DF6B3FCBEC1,073A4F80CE98AFC4,00001EF617C9001C,DD12EE3B40535279,4768E0216230F996,B29587020939BC10,0620DC4171922444,3C87C806CAE2B616,23DB567D5C5B537F,99D75224AC9EC48D,264DB9796D3D447E,940CA8235F042DFF,2BEF6D82137F4A97,C1F7344F93EE8760,000058EBECB8E4BD,1E812F622662E1F8,D726CB1F6636A131,6A455BAC6D2A97FD,CF2989733CE6C6B9,FD862002291DD87A,B5409E1875A79DA3,EE3E90A1BE0E3350,DB0FB45E5A5637C2,CAA8D3F1BA5D6AAB,BBBEB1234C3AC246,A315F83B1063B235,00002B70958C890E,02F67BC3FB653E30,3521E52565B77307,DD2326389D7F2E1B,640E2DEC64B40426,02351B6BA85ACC84,28816D4DBB9736E5,B51441A148FD7985,B3334610669DB657,19296A717B7C0DA7,F8EC98B4160DC21B,76D182B6E4D4D5AB,000042C721AA405D,633096EE2AC77064,6F2469BC00C8C198,669B96CBE92BC659,E7A7CEFEDDA1B428,B67F5BAC634EFD2F,2A5837C023CBC2C0,1D3C4752F58E509A,DDF8B6E34B62056A,5D8364031CD16673,5E3528AB0489F655,8AD9D9A8B82CCF74,00004C0D931A001C,4EDFC7E4FF67FE2A,7CFF4D1625E0DC8C,147EFAB8BF05E499,0594BDA99FC3799F,4A60BEA70DF41AB2,4E80400A46EA573E,92967E029714AD93,C643E9E9D996B324,8F60B88B1F220A7F,84EEDE843CAF3C37,672561BDA60ACA48,0000104724744F33,2E872A3EF99552DA,87B367B9D2A0F94F,DD9BCBA7D515FC3B,D66FE920FA596455,58AE6CD5ECF651AA,F84D8FFE895CEE65,5868C859D491E778,EF41E4E21247BCF6,0BF8FC4C98C71E1A,7A7EDCE294CE0607,7F56C76A5C857CF2,00003A32390B5056,91E70049AD802AE0,F66602BFAD7F2313,EB79FB653F1926B7,5B2626C9A8F8283A,AC10BC3F5F1B9693,1DCCC2EC9D1FDD42,9EBE93E4B7C8BCB5,F014A03F6670E3E0,EC18AA2507574824,88F1D27F6943793C,2221F009F8909305,00005F4ED0A9DC56,AAF6785A2D5A9959,0FA05CC7AFB1EE8F,24B2DADED23503E4,D8A6178D034B5B89,3CF66DC42C323C6C,8F4ACE674CFC5B74,F695555EF69FE797,4F4F168E649CA474,10A3AE4FFFFA0BCB,AE7A49305348C0FA,DE24912B95A43409,00001B37FC290876,BC1EC2B89C60FDE0,CA85EAFD6EF9A918,BDA1CD354EC3BA4C,B9E7D5BABB67F161,D03A23CB69B564D4,26DD84D010C9510F,3644D36C192FEB52,00E10947E519C523,B665B3B2AF668734,96192A6FCC81DEB9,1A3B97762F436F99,0000333AE5D59CAA,0585ED5E73BC01A1,BCDB8434AC0C9E56,20958778FC12D1EC,D7ECBE38B644F415,67174EF5A4A7A439,FFA41CFEBEAA6B01,42991B8EEF3D1989,527FE0D2312D169F,CF2B840B3C65A234,71B0E003733D515D,77D89FEE8ED44364,0000512E10ED80C1,A5AA61A2F956D178,C9238EFA406DD5F2,010E8E66818D5E90,3AFE3787BAE16732,1311BFE147A7D24F,5DC0AFDD6386F436,4CC932D76F8E701F,F85AF20E991A29AE,D8AC036B0F94E430,A4C1C1AFAD25CAE6,952B848BD506CB3C,00003F0688B0CE8E,A9492A4C3F89284C,FD6C5E47D8AA299E,D7B2DB53E0750A59,05EE75A5D7D2A80C,E012E221718CBE18,662E1AC8CC05A18D,48DFA25DAC517B7D,F8A5D129BE4A8070,4E7873185FF70504,C1E6A69A8F64459B,524754E17C0CDF4A,000020EA96A24169,5FB820027655F10C,9A0F1C9D5F23E2E9,FD10663AD6CD46F8,2E0253E6ED47B391,D0EB3544341FBECC,7A28337979A7AF3F,E01B0EE1AA9D1C35,E2EF48DC7C36913F,40F7D5DB402D8427,A8CE41E0F982EF4B,05339E5365AD0C30,00005C1648B98662,37084A4CA1BCF280,0C1544A19CFC54DE,3C319345BA430247,51AA20180AEC9A40,CC1CBE2A10A00CD3,A236ECE63728CC1F,133CD57C875CCF3C,175CFE556BD1D1DA,FF27D56F85CB485D,C62C9893714E1E97,556036831B69739A,0000600A99589A47,8AC4A4EB4C76C132,801E97E370AA57CA,8604DC97DCB625D0,7B5103FC1F60962F,47EFF6C36A933D95,BBDA10B884F5049C,898A6262013C91DC,7E21BB8335D8BF2C,7B6B45C91E65E6BB,5913A6BA8523E2B1,DF72548EEAC2F2DA,00006C3C86E8CCA3,4726C625C02FC452,B10A7AB721B88D4F,3E1B29C9607D08AF,F5B61896D159A49C,8238E66E3D2A7FE4,446CAA8BB034BFC0,CAEDB72D1DC91196,1D886BAB272291D8,A4F302733FBD8C40,B1EAAEBA920D77DB,075D8FD05E4C8278,000027BB4818CCB5,5E25BF06743CA419,197FDB801D2BFBFF,6ACA4A6B2E844925,00CDCEB802FE7754,43DF3BD5B670C645,CF2929BD5E9F7610,C0CFB7C2E4D9559A,52FB498B65FA9B35,E1940259FD8B58D6,327E7B31B166051D,6E6BFA975A41E705,00002BBBAD7A4BDF,5A58971BA0FC9A0C,6FDE3FED419B996C,E5EFBE478C74A8DF,43EAD625F7830215,F46242650DD0A0AC,F476939A9259F5C7,791BB80B81BC074C,BF908B67840D22F6,0BEE07D56908A9D2,F1838D0A82D6C74A,EBC4455A06D027A2,00003CE5DE113742,27A18E103F17169E,DBD7A421DFF535C5,3E23336DB53B89B9,CE3E90019F5214CD,EFC2A852293BD7EF,5EABA39DE14CB4F1,A3D75D94272620C9,C42BAEF2623E6E32,66207EEBEFA65974,DE43DBD2335EBCAE,36F449095E961F1B,000066D68DFD6A14,ECDD57F842A487E6,DE4194B516FDEBC1,E207DA50301F6CE3,EF031384C8294D49,B0DBAEF362BA592B,5F0D5F5836A11771,D5EBFFBF231EA876,AC117600696C905D,2F105AE96E20BA22,2EF71748DA39F72F,16B5ACA88E9111EA,00005BE42C5C6D0C,A2113602A1193C77,5965FCC840986162,A8E2363E8DBE8A75,5A44ACE44676E222,F9BFD47E2F6FC6AB,349DF23E4A983F43,97CFAA3F8DCD97DF,C1FE04B3DBCB14B5,22458C9D93441E3B,79E6A1B2BBCFE7CC,5CB7CE8739476EF8,00006AE1AFEFCC09,E8FDC60AF1B04FF5,5CE7C79FD0032810,F3E3725FFC4B4768,1309E3D685D218DF,78154FE9FC461AB3,C36808EF118D0CF1,E6E629FB74BF1070,B30CD7B782B18E54,5727852C26E1E3A2,4E526A5491A6B5FB,C9878A28A23EDC8F,00000C8BD93F930E,4C915FFDD5C7578D,FBA2906EFB4B339A,DD8292F569EA2E41,77F58CFA5E7AFAC7,6A4CDCF780DB8774,8C2F2F5F839B04D0,E02769A29F50F9F8,A1ABFAC9135BCDEE,0CA10A25D2FA6394,23E21E2569D632D7,D0548E98230AFC70,0000252FBADE7898,D2602AD35668DB93,9331BB64DC26D46C,E2758AC290A2A192,25794E2BFDE5A825,EEE6C6179C7E30C4,157DD5FDA8FEBCB9,FF1CA96E5A2A5618,5B19474637FBF642,473B7A07E29CF043,2EF5682737692958,2BF4A73B98F6BD28,00006F9185DFF333,7C4DE4A48ED9AEBA,FE7321A5CDBE0BF5,2D927C1C8694556D,59C7EE9B1886CD2F,1C9E9FC1BE1D7B0F,424F1F6B43834AB0,840D4881BF78ED80,0A1116AC2B394A44,873212041611E05B,D01BEBA2516A81E0,12FFB2342B72B5AE,0000081B74EFA9AD,3E04E0CE02CA1923,DE2DE994A1BF656C,B6C2139B58EBF78E,BE96F22FC93083F3,74F60031302B23A6,3EC296B617A0B59E,0EA05AECACC9A376,DD190B3CB6601F92,5882FB52FEB1F6CA,38F09AD68AA94E50,4211BBD78B013F8B,0000612EDDAD9388,982C3F070CFE1730,4661363DECD2E1E8,B4E32B2CF98FDB83,275D051AB8F62155,1E1C65B82C26D6D2,5F8F066ED57EB42D,47E6DE58AC099419,CCB22B7927B462C1,48CF3456A28F6F40,A55E81E24F96CE25,AA1711B24B7FDFAF,0000213397EF2468,6783D37F1EAD54BA,9ADE311D02DEA069,4DDBEDCB0954F0C1,8CA9F2F081BA4BC7,DF099A084E53EF33,D600AA8BDCC32F44,7AFE55FB4CE41964,6627DE4BCC64989E,5996BDD3D1964D6A,E64D5FEE9347EA00,50C4137912918A9A,0000001E1B2B4F5E,EEC6741AC24E8B57,4C96611DA1B9BA35,310B68CD8DA87DF2,1325452AAE3EB6B8,7D375CB858D807BD,87EC6AD72710BE1F,63EAD5BAA200FF02,39FABE24DACEEFE5,952C185C8FC6F325,73B395950105DBF9,6EFA13EF92464DFA,00000D844375F057,A28EBE4320ECCF52,BE274A13A199D95A,08EF712FA644B9F1,5406FF2E47FEBBED,C1D1859D81950B0F,45F3B3CC59E7289A,1CCD86CA4960B675,016F66174B725644,F0E95A14CE3A52B8,08AADB10DD4D1FD6,CB47743C19B2066E,0000267C36F1F811,41D0E26957F68D3F,03227B41870AB3B1,6773CF7E08E3B9CF,6E832ED5297389E5,AE42DD7FE3D874A3,E3826BD571D66B50,6DA004976819AEF0,DE377BB0D98F26CA,4B67EC969BC10C46,4A3CB5C67C5AD9D7,53062BD5D6840DBA,00004F187F0B5BBD,60EF6A5B7B555EE4,ED2A6CCB91F39CC1,9D5645D75B91D3BC,B5180F0360C0FB76,BAE39A31B1D57A23,BB99ED2B47482F2E,456A1150C7D6BA36,16562107CD4F35AF,8C7D5FA3D0E05C16,D2545AB3B1F52FBB,048B0ECC89265DAA,00005FF784C695C5,D56AFD10D2C923F1,F37AB86D23E3CBED,E5145B795886A0D0,400B0E9914EB0B21,2C82EA0A5C69CCF8,73CFB51C4A586B4A,B083B5B30FCF0DAA,4DFDF3046F4493BB,B53E5B6FFA57E201,8C0C5BA3CC84E83D,0D0629F2389F22AC,00002FD65502D47E,87BFF5B3FD5E6F7F,797FEAD977672D21,75DEE14B5BB3416D,84D3DB29BB90B705,669B6851CEBB4097,61DF470F0F9F2950,12F34394D2CF41FA,3414C50114044680,54D0F957B1457E6E,76366F6DB1208827,F5B8590DA6819680,000043EF2CB1DF39,34EFA3F10ACAA09A,49346418D0A602A8,06BA1E8BC6192A21,9502938704C17476,68A06C42D58ADAF5,B8E6F95775095882,C281B21AC0D4F2FF,436C656925B76E5C,244B6E41FD3B16C1,A42906F15C444415,0E155E2610A7E454,00005009322C7E96,76C1991FD6EF25B0,B3313D3BF018A3ED,6DBD1BC482019D9E,7647C7865197D199,7925679EF6A582F5,1BA386C7E798378E,A7B9663A05D0CB62,F96E898C45C07A3D,9E17C6AF23DBB0AE,724EC0FAEAFCCC65,3A90A90E41F57DD5,0000602EFFD491F4,FD9247331E2ADCDB,AEB8C191F9A852F8,4695FCD5F73B494B,BC9C1DC8A16E2098,0B828E35A943091A,67B50645B39D1DEE,002FA681134C23E8,27F44D440B003EA8,4AF389A56D833BD5,1AF71F72F97B8A07,D9F4B5F4C97B0937,00005B1AF19DE214,E396B14247E212D6,93E40F7FD98A3EFE,8B01DEB485C72A60,E48FE4D6A3E00FD2,79D517A80735C5F0,2C2F6899BB3D463E,98D953E40D786ED4,3A616D8EF97A9DC4,0B8301C70327E934,66A93EBF757FC98B,F05160803E9BC3E4,000039703F1598C3,4BA6432E55927381,05D3025830065F0B,06D59EBD8BF7A9B2,CA800434A53F396D,D41D68F06130D0A7,17CD15FE5403ED4A,CFB92C4B46446DB9,3A17B69367535EC5,1A9EE6F23FB05794,67A42ED3E68BB66F,768D50AAC46F5A32,00002CA63F23BCD0,2114A8290EB3EDF8,97110D2838B7223C,6BBF2BCD4BC1B6BA,64AB59F14CAF5A2C,D9F8AF21BC19BAFE,9330BD6D5F64B2CC,B9F31B6065894743,CF04EED44F26B29E,5DB6478E4D73A9D9,FAE735EAD7F92D03,1C588BE7CEA09312,00003B64EB1EED13,81A4F69BAA55B0B4,2C84A606FBFE4C7A,698F9F56CAA7641F,0CF4057FF32D2321,4C7C63FB88A14A21,21DFB89493A81C7C,23FF8B372D340812,98FF0A579E9E49FD,FC54FAFDE8858FBF,8D1187F3CBCCE93C,88225E4F93C3E005,000013DBDBD0420E,60193592239BD8FA,58965C710F90C73E,A2C88959149F47BE,AA32E98E1EBEDF9B,B08E58289CD57765,5D41B8BB1D4DB8F8,A3868C86D9A10F95,C1419096E6A3C6B6,A35AE74C60CEB79D,57195233C02AED0C,5684BDEDF2842A3A,0000693AAC05856D,9733B773D1209051,6CDCFA59FA420288,C2E41D767E8441E3,378FE8AE2007D0F9,50231D1D4016A58E,1C41B117CA7B1796,D9275E17C08A904A,9302E79A486CA668,CF40AE803AD5614C,31CD4D14A108366F,3A193B512D905464,000055D23ED4E998,137916F7E9A7D76F,FC8210ADB63EC4FB,315008AC05DD3699,822FA81FD02D23AC,EBB7CDADE60B0626,E128D6BD1FF576E0,AAFFA3C9B0D74A10,01B1F201C852CAC1,C03B011BBEDF851D,21437479C3FDFA14,A8ADC8BF617D1B76,00000FB9E280772C,64D09A01E6A9C54F,8B0E5EBC3651B00B,98D6BE175C37DAFB,6D3B3E7A95011851,2C5E2BB1762741FF,0EEA43631BD3DD18,0F78AF190F83936C,DA43D979D0EE128A,E2F8ECBB4BBD9ED5,95FE92EFD996BB42,D39C397438D104D4,0000420B475B4863,B1A4343F5C4811A6,E19B02948F5D667C,E1C758CA3D4B868E,EF433B439A263620,12BDE3856F3A7A8A,BFEDE8944D2DDCC2,219BE21D0D81D99E,82D259CA7DBFBEAF,4FC3C846E9A32259,DCD4F0967B9C89A9,8A3793C7BE1D27CF,000010D1F4644945,19C1F6D8B8E9969F,42DBA47E0BB14E83,AC6B1DFD04A4E04C,64829C88E4C0B1F2,B746ADF475387396,F61D9F84CACFFEA1,FF0D1DAA314FA383,4097C1707CD245D8,56AC3E214282BC6B,A60944A81CA2E174,1DDE57C5076EB707,000027A534C3BF7C,E024EB6A40860C57,11204BF3FC49A53E,D76B3A13BB2058AA,8D82D663111FD86D,2D8B400F0E8D5EB7,2612CC4CC08AB888,D87C0AF37E71EC91,1FED3FAD216CEC98,510A264FD76380EC,65176DCBA9D29C6A,918084380B4DB7DD,00003230950CF901,DCA5EC95051C47B0,26566CFF361B2E47,00CF03292A0F7709,4B84FFEAA9F38F14,E33472988AC18799,0F93C624EA26417B,6B41F3CEFAF32D48,7CED6F95B9CF502B,C377421D036A3358,5B56DE2FBF5BF6A9,D61D92A25F4E7425,000002D6FC30DF09,1B6DA75ABAEB4DC7,EB5BC9129042F05A,5D82FE776EC11766,3558E12DEF729C03,774A9C19E5355A1C,3923060BE5F5A27E,D690D4C9FD3934F2,133D8E75F7B82503,0963940B4E0180A5,8DC214A4DE1587B7,198F93D7F883F4C5,00006B99804737F4,B90AF9DF21A1BC25,F270F2D61E812A0E,E63EF2CB088B4DBD,14D6E4D6575B44DC,D5E6E5496B286071,02781AE2DA4A50FC,F7C31EB194DEAE8E,26AA2544A5978E0A,CCB7075C7C4FAD1A,22306D6632E4EA39,673CCFAA89D277D3,000066EF3D379F24,38FE3F4A64C93EBF,9E213B98F3D55AA4,6AFD916611EEEBE9,7EBD3F0301CE5B43,61F3A86172376E5A,E8BC33FC566450D4,64209C86273A4F4A,DEC7809F4088865B,19DDA5E7480527E9,C1754272836E15F1,F9EF1390A4292F1F,0000579051303FE3,D650E4406554FCF7,A433CD52C969D2F0,94EA14A2ABD573FC,5BCBDB500934CC1C,8A229CE80833872F,9C5D726CAF395CE7,86A56293AA25402C,C39C40E1C010EADF,CC55547249AD69E9,BC089FA31C694C77,7BA9C6AB07E53B8D,0000107577310D84,DBBB5D0210169430,D30CC223CD12091A,D53D4FB01BDD91A5,920255BEDF426A39,57B0D301FF1AF590,F3059CDEEA2B691B,04B9162B2A4D0718,52B8FB9193F0BD61,00DF141BD46E9510,231DA8A333EDC9CD,4F1B41032B64CDA2,00006B3C6973E454,67D2ECBA41069F4C,06CC9EEEFB19C76F,8ACC4A8E00706492,D58AF35AE41DE74F,1C35D56CB73AAC7F,428C26C193C22771,2BB1AD85F43AB818,EB245CB4F4937A3A,AD17277854DF5761,F60F386C74260FC7,E395BD143314CB8B,00004D7ED977EECB,F8C1476E6094F53A,BB3B84DC8DBDC45B,A301A8712F1879BA,67745EAC53363237,276180F3928AB60D,6B77B2D473674D7F,50096265479CA5A5,46C56FC13CA2D162,5AE188714A6BF763,E92B5168551A1685,54A82A33DA8F4E11,000013FBADC468A5,DA0C37E39BF8275B,0423011B17F10451,62F8006EBD07BCD0,A1213446AF510FBA,04D97D76FAEB6264,E4CC3CB0C9AB2677,D70DC3BF87599E8E,BF427D6E58F0B966,E4970C07FA5EFBB2,E3066D06C7A5F3BB,3AF06D6192DDCCEA,0000470B3F84633A,2CEB3BEC8CFB4B7C,328130CEB00AC0DB,C0926EA232E426A0,BE4B632921DADA41,D4B4C14E313AC04E,E4EA9C0BA27A0A69,9A91C91906B31D02,77FFDBD57D88C57F,9957D22216EDA2FE,BFFE9696177AEB05,74904810E112CEF7,000045F0B8350968,1E63D7C355FFAF04,EA936BDC5AE26C55,3D714A8FD72D7B81,55C1B7ED9D2D2EF4,ECFC48387D5665B4,D566927C1FCE9000,EAE87CA238AE72FC,BBD20501F5DCEAED,62BAF696A2A0384C,2282C496503A18FB,EE60230D212E53E4,000027A359F33254,DBDA91DB6CF4EDEA,4330CB1803765875,C8D459E9A13F2EF6,3DDD111F1319DD1C,869C44D7833C8ADB,239A6773A882D147,D582EF0BD5AA996D,8EB7125706B395B6,5B9971B32BCFCF46,DA3C221031623F64,EE6A149E8BDD296D,00000AC0000BEA90,895E43A088904176,DA54D6628858A992,FF62DAC3CE696DDC,2122CD0D0EA2EF0A,D53DEEB5E025BEEA,695DAAC84909FEA5,92BB3F1DCA9D0B7E,EEE9C05ECC1FE3A8,E0F4AB28A7C625EF,D5C52ADB4F49E07B,E0C278A4EF6C72CC,00000E4DB0C03300,A17F9066AC688739,B19A574782708E20,62DD8B35A4AB586D,6D0E1D8AC6FDEC25,57429AF466C84752,10735E528304342E,19C3C8128C8B8107,8F2F17D73BA7F744,FA4B30705F286079,509C89A6395ECB04,C278923F57981891,00005EBDDA869A74,AEA6CF19A0849D67,91A414E49FFD816E,C4AE41B486D705A1,ED064A8594DFB933,EED0EBBDC44B2FC0,29EF871F31F7B066,7DBD0CAB73D1270C,7668120E4623C312,2801C75B3583E2B2,CD5CF8410180E42E,36A2828AD26E682C,000063ECC4019096,13210A7779ED3135,154B03C19EC1CA42,0321622D4BC71032,213E87DE110B5894,5886EC9EE61267EB,9DB8E7548AE45B3C,33EAA3181FB39FEE,1A8C9436BCE5523C,65D02F1B0351C68F,18A43095BEE28F8B,EAF65024A6E4CEB8,000036E5E9C86C12,6EFB16416619DD80,3B1B57E855D74265,5E57BC86E6A5635F,8A16895E29E9E5BA,C03089DB4E8A6A92,F66CD04B038C313F,6372A090E0250E2B,5A5351F54A28B5C3,D615A91A63CF382F,A954B7DB28FFFA0D,D0AF531663D949EE,000022CCACDB7803,F719F06A3041B851,45CAEC0A43AA5DCE,587C104B1F53ECB2,EE1CD36D8FF8A53D,6DA87A5AAE7E71C8,9D2F4E9BC25BC3E4,39D99ED2880222A7,EBECCDCEFC4C1C73,8FF407EC5A28C5EC,E265C3FFD0780BA5,A54083B44438DF3E,00002A68F6358131,A926F0F2195C9262,2DC77C86B88BB514,C451A98234B0D529,BC2004C2D737ED46,C08EF8A7747372B4,DD3B8CC377AD66B3,B51C8D854E6E08A1,64A9CB4A67947BF9,490B1F1ED3CC5C4D,CE1867F43C7CA2B0,9A1EBA02CE040877,000067E9D4FFB9B9,C94EC3C084DFA65F,D19EAA3165A3124C,87315CABBDC772FF,F252798DDBB6522A,F0E1C7200E205F4B,6D1C92DFE421ED86,33A9A0AA052C76B4,EDDAE91157E2E2E7,6F5239D5485735EE,7525093446A92C56,B3783B1583F73B16,0000440A783DF372,6A79C0DD10D314B5,28B63B9B8A18909D,89498D6BECB67B5F,B58FD14B66180253,AE02D996CF8491BD,C5EECD56BB96E441,B0F9F1B4D289C918,81238F3CB6916FD4,4EBA04108A26FE88,09A85B4A136AE0E7,4055457C9CD24FB6,000063822C9EFB1E,EE6CB166E063459E,BEA228B68F8A3E86,C7C0B1DA9176C2AE,62A4D9F44BE300BB,7E8AD7060D35EFD7,0CFA31894D496EAC,D01E617A13B3C4AB,6D8CF3616EBCB43A,5558CB878131C6C2,B2E008680E3899FC,505C9AA4E49CA1B3,000059AAB47FC802,602D3F05C3FC411E,1AAF6BC895626CE6,2652026572F498E5,11C55C105A6A61F0,C93A5406830DB808,6B576724EE0E4644,B68918694EE39BA3,C2528EEE41AE02B2,C7305FBBD4DA9CA7,D9DD31ED8325BB5E,8559F4921A47CD2B,000029BB2208762F,2E93A66394609949,7F05284F1669605A,FF705592FD090FC3,D9C0D6495141CBC1,7B4F6248C2D51AF7,5563F5BC9E36764C,3555AD3DA4789465,5F5AF0C8D0850410,FF5B1C8E6E3BD564,FD840D396A258FE5,6488E7580810DF39,00000739456A4122,14C7F40B3664CED7,0ACA65FDC1DF0CA0,2585719A0C4DD961,5FB83997693C8CB4,2E035E7939C922A8,DC3D04731AE05677,C5EF2D9725C237F7,86D5C83EA146CC73,8899B2EC8B248961,6CEC5BD01BDF8E58,FE7A5F8009904E31,00005AF31EA4D189,A222A1E663B861AF,3E4156E90E9A5661,E1AE698486BCD18A,E545239E5FA1E2EA,4F4EFBD55ECDBC6A,B4CC37E17FFD3478,CE46A4E4CDCACCE5,196CCC1B4D1A3B8F,4ACF21D5B6B528A1,2102B2415A56FA68,252C79B68F2D79F4,00004173DC59D242,10362B28EDEC0BAA,6549EF926A03E35F,108B3D24D8CA055F,E208676A6FF7F994,7D9A5778D799E380,961F8041A3DC22FE,8F23D7193856AC6E,7CD5BD65A1EEDEFA,A4A6659936FADE4B,2ECE86EAE9AFD5F8,D51708A8CC083AD3,000004807FCCB5B7,509DEBAAC0195B11,5589E9FE999BD2E1,31C01213BA1247C1,BCFC073BD14CE4CA,AF6669E08D1462EB,8C5FAB746B99AADD,5ED76EA6D535F5AA,8726CC6B25E4CAF9,DAE7D3C30F474D03,AB849E2CBFCE4F2E,053DF0FB8875AB53,000040630184E5CB,9AEEA76B01517D8F,B2DEA2722F25A628,B0D38CE145A45824,6BA6B64712E7EF2D,D8A54C7E0588C224,FADF13744AC8FE02,6FC223EC3C2B903B,7F17ADF507EC847C,9E2BE60A8F5602E2,85AF8F35DF2C3F2A,A94D27D04A414116,00004A9665732B53,269940E73F89E306,EBB8D7B85988F69D,744B4B7FD522FA6F,16AEF5ADEA461BC9,757EB2C63797BAE7,995E874EBF659C68,0FF06BB8157FCB30,C239A4F013521F8B,0E181F5159AECA93,E767479EBAF24575,BD8900673FA897AC,000026F385E924E2,BA181D4BA7CD4692,9970CBA109377CBF,4BE5FE5B03A7CD72,DCB6BD34E5A9F435,F665CF4D51E0F190,AE19A20EBA143ACB,B5D68281C63367BE,EAEA3560D6B14A4A,DE129310CEF35068,AE12EABDED1F6490,2A0D2841B2956193,0000573DB2AD0B36,8592EC6124C56D64,505D62376DE6B884,2D496B9A7ACA7D60,32AD1FD691D1C4D1,35049AC6385A2D59,07E026580AE465B8,851849B13CD14311,24ACB631C151A076,EC8ED47CCAFB51F9,643FBF5D6BC3BDD4,E34370BCC56D4256,0000522A23656F3F,FF4DE65CC6DF283D,6D69878CF9B57259,65C966AAE809D0F5,3122F9FE04256549,94BFD2ABA2AF06C1,57E2E53E047641B4,54A0F872374B3D8C,81C3A279F13E56FC,9A95CFE8B0F472B3,64FC637255EEEA28,6D005024830B05E6,00003AD1262538CE,1D26C3DE020F50C8,7D52D4EFFCE9A550,6CBA4001C0FD3A72,4250601AC7C306D5,4E03622A4D9C4702,B6804505BAA7A24D,427084B205FE2C09,8D0B6722E1769793,24EECB3992DE3D80,FB43F4F6A4C76005,D6A5D0AEB8CC6AFC,00003C87DD5F6B70,84BA94FCF11AE0CD,D9F8188903FF2FA0,226B833ED66201F7,BB0288403A526854,C60A323B87943554,CB404B70D8DAF5E1,2B91DDCE704E140D,A1420F5B985B4760,44A6606DEB956548,8C8582F0E6347DDB,A064CE25115E35CF,00005656CC52800B,F5308FC809E1B403,DD05CE9CCE07A3EF,DA587B85F16E3F86,AA1461157105AE63,B22F1C23F8DA6751,7BDEB442355028E3,24FA8C50AA46EBBB,79C729E5AB9AD25C,DC3B3A8B8F33AAEB,3C8586E6044808CC,76DEED3E9101FEC4,000050727DF56B6B,2EDFB1AF9D5356BF,D1E25B0D907887BD,0976B5A3C6E6B777,834A4E99B4713690,522C13EE51CF13C5,AC3D5DBE82F4BF64,F95F84B34E34ECA5,9987FC388F37D75C,56588CC4F497A985,9BE8385D1B810F59,431CED1E1A408653,00001E6B920E9BFB,E5FF8C39CBD6B4E5,5434A1DD38566B91,A5C918FA26D1CBD1,58B2A939560338E6,03717721244B0389,553A9B0F8CBBAD7F,40C48553C235E4EC,1473A8462DE41B54,9FDDACABA04F0160,D4B73BF316E3D125,F9F756DB43F1BFDC,00000E4154878235,9CE4B83EB4C0C249,F6185C25667C75D2,564B49B58A2CB773,6C27D2F8513A30A8,A32A21D849DEBC0E,02442A4FCF7935B1,150E59BE77119AEA,78F1F374E59A2CC2,953DC0F00A70B532,565B95D2BB29032C,43CF4B4BF4048B76,00000D7184F6E3EC,BA4A13112B7E71B5,2138E8F920115B6E,E563338C73443EEF,0CB50D864761D703,E935C85B48FB1B4B,4E66F70F6B42B284,012A9B2781892DE7,65DE6B4694CCB1EF,032583042B4D0F13,E1638B009A1C9636,ACE5946F28176C0A,000014D2D0BDCEEC,0B923EDA3AE8A048,84A061C3B8748446,CE94CD1FDE69633F,2809B03978C53F75,A97245300E57C2EA,D2A8132B8B7FA7B3,8924306E774A77AF,38C19CA5F36A7FD4,34EE201493C0B8E8,C5852CEDCDC655C9,B9C9B6F057DF517C,00005E9DF7BF7D97,07692C1037DB2F52,89F8066B7038917B,70A36612B0BC4158,8D3D7B8959B9C4DB,08CA91383BF97418,C8EB7E9A3DC14154,0D7366DF20C19AAD,E8E42AACBD136148,74C003739EEDC963,5DB7E68AD63075DE,ED14B65EFADDB741,0000596919A0C19E,3943F474CDE9FC57,F241678C299C795D,D301DDD0B303505F,981BA31FD7501136,12C1862D65147844,0F6DEDC8BE8D8983,344079E6CD506D1D,287A2D5A07300E13,86290E2CEB97D352,B251B1C3C9506401,19AA9C515C6B2397,0000601DB5387FB4,F8905372FBEFCFB0,44865958CEC481D0,E93E2F9C4F1EC1E2,767BC7E85AE79E3C,9D2C4BBCE85E939E,CDA22D1BAB0CC4B1,0DA6180B4D356B5A,CE6B4A31A23ADF6D,627FEBF27021984E,E404F08B224793E5,B97BC29D0589B883,0000299EB1538F2B,B014E15D2F6C5525,4CF7E970980FC2AD,4D86FCF7220827F4,97452BD6B36463A7,C0168AE4B9174408,C5A43764D864088E,6CA33DFFFA256C37,1EB775718D23C764,63718D3033DD2911,FFA78F2F945CA85A,B869461F46EF3B19,00006EA3726FCB59,742EAAC3922D2A98,6D6AEBB98E3EB323,A90D00C2B7A4711D,1B547324567FB724,1B99FF594778A5F9,420113B8C0687C36,94511872CFEF96BB,A94DDF92C9B1C230,D4A2A4A7A59A02EB,A0543A479A43533D,EE716F06ACD3445E,00000D6FC67CBDE2,38B6CB2F462C7041,B9E75D04F6C373AE,1166D2B9E841C25E,0E2CC7BD10145428,7B35768B64F4029E,B23BB1C4CEFBBC14,5DE2652D75B6BE0B,E33555F53D5A094D,CEDABB0E93F51D43,260F0BA47A1458D5,E5A44D61565600B5,00006CFEA1C18231,12FA1E4A23808626,798061F143DEE794,A343618CF93FFF32,FEA44324222EDC1D,CA1BD813BE66DE0D,94EE09B1A50803BC,2AB44714932D7DCF,5D68F835CF8DF52D,13D370765C2A9112,5B45FA515ACD64A3,E46DF65A006B5BB3,00006E10FF3C0123,ADEC4576F3F1EF70,75125C752F261AFD,66A81FE2D408D061,3E14DC04B58587A3,FAE2CD65C78772DA,FEAEE61C78365018,D5358944F66D310B,D2429841A720F0D9,0E0EAB55553B4DFB,DDF3DC4049BE80B3,27B7C8BBACDDA2B8,0000626DA4787231,AC0006D183B0DD10,FAA71B77E1519C4A,F367096B92CDF010,354AC8E54C0C12CD,A9D93A80BD5FEB5D,84CBCF1E7DB1FBBD,3A3DAA7399B17587,B1C6260E3BB64E42,C0A93F169B0AF81F,EE9B85149661A0C9,CA4F89C86A145384,000016C661166F69,65A870FA14D2A38E,A616B6D4D73EB831,E3F21362AB832F80,AEA2A3279ED384E0,3D4FB0F8347F9185,8CC65018C87038EF,76FC27F8A29A6515,97B25729B52A0E01,9335629FD0C932FD,DF7FB3F7066BF131,B93248657128EBF9,000024273F632EEF,0C19B07BDCEB68CC,4D65BD493499452F,4A23B2E0A3361BB7,8638484A7FB4B542,9047A41B16BCB852,1F5AED9A9ECDB1CB,1623193EB0317BA5,E61B9685A267E47D,8991496FFDCB8398,999B98EF8F817808,8A2F7940D732534B,00005A69501635D6,789BCA9183DA0BA2,5C1A3E38305A5FC3,2778B78485ED5B16,C65EF3F5D88AD906,A32E6D0EE21822D9,8B0E25F27A2EA43B,C264FE0F8B3A02DC,13856E76AC1D89C4,46BC2C3D2455D36C,C0EEA2961E94010F,EE52DB7A6141CDED,00001966F3E740FE,D0685EB6A91E68AF,D898384E145A999F,875AFF63A94F1E3E,B571C98688B11458,824CB3068C52DA18,8C35871428958CD4,ACE4C9148CA578E2,BC5F88F15216E8BE,63A4AF43753F3475,37B3DB100879A4E7,6DD0246678F667FA,000050828EAC839E,788504967D979323,0016A4771C3C00CB,7B45C2984E1B9505,4B8DED65CE310102,66E37DEF066CCF3F,655684F96FDA74AC,97106B9C7C5799D9,CF7167AF95BF4663,9010A3D46388F48F,0F91CDD9C666EA11,AC5804414C7D6184,00006C5CAF982B2F,FA88DABF6F1EC496,E7D74AFF85466C0A,7058D38293921123,6314DE03D71E87BF,0227DB58A9B9951A,B508467FF57B4D76,EF779ED848D484C3,852DC1A3A8AEEFE2,8EEC948584A4CCAD,951F6C421E1AF5A2,D25B817417DC1870,00005940B4565871,75C69CBB345ACF00,36911A0BA101803C,62639D2C7A6828A3,2E63606709B97685,D0BB735A3AEA1B48,EBC44546B7C5BF7B,7F6444E985E29D7B,F064DC018DE80359,1E2A786744306ECB,5ECCAEC5683C20D3,F431793D950A0269,0000188021511D67,C757E0881A4618F0,48878DED38C0E75F,855108801A9F113A,5B4C3B5EA62AA7E4,BE6CB67171A7D2B7,563FC4E04669FBAD,4675C9DE6C64B227,76465ABE510BEEB8,1D29B4E0B7B85106,A45C903B66F49179,4E0A3E831F445F01,00006B886A5B62AF,FFAF54B37EDA5B81,7D16277259F93A34,55F92D00B2FE6D8F,55C1BC9A16729987,4FEAD19DE22EF10F,B3BCF00647D8A3A5,6F8171B546D0C3C9,9B40EF3CF9493EF8,4A06C912EBB55589,BE5AED0D0DB307B9,2FF7D722620DCD22,00001D7C8C1D621B,CB681CFB49370013,D690698182902479,8EE459D3890085CC,5D9A4D127357668B,3D6711A5A3E36295,195DDC7E9C5AB0C4,B8FFC5B20314C5E5,7580C212D953D4FA,20B0EC3E38ECF30E,D7B2B2B533B63CC3,915089E2F139CEBA,00001C28C54D84C3,561AF3539BA421AA,FB95DAEB38E65FEE,81A65304339F009C,68A3827E893CE03F,8428B31B4666A2E2,9B33EA7D219081E3,4C05FE1B73734910,49B4FB7EAA628BA8,8C59175BCCADCFDB,8171D5580DBD1A4A,E73BA4740F7A40CD,00001A915C8C63A4,4125E561120FBDBA,00CD5CF137879FD8,2B4F61195E2EB93D,9AF2BE70BC0733F7,CEF342D794E7A034,70789B16E7E484DC,928404636ED44D4C,953890401F381E8A,3B5A5C6AADCD5E2A,B062CCAB1DB9741E,F4A3E3DA0D47FED9,000037CC913BCA7A,B50D8647C1A8ECC8,6D1E2F1588E8206B,08B5825384EAA376,1E82B2D4E0671D2B,21DCADA137D060C7,CCC269558D8054E7,56E4F89F22B4067B,E274B2F44772766D,F3B1617D2C667309,1AC80FDF87C82DAA,C6BB0E831699C34E,00001405C04A372A,3A2B1510E2F48AB8,1F526D95BA079B66,A1FE9174C766D333,F760FFD8FC765DCB,987087B5343C0A70,D644B04EE51D5CC8,3713C43B39535D8D,FA095FBD556D42EF,BE9B82FD1C6FC3D2,C90FC0C166545996,58E6AAA80271494F,00006556B33918C5,2BF50A24B7B6C1F0,70C4F9E75C6B2653,D38517C6A4072E5E,3313B1D09BF29DD9,A690BA3072B748D9,8C984E2D4874CD7A,68A94C63CD67C0FA,A4C3C68DA228B701,5A81EDE9AF670E15,470D682EEC5E1615,65353F62E2AC7CC7,00006B5544F75958,2FE3C4F81ECCC2EB,61D5EF54056306C7,4734CE6BC733BB41,803B16F433A424FF,D1A3BC25D44C72C2,70EA903EFC1166C3,08668DF41D95660C,3DBC73EB7146ADD2,F7317DE9A92628F3,BE01163C25C2255A,BA276203B5EDB524,00004BC6D6AB805B,C9C5B2C1E3BF63AF,D33740B8AF9E6DE7,5BB8BAD31A11D14F,5E1A10C2EF9D6B93,8BBB1474BA16D20D,422C5AA3BBFC3958,3C8A3B78ADF16E9E,6FF8E53AF4BD7CA2,89D6F76C54C3EAB4,B1FDB18C89B0B26A,D374A335CF810EF6,000011950CF7A4F8,674EC11790FF3BC3,DC8AC45D64BF731E,B940540D4A180F83,912F95A83FB343A6,C9FDE9BE7848DB73,30D250DFE7F892E8,DA81B8191F2D0190,19E68D2AD5D6A4B2,120B89A8A0A4F7D1,5BDFDCA5C3A764EF,9C7D42CF23FEE039,00004103238D139C,2B51261AFA046E74,086B6E638DD249E4,136247D19ECADA4D,A24E00D939C530DD,5115C34C6C93AE25,786ADB5099148159,2DAB4B5A658A8E7B,8E33B3CCC501DD05,40E2F464466383E6,9AECDAB1BB8AB508,4EF25E2A4C38ADA4,000042EC415F42F4,67226F351935D3BA,E43B2F371BB84E0B,49EF1218DDF52623,401810E47D821C49,A468CC690276B816,5007E70DC7F440D0,A52724C7EEFB2720,8A0C55F9E080CB1A,536E4D645F15CE79,07A3C74F1F7211CD,BB47613D5A3CBB1C,000024E467948DF5,D0A4F28D3F64ADB0,26BD18598574C960,4E6D868F9442AB0B,3F9837E17BBE6083,EDD47C470A54FBA1,DCE4258BC6C9A2E9,C1B6D1ED7F1B5DC5,D541EBFF65B21920,E03A8B9216AB7043,C1826B2BA7E20C8C,EB56674FBD17802D,0000254BE273FB36,1E41FA241A66991B,EA1E7D96034B3E73,1BF4AAE4E1F417A9,CFFDCCD09B993CC3,66155527F53CBF31,EA98B4DFFF574F2D,7F0D34C9238D04DD,7B4C4BB8F72613AC,BCCAF8350D615826,031564DA71F9A930,448EE2F4576FC936,0000134A0E0A81FB,68CDA7E6185CF3A7,F755FD9C5163944F,40E272FECB3842ED,7A83E2E4ECAABD53,8762D8FD37BE72B4,B8E47125C977DB4E,5AA53C35115D9353,2A7E51ECEE43EB18,CE7C634588BAC981,02E4203CCF1FBF99,FF13E075D7A47AFE,00000EED73B8E6AC,FE9F167D976C88BC,72639A303F753766,F32A99852C5DC375,74EE6ED5E2842AB7,67530F53D06D8882,B4FFC7C5024822E9,6ACDCFA21B47EE26,4EA9E1795DC4A1CB,92587699E1F5F663,3EEFFF96069B129F,3FC04ACB40CD72BD,00001DA0C42DA1D7,D47CAC5198F6C576,5EB1986A3F19D5DD,A8CF48AB4B9E8DE8,E1A74D88AA2AC689,580BFC7782C655DD,78249BC6F9977F1F,A3BA47D6E4BB07BF,F804F23311898295,901F45FF6B9744E9,2469F2132B883098,CE8DB9826F0B59D1,000039069510948E,26B0FFBB4A3214A5,A5C93B1753A035F5,E2B6CFCA6561DD1E,257E988EEC8F5F34,0B177F5F88561A23,F62DE7C275E7E6E8,A7517896A71322BB,E5D4C4BE2340E2E1,B0E4F762C15121C2,301D9669F4D67EFD,87C0798CB6524A47,00004E58B5CFA352,E433976B834B7F25,83B308365B686A76,9ECAB44628A2CC83,F42A8B8792ADF191,1314FD1510E03D8D,46639EE129923A69,140A52991C11468C,5529D5E5DDB497A7,E0AE684B3845BD27,991CA537608101CE,5AB6467B0425D6B7,00001E2400A53705,6E06BF188F6D4B5E,1E7210B1488CE380,80C4ED8C215C1FA6,FB1B28C7068FB2D8,B64973B970F69704,E9D0FC300BC5D595,8989B27E7EEE8911,46647CCC159B6F55,BA926E9C6DEF3361,AE142E899960AF41,090EA6644B49F528,00004901E690CD55,8344E4B7942069EB,F8727BF4F07B597C,50FD1AE8AC666130,CDFB79D0EA063BDE,A21B3157D99AD372,D5114C348557F75B,C8CAF652304F7E54,8A84FD17AC6853AA,8E3FE3F115CBD6A1,A526C4BE2F17C469,49FE873E7E150BDF,000062A0DF5B7B84,E7984740B349773B,B5A7926A467D4B0F,90318A83C0A29F74,C3826C7EBDEBFDB5,9EF1772811AAB04E,98D31472E12A2A1F,590C93B0B2A95506,8016BCE92FDC471F,BB5B9499373A694E,6D84BB77BE695FF5,B81D90BFD31FD605,0000098B478BD826,66C96702459ADD1E,B53F4660A137D85B,A92FA8A21671AD1B,354CE62772067896,176EA6549FA02066,70EDA1E0960D391E,14F922624A00BCBB,EED936211D5C062F,69477D44BCAFCDFE,16363164E7D353FC,63837B9105C806D3,00003E51B7F3941E,2C9442566644A189,9A9DD574AF998B9F,95ED4F8710886CD3,5120790845F69DA3,EB984BCA274634B2,2A2D058DD1BA4692,384F2DF26DFE1969,0C6C9919A0EFEE99,38249743EB0C7D7A,CAC8A47402A5D29F,C715388E58117CEE,00005E178ABC630B,91C67AC914B16C62,760CDBEC9A482DFC,D9FE138F5C57FBFD,29928A12350F42FF,5972EA2A93EADD82,58333BC266A3F1EE,5AF2FB9D4772ADF6,C3ED8F751B4D9AFB,1F5040CB8DD03692,DEC66DF841999353,470CC2EE88CD10EB,00006F4FF6275E36,966E6517661BEAAC,2348B3F5C014BF1D,95081A343C01E5F3,669DA4EAF1DB561E,9E863C399EB059B8,2EBBE6488EE0709B,A4995A7C9E173A2C,967248CA981FE66E,08F4684D14D223F2,4E39EE265A34145E,C04FED0B10180680,00001329C3B108DC,BDB2E42A4E739CB4,2B1B3C8687D01DCD,50446F2FC1500811,930C975152A2680F,C4E29F593735C448,FAE1525E947C6ECE,ADF0FF4B574DA495,F752E1DA1FBAA69C,24991634314B83DF,47A264C18FDB5CCB,0061ABC12D3237F6,00003E0835304C19,59D039D1DBB08766,796886848113397F,738F2B462E7F2D75,66DD8199ADE4C30E,54EE91CB83CFCE56,E9CCFF68AC86825C,15BD4BFB5A0AA674,51225CEA3AA14621,F3B18FAADFCE174E,A5647DFE65BE0812,F89DA46937B73D3F,0000652C8895E76A,FC752B768E826158,9CFFE38B53A9836F,0459434312114CA0,ACD2899779B4F361,BBC2C9B13E830D6E,17C3C0637385D098,E3B7620096E11FBA,830BE74234D54B70,9BBEC200D177AEEE,67AAA0152F26E98B,0C5363F5C473D8DD,00001DF6252F34B0,5597DBA0515661F1,E01BA2CD34ECE024,975C83A99D25F0B3,2DB4A81B218DA2E3,B5CCAAAB1D71FC0A,B843CB565D61AEAA,69AD1B86E04C70F3,7CD92246FC771E43,B475E0C4614EB708,15DB76F300196A52,034B5DBAADD93B1E,00002961B6B03535,5A0D617402276F7F,8E748EAA824A640B,4AB8C439E9D7691A,D57501EC075D065C,124A55644EBD09AA,D507A2A95A01A0CB,EEA48B4E50628FB0,66AB9115FA76188B,1E4B479672309C0D,07F5900F0016285B,1030307666B0BEEB,000056F8C30FD94F,4E89C0AA7549308C,FC137159A63B4A38,19468AAB21706765,023A2CAEBEA49D17,E4135B4AF865FEF3,94EA8DF02A513864,DED39CD1F614E7FB,9CAB7FDAF2B57F21,219D58D7074BAB3B,9A73F0CA1C8B3AA2,79F2C012F4C0ED0E,000052816888F289,0C98E9B79D90ED6F,5DB0621CE38FC173,B736ABF510D14226,1CA5315CA7E55256,E85E8BFCC1666AC2,804A5ABED3F9CCB6,6BAFA1580B3104CA,26F93688A03DA62E,FEDD0194DD198088,D3A334EECF0101E1,F756582C515BBF2C,00004C0461EDC759,F42691D20E5C3C32,A230565F2D1BAF9A,5E44EE07392127BD,C062B6FC7F5D6E6F,14A97B9F9426A5F9,81E0E59DD820725C,64CBE41E18463D08,6E7498AE5119415D,BEA427A33BF1786A,B30E100763F7801A,A866A746264BDF1C,00000DDD92896F45,0FBC1D8D300B746F,BE743C5BFDC10BB1,CA43607B7AF5B67B,FC944844534053F7,0176CD396E38EBC8,230E89F258AA5627,B3C19EA4253B222F,FECEA79498551209,0433F4371C9F1C65,A88D0BC077D2F074,3A2E2351A01754BC,0000256C0E7E25F2,7AAD987B65F2B608,8FA2D142120EF633,21C073D2AC528136,B8E14ECFD08D4C68,2CA4913E32A8CDA8,4CA89904AD6F444A,8BA29A776868B837,7B69B495CCE831E7,E7DE530E5D5819A8,A75068097E5D3959,14D01A7C2FD0D8AC,0000361E2318FF2A,1F3FF4E92A248575,D24CF2311C7A4A79,ED15EE304CA9D470,E19D82EE3302897E,AD9884FA7F54651A,898952BE1C766D51,84F660FF12EE2E6D,83838DA8E7D3B83C,DB0CFB2FB68DFAE9,AE5B1953E5597DDA,E784743DA417CCCF,00000366FB2D5ADD,F0BD015614F147BC,B748F00210DB800D,D198624FD975CC44,5B1265AD0966A69A,751F2F0F34C46B1A,DA6D418D86F69EC3,437308C3EA78A4E4,5AD092CBF5D6257A,6EF1D85F0166F3DD,9E25CF3DBE1FF906,661CF91A557691F6,00006652F969B93B,0315AB40AB04A767,A88626BBBE6548A0,DE692C617A499215,0CFF815AF4EA496A,01C420A21BAA3746,2AF27508D8D6B026,0FC241ADFE889315,3D898A1B0AC56631,2B047A9264DC7A04,95BFC7DAF29B80D9,CCA4D06BA7DE465E,00005E7ABF294F5F,AAE85DC02057F054,79B7B364E962FE11,C0D48AB1984C3096,0C12950887425174,9E0EE32DAB985BD5,D548915C7F5FAB3A,A72EA7F382F26A16,E93920CC0C0B1D37,8375A4E0FCC88E30,B68496F2F0973BCB,89C38235E444C0EB,00001F51960A7FBA,BC98376FE164C7E1,C31A674CC9EF33A2,B1851615A18C4D6E,855A9CC1B7424A24,584C6962BA1602D2,044D32113354E185,0E6715D5EE6F7EFE,28E8FB6E06D17E3F,DB9E9F1AC7501AF7,5B4827935129C9E9,E5D256A4207B10A3,00000AE776207A03,1031095E7208F0C9,17FD098B262EF7A2,0A6DEF317654C69D,A4A37F6A7EC8A540,1D1EBF1FB5C8191D,E359E7F4893A5C25,C10336B74B921FF5,A73B6ACCD805020E,81ED815DFD0CB15A,34FCBAACC53FCD1B,C14D4FB7F9928619,000038BAD2AE4DC9,3D2147341F661DC0,53D91CE0F260DF69,9A4BF3521329E281,79D3CB69AA0BFC0D,A656B76477403CFF,4467106920A35FE0,54C5AABC6321CC03,B3A9B1419AAD16ED,C8930E4454457FC8,ACDFEA703E829CDA,B0818F20272616A7,000027AA9A9A6A19,5D7E1E153FB1FD9E,B8A5870ED5CD2964,79AF9FCA6BE98942,099E1646E4A9682A,140CF559E17531CD,8A8523FD5470106C,9D2BB1F65EFD24E6,6AFC3BFEC19E0EB6,14E84602812AE46B,4AB2D48B85699B79,150BBC1A06FDF231,00004C3F0ED22412,74268D7EA121F9FC,AE473C4199886245,3591F3C8BE2E3661,2D718DDA0862BAE7,F5A84F43861682EA,569A46C466626A95,20573BF55711D6AF,8A435D9A725EFEC0,C8AB23101291B3EF,F925F58D7F9F8E2B,D2CEAD159C772717,00004E85990866A7,4B164B37D414CD9B,B811777DDA398EAB,07EA14ABF4772DA0,134AB8CECB405C1C,2A839943210D09EA,C6B7342027236F83,FA7E15F01589CB12,58D15B9C19C709E4,8955A610E68DFC67,8981F10D0B6D6BC0,7C11A28E8BD42DEC,00003F1C5933D869,1A441B5AEBB5D1A8,D652FBA408464832,8DC9CFC1012498F2,19E7B143E806E09D,6D87781F09BD924E,9A94C56A3D6BC031,6CAC497CF34A4449,9CA71963420A2EBA,0CA44B2A4601D171,6879A9D346FE8F00,85E17A5A79937693,00006B03470B7A5A,AEA93E2FC47E27B9,533482FD7C37929C,11C7483B50A98A8C,C623DDBEB436E67B,51E7F27F776FC7B9,4E1EB321A9819F9B,376E70DA1CF2F7E5,2EAF590E213DEC0A,4C602FC1937EA7EA,EB1B25D0EF3EF372,7134D451D40B8816,00006774D943D93E,EC464EBA6EF36CAA,AA00B4D0C163AED8,D5C069A7B3860FFA,AB99898DF81F2AF4,A9EDB5DC434ADD48,4AC2CF37A61168A7,FE348CDC918AE55E,BBDECA10D7A87A22,DCB2273B3AAD4C01,A71E727465633286,ACD06CB9926682AB,000028A3D360A309,AB9D6873BFCB6CEF,7176677972874381,0582F54D10A47992,C03D9E16B238A76C,2E4332F18694FE89,A345728877182DD7,9275AB32E79811EA,BB47B44246A500B5,2AF9C00D12265D80,7162CF538BC8D560,223F112A6ECCED7B,000051E8F7A6E34B,FF96A8C0AA330056,FCECF206FEEA7881,A9D830227DEDE2D4,05E1BE313A43B5BE,08F7ECEB8E1204AE,C1CAB2FE9A5DF732,875251C1AFBE50E8,E35726485D992BAB,C04EDC7DC9AA758F,C986604B3A8BDD4D,D9AB682C975F6BD0,00006CF0274269D8,E366C4A01B14F7A5,3A94985737C7AF61,28DE897D33D7C864,7F9CC077B9A6632D,EEFA6DACA26D0B8E,F5BA706A574A43BB,258B8EFFAF3DAD2F,F677EDE95CB0DE2D,DE8CD400C3EF3784,3825FD6669F03F4D,D42618BA612C7875,0000354C80B3A583,8852A24E017BDB7E,93A977732F96E1B8,ECC122E74EBA1149,07B328F646C501B5,7EBC80B04495155E,73CEAA08B157C861,8F7F20BBD5F5D8F0,6CD222420BDF18EB,A3289708B9E7E9A2,915EA71AD890B984,D1B41AD25816DFC5,00003510E900C8DF,2FFC9F59D19C2384,931CE9AF876DC005,D6B33B1CBF748183,051D95CE5E82ABFE,F09D09EB0D459F9C,D7859D8CD3BF4CF9,1979180289FC8583,1188E3A5362DFFC2,235E580E84579F32,EFF3F2E0D543E90D,74FFE57B8673EBC8,000016908356333D,400A5EF4C8BA16D0,C8C13B938B0A965E,16AC6130DEE178B3,7D34F049275415DD,E9DB2EA06BC8E453,35891AFFC0B7FC6F,59BFB83414009308,658F5DDF09C58F37,ABFFC23D3EC9E3CA,1DB809BDEAB6F17D,BA8F221CB2DEB6EE,0000214B127A328B,42F7971D4A79C42B,D5DBDF1D751D411E,8FA54D2D69810FB1,1AC0C86A09AE036D,ED549713711CC20E,EDF8B84F8821BC1F,67EE7FBC193F33EE,4931CE9A04A97597,51934977894A104F,644CB9135D192BF5,73F626D683D820C7,00000CC7CC74B108,6EDD9A3935F8E0A0,DA551D06397A6DD9,E48EB477C5618645,22852940D7F2F3EE,ABC7E091EA62C473,BEC980642F0F4BC7,1CE7F8175A700989,ECBA319983D85557,9C944DE50E144C40,A5A2F661A204B7E1,6F65EFA9E1123F46,00001D5C4B04ADC4,6F41F4898285ABE1,332081BE8715417E,DF37CDFCA6617744,4AEF46CDCF115E26,7097EC9CE7EEB0BA,1791B6498C0C4951,526E92EE71C5DA54,C37837425A62B43B,BE68A2C6E6E2E103,B33380684E9BB452,7C21EAAF5338E15E,00000325F3AAA87A,C0568013364C2F55,C53E4D6541EADB84,EA02BB5BEAD679C0,F560CE44C0439807,CB0E27954C07D69C,C6A48D63A09471D0,735D1B8FEF3B5BCD,87C2A4251E3DAD9E,8106268FA9E1116D,6FD96C6EA7FD38A7,10413F190E64F593,000030CF027F63C8,F5DE1AF5CC130897,CEF14497845822F9,0B6E5F24B9CCCFB2,49B159EA28A6A62B,AB6C0EC870B0504B,9CC6D8E041322F2F,9F517BD2F63B9B72,C951A0D76F01282E,E62AB3105DECBA9C,0F57780795565425,F6013E64507F0CC4,00005CCFDD0FD854,207CF77F91D22BC4,2BF3A4F2828A28FA,5B2E2CA778FA4F16,4E0377D06AEA93F2,D4AE320E67C08962,64F433AD99F65B4A,7688E33C2AA0EE9D,2C40CEE4E047197C,79E190BBE1FF5A19,9ED08BC6B8B1F1C9,1D42CD0DB98323BD,000046AE42856D0D,80E0C23E6F3893A8,FD378BE537A06181,39950B554DD6471F,640D19999F950D18,F3D87BD6F10BE6F1,77F6FEB874B4290B,D28481BC5EDCF8B8,2D52BFFA85E37A8A,EA1244F273FBCA05,FFD62D5D7599DEBF,10E9046025470FA3,0000079BF52A2A48,82BFEA1F3B286CCA,3800AAC58ADCE77E,CBD470AC13CD89E5,AF2FD4237E02BEF7,5319D69327D6C168,D615DC8F34C58E6B,603C3079EBBD638D,7410BC6F00AEC34F,17DD918AC12FAD9A,AA93B65D20C21E37,E8F0946111978935,00003E97DC4EFBD1,9B7073C77C60DDCF,3611410D20F14D0C,8990D1EF84CA3390,B4A1408CAF3F4938,42EF2EB29A5C4440,14B278D362B6BAF3,6B5B25348B4531BA,5BBDD2820599131F,C1099E5CED0128A7,33E4AE0656D38DE1,15E7681EA3943295,00005C63143FCE6B,078D3D67495E4CCD,00CFF1792DBBEE2C,5BFF2721778526CF,BA63B612658BF18E,EDD4F04EBD3ADA9E,F0FAA3ED3AD2743A,2FFECADA89AA2A5A,B62E2B3176A505D3,32748B0672B04C0D,C41DD069F3588E81,E3F1554513215063,000053305C4DED81,E3F1486F6F019A9F,F8657F1E58E0CEC8,6A18B294D00DA79C,824988E99CBA8B76,0EF02A27DA5561BE,7E4FD92D63D5BD3A,088ACB15098F44CB,48F49731DEC548E7,1A05F9E44944F739,0F7374C715A82E08,261426B4B366CDD0,00005B9E8FC1471F,150826EA31CF5B36,791EE7FA1D867D9B,FED0639963E2E4FD,8E056153FC8DE2A5,D65A2FE430DC056C,D72E820021DF4BC8,03BCAFA199239C9F,9DB41645F78552B6,E9472093776D861E,4D2BAB59984A859A,AC0D1546606758AF,0000113BB2CF6E7E,45DF353A05167A36,5C7BEBA40611B73F,CE9D644F69DEEEF6,CE4AA7BFF449FD7A,0A860FDC1FCDC569,9FC7E5B11B90205C,BE68B0FB27F9E1AF,83BD602E413940BA,83C66C574DD59DC0,1D6999410E60ED4F,CF126BD92CF74130,0000287453F0C3B7,2E614FF0C71C9414,E0C3C9C2F1779024,27F5A4CB484FF49F,C821C05464865A0F,72D54650194EF134,DD3A577C0679DE87,616AEB7704794468,63451AB391DCBE4E,13F336A2C95A784B,397C7FAF1E1DF259,220E36E81AD3704E,000065AC6302DD38,51E954BCCA2B94C7,365815AD2853B3C1,641CC650FAB7F975,41F40C88196BC5C5,0A98FCEAE567DE0D,B50B77C48CB24719,C7831B2DC8CD38EA,78E83829561E991B,01C26B9E11A68F93,149CD5D9D5F54521,A40F047A288326A7,00002842A6B5036C,AEC654802F178002,2784BE0DBFAB185D,3FF5F85CBC104DFE,9E71B8BED0604D09,B1AFD39EB20E52DB,E4126021ADD38C4D,F30B9E92BA96F9CB,F4741A2E488D0EDB,446C7BB87A126533,FF28E3C5A65BE611,51E2F91ECFF5290F,00000CA6D7785B68,51DBE76253FA70CD,A865B0C96131A755,58099C164E381D73,C3A189E019B01C65,8CDA92F017E6D2D4,D10987F77688FBC8,16537B42B5B28E39,2722D233A723FD22,B495C22B57894248,5FF875F17DEF720A,5D1A48EF3C6AA24D,0000517AA6A7416E,2B49C89476179896,9448AA181B4DDFA6,3991B14324294D43,C777E52BBD8510B1,DAEA497DE263649D,1AE43ED4531ADA27,B675D760977B7C79,1DE3B1C16FE7ECDD,7E9A4F97CCF0E4AC,3B4571D27854BE6D,678B2286F2DFEE0F,00005ECFE66E9416,A6A2AC91AC47E5D0,70501B53B29BC0E6,13CADC7E9493BACF,B1706726279784C8,BC3E1238BEA39433,DBB61C0F8976617F,1DE25FD07738F776,E43C5A7DC18E7E30,EFDD03C254988D16,C0C7D1B1865AC041,55C982F7BC2C3BDF,000055CF27EC301A,D5AF0D570D1DD28B,25F7D4E5FF1A9918,01F1AC56860998B9,E67E32129FB496BB,0FD36048E791E45D,82D842327E5201F3,B804E5B9279F89BB,CED45B5D76424354,C1DB3F119EE20652,957350CA7DBB9FF7,507661D5B42B888E,0000295BA7C7E6CE,9382988F058C894A,9BD00506803CA00C,117991D50331C722,4AC40877CD50E8FB,E0DDECCFDB93CF49,D7C9E37B85C6BF66,EF134DDE78FE8F44,B9443BB16EB00962,A305379C026736EE,7FCDB0F25ECB0AFF,B74A08F49DD34B48,00000574E1F69C11,4F5E97AC91385E8C,246B1201B176E1C5,F12459595EDAE81D,CF88A468B2F97666,291DF7A5FDFF2217,C3FEFEC5BB1A523E,A5576E69EB2A9CE9,88C56DDCD933B71D,6DB2BFE5A64EB54F,29F2172BE2DF03AB,C344ADD5FBEBFB3B,000046660803BB1D,040536886AE9AEDE,6737EC36BB33C58B,B62982BF1AB88F7C,907DEA94B6D4F25E,C13F91807F579D81,98BC42B53A778FA5,61165A4CB1BDFD73,9EDD7138B6A4B048,82058E0F6F1E306C,92F987B2E9D2DA33,8BF011A68F2BF58C,00006E79F27CEA91,003BCDAAE7F062DD,CC8575212DD048DA,2DE178DD4E3AE691,489AB19DB7F36424,1CC9785B839E1B99,640EE35057FB9F10,5F4327632E218B99,4E6AD126A626F623,F37B0CB47A45294C,44CC65C150EFED9F,971E0F3211610FCD,00004FA4C4B1E66B,DC5D9483548C63BE,B814CF0757349A36,7E78FE406455CAEA,7E11311A42E01990,068FA5F926BA29AE,B08BF8068FE1137C,A1C8B50C5CBB33FD,F1A5113B0259C3F3,05CE0D0AFF25ACA8,4045B87F50E4C756,319497DB340A7260,000013934AF5320E,FF8D3F9D9F1DDBB4,8228EB717450C3D4,E2EE506BA49FF717,33F99835827445ED,09D7B10DEE36FA3F,2574D750ED0B90D6,0B12B15759EB3E59,7D45A63776521F56,5CFC1669357ADF25,2167C8F23A0D8FF1,4674D1A052ABE8D3,0000258D611A51D8,C010B70D9A49B026,E5793712B958E1AE,CC99F73C04D8F247,A5FDFB564D708E9D,658FF016F4436A3E,9C524A9B4788E661,BE1E1D09BE05FE28,9CD24A8E944A27DF,F9612A3EF0E9078A,B3377BA21A2A4D1B,4B19368F4EBC025C,0000506F4F494CD6,229F5FC968786C68,A5324D1B27675564,8446F8983263EDF7,C2C589587FB0A2B3,5D9D2F5660A2E546,E6246D35742D9251,F1F5614CB04E6E2C,83F3B36EB05803D7,5B926966C6BBD944,D3D01A2052E67CD5,E2D87738606220EB,000003D4A0877993,C1819DBE1F34EE42,1680E11970A12C9A,44A1B557954368F9,4273254EDF650B60,AA41817697554827,1843AB3317083965,30CCB854E8AC68A8,52E0C17D9F8E0245,777A8F8DF174B7AE,5518A34A8FB9E312,0E61FA5F20C434BD,00004CCCE5F9936C,3F126EA25565B5BA,2B3703C242733909,E61D9C93C2D5547E,B9233533E14EC4E8,F0949C41D2B0F00E,3BBC34D98A06E5E4,294F08EF1664AC8E,000AB9829302CA95,4452342B9B8CA943,2818672632AE843B,36725E831A086111,0000117DE69CCE56,490B708562FA1A6E,B5DFA8F0AE73A310,E2A329EEEF0B6AB7,8CCD4387405383A2,2CF500ACF0A1454A,951798AF833FA995,7FE4253284CA162D,6172CC727B423F76,868DF22C2E8B9330,4328F14B4CAFE50E,69C553C99BBE46D9,0000385B15C8AC72,1BCC7C49F4B7A7BA,CF57CCB317F8F022,6DA2F03C092DA5E9,973235DEF79F0577,A4C08847C730CF94,7EA9A16D17E073F9,15F8E1857B7EBFBD,4405EF06F4CE660B,28A9730055202573,5DC8E17778F34232,DA74B0A2E1FC6AA0,00004681CC06DB90,B47259B5467BA1F2,6BE440C337A2A7D2,36B55CE23CEBF85A,DA35BB591BB87259,D4723A960BF12114,A78E2E1A70326D7B,54ED36994A09817E,C3A204B8DE8701E2,8BA6A043FF259A7F,6061CC06F7EFDD17,3E99D121405980D3,000034E0179625CE,353B70B464CCF1F4,A60A3B56D9D8E66A,800351919094F5F0,64476B7351C55090,95CD2CC5FF8A66A2,4E07A148985D480F,2A69070C49881685,F7C94A092BE0770A,42DB226680B95937,3E718BC70D1F9701,4A5155BCF15F8828,00006BA8C3E4FBEA,7F44263E4D12D9C9,5948704EEE69E98A,36E0A3FC438D8AED,D6E56982FBB39BC7,8DE4D209D9CD573A,2C51524A7C7E5B65,CC3A11303B366418,438F83EADDFF4601,2FC7A6C7C3F906EA,C682ABC492BDDE93,4FD0E3E4FC4C2BF4,00004095B2A39F85,7B0A04952CB06679,0E0667DBF652D25F,D4ABD277F847E0D4,24FA83AD262F02FD,EBA2F394F680D7DF,C7011DD32ADC8D8F,AB81A179FCB870D0,C223C332122A303E,83319FA06E69FD75,D1429137DFC3BA5E,A719B921C00C825B,000065E62BEAEFA6,51417466159DD4D1,7791C6BF393B7288,BFA97DECA590AF28,41D9F039E2BFC209,0D24DCBAA94E730E,5D024A0A6F07DAFA,5EC6D012F10F0881,229B10F62D8406CE,02E38DA809592637,769A95C02317879B,B9CB4954E5398A78,00000BCDDDF80F72,D5F0CB1F0E0F9DEB,37EE5BC49CC13A09,162BE248849871A1,0F230B4C2A2B4DDA,949A7782FFD9DE20,6D74AF5B74F1B2B6,450F2C7B4627689D,2A141904574ADBEB,14D44B3128E86658,0B2F8C454FCA7E39,97050B16A9E2C83D,0000192ABE2032BD,1B2079D019BC9432,FF0CD3730FDD4252,67C15D679C86A397,B52BAF53A9834237,D4221DDD887F725B,B94BDD612BFDF732,E230963FFA8573A2,AD8997E26E043A4A,997281A050278AA8,9FF690D74F4613C7,1092247CFD6C7AE3,000062CA36984502,9AAAB2F2C926AEDA,D4DACD17FEE436D7,7EB78FA1EFB92FC1,89F528A3649B720C,DE7396D28350D3F8,7A5E42973ED617A9,33BD05746F881993,F7748239D290436F,B3B1B75644DDA06A,01B7056466F68919,5075BC4CAF582C16,00004C4EC585AA84,63F60A34B94FED56,678BF91F2F940C98,852F7B2CA7A2E72E,4162488E6FC72D76,93827B96E2E3B662,08ABF1FDAF85BA0D,067928BE1E7E22B0,A7F78488E2DE9EEA,0C112E5A1DC5BAF3,CFB36872B1A2B95D,C57A56C828C73644,00002CF57EDED814,8FDA4EA577AFAD67,1545C879C3758AB1,7715B08FD77326DF,549752FE1BB4AC10,91862981907E8AFB,357FC75C91E8A44E,1EABFBE16CA51609,61B95B1CB61DF1CF,144573C660D81837,21D39F03F2530C17,683BE786AECC46E5,000059FFE81211B4,FDA3908D619914F2,7722D8F368A150FB,F7DF58AF60D7E5DB,388CB92AA536B524,BE757C469EC82513,2D64D21D199BEAEC,CCB301B62E312D6B,5F4EA45ECC5B8E9E,788A68FB078F2413,0E9A5F09F13ADAF9,10E064DE7964B676,0000440F11E27E67,6041AC42CA542DC2,7178CB1C99B0D071,0D79261E858E73FA,564D2A4B50846B66,73D7F4D6F9E18901,BFFE0761424AFEB3,FBB796F786CFBB84,64259FB5318F080C,80CD411C575B4D21,CA56656A2EDB8FD0,ACB264A0977ED967,0000458D4BAE26F5,5A37F728B62E105A,53326FB0C5469270,216EEC605B42B96F,BBD9843D161CD5D6,4034413199753D9F,BC0DB834ED943B5D,EC2238B9EAF1658E,69A27940A30ED206,A1BC79D64ABD067F,34885D5E62A022C2,F4C72F26D7811EA4,00004BA27BBFCCC5,8AB27AC161738B2F,F1E6DB4B7B0728C2,43B0F05E0DCC6577,ABE171A15236C589,A778AE7BFF29643C,012CEDB23AE421E0,59C9D5CEAC370691,E9BF4FD3AAB4F0FC,844ACB9E6029C03F,39D4869DB5B7FEB5,03BAF62465B1FD36,0000602E80FBF04A,1F22CCB5A0958E5E,DB250434AA56091B,FE15879A961C36E0,770D37D06DBFBB74,AD77AAAB38F5D72A,6AE20C7CEA943B2F,F4E4811803374562,C01CFFAA970C2BA9,E340BEAD0A3D22A5,935A87F8140ACBE6,517250D03EAA5850,00002B8EE66AE2AB,EC34583C137B5B42,14929146E7A2ACB0,B84E94C331937D8C,191FBD89BD8FD408,75C26C43BA920EDD,AE00CC661BFC9CB6,813CBEA3BC81A6C7,23E2E1EE2C0B33DC,E533E8E9A7670CF5,F58801EBCECB18B9,438F207CEEAA037C,00005D961DC9C75A,C0D10C55681C1384,FE8BD8F01A557C90,C15F49EE6D009E2F,D71486A5D83C320E,08D06B44A378851C,D30CF6D3972B8880,08D587A16AD389B3,BE0A01BF827A8407,E6B9B2B9887E3FFF,44C056DED875AD67,ECF463A882F1671E,000057C91D1BDC20,FB7084167FCE6917,C559B2D8B4F89900,EF7778B0662BCB3E,5684A8EF5A6D6B6B,5B7E4532D4B583F4,455AF4C660EC7185,A4D3B085A34470A1,CBC83C5F633BEDE3,B85211DD04BC5506,4B87E6533CBB8F3D,AFD6AC0FCB9F978A,00002C9D0D0714BE,74ACD0DEA954D4CE,0FA0495C673D4916,6E44F6A841EA2BEE,3279DD609C7D79B9,0901C29C7E485131,D99FE521BE261511,B1F9760533D282CC,B0984BEC0D4A21A2,A7025648879F72C3,3F52B42BDFA9D687,1274E5FC5E57BC40,00004F6CA705B73F,8F835F5E31285D6E,854F9FA8303782FE,4250AE064E15C220,18ED140B08B3C58C,A35D051286582A35,3465B4B67904F397,701083BEA5418196,ABC13779FECA8D58,3730D9F0E3159248,3DCE6AC1217BE397,C21EE2B255463B1A,00001E59F30028A9,D11991150D2AFAFD,5A6FD6D5E193EB8E,ECC9CC978F04F5D3,F14908820860B444,E546532E736DEAA5,7E01C80D1B18F397,1ED477C59BB7D2B5,32BE7D9E33B4D4D8,20CD96EEFB9C8164,13B65599D6E0A18A,E86D5374F6A7B157,00005E41E1B225CC,A3512D9AC3FD0EC3,52E5FA5BD5F1DF1F,3AACD1FE4B99666D,61F9B7495FA9961C,230CAF64058AEB03,2E55DF92EC7D2BBE,4403BFC9BF89F7B5,14116614040AD2A9,F82A09B3BF5B06F9,F273A9F0C2F7F97E,B4078A177A9B48B6,0000418CC385C961,C6A835B4B0036B5B,6737CCF1E745FF39,38A997AF8D6F0CFF,3FF802877F568502,883669A4BABD552D,A786CDA749C828C8,C745291BB88E6FC8,F5F3F530CC665886,639977B3464A0933,6A08676C9BC7B4A9,9B755BCFDB7F2D39,000052F45E6505F2,D0874A979C5DDA7A,8DE8D287BDF4FC6B,00BCE5B9CB7D4DAD,5CDE4408A62BFD5B,91C94B2601F1F506,6361827032DB4D8E,BE08B6B672BEB692,448F6A79D5967F5D,31BB3317E9A541E1,C2C0E0FF1BDD2547,183A5906D029AFA2,000062B74176AAF2,67B586497AA0F1E8,12F0573DD3418B2D,566C3E2A1A09D2DD,2FD25559D0A42974,8C5C931F42482F7B,1DF89706D4557E73,75A6277A7B45BCE4,E34ACAC36F5F4459,81D727D06F45EBC5,E363F2143F2E128B,0C06867483A09AB2,000045F855D96968,82B1057BA0ED3E31,0C210F98AD8E36DF,EAC8B930E70ADAC8,BC8C37B7848AEE9D,64C0E161B890EB7B,ECE11E19BA607560,4939BB1A408DF8F8,D67C7C4ED25CF958,CF4E2C5D4970CCE1,D6450B8744970688,013F437137A24C6D,00000B498F7E0BA6,0C87B7D2EB733755,2540B249C17B6CE1,A4ADE5BC89A3B534,6D5C1A932A58CAB4,85A11E6971FB7548,85C7D10703F5611E,0460F7C91E7B4F52,41DE1DE04D12EA30,7BFC048D575550E5,8EBE71A9A4129DBB,C4CA7B0F3F5E84CC,00005E973137E9E8,87185B625B7E65BA,DE9830D02DF0BEC8,5A6B9919E065A7FA,185621F4F69DF072,A513FF6956448413,F7F0765D0D8D036E,E108A59DA5C7DC18,4693D0BF8DEC6BE4,2570AE92C1F0938A,E77C72F7AFC8D0F2,2E482250F657EE5E,00000F4920AD2790,AA7375215FEBDC11,0E0AFB44C523400A,8762CC68A098E86E,0F3D0E52AE7C5C6F,2F6DD97DB1126CAC,4F3FFB5CA0A195EE,B1E01B5A9CF50E83,435B729724426ED8,E95AF787EA410191,4FE0CD2258F3F762,407D1A5E7C86F4A7,000068BBD79EC773,3D8620D568A65581,C78E38738FC2E5F5,CB4931BBBE75DA13,3A56D6FC7DB2B85C,EF6554C4C98A4BF4,214615EAEA8A9100,E45D6AAC4BD697E1,D76C2083572252BB,49909CCFBAE7A402,F96D01BEADE30E76,34E290BCF896B3CB,00003E0BFF3D8240,E6DA67F12463B307,E658748E6AF3398F,E51D5557EC25ED06,B2274CD01A56B6B7,7A8E7C346D71F6A4,7420CA0B4081C5EC,EFE9A4241CBC740A,20E7A3DA590CC36D,BAA8EECC7B5EED5D,33EB48BFBBD2BDFA,C9F9FC113408CDFE,0000130743087936,ED664A23916B509F,71155D28BC6B2E58,20A242551FF4E4AB,71FE57D957365B87,1FB08040EB77A37D,0883B8999A48310A,D7FEAE7F1DCBD562,FFA707EC95BBF531,710E39AFC00E4DBC,5182DE776AEDAD5E,EEF207347E3A80B0,00002E788DCF9A23,A0FAB0DA84709B8B,511EA074D91F5610,E4E95417C5333212,CBFB0B8FA68AA663,45F20DA8C5E4BD64,9B20E6C9E90F0D8D,7B82F5245ED36629,6226522C3B13AB1D,D113793C2C24E455,BC141B7D56B134FB,82F853C6745A1BCD,0000012CAF47D540,ED0E88D24BDF1235,E3A32F7B51631221,6E8EC2B43FBCC7F1,6B60731AE87F3192,2632CA5EA4E297C9,B75576EA3A0344F8,7DE900F18895186C,C0C7CAA4FD33440C,933F399EA02174BC,270905A838D71BFA,0C49ADE7E141E9C4,000067311C9849D3,333728E7265CE154,284EB9F70E745822,3011D21C13AE7A40,C0FAB3DC592E3335,62116997F7684DA6,93ED3FF0CEDDDB80,04B5D57E3E2E39A6,7A30B190C2765BB4,C08B9FE39C6305E3,72F03D76D81545EC,9FD18A35FE463B0A,000015159A28FB30,F8D752D02F6EABF4,C2D99D8F4718B711,DCD49137E39FC059,5B6BA9C35A563701,613E08D07E66C5FA,E0BD2B9FF8A36670,6AC4EE473911000E,BFEA9F1A3BEB6526,40CBBD0F8511D745,915B320925F9FDA3,64A0E2E391ED66F0,00006448DEA3033D,474A329FAB105A57,AAE432A600DA11C0,558F6B0C59771245,E86A22CA078FB3F5,B72DC15420C994BC,0C8E34314B94FE2C,55F916FF5EFD16D1,461B04D4AE7F8465,EFD0A6DB37ECF448,2E7820A4E407D5F9,1B1D3FA7497CEF16,0000258BCB125B4F,BA8FC9661F1116BD,ADCB6B2F56831B52,BF5145D6063FD89B,DA05CBC90A1ACFAC,137620CFBAD64FF0,47A280D99CF89E2E,91C18557058F01E4,ECAEF385541432CE,C1B57F02667FFD90,A3A0489A92F71741,2EDA1F930C6947D1,00004EE04B884B80,DE19C100BEF434CB,46ABAF655B12CF56,B9CBDC978EAF4125,F4E9EA5FD0ED7626,A3C392342401FE7C,80E5045C22E89C2F,F2691D8A64DE00FF,703613E11747249A,058A3553000E474A,5E05084DF3E1D6BC,0E3EB74E87B1394E,0000092372F18873,DF44F790E4853C06,C454E366B5805C64,1D709EC03E2D5B90,61A4AF69881864D0,25C83DC19153397C,77DF8C25E6259DBB,4B36E0D26560CEC6,443EF8B4247B4D1F,40F4B87C8F5B7D31,BFB5775414685B0B,E5B9FF715422EC57,000041B430E44BCC,3889801EA327C019,19AA529B1C1F15E4,AA661443496F04EE,C4F51190224F4465,831CDD61B5CF93D9,DF07138F467D4985,5B1258F13583754A,5C401B4D8A04F077,C58FD45AD2A5EA3F,62336E85F40FD1A2,E026F6C0C627392B,00001673F2B9325F,4FB56474FADC8D4A,0741468E9543A254,40715BE40A7EAE17,7418C882350CEE77,D53F9B4A3CD488B1,69C7A2471EC99CDF,0CE4F3A86F70BDCA,4FA87A179936DBEB,37AF28582737EB97,021E637AE645831D,8060775997C692D9,000014B45D37ACE3,8F135CCBBD0A6554,4D06CAE032BDCD46,8EDE2D718775AC55,2241C564A17C5D37,72FEFF154091F3FE,FCFFE0E6315F885B,4A78843A3E47BD9A,883BD6BFB1FAA567,A6A051C33E167E72,0D8FDB60851F3CCE,96314CF61B63671B,00006B862B3E32E6,E65E8CB2A5EA3EDF,4A87BAC22D99E381,41254EBD7E5A4A90,F25A7D959A673779,DD8C19529016BDBD,053581E48CD04DA8,78974DDABBDCB304,EA67BA3A01182CB2,2B682EA70A2D6929,8AA0130096E06814,B20072D693EB97D2,00005B3652D2A336,81A87F482EBBF9AA,067721257994E59D,B562557A1EE6B971,BCEB2170727451C0,85F2FBC75740C24B,713FB3C7CAB1A448,1EC490B442951D66,CC76AA848E45604F,9AD2D4B8ADBF3501,210DF23217C5D4C3,FA54EFC5E89F8ED7,0000290E675B9F84,DE837800F7D27056,0AB894C143FFD590,BB7CAEC8A6398449,D545568D0DBF5774,26A83DC2C0C987A4,A565C2D3CB6C4123,A1164AF96BE09FB3,6D4DD4910F401515,C7B8EF8B613F3930,8C17274304E8D12B,661C128F15D20DC4,000038165A0524A3,459E738AEFCD150C,D71B0CF36B57C70D,808E68375B90AB55,B2AB36D221B45923,FD8C876B2F7395D3,EF6D69737351495D,4FB43BE410253EAC,0561325C0BE77D06,1AF42AE7525822E8,3C21DA705EAC8177,39330B2F0A30F701,0000495669FC55ED,E2A8B0DA4517B52E,B4A99954E9845843,E32C28F16C8A708A,C30CCD19D5FAF2F6,7A4B6C439162ECD1,4601FA31E810B251,B7F3D4A967716690,F4680DF20F246F28,B2E88EA34BDFFA18,2B33D19461CC470F,265BF3AE3C86B50C,00001FA10A8CAC77,9EB844D94D0E49FB,2330BFFEDED6C248,CAD7782AB7469D84,096AD79618569808,837767D2495E42B4,E688F8533987F681,96D957CF75A3BF23,0127EF2920739AE7,41038E4A3CDA5A8C,04C049993991D34C,C578FFF206AC899F,00004698C0387F45,61D87A33FB660E49,E3B6EE852B3D2A0C,71DABA480FBB8682,2D067FB0C6F478BC,D902172606CFD820,8160A554C7ACF56E,884769B253BCDA25,4E0FFCD2ED1E40AB,039B50109BBC2A34,3F7146F062C8C071,A1213D1C1439584D,000069FED6B213DB,D54AD0EE86683164,FE7630643C238421,161F29246A575FC4,0FE6E0484AE858FC,7B1F7325B2D7B819,0D82F2ED841566D2,525F64BCEF7B45B4,DFB99783FFC33922,14A227DA8E7A10FE,A9CD1F684B4D716B,4665ED13563F0247,00001C955256BA6B,871F08A1C4F115AD,B1BEA548FBCA6E0E,D2C78A3D96B6E755,9B3B1A6469A741D7,BEFB8D40427879CE,87F678A941E96892,CA01380E7DCBA2EA,5CFE481FBB81F776,2EC5F2828E65ADFE,F0E2ABE321F860AD,8E271A5C90D1B753,0000609A667CDA14,617099CA0B0B7413,AD49D96624D527E9,C24465E5BA354F3D,060B724ECD84198E,55A165AB120F652F,ED8AB2DA794C593A,18249F932788F6E2,544CA5456CC7232D,767AE50D623A72F1,5E15CC9097BEA23A,6908B248ADE50D96,00006926A3DE98B4,05D0F5F99AC8A91B,C11FA35FECF6E9B2,19BFE39EC0BA1D85,329BD838F796EC72,453E6465E7294F51,B157A4A745336E07,2EE03B187063EA97,AC43A45D9D76E385,195EC21B2259EF46,CDA74DA49291CD23,E818C08021AD1EE7,00006672F0D57B06,90490C51A505D071,B25FA2E85B9497D0,F649925888259462,6B55EEF5A619EA80,6A99C8189D763C6A,0F07528C1175C94E,5A306541BB2FCF44,4E50E1DC19410EAE,D9381CCF7C5EB8A2,EF1ECB779DD59AD7,6C0BC9624562A7BB,00000FC996F44217,5B39408E5B665FC4,2AB52850AAC79EBF,DDB72A6E849C7896,F2D3470386D32648,30A49B30F37BBD7D,40B86B79EF4C8EFE,BEA88532E0EE10BE,2E72B52550DE4ED9,EAADC75E1BC11EB9,A55DFF48A9FB699E,AB4E890587AEFC31,00000F098BCB0539,1E3A6D93F09B68C8,FE1E180E1D7AA3A6,829BAFEAB7023551,B8014DE5890EEC7E,EAD0A24F697CCC83,8CE9AFD48A275DA1,206A7D0FE4B21BB3,A8698249021C3CA1,763B137D229C432F,CF674B72E73363D5,0B09AFF9FB0A1F30,0000671E6B4A3F06,15BA1E2FE6A37ACD,2413E6423E7E2FAF,026DB2D15FD27F6E,2B3DD746F28B924A,D25A323E1E981AD2,DF825F375181CD43,FD0E7D7B26651A73,6D2486D1C62FB253,515A835FBFA3DFE6,67F8034016628A7F,E3B473638E946027,00005891D7FE15D2,122709ABDC406BCF,8EAFE2FBE9433037,AD25C0D63225F1B6,99FAB22E3DDB0F95,3DD45A9F80FF40C8,1A28F1D0656DEF46,DC079711F5D6C428,0E2BE76E3FC6A87A,A70AC73AE7F93389,3140CE4EFDBBDAF1,2812B8BD40DFE6EB,00001649DAC3B49A,000BE40C74DA2E4D,6E1BEF1B1495B14B,BD9E886F7982487C,0CC2B940E63F3672,61B66B409E52344C,219F9272E937F35F,38015F3E58503114,0290003402417553,45750DAB116261D1,B9A1E6ACA54965C3,918364AF01557A4C,000058D818E60F00,7C9F9E53C562A97D,4ECBA968FFB0E042,E4AA7308E06484AC,F354556DC69C9414,4919176805DAF58A,BD962CC9AA479CDD,434B933D9826929E,EB49253276F4AA90,3B67F28D2DE6150C,E2F54F2A7892BDF1,53E327C5F0D07ED8,0000660F152504AA,EF2CD4415451A9B8,7BAD49539743BF37,5DF237E928DC38E2,2AF36DE16B6B6BE0,CE10FD3E04BC6971,E1815CFFC7D4A74E,990E9ACDDD43F011,AEAA190195BC7690,B939A836BB679ED4,D87A189A6B7D805C,F0CCAEECFD07ECE9,0000334883A110D5,731F6F65C47AF5B1,6DDFA486D39A7221,53792C16B9FAB2F6,412ADD5AD6EDEBFC,A2BBB6D6ACD3E6DA,FF4AFCC72166DB64,5958765E3B06E8B8,9E1BCB327736F2B0,C54F60AB80A4A818,8E34C78A64E8AD62,0C33F286BDEF1189,00000C28575F432C,8291AA60D96818B2,A6621EAFC492CD70,5481014D3AD60621,6548E7B6C72A1230,82E495F5A786491B,3D4F20FF9AF91BDE,7BEFD9B19A5A64AD,02F394A27074A124,259EC182CBD0742A,381AD506FBE1FFE9,1E8DD8B4BC8DEA12,00003799C4DAD99D,CA3CA7737147F67B,1AE19CBD3B89506A,723EC28A11AC9115,70B322FCF4BFFC66,E870215D5937C416,94E72E2908D15A06,D303233DB89BE156,A32400CFDDAAA178,5ECBCCC4873FF4E1,D87F4E1926DF8134,4AAEE53C51054FE3,000041E072351C5A,8EEA7A1AD1B55C51,C809C2088F2D964C,B39D38DB10043CFC,1E609B33238A085B,2DBA22A40A81E3C5,5B629B54E4832792,ACC65619F2B9297E,48B15D98D1224082,7CFE378B34B6797C,BF266ADA79166002,6F653A842507C776,0000216848435E97,305392A3314E1620,0BFC4BF84E3DE920,AD91420A93B34FF0,5D2F64A234762115,D70D55A4FD45DB0A,A627253FF4FE5908,5DDF658AE8AD355D,DCD4D20E7BE46A23,636839D961D7F05C,79CC794CC06F5945,4A5F776278347E76,00005EA74C718B68,758820A04BCBD9E9,36D230158BBD2961,255C7AC44B3A53AD,B54C3E68E5C37E0D,762EB8344E45DD6E,2969DAEBBF242204,9144431BB4C281BA,7D8CE3C6842FBE59,DF6FB4C2B9B5A715,01CD4241FC06ACB1,C4A570B2CCC5D5D9,000064584FD5A6A7,06CFF4B5D4E44DE3,408002EF950EC856,8F7D4B47F0E53078,3524A4FC3623155A,C39A3134AE6EAB9E,2F1F1A2716AE8495,5D1F56BE74271446,C7A26C20CCCF1D9C,018098622F88306F,40859C5A434145BA,D0A7DB58D13C5FA8,000041B4A03A210A,BABDFCD2F71E3115,F79E890F9585A7CA,C52F8EC476B5A103,0EBC73A07177C183,72474B8BF0FEBED9,8056C6DC99362966,AD1498F36F7FD1B1,2B9A7995FE9D94AF,C11EE9665FC8BE98,E74D7FA65D89D192,1147024901A50FA6,00000F5104E596C5,91F37509286B77E9,C55D2ED1EDFC907C,C0BDC1682F83E883,7B0383CE2288FA92,D698E4D0B8405A51,48235A3343F603D7,6B7A8C314E24518A,C40A79138F5C0AE7,77BD43167AA32472,AA6AE5788DE63680,00E9EEFDDC36B18B,000056AD28902386,3B72C84696324A9A,0EBBCE2B2F2415FD,9DC66C02D45C3FF0,F8AF539DC41D10D1,A3794DC37992BAD4,341DF48559A8437B,4E39365B816402F8,39B95505952229AC,90C3DD5A68BD6DB0,9A5DEA5098C49D2E,E6DAFF181E71EEA1,0000463250D459FE,6DA2026960AD149D,7690709F7A940EDC,68439C56EB4135CF,06B86BDBD9A1CFC9,274F2B01935874AC,2A29E195F7ACB62E,64EB959D5D24F078,5DB89EBE89B9C56F,E1A60014417F9514,F217296DE9A2A8E6,35BFA9509E6D3323,000061CEB164F8CC,95875EAACBF51EC6,D1D87489821BD135,57F20DD0B3488BB9,653FAF28AEDE6055,C54458F17FDF29A9,F050674D5BF22F15,471E1C589AED8D8F,8D54707A7F29B6CE,C2FF025835DE7EE1,C217C30099581F93,B164A3F68E5D8ED9,0000547D449F04AF,5C35912D9BB56963,F287075CF039ED20,C15FC1976E63C52F,89C354434753AD1C,0AD625A22E223B5B,338182FA8A68C7B2,11C9748B6155C234,CE076F162F151D38,A650EEEFF9307E37,76628A357848A4DF,F888C97577DC1D20,0000572F4C425AC0,724EDCCF6E418969,FFF3049E9547EDAC,CDAACEFB3F174C5C,C5FA8AECE396A5D5,20EF1F2838EA4FF2,6E5E4B0A31185D09,63DF54347AE3CC89,BB87BF106C4BE285,9B57090CA0D8EA47,58F5C5708F314DBB,CC83DE60B97E4B7E,00002B90DEFF301D,214E6711C51EA938,348CB2EBACBB1A2E,A102A373C74DB85C,5BEA8FCD6FDE02B9,A6177740B3F2564A,8D5A57A7AB88332D,450DCF418CEBF27C,DF01D78AE0D9D09C,B43418CC46965B7D,2B561DEBDB9843C5,BFBBDFE832A061FC,0000680B0B6A1699,0A76FD8F62E9E95D,B1ACA9C76DBDEE84,6A93C2C8D57A232A,EB958C245A805D03,59C5FED85E831702,FFB3A0F74D7DADC4,7ACF625F63217651,35E1456658E011C3,3EC9652172DC6AA5,317D30B70AB94919,4EB202D27F146706,000054F4B461E7CA,7956CC7CC41F5FBD,3F8093D24179A8B2,159E30B134446546,F9B7ACC50F9FA439,5BE5FEA029EFFC8A,6BD857E79225F1C2,3553B4BEF3D8B24D,F4E5A9FAB7D55B9F,EB5EFB19802F8798,4FFF756571B72B47,2DC6B4648802BC93,00000EB24D37104A,F46CD81EE9E9DA10,BC0CA28CDB22B66F,618BF4F2452A2D73,2995D07FC59A907A,8F3242C5926E0422,6ED5E0A1E0028A8A,7A9866AA2BA50CE0,6CA8E15E8D4BDAA4,B6B03269376F8740,2C5982E790698B61,42FF915F93A92C38,0000484AAAEFB0B8,D32B97D0E700575B,F708B642C01BE5D1,D023CA5342044003,0D1109271FE077FE,652F8DB7F0DB42F9,1FE8AF8B53FC7547,FF1C60B4E40A57EF,CD340A23612C3803,A55B4444FA80E35B,7C6C73BF4B655431,8CE4AB63D4CC051E,0000399F4246DC4A,6982692DD60CF768,1E5B852B0252E408,C321628D716897F1,D89E50660C19DC78,29236BCF9B6059C2,CF13258259DE0A61,74A1BF983B9A068A,1C9D2A0299B9E024,25F53E9F59DAB4B4,2368D4B134622F1E,79B0549C277A74EC,000008D97495971F,BC05DF91E5282BEC,01AE043A882EFF20,817940A96FB411B9,C1F9E5AB2804401C,0025F1ECA97EAEE0,680320C06E571588,8A09B2DBD7774490,246BB1D9020D5A40,DCD14CADA604F401,E50E3FDB1D7A8A90,BAF759A01C540C1F,00003609F3A50416,CAB9EDE2257BA4C6,F38977492CE0A542,612199B9FEADD6F7,576A067028D538E5,342B8CC9D1813298,8CBCEF2210379462,E4BC8D4A70148133,0A8D1AC043E3F314,A466600816FC8ECC,6F310A61C2336E17,37EAE07035035D0E,00002E5B9F967796,F47E3E1F44209CDE,33B807CD69814BAC,A2AB3F6B5C67CF30,FB999C253A4C45B8,FE3A44A26C5CE1C8,89B420C6C488CE6F,970A77FB17CB2EFB,3146AE477EB638EA,0FAE45EFAEE89CA5,FD1FA7E6CBF44590,D5BD5A21CF53A50F,000025B3EC2DA6BC,49A1A1B912977815,E606AED9D2B6B9FD,36AB070AAB76F52D,ADA67CBAE4E5C8B1,BBBE4696719E72F1,AB4D826641B463B6,C78A64E597FBC259,CC0E6B9008A27AD4,C8775A0D152580E3,0A6A2D98DCE11A42,125485B0525795EF,00000EFD34591FE5,0616683C10655ACE,5EA201B0D90403D8,53A24D65E5EF30C1,661D7269A222C17F,13DDCDC7179C0F3D,82F5BEE1AD9403C6,9CA9EF2297C9D966,E50F33FA29FD32F9,0113C7FBE39964A0,BE01EA4172E64ED6,FB117EAF54D2F16F,000000F88FF42CD4,CCF83AD5280F00AE,C74C48C5FBB3194D,691833C7AF5B04F3,634146223456AADB,E764966B22F3E101,E29570138C4A543A,8A42A4FE74DED47B,A46D3FF43285E954,0479DCB68E744E71,DB34B301918EF411,D9008E7D2816BCD3,000046962062054E,45F0304098D32B42,2E7F195F6C8F47AD,2D3E4916CFD12B0B,E572034B5FEA2B5D,3DFCD85A02FE9B0F,DB960C3528D450E7,FF9FEAE4CD9D7015,80FD80794F644137,4E3EC1880FBB09E6,AC6EE4EDE376EA64,62AF7BD36A2ED4D5,00001870119E768B,B8299CD171234030,0F97D138DB1B0E21,A1F0DED9CEEF46D5,F2B9055C6F989B47,A3DF68E689D9A8EA,2A8503CEB6C5D31D,8C1288CB538C51CF,0D68991DBE7BCE47,94EE3B733A81EB80,5AFD5A7BEB4CB0A4,E36D653E93CC856F,00001F6D2C1A34B0,03D410FF4AA4971B,48BAD23F07C8B510,B1144C57A701741F,02688BFF0502014A,E2DB80B20524ABE5,41D83215D28FB2CF,1655FC22753CE0A2,0F72B1AF60B3B487,274277C68C350E5C,3291BE924AF2A278,FEC65FF0A70F976E,000069FEC02FE720,0835E71BA34B2150,0B43A3811EF3017A,6A19A6A54D104C15,94FB352FDDA14454,AAAB25D5F830E2C0,0D08685AA421398D,A07967FFC73C7FD3,8F5F2BA5B3CE9614,E9B09ED9236D397A,A3CB030A6CF73741,2CA745BACF4819E8,0000587C2A65E7AD,786918AA676413E8,27616C59DFA6A97E,30F2CF96455864D3,3EC61CA00995B509,CB4A07E41D8CEF79,B0ED48653B151A58,3247D24B6C25A955,C009297364A568CC,D523A644A0F5CD2B,23F3395019DF128F,FD87BBD19CA6A2F0,000024BB34B1EDA6,21B5B55FB64EBD49,75988D003637E8F2,25FF7B15062A7D04,99531C610CFB6140,7D6E660CF38E4FD6,B905B99F4915A9CE,D81DCABF1A5EF080,6BBC4F2765CA53CD,4F6B94B893970396,A750ABCD40081D1B,6BDBED8C29A2AFA6,00003EB9D0F8BD16,DC68FBD7187FB3C4,6CCE63A43F16269E,AFE78232D71FFCD7,E1135B8A99EB8D4A,9EB88FA62CF17674,ACA33048DF0FF373,D380F65C6CA4CC45,D690B46309946B30,ECB9C5ECC926F91D,03CAAB3249A614BD,6EAF7CE054F7D3F4,0000049FA0180E5C,83A4C16C1B9153B3,BD2BEFCAFD940756,DFBABB0973B07D6E,3D1FE6CAFF2AFE23,80DE1E048B3FF40B,DAB4DECA8E63391B,20B189664F2924FD,5B699E8FAB99AA28,9664CA32B3335969,ED2710667F8B1870,0E1844FF6280E036,00006329DCA1CFBB,FD6CD3E3C09E9FF3,07ADF36356587358,DDDF415727E64988,9A42902B18F4E85B,FD0B58080D0EA740,11A35309FE6CC70C,2FC0DCD5271E58C4,EA8DF49B74E43A5A,003FE1590179613A,62385B02B013E424,05342FC117F6894E,00002C79CC1F6F15,8BAB055B660C0FCD,4419EC09CCA84A12,1889923E513397A2,9FA262D468894C6F,ED797D5242AAAA67,66E98AD21951D402,3558259FAE08B463,F7FB00306190CDA0,4D2D3BEE798DA0FC,0A3E623D9BCCC255,877941BF2105AF4A,0000658BEFF008FD,20ADDB554DD071E9,375B47A23D770D99,9E37F51600134710,F0DFDC79BA81DD92,40ACD33354E7AB24,AD90415DCC092046,DB9DD1980BB9CE15,7BD82017F43F5902,B6AEDA5C6F5F3439,2E4E5B2962C3C502,D55572E17769104A,00000A40EFE902D2,0A6AC692171A471D,B3CA645B1A4EC6D5,741B0722C8C0EFAF,9FEB929E886676CA,F686F20B0E730D45,669FEB6889CC70E2,CD3BB786937ADB89,F8EFC3CC6D963562,DA5973F61266DD21,AE32EC4E92D86EDD,5D80F5C926BB82E8,0000141CD3DEF5F1,E5D8B8758CFC8DA6,D39A1DD8B6AB925D,1084602A1D6D90B3,7B69FEC8723DA620,CBA47E419C32F09F,8A3A0B09E40B2869,3F126AC298BA09C4,008306FCA872AFA4,E8C962F4462D3DAA,218F64E22770803F,D788E29A9D50E316,000064D299738805,780AE7CE2A0D61F0,B30C6874CAD94AC1,B525A74FBB354873,2DB1DF3BF5F6A31A,EB50C2C951CE053C,B7A39B3BACDF7797,D8E49C40556C34C5,77B26845CFD891B8,9FD8C89FD26FD9F0,893B7393C9875B55,6D7143A3CCF82642,000066FFAE71956E,7F0F766B6594F7D0,3B0646025722EF85,6A1271B156EB995D,0C0F3D0C6250D428,BCB660733A1AD680,0323DE4972F09021,3713480A9F08DA38,EA6D6CA02454755B,54C167E43618E4D0,547FB03254092EF5,7701E59A5AB16729,00004D3C623C28BA,E82948A9951FEADE,D0A65F44817A4C2F,8780B1B9778ED34F,9C1080DC2146BFA4,CFF12A59F9B69510,81A294A8493BD412,595FE5392FA0CE0F,A8D275B312504DE5,F01A296BB87B08FC,451CEBDC3D92BD0F,CA11D9FA00F70399,0000362DE079B88C,45F79902F143C914,ACA81C0CA8FA8F82,5A47E186B792D257,EC1F867BE3646873,9AD16412F98DB0C3,D808DD1827FE7A91,3269D0F23B6EC26D,ED16B0FB212CCB17,0594C65EDCD9B77F,245ABA28B49D7B54,8D72881DE4379F8B,00004D6DDD4A247D,EEEA4A11BF7E67E4,FBDAA4E028DAE25C,D30218A26BFB7705,B788F7521AB0F66B,498E1CC6D8978F3A,9624425702622525,2CF044EB25E0F312,0AFC898597DC5E0A,643EB26B25758B5E,AE93B95FB06D8991,551DD56885830A20,00000E309540499B,447B348F44073171,0BC72A24D872F400,5BC9E5490DAC45F0,2FAE00A88B0A8AD2,36CA8AAE0CF68901,1E47623533D4A477,3B925E8B9E26D38C,1D8DBB210F6754ED,988C8673EBAAEDA3,F31EA149977F70DB,0D7FBCC202915837,000015C4A95CC9AC,813B0C90E920B895,8C14D4E4972E0749,B8948D5ED8FCE829,34070A72F6A01C27,38C93EDD51E2AEE6,3CB04DB47B7085AF,170766974808CBA7,6A4B1EFC0C52B398,555DD33A80029021,AF1035B84367F3C8,1E055AD92C451F52,000047F54FA1A977,6F7280D0C210A6FF,E71742505E4F49AF,C465A180A8F6920B,9E89A4F2B271AEBC,2FACEB8D88BA6068,F8D37686358E5D97,50C0F9FD9F0420F3,BF82362621401BD6,141FD6311332A85A,1BD0F251C90C8B4E,36D4A1C888C62DC6,000060B7F2C161EB,9852349BB322499A,5EB3329A35068898,51BF60F16F42A6F9,028B80F9824DFB6B,94CD7036C7EE72C2,4C03861AB1335695,67E3D968436E6AF9,780680EA1D91D1AE,0ABA5D3CF8D901D8,4BED541CD97E69A8,791D3881D0202842,000011856D552D7A,70B73436380B6572,DE946AA36FA85EFC,DB103A906955A6E6,B23417586DE65E2B,F3C6AFBC31EDEC55,670454141342FDA4,7D21E9EE4FFF1968,2D879D6EC6FE2A82,55B247A701F84BA5,6D9853456F7E0201,BA384FCAF8C4ED7C,00005F4E6801A206,C41F613019E83C1F,20F089D14C793AF6,26E0A12D371E5276,56917A95EE46B44F,3CBC97CD8786C49F,171BF9D481C97360,FB6D455BA64DADBB,B1EC3D20666A45DD,212E30DD1F796C57,4BD1B3B037ADC84C,0D78AA2CB406C27C,00003FA97D803C90,87BE994C5263E337,735F8785071EE609,6A35CEF675457F10,C7E7A5AE38833248,E17981A02EEA3583,03E7BCAAD96EAF1D,9666634342E3EE47,AC9BE5E56804356D,38788129405A6797,592E54225676C046,E152C95B7A07192E,000020A983632091,B8A6B11B2239C405,567AE2971C9D7A77,42D87E8743B33050,CA66CD2045263079,989D444701D5A31D,EAA7C02D1F4AC8FC,C62BE6182D85CAE4,04805B1A1F15831E,8CA8755183EC01A4,CC01235E4A41B327,D73334092F2713D5,00002A5DAF806E97,D35D89AAA4D2810E,2295ADD5C1056B0C,466ABDC6D1A23241,CD3C9E2AC2F218B3,991AF19BC5DE3FE5,4D32782F6E5B1476,EA9B59DD1285E6FA,9C5FC1CF031654FC,7046D187A3EFFE7F,A9C23409CF0C4156,86F396F33E3CCE26,00004B9EDD537745,406752AAE8D30946,0D87D9001AD82070,FBC5F3B0588CD2C7,80BDFD3C2C56122F,51486062749CB7DA,343BC5BEFE070128,0A599AAC6ECE6564,9A585964C295CCF1,8E92F7DE5A13ABFE,1B662131E326F295,93B1E755BFC34ADB,0000490067B219C1,0DF9254A4A0D73F2,BAD82722EFAFF717,3BA3192BA2E855D1,8A3CFC025794581D,4167D91872C86E36,1173E637A0759B82,DE259CC96C4FF12F,BD60D9846E13A6B9,51CB186A437EE7F3,04374C612ACDFDAC,143A0600E5AEE976,00000ED1D33192B8,BDDBC2F8A739B55D,3C9EC5980007DE42,B0A18219D11753E6,2086EBC6EBB387F0,8C0BAD7C50CA0A45,1AA293B1CC961F23,1D8789EF3CDE3C0D,A13C383C449B4FBE,0C9B93D7188059A7,9B6390448CEC46A8,ED16747D38282F62,000004AC378207F4,F97EDF631EC53F09,298F98B28A9F11A2,F1D75BF458A75DC4,3C2B709B87DFBB05,E0712F9F3A4A8B0D,AF8863DD854F013A,AEED77804405CAB6,4B9DB3ABC3C4821B,0C2254D1F82E91D2,2CF8F9469F8618C9,AEE344D18C6F7B92,000000928EC28E8A,BD01E0DEB79A8236,82F450652ECD5008,3DDB71FC3AC09458,8A17A348D68B08F3,3D0215CA1CF6E6CE,583531C4A85C655E,B227EDDA79E3C6C1,768C3D71DBC08AC4,FB7D8BDB44F9A700,0EEAD7F0DC684531,5C59EFFB22EC2E0C,00002829255C6143,0045A104146E1BD6,A1762C927C398792,85ED8F1D46229D9E,1F6731B9DB72B158,0D079F28F098401E,E21CC6ED65430FBF,91A5A7BC1E379745,A3F990AA683BDBC5,F90CA4FFD56C2EE4,94B9D17DEE11C6E6,67CC042B6E66A9D0,000049A68DF8F223,239B3F92F0C3442A,9652B8EF71918DD4,5BD650BE8850AE63,297A333D6846E3FE,942F2CD613D71666,4A15958532A7772D,4A2E418251E54ED0,7822595B81D3FB0C,9E1F38DDF9212BE6,DE23FFDAB7467933,824BBC26ECC48F9D,000019CAE27C10BE,B4FA5AF447B82398,EEA606A3012832B1,C5B34585ED5D6008,DC961F22A9820DF3,1DC26B9DF445537F,E778525090411359,8D210E58A59F4913,5F06B0AA9CDC882B,0AEE769E9EF5C9B3,D50837330651C561,A1B192220C01C416,00003938DE189421,078DD140AFA77178,6A1D6366A3F8F1F6,4661B83215E21687,36CAB9BC75C8B940,83D93792FB3F0085,C02E1E1AAB2FBF22,05C9E798AB992DDD,89BE5009BB3E5059,DD4FF720E483C99F,95F54E7BC5D0B482,5052E1CE03F661D5,00002DD941A21458,100D9F00FEA96710,7AE0E730F200A92E,A6FBC9D79D873414,B1ABB5E3EB1BE8C9,CAF89E1F18E9645B,1C682E5987E1B47A,1ACB8F577F51D065,9BCCE0244E6A1DD1,0A622988CC927ED6,5EBC4CB23B8FC29C,9BAA827C63C2CE69,00003F4E9471F663,C9A307AF8E5B1F64,E20362E95B3CE08C,44FF6D0C188E5E77,838F8DFB095FB898,EB76FC0B13ADDBA8,EEFA3A5191B37A7C,2342D93253DAE5F1,8C1B5ADE44F81026,D0419C922A9CAC09,A7B40980FC1C8266,6F294D7E56B1F0EA,00004453DC2E6A89,1D361A0E0F05BDF6,7E9F14E9F16EDA5A,751093341D68ACB1,2FDA21E9DCB502ED,7C4D26BB995333C2,61A8255A17220D3E,9D77FEAED018D028,117E07A77F89AFE6,1110C190BF50DB1A,03E21BAF53FEB01F,AC0465E5006D1F7F,000014108E528114,C841091328BEAD8B,6632A12FAD5CFC5F,8BF74AF7D619D35B,C882BDF26CB664F6,58B46B8EABA95B41,4725108E5602107C,3E496C4321CFEAB4,F61461B074E46037,8FC4FCB3E64BCE39,D5C6243B9F5BAF4E,9B28B42D000BED6C,0000597F4A787069,19FBFCBA9D00205A,84F83838D38A955D,4494A20E148D9EFC,1ED39904F7FBFF6A,7AD8FC371C37D4B6,FF88D6F24FC7AA20,E45775C58339DED3,B2B588A4DA9D43F8,1A8A388A9D7F2171,0E8AEEF6E5085ACC,4D650D145B59F7C6,00006ACA601B8388,6ECEA16670C6AAE5,520D2A26CD7D9F69,A7F55CF0AC1421A2,221EC4D1FF69684C,EDF3D9512DDDDF12,D33D1D0A9D0EAE98,ADCA7B088BE30F3A,1B42FDE793674CE1,21FFDD31F7BB5DFE,75979D5392A147A6,81E51DB30B4EF0B7,0000314FB91DA831,ABC1808F7BBB76A4,BFB4FAA27BEB9B4A,C04B61AC3F6420E1,504D22999D8D72E7,FCBC07A5B35215AE,DDD43158151EB900,DD197639182D2BD5,5E2C3BD3C19C0BB1,05369D4CD13685F9,FD71960A2A125762,909E1934475D5DE7,000063144956840D,4B5C51F80F41637D,90A1F9532B0875B8,EE18B737907D88B7,29BDD1424A652E9C,5EFC35C38C8E1308,8245F428687482D6,29093D8612E3A832,1FAB5A46862D9EB0,173EA058EEE234E7,A0463D05190E977B,7693F47CAA446807,0000252308E5F57E,54BDAFBE9CE47EF4,795C92DB39DD4E2B,0BEE721E38A15124,2BDA2A250A00641A,DABD36864E00E183,3085693393EB31C9,DE0968916C51C0B8,F0B8638D78E0D478,005BF7C311391E22,06CD469FEBD74E48,796F146FB2BD7408,0000531F021D814C,EA250B2B726C2612,C7B5EB1240074141,BBADAC27E581759F,EEB88202A3834089,4C182DAEA403FAD2,9723BA1CE40706C2,14F07E36C07AB7A5,4DB48EFE55787FE2,E6F09896630EA44D,EB0376384F678285,7FC910491EB796B3,0000475DD415F0B3,45609DB7860CFA8A,B89B422CE1C4FE14,2710C89A3F7B95C5,C93B4B9768E419AD,D7558F8F258535ED,75625BC58D0F5886,87C47B0499F825E5,CF80679CFBA67886,F2A696C89CA430EE,33B02FACD5286C6A,DF64017EB4C496E9,00003322FD15F94D,E4D5A3DCD60D0BD0,E16BF61985E41AB6,7F2F158A8E838096,281CCAB6A9474623,C68649B230139A09,5F5F1608E36DDDE3,ECCC95EA0C62D685,8B5F2C1D998E45D6,89D98D6E4A2C796C,68CB764389073CDF,5431BFE43411339E,0000235AFA2C42B3,278F833DC9D2C6FA,97DADC433CDD75F6,5D55D08E62DFE651,3F7A502A25161325,CEBF048CAD2172F8,B4F5CA8AFEF8CE47,44D7F094E3B6E87B,BBB0B0A944B72B29,38C1A6E8605E69F2,954EC88743CB7E6C,A8026601300FDA90,00002FF7D52EFE98,26A1DECE048CD4A9,90DE7162CAF1A799,EFCD28884B5051E4,BABEAAAE7AD2DB8F,50285EB94FDE96EC,E165DD367361AD7C,8472BA2E66DA968B,055BC15437979603,0B85E84BD72D8CBF,4C0090D152A1FFA0,92D93301CFB8D295,000066CBF1595C7E,FE89A5A06D09BD3F,2D24D3DCEDD0BE17,6CB37C5070E36EE9,E588C08A0124D3E8,380FF2D67ED30530,CB62FF8AEDF1D560,FD78B8A95711A4C3,70DAE2518B9C8B7D,522EC3C6198030ED,B48ABB1C170932F1,F6CBDF67DB777255,000025489E82DA68,C03D1020AA1CFC3C,AF9297BE28E929E2,1CCD6B18D74C38A5,A9EA40FC918EF072,CA883AFAFDA5E76C,EE64895DEAA6D6FF,A2320E0CCDF1FA81,9A2F98F8DB7B3DFE,5B2FD9577999EBC7,AD3898B6E945840E,876F40CD49E4A375,00000C2A2A21B5F5,978605527C2E6EC2,77D8D9D29932903D,FDEFE33C4A5E3E08,4079E8048F7E1B06,46B5DA478CB8EE58,57D39A8B74CF9D74,D0B6F310099E8C40,340DC13AEC744A75,9EB03282D31F7660,AC33EC6956F2EBFA,B856AA519AFB9A87,0000066C28BBE931,3C7BC1F193A04001,2DBDB017D6C95683,205F9AE4AAEA33BC,3B4E94953C040669,5A6A1E1F3C4B7390,D28A9E9E28F4073A,A13E5C2547223010,9B83662761463413,8331D51A2095B95C,A628166CF66B1585,2DB686F24DB3713B,000025D18412D76F,8E1B23959BF4D365,5BDD90064DE63388,FEC2BCEE54F46AFD,7560A576C489311A,D2D3E4FAEC1CAC68,83BECDBCA588546A,2ADD2628D16FED63,271ABD0952C0983B,8DF140BA2C065439,5DD09A3010BD7DF0,751D6D8218530A14,00006655B74A8007,9BB9B4F70E04FF94,2C17A4B84A4BB7EF,2A93F1013DEC399B,9AA245874A6B528C,F19A064C6A9F2C3B,6BC99E1033B00422,7288B6FF267A2EFB,601BA401395B0389,98E9D3D731948A36,03686E3B83CB7348,9FD69BB7CDB7E55F,000015FE6A87C96C,86999786880E3D23,248B7528263A16B8,29AAD33A8884643F,AE442622D1BD931D,BA321C7CD826537E,8E3CD8D919012063,4CA0641E0D25372D,94F7983AE16F161D,B4B1EC4E7BD5FE63,B05A8BB55F429312,8F85903337376A94,00005DC4950B4F00,061C5571F1ED6C86,85603562CBA5714E,FA81E6663B762C45,13D659D8E1563F60,19166D1CA44025C8,D2AC22AEF1EB0775,E033C79D32DF2E80,2555DCA16001086F,03A15C7431EE6F8C,7843F884332ACC1D,109C940E28E67FEC,00005BB503866625,F8CA8DEDA0C75942,4AE907674AC360EF,0A0A604C56655EFC,61C12F613915A005,5E57C86B503137CC,6A9663CCEF2E16AF,86C0BA7D6A1FC4F5,A3723C58922A4404,4B8664DB8A696442,0E3554F017500BAB,F130C1783032A6A8,000035C1743D9741,8FDAFA6014EE4B3F,0F6E5404014BD7DE,B3E9A072EB18B1EE,1EC6537C6C15243B,62B20A20CA3C118E,3BE9F6B0D4BE2E46,0CBB9C765DACC849,94E6C9AE7DC2720A,195D5E12D0FC852A,361B9A69D660071D,E571C8375A1C3FE0,000006CA4EC9CECC,003A6BB691745230,47A47386EDBF41BC,238D0D86001378A8,5A829A6C39BC050D,D7A2482BE6F64EEF,65FD34D710F88D29,B10051D632E4EE1D,A679CDB6F96DF821,88772BE75CB6F808,2615F4B452EFF561,0C413B8BE6527376,00005D876F3AD42C,CBA13C89B1B0E215,744EE21A70696D43,9534BEF3720AE242,7C61BA99F1F1070C,B6D2F26BD7F32017,BB4314A486DCA7B3,79EBE930BFE62AD2,3CD39A296AE4223E,5311F39069EA6F39,48DF7CA39B68E46A,11B909E4977C89A2,00004AC2A3A24098,2383968D9315553E,D46D05C57E48E698,F10E4BB37112566D,D2A69542720B5675,9A165EAB58CC8689,CDF6471D4A10BE45,A2A753EAD15C9032,ACD804C98703706E,AEF0AE4CD515A1E6,699964DE72DD62C7,214DA8236ACBE56E,00006FB3714F3B7B,B5F5E7315C79048E,E838690B7F5058A2,2A0D3CF711D8CA47,6F950C3EA5B20A9C,F40747056A1E31D4,41A4762E19475C91,E96443B0F10FF911,774F9E38F62A0D5B,8624C5E6EA2135A8,C6CD1872A38F062C,DD0D692815BFC685,0000594CEF6545CC,43AAE3FCCAE26E9B,D8A4DCD2109FE0B8,5B1801DBE09A90BD,461F2635AC903570,9B7FE53D3044A4BB,D0F2D342C48A9AA4,268DA10A96EA184F,6DC9451D2F3CADF9,611E05A122FC1326,409BA5523158C514,3D4EB81AB9048023,00002562DA6965C4,E08D0AAB19CBE09B,66C38D645B381EFA,3E10AB687937E0EB,1E9C8A15CF99D4A7,9DCF999B83DED203,AB2492CF3BF3B93F,DE6B6444F6507E05,A5A7A5E11DD56745,CBA333A1E7F86035,B89D51BC8119F368,36869BA43BFF5863,0000205BD6C539D8,A37012D26672DBCA,05AA8E395B58953C,AFE73B55366C4C55,7D03133EDA59C596,3E3EE2DD682AEC1D,CC8D9CAB6E7459E2,D569DB95B984869F,BD38DA8AE75B92A6,73D8160E006A7421,A121A8CFFB5DFA22,54FD5A0C99D7FFF5,00002B439C910B7E,F55B1E497211482C,943C3F1571FBB30A,2AD8E8463F3E6C75,0DA7B0E891A39DDF,741F7358F788D4FC,DF11DFD66024E5BF,7CC5325255BB2BB2,309B6763E7AA788B,C7DF42C5DC21E981,FE98CF426DD310D3,45095DD7EC6C3331,00006D585A34E77B,3EB2EA1ADDB48183,3456B376B4B1B4BF,B8A1E70E15391CBA,796BE397B29FD18D,E207F4D1E5B11867,B526E00B1E43351D,B5AD9234AD3E7E53,92E96E3F60F42BCA,712190063D2D363D,E3AF15C03C0ED255,3182CAECB4E86D75,000019ADFE105CBB,65B771D6508B1B65,288DCFE05020145E,14E6F87C85334F57,69DDCF527E6381AE,54697C3B4B711F2D,119CB9DA526712BD,10269CDE71D8674E,7A5C08F917128343,BB2C7874BB19AC24,7418C75FDEE1E735,E70204350659F50D,0000465428466FFF,6906E3C59873D19E,B2AB07FB40B4B1A0,6660160BCC9641EA,B90824858766679E,29F31261D929A645,C0AE053F6BDA6233,077CBBB38A39C43D,8CFE8F2D8F9AAB92,FE087E66CB263420,754FAA496B36BD42,0143FB774A5D3184,000032CFB1B53BFA,50F53D9B461C9709,EF9680CDE844656B,1A9A510374485D27,49D7349C2F571FF5,F34CE51A0781DDFC,DD9172B262CDB88C,1CD65962487F6828,E8D5BD85400B5D00,47471CF388E93BB5,5BD6808657701591,9E3C52F9E1DF1ABB,00001DF609413910,63852605F202E718,7530E68245AF8C22,3C9CC51769CC8978,390DE8C19FC910D0,3A4E82B05FB76F71,9BA554438E35E3C2,BA714C5B1FC940F8,377CA17C3C389528,E6CFBD7657A783ED,7ACF63B72C1259A6,DE0406AFDD1AC424,0000446B8D61A49E,BA5B09430E7915F4,10AA621BDEAD8BCC,E494117EF82973DD,0CD42B69845F76FC,664CC7DD1D6C697C,78E142838DA16238,D1AA15BA57ADF814,07A7481152216567,903CB95A16515F1F,945427CAE4F37B46,041F9AF2268D62AA,0000313055FBAD4B,33B5440B304CF475,648CC8474A2254B4,109DAADADB5EB657,1439BC77FFA20F95,B51102E2F782208D,5150FF884C6B1997,F3B5106E35ECB390,A36A516F81122A3C,7B1E1F6B1D02C333,59F2778B53F6059E,761DDF34B348A70E,00005F932B650469,D467E6772D6A71C0,CF5667A74A6C6521,0AE4C72A21C73D27,DF3855B252C71674,17A2BBC67648EAB9,AC19A206E6EBFA93,09DA46A6DB12E268,D80C02D9EBE8055C,A74FB3D10E369C07,BF11F07A15AA38DE,1AE4A42D22FBFE6A,00006430EEA8C6CE,F9D53A2FCBEE39A7,002A8AC125799A99,07C8A03C9B7FE21C,ADA38BFB15E1F913,4975EDB216957FE3,D70121DF91352BBE,9C270B47604BA976,3470024EED3D7893,6FBC9A8ED76A7EA9,4468F5236DB05116,FBFE618F32BF8694,00003B0704C70546,A01D58370F41782D,B0F59CB045AEF743,1727F05A25A5F450,10268E2458C63BE9,F907D1A006CC24CC,6E536300922E7003,17257BBA1BCE8FBB,11525E5E37365B17,FD86FE2A66616096,A3CE041B8D3E3C9C,E7248D2084CCA369,000059283BCBE9E8,09871499CE78E951,CA67DBB2EF6EA27E,B08D754670242337,FB161C62AEBFE622,5715CCDF3C78B910,8C273597D9989666,4A960EF434C8F843,DFB648500A66678F,00A9B5C3FE084ADD,7B9C9A1C1FA35D1A,A0EA05C69CDEA5AF,000047CE9AFE7EBF,6E7FE9B56FC9857C,45069B84CEB9DAEC,0F795C509C4CD73B,24981F28831BF76E,6D8DD31AE1D866C4,A0AD8700059FFE90,8103E4AD22C58C48,C16E0F69FD767442,957A1C1D5CBB53FC,EDDE1711647FD8AF,F97807B8D9A7740A,00000DCAED080E9B,1A9DF380BB2C4F8B,AB863E2C92F7C5C1,813F947DF218300C,E747242708A08E9A,9FA12248961C4716,CD6367347E513C62,8C3A5E36C7BC9322,B153761040B507A1,E94C29B215616641,B96427E269A5AAF4,C8DD6EAC8CB28B91,00003A05FB1A345E,6E9F4E3AE7015FED,84FF7034E44CB548,41A3DF178A334D0F,81B7F65A9AC76C56,E8ACFFD5A44A4804,42556D66E5B33538,BC3796202B2FCE77,70CDB60108A92B7F,A4B93D502BB4AB4A,32CE8387AA1B1CA7,743374A659DCE2A3,00000C342A77CA65,6A33EA029CA4FA67,5A539AC17EE46C86,2D31067ED4AE32F0,00142C6CF3F358FD,B50FDF597A60D58C,DE5BE136FF008B1B,53ABBFBD505F6702,C0A290CE4F18B77A,E818AB202ABE8693,F79F2F506FE8C824,EECB7944D9C71454,000044A2D24EF009,A641918927FABAFE,5E1B3D3CA7EFE268,81A6B6FFD2E093DC,FAEFD0D206B775B7,715BBFD38EF3241B,780C2120AA4927E4,8AE19D1B7A7D58A9,C6E4A77721B966DD,F255E8D390B6AE11,501A034F6578A4A6,94E524D32064FA76,00002AA0C1ACAB96,E6CF3A4AA8A6192A,E746CE2A1F73C54E,169359002DE229C8,45B1978C75D4F45B,B71D6F456464C68D,A20890E62F2917EA,B325E23BD2DE0D60,D765A12AD5181C24,011E617E3D990198,56148A8EA22BDF8F,EC915C9A6223A3DF,0000698818F0B14F,8E96AC1F22243A8A,2A381F23A244AE47,AD7CF32D1AF4CF9E,D9D790A69FEE81C8,958465FE8EE22340,F483E612764AD211,DF1F3F492830954B,3F1B94A66D1AEE3D,BA86E3B3168C97E4,89684CE08A9BD2A4,3E0D076E6BA376DA,00006722CE0CB771,527864A477DCCC4B,FB1DDF4272B8BD25,E32C7FB187795BCF,005FEBF2F38C92D3,CD8EB19DDF4DB2A1,76F1F1767CD3BCC5,5E9939E358092A7B,10BFB7EFCB48A9AB,B90B9612D84F3022,07A06E9177D0693A,800A58B7578B3EB8,000025961162BE22,3EAF94543AB6BCC6,4018F625789AF5B5,917A7FE7F56CAC8B,0F0323E1353CB9ED,BE6B0BCAF62EE9B6,97729BBBCE3A0C1C,8EF53B08374A137D,440BD2B940B4D9BD,E794A51997CCD72D,26FB77E708371822,82C97300D17D8504,00005B72902478C5,9E2A9068B804F417,7E882142F6A2BC51,594AA002D786F54A,DC4B22A2D8DDF5B2,B1A644D21609A7D4,40CBE08F571A30F5,0549C3E2DE02AD00,DCAD5ECB49E6D3BE,653E76C9E49CBFBA,07659531C2B9CD35,9DD0E181252A386B,0000043DA8E9ADE5,C327E8942EE7584D,92C3A19E7AE039C8,EFA1DCE064047596,579532A573E86D5D,093EAFDD827803ED,2F59CA0B494BC73F,F71B85330CCB3948,DE0525ECC9D38A73,7990CCBE6A23D8A5,21FF4D825B53171A,6B49BFC25203C675,00001F4039D8DDC0,E3483A43A9B74D1D,A98E65D50AF09D4C,D7BFFF486D9E035B,8D44210168B163B5,8C18292084A11AC1,07C627915FA17AC7,61645311BEF0A4B2,250C37135F7922F2,C40486573499DDCD,009B7B9E35AEEDD4,64983AF6447A7FB9,0000111864BFCF26,347B505EF529BC75,52FE627780494247,F1BCA8548641F1C0,4B04AC9A94AA68E1,5819E1A0822739A7,C0D8630FCDE6E594,D02FAA35BC1067F4,81B1495F4FAD712B,C9B40BB45C3F3E2E,77B03FBC150C086D,A3238AF5C7814673,0000310FA5344B61,25230CB8CFD1DE90,31912C9F9FC024F6,13E22B7EA0FB0EC6,17CCD17005203A29,4CC9543979A882C7,FE9F4A37F581B784,C1A8033D134B5C1D,67AC364B5F5AD660,4BA12A6120BDA647,D61916ACA5E9F19B,C803338E61CE2BB2,00000031227BA2E9,75CBF84E602FF120,EEEAA9AE58392736,34D2058C133CFECF,55C097B31225BA36,605E1BDF4DC72EAB,F30653A889B44810,33D55D3C9AC2CBD7,0EF99FACB878C5F4,7F3C884BCC64A340,F8F2DE3AF187CCF8,45C8F2A358828926,000037393AB92536,715280AA388FA789,A56905B55BE63073,3B6BCFBA83A1DEB4,B4106D1F0ECC5995,ABC4E996EC64543E,F0FAD9E824521E91,A357ED159C192669,E1F66B83F6F105F3,F7575412FD4619FD,8703AA6FB9745FEA,C5C90E7EE5939198,000026A6D03FECB6,EE790C86CACDE989,1E2A1A8926B18EC5,1ED7B7EB1AF56B1C,5020F7ED30CA7292,DAFF946664BFD780,7B8A39FC0C615D31,94F38C173BF89CA0,86DEA8D2AEEDC4DD,5986D07F54EE985A,40538567AC7B3220,784CCDAB9DDAE75C,000050F2E9961608,88C874B05A6EC1B0,CA02CA7ED8A0EBDE,2BF6F4FEDA02A370,E8E58716AC88272E,FDDDFAC5D88008BC,3678239F90C18D3A,89E961C53031328E,8CF76BF9A4F94B93,50EF2BA8683B0C1B,04C2ED0483759927,B0F88D3B40F432D7,000049FDD3897308,14E95BF8B6BCE785,40A93C29BF203C75,B378C6D401CF5A49,D341F9205C53607A,288E2A7B3D486E74,97E04BCBBFCACCD8,6DBA78C1B75F6007,C6729FFECCC99814,D1324AC293596EB1,0DB3BD8E46F0E015,90077ECF0B15F374,000003C7CAF0171B,45EA2B5FA838CCB1,535658C343E6AB23,F2726CBC63360475,5AA2BA1C98A69DD3,25825EBBDA1E9E23,DCF7E1ECE68049A3,5A6ED13DF83DEBE8,E64E15C7CF202890,A9C40251898828E8,2F3C4EBB6B2AA2C1,FF720160E8E52A41,00004820A4E02168,70F021053D74BCB2,DF7EED720A883814,E72B430A5EC81E05,A276278565930186,5D14D05FE6BB0C65,FD0759510A1024EE,185DF517D845058E,C4A3C10F093E592C,01E11B37DF07BFC2,4E1DB0BEC605AF51,AF93DAFBCCAE1014,00004EA72CF539B7,B116FDF3271B4F61,74DC58CF12A16F85,3B753C0196E588BF,4E4461F56D81746B,C17E446E46D514BB,6FB0DB29D37119A0,2E015B19F64A430E,83614DF3ECD2F455,4D2AFC848E5C25D1,1AF1F64F09A61912,AC0474DBE2366676,0000628053437702,829D66361A85EC15,C93E70E991A6C1AB,744D111845ECC7A2,1B200D5AFAB6D86F,2B628FB12B44380D,2E6AFA25584494E8,23BA188800FD9087,4F5DC280D8DA5F68,91575C031DAA1EDA,31DAFD9447EC1886,D562B653197E5567,000047C89DD8570B,9A6D2BCB8C5890DE,5ABB7A7E728B96F3,C7C586ABB944F8C4,0A170C4525F05B23,EC1EBE25D30F9533,9AFBD7AFF1EC98CB,D6B2DB32602FA52F,7D99795C552EB771,27C872F33D0600B9,FE631BBF1A754454,C330A44FD1FB48CA,0000228EC2F4697C,3761B23F6CB94F6E,5326096A206CD50A,C4ECB56C6B46943A,FCB87A0DCA476FBE,744D4FE4C3BA7420,19B75F222EB24E5B,8D90182B2CB39DB1,AF808FF44C572480,AE840E7114A06D0A,553612FBADB42BEA,E35CEC00C18399C9,00003C321A5AB98E,8B082CBD229772D9,9A1EC8DB62975E84,1CEB251C6CD1FC7F,C156A083AF540388,68A10C6691BF0CEC,9B206C5FC41CC7FB,619309C7CFDCEC56,8ECAE0D92D6B94B3,4FD53C30F872C239,4E23A5D6CCB06E73,D349912088A2819C,000061C0F874DEE7,1A7E53D4AE3465C1,F61ADA632BF94483,69BD6751D9529F8C,9C52BB9BD762FC1F,B640B5BEDFBD56B5,AFF5E4937B4ED65F,A539AA2ADD0F60E9,480BC16715BF6499,A609BD52C9949FDB,D4CB2D662759E7AD,5E5020F8E6E2BB05,000001818C0B4D96,C44C219E134A2CC8,B750857AE143F514,19EF8E37BD1EDB73,479620C6A590B4AE,8CF08435283993E1,9816F57B9D9A00D7,FF28BC4434A7478E,1C565F11602B5232,DF43CD40E9E5F0BC,345BEEE4D1DDA71C,BC3F3BDA65FD4350,00001CA502D797A1,F4C0DCB5EEC49008,E95B33A169CF1CCF,CD21A7B31A716193,FCD7EBA69C1539A9,C8B076AB1E4ADA77,F1ED1178CA1F392E,99455F077FBCBBF0,19D60346127A77F8,D338FB479EF028E3,393BC1767FB76812,1C860A17F90F5565,00003805CCD23EDB,18194A4FC9FA15A1,6C159CE9933F9711,D4A5CC214D79A3E4,470D6B0E373F05FC,8207179D1A66C2C1,D1DB85C85A2B5B29,10D3AB5641AD5982,ACF4230A997008CE,B8E6AADD4C4174E9,151EB0597AD9D7B2,DE6105DECB9E820D,00003742D8CE6EE3,69DF0F9E3CB70F22,DCB0CC2BAC5944A9,F37914267CB66C98,61F0E8CE6077A046,22B959378B9D95D3,7F9A57D8464C1FF1,65005F398B5B8D9A,A9D24EF3E228BF60,216F32484D49AAF1,D508BB84EA888487,789C407B6B00C68E,00002FB2C97AC83D,3565B00C760E6597,1C72DEBCF3D8F323,F335D4ED6564EEE5,2CFCE24423AAEFE1,065D559FCA2FF43B,D66F492A5242B564,DE3527803A1EFFBF,5A16B3F2C0C2F6A8,57CFCDFF17649484,47C73AA268EBA8DD,02DFF0BD0C84BC7B,0000084450B7A293,11027560CCE5B9EF,66988169A32C6F62,CB852FFF3F218199,B53696B8957B787F,44D2EE50768CBE7B,D735EBC01EF3F396,12C2D4C469108301,C39FBCF89F2948A6,93F6DDC258627029,3DACE164408BFCFE,993BDA6F88307AB2,00004528BA651C64,987A2635F0C65111,2E83CAA1D0B8CFEE,E1FA645A01AAB08D,7FC2711127DC3B90,2F96B65986FA4E35,BCCFD20F663C8ED7,FD15F8A7E13C6FF3,7D7C8B9D570B0F4E,11010EE0B512BF73,652456433034B6F0,F32A6690AF99ED7A,000054DDEB2F4ED6,47B637D2E80B6F92,CAF8F8AB19C540D4,334F933870FF17CE,FB82B30D503041F4,1B8DA60D29B0C009,1A883463CB41D036,CE82252BE5E5D48B,752507CB9D8446CA,243EAF34E43429E9,DBAF4B0BC57C1561,44A5F147607A4244,00006D02872BC257,075834B50758B8AE,809CAEA766D5C8F0,9A926594AD89C080,2CCC0789F16091DA,C9A0A1407A25D6F7,91284EC8D2B68F73,C53280CC05EF997B,160FA975F4A3B1BA,07E3710700A88D2F,C0D2D4E7B2893B25,FD65ACE863CAFF68,000051FE404196FB,40E0F610A4657888,ECA976F6E3D15618,E024DB3C37FD418E,5EEA8883D6EAE17E,F329709F02AB3489,E76C3E54E498BF11,64B518FEB285D825,27DFE1F75D0D51D6,9DCCDDB25F1F57AC,FF1B0735978F634A,AA16D9700B21681D,000026EC1560CE81,CF4CB6B749119555,3235E285787A7724,4253634BB4755CBA,3385257C1D5BCF1E,5922E7730A8D3DBC,9A5C308A8B2E7990,53BF8AD32351C7C1,975B780576CF3B5B,B04EA106808F31EF,CF048120C257A938,23D45E0C5B54DBBE,00005F066523B25D,3535FDC5F4C3A4F7,E624586B70F5D262,301F29E0618BEE37,F644DDD7FE1C774C,A25A0C8D9A6E31F4,CDA399C44003680B,DCE4D82C41703622,283139337B440735,8C09471F20765113,EDE3239EF9FEEE85,A77D70B263425C02,00006CB13D5E68CE,06A0990E42D548C2,AB347A6826A3BD9C,B1E524245FEE8385,84D83178EF1F9805,0493D9C07164C235,BA4AC0D18593E6B3,67DA68E120674D71,CFDA07D6996A2CF1,F21F71F460E9B584,4F5756A1F8E48245,65FBF4EAE0F9BF4C,000030A9292C119A,FD4A2AD8B2B3D9C2,152A69165EBCDCE1,3ABFE1E0501815E4,9F47FAEA9644ECEF,E9938CCCBF807545,C28219F07CD9898E,0E6CE11FA14183D1,984E505D08169848,9F7BD1E6AA196BB5,42112209305E0E03,77752DA73C08414C,0000138813F2194C,450ACDD03C58358F,BEE6C2D35B89F5CB,AB6B14E3151E8F10,806D11F3325A0935,A641355F8119B070,998A12A0046CFD69,CE7C5B4687B45353,F06DB79DC4832D9B,675090FC222DCBEB,1CF5A3C7505ECC96,482D990DB79B15AA,000047A9EFA21BA7,5517414B92938302,FBFB32B31E07690B,0E88A4A7EBD82867,EFF9E55FE1D0F711,E52DF6930930CD17,C61C6DE427A5BE2A,D350DCC7CA645427,6F5BC902AFC29BED,367E856C2AC3D80B,9B19C628F2E51F7B,73A243C979707A08,00004D2A3C6AC56E,3528C3E58B5C1DA9,AD464E0D171A0AA8,3236C00A45B2A9B0,1861FA10D94DF988,6B9BA0EE4021DB37,5FAF15387CCB648F,8C84CA1E9C46CA3C,4D75452FA01E626D,B11B97EC811114AA,FF13D0E1FFC398B7,5668010172980837,00000BF7AD41C892,1349D680B460AF1C,7CB4D48168F216CE,723AE55569BD0799,C02452340CB539EE,A0282D8B657228F5,AA72CC923AE16237,CE97E34ED3F61F6F,60753C74B4D18E3D,C07C4A030939D8B2,48CB41EA20EC2F5C,BB6CA49672E5F0D6,000014F3FBC1ED6D,5396DA2E2C409FB5,70749FE1465C08F6,02D3A02B56317396,1881191DB5DCD5EA,67A3741FD63D3C55,8C6821955FA4E23E,C3A4972496EE6EC8,2897BF8EA99253CC,811DA719F2CD4B83,EB944DD21F830F28,DF8CACA9D2CA41EA,0000137E5D38BB59,2FF122D24FB203AD,9D0BED8D902147ED,494499CFE22136DD,93C60C0A1F104503,BA14566377FEDCFF,68AB334277FFBD6E,5EF737D7FA288DE9,27CC4E17B85B5C7F,67995305FA317172,B1DC3A5AA433299C,395B492E7BAED4D8,00003EAB8F4F1748,F9F9F98B07DB0D83,EFC1EF29B0294268,0E4CFEC86B479C66,00B6618B176BE267,10D4379AA555076E,578BEBF5AABA9CF8,3271EB1A02AC5634,5CBCAB66555AD665,7C1739BA6642C8E8,5474C6ACE5CC693F,129D17A5D4C7F00D,000067199C09C4A2,894E62B747414A79,9BCA855BD0588419,A17B293E5752151E,272F957FF4024E29,4C1E6475CF2B6705,CF4C6B381DFD214C,96AC3D9779826D48,7A7C606D13F4B563,1FE98EA2522F4F4F,F27FC5D103BCB67A,2F07A93D5CBA2569,00000EBCA9709A4D,C1B22425F20E94C3,590D9DFBB0809627,1382322497EC3516,60B5CAFC747763ED,C323A0C3F9149915,5DA17D20BAA1979A,A586E10901FC0138,1D031492120FE39A,625A8A8BAD07CF2C,B1131D965AFDD4B0,A417CDE682BCB8B1,000054EBA017B28B,6EFFE3CF869E6129,6CB9059A91E3C461,17C86D87E2FF0750,ADCDF4C463315575,80218FE3FE87057B,2E226DCEAD038C61,B7BC428BA59EE2EC,4871998006023122,9B3F6892D0778C12,8985663FF1F0EDBF,7D441C272D580E01,000057D65DA94307,E2E5D9772D123138,5D57CB60BD112059,A71E5A6BC20EEB3C,956CC7A94E7F9B6E,C1CBA2FBB0ECDAAD,57CD816F89012066,75B406ECA419FFAD,3535126CA4188F34,A3BB949D7AF1E3E5,B31953D164F2A110,53B560F65253B1B8,0000201877AEF077,99C91363DD11756A,5D7558FD9A79AA1F,5868B5A882FE6B4B,E5F1E6E63173AC0C,1A80F2D6BA134069,8A97FB40E53E938A,AB1FE445449F07B4,A7040FD91AF15C49,7F0DE01C4C917200,138B80E19E5BB9C8,151B3FDD2B182DD5,0000087D70A9D91E,0CFF551F7FFAA3AE,E57D2B6D19036A5E,3741B96B858983A9,87689061044390A5,B1ACCDE418827964,64B7D96661176716,A8158741EDEE1497,1C7D3BAE8F960D6B,4CD51B767208A767,CADB44D12DC1547D,11D1BD32FE37D4C6,0000525AD6735183,111E34EB6FB85A00,043723055392AEC3,9230D970320DF0ED,CA1D9D6FC6EF7A3F,AA9FAF718192B9C7,7D62DB992386A75E,2B8CA16AB9C401D3,16C6A5B4C8BF2B29,5748C751DA5CF333,DAB763AB7E9201EC,6695A0F915D59343,00000AE8C1B9D307,5EF4BB1B274D915E,4D5C741EA1C8F5C5,3CB63B638119BE0A,FED8A9401D44126B,C11B62508C54C141,0BB6197AFA75A1E0,EFA3B7C97C6AB480,CCC8DC0855502E21,CC5823DC38778F77,85A8A33F0F30A476,8A5162726AED22EA,00002556B8F0624C,8CEA3968AEB2ED78,AFEC34F2DB44BF62,42675DC6484CBBC0,E985CB2DBC5FCA86,B30F0E4308003661,FAC1291A3AA8A17A,69E06A1D6D700D4C,9B81932226E60A65,531450552EA6739E,343CDDD9306598E3,7F9E8D6348BE7444,000026EC04F1E449,C20E8505D26F15D9,1A38CA55C4445D45,F97478995BF2305D,B534CE7DE1477146,77776AF8FE4CD5E4,C3573B0D6CCFFE0E,943E9CE866B7DBBF,D80E35523AEF7F91,02F43C00F383B3A3,EC0C6E841AF8AA3C,03DF560741C3AF15,000031B77E159543,2EF42C9A5DFF4182,22E68791E64E4107,CCB6D26C38D194FD,3EC51798399B92D7,E634B6F1BED8A77C,628FB3B4D8847B98,1241149B41809918,BD7729A5DD6BF51A,45390C2FE6DBDDE5,3B148609CC895A16,7F26EF8A6A327D04,00002C22C9F9B8F8,8B987CEC8CBDA9D5,DF8AD17145C90D19,8E3380B558AB17B6,DEBD2A05B3DF6F22,3B71D30E0C449EC0,EB16BD54D763825D,E1C518A7ED25F703,58292963EE9594FC,A624FF51D64F6A62,D0C388D8DDC47D89,1A4BB10D188A69B5,00000B0D992840A8,D222C58E1A5588A7,92904C495FA9DDCF,59C107825969B2AD,D33621CD2A9A7661,1FAF8212A02059E2,6C60A3E9D2A11ED6,B6011185DE5F783D,9856930B4E73264A,7E102B349146B39E,F26BBE5B82FB2162,C464CB2568B8368D,0000076A0988BD66,1825B1A62E2ED010,E455E15314703011,E7CA766523E6F594,61D5C188D463437F,0F097AC19B4793AE,F60AF54A36970104,C71D023D694BE813,58DF88746C143303,46F753C9DC06DE17,85CF4ABB5A5581AE,E8A7E3946BF61074,0000099B3866679C,54EA43FAF2E4759C,5D134FC96ED4B0EA,F7E88CD2FC04D22D,3D44E76673656239,87D58AB4BF5CBF22,57C9C4FF1A2BC3D8,7FE0C257B719011C,5C0ADBE367B76C7B,D9A8CE69F7F84C85,CE19B10C18C28855,8F3A8E345289F710,000016735BED5335,4F7826D1C772C870,08156F179B9872C6,083A40C021D064E4,B554D7DCF79A992A,75D9D321EDE068EE,55F1F1A9F0C9328F,CED125EAF3C81EF6,709F948AF6B45B9C,5175C44858C47551,28E5908D14EA2FD2,FC4BDD113F62E043,00005BABE81C1953,9A6FC788FE28A72D,571327A7BAE1AD25,8B50FF626DD2B13A,A8786FCD3D497B76,9967D980F8D0D232,9D4C95E36B451DD1,0C0A6E45EC2EB6DF,18071F8E5C05D564,582385D70CBFFDC0,D531AE7241FB9DBE,0871BF70829E5689,00001539412513A7,28F1011847062E0B,86E4775A3E1AD1A7,A3C6009AA88FE4DF,B4DA0FC12158D677,B8D1457743F2F7EA,CCA154619194CF63,2F3D3290C71FF801,CB2129177A92FDE4,FA4554A5BEC29C35,0C36D132F94F6F1E,378C6F51409A720C,000041808DBE7900,4D9040A47C5BEFB3,67115D2505B620C3,11E613AB8BB32FAD,4D039C459F3F1697,753F422ED7250E7D,13A81340412CC848,05E82DE842E95B0C,081BE4A88D216FB5,3594237CBD4FA90B,B0152D25B4180C1E,7A92665BC221C52C,00002761A570CD67,2F29A105908CFE16,E379FAEB70621E79,F5996D710CF9F5CB,3C6EF5C95D1BC492,8EE20B4A53E3EA35,D2377864E255007A,BE67C75C77EABD8D,324EB55AA40E37D9,08F329FC461FF3C2,8BB502A6DD0F292C,A0E6D2A989D0E699,0000581318D59386,FB3E9F9FD0ED25D0,8A89F1BF5D629ACD,672ABF44A9A4FC16,9343430BD0730372,55DDCE62528D4C34,316F1120D6147DDB,55D7D6B47F0471A3,55D0434EEF2E4207,D3115BB9A5FD0380,3B7C8D73C13040F3,490414D77352F9FA,00003A89F8FCAAD4,C609A55864C317FC,BC6CB72BD6820D94,4B4078A361140180,877A6FD3D15A0E0D,2727D16B47D5851A,32F8AB8ECBF18811,8448A914E6CCB412,C76805796A9E9C0A,7C3C31F6E40B087F,ED44EFD6F78E4CD7,F067334616924541,0000125B6740939E,EB584608678BDF5D,2318DCC98A21CF34,B7C6C070FC4E2BDE,19F1FE842BFC4E10,B749F8BA660E1883,02132E2CF6481259,7277E711D0A0B2B9,81418393D84E4801,941000D1C23A8963,7995948580CBA511,3554BFDD7BCC1F3D,000029AA3694787F,187BE3F98D8B46AD,033FBD26C4830796,116DDDC3118B2A1E,E2E8DD716E648E6F,8E09A92E848BA166,CD670CF8EF58FA1C,5F5B292E5E1A5F94,B058C728AE64D6F2,66F2B9D2CE3F1907,AF60BE2A68A6F7B6,44257D01E95B57D2,000036464A48856E,4904B149C98DB8C1,23DA5C63CFEC01B3,8B95A6919D0DDF86,4FB5CA51E27DDE89,4BD0D28FD133298B,EC1785CD3AE74890,B0CD08B7BB0E0EA8,E325EE7DEC8F0692,36CC20EF487F6B9E,A414C26826A794C1,D0C94117866D9089,00000968AD95487F,6BB9E7FB28B984BC,95795A6AB5ABB5D4,0722FC1253E6CDFB,BF8CD565AB05AA7B,3A09F79015A3D0A5,5C87B1591B1A805D,B014A5EFD3E1195F,B745347F4678500D,ED8F9153BE2D4095,83FEA968F2702CF1,25164764668CC43F,0000644E87915CE2,A8E0A230F192DFAF,71C34D42631D62A9,1DF22DBBC5022EC4,06E1967720FD2D1B,B49F11231173EFB7,E903CD7E11ADD357,B457A970BBE0807D,B8F90B9FFECD4484,42C632E6900CCC53,53923746C169B39D,F0553EFD2B65B38C,00006B9089D7DB12,668268769D804BDC,E41FE328BD33D1D6,30DFD5C08B30CB24,2D2D207B9C19031D,07D7FDC6CE4D2710,A8929852FE88E68A,A7ADE3D79E69349D,A8CE5F6804968EE9,61CB79E92BD9DFCD,44427DDF297851F0,081054444261A970,000050840381F021,56C08905354DE42C,7C32F0DB81E1822A,418449AF6F26A685,41B8BF2D8BEF0122,E4E22B44E578A27C,62B7CEF2B7FE853D,3A3D3C529BC6507A,C97C4D747B66E16F,12197B7D419E7B92,40F8A222E8C33C7E,9C79A14D4673546A,00003131346B521C,5CEAB85FAF07DD42,A87E12F5A755D4C5,615FC0DE31E5C8F4,CC8AFE84EC78EF8E,6742AC165447ACB3,30A75E27D427390A,24382CEDE3926C1E,17F81DCF5FFDB8E0,D21B988E13B0746C,39592CD3CF6153B0,5B814BB928EDB1CE,000049DA0B78ED97,63384301B3C71967,4D518CACF399A1DF,B4954122D3ABB2A8,0705AC8C6B34E0CB,E165F31355B159E2,BFED7FAE54CC51D5,0EB16E0EF7CD3B7E,7496300B5A3BD60C,F405D0A92313C566,4326D9EC58438615,15D05351C66CD17C,00002020A65987E8,A70CA508F5A099A1,E4E2E92371BBE3C4,6678E54656ECEA5D,B749CA6577FB0FAE,B7A0E2D44454D237,CF514654DB24E3B2,420CD344F1A9BB88,4374BDD80471CA85,6D75AC6915ECEC7F,FA3C4EC170BA66D5,1AA14C1EB1A80510,0000084EB161D9ED,289B63C32A2A97DC,1016606782DBD4B3,5469ED6B6C1D2098,E90B43C73A216183,B55BB0B3784A6D62,4724EB6C0E6A784F,B9A679547A7C925B,84601A8802D8E91F,9849AC10EE95B5CC,3866DDE59D3A293A,C99190946ABE5916,00001CCA42806BAE,16BF68D828B22B22,6A2BA4009DA70D8E,C9E04FA035A41A58,0E8F62845C3E99F4,7DFC7AFF81C4F80E,25DF3C8058E8148F,F4B0DDAD1CE593E0,0B4BD6F8066F4380,DA28EB7C8BFB749D,B1AA13DC99EBAD17,2DC8987E99F4ABFA,00000F7C8C025F61,383D7C042BDAF3A2,882F0211D06AA191,53B0E86333636642,6FD522B37F365B4D,AF8CE21E912C7D64,86C733EAF8C9A3CC,8732CEB86F75BE39,043DA41D231DBBA8,0069315174D6C341,245E05FCBCC753FC,6D661B507874FBA5,00003C1C754CA103,40F10CB5D4145200,47319D40DE050444,5FAB1B6AAE955732,DFA659D3B453A548,DC26BDE60878196A,D059E57B42B37BDD,D479699306F4A5A1,179B01227B1A3779,2D0C5E667F2010B7,703D2D6CB516CF26,7714FB53D16E2C09,00000A01043F8F16,6C1EA72EBCE04C0E,A3A33F22E70C9DCF,21F1D955D3AEA387,C472DC3D5C04A4D0,7029590E668C0654,6437466C935332D2,85ABBA950DB24161,FC44EBABDE4C8282,EB794B91A3EBD971,6569915A299BA831,E976D6F7596D3133,00005220A38A8C3D,F1D101AE029C61EF,479E907D8DFED5C1,F9E92DDD605735BD,BA397423B994F13D,A5203813C59A2FD8,6D09C11C2E70BE27,7CFD61A5D622AE46,3A9DB6E43E2EEF91,B816C88D6F070DC8,2411856379B2A0C9,4D3CED7634D0B8F0,00004F16755DF483,B84F619FDA69CDB9,A1B6738D4EEF4A64,BEB0AE67B7B5F364,FB3968F956537DE6,F45203D8E188CA2D,EE085EEF7F2C7905,0834150C45C68289,80102959347BEAC3,ED3D68B1F65FE12F,40C6FE4CCA076E5A,E415736944883B4F,00005DDEA43259DB,6730C8766B296C04,D1F641EAE74296B5,2B0AEE1AC4E41D04,9C9233F6EE8B2A07,B87B5B20464B86DA,BBD6D4AC3344AB71,672E08147018AB07,01A1D36440EE05EA,1D291C4F6EDD5A40,A822E7E608DEEDE8,E6ECC81655068BA5,0000681F81039CF7,EED4D2C447FC87AA,BAEB2493AE37E2D7,D834DAC68F79B272,D33809174A277819,4778AE6AEF601D27,B289FFE020C7F7B3,851D459529562988,F8AC9E674430D3A6,E528CC50583A4C0F,4A9DE6CD32D65FAC,0ABEB330219138F9,000048994BAC15EF,DC888757F9724424,4FC819C211159280,E15C9B72224C2168,2E58D2CC0798C614,21081CED157BBD92,F41C0F4BACD62CA5,108623889AB332D1,8C65C4D6D4B1E5BC,8A0F4D48EC81D394,9F56770AD728935F,41D40E57FA78C338,0000278F702BB511,0DDE00440408C071,A1AC4D60BB1E16B0,2F8B7D3FCE318873,C9740EE7BA30B008,0EFD619442355A5B,EEE206C0960CAEAB,EBD46F29D086917F,5518D5839B6BA0A6,98654DAFA564A29B,58D973C5FDC86DC8,DF0BB04BD5E66C7A,000042A6CD15E7E5,C324DEE22343CF0F,4F58C591E427C0B0,42EA10DE227FBB65,6D025E298E94E549,4B90C273F662264F,8ECA159CDD515618,0B45C482FD1BFE86,044DD30299E5C3AF,C076C179958AFD9F,B1D346C7EBEE8B89,CD9D73F1C5543C1D,0000448823F901F4,A767042DBECD3197,4A355419B53358C4,33C244022539A53B,AF197AC111906165,1CFA5EC7D414A9AE,01577B4B70568C01,BB86DCB0DD1B9C0E,C277F86A0BBF10D3,37256E708EA7C6BC,3D87575CC4A218F3,10A03894567C7159,000062EEE8F7CE92,09BEE04DAC5CC865,811E5750B20890D2,E987DD03EA8CC629,FD8375E20ABC476B,B32BB9F24BE663CF,4046E6D5E54D3FF0,5C3F0E15FA6D4457,7561537628A47221,D535EB64DA72CAE0,49EC8605356FB2A3,748366807CC5AA1D,0000237CA8E5712B,F6EB2C7A9A63A819,A6B45CB38834691D,1839A987E6C6AE8E,8BC5E19A1D201CAF,0051C3A4BE0E7339,EEEFEE8B65369B19,3CEF133DCA6971D2,0822FA62D4B3521F,4A642F5995767021,B8387D74BFAF6C23,FF4D9505FAC1A4A0,00002E539C6991DD,6E836D6D2C94813C,599B78B282D3C8AA,42C6CED8CC90B322,8E799ED69F37E981,9923B484712F5C72,A99733310C02EC23,EC2EE88F3016CC94,12D1BD18715ACF02,57F8E48B0C0CDFB5,8324B9428ACDC2DE,9ADC0F767B5BEF04,000016C6984F4AFD,03144D76BBB0F9EC,9D86542820E7FBF6,34817A5D5347B14D,E160B5FF83549E85,D3339D122FFA43B1,C35A760D3397E0D2,6FC4ABD64DE6BE3C,DAD6B73BB7E428F4,4519F7A562C7443A,AF299262D3F63D1A,AF3EFF9F342020F0,000025025D9B0FBD,7AB9003D3B0DC937,E35FE58DBF184ACB,3E8CA6EAB245445D,6AA6DEF2091D2B03,7C6957EB020A7847,D56D290406EB95A7,E67C4B823A987C8D,4696489D0C4D944E,DE34DE8CF9431C96,66A01FD8E48D944D,041B65FEFA82E7FF,00004399960B057A,9161858E1B8544BF,EDC68696CED6FC06,6904D6EAB3E1022D,AD175AB905DF8017,95D3BE8E9858242C,EA5F9BE4691EB539,E22BDAB01699A457,90438616312C1648,D9815195FFBF8DCD,31542EA6BCA4EACB,215C8676E8673A63,00003D0B878AFCEA,05E28D9730D98244,FFFD47B2CEAE9619,72C56B43381F38AF,3B449F5B561974BE,7FAD38E11E022D23,322359508F8482C8,C57B3502587C1049,DDFD7CD4783002CF,80B1D1C61ABB09ED,EF9A46E8F2D40937,6272CE4BF33CF1DE,00000F0BE1C688EA,9D7BB160936EB87C,6640F84AA8D8A1F5,0A7ED711E94696DF,634A5CBD5DD89F95,2DA55A541BE13B54,346A0FC49B8E2368,409F1F61ECC5A8CA,F8311D4D146B8FC8,FEE747572E35CAB4,BDFE8FFFC0141C01,C845A049F48AD221,00001B362BD99742,861D60843C32BDE5,401A1526E8DE0A6A,88C56057C404E220,0FAE69C6FED1F940,B241C99E43F0A36D,A5F0D8139668FDFA,EDEFEF7DE377C9F3,6BEC081B0A098CAA,665C30DBFDA8E257,DBE029C2219C9D5D,114D55C3667DFA3E,00006A3561356118,3D791F951334DF3D,5FD677219C3A823E,A5E0028076C9125F,0B63AC3DB420266F,D677CF93DD045F7F,0B6B62B982F05F7A,A2E2F8ABB48416AB,940E35633404B770,94BE12FC370AE6D4,E78AB1A95CCE12B1,ED31E849DD467149,00006ED99AA59784,10CCE047AFF14858,C9854B00C5EFF9A9,1AFE4ACC1DB2E3FB,286059CDBA415E89,6499D6C8C368C915,B3578576B0EF6F84,90CDA4CBBBF10797,1375E4DABEA4E146,F62E4841B95FB785,10539B8B4B7B3C73,5D85AEB10F08ECA2,00001149ECB37334,3D659738E67E4DBA,9EC7A182ADE472C2,CB340AD7A2693F4B,A7DFFC669F62B89A,F8BBE1D903E8B9D2,7307C649128272DD,B84EDD08CD48FB54,146904257D00A45F,13636039FC4D5D0B,74668D98A6C0E336,F1F65B5C9D75D739,0000035C4D28EDC0,06D2AA255ACA2374,F5DECFE4241C210F,7329A9D1A80D99D0,4823E486E0858BAA,263BC5429FEA633A,0F15F97A9EDFB0AC,30168EAE08EBCA70,E1D0311097071E51,5424C42990DE39E7,6FE0B27803347E52,C861B29729E36683,00000AF1AD219618,0E06D0FBC0E5A2A9,412D2424929605A5,AB51045E37FEF424,8702D3590B9985BD,843E4C247941258E,036411C4EE1EBE54,8DBD0B6F08CBDA61,920060ACBC153B28,BFFCD69C7602B62E,466DCC679CEE5186,E8048C82211AFAEA,00000E33552D576A,8DD394A51E66CF9E,9CD04BAB6861297C,F638C53EAFB07261,3F3A0BAB4CA4EAB2,4BB2976EB3CE6754,9FB4C7504D761B9B,B2EB079492E059AE,F790D1D78467088A,40740D8DA506B614,F9C06C6570371A31,E85CAC9E4A57DFF3,0000405A4FBF0406,C01ABE33A316512D,5ED4870950ADD9C8,16CBF34C5E02E785,20DA5610907FFA12,C5732CB6D47B9F5C,FB6718847F56CCB3,7F90B2A7F5613DC7,895CAC6C58BAF5AB,3929D9A90A9F97E1,DFE968AA956400D3,9AED2881C59D5A33,000041DD5E6822E5,C37C611EA9885F22,394B35F938994198,2B84BCBD3D217C6C,767A8745CC50E059,F6E14DE005B3571E,2EA1D62A0A6C085C,70BAE162A2D93629,2C326C96C1FB0381,005F75579CA148AB,3D1B3163EA2D7465,16C111EEB3C34409,00000BFE4FA12330,AAE4AF07020B650C,4F84A8DA27715ECB,5BFC455726D35556,ADC859916AB3FEB6,B3F2D38535B4554A,01A940049B8DB059,C61C4AF5A609F24A,C5BF3497EBA79BFA,281EAEBE9C8FE692,1D1C31D6EFD4F9FA,D505ABE2EC661CB4,00001D0FC6EB3819,2D32398A8646A886,DDAAC2CDEF2BDECE,987228699172A634,4C4C6662E3D3905B,CB5F705C89D01FAB,4D3AF3CD812DD1C9,49EF1FAA15A4BB0C,41153C10B929ABF0,FB8C88B715A54251,95CBEDEC0D4DEC60,8F5CF8BD1EF6DB99,00001337FFCDEECE,1241693474F4A8EA,7D8BD3954FB5D647,75D90FC27242D80C,3EC92A8A8BDE0EC3,FDD836D0F922A771,D3DA41561BC06B0F,8D9A145BF625B61A,469A227A78EE3A4F,5BFC12DCEFB92473,4BF0DDA1FFB3CEAE,E41688EC95E5736E,000004BDF6124B04,C96C1217F658160B,C5DAF85A4F47306C,E5F9E993841D0564,AF8DA64774594CF1,798CDDD938316231,5525468456D6BA7D,279F96B0DA9802C3,E4597DFFE1290C7F,AFAC1C3CB88330CA,F023466D9ED946FF,F8C2D4E9D62A6BEC,0000641626851965,40F9874F0A8EF82B,A6FFA0ED2B453E1E,E2BC3E47A26E4421,418B238CA6FEC6CD,6384F054995EEC78,919ED84292366F5B,13B4FD6482F7DC7E,D004047A2D8807E4,F39C4469774A6228,5FF40BAB08A21B6C,B7A4CFC1209F5D12,00001F0D9E94A33D,2B00456958C289A5,49D36BA9F0740540,67D7763B84373D3F,BEF6AFD78F252B36,768CB894DF527DF8,8980B2E640837F21,BE488B874C2C8B80,E96B9D239EE5C341,6864C40DECA83FF2,AC98F576CD302385,A14DF9AACAD907A1,000007FC1402E64F,743EC874AF472ED6,A18ECD76BF1234B5,D48260547E9A57BE,FBE92C851211CE41,66B7B2D87ED4DAB9,A557E5EEFA878C65,B9ACCB4BB384FEEC,BF3BC5AB46C1FC37,50C2733C679541D6,3F9AA0C79058C940,B8A180906383426B,00000AB22B7BA67B,199B3E80FAA30B58,A5E3EA64B714438A,CEFFD8CF71065122,9D428A2146EBDEB9,5BAAA49C08E160C5,8785EEC0C08A9FBD,4C0E9C14ABD24B83,0D5C64A8ECFE8E03,7D0F56B0C17E9135,8075F9DB893017FA,AA4D90535570EAAF,00006434BB716305,5B8C094298BFAF61,3717028FA6E96E45,AC380A3379ED9DAB,81627E4B24860158,2602D1828794820B,3EBE6AB6C2444375,ED4337FC1E713B64,E2FE528D8D11397E,2EC32E9B551E7559,85389FF7DB8D6555,04110716C1645455,000045BF1C67D59A,F75F47D67CB564A3,071ECA83C6F7D00D,BA419211C5AF42B4,E5670E3C0F83F77C,23606E4054891A94,B98E6D7BF4E3E029,4D9D2282C7CE6854,DCC607DD0C39A404,BD590CE9FA9E75E7,27E41FB24D45EAB6,FCC30F4B02E0C556,00004E02F6677FEF,68DDE13C7D0CCC36,E472009CBCAD65E4,43C786D80F7D9CE4,504ADC647D18AB82,EEC6D39937145FBF,C6E60E5952BB3872,A22B9B5135F02AC3,333427DB9F7650D1,4BC4C608BF655FCB,88FB07B5A20B8989,234B360E6F3BFBE1,0000419BA6D153B8,334C1A2E2E7AC178,2E7496D7AFCFD40C,93F11727888B4B57,63E469B5EFF4C8CB,BB66EE2CA03D04BD,4CDE2FBC8A1C04CF,A972932CD9B97B7B,6C34607EF7504D69,D396EB62A494DD84,577459F4D115DF65,2D505CA0AD425380,00001BFB8322787D,4E385F85A446E222,8DA7889318633D69,B831644D7574FD76,7246DB036DD6CDFE,37DEDF36BED676FF,1CD5339DB36FDABE,BB0B8D6D8192880E,5E1E7BD76A486D24,F9E62B535F9B3CE6,AFC95D453AB692FC,9B67708C11B5A468,0000044911C51D0C,36D73322F603ECBB,529EA76C8A794461,52B2D8010283FA55,B26B747D6E61D852,BA3D9F1A091FFDDF,43F5C895E37E9067,1FE61096A60EBDF4,67ED24721B9B991A,C2DA8BB9D7B0CC84,A9B9DF2AA828015C,68EF0C1A054ED24A,00005A7DAACEC6A3,04ACAFB481E892D3,6858B1EAF1536E50,40C014FAD1A39107,C1C13B638553F26C,6AB2FCEDF9DDF12B,B2DFE4D18E1277ED,B91073A9456409AB,864665AE6141AE28,2CCDE919A8F06281,4E76ACA7542E053D,722716E2D80E201E,00003DB5CBE42DFF,99B143D44036559D,06197AC3845BC7FF,7A5EC4A13646873A,1E2C48C44C860D28,065457FD7A5C3908,532E9DDF4968CC4C,3794B9032B99BC6F,06A946702F08509E,D63BB6356DAB2AC9,94C9A0B49F8580AD,711ED120083F3C52,00004DD7BF05678C,6782A5CFDB109BF5,0412F1A1DEC71D94,C01540D12F71FA9C,84D2E19EC7D2AF06,479F97F57292F492,35D67B120C2DC8C0,7260BFA07BF086F9,583A82939DDFCB0F,F0F82C333516BED7,C6EA87CF0D662472,270BE8BC53B464C8,00004856869D8252,3AF97CE604BEC982,4F4198D3EB2CA968,684379F0FAAE25B6,6162BEE52A94AC6C,3D334F0AC9CD3C3A,477991629C6070B9,7F0ABE0B48C49D1B,95577F5DA56C9156,496D6ABAB790B75C,015CCED57F8C92E3,67E6C9AF38A86682,00006AA0837EB666,5D3470714E9FCE28,FC05B1FA389347CB,4F0786259A368BF3,D773C39F03E51B6E,7F7FA72807B19747,3B2B478180C391EB,26613079D7A59EFF,1E76238D27C601F8,617B7D6BB716290B,F319B0E325626CD2,910153BEE8CE22D7,00002E673E8884F9,B0EF602C48577827,35F489BD5119A22C,09510C4B8DC41D44,0552A270DE7054DD,7A9F5E9CAA0651D8,2B6601BD1BD88240,CD8691963AC336B9,AAF064C64A254B1D,BB23F4FDB1706B1D,ADD465F52B5FCA94,47EBAD45A889AB5D,00001D7DB917E6F0,AB9AE030197EFBAB,C0251BE005AD48CA,59D8067D2F1F50AB,7D4A98B03F302442,4040D3DAC327FBD5,E85F0DD99AF854F4,8639137BEE1135B4,11F39ECA9BED0E7C,BC2ACB29355A6774,34F47899E475E25E,3195DB9295214F1E,00004377615CAC8D,8A3AE72D617D4377,A6BA314CDAAB07BC,EAF2491785ECDF06,B61C65EB14330FAB,8CD16D579DC440C4,4B7E1A3503F4505F,043F29EDB61FDC14,E069261742C74421,2EB311F90235203F,98970D3E5390D420,F65E45448FF634D3,00001EE3FE457404,56572890DD987470,2DC0EA3A7A6EF325,BB46CE84782F58D8,2DB1EF846036F60B,633F41C9A91AE7A3,2384A319C897DA0E,68B48262B0341619,78B0339791AE88E5,F337D3807F91F6EA,5D0CB87DB7C61396,D54B943E431F91F5,000053C215389371,0C280A6C2978A2C3,A2F802997CA9790A,EF79073A0E8EC852,478C6E2833D93C4F,459997E2AA736150,6CAF6F8969D082DC,A9FFEFC2784FE979,47310C1475CC4F7B,D2445C1092DCCF44,7CEF8A5EC044237A,0F5204C9CD8AED53,00004DDC88066214,2D93E9128D12EF80,5FC8157D8913C238,08CC1A560F523706,5BBBA3673E5BBB1B,4AFC675DA76058D9,47371DD460F82FCE,76C235DB6531AE1D,5A609F986241BCC5,26D5961B46C36AB7,B17016DEEDFD11F0,1123781C74D21012,00005DBFAD74F166,02B5C5331595692A,EAA7C653071A7C93,523885E2060A065D,CB15480228CD07A4,6386ECAC71F18E3F,535FA0363F3AB414,E2D185BD70A8968E,D14749A811879427,34517797396C82EB,9F838173A43AB99D,D118F6F7C2784E2D,000011790DB8A445,6C51115AA42566AB,033018C2268D3EFB,46CB5DB954CD716F,1C1429EE43AF78FC,56BF03F017BED074,759F5D77F9C43E6A,9CDD2D3839D84F9C,19EB020D69CDDF49,3540928E5CFC5B4D,9DB15F63CE1B8599,E8AB2655FB889D13,00004AB242D306AA,1D2C46288CCADF76,9854D3E366E2F635,AB808CBACA0100B6,1EEAB3037B2D81E8,181F4CF70A542493,232E0F29E60BDCFA,8CFACD9D3C9758C3,9F763BA8F8038A7B,BF854E0767E22A48,5E77B89EB8650FEB,0B0F2EDCD3B0A8C1,000039F07B2BCBA9,5990C9B12A66BD59,2711C7AE88B16CEA,B6C7769821D7294E,38B1D5A731A7A3FB,C3DCF7987E459A0E,97551B2492F3631F,C4DBE7B2F8D5CECD,EA45988393932D91,534A63DE91FEC500,8A6B81A66135CA6F,5C9BE0361F044E80,000069C9787E3BD9,BFA799111731E6D2,9789C920AF1C5388,17322A82C01A97E2,1407509DFB84E9CD,777956ADBE66D0B0,FCE8F1A87094A4F6,69A6EFE6CE513D6E,913A83BDE4D057AE,4076EBB9B2D03EDA,336CF717B335A664,DBDFC25845E0E2D8,0000193D1C2D6B62,453529995E33D066,8B5354D5D5D2DED7,6AB08EBB85FB8B74,E2263C1612E44CBD,7E50F928FF6778F4,9BC82346CDE0C405,37AD6A835EC56226,C1CDBAA21722DBCB,F2CA6186593B9F89,CD6EAF6A2884F43D,AE4D49575B3580AD,000044852075EF54,8A2632A12A3AB157,127FD6A2267531AD,D4D1516E82F7DF79,B3216E312158DC70,6269BD64339A59DF,EF12484C7F8124B3,EE1404246C006AD8,5AB3AC6F7FCA5662,E11858BF2EE29178,B01B18A903DCD2D7,39A451FA38B6F287,000002E81DAA0CA4,38B634E7F5824BDF,2E509519AAEB19A7,EB77974899367258,8B78389EADCD3CFD,EECE3A2E2E9465C0,E601C3B728F55E99,755C95E2E9D7E747,25492B992A194ACE,DC6264AB78EAC386,F9F6734C043C2972,B3ED6D192B3127F4,0000057081B5BE37,3D08D2F39439B139,62B6A57CCFA25C56,7ED035B6CF6C646B,29C38017637825B5,BFDE508202F13278,65DD987C9A643C09,2C6DD52250C7521E,74D8B3495CE47D6B,8C9E9C1E3E301A78,5DBCB179416B0891,A135F9A9A5EBE974,0000582F235A6F5A,059AF7DD01C54873,5173070C6D93132A,710EEBD74A5A84DF,49D5FFF1FC466A96,BCEFE3EBCA133BE5,8AFE940AC503B7CA,56E41229399772F6,639FA8A8643C7194,64FC827535481F67,CE504197AE2DA8E0,56A8AFB768AB46A0,000066DCEF7637DC,F6765053346C1019,8FD4F86C841D220B,57EACC2042B57945,348450B73968383A,CE277CBDB37BC4CB,D42A5E8BD9EF8295,0967C49190107665,2C0B8B877CFECE7B,549D68B4CB1BE8FB,FEA69784846FA082,5698FDC7D6AC01A4,000020AC8C345383,2E85DB292B1691A2,BBE87CF28EE0105A,F7E857999EA6476C,71EFD698CB74760C,89D22B5E091BE5EE,F4EC566164A5A51C,C7A02FB960300941,27075CB5E7A69262,3BFEC472FAE3862D,4447473ADF75EC1D,CF119486F38A6CB4,0000381B1628FCDA,7832EFF89567BF33,200DE5E135760D6B,C5998AFBDD047093,A7DE0055ED3DD761,C5CFDEBCCE3C033A,1DCAF37F18504E36,01126DE9FFFBBA25,2F404C7A7B2D879A,8C2B70CE67F00F63,97DC357C1DDE0CCA,0ADE72967D907D56,000008F3A67E1122,9A65647F1FFE9B0E,548210DF139F95BB,7306A2C9EC63ECDC,0DD85F630391C65F,5792D44BF9063995,84265E52892D0D41,2C616C462B556A2F,88F20C4D7E9B037B,C1EC3A561ADE1363,6F4602CDC108AB2E,6C1519E071A8D8D7,00005EF2D743A8A3,11B9E61F77BD17A9,7D51B77ADEF857E5,54661343858BEB2F,8FA1C8121310C04A,B487A90A23F24E31,97107BEED3266C64,2CCE692807BA8052,96376B22BB6A4FCD,6D60D8AC6FC3EF89,B2A5A73C01F4815A,32CEC2FAACA09C38,00003D3E36DC3CA1,2A040C716EDFFFFC,9A904B6CA5A6695F,3EEED080EFC4ECDD,A852B70D6B1E1D66,9C0AD67324D84548,B763F2CC5B9EAC93,D8BD8156174B5C66,958CD77A77D8EE5C,E6F0A3B47DB285CD,7460643615380F60,EFFF85DE5B4A9258,0000410548172123,8A03B4499490A005,A8E45A7F528EF0B7,0E627A9ADB424A77,8AEB93C12CD9E76E,2EB5387504EAF351,B5A2DA0AF791980D,24E3FAD900AC3AE6,A95F118199B583AA,360F9CA16C3B96BA,FAA3D0509E8F68E3,4D0208D0A8FB9570,00000067464BC3B1,8225F39DE158B042,DFCD926985CAB492,BDD9CD72C3446E5D,DA75E4D43BC76D05,496569B6221E5E37,F69CE0894CD8D967,44E532C2E2B41A5B,D2E7379C0D2B57AF,8F6A32F8289F5472,A84C87CE06ED82DA,124A61709D287ADC,00004D3F28F062F2,002F5A592DDBD5C4,40D7BB269DA6B6FD,26572038C5F723D4,4847570A702AB519,E50CA77E80D07A3F,CE931AFAB75C421D,E1CA628E6B7CB19E,F1D7A9B4747F2CC3,1F673C64E031A958,511F1AC14865A857,9DC5227F68C05CBB,000001308A131604,909EF5D191E760EF,4B8A1ABA54CBFD29,ECBCBAFE60AA59D4,8C943724C833532E,7FF5C18ACB8EE99F,8EF6DB825FA4F7A2,E7F22471F2E8C321,A23EFF40C5F6411D,B8B905B42922515D,AB21D4A875BAB8CC,DCF57EADA8816307,00004B2278A5C047,930D8EAF45414947,7657CE0D09017811,9B829F87F98A3FFB,C24A876DA12F52FC,3F6AC717C4D98B5B,D75E3F5EF668F621,2BC086FA34FCAB0B,3F018964E15CB047,9736F45A79E882A5,5777CE52F4274450,87F52B6A64ABD591,00002FFAF3B90D93,16BD4D3F055175BF,C28702D135A5160A,D7C2CC41E90D3FF4,EE0B79F8E787F737,EE907F00EF73F5F3,B2CB996D098CFB2F,CCCB9D7151FB10CD,9EE65317AA07DA80,9E648AC273CF5516,D874F9A1D37D3FAF,24CBF5A11D1B6DB5,000053701B065C5B,139497E0335906E4,955E734A34D99EC8,27CA858869FAC7C8,CB8C6FE66EDBB856,F4D3E717C3D14B98,DB7F320BA569EE8B,D7E6EF00FEC05EC2,D71068D52E7B1A23,54263F4BCA227AD6,27F737EFBC2A7A73,2C745EE149631CA7,00004D1660364C82,DE8F7774BC6ABB0C,3BDF68832DC35932,62FD8757EE02AE95,B11005652928D96B,CE067373E3BCB04C,2FB1F0CB93E824CE,75628D5B41ACD955,8D7B3FEBC778E81B,355A0D340A66DD91,15BE9DB9E651BF76,6F0218D8BA17A190,00001DECEB2E5128,32D904BCA3ED4723,F1772241584E6E55,D7C437EE2428C91E,1E5A417C4F65C0CE,40CA508537CA60AB,ED51D9FBFEBFFE23,D844E9587C618A81,918F300E90F49EC6,62685D8331C51993,1AB2829432DEBC13,C425163136C7FC67,00006BF2AE9521B6,13ABE98448559B1A,11B7EEAF24C2E7E6,2DB2A28B47B7F4C2,A619C01E671D74A9,AA61EC636E93032B,841E0856882DB176,2488F3473E536E06,9D4799A9DEA83643,9786FA3C349701E9,DAC333271E110181,A778407067FB077B,00003E4300BB2D96,005ABDE93C296B14,D0C77A7CF89C83CE,5BC9A25B8F50919A,459568DB126760F5,DAD419B8F69111BE,812DBF38EFB96D1B,97C9BD2C623206F2,D4C8C648553708A5,C8F49B350FC24FB0,4A734B16CCB2A851,226881B81D5C55B1,0000074DD9C5D230,D2C497E0A8064758,EE8B796252B3886C,14355F4661C0FEC8,6CE5E11CDE0CE502,59853406A4D98E43,5DC80D5D4D99B00C,5F176DC59DA4D681,271EE8E32DE68E0A,EA24A544628B046B,ADF957CED1C5DE0F,A2B39F6008276AB7,00002606F0C35FF9,E329D7DC628D2895,5BA8204B42478594,80F3963721E2C4C2,81EA2C7A7F745067,169CA3539C86448B,EC7898C2C3737486,AACB99326407522F,8A86AE1927019C06,750CD9936BED3E2D,460E56FFF973C8F9,478806C21A9CF92D,0000332C69F5A999,EDD919953F8A058A,FD44F62DDAD1C676,8E5AE2544A98EBE9,F87284A3DA627C92,BA5C5D1E6E492A42,F526F255317710B1,C1DFCC343679E70E,84AD1B8DC8A69D63,0C8218604C62C74C,73FEDAECAAD593B2,7F2C53FFA3B02B3A,00002AB5570D37DF,83897E0D6792A7E0,5A22C09CFD11C418,8B4BD5C228C8EEF3,739490A4F612B25B,2C0462C98239275B,45D639FA1D0A3C99,650F676F5E52F7E0,68F4DB1FBD978B7D,3075E58F472FB9A3,2BC7F46528FCC896,845C58B0CB922871,00001A3C474078C1,A8F777751C06FAB6,B6FBCAD69918CF24,9C82499B455FC288,202306838FD992E0,DF70FC157472AA81,9E5CA57C9C823EE6,D92997F7E874FB68,4B9160A55E6864D3,46BE2185BFBEF724,82A243712C26E260,C10363CA24F375EB,000024F2DE3814D5,DF73A0056FE2EE06,53D6221D9AD3B680,6D54001D33F42BD5,AC7DD0B3D801DD2B,10DA304E23AD0CDA,8B654BB5D57E6EFB,4C689417D7291226,35964416DD86422F,6985C3B69A4221D7,544F7F1764AA68D1,27C95853609BA58A,00006E69332D275B,E5F0E093C3588BE3,C52E8A8EF2959BD7,4259FAA67109325B,8E7E353CAEA7567B,10D6FD635760BD2C,8F6C28CED8926BCD,97D0C93053791C63,801393D91FE969FD,16B738BAADB296C5,3E0C0E531B18ECC3,89DB9CFE30CC6F1A,0000425746D4DA19,10BAF22693C271E9,83C771F1947B9230,42764FDFE4DB6455,9C026B5E34DC687F,648AC37FABD0241E,847A3855A9C22E4C,D7A7BF1B76842B1C,087167D2A211A379,06C9A3DD19CC2A48,6941ACB96C229C3B,2280BE88ACB0258A,00005EC7A3FEE5C5,61FBD0157D327D2D,8967F339EADD8136,71F0BBD48FE7FE52,081404BE0F6E83F3,02CFBD5A9389A38B,BB3B1E6DEACBD377,E9F03F206584C37E,6F8243563D886529,716CB2B1018AF571,D35876FEB6A3D422,3906942509C9D699,000003AED25ECEB8,7960D7871FC543D5,FD91E5E9ECACB1D8,23F774206D787999,9FDAD2B1BC24B9B7,D1E6ACA5C26A91C6,82AA8244B106768C,18ED6144010BB323,DC4C48621451A56C,C3B0CA0A6F4FF0D7,6098EEC919D7BBB2,89E6ADC62037F0A4,0000386444D30FF8,DC635ABFC7231A8B,08597031C7BDB403,D6D7884FA743FF63,7B9C4A6C8E538ACD,09F54CC546206E5C,DD945ABEF3C7FB32,4F2EA6BC409F31BE,ED28A693377F8396,8AB7BC7B1A6AF09B,0275FD9906E96038,5F37B2A34B012071,00004581E57BA058,79E89E1FE06AF664,753045AE9E67F081,65E27ADC93DED813,9CC3E38F0D837224,2A032698CEE55300,151C03D75C979DBE,C43B47EA3FC78D61,B85896007E59CAA2,1F5767C3E44C7998,86C54EA4B115FC98,48A9EFE911ABCAA1,00002F74C94045F1,61E9D3DCD42B6860,ADFA7A77960475BB,F24D7669B73A620B,4120AF189DBC1CEB,9532F9C3DE810920,602DF0E16E204983,F08FC8359EC51CF8,60D3E14DF4F7F79C,3121129C683090B7,5F5F1F6EA61E98FE,A11ADA3425250291,0000633544C4B73B,6FD385862D6FFEEC,DD815712F64DFE5A,3E30B23791D0B0E1,464331E791DA07A4,C3F499F908E23348,8E029C4197528AEB,09AD1E1A21737549,840FA8F102A84899,5C77A727CD85D946,1EB8DCEC0C953D1C,30CD8403FF9230D0,00002C436D19D1B0,D3C55F07CBEBC0C2,A07AB4C33B39850D,14AA89A0DD3CE995,73BC7AB87AA30C23,19CB66AB2F2E7399,D4B59AB2B5BD09EC,08E7E938778B15A5,153EF6D1D83D10F3,E856DDAAFB8C4AD3,D4E71F3EFD77D8BC,6593AEC977C611C0,00002AD46C8D466E,CCFC1B46D25A3405,6A5B2B5935510D3A,8DCC63BF4BD91029,6AB23D8D8B269C01,01247724B4388882,A36D64635562AA3D,D17343AD45DA260B,B965E6D5E9FA8076,8BB1F35546BB85C3,A819C016B5A4E36A,6B617126C03B991D,00002F1C1F8DDE41,B24138004D187E89,CF9C90BE4392FFE6,D11B424458BD9059,1F50BBD271D154F1,C3BD53109C0D540B,74DFB721C01616FE,A061879DDE253BA3,41E3D4794838F6FB,239467339678EB38,48AC2C4713E34474,2E783984FAFBE8A7,00006123502A151A,F4D7ACA48CF96539,6D1DE49FB5CA7813,019DB9FCB82E2626,057EF4C54945CFFC,C4CF8FCD76C54219,90B33F722115957F,37060123DAD83E8C,85CABAD029F7B173,75EB25708401DD66,4693FA52A93958C2,A683C2EB89205DBB,00006632BFA208EC,CD85A5CF6B6599A1,67B1FDFF27F06D2F,877DB77DAE7EFF41,39FC7A63E6B26524,A178FF8A0259C434,E3A8BBD6174CA574,85530B3E7F64BE09,1810C365DE92FA3E,3E80D30D619D41A7,DBA8EEFE483E75A8,B3DE0E32C7358ABC,000061B5D5627DD9,BF0A90E936E1309E,087E54922A8EB26C,E2A63C6887E5FCB7,D5C8D041FEF40CC5,F171277898C8E29D,00F0A1A46C6E400C,D1738E5B76FEB0C1,C4A01B6F62E5CADF,96217AD098CAC94D,5387A4708A29AF0A,CE802CA0BCC64B1A,0000477E9512C124,717214E7ACE2BFF8,7CFB6AD990807DA2,97852200A659DE56,B00220A2F084645B,51E31F57A34015B5,B9E6C9BCA8CD8A56,7CD29244C6055923,225BF4625D060E3E,55DF9F4D575A2B1B,E42587B9DDB61D2B,FA37EA80379A4B94,00006D10DBB88F62,B7E19561DED1E97B,9368AF08E4909ED2,4DEBF5417734EB8D,5F6F26E82780CA4E,4EBD58F702A88938,2C58C34BBF1C997A,CCF8B66453BA6E8E,4E3DE565FD386282,A5FEEA63E3EA9090,00575076610DA15A,776794ED1072D1FE,00003327FA399AF2,EC78E72D51134BD0,A0ABBCCA20B463E5,A690282D7FBFC827,3D107DA3F483B79A,FA2F0FBE86CD9A0B,231E7B52C3C3533F,645801534C609A6D,F08F1381520F2CB7,A14040B9835A063D,5B1ED86443DC455F,6DA03179692EBA43,00006B68BEF566E9,803D03EC1F852D3B,7F928877967A3C15,4CF572FB57648667,DC116C29CDE2A6EC,739E099426AF1AA3,C4E6453B051E57D4,BBDDF33D34250D61,BA721A05027346C3,1B8D432F30317F85,012B678686BC7A0D,FE8DEB4AC7DE7A6F,00005129ACDE35C0,D0B228573F780F5E,E89ED1F2D32D90EF,F27285A3C776455C,1245009874CAC44D,DCC35CB30A694A43,E7B08B33813F4EFA,FB1EA145A0DE5490,277231A1116AC85A,2503CD5CD2D8FC4C,ADE45A4B68272889,36DDDDE0224AC17E,00006406CDA7A05D,30D1812A65336D60,A4F325188ACA8987,6044E34A127DE88E,F9205380800F61C7,957E7EBA6C1271E9,08B1A255653E2336,AC6295C98D8A8999,9509E92B2780027A,C3D00E30184ACC92,F6B862BAC22CBFA7,11763CF3AE5418C9,00002F4437C8BDBD,F151F7F1CDEA21C6,35EE2FB003122E8A,BB9E800619263A09,B3CC31212F51C08E,CC1E41BFC2190E41,CD6FC07F68CD18E7,810CE5663327973B,08CD687AE0FA4A09,502E5199A344F7B9,9F26BF43D4EC6330,AEC70CCC4C412348,0000055D8C2AD99D,44C6098AD7220D48,1580D2026998343B,D7CD25FD0DE9087E,CC607B872E4454AA,7D75AA9D9835A3AB,95186E98F4AD9B12,388E1E0236B2F28A,2B60F30F2C2BC0B1,659A7E3F109C3840,692C8DB2B533EA63,687AD799FF9BF440,000066DA609B6076,96BCE253A838373B,77F18D9A5E742989,268E9D9A6FD6647E,5200BAE7C03674CA,A9F7F0292FF30104,8BE26CA3CB2A1BDE,B288DD754597047E,2BFBA4DCF7F759B0,96F5C4C46D371330,892E6F587E51C75C,3D94AD13338E0826,000028D39B735AED,08D3EB72C2D8E4FA,C8E0D8C64EFE9945,AE1A3937C8FD5740,35659055CD2A5439,C19EC8028996D3A6,BC2CDBF47A1C396D,C22DB2A4EB2751C3,4E95DFC2F727739E,ECC99331BF227B4D,8486AB4F92DFA3AC,CA1D546BCC58FA9A,000028276829DC92,B743989C195751F0,1E5E5AFB1E1D65B7,0BF2FB2D7DFB7CEF,F0129B3435D92190,48D8A1F7972A99D6,5C0C8157FD48DD48,0ED7BCCA328264CB,C12963A776E34BB5,2E61B58E793E39B0,27808500D33E7382,DA395B081983AD70,00004219ABBB69F8,0B8B376BDC2AECB5,1F1B5FF782E236CD,D560924FDDD0FB3D,C41485F870C2E18B,64BDCDAA3A696AF7,D06B436ECCBABD40,DACC41A6EBD40AB4,90AD29CC2D73B468,C7D6CECC7AE9029F,253FF2900E38EA98,D3A349AE2ADC8B55,0000316565E4A319,A6980BBD6D908656,17CF695B2BEE57E6,BE99C65F44637D9B,38E0E4A9CACE3001,2E019941DF3CABB0,178CEC46C128572B,16390B1C0C68B8C9,216F52BF3FE28FFA,E933579536D63890,116F2ADACD131341,52C00A33A19909E5,00000ED43D4B79B4,44A4AB97BB18200C,8D072B15EDBDD5BB,6FC7BEA3B7A54A46,1F82B98ACA006146,DE94738E6C3C2F09,8B5966BAEDB5426A,03E6A605979410A5,C94B594E7FFB7592,53AABC920752508A,94D77216537695E0,7C2395A789A01235,00004302DC96A87A,F1F350B2B6AA5BCB,B59AFC33837E50A7,BD27096DCCEB4156,D1BD778EEFAB4214,A97B71B34EB3A0B3,8855F162C45E3AA6,4C500BE9FA028E48,1C90B4460563DEA6,A562C0E90CE06D71,7A69111A437CC2F8,69C4DFAABBF6088F,000036BE9D3A9CD9,2A29407CFEC0829C,7DC07AD75EED6B1F,374C9EA361AA5A0B,B18ED50266FCA693,0BF1FC08CC18A678,F9C7516035747A07,237FC55D1BE2AC54,AEE3AA5BA4E4D891,566C947E4F09E454,E2260746C4E67413,3264A5D31102E2A1,0000288334D37B4C,B68980B535F758E7,AF8C048BAD4C2E8C,E67AF74500C01D02,CAD5CD8924B73B32,0C83863B8BA0CD3B,F1A186770A81E38E,755C759CDB87918E,193385349EC56581,68AE48F7FFC6198E,B0F824E5D1B10FD0,92BC2A8A89C3B7AB,000006EE6474861E,7621F24611B2AC43,6544024E16563BB3,EFA0585D35547625,40033FA6D794BE1E,AB08C27CAFB10641,ABBECBD0B7C62AE2,83D09FA52BF0FA14,0B39F425AFB3A711,85260831CD43329C,BAE26A463012C7DA,92E9BDD4D0B9C107,00002643BCB70182,CEADD88FC7653680,7B47A978C6762D0D,C75AF284FF67C02D,C74E754E0507DDA3,7EC35814EA641311,04BC2711CD648981,5C226C85C1F7B9E6,F4A4CE28F92DFEEA,9C0560216C245649,F4F5BD0FDCC2E1EA,63A10D7BFEC84918,00006A557A04FD9A,98438249CDE37496,0EC97EB1B56062D9,53A8151A61D498FC,6A5E1C1120A0E6B8,6C625B5B3C2C6C32,78C66A8722F00059,739F1F49C8B5D539,F8D9D855E68D0AC4,3C157382C3117394,42270DFBE3514D3D,D0B4A9BD408E6215,00005434852EC714,B19F78DCF5A70B1A,4877E5E22495AB1D,89B6ECB50CF1342E,3097C3538CDA92B4,F4DB47BE163B53B1,B477629484C7AFBC,446FFD2A2D7330A7,B93B73C786DF92BB,CF8A845D4D4EBFAF,515A98DA48C0F659,DD22D51C9F97743F,000044857BF6509D,79D5EDD84AB3A90E,2A0B250F5405E635,CB3CB67A0BC763D7,71EA52DC5B0E2796,8BDCF0074B8C0F8A,1AA1CEA0B9F2BB7B,3B62413175665E64,35CF29186091D97B,B24042FBE807C999,25B05CEDD84E08F0,D488812E01C61AC9,00000AE2239E1419,87CF0BB4D5E7B367,B1A95E3B6E929DEF,74F7504E03519D87,91DDFB897298383E,F3D8E1BB397FA78E,2F30D071BCA01AE2,87DDA166A8F8E89D,6D51A97BDCF7D9B8,34DDFE3FA5055EA3,A31E75FF9C9C68D0,92507C8574109AEA,000039DFDC876954,9758F5E9CF2C5B98,E2967FE0379998D6,4A20D830AD892083,9247492E41FE456B,20FE33E867D9C776,1B06A98E679DBD56,E7AA6B101635594B,AC5F2B945752185A,CAF21400B584DD5F,D90C3D3322EA162F,40746A39F081C1CC,00002A3A3A06C4FF,E45C1B1F2C646C39,9D0E1341BCF3F9F5,E6F48FF46740ECC4,93E1F569262A8F3F,381FE3ED550EB80E,8FB9AA722A658A6D,5C9FB28D486BA21B,EBA7EBDF50AF2F81,5C185B818460A3B3,24680671E93C17FF,66ACEC7B50F1D42B,00002DD8F32BDFB1,C2DBD9CCF5C00362,EEED870C85BE159B,26A0ABB4D0FAF3E4,B7FC5D66BB6A4E67,E8C1A48E7BBFCAEA,7359A50EDFC1C5AA,DCA6D0A67EEFCFC7,657E3FA71406C40E,70D2433590CB2D78,AB9BCDCB6EDB7D3E,E00F6DDF504327B3,00004AE677676C39,0833912A2864166C,3C2D7EE4A62A2702,3F55B120E893857D,9FFFE1D15A06C9F1,ACA40CC3C7578608,92D2C28086D9D685,BE5AFDABF1FD8966,1E6880C759A866AE,0D5D16F7C187091F,EDA9129DA23E5266,59DA792D5A02B615,00004576A0183CE2,FE5D546B51BAF0F7,5E43EBB4641DD8AB,B5E8DFC6BFD9F198,3D9B4BCC72CE3F84,F2FD55FDA7159ADF,A7429C3683955EF1,B84FF1E26DE38E41,94C25B0A63C5E364,E463EBB8EC2F218A,EBEA97FFCF07A3AC,BB3C941051FE95C5,000061F78B399A73,A942AA14A095B80B,4040CEA5D93181F2,3218CF52E57E964D,DCFDF77B9ED2ED7B,E72EE8975BD225BE,ADD978222F2F7A71,E09CB4C3C153DCB9,48B8359C675B051C,9C20A39F8F71D36B,8D0B899F6620FC9C,77F78161D5FBA624,000006B0BA283601,9902389E7C858DBB,7574A4C9A86C1216,46B82C1D80BA6082,C388AD4CF5B6C16D,BBC08A033E119F37,16C77726EC6E2483,DF41C4F37CACAA3B,EDD3994FBD6E6079,7F468DB510CB82A0,491AA90F72592382,220CC1AC081EB0DC,00000FFEFE5513A2,96D40BE6EC757612,B8EAE5ABDCE51C3D,B00D60E90483BAB8,6E5491989770B523,5649DB7C9CEFB461,F6D55A4455CD9089,712FA79B5CF00EFF,9FF9B47FD06EA6B3,701FB4197FB63A92,DFC1CCCE779C460A,DA604B00AFF5895A,0000023C9890A1AA,138806DCB7C83554,F79282A529F99828,0885B24D974D3139,9742B9C6AF6A69B5,ECF5B9748F8BBE7E,F1B18D2D0D4EB4A9,AA90C09C9DB92124,DF4146BDB95A8A3E,B51902178AB571AC,2318843F53FD361C,8DA6132702DCB5A0,00003C525878BEA5,E84CA6ACE6D762CC,3CAAA437BEB65450,6F1E26832392AC87,FF1A29BB907833CD,44A9C134D5C464EE,6982E7569D835DE3,0133984DABD03ECA,AAE7D0F3121893E0,0604A96E1B9279D8,5718B69CFF4C42BC,3A4963642EE0125C,00004BD14201990E,67953B122DC420AD,48592D53722261F5,A1E272210C4B999F,C94910EAF0AE8A6E,E9EBC8A017555529,E297693409E0726E,F53B98377F868EE3,75510CC84592A98C,24EBC2A3795B575E,00A408BE5DE7D5F0,2585EE9179EEDBD5,00005ADF8A2BC7FF,E38A0EA412ED40C6,C793BB80FFF384B5,55076DB8D6DB2C1C,6B21116C4C965BD0,20C79FE5AE699501,52500EC8AD08A19A,D0FBE674A894D08D,FACFFD6354E216D6,BF41FC0592038293,5950B6D05D59D76F,03F435AC043925DC,00004A7601E04E1D,3B6CF46E4683D07C,DF0CDEE030D2AB5D,9819FD9E61199229,13CF6A5B4C3DC3BC,F6538BD3EF80A78C,323D73F8EEBA6B35,B384803DCB4D113B,E3D6BB55CF50FDAB,B84AC919BE0A285D,22DBD5469DFB32AA,6447C269E72690A8,000041AA40CFE372,CE50CA635D32B18A,2A1AA5F01E82B0CE,F3ECD17CF0E936FF,0B4B12485A9564BA,5E3F9C1F0AFF2258,AA39999D15930DB0,223C5675ACF4BCF8,C1FE162AF4C3EAE1,06A674BF5B46BF36,BAC6ED4A324A7BD1,735E4001E25FFBE9,0000541E8FBA4C39,A1760B4DC11A7CD0,265D3442CB2DD7A4,F4C2574D60E00397,9D6FB15583050D6E,D2B82926C13CEE7B,2419B02A3E539F5D,5F9EDE8FED1A6DA3,2E7E7AEBA9D23A6C,ED08B64D001A6A9E,9EF11C515560017F,0BC9A583707E936A,000056570383D422,CA4BCDEC52A8C307,AE4867E376479480,B010D63C91584FD1,3A3A3919B603809A,912B6427A6FFBAC0,621ABC36B84145C5,7AE3CE341ACB21D5,0C6F5BA1DD16D1D6,2580BB2328F9C2A2,61AF50FE73337B6B,3127579BCB01267F,000037FCED44D733,66FDEFA9E91EDB07,E5E976F4C5B160EC,86D37C5FF8B6AAC2,41C77547E419BA90,F6ECD696CFE8448C,571C7FCA5BD377BC,868D460A4E769639,3F5F24C826EE37A6,FCBFF0CB6E0A14A2,7BA3C7A0469CFD20,FF98C3A5A6C50C5D,00006D931D8BE329,27C6D2FEF8FBF705,EED8A180CD7401BA,D5E303C722435C5F,E24291833C5A35B0,FD3EFA069CB7B2FD,D52AA64889C6551F,AE75B5A766757713,E4272476C2C14AAA,8C3CA5A768B802EA,8E33EB3792F4EA99,EDEEED3D786C01AF,0000443F9B352E3A,FC0E7979749F43FC,E2E977D48D4E92C6,06609B426E3EB2AB,6CA5097A880A9E48,67A9A527668D8FFE,4D82722C9442A6D4,71B9F735CF50E741,3A5EE81008CACABB,1104F513986B4AF8,5930B31E0B2F306A,33C5F8EB42D98516,000066147418D2C3,28C7D4C1B240F654,87D833036D1535DB,CCB33DBED4D5B6AB,9CEF3C27035A4194,1F75C2992F3A5E26,DA9AEC138D77FE4A,92D05BD5B382EA72,893D1E88092B8F92,59101D235319187B,AC68A222C3231D41,87A699FB740D1904,00000B16FA69F304,31A557A737A14669,59E1A52B524B62D8,0B8634881840ABAA,AD4975E3BAFD06FA,276D2265353AC1F1,17E1FA4F18E9829D,62AE6FF7DAC3A507,EA9854AB1BBA0431,0236A868498D24FB,F25CF67083D21031,08429C16DEA68D44,00003AADB1481DD5,1F56297A97D87C53,E6B8F05515054846,7D86EF2370BAF2FE,0B424DE1D71D13DD,5DFF03EA630D7268,7534583D6F542A6A,8D76FEEB3FA48C10,BBB58FAD9527FFD7,31E86F697EE080A7,8C11CEF94B57AD77,234DCC106B285E06,00005ACF9EDD539D,6A68918D7012B1B0,196D1597935AB5C9,EA78F8B0700195C7,EE29756732CEE142,9966124808D87040,2B30BFDC20F965A2,E280DC091A1AF433,014F9F77655809F3,FF217E35F4E4EDBE,CD4F4A31C061DD59,D6F80EA1EA4437D3,000020CBDBFCAC4D,0089F9CFD1C68672,81F55805AC82A3D6,757E8FAF47B9F523,1BE161B7B5EAD06F,D50329F3406D6B44,20A79719AC18BC6C,E101F8DE37A81607,7EE63E2A8BA2FC3C,522098050A544D7A,8A343FA95013683A,2858F221584DB510,000045DAD5B4BDF7,661749E4237C6134,187B0A38607EAF8F,84C3DE4363A1DAFE,A87E13AAA5126D15,BC5128306D281747,DF66AD0BC71372F1,96EF7048D70A9D68,4A24F0018DE529A5,4CF7DBFA1FC56E0E,C2B83A99110A060B,82B7DB9C6B8350CE,000024FFE4A440D2,8DA9F299B6397F5D,8F338A7409D46285,7554A77F1CDD64D5,68DE4CDCD05AAEF7,216C083D97572D3F,AC212E889BDFD20F,C80D55DF000AC01A,12B206C6D0D10F2B,BFC19790CD5F7D7B,C9B9CFA2ED3C95C1,B828867B1B6DBEDB,0000152E3F0BA88E,399E6944A888B6F9,BC5A1CF2CC723FB7,24D71667E4CE370E,8528C5D5D403950A,44BA6A49A81C0042,8BDBB344AC212C99,D2B06D0398B04E46,8504AAE521AE8670,9B252D4432D5AA6C,06D1CAEE9F0588F8,9BE4A65F654564C5,00003B24508DB713,3DD2482B3E5463BD,B6D83CEC2DDEF9B0,7209681F09143A7F,63D86DC8441257A4,F7AAD116042176A1,F5AEBBBC182E9DDF,6980703B3EB9F8C6,DB4F765EBE61F352,BA13DF4CA2A654F6,19B49A309227A7FA,581939A5BDBD4806,00003633773C0E9D,AFDC815190862F1D,F8ACB347AA60B8B7,6726FCBFC97C6E11,9DB8A81B02EC386D,A0A99C9D215EAA58,059CE7E881F2C6FC,8B3852382A483030,E37F77DBC78CA391,1E729468571B237C,37ADFB99F11C0A58,E30BCE06F5B6669D,00000006FF0D8959,1F6CC0DFA8FA20CA,466A557D5BECC3C4,246DF8457A5C66C8,A9FCBEA5041E7325,1F40001D21F2F80A,446B3371F80C59DE,A01E4DD6A2A30CA3,5A0B0468424D7207,B37CCEA64D94B604,79C8A68947371435,EBA73B0845243C29,000005D8C308C44E,87E17E4932142531,2381043429509405,6285C3DBFE609547,7BFAEF93FCA5073F,570AFD2E004C819E,F3845842CE7AA30A,E3005746820E6526,04A0A475F89BE0AA,C19AC7212D8D0023,7D462B33E8091AB6,3141A34FFFAF20F1,00005ACA760EE357,AE92E1FC6FE3D13D,6632C309779FE75F,FDCE72D2AEFAE038,6D51BB6E8809B38F,61181A73A467333D,AA6F8A834AF972BD,A50C375B983EA58B,187755958B36824A,A1A78B57D098C98B,8341E431960DABCA,8A7302243BD7DF04,0000222EAF20D4E8,8A0F05490F164AC2,2EF194250AD7D849,1F0B04FC307276C6,B66F2A113076AF98,317F2E2CB5FE2171,1DFDAB907CF9B0B3,88976AC8B54096A5,A323FA5147F019A5,E24D693BC55DBA17,9495E006C6D359DA,B711CF4D6AF55F2A,00004C53775EBA52,FCE6E5DE02B56663,B58065A98C537347,49E5E2D6BECA3738,AA3BFFE9D16C986A,98921E38CF8C7B0E,31B5BBB00459DF48,9CE1C9D6055FA904,D6B2FF8500D2B920,7B62A6963D2D54C8,738FC8477B72D473,BAA77DD052C4071D,000025E2A7CBFD7C,35089C99742BFD53,D1E23350716E7986,BC84AC816EE680B9,DEB5C4E1A35FE237,0C1289A2F98526E9,E37427AF031AB4B4,1218F40D49BD7AE1,CEE5DD0348DBDE1E,48F5D1DAE208AA41,3D6A7C7EBCA0FC9B,607E483D8E3A168A,00004936FAC6ED18,70903E89FE9954CD,434ED5C0A7F3C6E2,60E6253EA52CBF5F,84D4C0535D9773F1,961DC25B42435C9F,F4624D6EF9F86F64,CD5D60557BD2B123,7603BDA70D2F7926,FF2F6D1DD51146BE,0CB6BD476ED39C91,3ED056CC04CA72E6,00001A68D3540FDE,23A9D768C64D0463,3CA352E7C43C98CB,1226D3BFC0F2F434,A63EBBCBC18FEB65,715C4996A8D3116B,BD49A23DD32BF440,F8C66AE74AD2EED7,6C57EE6114C1C8B7,FDCE8FE39A1B61B8,1C8B3EE16C684966,4786CD067B91F74C,0000025F76B8420A,E3C477CA05CE221C,BE7EDCF171B0ACFA,B1544A0D2D3D7AFF,00FA7CDDE9A6D5C5,F655981841D7455C,DCE043F3930840B0,FAC59457E2AAC09F,549427F44662EC5C,F13B7D316E44CB18,0C033CBB809848F7,8D829ECC4D0FCF75,00002210E3A7581C,21740369B045E294,FA4BD68C7660FEDE,AD47E43152CC312C,70D64F310A2FC3C1,681ADCC230B3C47D,A11C67AEFB1F6976,24D4A38E2B964A5C,A758BD7729910ABE,3DC5B4EB5F6708C7,EB3EF3DB65EE8503,BBAD52C57D75F45E,0000109254CDDF60,D5EC24FE76FAE4EF,1194A4ECAB8CC34A,0BCD8DB4A5E61C22,E079F07FD49BB9EA,11B9875E33482F40,FCCC4D350B55ABD9,6CA29EAC7E56FDEB,AD3C86866946D92E,AAE4971DD05BCD50,9F2FE046D6D1EA6E,0A49E529BB1110B3,000003B66308873E,B2060D21C93E9DE0,60EAA36818AD17E9,4D5CD3F06EE71D10,39CB85755B4B5BBC,3DCF832D2F2E9FAD,4585A1CCC2FA6E93,E8F4BF61A64DA7C6,905465F0EEBC2CDF,708411AA13485044,D3C1FAC216F1032F,EBE4DDD95CD628DA,0000299E0097D375,07EC06FB1DA25FD0,36D0A52A81C11F95,F24225F0C9509DE0,01546D79827F0294,38B0C98635B7BC72,621916E1DA0FE54F,459FE8054F6ABFD2,36EB357171647E61,4F35660BDD692A48,A0F38149666D621A,402FD3CE416E60E5,000014FB26803D74,FE86E1F54E325CB3,292503D8653B64E6,E0A24D9DB9239829,A5573F56A0574A09,FF15AFCEF6D5C6AE,6C39FAAF6D3AC63B,E76EDD17E33A87A6,5B2B49AB7E3FA497,944FB6C6164DC1EE,923DB4DF335DE57E,4900F3CF001CBE56,00002C0D13A93405,37DD8B3D5050E3B9,F6054D11055004C0,CD02ABDC592481BD,ECC24C59CC68DF78,77288A7F1C4FBBE2,93A459D665284040,A03DC358ADAB7377,965A560134736DE5,3EDF506B96CBB7B0,C2C2755FD84B3E2C,45049978A8C4646D,00001BABFAE07762,5AAF0D159C5E3DED,98EFD0CD8D0C7F3F,60A6259B3CAE4039,8C338547A0D85CBE,E8095AECB7F11C7F,17CB78D80199CED5,9C06DB684603867C,B6FE0BBC71E26958,4694205111536C1D,08E188C3FA06541B,1B333985B4BC3BAE,00003C466774DCC7,DA7193F67509C4B4,C4899126BD98FE7C,01F87977DCE81040,EADFDDB6DDF59C2F,8A885EAC36CF32D4,44B8DA796EEE2AD7,F69914041E7BE982,6DA30CCF557E0B7B,C61DF72CAA4BDE33,B8C71E31821C5D77,DCB399E140624102,000017B2E144520F,B5E7A2A6318367C5,0867E5E70ECB7698,F81B62947DADEDB7,924E43A5A04F5F8A,E48F6AFDB65443BD,97C3ADE58B721E4F,F4B7CB3D58028F91,5EE11C668E4C05E2,2C3E3A30DE724007,34A5C517C0DF1B2B,C03A6549FC720D39,0000143D1F5EDD2E,DE173B37F324AA5B,FD6C08F68FF01329,2C663BAF1E8ACB08,67BAA60E8ADC5934,46880EB631426545,3144321DAE924F53,75429A6F384392FC,4D25CBB17613EAB5,5E4F59E1DAFE1EB6,CB928AEE0BB202DF,E32445E68D207504,000041F313FB8B72,FA1F1CCCACB5F6A1,345AD1CE025005FE,6B62A5BA5353233B,B66BFF14294C467A,53E7ABDFE0EF33EF,1BC3430326262D32,17A53D0E42D88CAF,865FDD772B70A96C,C804F3008D67153D,E7DCCD84C6DCBFE0,0AFC4E554CE8A715,000052201AF29EE6,555603C811B18468,979472097499E852,E07853AC7202DEF0,6CF1BC6823F0D6F1,5BFF88DBEC4A9EE8,904A6D92D39ACF14,8B77CA650C1CF095,9888E2D9E6FB5B71,DDAD376037F32814,7D70E39894C44CA9,059DBA0EB78DA7F3,00002105B8E67FF0,E15A61741BCDFAB4,BD27300B0DBFD414,07C424D7152FB00A,2FF30502E161CFD7,37033626C808EC9B,5A74CD60972C5537,68072C5ADDAFF697,4B52DEAEC6A8A64B,7EA8727DDBFF2C5A,E11FC8D4C7874A94,ACD18F4DDFE93377,00004D6910E3AFCC,A3A97FD74FB4BE62,A449D5357659F717,67F1BF86CFD95E49,2B50BAFA19B8F1AD,4CEC8DCC835AD777,5E11F7ABB5FC93EB,60831974568A696F,E7882CB98B3447BF,BA0C17D230522292,9E332371231826E7,F836BEB510A387E4,00000B99AC09CA30,F0B79E4704E4A1E5,CE745A2A191D9413,9B204C9EB3B9C827,7161CF4C5F9D3943,3467EFC8AE3BAF56,6D091B0A6664C38C,E7561E516AE1436D,4D09EDD54857C9C5,88C7EC102F358F4D,A37932AE72B2FEE9,65CA1CA2B3862E03,00003647A1C8E5A6,65508961D3FCEEA8,34D0CE732C52856A,EAA8A5D731315D17,07A76AE3A1C4D6F9,7492B89D79F05AA3,5227CCDDF99480BE,304725D84226B5FC,5FD49932F8AE8DED,32D5DC902AD8475B,B6A5B544F77B15AE,11D6C0AB3654002D,00000BA6872DB439,E2D398E99E2CC076,22906C52B42BBF5D,17C40C39B9E12E3B,83AC33E2390B0814,4A66D51E8F34B88A,F1A9ECE69B79CC5F,0E440F6E29F85106,65EE04F59E50608A,2F0BFAD6E9060882,8871C4150FD9804B,2ACCF90016425EAB,000011F54A108268,7C18D2DE33FA40B4,8D0AACC08D0435D5,B1729726E5142C46,80B6689C74FCC1C0,C0384E12CB346932,47B406DC70AB325B,C6B063694A45FE9C,35FB3BA18A7F0F13,6FE5F78AD74CB1F3,A345A5A0D656C45A,CBEFD77329194C59,00000D56643E1612,93EB6EFDA6040C4D,93AC6A0049E9108A,F09A3537F747ADED,3457A9EFF0CC3951,FB4CAE485AE2EE57,921D1EF8326FFBC5,2AEA02D55AAC6458,1A93ACA1C5FB7076,0D465BA261866931,7A203A68E6EDE6E1,B04AD86697420C93,0000596AAABBE1A1,928B988D148C571E,5F6F941F9F42CE24,E0AE46751770E81D,73C2DAC71476EDA6,20BA0E9C8BD8222A,5ECDE89A538C72FE,2E20A55B641E41A1,470949C55C0771B4,8594FE28772C579D,365A3702C14DA40E,BBC4FBA6FACC053A,000047B62CA5A179,FC11BE59EBF4EB23,E3CB95EA4C3F0F7B,584446F3FCD271BE,F8D1CEC8494BD9CA,87EFF08057036142,4B0DE8EF83579A90,CCAA74E2FB48F9D8,2CDA3AF00D8AB07B,54E039CA2FE65ED7,0F2677091EDB754D,787B795B099E3754,00002A666D4F1071,9EEADC0AB7801162,E42BB1501729F9F2,47FAC0EE5112FC10,936459D7B12688BB,77C5201E02F3B500,F66B3A3822C34473,0FACAEBCC371190C,7BE25DA7254C3802,B48E74F8C5EF381A,F2F64DD50E95D0FB,B637BD07A73C8749,000021633376EBDC,A142E47287E0582F,EA92056F15197275,0A017A013AA601E1,CA5048DAF2916DD7,F65CA3807E5B35AB,385E30A02BCBCA1E,5BA15FC6DCAB625B,350186CA20BF4A6A,C4E2EDDA316DC66E,5C3474D16D0E7988,34A9B4492503FCB5,00006A81B115B1E7,6A6B82506D5900F4,84255F7FC3BD088A,61F05BA262D17E3E,C4791545743461E8,0C46C428ED1FD70D,8B926AA98F8B835D,808761E0F5AA067E,1AB7E0149C6E20E7,65958E617D118FE2,DA873C22F8F33804,ED276FDF2E1BFDE2,00001FC0EDEAD4C1,E57ADD1BE7B3CC03,EDC9273AC5D64603,755EDA61E09F37AB,2837A673A9EBAC08,B0CF605D278BF40E,857989FCA26B3806,6C96F58D1478DE00,C2257199123921AD,170688A1380B4312,48B03C85C0B93893,32352F1326EF93FD,00003461798A6668,E8AB1568CEF4C9B2,4A4AAC7490C8B0A2,F06B63D7845E9F7E,8A247D1B99D0058F,7FFEFDE31607F888,FC6CF639CA8CE5FF,74F6D09C3E3810A6,501A2B1B1F765202,B247189C385CB1CB,8117BC0FFE2EE5A7,1D9E707A1805C8A2,00001854B3F66538,C63E6382E9EAAE0D,D61F5C432811A69E,16C1C68A7F21FC41,AD6EE138A51B900C,037FDB4CC488156D,02E3371908C29F82,1D8FC010E62782EE,25353B0205D1FE3D,AABE3C8AEC28356C,72649AFDC5E1E37E,717E9DF977C7301C,00004AFE40347ABC,B96F3050C0465363,CDF6188B362F5B54,A37AF5541F7695E1,791F68013D39DE28,FF0560668615DC82,0DFF2DC0ADC4A936,A6BE9983F7A66E16,989847A1B7897332,503DC6D732095EBB,C18245C02D7A442C,3B46B66669794ECF,00003D2D8E41CCFA,9A357CE4EE9BCCF8,113863E032A45E39,4FB9BD11C4DACC1C,E58AEC1E0BF9FDC4,D775F69B1C458C7D,D5F46BCCF66A8292,5476124141801663,ED15241E5483BBD6,9E06B4F06A2A07CC,180123F6DDEFCEC3,69E38D2B0AB42F5E,0000097362A09617,7E7FFA76299BA421,36D726FE2978425C,32588411D1647EF1,FA8988A9769143BC,D199D8D791C64D31,BCDA4F339F8463F6,B762B1ADCAC8B24C,4960F511A260ECB6,44B41EDEB3252984,D3D956FC63FBEB13,2A088C097CAF4C8A,000041D5D6BC9739,C73F5E51857A0BB7,BE7E0B86CF3FC107,CC0AEA29A88B837B,DB9509F2EE255B83,E98E857C5F550BA3,2A6F2AEC7487AB84,1F8B29CB0F77FA4E,CB3ECE424764F323,B567C2CC637971DE,C97277F079654EE7,85260139F390E651,00002C1696CFD8B7,ACC65D1C9B8B8586,A29D1D463EE2FAE0,AED2F86AE8E8754E,56440813EDA58CF3,CA387DCC5943F4AE,E1D668D5F3D40731,68F7E6FEA8E5999F,083662C3FB435B8E,96D32AEE80414F5F,D0A013A252517F12,DBEF4E0BDBF7C5D1,00004A18BEE03107,085D34011F70C393,776C940B8EF436A7,4ECABA6466CD6D22,CA48439CE99A1B35,62FD97C0D02253A9,81BAE1131D5AB659,6C36F9899B80AE19,3AD00611AC8D32D9,899C84F8AC4591BA,E24BF199B9D4EAEE,C666AC1C5469DC19,00000A76DF57C089,A20038B24FCEB319,77598EFDA63FFD1A,92752239D010A993,5C79CD39A1B7171F,ED75073130E4FAD3,C5393FEED24493CD,9FD395715ACCFB65,9A51C209456048A8,9612E0337C212454,53F1A68548319B93,37B81823E75AF2A6,00000CBEC4E0CBB0,FF43DC0C93EA8D9E,04CF744243F19C12,5269E579D4E31BFD,D6104A980027423F,19E2028BF11C77DA,0866CD4853947981,6D1DAEF77F60ED3C,EA22225E939144B8,A14F81A4EA4BFEE5,F2BEA108C92A2A0C,C9F9CD0B9DDC8C82,00002AC0DD4A1A1D,98B1121E2F10CFB1,4512F0679AB83956,76FA790DAE8B0F00,70DAF4C02D1F4095,204171A70B9C9774,DFE46E017406AE40,773628D8C5169643,0A69753F9A42B40D,1D73F2D407E230B0,DEB05461060AADD7,51D213E0D7A66708,00006C5DEAEF033E,CB9E5782A52DD939,5D0E33223014EEA2,03A0F5F64F030979,178D18E83888733D,38EEEDBCF53DF32A,1293D75B24ED821B,4339617FBAF6AC56,EDB270784B9E1136,EDF92C48C669F430,DBD0E8583AD02647,212DA4251F43B96E,00003FE389B56537,1936D39BB9606E35,2B197AA1DDE9378C,B217652C9B675600,994B76384DC7B04B,2F7537F4CBCB468F,2F7163B10ADDF845,A32BFB3582943600,BE88E76FB1466B71,7882E6F2DEB48B34,9495144318073AD8,64DD70E4280C3168,00005ABB7A412D2B,B67AF973207CAC99,ED346ED7A30775D7,62D0957FC826B449,BBFC711B5DDB4B4D,347EBCA6D6DB4306,43805640C6981FA9,ADEA2CCC4EE9E1AA,0B75C9417389494B,0D34CF8F87CD9060,5C20FDEA9202B825,E9705470B6175B87,000067F27894E9CC,BB0F6E0DB5BD47B4,8D39AA2DC0FFBCF5,6AD60168CEF688C9,B10B111FE0B5076A,FC1F72222C062D25,8A1FAE49C0752D86,97C4F50E9576762F,8E21F439DA4FD5D4,47018B4CBAEFB6F7,8FA7EA6561011737,01A848328DC6C835,00005052A84A0D78,C6233ECADB0DB6B0,4414D62281970CBA,C6BF8697B4237779,0E632582C9797104,82629960C710E265,893E79458390AE88,00D92661F4132C42,FFA96A8E7EAF24D3,E5B7979DDBE8798E,F0E0F82A453DC800,5705B6F4AC629E39,000010366969B109,6F7D51F865432A19,15733819991C81C3,7EAF906C105E9005,D14A46800B1D526B,79D228519DB426C9,0CEBFBB43E781C25,2C230059E4C6D325,A8BF7465DB65E923,07144CDDBE5FE8EA,00B69DFEEAC21EFF,1CE94557E131E9E6,000061B1553A20A6,5921F9F6A79B0461,AC9BA8E6E9ECEB1E,1C40F3F61E02F19E,5948CFA12B9CB0B1,86CDC865A99AF06D,52E782B4C80E5A88,BAF2B493053CFE85,96BE64AB8F87612A,5F57160F1AA00FBA,0F1AFEA815E104F5,D652E9A07495E347,00000B8167E7594D,95CDF3419A1601D7,23AE11CF711AF625,8164C34EA69A2B30,06FA539E70E3711D,43FCBB77720D8203,AAD8B512263FC986,678AD505BBE78C20,13F743C18602E605,06B3EBDA83EB81F0,546501DD9E16166D,C71CB33EB8695E45,000015320B1B4B3A,867A7991FCE04BDA,818AF6550190F537,A5F94EB62E6DD5F8,091CC6699201D8AD,9AD3AA19DB10AD3F,6F7A1DC4A05836CC,645F478FFBEF1589,E0B0E980C5606622,4A1D8E777420EC97,83547BCD31858B4D,D3B55C695EA17D89,000065C08288007A,DEFF7548CFE90EB3,A407B745FF087A42,55D265CCA1F3B1D4,09E4CE6EA5006AFA,9B0D53BFE026E48F,395B0146B128EC6A,A58E96121FCD7149,69E598EE17850154,C115B944C5559B10,391B2A1A20465C3C,B22EA4A0ACD396D8,00002EF7C2C453F4,570FCE48BC0F296C,A1E48A43CEE5EF73,B855B2B136FFA242,F525D4E7CA844C91,AFFBE3A40D72C610,AA28DC88675E9962,4069DC6B8D1A65B4,ABE68001DBEF39EA,730E1A8732EE9426,67903904A9E8DCE2,F60A9E6A7C991148,00005569244D4EC8,C48FFE4B42F12019,4A97C627BDB91387,4291EC27D42EF787,F94EA50E42B0093B,69E33AA28FB209CB,96C99E7DC0F378A1,8EA1EC0A26BA9F76,D92ADF24240E79E5,10C83B7D195DDD80,E96F5C5C34046F17,675FA429D09EDC06,00005D7E72FE7D7F,57BDF09EA2C80595,A6C57DE038E965E3,2D46C1A0EA400780,893CE008414A9377,CD8B9F2F19A57F64,50E27C35FB6B3BEA,406E7E1BA6C96A7B,F7B0B0DD014E15B3,4C86F395E5F1E6AC,D216226020641EA9,A7478B1DDAA4767C,000033DB3E91C96F,ED6D51346D1E164C,F7A91D68DA16D9C8,1687FB0A74163FC9,561476C1027942BF,E18B8C791024960D,ADC58432E136D945,5B9352C789F76029,04B4CFD0A86BDDB7,814F7FE8249A4777,59758EC2ECA8EF69,289958301C8BA6CD,00002E3133C83DB1,D22B566F3E1BEF69,4CB0C8A010C340F7,38FD1CC56BC26D4F,69610B748861A5D1,EBC16851B8069D08,AE2BB67CB79ACC84,D1B3DF9CBF9ECB27,C9654B1962069C1F,3FCEC51581223A7D,CDFF44A08E9F2508,D21A39EA4A7F8AAA,00001364612344A9,9A98C8203D6D0BC3,0D074C7994592C73,E41EE8C7B42B21B5,3C911D86C51D2CCB,708583033CCA16F1,F89ABB4A373408E1,3516A0037767C57F,7A18ECCBDAAD912E,D9411810CA96B438,EBA0F5BA22B7A189,DB6590ED957E689B,00002D5427CA5BF3,8F75C7593077B8D1,43B75CBC0A07A2ED,D30AAFDCB3E24256,98025089E0B85114,2EC74722FC02F680,7C3E61EDD5C65939,9E3486BD61F11239,8D7A569010623608,D943D0AA1550853A,40528AE325442227,0CD964DC61B1A160,00002A65523EF6DF,380BE851AE6406E5,D64AA59D4B7EE25E,A99D345B28955D03,BB3FEE69B7DE9F6C,DEA38509409A8C2B,E82D848004387622,9D9099124D7B3D3D,50848A2D7625245B,AD6D5EBE4193302D,886BBE36FCC8C994,7BE64224F1118875,00003169A42638F3,98FF0546D7F031F0,A45ABF145A10DA84,4C3352CCBAF62C07,50934E9B0DCE8861,955EE86462CDE0C4,98551FD3DB9EEB60,76B02D1760D362ED,A0F90F1A858F97AF,A928BA0A852DB572,1243E7B8D42F414A,3F5F8B2AA55E6F83,0000005BEA8EC269,04A7DEF837A4AAFE,90F7452405BB3C6B,A179DB6E1AC96BB2,26379FEE5B1DA3A2,00E9B17F51918A85,8BECCED81E1EDDFB,8FB3355F5BF9AF4E,59B7CCEF12A8582E,E243069EE26D3E27,78526D49244245EA,3D935F87BE919085,000010550947CDDA,22B616EEFE3D1AA0,40D66C0621745B8F,6192185988FF09F1,FDB9D283CB4F9401,3E5EFFF8B20721C8,F1D1FEDC9F59466F,F39909785DF6DB82,C539BF09BD9B5448,BC739C545CBC8A53,3E44D5AB0273E351,E792C6F3EEAFC159,00003AC9609B8407,0A67ED0336FE5942,BBDB3EA287E12D9E,13AD5B684EC867EA,E740C31845571FAE,350C2033823D6AE7,CF5C7992C502FD20,1B066C56373CD93A,15C64D6700A5D9EC,5C019AA159B2AAC3,1C42A7D916CDA4A8,91DA923A46A15435,00000C283084E44D,96F7C497C709111C,A5D6D51F1B76F382,8FB6AD466FB7530D,1D075865ACEB87DB,9BBA2AB14FD7F93B,7BF80E4575C2C507,807F07982BA0754B,EE131EB34A50B4E1,45FA452A2630C233,FB829D5A6879CDE0,F97685E56FCD94FF,000001B5D2CD0540,228FB6FD13D54F98,2F587FCC3B5FA084,D627CAE104402D0E,9AF3CAFF125D27FB,2A8308B98ACD835D,F0DDEDC2E606ECF8,A0F3678488DF47EA,9A9A68108DD50B70,0FBDB91F2951A74E,9E98C5DF92A1DDB2,BEA47A3F93921DEC,00001E2DF21AB819,032FD25BE7D1E09F,7D59BA4A569717FC,C0F567DBB7C6326B,E02A8660D1501DB9,F0A3378EB46147A1,0CDB340778810652,406D00036A10C0FA,A639BAF59D57E98B,09145C6A267BA4C4,90E05E54CF76B74B,F67347E7EED0B6F6,000045E67A6A6CF3,9B99EDAE87FFEB92,61C84CD55823DC07,D111B4201294CA27,F9C809166FE88FFB,31A0C5C9B3369607,150B28F04C9B6ACA,6624790A31CC0E3B,C8F3891E99A54444,EB9C9ADEF2837523,90BC4B012A2CC065,6C844A624DA5C21B,0000035AA107032A,8480DE299A0D07F5,AF154AFA12FC4657,3B3884CDB7C53AD0,A940553146BEB803,0A7770725C9A6BC5,67F89C06DBD1942D,978788AE5B7BA75C,9E946CEA68653D38,84BC3931CEE2A713,0B59B024BC670C08,16C21B2E668BA851,0000078599FB41F4,86D5A44EF8C87A54,7E36886B7A0F8BBD,1BB7EAEF73AC7C2D,F350D1409E8006EE,EDB3A647367B24F8,126CCA547AA23867,4BDC03EABBEA9C76,7916CEBE0F90DCDF,2415FFC28E6BD00E,0CD05E9CDE3278E8,4182515DD250693B,0000506546BC106A,2EDE731D10029149,5D2D85312C1FFFE4,0C5D7ED43C3EB40E,8E18BDECD0CC9471,E8A8707006EA34A0,59C1C2DB6C9A7AA6,972F50D162B6D188,C18819EAC5DA4BDE,8BCC39D7AF721635,D39FF31D0C48F435,E9B4390C8D0A9C94,00002175BCA6451D,AC04E6E771D2EA2D,035B953697AF08B4,DB4BFB1D509A43E8,5209DA58B37B9789,C7BB78D247CF1AFC,2827593F0A1C31FA,A6124B9B443CAF44,479DB41FBF9BD4CC,809E255A22B5C15A,4C402F6BD5534880,0EE1335DC8C7D203,00004B4738082DD4,70934D310CF1A4E5,149FCB59280434DA,A697AA49BB370B43,CF7256C8DA2AD963,CB0AAAB7F6235396,67E7127A27DEDB61,C6DC668CA9C9DEB1,E5301D99DC5D224E,903CF8D389472134,1141DC86B2FB2AD6,3197D45CE86E3A85,00001206A33EC3E8,C1B6364557A6CEEC,0A8574FF56886C1A,84EBC5F6B173F173,BBCF665BBC0F1A07,F643C15A9C279D82,4479804122B5FB84,8B1FF09E9C6664DD,E259C1F58550E433,75D5D98B803DAAB4,0417008BD2D0561B,F87E63BAA811D1E9,00003C6EB3862751,FBC06DE4A02F5B5C,CCBB07F2FBAAC251,25930C1F1A4ECB4D,59312FE1968A09AD,278ED414C1AC23BD,A15841F71DA199F9,C1ADBEBF9CDEE8FF,54B819DAA288AB32,2E4699E86D8E7D64,B97EFA7798580BA8,599F6471072E0BF4,00005F6891106309,63B2CDE7B254999E,468EA253144467AD,8A54A8D7F0C61F2A,B204BFDC8443135E,5C9D3A8B706227A1,4818A7D8CB710913,DA8F446D13372C44,FBC6B23CFDE04155,257297858F04C5E6,E950F353DE0A6C06,7C35C46081F0E712,00002B903E150B7E,86AF364A2C42DFDE,1463AA0D35FD47E5,7C287F183ED55870,590A11BCDE4072A6,EF7E79B3E3AB111C,B6BC986E754AF517,FA9865019D457415,24BCBF4FC0955F29,E1EB1933E6D52030,2EAF9E8C7D1DFEFF,A1CC716AF9207076,000039A952B435FF,958A4AE9DD4DC540,08DAF0323C5C055A,2F9507A5CC80D3F6,D9B2DEDE673A2E06,AFC159A625B2A30B,3C9DF5208869E784,B5FE7E0490F8ED2E,5342808D2F70267D,75CB02407C616883,96941DD3FB6CCDC0,CF2C339C9C314AD9,00000BC57B7ABD01,B27427CCB6224160,0BB4F0952264CFDE,A468B87EF4390A1A,77796A7181427DF8,0B8FA269F48313C8,058D7EB06066308A,7AEB83DC9839E811,C4B4CC3DA0A45360,921FE8D62E9295BE,D10DDF81F57C3209,060C29D32FE019F1,000021C7FEDF13F2,2A30E07CDB7D2012,ED58B2E2C62D696F,553879EA5E4624FE,C84E2309290ABBEA,B19F68CA0625D0D8,34CAAA78E5A18687,613A50F446AB379E,2E35634485F8C022,126065C8B228FBB0,5498BDEF3FB7274B,CBF527C5128246DA,00001683109E35BA,16F442E7F178F92E,1AC374D0BAEE0404,1D78BF6D1D41BACF,B92BEDD96A43F74F,B6BE688B436576AC,F8F4A44FD13DA73C,8B364128702056B9,C80666E13253D270,693B40E7E6C7E79B,038BFE31D526A58E,4137621B6EAE81EB,000034E827C9934F,F0A6A960ADECADFA,24B776F5DBB08160,EC1AC963C12F2FFC,C21A9F093E569D26,3B1FBD55C1019B09,041022A4EF45F9D9,258AAEE403434E7B,FED725053FB251F5,46892159A68C46D6,F70792F112CE262F,A764A5EB2E22E10A,0000457C77FB0E5A,C6898FE157241B43,8F182CAAC35473E0,22906E6753F763DF,A3E0D3443354A1F5,983364E63DFB681B,1B4B213FD085A47C,731CEAFEB51A2AD9,742AC12DC0061B35,3CD7617B51A9566A,4CFC3D2F687BDDEA,135E2D0C3852A35E,000034513EC64AE0,762AE8AEDD4C614F,1CF28BCB184B654F,8008506573F70B42,D8176AB3EC3D0246,59B9BCCD90070FC6,C28F3F9D91E188A2,D17804D8F5935840,6A1509B9DB5D78D0,7538F0CA59DA4D05,F2F7A4D23AE25DE2,91DBEA03FA6FD331,00001E13F093311E,27A1CBD253B662E4,06BEAD15FF4979A1,684CBAD01BCB30B3,FBAFC58D8B607D56,AE818E0D2F7F8597,AFE47E24097B43C3,55F921C415C0D040,C11307B08E17014E,18BC6A53F6A8F221,ED579C2344A5F3DD,52A48659613DE57B,00006228E91D74F2,0422A3913D234A68,5C29CC11B53A9A90,765E40E48561F1D9,30E0B0D7B3D63E5A,851ABDA0603F58EA,8D4CF6CB0A1023CC,EC0D61773537A63C,8E8B872B15A26C45,46950D8ACC8DE5DA,7C7B0C0CC05A6722,86F9440D6807DB02,0000100203268439,9E985D83D29566D6,97DCD750EC50E952,9281E2197DC8D139,DF19E477B9737CC6,CF46CB84F7857848,F293FFF916174DCF,EDAD5CF9EFE8C724,DBCD7E56F3F76DA2,1FA62570C7E8438B,1EE5AE6684DCBB54,F450DFC47D5B2AB0,00000B2C4B43B0C7,40D0B2FBAF70D615,D7334E5186EC4076,A1F882C93E7E20F6,9337CB318093B73B,DC123B81A5D9CD80,22792E9F9FF4F42E,2ED0CD01DDB116ED,53269839055A3F0A,3FBF58E6AA1CFC16,412654106468929B,F5BF2DCD57E9FE26,000032739EE6C321,C180A07EE0BE1175,E0D16A73F08BA75D,F7678C23E7BB6AB6,CF5212F2D000D697,6A2E69C621E4AD4F,A3132BB967864779,D35D929B8B90E877,4A7F11F45D0591D8,44460ADFF943E6D3,31B97C080C777987,FB65D5FD328CADCB,00001F14D86B83E5,11D8B3CF4E59E7C1,FAE9A15D374A522D,E1710FC20B447142,E80F7FCDB9F775BB,A2216643664786BE,D3E2EA7541420BF9,B45913CDABE004A1,E39979C7DFFE51CC,664EF23ED0FECD01,99BFCD071D645893,577DBF099EFE82C4,000008D28B9BA07B,04E97E1B5E265385,966E12852B06C304,049B2782E3D879A3,71E4803B7E0A2812,1D4A044F0D37FDE1,C22A35F1D137E1C3,CC030203BE46E081,F4B2682258DFDA3D,E7DCD57ABD53FA80,D0976C23D0BD5288,7D96F806490AB11E,000033EB3FACB7EA,CE8ED54016A70412,5B49CA50B1B47E7E,15D05F66E27B333E,D0720C28D26B1B21,8E03BADA77581D66,E301CAB88A549C69,6C3D0657F9F9EC2F,9A18ABE746F539EA,5A9CCDDB468B51E7,F1DB09A068D77AAC,A61985F40714CE6E,000062538D9B86C2,E23022A969D3820B,91DB887EA92760FA,F1D26608705B75D3,14D9A3D2409ACE39,414BFFCFEC4C8A0C,15F7EC951CE513EF,B2B2BD076C023540,ECD0231813C91189,24F149C731438DFB,92C2F35DB4CA0454,E85E0653805B8F02,00003505BCBDD316,E5C62A878A08A089,34ADDC7B536F347E,526EB90F6DAEE5C8,5B8037D3CEAD6F51,D771CE6CE2A96129,97F12BF25A229922,9FA78DFE8A637543,B1F1522516C1E6D9,B339399A1F30C9EC,6FE21462A4F8C179,152CD117B40EA1DC,00003567E6CB9986,71F7247A30B6536A,4C5FEFACC7CE5BCE,9B8DE4DD30D07755,1E4B9355D3F43C70,2A3E5D575F1A7CB1,A74299936E800C7D,207C1C99C82E643A,96485B2B5FAAE940,B50D44A10EB9CBB4,5E69211590660659,D5AB6C0495ADFBB8,00006139E9108425,A8AF4FB7FDA0A48C,26269D7B0326F1B7,B07244596201EAEB,E5F5711BBA1AE791,64C1BB1C62A55722,07A1EB44BED88C42,307E96944A31EFEF,2C74E54E9C184FD7,D4F925D1129FFB88,74EA335CC292A983,74DC94C81DA744C9,0000062E32FC26F5,096374DBE27B641C,60D7D42A75901662,86AEBEA52E29A7A3,EB5AB7D16022DB5F,0AF522E78E0E1541,6FA7F29E2255D5D8,7B3BD518847D8759,CE9CD6EF9BE9872B,DFE4A3CD7BE2E479,E8D309A55E17E06E,129C3BB82A8A8C05,000051B1CEAB73A1,9A8F6C53405DA0DE,63F68D8D8306769F,047D9D1CDD2844D2,CF767055C3DCAE77,2E1811B15A321412,A2FACE18F5C8F40F,15376753B0CF644D,5C84248EAC073EB2,3AE016431069CBEE,DE1C2EEBE8039F03,BACB1696D7A9DC9C,000034D45CC53F86,EA003EB6EF106181,92428D837F139F0D,FE59B19CEF5BC506,3D302721D5E09E4A,2BBECFE4832C6714,6B49CB630F0C1056,2FCA707A2EA1BF90,1B7FD5DBB6C0D8BD,E7CA6CD30120A33A,46D31BA4861BD874,B30C6A08755E1A6C,000044F9D38FDD1A,BF58CF298F15A42D,F19D32E7D9090C8C,31A74A08B8C951B2,4AAA60EAC8D199B5,BCB43AFD9AA3D1D9,25F4C4A3FDA26101,2C052AFA9054BF98,3510BE208D979D18,44F579782C4E337B,7FB2BCBBDE4B6F7A,A3601710BCB64163,000026E6C8E9846E,28715D92CB4948FD,A972D1CF0E6C521E,42F368A9C29FD550,18DB8FC90A7D46E9,EC95534ED85D07F1,A5725CD32EC81AEF,0B1174D110922984,9B76174E83CC03B8,C4F879835D3E3FFB,704D599C70A91164,3F6A3C5DEC6F9ED6,000006BB7B0D74EC,7BEF49BD16AAE844,DBC4A963EEDA9C6D,F489137627012F06,ED14E2D63C49262A,7665BECC4062A750,C949DBF182CC652C,D7E83A07CB732D19,C25FE9134DBBEFDB,FD71DE2CBE9E3CC2,46A84CC4CB969C9F,6BDECE19691EEB31,000036FE8F93ED9E,132A30F7D0E5C353,0B226BE5371BCF77,FB2297C26AA69975,8BBB4EB348D5C221,655766267BC89F76,6D87741430F02DE8,25CA7E83EC7D5A99,1EA2C0B02B674977,A8541DA02DC2CB3D,2BA8D4EEB05E4BB0,33A2AEA1745DCA94,00006B36CEF9CC81,52B8E9332883517A,44476423B75BD6C8,0128E33BFD79C49E,F463E8D665C5E2C3,3544B535D4AFF253,F4F578C5497B3F7B,FE3140054383D5F9,16B2A19507BE7422,6104DEA36F346F7F,DF92F82CC9A908C1,741FCA99402592E8,000028BFAE7CAC81,8644BF7151617912,0CFB10EE224E0451,DD53BFE7C81C3DE6,F47DE3C9FE2B0914,FBA950C877221553,FCFCE533E3748031,7A58B05F005D0E24,20967EE68B71425B,06D0C59382A6B078,37A9034E11CE06A3,7059FFECB4E0302F,000025E2D9E162B0,58C430A873CFB33C,AB95E74C743BC764,45150F4F674B621F,523696692A5BDBA6,57AFC7EAF16B7926,5505A4A7AC35934A,3A4F92E5A9D5E113,4FB8CCE9E23C23FF,8401E001A115B309,2237E0B9F0FF6C11,E373124E908B3767,000065E817E90AA8,AD55CA57528709EF,EB4410C944668300,91C029DBB73F97A4,0A310FA8A430CD83,C25B790B871F6368,5DCF4A5FA7EAF0AE,16EF090C830B95D6,507B6079687D1B5E,79A7A1D65ECED701,0571718CF2C8E3FC,F61C1781DDCCFF51,00006391D09795A1,604E393DFD373792,18DCDF725719BF5A,B1C37197264604FC,838D46B39A0834F1,1E8EA3C6EBFD2E53,5D88F1EF56A55550,B10A4126606AC7C5,17C0072965A57693,8F9BB63B25890524,EA66C11EDCF3E72A,59030BD7667C2AC1,000059DC179D33FB,0E3F996F9144C77A,37A471D20098190B,301D023D55A3FEA6,17BC763BE4C8779F,388C9D7156DB658B,467BFFAD37C989C9,6B87785AA3F3A76E,5FB7BF82547D45F8,867D9354630F3AC5,6F5D3062A003E724,5628D6D313A8F023,00003CCB87641B82,73DC26A06A4C495E,24F782A38BEF31DE,4103E3B71BA2F3F3,B358F62180F94F57,6888D349B169E712,903EAABD72099F30,30F5AB22949FC7D8,016D9EA6683D7155,2827B7B22FD304CC,315AB9FC257D4DD3,C8DDE3159ABD2D17,000027F275D3CF1F,98DB99626D2ABE95,FA7BD50DE150CD24,30079A61EE64BFC1,F9B0C0B32D769944,9B2A2C11624D109D,420EFC66703FB1A5,0718849A618B32F1,02648370B1836D56,A2B699F1E36ECDF3,4716BAC24E2ACD23,CFA03A2157C42264,0000642B1E442E25,D76279BFE270BF94,9C7E0D940CEBC271,9A946BD4668C05AF,10514491CA5DD660,A917F5DE54799CC8,0EAE3D1E9ECD7C35,7BC13DA9F5351286,87620FABF9D5A68B,2D33A1E56D61F1F9,91C217FC457ECD76,2650F4A2EF06B461,00004005FA00D188,C857C8BFA73AF361,057038F81D006097,A7C2DED462463346,E08B42128167D37C,DBBF39CEE73855EA,BB211E4AFE1AF14E,B361862FB4C25629,FE6332D5B01F7E0F,45846A54D8CA0162,E676A34EA0AD7544,549B4BFABB56CE2B,00006B3DFF67C5D9,8D663327989481FB,A780FB5912C7EC44,344539C948BEB0A0,6B1990726A13F22D,0EE54C34B6E065AD,02391F512E933AE2,0BE562320ACD1843,1CE83ADC3C9C65F5,BC779D6CDAB7BFB4,4920626475091953,9E92BF85287CC2CC,00004E4EBAF1ADA6,726027B83461509D,F6274AE6E49F3647,AFEBC64276167F1E,B3C01840BABA468E,16077E55354C30EF,B67E299C53739E2A,5596ABD3E053C78B,38816E6FC047CA52,5367599AC77EE89E,9AC7A12439A1D1A6,37D315A0F7E06B40,0000098115BB88F6,409A4F51591B2AC1,B6DF4895DF3F5414,C5DC794431D555A1,88D7DD376216B0D8,1B154AFEE5A11DE6,97DAD13E3CADF2A4,DD351DA6657AF619,18D369E797D996B5,B69D212A9A96CF3C,4D93C33AC6D6AF9E,C6423127D6F6BA3B,0000677BD0E426B1,E880A5A4E6C95AFF,8B9A8208EEE07D1C,02A13755D3461FDF,1110A5E7D934A943,8B79E36B5B38D0D0,9E77430B547C1861,293A95AB0776AF1F,3927838B52AFA956,FBD610B26B6C10BD,1D667E823BF795C8,00CC1013590BEFAA,0000061DF22FA644,5438A720CD3A0B24,379D93DF98900010,C327B9B06CE5ED36,CD8D2CD166F4BAD0,E80057E8D9D93FA1,9E916771AA8A3BD2,18F2FF46F3EEF188,C6B3DB5F9D3BFBA2,3B31C7B5C6D83A7D,2A167D82B8EF00DC,6F8359EC0E495B80,00000C04FED949E5,7E0A2C1E775E500C,60E42BC22C6A4ABB,C90CF04B470040AE,16F6D4592A70D1D9,52BEBFE1D451C972,441094B3EA8139CF,5F4BB9A02C3433D6,1314EC75B80206D4,58BFB127EBF7469E,0AF7BB973417B5B7,B71B673424CDFE7C,00000A4CCFC3710A,544CD99252A7C8AF,280826DDDD14FE66,785926E18113F0F7,8C114D363BB901B6,18CB7C12AA84D4CC,9D65F39C18736630,6A55DB5AB0A58767,5CBA311AC6012A4B,C1EA339FAD4EE031,6D262B3F85015920,F633A977CD66849E,0000412ACB2E3AFD,D9FB4296A5427698,F172388DFF6CF740,518989504DB04102,816232DE058CD8EA,C9934BFEA57689A2,A503DA58DE4E6323,C0D8CD7E96E2E74F,2A7B3C303580F4DB,62E86F52BF813D26,540A5CAC4F968EA2,78F900B013A4AF1D,0000498DCED7CB2D,720BC30C89ED5495,219844FAC24656F4,E2D2ECD64CF3D1BF,283D35D425342E6B,7B5B2FA1BEB05AD1,0201FC6FADD08C03,6BE557C4D3FA250E,E0859289103132FD,7A125F6AEB549F8B,773C50819CCFD205,DE94D194259ED9AE,00000E5E9E112EA5,E286648D8D727FCA,1EB9FFD47E377EAF,17106038DB4875FB,532FAA677B77CAE2,CDA356B7C4FF6AC7,B52D6BAE96C02AD8,8EAC05069E7E3BED,83AE71EFDECEC6F8,CCACCEBD11E63244,701CCCCAAFA80924,CF5071F9C8F2D424,00005CE50653C411,48748E6BA7E9076C,F31A43E770EBDCDB,3AEE37D5B58AE783,C2A4A886BF442170,FADD9C5AAF7817CD,E388F5E0C71D7969,7AC0369ABF93AA1C,D78AF9D921490698,72E4270D4EE09513,3E44A1BB9B4B1BD5,2FC486B8FDDF4BFB,00004D18DFA383FC,81E6264FE3FD3A85,F7FF673D7C31AD9D,92C1BCEFEEC5B38E,6D6920809B1E0CAA,61C7E2B38F293BC5,AE9510206D5FDD33,47B9C976546EBBE3,D8F74E41367526AB,62864D61E69D893F,29DFF5B3C9D113A8,ACB8FFB19B9DC07A,00005AC24294BC59,4F2AF16C0221E159,65CD4127D62D6531,C1AA391D5DE11C7F,4265CA19A9FA3528,7E2353BC30E236F4,3B1F3ED39184D904,3D4DEDFD19E2F14C,34DC4CE832398FEF,F1C37E6E22551927,7283BCCEB304F0A2,2980AF182340EF8F,0000080CB4F52656,8483DA4E9F4DEBC6,246FE035B4FB8B50,C42920A18D5912DA,6414CC054D77D697,C6E5D50168677C51,4F169923EF328352,E10510144AA99EFF,DFE5D1DD762A9491,E75F7F873AFDE469,023EEF3F149724DE,F6E5B61E2692E7C7,000037EE43926527,38D5FE1041FD7549,93060095007DBEE2,92A18C3206E8067C,438D4B04B134B512,666492A14ADB80FF,D6494C4C52C00E9E,348D8B2A041A919F,29EB582763D676D4,7072D7D4E4B3A1CE,7C8EE15C9E4BDE31,3B2BF6E6476B8E16,00005B9BE853637B,E709D29714EB514C,D7F50514168EDA2A,14B1243B9F853271,CED1B44A7FE0F04F,742211974249F879,FC3FAC1D736A91CA,587B37BB56FDFD82,75DB638011787099,173EF406856FE53E,B4D5D203C159229A,73F4F8E50582E503,00000303A187D15E,0E157B91C9399785,6EDB1D0B6040909A,FC6562770B13B10A,3F6D2DE5095C7939,E94A220E99F104BD,69D66D2BE2F3461C,40028792AA251EA1,8F10CE4813621E35,5010C172B7C6A8EA,42E7F75545B31B9C,36A8C2947A16653F,000061E166490695,01FA206192910553,1C1F67C250DF2FA7,A244D6F1CC66C2CC,18FAA0F7D9B1A413,2CBE9BB55B73824D,3AB8A0A13ADDB597,8D0F6EBEF42B03DE,52824DA1010B89FC,D41B8B2BB7DE3CCF,1D7F26D3F6772FB9,C86BDDC8C02FFB6E,0000107451F13F8E,224D9B08E5D607A6,CF978BE3E94BBE47,58E93A243F91E5F7,CD1D4658212EFED7,291D92F8D06F9113,F57FBB54C2E5F57D,4A32D8C2D665AD90,4118A42F53BD87E9,24328E66CA1107DD,B0A93F144F447EC8,0EAE79C2FAF99462,00002ED23C0E62D3,E70ED7AB01F11366,85DD52855E79440D,6B0E5DA0F5CC0F0C,156D61C6402CAA29,98EA6C16A78456B1,1FAF00702743558A,40E4D2C733CB3C1E,4EF6EA2F504BD848,254461237A8C46B9,02CB382965A3692D,6DEB59A91CFD96D1,0000565C088425BB,A4532AF358396AEC,9E7A1CD5DA8E659F,5CC11A0D45DFFFED,957287A2B820CD58,9CA48C822A826500,175C06AD3AD5A14E,019D241342104753,3771458F28714CA8,B78258074AA5B09D,3D0317EE1B4697C6,20A2A65100ABF5C7,00002FF32201099E,BAA53DEA48A51F34,19EEB7B2370271B0,2E9BD8683A337507,47C5BEC0E63DEBB5,7F6E8C4A77978A23,D5B62ED3C8A5CC07,AA8C06CD421D183F,18D5F3F225886D49,DCBA38223E5C5988,05ED80788CAB3616,A9FA2774AF421C48,00004E2634D12BB0,023CF7BFA303C4B0,B2F6C49A10F28FA6,7F7B5EB0A0D8DF8F,B50FF5B322325D95,4139A0EE28E8E360,D9491AD9A02A2675,5412B39B4F317BC0,2D5023077731A0CD,E5F5D7807A14283E,6E8E01A2B8E952A9,E45D744943FB57B3,000053A4E67974DF,92FF4E0996398702,4E148199A374EFDF,64B93E421E5698C8,AA39BA00C3A8435F,F38758F42A283BEE,844EAB5D100FC773,D272E4DEE8890255,8268C8FA7207329B,C355648E2DE49DC5,06D5AE026EC63539,644DC5CB486A406C,0000174D15E1D10F,1B75844F6850D64D,B60937672F05E7A3,D506767F75FBEA9F,0C8F0453F8C12C0C,11567CE9FEF25C82,60435657D76EECEA,4E87E0D5E81CA3D5,F21E9009EB74854F,F512F74BBBF9AF75,092B2E6839A92133,3F6C49E8746AB98D,000013B9A347F79C,6207F9EE790D929A,E0BDA53533385D2E,98DD8F1DC2AAC9A0,133256658E7940F0,70080E3D8E11DEB5,BD7498DED927DDB1,97D5B206161114B6,47E37CAF3C1A90C4,F7EED67E77C6BE04,74CE5B07F09C8406,7849E6CF0214F066,00005DCEC7762F66,626F8FB1FCFA4C52,2FFF5C753EFE6D2A,1DC6FFF3E89E7C8D,2292A60898491149,0B105FC837E87BD5,CE8D8231F86C357C,50568F52A3D68618,C4471E125B5A96AA,1720A6354122CE41,2A56FF9D6A447766,41E7A8A18E593E03,00003BF3AD8A5656,DDF6E70E52F042A6,547D4265398F9123,C06060312D8D2DA5,689F719312966905,3A2DE88E5B77046B,A8FAE332D2FDE5ED,E594B508BD89484A,DBE82E43CE92959F,31C5DF8997DED295,42D58A9B565DF75C,D13D2535E6EDBC18,000032FEA46D4D89,5321A10ADB3C204E,E8CE1810A702ACBA,2128A73A1D2E7B2C,FDF93668FB4B7476,BBADCB8488DD48D2,1C535A321F97B3D3,79AD2F186D294CD1,090F4A51D963AB38,25637020E649D2E2,42F20C1FE4EFD601,A6D9F5210B78BF53,000031EEB7261C66,94E984EB2B91AFC0,2E899AD99CAA7A1F,FBD76683E09B7864,5C67F6CBD8C5DA35,B43DEE70F8E7BF32,C623F51F283960D1,F11015574FBD5785,381755F88E4AF240,51C77607D822D9FF,F572CC6570F9A2D8,1BFB68BD6C2D3E8B,0000387E9B46EBEF,D2361E687615D1CF,946FC828FAE1334E,E1220C8D88C4AA41,565AE1B83A3B5A7A,73019018989612DD,0B21AE7B2AAD230C,59F18CE0459BECDE,1FC402E520B193A9,FE8D27F2DDCFE710,D788253B6677F830,189756122222DFBB,00005A0C904E016E,9775565C611AC9FB,4B716B65FD79AD6D,F5D5A44EC877E38B,C62879CC76BC1229,C05AEF8801D2F454,F913CAAF94C1D624,7F5D20DE8B23383B,12BFAC4B4FFF57EF,B6FE0EBECB932B4E,AE25795F68AA00D7,315A682D7BA9251C,00000CFE2323A6A8,482D6E0A7C11B304,0E1F839C44D75CFB,08A5E6ECA29E6BC7,BE480613A34F03C1,1524946CD342A7FE,C34A91758F8B9473,232CC3DCCFCAE4BC,6ABBA171ABC8CEDF,A80CBD24F0AE130B,797EF485080BA0EE,39C5D40B8612516B,00005A2A0264CDE0,DABB23E7CC2481C8,7E384FF0867FD3EF,991608E5317CDCC0,F5AEC813FE062EF4,604C82B7193EEBD8,8CBB7F53FAF0B023,3512704C3F12E195,7E476EB28DDC472E,B4F7FB19860F61BF,4F92CF59E9978419,0AFD6F63D0527898,00006CDDB1FDF0B1,4738EA5B343EAFF8,11BB904784E32D27,7F81D35BF06605E4,5D4B88777B4D4343,A82AD163CE88D7EF,5C46001BE90B226E,F04658DB80F7F3FB,69C88E6D42646182,DDA6D7F015D5C4DB,5DA0C4760AE450A6,F87EC919F8890199,00004EA27D636DD3,BF4EF5788C9540B7,A131595A16FB04E4,CF89EC6C950D1737,42093BDF307F5F75,5B832A0BDBE996A2,86B33FF5247A26F1,52BF915839D58F8F,CBF66141A6046C5D,E9FC0C8B9AE36C3A,3B57E4C5D1EF1F29,0EAEEC34DAEFFBD0,00004D9F538F2C40,7368AA7D1D8769C9,82E86E298C43A5A2,E6457D4A10E5811F,F8EFCAF3C714CD41,1CEA41E6A8DA8572,6DA4BC3CFCA21973,F8485E79F8F51550,BC8FD7BA24CF3CEE,662C87078B03020C,15601E8FDDB04058,03050F2EAC6D013D,00006C129818A052,0D33A6B40FBEB038,1238B60ACEFE96DE,CB4E365DB9C6C4E7,4EA01D727C4EE850,426CF7CDE69043F3,631A17EF8DEF5D0F,8202EDAA362E0937,9CE610DE126038B0,4FADB334BB94FD74,6BD0F94730398E66,1CA9358B8CCC7DC2,00004089BEED687E,04114C68C0ADD915,88C6B4544A257471,3D5DD3F841CE9D99,7F58E3BB6A40CE56,7F5C4B737304BCFE,737D87F93018E7D9,460367BA40243352,75E94735B0485DEA,7262523FE263974C,69CC4036549D7A9D,FB538747D7836140,000010EF2924D18A,A163A54D9F4449B0,304F4C5703C20DC0,477373B16A14F63A,726B6FB4E39372ED,1FF81D7CB1127399,ECC332C7BEDD2C61,05DE3B1633F8253B,B419E8343DF14147,3054AEB694FBB727,FBC093274F8BAE47,77028F0904B6504B,00002E457898E189,F4E1F44393F58054,F530B5DF6213AC3C,4E96B5220D1455BE,A6E6C967F21EBBD7,1D58903C03D1D6B8,598CA5E9AD995B9B,CBBE37CF4DE5066B,EFC47AD25590570C,B32ACEF8CA5E8C26,3BCCB2D40DF192D4,DBA9A3E36D5747D2,00006DA596B5D741,A05CF266C8321F4F,8E38CBA5934EC1F3,4BB4B6871D9921B3,6C35E057AF9BD87C,DD8EC57ED810FEAF,7B988944AE335CC8,B0E81EF8EF951DC2,BBC8C48144C353D4,C3E4521B14063E8D,FECDBB02ADEE442D,1228FD691A605408,00000ECD70C51DD9,350BF209B0943698,67BA604716855BB1,4681DE7D9920506B,4F02688F36049B51,13A42FDA1C2C6E76,F4CCF4DF9C2DC42A,289D955E88B1DCFE,82914A830D81EA70,327BAD7EFE36B230,0851F54E06D51093,DF2B8E3E6343168B,000056D0FF09A014,7C9E953A4D92B50C,B27FA43EB0E9DDF3,3AD8E634EAF265AA,A6C899D397D9EED7,E46BCEF2C98CC2E1,BBBB1E23B3A74A32,AC521FDEDDA6CBBC,DDCE3933BA2F1AFF,018F0D254FC5BB02,F73126A9CBEFA907,7F36E78EBAD91373,00002AAE7D6AC509,A3F68198BFE2451E,9D5E5427441CFC17,C880D3915201B541,5458B1DA5E7F65C8,1001DC7FB28165CA,6D1479A3226EBB66,57E41B05DE9E080F,E7BAE72BCCD39308,68FBAF1024BBF471,8CB2B46266BFCE59,AF621BEEE89762A3,0000348C3AAE8B87,371FC5CB172A15B3,BE7E4A703E6EE96B,BCCBE9FA89F8A25E,1A8CE4DB89B8A7D3,D7E690AE5BE63A99,6DA7ED7B9E14A91E,FB1745F07FBFA60D,84C771FCF19F41D8,82BF02FEBEB1EE69,8BAC2E5492F42F0F,8BCAB61F4918A664,00006CAD40DCBCD1,7494BF8F3913663C,6C38A7E4AD25BA83,774D360D7CE9940B,9F15B50E2D0DDD3A,78252A4CA8B3F4F4,DA2FB6147C40C5EC,3693794B74A97E2B,C11DF0E32117B353,E79920C5BFD7B022,9D449FA5F5BA39E1,5450A80458A3EDED,0000388F03355D8D,29F4960B8D806D55,B370FA6C9356B20D,28F4261C82891420,DAAC4E82124CBFF8,D54284A0DA73EE09,B18865D263802180,90A924B24A19FE17,C192FC313347E8C9,EC79AAD00F799DCD,BA498BEDC041F635,0A7B15045A28CC8D,0000509078DAC0DA,450C0B6A6B6551E2,E0CB7A30E266C54D,8073795287A6C54A,5E2F41CE6C95CDA7,21B458955878ACA3,27928984D3569104,EA30E5D79A4673DE,07E592E04FC008EB,749405F4766E7CAF,A4C1D6706CE9CFBA,C0FA1FF15C084B66,00001C65A1F2AE1C,9BE1607F049258A7,F1D06B413670BEA6,D43A2F231D4899E9,DABB427B3FDBB23B,D530EEB649D83753,E72FD1BEA74CB110,AC625CE244F41EC3,118BBC2134ECA83B,67FE230EA0C6FFE3,520B50172D4DC994,84C3400CDA7664F8,00000DCF968D1F4A,38D00D14EB384F5F,FE48D3A753B6C376,A9CC04A92FB541D4,4353AA2A363DD9C1,C45ABFCE43479F43,0C7F49EB3C5DDB38,1C6E5BBBD640786A,37E3AC0DE1DE8054,884976111A1FDFDB,AE53489B94B5679C,90342CC195277191,00000E2633F09EC9,2008900A4231769E,39F4F97C46F4B704,B5542DF4816BE42F,254B39B2A47BB5D4,9E8B277CFE47CF82,FB37D22CA506FFC0,4FF815F33DEBDABF,593978C9941F494E,06BA5AB780FC7EE3,B772D037CE35E601,FDBEEF79EC74D627,000040FC2433B9D1,9CCC8693C89AF4F5,0D6CF216D19317BE,36CA45D93499EEB7,58C145E7219D0D4F,974253AA01EC0735,AA9AC7C649650674,548CE3C7D095BF13,7AAE2341700E6274,4EE2339303954490,FCD0B8691100A4DC,81A83CB90B9504DC,00003BDD8CAA622E,F96DA1BC7BE88565,B6188F52BF0EA29C,5CD341CAC2AD3BD7,BCB6E82AD0B701D4,5698F2D4F8B4E2EC,CFB8E3843ACAA178,464FA5F44C0D2124,830FB6BCB92E9768,8789ADD1879C9C5C,67074E4372535B24,26F4CF70CEDE536B,0000297037BDCEC5,9D172F89CA445497,D6243D0DE213CA66,74583F9BBFAB824C,3525CB6F50C2B47A,2878595A2CB6F4E5,245847FCB2DE1FB3,2C43A6A687213573,7FE09958415EF3FC,1D1D312FEF369366,80C605C8D3BA4053,E04B2D01E5E2F295,0000503CC72A1FF8,657A17B9AF8B8C26,73A932527A3B5D64,333B7C318102EFDD,9CC310D0BD14881D,B422AAFEE4D3D4C4,0732767792253862,7010F0FCEAC8FCC0,2A70E16226236698,9514E34C12348B05,B218479F57489E4E,372D4F38A3F6D80B,000053B3D5DC2945,4179F2600173D73A,2D9C41CF52CFA2CA,AB061C4BFDE18630,53FAAA197104F6AA,394832297261ED76,91007B6D5BB6E0F7,5DF42EAB35E0FD4A,F7AA13161B7535BE,EEEF7DDE6078D1DF,810C25FD8E4783E9,B49DF695DADC9014,000031AF0F729B43,DAB4EDD50529B1F7,569829BF99224B72,57884B335FB65C72,6F35590DD43E66F6,FEC9887A091F0107,E085D52AD909A9DE,3ECC055EC634BFA7,E7CCF6E0F929C7B4,822B41DA13995FBD,6817B9A43BE82CF6,44A0DEB64B07BC67,00000028F5839A56,523F4A99D3985730,A50CCA2EF9EDD502,10194CCC46024FD3,6968A3D1C3961244,1E9B72E10535F861,9384B4DB9813A4CE,56BBBB73892DB242,E754067E9777B404,E284807666D272A4,7703F15928C467CA,9645DA39704D362F,00000E1D96B7216D,34E37AF58DFF511F,ECFE64EE16124B5A,AAFB1BBAAD0453A4,6A0E913A93B4D44D,45673271F6746233,CF0BFED45E898BC4,21973B52D984DCE4,43230FE586664A8A,2746C53EB33A9609,3C1CD6EF93B58754,A6F10696CDC997E0,00005D7064E7B988,13C5F30793371C85,113A9773805700C5,925712984B66AF1A,AD93438FA123EE92,6AD0DFBBD73D7C05,9F6EA9656AFD8C8D,921489D89BBCFA07,8BF1F39B78992B25,658F26EABDEF19F7,E322F192AB81FF43,29A4A94043792062,000029DE09759563,9AAB607DD8E8E573,2B79C235E5E20456,A0A90F1D27584BC6,B7407A382EA4BE0B,FDBB9508139F01DB,7576793AFABBACA9,F787069C10F38176,2F4CCDF26D4B8390,5B07EA41F120CAF8,850CBD03928F4EB9,48FBBF68620B464E,000009423200442B,BFF9270811D8D0FD,D4A44BB7E63396F2,A20AFD321A9CDAE0,7B990F7D52C77755,4C1807390899E90D,D92EEDEAFC66420C,B28CE73B7BB00CC5,F285887EF29A9608,B7C62F27C649396F,E21503D0133D77A7,815FBDFEC41E1EF8,00002B425E489307,D843CAF8C5536E9D,BB5917CD84BAB0F5,6CC8599D39A73E6C,73D23B587C17B390,F40DC609E6816DA4,1DBFC538D23045A7,8E9B169BD9A01987,AD6EC69DD16CA13C,5A9D640E2F9BEE7A,6381C37D35FC0E8B,3BA1171503936946,000061C765A32513,86742454B6654D7F,EFC66BE7F504A84E,CF5E311FE61D8FB7,6E93E08372E220CC,2477A235F661D9C9,68B9236413AFEB50,C06C7D6009124C31,3CA7B8A4D9E3D9B8,A3A6EDA9793ED4B0,7A6055D38E057176,D351549A11423774,000015D600DC9B5C,29D20BE4936E3E27,7B6360919668AE13,5CC61286D4022366,CD43114C1144923E,3BC954F0E9C54212,D6D4188CCC2A91A0,A87AD48EF5209016,9C74D61B9E0A171D,FFC4655677EBB52D,A446D175855C84B6,03897CA3C7709612,00001B7168C6FBB7,F691035E39022ED0,70E391E8A8EB735D,2A60AA636CE9CAFA,27174820CCEBA85D,9A163B843BD1CC93,447BB87946924EB7,231B2BDDD5109AE6,4ABC37A349DBBB08,B8478074E4401E62,BEF3F1B301C27014,FDDF849B2C0CEB04,000019C379CEE903,885732C88EB23339,A0B75BE4B83105C1,B1A27B675892312D,1E4CF56B5E552557,D6D7DD4B61EAA317,A5E4FDE6A8913EB4,105B71F703041998,8F5582A1B57BB986,D68C2FC8E5C8E4C0,538F42001F7DAA3C,3B04252F0A5D9A72,000020D306792A5A,4AD95CD2D4F70AB7,D178DE8826915851,B8156DC1B6AB8CF5,C01CDB38F413B9EA,39CC139FAA49A6FD,68197248110E2545,5E0913634D8852A0,F6293585FEE4513F,B400F12A14E30B55,139FCF6AA6C2DCBD,711D4C4532CE404D,00006993FC0BCF26,8271F22860C83AD5,64057882ACD2DEB6,B79A98DE7375534C,88BB221D0839366C,D120685E25C168A2,A2A40805057FD7A2,44B72B3BB1732ABA,33F7C3A91CC52471,693F6F2942990C1D,F3AD4C3D02196F76,E63E852408FA31EE,00004938D3736EE6,E5B129EC402C3BB6,CADF55C0993E9250,2D5E5643D62B7590,68ECF6451118B399,FD9316E216AE5602,3EDFC920BB7ACA2C,C8611439A3C90911,8B636DD53747CBDE,F8D1E2FFB00723CB,47FEA52289E2C92F,2107309A10C24CCC,00000AD09EE710F2,EDAD959E15E0E3C5,B4F2E152DFE1C819,8557942214198E7C,3B47CD3406CC553C,2E9D35D1971033A1,9F579E34E0CE6F25,5F566CE266DE38AD,B4FAC724DA5FE276,5C12552098B7CEEB,7B627C72050D729D,41A8BB71CB6FFC9D,000007D134171DBE,C20820CD85F45576,20BEA323CAB6DBBC,BE1CB7E00627983C,D90418A0F383E42F,FF6C5B22F0421449,186718B597AA3BD2,A7B6D87EEA20EB71,6A3CB86DE3143D00,5D3D85CBCCF4DD7C,296A404087591ACD,879AB791F039510A,00003B8793225361,1D8FAEE03453F93D,1BB5C106887FE498,79D53ABA114CFDCF,A8CEEFA7226C35CA,C61BEE8B369DC67C,AC07A16D2A0ED01C,400FD115CF6C0D48,416246C04582E761,4A623552844168CA,11E8524D7ED8802D,7C645D13AFECBC1E,0000184FAD88FA67,29DAD76AC58028A7,24152C70EF08DC90,08ADBE3DC7C94C06,2E9DBB8FAC85D2BD,73BF7B99116BD248,69DC42031B1FC9AC,3A7AF28020B5BF7D,77942F1442F43CA3,2BB599F7E02029DC,0C49372597EA2865,E675F54601AAF5F2,0000692896E11F29,49CE02F61E006FBD,7907D0F109276B18,6B2BD607E0850038,09FD3F1991E4A624,9FE4C1378C6019E2,461154021E73BF70,E36982A5118AF6D0,C99B9C1C18A00328,24B2D4C47B90C9A1,37F9E52822DC6981,2DBB6DCF3DA9E438,00000F2CC4EFDBA8,69BB6BA67AAA0D91,1696F797FD84156F,082C406184DA0998,8BEE2D86099F3CD3,8EB3711F3ED98709,9FF7D3D39A606C8D,62488D89682CF19C,B884F538D1440E72,2DB88F1B3BBC5A66,A0D616F6756ED748,A648ACD06F1F6CFB,00004A8E5D7F225A,8151C951877F9ACF,7D3B09C33FED4A0E,933B7C4DF4030FC8,549C20AE9CA2CD5A,77DB0DAB66D3EE85,D77DB1EA4661AF48,0ACC4DAB75F403A1,4B31BE169A8B174E,C25E624A79CA131F,11909701E9AD6F7A,052660750E5E4C16,000032EAC444CD4E,DBDBC12E9B0A6491,910CE8BD66CB8D76,070232BBDC9508CC,3DA70AC0904E2484,C5E83D4E15FCF9AC,DBA618CEDF3DA2CA,0AA18D21FA0AAE58,E962E15F0EDB7177,7B41BF31FAF555D8,B3798184E6760013,CE2B7AC722A6C2D7,0000206A9494F6DE,576D35DA5770B856,98736ED6D441A236,8E9D0AA1D6FF13E5,CA3287B53148D3F9,311A7AB7AD2E8F00,7850851118D14D29,463D3E29B5176EC9,37DC7AB183159DF3,FF8BD81F7A2DAE1D,9CF6E9E9A5AAFB22,F2EF0A253A96CC18,000042307670A903,47C0DF27BE555C49,BE3A8BBA3F6B8C15,5ED77C24092231A9,A6E7E262F139A355,42AE127E41A5483E,A7859552A93922BA,C2F903FD97E3FF66,559D8C16077E4BE5,DA702485C58AC2F0,4EC3C9296B7B4F1D,63E93F68C395DB0B,0000621B8C5B3ED0,CBB1033A7E808437,72903E188B438304,EE9517C3D075AAC3,BB1E97421A8A5E04,70D8C0CC5CDBAD40,1361C7CB3AF91C73,4599DAB44CA7FD16,DD20C022C0A8C9FE,946F197EE088EBDE,1CAF02104BABAE8D,E538138469ED6081,000067948C681B3A,BC4F186DE7C0DAE2,7E08E67742FCE1BC,16BF75C22DA3B5A9,3E8BF804E8FB5A64,B6E86C8B83D02044,5C0FD710B4F40D2F,82B210587862DEF6,9B78BF04E4571AE2,107C3073B4366C45,07A6702F6DE5B116,F66CFBE437861D5C,00001D4AFAD38955,170A3EFCB938D447,8085323E105A1722,168D421BDD27DE03,FF8AC127BDD5CA9D,552679094FCAB615,CFB2434C722DC583,9EE0AF29E06B8A46,4FC941D86A5B8999,F32AB848E611AB39,B875958B99869429,9E7E76387D190C27,00002719E1BC1B63,AC83C83A5257AE37,4938645D309937F7,4599015B3893F950,D39FD26BFC18EB97,08C622BE30708E26,E3A5A779492A8E0E,BE67C859379415FA,F20C7165E88B107F,C56A06C715105581,A417B0F02417EC91,352CD20D5E30D63A,000068AF2B0F55EA,651C907CC382751D,634100F1D9D8CA7D,716174011877968D,A017A82E89EABA69,64E30186451561C1,8F8D2C72135CE9B6,AB7AC689DE5B2883,CC7BDE529BAF8093,AA290BE25D57347C,BFB8082A20EF0408,03324B80FA117742,00006C23B16BED91,4C5C5CDE7BDEBA3A,E909E2237360AB5B,A7D696567002461B,5A85BCD540E516C9,2BED093061B6A65E,0F3B8B769DCD51DC,181AA1D9508645CE,B7D0B0DE7964F304,9268760B62D5DAD6,05B7CE39384E3E22,C30C43B13683AF53,000037F86C8088C5,AFAE2E6B4E64A6CF,BAD9D846A48633A0,3DBAF235EDD649EB,2A74B802C941EBD8,F641CDD803D29DE3,F8D541D7FBE49494,D34A2283618512F7,A285924046E9514F,21D0A123CA929230,48873E70B09D8E80,492A64F9E3DE447E,00005C45153B1F80,1503A74C2F61D4D9,71DBA559388A1020,7B0B2D93C315E542,EEE233C4B6CAF5DD,F3FB63D66A0932E7,E3441FBCBD066D63,019EF20E3D8C17AD,E9AD160B869B4E04,EF482027400421DA,71D27CB0993DB8C4,3F37E850577DC4F0,00000678F007F7D8,DAA4CBF641391F5F,383048F45D23F556,F7F1483D247B3222,779C70049DC9364A,433DD356A62DC91B,7C6DF6859FEB763D,AD2909BBCB25A0D0,56F18DE99398E9AD,428B26B40F04FBA4,2DCEC398ABCA8C12,3DC1CD3D5E084380,000054AE46D8074D,E5378C7F9B5CF0B9,5F5523366BE8345F,60E09C7FD6853D32,40E8CF698036813D,519DB6D541C1941C,CFCCF51107452A1E,F7923B38136A8246,100817762BF70806,B71048AA5C59F7A8,02DE7A0E56EB91DF,4AD38E3F442CBA67,0000462FACF1C3F8,9BEF1492245A616A,C149085319A82A0A,F23BF82E7E47EF68,A29105F4E7AAFE0C,93A51D431980AEE4,2EB8A0EE98FE464C,4A8F23822A3F15FD,2E7A7E3A880FFB2A,5C170B7368CFAAB4,5097717A5EE9AB88,23012249857A28D7,0000589B157719C8,54D335581AF73164,DEC176EC2AFA2BCF,7DD3737BA2B9EA91,D361135D75DF23F3,6716887ADE271F48,94594C94AC2227EF,FAF7D32419E46DE1,DE8A8538513C6AF9,62A4FE31116C87B3,DFEA3D3E9FF40E6A,870DA8F7776F9796,000063005940D697,94F69567F0EC13B6,6DD44E3D5017C167,62481E810C50185F,13E7836C5C7DCBAE,A246AEAFBE893269,63E7948F1AD87B3E,27A14F781F6A6396,C5F1AC734C23A4A1,3EEFEE54DA004EA9,1F6CCB9DB9155F95,D763703B3214FFA6,000011BB72D700BF,3D6BEDFD1E091A23,4D456094BF44D2E7,2C52DC8A9C534FFD,884BC5EE9EF33906,EBFDB3470024A6B9,5D4D265D203FE364,B3791F2B57B302B5,B7150C0169F37C29,46105A5CD4B4671D,59299F6F8627ADC4,D7481E944EEF545E,00003C96BCBD8537,F7FEFA9229C2043E,51CEBA553A35DC69,4FA9EA49464E9F6A,31F9BAB7CDB603F4,F3EDD49C68A57F25,E72950094522BCE8,3288040A888FEFF9,DB42D1E058E691EF,D6E0D105A1BDEBFD,B0E5AC31649F785E,65831125B1A7B23C,0000385D1822FF72,19ECC39BC37A1D7E,B0B6D7ABB0FDFB68,19B441859DF0FBF6,421714B6B815B30A,8F412A4EEA204A3A,88A6D320D46BCBB2,98081A8BFF72ED9D,7F89DE25891A41EF,1EE333DF7C1DA517,018AE6884EEE4C4E,1D19BB15FA1D70E5,000034C2C9C5B53F,29EC1EF2F14ECD1D,B720AEFFE5B59C71,313A3EE25CE3B621,F9223E0318BEF5AB,3C9BCF49B5DFA201,B0730A8E3232F035,ABFB156C989ABD4E,B18600C7E8FA0D7A,89768E4C7039D393,1EF9A0CE887A1737,8F669E74961F3132,00000A3AC359780C,DCB2332A63CDEF59,433CB5D8CB0DD6BA,B0CDEF0DBA6564E1,77D3C5E9D84C50DF,37E0DCAEABD8EEF0,3A1595DBF1F83AF0,7B3D9BB6080F5450,02C940B3E8D1862A,B47F5A49DE7A20B5,69F46E49AC48A109,D34F95063112DE5A,000001FD8B85FE94,509F81F852FA30DD,400C965A02957E14,5407DA48084965EA,42CD66744C0C358F,CC33BC06C4470EA8,3DC32570065BD9E3,59EEC665427A83B6,0069345BFA9841D8,E2769AAB90E574C4,55E1C59146B09DF8,4E66A6AEF88DC94C,000051993C2AD918,F5FC35B71AA0D17B,FA057BEBA1A2D529,089EE4AEB442FD4D,3E9A028A571E7F15,1E83B787AA5614B3,81D1EF79E82BA4E3,3D0ABDF9D1C4112E,0B39FEE2CB1D3E0A,271B88E572E00C94,715621ADEBCA2203,C23752389E9DE59F,0000539A264C0FCD,DB52FF1811894674,F4B308A4B76FF752,DE9166DA0E7BBA2A,1709DB7FECF603CA,9AD80C9B70DC25DD,10B635B49D3D122A,2E40D96B8F6A4654,49BED9E2EB18D383,AEDA26AB23888002,C2CBFF3564B7CC29,6CA322DE9FB6BEEC,00006EFDC6A521DE,6161B3315EC08A24,FC1041C8CA23CF41,9C8FFA7669C86524,CB9E73C7F41DB93A,24765936BBFC1C80,ACECC8D3918DD3FB,77821818B18D2002,664337D46B3FB9B0,EDB8C5D5F40492EF,6C2FF69C590C6A5E,D165D8C08EC104A7,0000153AD7DF3896,4EFF4245307213A9,54EC1C602AB3CB4A,45290B1A709A5C22,24EDDA30D6815DB5,CB4F571344C47B6D,47F1BE83AE8F78E6,0E6C11CB651FCC28,A3A85E3A69FC66C1,81887B8B00E3E025,77059885CFA9DECB,E754D17553625933,00005E8500D6538E,1D045E31BE2F1292,A302011EA4865926,C74A69D08E5CB9D9,DB32C1FCD96B70B6,1B62F0FFD5413BFD,E677D1717FD0240A,D57AC2E8AC8102F0,1173F959AA719EA7,751F387CF8780F95,652CBC7613AD531F,6D640ECD3D83B850,00000B91F1DBFA64,A66DB5E842142387,3E5E567A3F20D4B8,739E91BCCBB71E4D,65155E8308661896,4D9AAB6B0FB76D3F,BFC1FE5ED8860AC3,8EB4A7AAAFB93492,2497931C3E21440D,9356EFE1753073D8,8E751500BDCB0A0A,A7AA1B1AF36A1A73,00006A6BABB3B930,B02B51E586D257A7,2F6695DEAC40B483,FA4FAA1EA03E0CA2,2E1099D98A4D78C0,C00FA71101E4D5CE,FF216006E6DF4775,A15703EFC2F01F1B,E57F4AFAFACE272E,F5D9E9DD89019DF3,E1E2DA70C67613C3,74334BCDA4A72985,000049EFAFD38FF6,66B7F1958749F169,C2144C1B4EEAEF9D,9FC3353213C8A0DB,2FE5AEC232299A22,5A67673F80912AB6,B0EBC69EEC64EE41,C0A98157F353D905,DAAF4DAD42F8A66F,4CED5B4D82A1124A,879D6FF461B55D8C,C5339E287DFCB9F2,0000545A5BF72980,5FB67BC2D415B042,EFBFAFB41B113E72,F7F2FD808B3F7155,D99184D36D694285,3E3BA51BB8329C5F,AC6C8804EA5CF5C1,E7A3A11A1CC9C003,A54B322E57677CE8,2E132D6B15AE637C,468DFECBFB7438FC,883BEFAA942B5F14,0000005FA10881C9,4686855253635A0A,C4EF936F7181D5D7,EC7B111AE3DE521B,B3FA4E1317C4E0E4,EA19B06505D72C66,743CFC10345995F0,3DFE2075EF073D8B,88C23E5B30D51450,7CAC94A9FA0F60DB,F41EDFFF875495E1,A6BEBDB657A2DE1D,000062D3113A7EFA,E0C2192BAC0B3FB3,1EFEC15D85D624A9,CFBC94CE874BFD31,9B2474E8D4FD13B2,3665A0EC52772AB6,7D751F01A58B895B,CB53A279B40CF120,E9842360983E7332,E1661AE13DE5B01C,5EFD2587C0AEE9B4,6C2E91A6A4FBFF4E,000043187E92F387,05ECF409174B3C10,CD23530F52622310,C1879109F27A0ADB,7BC6F46128C95CED,5898B68BEEF97D0B,C505152316DD2E9A,7CD8E6C3332687B0,40BAB969CAF88645,907ED15FCA5EBF40,6C8C43F208627CEC,6DF53C42F81F7BFF,000035BE501EE41F,FD2DB5BC4CBF7753,B95F75AD960C6094,753AE1B3A9142C18,B99DE7A07B1AB944,1F068AAC42E0E15C,86194FAB4145A244,A50F2325F8B6240F,61E5E8470177312A,0158ADB94F250F0E,5A1842FD8EFBE6B5,53428E0B875E6315,000026BBFD840468,68D0F9A4F5C897AC,F2F6264DA5198AF6,A4091A38450174B4,D89155C3E65190CD,D86B52818CB9A4CD,43E0EA7A3945B4DD,CBC995EB95CBC74F,97F003FFE9294581,0C5A6F8F9AE7FB92,7B543795E8FBF950,6416A26342693FEA,0000474CD2F58C05,DA62C8B9246C9E00,F337CCD4E7E42DA8,A2016F498D7F6DE5,59912F0A4783A669,E0320E3030986C79,5762EBE025ED36DF,1DACC0D9BC704B2F,3A90AC298D4C604C,DC5FCED462D32962,845781FF4C4A384A,72947A8E2965536E,00004141A52341D3,84E9963428456541,FB044BD362C7A863,A5516672555D8309,D257BA743FB71D79,4A56DEC1D29C9EDA,F4F334EC8F6A33E3,AD80AAB1D630A00F,2432601353B713A5,9CC051A516B7443B,64CB3A2C5D813C04,158CCDE705B300B1,00004C15E8432A74,19B4879F34FBBD1F,A61150540E8CC027,7FE993DD33094111,D114DBB93A1E9929,E18471A6E830BE75,2C481812935341E8,E18EC955516D5497,95D381CE166CAC4C,7132F9511CD6A5C6,B41E2829D121D641,DA3082AA61FB619A,000010D69855DE9B,51A9E1CE99185EE8,AB846A61FAAC7AFE,1C6B652D9E7EB1F3,AF523A398F89BB49,CA36E3C5F3489208,6301D87F1A178787,7EA01F0106029CA5,564D5143454C4BED,36041279239B112E,B1E0AD80C1E05E1F,4A09243124095F70,00003348A1B1DF7E,A91543B09B9EC6ED,27FC43B6C9A7B210,0151165A28F28B9B,B5A323DEE250370B,69A084BBCB0FE346,7D9B82366D94576C,E279A09664979C53,98FA449C8EF5C930,9672FBEB1A23B2F2,0620DD9B8D019200,664BDC6402DA5F10,0000257BD5B911F2,3AD9F29343B6050F,14BD0BD75927F254,52F3CB3A01DE060A,9E7EA97F03B39948,1C84D5454AA044EA,274E00140B803644,7724B0CF4A3A35AC,D74990C0D244FA1E,52208439B19FE4CA,B951CC97D5E026C4,4755A181FEA3E99D,00006B89ED79613D,4F1E3F579DDAA865,D792A94E2F6D6922,E576946EDA75B19C,38BC9601E3A47BFD,9701B4F5C41BE721,61093E96300DC3BA,82B0CAE4922CD407,1741BCE884A06343,665F3C331C2AD034,82397D790437D490,41AAE5417A9CD029,000034145611B10F,B84566ACC08C96DD,53AE3D11EB60523C,A78A0078071C358A,3F4E8D78109048BF,A8751BAFABF881B1,6A090FF8DEA6A320,B675EC13AB83B7FD,A4FB9D47BD910AF9,3604068DC5DAE1E1,001C1DAC6C5B2498,86CCF0CBFAA7108A,0000143B6AE83AAD,81E8EAE97FF1C30F,ED6A00E028A934B0,10BDDC0B80125E48,9EA8A6927C03E5DE,979BEAE2EE0B63FE,209EC11A19882792,FABC753EAF8AAAE8,37BFC3BF853FA79C,3B51999D2BEC044C,BC63CAEF411C2A74,38789EF38F8AFBEB,000012C65A3D6C90,ECFF3258F0C6C33E,E4F2649CEC7265EA,D1E1AF57B10FEBAC,197C39584AD41DC4,AA16ED4D9F4D3C5A,CEC572EF8AB138D4,B0EC62B57F1CC9EC,7996E60BB0C1986F,57BBFA91AAD784E8,F755A624816143A0,5EA70CB1379569C9,0000466CE59725FB,33D65553991216CB,09A90332B07ADF7F,6D75DAB4C814EF52,53F6B0F8BF3E0C84,2CD307DBD620792B,3B41A9D5B5F60480,FE9D54A9398AAA4D,98099783974227E4,2F26CD8511C9C29C,D35F02CF86CE9210,7EEDE7B846ECE245,0000484818A3AE2F,39518EDC20ED4678,AF90E75E28752141,84DD660314EA1CE5,3CD2E18EA4A97F19,0DC30804EFB387DD,FDAA4A7EB67F9458,261FF7FA192413BD,40ED2798026E8EC1,090B8067B29B6819,BD5B4CE73B1204DE,4C889062A19FE6CD,00006B1C244BB22A,77F19623B6BB5D06,70166DCDB816EBA8,ED29E10EF067FBF3,2E6DCCC62C069328,E70E6FA017F90228,52343D8A1246358F,3ABD466524D0D13A,BD544936F9358484,1B665F904E82F813,BCAA0357169F8931,51CFD9D3054DF22B,00000D55C8926415,012BBD4AA444B359,1CDFD0A691799E95,19BE05ED89CB2F6A,C8AED6D9833E46AF,5C1E796D9F360962,6828C96697C1F814,7A1C9EE29ED99654,FA37B2874F9F1910,BC19D5504260A86C,60921D092593826F,1EF38675ADA62454,0000278DE9332A7A,54DCF6CB90E40771,5970AF09E382CEA6,99F47F9516C830AD,90CB14CB6BD5F7F4,E33727769C0D3804,9A2AEA5184CE8F5B,AF28C4B00A8943FB,03F23FC04703FC4C,96295AA4C17F6F18,709D618DF695BACF,99EADE530101DD65,00002212018B5325,087B5A6F53F40EB3,42B01A7BB83CE6D7,7CB0A7175F887DBE,7A8EFB7BE310FAF8,BE999121D96A5CA4,2DC91B88D4A03FEF,0F1EF900D50BCAE5,DE833634AFFCD088,F9B5D13CE0596B1D,43171BE4ED93D3DD,C28142A766A27FDC,000064391AB19061,F06D880FC6996E3B,0CB9E1BBFB202BF7,2D07EC13D7E61598,D4FBFAB37763CE14,0E549B0F2CB47828,5910C51E679B95F3,7245958D82A9E14D,A93957290F8D279D,49C42E3DCA16B132,ED046C7A3AE3A700,D75914675260C41C,00002309B123D991,A2EB6634333AA99D,FECAF15960163C2D,3AFBEE8DB4D4688D,860DB37D0A4A5BCB,F0EE8AC104523929,0EAB2FFD530342BC,C0417615C081E7DC,764837D91FFB343C,47B47E39D2AE06F6,85601650B8F54CDF,0E625574A2FCED9C,000057CEA1A059E9,083E2BE5FB657BFA,01C133648577D10F,0B285417363B1EFE,2C6B5C10CB0C6F3E,ADEFDD56C69DB9AB,CBC2EFACBAA14E3B,1D3C406D96EE83D8,7A9941A36B710210,1FF67CBC40D235FB,B216D97AAF3277E7,A32CB6CA27B1A425,000057051FA0B17E,51031C287A0624D0,D8FD97FFA057ACF5,1D7037B8DCC8D1C7,68E84E43CCA5F347,68CC7834A83F66B1,0204D75A3B4B9FDC,9FBCF9AB55585E65,1CC466149835BDD2,E5B8276C2D41D8CD,2502E0EC7B807A02,C7600D61B33A4760,00003E5787C4DCA2,F97DCE20F8E17623,BB52800D45C99A44,6B5B686D6956E97D,5CB26DECF0C11AE5,AC752E6666E4C0B0,29BC57A56E06613B,3F58C296DDDC60DF,18BB5199184DE51D,4620B475344F381F,071909D18965E17C,DB14B042E15197A1,00005D3CFFFE99E3,B9CC8EC4BA8AF54B,057275D924DC57AF,C8E6FE4A9051A737,30A20CB13A6B659F,0319F5534C4F7EA5,CD1DD0D03B9CEA8A,E1A0FF34F90CBFE0,DF05DFDD86F43B92,55A7EB0666234E92,7A3D4CC011D03D9F,AEB9A7B648D7775E,000003D2934C0E8C,4235AB9B6B859C7B,ECF2CAD7B98DB759,898ED7771FFCABC0,C76759DD997498FE,64C13E943C4E9542,94EBFF2A156F4B1B,81ADFB44C2DECC79,E775AC51B1F3C13F,AAEE8CB6AF5A521E,9ECC58635B91F2AE,988D89E4BE7C5D2F,0000444344C7792B,ABD7460011B4F00C,532D8CB8FE601BC0,4750C65FF12009BD,4832A3EC07B9104B,70D7BBF0A2EC5787,5FEE266CFBD79D69,55DE1A4CE52757A5,678F74AD5FF2D75A,32FA630C2F5AA0B2,ADAE5CAA04FB7A00,9147AC0C466AF556,00006C36426A9113,A531FA22649F2B8E,901F17FC338D510E,CE949231DDB281C2,3808EFEE4AE861C1,C4EC1C5C4FC97DB1,66A45563D3385F63,41010962D9928F12,399F977191630AEA,79685AD15501B31F,459AF97C6022A776,8C3DEC3AEAC5B280,00005EDC97BE19ED,AA323A6EE25C72DE,172A2D39BC761EFC,6E4B748A82506169,60787CF73C326A76,8B488F821AED835A,38C23F817B252DB0,D116A2E74F426F5A,961B7AC3C4A5FD36,90D2E8D1D4DCC16B,66265EF14139F824,6B61EF15C597EAF4,000047C939D9DBAD,DCB3CDFFE1365086,F33D66F9701A5702,24069225BFD4E3D9,6A1564EF51382377,9591E25126718D0E,535263D1E9EA37B7,BD2EAB0B4949B730,415185088ED8C001,D2132B5CD8A30782,1CB090E23F0901C0,B05B41E2A43BAAF0,000000098AB65FD4,C7FA1E23FC72EEB6,25CCA39A5F344BF2,DC96E8406E251D55,56076B946036DB8C,CD6DEE72DF285EA5,70047A1756451461,35CF223210E2BFAD,5D27B46F60B94B02,04881D1B8FE1A7AC,35785C95F6F55A44,34B26CA3A0187D43,00001D85268D43DE,74037E6D7E3FB13F,D6312AE4E3BB12D4,EA4E0A33E1E67D09,9E7F850EEDBC8217,34424BA50AC7EB17,5C3E69576A5357BF,797CE7F8102D6B7D,A24E8684D25B1D89,892863B48B197C2B,D9C44899B774A554,B9A6BB0B30F4E196,0000340B66BA3BF9,608D6F384026EEC6,2E8BA2AE77710ACC,533F23CCF301A9C2,4B0B422824647552,0D0A31DC93E75345,C83B304FAECB048D,AED80FCB170E7D6D,21E89161C27E8320,0FCD08BF584BD604,5DAECB466FB52285,365943578DE5865F,00001B4CAE8640E9,813212BF034C70DC,A53E3CDC09DF8078,5270562D2DC27644,947FD66D34AC7493,EDBF50B64CBA2010,6F9892A4837AAE77,3B556EAECAE29722,9299EECADCFE1C22,DB7BAFCE39BE42BA,826919B4A5038440,23F921FAF34CB42B,0000010EBAF66BEC,8B4C5ACC89327087,749BB9B0A54D1736,97FC3DBA08118181,35E3BF604FE35339,0499A3054D79B683,70D6B5E8189B734B,0FA1D42567C37EE5,C45F5522855EA5BD,85FEA2FA7D2D5A9C,FFE829E9259FC377,6235E9D5505668D6,00003D96939844FE,CC97A67265BDBE6C,59CD12E965B9CAFA,63CC9411BEADBFBE,FC243E8272208E36,B98894AAEBC6EE32,C839CE7BDE29D8DA,D9076C74D3FC48FB,E52542ECE9EF0368,1831042F8B06D05D,0E84A66936211BA7,7407101DB3D73266,00004DE292811511,CABEA0FBDAEC3845,AC86233AAFCB3F6C,4FE5AF9DE370E539,803CCA4793C39AF0,BFD4644C744323E3,C69DD4370EC5C95D,F72DEB5A9D30DAA5,CE4622F9D7978F09,251FE97F7FD077A2,BF3F21F1B6CF6759,D3FFC9E688D23B9F,000038F35CAB5656,04BDD44237E82E82,54C0F33B241678E2,9BF2BF3B4FDB1840,C73D214D44E3F8AB,E83C08AA46A1942E,52375F61BF4C8E69,FE95C3486C738A2D,5EC8CEAE1394649E,50DDBC1AB797EDC5,FE813DADB354475F,883FA7237AEDA2F0,000036882885AC2B,4A657642104AEBC7,7D5887F2098465A5,BC49D4C0E61211E8,FCD053B26DDC4A13,0E6BA54D21AF5566,9594E75374DD7167,7AFDBDA82D23960E,2FC643A4955F4A8F,A43119C7A38BA714,D990544C5E48DE1D,C3D9E0F645C5C027,00003AE90C8E0002,F362763AE514E976,17BC4A080D5ABED1,16AD432B22B92222,3D33C7AEE1852B86,9D2878B8CA96EC8E,705C636EF3D2EC3E,A3ABE4031BE2ADD6,9BB89F0AD9630DAC,11A142A1391CB3FA,3DFAED4D4214FB56,2D53E8BAB24A33F0,0000607F39622352,A13F00F3F33CDBA5,B1F5039D60BC5287,57B77FF8402DD276,035F23097216D97D,66F3223B5608E627,7393B37B43E5C7B1,6577C74EEFD8E155,8C0ECF9EC257EDCE,7F92EEE8ACAE07E3,41779FBC9A9FC9EE,A8FBC4554D20A844,000068580A31BBA9,55C2278B268E5086,283FC28DF1B71B46,8B30C04E23F26211,23DE9E953CC8B421,F1438FA80EDE9E33,A7B7C1CD1FEA9EF5,180B4BAD689B3460,3A545FDA125070E3,19AE2D6FB9CCDE56,D01B3325DC41A05D,9BE73AA4946AD56A,00003EBD60BCB498,01312BCAA37C024C,466735A50B19E1AF,07E2673A658C766D,F67104BC49D52CF6,832183C781FEEA61,B2385C935621361F,3BDCAC04C7563A50,64EC17F553FEC3D5,32961D11854568D6,583996C4F7ABF4CA,234C9F65BA4B1EE5,0000603B9C0B8982,B021481C7CCEAFB6,21687DF4136E9AD8,0FF23AF72ED8177D,93C0E33CBF2350B7,0FD4943ADD9D0E62,32111CFCD3EEADF8,8B7EB509D7089D86,6DF5F248FB7439AD,3BA71B0D41F590B5,12B7E0A7FBFCDAE6,49949DD3E2F6F18B,00004F1BFE14BCF5,7E492AE3A775457F,746230E6D13BC69A,8BEF6AAF8D793BDA,83E09355E9331B64,47D4F690736944F8,E2914E7710F45664,598322645B8DD3F9,8674C0ED16C3481E,437FB8630856914F,939EA4FC03134C7A,D4FA6EF81FDFD5DA,00006245C4F572B2,D5E529AADC5FCC03,087A2C44DED01878,AAEF4AA49AC89723,C3781D5A85B0D3BB,32BB3E4085220713,299BAB0FC71D04D6,2A99185CACAADE9A,6F1B54BF749B38A0,9AACAE089D96E88C,AF501850AAEDB764,0B42D5F2C4D15119,000039520A41B128,1D2141D97037EEC2,30DB89D15E472EAA,02FBDC98D624F427,2AA9D5B8EE7255AC,5846A9B05EEAECA5,51DAD36B5B706B28,D75C9EB9BCF96FD7,33A5EDFBCE50816B,C43EFD80E2C0783E,DB8C646E7E0068F3,5BCE11B42216F292,000020F981F39890,FEC864331BA61548,9B1DEE335CD3609C,A0AA42E2DDDEC781,AE77DE3A676D207B,E7D652119416E1DD,5363864EF6605456,8B9E8C7512D5CC7D,92C62A0D065DBB7E,84C52788257A8999,1E4482646FD05D7E,26FDE4ACFAA24233,00003C7B210C2551,0B84D801D8B9466F,BE73C820F1DFD4D0,E6C62A6AAB6F4529,483E96D137DC4377,821C98837C899D4E,C2A9A3DE43AD5508,288FACFC0BBB4BE6,E23D9776408C48DE,7C751E2B79590D14,A24FE6FF583CF04A,F0A90177C0801DBA,00003310FCBD5588,AC93617C531EB652,7B8FF4153606A83F,1F718D914B99E29F,465A75938DD2445D,1DC0D46AA52F0CB2,BAEB2817B2925E17,17DA389EF5CC83F3,71F2F2990B1DC6B5,1951677A28CEB844,2DFB9D3259ECE486,1EA75261F2CB4043,000012E3A1484972,29E29EE0D1F31727,6F33B0E5F3EF7E3C,75895853FD677E66,83B86B6B1CA4573F,4A4DBB301A293095,46021BB1A8D1599E,88D327C3ECDDD1E9,7AD23D92C2A3A1BC,A21DC1C581FC1EBC,2EC9887AC64A6A4E,3040E02BDBACE268,00002441610966E6,BB7CBBF066C4C2A5,4D3B2DE28C17D727,22CA545C17877A00,8D9B0F47709BDDB4,EF2A1AAE1272ACC9,671E16BE5D175054,0B4D9F1DD94C92AE,C236F9D56A3422AB,8501A7CAD713DC1B,C0CB22DE33C8A96E,75012DA4A55A6A0F,00005E40C272FE41,F1836941510E78A8,3130CCBD9F40E01F,7CEE0956C7862E55,6194ED1200E160C4,E47161C9B0949292,5E38B5A66D41DDFA,D2A8192E71DA801D,97A8A6493D41B9AD,D6111ADC56BAB02B,D6528552B835C5F8,8B9884728E73DA0E,00003BA125A62A3C,0EA2EEF6CFF154A6,DAA2E97939917BC5,284E0E85A45E80B1,7981BE167CAB7BD9,6D47D9E5A2E9B482,5B27910641C22A6B,F6AB5B84C8043025,47F88E7E14B3EF03,A534A2226B5EE3C8,F900E42D222F0B2D,09C37BB84D055C65,00005206447FE4B2,6DEE0623DB38DAFD,3265F8E1CC42A0DD,C684248A8864D98F,3707C2366B2452CB,55A3553BB7A53AE3,5B118D237EA09065,6E0893C0AFBCF428,FE17D208C06C961E,C6C15799CA8751E8,300BB5BD22A17663,9A92B628F4CB2520,00003204055D8BE0,F22538728970D436,657292BA1499616E,18C06D3407225671,6657507BBC029A0A,0E738AF1DC4A2544,1818C547EF7A179D,A50B495140102BEC,D269D33690B60DE9,AF5695BE4CEF230B,3090006B21B00200,2047BDEA7B5E6967,000034AC25EDDC09,EC8658F234A352C3,25F136AABCC54344,D218ECEE25E50048,6CA7AB7CD12030E1,F1EB1FAAC216F24C,1592CF9A531FBB99,131114E0974FEC1A,6BC62364587DA890,A9CE388E88A25CC7,298D7C4B6B0ABEAB,26BF39A9CA3D4E3F,0000003CA0949426,44DEB08D588BFFA3,BCEC1B0702D131AA,4AE29A7EB4D76B45,7DF9BB2F8D362809,6DF64F71F2504958,E6C154BCE18FB79A,B365178764E35795,E0357AB8476D6F1A,F5C4F100441BD9AD,920F95F5923A15C3,2A199B88942278EA,0000283F13066553,AAF9A8E374C17E88,4DCA3CD7DF75F815,8A85EA4E75B4FFF7,957E0ACF06A443AE,C4451F7DE85918DA,4E79FB81A62F3703,891243ECDD772E71,FE8393929F6E3374,53307080BCD4B4D7,F1B8A1A3E8FBC96D,D3BB94F4BBC8017E,000051711080E538,FEAFE42B50ED6A83,AFA2A74D48F885B3,1AFB42B90BF9FFBE,7EFCFA95DDBF1062,7678B66E59FACD46,F2E62877224095AB,502602E4603076A2,BD16967CC67D36CA,78CB31F4209033C7,9FC55308B4496105,F05547E46315129E,000038174980E7EE,86D1A42F2A7BB0E9,A9C1595094858BA3,B5F29D190DA6D984,1A19AC33333D7DA5,58312C14190FA4F1,925BEC84B0EAFB6C,384F37C1B4B4B453,C979B84C94178F90,8CB7F00CC0E8C30F,B6D1650648CEFF4A,BD9F8047C993AB8E,0000609105B240F3,EEE119E010EE0D89,C85C9546D2A98BA7,686DB64A8E040756,A8332047F8A83B3A,B24AB270832F972A,4683A684E73BC665,F20F364BDACC4180,190BA19D5F6A103B,A1A3EE223EC4A08D,CFF23355C16FE4C1,FC211E9EDEDD976B,00004FF93C3924A6,84BA872BE26F3C3F,74251799792D97B5,A8FFDDE56DE60A17,8D1855AF823B6078,B14D4E8FCB120A7B,588EC73AF2034BF5,82E1B4D010AA33D3,9D380E8415569A28,2E35BCF8AE099D07,97E77FAE24C6DFA3,1F197CBDE5E02C6A,0000371AE37914AB,BEECF779380218C2,BF6F62CCD0CD05D8,200AA44EBD4F6606,AD8BEB0306F38CBB,3DAACD9A79506305,F6976ED09F533935,AA321D4409579EAB,906DF8D509C7ADDE,101361CA6E8ACD1D,E5DFAEC78EC5A06C,C6EE25345EE54A27,00000D0DA5F98BC4,3625C76165E8CDDE,1B16BEBF31A5EB0D,B8F602EF765D6FA0,1B0D517D6386396B,65BAC68907CE595E,3FC5E91D534764D3,48864EBFC396CF33,1E95A183A16E2DEA,7EFA8F6F7CB8833C,8801025A4C1245AF,60DF7D99CE41547B,00003569C7DEAE37,EE45856AEEEA3FA1,C760DAA4EE90011F,B6648C074A99BE7C,9CCFB19DF82B0846,7CE7AA60D443780D,9F4FD0B1DEBEC9CE,7B991315A641D8D0,C82E8B76E1065595,0DF51109417FD425,5CC4A4A1A3D552C3,071B65B3273384CD,0000416571735245,0B4BC378F49A96C8,AAF18823B751F987,284594629B7915D1,DE663758241EECFA,AAA16FE483EBF152,E0551DC8B09AE2F8,7AF0BFEE016486EC,3A70AF8334C45EB9,A208E54130569349,4306F99DC946D52F,FCFB9774AF02032C,00002CDA7F4A80FD,28D244D81B3C6D5C,36E8F5C31C478A2A,48A56E8DBD00DF99,B7C624BE352F64CB,20C8549B709065DF,1990F1476E65124E,76B7BDAD5F5CEBB1,71E697F68488742D,218FDF238BE042B8,0F737A590D379201,FB692AEFB2C6BD3C,00004439B383417D,86125FF66093B6E0,D4826715B4D5DCE0,FB228FC190EDF023,FEF85A7EAA0342C4,EA632C901943DAA3,506A26AB92F4065E,7F2020F911405EB1,06E0FF6227F6E028,463FC6B68165E3E4,3280FBB289641ECF,ACF10A3B2C16EB02,0000171B8F0BEBEC,55CD49E5A0720C61,1B1B5EE49A069428,742708F3CCB83B3A,346AFB808D806BF2,E692D0F73A55B6DC,99E3882D1E53FC8F,0BD69B7F2141F6A2,888D3381C9E788CA,70185A8AE9467E12,BDE2D71F37FE63A2,AD2DD5B8217FCB4C,0000612E03446EF7,B4FCF234D89CC30E,DCEEF38DA10FFFAD,CD1135BAAF31856A,454574B0B445CA08,24E8FAACB16125A6,3DE6B32254F256B4,B824E2D773DBA2CA,C4A04820B3C808EF,A62E8402B2A2BD71,5298034E73C6650A,B1CE2E0D8ED72BC6,000028C4F16FC4E1,0F012BB48CDFF00F,07A9023EF5A8E0FE,09654173D61EC43B,4AF84F955F1C0D87,79581A69B3EB685A,5CD414476D1B82B8,4EB838F6AF9C2509,CE6DF1F50FB3B420,4328D855A634620A,CC267D6990A9EAFC,067A90C9558F3951,0000641BB2D938A2,47C18C5846AAEC18,15C3F59441B9D35D,46E2D3D038A1F197,E7419CF0365E35BE,687E747A9865D622,F041D6A2D8EE21C3,7675E4E4F6739824,A9C34A0100324889,1669B37A6E10FFA8,65E2532EA6F68B48,6E841A01B5E28420,0000543DA9BBEAE1,57D561A09D23AB07,C08D3AB486045582,647BE4BF4B5C9A8A,9B238646BC66836C,83D2E40A625E560E,3EDFCC192E7DF43B,43DEDABC17B0E40F,FA59AF0D1CCF353C,CC167937B94E5F34,F68715B2029BB035,331E028EF04BA7F1,00005EFA24FFF334,6794C454DE4F0064,E97930192CD68710,EA7E79D3FEB14F71,8D10DEEFB14DC173,B9AF02588724B167,33862F19A1F9C5FA,AA4F637FC4F1274A,97282D535E726DB8,1DDA543B5212CDF6,95644E4681260950,EA8755203178C003,00000FA4C03C3991,56A670DD87500E2B,4353D91EF85A5358,4B720ACCE723B301,7318365664AF9C87,E7F30F9C07AE074E,373DAD195B12D31A,390D1F2236038B2D,3813AFCC823846E1,D53C9916C1DBD3BD,021E82ACCB039001,CA95928A29FADB4F,0000444952F5AB09,87A27AA45A85B937,268A79BA52A2D53F,F3A79E82330E019E,87155C13C4F308CB,F5B3E46FDF615036,684D01B52097A710,3975EA74ECACA8CC,C517A4AB9C3838AD,60011F7974FE0D53,EF278450B3CD477B,9D6B727AA1671067,0000693D87F9E1ED,46048807D7AA5E21,A869DB0006C779B1,D718C2E52F0505A9,03C350A744471075,E71725881060BDF4,AB12A3A6FCDA9C34,C148E7158516AB0A,2152227A0203751C,B964078F916E399E,1BD598AD5C0F322C,2F43172F4BADB268,00000F7AC1013CC2,3776C2A7BFBC7564,9E46EF1ADCB623D0,6D0174DF888F3456,BEF7B4F72A54CCC1,FA42C4FC2D931BD2,473EB8EB97868CB6,A9999E4DD6B519A8,AFB07904F7E195DE,34134FD99225A1D6,51A2654796677B3B,CFC5C1CC5E2921EC,000000FBF0CD134A,7DBDC64EA8DDB962,61F9F4B9021FC2E5,E5C22080B2AA5091,325C70081548B6CE,AF0C7FCDE267EAC9,7650C0041441A497,7053FF7D2CDF587F,571EE18921733270,10B7A358C0FA40DB,2337629446ECF664,F93B3A99D18C6B9D,00000D6088ECAD40,E4313F91FB042E34,8F867862CE2344A9,641B75BE4D79155A,20AFB8E0F92283C6,3F7854254BA1F6D9,6E0A2BB82599478F,5D51E4318D7C16AB,0E8509F2E2EE987D,24D8B4C60935386F,EF96AD97DD90C8B7,8F5114320C5907B3,000065820EB3BA83,80A2011A5077A61B,9A15A9FE922179BB,1616EBEB0E8ABC8D,72820A8DB6183B63,E6BCF825FB56562E,AAFFF75814116F70,0188F438104D25ED,3063FAAA8F85BCF2,F82C830AFFEA5E05,24DFAC754C3AE607,C55838144A7723E2,00002ACBF587563E,D16D640FE8C2E138,792DDD82FC5E7CB0,938AEFD54EF68C0F,46B0FA763B7EF539,1B2A29064C680056,CFA7C0D41B9F1EF3,D5B68A21AA19D2B6,8F1C635C5CACDAE1,A0B5672399802FC5,2AADD916D74423F1,DD9FAB9A51330DCE,00004935D3C63190,1C445EB8618E17B1,C53838E210660099,5743DB67BD05CD1A,B1433A1F50174F46,48ABD8D592AFD282,82C548969AA6344D,D250648678E17D79,FD48B8204956173F,79BC35E2EFA76919,20ED9274D024D8BE,0FC64254C5825CB4,00000400AB494291,ED876033750A348F,98A74DF5E0F0D658,E815D1271D2B1DA6,7A63105745AE6066,60F85A8B1CE28C02,FE1546138B31C76A,53AB0A1E2F99DA1B,8C5913D81D0DD7F1,777D39DDEC15A7DD,5752C78C3C4BB8E0,1096E6B4DFD3A5C9,00001A0325899736,C8BA9026AF4A28DA,DA51E119C42D7E31,6397ACBC1881A4AE,B21A6DD4C2E80374,3FE6BD44C2EB5CF8,39CE45A718261A9C,3EF0003E514E6A63,850D4F907EECB48E,EDEEDD256BFEE6DD,F4FE6637E5CB9F37,6F9297A2C77164E9,0000236F2FE565D2,B1CB507A89F8BE62,FBA876777F8D7F5F,C1EF2557FE6B85CC,1C4BECA9C0071D49,369D2B3D893D0762,0EE02141577ACF76,40B415ACB62D92F5,FF39E4F9490BA7BD,58014AD3E6D02549,C9A4D3A79239B946,9DD023CAF845AE14,0000586D406052F2,9390D7D5B1A54913,2E4B5F40AAF56C16,410ACF864FE63A72,8E7AD61A4C9E06BA,ECA428BD0A381711,F24D365ECC020E09,C454AC83DFC6FB61,7D77A753A0E61DE9,35DEAB73198CED8F,30A77D7295CF38E0,04E1A04A3F02537B,00005B2F08B07BDB,A9EA795AAD4C77DA,FA908D4B92CCB9FE,A3648311C588A3A2,57979FA92C08DA8D,40B1579EF845E62E,928337D4A135BA16,3AFC298B18FC666B,C5C6A1B7A933F9EC,DA790D817865A202,AA9E453C577E5C1E,8FDFF980D6B07892,000036884E9EDAF4,22350A40B9875D1A,639A23DEA3A6AD9C,C7CD28FCB2131391,6F6A24FD0E78958B,653C1149AA91C0E2,F2F28069C43D77CE,37C3941EAD3D91FC,3C39E801DC1F54E2,3D8BB34626B6F50F,3F5091B32853D9FD,EEBDC6F340B242A0,000032B2F25DCEFB,43AE880984282E89,86EF0DD920F040F3,C8504211F9FE5B0B,5DA4B2F2E3C115A4,3235CADD55E48C33,C9474C12CF7FF431,1E4A321B3DAD8F8C,614E1AA30A23164A,6A251B309F7A3032,5A495675FC69965D,348A2EF330E2846B,0000455DBD11B841,AC56018BD48EB4C3,E1FB65763ADB2FC7,8E336C08EA1BB7E3,71EF7BD76F88384E,540F62937A171C0A,A40385111AEA3666,704F7ACF5B14D3A6,75577EDD5A52BB2B,40F886D72FF34157,A7CF5A03F74C77C5,8C344F4AF42C6E18,00001DA7CD7B06EA,4512649A036A91A3,83B76FF4D1B2CCF3,1AA8C2398D862DE8,73636882313E8B81,E7C4D5423FA4DA0E,7FBF0DC520C092E6,9FAD3CE0D7EC6FEB,7CF79AD9766F4512,1E6850C72E2446CE,72BF3E305CBC5504,012041B677686E45,0000413FA21D78AB,AEB1B209A176C122,B2904D6D9CA392F4,6F07192DE3002E45,CF5EDC935B3B7F4C,36C3A319D36F094D,6BBF4A9792B3688E,8EC3416A4A93DD8A,3885E703E5BB8F0B,DA3B37F20A7CDDFD,6920D584AC1A3EF7,09B881CEA20EB5D7,00003B2BE095B1BF,9BA7B97E46370845,CC5D22984E18D6E1,30B7323196919F94,27BFAA9C81F4FAF5,6D01353D627B631B,E88F46D06E68928C,900217D951E3FBB5,4F3A8BEC2421BC3F,5F97CC8A3AEEB3D5,3D95ADA71714404B,2A99419077F86BB4,00002B22A4932980,E047E71AA056086E,6BD42F7F95BFF4B7,E7600F37491A5A17,B58C68FD257A5FDA,FE3F6F053B0813CD,EBC4D5A58FDC2583,A7E6AF35B8221B84,3F96BCE1BDCEB0B8,FAD5F068D0B11F3F,1055D72B6B2A80FD,10BB030E026B19E1,0000609DE35FA87A,AFB8166212852AFE,DF172858419B0668,DDB4A18E0C708787,399F1BB9A070E447,558E92FEE488047E,31A7371A18414B39,E01E030C97A3F3C8,C7CE440D7A4C0599,4AE64E75AA6BAD89,E134B2E28A7E0131,CB2BF9887D62ACF9,00004AB1E9513F4D,1826A5473465C5A8,34F80505E2498731,B42CB40A481D392E,6110131F681A01C3,D74CC5B664B2B70F,8AC0FA8EB7D93A1E,51A303F24E13DF1F,B68BFF871E83FD73,781B11006B18D1A2,985D0FEACDF87761,935E37F5A8A10FE6,000002E8816E15BF,F0B38F9972F898CE,F82B9185452F31FB,FFC3A6754930572E,8B6A9978E116A653,09F8000F04BFA874,D7C8A0E685382158,16808702623AACFD,B039605A02E36698,1A32DDC26499B2A5,C7F7291D08CBC208,FCE01A5D3A9F9F24,000029B9B7E2BE7C,6A825806A1A05CBA,98654D332ACBA59A,F4E7D183205B22E8,485963765D3BACE3,0DAC38BC320BE9E4,508F12FB5DED5B01,CF6B587EE26AE049,552EB7F69EA78F7A,5DF8F6EAABEBF46D,E47AA9A38D0D1851,D5EF8750F3F6734F,000037BC97C330D1,D632BD401FB80D81,75A49D69A069252C,EDAA818ED1A76F93,6CBFEFE3DF7E4EAC,C55780D8DB44D821,0B7C2F5C93E19DB9,15BEDADA14730E0D,E6DDEDB100F3D9B6,ACEF7F79275E48DB,954763130C8A37F5,789582B0D2E93252,000049FBB9670605,A9A1ABD1D143D843,090B231921108F68,ED60C5AB70DA7717,29D51F8227A4BFFF,09E4CB64887E07E5,7520EAA3B9AA2000,9764A098D0EB3161,ADC56DDDFC1D2AA3,55B18C92796BB1D7,07D426DBC22B9F52,D1B456C2DD11E195,00001CAC6F9DA9F8,6F1A6E64C648D465,0E81109B8C7910C5,D5BF455C9CF2BBDA,CBE03065CE6AE7DD,B806FAB34831E7DC,B1A7AD0E3888F804,854219398953FACA,A958BD3DDFB3D21B,922238D97A255C27,51010E4FF3981C38,D5CEB6206807E029,0000661567E9FDFD,D101DDAC7D2A5E82,1C02231C2685F925,FA4EEF4F76B504DD,FA548376FAE4D63C,14C37240CEE1D16C,1116C0C7C78220B7,E43D1E5259633383,19F73FC23E34CDD3,7472B67DF89D78C7,AC1E092B21CDF8F5,11A189DF49B6E004,00003102816BFCA8,E4D417FC6FC1E792,743DA940A013F0D3,0C657B50C8E6A4CB,9D612EF42D5114FC,7ABDFAF7D39BC7DC,32C6785A026580FD,8FB3FC57E3BB4292,D7EE2BDAF1A8595B,F570EC253530BDA3,D44DF0D3814E3935,2FD856747D9E38D9,0000610A502F401A,D0822C4482BE1D85,8B7361A335EB73DC,E46D6C61043362E2,6D65C00A1F5DA1A0,37B8E4AAF29B31AA,65F18AD795974190,B2C1EC0B67CB9499,2297FF262A86018E,0A7EBBDC4A3BFA3F,68B7928E0B1B76E8,E8C7317648909FBA,0000215DD3E70407,E29E9D3B594C3DA1,15B290366F9AC788,6BF0664D49843B3B,995EF37B7A4D6424,01CB057A8852D7A2,049E4E6A9BDBFE2B,20EFB1F69386E022,13D292C7AAB8B9B9,B3ED02D333CC57EB,016C7A42EE2C1492,5EE0A72D927A4861,0000101A49E01D13,EFA075F21CFAECF6,45804159CC7CD4F4,0A10113E5F8A929D,92BAD65EDF374449,E453830B06AD448A,EA0A5177F6B2228C,41789B3EA7C8F495,1E803705DC7467DC,50C35A4147E6C022,2D04DD653780F279,C144A6DF2AFDC3C7,00001A60993A718A,319ED199D7D2DE2B,7C1D9149BB86F73E,58623C0956399816,677704777D0815C0,EA1F7BBD8415CEB9,F0C1BA61789AFC73,E7ABA8ED0D8D56AA,5493A701FF1DEF4F,10416D1B053CC5A2,EACD412147065D90,0C8CE3BEFA86BDAB,00006C135F66E626,BC1DD6C03A4D6C73,1002E095A5DF2D0E,9B6966901D670B38,F3C85E9338831DF5,84534DC17133F28C,F4DED242564E859E,E460013F8B092F73,D5A2266080784C62,BC480360CE609419,FB7B8811092CD4B3,AE2FEF008CA1B500,00004276BC04E291,B722683E69B230D9,9256DAC2D5D6536D,88C8AE2C008D84D0,739BB617D6B33704,B1D36B44AA66C1DA,EF85A7745AEE4534,21174ED6E784D70D,846410636D4BE6A0,3C317FEE55F0284E,A96D3DE6FBA302B8,4D5AEA97F8A38719,00003906BE3CA392,7239C1B74B8984DC,B8D3586CC72F2A54,05529E278D2DFA81,C50B4B2058A0BC17,AA010D9B71564C6C,F89282D38B1E1C22,A898B62DBE14C747,6D7F0B17F5FA166E,7B2BFE40DBC48900,931D6BF77A69BEFF,50AAC9B3E02F1E8E,0000142620B1418D,D6C8E55A10E14E78,D8CA98CCB389B10F,91B164F89CB640A8,0CF019263200070D,E11103745AFC9A81,0C0659E5DC62179C,C219D4C389C20AFD,292B02914E939DF2,9A298F9661D2B4A4,EB51574510CF48BD,18818A92BE52F7DF,00006EF873472D8A,BF264A64AED0DEEA,09E82BA9770D47ED,5AF4551EB08FBB23,70D81A595DF8D724,949361F5C0DEE2CA,1D082F63498EA9F1,8C03D7742162C288,0690D66F23FCA8FA,A0885435BB0B4A2C,BD02042780CEA59A,1BB62559F2F53931,00004A3D29FD2D2B,68743A17E852AFE2,9095EC46CE3142C1,2A8F71F079C60B3F,6F127196F41F26DF,05D2FC6F65CAAD56,6EFC47D6DE0AB2C4,E102577A712E5B34,3525CA004F5D9B44,213ED7623B72D020,0A1570C5D338291D,1D502FB3302A8345,0000455251041459,5AD2EC7E2EA497C2,96B18367E9458097,A8BF78D641254B95,2311AD9024BB3632,08F3E348E4CC6ED3,C4F58EE50B4246B4,8B0F09312E3ED898,73220F87CE2F6659,480132E3A4AE5385,085131E0BBBAAD2E,56BFE502913E999A,0000627261C2E6E7,84F273E88BDA895E,18B30EABAB162E81,34A743BA0FB32846,63ACB484F63EEC36,B5D5FAAAB240C4EC,89883B996C460B95,7EF2DB1253C94AC6,223828425B9DAB55,C9EA81B770C46EFD,4994F2DC611F2033,DCBDDA8C05775F7B,000063550430BE47,F92899EB97C7537D,6E5718EB77FF7324,27AEBD1E05064041,4C2D6ACC603B0E74,9BF6457252EE46FC,4FC0E827AC07136C,5C95FEFC3F404EED,D70B9AF65A387A02,1E94F561B8249934,6AE17C3266526B0B,CB5BD257C043DBA3,00003DB85E0EFF7A,0108DC87953AF0E5,30FAFC80F85EECE1,2AB0FF74C490B880,2FD832E990CAB9F5,74608CF1813BB2E2,BD58CBAFA6DE8F3F,53EC90E1DF34FB2C,C3AC0466F805EE97,005D3203152F7058,56236863F87E1897,CBDC0E43685DF565,00004F241CBF60CE,36B697F58D6C320D,38504E082DFB9AEE,59C793DCBE7B51A9,B374210AE11DBF30,EDD02BF7B0D4B956,4691DBB0B60611A5,D40EE3963AC77847,29BFAB05D1C9EC51,59A14303983E75EA,B6EED2D4DA45BE5A,D25FB455D77EC4E0,0000206A96764883,AB87A3523B00687D,6B1163824CC5442A,4C069585443C6F9D,CD130F48CDB5B25E,4167EB7BD4E5B934,779409C0B686A20F,9EE62A2ABC2A666E,6601D2DDD1E5D8D9,872577A969CAAA93,1567A4BFCCA4A270,EB3EB0354D4C9903,000025E40ED46509,3FE5D07F4CEFDF46,F9C10A4F7CFDBB91,802C945027889C13,46FC3E9B6D551814,4A2A4E6CDA0B234A,DBB16FAFE9E5C6DC,CAF2E55A270F72C7,1828EE722B958DA0,599E9CD9465B1CD5,14380638B1833F50,C094C02191EF6C78,00001209C7E616C5,41EB2773FD1B8733,EFE38B5D99F3CBC5,6CA5F88A56E9804C,DF4CD4E33BEC9E1E,3C733424D8C8F0C5,181DE57789F10716,34835C86FC888848,F47600112E5A6637,02485E77B9FE13DF,6504FAA83C54B83F,34D863ECD8FC59AA,000033894787AFD0,F06A7AEAF077AB84,A87BA5FCF7170217,785BDB7CDF5059BC,7AFFA827E23A5EF1,704FDF4FB8CA7048,296A109A0FAB6A43,7BE0372C4E2D302C,CAE1819B7C5A3188,C133AC6948C995DA,8E21F95D5AB5A239,F4B767C04157D55F,00003F10C39E4446,2C65720ADEBBED44,C027291AC0FCCA45,8C0BDE9AA4BFF1D8,C8ED16B33A02D50C,8549728BFB8DC86F,FECE348DB0AF8BED,DBC588AE370A7C33,0D88E5FCF63E2953,289FEE55FB16D965,C0D5D9FD3550FB65,FB1889E31475DD05,000019DB4774EE8E,EBD59F31659404C9,2EB4315BE5758688,6801298D8EBFA2A8,906FF891C71E9BEB,CF5EECB685F980DF,843DDEAF3B760EE0,CD45D12212A1945F,F5240095B80E9107,648E22C29628FC86,AD83ADD024EAB421,BCD7ABD1AB27B146,00003F305C10DE78,7D5A37026DCAC9FA,B733FD5D7557CCFB,6576097C133227C4,DDA898923300A9E2,7D8FA228BD5F7893,69AA1694E12F8043,5550E36F129A4B2B,D8035D260723E346,AB1C6D5413E60499,3D09AA1AF7811ECB,7A23B2BC61A932E2,000015AEA856E07A,8E9E13E51222BFF8,42D572294398758D,13D13CB75451F8F5,B49C67801B4E4D94,8788EF5393E7E92E,C93D5983F94D01DA,56E6486DA902BED5,8A0C93902327D95C,1BFCD06F04246B13,D7D472970E8CEEBB,49E9F514F4C4D15C,00001EE89242D06C,2A5C751E2B12B5A7,99BB1A3669CC99A7,B932AAFAC5C6330A,CE30DA0AA2ECA4CD,F3EB95EC827932B4,1E7CB077FC211A86,7B54E3D5CB591DD0,9832A0F0117A70A5,999643A0D1B2C2BF,B26FC7413E2AA359,5CD5DA55F23316BC,000054939BA71FCD,0FC734BF373AD61B,B9D363B46EB5AB46,22D5EEE7DD6027EF,295E76030305F7EB,FB5590FA15A73C4F,9B040742C7115178,3A4335CF897A8E46,45185C84F67B06EE,267B4984889FA6A8,6F124D791FA4E903,E74F79752F392F9A,00002FD8D66EB83E,A62EA2CEE6BB9E18,DBA953AD3A2C1EC9,B28243E31DA0AD31,48FC684794FE4222,CABA18451D08481B,8102C98C57C64D60,10B59A607E1011EB,EC9AB027E67B602E,470049B422F2D979,BCFAF5EE5508DA19,65E2E8BB589E937D,00001801438CEE6F,390EBD4B929C38EB,EFA4046DCBD40260,00D7B96513743C1E,E9FBDD1DC3F6394D,32E1819B5BECDDBD,BC4CBE4673F4ABD5,0619FE62CD35893C,2C3916B653E17B60,4DC25350844C43C7,B414235442635C6E,B915C9D097884875,00003F209DAF8785,BD4C3350D5544B75,58F07341DFD4FCF3,0A5141FD2450716C,BAD376EE0880A2AF,B9A85C7078C8CED8,759AA7DFFBB41EF6,074FDD925987FE48,F3B4DBEC9CC7B95D,3E9F009FB6084BAD,63A9C2DDB0BA196A,FA8134A2FDADEAFF,00004262D48E916D,BA9CD922D19ADDA5,4632DA714579BAA4,9E27DDDD00394CDD,3DA719229A2613A5,64C1C6907973C921,6E341CDE9208B7A8,7BC1AF755B94CC6C,5D93C788414157EC,59615AC5155EACCB,64B97577B6F0966D,AD78E0127E3B5BBE,000031CEF74330CA,5F2DB2DA14B1C5B7,DD297FDD9D80E2DB,4AB36867630D2C19,70D5C6091AACB229,5EDF74E42610BC9E,0EFA451A6BD8980C,043BFA16EB0784C2,F29448E01137CC62,F99E7F1468E15E4E,9053271C60AA5D7B,C14009365BCC30C0,00006BA4161BB0EF,145868DE8F606810,C0C9A688335CA9A2,217753820815F41C,80B4D1F343EB9557,F723AA580FC52400,F363AE21CFD0BBA3,810D91B7DD8390EB,DE6F8A166D73D9A5,F87C7407925ECEC5,D5605CDD19E0F1A7,61CF4401C111D593,00006D78A616FF10,6DF8CB727215DFB4,59DA871FA081D64D,CF95D2D57973E5FE,2B071D022FB8A993,BE0921092244F29B,D3338BEF47DC6577,582F9E53ABC55498,50A4CE04FA5CB40D,A0C67C54AC0628AE,2442DD9807F24612,86FE69B1D40DD69B,0000562045002DB8,A1512AD2DA940862,D045B37131DC00A2,41BCC502F5F1C933,9E5E425AFA67A16F,665D96FCC12BB26F,FDAF0008AED67DF1,5B082349A0E42614,B013A96F8D50604D,12ECE4A408883B8F,8412AA31C35E6395,1675F255FBE3DF21,0000316F03E81BF4,6DEBCC9104EBF868,16D3F91EB5BC1BC0,A54BBECA58D88721,D186ADF012C12B24,26A4EA499270CB14,7629885ECABDB0D6,EE407BA8B52FB8D3,486B8B53A34EE3A4,7FCABD689ED6712F,8CBC21C29D65984F,2747F03933626B4D,00000EF4BFC7A8D5,B68FED6F73F47B6B,0B9EB15CE5D6E780,2F06DC48A35BB421,D3CEC77D0BC5F4F9,2407A97889FBB8DD,5AE11C01D86B5016,35A199335A82CB8D,32EA4ABAACB6689C,87C82A618126DD71,BF4D478F0B9AA667,BF926EDEF7A813E2,00000F8B35C3B980,5080091252D8749A,D2E43B8709255E0B,2B4BAC7F43AFB85C,81E5F4EFECDE8DD3,30D9889D6F5D9A61,82399F5BF1292358,70FEB632D7A78CCA,FAFACB6747982C54,0CB4EF0902691A62,E22CB87BA873B660,395886EB1496E2A2,0000516AD8093BF2,0CF135E59AC602C2,44F3FA973BC290DB,264E91E3CB65D5ED,354A1E9672B03FA2,4458609F98EE5158,89CF36987498169E,53D6D0390C1936CA,81239607B20E41E3,ECC137EB539DB14A,4BEAF3F010A68D3E,36092886C8CAEF98,00004E7D81C64722,D64602826219CB44,82C3AA0DE73B143E,E59B89ABDBFD5BFA,D3DE69E297DFE646,6083CCD2A75B2BC7,D40F0F8DF951AFDF,D0D3B629D1E8134C,6AFCE9CD132FB787,A54153CD180064A2,B4AC1998CECBD8C1,CEE87968D1C26C1E,000067E06E28B574,0E796F85D468C1B8,173644C73EFF0A14,41F490A40048FC55,69B2ECA35ED0BC42,4C5BE6D29DCB09E1,74102FEB7C8942BC,D71EF3701D14FA90,31F62683F453B396,2B356109FBF41462,F4177C5DEF47B0B8,A68BE668B365FB3B,000008DB95B33325,44699A1875757D55,96CD1FE0731C17B0,5613A70DFD31D7E4,8C6B3E0ABF105763,2313F24EBB9967B9,4855658D5A21E4D2,8D96C13752345575,BA5A84C6821550CB,1B0B793C6A7B8852,4A9A2A91FE9FAA81,43884667F6697D43,000008BC3B8F50EE,CB5E39C02E03B5A6,195A837898B9CD67,7705CBDFEA003357,254A5FA27D5BCC5D,92E70A47CE9BB3F9,73C9ADC40ABEEA72,D7A12323BDE8BA3E,2C118A1DB209CAA9,12A5C56C86D3002C,C77731FE5453B0E0,3FBA4DCCF0CAA0C9,000050486875D0F7,F2A3F729E6461A90,33D523CD49C4175C,22BC06C4328F55FA,594F49BA6C0EEDD0,C1A4EBAE3EEC2350,252E5F82178A407D,09ECFE17D82C0DF1,6F077D5F4BF7CB4E,653850866A4DEAD0,4AD7044625A46346,CB4A47DB71BDF055,0000492E992A8DD0,81D911C0646F3ABE,7CD6256E954A6777,A0DE13E0DED7892C,C276CDA4D14FFB4F,E4D3E410DF3BB9B1,BD8C2E06C96D83EB,608D913658773E18,3202D126C1AE1012,D3454C9B19269FA1,BB3BE770645CFC92,D89C583F5553023F,000037511DCEA0DE,843D3B6D0B87C915,480E10DDE9A47408,B7A70D66EA4D7927,797CD48913D82666,A69DEC44FD400739,A4A5F5E985BE206A,4690B4493462E85D,B4EB618E87CB1921,66D6B9E390401E92,CCCD6DF41960F254,4A4C41E1ACEE4A63,000039F3C8C0F7BE,B912052C3FB9A9F4,6F20E5FD7AF5C997,6CFEC727A17F0D09,966088B0EA5AA98B,61D22A449955506A,458CA2212907F80F,8AF810AFC57921D8,903AB89B4A201644,2269C2B128EF98BC,D6043987BC85A055,1BE3AEA795F6A48D,000021FF303EE30B,EB17A3CD5EE7C71A,01075123BCD643A8,84279F98F9EF3663,BE6F3795FE04C3F8,BB171CE98074A8EE,65C06F3C4FEE1F67,A9ED12409DD326CD,632AFA14825089A8,FB64D2E837D3544E,90F849796CED8B86,9D41C7AA40A5E242,0000144BF94473FD,37739F96485EBE25,8A3BA6ACAD3BAC3E,8704E43CD0462CBB,54D38BD6378F497C,4C0D56AAAF5D0F97,9542F5D24B67F593,CCA2C6A9002189CE,BBD2398558ED7228,2EEB8B1A610EAEC4,2D0A0FDF9181D353,8142F1A5B3C1AD3B,00000FDD8CCF975F,721A554597DDB1DB,8BF73EAB29634B82,21201A9468897999,F3E059CCB1D43FAA,174B42806A8B91CA,BC6CD57B45164668,E13ACC1DEFCC5DF5,3191CF1AB31F286D,03A1D9994CF0AEF8,3E3D40CBBB8E8598,FBF3B1276C69CDEB,0000485CF93B361A,CF3C288C766E9F2F,26E51DBD8D2FA4D2,CC712D8607AF628D,8B3F2000D298C404,64D58191052E7B0D,8B331D70FBE095E1,4FE5EDAB3864F890,C21F1EBD41058E62,572C410A20635E8D,162266E3196A9C4A,8864A59924B2B747,00002A27456B0E5C,DA3B1DAEAA7F556A,269F4260E4C2529B,A601A3B7E487EE69,DAD75436BE51F9A4,D9BF2525CD03AD99,28542BEFD5BE209A,EC66B24844B7F7F7,435E8D88032A6917,80DE5C279AB351C9,C78B4F7BD858560C,7A9FFCE7C539662D,00003D75B1728898,230BEE27DC715D1E,6EF6C93DA5D49C81,0CDBB265F50A4C7F,E7ED8271776C790F,3A17D2F08CD76246,FC945C410DED319D,B3EFA9C0C89C0A38,99A30A8916FDEBB3,6C9E479E745A0DC4,B2CF7E102C06E419,79DBD3270E548CEF,00005D05A8655AD4,42D9CF68B4E1068A,9A385800DE6C3B44,811C31696364E184,C1A4482C8FBC6D35,51B1603A9BB24C76,48918255A5329200,1A498648F334DDFB,9AA96DD5A44F43E8,DDBF81755C608468,3B3C71B275F33421,387A067798DEB56E,00004F55FEFF0E3C,B34B3B132BECEE4B,EA2343F0BC6B6223,8B91397B7CA6B264,F93618BB7F16F0CB,3835672EE0D994B9,957C528C5C7F57BF,3C10B4B606EF9B7C,5A74BE33995A813F,F5AFFD989D385405,1323CC6350B9AB75,ED380CF97319FCBD,00000267740508F3,496E3D4D2D1DC124,45EB0244B3708532,5190E9C010750286,330A9707598B9AFC,85A765191B01FF40,D681673EA232B1A7,FD2100130DCCFF28,53411206F1FF2366,D8FC9D9D575C9F3C,5AEE439D462E3C3A,B24F3EF0AFC8B4DE,00006F6B754C06B7,F3AEFA11103382A1,1BD505C406EC5CAD,EA62272127FC40D0,0937754E1DAD5CDF,FC29942D8340D386,4E26D99462CF6ADA,2DA8D2A1F5EF09EC,3D54A0F9045BCE09,777FED512942BD2E,8420616645ECB3D4,A102D7A4CF511750,000055368A40EEB7,39B3578F810E899D,2E4C0F6F25479755,03CFF221CA2630DA,3473A2C0250E8827,D961186D6ED192C5,F33A8DD9E725E442,F8C6702729E2F46C,A924AC2661757A52,7965283071C4C3C7,B1810FDE6C8809C8,2079C6AA2DB4BC21,000059DC7910234E,A447A380F52730ED,5D1D0DD35158FACC,0604E022DD195E0C,FE14BCBB6CA49E88,FB1F6179DE187625,C484CAC4581C771E,E5DE81C9DE982FEC,97F8DFE6616BB7EC,8A796EB01B49952F,6DE049A84B2A8441,D7354C6CB99BEDF5,00000B82C02AB2F1,0CAAE500BD7A1B7F,EC11EB34C27D53BE,B7A90D595423C24A,F3F9F965A3E09F7C,C43CD8CB3952FBDA,879F27CBF33EE72D,F8294F89F0EAB39F,328D1CC8493CAA43,CE02D45D54356F8F,ED6D5C3FAA22F9DE,4D35F6A6F3A787B2,0000104FB37B6351,737E5243FB222E05,C10CB2F48230972E,76036CD1CE5EAECE,4338D4FF145A5767,1CAC39661E56191E,B5942186E3397204,BFEF742B1F330550,87903B299A509AF6,DE62609CB2BFF80E,43026BB131B39C8E,F3DA9083A1F52F2C,0000647A1FAAFEEF,AE6E7B0C08B3A94E,9E4DBCDEF37A9DB3,66C576F5F42E459B,3D0A3B6559981542,1E2F3DF4B6D2D040,30E2392FFB8A83C5,3C506C86B4276774,1F3891D4E8675E62,CC8C505FAF60391A,F52AD00022EB8CD0,FB12D07FDC5498FF,00004DAB2B2BDBA7,6C9DF2360AFD2AEC,BAB43A20CC5B0A1C,5F9EB1AE89CABDA1,9D909F875237D280,AE8B88D24B825FD9,24C8623D5B067AC7,09597F9DF7BE3D27,B634B798C3DC6AED,C38F328569E132FA,6C41C2DE37F59B73,25D7885F729F1B33,00000267CD446C95,F53197F0F4A91554,DFD0B710F9640096,8B181F2971B9BCA8,DB6D1350E9D1C868,C8C1EA9D38C6DBD9,5975BDD2FCFC61B5,BF5B9303699B04DF,EE9ACE9C3172B243,C5E3981B6C4AEB7F,21DDEF1DEDA0A3E2,4DC612F788FDAC03,00001D022625CD83,ED12F1BD5185859B,7628B1C59130EF4C,3402E2781A0FF48E,1BFB53D0E50C942E,BAA520919C98AB90,195D2DB14FD117DF,9D6B7317F804B0E6,B4A90C8B6C840323,F5CF2A86BDCBD0A7,090481ABC5C1A065,3121A0A74546753B,00004405F1E9E3A9,5B71B498E72910E1,19EA3ABCE88D376A,D8B0C22072A92E97,B7A9A78594882C71,E869345FF268B9DC,0A377B0FA9096642,DA2FB79F801373FB,7A920D367786A773,A0EAA8B3864D96B8,C1FC5BB8D116EF92,E89FA39A28545BFF,000018418CD916B2,AD12F863C342E639,2E725AACCD244208,3F4A45A5CACD7742,35A15117DB725931,277D1E7A8EA290EC,181E834F2999EDBC,9AF04DAAB4B509E5,110E18E0ACC474AB,6C0861B55BDF97E0,AC4FD7AD6176DDA4,84E840CC8812593F,00006E90F38B8D2F,7689A19BBDE1F6DE,FA11ADB236BED565,CA6D92DF60A4C98E,86EBA2DAAC3E8213,737E0F006FFDF377,AE232DF96EFE482E,EE1F16CAE9529803,5FFF9767D492B098,DE1137B311971516,08CF9E3082E678DD,A133BF3AB88A87A8,0000208C90DBB775,FE2B3EC17FA9C050,49A651CC1EF61175,63F158E6170851CA,6D90CBF0973772AF,3DEFCD00F5FD5AC9,EC2713FDB759A313,299A903454A5AB3E,6BA46B6B09B4EB17,1642D4DDFE9596B9,301010ED9F5C53A0,C293EF22FE9246E6,0000012E459DB91D,48A7DE7296C1140E,6C30939CD9CCAF39,ACE3A536036FE0C5,7F5AE61534A962D2,6F68AD2A982BEC4C,443CC4E9A5437F0C,E27E8E743EFE899E,1C40AB46DADB3AD7,4A1EAD7645ED9C2E,10A76E1FEC5A5EC3,510FBB0947FE8A15,000055A058D3CFE0,FC0177406896A80F,35D0EE4F68D100E9,11CBDE7DE81C9976,75026FF33850C910,8A97B007FA194C24,9174EB469273247D,D51F39475D9A576A,79FA8DBCF7259AE6,BDBFD4263CB72DB4,095C8AF6F1F062C3,704D88BC27815EB8,00002A7F1FD2B115,032142F9CEB0E9AB,49A161BF4DD46F28,64113601A1244B32,D70FC1E62CC818E8,908F22DE4A32C3C2,487421DCA4D5FB07,2039713E7B60AC0F,47260D8E6B71886C,3E9F1CB9F39FB48A,3F2C8EFF00B736C1,E28AC20BDA7664AF,00002F19C6996677,DF6ABBA1FF7B7BC3,2F2AB792C9CD265E,AA4966EEE8E9001A,81ADA56DE31A8523,2403EE3331A84BEB,00D3A795DD70BA03,363B5B88B1FFF0E3,4C695BE03A2FC2AE,67CAB90E49E844A5,68AC408F94CE115D,098B063A0B4C10DE,000024D5DA3B8777,E6187C0E42B485F0,97AA6356468C352E,75FBFC155DCF1233,DE44B379B6F6B7E7,E2D647C2BB00A386,E639BFAF41DDD3A4,776D38257FF554B2,DE80F7540360324D,13E8F289A7C21AE9,43F18A0A39491DC4,09B8EDDB691FB8F1,00004A76CA38D934,B1B975E38FE190DC,BE0EC25257C10303,5CC49F5EF01E4197,EB037C905CF626B1,1C21B9830787A172,2F75372762A7525C,61F731A241EB2B9F,01B8A6A27D4D00A0,D9938606B1F83903,6126CD8708751B9B,A2009E0CD7FB7E99,000055C2AC2D18AD,E4CCF7637D566689,CDCAF7A37597CC1A,D3D2354F102CAF6E,DAB02424482B3E3F,A22D7C1F2EEA55A3,2B39B997F096967C,CBB7DD166BC5DB17,3507CF82DE22AAE7,40048B521FDC0158,0836EA89DB967C38,05305BFAB0660AD3,00002D40AC088BBF,19561E9FB447CCF0,24845876FDE9F991,CC88B19DEC59DB28,252FDC33044648D1,CFE889D53DF2915D,623FE2F49E318BAF,F0DFFA0329E8957D,7576C0190AAF1DCB,08BDC5085050C025,962054F188E2DF8E,26DC4304A2ABD97F,00000A8DEE6D5BFA,BD90EBC8BF13E221,7C464CD691D0F7F6,6559D25BCB46A270,BFB0079BBEEB072A,B96586D6A1D00F86,6232178D435C4560,9A93D8443B3751AC,99784AA8785E9F7E,DAE87178291EF279,F9F8D0A18456F670,66AA21861A6E5745,00005C7224EBF476,09FEA0CCA29DF058,038667B9F4C3CF46,59744663F06238E8,3DA4A7D004CD5533,42E5F441923E8EB7,B26B63A5CA6EB943,8AC8665D04155701,1A1CB79743E699AE,1526CFA4EF614AAB,4245628043716E51,D355B5DBE49FB2B2,00001940B9D833C3,CF87531AAA09AA61,DDD2CFD7B2B5BBDB,B92BD168AF12ED0B,DAE7930CBCBC4887,4C0AC2262BEA0248,7A0CA08CEABA1593,FD68DD646BC5EAA7,313582F5DA3049A4,A68380BE7EFB154A,3AEA17F9C6F3A6F8,29928EECAEFBB3B0,00000048ED92AFBA,1BD00455B3440BB2,46313AC46E911348,E277D0A44D293ECA,842E2E58BF7132A8,AE6947D28272190D,307FEC2247ED8774,B2A484F4D60EB979,F9061810A6407897,6ED2044AF0133034,283C786DDEF162C6,DCBCA07BCB79B99F,00004D0D165DF0B0,3AB8A86740D4F4F3,CFBFB2395FD55188,9EC1057C63F51BBD,306B137DD0663DEC,CB8F53262F809014,D31F99540ED3E64D,B5CC9B9B315782AD,29D81ADB4CC4F9C0,581E592D84C2C45E,CEB8CBC79C11817D,E66F90DDA56E2594,000035F6B608DBDA,6F3DE992269E13A8,8D1ABE1E26DFE7A7,A808D9D75CAD660C,A2A07DAA67065059,A035E7114DEE8312,DFDD9900BF1DF036,2FDABF02BBEF173B,1882D76E8DF431FF,6AED2B4359F72829,1A45FC5C2ADD6047,5763E12800A8DA86,00003052941E35BD,FB5764B50287001A,0CD2D53929251743,0F51A966178FE51F,42F9C237F233B6C4,74DD95B47CDC9245,9E819C500A5E1878,0E2E7E023C1AF87F,424DCF8D579B305D,06E7F3BE177ED634,838F182FA3A8228F,B9BA74C528783122,000024328914BBCE,83467FE500518ED9,D7F0A20F9BDFFD9F,E4D8D77AE1D47CD2,F56AC2915FABAAB4,D88FD6C78DCB21BB,A55AB4AF5FED1B4B,2305C692E27B74D3,9831458F42492CD1,AB5E7C14A3CC7BB7,5BF199CF419C494E,D2CB147942F3F667,000065849602CA4D,93429157F0514DF6,5A6BB493234304B6,22C49724C745E30C,B0E2B23420E21113,12371AFA04F53A5F,E502CCFFA79373E6,DE2434C5F87E434F,9BFD5F6ADCB4DDFF,7FAB01696FB6F558,56210994974267CE,4BAA81F0635892A2,000042BE4AF4E095,17C39C08BDE3D7EA,83130437EB0DE185,C02452E3AE4EA747,59952CE7214D5D50,0C4920EA77058A9A,801CCA50F1F2404C,84154EC24960153C,12C9CD6C229F8043,D9668A3EAB4454D2,66CE6C8D96342B4A,D44A68FDABCEA5AC,000062C9BD111842,AA6E2288CC13836E,E77B73FD684A29BF,BD4FBB2481883344,A57A58E80C20894F,610E5278C8AC2DF3,D7734AEE049257D2,9BF92E1CBD310C65,F08974015DE20D6F,129627D9D411EBA4,79E8BF4F5D346DA6,F07D557A6FE68C35,00000E50A32822C3,CA44A945D4A68A70,2F399EAA8700DC59,30FCE16404F3E99E,76191AEDA99B84BB,196896EA2C83E2CE,D3FB4A34336A6238,9BC4529D30175737,F827E038E3AD263C,7815E334339E8469,C7022170F61922D7,A8F1CF522F2A4C4D,0000275BD8B8B2CB,1D60663D0A93E5DB,C2A72FD9BE15D04B,3DD0056A76DEBD38,3015169793B995C9,87E2DEBD6EC44E4E,AD1D31A97005C0B9,8DA3CAE30AE6136A,89AD871E215F61F7,5E6C2029740BB1F8,574A1D60D1894DB6,C3EE5BAF2A54D5F0,00003D11D872177F,DA40442A12A1E37B,9DBB8EB538847244,F3441D93252D1A00,FF5B0D135CD7399E,CCDC9498153C812F,F66008D872D92123,A05ADC734566D9C8,C7D36AFCF0F144B5,EA4C53431767D327,E4988E57468FDE9F,75776F295DB2F5B6,000002A06AA95DF3,53B032A10667A72A,101737A0012766FC,61A149A29A47536E,A5045CC9321A97F3,F469D08D995FAE16,B644BF5C1F03E886,49E03C21F712A49D,1A2C03A489221FD5,34BFF1E610413255,88ECD4D259BCBCD2,AC24CB35EE934347,000023A0CA66BAD1,E32B0E7A371778D4,457519C5274BCB37,A805EAD021AB5319,6E0B7F6AD1228387,0A06F61D95D568C4,A57BA7A337979931,621F0B6B8C7EBE82,5243BD59FC0FD8D0,4907575B672754BC,794532F1DDB0F3B9,26B4CA1132E891E6,000063346434130A,6300D570C13FAFAC,B21AAD4FB6082835,CAF8F674063ED96A,353698741C073E4E,7332CCF7E3D404EB,30F6BA21E1768341,18D25B8730608CB5,231D4E9073D4FA05,DF509D1FC8735B77,6CDEDFD9EC048968,2A3D286C654512F3,0000483EF572993B,FE319F697DD47D2C,319C48860EFEF75B,3DA6EB8D30763FA7,E77FFFB6BF3A66D2,4069B3117DE3DFC9,EBEF37841A7D818D,072E5602D337ACC2,16CE25EB0106D083,C09A515C5C5706EA,9BD8224CE77B645B,019B69A4BC46D257,00002644FDE178A0,9BB1DBE653228DCB,D01E3D291F7ECE87,FE9971CE2958B218,DDC01A51F742FDC4,6E4059A3BD7B642A,933D13F126F49BCB,1F72FD28C0C18DB7,0C16F5D5697DF988,E6D961CE92AD76E4,7BE75F286DEC7D9A,C5062A8611C34BDB,00002BD2AC332D7E,84887D2D74B753DC,D559DAA5449FE242,39E7CC01F469AF0C,4CECC6A75090FDDC,C0CA6DB6A6A94660,C11329C047288740,90BD21E2BDAEA40D,B52482E6E05E24AE,DED1562A980BA99E,4D791BDD37933CF2,08AD0B127F146E37,000046F1FED7D937,A8E2D017E07240A6,E0824A6940212F5E,74EC52F0AB52BBC8,9C4CFE4404405777,A7E8A041C29719C1,CE395901D3686619,4390310B7368EB19,86A7345F4972B409,0909DF1388A83ED0,16CD22E8885D1A2E,17DA8F8E4A12A76D,00003EFAF72C6770,31846E71F59B3A2B,919E5E98D163EC8F,1139F6792E869FB4,7D8E42FB728A2EE3,762F991360CF7E13,B852E5145C3ED4EB,51342A8337219382,429D66E86260A349,B7BFE452F17FD3AD,794EAAA3E60CF887,D0BC839F52D8DDEC,00000798DCB47B92,8806910EF0A194A2,A1AEF8A8635E1756,3750ADA6A5BF72CA,2013221FA9834E6C,E1BF6D6E7F1353D4,C78E432336878E0A,2133C16F49091983,E07AA1B35D867DC1,18791DD298A78F39,1DE4941A33FB4D1D,D1731EF90F494F56,00004DFCD3BAFCF1,F16C72E5E63D3F07,0F8A9A41E61C862F,CE851386461DFDCF,AD911F8C82C75083,BD9E4E0FD075F310,A4880EC00BCC1A21,617815FB75EE6C2B,B7B736AD3AE20364,9BC219A81FD031C7,2F3C100B29E23DA8,E9BED0D73B3576A1,000061CC65870C02,3D995AB3C1ECFFC8,123CF590814671AE,023214C965FE29C8,C7F867AF2F019F25,A4DB4C632D7DB749,1ED2D706384DDE21,A0727DF292C0CE1F,C787EE7AD53392A0,A69C0381694E5586,349B0288BF8D6E91,395267B407D56EAA,00003E9D3121C44F,2CDBAEC5250492BF,021E6AC800A4DB28,D80F1EFF97DDDA57,67D623EC8E343641,A909296719940332,769F6AE95029EB47,AC0A31D9B82BCE51,7749E6835E5D384F,70F360D23C05B11F,D221B18E9C3C12F3,73B19C6272FB3F45,000044CD8502DDC3,8C5B93E7FCF75BBB,9F3DAD76EC4EE795,3A61C210CBD1156C,FD8BCE628C025AF2,54263C56D6A5E849,47825B345FBB0EA5,A8E5EDBF875C2455,BE88F4341C7BB448,E83FA9AA340FD32A,BC6E0CD104D58D96,03ECE7026483D2E2,00001230C55E84B6,9229A6C4682E4E40,6F470794BA7DBB44,103B84AB358E7047,ACF1C9BE01916015,D192FE463BB984CC,A139C55CB77A7C68,59BCF21EE52C20FC,A3F6144E232117D2,23E3B638EC423A24,3ABB650B709E69C1,6CBD173D5C55A2C8,000062523C7071E3,DB6F9771099BE09B,2D779448E38DE856,2AA3D34B8D7CA528,0D83A2F316FCC6ED,FDEF90354439670B,0EB3BEC0ADBF45B8,57411B1360D68FCB,6C908BC1B581495A,1499B31E39ADED29,DB6A6323FC16CFCC,E0C7FCB7352377A0,000008BC329033BF,96FAFBE5FEACB5B9,8ED4706293642332,E68A928EF4A51381,AFF7849D6EAF9DD8,FF3E2FDD9BFE5384,66935A59D28F28D1,23E95524C79B443B,09402619CCCC69DE,32E20981CEDA9020,E1083952A4FD604F,A52D96C4C04486F6,00000FD12D8DD918,C0DE6C4FF806BBAE,DE745FEBD489DC86,1F53767D652C9155,66E8951A19A78E16,06CC22A4E60BAF8E,9C1DB3E330608324,9FFBF057353A7D41,CF86C4031A1ED83E,104F976032B4C6A7,1ACD6BDE054195CF,131E9E1D72D1CBB1,000027D71497CDF7,CEBB566A37B60E1C,36A1BE9F5CD46BC9,7DFB845E80F2B300,ECF1F85FE7D937FF,A39788890E0C2161,991192474C8CAEAE,A480840F27065516,04E9A6E91BA4B5B5,0617C567224C17A8,5C5BC36A13E90830,8B94B2F174578E50,0000169B81A0518F,C746141315C7E266,6EB9B6092DC2F093,D391B8B9D3002A31,29D3CFB71A0DCEB7,8AA8C93552517D2A,C1579299A9F62938,EBD4F678B85CC8F2,8CD0D5AE27560F76,A277514515454C67,59CBE9B81113D89F,41BBE3D2E4B9DDA5,00001B85F6EC275D,06CF4FCA7507CEAA,E70DEFEFDBD2D640,D22B03EAEF8DE729,22721260E8046D82,0BFC5C096F141B6E,A7501AE062B57F1C,64D81F43E11C61E3,08D829DDC3AB747F,951C28BC9CFEE07C,070602ACB064C366,19630B43C42F7B54,000006C29FBE9A80,F8977B6D2B265EAB,099ED967ABA292C0,0270E84534979D29,4B48356F1AEFCF47,0D9435E46B570FE8,7B4E87CD4485E2D8,D7ACE4FDE76F5E4F,6C397DDEC540200E,CE728DBE4897D5BE,5C57E906EA0D5928,640C3705A43F3FF0,00002FFD1D58007F,A7C32866A3CA9184,5182E0016B4BD5B0,DAB4C2039EC1C8D0,961F52A85ACE91DC,56EB3ADAD1A29D70,66A79D915229590C,3FA3654C1DCF439A,734BB6297043A009,134EF8C2B0234D50,372A03E5A05B21CC,36DE816541AFB17A,00001D59B6BF184E,6F702DEB922B59F7,712D02EAE09ABE19,FE727ADDF8C6CCEA,43CBC0567AED982A,D5866B3D51A05077,8C6BF3521A4FB267,8C5FC01BB7D4E4B7,DB3E94F942345F0F,392B0607B8B3F98F,80C9FBB7FBC995F4,BE4454CEE62E0A01,00004558B5055828,9C44ABD779E15A56,11EA1087FBEE0EDA,7FCDC28C4FAFC8A3,CB428C68CAFFB9EA,D0D9CC4A0976D530,02610F45ECE96D02,05D881AEF738F051,DF71B282874965CD,3C716E8549ACEF54,5AC39E0D4D5596FB,395D140F80D9A004,00004B708019F2EB,584ABB025A15A0F7,573C74A57DB61A57,E631B8E508DB4E8E,C85C81F6358B72F1,BF513607DD4699F8,B78E048D478D9233,930C3C13DB7E771C,C0EE365CF13982A3,2449965800249324,BE8DA418088932A5,C06599AA246AE995,00004ECDEAF3668E,89EDCB128EDE3086,7F5416C73E01824D,55C74351B503F27F,B1C5C2D1DCAD53B2,923A8BC3EBB58B7B,BC1745E94DAEEA5E,D5840B4C6B350E5A,DAA7D070FA1A646F,A7993714B316590C,5200681210E45DA4,EA8735397A568BDD,000069D5D55218D9,04A720B6FDAB819B,E9B865D5819FF10E,D4A509F0D0A60C55,8D7C62B6E4799F57,C31C3E1F8F47FA36,AE4D6D26C79565DA,18985759E51643ED,DEA418388BCD9D4F,B8F17B1018A34785,5AA7F916E575EFC7,EF127AEA27BA981C,00003D83732DD80D,19C25F97E4207644,21CD07BE1B3A319D,946DEE7468FFCE80,5E0E3D8AB84C8A5A,3F56F4625F16C85D,B237D6B42E7BD864,FAFD9EAC3C644A70,9C327E0CF6603905,FBA918E7A4C5E9BC,7CF2EFBC4F8952A1,36BA22DED30D5E81,000051ECFA5E8949,A77F214D16AC747D,F228F3210B0AE05E,9160C3FFF830CED7,1F1ADAFA98DD5B2C,2A170C0F73C827D8,400CC2A403D57D7C,5A084F3FD6881615,4A43D2C43254B28D,75BC3EFC4AE8CDB9,BF4957ADC6B25CF0,5701890F12063536,0000678AE9CFE233,D163EEEC1BAFCA52,226BDC5A477ECADE,40AC4CA80EC286DA,EB9013919BE65D37,233B5E7D9B2F69FE,341204A3134E7D6F,1363DF8394C6DCCE,0CECDFE19C4E3E67,28E14E96AD97AFE0,18F93ED78262F82C,9304F5E4678E0988,000067C157C7D0EF,CF9E757A6411673A,0A309A107DEE3CA0,BFCACED054770CD2,D1BB52AB92AC7B2D,8CC8103E5ECFB202,50B918523492D4BF,D118A328BC6AD4F8,71AA7B2D04BC030D,9F814749AF62E4C4,41B980832A915F02,1310D1DCD43BF360,000060F779DB48B7,8F754100C9AA8FCC,4C67A044D164B8F8,732D36E6822614D4,1E52E439A6D506CA,CB45E4867086BD5A,8E9FB514D4BE3F22,C8D339925B500209,49D9337CDE84BC08,1F123B39AB9BDCFC,96833DD05E59847E,8100871A04A5AD6B,000028291A674709,4E2E452B5DD412FD,CC47A9A54E8886B0,7774BF0959433F0E,14D1AE13977219B3,0CCFA7C6B78A528E,307EF05D2EE0EB2F,E9C66C54F33B5FF2,D62D5B1640B152C9,105ECC0C6CE60AE5,3C8CDB957A871D2B,1A73DD5C8E7F7B5A,000059C7AE15D0C8,5DAC5935217C07D7,E34ADB689B475E50,2664492C1FDA19E4,84116D74BC16D84F,30823848EB838B18,C804DAADDF198D24,FCD58C1D8D723606,49E18524A1385F34,217F0E5047391D57,6F5212C444BF759E,04D0ED5F9ECE91A0,000007822BBC1293,1EE4D5778DCFBAC7,949040AE1BC79306,DAF5D935DDABC083,A508AB0C4CD700DF,B0C50D5E081CEDDE,2ADF9976177BF5A6,DC78551CEF0A9DC5,09740311A0B0ECF2,1DB9F90B32B6FEFC,0E403E3F388EAE50,B154827713825AB0,00003BFA7C32CD9A,83B45F42161447F2,8E86D3E13F8D7486,05315ADFAC5F1A58,E8433130583ADF1E,2EB3D7833B8C33C5,CF69635ECB730722,969571A3B0448BC9,7FC7645C733797B4,ADC4574B4C7D431B,FE63DDEBFC7288C1,3E936ED8B74FB1AD,00003225192E816D,BBDF3227A669AEF9,A0AEB402C419A332,D75D650C510E8E56,E64C082DB9BE4185,DAAB0593FD234E50,ADF39FF3546F453F,F864475A1E777F06,63FD975550A9CC51,24DC84985B91DB31,76C92ABC13A889C2,FFE28558351BB676,00001CDA742A0302,5BC6F10DD89EA645,2C046CACBF32AD92,AA4D2CE5966E52CD,632F857CE3DC8D68,72D33C846517BFDF,FD4FC5B00D630F56,37D89CCC722A5180,7E137F918B0C16E5,EC32930721D7C98A,2B48AFF525527B91,2454B7B9382EA06F,00004760C15846B9,C3934D2019F6A22C,42E0C711B579740D,469AE8495FE7FBCB,C1D3D43BD2F9DBBB,975513B34873173C,DFB52046F1715AEB,DDF94F7E126A9431,AE96487F763A869C,666FE9C2DF6525EB,B40D6CF282568365,853D5912FBFB6B91,0000688C081910E5,C5195BDADA845207,F50D17F7923F93C9,831D120DB9A7283E,3679BA2BAB105006,260E6B21FB65346D,E15CD65BAEB7DD31,9270A172CEF2FA1B,8D6955EAF624F7BB,F7B0EB1A24C038B5,0A8C1A7F918FE6E3,56EFA0083976E393,0000182552A310A9,21FBACCC7B2D175F,B2A949E459BBDCA9,0A3F78055086C9A0,C3EE3C6035BE1EDF,4DF82E1A55D9EFE2,85D4F4F0C8E52EAA,15DBB59CD3BD04F2,7C810A16B96DC400,2CDD6AD605A6770E,58151586F4C1E54B,B35D5D7E044A22AB,00005139BEB07EC6,E6E2E3C66F547832,3B416603AF3CDDF1,4D7CA5F302D93581,E63F53B65C4470BB,B2820F2EA7F2F54D,C3ACDE63EC7A09A4,8BDE9BC796584F35,C7698B881AF26D15,7559B0C65FA1ED69,BFECCEB092D34B47,F205684166E54969,000019386445A1E6,3464F28E033EB388,C35E7B8217F029A4,FBEB6285AA9E3FF5,C68558C100A2D4BA,3F0D53D883B08C66,E09A7A6550D11C31,7EFCC7A80AE6284A,C67183BDE9E90BEC,ACF765825F108CE9,6C6D903852E1D1C1,B31D21737C1C0897,00004D28C2633021,FFFFFFFFFFFEDB29,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,35CFFFFFFFFFFFFF,47627250894E0621,388F01AD6A5453D3,9FD8705A9547CD24,9C5F0065455576F8,FE8D7F1991540A3E,000021455842889C,3491A5216328750E,BF0C22B2AF31F1D6,C7EF63DFC40D80A4,AF5B79C2C560B8C5,AE73C70F613FBE71,2C6D629536721BE8,C9BED31D01E0D4DD,E2AD5C56DF13CC71,42EDE69D8A687750,B698857D9E00B623,B7D4B27BAE733547,00003B27DB42AF71,5403C05EB62735C6,CFB18204BE838E44,2F6647FF437FA23F,E346F21DF8AB3F3E,276F85AF5CA7D644,49A64B4064CE192A,C59D594AE4AD2F57,85C2B9A702E067A5,9B43FC875289C257,BAE9CBD4384F251C,C51D8855F75EAF69,00003E881E59448B,126945C188119C28,10B5319DBE344CFB,F1ABEA805A177655,02971C60CAE4B5DB,F11525BE2DD69C84,4975857487EBED86,4D0DA89081219C01,248614C144731463,886893143055FE52,99BB2FB5BAD243BE,0DD254950F8CC252,00006BD4D8F4A877,5403C05EB62735C6,CFB18204BE838E44,2F6647FF437FA23F,E346F21DF8AB3F3E,276F85AF5CA7D644,49A64B4064CE192A,C59D594AE4AD2F57,85C2B9A702E067A5,9B43FC875289C257,BAE9CBD4384F251C,C51D8855F75EAF69,00003E881E59448B,ED96BA3E77EE63D7,EF4ACE6241CBB304,0E54157FA5E889AA,FD68E39F351B4A24,0EEADA41D229637B,A53A7A8B78141279,96DEEDF4C8D6DCA7,B60F8658CF84B813,7FE60553A695EA24,EBA7854EA1E01389,00403C0A882E1A13,00000410FC4D4EA5,FFFFFFFFFFFEDB29,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,35CFFFFFFFFFFFFF,47627250894E0621,388F01AD6A5453D3,9FD8705A9547CD24,9C5F0065455576F8,FE8D7F1991540A3E,000021455842889C,CB6E5ADE9CD78AF1,40F3DD4D50CE0E29,38109C203BF27F5B,50A4863D3A9F473A,518C38F09EC0418E,C2429D6AC98DE417,1A2DC3684817A3CB,F7E83EC334E40005,C560B1CA4C837125,CECA2F86BEB1A124,563DDE23E947A71E,000034BDF9FF47AA,E6E2E3C66F547832,3B416603AF3CDDF1,4D7CA5F302D93581,E63F53B65C4470BB,B2820F2EA7F2F54D,C3ACDE63EC7A09A4,8BDE9BC796584F35,C7698B881AF26D15,7559B0C65FA1ED69,BFECCEB092D34B47,F205684166E54969,000019386445A1E6,CB9B0D71FCC14C77,3CA1847DE80FD65B,04149D7A5561C00A,397AA73EFF5D2B45,C0F2AC277C4F7399,0E15859AAF2EE3CE,64EFCEDD3F12505E,1424175C2A0EC08A,5B5732E577DB5B8D,18F524CC09D08586,5AF56F2C1B9ED3CF,000022BD12DEC6FA,C5195BDADA845207,F50D17F7923F93C9,831D120DB9A7283E,3679BA2BAB105006,260E6B21FB65346D,E15CD65BAEB7DD31,9270A172CEF2FA1B,8D6955EAF624F7BB,F7B0EB1A24C038B5,0A8C1A7F918FE6E3,56EFA0083976E393,0000182552A310A9,DE04533384D2E8A0,4D56B61BA6442356,F5C087FAAF79365F,3C11C39FCA41E120,B207D1E5AA26101D,68DB0B0F371AD155,CE10E0E8763B73B6,5E1491035A8A0876,DB712D91D1457168,2D4D9F7D67F071FC,5AB533219370B9BB,00001EAC16917855,00000000000249AD,0000000000000000,0000000000000000,0000000000000000,0000000000000000,8310000000000000,5527B1E4375C6C66,697797BF3F4F24D0,C89DB7B2AC5C4E2E,4CA4B439D2076956,10F7926C7512C7E9,00002D5B24BCE5E2,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,0000000000000000,C5195BDADA845207,F50D17F7923F93C9,831D120DB9A7283E,3679BA2BAB105006,260E6B21FB65346D,E15CD65BAEB7DD31,9270A172CEF2FA1B,8D6955EAF624F7BB,F7B0EB1A24C038B5,0A8C1A7F918FE6E3,56EFA0083976E393,0000182552A310A9,21FBACCC7B2D175F,B2A949E459BBDCA9,0A3F78055086C9A0,C3EE3C6035BE1EDF,4DF82E1A55D9EFE2,85D4F4F0C8E52EAA,15DBB59CD3BD04F2,7C810A16B96DC400,2CDD6AD605A6770E,58151586F4C1E54B,B35D5D7E044A22AB,00005139BEB07EC6,E6E2E3C66F547832,3B416603AF3CDDF1,4D7CA5F302D93581,E63F53B65C4470BB,B2820F2EA7F2F54D,C3ACDE63EC7A09A4,8BDE9BC796584F35,C7698B881AF26D15,7559B0C65FA1ED69,BFECCEB092D34B47,F205684166E54969,000019386445A1E6,3464F28E033EB388,C35E7B8217F029A4,FBEB6285AA9E3FF5,C68558C100A2D4BA,3F0D53D883B08C66,E09A7A6550D11C31,7EFCC7A80AE6284A,C67183BDE9E90BEC,ACF765825F108CE9,6C6D903852E1D1C1,B31D21737C1C0897,00004D28C2633021,FFFFFFFFFFFEDB29,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,35CFFFFFFFFFFFFF,47627250894E0621,388F01AD6A5453D3,9FD8705A9547CD24,9C5F0065455576F8,FE8D7F1991540A3E,000021455842889C,3491A5216328750E,BF0C22B2AF31F1D6,C7EF63DFC40D80A4,AF5B79C2C560B8C5,AE73C70F613FBE71,2C6D629536721BE8,C9BED31D01E0D4DD,E2AD5C56DF13CC71,42EDE69D8A687750,B698857D9E00B623,B7D4B27BAE733547,00003B27DB42AF71,5403C05EB62735C6,CFB18204BE838E44,2F6647FF437FA23F,E346F21DF8AB3F3E,276F85AF5CA7D644,49A64B4064CE192A,C59D594AE4AD2F57,85C2B9A702E067A5,9B43FC875289C257,BAE9CBD4384F251C,C51D8855F75EAF69,00003E881E59448B,126945C188119C28,10B5319DBE344CFB,F1ABEA805A177655,02971C60CAE4B5DB,F11525BE2DD69C84,4975857487EBED86,4D0DA89081219C01,248614C144731463,886893143055FE52,99BB2FB5BAD243BE,0DD254950F8CC252,00006BD4D8F4A877 - -ph3_T2 = 61F2C46235355981,B14A772CB29B82A6,D42C0B8FC04184DF,FCA910510D39E137,7C362C336F08DC04,5AD83F13B81712F6,4F3DBBC2A96F63FA,0A57610E390A5607,14C5DAF1A1626E5C,9E44E107664A2F4E,8DAAED26BBFDB0E3,00002D6B4A339DF9,3E26404B0AF5D1CC,500F8B5016019FE4,783C57F59330D4AE,9A63B0E9FEC0B16A,60C2C9156C323CB1,7FDE85AB8348E8BE,0D948E42F685D4A6,0D2620E19066F726,E0F7B959E1E34CC4,DA22A41492CA4FB4,45FC1205CD9A9FF3,0000647A168C97DD,A3E1E0F284119083,54A1675AD5FCE7F0,0367178870AE5931,1DDF75E74BF11C01,D575FEF284B33B38,CE98D0BD1FFEC121,38F63CFB654FABE3,E6787C23FEE5167E,673649AFC7CD4016,E94DB8301F0C3EE7,673E019BECC49377,00000D2F6E941025,380DD270B4E38753,3887493104C70199,ACB249A68C2C8A2C,2AF58A3740A4DC72,EB9FDADA18EA7B81,DF2B51EB589F2BBB,2B5D7B01DA7B98F4,D29718C86EF95744,45BE21485F9B5841,359BA73A6AF7D10B,E9A780CED50BB85B,00005962C56E14AE,6D528C376AE2568A,F5E98924F27E28F2,83BBFCC7C51C11ED,0DF8E1157C0B2104,09EAC3B579A1FB0F,1D8A1308F31C3293,04F39128DBCCCF72,84757DC1D6865E0D,9077B3C839D63CAA,9885B3F80F35DEF5,5D2A7A7F119311D8,000005E9573EBA6E,EEB80519CE828003,5FAA4F091FFA4B3C,180F1C0D7A185086,4E39DB5A8788A014,92ECBDA3B525C47B,0ACBCA986C588FBA,B79A38862540BF6A,475048369F46FBCB,3DEA309CD1624773,F1C9CFC0B8AF783C,C976322CE2C8C02B,0000239CFFAD4B79,A433E0DD4C33DD9D,1DB3C40D971FBC98,7148DFCB642ADD87,A90DF39D90FEB5B1,C30D9D6BD4D03BDB,FC9B4AC25D560D3E,655F6EB70FE2464B,DFB7E778CC4C60E3,E19C560DC64269C9,C31206407A0FEBFE,080218BA788FB306,00001B23221F863B,8C3EEBB6C18E2751,6D8DA6F801331A10,203945342960FC09,C21DD47346BA5B4B,801E1D5637E8BFB3,30D207D58C2883C1,3F0FF731C15A5372,A8948F3D9D05CA82,5699F3E728A4995A,0978DCFFC7D1FCBE,B18D4EE97DB42F2F,000050F2EC7B0BAF,A78927CF314B8C94,CD8550A2160099E2,43A5069BD3B2FE47,61CF5B9C1CFFE0BD,F9075CB076B7BCFE,7E26934BE2ACD14A,8FD4EBC9B50A43FD,F9C0B9D603608F11,B8BAD7BAB7E7B8B4,C99B88E620745263,7AA683F3112BD1D6,00000007726CA73D,8027986681D32884,DC639598DE6C7D0B,1331F490E5D4111C,96DE70470A45E502,4FC409BF13B910ED,78BA2F3829ACD860,E8653E219B87EA16,8E98824746BD30D8,E04A044C5AC1E23E,894A19390A89078A,4C2E506BB1950536,00004B2B337B7465,6B2E15CA156FC79C,77188A6E2E7D8B91,6CD043B43052F252,E1BEC7AE9D6EDDB8,DDA346E92E996B4A,2295EA20B1340163,1B7E59C08B6A510B,0154984C4076E74C,4A41430F237B4005,A7AFA207DB760555,E1CA6D12AE3A29E7,00005DCDDFAC4320,07AED6895B0CE7BD,0E2592AE7447D965,492AEEC10F601D46,E59AEEE4A025E80C,B61660758F5660A3,E97E78C2288FADA3,09CB16533AF75E84,5A41C21412E81810,20C679A70AB34175,ED569B6A5612B192,56532D50825658C3,00002623A5E90691,30FD5A3045EACC1D,1FBDBC13BDA82DE5,3A3EC2934A322064,DBA996F38E453D23,A11BE6A70BEDD90E,45C19065005CB33A,4426AEED0619061E,76FA12F869ECC7CC,DA55C31FF849950A,1E0029A16B1228C4,CD59A6AD63FD8447,00005A55677BB501,FCF27604F4B08E92,62769B284268C25C,BA0CD67CD35E982A,B2194B734F471A50,9B500EBEDE8AF10A,863BE756685D164B,0877A32C1F62857F,40FB1CE4819CCEAB,D5EC1C7578B6541F,8D692C11E1253C2B,C5091ED42C8BF666,000007C6532A5A14,F42F6A14628B8F21,8EA82569519644B8,4F80AE531AE0EFD6,3FFC70361727D330,734D3549A86D3032,5EED94A9536AEDBD,5D2CA5FCCB6A5C99,2A70FFD43D8E2A2A,B6D672F5F67B5750,3422F460E4781E65,E3A8FB856ECAC907,00005CA66BCE5A32,150AC998C143A5F6,46102EB917878DD8,D2C9150AEFFE6D74,694DE55C6265A7AC,CE58ABD3FA7799F7,1A829B6BFC595EEC,F45A23838B981AF5,6D3017F6D0E11F2D,FB554B978A50ECF3,039348E2DAFA0776,303B29BCD086DF41,000043931162ACCD,B43A5B7EC264A484,CC91FD3A4AF8C866,A09A12C3A46CA8F6,886A77C6ABEA7A11,9A953AA6BD9A1871,CA47A5D6533BE74A,7FBE28A88A394C8F,DEBFDC4033F480A0,96826AFAB216C488,2F6CBF18A8723C12,3F637ABBBD64520D,0000202B45A4CBE0,BC28A0F4EFEF59BA,C5FCDD4CB236024D,A7F8FA7F004B2462,E45DF3A3A2317475,403B8B831862F2C7,B387AD1E0D9C4361,F88E048E2A030F39,6DD9A98FF681C183,A9A5644A4B061A4D,88A9191C14DCC723,0B441BD1A86F5191,00006D19455EDAF3,0D2C974E28703A95,175559ECB942C34C,7CD732A9A37F2676,F2FA7524199AE520,D16E612286D2EE3C,B755DB85BF9CF7D1,32AB8DE6D35C9B0C,9BC090F62B4CD17F,BA40606F3E7AA0D1,E203E9B3174F5F66,2F13B46444F735CD,0000653531FB68C9,DA48FD257901590C,534CFEF849AC6CD2,81635EECE6895A6B,7A5EEEA3B37CE63B,A3382AE6B52A52DD,7CA88A5FA81D0C99,0BFCA0451505AA86,BB38A5EB1964C3FE,698C82FD96357312,077F5C131F6E5F82,098ED1D2461C693E,00001DB8AC87CF5F,E6570173DDCBDDFD,4F5401BF473E8433,F95D519665F12BC0,9EE519F3F4E39C8D,BA1C60BBB24FADE0,F8C6F9E575CB937C,5840112F5A529F33,D4118A42AEA1B0ED,B67D3908E1419945,8CBB35343C590AF7,2CB9B99D9FC6950B,0000212A4B33D257,24011EE9F6E74861,37DB9AD9F53BFC99,4E1A0877A39771DF,5B89DA750C844A12,99674C0EB0BE3A85,D8E85B87645E10A6,2D4B4BF6CC5BB090,DF40EF7E5D94937B,F8108D6EDA17256B,7339FCFCF73F5495,74FD2B4410839642,000034E57C46D50B,BCEB409B401223CB,97803C03A2190A51,3BE6A9D77A4B823E,B7686663E7CA86C9,4C2E034714E5F721,64428B94E70B0D4B,C562BECF74BFFFCB,7B89522C69D71ADE,DD68D30FF08EE555,820F9F35E2B8FF3F,4FF92D89D2BD54B5,000068BE2983BA5F,722A6DEF84D2A077,3226ECD43774B9DF,905FD3C9B1D5D888,6AD3CE3D7053313C,4004EF0D83712C08,0601DCD6E2BBB8C7,782C7E9184C522AC,E9FEA5363B4720A8,EBB8649C8FF39264,1CFCFB9370084C1F,EB847AF675C0AF4A,000006EBB36983E1,81CF5DC5BE123C64,F75EFF5DC1850BDA,286AB6E7CD68399F,DAF45719B6E3CA5D,86F92B4297721168,3A5690E6F3BE9794,4A80C1CFBE34E306,CAD698244676F53D,367B4D2056B09EEA,A5CDDEF2EF51838E,FED1FFF910F75272,00000E0C28703833,7D9E374864DC1729,B76D13AD977F4351,F57C91CB9BF62AA1,02DD6FF89B9E016E,B38148BFBA93F989,B9CB8D05032D2BE1,9869628E1DD4C118,C41FD6606CF8E64E,B79ADF470C090C66,54B7D64AD46D23F2,6FE6671ABCDD4A43,000002A4C465FEA5,B43A5B7EC264A484,CC91FD3A4AF8C866,A09A12C3A46CA8F6,886A77C6ABEA7A11,9A953AA6BD9A1871,CA47A5D6533BE74A,7FBE28A88A394C8F,DEBFDC4033F480A0,96826AFAB216C488,2F6CBF18A8723C12,3F637ABBBD64520D,0000202B45A4CBE0,BC28A0F4EFEF59BA,C5FCDD4CB236024D,A7F8FA7F004B2462,E45DF3A3A2317475,403B8B831862F2C7,B387AD1E0D9C4361,F88E048E2A030F39,6DD9A98FF681C183,A9A5644A4B061A4D,88A9191C14DCC723,0B441BD1A86F5191,00006D19455EDAF3,E9097A7F80B4B241,CB1BDBCFEDBBC653,73E5B366E64411EF,FD2FB77333F05CF1,974317F24756890E,92B81FEE0247C1A6,7036B2BD859C86C1,2D83AA1E11E00904,E3E20E34DBB5D8FC,8136F009DD350A2A,EEE6EADACE98D719,000031B97491D0C2,139FE4278D7746A3,6D8C4430D4885FCF,12E3F601E2BD82FE,4E90C4820B8D212B,0843F7AD334EA1E1,95AA2B2854C2A60D,40ECD8C7B0D54C2F,AA2602AF9A66AFA5,42117BE5DA4726E1,4DC2EB0A9BA37157,8043773760C80262,0000252DC1457B78,E1BFB4BA164A6C2E,1B4F30C541003DB5,D3D06ACBCDBB4F0D,8B52A39DEB38CDDB,76529B49EC389C49,F4F02339DE646D57,AFACC7600E29AF52,598D8F128E19C279,836FC4FF2D342237,ED001A2E81B54CB9,C0137AA63D9F3115,000055820DEF4910,7C861620B1B65A38,10F54A6CA7068BEC,CC93985E64587FB6,A521A9A4E36F5F29,B00780DFD671222E,060EA946E8115E62,9BF04AA54AB167BA,96D06D6CED86FBC5,EDF737BBC49F05FE,79151A1CF64F4F1F,B6FA508C99A7F949,000041AB9236E456,73231208296F63D7,4202AA7149FCAA1E,EB6DFB7C4307DFBA,439E1B971BCDBCA8,9F638C6B2E942C88,36310C3674614D44,964290CFCEAC2DC3,FF964C28EA7DA7DD,6F91373230072B26,4BC8703E079ECE99,B82FC3D7D623200B,00005AC6CA5045F2,53C05E65165701E0,C737E5CD72F340B0,04C1C0B297E1FCCD,4637A9144D685AD6,5D296D3313A83199,5907EFD0778BA293,975D79C2114ECCFF,2C8EF7134097AB88,8309F5DEE8F7AE8B,3CA9B5EDB6EEC75D,88CD7D81297DD287,00000CB866AE3567,6792E5D6901A3BE2,BCA6EA804EF4888E,E9220225647C77A4,65FF6D06C4D952C9,02BE89C8419C0669,A2B56DC7F4AF86E9,97EAC51F100C2EE2,B180D5E73E3669DF,9E5BE2B126F5894A,0448472A296DEDEE,3854AF52598EF00F,000030E91A57C08F,28120FCB3A49F4D4,E3BD186B616EFF08,9F22B57B6C7F0103,E9A1D66F2C8A1DAF,0094082381032691,B6722FFF46C52B47,82AE14FA59CB24F7,471D668D0E165525,2B1D3014E1FF9277,CC6E872DB08195F1,B0667FFE9AC1D9A1,00002C0B826A9B8B,60AE886F08F4FF07,CBDF7E92141D8C2B,7AC749EF515D4998,CC60577E5BDC0062,784B8A2887A6BDA4,1E945061B1F3B7DE,D43EAB76E326A336,C9ED39FFB18ED8FE,DA2F47CBAFEBCE04,0813C95D376B4924,5FA89146E0E4381D,00002B61A1FA30FD,5A533EE1C61AD161,6E1310CD5678C227,C14DF41B1E77E5FA,457DE2A8AD0F6790,0642A4461C2563AD,43F1BA8364E54BFE,374FDD91091DAB70,32526EDF54DE1FC6,8461759438494423,7C441E3BD742BE03,F21DF043D0BB1980,0000102C9176C000,2A6EF8B8529DF8E6,1C2F2068FE8A66BA,49FFB66DDC0A6628,8542DC354B9D477A,DBA794917605D810,02A9613BC9B935A2,37CCF7AA3449050D,FBDB217F232629BD,146A0D67A72BF073,A174BC6DE598BE01,8833D272FBF69E91,00003F183A9E1155,1C7084FB279375DA,C84747D9517E2ADD,AD11724F944BD985,3FCC48CC10028C76,DDD31938048D04CC,62D7E39DCD76BC51,BB4803AE3AEAE8F6,BED36695E740FA58,332136FD02FEAC85,0D74D3E56F7302EA,05A82DB79793E3B1,000065CCAB2ECF68,109BD8F17A7872CD,E93012465F4284E8,7D9CF0A6534390CC,7527BEDABA14DCE1,1EC2A9320A672BA2,9454B62EB5AB4077,31009B017DE5A264,D1FA0239028A7D11,C65CC89DCF1281D7,A9410009559BBF7B,C8E180919D8D6C28,00004B6774439AB6,828A7CF6DCB4BEE5,E79AC630CBA04A9F,E9B8E99D82C599F4,4D141AB44F0071B2,89F4A14C10DF7857,E25F58347FF69DD7,0E7F91FEA969D463,9EEF7FD2252F2693,5FD503DCD28823C2,5CD0EF42DC1969B1,6CF338B33295B00B,0000424745244CD0,5364126AED2FFC77,4971C5995D1D0E29,76A0ACCDB0807E04,9F9F89C47C48CDFC,C105EA35891B69FC,1B2781DC3B5BC5F0,40360ADC5C1882E0,B646BA77530106EE,585057B3AF56CDA3,9ACDFC9DFC5B88EB,0560C67287C906D4,00002B86C538CD53,0422AF0AB0AD57D2,3B4616D0F09A2990,F38E2C087CCAE69E,7805607431DB5F7B,81225BA4752B2CB2,0A7822646E2CEDA7,CC44C80DE1C474A0,2AAF08907B8C8957,2B26729F721CFD39,2FBD094477E70928,5FA5035016F7BFA7,00006CA651AA3822,773B698AFEA24607,7AD617D0E9934726,C3C01985DEA883EC,B26021757C9326D9,C2B2856104B7BAEB,367E158A763710D3,C872AFBC1305EF14,049A809E0DB12034,9498905131D5B7DC,0E0338D2E1C1B3AD,C17E09A9C1945F41,00003E561A290DAD,4369FF1CCD85AAB0,D66B93B760D04A4F,0764A8931CC68CA2,FD563EFF9906DDC0,A41FBE4A1587D251,39A5327503CBB5A0,90BAF092A1384A39,A7FAD46C63CBAF2C,D60B4B35036D39DA,6DC19A53EF7E7673,263C89FDA85264F5,00006169CBC55EDC,980628B78BF4A264,2CB6CE7A0E89A8EE,E3D27529528E3420,36D9D5E70EDDB735,24CCA8CAFEA20C02,468CE2AF63161252,8F339FB05141076F,4D0FDF690D1326F1,90E481F5AF7CBE41,A53D954D57B5B9E9,E10957CB638B7C27,00004B8A3C418D08,75D79E2E3449AC44,050744808CB94DA4,103DC02D38E0B693,96D4AD7C4F8CC225,FCCDFCFB5C1760E2,BBEE94682FAEF9C1,36479245BFD10E8E,7E5278A9795185F8,7231B7E8C65ED355,80FFBB0ECD57C3BB,F02EC45472635ABE,000055970D2C3297,7C4B2B60EC103CE6,AA902DBAA18F7332,D260697CB15E37E7,6CF6D812C67A050D,7012D1A0755C1649,1A969CA0D56EBE16,0D53A83718B8C147,DB2FC2B3592F1AC6,837402EBD91302CF,8D5BB4A3FF69C499,A11D55491411B555,0000162AC625C40E,5F75A23A7B0AD0A8,49376ECA6A75F4F8,FC1D6DAB1588D196,9D15DEEF58D02717,7B095556F06A5638,E044086B041723EF,7962A6E38B068DCE,66E5989538D02570,2BC69D570684D629,C2F6448E43ACE035,2E98F2FFB6B175F5,000016C124A1F6AF,DD73BA5F627182F7,A4F300EA17886CE7,8BC5868888175A0C,33EB2C9AC9BCFA6A,F818D4B82C4A6B2B,54AEEBFF5B162FCB,14D342F01FCEB8C0,685B9517BA2F7AF4,43D6D3F33FF44993,A1B1EC066F023188,E9755F77ECAB40CB,00002C69FA17A954,0F67C097BADA8B17,6EE29198BC8711D4,FC13D559A05FC1FD,E665DF03DF89889C,39AC39AB0F639F85,891BEA74FB7DBCBE,955E9A7D27C7044E,10604198EC067F8C,6F299C603CE80285,98A1BCAE04FAFC2F,5C8CC140E15C0F55,00004E0B7C3CBD97,A4A9912AAAC5A394,7D2FB8574D3E9F9F,D06B7FD2914C9469,C1410D6CA79B8C38,8518617AF34EB8B4,7A04FD979FCF207C,D090B56E437F93E3,FCD3B44D9C54D4A6,62E2E27F565C65FD,2FB42B46ED021294,1ED737E75604E4A2,0000614805BF0AE7,A0BC33559E6DCDEC,0B1155001569C215,8BF0553D9A78B15F,39116AB0B1C6C089,5C9E1956745B0729,8FF5DE369FBBDFE6,8977F3A6BF168888,A470DC48A46F8517,586C44714D74A519,DCEEA8F31104F5BA,C983C30052A82ADA,00004D4DDFF6C810,FBEDB09806CCDAE6,A1F870F8AA3E116A,3C199B5426FEBE8A,B61FB4B66BC3F60E,3D557622828B9C18,84ADB1E5AE56DF09,369F50E163226596,899ECBF04148942A,6C32A1615F99FA8B,3E054465757F8984,2FB02885ED0B713C,00006DAC6BC2852C,3A0151DC7FD03B26,84C10CCA5741DAEC,D0E54CAF9EAE9685,A0748FEB30C0193A,F04D78B46FC775A1,7F32F3FF9E811564,295911996561A30D,AF5C40F781DDA447,45A2AB128A0A9C20,08BBA16CE4166AA3,A0AE5C1084A35710,000052E48FF40862,7598E6AB9575E3EA,16583AA13BE3AC77,3F291FEBE72E30FB,CB62F630287E1136,72B0E6C9C62471EE,7A032F8E8A65F03C,9798F0C8C008B737,984FA33CFBF5B256,B50D5C9B7CFD6838,D9F9CC0AB1A1626B,FB97C09A556E231B,00005C63072A4D9F,FE0EAF1FC65CD316,7DF8BC1B4DC1AE4E,046F66CE33C31762,5E546C4180DEE836,4CA336E976936830,AF9B7D6C30E83568,5EA5286E734771EB,85F96F6D896F11F2,73A5AA4834A20E67,F32417FC4244EB17,25BD70AC8CE3D640,000047736C8ED2BF,1EFB33681F4B2572,0850188812B3703A,EF2A0179055B2990,F1F81A263E25191D,DFE2A08A71765B98,55517DF9A3006040,908250FAAC3989E9,21AF04FDC837F251,44771B8F54FE70D3,7B7DFA98E02350B3,DA850837187D894A,000060F018DA217C,D8F966965AE7743B,6C3E0C8921329792,0749015C6DBB05D3,EF321B15D7DB1CA4,FD605A6A704AE8F2,E70DCD818B7030E7,FB95BF41EE2B3D9B,E8A501E2004E01A9,056744CAE84C8A9A,6AC67427ECF73160,E280A3BFD4094665,000048BF7D4AB109,5AFAE485FEC4062B,25A73B47C7C271A4,CC62B858E487B9D0,863D7A2400934426,353FACF62FCB2BCB,24C562717C74FBA1,5F96D99FC2E7281A,C05AC5F192DCC8C2,13AB63DE169FE213,F64459B10EB35A54,48137378E3FDF1AF,00005612CF97F05A,D7569753C12FA8E6,982CCA8D3F27A17C,C3C1F36EFB9927BC,2757040DA6C108B4,BF82A25813AAB0B7,081E26305B9B0FBF,1BC755BF24175935,AD94986F709AFB3C,73487A082370D566,C32E78FF005385DB,2E7CCEF808566542,000033E5504D43E9,D3B6CF8B6F085CA3,528D43C71F98B35E,C834B9AB9F8BC84D,A660F4B563B15433,F4BA0AFC05846408,CE1505D862BFCC26,D63826F7B50F8CD9,6D8A9C59893A234A,77455D091005BE5D,9BA67F5D5DA622FE,BB81A7940CAEFFC2,00005AE43A09CAB1,3C5EDA99EDD01413,473FC7577EADB7D9,9E6F1E2F67B0B230,D57AD72158039B6C,449937EDE066ABA8,666356B80138B78F,63B2399B5C1256FD,B6C54E38289BCE53,94A8D85C73943D06,9CA0A326FAE02D8C,ECF35D17214E1F53,0000196307612488,4896657737679B88,0463D33B84F9A4AB,C1DE8E142EC345D3,6F6F4F81B7419F74,9F30E6486A72FFD2,3BED05C83C4A4B7F,DBF2CA47A20ACE2F,DB3E6BD787ADE40D,2E49ECC143A4D0F4,271D694F46F5C624,1BA611B648148380,00005F962FE15E39,4F782C02D928D597,8CB3193171310E82,488661088421815A,AF7C57E22D174333,E469A81D43BE1E23,022C9F31FDF9EDCE,26DF7D8C4E8E013C,D93947C7336DC1EC,5454B15844C718D5,81CF3CCF90C214ED,27240A20CFCABA5A,00000BA953BA41B2,B50F2B3C4B90CC29,C2C51A853FA8D60A,484677ACB00D30D7,9427BE8FA8964949,BC9D91D82D3FC627,0A0D0B998CC5AA65,3BD3EEA4E9B9EFD5,4FFFB3857C7280A8,60A1827002F9B121,5474747A2E186578,B4D401437255D802,00004F95E61FDE54,2D66D5BEEFDC10D7,BCDA7D94AB7189E6,FBA535E7477EB56B,0A5D261D7DCC9B13,E432008D8CEFF4FD,3150695A912EA8F3,243D393198C6D407,DAE0A2A9AD5F7D84,7FDE04B97BCB27F8,D733287B32242C68,FFF1F008839CE79D,00003C63AA9C96C9,6B603DC0A319B18C,A8F5E24F6D030877,5E3F98D8874DFDF7,C925E5BAA414B9ED,9A49C0D616B5D968,5B68396FC4C03CD2,71AE9F37A39FB40F,36F3E296C976A9D8,D2502F03C9143F9B,5BD349F0C74B0F96,84B0C631B0EBD4E6,0000368D422DA9A4,FD7DEBD7E7C46B7A,A2F5853DB0A57102,71E10940E4E3287F,EE7BBA7DB5E5E278,5EBB31B109E7B425,ED2E405A63FF6EE8,E4B04D5F002A7F98,31FD61AE5E1B4F39,3EF4E116E2168A2B,35D952C3CECFCE5A,9A08A78F29CBB14B,00006F18F073885D,FF8B435BAF92450B,24E2069E1556EE2B,67790A6C5E836623,BBAF6A1E1133A877,BD5C7B5F8ECD2334,3B30FC03C87BAC4A,D8601A328984073E,7D7545E876827385,646EAFF3F49AB48A,2AD449682E711FFC,31D47C17E9D61E9B,000036893C09A4B6,86F822B0461188F4,F4FACF740AE0E155,56D76BAF89EA68A7,2F7A1AEC7E3A4A47,55239317B6DE578D,6A5726213C2E5525,A063F3D31B664D66,3C816ED211EDD500,C55E43CF077A66D0,02888C66F7DF4E4E,BEDE01ADB6B0C2A5,000027CA5D9B24C4,774FE39CE2D77093,F6EBB649EFE12A0D,17379D060D3B9308,B21C85A2689B4C65,DCE339820226BF55,031FFA7CFF278137,B0AFEAEE426D41A1,CA75F673C6FE31F0,4DD9BCE971EBAD8C,9FBE4E912E479B16,14D9713805618237,00006902B766F387,28943D21A091C50D,EF1813E626F0A0EC,185BA6FA65CAD334,BFB79835F07B5A84,45FA0E83344C2AE5,E127647CFB8601BA,5D22DB1301EBAE77,22D9E62F56C14E6F,99BBC7A1E22421D9,0DCE5D1449453464,9980C95503568621,0000006D1B1829E7,6A3974F5423E5E43,7483BCB551F92553,C2E4C277166AD21D,A7E435330784B22D,FD042D4935C2AE1C,43464C72E785410A,86D459E281355769,F1E8A6AA85785387,8145FFD13C9F189D,5118BD9BF1D3F5D8,C9A03581BBAEA8FD,000031E8586A2B49,0C69DCC1C79B88FA,ED2F6C54D45D47EE,9094016C79527B33,2B25B51EE3F4CC10,093C49EDBE2F54D8,F3301673E9D34BE6,CE77057FFDF1E224,09119979F9687F21,BC9744F95A3B084A,50B8F48954ED5DFC,D67FC1B7080E23E5,00005B7B06758CF4,040756595C4F82A6,8056D0044FA25D57,D38BBDE5B4FA3165,D0594AADFE484215,0B28FF65B7702209,EA0B81E590672907,58E0910FED0F5211,82E3CDC897AA2E2D,A20B6D1BC27537DF,23FFF93F0EBEEEEA,3A1E8BA12C697B77,000020C8CC428632,8653024D8A951344,D120E594A3F18909,300B45619E0F93A2,7C71E5FD35FC9AA5,50038248CFBB9E83,32DDC5A1807079AF,7F5011DEA8CCD3F3,7CEB548361B3BF77,048F388AA5688B84,5BC5EF9234298D44,E2E333CAF79507AD,000015AEEE328B74,8BD11A24BE729E7E,E7060BC98E3754C3,25137F8F5F4FAA9C,D876BA798554BBE6,E1B1F79B9C7BB98F,6AF9D18C2C40845E,7319530CDE4DD361,60CEDC0720F997F5,3E05FAD979FA6F71,66DE5D94C179F723,22BA03FB3F80E866,00005E4BF388EC14,2D23BADE15022408,739BC18B3099F27F,BFC34E37397C74A3,255C15CE3CD7CA5C,3CAD5C4DB9FFF963,55C33185DF5EF423,CAD95D800947E396,5C36FEA4D3C2BEA6,15B021146E87577D,E6EBC02C9CCA9244,92C9FE3205FDAD82,000031B32D460DEC,3D3DC04A3B15CAF5,28538EC3BB947C79,B8F1E2E0903BAB5F,EC7C40DEF190ADDB,4582787B4666F5AB,B3D5C730E96DAA07,B2B5C495365C0B1D,4025041905132B20,30198B0ABBF210C3,D5B8FC07B5BF005A,DA6DA6F5EBF525C9,0000438F2528AE6D,752CDBE367EEA4F7,4E58E6BBD94B291E,8AFB1CD34F2F97C5,2ED46CBB75C32378,7FD4CDF785908086,5AF6471F1E1B45D7,91E88233067BFFC4,DABC08F8B1A77890,F9552D5E0FFE8E48,BA6809F9D51D994B,35BB985B8C523364,00000D949DE2A705,5F4B548C24BA41AC,4EA620A21D33AD83,20A57C65530476BD,33E51B659893652C,62E08696C7DB54C8,D5E363D045009221,4BD76A9D05126E0C,74FDA8FD1567C24E,FB897D1DED7B6C02,84A137C82C97A09E,FE790798B22E2CEA,0000169087A2B928,81850FE5165BB484,3FA5A38F05BD9176,924F682643C75E7D,9F92CD21E154C745,43B0AACEE146C919,E616D54B5AC6D3A2,70DF17764386602A,68C91FE666AA58FA,568845B4D9E9A8A2,5D544F0109DF1263,05C89F8C94594C55,00002E795EBF958F,EA7CE1BFC154DA4C,89829AECD84FA92A,85C0D9CDB12EAFA8,BCE7DAE8EC19D18F,28E8C114349EBB0E,0B3E0161B1C9D2DE,60E5C614565F774E,FE8731DB5B4F5A1A,3C7E92281799BF0C,9E4C2F60DA8AB53C,E8295F65671FAB39,0000430D1A11CE4E,9C7E9FD26F948407,DC6190618CF4461E,6C7D302E1D0CF9BE,2C3AA738E433C239,A6581B92CA335509,02A3D33FF1E6338C,637ECA686E653B14,E25EF7943CEC0038,C068DC0EC4ED1296,FED60B7B1A3E73E1,2FDEA71545E5F4C3,00005DD7C18EBF31,A5B7AFB26644E8C5,779079D2B1C10A18,E7AC5CA4722322A4,A0D161B56EFA67E3,74463E950301A637,31DF6451AFD31D4D,716A70B7E2D30135,D0496673510F7AEE,7B3FBFD46C9F377B,28C5BD46C3A53833,073E3C9052658FE6,000041D243E8C87D,E0434C9226D11285,715914F4A7F87D2A,20E55224AD314179,A27369B68E9CCEA7,4482E9AE999518E6,02BDDB0EC80B043F,E3141772CFEEAD89,8115F0520A19CB7E,FF87A80151E7C2CE,6E2D752C66FBF73F,E13CB5B0DE4E678C,00006FA561734EB7,06392B4B1784272E,3EC18A8CFEE40895,58F6A2DE4E4C6B7F,16CA061DD0D90CB3,4CE1A46E4B0811A9,34510EB5CFD2D846,143F5A70383301D6,89664DA18A374914,37242ACE4E4E57D6,65305EB7E2AB5953,70FEC62D097F5C8E,0000214EB96C2756,ADE97FC94F22B040,787F36C729242066,8939ADD3DAF96322,0DFC058034A2ACBC,12395EF2DFC6715A,BA40B3A1ABD8FCA6,AB08B2F88FEEA93E,32C396A3E7DB9109,9BADFDEFE6B176E7,BDC3D41DF358C18B,065152118B53B20C,00002CE2DF45720E,165BD5FA4BF6800C,7416C84C30CB6739,079A0128A2F18CA7,258AB70147896DE0,21EFA4DC19595A70,3C96DD051F5A2875,B8629EAE5C31412C,71E805AFE37E147A,E2ABC55A8C568181,509C640F26F47078,8AEAC0C5FDA6759D,000068424A09FC1F,C2E4C74E09FA8DD0,4726BEDF3F5E9159,9E1256E5E33AA36A,F8B49B3F3CC80C0B,787D51EE0E3868FE,3B016300B2E3A96F,50C8F71BD37D3BD8,694D60C585609214,6933F7350AC82A16,79748E02CAB678F7,C491B5402B584F59,00004848C177A30D,1665DE544D112900,C6075C1DDD4E2C17,B204E092AA991EFD,F1ED9B27820E4AFA,241C665ACC75EDEF,CB3A6DE9FDF19B87,22E29919A31DA1A8,775CF19EA4A5DD83,6F880802335BFC45,424E23FB9A49DF4F,F8F8541A3901CC96,000063864C30F9AC,26833C4EDDBEC73B,B71DB42419021A11,63664F3A50F4023B,63732E35609653E0,FF27D455F696891A,B9BD77EDB0CA3E61,0C9D8C702C9F3D6D,586B6812ED2375EA,69D9DACB1F66691F,0964C79F53344132,21168256BCCAA376,00006E5AB0B94AC0,04FD2A7E4A73422C,E5117D2F38B2C335,29B888D0EEC26256,3E1641F1AF5D6924,847148552FE91E85,B55DE057155737F3,D9FA5BECEB70BE9E,810015570E9DB804,00F5D1B1B062A580,65715A8B59ED3348,A25581115F80E819,00005F86410CF057,7D0C055DF7E11000,780CEF18F2C1AA07,5F5F0914E8280030,83D152024980ADFF,44F3927785AF3650,EECE642BB60EF046,C18B75199563EA59,10AA79E90C9C5BBB,78A0A0114EC2B5B8,256CCB58E940B472,4DC9BD0A335ED63F,00001DB0CA249608,56C4041AF1DB97EF,69841ECDEEE450CC,4FA6FDF12C153443,7FB341CEDDE8DADA,9FB9A126CAAC9080,91750EBF25B3D23F,B9F19F13180A0DD4,A9B84B345D3F047F,A99D0BFF593CE034,0B313C83A5E49402,B4A0E9E8BA50FD5C,00005FC30C8E5F3D,A43810CC2EBDD867,3C222C23E4FA2AE1,A2206DBAEC594785,0EC463D1BA112B1F,DB566AA1F345A4C6,7C80649D9D3F3A9E,D3442AF826C2DEB1,39391ED849543907,7A1E4A9240975932,F7A8B08D2F57331E,9D2C1DCA9FCDC855,000048D3BEC20023,F7E19962CFA3D3CA,35CD11AF98294F3F,7AAFCB9042969B89,1FFB349CFC9B1D84,08E2FB9EE3FA23C6,965D6C870482BEE3,D480B42E9AA97750,F937BCCDE03D83A9,C591F81FD322410C,9D4612AFF62B0F99,27822ED265442B9C,0000589273A865F5,535C038D672EF999,13C19195C59AB049,5AA5C582C319EA16,7D483AE1A2480CAA,6BF9DC5F41EF9E1C,7A581B621A7000EE,D41F7EC13556132F,5B32BD497B6D85D3,C406AF4E2744E0D7,D802786F76E81917,586BE80C10AE137B,000011346D99F943,9C0773EAA8AB91B0,491D3E7E26CEC6DE,0BF410AA460199DF,49DEF5463FEE5367,C11F9CEF93F6AEC0,0EF406171101EADE,FD7E81120E5A6731,A7C73660F69C5754,87DD2B70CCD70A9E,32DFA1A66E84EDD0,8E08CAB0244F4654,0000590DAD701599,4E9A94FDDC47EB5A,B519D19E6FDFD7F7,ACFD936500C76A68,A601C6BDA40F157F,8944E8478629900A,B6025166E29E43BA,3FD1C0A96697CFFE,24353D83B7D794CE,EDB34650368485F9,7E7FA91789BFC839,227EBFD453374EC3,000023EDC8C0CF6F,FFD3C980A01F6E25,69D18986D1EAEFAF,B666EF29F046BA2D,8609F68ADED3C09F,1B037C1DE7E8A2AD,0A8B1A343B297DFA,FC1927F169B34F31,866A5CA2580D87C2,093BC9EE7555D20A,2712440ED1F9A355,211C47B6F3267E67,00000EB4C7AFE82F,B65884B667D32E63,A92DD778B4F6D67E,304C812E5B521D63,9CF464BF88C541B8,6173F2EFFBF77E10,DBEDA7B4733B2122,EBDC5B8B877B1368,5DEB78F399650024,63A396438ACB9D75,E90EFE55AF82F2E3,1FA3461A673E09A7,0000458D223FD5DB,FFF1DE936FB855FD,B591577C63E8CE0C,4DBB4B2A763A8FE7,CC4B8CCAD959B6A3,00773074FB2E36E3,A125A573C6099993,D6ADFB177A000D7C,6D26BEE4061C6F3B,F7E1672E15EE239F,11E053D565777CD2,25F1AF3E12E34F47,000048D6528FB383,B8C577D96203D4C9,8CFFA4A233224CE7,B77C0315938B3C89,DF4F6A3477BA5862,AA085F1F68C5BC00,620B94955E4F4E25,811ED61AD7EF128C,1BB43B63A2DBBBDF,4E5CD1A29EC46BF4,76F2BF645A6C1D3F,2F316D293283CDE7,000002E368FFC9F1,22060B6C61659F92,8BCC5511005FA209,2F3E0894F5B1D052,168549CC92B899AD,9CAC7F3B91CE6D4B,CA2A205DEA44FA18,546842A2DB066985,60264008A24E343C,4E65A40DE005646A,14AE8FF2221F8A78,C4E4A6909D253579,000040807443AB9D,7E2B46594B3B1777,F4B757F73E1250E3,B9C52948DB210DA0,513F7D6212C80474,3FFBA7F01764A888,3CA34EF30025CFA5,C65180000850607B,6D7778414BD53D1B,860C84B7A4BA6C34,8A66EECB63FB5B97,89314F6F8B05C9AE,000055355D9AD9FF,C61C5F7DDF85DA52,F399180A773A71E1,C9CD8AE33A10DAEB,B842B38474A82C84,B9B7F9BF6505BFF8,F8A75137BE3227A1,9E77445887A72FDA,7C7963607B70255D,7F1CEC9554BD381F,38871B39505EBD0F,AEF155FC5E1386F7,0000460CE6C3E4E6,84A250B8CDD51915,047142B5858788D2,12EDDAF3495468F3,C0257E323AF49A0A,0806CC864997B447,AD5949AF544E110A,8A8B839E62500743,49FD16C331707794,03141E829BA33C73,2715303A7620BF2D,37329A775BD56EBD,000009671358D061,5B5CE49F2F1EF6C4,3D7E4BCEEA3F9214,F5C64FB0C5938485,FDD925AC3A04A0C6,15089305A3EAA482,0A4DCE7C02D663EC,07158F5E30AB4A3C,A675728747B89725,51BD65BA0712DED9,46708656D571F772,A4A58D74D8CDA9D5,00005A1753D526F3,4757ABA2D7E5D5BE,8C144320E6C927CC,0A72C9318DEBD018,660FE9390211D00D,0046FBAE69C5685A,E87DFB6BC7DFE6C9,0A63D689BB18BF71,0AC007C0B450AFC2,2EE6532CB5BEB5BA,C72EEE1C965C1D9F,69720A79C718FE37,0000377ED87FB978,902E456E8F5A4FBE,358BC3F62279BC2A,D318B5FE8A8ECDF3,A09BDEFF32739534,21B9A9654CC1F325,72C8280CB60CFBEC,99E69910631554EC,A8F4317F8DB59A7F,7AAA6353E0D0B177,520B1C85F867D51C,DC3440F586677A10,00004B9CE6D1C75E,914F38B6E4BD43F9,81C581966F1258FD,E244D6E6DA67B302,160BED3F7C4567B1,B239F1CB3AF3DE40,C22BDE1C392A97CF,0E5B8DA2EEEEFCE4,FF37D7DF6875CC74,6EE6C0E38BCBD032,E166D80DF732FCFE,8FB1466EB04BD9E8,000009E6019BC8BF,C91AC031A9B26853,D563828AC78F7E46,880BBEFAB051B7BB,C206A6F8A85F16C8,0D5E8CDA52627902,08EF40ED9C747E41,B4F65DFA45B18587,396528BF9588D0CC,4BEE7FF6A192D8E6,B1ED552787ABA632,D60396CDA415D370,00006337CFDDD1D2,D054E19AA6341276,1398C7156480636E,AE46D26CCCA7150E,E0744C28E974B99F,3096BCCBB853BCCD,C14541AE67A5F799,6BFD4B322BFEC701,C9798F017493B501,8B32115E59604B41,83E5068888A8A136,FF574C0AE710D1B5,000034A5B21D9F93,119478D0C34516D5,1ABA8ABD783C8181,0623D4D6E0443380,A2D52D73E32EA171,AC89A09E79ED5CE7,5A416288108AB4A6,58CC31716474F79C,699C2C9109190AC6,297AAEBE806B58FD,78023EDA03432FA7,FA7E7A8DB7166AFB,00003FB374A2EA18,22EC3F49589E45CF,12356FCBAE6EAE11,7786C169EE925C57,811442721C5F9F26,C9CDB16695813010,EBAB007E1F7CC825,897BC9FE6EC0091A,A7DD601924F3956D,ED1B8516A750E52A,4C8101DB1C8BB6B4,84DC086CBF7B03C6,000021C7D62F649E,642D37438FA766D5,E606493723F7DD28,EB940126876D4629,33E1F0C7D40ADC90,A19A6E7E9821EB65,B796F21BE2693BB4,37613CEADCD2BD50,7752A212680D4AE5,70730B2F0F14A758,684090F9B3E31A8D,1A418EBB9736D866,00002976CFFBC2CE,101C79FA8CF40F13,589129F52EC35F7D,3D5621190215B43E,1CD364D16D7FB069,C09466AE9D2F518E,C05948D760E8515C,E51D5A698E909411,4527FFACE7732627,951E1BC366CDD700,79B7FBAD70AA18AC,51B7F28C694AFBFB,0000556D7D5F14DA,882ACECE07496416,20E38C7E00569B26,D1ED4FA62586D86E,AD24D81F6C766E8A,8BE2169FDF6F490E,E099AF826BBCF51E,EBA40B4B5C223C25,6D04138F0511342E,06CC6B3052A0BDFD,B781AC63F284B201,F9043F9B1EABE82E,0000440175A10054,C8175CE823640CD1,FF5D759522B3D16D,30F89031AF3F7F20,64A6E878EC670EBF,A754E49542B6B9A0,ECA8395BD15CD6D3,110BCB2E753A642A,3C8803870CD557D0,24A4FD5D53633519,D95259529AAFADA2,B0ABA6564925BBB0,000006BE41FC3074,D421FE9A89B8D87C,68D34EABB9A1A733,4351F5571CD3A2D6,029BAAB5A12E56F3,252A6D492D9CF42C,CEFF9C61471A0A19,505D9500B4174857,17FCCF3CE3544746,5B4FAFE755056BF6,89D8AEC435A5363E,6185193FF6D87AD8,000006B3ADA8B54F,FCD2A7E991C4A8EE,1694AE003485F44C,D173B5C97EE2DC51,38CF460203101D14,EC226BFE1D0F55A1,E904A68BE15F973C,93CE2AD5281991D2,DDCCA81381F6C24C,C9486AC34A2E2481,078AF2C7E94BD229,2DF82A6059078631,00003E38B9561617,12DB8D33D68BEC1F,457B0C9F8533E50B,7F594FFED01C16B0,899761B8754ED5EB,C170F1E28F6973EB,54F2A2B83283412A,297225BF88F97BDE,A5424DDD59E8FE70,5069FC7A8D18B9CF,EE041780432FA7A7,4A169FF728574FCA,000040D7477EECF3,B38A0AE13EFC62D3,1FB388E49656B04E,E38E63AD2E629C6A,6B3BF644AE49BC97,3C06C2E50946E009,091F54F8F9D11DBF,4D1C67DD8D2DDFA4,D31E6157D11C9CB3,6BD3EDAD53314BF5,CF8EF13EB641CF7C,168626882371D7B9,00006CD080D802D3,055DB94998AD475D,3F53C425CA7A5C34,3C5C438FAA44F546,5F94A7207E968415,BEFEE702D0999E50,9BCF95956D35B20A,ADFE6435FE802233,D36BAAF2F52783CE,4D98298549B64D83,71A303C982221F1B,7A6B35E3F1411A0A,000060DCAC2B2292,12EC42A2527B1419,5B7DB8EA01CA63C7,6CBEBBC480210D76,A027F42F6596AC3E,7D066CC01919015A,E50ADD4F957EAFC9,F5D85F941E0BF137,CE89F7ACE2D022C7,5A38621B96A65430,512078AB3DF79532,BCB0C427E58EF6F5,00000061BAEB15FD,50848DBA39321A7C,E973C6AC13682FF1,8B96ED22DC76621A,0FCF0D2C140D3208,91262D08CA79384D,11FE7BA0DA7F9DD4,316CA837046221E5,076CEBEC8243EE05,463D3531BAF2CB01,CA699EE34E4257E9,0658887D2776501E,00004532CFBECCA1,50F67E1D822D61ED,023851649FDBB3D0,FB9E14D1217F78D0,0FFB021C8D09918E,0B0C716D04197C1E,F1EF5308EF446EDC,3973EF6912F8518B,091FD6A5E3602DBD,E6504827C3545B23,3DBEAF64560E6D6E,FC8B3AC4C5DFFA52,000059CF3D7DF3EF,6C13DBC0F6B7F175,22B0115ED201505B,D04237D0695D07B3,5ED76164FE31B671,AC64E87948C7AEA7,CAB514BAE5D5E1C5,60031F7D9F04045A,FE033BE785628FD9,8C136BACE9EEACB7,893046B58D5D6E04,6FB6F3894988EF9B,00004630884BD33A,1427F517D84254FC,04F44F768147DB27,8E5A2DC74C23AB3E,206729AB25F75FF8,E4B6FA0D870C2B32,C8060E30DAFDB37F,6F5F998A3B7CD2C9,239F3B07377B80E1,6DBA3F76741B079D,88F0991E64995F72,88B1AFA59CC7B532,0000083C4251AEA6,5A6802750FB675E6,4607A5CD9C42EF44,99510B91419D0A59,6248348A1074581B,83721AA394EBA5C0,EB5319727FDC2783,3DCA97D2151D36B3,DBE41B9E1AF2F40D,02F6C1391DAD5656,6D7C863831E92FB4,D5968ACDB5757DC3,00000C8618201A00,7DEC517F2060A3A5,B11B49C0AC247785,DC585A7638AE9B75,42AD804C7179763A,FF4F13370BA45190,A6B8EEC8B1A1A84E,AC6ED06124B44F76,4D95F592268E0AF8,20D1C2012715B67C,8DE11E474D1B4B92,D71EDB064BDAAC62,00003187DAA3EEDA,985286D3F38ACBFD,CCB937386C5E8578,C4E6EC92A169C880,AF6110DBC14D743A,39735D85AEDEF510,A8DCA3A818E569EA,41C2243537BDF912,266D73843116DF91,A729D0DEE0FE967B,B50FF60E8C66AF7A,182BB2F1A3C9B2B4,000034EDB1614659,C4013390FD330D4C,542559B7A2BC8B38,C6375885138ED051,BF0548590A36E25C,D1103BCEA0465500,757DB82A06C87871,8E4BD9B01C756F3E,23DF74219FB11454,83B33B4E67FC9F3F,2223D0482604FAC8,A06BB17B9B963F95,000063D2A7EADA18,ADFF611CEBA3F7BD,B050DE94DA1B7243,DB5D11693EDFB735,D630A79622E2A7CC,ACC12FFC2CE5ED08,4C47A9DB89A34341,54E37168F36B202E,5C8F488C5BAD0748,78F80152A2E75D5E,C73A617EC3EFFB5E,BBC62156DC18C9BF,0000638FD75531B4,244EF22E57389F40,3A9D47367C3DCE3F,A00D71BB31C73954,C1E82CA215F5C0CC,FB83E704CFB5241D,45CC3E1BA8F23EE0,DE3A2010A83798BF,E56709C07ADE538F,D1F2CB58E93C7BF1,A17A5606596FB9F5,FC2A836D31110012,0000080F33B655B8,7A9BFEC211EFB636,81B9AA2F57C1BEF1,0461E871A6906EF9,34F50FB584C28E68,9999EB6267D0D5D0,88E9AB460B5E7118,A999AE05713AA556,252ADD91650CAB3E,E3E86BBFD21D6391,C6684720F59886AB,B75051C7D7AE45EC,0000017A98761279,EBB3D3C94DD0DF6C,0222A3AC195E62B6,87A71D1216145C58,143D5A54DF13A170,A00EB689F0F04004,0946B3BBD71BCE6B,D27F224C5D2B11FE,D936AD2966D45BD9,EAAB07D4BBC88AF3,4A19CE996F2093E2,B8402A5B6C26D9B3,00001DC8FC4BA51A,3B53284BFF8F8C23,A11774D0F830F4C5,BEBAFAA3B8B9958C,1F6B2AC92C8559BA,D4A871BBBE7738BB,3D2BA628BDAF73F2,43E7661CA673A3C9,CBF28699FB5FD640,979F11A5D41F7A34,A1A181852DB171FA,5021F6EC0F5DA35C,00005140A0F3AAFF,80C28D441D1B2A2D,43749EE078E487EE,DF261DCFEA7D89D5,184506BAEDCE233A,3930DBBB07AECAD2,CD04229D265FB223,29A0B65F6090FC48,4E54272E4D95C4FB,D592EFC5E9D75A11,43A6EA00961F0119,1EAE55ACCD831C73,00004C579EEC333C,58FE5233A9924701,A829A44F77F48443,0D4BFA139381BE61,C7D70AE93D198598,E8350665116A6F79,A983D438360F22D5,8732526D867B7588,7665E2AB0A85B183,834D0581F73940D4,F7758DACF3C968E4,550F0EAA92F9B25A,00001366C817EA6A,2F9BE689D87CE5B1,311A93459C7B24FE,0E673C493681C8C6,2D8FDD9A02CA9FC3,F057E69FC9521F4F,B66068D5B9FAA844,009CFCA489E13C50,BA7F66C977EEAAF2,5EEC7E926355CE39,4275FF84F1D5818D,3D5700457B9A334C,0000046CEC7A3E1E,2457004D4FBF7609,EC87D71A781797EF,AA9C6018E7464625,29CFD512250B7E94,9A1EE2B3D2AB83B5,8A68B825BEACA27F,65D7F486EAD9F3BE,3DAB4FC0235D49E6,238CF5015F9EBCE3,3EB08DB3A0883F11,628F77CC7DCB2A68,00003C9510EB88E9,80D2D4C7AE687777,450CA90078A074DB,B0470F8813EED022,85FB772ACD3F95EF,5C75FB50E32A674C,8EEE77D253B62D7A,2E923EA349A438BF,E8C6D9BC87104A68,AE37DF71B215842A,20F8AE375AF842BC,909AB97CA1A25A61,00002CC8C79117F8,C5AB38046FB54FC3,09021EB2E903B909,24FAF16C71566AAF,D76A2696E2D2662A,57FCB86F9BC2C2BD,406835B937598801,851D85DAA9E2B619,D0E3148C94D7EE8C,60809FE60F1D44A3,52727B7335E9F4D9,65E5F1CA614E6244,000025981CC5BF01,44D12B8F0D1C8EDD,477A0919CD66414F,BCB03BAA4D4D5272,B0926E8CB2C80B5A,7DBBDD1DF010019A,73E634D6DA9511D0,4020DA2E69795D85,D85B6AC215AE91D5,3F25CFD4AF2813BB,2534D70B48D2D5FE,016D135ADFC71E8C,00001EE02F9B8166,C1F4BF88F5751FCA,9F093757280845DB,8DA5D6E50D46A620,246345A3FE1BD00A,698628ADF286B293,218F5C443D6B881E,2DE101B540E60D71,935EEE849732434C,53C7B6F837D87CAD,19B00F22BA9952F9,7AD250E33D3563BA,00004B7934B4B7CB,EAF134F806EE657A,97F73EE7FF796DC1,7E268B37C7A5D840,CFD72214B8ECB4D5,5C1802CBC63F19EC,FAC6DE3DFC2477AA,3F0528904F5ECF00,83EDDB7A76164E58,2A2E5AA35D424FA0,6F2D9B296AB62462,CBE2435EC3D2C376,000050F57457F0EF,0643CCE2C301C456,FE3777E78B2B2BD2,66A8A13A111CE8A1,A2E3E90C3BD88DB8,E5E64CAFF0FC8CD3,81E1AEA5E7B190A0,B25D28A282B0A414,4D96E064B10BF2E5,A12630F9295DFD98,596ECF0251314F2E,E65019F1F896488F,00002B392829FCFB,39A9FD49FFC4585D,23FB4302AE96039D,59E4DEBB0F8CBA81,FF3E70F315744648,E1F08D80D838A793,67810A579F07C009,B9656A1278698620,92CDE699AD688A28,BAE2C8BFC36269B4,9F1E9C75DFC80768,46E355AD2CACFCF0,0000271023884DDF,AB6692E78B59E2B1,C0CF9D72FCD01B20,5A7DB2F66E241B44,35D64EAE5509C1A3,6A787FF8D64D8AD8,6E4ECF5615D88F6C,7FB5230D6C15D871,77A1BC0DE3FF1BD5,258810313D75E848,9EDE2ADA2D45E00F,800B83AD006DA521,00001932DC3C4834,CAFD957CA2D402C2,A8DAA1143E6643A5,A118CCE3F937DCB8,1F03EA8999C87688,AA33320E928BB163,B3024798AF9616DC,B9CB152BA40A8897,CD2783AA405EC461,90238A8B4C8A6BAF,AFCF2434EC21E7F7,9E3F8B6501D7EC89,00002C831B68F56B,B8261A839C2B4F08,517A3A3BF4D57FFD,63248FAF9B1CA601,47CC401777E801D2,D58F3B9F3EA56080,DBBEFDAFCEFDCB15,BAC1A9177C49E3D8,580F89115B907927,2B23AA2A0E8AA9CB,BD5832F195F6771B,42C7594786D8CF3B,00004E194082F295,ECD3051B9DA82ABD,4AEB1A4934301A7A,805C334C5E384634,0CFFA714D58D180C,0D769CDA581150AE,F80BF7DA1C47298B,7E73F736FF450A67,4F7C404C93C8498C,E056655C4BF56036,44CE99A9CF55D24B,6F7CD8A22E5C61F1,00001B784718E1CE,017287FB270B5415,D9789BEA28902292,1D60EA8F012FCB45,8FD4C33A5C1D70D8,6CD53A78011D149E,E52F9AADD0CA099E,A229BA870D2F1753,6C5F51241B8D5810,CBFBD183A2259A23,E6809C570C3FFF9B,74263E7C8E26FE3D,00001231D34854B9,B8EACA97478B2ABA,C2B2F6B3EC19F038,672EFBDB33C01E13,73C6795EAB31BEA2,49F4BB8B6555436B,EAFE693EAD0AF2FC,7B63DC93FAD4E090,31CAB196A3A6E329,724DF9FDB028FC69,AF566038A92843DE,F1A7D78F53CBBACC,00002CD063141870,CAB3D264A24EA227,333069CACE76419F,89E11B4144F31DC5,64A2073F2C80CF8B,23C4A16A5DED3FC7,BF19FB73FFBBD55F,3F7DE894B2C533B8,DAA560C6B61D0493,EB59B81108B96112,C34FF8906FC0CE0D,621689A8D800CC58,0000034234793302,E358401F0E583B37,C2758A18DF914375,AC1077096FA0FD88,49756A62E0853469,3E137EADC4688633,0F07DAE8BAB218B2,52BB647724D9A107,04147C7B044CCD31,5F96C2F6C1D42E46,FEBEB2FFFFE9D116,D394C8A2BBFB763D,0000129F18999A7F,B4F94F09A6FD15C0,D8E9317619AD2E66,A81A350962F64913,3D93549AF70991A3,EF2E575F8848A69A,9C51E235FA28D437,920F5680420E8AF3,60798D583939CE1C,BC1B3475BB5BEE4A,70F5AF3243CAA1E8,792C7EF9D9F26589,00002C38BA0E6848,35B7E4C5B8F7DEBC,90A3A02A03824979,D20CA40FBC9DD846,ADE0F2544AE499A0,2BA3574946BBF93D,0EDA3443F2B07FA0,50137543A84C4243,211016162F69218C,CD2F3803412B3ABD,BB78236D8F691C9A,9A72C6532556D64F,00005DCA59D4FC3F,7BA621194D3638BA,6BB2E3381E97ECAB,CED08E3A8F45CF65,9634225CD864CA0B,A8D953514935A67F,9E5C1A48AB40985E,5F663C606F28AA98,9A8DFB815F716041,D415FA32DBF54505,04687C051CC78CE9,79B97DC0151B4BEC,000056FF44554C83,3D384EDC71EF664C,790B8C7DF53F580C,5A55706AC489F4E3,1495FD9CA9D71D15,14202682E7A5A8FB,F8B3A2A9FEE32968,2A7FA904E13D1BDD,A6D53EE44374B69F,518E6C4AEAF5DC75,3DBB1633FF1D9CC2,7376B7F4EFDBE350,0000349340F2FFD0,5A54AC6BF7570F63,4B599D31CD9DF30A,6275F155DE8995D4,A1373512E0CE7169,03AA97A4F1E0097D,97796BB8EC604366,20E9AA6249875218,712D8CF728D9C731,44FC3EAEAD4172CC,0C9ED47FE8CB35D8,41E571290E0B0753,00001C8EC09EF84B,79BFD92C9A9D2234,A30FCF6918708742,C58DF62B23F98C94,03662251209B02F7,B0EBC9F01C174163,F9E2B09BD93AEA60,078AA25A2A5CFACB,61A6463F8769243C,D177958E83DBC19B,A3957517A15189BB,6B015B4C2A952E7A,0000014B0FA9426D,1CA659AD7BD93735,D96CC8DD172846B7,281930EA5F64FBEF,A7CC852C3C09D3E8,FEC12551EC4A4612,9A2046D4559054E5,D0AFA1229BE69781,085C07A4D6D91AF7,80A566B5F1595DA4,450863CCD67FBF44,E546752158157341,0000340C0522ED4C,003D3230DC2F548C,B173FD5146F156AA,5CB82A78E3EBBED4,D3C287D3AF5390DB,D8FCDBD9B163D3DF,8C76FBE395D80A5B,1A114D9BFEEC7FE5,2D7CE75E7F39A36A,A43629046D7576DB,5692D8AA2105FC62,279F0461BA937C1B,00003AD4527F8115,5787B3000A8760A2,4951A448374477C1,14030855AA029833,7D74AE192938EE08,3A2001D0B8050591,1E353D8A29CDABBA,3D47C1BCA3EEAE88,E3A6DC09445CF0F7,581A0228AB782F4A,3674448098072862,2686D68883AB957B,000008B3168890F6,01FEFDD9D715C8D0,CEA3EDC4AA21773F,170F665030441119,AD5E6CD764017328,35563CDAA30BD6E3,E3627FAC1B13A642,1132DA6C86137FCE,0893F83EBB71497B,8C34307D8E8D868D,DBDBEE0589464B42,9EFE915FFCED2933,00006A85FAC0A11C,CD32A397C82F78D8,C08EFF76F7E6549E,F15F50C16ED5CF22,8D7631EDFBA21B5E,8E80F03C2BE8EB73,47F68FE9FE822D7F,FC0E08A3A3835989,B2AB31BFEF663DA2,FD795F7BEEE13D92,65B1FA00E7F27242,A107237127D2EF1F,00000E8BA1F83C97,4C6CBE0D06C9A37C,D484C07D556A4043,3BB8585AE7B450B4,C08468A96EFB3B94,C4D13F2616325C8C,361B4721737786F1,894F878A1584154A,DCA3B4071C7BEAE9,3EBA3EBEDF01B3D6,515F5A0FF8907D87,10FA275746040E02,000066BA2DD87C99,7654A0A8B5DC2D10,D153FA0031C522D5,F222853142376D48,1C47D6E77EA8AC7C,91A951C9D61E0C1F,6ECF9E59C5CADB2A,AF0AAACD3CCC9C21,74618EC171373A9B,CE3A5FE59274B35E,3C7A7A3935C27DB4,6735D8276179B1F4,0000207238C4A05E,051142CBB7986B2C,751631C602D282A7,D5F3CF575C9A6A3C,FB43D2C279A6C385,CEB98671B8317961,A9AEE73E8607D134,B31B556FDE175A39,48BBA727309D90AB,40D35E3613254D6A,23BB258BB1D1EE44,AB475A9BF5FD9933,000052D609454CC1,605C1D3C389CE7E3,4EF854057EDDC294,747A3D86446C218B,A7460DC5F24861C5,15BFCA44797C573D,58CD174C2457FC12,C241790BA4289F47,BBB46DD535212F70,4177091584A22BF5,DA4771C40AA597AD,64EB27A79B06F5CD,000003FE9B47162A,F78B0113E6EB753C,52CAD5D1DE208DF1,D11E57F403D0BF71,599F25C503FBB7FE,3511C144A65A51B7,F6864566CB1EBBD3,6FA8A2569CA84672,58AA1793C900BDA0,D35042C7544F0153,C9CC5344192BD92D,93A6FFBA82BBFEBA,0000690C2F3DC3A6,9A2077689093FEC6,928CCCEA981F74E7,0DDC33023C5F1B24,C13942592B450CB8,925737B823CE3000,298AD11A3EF22366,CD7734CAD18662D5,2BB15563FE178794,4DD9C12C70E6D9D0,CB8474BCC1E7F28E,1A50A77AA7B98F5E,00005751B596A6D0,B1ABE373CA94A3AC,FCCE1793E46D6BB3,A1A98674089847F5,2A3C413193F70354,34BE6895597DC17F,20A1E3C8B43ACADD,3B2FD54F663ADCE4,C71245C5C30F9C3A,23CDAD274589B58A,5D2B415669450F89,100C24E068E8C977,00001596C12B7030,9EDD70167F5344A6,28B5752C2ADC0C8C,C7BF9E137C580D3D,D5F67382AFC983BF,356A44457EB93300,4092F6D9DBD13544,AB5F29F48083E07D,F691BC4C7A4C4983,36CE403B677EF687,3FA6C5FEC73A1641,BEA96461F191C671,000056B65824E74F,7BEB78E98E7EBB73,CCF900C31B4ECB77,54AD1F50B4417C51,DC0B30283343343C,80D7B79A285F8B4E,8FEC295FE783184E,019CC7F61B594A81,E7117BA092289445,C1D6BF38490FCDC7,B5E604897C326012,B17E3D1DDB212662,000040346EB071B1,2EAABF52BA7CA8E4,FA922E6031DBBC1E,30A44C7080ACB00B,039D1AF3D0E886E8,A4D3D961F35B1907,83DD475A981DEB3D,61EF9E6DEFC4B6CE,82A00094EB83AC35,3A1D138259725A8B,C57523803D67BC9B,71751EA114E39E80,000011FB0F5505EA,3F811FDC280BA7D9,9548B8D7A755E491,9CA29869CA9DF561,6AD4025D6D171E56,635C11F0E90A8F95,ADF50ADB201670D0,3344D2FBF5B5A78E,6D6A46347926DF18,5FD58B5219BAAD02,CFE7A9678405EF3B,4F0A61381F67AA54,0000596EEEC6E6CB,E29FA8E8F4E2C2D0,4DD2365889E10E0B,C62CBF2B104F80E3,4E9723FAAB0341A3,217FA9C9FF4191C9,0C78D083FC6AF7D4,0C032D6AA4FCE259,7A653D3006B7E433,D0746AE2BF8EFA65,15ADD27E4BA7B792,0F3EDD5CA0E8CB8A,0000188FD4242CB0,8FE971FC03267BC2,513A2C121182D35E,42455B0B3DE06CF3,905FE2D6BEE139CF,C4FB0E1830B6A944,4AEF35C9AF33F550,B9553706C7A0B1D9,DAE2B76412BBE8B5,0DBF5F3F23297F76,05150823B6ECBA72,AB8957C1002C59D9,00005BBAC33BC455,7E1DAF372396B902,0EE28070E643CC71,8B75D91FF9248FFB,585EEF13874469A7,9233B99FF0B1F934,D3ECC698C0365082,DA6D3282BAF462A4,93A56568295FC1F3,26BB8319FF8EF03D,0D946FE16CED1C80,5C84F01AC556C969,0000390D49F1B0EE,C5E4925F38BF46C1,B1BE67396749D205,DB9A846F5FE11E1A,5527CB605A91CB42,36310E83EC2FDE5E,05A1FA00E20EA736,9D83DD412A5207FE,6FCCD0EEBA06BC08,498B1057F6F9568D,C51AF40F16765057,98CC4DB908D9D1BD,000022DA63B7F6BF,6504F351EB2F2E40,901034786BF14AF4,A4940277B666AA5D,3A1E60C81A585992,8E056EFEC198EE64,94ED38B005EBD5F9,2E9825ADDD6B4A6E,392257699C20241F,379061EB444A9E20,BD65C3A964F086DA,512868AE2B1730FA,00002E3121A33D55,8D44452708804055,1A6FBA76B57C5DA1,22A29E18EA7D9803,DDF43B4C25918395,6B2FDE72924EBBBF,8EC4CD96F256BC45,45CDB802059A82A0,95F169EA9BDD6F5E,1A259CACFB516D0F,357726079577D955,132ECF69ADE4C117,0000572611C4913B,98C9C31B19DA602A,8DC62C1875D26501,B367FF053ED021BF,42E4FAB6668F1C13,10045B7004F26E2C,7E8CFD360AE2FB19,D0A42F81C7B6DBC7,DF5A7AFAB3E6DC2E,E5907E3790D1BB27,2069A8E5D6DA26AC,64B0404BD58D8595,00001112B04CB7D8,19C18473C8DC429B,15F8922C13F3149C,8AC7203AB29B3476,3F0E8AE9F9341E42,611ADFFB0CAF3148,E8EF759F95A75556,59F55A9573A609E7,8E520D789E8B76C7,6D910691B7DB0DC6,8B71A75BDBA43F46,1D12B22932B3F1E9,000056FDD5FBA85E,1FF8FC8A5D90993C,E75F097A61D54F37,C3410B322C02258F,66BA351C15AE0F02,42C5713AE0FD6F81,2D7D311480450C2E,F23C2AEAF9E91989,55EA46A4067781CB,71B0CE19EAB1337D,07A6B002B3E5DBAC,61FDEC9BD7D23F66,000054D012931062,808A49CC40875842,D45269A6A22C2C43,058FBE12AEF8E9DF,5A7DE3A3AF79E073,E11AAC6C6A9EDE94,1EF3A96DD6C3087C,BD700BDCE10E0A6E,AF7E0795686A3FE0,7BCF098B72F8A10B,B25F7C6C2BFEF70D,6F97C6E90C889B58,00006D3B2B3612D0,BEFA82CB7D1A2F55,56D51F31599F81C6,66ECD6BAFD0B3523,2B60ED25592FA9E0,5C2EAC804A37BE66,CA9EA4C9A3A4B6EE,490C3EAAFBC39F85,6ED31D42E5E2788E,F0CA142C31DF8D24,1DDF79AFFC0D2BD5,E4D94E4F8921F8ED,00004181151CBA5C,69760EE8430A41E2,178FFC0909F259D8,ACA9083F7DA4E07E,F6E94F4014557245,10F7FCDFC50958B5,841C39DF3D657FB1,901476C51BD028D1,78ABC4B4785D7840,22DFFFFAEE3F3442,13E85EF474CFB4F8,6E5CB595B1CC2243,000034E77DB7B80D,4B4F3F36EEDFBA9B,8BDF8DD192DA8F6F,EFE9297B12FF566F,9F16E3C44BA8E292,EFF1120A8067F658,C952F331AC1485A8,C81D201E05AE7974,931FC432A71B0149,C7976309711334C5,C9DB0A52F2D4645E,E6A4E64EA350333E,00002EEF8EEF5C38,55EFA270ED225CBE,E283A55A4F23D61C,1A239E2565F813C1,F166F2F035FBF751,F1CE27B42378E1EC,FF638E0F667775A2,8B4B9B32FBA9F74B,082CF37B230E060F,CA42E856536E6026,8C42FC2AADAE6E70,EED4C2716FA14A8D,000011F65F6A107E,6D948880EE6F8D53,FE54773452A42FA4,C884403A0E0CA477,0C01DF904E5E7EAA,811AD9705DA82350,057B690591972A56,94259F582F1E2D2B,EA0AB0492A8C46B5,EDF74E7E4A6F795D,562D9CEE6BE09077,3E5EC5BCE675A136,000018C2790010DA,747F22A414A4FB52,C06C9957488A8270,8787DAF067E96D5F,FB49FE2D647BBEE8,D8A597338F7EFCE9,188EF5E72BA1B6F9,C0DDB5DDBA189E1D,5F79ECCFEB819CCB,20E5FDE87699CD0A,762E2C5EBFD32E65,9B2C05CE76A6C130,00004033E99E63E6,8913794733ABEA94,42F9577744285B5F,0FFB6BA46900E292,87E4882E781EFEC0,C6692E6B5AD8E28B,A8F19D38ADC784E1,F48A0295FCF2099F,A5307F5D79C43EFD,F41C73597D50ABDB,566C042D741EA268,46FD6D7DA72FAF0E,00003DE008246844,9A9EE4D64085C070,1AB8458ED5DCA0C6,0BCE6B44327B1F1E,2DA94C707B850757,F15F439279CB0B4C,B9542D353B421346,FB89C95366254401,C5A829BE95F4C140,AFF0D28B74227D0A,7F98CFE819D08F76,9DF9E3DAEBA03B2F,000029EC3B068092,65F2128C93429DC2,6751A0E52FE07E93,188D757D339AC8FC,9AF75A455304331D,12334C32B1A8644F,DC4FDA32096E13DD,40268DF0ADA9E6E2,15AAD96B06A74F90,1D8585A8A7DBB900,6E0B55AE78F77B23,6AE63B8F66B93F0A,00001A76AD6963CA,F63EE144F6E55DEE,22DE66660CA2D964,E44480913BAECC28,8E6FF3404440447B,227B76CF31BB0D01,3B1759557D91AE5C,981B483797200CC4,C0FA5C1F9C522FD6,D0F2CB8429DC6723,6A721DB0489D5411,0E6351C288646482,0000074F635CE7C0,DE323F37D64C0A00,EA5DDEAC2CD6C513,5A4FD9BB2E8B3930,D09CEE59D0BCA683,52930AB3D276A886,F1E178994145363F,682A90ED4C7378B9,C88A646A7217C3CC,F21CEAE627CFBB15,1741327D5B011706,5A0AF370CA4EB764,000048A18985C74B,CDAD6DAE8073C44E,A8BC67BA52D991B3,62544BD8798B8D75,A8AC9564AEBC472E,15FB6D389A1B9FF4,E05208C948DAB65B,93867087A526E753,A455869C92188112,3682C4164B891196,039696C4BD5B67CC,98936BFB2EF87387,00005CD52C1CD281,F1CCD5685612FC06,EE45ADAD6768CDBF,164AE7C7ABA21B67,082379D8D203F0DF,87474358EC83FDEE,090570FB9B5930C9,4D57B6D0C954DB68,1A019E448E7EECD8,9E24D8F686D4078B,B15F27DB578A4D2A,C2EFA71071C59015,00004F4EF842376C,BE45DF6B5DAEBA63,766949F5ED0AE41A,E9A73BF2286C92C0,6A168FBCFB3E1675,C8B01F1297CAA2A2,39F9A3557E650532,4C853ED25BC28602,D1C61B48E0A2FF05,A0BB1C6F808F4E5D,2018FC36A347D412,0AFBEC9FA9B93EE4,000041CB612132D6,B14336F4784638FA,AA304023944FECF7,C7D802B025EE3CA5,6ACD35898242985C,A4CB819A8511DCDF,70891BCF42015C2F,CC46A870CF0F342D,9C88DC01BB236736,64C6491BAE0D631D,0D3061AB7AB5AD03,C368984B2CD7A721,000016B679989350,015F97F8826A0E6F,A9A357AC36BDDDDD,776E301D1829CD6C,DAA971077473D48B,4345CF108252B838,21D48E1723325B36,92DFDA5088AB4D17,B73A91943B79DB48,86B04DF0EC74E1FD,49F9D38D43649083,547C278C387A94F9,000045FD6E139D17,A20FF2A271DDF05D,4106471CB624EF3D,0C88F07641EB989C,8AD5E909DF675D40,38A13185C23EABF1,6B9E60B7BFFEA72F,E44AA9BBBDC04E63,06090ABDD9A4D4AA,9F2D602B67AFBC1E,321BDF38B4A18DD0,AFC807BC8A8A3131,000005E9B23B3D56,45E4D0354A3A4DE4,675FE2858C9A2278,EB80E9F385B546CA,6C5F9CAD6A818AB5,8E663808885017D3,6832480B9437D9DF,5BEB4E0E33AA93E3,60941CACD7D34372,D3A1DD177344F104,7BB9C2E8A010ADF4,1AA27735D72E2B3E,00004B96B317ABF8,38DE578B402B0F94,2FCD42871256E2CF,AF5E0188E7AD3338,2475EE5139E6B657,4AAA83D15219CFCE,5E5BE23C2B8B5A8F,25BEF713B0C8813F,ED6D180DEAE793C2,618A71D834E4A7E6,EAC858F4A1897A13,7F8834ECA87EF214,00005BE7BA1B3E4A,322661A61406ACC5,CCD1E2DD7CEA38D3,FB3505BCC048AA4C,683AA44871C7FA3A,97CCEEF551BFD7E8,050255891A6E1652,4E622CA9DD9D3FDD,913B3839A093FDCF,7ACB08D173DFF9CE,1843AD17A9D9F7E9,C6E73696136A9DAD,00006D64649A7E01,FD629520B496B181,E071498CE06DC440,A16D702B04603C22,420FE52C732693D6,3409101CF068E769,911B8E70529B5330,E06769D26AA04624,BB9BA53C555CE5E9,FE8AC9F2D48CFDD4,22B8CE9D616030AA,544E6AA208C7CA16,0000245CA6E99F29,BDBBCFA36F02A800,53209DB988B36F19,BF123299DD8D4FA3,2009B77D5319B359,5D7EEC7DF2EBD904,3B60F4770644F653,FFD2FED12A3B88EF,F0E52AFBA84BD65E,82C0DA35487770CD,B59588E9CA1B1D5E,02FDF443AE2420F4,00002F7A121B1DEA,8A1A79ED56C72B22,FC3F31372CB87B3D,38425B70A650BCF3,2BE7AB2CF8B44228,986D3816069E360C,A9E602B43C19893F,C863A7142EF65380,B07CDCAFCDFACDE4,FE6D679925A6AC27,C5FBB7F8D769D8E0,98AC83CC2075ECCD,000066304AEEDF11,B387843F2167BA58,208E66A695FD9E05,1B5A3EB0BB4418FE,7E1ED9CAA0FA6560,C849E2B78725ED4F,DF321DA62E51B3DB,F4F2224DCB39F38A,2168CB6CA0A093BC,A22AB97956F1B67F,CE1A9CF747C027EA,5A23FD36E11201EC,00002051C8E6D076,C1DEADF2AC826461,4A5F3B8C434DF319,9C4E9ED04FED7878,D0BBE8084EEADF6D,8C40373035465300,EC2BBBD43EF0A3EF,7472E9780872BF54,2F82CD84194334FB,BC22B27F087DD039,B973B93495C27121,305E2F435000DD05,000060FB0D6249E0,283B740C41BEC512,0CE808DDA83AE0BC,473D9AB249214DB3,D87D33C5C8C3A38F,43DA83510A0BD12D,1680CABD44ACF41A,46926F0A3AC5BE2B,B2AC61B7DD1CE74F,FC8D62B870546B9A,8B547425D3B66F2B,6CC6E7D28A734977,000065120D1B2D59,6E50BE85E8FC8FA6,CC89B7B9C9740A2D,B8219905855C3ACC,22751D55E41041CA,15698EADED3998D7,7EC6C0D73C2C3F3E,15B6323DC50F14D2,3C3D372C5E556C3A,9037ABF18775F5EC,3F05482B786E62BD,A1429FE8A3A4AFF9,0000245F694D58AF,C22E345B7EAAE790,DF922071988592C6,4428190E98362571,DE8BAF2176BEE188,AB1C318C3E5F8699,6D8526833E90432E,589312813D04509B,7296D435742BA000,A1BAD32B04A6BE0B,39AEB473AE4DA4A3,43FE024C5B98D025,000039D925C5ED9E,950C525DEDD1AC2F,7F0972AA3A775F33,EC1534BDA03C4F22,72F82A23CC48AE67,8401711BC9221F3A,87334855232E0C4C,467898094EED7C94,8FC344BD79CD271B,12337A6B2D89AAE5,A04F69D0EA53D62A,469EF0C76643219B,00003FA32DD7D23B,D5DF93F96958B77D,258F40A977504973,4AB84F9403625B3D,69FBDCF7F5706323,7929B9946817ADCA,438759E15458C56B,F1A15B2672D85752,23D784B470869915,7FE2D86B7E8DEDB2,058380B0F7D0D1F8,5BD268B43D9F58E5,00002D36B1A95174,CA06322A128545FD,2DB9FA0056DA95E7,FCE1204FFE048B39,AF13C1B7D2F66654,EACCDA02C3119143,6D20A2CBDA2F306A,FE84874A954D5D27,D8768885C51E0FB7,E7522765328EC078,56493A41E38A0F5F,4A83ECA8A98A0054,0000592A4B001E25,CE53FF24396A65A8,00FA17B61A81A27D,579F0420FF2C3260,4F7F44AED6FAF06E,59FBF0E1418F6CF0,6A575B6DAB711DFA,6702FF033F752284,4E2838EADDC518D8,9944E3F2C72E8D33,9E7EE369BE9F494C,3576B2AA96267E21,00004EDE95AC15EC,19B8AE66D873E12D,C08D58FC550F9656,DF43456A8A919414,D9B5D1E2550B5484,0D4D96193C25E810,73A5F57CE5C2C48A,F68F4B3B46B32196,9E3B0CA3FB1BFFB5,8B09813229D78E23,1C87A7EB8802509A,47E38B541550CFA9,00000850E207FF88,B4065CD6A0506832,53943A83A82BEF8D,B277DF587F59ADEA,842A452ACE2BF598,5ACF276E96E652B4,92E4CB6653D76FD8,AF882D43667A8C44,48F00E54D3BEFAE6,44C9C325210C65E9,C5852E12A5A63D4C,F8F8CED1394169EE,000048039616D075,D338D145B4ABF8B2,594A63ACA5783C9E,BBDB304F0DC78A58,1B9AA5825AC8BF87,A9CDE66DBC4B5252,5A3CE015244A1597,BDB74954AB0511C0,52B597309A8B4AD6,9E1E9FE68A977E68,1CCB65253FE09BEE,8B6BBD0240717496,000065BD4A08599A,B477E72BEBD2070A,3E07AB9EDF338EA9,C29385A93339BA9D,A8C016C756ACF22B,8577FB88997E71BE,7E45D7A41F0269B2,9BD7E807C4BE772F,ABFBD4868A02E375,5331ED44B98F4AEA,AC6E982522C4D7EA,5075DBE3D418B19C,0000216EFFD4877E,D7A7B29CDE6C1B4D,44D45383D11D04CD,73B9FFBE7FBA00AF,1B499CE98D68F3D6,A4AAB78E65B4A575,D5E94285F413EEDB,F5C50CD01229CF81,A968F49405110D28,02BB198B6786220B,D5E0F38FF7D5DA4D,0260F098081C288F,000056418E21CBC8,EB3E684CF975CAAA,21B079E5BE7112B7,FCC8283A112615D3,1380649709696D06,E6C3E8341A53DA1D,439E4DF688888A19,7D5670FD93EA4019,AC742A609F776914,9D59C9F71F5F9C79,E5ED337ADAFA77D7,1D0A1B048E2CA3A4,00006E1F17A235E8,38F0DDB523DFE08D,D333C6B8239D9E6C,581F83084C13CE35,62395A89E962A97A,3066FD851E356FA4,8909A3BF9C8C5C1C,8473D93EED2DF7A7,9BFE29A1334C84F6,0BC27750BF030EC1,2484E642A95774B1,C1E66EE2CC758429,00006AEC5679A40E,FBC78AA130486354,479148B802944B90,29B00148BC4BE3A1,FD8C761B5932CF9D,273D5FB25AB4937F,3AF45F36322642A4,0482A2C1F3ACEB6C,7283DEA642327A02,2980FE62089BA3F2,EF8DA20998ED9F46,78AE3777A76E1E4E,00000EAFF2D429F2,C3E99BED21561AC8,A557561BF7AB6AFE,7400566323FBA1AC,35BC10946B91C01A,17789DDEFAB81C87,11111EDBEBAD26F5,881164D16AF05D3A,B480019E7E4D8C41,F914DE033BC81F1D,705C3A16107F743D,6CD95A1D8C1A29CE,000042015600F54A,67B56CE37DAF608B,B1772D855DF3C54E,FBB84F965F295A24,5D587FFCDC4DA203,1861EF8D505367A3,BCC2B870C9D81550,F4B7CD2647FE7B15,BA700F8C74414254,DE7250C3A33796CE,05CDF6782CE3CD27,71AF38CB26FAC7D0,0000320AF48CA5A2,3D08C7FF0FF6EC1B,F2F67F05CDA5B931,E30EDCCCA6AE235E,A21FD84245EFD1BE,83826A8B41B00FD3,1A689A82B1D3F9DA,EADCACEC7D1E8A23,C0D13DA6ADE2D884,ACBFF74FD39EA1C1,6630D535DFD4961C,A6139CFED8E2A949,000033E747D29939,22219CF04EF38E93,BD3A6352F78D2BCD,663C1EDCFA7DF3AD,D53136C2A02E9FA7,5D5BDB199CEA60C7,D151871F820A14FB,417C7B07B1734D1C,D5C73CAB9E681641,249FC4D69C4B2B04,AEBC2D44173085DA,93D40824F9C91A6B,00002D6E0DE784B1,F04754F8D5B8E3F3,EFA06B020368B676,DD5A8A13763C6A07,CE3E43AFFCDA6E76,7A3F413A00399D40,53EA8984F916DEC7,F123130EB5E2B902,038F3183393E9D69,D4CAD2AA84518C85,3681809D81E274AC,973A197226D5B781,000037B8F7FACC74,7685CC332000A669,30CA695945A5C96C,224C1953C2FCD221,6ED5D111545D31CD,74EA781B28D4D904,73E87FD88E421B39,0B83EF528487510C,0F846AE83F311FFE,1D1028CDBECF184C,39F8849FC6314390,9A267F9ABFC5D013,00000A7BA492A3B0,837E77D76E531706,8C2ED743A83FC1B0,7A9E69FBC921FA2C,96D319B983DC7EF7,FC57A4C76FB664DB,4BDBF14AC8AE5167,706FA43B5581D462,4FF0F285F96A0F5C,7203E554CF374EF6,807478FB393922D3,C8E21711D1F8C485,0000111EC94536DD,198515375D02DEE8,3EA533A10A16A5A4,11A07F466AF15916,E452BC8C63C5EBAE,2F1C1CC07C3BDEC1,26CD052C098560E9,CDE0C8EBE58F74E7,A86556CFDCC5349B,5321F5AD7C341A5B,B230D9EE3A8FD567,66619761B1092806,000060603DF4FB8C,B669ED5C9F4AE4B3,0F703731A304B263,78F708F74842D710,CA638FDD2A600758,F0A66A4CCB78789E,2BB82393CF775168,36AD1DA2A3C9961C,7F4F26C55D0B2D62,380C50ECAF99FA75,37D609C398646E6B,82B2C74DEDA13D52,000012186A046862,493611B8DDDF7C92,583F8BF326231B74,5BC5989FD475D162,27851165BC93331A,D77F17EA4A4FFA8C,F16E2A2FF39B7520,D45BD9B726A68046,006FD436B00875B9,4837B168972B6CE4,E2B97307D75D330E,61FA3AC811C6CDAE,0000438C04163299,F5E61D9F129128F8,7DB3C55972FC6076,B97E05C006ADAC7C,62DD0FAAD4834282,95F151ADE5E61FFB,32ECC32C710B8D03,419741C8175DCD75,E0D9A19AC6643C3A,0F8ACDCD0F24BD21,78208008C87930CF,E84B1745CCE75468,00005642DDDA3B7E,ECC391C25CFCBBE9,27191A781A37A4C7,9A90867932E11B11,9135C85267C4A1BA,B5D3B4D9A4D2B0FB,18B7764F2DAB3EBA,B3578375E663AFAF,B7274B9D56A813CC,01E487CD25CFEB2E,AF0945C6A74A633F,00DEA4CD6B34A074,0000557A9099DAF3,D4D48AA928A778BA,3518FE569DC80284,71FF7530E9D1A1B2,CD440216F69FB0FE,36654E8544BF13A7,DBB4E787A0CDCB31,3F24E06C46163F3D,55571F90BCF13773,2242A46B2230ACCB,5426A8CAE1416EFD,46B83BA37343AF93,0000190C93E457D7,C624F25334C3E83E,E073D40B5A963B3D,DF186C30832FF279,84A4AF4E2D27306E,C6C49A3066DCB3D5,EA6BC7710CB07015,ABFA6E9A306DBCF6,81F45F9789DC506D,97FAAC97C72B18E7,9761BF18D8BF6D07,03DDF3092BFBCE91,00003AC225304A50,5C7DAF1BE2A36B38,AA3E38AE4473C60D,01A2F5D8274C7696,F8C7934D743E5D57,1EA055B4ABA44A0E,0395828EFA3B9CFC,F191959883B7B97D,0C2C33FE0932BCA1,43AAA1971B87A766,67A7DFE70944C34F,618626D43A23ACC5,00002BF21177EA90,14B9DB0F0DB21CA0,A19E784F5BE9FBB2,7411BFB35B062C51,B4F58ACBBBFDAE98,1C3A2AF4437B6242,39FD9E65AD437D2D,EBBB0CEE716246C1,D968FE15CEAB4F2B,469F362EDA51EE2C,FAC29133DE4F923B,0ADA1E753CC80B33,0000374040474DCB,21F778D241B58D55,DB1065C78258EC68,6660085833CA313A,A8EF394393DD2924,88B126BC3AD17B6C,2E83B018FF56213B,A814C90977BB2C33,DD0AD4E81FB7D8FA,9632CB16F950FDC9,FB987096248FB697,52010CE82094120F,00002A9C521DA6B4,6A3C8D5169D6C0A7,BC0D5DC4794A665F,AC7749C044FC3A3C,AE3D0A75CF985F73,A9E4D2B6C93AD7C8,6DA272454F048459,CA64120AE76374B5,28088546FC609996,5F64F3148C685F2C,16FCDB15C0787FB4,A2EEFB4C3B7914B9,00005D5BAB1EB411,74E6A90124A96E8E,434354DCABE87255,41E68D0F10CDB257,CC2DAB7A3ED636BB,003F5BD77EEB5437,B9AFF3A2112A264B,EFC4B1D33C86F485,1AAE2774CF3CFFE9,C18CF4AB8940054E,DD34210931344FDD,2B50C672C8979AC6,0000400CE6DB74C4,577409B083BA6252,CE289893F4252C7B,3F9EB721B7D80030,EDE07AE1EA39DDD2,03DB6CFE6621F00B,94484DF6F39B17D7,12C9932F5D5A4F81,814DBD4CCCB81C45,CF8AD9431C4228D5,2DFCE70B6CB8DFD0,D327516EFDD17F1F,00005DADFBDFA56B,7AC776C90DE7FDE5,2D9B16AFFCF15B83,F476219A7AF221EA,DD911EE4F79351FE,6EE7EC8ABCB429E2,311B1E61C25CF35E,6A8A3824C0DB3B26,B52721B5E7A089E5,4D25AC359BA57D89,2286BA72FA96244D,840A4249714BBB92,000055C315481898,1A19AB4FDC2D3FD0,984AFC8673C39047,9D6AF6B07ED118BB,6DFF7E39F5F8DAFD,201F4BAA752BE51B,9596852522CB99F8,55B00135197BAF08,C35B2326B984CCBD,FAF25569FDAB3E81,CF9677D732836451,0252DF1B9F1A6E64,00002BBA7D4FCB35,17349D1472AF643E,C68D2119A2A7EF34,4CD50133285ADC48,394F5723C8C367ED,37A936E9286FC7C6,D957F2FF02E761AB,B7F18AD4902EB59A,5840E137A1159E95,AB262BD632D0AF2E,E0526A7E00F6FB67,BF28E41351C56856,000006CE0FD058EF,0E02F941422932FD,679E42C45DD59512,C827DEB8037810E9,3883CEDD4F42D7EB,075074F8F124B47A,F15238407F4F4F9E,1AE424D96D67DB51,C62B697B08CBCB3F,9E2966B16A2C7998,A23D56B0253F0B40,8744309FB0714AE6,000054445C24F2DB,02ED579975F8C884,CDDFEEB7E5F57864,033EA7B3562C6F61,5192692229580D2C,A38F8015C46A8902,05DCE161FDCC3F11,A502E207B7EDDF50,9DE4C076A28BF0D3,C058B4F82F1C13FC,7CBC14BECF08690D,813E1D51BCD7C2EC,0000257A81E9ACB5,3FB7B3F303AE0EE1,17719BC15267966E,F263DF16202F03A4,C0A17CDD43F8DE7F,0273199E2828658B,0F2AF5981707FCCE,5CEFE4A10FD579F1,CFA14456A856E0F8,B639847A3D2708CD,1099A662BF09E608,29ACB424B6D7E361,00001F6F4A5EF1B9,E8D268BB2195BC80,A009F601B2C6A411,5694AC30749E01F3,D97629B0BDFEF522,0F7D792189A94E6B,5369AB0985677384,48004FE7E0DDCF35,9A904E5C4862D63C,1B2A96E73916A995,21DFBDA04236D52E,6E26132F917DFBF5,00004314AC621E1C,C5F14632BCA4BFC1,B29FA4D67D2A0FE7,E4539A0FFA316CDD,C25766F3F5BB4693,BA776282AD76CBBD,5F41CBE7766DE2D0,78B66CADD14449AD,BEB509636623C9F0,3F5EED114EF5C6CA,7BD2C41205CAC74D,DFF7307D9AE86966,00001D34ED0B122D,19029E91112E8CC1,B5AB0D810B8B2A5E,4D59D7150E91A21D,7F69C6A57AEDA63A,041A5E32986ECD23,E0EA4ABBAB3A8009,A2FC60FEE2A55495,7D78A4B039C53B61,577597D54F02F958,6261B143F435E72F,2563B7AEC77193A5,000017FC3F8E76A7,9029D384A9A487F1,EF10B27F93916F91,19463439B0C90450,ABB948CF0D639463,2FA7B73683B27F43,7B02F42B7537591A,AF04EA080983B4AC,7EEE736B63D331DD,F427C319F0B4CF82,7D8DE953303F8F89,20342A403C191E78,0000233058B03CAC,52927F209D97C74E,74B76C04B2CCD9D2,CABB6709B444B83F,0FE26C2D7E2BD1B4,30B2701930615D7E,C759FB961CE3EFCD,00804D89666D98B6,5A57AAE0EA82E740,D4D7BBB21EFFDFE0,7F447078FD8DE31A,EF0AC6AB99315615,000058DCBD8D6808,BCE4B13EC939AC62,A3B81010F3308BDC,A30A15B29BE6EB59,64D5557367DFEC66,B21E0E3F0B3DD836,2CC1D0DEA6728EF8,D339D37AFB69ABDB,82797D1BAD68E466,27808284563D6ACC,9B8611A28EB29351,FCC2C6FF8D313728,0000293DB253A36C,C4166BF17F9FEFF4,DD1CE9D423B6BD3D,3A5B32C1A1082981,1D72F901DA1517CD,A73E0517B0B04BBC,7FBC20C00DF635F2,E7D812C7DBDFBFAF,7CE9CD42BC1EE4DC,BFEACE3BF7566C80,9913A60F71201582,94A164619D5148E8,00001C30BAB4834D,B7E7D17275511CAB,A990018E2A5FFE41,AAA866911154D663,608C409E2C1FEA4B,EDDD4FE2EF3ED21B,AF182FDB350F6E82,A2982DFBE55D1B10,EEC148DC4AFBDFB1,5F50F0BF7E6E1731,17C640164D064E1B,4146B32E8831F900,00006267F3D42FA7,8BB738776EE64B14,0BD4BBF5A823C746,4A53EECA9269E1C9,955E2BEC69CEA440,8FBAC91530FF223E,8143791C3E841D45,D56185F83118DFC6,CFD5AEA1699B5496,D854BC858CDD9186,3C6AD88DD1872FD3,F434B1687A14A38C,00006B3E868F636F,DB50EEDCD842BA07,054BF4BCF45599E4,8B3DA0D8001AADC5,AF4FCB4D034159E2,D22E2E31D33420E4,0503A97210E33FDB,B1802B5B40C35AED,AD9F4474221234C0,9F30C6AB94F37CCE,B4506CA3EFF45A65,70E0FEE54131924B,00003E3487DEC761,B47B9A63861A8BB8,DF86B6DBCEA3C04D,91C71FBBC848D4FA,EE97AF027EC79DED,F1DF7659F141FA32,BBEC72FF748A7669,092A09D011EEFBE2,034AF5F65DEB8269,CDD7A871C213D100,E55B159614544943,454355F48737414B,0000554EBF914DC1,F12BDE22AF0B5976,E339D0A0F485E7F5,2AFC310CA38CD0CD,F91AA210F74F3DE5,E1E3F33FFF32311E,42EE7D59F5681FBB,83C91431CB6F9DFD,73A6B3FA8F69D221,7306A3DE5957FCB5,35A06F95EE4076BD,17B6DED0BB62D139,000069824F464241,6BDF52003DD9B06A,B4BDCD071C31B2B2,6729F6ECEC168360,CD00EC1A628726BE,AFC6978477E0648C,18A31A0CA015D03F,2847574D058E2BB2,6DFD8BE3E68B0BFA,DC31E859AFE1DD14,48923402437F3E64,AB1B31620AA732B1,000024F4B484A3B5,6889908EBA90DB5A,0A5F9ED77DE875AB,421CE8134A9893AB,574E90E86B1001C6,31B9C1DDD84EE60F,4B9BD2C28C040869,C3FEE3CD0F9B7047,07716A0EB0DE8E3F,C62E0FAA311C9255,811098928D5D185D,DA675712609A5756,000031C2996EBFF7,D376DF3BDA0B6765,1DBE56F186FF85C0,9F44300DF36A41B3,50018D0919CAD0BB,2D98B984D7240ABA,729A26792BB71619,B90C872A8F8474BE,EC861CD039E9CADE,CCD86531C8B97535,4C0ECD750E48558C,FAE7BB83863A072B,0000238D681F8DA9,15976F7EA2B2954E,DDB43DD3206D9547,8301C3D13207C4AC,3A29276B5183C838,FE1CDA03A900A023,CDCDBD56215CA556,204588BAD95F20AD,4A70CE812054EDFF,3B89A06E05C0B12F,92581445C399D740,C420C8226F69CEEB,00002423959C8A17,7F8736D2AB731883,2E82C1E4FB936A3A,269059EEA981B1EF,D9322F29C0377285,9BA8299B546F38FD,630AD3B1E9159561,DFCFBFED0F622F03,8729FB490C0E62DC,2F44E99B74E64BF1,CA34C42A7307C783,B5500308FA253A48,00003BD40B75CC38,2F6390FCE91AAE3E,E492D59369442ED5,D5173302E79E00FD,473744BE28135FD3,358BFEFBB686A91F,45C560D5B1E76D66,113F5FB4903AF0C2,672EB6750B4482E2,773D475D87BDB9CD,FEDDFFF99FB082E8,E8EEFA2655E2ACBC,00000B02220A1A51,4F75CC437FEBC4B4,53AD015EB75DB671,C2AE147C9F51B911,CD60D4E5DEC812AF,2D130639209B38F4,59E4CAD9F4776026,49C46B5CB1763370,1B6C8317261343EF,C91DF1C27232D387,DB9279C2E6B3251C,3638918C6540F211,0000583DAB54F4FF,7362594B0A90C8F0,0AB40ECBE9185BC6,92FF74AFE8564FCF,73A7072190725AF0,60D27BE63AFB799F,7F6E13926FBE4BCC,D3359A304E2F81C9,2E33B8AF475E0701,DD58327639927A52,A4AB83FBC180A887,3D02D44C6FFF5909,00004CFB58C78293,F3DDE40D2D9A51C6,81433B7E6EA77CA7,F7F73714BE20F5DB,B9B40E13AF896755,CEA7F5B8C46C3F1E,8270A05501825BCA,CE36DF678322BF90,2BC18297AA4DECAB,E6126041C01CBCD3,D7D9E153A207F3A7,E69FFEBA34C3A929,0000467BF39A72A5,03AFBC7F53586482,91302D23F3BEA740,A11B8D1D284D16B0,63BBAFAAF4CAE04F,1AEC1BA88E8B5231,E9AFAE27A9B3E79C,5B94CA41E6E050E6,A6A109AE92EFCA13,C7D2879FCB150ECB,EE1C891DCF63C1ED,5FB35D8800F63B8F,000042894CE2A792,B2BCAC141E9492FF,C0D5E82634FAFC05,4E464731010A17F3,D8B57A162B8680A2,A8E7F63D0C87B246,963D65A0E90E5808,D625C25306381CDC,C6313601038E35B7,025BC928C9C11E04,9EFE9ED4FC60D99C,9CBD61ACCAA05FD8,000019203046121F,0B28431312913A14,71785F199AD8D733,D91B427F545E6ACD,9B08E4BFD645D4D1,81C46A583186FF13,29B560DC2622E9AB,8FEEB70009DA995D,4BBEF1D89C59944B,0C550935C1F48703,3BF5F398E3A29AA1,5B57D659093D965A,000019D369691D14,CA97077C206F3723,CBD1870ADD2E5FB1,D5C4AF77EE2C44AD,C14155CB25FFB1CA,8D18FB34DCF4B727,A904F3BC6716FC81,876D30777B9D3AD1,1648179041499C40,2B4677D84BC74A96,425B6C88B45A0DA9,5C8B9278E662A17C,00005D2561E43BCF,B44369C0A0B89D57,17421A88FF463AE9,B5E05DAC6FECE9EA,75736E9FB46E9976,44D5FBDE85EBDB7F,6183FDDDB9D9BCF5,D4E2F04B5278961A,9B6EDFF75259CC3A,D9ACB17F9056A711,42C199A8061D89FE,8AC4A242B8999BF7,0000393F1DF38B09,A2F6E6A2F43ED6F9,ED156EFAABF97604,FD34CF322BF3ECEA,3D59F88A6762597C,3761B4941E1D982F,104C3F47D173C314,9B38D01DA9EB1E73,D5AE6D3F4DE89A8C,270038A93A330B8D,00C7468DBB1F0DEE,F959D821B1FD9147,00002C3E1F4E8EE3,9676BF421535535A,C3BD7AB4F0DACD94,1D8BD4A8D90BDD20,5AC2B76924F28EB1,52677D8E7572AA31,3B4B28B1A24E6E60,97A703F09E1CEC2D,0A18B41D3B5CDC95,604016B8A50177D9,A2F8CE4450FF732A,AFE96D2F9B7000F3,00004968CA6AC8C0,9916DDDD9586B8C5,BCB5D8A1D1C0728E,4DCB000425FC75E2,FA0C3BF57EC19FF2,A28E6937C56C5620,360748B6219212ED,43BF361BA60D0D62,6380F065D5BEA452,F44906B430F67FD6,ABDC244BC778C235,A77BCC94DB36AA5E,00002D54F52EFDB6,6DAF95FE79981425,9EC740A53C875DBD,38EAB1A75F2B440C,32BD2C31EDDFEB57,36CA0FCA6E52A02A,978405B4AF99F03E,C6BECA3A55A0A0C7,7703920C5C53479B,1E99F26AA0F64370,6DAEFC519E84E5CB,A19553F97708D994,00003C5C729935F4,349DFC74117AFD0A,DB3032F0F0EE7D95,F382D562CE91C799,BB5ED4544E97C410,995396A3052E1EC0,C678F6B13F333019,D71B326555C3858F,9C9E3C1A48D0E13E,5692269CEA808133,C6A8CE35E3400546,1CD29EE9E7379D4C,00003C239F3C7BDB,990FC12250B96277,655611DF69C4FC51,84B952F73B73024A,25E7C40FC982D624,66F1E7C2B62ED2C1,9256C8F88E474DD1,1E5B249B2E0B9A6C,372D43694A9BAB24,4A71C2FB86925367,90B593F5CB4006AE,807B5CC522B52443,000064D139EBA174,4F72BB57C8E5B2D3,4EE5FF60D3448F17,714EDA36118F7685,D54C479D974F26A0,C5B83DBCB9EE2DA2,92271194DD39ED89,BFB5B7978CEED372,CFDAA66A6546F5D1,3C00556DABBE61C8,74865AAD1EC74551,62C377C7D0F4B965,00006D0A568950A7,BBA75EF44C1EE015,EE408CDBC5DB54ED,DA26BA2BF747293A,0459BCEFC83682C5,078B188DE890CA50,514D3FB0F012235C,A462330EC3C3521C,A9FEFB2CAC3B4D26,F2A8B908D60CE4FF,BCEA2E1AC7673BAC,58A59ACCD6C6BBB1,000067F7E3F1ADC4,243406934867A15B,F7467E6AF60A01EF,DAE983BABB9D8442,2D28DEE4398BC88C,FE5FD0A76769567D,09BB8F31B2426B38,84F88D23E9220FD2,DC19470E173A19B3,803A2CA7D75C902B,AFA8EBF829817FEC,F540E3CBA6C6A0D5,00001A87C69DA5E8,B88E2ED8C1C056DB,B209AAC854B0021F,CECEE17039D7DADF,6EE4DDBB8100BFE5,402856A6810934F3,B9E791D7F6FAA09B,A1F24902B02146CE,B04C95761D791461,14926E0C8DB47A73,5A4F297CC620DF5E,7B83CA853827F19A,000064DE457CDA39,474A574D304E37B3,E87BE725F6BE3B7F,F4099398805563D3,16DC5572F9A0563B,BE498AE49B5F297C,D00049601760B9E8,23C34B60DCEECB1A,9DAC5DBC33D15C58,A2B1D2521E7C610D,ADF6A41EBDB557F0,DA25CE283BF18D1C,000009A980D08CCD,F9AE1284D2C46855,C0386AA8C8DF04E7,B801F0EA278A67CC,AFB8C8142DB791C7,BE60FBD850BBAE90,2690B8E8DD004BE1,49546DF5463E0EEF,716A3470394D0FED,A5C03C6397605DFB,8FEEED09BD941A25,883FE4A193DB8CE9,000024D37BFCB1EF,1FDABDD7F8A61082,0CBA6404F8835E7D,5A77642CC09E305B,34F834D0EDD37732,9946A440FF23AA73,964681B78451B6B6,F3B83A5F51CC9F26,ECD0EB78803C1F78,54B630CC08000D28,039C4310C85FE203,1CBF09F1E286EB08,000047AC1BEC0185,4DF3CEEC878A5F13,7997DAEFA8996DF4,A9AE6E4A12EDA383,DF6A544820C226F4,7DFEC6213424DC86,E48C004123435D6A,52A12B437856D8F8,A00866B7614929AB,1C09F9EEB7415934,1E0F78154C21373D,3FD4C79CB11DEE01,00001177A0994BEC,E822C3E7C22875B1,98F78B8EAB40EC46,4DA1BBFE27F19CB1,14842BBD8DC05742,0F991FA8B1F05FD0,4A659AE40210BE5F,B0FA39F4EBD6F64C,69BFF4DA31BD0204,210B864E74A770AC,B2C44FDBD592BA2B,469B7868704624DB,000030A1B4E09018,ED33FCACECBA55B5,C1B5EB36F9446D4D,C2DBE9F74C8C672B,3C4F71DD7744722D,0340F4B95AA766D3,C64C077432BB2E17,B6FFEA9C69D2FBF8,06B03B22ABD6AEB6,42F097C42A7A9EF3,85176E3D77DB0C7A,D526E7003F407446,000024508EC6B93E,669AC918EFE0BFBA,0B8774635586DA62,8F5843E5BCA41368,A239EE4C8039E914,8EEB21EA18CFD882,08E66CD17FDCCA32,D448CEE239B55602,665DB910DED0F409,8500D86BF43C5536,0B07FB6C200474EB,75A18C8E9ABFAA7E,0000487E3405CE1E,1EDDAE2ECC676B74,A9E90FAA06C9C00E,F74975E54A8422E0,1C5A6CEC1956208F,52F958CE81C35E56,A08A771DCE1AE452,32E06DB150876537,AF9B4FF1F02A2A9E,1BCBC6E6660DE7FE,EFC0E168CDEA91EC,62B4F0839414F48F,00001EEA89B2AD99,578E554D2D91ABAF,3903079E4ACDCA78,70550F09F1F2B726,50DF0FCE726B9D41,EE9C420A8E9297E5,A85FBB28F9C0A7BC,A71C5E325E547BC9,7FCEB5B5F85DF441,601FE429229D90DC,22E7FE275CD7518E,7C7108F2953C7284,00002966BE38CCCD,641D7B5E5C25DC10,4EF1AC640CF86210,F69786EF34242F2B,18B7AEA2F13E995B,13692BEDD310962B,82E8A95FB5835E6B,C6055631695737CC,39E24033613A04B9,61EE64521ADE8D4A,669887F970007577,603401E9D12BC119,00005EFC0C039B7B,2D440A7AB02BD99B,D2995FBD5DFFCC53,353AF93F7E7CC108,17190F1F47A0A61E,DA896031AB281EDE,991A22E54BAA2A02,24D41AD6BEE9270A,AB8F16972E86EE7E,6AA9C1F12CA4CEAF,C9FA1B1F558FAE83,4BDDA9840C10FEC0,00003C1284D34842,497CDC5E804EFB0C,F2CACDAA528048BA,A4BC994ED2448715,21BF53BF8E65F70E,CF2F200B233452D6,A0151279F74CA869,0082BCA4C44B171F,4F8E46F4AA7F51B2,D0FE43A571319899,A2C8A865F71D3E86,4B8BC5FA7735E076,00001D959801561E,591DB20E4DF65182,7D41D4A00C1B9B5C,1A00541F274AD616,7A7035CABB6FD73A,03AA677E39EFF77B,6CCA83E8FD9C7BCC,B53241AE53766276,8E3E63D9F8ABA54C,177E56B09D9B132E,9BC121BB13AB0BB7,2DA0EC4AE5A3E2E0,0000601961A1EDCF,B56CE7D1BC20C0A2,EB544F46209420A2,C4F38EAF8E46CFE1,82F96E444F057BEC,67C6BC9C426CE827,BCA7568C13F14024,AEA4DD6870EB708C,E3483862D0D39EF5,DA14FD3853B4926D,0B4F7296B7D1CECA,9C2D80028BFF4631,00001ACA87956769,6890503ABB39884D,B61CF8A6FBA03F36,2D64845F23308537,5C9889FF821A5768,D7354D020B55E98E,3FA393388B9C1488,FA4DE5AC5F8AE0E0,3017DDAE121F5C51,6577004747748E83,D3AB123331C7DB85,24414E946968B7AC,00006A31FCBEC88C,2073DA773AF7155B,06720204834F38C8,8011B50C87E4F4FB,457A352720844F30,84C9C772CCE753BE,832AE0009B57A6E6,E0029DCEFCAD1EFC,24021ECC71033F08,EE740D2E9A90CC7C,B46FCFB98069E38E,E278FD75EFEE0D1A,0000024B4D99B8DA,25637BA0312CABA7,CCD45F01CDFB5433,CE3FD4051299D01E,35897AA8E4238C6F,782B5A751E0C123D,6462EA4EF638E32A,075F00AB3153B8E6,DD18A0FE0260F1F0,C29C492C292ECA35,406D6646D5B60E08,C213C6306F4FE37D,000028DECC9BAF25,B4A39300AEC96390,F720D271C1D06D89,7B1A0B11087967BB,E33E9CF1E247F29C,ABBF137AC649D19E,77D77F4F277ADA97,778B04CC02038B4B,E0844CEEB9895365,695B66FB4796DB74,7DFC4F25CF5396A3,A940729A20A90780,000068BA314138D8,23BB737483BA851A,A8927D498DEEC186,E42F52D7DBD3ABE1,B142777D0C9BBC65,BCB6084895D6D40B,33F0BA6F455C0D87,B3E8FED9B7376193,86A161A86D807745,8F97114181717571,0ADB0DC3CA70017C,44DB5D688E6A4969,00004FD6E159E98D,311E9A4088295F57,4A7D204BC8B58531,18C76BDD407ECBDC,9BB5DAE68FA93B15,43A9D43343028DEB,1254E2F78913142E,C5624CF1EB324B67,26392BB7658E7E79,2A85260D4A64DE54,8AA19AD72441FCB2,94CDE4D6C6D9D3DA,000047E02CC29252,635BD890A8874CE8,4E2C3E97094BE972,506A09430B132D12,F08C42D463693D8C,618233CCE76AA9A6,49F3EE768C8491BD,F0527248F5D81523,6293A532A935164C,D020B941DDB68DA7,8B42418C9B4B5770,4479AEF12A35B7C9,00006E797F9E29AA,37042D774CFF5458,44957124A56EDF7D,71B370F07F04EDCA,D54C10610BA33975,CA27E43BFB1EF6AE,62AD4EA6539B46E7,E5B4B7D395DB708E,BEBC9D2E7F4ADC15,62F2256BD7694C87,AB6698AFD90FB265,73AC4B7E0D4A9862,0000284B29B54ED4,F2BD5573E6425DE0,C95AA5AD6D54438B,D1B3214A6A53E21B,52911864684FBBCC,504795E06CF61869,BCEF968D8E54A660,8D7BF7DA4D49DDC5,2BF971CBAACD6231,24E0843C3EA26BF1,64BF7B2FE6B616A6,DCC751175EE7C249,0000140D613DD8BD,6642A8903F125963,59D4054795472D99,82A4F47A7EB88607,34D4809C7BD976F1,A158581C04254BA9,D132C6C6F9755B39,8626E051824D28A0,4B89EE9AA9B08DB8,459E17E292A3D4AB,BAB6C985A6DD12AA,85E25B69486C8BAC,0000245B5295F70D,C2F15172ABA77096,E6DD3F1155E0A4B2,F2910E6578E05062,177D97BA8B588C25,ED9AA9CA86311968,3943B319B2E489F9,8863999F772A531C,80AEE0BB8DEC6E49,808F000E87693CD8,F5423533623CCA62,B6AA768098C7F9B1,000064E7F206CE92,8AE1469C8C182C66,A69E6DD1C8E78E5C,021BB7FA5399366E,5A0853935EDDFB2F,16B75801F7BFC80F,951298256C8FBAE8,42F765ABCBEDBA98,C7A784D68F3DA7FB,70902C5C14122CD2,5A9D610571E10F15,7AA1491985C5E03D,00003C7766B328CD,7671D02F35B25860,383202A0FA9F881B,C5F4CA33E4293D9E,945B512053C060EE,46925564C6A5A7E8,3E0B2BAD65307258,71A198AF0C66A0C7,D24DF4202D383F2A,32260F7D7DCF6AF8,DB2794FA285CC090,B752691DFFD2DE9A,00003C4D9306E0FA,2BF891ECAE4D3DB4,F5A9A4F1D6072B38,C1EF964ED2199367,ECBEEFF07C9728D0,72829B07F1890B27,45D8CA15B0460115,C1EA53E7C604A526,2936D5526DAAC39D,F3E532DF1758454E,2EFEBE834D9B9FC7,638875D9320D96B4,0000487F64912E65,607E5B8FA7AD7F08,56067F0C8DFF5120,6B6CD8D4EE6706AC,D17710C857FA133B,E8F8A85BD0ADCE4A,7790DA45EE8A4732,78BD540E00A1210C,C809214549543164,C635C92BDAB89C05,35003139D90223F9,A570DE131B982DE6,000039BE8FC9FA32,58967AA1556DD281,A7BD214DE70DF741,52BFBC5820946902,CAB21FA0080831EE,5E679893B06B68A7,7A980942FBAA979D,32172E25916DBA58,7D2C6AC35CE85FE6,6C93C1BE69F8B0CA,AE7E4D91A270D361,6B18BAC95C14E5B8,0000523AC3CD97E9,E17C789BEF6C6FAD,1591CAD491B270E9,087BD68A8B1E76EB,66710939D0F574A4,23F10E9BAFAEAC83,9E8BA9B5E3A37772,E586F19CAF171C39,0A28C3F6DDD750EC,6177C52CD3A41519,DCA76BA273975DD2,CB5C1D9CF4349102,00006220D29000E2,66F94160875A9814,4A5DE3BB15A59355,25D6F935FC6564E3,E77C4271720F43A5,012927DABB067147,8F728AA146EB1A1C,7EE8AF52924C2073,AE1AA8EF5F917F76,92A1E1C818079EBA,6F943FDA716C3F53,06D9F7AF6F2C790F,00001EA20F1F634F,83E5D29B6AE2D891,60B9237D3348EDBC,1F4A9ED1DE34A9F6,E1EFBFE1C6403C72,AFC81A59537AD93A,97D5704DCA527C29,17AB98D2E1473975,4918BDE5BDC48868,A381E7FA3056FF6F,BB06402B5FEB95AE,503E6CF591AE3F1C,00000C283BC894C6,07830C4AAECDBF54,6F6A7126A6CC1D0C,956F87255C51F102,F7FD6B5803567C5A,394DF44984FE2277,144D6F915CFB7DBB,4BC3363BED73ADCB,65FDDEC5E4EA3891,77635AC543B7B301,BFBB4BEE1D09856D,D4B6FB702B7BA1A9,00002C7386B470D1,CF962266F9665F4F,16392AA404CD5A80,F9BDCF51B20550B0,A8710E642D11BA2A,BB910B0D6F5FCD91,ACB061A4702DDB04,30A27CB82FEC6330,7DA53A40683000DF,F5C7413AF011E831,50C7AF79F573CE54,CC97F782EE61B07B,00002F0A5FB60FDB,E864DC90A79FB9C6,DA4876B13CE9FA19,A8C170696D3D5EE1,808044F42F3D0B55,3909EC842626DE47,CDBAA4A6FB98E1EE,1EA279610DE72BB5,8D88D46E6F08C1D1,1BFCFE71C72FBE7C,0A80B62861DD14B3,AAC8F1C1D1A5C816,000017D3E19F11EC,3C707FADC3AB558D,1BF95918AA0A58A2,31D91168E36A6A20,324EA62B5832BB23,2113720CA0ED79B5,0282EB34EE490A38,0D74912F7076F800,33E763662068B236,28553726BCDA6F5D,EF9EAEC20CEA7017,D3B752AD8756C6F0,00003343D0EDF980,FD8E2EEFAECC901D,7116CD7D18FA5FF4,4EA99958BDFA4FD2,6F784DCC36F33751,62BA4F7538B9A66C,A20C7B75042CC161,91C6D3248C1C6279,1A684577106E242B,8E5A8B84FABA13BE,AF29EAA3CBF03642,6CFDEB7A75C9FBC6,00004A3207004971,428441B6B610E803,4935499C19A216D8,953171D2B4EAF7F7,54E4E92AF771F384,A33BFA6D9042A0D9,39D6076DD8440FF8,B9EDE5E5FC05FD39,91AF62339975767D,A6DF97B4E1B94464,C999C16E4AF82599,E75EB4B253BDE6DF,00001F337334A2D9,785B281052993F02,18B3E9FFFDCCBC83,4111661ECFFE7BA4,9CEC24A07B916EC6,6D7D413DA1C2E291,F17B1BFB8441E225,43F5F2929643C746,BC0C8FA4C56BC461,D3A426A9961F5588,4150D2D9A4841443,C3AA7BAEFDA24090,00006850569AC3C7,5674CF62F018C10E,FE7E62767D6415EF,E8B6A06F5D791F1C,64DDE0A3E496E1C7,FD8057C0D5D8BB63,8DED40F3ABE2B0C8,4D8E905406198432,8C6A9D2FD9AC6F7A,60CEE7BA1BA9EDDB,BA04E287963A8A3E,A2FA55734D7D35C1,0000680BB6A20E4A,9B36FA9396284210,29AD29E8CD39F3F5,BA324B16975494F8,E004E1CAAC88242F,1DC78EE8B0D97ABC,2DF0B29E53CDCB55,89A05063A8B1BCE8,D754B49E5CF8F2B3,00881B022C76985A,F7DF1FCD61EE93F0,FFEF07C8998CD8C4,00002E3EC05632B2,F5FE84E2ACDCD518,F3EB8E71F2710C5F,DA59E7C6BE4BC021,8E05E8513D34853A,E0E164C9C62451D4,E07B983E6072F926,42DD3D5C105D20E7,28AEF5498868BF5B,78069631248C0CFE,ACA5EEC64E5A9206,CCE166A6F3A0B6E5,00001BB28B3C4DDF,A2DAD1A20657A410,55C04D13EA5C3026,CFE7C08CEA72A7E0,4990B436E5265092,082EF20ADAAAF8EE,3C629DC739DA0A1A,B04A1AE9CE7B7368,5CAF7584EB0475AA,C0E178112EA8BFC2,AD1F4E54E07D30AD,56CE61BCCD4B5DD1,00001141439F711E,863D1F666BCBD925,5A57F9CB63292F33,E9100892965026F6,083DD066A4DA8073,E9A28581E96238EB,50C8B50325E6FB8A,17E6E4E67975A759,FAD455ED9BA03D21,7C5A0C6E3A6CE42C,DD830E4B8C206E99,AAE29F4AB4373A88,000059152F9248B4,5FD5BF4AE967694F,A4E9CCB399D9F40B,B918255EDAF1C1F2,8182074D9ACF4E7D,9EFB9435EAC87A43,570F15768BDDCDF6,1EE59F19E676B812,F24F055981712604,71580F03650DAC6D,40B6911BE6473F2F,6E2B40BDDE3195B2,000008987802E7D3,26B6C0FD1EA9DF88,FA54D1C17C7078FE,81EC1AC050617BC6,EFCBC3CB1F3FE8D2,FBAF0D0F6B0D0DC3,9E2666DF49CC7856,9E3EF5A1CB974920,B12E8D66A7C1EF4E,B4EFB86702BF6902,93082D8A6E47A5B6,AADB740C1A4B7489,00002145013F1D81,C9C25FB19D88FDC8,96B816C56C215351,207B3093B08CF71A,3FF5FA22A2F3971D,5EE7940DF5F26ADE,E43DF297068F12D0,336CE88DFFDA8692,B965E200EDB4C596,1721B5294F54000E,7AD588DCB0C6705D,C86952F451E39CD5,00001781609544FB,B2CA9E2B70217E54,C979FB43618208AB,C4AB747A312C4D8B,F8B8FBC362AB2B50,A7E4721C65BE9E36,BBEF7CAF0BA52F86,1F04ABE7D0D0DD3C,B28B3C4D2242CC4C,81AEAD33B4344A5C,DB35E7DE36479DAD,5BC4D546059D4BBD,00002D2306EB22D3,066402DBB16B6234,9CF5E3738CC22495,C81A4579F839032D,E36F0EB530587816,6D1A3CFC0FEEF294,3F831DBC5C23361F,A03B509EA0C77BEC,6BFD27D076197419,1D0077BDCBA1E1DF,84A73E195F148C6C,3EBE063E73DC02AC,00006FD2501961F2,4BACC9B972E7D921,79F0AD6BEE935992,FE15ADF393DCFE7C,D15B2C6A9C5F4343,0F9E2AED68A6CDDA,25A0315AAA410255,8EFD7380D189B7CC,2EDD1B4362B6FD8A,3F63820CBDEB1E98,0302D9587763DA27,EA94D5A21CCAE672,000035EF0BF6AE7C,D62C77D1FAB3B8F4,5934D5D2C6E0136A,A85A9E7CF0E16EE8,E299D954BB06B2CF,02D37F86B786636C,86372AA65D7C6DCE,8D4BF83192047E11,97B2E95656088E62,200617DAE8A8C27A,AF5FD5C1B63AA8C8,38511DB3F426A6FF,000052843C05DC1B,322F44AA8994C93F,903F0AF8A95BC511,38088F93FD57330B,32BBA003BE722E1B,56A7B81D699B8244,304AEE1F8C5E0775,A27C64B5F921A28F,4B4658DA5059D1F3,81D9E09072DEF9BE,3B72E58B2FF89DA3,828DB83B9405E23A,00002A6143B41456,C8E8CD51E31784D5,BB0842A896DDD063,7043488665B0213D,E99A276C1D02011C,21AD7C128527DB80,F695A4F479F9BDB4,647C7B731792689F,0B57FF6BB14BCF1B,9E19BF7FF05F2F6A,04EE3D267901D771,89A11AC2E3CD2A42,000030242E1E3AC1,120ED11D66BFB459,8A0C8875B7070E45,D3BE1309D179E736,EB820B3CF1B6670B,66D83AF0549CDAA0,7A3465CD32E2F6CA,934E74E770E6FC08,BF1F767BA2BF866C,737880236153A4A5,9359A9E1AF56B3CC,8A8BA9181FEAE39D,000069455ABA559F,EECA30EC7FD116D5,DF3E769E43B7B38D,3D059629507DEB1B,961AB086A82963C9,946A61E87751F12C,5BD995928866C05E,945C39019B36F2FD,B459D24DEE2282EF,76D48D17ABAF60E4,6F2724722062E20C,59E5E409F1234FF4,000045AE3D929D3B,4FB3F4647E00A990,6D7C4E359BE842F1,0D4687A6F054E477,5C88301EA4321446,3529EFB012CEC2EB,94CB8CBC48FAD778,6346E4ED260E8BD9,1F04C26387860445,63B96F63C5BEB9C0,3F225C3079EC88F3,D809BABBC16AB0B9,000026EAADB7D46B,F8A3FD32D1656C3B,5B393C5F891864D8,86D40175342B0A93,27B7D4CC9B66FB55,BF97D134D3D18BA5,4E97FFA3231A37F0,7D0077F023DC3DD8,9A6783C1444752B9,E64947C3CD16317B,C27FAE91490CB77F,5487631E4D121EBD,000056DB364F696C,819FFEE62E6F36F0,3661F0BDC2A49D4C,6720375BD05F25E3,C9514C16EB7E2211,A1258C89C3FF8214,527082C36560D2BC,4BD2AD5326C04EFE,1690F8782A3979E1,09DFD508C4F468CC,6E46BB1EC8983979,9921A9D61A5B187E,00004774F2BC7B57,4656BF131ACCE913,E6F0FB6CA9B67CB4,F695D51C2CD08002,7A5F9D1D5AED7B0E,643D03472244DF03,0775BF61A6D49E52,C4AC8BDD967EB118,DE530E637EEBB600,C1D9FD37E56DA4DB,BDE395263553C1FC,75E5CB79B21AC97D,0000048B5077CC04,F6689E227295E8DB,A1303F3DCA10FC2B,0927DC209361B7A1,23364FA992E66911,1161EB4949294D5C,B6971E9E1908BC5A,02ADDF36CD545E0F,845CF404EA7A7B93,53BDAB28956F857C,E1B0C16FC3D2D743,5AB918CF2C8C3F92,00005BA937CBE2BD,A0E2EFABF44009DC,1B58E17EDB2F2892,5A2027D2BE090046,95E9E038C0E7609D,DCDD5841EF30541F,32287A8674A42D7A,0F3F8737B5D6F792,05E17A55593583C7,0840DFBF9416B4C3,9281F8FC324125EB,6335DEDC3D3A86EC,0000285FCE40B5E7,08DCFEE8BA7CB696,06A1320AF6C3BBB7,DE0D822C4D77AE9C,0083C078C6119E09,F8A716036B1F6513,339320AF5F47A208,D536388F92BAF663,1BE01596999DEF50,18500A99E1602AC7,E60FF19255D6C291,A74D2624B6CBA6A6,00002007D3746779,291559ED5D93D729,6A08D09AE9081275,6C248567D2249660,905FC8F415563277,CDB20CAA4F7632AA,3A85B2FBD2AB1781,719408D9D98A617B,FE446A6AD197029A,372F15A3C044AFFF,5E91519AD83B1A08,C26620EAC48E1A96,00003E9F77122EDD,92757F762557F66C,2EA37F8CAF36EFB4,0019E9AB72D46ADD,93B3D77F6352715A,F4A120434ABB14C5,077783EE4DF2CBDE,FB6B825A40196A71,771490759D06730C,D4CB1BA83062F1E5,D56C69A52D5CA258,DD334C28FB9301F5,000036722BC4C429,87E7AC7C4C892231,9B4C89384E389DB3,BC29344B12F05D1C,10FA6DE8576208A9,6288C405CCEB64CB,D8CBB35966FAA739,9E8D1D4A2E46B954,7870531A64F401BC,D9F51973E198B591,98F5C49104D3CBF1,ADADBE9F4AA59C4A,00001CE32041DF7C,A0863E8FB38641DC,C227C449D8A465AA,AB35BAB04C9958F1,D92C36D7E1E3873F,360756C1F1707A27,755FEB9E8512C6DC,713D7ABFCF653012,9A2272725D8626C9,BC3A1619B644D99F,16E7BE10FF1F1123,5630004AFAC996A5,00001940FEE45797,7266CB4174E6E2C9,11A22C22A4D94291,BB85AFAE9FFB5A60,A5C4C75CDC68451B,674B66FB3AE05BE3,0E60E480EFD837A3,451B05F377A915A4,0A94B85A8E18FBFC,EA30BC009BE8F391,474B6EB768875153,53105300C8015C8A,000002275E41C91A,E48DE5CC6ECEA0E1,F8319E02476428B7,E2D7E8ED0DD55B74,9573EE605C76CA35,01B95CBE88FA20D4,3252400F07835B3F,6C3D4A11385544B7,530AC686220F3292,80C604CB1B3187FC,B517189CBA9D8970,A6903BF14E2AEAC5,00001E608BCA7CB8,5CFE3DD1C367F51B,048471A929BC84B6,749465DB66CAE883,B0557B44CEB06501,EAE9B7739D1E9C28,EBA7ED0F95DEE087,B5986B8FE3626439,DD7DA7C7D77DC997,307B70BB84F59159,EAAA349C63767FA2,399AB8F725AE3049,000003F1A396DF09,8BE7A05177EB4382,3BB07E093070F62A,91CC03C9477F8AAD,1C0A130FAA3509BE,9B526EA73EF0D481,8F68AA5B79CEB9B0,F8E37C98F07EABD9,7F36100DB07B2B12,4994FCCA21101928,409E40C442E68E12,8B93D1AAD92087C8,0000052A74D969ED,2D35D046FEFF583D,EA9907AF4F39ED24,B544F379BDB2CDA4,E8D1E23785CB9E0F,A84F73E2C649C7BC,A03886D80667245E,BFB95AE72EC1C870,D9214B3FF63A7650,6D20C5CB0255984C,1F65918D2F6873EE,10CC341B5952263A,00000A87B2FC7557,D424456A077E3EC3,8F5BF58F05B9080A,372EBD50D37E4457,215E8F07F69B4328,ED721D75D83A760F,31E637E5F32C858C,A95E6023AC12C118,484764BFC1A9E8C7,9591B281380EFC2E,2AECFC1E33997ECF,FF3D89D88101F96F,0000087692D69928,0B21A7E6B82C4C2C,125D875347B7D833,A7EC795905875583,436CD36C5168D129,4BF351F7F654A46C,596C02F2E8AE48E2,B9C7E725F5FAAD57,4DE6CC1CE74CC328,93D094506C1ED836,F904B893816871F4,21568145B381CEE3,00003D9DCA5E947C,3CA835CFD5A856E0,77F6DBECC5FCB1D9,34D15A5599B96DEB,36EE7350BEABDCB9,403642B588376378,4A29EEBDDDBFF0DA,8718EEA1C8BE1ED1,65930DEDA3CE6F91,412DC24629195F53,E8A938C1DC06611D,6064B507E644E9D9,00005CED3BA3FABF,CA129AB9D918237C,4F37D50D08B333D4,1B5888A2D0E92272,5FA0CE2245C476AC,06B29B3ECC64C08D,3B6722265930DB8C,138A559A6B74C1BB,4D19A35E912F5021,616678EAFD1FDDBC,F8F759ECDECF81A6,FCE486559D04D92D,000065C4F592E9E1,F32617A285922F8E,2958D726514C332F,8D3C2FAB08FC045C,B21A4A64C577559B,01EB30912A8DD597,F7191A8C7B841D45,C1BDF8A1A2052A20,A8C3B034F61BC550,6131E22F490BC13D,2FE7DF6C23644F08,55FA39CE24F928E8,000044220AC984D4,D632ECCF2F70AF53,63C736BEFB7774E4,6557048794622B83,B0891231EB957D95,611FB4890FBD55BC,1280FA0E0DFDF050,5663F3068D619300,2D0185CCC241EE0B,BE7BF7344DF15E1D,FF96213582FCF7B1,37EB9F3CC5463387,000018AE2367D7F5,FDB7870DB312C5B6,D4F4707954A35840,3BDA857B727BEAA4,9F69821B7E54205B,7D4FA66588087303,11472704741C0A31,0C04CC5E1978B13D,DF29414C316E5F77,8FB5CEE8AB7E9F09,F84B1D874592A326,25CC1AA44A80650C,0000301E4F2D8604,3E8CB9EC658432D0,7CD66229194F24F1,740C1A10B0A6660F,7C0FEAD34D0F84FD,03BD5861EB4B0656,CF19FCDED5FD2E80,A68678A629E035F1,660B9E813AF81874,EF9356A018BC1CFB,77DD0E2616AD40C3,71860A5248B7B11F,0000171706182363,B8AEF87C21078F48,A35F43BBDE6930FE,95A1F154CB52FD82,D8B0E4D6317E3035,59950011EA3AD5B2,45672666C49515BB,43AC188A52C56D06,B43AF0B76D3BEC3D,C5F1C46527DAF90B,24FE9CC55C74BD64,727A8FCF1AA24702,00006136A2499AF1,D9DF14B10BD049ED,AF04FC4A82D9ECA1,B43C60E1F39914D2,B39B5D3DF6C1B92F,6219644CE85B2C46,490FA9D74A6E1A2F,6626AE8E2F0314F1,EBE9AA905E4C49A8,E9A92F37BC836927,8383487842467322,3A059E38019A49D4,00002C1BF1FD44D8,D02780122DFA9C0C,9B5E3EAE31443E91,6712A6993B85108A,E2A27277C80726FC,FF247BE135768EA0,892A050641CFBDBC,193C3C83F939DEAA,598A673725C09C05,15D46C77639333C0,4F5E4C18FA1E2634,6CF784F49062F296,00006DB8AF4C53CC,D1BF76759F366240,BEA925347BC1AC75,3842F301A4A17D0D,D6A3CA54CD30E602,FBDB4A6E9005AE63,3719165673B96811,D5C02A9E74721D7F,C39807220D0D03AF,6345D5092CDA2FFE,7A8D8E268B141032,11619B4350D1F271,000015126170E4B6,D31323E8505361E6,2EC66FEDBC7C201A,C435E89D38FC9F2F,EF76F8078BFBDE5A,6B03088909EDE240,90027F5737E97116,24B746AA00023C27,4547BD8796D3CAD7,9DFD0AC67CC789E9,CFA0A87F5303C057,DE7E237A3CB15320,000005ABCED50F2D,C527CF4BD62E66FC,89954D35587E53D2,F6F4C910968484AC,5C2F4617F5269F0D,27147F99D0813EF6,CBA810E4C556C534,267B3977ECAC2F78,63DFD829D16F9915,352381983758845C,06D745E0D081E4CA,DF114004F24EA945,0000535AFF27A009,4D45B2777BD4E76D,98F773940789E269,38A350E48F986239,9C1CE30795D79E3C,675369351894E641,890E5D4423E7D23D,CD5CFAD4D1FFBD11,3EFF877E5AE656BA,2C1C5AD3B7609303,DCE00D1495EF9DBB,102F91B732A8942A,00005F30235DC76F,8C923AB0E792E42A,07F175CFC7B44182,06E84C39A0D29E52,CFFEB2C1A59D3990,B430610192DC9C1C,2E16497793E9392D,7CDEF52EA7869E6E,A873A55DD7BFEDE2,7DEC7CAFE82354B6,70C7176F47429298,539C23B07719D648,00001CF16EDC3557,E002F7FF55AE4AB1,8306718DA565AB86,5A69632E5CDB5BF5,0D1F16132A0667D7,299C25A34CFFA3B4,A050464A4FDCF7DF,B734CA320D98B5D9,ED2FE873383EA17A,DA3034E8E3C043B1,073ECB81AFBA2305,4E4016BACE9F44A8,00002FB738279625,6F4F131B955E9D8B,FDA8E61D48A74042,E5A5CBDCF84977BE,E18E2253111E69B0,CD7EF29B5DF1385F,8C946034D1AEB219,878CB021B501BA37,88DB8699E8AC0CB9,941A484DF0EFA09F,73A0776CF834A88B,297562A7ABE23CAE,000061ECF1F5091F,9F7A81B076D05C48,9F0259D61B1C6513,8E447DA02480322F,06B67507434C4917,A4D792509C42CF0F,435C20689BD1CD52,6D396F43766C5ACF,6A2A29D0554EBA80,F814DFC09F3FD856,8E8C344BB7499769,AC550AECB87AD9CB,00005D5E4417B936,C0E3400F3A69D928,63A20AE9CA257A99,6806E65AE822B639,011A884F02A6CF44,4EAD40DEDE837043,0742A57839858E2C,F2620AAD23A018FB,4D34473892E190FB,85C8DE44F54A938A,88BDE513903A6A53,7148CBD4B6A281BF,000005283FB2E3E1,6DAD99A632D98393,237B131EE6A56923,1E297640C9AE9DD2,89261B8FCEAFF6A6,DF5558DB3290982C,D981EF9B188515ED,B9A7BDDADF8A89F5,562A8580D2068B68,AD78BC412E2E4514,BDFBB72867E3DA0F,BA4964A1ADA3E9C1,000013989B2B21EE,000F0505803BE4F4,5E7F1CED0C1EDCB1,7E7144A49AD29C8A,D68DF976E8A4EB3F,0056BEA05FC5090C,A53FD4E2BE448E59,0C79A2EE9005E8F7,EDB5D511D9583FC6,D8F99E4CFABBA09F,A5F14B28C84904B4,16F9CA099545A5F1,00002DD06D24E146,5BB6CB5962C0AAEB,A151C6FAAACEE6B2,0B103B9625F93B00,4361EF1B0C34D3A9,2869B2BE6BC0A6FD,7FDBB3EE11A3222E,11F50FE46187CA1F,D52203D3DF2AFF8C,334DBC4912D89175,FCDF6383856937E0,2DC7CF1743F4C251,00002F8E011762E0,0C6CFF93160F6B50,F7F8D151BE38B3B6,B8B6C1C7EE847DC0,A0283D7B73D78CFC,DCAB20A9D2CBBEFC,33844B3975764F1D,C6AAFF3A5D27FF37,131F0E34006EFDC2,54C304C3D98A1A3A,EE2F17D49518D203,2DC01665E05A3A8F,00006C3F5301F590,5EBC5D2E01135D0A,2D588704E891EC2C,1EECE889D045D9FC,C7E39FA3C96DA411,09B4B41CE83CE2F6,B59ED0A4AD099F63,1542CB30012F814F,7B151B94B8AD432C,33B99FCD96C801B3,604EA3D4C9312C60,42F1CA25412FDA21,0000556B83348FF5,28F195F40570E2EB,A8ACF4A6A8A56229,7843F73C9E5B94C5,6AEE60FBBD46F431,3E495534B5B0873F,8609F8E97742D27B,75F7410561EFC679,F10F123FD8207EC5,76BE82FBD7F293C7,D524ECDA57778B5C,AE7CD1B888D03592,0000087D33D1F600,DA9D15DB42D1EFC8,E5CFB6EEA9A79D3B,6B2B5B6AEB8F97B3,DA97CD1108B0FF80,680914D39CA985D3,CDE72DA8787CA34E,D6E681A75822B75C,691F374377CC77A9,4232F1110C2625BA,3C582C6E11BC8779,13B4025F3DD0090C,000059E4AD2E11D7,88A23402B5DE736A,66F6A1917C86C6DB,6A717273D238DE7C,1BF8678277F9B74C,EB1DFCA2EBD86CF1,AEB48B58A2456EBA,5640B9A38CC3CDA2,5CB897A57ADE5C7A,D58C7CD39515FB44,59160A70305F063A,3C330D91427024AF,0000495386F4A9C1,408F4CBB2BA87FF3,BE17F4A69676C4B9,7567408999629AE6,EFE1973497D06C19,50C73A8AFF16FBBE,3662EB997181B9E0,06EEFA3E59152D79,718305F3133FBED3,231B1EA7562599B5,59C0769A61F33851,2389200184EFC4D0,000051ED1E345EC2,824C4DB87FDB0E28,BE42426218655860,6CF4371E963C2310,45D6C8E6B93734A2,62A8DFE2CD440AA4,8ACD9E1AA7ECC362,928CF9CAC3A7DB19,875FECE08A0BC990,18C8F6AB43046F46,0CF3C3D724C017D1,240358789A249894,0000433D9D276FC5,2F7F81618EBB5524,B4640AAD64676B0B,CF32CC8C04505572,3912964973C6116D,14DEA244C03146EF,78F7A03FCE416865,C25DA386ADEDAC2E,C847532A2D20B70D,1CB17F3B8CB637B6,84711009D6DF2978,04985299FBB1324E,000052A84BD7A364,E92A999382AB4514,D794AC225811656C,33B5B7AE222AF5BB,27A269265331FCD9,CFC713A30AA86A3E,21F4F67AA36C60C7,61FC322AAB385BA3,A495F9B10520B07C,DC5065D1F24B8144,548E59AEC5279771,A2D8BA07CF4F1986,00002106BCF8B6B0,642ECE677577DC73,DB4B0EC12943BF3A,99076475B3A4B011,893DFE8D29F4FADA,3ED5100CAF5D16AE,D48EBAE82F3D9500,7865B39E70D3B76A,1EBCF82A9EFE940B,65CB539E9DF696FD,810DE9DBD83CB56C,BC8EBD0844F4F0B9,00006482B7D26F20,B80CBAE541D25BA5,E121D3CF21091CF4,3B1744BF0CDA4388,11DCAF4D1A52D00F,15EB55916164DE4C,80CA3FE1E0D7A223,B4F7AED6783D9478,8A42165EC27BF392,618F13D6B6770DAD,8E68D5F504D921A9,055677E301151B33,000046B88253A482,D6FC2EB10684B090,5CA37129CFEAD0F7,897DF203C043EFE3,0E06E908EE5A1103,5B9BB9008909714B,E1DC320EB55E710B,9031C7533FA31CFC,C8A56FA4994B0CAC,CD1E7971389AE501,6B1E02BF9EE0A9B6,5531ACC0AC686353,000050E33C5955B1,E72E7D704981937F,44AC1111B87CCE60,FB9F52BB4FCDBBB7,F63E02C79B6B3F44,817AA5091C68C6CD,9BF9FC2C94438E00,D92819AF0AF44A25,46149CA8FB3AFA5A,19E0621B99496F9C,371D9F476FC5C194,F718D4A9DD3CF334,000007DB3F637CA0,D54E0C0BF6E480AF,747704C639787E35,23D6F07E2F9D089F,F4FED21016069FFF,C2CCC4581CBF8BD7,2FE6E68B4537C440,954DB647858D0A55,ABF45919B2C0D4D7,1B75784475E5EE8A,7C08EFA0ACDBA606,D437F5175EE870D5,000061C15B0B1CA0,311BDA7E0D339971,448A886AC88C4DAD,389ED7B9A1E479EC,6273EFBA749C4114,95F60D9B39D85B30,BDA025045DE37A8E,BFBF694EE7DBC395,07F770A3F62B61B2,59450F8E328B3246,6FFE83A0C95E6F74,1D8F28D564490BD1,00004C6043B42BE8,67243AE353D47BB4,378528B08D6D50B6,78699E3477E5C312,C6469F0BA8E39477,F7FDB35D90A0D111,5E642E895B98CDF5,CBE05BE9397D3815,2ACC0F79E3CED278,D2F2DB7DF4E6A875,2AE00B77112CC8B5,182BE13F1B5C50A3,00005609A681B115,79FBFE7C91FA526E,C3C05F00A5359575,70579BB8446D1C3C,C23572A864ABE590,48B2A75B843D4045,671F0FF083DBB297,8795DFD6F144A9AF,38DA10D5900E2649,C65A34486DFFDD8C,9DB712F52B6B86F8,3F83FBB113D44385,000001CB057B14CF,20636485B11AE710,E01B864A041E6C37,739EE543A8C49036,69F049AA744B5036,03447F68DDE76C84,E1DDE5AC99726B89,7434AEB2C9F71217,996F440113DFE05C,61BA4992EDDDC07A,F3A0E29117A80AB1,41E799AB5151F0D0,000066E8D15724A4,9651C21E6A7692F9,3F221AC388D0C39F,702D99811847E95A,7A88B0106D18243F,A80978A28D7023B6,89CC818D5BA4F2E3,C6ECF8BBC6B59EA0,99D2B4614CA4AE18,5334B0A28EC39D85,F21E307BEAB8C509,3103D1AD405DFECA,0000375385FC6B2D,852C89F5410AB714,57A9B5329335C667,86B8746BF0B998CA,9B050886331CFB3C,4B1E0CDE543F789D,6C429EACBC952F54,86873A8F2DAEC690,30368AF89E76D0CC,52FE4C323292012E,1BE636C7B5BBF148,CF1E563B827F9CAE,00000CF2C0C16F77,881ADCE29D82B22C,62BFD9D9185F0EF3,A4DE408BF1139790,4D1A428A7377404C,A9E43910C05EB319,65F86BFF0744EA1A,6A5BBE2CA0AECB0B,0847A1061CBFFA7E,6B812FA741FBE77C,8416229FCF1BDD3B,556BE76F94EE44F6,00005F9621B57B58,0A665DD8E10276C5,66FF24CCF3015A05,6E254FACA7CAC650,0A4A5CA62AE450CC,EF56E988A7723DB6,E3224340333DC605,7D69E69E1539C9EA,9F687BD9FE33A1A5,035DEFBC41FA67EA,54FAE596A5F38BCD,45B49FA13ADDB2EC,000024D6334BA2E6,826DE3C3C6B44138,ADF5E5F90EEA2315,DB0FB0DF9953F58A,1FA0A966AF985910,08B2CFC15EB62D9A,570FE3D280DD45A8,A659996C30145962,F66ED2A2D82808F2,0A1FD0740506DA8D,D6601D82484737A8,279E68D2190B4D4D,0000378083B765DB,060F57AFDA2CC988,7190A9A54A37E291,4F57F53872AC7DDD,94D060AAEBCA02DE,56B36FC35AA32559,64FDA16DFF0E2025,4A462A253D39104F,1C0BD4BA8A2C8AB7,AB9C4AE5F3D0D2BB,A05CE937BD727D82,42D3183A1D845298,00005636984F36CF,9C9E2F452542F60A,A9301D9CB065CA52,1F46D8A5F4C10234,02387D6B8BDFA435,4FD0FE739BF05489,A477716D5356E13F,BD749995D0389D49,6E0653A1631824C1,FABBC21750CFCC0F,7585D7C76E9BA40E,3AFF329329956ACA,000040F8563F63FB,52EFD9AECCC77EAC,4CF58F3078AB814E,C075243D22E8B387,333B60CB4CAC5494,20453B8BDB4A6A36,99EFDB715AA88C31,43DD03A268A58F2D,976AF76B9DD0499C,98B59F26D282CF3E,B6147FCF24DE2259,751A50C55CF33215,000057CFDFCA2C5C,889FA9503EF06703,7543DA91E2E0F087,F0155388CFDCF8C8,44F8D6DEB068E133,1752D309CF9255A4,A9930279D33B03A2,78C52B987F3D9033,B239FE206732BEA6,78F2A7EA4BAF293A,126D7F603A8EE9A2,E8301C06F196DC1F,000027FC9E7F7024,C3C54B4DB6E23BBB,74F95F56189D20CF,BB4F752769A28D70,7892447E8705B78C,0D80401038A9FA70,850DBB4CF8104658,50CABC1E94D898AC,F4793C816E7B8A9D,0EC1B6BC2B1232DB,80C3A9CBE2D0B35D,F8A42352EEB37F5C,00001FC6F95E9784,39ADD36856523AEB,7E21D322D1EF5C78,7787BD41B3321BA0,9F22983B59FB5858,BB6641B05B7626AE,C7B87A7552E0E935,C9051FFDAB7EFCA2,BA3997B6FBFBEC40,2D0351D05BBBFE54,EFACBA166B1A1015,5FD9031866096886,0000547434751E22,BC12B3EDAB49EB85,3DF27134523DE005,51AE708180656E08,5D4EA4A40C92A08E,F4CF61B168DFDA40,3FA51429DFF862B9,A5D2BAF841EDC62C,795CF10234B05A2B,58A1326E8165E380,69A41194F0958201,9159991BD65531DF,00002DE1A550B2C6,C2D58A9AE93415E6,D706488F2BB328E9,5827210CB9A9A3FE,0D6229CD96EDBFF9,39B056A05E440D22,FB36F0F0C7547486,F1F1F8B3A89FE02A,6AFF92CF9C359A10,00B35DEE02631F05,4DBBF8EC5F4ED5A2,36C6845F8C71CDB5,0000284BB5432FE6,6FC38001C7D1F6E9,7AE3702AAF45288B,90F0386A0DDC024F,D20DB13EE77D669F,4846D5F79DD7C5C9,5090985E8DA28DDB,54808FFA7E22834F,C3096E9C13583882,5329266A6E603033,8BF53E43020C138B,B3607A09372E9B0A,0000304877928DE0,12D918AF32271B87,9976E9CD4A0DE952,766AA9C5E661BDA0,18DF9D3E67B1B8AC,98DEBF9FA30CF238,047E732EDDB34730,407A871B8D7DCC26,B69EF6DFA77B20E9,F4A2F47CD07ABBB3,7BCF3EAF667DE69C,8F85488281FBE5C6,0000207A48528169,B4BEC35D3622AD49,3221264F078EA80A,6B298EBCFBD6C179,A44DC737EE7F0AC5,BCE51CCFBAEE0E14,E6687C277FD6A764,C0E2749F2BCB7BC5,35DDA60FA7CF2FFE,2C99EDF4B5A49F7A,31D387E4F22140C9,3FC621CF2DD93B45,0000242089958EE7,E693292B3B8EB690,3D6FA7016ED39B9C,C2BA0081210E248F,E5055C382AB55D04,D42D6F9841187952,DEA201C622E3AE89,47F3A49261D3A1CE,69CB8CF20EA9F685,F57FC703ECA0C7A4,F4B60731F4129203,659733C1428D71FD,00003E62E3C8FA26,61E0CEBB5EA285C5,B88285D5B57764AB,40A5B8AC43CF3458,261B4992F0DD4456,C2061F28A908E5F7,25058A584A78BDF7,D107EF09221AE288,950E315394A001B2,418FDCC15E53A2A0,C08E290427CBB68B,A3ECD94535560E77,0000479574DBD439,F7BEE61A74E5E6A0,F394FE3D06AD5263,635A134CF40367CB,B28C631D730DB038,F674FE6669B6C9D2,6F24D7C15CC5DE49,66F3E5080739FC79,DE2148C11BAAA87A,69FEB75613EAB57F,D7FC4E72A1EB2B2D,5038F0D33C5D7FF0,0000429C90928F03,B8883801CFCDB828,B8F73365A07670FE,E4B0CBD710832759,7A14EAB1194ED6D8,E1DC4314FF428413,B2FB2708554B48F7,595D1A87DAA08C9D,4550FB95A391FDE4,15578F1EB129755C,D5FAD01C95685415,079F447B3844EC49,00001067434D6DA8,86265DBA88F40350,95D1ADC59813EE33,288C8C46D5C13179,192E89C15C4A428A,AC2407A7BD773E94,617A9BA4B29D9B0C,8BB1D42A87456F24,9CF525C3FD6F9DEE,B21FA26CF62FEA28,C555629A8DD607E1,4B8455FACB5FF0B4,0000687B90174DAE,62A2EF6E19FBBDB9,A5EA735B54FD1422,7E1873CF4EF7D490,3739C046757343F7,ECA0B5B86D4E1C75,D80B47B69B51B8AD,C6F289AE211D98A3,2ABF6D7A22C442BD,4FAABF635B1A7E1D,5921D91C29B10746,BB18880E4042DF82,000052B07602E777,C6C15E930F1F1AF0,EEE38CAE3D422183,C60942ABA578874E,CE0E52E6A6B3D648,4AD77AF5205AAC7A,69F1BA12098A01DF,59BECF1404725179,0DBBD96F3D29C537,ECC230DEC370FF35,C7E03EB4ABBA3110,05929CD21DC8E9A7,00005B5E34A114E9,413FBA5489461F39,578D3EE485D3019D,8B164452F53B593F,00FDE4CAA44EE725,B1AD95B53C089A63,B84DC2E19DD46E47,89380B16837A3062,10E528B3611E1B0B,FE0C118F6D2AB69F,00A206581EEDF0A0,B7D0D33B42685922,00000464D43F5551,DACD1BBE8BC1DCED,506881F2EB62FC1A,60B0843D42396241,EFC0A2FC34DC628F,CD827DE45225983D,1B9F067C1F340036,DC68C78A118CFA0F,3FA25134297AA7C7,AF233231C6F35FAC,4B49FBE53EE7C49B,B6A9972CA5AD216C,000042831C482173,57645F6A05E4B042,5B5BCA8B911F974A,885266403984BE92,1E020812B3B57CEA,ADC59186F09ECF42,4D213CF6B5AE8A87,88BA67ACD6751D28,E611FF2CFF7C7767,71F0B3D04628AA98,20102BC33F60D6C3,F5792F9AA6CD7835,0000651ACF11C371,F971D52B75253D04,EA624E64BB4965B0,F44A975FA245B3FC,75A0F3A096F7312F,554608680A792A50,9A11EA63216368BA,8F2047DEE32F787B,B8CFC5E34DB3115A,A7DCD99979DAE483,72C482CF7DAB9BD6,91EFE4E4754F741A,00006E43FBA67401,FFC373845866917B,1AD86B3C00D71BAA,39EF385A340E73ED,5AB68687118EE0BF,C7994B7D82BE1F4D,00162498BFD6B6DB,54D23FAEEC655D41,1E85743FAAFCE819,C30B3CA53BDE91A0,018DAAC195A0917D,9465E9A549658FB6,00002F8519728BA3,5B9303F1C7AE98A2,862203450E0D2638,36F381C1FED551E8,6644E7AAEEA68852,F64CD30F6CD4C874,9FF4EAC98857B860,367383B8548A590E,8628FF167176DD2D,DD5B419CAFCF83F7,4CDEB99650CCD407,9067A0FF0251B4F4,0000158DB55E86AF,563094001F25BAD8,CEF10CCE7C5F6761,90337B03E0BFAAA7,C3FC40E6D6178DC3,0ABE527B40AB9D6A,E3B625C002CCDC87,C2748747BEA1C5A0,63559511A321D07A,191BFB6173CAB143,43E98DF78CDE66BD,C7A299B2B5B59FDE,00002D5EAF5286C5,2F11824B6A1F46C2,75E6CDC014354FBB,BE15A98F38E16346,4C25AA9A8A818E7D,DB388F11A23CB944,3DCADC0E4E4590EA,C331202CA9D738EA,53BB8D2860B719DB,39464BAC40A4C395,71B96C1314B19B51,9B32622EF06C8C3E,00002CFBFC7F6765,89884FCBED733888,D927B4BE8E6B2188,3D4DE08B6E127AB6,7EEA35B9B93151B9,CAA7857C50F538DF,473DF0EC5B1363A3,B83DDC13B8B84974,41A874DFAA177C90,92385F3992553D80,E0F4FDEED8A98BF3,9A2393D66EB3452C,000022B5BA237943,79F87E73097ED103,8F02C4FBCA29C068,7845A86504266F43,6297786D3C3FB2A8,E4AC4F09DAF8AB57,8C9348C4FA6AAE05,9F3BEE487D35CDA2,C75C1480BC189743,C39B3CAE06667EED,9605B988F61701CB,F495C385B7B6B7FE,00006F1016781AA6,1AD00A5F6A92C914,F80E457941BCDAAB,572FDBF7AB386DD7,74B0F8EA339F4391,F5598973D764F36E,3CAA1CD262F5588E,3D04D2A7968E48EF,0D9B9FB054381F53,5790CD98F4848C26,50FE45C2A1CB8A76,8C08DF375ACB0692,00005C0E18349494,8A35CAB6357FA122,9F0828FE62B7871F,4A9D0F40098DCBE5,5B9F338C8B73A2D9,8E335DA18E5CFF6F,8532E5136D835F3D,F831B61222F48ED9,E1739F8FFB72C068,B70D433C1C80B063,E8994D88B75E8774,00E392B298AF5302,000018939DA1E521,AC3D16BCBBCE37C3,AF43A019ADA0209B,06EACD690402E966,36C4848EA59F9BCC,D8481557F0DA6937,FB60D19582EAEA95,DB58B5318E7F2441,6872F586A80EDED8,931B8DBF2B019781,0DBDBDFFF5E9ACD8,98515238BFFB24CC,00002045137B6F15,5830E1417C389676,22E895FE1C5507C5,C97C8C304997CCC4,6F4C7270C7CDB4E0,21444500C176948B,21FF884C6D1733F7,3572B41425A5EF0B,8704591F7EF4E5F1,6C1118F215699A84,52482DC0E68BFF45,655D8B6114B2A424,00006CE2CB182A50,F64ED87BE8AF0911,CEEA8E61E42B333B,B13FA8B19FA443BB,34F0C9D97F94941D,6CAB1C16B59C8AAA,2E4988659935F213,916F4D3ADD3C844B,69B11036D3FFCBCD,A4CC3BC499C75B20,BABB4CEC6DDC8D41,4E25C049211D7D57,00000ADE94C8ED98,12E4073801C69BF3,078892C1EB5E279B,12392646624ED84D,E70BC1EE56988302,D07B4D4C716379D2,5913FBAEA686329B,7BC5C1B2779C0A51,7907DB322308E7AF,B79EC226CCFAF285,C1621718BF5084FD,0BD1A366F7787241,0000362A5F8F02FB,070F370095D0B8D5,A648A7D23223F408,0912A25DD22CA683,C9702087F291A16B,1B1F6798DAA2854D,FABF93CEDB004522,854C94F670459E4A,001C305F19804782,6E1480540FE3D725,00403C7B2030A357,93C01B4EBE3EEDFB,0000662B5322DACE,A5E81C43AEDCD3AF,BEA297D55F8516EC,C83632594985338A,9F271A9A87526ED9,19358A3A818FC0F3,79D80DB18780AF5B,0A243F16A4B582DD,A105A98EEDC37D7D,E074F95669606A43,16028DEBD8CA49FF,1094C24976853592,00003AAD3DCC864B,00A4336300B0EDA9,3B22E52AA4AD1524,E9FF628EA29F1229,FFF412335DC94D06,D6451D1ADBA583EB,3C400B6D45B6EA26,E0725F0515DC0460,A5DC4FB6D2A7C759,DBB42E8F1EB25CF6,38E0271CEDDA20C1,584007FEC20D78D1,00002092EAE0334B,845A21CF264776EE,FE38972D167ACF96,4C4545147E3B8CB9,D8789B366F057B04,3E072EF921A0E17B,1B23621D334924E7,3227300795251DC9,A4F085A05B5BE8B9,6A5A9EA172800210,CCB9FE5706CF7E66,2039D6DABA85864E,00006CD896056228,BD6D05CBD53B6EFE,D2DF53C8CA0E25F0,10CB1680CE138277,33C2C23DE7E57455,2C2E7CC9FDF857D3,413D1AF0EF4E73A7,76F9EBB7C9B8F6E0,A8F4936EAE8FCB9A,F083B8D170281D91,F874AA91F894DAFB,E085DF951FD8646E,000055E9CAF04176,17E401D13428E6DE,FFED26825E714877,C95E297F6649C42C,44733DD55C0AC4E9,8A6A26FE0CDD15A0,0E0B63926D371CB2,E0614A2D0C6364CD,5EE4026ECD044BF8,EC0B803E5C0D66AF,5A26DA23C12FC79F,9653308AC420D542,0000449906E508F6,A7AEB9045A4A8F78,BB17287D2E92DEB5,D6734FA0AE1B348E,C4C17184C2A671BA,62E8BFBD20741EA0,65AC654A75D391E9,A580B7E5B6B203DE,B9C4E74D059B747A,D1701670D90B476B,D3DB70330FA23E37,197D6681FA60225C,00003BC3ADC49702,B80BF8EB7AE5583C,43E12B341DA1246A,89EADDCF32509D31,A831EAF11FDCD4DB,F44BC5BD8225B075,74544284DADEB68F,9F47233AA06D762C,435191307DB93B05,249C99FEDA8C8619,9F52DAF9C9D74255,F25ADE91A2BFA191,0000658E24967AC5,FF5B59351EDB5B93,7AFC4B0946B551E6,8556BF7A9D2CAF19,850875B1E3F92844,BD02396F95535FFA,7F84567109A412F0,18EC2A2E896032FA,2C5817E23A7170C5,B69F8C54640BAE83,C10BC68890034B2D,753F1F3260431F5A,000062888C6BF253,067FD25A2E65564A,7BB864ECE7BAFAC6,0B473FC84AC55973,2709D8A31CD27256,A5775801917FACA5,CFE54051FBBC1EE6,98751EEA1BE0C582,01546EA6CEF3023C,27342BD0DEC42775,DC82E50B071DA454,D9F12B95B3F7B21D,000058940344A3F6,4E5B09F4CEDDDFC3,1FBEA35983E830CE,190ADBAA86551061,34251BD52C19C1BA,58B78FC85AE369C8,05830CBAB8E009BA,528C697A57592253,A1DA52365BFC490D,E3C8382D2D1EB448,9A325F0BBF1119F9,205CBC957F8FAA7C,00002B86ECDF059F,0115445397470E3F,B24B395F7D2E211C,3720FA85530A5AE8,2CB1082B0320ACA2,A8D6A3BF0892F99E,7CBDA81D76FD1EE0,D968F1D62A03FDB6,EAFCBE291D70889D,70FFEB7A69C4244A,F1686561F56F4CAB,1F0D7D0D57A07580,000002DAAEDD23C1,A4204229A876CEB0,2D34C2ED3F84B668,253F8676A0AFF47E,99446A267E8D38BD,6E8FFBDF1E94168F,D9A60FF37F4B8FE2,9874501BBEE59E83,0FC42B1FA1C68020,47F922CB463A1BED,8198DA7CECE0FA33,27ED48BC219ABBCB,00004E89F0235604,572CD3CD95CE5930,971BC10FCB9C1CD9,388358287F31F180,4F0AE9AC8B73DA97,1AA33886D939B4B4,481C36DDEF4420FD,4B095599FF265E08,0EE41832323040CE,01D9D1A029096263,8EA7868A8618F9E7,07ADE01C647B0D53,00001F66C908F8EC,5F380B97B6508E1F,9B18CD00CF392E2F,61DC667D88EB28A0,7FED6E55263F607F,DBC916C26D5A9704,8F4C930CAF007DE1,8112E95A756ECABB,59007E8BB9392F29,76A13603D90FC97E,1126C6E03C1A7D1E,337C79EE1FC7D78C,0000042CC40E3CB4,6F29A286D3287E5E,B325067BB08A58D4,5820214F7CAE8ECD,EC9582E8D9AF8F35,9DEBA2F7E62D9529,DB3A9E7C71846A2D,A1E6BB011C60F311,56B6A0C1C3503F5F,2119DAB107D6F85D,54B7B8C3E39E65B7,F9A976F86A9F71D6,00001CEC6748E4F8,A058DD8E2DEE9391,1BEA3C72622CCD37,88831EC22721C584,D38703502072EC2C,329B7D89C8B35A7D,F7A21CD3D3CCEBB3,BC05761E5C0C9E1B,C3D5E408D81BB43D,7AB76BC70F14130C,F95B14688BBEDDB3,0856A9786FCEC8DE,00004C9E87C8E01B,9B035A3604FBEBAC,FB67CF99F94B63BC,11226A78436794BE,AAEFD71B815695B1,FCDC1B22D15ED0C9,E9A9F62A86A38EB8,76E4EA4CDB86B431,0CE47CF430330F3B,0A0AA22821F7C307,72A6C97D29046947,0197C85EF04F55F3,00005CF053FFF315,671AF4FBE8D20FC5,106808B61E14FDD9,B091B75040ABEE51,995E606B54CEEA51,2B09FB1525494F4A,7E8045CB0E8813CC,710A8139EDCC54D8,596999F8DE00AB5D,EC96BBEF74E16734,E7FBE15AA694894E,7220BDCEF5247648,000030A587EE42AE,E2F5DC0694ACD417,DBE07C0650668B29,929C09A881DB1939,5B371B7B343A9A67,86E78A8A620ABE47,2A7C504CA09F3C9C,4FE91B9DC9687C8A,2439ABDB216629F9,0EFBB32290C41C8B,C5592A2F27A64C21,4F365E97184FC8AB,00004971E6DF8EDB,FE8B1E32C2186EFB,11B6A7CCA81D4910,A6740579A8AB89D3,882ED42D2E75A619,12390ED80BF20018,4F5AB39624BEBC56,8FC0159F40072BBD,7BA43874D0F92515,F40DA656D9CFE9C9,57563CE2C53C72C5,F6B457E8B0E42C20,00004AE36B2099E2,82DF0C17F0D243EE,C93C29F1229A7CEE,192135F5F50C86E3,15FC19D022F2495E,5BE3D72345947E2E,883519C997267A9E,C0C958302618CF10,22D41079E6FE8F32,437808D547150E66,ECFFB3E30429DE94,E55F5F26FCF2BC76,00001CE869D5F6FB,787BA9577254F6C2,A5B0EBC1DBC1C963,9851D08C74858292,E0CF7228CE811906,A7FD3E0450818B4F,C01A5980418B385F,8618CA1C3FA1E9F5,7D6411390A38A844,8B0FEC7EA7687593,EDE07E6D45FF65C5,127BFD1A5A8F861A,00004C4DB41F24EC,F36AD2C8A1B471DA,F9E1F8BF1B0C3928,C754BAE3571CA976,A96F9573BBC84823,7B8CA764771A57CB,B38B1BC77FB7093C,8989291282146B6A,F5CF6F6C359B1F75,CC7A1AA92BD0A168,7A61892E1E6A294C,DE11892EEF733587,00000C5BE681EEBF,94C49D46CA138D2F,0DC44072E320CBC3,B96AC405E5824B69,DFDB4A10A93F53C8,B8F03FF0718B5601,344D74C70E2DF3D1,C03D3EB971C823E0,DB6B23CEAA150F3F,F13CCD1373C314D0,FA2E6284B7C77E38,4B9EC642878D3694,000049786C167E5F,6BA6DE91C7D006B0,7F613587E9AF855C,DDC7558053A2885A,47E524C765E99952,0246C982024AF662,AF0E31FB228AE181,15A4457ABBC73A9B,3B65C89104F4EAE8,E1202A0BB61CA7CC,6A7FB18550EC827E,229C96271BEAFCAC,00003AB9F1C7FA57,573FCD292F476D12,8E6810111AAB8CE5,D62737FC7A508205,2615670146CE13D6,00AFBFF080F6E7F0,4853A9F3F0CE38E0,A1106CC32E70516C,74D61FBD5B6D5A64,76F04DC21FEC21A6,A8BD48796B757A62,0CAAC848B90FC25A,00003A6AF8859A98,F104D54750FD303A,0109E35CE0549B0D,4927EBF4D8C1C9CD,C32D69EE70F08765,38098E5F843FD0F4,7D83E0C149E312EB,3BDAA10B275532D2,106812FA413E804D,12C4E503BCC76015,22C130CE6CDE74DC,DC30BEB902BD79D4,000045FEECB5BA8F,F946FD2F484B8D6B,9CB4FCA351716C22,CFCF0EAFBB29BC30,426ED56049372181,AEA589952711443B,0EF8DCBC0C8AB64D,A4A9AB4473B42047,BD021F49CAB99390,977F956B45D57283,E0C9E4A6FAC331A8,8578DC15E77F3AAF,000066009CECA13F,BBF08C6F5850244F,DB76F290E9442881,1BA31F1046C362DD,13A5246A04BA1DD9,939A922185FA55E1,55504390C0928F20,8D18FD35BC8D4282,12660BAE658E8E3B,3723589D6DA0D767,E4DD586320377E06,9BFECB02CC35D539,00004F1434F0883B,0FD445CC7978F128,06EE18B0C08F917F,65779E49B45470D6,588C56B1AD1754E8,39FEDE135EFFF5FC,646C67FF6EE7305F,80ECD78EE26D6681,7605FDED961FCA7A,CA49842A1C52AFA1,6A8688782997D7BA,C4CC29C23591F54B,00006F1F8EE63670,C7643132E952B7EB,72B7364C2A9FEB8B,C4DE51942A45A1DE,C4FCC96A22562042,2BAE6CDD447B88FF,10D657C81498A175,AE9094D3071D660A,D5ED72497DCB0423,970DE75A6A766B21,8E90052AD68881CC,EE7125E7D4424DDA,00004E62C4873C22,7415BD049D12C71F,050C06E012F81238,2B7177F59BE0AA7D,2767F3CA8E72C42B,5744A797E6D9AB9B,872A49D2E3FFD50C,9DD7F162D3EDA349,94465CC2849C2E31,F439B7DF23B4503E,C03E5E79960767F2,59655D75562AE847,00002A9C0D0EA78D,336EA4AD8540F6D4,5750606A940B335E,EBB3168505C6B83A,D6355F44FCD139B3,349B37458393DB54,679D3674BD564FED,E74AA5E9CFAC2FD0,40B192CAFF19A3E9,EF73936E5F592B5A,90653298786A7E7B,AFCBC2902618C971,000043BE04E6E369,A2A37B24DCE0C4EE,012DCF2069F4009F,A68F2D4E9511CC9A,30CDB16C176AE6B5,EF7891C65E5D3E15,DD76C5B6C0F30D88,DF5FBA9E86C643BC,DC53278711156020,1475D6D7E59F2461,A8464B0A9B96925A,69F3939B3E2219A1,000007A5FA3877EA,5A9E4289DC40FCA9,F48822D67623BE48,A19EBDED19222B6E,5AD434F9AB8FCD69,5315375983B0CB99,94680D77027AE101,658B210A30945864,8514A4792F42FD7E,37AE2FDE2D805D7C,6135DF7361B0B734,36117F2C0853AB9E,00001AA6863A08F6,B839CDA7E2D1EDA4,A64990624C0EBB66,5181BC58237F091C,A678627A2D794650,59AFCA699AC4F0B7,F0E80B87B738659F,E48D2B081C119A24,24639FBC3B5C6F8A,F4645495B36A3906,E6F1E462232CDEF0,D1F196251905AC58,00005659D7E8CF16,CC17C81AF195E238,6A4979078B359BF1,F9CFAFED6CEFCFC7,6A0F51CF5D9A1509,168E5F9A2EED4157,B5DB4680979ED790,7CDB9D8385BA22DB,048441C4024CB3B6,EAA34D23E55BDBD2,0CA2CC7CB1292070,D8B04C526C5A2B7C,00005F29D0E03E41,A22911CBC2BC9A1A,A3DB63611D9375EF,B83BEAE2348B1424,7AF5E97BC6474D5D,FD60417AFB62FC7D,C333DC0F2665DFC6,3ECA83BEE5EA0AB1,891A37EDBAF60B3F,C6DAD3BD46DA8D05,B15162F0D75B69F8,C8F3BE4A974A37EE,000012D8A1FDED20,1B2ED31E41C0A269,08ADAFA7949269AA,46D86A766F2202DC,4DE0963F345F30AE,EC15EE8B1EF04B16,6337FBC510E49377,91EF42B37A56C3D0,748BCE168DA610F0,1938C279820BE012,9B0F47C08013ACFD,BDCDA66641C3F177,0000175E3E239C4C,A265682B0398FE95,3834D57CB83CD97E,C9D3B1B3D9AA6E7B,B4284E250809CD96,1D5CF2D17A0C3D14,6EF4004E80A7344F,985F38E59D19E3EF,675B34C27CEB50C7,0B982ACC86FE1106,4ED93626A803A1A1,EBF1762AD91FCEA8,00001B2018404008,2224AF58640CE5B4,A027CE1280C91C2B,63DE2CFAE23C0255,820B90785BEB2494,5597686279AB3469,77E16B7343FAACB6,7B7DA8B575619B91,0D47CA3FDEBAF22E,913214338DFCD3D2,63A73B0FCD6FB3D2,75136B586CE58E09,00006E2B9B839086,0F25E87CF4B4EEF4,42BE36CA5E04F2E1,6B6E86D947729FE3,5595EA658AD57E27,A8ED4165C533EA01,C01A0D047F067138,D97286B1FE51B23B,19AC95D3C65D29F2,AC48B94AFCE810D7,6E646F5DCD9E72EB,4775415F48D384AA,00003E6004E091EF,32D99C23EBF8BF66,A005E0649EA097B9,94579A61640AEC8D,8BE4676ECA960375,6758C175439EBC1B,00F89EED693BF769,4F7674B159A5568E,6D49B12091F479F4,ECA15E5281BB914F,BA67832D80AE81C3,51B610874A8E9F8B,00004D75962ACED1,AC1DA4521B751541,7AA49DC20B9F2E6F,1056CBEE6E8771C6,D24CC78DB7708D94,07BF7557221EC66E,F19F9E337B28AF87,12B1925222D4CD9E,3CE0898EE96E185F,5775C065F2ADE970,8E038A146E20C29A,AE088815CDD07277,00006F739C430D26,3B90B9080D968B71,3B9679A0E48C3819,7B15CEA73FEFE19A,8FCDFCA9349CFEBE,F90E5F3BF050F0F2,E82770F6047DA3CB,A63E082AFA5BA228,511A25A9AD0D7108,6D112472C0B851DE,E3B4E8D57313F2E6,3DEF9DE667FF279D,000011454593E746,B83BE9885953CF8A,1D908BA280F56BE5,88B7BE1E8FE87A2B,4E55D0201AA8DEC0,F335C1C8FFFC7D4E,139CCE0F1D7044BA,6C31BED2F272CEA7,360CEB0950F8C8B3,6EA468418A5859A3,BCFAAD4CDD2FAD3C,F646C3FF75268DC2,00004E097D583756,DBF97449FEFB895C,7B35DC4FAF1DDAC9,1991F8FEB9D89712,69237BE09CC1971E,0652DF0683DBDBDF,A14897EFDB4B12BD,224FAA22D923F167,A1338C72C8A26E2F,6558C1E6D78445F1,FEB4CC21CAA25430,7DE78191DFA9E5F9,00001EFEE5CDFB06,6C4B8BC35B33291F,DFD441AA64FC6788,B1F930657EB99D1B,15676AFF6F1C705E,B70ADBB67F4C8D7E,8126263DBA998B75,290FE88880B28EED,FFA3457DD9F51BB0,F1A94B499AA0C686,D5A555D7D65E7EDA,2B7A7166971425CB,0000047252C03AD4,0FEF4996C77F6749,4E92F6E6A2FA44D3,ACE7691119653D9A,B279F2B1942C9276,26502CA228A45D63,84844B3E4DA5C76F,32F6F421DCB52A89,CBA965F95864CB7E,A0796CE6A845C2AB,20BB1AA2FA5D3A6B,5C3B62E212262A5B,00000DFF25B4C6A3,69E6EC6B0B6548B4,74263ABA00CC0F91,EB199DF4F259B4F8,AA01135C10F7FC40,4D25A156DDAB9A48,ACC46FB7C64473EA,67EF17B147198FB4,9D7775E68160D5B9,75B5E1F33FBD6CB5,4DD2E51DBA91B323,BC244DF8AD3978B5,000051D775444A72,41983A540D65BC1F,859ED5DE9603B97C,04C4E64769AE556D,8E96DD70341E35CE,99151ACA29F5E062,B94B7D65958DAB8C,38B99977B92B401A,6412E4711C5AB105,5068A4C8879516CD,49CD14183C20EFD7,6F0152848092BF9E,000014C1DB8E402D,5EE47C05DDD26C7C,500442FB468C6D51,2CD76C41B1DCA02D,B2A55E1ED383BDF4,A269FB3EDD42D86C,F134361F9E809A7B,61CF2DDD91723FB0,EE2CE1FC7D2912AC,0057B3D7568605C7,9EE55F0E776F6944,FE72B6E4414CC0B3,0000487B3E48142D,9F7808137D6A9B8D,10EAE547C4B5D065,63804CAD1B406F68,4E05848BE6F0DF3F,81D460720D7D47F5,D5EF915904801D05,4737005626EBB406,368D8780DD9B2B8A,B81421509A6470E4,23DC21A826D7289B,D11EF961FF1DB794,0000636C6A3ED2F1,B1FAF44E7BFEF267,A78070EDE8CFC6B9,D5B7D7DAED62C4FF,7A9AB2EF05C5D28A,6A089492BC0482BF,A1DBB79AFDDCC6AC,25A0C856022C1CF8,DB23ACE61E891134,F2C3312466F321CD,9148C9EEDC9BBFA6,50BD7C3E4A860481,00006958FB85EC12,71948AEC47C8CD04,7FB38BACC23EB8F6,4637D4F892C1EFCE,A328744398CC8BC5,57717F9961C1E75D,B44E5F1DC294AE01,570A0A3656283EEC,9B77FE218D801117,1FAC40BDDE6F1D10,4426D6842B9E744D,B8F43A6195CCFA5F,00000241C6C3A38B,EC4D6AF57EDD0E6F,A49FD8F297592A71,C084DE2AF1781CFD,798A7D82F987739B,5CA5BD65B6FE0AC2,4EC1AB3312B4F03C,6D26AF1E8AA0E1C2,73CD7890546126CA,3B5BA96BF945E49F,A9186ED8D99395AB,0740A5CF012977AA,00001115F6955CFD,B5F1E4FAA55867F3,0933E9FE8FD465E6,27D9A09FDC34320B,97643A5D1F3306B2,C5DF6DA0FAF2D8C6,F40A6A3083CF9AB1,66DD0481370D327A,87BC92814A01DBFD,21903E547D046FEE,BEE47403E25EA926,D254B2057305DABF,0000546806D754AD,A610CF522B74CBE1,09F1A4BFDC247EBC,95781ACC5E334228,EADFD81BB5C6B3CE,A9D08E7C5C4ACFC7,3CA073455F3EF0E4,DACE28AC9AA6B754,79346B8E75EC858D,EB0753EA6B22F80C,F6BD4A39F23518BA,E1FBE39C6FE73590,00006C2A06D4971A,81A531231B0C7EF4,AE6924B5292528A6,03B2F21AA021E09E,2157B89404909FEE,DEC39B5946F5EDF5,8D2E70EC2FEFE10F,C207BD49534DD359,0763222163FB30D6,53F002798FEF0970,0ECEE08F43375EB9,A60BC7C28221BE58,000069B4D702E431,0B084058B5B02E6D,B41BCB0A3293F071,C6017FF9940CDD2D,674186430E10668C,FD12C90AE322EDB5,FEDBDFEB5316A177,E1F07D786E5C0C60,63E1ACFAFE26C2B5,C54E35C28B244382,E1EC10F780413990,0FC25DCCB2B7D0F0,00004B6598235614,83C7E056930CBB7B,57754CD84078D762,3352B83C666201B4,9FB7940658D7E756,21E9822BDB65B6FB,0F34ACF00A580407,E2758282FE5BD757,1FF41F1B102EC21D,8A9F283915D1671A,338EDE0FF4277F2E,40F1A602A8DB92D4,000052E5EA96456E,C39A747B5FF8C061,E5E80BD7CA835354,D7276FD55225349E,1E9838893E99A650,4ED60B6C5EDAB2F8,246F42ED71785763,60F6B3B2B7D1CABA,4339888E2873362A,64F97BE37129A460,9BFA0357CDF5F9BB,C0889C0AED546654,0000338C174CCCE6,69146B52ACB6DE12,5CB5CB45DC6777AA,57DA05651AA18EF2,942AF571ACBAA70B,D3187F9559770000,6C8F59771CA5FFDD,54CD3C93035FE83D,F25D8A8CD50C4A0C,6C3291E416B62366,DC33FD6B8101AEBF,452A2F3198A31903,000019F831210D24,3E098CB650B0D39E,49E9981D1E739BB1,D6C5882B403F1954,35DAAF005BA319BB,5897759656B15D57,3A03E74EA7979FA7,1AF5BD6020C39324,A110A4F5B6BEEE34,934FFCD73AFAA0E4,8C833DF14430EFFE,EF7D06D607F8DE81,000010C1767C5CFB,8D72FC4FD34FAF22,DD2C08B61FBFD334,F73E7807316AF940,7B0CE89B6319CF07,E5B56972CC14393D,8B5A8E4171E5E880,D00A652F5577E7D9,333C41A14C8BC0E9,EA66CDF6ABDF3983,9C79BC3CEDFACED7,3DA1DDFFACE73A6C,000009DC92A7A906,975CEE2B21A49936,69BFD242B2430FB1,F55C26467D26B50E,48E3CBC43E422388,91BC92B169AB7360,CD5C145FE1F44EE6,1C410EF0527BAA82,8A4906CD644E334B,A4AE091615620338,66E8D53105F49342,5DFD9F7F82683E65,0000513A4B33902F,48E9E3664ADFC057,3EB11C36076AFD0E,EEFE7C02D3674BF4,E272363D4EA3009D,1281EAF9F68C727D,9B054DC64A08E23A,EB959F0D49EF6746,D2DB1295C002333A,EFC9422474DB32B6,3F7BC5853BEE4A94,6DE967F045C17050,00003F33C24C7A97,04D1374293F56B9E,C5B115350FA64E50,90B0BCDB50DC7FCC,4936DCF9E63FDD9B,8684B8E7A030FBBA,8FDF7E5AABEF67A0,6A0E2025C0CBAD87,49E8B571D29116B5,A350C5729E51818F,88E99DADF1169E73,57A9A174B0A9AE2D,00003C074EE2A057,07226C6AEF408093,B0B21151AE4DEC05,0A21D6A886CA380A,FE15BF9D81C46B0A,383826C5D1BEC8DA,D53C59B07B80090D,DB5246D88B8678AA,55D275047BC6DE6C,B6AE24B2481F0760,6A60EA1A9C565D7F,230B0E6EACF3443C,000005DBB9088FD5,69611D949A70DDC8,0A1BB2640333B17D,A222F19C8A2274E3,F3A7C430FE9E1F28,FABABE44E33D5870,C7A778F68902E41F,082A4FF04862B47B,B14A57950BC54166,7B2483026BABC68D,55344510D5CDAB6E,438B5BFDD85D3DC1,00004FA573BA77E0,0A8C540B29D94C4E,6EFEC270F9981598,36C31C073FFCCB2F,B2E4205B0C3DF148,E2D9D02B5B243E06,19A2EF23910FF885,2A057A23D4DFB66C,8850FA8A9071A19E,67D040065A247EA6,58150DCEBACE66C9,DE04B21D537ACA36,0000060E0EC6C3A0,02255900F22B78C3,7E0F4F0D12E2CEAC,6938E01D682010D9,A60A9556B5C3AC41,D0954933AC2E46C2,2B68CF6486413C8F,BA06B587987DAAFA,8C20E8B0DDB4A26F,77304F0E41D68643,E4D859F19C826632,576C159A46419472,000019FA16BB984B,FFDB1A0BA10E22CF,41330DD98592BD2D,132E74F792421E97,ED0ECC77DCE91741,46D90C929304436A,D9ACBB548D82BFAE,ECAB27A69114C428,2039F0B414FE4254,EA8D09B4BE5F80DE,580E52406E63E781,586880E0F3D6DC7C,00002A1AF3A7A63A,9CF8B1E6B0BE97FF,F642A3AB48E64EA3,01AEBA603050E437,567513881995F26F,3478D53F26BB7706,FB1B6401E96B29CD,4A0E35DA59256DB5,B2F09EDABE56F607,4EE886D55076DBE1,B60B71F23576B546,1C98CCB8CCAB25F1,0000137BDEE9235A,388113637C9AE658,72F041C41400B41D,8F9E230714987506,764FA03CDA24F468,129B6332DFAE2C5A,A0F12813F4658EEB,D2469EE08C5C41EC,3DB73BF62CD938DC,AEA48B506C68D9B6,9D3FE110443972A2,7E1484768203297A,000018C6ED49399B,BEB1EBE0109C8633,C6553698AA045973,E3CBFFC031EB101D,60BD7BB793D801C4,3D717D5892A162E3,EC2C6201B1619732,6487338707DBD781,AA3261D2452E8685,DA9E43BE1F8F0BE9,5E589A1DC73A9C49,C141075A8C8B9002,00006318E1459AD6,3F2A7CA6FA9C1720,4D2F5DCB38C36729,E562B5E0B99256F0,24F9226AF103AB36,AACFD82E4D030568,B2B1F0130BBEC6C4,1D80032CA59E3B0D,AE1B55E364048B0E,21BE0E07D3C63AAE,DB1F8FD62CA1A7DB,C75D94F0D6112994,0000602E82204655,A1C8FACB6DCF1241,6CEA8827C1EE6948,22D6D6C882852FFE,8B6168DCF4409A7C,56CBB233A8DFE686,38D6137195333435,67491D44257D967E,EB502407D9927109,7018A56016068269,C85646B64C84C134,DFFBAB5CD751DC2A,00001B04504BD768,BB92C225A067F0AA,C0B30B03980245F2,AA4C305A5987A866,B5C0821E9235F73A,D80C5408ED4408DC,3F7BBF2C5C4653E8,7781079AFFE05131,EA80C698C726B633,A8E7D3637319BC54,B07ACC0A14B8CF54,6A763D73A9419F52,00006C57ADC5C5C9,0709F886A5B0001B,0B7B30F11C15E9A2,B3C3A11FA1E55ABD,219465F9872A1D9F,4A65B1E4887F59C2,84C5DD25C046CDE9,45818F0A56A117FB,B7A895E847684E02,9A655DDC2D5D19D6,3F2383DBA5C510D1,C5BB2EB4B6A3ADD6,00004A69995C5C20,C0A7B8747F7B353B,F7CA3E589022FB8F,02ACED7A8B8BCC58,390D50C0892EF2A5,D6F6503C26849AFA,BAC8DD01F0CD1809,53B9B035E6B90EE8,2FE8C17784F3AC53,A728C34B7C780A4B,F6A62915B11290FF,C5B4BE0F40710A94,000026791E28ABF2,388110F09387DBF5,B6FA6B5EE2245CCA,B4C4279CAB8E7727,CFEB9B794886C6CF,B20BB0E34065AEC4,C49CC2880106960E,80EA7A85B685BBAF,60F73AE100560A8E,2611FD3CE268B4EC,968A465FA895B879,B2D6BC8C47360193,000034C095D2214E,AF26D8A3F84E914A,80EEF0D4E1D15073,1DD8F66087DE36E8,DCE0547929F70A66,95D8FE6C389BB4A0,78A9E0CC9D0E5F81,235CE9B2E1110941,73118CC8C43A652E,6128DECADEF960A9,D259774D071DCA07,CBCCA6BB2B586312,0000567565E5D717,10E328232D4FFFB6,1119BFD47BF5D5EC,8BB962F8938DDEC4,69BAF0ACA843FC0F,CC07CAB2B09A87C8,8D027D9BFC167028,2B37BEE44BDFD5AD,FF69CF79462FDA07,D4EC75BB4F312885,03D17F36CCCA4B2D,B2CBBD0774219891,00005609C9085CF1,3F412E9B87E9F083,2D57195BAAA6F671,5FA9F9CC70CC204D,F9FB6680C2EDCFAA,E7A8D377D9611E67,A3FA756286DACE06,AB7B2BB920990011,092B3550302B9427,58D9DF4B4290481D,412844385F2BEB5D,A42BE22E5FBF4BFF,000030823578D94E,07AB913290DEB349,32A0A01FCB29A8E5,C9A17F44A8B5D3C2,8DD9C30BE016E710,6579E2E3362B4CC1,E67CDD2E691E404E,2E7F3045655677FB,B2F5356249E1E151,5495F17878E65B24,29CEED8809803CFF,366AE4F695DC13C1,00004096B9490EDD,857CC218679AD606,2D313DEBE540CFE0,E62D0E0228F24A66,0D5DA3786F77C14A,391BEF97B5D2AA25,AFE7E18A2141CFD7,AF3D6A2FE62D594F,E5CBCDEB6C26F49C,84B157105CB6DD17,37A3AAF64B5DE74C,04D363DE7AEE7851,000004640B4C214A,C82F2F78220265EE,03CFA7B273110FB0,4D7D88814454B576,56550CDBA26D4E65,1B5126F8F8BEC9C8,A8062F1A17E3A3AB,D2CAC1035514A2F6,D646C20A39F6CB44,4DA857D8F1277737,202AA67A03547B51,4734B6202E68B154,00000EAD1D24B04D,4EC6B01D583C8E34,72721D4384B9A515,BB795C54309FCE45,6477351CD8914038,29D6D625839677A7,033D3E0D8D9D1235,C82A59B8C4F8A356,5CFB2D42B07AFB1F,FA1940C823C12CCD,1E1C1D441017473F,DC2595ADE446DEC2,0000127254B93803,0BA2F81249777BB2,99FBED250B71C956,40357541E6DECB9E,91EA2EE432BE0692,1E9BD3365C7714CC,F88B3DDEBEAF17A5,97CE148CDF7111EA,E0E2AC75526C974E,5CC5AE522F7EAC36,52010961C46F3983,CB11C1717301D27D,00006F2CC3A01ED9,05A06B33C61F9C36,DB4A0F429083BE1F,E26F6EA3F8B1D9B0,04FB970722992637,DEB25FCA7E0E2924,4439C299F2BEB076,F714C12488A81863,5F2DB83AE7393D68,790D54B37CFB7FBC,3BA60007509A1152,76AEEE936DF75646,0000155CD7E9EAE4,4568F308424058F9,509A2272687415DB,037B5485312ACEFF,EAEF0791053945AB,42C2D70939C43D90,95C8859621A86DBC,C19D686109C0A19D,7AD4AC7901925C6C,8233685517A87CCC,9B4A2631A22CAB85,14CC339C3E22D281,00000C6F8202B91D,3C1E1C47ED4D332C,F30A80AE3AA20BB0,3FF040917945DA80,D40118B7276B7621,BE00A517D7DF1993,7CB14E1A3F923764,2DBA21E2B159F1BE,1212AD736E296379,1DD7C68DFAD70A73,2866DFFC73372E99,2B4B758ACF5B68AD,00005E6D7DDF88C9,4FD2773E58969345,338F4C2281ABCCA8,48211C3EB5A7ED0B,BDA1DBAE42351D7A,4AAADA9EF637A3CA,6134EA2EC2F771F0,D6AD081309A212C5,F6552B8DEA1DF8DC,741A662D2E4A9E73,007EAD741C10C708,70D23E429B3F2FB2,00002E561F6D7157,3A8CF26701B48D75,CA0DCBCCCC103A5A,22E50FC32088C4F2,B796228E15346584,85C7DD84514BFBFB,2F4C8FDD32F67B84,FEB1A072BFAA92F3,6B2D72560AC399EC,90E561183974E342,D33C4C8B33C95557,6C2E950BA4B5812E,000027969493DCBE,D1996C00D49611E2,919889D962128927,17E33C5350996128,97B9845892BB1B7F,2847585A738E83A1,0401F0E2AAA2FBB2,6174B4CFB8637585,95D3E09A5B91689D,39C40570A4744150,D49FD7590EABEE1B,521DB69B2E3A610E,000058BE32DB6DCE,6B8B57C30D27860F,2582B156F9C36CE5,A44DD7078924C658,B456C1D4CA9265AA,748456E27BC83B20,9FB392B800D49FA4,B2F4753C2182448D,581FFB77B2385DD0,6F521C9075446325,C668A59814E059A2,55E4B5A83A27E8EB,000069FA609918C0,BB421CF6674A3AAA,8F3D4184ED769BAD,42C004D33A7701D2,431F6F2683C62FEA,AB88B7C10EA7F4C2,62FBBC26A3999D60,239CE7F05BDFFEDD,E718BC5187D0D49F,862F0292428671A8,0AC51FBE64D3B22B,73692FCE5808145F,00003B908743C4E3,F6391651B221E5EE,BAFE7DECCDC36954,60DABA611AD20344,E983357B224730DA,01C8307E5B99BBD7,E69CAE296E1535DC,9BC21EEF3769D483,5584D8E0A2F26CF6,ADE37BF1C3A474F5,F26E9AFB6A3D3662,CE005CF2895BD375,0000551E8725D41B,8D711031C6147C69,17683B3F0364DFE9,5D912E2D62314D6B,2CE801424937FE04,06A8ADB7F22065BB,240E9D94E1158934,5E81070B81CEAA14,620820C589FDB7AC,76F01E5125EDDF67,F2C67390EE081D29,741E681ABC59E415,00005BD0E3A0B8D2,0DFD99682CE55600,41A6B6BF4496AEEF,E537D96F6AAF153F,E9B3263A1630B158,EBF51F4DE21A95B2,F85D8E0E4211A202,C0EBC5D0820E19A0,70E80A4C88597737,2985D7D5B713DF24,23EAC318D814185E,15CE2696874E2F3C,00002DF4A05D2268,877BC7CADE293DF3,326CE1E177D0FC8E,B3AC13EBCF1FF83B,A342EC816738B83C,162EE52735A1C802,DFF3E8241FC65A89,7E0BBDB06C8D1EFF,8F6A72B341C06DC4,F4840040BD266B2B,6A72C34EFF83B91D,FEFD165790758DA1,00004988442A82E4,761BE9567B238EC5,C61054884C6EC674,C8A0CCEB80A06D98,BBA161B3E306CD1A,26FEC5716EA69C75,935DD87A773DF46A,BE1F7B555E77224F,38354822E0C035F3,9E9D65064213DA2C,1CBE65677EC7700F,D69B34AAFE544AFA,0000424A318BC91F,004AB2E15B862B37,222D01FC359607DA,726227DEA4839187,1F2536FD2BAD2B38,E4ACBEAB895597B4,E13D830CD45249DC,D858F53C0779F065,2E1D50B45E5A8D51,E9F9D4FE9970D692,2A88057441390502,8022650F13180DF1,00000DC7BEC6A903,9D0BA95F0A938E9A,7713F27CF3B52D90,E56E5AB34319AB1C,40D2F4B884F42743,24B79CD94DD46E0B,E11733EBA2BD5711,F33C2F6546033522,75B497195779C002,AA9F17BF4AA66D55,79C711A90C8CEF86,E6562645F9418366,00006EC8353198E1,9C7E59A6DD7B73D7,9F2F3BC1D4863B6E,6157017CC68D0319,D1A8B5BEF385490E,E7217E5C5864AD42,FFFF85523FA79027,A5B26C1812081B83,14EED3BEA37E7F0C,4DF65A51B6C51058,081606CDBA39845D,3722AF6845D2890E,00004EE5F39A6556,D40D2B62CFEA8BF7,AB514D16EEFE1A66,14A1E9690C988030,D6C9845B64B79812,AB416E2507F0BB6B,D471659B4BFEE629,C754CBF12926C015,1B2E6A6B09BF8A6F,7839E319EC525D98,8FB454C3CE39D573,F0EB3149EB14EFA0,000007D4307FF1E8,9BDD189F945E2105,EA2C9AD936DBABB5,68549346FF04F854,12DB56E5D40A0547,576C7CA8576BC01F,3E349023BA5B6257,063E20023CB89CAD,9F8A77413DF45C81,E15F65604A9C8E59,5B04DD6DC11BE487,9B0E8956DD71AE37,000023435E4C7708,5637A9020A26ABBB,E3F0782FA1F95427,CDD1D49E70DF371D,07FFBB00FE2B55E8,7F7A5173844FFE56,22CDD598B15CF082,2BE75C3BD925CD0D,24D454ADB2446882,F58CE1F767D2BD36,CBE41024233CF54F,C9C8B177B1CD111E,000052F51DCC6C92,FFA61A1E39E2CDB5,05D40DC25CA09AB7,7EBE5B79F4E8F9EB,E775D3C94DBEF0C2,26017E2BD143BA9D,EBEB8FD6470D358F,1007EA4DF2DCB94E,7870C6E1683DA3AB,98C7F01D704B248D,8D90AD4041377939,2AB7ADF233CCA2BE,000043B2A62EC660,510EDBBAC41FE1E7,64F3485CA2B5269A,D1EA3F19E7590377,59DCB8A741C40B10,D487AF373EBBFCCD,A885DABCB401C0D6,C4B3DAB003DAEC71,4C81AE87AFEF8DDB,2A526AD734D1426B,FFD5C9835CC47160,526D9F9EDF2F0024,000043E54E6F908E,C7DCA0BE375202DB,4F7342EF28C5AB24,8C5C34628DEC49A3,BCF621A526BCC20A,F7447F76D2787CAF,5FC4BC91EFE594C5,A43F36F8FEA63491,4E5D5C432E7AB474,4327795F257A9B74,D9A69E03DF827A1E,CC74BE6013B03B71,00000E0607D84AEA,1C2D8800B00C2302,AF4B68DB1C438A0E,AD544EC5AFECCFCB,90AE37339312EEBF,3A4AABFE989A1214,8DE804BB216708F6,34375DAC7B7967C2,45DC33BDB370BEA3,3DE60092FC1335FB,3569D3AC4ABDC6D8,6E4828C3CD742CDB,0000044F61372F6D,A89C221AF5D1AB2D,41B5568550C30D9B,9DA4AAFC4BDFEAA8,989CD53949517A6A,904212CCA259C515,D5C163EAA248CCF4,9E70A37E06BCE79D,D985DCC9518B691E,1F5CD460409EA8F9,FFE263D75310BB68,82F625DBB34B6641,00001007154E59FC,1FA7453909320070,D16E72801AC0598D,1E13A01E7E5C220D,C19CCA53727F6061,939B6272D4BD7FE3,0881931C8CA9261B,760415380716F7E9,842E0D3846707F62,E5C673BCDEE436ED,E45458DB68B6A647,2838A15CE4841CE7,0000309F3BD4804C,B1A20E295B8CA53A,4C78CCF2574974B5,2B35A10AB6A19900,B9F8837CF2A3E305,BE7FFCECD1F4B5A2,5C63CCC25B0EB619,8148D7576EA0AC82,192BA963BCCC5EC1,1FC62E8502F33AFE,C4B62EDB4C005A57,A7F4826AE33D2545,00003328D8D54B4B,F124504E3D3A01D5,61EB0E49434FB058,0F0A305CFFDE4182,5FD82BAE88BD5E17,F57C001E4FB309C5,DE63278DAAED9177,F3C533832E358DAA,511362D150A9BA48,E525BD7367997221,D365C6241EC7AED4,B8B0BE1F5E6E2B3B,000000776F8380F0,3C14F714AF4957D6,29AB233BA0820A12,02DBAEA9FBF2680D,1EC9FD04C8A3DA27,934F1133B7E6B9D2,F2CD99649B192AD3,141DD6D5A66D56CF,597A2B47773A2CBE,8FDFC650B6794342,DB1EABF3A9F6CF2B,C69DF48E858A1AAF,00005706755D4409,34A62E961F9B9DE0,7572B4B8559D7DED,CA5EBC23D3C95FA5,8E5C8376E9299A81,7DF2386F4A9C369E,FC76C48C47EEA42C,CB5A233E4D36B0D9,340A3A22560B2D71,890CC831E2DD4560,0A4350F040AAFE25,989374C50EE2484C,00001C27FEF22064,114267CFCE9A279C,2E71B4DD64F52B58,9D92A8758DD4C6AB,307166DBEB0DFD09,36F20F7E48585C44,E4E667275C6B88BA,759DAC2A14405D3E,50B9AC00E9F419BF,ED68DADC945B73BF,D92B5E6566717A9F,41C524799CFA496E,000051CA5C711471,19C43C034BCCBABE,E5D06A8B5BE27DB4,A38834CA1DBE3C9F,40207F5FC107AE6A,2060F4B8ECC0627A,3D227E5A1659BC56,5779066F82AF1C38,0C5FCA681B042E17,6C6B8C9AEECA983A,1B3CB207E8B78140,46D5701B2DA90F62,00001159D569421C,C4C225E3A6C5FFF5,A053058E264B8A74,0A69AB9614B6A54F,A66981250DCD27A4,75A594434B531A2C,EDFE8C6FCF9DA0C3,1E9BE6D3FAFF491D,A26FB8ACFD1DA41A,1120E2900E5CE7BA,D7DFF3890AF1F8F6,874CE6796B5B09CD,000010A71BD355E8,06E97959C2D29492,78723C94209FAA56,DA4DC67D0AB6EE7B,6AA820F9558A6317,F9D5A5DE22741F09,70A15C4175FB9268,478AF77DEDC65C5B,6562E8187C1C6954,CF1FA32382BB552C,5EEA1822A99B2EAD,4E908695EEE41B26,0000254F3565F620,41F42A3E5130ADD5,01C53FFDD377EB68,B8018AF5120257FC,EA37A73CE43C35D3,230F301E90F5AE56,B2576C89B4C66A52,1AE61AB2F83BD593,A37AA004B4340AA9,6AC29219996FB762,B610936828830A8A,3585674263684370,00005D8FA14E6140,FF4C1E8AF0AED469,E5FF22F4E4B894B2,7AD9411630E28B42,15A0EFC3608F62BA,9E2816896ECE4B91,A233A0BA4E383C29,A4CED9CEB36F7FEE,778E1F1B3E8A1D5F,530CE8E01C63434E,F024B5DA49C0E046,51FD4AA75975E113,000037B1FD028B94,852B6CC3C7AD9286,A9A2624A1DFC3BD6,E759A9F107086271,640D6F5E87753828,ECAFB6ECCD6410CE,F57546202D6789ED,EA529268F8D8EC52,C927E3FB94D8E0D9,881F3800F09ED1A3,EADCA5FEB15895BE,D7021DBAAE0DAA06,00005D75C516C3C8,8669C5A778DDE1C0,0F6402639C50467F,9ABAD1B14B91FCAB,FEA948BFCA8D8AB4,6FCCB77FC57332C6,6E7F31093FA554C0,EA8A7748233E2F17,29B6DF4FD9F3EBAB,DEF0455D9CD95960,951A8C459D26E964,9DC2972F2E640852,00005753DCB79082,59C645671776D5B1,4189E87062D391C4,54800FD6CDF46217,5CE81B6FB44BDABD,FCA07A0731A6791E,245E1A6F108DAD7B,7A1CF354E3EED285,AD28D1DA14D5AE80,4A1D541823CE9B29,49EB497FBF453937,EF2A9AA2A8FFFA40,000058F0D4BF10A6,7B998B3185B6C82B,2A3F42B09332BDAA,D5C48F2A1D1E2D70,4E53995CCCC79F82,FA88B217907965E5,0EB381F49B6A0637,F384603688D81F22,86132AA3DD5C05B2,1B45AB539D176E6C,39E62C69569A6288,6A740B2A71E11B84,00001384720D0B89,77C08D5A88EB4E49,DB503F7876CAA696,213226EEF8119568,0BD122D91B485B6E,DA82F248FF88EC70,4B52D2112FB9C033,17987A21AD7B5561,0B366F2CECF67724,137768775FC84AD5,220D800DF4822A36,02109FC48FC54181,000053F534487A5D,B6BC08EFB93E7EB6,2723B0022C9B2623,8CD513AE2A6B87F4,1311C552C5E0C872,A818C3C9B02F7C09,D24426C3BFAA880F,5B955C11DA13D390,8A07760C19134BA5,7619D0DE0E436850,414801D7FB0A1ADC,B3B7B0F9638357BB,00006457014F9FD9,ED39141A7D70B7B4,CFC368ABB288025F,699C9EB40C4A2A72,C2F59E771766489A,FE015AEC817379B9,B49029DDB9C1C7E9,A5409284E2B06891,F8985B9C50412548,A6311D2C44EABEF7,8F8FF3F98F54EB38,418C3BD62F482CEC,0000027FA0EAB9B2,9AF07F2F414A464D,56A747B06F4623FF,695DEA26C4E56B32,5B43E97B30A0027D,9768300AECAFBD44,E42A2856BFB9D0C4,CFC9677A81F342CE,3497B1E52B7678E7,CC082ACCA5B60579,9C877A68ACEAC8A0,E2DA0EE87D0F28C1,00006C94B5797248,10369055F7A97650,A4DD6AC26E6E8378,8D9A8A4AD59B0343,9D0973BC7B1664F3,14944FBA1FF602C2,1C80E57A82356A7C,4874A24DA908A990,66345D67BDEFC47A,97BB99C24CF9552E,93EC59AD255DAABE,1284B559FCB4DDF6,000012E348370A9B,6E2BE5F4CA050403,7E5EABF7E9953C6B,3624855D5D1C9D1C,2C573D0911D71995,7927FE7A7FE2F324,4B73BC9D126C5B64,00A045FA542DF0CD,07C9EB2259255C96,0C652117258B499A,A6FD6EB65C7F1740,207FF3FEAF865309,0000065D68CFCD8F,E00DF3F3E29C83D4,E3DD74BEBE71A0ED,CFC0F7425FDCB2AF,03396E99ECB4D979,0AA4B71E5E73C53A,6D8ED07E9339F832,55072028E76A46A2,E0E76E6F3915B578,65B87A4BAB71FC43,0FFD1ABF7AC25B0B,D4F53F2C34D9B0E8,00006D4E736C7B96,22BF053ADE813937,14EA626A40A10671,A9EDCBCBF37F4F25,095C520C01A7CC0B,8B20CC14507AC13B,2BD4ABB77DCC81B2,0F85B1068930AC57,D72D3B1AC772EB07,2C432D7E205FFCAA,7D59DA4F19ED11F4,881EC5C53FF58565,000053DD94E33049,F5CFEEA576416FDA,9D4D1D4A76D03D18,9EC43055F1D2015F,27028AB353C9EE5A,60056F5B30DF7ABE,9B2550DF0D316CF2,E1AE793B79BAC281,C9A80E3FCFFBC996,D229969730AB5CFC,573A1A88D7D4B74B,ADB6EB693619855A,000028A0640DF174,48746DE0AB19709C,8B0C2C6A2702AEFE,23309A1E7A8518DC,8C3A4924850C4845,2D12348D66713717,28952410D6907CDD,4513A152144CE8A2,87A78DFD119CE2FD,04DD10C4342F4BDE,839ABA8477AEC241,B052C47A2AAEAF03,00002C1A85231FFD,513D8AFAE5AF7111,4357AE918B69BD84,03D26A8F13B3C1BD,EC63B55DFA9F2E30,38823F591D4DF598,396D5E0498EB23DD,84CD83BE95B44498,B73FC58F95212F23,8FF1566F5459E4F1,E0D9B636EE05DDE3,C0BB4FB2B2B4159C,00000BF26CBF184E,01533309EA54C729,618A2DE8E723C6A1,E8B11CF9E2EC6F12,52B4E39A2A16D391,8FED8E45D15C8E04,4728047975336CE5,12BFF37F080A7C75,954D0387DD1204E7,C1F6918048E586D0,7CC3911BFD95C091,F8FCB873935BEE53,00006797513825C5,20DBA642E53EB49C,4647253AF1982B11,0FE89B9A1EC8C42A,C2DA22332E659F3F,FACF7655E24FE77B,363220D7507C8BE7,E10BED971229E1F2,2B132E9C19A061FD,CC60ECAD2C75AC85,BDA239AE589A7B07,D60A47F1AFE5E48C,000028107559575D,CED47DAB5F13291D,FD3980816FDAB054,6D86764136F0B9B3,FAE3A3886B792BC2,5056DCA8DBE8CB39,5B049FA6B860B433,E95D2924B510463D,5D8336383B672D2D,6F34BA6CDB80344F,D361E60506D6DFBD,7034DFBBEADDCAA8,000056C5C8FFC160,5D0B0A3BABE34B30,568874C278EDA8A0,985DFEC55DC0DE85,3233D965F4E233B5,5597B12AB107CDB8,09294DE5EBCB41C8,8D134ED4D77125E7,3A7C31EEF66CB76F,A81089E0DFEDA8E7,64367ACD05B61DF3,B8BBC8C0C14CF7B4,00002C6F070C3C21,696524876340C978,14639E4E52494D6E,F2194DB54EB29849,6434328B941B9D7B,A05A199E772FFF95,46595D77D48C31A0,3EB549670BB3A668,033D3D5491EA375C,7CD824CAA8A2DE27,D2AE90FFDEFB82E0,88E344756774C217,0000067AA5685C93,FD56D8A3EE7589AD,DE4AB1C39354CB77,C20FF624BFC82929,728CE8F66CBB5634,18075821088B7730,717AB9732DDC1AEB,5392725E8CEEE4BC,084DDD5E98FAE58B,279B6BA1A49DC919,22D1A5E2D0AC6F74,5FC0543C3E8E8673,00006258C0E46B9A,5A0C7D0FC66E0CEC,EA2533CEBADC494E,2CBE60A3350717E9,5A9115865C4D31D6,F54E1BA61888FAA8,F45E93FCC53EA37E,54FAE18B413884B7,B328A864A79A5043,F2C9DA12AF401B3E,8886FBD0BF5EE7AF,6922A66AF38EE140,00001C1DCB95C607,E459ACB132FDE76A,24E14B2253B1E1D2,2129D582CB1F53BD,D16E767BD37D94EE,BE88DA31E3480649,CC258901A68D4E0D,14984947B7BC0124,88E6590E58D8417F,2B40B7155CC4C912,87C2FFD839D5670B,4A3819D30EF91BC0,0000637819EC4EFE,1C498F5C89DC35B1,EB190F49FB2C14E4,48F2F080409D11E9,462B8BC5D53C2475,F55979CD90669493,8C53D5D28E841475,085CEEB2BF1F1EFD,DBF26D0A48B8F826,379C0DDE4E26C449,960A0ECCD1A39982,782F1732194BEFC3,00002115CCC68B27,9B9B5B09326CA2F6,BA877BAE42913699,31E0177363B47F54,20196BADC37C3951,CEFCD552A674536C,DB8062BA94F7CFB0,9B9CE956DDA6F6C8,52CB502E9ED493C7,44767BCA31592D71,AF2E802603C69A9F,BCDEAE977ABC2216,00004BC51E7523FD,11B51199CCE51734,F14B9E83B27C7E19,917D779E69E831C8,31DDA713B898580E,E8F24776022FD2DC,8C97B8278C1682A5,486B1C7E1624CA1B,04E59844D7221BA2,D77A85320F8F3145,59D9CE850644A96C,3BF589A9C3B654AA,00001C3E987FFB2D,E44FAA204DDCD39D,13E5E2512E29B006,9D5813D192BD5152,4F4FA0D64709A2D0,49664EC990367882,5F415C799690FDD0,4083AFEED83D6574,B53C77652BD726FF,7D29C969BCA1FEAA,DA0A130AF30582CF,3D8C643E658A866C,00000ADE492604EB,A330D95D051AC009,105E757F67E631BD,8E99BCAFCFCB91DD,A1AE9964F26FFD23,9A305C328C21EF38,33DB35C8981B8F3C,2B43908AE8F3171A,D1AB3CE0C1A9FFB3,B467F39DFB2D522C,DE9453767ABB4FBD,433EA7B102FDC9BD,00006B246146D3A8,10E2D7800041F5F8,69C733B0788CBCD9,21C821006A696978,61F2D50031F2B2B5,F8F81467324D6A58,53DDE2926B25E5A5,0CC90D0509BF7E57,C47BDCA77DD8BD00,D54C3736C1EC53C3,8CC60FFAB85189F3,52573F67C170DA37,00003F4638B383DE,DCCD402862199EC4,8E28862BC03E9C4E,DD897FCBE830512C,A6E5424AA2CC33C7,8B62F7A5FD7C38E5,AA2F911BE14000EF,0660580AD241C23C,7C6241063656F762,6F8A54569FE6E4DE,63DFBEFB0E892554,14E184B29A6FBACD,0000597F28A4288D,98B2D0D57154175A,C1F5540C7B37DC32,6EA345BC698E44AE,0B9DB15B8665D220,D3DDD2930D48A721,4E507E9E5B957656,C09930D0589853ED,1542A0CD101E94D9,04A20D9A7DB53D6C,BA57B7F941479D0F,FD5AAC18A10F48E9,000062CF301D94AE,5AFD10E06F41EB24,9DE06775EBF4AA52,8F2F8287099CE27A,72924387EC25D762,E3917EF7D00A4B3C,4A003B71903F9B20,38C4E5BA4563496C,34D719BD834E0E2D,1ED4E85714ADDD48,3C765DA03FD55B42,23B2168452A97C8E,00006D7224FC56A6,A3B63B1F6CF5E47B,0329DEE050CCBE71,2B40176F2A170460,8B431062CCA00F4C,D27EC13F03122FF4,D362F64E3ECD6333,1816DA31657352FB,5ACBBE527D8B66FF,18E7D551D1FD24D7,5322911A5950E3B9,6252D75F6186C7D2,0000035874B53B60,BED755ACF8EF6570,3168DF17F733A0A0,1367B94726B123F8,D12BBB428F29654E,8FA59871E2D7D5C5,79E293C5743B6DAE,6A555184FEE3BD2A,38CC69E4944F942F,D31373A79520E87A,79E93AFC943FD866,017D21EBEDFB38C3,000047F7BA37B134,55C047FFA86452DB,F66036CA59A6550A,9B9F57BE25B45CCE,C328EFEEFBEC2D05,6A0C82D074F5F257,2A70B37B6986B04F,1B2D627452F27B06,9339C189BAA448CF,D990DEDAA0B3E098,E018565440127E43,5ACB395AF6BB3321,00003B5C04A6D3A1,84FD534380E878DD,0DB1659909A3B1EE,7AA15B2C73C7307F,479F1DCC1168FA69,4F57B3E49DE61F8F,E1393FFB1B32F77A,DF086CA92D119BF1,5199B7681E48493D,1ACB8C829C834ACB,604936B0788AF12D,1280B6C9ACB0096F,000025ECDACCD8E7,33B0DAAAD0925BA8,AEA98DE74CB8353D,65F36D0671570695,4135E09903A15A8C,0B9484F806B62CE8,9AA20F9933CE2E3D,B5B8F068ADC0B562,26FA55381FAE9FC0,1AD34EF7E25098C9,863603D72AA42B16,BB14FE9045F10EA2,000061593ED22F2B,0BD792EEA04A1E95,9C944E9EF6C53B93,E8A218464B85E258,8095189AA9B5C04B,2FDCF790D6AF44EB,3C019A3159FA3A6D,FC396B356B095924,456BA93A7D8B6BDD,E8E8B2F0C15780B1,3D2835D08594B5EA,9525E812791829D7,00000E34DF7215CF,61C7E6E4D3DD3F88,C9603B7B8F733ACC,1648EDA959D8B516,8BCEC4ABEC4E9AC9,52140DC75929C8F1,C6B1B6CDCD6FEF27,F75012BF21663C7B,4D923E0FBC75BF99,97F1FCFD7B370FFD,3B26C8056CDCD65E,4AB0ACAB3E7828DD,00001D1E8A42A991,E874E70E5B07B729,22D75D6C817CE981,76E14EB0E59E0A33,FE3D9268D9038E6D,FFED56F11EBBEDD0,FD5BA9242646AC1A,9ECCD2B0DACD10EA,66BAF6C57CD97302,4F59C600EE6F74CE,00DA2231709EBC8F,05FC8147574F7DBD,00005E6E88BD81AE,079786B74D7CAAFE,7DC5CFCA204841BA,2925D00403B59EE3,B0B1B08DE454CD59,68389EA1BCB39855,868FBD68544FBF60,F68540CA940A92D2,373DC6040C6CAC6B,D383776E105F1791,40A6172A20053FB9,3477B29D0082FD94,000023922C067212,FFE3985B4B026C50,12AF310D9605856A,646677139CB2231E,18AF992E1B1E90E5,9E18FC2B19AD5B5A,57C54DD2436FA4F1,CD127E375EF36D59,7D0F69BBD1A56294,7BB1CB9B8722D6E2,0C5B759D7DC99421,48D1494E74FBACCC,000013F8011E278F,F377498B0E607C87,472E3FFBBC6D6F31,42B217E725463BAA,E11CC82677B7D06B,B66F52A7934F977A,B05B84545EFBCEB0,BC0D8290979E067B,A695066C9055C751,6AAC063494E4B082,A56A1223C7BC6DB2,3F8C57749902F7A3,000065113E588B6E,4F9BF60F99364AD8,09C7D03907A4FEC4,C39D50E6ACF815AA,AF65F3761FC5389D,127B09B07172CE6E,CE29810534D3D958,638C4AFF15E5FC47,208C88968FBB5592,498EF2BBB3FD05B3,EF09E9E2BBD26171,B1902F6C9B245717,00006F504468ADD0,AE506CF70858F806,91A10B0866BEFB18,E3E01323B7F710A0,4959F93B7949CFBF,521E45AE49366D11,E57FB75BCEC88454,388192AAB40C220A,1F73B0A510BCB4F2,3AD0545BAC371C8D,502CB1731CA3F2DF,101B5C5F9D407B0D,00000B2F22BA692E,E533C4CA1D497596,5243AE5ED742735F,5784442ACBC3DD8E,C593FED3AB230E83,5E275657C179966C,BDABEA17DA949CAE,AC864230D4AE89A1,796D8A2B0E67576B,98238C2D377F8B73,8FC5470F8C740903,EA1E9C0EA11ED867,00005E351C05B7E0,8B103D02AC0993E8,4AC9600CAE6D8323,45670267FAD14509,3FC5F235BEDE66DA,17223F02DB8C162E,8B551DE4ED7251BB,A1EB3F3479C71DDF,776C323EB45364B9,87CF15CB912E20A3,41F18CA86D26B260,8C79EB5D085D00AC,00003CA1D619EAEA,3374D7DE0E67DCA1,BE40475166F473C9,65B9008A94F54011,D9162B8BC45CF302,2C453387A8536173,8B63693E4CB98BAF,31EBFDD1D191FE61,1EE143D655AA8A12,44B632FF159C2BCF,97C336FE2AF074C6,16EACC73351BA3E9,000067C8E50F1D7E,66DDAE3D34790799,475122DDB407BF42,D15F6154E61F870C,72A41CEB32D798D4,0074AEBE18C5ED04,A980DF118F08F4BC,0F40EF9CD0FCFB38,8AAF37E103BDE836,3BD60AA32F1BCBB1,B4BA6083855B2172,FD8F76F59C014A63,00006A692F062138,7D8FC784E48400C2,AFFED52CBDB75A42,34449B9F5A70EF8E,8FCD1D472DD31C21,47D24078BF32FD11,AF4829B5E2C8D8A2,F9A00B7571FAA118,702184B499A52089,44AF4D28F7A5DF64,F3D9F6FD2685A695,23E76F686A29C730,000005F40DA8B60F,30E0939D22BA35BF,3F0778AF3AAB470F,A46037F412F46776,A156AAFBC6DD9049,A84A6030667FA249,7011F316A0542953,E27157742FBF9B38,A25EC7A03C7053D8,1B07A478C3127920,2B50083F2FFC8A6C,001C6EA452930A6B,0000009FDCFD6E23,DAF16E8EBDFD658F,3928BE980292E024,0963C2FDB3F413E4,457661827BDF7334,923E21D9F24837B6,44D7C0D1931E4E3B,FE7D3EE86CABD835,BA1BDEB8EBBC1826,CF8F7355BA1CCC78,DE396B49611536A4,32F9704E03FC68C6,00003B51D4C77C47,BDBA6940E9C388F6,0CA12C289C818DF9,1B7DEE16BF8FC4F2,CD6097C81AFA4967,8792FBE393DC180B,9CA500DFE628BF39,56739B58D9E749CF,8D127DCE674F900F,98672C7AEB830849,8106DA1B029625D2,60D7060D57C9C785,000023B55DE167E6,59670540B08E48DA,C906EB276A600558,56DED84154E74F0A,CC231FA39925F012,8344817DCE38024A,96AE7AC7564E18D5,60C242E7B22D7780,9DF0C8FB46E7A8CF,79C1A0B0C5AF5F8D,6CB41CF4E6FDEE36,8775966BA6D9761E,00003FC1D28C1822,29CB9BE18ED10005,59547F0C825F135D,596ABEB6667C5109,2E152DE1D84BABC8,9CB0DD21C780AFC9,CAF6D696D85B7536,CD94C06C980508B2,77386C8DBA0AA7EC,95C6416B3AB960A1,69EC085FC926B1BF,FC7991E4944794D5,0000419D8CEE837C,E5A2412202972D88,972ED3703510628C,3308AE377CD0804C,61441C4ABBEA4327,C90D0A1FB3070B54,0B68DF32DDFA5336,6E80DA355A5F8D68,F936EEF2516C96B5,8C330DDF811C715F,9DD79E5043FF2F6B,DF49839F3E5FBA3F,00004EBABC84A4B5,AD0031909E1AE183,F82AD6D6632ED84C,8EC62C986FA85741,99D56E1665B2553A,3C31CC66193B0A9B,DFE1E98496301716,A64CF731A26F5B9F,36A4EA4ADAB61D9D,E9617A04B9215010,81DDD88C3FA06576,2DC7B1B227D4C17E,000028AD6E7628C5,E3AF0D3068493A98,E0372F5683F3EDAE,6AA4F23971651183,52860DA010B47E3D,AB3DBEE97AB8EDF1,747AB9BA780A0C7E,22D4105D31DEB8D2,3257DD7FB310A527,F9BB47B04A4844AD,E7D6960960F00EC8,7B069B59198C9654,000024041955325B,FA9F3D4BB33751D0,23A24B5F86AD482F,B99A4E9C9CBF9320,5AE3A80313DED593,AE76A04173002730,FE55D36D3D7B1C93,FD1A3BF75B7F078F,88FC6633B2BBF47F,2E091856366F2A8A,71EBAE959C76F9CD,58ADBE4CE8411163,00006B869FBF170C,A4C2F705BCA995B4,4FF7C0CA73E3699D,7B7D57168E144365,29A3BE24D92A1450,D0B580223EEA0ED6,8FEEE38F0AE89140,E7892B8F44490680,F87B46F1524BE072,CC9DA5E9153C5EBE,F0FB2454E8480E3B,6F5870BB49B46286,00006B1F2EDDC712,65BC50836C802A1B,01AFD97FFCC51E73,C22DD283A5612561,6B9936FD074A1C4A,09342E883D13E1B1,99E0C5537D05A1EC,BECBE6E06C13FB30,0E7B9061A3DB6FFE,1B57CE913BAD58D1,689777303E169CAB,AE6E49A8E0CC3E7A,000048F6E476C71A,9051ABA329227E06,2967220CCDBE9FBE,529909FAA4AF7EC4,97DC82A5C82C26BC,66C7617FD134FC7E,C3E37C5D2E9A7A23,424BEC25C244938D,A6A600C9EE8B357F,0ACD0765A30AA0C8,E2805829F7484734,4A30110B856F5073,00002030D83C1996,73BBD3B8ACB6C07A,B3BC399E1598D936,ADD2E0BEE27DC1CB,F1C0D193466147B1,70B315C26EFBAAC6,29EDF055B1EE7F1A,DBB89965AFB5B20C,865BE71051D2CB5F,92F0B458368B6B4A,D149080CA26F70A7,3CCAB79897B95CAD,00002DECF5080254,C7713145777D4BAC,DAE0415283F7F92E,660988E716A6E01E,0AAD4CD94EAAD2C0,50C32A2E5B1ADAB8,283328920CD8CA1C,E558FB227802A898,296055D63B6816C9,FA36F9F7792157AE,2E4971C94A4F4EEE,6A7C39E69CD29DD7,00002EDA4C4A36F1,3155D7D307BADE9E,4B6464A430EA4013,499DCD9ACF2EC15D,B9E136E5C2101960,07A8CED3B84C2E91,4A70AAAF85372D0A,55D5FF75820AEBC8,5C11DB2E3981EA90,856726393C6BD50E,E8FADA5966680B86,1C05782FB845601E,00000C8F8CA5F760,8B578DB1D247EAC1,7F7A91A2CBC86A49,310CE2A2980536AC,AFFEBB828F2F74AE,1EDB41246144E6BD,5E175E8C7E37EBB6,C33C9CD8239CAEA6,4900B932B7E29390,60EF86BA77242B58,435D1D3E27B51DF2,669879DB132C7B31,000050ACE90EF962,BCE3AD601B3FBD5F,8AABA34D737A2D64,B1625D35053E777F,ECB598D141A015E9,8E397499ABC3EE3C,C4421E86EF50D505,C59095A8BE82EFCC,BB5799C4A1CE5CEF,52E21A846ABC9E58,6FEEE3ABE80E0D17,0BA729B4EB9FB0AF,00000DA4CC3B6B2C,5629A08F7D3500EC,F695A17477B49509,7F157B3479E2A6E6,704A0D0C2F3D1A72,1A4935BC0253E758,8CD11A9B22AAC7C3,1FD2048060CBEE28,FA5DB9EEF2A874E0,E788625342109AFC,52529D6F0B535C89,C6459EF4A79EC3A8,000038E4BBF5FB0B,6B9470B5C28061F1,4FE81C230109487B,60EAFDEBF56BCD91,F9F2C9BEBF63D13C,888CD3B674BF1F1D,DAD975D8826303C1,86DC486140A94FD5,B181F47B9B1DA5F5,17EE75B43D79F6A0,B72E7F67C2D8A87E,433CC7CBBF699F69,000019A7F78F07B8,CD9A4C8B7B928A56,2734AF9AE99AE7EC,121348287293AAB1,5E6ABE72243D1E87,CF595017C9A35D1C,E06506A83FF63EA5,C0F141930C7A1198,44EECE08AD87F2FB,4514B690E122B700,D3CCCB2F8EF438E0,D485E80B7125125A,00003CF095A6BE9C,4DF5BCC14B0BF42E,0413234D7C097AA2,F04C4D7C8C634992,234FF61F551CCFD7,0B0426D810B2F31F,5B34D12A9D453CB1,284F54374749523E,A8E8FF4316F9B943,310AF91E30C30111,BABEFCB95A1FAFE3,1419538E6CABC15C,00006E7765AD924B,3B2285235AB4FE64,D0C6153404D44953,68ACC9948CBCEE0F,523AC4A7920B456B,B51EFF35B858084E,8084EE1E21504614,B4075F3FBF7BBF06,B7C08D3DA24525D3,1B56083EF0C1CB70,052757B52B1C2D14,D5C196711526A98F,000014809E2C948C,18CB9C59132A0710,A64FD3F178DE42D3,DE152418F78DEAFD,10C56A0E4DA4E12E,4CA4A2181FD28D40,9EBEC7A6241D5D95,5684988D831EABEA,05B1F15B8D56432E,B07F07B78A4F5C29,F2FDB35FC48A9BCC,C349EE239897EFF1,00003CD537E7E676,3A66E29B28C970BC,BD561C97040BFAD1,D83D765BD4A6A62D,D94D8032B138857B,97EC407B4CCE7AE6,9884480E662F1327,A6217BFAA4332009,4436A3F9068405C6,821CB7B309025F59,882A5348726E0DF7,07FC455D2D721911,0000349A2C1470F0,3655533B7AAEDABE,FFEBD6C1207FA3DD,A110BB99C36CEB96,CE55A33E845B3498,7567C758552C84A1,4054DFC21267FB1D,6A1C8F8B2733BCC4,1D1EF4C2BEB18DB0,5A42830B73AAC370,1106E70935216110,E0F10B2A4B60018C,000048A03D7118CE,84421D4C89F2F631,6AC2ACC8579CBBFE,8DA55F79B1BC58EC,FC95C08A98242F25,8ABDE1785AA2AB7C,92FFEF8975D891CF,EC2D1723A3159EBB,357AC709AB1FCE4B,F9CC0263AF374D47,A2838A94DADED579,18A329D91FA18B8B,000043C8C0387C87,72E78D83B00A618A,E1421CC74FA4DAA6,459D9EBEC6389773,9BFF8840B2431C2B,FFA663003C8C9FB4,AE15943525482391,B892ED65C8347887,F7B0030863906A6E,77261021532A11DB,141D32729AECCFB4,15620B7ADAB0EA50,000059E9ACD38DFB,D7AE78BBBAED54FC,9A9010C7E9D0BE45,E28C43009B16B396,C4BAC48940E9950F,1A7D5FE4220D4395,D11EAE8F8698EB14,873BE0390E49D36D,B954EA77A38E778F,B984A99B6316D0F8,9E8786507CB5E71F,6792C8C116605D93,00002B76502728E5,5807EA3993C95862,E1E154D2055583CA,BF80D80EAFFF1A4A,6E99AAC7922E3206,1AB24FB94B76B460,8DD4732CFC46C180,0C1AFC5557AD4F69,1521057A9CD38968,EE52661C5B81E150,1B5DDE20238007AE,FC57799D09DA753D,0000619DD1E2263B,AFB5F208554A4B1B,95B69089F4DE0B7A,207F45B4DC1100B9,85601ADE396DBF53,F468BA00D6A5B1D2,82FFCDF7E8111F01,7DA6861169C4CD8A,3EE6689D5414D3E4,B720D0307177E9D1,E5452AED1229475B,9DBB70FAF790D3DC,00000C1637E36D74,D9A6B0AA33274BD2,EEAF984B9DAB9F2A,E46A971234453DAB,CD08E35AC43D296B,EDEE315104A4D974,EBD647CEC1830843,327632C647D09957,36FE0025333DF0EA,53B6D1AEA26932FE,CC9EAAFCC0E802A7,95D55996EB06FCED,00004EBC79BF8F8F,D585AE8CAAEE5EBC,31CBBCC227316188,CD7D73B4A17DEBE2,2583ECFFD17EC13A,27E884B700D68C43,8859D0D13CE912F9,2E15FAA1E3D6AF40,3BCA4974409BD63D,8C336E24BE6248C9,0DF251F94620ED35,EB5101E683A3145D,00000841E61BB0FA,230520E7514ED4FD,806B39A0A6519F8B,1AC1AA24D8148923,396B168F1F447484,7204244F7DA19F8A,4EF36E1490A7039F,7185834271F12ACB,986D1D3E892B5DF8,6FFFB74A72BB284C,04689B008543CAEA,A75E20C637D8A3A0,00001639B9556454,F99BAE13B4C12842,5777E29833CFCB88,F2A3B8676AC010BA,2B48EC2BED99944B,A4DB41AE60F4BCF4,65C144563699398E,5247C665534C057F,16AB0E4342029625,9ED5750D7E5A7562,BB2FE2C80A354F3A,90FE4E65DE79BD41,000003852BA4CF6D,B42BB233FD28F21F,9156C3D28A997655,5B10A057C2AD1389,FA30121882C29826,535D603903073AA8,1F34E5A4BF9F2DBD,D8D8DF990B7E5003,A6D068AD38F3250C,91E800CF0D6E3508,D6EB68A443EAA582,D571D50EC5BB0427,00001A03EAF7C2EF,E8708FF45B546FAC,8A3FA220F4A9C041,3812A75976FB2B22,1D377409C8552C20,F8F6F739C6866092,02822AB7B0690FEA,C1EE4053957D4863,5DA2F6820E7D1E83,8AC4E8B164C5D320,8A0D55D284A4D8C9,9E55A7D564A79EE9,0000257AD93E993B,5FDB4D24F3A9EF6A,B9A2450F2112BC08,3A17A84BDFB1E7D1,2979CDA20DC5859B,69BD4C44587E1678,FC8D6B9A0B120992,58BDFFB7BF6E026D,CB07202FCD5DD9FD,8D8D2C6A3EAE557A,1560504E48717140,B9B16E860B2D20FE,00006A3FA207EAE0,EB21CCA26C93D776,157ADC578A759E83,02F35863B7F9EF12,8892C3C36463D830,7F37484D25433411,A894DFE8AD552FBD,FFE6EF197D5E9A49,229CDE964928917B,080CB8DECB0304D2,241BF2DCF3E7D816,8EBB58ED0448ACB3,0000173B7EF9D85B,C2FE83EA2CB447CA,8F5610F4646EF28F,CF5405DB6CC689B8,1E5211D500CAB986,16633EAA2E16F33A,CE9ADD49B7D75D42,C26BE3AB846D240B,2AD492782FB64B31,4EF891A919EC3F46,86DF922EFBE3F715,36EC3496EAB569CA,0000314B40637CAC,6638657D53B27610,852086CB0CDDB4C1,D6867860DDB82EBB,C12DCB3B28A80396,85D92FA67F2314D6,4F45E8CE534ADC08,F85C1F35E2DA46A3,773C9B5A8E911860,BF83F658D3B2EAB0,339B95D64E6BA596,A108E0640F0D6892,00001466BDA0CFD6,F18EB1A520FDFA9B,1977569F45C56B36,2D806E179D2247DB,B827C026E355A3DA,37BA53D750EE2C8F,197F63FB3CD3AC57,D5B7680177949216,EF7A2CDAEBC001A2,AAEA530A1A963C29,EF97F0072B5AAD34,7048C1476C7F57D8,0000133C1F1FD6CB,74214EDDD5405B98,0079F84C5ED342E5,B6EE13302B8DAB1D,B004040255926314,8F07065AF51E2945,8FF5322860B8D238,1F6071FBFDDFE1AF,CF48B39CACA9F290,59648D30E3E4584F,C04AA924BA09DC71,A9C58CA956F5362C,00006D1D19571525,CE92D211C982C5C8,7FAE580A8727A5D2,7E3AFA328AB95C77,7F7B079D83D21F93,0E7EA5C486F562D2,E3B7F1CE61E27F4C,B5450C0626C110EF,1CE8A64729D377EC,8A04A48AA1705D3D,D47C031C9EB973FE,4B5918C6DE855C0C,00005F3B31DA0A5B,4C9C41F3852F4107,4805287E7A08CA0B,EEC1001B48567AB9,7F9AF80BA60C6842,565F507891D156DE,7AD316095ECE99D9,D35042644604A3D1,1088D4CF45354E15,18197D7E2977B6BC,D847B428BF594972,41D65683513ADF49,000026947577296A,53FD7D53D5B6BD50,B19571E8066BF852,5B8564EE357C33E6,A47D99E72C680855,2B08D58570F6957E,D32EA59E4010486F,5ABBB7228D665A4C,6FC5221365F00BCC,F94AF2B597FBB24B,2E7E29C593D06E8D,69B4B1BAFECB0119,00006D52CCD8BCCD,1188A6D1B40C5350,EC1561AE9603583B,C1B7EC45029F2586,2947E465B829AF19,FE7764498B769A1D,089FA64B8BCF54C0,C7FCFF67A8CB45E9,10D793BEC23ED51A,C8558D2DA2056EEA,18EF59CDECCD085F,2A165C70926B158A,00001E9DFB5A288D,9884CD857AF50612,A74A34F3F07559B4,E973C7630CCDBE06,71AE5FC19C6F0BD5,73214C8F8F5DAEE1,B868CA3906298338,E61A5C925A187B61,C1B4D8698A4868EA,9F7FAED4D1A09195,CC82F31A2D4DBBC5,610F6C3C87F779E8,00000A1BF8958ADE,7B3AC915FE43CB52,B013C909A9AEEBAB,CBB3772CB36DD4CA,787B2CF5249668DF,8C75E7181C9015B9,6161436610DBB37A,2FC3A9CB8166FA21,E7A5387B5574F45E,1BC39D8F93717761,77525C93016E3F0A,DAD99007B6207F00,0000406F63A4FFB5,187F0D438BD86928,E749924029725119,2D34811C964FE67C,D4A32BB461F269B3,EEA4912420AF57B2,ED3E98C424FA78F9,0296248818F97F00,B4BC23549EF57533,D58CDB4D03143CDC,8C4E0BBE334E373D,192F8B3FDBB575D4,00001C2646E9E3F3,502B13B043307C59,6BC548FBD519383E,49F932D9F32D6A61,FEB221F5C0C5ED82,44D5DC46CA845852,C4883EF69BCB70AD,4453F1DB2294F1E8,4001F217D6FC00E7,4E60A051B780ABF5,1F39EF13332C78E9,73271B20CC44A80B,00004C400C90F5EA,936DECA8B7D0ECAB,53ADCD4A5175EFCC,7DB03198C34E30A4,4C41D4AF915BEF65,5A153A566E522093,2AEE2A2E81AC57A9,15A20EF84935C9A3,53F509A33DB9DC5C,48BB1561EB8EC1C9,7875A0B7979E14EB,350449586782293B,000050CFF5A152BF,DC7DAC275F25469E,21333EEDE102C53F,BBE3D6AB6CFD9F9D,ACC01784398F14FD,B319B9EF32CB4E79,17C5BEE29B2BB081,8949B0CDABD8B213,D067392FC15A1940,64856AF47EF37DBB,C8B54E40CEEC404C,F11E74959D1D09E3,00002B4FD38CD049,94F009FC48196687,ECF15E8BA1C8E0C9,177D664E4487F4E7,12CB84B246D346A0,D8ABE12284202FF6,17F419C4DBEFD2AB,6D7CAC7637FAE84C,B6224B798156240C,EB30B45F10C21705,D9CC5E3878885BFE,71134C1ABA358263,00001162018C2915,7D42FFA62CDA5AC4,97245BF332C7FFAB,A88DB057A18C742C,64398398C9190263,5451DC33C3759752,F739685A48F71E9C,D6F9DDF2FA37FA59,175B1253A34FC0E8,A5FC29E3A32E93D5,8B08DD8BEF62E06F,240F9799C2B46AC5,000068A4E01D27F5,F9AA2555A287FB02,A6CCBB48D3D77D54,E46FEB654519EA13,0E1A331433CEE108,2C635FC684A3CD75,41743F276F500E24,10159FCEDA3C2C01,92147B31A3FE14CB,DA649CE683521198,2E7AE80BED2A4BAE,101BB45BAAD75049,000032C9C32274B4,7EE6E22A030D5E6C,041A9AF89D1A8D3D,DB4BA3E2030DE85F,013C4D30F0EEDCE9,029E2E47ED1E4EF0,6EF17D4A40D40297,B2B9021F963424A9,097D589B8C0BCF57,886B4BF1736F6B38,6AC3AFCB2E57ED22,8B3EF133E1D609AD,000041A7949F458F,6C08ADFAF73F9EC6,92DC325561F23A8C,8D7417392EFF4796,EF6777A360A268FF,A59B8DD4685E2375,BD6FBD8222608448,9638CB0604D14393,59EBAC4394A4BA00,EA86EDEA033B22C9,020BD737C2654C0E,FEB20D0ABF20B109,000064E8B60DEF8F,663ECFD819C902F6,4FAA4EAB6AA14ACF,D973B9FE264B6CE8,3413F0EF1EFBC978,D56AA779A8535F8C,C799A8FAEFC47741,BC7055470BB5A60A,A7844B6888E8FD43,ABF6A473D64D392A,5D8C79F9EAA910E6,4870B7A755290DF8,00001DB537244286,C311D169A2445C29,E964B64C5A32563D,8E8CE0BE8230347A,877B77D00811F769,1B61189283AEA596,7AC3D1F69B88CDE5,D2E4656DADAB186A,7263AE61EA77305E,5DFA07DFC8603478,EE0801AB83995C41,1DD75F293C9E77EA,00006005E504D65D,63EC1C85AD0D753E,8CC8DC64041BF4B8,3B11ED9CBF705FE9,696B109E52E592F2,1BEEF446158E93DE,155BA80E5CADEF75,FB611D1A9CBC58CE,B245FE67B5BD8460,6F64E46E4093E369,DE7DDFAE8B9ABD18,273DF149A2C13FD0,0000417FCAAFDA7F,AC5FF123B44C4F72,00DBFD2E71B9C215,3B6260598D4FD436,CCC4020D23EEE37E,BE2398F8A2BB5941,5645CF2DA1CD6F6B,97743D12F8877AB6,FBD7E1B5B8D408C4,BF4B7F2D5846D8CE,9B1265670AA503CD,C23D975E90F56CE8,00004666938B6316,EB9D08673423F50C,77810E0C59908E75,70CD86E87E34732D,FC500953C89D94FA,4F68BCA3A0633621,3F01E1867B3AE3C1,95A74E744251E637,FBE3D9C4AA0B0F87,6FE9AB8AF5BE5A42,D9E13B7116BB9AC5,992DA66390A92423,0000260D6F971BE5,3F62676828C38159,9F2C7991D33B8846,49DA77F0EB1758A5,F5FA8705B39C0159,0474BF5D8191C7B3,82B6BD1F2B6869C6,FC571F132E200A8D,AEE4D0217900E822,7C2D0E0B7DC7B1C1,D4B9103086DA2469,94F634F36EECE004,000030B0085ED01C,6AC87CFFD223A756,B6837592104ED972,7D4BCE1A2A2E3D96,4B3DB15B353DBEBE,D7A844AEF965D010,6C072906D3F5A564,C7164C1A892E6557,35549E5C125BC582,D3C5A9EF79B78292,D3E092B41FCB570D,6C58088D128AFBD0,000031DBF24B155E,A9C6AFBAC8B4D830,467EEEE06932CFF0,3A4634782E6302B9,F890020003E37F68,4D99D624F5F5725E,6A224055427FDEAD,637C297AB7A6BF7A,779E22AD20190F44,7538B0B323690437,2BF5EDC1AAF1A547,17E68083A36E5E06,00002F35168EABAC,C3CE1FC5DDA1773D,70A5EE48B74F4F59,FDE92DD9256DEC80,BBAC189979A13092,C2E35A76BFACB421,05EB9F165F9D5442,0B5C99608FB4DE16,B2811066946F5D1E,506239D7DBE0DAD2,5F05B9153878DC85,0BD5F494043EC887,0000117491F6B159,110B60184D49826B,B7804E8BE7496CB4,4B9FAD599D5D7078,3669DCE20AF8786C,DECEFAE44B9BCD09,5604CC4BD5E3BE44,EEF8E27118431408,AC3229D36FE4F726,5B99515156F6C41A,BDE6B3C37932A8CA,70A5F768098873ED,000039005E57C96E,30917D84C6E6D6AE,6062100452BFA923,3E2E0E59530F0C2A,F17B513F29D8C66A,63E852AAD3796FFC,F5E7EEBE33D7D4EB,93FF3E0E249EE670,3027B477F7BFA009,58725B422EBF7209,8E16C62E7406892F,24FE988909E84ED1,000001EFD2967AB1,B971F6A751DDF6B9,42489AC202AB64AA,7286A5D0701D6EAC,D9A1187C94C67F98,EC405C8086C2ACA4,E0A57032E9E6BCC9,E037B03DC476BF9F,5B15439DCB7344F4,FC8BE6F553D674E1,00BDE6572FF3B372,A7934D7364C1613A,000066639A1A5E8A,0198511EFC688AC5,C15D4121B574CBA3,C57F75E2042238DC,4E7CD9C39EC66CFD,62A7D9443CBB17DA,E69E7028FEF79392,59E1412243837273,F93F084568B87130,9347CB83B8AA65E3,106A823580CF687D,D5B9907716DE1077,000015F41B867F54,579F453C61DC24B9,37FF329278BB0955,4A368588E4A6BDC3,215AB36215762396,AD4952A9CDF476E8,FD0512C34D39097E,4FD1633BC0600037,7A5E44C2324D1A6A,4FBA0DDED0422CE3,C4C55FDD2A5AB294,E672D497ED9CCFFE,00001AB84DAD88CF,31366D349897D829,6CF64B7C89157719,5FD14CB2F027FE17,AEFE0CFF947D98EA,FF06D8D0320EE2EA,5E33F8FFEA13CEFA,B5A8FDE850532287,D7152D6CDFFF7EE9,A94CBBD50F1C592A,A5D397CDC033629C,0080AD46F88CAB96,00004F3053126E56,29DF52119AF79443,0D372505CB817271,B9E07AF5EAA062C7,CEB07223A400D5F2,1E108C7F5C69DA30,C5706AF28641B727,7F6BDA22C1C4BD9F,BB150AE26E9EC246,35B3EC79D88152F0,6EB0416B88CCC799,EEBC77B844CDE4FC,00002400AFEEC906,BEEC35915F4F9D25,0665C88C236EA678,57A37C90C6729FC9,F3A1E8942951A98F,5580BDCF9BB213E3,44CC89C063FED83C,64DA24C75D8576EE,A4D31E289143F225,2DB56D7C50FC642D,5E5DD7308F4306AB,8425970C81D6E6EE,00006505EBD423CB,A79664FCB7C3616A,E36FA209F36584E5,898F9588AC339E40,5A22C313D57EA196,678FDFB96E96787D,83F79A25B25E7822,E6A4FCABE8A16D73,BF0099FDD1C01BB1,8A65982787C3AF28,E468CBD4B16F4DFB,5A5A29EEA8D10F2F,00006EC29A7281DE,1CB5F05FA00D537C,D78792904A7B633F,17DB439449E257DB,B1016DBB16117A16,412427D926BEDECD,199705AF4EC6BBB6,CAE854FD102CD14D,8B45B866312F2851,46E991655223A4DA,95A354E86A00D35C,EC2C0EEACD525632,000048832A33FA87,3E7EBDD5FDB8ACB5,40624B5217AC056C,2A0444B180AFEA1D,2042AD93B03CF593,E69F2CE689F66063,A458818A211DA9A2,680DA01933D86777,C689074EB7DCF741,A902A8CBA41D2625,21895CE22F915F7F,56A4A6C76665CC86,0000305F4C1A9D51,A4177332C06D93E9,140CB59C011E4C87,10A47CA6D5AC2D6A,F23277C54BF08D04,988F736EBA6148BA,783E8A583EFA3FEB,62ABFD92F1A213B6,461A3EDF1235174A,4F53FBD1F1B05B4B,2A355FC7CAC9799B,25C6C7820554994D,00006802AEE3E4F2,88C813326D19DDB8,E9BA9A5BC1C438BC,816C5E67AB076E50,0CF93A2CF26BD6D8,6EE003A2265BD987,1958DEEB3BFA7DF5,7A57B4E905BCBA0F,A68524411E93C227,7E243EAE59D468CC,8CA56D954DDD9772,2F28CCCAF0C714AF,000001AA38428CE5,56EF2175EA4987F4,68A6BB892DE90D6D,CCE1BB8180D97A01,BFE3143E25B61BDA,173B9888A997E8EA,0BC45E9D4FF4FBCB,AF87443B7CBD19CD,56D99340A67AAC71,B10ED7414AFF93E8,8EC710FB4FC2AFB5,80D58AF7FD1565B4,0000209F67D66BC4,F41A948DCCCF8ED3,9B5C9D96F5C4F88C,BBDDB7F094236BBB,AE730FF3F5D3D899,C2DBB5982E0CB123,88031636F06531D5,25C1D185C7E32CDD,05696E9633951FBA,86CBE2314210D84D,DDCFD008584A4460,E483F77636A351F5,00004D871DBA3FC5,028B95A3FF98ED4F,4B49FEA67B60584C,FF7061E437AAB9AA,A192E5C3FC76B556,136778CB0ACD9AE0,4D7B814AC4C6BF03,B6A69CAD0393F17A,C642262BE88FADC1,618F6E087BD876DB,F10F8A6C11168B6B,6B69570C309735B3,0000294B74AFBB91,D8C9414C66B55BDE,2CC267BB3F5B143D,744236AB5FF99EA1,F107927DD4A7B53A,236295E217CB1B83,057B53AF5682B6BB,05D8EB05D07D1351,39245C7CA1247CFC,E25BF8B5865E8ADF,7D91845B42646E9F,181EA7A17301F05A,0000313D2DAB8692,6F7012F18A6FF1C6,E8DF176C54DE1C50,AD41F1AB3DC6EB1F,79059143473F4ECC,7EF44B4D0A7DBF10,23417644D02666AC,2E53FC699909DD9F,7519C9749EE38982,5A10070E81DDD419,56B7120EE02A01DE,AE704831BDC14671,0000458E2DC62320,1CC813AFCB25A5CB,A60C7CC6ECDB59B2,4650B28AB1A703BA,A83DF666ACE1E9AF,C33D542839AD71C0,5C6D560145D2BAAF,DBACC5364BBC8525,478F98E8BE3D5710,9E0015966B21C995,BFBE36C6AC6FE62E,779ED7F4B2A46173,00002250F9210A99,083B6888C5A255FF,1159CC9374DB92BB,D5A3E76E67D5FF1A,70D4A61468429421,2297F3B3DA531CA0,F48E44D4D261410C,2FE91246FE644696,F9368B5E62E0AB4E,C13DF8E914F68242,05EC3835521635DA,880C09FF11F1C28E,00000F8D780DDDB7,833D6BB8C258666D,B7533FBDE4581270,78A0129B03783820,31383258ED3A6F2B,BDF5352DFC630EBC,CD22A04E1BE0B07E,5844A1D63CDB5018,417F55BF3EE4450A,04EABEC5DAB9FB7E,4271254F5DCF6C94,6904322183841CBE,000057E73FD235B2,7FC8A8630D568D50,2319EA3C615F6AD8,9360A0D2F85E3570,714BF3CE31D38C62,BFBC73DDAAB9CC68,43E64187F1FE3239,767E525251695C71,4668FAB5C72678D8,9827B0C4C20E479D,E51CC07552216CFC,CCD20C3A23A2E882,00001B690D213D16,F046D5325DAF8FF2,5A30FC834F002E73,3A7062CB5A01196C,24FE870923D6CC8B,37C08CE47F65CDB1,268FAB678D6FA03B,843779CD7831785C,8AA2BE6F96FD0B2A,3E7DE215C9419E53,E3DC68BB17E37549,16DD3D075FE7D2AA,00003297754C0F5E,6A21B10BE7B5BA47,1035E3750CA22A0F,4C25DA5418634BC1,DCE6F82950FECC6C,66F02A958A84138C,5C8B26B0F9BF6306,DEBA35DB39B97683,EDEA66410C2FA43D,67BDD72B23F99057,9F75DD753E82204F,F7350B50848BF041,000059C5F65720B2,732E2C5CC7924A96,C2E4424F56240DB6,A57D63781AAE25FE,816DFE70506E5DAB,BF3B6B96145F40C6,AFACF2D9D59459D4,4563214EFFF6EB0D,EFDCEDB6035FE13A,8D66E78BA7308C66,BEC9360C7170A2E0,3B4B1AF8F82EFE38,00004B51B00ABD9F,F349DA3F63E03253,61C9E187E82FDBEB,376CCB6AD60A4F9B,BB8F904430D71C2A,F7B6A200F7B62E0D,07E73F71A6751B51,5E68A40C042E472D,34F8B4EF8DA2E0DA,B30C11986C3F99D9,DF5F69CEBCECE53A,439D96E99108490A,000032C9DD30C7A5,020881AB5B14EA1E,79C2673C02E33E30,ADFFAD2F07A28BC9,13D7086143168CA5,A8365385764F1D92,E25567649F992512,8C230AB6423EED05,CC106F7E747F592C,F0013173A1ABF513,D2916A4BE9436C13,5583F8E9D3F91BBB,00006282B1650C84,7ADC0F1E648272AC,D37120BD0EDFCBFF,A601A9AC65E22EAD,9E404299C42D6A4E,F3C759111F11E391,EF2C967A444743DB,335703E0ECB90B21,D61C4B83F52EC9BD,24BFD141022F0C63,75EB80B6646F5EC6,F1F37F9404D65917,000063C324BF316B,9F1FE6A5BCA3CD18,10FB08D04BDF83A1,44911BE46F983C58,0DB8E2CCF177987A,554CC75A0BFA4D74,F7E6D18C9F32DC47,F5E612B67793804D,B0532CD7996F2F0D,914D55128CF7F9A1,32265B453902FD08,15559031279C2D86,000032349F0408F2,30521F26285C7CCE,0B7D51FBFBCACE20,0C4351DED9ACFFEF,A7836BF68390AFC2,D2275B9C9A6C78A5,7020CE45512BA7D7,325052B7F0514858,CD741889DEC741A3,E6F4C970FDEFC64D,674E61CA6AD129A8,6E73F05C4BE47DF4,00005AFACE899D20,F9AC9A49F538A20C,E895AEC270F406E4,BAD5B05C6AA9CA64,F2AEDD29E338CF80,EC279EF03A57B9AF,20B17231DEA0072B,7F977E3417DC21CD,76883CB7EB75F9DB,9087383F794452DE,12E474F6E3179E19,2F2B9DD895336FC7,00005AE24C62F469,0385D1C7FDAD1BAC,EFBCB32F2B36FDCE,1607E2F6AEDBFFB0,A7DC6CCEF0C45A37,5F669AAE940EAF88,98F1972634CAAC14,2412E3EB402A47AF,F9AE5C555A499695,1789CC8CB3A324D2,D4BBBB86DC0F47A1,C74EA01E0699D0D2,00006C9D4DEA7D3C,B3D92FC1A3B54C5B,4FFD98E1516F33E2,3E9AD077ACBA6C7D,5A72D7724089B2D6,04EDB9831478DC94,ECBCFF90B8B8EDBD,9E2BA37CB0E42A67,0B4F5601749A1D52,713E73CC5F3B1911,DD97CDB8E4C385D5,3C935B8DF4ED6E48,00003D6357DD210D,22005FC14E18AE7C,02A91D17FFB71C35,B0782440ABB48D7A,E0B9AB1DCD566824,96C64CE880C5C119,96A01B221B43010B,D9C917EB4DB6828C,C01597A8B2B4C3C7,44EF0CAB13773FF4,E13E100CD7A76D2C,C52444D9AB3D75DB,00003D1BCD7BF7EC,5477B194B7A03A72,8693D9852FA9FC32,5619906074FA11E1,6A2909FAADC2E82F,3849013731435DAE,E590A7E8932E9D4F,9DF921D6B709E31E,FBF05EB44E6E1680,3A87EABE47A8D4B2,10FF305068508357,E45845566E9CED15,0000091E3AAEB2EC,34446B6335B3A49C,086C7A3F0CFF873C,8A2155B17BF80B1D,C5515D7D0B514CEC,315C5AB771C8B902,03B6C9D40F2884C0,A14744D633E5B5B9,F9ACB276F394750A,1D6A18EE688767F9,28C8F64CF5E43330,3A40555A17985986,00005FB510F236E3,F658C349D49C0355,7DF07A02DF0FD24D,84AD86B007389972,CD5726CCF1512252,337C2B9C43C77C1D,E016EEDD7AA6624E,DBA4D17E4C5FC6D2,96187EDCB613B35C,F72924A32C6DB7EE,261F8A935E4AB84D,BDA345F600BCC97D,00006F9FC73FEEB4,4912192E5C2A2C5A,D87FAA5EE3EC711B,C2DEF76B011F4EE8,797735AFE08349B1,3CB44D038D8B6859,4A30FEE8EAA73E10,FA3E1722B7A0EA84,456A9408B64AD66F,60E82637AECD7975,608E3946DC8A133B,640C677099355F40,000045CBBFCC796F,98373014D6AD6DF5,EF9C1EEA8A1A7A94,F1CA7A37E9ECB4C0,15B9F19D552D694C,A7147B9F43B2B653,884D4AC21D40EBF2,B099AFE52AEDA667,ECF692C9D0B3A132,18E5F1F80372A6B4,95E6A6D0789F6562,CA9A2BC96F343C7F,00001073D2D9E52F,C4FF40DC78DEBEAB,CE1C76A5AD3A86CA,F38CC6D366CFE0D3,D8E7F5779319C193,D0C14FC2F386E5F5,A0BEB07BA4066433,4ACB7792EC4BEFF3,882032B47F89D6DA,1BEC17F438BB46E3,5225EAEAEA89C9A6,E29BDF7F6B2FA6D5,000009294D9576DF,8E1DE691D33E8624,CBBBFE7E84FEB1DE,5294F3F3941EFE05,03C8ED32E1FCE38F,AC2254E5ECCB35AD,EFC22684C58414F2,12506CCC0208DE4E,AFDB7FBB0234B7B1,3ECC43B5879BF50C,17C0FAA04B2F7C48,7149B7C00BEF5D81,00005709FAE37492,F491ACA16AF169DB,53965E120DA57B60,1FEBA922611B466F,F258578C1417677D,88D89B18836B7C39,797852C98F149676,9DDE0648A372F650,A0184280C1E6A56E,E87F00A61D572AF8,1C59346C251D7A4C,869397E944D16A10,00005E3BD80FA3EF,2FB88AB40A1E9CC0,2476D6CA28E10C30,C6A119FAFF3CE8A9,622D2A6134A504FA,731258BDB8964048,DB66B7CAABDC6616,C9F3FFBBCEE00498,45CA83017E09A61F,4457443458DE71CC,EAD7C886526CBF77,550BA79249944C62,000068B7ABF0ED37,D48F9B9B7938C6BF,09AA9983505094FF,0F5A2E19E417D82C,6774772407A75574,8EF357D6B555AE9C,A530A903738453F1,8207F6F0011DEC44,C15F674A5D3D5C0F,1BCED547FB3445DE,DB572B4B79F4E7C8,C5B0BB3F51EC0FD6,00006DC6171A9A30,73C10E6917DDF996,25033198DCF376C8,76186869BB904982,F288EFEBCE248C97,DF730567C00D6FE5,498F370A12807163,B3C5A9D869BD0501,A80D70DCCBED24AA,1153422B0CCA50D6,3B726C74EC576DE5,6D5C9E6D0DFC3BE1,000067E502ADA241,3B08969565D4D9DE,56785B5B2D9076FB,118F57D8CD59A533,CDBAC8B0087961A5,53C18188807DA826,78B58C1FB467DE19,2EA422721EDD98C6,9E191713D333E895,5157D5C98A8399A3,AC7AE89EA5A41D56,F9809FBE151A2BD1,00003D6A67862722,677539F9F8FB7185,2A17E7734849358A,E689FAF244B06344,4FEBC413EB360CF3,1AA0490847E65BB4,A7F2A19A02D4CDEB,DA935AE5B1919812,3E3B625136B95A33,3A9991156B830FCE,98059B38DFDDE104,EE135582A7979060,000031F3195124E9,02FE25E5E2B92949,F6A78AB0C2B0E5C8,D90546B9FB700D8E,5F98140147AAD659,D264F6A295E5B6D6,7F24758BF48FFDEF,E9940293BF55F2B3,6F412E371F5FA067,EB1F3BD697D78475,DAABBEE59E15E90E,40C65279E12A016D,0000038F16DA29AB,AAB9CE7180E0132A,D0E77898F9F211D0,BD968A67650276E9,1BFCEB8CAB8E0965,DD5BD695D3396A7C,40F8988A5AD0E93B,A7127CD50D466CB1,930AA782C922CF36,3BDDA665519D5F99,2977898EBB556581,CC5471757B138EB9,00001DAAE7F23CEF,C675DA81DCED771B,0F8F5C85B5013AA8,2A0A6E50F688DF6E,014CEAF7C9D8D4ED,7781CEF4D99833AF,0BBDAF7AB10C6A62,1EC6EBB4473C84F6,18223ADD57DE6B22,3E0CD275701B13C5,F7F8CE58262978D3,3BE9C8040C9A7F37,0000149D56F422FC,CD4CD63D8ACAE719,4F50B8EE8232E97C,0ABC9B4A6CADDD36,7856CBA432C05C78,432A53189DD94A8D,42F3DA42933F3E46,E1C4FEAEFF39567D,B243A9C5B8E815A3,1BC13ECADB3C95D1,52EBEB1E984693DE,39D77C9CCFEA2C90,00006BE37759E6FA,482E03911F023D51,62ADDDF377C7EE1B,B73443B436982AF2,085C1256B7523A04,C6D5DABF3AAEBE5C,4ADF8227214C53BF,418D844A78F7A9ED,D524E737380C69EC,683099B228158C65,AB1C3B8A22169987,9ADC4424571F0341,00004930F0984329,06821DB8AC82885A,A6580706D15F0C21,3FAC7D55F5A69189,45AF8C7810A72EC1,B51596C328F0CFC7,CFFA49CC13803BAE,4304AD8786F734A5,6012EE4950E9A2BE,D0FDFE6D1F6686F3,63C4B549509B6840,E0ED2747B0900184,0000453974C31B64,FDD1AA43862ABEB0,BB631DE52B08D79D,A1866302271CF9DB,050A58A055E5BF32,11BB9D123EDBCB47,E487F5C25AF88C09,AB29987AF04D6EAA,9BFA2E548147222D,97C62E1FF0A89642,BA6435552310396F,F23808C7276E6D71,00006775A22794E7,6B8649E521E3DA66,2269951D1D398F06,99ED103BA734E284,2F171A9B3F91E627,197E487167B69BC1,A82D5EFEEA3E92C0,C99FA6FB8DE32F6C,05256BD2A6DCFCE7,FFEE0C4222087E23,601B15BC3D6D6A15,E9E498392227E4C5,00000C79272B11A3,85B01AB89E17BAF6,1D4A297D94F814C0,F0D4031BACE43478,7B7674E1CBD31955,04ACD094E776562E,7B972B5E8D6F8903,7C820F159898935D,DD1E6638463A9169,21CD471E003FED4A,FE6F8CB0ECC20344,784E110E7E4CD423,000048A8A84D4FAA,9B5B72A98CDA90B9,5F0A1C711A4A95D8,ECF7D8C292A96A29,7BBAC59077F53697,F1F9A7DF3FB16907,26ADC1C5F685DD0A,A4CF78B1E23BC09C,BF15BD284A7D88BC,0761179288554CFB,F0A0790D094164EC,5465A61A2805E558,00006FB962B9CDD7,D8D5680FB6B2C9EC,8196A6EC13D53CD9,61E6CCBCC191165D,E3716AFBCF6132F9,46C1BA950471FC01,B2E4E28287867CC7,FA488D68A092B9C9,DEA04B5E7E4237CC,BE4B438219CFF592,57E5E3886156B3D0,727554688603AE8D,00003AC3B55DBF4F,136C1C9F466EDBF2,5373F455A8DCD128,648D7026CB8863B3,0043A679B3DDE491,D03B78E410517938,46152815639DA6B9,93538D887F9D2820,B6D757B59D7C1E96,2998C0E3E60D14FB,E272AB208FC4E323,4FF32AEC94B5C755,000011BD8B32E2D9,F605CEEB66CDBA95,5ED4A7A333A75EE9,0B8A190FEEAA279E,79F9A72D94851F96,C035A967206309EF,5F8FD7FD36B827D6,F60C815E394D8788,C40738C5D3D5BBAD,3A0ABB0CF01CEB16,EDE21BB51BFE9B59,1C380B96546C5A9B,00001EF8FDA8DDBB,2B9E15BFDF9238EF,2B0399A7B37F982B,D2D57E0830F9CC88,3B8C6644D4589DA7,9E94E128FA2A5EE7,3324484329695212,A874FA3C6C53A679,4B3FAF98D30C1D2E,27075DE5CD4519A5,002CE7C77D99100C,B7657F0A158EAC18,00002FB4C338B13D,490749B5A6751FFB,43B67F3279769F06,0214DDFE57F611E7,C9FE938C24BF57A3,45BA1023F896E99D,F811D61973FD4559,E89EDE87B7B9F0BE,CA38D54441738CFC,B6EAF20C710F62B1,D4C13CD9068D64DA,30531915D9842FDF,00002D6F6EB5D86D,1BCC001137023C60,57282E7AA3D1BAD1,CF56FB407D7206DE,122AFB4D1CA6731E,9EC3A2ED311E5A5C,19693F7DEB0A7442,B9AB210824DABEB5,0B174FF5E05C02C7,44A38B47FD7ADB41,A738C743AC787A0C,8107CC25B03A1D9C,0000249A07A116B8,69132248A98BF7AF,56FC71332FA26F18,7AF37F03AEA5E7FC,87B9F2F30A7F5842,5607176097237E74,54F974097562736F,1A122DE648EC3560,DC92917D66DD7189,F47C4540BC6003DE,0FCD13A380ED1927,5F804916FB23673C,00001A7AFB35FDAE,85BD5252811F323B,DCE6726EA4660D56,28DD0E437E7E051D,730A2BA5B9BD1AE7,42E12CF1DBC15AF5,8070E1186970EF4C,4140AA92FF2AF8E6,89F88DE4564981A6,56A4CFF15E1BA9CC,30AFEE1B3621B2F9,1C6A27C2A2A40733,000009332CC36AC2,B1D85CED7458C987,D5972CE7937EADD2,06326D12ADE15D52,6A3F6BF64EF3B6E8,7669C6633D762215,8BD17C837FE86DEC,E8B60EF874495E9F,81D700B4EA474FA8,C79BDFB72B0AF8A4,B6E50504CD4CE91B,F22FBD77986440D1,0000464E93CC211B,B7E4AF71CB827F07,140C837BECAAC460,F9C065078707593C,AC64C8AA59CA0D8A,147BC2A027AC0F72,D9A993DF2F4F6809,49CB9C7D8215D44C,609A7CB9FB3612B4,2F259DFBF0828105,C00EC5916D739021,7CE4BDBD72029192,0000610BC6C669D4,4099863769553B39,2F8E0E22C2C678FE,EC8805819FCAD8CD,83C469A8A91EFCCA,47B25AAC51B41C3E,DF9AEB8A0A02B2FB,D0F0CEF8EDF320A4,6ED23BE9F2A64652,D0125F724BC580AD,59A5EC0390086CFF,5276841B7FF35C28,00003FDD2CB3070D,B057998902140D75,6626CEBC61FAF504,66DD759D57BD8485,8C616DC3A9E822C1,7D5D813381551EDC,26268D3FEDCD91AE,6C0527BEF9A91681,52D08C16A601BD63,867251B36E47D55A,1D10F9661CEC7CDD,CF23773461172743,000051DF0A0A0B77,2AB2C550C6897A59,0EE5D584CC0FF824,8FCBD65426C8AFA1,EE94F896C4D36036,D2B6757824961B1E,5BA46B56EEB3DA4F,8D7BEA1B0DBFE75A,DB1B7624CBBA9013,329BB2D922BF4668,7A051BB93C51937E,7FAFEB01D4D1C0BA,0000200415811DDF,60FC0AF82059CC4F,195ABC426A9E6093,1F06AED42311310B,F6EC19125BD287A0,8587BFCA8E71B597,7233BA5EDD5D2828,B99495D71F035ED9,E905C09546DBD071,F994ED6253235E14,20AD2057CD6EF3A7,4DF5FD5C2399C4AE,000047A034199649,70DA216BB6203F6A,69C3B10E283A41F0,41B6BDBCA4204172,160786F1971A7134,7D22B56D110DFCDD,2C971980B59F4BF2,CC132F07E48060F9,98AA34C13A76D404,7CA36B247B32B176,356010A70D439A11,E705F042351667F7,000005FE4F9E55E0,21980711B617BE7E,F447B2404131936A,B3730DC5A4136B7F,DD6F59E72A51B36A,A8B33A181FB5338F,15EA3AA26261E66B,6492280E014F26C3,99C75937C058BF33,2BAACF7C8F8DD53F,7C8511398BE19E44,F1FC0144B0670938,000005C3C60F93AD,E8DF786C3794DB3D,719E7D0A1F320BC3,CB13CACA57A3AB26,B9D170B7EC2D42A6,391EBBBF3D0AE2A2,B51884F84BF04041,2C74BE3CD70C7E6B,BFA717ED59809999,7DD5FDFACC1B66F1,73AD7649809D5853,721669EB76EA3F2A,0000606531281C8C,15B9A6B90140CA1E,4B9238F5966A4CA0,1371C038996E631C,9089EB93F6744DB1,2539746A374AFF6A,B9D1CAC614FFA998,3B4DC8E06F31C10C,12F7B69154E9A3E4,470F8240F3BCE39E,F21F63BCE1BA72C3,6AA13B5DBB81F72D,0000524A79F6093D,39CEA7EF1C74C433,78BE146FF851FD4D,D2BDB304DCF326D7,89B9D46ABAB0902E,6EF298078A6F9A5E,1DA8E6F121DCE4DE,0CA045925F073C2C,0B1231F35F45E10A,CEDB384E3161BD25,2C97573C03ADCA04,807A5275F1120426,00000B0F9F467234,350CE84C72E8E8F8,C3041F72E6D71BAA,80696B8E7331033D,34DE4B71F92EDEE4,E9B0C77932514501,6D2F10AD7CCAF322,5F235C93BBD5A820,AD6AABD5A0FCA4E1,8CEE55301358A73C,76F6DFDA6FBEED99,ABBA6680DB6967E1,00000A894A392045,4A0E6C73E0DF3138,70DD83CA16F5B8A1,3305AFDED55E2161,2CE033E9D6A15D2B,CF8490BD3FE40317,DBB20F8B77049505,D8208C3A1D255D31,84CD5F290861CF81,C21C4E6DE9C9200B,5A9660593975B591,FAC4278BA270FC52,00002EB3AFA62D8B,C6C28C51A2866A24,5F252BC5E06CC616,DE737D0511CBFCCE,EEF193FCAC0FCA9F,BD263B81F46B41B6,59023237430A5C42,4F19459C7C14BCFB,55D54B5CC593620F,8E2776FD466D04B4,1CA9AF39F773008C,DC987044CD4F9E51,000037129B3DE9DC,ABFEDF6684A4CC81,A996A542DF8D053F,8B6D87116719B022,36D1CD339A3772DA,E4E53FAAB4954437,E6165C5E70D76B61,5386F69F02AAE951,5A843C7419934F6C,51F93CEEE71FD778,B382F34BB1D25155,F2D1B4EA3F291D5A,0000543FACB29213,C7279F9C5228FB0A,C6C526A9682A0980,1C95BC6B8BBBB3A3,F582DE11F083D135,0A4854D585462341,3E290E3AD41BE610,6D0FA3E985A83449,8825031BBED74D8E,8BDC21C141824148,F8F3C9C57C08F8E6,2F7EEC5C71CFC318,00004E985BF2C65C,04553F43295D3803,33D94ACA9B848CD3,9094694D46DE23A8,28760E0F13705AD9,6FCEA7F87CAC2F90,B83CAFF70E3B4464,CD7F1D3A358B95DF,D57398662908D751,C93DAF9B1CB52776,45709F3F786ECB45,5D3709D0B6E39F5C,00006C75723D0653,FDE29AB5436DE426,9A1B1D61B4294C3D,6CAC87EB91FC9318,378EC56F9DC636A7,6F8B93532DBCD321,D6238D76DB36C174,B0A9CEC0D0F8D7F6,BF4634E1BA75350E,6B6930324A2E9344,265726546BE8BEEC,79B3B0DD594DE8B7,0000167EE222FCF2,E4D32F1335A88D8A,9893565F35E107BB,0E035C9484BDD63C,AD339C727702D374,3CBF021D1B890EF2,61C13638D613F0E2,006481907EDB0265,B31CCB8069C4A62F,0039128D04B76AF7,92D8C0237BB59C7F,28678171CB0EDAC8,000055012AFF18AA,7F69AE2A2547EE7B,D9374F60DC47AF28,85F504AC6802D450,6098C85BCF34190A,FB3DE6DAE68CD939,38C537E7CA59C324,54AEF1B3D55483EC,E40F257F24DC20A5,4E6FE1E9F1EEEAA3,5C8AE46DAA2AE9D8,3F9D7FD4A232D59F,000016C4822305F7,7A089FCA7FB2D7E3,95B39449EA811B5C,A8CE896A7D55FA7A,F1D3A5F632FC1F32,B55312BD3F4B54ED,1A75222B441D851E,9F0DF4E11C03324A,67B7F29E83D440C7,2D275624D2E86B79,0A44DD267A597AEA,8162E567E7D2ED7F,00001C961F7A1DC7,93B3A7686C84C045,F728EE716F853973,9D46CEDE3984D01B,AEA956E491DB5AD5,9CB9C63E618723D9,9DE439D7500F72FF,B0FD4942C9786C22,D781A02ECD175C71,65A46E7493FCA556,8F071FAF97C5B594,B7D9BCB6D1172E29,0000250A4B8A2C21,3FBE20C7B8814D5F,F6B96861C97E4466,B77A583EDF0AF98E,D8756D63BF9AFD92,988AED986D758E5B,858320FB0F5BF232,8E94E3244F82C8E1,0C2CE404B931D295,46619C355FD10321,DC72E4B8E700D176,9C2D947EE97CC57C,000040263924437E,6833FD5521A9AD74,3FE4125C294AB463,3446286BDB70F0C2,3DB4C3EABDE967D3,4A96A34C85DD6F44,206B67070AA3A3B8,3B78F226ED37E5FD,F3F3AF887D58B894,140D186ED4BC7B9A,F7A8311ED7CCCB72,9C62734E6ECB9C63,000052F6E3B73968,574A009863B4FC3A,01E23481621CB34B,952583FB7AF18F8C,8BD0EB410A310410,A6D92BD68A024181,0CDC0462D8470C55,29A9445993BF3FED,9F7691ED41EAA27C,E2B35F878E0753E6,A10B03C7F8FF7378,168C040603289967,00001C4EC722D84D,585515667F0E583C,DE72C5F81AA8E14F,D1F0FDB125ADDF40,93808F707059BFE5,D6F23DD23B6B88F2,E65CDE1A2A24E55C,B670F86F61A30FB8,23446E2E25A4500A,A86BA42E54E416CC,173E561FDAB7BC87,8E54D8A2548A10CD,00005EC49E34BF5A,58B0CA0EF258490F,A561CF2C55D4B2D9,D8C72BEB6D0C5CAA,99AAF2DE33FF42EC,B8A8D9016E20AA1B,B127DFB22BB8C102,C28E639031B283E1,C1BF2C983FD854FA,826870500DD2DF31,9D59EB38804DFB9D,2CDECEB5CCDBF7E5,000057BF6B4D229F,DD55E483BFEDC4F6,C94FDEFB48FB88EA,6491E49ADE323AAE,BA480AE0818C19A1,6C2DEF1B919CD8E3,F22F72263AB7049B,C6B2D987809F3528,74E2BAD05166E199,B1D7560929D57770,2F4225F86AD3E239,524468946ECC165F,000066F9CACB0695,0837F860B6CD0248,22469272105052CD,8EE984EF04CCCECE,86062E2D433898B8,917A564608CDDCD8,E5FD6527C3021182,B91701761908A121,61A11A70A8A808BE,9DC353306C9A0A66,E216FDD545087903,5B6A72D84BDD23F9,00001CC8AB6C3E2F,53AD16A09C50BD88,6F17C6BF775CE4C7,6AF5191BFDCA5A27,A53DFA3D1CC23E72,B1E71F20B4632315,30BD4ED8A26B6AAC,C0EF18CDAEEB37C6,F5662314D78FA586,BA2E117CE031A12F,28E16A497B12A7FD,5C9E5E0CCBEDC424,000033FCC6A05BE6,8337B658E3BE8D6A,D6F237FE253E5653,2030294AC3F82A36,3EECB8A1E388E341,9C3F967C0342ABC0,6DD3F7C8282E3EC9,B8FD8799627F1C9B,C302880FD0BBD448,98B2F7370FDA5172,2E1CA562BE729335,59D52E0A61FECFE3,00000716D89C5F23,11402B37A45E2A51,89E0FD043EE877F7,C50A437369165831,875D45C55CC3D6E0,80541919C3150C48,17819BC89BAB68A6,60F3000093C8C3B1,E54CB7AECDA58889,CAFA972219020F0D,2A929961CDDCB81D,2EE9AED167263EF4,000031DB3E5B8C69,CC127D169513B4FB,E7412A9AEC23AEE4,7D51BDD7280E902E,98559C42F02D0183,FF802D2C28D2F47D,AA1653209868DC24,B962C5FFDC1EC7A1,ECD080D2CEDAA5B8,DC5ADE7B0AA774E1,C7E70E8E601C30FF,918D081D5FB6FE3A,000048795C6D101C,71A48C205EF2BE48,2E8F09180898FAE0,4E28CB607A463DCF,E574B6EB1BB5BB6D,12BB918AE19F5D49,E5C23C993A48537C,E582D2F277102456,F21CF6549CEB20BD,366C91C883C65901,216BD0A07D93DB40,BA5B7C9147E20BC4,00001FF22F6F71EA,6D22DA9DFBAC4438,70159BBC324A75C3,87DD03CCF87E274C,55F15FBF0607E3B0,780BB8F5875836D4,9F9B59248B8E734F,6C260E53896E4823,AA1132DE35F08373,7F2AFD58773EE233,E1B795E1665C52FD,4E6C724E45218F80,000043BDD217611C,D91C0DD452EAED94,A8CE31CEABE68232,B2184D1F68F5FE5E,D5424371665EE7B7,78C7B200D274A156,D1E668A6F070A92A,C7081E07667FDF6A,508B4D47C76622BD,5F9240BEA94F9C68,41A590C450ECDD09,9EB058CE22F9E218,0000148A867E2E5F,A93C26FB5D69AC72,EE5FCB62228C7A61,21766475A713CF38,5EEDBF80FC045C2B,D112C2A0A72CA8EF,F107DA3E526D590F,88AEA68594875017,F399E1DC3A03973F,F45F8A5F4216226C,5FF59AC00BD6E6D9,F20E10E0DD2956F4,000013C22506EDBF,AEAC241C35C9430B,80B516F0902206E2,04EBCAB409FDF678,0F439D3BD2B636D4,D4975E3661318BA2,840D872D64F6288C,AD86D70D30385D63,25F6E066EA1CF4F0,FBD57BFE23487F9E,4322D626F848451C,02773FC06948CF46,00001B5A1B917DCE,5BA8F1164692989C,9F8345C9B4B90A24,9019CB8011B80D9E,A81AF79F9DC2CB42,D1CB0090363B6B77,8D4E6A952BC20B2F,DA87B10D47832F7F,766A77F9A4187DBA,30882BDD426D3F24,42C5F6EA8C63BE27,632BF7A2D1FC286E,000036B957CC61F0,C20B0B1581BA40B5,2D97DB0A43E3D2F6,A6F1758561EECD5C,FEDC896BA57A246A,714E2CD506B840B9,D04C56A847E0F8AF,CC3E826043FEA6CC,079E8E13F545BC48,EA6EB1C7E91C0C03,FAE608F6BD9F73CA,2339C5B2F1EE7BCA,000055122A38BECF,EB1694CB5BAD27A9,AADC96AB72EB76F2,6ED5EBEE6C3B0754,A2022CB851FC83E2,7F40EF2BEFF1D81A,50D3A4B88DB3B72B,A77B23BAA2FDF6DE,3AD543A79F094BDB,E53CEE5F765430B8,3CE2A3AF8526D1E8,0F8992D75E047C60,00004E423D5C19A1,F5C32FFFDBD6C8AC,DF398B8786370FAE,044E771D4BE9601C,FD7E57E7B31AF05F,EAD7A490AA7BCC81,CDB27A5B3B361AD9,A7F412EFD6877BA0,55871A3EA28927C3,23339521D29D48B1,14E0783E9AE124A0,A7EA265A65357388,000050F323F15A83,A8531CB66A296096,761CBA6D580C93A5,1A8475B04DF0776C,172E80D97A52F923,9B7AFAD0DEC79435,00334A5B39F5AED8,94972158E331C901,C62915ABB96C25A9,C86B9CF3C1ED0F9F,49BE16437F1B6BCE,261BD757296F7F60,000009A185042ECE,CCE7E3F1009D0FFD,6CDD9030C39FABB4,A30BF47F180EBD76,ECA136E4C2D85908,A9345F79D6372A3B,219D47C8BD5A70A6,588BCBEDCAA77B84,85F64D1D54EBF859,BC287BDC8F3F02A5,FAFDA106F4248C56,ACF687862884879C,0000190C076C7070,53E74F70B8644717,BEB078DAE7711E1E,B9069E259B34A638,A318A7D020E73D0D,0D4D1CC7FA7E9EF9,6EE817F297E1B8DF,FEC759570B8AFB5D,4A3C35EBE0AA2E04,6A70F3F82A48C274,752B741372D22C39,47D1215355925358,00006F87AE0A0301,D04FF279D0F9984A,156DC73F47557E99,1A59C28431F9BAA3,6738513757E9E97B,17E543A98AAB9206,72619525C3616683,5E2783800F37FBAE,457756008DE0A457,CE21D707D4194A1F,4A5AC24172A427D1,5FCF0AD23AEB448A,000066BBD0ECFC70,B8611F0791E6607F,C11D91EBC16DE8CA,8DB94149D662BB6F,48EC125902CB561C,41D05D06E17850CE,62ED6A799B325928,03BB9E3E708AB74C,490D7BD9A88CF95E,DD5BD0C90BD59841,A6E7BA205D849FB2,66BF3E8E4939F1CE,0000524BC6120F11,96C1671F6595D880,FB9B34E697ED52E4,F7B8284CC99FECEF,4C9505052489E50F,CF5752DF98BF88CE,24B56CB7ADB60AF3,4D37935D4439B85E,2B507074BE5114BC,BAB034FA3EA555AF,C5E86A436181B692,3FDDEC9489AA2545,00001588B3F63178,0221B18D023C0C9C,75A1746D22B3C273,56A4B41D28393E9E,38B4364900F8B9F3,010CE00F5B19B62E,B99F16D188306C9E,CAE2AC1CC60B8362,39D12FE2E2D82EE4,7BD990E31E7EAB37,5EEC5325CF486963,8F06862FCB9F5A64,000050C7029FD71C,43A190CA75CE3923,34566A6A694A68A4,4F31FDBCB5893CEC,6416DDEA371E9653,83E5A2FEE0ACDEEF,936F196C2BB18B1B,0B52BDBE449A8558,BED885EE0A5E2FAB,96112EDBFD8E3CCD,6D875E0D41C7471D,8BB17D6B301CB580,0000572888176520,55A631F313705B8B,4155F42887E77A49,26F60F28E97878B5,5AC425B806500611,9BA0BB6779529839,47D3E724E1D2F08D,6A43124F507D3833,1039AC54293E710B,FF6BAA674376A9C0,808E01D2C67F32AE,E3C839F41BC1B845,000062020A64027C,18BCCB41423764CB,FC0B226512AA9C56,2E6B7EA31A9FEBB9,A48CD74FEABB967D,10CF7610A0481AA1,03D4EE3AC8F9B94B,02F634FAC5CDA792,F6452221FD731C6D,AC7BA8B57F672EB4,938112D1DA9A83E4,1C8BBBF5C3523AC3,000012F49253FF20,DC7DB95F4E8994E4,C52A742332B11F4E,36A7939558CE4D1F,958FAAC2C336736D,230D767EE32CA203,0E8F8C61F0691B0C,FB849674B86CCAB9,27FFF286DC4F30F2,D0239EF897D3113B,3A9C1C1EF07DA2CB,1F7173E3FD0AEB91,00004113560C02F6,D0595C5CAE6365DE,CAA3C00CD880DEED,E076BF596C304A71,FB6EE21987327A69,9D402EE23463239B,AA563E101969B5D1,5C4558364FD25BA7,39024247C2B92B91,45941682B42F7014,8EFDD5116C3E87DC,BECA7D63B3A3B835,00000E61119851D4,F9EE298CCB07C4FD,06DDE07A5B765D3D,809457CE9B215806,3212215038CB6364,4F0304068AC64EC8,D32881B40D41022C,150CB4B63239C875,7DC2EB03240F729B,AF9D17D6219D4930,E9C534B1C6BF87BD,8438533430D9742A,00003B496460BAF2,932F0D38EFE185BA,250B2D632499736F,26E986275DB62864,4C0DF706A66CDE41,CE2210422EEABFA4,DB43BA45F8A6826D,95872CB6AF26BBEB,8CC1F1ACCAE56A63,B2C54D02A646F78F,AD86E564A30F439B,15E8789D128ACA0F,0000661F3B634BAA,2168637956D00D8E,3DE4B4A89B3EEB91,8D78402CEAB84ECC,61F4DA8CF278F7C3,30FA3A341BD6D4BC,6F6F47017B524A79,71AD5D100E1D3FD4,6AA316B26BDC9F44,8F7DFCFDCE13FBED,B26D59157E5ACDDA,DB171D0C0D3F6316,00002149767CA0B1,D5105546710F61B0,0770F399CC420E52,CB0A49DBFCD27396,69137A33A31E22B5,E85265FA8BDE429B,BB703DE2AE1D078D,DB88E0C87599BF12,780E5B8BBB669F32,6AF825A6E385AD75,E62325D250662D67,42BB61BCECBE88ED,0000447DB3EDFBFA,23CBA6F7DD7A0320,CB52060F012CE738,B90A7B0652CA95B1,EF07345596FF043C,341ED2674F0CE68C,430BE77A7CF89D6A,E3EE28ED8ED72D8B,A9A64B20463B758B,C2B8220ABA61AB5A,0CE49CA3DFCA6B57,30C192E55FF31398,00004A2DA9B2F32F,1C6AC0550C2D5FE7,017F8CAD9A35E90E,19188D2FFB3C034C,86209293348EBBB0,E21B3E2CBFACAD6C,0B161C23B1E6D1E7,4349D4274CBBE535,BDC2E11BA23A08EB,1EEB8BD5CFC6483D,510F8B063DB59AE1,F91796ABE0233301,0000272E64477769,BE2BDCC49FA4D961,0C4E4D3EB495CB05,F1F50B1BB186CC2C,7448457D97D6231B,2BAAAE5C6B56FD76,2EC17FC178FB2A95,C1820A7207BD7CC2,5381C6C07BD0F06F,3A6AD88086A50AEC,96B3D67B0BCF0404,66110DA02D1C79B5,00003101C1DADE10,45CC104D2E32DA7A,46BEA974193FC9B9,59624F61C66F15CD,F4B8543DB01ED113,67582729A126C5EA,40E17F99FC7E5EC6,4DFBA13C382D70D1,59C7797580635F23,05B9412B2A4376F3,319FEE67DCABD11D,80C3A700C589707B,000037F24E591A91,5FB34544EA7E23D0,A422DC41C9DC3A8A,62A2243BF4032B28,56118D5D2E9A2398,E5581435BD35FA84,C72DFBF6A3EEF90F,97D9A8675C3434AE,34CB5D66805CBC43,586082A84D0E0D0A,4B64017B51D63E10,E7ED30704107C0D8,00003239C9870CF7,D99FE085129F339A,BEED7E437FE4B91F,198E08321E600FC3,CE7A330290DA8351,881EA7B207C30B0A,0554B74D3A780A4C,173D8B2EAC6614BB,47672F31877C1ED9,E4D034DB8AF97D26,FA95CBC26BE504D1,9B09B8FB9B77E2F7,0000595D75884F96,33B68BBA3F235CD9,C580B6B6DD06B092,76D4BF83E04F8BEF,7C59D74D5248C39D,71098BF7E71E0FDB,25D22FE9E6C62A22,BCBC88E536A4A8AB,0388DE2AF9B2A98A,229B495954264BCC,67D4D82B1DA60C3A,0C51485B84CD05E5,00000F648EE9E0C6,BA5928C8BF7FBD5A,0B95B486E3201F25,9BFFA1BB4C2A5851,197111C01C93529C,1494D53321B9F5F5,017143929673E780,40F80ADB6330FCC7,B51CF17801391969,63D279B23F612156,EA6799CD20F0BEAA,85EC560AA05B2A3B,0000645136B8CF89,84829106F2F21E85,D70D2D02349A53B6,7097593052DB3672,1795724C83F45BA5,934BE196C1133713,C99C2F626386D1DD,F025D8BA48DBEA78,3058AE761F0DC46E,991EFCC32439CC2D,55DD592D8D157316,6C0023AEFCEFEAA0,00003DCCF3195E07,38C33C2F7CFC2B77,2AF6AF53A5B7B2B5,DE64239B6FC84942,00CFADDAC19EB3D5,69AA39946CEDB674,3F904E5E986ABC37,F348D1563369108B,339BAA43019491CF,95F0FF59DAF00E6F,ABC9631CFC750018,6062CB83751DC3E5,00001970824ECE19,F7815A4357AE58BC,58BC27BD6757BA77,0DA075F32FD1E15C,4F68B5A1D3358376,1D9660795D472B75,EDD5F21C77347CEE,E51A27CC175F736D,A1679D0D4F91962A,D33DA6951F9245D7,ED61ADAB58EA3DF6,A514D1F2CBB50EF2,0000069219E7AD83,6E39E803052BEC21,3E049125D6E36D99,538077C48298AD02,2773E9B159F5BF85,059505CFAF35096A,3E1706D024917D58,886084BC58709B44,5D55F05B40190926,C7A43C9A96BFA482,DCBA7EB0CA34515B,114847E17A4DB25B,000008EC984BC9E0,AC7D42F602948B4C,0F0A3541B3504161,A3029533D5D7D24D,C19DD746AA4DCC8F,7BCFBAEAA3C1225B,249696EBF46CBB68,E7C5DB4583329C29,2E64975E14C4E9E7,4E1BC5363E37DC45,258030872414C0BE,D34EDE9301D7B8EA,000004979DF4FDDE,34A6B3A098B29662,EB79D605043D9FEB,202991079574F79A,84464629D749830D,433B6C4976EFD298,512CC5D5293D703A,46E1E202A6128043,DB65AC99EE6FCE50,FBA40D9E113DD5CC,683D9338777B092C,CAEF3E02AC7DE986,00001D8EFA321795,0A17DC52D40550E7,D01FEAE295549832,1D04ACF394EAA5E5,AD237522327FBCD3,B8B479FF8A1BF2D2,222CCD873875717B,BA2250764063D6F7,46E2CB776B0D61E6,D4E92944293AB979,17888248C567A2F0,A1EEBF093564D80F,000033DEAA33249B,02CA62ACCCE1A243,F5863F12C098F6BF,C1F06918E576EA1E,2BCD0FE2FCB3D7D4,8305CEB7B7B2D815,74055D41A8EB38A4,CB950059A50B4965,99B8E9081ACC6535,A075B0F03E4E7339,8CDAF379714AA7EB,D50CCE4C5BB418DA,0000014FD8D721A1,66B9613197F22607,C1E98086E7D7D9D4,FA3670770520DB7F,C798E06B931662BB,DF2AEA532B385813,C74BD5AA860F0872,9680692E55EFCACC,DE17F647FB4E17EF,D64FCE69BD3C5709,4616A04C5CEA7D48,6CD7822FE40E998B,00005881DFD6B08A,43698EE563250D2F,B78656EF6DC30732,941CD546BA4D0C19,B8221BEC4EF93B79,68907CF64FE9F4C6,C1744E0ED94BB79C,033E16AC58EF480A,6F009DDE3CD478D4,9B60E44189E577A7,3E6C87522F2F1FA5,BD06DDA9FDCDE5B9,000027FBDC4911DF,9079C28DC4C0466C,88A2F356F3D8998A,CE78B995D4D5FF00,B7B798D4EFF116ED,8A9A0AEC505FC30C,546D43E8EF2B2DB5,3F789A3AC189FE79,F1A2EB90B7BA0D0C,4D09447B73457E8B,09366CF477632083,40F2AAB4F09FFDC6,00005F845D5B673E,3F002833D4B0BEC8,84904BB1D68DAD1D,377C2B78459BB1BB,F3D5D27AFB51DF62,CC8543DA6415CB92,0793537B958F199A,73651BEFDAFF6A17,8C6A1C89EFA0ACD7,C9C8C0DAD6BB6CD6,ABA0C98F409CE935,BB29326CDB1D7D4D,0000226E72B478CB,B1684FA4BBBABE63,AD56E93E634C7A93,229F8791FE5DA6B7,AA28BEB54DFA989B,B6E613E881FBCCE9,3DE2A936674A3A9A,8A0CB1EC28FE5E80,357518E5224946F5,F9F3E0DF3EA6969A,0BBD2C58208473C2,2BCD2E1227CA8FB9,0000103404F0B9DD,A6E8D8A944FC5CD4,3B1ABA3EEF386282,33F8D6379789DF4F,A3DF89306958E071,C3D3568D72695B8D,2CCA0456D1F7732B,2499B435AFE5250B,8D23F49175C0ABA9,128F94DB71F4B8AB,4179DDAE44CEB809,D68E1F0D40D901CF,000044F323A5A9E7,86D6F886DC38CA5C,B719638682E1D30A,E37E1E1AF3F84FCE,3E4115567435A9E9,AE3A6BDE0689328E,44A8E9930E6EE768,C7F5653D74323110,793D7FCA724B138C,8FB726956969919C,288B72FE23A5F981,06106F76295D489F,000063112F858470,225739002FF0F34B,D5120A06F3646C2A,F316E41106D151F9,387D5089E2B12C30,E638593A4B93D46E,7649F6838482F294,494ABA75F5508CF8,48DD125E3DB64B7D,3BB982B7E1441478,D50606B3A71AEDC5,368D8E2CADDF7424,0000361D43F19D21,8AFD1DA723C90437,5CC151E112BB9FC3,A42200019DF44AB7,A95AB585DFE576EF,8E6968427C6ABBBB,932BC05701B906C6,7D2AA4F19A230E3B,48D9D6467C99D1BF,F34F98058A342973,464736B56C6CE022,DFAAAD1940BE52B5,000018425B031F80,BD9E6F983B25A65A,517AF4646A968919,0E755D92D005BE03,E7106D42232B668C,262417B1D3E51F00,19535956B2E47DBD,06D5E7E09E81426D,752E8714261E030B,8B51CD82138984CE,F8625946F492066C,0821E2CEC4C9ACF8,0000075EEF5A2D90,86CEE5B094634355,064CCDFE602D433D,50CA0DC170425EB6,08C0C2BA3F7C2D8A,FA71C3685D4B64A3,6F925FA697328D7D,0657ACA787692DB4,5908F9F42193FBF6,506945D6D908A1D3,E8274B1F225879ED,4F7D8AA9577FB0B6,000060B1C373C937,16C059CA85259BDC,12CDC26E78AEB101,4445803CAB7E5A47,4217583A57BA22B3,33E19DB1D77BC9FD,1E455D31B235628A,6E9A6208C0845FB7,939F84903ED32A9B,D2C7F716660A74FF,81FE5B3B921D630B,D7E0CC54AFAF3A5A,000041EA92964811,6EFB4921A6055823,ED8C80D80FE7BEEB,DE926725DAFD55FA,FCBA90AD6143B47F,D6B1BE7773F9D0EB,DF09FDEAC952C9A8,3C318BFA1D8EDF63,1E4AABB594DA36C9,8F57060ECA2ACC51,AC4B526281BE8E28,A857EC85F24B1D73,00005FF608776763,4F3FED34C3467896,6FFE58200D69363A,1AF21894111FAF36,A41FD1DFA7E8CCAF,19CA3634231E546F,AE7735AD5FECEA16,A6B9F828A41A5449,2CE606C1F45E2804,5F91B621205E32E0,6B81D2220F693E2B,4D4EC42532C33C19,000054F600A0FC76,58B86A5AF64E0E21,EA03C3F49F8EFAC7,56F743E121158975,DC06E4923EBDD46E,0CE181ADDAE026CC,FDA443E9E1F3DD88,0BC026E2EDD3CFE6,7C0C3FF2CF741C84,FEF2F28A34E8E507,367083C291B17115,76464AF3F835C331,00002E26C4716CC7,DB4B081A5709A600,4BEF9C680C24548D,6884611151FF7989,6A3FB6017AACA212,D98AD5F933AF6F0E,D56DFAF73EACB9F7,EA07673B1B3B3E5E,EED8F24D8D13CDD4,921DD3A22E4CAE26,57C571469CAED30B,312CE11B64D5C275,000022D3CC14E30D,826B12D06F57D315,4DD8AF904CE64A11,D2540B7AC72AF9FB,8973AB44D3C56BD2,88CBAEB43401439E,DE51263417DF20CB,ED06DCD5BDDB04CF,C6B373C449B9B056,65CF21EEF2A05272,2BCF4C5702C850FA,A5CC5F1F2EC1CFFC,00000CCF40DD7EAA,B65C261E529848C3,56B3EF3946D077E0,A72DF26BA364FF37,3114BD693366F76B,077B061F7C96BD32,82A8EDD599625462,75E2A1B54A498CB1,A317F7FB904B7497,8C66A5D8BAD8661C,A4B3570D445B7EC5,E8F30F59F500EA7E,000069B562ECC501,D76077E11FEF0F2D,3F05B439C7C60048,2ED1ED2AB02340C7,B8F612906CCA670B,38F9A1E2E480388B,168E3CEFC9E610BB,4448209ECAB1861A,C502B9DB6E119B56,BEABBFFFACB9309A,9DCCCB303EAB26F7,7EE6EFC7E4910BFC,00005ED31A76E5D1,82CF8E16D5E34D96,780E3C0D9DFF2777,68859F36F105A62D,A6C78B61E211B96B,FCDC880E9382B7CC,F2284D61C2264725,E275EED4A7C99D65,916EDA87C0AF5449,F69DC36AAF1E3644,FE315994739F2650,199D3C64952722E7,0000407031363FAC,0EADA80CE5CCB852,F29F21F4BD2EDDA0,37444366C3ACF17E,37E93433BA55E652,6E5265471A45338D,58A496A1F64F1784,5381BFFEAF5059D2,29D24FF598F3FC36,DC5BA9224BE153F5,246CE168FE7EA22E,12586CBCD4185720,0000437C8D309AAA,8C9A3155E1E93662,D9100D1CBC382CDD,1178FAFFF6C7754C,1A73718FD791A0BF,3DF6F9664916CAC3,F3F084B1A09B1E95,22D36813E4F885C3,828C9FC021F36DF6,3A49ED42BC69A2BE,DFB946994EE242BB,333BBD531EB653A1,00001B2798C85FCD,888ECB498D112F58,EAF609724AA18261,9A0D66BA3F9672F7,C857D7A8BF9D974D,AAE5989A13F4D7D4,EBCCB78A7F9CEB27,E2B786C2750B0BB0,6704685426AA92B8,9DAC8CD6381B6025,D8BE417D07361596,2702B3126AE73760,00004DFA35CE7664,0EF7C77F266A9C13,7B76952B1C013379,63C01646ACAD67CA,CB3B69E3C9E323C7,7ACE41D2B0574182,73A208A22D0DB989,434482A0A968D247,D66BFF2A7A2FEEBE,DD2D4651A6F3407F,42811DACE175E7EE,02936492E48D3BB2,00003FFC84C193CE,4752C1A870591CD0,6EBCB457B77CD5B8,3C5A5B157AEC2521,CB8F88B24318791F,5BEFBBC9FB251FF7,98BD95BA5B9C7121,E50EAE11C1142BB6,AE52D883C1494664,0DC7259059E4360F,F153B0A83BEA3B85,01A950A35D28EE91,000034D1BDD4F85A,A7ADA7C97349D29D,0D9B3C8528F89FD2,6124C6C23EAFD5EC,10BC353670982CD7,88ECD65054A0F0DC,600C66004EEDBA2D,8011CA7B759268E4,A37E8B67FF0C3849,7462C66149D794FE,2F68D0FDC937EC2C,46C62310C3101B12,000039AAF4ED1201,A86AE17B8843402B,1B45040FD14C561F,A116784EDEBCC43E,734CD3F251046A52,10A7733351A45D8C,397C5955779C46ED,58E6D9A8AD41FF58,7B469B07D0167585,2F6DB6374630D3E7,21183C773DD8616D,73AE34819B96676D,000049A6526D3482,8DF4F1EBAE9D8E9A,BAB5A35C7D5A3D57,0A1BCE887D5289B9,5779F41C0CB21CF7,226CFECADF4D323C,AD0334BAFB757DE9,EA05EAAE09DC35BC,759D8FD3D560CD1F,D92228A43B276BB1,5198742ED08CDF2D,19942F2F84E7F79F,00001EC0951EF8B8,6C5B5D0146DE009C,ADC114946C87821A,67B4A6EBE3873CF6,F5FAA51E972FF78C,BA435963EB10DF46,9F459B900CB784A4,45FEB181AAF9F882,25EBA2167C681CF4,DEBA7A8E6CEAB6EB,9B4F6614D282B7BB,3E357873C7580AD8,00004E2ADF29AF11,104F409770AD8C76,B72CC68CA7963D49,C619708F61910C6A,37B6E6887E9E90E4,37AE6214CAD6AA8F,315190ADB72AC6B1,0A0B35AB80386FF9,8C9AE391ACDB6288,5939965EE261AE1C,1F0B37BEAE0749A6,934A961574B7CAB9,00005ED00E22928C,CF532C6552BA66DC,76B7BE06B8310BB9,AA546BC1AB7A4054,3DA404C1DD02BBF1,1A79E86DA6A24B47,F11E29C4E3192927,BD091247D790A28B,73F7312AA5A9C0C4,B46A0C1B035FFB56,13666253FEA6BEF4,93F875C9A44B7DBB,00003740CB49E97E,47156EAB74E321A6,5025084B568E6E7A,4749B7053A991DAE,8F138628DC1D1193,3D0A427E7BD06E34,550B738354174FED,421E0BB2CC63CC47,FE6180A380087E57,5D09FF656206BECA,C090B8F98ABBF54C,E33D2C5362E1E4C6,00002B95DC993FCB,8407D2BAF88B5872,BBD3F1662C48966C,4B316F220CC1492E,8D6CB1160F8A411C,101AC1831678F50A,33B5A552917A42C6,8BA64D409BAAC6A9,D2E3599BF23FE3AD,B25D96B01E42C355,4ADA1F4CCD3E3CA1,1F1DAA92E5695C0D,00006B2DD1129A1C,C7719623BA2F5C2F,1193105423DE1146,BB22206E003C6BD4,E8BB74B83817B8BE,1240F5E1664422D5,D037D15BDE15A7F9,A9B5D5D0C493C2A7,A254EF8A27CB8AED,093B01ABCE702D0C,E76C0617D2FD94A2,1FD77098F0D89539,00004769904144DF,9FE1B4F565831285,DA50B5D473B6BF6E,EEA594CF39CAF38C,E25F901A5F16AC10,51232C7850D1FE22,F36C82FBB572AB0F,1D551A4EA9B27D1F,D84782CD91AC4812,A809CF97242974E7,A69DF47C5DCBB772,2B9EAC562C4F688A,0000185D29E08A60,50A0E113B3C2216F,41BF8B836AA7B385,79104052AC2ABA13,5C276CB377F3B27A,704AA7AB4E44F96A,AE03E33DBD247E3D,76407DB5CD0D98BB,DE91B4CB12C18D26,5D55ECBC6EAEDA31,F0574B8CF3943AAF,B1B96F14296775C8,00000AAA12698F34,8EB7B9D84A5EE71E,8CD0A5B08B7B5BA0,8A8680B9A06E2D86,558922DC8D3F2AEA,0F29704B4811825A,D64F2FBD14313B21,D358B2656C88297F,124C2ED97C76D674,8487E320470439E4,FCA2CD1C70979EFE,012ECAC89483221D,0000112ED31B05EA,6838CDA4B8095B8C,3144749C098F6B0D,865AB6B2E2F489C8,6853DFB9271EFAA0,12B2DE97E3FC3253,42CE16C6D3344752,A22057AEB839F5BD,2669009D11ACAF98,9D01168FE8AEC42E,8AAC9EA537F1F92C,668A61E5B2D80604,00006D7E4A7D2B7B,8B4172532E034F32,925DD03D81DDEB2E,B7C77688EA306984,A2F8F1076D7CD99C,BF65D1F6F16AF1F0,8B7EBBD7063FCCAE,C606FDAD1A17C5C0,0EE776979541A632,6F090E865162989C,C5F896EF34F1F216,65AA33C1F8BE0216,000003BAEDC1585A,2B12FAED3750042B,CB31D43E64DE611C,9AFF6116B1673653,A9CA64A30F09AFFB,76728BF07C73AE5E,27DBD843E561F219,9A6AF2558A49F8D4,23E3219003190ABB,CE5B1CAA4380F65D,C3C094A835117E14,7C0BC14AF9CE0ECC,00005878034E2475,B449B3563E0B562B,9F4ABE209FB206F2,27F84F68102FEB0A,C9B1FE50D5405BFD,3F75A59341CC4902,C90BCC53C38ABBB6,BA061A14BD4A5D2C,31AAA476BC0D9D80,0E61D102BE62B877,B851F8DFC4E45EAE,6495376ED4A6B063,00004B1F08772322,241D759C6930D842,1F12C4E846DDDD7F,A7E95D9245F166CF,7CBED1C2302211F2,29E2E767B25EAD8C,7D29E474B613F4F8,03C53CC0D59B23F1,8DC0B9F3EB761C4B,9961F25ABC2B144B,0D74C73C52C088FF,E5AF3ACCA7608CFF,000061BB4FA25F01,361B94D29CA08EE5,611100A5A0CD29DE,9CA510B4D90CB209,2BDF821D0761C372,C233EEF049961B3C,C2FDB6EB51806E36,830642A7269D37BF,3818B166445BFFF5,8629BD47851F9714,64EE8371A36EE04F,7A0885F6B6645858,000052A6F768CE6E,8B372B6BABEF1EB8,32571D6DAB9A9B34,12977245FB9D8894,1E46F0658FFED33E,7CDC23BF046ECAC9,3B78E0187DA878EE,A6982B423846937F,7D9096A376ECF94D,A04FDCFDE5C88BB8,71817FBD7D43766A,92E7FE3203208B06,000068F294BF5B5C,CBC822241707962E,DA7C723576A70D55,A02415C8ACB91578,5D99657657CC2316,552E0A093E941385,C8FCAF16990590BF,EFA6F7BD9569326C,A186064BB09F6FF1,312151B00892C9D4,6158D843C473259C,D62339D8E7753CE8,0000037B9CBDA289,E08F507E4DDCBB48,77AF93DB3459D1D3,C5A12F1EE56CD49D,C71470533CDC3263,3A1D663653660838,EC4218B5CCD2BF6C,B06D0EB8344686E2,E07E8BF0AB9F1B36,3A8566AAA9D4163B,2DAD38145C29A9E4,F6E24226703E643E,0000089AEF1D27EA,401C2B07C94B23C7,94FA402C438C4F58,FE3B921E2C50C0A4,FD96ECF690A33564,CC9907C0572C88D4,EC3FDCA719F93F17,DCFE69D038655196,22624303D69BD022,C015AD865720E6E4,BC83149348DB7409,FE04B84A9D15DE6C,000010D4089DC5F2,75017B90FD2C1160,FDE949A61445E7DD,1749BA4DCE5EF785,6EE6C1EA2F5CE54A,FF8471193D045039,792727CEC0BB30D0,6E3EED7FB7B5E0DB,FE05B98C5D6168FA,635F609B9E174F00,952AB27ECFE6334A,4759975E18796E15,000051E697BAD31E,B310F581DE4F98FD,CEDA30BAD8553DB1,201B7338E42193ED,16883049F1A4A051,77DE315D17836C04,07E757228F8F097D,B36087134D0ADE51,FB7399A7EE61E4B9,8F86E5EBA17CAFA6,EF5D72404C73B86E,E8292BC6319869E4,0000351639B35E7C,4A73AB533C8F4706,D609F1074C2CEDA6,E6739223D7C0DD91,E104ECD4CEF58FE7,8C2F4625F14119FC,31B6327EAE39C566,A5C83283B1C70953,2969EE4786187B8E,538D116B27550C2D,7542F695FC799225,51CE99E90ED9CBC4,000048AD5A7A5FFF,BFC9A2F213DEF6D4,BFD8B395AA6F82B5,6CDA819C96E64120,FFAAD3835B127B3B,428C734C87C71A57,32E9F7E0FF9C7848,15829D95E24B54FA,D6C634F9271E7C85,CE62F67F975B90C9,B9595AA2FEF5EF25,D9E686EC2F697439,000012D3A2F17524,C6786EC2E45FA957,B4BE40BEB4C482ED,5B54A5590C325BF3,6E55526EEB725C20,B9A112E29C8ADA45,B9A662B3D6BCDA1A,39271694A92C279E,84D03517F278FA0F,2AEF213440B41793,AE7F8711F2996EF1,69CDE276A3B7B090,000029D15D95661F,EF6BAA825042CABC,E5226504A3A87F48,4D2EE8A197171890,BD44358DE46CC9CD,5CED0BFBE6A368F3,416AFDFBD00705E1,B21EA46C857AAFD4,1A69CA4E4EF5B731,0E7BF725CF4B2BD2,36237FDDDFC55E45,85A6516049EFDC82,000018752472D62D,541184F9B03B21F8,912A511FCBFC7170,52CF8742BF9203E5,1742A34718B3B06F,F2BEF156CE2545C4,1BC6EFBA24F78DA5,635FE267FC8FFF57,9E66C441BCDA19AA,06CAE7EF4E34F367,C6456AA2BBED0B49,EF9DC5FBBB1F14E7,00003C0813C5A00F,36080BF106F35260,EE068882135B148D,6EFAE2D76E9E5386,40E2795FA7DF59F8,FD60D747F34FEBCE,0E2CF9B3FE650539,83F5F8831D927C98,D6C7F9CB301B67A7,BCE908533E513134,0F6FE9500F31E962,31BC433D46CF6AC3,0000024E9FD646D8,1A9F1C3A2ED56B3E,DA164B9B6B8DA23C,A1177A077AA14956,37DF931AAF9F1012,51AB90DA66678C03,7D71CC57E8DB57F2,41D52C8A92781350,DF9B6922D6415F66,033C42399CEBF943,7076DAE1B8D13270,C8C477AF512EE304,0000383CF467F438,C56A01039D878A18,FFB53BE7BF5790DB,5FADE530D8B95CDA,7266574E8CB8D340,89FE85DC7327ADAB,EBFC5F605DDBDFF6,C01134F0C1FFC132,DD531ED573F28157,67B3B80D5307D7CC,5FB6328B8393BCBE,51A7812322E9D7D4,000065AE155D9622,D17886011DF81E77,A10A77B2E30C9FE6,11A6FF275D03CF84,AD679F0576499A61,EBF676F9EF2F01E3,AEA7924F26DEAB72,DB8CF1C82338AC2E,FDC7D88F95ACC5A0,4A01127B9E4B88A6,8D9511B13152A813,5DED727C528D95A8,000042A9C8C80747,803FC5EBA54494C5,17EE996BC8131EC6,FBAC13D70C8A1962,57A1B3B1EB5CF27D,2D44BF8B04257433,E69D0444FF2B8B77,DDCDC0F6C2710D19,B6932F5EC3BEB3B0,41D5B676FFF8CB97,AB13B69DC198ECF9,7F47C1E3894767E9,000069ECAC912806,0142ECE47EED846D,3F8813B08421468B,384502261AA3A117,6526EAE5F184CFCD,9D392E05373CE59F,746CE3F969A2551C,0B00625E00BBD8E8,0F8540601125D93C,17224D19474AC407,C3C4B08761FBB8C1,C4DE47A3A3C4508D,00001F6B4A5BBE42,70B8C08EBE3D0F21,3A73C6AE61520164,04493D4A87014CC1,F230027BCB782D71,3780AA9D6EA7B64A,5FBEB75C017DAA78,555D582B80C74785,399716C41C5E9E7F,2957CD414FE6499A,630638AF9018357C,8A03602A6B39B7B8,00003BD00BDE5C69,824019B8BA200EFB,C4F1CC7BB0BCE1DD,56C3492A6A15341D,BB6835C499B2A1AC,CCB8DE994CC9E395,C6D302073842A38D,9F32132063A95DAE,13A5C8DB114B7C75,C95C5BBEA46328EA,DE0B1025FADB9E64,0B66B44EBABE10AF,00003F9F9A1B55F3,3983AF95C4280876,7B8A987157C1B88E,5CEAA9CE8F6AE1EF,3EF3D7AC03BA1552,42625D4F3F7BC830,6A07DEF0A0ECB021,98D291B193AFAE35,F4B09F7823948BD2,ADAFFB13DAF7E490,75069ADDB8041AFF,5718143A9413F0BF,000039AC9A17EAD1,63F1DBBD6022B3C4,BAE0EBB598DCB1E1,723A3C7B98A54D1E,2ECBE6D242F7CF6D,482AA8458EE1A392,E96EE32C82BB8DF2,F6EE1D984339E90E,BAE0B318A21BCD10,8A768992DE78E088,4A86AA23AE1DF364,26658303E6B090CE,00002488AF961C4A,1C093B9F0749ACDB,2A20F2C7713CB6AA,9D4713A0012B147E,83888687810C9B0B,72D8529B5338A5C3,31EDDEA94D6E8D9B,9BB8A857B3CC540E,4DC939E94B6F77D4,197A4484C009C074,CCE5CA8B2E7F6E6B,C9A27DE9F038015F,00003A143B0E7890,540B5E46B1964C06,C25F5FB48852E382,0F90DEC971874AFB,C5E94BE1C446AEEB,4200F2BF886471E3,83115B5E5944F90F,9569A9B371530377,D1C3C35046BBF089,9E1FC77CC0362CA6,B1AB1A3D89CE6163,6981CE75EC1BEF24,00004269A152D0CE,BC131FDA84473EB0,DCF0A83E69E2055D,C0E6858CD7B7BA79,78E36D18AEE221C6,9DF167682C2D50B5,CA886D12DFFA111A,DAB7A254C4321AAE,DD8AEAD0170318E0,344E5588489AED4B,6569C40EA6A46607,E74D0137DEB952DE,00002D2B8BC35CE9,291FC65ECDE9257E,F16DE4177EC8B35D,F9C5AF69660A0717,95F92292B7F76EC0,9491A905A047E201,B0083027D4FC66F3,B2DD584BDBE2FAA7,9EEBBD2327494FBD,9F0EC6C81B6957A3,2FAD17F5B1B3A9E4,98387B3C8B31309C,00000CD2881EB857,E53551C5126450FB,CCF5070E28187573,1EB6B2CBB663D039,BB3B01F2973956C5,2B5DA04D00BFC047,9C5AF302A22DF6DF,5FFE81D2E3F0E0CD,3E295B5ECFB0EC2D,07CD8FB87206A262,54CBE519D185C3EB,550927302FBE55C1,000031FDF81845E8,0C7DE34762ECA3BF,4F156177E5611DF4,A043F96740F9D19E,7135F5CB81543EF1,E3934827B831007D,4C9EB5965A486470,475E79EF1B78BBC8,BB0C18CB2BC47C1D,10ABC84B97AB5D8F,55FD3505BDA1887F,5657F91AF6455893,000046052A84436E,49A51995E07CFA49,A5A93E956B2F7FE1,209AAC7B1ACFB687,B81104BE36FD02F1,B0EB2DC737785D1D,161EF898E011B91A,39C02D6A9D8BBAC9,CC08AB9405BE28A5,96171EBC23568363,6F5C404C11AC2821,11E2EB150D202209,0000467CF6CBCAF6,32D0CF9057A1DD75,BD715C1DCE21E76D,81169F7A5850E7B0,F1D9303974DF44BE,32D236A26BE9FEAC,323F7F2D8BA2C51F,9C96EA5F3244198E,F2ADF142D0BD6297,6B787EA0812E4D50,C60273B17F8B5FFF,EC5CDF06FBDC20C4,00006ABD0BEF6871,165A146244DF0186,A558109D186CCEE1,38B4320FC1A95D5C,C3791A98F54791A2,FA367AD20C1E6565,FE9834C2AEC3C694,8612DAFBB637C03F,37C86C8572A466ED,5E74CA7940A6276F,FBD54C00983F8269,63106E0D1345A9C3,000053D71FE0445E,AE774EEBED6EDC97,6DAB39DDF15ED7A1,EEB5A3B2E0FA0A05,62192D82CB3C4F34,C81C0FD8E01A90D1,83EE0C9D71C072B6,224F2B16A1801BD4,A07FC0D5AD26EE94,124A51194AEA5AC7,1C4CADA6AA1B6413,D76BBAD2247CA026,000029A5BA3667D9,EA9F6EC531ABFA2F,2D22D07A7E25602D,B24DCD591CDAE074,80BB765E78EE7D8D,53756C17652AB0E2,57BD71BA92219F90,079F1007E16BA15E,585770ECDC40CF3D,90785DE85B6F762A,BC909C22B888FC8D,88AB6EA7A8C5EFA8,000027FCF82595EF,A8A84FAFC5018251,EE11D5464FB01A9D,4A58520286A86BCB,3961E2A0C93265BD,732F335638AF95AA,BAB6C39B001D9EA3,B77E5AD45ABFE412,5F73771608F9328C,D4C3FB43EFCE791F,9A7A3657845D1433,65F645F17268DE3A,0000169888122554,AAB99DFB2798DC64,4E4539D91F437A69,68A0C228F4127DF5,EED808BA008BEF74,ED327453C05D0538,11AE23CA81E9E872,EF969DEF5C4EABDD,4798BDA347AE631E,43ACEF17CE4F56FF,6B649979752D7DA3,F6D059CE6B28AF61,00005F506645BF2E,559C5EEB513472C4,35F847F87DC0E716,4D9CC56C7145A6ED,74E34B089F0F0E1E,52948526C8582DE4,9942E5A50F0FBF23,CCBDC1BAA300E4C2,C491FD5E5C91F69E,D4CF28CD3DB3ACCE,C16698D215C02BAF,02F9B59E96514F4B,00006160EDFE234A,5812116B7478F4AB,0877F77A4FB31F07,25E4B3E7EEA4309F,5362368D0F85FC3F,401F3BBDECD91C16,F424EEE34597B26B,D50AA850F7057C54,57C13452AA1CE57E,09EB097B3984AFA5,C4033F60658D7423,239A1AE89DA56AB6,00005E6ECB2DDD49,E9AC29AD54EB37FF,CEED4C420175597E,AAAF328514851AF1,C24BEB7DA0EFE6C0,A43832A94D9058EA,6F2D5064D822B17F,8086A3DD494D1B85,5AA3E1BB8208B072,293BEA9060A01E80,CDC2EC2AAD7A61E1,7D851767AA43614A,000069DC6FE25F51,6D18E81842A649F0,5FDF9750472BADA2,4FA8254D86C9E071,5B68E8503181685C,1B3A4B1BE7F6BF93,AD00E81952CEB68F,EC8158F304D83424,7378280B81F043A8,4A4D476A79312D7C,B0C68C75EC825132,E172C3345B238EA8,0000406870AFC34B,D9C6D4364DD5BF71,A1054D1ACADD18A0,4D4E09C4B9DB56EE,7D370A50630B13E2,4BB0AD106E7D540D,8D338B0CB4C218D0,72CE1BEF893D2B58,B320B2F1C8D6B5FF,C6E7A78B8AD8E986,D22D613F5524F73F,BD63BF735C78EF5E,0000078B7452B4DC,15EC9E1C949CF867,706A4DAE23256FA3,887EC75D2A5CF36C,DEA92E7FD725E613,D34EAB488F3FD4BF,338DE19FDB0FCBFB,8C12745F97F39FD3,99E3050986D30D47,F4E9EC39F34EDD14,D8248FA670C81BA0,354400EA403DE1E6,000021F36090FC23,C8D5F3F954ECA024,9599D2FEB4DF4BE9,CA9EF141CFA9CEFC,EB78AFD2FA166879,A136430C0C2BDDD2,EB040DE749072C87,3F30FFDE0F08FBBB,B2399EDF9AEB3843,201DF9704A4314D4,CB9E5C66A5582F4A,647F3F7E8BB4773C,00002E6518ACD196,1866194DA24220BC,49C038A6B8825927,74F18F9C52A48F6E,EC2324EFC96168C4,6FA6EC20C6BD90CF,CA4F31D37A9EFE12,075C54536C0EFD63,23C139DD6762F684,E3096CF2F5C6EAAE,4D97BACFDF1F316C,19C0F5E4F7FBA2EB,00004F8A0DFB38DF,DD51A1C77B947195,1D147BB1E54EA07F,1426481A3C341202,E51318DB8FEF340E,76A9E1952D4C6D50,592A0C5EEDAB3387,702C2A9903FDD98F,AC31E279387C2DA3,ECE5DB8F9C3463B8,D78A9781BA33626D,5ACE1F89C11E7DAF,000022923CB9407E,6A99DC687E9614AD,9779B80B1D7B3A71,FCB7D8DA7BAEB867,9BB6B3FF4F74D4FA,B725DEC60EF8A86E,76E2F68FEBB8F26D,1F6B548417441F26,0B87CC520EF3081F,D321648CB0B8F464,5AEA1F081012DE9B,ED8B66E7EFCC75F3,000020E97DFBFC23,9AF8E7CB5C6B55C9,64AC4E16400270D5,B9C54BABA85FD7B4,28EA35CCC9226B1F,0E4ED9E6703B4DE3,4FEBEF02BBA881C7,5AB768F88745D501,A474FFDC831F15C8,4EF73B4A0E2BE466,6CD39BBDEB944D4B,C6B494DAC76CBD98,00003DDE8ADC658C,3BADF38FB8511327,D1E66A57E1785D30,5594615BF47D172E,F6415D4436FD5C99,84D444E887C8CE38,87CF8E03A62ACE8E,36ED9FC41F6F8E9D,26AECB5FB40C94D4,FDF9E2E4760C4026,F93F15D9228455DC,13E5670172EDF891,000065BD818031CA,B3C870B30964382E,9EE46B058C75692C,16E4C2A703B772FB,E1341ACC3D3810B5,C102ECB9C4F621EE,2A9F59B015B4BB52,2B9CBBFDF725A648,84F2D6E48C1067F1,96BFAC6353A925D9,B5A8AEBBE8A50AF1,9EECC07BD17C6D7C,00000755A5415C44,CB657131697DD6C9,95252ECD8753FF90,F6A388DE041CAD1C,009D0AEACB0B2EA9,AE7EF5DB9DF314FB,CD00A8D9BE27134F,7FE18CFF10DF6ACA,FED122DB15123139,4106CED6B8FD60A7,36F0D67ECDA3BB65,894C72007A7EC04B,000024EA1B66487D,DE9BF9BCACB0EF7D,3F1DC2B7E2EFBB95,CD17F94ACE963E81,817BEE01E00E1701,68C2DAF6428CC3A0,EA802449FD66543B,D93C090B71C6C263,1A79183B421149C8,17D7BCFE2F109524,8028ED1234038FE4,562966BD4DE7821D,00002D5D20138FA2,74D16B8B554EB8CC,DA4F056FE6834DDE,05A8D33A23E61413,64BCD8295F3133AD,434C394C8E71415A,98FCBC64E5EABC5B,EC20D9348639A022,06227B5FA7B371DD,E5942832B817124D,E54DB5104A2AA0AA,54CFC7C335C875B5,00004D6E7FFC7E22,5933295338993AC8,B9DCC4241DFBDAD4,73C4DDF0B076CB3E,03EDC216CBFF8BD0,0EABB3572F3353C3,775DE70AA2D22030,3B89E4A62B397A30,3A3CB06175885B46,A2E27A19A5DE1E53,17110DAFED0C9F1A,0CBCF6365ECF0EAC,000010B0F974F13C,C99D5F92B65EE2D3,53CD9742740237BE,FF1C5072298F123A,CFA71021FAD7D633,335C4F685FD9B617,4396AC59E7CA60DB,52EC7C6D07DCF549,20F5E246D2999639,246A73C172B0A76B,F76913DFE203ACFE,DFEA35C1A303105D,000035511E163E02,401FC945812B8E05,9DCCF8FABBE23CCE,A62176F5FAFDB8D3,85E0FA7CD0CA0E51,8C55C8E7A091693A,EC703E931C131DBF,FCF4B2626DF8D95D,3C4B84F17887C13C,8A363557A66411D6,906BE47318498B3F,7CC0AE95E5DFC214,000069A87A800E02,810BE7F917D3B6CD,E63E9A1E08A83F9C,A52403F508816A0E,7DE7907DCA55078D,618A12351AD3EA4A,29021CF68098D152,103D32FC39EC2999,A56D0587FD4DB6B8,2AAF4CE2134E63C3,7C9AA56383B23AC1,4E68E87E98D85C8D,00005E2AC1820009,0FCA251D228B3A34,7DEB67A97C744C98,4AC2C06B4CD96493,8F0A8D12A0E7C9CD,FA5A73BCCD7A1DB3,9081BF166B16084C,3ABEC3E7CBDAE1A6,077B50571A76D06B,7C2D180C187C26B5,79CE8B6F1657BEC3,6E3821641543EB75,00006F4D25FDB706,17BDDC22BCBB831E,3A087D9199502E4C,1CB82F88F1968927,B7510A983260C6C2,0764A90D80CEF670,72D3F86DE4EE33E5,D2433738D185B1EA,E4390AFC9B13009D,9C9C962FEDA018A9,B86C00BF87B31D42,41527143F8E9D35A,000031863D55D746,618CFBA940F04E0C,413CE3DBEBEAE72F,03D8D656E53CF897,D1084302E5FA1EF2,99DF15700423AE79,EEA9539EF7311362,CCA92237B3ADBD7A,D13CD43FE87F6E57,CE44C8FEF3979A65,1AA1EEE9928052EB,3A034D2604A537EC,00000732532FA709,C08748159EAD2BCA,F34319ABC229BBE8,3790F6DC3FF76B30,D6E5BA20C73BACAF,326B22A58DA4D7EA,4CD9BFFA8DD8D25C,A95C139F10569843,0D23FD934ADF2497,4BF8D8670BFF3926,8CF429869B59BAAC,F6344984288B3A59,00005F76F172E72C,25E678388DE8C510,9C0A1550E500F888,46D9C13AED4B9B86,9C146B0984C745D8,17A5F200D0626178,E1FCC57601A9CE65,EDB283919B2549A6,5889E55A8105F601,1F890CE2BE07D1D1,0E738B6580F84122,06433E20C8D38B59,00005331982369BE,310CA43AEA6A145A,381EFD6431B84A44,DAA82DF3CE43443E,4E2161C108F6CC7D,A2079C8619631488,0BB57C218D40D821,F05BFF6F2BF1AD7F,DFD9C03B6ED50C30,76E0F9034F4D8760,675E1BB73EACCE4A,10820724923AB16E,0000579CBA7A7D98,040AECC2974D02E9,5B71DE7D8C0F87B0,FA9E6E72E49C087B,8E2430DE54EDA94E,64424C3E837B9B03,B6318C49D77F5E54,43A518A8663723D8,D30DB1CCE85B55A9,8CABA95818CCA253,EDC35961D27A00FB,D936325CA918B64B,0000675A181E4481,1E56591A3EE58647,26BD6E647E2CA075,32727F0771B84495,FE19C74339ADDB4A,2DD9F6E8841355B1,2EB965AD95321EF8,C737366787E34463,F86B61382A8D1EE9,D308DC16287BDB9A,3F7E08299A6A9287,17B4AE70918A7EB9,00002DE95EA54C7A,92F478E5B870E249,24F2D72984C317F2,B0A637622F88AAF0,CCCED196A144E43D,4C2CCA385DEADBE1,E4B0FE33435EFD9A,D256B8DB1C1F3DB9,BF8935403856EB14,B31CDA1B009DF026,151156557B809782,029849646C2BACCF,00006B83504DBF26,C99DBBDAFF07A11E,2F2FF428F8BCA87C,C0B1B63ADB9C9441,128CDA6CE8E80105,9E1DB3BA80243952,27DA49F1ADA7A02A,9062BC2C2EE0070B,95175243EEA56C14,D2C4B841E9E4B763,E03D9EB3220EAC22,06A3EF11D589BF8E,00002B643993A3AE,1E67792F8C201D0C,CB61147872A609AF,48ED0EDC311F88E6,AB26CF090686F2B1,40858B2D3000AEBF,872A74AEF37FC08E,F8FAA69AC897CB72,5C14399A060E7251,EBE6481C54139E8F,215A8FD70E5D7488,73ECEF09C14D7449,0000171E4D6A0682,25F8D28E0FBB2A00,0C606D02F86AF4E9,4E6C9FAFC3BA3C9C,D00C4E8E3AAFFFA4,9618341215006103,749E845CD59E6E8B,49E3BB6CA15B71FA,4901BFA053E97222,15BDB5CB9B6A1110,9A4EED2E7D89A6FF,65A2EB9B36B7D92C,000050E6DEBEB395,4DADACC380F921CC,B21E5206542470DB,3E8ECBE88F803F54,F06AAA58B4BBBAFC,92163797C34178E0,7ECF313A46558187,F8DB2F66B9C869AF,8A5FBE2F8FCCC9AE,E670F5F4E7B7DAA9,D2CB6558CADA7BBC,EC0C866FBD8347E5,00006B0242AF1B4D,E702546055E0816D,1A9B89B63F65BC3A,D2BAACD6047D8DCF,40A0B10974FD2EE7,2201FA820FE2E53B,67F7D9450FABDBBC,15195D7D484DCE82,8695F62BF055E062,27E1A97353DD0632,421CD53556D40A84,8C1AADF7BE1D8934,0000290F6DD7ACAC,4066E6AC798AAE98,D60EF96874328EFF,10EEBF4CCE14133B,5522462E6B74443D,72AFDD80BF21BB92,122DF06A39307B5D,15D27DCE16733544,4E1F49F993C1D063,5C0B366E4FFC0E96,037843CA13EDD1FD,110063CA6AEB5976,00001BD13E3B788A,F20D5459FB3D7321,E6CB92B6F94F2B0B,C157F2DB4AE86181,45D9C6ED56C33593,868E77A69F3F6507,462FC587DC37E91F,96C052EC7DE08E97,D869BBEB0A24600E,BAB2100466FD74DF,9342E7DC635EADC3,FFAE15A2A26C9EFC,00000429D96807DB,80A5322BBC56EB86,E51F54DDFD7A2DFD,548269063C212D9E,8227F2287C7B09BE,1D45CC34C9869CC7,7D4EF4B8574F4496,40791FEA826C0CDB,368DAE7A04D46273,C7BEDA9BEA99616E,4A309CD74C1BE6CA,55334A90F33DD162,00005736140B341F,A86A7F0D241DE7EB,5501AF8ACC5456D3,38EF345077DF5786,45EA609A0769F98C,AE0232A91E981F6E,8475EEDED28A8EC7,BD9C3F6E3C6CB13F,DBF5015837430931,26A2C3C4C7045297,30B7091D8DCF503E,63B619333A73422E,00005982FC1674AA,3653598B4137B1E7,5672884BBB4D8998,8BBFCDB3A2448CA5,01CBDB92F84038BC,39D43C8F7050B26B,D24AD4239A9457DB,2CF2FF79C0C50781,5BEEEF787CE76008,8F43A0000FDADF5C,DF12E00F16A5EF61,866D1CF0AEDABDFC,000054D5B1C48EF1,0A5164CEEAE4CE92,6353CD3A43C1736F,354A7189EAA9C22C,7732FA3BE235CF63,BCAA3953574D3387,701505C3FF28DCD4,3D115835FA054A58,D73FFFE73562DD1D,7ECF7E14346EFA9E,EA57907CF6D94E9A,A097014539E33BC2,000063217E09D702,FEE2D0F7BC9E6653,F6F8B8BE88917EB9,FE548DFEDCC7F90E,3F939AA27942F496,1A47313B300CBCB1,B6B66B226AB74035,65E60CE131861B0B,99DA89E8DCDA897F,B5A503E2F328DD6A,017E7BCFC8B62681,40FC94A04EA98954,00002FF8BF1B5755,620892439B3D4CFD,14F2A907EFC5396F,2912BECCDAFB5F64,D4593D177F567F60,24C3AC0A0F45B585,3A516920401222FB,C6FEAB327CEE48CC,F0D40262D8E5DFEE,7F72ACBCEE1607CF,415F99993DB150D7,E4BE6861845B2F67,00000B3448C89568,D04ABB164984E670,40A8197420AC6864,DE2B4944D1C25C5C,2D0D1A8DAB443B03,4D21BA6CE5847948,3F8EB6EFC08DC130,ED813A0CADE90861,DC432DEC77702386,D6BD59BA88965B16,58D3BD2CD2F552D1,DDE8FFC3BBC27EF6,00001C2731978D59,EAB32CC1442BDB5B,DC227858EB8570CB,8769055A2BF9F7D2,DBBCD26065E01904,D6B68DC15DFF0930,8528C46FE8DA91FF,9EC0F8253FC0B0AA,9A80BAA67D8EB759,E54C3B426E3A2362,69713D5CE04A88BF,D97486A19160B1EA,00001E0CFEFD18F1,A2FA10505B0BEC3E,07D24F5383777B61,8362BE5BBB146E6D,9EDE5DCB26D8126B,C12BBB1D86135D92,DD97034D4BFDE278,D4F9431A903D97E1,518D04E6D9D3A115,5E159D2A0DFB1CF1,2A295944387E2A2F,A949F65665219B9D,000033038CA4030E,6E6801D390328F62,D2C6E69115F3C5BA,EE2130870A1A6142,E77A1DAC06C921A0,DF1700CF4FB6916A,2586F9534B1CFB1E,FB1C228D6D08AE4E,525144EC98AB7A96,8B5AF829CD4C0CB8,F310946947CB1F2D,6655D8493B0E5E7F,00001F780CD0BF89,639B9CE25281321B,CD8CCEACE06A54A2,3394D1E9EF1EA88C,AA123DC05313C99E,E98FDC8302DD8831,7CB6C32DC3E3EDFC,EBB741501875FD69,2C78A04D3BD291C2,947594ACEA0A0A1C,3D81D27392F1F9E0,BC76571964EFBAF4,00003E5E9DDB69DA,9B6A91BAF86D0CFA,A132FC53111DCE10,D7A0C1643D5B3CBC,A335BD133E3D9ED9,779FC9C3D113548E,A155CC1C54DFF4DD,5B3282CFF73A95CD,2CC2321828433BD4,07C4C7DBF3420770,7064771803D40F49,0EEBAE4831E9EDB4,000057635A42985F,8C8A43A105FEF72F,D1BE98F87432C351,870D7B3469695478,736137D3ADBAEA91,19861B0958550321,4A82FCB05AFA2A87,01A569B431BF7646,675AF733D3413CC3,64277F25CC4BB63F,947C0E1893F1D17F,D04D80C8045C6BB8,000020332A437A64,4B297BC0950197D9,FB5590438BAED6FF,5CE6F1BE5F6CFB14,A5D6CDBDFCDF9304,A54602AE9D046C9B,05334F48001780C0,63361CEE27C8CFAD,CF4AADA2990D85AD,DE3FB24ECB106C8D,BDB7F14A9759D8FA,1404ECE5EAE23770,00004E72FBF57848,8005C0C49C1536AA,4C9A4E68680338D9,5A4EDDF7397C35C2,81573996C3715ADF,BD9ED18BEAC23371,9121173D667AB19B,684BEA6DE4EF33B8,A463B4882839AAFB,704171ABAE139777,DB68B343EAE587A5,A5BB14964BA1C1FB,0000073D4E73C0C0,D819BA1DFDC76DF3,2C6C9BBD162CFF8B,F2917EA2DA0493B6,D7E378029C02B854,EBF627297BE43775,C52B95FF9B019663,800FF5A8051889E2,2A5903574A783B28,C1688222A84F58C1,134378BCFE23BD51,DDE8CA7120C98B10,000003E7E4EDBAD7,7A2CE8AAAC698E36,B40E993413A57E25,7B941B36A66CFE86,9D23C72C6A268D20,71FAAF90A0BF908F,242D62F837E8698F,E89146ACE9E0B89D,F053CE15902DE99E,D36B9B37A989A1FF,563590AD3C67AAED,96ACEE637A7B6276,000037F75B8C0469,AC5876D03508DEF9,A0B6F4E28D1F3164,0BA56CBEAC0C298E,36D85FF12E4FD162,AE31E3B07DAA87C0,3506A5D45A520D63,1231F50EB2285CC8,171EBB002E1CFB9E,67B1F5E75CBC7DCE,9B28F62BA5BFC282,71EED7545DFD9D4E,00001ECEDEFC61CE,68E2E10335E05431,9B432C3C865324F2,9D53B9A33861B9B6,80824C7A45EA6865,82B06A4772632D6E,C178BCC061843B36,B9399BE83AD37B88,A29D97E0392CD8EE,B81BFB6F505A4216,BFA380512768664A,F460BE495D47A682,0000001662202EC1,751A710B226FD12E,93BD08379C3756EE,FA5FF475DD3D5149,A22A30B09B0A1832,662C75DA2380C8C4,4943ADCC89F5D877,447D747A3A99260B,154F3E64017B8B29,AD2771D1C1DE492E,ABB9410DFE2DA7BF,F60BC20D966112BE,000046F3DF15DDC9,F067C2D73D24AFC3,37F76BF5BA6FC0C7,B7D89B7ED518DBB0,99989D2C79FB78A3,14DC2F60D477EBAD,77F6615D8401BCE8,1D38B3F534C78CDB,4945854AFFE60738,D7A1F7D14E780434,3183964990ADBED1,50DAC8AF233E0A82,00001A96E1A6F595,F7DDFF17A9B846DE,19613F9CD01A93D4,1946F8AC11A5FAD7,722D4846E15867D6,09CDA4AC5B6E0EF1,00A3CE0D907AD649,8D9602B3FD3A2875,870FD12F037CF32C,A17907911CFAFB9A,CAB027A658E97FB2,860799291E45BCD2,00006C131A9ABA05,D79AC4115F842014,689F067CEB469B23,DD9EC791C063EBD1,B6683837361FF909,4A432C7AD760303E,7D84E3CAEEF719B8,6A02B3BD4CBC8B56,C133FD87AB78E733,78EE292D0C7BF89E,C415491051658637,1687CEB576981667,0000514EEDBB228E,BBED5F8959EA56FB,658B7CB4E1FC5AF7,90CBC16F29EA2144,2F7B550F52959319,FB5491020EFE39BB,4C82A068FA0C6157,7CE243E2FFA3ACB1,83C3BE890287533A,ABA1F9BDE6491488,F2D027682270897A,151F80A9BB99D58B,00002FF41EEE97A6,DAC45E01C66B27B7,123AE255B9D57633,0F1FB94821897067,3301D0C9892F2B5D,CC8250D0A021C43B,C3ED89327B5AF9CC,A94E30B02B1AD793,1D38EA56D84FD048,87653E3A1E4E777F,ECC3FAB3ED25DF2C,43735ADAD225F729,000017214A45BCA0,409A3AA683181F64,52C37B50C3787026,2E1ED11FEA40E9C8,C71237B1D0E4DE01,F57943825948799B,3F207B69F6F78C0A,1BC496DEF7B48916,5B00FF6A208E4500,35F276888F89AA26,7FB7087E99D4D7CB,27596C00C4F895F1,0000696D703C059B,044BD970985BF5BC,C5192D7EEB5732A9,0A7D9E787B6022AD,2F087F37531B4752,2A7E583B698BD5C3,F207C7F82DBD00F1,B206D5F3BDE29F58,4CD0AD5DD35AC743,E6A116BCC2257C7B,42F46A7800EDC3CD,A7B7EF87294158D2,00005117DFE56DD8,90A71A3E2CD64315,DA30433C960DC475,3C35DAF6F3ACC533,3158569795C5F784,A3E44771A5CB174F,E6EC0333E4A53431,4B6D5740BB0D6191,B382D1B1CF8D88E5,DE7E069F847B3E23,E0A6BE26D4E1F417,585290649E15201C,00006CB5EE31D6FA,F271069925126004,40D8E0BF541E4AA3,BB2EDA3A7AEB27A2,020A265EC1F9D558,CE577D9C71E8520C,E76271F2C02B81EB,FEF79E2508DAB43A,482634E5D3D612CF,BDC5060C65BC9AB0,D73DABB1DBFFCECC,78E037530A2CFDB6,0000615089FFB96A,1A60FAB0A73845AC,C694820FC2071925,3EEA4AFEB3F54151,1D815D96BDE7499E,C031F5E4A1E87B75,7ADCED8C32E834CF,881F9F59F27A1FD8,B00D43D41CDFEE0B,982EE83EF0BC68B8,BDBB5BFD2CD61496,8DED4C57A0241098,000056C63292E4E9,00ABD859F7E72287,F4C25A1B5F5C56BE,8ED6933A8E31AF6E,F7738D089DC9F9C3,E57400E7E067F308,6C374D5CD83943BC,EE8787A1B232C0CB,09EF38A8B2EEA813,248A1FA44032B093,ACF6E3E05BE9DBAA,19BFF8439EC4B32E,000040D5974B939C,C9EAD87F9D323C72,F014E7DFFE05F7A2,D359D254CDC4507F,E1B8DBC60A758D56,FBAA222A2C9D55E0,4EA5549CC952683E,928F95DB0C991A12,FDAF52EDE56E4966,111009782E717184,9066DF406EF1644D,DDC7893D7B931873,00000DF0FCBD2081,2CA7A065340E6EC2,3590BDAA03F21290,824A73DFA29E1319,A97186F7458DB0F5,7C5C41715D68E567,F8B8EE687E620AD4,AC49B37EF2C8D17D,6C3A06354DE84F45,62388E9A27531262,4682BA29FCFD7A9D,12AD9A5827B405AE,0000362FAF6A19FC,5CDCEE09B9BDFAE3,04C174FCA2B653D6,53E3EEBEB0747DC5,991D9D052C013ADC,3B9684CC03412D80,55CA432CFAED179E,09F244DD9FFBE10C,6DEE901941980B9F,259432302E8DE853,2D560D1D52F355BC,D972B23F548544E1,00004C53ADD7A01F,AE35FF04C6802DCE,DF0D46AF0E9184A0,3574BC672E1D2205,C2D8C3CC15B706CE,8A67D96DD6195940,451F1E925E6F4890,F1000F760F4BF170,6DB9292E60B4D417,2C32F00B3BE6B912,890D18F64743EA4C,5DBC978C8A85E473,00004449CCB5528F,BF0E10707D98D320,00DAA02B986FA35D,60ADE7D289191A0B,B9E73EA986985001,C18C6E0377D9A55C,793D8C3D3EF18223,69633B5E1688B5B1,9541CFE461748135,5EA891B33499D7A2,707E61380584A58E,7BB87F1D7BA640E6,00004346816B0CB8,FEBE359321D8C92C,AB3DE8B0B892C926,715607240C269B39,268ADC2035A9A140,97C6DD1CE97DD4B4,FB84F0B020A56F1B,B344D655C0975827,8591330FB4831323,0B7D815FD52AC5B4,BFD77F8A3C2FC4C6,B6467514F56C51B0,00004A5AC523A845,B7BBCD23B3AE7548,FB0BB4CD916DD927,9B7E2EDFED92BA14,66ED4AAC40F2681F,6AB0C9535D2E966B,9B0FF89B48C4BF0E,83AEBFCF1869D21D,E6AA4D0D3ECD21B0,4198E73C12092EC7,5618B344F4C94A38,2D760E9366CE2D6E,0000181EA20F3EC9,22E86564BD228BCF,E3BD8D9832178E94,4A3FE11DE2D28B22,500F982DF9C31816,C172C0C92EAEF835,5FFB98F02C692C45,FFE1D255433DF230,5D157F8644815456,9258E0D792A93384,910920D5604F0B0D,D84D748C258C8C35,0000353C633DFA46,87BEC856D195DCAD,9F9CD7C0BA6FF0FA,643E3EED2107195D,0E84737355E9B705,DA9DF2CA33C63D6B,455BCCACD55F671A,C40A9BC4086496F7,41D40EF9C8D5632F,3EC09F1302282F13,46DC03C8ECEE148D,68329264C327F4FF,000054A3863A49DB,A50AC81C1E89FDEA,C38B137CD45FEF0A,66D1209FAE78B32B,D6FD9CF90019A3DD,95675B5949B99998,30140E264E9E0746,2B640140A15A6F7F,B97691F7C40E1C5B,88B1CBDEA2B439B6,95A42AF1D80B965A,4794539BDDA5FD1E,00000245E2C3FFF3,1021348C568E3D39,5E7CB227FF13D53B,5AEBC25A2CE9F20A,0194563B626D0604,33ECBD91ECC1329A,4A602F620D78D857,707802F1F615F3CF,05C40FF1F9951744,F475AF80FCC0488E,0ABC72A43741199A,87A7786F430BD5A9,000016E4FCCA9B38,EF3973A110782F5B,8138E76818D15CB0,F28DD2D0062244C6,C23F96311DC6D03D,E37CACDEC3DE33F5,AECBF4DAFA012A8E,E433A56E585C4933,8E2D7EB57C2A1BEE,A3C8BAE7B1C0B418,CF5C7E36AF4734F8,623AAB772CDDA657,000020231C704617,5503EE0F2E2CF64F,C43D82B5382B432D,5A6874147F2FECA1,30D8C3DA3EA07DD2,98BA8123F133F61A,EB3124373776EE35,707327EF41EC17DD,62A8AF407311F548,46A79CD92AE4F80C,F912DB06B742DDBE,4CE1772C99D77B0E,000049A145583B8C,F06C021F42DF4427,C9D193249C38F09A,FEE11CED4F8BE1CC,769C3DAA7E69FAB6,CFAB84455B37AF8A,A97527A617804275,8EB69898AA08CAFE,2895CDAD9357AF43,BD4195AB0B9C7F40,2D0269DC632B2109,B3A06A59DB3DAC2C,00004EF7A7852D75,CB32624807049B34,8C8D89E3DB51E9F3,4D0D5B5B80B5B067,FE1017BAF5B8FE25,D8E683BF22822C06,93349AC474014CDB,0F04ABB73FDF2890,7AF16AB8B11CF015,42E4F102D1E3F322,A8E0B62B7B347903,7BEA2E5715EA5509,00001C28DB11F907,869574360924543C,0FC9EAC94C1D4FDF,6CFC8035F84A09F5,A3DA976B25043B44,973DF82F96A666BB,9BD806B520864584,9277CB4362EF64F6,04CE197BDC68D19B,FA6AF828CBCB61F2,D366717445B6B831,7211839C995F4B2E,00002DA42796C72A,EBB4A2AE2633E1F0,4E6B3979E0CE798A,CF93355F363BF297,0D6FACAAED22A063,A1888DE54C08B0BC,7C5D384D0932D8B4,A90008A73F2DEBE7,D5055FB6315E1016,EE915CA5AB311861,5554DF5896D8EE9A,96112663A0DC6C34,000017899B15C35A,84477FA4A6C6DB3B,AECB2C0F35638F8D,680A05E0A0106BB8,8389FF85F209AEF5,910CEBD157AEABFF,D3E3A7C49F9C4F4A,DDB815354E07E4C9,ECAF10D4B873C891,716F936DAE03A072,E5581BAA71543B2E,BA2A917D754E4E0D,000004051296BF16,1C78ED12A7F2E513,5DDAFF57BB3BF0AD,9367AD54AE6797B2,728AD5AEE8F70F45,14FB042A0B622F9D,77E0973B01BB2E7E,02CFC2745E15D892,ED5CBAF4B029C871,D99D7187F66C7BD1,10F5443C80193D00,BE99402D8CA209EB,00004D53F798B180,015891570EE58632,C400D7BA92157388,339C848DCC049C11,3D8784294147479F,C423421AA40BB066,8694B2CB4975F3FB,2E1400A4A7C30FB6,8A6B574F3FE538CD,B80E83826C8DBF6A,A69187EDE84D18AA,D63B55CEC1BFAB2C,000006A293F1FA82,D79077773A791819,1763ADB2A7468307,DAC7C73661737E40,C8C6597ACDF359AA,7CB160BB44D6EAFF,6DD2A5E1250D2218,A73AE1B29832E6D9,9EAE88FC5E5165D9,EB1BC7C05979E53A,AF4044613571EC7D,53BC853D1F58E631,00000EE368CF983E,9768E1E2CD176110,4B435FBFCD5C16C5,5420F6CCCE55DC22,E22F4846F44286D6,C10355B3BCC0F06E,7E7EB25C08BB21CC,5686DBAD7F6CD0D9,D040510468BC6237,E06F865EC40798D0,42E1EF3360239BA5,EE986969F7111C7A,00006EF26AFDD2B8,542CBD26372D6669,031988FEBE36DEBF,2DFD61304D489056,4CA6ED18EFDEE34E,5A880E5761F38657,34EA0F11C3274625,C6D735E4B3BB0567,3568BC439A19B26C,F0CAD9118FDDB209,58D2EAF011042C9C,89E614A8C421FB78,00004B89D29DE4EC,3E8E079AE149F4DE,518092ACF2218D34,12E58C86C98E878D,EACF900A8A9A5D20,717E25B7AC36E070,1B81EE6E71301C72,7851059C911B1DB1,44711D3C193C182B,BF3BD5CA4E8D2DF9,4A5DC136BBA134D4,8990922B5EE1E2A9,000047D57DEA97AB,8CD377B1B7BB3684,0C0E0ADD7C847C6E,824329BAFD79FFE0,15DD106B731ABBD6,CB6FF16563F2A500,051E4C6238E84C56,A73B55DAAFFE1A0D,71923AE38D52F6B9,083E74C073D2FC97,68F252324CE3B63B,8BC50721363A7531,00005450D3C51465,55DE4A6CEEC0A68A,0204BAB393CB54BD,C39F2A448D428E46,195759E6F3D755E5,4DF35AEF6A3AB762,73256230F4E5E196,99D6FA095C32C632,13640D6FD61E5F83,F443E2C507463EF4,155A1859A3C40B25,77D48C782ED6B8BF,000004933E0BBDB6,431DE2D5E1EA08B9,3E3D2CD9CEC56898,326D86B92BC8FAA2,8D524D01D51AFE13,D7BCB36675EFFCD7,A3F9994A6B01867C,3CD70DFDF2A7B6C8,810F770CC84FE521,BCA66A6CF33AF7F3,626105450A881F80,59988613761FA547,00004F2B67EE0056,B02F7A0196E08232,23D7B2FD8350399B,CA662E9C5730E41E,5A53A681AD83852D,C8025C1CA0EAC3F0,21BA06B249204319,F09101CB5AC8D4E9,118157EB6D966EDD,5B7B48905A817B98,2D123C4DD18615C6,281F9E2E523AA7CB,0000356971A0B3CD,A06E69E774256190,FAA0648D18B21504,8FF61851B1AB77A5,9A2120AB375C8DAF,B718EF6AC80D0EAD,33F905EC6CBB634F,64E9B3ED94153CCA,2D51063EB3C44635,4BEBD9AE41A5DFD4,1E7E846C2962A423,1BCD3714EA225537,000003CF4DB23470,271ECE2784142A0E,DD26847BADDD7ADD,05CBE53DC166EE5A,DA9382E891FC93C3,B54846428E42A361,86F013343E9BAC62,975512D9C896BFD8,2F69D1BEF76998A5,DD0B6D5E4F3CFCF9,F96CD163DF94B63E,AD0DE9F2AD719E0F,0000503B66838453,BAEB3B5DEA58B102,E849E510E45BB0D5,A3420764B9E0AC95,6A954FEF3BE85468,54869245C6118CBB,2CEB0E8461C9ABA3,4408C07403220C25,9CD48E78F1704316,B980577C99172692,73B470D34266EB4A,4B6DF05DA4216635,00005165AC7A98F1,250CCAC4B7888200,EE0A3D0DDB3E5FCD,D2231745857CC44A,EE363D2FF96DBF87,0CEF47E1B0D366D3,000E0D57FF398D38,2BFD83642F3A7627,0F28782785364C27,0AE4A625CB33D063,DB44B4DA2EDC526F,B4C4EE044527852D,00006226E1BB06CE,4EF3EC2A2A3F8173,BEC7FBBB8AEB9608,73746B53482BEA61,0619FB58FEC5A65F,3F4E7F162E9C1C5D,9E535D21B4167D53,197DB7C832EF3557,4B8B83F535D773FE,A20BDF3D404505C2,0BA1B3D7B048A1BB,25096348FC536B76,000041792660B093,34D5D2608ACB1ACF,476805004E5520DA,577583E96DE2F54F,0C36E4A8C285E88C,551C2F3F7B46C349,D6C456F835DED359,1293B68F42CBD2AF,8365A28EAB2B200F,F25D50D81D204484,24D1FFA1E932C17D,732E4D90EB47188B,00004E7D1A0B5BC8,5EE42F96811DA7E3,66894C44DE462883,C0B6C201A6D2F95D,1FDE3EDD46092E5B,078C9E8434615019,5C4BC62AC0B9B984,9CD05A0AD6B1FA06,D10D62C039ECB18E,559D635B4B9B2714,BA07B03DDAAB2A5A,91452DA8BAF3DC52,000059C120862BD6,53CF244AD80657B9,C434D2787805BB62,60BF2410C1277C8B,6D6693CD8425913B,9492434B9040F961,8779ED27354329F9,7A89FA6702A21366,56BBD105C35EB8C3,AE9EB6886EB6A9A0,5E9072A543B7C4D6,5680031EF050DFA2,000002C03F33EAEF,BF95062B3EAF16A9,04F0139E2A4F43A7,D1CEBF3A603F7AB3,DD645DA0011E921A,BC676A18008F85E5,58439DFA3E4CEAE7,8D1CE45DDECD393D,59E3DFF551375DB5,BF8D04F942DD3F68,7243BC37DA98C3A0,94FB62CC6974EFA6,00004C8EB5724DA5,BBDA8A1EC4375577,817CB46E9899FFA9,527C232762574BFC,2C2BDF5D7A61368F,C08056864802C529,F45C5534FADAEEA7,80AB6318F65C0F0F,9A35B27FE795A1C5,F662F2F63EC0EA9D,25F83860CCF4D8D0,1D97383E6F2489A0,00001650BE5A8F36,36669AF691B9770A,7F2495D44C5B2A74,144DEF623BC77A75,6859C1596C595AEB,80F19F16B1D45A7D,606844F0AAF4D704,AA825C2BF18C93F5,4FC57F70EA3A7221,245C1761CA2B90BA,AB1F7579C83477AF,CD755824AF568AB1,000018EFDFD8FA25,5EB223EE18AAADF1,477E5CEBBA4B90D3,0F07ABF0DE186559,9520371E9D7D90DD,5B96C7AF4C6B415A,5AF8D5498A997393,B0F42B81F1528D84,6525379229A686ED,F677C786ED428EF3,F8F416C653B718A9,D325E69759746F1F,0000659EC00B5B95,BF4A1D264D9E47DD,BB2966A9B99BED5F,395A65F2EBC844AD,1E0A90C201A78DE5,50EB1A8C0F03A050,F3DD6919A9FB2C19,5D3D3191AAC21FBC,F9A434E6378C64E5,B6D7EB8194B9F750,09660040C0B5DBA3,7DFC5F6ADBF7AB43,00000712210F02C8,9848E40440749DEB,EBBC3B5DFEAE8187,504B8780967F65AB,A4853DF3EF897137,A0CF05A4C3EC3744,D399C6CF10FE14E5,ABFBC96384CFF86D,FFA697F9F34AFED8,A8E29A549920319D,858AD3C1CB7BC5F9,B940C504E7F54792,000034ACB9B35888,0F49FCB919B50709,A67A4318CF885023,CC28C1B8B868336C,9B200EE2BDDBFDC5,AED8C28E6AE07959,10A7452E18111E07,557959BE7A0630CD,5EB33AEBF3C9C0B8,FC5A7668410482D6,3453D9FF17749447,16F02CA0D417875F,00003F99A6034054,4EDFC7E4FF67FE2A,7CFF4D1625E0DC8C,147EFAB8BF05E499,0594BDA99FC3799F,4A60BEA70DF41AB2,4E80400A46EA573E,92967E029714AD93,C643E9E9D996B324,8F60B88B1F220A7F,84EEDE843CAF3C37,672561BDA60ACA48,0000104724744F33,2E872A3EF99552DA,87B367B9D2A0F94F,DD9BCBA7D515FC3B,D66FE920FA596455,58AE6CD5ECF651AA,F84D8FFE895CEE65,5868C859D491E778,EF41E4E21247BCF6,0BF8FC4C98C71E1A,7A7EDCE294CE0607,7F56C76A5C857CF2,00003A32390B5056,045793606BBE49B9,FFEEAA631922758A,052871001B1A55CF,77ACFA8B5205335A,D53A82B2FD7C2E33,6C747433AAEF2DE8,3FD85C4EBF60C45A,3131B510A0E95F87,B6EFCB556A51CB59,2E9292E6BB83D25B,9B1FE522CE8EC9CA,00005D878F8E8631,896C83A4D5AF1AB2,DCB0CA09272B3C5E,5D4DA2C953CF962F,AF3DBC35074C4AD1,259146970E6D2C06,EB57357CCDE3BE87,5C10184B542A6F02,452A60383DB076ED,6D7AE2CE2573B02C,AF198E1AF7BF7696,72BA7DD87353B538,00000B89D9118C93,8AC4A4EB4C76C132,801E97E370AA57CA,8604DC97DCB625D0,7B5103FC1F60962F,47EFF6C36A933D95,BBDA10B884F5049C,898A6262013C91DC,7E21BB8335D8BF2C,7B6B45C91E65E6BB,5913A6BA8523E2B1,DF72548EEAC2F2DA,00006C3C86E8CCA3,4726C625C02FC452,B10A7AB721B88D4F,3E1B29C9607D08AF,F5B61896D159A49C,8238E66E3D2A7FE4,446CAA8BB034BFC0,CAEDB72D1DC91196,1D886BAB272291D8,A4F302733FBD8C40,B1EAAEBA920D77DB,075D8FD05E4C8278,000027BB4818CCB5,FA0A1386833930A1,8F43E4094788E379,DD2FF9E6EE86C227,FF9E4A2A8550704F,EC6E1C9F2D463940,DF50B8EF59B7C8B3,3E62CB2071438763,8004DBB33E482BE3,78FE6BCCBDBAFB4F,C7AEDD0B07EEC92F,12535CA139D4B061,0000343E51176A0F,FD30A21727085681,38150033D6A207CD,50EE2B58EB07B0BF,8E0496D9DB79A155,7EC06D882D799BC7,541755B0060A6734,7E7BD5A1ACF01D1A,40EDB0AC6402170F,97166ACF9511C1DA,A52B2A0200D6CD8B,05214835FE784EB1,0000251EDF5DDA52,9BA019A8A3F93393,D74FE2AD597C0ED3,38AC465AA7112EB8,CB954C7255F23560,E34FF78270AFF6C9,2CEC02FD69E62BED,F1B377836978BF7F,23C32D4B96615C74,0595047394F3E6B8,744B37B74B5B5320,02FAEDBA0C15693E,00006EDC88A3017A,B7A12E451414AC3D,8E4ED4F9A609766A,D268A217599AC4CD,9CB1D1C1A4339AF8,5248E642E63E4024,8035F95F0EC7264E,96BE4D304AA2AE27,A2C1FFB9E532BD0E,8F53D5A2489CEB98,CE9999E4C656F1E5,47538DAFC542632B,00002130CADBF587,5E25BF06743CA419,197FDB801D2BFBFF,6ACA4A6B2E844925,00CDCEB802FE7754,43DF3BD5B670C645,CF2929BD5E9F7610,C0CFB7C2E4D9559A,52FB498B65FA9B35,E1940259FD8B58D6,327E7B31B166051D,6E6BFA975A41E705,00002BBBAD7A4BDF,5A58971BA0FC9A0C,6FDE3FED419B996C,E5EFBE478C74A8DF,43EAD625F7830215,F46242650DD0A0AC,F476939A9259F5C7,791BB80B81BC074C,BF908B67840D22F6,0BEE07D56908A9D2,F1838D0A82D6C74A,EBC4455A06D027A2,00003CE5DE113742,0040DEDC9F086739,F7CAE2CB1A2A883C,A2FC7C28E9358B2F,28006C345630D942,0184C35C65BA480D,C1629635D9D117E9,012CF99EDFD2C9EC,C678E227B8C36E12,5718077781125FC8,BA90B4F3D1805E56,60A6087ABF69133C,000023861DD5BE18,EC69BD45289A57D7,38D3BD94E67C83E6,EB701789E533ADFC,6F2997E6CCA70B54,50A3B54071A2AABF,700200254C84FB74,C0866B150EE92EDF,5852EC006CDA2FF6,34E27BE1AA3323EA,889AE429A9A88E37,A8E0583374D867A6,0000046F93A25E39,F314AE19BAD0E1EE,BDAA878795F1C099,2E04190E42A2CE27,29BDC8F73324ADC0,AFA7C4C97FC54B60,59F3A046C8EF1856,5F040E3E94D60332,2999204A9359070B,4841091048571AFB,46B1B64E4D8B8EF1,52287EF8A8D6B7AE,000049268FD0633D,C5A53BD1CD445C9A,DE6F4EE2D69655C1,A5EAB26D34658258,B51E6CCD4232FA98,683E61D3142CCB7B,76CB6C31B777026E,CB5C2CF604B16EE6,C9547AD687A79099,29D69CB276A117F7,A68B197216164DF3,7292FB3B77169B62,0000311EFC608E42,27A18E103F17169E,DBD7A421DFF535C5,3E23336DB53B89B9,CE3E90019F5214CD,EFC2A852293BD7EF,5EABA39DE14CB4F1,A3D75D94272620C9,C42BAEF2623E6E32,66207EEBEFA65974,DE43DBD2335EBCAE,36F449095E961F1B,000066D68DFD6A14,ECDD57F842A487E6,DE4194B516FDEBC1,E207DA50301F6CE3,EF031384C8294D49,B0DBAEF362BA592B,5F0D5F5836A11771,D5EBFFBF231EA876,AC117600696C905D,2F105AE96E20BA22,2EF71748DA39F72F,16B5ACA88E9111EA,00005BE42C5C6D0C,5A28831A8A83D729,226240B756458C75,578BD8435128D187,085A7EDE6C00415E,AE30C7787240F928,9906FB8D97BFFE25,5959DB951E84205D,82FAA5746029E8AB,9F32D5B529233C01,24D2BF6048291253,153C279AE9A56E90,00002B2ADD2840DE,8EC53C0F8D2D63BE,1E5CF0BD678C9F2B,745394AB638A19B4,ED92787BEDFC73E4,747032C4048073DC,D3E6BB0195159BEB,238720730D79A783,647D82596F415073,B3E74C49C15E8651,2893E7705317E44F,1A108E696A6FA079,00000BEDCF568911,C4DD3D7D3FFF4E65,AA47F16C9285C9DB,29D2B144DF0C99BB,531E21213EA65298,4DE4C494720178DF,408F63480ED07184,C4BC232C3045D158,1E6A5CB742A15561,60D9BC603E0AA5A7,BC821410C4549727,44CC5FD0C13C212C,00004B576F3EA18A,622B16A940DAD2D5,664A6CDE3C3AA0BD,D856F447D77C9FA9,279C2E99D2146284,B072E8FEB15A748C,D049A46025A52618,590A0A018E8E8675,2870F54E1CA173A7,E503DBD78FD0461E,11F8D5B456BAC4ED,88A3962C0F2E982A,00005DE9038464AD,A2113602A1193C77,5965FCC840986162,A8E2363E8DBE8A75,5A44ACE44676E222,F9BFD47E2F6FC6AB,349DF23E4A983F43,97CFAA3F8DCD97DF,C1FE04B3DBCB14B5,22458C9D93441E3B,79E6A1B2BBCFE7CC,5CB7CE8739476EF8,00006AE1AFEFCC09,E8FDC60AF1B04FF5,5CE7C79FD0032810,F3E3725FFC4B4768,1309E3D685D218DF,78154FE9FC461AB3,C36808EF118D0CF1,E6E629FB74BF1070,B30CD7B782B18E54,5727852C26E1E3A2,4E526A5491A6B5FB,C9878A28A23EDC8F,00000C8BD93F930E,25C899273C690233,105154F7B9C714CB,89E83072B8B5B463,662551049DE2FBEB,C96EF88D23781EDB,84758E6F87ACDD99,63C3CE1A8E2B6763,0A61B657E76B1430,661081C871D417BF,CE3AB3BBCDB8FDD5,B4744DAD3095FCC0,00000CFE6A7EB721,ABA74B0E49E733D9,6B944F6D5E0B39F6,7FDA3D4C9AC9CF74,E1F9CEC9280AA003,E025C72CE813BE0E,C6D5C012829326A4,E1C69FF0E6200D3B,F42AC369FAF56651,4DE77480B246A30A,62AF95A646E89542,49F772738E1E3097,00004B99B3D70441,41D0E26957F68D3F,03227B41870AB3B1,6773CF7E08E3B9CF,6E832ED5297389E5,AE42DD7FE3D874A3,E3826BD571D66B50,6DA004976819AEF0,DE377BB0D98F26CA,4B67EC969BC10C46,4A3CB5C67C5AD9D7,53062BD5D6840DBA,00004F187F0B5BBD,60EF6A5B7B555EE4,ED2A6CCB91F39CC1,9D5645D75B91D3BC,B5180F0360C0FB76,BAE39A31B1D57A23,BB99ED2B47482F2E,456A1150C7D6BA36,16562107CD4F35AF,8C7D5FA3D0E05C16,D2545AB3B1F52FBB,048B0ECC89265DAA,00005FF784C695C5,1F1390D92AA28331,25605B125AE86518,8A82F53273BCEBB9,22459BF2040B3EB8,439D5661BE18E9FE,8B39BD6FE3782C5F,774EAF38FF25502C,5CF6B8C2059325F5,38FAAA7D530998D3,2D1A8629FAC22FA1,FA3578150483DBE2,000014BD59382F1A,1F76B16ED75C1CBD,5CBFD0EE5529E2A6,CFE1AE19EFC862CA,E1C7A4DC688F155F,14B8CAC3C8D4ABE2,7DB662EEF3F688FE,94020FFD05CCDA34,5D91803C04A83065,0E238D7866E96E5C,51F3CDD566310578,E8B3945548CCC5A1,00005925B67487E8,81A4F69BAA55B0B4,2C84A606FBFE4C7A,698F9F56CAA7641F,0CF4057FF32D2321,4C7C63FB88A14A21,21DFB89493A81C7C,23FF8B372D340812,98FF0A579E9E49FD,FC54FAFDE8858FBF,8D1187F3CBCCE93C,88225E4F93C3E005,000013DBDBD0420E,60193592239BD8FA,58965C710F90C73E,A2C88959149F47BE,AA32E98E1EBEDF9B,B08E58289CD57765,5D41B8BB1D4DB8F8,A3868C86D9A10F95,C1419096E6A3C6B6,A35AE74C60CEB79D,57195233C02AED0C,5684BDEDF2842A3A,0000693AAC05856D,253676065EF7638E,11E4BE3351D1EF0D,6497289D3562ADC0,2B71B1F09737A4A4,39839A10AB4F16DC,B46227D6DE4DDCA2,AC44F666EDE53C03,8F7E67785FD2609D,BCD7F8D7163C9236,D30E031EB9E60CA6,1FE7B7741B88D3DE,0000500AB7616D9B,275450B9323F304F,B7918298F654E41E,85580770A3C4BB31,6A4B042B12F8D684,B7E3E44845AC0DDA,33151D83F32B9B67,1E76318D8C9A3349,06EF41E81D35CF5F,7CE4B4CA742725D7,02024417F93F4C94,A919EC5C81660193,00001E1600DBA009,B71D29755042EA40,F57503D0A1AA47B0,4A78F4DBCF2E38AC,B56F33CE32201216,83554CF928767B82,372E7A57A4BEABC9,4233589C315FEA60,C2F6D417454A89EA,EF6A922607195B73,E1F138AB324692CD,628A00AE2CE162AA,000014D9640BA509,9E4CAC2586B7920B,31660BC1F83330DA,68A1CB43C29CB5F7,81072DAD7057F6E5,FC3DF121FD828AC4,7A684981E23650BD,650C210FA4C2B524,F8BF56F12A844442,87F04E1A2E929DE2,7C5696D385F395C2,533E9DA51A0AD824,00004FEE63EC57F4,9733B773D1209051,6CDCFA59FA420288,C2E41D767E8441E3,378FE8AE2007D0F9,50231D1D4016A58E,1C41B117CA7B1796,D9275E17C08A904A,9302E79A486CA668,CF40AE803AD5614C,31CD4D14A108366F,3A193B512D905464,000055D23ED4E998,137916F7E9A7D76F,FC8210ADB63EC4FB,315008AC05DD3699,822FA81FD02D23AC,EBB7CDADE60B0626,E128D6BD1FF576E0,AAFFA3C9B0D74A10,01B1F201C852CAC1,C03B011BBEDF851D,21437479C3FDFA14,A8ADC8BF617D1B76,00000FB9E280772C,8F10B155788AD213,07B25A39533C4DE5,EBB0CB3319E4C690,31A7AC76BB1C62D4,F050E8FDD4D9E154,17D37FDB7B750D09,C92659FAA6C4FB54,5BA3929A7AAE53C2,08E3C720ECA568C5,00B487FA0C8818E5,A9FA16385344ED95,0000243A39CD49EF,D3EB47AB1E2965AE,5442A7F36B06BF11,FF6A86F40D6AA20B,EFFB82CC1D62EA57,9280B63374D81832,CFD2ADB7CFDC43F4,ADF0DB6461FC90B4,0B0E3509B5B7D0F8,A277CF0B7B034066,4FA80C0B4AB59738,C25EF0E472410CD8,00005FEE6C84D7FF,0F5EEEF8AA7CD132,F1C174158CDDAC81,CA76CBB38C5AE8F5,54226690E6106807,B7B6B0BB40C4EE03,8D334DFB8F882DE8,5C6677C312A6F542,C921C209A386A612,98BA144D81EB2CE1,6D89707DC1281C69,2401B8AF1187CC68,0000125444880B0A,694B8FD7BBBD346F,9D83D52747344285,0937C8BAA93FDAA7,7EE25CF3F1C6ABFC,0FC2E4B06352F612,84FA6125442949C5,B82536815878DA5A,12329D83B48C67CF,E555806BE5CCA1F0,C990A9556EFBFE1F,ACE49616982E0409,00003BC2B9C82727,64D09A01E6A9C54F,8B0E5EBC3651B00B,98D6BE175C37DAFB,6D3B3E7A95011851,2C5E2BB1762741FF,0EEA43631BD3DD18,0F78AF190F83936C,DA43D979D0EE128A,E2F8ECBB4BBD9ED5,95FE92EFD996BB42,D39C397438D104D4,0000420B475B4863,B1A4343F5C4811A6,E19B02948F5D667C,E1C758CA3D4B868E,EF433B439A263620,12BDE3856F3A7A8A,BFEDE8944D2DDCC2,219BE21D0D81D99E,82D259CA7DBFBEAF,4FC3C846E9A32259,DCD4F0967B9C89A9,8A3793C7BE1D27CF,000010D1F4644945,280F9A366BB9761B,4FD5276DC31D24F8,34386C42A11E074B,23AA77B67B539E4E,3E820D3507600119,30F3B3529C70FE88,DAA976983F8AA6B7,523683E09F5985EC,D919FA03B0582CBA,ADA261E08751F639,58CCB87F1E1AC504,000000C3E01EB49F,04A25EAE75BD2A54,5857A8768E686F16,6F7C9D8361B68227,6DA0C3755E6BE4B0,78824EF24D1E4639,8F453A8D2E6F1C5F,4AFA78D688DDA0E6,F4AE08D67000FA3E,1F4DDBD1A1AE0D5D,1C202D506B10B283,E65EEB347BBD2FDC,000038CB613E1C27,6BD8B55892B96433,D49E7F62696D3F44,DE12725915AB49C0,B3C167DB1BB05544,EF64C20108910163,F36F95A7717691A9,CEA3CCE0C629A7ED,BDC75FBD1117D352,26891C897BB028FF,874079D2C84974C6,FA0189603B789A29,00002C1726577F97,F4C362383EBCEB72,455641E810B83BE5,D819A87D8B7F8197,AC19A6B0FD0878E9,00B8B9690BD41F41,07C3AFA9A2014B91,13DBFD0A75CF39F3,A128211CD68FFADC,DEEF9B9BCB493278,E69F7194A2530E70,B26339AD6390850A,00002CAE7F819BCD,19C1F6D8B8E9969F,42DBA47E0BB14E83,AC6B1DFD04A4E04C,64829C88E4C0B1F2,B746ADF475387396,F61D9F84CACFFEA1,FF0D1DAA314FA383,4097C1707CD245D8,56AC3E214282BC6B,A60944A81CA2E174,1DDE57C5076EB707,000027A534C3BF7C,E024EB6A40860C57,11204BF3FC49A53E,D76B3A13BB2058AA,8D82D663111FD86D,2D8B400F0E8D5EB7,2612CC4CC08AB888,D87C0AF37E71EC91,1FED3FAD216CEC98,510A264FD76380EC,65176DCBA9D29C6A,918084380B4DB7DD,00003230950CF901,4C34CF8C01CD3061,2CB6ADBC0D386C9E,4EC74BB4CEC37D07,7E629EB4934A5294,40645EA426CBDF8D,F941CA52AD2ED6A3,DF50525C93C8A284,B49F6ABDA55139D9,574047985EE23724,58A22AEA6CA872D2,9D4B096459DF7003,000005DB1FBFC817,ADCF11AA1A779B3D,56367B25223B34EC,3A006A3FE37DD194,11A254379A3D07B3,04F824B85D9178DC,6F95E70DD841F126,B5A98E960F6219AA,0216C4468DA3B3A8,F1D412A06815236B,50A31D574B8F7041,B3528B81CC8E07C4,00000F4C0AB3CBCB,DA0C37E39BF8275B,0423011B17F10451,62F8006EBD07BCD0,A1213446AF510FBA,04D97D76FAEB6264,E4CC3CB0C9AB2677,D70DC3BF87599E8E,BF427D6E58F0B966,E4970C07FA5EFBB2,E3066D06C7A5F3BB,3AF06D6192DDCCEA,0000470B3F84633A,2CEB3BEC8CFB4B7C,328130CEB00AC0DB,C0926EA232E426A0,BE4B632921DADA41,D4B4C14E313AC04E,E4EA9C0BA27A0A69,9A91C91906B31D02,77FFDBD57D88C57F,9957D22216EDA2FE,BFFE9696177AEB05,74904810E112CEF7,000045F0B8350968,E09F7E950E1E1717,13BA5C90BEA1C487,A15ECE2AA27BB493,657984DA8DE14509,9B915BFE47DF1F1A,BD3BCB4ACD9B9C87,28B36419C1262961,20F6FEB13A50058A,B146EC4019A12E1E,6B65F79DC3E60DB1,4BE2C2A9A2DC3092,0000486958CF6E35,1BE852E3FB64ADE2,8E2984A50A004DF6,3FBF73398FED395D,31AE122603925C89,A9CDC64FF794D956,63A4AAE1783F5038,3D6ECF9D7830A6D7,4CA78C01AE5B3764,8C136C42E8854664,76D6D309AE2240C6,267E8CAD862B60EE,0000266CF49E636D,A926F0F2195C9262,2DC77C86B88BB514,C451A98234B0D529,BC2004C2D737ED46,C08EF8A7747372B4,DD3B8CC377AD66B3,B51C8D854E6E08A1,64A9CB4A67947BF9,490B1F1ED3CC5C4D,CE1867F43C7CA2B0,9A1EBA02CE040877,000067E9D4FFB9B9,C94EC3C084DFA65F,D19EAA3165A3124C,87315CABBDC772FF,F252798DDBB6522A,F0E1C7200E205F4B,6D1C92DFE421ED86,33A9A0AA052C76B4,EDDAE91157E2E2E7,6F5239D5485735EE,7525093446A92C56,B3783B1583F73B16,0000440A783DF372,F4A9FD1165931235,3DB2EAB4A2D87922,8E8BAABB7A68FA88,396019CF77644C74,75D2A4AB6654CECD,352C937678ED1D9A,A7C8C417D1A6955E,91B39FA069EBD11B,C6D176353D6C8D8D,3E1EA76AB3A86040,793492913B28A4CD,000063E2FE167F0C,7EDA11DB88D3CB29,7C4C2DEDF4A15CC9,6BE0CEA76CCB5BD2,75BEA59192A394DE,4AFEC50183172FA3,169B538AFD5158C6,8C3B0C0E82834390,9CBDF294D13C3007,86DC5358ABFA63B9,1C94F472D1939F91,17E0212ED3E814F9,00002371C2842028,9DFDE07AF4DF5391,379D400E8D7352CD,B306486238ACA424,8F06A2ADE1C9BD3F,D3615B4B6F093C4C,ECD8CCB11E706D4D,B72D5EDE9C89A69A,749D4E0A29F99D97,69EFF982CBC92E2B,656877EA82F95FC8,E0E9DBCB5D1E7709,0000157B2D297C67,C58680E2F91AFACA,02C12B25858F272A,526EBA7F7AB86EA0,C3D1C80F8559A75C,5B87200D8125919F,4D6C7E1AC1F5094E,AB0FD0533FADC411,DF3337654C96A9C4,4467E4A65589E582,DF8EDA2E87C847A3,12F9CF492885559A,0000313293A5464F,6A79C0DD10D314B5,28B63B9B8A18909D,89498D6BECB67B5F,B58FD14B66180253,AE02D996CF8491BD,C5EECD56BB96E441,B0F9F1B4D289C918,81238F3CB6916FD4,4EBA04108A26FE88,09A85B4A136AE0E7,4055457C9CD24FB6,000063822C9EFB1E,EE6CB166E063459E,BEA228B68F8A3E86,C7C0B1DA9176C2AE,62A4D9F44BE300BB,7E8AD7060D35EFD7,0CFA31894D496EAC,D01E617A13B3C4AB,6D8CF3616EBCB43A,5558CB878131C6C2,B2E008680E3899FC,505C9AA4E49CA1B3,000059AAB47FC802,023E197917CD72DF,98F3207FAE9FABB1,0DFD6C036156E7A2,7C0CFAF93F863FD5,19F10F0B7261818E,099C2991338D00EC,F9D1336B6ABC7BD1,B306BD17B830CE1F,A0FB45C9711EF88E,38D75527C35AEE1C,C68CCB66A3219FB4,00006483C0CFFA3C,BD891F96CFB59400,8259639030BDAEFD,F15E34CCEB190C70,FBF6202407B65617,530DA4F023C9E20D,1CED240EAE012E6F,AA1D62EEF03A0D1E,3CE9D331A1587ED1,9695232A8EAEA034,9AA9D6DFCA151D3D,F7058F6D5BC1E993,00005BF996E1A939,324015DBDCFFBF17,3E1C04FD526BFC4A,66460C3A1913780F,9BBEB7D37BB13404,333F3CDB2143DF68,1CCFBB4BF0FCBCA0,B164DC7B5A153B08,CC390BBA759CBE32,4109D0349B62546D,C48B33CDAEB08A40,1D7D09E491A9FC2B,000017C681DF379F,5A696B1EC1B9F7C8,FDEF3132CA4F415A,D7700992292057AC,C0AB1DD9C07610A8,E93CA6651D25BA9C,9D1DD03D156B2182,AC1E39FC58460C7E,1C2874B6FEAED07D,B52C79F0E596241F,0BD0B66151E80F87,7D127072BB70022A,00000A3D24F0916B,602D3F05C3FC411E,1AAF6BC895626CE6,2652026572F498E5,11C55C105A6A61F0,C93A5406830DB808,6B576724EE0E4644,B68918694EE39BA3,C2528EEE41AE02B2,C7305FBBD4DA9CA7,D9DD31ED8325BB5E,8559F4921A47CD2B,000029BB2208762F,2E93A66394609949,7F05284F1669605A,FF705592FD090FC3,D9C0D6495141CBC1,7B4F6248C2D51AF7,5563F5BC9E36764C,3555AD3DA4789465,5F5AF0C8D0850410,FF5B1C8E6E3BD564,FD840D396A258FE5,6488E7580810DF39,00000739456A4122,8425111FCE055D88,350EA2333D7141D4,ECA1006D84E8FE83,C3A7A85631BD6AA7,599C3E027A786DCD,9BF17513FCF9C8A3,3070605ABB1A0E0B,76EA4ABDE0338A82,405929CE68AA2FD5,FAA292236986CA99,E2BFE89678D1B8D8,000022E0A8EF9CA2,72D419859CD087ED,C656763F0D6D7201,08A6C4CB868F9DCA,8E59EFDD17BC2B01,218018D039C4EE19,7DBFADE0809CBB6B,209CD7F8A53DE0A0,A5F2F641C0731BC6,E11B57507DA771FB,AB824B3965106950,D4633228085441FB,00005D4A07D0D8B7,1A0D29860DCA4378,913C15D36047CC4A,1FB21CFC48C558A7,1025DE0E85C65014,B54DB8AC896B35DD,44BA3580D061CC96,FF0842E84E3B7AFD,C48F0920BF061552,5AE70AC6B623C781,8BDF5ED70C10EBB1,7CF901207AC6512B,00005CD48CC2CC5C,2DF468B450C2B73B,70C1E073060068FC,FB027FECD9FFD1DE,6E5EA9EB5A5DB267,ABD494E27FEB9FE9,52BB9401D30BCFB1,C9450CE22042D44D,80B6A7CB23D0F45F,E0A6938210AE0D24,4BDF59804FB72467,A3A3C773A019D4F9,0000454C679CA06E,14C7F40B3664CED7,0ACA65FDC1DF0CA0,2585719A0C4DD961,5FB83997693C8CB4,2E035E7939C922A8,DC3D04731AE05677,C5EF2D9725C237F7,86D5C83EA146CC73,8899B2EC8B248961,6CEC5BD01BDF8E58,FE7A5F8009904E31,00005AF31EA4D189,A222A1E663B861AF,3E4156E90E9A5661,E1AE698486BCD18A,E545239E5FA1E2EA,4F4EFBD55ECDBC6A,B4CC37E17FFD3478,CE46A4E4CDCACCE5,196CCC1B4D1A3B8F,4ACF21D5B6B528A1,2102B2415A56FA68,252C79B68F2D79F4,00004173DC59D242,2F512E0D80F577DF,B29D01E35F7F8977,A50DE53503FC7FD0,8F81837CE745895C,4DA4486A0A68C15F,417761C203836E21,4788D652B6B1DC4A,30787446A6B70BA0,7BB5257BAA2F9DB7,52CEF4FEA8C80EFC,26C3DEF7B0752249,000058DD11C56DDD,1C21AFB182C0E9D0,A8DEAE535A6E6B98,1E29561828444914,7C43BBAF8CF2376E,223884AB021779F2,7A209757FE4968A5,D8299970F72B82D5,B2115A345420B12A,30FCB051387F9FCA,C156A8A2EF4C5777,AE698F8AC6973DD3,000063A0239BB96C,84BA94FCF11AE0CD,D9F8188903FF2FA0,226B833ED66201F7,BB0288403A526854,C60A323B87943554,CB404B70D8DAF5E1,2B91DDCE704E140D,A1420F5B985B4760,44A6606DEB956548,8C8582F0E6347DDB,A064CE25115E35CF,00005656CC52800B,F5308FC809E1B403,DD05CE9CCE07A3EF,DA587B85F16E3F86,AA1461157105AE63,B22F1C23F8DA6751,7BDEB442355028E3,24FA8C50AA46EBBB,79C729E5AB9AD25C,DC3B3A8B8F33AAEB,3C8586E6044808CC,76DEED3E9101FEC4,000050727DF56B6B,4EE57767E83BDC4A,A86ACFC7E2A6B753,7F821B3EE4872A4F,FB6B85273AC11002,F3255537E7F6DCB2,DB6577E4633CEFC7,E7D1F8D7777927B2,3288F340BED2EE65,B0D957E29F86987A,BCBF64E76EB7534C,4C26B61C32A09BEE,000057814568AD6D,91E3C9D8A142E51A,8449791EDCEF5B0E,BDB906C59CE0CD28,1229BE95E499D55B,E72315DF3D97BEAD,50A52613A40FDFBE,82B6895EBAA39BA7,35935D68182B337F,C0C535864B4F13BD,4996343EA8CAF5CC,F07134537D4504E8,0000492FCFFB67C1,B014E15D2F6C5525,4CF7E970980FC2AD,4D86FCF7220827F4,97452BD6B36463A7,C0168AE4B9174408,C5A43764D864088E,6CA33DFFFA256C37,1EB775718D23C764,63718D3033DD2911,FFA78F2F945CA85A,B869461F46EF3B19,00006EA3726FCB59,742EAAC3922D2A98,6D6AEBB98E3EB323,A90D00C2B7A4711D,1B547324567FB724,1B99FF594778A5F9,420113B8C0687C36,94511872CFEF96BB,A94DDF92C9B1C230,D4A2A4A7A59A02EB,A0543A479A43533D,EE716F06ACD3445E,00000D6FC67CBDE2,C2006E62C252C2CA,1A13726D9598577D,DABD1BBE06000286,C3AB2BB6AD831206,8DFB031655CAB855,A078901E22E14146,3EA0A398382A81DD,EA62AE384787D098,DCE5086634981AE2,914FFBF590A92FE9,09951619CDEEFFAD,0000440CB5DE39F1,AF16DDE0E4F16584,1469681493C636B5,FBA9432824B2CA54,F02B96B8D4B40DEC,CA8A529ABD9D4F76,E0C2C5FBE23D20B7,C8B645488632621F,6E2482025144B6AD,87E2EAC388EE7F22,329191FE83E69FC1,456928591BD59BAD,00001D7097E439F9,E703426743642091,1EF2A6972B4B3CA5,E376F8AB99515130,3288EECDFDB6C29A,AB2ED8393CCDFC1F,364F3B4A1C27CFD5,5DC2874E11054A44,3541487A8B256299,7CF456C1B5483E18,7A542DC6FF007D11,0E58BEF025F75016,000059EC14022518,65A0CD0256410A21,DC84519A2208B29C,3F60918408776DC8,E5AAFCED99FEDBB7,7D5B7DFCB279C8DE,C79EED823D0844B4,ACFB7D679E46ED21,5CB5C939477600D2,A8E54DA7B5F00446,B640BF25F5596E0F,2B92C87867B8138C,0000326B9960A40F,38B6CB2F462C7041,B9E75D04F6C373AE,1166D2B9E841C25E,0E2CC7BD10145428,7B35768B64F4029E,B23BB1C4CEFBBC14,5DE2652D75B6BE0B,E33555F53D5A094D,CEDABB0E93F51D43,260F0BA47A1458D5,E5A44D61565600B5,00006CFEA1C18231,12FA1E4A23808626,798061F143DEE794,A343618CF93FFF32,FEA44324222EDC1D,CA1BD813BE66DE0D,94EE09B1A50803BC,2AB44714932D7DCF,5D68F835CF8DF52D,13D370765C2A9112,5B45FA515ACD64A3,E46DF65A006B5BB3,00006E10FF3C0123,A765EAC5C2761C59,7B348BC356AEC6DD,737AA1D92DE17536,DC55C693A78B2F95,245DB25C5FC6722C,C95EE0CFF823D3EC,AB0CF6990403E630,6E92D6D46A15BFB4,0627C8B92182B1DF,63D1A08C5148E03C,2B2B03597D4F2B32,000063EECDF4B5E6,F5CC9525D5E34628,45D306B58C1E9F54,840600067D305E3B,F5EBB47FB684C0E4,EAB71771D28F030E,135D40AE6C721D09,DCE2B98815F5557B,76A1AE0DFDA323D0,262681246AD6FA0B,DBD1BE9A14751CBB,ECE17963A0185728,00002453B468EAC4,6CB071E78389F5C9,9572EB561DBBEB29,B7DA20471820863C,DB067411ABCE8C4B,6906C405986671FD,4EEA9116F9FA2EC9,8663A158D1E413B9,014ADC8A45030DBD,9F6A7E752BAAA803,0C1609445F94F2CD,72C12C42F203B906,000046251F143946,EE4B7E4B796C213C,E0975B5E4D511610,8F36B464824B0821,DB1EBCFAAEE9F9F5,DB20051C7A6A3104,5498A088E419F66B,892CAD8C46FE5C71,6A46C34FCB4A5CE4,1D2ACBD0BAB9C6DC,F01AA53A36C1EFDA,555433F1533D9C66,0000139F1511B031,ADEC4576F3F1EF70,75125C752F261AFD,66A81FE2D408D061,3E14DC04B58587A3,FAE2CD65C78772DA,FEAEE61C78365018,D5358944F66D310B,D2429841A720F0D9,0E0EAB55553B4DFB,DDF3DC4049BE80B3,27B7C8BBACDDA2B8,0000626DA4787231,AC0006D183B0DD10,FAA71B77E1519C4A,F367096B92CDF010,354AC8E54C0C12CD,A9D93A80BD5FEB5D,84CBCF1E7DB1FBBD,3A3DAA7399B17587,B1C6260E3BB64E42,C0A93F169B0AF81F,EE9B85149661A0C9,CA4F89C86A145384,000016C661166F69,2A27D160C2E5439A,A08CA4B565D96009,618F0D761F6FF941,54194E7115497BDF,ED1A2F09B44F9365,B423694B11C3945C,372E968560202129,D356BD498D7ECBBA,9E54A9358CB4ED0A,1FAA733113EFFC2C,F73A87D1401E1A3A,0000167C9CA56CA4,515DC34E85A3C997,BFC815A672890DDB,103F30D17F4BEF53,D1BEAEDAEC6C9B9D,76B038CA53300C95,79A2DB06DAE21C01,820C0FD84DB4DB97,235032317574F605,EC36C16562D3C17B,A28B034D7DF4B21C,B6DEC434949B26E1,0000119CA7C790B4,AA66C2DF9D4D11F5,A84BB8659A5771A4,8428FEE89550D99C,0368697753D75A81,E8D9C4A2274146B5,C3CA2DB2D8E71296,83D53A6DCE903535,F2291F78B2061AE8,A9A262909B5378BB,2E09B74CDF589B51,C9DF36D853295BDF,000037963EC0296A,FC74315F1BD7B09D,DB607E68B3104DCF,EBDB91310B33CD87,ADC865BC5408C06D,4974EF217B09F688,7A6DAB2C195BAFDF,183B7804498EAF0D,03C6B0F3C6896E8D,7A99E4C0C5DCEE8E,5311BB37137801AF,F49001ADD9C5A835,0000354322FD8C07,65A870FA14D2A38E,A616B6D4D73EB831,E3F21362AB832F80,AEA2A3279ED384E0,3D4FB0F8347F9185,8CC65018C87038EF,76FC27F8A29A6515,97B25729B52A0E01,9335629FD0C932FD,DF7FB3F7066BF131,B93248657128EBF9,000024273F632EEF,0C19B07BDCEB68CC,4D65BD493499452F,4A23B2E0A3361BB7,8638484A7FB4B542,9047A41B16BCB852,1F5AED9A9ECDB1CB,1623193EB0317BA5,E61B9685A267E47D,8991496FFDCB8398,999B98EF8F817808,8A2F7940D732534B,00005A69501635D6,91B541F4B7D82AAA,B5E3EEE1F06A7BAC,CE027C44604F9947,6A22F6BFA2D05DA1,5906EFB9B56197E2,6AFDD44A20240A96,22055F0599176DF4,254D050BEDA1C945,0D5E501391BFCB0E,AEFBB2917590EAB9,FAF38C242061167E,00001AAA51D32733,159DD4C590D10225,CFA460FDE9877381,62E3DCA58F63BBC9,A5E0B5476E524D5E,2CE98A0A25CE3819,1487A09133A370A2,5C94B31E356239F8,75CB546F20DE2112,78D59826130CB0A4,ED61AFEE8E051554,FE93C5BF9F6B4C85,00001751CF00E461,561AF3539BA421AA,FB95DAEB38E65FEE,81A65304339F009C,68A3827E893CE03F,8428B31B4666A2E2,9B33EA7D219081E3,4C05FE1B73734910,49B4FB7EAA628BA8,8C59175BCCADCFDB,8171D5580DBD1A4A,E73BA4740F7A40CD,00001A915C8C63A4,4125E561120FBDBA,00CD5CF137879FD8,2B4F61195E2EB93D,9AF2BE70BC0733F7,CEF342D794E7A034,70789B16E7E484DC,928404636ED44D4C,953890401F381E8A,3B5A5C6AADCD5E2A,B062CCAB1DB9741E,F4A3E3DA0D47FED9,000037CC913BCA7A,32E123C121EB0E8A,665B07BCD168D419,5B2B2CB3A56A5236,C6FC542BB3596643,E615B242EB82933C,9BC0247B28D9202C,CE2D8EBEF7E9F5E0,EE708E7369B2E957,FF1D0E520D2C6F86,85AE0BBCF0B2373E,EDCD91E634E72F90,0000017652B581F9,D293651F41E3FB17,37318AAC2A953811,51EF8FADCA1B0683,B99FA8BDCE0ACB6F,FBB634FBDCF2AC54,18B8E1380FF94B75,B7D50D5A89BAE0CF,1A3AE5B74AE3EC4C,8307BD4FC1C74579,1F13D9FE45F7DB95,55ACAE110A6FAA0D,0000293C8FF12965,D0A4F28D3F64ADB0,26BD18598574C960,4E6D868F9442AB0B,3F9837E17BBE6083,EDD47C470A54FBA1,DCE4258BC6C9A2E9,C1B6D1ED7F1B5DC5,D541EBFF65B21920,E03A8B9216AB7043,C1826B2BA7E20C8C,EB56674FBD17802D,0000254BE273FB36,1E41FA241A66991B,EA1E7D96034B3E73,1BF4AAE4E1F417A9,CFFDCCD09B993CC3,66155527F53CBF31,EA98B4DFFF574F2D,7F0D34C9238D04DD,7B4C4BB8F72613AC,BCCAF8350D615826,031564DA71F9A930,448EE2F4576FC936,0000134A0E0A81FB,DCA64A28B8B285C1,1CA1DB7F6B7F8FDB,F92125145EC0EF77,704B95423653D488,0C402B5BA2F379F6,6E14173F26336AB5,9990D7DD9A5BCC16,70F07D0288BFFBAC,36B61D4DBA8C55DA,069AAF4C343306CA,116F5A4018895BE6,00006A64CAA1CCCC,7650F62284F9CC35,98DE0DF606587598,815BA0E26C463B04,22D27E3115F475D1,012F903A9E91FDED,220D500C799265B7,60C483C18DF51451,E697E284E2ABA941,1F3CAE671CE133FD,B6A5E5715E85698F,824914DEAF48AE83,000008E6C1036CA0,6CF2C09CB6C8498C,9A68834D81173AE5,579B7B6AF0A6BA22,485FD9134B522659,102BF0C44474D204,968677990996885C,4AF6975210961597,F0F81A52AC4D7236,1FBAD0DF67DBA59D,313F2F5EC7307A94,DD67BB1456A6F489,00003201908FD16F,07DDCE6706D46A94,F4CF9BA9A96CF076,1FF929EA043CF7CD,62B299556AC9BCDD,F373C01E5AD72EA7,E79FABFBED018EE7,6DE1DDD5DBC745B0,26E562054FC58AE1,2B0EA08A3C1A2BD4,3EC18FA19BF4C2BD,CC56E69563730869,00004308C2861298,68CDA7E6185CF3A7,F755FD9C5163944F,40E272FECB3842ED,7A83E2E4ECAABD53,8762D8FD37BE72B4,B8E47125C977DB4E,5AA53C35115D9353,2A7E51ECEE43EB18,CE7C634588BAC981,02E4203CCF1FBF99,FF13E075D7A47AFE,00000EED73B8E6AC,FE9F167D976C88BC,72639A303F753766,F32A99852C5DC375,74EE6ED5E2842AB7,67530F53D06D8882,B4FFC7C5024822E9,6ACDCFA21B47EE26,4EA9E1795DC4A1CB,92587699E1F5F663,3EEFFF96069B129F,3FC04ACB40CD72BD,00001DA0C42DA1D7,CF4BF981CECD536D,1C07A07CB33D729E,46FC5F9CFE06EE3F,64AE9ECFFC9C8701,D1C9C7431D29273C,16E7E59B1E96F853,352839D2EA496DFD,B2C5A190194AD4A2,FAFB7A6768EAC333,957C3BEF81CD3CF4,4A5695344E695EB8,00000605C0FAEFE9,E65BCF4217D96B23,6FE581FADD30486A,93F8F91E8FC10678,AC122F9EFAEB3C0A,D96248ECDF73DCD5,7C7E852DB6640E61,E016A921FB516135,D703A971FD41B12D,0E97B15C10C37FE0,BD169FB775B0B343,E2BB2E7C04B0479E,000039856C1567E6,D04CCBABF7D61A7A,B669B8B0CA5C68A0,435C6C7AA1CA39B7,CF5C98404CC27C05,8335CFDDC9073A1E,4837FFE80A560845,B3FA295947AB7BAC,77DD9A4BDA2099DF,62F6099F4579E57C,78C58365DE65D488,AB4CFE9035CF714C,00002B3239EC5664,1A4F8158D23AB98F,3C889F3D69006653,8F8496E927DE13E6,99E15CA5EEF24603,00AC63F6AA9987B5,02D089DF7433E008,AC27F3F01267B7A2,0379CB58AE89F512,865B4A538F924856,A630B6B8363A2126,8CDF2D2EF56D7EED,00002056C2CCC618,D47CAC5198F6C576,5EB1986A3F19D5DD,A8CF48AB4B9E8DE8,E1A74D88AA2AC689,580BFC7782C655DD,78249BC6F9977F1F,A3BA47D6E4BB07BF,F804F23311898295,901F45FF6B9744E9,2469F2132B883098,CE8DB9826F0B59D1,000039069510948E,26B0FFBB4A3214A5,A5C93B1753A035F5,E2B6CFCA6561DD1E,257E988EEC8F5F34,0B177F5F88561A23,F62DE7C275E7E6E8,A7517896A71322BB,E5D4C4BE2340E2E1,B0E4F762C15121C2,301D9669F4D67EFD,87C0798CB6524A47,00004E58B5CFA352,F32ACA7E5BAE0A09,3A6305AE3D3792CA,924E6BB2EEE1FF5D,EDF6E429AEDA2CFD,DFD499766A871CE0,07F0D9E28A64CF16,36375CDF14658893,2DE493010D7EB804,A1EC9BFD5C4BE3E4,941CF1C5090E99D4,68E6486F9342023F,00000808830FF96B,EEBA370CA8F853F3,D5BFFF707B3AE0C0,3CD445B9E74567AB,C0B465698F12E16E,916542EA2D1A10F9,AA2F18D79EA01ACA,19B75C5000050B6A,1D82FBA6F23DA37E,774457AECD003A5A,57E0993E71763CE8,C76F538EE4635DB6,0000104A0B6E8466,AA7F21427F6ABB5C,BE042BE4485CEF77,F48BA7F52B6B4BC3,E40D12D9595F8621,BD53CA94998CB75B,E24CF40BE5178DA4,5CC6FCE13BE09A38,6F4139F7CCA213E7,A839F7621801A84B,3D95BF704A0EB6C0,22544E367A5635C5,00005E5E48D098CE,C9B05BD933194E1A,F1FDF2CDA84DF75A,86B7CB44148CE012,117180112AC898E6,9CE66D9B1B65853B,2E0CC113BF56D1D7,02A1730AEE358C98,433EDCA5A04B352E,8D05F588C52A6723,761BBBFDF9EDB484,109ACF2885D1B4B2,0000533FFB116230,E433976B834B7F25,83B308365B686A76,9ECAB44628A2CC83,F42A8B8792ADF191,1314FD1510E03D8D,46639EE129923A69,140A52991C11468C,5529D5E5DDB497A7,E0AE684B3845BD27,991CA537608101CE,5AB6467B0425D6B7,00001E2400A53705,6E06BF188F6D4B5E,1E7210B1488CE380,80C4ED8C215C1FA6,FB1B28C7068FB2D8,B64973B970F69704,E9D0FC300BC5D595,8989B27E7EEE8911,46647CCC159B6F55,BA926E9C6DEF3361,AE142E899960AF41,090EA6644B49F528,00004901E690CD55,327B95430AEEBDBC,C536C19BA9056432,6D3E3E816AF3F5E5,EFB9448E76179B26,D7FE3C47A700277D,E38D7F4E6A6AFDD3,358D1577B6FCCE5E,EE81DF369D4E2C28,A2EBAD34D63FB8A4,8B4001BAEE0352F7,47EA51F3A930B548,0000675D29FA2942,DDAA90D07BA6D943,3609D4F5A6067899,C095AC8E2C932277,29ED986DDDEC66BD,9AE02A8B0DA8B9FC,C132753B2116300E,4CA6D00E3281472A,097E1C16FC32811F,635B98591B62FB58,1A0B88AD29A75316,C94CBA22E589DF75,00005DD2A08E2134,FC752B768E826158,9CFFE38B53A9836F,0459434312114CA0,ACD2899779B4F361,BBC2C9B13E830D6E,17C3C0637385D098,E3B7620096E11FBA,830BE74234D54B70,9BBEC200D177AEEE,67AAA0152F26E98B,0C5363F5C473D8DD,00001DF6252F34B0,5597DBA0515661F1,E01BA2CD34ECE024,975C83A99D25F0B3,2DB4A81B218DA2E3,B5CCAAAB1D71FC0A,B843CB565D61AEAA,69AD1B86E04C70F3,7CD92246FC771E43,B475E0C4614EB708,15DB76F300196A52,034B5DBAADD93B1E,00002961B6B03535,D1A37478DAFABE0E,313BCD0CF737BE1D,71F7121638DFBC48,6EA60DE134281C30,BC82CACBB01356B0,102746B81C21CCDF,9900EF7755261A5D,D89E76DD6C95EFB4,8E168D1DB77D37EB,61C1D21A7144073E,E0818D6F01C8425B,00002D0D39F4455D,6B012D10ECF3429E,FE57C8C0D8AD7BAF,A7EF217963727561,1FD782F84633E7C8,1197165D36A89EA3,E318866D3F1C5177,9E98E47AE914DC14,3855BA951BF82151,AFD75E23C24C3490,5381D0BAB493F4D3,82D1693AE0225FD6,00003581E01547E2,0315AB40AB04A767,A88626BBBE6548A0,DE692C617A499215,0CFF815AF4EA496A,01C420A21BAA3746,2AF27508D8D6B026,0FC241ADFE889315,3D898A1B0AC56631,2B047A9264DC7A04,95BFC7DAF29B80D9,CCA4D06BA7DE465E,00005E7ABF294F5F,AAE85DC02057F054,79B7B364E962FE11,C0D48AB1984C3096,0C12950887425174,9E0EE32DAB985BD5,D548915C7F5FAB3A,A72EA7F382F26A16,E93920CC0C0B1D37,8375A4E0FCC88E30,B68496F2F0973BCB,89C38235E444C0EB,00001F51960A7FBA,EE874FE968D29386,8A211E047C74286D,06823DB77D6D402F,57F4875AE8BB64CD,59C12CC715A9FE5C,0DFF82AC9C2D41E6,18DCBD7784DB1F91,F370B7A642A5EF65,AECD81276E636FE9,5C60446D24DDE0DC,763000D04D1ACF9D,00006C261D588368,84B4C599B28CD984,77A31B76F762799A,A1226590C575F7CD,0CB553BDB779D936,0B725219DBBC029A,C5A70880B4210897,A3952915C1B12094,A0EC3FEAE1804998,3068E2268096E6DF,7B11747D57669FE1,3730F171E8551235,00003F44498AFB4C,CC63E86FFAA0ACAA,B1377C6FF31809C9,1577D922CCE3AA2C,4FD42E85CD1AFDCC,6B995D413D0EFC27,D252910504436142,D027D313E613A139,D627C1523B1B44A2,DE073D18C9C112B0,D4F38E0CD207FE4A,BCD9BBB76211266D,000038EE13C822CD,D28B20237E3B17FC,A7C7B030228E442E,109C23DFE6E04352,D3A7DC6F892A46CA,9899B96582EED6A7,84ECCCA4033B2B43,FDC6C1AB88E675F6,CA6A06E782EDE57E,128A4C61A16B5A11,D587B046E4294692,44FF745C131F453A,00003FDA7354BE2C,BC98376FE164C7E1,C31A674CC9EF33A2,B1851615A18C4D6E,855A9CC1B7424A24,584C6962BA1602D2,044D32113354E185,0E6715D5EE6F7EFE,28E8FB6E06D17E3F,DB9E9F1AC7501AF7,5B4827935129C9E9,E5D256A4207B10A3,00000AE776207A03,1031095E7208F0C9,17FD098B262EF7A2,0A6DEF317654C69D,A4A37F6A7EC8A540,1D1EBF1FB5C8191D,E359E7F4893A5C25,C10336B74B921FF5,A73B6ACCD805020E,81ED815DFD0CB15A,34FCBAACC53FCD1B,C14D4FB7F9928619,000038BAD2AE4DC9,9D6E6049BC63341E,63D06DAD366BD812,B500A46A94787CB8,2B700640060B9816,41C55ECAB78E281B,BB7063C762BB1DA4,260F356EB54536B7,2AA21AA8289D5E88,19FBB74FBC85D30F,36F91C0AFDAC0C8B,2B60E273F008185C,00005153AE411334,D6FF70F76BD9E22E,DD88325F6E11A04A,1208173A25308A56,9A2FC76B6B649C51,EE911855B80BD757,6AEDB9C6455D965E,F91F205CF9182831,3161AE68EDD8DB8F,0E1788CC7D57F0CD,975EFAC7F316814E,A958BEEB07833D1A,00000C4CFAF24FFA,325C98DD35009D4A,88E2578A3D415AFA,1CC549ABBD22C298,0A68FC5055AC7837,644BCF14B629C392,70CF0ABB8BF76AC6,8802BE53BF1A7E20,172FF328B7186A64,C8932E707536ECDF,81B57FAB9E0E4877,97601D752C57F6D6,00005621BA573991,6DACADB4C0CA618E,EDA30BFB6CAE3449,37D453BE45E195E2,40DADECB5E3234BF,A149FB7734ECAD56,DBAF530B3A2F8EFE,F6E2B9F5B45E453D,E7749F4C894FE97E,00D74595A2CFC124,FEA1562D462574FF,FD57FE4F4C677713,000020E76E8101ED,3D2147341F661DC0,53D91CE0F260DF69,9A4BF3521329E281,79D3CB69AA0BFC0D,A656B76477403CFF,4467106920A35FE0,54C5AABC6321CC03,B3A9B1419AAD16ED,C8930E4454457FC8,ACDFEA703E829CDA,B0818F20272616A7,000027AA9A9A6A19,5D7E1E153FB1FD9E,B8A5870ED5CD2964,79AF9FCA6BE98942,099E1646E4A9682A,140CF559E17531CD,8A8523FD5470106C,9D2BB1F65EFD24E6,6AFC3BFEC19E0EB6,14E84602812AE46B,4AB2D48B85699B79,150BBC1A06FDF231,00004C3F0ED22412,492FA745EADB0691,749C6CCDC0E86DB5,FFAB2BD53074E5B9,BA4EEA4DDC4C99AD,56D4FBC8F81C97D9,81D64548D9C08B99,8D9AD62A00E77EE0,C96E2B5A38E8DC2E,4CD1F1E5AA8D71E0,F3964898F0566C02,79530174E01124B3,000026B736CAD020,0C2CCB55988549B4,0262DCFD48083C78,A184ED074ADFC7C7,6B170D26C8D18E26,E64861E7D9F4EDA4,8BC3B8DD5922F8BA,02DF4644CB94C5E6,D6604FF77879A065,743E532D4E9C4987,F22D6DC980074614,E8BA55C580FA51F9,00005553FB8FF4FF,20CEDA4301C70C6B,1F1413EC2C393EC4,6285E9BCC0BBD24B,FF04278F1AA439BE,AB69E783ED6FE30F,EE21170026CED4C5,A5FF33C613DD8BC3,20033E16CD5ED962,30B69820A47D6B51,7CA8BA846E62005C,E61121B6D4A721E7,0000427195450457,78F9AC6ABC265A9F,91FA4161FB0EA998,18ADA8B23B985FC7,00E39E7055A50C0F,31BAA529A0AD99A9,8BB61A3AB48AD76B,BA4C60B9A44F808D,CDDEDADAE7D4AEEF,E6C632EF21FBC74F,033B032AAA89B54A,44AC0F6CBE75C270,000018393B60B68A,74268D7EA121F9FC,AE473C4199886245,3591F3C8BE2E3661,2D718DDA0862BAE7,F5A84F43861682EA,569A46C466626A95,20573BF55711D6AF,8A435D9A725EFEC0,C8AB23101291B3EF,F925F58D7F9F8E2B,D2CEAD159C772717,00004E85990866A7,4B164B37D414CD9B,B811777DDA398EAB,07EA14ABF4772DA0,134AB8CECB405C1C,2A839943210D09EA,C6B7342027236F83,FA7E15F01589CB12,58D15B9C19C709E4,8955A610E68DFC67,8981F10D0B6D6BC0,7C11A28E8BD42DEC,00003F1C5933D869,4C594C2590D07BCB,CB6310743D92CB5B,19C6403914F4ED42,4608E389EFAD89C9,2399C30FA54821CA,3EC5D598205CE25A,2C58E4BCD5814176,7467737BF73C2BCD,31D4DB546C9EF0C4,F500EB031253715E,EABE08373BE764ED,0000494CF5D3941F,BA58A640EA4C9235,DAA26013F74B83A6,BA03726ACCC2C280,688C08219CDCAFE0,7334C94EFA26CE63,2A655E1D55E07594,00EC0A3B80D32EBB,9EDD1AA393144997,57245783E785E91B,410DA44A0A892D29,9C3D5274FF01F19E,0000105ADDA2C345,400A5EF4C8BA16D0,C8C13B938B0A965E,16AC6130DEE178B3,7D34F049275415DD,E9DB2EA06BC8E453,35891AFFC0B7FC6F,59BFB83414009308,658F5DDF09C58F37,ABFFC23D3EC9E3CA,1DB809BDEAB6F17D,BA8F221CB2DEB6EE,0000214B127A328B,42F7971D4A79C42B,D5DBDF1D751D411E,8FA54D2D69810FB1,1AC0C86A09AE036D,ED549713711CC20E,EDF8B84F8821BC1F,67EE7FBC193F33EE,4931CE9A04A97597,51934977894A104F,644CB9135D192BF5,73F626D683D820C7,00000CC7CC74B108,9A7B35D55CCA8845,82AB407CF1F1F3A4,08EADDA156686857,7142DD17F354650C,9DA425FB562A3406,C73E376A60B7C1AE,C0F757762AC6E91C,A1B850460361EA58,45700C98CACC5A39,16544E25A36D8E9C,7BCB3E77A2A1E2AD,00005677CB6B400D,D51FC460CF74B773,9E43EDE492AFE342,ABEAE7EEB33693D6,8BCC599436578806,284B44353D7D0684,C8E42EBB212F8144,9D0AC58866294E81,F62912B4710AEDB7,C41EADF5178B99CC,F17244527CB7B09D,DF3977929745F91C,000013E662A6696C,078D3D67495E4CCD,00CFF1792DBBEE2C,5BFF2721778526CF,BA63B612658BF18E,EDD4F04EBD3ADA9E,F0FAA3ED3AD2743A,2FFECADA89AA2A5A,B62E2B3176A505D3,32748B0672B04C0D,C41DD069F3588E81,E3F1554513215063,000053305C4DED81,E3F1486F6F019A9F,F8657F1E58E0CEC8,6A18B294D00DA79C,824988E99CBA8B76,0EF02A27DA5561BE,7E4FD92D63D5BD3A,088ACB15098F44CB,48F49731DEC548E7,1A05F9E44944F739,0F7374C715A82E08,261426B4B366CDD0,00005B9E8FC1471F,EDD01FE1D85294FD,DD42810CF707F19B,03264DF3CFEC00AC,3E49D26741A3E46B,F60D3DC2BCF90065,C19FA87F6692B07F,943C8B0A84D9B312,5DEE844B832CBE20,A4D3325B5135D4C4,8AFDAE9B7E875660,5106FF984D5F50CA,00001773FD29A68E,1CB49BBC80030F4F,E8B388E6E3F6310A,405FD3BFDCA0BCBA,C6A8F07AB03F40FC,CFF17F2CDC278C33,926DC7482357E522,A5512F2D0793FA4F,00A4600B23B85F26,23B223983123ACDC,D8081983C2BD24CC,12F2B5AE2233B675,00002DBA2B917F53,7A50888B8125446B,C47B1AAE5E2EB37B,429F09607E8C0C27,F58F2DDA8C11B66A,ABEAE1E8D516BC8F,907701235017A3A6,5500A4C2AED1D33B,F0BF6975C9E060F1,E50C35E563EECD30,1A32B815567B22AF,8FF9C0FF5D005A5D,00004607735E3A00,A42C6EBA3889B4F7,F39DA1BCE7C1DE75,7324FD33E164C44B,EA6728CF81B7D9EA,5BA7DC7990A1532B,6D0C24D776C93E75,BE9D19FCD6ECE840,F94853ADD0D394FF,155D170E2EE7D9DC,0000694D31D72F36,3E527789B4936485,0000103347B7EA7B,150826EA31CF5B36,791EE7FA1D867D9B,FED0639963E2E4FD,8E056153FC8DE2A5,D65A2FE430DC056C,D72E820021DF4BC8,03BCAFA199239C9F,9DB41645F78552B6,E9472093776D861E,4D2BAB59984A859A,AC0D1546606758AF,0000113BB2CF6E7E,45DF353A05167A36,5C7BEBA40611B73F,CE9D644F69DEEEF6,CE4AA7BFF449FD7A,0A860FDC1FCDC569,9FC7E5B11B90205C,BE68B0FB27F9E1AF,83BD602E413940BA,83C66C574DD59DC0,1D6999410E60ED4F,CF126BD92CF74130,0000287453F0C3B7,D7B1C77DDEDF34B8,927AE0297C58296E,C94C117CD5BFDED6,FF7932EC340BB9CB,8E59E5108A3ECE79,E0612F8730944B00,37451DD869753271,E294AABAAA6D58C2,29FD1D97168227F2,B82DDC7904DCF8F9,FC68016A6E00FBAD,00006B37F90049E8,CA800D4E4EE06414,D4811201D9DBD6ED,764113F59E3FC14C,0A592D4C83683570,BDA1773596393B92,B31A3B7E6B7BE11A,3E70BC135DF9CE5D,FEF93E1630C635EE,A1906CD71254FEAB,57E0275095419C3E,1FED98DF5E9B321E,00002ABA5E76831A,AF0ED581EF6686C3,C6E31C1E2C2BA331,06D3D02125012AD3,EC44828F1488FDD7,E5974AD599700226,A650EDF52783AD1D,EDBB7E01AEF45DD7,D5783925DCBF52D1,1A6EF4C52A044518,572739FE31F2D9CD,C8BA6A4FE59BEC97,00000F59F0DD5A2F,F09005BAEC861ED8,D561A825013100E5,B1E0E70C453B5EC5,0E510B64933FED07,0D4B3615DE6D4777,345A4FF455825B45,26EF90BA1F340D37,114887E2B7A841BE,D6EA6CCCC2409540,9B7E494F48C33B2A,B3F15B2E313772CA,00001280C82FCA08,2E614FF0C71C9414,E0C3C9C2F1779024,27F5A4CB484FF49F,C821C05464865A0F,72D54650194EF134,DD3A577C0679DE87,616AEB7704794468,63451AB391DCBE4E,13F336A2C95A784B,397C7FAF1E1DF259,220E36E81AD3704E,000065AC6302DD38,51E954BCCA2B94C7,365815AD2853B3C1,641CC650FAB7F975,41F40C88196BC5C5,0A98FCEAE567DE0D,B50B77C48CB24719,C7831B2DC8CD38EA,78E83829561E991B,01C26B9E11A68F93,149CD5D9D5F54521,A40F047A288326A7,00002842A6B5036C,0D5675DD220BB886,353F64710969CB41,7C3EFD0ABABFF2E5,CAAA7E0BEB2700B8,21E1213DFED9349B,B22F58C4E3087237,E3F94DE8FC09FEA9,A4AD217C312431CB,7BAEB1CA1CDEC212,2378DE1509DB19AE,3CDBE51F2DF1AC4C,00004C4742ADA540,7709D9D35FE56DBC,2C7B686342A27A89,32CB472BD7E66A8F,6D10639D05A0EE81,E964AA641B288E1E,52746F24CC171477,97661670D6597A8B,CB8EDB7A9AC143EF,1DA8CD9B58F5A3FD,6EF61505A1A1C586,D436797AE6301B42,00002D4C5F3775EB,AAFF0943E3BBB117,A44A398296CF294B,76D19BD6AE3B512A,834C8589AE89CB53,C09840D7E3B7BBA1,59B5E6B087062BFA,7CA378687A6D7479,514825FCECD9AA86,E7EFCB48FCB2F01D,8C0A015BA825A3AC,B15BAF8390FA0AB0,000067BEFE7A3BDF,989848E2B43C1092,B9E611465B29FF5C,8F7D5DBBDE5DB068,733E0B37B1BDFA35,4AA3BBBD3DD215BF,B7C4B99D17CEC9A3,7D3B3D04A466C614,8CAE59E026DD529A,8C1A0250EC029866,3436820462F8B863,DB552D77D731340E,000022346D649964,AEC654802F178002,2784BE0DBFAB185D,3FF5F85CBC104DFE,9E71B8BED0604D09,B1AFD39EB20E52DB,E4126021ADD38C4D,F30B9E92BA96F9CB,F4741A2E488D0EDB,446C7BB87A126533,FF28E3C5A65BE611,51E2F91ECFF5290F,00000CA6D7785B68,51DBE76253FA70CD,A865B0C96131A755,58099C164E381D73,C3A189E019B01C65,8CDA92F017E6D2D4,D10987F77688FBC8,16537B42B5B28E39,2722D233A723FD22,B495C22B57894248,5FF875F17DEF720A,5D1A48EF3C6AA24D,0000517AA6A7416E,DB92C8AAF3003D04,62F238A51A71C3DD,F8CBA427327FF88D,692BAFE8DD0185FC,0577DFE7817BB2B7,16444CF4C2DFD55F,F5A48C67B35DDC78,06737124193D00D2,7210C91637E7C99F,576004CABD61DFB2,06AAAD2ECF8CBA97,00005D0B71D128C2,A56EF3E5D0CBAB27,6B72F9EF4141AC09,2AD416289833C89C,860842D3C8B51280,CA068AA19AE6BBA4,5C2002DEEE08C512,4D0A1561E1611742,EC07C5EC3A7A9926,B29FC83238287D1F,BA42FF92F75EE724,EB400907939614DC,00006BE9000CCBD1,FF8D3F9D9F1DDBB4,8228EB717450C3D4,E2EE506BA49FF717,33F99835827445ED,09D7B10DEE36FA3F,2574D750ED0B90D6,0B12B15759EB3E59,7D45A63776521F56,5CFC1669357ADF25,2167C8F23A0D8FF1,4674D1A052ABE8D3,0000258D611A51D8,C010B70D9A49B026,E5793712B958E1AE,CC99F73C04D8F247,A5FDFB564D708E9D,658FF016F4436A3E,9C524A9B4788E661,BE1E1D09BE05FE28,9CD24A8E944A27DF,F9612A3EF0E9078A,B3377BA21A2A4D1B,4B19368F4EBC025C,0000506F4F494CD6,E61A9CEA10BB138F,48B00F79779E438E,1DD29F4E8AE8AC0B,64EA8F1C76C148BA,00465DE069CBF323,7EB8E4F81F63FAC8,83604F634565B046,8A7CAB3EC58D5C52,9A3F67D149137611,94E893A08CD4948F,8A8DA34FE8CF5249,0000523AA2985429,AF21983647827058,1CE5D77B4E6C55E7,9913EDD703E673A1,98CD3AFB511275DB,442C004D0F838431,3A44497FBF9BE913,685345B76F2E432C,BA02165878BA950D,A8DD39A062249814,A382BBF19AAB0B31,6CFDD0B5FE443E2E,00005413F2E64B97,7B0A04952CB06679,0E0667DBF652D25F,D4ABD277F847E0D4,24FA83AD262F02FD,EBA2F394F680D7DF,C7011DD32ADC8D8F,AB81A179FCB870D0,C223C332122A303E,83319FA06E69FD75,D1429137DFC3BA5E,A719B921C00C825B,000065E62BEAEFA6,51417466159DD4D1,7791C6BF393B7288,BFA97DECA590AF28,41D9F039E2BFC209,0D24DCBAA94E730E,5D024A0A6F07DAFA,5EC6D012F10F0881,229B10F62D8406CE,02E38DA809592637,769A95C02317879B,B9CB4954E5398A78,00000BCDDDF80F72,2A22F023CC7269BF,46568E202297BCA6,B15CFBCFD052AC03,95283DBC00CCBDD5,AFF5FF4BB1193960,C828A89DB48B3240,E6AAF0E16A401568,52120302F51E372E,025A9831FF3C0442,E8C2ADE7C9187A83,557D5A9EB484BC25,00006A236C7155AE,6177B8932B28D836,FDFF07A47BF9A346,B756E364315073D1,C6525E26DE121DB8,0660D45AC740D5E0,994F16CBE6EC907F,2692B09CC3403182,89B8A7C2FBB46C49,6FD087745CE63845,58A25CBEA2517496,BEABD842A650B65C,000043739B8992AC,280C11839859CA77,7A9C5DFF6F0F0D27,6BFE6CC4BAE3152D,E2045DF079426E58,24BFE65D7D0E4BF4,4D6F2C119CB0987D,F6BE7A9B10D00577,8441A22214259056,70BCDFE1B3C49400,1510387A21A97239,57FDF061F33EC96A,00002ADD84E95DB3,B2E429E4FF188AB2,F12C37B0B4CCA6D5,683C39587D712F68,BB5C7A54782A5FAB,36C7C7F7EEF1444E,0753D192AA7F6017,EF8CB3DCB3D24DB5,92CEB9B2A9C523EC,2E3922F3F67ED662,6A7B1485CD5391ED,C9130F2CB1FC7332,00003E61C12D5DC7,D5F0CB1F0E0F9DEB,37EE5BC49CC13A09,162BE248849871A1,0F230B4C2A2B4DDA,949A7782FFD9DE20,6D74AF5B74F1B2B6,450F2C7B4627689D,2A141904574ADBEB,14D44B3128E86658,0B2F8C454FCA7E39,97050B16A9E2C83D,0000192ABE2032BD,1B2079D019BC9432,FF0CD3730FDD4252,67C15D679C86A397,B52BAF53A9834237,D4221DDD887F725B,B94BDD612BFDF732,E230963FFA8573A2,AD8997E26E043A4A,997281A050278AA8,9FF690D74F4613C7,1092247CFD6C7AE3,000062CA36984502,AE942591D168C9D0,4DF62CE1AD19764C,E2F283D7DB59BE46,629CDA96573B775D,06F9BAEBD57BABB6,1F637BBBBA24FB1F,D874304CD4D2F4B2,5F762000878F2D65,AFBB54C3720AF77B,DD0B9638BA898C3A,1C357012DDDA0DCF,0000110B7CA436EF,E7716A526056A4AC,0EE966C35E83D709,BA1518C11AF798E1,F97B02548F27E818,C035B879421A5C62,E833DF9A24B4A481,82446CD1C5AC86BC,44041FCD2FEFBC86,B3C71C9EBBBC615E,8DDE51BC66D5CC12,AE8155D6648CF41F,0000520536C4DD30,24E27A67B40C8BE6,3B24AC478C9DAA35,0298237E262B8B40,145B696E838E3F3B,78C1C08B0B9F60C7,C8E9968981195D00,64876FEB81FAF23E,8E455159D6A36432,C9721C27C7075E7B,35CE9FD4F4D8EF06,4FE9475A8765D918,000027DA9E194682,BE5F994FBA06F5BB,D82F0892C0A2BD66,52EDD651D7734219,5D9BB21F85BF9692,67E493D44F8A7D4E,F5D8232E0C8B228F,E8ACCDDDF96A0928,A35ABED950EC36B4,0109B71FE11A34F8,681F2EA66EC5697E,0626D0B0BB94FFB9,0000001900A85851,9AAAB2F2C926AEDA,D4DACD17FEE436D7,7EB78FA1EFB92FC1,89F528A3649B720C,DE7396D28350D3F8,7A5E42973ED617A9,33BD05746F881993,F7748239D290436F,B3B1B75644DDA06A,01B7056466F68919,5075BC4CAF582C16,00004C4EC585AA84,63F60A34B94FED56,678BF91F2F940C98,852F7B2CA7A2E72E,4162488E6FC72D76,93827B96E2E3B662,08ABF1FDAF85BA0D,067928BE1E7E22B0,A7F78488E2DE9EEA,0C112E5A1DC5BAF3,CFB36872B1A2B95D,C57A56C828C73644,00002CF57EDED814,190440E2A5DB8CE3,A03C5963F98DE285,B16FCD28BE70E298,D96D3957B26B0B74,7E2516A619942E13,593EECC47293E4A5,D774D9EB99903A35,3A3C0E0AB6B4354D,5F50E24E3D6F0991,474AB8065782EF43,D3F776DBB4952239,000068FC0514D3A3,DCF59D46EC7CA7B1,CF8D17F9A36BF8D8,7E6BA91B9CECD5FD,6A227FCD6C68AF79,D14F18107F85A3C6,3D8738FA1371C9CD,7BA39E5E465FAA26,4EA5F40636422113,20D324B0593D518A,B94AE98A4A5BE9C4,EBFFCF468EF27EA5,000030D206A6C068,A7A7229EF8755420,C6AA3F2CD76FBBAB,E1DC64A95BBB20CB,5858E1BC48B55B42,DD14313D672C1D76,70D4CBF123DAD361,A2C9D9ED222C88F1,6F534ED43D7C6B5C,F6D6517E66773141,DC2F8C4FB5085517,59FAF6E02EDAAC43,000033CD5BAFD7B6,8ABE08722E0B72FC,575AA832FEE899E3,A9CA4E5EA3841308,68475B8E5EA67DBF,75C31F9A326B3686,B4C0154A93C371C6,C0C6180E86811799,DA51B520BFC7FC63,F83112A87119AEF2,DFE93962BFD2ACC9,1F2900B0EE57CC56,000021936F17BD31,8FDA4EA577AFAD67,1545C879C3758AB1,7715B08FD77326DF,549752FE1BB4AC10,91862981907E8AFB,357FC75C91E8A44E,1EABFBE16CA51609,61B95B1CB61DF1CF,144573C660D81837,21D39F03F2530C17,683BE786AECC46E5,000059FFE81211B4,FDA3908D619914F2,7722D8F368A150FB,F7DF58AF60D7E5DB,388CB92AA536B524,BE757C469EC82513,2D64D21D199BEAEC,CCB301B62E312D6B,5F4EA45ECC5B8E9E,788A68FB078F2413,0E9A5F09F13ADAF9,10E064DE7964B676,0000440F11E27E67,E3446E78C99A707B,E95F7CE3CF99C917,A3A83E7B515960EA,B57BEDB3B3A29C5E,51C8613BA28FA516,CF172B4B33886448,EDE752F82CCE4D4A,7428C3F7A8D66A3C,CBA205B8D2E9A5F2,BFB412114DEB5EF1,185B1E923351064F,00004FFD3E86F507,A1D4ED9F757318AF,F0FD8391C7DA2A48,BBD965B14B0219B9,C035A4276A197031,9C434D987F34B5CA,A021B3CBD88CFC22,3828768F569B1550,AD13A9E90D76AA7E,532F3359FF73FDB5,24E700DD88F4B3B9,90B0F85B9E2C33E0,00000FA0D9669AB8,8F835F5E31285D6E,854F9FA8303782FE,4250AE064E15C220,18ED140B08B3C58C,A35D051286582A35,3465B4B67904F397,701083BEA5418196,ABC13779FECA8D58,3730D9F0E3159248,3DCE6AC1217BE397,C21EE2B255463B1A,00001E59F30028A9,D11991150D2AFAFD,5A6FD6D5E193EB8E,ECC9CC978F04F5D3,F14908820860B444,E546532E736DEAA5,7E01C80D1B18F397,1ED477C59BB7D2B5,32BE7D9E33B4D4D8,20CD96EEFB9C8164,13B65599D6E0A18A,E86D5374F6A7B157,00005E41E1B225CC,76A9EB1D59A5E648,9079938187C24ACF,7B36CAFD4A4E4EDF,7636D265EB1750E1,F1263DA8A64FAA8A,EA045E6503E804EE,3CDBB5228B46738F,3E572E7D2D2BEB51,4E5199F7EAEFC4A1,ADE4EF31E926CBB6,A5961A8C4CE19A7A,00001AEC4558A8AB,B16ACEC76629F0C6,6D97AC86DC3AE427,B9501A81AA165132,B8DFF97251005178,C2582CD10CCB5552,D65186D8FB9B4728,8DCBA19439CD7FFF,1A0CB6068A764A4A,A598704613339895,CBD3245A4A15864F,8BF2C787160F3030,00005BDC2E3F429A,3D8620D568A65581,C78E38738FC2E5F5,CB4931BBBE75DA13,3A56D6FC7DB2B85C,EF6554C4C98A4BF4,214615EAEA8A9100,E45D6AAC4BD697E1,D76C2083572252BB,49909CCFBAE7A402,F96D01BEADE30E76,34E290BCF896B3CB,00003E0BFF3D8240,E6DA67F12463B307,E658748E6AF3398F,E51D5557EC25ED06,B2274CD01A56B6B7,7A8E7C346D71F6A4,7420CA0B4081C5EC,EFE9A4241CBC740A,20E7A3DA590CC36D,BAA8EECC7B5EED5D,33EB48BFBBD2BDFA,C9F9FC113408CDFE,0000130743087936,AF7D8A77FA9A7D35,DCA8DC4F15E34905,28C978229CE8FE7F,0397D23DC6FCECF4,BFE0BAB4DB55F0DC,91A3D5C0AB2F1874,5DBD37E2209A8083,6170AD1EA0C4B7A7,1ED3211FA2110A9E,8FD353EC4738600B,F3F5D3860C9D4DBA,00006528AF1AAB6A,75DEF98F58D582BE,A9BEC8C938EDDA21,5D85F05BBDBA16E0,50906EF8B8435ACA,FD48F9874EB81811,D27755A2AAF9BF04,B387098F5B6FD95A,1AD7ED41846FC304,DE27AFE34BE70D39,E94008807FC54D9B,B6CE5608EE3B65A3,000006B9B293F0B1,48BEF687D56DA820,98A1EAAD8C7D140A,885383C00B07DD11,3E575EF2AD944383,760D7875B9A05E51,D415552BFFBCC328,045B24F48187F603,F6A126240E03F7AE,9D826785FC737F63,677EF3B1A66F50E3,DBBEBE0AB495F1FA,0000350334767473,EBDF44EBD6EDD0F5,D3FC43AD69FF323E,6DD6DB6BCA128C63,C21B9A7B31F088A7,A2C5635135B69FF9,8E1BFA3330E5AAF2,65AED84E09EDB3C5,024786EEF5BFE339,18CB2AD8D4B353AD,D9D0B5BED5588D4D,E7F350F0DBA67163,0000564281ACD43D,ED664A23916B509F,71155D28BC6B2E58,20A242551FF4E4AB,71FE57D957365B87,1FB08040EB77A37D,0883B8999A48310A,D7FEAE7F1DCBD562,FFA707EC95BBF531,710E39AFC00E4DBC,5182DE776AEDAD5E,EEF207347E3A80B0,00002E788DCF9A23,A0FAB0DA84709B8B,511EA074D91F5610,E4E95417C5333212,CBFB0B8FA68AA663,45F20DA8C5E4BD64,9B20E6C9E90F0D8D,7B82F5245ED36629,6226522C3B13AB1D,D113793C2C24E455,BC141B7D56B134FB,82F853C6745A1BCD,0000012CAF47D540,D4E10E62952C5707,B28ED60E3802DF19,85886C88C13AC551,B99B39A40E90D4DB,857590D900D1D7E8,68502627BD1BF740,7EBEE6B82AD8C25F,E141546A314572DF,B2E3A45F05993113,C6241E8B99EADBC2,22596FCCC2E0FFA6,00001E137187D4D9,69344374C7A31C94,0E448AB016C450AB,55E4784BD85B9FEB,E390013F6C6917FC,9C8DBD1C0A264034,3C155F8426DBF874,BD235BB7BB321469,CD964A2C661F4433,68884EA70ACBA3B0,50A5810E4FE02091,BEB8139161B5E358,000017EE567FA34E,921C5FBA00E3D02D,3D5DDF3AD24C6815,822D958AC85C27B5,28D864D16065C001,DC2E4CCECD4B314B,F65F0CE32408E994,071903AD1BDA6C93,3B525B3784F976C8,FB52F2F5DA08D756,AD18F4028862E7CF,FC41DE0F1157A9D2,00000BB7E5EE4CC3,CE6EBD31E53D0839,BB56CFD77A4E6F5A,AB5A3525A6037440,4ECFA48BEE6EA2FC,F86F7826993EF5F7,B1820D4DBB49F7AF,FF439E312DC8B2DC,EDB3D96ABD82FC0F,40A3B54EE9EDCA42,8EEE1AEC060CF640,AE84A865C53DF781,0000658CE0CFDB8C,ED0E88D24BDF1235,E3A32F7B51631221,6E8EC2B43FBCC7F1,6B60731AE87F3192,2632CA5EA4E297C9,B75576EA3A0344F8,7DE900F18895186C,C0C7CAA4FD33440C,933F399EA02174BC,270905A838D71BFA,0C49ADE7E141E9C4,000067311C9849D3,333728E7265CE154,284EB9F70E745822,3011D21C13AE7A40,C0FAB3DC592E3335,62116997F7684DA6,93ED3FF0CEDDDB80,04B5D57E3E2E39A6,7A30B190C2765BB4,C08B9FE39C6305E3,72F03D76D81545EC,9FD18A35FE463B0A,000015159A28FB30,D5396F4CE7FE66D0,A095735AE757E4DF,A647EAD6D0270D47,99827BBFC7E3F1DC,6CB03D88B52E8E90,1BC3D0CB147BCFF4,EEA828CF2385FF25,9157F087CAA34D06,7B8AF67DEEC5339E,3981549642ECBB27,3EE1261831CAE37F,00006AB5DDFF7D03,D47B616F682FC36B,0061B00762BF2355,AFA2A2ABBAE32B97,69096F83CFDF7297,624C7973E7DA9131,5224D513E6E30178,D31C231426296490,0D63AF18382C1B75,13A235D9827DAC71,A304C599843D49B9,954E9FCDC0254EC8,00006A2F41AFF021,93EE6131DE8934FF,66F0D1D3A514DEE8,9E84DD3433A65FFB,03D5DF9847E8ABF7,A2B4BD8EB6BE5878,653B4D9A1B0AE33E,6B1072EA40411F2C,F0DCCC748EAD580C,267E2444C6073B19,E20BA85B9ED52CE9,5008A83AEEE59B3C,00003D248633AC97,F04CB3DC6DD7646A,71FF57D4E6C8DFEF,3581065243F3B2B9,CC3ED4625EC6F7E6,98E1CF39C1CA0FB5,22B8A1ED0A830F8B,C3F29BF39205F34D,EC31E0C0B01B8039,C0801E9ACC9DE173,91F0692D44406663,85736BDA456F297D,0000156DD351AA2C,F8D752D02F6EABF4,C2D99D8F4718B711,DCD49137E39FC059,5B6BA9C35A563701,613E08D07E66C5FA,E0BD2B9FF8A36670,6AC4EE473911000E,BFEA9F1A3BEB6526,40CBBD0F8511D745,915B320925F9FDA3,64A0E2E391ED66F0,00006448DEA3033D,474A329FAB105A57,AAE432A600DA11C0,558F6B0C59771245,E86A22CA078FB3F5,B72DC15420C994BC,0C8E34314B94FE2C,55F916FF5EFD16D1,461B04D4AE7F8465,EFD0A6DB37ECF448,2E7820A4E407D5F9,1B1D3FA7497CEF16,0000258BCB125B4F,4537B37657A96D1F,FBCFF387E631872C,593C7B0B9F6CBAE5,4E5F683752270456,24E1561E6F10D355,B6545066B4FF0D77,1F6A48CBB6F14032,20A5C07876D85D5B,1C37F3C5530BA087,C9DB29AE52CE8800,32B32CC77095EC4F,0000310096BE12B0,46CCCDDF03D5E3E0,AE1DF457930586EB,99DAB61420EA1F4B,34BBB49E211B382B,F8A53FD0A3E43330,1B887700F01245D7,73EE4DABA41B718C,0EB1F215569682F8,DB2ED06D8EF44AD5,274A0F7C211BD93F,527038D68E0C82A0,0000546353002EF2,DE837800F7D27056,0AB894C143FFD590,BB7CAEC8A6398449,D545568D0DBF5774,26A83DC2C0C987A4,A565C2D3CB6C4123,A1164AF96BE09FB3,6D4DD4910F401515,C7B8EF8B613F3930,8C17274304E8D12B,661C128F15D20DC4,000038165A0524A3,459E738AEFCD150C,D71B0CF36B57C70D,808E68375B90AB55,B2AB36D221B45923,FD8C876B2F7395D3,EF6D69737351495D,4FB43BE410253EAC,0561325C0BE77D06,1AF42AE7525822E8,3C21DA705EAC8177,39330B2F0A30F701,0000495669FC55ED,05CB816D062697B4,73D17FA13428385A,4F05809C789FE53E,B3EB505E843332D4,CF23C9100B90D284,D8732CE5229043FA,D454E5ED994B1AF5,95C2F2CFA829997C,047E012AF4D2BAC9,A0578B1E7B56706C,B30789D2FD2BBE86,0000419069F1BB75,BB2A8D7C4A8B8C30,66608D904D5BDF28,744097CD616E13C9,3EDA7D38E0CD203E,48D386A1FF75D682,355DF5AE6435EA0E,9BE291CF7C6C76E7,E06AF2A7A3C76334,7A6BF6D9FB2B5B53,06F1DDEA4CB87408,7B8FE682F04BCAB7,000001EE33D7A52C,5B39408E5B665FC4,2AB52850AAC79EBF,DDB72A6E849C7896,F2D3470386D32648,30A49B30F37BBD7D,40B86B79EF4C8EFE,BEA88532E0EE10BE,2E72B52550DE4ED9,EAADC75E1BC11EB9,A55DFF48A9FB699E,AB4E890587AEFC31,00000F098BCB0539,1E3A6D93F09B68C8,FE1E180E1D7AA3A6,829BAFEAB7023551,B8014DE5890EEC7E,EAD0A24F697CCC83,8CE9AFD48A275DA1,206A7D0FE4B21BB3,A8698249021C3CA1,763B137D229C432F,CF674B72E73363D5,0B09AFF9FB0A1F30,0000671E6B4A3F06,3134C358FD62E21B,AEA302CD34D1E61D,4DA9F447E4539C98,D76676FA35C31141,4D93E935D79CA6A9,55C58442ADF8D952,DBB6ABB5D8BD8F0D,88026D838EA70AE4,E6443D6EE0C82146,31C11DEBA986372D,76E0BA3194F545A6,00002A7CE74E9057,CF04EAFD0838E41D,827D2E2BCB2117A8,B7EFFE873363CBBB,075C32CA5B06EB52,714CA239000BF400,5F988F15CE829BD7,E37B68EAAB6729F1,FE3BE1FE1113DA1C,40C27E365BA3EE8F,3BB9FCC204D84D8B,FC6304D248A7CA75,00000F8F837BE977,C10D2A8C71F67D75,1A662B42C80C7FBD,E0C0DCE285F38452,D28E28D3323E0052,52DD3D0227C852A3,84BF2FAE59416141,527DC39CC66BC29D,891054B81C3B12FC,60D480E06DC2CB58,03AAD30DB92A3367,AE1E50F0929CC96A,00003E00E95DA639,943B3A6E47F86B48,B084DDC575C59122,ACE8E4C5687E7F66,34072C3275C879C5,75E00081E8250B4C,D9C7EF917101A648,0CD8A19695A1B631,8F5F7645B5E17632,023EA1E28B1437F4,7303299193814007,5BA4920C0416C186,000011BDEFB40B13,15BA1E2FE6A37ACD,2413E6423E7E2FAF,026DB2D15FD27F6E,2B3DD746F28B924A,D25A323E1E981AD2,DF825F375181CD43,FD0E7D7B26651A73,6D2486D1C62FB253,515A835FBFA3DFE6,67F8034016628A7F,E3B473638E946027,00005891D7FE15D2,122709ABDC406BCF,8EAFE2FBE9433037,AD25C0D63225F1B6,99FAB22E3DDB0F95,3DD45A9F80FF40C8,1A28F1D0656DEF46,DC079711F5D6C428,0E2BE76E3FC6A87A,A70AC73AE7F93389,3140CE4EFDBBDAF1,2812B8BD40DFE6EB,00001649DAC3B49A,D6435A43C3F938A9,BA08AAAAE3401FDB,1E952D98FC561B65,753DFF778805CD1A,4C22BDCD82B4C0B0,08FB7B82E115CD8F,44101D5EA6F87CAB,B51BF56F1819530A,B7111464A9C8C81D,A87BEB5AAD981188,7E6ECE10DFC9F75D,00003AA01974404B,1498983AE434368E,24E60848AA7786B5,1313AF966F1A7A74,419D9393E2AD5F45,84CBFD2CD7B6E089,06AB7892AC9C3784,F720025BFE28D58D,99E7D890C83A6388,73D9280A80ECA894,F87FE47EB50EEF24,EB34D768EB828D30,000044897A5E3972,BE3C132D40B85CD5,089B007E5F867413,AE805E729806C8BD,12160A92B5CD17CC,16C814B026A470DC,7379F02AFD15C3E5,F7AA5D3EB2784998,475B8027BC1B8350,3113CF535613C3EC,C99A5BA1292FB994,9F8990ED64B5CE8A,0000561D753BB438,C744ADE8AA948054,ABC2903E8748A9DA,9B38CCD71F4FCAC6,A721746D0D6A5987,7A1B73DBC503206A,9FCD4DA480EC7AA9,DBE68F5F1008DCC0,27F36750DE3628BD,EF5507DE3CE8BDD5,308AF1854AF216CB,09AE0B5D87E78DE8,00006E68863FD13D,000BE40C74DA2E4D,6E1BEF1B1495B14B,BD9E886F7982487C,0CC2B940E63F3672,61B66B409E52344C,219F9272E937F35F,38015F3E58503114,0290003402417553,45750DAB116261D1,B9A1E6ACA54965C3,918364AF01557A4C,000058D818E60F00,7C9F9E53C562A97D,4ECBA968FFB0E042,E4AA7308E06484AC,F354556DC69C9414,4919176805DAF58A,BD962CC9AA479CDD,434B933D9826929E,EB49253276F4AA90,3B67F28D2DE6150C,E2F54F2A7892BDF1,53E327C5F0D07ED8,0000660F152504AA,5CAD975631A98FC0,8534B136E9FDAC82,BE51FD22DA750639,6BC204332D981CBC,F6F4DA4A9CE51E12,51583EED1B86DBC9,7EC82A21473D184D,AF0AD60C01A72861,797E7674CA1B180A,A65C0EFA133B15D1,7E63ED34DBF1C1C6,0000106E0358F41E,FBAB1708B9353161,90DA2364C9301F42,271165B2853E9FC4,46A13F2B31F35BFE,02B17399AE054E2A,8A992FDD0CE3BFEC,C29DACEA8D93028E,77A7335A2234E713,C9002DCF4D5AC247,072BC94DD3213807,A5D5BE11EE42934E,00002915DBB6C6A3,049505CC6CD021E1,2E0E9EE480853EAF,26DA5CD7AFFE2207,91A70F61521287F5,4E467EB64387055A,EF7306FEE500F327,3F06D673DFE26F09,CED84C1431646E03,A75EE9EE70300EDD,FA8CE128140030C1,4AFF401C7C820D3D,000038C77677E20B,14F6FD871B534176,6443B1933650C453,D68B4BCD3AFF5331,CD76CFD4DD48BF5E,93D23B89EDA87C3B,8FD6D2A62525B87A,C702582454110F08,C6946EAE8AC0D0AE,8A36F3A3F713158A,B009F2AAB8A90A36,94E873F94A206BB5,000034A5876ACC1A,EF2CD4415451A9B8,7BAD49539743BF37,5DF237E928DC38E2,2AF36DE16B6B6BE0,CE10FD3E04BC6971,E1815CFFC7D4A74E,990E9ACDDD43F011,AEAA190195BC7690,B939A836BB679ED4,D87A189A6B7D805C,F0CCAEECFD07ECE9,0000334883A110D5,731F6F65C47AF5B1,6DDFA486D39A7221,53792C16B9FAB2F6,412ADD5AD6EDEBFC,A2BBB6D6ACD3E6DA,FF4AFCC72166DB64,5958765E3B06E8B8,9E1BCB327736F2B0,C54F60AB80A4A818,8E34C78A64E8AD62,0C33F286BDEF1189,00000C28575F432C,E915C9E5F3A36CB9,2D3A09BE076AD6E5,7D451611B9374223,D2888822F52A3521,A7AD6AC0A824AF34,5A6198BD933148FE,62247D77517BD243,9CF3A960C0E17FC4,672A627294112813,6CC36C2E15FBA8B0,868BF6354A64DAF9,00006D5254064D37,E697D8CBF488CD6C,1F53E632D6EFC203,AF95362DC50152F1,A2DCA91167D3EBCA,2E02F31159624E78,63847FC10492EDF6,55988C46DB8617CD,2042301F7C4D79A6,7FFB5B72B8B7AA4F,2B0D4EF8DC7E0A80,1EBE1C78CDFDC139,00000B9FB1F53B7E,3B72C84696324A9A,0EBBCE2B2F2415FD,9DC66C02D45C3FF0,F8AF539DC41D10D1,A3794DC37992BAD4,341DF48559A8437B,4E39365B816402F8,39B95505952229AC,90C3DD5A68BD6DB0,9A5DEA5098C49D2E,E6DAFF181E71EEA1,0000463250D459FE,6DA2026960AD149D,7690709F7A940EDC,68439C56EB4135CF,06B86BDBD9A1CFC9,274F2B01935874AC,2A29E195F7ACB62E,64EB959D5D24F078,5DB89EBE89B9C56F,E1A60014417F9514,F217296DE9A2A8E6,35BFA9509E6D3323,000061CEB164F8CC,7B27DCD57A0DFEB0,91E32CE93FC4BE43,B17D6F7F85A077DB,D92A8174D2C92D3A,4B20CFF6E7C2EE0D,E40A523F29F2E5FC,F1E9FC92EC104AD1,86AA0579F029F221,75B6955B3D7A4717,F2D266E5ED080BC7,C8DAC8F2C025E15A,00001FCBA37D8419,5ACACB4F2ED24A76,02F62AA5FFB25174,A360837A90FD5492,4FAAB5E712D25B97,34722A2ED6C03E17,F45230952FC0AC3E,23B89B7106E64152,4273AF41C208250B,B53415EBAC76E1FE,3810E89658AE1EC5,0BC0B19988ABD868,00000934A5A98174,6982692DD60CF768,1E5B852B0252E408,C321628D716897F1,D89E50660C19DC78,29236BCF9B6059C2,CF13258259DE0A61,74A1BF983B9A068A,1C9D2A0299B9E024,25F53E9F59DAB4B4,2368D4B134622F1E,79B0549C277A74EC,000008D97495971F,BC05DF91E5282BEC,01AE043A882EFF20,817940A96FB411B9,C1F9E5AB2804401C,0025F1ECA97EAEE0,680320C06E571588,8A09B2DBD7774490,246BB1D9020D5A40,DCD14CADA604F401,E50E3FDB1D7A8A90,BAF759A01C540C1F,00003609F3A50416,938B8C5C66A4420F,FACCC6D4DBE130C7,9CF7204064310C76,8004C7E521438426,95FD0D71AADEF3F4,EA72ACF6EB6D5E0E,052D7B002CAB5E80,B2F71343F602DC87,5B232A7C2874219D,B6FB03FD9B5821E9,D43B623BA07E4385,0000327B90F0A4ED,16D1BF659F8908C5,A2B0954AB99EDF73,7D158C671E67946B,9209000C552F3BD8,B4ADA76830CD1935,9A6915A98AF3B258,0FBD93E0C53BC00A,89419F38908DB1B2,619BE4D65CD89FBF,46D65ADCDBB60E72,64284A257187E539,00006880C3DDC3F4,A77EF207E2F08674,F74981DE6AD8C237,8D9E3656C1AB5724,95E1D880C8658CBD,105AEA8FFFB39681,E655CFF8AF1F07AA,77335BDB8D1EB365,F2A924CE24266CBF,645D6E50A8348B44,3DC5FC9F486F7B2F,016F07F0B8AA1948,000012283C94C760,8BBE843074554606,F1E52487428532B9,79BC58A67121EEB4,51BF1237C8556CD0,9CB33536AB0B46A7,38C0A141A0411762,153A478456401D7E,DD369B5E5048BFC5,B1951F351A0999BA,D94C1530EBF11D93,4332B3FEA3BED344,000042F655840D20,CAB9EDE2257BA4C6,F38977492CE0A542,612199B9FEADD6F7,576A067028D538E5,342B8CC9D1813298,8CBCEF2210379462,E4BC8D4A70148133,0A8D1AC043E3F314,A466600816FC8ECC,6F310A61C2336E17,37EAE07035035D0E,00002E5B9F967796,F47E3E1F44209CDE,33B807CD69814BAC,A2AB3F6B5C67CF30,FB999C253A4C45B8,FE3A44A26C5CE1C8,89B420C6C488CE6F,970A77FB17CB2EFB,3146AE477EB638EA,0FAE45EFAEE89CA5,FD1FA7E6CBF44590,D5BD5A21CF53A50F,000025B3EC2DA6BC,C41BB21C5C9F253C,A9E85FB12B3C67A0,8B9F9E5E30B300C8,4CFBD665112BC662,39A5F2B1074F2D5C,780B8A9BB824390A,ED3EF0166FABB3CB,5A1ED935FC6BFB75,2F325AC8CEC40B3F,2B789F7BF5B3C2EB,424DBDD0732F495C,0000143D52212457,2C48B3CBFC77EDC0,48273D81138BCA0B,A2AF3D3A5B584B51,F47438F8F8EBEC0B,E1109F87683D12F3,7AD72F9658B7853E,28B1AF00C572717C,62BE3AB1D6C052D4,0B968934DAABA769,E8D97BC4D570BD43,C0A6183914D7D621,00006899A43F4E14,A0F9F2EDE27071A3,2BF26FCE2D47AD24,D7328B1A4B737203,16C49E2591831C8F,E062C184D01A2B5C,EFC5B7F272EF0DDE,24FE33D63ED2951D,5272727008EEE684,36309A10ECB54242,EAADCD2765CFEEE9,D8DC101FC9223A98,0000254008721CC9,33732D680E885C69,DFFEF04665FCB7B3,55E4A339FC7BAFF6,9C4C70B3B43807AD,400F5309D376AC7C,85F14D38D9703C51,0FDB4194ECEEFC48,6230AD8CA80EFC5B,1E737FA5415AB951,76D6657E06F17EDE,6BF71A53447C75E3,000024357B546E1E,49A1A1B912977815,E606AED9D2B6B9FD,36AB070AAB76F52D,ADA67CBAE4E5C8B1,BBBE4696719E72F1,AB4D826641B463B6,C78A64E597FBC259,CC0E6B9008A27AD4,C8775A0D152580E3,0A6A2D98DCE11A42,125485B0525795EF,00000EFD34591FE5,0616683C10655ACE,5EA201B0D90403D8,53A24D65E5EF30C1,661D7269A222C17F,13DDCDC7179C0F3D,82F5BEE1AD9403C6,9CA9EF2297C9D966,E50F33FA29FD32F9,0113C7FBE39964A0,BE01EA4172E64ED6,FB117EAF54D2F16F,000000F88FF42CD4,FDCE9272C5859006,2563745EDFAFFB5C,EB0C98D5E01B6D80,3AF79402B4CEC6AB,8017D6D4A26616DE,83C82CA0E5AA9070,7F9BFEDF703F7A7D,5F788180672E523B,07908EA392CA11DF,625C36409CA57A6F,9966AAED97FB5AF7,000018EA54CB5377,777DE84DCFE73658,126ED9B5D0C26A3E,A1718C12FEA83BAE,648EAF5D32C1734A,F74A815BA4BD7A1A,F895F2F11F4F37DC,A92EC19CC309C73B,1791E1985667771A,5975447471A5E0D7,767B8E47926AFFBB,E26CE0CA21EB0ADA,000052929D425716,F7AE52CBF3092EDB,2AB129E24E3EC9F3,6C6540A5A678AD10,6B39EE7D35235BE6,0E82B29225735454,C667ED017F946A8A,5CDFD10497D00ABD,4E398207BD621C8D,1FE91B5B37032AA2,8A2A902162848058,58CDB465BB0870D9,000016E46E2FC393,02FCE3166EB57A2A,2F798C912319AC5B,EC9E079F506E8262,E8AE1BB10466B345,6BF7066C325011A1,7653D09877262615,479E60C62144FE9A,AB69AAFCB4BE4E24,3E42210C0880C444,583C3CE060E5035E,3401D951DF108827,000008E3D6B4C815,CCF83AD5280F00AE,C74C48C5FBB3194D,691833C7AF5B04F3,634146223456AADB,E764966B22F3E101,E29570138C4A543A,8A42A4FE74DED47B,A46D3FF43285E954,0479DCB68E744E71,DB34B301918EF411,D9008E7D2816BCD3,000046962062054E,45F0304098D32B42,2E7F195F6C8F47AD,2D3E4916CFD12B0B,E572034B5FEA2B5D,3DFCD85A02FE9B0F,DB960C3528D450E7,FF9FEAE4CD9D7015,80FD80794F644137,4E3EC1880FBB09E6,AC6EE4EDE376EA64,62AF7BD36A2ED4D5,00001870119E768B,4302BE473CAF766E,C0626B1500015EF3,D6A5F7B37F8D518D,C69300D082156AD0,6BE3A9A80E0828D7,65B4A22885C7D424,FB419303BF6AB80E,FB04A13BC9BD3CB4,AC816B40621C2B70,17BD899574BA97F0,FDF2C538A7073BA4,000020085E313C86,75E14F59C7E68683,B3AC850F2DFF7163,7E29317A830AE4B2,747EC2CCFED331FC,F8556BE16E64F34E,04065013E504B286,A1829CE3DE8DF24E,A314F4F3F6A29B8B,BB8B17A4D5C5ABAC,025548DA6FB28E26,C1B1519EED1AD038,0000400B5E7D2484,8BAB055B660C0FCD,4419EC09CCA84A12,1889923E513397A2,9FA262D468894C6F,ED797D5242AAAA67,66E98AD21951D402,3558259FAE08B463,F7FB00306190CDA0,4D2D3BEE798DA0FC,0A3E623D9BCCC255,877941BF2105AF4A,0000658BEFF008FD,20ADDB554DD071E9,375B47A23D770D99,9E37F51600134710,F0DFDC79BA81DD92,40ACD33354E7AB24,AD90415DCC092046,DB9DD1980BB9CE15,7BD82017F43F5902,B6AEDA5C6F5F3439,2E4E5B2962C3C502,D55572E17769104A,00000A40EFE902D2,455F9C80B430CA7A,C0868D97EFCAB9FB,C68013D532243360,1D7D88E163989F8E,FAB434E0C77C80F2,D6CC3285B9DE3E02,B950A3B58F119229,172799468CA02893,3BBD0EA72CF0D657,B83D89DD1B23E5F0,9A2CA71FC0FCC6A0,00001DC0E96DE399,CFBCDF3A6D9A0B29,9A268EC4B5C56109,94709CEE8D47396F,E4CC1FDAA1ABE016,06E676ED16FA2523,67BF4A828CA1B893,CF4E3511706C2B12,3EAFC3234B0C63BD,E618D647F314E6AE,41EB45C4CA3757EF,1D9B92C9BD29C8E9,00001CBA54134BD8,813B0C90E920B895,8C14D4E4972E0749,B8948D5ED8FCE829,34070A72F6A01C27,38C93EDD51E2AEE6,3CB04DB47B7085AF,170766974808CBA7,6A4B1EFC0C52B398,555DD33A80029021,AF1035B84367F3C8,1E055AD92C451F52,000047F54FA1A977,6F7280D0C210A6FF,E71742505E4F49AF,C465A180A8F6920B,9E89A4F2B271AEBC,2FACEB8D88BA6068,F8D37686358E5D97,50C0F9FD9F0420F3,BF82362621401BD6,141FD6311332A85A,1BD0F251C90C8B4E,36D4A1C888C62DC6,000060B7F2C161EB,3EF298874ECEA7B8,C811D6AA1F876DDC,3775F91D34542025,BFFD29846DD90FFE,58886A112EA93090,1624ED4637345630,424D28A168DC1D40,7D3592280AA36FB2,DC5E58AB2D7AACC2,FC5405D68B65A93A,35270D025092E7F4,000066349528D38C,B9E865A8B111466C,93FD3585DBC29E4C,8137B5789BEEC6A7,10B02FB9A672DBDD,4CDF949948B85B9B,25D9DDA9192515E1,90012F997C0B50F1,7B4E5A224D75A3FC,AC30DC4DC2975468,C832EA6FA69039DB,C87B9F8073E35597,00005C2F77941822,EE815F8240142563,F27912890BF60C7E,49421195BCDC90CC,5C7ABE41161E197E,A62BB4AA485A4A38,5E157C44D2105A01,096A3B4199B58160,98231EA771D44968,5F5847CF681562CE,6BAA345524501EE3,0C5CFAA528167B0D,000037D8D0E708B1,65E46BA9D2779D40,671598712560486A,69DA8ACBE66A8A2D,6930B76C58E127C0,B0B9925BD894FCC0,6CF82523C5E6131E,0C84B4EF34C3342E,8DE777E1D92A4084,DE83B4ECCA850BB8,340A6797E8A6A1C0,37F1A9740F7B26E4,000068BEFF908522,9852349BB322499A,5EB3329A35068898,51BF60F16F42A6F9,028B80F9824DFB6B,94CD7036C7EE72C2,4C03861AB1335695,67E3D968436E6AF9,780680EA1D91D1AE,0ABA5D3CF8D901D8,4BED541CD97E69A8,791D3881D0202842,000011856D552D7A,70B73436380B6572,DE946AA36FA85EFC,DB103A906955A6E6,B23417586DE65E2B,F3C6AFBC31EDEC55,670454141342FDA4,7D21E9EE4FFF1968,2D879D6EC6FE2A82,55B247A701F84BA5,6D9853456F7E0201,BA384FCAF8C4ED7C,00005F4E6801A206,D9E4DC37B004C14A,6268FE42F69E7395,697C784097983363,BA11F60BBD5A8EE8,E28F02E39B97B109,B39C364E3F24B873,F5F5159EDBCC5740,C09D2E26D53E85DA,486ABC6B4DA8B23B,6254A3F71F49B422,29DCBD268E13E157,000068AED95EB48B,C106A2163B623DB2,0F0ED11877510D9E,A76014ABDA7660F4,08853BC9F2D193AC,60B6A68E56283751,93287FA3073BBBC5,42244BF29944739E,11BFE4679BACF410,5156F50966BCD6C2,805C70F87EFF7E16,6D02B1028CFBCD1F,000012F7C1DAA6D3,B56596E1A1E45364,7230B57BBFA59F80,E59706AE1AE6C3C1,062A264534D32195,842F7A670D42C7E3,3A886B032A97F1CF,BFF05CD71F924694,2762EECF32B2C155,5947436C81142B78,D1EDEF5A0F270F4F,D144E9934686C6B4,00002EECD2982511,24AFF979398F12C1,DD50366217639333,6DBB30336CE0DCAE,3DD216C994B4BE31,2A1DDA8A5DF30675,BA121721F371F9AA,C9B3D024CE3EB358,4AF8307D4489E5EC,08CF1FC92AA76F8F,08D33C80ED2022C8,8C6315671E9CBC1D,000009B11696E0E4,C41F613019E83C1F,20F089D14C793AF6,26E0A12D371E5276,56917A95EE46B44F,3CBC97CD8786C49F,171BF9D481C97360,FB6D455BA64DADBB,B1EC3D20666A45DD,212E30DD1F796C57,4BD1B3B037ADC84C,0D78AA2CB406C27C,00003FA97D803C90,87BE994C5263E337,735F8785071EE609,6A35CEF675457F10,C7E7A5AE38833248,E17981A02EEA3583,03E7BCAAD96EAF1D,9666634342E3EE47,AC9BE5E56804356D,38788129405A6797,592E54225676C046,E152C95B7A07192E,000020A983632091,47BA97FE80CA2354,D977489D46C49DA3,EA798B39EF112613,F62CF4610E5D8563,2FBB0CA879A57AD3,4F026BE7DE0935F6,7D875C167FE03DD6,D6BD437F448128E4,EA87A2C80EFAF99C,DE06A3C547042740,CA12E0234D45AFF8,00001503446BE6FA,6D8097ADBDF52F06,8B6A65BED592EFDD,4AB83593FC27A97F,F6EBAE57EABE11ED,86B28A5B618ACE8F,38185507684E1BF6,6CC81CC10B9596E1,FBD63E6E9F05BA48,5573F48DB48981E5,2CBA175D765B7DB8,F86D76A70B280D2B,000002444794A77B,5C167C3DA634233D,39CA292A3E982535,CC4FB8A20B68138A,05300030E6C7EA6D,412C8F7C36B5F345,90EC9E4C5B690BDC,96713B0097430C90,867DCE5574FDEC2A,C7B35A5DF49FF451,C8EC4A475CB6AEA5,7841E0FDBFF71B77,00000E099CF206D9,39A9482B5E10D8AA,5389B3382C413C19,753E04EEF8C8D477,FB5A544045EF89D5,758D975C87BC22DE,82DF300084AE6847,CF44A5A84BEABEB3,632693F74A05A573,CB297CA7D7849360,B3D6D655B5874CD9,1DB0422AD941D6A4,0000223A9694990F,B8A6B11B2239C405,567AE2971C9D7A77,42D87E8743B33050,CA66CD2045263079,989D444701D5A31D,EAA7C02D1F4AC8FC,C62BE6182D85CAE4,04805B1A1F15831E,8CA8755183EC01A4,CC01235E4A41B327,D73334092F2713D5,00002A5DAF806E97,D35D89AAA4D2810E,2295ADD5C1056B0C,466ABDC6D1A23241,CD3C9E2AC2F218B3,991AF19BC5DE3FE5,4D32782F6E5B1476,EA9B59DD1285E6FA,9C5FC1CF031654FC,7046D187A3EFFE7F,A9C23409CF0C4156,86F396F33E3CCE26,00004B9EDD537745,7EC8B627B1966C52,0269CB21350F5AF1,0ECCC360A8A0A9A6,02C6F24E5275EB95,DF604286614C790E,8C288F35FB391293,C933F7EBF54912D2,9A9A5776A036E697,CD18C6BBA71F91C0,BCF7D20B97941F9A,609AAF0387EE964F,0000130D654487AA,E6CF4FF15BE90752,8B2B54107684CBEE,A46B3040CA747614,E8E12BD025E7C2B3,7AD58972C0F1041C,B6E79866F95D9B9D,E6355B182632674A,96C4E1C7D7C0AA37,AB7A9E594E42812E,C83877C350E88A98,7000B67019FB9CBB,000004A0F294AD20,078DD140AFA77178,6A1D6366A3F8F1F6,4661B83215E21687,36CAB9BC75C8B940,83D93792FB3F0085,C02E1E1AAB2FBF22,05C9E798AB992DDD,89BE5009BB3E5059,DD4FF720E483C99F,95F54E7BC5D0B482,5052E1CE03F661D5,00002DD941A21458,100D9F00FEA96710,7AE0E730F200A92E,A6FBC9D79D873414,B1ABB5E3EB1BE8C9,CAF89E1F18E9645B,1C682E5987E1B47A,1ACB8F577F51D065,9BCCE0244E6A1DD1,0A622988CC927ED6,5EBC4CB23B8FC29C,9BAA827C63C2CE69,00003F4E9471F663,3BCA75C8FE6B0B35,EFD6719927AF055F,0C868158843E87D8,A612858AA95ECC0F,C20BE4598FD09EA7,07E134DA738B4EDA,E92394C5D564EBC2,7385C829482A959C,0FC491A70623EDCF,961B3F72FE281366,770A2641F06DEA90,00005FAC277118AE,4515AED77C0DCE73,BB6A92032CF12608,3F21077DF3F8D3D9,DB04141028BCF017,252FBD680583550F,23226A6357987430,BB71AD43335CADEA,A0870DB026C382BA,CA26869967A699B1,6B7CD7BB8A04C683,8D897FCB48355E1A,00002BD55E94C6F7,EA250B2B726C2612,C7B5EB1240074141,BBADAC27E581759F,EEB88202A3834089,4C182DAEA403FAD2,9723BA1CE40706C2,14F07E36C07AB7A5,4DB48EFE55787FE2,E6F09896630EA44D,EB0376384F678285,7FC910491EB796B3,0000475DD415F0B3,45609DB7860CFA8A,B89B422CE1C4FE14,2710C89A3F7B95C5,C93B4B9768E419AD,D7558F8F258535ED,75625BC58D0F5886,87C47B0499F825E5,CF80679CFBA67886,F2A696C89CA430EE,33B02FACD5286C6A,DF64017EB4C496E9,00003322FD15F94D,DF1CA7E76F272162,63141B96F45C8DC2,95380572A295ECAE,E0F3D561D539364A,451D0BA5165B298D,68494D9A7094C1E1,3DEF08B263AC5826,5B2445284F050637,A795DF85D4D1D074,9A0DAB6F02D12B0E,58326B1724991400,00002D9EDCC0AC47,87BF29995AC7E8A3,EA7DCAFEC1615376,3EEB00BDB10DFA49,0442AF0DB29F4445,2A94A5A45C753E6E,DDE26D69432F096D,E052902E7BB95C4D,C7B6F3A012F423CD,62A8FD4CB018F608,F8A9D06690895739,92B7B34E41916F7F,00003B6917C47044,37950F9A47DF4DE1,34328145871C7ED4,7D170898E9946FAD,246B5C0CFDE9F372,48F142CE6FBC2BB9,EB40C99D4BF61955,C66E8A9D658CFA9B,494A91E7A38F3C24,AB624A27D8368BD8,E4B8100DDEBC12C9,E914F3BA14257619,00002DD3F2C7AD33,5218B20565499CFA,CDBF5417A1A9AC02,3339C79394FCB425,43DB6C79B8950C12,C3A70AC1A1D3E91E,6D4D8FA65889EFDE,19D2D00E24EE6657,2201FCC030CD885C,7B760B09A5AD8398,A59E9C91B8465BAE,1A4A38A82BDA391F,00006C6CA1117AF9,E4D5A3DCD60D0BD0,E16BF61985E41AB6,7F2F158A8E838096,281CCAB6A9474623,C68649B230139A09,5F5F1608E36DDDE3,ECCC95EA0C62D685,8B5F2C1D998E45D6,89D98D6E4A2C796C,68CB764389073CDF,5431BFE43411339E,0000235AFA2C42B3,278F833DC9D2C6FA,97DADC433CDD75F6,5D55D08E62DFE651,3F7A502A25161325,CEBF048CAD2172F8,B4F5CA8AFEF8CE47,44D7F094E3B6E87B,BBB0B0A944B72B29,38C1A6E8605E69F2,954EC88743CB7E6C,A8026601300FDA90,00002FF7D52EFE98,675EB8C68989D696,877FCF2E5A2BEAE1,B6D88D55B9FD8BAE,CA53FB98EE7619B2,E6ABD1A4CE6E26D8,ADEABA0860DE3B08,C753202C8E14B5D6,70EC05D6FA31987F,D34B61AE05B95BAC,C471FDE7A6EDFD80,4C9943804B1DDB06,00005E3A8AF7A2FF,8332CF1AAC2B7776,6A9906CBEB0A997C,3747A1FF18C5350C,2682A6F69EF77E90,A2C4ACE54EF4A342,44A404E4725CB008,93D03FF6963F3811,EE320396E0D5F40E,B6C39D33167EC21C,4DE29514774B8C5A,8DE9FB6634D02E19,00004C5E5AF7DF09,3A13B215ED7D28BB,96709D97A2813240,F6F619DCEC822D1E,9259526E9B9BE562,B13BAE82548969B9,80A859CC4E41FE5C,4508EE73019BF39B,F8E6DF81C6E4FE3D,14805FFB47FA3C82,EA728D81351523FF,EAC281B86D761C07,00002650C3892D27,2B222E8DF5F45527,EFA2B9C136892DC9,37DEF26F091F13AF,2E2622C48C324C63,F732F01CD34CDB74,D13CEECA18DA3390,99DDD2BBFDE64B33,4605B72A793FC018,EA04E7C598EA0CD9,CEABBD4333858C1E,F9D1E08CE336623C,00002BD86B70BED9,26A1DECE048CD4A9,90DE7162CAF1A799,EFCD28884B5051E4,BABEAAAE7AD2DB8F,50285EB94FDE96EC,E165DD367361AD7C,8472BA2E66DA968B,055BC15437979603,0B85E84BD72D8CBF,4C0090D152A1FFA0,92D93301CFB8D295,000066CBF1595C7E,FE89A5A06D09BD3F,2D24D3DCEDD0BE17,6CB37C5070E36EE9,E588C08A0124D3E8,380FF2D67ED30530,CB62FF8AEDF1D560,FD78B8A95711A4C3,70DAE2518B9C8B7D,522EC3C6198030ED,B48ABB1C170932F1,F6CBDF67DB777255,000025489E82DA68,32ECECDD1FEC2B84,BF5C3B4A95D0AB43,327119742A891AB6,348A744DF99B08B0,9E93B18F67B506EA,D18E463FEE2FF21A,D69C0C7FCFEE7BAE,A683BC18D19DC65B,CE193DB10A5BDA29,33F71B63BEE76709,5DA61C802C5AA1DF,00001D5EFFB8B9D1,E2740E59DBCA23A6,D8EB8C03A8F34E9A,B686F4FDC3797E69,9827A16801618E6B,8EE425152AF88D73,A97E50C75F6457EE,8C9216463FA1C847,3C70596E5CDAD9A0,5F5F30919373F3CE,E778EDD5F8B58F0B,A8E07F80D624CB1C,000031B29855F14F,9E740580D194AFE2,71057D2043EADA83,83A3E112F239CCE7,313DB2960E943654,883865AFFEB52553,684DD296917A0D65,8567A18D093FC6E2,8CD2291AE5436324,AC293393BED9847D,4F11582EDA077E98,AB2E6E7017BC4C77,00004C3E3B7497AF,97817261E4862082,9DB5E2FA5E319183,73AED61240482474,D71A640C2B1FF241,DC293F45067A07E2,1C1D8DF50917F855,AE59E66ADC1F416A,CAB6BA871004ADC9,490CEB3D9ED654E5,CCF48299EEB2B261,CCDBCB70CB90A027,000065D4B333DD16,C03D1020AA1CFC3C,AF9297BE28E929E2,1CCD6B18D74C38A5,A9EA40FC918EF072,CA883AFAFDA5E76C,EE64895DEAA6D6FF,A2320E0CCDF1FA81,9A2F98F8DB7B3DFE,5B2FD9577999EBC7,AD3898B6E945840E,876F40CD49E4A375,00000C2A2A21B5F5,978605527C2E6EC2,77D8D9D29932903D,FDEFE33C4A5E3E08,4079E8048F7E1B06,46B5DA478CB8EE58,57D39A8B74CF9D74,D0B6F310099E8C40,340DC13AEC744A75,9EB03282D31F7660,AC33EC6956F2EBFA,B856AA519AFB9A87,0000066C28BBE931,C6AA50586D34F49E,2BA465BE0C5DF78E,5639DE321DC4F667,4E8ABA6754D061F6,751F8877024FB71B,A223371C93E6DD11,C2E508FEDBFCDEFD,4488EF82D67D49DA,BD1480EFB4C152BD,FC8EA3FBC6601887,FEC83B9345B90182,00001460D1434DB0,8B1ADEFF055E5EC2,1AAF71FC7E910864,B52974DF74748BBF,2F3B7EF9B613E996,6D4FD4AA18A1C854,E6C7E9F0A36754F6,74CF5367E3218425,DAC7BA71D9038988,24E51007062EDF92,00AE676157AA8209,5A605E2A8FB0D894,00002108C414919B,CBA13C89B1B0E215,744EE21A70696D43,9534BEF3720AE242,7C61BA99F1F1070C,B6D2F26BD7F32017,BB4314A486DCA7B3,79EBE930BFE62AD2,3CD39A296AE4223E,5311F39069EA6F39,48DF7CA39B68E46A,11B909E4977C89A2,00004AC2A3A24098,2383968D9315553E,D46D05C57E48E698,F10E4BB37112566D,D2A69542720B5675,9A165EAB58CC8689,CDF6471D4A10BE45,A2A753EAD15C9032,ACD804C98703706E,AEF0AE4CD515A1E6,699964DE72DD62C7,214DA8236ACBE56E,00006FB3714F3B7B,B42BFE6F3743E160,8699F91F25B8A05D,8F6209639C16D38A,015962BC755E79E4,8E9206D39E116DA7,DB0F25E2B2E8C776,6559A42ADD36C998,563B9CDC360E3081,9C9C1A3B341144EA,48D5F12128420D3F,92C2FB82FB926233,00001C8147184E76,789602410AC549F7,EB437CC65A6D91B2,B11BFDC74430F96C,A45CDE2B546F0513,1B59F468DFBC850C,3425659CB4F27FA5,F3173BA16EB3963C,7CE7C94B4ECEBC3A,2D9978A066A5FEE6,6B1059AEE8F9E459,1683811D087F2C24,000066368B2D20B8,50F53D9B461C9709,EF9680CDE844656B,1A9A510374485D27,49D7349C2F571FF5,F34CE51A0781DDFC,DD9172B262CDB88C,1CD65962487F6828,E8D5BD85400B5D00,47471CF388E93BB5,5BD6808657701591,9E3C52F9E1DF1ABB,00001DF609413910,63852605F202E718,7530E68245AF8C22,3C9CC51769CC8978,390DE8C19FC910D0,3A4E82B05FB76F71,9BA554438E35E3C2,BA714C5B1FC940F8,377CA17C3C389528,E6CFBD7657A783ED,7ACF63B72C1259A6,DE0406AFDD1AC424,0000446B8D61A49E,FA9B531180261D16,C35B7B05230AB59E,4FF5F7FF45B38DA3,B8BE5EF63D092B35,5523E09DD206CA87,821B8BABB45EB162,FC36A391D5FE66D8,1B543660B9455D21,0510D6AC69527EAC,3E9EB544280A749F,CC16AA0F85C41F1C,00000B3C740BE7D7,AD7FFADC599B9646,FA2298737E128DFB,279E54521D8596A3,12820B786F88A3E3,6D43B6F82A7808AC,AB51ABBD25295551,34CEE18F9B2983D8,1227AE7827475875,EE85E6939B6BC9D9,077DC51D2A0F189B,2E3E3476E3818028,00006CD9D13BE209,8638FB3A41DDA5BE,FC69F0F2BF9593D1,B2287EBCF918C8C6,11FBF89652AD7F9F,C8DC5DE6A5EC46AE,9D610DE5EFD003F2,B0E29D9A4067D0B0,F1C339510A682B0D,E2E4B848C74885F8,2355CAB54180664A,0410CC47B94B9F66,00001678CD2D6E90,74B1FCB3DFEC9FE4,E11108F22BC40214,1A63209083AC5DB4,273A38886154CFEE,97E1CB2715A66536,52B9B2F7DAACAD29,4FE30DD4E7F3B628,7084789AF11A42D9,88E5EF82D265784C,40032167CE008E61,B5E4CF17AA44E36A,000003FF47BDE24D,BA5B09430E7915F4,10AA621BDEAD8BCC,E494117EF82973DD,0CD42B69845F76FC,664CC7DD1D6C697C,78E142838DA16238,D1AA15BA57ADF814,07A7481152216567,903CB95A16515F1F,945427CAE4F37B46,041F9AF2268D62AA,0000313055FBAD4B,33B5440B304CF475,648CC8474A2254B4,109DAADADB5EB657,1439BC77FFA20F95,B51102E2F782208D,5150FF884C6B1997,F3B5106E35ECB390,A36A516F81122A3C,7B1E1F6B1D02C333,59F2778B53F6059E,761DDF34B348A70E,00005F932B650469,758A1A016C470B98,48A92ABE4069E958,9D720CD1A32B7969,61751787F57FCFAC,34EDC96BE16B31CF,BA2623ED28C971A7,1A750B9D5815D32A,D211B328CE57E36D,7BF5E12FBBA45474,73B08796BCEA92BB,5A24589D517EABCB,000040D6A4FD58C9,51E289FAAD1FECA0,C039C3DB5E3D58AD,7C182E5D0AB5A381,283D95BEFDE4E6CD,86AFAF8ECC438540,DF24AF0B13C0CC49,540830E7EB9C7A11,2DC4865B6C038604,CCBC4DCB960ADAEB,75F9BA46F97E5B18,06746E7FF5DBF470,0000287F37159321,81F6C033B1B23AF5,D0B866D12D1F526A,C77573086CF1F5F6,4605C6385CEDA478,40E0DADEE4CC1737,4A482F1A47DD0789,7EEDD956CD02B75B,89BDA7CE88996778,2DDD7BF5E0014640,61E7BE656552BF60,1E0660671D5F45F3,000007727DD5C868,6AF03ABB9BDCA77E,40A108E5CFE2D8B4,F2D62D732FA1A477,AD6FDA08B8E05DCC,436A0D622211DC97,81A9173D531772A6,C8964DEFB0878C20,74505472A624911E,CB58FD3CE223AD55,4EFB791E2EC13740,96C0F06D816DFE8A,00006355B18C250D,D467E6772D6A71C0,CF5667A74A6C6521,0AE4C72A21C73D27,DF3855B252C71674,17A2BBC67648EAB9,AC19A206E6EBFA93,09DA46A6DB12E268,D80C02D9EBE8055C,A74FB3D10E369C07,BF11F07A15AA38DE,1AE4A42D22FBFE6A,00006430EEA8C6CE,F9D53A2FCBEE39A7,002A8AC125799A99,07C8A03C9B7FE21C,ADA38BFB15E1F913,4975EDB216957FE3,D70121DF91352BBE,9C270B47604BA976,3470024EED3D7893,6FBC9A8ED76A7EA9,4468F5236DB05116,FBFE618F32BF8694,00003B0704C70546,8B60C351D7174DB6,8EB759F9AEE9E0FF,D9FB2373D7C7FCA5,459545B2EEBCB2FB,70EE649D2513E22E,54C195DCCF45315C,A4D849F9428FE722,71C5999AD9053903,D0BD75B75F9A35F4,AE3A067569ECA483,C0E9E757F55383C1,00003B26C319A906,3FC23A900FFEE7D3,037E2EE3880F5DD4,686A021103C36591,72BB382C8FA263AD,50EF9540C1C6FDAD,EA6D212351F50E67,7543A178B096E277,5C1BBF8164A0A460,9631C0250F88E950,EFE5BCD6F55486BC,EBCEDABDE15F77D3,0000689F1D154FDA,1B8691A48F00FAE2,0CEAF2D348A1ABEC,46F76106ABFEF265,2BF6C283726C623E,50CE0B55A643F2FE,16E71E26C040939D,90406C075F905291,6A95DE6D55C83262,14334F61F50F2402,DDF473A03595C82A,FF45DC82F7AAAFE6,000008E5662397B1,299C5AAA70C13422,EEDBD0D8A5DEA2AF,C9D609F200D7160C,FFCEEFD87D4BCABB,A65F52C316571B93,1D58B2CCF6163020,679FDA8132B8ACD7,64FB58D29062F105,6A1F6FDA2319C443,B09B4C27457AB735,F483BB7927A21E52,00002080F63BB7BB,A01D58370F41782D,B0F59CB045AEF743,1727F05A25A5F450,10268E2458C63BE9,F907D1A006CC24CC,6E536300922E7003,17257BBA1BCE8FBB,11525E5E37365B17,FD86FE2A66616096,A3CE041B8D3E3C9C,E7248D2084CCA369,000059283BCBE9E8,09871499CE78E951,CA67DBB2EF6EA27E,B08D754670242337,FB161C62AEBFE622,5715CCDF3C78B910,8C273597D9989666,4A960EF434C8F843,DFB648500A66678F,00A9B5C3FE084ADD,7B9C9A1C1FA35D1A,A0EA05C69CDEA5AF,000047CE9AFE7EBF,AB83FDC852D1C00A,19D24C00DD3692B7,900ECF14AACEF037,247BEFCFAAA45AE8,2C0520E607D86A23,141579F645678EEF,64A8CFF77D322E6F,06862AC73CFB2252,9A2CE69FAB334BF0,160527FB69405281,EF405C1667D6239F,00001BF0DE8AED0E,443905EDFC94ACBB,A6AD6C8A2E9DDD50,D35617BC7236EA83,48D2551C51D0CDAD,3568CD2D2FE3C8CD,41E8EFDAEA048C66,C3B456D11FD04807,CE048008B7E0151A,126358EA0C0901EA,BF6C9E8815C37C03,1BABD18A286DDF22,00005D6BBA2DA5E6,3EAF94543AB6BCC6,4018F625789AF5B5,917A7FE7F56CAC8B,0F0323E1353CB9ED,BE6B0BCAF62EE9B6,97729BBBCE3A0C1C,8EF53B08374A137D,440BD2B940B4D9BD,E794A51997CCD72D,26FB77E708371822,82C97300D17D8504,00005B72902478C5,9E2A9068B804F417,7E882142F6A2BC51,594AA002D786F54A,DC4B22A2D8DDF5B2,B1A644D21609A7D4,40CBE08F571A30F5,0549C3E2DE02AD00,DCAD5ECB49E6D3BE,653E76C9E49CBFBA,07659531C2B9CD35,9DD0E181252A386B,0000043DA8E9ADE5,43B71A48717860DE,623690A5B0C06657,1C9C9658A3A1C198,FAD681667E87CF11,AA6678F150B6CEA6,FAD46932DB9D230D,22AFA4037105DAEB,A43C70966D5D64F9,0D406D6673E42CB3,3BDA5876EAB167E3,CA2E5F5309073B63,0000510C15B34E19,BDB167CA77AA0F25,A9866E8A97D780BC,7A6DC45FF68F3520,8C62C0E14348219F,D0412DB7ADC5FFE9,3CDAF03B20CA59BC,0D9ED1DC10AA595E,5237744665A054B9,A12A7B5D4703EC3B,E7D160C0FE4A09E7,D38655E336473D95,000007561A51E174,14E95BF8B6BCE785,40A93C29BF203C75,B378C6D401CF5A49,D341F9205C53607A,288E2A7B3D486E74,97E04BCBBFCACCD8,6DBA78C1B75F6007,C6729FFECCC99814,D1324AC293596EB1,0DB3BD8E46F0E015,90077ECF0B15F374,000003C7CAF0171B,45EA2B5FA838CCB1,535658C343E6AB23,F2726CBC63360475,5AA2BA1C98A69DD3,25825EBBDA1E9E23,DCF7E1ECE68049A3,5A6ED13DF83DEBE8,E64E15C7CF202890,A9C40251898828E8,2F3C4EBB6B2AA2C1,FF720160E8E52A41,00004820A4E02168,F43FEF840B2D91CF,A9DC810E17F140C8,03B78837FDF8D3BA,92F8E127A4A633D4,658A9CDD5DC44DC8,4DDB977F5EAF7348,6268D1B7F4AED7C6,0067C5BEB93EA9CA,1CFB2EDF48104DDD,0156DB834C242988,0A1FEF187D41FF35,000019FD124FE808,5A597759E1E9F3BA,A21C10A47E3D99AF,23B6D5675E511C08,719F9416234F1C65,D8F85C2838228A79,0135B887FA73C91C,9B16CB5EC96277E9,A8804D2B5CDEC203,3BD60E5A35DA6809,34155DB6C738359C,4132DEF22DA06660,00003B2D5B695F78,E9233CE1DDDAC05B,59F45236D0104AB7,FA840F0E55FE78F2,5C5FBE1A52BCF8C4,6767BF2B82FC2390,04B9730314EC3381,69B4B44693618980,27339292F1B0C2CE,88FE031F52EE381B,0B7EBD524C795B6D,B30973A35501F2A1,00005F550001D77F,8EEC8B81ECFEE1F9,23549D90DF941949,7BCA22860232A5DF,AADAED5DF2D6B0F2,0681788BDE3C29E5,4EF621E69F2391AA,726B139AF56B9896,D98D2959E19A9B9E,20B3B38443552FC6,D52004B98780EFDD,6C465F5ED7F5BB2F,00005C48CD6EAD41,70F021053D74BCB2,DF7EED720A883814,E72B430A5EC81E05,A276278565930186,5D14D05FE6BB0C65,FD0759510A1024EE,185DF517D845058E,C4A3C10F093E592C,01E11B37DF07BFC2,4E1DB0BEC605AF51,AF93DAFBCCAE1014,00004EA72CF539B7,B116FDF3271B4F61,74DC58CF12A16F85,3B753C0196E588BF,4E4461F56D81746B,C17E446E46D514BB,6FB0DB29D37119A0,2E015B19F64A430E,83614DF3ECD2F455,4D2AFC848E5C25D1,1AF1F64F09A61912,AC0474DBE2366676,0000628053437702,35360BDABC7E2FE8,83A8D847EB4F4F5F,A2263F3F99A3B2AB,4D712EBCD7783608,97391E551B229D0A,E713303527B21377,C3608A56A64A123B,F71B3C75AF9A65D1,24932ACAB3D3EED8,1466032C79BD8E43,29B790BF0BEC8E61,00004F5938510507,21B286A530D34DAD,C801A0CAB551483A,41F08AA04A329410,83079B242D28A6D8,6533FFDF86F2C6F2,6C4FC36C0EDC5380,FE924E81CD145C27,657F3A8D2CDD4A93,38557DB4C7458FA6,FC903919F69C13BF,1EDF9168DF323239,00001EAB5E16595E,F52468F9C24E7271,0280055D8759331F,D0432F785F212C1B,FE80CE639C2EFA6F,3191A61820A12170,9FF4EE83E926D2A4,8EF24351A9C6248E,C68DCCB2D0A36A7C,16CABACDE3D97494,2FCBAC53CB47807B,02108F0CECB0F06B,000033637DC72A9E,BE22C6F0270EEC04,A9A67556CEEBF9A3,9CFE44B9222BD2CD,4574358A9DC25699,8F9B4BB88D0611CD,086FDDC426BB625C,7A5C3E3028179A4E,5C3A57E2B241B34F,46005FF20DD33687,C8E9E7B21E6251ED,80431561F2B8FBAD,00005B38EE99BA22,829D66361A85EC15,C93E70E991A6C1AB,744D111845ECC7A2,1B200D5AFAB6D86F,2B628FB12B44380D,2E6AFA25584494E8,23BA188800FD9087,4F5DC280D8DA5F68,91575C031DAA1EDA,31DAFD9447EC1886,D562B653197E5567,000047C89DD8570B,9A6D2BCB8C5890DE,5ABB7A7E728B96F3,C7C586ABB944F8C4,0A170C4525F05B23,EC1EBE25D30F9533,9AFBD7AFF1EC98CB,D6B2DB32602FA52F,7D99795C552EB771,27C872F33D0600B9,FE631BBF1A754454,C330A44FD1FB48CA,0000228EC2F4697C,174B96F6C55ECBC3,E769F1DF79722866,792A2CE9652593CE,7BC96460CD611AB1,B2235EF36A38595C,C759F5E577342C5F,7EAB94D127B19040,C198A4B67219BC67,550D636D625F48FC,D88D4209A02E4CF0,64E149FE7760D2AE,000014C377263A9C,36A7EFF64FDC911F,E80E89E54E232024,3CDF9F8E68663316,E775CE1312E6A132,A69557DAB16E5725,812BA67191FC4AD2,9CCC1BE9265F74C1,0BE9D3A26946344A,BD032F7CDF8EC45D,6FD8B3FE31748723,44404AA71C66C73F,0000361E9AF8CA33,1B1F77428282F43C,0F61FC95B48F9D30,620782FFB4F82F2A,C7E4AE0F5CAF0B9C,DAA31ED54510042F,F3672A12EAEE631A,BDD587379F7D5744,1567730AABEC9EE2,EEB0F4482343DA4E,22038A07246C918E,D1258CC152F4B812,000000CB19987EAD,87BEEEB47D680E99,733FCE19381FD9B4,31625CF6D32199D2,B955383B263B1866,33631CA6B0D41985,52C94EB8E6424443,EE3D4381EF67894B,6721F862EA648044,9DC926F4DBFA9D16,E1DF1AE81696D064,D46F23FCBAB3F1A3,000022F5F9480477,3761B23F6CB94F6E,5326096A206CD50A,C4ECB56C6B46943A,FCB87A0DCA476FBE,744D4FE4C3BA7420,19B75F222EB24E5B,8D90182B2CB39DB1,AF808FF44C572480,AE840E7114A06D0A,553612FBADB42BEA,E35CEC00C18399C9,00003C321A5AB98E,8B082CBD229772D9,9A1EC8DB62975E84,1CEB251C6CD1FC7F,C156A083AF540388,68A10C6691BF0CEC,9B206C5FC41CC7FB,619309C7CFDCEC56,8ECAE0D92D6B94B3,4FD53C30F872C239,4E23A5D6CCB06E73,D349912088A2819C,000061C0F874DEE7,9D1737CE34FF82E5,C1694C98CEC4278C,F8AA2A84B04937C6,1C150D9CF23E240D,4AA0431B113B4630,32142C8C95E11E70,340B82382B543EB3,C93F796D77D69049,BD379DC3C888E55D,1DEA19CCCCEB52FB,8450B134945DA6B3,0000383F1C0009D5,46C93816A16A25CB,9FED7153F0655C18,98FDAC5FCC9535E0,48B37CA5E3C2E525,0BF9231848D4BBFC,8359E89D3F63B748,F0F5F9351AC0FB50,2D932429BCC841B9,59568F196CFD2ADA,EF467477B27B827C,85F8AF169DD40885,000019E4646964FF,47B637D2E80B6F92,CAF8F8AB19C540D4,334F933870FF17CE,FB82B30D503041F4,1B8DA60D29B0C009,1A883463CB41D036,CE82252BE5E5D48B,752507CB9D8446CA,243EAF34E43429E9,DBAF4B0BC57C1561,44A5F147607A4244,00006D02872BC257,075834B50758B8AE,809CAEA766D5C8F0,9A926594AD89C080,2CCC0789F16091DA,C9A0A1407A25D6F7,91284EC8D2B68F73,C53280CC05EF997B,160FA975F4A3B1BA,07E3710700A88D2F,C0D2D4E7B2893B25,FD65ACE863CAFF68,000051FE404196FB,FC7DB2BA01CAD447,1C1D1CBFA9146619,55D55C36DD1A7E7A,F3076CF7ACC0B54D,14E59FEAFA1E06C8,37BD514E10644946,9A0E8F6A6B3C5D6F,E7C1576CA9B8345D,B46A34FCF6078594,103BE61A803D0162,067FE31A937383AC,0000153C404B9C26,3761345BDC23C441,C0DCD8EB646DCDD4,49C68F1BF3637089,1E575E07DC150FEA,7DC6060D34B01078,E2E58B8F4EBE91F7,BFF0337B446779DD,28901AF766E6C42C,26F3BB37D075D431,AF0A62A748789085,5E2526DDE2220ABA,000066838B2D2E17,1349D680B460AF1C,7CB4D48168F216CE,723AE55569BD0799,C02452340CB539EE,A0282D8B657228F5,AA72CC923AE16237,CE97E34ED3F61F6F,60753C74B4D18E3D,C07C4A030939D8B2,48CB41EA20EC2F5C,BB6CA49672E5F0D6,000014F3FBC1ED6D,5396DA2E2C409FB5,70749FE1465C08F6,02D3A02B56317396,1881191DB5DCD5EA,67A3741FD63D3C55,8C6821955FA4E23E,C3A4972496EE6EC8,2897BF8EA99253CC,811DA719F2CD4B83,EB944DD21F830F28,DF8CACA9D2CA41EA,0000137E5D38BB59,D8984ADC5987F02C,3AB375998F99AC1D,30F03F89F75574EA,EE9052CF600C643B,45E029BC337581EE,05C7B6B0E2CB305F,5DEC0BF212C56F28,D08F5C5934117499,F5F2945D202FED7D,15D87F6DA51465A9,EB60D6AB50FC3ABC,00005231493ED54A,9699DA292BA23965,24FB96AAE2EFE289,36D6239BB41A8FA2,70FF1F16CA70E69D,1AC89DAB67074A13,8E5645C096644D5E,5F0038ED9070C4C5,F2F098646CCAEDE7,BF1E952546D2BBCF,1D8B5B01E06836A4,437CA5363D7D24A6,00005BCA6C49BBD7,E67B3CD6F0AB2899,781A0895E7F70180,FCD404235E7EC131,A4B03AE70E0F783E,22EDF786319CC301,8813075001E90B51,D90889C71C30CE3B,17DE6F98E9B1F750,81FE2C6EA3B656D2,C86934849F1A9589,1DED02CF3010667D,0000409BC3A390CC,7BB55BBAB561DD54,8D438D5B712374A1,6A8E77846387E80B,CA49134FEB6F611E,2AA07676FFB00332,AF5FE6063E8BE489,FC709392818BB34C,5776CC24CD71A86F,BC8A4DD14B5C9DDA,F57F1858B3D55F6F,90E82B8410F739B3,00005C20AC1D72F2,2FF122D24FB203AD,9D0BED8D902147ED,494499CFE22136DD,93C60C0A1F104503,BA14566377FEDCFF,68AB334277FFBD6E,5EF737D7FA288DE9,27CC4E17B85B5C7F,67995305FA317172,B1DC3A5AA433299C,395B492E7BAED4D8,00003EAB8F4F1748,F9F9F98B07DB0D83,EFC1EF29B0294268,0E4CFEC86B479C66,00B6618B176BE267,10D4379AA555076E,578BEBF5AABA9CF8,3271EB1A02AC5634,5CBCAB66555AD665,7C1739BA6642C8E8,5474C6ACE5CC693F,129D17A5D4C7F00D,000067199C09C4A2,62EB7D161D8C272C,370D8E15A397BBE4,F7AC6BFFB85BC110,447FBE2450F25CA8,5671699416934077,5CAAF08EF8D3677C,D578B4ED7606AE3C,623255DB55B65EA1,5A1BDF3F702F0338,E9B0916C72F0D915,13E5C9ED2C0A28EA,00003D975769068D,73BA18A92D617147,BDF8A702F00F0B3B,D65CAF2725AF1A7A,982C4B99A4F0D73C,E6B8555529D75580,E8A3BA490E4C0D51,88AC4D9B9565D379,6CD17F7E6A2B0045,A63CBCE207A64761,7FA8249BCAC37EE0,6498932F11D17F59,00001F3E4E3D579C,D67F077F14410733,26149CE06D4CFEE6,79EA133DF8FC1D5B,F08F9C8ACC5C9CF6,1F357836F2516E34,8FF0A3E560E05C99,8F5D663E2FC2FBAF,F3ED4EBB49219266,5F438CB60F7548D6,74F37A0047FEE42B,14F35251D9F4909F,00006B391F5B2CF5,D851EBE8E9E11FE2,B51CC047B8A7E449,E3808F9EB907C5B0,A7DA8145ECEBD73C,415F0298966C24E4,E3E7EE3C16A59BD7,53BBF08D1270BD31,F2A9669FAD5B6E65,A25B58B1BDF1CD25,AA946FF518E5B41A,8E4869711C77B659,00001972C886351A,894E62B747414A79,9BCA855BD0588419,A17B293E5752151E,272F957FF4024E29,4C1E6475CF2B6705,CF4C6B381DFD214C,96AC3D9779826D48,7A7C606D13F4B563,1FE98EA2522F4F4F,F27FC5D103BCB67A,2F07A93D5CBA2569,00000EBCA9709A4D,C1B22425F20E94C3,590D9DFBB0809627,1382322497EC3516,60B5CAFC747763ED,C323A0C3F9149915,5DA17D20BAA1979A,A586E10901FC0138,1D031492120FE39A,625A8A8BAD07CF2C,B1131D965AFDD4B0,A417CDE682BCB8B1,000054EBA017B28B,4C756AF2341E85DA,76EC5456E3218080,F1312863B3F71963,933F999F6DF0A46D,AEE139FFBE4B1230,D9FBEF50D7DEC768,98F7E7C48F827485,EC5DC47AAD6168BB,A415154B6EC98366,74C93DF8546D6BE9,E4A4B5FCBA4506C6,00001252871A4534,12A89B4687F0A1F5,449A38771C8EA701,E02DF4D67D79DABB,0D36258BF583757E,87A1C2C2234DF50B,FBDF7933BEE25173,1BB008BEC722EBC6,5EA8CE41154057DE,ADCA7DE8305ABE21,7A3BF4EB10B57F95,CC0C3E8285D3AE79,00002C41548ADEAB,90FB8AAF89D0DB08,AB08019BE08B9706,7B09F09D6CA54ABE,65CCA51338CA96B0,C5258287F81DC1DF,7A942CCB380EF28C,CB427EE2C17CFDA1,B5525A7B113EFD6B,1CD2F01246FA0E73,3432A3CBCDD58FFA,CC31A5178D0F8FD8,000008FF8F04A659,A6DF02501489E839,C1FA7524E3301058,5FE2467B99C6495B,DE520E9CCE19C60D,169207853A839B35,6F67E5B73B03D059,2F54FF5B206E8C4B,4DB24ADF6BD4AE8D,EF140D19E16260CF,5C17516CF523E570,7140AE681BBC61A3,000044E00817A1E8,6EFFE3CF869E6129,6CB9059A91E3C461,17C86D87E2FF0750,ADCDF4C463315575,80218FE3FE87057B,2E226DCEAD038C61,B7BC428BA59EE2EC,4871998006023122,9B3F6892D0778C12,8985663FF1F0EDBF,7D441C272D580E01,000057D65DA94307,E2E5D9772D123138,5D57CB60BD112059,A71E5A6BC20EEB3C,956CC7A94E7F9B6E,C1CBA2FBB0ECDAAD,57CD816F89012066,75B406ECA419FFAD,3535126CA4188F34,A3BB949D7AF1E3E5,B31953D164F2A110,53B560F65253B1B8,0000201877AEF077,7819CF46B1ED9F95,1C81D4ACA0F5B13F,03B672D6D3AD7743,1B57AF16984A6898,0C3B22AC78789FE5,C45E1B4F55D1491F,1881E0AF9A0CCC68,7FBC16A70BBC9901,2CA3D6F31F09A470,490396301AB0FEB7,BABE3ABAA2BE377E,00000F38DA824876,ABF2CE4BB2DC1402,8C84F253724CDBF8,868F8412F4639EC0,D4B2705F15AFCB5A,C330449B48FC7589,14F3C53949C90960,C4BABAE6AF1140A5,D332CEFD558E49F7,7113D2B83DC70F3F,7A80DB87D95EA704,1EFAB2574A62C49F,000032AC9904F286,D222C58E1A5588A7,92904C495FA9DDCF,59C107825969B2AD,D33621CD2A9A7661,1FAF8212A02059E2,6C60A3E9D2A11ED6,B6011185DE5F783D,9856930B4E73264A,7E102B349146B39E,F26BBE5B82FB2162,C464CB2568B8368D,0000076A0988BD66,1825B1A62E2ED010,E455E15314703011,E7CA766523E6F594,61D5C188D463437F,0F097AC19B4793AE,F60AF54A36970104,C71D023D694BE813,58DF88746C143303,46F753C9DC06DE17,85CF4ABB5A5581AE,E8A7E3946BF61074,0000099B3866679C,4D38EC7EEDD6182A,5F17361B216E5831,EC947336B33B7863,656DDBD355D56C86,59E64BCDF3D1514D,3A58013E0B2C568B,9FED9F16112BFA5C,842AF09036A924B6,65041150EC38CDD9,866C24A3A477313A,57E5FE095CBC28AA,000027510EB28388,E92460589FD9F253,587CB98A41901A05,CD61BCA21E70DF12,42F80D38792D1F63,E09BF5B3CAA71FBF,CFE3A8871EAB9B51,0CAE98E59D8B0B1E,AF72D2A5E59AC99B,4625CA36DDB5A14A,D701568BD91334A5,63D7D8BDF38CABE3,0000695851E27551,EB584608678BDF5D,2318DCC98A21CF34,B7C6C070FC4E2BDE,19F1FE842BFC4E10,B749F8BA660E1883,02132E2CF6481259,7277E711D0A0B2B9,81418393D84E4801,941000D1C23A8963,7995948580CBA511,3554BFDD7BCC1F3D,000029AA3694787F,187BE3F98D8B46AD,033FBD26C4830796,116DDDC3118B2A1E,E2E8DD716E648E6F,8E09A92E848BA166,CD670CF8EF58FA1C,5F5B292E5E1A5F94,B058C728AE64D6F2,66F2B9D2CE3F1907,AF60BE2A68A6F7B6,44257D01E95B57D2,000036464A48856E,AB76ADC767589909,5CBDC5CECACFF666,9BA87016B4E42EF2,BF2D7CF5EE46C019,40B11F14FB9BA99A,2678AA8193ED897B,1FDC9EB3DA9B80BD,1EFF97D4E45073EB,F402517456E279DC,986C441F2E5EDDA2,1292D181FCDA896A,000057DE36C85F36,236B3E47600937B4,F81B7429EBBBA4B7,BC46C05737D570BF,E2D85C0B24C67916,50F47B9E09697AE7,6F362C31FD6D4D2B,D51825F0845BDCDC,FD71B4880FB79F01,E97BB78669A77D56,0FE3275AC8054542,BBFFE199AE816ADA,000038C211D5D53C,5A473EB680633494,614D88172FC076EA,E5D520507735AC25,E1AAA4DCB0EE4361,F3C4F173C78E4577,2F19C73A87A1B0AE,3D803408EB33A79D,3674F0065A7ABCE9,1274BC58451D3451,9401D23F88E9B0BB,BEF0E5CC27670DE2,000053C66B1B9CCD,677AEC41F9AB5176,FA8B64EC984E9D2E,E7FCD36AD57DCFA7,104F49EA7A831AAD,35C6C3E1307660F5,1C336BEF9DF77BD9,C1EAE561C900FD1E,50D2A99675F2EFD1,69D07A26F7B346A8,DEA82E4F398459C2,9106845A3EC7B7E4,00005D649DBC65F5,4904B149C98DB8C1,23DA5C63CFEC01B3,8B95A6919D0DDF86,4FB5CA51E27DDE89,4BD0D28FD133298B,EC1785CD3AE74890,B0CD08B7BB0E0EA8,E325EE7DEC8F0692,36CC20EF487F6B9E,A414C26826A794C1,D0C94117866D9089,00000968AD95487F,6BB9E7FB28B984BC,95795A6AB5ABB5D4,0722FC1253E6CDFB,BF8CD565AB05AA7B,3A09F79015A3D0A5,5C87B1591B1A805D,B014A5EFD3E1195F,B745347F4678500D,ED8F9153BE2D4095,83FEA968F2702CF1,25164764668CC43F,0000644E87915CE2,C081AAAA2CBBACA8,7B314443DB098369,BB9A291ECFBD2E1E,4E5021F0F04CB62B,2C1A181640D3A054,880AB60BF05F714B,A63D5103F3412018,309FAC323B55CE56,6A53F3C36C7DE2CA,DB1B69BFDBE7A13C,353FD3533198F04D,00002BF5D10AF6AD,0A0F41B5FA6E37FB,AC7CB5D91A20A0F3,01E904CDFE52461A,D2D5EF1C5E65215D,85814BADDBBA300B,DBC303530E698DAE,9C2FB3DBDA91E46C,345AEF67B9C1DED5,B9A0FC8BF4286816,6444F57F38F4C14F,9B2C4ED6BBF0D36D,00005808C5F1689D,ABFBE7C67B291DFD,63109C03B452165F,4CD3F32ED4ACDD32,37C909AF48778091,7784F1D69BD5BC22,6A96E695B1017F27,2BE9DFB6EC753E45,A6A458F340823E46,AE39D4EDB10DEC46,1BB1236BF721989A,4883711072A71BB8,0000425AA77D0C5D,C4D0BC61C55FD5E4,D24F8054E86B9C88,BD1E6D2BE1C9D1A5,E663FA657F3D577B,CFAEC2840AD1395D,323D92C1FF1F1502,89B11DCE575E214E,1EAED0A5583938D6,92684F39D980D549,E0260078D353284F,14BD0C1CCD829D20,00004A3004217BA9,A8E0A230F192DFAF,71C34D42631D62A9,1DF22DBBC5022EC4,06E1967720FD2D1B,B49F11231173EFB7,E903CD7E11ADD357,B457A970BBE0807D,B8F90B9FFECD4484,42C632E6900CCC53,53923746C169B39D,F0553EFD2B65B38C,00006B9089D7DB12,668268769D804BDC,E41FE328BD33D1D6,30DFD5C08B30CB24,2D2D207B9C19031D,07D7FDC6CE4D2710,A8929852FE88E68A,A7ADE3D79E69349D,A8CE5F6804968EE9,61CB79E92BD9DFCD,44427DDF297851F0,081054444261A970,000050840381F021,AD768127DC363E16,189348AECBF2A48B,CA7067FB9091E135,471CE0AAC0D53583,391C782FACE4BBF5,8CA561D27E5CEF3C,4EB8BDF102CB9990,AE086D3A7B831BA4,E81C25FC46139673,3023DDD72E6C3A16,8B2719E8695B65F1,000033C22307EB57,A7CFE0778679C44D,136A0721F403B55B,965A11A0659B4173,1FB24FF0DBBE5DBF,CECD5EEDD7DD4E35,93806DF43FD5E6FA,606530FD1A17533B,5EC28A4AAD5CA5E0,E7DDDB72F98D13DE,353E8B94789A9BC4,4D2FEC07D956B1F5,00006E13620C0F0B,EAEAA68DAAF974DD,BA5534731A8A55EC,81E6187379B9CD46,2C42368EF8E10B97,6416B6D7308F9E7B,913BCC65EDF1980C,F1066ACFDAE1F543,1EA79EC74AE0A9BE,F918C9543C869AD9,894060DB8068A315,E188E2878FF8B8AA,000069A54222A41A,D1AA11F5CA071D8E,6FAE6466ED9BBD5B,50FF29B1649E351F,0A57662579E3F5CE,41E416656299E706,1BA92DE18B37D607,0068E78623A776B3,7EAF4798FE0656EC,7BE1AA56441B922E,49FD07D249D54BAF,061AFA3C84CF4E4B,00006BCE82C7F933,56C08905354DE42C,7C32F0DB81E1822A,418449AF6F26A685,41B8BF2D8BEF0122,E4E22B44E578A27C,62B7CEF2B7FE853D,3A3D3C529BC6507A,C97C4D747B66E16F,12197B7D419E7B92,40F8A222E8C33C7E,9C79A14D4673546A,00003131346B521C,5CEAB85FAF07DD42,A87E12F5A755D4C5,615FC0DE31E5C8F4,CC8AFE84EC78EF8E,6742AC165447ACB3,30A75E27D427390A,24382CEDE3926C1E,17F81DCF5FFDB8E0,D21B988E13B0746C,39592CD3CF6153B0,5B814BB928EDB1CE,000049DA0B78ED97,2EA8C6D3A190E65C,4FBD41138905C7D2,349BD5535BFACDA9,FB05A7B0138FC847,E2946C8B7BB7E683,03D6BD8A6AD611C8,76BA435481B4E333,1CB9DA5B25BD8DA4,500D3106E3440A02,BF1E7A5B2D107248,6399AB2FF8EDFB12,000008946C51AF32,296E91A8B92A7F84,96F3EAA66D85DDCB,10109740B1F75BC5,731C1CEF5A43F029,AF4EB495E4F07737,AEEE6D1BBB859038,FD636990E55A12C9,BBFC87C305EFDCF9,CFB3CBE3B60F81F0,AC0BBFCC9AE901EC,643053027339E764,000008C0AE7A6504,B84F619FDA69CDB9,A1B6738D4EEF4A64,BEB0AE67B7B5F364,FB3968F956537DE6,F45203D8E188CA2D,EE085EEF7F2C7905,0834150C45C68289,80102959347BEAC3,ED3D68B1F65FE12F,40C6FE4CCA076E5A,E415736944883B4F,00005DDEA43259DB,6730C8766B296C04,D1F641EAE74296B5,2B0AEE1AC4E41D04,9C9233F6EE8B2A07,B87B5B20464B86DA,BBD6D4AC3344AB71,672E08147018AB07,01A1D36440EE05EA,1D291C4F6EDD5A40,A822E7E608DEEDE8,E6ECC81655068BA5,0000681F81039CF7,76E0F28CA887905D,41EF3B6BAC3AA714,F8A57602F11900D9,455ADDD64E6F42E4,8F6992D17A4216BC,A94656757200646B,D17D4BCEEE37FD18,203CB6823929FB15,0EF1EE5FDB531FB2,7C9EA94BDF2F2AC5,5439AE89EC10AB55,00000B13AB5544CF,F6566ED3487466AA,8F9B8473A329271A,FA540F922DB72841,153AF81F3D4492A0,5B8876D4E0C75F63,564099542177191F,DF3631383AC8A4F0,377EB5DD1392AFE8,D3FACA73FFC07138,65955B848CDF3AEB,D30ABB0C48181A3F,000068AF8F6E6088,03144D76BBB0F9EC,9D86542820E7FBF6,34817A5D5347B14D,E160B5FF83549E85,D3339D122FFA43B1,C35A760D3397E0D2,6FC4ABD64DE6BE3C,DAD6B73BB7E428F4,4519F7A562C7443A,AF299262D3F63D1A,AF3EFF9F342020F0,000025025D9B0FBD,7AB9003D3B0DC937,E35FE58DBF184ACB,3E8CA6EAB245445D,6AA6DEF2091D2B03,7C6957EB020A7847,D56D290406EB95A7,E67C4B823A987C8D,4696489D0C4D944E,DE34DE8CF9431C96,66A01FD8E48D944D,041B65FEFA82E7FF,00004399960B057A,6BFD38D9801B09A0,2F82054647E72A9D,290F5993C9E0AB29,59D514CFE15DB6E9,DFEEB741F8825943,74DE327FD5D961EE,8F346A857517B813,FECF1CBFCB11C23A,15E0490DEDC2E6F1,9AEB1B84750C9A5C,2F170827A29BABAF,000060EBDFBF816C,5028E33DDE1DA3C2,5277CE1AC8A2FB18,3BFA5786BD304190,5313D522EAD695C2,3411571A24D4D570,B2C1EC4EC37B5275,C0F500B8426B9D29,6541DAD9784DCE6F,D3E7D1DF244915EE,5816061F0373107F,8879C789AF1ED16D,000042F2E70C66E2,1E54A94E4D115EBA,F2C2B3F9B59C874E,F87ECC50B4CB0B20,0A73F99A6912DB60,8370AABBAE36EF7C,C71112A027E7E650,36ED7A22F6B52979,1986E4B7DED3B900,BF350EBDA2D90D84,6D369F518156A63D,D29AB3584AD9A9FF,0000648F767CC324,33DD7BFF0D68658A,341385E69B58D495,CCADB2068827BDA0,68495E89CED5A085,515781845DC015C8,D7450352D398350B,A1EE0A89F0E25C57,8F4B2838D037A499,CA4221057CFC1F86,328BF2E50F0405F4,53B75E9AEC2EAECB,000060A89BDAC91C,9161858E1B8544BF,EDC68696CED6FC06,6904D6EAB3E1022D,AD175AB905DF8017,95D3BE8E9858242C,EA5F9BE4691EB539,E22BDAB01699A457,90438616312C1648,D9815195FFBF8DCD,31542EA6BCA4EACB,215C8676E8673A63,00003D0B878AFCEA,05E28D9730D98244,FFFD47B2CEAE9619,72C56B43381F38AF,3B449F5B561974BE,7FAD38E11E022D23,322359508F8482C8,C57B3502587C1049,DDFD7CD4783002CF,80B1D1C61ABB09ED,EF9A46E8F2D40937,6272CE4BF33CF1DE,00000F0BE1C688EA,A4A32E1A9B1D8B05,62E41216840C167E,34A4D09114281E07,D34EDEDC228E3692,697D8A1EB36EEA00,BA53DD51FCE695B1,2F9DBD26F22FD882,2AB566937A2D115B,29762BD43841E219,AF261F6E69D228E7,BCAAA79E1B516F57,00004348A9F58989,125F8EEC240F6661,FE0AFD854634C365,F6F05255B0E36C77,332A8B9A85A4D102,57061109E12611CE,0BAE123C9EC8F6F7,2A34E8DF233EC046,2998E388DF052277,48B71176482C5457,2DBE657B0ED81634,BB5E620126FC9EB8,00004783BC2F4BBA,26CF3161E60547E5,502E98AF37150A39,7382AB67B5657CAB,4BEE274C179CE8BF,9EE01555A56C32B8,BD2B46E6B980079A,B2D7E6C04D85D1E0,60DE6859581A87E2,928DAA7BC7573A30,538EB68C5C8A0356,27999BE6DDFE3F8F,00006AD3F9817481,D200E1C9717201C9,757A7B63FC38AD9B,E5CC15751F1D280A,04F6BB1824AE61C3,19F505E3F22B0BDB,779C9FFB2C5A7DB9,0B66DA656FC37C42,935CAAA6BFC782CE,A6EFC3604668046E,E89E3100E71B60D5,F530AD395F1F9B87,000038B3B6765B70,9D7BB160936EB87C,6640F84AA8D8A1F5,0A7ED711E94696DF,634A5CBD5DD89F95,2DA55A541BE13B54,346A0FC49B8E2368,409F1F61ECC5A8CA,F8311D4D146B8FC8,FEE747572E35CAB4,BDFE8FFFC0141C01,C845A049F48AD221,00001B362BD99742,861D60843C32BDE5,401A1526E8DE0A6A,88C56057C404E220,0FAE69C6FED1F940,B241C99E43F0A36D,A5F0D8139668FDFA,EDEFEF7DE377C9F3,6BEC081B0A098CAA,665C30DBFDA8E257,DBE029C2219C9D5D,114D55C3667DFA3E,00006A3561356118,2DF7B9F282F5EF1C,92FE0FF3CE30923D,871C04924B56D877,87D7A8E1ED634801,1DC322613F8A76E4,8D65A8648637190B,2903D2C74ED10CA8,703E2F4F75A119C2,DC27D35008B1B69C,5F0CF99EDD16A74A,05A18D867F2D7D82,0000349364B329A8,2FAA222BED429841,02D347AE4FA7619A,0B40AEDEE0A7B79B,989A0A66642C467F,77B415EF89A8CB78,D90EEE6A725EE40C,705DBF4A5C253B49,81D8BB758D6775AD,340D0E1D7DAE2FE5,3FCA143FF329B552,B4C6B369F191D5ED,0000122FA744BBB4,95F23F988EB026A8,3CE0C545CBA4E6FF,C96B7A3BDD018036,D82E525EE621C0E8,58036EE2A9CCB606,AC87C2A1E4C8FB6D,929B5651752A3C19,34D4DCCDBD1D6EDD,15A893B40C9B3EC7,B6BDFED9200D3343,EEE41EBF637A0A4C,0000573E0B65939D,6AD855D0646A14DB,FAB1C2E5E4505CCF,51265F5022CEED85,B5D094FFC7E07429,DE4C76CA4CB98537,9613692317F12801,6397BF88F5396D2D,C44EEF5DED846D9C,05E27008D87BF20E,3847626BBF7F9D5D,39541B9A41E81E65,00005A1D5C5DC79B,3D791F951334DF3D,5FD677219C3A823E,A5E0028076C9125F,0B63AC3DB420266F,D677CF93DD045F7F,0B6B62B982F05F7A,A2E2F8ABB48416AB,940E35633404B770,94BE12FC370AE6D4,E78AB1A95CCE12B1,ED31E849DD467149,00006ED99AA59784,10CCE047AFF14858,C9854B00C5EFF9A9,1AFE4ACC1DB2E3FB,286059CDBA415E89,6499D6C8C368C915,B3578576B0EF6F84,90CDA4CBBBF10797,1375E4DABEA4E146,F62E4841B95FB785,10539B8B4B7B3C73,5D85AEB10F08ECA2,00001149ECB37334,ACCA76EB64ABDFF6,4D6C8169F5DBE0D3,ADAC335817A40EAB,0EDBAC4CDE55A725,5CDC2242C619ACF1,82027BADCE056810,CA95FF547249E627,346867F01FA4620A,6E3A649DA20D6E18,805D82B67F04691C,DC84CC2C2F79E912,00001B3906C28275,757ABA47E0109679,020E34673C6DC063,F660902B570085AF,AF00A13554FBC957,1C345537FD0D6EE6,D3D44F1AD62232A1,464B437D1C7A6B92,C23FD9ED4A6C7CE6,85BB8A754D54E1AE,3B1AE23F37482FD2,2822201F0BA82B79,00003EFDEA15BEFD,1241693474F4A8EA,7D8BD3954FB5D647,75D90FC27242D80C,3EC92A8A8BDE0EC3,FDD836D0F922A771,D3DA41561BC06B0F,8D9A145BF625B61A,469A227A78EE3A4F,5BFC12DCEFB92473,4BF0DDA1FFB3CEAE,E41688EC95E5736E,000004BDF6124B04,C96C1217F658160B,C5DAF85A4F47306C,E5F9E993841D0564,AF8DA64774594CF1,798CDDD938316231,5525468456D6BA7D,279F96B0DA9802C3,E4597DFFE1290C7F,AFAC1C3CB88330CA,F023466D9ED946FF,F8C2D4E9D62A6BEC,0000641626851965,AF6F75FD52E392A3,E208981C62638090,26AA48683575CB81,7E9B9716A767699A,CF37E149D1AD557D,C942A4EF22190A09,42995DDEDDF8306B,597D3D8F47E8E912,66F4F6D245B9F971,6A4C1638CE56918B,9A67867256F20A7A,000016A3407D8FD4,1F9CEB5E936000E4,EEF24D95BD18BAA3,E8731F6729C9AA51,06B5CB64A4CA408D,9151D6500E446571,F23E9CECE47E3A49,DE6A10994B22EC37,CD4C9AF1F9FE2FDE,8288B44EFD5EDB3A,27F905F33840135C,9B69755F410B0FB6,0000108ECA6FA840,4E385F85A446E222,8DA7889318633D69,B831644D7574FD76,7246DB036DD6CDFE,37DEDF36BED676FF,1CD5339DB36FDABE,BB0B8D6D8192880E,5E1E7BD76A486D24,F9E62B535F9B3CE6,AFC95D453AB692FC,9B67708C11B5A468,0000044911C51D0C,36D73322F603ECBB,529EA76C8A794461,52B2D8010283FA55,B26B747D6E61D852,BA3D9F1A091FFDDF,43F5C895E37E9067,1FE61096A60EBDF4,67ED24721B9B991A,C2DA8BB9D7B0CC84,A9B9DF2AA828015C,68EF0C1A054ED24A,00005A7DAACEC6A3,DBE03FF96DA2A64C,A23A4ADC7385CD74,F461A62154CE140B,B56CA76132C362F2,76418981EF5B4A2D,1AB87EC6F1621687,C5142CD87D6B8E30,10457065C27D38A1,47066F2C39AAFCDD,BC2CBC5A47FF4EDF,6F5996D2DF6B6C19,000018F5251A9882,52D87C13CEA76E09,FC7160039CE93DB8,C254C840DE6560B6,AF6BA20EFB9A603B,42833E2286E3FB1A,4E04F4F3F11FE848,8FB8F55B9ECA7DEF,3AFCA4DB1A30924F,09952C530153159C,ECDF31CBC8CFC59A,AECFB558C26B7EF6,0000243C6F82E83D,872C78CDCA65E545,5B392789D28B97BB,38513C6937AE41FF,C4E1A62C24391A22,12A43F6CEF8AD009,2E7528B3D1292832,B9C69BA20CE956F8,BCC1B5F8D2287322,C30A0AA8E94B507C,54BFEE4BC6B15DEF,40C98CC5BBB37DAB,00001FD46C572237,DA8261330F105789,0402074C9855D18F,5B2D1B91232C61F1,27E6ACAC6DB1B689,5A7C152B0C128941,054DD25E25831187,5443712E026FAFCF,90652C3526536FC2,6173EF7352F9AC7F,266223032D56B6CB,057E06D0C100F885,00004D4529AFC63A,04ACAFB481E892D3,6858B1EAF1536E50,40C014FAD1A39107,C1C13B638553F26C,6AB2FCEDF9DDF12B,B2DFE4D18E1277ED,B91073A9456409AB,864665AE6141AE28,2CCDE919A8F06281,4E76ACA7542E053D,722716E2D80E201E,00003DB5CBE42DFF,99B143D44036559D,06197AC3845BC7FF,7A5EC4A13646873A,1E2C48C44C860D28,065457FD7A5C3908,532E9DDF4968CC4C,3794B9032B99BC6F,06A946702F08509E,D63BB6356DAB2AC9,94C9A0B49F8580AD,711ED120083F3C52,00004DD7BF05678C,1F464FC13D578CD4,FF42FEA2017E43B2,FE4FF09CCA993D45,30C6CDA4F662DDE2,D85354844625577C,E78B5F92493C0813,D1992FE4715C61DC,87511C22ECDE54EC,3A01595AAD238CA8,181219719C098D76,F30E3B85F8F2BD4D,00005257F8DBAB74,79C864834350F8C0,C14D6EC4634BA936,D07A9BAED4131289,30E24CD17B33512A,97B634EE4628DD8C,15B8772250E320BF,1DB660DD0A154699,BC460FFC0AEEA2A6,061A5C6C9B4C8E98,900B76A927242A08,DA7395326356A1E1,0000430D0F9C37EF,93B8B5E444E4023B,E0AECADBDE89D869,15B2A63462DA699A,10B74A3079801F5A,13DEF7DE35D894E9,47B5AFFB50BDC847,01CB02D36E3680B2,06417922D8970EB7,A4CAF27E7D4D15E2,C38CF2EB4E9479FB,A97A0453E3FDEB86,000017C7703273BF,A78DCB9FE71973DC,DFF82C9B2FDD2A7E,61523D98D9728EDF,910E3C383E5C3E86,3C44DB732988957C,684AD5D031A3DB4F,0E8B69ECBBEAE776,6CE152099F2F17BA,F4C3CE8A71EF9DCB,8C5AF6FCFE586125,63EEEF9EAC0D3362,00001DA3471ACCC8,6782A5CFDB109BF5,0412F1A1DEC71D94,C01540D12F71FA9C,84D2E19EC7D2AF06,479F97F57292F492,35D67B120C2DC8C0,7260BFA07BF086F9,583A82939DDFCB0F,F0F82C333516BED7,C6EA87CF0D662472,270BE8BC53B464C8,00004856869D8252,3AF97CE604BEC982,4F4198D3EB2CA968,684379F0FAAE25B6,6162BEE52A94AC6C,3D334F0AC9CD3C3A,477991629C6070B9,7F0ABE0B48C49D1B,95577F5DA56C9156,496D6ABAB790B75C,015CCED57F8C92E3,67E6C9AF38A86682,00006AA0837EB666,1B1CD64C0BA9E31B,C186335C10660049,0F6AEB034E5374EB,07EBC409615A8809,9D3C0A7D770C52CE,8AA9090E077EBF9B,B1EB705C7B7F4F72,AF244EAF6CE1761E,E5078C9FA1F00ABE,268F6E4862ABBD81,420A3676E8E64E3C,000019088DC9C93A,A018D56EDFEA7E35,F7FF9FEB31603560,D5B89CB37F73D5C8,18FC48C31A57F456,51297A32E1473FD7,51AB1E64697C88C0,5D92A49FE5D0289A,C280EB75C392F2B3,EDA5283852AB76AA,56E9C1586ECE787A,254189DD318DDD10,0000505CBE439FBE,CAF4E9093C943E1D,93C1D192EFFD4C1B,AD3A77DF3298CE02,13CC3C30A75701E8,F06FD53399DBDC43,3EFBD86590BABDBF,CE763893DCC31A4E,21FF1D497D55039D,2D8BB9C23EE30F1E,64FE24B30B208F1E,F7B1C111460AD274,000032D58B44064A,98CE6AC6B8D6870F,89754E95F6A3E1DF,3DC17BD878B9DA2D,7FADB52CCB43CE65,F2E3F4BA54173AFC,338F0002CA5A51BC,FCB4397B698D7189,AB6D36C966E87B98,FEA7D27966D59F84,A5BB6D616D7767F1,780AEAB272EBD213,000029722285BA0F,5D3470714E9FCE28,FC05B1FA389347CB,4F0786259A368BF3,D773C39F03E51B6E,7F7FA72807B19747,3B2B478180C391EB,26613079D7A59EFF,1E76238D27C601F8,617B7D6BB716290B,F319B0E325626CD2,910153BEE8CE22D7,00002E673E8884F9,B0EF602C48577827,35F489BD5119A22C,09510C4B8DC41D44,0552A270DE7054DD,7A9F5E9CAA0651D8,2B6601BD1BD88240,CD8691963AC336B9,AAF064C64A254B1D,BB23F4FDB1706B1D,ADD465F52B5FCA94,47EBAD45A889AB5D,00001D7DB917E6F0,C60103001624A3E0,F5DCB74C5BC79DD4,9B6C7A968A8C9675,2E06CB225D35A0AE,5BC520DA325C3988,AF1353016E80BD68,585BF2FCAC7BC46D,A0A16695FBB17449,A722D6DE2AE1EE7E,1ED0386C8A8C7719,BCE78A678DFFFB78,000002E115AC922A,C2D57880E536026C,031632A7EFE5A6DE,6C4B4F75A9092397,E5CFB41151B9478C,EEA7856259156D18,AF6637B5F08A4541,3E39C3B0BB8F1535,FD439E2F0C8CDE49,D204C9C877DBB008,92C2314D18B91469,E49FD9F2D407491A,000018CE772EB4D9,5990C9B12A66BD59,2711C7AE88B16CEA,B6C7769821D7294E,38B1D5A731A7A3FB,C3DCF7987E459A0E,97551B2492F3631F,C4DBE7B2F8D5CECD,EA45988393932D91,534A63DE91FEC500,8A6B81A66135CA6F,5C9BE0361F044E80,000069C9787E3BD9,BFA799111731E6D2,9789C920AF1C5388,17322A82C01A97E2,1407509DFB84E9CD,777956ADBE66D0B0,FCE8F1A87094A4F6,69A6EFE6CE513D6E,913A83BDE4D057AE,4076EBB9B2D03EDA,336CF717B335A664,DBDFC25845E0E2D8,0000193D1C2D6B62,22BCF5CC4E7D123F,B0C681124E61E004,9FA994C15B5EEB69,1DA9811583B29A6A,84502D38D443104A,4EC56007876E9D4D,1FA76856CBD42AFF,29A6142C7B9C1D1F,B2FC4981ADD67155,C15F7FE824449D11,B43E49A738998F07,00006E284472F609,405739053214E0C0,65A0DDC472948C09,432A3E48798A1532,6FBBF7932A303835,47CA3AC0207B9AAA,983C17B3AD783CA5,73B689DB4A9AFEFE,B15F11E8BE657575,7EA3E14B2DC6B912,B223A152AF0ABB02,CC2583705C71C236,0000446E7E63CB4A,9A65647F1FFE9B0E,548210DF139F95BB,7306A2C9EC63ECDC,0DD85F630391C65F,5792D44BF9063995,84265E52892D0D41,2C616C462B556A2F,88F20C4D7E9B037B,C1EC3A561ADE1363,6F4602CDC108AB2E,6C1519E071A8D8D7,00005EF2D743A8A3,11B9E61F77BD17A9,7D51B77ADEF857E5,54661343858BEB2F,8FA1C8121310C04A,B487A90A23F24E31,97107BEED3266C64,2CCE692807BA8052,96376B22BB6A4FCD,6D60D8AC6FC3EF89,B2A5A73C01F4815A,32CEC2FAACA09C38,00003D3E36DC3CA1,10C2794620F28589,78CA5B45D37A8602,2DF97CDA01EDCA53,304CB52B9AB7C791,DBD56253E6C5E1D7,1A22B7B9959F0D9B,8200F81AFB8B8DCF,53D88743235C6CCB,A054BF98F1059085,9DCF9EAE47110457,518573ED06011390,000053DA952743B7,258D529AF159E393,5700701379D3EED0,FB4291DA0B09ADAC,E478D6AF0028D063,2A2DD896F18C76C9,A19B3A7970D67361,E11D39B1D81E11CD,A7206740F157649C,A791CD73BB69FCE6,EC4DFA60E6A1411C,0BEC5389C34DBE79,00002A6EAF7E3EAA,5346F6959B76C292,83692B87A126C7B2,DD88E87AA786BCEC,94CB5D733AC5EBD0,DF7FF57E2AD538EC,B2632A688ABB578B,23EC5FBEA13060C1,33782A63C6025B2D,66AD82B45868CE65,E10FE691A2D1A114,F993DCB11897FD4A,0000263DD98761F0,94A19D6CBA6EB584,0B9906BA417DBB28,FB1B4F39A1BC599C,13A33FE80203B3A3,B5A53A3D8C432610,38958F445CF9D0C3,C24102A1F5ACD889,CCA37CFB7B4FB6E6,E44AB653C6C73E83,CE22A69F1DE84755,DDB5B74F47A4F0E6,000022E60060922C,2A040C716EDFFFFC,9A904B6CA5A6695F,3EEED080EFC4ECDD,A852B70D6B1E1D66,9C0AD67324D84548,B763F2CC5B9EAC93,D8BD8156174B5C66,958CD77A77D8EE5C,E6F0A3B47DB285CD,7460643615380F60,EFFF85DE5B4A9258,0000410548172123,8A03B4499490A005,A8E45A7F528EF0B7,0E627A9ADB424A77,8AEB93C12CD9E76E,2EB5387504EAF351,B5A2DA0AF791980D,24E3FAD900AC3AE6,A95F118199B583AA,360F9CA16C3B96BA,FAA3D0509E8F68E3,4D0208D0A8FB9570,00000067464BC3B1,EB35327AF19F9FE9,19ABABABA281EDF0,3C9453596A0A1368,E3BFA643E3028350,234EF22278218FB1,33DAFFF82CE822A6,0202B56E4F57CBD3,EF32D4DA3C9065EF,90155C14B9CA0A01,3D1D3DE431BA0C1D,95F31FEE96B20FC6,00002F2ABC16EBCF,F8DB6E1E3D3BBA27,EFB36F1FB8A393DA,605BFA36C11AF0EE,6AC79B2B102A63E9,EB32AD8997C38966,959493F063881547,A313A66C19F159FE,CFBC138718E5909F,012DE69C5710D0F1,CC1E9875B4E45F80,0EB8D9D1ACF2B33B,000059308580064C,BF5FF2CFB47B4EF0,8F4D8E3D3C7A06F0,B54B1C6D2577E47E,48A0746EDA910E56,AB4B7CFD0142E264,2E2804AB2BA484AA,04B251CD98A86451,E7B3E0E9FEA5CFBD,209AFD5C5389EE1C,D6D892A1D8903EFE,3CB1D3547727A505,0000573B0E02B788,DA9725A436611029,67FE63E71FAF1DC9,902D548BEC4449DE,EB6C9865E1D3A6DC,6D95CF84912BF84E,E368FFA80711547A,647B007A740C9083,81353CFF1DA8D3C0,0E97355468E1FE39,D049615EFCAE1DE5,29CD1672B096B2C1,00004E694B6EE42E,8225F39DE158B042,DFCD926985CAB492,BDD9CD72C3446E5D,DA75E4D43BC76D05,496569B6221E5E37,F69CE0894CD8D967,44E532C2E2B41A5B,D2E7379C0D2B57AF,8F6A32F8289F5472,A84C87CE06ED82DA,124A61709D287ADC,00004D3F28F062F2,002F5A592DDBD5C4,40D7BB269DA6B6FD,26572038C5F723D4,4847570A702AB519,E50CA77E80D07A3F,CE931AFAB75C421D,E1CA628E6B7CB19E,F1D7A9B4747F2CC3,1F673C64E031A958,511F1AC14865A857,9DC5227F68C05CBB,000001308A131604,F775500778EDC1EE,55D5C1CE81CDFA71,C30D5E44B2145863,39C2420E01107523,E6DA7A3189B5B742,C55BE0C17B891068,9F1BAC321260BF5E,D980D38B3FCF0E01,C52792979426E12D,6EA5357E2E0F4A09,691E45EE085E28EC,000043E6D863AC1B,A9103992B0056C4E,7297DF637F4E795C,A7E660DF434100FB,5F0B862D9E8B3E2E,C276A9748B6B2195,7AF1C1FE005D4FA9,F82438D54A883646,C4F7738B11EF7B85,BA5A4A3959B41093,A16CD095CC51B8FB,2FBE1873FD1701AA,00003A347E946C35,9E1D57F5DF33B665,2B30D8E825670903,E6D45815AD31B9DB,9ECCD3738C302DFA,33BC2D95C03654CA,A8BE805076AED59F,ECA9FE2066E90E7E,F01C6FB89A3E9F24,355D2CAC45CBAD3C,F645745A9ED56AED,5C53E0D173591680,000059E90C678638,CF8E28536190C825,3DBCB4BD5C29A8E7,B29F0D762C09C6FA,833DDFE0080BEAEC,C30107AF9FC8E937,218E69E89AD01966,AA96107774423434,1F2ACAF639820530,196877A9ED86124F,ABDD1328E7A578B3,B13230D00956E398,000046C435ABA9E5,909EF5D191E760EF,4B8A1ABA54CBFD29,ECBCBAFE60AA59D4,8C943724C833532E,7FF5C18ACB8EE99F,8EF6DB825FA4F7A2,E7F22471F2E8C321,A23EFF40C5F6411D,B8B905B42922515D,AB21D4A875BAB8CC,DCF57EADA8816307,00004B2278A5C047,930D8EAF45414947,7657CE0D09017811,9B829F87F98A3FFB,C24A876DA12F52FC,3F6AC717C4D98B5B,D75E3F5EF668F621,2BC086FA34FCAB0B,3F018964E15CB047,9736F45A79E882A5,5777CE52F4274450,87F52B6A64ABD591,00002FFAF3B90D93,6ADAA100A868744C,6AF03E218D66F1E3,0380BB9683032F65,96C512E771A5B52C,3E885747EE485B45,92EE1F19F10E4C61,F90D4B916E7F5EEB,1D1715ACE1DEF6ED,1918E2F9BBAA832C,44F966C59D38D136,8AA5EDDF33657128,000024CDD0211E1E,87660483B5EC07E4,ABE9E07A62D60B5D,3E9ACA07A51AC000,2ABCCAC34F60BD6E,382BF195D2607BC6,AA70E686F9BF2F0D,4576AFA654420E88,78B243B7E8CE283E,E22C312F9CC43B51,A769F7260BB75FC2,0566E96B9C3DFBDB,00006BE8D94ACA56,EDD919953F8A058A,FD44F62DDAD1C676,8E5AE2544A98EBE9,F87284A3DA627C92,BA5C5D1E6E492A42,F526F255317710B1,C1DFCC343679E70E,84AD1B8DC8A69D63,0C8218604C62C74C,73FEDAECAAD593B2,7F2C53FFA3B02B3A,00002AB5570D37DF,83897E0D6792A7E0,5A22C09CFD11C418,8B4BD5C228C8EEF3,739490A4F612B25B,2C0462C98239275B,45D639FA1D0A3C99,650F676F5E52F7E0,68F4DB1FBD978B7D,3075E58F472FB9A3,2BC7F46528FCC896,845C58B0CB922871,00001A3C474078C1,F26C95C4846CC9D3,29F88B5DABDD5961,20FBE06B3B1082AE,70083672EFB2F610,30B8D475D7CC2ACD,863FEDC7C196F48D,2AACB1608107AA5A,DA2FA09648DBC129,2542F69608ADAA8D,FE013FEA88349232,C3B09C765B0E3486,000063584179FC79,03C74A8AC49011EE,85D8676936EB0A4B,24F6E2A8E2237EE5,ED360C3E74CC74AD,9FB4691CEA01805D,50191233E222B567,D6C8086CC4C1F1E9,98AA257CF560512F,6951A5833EF123B8,F5003B3CE5088BF2,31B208CD4FA49315,000048166E35058F,61E9D3DCD42B6860,ADFA7A77960475BB,F24D7669B73A620B,4120AF189DBC1CEB,9532F9C3DE810920,602DF0E16E204983,F08FC8359EC51CF8,60D3E14DF4F7F79C,3121129C683090B7,5F5F1F6EA61E98FE,A11ADA3425250291,0000633544C4B73B,6FD385862D6FFEEC,DD815712F64DFE5A,3E30B23791D0B0E1,464331E791DA07A4,C3F499F908E23348,8E029C4197528AEB,09AD1E1A21737549,840FA8F102A84899,5C77A727CD85D946,1EB8DCEC0C953D1C,30CD8403FF9230D0,00002C436D19D1B0,A9D5DDFC5B6EA96C,76E36C7966D3E487,FC85731ADE8BE4CB,582D3F14C1BF7EFD,35A76CFC03BAC9D4,177F2A2C4D02990D,58E43DB477824E69,7A94A5E84174B8B9,F6DF1CB14C581F7D,A9681027A78DE675,80B6B9C7D7E75CFB,000057E93607C934,2C85B7A093F21DE4,555888711D04CA44,842CB6E312F3C8CC,CAC0589AE42449AB,D30D84AE6FA9DBA5,E378DCA95327678B,A1CC3DFD5DE22936,D58A6751B084ED82,A6A712FFB649340A,0F935191149E9DC1,215C75983AD243EE,0000394BE1CE6AA3,DB2FD839CF9BDC90,0F7C6C5F3F3E6283,521A4F6086217324,933C6CEE08BC031D,B856BFB5E911A3FF,FA9891069DAAF73C,A73762B2B38AA0B3,E8498450BFA2403E,6A0E8BFFD8F8FFF2,9AE459CFB5D004B3,9D282DF70B36AB70,000050D631A0FA5D,4673625F523DF20F,B5394105687D5D9B,B4BFEE3E31240963,202C6F518A3ABE20,CFF84153B923C874,BF0FA8F305D8EF26,679D64B34645903C,8C57EFF59C6F213C,BBEBE64C223B7857,B51FEFA4D560592A,4FE37761C6C69B69,00004E107DBE0A5A,D3C55F07CBEBC0C2,A07AB4C33B39850D,14AA89A0DD3CE995,73BC7AB87AA30C23,19CB66AB2F2E7399,D4B59AB2B5BD09EC,08E7E938778B15A5,153EF6D1D83D10F3,E856DDAAFB8C4AD3,D4E71F3EFD77D8BC,6593AEC977C611C0,00002AD46C8D466E,CCFC1B46D25A3405,6A5B2B5935510D3A,8DCC63BF4BD91029,6AB23D8D8B269C01,01247724B4388882,A36D64635562AA3D,D17343AD45DA260B,B965E6D5E9FA8076,8BB1F35546BB85C3,A819C016B5A4E36A,6B617126C03B991D,00002F1C1F8DDE41,0E90542BBF34F3AB,F5F67567A0CACC53,69D0CD449A8BD118,19507AD5DA9148F3,D5A20B56CDA7DE84,A8146A52DC58C092,149DCF423CCD4F28,788864978B872684,21B02A8741325BF4,4519DC91754F27E4,1B37385B24CFB8E3,000007FFBE33F6E6,209BE8EC8AF673A7,D75E0765E54BF1E1,17F0C62B67809064,98472024991F5E3F,F6F3F4371A4625B7,911A82BEFFD0D993,7C0ECFD8F68E004E,E1781B06DE46BFC1,7C68EAB2FBEC8ECB,1B9EE0F9665C58A6,E8FD2252C1868336,0000486FF4909A3D,A6380D6FE7DA0AA3,0AF366713E7294F0,2B28EBB6B33A5D82,C184CD4618ED1E8C,C1595B7C33DE7AAA,FA2F3AFCC6C76CE1,CC1B3AF8C9FCC82F,EE2E09070F135064,E5E0E0FF94741E69,C63821FEFC334287,612C8CB2B6347E7A,00004C3B50E20DF3,6D7A4EBD9045A401,47A68EC902BE4B3B,228B99DB92775828,8C69013E32E011CE,B1F8654770A9449C,58B82045FD3F4B5B,50D39470BE0CE291,5402631FA4CAFFA5,1F0EFB9675318AAB,DD19E47678E8C345,EE5F635237FC2F70,000000B977D5D5CB,B24138004D187E89,CF9C90BE4392FFE6,D11B424458BD9059,1F50BBD271D154F1,C3BD53109C0D540B,74DFB721C01616FE,A061879DDE253BA3,41E3D4794838F6FB,239467339678EB38,48AC2C4713E34474,2E783984FAFBE8A7,00006123502A151A,F4D7ACA48CF96539,6D1DE49FB5CA7813,019DB9FCB82E2626,057EF4C54945CFFC,C4CF8FCD76C54219,90B33F722115957F,37060123DAD83E8C,85CABAD029F7B173,75EB25708401DD66,4693FA52A93958C2,A683C2EB89205DBB,00006632BFA208EC,5D83B27F07DDA484,279BB8769421068D,95BB6678C03A1D37,E89B7C2ECE8B3DF1,8FBE520F32E5EA62,FCCEDA22DFFD7D58,4ED70DD9463FCF7B,203B4331AD50E7C1,F178525475348959,8077B461EC3C21BE,AB51BFD6323A7616,00006C893A72DCCB,73300BD614925824,56F981B2AA590A8E,0F3EF57DE8D1BEE8,928A0BF2ADEDE49D,A648B6444F0273C6,1DA572EEA99C2627,49B82C04799E1923,1AE260CC2C310DA8,90910ABE2CEF4B60,1F19E1699B88494C,636F8B28BD5B1DE3,00001A28E058D75F,CA3E3361B87FA17F,7C171A9EA24250BC,B3BCD29E9E08ADBD,10FAA53992ACEC82,9DBBEBAE4B976101,799711BA612D10F2,C6CCB8517FB659AD,0E1FC9DAB631A6CD,98B89EEA2B4F3BFC,4B066B153FC0C760,895254C9379CB7A7,0000197C46E4FC56,53994EF729241707,D529374D7A9904BB,3F936FB0C085A0A5,C04385DA81F3E6C9,143BB916FD8F8EDA,D5024AB298274A3D,20DACD39AF58E0B6,1BC27DCDF53C77B8,A09DFE5EB0EB824A,64D54C6377DBF3F5,D51C6948EE943F94,00005A3F800BE86A,CD85A5CF6B6599A1,67B1FDFF27F06D2F,877DB77DAE7EFF41,39FC7A63E6B26524,A178FF8A0259C434,E3A8BBD6174CA574,85530B3E7F64BE09,1810C365DE92FA3E,3E80D30D619D41A7,DBA8EEFE483E75A8,B3DE0E32C7358ABC,000061B5D5627DD9,BF0A90E936E1309E,087E54922A8EB26C,E2A63C6887E5FCB7,D5C8D041FEF40CC5,F171277898C8E29D,00F0A1A46C6E400C,D1738E5B76FEB0C1,C4A01B6F62E5CADF,96217AD098CAC94D,5387A4708A29AF0A,CE802CA0BCC64B1A,0000477E9512C124,30CE38DBC0BB5094,CE37A1179263F6E6,EF6C2435FA2DA713,AA2E0EF58B2DC593,E01DDBEE598A8E77,824489317D07C686,7797A27416685894,28750D058ADA8E5A,6B99677F0D403D72,5B52D48AD85958B1,B5864D404B06F2AE,000032A1F041C293,CDB5C81853EF9B7E,D5CEB17FDBA14E50,A8193963900D1DCB,AB85F9213DD4FE00,57B1DC63A8E05E4A,0B6EC191BCC96C55,15A279CE94AEF8DB,C4C1CF7AEF43708D,9B522E6D48F1CA2D,E9783DA4028B300A,F158B4E7A3911AD6,000019103636A6B6,96BCE253A838373B,77F18D9A5E742989,268E9D9A6FD6647E,5200BAE7C03674CA,A9F7F0292FF30104,8BE26CA3CB2A1BDE,B288DD754597047E,2BFBA4DCF7F759B0,96F5C4C46D371330,892E6F587E51C75C,3D94AD13338E0826,000028D39B735AED,08D3EB72C2D8E4FA,C8E0D8C64EFE9945,AE1A3937C8FD5740,35659055CD2A5439,C19EC8028996D3A6,BC2CDBF47A1C396D,C22DB2A4EB2751C3,4E95DFC2F727739E,ECC99331BF227B4D,8486AB4F92DFA3AC,CA1D546BCC58FA9A,000028276829DC92,A8B2ED7698A43F0F,A1E290B1E49B6B5C,EE5CF0690923D4F9,680E648BC0E02A31,42F4793F3A4C71F8,12A7AE3FC8A0C4BF,61458568B1F344A8,2C170C4A82F10EE1,650C5ECBD630BDF7,2967180785E333F0,CE69D6548CB92F61,00001180153FCB49,7AF57A7183C0396F,147FDC431FB6DF12,7C44416B07820AE0,3A4A2E0A15BC4A5D,B41F153E7511034E,D24344BC47A524B8,6661D346BBA225E3,1CC6F17489D10F27,AEA5FC3FD07DF176,3272F9A6116A628F,92BC272203CB7776,0000431F1764115A,CEADD88FC7653680,7B47A978C6762D0D,C75AF284FF67C02D,C74E754E0507DDA3,7EC35814EA641311,04BC2711CD648981,5C226C85C1F7B9E6,F4A4CE28F92DFEEA,9C0560216C245649,F4F5BD0FDCC2E1EA,63A10D7BFEC84918,00006A557A04FD9A,98438249CDE37496,0EC97EB1B56062D9,53A8151A61D498FC,6A5E1C1120A0E6B8,6C625B5B3C2C6C32,78C66A8722F00059,739F1F49C8B5D539,F8D9D855E68D0AC4,3C157382C3117394,42270DFBE3514D3D,D0B4A9BD408E6215,00005434852EC714,B3EB7DE10C4DDAA3,757944A1A5F84E45,F7C1A9361C258B4E,5C1A8EDD9FD56775,9B602B26399C35C1,75031179EEA07F36,563D67D46E2D20C9,1891DA55EB04DADF,EB36887EF626889B,2B19585CD4553EBD,7B748942FCCF58C5,00003BDFAB0D663F,AA4C2D2595491FF8,E7B474FB224231D3,4604B3ACCB7BB04D,698D6D014C410C76,5BED7B73E3EB2993,9E6FBC00303084EB,C9304AC38FD9F372,B66A6B7C6D2A4D8A,23DFCB734D33A665,8E547BDF363C5A7B,898D88990DA8A2AC,00004EC8C6A74D59,F4CFA5B8BE4CB96B,A9446B6B85CAE9E8,2E7A095CD6B6F3D3,DC45FD363372E838,4F57DA10D9EF8AAF,AE6E368A7EA1E4DF,DAFE130DF4CCC988,7AB4BDC6477A7B70,279E505ED2995EDA,FCA10CB445911E68,0E0B2061FBAD3DED,000065E0EAA59538,A73181966E84879A,421B189D3E6BC69C,56BA9935004440D2,130A5FDD38356EF8,F0A39F5646CB3ED8,FFB8FBE977D60861,6FB40987EFA9664B,B2502BFAAE0B5C47,A3C7E84E82B586B9,45961832F0DFF8DD,BF05E2D118053BFF,000027A40D45322F,B19F78DCF5A70B1A,4877E5E22495AB1D,89B6ECB50CF1342E,3097C3538CDA92B4,F4DB47BE163B53B1,B477629484C7AFBC,446FFD2A2D7330A7,B93B73C786DF92BB,CF8A845D4D4EBFAF,515A98DA48C0F659,DD22D51C9F97743F,000044857BF6509D,79D5EDD84AB3A90E,2A0B250F5405E635,CB3CB67A0BC763D7,71EA52DC5B0E2796,8BDCF0074B8C0F8A,1AA1CEA0B9F2BB7B,3B62413175665E64,35CF29186091D97B,B24042FBE807C999,25B05CEDD84E08F0,D488812E01C61AC9,00000AE2239E1419,BE84BE45FD6AFFBE,65C0E8747DF22046,C913911476CDD23F,A1EBBA62AC145F22,C55139E106E6A1BA,015F575C9D314D0D,5EA51FA12695AD3D,C718E69BC1308AF8,F0EEE9A3A9BB2D23,807277BD681CAAF5,632EE4F68DCB008D,0000201D49E0375F,599EBBC390686517,C70C83B3EA56910F,8814049EC173A56F,6B7FAA49847753A6,D18FAAA2268EB7A6,C33E53BE10582D16,870471CCB14F2D01,4861D73E2BE2F2B3,830D8BFBFAEECD71,A3F7EF2C449D22CC,29DE18FB490E6ED3,0000097A57E6AFA7,70BA45CC540D99DA,2191287BC67DF77A,E19C8C41D24810A8,3F908944A5123CEC,05DA45C630E1BAE7,24456E52FDF84873,E75B29F08F39A357,967A1DB4781FCB40,CB8392A9C4F3E0BA,6713B7C61164220D,0C493541F9C75594,00003CC18F38164B,7BA4356A5BDB4895,5625406E46C2B790,8E410C49AA9E7881,2EBBB54452A38AC8,80A958871D8163DD,5E81702BF126B9F8,EC6426F801DD2101,2DACF11ABF852210,2D8844BC3A9DADE1,FEB9859CFBE1737C,F2AAE91DB8636B47,00000A08200D2EC0,87CF0BB4D5E7B367,B1A95E3B6E929DEF,74F7504E03519D87,91DDFB897298383E,F3D8E1BB397FA78E,2F30D071BCA01AE2,87DDA166A8F8E89D,6D51A97BDCF7D9B8,34DDFE3FA5055EA3,A31E75FF9C9C68D0,92507C8574109AEA,000039DFDC876954,9758F5E9CF2C5B98,E2967FE0379998D6,4A20D830AD892083,9247492E41FE456B,20FE33E867D9C776,1B06A98E679DBD56,E7AA6B101635594B,AC5F2B945752185A,CAF21400B584DD5F,D90C3D3322EA162F,40746A39F081C1CC,00002A3A3A06C4FF,55E7A5F32D55D023,2025B261EF077397,AD302044F80B06F8,A7BD82CA0A1D24D5,A3A74D541776E586,329FC15E6E0E99E9,48A7A2DFF3C2A0C8,4FD547697B5E1AC3,C964E6D490F31648,ADF40DC53C047EBF,9E81F5D231B15144,00000B11683999F3,1F3979403BD42231,C90FAAF63B7EEA2A,3322D8F87029FDB0,7E1F5D689229B5FB,A6CFFF6FCFF90BC2,1A9D0539B16E69CA,1EBA9E6044441E7D,2653A9DC9B31BDF8,BAAB7CC68AE62271,E478332F56051654,4323C6E33764F10E,000031E51315A157,CEE09FB5B95F19CB,EFCBCB565D931A3C,8D2389C8241FA816,1B1A5869E4BC7E50,E51D85B743A12999,FDF33827EE18F49E,6F7F2393772EF77D,88245B112E0CAEAE,913F6DDEF8484785,F649607A740C4BF7,996B0A515540B782,0000115739CDADF8,B2DF4973BC96BEBD,B785115314E95805,82C977B90F513375,CD4A8F8005FA84AC,5395BB207B109CB7,57CA437ED4BC5B54,B090D9101EE7BDAB,F35B2E8EB01E6790,AD96F52564F280F5,E0DE0BA71CD873C2,7D1026885A85E8F4,000038ACAA359069,E45C1B1F2C646C39,9D0E1341BCF3F9F5,E6F48FF46740ECC4,93E1F569262A8F3F,381FE3ED550EB80E,8FB9AA722A658A6D,5C9FB28D486BA21B,EBA7EBDF50AF2F81,5C185B818460A3B3,24680671E93C17FF,66ACEC7B50F1D42B,00002DD8F32BDFB1,C2DBD9CCF5C00362,EEED870C85BE159B,26A0ABB4D0FAF3E4,B7FC5D66BB6A4E67,E8C1A48E7BBFCAEA,7359A50EDFC1C5AA,DCA6D0A67EEFCFC7,657E3FA71406C40E,70D2433590CB2D78,AB9BCDCB6EDB7D3E,E00F6DDF504327B3,00004AE677676C39,5E90300EA2216651,196BD5CF66CB2E53,A47620C9FF41E25F,AFA9E275318573A0,9CE930681AB3902C,59DCAF29769B04E1,BEAB85B9177274EA,20ACBEB98E19A28C,B5CB8E94967EAE38,54D6A60032CB24CA,5247FAFFFCDEB656,00006E1D2A2EA320,2B7CD5AA8F6AB7B9,136CC921138EA81D,5ECE844B527D013E,11555329899185AA,789602E60DA970AE,27A41DD00033AF0D,B6B5FB78C32B868E,BD0874CFF3594786,248D6E87B1C62EA2,3299C132FBE48B6B,D79A6EA6A65DEBCB,0000177E2FDB95F1,E38A0EA412ED40C6,C793BB80FFF384B5,55076DB8D6DB2C1C,6B21116C4C965BD0,20C79FE5AE699501,52500EC8AD08A19A,D0FBE674A894D08D,FACFFD6354E216D6,BF41FC0592038293,5950B6D05D59D76F,03F435AC043925DC,00004A7601E04E1D,3B6CF46E4683D07C,DF0CDEE030D2AB5D,9819FD9E61199229,13CF6A5B4C3DC3BC,F6538BD3EF80A78C,323D73F8EEBA6B35,B384803DCB4D113B,E3D6BB55CF50FDAB,B84AC919BE0A285D,22DBD5469DFB32AA,6447C269E72690A8,000041AA40CFE372,43758594F5FF32A2,D0B496CC9EA87A9C,A6FF742145FEA5F5,B9BE7DA1E332B809,168D106EA7BCE40E,ADE835C18BA8DB66,2A0216B4CC44EF4A,3C817F611FC73F3D,D2AF9F57E70D46B5,0D184046195A309D,833D6D8D5C16343C,000063EDDBA51A1F,B6B33F57E8E12DCC,AF85D12762910809,689F3D3B4B76C199,FCA5D5378D995EB0,AAF049FD563684E9,266D98AD7DEFC413,D7656CE7170C7C96,50B3BB50DBCE95B3,EA130AA3F3A86889,D55CC404B4C85AB7,3F0331E0CD3BA735,00006CF86116D1C8,1F56297A97D87C53,E6B8F05515054846,7D86EF2370BAF2FE,0B424DE1D71D13DD,5DFF03EA630D7268,7534583D6F542A6A,8D76FEEB3FA48C10,BBB58FAD9527FFD7,31E86F697EE080A7,8C11CEF94B57AD77,234DCC106B285E06,00005ACF9EDD539D,6A68918D7012B1B0,196D1597935AB5C9,EA78F8B0700195C7,EE29756732CEE142,9966124808D87040,2B30BFDC20F965A2,E280DC091A1AF433,014F9F77655809F3,FF217E35F4E4EDBE,CD4F4A31C061DD59,D6F80EA1EA4437D3,000020CBDBFCAC4D,31CF41B5AA1ABD1E,4AC82719BA42FDBB,4E6C75230EE52EE6,070E051F0573EC21,B1C6CB7AB140A013,77A61B03E646FB60,E477BEBB7EB8E74A,9DB232C027E8F409,9C0A243F8F1B66E3,39694612193C6EBF,1557E85AC76CCB97,000056E2E1F157E5,7C4F6B65467412E9,764A3141A1DD7455,6D0CDB60C9516127,013C21B52ED0456C,5927416E17CDC49E,6BC8DA767C7B639E,F84B7B28D38135E2,B98DF59ED491CF49,3136B3498CA2CDFC,6D059FF732863AB3,71F617BB136D8C01,0000204348971999,A7E43F752E068C89,8074B3B08B9AAD04,FD884C6A51952674,F34E40B1EDAA1ECE,B5A70BD9FC0B713D,CA4FB2C4E5282446,F1A258BBB7345BF4,E2F547AF8C55B074,B2C7CDECF5E9A8DA,3451F0337DB0A766,A34AD863F83B5570,00002FFE135F5AB4,98DB4B93395E7F25,5172079601B1FEA6,951406CA6E42B045,F3C47E01F439B25A,A33E22CF8CA5E7AA,26C40655D9A4C761,B9373935880B5302,0197D664747A73BC,0A9886FD51730930,5E17DBC553999E96,2B70E02ED94DFE24,000015D95AB5C571,0089F9CFD1C68672,81F55805AC82A3D6,757E8FAF47B9F523,1BE161B7B5EAD06F,D50329F3406D6B44,20A79719AC18BC6C,E101F8DE37A81607,7EE63E2A8BA2FC3C,522098050A544D7A,8A343FA95013683A,2858F221584DB510,000045DAD5B4BDF7,661749E4237C6134,187B0A38607EAF8F,84C3DE4363A1DAFE,A87E13AAA5126D15,BC5128306D281747,DF66AD0BC71372F1,96EF7048D70A9D68,4A24F0018DE529A5,4CF7DBFA1FC56E0E,C2B83A99110A060B,82B7DB9C6B8350CE,000024FFE4A440D2,33DB0CC2088EE715,679BD351DBE9E41F,BC033F0F1B0B0372,C78F36D6623C0EE1,480B881C834567AE,FEEB435869BC79E3,7973A517ABC0AFD2,ECC8E86A1C72F9E8,6E17CB5B24DA08C6,92EB6F5C55BD1BC6,8F071A5F5E41FEB4,000059466FFF9245,D8E22D309BF704D9,2E746CBF6A24AB73,34593540B7390F71,D0D24838A5D3D6A8,4E0DC647B33A9F46,2DEF06242DDF8594,01CB34E6E89717AF,9501E9F43F99CA5A,33DF8EEE1BC6617B,D8328F50618B4D22,A28D6EDF24EF913D,0000019283D5BB27,94B20C8095D5F7AB,B3D0308A09E04165,EB692703C633DE26,FFE3E71D00676C13,DD8B3F03D9F7108F,F22C967C27000B4B,047B65875C59420A,40DB13D997044B2A,FA6594F20237C0BF,3375F391608CF0C0,EEDBE5182E7EA961,000050FA4A97C398,E2571897F226D0E9,6F9C8B7E2143B75E,4FD840FE42876892,B2402EF3E1D29622,F495AC19BBA2FFE3,40A882476A20A42E,678D7DB0FD335D5B,EE56FDE169EB2D45,0EB07CD08F15D97F,B931FAEB46049A2D,E08602BBE9D57D5C,000029A9BDBE9B34,8DA9F299B6397F5D,8F338A7409D46285,7554A77F1CDD64D5,68DE4CDCD05AAEF7,216C083D97572D3F,AC212E889BDFD20F,C80D55DF000AC01A,12B206C6D0D10F2B,BFC19790CD5F7D7B,C9B9CFA2ED3C95C1,B828867B1B6DBEDB,0000152E3F0BA88E,399E6944A888B6F9,BC5A1CF2CC723FB7,24D71667E4CE370E,8528C5D5D403950A,44BA6A49A81C0042,8BDBB344AC212C99,D2B06D0398B04E46,8504AAE521AE8670,9B252D4432D5AA6C,06D1CAEE9F0588F8,9BE4A65F654564C5,00003B24508DB713,C064C81C83D1589A,11444A44FA0B935B,A8237D4A2FA63E42,D0C4C9F77F33BEB8,9299730E9EFD929A,6DD6A8518C16C7F2,C19840B8387F5E4A,0D650A9FB846FF0F,760E48B4A9FC7B05,70326E701BC1E406,353B5CD55326B2E0,000023B3C6BCAB1B,9BF1E2B3043EE4D2,00F8BB29A95CB846,B87BB0007257EC24,77E7E426C32B95AC,63EBDA7195758604,BF6784948EF81D48,809C81E87E7F7B7F,2840B77234E0E4CC,D9876ECDA5E2955A,42CF71C6E403DFE2,A3A6A23FC8B2ECE9,000008CB777CDF55,7E2C20C44ECCE2F8,49F9F774B12253AC,72715DB8E55DB084,630F9D40A50D1EB1,F6E1D08444D323C4,A360CA498C3D0992,8CAE8C6FDEF9880B,2920CEFCE64CFF60,4E0DE3E35E428F77,282374C26B9DA584,DDFD4553AAB286F8,00002C19A98A8602,98B8621ACD4EF745,BEFBB17F1430C2DE,F3C4D2A85DAD7D69,4B1CCA8D813F175F,478A7974DFFC46AC,C57782A8CC7E9C00,533D9A7B1C734941,0701687DB2C54E5F,959CAE6C53B34810,384D6598D704836A,8354C80C84FA30AC,0000028079468072,3DD2482B3E5463BD,B6D83CEC2DDEF9B0,7209681F09143A7F,63D86DC8441257A4,F7AAD116042176A1,F5AEBBBC182E9DDF,6980703B3EB9F8C6,DB4F765EBE61F352,BA13DF4CA2A654F6,19B49A309227A7FA,581939A5BDBD4806,00003633773C0E9D,AFDC815190862F1D,F8ACB347AA60B8B7,6726FCBFC97C6E11,9DB8A81B02EC386D,A0A99C9D215EAA58,059CE7E881F2C6FC,8B3852382A483030,E37F77DBC78CA391,1E729468571B237C,37ADFB99F11C0A58,E30BCE06F5B6669D,00000006FF0D8959,C313D2D8422C7658,009968221DF52949,34EBAD3A9EC3EC9F,4480F1C58F457C78,E7FFDC3A8CC71602,74963AAF2289AE1E,5BA4365ECD4D2FEE,FE06508A0654A507,348C4D94A4CA1972,A1ABF76CDF4D3DB2,B0F03215F0BB6E2A,00003BD7DB800DFA,FC0A5946A0682E4A,12F22A1CF7F46578,B0984C8482EDF24A,38301C23797B554D,8C319BFFB06ABE61,F7F0CB23A098EC39,F0DA70C973E704F4,70DDABB722F3CF62,A92FEE8D571DB7D6,D1C6EFC625DD416F,8B2012C5052EE0AB,00004F9401396CE2,E3C477CA05CE221C,BE7EDCF171B0ACFA,B1544A0D2D3D7AFF,00FA7CDDE9A6D5C5,F655981841D7455C,DCE043F3930840B0,FAC59457E2AAC09F,549427F44662EC5C,F13B7D316E44CB18,0C033CBB809848F7,8D829ECC4D0FCF75,00002210E3A7581C,21740369B045E294,FA4BD68C7660FEDE,AD47E43152CC312C,70D64F310A2FC3C1,681ADCC230B3C47D,A11C67AEFB1F6976,24D4A38E2B964A5C,A758BD7729910ABE,3DC5B4EB5F6708C7,EB3EF3DB65EE8503,BBAD52C57D75F45E,0000109254CDDF60,CB12EB5378A9F1F9,24B1B0A83614D5FE,6F00D92EABFB4946,747C81641AB920F4,46916E20769B1147,37D19AA1D82B81D5,ABB7743A169F397C,35A9CD2403CD1814,CECDDEB7B230C004,D986318888DA8692,8DB26C4CB69D9747,00005F927D42D4FF,DA4B3A0ECE11E3F9,2EE5DE85424ADC23,49A5699940548F8F,E3972D5E1ED2635D,E24E5E0C417CECD4,B84F5A34B96E31E9,10BFA2B416CBBD6E,E34AC26243353462,63612BA1E5D784E4,BB30E99F929DD75A,456E3ED2D2685872,000066A837C6DA6C,DE173B37F324AA5B,FD6C08F68FF01329,2C663BAF1E8ACB08,67BAA60E8ADC5934,46880EB631426545,3144321DAE924F53,75429A6F384392FC,4D25CBB17613EAB5,5E4F59E1DAFE1EB6,CB928AEE0BB202DF,E32445E68D207504,000041F313FB8B72,FA1F1CCCACB5F6A1,345AD1CE025005FE,6B62A5BA5353233B,B66BFF14294C467A,53E7ABDFE0EF33EF,1BC3430326262D32,17A53D0E42D88CAF,865FDD772B70A96C,C804F3008D67153D,E7DCCD84C6DCBFE0,0AFC4E554CE8A715,000052201AF29EE6,9112913654B635D8,CB219E742F975105,7DC7680578004A9D,178F43E03BD785EA,F3A04274AD9D4B7C,93825C4D3B1A05BE,BE8E838602CEB867,E6B839DE926170C3,14798E860F10E9FA,8944B6FF3BE2B0C6,9DB59372D056EE31,000043C81DD9BFFA,AC7AF486E4B670AD,B90EC1E6C4660BCF,17299A97C7710561,F5D8A86E2184EC1E,3E878B1E74453FCC,70B670BEB8E95CC5,24272AF35475E20D,390C3F3C47040545,19793295674268EA,1C779AF061D1BA46,1143A62A3B285594,000051C359ED1E5A,DA4730129FBC2F28,CDEA88F348ADB075,4BBD3BF88C2A9286,C9F2F2B16B1D3D48,69FE0CB341F9BC2B,C304C8BDEE612A04,6813A867BBE83A2F,446EB3AE30CFABBD,29C012058D1868A1,2F96E5B9E7BA97C4,02AE28EB967622B2,00002C58FF7BF9FD,A18B79F7ED429C16,A5BF5BF5C84190D6,7E6E4D75784D1AA0,B001A15C52A99644,EA982226B551BE9E,EB8B0E4EEE85AC1B,F631C8D86CF7C192,40C525615FAC2198,084913260EAF6385,A29A5868D56CB65B,4CEB846AB9DFECDF,00002D5284DE144D,555603C811B18468,979472097499E852,E07853AC7202DEF0,6CF1BC6823F0D6F1,5BFF88DBEC4A9EE8,904A6D92D39ACF14,8B77CA650C1CF095,9888E2D9E6FB5B71,DDAD376037F32814,7D70E39894C44CA9,059DBA0EB78DA7F3,00002105B8E67FF0,E15A61741BCDFAB4,BD27300B0DBFD414,07C424D7152FB00A,2FF30502E161CFD7,37033626C808EC9B,5A74CD60972C5537,68072C5ADDAFF697,4B52DEAEC6A8A64B,7EA8727DDBFF2C5A,E11FC8D4C7874A94,ACD18F4DDFE93377,00004D6910E3AFCC,147127FDB43B9E5F,2A45E2A68483E949,76F275D9848EA513,5D1F4312569DF0E3,9501061472BC1E54,2CF4D325A782DD3C,2644F37D0D5B789D,4F90B25577B68C53,92AC3E3BD666D3DC,28808BED8F2CAC71,82F1DC342F58038E,000005CD16D2B646,19201FD67D9A7DD0,F8DDB9DB469D6C0A,BC030CFA4B2CC13B,6CF86C2003B8E79B,150B26F628BB4016,C903BFBEA3FA894F,E1BAAD28D5A06EDB,412974DBDD7BDE4A,444C5852F2F41351,227ED61CEE87F650,EA1AF5327F0B4FC2,00002E3556D6FB42,A65C7C4390247960,F33C56986DC46F86,EC80475B8B6C2FEB,6E97D0F592458548,196E139B234AB0BE,E98AA30E2139F659,4606A51D2C1826D7,998ED84E7E629919,419CC14DC38A0E5A,BC5EA2BDAC5E3C3A,86EF5988B9D527AD,000058353CD3EE5E,BBAF86481AB6E557,D734FEB03498EF7F,0F3F9EE2BB104E90,64708439298249A5,C22D93AE0DA589BC,34DB614E4D10F292,0DD3A07823303380,F16D6F1922106833,292C336F08533A46,499BA446C87859DA,942E3383A373AFBC,000030895E37CA15,A3A97FD74FB4BE62,A449D5357659F717,67F1BF86CFD95E49,2B50BAFA19B8F1AD,4CEC8DCC835AD777,5E11F7ABB5FC93EB,60831974568A696F,E7882CB98B3447BF,BA0C17D230522292,9E332371231826E7,F836BEB510A387E4,00000B99AC09CA30,F0B79E4704E4A1E5,CE745A2A191D9413,9B204C9EB3B9C827,7161CF4C5F9D3943,3467EFC8AE3BAF56,6D091B0A6664C38C,E7561E516AE1436D,4D09EDD54857C9C5,88C7EC102F358F4D,A37932AE72B2FEE9,65CA1CA2B3862E03,00003647A1C8E5A6,416F23E26F89C8B6,38249C5250928E32,7378C2FC7C297F90,32AECA1B085348D9,DE4334263BE2A031,4539D3992DF3F468,EDAD676E106D2C44,F955B837DE54C6EC,08E3F147DF65BDF6,91D732458150E48D,4A64FD997D01A4EE,00002D2A17B3645F,68ED8C74F3633819,6F4FB7E6EF36350F,FF05FB7A0DAAA5E3,70AB74C4E1F30967,A6C74BB95834991F,DB47A0624A265A3D,8AC2BD096AB01CB4,284E2873A9E655BB,C3AE1C48672DE4B2,5D01105851D048D5,0F7A5CB81BB2EC64,000065D696FAED26,3B264D05B42A2E5B,BBB90698B48FC76B,CBA6B8C932A90963,DF5047888FCEE601,C5473BD0BC05123E,D0B68476E47699EF,8CC132F0279296E0,FBBF51E4ACF46F77,1F75C546484F6280,93C7C20FD02AF7AD,B78D0FE740EC8479,00002B685C0684DD,EAD34EB348D7A4EA,80C134B696B7F908,BDF7BEC70CD29F40,542B3C9DE2A3804C,1B8091859513E524,A315785559F70761,3C472AFC18933F2B,3052A03EA206B35A,0E38D6DFA59A7C1B,D972D300BD3B9B49,683920D5FAB704F6,0000404FAC21F24F,65508961D3FCEEA8,34D0CE732C52856A,EAA8A5D731315D17,07A76AE3A1C4D6F9,7492B89D79F05AA3,5227CCDDF99480BE,304725D84226B5FC,5FD49932F8AE8DED,32D5DC902AD8475B,B6A5B544F77B15AE,11D6C0AB3654002D,00000BA6872DB439,E2D398E99E2CC076,22906C52B42BBF5D,17C40C39B9E12E3B,83AC33E2390B0814,4A66D51E8F34B88A,F1A9ECE69B79CC5F,0E440F6E29F85106,65EE04F59E50608A,2F0BFAD6E9060882,8871C4150FD9804B,2ACCF90016425EAB,000011F54A108268,81F990D0FF31B71D,DD8947DC195906F2,4F0B3D2D842F7D76,A5921170479925FB,07F7FFF1DEBD5103,84AB987C67EAA794,322D5640350D6A65,EDFE6AD29980643E,AFD69BA6884CCB5C,EE787DAF84565BEE,366BB2541BA91966,000013B898E5302D,7432C44B6394B528,9ABF8858BE49998E,F152548E21CF37C2,C8FC5C45C36CEC82,A8B910CBBE854CA9,941A88C8FB5ADA85,C37B58CCBA70A973,7C153F79B15AAE73,00F7B8D71481CC78,E5DB431B2C66058E,A37C30A464645CDA,000007C943D0B78E,E8AB1568CEF4C9B2,4A4AAC7490C8B0A2,F06B63D7845E9F7E,8A247D1B99D0058F,7FFEFDE31607F888,FC6CF639CA8CE5FF,74F6D09C3E3810A6,501A2B1B1F765202,B247189C385CB1CB,8117BC0FFE2EE5A7,1D9E707A1805C8A2,00001854B3F66538,C63E6382E9EAAE0D,D61F5C432811A69E,16C1C68A7F21FC41,AD6EE138A51B900C,037FDB4CC488156D,02E3371908C29F82,1D8FC010E62782EE,25353B0205D1FE3D,AABE3C8AEC28356C,72649AFDC5E1E37E,717E9DF977C7301C,00004AFE40347ABC,3EE3549A8682E478,811F367FC2732487,55716B6754EBE31B,C9053C79BD462B9F,2FBBB0206A92B5E9,064BA2C46D11AA8D,04A280F353826C44,043F017DB683ECFE,A313E1521E72A195,04A7E419C1B7933D,4DB7327C409E0A5D,00004CF4E8007C14,F1221458669A178C,B88F1499DF552A70,98F529C007E49EAE,6E1F56D177717583,31BCC962F62BF0D2,7E28CBC74AABA14B,BFC1421FA8653D6D,55E83258D6F4118E,E87E5A203DE6A66F,7886AE979E0E9D71,AEFE41710204EF67,00001F1738D04D4D,98B1121E2F10CFB1,4512F0679AB83956,76FA790DAE8B0F00,70DAF4C02D1F4095,204171A70B9C9774,DFE46E017406AE40,773628D8C5169643,0A69753F9A42B40D,1D73F2D407E230B0,DEB05461060AADD7,51D213E0D7A66708,00006C5DEAEF033E,CB9E5782A52DD939,5D0E33223014EEA2,03A0F5F64F030979,178D18E83888733D,38EEEDBCF53DF32A,1293D75B24ED821B,4339617FBAF6AC56,EDB270784B9E1136,EDF92C48C669F430,DBD0E8583AD02647,212DA4251F43B96E,00003FE389B56537,B68E4F9D0F42B0CC,0B0D174BFFB5F51A,9AA4B403F4D477CE,984A332F14860AED,47CBCE81590E3BC4,68F91E4DBCC47D41,52D6508B74A700C8,26A1F311F607D782,824F247D35298BFF,4501A3D934D2D67D,B327726DA66F63C7,00000DFF8EB32993,D99F8EB4880AEC35,C54F28A764DC57C1,431CF538402E3289,DE79584A7191179B,474F6442A52D420A,1E73835FF1454F59,DE9DA30881500EA0,D81A0376BAA876BE,FF918C60FA68DA2D,78008AB2900ADC02,B427BB45D1867130,0000487B6C0FF1F5,8A5199B54F32114E,8497F347CE12D6C2,5DF098EADB1CF011,5B6B72F1DE289623,8082F21761BBEBEA,236FD0745E9773FF,CDDF46480B85C52D,547E0F5D89CF5C8F,D0699433FACC1B26,3F54A7039AA571CA,8BB2C28F8E770BC0,00000CB05F711053,9F9D3D85D78C3C28,FD6388FBA3085A33,9887693F39DA6EBC,3DBC5DC19B984617,3AF56618FC50DA55,B2565C3BF4E81D57,83C36416F05D6001,2339A4CD56E5A247,02B6518E459BD3F6,80BD9177136F8834,5A6432010E9C3DE2,00006B085B03E9E3,1936D39BB9606E35,2B197AA1DDE9378C,B217652C9B675600,994B76384DC7B04B,2F7537F4CBCB468F,2F7163B10ADDF845,A32BFB3582943600,BE88E76FB1466B71,7882E6F2DEB48B34,9495144318073AD8,64DD70E4280C3168,00005ABB7A412D2B,B67AF973207CAC99,ED346ED7A30775D7,62D0957FC826B449,BBFC711B5DDB4B4D,347EBCA6D6DB4306,43805640C6981FA9,ADEA2CCC4EE9E1AA,0B75C9417389494B,0D34CF8F87CD9060,5C20FDEA9202B825,E9705470B6175B87,000067F27894E9CC,E0B765313F29B0F8,0681265A360F7F67,548A16A4E08DDF1C,1AEA49B352439738,3153DCFBCDC04735,21A03D98047DC834,45BB2ECB682EE16E,56240361E62FD05D,A486232A55A696A8,F4DDB6E78AB785AB,4E479C2CB3C901CF,00004F7B6E6EA090,09A91642AB6B1577,D476B5FE030988E4,EE4AD7E46090537B,AF418725AAF4679A,864382B8A75CD73C,B87ADE16D6DC4069,CB3A549C0237160D,DCDFFE6365768FB8,AD7B4740BE6C6F34,22CC13C6C2660BC8,EF1F605B2816D913,000062127903E279,6FDFF8C38A7A42B3,35E13BE9587EB799,70EFC545E7BB38F4,B8CE1E2A43F40FF6,29AEC5330FED4D1C,3065822B950F4D0A,2EA95518AE3C22BA,AAE0BF14E2B41E93,C04BB03B0FBC6C00,0FBD6685573DA106,3D740D23863A9EC2,000002FA600665A5,F379FA3F25C2F8BA,418B6D31D32D325F,3092B48B62B9EAA6,3D70ED7B6F202E2A,AE65067BED6416CB,5F5E05787E9577B6,0ACF2B65CCD6BF8A,B07B85DADC423A46,E16CB57A9E6A6C2C,2D2380AE113210B1,0F792F8C3A5C2E88,00000BE130B8D827,BB0F6E0DB5BD47B4,8D39AA2DC0FFBCF5,6AD60168CEF688C9,B10B111FE0B5076A,FC1F72222C062D25,8A1FAE49C0752D86,97C4F50E9576762F,8E21F439DA4FD5D4,47018B4CBAEFB6F7,8FA7EA6561011737,01A848328DC6C835,00005052A84A0D78,C6233ECADB0DB6B0,4414D62281970CBA,C6BF8697B4237779,0E632582C9797104,82629960C710E265,893E79458390AE88,00D92661F4132C42,FFA96A8E7EAF24D3,E5B7979DDBE8798E,F0E0F82A453DC800,5705B6F4AC629E39,000010366969B109,A616FD0A970790CB,6C6FC8C190BF2942,0050E3BD917068C1,681B2F67C94D6DEC,D5FDE2CC20827592,836E0260351BF2F2,E9C7821ED820717F,CACEF1F81159121A,C7F811210071F27F,AE0E76B17691B1FD,6CAA8511E6BE428A,00004C4EC1036020,CC8554EF71D161E1,68CCBAAACD9972BE,BAE78E14B2EFE36B,363C4B714EF68BD6,DE2855F8F6BF04E4,B9F96565AA5F5AD0,FD411852F7AB303F,FB97ADD362E54D5A,8520EAF421248037,318856A57BA77E9D,8989D9D5A626FD70,00003594036E74AF,4BE3891DB64699E3,0DF1967E63860318,4E1167C49101441C,DDFC8F2E0E71930B,0014A2986D740D51,5D5319A42AB665B6,87211BFA8BEEB7F0,B63D4F8C48D4560D,D47DFA84C094E6D2,A3773BCC8E7F5C3C,B6A08789A85AD770,00004FF773A6A892,C3DC33852760E01E,66A0A4861D7F0E9E,CEBF3DCC28419179,B57EC35613CF63FD,850DDB551A8C6751,A6700B4FD9048BAA,8ED4C39B04C1EE16,D41DE7EB59E663B5,859478DDD12738CF,C2F6B7D7D82995F8,4AA96D4B3CCE2B8B,0000420D73E9E44B,6F7D51F865432A19,15733819991C81C3,7EAF906C105E9005,D14A46800B1D526B,79D228519DB426C9,0CEBFBB43E781C25,2C230059E4C6D325,A8BF7465DB65E923,07144CDDBE5FE8EA,00B69DFEEAC21EFF,1CE94557E131E9E6,000061B1553A20A6,5921F9F6A79B0461,AC9BA8E6E9ECEB1E,1C40F3F61E02F19E,5948CFA12B9CB0B1,86CDC865A99AF06D,52E782B4C80E5A88,BAF2B493053CFE85,96BE64AB8F87612A,5F57160F1AA00FBA,0F1AFEA815E104F5,D652E9A07495E347,00000B8167E7594D,FEB35869EEF34496,21480F393B50AE1E,8DEB9C759912F3BA,FA1F4B5BB763E41E,352077593C8F872B,E95CFCED06D02938,CDC0C7AE939CF090,019350D2AC9AEF44,9768206ED6C7DEA7,4F3FA24870B144FB,129A453C28D157CB,000062D33127C0CC,3DEA3DFA01EEABD7,9EA91EA0E15FD30B,BD167F2777B3E629,DEEFA2373341B2E9,F5F1F3DF8BA63646,6BE9213925B38CF2,A779AC49C4B43013,7214A7DB75B9F0C3,228D3993558FB8D1,75F52A3E8EC73EA3,AF604B6D619C8CF6,00003052A53A2186,9A98C8203D6D0BC3,0D074C7994592C73,E41EE8C7B42B21B5,3C911D86C51D2CCB,708583033CCA16F1,F89ABB4A373408E1,3516A0037767C57F,7A18ECCBDAAD912E,D9411810CA96B438,EBA0F5BA22B7A189,DB6590ED957E689B,00002D5427CA5BF3,8F75C7593077B8D1,43B75CBC0A07A2ED,D30AAFDCB3E24256,98025089E0B85114,2EC74722FC02F680,7C3E61EDD5C65939,9E3486BD61F11239,8D7A569010623608,D943D0AA1550853A,40528AE325442227,0CD964DC61B1A160,00002A65523EF6DF,B6021703D669264C,8383A457C3D511EA,69405EF720233BAB,9082C3739BC39AF7,52B30092B1DA480E,0A461AA0A7A177F8,C72747838FE12C0A,9D75E5BFA4E09783,89761857F6E8D366,7789190990CC52CA,521FEA71D95E25D3,00004700BA429AE6,07B5432C7943D14C,F0B20B13C2D7C787,3D617FC2E6BBB79E,85E95442E319E0E3,6F1E3F0F3345D0EB,22B9AA97BB033F92,B6A54D5E625BA32B,44624840C20FE930,3F1FB9E2CE4DADD5,ADC5958FF3AB5E51,68A2AE55D26BE2E3,000053C06535DC4D,9B99EDAE87FFEB92,61C84CD55823DC07,D111B4201294CA27,F9C809166FE88FFB,31A0C5C9B3369607,150B28F04C9B6ACA,6624790A31CC0E3B,C8F3891E99A54444,EB9C9ADEF2837523,90BC4B012A2CC065,6C844A624DA5C21B,0000035AA107032A,8480DE299A0D07F5,AF154AFA12FC4657,3B3884CDB7C53AD0,A940553146BEB803,0A7770725C9A6BC5,67F89C06DBD1942D,978788AE5B7BA75C,9E946CEA68653D38,84BC3931CEE2A713,0B59B024BC670C08,16C21B2E668BA851,0000078599FB41F4,BC3EDE2ACC923DD5,002155D44F081C22,30835F6ACE7E1EF2,1F1D5462AF991967,F6ED5CFD2F16D250,CE029E569AE3AFC7,2D3B3AF9A4E561B9,52B3D633ED808F2B,BEB9B5B38279D3DC,1F1B0B955700E458,9177265FDCA55252,00004EDA859C5308,2945E1768A7DB8A1,6193847A1E3BA2FD,28345723045A65F7,666CEC70DE42D82C,42D47EB51F4E688A,B92F83585547A183,1695D052F0F7CEE6,A2924C9BA201E8E4,FEC3E7AF29DD8B2A,EB496C1CDE910374,0C12072A2886BFCB,00005EAF752C8470,C98FB66FED935500,71E093F93012732E,7D58FDFCC14B4E94,436893614368135F,D17F0008DE22872E,50AA46484007DB65,0CD453719285C4A5,9C9593967E1E5D10,F39A4808B3D77FC2,DCBE15809DE14A81,7BB4565AB38B3B28,000003A44DECA5C4,411DE34EFB65CFFD,6E7DB02815348855,EEEA910E57B87B7D,8F832FD36659E3BD,CA0D8250EB96E260,2F343ECC5B0C4A53,FC8A8398832B37E9,C4491E1876EC71FA,1401A1939315C43F,2C0989252CAE65B5,D4ED4B58573786F4,00000D28FD30D5A5,86D5A44EF8C87A54,7E36886B7A0F8BBD,1BB7EAEF73AC7C2D,F350D1409E8006EE,EDB3A647367B24F8,126CCA547AA23867,4BDC03EABBEA9C76,7916CEBE0F90DCDF,2415FFC28E6BD00E,0CD05E9CDE3278E8,4182515DD250693B,0000506546BC106A,2EDE731D10029149,5D2D85312C1FFFE4,0C5D7ED43C3EB40E,8E18BDECD0CC9471,E8A8707006EA34A0,59C1C2DB6C9A7AA6,972F50D162B6D188,C18819EAC5DA4BDE,8BCC39D7AF721635,D39FF31D0C48F435,E9B4390C8D0A9C94,00002175BCA6451D,04B744D92085076E,B9B1DB8A3185C39A,096CF6CDB091D222,C351BF2C1F1112DD,CD88061D147B90C3,AC0EE16C4D79B3FF,B8E96E6FB54EDA62,97D361A305143356,E8914F3F509DA219,CE1C90E23F19A9D1,AB48FB55CABC3162,000056F682B72A1C,41777688E5B51FF5,C5A478F186EE1FC3,ED3A3F6CBDA91C9A,FA99ECC7DB462A53,576F9DA5C1B15FF5,A840394AE6CB85AD,E5271A887A8C58AC,416367084471D33F,924D85EE23F1D9FD,4DD15761192EA8F1,4CAAE1899CCA4329,000013A3785EEB42,F1B5076E4C526E65,2256BEDC67F15CF1,A80FFC009BC78894,7850D0539713CDFF,BB540623EE0A94EB,E2CFFC698394A8C2,750E68FD5F2EDF64,25A3096CF01B0030,CDE8503586FFF15E,74A1BBDBBCA235BB,6C3C22BB90780394,000027A79BD4471D,810763C0F437DB86,23DF8A16FE169088,75D76BF721CDEA0B,B0C23843B7D55175,3EA9010702E0316D,76F0D44E4E503304,FDD9AB4266BCABFF,569F7D0691A0D2DB,3D9DD00643FC75A8,3835D7410338A879,D2F12FC19E49286D,00006B76F782EF46,AC04E6E771D2EA2D,035B953697AF08B4,DB4BFB1D509A43E8,5209DA58B37B9789,C7BB78D247CF1AFC,2827593F0A1C31FA,A6124B9B443CAF44,479DB41FBF9BD4CC,809E255A22B5C15A,4C402F6BD5534880,0EE1335DC8C7D203,00004B4738082DD4,70934D310CF1A4E5,149FCB59280434DA,A697AA49BB370B43,CF7256C8DA2AD963,CB0AAAB7F6235396,67E7127A27DEDB61,C6DC668CA9C9DEB1,E5301D99DC5D224E,903CF8D389472134,1141DC86B2FB2AD6,3197D45CE86E3A85,00001206A33EC3E8,463AB883B98EB04F,1DB5F4DC168C8D5E,A54FB00CFB80F7F6,62D77C8623EAAC5E,AAEEECBA8E7C5082,21FC8954633AEC87,BD8BC43602735B4A,05039A7B0A4C384F,76C0DF3042005D32,881EC99919C3459C,E63B32E2318135C6,0000219FD56C889D,50AE72E1DC5150F0,B77F06C06A198C7C,65CB4172526795B4,806EA0E781A8C175,F707D0E996CF7865,8C73C05862478F80,199BD4794C67FCDB,477DEACE8638BFE9,E3EBF4ABD60D1F6C,8F5D242022E30926,E5DDDD63A93D92EC,00001434509638CB,60C236997B5D8DE5,02C95084EC84BEF9,393CBD8A4CCF5CCE,E3C4D8814EEE62F5,AD5728B792888561,580194CA7998601D,D14E3A2CC2B8CDB0,69C02DBCD3E88CC7,CAE49D1B69967448,47FB6A30AB5D0839,D1327133401B5917,00004EB841992D72,624C367D871F1EB3,7397DB40AC44773C,EC8DAE076C6CAB18,6C8B3B5086ACEB1E,3660D67DDFE31927,8780956D7698DE5F,9F524D490825EC1C,85203B13A916E55A,56F3F8B42FA4CF24,0CDEFB22E21B904D,706BE66155B424B6,00005CF6E4041692,C1B6364557A6CEEC,0A8574FF56886C1A,84EBC5F6B173F173,BBCF665BBC0F1A07,F643C15A9C279D82,4479804122B5FB84,8B1FF09E9C6664DD,E259C1F58550E433,75D5D98B803DAAB4,0417008BD2D0561B,F87E63BAA811D1E9,00003C6EB3862751,FBC06DE4A02F5B5C,CCBB07F2FBAAC251,25930C1F1A4ECB4D,59312FE1968A09AD,278ED414C1AC23BD,A15841F71DA199F9,C1ADBEBF9CDEE8FF,54B819DAA288AB32,2E4699E86D8E7D64,B97EFA7798580BA8,599F6471072E0BF4,00005F6891106309,C992A482480673F1,4BDA4941AAFF7045,10AB4E5B42C6507B,3D0BBD171A574CF9,14547AC06F11D805,1F05A251979D1674,A59BB2967FA8E51A,C22AFD57C1CE8CE1,7064019EB95AFBA1,20CC08E82BC1EF5E,70230E0D6C9CD3C1,000023ED8C4479F1,C7503E630C33076E,6BA9DDC7B9062E32,C94BDD8260560502,5ED055E2CF588C72,91FB7616A39CE72B,52AD43518D4CEB2E,37B77711CDDCAEE1,1FA483DC20B53913,1B2EB92DAAB2771D,B07042BBFFA3920A,C87FA4C8F7800BA0,00000DA3E35D2CC7,762AE8AEDD4C614F,1CF28BCB184B654F,8008506573F70B42,D8176AB3EC3D0246,59B9BCCD90070FC6,C28F3F9D91E188A2,D17804D8F5935840,6A1509B9DB5D78D0,7538F0CA59DA4D05,F2F7A4D23AE25DE2,91DBEA03FA6FD331,00001E13F093311E,27A1CBD253B662E4,06BEAD15FF4979A1,684CBAD01BCB30B3,FBAFC58D8B607D56,AE818E0D2F7F8597,AFE47E24097B43C3,55F921C415C0D040,C11307B08E17014E,18BC6A53F6A8F221,ED579C2344A5F3DD,52A48659613DE57B,00006228E91D74F2,4F3FAA60CEDDB040,6AD915EDE8557CF7,2D78BD6CC52A7E46,21825828B2E562A1,A93F9A2CC4B69B77,5E2186D5F15CC435,7CE03236C6F2402E,71E99D1AA5159706,6F563578BDCE8790,5D9B2EC2D1D16B7B,32610E9C06A4AA6B,00004F977F97442C,B2ED1050C7DA593E,4B23BE447FB13002,112167256E455D5A,A739C3E04B1CBD37,1F1BFF57302FF163,2612B4C17F228574,733F04FC0BF46A9B,925B65BA6742DA6C,266C82F56CB7731B,B30E9B8652AB9BC2,716E8623E70635E6,0000220135292E9F,E5C62A878A08A089,34ADDC7B536F347E,526EB90F6DAEE5C8,5B8037D3CEAD6F51,D771CE6CE2A96129,97F12BF25A229922,9FA78DFE8A637543,B1F1522516C1E6D9,B339399A1F30C9EC,6FE21462A4F8C179,152CD117B40EA1DC,00003567E6CB9986,71F7247A30B6536A,4C5FEFACC7CE5BCE,9B8DE4DD30D07755,1E4B9355D3F43C70,2A3E5D575F1A7CB1,A74299936E800C7D,207C1C99C82E643A,96485B2B5FAAE940,B50D44A10EB9CBB4,5E69211590660659,D5AB6C0495ADFBB8,00006139E9108425,8F9AE0CC1D22F00E,B038E50B2E0AC69C,F19759B885EACD0C,4E0E7F7B2C6B9A2B,BE4FEB5B4BE9E3A9,8B63FE968F72E387,B7D5FC3272EBE560,4A148F36D180BF1D,A684BB6865246BAE,CE8DC073927CEC96,6B64C6F83FE384FA,000044319F3CC90F,DEF76703BDD902DD,E1C6709D9E0946E7,8647542F14194A8B,907EC22F69B1233F,67FB3736815E143B,DCEFBEF87369F843,BD5D3B5894B76FE9,D906F4A2753EEBB9,51FBD651BA528600,7815D78AC4841358,D2975C3208952C5F,00005EE1B05DFF37,33239C1CF1FCC7E3,426B71F720D3AB2A,62426BD68F799074,E473261B419104D5,5B2E8920555F1683,67491864EEA202BA,929667860034ED8E,D22045169214609D,39EE564D15F4DC89,9C7E2CD0D4AC4CD1,A748AC1A620740EE,00003A4A856579D5,AEA34D9A5078CF2A,36B849F46B757D7C,42471BA5340C3483,AE03E426154BE107,2D090DA87EF85531,6540BE09570CCEBF,5F2611AF1EF5543C,A20BC500CE88D85B,2478AAAA5466AD64,D86BB7FCED1BB5CC,508335AF13ED8A99,00004E11F56FE68D,A8AF4FB7FDA0A48C,26269D7B0326F1B7,B07244596201EAEB,E5F5711BBA1AE791,64C1BB1C62A55722,07A1EB44BED88C42,307E96944A31EFEF,2C74E54E9C184FD7,D4F925D1129FFB88,74EA335CC292A983,74DC94C81DA744C9,0000062E32FC26F5,096374DBE27B641C,60D7D42A75901662,86AEBEA52E29A7A3,EB5AB7D16022DB5F,0AF522E78E0E1541,6FA7F29E2255D5D8,7B3BD518847D8759,CE9CD6EF9BE9872B,DFE4A3CD7BE2E479,E8D309A55E17E06E,129C3BB82A8A8C05,000051B1CEAB73A1,A3BEF76E4D61879A,2C6F5D6552D68FCE,42518E618F0C0573,034387870D3C334B,F39A7D586ABBC490,549FC644BFC34A22,9748D9149B3B5853,21BFE5D7BB9C01A8,1CEE35363CED5123,BF020B29AFAD5D3E,DD8FAF7C5F1CF638,0000586884C1557F,04515DA0CADD432E,971277AC783A8E20,A6C9FEEE5B8DCF25,DC545BEB7BE5232D,45DC82134B4853B5,63105B577F0EE579,65C07A9D3DDD6B6B,1A20464E088B6FAF,0572B57182FB3BC0,0FFC6429AEE9DA6C,8E34F94468F2CE96,0000654B7A2F395F,6B4693B548E730D0,61F5D680601187CE,1A7954E08F2B1881,6AFAC18E9404C0E4,F9B843C654240BEF,62F7A7E6618C866F,D68C398926055632,898B37209C30EE5D,C027BC86DDA1929B,0516B795B248C820,AE4143EA07556FFB,00001A8C4AFABD08,5C01A1C47C7BF346,EB1BB0D403485C31,ADDF6CE80D23CE0A,933D32730831425B,81C4F24CC15D17CB,AD6094955966A10E,7D05EBEAFCA78B66,31A96C0445B9CD4B,CAEB8D1C580D02DD,4D0EBC042D7879A8,28B7FCF18F6D947C,0000698E89AD8434,9A8F6C53405DA0DE,63F68D8D8306769F,047D9D1CDD2844D2,CF767055C3DCAE77,2E1811B15A321412,A2FACE18F5C8F40F,15376753B0CF644D,5C84248EAC073EB2,3AE016431069CBEE,DE1C2EEBE8039F03,BACB1696D7A9DC9C,000034D45CC53F86,EA003EB6EF106181,92428D837F139F0D,FE59B19CEF5BC506,3D302721D5E09E4A,2BBECFE4832C6714,6B49CB630F0C1056,2FCA707A2EA1BF90,1B7FD5DBB6C0D8BD,E7CA6CD30120A33A,46D31BA4861BD874,B30C6A08755E1A6C,000044F9D38FDD1A,34F6EB299BE2FB52,2915A04048C07EB9,2927FCBA9E91CB83,E33A0D3E3B7A10C6,A40A0F592EF947CB,429249CC17493984,7421C2CABB3F4719,E58324D3DF3C8C5E,AE8385D81DD979DE,8B9BBA46A0522C19,00053FA590506116,0000176B179BF22D,D12C8A8973F04E62,87BFE171801C81C2,13DC64DB46CB2140,E2AE90B368BDC123,9D1DAEC12F2CF8A4,B7D8590747C4D379,B2EC3743C79BFA1C,319A37CDBA9EAB9F,BEAD577FDD2731FA,B996117A02448429,D812AA8EEC6AC0A7,00005B8080211D38,5AF556B2BBAE079E,1D135DAF33F6BBB6,17B242326A182F25,CDE18AB01B4CCA11,AFA2EDF1E3E79507,90767FA374348141,1450C73E91FFDAE1,F13AD67E17CD4A6E,AF10739A200C4130,3B8BD02E57F8AB31,E855387A33A2D0A2,00005AB3F207730B,D7AC069398D2F12A,F6C2905667D4725E,E7CFC319531CF361,0C82790CDF9A3CA1,38B2D4EC88F93103,8B8A9BFAB5BF162E,ECE9EFC38728668D,C2B3D4FCCFFD2DEC,E890B654557B8371,BFC82A1838F1DCBE,0FDC0EFEC475328F,00002B299929AF70,BF58CF298F15A42D,F19D32E7D9090C8C,31A74A08B8C951B2,4AAA60EAC8D199B5,BCB43AFD9AA3D1D9,25F4C4A3FDA26101,2C052AFA9054BF98,3510BE208D979D18,44F579782C4E337B,7FB2BCBBDE4B6F7A,A3601710BCB64163,000026E6C8E9846E,28715D92CB4948FD,A972D1CF0E6C521E,42F368A9C29FD550,18DB8FC90A7D46E9,EC95534ED85D07F1,A5725CD32EC81AEF,0B1174D110922984,9B76174E83CC03B8,C4F879835D3E3FFB,704D599C70A91164,3F6A3C5DEC6F9ED6,000006BB7B0D74EC,60F7366FB483A25C,B166CBAF548DC1DB,EDCA38D5BBF24AAB,D17946902F330DBC,993117484D746251,8E9EA1A4465B3DF8,41ADBC7EBD73B2FB,816F1F13BEF26598,50A75A6ACCF95623,F5E8B17FADC6FC5C,4F86ACE24988A286,00005ABD0D063396,658DE073A4066B67,2E3699E1D80CA35B,5EA5F51D7A04CB83,71754855C95A6A45,AA74C6758968976B,8DCFE3631EDEF810,40EC740C8E9C7556,FF31A6DF188AF0E4,CA84A0ACD8F98105,6F323DB6D1C84289,EA1C4AAB9048D256,00006D711DFF90D1,73DC26A06A4C495E,24F782A38BEF31DE,4103E3B71BA2F3F3,B358F62180F94F57,6888D349B169E712,903EAABD72099F30,30F5AB22949FC7D8,016D9EA6683D7155,2827B7B22FD304CC,315AB9FC257D4DD3,C8DDE3159ABD2D17,000027F275D3CF1F,98DB99626D2ABE95,FA7BD50DE150CD24,30079A61EE64BFC1,F9B0C0B32D769944,9B2A2C11624D109D,420EFC66703FB1A5,0718849A618B32F1,02648370B1836D56,A2B699F1E36ECDF3,4716BAC24E2ACD23,CFA03A2157C42264,0000642B1E442E25,25B088FE3471351E,547F79C16D611B78,D303C80574E3431F,A07D7D5FEDC7EDC0,612AA61DDCB14EB3,32472F5F2C965ECC,8897C5A10259B0A0,A97BB0D92FE691D3,AF1FAAD51CA61D46,CBEB37CD2864C8C4,FBFED970D357E83D,00004B03D93E4576,8FCEE66E0D5DE604,810867A21B550BE4,8CD109F1523D08DB,81A5B494E2A99CEC,DF35CF3AAB5948EC,092524D03D853729,0E483027C77B23FC,2027044F728D1FA8,CADB4059E8458B4C,5EFF9BC512D39C5F,9852638A71240984,000063214E3E3C03,544CD99252A7C8AF,280826DDDD14FE66,785926E18113F0F7,8C114D363BB901B6,18CB7C12AA84D4CC,9D65F39C18736630,6A55DB5AB0A58767,5CBA311AC6012A4B,C1EA339FAD4EE031,6D262B3F85015920,F633A977CD66849E,0000412ACB2E3AFD,D9FB4296A5427698,F172388DFF6CF740,518989504DB04102,816232DE058CD8EA,C9934BFEA57689A2,A503DA58DE4E6323,C0D8CD7E96E2E74F,2A7B3C303580F4DB,62E86F52BF813D26,540A5CAC4F968EA2,78F900B013A4AF1D,0000498DCED7CB2D,F25C44A760C49753,B6AAB8391F1756A6,49AD87CD97A12617,0457DF63FB1F2202,74709EE514F0D72C,F49074322743C8BA,51D532F9736805D4,55AA84BBC622720C,386A277B56EEE4DA,A4F6DCD54D9A20D8,2DDC9F8E6DFDE993,00002A99B967B506,B82F851234BA5004,D6A080D1D78EE0D9,842052672EEC9C83,F81E617C152E0068,7EE1E74BD614264A,553BFD8A7DC79F1C,85D97DB96B1F5FAF,030D7BFF56043EBC,44F29AD45726E181,E9042BD941454AF4,7B9C365047CE0B6A,0000114FADA09C2B,ED429CA3F760A74E,7CC1DCFD968635B2,C120BEC50A67A34E,998AFDD771FA7704,F5D11CDD3F92D297,3C28DF5E5C72F5E9,557902866AC815E4,B33533F7363EEECE,725428A08B39647E,294763EAEE3793BF,AA080E59D049B09E,00000C287A497200,34E55B77170528E4,9F1685344631A6F5,3E3C786952EF2819,81CFE5D5A0D77AE0,4C012329E6C35C47,1213D1F301B96A42,8F0027A974D1C73A,BF57AACCEB382C7A,9A2EF09641AB7686,53A2D33559831766,C0FCA27E3A5E86FB,000055A37BC9AE93,720BC30C89ED5495,219844FAC24656F4,E2D2ECD64CF3D1BF,283D35D425342E6B,7B5B2FA1BEB05AD1,0201FC6FADD08C03,6BE557C4D3FA250E,E0859289103132FD,7A125F6AEB549F8B,773C50819CCFD205,DE94D194259ED9AE,00000E5E9E112EA5,E286648D8D727FCA,1EB9FFD47E377EAF,17106038DB4875FB,532FAA677B77CAE2,CDA356B7C4FF6AC7,B52D6BAE96C02AD8,8EAC05069E7E3BED,83AE71EFDECEC6F8,CCACCEBD11E63244,701CCCCAAFA80924,CF5071F9C8F2D424,00005CE50653C411,595D6E020E7099AC,058614153AF20949,E8C35A6D4CB0B12A,3B07C9A8C3076690,BCDAC7D49BF97129,0F46A80F176CD374,A1F4F19C23AC4719,549B7BAEDF8A4449,1378D91D03039EDD,2833D849276EA279,1D0DC84E9481D78E,00003CDF8D77BDAD,A2195FD1C0DBF4BB,1FD4737319919750,F754BDD3A13FA45A,677EAA98CCB7DBDA,E5F934ED6C4A6ECF,5F93524FE22E128F,2459E0138CB43F55,44207354D83E5D75,3DD1EEE71A30CD93,5E6E5A7300F2322E,2045265F67A3232E,00004E8D6C470C70,217F42CE9A00F39B,E6A056F1591EFE45,C2DE0660EE3C5644,B1214BDB1D291390,10A844FF77AE903E,AB702C31A64EA589,A29C15CFDB13C2F8,D1F1EA9B961393DD,6D558BF549FDC813,304A458EB8F8AEA9,BAC30987B0D48D05,000052C5B6A522E1,590F24F92D47D15F,DFCDB30B1DE00A2F,B602F08CAAA158B7,785A325B11CC2A81,AF51663981B78133,24C8BF901F7EF4F9,C64A6F7C34CAC0A3,C9B47A17F37CAAC0,19781808D9271997,2CBCAE23B49E02DD,313D1E961D6DD79E,0000542CC22B0523,48748E6BA7E9076C,F31A43E770EBDCDB,3AEE37D5B58AE783,C2A4A886BF442170,FADD9C5AAF7817CD,E388F5E0C71D7969,7AC0369ABF93AA1C,D78AF9D921490698,72E4270D4EE09513,3E44A1BB9B4B1BD5,2FC486B8FDDF4BFB,00004D18DFA383FC,81E6264FE3FD3A85,F7FF673D7C31AD9D,92C1BCEFEEC5B38E,6D6920809B1E0CAA,61C7E2B38F293BC5,AE9510206D5FDD33,47B9C976546EBBE3,D8F74E41367526AB,62864D61E69D893F,29DFF5B3C9D113A8,ACB8FFB19B9DC07A,00005AC24294BC59,2FFDD1CD160BAEB7,CCA369C76C422938,B8381E50B3D46960,B683BE6871E009D2,EA18BD1A249F2010,493D61ACF3BC6BFE,57C872408A93EF43,1E375F6ABB7E2DED,E96A61166207F39E,A729A5324FC395B0,A938AD5F77B1B794,00002ECB58DDB51A,39B3EE9D3D77B472,48D5C765924C42C9,EC283DFB3FC5D477,97F2F186FDEDBC59,BE68DD7555D3A338,991BCCE94EF7024C,6D8455940BCC8588,4B07D6AE43CF45AB,FE622277117E750F,56FA152D514C566A,0D96A6DC628B6AE3,00006479FC6AB44C,2795CD2191E5D989,7480B2B5D2DDEB79,0F25999D2FA9A4A6,453A0E459C6D0F51,5E2E7ABAAE9F039E,8D514B8DE150BD1C,43AB4D2633EB861C,54ABBBF247150555,E4CF0180B7AA6121,A6CEFD18C80A78A3,CF59816B3405F05E,000050D72B7358B3,6C64BBADAF83E2C3,18EFAE2E1F954854,E3B179DA575CE6B0,78AA4BBF86B2FE4F,DF6759BC6D30362C,19BBED538F9B4EAC,7CEFA1A395DCD4AB,830CB8A24D93805D,2B4893FC943385A6,0D94E78B4E4D5865,5563F5625B3F3AF5,00005D8EA0953BB4,4F2AF16C0221E159,65CD4127D62D6531,C1AA391D5DE11C7F,4265CA19A9FA3528,7E2353BC30E236F4,3B1F3ED39184D904,3D4DEDFD19E2F14C,34DC4CE832398FEF,F1C37E6E22551927,7283BCCEB304F0A2,2980AF182340EF8F,0000080CB4F52656,8483DA4E9F4DEBC6,246FE035B4FB8B50,C42920A18D5912DA,6414CC054D77D697,C6E5D50168677C51,4F169923EF328352,E10510144AA99EFF,DFE5D1DD762A9491,E75F7F873AFDE469,023EEF3F149724DE,F6E5B61E2692E7C7,000037EE43926527,05F1343378B26467,51AA87AD7E2D61AF,C1A29B5F8CA7FA99,4BD4B35E90F1979B,CDC10B67FF664AB0,0A192D8C3C458A56,F98C81D2D29982E2,23F8ECEFD8D90623,2FA9175A10A3048B,852BF952CCB7CB9F,592B40E8B82DBA34,000058C7F198DA59,4FE902D4D91A3AD5,0CD0CC79AC492411,2F22BE23C5826976,C373B5821F084452,A47E812023158330,BD375CA459F5AC8B,403FDF3A2A0B06A7,12D05AFA35BAF282,70A64D7D04CC085C,418EC7659C994A17,32AA49D2CEB1E4C3,000012E1D5AB42C3,023CF7BFA303C4B0,B2F6C49A10F28FA6,7F7B5EB0A0D8DF8F,B50FF5B322325D95,4139A0EE28E8E360,D9491AD9A02A2675,5412B39B4F317BC0,2D5023077731A0CD,E5F5D7807A14283E,6E8E01A2B8E952A9,E45D744943FB57B3,000053A4E67974DF,92FF4E0996398702,4E148199A374EFDF,64B93E421E5698C8,AA39BA00C3A8435F,F38758F42A283BEE,844EAB5D100FC773,D272E4DEE8890255,8268C8FA7207329B,C355648E2DE49DC5,06D5AE026EC63539,644DC5CB486A406C,0000174D15E1D10F,F6C3D882E389B300,DE7A9CCFBFCCE1D4,F6C087C65030B82C,A5B56BCE59EB7311,EC083BA21EFAC788,BC7C5A1052CD1C75,4A5358B96D6951B0,800CA6AD945D2E8C,6DA9B85F099EECAD,7347B28E1527E5E6,10D3D8DB1A0CCEC4,00004ECC02E5005E,34C0BE93D0657953,F617DD5AB5C14E0D,65FC39E48CD7E45A,A13470C556615FFD,F10602E0189FB2FB,3BE31ED096D563A9,50FB19198BCDBE8D,4A3968E9F0896E9C,C534F194199D3819,C0D920E8584563E8,A9E6EFF234125175,00001AC653DB7A4E,482D6E0A7C11B304,0E1F839C44D75CFB,08A5E6ECA29E6BC7,BE480613A34F03C1,1524946CD342A7FE,C34A91758F8B9473,232CC3DCCFCAE4BC,6ABBA171ABC8CEDF,A80CBD24F0AE130B,797EF485080BA0EE,39C5D40B8612516B,00005A2A0264CDE0,DABB23E7CC2481C8,7E384FF0867FD3EF,991608E5317CDCC0,F5AEC813FE062EF4,604C82B7193EEBD8,8CBB7F53FAF0B023,3512704C3F12E195,7E476EB28DDC472E,B4F7FB19860F61BF,4F92CF59E9978419,0AFD6F63D0527898,00006CDDB1FDF0B1,28C76A90CF9FCEDB,08F932DD37D9DE82,EBE8FA8F174E79EB,D94029FBE7402FB8,F1BD77E5815C4622,54897F509BCEE878,8D58D63880B4DB66,7E3C1D82C12D610B,6EEC467B0194F4BA,C8C4A41BCAABDFCD,78E77DE93B3D2832,000055E0057DDBF5,D81852632BE45489,174E2BAC8EBE324A,DEDD58F6BA6E175C,12EE9CDA2209FB5D,7C8D36E322046020,8C53CD17AF93B1CE,E769263D8A4A1B13,B360AE387DC41E65,69BBDB76A8B5B9E8,59F94B4001267465,4879A3799445CB9C,0000261CA7E2529B,63B0928FA375AB30,8AA775374916A734,2D9F4A53F3626C5F,106CCCB7A5FFE197,2B2D50BF7E247A6C,9FF077FD654C299D,E14F701B736C97D2,D1D18AE7489678E7,8B050BA92B91C19B,9FE43BC335F41161,32DD3B7F45AD7FBC,000033239A9559F3,F61E10014C6D3E66,843CE1219F0A1C90,273E04DDD69EE8D4,3EDBEC0FCD0E6B17,44938A2298280FAD,35C78BE4B8231DEE,39731D4B8CC240E4,304812E63E38F19C,B6A3C75B147AF25B,6DBF2E28B0638282,72AFED62B6FA3F63,0000604FC3F8C003,4738EA5B343EAFF8,11BB904784E32D27,7F81D35BF06605E4,5D4B88777B4D4343,A82AD163CE88D7EF,5C46001BE90B226E,F04658DB80F7F3FB,69C88E6D42646182,DDA6D7F015D5C4DB,5DA0C4760AE450A6,F87EC919F8890199,00004EA27D636DD3,BF4EF5788C9540B7,A131595A16FB04E4,CF89EC6C950D1737,42093BDF307F5F75,5B832A0BDBE996A2,86B33FF5247A26F1,52BF915839D58F8F,CBF66141A6046C5D,E9FC0C8B9AE36C3A,3B57E4C5D1EF1F29,0EAEEC34DAEFFBD0,00004D9F538F2C40,08DF4423E6B0A970,922843948CE64C1F,18339780359DA2FB,97CDDD5B9C8DE7E9,726460682A9C07B4,1D6DF1916DB9FA7F,03420A1400A1A6F2,F30CE6918E9EDF1B,02601939D9BDB154,C3A3501902F8AF4C,6E731AC361038824,00006A3CA2062366,176CC3BF8E7920DB,516BC650FE90BBFA,EF4D8639B9F3AF5D,7E980AE7023B005C,D00A9C2F54013CFD,94FA0597AC4F9B28,A0813A0D134C7CC1,BA71DE7BA0989686,71F03E778FD13B36,C30821CDF296FBE2,2546687DA2096DAD,000003647607D41F,E0CD1799A189FE70,46A8F2159D658651,356BDABA6C2EC841,4FFCA4589CF5CD06,C60CAE6B7CEF76F6,3EE9760017C742C6,E30857D5D2EB01BE,1698D54901CCC9A8,51D322BCC206D708,D40FF2AA425BCEBF,9167F3A5A7E2C1F9,00003BD50BD68E87,16FA37BD6B28ADDA,5C9CB795BB3E9A96,99AD75FBDEB18651,B6BD31DE655FD9D2,12FFEFD4AF46C195,EE3F4F64DC6A81C4,6AA46F36E2B9A45B,4E4243C6559032F9,FC9D351B48785B65,003325C1F785E9AD,C4406B9FBD41C24D,0000115368206DC0,7368AA7D1D8769C9,82E86E298C43A5A2,E6457D4A10E5811F,F8EFCAF3C714CD41,1CEA41E6A8DA8572,6DA4BC3CFCA21973,F8485E79F8F51550,BC8FD7BA24CF3CEE,662C87078B03020C,15601E8FDDB04058,03050F2EAC6D013D,00006C129818A052,0D33A6B40FBEB038,1238B60ACEFE96DE,CB4E365DB9C6C4E7,4EA01D727C4EE850,426CF7CDE69043F3,631A17EF8DEF5D0F,8202EDAA362E0937,9CE610DE126038B0,4FADB334BB94FD74,6BD0F94730398E66,1CA9358B8CCC7DC2,00004089BEED687E,435F46A349A614A0,752FC3CB27373AE6,5AEBAE0C6FD8A411,57716D19D73FDA7E,4632DAE9F8AB2646,6799DC8B21CCAB02,53B4A57CFD52F8A7,A7FC648D90A75671,B108050C342D9280,8A2914966FEDBC40,775EAE2BC590E149,000033785B2D4DAA,A53D207FD6DE8188,EF56BF398EA028FA,765DDEC55F719325,4631A35888A98F31,75461AF63373CCDF,8E40C5596D75D445,316F9C5EEBC1C657,C64F2A6DB27CFD7D,1FB029518A5C10D4,66C57338723A1AE9,CA27B1598C4D5801,00004E11B9DE3599,00BC5C707C3789C2,7814D1FAE3551D2E,03EAF3F109DFF3CF,E274BF60C6887237,67FE232E9C21F036,034FCF60277928BA,37DEFAA3400786E9,56CB072D0B366F6D,F55AED16052489A0,E4A8BF612E319888,CE56BD67BA15A084,000015DF5A7E5E5B,A0980E199F2B9F52,D7E76CEFF4ABEE6D,3D43893FA7E684D6,E2449CDE89932C40,9AC37DBFB39D4D93,CEF82602CDD25A92,3B6D6990198E5071,B854D94579C2757F,4E33E8F807FC071A,4A91B2CC8C884752,395D53360E8CB5EC,0000237F7E0353EA,04114C68C0ADD915,88C6B4544A257471,3D5DD3F841CE9D99,7F58E3BB6A40CE56,7F5C4B737304BCFE,737D87F93018E7D9,460367BA40243352,75E94735B0485DEA,7262523FE263974C,69CC4036549D7A9D,FB538747D7836140,000010EF2924D18A,A163A54D9F4449B0,304F4C5703C20DC0,477373B16A14F63A,726B6FB4E39372ED,1FF81D7CB1127399,ECC332C7BEDD2C61,05DE3B1633F8253B,B419E8343DF14147,3054AEB694FBB727,FBC093274F8BAE47,77028F0904B6504B,00002E457898E189,D577575D516DC0B1,0311B847FDF2A457,A54AAA2C2D45ED3E,0B3AE59C03ED03A9,3549F6A2F95909A1,FFF17E7EF00141A1,EAD1AE70B9604D7A,4F2114289A84B8BE,79668645D4C4D595,8FD4A4BBA6F4DBF5,14BF68FEABB25244,00005FB0B7C7CC8F,9EE8D044AA5E9BA2,F372BE04852CCDC4,456ECB7C8D42E256,732403DEC1F472DF,F5307B49313DAB0A,BD2F977D056A1927,87E86A5235D24E6E,2A20BE0BEB408308,4BF0A81A0B42B86A,2CEAA0A62793EF07,E16DA3FE93EEB18C,0000697A7BCB5051,450C0B6A6B6551E2,E0CB7A30E266C54D,8073795287A6C54A,5E2F41CE6C95CDA7,21B458955878ACA3,27928984D3569104,EA30E5D79A4673DE,07E592E04FC008EB,749405F4766E7CAF,A4C1D6706CE9CFBA,C0FA1FF15C084B66,00001C65A1F2AE1C,9BE1607F049258A7,F1D06B413670BEA6,D43A2F231D4899E9,DABB427B3FDBB23B,D530EEB649D83753,E72FD1BEA74CB110,AC625CE244F41EC3,118BBC2134ECA83B,67FE230EA0C6FFE3,520B50172D4DC994,84C3400CDA7664F8,00000DCF968D1F4A,35D9EE0FE140E076,7B4E637127B6C4CC,18F3FA1DD6DE9A32,7EF77C04A1459B7D,B38E79DA9BB1C903,D702F22B2F0A3F9C,909DF6FE0AD51BBC,3CAB75B2F2C955E0,A1B9F2C83720C400,F71C8A5C2020CF9B,FC3C03C5170CB4DB,000058C0A9DCC131,28F3FD557676051A,A3C49A125D1389E7,DCF0620718FDDB7B,A58B0E801F4D8EBE,8A5E3CFE2F765AF2,2B2FE90E765EB91A,933DEDD8A754750D,7C2396A71F7C47E8,96FDB10C5B85C27C,C81B4B6E2AD5942E,AB2AE0241E317E0B,00002621D07842CA,523F4A99D3985730,A50CCA2EF9EDD502,10194CCC46024FD3,6968A3D1C3961244,1E9B72E10535F861,9384B4DB9813A4CE,56BBBB73892DB242,E754067E9777B404,E284807666D272A4,7703F15928C467CA,9645DA39704D362F,00000E1D96B7216D,34E37AF58DFF511F,ECFE64EE16124B5A,AAFB1BBAAD0453A4,6A0E913A93B4D44D,45673271F6746233,CF0BFED45E898BC4,21973B52D984DCE4,43230FE586664A8A,2746C53EB33A9609,3C1CD6EF93B58754,A6F10696CDC997E0,00005D7064E7B988,0F21F839ABE239B7,F2F8EB869A9EA6BA,C73873C41A7F3111,9444240FA9B64137,7BAE4E4C4CC21E67,91A07B2DF7B57AC7,D70F4305BB59E9F9,26E5B29F2A5A04A7,2CAE3910D3353D5E,99080EE0587D1824,27E14294AD11A5CD,00006B26D4CB65EF,0344B5D51C45BD89,8D4A64D45EC55CB8,A876340B412CB211,14344EE06CE8337E,23D76EA372FB955F,E99460CBB2810732,C2CB6F934F6DDF42,C6895B658187209B,9A9EC8C4BDB0055A,D8E1364B0A067384,3FD3AB69028B8002,000042190C31CED3,6DA2771E248065E8,0F7DA258CE5131C1,D3D3ACBD7FC7C29E,3655C955005C10C5,6737BADD4553F51F,57B49D3267E6D83C,5596076166C1507B,49845C95C7FEE3C3,8E624867E7B00CC4,12080D978733DD52,0A151F88840ECDF0,000041CB5DEBFBAD,EC2A67BD5D63BA58,BD4C5BF8ACF07573,F76EA1BDD7C81C14,1B1B2CDE7CCB4DCE,C460B94F17D192B7,929EC119CA98F08B,FB8A07DEE20A2796,990D88D4AF4153DF,C80D3CC5F45A32F0,EAE4F1EB5CA7762D,589CA8FF005625D5,0000313B086836AC,13C5F30793371C85,113A9773805700C5,925712984B66AF1A,AD93438FA123EE92,6AD0DFBBD73D7C05,9F6EA9656AFD8C8D,921489D89BBCFA07,8BF1F39B78992B25,658F26EABDEF19F7,E322F192AB81FF43,29A4A94043792062,000029DE09759563,9AAB607DD8E8E573,2B79C235E5E20456,A0A90F1D27584BC6,B7407A382EA4BE0B,FDBB9508139F01DB,7576793AFABBACA9,F787069C10F38176,2F4CCDF26D4B8390,5B07EA41F120CAF8,850CBD03928F4EB9,48FBBF68620B464E,000009423200442B,DFCD9B95F4B221EF,DDB3220DB633F446,C3D0D90E218A9B44,D5ABBDEACF31EEEE,1F4B6D5460DA7783,73E0D4049868CC95,5517595DE32D7FAC,05007918D62CC659,CA2BE226E7559B30,0488F98ABB6DB523,52A9B15B57308E4E,000055995B656D9C,9E6528226E6AC1A4,A6F02C4A61BBC097,3C919685A72E7F69,D0A0A5B9F7A85A53,C299A89F5984AFA4,5DF88D2BD31DD4AB,1712B5C8D35040F8,443B383AB5770EF7,F761A9BDE427DC62,4CCCCF9B491A797D,B40302466A318F4F,000025770A02AEA6,46AED03346122A47,66580EAE22DBB0BA,55EA8E51EC4DD865,099D373CEB6556C2,89D22FD597BAA71B,5531A2B105B449EF,7E13CB9046A27ADA,3E551EDB9C31536A,0E55FAF518C66D12,6B47D7934CAB1292,6560E61A5B8D980F,000012103B06E240,69452104C41C7329,982EFEABDBDA7A18,91F6239E59C06F84,1C68E4CBEBF123CE,27F2B4298AB994B4,9733F2F84099BFD1,DCBD93DF5E4C608B,BC269C3DA4048F96,685A02D407AA6E0A,1B78547DAC71BAA7,A9964734703E8F4C,00001B10FB7D6424,BFF9270811D8D0FD,D4A44BB7E63396F2,A20AFD321A9CDAE0,7B990F7D52C77755,4C1807390899E90D,D92EEDEAFC66420C,B28CE73B7BB00CC5,F285887EF29A9608,B7C62F27C649396F,E21503D0133D77A7,815FBDFEC41E1EF8,00002B425E489307,D843CAF8C5536E9D,BB5917CD84BAB0F5,6CC8599D39A73E6C,73D23B587C17B390,F40DC609E6816DA4,1DBFC538D23045A7,8E9B169BD9A01987,AD6EC69DD16CA13C,5A9D640E2F9BEE7A,6381C37D35FC0E8B,3BA1171503936946,000061C765A32513,27FB534C372915DD,322CF3DD41608FA9,3BE82053AA11A00E,AA543581ADFBE61E,204880888610EB43,4833213CD1F12AFC,45E74BB77620BEA3,131EF43203492264,27B7EEA0343EB62D,F6C1FF559E062732,A1693C2D7438FAD1,00000FDA3CE34958,78F5AE19F34F4DDF,C716171F0D5C139B,E7CC82C32F697F8C,607A9A71D6C558CA,C3E3AC0785C12262,A1BBDFC3FC79B3AF,AF6E7F5C5F2488E9,43D70F0CDA4CC2EE,4D670D15E1EDFD10,D806C69A579D42D2,6CBD49FF1CF401A7,000018F8A8798B9A,EEBE714DC9514C0A,7C6874761CAF9671,B3BE4C8F4526CE67,E2056921F95D1AB5,CCC9433F908E250F,74FAA88210DF323F,7C06FBF9332F848E,F8252AF606D48FF9,4349AE289367396A,E4A571E9C9ABCB69,E6D53D89031E56C0,000052DF2C0BA2A5,48B7A04E2DAC4DB6,B632C2D9BD47D362,CD5D037E23D1621E,BFFC4F67DBF71315,77615898FBC0B292,DBBBA6F4136839B2,46106B07F92E4975,84C885939D14D3C6,87E0C80C288A7928,25107ED19254E44E,9D96876E524B3A65,00003FD027F924F5,86742454B6654D7F,EFC66BE7F504A84E,CF5E311FE61D8FB7,6E93E08372E220CC,2477A235F661D9C9,68B9236413AFEB50,C06C7D6009124C31,3CA7B8A4D9E3D9B8,A3A6EDA9793ED4B0,7A6055D38E057176,D351549A11423774,000015D600DC9B5C,29D20BE4936E3E27,7B6360919668AE13,5CC61286D4022366,CD43114C1144923E,3BC954F0E9C54212,D6D4188CCC2A91A0,A87AD48EF5209016,9C74D61B9E0A171D,FFC4655677EBB52D,A446D175855C84B6,03897CA3C7709612,00001B7168C6FBB7,D10574109DBF5FDD,40ED1C802BC574DE,CC6A385FC771806D,A53C3FB46CCE3247,E31C83B37B6A9E8D,D79118AA13967760,EC21F107F1E28136,A5D757D09015FED2,D1F7A7A57F3F2089,6076D3CA220F6B67,8A86823A34FD7017,0000594C545859C0,456E0DF44F0D495D,38EED792E9F5F8B6,0DE6901A15D5D0C4,2F5518991B1FF5C9,9FE56EDDA3D401A5,BB5E04F488E4CA35,654538C6594C77EB,0528F2196908B503,42AE7A272EE68B65,8FADA38A20EEAF1F,DB7F9FC619345507,000059F1CED76D14,29DAD76AC58028A7,24152C70EF08DC90,08ADBE3DC7C94C06,2E9DBB8FAC85D2BD,73BF7B99116BD248,69DC42031B1FC9AC,3A7AF28020B5BF7D,77942F1442F43CA3,2BB599F7E02029DC,0C49372597EA2865,E675F54601AAF5F2,0000692896E11F29,49CE02F61E006FBD,7907D0F109276B18,6B2BD607E0850038,09FD3F1991E4A624,9FE4C1378C6019E2,461154021E73BF70,E36982A5118AF6D0,C99B9C1C18A00328,24B2D4C47B90C9A1,37F9E52822DC6981,2DBB6DCF3DA9E438,00000F2CC4EFDBA8,65E44D8075FA0052,D3CEAB965C2E85F7,76C89DF90837182D,136DBE53555C6723,B167649CB189934F,8A609558058BF923,153033200E30A39F,F055FD8897ABA154,74AAA16F8803B525,2AAA793A824F0235,24260CB820D55F1D,0000176766EA6F40,7C3FA894022645DD,7D7CE7B0FA70F04B,4D579616F34386FF,D6681FB7450AAA17,6DF83FC039004E36,58EA48F5FEB88298,85217E133F6313F7,D77E65D00E7794A7,05DC577DD11DA1B5,5D269FFC43A7D5CD,CF32964240F9E25D,0000504FD21F4365,AC83C83A5257AE37,4938645D309937F7,4599015B3893F950,D39FD26BFC18EB97,08C622BE30708E26,E3A5A779492A8E0E,BE67C859379415FA,F20C7165E88B107F,C56A06C715105581,A417B0F02417EC91,352CD20D5E30D63A,000068AF2B0F55EA,651C907CC382751D,634100F1D9D8CA7D,716174011877968D,A017A82E89EABA69,64E30186451561C1,8F8D2C72135CE9B6,AB7AC689DE5B2883,CC7BDE529BAF8093,AA290BE25D57347C,BFB8082A20EF0408,03324B80FA117742,00006C23B16BED91,8D6F1493B1C48DA3,D6476191443BDE57,29316D758A9C742A,7A4FDFB1CD79D248,BB0D485EF154C7BD,5C6FCC8CA6713531,B69840D4028C4323,72830CEBF20735B7,69F29F8757AD5C73,2629C23DB7B6773B,5AAC988942BFB213,000004486058DCD3,29D0A47CF9008C8D,1747107FA223891F,8AA280314CE27AD2,8818C050F751F6E6,F2DB03F1936316B0,5604A6E5156109BF,8B5196BD61EB3DB9,1467B5CCC91A145B,C27F5E6567E2DB4E,190BA761FCA75F92,15F3CEE63C2C4C27,00004733FAF1C00B,9E920910DF4A7F56,C49BA11657E195F6,F91E2625685A2247,5B9FA76B10FE15CC,FEEAB9704EB6C4B5,2CC7297122F33645,4734C4822C83F4AE,1C521F06BAE1863F,C0C30922D30C69BB,A6211F21BE5783CD,384B4D042D1946E7,000051C8BB6C9153,AE431E2562DC85A1,A7593526D40AA2AD,E608AA3FDA28E743,2145646136D4787B,B0BDA6647D426B86,D4493698049A5B3C,1230C3D44522DC50,24ADCEEE89CB040B,C7294CE5BC1BF8C0,002473A145DA0C71,3D816935AC6E7BE0,0000333B8999F4CF,4C5C5CDE7BDEBA3A,E909E2237360AB5B,A7D696567002461B,5A85BCD540E516C9,2BED093061B6A65E,0F3B8B769DCD51DC,181AA1D9508645CE,B7D0B0DE7964F304,9268760B62D5DAD6,05B7CE39384E3E22,C30C43B13683AF53,000037F86C8088C5,AFAE2E6B4E64A6CF,BAD9D846A48633A0,3DBAF235EDD649EB,2A74B802C941EBD8,F641CDD803D29DE3,F8D541D7FBE49494,D34A2283618512F7,A285924046E9514F,21D0A123CA929230,48873E70B09D8E80,492A64F9E3DE447E,00005C45153B1F80,8F02DBFDBCF308B2,A508F4488E48E540,F464DB46FEC20731,869DD5C25A58E89F,199D96851EDD7F01,57FAC2B447478EB4,178FF7881931D7F7,7FE9D365F7F76E8B,0B4DC1D1F1D7D205,715C13C694A84A9B,D7CD0F5691FCB8B0,00001FB81B3AF0C4,75E04E01F97CE05C,F186A4995E83941D,290C948E9303F9DA,6D5F60AB4602544C,D3F1975715CCC5C3,29A3ACF4C7D6C8D3,5E95DF462ACC16FA,E3A58BD988691252,A9EB0A5C35317D4C,70860DE5A5C6948F,B5B1FB47D2AAE0D5,00005D132187A2C7,BA9DD314E9FA282B,A2F2C7468FD36EB9,09AA43073174330B,8A7D6B08CCDA5C21,23602D4BBEC94E72,925542321BEF4045,C107617144407F8D,B2DBCA569706D17E,C1D08A69E37B7C4D,944FA223C4020AEB,18A2AE7129B0F24F,000029DC5695566D,007160635C7A61E2,908905374E211EFB,AE07C415D001FB6F,23EBC6109A4B499D,F9D0F173F55198B9,FAC65156F5D62B97,8CF2C33DDADC3876,9E6DD082C222A9A8,B24B14000F52B079,E965811D9E72B67D,A702CC70DE667329,000052C282B340F3,1503A74C2F61D4D9,71DBA559388A1020,7B0B2D93C315E542,EEE233C4B6CAF5DD,F3FB63D66A0932E7,E3441FBCBD066D63,019EF20E3D8C17AD,E9AD160B869B4E04,EF482027400421DA,71D27CB0993DB8C4,3F37E850577DC4F0,00000678F007F7D8,DAA4CBF641391F5F,383048F45D23F556,F7F1483D247B3222,779C70049DC9364A,433DD356A62DC91B,7C6DF6859FEB763D,AD2909BBCB25A0D0,56F18DE99398E9AD,428B26B40F04FBA4,2DCEC398ABCA8C12,3DC1CD3D5E084380,000054AE46D8074D,FEE85D53AE5D211A,479BAD830D5D8F57,EB47104654706D68,7F55855AA9025825,D7955A292E3B6A97,819EA95075507C06,68D3D5E3F84DE34A,A3B9AF95193BD8C3,5AB18A2C166CCF90,D95D64974748A5C6,6722054D27604C0E,000024B586C3D185,A3A580E57E825C14,3992592048C33AAF,2A2AC3A0894DC4E9,3FE0B87245CE279F,C75C7EAAF754694D,147780106549E1D1,1A1A4F3BD984B730,9C5F57FA3A6317DD,94BBFFEC578CC502,439D7DEE8CB3F0BA,5D73D92AC5376B8F,0000478ECB748298,2E5AE60436A3C9FD,4342442142672221,8A1DAFB3F82CC475,209A9E4807A2C4CC,3E5A617F79D01190,EC8B6B5A94F39619,269083EA82E5AEBB,2282E4B79675E8FA,C63A09CC57EA1854,6579D4C9C291510A,EAE44374DD698675,00002B527E6097F7,3C4D97EACB738B93,047B57465ED999CD,70A88E1BDAA2DF7D,CE3301757D2EFD0E,6A1C44E3BEBC6ED9,838088B95B625284,416337A6154CD6AE,AF516044BE0632B6,6A08C0F7837CFD73,CE821706535242BB,5409B29AB8BA82F3,00000AAA2E558CB7,E5378C7F9B5CF0B9,5F5523366BE8345F,60E09C7FD6853D32,40E8CF698036813D,519DB6D541C1941C,CFCCF51107452A1E,F7923B38136A8246,100817762BF70806,B71048AA5C59F7A8,02DE7A0E56EB91DF,4AD38E3F442CBA67,0000462FACF1C3F8,9BEF1492245A616A,C149085319A82A0A,F23BF82E7E47EF68,A29105F4E7AAFE0C,93A51D431980AEE4,2EB8A0EE98FE464C,4A8F23822A3F15FD,2E7A7E3A880FFB2A,5C170B7368CFAAB4,5097717A5EE9AB88,23012249857A28D7,0000589B157719C8,116DE6F8C4D1EF59,5CA0E3717015CDFC,C777105E746F345F,9C22C6794836EAA6,3474D3141AB756B4,74A11ADAD8188960,55D438B21DCF01F9,AA84BDA95BC56AC2,E12B978D122222BF,DDEF7F461DAA8525,57277E5BB70E82F6,00000DF5FBAFD1CE,01FF6B3308D975F7,BF3636C4E2CE117D,7512B7A53A3C108F,5E088AD33E08511D,E4620158824C3A42,7B18B31FA05BB696,981AE13FE99AB7D7,382599646614339F,3F7DCC40557F37FA,7BC74D0CA066533F,2216BB85C8064A35,00004A42112E8695,F5FC35B71AA0D17B,FA057BEBA1A2D529,089EE4AEB442FD4D,3E9A028A571E7F15,1E83B787AA5614B3,81D1EF79E82BA4E3,3D0ABDF9D1C4112E,0B39FEE2CB1D3E0A,271B88E572E00C94,715621ADEBCA2203,C23752389E9DE59F,0000539A264C0FCD,DB52FF1811894674,F4B308A4B76FF752,DE9166DA0E7BBA2A,1709DB7FECF603CA,9AD80C9B70DC25DD,10B635B49D3D122A,2E40D96B8F6A4654,49BED9E2EB18D383,AEDA26AB23888002,C2CBFF3564B7CC29,6CA322DE9FB6BEEC,00006EFDC6A521DE,3551BBEEA8926A19,91561609EB60C52C,E5609C1D05BCA117,8B881745A11C8B0E,566012BCC0CA8837,00706E1E930E071B,69EA632E896A646C,B3CB76BAEF4071A0,DBF309CE62D08EE4,BCFAA62FC92821E5,159A5319C61F4A56,00004D536C622E1A,B0F803AC30585C4B,7C670B48FE828AD0,C71A90B3390DA37E,B083CB262089C0E4,D5FEADC8F6E8B132,804C818A4A05564D,CA11033F593E800B,F1CBB1B9FC20C4FB,659ECA6D3E18C908,2B80B4DB1C9BDE0B,1B1B07CDF98328B5,000053C4E1023F48,E0C2192BAC0B3FB3,1EFEC15D85D624A9,CFBC94CE874BFD31,9B2474E8D4FD13B2,3665A0EC52772AB6,7D751F01A58B895B,CB53A279B40CF120,E9842360983E7332,E1661AE13DE5B01C,5EFD2587C0AEE9B4,6C2E91A6A4FBFF4E,000043187E92F387,05ECF409174B3C10,CD23530F52622310,C1879109F27A0ADB,7BC6F46128C95CED,5898B68BEEF97D0B,C505152316DD2E9A,7CD8E6C3332687B0,40BAB969CAF88645,907ED15FCA5EBF40,6C8C43F208627CEC,6DF53C42F81F7BFF,000035BE501EE41F,8C1E876B12DD6A51,B58EC14D12756831,6D56543077190D64,0EABACD7EF8930E1,880868115F696CC6,3AA52E35B7419B75,299F579DCA1B39B6,12D8217DE9782F51,3EBFDE9795DD27D4,0A59778155FEE262,92E20BA92E232D0A,000009276B7D062C,00A68DBF4349F582,E18ACDDD6F5717ED,D2F67815850E5F2B,EA4E698FC337400B,6946726C6AFA5977,32954D063151834C,A809569320218988,8EC8B958131ED0FB,8515EBE642B11DE3,FEFF8F734A054B92,78CFCCDBF6ED4052,00006630AED5BEB5,7ECE7D17F6F7236B,109450504DB53F80,254D33F089FDEFC3,0490781A7D8EF85C,8C9543CE429963C7,816530FDE6E817F2,5E14509341701779,1BFCCE967466C793,05EF1AA40023F422,29969E56C2C2FF0E,15DF6E521D4CAECC,00001AF3D41D4637,0450F84554F655BC,7697CDB2E3909E94,8BA0CCCE402CF038,594C6DC35D61023F,8329148633D781F9,C2CA27915EBDF6E5,B37678C23E95E554,C61FB3C25E417CF8,2918822A93E8C2F3,91F337092AE34223,B4AA9652851C59F7,000013D978244F8F,FD2DB5BC4CBF7753,B95F75AD960C6094,753AE1B3A9142C18,B99DE7A07B1AB944,1F068AAC42E0E15C,86194FAB4145A244,A50F2325F8B6240F,61E5E8470177312A,0158ADB94F250F0E,5A1842FD8EFBE6B5,53428E0B875E6315,000026BBFD840468,68D0F9A4F5C897AC,F2F6264DA5198AF6,A4091A38450174B4,D89155C3E65190CD,D86B52818CB9A4CD,43E0EA7A3945B4DD,CBC995EB95CBC74F,97F003FFE9294581,0C5A6F8F9AE7FB92,7B543795E8FBF950,6416A26342693FEA,0000474CD2F58C05,50D957DF8C37A1BD,3E6DAB141BB732DE,D12BA4DA26D5455E,3261F72EE6A90FCD,3AF0C45C26832E81,EF1D74C0E576C6A0,26B663BE31BE510F,5D428066328B0F57,5427C8AE30BC534B,AA5B1258B1883B7D,F0880AB3EB0A16CC,0000046DC6112A72,0E60FB4222839C90,0AA435E904781D32,436DCE20BB49BDE7,B2429EDC18C02240,952C6A56C5133F06,1F0B8F1E0258C600,61559E86BB014084,7C947F55992F18E4,D90402C0DC1B60A1,EAB54D65687EDBB2,07DD8230B54FE4F9,000002D16CEFEC41,5990D4FA1BE21A8E,1182F3731E0D1C26,64F8B52F83B35E61,68A692DA89EB8FD0,0026B9C5F3D88956,A41CE5069882F328,CE237010AA6D3235,E3A00FC337F659EE,9450FF978E5E32B3,DCB2B96C0A2A02A6,D6216A143157D062,000036EB45C9A2CD,D623ED9098D3B682,A43F9A19F62F91C1,8B032C1BF00EC1EF,9F9D53B3EC41FD57,3582EE31E2F39B5C,AA2006AC343F1FBD,A2AF3736FF258283,D930D019B1C836DC,F21896AFEDB54338,541F129930E36E21,1EBD375995063AA9,00000385F831DEC6,DA62C8B9246C9E00,F337CCD4E7E42DA8,A2016F498D7F6DE5,59912F0A4783A669,E0320E3030986C79,5762EBE025ED36DF,1DACC0D9BC704B2F,3A90AC298D4C604C,DC5FCED462D32962,845781FF4C4A384A,72947A8E2965536E,00004141A52341D3,84E9963428456541,FB044BD362C7A863,A5516672555D8309,D257BA743FB71D79,4A56DEC1D29C9EDA,F4F334EC8F6A33E3,AD80AAB1D630A00F,2432601353B713A5,9CC051A516B7443B,64CB3A2C5D813C04,158CCDE705B300B1,00004C15E8432A74,5A62F185C5E511BD,FBB6DCFC4E871CB7,F2B5A319DCB63868,28DAA1474F1474AA,145EB894286B672F,D8EB9307E40837F4,827372BB0AC0BAB1,B9EAA68E6C18E764,874C5F5C8B93FA88,249483DE4FA10744,B340301FDB0EC981,000011AD28279BD1,71F74FA61DD326BF,C9CBCC336E556CE3,C7D19B6D2C4660D6,0A24A661740439C5,B467C40DEEF38D8A,CE4BF41B27ACD9F1,A9C57989C6E8709D,BB63DDF9D1679C76,DA6608BBE10D94B0,F9658E14E05E6DE7,DBBA3B0FE58132A7,00001D0D582BB9DF,BB1073C72F842CEE,30F2C744EBD2A61D,33DDBB644A944C00,BB5E1366F4AD9E59,D30BA9F35295D52F,319C12188B60D0B7,C051656FD4D866AE,A29014B2328528D6,F214404D6AF265F5,8AB16B997F0A9EED,96539DF42EC6E6CE,00001A99378D95A0,12CF3963F253C50B,D3A40CFC2B7A3C6B,32BB83255CCB1924,F457D260C06F8B9B,2CC2E802DE5CBE6B,029F1A3DB2CCF39E,D5932D8976465AC0,6645F0DE114E6468,0A0FBA6FA609E0C7,A82D74D349EFB891,3B9A4D4C688F165A,000042E357A58B80,19B4879F34FBBD1F,A61150540E8CC027,7FE993DD33094111,D114DBB93A1E9929,E18471A6E830BE75,2C481812935341E8,E18EC955516D5497,95D381CE166CAC4C,7132F9511CD6A5C6,B41E2829D121D641,DA3082AA61FB619A,000010D69855DE9B,51A9E1CE99185EE8,AB846A61FAAC7AFE,1C6B652D9E7EB1F3,AF523A398F89BB49,CA36E3C5F3489208,6301D87F1A178787,7EA01F0106029CA5,564D5143454C4BED,36041279239B112E,B1E0AD80C1E05E1F,4A09243124095F70,00003348A1B1DF7E,FC3319489C6CCC96,FD14B63A46FF51EE,8561E17BF1C58E48,CB21111338EE9B27,39211FD334F456B7,568BAABF11DC64E5,A241330AE694B997,6FD62E6E6709F058,AFE988662400BA87,6C63072D745B0DAB,80A6441CB044BC34,00001238BD536769,D7593EBF71085B5D,B80017D4F082206A,43823A4BACE41611,2C46A621CC6201CF,56C2C0594D33B9C3,1F5945A6B360772B,23918ECB0CFBCFB9,EF229E91B7A08C11,BDED175FCE697130,87A691E916809B94,245BE42F8D8871C4,00005B5C5235980C,77F19623B6BB5D06,70166DCDB816EBA8,ED29E10EF067FBF3,2E6DCCC62C069328,E70E6FA017F90228,52343D8A1246358F,3ABD466524D0D13A,BD544936F9358484,1B665F904E82F813,BCAA0357169F8931,51CFD9D3054DF22B,00000D55C8926415,012BBD4AA444B359,1CDFD0A691799E95,19BE05ED89CB2F6A,C8AED6D9833E46AF,5C1E796D9F360962,6828C96697C1F814,7A1C9EE29ED99654,FA37B2874F9F1910,BC19D5504260A86C,60921D092593826F,1EF38675ADA62454,0000278DE9332A7A,4B7ED66F3A696638,9CF2D66F4099BA40,158596C1345AE814,D206B8D2F47FFB41,9056F93C08ABA0E8,0195EB56961E85DC,7F7957B5C5B17B35,7B7AFD225CE5934C,1843B184DDAE4F98,D22AB87E34E478F2,20DFBF8EC488897B,000053ABF7F47985,8E52A187C45101E2,ECEF7CB08525E185,D86200F8D3B03347,80456E83B2D03B0F,70BD76C32A4795DC,EAAEE9126630CD41,CFB5C0C7E07D1ED1,B1DAD1C53BF42D96,BC2E1CF32FAB01D7,1C5CDD0DAF868D39,05A7B67DDC183EE6,0000578D4B93B8EB,4235AB9B6B859C7B,ECF2CAD7B98DB759,898ED7771FFCABC0,C76759DD997498FE,64C13E943C4E9542,94EBFF2A156F4B1B,81ADFB44C2DECC79,E775AC51B1F3C13F,AAEE8CB6AF5A521E,9ECC58635B91F2AE,988D89E4BE7C5D2F,0000444344C7792B,ABD7460011B4F00C,532D8CB8FE601BC0,4750C65FF12009BD,4832A3EC07B9104B,70D7BBF0A2EC5787,5FEE266CFBD79D69,55DE1A4CE52757A5,678F74AD5FF2D75A,32FA630C2F5AA0B2,ADAE5CAA04FB7A00,9147AC0C466AF556,00006C36426A9113,D986CCB4B36185C5,ECBCB70DF7DA5563,2C0E160F0D77322E,F1EA2A9C2AC15748,8C6EDFD5579CA84B,724F33A220A88CC2,6811712081ECD06C,1C5219B02E529EE2,97827CEDFFB2613B,65A811E26FAB3064,0B521FB34B2B670C,000001C69763C683,7534ECB973DAC81E,883374AD5EA4CA8E,E4F1ED142E3E37D0,005F0C1E6C6F6318,83CDBE06E43C243E,322DB25AB0274E0F,85AFDE71428F0C16,3508CBE7D7BB8F66,134FFFD511736D83,06976C420C4B2D06,957AB72156719A47,00005098CB063242,308EAEF5EE9ED2DE,B79D8F08F1DE135D,BC10626FB17EE0D1,3AF0FEBE1AC8D536,9B61CDD9E8D8494B,1139396246B8D3F5,E5926529D1DCC166,5C924CD4E04C55B0,28D52F4856A6F96C,B99443EDB5C2F6BD,699995C8590F6E0B,00005CAF97B83336,1EBADC99BE94FAC7,92263F20165C292F,5BE44105A889B5F2,0BB0A27805FD8F31,43FD8365A279E655,41AFB2753DA6DC4D,7B1F8123B9DE8A0B,8B488794B61CFDA0,20EFD2464CA6CC3C,4694AB5A191B0EF4,DE0B25A1902CF156,0000034498EBC45C,A531FA22649F2B8E,901F17FC338D510E,CE949231DDB281C2,3808EFEE4AE861C1,C4EC1C5C4FC97DB1,66A45563D3385F63,41010962D9928F12,399F977191630AEA,79685AD15501B31F,459AF97C6022A776,8C3DEC3AEAC5B280,00005EDC97BE19ED,AA323A6EE25C72DE,172A2D39BC761EFC,6E4B748A82506169,60787CF73C326A76,8B488F821AED835A,38C23F817B252DB0,D116A2E74F426F5A,961B7AC3C4A5FD36,90D2E8D1D4DCC16B,66265EF14139F824,6B61EF15C597EAF4,000047C939D9DBAD,A76697B508280D02,97B2CFC5A5A928A1,6E744C7A3DE5833F,6D82AF171FB48339,766EFADBAD47BB10,249C4B976AFEB52A,746B6D9627A1E7FA,74D8B7C02B57675B,1D68EBD1E5120989,F937EEE77025AAEF,413E22D8E9826707,0000459A7D316BE9,ADC891F1BF2E283F,D151380F94AFAAF9,90CEA54B8058240F,D31162627FF83ABD,BF6127D79101ADAC,3B32F89FC99F0DDD,3AAFC377BEB19052,9DBA7DA541630C6D,B6F83C42BE800675,0344BFAAE5EB6C5A,4635B69D65118ACD,00002D9F429DB440,C01767C65BA27EB4,FD932C0EB3992542,6035159B9E4B46C5,305BC4CEDE861079,445B7EEEB56B6B1A,F62743ADB95903E4,734DE2935869D235,9527D60CCF211597,57BE7515467DACC6,C55EB0EE8B0E12FE,1DC1D55AB045B22B,00006745815FB468,6B9EBBFE3C0E9294,DEF164CF93895BCA,B2B05652BFEFAE13,239E53AB10E16F4D,C4605B833813EA89,10963B445CB25C24,21E33F4B32584FC4,14263FDF345C834F,D574F02496DC9636,B86E0C9544B9B01D,E55D70593A0A3F0F,00000DCD21027218,DCB3CDFFE1365086,F33D66F9701A5702,24069225BFD4E3D9,6A1564EF51382377,9591E25126718D0E,535263D1E9EA37B7,BD2EAB0B4949B730,415185088ED8C001,D2132B5CD8A30782,1CB090E23F0901C0,B05B41E2A43BAAF0,000000098AB65FD4,C7FA1E23FC72EEB6,25CCA39A5F344BF2,DC96E8406E251D55,56076B946036DB8C,CD6DEE72DF285EA5,70047A1756451461,35CF223210E2BFAD,5D27B46F60B94B02,04881D1B8FE1A7AC,35785C95F6F55A44,34B26CA3A0187D43,00001D85268D43DE,39EF6EDB3E4BA9F1,29AFE8433B74BA57,5CB23FCCAE62F661,174568CB30EDC558,0BA4F434B7449296,4C78EA6540DC96BA,5BBBDB9BAB7BB829,BCF7A8574262A885,0F4CB6CD2C4A9CDA,23EE33FD869B209A,A9005BD4B7DCDA04,00004F4864C93B67,09241C30F215B7A3,35D3DAA43A5FB3AC,5D349E862EB95D6E,B644602102C9244E,81E7F3F785BAD8F1,AF5DEC055E2E84C7,498CA28DF3A0954B,0B6E094EC164529D,973A3D5398A7BCD2,1162D2BFC3F2CC04,3119551F8AB7FF0F,00006F0FF26D710F,3017295B6FDCA1E4,B30AF5E2EB1F1575,20841AFA4279802A,AAAD5463DE4E0F67,4563146206E0EDB8,5BE78E34A5112B76,B09B23D1B4B28C3D,A290781E65721A57,876B64C39686C15A,043D82E66F324B04,D35483A98BD07639,00004A5370D93A1D,706703873DB06040,D4B5845063B6A206,C82074E12D80A35F,090D2BD7E17073B4,176FC4E0230776B5,43593787E3D65D82,3BFF3D197E2047A1,F0ADF60B1D2BB215,FFDD61E3C13E9740,90BF706ED4525D41,A394E7F4EA2AA2BC,000006748A81C1A2,74037E6D7E3FB13F,D6312AE4E3BB12D4,EA4E0A33E1E67D09,9E7F850EEDBC8217,34424BA50AC7EB17,5C3E69576A5357BF,797CE7F8102D6B7D,A24E8684D25B1D89,892863B48B197C2B,D9C44899B774A554,B9A6BB0B30F4E196,0000340B66BA3BF9,608D6F384026EEC6,2E8BA2AE77710ACC,533F23CCF301A9C2,4B0B422824647552,0D0A31DC93E75345,C83B304FAECB048D,AED80FCB170E7D6D,21E89161C27E8320,0FCD08BF584BD604,5DAECB466FB52285,365943578DE5865F,00001B4CAE8640E9,C0026AC91418C208,EB55BC8A69A4BDA5,293B4F00B0D12E8C,AD12B4AD6B349266,71814A8CFF930CAF,4CC2DDCD99BEB258,55703400E010E5DB,4422253A5F5FF7EF,EDFF246A8302FA10,4426EE5AD669C71A,045A142021E3DF58,0000649538174177,C1B6E80687D02DD0,7BF402E51C5F5F3B,AEB9C1AE70A6F10E,AF1123BF39088A89,8B3BD8D1E3984B59,C4B7CF348923A4F6,0BF293311FC19DFF,E5EB8567307DAB22,17F421F77E13D60C,B38B85F5979B70AC,CA080352A4373A93,000011144EA2C0E9,55C2278B268E5086,283FC28DF1B71B46,8B30C04E23F26211,23DE9E953CC8B421,F1438FA80EDE9E33,A7B7C1CD1FEA9EF5,180B4BAD689B3460,3A545FDA125070E3,19AE2D6FB9CCDE56,D01B3325DC41A05D,9BE73AA4946AD56A,00003EBD60BCB498,01312BCAA37C024C,466735A50B19E1AF,07E2673A658C766D,F67104BC49D52CF6,832183C781FEEA61,B2385C935621361F,3BDCAC04C7563A50,64EC17F553FEC3D5,32961D11854568D6,583996C4F7ABF4CA,234C9F65BA4B1EE5,0000603B9C0B8982,8C20C80A88A1303B,BB4C1C552517719A,146262A697632DF7,4CC66D4671618F9F,3F2E3730BA9E6506,5855814A47F7C94C,901F3AE33129940D,9F743493895835F8,3B9FF5B3DE741A08,297B5115D1A03EAB,B998B6221D45450A,0000029010B285F3,A200691A55F9989E,136357757731F3A9,7AC5CACF95D7161B,BDCB91FDC135CB9C,C339C748596424F9,EA7113D2337FCBDA,2EC94BC6549C4CDF,1CF1BF30038A444A,C7EFED000004B16D,6A9DFD42C7E1F1DD,CFA72877F3C5ACD0,00000119B7A22670,BB7CBBF066C4C2A5,4D3B2DE28C17D727,22CA545C17877A00,8D9B0F47709BDDB4,EF2A1AAE1272ACC9,671E16BE5D175054,0B4D9F1DD94C92AE,C236F9D56A3422AB,8501A7CAD713DC1B,C0CB22DE33C8A96E,75012DA4A55A6A0F,00005E40C272FE41,F1836941510E78A8,3130CCBD9F40E01F,7CEE0956C7862E55,6194ED1200E160C4,E47161C9B0949292,5E38B5A66D41DDFA,D2A8192E71DA801D,97A8A6493D41B9AD,D6111ADC56BAB02B,D6528552B835C5F8,8B9884728E73DA0E,00003BA125A62A3C,59B0E8124606D7E5,759D6A536D306178,33750558D9986BBD,04018F0069190D39,E7AA3CAB3BCD5D05,0CDF27BE3D17E641,5226AD5495DEDB0B,606489B06EA915F7,38DB7413AF329FBC,3E835A467C36E4D3,34826051E13AF152,00003A89AF321EDC,A90623E70E11A00E,C153EB8B8FEE9F27,F230BCFDDA0E36B4,63661FB8E94DDC78,520B9E1DACB0A3B9,9B5E31FDF3F9D530,D8229371CC0909E6,63456BBE13C4C9A6,67AB945A53734B0D,BCE69C71B1C0BCCE,5B33C8E594D83BE9,00002A23D1CB8C18,7F665FFD71405025,11A9A25FC1357A50,63E399A08D7FF9D1,4529F9F2E4582528,600F8E8FD225934F,1B1613CA69044C85,59638BFE4F6A1D2C,73ED25EDABB3EBC2,676F418D153B3EBE,4404D0A4296A090F,40C95772FC8226EE,00006B8CAF96B557,8E41C357B73EC90A,19C6D4DCB6C8CAB0,B98B511A7ACA13A6,A2EB62AA7AA3584D,0B5D0B822101D74A,BE26921C4AF835C7,5620019CA8AA47DC,686771FC89CFEE70,3EFE62CE09E22224,08B3D7029DE22116,5080D9633ADF2005,00004605E3023E08,0EA2EEF6CFF154A6,DAA2E97939917BC5,284E0E85A45E80B1,7981BE167CAB7BD9,6D47D9E5A2E9B482,5B27910641C22A6B,F6AB5B84C8043025,47F88E7E14B3EF03,A534A2226B5EE3C8,F900E42D222F0B2D,09C37BB84D055C65,00005206447FE4B2,6DEE0623DB38DAFD,3265F8E1CC42A0DD,C684248A8864D98F,3707C2366B2452CB,55A3553BB7A53AE3,5B118D237EA09065,6E0893C0AFBCF428,FE17D208C06C961E,C6C15799CA8751E8,300BB5BD22A17663,9A92B628F4CB2520,00003204055D8BE0,99EA2C45F2C4A815,F5B641443679C7C7,763B811D43583D97,F0FFBFB9303D4097,482AFB65663567AD,421F5B07AEC6D664,95D2AF2E415755B6,3B6EF4821AF2B9FC,A25A93F5875C613C,15012FF4185BA2F4,99B5380C3D5A894B,00006958251654D4,BA6A914E1EFC24CB,E05BD4B824CE037A,170C68D582AD89C8,EA0DB6852DAA12B0,56A8131FA57101A6,93F3E463B4BFBC40,08AE5A54FF71D2F6,8B921AF11951C9FB,B715F948CF016A58,7A326AC308C05D76,A6AB8AB847B4E8F8,000009570CCF6A98,620CAD7B63129464,75563FFFF5A56B03,A57A2EC0E4A4C0F7,8DDC4910C7D0A92F,0A7F2A11E725F5E7,F18A2AA5D6E24B4E,37E41B1AB2D59A2C,D89F5B50829CFF56,3671186521FCA5BE,5B7BDE65B961F595,B86A39EF2BFBC81D,00003B3142A51345,9C7203389DC849FD,E2EA19CFFC50C063,BC09FDA3FD8B7235,71E3D69DB91AECF7,F0B3D2FF0342AB99,C4C79464C91C17C8,E428257F8D159E25,EBB97FE1FAF0973F,C4AB53DB738A8F13,20F789702A74C019,0D3A890D42773884,00002E1D9DDC9CFC,F22538728970D436,657292BA1499616E,18C06D3407225671,6657507BBC029A0A,0E738AF1DC4A2544,1818C547EF7A179D,A50B495140102BEC,D269D33690B60DE9,AF5695BE4CEF230B,3090006B21B00200,2047BDEA7B5E6967,000034AC25EDDC09,EC8658F234A352C3,25F136AABCC54344,D218ECEE25E50048,6CA7AB7CD12030E1,F1EB1FAAC216F24C,1592CF9A531FBB99,131114E0974FEC1A,6BC62364587DA890,A9CE388E88A25CC7,298D7C4B6B0ABEAB,26BF39A9CA3D4E3F,0000003CA0949426,B70B42BAD8C6CC17,EBBF56CD31720251,0ABA560F30AD36E6,37C611873469B2C8,88F16826D2A24298,9C39E90849193E24,6372F61E70F39ED0,A632CFFCBFC8F6F6,BC0D7B944DA24428,2542DCDD6B5FDFE0,362F92CD4CE3AB83,00006C6B690C6165,42D69D52E553A546,FAE6CF575DD670EB,FC45D2E67144C0D3,CFE47D094FF9D449,FEC0E3A654D763DF,307AB8E26552EAF2,4AEBCEAFE8E1E8C8,1C738E2B4C80E67A,24D202B0241B2353,21882F8D10BD9C4B,1E2B5448229E54D9,000003C529334DB1,5A46A4906FC5AD46,D1F67CA223B1CD3C,78360E0A8D53E16E,F3A354ECB6E40DF9,F290DF0AED02797F,5EF1F7BE1CCF2370,702B7A0F60DF71F7,16C5190DE23A24A3,57DD887F75B4BD12,D7714E326F568B46,B00742C95D39B996,0000661D1EBDC7CF,396255B951726C56,9020DB29D4F0D52F,1F90EF05C1B613B2,4BB0794B35A49C5E,7175A135DA3C3EE6,C5F7305E94E81089,CA744C3B7862FE46,4F006E55C0917082,E7D2D4D010F12478,D72728EF86ACC212,3B2E3C3FF78D0329,00003598FC1EC584,44DEB08D588BFFA3,BCEC1B0702D131AA,4AE29A7EB4D76B45,7DF9BB2F8D362809,6DF64F71F2504958,E6C154BCE18FB79A,B365178764E35795,E0357AB8476D6F1A,F5C4F100441BD9AD,920F95F5923A15C3,2A199B88942278EA,0000283F13066553,AAF9A8E374C17E88,4DCA3CD7DF75F815,8A85EA4E75B4FFF7,957E0ACF06A443AE,C4451F7DE85918DA,4E79FB81A62F3703,891243ECDD772E71,FE8393929F6E3374,53307080BCD4B4D7,F1B8A1A3E8FBC96D,D3BB94F4BBC8017E,000051711080E538,A13C2E30534180B8,C59FA3E2128849F1,BF5444340F0BEC04,B0CE3455F1BDCFF0,EFE6F69D4FAA4277,4FEA4034F9F42F18,C3A506A84F4734D1,89C122400D576E26,B60EA14CD46D8EAE,783FCACB1949E076,78B14E3B3176029F,0000664FD856E66C,BE1DD4F4BF408EA3,92E93AD67347EDA6,7E39428DE2F00E31,A64A7F8A8CC55EBA,87F6583403D5CBE7,3FF8C8B13CF7D9AE,22679BD8177AD24B,00B8A59B9DE41175,8C05890238B59FF0,45B629F675164C7F,43F342C81F1FDDFD,00000A73595814CE,28D244D81B3C6D5C,36E8F5C31C478A2A,48A56E8DBD00DF99,B7C624BE352F64CB,20C8549B709065DF,1990F1476E65124E,76B7BDAD5F5CEBB1,71E697F68488742D,218FDF238BE042B8,0F737A590D379201,FB692AEFB2C6BD3C,00004439B383417D,86125FF66093B6E0,D4826715B4D5DCE0,FB228FC190EDF023,FEF85A7EAA0342C4,EA632C901943DAA3,506A26AB92F4065E,7F2020F911405EB1,06E0FF6227F6E028,463FC6B68165E3E4,3280FBB289641ECF,ACF10A3B2C16EB02,0000171B8F0BEBEC,83B8EAF5663EB538,E0A42DFFF5EF6EF8,50055B9CCD292692,119E5D87C5781E56,D37F576C57E74A36,C37897EB6D66A1EC,B465E19D4868E9EE,24066B7415876AC1,AED2430A30AE44BB,78BE3F42CE88FCB4,7E1BB4F8A9E2110D,000022FA957B55FC,D15E2398D08DB1BC,C6CE98A24FB641FE,1990B6D0DE598B37,CD9C16F26CA07C6B,AA5F0DCD3B14D599,C723677A5E7E3CFD,A68ECD87311BA1B0,86B2BC52BA6BA60E,0CD8C6154209CE63,6F26EA6F34C8E19E,E6C78A1AF4533C3A,00004AB3B418584E,46048807D7AA5E21,A869DB0006C779B1,D718C2E52F0505A9,03C350A744471075,E71725881060BDF4,AB12A3A6FCDA9C34,C148E7158516AB0A,2152227A0203751C,B964078F916E399E,1BD598AD5C0F322C,2F43172F4BADB268,00000F7AC1013CC2,3776C2A7BFBC7564,9E46EF1ADCB623D0,6D0174DF888F3456,BEF7B4F72A54CCC1,FA42C4FC2D931BD2,473EB8EB97868CB6,A9999E4DD6B519A8,AFB07904F7E195DE,34134FD99225A1D6,51A2654796677B3B,CFC5C1CC5E2921EC,000000FBF0CD134A,3C30A0DC8C406EF7,819D82DB9C48EAD3,3EB0DD5AD5B89447,A15AD12FB53335A6,DD20BC3A9BC910C9,980EF9D6B9593406,6C7CD371D7496A13,91EF2457AE0D8836,F3B5758FDEC43DAC,B71C0BAFF2E41B8F,404196D17C4B4AAD,0000008D352CE35F,69515E45FDE68E8A,C35BF4F0C4C4F712,EC4848CF1BB96E4F,BB5E425DA1A534AB,EEE3F683C7E96968,2EBB6330A9682DD8,C87F311E691326F7,3DE637F388D38110,2F348167B17A50E6,82EF351038CFE86E,B28B10689B440587,00006B91AF91BDBA,EA8973D999058A0B,D6B8300D0034B3E8,6187D187AE3F84A8,38CA3204D6D82424,14CDB23AC1D3A34D,3E76EC1B538518DC,2F22220B66794138,DC7AA18601BC4671,FBDD29BA796EFE01,63EC2DBC4D28F67F,3AE5C884AD0A8E97,00003F2AEACA9D9D,053BCBEA1444CAAF,8FB498FBA85DE55C,C521EF3F5B0C0363,C16F9949D6B2F4BF,252BA96630296C9D,D535111FE32694B3,6D217E83654DE44B,AA519523DEC1811F,45912B18A14C6E85,F8AC8A856E558E3D,521E90DF0D430DE7,00004CCD8B07D861,7DBDC64EA8DDB962,61F9F4B9021FC2E5,E5C22080B2AA5091,325C70081548B6CE,AF0C7FCDE267EAC9,7650C0041441A497,7053FF7D2CDF587F,571EE18921733270,10B7A358C0FA40DB,2337629446ECF664,F93B3A99D18C6B9D,00000D6088ECAD40,E4313F91FB042E34,8F867862CE2344A9,641B75BE4D79155A,20AFB8E0F92283C6,3F7854254BA1F6D9,6E0A2BB82599478F,5D51E4318D7C16AB,0E8509F2E2EE987D,24D8B4C60935386F,EF96AD97DD90C8B7,8F5114320C5907B3,000065820EB3BA83,EF617C6CC9352F9C,7961C7E5B83276BD,62808CBB3E12354B,D0ECE1D3E770E863,372A7BF2345818F0,073CB8B2EBFE7450,8B29E9A129A1D472,5189B40EFC3870B7,E53FD74A24890D72,5AA766A7C0047F94,45AFBEA81113CB80,00004C622400156A,DFF480432AC74239,AEEA98E0A8B40DD2,655A6B6F8B1B8A00,709466E8FA2E8E0D,7598B49457DD143D,1F0ADE0BBF0E54C9,18E5C664B6A70F27,E7D0A6AF3C89AA0D,30A77BD61FB7FB40,535A7FFB12E7ADF0,6B7ED4542557411E,000005BF53DADEC2,804505029FEC1135,C5F668C6CF2071B5,C52B4C51B8C78206,0B2DB59CE72958B2,3F414D9E65167F90,F5C81A85AE24B204,78A763DF01DF5E1E,CAC11B40717D9C21,C3475A6A25310A85,9CF1FD5AFF64F4DC,74295B3AFE533F58,00001C9819A14801,1C96B7DB4A274A37,1EA3F7384CC0A43F,95DA78A421AA49EA,26A8A7470E3B9395,2346A42A2AB7C1A3,2634A4475D4EDFFF,18A6D5A795B65176,471773664FF2CE86,87B75A66EFD35038,99EEB562FAF7453F,03927CB712512DA1,00005E77A360548A,80A2011A5077A61B,9A15A9FE922179BB,1616EBEB0E8ABC8D,72820A8DB6183B63,E6BCF825FB56562E,AAFFF75814116F70,0188F438104D25ED,3063FAAA8F85BCF2,F82C830AFFEA5E05,24DFAC754C3AE607,C55838144A7723E2,00002ACBF587563E,D16D640FE8C2E138,792DDD82FC5E7CB0,938AEFD54EF68C0F,46B0FA763B7EF539,1B2A29064C680056,CFA7C0D41B9F1EF3,D5B68A21AA19D2B6,8F1C635C5CACDAE1,A0B5672399802FC5,2AADD916D74423F1,DD9FAB9A51330DCE,00004935D3C63190,882527E4B9276154,7FEA9CACABF69EAD,AB1742AAB7E34072,1611DF447FBC1D93,E5B4EB1C4E550195,20B6E2B0DA4F3B01,07F6B5036BFF18CB,F8B2B96FEDE880E1,4FE16939477E118E,B68E7A281C560665,490CC8F81422990C,00005A11901177F4,27F9E4286CB10725,6BE1C79A4BDC5B3F,C2C3EE5A3181BEDB,98836B9EBF1573EE,0D7480AE02DD3CDE,8799303C7E46236A,CDAC4B35D744BC3E,1DF4CF19C01B3022,1CB6D0FE32EFCB3D,FB951623E693D631,2B6F6ECA549D9CF0,000043E72F0AFC8A,A939D89934703F91,68227D55BD139426,398FC8B7503FB061,1987030C11AFDD6B,E0FBD93216DB102B,FFAB678DBAFA10AF,43B0213ABBFFBC82,10DEB4B6271F3B80,896D732EC6D76E8B,D4F798BF3C4C2133,25E01AB9F657179B,00004CEC0633D57D,5A8FCDCAE69BA7A6,1A3A5A58DDB6CC65,96DDAE645ABDA11E,E1D10129EC270A30,08ED3D5EF39B9E0F,F27123928D71BEF2,2F78C604C796B332,617B9CE4FDBD52A7,2071E49676156389,65D58541CFDB3532,7AEE4FCB1587AE0D,000005612BF753D4,1C445EB8618E17B1,C53838E210660099,5743DB67BD05CD1A,B1433A1F50174F46,48ABD8D592AFD282,82C548969AA6344D,D250648678E17D79,FD48B8204956173F,79BC35E2EFA76919,20ED9274D024D8BE,0FC64254C5825CB4,00000400AB494291,ED876033750A348F,98A74DF5E0F0D658,E815D1271D2B1DA6,7A63105745AE6066,60F85A8B1CE28C02,FE1546138B31C76A,53AB0A1E2F99DA1B,8C5913D81D0DD7F1,777D39DDEC15A7DD,5752C78C3C4BB8E0,1096E6B4DFD3A5C9,00001A0325899736,464575CC3EED4980,B262C92D49FF15E4,DB3C1D2215593FB5,9C68AC65CEBCF76F,A9B3445A632BF3F3,12C26DCC352DA7F5,0B5551EBF39A34BE,04B13B95151D256E,10D068E95FF0BE6C,8D39EB27B0788434,5CBB54AB8D19B82A,000006F14495E7E7,6811534E49CF7534,2010F0145C23DE34,309BDF7A8D0426F0,A86DD13D4CA6FCEB,27E59EB8577694AD,70BB60E19671F853,A333C4BD2A87294F,6E96DA662091FC3F,919C0A10DF4765EE,A4E700F738C67C12,F42916E8745B4D00,000057CF1E70017B,AEB1B209A176C122,B2904D6D9CA392F4,6F07192DE3002E45,CF5EDC935B3B7F4C,36C3A319D36F094D,6BBF4A9792B3688E,8EC3416A4A93DD8A,3885E703E5BB8F0B,DA3B37F20A7CDDFD,6920D584AC1A3EF7,09B881CEA20EB5D7,00003B2BE095B1BF,9BA7B97E46370845,CC5D22984E18D6E1,30B7323196919F94,27BFAA9C81F4FAF5,6D01353D627B631B,E88F46D06E68928C,900217D951E3FBB5,4F3A8BEC2421BC3F,5F97CC8A3AEEB3D5,3D95ADA71714404B,2A99419077F86BB4,00002B22A4932980,74F24E9800889FB4,4E74051C48F8E0FE,E361EFC167C0C759,FC26BA1485AAF955,742BA396C5C60ABA,2D3F33DE3D9BFA35,4330F263FC62FB96,2F6B1BF408178731,95FC7C78BE93A0DF,9411B6AD42C9CF02,C95A7D5B88008FCE,00004A1AB2A922AE,03F7504D74FC69C7,8B057347FDB69094,4FF3290168F0A844,D19F41ECFFF2A16B,4883A453C7BDB007,A7FDF77806AEE704,7D1EE9084B95DBA7,4AC63631BF75D4E9,3C1D5AFB16AB179A,B51EEBB5DBCD4A1A,72663230EB61B4F5,000066FC8DD8117E,D101DDAC7D2A5E82,1C02231C2685F925,FA4EEF4F76B504DD,FA548376FAE4D63C,14C37240CEE1D16C,1116C0C7C78220B7,E43D1E5259633383,19F73FC23E34CDD3,7472B67DF89D78C7,AC1E092B21CDF8F5,11A189DF49B6E004,00003102816BFCA8,E4D417FC6FC1E792,743DA940A013F0D3,0C657B50C8E6A4CB,9D612EF42D5114FC,7ABDFAF7D39BC7DC,32C6785A026580FD,8FB3FC57E3BB4292,D7EE2BDAF1A8595B,F570EC253530BDA3,D44DF0D3814E3935,2FD856747D9E38D9,0000610A502F401A,BDCE24A83D0B9108,568E3801B54A252C,5FB647C34AB56E32,24B757262F4D3AB2,1C75476485BF7BD5,097AD5A13F3C8792,334241E1CCB28F9D,2B9201C13EDE9612,EE26E349147C5C9E,41C34F7FAA16592F,37FD5B177A6BDFFE,000003B3C91BF921,C74AAB4972F31186,2D0A54F407EA0743,BBFBA993299CB3B0,8E23A61C0CF4A992,F7DFB9FBB961B049,2D48CAB99609FDE6,8C7F59B6B0E2590D,8F660203041B0323,08A65B1F16F7EBB5,55E721B4A5C80027,985EE69475C3F29A,00001C54980ADF50,6506BA47E198A805,43ECFC862A17568A,872B4DB4FE6F124D,30A4FD8AAC0BDD5C,3643B22236BCA00A,74F6661FC05C262A,30963421E2A2C810,93BBEF2417C88BE0,763AAD9C98ACDF30,A5E9B7611C702BE8,E03F1C876FDC548B,00003BEB5F362977,3D0F3918ABDC7A6C,EFD3AA4D9AFFA0B6,D69C50292CCF742C,3DCB6D1A07B2DC74,9251C4CFDADBC5EE,01A2D271E4282B10,E9E72FD037DC369A,222C74D03C9D1BA3,6CF7E97412F1D2D3,8929626C3769D03C,DB2ECB40DEAD4D90,00001B708C3A8BC9,D0822C4482BE1D85,8B7361A335EB73DC,E46D6C61043362E2,6D65C00A1F5DA1A0,37B8E4AAF29B31AA,65F18AD795974190,B2C1EC0B67CB9499,2297FF262A86018E,0A7EBBDC4A3BFA3F,68B7928E0B1B76E8,E8C7317648909FBA,0000215DD3E70407,E29E9D3B594C3DA1,15B290366F9AC788,6BF0664D49843B3B,995EF37B7A4D6424,01CB057A8852D7A2,049E4E6A9BDBFE2B,20EFB1F69386E022,13D292C7AAB8B9B9,B3ED02D333CC57EB,016C7A42EE2C1492,5EE0A72D927A4861,0000101A49E01D13,105FAA7B97475B42,70CF0BC025CF72F9,08A9F27B136510E1,EFC1B654CE57E3F6,AAFF7FEF681B035C,3217146AD9BF970F,7DA2D55AE234E266,1874CF7EA0A9EB36,31BA455F8094D09C,0ED14CBF3CF88405,8D3048E8C6740B15,000005977B065A7C,1016F43584C35A0B,33170ACA09B129D1,629615710A4D86BC,ADDA0188B7B0D390,A4E187892891F27F,95A63E7F9D3839DB,4F82E745EC840827,E818D64FBB21972D,9CE5CAE114995E3F,EC65AE5579C6A494,73668ECED4AD6037,00003DC33965BA3B,90F1001EF7844509,12A41EDF4039CA70,43FD34FBE065ACC8,EEB922DC2C2C6244,0DC29B3056B6EC99,47EF7B135CCA3802,659F2656BB4DA8E0,D549248F43BC142D,92B9786372CB1C71,1777FAA860D971E9,A2EB9DC054C5B7AE,0000095F288F8494,427D0463A12C6692,0B9F35D0B15AEDC3,72911C32AA253771,279D89646C9FB7B5,3CEAC3DFCA1F2A38,27018AF3294DCD38,472175E7E697DACC,784B1B88981A18A1,D841743A86F8D8D3,F569822033AA29DB,A97D96DA37BB8BCF,000059B9562E9030,EFA075F21CFAECF6,45804159CC7CD4F4,0A10113E5F8A929D,92BAD65EDF374449,E453830B06AD448A,EA0A5177F6B2228C,41789B3EA7C8F495,1E803705DC7467DC,50C35A4147E6C022,2D04DD653780F279,C144A6DF2AFDC3C7,00001A60993A718A,319ED199D7D2DE2B,7C1D9149BB86F73E,58623C0956399816,677704777D0815C0,EA1F7BBD8415CEB9,F0C1BA61789AFC73,E7ABA8ED0D8D56AA,5493A701FF1DEF4F,10416D1B053CC5A2,EACD412147065D90,0C8CE3BEFA86BDAB,00006C135F66E626,EC36E484B4DFFAD0,81DE4E944D7B302F,00F48D21D1C01B5C,B2497EADD7D0DC63,290F519CD5E0E355,427F5413D1A8B56C,5996640DDF547794,125B0B2339D6EA90,78FE8581776D4F6E,E7A8B35AD428FD2B,D8060852924430BF,0000633AAA8AE3AA,04785D9B2C1EBCAD,7629F78B66A90E97,6FCF8A06064A6E5A,6718FC681227537C,00DDD3DF0B34ACF9,A4F50D61F95F4722,70C4A7F3091903DB,05F280A3EFFD771C,BE3CF079DFF5EFBF,E3A8D57A4970BD6B,E866F4176903B76E,000025E11674C6BB,B4DF5186D6827D64,2DEC16040D80758E,A4A01AB462FDB60F,DBF8134DD61AA6EC,0B542FA54F1C9E5B,B446408BFB774342,CF3CDC40B29C2605,878E2B3113E20F65,931B756304A26F43,6B3485DF98A5410E,19DAB3C442F1D8BD,00004885326B5265,20531174E6B7FD32,689C78C8D68701F5,F176BC15BB5C4EDA,87E12A868C381853,12644C8AFFDBE28D,2FEE9A0C1E952579,CBDA70D56621ADE5,172C89CD96982AAE,3BFA68B4430B9290,FC578CCDEE7858E7,06EF99FBD6015C58,00006264751C17FF,BC1DD6C03A4D6C73,1002E095A5DF2D0E,9B6966901D670B38,F3C85E9338831DF5,84534DC17133F28C,F4DED242564E859E,E460013F8B092F73,D5A2266080784C62,BC480360CE609419,FB7B8811092CD4B3,AE2FEF008CA1B500,00004276BC04E291,B722683E69B230D9,9256DAC2D5D6536D,88C8AE2C008D84D0,739BB617D6B33704,B1D36B44AA66C1DA,EF85A7745AEE4534,21174ED6E784D70D,846410636D4BE6A0,3C317FEE55F0284E,A96D3DE6FBA302B8,4D5AEA97F8A38719,00003906BE3CA392,57D940AB8E79438E,8DD49517E857E2D4,CDEE581D15B3FCC3,C19D969D3A5BD6AF,CCF4197EB2C0D1B2,D12A3A9081D6A8E1,E0ABB78415EC969F,E7B11DC62856B776,C8CA957C762A3F06,FF397288C48A4916,6A3270924A44745D,00003AE13B3448E8,6D268C2A6D193E0B,370EFBF3765E5D79,51D7D8862504E4E4,8DBB5FED5C8CC895,12759EA6D8D0574F,E620168ADAEE99BC,4461FB6229D64D5B,B2F43F5A90B82099,051B33077033C8F9,58BE65C8A0CFAE67,44763CC9DB147F5B,0000172BE520344F,36B697F58D6C320D,38504E082DFB9AEE,59C793DCBE7B51A9,B374210AE11DBF30,EDD02BF7B0D4B956,4691DBB0B60611A5,D40EE3963AC77847,29BFAB05D1C9EC51,59A14303983E75EA,B6EED2D4DA45BE5A,D25FB455D77EC4E0,0000206A96764883,AB87A3523B00687D,6B1163824CC5442A,4C069585443C6F9D,CD130F48CDB5B25E,4167EB7BD4E5B934,779409C0B686A20F,9EE62A2ABC2A666E,6601D2DDD1E5D8D9,872577A969CAAA93,1567A4BFCCA4A270,EB3EB0354D4C9903,000025E40ED46509,A19E53E35EB51DDE,E89A9B17C73495F6,AF81FB21BE6BABCC,EB1BAF406CD79422,CC692B4DC46900A9,A50A424558F616AD,CA9BCECD58A9B44A,CB3EC8E97BFC8A99,F8F3F5108C455C47,7D5326F853C1EB75,6C1586C43A6ADEF4,00004EF98D6099CD,AB7B76C896C516EB,183BF51FCE8F8CB0,DDEC593A0DA0A0B3,D5D8AE1C482F0AA5,7CB162769F29A49D,4628F59B6B3F3FFB,7A05E8EBD0FDFE25,3647A5E92B2FB8DD,ECD9143BB79C22D1,96BE759AFE39B3C8,ADDC03E30D4D88C6,00000FEB55062AFE,0FC734BF373AD61B,B9D363B46EB5AB46,22D5EEE7DD6027EF,295E76030305F7EB,FB5590FA15A73C4F,9B040742C7115178,3A4335CF897A8E46,45185C84F67B06EE,267B4984889FA6A8,6F124D791FA4E903,E74F79752F392F9A,00002FD8D66EB83E,A62EA2CEE6BB9E18,DBA953AD3A2C1EC9,B28243E31DA0AD31,48FC684794FE4222,CABA18451D08481B,8102C98C57C64D60,10B59A607E1011EB,EC9AB027E67B602E,470049B422F2D979,BCFAF5EE5508DA19,65E2E8BB589E937D,00001801438CEE6F,9F1653BBB5B3AD94,23AADCDCF407FDA1,7FC501C94223A6E4,AFD6184A638634C6,5BEE0F1B9A399726,98B383050AF5AC56,34DFF0113D9EE216,652D8920721CC924,EAEDD5CD971B7570,921E3647DAC17756,8318B8646C295CE2,000014DF17EF3277,C7A146E0B8FFE4C2,A80268FB105DB2D9,C0BB7FB837609A17,D4C9A6DECD23A623,9DE21BD7E370DF2C,9278424F9A6585D3,7BF8B308B8D00EE4,51A17F2A923D03FE,8328732F89D65841,478295092263810F,A84720153431640B,000024AAF9C35451,DCE11BB6B9446B57,129D7FDAA1961A8F,45B706CE73D56F23,0DA35CD342BC1179,B7110CF77427F947,0FA56B72A0598E37,E1ECE8F0D5BE0511,A481A44275202E5A,B6118BDE1FF4303C,C7B171AAA1988313,BD98C27B0AC162DD,00001F1E9A590DDB,82265178AB18C4B1,7F9B579942B3CE8B,5595C9271F76AD73,8F014BED25663884,8A2E68C45097344E,3626ACFE87255157,70FB6A5A933756C0,D450590DECF52D79,DCFA8A36BC968151,52A66A5C84CC1697,E968631352C8A7CA,00006F92D3A4B680,390EBD4B929C38EB,EFA4046DCBD40260,00D7B96513743C1E,E9FBDD1DC3F6394D,32E1819B5BECDDBD,BC4CBE4673F4ABD5,0619FE62CD35893C,2C3916B653E17B60,4DC25350844C43C7,B414235442635C6E,B915C9D097884875,00003F209DAF8785,BD4C3350D5544B75,58F07341DFD4FCF3,0A5141FD2450716C,BAD376EE0880A2AF,B9A85C7078C8CED8,759AA7DFFBB41EF6,074FDD925987FE48,F3B4DBEC9CC7B95D,3E9F009FB6084BAD,63A9C2DDB0BA196A,FA8134A2FDADEAFF,00004262D48E916D,53D15E5DD41FDF7F,F642A6A3B2A03E15,23ABCDAF82BDCA7E,0E737270B6874F33,61D4EBDD6E40F516,A3689DDC200AFB85,9CAC565F74D45490,B4CE70A6A6CBD79D,C2FE2C60E93A14C9,6DC03FD3B0CB60C7,0473B711EDC10265,00006C487F782901,9313498F1CBAF172,E6008631A7CC973F,7E72901815C3BBF3,CB5BD62FBAA904B2,C1A1A44918251E32,47D1B53EAF9CB0CE,6A0C7A701409AEC2,56989191CC9E127E,FE1301BA129AFA11,F8FD223B45F101E0,538D6AB3D60257C8,00000797C36CA6A3,0303DCD1B84F697F,4A878F5311308D2A,18C030BF358FBA50,382318AEFC9026AB,E6C426724E6DDA04,DA661B290A8E25DA,314CD6EE789953BF,1AD30FACD2BA0971,D66721B55EFD6965,5C67081E936C7B4E,32360C1467B9D3F1,00003478CA052D83,98CF46F9DBD0A45A,686D7D944D3DD9BE,CD0902F6D0A54E07,FC218FAECCE25FC8,0899BF56B9FB9A3B,3648058330884E9A,D52B1AE2D211D4BB,0AFB852F55A352F3,B8B0C72FB6FA54F2,17A12AED9DAEF5A5,20FDF90B73BE4C9C,00005F2A11B09217,BA9CD922D19ADDA5,4632DA714579BAA4,9E27DDDD00394CDD,3DA719229A2613A5,64C1C6907973C921,6E341CDE9208B7A8,7BC1AF755B94CC6C,5D93C788414157EC,59615AC5155EACCB,64B97577B6F0966D,AD78E0127E3B5BBE,000031CEF74330CA,5F2DB2DA14B1C5B7,DD297FDD9D80E2DB,4AB36867630D2C19,70D5C6091AACB229,5EDF74E42610BC9E,0EFA451A6BD8980C,043BFA16EB0784C2,F29448E01137CC62,F99E7F1468E15E4E,9053271C60AA5D7B,C14009365BCC30C0,00006BA4161BB0EF,AEFEE699DC1710BC,6D947812395E0706,B66E288019CE5446,F7501903A274EFD9,979ADEDF6A46A177,8CF28AECCDE721F9,012427A3E84E3779,E2E2B0F0D0EB1EF4,F29B3E9965A7159A,153C338DBA1CB0D1,84085D65A1710813,000007ACCEE38034,075F1CC7D6C9AC78,B0B56D864E4A7242,0F2777E76FD669A6,82C424A9BFCFD718,7278F3B6D667BBB5,6FF2DF4C117B87F9,94873A9241424938,56E76E31F76B3D9E,F4DB0623550F81A8,FA650B020724F6F9,B769F9DE4513927E,00000C28901EE4F8,B47F57EA6FDF5047,C53D900BD4D5B082,EBF3D29ADAEF0DFA,91F2CCEE43B0FB0C,40421A8274A552F8,2045B3B56B682CF3,25D05DE842CB0F23,D318430037E728C6,9A65A479325EE038,EE50880F80B10D18,5444453804D450BB,00001B86F458FDAD,E0BAB5858D724766,00151B95FC15E559,95066AC1581064F0,C1F6BE4143C82F77,9239391BC1B0260F,E2860E3F013451ED,43E047483AFF1090,BCC4120276B44D77,89AF6B3AC28700AC,1FF036CFCFB6E744,E1CFCFA8A8E3266D,000016916C51502F,145868DE8F606810,C0C9A688335CA9A2,217753820815F41C,80B4D1F343EB9557,F723AA580FC52400,F363AE21CFD0BBA3,810D91B7DD8390EB,DE6F8A166D73D9A5,F87C7407925ECEC5,D5605CDD19E0F1A7,61CF4401C111D593,00006D78A616FF10,6DF8CB727215DFB4,59DA871FA081D64D,CF95D2D57973E5FE,2B071D022FB8A993,BE0921092244F29B,D3338BEF47DC6577,582F9E53ABC55498,50A4CE04FA5CB40D,A0C67C54AC0628AE,2442DD9807F24612,86FE69B1D40DD69B,0000562045002DB8,F87AACE82047AF7D,9A75F73BF71AE699,194DD3D57ED06B70,62F8246F5D64AF76,4F63580F3DEDACED,3D70195143875D1D,18667C0002CF858A,3CD972604F70CAD8,BDD19576985954D6,61A67E71EC542C71,9C6C685C9F7063A9,00000BFA6791A2C4,123BDFC36C20BA3F,6CE6261BD1BF0168,BB230B491F81F860,98C59F619C1BFFB3,14CC3B02A4A6F790,F408CD60BD028E15,86D7AC34E9BC899D,AF57C7EB678654C1,1072B8BE1783F31A,CEB78CE255A8F6E5,5527ACAB1B2D34FC,0000426490E8E965,CB5E39C02E03B5A6,195A837898B9CD67,7705CBDFEA003357,254A5FA27D5BCC5D,92E70A47CE9BB3F9,73C9ADC40ABEEA72,D7A12323BDE8BA3E,2C118A1DB209CAA9,12A5C56C86D3002C,C77731FE5453B0E0,3FBA4DCCF0CAA0C9,000050486875D0F7,F2A3F729E6461A90,33D523CD49C4175C,22BC06C4328F55FA,594F49BA6C0EEDD0,C1A4EBAE3EEC2350,252E5F82178A407D,09ECFE17D82C0DF1,6F077D5F4BF7CB4E,653850866A4DEAD0,4AD7044625A46346,CB4A47DB71BDF055,0000492E992A8DD0,E46DF16981B084EC,E4C3E1999CA3AA3C,CA997817C2449FE2,676F23C580F3CEFD,4366575D4BC33B00,86BB09F502BE93A6,458C30ABBAF83492,54CE3B8F5DB0197E,B97EB6EB98B0A308,5F1ED27603F4BDA4,E5F4612DF9EFA70C,00004B385700C7CF,737933A1687ECCFC,B5960720B49BD6ED,000E646698E6769B,8165BE69C6CAF517,6413324134B22AE2,42398DDE86EA5B01,FF563CAD0FF0F592,B710FA789524C8B6,80E4DDC6AA7E727F,CDB5648029F45791,B74DFD2E0B6AADA5,0000037E37177D97,230BEE27DC715D1E,6EF6C93DA5D49C81,0CDBB265F50A4C7F,E7ED8271776C790F,3A17D2F08CD76246,FC945C410DED319D,B3EFA9C0C89C0A38,99A30A8916FDEBB3,6C9E479E745A0DC4,B2CF7E102C06E419,79DBD3270E548CEF,00005D05A8655AD4,42D9CF68B4E1068A,9A385800DE6C3B44,811C31696364E184,C1A4482C8FBC6D35,51B1603A9BB24C76,48918255A5329200,1A498648F334DDFB,9AA96DD5A44F43E8,DDBF81755C608468,3B3C71B275F33421,387A067798DEB56E,00004F55FEFF0E3C,A75BB39525528879,B9E884FCF99BD6F3,3ABC139E39E939F6,9790B044D19F40CC,21D67DF44199ADF8,F87FA53003690B85,15255FA78694D86F,3BF4E28AA9ABAAB0,67FB8A6030DF1BB7,162BB85533AEC259,9D5A7819852670C6,00002BBA68B90B9A,33B84E7DBE72C963,9CA603890B0517CA,0ECEF00E223BC76B,354679377A253E86,215F72E16C75B963,F02ED42F22DEE581,3C018F22D6B65BCD,80342A6958D2298A,C526249402391A1D,13906607EDD6D859,68CADC09D566F8CC,000018BC48C2C591,B7FD216735430882,679B57CE6ECDDF86,ABF14F0680059897,16BFE8F837A9CDF4,1AD4D8F1FA24857B,E44F578359209479,54E84E9322D5D4F2,A5C824F9959B1C73,78CD3B8AD01D00FE,A90714107744E9CF,20CBC65C21D957D0,00001A95CDFBC15B,77AA91C5095B7622,8BBFFE04E59BDD13,C185DA21D67254EE,A6E995EA10F53A8A,658867406E57715B,E2BA5196DF064F3F,0D8DB8FBA0DD19F9,F2923ADAA078223C,F7807B27DC2F372D,8173199C40A403E5,93C23438F925CF7D,00006F53E5CDDAFE,B34B3B132BECEE4B,EA2343F0BC6B6223,8B91397B7CA6B264,F93618BB7F16F0CB,3835672EE0D994B9,957C528C5C7F57BF,3C10B4B606EF9B7C,5A74BE33995A813F,F5AFFD989D385405,1323CC6350B9AB75,ED380CF97319FCBD,00000267740508F3,496E3D4D2D1DC124,45EB0244B3708532,5190E9C010750286,330A9707598B9AFC,85A765191B01FF40,D681673EA232B1A7,FD2100130DCCFF28,53411206F1FF2366,D8FC9D9D575C9F3C,5AEE439D462E3C3A,B24F3EF0AFC8B4DE,00006F6B754C06B7,EA5B7CD14AF47B69,59FF3A75DB13A0D9,07F1CACDB2495E31,EE9C7F77E168F18E,F1ED14B4C80B8A80,5E30B2BAC8CBEC69,4C53539DE069627F,670D8A75F3AB5A70,597595CA41154DD0,3C355242140AC63B,B1250ADC3DAFC6C4,0000536C384FA99D,80FEA6D78A2BDCCD,B1B22441AC3A9440,FE5E184878E1A2BF,E587DB2B83C539B3,E4D90710C9970C91,12CAA134D44EFCEC,C5E54FC7162F70D2,E8D48834BB92BD2C,1BFD8303FFBA9663,697009E9B0577360,6CB8AC8589604B88,00002359A0D36D19,A329EA8D74FD9338,EF85EDDB6BCEC71E,E2FE754FF440935A,5917D51332A699B4,E7F0C298BEA5758A,037F5D3BDCC30D21,FE4D8FD807621E1B,2F53CFF8153401A0,36E46F1165951F70,2BB77E5B7F318D76,01E652CCD8A67CAF,00004960FC9EB285,8B945E6671F9A4B0,D41E2B42BD2A064E,7E2E06F7EFFEF225,2CDBB2E313E02464,DD13902BA77105D3,E55C0792CFFF2000,6031E2049847DF61,836E57E4C99B5672,872E956F014CE093,907B0EAB559ADD07,17F1F25AEE2C4F49,00000ED92A5E4A5B,F3AEFA11103382A1,1BD505C406EC5CAD,EA62272127FC40D0,0937754E1DAD5CDF,FC29942D8340D386,4E26D99462CF6ADA,2DA8D2A1F5EF09EC,3D54A0F9045BCE09,777FED512942BD2E,8420616645ECB3D4,A102D7A4CF511750,000055368A40EEB7,39B3578F810E899D,2E4C0F6F25479755,03CFF221CA2630DA,3473A2C0250E8827,D961186D6ED192C5,F33A8DD9E725E442,F8C6702729E2F46C,A924AC2661757A52,7965283071C4C3C7,B1810FDE6C8809C8,2079C6AA2DB4BC21,000059DC7910234E,93C66CD188AA31D3,B527E952A4AEF9D8,A9C82B94F120D31C,2BDD088DB4D1629A,87256CB207F8761D,4EF5DAE4D78FE437,636D2401953F6718,A5DDC8B8E369F222,AC3072326F44D2BC,6FB41287374F167C,11D4D165901789F2,000000FCD2068DEC,A00EC97A684B15A6,564A5722AA26BE38,A8277631ACC8D6D8,B2A1ADCD0842BAAF,B84637E43721F151,C9E3C970CCA1674F,F689CE0F845517AA,A997D5C2510F321C,3B78F4E4E74141F6,469CE900B8E5AD73,EE0F5A3D39A8FAB2,000017E1CB317E07,0817124E2692E8A0,83407F76249CEDBA,8EA83507D387BBA3,FBAFFF5A09B816FD,52EB25A8A3E22C4F,3526B7388742FE2D,A35713EBCA62C749,F59C9606C81CEFFD,5D991DF4B45B4591,252E1BBBC0BFBA33,E8603A8F2EED800E,000004B8A5C249B9,68E73E66239781F7,92D376E5B9D6AAC0,9A837075ADD765A6,1EFB5C17D4EC7E1C,26952D25B8307797,8CE94D71BF232B79,1D345EE588C23440,667C22A6AC0B7352,D86F2CF897521784,186F91ADC0965256,6048004D098FCA0A,00003EB0DB00ADD4,A447A380F52730ED,5D1D0DD35158FACC,0604E022DD195E0C,FE14BCBB6CA49E88,FB1F6179DE187625,C484CAC4581C771E,E5DE81C9DE982FEC,97F8DFE6616BB7EC,8A796EB01B49952F,6DE049A84B2A8441,D7354C6CB99BEDF5,00000B82C02AB2F1,0CAAE500BD7A1B7F,EC11EB34C27D53BE,B7A90D595423C24A,F3F9F965A3E09F7C,C43CD8CB3952FBDA,879F27CBF33EE72D,F8294F89F0EAB39F,328D1CC8493CAA43,CE02D45D54356F8F,ED6D5C3FAA22F9DE,4D35F6A6F3A787B2,0000104FB37B6351,905D61C552D52FC8,E256E495D4174AE2,AFDA3455E8EB5895,1884D69594AE59E9,7F9FD55B2D8F1B5A,E835A0AF45EF2C63,338B6FEDDB0C2E2A,4F41B76182ADC982,D990380800121005,40E1EEB44D457036,857809274DEF7229,0000356F31512FF0,67360A87AB380636,942B89323003ECE4,328DF0A650F06753,2050FF9B111D887E,8CE8576D9B954ED0,42BFDF8C47A8B1C8,FE24A15B55EDFEF9,CCE8A3FDE9D267A0,48657CE0EC1234C2,EA8E831FBE749F8C,488703D595E79A27,00000C242B8C14F8,FE2B3EC17FA9C050,49A651CC1EF61175,63F158E6170851CA,6D90CBF0973772AF,3DEFCD00F5FD5AC9,EC2713FDB759A313,299A903454A5AB3E,6BA46B6B09B4EB17,1642D4DDFE9596B9,301010ED9F5C53A0,C293EF22FE9246E6,0000012E459DB91D,48A7DE7296C1140E,6C30939CD9CCAF39,ACE3A536036FE0C5,7F5AE61534A962D2,6F68AD2A982BEC4C,443CC4E9A5437F0C,E27E8E743EFE899E,1C40AB46DADB3AD7,4A1EAD7645ED9C2E,10A76E1FEC5A5EC3,510FBB0947FE8A15,000055A058D3CFE0,6FF87785F52A7E18,8EF89F7BB7FE9C99,8FF27A36ED8BFBD8,970A2AEECE868241,38E8D84004672D35,9EF57AA8BB0FC3E2,8355CF73FC6BAE75,8408CD3B07BF1F0D,5295E3A8F5443A38,131B7C97ACC11414,7F224E35D975BA14,00004546B01D8FBE,3A8CB19A1E62FBFE,3B79A8F56F4D080B,4E6E2D25936BAFFB,B0A79F928B3ECC64,857B6466C7808595,95CED87CE4052F3C,B623F956C9704E18,07F919063B9E5C0E,4036FF9126BAD32F,ACB53D2D9C3EAA1F,3A2C8498A9F09CC6,00000278C304D445,09FEA0CCA29DF058,038667B9F4C3CF46,59744663F06238E8,3DA4A7D004CD5533,42E5F441923E8EB7,B26B63A5CA6EB943,8AC8665D04155701,1A1CB79743E699AE,1526CFA4EF614AAB,4245628043716E51,D355B5DBE49FB2B2,00001940B9D833C3,CF87531AAA09AA61,DDD2CFD7B2B5BBDB,B92BD168AF12ED0B,DAE7930CBCBC4887,4C0AC2262BEA0248,7A0CA08CEABA1593,FD68DD646BC5EAA7,313582F5DA3049A4,A68380BE7EFB154A,3AEA17F9C6F3A6F8,29928EECAEFBB3B0,00000048ED92AFBA,82234A2439DF322F,EA642B48310E0FDE,05EBCA52AB4A1F52,B3A4A6C34AD7BE26,613865A892A76A4E,CFBA0D11ED14B3E3,B44AB06B5800E9CF,2F2628522630B2D5,4B7B4026B47EDE16,9094E1BA6E19ACCC,F88930CC8DC97C27,00003B0D7601D276,C29FACC0CE82973C,AB0470B2207C27F2,064ACD8F09D7863D,6A9D825F6F23FCD2,45B11528461ADD56,B530069257174D39,E39B4F1DEE8655FA,B4836E43FA33EA10,13DD2291A3CC53C1,EFE679D67E84C63B,53906FAB428F3179,00001814083F1950,1E71C31B9F637CF2,7B00DB2A7D165D5B,55BC11C7DD496CCB,7F34918B7B4EE93F,C3FA30A7E3C11AAC,377722FF84AF84E6,FD8100008EA2EF46,009B4B6525A7D97E,7502ED7A4E136163,5E17A6B48BE52823,2106389BBB2038BB,0000102BA6462740,D1541DDFC328DC9F,506247BFB9E0A253,9ECFABAC3ACD16DE,3645424A3B957AFF,C7BE73DA1386A70A,738ED001F532C3C6,32DF414121A715BA,087196D2CEC10E55,9B1FFADE2773F353,A335AFEEFE61E951,1A320CBE41C184C6,00000C599B0AB3FB,1BD00455B3440BB2,46313AC46E911348,E277D0A44D293ECA,842E2E58BF7132A8,AE6947D28272190D,307FEC2247ED8774,B2A484F4D60EB979,F9061810A6407897,6ED2044AF0133034,283C786DDEF162C6,DCBCA07BCB79B99F,00004D0D165DF0B0,3AB8A86740D4F4F3,CFBFB2395FD55188,9EC1057C63F51BBD,306B137DD0663DEC,CB8F53262F809014,D31F99540ED3E64D,B5CC9B9B315782AD,29D81ADB4CC4F9C0,581E592D84C2C45E,CEB8CBC79C11817D,E66F90DDA56E2594,000035F6B608DBDA,104D7121692A6406,4F5960EE5F46CD8D,0F70D5ED37BAF118,A884BC85CC9B8E57,A90D17CF04FB8C42,ACCDA98D7520A821,21E3DDB77834173A,6829E8663321D82D,5FB01636CAF6E2DF,859BBA23366343AC,E6704D442F3C400D,000015A1B5CAC2F2,7DCD70A9238AF25A,EA22EE0F0BE80C7E,8CE01B594BFE2A71,7026CF10ED143BE2,1E08CD83BFA9E9CD,327408B186165789,375E6B4D86AA5EB0,77DB4E29F2741679,C165BD03E2131130,76B89545384F6499,8560C057293F76B5,0000007FFF49355D,83A486D4CDF631CA,268C5A1BC282468A,3F4871ED95928102,2BF1C27609204D02,9A6D2EB7C2BC885A,50EEBDE7B8A97B48,320206BDD14BD4F4,47B8ABE6C7AB20B8,67D91FBD0618D9E1,A3D3B175D29A3387,BC60421F0924F3ED,000051019A9B383D,4F2AD631B052AF86,C424CAED1FFCC1FD,888C8BA7A5294AD3,AA6EAC8F90EB9832,9F386263811BE3CF,2D4AADF0721185A8,D0F3A8248841A3C0,46D8D2EFC923E380,BECF51D9D7E983CC,4A50FFDFE7C94864,E9284B135F00187B,000015622BAA7883,6F3DE992269E13A8,8D1ABE1E26DFE7A7,A808D9D75CAD660C,A2A07DAA67065059,A035E7114DEE8312,DFDD9900BF1DF036,2FDABF02BBEF173B,1882D76E8DF431FF,6AED2B4359F72829,1A45FC5C2ADD6047,5763E12800A8DA86,00003052941E35BD,FB5764B50287001A,0CD2D53929251743,0F51A966178FE51F,42F9C237F233B6C4,74DD95B47CDC9245,9E819C500A5E1878,0E2E7E023C1AF87F,424DCF8D579B305D,06E7F3BE177ED634,838F182FA3A8228F,B9BA74C528783122,000024328914BBCE,B07AB8817DB3407A,F8A86018D28378F0,D22488CF3576BDA9,A827225B88D0D573,686C40747A89D34B,4EE182825A41F3AE,EFA88EBA0F1A0413,06F2BC8829A435CF,2D5E763998C26939,4AACAA1858A50447,349B9067DB277081,00002EEE73332322,7FC075E1CFB25BE5,8A7C6140D05F4BCC,9FB9A69360604653,B6CCFD98CA889184,0BE32A3D1A5C56B5,BB1B28E79D33CE24,E2CAE2FB21194CFB,3975E3BE97317E2D,1E00E086081D111F,1757BAF8F1247DC9,7937F5CC7E96A197,000031BC189558A1,73D7357486B195EA,617B952FAEAB8F20,0EAAD4ECE554DC78,9C2D80CD70AA64EB,48532EB84986D19D,74E7540A59A30A7A,078FCB76BBF53C39,06B0E46AE415F089,3992DC3D01031AF2,5FE307890456812E,F736EF2A3D867BF9,0000306BBFF68092,B3F17C009A2EC718,CD81AD211A604CD7,E851973EAC54DA4D,AAB4FF7B5E9ACF36,CD644765262FB864,A04F97C7D5D7BDAB,1AC519CC3C37E632,F3D863B113FCFD25,E603529B0490132D,9DF44EFAC9F1E55C,44C95FBFC5478B2F,000015806B00929B,83467FE500518ED9,D7F0A20F9BDFFD9F,E4D8D77AE1D47CD2,F56AC2915FABAAB4,D88FD6C78DCB21BB,A55AB4AF5FED1B4B,2305C692E27B74D3,9831458F42492CD1,AB5E7C14A3CC7BB7,5BF199CF419C494E,D2CB147942F3F667,000065849602CA4D,93429157F0514DF6,5A6BB493234304B6,22C49724C745E30C,B0E2B23420E21113,12371AFA04F53A5F,E502CCFFA79373E6,DE2434C5F87E434F,9BFD5F6ADCB4DDFF,7FAB01696FB6F558,56210994974267CE,4BAA81F0635892A2,000042BE4AF4E095,473FAEB62198B3ED,9F28D13E7E8C472C,C5CB5CCBF74830F7,2BD1A3ABA0C73FC9,965EC5AC5CC7E37D,B23FD00DED4F2728,F78B821FC00DEF22,84F8E7FCCEE16DEB,FCA1E8D49DBC3945,A65034640E07F676,BA422FDCBAEE6884,00004FF4011F02C7,20E89B0000F9DB56,D282768CE406830C,E98C3DDD96301339,A97EF9767383F477,38F1D5C4FB2A1248,787D1CC9BED7AC38,EF068A9634A8F280,6B879AD495876826,A5359BC17E876C01,5A03CC0406D6805B,2F1612F9A5C3F1A3,00006F25FA811760,FE319F697DD47D2C,319C48860EFEF75B,3DA6EB8D30763FA7,E77FFFB6BF3A66D2,4069B3117DE3DFC9,EBEF37841A7D818D,072E5602D337ACC2,16CE25EB0106D083,C09A515C5C5706EA,9BD8224CE77B645B,019B69A4BC46D257,00002644FDE178A0,9BB1DBE653228DCB,D01E3D291F7ECE87,FE9971CE2958B218,DDC01A51F742FDC4,6E4059A3BD7B642A,933D13F126F49BCB,1F72FD28C0C18DB7,0C16F5D5697DF988,E6D961CE92AD76E4,7BE75F286DEC7D9A,C5062A8611C34BDB,00002BD2AC332D7E,6EC9F107D755218F,99C4BD7FE3B3E4B8,C68FA4B551857D9E,26FD5CF5D1C502F5,C9CB5B92CF99A933,80EFF7C65005EA80,D00E8E9493974CA8,2B9B0681870443B0,9E26F8BA5817C555,D3D61BE95B0A3CD0,B58EBF464FDA03B1,00001BE6F893243C,53B6EF66F918C81E,BD88C04DA2C1A7F3,531B7B5F0BCC388A,73A2668E57B16214,28D95A3D120B2E21,EC37263913C5DF7A,BBAD459E53FA7AC3,1118936B2648B193,424ED3FD5FBAF9F4,95FF76E28E74C783,1758A4A1C3143062,000037AD642ACE26,9229A6C4682E4E40,6F470794BA7DBB44,103B84AB358E7047,ACF1C9BE01916015,D192FE463BB984CC,A139C55CB77A7C68,59BCF21EE52C20FC,A3F6144E232117D2,23E3B638EC423A24,3ABB650B709E69C1,6CBD173D5C55A2C8,000062523C7071E3,DB6F9771099BE09B,2D779448E38DE856,2AA3D34B8D7CA528,0D83A2F316FCC6ED,FDEF90354439670B,0EB3BEC0ADBF45B8,57411B1360D68FCB,6C908BC1B581495A,1499B31E39ADED29,DB6A6323FC16CFCC,E0C7FCB7352377A0,000008BC329033BF,D767F72D54B66C1B,45C41B9DC1ED7926,91C1B56859EC76F2,14C437238B81B547,0E8031EFAEC1627B,D81F30BCCD4F20A4,FDA39ADF56FAF896,F357A7E4E75CF438,3AF67B49E72693A8,0A9FBA9A712048C4,D02DB1BACC61A52D,00002B52B4E368F7,CB17D2BCE79AD3D8,C30EA46DCA3E3D39,C19BED19CF6D991F,A51C4AFE2586351E,FD97EA305BD8C577,6135648237FFBCA9,D6A326486916FC9B,11DE6072D04CCDFC,CB6380878B0DA387,44DE1E10F6B570BA,A55A3E4B7443819F,00005C4ADE1200D6,200F8E7FD7A17328,7F3B64BDB430BD85,4CDBA905209DB943,CD0C4732876E0F84,0AF7591B130DDE16,8653AF79CE87B3BC,FCEB9826BFD83851,B9F3DEF125CBF24D,3E987DF716542708,6C8C2568EB8CDDE8,AC29F56B460CFE7A,00003ED09F1B9E9B,6177D1DA245FB981,43F32C6F483AFF7C,845B9622B7B33FD3,8B4905B5B09243F7,34085571DCBAED9C,D98589F7E34C7A18,95396F0670546B25,9FCC84E9AAEA52F5,4A4282E00E812199,C5E605144ACDFAFA,C135C3B996C562F4,000041A13051B175,96FAFBE5FEACB5B9,8ED4706293642332,E68A928EF4A51381,AFF7849D6EAF9DD8,FF3E2FDD9BFE5384,66935A59D28F28D1,23E95524C79B443B,09402619CCCC69DE,32E20981CEDA9020,E1083952A4FD604F,A52D96C4C04486F6,00000FD12D8DD918,C0DE6C4FF806BBAE,DE745FEBD489DC86,1F53767D652C9155,66E8951A19A78E16,06CC22A4E60BAF8E,9C1DB3E330608324,9FFBF057353A7D41,CF86C4031A1ED83E,104F976032B4C6A7,1ACD6BDE054195CF,131E9E1D72D1CBB1,000027D71497CDF7,9F1580251E9E97F6,4FD100EF08DCC7F6,18D6B74AA9AD668A,A2D400D65EB680F6,E170E04F4B53D453,BA5A0667773E7C44,6EFB6BC60FA1295A,6FADF596808F6FA3,ED5ABE19E66332F4,442CD3A9F43D1096,1F4CEB36E0BC4796,000017A72DA4722D,89E534DA43C1CE7E,89A23D2DB540B7B9,113C676C146702A1,6D70A26921E44F52,33EB45242FA6E552,A209D688C02C9307,916B0B10AE07ECCF,0008CA9FD14883F2,C81206A37126C4FE,770DC23AF7F929CD,8D8B53259FE03095,0000382E7DF5481F,D118D19B049C991B,625E8A7B6F52C70F,3129CB69B511CA6F,42EE0C1B76B3848C,D4DEE11738A1EA05,34A2CB69AB3BF9CD,0486672A69A8D829,61C7DD83CA723C94,5700BFB5714CC00C,6B3EBBFE5BD4761E,D04EC530B95A654A,00001812ADDACA50,22226681750A620B,B757B360524177AC,6829F8B353001DC0,3872B9E01E7EDEE4,6495C719B6A9AEFD,42EE4B90F0E435F3,19D2D14B4E00967B,E4F5879A87E00F82,DBFE978C25C692B5,2BC698AE290964E4,4F360903DFEADEED,000002EBC5DFFC9F,CEBB566A37B60E1C,36A1BE9F5CD46BC9,7DFB845E80F2B300,ECF1F85FE7D937FF,A39788890E0C2161,991192474C8CAEAE,A480840F27065516,04E9A6E91BA4B5B5,0617C567224C17A8,5C5BC36A13E90830,8B94B2F174578E50,0000169B81A0518F,C746141315C7E266,6EB9B6092DC2F093,D391B8B9D3002A31,29D3CFB71A0DCEB7,8AA8C93552517D2A,C1579299A9F62938,EBD4F678B85CC8F2,8CD0D5AE27560F76,A277514515454C67,59CBE9B81113D89F,41BBE3D2E4B9DDA5,00001B85F6EC275D,EAB335527B5DDFAD,FFC7218F0D085D83,08442B2F30E13D60,D28417F8CC49012E,9B66DFAC65B71BC3,D2E48DBCC390F2D1,37A12E3CFFDC3909,4F53B04BE06A1E13,884ED9E04DE3780A,E0C78A861B969B53,0C5A1E56E2A26011,0000057176719089,8CCA00492F4D9FE5,96A79F86C964970E,27847795D7F85AC9,B0D6E5E11B632529,A5B5AB6E618984AB,8B7CB202ADAE3CE7,50232AFFB22C6F2A,6C7D3042F4840304,AC08D493B9DA70F2,5A4B775C18102E55,36A85F03891895CC,000016627066D19C,87B498FCDA3DF876,7AA6EC4D1A7BE36C,B9006D0BA9410C9C,E75C47C771D95A79,76D43F2638E057CB,2F15C4D7AC5F1F8C,3D04C07B9C278785,1A7FD58221704D89,776B1B02501246B8,64B833B13574702C,1526689FFB5430A1,00006E295C356151,5A27431D5D3EE696,6A104694E5678DCF,6D6AC3E2E44FBB4E,55F60B651B97501A,C7BE950F59C28E43,4B3B671C905A9FBA,A16966D2D83A1C59,9D3D8ECF70038370,B7CB5875AF60BEDE,E4E6D6C5A301D9F6,BB10FD7A7C586DAF,0000697E678D53D1,06CF4FCA7507CEAA,E70DEFEFDBD2D640,D22B03EAEF8DE729,22721260E8046D82,0BFC5C096F141B6E,A7501AE062B57F1C,64D81F43E11C61E3,08D829DDC3AB747F,951C28BC9CFEE07C,070602ACB064C366,19630B43C42F7B54,000006C29FBE9A80,F8977B6D2B265EAB,099ED967ABA292C0,0270E84534979D29,4B48356F1AEFCF47,0D9435E46B570FE8,7B4E87CD4485E2D8,D7ACE4FDE76F5E4F,6C397DDEC540200E,CE728DBE4897D5BE,5C57E906EA0D5928,640C3705A43F3FF0,00002FFD1D58007F,36C9D199671A560B,811E46F800AE29D5,42B3AE93C95D507E,1C3F9744F447CA41,DE1F0153EC2CE3E5,B6E6BBB3F1CD3C02,0BD8B6C11B9322B9,47D5D8823DD42DAA,BADFF8C26C8BE79F,CB2146A0F73FEE9D,6C8FE6A7846F7C53,000042D6CDF3A10F,8B6B827CAD7C9AE1,7E160270921B6849,2CFA5ECBB17FCDEA,B7FA66218D486C3B,6444AE41F1340D05,C956D9AD237E8436,5562801004AA72DE,11E8B6FBC12CC220,C8EF3779B33F882A,4546C16F0A631B54,010D2B79ACE8BC33,00003B9800BF6FB0,D163EEEC1BAFCA52,226BDC5A477ECADE,40AC4CA80EC286DA,EB9013919BE65D37,233B5E7D9B2F69FE,341204A3134E7D6F,1363DF8394C6DCCE,0CECDFE19C4E3E67,28E14E96AD97AFE0,18F93ED78262F82C,9304F5E4678E0988,000067C157C7D0EF,CF9E757A6411673A,0A309A107DEE3CA0,BFCACED054770CD2,D1BB52AB92AC7B2D,8CC8103E5ECFB202,50B918523492D4BF,D118A328BC6AD4F8,71AA7B2D04BC030D,9F814749AF62E4C4,41B980832A915F02,1310D1DCD43BF360,000060F779DB48B7,A97CB0325F3BC472,12F7D6C22F1192BF,6B6523E4327BA674,6F4F4525E4A070CF,887C579A543E684F,EAD84F73A96DD619,1EF2109E9DABBAE5,6399571DBE3A8B12,CD24BA882C1B7E6A,CEDE8912469E5B96,F58C4C3442BA8CB8,0000320B150C23B4,0F395D951EFEBA63,7F72D6CF11123F1C,288DD45FD1B09503,B6954FA5153EE32A,4C392A802CCD6600,42A16AE931998663,EFA9524E4E99679B,7E7049E4E9C5F091,1175DEDE648434BF,B5B6D01732383903,0C13464066340B2E,00006E96801DEF70,C5195BDADA845207,F50D17F7923F93C9,831D120DB9A7283E,3679BA2BAB105006,260E6B21FB65346D,E15CD65BAEB7DD31,9270A172CEF2FA1B,8D6955EAF624F7BB,F7B0EB1A24C038B5,0A8C1A7F918FE6E3,56EFA0083976E393,0000182552A310A9,21FBACCC7B2D175F,B2A949E459BBDCA9,0A3F78055086C9A0,C3EE3C6035BE1EDF,4DF82E1A55D9EFE2,85D4F4F0C8E52EAA,15DBB59CD3BD04F2,7C810A16B96DC400,2CDD6AD605A6770E,58151586F4C1E54B,B35D5D7E044A22AB,00005139BEB07EC6,61006F44FF630A55,F82C21B3ECA29E03,1986D756E355328D,C3E012BEA3250C65,0B2FB8E29E328A97,3F087F656BA9A72E,ADF4B092A7350915,8B8BBC3EB66C8BAD,957509CC151FB220,77B845B50B5BAA32,ED11A1B93F008941,0000108D16191D7F,18B8108A2E306ABE,4A3D776B6A7357A2,2D1D3DE3648B759B,400C90C55416AE8F,9EC1D912464EB731,9C17A7E66945585C,5A2FCED023453BA5,F1C5A9EEAD61C462,665C044A60BB4010,29D4710253C2F81A,79FF6AB39CE9F777,000052C069B6389D,D8E911C782A0BE43,0DC93E7B9253E5C7,12773C05016BCF09,DC101BBF5A73ED72,0F1E64DF05A5516C,483B17308ADA54D1,FEA6E191FA4BB6CF,57D05CA9800570F9,F23B50E85B0CFE09,E4A28426E05F4457,C1B2D716983AF290,000013D6654E5B17,D5294827CC220505,9492AE7268BE7768,77C7A638719F9007,8496AFBA17BE99A1,B60B6307A1078E5B,00E291463C485AE3,D62FB40FFAEA198D,612EA7CCE8FFEFE3,A2D8B0A87D4CA3ED,13A4E0E775326EDD,7F8F81C757AE3A84,000035E94857E81C,E6E2E3C66F547832,3B416603AF3CDDF1,4D7CA5F302D93581,E63F53B65C4470BB,B2820F2EA7F2F54D,C3ACDE63EC7A09A4,8BDE9BC796584F35,C7698B881AF26D15,7559B0C65FA1ED69,BFECCEB092D34B47,F205684166E54969,000019386445A1E6,3464F28E033EB388,C35E7B8217F029A4,FBEB6285AA9E3FF5,C68558C100A2D4BA,3F0D53D883B08C66,E09A7A6550D11C31,7EFCC7A80AE6284A,C67183BDE9E90BEC,ACF765825F108CE9,6C6D903852E1D1C1,B31D21737C1C0897,00004D28C2633021,9B121292E3B0D1EC,7DE66C749F44F9A4,A2AEC71DB41C62CC,A8373A7938571B23,7DF0D6BCBAB3BCE7,F93ECD638F5966B2,CE0710D616DCBAF9,15A3B37A27E4BFBC,E09B38DECE20CAA9,C3C6EEF11ED7A615,5379AF04836B8FE8,000046645E822D22,0931A5D08CC7B931,B7DF348CAC5822DB,21A832DD86611161,18A20A0A5958D2A0,4B65785D0714A8B1,3DD4B6A79330A677,1960F44917AEAC46,ECCA2C4C8C4C32A3,E8BF4A8235755F87,B76F69F2410E54A3,3E3BF60A4FADD32F,00000F11FC744C7A,C55D323890457ECC,D0BC1AEAFCAF5ADE,28D9C4176FE657B7,E455BE2A0E4F1B58,03A7EDBFE592BAFB,F9EBE5CCA77B7425,82038A744973EFB8,EA55F0D1CA2D11F3,604CD6F6067B0528,C24DC63B08A79AB8,1B958346B7FBFC79,000055DB84FBCC15,B13F3005798EC031,E8DA95AA5E82B45D,08EA49ED4F26AB0C,52CBD7D51CD2AF6C,60464F86AB3A775E,3496B43EAE74979B,2749C1976FDEC93E,D2E637318FD69FB8,1698BC703E05681C,E951B59328D4C238,B2A003EFEC920BB9,00005E6C4BF7C52C,FFFFFFFFFFFEDB29,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFF,35CFFFFFFFFFFFFF,47627250894E0621,388F01AD6A5453D3,9FD8705A9547CD24,9C5F0065455576F8,FE8D7F1991540A3E,000021455842889C,3491A5216328750E,BF0C22B2AF31F1D6,C7EF63DFC40D80A4,AF5B79C2C560B8C5,AE73C70F613FBE71,2C6D629536721BE8,C9BED31D01E0D4DD,E2AD5C56DF13CC71,42EDE69D8A687750,B698857D9E00B623,B7D4B27BAE733547,00003B27DB42AF71,693EDEDB540AB6E0,0CD808BABBD1DA42,9679EF408157216E,301A2E4455CA8770,D91CB3C27F3DDB05,AF62159045360E6B,3271C312B5B624CA,BDE86580C1744893,876F0B42F9C51BE4,2F7E64F62E5A1BAB,6D8AA8140FEBB2CB,0000222ECDC05133,E1A0BA8B157D58F6,DEA9FB99E09477BC,491F7B1CFAAF9E3A,811085298A26343E,D37E3F484C6AC55B,D28D9BEC79E1C2DB,3A1DB4F3FD6C6CEE,3BD1571E9F126921,7F660D8E658E6BCF,2CFAEA145AF5BA7D,ADA1C2B2B010F4C0,00006D5AA75E7391,BB713D3ABD1369A0,6F21BCC931A9739B,F1EC14FE1967F6BF,E8798060E308740C,F992D1A8F10DDAC8,F948E328C738C333,DAE00B95DF687B71,3BEE2B9C41D04E1E,62DD3D68B39B87DA,781FF20553EEACE3,D31F2606694F9C2B,0000675C36F59D60,F9F8483B6DC8FECD,386C5DBD9B45E3BE,F91A5E7DB4B07C5E,620CBA654419EF75,FF2C4DDCDA4742B0,E9E34BBE61972013,0DA43880130DBD53,48EF7D81B67E0E88,DF98040BA7DD133F,871B4EDF6B8872E8,403B40698134A467,0000106151985426,5403C05EB62735C6,CFB18204BE838E44,2F6647FF437FA23F,E346F21DF8AB3F3E,276F85AF5CA7D644,49A64B4064CE192A,C59D594AE4AD2F57,85C2B9A702E067A5,9B43FC875289C257,BAE9CBD4384F251C,C51D8855F75EAF69,00003E881E59448B,126945C188119C28,10B5319DBE344CFB,F1ABEA805A177655,02971C60CAE4B5DB,F11525BE2DD69C84,4975857487EBED86,4D0DA89081219C01,248614C144731463,886893143055FE52,99BB2FB5BAD243BE,0DD254950F8CC252,00006BD4D8F4A877,C6167EF37DFC3767,FA0A9FD081097C34,D401ECA41B3EFE68,600FD18202670628,E5B1E23E5C2823FB,676C696A097C0400,37510460A877B8C4,F7398231DD85CFCF,809E3DB366BF384C,2907EB2870F768BD,5F4E17CFC07F6094,00004B8259DA7E84,BC71379D9DF19A46,4A553706FE4B1FC6,4AAA68550D141A6C,448A1EF4C3A7EB12,174989F55AB8D72A,537AE95FD3030287,5FEC7BC5219D5690,49FE98F84F95F7F8,44CB44C5F37D4C53,6F3324E97E21CE0B,13A2A7B3527F1F73,0000530EB3E3A69B diff --git a/core/src/test/java/org/bouncycastle/asn1/test/BiometricDataUnitTest.java b/core/src/test/java/org/bouncycastle/asn1/test/BiometricDataUnitTest.java index 9d883d03ee..f2f0db8aba 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/BiometricDataUnitTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/BiometricDataUnitTest.java @@ -9,10 +9,10 @@ import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.qualified.BiometricData; import org.bouncycastle.asn1.x509.qualified.TypeOfBiometricData; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.util.test.SimpleTest; public class BiometricDataUnitTest @@ -115,12 +115,12 @@ private void checkValues( if (sourceDataURI != null) { - if (!bd.getSourceDataUri().equals(sourceDataURI)) + if (!bd.getSourceDataUriIA5().equals(sourceDataURI)) { fail("data uris don't match."); } } - else if (bd.getSourceDataUri() != null) + else if (bd.getSourceDataUriIA5() != null) { fail("data uri found when none expected."); } diff --git a/core/src/test/java/org/bouncycastle/asn1/test/BitStringTest.java b/core/src/test/java/org/bouncycastle/asn1/test/BitStringTest.java index 569aaca16e..b863c069e1 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/BitStringTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/BitStringTest.java @@ -110,7 +110,7 @@ private void encodingCheck(byte[] derData, byte[] dlData) { fail("failed DL check"); } - ASN1BitString dl = DLBitString.getInstance(dlData); + ASN1BitString dl = ASN1BitString.getInstance(dlData); isTrue("DL test failed", dl instanceof DLBitString); if (!Arrays.areEqual(derData, ASN1Primitive.fromByteArray(dlData).getEncoded(ASN1Encoding.DER))) @@ -121,15 +121,15 @@ private void encodingCheck(byte[] derData, byte[] dlData) { /* * Allow this since getInstance should work for - * "an object that can be converted into [a DERBitString]". + * "an object that can be converted into [an ASN1BitString]". */ - DERBitString.getInstance(dlData); + ASN1BitString.getInstance(dlData); } catch (IllegalArgumentException e) { fail("failed DL encoding conversion"); } - ASN1BitString der = DERBitString.getInstance(derData); + ASN1BitString der = ASN1BitString.getInstance(derData); isTrue("DER test failed", der instanceof DERBitString); } diff --git a/core/src/test/java/org/bouncycastle/asn1/test/CertIDTest.java b/core/src/test/java/org/bouncycastle/asn1/test/CertIDTest.java new file mode 100644 index 0000000000..e162f0e9ac --- /dev/null +++ b/core/src/test/java/org/bouncycastle/asn1/test/CertIDTest.java @@ -0,0 +1,54 @@ +package org.bouncycastle.asn1.test; + +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.ocsp.CertID; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.util.BigIntegers; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.test.SimpleTest; + +public class CertIDTest + extends SimpleTest +{ + public String getName() + { + return "CertID"; + } + + public void performTest() + throws Exception + { + DEROctetString issuerAHash = new DEROctetString(Strings.toByteArray("IssuerAHash")); + DEROctetString issuerBHash = new DEROctetString(Strings.toByteArray("IssuerBHash")); + DEROctetString issuerAKeyHash = new DEROctetString(Strings.toByteArray("IssuerAKeyHash")); + DEROctetString issuerBKeyHash = new DEROctetString(Strings.toByteArray("IssuerBKeyHash")); + + CertID a = new CertID(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), issuerAHash, issuerAKeyHash, new ASN1Integer(BigIntegers.ONE)); + CertID b = new CertID(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE), issuerAHash, issuerAKeyHash, new ASN1Integer(BigIntegers.ONE)); + CertID c = new CertID(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, new DEROctetString(new byte[1])), issuerAHash, issuerAKeyHash, new ASN1Integer(BigIntegers.ONE)); + + isTrue(a.equals(a)); + isTrue(a.equals(b)); + isTrue(a.hashCode() == b.hashCode()); + isTrue(!a.equals(c)); + isTrue(a.hashCode() != c.hashCode()); + + b = new CertID(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), issuerAHash, issuerAKeyHash, new ASN1Integer(BigIntegers.TWO)); + isTrue(!a.equals(b)); + b = new CertID(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm), issuerAHash, issuerAKeyHash, new ASN1Integer(BigIntegers.ONE)); + isTrue(!a.equals(b)); + b = new CertID(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), issuerBHash, issuerAKeyHash, new ASN1Integer(BigIntegers.ONE)); + isTrue(!a.equals(b)); + b = new CertID(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), issuerAHash, issuerBKeyHash, new ASN1Integer(BigIntegers.ONE)); + isTrue(!a.equals(b)); + } + + public static void main( + String[] args) + { + runTest(new CertIDTest()); + } +} diff --git a/core/src/test/java/org/bouncycastle/asn1/test/CertificateTest.java b/core/src/test/java/org/bouncycastle/asn1/test/CertificateTest.java index 3bd89aef75..05a5e81d6d 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/CertificateTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/CertificateTest.java @@ -8,6 +8,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AttCertIssuer; import org.bouncycastle.asn1.x509.AttCertValidityPeriod; @@ -553,7 +554,37 @@ private void checkMalformed() // expected - anything else is not! } } - + + private void checkExtensions() + { + try + { + new Extensions((Extension[])null); + } + catch (IllegalArgumentException e) + { + isEquals(e.getMessage(), "extension array cannot be null or empty"); + } + + try + { + new Extensions(new Extension[0]); + } + catch (IllegalArgumentException e) + { + isEquals(e.getMessage(), "extension array cannot be null or empty"); + } + + try + { + Extensions.getInstance(new DERSequence()); + } + catch (IllegalArgumentException e) + { + isEquals(e.getMessage(), "empty extension sequence found"); + } + } + public void performTest() throws Exception { @@ -568,6 +599,7 @@ public void performTest() checkV1AttributeCertificate(9, attrCertv1); checkDudCertificate(); checkMalformed(); + checkExtensions(); } public static void main( diff --git a/core/src/test/java/org/bouncycastle/asn1/test/DERApplicationSpecificTest.java b/core/src/test/java/org/bouncycastle/asn1/test/DERApplicationSpecificTest.java index 8cc88e1268..6d72137fa5 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/DERApplicationSpecificTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/DERApplicationSpecificTest.java @@ -1,12 +1,11 @@ package org.bouncycastle.asn1.test; -import org.bouncycastle.asn1.ASN1ApplicationSpecific; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.ASN1VisibleString; import org.bouncycastle.asn1.BERTags; -import org.bouncycastle.asn1.DERApplicationSpecific; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERVisibleString; import org.bouncycastle.util.Arrays; @@ -56,7 +55,7 @@ private void testTaggedObject() // Type2 ::= [APPLICATION 3] IMPLICIT Type1 explicit = false; - DERApplicationSpecific type2 = new DERApplicationSpecific(explicit, 3, type1); + DERTaggedObject type2 = new DERTaggedObject(explicit, BERTags.APPLICATION, 3, type1); // type2.isConstructed() if (!Arrays.areEqual(Hex.decode("43054A6F6E6573"), type2.getEncoded())) { @@ -73,7 +72,7 @@ private void testTaggedObject() // Type4 ::= [APPLICATION 7] IMPLICIT Type3 explicit = false; - DERApplicationSpecific type4 = new DERApplicationSpecific(explicit, 7, type3); + DERTaggedObject type4 = new DERTaggedObject(explicit, BERTags.APPLICATION, 7, type3); if (!Arrays.areEqual(Hex.decode("670743054A6F6E6573"), type4.getEncoded())) { fail("ERROR: expected value doesn't match!"); @@ -94,32 +93,32 @@ public void performTest() { testTaggedObject(); - ASN1ApplicationSpecific appSpec = (ASN1ApplicationSpecific)ASN1Primitive.fromByteArray(sampleData); + ASN1TaggedObject appSpec = (ASN1TaggedObject)ASN1Primitive.fromByteArray(sampleData); - if (1 != appSpec.getApplicationTag()) + if (!appSpec.hasTag(BERTags.APPLICATION, 1)) { fail("wrong tag detected"); } ASN1Integer value = new ASN1Integer(9); - DERApplicationSpecific tagged = new DERApplicationSpecific(false, 3, value); + DERTaggedObject tagged = new DERTaggedObject(false, BERTags.APPLICATION, 3, value); if (!areEqual(impData, tagged.getEncoded())) { fail("implicit encoding failed"); } - ASN1Integer recVal = (ASN1Integer)tagged.getObject(BERTags.INTEGER); + ASN1Integer recVal = (ASN1Integer)tagged.getBaseUniversal(false, BERTags.INTEGER); if (!value.equals(recVal)) { fail("implicit read back failed"); } - ASN1ApplicationSpecific certObj = (ASN1ApplicationSpecific)ASN1Primitive.fromByteArray(certData); + ASN1TaggedObject certObj = (ASN1TaggedObject)ASN1Primitive.fromByteArray(certData); - if (!certObj.isConstructed() || certObj.getApplicationTag() != 33) + if (!certObj.hasTag(BERTags.APPLICATION, 33)) { fail("parsing of certificate data failed"); } @@ -132,8 +131,7 @@ public void performTest() } } - public static void main( - String[] args) + public static void main(String[] args) { runTest(new DERApplicationSpecificTest()); } diff --git a/core/src/test/java/org/bouncycastle/asn1/test/DERPrivateTest.java b/core/src/test/java/org/bouncycastle/asn1/test/DERPrivateTest.java index 48077bd0d6..904b76ce79 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/DERPrivateTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/DERPrivateTest.java @@ -88,7 +88,7 @@ public void performTest() ASN1TaggedObject privateSpec = (ASN1TaggedObject)ASN1Primitive.fromByteArray(sampleData); - if (BERTags.PRIVATE != privateSpec.getTagClass() || 1 != privateSpec.getTagNo()) + if (!privateSpec.hasTag(BERTags.PRIVATE, 1)) { fail("wrong tag detected"); } @@ -111,7 +111,7 @@ public void performTest() ASN1TaggedObject certObj = (ASN1TaggedObject)ASN1Primitive.fromByteArray(certData); - if (certObj.isExplicit() || BERTags.PRIVATE != certObj.getTagClass() || 33 != certObj.getTagNo()) + if (certObj.isExplicit() || !certObj.hasTag(BERTags.PRIVATE, 33)) { fail("parsing of certificate data failed"); } diff --git a/core/src/test/java/org/bouncycastle/asn1/test/DLExternalTest.java b/core/src/test/java/org/bouncycastle/asn1/test/DLExternalTest.java index 011d45282f..ecc8a3021d 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/DLExternalTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/DLExternalTest.java @@ -18,7 +18,6 @@ import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERUTF8String; -import org.bouncycastle.asn1.DLApplicationSpecific; import org.bouncycastle.asn1.DLBitString; import org.bouncycastle.asn1.DLExternal; import org.bouncycastle.asn1.DLSequence; @@ -163,23 +162,23 @@ private void checkRealDataExample(int encoding, DLExternal dle) DLSet msBindSet = (DLSet)msBind.getBaseUniversal(true, BERTags.SET); isEquals("check number of elements", 2, msBindSet.size()); - isEquals("check first element in set: " + msBindSet.getObjectAt(0).getClass(), DLApplicationSpecific.class.getName(), msBindSet.getObjectAt(0).getClass().getName()); + isEquals("check first element in set: " + msBindSet.getObjectAt(0).getClass(), DLTaggedObject.class.getName(), msBindSet.getObjectAt(0).getClass().getName()); - DLApplicationSpecific objectName = (DLApplicationSpecific)msBindSet.getObjectAt(0); - isEquals("check tag number", 0, objectName.getApplicationTag()); - isEquals("check application object: " + objectName.getEnclosedObject().getClass(), DLSequence.class.getName(), objectName.getEnclosedObject().getClass().getName()); - DLSequence objNameElems = (DLSequence)objectName.getEnclosedObject(); + DLTaggedObject objectName = (DLTaggedObject)msBindSet.getObjectAt(0); + isEquals("check tag number", true, objectName.hasTag(BERTags.APPLICATION, 0)); + isEquals("check application object: " + objectName.getBaseObject().toASN1Primitive().getClass(), DLSequence.class.getName(), objectName.getBaseObject().toASN1Primitive().getClass().getName()); + DLSequence objNameElems = (DLSequence)objectName.getBaseObject().toASN1Primitive(); isEquals("check number of elements", 4, objNameElems.size()); - isEquals("check first element in set: " + objNameElems.getObjectAt(0).getClass(), DLApplicationSpecific.class.getName(), objNameElems.getObjectAt(0).getClass().getName()); - DLApplicationSpecific objNameAppl = (DLApplicationSpecific)objNameElems.getObjectAt(0); - isEquals("check application number", 0, objNameAppl.getApplicationTag()); - isEquals("check application object: " + objNameAppl.getEnclosedObject().getClass(), DERPrintableString.class.getName(), objNameAppl.getEnclosedObject().getClass().getName()); - isEquals("check C", "de", ((DERPrintableString)objNameAppl.getEnclosedObject()).getString()); - isEquals("check second element in set: " + objNameElems.getObjectAt(1).getClass(), DLApplicationSpecific.class.getName(), objNameElems.getObjectAt(1).getClass().getName()); - objNameAppl = (DLApplicationSpecific)objNameElems.getObjectAt(1); - isEquals("check application number", 2, objNameAppl.getApplicationTag()); - isEquals("check application object: " + objNameAppl.getEnclosedObject().getClass(), DERPrintableString.class.getName(), objNameAppl.getEnclosedObject().getClass().getName()); - isEquals("check A", "viaT", ((DERPrintableString)objNameAppl.getEnclosedObject()).getString()); + isEquals("check first element in set: " + objNameElems.getObjectAt(0).getClass(), DLTaggedObject.class.getName(), objNameElems.getObjectAt(0).getClass().getName()); + DLTaggedObject objNameAppl = (DLTaggedObject)objNameElems.getObjectAt(0); + isEquals("check application number", true, objNameAppl.hasTag(BERTags.APPLICATION, 0)); + isEquals("check application object: " + objNameAppl.getBaseObject().toASN1Primitive().getClass(), DERPrintableString.class.getName(), objNameAppl.getBaseObject().toASN1Primitive().getClass().getName()); + isEquals("check C", "de", ((DERPrintableString)objNameAppl.getBaseObject().toASN1Primitive()).getString()); + isEquals("check second element in set: " + objNameElems.getObjectAt(1).getClass(), DLTaggedObject.class.getName(), objNameElems.getObjectAt(1).getClass().getName()); + objNameAppl = (DLTaggedObject)objNameElems.getObjectAt(1); + isEquals("check application number", true, objNameAppl.hasTag(BERTags.APPLICATION, 2)); + isEquals("check application object: " + objNameAppl.getBaseObject().toASN1Primitive().getClass(), DERPrintableString.class.getName(), objNameAppl.getBaseObject().toASN1Primitive().getClass().getName()); + isEquals("check A", "viaT", ((DERPrintableString)objNameAppl.getBaseObject().toASN1Primitive()).getString()); isEquals("check third element in set: " + objNameElems.getObjectAt(2).getClass(), DLTaggedObject.class.getName(), objNameElems.getObjectAt(2).getClass().getName()); DLTaggedObject objNameTagged = (DLTaggedObject)objNameElems.getObjectAt(2); isTrue("check tag", objNameTagged.hasContextTag(3)); @@ -215,12 +214,12 @@ private ASN1EncodableVector createRealDataExample(int encoding) vec.add(new DERUTF8String("example data representing the User Data of an OSI.6 ConnectP containing an MSBind with username and password")); ASN1EncodableVector objectNameVec = new ASN1EncodableVector(); - objectNameVec.add(new DLApplicationSpecific(0, new DERPrintableString("de"))); - objectNameVec.add(new DLApplicationSpecific(2, new DERPrintableString("viaT"))); + objectNameVec.add(new DLTaggedObject(BERTags.APPLICATION, 0, new DERPrintableString("de"))); + objectNameVec.add(new DLTaggedObject(BERTags.APPLICATION, 2, new DERPrintableString("viaT"))); objectNameVec.add(new DLTaggedObject(false, 3, new DEROctetString("Organization".getBytes("8859_1")))); objectNameVec.add(new DLTaggedObject(true, 5, new DLTaggedObject(false, 0, new DEROctetString("Common Name".getBytes("8859_1"))))); - DLApplicationSpecific objectName = new DLApplicationSpecific(0, new DLSequence(objectNameVec)); + DLTaggedObject objectName = new DLTaggedObject(BERTags.APPLICATION, 0, new DLSequence(objectNameVec)); DLTaggedObject password = new DLTaggedObject(true, 2, new DERIA5String("SomePassword")); ASN1EncodableVector msBindVec = new ASN1EncodableVector(); msBindVec.add(objectName); diff --git a/core/src/test/java/org/bouncycastle/asn1/test/EqualsAndHashCodeTest.java b/core/src/test/java/org/bouncycastle/asn1/test/EqualsAndHashCodeTest.java index 3f950735d4..bdfb74969a 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/EqualsAndHashCodeTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/EqualsAndHashCodeTest.java @@ -17,7 +17,6 @@ import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.BERTaggedObject; -import org.bouncycastle.asn1.DERApplicationSpecific; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERGeneralString; @@ -55,7 +54,6 @@ public TestResult perform() new BERSequence(new DERPrintableString("hello world")), new BERSet(new DERPrintableString("hello world")), new BERTaggedObject(0, new DERPrintableString("hello world")), - new DERApplicationSpecific(0, data), new DERBitString(data), new DERBMPString("hello world"), ASN1Boolean.getInstance(true), diff --git a/core/src/test/java/org/bouncycastle/asn1/test/GenerationTest.java b/core/src/test/java/org/bouncycastle/asn1/test/GenerationTest.java index 37908868ee..a90f144ecb 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/GenerationTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/GenerationTest.java @@ -13,8 +13,6 @@ import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.oiw.ElGamalParameter; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x500.X500Name; @@ -38,6 +36,8 @@ import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; +import org.bouncycastle.internal.asn1.oiw.ElGamalParameter; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; @@ -129,7 +129,7 @@ private AuthorityKeyIdentifier createAuthorityKeyId( v.add(genName); return new AuthorityKeyIdentifier( - info, GeneralNames.getInstance(new DERSequence(v)), BigInteger.valueOf(sNumber)); + getDigest(info), GeneralNames.getInstance(new DERSequence(v)), BigInteger.valueOf(sNumber)); } private void tbsV3CertGen() diff --git a/core/src/test/java/org/bouncycastle/asn1/test/GetInstanceTest.java b/core/src/test/java/org/bouncycastle/asn1/test/GetInstanceTest.java index 76d1153b0a..faff2ffb3c 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/GetInstanceTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/GetInstanceTest.java @@ -6,6 +6,7 @@ import java.util.Vector; import junit.framework.TestCase; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1GeneralizedTime; @@ -15,15 +16,12 @@ import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.ASN1UTCTime; import org.bouncycastle.asn1.DERBMPString; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERGeneralString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERNumericString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERPrintableString; -import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERT61String; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTF8String; @@ -33,10 +31,6 @@ import org.bouncycastle.asn1.cryptopro.GOST28147Parameters; import org.bouncycastle.asn1.cryptopro.GOST3410ParamSetParameters; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; - -import org.bouncycastle.asn1.misc.CAST5CBCParameters; -import org.bouncycastle.asn1.misc.IDEACBCPar; -import org.bouncycastle.asn1.mozilla.PublicKeyAndChallenge; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.CertID; import org.bouncycastle.asn1.ocsp.CertStatus; @@ -52,7 +46,6 @@ import org.bouncycastle.asn1.ocsp.Signature; import org.bouncycastle.asn1.ocsp.SingleResponse; import org.bouncycastle.asn1.ocsp.TBSRequest; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.AuthenticatedSafe; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; @@ -140,6 +133,9 @@ import org.bouncycastle.asn1.x9.DHValidationParms; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; +import org.bouncycastle.internal.asn1.misc.CAST5CBCParameters; +import org.bouncycastle.internal.asn1.misc.IDEACBCPar; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.util.Integers; import org.bouncycastle.util.encoders.Base64; @@ -363,7 +359,6 @@ public void testGetInstance() CAST5CBCParameters.getInstance(null); IDEACBCPar.getInstance(null); - PublicKeyAndChallenge.getInstance(null); BasicOCSPResponse.getInstance(null); BasicOCSPResponse.getInstance(null); @@ -482,7 +477,7 @@ public void testGetInstance() IssuerSerial.getInstance(null); IssuingDistributionPoint.getInstance(null); IssuingDistributionPoint.getInstance(null); - DERBitString.getInstance(null); + ASN1BitString.getInstance(null); v.clear(); v.add(generalSubtree); diff --git a/core/src/test/java/org/bouncycastle/asn1/test/InputStreamTest.java b/core/src/test/java/org/bouncycastle/asn1/test/InputStreamTest.java index 7ea40476ea..e3c1e5c59d 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/InputStreamTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/InputStreamTest.java @@ -76,7 +76,7 @@ public void performTest() } // TODO Test data has length issues too; needs to be reworked -// testWithByteArray(classCast1, "unknown object encountered: class org.bouncycastle.asn1.DLApplicationSpecific"); +// testWithByteArray(classCast1, "unknown object encountered: class org.bouncycastle.asn1.DLTaggedObjectParser"); testWithByteArray(classCast2, "unknown object encountered: class org.bouncycastle.asn1.DLTaggedObjectParser"); testWithByteArray(classCast3, "unknown object encountered in constructed OCTET STRING: class org.bouncycastle.asn1.DLTaggedObject"); diff --git a/core/src/test/java/org/bouncycastle/asn1/test/MiscTest.java b/core/src/test/java/org/bouncycastle/asn1/test/MiscTest.java index a2627dafcb..bc87ad3bdb 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/MiscTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/MiscTest.java @@ -12,11 +12,11 @@ import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERIA5String; -import org.bouncycastle.asn1.misc.CAST5CBCParameters; -import org.bouncycastle.asn1.misc.IDEACBCPar; -import org.bouncycastle.asn1.misc.NetscapeCertType; -import org.bouncycastle.asn1.misc.NetscapeRevocationURL; -import org.bouncycastle.asn1.misc.VerisignCzagExtension; +import org.bouncycastle.internal.asn1.misc.CAST5CBCParameters; +import org.bouncycastle.internal.asn1.misc.IDEACBCPar; +import org.bouncycastle.internal.asn1.misc.NetscapeCertType; +import org.bouncycastle.internal.asn1.misc.NetscapeRevocationURL; +import org.bouncycastle.internal.asn1.misc.VerisignCzagExtension; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; @@ -114,7 +114,7 @@ public void performTest() for (int i = 0; i != values.length; i++) { - aOut.writeObject(values[i].toASN1Primitive()); + aOut.writeObject(values[i]); } if (!areEqual(bOut.toByteArray(), data)) diff --git a/core/src/test/java/org/bouncycastle/asn1/test/NetscapeCertTypeTest.java b/core/src/test/java/org/bouncycastle/asn1/test/NetscapeCertTypeTest.java index e5aa96ecab..6238f170f8 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/NetscapeCertTypeTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/NetscapeCertTypeTest.java @@ -2,7 +2,7 @@ import java.io.IOException; -import org.bouncycastle.asn1.misc.NetscapeCertType; +import org.bouncycastle.internal.asn1.misc.NetscapeCertType; import org.bouncycastle.util.test.SimpleTest; public class NetscapeCertTypeTest diff --git a/core/src/test/java/org/bouncycastle/asn1/test/OIDTest.java b/core/src/test/java/org/bouncycastle/asn1/test/OIDTest.java index dc4bd6911d..64b53d8f8b 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/OIDTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/OIDTest.java @@ -1,13 +1,11 @@ package org.bouncycastle.asn1.test; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.util.encoders.Hex; @@ -64,6 +62,8 @@ private void validOidCheck( String oid) throws IOException { + isTrue(ASN1ObjectIdentifier.tryFromID(oid) != null); + ASN1ObjectIdentifier o = new ASN1ObjectIdentifier(oid); o = (ASN1ObjectIdentifier)ASN1Primitive.fromByteArray(o.getEncoded()); if (!o.getId().equals(oid)) @@ -75,6 +75,8 @@ private void validOidCheck( private void invalidOidCheck( String oid) { + isTrue(ASN1ObjectIdentifier.tryFromID(oid) == null); + try { new ASN1ObjectIdentifier(oid); @@ -105,6 +107,15 @@ private void onCheck(String stem, String test, boolean expected) } } + private void testIntern() + { + ASN1ObjectIdentifier oid1 = new ASN1ObjectIdentifier("2.2.100").intern(); + ASN1ObjectIdentifier oid2 = new ASN1ObjectIdentifier("2.2.100").intern(); + + isTrue(oid2 != null); + isEquals(oid1, oid2); + } + public void performTest() throws IOException { @@ -120,6 +131,18 @@ public void performTest() validOidCheck("1.1.127.32512.8323072.2130706432.545460846592.139637976727552.35747322042253312.9151314442816847872"); validOidCheck("1.2.123.12345678901.1.1.1"); validOidCheck("2.25.196556539987194312349856245628873852187.1"); + validOidCheck("0.0"); + validOidCheck("0.0.1"); + validOidCheck("0.39"); + validOidCheck("0.39.1"); + validOidCheck("1.0"); + validOidCheck("1.0.1"); + validOidCheck("1.39"); + validOidCheck("1.39.1"); + validOidCheck("2.0"); + validOidCheck("2.0.1"); + validOidCheck("2.40"); + validOidCheck("2.40.1"); invalidOidCheck("0"); invalidOidCheck("1"); @@ -140,6 +163,14 @@ public void performTest() invalidOidCheck(".12.345.77.234."); invalidOidCheck("1.2.3.4.A.5"); invalidOidCheck("1,2"); + invalidOidCheck("0.40"); + invalidOidCheck("0.40.1"); + invalidOidCheck("0.100"); + invalidOidCheck("0.100.1"); + invalidOidCheck("1.40"); + invalidOidCheck("1.40.1"); + invalidOidCheck("1.100"); + invalidOidCheck("1.100.1"); branchCheck("1.1", "2.2"); @@ -151,6 +182,11 @@ public void performTest() onCheck("1.12", "1.1.2", false); onCheck("1.1", "1.1.1", true); onCheck("1.1", "1.1.2", true); + onCheck("1.2.3.4.5.6", "1.2.3.4.5.6", false); + onCheck("1.2.3.4.5.6", "1.2.3.4.5.6.7", true); + onCheck("1.2.3.4.5.6", "1.2.3.4.5.6.7.8", true); + + testIntern(); } public static void main( diff --git a/core/src/test/java/org/bouncycastle/asn1/test/ObjectIdentifierTest.java b/core/src/test/java/org/bouncycastle/asn1/test/ObjectIdentifierTest.java index 9f74425b58..f5e00d2f9a 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/ObjectIdentifierTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/ObjectIdentifierTest.java @@ -15,6 +15,16 @@ public String getName() public void performTest() throws Exception { + try + { + ASN1ObjectIdentifier.fromContents(new byte[0]); + fail("no exception"); + } + catch (IllegalArgumentException e) + { + isEquals("invalid OID contents", e.getMessage()); + } + // exercise the object cache for (int i = 0; i < 100; i++) { diff --git a/core/src/test/java/org/bouncycastle/asn1/test/PKCS10Test.java b/core/src/test/java/org/bouncycastle/asn1/test/PKCS10Test.java index 4d860165df..d959901942 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/PKCS10Test.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/PKCS10Test.java @@ -4,7 +4,6 @@ import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTestResult; @@ -46,7 +45,7 @@ public TestResult pkcs10Test( ByteArrayInputStream bIn = new ByteArrayInputStream(req); ASN1InputStream aIn = new ASN1InputStream(bIn); - CertificationRequest r = new CertificationRequest((ASN1Sequence)aIn.readObject()); + CertificationRequest r = CertificationRequest.getInstance(aIn.readObject()); byte[] bytes = r.getEncoded(ASN1Encoding.DER); diff --git a/core/src/test/java/org/bouncycastle/asn1/test/RegressionTest.java b/core/src/test/java/org/bouncycastle/asn1/test/RegressionTest.java index b42a20f200..0cdcfbf37a 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/RegressionTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/RegressionTest.java @@ -55,7 +55,8 @@ public class RegressionTest new DLExternalTest(), new KMACParamsTest(), new DERPrivateTest(), - new X509AltTest() + new X509AltTest(), + new CertIDTest() }; public static void main(String[] args) diff --git a/core/src/test/java/org/bouncycastle/asn1/test/RelativeOIDTest.java b/core/src/test/java/org/bouncycastle/asn1/test/RelativeOIDTest.java index a35fa0565c..390cfb65d8 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/RelativeOIDTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/RelativeOIDTest.java @@ -52,6 +52,8 @@ private void recodeCheck(String oid, byte[] enc) throws IOException private void checkValid(String oid) throws IOException { + isTrue(ASN1RelativeOID.tryFromID(oid) != null); + ASN1RelativeOID o = new ASN1RelativeOID(oid); o = (ASN1RelativeOID)ASN1Primitive.fromByteArray(o.getEncoded()); if (!o.getId().equals(oid)) @@ -62,6 +64,8 @@ private void checkValid(String oid) throws IOException private void checkInvalid(String oid) { + isTrue(ASN1RelativeOID.tryFromID(oid) == null); + try { new ASN1RelativeOID(oid); diff --git a/core/src/test/java/org/bouncycastle/asn1/test/StringTest.java b/core/src/test/java/org/bouncycastle/asn1/test/StringTest.java index 736ceac7f6..50c9535ad5 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/StringTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/StringTest.java @@ -1,6 +1,7 @@ package org.bouncycastle.asn1.test; import java.io.IOException; +import java.io.UnsupportedEncodingException; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1String; @@ -86,17 +87,25 @@ public void performTest() } byte[] t61Bytes = new byte[] { -1, -2, -3, -4, -5, -6, -7, -8 }; - String t61String = new String(t61Bytes, "iso-8859-1"); - ASN1T61String t61 = new DERT61String(Strings.fromByteArray(t61Bytes)); - if (!t61.getString().equals(t61String)) + try { - fail("DERT61String.getString() result incorrect"); + String t61String = new String(t61Bytes, "iso-8859-1"); + ASN1T61String t61 = new DERT61String(Strings.fromByteArray(t61Bytes)); + + if (!t61.getString().equals(t61String)) + { + fail("DERT61String.getString() result incorrect"); + } + + if (!t61.toString().equals(t61String)) + { + fail("DERT61String.toString() result incorrect"); + } } - - if (!t61.toString().equals(t61String)) + catch (UnsupportedEncodingException e) { - fail("DERT61String.toString() result incorrect"); + // ignore test } char[] shortChars = new char[] { 'a', 'b', 'c', 'd', 'e'}; diff --git a/core/src/test/java/org/bouncycastle/asn1/test/X500NameTest.java b/core/src/test/java/org/bouncycastle/asn1/test/X500NameTest.java index 5778a1ab23..e05b9ccb73 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/X500NameTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/X500NameTest.java @@ -7,7 +7,6 @@ import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1IA5String; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1PrintableString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; @@ -46,8 +45,8 @@ public class X500NameTest "C=0,O=1,OU=2,T=3,CN=4,SERIALNUMBER=5,STREET=6,SERIALNUMBER=7,L=8,ST=9,SURNAME=10,GIVENNAME=11,INITIALS=12," + "GENERATION=13,UniqueIdentifier=14,BusinessCategory=15,PostalCode=16,DN=17,Pseudonym=18,PlaceOfBirth=19," + "Gender=20,CountryOfCitizenship=21,CountryOfResidence=22,NameAtBirth=23,PostalAddress=24,2.5.4.54=25," + - "TelephoneNumber=26,Name=27,E=28,unstructuredName=29,unstructuredAddress=30,E=31,DC=32,UID=33" - + "TelephoneNumber=26,Name=27,E=28,unstructuredName=29,unstructuredAddress=30,E=31,DC=32,UID=33", + "C=DE,L=Berlin,O=Wohnungsbaugenossenschaft \\\"Humboldt-Universität\\\" eG,CN=transfer.wbg-hub.de" }; String[] hexSubjects = @@ -67,7 +66,7 @@ public String getName() private static X500Name fromBytes(byte[] bytes) throws IOException { - return X500Name.getInstance(ASN1Primitive.fromByteArray(bytes)); + return X500Name.getInstance(bytes); } private ASN1Encodable createEntryValue(ASN1ObjectIdentifier oid, String value) @@ -78,9 +77,9 @@ private ASN1Encodable createEntryValue(ASN1ObjectIdentifier oid, String value) X500Name name = builder.build(); - ASN1Sequence seq = (ASN1Sequence)name.toASN1Primitive(); + ASN1Sequence seq = ASN1Sequence.getInstance(name.toASN1Primitive()); ASN1Set set = ASN1Set.getInstance(seq.getObjectAt(0).toASN1Primitive()); - seq = (ASN1Sequence)set.getObjectAt(0); + seq = ASN1Sequence.getInstance(set.getObjectAt(0)); return seq.getObjectAt(1); } @@ -93,9 +92,9 @@ private ASN1Encodable createEntryValueFromString(ASN1ObjectIdentifier oid, Strin X500Name name = new X500Name(builder.build().toString()); - ASN1Sequence seq = (ASN1Sequence)name.toASN1Primitive(); + ASN1Sequence seq = ASN1Sequence.getInstance(name.toASN1Primitive()); ASN1Set set = ASN1Set.getInstance(seq.getObjectAt(0).toASN1Primitive()); - seq = (ASN1Sequence)set.getObjectAt(0); + seq = ASN1Sequence.getInstance(set.getObjectAt(0)); return seq.getObjectAt(1); } @@ -150,7 +149,8 @@ public void performTest() throws Exception { ietfUtilsTest(); - + bogusEqualsTest(); + testEncodingPrintableString(BCStyle.C, "AU"); testEncodingPrintableString(BCStyle.SERIALNUMBER, "123456"); testEncodingPrintableString(BCStyle.DN_QUALIFIER, "123456"); @@ -334,7 +334,7 @@ public void performTest() for (int i = 0; i != subjects.length; i++) { X500Name name = new X500Name(subjects[i]); - name = X500Name.getInstance(ASN1Primitive.fromByteArray(name.getEncoded())); + name = fromBytes(name.getEncoded()); if (!name.toString().equals(subjects[i])) { fail("failed regeneration test " + i + " got: " + name.toString() + " expected " + subjects[i]); @@ -344,10 +344,10 @@ public void performTest() for (int i = 0; i < hexSubjects.length; i += 2) { X500Name name = new X500Name(hexSubjects[i]); - name = X500Name.getInstance(ASN1Primitive.fromByteArray(name.getEncoded())); + name = fromBytes(name.getEncoded()); if (!name.toString().equals(hexSubjects[i + 1])) { - fail("failed hex regeneration test " + i + " got: " + name.toString() + " expected " + subjects[i]); + fail("failed hex regeneration test " + i + " got: " + name.toString() + " expected " + hexSubjects[i + 1]); } } @@ -404,8 +404,8 @@ public void performTest() n1 = new X500Name("2.5.4.5=#130138,CN=SSC Class 3 CA,O=UAB Skaitmeninio sertifikavimo centras,C=LT"); n2 = new X500Name("SERIALNUMBER=#130138,CN=SSC Class 3 CA,O=UAB Skaitmeninio sertifikavimo centras,C=LT"); - n3 = X500Name.getInstance(ASN1Primitive.fromByteArray(Hex.decode("3063310b3009060355040613024c54312f302d060355040a1326" - + "55414220536b6169746d656e696e696f20736572746966696b6176696d6f2063656e74726173311730150603550403130e53534320436c6173732033204341310a30080603550405130138"))); + n3 = fromBytes(Hex.decode("3063310b3009060355040613024c54312f302d060355040a1326" + + "55414220536b6169746d656e696e696f20736572746966696b6176696d6f2063656e74726173311730150603550403130e53534320436c6173732033204341310a30080603550405130138")); equalityTest(n1, n2); equalityTest(n2, n3); @@ -663,6 +663,10 @@ public void performTest() { fail("padded equality test failed"); } + + isTrue(BCStyle.INSTANCE.attrNameToOID("jurisdictionCountry").equals(BCStyle.JURISDICTION_C)); + isTrue(BCStyle.INSTANCE.attrNameToOID("jurisdictionState").equals(BCStyle.JURISDICTION_ST)); + isTrue(BCStyle.INSTANCE.attrNameToOID("jurisdictionLocality").equals(BCStyle.JURISDICTION_L)); } private String getValue(RDN vl) @@ -676,6 +680,20 @@ private void ietfUtilsTest() IETFUtils.valueToString(new DERUTF8String(" ")); } + private void bogusEqualsTest() + throws Exception + { + try + { + new X500Name("CN=foo=bar"); + fail("no exception"); + } + catch (IllegalArgumentException e) + { + isEquals("badly formatted directory string", e.getMessage()); + } + } + public static class DNQStyle extends BCStyle { @@ -714,9 +732,8 @@ private void compositeTest() // composite test // byte[] enc = Hex.decode("305e310b300906035504061302415531283026060355040a0c1f546865204c6567696f6e206f662074686520426f756e637920436173746c653125301006035504070c094d656c626f75726e653011060355040b0c0a4173636f742056616c65"); - ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(enc)); - X500Name n = X500Name.getInstance(aIn.readObject()); + X500Name n = fromBytes(enc); if (!n.toString().equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne+OU=Ascot Vale")) { @@ -736,12 +753,7 @@ private void compositeTest() n = new X500Name("C=AU, O=The Legion of the Bouncy Castle, L=Melbourne + OU=Ascot Vale"); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - ASN1OutputStream aOut = ASN1OutputStream.create(bOut); - - aOut.writeObject(n); - - byte[] enc2 = bOut.toByteArray(); + byte[] enc2 = n.getEncoded(); if (!Arrays.areEqual(enc, enc2)) { @@ -753,7 +765,7 @@ private void compositeTest() // n = new X500Name("C=CH,O=,OU=dummy,CN=mail@dummy.com"); - n = X500Name.getInstance(ASN1Object.fromByteArray(n.getEncoded())); + n = fromBytes(n.getEncoded()); } */ private void equalityTest(X500Name name1, X500Name name2) @@ -769,7 +781,6 @@ private void equalityTest(X500Name name1, X500Name name2) } } - public static void main( String[] args) { diff --git a/core/src/test/java/org/bouncycastle/asn1/test/X509NameTest.java b/core/src/test/java/org/bouncycastle/asn1/test/X509NameTest.java index c1f40770ec..9d5880cf28 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/X509NameTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/X509NameTest.java @@ -323,10 +323,10 @@ public void performTest() for (int i = 0; i != subjects.length; i++) { X509Name name = new X509Name(subjects[i]); - name = X509Name.getInstance(ASN1Primitive.fromByteArray(name.getEncoded())); + name = fromBytes(name.getEncoded()); if (!name.toString().equals(subjects[i])) { - fail("failed regeneration test " + i + " got " + name.toString()); + fail("failed regeneration test " + i + " got: " + name.toString() + " expected " + subjects[i]); } } diff --git a/core/src/test/java/org/bouncycastle/asn1/test/X9Test.java b/core/src/test/java/org/bouncycastle/asn1/test/X9Test.java index 64749c191c..7b686d67ab 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/X9Test.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/X9Test.java @@ -165,7 +165,7 @@ public String getName() { return "X9"; } - + public static void main( String[] args) { diff --git a/core/src/test/java/org/bouncycastle/crypto/agreement/test/JPAKEParticipantTest.java b/core/src/test/java/org/bouncycastle/crypto/agreement/test/JPAKEParticipantTest.java index c6ecba22f3..33ce2f4408 100644 --- a/core/src/test/java/org/bouncycastle/crypto/agreement/test/JPAKEParticipantTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/agreement/test/JPAKEParticipantTest.java @@ -24,7 +24,7 @@ public void testConstruction() { JPAKEPrimeOrderGroup group = JPAKEPrimeOrderGroups.SUN_JCE_1024; SecureRandom random = new SecureRandom(); - Digest digest = new SHA256Digest(); + Digest digest = SHA256Digest.newInstance(); String participantId = "participantId"; char[] password = "password".toCharArray(); diff --git a/core/src/test/java/org/bouncycastle/crypto/agreement/test/JPAKEUtilTest.java b/core/src/test/java/org/bouncycastle/crypto/agreement/test/JPAKEUtilTest.java index a761ac7c48..41a7abd866 100644 --- a/core/src/test/java/org/bouncycastle/crypto/agreement/test/JPAKEUtilTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/agreement/test/JPAKEUtilTest.java @@ -88,7 +88,7 @@ public void testValidateMacTag() JPAKEPrimeOrderGroup pg1 = JPAKEPrimeOrderGroups.SUN_JCE_1024; SecureRandom random = new SecureRandom(); - Digest digest = new SHA256Digest(); + Digest digest = SHA256Digest.newInstance(); BigInteger x1 = JPAKEUtil.generateX1(pg1.getQ(), random); BigInteger x2 = JPAKEUtil.generateX2(pg1.getQ(), random); @@ -159,7 +159,7 @@ public void testValidateZeroKnowledgeProof() JPAKEPrimeOrderGroup pg1 = JPAKEPrimeOrderGroups.SUN_JCE_1024; SecureRandom random = new SecureRandom(); - Digest digest1 = new SHA256Digest(); + Digest digest1 = SHA256Digest.newInstance(); BigInteger x1 = JPAKEUtil.generateX1(pg1.getQ(), random); BigInteger gx1 = JPAKEUtil.calculateGx(pg1.getP(), pg1.getG(), x1); diff --git a/core/src/test/java/org/bouncycastle/crypto/prng/test/CTRDRBGTest.java b/core/src/test/java/org/bouncycastle/crypto/prng/test/CTRDRBGTest.java index 4e06286c25..aa12532df0 100644 --- a/core/src/test/java/org/bouncycastle/crypto/prng/test/CTRDRBGTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/prng/test/CTRDRBGTest.java @@ -142,7 +142,7 @@ private DRBGTestVector[] createTestVectorData() .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBC"), new DRBGTestVector( - new AESEngine(), 128, + AESEngine.newInstance(), 128, new Bit256EntropyProvider().get(256), false, "2021222324252627", @@ -154,7 +154,7 @@ private DRBGTestVector[] createTestVectorData() } ), new DRBGTestVector( - new AESEngine(), 128, + AESEngine.newInstance(), 128, new Bit256EntropyProvider().get(256), false, "2021222324252627", @@ -168,7 +168,7 @@ private DRBGTestVector[] createTestVectorData() .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"), new DRBGTestVector( - new AESEngine(), 128, + AESEngine.newInstance(), 128, new Bit256EntropyProvider().get(256), false, "2021222324252627", @@ -181,7 +181,7 @@ private DRBGTestVector[] createTestVectorData() ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F"), new DRBGTestVector( - new AESEngine(), 128, + AESEngine.newInstance(), 128, new Bit256EntropyProvider().get(256), true, "2021222324252627", @@ -193,7 +193,7 @@ private DRBGTestVector[] createTestVectorData() } ), new DRBGTestVector( - new AESEngine(), 128, + AESEngine.newInstance(), 128, new Bit256EntropyProvider().get(256), true, "2021222324252627", @@ -207,7 +207,7 @@ private DRBGTestVector[] createTestVectorData() .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"), new DRBGTestVector( - new AESEngine(), 128, + AESEngine.newInstance(), 128, new Bit256EntropyProvider().get(256), true, "2021222324252627", @@ -220,7 +220,7 @@ private DRBGTestVector[] createTestVectorData() ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F"), new DRBGTestVector( - new AESEngine(), 192, + AESEngine.newInstance(), 192, new Bit320EntropyProvider().get(320), false, "202122232425262728292A2B", @@ -233,7 +233,7 @@ private DRBGTestVector[] createTestVectorData() ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F6061626364656667"), new DRBGTestVector( - new AESEngine(), 192, + AESEngine.newInstance(), 192, new Bit320EntropyProvider().get(320), true, "202122232425262728292A2B", @@ -246,7 +246,7 @@ private DRBGTestVector[] createTestVectorData() ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F6061626364656667"), new DRBGTestVector( - new AESEngine(), 256, + AESEngine.newInstance(), 256, new Bit384EntropyProvider().get(384), false, "202122232425262728292A2B2C2D2E2F", @@ -261,7 +261,7 @@ private DRBGTestVector[] createTestVectorData() .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"), new DRBGTestVector( - new AESEngine(), 256, + AESEngine.newInstance(), 256, new Bit384EntropyProvider().get(384), true, "202122232425262728292A2B2C2D2E2F", @@ -275,7 +275,7 @@ private DRBGTestVector[] createTestVectorData() .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"), new DRBGTestVector( - new AESEngine(), 256, + AESEngine.newInstance(), 256, new Bit384EntropyProvider().get(384), true, "202122232425262728292A2B2C2D2E2F", @@ -288,7 +288,7 @@ private DRBGTestVector[] createTestVectorData() ) .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F"), new DRBGTestVector( - new AESEngine(), 256, + AESEngine.newInstance(), 256, new Bit384EntropyProvider().get(384), true, "202122232425262728292A2B2C2D2E2F", @@ -303,7 +303,7 @@ private DRBGTestVector[] createTestVectorData() .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"), new DRBGTestVector( - new AESEngine(), 256, + AESEngine.newInstance(), 256, new Bit384EntropyProvider().get(384), true, "202122232425262728292A2B2C2D2E2F", @@ -369,7 +369,7 @@ public void performTest() SP80090DRBG d; try { - d = new CTRSP800DRBG(new AESEngine(), 256, 256, new Bit232EntropyProvider().get(128), null, null); + d = new CTRSP800DRBG(AESEngine.newInstance(), 256, 256, new Bit232EntropyProvider().get(128), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) @@ -408,7 +408,7 @@ public void performTest() try { - d = new CTRSP800DRBG(new AESEngine(), 192, 256, new Bit232EntropyProvider().get(232), null, null); + d = new CTRSP800DRBG(AESEngine.newInstance(), 192, 256, new Bit232EntropyProvider().get(232), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) diff --git a/core/src/test/java/org/bouncycastle/crypto/prng/test/HMacDRBGTest.java b/core/src/test/java/org/bouncycastle/crypto/prng/test/HMacDRBGTest.java index 3af6d0ed71..afba06f777 100644 --- a/core/src/test/java/org/bouncycastle/crypto/prng/test/HMacDRBGTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/prng/test/HMacDRBGTest.java @@ -103,7 +103,7 @@ private DRBGTestVector[] createTestVectorData() .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), new DRBGTestVector( - new SHA256Digest(), + SHA256Digest.newInstance(), new SHA256EntropyProvider().get(440), false, "2021222324252627", @@ -118,7 +118,7 @@ private DRBGTestVector[] createTestVectorData() "4D33CD070CA7CD0C5608DBA8B885654639DE2187B74CB263" }), new DRBGTestVector( - new SHA256Digest(), + SHA256Digest.newInstance(), new SHA256EntropyProvider().get(440), true, "2021222324252627", @@ -417,7 +417,7 @@ public void performTest() SP80090DRBG d; try { - d = new HMacSP800DRBG(new HMac(new SHA256Digest()), 256, new SHA256EntropyProvider().get(128), null, null); + d = new HMacSP800DRBG(new HMac(SHA256Digest.newInstance()), 256, new SHA256EntropyProvider().get(128), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) diff --git a/core/src/test/java/org/bouncycastle/crypto/prng/test/HashDRBGTest.java b/core/src/test/java/org/bouncycastle/crypto/prng/test/HashDRBGTest.java index 2ffd5c5b9e..d89ebf8513 100644 --- a/core/src/test/java/org/bouncycastle/crypto/prng/test/HashDRBGTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/prng/test/HashDRBGTest.java @@ -103,7 +103,7 @@ private DRBGTestVector[] createTestVectorData() .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), new DRBGTestVector( - new SHA256Digest(), + SHA256Digest.newInstance(), new SHA256EntropyProvider().get(440), false, "2021222324252627", @@ -119,7 +119,7 @@ private DRBGTestVector[] createTestVectorData() } ), new DRBGTestVector( - new SHA256Digest(), + SHA256Digest.newInstance(), new SHA256EntropyProvider().get(440), true, "2021222324252627", @@ -377,7 +377,7 @@ public void performTest() SP80090DRBG d; try { - d = new HashSP800DRBG(new SHA256Digest(), 256, new SHA256EntropyProvider().get(128), null, null); + d = new HashSP800DRBG(SHA256Digest.newInstance(), 256, new SHA256EntropyProvider().get(128), null, null); fail("no exception thrown"); } catch (IllegalArgumentException e) diff --git a/core/src/test/java/org/bouncycastle/crypto/prng/test/SP800RandomTest.java b/core/src/test/java/org/bouncycastle/crypto/prng/test/SP800RandomTest.java index 70f1721a17..847d38820d 100644 --- a/core/src/test/java/org/bouncycastle/crypto/prng/test/SP800RandomTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/prng/test/SP800RandomTest.java @@ -258,15 +258,15 @@ private void testNames() isEquals("CTR-DRBG-3KEY-TDES", rBuild.buildCTR(new DESedeEngine(), 168, Hex.decode("20212223242526"), false).getAlgorithm()); - isEquals("CTR-DRBG-AES128", rBuild.buildCTR(new AESEngine(), 128, Hex.decode("20212223242526"), false).getAlgorithm()); - isEquals("CTR-DRBG-AES192", rBuild.buildCTR(new AESEngine(), 192, Hex.decode("20212223242526"), false).getAlgorithm()); - isEquals("CTR-DRBG-AES256", rBuild.buildCTR(new AESEngine(), 256, Hex.decode("20212223242526"), false).getAlgorithm()); + isEquals("CTR-DRBG-AES128", rBuild.buildCTR(AESEngine.newInstance(), 128, Hex.decode("20212223242526"), false).getAlgorithm()); + isEquals("CTR-DRBG-AES192", rBuild.buildCTR(AESEngine.newInstance(), 192, Hex.decode("20212223242526"), false).getAlgorithm()); + isEquals("CTR-DRBG-AES256", rBuild.buildCTR(AESEngine.newInstance(), 256, Hex.decode("20212223242526"), false).getAlgorithm()); - isEquals("HASH-DRBG-SHA256", rBuild.buildHash(new SHA256Digest(), Hex.decode("20212223242526"), false).getAlgorithm()); + isEquals("HASH-DRBG-SHA256", rBuild.buildHash(SHA256Digest.newInstance(), Hex.decode("20212223242526"), false).getAlgorithm()); isEquals("HASH-DRBG-SHA384", rBuild.buildHash(new SHA384Digest(), Hex.decode("20212223242526"), false).getAlgorithm()); isEquals("HASH-DRBG-SHA512", rBuild.buildHash(new SHA512Digest(), Hex.decode("20212223242526"), false).getAlgorithm()); - isEquals("HMAC-DRBG-SHA256", rBuild.buildHMAC(new HMac(new SHA256Digest()), Hex.decode("20212223242526"), false).getAlgorithm()); + isEquals("HMAC-DRBG-SHA256", rBuild.buildHMAC(new HMac(SHA256Digest.newInstance()), Hex.decode("20212223242526"), false).getAlgorithm()); isEquals("HMAC-DRBG-SHA384", rBuild.buildHMAC(new HMac(new SHA384Digest()), Hex.decode("20212223242526"), false).getAlgorithm()); isEquals("HMAC-DRBG-SHA512", rBuild.buildHMAC(new HMac(new SHA512Digest()), Hex.decode("20212223242526"), false).getAlgorithm()); } diff --git a/core/src/test/java/org/bouncycastle/crypto/prng/test/X931Test.java b/core/src/test/java/org/bouncycastle/crypto/prng/test/X931Test.java index 3cfa3adc83..5613e37c2c 100644 --- a/core/src/test/java/org/bouncycastle/crypto/prng/test/X931Test.java +++ b/core/src/test/java/org/bouncycastle/crypto/prng/test/X931Test.java @@ -32,7 +32,7 @@ private X931TestVector[] createTestVectorData() return new X931TestVector[] { new X931TestVector( - new AESEngine(), + AESEngine.newInstance(), new AES128EntropyProvider(), "f7d36762b9915f1ed585eb8e91700eb2", "259e67249288597a4d61e7c0e690afae", diff --git a/core/src/test/java/org/bouncycastle/crypto/test/AESTest.java b/core/src/test/java/org/bouncycastle/crypto/test/AESTest.java index f8234db5e1..e06c33bd2e 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/AESTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/AESTest.java @@ -1,18 +1,23 @@ package org.bouncycastle.crypto.test; +import java.nio.charset.StandardCharsets; import java.security.SecureRandom; +import java.util.Random; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.DefaultBufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.CFBBlockCipher; +import org.bouncycastle.crypto.modes.CTRModeCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; import org.bouncycastle.crypto.modes.SICBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -36,85 +41,85 @@ public class AESTest static SimpleTest[] tests = { - new BlockCipherVectorTest(0, new AESEngine(), + new BlockCipherVectorTest(0, AESEngine.newInstance(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), - new BlockCipherVectorTest(1, new AESEngine(), + new BlockCipherVectorTest(1, AESEngine.newInstance(), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), - new BlockCipherMonteCarloTest(2, 10000, new AESEngine(), + new BlockCipherMonteCarloTest(2, 10000, AESEngine.newInstance(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), - new BlockCipherMonteCarloTest(3, 10000, new AESEngine(), + new BlockCipherMonteCarloTest(3, 10000, AESEngine.newInstance(), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), - new BlockCipherVectorTest(4, new AESEngine(), + new BlockCipherVectorTest(4, AESEngine.newInstance(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), - new BlockCipherMonteCarloTest(5, 10000, new AESEngine(), + new BlockCipherMonteCarloTest(5, 10000, AESEngine.newInstance(), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), - new BlockCipherVectorTest(6, new AESEngine(), + new BlockCipherVectorTest(6, AESEngine.newInstance(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), - new BlockCipherMonteCarloTest(7, 10000, new AESEngine(), + new BlockCipherMonteCarloTest(7, 10000, AESEngine.newInstance(), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), - new BlockCipherVectorTest(8, new AESEngine(), + new BlockCipherVectorTest(8, AESEngine.newInstance(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), - new BlockCipherVectorTest(9, new AESEngine(), + new BlockCipherVectorTest(9, AESEngine.newInstance(), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), - new BlockCipherMonteCarloTest(10, 10000, new AESEngine(), + new BlockCipherMonteCarloTest(10, 10000, AESEngine.newInstance(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), - new BlockCipherMonteCarloTest(11, 10000, new AESEngine(), + new BlockCipherMonteCarloTest(11, 10000, AESEngine.newInstance(), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), - new BlockCipherVectorTest(12, new AESEngine(), + new BlockCipherVectorTest(12, AESEngine.newInstance(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), - new BlockCipherMonteCarloTest(13, 10000, new AESEngine(), + new BlockCipherMonteCarloTest(13, 10000, AESEngine.newInstance(), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), - new BlockCipherVectorTest(14, new AESEngine(), + new BlockCipherVectorTest(14, AESEngine.newInstance(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), - new BlockCipherMonteCarloTest(15, 10000, new AESEngine(), + new BlockCipherMonteCarloTest(15, 10000, AESEngine.newInstance(), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), - new BlockCipherVectorTest(16, new AESEngine(), + new BlockCipherVectorTest(16, AESEngine.newInstance(), new KeyParameter(Hex.decode("80000000000000000000000000000000")), "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), - new BlockCipherVectorTest(17, new AESEngine(), + new BlockCipherVectorTest(17, AESEngine.newInstance(), new KeyParameter(Hex.decode("00000000000000000000000000000080")), "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), - new BlockCipherMonteCarloTest(18, 10000, new AESEngine(), + new BlockCipherMonteCarloTest(18, 10000, AESEngine.newInstance(), new KeyParameter(Hex.decode("00000000000000000000000000000000")), "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), - new BlockCipherMonteCarloTest(19, 10000, new AESEngine(), + new BlockCipherMonteCarloTest(19, 10000, AESEngine.newInstance(), new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), - new BlockCipherVectorTest(20, new AESEngine(), + new BlockCipherVectorTest(20, AESEngine.newInstance(), new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), - new BlockCipherMonteCarloTest(21, 10000, new AESEngine(), + new BlockCipherMonteCarloTest(21, 10000, AESEngine.newInstance(), new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), - new BlockCipherVectorTest(22, new AESEngine(), + new BlockCipherVectorTest(22, AESEngine.newInstance(), new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), - new BlockCipherMonteCarloTest(23, 10000, new AESEngine(), + new BlockCipherMonteCarloTest(23, 10000, AESEngine.newInstance(), new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168") }; - private BlockCipher _engine = new AESEngine(); + private BlockCipher _engine = AESEngine.newInstance(); public AESTest() { - super(tests, new AESEngine(), new KeyParameter(new byte[16])); + super(tests, AESEngine.newInstance(), new KeyParameter(new byte[16])); } public String getName() @@ -125,7 +130,7 @@ public String getName() private void testNullSIC() throws InvalidCipherTextException { - BufferedBlockCipher b = new BufferedBlockCipher(new SICBlockCipher(new AESEngine())); + BufferedBlockCipher b = new DefaultBufferedBlockCipher(SICBlockCipher.newInstance(AESEngine.newInstance())); KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); b.init(true, new ParametersWithIV(kp, new byte[16])); @@ -156,7 +161,7 @@ private void testNullSIC() private void testNullCBC() throws InvalidCipherTextException { - BufferedBlockCipher b = new BufferedBlockCipher(new CBCBlockCipher(new AESEngine())); + BufferedBlockCipher b = new DefaultBufferedBlockCipher(new CBCBlockCipher(AESEngine.newInstance())); KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); b.init(true, new ParametersWithIV(kp, new byte[16])); @@ -187,7 +192,7 @@ private void testNullCBC() private void testNullOFB() throws InvalidCipherTextException { - BufferedBlockCipher b = new BufferedBlockCipher(new OFBBlockCipher(new AESEngine(), 128)); + BufferedBlockCipher b = new DefaultBufferedBlockCipher(new OFBBlockCipher(AESEngine.newInstance(), 128)); KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); b.init(true, new ParametersWithIV(kp, new byte[16])); @@ -218,7 +223,7 @@ private void testNullOFB() private void testNullCFB() throws InvalidCipherTextException { - BufferedBlockCipher b = new BufferedBlockCipher(new CFBBlockCipher(new AESEngine(), 128)); + BufferedBlockCipher b = new DefaultBufferedBlockCipher(new CFBBlockCipher(AESEngine.newInstance(), 128)); KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); b.init(true, new ParametersWithIV(kp, new byte[16])); @@ -262,7 +267,7 @@ private boolean areEqual(byte[] a, int aOff, byte[] b, int bOff) private void skipTest() { CipherParameters params = new ParametersWithIV(new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), Hex.decode("00000000000000000000000000000000")); - SICBlockCipher engine = new SICBlockCipher(new AESEngine()); + CTRModeCipher engine = SICBlockCipher.newInstance(AESEngine.newInstance()); engine.init(true, params); @@ -391,20 +396,20 @@ private void skipTest() private void ctrCounterTest() { CipherParameters params = new ParametersWithIV(new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), Hex.decode("000000000000000000000000000000")); - SICBlockCipher engine = new SICBlockCipher(new AESEngine()); + CTRModeCipher engine = SICBlockCipher.newInstance(AESEngine.newInstance()); engine.init(true, params); SecureRandom rand = new SecureRandom(); - byte[] cipher = new byte[256 * 16]; - byte[] plain = new byte[255 * 16]; + byte[] cipher = new byte[256 * 16 + 1]; + byte[] plain = new byte[256 * 16]; rand.nextBytes(plain); engine.processBytes(plain, 0, plain.length, cipher, 0); engine.init(true, params); - plain = new byte[256 * 16]; + plain = new byte[256 * 16 + 1]; engine.init(true, params); try @@ -421,10 +426,48 @@ private void ctrCounterTest() } } + private void testLastByte() + throws Exception + { + CTRModeCipher cipher = SICBlockCipher.newInstance(AESEngine.newInstance()); + byte[] iv = new byte[15]; + byte[] key = new byte[16]; + + Arrays.fill(iv, (byte)0x0a); + cipher.init(true, new ParametersWithIV(new KeyParameter(key), iv)); + + int lastBlock = 255; // the last block + cipher.seekTo((lastBlock * 16)); + + + for (int t = 0; t < 15; t++) // the last byte + { + cipher.returnByte((byte)0x00); + } + + // + // This should return the last byte + // + cipher.returnByte((byte)0); + + // + // This should fail. + // + try + { + cipher.returnByte((byte)0); + fail("should not succed"); + } + catch (Exception ex) + { + isEquals(ex.getMessage(), "Counter in CTR/SIC mode out of range."); + } + } + private void ctrFragmentedTest() throws InvalidCipherTextException { - SICBlockCipher engine = new SICBlockCipher(new AESEngine()); + CTRModeCipher engine = SICBlockCipher.newInstance(AESEngine.newInstance()); KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); byte[] out = new byte[tData.length]; @@ -497,6 +540,60 @@ public void performTest() skipTest(); ctrCounterTest(); ctrFragmentedTest(); + testLastByte(); + testCounter(); + } + + static byte[] fileBytes = new byte[0]; + static byte[] iv = new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + private void testCounter() { + Random random = new Random(); + for (int i = 0; i < 255; i++) { + iv[iv.length - 1] += (byte) i; + + String inStr = " 1234567890jl字符串"; + for (int j = 1000; j > 0; j--) { + inStr += (char) ('a' + random.nextInt(26)); + verify(inStr); + fileBytes = new byte[0]; + } + } + } + + private void verify(String inStr) { + SICBlockCipher cipher = newCipher(); + byte[] bytes = inStr.getBytes(StandardCharsets.UTF_8); + + appendFile(bytes, cipher); + appendFile(bytes, cipher); + appendFile(bytes, cipher); + + byte[] out = new byte[fileBytes.length]; + newCipher().processBytes(fileBytes, 0, fileBytes.length, out, 0); + String outStr = new String(out, StandardCharsets.UTF_8); + + if (!outStr.equals(inStr + inStr + inStr)) { + throw new RuntimeException("fail"); + } + } + + private void appendFile(byte[] bytes, SICBlockCipher cipher) { + cipher.seekTo(fileBytes.length); + byte[] out = new byte[bytes.length]; + cipher.processBytes(bytes, 0, bytes.length, out, 0); + + byte[] newFileBytes = Arrays.copyOf(fileBytes, fileBytes.length + out.length); + System.arraycopy(out, 0, newFileBytes, fileBytes.length, out.length); + fileBytes = newFileBytes; + } + + private static SICBlockCipher newCipher() { + SICBlockCipher sicBlockCipher = new SICBlockCipher(new AESEngine()); + byte[] key = "1234567890123456".getBytes(); + ParametersWithIV parametersWithIV = new ParametersWithIV(new KeyParameter(key), iv); + sicBlockCipher.init(true, parametersWithIV); + return sicBlockCipher; } public static void main( diff --git a/core/src/test/java/org/bouncycastle/crypto/test/AESVectorFileTest.java b/core/src/test/java/org/bouncycastle/crypto/test/AESVectorFileTest.java index a3e8b9bb7e..d26f07eefe 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/AESVectorFileTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/AESVectorFileTest.java @@ -16,6 +16,7 @@ import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.engines.AESLightEngine; import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTestResult; import org.bouncycastle.util.test.Test; @@ -35,7 +36,7 @@ public class AESVectorFileTest protected BlockCipher createNewEngineForTest() { - return new AESEngine(); + return AESEngine.newInstance(); } private Test[] readTestVectors(InputStream inStream) @@ -71,7 +72,7 @@ private Test[] readTestVectors(InputStream inStream) while (line != null) { - line = line.trim().toLowerCase(); + line = Strings.toLowerCase(line.trim()); if (line.startsWith("blocksize=")) { int i = 0; diff --git a/core/src/test/java/org/bouncycastle/crypto/test/AESWrapTest.java b/core/src/test/java/org/bouncycastle/crypto/test/AESWrapTest.java index a74db614ea..21601028e4 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/AESWrapTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/AESWrapTest.java @@ -71,7 +71,7 @@ private void wrapTest( } } catch (TestFailedException e) - { + { throw e; } catch (Exception e) @@ -121,6 +121,58 @@ private void wrapTest( } } + private void unwrapTest( + int id, + byte[] kek, + byte[] in, + byte[] out) + { + Wrapper wrapper = new AESWrapEngine(false); + + wrapper.init(false, new KeyParameter(kek)); + + try + { + byte[] pText = wrapper.unwrap(out, 0, out.length); + if (!Arrays.areEqual(pText, in)) + { + fail("failed unwrap test " + id + " expected " + new String(Hex.encode(in)) + " got " + new String(Hex.encode(pText))); + } + } + catch (TestFailedException e) + { + throw e; + } + catch (Exception e) + { + fail("failed unwrap test exception.", e); + } + + // + // offset test + // + byte[] pText = new byte[5 + in.length]; + byte[] cText = new byte[6 + out.length]; + + System.arraycopy(in, 0, pText, 5, in.length); + System.arraycopy(out, 0, cText, 6, out.length); + + wrapper.init(false, new KeyParameter(kek)); + + try + { + pText = wrapper.unwrap(cText, 6, out.length); + if (!Arrays.areEqual(pText, in)) + { + fail("failed unwrap test " + id + " expected " + new String(Hex.encode(in)) + " got " + new String(Hex.encode(pText))); + } + } + catch (Exception e) + { + fail("failed unwrap test exception.", e); + } + } + private void heapIssueTest() { byte[] key = Hex.decode("d305ef52a6b9e72c810b821261d2d678"); @@ -187,6 +239,10 @@ public void performTest() byte[] out8 = Hex.decode("6f0b501f1f2f59e3ae605aa679ce43a6"); wrapTest(8, kek8, in8, out8); + // backwards compatibility test + byte[] out8c = Hex.decode("dc26fb6911d71971df0356d6bb9ed6e6"); + unwrapTest(9, kek8, in8, out8c); + Wrapper wrapper = new AESWrapEngine(); KeyParameter key = new KeyParameter(new byte[16]); byte[] buf = new byte[16]; diff --git a/core/src/test/java/org/bouncycastle/crypto/test/AllTests.java b/core/src/test/java/org/bouncycastle/crypto/test/AllTests.java index cffd2b347a..1ab4247f85 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/AllTests.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/AllTests.java @@ -21,7 +21,6 @@ public static Test suite() suite.addTestSuite(SimpleTestTest.class); suite.addTestSuite(GCMReorderTest.class); suite.addTestSuite(HPKETestVectors.class); - return new BCTestSetup(suite); } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/Argon2Test.java b/core/src/test/java/org/bouncycastle/crypto/test/Argon2Test.java index c99185c6bc..608b4bfbbd 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/Argon2Test.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/Argon2Test.java @@ -2,6 +2,7 @@ import java.util.ArrayList; +import java.util.List; import org.bouncycastle.crypto.generators.Argon2BytesGenerator; import org.bouncycastle.crypto.params.Argon2Parameters; @@ -134,7 +135,7 @@ public void testPermutations() } - ArrayList permutations = new ArrayList(); + List permutations = new ArrayList(); permute(permutations, buf, 0, buf.length - 1); for (int i = 0; i != permutations.size(); i++) @@ -166,7 +167,7 @@ private void swap(byte[] buf, int i, int j) buf[j] = b; } - private void permute(ArrayList permutation, byte[] a, int l, int r) + private void permute(List permutation, byte[] a, int l, int r) { if (l == r) { diff --git a/core/src/test/java/org/bouncycastle/crypto/test/AsconTest.java b/core/src/test/java/org/bouncycastle/crypto/test/AsconTest.java index 7b31e0bb11..cb6df6c288 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/AsconTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/AsconTest.java @@ -8,24 +8,27 @@ import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.OutputLengthException; -import org.bouncycastle.crypto.Xof; import org.bouncycastle.crypto.digests.AsconDigest; import org.bouncycastle.crypto.digests.AsconXof; import org.bouncycastle.crypto.engines.AsconEngine; -import org.bouncycastle.crypto.modes.AEADCipher; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.test.TestResourceFinder; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class AsconTest extends SimpleTest { + public static void main(String[] args) + { + runTest(new AsconTest()); + } + public String getName() { return "Ascon"; @@ -34,165 +37,342 @@ public String getName() public void performTest() throws Exception { - testVectorsHash(AsconDigest.AsconParameters.AsconHashA, "asconhasha"); - testVectorsHash(AsconDigest.AsconParameters.AsconHash, "asconhash"); - testVectorsHash(AsconXof.AsconParameters.AsconXof, "asconxof"); - testVectorsHash(AsconXof.AsconParameters.AsconXofA, "asconxofa"); - implTestExceptions(new AsconDigest(AsconDigest.AsconParameters.AsconHashA), 32); - implTestExceptions(new AsconDigest(AsconDigest.AsconParameters.AsconHash), 32); - implTestExceptions(new AsconXof(AsconXof.AsconParameters.AsconXof), 32); - implTestExceptions(new AsconXof(AsconXof.AsconParameters.AsconXofA), 32); - AsconEngine Ascon = new AsconEngine(AsconEngine.AsconParameters.ascon80pq); - testExceptions(Ascon, Ascon.getKeyBytesSize(), Ascon.getIVBytesSize(), 8); - testParameters(Ascon, 20, 16, 16); - Ascon = new AsconEngine(AsconEngine.AsconParameters.ascon128a); - testExceptions(Ascon, Ascon.getKeyBytesSize(), Ascon.getIVBytesSize(), 16); - testParameters(Ascon, 16, 16, 16); - Ascon = new AsconEngine(AsconEngine.AsconParameters.ascon128); - testExceptions(Ascon, Ascon.getKeyBytesSize(), Ascon.getIVBytesSize(), 8); - testParameters(Ascon, 16, 16, 16); - testVectors(AsconEngine.AsconParameters.ascon80pq, "160_128"); - testVectors(AsconEngine.AsconParameters.ascon128a, "128_128_a"); - testVectors(AsconEngine.AsconParameters.ascon128, "128_128"); - } - - - private void testVectors(AsconEngine.AsconParameters asconParameters, String filename) + testBufferingEngine_ascon128(); + testBufferingEngine_ascon128a(); + testBufferingEngine_ascon80(); + + testExceptionsDigest_AsconHash(); + testExceptionsDigest_AsconHashA(); + + testExceptionsEngine_ascon128(); + testExceptionsEngine_ascon128a(); + testExceptionsEngine_ascon80pq(); + + testExceptionsXof_AsconXof(); + testExceptionsXof_AsconXofA(); + + testParametersDigest_AsconHash(); + testParametersDigest_AsconHashA(); + + testParametersEngine_ascon128(); + testParametersEngine_ascon128a(); + testParametersEngine_ascon80pq(); + + testParametersXof_AsconXof(); + testParametersXof_AsconXofA(); + + testVectorsDigest_AsconHash(); + testVectorsDigest_AsconHashA(); + + testVectorsEngine_ascon128(); + testVectorsEngine_ascon128a(); + testVectorsEngine_ascon80pq(); + + testVectorsXof_AsconXof(); + testVectorsXof_AsconXofA(); + } + + public void testBufferingEngine_ascon128() throws Exception + { + implTestBufferingEngine(AsconEngine.AsconParameters.ascon128); + } + + public void testBufferingEngine_ascon128a() throws Exception + { + implTestBufferingEngine(AsconEngine.AsconParameters.ascon128a); + } + + public void testBufferingEngine_ascon80() throws Exception + { + implTestBufferingEngine(AsconEngine.AsconParameters.ascon80pq); + } + + public void testExceptionsDigest_AsconHash() throws Exception + { + implTestExceptionsDigest(AsconDigest.AsconParameters.AsconHash); + } + + public void testExceptionsDigest_AsconHashA() throws Exception + { + implTestExceptionsDigest(AsconDigest.AsconParameters.AsconHashA); + } + + public void testExceptionsEngine_ascon128() throws Exception + { + implTestExceptionsEngine(AsconEngine.AsconParameters.ascon128); + } + + public void testExceptionsEngine_ascon128a() throws Exception + { + implTestExceptionsEngine(AsconEngine.AsconParameters.ascon128a); + } + + public void testExceptionsEngine_ascon80pq() throws Exception + { + implTestExceptionsEngine(AsconEngine.AsconParameters.ascon80pq); + } + + public void testExceptionsXof_AsconXof() throws Exception + { + implTestExceptionsXof(AsconXof.AsconParameters.AsconXof); + } + + public void testExceptionsXof_AsconXofA() throws Exception + { + implTestExceptionsXof(AsconXof.AsconParameters.AsconXofA); + } + + public void testParametersDigest_AsconHash() throws Exception + { + implTestParametersDigest(AsconDigest.AsconParameters.AsconHash, 32); + } + + public void testParametersDigest_AsconHashA() throws Exception + { + implTestParametersDigest(AsconDigest.AsconParameters.AsconHashA, 32); + } + + public void testParametersEngine_ascon128() throws Exception + { + implTestParametersEngine(AsconEngine.AsconParameters.ascon128, 16, 16, 16); + } + + public void testParametersEngine_ascon128a() throws Exception + { + implTestParametersEngine(AsconEngine.AsconParameters.ascon128a, 16, 16, 16); + } + + public void testParametersEngine_ascon80pq() throws Exception + { + implTestParametersEngine(AsconEngine.AsconParameters.ascon80pq, 20, 16, 16); + } + + public void testParametersXof_AsconXof() throws Exception + { + implTestParametersXof(AsconXof.AsconParameters.AsconXof, 32); + } + + public void testParametersXof_AsconXofA() throws Exception + { + implTestParametersXof(AsconXof.AsconParameters.AsconXofA, 32); + } + + public void testVectorsDigest_AsconHash() throws Exception + { + implTestVectorsDigest(AsconDigest.AsconParameters.AsconHash, "asconhash"); + } + + public void testVectorsDigest_AsconHashA() throws Exception + { + implTestVectorsDigest(AsconDigest.AsconParameters.AsconHashA, "asconhasha"); + } + + public void testVectorsEngine_ascon128() throws Exception + { + implTestVectorsEngine(AsconEngine.AsconParameters.ascon128, "128_128"); + } + + public void testVectorsEngine_ascon128a() throws Exception + { + implTestVectorsEngine(AsconEngine.AsconParameters.ascon128a, "128_128_a"); + } + + public void testVectorsEngine_ascon80pq() throws Exception + { + implTestVectorsEngine(AsconEngine.AsconParameters.ascon80pq, "160_128"); + } + + public void testVectorsXof_AsconXof() throws Exception + { + implTestVectorsXof(AsconXof.AsconParameters.AsconXof, "asconxof"); + } + + public void testVectorsXof_AsconXofA() throws Exception + { + implTestVectorsXof(AsconXof.AsconParameters.AsconXofA, "asconxofa"); + } + + private static AsconDigest createDigest(AsconDigest.AsconParameters asconParameters) + { + return new AsconDigest(asconParameters); + } + + private static AsconEngine createEngine(AsconEngine.AsconParameters asconParameters) + { + return new AsconEngine(asconParameters); + } + + private static AsconXof createXof(AsconXof.AsconParameters asconParameters) + { + return new AsconXof(asconParameters); + } + + private void implTestBufferingEngine(AsconEngine.AsconParameters asconParameters) throws Exception { - AsconEngine Ascon = new AsconEngine(asconParameters); - CipherParameters params; - InputStream src = TestResourceFinder.findTestResource("crypto/ascon", "LWC_AEAD_KAT_" + filename + ".txt"); - BufferedReader bin = new BufferedReader(new InputStreamReader(src)); - String line; - byte[] rv; - HashMap map = new HashMap(); Random random = new Random(); - while ((line = bin.readLine()) != null) + + int plaintextLength = 256; + byte[] plaintext = new byte[plaintextLength]; + random.nextBytes(plaintext); + + AsconEngine ascon0 = createEngine(asconParameters); + initEngine(ascon0, true); + + byte[] ciphertext = new byte[ascon0.getOutputSize(plaintextLength)]; + random.nextBytes(ciphertext); + + int ciphertextLength = ascon0.processBytes(plaintext, 0, plaintextLength, ciphertext, 0); + ciphertextLength += ascon0.doFinal(ciphertext, ciphertextLength); + + byte[] output = new byte[ciphertextLength]; + + // Encryption + for (int split = 1; split < plaintextLength; ++split) { - int a = line.indexOf('='); - if (a < 0) + AsconEngine ascon = createEngine(asconParameters); + initEngine(ascon, true); + + random.nextBytes(output); + + int length = ascon.processBytes(plaintext, 0, split, output, 0); + + if (0 != ascon.getUpdateOutputSize(0)) { -// if (!map.get("Count").equals("71")) -// { -// continue; -// } - byte[] key = Hex.decode((String)map.get("Key")); - byte[] nonce = Hex.decode((String)map.get("Nonce")); - byte[] ad = Hex.decode((String)map.get("AD")); - byte[] pt = Hex.decode((String)map.get("PT")); - byte[] ct = Hex.decode((String)map.get("CT")); - params = new ParametersWithIV(new KeyParameter(key), nonce); - Ascon.init(true, params); - Ascon.processAADBytes(ad, 0, ad.length); - rv = new byte[Ascon.getOutputSize(pt.length)]; - random.nextBytes(rv); - int len = Ascon.processBytes(pt, 0, pt.length, rv, 0); - Ascon.doFinal(rv, len); - if (!areEqual(rv, ct)) - { - mismatch("Keystream " + map.get("Count"), (String)map.get("CT"), rv); - } - else - { - System.out.println("Keystream " + map.get("Count") + " pass"); - } - Ascon.reset(); - Ascon.init(false, params); - //Decrypt - Ascon.processAADBytes(ad, 0, ad.length); - rv = new byte[pt.length + 16]; - random.nextBytes(rv); - len = Ascon.processBytes(ct, 0, ct.length, rv, 0); - Ascon.doFinal(rv, len); - byte[] pt_recovered = new byte[pt.length]; - System.arraycopy(rv, 0, pt_recovered, 0, pt.length); - if (!areEqual(pt, pt_recovered)) - { - mismatch("Reccover Keystream " + map.get("Count"), (String)map.get("PT"), pt_recovered); - } - Ascon.reset(); - map.clear(); + fail(""); } - else + + length += ascon.processBytes(plaintext, split, plaintextLength - split, output, length); + length += ascon.doFinal(output, length); + + if (!Arrays.areEqual(ciphertext, 0, ciphertextLength, output, 0, length)) { - map.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); + fail("encryption failed with split: " + split); + } + } + + // Decryption + for (int split = 1; split < ciphertextLength; ++split) + { + AsconEngine ascon = createEngine(asconParameters); + initEngine(ascon, false); + + random.nextBytes(output); + + int length = ascon.processBytes(ciphertext, 0, split, output, 0); + + if (0 != ascon.getUpdateOutputSize(0)) + { + fail(""); + } + + length += ascon.processBytes(ciphertext, split, ciphertextLength - split, output, length); + length += ascon.doFinal(output, length); + + if (!Arrays.areEqual(plaintext, 0, plaintextLength, output, 0, length)) + { + fail("decryption failed with split: " + split); } } - System.out.println(Ascon.getAlgorithmName() + " " + Ascon.getAlgorithmVersion() + " Pass"); } - private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, int blocksize) + private void implTestExceptionsDigest(AsconDigest.AsconParameters asconParameters) + { + AsconDigest ascon = createDigest(asconParameters); + + try + { + ascon.update(new byte[1], 1, 1); + fail(ascon.getAlgorithmName() + ": input for update is too short"); + } + catch (DataLengthException e) + { + //expected + } + + try + { + ascon.doFinal(new byte[ascon.getDigestSize() - 1], 2); + fail(ascon.getAlgorithmName() + ": output for dofinal is too short"); + } + catch (OutputLengthException e) + { + //expected + } + } + + private void implTestExceptionsEngine(AsconEngine.AsconParameters asconParameters) throws Exception { - CipherParameters params; - byte[] k = new byte[keysize]; - byte[] iv = new byte[ivsize]; + AsconEngine ascon = createEngine(asconParameters); + int keySize = ascon.getKeyBytesSize(), ivSize = ascon.getIVBytesSize(); + int offset; + byte[] k = new byte[keySize]; + byte[] iv = new byte[ivSize]; byte[] m = new byte[0]; - byte[] c1 = new byte[aeadBlockCipher.getOutputSize(m.length)]; - params = new ParametersWithIV(new KeyParameter(k), iv); + CipherParameters params = new ParametersWithIV(new KeyParameter(k), iv); try { - aeadBlockCipher.processBytes(m, 0, m.length, c1, 0); - fail(aeadBlockCipher.getAlgorithmName() + " need to be initialed before processBytes"); + ascon.processBytes(m, 0, m.length, null, 0); + fail(ascon.getAlgorithmName() + " need to be initialized before processBytes"); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected } try { - aeadBlockCipher.processByte((byte)0, c1, 0); - fail(aeadBlockCipher.getAlgorithmName() + " need to be initialed before processByte"); + ascon.processByte((byte)0, null, 0); + fail(ascon.getAlgorithmName() + " need to be initialized before processByte"); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected } try { - aeadBlockCipher.reset(); - fail(aeadBlockCipher.getAlgorithmName() + " need to be initialed before reset"); + ascon.reset(); + fail(ascon.getAlgorithmName() + " need to be initialized before reset"); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected } try { - aeadBlockCipher.doFinal(c1, m.length); - fail(aeadBlockCipher.getAlgorithmName() + " need to be initialed before dofinal"); + ascon.doFinal(null, m.length); + fail(ascon.getAlgorithmName() + " need to be initialized before dofinal"); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected } try { - aeadBlockCipher.getMac(); - aeadBlockCipher.getAlgorithmName(); - aeadBlockCipher.getOutputSize(0); - aeadBlockCipher.getUpdateOutputSize(0); + ascon.getMac(); + ascon.getOutputSize(0); + ascon.getUpdateOutputSize(0); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected - fail(aeadBlockCipher.getAlgorithmName() + " functions can be called before initialisation"); + fail(ascon.getAlgorithmName() + " functions can be called before initialization"); } + Random rand = new Random(); int randomNum; - while ((randomNum = rand.nextInt(100)) == keysize) ; + while ((randomNum = rand.nextInt(100)) == keySize) ; byte[] k1 = new byte[randomNum]; - while ((randomNum = rand.nextInt(100)) == ivsize) ; + while ((randomNum = rand.nextInt(100)) == ivSize) ; byte[] iv1 = new byte[randomNum]; try { - aeadBlockCipher.init(true, new ParametersWithIV(new KeyParameter(k1), iv)); - fail(aeadBlockCipher.getAlgorithmName() + " k size does not match"); + ascon.init(true, new ParametersWithIV(new KeyParameter(k1), iv)); + fail(ascon.getAlgorithmName() + " k size does not match"); } catch (IllegalArgumentException e) { @@ -200,8 +380,8 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, } try { - aeadBlockCipher.init(true, new ParametersWithIV(new KeyParameter(k), iv1)); - fail(aeadBlockCipher.getAlgorithmName() + "iv size does not match"); + ascon.init(true, new ParametersWithIV(new KeyParameter(k), iv1)); + fail(ascon.getAlgorithmName() + "iv size does not match"); } catch (IllegalArgumentException e) { @@ -210,24 +390,25 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, try { - aeadBlockCipher.init(true, new AEADParameters(new KeyParameter(k), 0, iv)); - fail(aeadBlockCipher.getAlgorithmName() + " wrong type of CipherParameters"); + ascon.init(true, new AEADParameters(new KeyParameter(k), 0, iv)); + fail(ascon.getAlgorithmName() + " wrong type of CipherParameters"); } catch (IllegalArgumentException e) { //expected } - aeadBlockCipher.init(true, params); + ascon.init(true, params); + byte[] c1 = new byte[ascon.getOutputSize(m.length)]; try { - aeadBlockCipher.doFinal(c1, m.length); + ascon.doFinal(c1, m.length); } catch (Exception e) { - fail(aeadBlockCipher.getAlgorithmName() + " allows no input for AAD and plaintext"); + fail(ascon.getAlgorithmName() + " allows no input for AAD and plaintext"); } - byte[] mac2 = aeadBlockCipher.getMac(); + byte[] mac2 = ascon.getMac(); if (mac2 == null) { fail("mac should not be empty after dofinal"); @@ -236,39 +417,39 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, { fail("mac should be equal when calling dofinal and getMac"); } - aeadBlockCipher.init(true, params); - aeadBlockCipher.processAADByte((byte)0); - byte[] mac1 = new byte[aeadBlockCipher.getOutputSize(0)]; - aeadBlockCipher.doFinal(mac1, 0); + ascon.init(true, params); + ascon.processAADByte((byte)0); + byte[] mac1 = new byte[ascon.getOutputSize(0)]; + ascon.doFinal(mac1, 0); if (areEqual(mac1, mac2)) { fail("mac should not match"); } - aeadBlockCipher.init(true, params); - aeadBlockCipher.processBytes(new byte[16], 0, 16, new byte[16], 0); + ascon.init(true, params); + ascon.processByte((byte)0, null, 0); try { - aeadBlockCipher.processAADByte((byte)0); + ascon.processAADByte((byte)0); fail("processAADByte(s) cannot be called after encryption/decryption"); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected } try { - aeadBlockCipher.processAADBytes(new byte[]{0}, 0, 1); + ascon.processAADBytes(new byte[]{0}, 0, 1); fail("processAADByte(s) cannot be called once only"); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected } - aeadBlockCipher.reset(); + ascon.reset(); try { - aeadBlockCipher.processAADBytes(new byte[]{0}, 1, 1); + ascon.processAADBytes(new byte[]{0}, 1, 1); fail("input for processAADBytes is too short"); } catch (DataLengthException e) @@ -277,17 +458,18 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, } try { - aeadBlockCipher.processBytes(new byte[]{0}, 1, 1, c1, 0); + ascon.processBytes(new byte[]{0}, 1, 1, c1, 0); fail("input for processBytes is too short"); } catch (DataLengthException e) { //expected } - aeadBlockCipher.init(true, params); + ascon.init(true, params); try { - aeadBlockCipher.processBytes(new byte[16], 0, 16, new byte[16], 8); + int need = ascon.getUpdateOutputSize(64); + ascon.processBytes(new byte[64], 0, 64, new byte[need], 1); fail("output for processBytes is too short"); } catch (OutputLengthException e) @@ -296,67 +478,68 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, } try { - aeadBlockCipher.doFinal(new byte[2], 2); + ascon.doFinal(new byte[2], 2); fail("output for dofinal is too short"); } - catch (DataLengthException e) + catch (OutputLengthException e) { //expected } - mac1 = new byte[aeadBlockCipher.getOutputSize(0)]; - mac2 = new byte[aeadBlockCipher.getOutputSize(0)]; - aeadBlockCipher.init(true, params); - aeadBlockCipher.processAADBytes(new byte[]{0, 0}, 0, 2); - aeadBlockCipher.doFinal(mac1, 0); - aeadBlockCipher.init(true, params); - aeadBlockCipher.processAADByte((byte)0); - aeadBlockCipher.processAADByte((byte)0); - aeadBlockCipher.doFinal(mac2, 0); + implTestExceptionsGetUpdateOutputSize(ascon, false, params, 100); + implTestExceptionsGetUpdateOutputSize(ascon, true, params, 100); + + mac1 = new byte[ascon.getOutputSize(0)]; + mac2 = new byte[ascon.getOutputSize(0)]; + ascon.init(true, params); + ascon.processAADBytes(new byte[]{0, 0}, 0, 2); + ascon.doFinal(mac1, 0); + ascon.init(true, params); + ascon.processAADByte((byte)0); + ascon.processAADByte((byte)0); + ascon.doFinal(mac2, 0); if (!areEqual(mac1, mac2)) { fail("mac should match for the same AAD with different ways of inputing"); } - byte[] c2 = new byte[aeadBlockCipher.getOutputSize(10)]; - byte[] c3 = new byte[aeadBlockCipher.getOutputSize(10) + 2]; + byte[] c2 = new byte[ascon.getOutputSize(10)]; + byte[] c3 = new byte[ascon.getOutputSize(10) + 2]; byte[] aad2 = {0, 1, 2, 3, 4}; byte[] aad3 = {0, 0, 1, 2, 3, 4, 5}; byte[] m2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; byte[] m3 = {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; byte[] m4 = new byte[m2.length]; - aeadBlockCipher.init(true, params); - aeadBlockCipher.processAADBytes(aad2, 0, aad2.length); - int offset = aeadBlockCipher.processBytes(m2, 0, m2.length, c2, 0); - aeadBlockCipher.doFinal(c2, offset); - aeadBlockCipher.init(true, params); - aeadBlockCipher.processAADBytes(aad3, 1, aad2.length); - offset = aeadBlockCipher.processBytes(m3, 1, m2.length, c3, 1); - aeadBlockCipher.doFinal(c3, offset + 1); + ascon.init(true, params); + ascon.processAADBytes(aad2, 0, aad2.length); + offset = ascon.processBytes(m2, 0, m2.length, c2, 0); + ascon.doFinal(c2, offset); + ascon.init(true, params); + ascon.processAADBytes(aad3, 1, aad2.length); + offset = ascon.processBytes(m3, 1, m2.length, c3, 1); + ascon.doFinal(c3, offset + 1); byte[] c3_partial = new byte[c2.length]; System.arraycopy(c3, 1, c3_partial, 0, c2.length); if (!areEqual(c2, c3_partial)) { fail("mac should match for the same AAD and message with different offset for both input and output"); } - aeadBlockCipher.init(false, params); - aeadBlockCipher.processAADBytes(aad2, 0, aad2.length); - offset = aeadBlockCipher.processBytes(c2, 0, c2.length, m4, 0); - aeadBlockCipher.doFinal(m4, offset); + ascon.init(false, params); + ascon.processAADBytes(aad2, 0, aad2.length); + offset = ascon.processBytes(c2, 0, c2.length, m4, 0); + ascon.doFinal(m4, offset); if (!areEqual(m2, m4)) { fail("The encryption and decryption does not recover the plaintext"); } - System.out.println(aeadBlockCipher.getAlgorithmName() + " test Exceptions pass"); c2[c2.length - 1] ^= 1; - aeadBlockCipher.reset(); - aeadBlockCipher.init(false, params); - aeadBlockCipher.processAADBytes(aad2, 0, aad2.length); - offset = aeadBlockCipher.processBytes(c2, 0, c2.length, m4, 0); + ascon.init(false, params); + ascon.processAADBytes(aad2, 0, aad2.length); + offset = ascon.processBytes(c2, 0, c2.length, m4, 0); try { - aeadBlockCipher.doFinal(m4, offset); + ascon.doFinal(m4, offset); fail("The decryption should fail"); } catch (InvalidCipherTextException e) @@ -364,38 +547,110 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, //expected; } - byte[] m7 = new byte[blocksize * 2]; - for (int i = 0; i < m7.length; ++i) - { - m7[i] = (byte)rand.nextInt(); - } - aeadBlockCipher.init(true, params); - byte[] c7 = new byte[aeadBlockCipher.getOutputSize(m7.length)]; + byte[] m7 = new byte[32 + rand.nextInt(32)]; + rand.nextBytes(m7); + + ascon.init(true, params); + byte[] c7 = new byte[ascon.getOutputSize(m7.length)]; byte[] c8 = new byte[c7.length]; byte[] c9 = new byte[c7.length]; - aeadBlockCipher.processAADBytes(aad2, 0, aad2.length); - offset = aeadBlockCipher.processBytes(m7, 0, m7.length, c7, 0); - aeadBlockCipher.doFinal(c7, offset); - aeadBlockCipher.init(true, params); - aeadBlockCipher.processAADBytes(aad2, 0, aad2.length); - offset = aeadBlockCipher.processBytes(m7, 0, blocksize, c8, 0); - offset += aeadBlockCipher.processBytes(m7, blocksize, m7.length - blocksize, c8, offset); - aeadBlockCipher.doFinal(c8, offset); - aeadBlockCipher.init(true, params); - int split = rand.nextInt(blocksize * 2); - aeadBlockCipher.processAADBytes(aad2, 0, aad2.length); - offset = aeadBlockCipher.processBytes(m7, 0, split, c9, 0); - offset += aeadBlockCipher.processBytes(m7, split, m7.length - split, c9, offset); - aeadBlockCipher.doFinal(c9, offset); + ascon.processAADBytes(aad2, 0, aad2.length); + offset = ascon.processBytes(m7, 0, m7.length, c7, 0); + ascon.doFinal(c7, offset); + + ascon.init(true, params); + ascon.processAADBytes(aad2, 0, aad2.length); + offset = ascon.processBytes(m7, 0, m7.length / 2, c8, 0); + offset += ascon.processBytes(m7, m7.length / 2, m7.length - m7.length / 2, c8, offset); + offset += ascon.doFinal(c8, offset); + + ascon.init(true, params); + int split = rand.nextInt(m7.length - 1) + 1; + ascon.processAADBytes(aad2, 0, aad2.length); + offset = ascon.processBytes(m7, 0, split, c9, 0); + offset += ascon.processBytes(m7, split, m7.length - split, c9, offset); + offset += ascon.doFinal(c9, offset); + if (!areEqual(c7, c8) || !areEqual(c7, c9)) { fail("Splitting input of plaintext should output the same ciphertext"); } + } + + private void implTestExceptionsGetUpdateOutputSize(AsconEngine ascon, boolean forEncryption, + CipherParameters parameters, int maxInputSize) + { + ascon.init(forEncryption, parameters); + + int maxOutputSize = ascon.getUpdateOutputSize(maxInputSize); + + byte[] input = new byte[maxInputSize]; + byte[] output = new byte[maxOutputSize]; + + for (int inputSize = 0; inputSize <= maxInputSize; ++inputSize) + { + ascon.init(forEncryption, parameters); + + int outputSize = ascon.getUpdateOutputSize(inputSize); + if (outputSize > 0) + { + try + { + ascon.processBytes(input, 0, inputSize, output, maxOutputSize - outputSize + 1); + fail("output for processBytes is too short"); + } + catch (OutputLengthException e) + { + //expected + } + } + else + { + ascon.processBytes(input, 0, inputSize, null, 0); + } + } + } + + private void implTestExceptionsXof(AsconXof.AsconParameters asconParameters) + { + AsconXof ascon = createXof(asconParameters); + + try + { + ascon.update(new byte[1], 1, 1); + fail(ascon.getAlgorithmName() + ": input for update is too short"); + } + catch (DataLengthException e) + { + //expected + } + try + { + ascon.doFinal(new byte[ascon.getDigestSize() - 1], 2); + fail(ascon.getAlgorithmName() + ": output for dofinal is too short"); + } + catch (OutputLengthException e) + { + //expected + } } - private void testParameters(AsconEngine ascon, int keySize, int ivSize, int macSize) + private void implTestParametersDigest(AsconDigest.AsconParameters asconParameters, int digestSize) { + AsconDigest ascon = createDigest(asconParameters); + + if (ascon.getDigestSize() != digestSize) + { + fail(ascon.getAlgorithmName() + ": digest size is not correct"); + } + } + + private void implTestParametersEngine(AsconEngine.AsconParameters asconParameters, int keySize, int ivSize, + int macSize) + { + AsconEngine ascon = createEngine(asconParameters); + if (ascon.getKeyBytesSize() != keySize) { fail("key bytes of " + ascon.getAlgorithmName() + " is not correct"); @@ -404,161 +659,201 @@ private void testParameters(AsconEngine ascon, int keySize, int ivSize, int macS { fail("iv bytes of " + ascon.getAlgorithmName() + " is not correct"); } + + CipherParameters parameters = new ParametersWithIV(new KeyParameter(new byte[keySize]), new byte[ivSize]); + + ascon.init(true, parameters); if (ascon.getOutputSize(0) != macSize) { - fail("mac bytes of " + ascon.getAlgorithmName() + " is not correct"); + fail("getOutputSize of " + ascon.getAlgorithmName() + " is incorrect for encryption"); + } + + ascon.init(false, parameters); + if (ascon.getOutputSize(macSize) != 0) + { + fail("getOutputSize of " + ascon.getAlgorithmName() + " is incorrect for decryption"); } - System.out.println(ascon.getAlgorithmName() + " test Parameters pass"); } - private void testVectorsHash(AsconDigest.AsconParameters AsconParameters, String filename) + private void implTestParametersXof(AsconXof.AsconParameters asconParameters, int digestSize) + { + AsconXof ascon = createXof(asconParameters); + + if (ascon.getDigestSize() != digestSize) + { + fail(ascon.getAlgorithmName() + ": digest size is not correct"); + } + } + + private void implTestVectorsDigest(AsconDigest.AsconParameters asconParameters, String filename) throws Exception { - AsconDigest Ascon = new AsconDigest(AsconParameters); + Random random = new Random(); + AsconDigest ascon = createDigest(asconParameters); InputStream src = TestResourceFinder.findTestResource("crypto/ascon", filename + "_LWC_HASH_KAT_256.txt"); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); String line; - byte[] ptByte; HashMap map = new HashMap(); while ((line = bin.readLine()) != null) { int a = line.indexOf('='); if (a < 0) { -// if (!map.get("Count").equals("3")) -// { -// continue; -// } - Ascon.reset(); - ptByte = Hex.decode((String)map.get("Msg")); - Ascon.update(ptByte, 0, ptByte.length); - byte[] hash = new byte[Ascon.getDigestSize()]; - Ascon.doFinal(hash, 0); - if (!areEqual(hash, Hex.decode((String)map.get("MD")))) + byte[] ptByte = Hex.decode((String)map.get("Msg")); + byte[] expected = Hex.decode((String)map.get("MD")); + + byte[] hash = new byte[ascon.getDigestSize()]; + + ascon.update(ptByte, 0, ptByte.length); + ascon.doFinal(hash, 0); + if (!areEqual(hash, expected)) { mismatch("Keystream " + map.get("Count"), (String)map.get("MD"), hash); } -// else -// { -// System.out.println("Keystream " + map.get("Count") + " pass"); -// } + + if (ptByte.length > 1) + { + int split = random.nextInt(ptByte.length - 1) + 1; + ascon.update(ptByte, 0, split); + ascon.update(ptByte, split, ptByte.length - split); + ascon.doFinal(hash, 0); + if (!areEqual(hash, expected)) + { + mismatch("Keystream " + map.get("Count"), (String)map.get("MD"), hash); + } + } + map.clear(); - Ascon.reset(); } else { map.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("Ascon Hash pass"); } - private void testVectorsHash(AsconXof.AsconParameters AsconParameters, String filename) + private void implTestVectorsEngine(AsconEngine.AsconParameters asconParameters, String filename) throws Exception { - AsconXof Ascon = new AsconXof(AsconParameters); - InputStream src = TestResourceFinder.findTestResource("crypto/ascon", filename + "_LWC_HASH_KAT_256.txt"); + Random random = new Random(); + AsconEngine ascon = createEngine(asconParameters); + InputStream src = TestResourceFinder.findTestResource("crypto/ascon", "LWC_AEAD_KAT_" + filename + ".txt"); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); String line; - byte[] ptByte; HashMap map = new HashMap(); while ((line = bin.readLine()) != null) { int a = line.indexOf('='); if (a < 0) { -// if (!map.get("Count").equals("3")) -// { -// continue; -// } - Ascon.reset(); - ptByte = Hex.decode((String)map.get("Msg")); - Ascon.update(ptByte, 0, ptByte.length); - byte[] hash = new byte[Ascon.getDigestSize()]; - Ascon.doFinal(hash, 0); - if (!areEqual(hash, Hex.decode((String)map.get("MD")))) + byte[] key = Hex.decode((String)map.get("Key")); + byte[] nonce = Hex.decode((String)map.get("Nonce")); + byte[] ad = Hex.decode((String)map.get("AD")); + byte[] pt = Hex.decode((String)map.get("PT")); + byte[] ct = Hex.decode((String)map.get("CT")); + + CipherParameters parameters = new ParametersWithIV(new KeyParameter(key), nonce); + + // Encrypt { - mismatch("Keystream " + map.get("Count"), (String)map.get("MD"), hash); + ascon.init(true, parameters); + + byte[] rv = new byte[ascon.getOutputSize(pt.length)]; + random.nextBytes(rv); // should overwrite any existing data + + ascon.processAADBytes(ad, 0, ad.length); + int len = ascon.processBytes(pt, 0, pt.length, rv, 0); + len += ascon.doFinal(rv, len); + + if (!areEqual(rv, 0, len, ct, 0, ct.length)) + { + mismatch("Keystream " + map.get("Count"), (String)map.get("CT"), rv); + } } -// else -// { -// System.out.println("Keystream " + map.get("Count") + " pass"); -// } + + // Decrypt + { + ascon.init(false, parameters); + + byte[] rv = new byte[ascon.getOutputSize(ct.length)]; + random.nextBytes(rv); // should overwrite any existing data + + ascon.processAADBytes(ad, 0, ad.length); + int len = ascon.processBytes(ct, 0, ct.length, rv, 0); + len += ascon.doFinal(rv, len); + + if (!areEqual(rv, 0, len, pt, 0, pt.length)) + { + mismatch("Reccover Keystream " + map.get("Count"), (String)map.get("PT"), rv); + } + } + map.clear(); - Ascon.reset(); } else { map.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("Ascon Hash pass"); } - private void implTestExceptions(Digest digest, int digestsize) + private void implTestVectorsXof(AsconXof.AsconParameters asconParameters, String filename) + throws Exception { - if (digest.getDigestSize() != digestsize) + Random random = new Random(); + AsconXof ascon = createXof(asconParameters); + InputStream src = TestResourceFinder.findTestResource("crypto/ascon", filename + "_LWC_HASH_KAT_256.txt"); + BufferedReader bin = new BufferedReader(new InputStreamReader(src)); + String line; + HashMap map = new HashMap(); + while ((line = bin.readLine()) != null) { - fail(digest.getAlgorithmName() + ": digest size is not correct"); - } + int a = line.indexOf('='); + if (a < 0) + { + byte[] ptByte = Hex.decode((String)map.get("Msg")); + byte[] expected = Hex.decode((String)map.get("MD")); - try - { - digest.update(new byte[1], 1, 1); - fail(digest.getAlgorithmName() + ": input for update is too short"); - } - catch (DataLengthException e) - { - //expected - } - try - { - digest.doFinal(new byte[digest.getDigestSize() - 1], 2); - fail(digest.getAlgorithmName() + ": output for dofinal is too short"); - } - catch (DataLengthException e) - { - //expected - } - System.out.println(digest.getAlgorithmName() + " test Exceptions pass"); - } + byte[] hash = new byte[ascon.getDigestSize()]; - private void implTestExceptions(Xof xof, int digestsize) - { - if (xof.getDigestSize() != digestsize) - { - fail(xof.getAlgorithmName() + ": digest size is not correct"); - } + ascon.update(ptByte, 0, ptByte.length); + ascon.doFinal(hash, 0); + if (!areEqual(hash, expected)) + { + mismatch("Keystream " + map.get("Count"), (String)map.get("MD"), hash); + } - try - { - xof.update(new byte[1], 1, 1); - fail(xof.getAlgorithmName() + ": input for update is too short"); - } - catch (DataLengthException e) - { - //expected - } - try - { - xof.doFinal(new byte[xof.getDigestSize() - 1], 2); - fail(xof.getAlgorithmName() + ": output for dofinal is too short"); - } - catch (DataLengthException e) - { - //expected + if (ptByte.length > 1) + { + int split = random.nextInt(ptByte.length - 1) + 1; + ascon.update(ptByte, 0, split); + ascon.update(ptByte, split, ptByte.length - split); + ascon.doFinal(hash, 0); + if (!areEqual(hash, expected)) + { + mismatch("Keystream " + map.get("Count"), (String)map.get("MD"), hash); + } + } + } + else + { + map.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); + } } - System.out.println(xof.getAlgorithmName() + " test Exceptions pass"); } - private void mismatch(String name, String expected, byte[] found) { fail("mismatch on " + name, expected, new String(Hex.encode(found))); } - public static void main(String[] args) + private static void initEngine(AsconEngine ascon, boolean forEncryption) { - runTest(new AsconTest()); + int keySize = ascon.getKeyBytesSize(); + int ivSize = ascon.getIVBytesSize(); + int macSize = ivSize * 8; + + AEADParameters parameters = new AEADParameters(new KeyParameter(new byte[keySize]), macSize, new byte[ivSize], null); + ascon.init(forEncryption, parameters); } } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/AsymmetricConstraintsTest.java b/core/src/test/java/org/bouncycastle/crypto/test/AsymmetricConstraintsTest.java index 28293bf4ec..dd7eaa4887 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/AsymmetricConstraintsTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/AsymmetricConstraintsTest.java @@ -52,8 +52,8 @@ import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.generators.X25519KeyPairGenerator; import org.bouncycastle.crypto.generators.X448KeyPairGenerator; -import org.bouncycastle.crypto.kems.ECIESKeyEncapsulation; -import org.bouncycastle.crypto.kems.RSAKeyEncapsulation; +import org.bouncycastle.crypto.kems.RSAKEMExtractor; +import org.bouncycastle.crypto.kems.RSAKEMGenerator; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.CramerShoupKeyGenerationParameters; import org.bouncycastle.crypto.params.DHKeyGenerationParameters; @@ -79,7 +79,6 @@ import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.crypto.params.GOST3410KeyGenerationParameters; import org.bouncycastle.crypto.params.GOST3410Parameters; -import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.MQVPrivateParameters; import org.bouncycastle.crypto.params.MQVPublicParameters; import org.bouncycastle.crypto.params.NaccacheSternKeyGenerationParameters; @@ -220,12 +219,12 @@ private void test1024bitRSA() isEquals("service does not provide 112 bits of security only 80", e.getMessage()); } - signer1024Test(pk, sk, new RSADigestSigner(new SHA256Digest())); - signer1024Test(pk, sk, new PSSSigner(new RSAEngine(), new SHA256Digest(), 20)); - signer1024Test(pk, sk, new ISO9796d2PSSSigner(new RSAEngine(), new SHA256Digest(), 20)); - signer1024Test(pk, sk, new ISO9796d2Signer(new RSAEngine(), new SHA256Digest())); - signer1024Test(pk, sk, new X931Signer(new RSAEngine(), new SHA256Digest())); - signer1024Test(pk, sk, new GenericSigner(new RSAEngine(), new SHA256Digest())); + signer1024Test(pk, sk, new RSADigestSigner(SHA256Digest.newInstance())); + signer1024Test(pk, sk, new PSSSigner(new RSAEngine(), SHA256Digest.newInstance(), 20)); + signer1024Test(pk, sk, new ISO9796d2PSSSigner(new RSAEngine(), SHA256Digest.newInstance(), 20)); + signer1024Test(pk, sk, new ISO9796d2Signer(new RSAEngine(), SHA256Digest.newInstance())); + signer1024Test(pk, sk, new X931Signer(new RSAEngine(), SHA256Digest.newInstance())); + signer1024Test(pk, sk, new GenericSigner(new RSAEngine(), SHA256Digest.newInstance())); // legacy usage allowed for decryption. rsaEngine.init(false, sk); @@ -396,7 +395,7 @@ private void testEC() ecAgreementTest(kp.getPublic(), kp.getPrivate(), new ECDHCStagedAgreement()); ecAgreementTest(new ECDHUPublicParameters((ECPublicKeyParameters)kp.getPublic(), (ECPublicKeyParameters)kp.getPublic()), new ECDHUPrivateParameters((ECPrivateKeyParameters)kp.getPrivate(), (ECPrivateKeyParameters)kp.getPrivate()), new ECDHCUnifiedAgreement()); ecAgreementTest(new MQVPublicParameters((ECPublicKeyParameters)kp.getPublic(), (ECPublicKeyParameters)kp.getPublic()), new MQVPrivateParameters((ECPrivateKeyParameters)kp.getPrivate(), (ECPrivateKeyParameters)kp.getPrivate()), new ECMQVBasicAgreement()); - ecAgreementTest(kp.getPublic(), kp.getPrivate(), new ECVKOAgreement(new SHA256Digest())); + ecAgreementTest(kp.getPublic(), kp.getPrivate(), new ECVKOAgreement(SHA256Digest.newInstance())); try { @@ -860,11 +859,11 @@ private void testRsaKEM() KDF2BytesGenerator kdf = new KDF2BytesGenerator(new SHA1Digest()); SecureRandom rnd = new SecureRandom(); - RSAKeyEncapsulation rsaKem = new RSAKeyEncapsulation(kdf, rnd); + RSAKEMGenerator rsaKem = new RSAKEMGenerator(128 / 8, kdf, rnd); try { - rsaKem.init(kp.getPublic()); + rsaKem.generateEncapsulated(kp.getPublic()); fail("no exception"); } catch (CryptoServiceConstraintsException e) @@ -873,7 +872,7 @@ private void testRsaKEM() } // will pass as decryption - rsaKem.init(kp.getPrivate()); + RSAKEMExtractor rsaExt = new RSAKEMExtractor((RSAKeyParameters)kp.getPrivate(), 128 / 8, kdf); try { @@ -899,32 +898,32 @@ private void testECIESKEM() AsymmetricCipherKeyPair kp = ecKp.generateKeyPair(); byte[] out = new byte[49]; - ECIESKeyEncapsulation kem = new ECIESKeyEncapsulation(kdf, random); - - kem.init(kp.getPublic()); - KeyParameter key1 = (KeyParameter)kem.encrypt(out, 128); - - CryptoServicesRegistrar.setServicesConstraints(new LegacyBitsOfSecurityConstraint(128, 80)); - - - ECIESKeyEncapsulation eciesKEM = new ECIESKeyEncapsulation(kdf, random); - - try - { - eciesKEM.init(kp.getPublic()); - - eciesKEM.encrypt(new byte[0], 128); - fail("no exception"); - } - catch (CryptoServiceConstraintsException e) - { - isEquals(e.getMessage(), "service does not provide 128 bits of security only 96", e.getMessage()); - } - - // will pass as decryption - eciesKEM.init(kp.getPrivate()); - - eciesKEM.decrypt(out, 128); +// ECIESKeyEncapsulation kem = new ECIESKeyEncapsulation(kdf, random); +// +// kem.init(kp.getPublic()); +// KeyParameter key1 = (KeyParameter)kem.encrypt(out, 128); +// +// CryptoServicesRegistrar.setServicesConstraints(new LegacyBitsOfSecurityConstraint(128, 80)); +// +// +// ECIESKeyEncapsulation eciesKEM = new ECIESKeyEncapsulation(kdf, random); +// +// try +// { +// eciesKEM.init(kp.getPublic()); +// +// eciesKEM.encrypt(new byte[0], 128); +// fail("no exception"); +// } +// catch (CryptoServiceConstraintsException e) +// { +// isEquals(e.getMessage(), "service does not provide 128 bits of security only 96", e.getMessage()); +// } +// +// // will pass as decryption +// eciesKEM.init(kp.getPrivate()); +// +// eciesKEM.decrypt(out, 128); CryptoServicesRegistrar.setServicesConstraints(null); } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/BigSkippingCipherTest.java b/core/src/test/java/org/bouncycastle/crypto/test/BigSkippingCipherTest.java index c63b539e6b..6ca7bbd232 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/BigSkippingCipherTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/BigSkippingCipherTest.java @@ -8,6 +8,7 @@ import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.engines.ChaChaEngine; import org.bouncycastle.crypto.engines.Salsa20Engine; +import org.bouncycastle.crypto.modes.CTRModeCipher; import org.bouncycastle.crypto.modes.SICBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; @@ -23,8 +24,8 @@ public void testAESCTR() { CipherParameters externalCounterParams = new ParametersWithIV(new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), Hex.decode("00000000000000000000000000000000")); CipherParameters internalCounterParams = new ParametersWithIV(new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), Hex.decode("00000000000000000000")); - SICBlockCipher linearEngine = new SICBlockCipher(new AESEngine()); - SICBlockCipher skippingEngine = new SICBlockCipher(new AESEngine()); + CTRModeCipher linearEngine = SICBlockCipher.newInstance(AESEngine.newInstance()); + CTRModeCipher skippingEngine = SICBlockCipher.newInstance(AESEngine.newInstance()); Random random = new Random(); linearEngine.init(true, externalCounterParams); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/Blake2bDigestTest.java b/core/src/test/java/org/bouncycastle/crypto/test/Blake2bDigestTest.java index 8a7bc6428c..1e2cc74960 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/Blake2bDigestTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/Blake2bDigestTest.java @@ -1,7 +1,5 @@ package org.bouncycastle.crypto.test; -import java.io.UnsupportedEncodingException; - import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.Blake2bDigest; import org.bouncycastle.util.Arrays; @@ -124,23 +122,15 @@ public void performTest() for (int i = 0; i < unkeyedTestVectors.length; i++) { - try - { - // blake2bunkeyed.update( - // unkeyedTestVectors[i][1].getBytes("UTF-8")); - // test update(byte b) - byte[] unkeyedInput = unkeyedTestVectors[i][1] - .getBytes("UTF-8"); - for (int j = 0; j < unkeyedInput.length; j++) - { - blake2bunkeyed.update(unkeyedInput[j]); - } - } - catch (UnsupportedEncodingException e) + // blake2bunkeyed.update( + // unkeyedTestVectors[i][1].getBytes("UTF-8")); + // test update(byte b) + byte[] unkeyedInput = Strings.toUTF8ByteArray(unkeyedTestVectors[i][1]); + for (int j = 0; j < unkeyedInput.length; j++) { - // TODO Auto-generated catch block - e.printStackTrace(); + blake2bunkeyed.update(unkeyedInput[j]); } + byte[] unkeyedHash = new byte[64]; blake2bunkeyed.doFinal(unkeyedHash, 0); blake2bunkeyed.reset(); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/BlockCipherResetTest.java b/core/src/test/java/org/bouncycastle/crypto/test/BlockCipherResetTest.java index a35835b07a..f267ef5eaa 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/BlockCipherResetTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/BlockCipherResetTest.java @@ -67,18 +67,18 @@ public void performTest() testReset("XTEAEngine", new XTEAEngine(), new XTEAEngine(), new KeyParameter(new byte[16])); // primitive block cipher modes (don't reset on processBlock) - testModeReset("AES/CBC", new CBCBlockCipher(new AESEngine()), new CBCBlockCipher(new AESEngine()), + testModeReset("AES/CBC", CBCBlockCipher.newInstance(AESEngine.newInstance()), CBCBlockCipher.newInstance(AESEngine.newInstance()), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[16])); - testModeReset("AES/SIC", new SICBlockCipher(new AESEngine()), new SICBlockCipher(new AESEngine()), + testModeReset("AES/SIC", SICBlockCipher.newInstance(AESEngine.newInstance()), SICBlockCipher.newInstance(AESEngine.newInstance()), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[16])); - testModeReset("AES/CFB", new CFBBlockCipher(new AESEngine(), 128), new CFBBlockCipher(new AESEngine(), 128), + testModeReset("AES/CFB", CFBBlockCipher.newInstance(AESEngine.newInstance(), 128), CFBBlockCipher.newInstance(AESEngine.newInstance(), 128), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[16])); - testModeReset("AES/OFB", new OFBBlockCipher(new AESEngine(), 128), new OFBBlockCipher(new AESEngine(), 128), + testModeReset("AES/OFB", new OFBBlockCipher(AESEngine.newInstance(), 128), new OFBBlockCipher(AESEngine.newInstance(), 128), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[16])); testModeReset("AES/GCTR", new GOFBBlockCipher(new DESEngine()), new GOFBBlockCipher(new DESEngine()), new ParametersWithIV(new KeyParameter(new byte[8]), new byte[8])); - testModeReset("AES/OpenPGPCFB", new OpenPGPCFBBlockCipher(new AESEngine()), new OpenPGPCFBBlockCipher( - new AESEngine()), new KeyParameter(new byte[16])); + testModeReset("AES/OpenPGPCFB", new OpenPGPCFBBlockCipher(AESEngine.newInstance()), new OpenPGPCFBBlockCipher( + AESEngine.newInstance()), new KeyParameter(new byte[16])); testModeReset("AES/PGPCFB", new PGPCFBBlockCipher(new AESEngine(), false), new PGPCFBBlockCipher( new AESEngine(), false), new KeyParameter(new byte[16])); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/CCMTest.java b/core/src/test/java/org/bouncycastle/crypto/test/CCMTest.java index 2bbfe2a02b..b6511e2ae5 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/CCMTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/CCMTest.java @@ -7,6 +7,7 @@ import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -55,7 +56,7 @@ public class CCMTest public void performTest() throws Exception { - CCMBlockCipher ccm = new CCMBlockCipher(new AESEngine()); + CCMBlockCipher ccm = new CCMBlockCipher(AESEngine.newInstance()); checkVectors(0, ccm, K1, 32, N1, A1, P1, T1, C1); checkVectors(1, ccm, K2, 48, N2, A2, P2, T2, C2); @@ -150,11 +151,58 @@ public void performTest() // expected } - AEADTestUtil.testReset(this, new CCMBlockCipher(new AESEngine()), new CCMBlockCipher(new AESEngine()), new AEADParameters(new KeyParameter(K1), 32, N2)); + // For small number of allowed blocks, validate boundary + // conditions are properly handled. Zero and greater will + // fail as size bound is a strict inequality. + int[] offsets = new int[]{-10, -2, -1, 0, 1, 10}; + int[] ns = new int[]{13, 12}; + for (int i = 0; i != ns.length; i++) + { + int n_len = ns[i]; + for (int j = 0; j != offsets.length; j++) + { + int offset = offsets[j]; + try + { + ccm.init(true, new AEADParameters(new KeyParameter(K1), 128, new byte[n_len])); + + // Encrypt up to 2^(8q) + offset. Note that message length + // must be strictly less than 2^(8q) so offset=0 will not + // work (per SP 800-38C Section A.1 Length Requirements). + int q = 15 - n_len; + int size = 1 << (8*q); + inBuf = new byte[size + offset]; + + outBuf = new byte[ccm.getOutputSize(inBuf.length)]; + len = ccm.processPacket(inBuf, 0, inBuf.length, outBuf, 0); + + if (offset >= 0) { + fail("expected to fail to encrypt boundary bytes n=" + n_len + "size=" + size + " offset=" + offset); + } else { + // Decrypt should also succeed if encryption succeeded. + ccm.init(false, new AEADParameters(new KeyParameter(K1), 128, new byte[n_len])); + out = ccm.processPacket(outBuf, 0, outBuf.length); + + if (out.length != inBuf.length || !Arrays.areEqual(inBuf, out)) + { + fail("encryption output incorrect"); + } + } + } + catch (Exception e) + { + if (offset < 0) { + fail("unexpected failure to encrypt boundary bytes n=" + n_len + " offset=" + offset + " msg=" + e.getMessage()); + } + } + } + } + + AEADTestUtil.testReset(this, new CCMBlockCipher(AESEngine.newInstance()), new CCMBlockCipher(AESEngine.newInstance()), new AEADParameters(new KeyParameter(K1), 32, N2)); AEADTestUtil.testTampering(this, ccm, new AEADParameters(new KeyParameter(K1), 32, N2)); - AEADTestUtil.testOutputSizes(this, new CCMBlockCipher(new AESEngine()), new AEADParameters( + AEADTestUtil.testOutputSizes(this, new CCMBlockCipher(AESEngine.newInstance()), new AEADParameters( new KeyParameter(K1), 32, N2)); - AEADTestUtil.testBufferSizeChecks(this, new CCMBlockCipher(new AESEngine()), new AEADParameters( + AEADTestUtil.testBufferSizeChecks(this, new CCMBlockCipher(AESEngine.newInstance()), new AEADParameters( new KeyParameter(K1), 32, N2)); } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/CMacTest.java b/core/src/test/java/org/bouncycastle/crypto/test/CMacTest.java index bf81f69638..b14dddc478 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/CMacTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/CMacTest.java @@ -3,7 +3,6 @@ import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.engines.AESEngine; -import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.engines.BlowfishEngine; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.engines.DESedeEngine; @@ -67,7 +66,7 @@ public CMacTest() public void performTest() { - BlockCipher cipher = new AESFastEngine(); + BlockCipher cipher = AESEngine.newInstance(); Mac mac = new CMac(cipher, 128); //128 bytes key @@ -264,7 +263,7 @@ public void performTest() // CMAC with IV // 16 bytes message - 256 bytes key - mac = new CMacWithIV(new AESFastEngine()); + mac = new CMacWithIV(AESEngine.newInstance()); mac.init(key); @@ -282,7 +281,7 @@ public void performTest() // CMAC with IV // 16 bytes message - 256 bytes key - mac = new CMacWithIV(new AESFastEngine()); + mac = new CMacWithIV(AESEngine.newInstance()); mac.init(new ParametersWithIV(key, Hex.decode("000102030405060708090a0b0c0d0e0f"))); @@ -344,7 +343,7 @@ private void testExceptions() { try { - CMac mac = new CMac(new AESEngine()); + CMac mac = new CMac(AESEngine.newInstance()); mac.init(new ParametersWithIV(new KeyParameter(new byte[16]), new byte[16])); fail("CMac does not accept IV"); } catch(IllegalArgumentException e) diff --git a/core/src/test/java/org/bouncycastle/crypto/test/CTSTest.java b/core/src/test/java/org/bouncycastle/crypto/test/CTSTest.java index 9af56fc601..e59c95844b 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/CTSTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/CTSTest.java @@ -148,7 +148,7 @@ private void testExceptions() throws InvalidCipherTextException try { - new CTSBlockCipher(new SICBlockCipher(new AESEngine())); + new CTSBlockCipher(SICBlockCipher.newInstance(AESEngine.newInstance())); fail("Expected CTS construction error - only ECB/CBC supported."); } catch(IllegalArgumentException e) { @@ -184,28 +184,28 @@ public void performTest() byte[] aesIn3 = Hex.decode("4920776f756c64206c696b65207468652047656e6572616c2047617527732043"); byte[] aesOut3 = Hex.decode("39312523a78662d5be7fcbcc98ebf5a897687268d6ecccc0c07b25e25ecfe584"); - testCTS(4, new CBCBlockCipher(new AESEngine()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aesIn1, aesOut1); - testCTS(5, new CBCBlockCipher(new AESEngine()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aesIn2, aesOut2); - testCTS(6, new CBCBlockCipher(new AESEngine()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aesIn3, aesOut3); + testCTS(4, new CBCBlockCipher(AESEngine.newInstance()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aesIn1, aesOut1); + testCTS(5, new CBCBlockCipher(AESEngine.newInstance()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aesIn2, aesOut2); + testCTS(6, new CBCBlockCipher(AESEngine.newInstance()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aesIn3, aesOut3); - testOldCTS(4, new CBCBlockCipher(new AESEngine()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aesIn1, aesOut1); - testOldCTS(5, new CBCBlockCipher(new AESEngine()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aesIn2, aesOut2); - testOldCTS(6, new CBCBlockCipher(new AESEngine()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aesIn3, aesOut3); + testOldCTS(4, new CBCBlockCipher(AESEngine.newInstance()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aesIn1, aesOut1); + testOldCTS(5, new CBCBlockCipher(AESEngine.newInstance()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aesIn2, aesOut2); + testOldCTS(6, new CBCBlockCipher(AESEngine.newInstance()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aesIn3, aesOut3); byte[] aes1Block = Hex.decode("4920776f756c64206c696b6520746865"); byte[] preErrata = Hex.decode("e7664c13ff28c965b0d2a0e7ec353706"); // CTS style one block byte[] pstErrata = Hex.decode("97687268d6ecccc0c07b25e25ecfe584"); // CBC style one block byte[] pstErrataNonZeroIV = Hex.decode("571f5108c53fe95ab52df783df933fa3"); - testCTS(7, new CBCBlockCipher(new AESEngine()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aes1Block, pstErrata); - testCTS(8, new CBCBlockCipher(new AESEngine()), new ParametersWithIV(new KeyParameter(aes128), aes1Block), aes1Block, pstErrataNonZeroIV); - testOldCTS(9, new CBCBlockCipher(new AESEngine()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aes1Block, preErrata); + testCTS(7, new CBCBlockCipher(AESEngine.newInstance()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aes1Block, pstErrata); + testCTS(8, new CBCBlockCipher(AESEngine.newInstance()), new ParametersWithIV(new KeyParameter(aes128), aes1Block), aes1Block, pstErrataNonZeroIV); + testOldCTS(9, new CBCBlockCipher(AESEngine.newInstance()), new ParametersWithIV(new KeyParameter(aes128), new byte[16]), aes1Block, preErrata); byte[] aes128b = Hex.decode("aafd12f659cae63489b479e5076ddec2f06cb58faafd12f6"); byte[] aesIn1b = Hex.decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f"); byte[] aesOut1b = Hex.decode("6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04"); - testCTS(10, new CBCBlockCipher(new AESEngine()), new ParametersWithIV(new KeyParameter(aes128b), Hex.decode("aafd12f659cae63489b479e5076ddec2")), aesIn1b, aesOut1b); + testCTS(10, new CBCBlockCipher(AESEngine.newInstance()), new ParametersWithIV(new KeyParameter(aes128b), Hex.decode("aafd12f659cae63489b479e5076ddec2")), aesIn1b, aesOut1b); testExceptions(); } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/CipherStreamTest.java b/core/src/test/java/org/bouncycastle/crypto/test/CipherStreamTest.java index 1685084433..69d134ec33 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/CipherStreamTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/CipherStreamTest.java @@ -9,6 +9,7 @@ import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.DefaultBufferedBlockCipher; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.engines.BlowfishEngine; @@ -259,7 +260,6 @@ private void testWriteRead(Object cipher, CipherParameters params, boolean block * Test CipherOutputStream in ENCRYPT_MODE, CipherInputStream in DECRYPT_MODE */ private void testWriteReadEmpty(Object cipher, CipherParameters params, boolean blocks) - throws Exception { byte[] data = new byte[0]; @@ -402,7 +402,6 @@ protected void fail(String message, boolean authenticated, boolean bc) * Test CipherInputStream in ENCRYPT_MODE, CipherOutputStream in DECRYPT_MODE */ private void testReadWrite(Object cipher, CipherParameters params, boolean blocks) - throws Exception { String lCode = "ABCDEFGHIJKLMNOPQRSTU"; @@ -493,7 +492,7 @@ private void performTests() testModes(new RC2Engine(), new RC2Engine(), 16); testModes(new XTEAEngine(), new XTEAEngine(), 16); - testModes(new AESEngine(), new AESEngine(), 16); + testModes(AESEngine.newInstance(), AESEngine.newInstance(), 16); testModes(new NoekeonEngine(), new NoekeonEngine(), 16); testModes(new TwofishEngine(), new TwofishEngine(), 16); testModes(new CAST6Engine(), new CAST6Engine(), 16); @@ -510,11 +509,11 @@ private void performTests() testMode(new ChaChaEngine(), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[8])); testMode(new Grainv1Engine(), new ParametersWithIV(new KeyParameter(new byte[10]), new byte[8])); testMode(new Grain128Engine(), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[12])); - testMode(new HC128Engine(), new KeyParameter(new byte[16])); + testMode(new HC128Engine(), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[16])); testMode(new HC256Engine(), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[16])); testSkipping(new Salsa20Engine(), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[8])); - testSkipping(new SICBlockCipher(new AESEngine()), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[16])); + testSkipping(SICBlockCipher.newInstance(AESEngine.newInstance()), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[16])); } private void testModes(BlockCipher cipher1, BlockCipher cipher2, int keySize) @@ -528,11 +527,11 @@ private void testModes(BlockCipher cipher1, BlockCipher cipher2, int keySize) { testMode(new PaddedBufferedBlockCipher(cipher1, new PKCS7Padding()), key); - testMode(new PaddedBufferedBlockCipher(new CBCBlockCipher(cipher1), new PKCS7Padding()), withIv); + testMode(new PaddedBufferedBlockCipher(CBCBlockCipher.newInstance(cipher1), new PKCS7Padding()), withIv); - testMode(new BufferedBlockCipher(new OFBBlockCipher(cipher1, blockSize)), withIv); - testMode(new BufferedBlockCipher(new CFBBlockCipher(cipher1, blockSize)), withIv); - testMode(new BufferedBlockCipher(new SICBlockCipher(cipher1)), withIv); + testMode(new DefaultBufferedBlockCipher(new OFBBlockCipher(cipher1, blockSize)), withIv); + testMode(new DefaultBufferedBlockCipher(CFBBlockCipher.newInstance(cipher1, blockSize)), withIv); + testMode(new DefaultBufferedBlockCipher(SICBlockCipher.newInstance(cipher1)), withIv); } // CTS requires at least one block if (blockSize <= 16 && streamSize >= blockSize) @@ -551,7 +550,7 @@ private void testModes(BlockCipher cipher1, BlockCipher cipher2, int keySize) } if (blockSize == 16) { - testMode(new CCMBlockCipher(cipher1), new ParametersWithIV(key, new byte[7])); + testMode(CCMBlockCipher.newInstance(cipher1), new ParametersWithIV(key, new byte[7])); // TODO: need to have a GCM safe version of testMode. // testMode(new GCMBlockCipher(cipher1), withIv); testMode(new OCBBlockCipher(cipher1, cipher2), new ParametersWithIV(key, new byte[15])); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/DSATest.java b/core/src/test/java/org/bouncycastle/crypto/test/DSATest.java index 09c84d35b5..609cc3c20b 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/DSATest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/DSATest.java @@ -443,7 +443,7 @@ private void dsa2Test3() { byte[] seed = Hex.decode("4783081972865EA95D43318AB2EAF9C61A2FC7BBF1B772A09017BDF5A58F4FF0"); - DSAParametersGenerator pGen = new DSAParametersGenerator(new SHA256Digest()); + DSAParametersGenerator pGen = new DSAParametersGenerator(SHA256Digest.newInstance()); pGen.init(new DSAParameterGenerationParameters(2048, 256, 80, new DSATestSecureRandom(seed))); @@ -563,7 +563,7 @@ private void dsa2Test4() { byte[] seed = Hex.decode("193AFCA7C1E77B3C1ECC618C81322E47B8B8B997C9C83515C59CC446C2D9BD47"); - DSAParametersGenerator pGen = new DSAParametersGenerator(new SHA256Digest()); + DSAParametersGenerator pGen = new DSAParametersGenerator(SHA256Digest.newInstance()); pGen.init(new DSAParameterGenerationParameters(3072, 256, 80, new DSATestSecureRandom(seed))); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/DSTU4145Test.java b/core/src/test/java/org/bouncycastle/crypto/test/DSTU4145Test.java index d26e325292..c3023dd5da 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/DSTU4145Test.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/DSTU4145Test.java @@ -47,7 +47,7 @@ private void test163() BigInteger r = new BigInteger("274ea2c0caa014a0d80a424f59ade7a93068d08a7", 16); BigInteger s = new BigInteger("2100d86957331832b8e8c230f5bd6a332b3615aca", 16); - ECCurve.F2m curve = new ECCurve.F2m(163, 3, 6, 7, ONE, new BigInteger("5FF6108462A2DC8210AB403925E638A19C1455D21", 16)); + ECCurve.F2m curve = new ECCurve.F2m(163, 3, 6, 7, ONE, new BigInteger("5FF6108462A2DC8210AB403925E638A19C1455D21", 16), null, null); ECPoint P = curve.createPoint(new BigInteger("72d867f93a93ac27df9ff01affe74885c8c540420", 16), new BigInteger("0224a9c3947852b97c5599d5f4ab81122adc3fd9b", 16)); BigInteger n = new BigInteger("400000000000000000002BEC12BE2262D39BCF14D", 16); @@ -95,7 +95,7 @@ private void test173() BigInteger r = new BigInteger("13ae89746386709cdbd237cc5ec20ca30004a82ead8", 16); BigInteger s = new BigInteger("3597912cdd093b3e711ccb74a79d3c4ab4c7cccdc60", 16); - ECCurve.F2m curve = new ECCurve.F2m(173, 1, 2, 10, ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16)); + ECCurve.F2m curve = new ECCurve.F2m(173, 1, 2, 10, ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16), null, null); ECPoint P = curve.createPoint(new BigInteger("BE6628EC3E67A91A4E470894FBA72B52C515F8AEE9", 16), new BigInteger("D9DEEDF655CF5412313C11CA566CDC71F4DA57DB45C", 16)); BigInteger n = new BigInteger("800000000000000000000189B4E67606E3825BB2831", 16); @@ -143,7 +143,7 @@ private void test283() BigInteger r = new BigInteger("12a5edcc38d92208ff23036d75b000c7e4bc0f9af2d40b35f15d6fd15e01234e67781a8", 16); BigInteger s = new BigInteger("2de0775577f75b643cf5afc80d4fe10b21100690f17e2cab7bdc9b50ec87c5727aeb515", 16); - ECCurve.F2m curve = new ECCurve.F2m(283, 5, 7, 12, ONE, new BigInteger("27B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", 16)); + ECCurve.F2m curve = new ECCurve.F2m(283, 5, 7, 12, ONE, new BigInteger("27B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", 16), null, null); ECPoint P = curve.createPoint(new BigInteger("4D95820ACE761110824CE425C8089129487389B7F0E0A9D043DDC0BB0A4CC9EB25", 16), new BigInteger("954C9C4029B2C62DE35C2B9C2A164984BF1101951E3A68ED03DF234DDE5BB2013152F2", 16)); BigInteger n = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", 16); @@ -191,7 +191,7 @@ private void test431() BigInteger r = new BigInteger("1911fefb1f494bebcf8dffdf5276946ff9c9f662192ee18c718db47310a439c784fe07577b16e1edbe16179876e0792a634f1c9c3a2e", 16); BigInteger s = new BigInteger("3852170ee801c2083c52f1ea77b987a5432acecd9c654f064e87bf179e0a397151edbca430082e43bd38a67b55424b5bbc7f2713f620", 16); - ECCurve.F2m curve = new ECCurve.F2m(431, 1, 3, 5, ONE, new BigInteger("3CE10490F6A708FC26DFE8C3D27C4F94E690134D5BFF988D8D28AAEAEDE975936C66BAC536B18AE2DC312CA493117DAA469C640CAF3", 16)); + ECCurve.F2m curve = new ECCurve.F2m(431, 1, 3, 5, ONE, new BigInteger("3CE10490F6A708FC26DFE8C3D27C4F94E690134D5BFF988D8D28AAEAEDE975936C66BAC536B18AE2DC312CA493117DAA469C640CAF3", 16), null, null); ECPoint P = curve.createPoint(new BigInteger("9548BCDF314CEEEAF099C780FFEFBF93F9FE5B5F55547603C9C8FC1A2774170882B3BE35E892C6D4296B8DEA282EC30FB344272791", 16), new BigInteger("4C6CBD7C62A8EEEFDE17A8B5E196E49A22CE6DE128ABD9FBD81FA4411AD5A38E2A810BEDE09A7C6226BCDCB4A4A5DA37B4725E00AA74", 16)); BigInteger n = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA3175458009A8C0A724F02F81AA8A1FCBAF80D90C7A95110504CF", 16); @@ -230,7 +230,7 @@ private void testTruncation() // use extra long "hash" with set bits... byte[] hash = Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); - ECCurve.F2m curve = new ECCurve.F2m(173, 1, 2, 10, ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16)); + ECCurve.F2m curve = new ECCurve.F2m(173, 1, 2, 10, ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16), null, null); ECPoint P = curve.createPoint(new BigInteger("BE6628EC3E67A91A4E470894FBA72B52C515F8AEE9", 16), new BigInteger("D9DEEDF655CF5412313C11CA566CDC71F4DA57DB45C", 16)); BigInteger n = new BigInteger("800000000000000000000189B4E67606E3825BB2831", 16); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/DeterministicDSATest.java b/core/src/test/java/org/bouncycastle/crypto/test/DeterministicDSATest.java index ed5433240b..3018d4884b 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/DeterministicDSATest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/DeterministicDSATest.java @@ -51,13 +51,13 @@ private void testHMacDeterministic() doTestHMACDetDSASample(new SHA1Digest(), privKey, new BigInteger("2E1A0C2562B2912CAAF89186FB0F42001585DA55", 16), new BigInteger("29EFB6B0AFF2D7A68EB70CA313022253B9A88DF5", 16)); doTestHMACDetDSASample(new SHA224Digest(), privKey, new BigInteger("4BC3B686AEA70145856814A6F1BB53346F02101E", 16), new BigInteger("410697B92295D994D21EDD2F4ADA85566F6F94C1", 16)); - doTestHMACDetDSASample(new SHA256Digest(), privKey, new BigInteger("81F2F5850BE5BC123C43F71A3033E9384611C545", 16), new BigInteger("4CDD914B65EB6C66A8AAAD27299BEE6B035F5E89", 16)); + doTestHMACDetDSASample(SHA256Digest.newInstance(), privKey, new BigInteger("81F2F5850BE5BC123C43F71A3033E9384611C545", 16), new BigInteger("4CDD914B65EB6C66A8AAAD27299BEE6B035F5E89", 16)); doTestHMACDetDSASample(new SHA384Digest(), privKey, new BigInteger("07F2108557EE0E3921BC1774F1CA9B410B4CE65A", 16), new BigInteger("54DF70456C86FAC10FAB47C1949AB83F2C6F7595", 16)); doTestHMACDetDSASample(new SHA512Digest(), privKey, new BigInteger("16C3491F9B8C3FBBDD5E7A7B667057F0D8EE8E1B", 16), new BigInteger("02C36A127A7B89EDBB72E4FFBC71DABC7D4FC69C", 16)); doTestHMACDetDSATest(new SHA1Digest(), privKey, new BigInteger("42AB2052FD43E123F0607F115052A67DCD9C5C77", 16), new BigInteger("183916B0230D45B9931491D4C6B0BD2FB4AAF088", 16)); doTestHMACDetDSATest(new SHA224Digest(), privKey, new BigInteger("6868E9964E36C1689F6037F91F28D5F2C30610F2", 16), new BigInteger("49CEC3ACDC83018C5BD2674ECAAD35B8CD22940F", 16)); - doTestHMACDetDSATest(new SHA256Digest(), privKey, new BigInteger("22518C127299B0F6FDC9872B282B9E70D0790812", 16), new BigInteger("6837EC18F150D55DE95B5E29BE7AF5D01E4FE160", 16)); + doTestHMACDetDSATest(SHA256Digest.newInstance(), privKey, new BigInteger("22518C127299B0F6FDC9872B282B9E70D0790812", 16), new BigInteger("6837EC18F150D55DE95B5E29BE7AF5D01E4FE160", 16)); doTestHMACDetDSATest(new SHA384Digest(), privKey, new BigInteger("854CF929B58D73C3CBFDC421E8D5430CD6DB5E66", 16), new BigInteger("91D0E0F53E22F898D158380676A871A157CDA622", 16)); doTestHMACDetDSATest(new SHA512Digest(), privKey, new BigInteger("8EA47E475BA8AC6F2D821DA3BD212D11A3DEB9A0", 16), new BigInteger("7C670C7AD72B6C050C109E1790008097125433E8", 16)); @@ -89,13 +89,13 @@ private void testHMacDeterministic() doTestHMACDetDSASample(new SHA1Digest(), privKey, new BigInteger("3A1B2DBD7489D6ED7E608FD036C83AF396E290DBD602408E8677DAABD6E7445A", 16), new BigInteger("D26FCBA19FA3E3058FFC02CA1596CDBB6E0D20CB37B06054F7E36DED0CDBBCCF", 16)); doTestHMACDetDSASample(new SHA224Digest(), privKey, new BigInteger("DC9F4DEADA8D8FF588E98FED0AB690FFCE858DC8C79376450EB6B76C24537E2C", 16), new BigInteger("A65A9C3BC7BABE286B195D5DA68616DA8D47FA0097F36DD19F517327DC848CEC", 16)); - doTestHMACDetDSASample(new SHA256Digest(), privKey, new BigInteger("EACE8BDBBE353C432A795D9EC556C6D021F7A03F42C36E9BC87E4AC7932CC809", 16), new BigInteger("7081E175455F9247B812B74583E9E94F9EA79BD640DC962533B0680793A38D53", 16)); + doTestHMACDetDSASample(SHA256Digest.newInstance(), privKey, new BigInteger("EACE8BDBBE353C432A795D9EC556C6D021F7A03F42C36E9BC87E4AC7932CC809", 16), new BigInteger("7081E175455F9247B812B74583E9E94F9EA79BD640DC962533B0680793A38D53", 16)); doTestHMACDetDSASample(new SHA384Digest(), privKey, new BigInteger("B2DA945E91858834FD9BF616EBAC151EDBC4B45D27D0DD4A7F6A22739F45C00B", 16), new BigInteger("19048B63D9FD6BCA1D9BAE3664E1BCB97F7276C306130969F63F38FA8319021B", 16)); doTestHMACDetDSASample(new SHA512Digest(), privKey, new BigInteger("2016ED092DC5FB669B8EFB3D1F31A91EECB199879BE0CF78F02BA062CB4C942E", 16), new BigInteger("D0C76F84B5F091E141572A639A4FB8C230807EEA7D55C8A154A224400AFF2351", 16)); doTestHMACDetDSATest(new SHA1Digest(), privKey, new BigInteger("C18270A93CFC6063F57A4DFA86024F700D980E4CF4E2CB65A504397273D98EA0", 16), new BigInteger("414F22E5F31A8B6D33295C7539C1C1BA3A6160D7D68D50AC0D3A5BEAC2884FAA", 16)); doTestHMACDetDSATest(new SHA224Digest(), privKey, new BigInteger("272ABA31572F6CC55E30BF616B7A265312018DD325BE031BE0CC82AA17870EA3", 16), new BigInteger("E9CC286A52CCE201586722D36D1E917EB96A4EBDB47932F9576AC645B3A60806", 16)); - doTestHMACDetDSATest(new SHA256Digest(), privKey, new BigInteger("8190012A1969F9957D56FCCAAD223186F423398D58EF5B3CEFD5A4146A4476F0", 16), new BigInteger("7452A53F7075D417B4B013B278D1BB8BBD21863F5E7B1CEE679CF2188E1AB19E", 16)); + doTestHMACDetDSATest(SHA256Digest.newInstance(), privKey, new BigInteger("8190012A1969F9957D56FCCAAD223186F423398D58EF5B3CEFD5A4146A4476F0", 16), new BigInteger("7452A53F7075D417B4B013B278D1BB8BBD21863F5E7B1CEE679CF2188E1AB19E", 16)); doTestHMACDetDSATest(new SHA384Digest(), privKey, new BigInteger("239E66DDBE8F8C230A3D071D601B6FFBDFB5901F94D444C6AF56F732BEB954BE", 16), new BigInteger("6BD737513D5E72FE85D1C750E0F73921FE299B945AAD1C802F15C26A43D34961", 16)); doTestHMACDetDSATest(new SHA512Digest(), privKey, new BigInteger("89EC4BB1400ECCFF8E7D9AA515CD1DE7803F2DAFF09693EE7FD1353E90A68307", 16), new BigInteger("C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1", 16)); } @@ -120,13 +120,13 @@ private void testECHMacDeterministic() doTestHMACDetECDSASample(new SHA1Digest(), privKey, new BigInteger("98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF", 16), new BigInteger("57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64", 16)); doTestHMACDetECDSASample(new SHA224Digest(), privKey, new BigInteger("A1F00DAD97AEEC91C95585F36200C65F3C01812AA60378F5", 16), new BigInteger("E07EC1304C7C6C9DEBBE980B9692668F81D4DE7922A0F97A", 16)); - doTestHMACDetECDSASample(new SHA256Digest(), privKey, new BigInteger("4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55", 16), new BigInteger("CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85", 16)); + doTestHMACDetECDSASample(SHA256Digest.newInstance(), privKey, new BigInteger("4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55", 16), new BigInteger("CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85", 16)); doTestHMACDetECDSASample(new SHA384Digest(), privKey, new BigInteger("DA63BF0B9ABCF948FBB1E9167F136145F7A20426DCC287D5", 16), new BigInteger("C3AA2C960972BD7A2003A57E1C4C77F0578F8AE95E31EC5E", 16)); doTestHMACDetECDSASample(new SHA512Digest(), privKey, new BigInteger("4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8", 16), new BigInteger("3F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67", 16)); doTestHMACDetECDSATest(new SHA1Digest(), privKey, new BigInteger("0F2141A0EBBC44D2E1AF90A50EBCFCE5E197B3B7D4DE036D", 16), new BigInteger("EB18BC9E1F3D7387500CB99CF5F7C157070A8961E38700B7", 16)); doTestHMACDetECDSATest(new SHA224Digest(), privKey, new BigInteger("6945A1C1D1B2206B8145548F633BB61CEF04891BAF26ED34", 16), new BigInteger("B7FB7FDFC339C0B9BD61A9F5A8EAF9BE58FC5CBA2CB15293", 16)); - doTestHMACDetECDSATest(new SHA256Digest(), privKey, new BigInteger("3A718BD8B4926C3B52EE6BBE67EF79B18CB6EB62B1AD97AE", 16), new BigInteger("5662E6848A4A19B1F1AE2F72ACD4B8BBE50F1EAC65D9124F", 16)); + doTestHMACDetECDSATest(SHA256Digest.newInstance(), privKey, new BigInteger("3A718BD8B4926C3B52EE6BBE67EF79B18CB6EB62B1AD97AE", 16), new BigInteger("5662E6848A4A19B1F1AE2F72ACD4B8BBE50F1EAC65D9124F", 16)); doTestHMACDetECDSATest(new SHA384Digest(), privKey, new BigInteger("B234B60B4DB75A733E19280A7A6034BD6B1EE88AF5332367", 16), new BigInteger("7994090B2D59BB782BE57E74A44C9A1C700413F8ABEFE77A", 16)); doTestHMACDetECDSATest(new SHA512Digest(), privKey, new BigInteger("FE4F4AE86A58B6507946715934FE2D8FF9D95B6B098FE739", 16), new BigInteger("74CF5605C98FBA0E1EF34D4B5A1577A7DCF59457CAE52290", 16)); @@ -142,13 +142,13 @@ private void testECHMacDeterministic() doTestHMACDetECDSASample(new SHA1Digest(), privKey, new BigInteger("22226F9D40A96E19C4A301CE5B74B115303C0F3A4FD30FC257FB57AC", 16), new BigInteger("66D1CDD83E3AF75605DD6E2FEFF196D30AA7ED7A2EDF7AF475403D69", 16)); doTestHMACDetECDSASample(new SHA224Digest(), privKey, new BigInteger("1CDFE6662DDE1E4A1EC4CDEDF6A1F5A2FB7FBD9145C12113E6ABFD3E", 16), new BigInteger("A6694FD7718A21053F225D3F46197CA699D45006C06F871808F43EBC", 16)); - doTestHMACDetECDSASample(new SHA256Digest(), privKey, new BigInteger("61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA", 16), new BigInteger("BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101", 16)); + doTestHMACDetECDSASample(SHA256Digest.newInstance(), privKey, new BigInteger("61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA", 16), new BigInteger("BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101", 16)); doTestHMACDetECDSASample(new SHA384Digest(), privKey, new BigInteger("0B115E5E36F0F9EC81F1325A5952878D745E19D7BB3EABFABA77E953", 16), new BigInteger("830F34CCDFE826CCFDC81EB4129772E20E122348A2BBD889A1B1AF1D", 16)); doTestHMACDetECDSASample(new SHA512Digest(), privKey, new BigInteger("074BD1D979D5F32BF958DDC61E4FB4872ADCAFEB2256497CDAC30397", 16), new BigInteger("A4CECA196C3D5A1FF31027B33185DC8EE43F288B21AB342E5D8EB084", 16)); doTestHMACDetECDSATest(new SHA1Digest(), privKey, new BigInteger("DEAA646EC2AF2EA8AD53ED66B2E2DDAA49A12EFD8356561451F3E21C", 16), new BigInteger("95987796F6CF2062AB8135271DE56AE55366C045F6D9593F53787BD2", 16)); doTestHMACDetECDSATest(new SHA224Digest(), privKey, new BigInteger("C441CE8E261DED634E4CF84910E4C5D1D22C5CF3B732BB204DBEF019", 16), new BigInteger("902F42847A63BDC5F6046ADA114953120F99442D76510150F372A3F4", 16)); - doTestHMACDetECDSATest(new SHA256Digest(), privKey, new BigInteger("AD04DDE87B84747A243A631EA47A1BA6D1FAA059149AD2440DE6FBA6", 16), new BigInteger("178D49B1AE90E3D8B629BE3DB5683915F4E8C99FDF6E666CF37ADCFD", 16)); + doTestHMACDetECDSATest(SHA256Digest.newInstance(), privKey, new BigInteger("AD04DDE87B84747A243A631EA47A1BA6D1FAA059149AD2440DE6FBA6", 16), new BigInteger("178D49B1AE90E3D8B629BE3DB5683915F4E8C99FDF6E666CF37ADCFD", 16)); doTestHMACDetECDSATest(new SHA384Digest(), privKey, new BigInteger("389B92682E399B26518A95506B52C03BC9379A9DADF3391A21FB0EA4", 16), new BigInteger("414A718ED3249FF6DBC5B50C27F71F01F070944DA22AB1F78F559AAB", 16)); doTestHMACDetECDSATest(new SHA512Digest(), privKey, new BigInteger("049F050477C5ADD858CAC56208394B5A55BAEBBE887FDF765047C17C", 16), new BigInteger("077EB13E7005929CEFA3CD0403C7CDCC077ADF4E44F3C41B2F60ECFF", 16)); @@ -159,13 +159,13 @@ private void testECHMacDeterministic() doTestHMACDetECDSASample(new SHA1Digest(), privKey, new BigInteger("61340C88C3AAEBEB4F6D667F672CA9759A6CCAA9FA8811313039EE4A35471D32", 16), new BigInteger("6D7F147DAC089441BB2E2FE8F7A3FA264B9C475098FDCF6E00D7C996E1B8B7EB", 16)); doTestHMACDetECDSASample(new SHA224Digest(), privKey, new BigInteger("53B2FFF5D1752B2C689DF257C04C40A587FABABB3F6FC2702F1343AF7CA9AA3F", 16), new BigInteger("B9AFB64FDC03DC1A131C7D2386D11E349F070AA432A4ACC918BEA988BF75C74C", 16)); - doTestHMACDetECDSASample(new SHA256Digest(), privKey, new BigInteger("EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716", 16), new BigInteger("F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8", 16)); + doTestHMACDetECDSASample(SHA256Digest.newInstance(), privKey, new BigInteger("EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716", 16), new BigInteger("F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8", 16)); doTestHMACDetECDSASample(new SHA384Digest(), privKey, new BigInteger("0EAFEA039B20E9B42309FB1D89E213057CBF973DC0CFC8F129EDDDC800EF7719", 16), new BigInteger("4861F0491E6998B9455193E34E7B0D284DDD7149A74B95B9261F13ABDE940954", 16)); doTestHMACDetECDSASample(new SHA512Digest(), privKey, new BigInteger("8496A60B5E9B47C825488827E0495B0E3FA109EC4568FD3F8D1097678EB97F00", 16), new BigInteger("2362AB1ADBE2B8ADF9CB9EDAB740EA6049C028114F2460F96554F61FAE3302FE", 16)); doTestHMACDetECDSATest(new SHA1Digest(), privKey, new BigInteger("0CBCC86FD6ABD1D99E703E1EC50069EE5C0B4BA4B9AC60E409E8EC5910D81A89", 16), new BigInteger("01B9D7B73DFAA60D5651EC4591A0136F87653E0FD780C3B1BC872FFDEAE479B1", 16)); doTestHMACDetECDSATest(new SHA224Digest(), privKey, new BigInteger("C37EDB6F0AE79D47C3C27E962FA269BB4F441770357E114EE511F662EC34A692", 16), new BigInteger("C820053A05791E521FCAAD6042D40AEA1D6B1A540138558F47D0719800E18F2D", 16)); - doTestHMACDetECDSATest(new SHA256Digest(), privKey, new BigInteger("F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367", 16), new BigInteger("019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083", 16)); + doTestHMACDetECDSATest(SHA256Digest.newInstance(), privKey, new BigInteger("F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367", 16), new BigInteger("019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083", 16)); doTestHMACDetECDSATest(new SHA384Digest(), privKey, new BigInteger("83910E8B48BB0C74244EBDF7F07A1C5413D61472BD941EF3920E623FBCCEBEB6", 16), new BigInteger("8DDBEC54CF8CD5874883841D712142A56A8D0F218F5003CB0296B6B509619F2C", 16)); doTestHMACDetECDSATest(new SHA512Digest(), privKey, new BigInteger("461D93F31B6540894788FD206C07CFA0CC35F46FA3C91816FFF1040AD1581A04", 16), new BigInteger("39AF9F15DE0DB8D97E72719C74820D304CE5226E32DEDAE67519E840D1194E55", 16)); @@ -183,7 +183,7 @@ private void testECHMacDeterministic() "450F76EE3DE43F5A125333A6BE060122", 16), new BigInteger("9DA0C81787064021E78DF658F2FBB0B042BF304665DB721F077A4298B095E483" + "4C082C03D83028EFBF93A3C23940CA8D", 16)); - doTestHMACDetECDSASample(new SHA256Digest(), privKey, new BigInteger("21B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A21D3DAA33" + + doTestHMACDetECDSASample(SHA256Digest.newInstance(), privKey, new BigInteger("21B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A21D3DAA33" + "BDE1E888E63355D92FA2B3C36D8FB2CD", 16), new BigInteger("F3AA443FB107745BF4BD77CB3891674632068A10CA67E3D45DB2266FA7D1FEEB" + "EFDC63ECCD1AC42EC0CB8668A4FA0AB0", 16)); @@ -204,7 +204,7 @@ private void testECHMacDeterministic() "64A9A817C47FF78B8C11066B24080E72", 16), new BigInteger("07041D4A7A0379AC7232FF72E6F77B6DDB8F09B16CCE0EC3286B2BD43FA8C614" + "1C53EA5ABEF0D8231077A04540A96B66", 16)); - doTestHMACDetECDSATest(new SHA256Digest(), privKey, new BigInteger("6D6DEFAC9AB64DABAFE36C6BF510352A4CC27001263638E5B16D9BB51D451559" + + doTestHMACDetECDSATest(SHA256Digest.newInstance(), privKey, new BigInteger("6D6DEFAC9AB64DABAFE36C6BF510352A4CC27001263638E5B16D9BB51D451559" + "F918EEDAF2293BE5B475CC8F0188636B", 16), new BigInteger("2D46F3BECBCC523D5F1A1256BF0C9B024D879BA9E838144C8BA6BAEB4B53B47D" + "51AB373F9845C0514EEFB14024787265", 16)); @@ -236,7 +236,7 @@ private void testECHMacDeterministic() new BigInteger("050CB5265417FE2320BBB5A122B8E1A32BD699089851128E360E620A30C7E17B" + "A41A666AF126CE100E5799B153B60528D5300D08489CA9178FB610A2006C254B" + "41F", 16)); - doTestHMACDetECDSASample(new SHA256Digest(), privKey, new BigInteger("1511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659" + + doTestHMACDetECDSASample(SHA256Digest.newInstance(), privKey, new BigInteger("1511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659" + "D16876E25C7C1E57648F23B73564D67F61C6F14D527D54972810421E7D87589E" + "1A7", 16), new BigInteger("04A171143A83163D6DF460AAF61522695F207A58B95C0644D87E52AA1A347916" + @@ -267,7 +267,7 @@ private void testECHMacDeterministic() new BigInteger("177336676304FCB343CE028B38E7B4FBA76C1C1B277DA18CAD2A8478B2A9A9F5" + "BEC0F3BA04F35DB3E4263569EC6AADE8C92746E4C82F8299AE1B8F1739F8FD51" + "9A4", 16)); - doTestHMACDetECDSATest(new SHA256Digest(), privKey, new BigInteger("00E871C4A14F993C6C7369501900C4BC1E9C7B0B4BA44E04868B30B41D807104" + + doTestHMACDetECDSATest(SHA256Digest.newInstance(), privKey, new BigInteger("00E871C4A14F993C6C7369501900C4BC1E9C7B0B4BA44E04868B30B41D807104" + "2EB28C4C250411D0CE08CD197E4188EA4876F279F90B3D8D74A3C76E6F1E4656" + "AA8", 16), new BigInteger("0CD52DBAA33B063C3A6CD8058A1FB0A46A4754B034FCC644766CA14DA8CA5CA9" + @@ -293,13 +293,13 @@ private void testECHMacDeterministic() doTestHMACDetECDSASample(new SHA1Digest(), privKey, new BigInteger("153FEBD179A69B6122DEBF5BC61EB947B24C93526", 16), new BigInteger("37AC9C670F8CF18045049BAE7DD35553545C19E49", 16)); doTestHMACDetECDSASample(new SHA224Digest(), privKey, new BigInteger("0A379E69C44F9C16EA3215EA39EB1A9B5D58CC955", 16), new BigInteger("04BAFF5308DA2A7FE2C1742769265AD3ED1D24E74", 16)); - doTestHMACDetECDSASample(new SHA256Digest(), privKey, new BigInteger("134E00F78FC1CB9501675D91C401DE20DDF228CDC", 16), new BigInteger("373273AEC6C36CB7BAFBB1903A5F5EA6A1D50B624", 16)); + doTestHMACDetECDSASample(SHA256Digest.newInstance(), privKey, new BigInteger("134E00F78FC1CB9501675D91C401DE20DDF228CDC", 16), new BigInteger("373273AEC6C36CB7BAFBB1903A5F5EA6A1D50B624", 16)); doTestHMACDetECDSASample(new SHA384Digest(), privKey, new BigInteger("29430B935AF8E77519B0CA4F6903B0B82E6A21A66", 16), new BigInteger("1EA1415306E9353FA5AA54BC7C2581DFBB888440D", 16)); doTestHMACDetECDSASample(new SHA512Digest(), privKey, new BigInteger("0B2F177A99F9DF2D51CCAF55F015F326E4B65E7A0", 16), new BigInteger("0DF1FB4487E9B120C5E970EFE48F55E406306C3A1", 16)); doTestHMACDetECDSATest(new SHA1Digest(), privKey, new BigInteger("256D4079C6C7169B8BC92529D701776A269D56308", 16), new BigInteger("341D3FFEC9F1EB6A6ACBE88E3C86A1C8FDEB8B8E1", 16)); doTestHMACDetECDSATest(new SHA224Digest(), privKey, new BigInteger("28ECC6F1272CE80EA59DCF32F7AC2D861BA803393", 16), new BigInteger("0AD4AE2C06E60183C1567D2B82F19421FE3053CE2", 16)); - doTestHMACDetECDSATest(new SHA256Digest(), privKey, new BigInteger("227DF377B3FA50F90C1CB3CDCBBDBA552C1D35104", 16), new BigInteger("1F7BEAD92583FE920D353F368C1960D0E88B46A56", 16)); + doTestHMACDetECDSATest(SHA256Digest.newInstance(), privKey, new BigInteger("227DF377B3FA50F90C1CB3CDCBBDBA552C1D35104", 16), new BigInteger("1F7BEAD92583FE920D353F368C1960D0E88B46A56", 16)); doTestHMACDetECDSATest(new SHA384Digest(), privKey, new BigInteger("11811DAFEEA441845B6118A0DFEE8A0061231337D", 16), new BigInteger("36258301865EE48C5C6F91D63F62695002AB55B57", 16)); doTestHMACDetECDSATest(new SHA512Digest(), privKey, new BigInteger("3B6BB95CA823BE2ED8E3972FF516EB8972D765571", 16), new BigInteger("13DC6F420628969DF900C3FCC48220B38BE24A541", 16)); @@ -310,13 +310,13 @@ private void testECHMacDeterministic() doTestHMACDetECDSASample(new SHA1Digest(), privKey, new BigInteger("015CC6FD78BB06E0878E71465515EA5A21A2C18E6FC77B4B158DBEB3944", 16), new BigInteger("0822A4A6C2EB2DF213A5E90BF40377956365EE8C4B4A5A4E2EB9270CB6A", 16)); doTestHMACDetECDSASample(new SHA224Digest(), privKey, new BigInteger("05D9920B53471148E10502AB49AB7A3F11084820A074FD89883CF51BC1A", 16), new BigInteger("04D3938900C0A9AAA7080D1DFEB56CFB0FADABE4214536C7ED5117ED13A", 16)); - doTestHMACDetECDSASample(new SHA256Digest(), privKey, new BigInteger("0A797F3B8AEFCE7456202DF1E46CCC291EA5A49DA3D4BDDA9A4B62D5E0D", 16), new BigInteger("01F6F81DA55C22DA4152134C661588F4BD6F82FDBAF0C5877096B070DC2", 16)); + doTestHMACDetECDSASample(SHA256Digest.newInstance(), privKey, new BigInteger("0A797F3B8AEFCE7456202DF1E46CCC291EA5A49DA3D4BDDA9A4B62D5E0D", 16), new BigInteger("01F6F81DA55C22DA4152134C661588F4BD6F82FDBAF0C5877096B070DC2", 16)); doTestHMACDetECDSASample(new SHA384Digest(), privKey, new BigInteger("015E85A8D46225DD7E314A1C4289731FC14DECE949349FE535D11043B85", 16), new BigInteger("03F189D37F50493EFD5111A129443A662AB3C6B289129AD8C0CAC85119C", 16)); doTestHMACDetECDSASample(new SHA512Digest(), privKey, new BigInteger("03B62A4BF783919098B1E42F496E65F7621F01D1D466C46940F0F132A95", 16), new BigInteger("0F4BE031C6E5239E7DAA014CBBF1ED19425E49DAEB426EC9DF4C28A2E30", 16)); doTestHMACDetECDSATest(new SHA1Digest(), privKey, new BigInteger("02F1FEDC57BE203E4C8C6B8C1CEB35E13C1FCD956AB41E3BD4C8A6EFB1F", 16), new BigInteger("05738EC8A8EDEA8E435EE7266AD3EDE1EEFC2CEBE2BE1D614008D5D2951", 16)); doTestHMACDetECDSATest(new SHA224Digest(), privKey, new BigInteger("0CCE175124D3586BA7486F7146894C65C2A4A5A1904658E5C7F9DF5FA5D", 16), new BigInteger("08804B456D847ACE5CA86D97BF79FD6335E5B17F6C0D964B5D0036C867E", 16)); - doTestHMACDetECDSATest(new SHA256Digest(), privKey, new BigInteger("035C3D6DFEEA1CFB29B93BE3FDB91A7B130951770C2690C16833A159677", 16), new BigInteger("0600F7301D12AB376B56D4459774159ADB51F97E282FF384406AFD53A02", 16)); + doTestHMACDetECDSATest(SHA256Digest.newInstance(), privKey, new BigInteger("035C3D6DFEEA1CFB29B93BE3FDB91A7B130951770C2690C16833A159677", 16), new BigInteger("0600F7301D12AB376B56D4459774159ADB51F97E282FF384406AFD53A02", 16)); doTestHMACDetECDSATest(new SHA384Digest(), privKey, new BigInteger("061602FC8068BFD5FB86027B97455D200EC603057446CCE4D76DB8EF42C", 16), new BigInteger("03396DD0D59C067BB999B422D9883736CF9311DFD6951F91033BD03CA8D", 16)); doTestHMACDetECDSATest(new SHA512Digest(), privKey, new BigInteger("07E12CB60FDD614958E8E34B3C12DDFF35D85A9C5800E31EA2CC2EF63B1", 16), new BigInteger("0E8970FD99D836F3CC1C807A2C58760DE6EDAA23705A82B9CB1CE93FECC", 16)); @@ -331,7 +331,7 @@ private void testECHMacDeterministic() doTestHMACDetECDSASample(new SHA224Digest(), privKey, new BigInteger("143E878DDFD4DF40D97B8CD638B3C4706501C2201CF7108F2FB91478C11D6947" + "3246925", 16), new BigInteger("0CBF1B9717FEEA3AABB09D9654110144267098E0E1E8D0289A6211BE0EEDFDD8" + "6A3DB79", 16)); - doTestHMACDetECDSASample(new SHA256Digest(), privKey, new BigInteger("29FD82497FB3E5CEF65579272138DE59E2B666B8689466572B3B69A172CEE83B" + + doTestHMACDetECDSASample(SHA256Digest.newInstance(), privKey, new BigInteger("29FD82497FB3E5CEF65579272138DE59E2B666B8689466572B3B69A172CEE83B" + "E145659", 16), new BigInteger("05A89D9166B40795AF0FE5958201B9C0523E500013CA12B4840EA2BC53F25F9B" + "3CE87C0", 16)); doTestHMACDetECDSASample(new SHA384Digest(), privKey, new BigInteger("2F00689C1BFCD2A8C7A41E0DE55AE182E6463A152828EF89FE3525139B660329" + @@ -347,7 +347,7 @@ private void testECHMacDeterministic() doTestHMACDetECDSATest(new SHA224Digest(), privKey, new BigInteger("08F3824E40C16FF1DDA8DC992776D26F4A5981AB5092956C4FDBB4F1AE0A711E" + "EAA10E5", 16), new BigInteger("0A64B91EFADB213E11483FB61C73E3EF63D3B44EEFC56EA401B99DCC60CC28E9" + "9F0F1FA", 16)); - doTestHMACDetECDSATest(new SHA256Digest(), privKey, new BigInteger("3597B406F5329D11A79E887847E5EC60861CCBB19EC61F252DB7BD549C699951" + + doTestHMACDetECDSATest(SHA256Digest.newInstance(), privKey, new BigInteger("3597B406F5329D11A79E887847E5EC60861CCBB19EC61F252DB7BD549C699951" + "C182796", 16), new BigInteger("0A6A100B997BC622D91701D9F5C6F6D3815517E577622DA69D3A0E8917C1CBE6" + "3ACD345", 16)); doTestHMACDetECDSATest(new SHA384Digest(), privKey, new BigInteger("1BB490926E5A1FDC7C5AA86D0835F9B994EDA315CA408002AF54A298728D422E" + @@ -368,7 +368,7 @@ private void testECHMacDeterministic() doTestHMACDetECDSASample(new SHA224Digest(), privKey, new BigInteger("0EE4F39ACC2E03CE96C3D9FCBAFA5C22C89053662F8D4117752A9B10F09ADFDA" + "59DB061E247FE5321D6B170EE758ACE1BE4D157", 16), new BigInteger("00A2B83265B456A430A8BF27DCC8A9488B3F126C10F0D6D64BF7B8A218FAAF20" + "E51A295A3AE78F205E5A4A6AE224C3639F1BB34", 16)); - doTestHMACDetECDSASample(new SHA256Digest(), privKey, new BigInteger("02D8B1B31E33E74D7EB46C30FDE5AD2CA04EC8FE08FBA0E73BA5E568953AC5EA" + + doTestHMACDetECDSASample(SHA256Digest.newInstance(), privKey, new BigInteger("02D8B1B31E33E74D7EB46C30FDE5AD2CA04EC8FE08FBA0E73BA5E568953AC5EA" + "307C072942238DFC07F4A4D7C7C6A9F86436D17", 16), new BigInteger("079F7D471E6CB73234AF7F7C381D2CE15DE35BAF8BB68393B73235B3A26EC2DF" + "4842CE433FB492D6E074E604D4870024D42189A", 16)); doTestHMACDetECDSASample(new SHA384Digest(), privKey, new BigInteger("07BC638B7E7CE6FEE5E9C64A0F966D722D01BB4BC3F3A35F30D4CDDA92DFC5F7" + @@ -384,7 +384,7 @@ private void testECHMacDeterministic() doTestHMACDetECDSATest(new SHA224Digest(), privKey, new BigInteger("0B1527FFAA7DD7C7E46B628587A5BEC0539A2D04D3CF27C54841C2544E1BBDB4" + "2FDBDAAF8671A4CA86DFD619B1E3732D7BB56F2", 16), new BigInteger("0442C68C044868DF4832C807F1EDDEBF7F5052A64B826FD03451440794063F52" + "B022DF304F47403D4069234CA9EB4C964B37C02", 16)); - doTestHMACDetECDSATest(new SHA256Digest(), privKey, new BigInteger("0BB27755B991D6D31757BCBF68CB01225A38E1CFA20F775E861055DD108ED7EA" + + doTestHMACDetECDSATest(SHA256Digest.newInstance(), privKey, new BigInteger("0BB27755B991D6D31757BCBF68CB01225A38E1CFA20F775E861055DD108ED7EA" + "455E4B96B2F6F7CD6C6EC2B3C70C3EDDEB9743B", 16), new BigInteger("0C5BE90980E7F444B5F7A12C9E9AC7A04CA81412822DD5AD1BE7C45D5032555E" + "A070864245CF69266871FEB8CD1B7EDC30EF6D5", 16)); doTestHMACDetECDSATest(new SHA384Digest(), privKey, new BigInteger("04EFEB7098772187907C87B33E0FBBA4584226C50C11E98CA7AAC6986F8D3BE0" + @@ -415,7 +415,7 @@ private void testECHMacDeterministic() "536A9900C4EA6A10410007222D3DAE1A96F291C4C9275D75D98EB290DC0EEF17" + "6037B2C7A7A39A3", 16)); - doTestHMACDetECDSASample(new SHA256Digest(), privKey, new BigInteger("213EF9F3B0CFC4BF996B8AF3A7E1F6CACD2B87C8C63820000800AC787F17EC99" + + doTestHMACDetECDSASample(SHA256Digest.newInstance(), privKey, new BigInteger("213EF9F3B0CFC4BF996B8AF3A7E1F6CACD2B87C8C63820000800AC787F17EC99" + "C04BCEDF29A8413CFF83142BB88A50EF8D9A086AF4EB03E97C567500C21D8657" + "14D832E03C6D054", 16), new BigInteger("3D32322559B094E20D8935E250B6EC139AC4AAB77920812C119AF419FB62B332" + @@ -449,7 +449,7 @@ private void testECHMacDeterministic() "501AC282D29A1C26D26773B60FBE05AAB62BFA0BA32127563D42F7669C97784C" + "8897C22CFB4B8FA", 16)); - doTestHMACDetECDSATest(new SHA256Digest(), privKey, new BigInteger("184BC808506E11A65D628B457FDA60952803C604CC7181B59BD25AEE1411A66D" + + doTestHMACDetECDSATest(SHA256Digest.newInstance(), privKey, new BigInteger("184BC808506E11A65D628B457FDA60952803C604CC7181B59BD25AEE1411A66D" + "12A777F3A0DC99E1190C58D0037807A95E5080FA1B2E5CCAA37B50D401CFFC34" + "17C005AEE963469", 16), new BigInteger("27280D45F81B19334DBDB07B7E63FE8F39AC7E9AE14DE1D2A6884D2101850289" + diff --git a/core/src/test/java/org/bouncycastle/crypto/test/DigestConstraintsTest.java b/core/src/test/java/org/bouncycastle/crypto/test/DigestConstraintsTest.java index 9a583d233a..aee2dc4917 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/DigestConstraintsTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/DigestConstraintsTest.java @@ -4,7 +4,39 @@ import org.bouncycastle.crypto.CryptoServicePurpose; import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.constraints.BitsOfSecurityConstraint; -import org.bouncycastle.crypto.digests.*; +import org.bouncycastle.crypto.digests.Blake2bDigest; +import org.bouncycastle.crypto.digests.Blake2sDigest; +import org.bouncycastle.crypto.digests.Blake2xsDigest; +import org.bouncycastle.crypto.digests.Blake3Digest; +import org.bouncycastle.crypto.digests.CSHAKEDigest; +import org.bouncycastle.crypto.digests.DSTU7564Digest; +import org.bouncycastle.crypto.digests.GOST3411Digest; +import org.bouncycastle.crypto.digests.GOST3411_2012_256Digest; +import org.bouncycastle.crypto.digests.GOST3411_2012_512Digest; +import org.bouncycastle.crypto.digests.Haraka256Digest; +import org.bouncycastle.crypto.digests.Haraka512Digest; +import org.bouncycastle.crypto.digests.Kangaroo; +import org.bouncycastle.crypto.digests.KeccakDigest; +import org.bouncycastle.crypto.digests.MD2Digest; +import org.bouncycastle.crypto.digests.MD4Digest; +import org.bouncycastle.crypto.digests.MD5Digest; +import org.bouncycastle.crypto.digests.ParallelHash; +import org.bouncycastle.crypto.digests.RIPEMD128Digest; +import org.bouncycastle.crypto.digests.RIPEMD160Digest; +import org.bouncycastle.crypto.digests.RIPEMD256Digest; +import org.bouncycastle.crypto.digests.RIPEMD320Digest; +import org.bouncycastle.crypto.digests.SHA1Digest; +import org.bouncycastle.crypto.digests.SHA224Digest; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.digests.SHA384Digest; +import org.bouncycastle.crypto.digests.SHA3Digest; +import org.bouncycastle.crypto.digests.SHA512Digest; +import org.bouncycastle.crypto.digests.SHAKEDigest; +import org.bouncycastle.crypto.digests.SM3Digest; +import org.bouncycastle.crypto.digests.SkeinDigest; +import org.bouncycastle.crypto.digests.TigerDigest; +import org.bouncycastle.crypto.digests.TupleHash; +import org.bouncycastle.crypto.digests.WhirlpoolDigest; import org.bouncycastle.crypto.macs.KMAC; import org.bouncycastle.util.test.SimpleTest; @@ -139,7 +171,7 @@ private void testSHA256() try { - new SHA256Digest(); + SHA256Digest.newInstance(); fail("no exception"); } catch (CryptoServiceConstraintsException e) diff --git a/core/src/test/java/org/bouncycastle/crypto/test/DigestRandomNumberTest.java b/core/src/test/java/org/bouncycastle/crypto/test/DigestRandomNumberTest.java index 7bcaea8af4..d23c2b671f 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/DigestRandomNumberTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/DigestRandomNumberTest.java @@ -1,12 +1,12 @@ package org.bouncycastle.crypto.test; -import org.bouncycastle.util.test.SimpleTest; -import org.bouncycastle.util.encoders.Hex; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.crypto.prng.DigestRandomGenerator; +import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; -import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.prng.DigestRandomGenerator; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; public class DigestRandomNumberTest extends SimpleTest @@ -129,19 +129,19 @@ public void performTest() throws Exception { doExpectedTest(new SHA1Digest(), 0, expected0SHA1, noCycle0SHA1); - doExpectedTest(new SHA256Digest(), 0, expected0SHA256, noCycle0SHA256); + doExpectedTest(SHA256Digest.newInstance(), 0, expected0SHA256, noCycle0SHA256); doExpectedTest(new SHA1Digest(), 100, expected100SHA1); - doExpectedTest(new SHA256Digest(), 100, expected100SHA256); + doExpectedTest(SHA256Digest.newInstance(), 100, expected100SHA256); doExpectedTest(new SHA1Digest(), ZERO_SEED, expected0SHA1); - doExpectedTest(new SHA256Digest(), ZERO_SEED, expected0SHA256); + doExpectedTest(SHA256Digest.newInstance(), ZERO_SEED, expected0SHA256); doExpectedTest(new SHA1Digest(), TEST_SEED, expectedTestSHA1); - doExpectedTest(new SHA256Digest(), TEST_SEED, expectedTestSHA256); + doExpectedTest(SHA256Digest.newInstance(), TEST_SEED, expectedTestSHA256); doCountTest(new SHA1Digest(), TEST_SEED, sha1Xors); - doCountTest(new SHA256Digest(), TEST_SEED, sha256Xors); + doCountTest(SHA256Digest.newInstance(), TEST_SEED, sha256Xors); } public static void main( diff --git a/core/src/test/java/org/bouncycastle/crypto/test/EAXTest.java b/core/src/test/java/org/bouncycastle/crypto/test/EAXTest.java index 7eb8582ec4..568535b39c 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/EAXTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/EAXTest.java @@ -3,6 +3,7 @@ import java.security.SecureRandom; import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.MultiBlockCipher; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.modes.AEADBlockCipher; import org.bouncycastle.crypto.modes.EAXBlockCipher; @@ -117,7 +118,7 @@ public void performTest() checkVectors(10, K10, 128, N10, A10, P10, T10, C10); checkVectors(11, K11, 32, N11, A11, P11, T11, C11); - EAXBlockCipher eax = new EAXBlockCipher(new AESEngine()); + EAXBlockCipher eax = new EAXBlockCipher(AESEngine.newInstance()); ivParamTest(1, eax, K1, N1); // @@ -152,11 +153,11 @@ public void performTest() } randomTests(); - AEADTestUtil.testReset(this, new EAXBlockCipher(new AESEngine()), new EAXBlockCipher(new AESEngine()), new AEADParameters(new KeyParameter(K1), 32, N2)); + AEADTestUtil.testReset(this, new EAXBlockCipher(AESEngine.newInstance()), new EAXBlockCipher(AESEngine.newInstance()), new AEADParameters(new KeyParameter(K1), 32, N2)); AEADTestUtil.testTampering(this, eax, new AEADParameters(new KeyParameter(K1), 32, N2)); - AEADTestUtil.testOutputSizes(this, new EAXBlockCipher(new AESEngine()), new AEADParameters( + AEADTestUtil.testOutputSizes(this, new EAXBlockCipher(AESEngine.newInstance()), new AEADParameters( new KeyParameter(K1), 32, N2)); - AEADTestUtil.testBufferSizeChecks(this, new EAXBlockCipher(new AESEngine()), new AEADParameters( + AEADTestUtil.testBufferSizeChecks(this, new EAXBlockCipher(AESEngine.newInstance()), new AEADParameters( new KeyParameter(K1), 32, N2)); } @@ -194,8 +195,8 @@ private void checkVectors( byte[] c) throws InvalidCipherTextException { - EAXBlockCipher encEax = new EAXBlockCipher(new AESEngine()); - EAXBlockCipher decEax = new EAXBlockCipher(new AESEngine()); + EAXBlockCipher encEax = new EAXBlockCipher(AESEngine.newInstance()); + EAXBlockCipher decEax = new EAXBlockCipher(AESEngine.newInstance()); AEADParameters parameters = new AEADParameters(new KeyParameter(k), macSize, n, a); encEax.init(true, parameters); @@ -325,7 +326,7 @@ private void randomTest( srng.nextBytes(datIn); srng.nextBytes(key); - AESEngine engine = new AESEngine(); + MultiBlockCipher engine = AESEngine.newInstance(); KeyParameter sessKey = new KeyParameter(key); EAXBlockCipher eaxCipher = new EAXBlockCipher(engine); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/ECIESTest.java b/core/src/test/java/org/bouncycastle/crypto/test/ECIESTest.java index 738aa586ee..5e8a41ddb8 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/ECIESTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/ECIESTest.java @@ -12,6 +12,7 @@ import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.KeyEncoder; import org.bouncycastle.crypto.KeyGenerationParameters; +import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA512Digest; @@ -20,7 +21,8 @@ import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.generators.EphemeralKeyPairGenerator; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; -import org.bouncycastle.crypto.kems.ECIESKeyEncapsulation; +import org.bouncycastle.crypto.kems.ECIESKEMExtractor; +import org.bouncycastle.crypto.kems.ECIESKEMGenerator; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; @@ -523,14 +525,16 @@ private void doCofactorTest(boolean newCofactorMode, boolean oldCofactorMode) int myKeyLen = 256 / 8; /* Create agreement */ - ECIESKeyEncapsulation myAgreement = new ECIESKeyEncapsulation(new KDF2BytesGenerator(new SHA512Digest()), myRandom, newCofactorMode, oldCofactorMode, false); - myAgreement.init(myPair.getPublic()); - KeyParameter mySender = (KeyParameter) myAgreement.encrypt(myMessage, myKeyLen); + ECIESKEMGenerator kemGen = new ECIESKEMGenerator(myKeyLen, new KDF2BytesGenerator(new SHA512Digest()), myRandom, newCofactorMode, oldCofactorMode, false); + + SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(myPair.getPublic()); + KeyParameter mySender = new KeyParameter(secEnc.getSecret()); byte[] mySenderKey = mySender.getKey(); /* Accept agreement */ - myAgreement.init(myPair.getPrivate()); - KeyParameter myReceiver = (KeyParameter) myAgreement.decrypt(myMessage, myKeyLen); + ECIESKEMExtractor kemExt = new ECIESKEMExtractor((ECPrivateKeyParameters)myPair.getPrivate(), myKeyLen, new KDF2BytesGenerator(new SHA512Digest()), newCofactorMode, oldCofactorMode, false); + + KeyParameter myReceiver = new KeyParameter(kemExt.extractSecret(secEnc.getEncapsulation())); byte[] myReceiverKey = myReceiver.getKey(); /* Check that keys match */ diff --git a/core/src/test/java/org/bouncycastle/crypto/test/Ed25519Test.java b/core/src/test/java/org/bouncycastle/crypto/test/Ed25519Test.java index 1633d54b0b..646bda7d61 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/Ed25519Test.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/Ed25519Test.java @@ -13,6 +13,7 @@ import org.bouncycastle.crypto.signers.Ed25519phSigner; import org.bouncycastle.math.ec.rfc8032.Ed25519; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -31,8 +32,11 @@ public static void main(String[] args) runTest(new Ed25519Test()); } - public void performTest() throws Exception + public void performTest() + throws Exception { + basicSigTest(); + for (int i = 0; i < 10; ++i) { testConsistency(Ed25519.Algorithm.Ed25519, null); @@ -42,7 +46,7 @@ public void performTest() throws Exception testConsistency(Ed25519.Algorithm.Ed25519ph, context); } - basicSigTest(); + testRegressionInfiniteLoop(); } private void basicSigTest() @@ -88,7 +92,8 @@ private byte[] randomContext(int length) return context; } - private void testConsistency(int algorithm, byte[] context) throws Exception + private void testConsistency(int algorithm, byte[] context) + throws Exception { Ed25519KeyPairGenerator kpg = new Ed25519KeyPairGenerator(); kpg.init(new Ed25519KeyGenerationParameters(RANDOM)); @@ -155,4 +160,693 @@ private void testConsistency(int algorithm, byte[] context) throws Exception } } } + + private void testRegressionInfiniteLoop() + throws Exception + { + String[] testCases = new String[]{ + "pub=MCowBQYDK2VwAyEA3/3evB5w/U2/UClcztEy9jyUhCYb4lsYC/Uc0Y3XU2A= priv=MC4CAQAwBQYDK2VwBCIEIPqycfmKBOt+r71r9rPfm/qHloKw1mi0u7EtapwiyLFq msg=XffXN58qcNEDB9bG0Bi4+rJx+YoE636vvWv2s9+b+oeWgrDWaLS7sS1qnCLIsWogbfSKviAwbnT17l1hipS+Qw== sig=ygsIhBS66Bh6JYI+7NS7WX/KXIIqjMX4zlgqbH8euNCg1mkdj1E9gTZ1fxSfws8ZywBfLY1Sy+7ldggN2tLIDQ== e=found 57 iterations", + "pub=MCowBQYDK2VwAyEAHE6pGleQ6FLeLw37qqETXGJ7ypORl7ipr8mhKsuwGaE= priv=MC4CAQAwBQYDK2VwBCIEIOOZeFAaz2ab5MpacOllrYaslZc5GniKpptk6wBxJXIf msg=5uTZqblhMeTvsI2p6090Pjkkdqd+8GZQMN1Mnv/WvVFmnJN5IBDOjahUTJnfhTxs6EmeXSYeO4WrevJor16ETg== sig=s8aJ/GKWfb2dz7ll7Ne+CrCdjHI1K3Y/7gLDOIZavFpxHcH8giHrrQ59TIWU3T4Fhe/we9EPcW/KzNcU4CUXAQ== e=found 58 iterations", + "pub=MCowBQYDK2VwAyEAJHkMcEbTWYrCDb+3JciGTTTwiTHHOGt/H0oWdCF7KjQ= priv=MC4CAQAwBQYDK2VwBCIEIGazYWgWo6F/+K0HNs1V1/N9LQm6T32nqJJ87pH5FSWb msg=yBv8Q3VCicgj+eBdgBrcdnp8uNO+LfgSVGazYWgWo6F/+K0HNs1V1/N9LQm6T32nqJJ87pH5FSWbXmXIcTEWeQ== sig=o4KkE0Fe5PQXZ66mfG7tnh/k2/5EaPqXAOmgo0ji+apD2iiaQcb+1skazsJWbwoubWSDFiWUlJdh+eY/x0f+BA== e=found 59 iterations", + "pub=MCowBQYDK2VwAyEAQ0jwSazJght+xwc61Oot3UmMdefnvHBOvi3VsQ+X4qk= priv=MC4CAQAwBQYDK2VwBCIEICD2bl/Zm5YSPMftEm00BM0MUe6j+nlZXqztAkE0xrky msg=fADFP9wG2ltHE+pIErYCjodSbK5U/wnHzBHhx/vHJjhUxQv7uWx27zjvEYKLTJeJJvD3J2fH+afqfAJv7KmAPg== sig=dFQffK66bpOuv/CVySTNuuVvZ9vneh8N2gVYmEDjwEeYKVxDXOWR7Lz9VL4VREnMKmY1ABZqFGat42mtDhT7BQ== e=found 60 iterations", + "pub=MCowBQYDK2VwAyEAw9qjlWaWApPsYJoi1urhuZRPJ0HwKmcxSH+d+UrulFY= priv=MC4CAQAwBQYDK2VwBCIEIEChvJXCKYlzD95RdByx424MtBDDuNH+RUkdGOrFje93 msg=cpZ5pNbNxLTwIKyTGTCUpDNSOQZAobyVwimJcw/eUXQcseNuDLQQw7jR/kVJHRjqxY3vd9/B1yDiHPqJPl1weQ== sig=fQZ9FXypim4TXvs5XmLyfHlnl+H5dxsDruEXBRChZBPpYI+RU/DAN4/KJfxf3jWsr8EknjmVgPncDftqBtGeCA== e=found 61 iterations", + "pub=MCowBQYDK2VwAyEAHVoqu90LAbDc9tY/24I85V3Iddy9IaYaqC6QnztbIWw= priv=MC4CAQAwBQYDK2VwBCIEIC5EY5KGGA9Vz+RXn+Jb3C2P3vLngGox1x/VMq/xgQ/c msg=4g0xLkRjkoYYD1XP5Fef4lvcLY/e8ueAajHXH9Uyr/GBD9xDLCrQyr7DAX37FiM6XMXXdImapHyrKxjZ4hljwA== sig=goY0VKd7aQHUnHkfIX2ZUbE36lbJeOIT2949NsG77LmDn1don59tvyxfC1XaXVRiVx5lz6FbRQprvDqK8ltFDA== e=found 62 iterations", + "pub=MCowBQYDK2VwAyEAO2X9m9WY0jkQ3rsWHgB07rKXKSowZijSwNcats/rxls= priv=MC4CAQAwBQYDK2VwBCIEIHpGklIDOOxGzlBBJx8Z8q+uNYC7qwAT7Io3moNwpdNx msg=qY16RpJSAzjsRs5QQScfGfKvrjWAu6sAE+yKN5qDcKXTcU8uPgLQEoR22vXmN0ZL1IjapYbh8IuG5X8o5C+9bQ== sig=ENLBlvemjb580cnBqSE9an761T3sVD7A/WYM9GZIspeOj8u2eyjMSrzOcu+hvL3sFNxZvuIkv0WNBZSfNre8Bw== e=found 63 iterations", + "pub=MCowBQYDK2VwAyEAgU4uXIkXFTLtmF3rLM4rUbpMQqJAJKFAzKJm7T1CpiA= priv=MC4CAQAwBQYDK2VwBCIEIFjsWgCM7VfazSZBCZ1VOijO1YGF1keRqw9HVh5VRQxB msg=OijO1YGF1keRqw9HVh5VRQxBSbw4babQ5wmgtR4LVClBV2VEHtuBTsPAqisBJNocB9h+LWJu+DejyjmHpcz9WQ== sig=jSRxppkrB+yUOs668HXOMy4Jjj4H9MP+cmXMwzEqsVl8wc6fp7EQj5+TrQKMxmE7wssKqEMiKkdBjDhtwjH5CQ== e=found 64 iterations", + "pub=MCowBQYDK2VwAyEAtouD0lJ0YQHbkEaX8gO3r9S0ChGHc+yTSaoCIvapPwE= priv=MC4CAQAwBQYDK2VwBCIEINjDs+pGo0ltBaFttGeFJCf9Mxx1HtKQTfDM+RvYsv5o msg=QnVUUQt6Oc4jVIN5s9jDs+pGo0ltBaFttGeFJCf9Mxx1HtKQTfDM+RvYsv5o1RebMvFrjIccGemNKesf2D1Dqg== sig=uRWDxSUqrlhZugfNof0M9ChCSAyXRwxPQj4BFMs1hPeN2OZOs9zwwX9A/txWOvjFFrxzZv2RfxYDsbBw361fCw== e=found 65 iterations", + "pub=MCowBQYDK2VwAyEA7gJi5r5MaxpTqo6RUdDKnQ6dBI7F8nLQEKyBeHXIY8Q= priv=MC4CAQAwBQYDK2VwBCIEIPpWOkkMNiGqG3fvJKZmCmk4wkMlU/9pANei/BX3Mmxl msg=0p4n7fEf9tz7VFfwSUwQ6DD6VjpJDDYhqht37ySmZgppOMJDJVP/aQDXovwV9zJsZa09HhhSgN28xezygc6rxQ== sig=EinE0Nh/AIUdB6L4m93Y9/k0EHM9gXgGfBk5w3yJ4DyBTzwmfcvKpMM4biqeeGkLp/o178h99qo7VKHy4iu/CA== e=found 66 iterations", + "pub=MCowBQYDK2VwAyEAQ8fC52l1Ap4uBSm1UBbMGhUVYxQh3hrrwpO34TuwsMo= priv=MC4CAQAwBQYDK2VwBCIEIMCByifE3xspIRrcWScSuaPmd3teD9OAusym1ko2SHHN msg=LGrH8cQFin0saRCHUg32Uvl6W9CwSOI8sQKyw61UPe7AgconxN8bKSEa3FknErmj5nd7Xg/TgLrMptZKNkhxzQ== sig=xuBEeHak/xpR0JWm3zIgMZBdNoAu4nBeYT4ZCMWWWIAp+N8WLRLEwqZc5ATRxFSIAyroeqqwfM+HCd57CYfJDQ== e=found 67 iterations", + "pub=MCowBQYDK2VwAyEALz5ECUSoAyj++sngkV9x579Rn9gIv60EhWM/Mo04qYI= priv=MC4CAQAwBQYDK2VwBCIEIAj/Likh1ESWhlieUj3NJsJYiyEaAb+NJGo0mJQlSFsI msg=Likh1ESWhlieUj3NJsJYiyEaAb+NJGo0mJQlSFsISkKXYllc3AFZLfIxEJhlg7kkSPRoSjsywIKkQMKz0nTqmQ== sig=wyrojflpY11TM7qOQID9w2MuNEiBUe5djMdOd592gBtG3rC34bCM+e4YACZLRokN4+fIAEYkVBj9IsmqPa7DAw== e=found 68 iterations", + "pub=MCowBQYDK2VwAyEA3v9XVY2xwD7nD5NUZl3lvzlX7Vl+sSNQ39gDfBVy6Y4= priv=MC4CAQAwBQYDK2VwBCIEIHUSb1VM6d2XAr/tGjaihT4lwDrhS6m+jQD4ss+BuWHP msg=f8Cm7q424+L+dRJvVUzp3ZcCv+0aNqKFPiXAOuFLqb6NAPiyz4G5Yc9djz1ZDGoobooR+E9P8LPdcnl3VW9XDg== sig=ArQBwnYbRe/TC/9mHVu9DpK2tUXh4QuikFZl7uKo4zaozZcR8T141Exm/c1gpEVZTVkzgej8LUsRD4bcO5L3Dw== e=found 69 iterations", + "pub=MCowBQYDK2VwAyEAcOsf+gEhq9BSSqzZ/qxCn/c4soTZuAQ2OIUmZbxOpo8= priv=MC4CAQAwBQYDK2VwBCIEIJjji9eyxdpYzxuxWfMJBunPDOVmBRMj4BVVP65o2Hlg msg=u4VP6f9VElsVCcWHrLH+6l138t4veA+LuUmOhVIzd8tg5ACs6fABUxYLd9WS5lixkY6lHSwtYnpxdTjw4W/xfw== sig=95we7zTeiWqIUgYq6ITdhOuY+wVeT52vFLxJ9lIHfbOvQIoUG/jIJ4tN8aO+E8+0ogKw6hbMe5kI8BDcolD1BQ== e=found 70 iterations", + "pub=MCowBQYDK2VwAyEA5N2A+KytH1SUeGrALPa4exr9T7ilFqY4mP263N/dpoA= priv=MC4CAQAwBQYDK2VwBCIEIPW2m9QjkRRPOvH8+G9UzZawwLHeAvpb776Kbjy++FDm msg=GKb1tpvUI5EUTzrx/PhvVM2WsMCx3gL6W+++im48vvhQ5tHN4ZL4Npk59iwd+Xt3q244B0J4TrBjQTCJNOe1gA== sig=xBAT3nWrOK3BmthFVhjzQmRyuc//xEXnht058kFn7iMiK9qTawfPYrh/0GtMT+D8T+ywSHs8dheT2u6IMpGvCw== e=found 71 iterations", + "pub=MCowBQYDK2VwAyEAck4cyMfKmNjVvsYCniBLPGufQHdhsYkHxwN/yLRkFqI= priv=MC4CAQAwBQYDK2VwBCIEIOnPLabQHydXPuXSFvVoefv5gGDw7g/hjwlkaYXvfkU2 msg=pTdX5+nPLabQHydXPuXSFvVoefv5gGDw7g/hjwlkaYXvfkU2eKdkOblsgfjKiunbgZSTPS+CsOJz3/C1qkuwoQ== sig=BBauQZjlkp/KGMQralAlgGOASATf4FTVr7pQJjRI+Z+ZRgWHdqwfwc2f+bskbFzdk/dMfX1+/adjpNqnQx++Aw== e=found 72 iterations", + "pub=MCowBQYDK2VwAyEACvojkSBSZ7VCiwZ3xXoU2ATVM0WICTajOKL9lE4p+/8= priv=MC4CAQAwBQYDK2VwBCIEIEGLCxghINDDsZ2KD5pbvtezu48inGVtJDkhGJTNlExL msg=0MOxnYoPmlu+17O7jyKcZW0kOSEYlM2UTEsyjeEVoSB1oWw43IbtQsU1aXjEAbsGR37fjN2CJUSIIjbjWobglA== sig=tazDpJk/+ksUjyROEq7CQeYG3JWvSuo/a7n4i27dTtLnBZdJKI2Ss/CFgoUaFR7MghXmuFTgjRNkFTyIRH5kAQ== e=found 73 iterations", + "pub=MCowBQYDK2VwAyEAcyMeLZ2B6y+bumyenoAPjsVS3hYttEc65namio44OfY= priv=MC4CAQAwBQYDK2VwBCIEIMGtgiHjjye6/sD0KGQsl3yMeglzwgUcLfr6kvZv1tLi msg=448nuv7A9ChkLJd8jHoJc8IFHC36+pL2b9bS4tSUHiMdMbHfGNxLoKVyQWmwZI25RV3tb6uCZjShyeyAQxf5qQ== sig=rleDJhVQLfwwW/8BeJzQ0faH8exOaLOj2mZ7Pl22xb26SO/kJTNjwRwuJIa1ikE3VUYyin+Z8l1AKIsB1bUUDw== e=found 74 iterations", + "pub=MCowBQYDK2VwAyEAVbTtelb7fdEllJU4Isl/qQBVfpCwf/FS98Qo+39Juts= priv=MC4CAQAwBQYDK2VwBCIEIGR4+PJZWiLYLvY7K7QjxgEDc6wJNEP5FZVceJcYQFLd msg=XHiXGEBS3ebu2T5Ysp26sqATj5AgBZ5lUMXuFKDyRu7aKqKSj7IA7A6kqAHTKRgApzYkHFebiEYN4OYbnwL5yw== sig=DJyEPFFWYsBLXZhuAbeAuGFGX6d1uGdOyMQWfZUxb0VRUHtOqSqnkqxD6MFQCqrCRK99csxWM/sjzu/ElUEGBA== e=found 75 iterations", + "pub=MCowBQYDK2VwAyEADpJZkPbMGm3OJGBNebqCWuhtKM9K7GYoummru/XeKmU= priv=MC4CAQAwBQYDK2VwBCIEIPcAlXkRpRVYcwmciwCGfXpZMhocJ4Su/l8r2kfil4AM msg=tyoG4LBmsMzwLstDhgGON++RjqIxe27QojpSXRLFBU3b2Ipl0a/3f9hpdA/20eNxNcO6RXOcZApNwXfcGwr+wg== sig=1sTcSr9s6K0vpvLL8r2ha7hf8zLez3rF6EIWZHkktuaJoguKzcfzc27lIl4INnJcDIhalsi2DROCaYTfDKhNCg== e=found 76 iterations", + "pub=MCowBQYDK2VwAyEAVF/N5oJKWCGWHfiAslb8VdiCxx5JO7JZZRK4jqeNpr8= priv=MC4CAQAwBQYDK2VwBCIEIIGsfXvUljv/gjBtQYZGb4AuQrkdiYfR3auP3wEq1HE+ msg=gax9e9SWO/+CMG1BhkZvgC5CuR2Jh9Hdq4/fASrUcT6+uYYI9C8+sjoyKDeM2x4RFSmY6SnAhg5qTxeEoxxNbA== sig=AJBypRL1pNBImpqiZF7G6eXNvxWHlAbxwjT+MV1H2gFBsAG2Ym3CcsyHPd0QsqXkU2NdenmPGcDcUBjFgXLrBg== e=found 77 iterations", + "pub=MCowBQYDK2VwAyEA+ia1bvX/7K8dvgMawIcr+MTySXi/AgVAL2drXfvqBPM= priv=MC4CAQAwBQYDK2VwBCIEICrDfb37zqLPR/skhQQmsGhTmw/zHOfbjmAjGPEW/8oV msg=vE8KZwJ6YtP/+WyzyJWretDzt0ubvZgUtNBIuEcpELCMWfbtTVe23JPMKmjDlCTdnAtrwDbLqb5FIVEiqOXzcw== sig=20vXY9u8jczxgmmBTTWT8GypkISPYyeudzcBBRW8DhFN/469gCsM7ORIFj+kpdcS36sKeBqR7Nb+668rdvKJCA== e=found 78 iterations", + "pub=MCowBQYDK2VwAyEATbYfEv8ed/G/fVWIK6UmJnEo4r1CbWTRGqZLw+HITp8= priv=MC4CAQAwBQYDK2VwBCIEIEYmeASKShp0E4i7tcQubwJKh7FXMoQ+AVVgIInCCQv7 msg=JngEikoadBOIu7XELm8CSoexVzKEPgFVYCCJwgkL+07AFp7AzE5dUJa2m57x2Vgya5fJJM0A8xDx8ycIfCsXdw== sig=kF8val6rPSkqlKCE2LQMY4TOtcuBr+TXHBikJLnaOrJaN3UpdIuENMRZ5PcpQQPaUpbV2H7U7d2Tp4QVCTm+DQ== e=found 79 iterations", + "pub=MCowBQYDK2VwAyEAbHE4FALgveWrQGocE8gnBau1q5PpS0okUZSNHY06U+s= priv=MC4CAQAwBQYDK2VwBCIEIJT/Ds6W00gFY7t5Orz8jUbrLO7WXT/XQ8wk41xVeaaT msg=lP8OzpbTSAVju3k6vPyNRuss7tZdP9dDzCTjXFV5ppOAfhGgM/MxuyzejSkeA0JkR/b+9HQh8gOgaA601guxAg== sig=tG3nio6FoZZR9Czx6K25m5qLxIuTpSwBABkek65zya2t/eEVA4117dwB2OQpDssGbzthvpWcyj4tI551PgncDQ== e=found 80 iterations", + "pub=MCowBQYDK2VwAyEAlT/tfiwUqJmUvhwfGT3SZzp3fE2AIH40b7r3eXvWmus= priv=MC4CAQAwBQYDK2VwBCIEIHjr+VxWtvNNPJxbyiqBPEig906yvaR3UkhisWnyyaoE msg=+VxWtvNNPJxbyiqBPEig906yvaR3UkhisWnyyaoEaq+wmzpfZ7h77z7awiRrvzpHhexuwmR0kBG+32cuoG2FIw== sig=pqy9Bjqk89dM5Vqi9sXWps7gj0K5VZ4TSbE54/bmzz0dQlmrBB3BoLr9jR3lYmQSHGeUAiOEMF/IFqiUtVAsDw== e=found 81 iterations", + "pub=MCowBQYDK2VwAyEALI9zvH2ox89t5vAQ3rgcUXiudRR0qqHXSTtqfSrWtR0= priv=MC4CAQAwBQYDK2VwBCIEIABqFXbYOdPeA7tNMv+mOgMwMULjSEF/ILV7jHyvmmsH msg=SEF/ILV7jHyvmmsH/yenViLDIDsUMZ2+O5OClYh62MfqPvmJfnm5xS0936u+EITgSGoFAM01tTz+FhDT3cFZcw== sig=UMMD7kAPsI+lg6IRL/fVfAfTuPuUkuKUHu+zHn4GyDel0SeHm4qeCkDoGIYcqAKUXodTCe8HFgGXO6B/LOaFCw== e=found 82 iterations", + "pub=MCowBQYDK2VwAyEAaluPrsdE7hJvsRlYQxKlJpLCErJVA7oJ+6VBP6ZpBK8= priv=MC4CAQAwBQYDK2VwBCIEIJdiqV/cVG3IhVWka+6RJcg5/Euw+MOb2nvvugLRXZsa msg=VG3IhVWka+6RJcg5/Euw+MOb2nvvugLRXZsag4W/k17xGzCj01czIctEQ2Ghi3mkNlAy0xSx1iI8w5oKxoyYTA== sig=TCG2PI2fhSxKFFdbR6LYTZjQcUl08fphHg8Extx55xT6akJGPSA394JGfXTQ5EmRwpmSrOc3ctWNg0W8LkzYDw== e=found 83 iterations", + "pub=MCowBQYDK2VwAyEAgVFBME0lxzYhAT3mMzcN4vBD14XvUE3T7WvkCz/Hi6A= priv=MC4CAQAwBQYDK2VwBCIEIGxbsvPeQP5alHZwIFpJ/zE0VCeDg4UVZNAULW9Gz6Rn msg=bFuy895A/lqUdnAgWkn/MTRUJ4ODhRVk0BQtb0bPpGeSamrYBUN5isjpmzmEyT+PNLDnDVltWRZlast6wHKCiQ== sig=o0bihdMu3Nbu37kOilhK605/skxlRzmuqckuws2sQsXU1vektNygzTVGplO0YhzaqVRiaEQ25XyX0E5WInjYBg== e=found 84 iterations", + "pub=MCowBQYDK2VwAyEADswLfYaCgPTNDo6VABvIVVBL2RYzGsZwRGxD8U8sBmI= priv=MC4CAQAwBQYDK2VwBCIEIF+8551mbELCuqvXE8qIYSdQY3xcyUcAJbIBk4E/b1bJ msg=551mbELCuqvXE8qIYSdQY3xcyUcAJbIBk4E/b1bJRqeo4ZJpgVjI+9VWvsp+KgIO3PHMeP2/MR352QtwkV8Jjg== sig=OK2GAlZ8ktI0sc8DZUWTen91ZodncG4F2GEAiRWT7BMG171Kt4TmpOONC7zxg/CZATbpQsYjeJbYChOHzD2YAw== e=found 85 iterations", + "pub=MCowBQYDK2VwAyEAmf8knio0TlExv5yjOXhS3To0t1zTwjqM6WkFCqcgm2Y= priv=MC4CAQAwBQYDK2VwBCIEIAcdGU61Dl6Qm09qZYD8o0Ijd4TstKtRsEnSC1wKseoJ msg=Bx0ZTrUOXpCbT2plgPyjQiN3hOy0q1GwSdILXAqx6glr7GkcJj+5i7A8plIVzfqdVqcAhIotNFj7urMLHIaNEQ== sig=Fap/Bkr09J2hZmS7MFQiAdQlGdRIxd5UUyf+2j9NCVH1UDW73cCHrYhgQzIYqLLKRDm4g68XQkDKVip99A9MCg== e=found 86 iterations", + "pub=MCowBQYDK2VwAyEAZmMMrMIw9N+GEaZ+MlNEJhp02NBmJ0ff5oMAar+DoOc= priv=MC4CAQAwBQYDK2VwBCIEIIDlRkWRmt+LuJ46+mCurmpzSgoMK+giRrLrOoFPfwMC msg=kZrfi7ieOvpgrq5qc0oKDCvoIkay6zqBT38DAhcD3/vxzbq5F211Rh73Lgjt2kIBQ2AKCE/kZhH4zmhwaO8DRw== sig=FoDjiSWwscc8094p0SEuBLw58VABp1KdO2v7DTxJF8sFJgLBCMQwoKaJh/IWvErAs01xNO+j5xTzuA535f+KAw== e=found 87 iterations", + "pub=MCowBQYDK2VwAyEAlFfIiS9RuWVB2EEt89Vwxbkp0qtkxysWH59GajLVnDQ= priv=MC4CAQAwBQYDK2VwBCIEILJ7yOj2x6u8927a68u22Mn9/jt85RLzZx7aL5wLWjkV msg=snvI6PbHq7z3btrry7bYyf3+O3zlEvNnHtovnAtaORX+s2PwQjBdgbxjPaPwfSLgxFmnWk4Y5QSONrkg8nSzOQ== sig=yHkgcBJ1q/8SHJQS1mfFicAnez3hLoO9wxTwC320MQVBUbstibJ5dZWQKPQTxZc3nUKngOfljHWyQTZmhWQ7Dw== e=found 88 iterations", + "pub=MCowBQYDK2VwAyEAntmlfS2c/Iy1zr6sZyb0qyDK7WqUWdtsaa1I7CJe7gM= priv=MC4CAQAwBQYDK2VwBCIEIKC9jpiEaaU9gYJXUt2ZCypHSydp5iOV5U56nFeqaxAf msg=oL2OmIRppT2BgldS3ZkLKkdLJ2nmI5XlTnqcV6prEB+7hLJTfgylcRN+Ng2MBDU2IjIquzE4oRirt+Anagx9ew== sig=AlKASNgsDM3hZq+yVGgrP9Cs6ut1sqbly9q6V613jrszQxs8G0hr+uEzZlIUMmRPQsx1MeUWOwVMKjruSIqpCg== e=found 89 iterations", + "pub=MCowBQYDK2VwAyEAe3onup6XeBxGwdWuV15GuBBgWPMYHypWmNksVjY9T3A= priv=MC4CAQAwBQYDK2VwBCIEIIx4VqqMrh+55Tlhbz04Eu0OSSRkIVBFwuED7hCn48KE msg=eFaqjK4fueU5YW89OBLtDkkkZCFQRcLhA+4Qp+PChHChKuKYO4nuCRoyK/OgE1ixwj7du0TazPZ9vqIX/gxkxA== sig=ZV57Xncn3MBEOzPF0z5O4VNPIJe9NYz8DGjC8MFZAeCdEWPzl2RclqtHzT9wG6fxfXyk2trOYO0UGLYprAEKDA== e=found 90 iterations", + "pub=MCowBQYDK2VwAyEAMSHRc9b0uFPLiF7PoiOtz3nF9ONP833g/8lGRaeKsEM= priv=MC4CAQAwBQYDK2VwBCIEIISX12XJ3repK7/2EMbAzZJQXdU4tNKM9xhehI0aTUJK msg=hJfXZcnet6krv/YQxsDNklBd1Ti00oz3GF6EjRpNQko4draNLxRGDGAcxlGKY7LEJiyFaGCoPptQaKQdg5sKoQ== sig=J5+N17b5XRRe7jYPFKyfgzAJAu7xfkRoY1hMbbqdct5NgjFdgcE+vqB7ygS7OPFnhj8MemHIWEvoseEgIfL4Aw== e=found 91 iterations", + "pub=MCowBQYDK2VwAyEA4Qs8/gmbNddoDAJF26eotJ7vXz0eB1kY5fUNdgazKUE= priv=MC4CAQAwBQYDK2VwBCIEIHUOUwvhq7F/oqKzRoQ5/5JGwmAdqD1Nagjul/xu2Ubx msg=dQ5TC+GrsX+iorNGhDn/kkbCYB2oPU1qCO6X/G7ZRvFpN/T3drIdx9JHySmFqzxs6ozOrPIl8Z7N7z7TexoCdQ== sig=D0P0GHtEGXw2U4ufZTGQ9nw0u/3KVi6uKeEg9iZug8A4cW3IWEpaTDgsDQiIbQV1G4walipOoGwOEaYgcov7BQ== e=found 92 iterations", + "pub=MCowBQYDK2VwAyEAaFcWF7so4FDMjXe7rx0Sc8SJhQUiPgiP8+rZnEQqRIc= priv=MC4CAQAwBQYDK2VwBCIEIClbAlg50Y8EgrYktJUhlhagflkXEd3nQTL9sEGFKndr msg=KVsCWDnRjwSCtiS0lSGWFqB+WRcR3edBMv2wQYUqd2u3Y86Iza/ftJtSL37uc7+jxbk2an9WFUgKxr3TE0ZJ1w== sig=Lm6fLEspvqzSHUDYTGqOpkyGkH/MExrYPTaKTJFGwfc1rlgmltD/FZX/3QuDFz2RC3R+61/w4NOBt+5SXY07Cw== e=found 93 iterations", + "pub=MCowBQYDK2VwAyEAvPN/2oNoXurS+vDYHCbjYuPfXgbe0itAbFhEijxJeow= priv=MC4CAQAwBQYDK2VwBCIEIPOrXDYpgo4GV50wKFxBZ2gzLjjSwGoYU+OLIjrY2jDB msg=go4GV50wKFxBZ2gzLjjSwGoYU+OLIjrY2jDBghVSp/ug4Cd9SfNbTsQNlNfvv49897siFoRH0wL7kEMobwLqTQ== sig=j+FR8fXWQBoTg7udoMiaB2fYii5+0fQHGbfRN5ZdTAnBPjLOIu/60CevpLQZ3wU4xQFMMQdMR/sYKa/bGKGQAg== e=found 94 iterations", + "pub=MCowBQYDK2VwAyEARwQK6+aqwEQkHuqHNt4KD2YOfvzd4EDIg3MtE14qHYo= priv=MC4CAQAwBQYDK2VwBCIEIB1VShb8viJS0hvqhAXO+ApFu77HOXbJ4V+k/c1JCuRF msg=HVVKFvy+IlLSG+qEBc74CkW7vsc5dsnhX6T9zUkK5EVmsJSbifLY7dXV2dqt3IJcWmrjjzzyxvo/cxScb+/mLg== sig=+GKFVPRIFUZXl/UVEA7Ew7dJpIIktgJc47TjCz+Xn7d73e7HdYk+SzNO3CAHf1rXsn+6g6aq14xJ40+sm5YeCA== e=found 95 iterations", + "pub=MCowBQYDK2VwAyEAsA0JXns6Fdx3PWAPV1YMlyzuZGiTGDAdGVy0R4kfAJg= priv=MC4CAQAwBQYDK2VwBCIEINg1tiot0KrcoQz5LAWPQi8VUq40bEHOlJIZgrNL1Bf2 msg=2DW2Ki3QqtyhDPksBY9CLxVSrjRsQc6UkhmCs0vUF/Zu03kar5GVOIPS9hcPPiMPalsG94tTfOcd6K489mSgWQ== sig=5DISt2qCS/TEyxsrBNEcmT0WmftDgXLU3fGZGliQ13qkdcbGfbBBgn5ZynWYjkZs+vWgY/aUFJqR1xdrT/jmDg== e=found 96 iterations", + "pub=MCowBQYDK2VwAyEAyXjgbLtOOWNQTI2yHWwu6wraCx7+SpA+l+MorxAuyC4= priv=MC4CAQAwBQYDK2VwBCIEIJQCZBRpNVYNKJT2RglfyiZBHqgQNT7p643mWANtMs93 msg=lAJkFGk1Vg0olPZGCV/KJkEeqBA1PunrjeZYA20yz3fjvqNAj4OYV5woBHgFBoBzBMYNMrQFXi15k7pnan5nQQ== sig=2rVSgYmxPpK5rxcfOJ9KQ8vwzampF6wLOi3bLpeBuWZkrM3c3/00WhgLzxkKT293YP9M9vQWJ7PAaHw0kujmBA== e=found 97 iterations", + "pub=MCowBQYDK2VwAyEAln54NhyJ/X/2jquXbp76ah/LB6oDIDr4Kd2WuzG67Hw= priv=MC4CAQAwBQYDK2VwBCIEIPM6tBV/BMq/nT0sGnR1UdDKFHYAEcsWbzbOT7qGHsM+ msg=8zq0FX8Eyr+dPSwadHVR0MoUdgARyxZvNs5PuoYewz7cZ1HatzjU17kcntHRNKlYBD4S4oYNemfMlI6F6ph2iA== sig=KIoQvdBfc9mxQ0/v4voWTAexNlAUyd/oUqMZWWHIIS/tCMO4n/+d7vkKbseaCKjIjlDSNDLTDkiGlTvlXC+nAQ== e=found 98 iterations", + "pub=MCowBQYDK2VwAyEAS6N91+jeeXJEbYbxEBlxjvrFy9hoJzyPWytHVP/CUno= priv=MC4CAQAwBQYDK2VwBCIEIOnlWtKs7cO6oDUYZdDRupL+rcoDOrnGBNF4DahV3pb2 msg=6eVa0qztw7qgNRhl0NG6kv6tygM6ucYE0XgNqFXelvYg8JqZNeSllXXMjUnmDLs3kZ49fXJuEtwju+fN2bV/LA== sig=OLNQWDDTXk6Y20N4L0ExI4tVAghBdEMtMDh61O6s8qo38gBqN6Z9+z9fB7pT75qJ3TS/cr2gpkgsMJCN408ADQ== e=found 99 iterations", + "pub=MCowBQYDK2VwAyEAep3fxNQ3AZVdrzzQQh2r6Q6HG72z04tRbF4Y3MaVfpk= priv=MC4CAQAwBQYDK2VwBCIEIAO05+oHAN0iDVfxh6PrV23NHSAG39ic3oI6j7q2zVU2 msg=A7Tn6gcA3SINV/GHo+tXbc0dIAbf2JzegjqPurbNVTZnffJIGIVWmda1asLPawPKBm6d7wom9x1aTvC75D1zqw== sig=OwfEYNcZkywink/oki2yQdSStICDGNGDMzBkiwzMT48JZdfFAAJv1MpE2PAltUQ7AKR6d8ayNAnaB+j2fcehAA== e=found 100 iterations", + "pub=MCowBQYDK2VwAyEAtmWPpI2qjU8+cuDxey/OeGxfI0HI8YKpTCNph83eQbM= priv=MC4CAQAwBQYDK2VwBCIEILNmVpfQEeXqAgU3AT/wzVfZKLch2JCKQVo1twgU7Vcx msg=l9AR5eoCBTcBP/DNV9kotyHYkIpBWjW3CBTtVzE8BX9m6gpvPXySqSXM+2EZSOHdWrqOuAjFl3f9/D5SV51Y3w== sig=Xcvf0aMYrUHrFl++l0AIF4gTFL3+CAAw6JdS2VgGz7kvmgFtI8kY9h0PZ134Zu+8nNVCvDxW/8nBRdFGPlJoCQ== e=found 101 iterations", + "pub=MCowBQYDK2VwAyEAxB4rpEdE6bQs2h2EWS5czrD7/EOiLjphE08wOAKyr+g= priv=MC4CAQAwBQYDK2VwBCIEIJ3civsLgKDYpvKpfXq/VjIlqV84wyWMPQPoG/Z2bPUd msg=ndyK+wuAoNim8ql9er9WMiWpXzjDJYw9A+gb9nZs9R197YzifOxRBzP2IDK6iEV8GH0Zc00L+TSum1AyL/HIuw== sig=PQFAHZE8iojkwYYpdditN/P40LRB+6JRB5aMWaXS2ZBl8giA/WaN7z+QmvusGZzspIPqcU3IYxLkpxqiC+1GBw== e=found 102 iterations", + "pub=MCowBQYDK2VwAyEADb2Wja4KaAI9S3FDjyz27HMJmRiXFM5bW8Um80DuVzs= priv=MC4CAQAwBQYDK2VwBCIEILOzZ+v4C9bwHglFkhU8BpQTwPi7gXgptY+BRBf1mFso msg=s7Nn6/gL1vAeCUWSFTwGlBPA+LuBeCm1j4FEF/WYWyjP5l49E+h39fGv22Us0XQq3ZzCi5PXuHHWE7aqzCalyQ== sig=gw+6zaHeASQU1vzZzAMDo0WBWRDKwvYir+Epb3CHCzjCptBbRbkyTezKV04zgjCC8v6pnTW+PV/JswFnEyahBw== e=found 103 iterations", + "pub=MCowBQYDK2VwAyEAY+kkohAG8v6XX/g5ehc3qm6uAe2wiPp2JD667ZTUwZs= priv=MC4CAQAwBQYDK2VwBCIEINGNGzJsI60cXv4kQAXN9lPtkrCAuIOf75woW7D0JOL+ msg=0Y0bMmwjrRxe/iRABc32U+2SsIC4g5/vnChbsPQk4v4Pc8sVc0KgHGRXTam3wqe2+z89MWV3CwrFlI1WgFepRQ== sig=8oO1Dk3MEb7ci90HGiLr9IIH3I2r3ot706oDagqFB9WMjXiz8/VOrk671sEsAmkEqx9Wi6BR+TToNfrVwaVGDw== e=found 104 iterations", + "pub=MCowBQYDK2VwAyEAV+eerrwAURGpcHcK0JeGobQoqRoNFwG3iyMszmcpr9s= priv=MC4CAQAwBQYDK2VwBCIEIF+GlnmbaoCNTb9Dp0bB1oThaqV9wLsK7ZZX/WH7Su8+ msg=X4aWeZtqgI1Nv0OnRsHWhOFqpX3Auwrtllf9YftK7z6LF7MaQ/zv/YrcFHLgNh+tO8pNZNdxTaGHJqF4pQi29A== sig=lvsqZuf9cjMwTfU3UTWpm4F+vdGQfRpB2Vr8821in7KCya+SU9L7O28etc7K6jAehVh1WhwM89bkI4KhQBOxAA== e=found 105 iterations", + "pub=MCowBQYDK2VwAyEACVSLzN/JMMBQKViu1fIlHn2OcvUdHLMrIxVYRcik2wY= priv=MC4CAQAwBQYDK2VwBCIEIPGVBkBRaQ5VRcjtx9GYH1QvA6ByaLj8l/OdLmQwN4f4 msg=8ZUGQFFpDlVFyO3H0ZgfVC8DoHJouPyX850uZDA3h/iMs107I9zrBTcO84NbjmV2B4pyrgbM0xQDjYrulY2xMg== sig=9KLcuiDjbHlLiTSpHLUux+xeRyUHcwx7xmLjbdoPr/3KloJDSVcJyS/AFxijLi/oCGiCk0d+IGNSsjBgYWahCg== e=found 106 iterations", + "pub=MCowBQYDK2VwAyEAjvV5DVaAbsrgVhzuIG2U3kRsGwZKX6PHjZpw/kBSNbg= priv=MC4CAQAwBQYDK2VwBCIEIAysY9jJSOqH6zsbLOoZhmm4dgoW8F+WaD0tjiPaiWHh msg=2MlI6ofrOxss6hmGabh2ChbwX5ZoPS2OI9qJYeGbELTDkeTTuBIxJkgMmto8J4ZZj1COP1fl42RuDoD1KErE/Q== sig=C7hZ34BoCJM5URpDRyN6sAJubjX6KGj2SPhdcSzHK+fgQViJLuUqn1JXmP3XpHYH/Po3O1CluRT4ywIjVh3DCQ== e=found 107 iterations", + "pub=MCowBQYDK2VwAyEAVOUySxyz79hRissjZEL+quwGOxc+AdwFas7VrRgsgSc= priv=MC4CAQAwBQYDK2VwBCIEIKxd3M5fRFsBy3Fz1cOuUV799FcJ/UvCkGY6KjdhK+0n msg=XdzOX0RbActxc9XDrlFe/fRXCf1LwpBmOio3YSvtJ5MaW3Lb+tdIdsynqxMne1zOt6B+kZIISyidVbf60bMFeg== sig=YmZA7rBj45Zli4gmwHsEa20sEhwSWXrKomj1juUhGfNujwyRxnYKoSt4QjNvlvl5AVInnhXQl0dA7hkPm9JIBQ== e=found 108 iterations", + "pub=MCowBQYDK2VwAyEAZlIDdXJgAnnhHVoNMQWO+OE+VcMAlQHhlQ+x8Hi/7uk= priv=MC4CAQAwBQYDK2VwBCIEIL4S80IGx2KYQQE1zxQj06ZYpCp2LDr5U3ZzuSrLpSXZ msg=KnYsOvlTdnO5KsulJdmDAYwRIWvfaIlUWSSFTSm2MAdqK5rcTcs5ACqRp8lZVlB2FZYBoOJ8yfNvzvqQLKgo9A== sig=Akz2lxK2ijLs+y30Qsf0Q6DfQuvlXAQ64zqjcpBZEsHclHzi0AdsNZw4GXaYqwSoCrPVzQVl+0Ni/mUaXmjSCA== e=found 109 iterations", + "pub=MCowBQYDK2VwAyEA50i4BEW6p4B1yBk0iCrFGUM0YRzz1A7zbw4v25dhg5M= priv=MC4CAQAwBQYDK2VwBCIEIEa77POdeLW7Yu5ob0jgT9jgrKS9JSxysD9FSAEhlcO7 msg=4E/Y4KykvSUscrA/RUgBIZXDuzm6v+E6kdQxEC0ip+Ka0CE1Z0A11Y+gv57xvMdb4eW0Iz3ggJtY8nfVO353SA== sig=It7Wf+Av1hSsJXU4X9cy2lJs5Hd8xblaAIxkETy8y2AEPoCnkwBF//GtB2HZH1AFzO61OadpkiiZPYrwKhm0Cg== e=found 110 iterations", + "pub=MCowBQYDK2VwAyEANkftEt72NPdPk87PrASjacXTl6PavTzAwx+JnyZKRJ4= priv=MC4CAQAwBQYDK2VwBCIEINgCmCrO9vmG172MlaQL14QlI0h7rOhTrAJ/bIL59Bn2 msg=laQL14QlI0h7rOhTrAJ/bIL59Bn2LlnYtukvEZDmGNPGCwbOjNrxSz5xh8R4ktueccMEdqLsymc7VqrhfRFL1Q== sig=ekz8oTUmcj8E/7JkKmz3jGPn4A/Vzo6IXs1Br8a40f81PezLt4fg4AET8yKnflXPLnIxsvWMFf75kcS/MZQ9BQ== e=found 111 iterations", + "pub=MCowBQYDK2VwAyEA/4riYc3bZpCPbqWr/xhgHMI+qLvApmqe5oxKC8HAcps= priv=MC4CAQAwBQYDK2VwBCIEIBlCc9I42RFdUSpapkLcZRXZmS3IQkbjs0eD4TIwofO+ msg=LchCRuOzR4PhMjCh8755nw/BOYJpgXD0ylEIsBZZ62eq+tgCglyZYIpN/94ClwRS/9xi3A5NYNPNz5/mj/TKNg== sig=/Ybq0ft2t16ji2KqGfEnE6nDP71VToLc9X7V2HHnq0CVW+hcJPM7TSmsTPFu7N96jCwajpZnyK+69JaKcOhVCg== e=found 112 iterations", + "pub=MCowBQYDK2VwAyEAF4l0xsXs4JpegvWBwtYSvMAW8cxQ6wtoVHKj/ljLk3A= priv=MC4CAQAwBQYDK2VwBCIEICKG9KtMFNm+NY01HdZo9vfocfFG8z6+ZIbVWIDGRr7E msg=hvSrTBTZvjWNNR3WaPb36HHxRvM+vmSG1ViAxka+xDHPNQm/wQmlAw0Tm4W5baDGnRVWshIoFi9lIYISeU6hDg== sig=xk3MjjaQ8aWi+pYS7iztra/l/Jie1/FrCXMP5J4FtQ3Zplm0BNJ8xxOK3GbsajAWIrtJT39r/N+IQUh+ZJRsBQ== e=found 113 iterations", + "pub=MCowBQYDK2VwAyEAkzgho5/z+HviQDIY9bkPHqyXMQCiXRrIiQCgXRkwqzw= priv=MC4CAQAwBQYDK2VwBCIEIOlUfDbMqvNWdgLVt7XbebmEeAUpE0iaBTNiwdaqIkF5 msg=fDbMqvNWdgLVt7XbebmEeAUpE0iaBTNiwdaqIkF5jlsgNDGyTJmnvIELx0AitTL/hcFhNVwVY/vnstmHvfYkew== sig=TziR8PAa2Xnuk6XixgTSX2arI/9Tq3wt1rjc+5hUI/iVtAkQHRCpv6CYZlICBMuT6kgh8gaPIvHgjP6yPW5HBA== e=found 114 iterations", + "pub=MCowBQYDK2VwAyEApI1F6sU7qwmXHxGL7dtf9tu1XyzAzwi3ssF37Jf0dSM= priv=MC4CAQAwBQYDK2VwBCIEIIw6ZKX5nzKL5PZv1q6cTsfa7eV/yP/CLCmyxIklP/wd msg=1q6cTsfa7eV/yP/CLCmyxIklP/wdT1sYiSq89jwR3b0hxERp6yU/itMNA7rC78lZjgQ9jOaZcoWiWkJE+5k5AQ== sig=DD17y3VKQVgikhAPgFWMZC7Hyx/tKg069CvoRYfXOfdR23Vq236SH6A2JcJPuXD0eNnKWVLit0J6HPh5eFgGBw== e=found 115 iterations", + "pub=MCowBQYDK2VwAyEAjlAWDsH7LRj0ZAUIVliBHNtrsOtTzA3vcvvaYpf2d+I= priv=MC4CAQAwBQYDK2VwBCIEIEc2T1fCXGz6QwLmlxyUzobRp0ScJTBIvn9nyV/dnsua msg=eXtSnxApDQM4oGuHDCKDnWHClGqMYRdM47wRgdiagdeHuIGmgqTCs2HbGJ9iQ3xzDKz0bA28/ZUKuECC3v7VIQ== sig=J1aBRj5B+Vkd3Fns7HjKvLiROS6Pykf1NXogsGfzqYEG55wrsq84J9WTNxPrAI67XHl3V0XQJhrcaQ6vTVYIAA== e=found 116 iterations", + "pub=MCowBQYDK2VwAyEAx/J338CWREzgr3VDj+SYEoRkufWma184TOstM64JIvw= priv=MC4CAQAwBQYDK2VwBCIEIOwyhIb6cQvGuXavoAP2bNZIMrkDGJqpkz/rwLkwqYE5 msg=k5jbL+4bGuCPkwlCPujRhoAMsLTVgDXLBR82linwu81mMkF//K7mjshaBUf/6RjwM1ahvsMeUrqYsA9N8ExVBg== sig=7eWOr0C48A0FSRz6ERZGV8BoAV77aIH0vLErlozjehYaOqzB2xBN343ak337DncVCQFmj1O+zOXc+oE5kH1AAw== e=found 117 iterations", + "pub=MCowBQYDK2VwAyEAsV3ow8DVlcbtSwNq02ifJ95G4MdPUJ7r1FmAbhTeX9o= priv=MC4CAQAwBQYDK2VwBCIEIEDOhJN72N9SVZZEvhDoRNif1ggDElqVYpusx+rA+Twc msg=vX1KKcCsAHuzAyNwmLQbj1hHdu0xYvraHvhhUtLdwLjYriq8oGpktEsXe0R6Urrba4/dgoiJrg3ZswQ811Q6vg== sig=zsaQwF1jX0g+1zqOE2UqKFGIalFWTITFycgcSPy0RrJkSwrtheMTxbKAQ0LzDTkJihqLBfCXu0wfO1Je+ixeBg== e=found 118 iterations", + "pub=MCowBQYDK2VwAyEA7dZmMFlNTWPWPZgCgWX+GMEIwweha45WyeuaJEScQEY= priv=MC4CAQAwBQYDK2VwBCIEIFJXyspLbXKewnvs3oEa9c62lm+8n9Dmtx4KxQ+Ohnfz msg=2U0jfWaZXC71/PiaxinTygfhDkjwCnVIcFfwiTnfm317zs+awCOx/0wvlH3AEJHOl+fwTLaOd3DupZ2LiIQ7/A== sig=rxa1s40iO/DgWBYElFPWzOT1/vRWKu92h7a9LlOthgAlPBoeOdZKJCI6uIJegVlW0vgkCcHXf4rRc7VomPuvDw== e=found 119 iterations", + "pub=MCowBQYDK2VwAyEAcKGYlao5G64KfCrn0rxhttE0nbyj9bmXNNHIpmt8Fgw= priv=MC4CAQAwBQYDK2VwBCIEIE6pRyNDgBX1xzVpC5QXW8I8Y+AQHBx31V1TieBCwZ0q msg=cD4WTqlHI0OAFfXHNWkLlBdbwjxj4BAcHHfVXVOJ4ELBnSpWhuYSQwkKA3QTldz8H8IVK2J0k0qtv8JDBa2sjg== sig=gyd+gBQhXu57ixVnwzgt7Ar4rC51pduSmd6EdLLZgPBN/zXwxsLY92KjALsXoiy5I2BKNHbKaLaA7E7eWz5hCQ== e=found 120 iterations", + "pub=MCowBQYDK2VwAyEAiOHKTeVVFdSn1Cb5GaOujy/ZiKKK5JTx1rOoyH2hZS4= priv=MC4CAQAwBQYDK2VwBCIEIPr6hfTbh24/qN2LTEBmsoO+O7LXSGOEnhccKGkQ9xao msg=HAZszQIBEZX3T956a6X2qPnpL18/UrgMqG36+oX024duP6jdi0xAZrKDvjuy10hjhJ4XHChpEPcWqLr3EgEh3Q== sig=XK/tnbhmjUuP2zShxHthiNTDdMpnxZDBVV3DCSoth8CoFJpm9j7l1m8RP2DkNBOk7N3C1eQuYX7Xtmg5Dqv7Dg== e=found 121 iterations", + "pub=MCowBQYDK2VwAyEA2fYktkj1ov74JQ3ziXQGIEBu69ZyNK9HJXcwOjORB4I= priv=MC4CAQAwBQYDK2VwBCIEIAXENRxhQHqF2NsgH+Yo2M4j2gz7T6CE8Ti5gc4lwGmz msg=s36EjclDkM5ovsjWHnTbQgpRzBcOToob27OFXDMvthJ/Wkiuujtl9lBpQ6BS+LcHAN8A+1Tdg2cAEM4kf78FVA== sig=5HL+dmVc4FnY5fxYQYh1G3EQ6mDvVmnTvO+0VrAGKT0IbpO1rzfE6s59tRIOlwegK1two489j5luttd2kpw2Ag== e=found 122 iterations", + "pub=MCowBQYDK2VwAyEAxgIbd+1KO+EwLcNYV0viNHISlJ/yMr6ejj9o6bZZaQg= priv=MC4CAQAwBQYDK2VwBCIEIIcxnu/B3ye5/U+gErU8IEiNJ6hKwrZyIXHAxl+IetKa msg=iHrSmjW3+YWb0eieg2VzaEwvLYfQ74WpmNx/9zzojVyyDEmzxba1RvJELvN1g1tiGRS04X7tMR3V2zC7JL+O4w== sig=NC5YeGcd9z/2A82B1c8a+8/gzFURMBr/5wDhFWgFy+dAOE9o+9JplsxTKgEtYkB20na0X89fyiuU0i7/TSo5Bw== e=found 123 iterations", + "pub=MCowBQYDK2VwAyEAn328lpY3CdJ7a83KonTKMTHTaUZOoVVow2eDGvLQXU8= priv=MC4CAQAwBQYDK2VwBCIEIHvvqFTxw/O9Y81plNuGexhSqOUCAJX4wKy5G/RSYE6S msg=QTALCo3mn6sfHr1J2wA6E+KSSBY0jgnO96RGVWsbAPmge++oVPHD871jzWmU24Z7GFKo5QIAlfjArLkb9FJgTg== sig=GyNNRaiV6jBM/Un1moAf6+9HoG1doryo8EH9ozNAoIIKhzOzBcXL8K1Yyxw1ikzjhB/cthvad5nIqCnFy/s/Ag== e=found 124 iterations", + "pub=MCowBQYDK2VwAyEAODcrDW4/Tiw57u4yH0GaqlbMP/CNb5xYJBtWSPUlkhY= priv=MC4CAQAwBQYDK2VwBCIEIBWmfL19HXVaNb/V9YjvUD4HlTXbAOGJymU43nYSzYbC msg=xNF0lcWH0tr2cZmfb86bqLDM4sFtpf/j6DIOCZw+rPR0vXBz3opqS9QqBoZrqxu/HnINC3vMzbBcfVeA1fJapA== sig=CWdE2P+RAySVsX5RBZRFMdPMVzW6Ll2OqMMrbxY1uAbXPBrPhmCTKzyXpkMQYse8p6PQL8Q8Nisk9rpRG9JcAQ== e=found 125 iterations", + "pub=MCowBQYDK2VwAyEAeMRPfeY1/Ej07VytXhsMqcknQhs1D4ybys8KoGdEcl8= priv=MC4CAQAwBQYDK2VwBCIEIAeBzvUPjV8+3MvxZy6vb9+fCBnLp1OKntl4jx6/M4iY msg=zC2R+O/dtgeBzvUPjV8+3MvxZy6vb9+fCBnLp1OKntl4jx6/M4iYj/zoYHQFKjVp1BhJc2ilT61DqWc67lf2+Q== sig=ZwHxu+72a0T2XCU6ofoZYytanTGxubKpzE7Nv9sdZHmJr866/Mp3z9NT53XbdokbyR7aoKWwUk+MxQPD7BGUDA== e=found 126 iterations", + "pub=MCowBQYDK2VwAyEAmIMQFNgNIqtEFnAL7UUKNaVkR4pq/U1oqd5hGru+A4E= priv=MC4CAQAwBQYDK2VwBCIEIEjc4Yp+7SviDjcpVR6F5uRGECy5PD9LIQO51zhba696 msg=NylVHoXm5EYQLLk8P0shA7nXOFtrr3pbRCAQOXYem+Reei9u7svzNxid0mYSww21HFI61av2xcnLVtAj74vCQA== sig=qWIwPgXSyQC4gvQ3EA59Kc2lolXXX/CJQ3m05SqhXUVCVxMR/QZbHuSEOJdNS6sOVAU6HhQxCsOKlJn17EHOAQ== e=found 127 iterations", + "pub=MCowBQYDK2VwAyEAYdHTU+z+QY9yPjN+5AL1GQueMSCy1rx3M1d806OLX30= priv=MC4CAQAwBQYDK2VwBCIEIDrZHcmldayL2KAfqJbBoNH5bUiU2V/LQZac6W/q8LKu msg=bjfcDqqNdm3usjrZHcmldayL2KAfqJbBoNH5bUiU2V/LQZac6W/q8LKu27+Lp9HyICeAqccrC8CwhFWgmJcEYA== sig=OCPtS11eq67EU+Y2ZicrzgqTovsqq5Lb5uG7Tk7mpAQbAxyb02Cm8vFIJ4cnSfMdC0PsgdhPORgf9irGdS7/AQ== e=found 128 iterations", + "pub=MCowBQYDK2VwAyEAUyRbp4YiA0rm50jzBL33lwnOjARoaHdEXNn40NK0P/o= priv=MC4CAQAwBQYDK2VwBCIEIHyDIlRjqb+Sb6qLHx2L3Hy5suUruXKJ+tNB4gnnZBTB msg=fIMiVGOpv5JvqosfHYvcfLmy5Su5con600HiCedkFMF37opZtphHd9PZKZD8BKu8dBoCxA5QvuASqYFeAI1heg== sig=uGHxzBRY5tN2as7RjVjRQEq1iEs0wB7Vqhb4hdj40T065HA2rh6ce2atRq5pUi1cMXEmVkIszxozWcMfHUIsCQ== e=found 129 iterations", + "pub=MCowBQYDK2VwAyEANKGfP0zeLPFc6hEt1VvkjxTJchfDMXRzU2YKz3P4zBg= priv=MC4CAQAwBQYDK2VwBCIEIAepORePNseu2WAOKT27U51DbmCfCNm/uUAOAvPUHcjv msg=ovhoXmGlzVfukw0cFSDcFjyyH3wusPP63+MHqTkXjzbHrtlgDik9u1OdQ25gnwjZv7lADgLz1B3I7wSr9+aY6Q== sig=XSeK/GK7VjgXQaEAJZMQxhLho/Vk6GrqhNzjlNGRoA3n90TESPaB7jgETupaMPc/7tW3ajHMes0brN/gowmkAg== e=found 130 iterations", + "pub=MCowBQYDK2VwAyEAEQzJXljPO6he8KgNb3GstmtJf2KAt5rvSS/pg8s/+18= priv=MC4CAQAwBQYDK2VwBCIEIDauwah1wGBxy4j86YjZa69dfNrzpAy1tH4xFx3PszT4 msg=wGBxy4j86YjZa69dfNrzpAy1tH4xFx3PszT4w7BFTMFYjJ9js0kgcNW8txOfCHatw9dtMNKHpxwUqkLI45l+iA== sig=HnIqSJ8Kec5S9ByX4VJfpeDJpToLJ6Q4kHns/2ClxL6gG7eN6wyXueIgMIIcEKccToIsJNTcbJ+qkSyEk+0VBQ== e=found 131 iterations", + "pub=MCowBQYDK2VwAyEALusS6fp6G/FtPYCNWOTFq1ISq8V3TA0DSmN5ju6a2+w= priv=MC4CAQAwBQYDK2VwBCIEIHB/Hep4WznYrotW1sfMtxR+uOGbP15iJ3NchMKlxRT2 msg=w/D0I957dumGHAI4tvnK4HPDn60VcH8d6nhbOdiui1bWx8y3FH644Zs/XmInc1yEwqXFFPZ0C7b4faU3iXLzmw== sig=8IDG4SVEnUOEWGA5mwEBJKFapSbplFOSgpCzONUVsQr/XicA1pIxVZJhd9dB8m1g2qKHBBI3xBICbff7Ja/XBA== e=found 132 iterations", + "pub=MCowBQYDK2VwAyEAxfj1xPSyPSoQ0snOT1ez6MpkaD06hzSFubwh4H46Kz8= priv=MC4CAQAwBQYDK2VwBCIEIJz7YoGp7tZssgpFv4KVWgCoN2QNjjZMQiz3oHQfXfXU msg=wXiQXg+Ul950ZJPaMWBHz9TenPtiganu1myyCkW/gpVaAKg3ZA2ONkxCLPegdB9d9dTbNJRHD0FccCMylNgtLQ== sig=2FHnSc+maLipWVXC8THY8D3WAbYAdnJa/ZDe9Z0uoqscna7g/1MaC8hOYgbngB9NcsPhELKnh7MfahboI2ZtCQ== e=found 133 iterations", + "pub=MCowBQYDK2VwAyEAN3sM/Rxz1hYmLZL76OsjkTn6xZw3Y2imuoIWfxONklo= priv=MC4CAQAwBQYDK2VwBCIEIGy19HsQGbzOdOqudIr42F7VQyPcSdJseqhdWZUJUsLE msg=x02f55Gj0W2wffYS6eqhS4ft2wZ+1Ps+Nz89SkhZK95vXF+wWOD7aa67J5rxvTPnRKT9L4IWi4GH2mviIjNfag== sig=6wjgs9WuiPEKBYL6AUoP5c6z1m8iyMH/5gXeCwjYyXy9WJvLIlWaDno+cax1aUPNZbz+pt1G/G4MeYOJBP5YBQ== e=found 134 iterations", + "pub=MCowBQYDK2VwAyEASNbA63RlnLdSyuyBF+WFNohFKJ9+F4wi/FY4l9JcVKw= priv=MC4CAQAwBQYDK2VwBCIEIBxK5DAmCzNQ7Iy1GhiyCqgPE7swenOzB5iu7vsQ5YvA msg=SdlbWypKKps5ujzrT4Ioaj1O5KKHWDgv/RNSDP1MMdlGuxCxwidgH8hqkv3D541+SD7NUbF38hBaHWKwEi4xTA== sig=F6o/H61xcySsNdqmF3r+p+HF0E/vajX7Rk377h0Qr09fQeOlqPLNf6KPy7akyyvdplM37QyI8IEJIBbjtQkYCA== e=found 136 iterations", + "pub=MCowBQYDK2VwAyEAtK2N4hAzgo8jxf70zrdyhXjBNIDmQrQveJTceGOuawY= priv=MC4CAQAwBQYDK2VwBCIEIJlsnKHDv4soVPN5eKAzD8HjsUvkZBo7G6rLraONtxgO msg=eXigMw/B47FL5GQaOxuqy62jjbcYDkNI9YvOPNlpxiTM4zPw7CrKpunaVdCx9to7mMmJUNFUhdYclMbTTB9qVg== sig=5acadnBTsnNcpS8qE/OAORmo6ww5PMa7puoaC4a39TcAIKx04Mz1hJLDAzK3Yt4l4080ZE5ivIKyQ5BY+tesAA== e=found last=7 s=0 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAA0KPeFKAEZc5+A6xLb7/06poKa9xhKKXpabhhSxh7zo= priv=MC4CAQAwBQYDK2VwBCIEID5GgFmIxxd8E30MYAAAqhto5RY9QQpvOmZINZcTUsJ2 msg=PkaAWYjHF3wTfQxgAACqG2jlFj1BCm86Zkg1lxNSwnZGIwnDSSdBpU6qWcefuwNGgKpOHtHO6Smviq7hnpzXiQ== sig=7sx8YX78+QYt9eXmP0XRcOkrlHLa0FkveOOBwdMll0mcgcJEIu8sMuRZa4BcJsfvLmaSdLQ2BkZPLTPP2/Z4Bg== e=found last=8 s=0 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAmnIcJ/4T5M/31gQnujbv5h/T4ccJOW9YSJwUBYw7ses= priv=MC4CAQAwBQYDK2VwBCIEICsx3yGMG5FHTtNynjHRd4D6PvunCas3DU39ZxjPupnd msg=KzHfIYwbkUdO03KeMdF3gPo++6cJqzcNTf1nGM+6md0UiT8yZeWQQLtF70i8CU99Ty2NgAemjkIYgDzdi5Wm6Q== sig=y0HnMN953kniqWlt1yLE6eJG3YuKCRPCQmYD/uuXkGieJoSLmfkrUn+o9bPCJKAftKbWbj0B+MC06CqICXBsAA== e=found last=8 s=1 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAuxOmF36g51Vn21r7uWj8Eg7j79UhHmaZ2EhkJ3GFYds= priv=MC4CAQAwBQYDK2VwBCIEIJkQm0JsPdi4V3NJ+uxYAPi6IBnvxnfBMAGNy8ofxreV msg=mRCbQmw92LhXc0n67FgA+LogGe/Gd8EwAY3Lyh/Gt5XvUX/5+BDScGWCHGfgp2pHNLmWi92CIBJ9YABT26j1xg== sig=3cndiSbcEmKDPfC/8ExTtmbZfwPp8OlzeL9zqhlUP59++HkvxabP0lnsI41r5mve2Dlpbl8D4kOw1OmkPwOyCA== e=found last=8 s=2 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAZf0og+I/2mW153yMsTAsX/I8qATJsbYgL3uCIp/EiDI= priv=MC4CAQAwBQYDK2VwBCIEIKc3ng3JGh9fSnc97IthMq69vrYaDjzAa1wDlf5lSKBm msg=pzeeDckaH19Kdz3si2Eyrr2+thoOPMBrXAOV/mVIoGZX9zRYHmYvYB2TdK6EbZlEt3MWRe4ij1Ly+5XsJR5CzA== sig=S30dCRLlVJIJl2YLDOJ1gu5i2sErbS0ufQ/18l9SwLnO1V7cTjHO0z7+rxlS2sn2YVtRReRk2/N33fmYy9cNAQ== e=found last=8 s=3 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAhDv5qOwezFXaBQQ0dn/UoHaKsQWQ1FArc4Gv7hdyE8A= priv=MC4CAQAwBQYDK2VwBCIEIGfv99hGFwhBJ7XaFOJGzINufKOcSQvLqYjd1LLYjeCH msg=Z+/32EYXCEEntdoU4kbMg258o5xJC8upiN3UstiN4Icu20Bcw0EJ3VAxUx8dkp1dW84+HgKjLKWlJWIfi90uLw== sig=PAoMCOC5QaSwIwYUJ+cLJbRZIh7nF5D6Q5f1LRJ0QtqhBs8uanPU1XF3ueevYQGIq7imZafTzylSzuonEpy5Ag== e=found last=8 s=4 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAhn0RQrj2+s3kdX/Wjop/hJA+e+rGB+WAqiA7HiCIp9k= priv=MC4CAQAwBQYDK2VwBCIEIJJ+gl9Z6QoYG8BjDe0YQWFNnUnVpjQ6+8ftbl/YBxxE msg=kn6CX1npChgbwGMN7RhBYU2dSdWmNDr7x+1uX9gHHEQ/1aU9jUBPOSoInnYaj8uOwB5dQsm4IUENw9VTcGMaqQ== sig=XtnSZFQI4EfWsz+HzmoOUda2lgXy2kiayo8uI7x6Ry+nF+SQOk72+I44hLvkzoxDLXhpuUWSTvAJ0c/JkNOHCw== e=found last=8 s=5 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA/xPic7Gv+VybpXpXcDvnLY8O1GURIS+XYCNI+ZcHEgs= priv=MC4CAQAwBQYDK2VwBCIEIDEv8hQTnEzM9jDBe/mKfTUpa83oBRyYjHXjJEYLXIY7 msg=MS/yFBOcTMz2MMF7+Yp9NSlrzegFHJiMdeMkRgtchjt3YFbSfSFGFgwPt6/8IMeRci1VklvlqwouDk9UQGCL4Q== sig=XOfZWpLcy/j5W4kd1fTjyDww4oZo+Ma/H+Ev313I+a0gH8iX0cNclElGZkyGgcArgNczVR57+FS1t6Fh+MY3AQ== e=found last=8 s=6 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAGYtOEebYKoq40cwB7mQ25w+hmRojT9v/3OzuS4ByWwM= priv=MC4CAQAwBQYDK2VwBCIEIKxEm8cUl/ymjrRiHW8TLDkUnZFy1OLhnjWniQ+sEvoe msg=rESbxxSX/KaOtGIdbxMsORSdkXLU4uGeNaeJD6wS+h5WHuD5Ho/2zH9NkWfpRaLEnn7SRFvKZSD1U6+Nfnyjew== sig=2e0GLWlKwrI8l6qRvrlUQ2awsfftHGO0WwwyxMK0dWU1MG8NfPIZ64qs8T3GR4kxFJiXWsjH4DnMpgC1DOMeCg== e=found last=8 s=7 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA9M2wf7buDQGPqLWIDX596fvR+hvbWOU9NUTd/WsAXig= priv=MC4CAQAwBQYDK2VwBCIEIDbjwhJmzMto0RDL75xJChRXE1QIj2/q7xbIr9HmrHak msg=zMto0RDL75xJChRXE1QIj2/q7xbIr9HmrHakMsRzr9P/p5iH3pV3XndY2cecDcvpxRcnGa/36zm1Q4Vc2fjyLA== sig=ozhXIpDtjoWMb3y3gXpMF3EoO0brOkNFqlh39UvXGKh6DGCsEZkP0laoOa9CmSNsudW7AWHFpuDGb6h9TD+BCg== e=found last=8 s=8 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAnQlX1byz9yXLVplcKH3Q5BVWiEr3/ciL4UTJMh05vME= priv=MC4CAQAwBQYDK2VwBCIEII0XSb2W/olx0iwraXP6BIHxSpJ6ppd6zAb3pxbo7Vcw msg=iXHSLCtpc/oEgfFKknqml3rMBvenFujtVzDd0l80J1BRzbc+g3sAClERq1i9W6Lf6p5Q4EKXrhHo4jDpdO1t/g== sig=D32gwLV4Ct9RTKHshmhyOdAqUq980il27KJiIVpEIbzCCN4Tu/Ot14CmqD3DrMWhySCE92mE/OEM/JEIim97Aw== e=found last=8 s=9 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA3lj7c1xVRL9GifpF0vbVzJhA2W8DM6llkQ5pQm37ICU= priv=MC4CAQAwBQYDK2VwBCIEIJ+CGWFDgWBD8aHfwm4G3j3S3oc7cOoloSA92c4y0m93 msg=2c4y0m93SRjJAxs/lcmXCFEh+lA8iBT6cwMOPCM9aom7Lj4g4wfaK/EJzl3ihLZUCsfTGb2FVqN7HKI7QjpzTA== sig=Y1oBzCgNMgOWCDCJCtofjPdG+MJlxiovz3dewzZlEyD8CgU3Veg4PjnZf0/XTyqqbtyjZpe6H4xe2LPuNFRzDw== e=found last=8 s=10 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA7e+dmJxL+hA8MSGvJmWeXY5QO36yH48Ej3D1qXAB9hE= priv=MC4CAQAwBQYDK2VwBCIEIGTSzmUPggVaGDOeBRYH+HUAxmUCd7oNOf6EZIQIArqX msg=ZIQIArqXIWigmeFdfQlOczuahBjTmQpZlCRflabFX8a/5SkXuQsr2j0RneE+gJsfQwmlR03ypvA8hee7vbgvhA== sig=Z6JzeB+7R0rZUIFBMrlVRKdZHnZNWe35zDnDvUaI5oTfMqotoODBYv9nVs8fhhGNWoI7ER581271kq0uaf7CBw== e=found last=8 s=11 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAWbBZIPRGne8NoLilzqGt8t5gIwN+aDV3dtwXlsavt/U= priv=MC4CAQAwBQYDK2VwBCIEIEzZNwhT/2z272OB953mXMqvSATvi+QgOEyUtfnz0Tb/ msg=m1c7O4i6RapRT/4r8a8paR/D+Y2Mwd5MEfd4+JMcKIeNSAgT8m8bL9xdKLREQ47U2RHjJ1DIsQcjmcsAuChn0Q== sig=5mbvX2i2thc3177yXObrD+o1Azy/+nAA7zugs2UBgT4Qe+rrPW5bnYm6PA5le7+dR8x2AX2QlAo9ay4qciK9AA== e=found last=8 s=12 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAXNaMG6/QO8MW7JXygKXAC1wTiqdZFEMJm6VSppHEYzQ= priv=MC4CAQAwBQYDK2VwBCIEIBCXYtkB5I2zPtAEgbtSuOod2OBTbl8lqonm0uEd/Vsw msg=zQ77IZHxLLtgdfzpej4P5z+ZyWfO7vtQvgKOYbO22M/RnnWPu9aQNYVIc6ceUpnIUNW0SBEBBbUD5k2rjJ8erw== sig=twCxzMDHJLDyD55Emi8GhdHQGBmMw1yc23DhTVQLVFvw82Cd7c3LxhtywMmtrjOHkiF4tJnlXvf0MvWaRXlGAA== e=found last=8 s=13 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAeXVWB9eA9kvLwcseA7WgPni/V3Ju8suZrgVA5ny5DZg= priv=MC4CAQAwBQYDK2VwBCIEIOK2CDCISOXlLazxVdFz009cXMHhMZoySakzjEDeojjs msg=M96mO8n+Tlu/bMKVR2unmeK2CDCISOXlLazxVdFz009cXMHhMZoySakzjEDeojjsgsSO4WHhDl9aYS48VaZjAA== sig=qOFKE+ETWR/Ji6oZBsFFFy/wSss8QuWvuyp2C4PiDS+IShrikZeOycQnYJa1AvuiEwAX8+52GiRcucgq3BIUCg== e=found last=8 s=14 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAqjlMWK/99AfUyCCN5nf6y1j1VbTSfCW2N2tDO5u1YA4= priv=MC4CAQAwBQYDK2VwBCIEIOcsjKsviaKhOp9DnkvWydUDgvdaVc3gKduAIoi+yP4d msg=S9bJ1QOC91pVzeAp24AiiL7I/h1OQL/3vosVSt4pzTB3Vhezar+q00i/KEuG54xdkouoVBITo5mwITdut8198A== sig=j/oMGa4uQKe+esk9qT4UgVtC0i6H6MkKg+etalg+nkJtplcyxH/G37LLZt8BjgiKmTB0c+MbpFy4+DuZhl/rAg== e=found last=8 s=15 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAWWmXyvXKwlqbgc2YwPfCnjFTInMvfCMe4oscv+e7Qrg= priv=MC4CAQAwBQYDK2VwBCIEIOnbl4xnhiJKS8LxEiXgMUXP3PeM1sRx8LWPkfqoWrg0 msg=mh+ELRgCFk8vQAVSGQWzCk/GRUK+HXIFdgf6vwle+6xDALtcN+n3QuOdUIuvdDpTdXxA+oxQCUgehjCveNPTTQ== sig=ftdXyEV9fAzdHJJwkPS9e2OgD3Q0oidFj+2lb2juIn7F0rn19bEAY8aX+2cbBl6wOJdUAdBibHbDLEpmnz1fBA== e=found last=8 s=16 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAkYwNXxIjO07/jOzUKfwqa5in9Npxv1Nq/AxM1iFy20w= priv=MC4CAQAwBQYDK2VwBCIEILwQkUC1RzqHYKebQPibHkCWT/TJDlEMV5sRZIeiSQYx msg=vBCRQLVHOodgp5tA+JseQJZP9MkOUQxXmxFkh6JJBjGixD1uOTGaZWI/wng1YS70HNsLXLh+iJ+1Rdq+x1nm+w== sig=hpFMkzvbCEsH1gU+5kh0UgX4aZhZaGJaWb9p0UwlMo0Xu14VdFlG7B3Ep//KKmnBKJF9vQNrbq1Usz17w6QHBg== e=found last=9 s=0 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAV02+cCQrM8L4JKFopwC2Irk/r8IvdTHPFsSpIk28BqU= priv=MC4CAQAwBQYDK2VwBCIEIB0WJu1FrVCAK6qDO7TeQ6XwTnrE+v8o5icfZc5B+LPa msg=HRYm7UWtUIArqoM7tN5DpfBOesT6/yjmJx9lzkH4s9rCrJ9F08XlZpiw9qaxJyXkkWZy9NjB2FgQuuYLfLKjvg== sig=2Wk/i9ez9AHXNU0nRxONp4cXSTE/bvGLuz+7r/wvMeSuV6giEcOI96dj5dlhkZDOMVo5eGV4lRm2NwEgpscEBw== e=found last=9 s=1 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAa4KfKBqr6aYogm4cGelwOKZXt5IoLmg2LkgOZ6MC2dk= priv=MC4CAQAwBQYDK2VwBCIEIO3itNpDAh3vqm+3KL+XYL4JEGxKrnbtTLQA9jxLkB3N msg=7eK02kMCHe+qb7cov5dgvgkQbEqudu1MtAD2PEuQHc3mk3frDhDe792tXRKhsa9c7AGoLmCdN1TXkeBYMhZ97Q== sig=lASYRIYV4FWbqWpPskbBOuqNYxAGXEDp60ZqAopAOo5dO/A9SluLLC2X6BSJmLgjRdlr0/ycE+XxkocXlIhuBw== e=found last=9 s=2 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA9pByVlq/HxICKK8qchUErWL/krcCSX+9IJkicy6iG8Y= priv=MC4CAQAwBQYDK2VwBCIEIBgPTZtMsMfSrpPCS/TfBxB/JdEfk/ykwO3/Pu+zFnjU msg=GA9Nm0ywx9Kuk8JL9N8HEH8l0R+T/KTA7f8+77MWeNTeYlaLDNEmVq5adGbq+VbkvFbQK+sBIAGCKIeESrNulQ== sig=2olUmwUJ54cnHlXg6GNOJ1ZTToPjJCdx46EbgntQCniZ0+OPctPWLtDyB7cxGdAcRwXUctz9Ti926TR4SkMkAw== e=found last=9 s=3 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAANnfxxbj6gQfyUeFK4zVpbVWqS+NkZiErRjKAwqTeZc= priv=MC4CAQAwBQYDK2VwBCIEIDX4Pc7iA5sFwdbq11pHy4oUpswqrzmfsOdIrKZgQOjx msg=Nfg9zuIDmwXB1urXWkfLihSmzCqvOZ+w50ispmBA6PFZNNyNk9OTDE5dCK+d0zYeo0lZLkLBhcWrZfx2m7Oscw== sig=d7YAPky2medLciKt0p0T8t0vYdPRWnEg5Op+Qt/Ec8BMwxLVazignMi0q0pJtqv0OgK/Jo0PnAOIDe3N0GA/Cw== e=found last=9 s=4 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAPTYLTlgIw05E8u3QroDWVXI3ZMCSCPHbFROLNgqlDlE= priv=MC4CAQAwBQYDK2VwBCIEICkg3bbZvhWoOJXHGQvhSSlW99dNvxsC37HDlDAR7exD msg=KSDdttm+Fag4lccZC+FJKVb3102/GwLfscOUMBHt7EONvGCsFc+aNaXKKE5BWcEqKq/PbL9CkRtIVi+KdFP3vw== sig=NfExkMHj4/Pp4PPTBtnK3cu/pvCSfcBfl4daGYp/k0R7rWO5Kndcg9glv3LLmmnXhAwyQo6s2q7k0bsC3vh9BA== e=found last=9 s=5 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAtmT+YSWOXfl+r+ZOFS8+GZrfxFyk0F17rgqck9uJd84= priv=MC4CAQAwBQYDK2VwBCIEIApJRMTJ3VGYFnZBeMOiSKUuJP5cloneLu6iDmRIbOHb msg=CklExMndUZgWdkF4w6JIpS4k/lyWid4u7qIOZEhs4dtH0nACdz53tW/8M/CS01fUPVecHIV8BTxGmNH1m4CoHA== sig=0oYGnwIENxqAL2KS6p180hAAxYgDzalNQPTeTn5IOU+8J7X8gS7l1OS+CT6gXEhxMT7QfAof+tZ/yGb8QT1FBQ== e=found last=9 s=6 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA0uZpdCaB41K752gkuJ/yCS+GSqbzbUCrZJIZFCHYpwA= priv=MC4CAQAwBQYDK2VwBCIEIJBsyZOs1AyRoESIwj8q0rGAbE2wKt6mhNHnZa60Y880 msg=kGzJk6zUDJGgRIjCPyrSsYBsTbAq3qaE0edlrrRjzzQpBr9hwq+ON+Zh1buD5QVi3f+YVNb9i4Cxtq2jrGnciA== sig=EFZ+ptOmdiVI0wreL9QoVBHk3ODW8md4F60rbKxK7PF5cxDURE5XZXP0Rm86Opo4aU8jAe+a1XjKCPj9FAwSDQ== e=found last=9 s=7 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAqiGoAZp3DWqruj+Fp/+XYlZGodqEGafsW+dhyK++RE4= priv=MC4CAQAwBQYDK2VwBCIEIIiCxByaJP/yUxt+BXsS70bzbe8iJkgmRhqGoG8Znydv msg=iILEHJok//JTG34FexLvRvNt7yImSCZGGoagbxmfJ2/NGe6/3JvE2VV0aJILU+RR1KW+KqbAIJ3R7oXl6ynS3g== sig=y0DY/wQ2zyppos1ixORCPwYakPY1n9lYvzs84Miuka1SUoGqxGQnnKUwvSEAiD9/4QSNmEZKreO3DIqYfF5eDA== e=found last=9 s=8 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAG0DkU9Cw0kKK6y4L7ge8OlQ3vgX37/qpa1dXy0ZW3Dk= priv=MC4CAQAwBQYDK2VwBCIEIOUGERxLBkusITTcRfJjBLueOIYAMYvC/O1O0IRvz5Hx msg=SwZLrCE03EXyYwS7njiGADGLwvztTtCEb8+R8QXqBFDQjqrQUHIv1h902+dfVM0oON1UH9xJ+yPFQcgnJbrvzg== sig=1G/9BCxaO7LUkc1PUeun4WJeg0E+sQ7c+HtWdA065FMtHApi1jSyeLAghMYD7nAJ8XWH1ZeL79tAv50mQcvIBA== e=found last=9 s=9 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA7MnHuT6tt/lCl+TIT5pnyCYU5XFDcSNWNQJMBZPpGEI= priv=MC4CAQAwBQYDK2VwBCIEID3YdiSenH94I9G1Owqrijo4Phmbau6wIu7Hjq8GR54U msg=Owqrijo4Phmbau6wIu7Hjq8GR54U3zhDfkfTkkvy2FfQ67Dirf3bYg7X5DH3EeyjqJ7nVqSv0WRfd11+ALrnLw== sig=cEGpmtKuNKCVE+S/zz726cGCVsi57RqkSfavuouzKR1vZiztiDI2KG7c4aWEe9Ner8XiTLRhG1dXksFNMrCPDw== e=found last=9 s=10 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA7wA0xL4EtGwZiaCkEyKW3LjalBDRpL0foWdiriRydbU= priv=MC4CAQAwBQYDK2VwBCIEIBUWjC7M0ncKM5bWoz04QWLaGjeq3+1TeG9V6JaZlOei msg=sX1K6e4C7icuNDL0p8CGrgNYa51G5NRVMqNLaml5sXh/KcEB1ysB1Lhj4Xl64K/EBqBEYgOlazNtEXzBR0Yfww== sig=6712YpTl/NP+N+7Ugx31lAuon01yIU16cWx1+Nb3YPSJWFmHefVRS/p/iU5bAR2LTZaM+IOfNEzrnNgFwwZvDQ== e=found last=9 s=11 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA/PUSpUlNlkmMJL6V/wu1YM9i1QrjEdZ7AB18OWZrdD0= priv=MC4CAQAwBQYDK2VwBCIEIF9kxqbFR/bP8cPX9xLs/p+utd9zs711Z54OI33KOTGc msg=X2TGpsVH9s/xw9f3Euz+n66133OzvXVnng4jfco5MZzRGyWLlaVPkC4zIlfgwoRj/klcUSG2r2qm1IkCkgt63Q== sig=k4oTptQNnSQAaM9XTRRdKKqJM08Uh0sLjyVwXpdXMhLVskbkhOO5WH8jq8uNNPJhWPy4BXSQ8oU9zELC0C4ODA== e=found last=9 s=12 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAzDxv6JewiIIhyMvN51dFnqL2iNVcZlSbXZXc6Mdiaqk= priv=MC4CAQAwBQYDK2VwBCIEINsb+bZLSge5sDCWmZSxXTSQGT9zyVFfMASt3X/unDSz msg=NJAZP3PJUV8wBK3df+6cNLPe/XPjhD60FN8yrb0RrZDr4ZtkSAUVbdmAVnxePeL0h2VRaf1er5JOYcLwf8gNUg== sig=okXEnDcP9+a/ayCrbP5fuE/GgqyHPXTXzYcckPYIjRphsCCXM26jJYZJee1j8GZ9iGGa4NfY3dBHUrAUCQ+8BA== e=found last=9 s=13 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAjvYiTOSSJMsUtS4N9vDcHYChbjQrZ1ojbpUN/kOzm18= priv=MC4CAQAwBQYDK2VwBCIEIF0jbm4I3fMCh1KqsOW2JF7Ji9epRhX2JWf7vpnOYgzJ msg=yYvXqUYV9iVn+76ZzmIMyT0Q/18/7WiceC1ipvFW+MCoPMWgf2k3GC7eYSqgOcG74QqS74ZyUQgY5wxAwBktHg== sig=k15nJEzbeysp6a3hzly1tAGYjTgNuN2bh3JTIUdfY4pxSb6Rq7aI2+p1TKfs3I7WxMzOv0v7iixLuhIU9X5OBw== e=found last=9 s=14 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAmcNAEiexHNXUoCvWg508hPzmO8yJYdjJumnSNv2ycTs= priv=MC4CAQAwBQYDK2VwBCIEIOViP5P1lT7CgNfAGlbQw77Z2ssolKf0y5rl1gCcxKIJ msg=gNfAGlbQw77Z2ssolKf0y5rl1gCcxKIJVz12vKOZVj2yto6hSEfy4xa8f4275UQfubdg/rfvYjp6MscUcrl9ag== sig=xKMlGqDwTD2Y7AhghforyjtVkj5mDpg6KQZ/BPWNiAXbDZkzGFPqLxQn+RO3ODZaLE/BOZZawRtKkC4IJeu1DA== e=found last=9 s=15 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA5WH5O8LU2VuNmJawr40b1s1VlvN80HxbqRlUaASCHs4= priv=MC4CAQAwBQYDK2VwBCIEIH/UIR0thAsHZJKnDtjiuK37WpRE3bNFL0vDXfa2NYDr msg=shC6+xGvSAlng9Rxivs6nxjUjo7eSHdo2VOSglzKS48BtXax6vs/wy+SMlogaW+yuRbnvmzXN6AVLvxUl/3abg== sig=N82jX5T2xTUx71eX+pw1/ZGk2lW5mXwJPytuUtGz6UZHij05/EMVr/dO83BnC+LoXj9B9lURl+JGHGFiHDHcAg== e=found last=9 s=16 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAcK0asppfJji2L05PctFMUNDnCls5vUiAJS9Hfz9lHLI= priv=MC4CAQAwBQYDK2VwBCIEIP3p2HiLW/JoWRmvGnbbNA0+bvcFYqyVZR5TnJ/Ep1tf msg=nNhQn5P9Nsd14TO1DinQUHdo8WcW4nCTeLNgjK8C+JnDq04SFdYFEQIHZkzns1+GPd751YZq1OaTHKLvxPcGqg== sig=yG3UygI3hYRSGo+9JImcjzTyZfqd0TWgZq5Hy0HuwiTwHBONPplQMo2a/XEVFQ1o6lcmaV8VbqOGi/llhqfwAQ== e=found last=9 s=17 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAY/zIG6Jfs5QSmhzkbhjR+3n3KX40SlneOrSomd6Mbuo= priv=MC4CAQAwBQYDK2VwBCIEIFuvqYK/ObcLTRooeSdPpb1MdVkR3MSnK4YUYih1KRpz msg=TRooeSdPpb1MdVkR3MSnK4YUYih1KRpzXxvFIujSDuuXnwx4ryuy+VpNvO1RWnhb4bKrWz5K3fVjwM3N4Xz0nw== sig=pXs8vQuYjpl/3kouKfoHGL+3NK2cobLi/kdp3SIXpkrEhD7z0m1Ly9Tu0jE/OQ3onYUPxMbkKBv1iePqMsUkCQ== e=found last=9 s=18 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAAgtEREehKgJzyElLZdQRDekKQHRsQYliNTM4b/4yyos= priv=MC4CAQAwBQYDK2VwBCIEILtvd1N2uiUQxu7QIdhOZku1kW5lixXgn8HgNv/UAAPJ msg=d1N2uiUQxu7QIdhOZku1kW5lixXgn8HgNv/UAAPJ0FP1xwL2KN6xHHaQvudejJYDAAQRfbFzKWhMDam9Z3wzGA== sig=NLQx/T8mKzkO5kXIDoDPg3sJvS7jyrGE4/vu1x5nZ1hYqrhmCHgkYW+keB1iylplin+shWJCqRabGOwkxJjDCw== e=found last=9 s=19 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAZJFyOeWROi4E9BnEiIAaAt0AMMj54bxhymyJ2cHmLaE= priv=MC4CAQAwBQYDK2VwBCIEIF5c0l1a1epb0vy1p8fnWUiuP7mAJlKN0CzWE/qmjIXN msg=67z7TPrx7YTHyNV2jm+JyQbqNjEmhvQPE5ZFzvkkSYu/WLg4uiOWnpyOVFoHMsjC3vgKOO5gvB5ZXlzSXVrV6g== sig=is22m/5APwQTBKqiO326H5dOVKncnV+NcwcS5qV7GzK3pvQns3gpHBJiIeMo+ws2YFT+kYjbZ1KVwjjs1D7BBw== e=found last=9 s=20 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAD5+SD9ck55fh0YXAnJ01UpxamLnT0cj4nxL0gIoay1E= priv=MC4CAQAwBQYDK2VwBCIEIMcoYeZci52NrQneWZ/w9KXIuAUlx9brTR4P23vM8rOf msg=600eD9t7zPKznxtsqEoAefvhHq8vVetMa3HhStvd75SVSc4VCWJTEGcWj/uFYn+GPSAs8uYzZFI2YGQ65bQlQQ== sig=KufNow3WBbWH6dv71lzxT0laWZ1RI8y9S5N8v56OWiy51Ql7k6kvE0POIa0hN4HsHxoSTg/jN0JRgKfJcDI1AQ== e=found last=9 s=21 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAoAYZa1Nt0e+7DsDzYVRU7lz5NUYV4L+ziGWGjYe9sBc= priv=MC4CAQAwBQYDK2VwBCIEIBUWPxM7whavZBNoBs1HMk1f37OxVxgHvjCMmqtBPjFw msg=GllQHAyjfOskgeglz77OOMOF4YgvWJdN3KntGV8m425ZYO64pNz9O6NM0zZMQ3dylPMbO5PGHr0npBB509Dkrw== sig=NGdbuHsDSnAtad+VZrtKmvq5RKuE/hkleVnFQgOebNIWJbXz4HWWd8I15fQORnMrtcmylkpUVmDpkm8WktjOAg== e=found last=9 s=22 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAipKryMwM/0tYkWGKeuWQ2BrLD3eZhoplGBx2pUXuoYY= priv=MC4CAQAwBQYDK2VwBCIEINofJjfOZbLD0vBp2YvJ2VO2r1cK3hVXSVgasDBrDhYA msg=4TIn+/vaxTWHcDMY9JtioMLg3eL58mc71vn3fCphyc7UAVpIQqzBppdN1NofJjfOZbLD0vBp2YvJ2VO2r1cK3g== sig=8GYXZR0fCaRcfYfPjFoYBLqWPpf667gW5j3LCm633VwppYseQl9llSme5HZ4HxpGjUpwWa0LBHm3pu79qP7CBw== e=found last=9 s=23 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA0+r9hsqiTjCjFDcVZJUQ/WnpzKlMPAFIC9gr0UWXsfI= priv=MC4CAQAwBQYDK2VwBCIEIL3hgcrDSSwEc5mPDHKsilZwVpo1+am7bDKxxNRp4W/q msg=Xlw1fpWAd8bMdBiP8lR+UqkUQ6zKSsIh8pEsdlzkQnIGN0BjP+bho+rBymms793O2pQtPRSAv2ZqSsGYSVdv4A== sig=KrWy0pedC2y0kGnGHMrRKwcqNCKqJrSJChmDIp6/kr9hiWevv9SzOtkBz7dyqz54kQKkV7aiipl38eVWpTU8DQ== e=found last=9 s=24 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAqJNqsVH7WHQqzDWzuBBkpUZ3jo97OAFJwwsYpXmNkqQ= priv=MC4CAQAwBQYDK2VwBCIEINuYcHj/RYcsDZo2xow9O4LUvC9svVIczDzfwfBg6ZwR msg=zj62QbXbmHB4/0WHLA2aNsaMPTuC1LwvbL1SHMw838HwYOmcEdMgHRUVbLlmielkrgnMB1TTh7j1/LE0yXi4QA== sig=M7ncAHELwXMVNgmr79fhUYJJz5njUCRp6C3lPCopgRBAQVQ74ZNp7wU96M6TtJqNqqgjmnWXZdY9+VEEkF2YCg== e=found last=9 s=25 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAlSB6wk24gl8uMIYOftnOXlAS10f0QZhgW9DtRUD0VGE= priv=MC4CAQAwBQYDK2VwBCIEILVArKqBMcxgyHED4D0JekGFOoiGR9mU/VuSj8jfZi3B msg=M9yKYgzvBrGVb0qCfgbDrHd09kSe4GxbcsqgxB2QswTg7ASw3FshhmVc4rVArKqBMcxgyHED4D0JekGFOoiGRw== sig=y1FaqnbV3A22fYhfPap8p3RSPi8q9mm2ODkwlVPiYPOVmHmQ/XQWG9Te0qQxlu4IkzmdN84dLGhqjgl7W0z9AA== e=found last=9 s=26 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA3m0trGWzujesZ5wBv93uI9jJr8g28SH8s2dAMFUhZ24= priv=MC4CAQAwBQYDK2VwBCIEIH1h8TSXkvgzu356h7PWV69yPPM89jEolWmVUtSQuL2g msg=6KrNoCQDEWn6eJgxfWHxNJeS+DO7fnqHs9ZXr3I88zz2MSiVaZVS1JC4vaCqSoHu3PMR9qWlPJfANvll5c2IRw== sig=2skkVrGw7D6+NxD/+6rKR4QZq6O/JFw6Cyoc/yEKEfqS2S6fh1xFntGgzSuKkV1NI70NBPrGG0hS7TLuEHglAw== e=found last=9 s=27 in addShifted_NP", + "pub=MCowBQYDK2VwAyEABmnUosH9Lwbl/jpp1HWPNERP3dVm9NuObFysF9nkajo= priv=MC4CAQAwBQYDK2VwBCIEINuEYV1lE8tgKaA5fblH0iclSJBP1quiVgSnvcK9lkfG msg=R9InJUiQT9arolYEp73CvZZHxuNIwb+QZEqOdfERwmv5S3Q8oUp58NBqH1RKKHkZw+0b4+ZONP9/gAo3q624Kg== sig=oXpXy2gJwiL+JqWM/bWGyvqlOdhdzrmF1KZpWCSGuOteqme67OJLJw20DQyw/T0ad/ZbxsZpSzxOAcBOQ/d5DA== e=found last=9 s=28 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAPha2E/NsKWms+kDeMREZw2096/jH3Qg2hVCNTZK2pmE= priv=MC4CAQAwBQYDK2VwBCIEIOdOB6Uhu2oOn/m/RTIfQGVjHfn3vUy4gyQGok9kBJJt msg=LYYP9iKova7ayzxv9v2IBVbf2sA+bHKdJwfDk3FaXv+McuJfAYZBPrbM7NqOzhmcjEOtJbge8mN3FbGX2QzZ2A== sig=tVXz4p3SeVj5Wu1F7cOVTD6wo3EMfMhzsMQL7DK+w8F42GEupnfRA31XKQ6nbGCunABSSp+7XWfrQ1O564K8Ag== e=found last=9 s=29 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAIDJrbhcKpHNDeU2And5vrjTfoFnrfVq5bNOBa5ciA7g= priv=MC4CAQAwBQYDK2VwBCIEIDnSKvmbcaK1ndX8PAHq/XK7uGtXE109p9bKVPVuGPs9 msg=GcGC8+7ZATrixeIByMfGrWIGl9hzTzPQzWqZ8mzGgv850ir5m3GitZ3V/DwB6v1yu7hrVxNdPafWylT1bhj7PQ== sig=oooEOxSLirwLOvrHLUPA7lwSu0FMO82pgfVc0aWNWuJSkX1sOgKa/SA/Q+YNeoskf2YykxmqjpQUfRQiQ16qCQ== e=found last=9 s=30 in addShifted_NP", + "pub=MCowBQYDK2VwAyEASdXGBZFDSTHhwH0LVGVdKIr9jip2rcA3khhER4OqAHU= priv=MC4CAQAwBQYDK2VwBCIEIMYtC7NIDMqmG1Zx7nDsU8qznfPYoebif1tlhARFdc8i msg=DMqmG1Zx7nDsU8qznfPYoebif1tlhARFdc8itk3hViPL1v5zgMkM4Q+1gdOjPkxCP5kKX//T2uPB7Og+EmlIPg== sig=1ZHDDRw4DmXlzzyY3YvGPrvQocFM4NDpp++DDUsvnRRiR6EI+9P4m45A7UiLIlQIuEt32XBklicKK3JrX3PHCQ== e=found last=9 s=31 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAVlb0HkE69Gu8hMjjVZClUj32j3S1TvMJzdNvea7bLqU= priv=MC4CAQAwBQYDK2VwBCIEILT7hBeRhO6SdBNPGp5zITWWZPxeEYHjcUgzoaUNLGvh msg=tPuEF5GE7pJ0E08annMhNZZk/F4RgeNxSDOhpQ0sa+HnrBZW1//ktsWgKOs/lVhYQYtmDI+aZJQkr23NmU75ZA== sig=0Imh+/3HzkReLITQj14y2dOrsF7pN7/r/hzD0Mb0ES+RpYUALuoSuOZR/M+ibXbRItfDXpInXqZjaNyEJJIZCA== e=found last=10 s=0 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAEyGSb7hg3v3jaRD1coUoO0v1QUAL6avu+wnGLhS2GkQ= priv=MC4CAQAwBQYDK2VwBCIEIKUXz9TfYiR6pkR0np9usl6VsRw2dsfTi9YesskbKz6B msg=pRfP1N9iJHqmRHSen26yXpWxHDZ2x9OL1h6yyRsrPoG+Zq3/bulDuUN+GP4DezuGBh8FYWmh+GSiK0ZU6zuC9Q== sig=vZGqSpuz2j1Q4wK5f6dfAD6xh7zbV/A6pit1tdD/h7ouFRCO5+4WNod4QeEXn3X45Kifd1yzKjhiUq1ntMBKDw== e=found last=10 s=1 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA/LTQ6dWJsf0x8r4xflrzGu5ob5jomD9Xz5eZudZBP4I= priv=MC4CAQAwBQYDK2VwBCIEIPW0vIq8LUQaYknhv396XMiXvG3HPrl3Av4rK2/U5FgE msg=9bS8irwtRBpiSeG/f3pcyJe8bcc+uXcC/isrb9TkWARRa//azQy0mojFq3oU4IL0EQMWIbcMo4otwarf6ugGCA== sig=4XAJOZD5EPWQQlOaEuE84GkqygJVC/44gxANqLF+Bw6tmqHJ11cj7W93osV26Q8sErnutn+UOZYWLHXTpxq2AQ== e=found last=10 s=2 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAhjx1zduYLyPpAm1AFkcZSUn5B71Xdoo/8fORQlIXMNU= priv=MC4CAQAwBQYDK2VwBCIEILjaLTCMl77XJ3kQ0iQLzEOZW7anp2iOPB2IAWCzVUd0 msg=uNotMIyXvtcneRDSJAvMQ5lbtqenaI48HYgBYLNVR3Rqd8DW3DrII3u/FRgcvnqzgqg0H3nIQ/pl5+pbJIF6GA== sig=/f1hI2xcSZhG2KD99ULeeo3BmtKbd7eGCbaEdzK4XeSbMn2ahLsRI+p520FPT1I4CXwLg/o/Huj0Ng3IG9sbBg== e=found last=10 s=3 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAb74RfkAN9uRYgqq9epXLudL2eTv7ZYv4iwZU3OjfdyU= priv=MC4CAQAwBQYDK2VwBCIEIH0SNr0d7xZPBqtZqI2LHH7O36ltE+xAjsgcWpBSggh8 msg=fRI2vR3vFk8Gq1mojYscfs7fqW0T7ECOyBxakFKCCHx/gcR9Np2rftkeEfvMLUedxd5OnsnvoB/sYqksRdn+Ww== sig=p+9T2O/LUd5A3xUaGpx+CAphKAkMA+RBuh/8JyO4UxJGDzMNGOnFenK3sliJFO8LFZUd0uWDAXW2pDWVM5bkDQ== e=found last=10 s=4 in addShifted_NP", + "pub=MCowBQYDK2VwAyEACwJo6J60IffgxcwJuzJKcM2W5Mfm73pxiwKY5ueMTaU= priv=MC4CAQAwBQYDK2VwBCIEIBpf4YFV8PyjuTT7iBv4WEIDsLeUHH9yqvbrGkozKTap msg=Gl/hgVXw/KO5NPuIG/hYQgOwt5Qcf3Kq9usaSjMpNqmI2Mx2Fv300kvTSRHPX2xBYVQA3V/1mhumc/l0BsKcRQ== sig=mV5ptzJgqw4Il0LYbPpDuSUXRih4Gj8ZL3LymD3j/dzNerJcpkoc8Q+rFAM/AE0PoH4DRsiBtw5UK4iorrNKDA== e=found last=10 s=5 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAcN71iSHVJjl3V//79Z4bN6WLMqIZBKcSYEJYoVYSaLo= priv=MC4CAQAwBQYDK2VwBCIEIDKHweTUgYfC9tPsHntGddFL+uWNg0Gr83x0dJeGCmkB msg=MofB5NSBh8L20+wee0Z10Uv65Y2DQavzfHR0l4YKaQG6AZF/9O220wMP+rlN800BUJIyLGMzJHCczw0wrgsUhA== sig=PXOl/Srjj25XUaIx74i8jzMgGzB0ZasYA1oKgTN8zrrCUAfhjXmFUQgUEX5U097ue2nljNY5bF9hYpwYNudzBA== e=found last=10 s=6 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAuyAA2Re4VIzhYipYG6ShThl6gA2hMIpZXnq3Lzit2yU= priv=MC4CAQAwBQYDK2VwBCIEICf7I7MjMcy8kaj5rgh09BkNdp2hm4MrGF54Sdiim30W msg=J/sjsyMxzLyRqPmuCHT0GQ12naGbgysYXnhJ2KKbfRbY0cGlxpRRGmgWPDu/FNcnrAZmIsjfvpJky+VDP+103g== sig=cYipUjeEX6FkjqYgb6kNVDS5j/cN8y4sF0fmqUfRQk9wGB/BogIlCDgjgTL7QJAFFBEZkG90FuMAED5O4VIJDg== e=found last=10 s=7 in addShifted_NP", + "pub=MCowBQYDK2VwAyEARCMeILoMCOou6KDO2Ek5Mmag4SqAK2zx6g1Cqhp7WJ4= priv=MC4CAQAwBQYDK2VwBCIEIHxbQJcE5IqzmV9KSX3XkaB1/3FuqcMPiMU2GJR5uKml msg=fFtAlwTkirOZX0pJfdeRoHX/cW6pww+IxTYYlHm4qaWmDvL9w8w+luvuYjUiXqPiO+GOVDoEq11c9pNkD/9Tlg== sig=HMMJdYuPXSX6rb250uKgA7aqiyxa+V91Z29wF3/nEs+FIhq7TpDETubb3H4J5qFoDo8KUH6XBEQOP7eUY+HFAA== e=found last=10 s=8 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAqPNOyJi+N031E1E4biSAutBdEREnfQG5j6uOAsxpr3k= priv=MC4CAQAwBQYDK2VwBCIEIHNstdLNN2PJA5aT2xTuOXxxIScfy6hmNlLZ2Pqn+gaB msg=bLXSzTdjyQOWk9sU7jl8cSEnH8uoZjZS2dj6p/oGgc0JE/T/zeo37llQFkCSx/3aRbC8/pUASP1at7T9rO9h9Q== sig=GPawjStneD3u9xDQ21zztsDLh0IldbCQxkMy7/RXyXpbXnydkUHkjHgNMU3NkLwYJYeAI4vjIsyk7jyaB7nQDA== e=found last=10 s=9 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA4Z35dH8/CcN2LRm65u+z6/GXI6TRYxiEGcpEeLi2aXs= priv=MC4CAQAwBQYDK2VwBCIEIExKZwli/QlK0APOGNrtuBTqJ8fzUECrsxlJeCNrSRyf msg=TEpnCWL9CUrQA84Y2u24FOonx/NQQKuzGUl4I2tJHJ8W9qxEbtrisez8Y/mkFjnEcupXFlJ8j2qTGS9XZzB9SQ== sig=wIr6xHZSwi3ZSzQa2mDx3e68YwvlnehAIATZOI189w2YR1ZEgZxe9FvOido7qoRCPiOIp5qHvf7VTUjivPQ5BQ== e=found last=10 s=10 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAFSY+d6OU8g1lOHw57XHLafiIlpEUAmGpGBVOiS3rLvA= priv=MC4CAQAwBQYDK2VwBCIEIJRt/rBnUz1pXGVTCs0+UFeKL/h0PutEnRf6wzQAWuNN msg=/rBnUz1pXGVTCs0+UFeKL/h0PutEnRf6wzQAWuNNIZkh1NgxaUQLACQVftEUyk/6Gl6p4KF3SSgTOmm/FEEVoA== sig=8T4CEiItW7hHr5AtV04qHa6eP8VCwbJjZe9ABr6PRf7bQ+npCGuGeifqUPWLhbj9ctOXQLJqtoOOat5jZQfZAQ== e=found last=10 s=11 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAV7uL+/xqgXThMWDfHPPFYoIW0Gfa7oWBq9PzCMUu+Jc= priv=MC4CAQAwBQYDK2VwBCIEIJtNGKIeKjiVbofOWpvinLPZxEy7EWt3TVeoel080KPo msg=HNytJfxnrbV4fPC0wCtRUKTDkyzJj6JYLdhNQtdE4ARAd7keEF/iR8NXLEF4Jcf5irCYintWcfe36xVw/xrSEQ== sig=j/4rq7SGZ3cPq74N/YXDlG73qRXcHDljiAy3HNi/peSoSlLirM7iZFEm84HI6CNvOk6fpfakyhVnkKDFLs8QCQ== e=found last=10 s=12 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAWMZBMZHJxDr76or2k5Dkz5l1ISaBfX1uuSu9XyTRWvQ= priv=MC4CAQAwBQYDK2VwBCIEIBFLFb9Ccam98kur2cf8M61x9mgBS70PJuwLJYBsecPI msg=v0Jxqb3yS6vZx/wzrXH2aAFLvQ8m7AslgGx5w8jhwJUpjCjce3hVfuAV+7FLVBRNcOGmMJ0kfxKXaASxTUl7aA== sig=NQhphVoFN7ruP/SGwMB/11C7gD+EE//LmzG5PSWCVcFPz68z0drfhYUQpNxqbvUpSdh7Ejr9ucIsPVjNf/KYAQ== e=found last=10 s=13 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAMRcHnGvbdcg5hoYKyCKhQdbKPcmixfmbhEAZV1qN3I0= priv=MC4CAQAwBQYDK2VwBCIEICylxlnaUW1l63aNDHpMRukSUlmEkPWooFb0ibZb1Xlp msg=gJbulyePFp5MbZrYypQCrpQV9i2X7mXkPqBx/QxS+i2yxRWXjHNNFl6QzoqtBPl9z8IYC+Eux6UNjwFSmWcwng== sig=1ZN0KvQ1QU388vnTcsb5zKd6BgCWZ+S6Q+ddCk55eQ/6Mw4V7GuPmWBrbBimMUq6uc0SsLnMSMblK/X93EqDAQ== e=found last=10 s=14 in addShifted_NP", + "pub=MCowBQYDK2VwAyEATXo8KJbJlqPzvfXmSPDSY/XKi/1yGVbR+RXyvE3rSQI= priv=MC4CAQAwBQYDK2VwBCIEIEJMFXpB+27KcaoZ1sLTWfq4za+3LnMfuBeNZHqyeYjD msg=Hj83HhWVXaHKGd/BCXyquCXAnFWvUtljaieNV3oEAy0cHyqqu0MIsQKi3Oa8iAmIJDOAc1TIhOm0VTNBJ6ziIw== sig=6LUk2SJ1pV4Qrr/TS3+HVtuBFIhHyPoFnFqO9wZOZIylHVlK1Y5j15V+UVdi/k7xrsVlY39C+mt93Am5t4c7AQ== e=found last=10 s=15 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAwYjjGuOAEJKSrZUN3uM7n9jQTpaIzZlOlo5k4HgacyA= priv=MC4CAQAwBQYDK2VwBCIEIEo3olAw56nD3Jamgby0MAwGxRUt/xrl2HQvlTz7NG33 msg=kA6eRBB3+b8n7NnBwSF59WuBzD23NbqzcfDJGJcbsfKMSebDLmhg36GyDf++xDVYfyqyAF2FjnZjRYOk0Z8HMQ== sig=4P9rKPx4S0lAMeq+nULE6cph3rAsZvthRRVWIb5WeXFZ+8r3Zn1AfLjJiUXzeoL9Z5UneXxpRNlsDH/39ocoAQ== e=found last=10 s=16 in addShifted_NP", + "pub=MCowBQYDK2VwAyEABMJYQbNPi6qVtn9bV//RwD2mQ3D8/jTxiV7oXdAj6V4= priv=MC4CAQAwBQYDK2VwBCIEIHG38dnVo7GPjumQox3tTMlg+5FyO5ut+kuXkfScG9rH msg=zu3Ia4/WRT8wVZIaBZ40felwTg5LkJlJLO6JCzDbcaZbqNBVGLu87X1QdVXXjk0T31eRv4vWrPQE3eZ9cFlkEw== sig=bKeLxhg/6MQszu4Iv5fqZ1CEl+xqdqxOUrDcZ4JEtNQGVFre+GZEipA0AOA08GUe50BmlusCXfB31tAilcmADA== e=found last=10 s=17 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAqQSEbqatOY5e/ntBb77xqoekEwyieWxIu5hj8G8qrGs= priv=MC4CAQAwBQYDK2VwBCIEIPbmbBobF/PIKeeJCm7wp+mmEjSa7ilsc5ZRxJ8EvxU5 msg=LVlmCar25mwaGxfzyCnniQpu8KfpphI0mu4pbHOWUcSfBL8VOSFei6Q0XOsh0zIH1sarOizq7bQQjo5CzZtupQ== sig=ltEZw/l/O3s9r2NCcwdypi8X98ZAUgDkV8imfRqVWTgmyBoPQYXOsv8FDdfEKJhbwvDbja9sDvHAaS6Yh+PgAQ== e=found last=10 s=18 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAqpB1OA8D+a7IaM/L7Qm5zcp8Dw7jDbSeH8jHKQa1kmU= priv=MC4CAQAwBQYDK2VwBCIEIANjMFRGqjv4rnHLEIEXxlCfdhQZGA93m5DgDtjJTp7S msg=sevxozGLEYZ83MZlgRru9G2fIe2ImRiBxmc9YM80j2vUmACaB6xpsRj/kO3N3+ra+MmNHy63eO/DtALK6/nZYg== sig=9dw7rj/Gapr2G40i1W/5Vgv8YwJA2v79IzODttfJMnf+SIgshZU6Flz0jIv9iGkvpL5AaUAsdpkGTvAK1/cODA== e=found last=10 s=19 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAS4S4ii20i/mBlz5SulqFvxfw51R072Ng+G0pUifnmmI= priv=MC4CAQAwBQYDK2VwBCIEIBq7Kjo7DQGGhGRjGu0HKU2u+LD1KvX3SzckOmA2ALRl msg=+LD1KvX3SzckOmA2ALRla+RBw8SmZtsgLOMUsI2T3E4QWFUuQlqSPXEOQXNuQFxKBBpVRFx2p4us7WufxwHbNg== sig=Tm+Q+KyZXMfdB9ci1tjEvtR0CHfT0IiSRWEh6MJ7T538GnaHq/2OMsDEyREmWy4oi6sbFJnuDz1MALmOlaSeDg== e=found last=10 s=20 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA8r8zd+TXo3/AcvzsLSz6QalHsr/WnsX3YFJRS87P3lk= priv=MC4CAQAwBQYDK2VwBCIEID93XYwPYWRCK1Ez61moO6V29kemhvuJmmsycQXn8RhS msg=wOhj7z93XYwPYWRCK1Ez61moO6V29kemhvuJmmsycQXn8RhSEnAa4lBG3fGlhOn7XUpBBPWokO76Zqlm1V1p3Q== sig=R4GTvyLRt5SaFIryG6kpWEsc/kW9at9LkKilDND0fcjcg27olpnqVNCzpgeeFRGGiMRyc3UgDra9UfuwXKgRCQ== e=found last=10 s=21 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA4zUc3dKw2Bo1IwG+G66aUUpsKHihDr4KqRP63u60j3o= priv=MC4CAQAwBQYDK2VwBCIEINsJudM4W0AO8AWudVWZSF4KwYm2+OembJswyCnxelHo msg=AFjvIonAhEVdA0uqtMLaswvbCbnTOFtADvAFrnVVmUheCsGJtvjnpmybMMgp8XpR6NMI2SNQI24YycNNSiyUDQ== sig=WPEAtMZO1TFIwl6lThmzCLJqugzI6aBcWm2EALM8cK+fZY4S/dAUAOOO2mxp/Pl4LXyrSVLgE6E6yGjanaSPBw== e=found last=10 s=22 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAkdQkNm2GGT3obDqrf/HGqEm+72Yir9MaLWcPWeiOdnA= priv=MC4CAQAwBQYDK2VwBCIEIMC21Eyuf7BirEkh2e/dX7AlKRI5gh/pIDC765pkWUUl msg=dGAay9vdIjwzvmhvblcduY5dn3WSVMbpKnuIbTVo1WH5i12dAIQsNpsdsBJSREyuZNF++F4aDEN/S9vHTvtyHw== sig=D6d3yPXemyF+87iayBOBNUdErt+4bwmZJOeoNaIwDfY+Lkc3ne3sCcYTeS9yk3ormHlUF64R4i8OBd9SA7aFBQ== e=found last=10 s=23 in addShifted_NP", + "pub=MCowBQYDK2VwAyEACZXeoWc7+Uz/p8YbCbZl6KdrhWROE2+75lgAFz/Vjwk= priv=MC4CAQAwBQYDK2VwBCIEIMwnyOrv3mwWcAyEjtz6Z2XXVoneHaU08fIE80QO806+ msg=Br69k9FDWZpNrbg1JIsuCZ9FvoTmzciTChrlAAbn4BKRmhvwJVK3TBW3wwlTUswnyOrv3mwWcAyEjtz6Z2XXVg== sig=f3N+VPiv5fshu50pazT8FHapZYgi8YQUiLvxElw3sSsibUgtCAaqqnn4iM8wp8P0VGxwOE8KUfdiGiVB4MhnAw== e=found last=10 s=24 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAbxVtq8KC4xo4OZvKpF0/ZCPBKrtSYTAPWx5hrj4Pl0g= priv=MC4CAQAwBQYDK2VwBCIEIOkKLYsfS7Ql6jK7LNtilHq6ZgtOcyqBeM0sWNukksqX msg=I/TpCi2LH0u0JeoyuyzbYpR6umYLTnMqgXjNLFjbpJLKl8rT8S7gTNV4/ZJLePM5bIAlaURyD/IDZKD5WUc1xA== sig=OHAvOqnuQpKmka16etSSBQbwsjZkxgQqR2jKT0emwtUBkJ+uJTbIZt56EXpp9JtCJcZSS5C42Jr3V6cvOq82DQ== e=found last=10 s=25 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA50prt5SC2k5D9pTAIyyRW36S+Ti0I7S71n46e0VYwbo= priv=MC4CAQAwBQYDK2VwBCIEIBa9gJJXvvZBMS+RHLyQiYUxjB8C0ZtEVL3olCkwCjK9 msg=jIIgOgAtkjG9Ip9bXhyzI9i6VYGn3HiqksTbBWdU4NoUbg0WvYCSV772QTEvkRy8kImFMYwfAtGbRFS96JQpMA== sig=gkzykG06/C35xXUrX1C2hDwCgZusIQ1/1zn6ELHCDgBlEs0QQt56ZpaohnJZfsCSwYumb894xgCe+HlkhgYgDQ== e=found last=10 s=26 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAnc66hJZtPTUtCbOpDJM46whnhWV1rMza5DeN4Dk6g9A= priv=MC4CAQAwBQYDK2VwBCIEIF6R51kFPvUBoFQ9JR27yZi0C0ph3NsQV5S12xoRNcWi msg=yq5pSls4gRmfPAUXARU58qekyW5MnhMN0yx9L/ielQAv6Qtl2b+ayH6+1RkVX5N9u3GfjLMa85rMUt5xTpKIdg== sig=lS8azKVMOpogMBOkxDNGDARCDzuMpH52bQ5PD4nEUpWWMe5Jq5qCLCHsKUrKycdGrcoEaHRr25s9YAD1yXdiBg== e=found last=10 s=27 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA9ZKsRgfPpFfwlU9xjHLnGlTRNL1Pser1aYIWNTfMxjU= priv=MC4CAQAwBQYDK2VwBCIEIOFkozS/JK4EUrxeOHbw/Ip+22ql2EE6sHOV/8a28m8E msg=4vt9ncFtozirIg0ah48/maPhZKM0vySuBFK8Xjh28PyKfttqpdhBOrBzlf/GtvJvBO+mfw7W3F67FOWjN3qf5Q== sig=MnbhVIzMyuxhtZRK8oPY6ydSLr2SetxHVdkqUcorNDvNm4G0GbVFYGwhDXHB+HgxJo9JwMBnvovFVNcRoaN+Cg== e=found last=10 s=28 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAdnEYGyTkdvXlN4olxeZHHFpwyT7bFEr9oEc7HDj54fk= priv=MC4CAQAwBQYDK2VwBCIEIPaDt6jiNXdd/TStZO7Gt1NXACLEn42mIJUeWSSNbAH0 msg=t1NXACLEn42mIJUeWSSNbAH0tM+zPzkCiNGjuE1yWUlJWW54AaWm3JGSAg8a7/41Oc8uRCnmImGE/rmadkHJEg== sig=Gjm6iNbb456h9S+d0GDLOBmO/3JNiXaYmxHcsq1cWMr37pF8SxuLK06DtMkXjYWJlTGsCe7+r5IFl81GKx7PCw== e=found last=10 s=29 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAJC9DNWFv5HpWMhpRzHs18/rbvBx1npoYhAvL3hOJugM= priv=MC4CAQAwBQYDK2VwBCIEIECTblrzuON08UsQOjxvLkgCThpu0XZL2EU7Xf+Tlsn3 msg=WNPX6ECTblrzuON08UsQOjxvLkgCThpu0XZL2EU7Xf+Tlsn3cwACDY4WqOoOMzgnRmNnXcIdw4x7iOdyjbf4Dg== sig=VwGI9kIX0rhu0UdmpCs5RwPJocPHOkINuN2GrKEl9nO2XRfgdexuegl7lrdhsU4nIdB1y/WP0FIgHjdnyv2RAw== e=found last=10 s=30 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAoNrzyvd6JA4U1lJPv57gJ7h+MCP8MsqBFYKSQwPqYCY= priv=MC4CAQAwBQYDK2VwBCIEIDb4nYWmjDa11jn5TIR+reqlYn+nT7UtEyYThPKx/F83 msg=f6dPtS0TJhOE8rH8XzdK/jFBDfoIMQUW/kl2PMGF1iAN2Wu+31+gbAZPEHtadhO+6GchWnp4SfJCyAH4G4Cv/w== sig=BPRs7WWFQtsjNtEHaed7HiaADlSg0l+PKRFXOwj36plse3F/30dgXowjB6/VgcrIZ2OdEnbKt4d22dwHQY59DQ== e=found last=10 s=31 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAKU/2jLBnlWBLDa+1+5TCXJqHiIZyY1OGftYVBR5eN1o= priv=MC4CAQAwBQYDK2VwBCIEIFiz4GkbPmQhS23yuHc2qL1FzkLgOtkZCVrzHhJ2gW98 msg=u+VxJp5H0JPMIHWhgHhE27LCy+Yi9Zhz6NPYm+mb6HdzoskWICXPiac4XjbvBdtP7E1CGiIb5MaK1JWaQwf67A== sig=z8Qz11FHsKSjqI0wA3YlPqZnIR4wVRHBOmMF/pdy9yLr31xipzrJJSqHF7uuin6uVyWk4ygHdOoz4b+hJgDYDg== e=found last=10 s=32 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAMfWtTtz4JLILkUh8UhHW/86GrGeg02k/wL1fq0Yl9Qk= priv=MC4CAQAwBQYDK2VwBCIEIBSCZ3huUUH8ccjilK5MUo7HwUso79RLmBQ0nJCJ5d7V msg=rrAEc+tOw4dklgT7RCuJY0Yf1yYa13BpSbZTNwTREoTQ2a0j3FGPa2rcyNUYBmw7MUgNu1jY/vdS7rAUgmd4bg== sig=i7TAIFtrQnpTdI+4p1ikjvPjrgYwk1THr505niN9DSYY423YhY+r9NAarbAf3m+NYP8d9HjopzOQ4638zt6/AA== e=found last=10 s=33 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAH67SSmFE2UoeCllSBXENGKWgr8UhxEtMSicavvc7iz8= priv=MC4CAQAwBQYDK2VwBCIEIEXRHvPKOKunEplY2SlS5Ot1TQp9o/Qx/cG2jzwpLhIP msg=RdEe88o4q6cSmVjZKVLk63VNCn2j9DH9wbaPPCkuEg9JWERFb9rJIzqNhzZX9BpX18895TmFP4wjAFK1xLbrWA== sig=gLUZNaZQP7V5yyaQDDiph9UH/Lld0yuPyYihJv6c0QXXdhleOuJ2Z6x+S6Y5hqWDWESgoJjVKTMeWn33TFLxCg== e=found last=11 s=0 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAu5/OicpI/dl3JKhXW4/qHe3zyJCv36g+YdMxevtRoac= priv=MC4CAQAwBQYDK2VwBCIEIG3rShHEhyW/7wK90qhoeatkKD9y6Spih/9vPJyyWs+p msg=betKEcSHJb/vAr3SqGh5q2QoP3LpKmKH/288nLJaz6lpki53PluycjHivsbNs3oNbqHYYZWPEkIOuZVX7lQbCg== sig=CBW5muCujXDu0izreGTdqNB+7POtAu+DlfMS4DnzQDYtlgxigHW9AMoZRgbXRb8Hx7IieL8lNtXREBSSWB/WBw== e=found last=11 s=1 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAJNy7tOGnvPNxR+w2xU5j7Ff9H+9dabmFhMFIvFYc2qM= priv=MC4CAQAwBQYDK2VwBCIEIL3e6NSAIC7j5FkEUWg3LsXgk1LXHnv0shJVGGPfZnqZ msg=vd7o1IAgLuPkWQRRaDcuxeCTUtcee/SyElUYY99mepmZ54VwEJi0ntlvcvJhikf/SId/eRRng2e1uTuPPmJdAA== sig=xMnEhmn+J3Xf+qqAAna4zQ58b3/MJac3k9qjrtU92B5S9w/HwPTK586KqEyG+iZgJY4ZgQj6iKRxHKQNWR0JDw== e=found last=11 s=2 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAhveHcTGTusRrwHInOckptycpDK2nZdK3wr/so/FHtoM= priv=MC4CAQAwBQYDK2VwBCIEIISGSQ5tjwT9CHAF7ddg9cLLFoTey//xs4JtfQOai9Re msg=hIZJDm2PBP0IcAXt12D1wssWhN7L//Gzgm19A5qL1F44iBNr6rHtK/Gn6NMx4lLM66J2KdX9Eug2M3vE4TzXfA== sig=VInzg4YsPsXdfY04N/z1ZISqePfIsYF66WIvK/GIoSwh7nyIBjnI63zJ8nIZv23yL74ZYp9UA9GlBn2yIm50CA== e=found last=11 s=3 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAr25VJ0Nl8pOwup3LDTv0r8EX2MRFOunoHs6EroA1qCo= priv=MC4CAQAwBQYDK2VwBCIEIM6OoUlxc0zsds3cO9WlbtG2Q7NgLSSGRP3II3XhxaAn msg=zo6hSXFzTOx2zdw71aVu0bZDs2AtJIZE/cgjdeHFoCeV0kLg8ZlHHwxuUsrbfaeaWvoZBkMZZVFjIUShJLLn9A== sig=nsMqFs0WUYoDxi/p6sJCbESzwdtqnMNzseWeIMRsNo8FBDJ6SC7Fart2tPo3b/nW6HZmunMxR/yQI0JTuKFvAQ== e=found last=11 s=4 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAIFzDlBSlMAyII7GkwYCmvCEHdOHzLV1Ar2hnQCYt7VQ= priv=MC4CAQAwBQYDK2VwBCIEIFmyCNCTE7aBDI+GhcDWxu5r5I/+SwW4o7RxxiQjzkAh msg=WbII0JMTtoEMj4aFwNbG7mvkj/5LBbijtHHGJCPOQCFDm+Up4/yjD1+uUTc7hFXXev6CLS3BcxW3UWb9zI1OFA== sig=uuGz6SA+raR32Nt+AkTvFElAytDC+zVcvScd+w1c+4wi6HqsLXc3KHeJDFY1cEmoosML3cLno1PHngsai55hAA== e=found last=11 s=5 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAPkvPcRmCirNxX3716nKRaiNXbeM6XmSYAXCE9WjDwHI= priv=MC4CAQAwBQYDK2VwBCIEIHkkjPBbn2dlOmQDq0ANs5W8o/oRhJNjKKNOq12QmYBf msg=eSSM8FufZ2U6ZAOrQA2zlbyj+hGEk2Moo06rXZCZgF+0qprXj+WrnmQr7sc9vwcFtSzfnz/yLFFZeCJ3FEXKPA== sig=diDsW286QNlKwB2pfRiFydq3JkAwD34hPjWNJ/Z73fGLOVuJ+OqdpRs7SgNGbT5y/IRRUbxt6Y3K27upV2KqCA== e=found last=11 s=6 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAKO6JRIkJeYzB6x/cJqQTKnHiUgPWTlxI+G+FP08bOuE= priv=MC4CAQAwBQYDK2VwBCIEIA+YF4XsQiyJA4poxuKSBAqMOOeqLCi4l1vieHL1T8js msg=D5gXhexCLIkDimjG4pIECow456osKLiXW+J4cvVPyOwSbKg+8JAfE0yylUcCiS00YHROutOHMMftU0XgzC55ow== sig=SkyBy4MgE/KUzB1+UU4sEwIz6/xzO8Up5Jy9pj8j+LLN7xYLSShg0de3E81U8f9zp3y0MlLg46JS2YqC5UavCA== e=found last=11 s=7 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAI/9xOLfZwT4OhWPuEMmAyfS17KxKNyyaSWhUQOedDQs= priv=MC4CAQAwBQYDK2VwBCIEIEktvOGcSC57HhkT4tCoM3cNQDrDssUX1MGYfeivwVno msg=SS284ZxILnseGRPi0Kgzdw1AOsOyxRfUwZh96K/BWeimiQptm8+D0PgYoWK5S/VwMGAAJRc2ZWOi13ngyAdmYQ== sig=+WQ2XEQ1bEWPH4KPqqtJ3ZJYoC1wLE/L/GR3GrxGo15i2hOKADowbq9dQCujCswlbOs45XmEvR8glxdLfBWADQ== e=found last=11 s=8 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAH3pupeRM+ImzqeXLRZ3KiBEeGJSixQLTn3HwJELBjpw= priv=MC4CAQAwBQYDK2VwBCIEICjT/cTsZKT114yKU69XFquI0Z0Dzo4I3stF1idrr2Gt msg=/cTsZKT114yKU69XFquI0Z0Dzo4I3stF1idrr2GthwRqvQLwzJy82LcQToQFSSZ7/Awrm2pam3rm338R684iNw== sig=dfhrEjDsXrfr9Xnvx/y4F0E10RFdrnlw12Ab5Hv9ZLNyTZGj7MeoHDXDiE+CbmU+ChqXjO2mlyGQJpdLC+WDDA== e=found last=11 s=9 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAc1lTNNekCBSQgBHSWKNSsCigq3niuuEwl302agk8q2E= priv=MC4CAQAwBQYDK2VwBCIEIM4rllaaHYXgHpngGLE4siGc5CjkQrjL5YiDCF/6ChXe msg=ziuWVpodheAemeAYsTiyIZzkKORCuMvliIMIX/oKFd4cJE0joNoVJzm7tJBIiV6wgqwpCF3DQvD/KLm153s8HQ== sig=8dh0R4fSgyai+gMaqtqn1s0IOZ2NwUgyhqk+HgGPN+GwU+Pa8zTLEpEk6U5C4MFnifD3pGheNuTHFV+Uoz9QBw== e=found last=11 s=10 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAa9JM+bSVNb1HGtugdGUMFvaNheU4s4qILCbQOHsYWM4= priv=MC4CAQAwBQYDK2VwBCIEIDzng9n2X0ZS4OUh4mObO+D/V69V4fdcVRBJkVqdIeWf msg=54PZ9l9GUuDlIeJjmzvg/1evVeH3XFUQSZFanSHln9txvxtqC8ve4bvnkqx5/kAsvO3SN4s+1BaO8h/SskY1Eg== sig=zcb3cvMbGkfWmBsvPsD1Kij7tB9SCzeYtAV+nv38epl/16Uw+I9mnF99AJ9lQeI/bbH58cB/ky73snArv+lMBQ== e=found last=11 s=11 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAFf7CWcNudycFYYLUxzoxK/eL49YfUfwf8SSPZhgJmhw= priv=MC4CAQAwBQYDK2VwBCIEIOqbiByWozm8sTlavmtfCeMPEPQCtZ/F78x1RFA4ZrbC msg=m4gclqM5vLE5Wr5rXwnjDxD0ArWfxe/MdURQOGa2wogAVidgOfekO3a3Uo0NFYut7E7FDQeWdPlCCFC2dPdJ5A== sig=+DEgL2lID7/Aar46WfIH9VmS8rXj30jHCau8oIJO85FZLBI8lUeZkIF9Ryk110q//nE2Pz4xbD8jYziOU7TyCg== e=found last=11 s=12 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA3usUzG1o6zXMXIioxcnkIE8Sv8+q8tnhPTOQoWl1zwM= priv=MC4CAQAwBQYDK2VwBCIEIH60m/gied7HNipFIyKQga0UIum65G13ivIdgYDFco3S msg=InnexzYqRSMikIGtFCLpuuRtd4ryHYGAxXKN0uEPonimdv5MeZu9eAvNAtxhJTndWlGsNIT55ORIA04aWofp8g== sig=M3jb679zGQrz9CjMb98spOevNoU4NurvQp8Yg/huSolc18+KXWPxhc4lKC/ne91oCk20wAQx2PEd8iSKu53pDg== e=found last=11 s=13 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA3aktVCM10MLyCN6qPw0jpH16edO7bw6dRXE8RLtym4Y= priv=MC4CAQAwBQYDK2VwBCIEIGmcWwMp6Hg29CCkpRPRjcIR02HYYKvDzYVc93n6WjlX msg=lPzLeAFFj03UdUuhPhGIi4vqKZj0rDeXYr/WXD5AWQxZvdfgq6glA9/yY9sj0xgZXq4UOQ2QjkNQqMpjnaPBPQ== sig=4o6jr5G8tRdT791yhVTLLoTuxdM02ij0wobQ3tcEJNrsdYw0u7Gljy3wMkqKCIwUsQc1VxTEsIU2pBDihYtMCQ== e=found last=11 s=14 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA2xsG709fe6bm0YpBA4zFyLSPnFCDGv3gKLkwXZiZrK0= priv=MC4CAQAwBQYDK2VwBCIEIOhf6ZkMh9muvv0af/JgYcjjh+K6STn5/lbKIEspf62W msg=d4yVHg3rokgAPMagYLoGPQHlfzDB8fmKw9+CAyWBUaQTapJhUsg2eGFLsyd9e5L3723nbKIN6l6YhrMCU/si/A== sig=W+GWFQQcBX/JC0FvpCPViBD78ZszJMijxRKcXtRnpViCdP39olXgiccICN3Og/ahoUmKTklL0Xni+0287i4wCw== e=found last=11 s=15 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAB7jTjiu6AluKWhPcbMJFxoAi24wtHKNfMU9C1PniXSM= priv=MC4CAQAwBQYDK2VwBCIEIO0ZoqvZg5pH2i2txjGUfOVOLZhWbRTaS/HkjFhhXMpp msg=B1jtFojanqkiRmMRMBcHoXrq10HWTMQGucvBd5JOg9r18Sn7GQ62tH/365AZ9UcPR5L6SI45gkRyeRH0GtfG4A== sig=3QDiyWD2EzAYzHcu9oemchtN+nJHrqsfs+VUP4Gnx1CPEAAhV3Yrb73pk5uj5ZNDuL7N/wKGV/j+hsoj/FOaBw== e=found last=11 s=16 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAD9bVrh7QvLnO/2vh5Ssv1pMOKjVKCIOUeBZVxPANJ5A= priv=MC4CAQAwBQYDK2VwBCIEIDaRkc8G43z4YX46iKJWbtML0Gd1jeB5kaYHAhsV4boj msg=9Nm1ZwF9OHaO+6c8byxT7DA4WcWmRqNbsY6DcgwAqp6POSpz9GTijG37hrjxNUa8u+e514XeU6brDx2OuM3HFg== sig=AMm+NxaFB2ERAG+C5Js6YH0LuLfxdXaGjgUB4l4BypQuAIPFRWECPDUPiKFtkkLd8m22smwXWzbBeBQmHz4aCQ== e=found last=11 s=17 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAwPxVooOYPATcnM4+VVuRFH6F211N1I94pjL9FQ/qaVs= priv=MC4CAQAwBQYDK2VwBCIEIJgyFhII36qr5iVvqnS4v4dyUnhfsf1mZo/zv0XW3XY2 msg=q90lajF+u0nS3GSLKARwD9aM09QA28S/HLsAiLB7joHyAEJfFY6ys+McToGXMbHuAyKAUXhgY8J3pCKuJGH4xQ== sig=9VWMtuCUJnWwuyGKqfL5oVMc7aoGuhtQmRsMsI22UCInlv+CwozmbZ5f+JszP2oHVW2x+oACsuSkn/m3TAasBg== e=found last=11 s=18 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAtty5UzHE5OjNM0dV+Un73nWCEpEX9SXAOtdVvnKOano= priv=MC4CAQAwBQYDK2VwBCIEIOuJCXjVfdEpSxB40cmWOEHuN33Vs7XEgKnzXyVQuuus msg=fdEpSxB40cmWOEHuN33Vs7XEgKnzXyVQuuusU2CLaD8AYY+2HbObQnvSNxavay7NAVLA5wcjtlsRbhBfjdqeLw== sig=1QCLxLtalY+yUP0xWuMOhdpl73+Kbkb6OSUlLBhRudgl+EwWbeODq8sefed87M5/eU4bGXJZ1AQbYlJTUrxLBw== e=found last=11 s=19 in addShifted_NP", + "pub=MCowBQYDK2VwAyEABIzpHZ/q2FRYIVolgXSty0IIV78SbNgeixUAK4dHqYc= priv=MC4CAQAwBQYDK2VwBCIEIESfQP8ltDEK09sdBeuBdJCWCrZ6lzRnV+vJDeqj3zFX msg=r+Dl/d7mrsmd+1hMVv90ptjpWxd1bQQoITnm9bZHuvNaoTHpOAlhUU4wImOkWcWDeDm8Pgbw8swYJX7AxVwNpQ== sig=9iILIdx1HiCpfk9eOEhb7OA1CJzb7qhBfgc8PXX5H4H0x1ekMC+zgNDRxmbg28BiHq5Z5HWJxQ3fDhFZyscUAQ== e=found last=11 s=20 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA943BWCrqddCPqWxp4I8Mr6jC/QSvDw46c5LdHjiBuNM= priv=MC4CAQAwBQYDK2VwBCIEINSb9/HJM6D6V6RJ236xkdOc+UKQz5s+/2KqNXL/KeS/ msg=msRXIJwIyDJrD9orpYMn5gLAXT5jswp1DeryqWxnK9teF7Z9O+fH3Uu8WI3Um/fxyTOg+lekSdt+sZHTnPlCkA== sig=snNCOoUvGWavs3R2ZqFg6Mf9Whs3lBTPx6200KKCReRpuM9vKu9q5U6dt0bhSGdr/K+gPmIwQYAya1OsHcbACQ== e=found last=11 s=21 in addShifted_NP", + "pub=MCowBQYDK2VwAyEArvDvmY+Xw9YQcMFLZfkV/vhO4dx0V/y498nZZzw9EPQ= priv=MC4CAQAwBQYDK2VwBCIEII8C4L9oKpu19vBJefVwskXJhfV2AKEgo+cVJnSd9kCI msg=gdAv56cM6JMyIP2txs0MPQjS5qNtJ0E00Bc3ba7ya2qvZvl6kCEqb9JYCyXglwWFFuYsnfRHwUgsZb9B71w6iw== sig=2OUWoOnrcUHb6IKYJWC+/gKiMojX2JQ4n1RamPgYKDgbb2zdSxDE6vu2n9DBcvi6Rd9Ys//OSw5lYWAFnqSXBg== e=found last=11 s=22 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAjZ9fo188feZ3Ek39EpFAX6OC1rE7PRUBZIm2Eyj5qCM= priv=MC4CAQAwBQYDK2VwBCIEIPwXJLdsjJEJ3Q6q84asxlWJKFZylGNaeUpjndCVgEXf msg=eUpjndCVgEXf6n9kNyIydJRiGK16gGo0+8QJ8MzV3vKLzBBsbrBQTL7KIzrKXtoIlH4oro/dDaa97VU+iycDVA== sig=gURlNzID2Em5zuQpxi21CP4huCT97DJfKVJNtJKiYRidUJr0M5Xg2ffM0ySoeaHaw7yna+Bp0uyFIn3jg3idBg== e=found last=11 s=23 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAOff3r56/XDlzQpcmQXsAaGPUJXoTaMxWT4JB3QR6ApQ= priv=MC4CAQAwBQYDK2VwBCIEIAT1wftFaY+xSWt5vRqkwKReGc69fDuyaB4+EHlDEED7 msg=irBUnXl7Wt+f+6eAK8skK8L8jZne5GTTo2KTuPofbTdWhzy/aDVHCwT1wftFaY+xSWt5vRqkwKReGc69fDuyaA== sig=S7+EnEEp21tm3fGPMJ1j5RFX/lCLU5OEiCqfZWzb3TrJQqlPdoIsOQ9DX2xC+QuYbM0rcXmGb8/cjenqLs2bBA== e=found last=11 s=24 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAS8n5JxAl5aXpOc6IumYPgzaq+EGhl5gCjv5/SYteKxw= priv=MC4CAQAwBQYDK2VwBCIEIGacq7r9Dvz0HrcROukmNgn70AtSBbcFgMuNhTmKnBJY msg=TsW39+nqc7muxR8fEoh5da7fERd48uVnbCwLB00TagB5w/c7z17VwlPT02acq7r9Dvz0HrcROukmNgn70AtSBQ== sig=o5Bg/3GLULzpO0rEJVFA0pCBDvYt9qv19jDxq5kSG90nKpe2TZaXBbgsu73rXb4nxZGPYJb4cCKafprI1fC+Cg== e=found last=11 s=25 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA8AacbY1mAXw6ibYvCdT0i7rKvzyX8f7UXcUjXjcdYIw= priv=MC4CAQAwBQYDK2VwBCIEIHEQL9at1ZdynBSsKcUXHmvfuPD25T7Axsd74VFV4fqW msg=Xg/2qyCC/85dy0DK9JqfHHEQL9at1ZdynBSsKcUXHmvfuPD25T7Axsd74VFV4fqWZOKu+oF4v69YU80WKyj5Dg== sig=GFMcZKo9UlyW7lc8UPohXh6ER7YPaOILejFp+aunfuojT4mFwSavoe0GLYM0K541jL2KWfeHYOtOTTbRWCiwCg== e=found last=11 s=26 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAX1TNuehcLRMwcmoD52UpA+7dO4dM9ip4BO6ukXMbJxg= priv=MC4CAQAwBQYDK2VwBCIEIK5wAdf7UrMleZOEcaesrsQpd+LL+YjBSVolCkHoACi8 msg=TkSuKdge6nb2Ehjk5q5wAdf7UrMleZOEcaesrsQpd+LL+YjBSVolCkHoACi8t/KfS7UqhywLQLaJ93aWNsmLig== sig=LW9CVbobw19sk7FCapc+KVxDDb3800c2YqDkddE1lVpYsW0lcv4DxtpjsSBOnVwQ6DKuyYUxYk10Lh15SoSdCw== e=found last=11 s=27 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAHE4LmYF4PNv4lxODWJuxi0A0j6Pj8PSwmz+Y9ZtPdDc= priv=MC4CAQAwBQYDK2VwBCIEIC6uLj4tMpwKL5fDGE7AcY2ooEwIs4LZpWBCJWoouWA6 msg=t5xHPUo1BHNEnxd6aMzS2oqWinNSh07fTC6uLj4tMpwKL5fDGE7AcY2ooEwIs4LZpWBCJWoouWA6rA/t+ob7EQ== sig=su0Mw63Dnu5GVTV8O4q/5Pa+d2aFe0z6PP/mMgHimh36YMwWGhEbQLjPbw3Cm4dW9i4Z2bZ+ogHXsPjSTcUMAA== e=found last=11 s=28 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA779LBUMedNNSCjX7XaLV/Md8xwycxhVbc+YNqJCcqXw= priv=MC4CAQAwBQYDK2VwBCIEIOW/k5MyjvrrfTAoSRVTjhp9URY1kQDUUJReEy/sHPPO msg=ANRQlF4TL+wc887mZDCtz3hcxVDaP9pMrI7H6toaFmlQUJQSz3xcyo5V6lYaGOPmtHtBPpY2ZwI5aLtIcj62rw== sig=4hkPA+RDygUJoJGkvdHSqx4UTAP3o3bxEEInC318NIzM6HDvhiAWGBtRSiuMmQ+O8AOwOO+F9XIENUrc0VeAAA== e=found last=11 s=29 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAgMnMT/vNMyNUnUKj5xdwUp+/m1cVN4KWKM3A/5HU16Q= priv=MC4CAQAwBQYDK2VwBCIEIFdLUd2yZoLmyA2/dDyQlwySeWeZ//PW0bw72XNqoz/U msg=9ZdUu4BL6c+GvVIpp1aDN/Sqj4cKJqhOmz4sxPPj9ZySNTtGuHHLHlNM5U1B/lZDvYq9fI72zndmFITt7q6uwQ== sig=J51qu/skXQLXLwPlCs6ewjUBX4SyDzMIjwJ0i/SQKUSD4FZbtF7oHsgB1edbaXFZcW5TWONwVVPdiRDW/xBZBQ== e=found last=11 s=30 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA3guKyasUs1kozD8zvM0VirHC/VvewiVDnd/LiAy4JaM= priv=MC4CAQAwBQYDK2VwBCIEIF4cs/YxaRQLBsJDD6R0kFwhYSm/USQU7DiBzeSSUTgQ msg=Sn84dQ7/d9AFVW7Ti2rvhhyMMp6j4AEg/Qvz7eBJBAkDMTEJl2ZZOpqRGq8rJT5uZlqH2qkMTqN+99AFNuOtkQ== sig=U3/i6yeIoSfTWUBiowAZKvdm+EpgYHuAcUGKd1yacBcp2XlVcRfrhqW9SvV7ajOzfMJ3pqSuNisQY8jz7LoZCw== e=found last=11 s=31 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA1EQS/jv1XrsTnfSmdX8gfigRaWC1ijFu58tWErTW65c= priv=MC4CAQAwBQYDK2VwBCIEIJCV35SkiqOXeuk5neoQqoaJe9vRx3CyCyHsMRTOZ6uT msg=xyOc2VeC9hIbFA5PyRLA+8EpkFeampswlQztLvvhYvFXmoKbyXzh13x2fjboH7yeTecXVnYtFMPe/zIeqm2HcQ== sig=vBbWaI0YnV539dv6Rp9lI2uhTLODgkdfWfD+ygbRzTiJtjvzHLxyZqmpVWZCjOzk8dQKrCn85S5hm76AzXHnAw== e=found last=11 s=32 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAQm8JYWxnvtOOnXzqq59esG9rOsStg28BD41SN9cJ8wc= priv=MC4CAQAwBQYDK2VwBCIEIPXKA/f8wAoOvr+TrSrm2FQYl2ZHGWzhbLLeH2HH2w07 msg=bOFsst4fYcfbDTsy3+LB4QyGTWocVGLCcCf4MgOkNfs/Yn2IL+6W8yvBYyyl1l2bE3xS3YgwLu6Ro2Xyl5sMeQ== sig=JMxekAUV0af5UqMlzOrtZYw4sGOmQzdNDN+PYimZlassiRyj1OG73kn3QnPQ/llCXSPrSHMXbZNFVUoDxpCxBg== e=found last=11 s=33 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAmU/ljaiwso42qg+bTDFhnMeZFySmeJT5v/YEBkiRD78= priv=MC4CAQAwBQYDK2VwBCIEIPaZLvV/lQOMVNjxxSy3B7FoQxbcrY3/OpKBOBpW2Fe8 msg=oMnEI71JUEBpXB4uEFIkYmVr/Om1Rf4Qvwf3E1dd1DHYlGK/brEJ116MS/XuWqCkZ5n2mS71f5UDjFTY8cUstw== sig=CTe1opltJKHcucc3in4z2ECuTAAXsWGMCNZKm5XSYYZorSEStRaAyhB8q4Z9hSME/Xu12pI/mcbXKb+opkbiAg== e=found last=11 s=34 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAW83IcFI5yOFvbEWOEBVCCQj1yJ5vB9NIKJvx3GIkJmE= priv=MC4CAQAwBQYDK2VwBCIEICy/9Ak59X8S+T9ewx3tb+MW3C6IgxEBfHSIYjpLJBLx msg=LL/0CTn1fxL5P17DHe1v4xbcLoiDEQF8dIhiOkskEvHlU34MeNgRu0cpgfu/vkEdtXcXkhZiinDP9f36sbUf+w== sig=NVD/+BRF3SbF64JUoMdjkMfa9JAstToqnAFRjKFjaN21jU9HpJyOdU9XN+f+WLD9XM5R5pGN35zt/q45cYdHAA== e=found last=12 s=0 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAEm+9ZGyK3v1OBkrllTnZfa2yWaFEX3qi6r+J64kSvS0= priv=MC4CAQAwBQYDK2VwBCIEIN1pCRQZKbQ8xVDd66JoBvdnMTOo2oY8ArqjUKXI+x0w msg=3WkJFBkptDzFUN3romgG92cxM6jahjwCuqNQpcj7HTCM1uAUjADKqaPRumnYJBgxbrfTPf/E9YyHK3CvrEsB8w== sig=TmreIp/joleEZZ/opU4I6PtJRBnJXdRYSDJF0wUeupIH0GwhIrti8kwtG8d+rNcRwiA+ar3c1hm32bcVu7LRAw== e=found last=12 s=1 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAFJeeUQg6+lZPMn+zMjq36V467RsPidke9a78aRS1uu8= priv=MC4CAQAwBQYDK2VwBCIEIK1akVONTOBoIMqRQ63fgUYyj1o7DeNdsKrC/Lgcxbfm msg=rVqRU41M4GggypFDrd+BRjKPWjsN412wqsL8uBzFt+YE01vYgpe5xg9yFRAIOWrLrm3bSottKXGqj3P0gPMQ/A== sig=5xQ2b0uRRudIlO5LFq0sAbtHcndGyrPzdpKpPGJikm9IjtNLQ8K7UU+uukA2sowTw1Dpl9+080EBdzd1rKVGDQ== e=found last=12 s=2 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAOSK27uFAUHEz+iej3U7ise+To+dgXlZj7qdGIc0pBk8= priv=MC4CAQAwBQYDK2VwBCIEIFsjV9xhZODpsNePXOBpgpvJIfbymUV3BmP42IJrE8sF msg=WyNX3GFk4Omw149c4GmCm8kh9vKZRXcGY/jYgmsTywVU152GWVKE7CnCs0MRGBqvgIMkt48An0F1EdfEYlQUKA== sig=J8gHAPaOT1C1szZVLg8ZyHDVnmBgiov461c12M4AadegzaJNW1BzfzKRiHh5zKTUkbKoseb9fL1DDMdI2VyfAA== e=found last=12 s=3 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAFTSYYcPJ9QmYXPbA7v6C6hhnHpqDL/xUzYUX4DnIvIA= priv=MC4CAQAwBQYDK2VwBCIEIJ7nDv0NCDAiv9NyFJSIqxvDmP5lncPm+lbmgPF5Wdaj msg=nucO/Q0IMCK/03IUlIirG8OY/mWdw+b6VuaA8XlZ1qOHmhVULN1J+hL7AHJGAmNP2ZLk+XrHZb9Hp12Fgs3TFQ== sig=csuWC+zoLp8FvnYDf/8xq4bWUmGYn+SGMStgYBgAFrOasBNptsPpaN+x0BcDBnJjNz5MSO83XkSAQOCXvGkhBQ== e=found last=12 s=4 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAtivgcUIUUJhkhbDl1vFfz7Mwp+HbetVfxSeuGZr6rus= priv=MC4CAQAwBQYDK2VwBCIEIDg7N0fOrlK2drBjkm005gAM+awo73mzXp40X5CZvk0c msg=ODs3R86uUrZ2sGOSbTTmAAz5rCjvebNenjRfkJm+TRwi69iX71pfV9gLVCh0f+nZRIsLCbyUWGuP2ifKiwtX3A== sig=uf2UKrhJryRYbIXF1aEyxyHUKw9nG1fU+K50rNudXNKPftgH+pS0u+IO74TPS7Z1NZMRa17G3JbwLuGj0aPTBw== e=found last=12 s=5 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAmzojeuftrTUqKbXSsvym3Av9JMkY0KtljAKjwNfQ0BU= priv=MC4CAQAwBQYDK2VwBCIEIPkUAa8PUdZ224AYbJqmvjbW8+sqWcCplJxNlNpK91ul msg=+RQBrw9R1nbbgBhsmqa+Ntbz6ypZwKmUnE2U2kr3W6W3mDs8Lkp+C+deHO2msPKMarqW+gDL0C0nLAzClVARRQ== sig=wwtxSI4FQ6Q8t6hvv1Puws91thvXs40WnBvyTq4/9MZla0l5dMiHUc12akkBZpZuPAMMTQzfjjEwp03eqqp/AA== e=found last=12 s=6 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAequiZMG1y6AaLfMFdLm4Wbf4AIJv49lRhxdoRq4cGGc= priv=MC4CAQAwBQYDK2VwBCIEIGtSt5c58QbHsuU6GzR1s68bJLWxeArMajBfmMnv0fE1 msg=a1K3lznxBsey5TobNHWzrxsktbF4CsxqMF+Yye/R8TXvQQ0N4euyI2e2aXObt3x38ZNMgqX2qq5KoI0KmOdtQw== sig=qlK7CB0SBHNzEyUnrQMQcRkUGBGk9E/lBb/oqD9UF4xf+FLyFrMQIqzrWe0X7zM+q3ctjba1n57OHCQmgqQuCg== e=found last=12 s=7 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA/ULn6wzVVVQq6kGbfA0+E6TuBtDbS63UeWDmPLZc0hA= priv=MC4CAQAwBQYDK2VwBCIEIP/1OwI1xl+dz4QwU0I97vMjjXmoeVnIEJDNH1eznu+9 msg=//U7AjXGX53PhDBTQj3u8yONeah5WcgQkM0fV7Oe770O0j/ZDrFplGEMqnOXJldC+kfBoZAVt1joyh6YHvnvkw== sig=FfbMX4SEZM9ydqCtMPJwoeKjW+AaET+BkkJ0m0J9Piv+Oad9Pcjw8DnsU4zShVN/ZVuvu6rrPavbToSSMVODCg== e=found last=12 s=8 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAmhP6v7V5ugQBoAtgf4d20a5KBD8VyQhL/CL+hGd2vdU= priv=MC4CAQAwBQYDK2VwBCIEIBgyzg9CuNIZQm7+1IV4iL9pSK1sinOwyDIJ0k5UNS/0 msg=Ms4PQrjSGUJu/tSFeIi/aUitbIpzsMgyCdJOVDUv9Fj+z+hVCe9D69Ptn3pJqux78REOUb5xzgpIbt2tOFKF3Q== sig=UlGDokcJHqpd6cEUx7akEsYUXF5/rLz25e5MhR/t5SRLv7ufFkFPyGG6r94RlPvtgeG6xMtpW2rBioGMMOFoDA== e=found last=12 s=9 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAepAtZIq+a6CM+1vDB51EVo8EwtoDmWXdgFWq3qigo60= priv=MC4CAQAwBQYDK2VwBCIEIMwtOfx1KBQfSItOIP+zlIClskqD3BIIBCLUWDiWMmMk msg=FB9Ii04g/7OUgKWySoPcEggEItRYOJYyYyTw15PeuxBl8wt7V+S5Z4vbfjsIF8nS4MHqWbYVHNewk5i6gMvaTg== sig=MZpuu8Iredwb9MhlYcABX5K3rTsorsYaEywclDfKmSFEWDiTev8jYnvz2bAmKOoRacCUHHB0zDRvt8DeM39tBg== e=found last=12 s=10 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA69Ilg5U3k9/aNFsWzWUyePGvlJKy3YQo7j0OziyLmsA= priv=MC4CAQAwBQYDK2VwBCIEIDA8TW4d3UT0SHVEkpIuQJ26Ypq9czE5V2dPosi9n3rh msg=RPRIdUSSki5Anbpimr1zMTlXZ0+iyL2feuGJlvvx1ZOft2R1NsIgUyY0d7e23xRkip8eKv2C2S1fbcVODaKUJQ== sig=0YoG2ZEEIrzSJsKxx0UetO2rZnL8TtiSRbJivGfqksdhusGOrks6cHvQuvMB0gixdydBzUDowwqXm+vB/qtSAQ== e=found last=12 s=11 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAJst4paVQsxtSI1xhRPvNW7gg8B6aAGwmIrl3tqpv1jA= priv=MC4CAQAwBQYDK2VwBCIEIMEFKNc+VI4o9kJ919b7xnmRoQffnODUS3A9HlGuFsdC msg=wQUo1z5Ujij2Qn3X1vvGeZGhB9+c4NRLcD0eUa4Wx0KC9oAgrfoBHeYnjS8cJxdOhZRZqPAeEG/BxX2RgfJWwA== sig=TTTycy9qze/aY5Vwx93WEYClLWYLnFL4TncJ937fVVILRwI+2V8yBS01LYlwj0ID8lDd+HxDTvhOId5NcnU1AA== e=found last=12 s=12 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAo9fwcEHKuH11H/JsQDk11kQVxtot2R4rxMTF19TUabA= priv=MC4CAQAwBQYDK2VwBCIEIOloRnMarNksIRe7EJnvv3pkg/yxneqP9nG+NwU/KWx/ msg=X5OdrbYcf6fFvEsdY35n92oy7ygmxXJF3axPP3GHlKKLqlpUlJ+Ah68pKkFHf2pbupCSCdpxPUQxBHJEbkAYkA== sig=98LPk1Qe3lcnNlwXX+DiKDK+d+PDR9TBFf3n1f+f+W7YVsRe/NlYSj2VHzgXS9gqygXpk6q88HiWKyDeO1/jBQ== e=found last=12 s=13 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAZPbYTPjv7DY4oZGhMDQKETWh3yPc+HeTl5eZFwTI8rY= priv=MC4CAQAwBQYDK2VwBCIEIDAZ7t0fFxVb30Qn/HhzzFdQxOA8f5NGWpGLXfe9cQjp msg=QLKbwsAYAJjAPnVDhgZgVlGKAOTm5v/5+ZYwy8hhclFbAfbpdClikuw1/DL9R9EPcuPKlPtQvNYoDD7MGqVI6A== sig=CozqDl5GV7dD88twWjB/0bgvuPM5wWI3a4HQoOwyR33NLisM1XdVnrYiIXP2s4Qc/vdTnVsFh6/CcLZAsmxHDw== e=found last=12 s=14 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA/Kck1CUJbr1/3T5cr7kLrdcBMkk+FPEvYBFuIF1SHqo= priv=MC4CAQAwBQYDK2VwBCIEINHyisn61/t+tWBse5UEP/xNO2QcvhCKZ9kku7djemZH msg=e5UEP/xNO2QcvhCKZ9kku7djemZHaEYu1RyXEdSQ6ttS7KeBqUv5c+K4p8NtN4xOMmShW8t+6jbcaIsEYndzYA== sig=5H3GweaUrPFECqwsKJCkH47Y0/WGRzlJM4I/MLpdn0lV32j37NYEnMq32+P+bG16vJjCSfp2/ktvNRz6rgKxAQ== e=found last=12 s=15 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA1dxOtQWuKls4NylCfsLcgvtLSynhui7Awz882Eqhmbg= priv=MC4CAQAwBQYDK2VwBCIEIBDbu4zBmrY++EJ2DhcMk+6ypPfT4BTBamJnQs7ysqZS msg=mrY++EJ2DhcMk+6ypPfT4BTBamJnQs7ysqZS1THQPXP/8CYJqKCaiQtyeKub7mxOO39C0aLD3YG1BcILR5WESg== sig=8Kh9qxOfD/gDqYZwHI572L/9ofvdPnwV6n1xulNhuqYCDYMPuy3GvuA9b6RXKOBlYbBqxmqfwwC7RodoY+q2AQ== e=found last=12 s=16 in addShifted_NP", + "pub=MCowBQYDK2VwAyEATJMDnSuY3FTuoIs54vbRLSgqd5rnd007B7bc+K6sJcU= priv=MC4CAQAwBQYDK2VwBCIEIAD2g7JPRKF3+zDLSZn75cGesg7l5for7yVOCS6y3/tx msg=5eX6K+8lTgkust/7cYKUxa6mcvt+dRmCOVwsP4Cn09E8QbE5TCH57TN2kcAkWvUIMbGHdtb32qToyObyIfTuSQ== sig=R/rkvbOp+Ce4e3fr224ir98dupq6jQLFowMv1xMCbLvz+r6QDcNRw7Cxet+7JQC8co/P5qhBUwUyZiNl8qX2BA== e=found last=12 s=17 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAHGMP3MXWwAVS/kaf79qjrTKpe2hVwpUtkuSRfKUTxp8= priv=MC4CAQAwBQYDK2VwBCIEIE41vi4rwsZ7xnn59DSpySOLBJF/0MNKGniVzThv0Hbs msg=p6ifOZ1/BNOnjoErAcPgQaZTuxaqvA/gZmcGrcu+jYqrlCMapCITN3ToX7OpqxPr53Fk0VSxQWgACEegc0hSCw== sig=boTwhqxV08H/7Bi3c2QfPmGC4b8bXE9URd8E5Okqo0fdjPfJN7qPqwxTjQTLqRQUZXfJnD6tb9/ejsr3gKIyAQ== e=found last=12 s=18 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAQtkg0iGRNyPYVE2/sY3S6efT3ZXB6RhbBviGtS6GnyA= priv=MC4CAQAwBQYDK2VwBCIEIJMux46hEtVkqt243pAFevumK7wxtyYJ8zYRj/oOAlNz msg=1WSq3bjekAV6+6YrvDG3JgnzNhGP+g4CU3Oq4tHjrMgeAIsHWXciHLrIPi6UKjlX/1dXS3ydzoTfbP/ZeRGbfA== sig=lydECVEyiqE/w8JoFnxQzDS7Xt1eHQT4u9fTCMDRcXG8U42b2E3Yq5OFACmQKn/oU59N7jrf71tHSjqdv9NyAw== e=found last=12 s=19 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA/OmFLvu0O0a2ON8O4TS40VGn0vJZSW42Gg2lm2Erly0= priv=MC4CAQAwBQYDK2VwBCIEIMg/+wMPwvQ0/+qTKt1AqcoFid/0yAuvQ9AQrn92J+Vi msg=Pi9r1cHjxVXVFs7EShcESjWNjRHFTfGYV9mBnCK2GjV2EETY4j40mqxrrj3VX3raJ8ClLPBFJCGX7JE4QpENig== sig=bxO56ImQg+BRwxkUHGaP9HliKV1DCBOljlZQD7srPCxY37mDVsmJoCzOxadANNjnaw3XgWnH4Uycabxv8El/Cg== e=found last=12 s=20 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAIzAZNck1AFc1c4RErSpah+vayo3L+hscNcjO+HhEzWE= priv=MC4CAQAwBQYDK2VwBCIEIOLO6dcp9C8jwKOQ7tbZx57AyuuJZ3T0zF0igVQToX2K msg=ajkRb03guHR56eLO6dcp9C8jwKOQ7tbZx57AyuuJZ3T0zF0igVQToX2KJ+a9at5Zh/Ju7bKqyzl1VsHnZpre6g== sig=eMYCzL1cHPGkilCJUZl4mLuPbUYEBzeMIQcILs63O+Wg6rmmZmaXNVReCBjEPyE/62PKiTro+5+jq05UBRQcCw== e=found last=12 s=21 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAPOnmSUAOJw3LEsxnAbTvJ1Jda3NKn2IzfA/ERwhA6eE= priv=MC4CAQAwBQYDK2VwBCIEIMONbT7N14FeoYPtftKu2kVubr0y0dr/s9bDndTCXjR7 msg=fYmjOCcg+1Z88UphGoc/lgy6r4Ve/WKNXdqjXSy8viUSLVXQR6EB1oZ5cSwU1NUufpYEjb83s0xIzQAgU80Erw== sig=tDi8YGJp2Hhzh8iGNp5ydO+wLyIxRevqHBhizRPHjEhgjLuHmBBZPVBodtCkCGRxZX6LEqcWWL0jLTEIHXTACQ== e=found last=12 s=22 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAfKd4tnhN6rsfQxQZiDLNIIN5GlVWVwHjNY4kAt6S4fo= priv=MC4CAQAwBQYDK2VwBCIEIOcJBImbALp3mbS9SanBcc6l7kaUV5P58ZDFWMco/jfV msg=m+oFP6Xtbx2WmuvkkbCtE8P8kUOOw1+cKN8UGI44C6hW2VJA+b8icAq4rQlu5wkEiZsAuneZtL1JqcFxzqXuRg== sig=T0ufCo9+um3cjh732hy/kAzWCxpXsJSwG1w5ZbC4cVP4ZygxlRWecxA/5WsMVwW3qMbYjU7yF9Gg8bOdyhTVDQ== e=found last=12 s=23 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAvUYdF8RPPcFhFqquCn29vCjVFdvlNJ57DmxsQX692rI= priv=MC4CAQAwBQYDK2VwBCIEIFWmvj6WfNlrspGPgOVyO6FdS7hSki5D/S38xvGZRUSM msg=ri0YKU60+V60OpnFLMlY8dUsE8qGmxkeirNPGtnVqNWLp2gNFHIjzwWq3QkpAOVAA7lwR85HvnDtpYjc1hTFoA== sig=A0jtHx1jXDMApfw8i30L1GmI5dmjNjhYz8uGZVw7LHO6ocPitho0l8a0ogFkPmGm0Fh/xSdYPEcDn+g/vZBhCQ== e=found last=12 s=24 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA7n6N0aLdB/G6ul/WCLDBlIfxmOixL235mJoyaDfBONQ= priv=MC4CAQAwBQYDK2VwBCIEILbXQExs2T1ZP+KQt2fHapAMZNewXwhHtFmpQuDtm2ne msg=YMszv0bGihq210BMbNk9WT/ikLdnx2qQDGTXsF8IR7RZqULg7Ztp3hn1csqGxNciPHHKT0aqzvnJeoz1MaHu/w== sig=SkQ1zvLWEct2dHYH3yAFwSOROOdrX4ycY4eEOoH6TY+9sAO374/dvj0RdxghlGArYmdH9wrIrkDJ9NsE7UIYDw== e=found last=12 s=25 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAlpjggGfj+IvKfrHJVT4sr8jHfMKeAzOsKugzlSUg2hQ= priv=MC4CAQAwBQYDK2VwBCIEIAASQWVl9/QdtNLQdNNkmHCsb6y11nzoD0/h6RDcYd+A msg=mTs4+1HFdIJZj3zDRFicO5M3XRJzNT876agDrvkAMabJS0LQbAASQWVl9/QdtNLQdNNkmHCsb6y11nzoD0/h6Q== sig=+GUcXpmgIMXjHukGMMQO25H6AmGlxygHQw++YmPsUIpbTzYZ78X3lNSrUSp1cSVaC6AdXpzOg4EeVGsWNQv6CA== e=found last=12 s=26 in addShifted_NP", + "pub=MCowBQYDK2VwAyEASlyElqW7pbtb/30iG639z99G/kTt2xZ05jreOMI1vME= priv=MC4CAQAwBQYDK2VwBCIEIAbY9YnfF0JC+Oo8+qCIC35kK5FG7AdPZQ75MdRx5c+z msg=IkI1IekmAnndmThaZ+ySER6H+Hzdn9eS+dUIE/tJGjFDKpZfZxKK/5eEkEXW7yBJmp+UScrRb0va+SHbBcXgsQ== sig=JF2QMjpcTnMz8UPQ7cJbNbNsiQb/e+0ZzQYZm/9ZOfXxPxLoifQz2cYoXOFQKeJnVwnMeWpmBMnW8OOrC5R5AQ== e=found last=12 s=27 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAoG1e1et824NdcyVNIYzoZKkyFzRREizJ1EcWS7Y9XEw= priv=MC4CAQAwBQYDK2VwBCIEILOYDXNWuaws5z72uuCq+cMUvDIEQQ/7v6DNPcLth4xc msg=APsJZgnIYOF5hhlwMBMzfp05MkyUM9sAvdrdgZWzmA1zVrmsLOc+9rrgqvnDFLwyBEEP+7+gzT3C7YeMXDW/0w== sig=2MRqHwLn1U58A7uICCcAG3Oqp4KschHhCGQ2MKTENgIV7vXCQUwdHaxTsZtPnBEbg7wXXASFepkyF7e+bqUWBA== e=found last=12 s=28 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAuyNaLKSQcDYRFUSfOmkdM8LrXpbZTBweTftg/AJjlhs= priv=MC4CAQAwBQYDK2VwBCIEIBH0Jr7nVxxvqERti3jHUuYIGqAZ1rpjqQL7rP/uX8bi msg=vpTYKheGk+qz8aaiSn+RsZYM0cAsuqtiEjP+Y17niYlh4d1QEfQmvudXHG+oRG2LeMdS5ggaoBnWumOpAvus/w== sig=3LDCKVlRmNGpKuvH1Fx2RzbvHhYKFwNrLkNZIOiXozPqzZzuiQQIm2A9gmdynniH5PRR/rVM3zANySf6AGtLCA== e=found last=12 s=29 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAGieV9F7tI0EbSSdPYENA0m1Ev5ARTu0eRYGqdpln0Pk= priv=MC4CAQAwBQYDK2VwBCIEIJVIgzzDEbosyqseFzZ7QJFxjQiUMe7qgLcgTV3dCma+ msg=cY0IlDHu6oC3IE1d3QpmvnDQL8muUBxj3XSOll+0tsWRbbtvZ5IIKXR3in7CNzdZJWrpnEzZ0QyOb1bPZWJIsw== sig=FXdlfVNjpAJbLBuJmpaWbLUfgpRS9Fvo4V5/chb7JNXIySGcrDYguF7WiMc6Zjh42IAy95Ho1IQY2up8fv+oBA== e=found last=12 s=30 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAEb5rFpjJbMqC7ARi3LG2WE0inazxeULil6RuWr8zilY= priv=MC4CAQAwBQYDK2VwBCIEIPbCxtrfJJmQfskKZTLuE51/GTWKONfusAoTkyg6zioB msg=TcYRfGbWk9X3iCuR8w2Up8rLfUyMYEj2wsba3ySZkH7JCmUy7hOdfxk1ijjX7rAKE5MoOs4qAd6NHwPVwqpwDw== sig=fJ30iTh92YlAKdkdFKjoNfYiNcxj4hHg24zra04P/dQI1Ddjd7dyWfcZ9xDX+Z07A3DHgJQtzEDGvVMfbJWPDw== e=found last=12 s=31 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAyRBlz467LY6UINeA2Dtofbj7W++8xhuhoLtX0NtyriQ= priv=MC4CAQAwBQYDK2VwBCIEIGaX7x4PDTZS8tAzllGR3KSHccJhxtzjCFgrviQvTbKt msg=dUU2xq82I/cXXRbNegr8Gwb9vOgU06Mn50oYB040xBcA5WaX7x4PDTZS8tAzllGR3KSHccJhxtzjCFgrviQvTQ== sig=uF+xokfQPW2EeKqVt6xs9K1xa51HwCjlOGPFv9Jk8Qh9mO2RBuaOSSN+SwWrr3eVOyYMOop4EIZnlfyXtt5HCQ== e=found last=12 s=32 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAcI757lYVXr3vD+c6uVDQtYUMxAeJzbK8ZEYjznz7XGk= priv=MC4CAQAwBQYDK2VwBCIEIM0O33PpBppcHdqMKKi9IHyGPmpMp9dc3VDPBs7CESjq msg=KOoMYUIo+R/Qj1n/J9oCxL54Zgtu+3gMg6ga4vSeeNraFXWJDwQT0yiOsEr0R/mIfUjoYu0Nm6OfOr+FMgz1YA== sig=PD4btTeGE9rO/48lTQ3ajKOvP6zCKiGLVT9nnYRaOC9yXNUNlXPtZY1fFLCyPOcSSD5xrTOx0Bckx7NQ9TpqAg== e=found last=12 s=33 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAPJjaIfpDLOspifabH6D2aDwg7TpH25/VzHGSbtVvDSU= priv=MC4CAQAwBQYDK2VwBCIEIOnr4YF59sc/nZrkhBQB4Am4ENC2H8bpDDlsDeYja+KV msg=iyW6xe/p6+GBefbHP52a5IQUAeAJuBDQth/G6Qw5bA3mI2vilQmDn0qF2CY8/g6QkzVxXu+f/vfastRhJjrYng== sig=qLhDBZ6PhheR36GoZg+yDljuvMg3SzJRfEiv3qo9hzuCPStyKVkVx2iz/e56o7r4c5NmN36z9KrSmf0RzsddBw== e=found last=12 s=34 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA0aF0QLsxlvFFASEPI+6gV3SmPkkr/iZmxmBrNXZCkz8= priv=MC4CAQAwBQYDK2VwBCIEIONNP2HD9Ou4XI/Bnrspd0k6vfLflkWQG7b1gJHMEW1A msg=vw1PPX5U0/JkTyWUUZfxfVs2vW1pObKc+gpbHSozrb9KH2vnc5PmNYl6tkT7YVudp9e/VMEtD5192IlPZgH4GA== sig=t1jj+Lz1pMmtKZq6QLWUQrT+7qJKmoxLAmee0GfViTq6rzv8hKW4aUJu6391DDnEdglctvIm7brb26+tu+yDCw== e=found last=12 s=35 in addShifted_NP", + "pub=MCowBQYDK2VwAyEADpZMbzPavsucERbuRFdHH3+6JBMz2XTTZ2jIesLl4cI= priv=MC4CAQAwBQYDK2VwBCIEILWt5ixReJZYe4f2XstytJPmTR8y8ZrRZHcZHPUm0NJH msg=XI/HQWkU+bdJA0/tpg6XhEtMsBW4pxfN3GsUn3lUM3rUkCwduAWm90l4uZBFl5c+RsR81Ca3yiaeStoBvo3utQ== sig=C0bitsFOyYAha0A6Vkom/DsQyxZ51abNay9B09xnSAzZncpDbPRmMvDk5cjPiuiUOfcB0u/ZpGoeTbxxxoifCg== e=found last=12 s=38 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAkmn6//0jrnVpn8ogZoIbMOsAeDnZXMA236IoPAeT4b8= priv=MC4CAQAwBQYDK2VwBCIEIMsq116JYX61g8C8OB9OCZasVnThds7p2iZhKPZzfhDQ msg=pvJekBSTmWn5BduyVE2IZDrSMnyyXok3uDq92niROMJMiKl05dmMlCzgoZZ4Xd/SBXx4f8mowqjwMwyxrKAByQ== sig=sbidO+fLkeEQctgZkgNqEvGBxxN+KP/7BuD+AmXFplixpmkgmu+bmqkICf+uhoZxIPixFq4WYaO8DVMyd0wpCw== e=found last=12 s=39 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAG64VYGT6s9NGenUTjjYPHU195IyeihSrCuERKNoRnAI= priv=MC4CAQAwBQYDK2VwBCIEICe71DJWcXWoOp+bfiEuHFUMqUo3UcZGjkNflThdz81g msg=J7vUMlZxdag6n5t+IS4cVQypSjdRxkaOQ1+VOF3PzWAQxItjFNWhWkams4pqdq4L/r6iGvrX8XR7NVBn3xfPtQ== sig=eO2lLJs6Zwk+Qos80FbKQzgbRXL5ZenSyUKdr+iXAy7YBM1lrQhabg6l+ZYbsSSdwXT2ys5uMfCdrOAUMYz8Bw== e=found last=13 s=0 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAlhhN4dsZYSmQiYmbgc36PNa1osuDEmg3VmaOC/ekrHs= priv=MC4CAQAwBQYDK2VwBCIEIFzg66vWe96qbgRK5G0PeTofkgtIHbN9yJOinYNYbSLG msg=XODrq9Z73qpuBErkbQ95Oh+SC0gds33Ik6Kdg1htIsbbd0RKzWoS3OckzdQYSbWfqvHy7cQxYbfOl+j2+75A4Q== sig=pIR2HzA3Z9pVNoSAYKA5cxr1x05y92yJc0XlRPFnNUGLLA78RLP6H0/Yl7wyXIoM7xciCHF8BUJm7p+EjKWhDg== e=found last=13 s=1 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAFsiQ5P1JWvVonc68/C+8cySEt3gJ6R7b9WBqpFaNIws= priv=MC4CAQAwBQYDK2VwBCIEIKNHp5drcjffIf6d4Ya4mJl5i7b7LsoiKalOpSYD27OM msg=o0enl2tyN98h/p3hhriYmXmLtvsuyiIpqU6lJgPbs4xPVuNCKbQdG2uUpvhv5CM7kX9kW/A4CyI8+szm691dFA== sig=YSIJYOb1MXLDSLBitnSBJHyXLGjso+WHY2qGQtnzxEcaSrjoszlOsX7wDK41EqqxEh1QxEzzAERwFCoz9ZrCBg== e=found last=13 s=2 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA97gOtAmQSeK7ARsCH91Mq/7LfN+m2s3VtZ71xbtCzRI= priv=MC4CAQAwBQYDK2VwBCIEIPipiHDZXv+TKgIz5HMkPjoMnEbnCbxGT/jPZvbwomNa msg=+KmIcNle/5MqAjPkcyQ+OgycRucJvEZP+M9m9vCiY1pnPjeDEbX19ZhZpXnnkdVdmqtKw6C43hF6jXBeSrGMhg== sig=2nTzMWeWuMu9hdq4KJ6HCk+/ojosFi7ESqtmoM2ghKG5OXHkw0RGz58jeiSjsfqGXhP1fzH6ju2sLowN9VL2Bg== e=found last=13 s=3 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAgCymeYN0uEwxuIpSaupcY9+Zf7fERcPtL2FQ+EuZZsQ= priv=MC4CAQAwBQYDK2VwBCIEIGRa9bCJTLKrtUkTHsJZur9Z6YngbXsYMK0Oi4zb6hD+ msg=ZFr1sIlMsqu1SRMewlm6v1npieBtexgwrQ6LjNvqEP67P1jXrkb6C1EkC9wd+/mvH5Hmiz3T8Og5leSCJtPXdw== sig=cW1VLAeoaRH8s0zJlF0vQ9bZbo01fc7fOr4N0IrvzmD61dqmhp728hCHld5/6V0IBZ/asMsFse5P89cfjdX7Cg== e=found last=13 s=4 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAsvdPAxLAT8bEiLqTr0Yxy/21h7KV4VrLgbVe8darptE= priv=MC4CAQAwBQYDK2VwBCIEIP59ecmxOTf71CS7nc+ExobtRb9eeHYjGffMwhEXs2Ef msg=/n15ybE5N/vUJLudz4TGhu1Fv154diMZ98zCERezYR+Sifx0NKL3tLixYFWRjL3O10jtyhzYxiATbsyrqOnhPg== sig=v0Ys2hpGUV3Fh7QApNxavPoqC0TgItbKDprJb38VbNXFSQBXxq9CQ9sLiEELgEcG0o+0TFxeX+JEZdhCsTS2CQ== e=found last=13 s=5 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAdIABRVuoo1UQCYokC3CX8sANT6ws0RjFEz7sNirtKAU= priv=MC4CAQAwBQYDK2VwBCIEIEnDb80n3jNdAyd/AiCBZa2wc8t9U/AUFLO2nkeXB874 msg=ScNvzSfeM10DJ38CIIFlrbBzy31T8BQUs7aeR5cHzvgrFVgktZCh62C9iGPoSfCd7GGJoJh+MQzJPEUR6Gzr+g== sig=7TQcpPHVoKNDwKtCaXXnLBre8K9u6hbJDcUOA/HhUtnhldAwx2TO01EWHHNu/0VasqMD98WtHVXWGr5+ACx0AQ== e=found last=13 s=6 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAh8CPfDa9KaNy9LxLwLIakynEgNSwr4kFAYvrg+vRyo8= priv=MC4CAQAwBQYDK2VwBCIEIBpe5GIP4bFF00tL5et4rHhLFssxLj8ivJy2F+t4IF3i msg=Gl7kYg/hsUXTS0vl63iseEsWyzEuPyK8nLYX63ggXeL9aFLawzwKWsaoZy24FhEZ+xY/41NZdsr+5Mp0i7VdrA== sig=QjWXXiosKt8Q8bqgUe6q5mnp2NlVNCStQc/MYUHssNuNMrmEuqoreBx8tFBDlXkpAH/rWFmEPbZN8F/5ZTzeAA== e=found last=13 s=7 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA3/1d+ZjhAKuFdijcaryEfNNhjpYEqtbCQDeAwCfiug4= priv=MC4CAQAwBQYDK2VwBCIEIM19w9f/HbxiiqH+gZ4Xnpa47h7HxE4sBbwLqm2s+PEr msg=zX3D1/8dvGKKof6BnheelrjuHsfETiwFvAuqbaz48SsMOuWE7ZJJ0X36AOIGlcv+48QSGEvNFIcnXOZju4Edcw== sig=JzpFAcAWo6RGenAfpcKyLDyF/luaR6+x2I3wkIWY3/wzY0QQKq73STCTQ/rB4fYp14TLtJ9EToSZ9M0cFlDFCw== e=found last=13 s=8 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA+OUjgNQFXn5upYUIdJZwWRN6J2PkwiBGag9t7il8Zkw= priv=MC4CAQAwBQYDK2VwBCIEIBVwJm95j+PaBINhIh0pODbdHt81xtAwLoN4lo66zlyI msg=FXAmb3mP49oEg2EiHSk4Nt0e3zXG0DAug3iWjrrOXIiuGmv1+Px6ugIGJwzcwJ8QAOCthorNWmPIo34mZn8W8w== sig=8D+LS1dUKz3oC07wZv/M9TH4QmSmi/IwsPWW8F2I8Q/rjCnFe4DJuribZlsK7/Otqoe7B55nd3WHLV7hhU7TAw== e=found last=13 s=9 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAgIPQalfnDN8siJ/xF/40xZfWI8ITus3QYv5Hu5F89hs= priv=MC4CAQAwBQYDK2VwBCIEIMEwVk8jifyN9oUKrtJCLZwn37985MhpOQ5ceRDVD5EP msg=wTBWTyOJ/I32hQqu0kItnCffv3zkyGk5Dlx5ENUPkQ+tiqcgkT5Dzkxu0oortVlcuE81sli+sScNlQ9XxdRKRg== sig=F7UfmBGyYna63JP8anFuiltralSo/1LtBZVK0UsocxsniI3/M9ha+rpXvvDOZNsNQ9SERU9mjdpxpO+bUpBCCw== e=found last=13 s=10 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAIMWO2oYT+4d8dndcvx7VItYE3jq8sH67tXKyjKSuYJQ= priv=MC4CAQAwBQYDK2VwBCIEIP+ua6gsobhQVMAx8z99QGlPgnAZaq+65ZIR54MstXLi msg=/65rqCyhuFBUwDHzP31AaU+CcBlqr7rlkhHngyy1cuLBntgxtLSWIv9upeCHEp+ubJWzVlQzouwSod6JXZueFw== sig=dPyfIMCYvCpf6TxQ0IPkjT6zz2R3Q1Orfy66aVTOQ0SxEtqtwbJsqvNxBPgzaaCI88Bw+C4q4mWnIQWc+jLgCA== e=found last=13 s=11 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAAG6JI49VyxH55EHbPaSYO/hQ71fiQPd8tY/J/chSoYE= priv=MC4CAQAwBQYDK2VwBCIEIDS5SSOfeGkTkJLXMoKwMhkyZzeiVuTWlndHxoqLTO3h msg=NLlJI594aROQktcygrAyGTJnN6JW5NaWd0fGiotM7eGf+9O6A3v36QIAG6sCShhmmhIVKBRfamU+yuqnMfN4pA== sig=p3wKfXjQvx9+cz5pUa/huKeGnlMxyGrjyfQt0/w7RcVVSQAwsRW92wlUNBTgO0m8uHY+lWXjQmkyGl+zDQPjCg== e=found last=13 s=12 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAXYXLxRI5OE+1t/JndjW29EWlzs5HKCNSZb6u+AtRKto= priv=MC4CAQAwBQYDK2VwBCIEIJ3/2ikjdDdhU5MBQiNmFK2MiJ/vKbY500OQXmdCQ/OH msg=MXV2ry/9xnrlNu4zEfvCkHVKmqfqp3QZI66Ty9IktpkFNc3XwVqCpiC3CHW2puEXtr2S3iiKoLgl2GjB87ao3A== sig=WDs2IbSLd3o+SQWbMJaNVtcuX460Ar0comq62eAjZleDFRFUQmpdFufm+kIKz9qsvEjeYfV+BXlO9X180vbtBA== e=found last=13 s=13 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAGE+PjOmZNpcVIfYnWzt/0ViwqGTJhVeWMu0ya2XKK9M= priv=MC4CAQAwBQYDK2VwBCIEINxvwwkL5rWwoAI6426Su3Tzsqrr/ANPuxhZkh3kriOR msg=wuLwGI+qWSeMjtutH+olth+X44f3jiR94sX1hu/BepN05QkSbpMZy5hCcnXBN85VHgaXp/DrphwjRk2kT2vLUA== sig=1/9HCstHrQCF1bVP7kYfHPQXeBZcfOzIzMxtaZz3gEQmnEo7EanHwaNLx4npbIR4ZFyRcDVOtOV+yim7Mu5pDA== e=found last=13 s=14 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAf9n1Li5LZZbcWaTde5yNdlHb8WcUugboX/coNMVz2E4= priv=MC4CAQAwBQYDK2VwBCIEIBZMs/NQGtORzp11s5cRjI/RXl9sHRWDkcChB5e7yuLG msg=X2wdFYORwKEHl7vK4sa+ylqIK6HtOECV9UZSvAUJMjF6T2qTEwgzN/bAmbolMgou3V6AVnzWOagbBYAPALjqIQ== sig=TxzPRJoYt8iGwNiCI6KQTBHERHBEUrISMqdx5fHJTI7G7+3KhaSktOtk4WEI7zxGfH+NWmbGBa2lwxN0icqOAQ== e=found last=13 s=15 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAvKqMoL7VgmA5dWDZw189/4HRBCYvoiLYLuU3KeWY01o= priv=MC4CAQAwBQYDK2VwBCIEIAxCo/oQ0Yih58oBUtCgWmLMZDYdftmAt7x4b7dPuzcC msg=T7s3As7GTzTYcnHjC7fSra22lR7vls0jWX2FrTdJGmnFlVPKp6IfmfWoEUVUHHnOk+Eu3ELstp+y6LVsvWWoAg== sig=xXsUuN3RH20+Uqol/AVtGs28KoMNM7KQFJKTL0hIx38KqYyKUxV3kz43uFrmV4PcNuAGOU0DymwzTUAH7lv+BA== e=found last=13 s=16 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAelYJJyFx7IdoZs6z1g7CBCpHPruui4xwo2P0h8w4q+U= priv=MC4CAQAwBQYDK2VwBCIEIPUSjXiMV7ypdqen34XYZL3HJfmZQtrqbPnad9tqHjiR msg=V7ypdqen34XYZL3HJfmZQtrqbPnad9tqHjiRGivOzugCgMftLtcK9J091ANOQLKn2/2X7O4vAHFJ/oBZ5+WvCg== sig=zJnZpedFD6fiKciaKKoYjEpDw55JDv2MYD+l1J0Bty6D/7o/b6w9M2WDxOt+UoHWwgwrfxYz2Zpu0U24VTPPAQ== e=found last=13 s=17 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAgw1dL+jmUmbWzTu+hjKmsCyuIFdLFyvV9GMeCIKnZKc= priv=MC4CAQAwBQYDK2VwBCIEIDA7SvJbOrra7xFAfcKPAsJ2B2QpH8FVZklgdzteYNzZ msg=kBo/byfAHl5EKDkKPArZF7CuzeZIxAIPmrRK/0WPeQEgXUiharWnho753I/O6AJ3v+6Asc/ehV+rZqZK6dtpzQ== sig=eGuGh8b5yMliq2ZxzlVZ7fbf3MmQ0B4nLe7mnwC1wAYdwmg/EFy2fl10ZbpwiyawtivRV23OHe+uBUaUobzgAA== e=found last=13 s=18 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAtELrXeG+8yIDXQqT8gYKcGQ8nGgLZ6WUfLULbJfook8= priv=MC4CAQAwBQYDK2VwBCIEIIDxLx0NlcbF4i9+rGRqek5gQQ2akdmYRiYCaHFZkLV3 msg=HowidYDxLx0NlcbF4i9+rGRqek5gQQ2akdmYRiYCaHFZkLV3wqFawjue+g1Ucj9QbOcthxLgDL2O+OUzudrT8Q== sig=f3J6DB4OP5e7MYFGqmvJCFRsqB7X7cfTkpduhrQW4vKh6OsCT+EtCWx+0T7Wa3kyNoZa0arXZKOD8RXKwgWlCQ== e=found last=13 s=19 in addShifted_NP", + "pub=MCowBQYDK2VwAyEALbvXaM/R5Qszs43CaDIvxW6gTLjJipmYuR3ZI1ATxoo= priv=MC4CAQAwBQYDK2VwBCIEIKjGknu7GikB0t5vJ54I8m4Gt9TsKcHxTcgUmSYzz7Rf msg=e5UVsPuQpCw48QI1Sa/Lf3rlxG14xy1dsYaEejYnNYrIGmJYwg6CZ17I7mEe2dw1PXPjA9hF2kbFt1SvbWEEwg== sig=WBiGl68XXNcXSbNsM9QSNqrU7j7FAdiVHJ8zVb7U+s57q2EJDAwT1j+oFffmaT614THjNMptjxovf7e6m+S1AA== e=found last=13 s=20 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAw0hV/197yK/mSBkPwPVOajiSpEHayoiVdiBcXP0//hc= priv=MC4CAQAwBQYDK2VwBCIEIGpQaCKO3rzM+xcdmf3eQSnULylhi3AMvm6k4PqPGDEO msg=5kEjqQSMIvL16zwogjq03GAazRdjTuW0VDBBOKHQAuOIhmpQaCKO3rzM+xcdmf3eQSnULylhi3AMvm6k4PqPGA== sig=OBJpdrJdlHqSc0nmGFh8AzYhKIZKtho242HrYVPB9NxFydsig6qAj/6i6e+yxOYCPToeyGBJzFhtV5s1dVkEAg== e=found last=13 s=21 in addShifted_NP", + "pub=MCowBQYDK2VwAyEACOK/7lb0Zpwt/RSRH8/i9xI/nnNwL0mIenvddV9B5vA= priv=MC4CAQAwBQYDK2VwBCIEIIdJ3yFgW9Glm9OTJTcw1rypoXhLf5Omfb5kPbNW4SM0 msg=OmKlhwOSNoi36f/hDvfVnkHR/f9+lpNx1H85Q/58xKLFLb1Y7f58vxPN9f01sUbDj928O0lRomQ07UOHSd8hYA== sig=dCBBs5NdCwCW225/tgGbWWJYMoOmWduxV10Wel2SlY1uwpp7ySZz/PAUWYwlb8m2AT5eloY6l8o5Y5KjnaGkDg== e=found last=13 s=22 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA/O3ERGwF1QdI22iyEuFEI4rTbnynGD+eI5Sb8z2Op5g= priv=MC4CAQAwBQYDK2VwBCIEIFmc0dVevA71VwnjKcl9RQbh+/vaCoNHKurJSge0L6hq msg=4OPYnEzR4v9ULeqilGtaMBUmmytGeQi52KI8v3fpmSqdlA+wzK2dKWCMlLicmQOVCWNZnNHVXrwO9VcJ4ynJfQ== sig=6NBO4S248jZ6IHxjwX5gxPuZBCgaWZ2yaglYtA9ORvVReBN8agDEYPQ4baY0M2xY9Hr6AxiaKgRJnfGm4o0sAw== e=found last=13 s=23 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAbfgmWlzR8hJhtLucXm7Aa4fNG02hmvTQ1kXc5lx94XM= priv=MC4CAQAwBQYDK2VwBCIEIF+jF470RRp8/yn5JSP9T3hFX/CES9/yGMXjdJ33PEhS msg=P/8CBiylpO4FpRLlxmPFSOs/XFHtcbDuvS+yZux0PxnxY4j2iRARSc05f0VyOCtLWB/Day/+shEStYVdeb+QnA== sig=atxFL4cX698JSvqEsutaojBYbV/YY7dOnCXwt+zjiATqchsdviRHiO6Jgh7e0BuLptz5IvgqdYXd/mtdSPdLCQ== e=found last=13 s=24 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAGeNi5dOxYEGPTTTy7wabn83cgmMYlSgEOUTk4Q3N8T4= priv=MC4CAQAwBQYDK2VwBCIEIHuYQxkLhTwilCkA0SlIfhUGI8lGOrPBfjfH0vg77Er7 msg=WewkUaAkYsd8tAvJZ2e5sL7Bt+zucb1uRNiMktnljVYqzUiM/S5ZJuKqfYLIheMbg/0lKuI77Uy9FTXc2wlwzg== sig=xZxagOmPMVTgGfTRXXkgEP7UwXWaUtlFkqGvidmSpJ4O6jTKx1b7UZ4qsBEgVS/P9mVWUmVRutAo1FYpmwzRAg== e=found last=13 s=25 in addShifted_NP", + "pub=MCowBQYDK2VwAyEARs00IZjxLwFg0HfKBEC9E2qVNl425Fm2TRn84g2h8Gg= priv=MC4CAQAwBQYDK2VwBCIEIGr+2HjNcx/9A0wPKlkbYNF3GQXNvMO4TJsLsIfNj26n msg=1Bk+TKrcbjI8z8cf2vExTMRgEGxNZCqmzBsb0JnHKvs6690dVEsZRPUFSfODrMueHHg6F8fYXxQnubhN/CS5Fg== sig=Vqkdjo3nLmX1SX5a7Remo2IpUGj2gGghLsTNTHTUGcn2MlULWXdNQOnZL7E8100jgJk3tw0kR4gXJK/fAPZzAQ== e=found last=13 s=26 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAsPJq6G+NNb3QmK35iGLssZaz9nGDex3rJA5bDUKvbd0= priv=MC4CAQAwBQYDK2VwBCIEIIftC28enEVteoyBpv7I0Ok/lkS8mKrzF+qIKxiz47ie msg=U0m3i5weOB1op/8WAU3fPIrrcvWBswCrziHZiwtkZc7h4PwEk39BrBim9iMOSaQz5kZRqq2FdFFquaL/Iq9gtw== sig=GK2BAgWhJP2zGG7fROhV875MDp1kDb9P1f+LE9jTq6oLjGGdua6HUf2A91ezsZNr6LJBY9g92gQ2puzLYdp6Cg== e=found last=13 s=27 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAdQC+chlYOHlElYKovixji/6AvIM5ftwOUYDlQkkvRyE= priv=MC4CAQAwBQYDK2VwBCIEIJZ5oBTdbL9KJzsUtJnD9+9C2sZEp2r4FmNQI18TTS5R msg=lIKWLmYU/5UoajP4Pge/x5oA8Uty1LFeN+7jBgReo96s6x8Dpy46YlgS6IKvRiS40vNpEFL8W3A9eTt4Ao5WVA== sig=EihlZKkNNOSqWpM+NxU4lcULHXa3dhd4ODJ8slNawm0fzfGPjwzssdqBFQ5hZxjhnXWSqug2W5Y5zIFXjAjcCQ== e=found last=13 s=28 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAx1dhb+ZgWE9O08L66WeOuwo0oZrS5y5skiH+CJXeCD8= priv=MC4CAQAwBQYDK2VwBCIEIGHNhfdFIYrMmGadzZD8gb/IByGtd7/ZoHtgbnadVT8a msg=K+mvYc2F90UhisyYZp3NkPyBv8gHIa13v9mge2Budp1VPxpK2jBlpiygrs49bCBMn7acsIyhw+POmbaIWCNZGA== sig=DjKdQwGEy0LhEp0kmSz36WKnC/yM7Kr5uVpHG89yDug5XWK1ojomXeHSKulB6z081UFcr6fZLlExLoNTphOGDw== e=found last=13 s=29 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAgDofkq0/5UZIe7ZuGeUAevwMDP9rnemCmBPuDVz/Ze4= priv=MC4CAQAwBQYDK2VwBCIEIFLUzoYodONr4E9m/0YDjtiL0+Qe6XKksz/cLXKlUQoe msg=ViZvK1zby/g5NgXGJ5BsffUkz3BKCpvxUAA8LVLUzoYodONr4E9m/0YDjtiL0+Qe6XKksz/cLXKlUQoeE+l+SQ== sig=jeSuMXq6j7rmCXRrgSGoQkhokMME2Cfk4RQnocxoaJufYJ9th6vZeT+d1Jtyg8S4FY/jgjAoIICKQxjVfdxDDA== e=found last=13 s=30 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAKzRc+zT6RqQc5JpT6h86fryHv2+mZllEdrsnwQsUtIE= priv=MC4CAQAwBQYDK2VwBCIEIKm5UZRZXuN8EZXDwhsESptkGNZ8Hs7lh59p7eO6d6UB msg=BEqbZBjWfB7O5Yefae3junelAascYAIaue4TzLeyQYHvaUc9akhXpwL/0kMErGYWWJ2tJipXnJQzMHhaE6EHCg== sig=WwRz+nQ/SNUN1rjU7tt/AmfjnQRnRMNns1drxDGEbJcUBoIDHxJZxZaxvP5xBBpOzEqe+M+Ga7MRu3ePOMO9BA== e=found last=13 s=31 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAmZlleu/HD5HbPDf/cmpOLe0aiDY+3hksDgjeSgfvg6s= priv=MC4CAQAwBQYDK2VwBCIEIJXmL1p+KueyAWLyJ3DkXjAEyKps3I+SHBuuD4WwWhJZ msg=5sgIrM4cdQR4iHvCz/qerrKpcQZ8HiWS9YdOItHHHsdHt9ZH+QK6MLUVN7NgegGl/1MRVlPZ9oDvVzzcuZbnAQ== sig=v26b6Lj7k38MwRqchaT+Me5DGrUL4RpWq3PEbUDwePxGxCZmmpCk8mUXu+Bbf8Q3o9ic+Wb72noT1Q4VgnXdAA== e=found last=13 s=32 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAm+TQGrX9GHO4UnbOictk3C9r57tMuHii5sM2a8GMTbs= priv=MC4CAQAwBQYDK2VwBCIEICEN4iLrQutrk57jfvU4uGSQH5xk+JNJLuPh5Sbia2jq msg=O/chDeIi60Lra5Oe4371OLhkkB+cZPiTSS7j4eUm4mto6r2lFSBu53Y1+2VSExXmYZFFdiFMGew3a3jK+PuaIQ== sig=yhc26/4dO35PcDvYMugZcvgpM0TAaIRYBS0b+74w8hJg1+mbcle90jEJnQMnpSaj0vrR/PJLMC4NGFURzQEJAQ== e=found last=13 s=33 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAMoc0i4PsjIzyqVYllo1fXwq9faVjPUefA8dO7C7uvIE= priv=MC4CAQAwBQYDK2VwBCIEIBmIc/owUTm06JxF7vdKvNyIRWQmzbGGJICb5KPodlnw msg=mc1aJBZCEmE0muzPEu9DOeAsPuel2oR0p/Z74w3TIiZJDnyShbYZiHP6MFE5tOicRe73SrzciEVkJs2xhiSAmw== sig=6YQ0+PDqEbUD/tdOwb59+3M/gLgZu+jwkKzaPNA7tqvVks7lpO+YswQ5xIglHVrQaMUf7P9FUhIb/UOXZTu6Cw== e=found last=13 s=34 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA3XQkOCwf+RFkk5TZQ8lXjZ8LetYJsXbnjAR/G8MLiCg= priv=MC4CAQAwBQYDK2VwBCIEID/tKLfi6zsRa/XRzz2yrrFS1Kcm7EtaBioS2twKdcGl msg=OxFr9dHPPbKusVLUpybsS1oGKhLa3Ap1waXqQHcRquJ4NXYJs2CkDaDeUnKE8DOdL5kPKWIA6W3Zt+sDHwMoVA== sig=eMEJ5WY11ZFxocGWO8RWrB/dbDuNETQZu5FHo07gabwJaHPhpZAGlNHnKHsAf44JkN1lk40WWSQ7CvcBiOY9AA== e=found last=13 s=35 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAgnfTT9aJFS3dz0Cm8fly3o29BWt2TV8SX7k1LH/7NT8= priv=MC4CAQAwBQYDK2VwBCIEILEQKV3r/aoFgwbP+C1D4U0CGZBcZZgFLnqtGtbddyQk msg=oO+5nG+6/NdXYA+gmHUqV0rA9KqB/kW3lOUAo5TQCozTIQk2PKwN/XuJqgpFhbaafR2AaVHyX0A0NmqJSrEQKQ== sig=xS25TyZDfmXBWrlqhxsTD424IhOKHO8tB0emR8io1Y2Xim6+OAptyFzyzfgw5GSJKi7up5/fadBdVfgTCDqhBA== e=found last=13 s=36 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAalhMTR5GewKzwQp093RnjkT7XeC8P2IhnknFUf+iaiA= priv=MC4CAQAwBQYDK2VwBCIEIDRZqPVUjRhlEl/2BsQJzhw3ux1XiuWLq8iZoUgW+CRx msg=NFmo9VSNGGUSX/YGxAnOHDe7HVeK5YuryJmhSBb4JHGHXCMb9x//rVjJNiud2hmLU87E0n5Xj/MCSoZVtzDhGg== sig=cTAbOor6j22tvjPFSyhnqp7HcYFuIBGCN6w3xNwX0fsnFeff92J1Wp0QkhJJ5OcbuwKGU9rVVXUM+cHFqtVOCw== e=found last=14 s=0 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAjCVWw4bKywgqnomHshS1UdJ5eU5LsqWWsle5yGcJ4+w= priv=MC4CAQAwBQYDK2VwBCIEIBlGwMotRjviah8DTaCMHDMhaKpaOceFSR+QMoLsyDIV msg=GUbAyi1GO+JqHwNNoIwcMyFoqlo5x4VJH5AyguzIMhVErJyBmKqSDlK4Di+ObTwTKZbU+dFVFLylfBbUT3FdZw== sig=oS5/BDgfKqkpX7RZkfclOYwGW+vaW2bioYrAqBC3lUeOFj8Yx53DQgU+IuPMJFiem7/ykJzJgYYZVGZ1Wr8fDw== e=found last=14 s=1 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAnIP97EdvWheZX/nFOt1iIJAk/dWCU8ihy9IPGS1X8bs= priv=MC4CAQAwBQYDK2VwBCIEIFU+O4btlEJ7INidQ8izFw3Wx4HUL20mRCGMJUXK5QTC msg=VT47hu2UQnsg2J1DyLMXDdbHgdQvbSZEIYwlRcrlBMIXZtfGQPBUYVXeanKcfMQzsrP7XkJ46itO2ZlNHkRY7w== sig=UV4omuE5t6KBSDq5aW6s1mwbS9R9nwU6lC0MonGFIhvNxB0crCZgnRAGWch3gxea8mx69eKANPP9u4AxUbXXCg== e=found last=14 s=2 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA1pzjLLlKW+nbf3BXU1U8EdFFv4qRTRquEiQhlm51uBk= priv=MC4CAQAwBQYDK2VwBCIEIM+4YC5hXxoyWQay2JKFuBJTy/CwWBfkuvEipq8BSGRh msg=z7hgLmFfGjJZBrLYkoW4ElPL8LBYF+S68SKmrwFIZGF3mKwswmZmqBZvz9r1fZY4xEMjOSFDyczgbjKrdwTRZw== sig=LvPmMkFLojV3UztPRK51eB3ITxFVN+72sz3hCJg4d/KWXr6necqo+mQtWienp1tr4KI/i4Kqjz2NoTLTzORkAA== e=found last=14 s=3 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAy4Kh6AIXHgbT02itCtoGIibK0VqaJNt7gob1UUsa/xE= priv=MC4CAQAwBQYDK2VwBCIEIGP1a46tZYpU9lq+kja/U/4IrgQxQ4nm7SJH2XRNiwf1 msg=Y/Vrjq1lilT2Wr6SNr9T/giuBDFDiebtIkfZdE2LB/WbIpuSfgcy/Sjcs8sXH+oBmcSFNrSOMvaaLdyKKQyuyg== sig=8xSLthxKmijCuUjE1OyYuT+DizMc5Wa6CQ703WTJzwAVeOC5KQfrmkeCRhlsQD/YlOQShjM9bX2ZG006SoysAg== e=found last=14 s=4 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAktQJcODwixp4d8x4i0sazV4aDhtlppP5uN1sxxi9j8s= priv=MC4CAQAwBQYDK2VwBCIEIOA5k2zVtBu5PhSeIySC7gDZK47qn5dbT6uDN5Nsi5Hv msg=4DmTbNW0G7k+FJ4jJILuANkrjuqfl1tPq4M3k2yLke/F0Rr2Wq6Orq3DSnoJe5vp7QeyyYEh14V4aFnvnd79CQ== sig=sLZUdKya5+LGTi/UskPkKLU/h+Pfe9UPvmHkpIA/3OOmunU8/gpJwRcxaWT7bvNyoTGTF4D5rHqBsIUklpA0BQ== e=found last=14 s=5 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA8Vu1Whv1H8woMRamRy8S2bMS0H7ab9l7c77LRVKW2FI= priv=MC4CAQAwBQYDK2VwBCIEILZEAxIf/9PsCK8iQGZoOAEZjuWpffhOWBI48Xk61O4f msg=tkQDEh//0+wIryJAZmg4ARmO5al9+E5YEjjxeTrU7h9WAmhQRh1daV00AAICqdS4G1LOLPEOv5hIVimwBXI3KQ== sig=2XiMk+Sadk6PP+6nJaLpr5006I77MYkV1hOAMaYsOwQk5TTVQxxQ6pNrSXwDo4TOT+DZsPTBwSI29o6YrRsMDg== e=found last=14 s=6 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAtevlqRpPeJU0ULvlPna30uIFJrrMLAma1Ml7TjjooK8= priv=MC4CAQAwBQYDK2VwBCIEIKOuM8evEFyRHee+Zb2KzPhOcXCzKcblamDvSKjWEfDn msg=o64zx68QXJEd575lvYrM+E5xcLMpxuVqYO9IqNYR8OeJ2u6HE2FOmlfL5A+F48EDujrqq45U7ef0dkfyArHGIw== sig=kkPUnjn79VlBZny3K2r4OgtCuR9CEGOibzshLd0GOftgWSFJEWH36Wh1zAqBYYrrLdbDWkSUDH8b3CtBFj6QCA== e=found last=14 s=7 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAdCLm/vIJOXdiutrv1EfsGPAGBHlvH4NdfVkXTPk1+dA= priv=MC4CAQAwBQYDK2VwBCIEIMjoHwuJA5eIOdRmS+ghh/IZj3B7D3PO7ryfV1b/xHSE msg=yOgfC4kDl4g51GZL6CGH8hmPcHsPc87uvJ9XVv/EdISpq45RsgpASeEYHIbuKYNg7YyhUOjbqDB5GDx6lfnyIg== sig=MbW/0EtXK++PRVvftPsTJfPa25AA3D8dY214/wIVHbYjjOWApr7JrFxyQSScOPjFPSewpUHGjVsys9tnXgefCw== e=found last=14 s=8 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAkVW2PfKqa5QbPDma5xWYnqRH7sJjp/SZlObfjeIHM94= priv=MC4CAQAwBQYDK2VwBCIEIC93EXIzoEtBYPV1x5ZTzaV1M3LDdh8QXmRfT4urIjBS msg=EXIzoEtBYPV1x5ZTzaV1M3LDdh8QXmRfT4urIjBSXYKGP/IPx4UxZN4kv/7lvU1y2ROKNlz7BfRD4cpc0kKgSw== sig=symhm4eves/ND9On+/PT7ziE37KAbLGb78d6N6flPIH3Nrtv497SotY3Asa0K06V3TFXxVb82trK1d2+cQ9NAQ== e=found last=14 s=9 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAYRzqTQ5Ea/GQkKfvwhvVABs5zZnYFGqmyEQkiWwf/Uw= priv=MC4CAQAwBQYDK2VwBCIEINghi4zLHbG0exb4BCAIHc/285OUOZjXwJj2CNB4fm/u msg=yx2xtHsW+AQgCB3P9vOTlDmY18CY9gjQeH5v7gWThbGlfvBwmwmDrSgXjeAfZkEkAQt3eg2uRcw4yoZAjDuf0w== sig=IUduEcVrXxlC2GMiImscHsTTfWoxt67WIMjzxCWW+u0kYG9MV8jYUzysGsyxHfYPelfQhsolMyRgkiqfqIZQAQ== e=found last=14 s=10 in addShifted_NP", + "pub=MCowBQYDK2VwAyEARGLw7ytONHmcHBhAn59IuZwdV3tEGX/bWl96qxCBMcU= priv=MC4CAQAwBQYDK2VwBCIEIC9DEp5jNVWk7OH8QbzCMs4cmCnZwqmjg4z1GGvtfTTV msg=L0MSnmM1VaTs4fxBvMIyzhyYKdnCqaODjPUYa+19NNW+P5B259sevNkrtAzuEZZo3fZ4REjZYcR5zuCs1DXRdA== sig=EWxmX686sWuB6I6wSj6OBUoizNIYtpcN9lIVR5AKzcXTH8+tVhxobOZP2E3URA9dSVbiRVkNesPbujv+urJDCw== e=found last=14 s=11 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAGaavvJQkYApJqFCo1SpwyzbvPlEI04RWalQpUki29sM= priv=MC4CAQAwBQYDK2VwBCIEIBNdcwVj7ibtrNYyKo/LjOHWixM4ZEUp+DgdIE/xgq7C msg=4tNBWCmYbiI9BHhRDc9Z2Ee5jgejIhyzc2eQmtEj7r82M1MW9jeaAt17yDTd4TozLuucq97VrUnMZMHomSlg0w== sig=6sTRa4ly2OJVdAYbCFZKKg7NPBxWT7CmVhpcql/EQTXy+F2Ob2dwtAdItoH9QsnaaODWz4BzqTusM03IxLxECg== e=found last=14 s=12 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA/BtX8y6TtfB6J16osePQ2goWNS73D1aZgYe0dIu0Pw4= priv=MC4CAQAwBQYDK2VwBCIEII5ma4tvCG6gwyyRDvQx7OLcl8BklEV5+q5J6N4/672L msg=NlQVO3xzdbXc093G7tiM8zzT53ePXlmSMTy3BivJP8hk0g1WkuGNNSkdiDxQ3VvE9YhjxIvTfqInp6SHl8FJNg== sig=Yd9xwMRGfljaeriA34F92A4Gz/Xx9gZrmbr8+7WAhX7yFwX8vVBikX87UvFbsWhRxUyqSNSTFCy13XOrsJ18Aw== e=found last=14 s=13 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA62CWMSh/Z/rQLG4tG8Cuw8JmdGXW+N5CgFawuiOSNGc= priv=MC4CAQAwBQYDK2VwBCIEIIhjk45YAKiO1zFUlM2InBE4UFit5WD0bVvl9NJuvuHC msg=zYicEThQWK3lYPRtW+X00m6+4cLZcIJxXionNlwzJdvLwRXfW7VO0Z4nimq3laalBsL0VMXU9wmXZDe2F2nhEA== sig=YPVDKuhjy6PmI36JY06cTnvEomcpqaoXszzr+5OYJ0diXvRUcPyRMc3sEalWiQrIUnbn1GzVyQA7l37vg642Cw== e=found last=14 s=14 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA2uM9enIkR/oM/YXF+BnAvvIoRXCQ4pPOpc2dz08tV3s= priv=MC4CAQAwBQYDK2VwBCIEIG5eVKErc+1sU+fHxzRL0odQG0eNjE28tpgS0UzSlJZp msg=bl5UoStz7WxT58fHNEvSh1AbR42MTby2mBLRTNKUlmllABvDcFvBOis989kT5UJbIaVRQoqIGoahtnOVdDbEYw== sig=WdNSg/M/ROmyIowfwS9jXxUVRmgyy7ClhrPL0XlXV0zUAzoYoiJfS3pBcwAr4nx8OXBi479KOHIF7OYPG8A7Cg== e=found last=14 s=15 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA6EvDdnb0llwlZ9QOdMbb2Bq9+LMZ6oD3CScnuJU1JRw= priv=MC4CAQAwBQYDK2VwBCIEINaQylwvc24EXS4GjXAhzSpJ3YIHDCME1dzbVg/4ylaZ msg=hsh5xDQ+jD4TtbaOsbYa+NKQDYEv7TMTlx11ogo90DVIxk0FFtadRX1ILcgx/8lMp2T2IWicj5h2gv7GLW/XIg== sig=MukIYeEO6/P6zJrvECkCK9mC+lAKiNU9gIv1U975EoWcGvLagRAnsGUu75quWu9kz5krlnLEYGTKjW7/5T3bCw== e=found last=14 s=16 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAaZb4qleF87VuKdIWpniXxqYx/ClnngejZQgecqkGFj4= priv=MC4CAQAwBQYDK2VwBCIEIA1q/26f313uDNOo04cFTOHIDUnIxuBEB5VkRa/fAZET msg=FeaQpCWPiI0Nav9un99d7gzTqNOHBUzhyA1JyMbgRAeVZEWv3wGREyzEPZ3SQcHL+w1CSMk2L29s4DajHlEigA== sig=QwwL+szv/IfJ1I0iOf5XRqG37y25Y7e0xPawD7PNKauFaFnDOeRP4RH62wUt8seWPa/5ZTmZdOOg6vVJed3zBg== e=found last=14 s=17 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAaIVChkJbndXOtPuW4X01DSV4zyfYDlGiXjXj7sBBlQQ= priv=MC4CAQAwBQYDK2VwBCIEIIIPFnXjEAGVKUqJ5CzWs174DcPJ+xX4Vh+ulyDYi7pj msg=xhvkgg8WdeMQAZUpSonkLNazXvgNw8n7FfhWH66XINiLumPY1UyLVMVnL8UmfB/NBhj3Gjv73ORLZHiPqnQrMA== sig=gjl0P5BykGQtidaVXZ4OapR2kxIV+hjM35xMqxvKEV0XOjje7SB1b50DOYZDdHSYbzwHMOuDKzP1bVYCcnjECA== e=found last=14 s=18 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAmeiFD21Ehm8mxZJzqOfprFvVc1NA1Wga4DwE8QzWkZw= priv=MC4CAQAwBQYDK2VwBCIEILBkQAvrXdn3NW9FvPByDgpDTLfVbw77Z4qXFAnXGlxX msg=QDDuUCGPsXhXevhN3Fxvk1dvTGTLs7d+9uwLwPwUfQdU5W3j49DTbCXUhRjXiLfKgUawklCjkPoB9LLHS2/vWQ== sig=ABDsl3kDVlM1lE8pRlphHP8kY/rvrLRC8YTOyHF+s/3ngCOWQi5i3qhoGMChwAfhmQwfB2R/IV/RaSo8NfeoDA== e=found last=14 s=19 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAkia57Z/UB7qW/coLTgwWZduZVVAVBWApP5V3rOwgPZc= priv=MC4CAQAwBQYDK2VwBCIEINmYIaCAqh/1kYU+9ilg9HKvrmhdD4u40BE1GtmIMoRn msg=OZp/hXcmkKPucKrD9gBgI4eCXfktUclWBKz13UpRvQvaNDo2htqZxz26Bm7zhsqXoODhpc/lFIVRW5vWzTTngw== sig=ygj+kP09VML+z4+1aiasdLzZcJoCXlVeq9pN0qLqNoyvpIt58WXj8+pvGQ6y0fS4QD8sdsQFBE/gYwmuqbv4Dg== e=found last=14 s=20 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAmTB+coZ2J+Mu74e/HyX+JmHGrvzKHqce0YfkLjOyZzU= priv=MC4CAQAwBQYDK2VwBCIEIFHEz1/X7QrMX3t6Amhq0wi9w+pVzLFeCY77pam6tOd+ msg=2aSjhX2Q5yVBcSZsmU2UEDySzOmzphMuDVwAcIg27jdRxM9f1+0KzF97egJoatMIvcPqVcyxXgmO+6WpurTnfg== sig=ByEyfMNXU+golEoLQWSxqo5xFJb8mSM5RVYtIVoT9OV0kZo2ryAxCDrISlKnvfy8uTWfwzXLIw30jBhmSWHDBg== e=found last=14 s=21 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAOAtVakSIZMTFWkuW1qcE3QDUUjzNQRPCB8MK+PenZhI= priv=MC4CAQAwBQYDK2VwBCIEIEexwQuuiENLEJSZ+bm53rhkk88zYN35tw9DiBb6rzAS msg=tw9DiBb6rzASYE6kl3SK+m+QKAvKO/D0d+LhzGNFgRMd1tKOieUE0TlCEhfTNyowguWAM2Pc0p2R6IsWmuNv4Q== sig=e9+DgxlR46Nczm+prDRUavvENbC2sStK6tx6MQ9/KIRUT9STmFDdVRr4/XQ+69ZOVYLdJI6WRfY+ZciqqS4KDg== e=found last=14 s=22 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAU8RzwoVIfNwRVX9X9OSnvQBCbHeFf+t4N6DanMJHnaw= priv=MC4CAQAwBQYDK2VwBCIEIC71kdEkIIUG08HFAqSak1O5WtR0n229yh5ZU36OUC3G msg=wbWmuB/9iPwI+iIc4wteif97dodMulWC2lEK2fOrY0tOa7o5mc0UczDNHZbXWIj9LvWR0SQghQbTwcUCpJqTUw== sig=x/ppbpEbvUjz+uCmIWl5lIOitlZxrGvRN4ZlPst87a/dBMcN7XYuxHkXZKbpmTsmdhnFBy2r00r02fGFSpfFDQ== e=found last=14 s=23 in addShifted_NP", + "pub=MCowBQYDK2VwAyEACnDDfo0cBXw82tDq5HPCHd1lDgavvbmz4v1VzhZcmlM= priv=MC4CAQAwBQYDK2VwBCIEIAQOBniYtRl/lJe/tBc9iLAgm/h3Y4OaxHuZ1/1rZHsP msg=uFbaGVdVirsoS3e9sEMjaaN1Y48w9qc5APPf6PmvG+Hnz1oitR1K8KgOIVxNwKbyeawSahx/GmJd0sQyZ/uMbw== sig=TkhZ+wSGathHomqYR/+QdRO6Bb2PaB2qOBF4WrHYOdprOhvYmC7svOagH24lxpnUWIYANk4EpyVIlP+TiA/ECQ== e=found last=14 s=24 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAa2MRGNSORs9mAmccujEEr5I4piY0yevnoqilf0uPAbI= priv=MC4CAQAwBQYDK2VwBCIEIOFeIxD1N8e0yJ/h981CSjOEmbueZx4cut/VuP7daCIp msg=J1dNGjn1pz74R6VkDeC21HcaatwWpeEW2UndWdkli8OXCjjfYwj9rhskGcdre+3U9q3SFQE8mR2G4IaRabCQSg== sig=8c4BLWoMzLMxUTJZTQfKuFKU8kw/SI9bJrvlDnmOMngAKxZK2R0FwzoF/jmcG1XZIQXsOFBDv4MXR/QhsIRBBA== e=found last=14 s=25 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA/TVTG7WQt1XIDLlNyl4yAhbveXq/mPT23OK2p671Vm0= priv=MC4CAQAwBQYDK2VwBCIEIOew8YuwBrvvDDH0bIRq7+TMEEByVFVhuVQ2O7rh9t6g msg=0cu8hzH+Uel1+2Zqm3utnP3eDuew8YuwBrvvDDH0bIRq7+TMEEByVFVhuVQ2O7rh9t6gfRtq4VzdyB+flp7pJQ== sig=Gk6aJHFW7x/3tAr19Q5TYH/nUCR6H/tHFxeTluH7MueOCP02lanuRPi2r3SbNJL3Nbop8XKAze4qe8WfYS6JBA== e=found last=14 s=26 in addShifted_NP", + "pub=MCowBQYDK2VwAyEATnkhKuQcz6CTCkmUmxBbqJ5CxcAiSvXXVncT49Nvk18= priv=MC4CAQAwBQYDK2VwBCIEIDWj/k1VYQMSkN2xhrLtLH8bi2uvVQJ6wWNlBS6Hq0Bn msg=EFUjdTWj/k1VYQMSkN2xhrLtLH8bi2uvVQJ6wWNlBS6Hq0Bn949u9uGvqrA7ivtOhw4l65by7M9PVpX2gGZfCg== sig=y7BJPBTBm5NodkBWVo3XLvdGRWeD9l0tO83bg2rku7rzr6uYaE//e+9tDP1pWmQT8wS3WjMB2OlMsNCHh51+CA== e=found last=14 s=27 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA8JZb30nb0g1x14OfW1W/nukoX2z5PE8kwdoOlPsRXzM= priv=MC4CAQAwBQYDK2VwBCIEIFiVw01jLqdl42ltnw+B0J92oF95nW1dqWME9EVEd4YK msg=w01jLqdl42ltnw+B0J92oF95nW1dqWME9EVEd4YKi8vfN5VL0Qcmhs/wv2VnLE25udC87J94pvFhbnOxvnTzaQ== sig=B8iXl/lYGVuoNcvdSaAYH9Ny1zsw9y0+/v5IwZ/9l4EYyAFe7gOLVieaUxGr6oTexk1d8ESdvJCYCFnR8B1tBA== e=found last=14 s=28 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAqdqwhlD0Ao0FOs/k+aaCmzMbTsuhp1evabO80hBleQY= priv=MC4CAQAwBQYDK2VwBCIEIAMv3Bo3hUdpOTdQZjUoAFVhh+UjgVR4QBMJRNx3xJDl msg=L9waN4VHaTk3UGY1KABVYYflI4FUeEATCUTcd8SQ5Vyi3nxmJas8TeRhOiVb1y2GayEZ/zL7B6HL8zvOecUGlg== sig=wr99uHFzM3PXphB9TVHlCm3tf2kaYJ1OBxFdHAfMGYZ1X87hWNCBzA6iCYuGnL10r8QCzgWBo/lebtcVJ+fyAQ== e=found last=14 s=29 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAF51jeLxl1rYM1rBSJ5gLJMXHxD8CFZUBK3BB1JW5DSU= priv=MC4CAQAwBQYDK2VwBCIEIHky5Np8wUdkBuei3Pt9rdADXrLPxmaewdB7FSkPUYGj msg=p3ky5Np8wUdkBuei3Pt9rdADXrLPxmaewdB7FSkPUYGjATtqqE9LM03m7rqK2f+Rig+kbHFxYJlAkIMmnT73gw== sig=kvqehogHT00vPmv/ghO/nS8i20h1iXoItb0WSeGwjZkNiQW3F27mnfV02WszvM6SwxeBtLHbUHAb+NNufPF8BA== e=found last=14 s=30 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAdO7JFnLdvf8zH0rs1SpdiypIv5TAY3d9qhoq5o27X7E= priv=MC4CAQAwBQYDK2VwBCIEIIu7AWSTwPgMQQb9SVF0nxWoTvwgAe7NGxnTBERgzbyL msg=xIR6xVrXPxdx0cgCWwbgREYRi7sBZJPA+AxBBv1JUXSfFahO/CAB7s0bGdMERGDNvIv4s+2YzydMZvgfm4ivww== sig=KJLXT9FnCK7seLb4x0boJROG68b9BHTYNBeVe8IoSFPW9sSIzQPcq7Q/GiBtKpxCl9MgCl98U2DaEsnWLqgfBA== e=found last=14 s=31 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAZ07XJoey2kjQ2hjQed9aDBb0Q7fmwRWq+QnPusXhans= priv=MC4CAQAwBQYDK2VwBCIEIMRxbLSLpINPpCfBjJFESwHvCIHIVBhyeaOwgWNafo9h msg=EI2cR9RRjYdqYZrVzQa3Oe2c71Tzfu1/5V2K6Z3uMxPkRFhTj4oGucRxbLSLpINPpCfBjJFESwHvCIHIVBhyeQ== sig=VDmoiUFjMUj8zoJDK9NBDlWBqsRRsI04rFpNcyShP2cJ1/LgsBUj/8/etNHTVl8EUFXCq5VxfinioBl+rRaMAQ== e=found last=14 s=32 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA3qX8W/FO8WgHq6GQsLFCwWFpEZh9+oY4dqSFRYc0PFQ= priv=MC4CAQAwBQYDK2VwBCIEII4KLBvrrluOTkiaFQC6SN9femr4iAtF6iKg+qJzkABe msg=khcD7Bym2d1PLe/HQ2sM7+IEjgosG+uuW45OSJoVALpI3196aviIC0XqIqD6onOQAF4TmWMmaKllHDvAoLRG7g== sig=5bFiD1Q7+lhkr0GXjOWTr2Qi4Hh4X3XQYQglMHQ9BEEGQD2EToHy1KC9thcRiPFA71BR9gJhwsDCftzh+/FLCw== e=found last=14 s=33 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA+b0dlNC+xjKtPyJ68RTL2LORfDM8m11+ERIdpCL3G50= priv=MC4CAQAwBQYDK2VwBCIEIDSb5VHQznWyyQABhaP3UoYNPaHMuD7714zmIpxmcMhk msg=hZ6gnRnv2IggMQRNof7DnqhWxmrTIRLRr4Y0m+VR0M51sskAAYWj91KGDT2hzLg++9eM5iKcZnDIZBWzWFDDkA== sig=U4+L0Qe42Owgqstyb8Im8XNvD6BxkcpbgQTdmQWdpphKssAxIX5t/8W4S2sjf0njHGxWnhwOXWgk45numzmyDw== e=found last=14 s=34 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAdrkpLk8EZ6zrrF+K7ejlPkv6ZWMKkbM9PFh/dKKkHIA= priv=MC4CAQAwBQYDK2VwBCIEIDnxg9OEsKzD7ua96A35VD7nclFpUqI39ShNuGnR1KN+ msg=k4BP15XQB+8yfxEMC2csIPQvrC09vV2RyLc58YPThLCsw+7mvegN+VQ+53JRaVKiN/UoTbhp0dSjftx+cuXIoA== sig=2LXBbdBtV80y26jIkHcOOXq7r/pSN40Shu4f7mFvWwMjpDnTXXxTkRkck8a/hpuMtOWqckgrf+AHA8+JQcEKCQ== e=found last=14 s=36 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAsxFcwDcLojXUEiyyLdu0obw8GrQrJuH49phvSUswKOE= priv=MC4CAQAwBQYDK2VwBCIEIKKiYMz+tmr/m4rR/+kZ0NjgOqhqJb+AXXs8KDkEb3VP msg=V53rmEee1A/bQLG8OwX1ajQ0Y871pOjlODMuDMsCPVTWGJ4xEaVSv7rMaS9i3c+0Zo2iomDM/rZq/5uK0f/pGQ== sig=tpan+EcrcfGTSNsUEWu0h1Dc4YxwNiX3Haxofdo7Gr7B104Xb1NbF8M+E5a8FTdE0+PEPTIDqmdYMIqAsmuUAA== e=found last=14 s=42 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAWNPmakqyrHHejUO7H27qbFzcylW5bEr+OPSqus1vPIs= priv=MC4CAQAwBQYDK2VwBCIEIBCvTw6Hoyn5JsxHYSdNnXElw85SI82dSaxqtcNo9HAs msg=EK9PDoejKfkmzEdhJ02dcSXDzlIjzZ1JrGq1w2j0cCxSCb4SS8M9sJjvKJLG2mhjl9EWuTkMH09B+E/Y9LklOw== sig=DooigK1dWSZplUqtfll0eJfvf/iEzY35snfb00ejoaCO1Rv+YVbAMJwDXCF1TPUeEqNaiegP5a6afqiaXK7/Bg== e=found last=15 s=0 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAcRgbHN9sPEoAeBLd8TYxQQoE5nzCtjqReIWZHTkseRM= priv=MC4CAQAwBQYDK2VwBCIEIEG5uYTnQfGD+DIKGTVYEBzEz1s51v4iV6JzNqXYt2DO msg=Qbm5hOdB8YP4MgoZNVgQHMTPWznW/iJXonM2pdi3YM4vgB+3rUaJ5ku8qRCzR4O+aMYnX3OrtoLi9oCpDgWE6A== sig=eVpayQhFcfEnDAEitsHTEOVOTW6rLxnlgbOm/xteUGekfpeCufPCq1Wq5rDvV3PTNY+V0Er0brHy1WvxY7REDQ== e=found last=15 s=1 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAbuMmAO6GnYEZLiZM4HNHBkCNiszgm9BOCFTdYiseA2s= priv=MC4CAQAwBQYDK2VwBCIEIIRh+MIVXOT4HRrlILID8LMJjNmdH7AfqU2leELfJqsq msg=hGH4whVc5PgdGuUgsgPwswmM2Z0fsB+pTaV4Qt8mqyr7oMPe29ZH4+R8aPgl7M3o4jFO1NO5PgQL3MIFRRixFA== sig=V0f5iy+cfx5oKnY5CwZ4eP5/IHZqVQiqPsK22kJy0aBBQfzU0zAlyl6h5G+c/97ZL+Z505Xuzgnx00IYZScLCQ== e=found last=15 s=2 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAe7yI4bJRIweGtomYKBmCNHQm1x08weTktgojd7uUjfk= priv=MC4CAQAwBQYDK2VwBCIEIDHahbBLqbjLMKZuhCDFJsqaroa0KPVgiuVvtatVp/ak msg=MdqFsEupuMswpm6EIMUmypquhrQo9WCK5W+1q1Wn9qT3m/n2f71WgLtuBad8ttL0A7TLI1BxdS+GZs720dAYTA== sig=74QERXzquku/Otp7j5ALUxVT8+1vsqIo1/Rog/Hp/aOFX2w4qm+MFLXNogGwJhyW8PHv3uLzA9BN1Wtno0vNAw== e=found last=15 s=3 in addShifted_NP", + "pub=MCowBQYDK2VwAyEADaA0iFmpirfLRE/jdjuybbNk4u/+VukP0weiCurZN+k= priv=MC4CAQAwBQYDK2VwBCIEIDFiSUuUIpeCvaVL5AQyAalY3EFcfofaSzE0eYv4O48U msg=MWJJS5Qil4K9pUvkBDIBqVjcQVx+h9pLMTR5i/g7jxQJZjgUGAbYXq26rukea6w5K3tAZ7WylOXsygJOGb6ZFQ== sig=dD9kDLaNt378wcxjCP4kcHM4wUBprZjT9nMxowKElnLweTsTxtmJeHFvI0IHNfAK9wYNpu1ycBL3bYqkS2hgDA== e=found last=15 s=4 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAXtNr3apyDyAkNEeLUXTahcfAGIR4LJbjbi+e0HsKxZs= priv=MC4CAQAwBQYDK2VwBCIEIFWBu5LbX5JtxZGAG5FckyMyiPnwLPiztNNhaF4ZTX9e msg=VYG7kttfkm3FkYAbkVyTIzKI+fAs+LO002FoXhlNf17knsuY8UhJEMZ5lPYstvTltnU1TuyJhB0WJqPM/vpzLw== sig=S6/9rLrfIJ41UZPYp9LHt/4RTtrwy4EkgKafgPqL74idsdJ500gNCAoVk0NufJH0VPQJzMUFbM35z+D5fsJDAg== e=found last=15 s=5 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAqgCSVaGc4AudoMr4//2/fTsLJz+CGEXjqI3NgOQbvGA= priv=MC4CAQAwBQYDK2VwBCIEIAZlNwFjEAXWysmihFNSnQLnYphx+7VomcRw+8RfBMQq msg=BmU3AWMQBdbKyaKEU1KdAudimHH7tWiZxHD7xF8ExCpIsviVBLX0z2Djerysfw+OYrwKN7Lf12u4C6J295SAVg== sig=rFC0mcAF6HN9JF4tFY7jT4x93gNWMrr24WIZ72tnMdVq9Ik/5uG2cNeQDtx/YvEgQBhLfSVfZBhtS29hLl9JAA== e=found last=15 s=6 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAhDm3Lvb6tsQAwcAjpP78gSULPEQzD3Ko+GT1peMOp/c= priv=MC4CAQAwBQYDK2VwBCIEILVVqCmAqJ9H9W54OxKMcP0ytDIRwqu5QpUPfiurjxRp msg=tVWoKYCon0f1bng7Eoxw/TK0MhHCq7lClQ9+K6uPFGkIdjHcsbfsdsoxdl6UEPHY5A+Tt8yH5MPgcXLkOkQCzA== sig=eLAZwBbNhI30Sv6LfnQSIPqapc78/OXfkX2V25TKf4ZbefAAs1Gq3UT5NAOMOBD2FQHltefNGQrPHqAE2OxbBg== e=found last=15 s=7 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAn/9yv5NyZdRp+/1NavuVSy7tVGOJ4sMI/HwhzPPe7gc= priv=MC4CAQAwBQYDK2VwBCIEIGwS1kDyBWuk1FA0gk/inYZsbXSOU56fIn6zU7+vCcGT msg=bBLWQPIFa6TUUDSCT+KdhmxtdI5Tnp8ifrNTv68JwZM/XLTdGVTpf2eX+54PuaWY9Xs6fNfmPEJQt3hb0vLuhw== sig=uPgjbNZ+iK+rD+qtYQmdkcNClrFbDPwF7XqI++ho5K2nmh1xu0L9blIZHhddfxpPZNI2nc6RZ7K38s1dMKjUAw== e=found last=15 s=8 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAVVB9a2cdMffP3NZnFctw9iG3DpzewzI5KEMG1V0K8pI= priv=MC4CAQAwBQYDK2VwBCIEILH66tKKUf+0eETnw7Jlfim9JKG7QNsxazANvEBNacMv msg=sfrq0opR/7R4ROfDsmV+Kb0kobtA2zFrMA28QE1pwy97W2475s4C5bOeW9AuwZjhMe+aCvqM0KujPaHz4y8KvA== sig=TSmVhUJsxXGxDZ1bf7CF/h1dN/na48d7xMOzUNvKsc01ZpDfiGY2YvtvUUoI1nuYyMz3D4tp+o+gd+HaIXdIDw== e=found last=15 s=9 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAAwUQIo4M1qy6efc4w7fy9w4794IQSas/9qFl05h1WcA= priv=MC4CAQAwBQYDK2VwBCIEIMhJq6xLjtXELk9aEoHE01rNCH+j38K0YQEamjssRqAD msg=xNNazQh/o9/CtGEBGpo7LEagA4uswFEWy1FNgkQx+d2yIwgRx5lDhirsnnFS8141Ru1fJWXeQA4cGsIvEE3GPA== sig=EKpMVwjdFq2c9aVShr9h+NqX36uT2KPSQxlP1hz7cHy2qXdflf50xUB7g72y6e/Etiu84OOOkbzfupFPvcTOBg== e=found last=15 s=10 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAg0uXLg26eJhHIP2EuV5VMwkZ9M0EqBGbSnMBLj8qU4k= priv=MC4CAQAwBQYDK2VwBCIEICiFe2OSiR1uRxEu55Chsy5N8GtdWh4Kue+aUS8ugOGw msg=KIV7Y5KJHW5HES7nkKGzLk3wa11aHgq575pRLy6A4bCQygddkX6sMQdBRxzB7kHolECRDF2IuzF4G0TygASbGA== sig=5zb5O/zUnoa3oBOZYg9aHHHszbrW3zt7UAj4HhU6D/qRR6Th0wVRbTWfZdIz9OmcRbbVEuS54qEtNgctCrtDBA== e=found last=15 s=11 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAhDqAxB5WzgL9lnfCzHk+G8xaoCvKE4FR7nd97r2SwUk= priv=MC4CAQAwBQYDK2VwBCIEIMCr4lM25BDZ6Ewzbw6y1HQjwwEmozSLdJ8ZnAw/+loR msg=dCPDASajNIt0nxmcDD/6WhHulqT9yepiHLDh0IkC6lUYxYEO47oDUNdiKuP52ZkcH6kFLWxvLU3qonrewaS7Vw== sig=y06d8b2CCfZHU+VG9sgIbi3B2kikJIsuRdHIKv3zMwIaHLkAYolQhA9xOy/7Vijz7fWvG1z7BZ221b8KCHLQDg== e=found last=15 s=12 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAJ/YL1hsAQpPFOn526Cl0U1aIoCmFM3MJmxCmng7Ecto= priv=MC4CAQAwBQYDK2VwBCIEIJztITaSsxFJFxSSQI/lStdfomadpDVBc7OQYIPTcO7A msg=nO0hNpKzEUkXFJJAj+VK11+iZp2kNUFzs5Bgg9Nw7sCkOcOwWeJQmy0PtifUqK2ijNwHoz/H/117INH42qw7ew== sig=hhsMtJwNEcV252U6tsAilLv7RkL4DQm4V22w/HllCu0EU/ehQ09YuhJBSAkucR4cKg3O1FibBrFmmQYDcVV4Aw== e=found last=15 s=13 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA/RGUcow7+t89TEYW5T0C/pQTY4C+uXUMnM8TCJM46l0= priv=MC4CAQAwBQYDK2VwBCIEIGbtJhEiX09W6FfESZ+FWWKV+Yb5q69Z11eH8d0f50sQ msg=lWBRMcKQfzg4ItoVY8s02Xzca5imvow3wMkf7AVexf2mvxgAJDYpjGbYvQAJ14yLfnQi6sSCbxHJo5OrbfP1Sw== sig=vSdP08bMaY6apW1QfrXU8q20WyCUPou9zkRjlVF+CwMLrsft3HStpMpDtRFqIRwRwj3nSVKeBlC1hKsG9RTqAg== e=found last=15 s=14 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAXZRDI0Xz98qFIoZWMUf4uYej+4Y3sLx+2fQ+61/Ip0k= priv=MC4CAQAwBQYDK2VwBCIEIC4ycR/Pg+EvlWb9nofu/SEoGphxh5FQ1ydVzKTeEv2f msg=zKTeEv2fDpXsItQ4NX63x5O5JbLUJAS77Y2mpHzqb1vpqR1++wCuJo7tVC+sNvVZ9j3/6z4pmkrl5+38NHEUyQ== sig=kmuV3W9aMiRSnhtqQSfIOsGjUcGKmcSa0apr3cBSSI/V20YYZTMO3UTgv6DG9DAIvxHiX+GKt5bM5RZC5dPTBw== e=found last=15 s=15 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAR9DKim6AFz9D0L+oEVfTARHniLVxGhpQQk6OK/6UjpA= priv=MC4CAQAwBQYDK2VwBCIEID6nAPJIMrV5c4Q5L1ggmOEx0+dFdxW63k88jX4GF0cf msg=bHyD0n1LgF7WqM97TpmOax2QTLw/SDiqoK2BcICQUVc5/U+Att/y10LtigLxBBHH/NeAdScpdAwGJusBO06bMw== sig=kUtn3Hux64xmPBEk7tHxKySscj7xvWA8D/FxGAFTKtA+0EoSfXi3lT/ZBdhatQJ0GOcR9gZh+qiamHPAA+qnCw== e=found last=15 s=16 in addShifted_NP", + "pub=MCowBQYDK2VwAyEACW4+FQWXjtCYSSMsBHdojsTuDAOmLNoAeXXi2wfeKIg= priv=MC4CAQAwBQYDK2VwBCIEIDdk/4sT0/betFtwkN6YbtI7fbFM133ioFBR260gRfpU msg=LP+f6rFEFoMHN2T/ixPT9t60W3CQ3phu0jt9sUzXfeKgUFHbrSBF+lRCgrVQ32eOH7tIOQX1V3xyXDaj7BAO1A== sig=Ysd9z55LfRXUt+BxKNM0356yjhDR2VohdIhzgdZjD9K5eSM+QjMZ818I3uCv38upJ3UI6g44x+NLXcM+5H2CCg== e=found last=15 s=17 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAWpG0npFRhbH92UGlmsdLcJ5K+Z5XCJYh36fuaHz0qhU= priv=MC4CAQAwBQYDK2VwBCIEIOAVsqAlrFCg0k+rvoz/3qSMHdCGxswj2F814wNG0jxW msg=wd8M7e33U0tdWlZFgtXI+fOWwDcgPg25PFZspsla14Tz8f4jIK2CsQrSxtZgSN+MEaCIgy3p9cRIp1afGTITxQ== sig=ZWbUkdTeJpADQLwRiGH4RX1WZwZXDPugxLYU2N1Pao+vObfViQ5BWm3NXpTnHJPjnrS7VNDGWoG7vTe4l6u8Bw== e=found last=15 s=18 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA3k7BzDYQSsLY64V3S273re9BuZfZeSgdheM7l4JpXug= priv=MC4CAQAwBQYDK2VwBCIEIDdvw4Nhg+wrAOH2GLqxTtot3uPnVcbu2mX9miEmRgXp msg=miEmRgXpwsl+ns5PYUJbr6dTPYWRmlkqYjO4alal9RjcdSnwEyE+y8Hqm6CPtrJsltA+PgBHvvDHEGuW/hJGng== sig=4ChblR75A6ZM216R85mj8MZIhe1xt83qqrt2trHCsq4Lh25L6/Woi7bCVD0pVWvc3lD2BDJyjbT3QCD2+TYIBw== e=found last=15 s=19 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAlfQqLgqBFHehUOWnU4eN/gm+CKSkLmSEo2n1K+ELKx8= priv=MC4CAQAwBQYDK2VwBCIEINwW4QAMDFHX+ddkvy/A7wRycB+ahyKgLtOdQFtfaxPL msg=dDajbxZOplSoV4lyWIaQHXqHNcXXHojUYoc5lczMklv63BbhAAwMUdf512S/L8DvBHJwH5qHIqAu051AW19rEw== sig=zu2yGljWkC6D/Zawl4LUDA4XcdMguA4OAW3zb9Ui4EmhMLjfBrOZ752oGjC5PpwzPwhUOmy6gxB9mfMi4Z05Cg== e=found last=15 s=20 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAs9MlN6HWo2TsgLW0LomaSow4B3pBzPBXv8raChJ+wdM= priv=MC4CAQAwBQYDK2VwBCIEIPJ4b3lQ1l4H9WQpccfz25THdmBSSibuFNtovFUUtU4p msg=4FfucowYvTAsVRfxVHpWUTh8XcUP8JkLZ8eKTz1KW5WBFN7N3BwTatsFjgYwEVOoMOlLQ+zqIMPdzsHStkZJxw== sig=PhWrVJgl2jPJbEP+jsAJjlYhH/9ZU/akRPPC+bjZJASfGtLF81sR2dtnEJJ67IOrmrn2VrqDyCmbaJp6mPMyAg== e=found last=15 s=21 in addShifted_NP", + "pub=MCowBQYDK2VwAyEArqGiXTDjJCRBvXI3MlNRwyuLil3tQLSynDB3QUHSJlk= priv=MC4CAQAwBQYDK2VwBCIEIJFCgCW0JY8ueKKD/cJ4ucM0BdZtx5pZ/Dkg38uoWyL0 msg=g/3CeLnDNAXWbceaWfw5IN/LqFsi9ModeJ4fggVFU4vojDWIaq6IwmzymEwYhzDgYkvkROA5V2QagJYmC1j27Q== sig=s7dchSkDITB2wp8tjoM8uKhXm52Frej/g2pvJ4Stq0kJ+uyuiGQWTtPiub/9PXploJzdd8AdOyJsrAaPcTFiAQ== e=found last=15 s=22 in addShifted_NP", + "pub=MCowBQYDK2VwAyEASXFlHAHXy2RrnNrM60PBTaWA2tokGbavOK3DyMqRDL0= priv=MC4CAQAwBQYDK2VwBCIEIEJ968k9xwr745P0kFdd/0A2cPKOqXhmuIiLPYNnz/1o msg=GOBQueZP5hzvyveAeVQKkHMT1dMB3UJ968k9xwr745P0kFdd/0A2cPKOqXhmuIiLPYNnz/1ofWfYdsoDJXcTkQ== sig=eFcuG3DdOPYdBQTo79MKfDN9ZPzmq2NhVHFgs2PZPerqLsWm99Tyd7OC0qxwlwHLnPIb0jZavOT8RrD2YkP6CA== e=found last=15 s=23 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAydzyd2wztJHVVpRd7QvF1/1/O0uW+0CXI2g5/5r+6Ug= priv=MC4CAQAwBQYDK2VwBCIEIGgiz/cBNBH71WkV4DvATy+hnF/xLfxdCL6yyEiMzSpZ msg=whfAgLqpkFc8gpVfLLIjpYRMX2HYhE5IhiUZkzEuTj7J7meT+D1WJgDyxlpoIs/3ATQR+9VpFeA7wE8voZxf8Q== sig=Cein4zxKbMhz6VHuGVmj50forw8RKeBhYM9CJ6WEy3EKRuHpPivmRi9lWqGJB5EbtxMY2mU/QuRvuUD+Oq92BA== e=found last=15 s=24 in addShifted_NP", + "pub=MCowBQYDK2VwAyEANQPE416EO1e/YIfYZwokJzJW91j5FNWLI4swn0gjmP4= priv=MC4CAQAwBQYDK2VwBCIEIJmNgRfC4yHNaWrqxXrsWJKFIh0OWjsKmEJ5IWfsA6Nv msg=yUhk92hrerFdxOl+q6q2FjHu3iXHlfp5HJdgnfXszZ4tk5meUPBMTESdSY2eVWZnL9DULjnZihjHX5armW3lzw== sig=1k0Njd/4NDnJ9WkuvTZnFMZ1NIfG395A2P6yqhJHV5dcw4SIAY+IWxQoQEmTdxUrH+IHG1m877YwKnDuuWn2AQ== e=found last=15 s=25 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAsMWGI3+oO67hdRp2aSpGVGYBDsaWyLki7aWs6HAS6m4= priv=MC4CAQAwBQYDK2VwBCIEIHehqPYlfBfYH90FLccoweWZpMM3Evmdp+hdcWHWuJR8 msg=TMOMgHpnLgnRa5NAh3LwMx5b+r8duN4Bo9LCl49kdeQrHBLKgwRsOM1b8NzoIOsq2TNO8m9K5bpw4VlImnehqA== sig=fYLpXn9C5x19l4cN/emKTDM81tdIg4G0nN88nuAMqknvuNMdmMhPUO4KTBrGP5obyo5s39MJ1WTK+fe8L2+VCw== e=found last=15 s=26 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAkiTmVwCQkfzx6JjgC576f6dw0+Wo7PTp6xzcNFGxzRo= priv=MC4CAQAwBQYDK2VwBCIEIFgSkJrNttZPMxJC757hYtsjF1ca2kacH/i0Ku0h/mzS msg=q6riLhAv/Ypbki0gVo/QiyLt5hORyMPlof52FyoujQS09l9gA/ydd4B2QE8dLoWSRFcwKJIGHN4gpaZWZuKFqg== sig=Iv5NLvdV4kc/cJAA2bvnHgMXibj6tj6hWl97sZz5LA/Ix+Vh0VgsWHlEHEc0ccVZwGX25BqSrghL/abxVFz7Dg== e=found last=15 s=27 in addShifted_NP", + "pub=MCowBQYDK2VwAyEARnKigl2gKR5lHyyUuORJYruDxgUj7O0p6rNG51VmcC8= priv=MC4CAQAwBQYDK2VwBCIEIC9mp7zcDmrPd+sTwmZr/LaLlXBGvsOLxpNicHT5QgGb msg=aEVcx5Xb3s48Ip3cG98+XLEhSkJG8q+W3GEyAGodlzK9OemVEJRMat3FumovZqe83A5qz3frE8Jma/y2i5VwRg== sig=BN+ew7sg31lM0Or+YY7hhYtM29C887tHh/cEcXT9sOLW3d/5x7hQN59QyHqmQ1Hn+DpYIhZQPqEiAf3zNbbSCw== e=found last=15 s=28 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAn+8vHv2QlMeijiySod0yhElhWPghcpH8RHfY9tkT7vI= priv=MC4CAQAwBQYDK2VwBCIEII3SQkZSpQQX0mZDz/iIlHWX0KMJNIMYWraCOL8yIUfg msg=R+C0Dl7wrlYM4046xoAOnfRsh0PtUrf+QH/jvDEHWpz7yNeCHI34NQH9nZnmfy9B0LWhS0dyeK9iODjOQJG6Eg== sig=M6oJH1fCDACrWcGoLD6LkuThPgUQLUbmAT4cqz2V7O/2JS0YIqSZYM6Cpn1VZHwLEsu+oYJaMi3LVnsnLU6QAw== e=found last=15 s=29 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAIMh/nCVYBLpo9bGoFamZ6AlkjUWSFjc1hwflbTYzACU= priv=MC4CAQAwBQYDK2VwBCIEIPfQE8rpMw8Rcxk295Ltio6b2rynJAsk1wnNmIRIZbSt msg=tsDUiGmiJBMz9vfQE8rpMw8Rcxk295Ltio6b2rynJAsk1wnNmIRIZbStOkQv90OkGM9Ussrj9ZTwkyQL4A2tJQ== sig=u3/pWM8j1SLylE8+L3W5p1aETwMEmu2bmfrb/6q5lr+oq1gaTJ4rMEAyEbvA0RQ8b9oiR+LLCQBdTBqz8F6TCw== e=found last=15 s=30 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAOV6fvMN4gZSuTKffd2zbGskWB99hr7res2WhHevHuKo= priv=MC4CAQAwBQYDK2VwBCIEIP6a3wkUPLbsJbS/EMD6XGo9/yAyEslZqQ+GH/q/tyE+ msg=PLbsJbS/EMD6XGo9/yAyEslZqQ+GH/q/tyE+pPlvTFtdT/MscOwng2IuQ4WDVoumejzPuqC6Wf9pWwoGlJDb8w== sig=q1tizST7iXXD54JwMFVilPEkRvKl/M1E+WGE9tRXsjp+1fg2ETAV2rjxvWwJQjH/Yy92zPQElYF4WI136oB5BQ== e=found last=15 s=31 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAEsGGSW/Gu3HAiv7/MPHz2PswMvQM2bOJfuTXxFWqRQk= priv=MC4CAQAwBQYDK2VwBCIEIFkwoE6pPsuNV1xsq/cmcWbZVL+mL2rZT3OCFxMMQz+i msg=y4qiB5Qpz11hMHNMgKISD1kwoE6pPsuNV1xsq/cmcWbZVL+mL2rZT3OCFxMMQz+iYvuoLyjeZB6EK2LUFQFY0w== sig=8yXqIsBxr7OtWWGg67O0HP7dPWFOYv5H2GbVzNMYo280/3wRCYMmOP2Tq9MTuEfUlise5EnPOUtaDEFEK1JvBw== e=found last=15 s=32 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAFhE4dGE8o/tUm/hx/aP4lTeL+I+aTtO/z180zOJYVqI= priv=MC4CAQAwBQYDK2VwBCIEIKGfcdFXVqOXnS+XEI5thtOtaRULhGYecjjOYX4CBQPV msg=CTOPoSYin+Ap9x5x5DkEy/HxQLx0kVh2gwXDZWJK5HTJOK/ZhIFKnsI9QP9hBez2KqC4/hgni7kysfll2488pQ== sig=nti3YWNNWQXJ+17TRji0aTgToPBZ5TEx7UfYOelGNbO6DVHrplr3elQ3lOzQdk2lsIb/Vfs6GyRBEDFprwv2AQ== e=found last=15 s=33 in addShifted_NP", + "pub=MCowBQYDK2VwAyEA6bUz9hWfvAu6nzxcwUpONCWGks18fsDqk7AqFS7PXPE= priv=MC4CAQAwBQYDK2VwBCIEIMp7R8yHwffb0d1CQfD9mVF1k4pC500P7R3AQqAZRk6i msg=QL/CK9Mw29OWSs0hwU9alwfWKSsV1hERVwoFO1zVHnkq4tpuBlPp2rnzPNPufRbeIFnKe0fMh8H329HdQkHw/Q== sig=o2uvOo/nANVXhXTHnzHjzOpNJ+ONmE4cbXBtHxo50ck6zbLGevizJvjO5H+YkGjsRvY8+DsKhREwvcax7uJLCw== e=found last=15 s=34 in addShifted_NP", + "pub=MCowBQYDK2VwAyEAQOWjVLS8HFScIrUbwVVgRP5D9jTS52XeaGAuDmxYAxQ= priv=MC4CAQAwBQYDK2VwBCIEIOk2lhkb4hFslloPTx+TmYKr4NxMxUlRnD8PQ4craCtL msg=6TaWGRviEWyWWg9PH5OZgqvg3EzFSVGcPw9DhytoK0t6CFR3PZeN6edgjxrZ0dW1zVP3rgaEqleaFNd8URBEfA== sig=jtRs/UGspouo0iYaFfBd8wa91CSa0pQV6xSeLCnsZluk4AYiVNBWjFZZ9oU1HsPLzdDEGpGbmU193LnedXFZCg== e=found last=7 s=0 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAHpDsS5HdjkJb0dCYT5hhddSm166G9HQoC2k3GDMD99I= priv=MC4CAQAwBQYDK2VwBCIEINw8Y9Rsrb/5kqGsTPwV8STseqmv84Q6YKEcEv2w2ovQ msg=3Dxj1Gytv/mSoaxM/BXxJOx6qa/zhDpgoRwS/bDai9AwMttrMoZdQ4iLnemnlvC0ZTWWwwRPXcEbopP75BvxrQ== sig=3EJD6U6e9fjBO2Ju2rN8P6UK+IsJ2uyLMj4wD7fh2/AHDfwpbFJTZMXsl6EX5OqJ6/W0Yq2nBEA+fcO1zo2YAg== e=found last=8 s=0 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA6DIyqh98QypyNljYuK0Yox+RY2chi22UFMQ6mKbbvys= priv=MC4CAQAwBQYDK2VwBCIEILUJF/RnkQpvBEq73BpXpaAjBEsuCA7SojGFSm2uVZW/ msg=tQkX9GeRCm8ESrvcGleloCMESy4IDtKiMYVKba5Vlb9l9g6m23Tv9nd2XfUwCNrBRtrCpKiOZaufteVa7LXCHA== sig=WRWiex3AumHOjuLndKw7p4OdjJM8pidHgY8YzsTjSjtTtwRJvzLgbBOP1rPqxFF+aF/UqloJclS/gda7o5uEDw== e=found last=8 s=1 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAsOPphmmWs4k9ctn9dMnHIkNZXI5vuvTckkPaIrwiNz4= priv=MC4CAQAwBQYDK2VwBCIEICFqwYdweTEkVfkZ+ffquTocIx7s8ZgPGe6AJdCewL5D msg=IWrBh3B5MSRV+Rn59+q5OhwjHuzxmA8Z7oAl0J7AvkO0ne9GYj1yT4wSeunnnb1VcDxjtZ+w8qN8lBfZDzVnzw== sig=rdFSJFIg0Hqky2z7dPucCjxjrqJQPHk8bMkby0AnuRkKA/E5LLPuMt5EdPMYrCyxXPHK9vSBkwahgIjwS+jUCg== e=found last=8 s=2 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAUpNUaZcL+urJA17UAKo4Na2VoztV/aVyEyQj0SDBjIY= priv=MC4CAQAwBQYDK2VwBCIEINvxglX/8m5YI+eDzCvDM0nRlUlc+qwem9TnZuCHORda msg=2/GCVf/yblgj54PMK8MzSdGVSVz6rB6b1Odm4Ic5F1pDLTRl2QeNY9ip4/jVfe59LnUYO1ot/Mf1FOTl1ud85Q== sig=9EpPk/qHoEZURIE1CR9XJfmceZXedjBkCfvWaI+sGTawJSEqoOrT22xOwVhYbUWviC9WSK5WSZwt2PRo3IqlAg== e=found last=8 s=3 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA6MHneu2YsrotLji+Jd91XULghdgZq5xaW8kjkGADM34= priv=MC4CAQAwBQYDK2VwBCIEIBOC9gDzHHJcD2uJi6iIeysCHFwlwl6fkfW22cuoRvYm msg=E4L2APMcclwPa4mLqIh7KwIcXCXCXp+R9bbZy6hG9iY7oT7Qv8XnP5Vc4tZMvOeWDFf82LQleiHlZO0p5w881g== sig=j3k6/eCF2wO0x83LpLHD4Dmi2HCrAcd0me9QL3y8AIbRiutQJp2s/1Jcp8tRTaAyrLNY1lcPWuFEABMrzF1OBg== e=found last=8 s=4 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAJbm2aEiyqpX8lQvQ/f30pAd3anLtbpdVRcMl+qodWgk= priv=MC4CAQAwBQYDK2VwBCIEIHRcig9pYtmZZq/jVW/nfTy85QH1mbViwciYy5fCq1qR msg=dFyKD2li2Zlmr+NVb+d9PLzlAfWZtWLByJjLl8KrWpFE5ir3WAxzitYBUmfKEVFFQrS8Vazb3lE9V3X5aZnXYQ== sig=21WAOMBavwYUk2pkYkW5N4wLK5QNEhspiX9YTpV2eWciPF/nu20U1hgKRWRilqfWNjs40C1qTc8Bk0GD+EfEBw== e=found last=8 s=5 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAmM3/Zggp0aOINx+uhCmCIcTsi0k3fmMSgBPTmNrSaYQ= priv=MC4CAQAwBQYDK2VwBCIEICfJ5oMNeYYIEmcbLP25t7BF78SNRPL/J85/i/uecT49 msg=J8nmgw15hggSZxss/bm3sEXvxI1E8v8nzn+L+55xPj17H0rPKN6Z1KDATr+4NliCZqqKhQZZbtiqoJOZtQsapQ== sig=2zvO7FUyWl6Owov/MOz5i8AD/Am9fE1na5lj4BJmCQiWkcPIi26RXQG7rkZ+pPWMz61g3NdwRABx4E7gASzkDQ== e=found last=8 s=6 in subShifted_NP", + "pub=MCowBQYDK2VwAyEADE6T1shUGBsIc3CImli1AnfE2K0u4+OGbUZjPMGgQsY= priv=MC4CAQAwBQYDK2VwBCIEIMWzWhvXzzCvC3O42bY9uM8LCEPxpQbCXxdHb160h6AX msg=WhvXzzCvC3O42bY9uM8LCEPxpQbCXxdHb160h6AXa4QHMXbIx1KTqyhmmTzTChmMIpKgj7H1Yna3dqNYJAMqcA== sig=mKKQZof5Y9VGkqFEsxwDHk7B8VEN3us8I04xqqUDYC92wGnnanHlKAwYJbgxa0n7oFqzduJk4tto+xOsnVv1AA== e=found last=8 s=7 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAzpSqMVjUK8gtPguKb5kMa8efjbfnIKsDFIHjrN7qBmg= priv=MC4CAQAwBQYDK2VwBCIEIKIlq7DD502/di/TdOJUV8vmyhS006JckoF2gVwpUwOk msg=w+dNv3Yv03TiVFfL5soUtNOiXJKBdoFcKVMDpPnqXJMPC5yetvVu42FzW3t4NOADQA8Wivsldxdui28//itMxg== sig=PhZ2Ijp8mQbM8+wHdq50wbLCxErrXPj/1HaPQ0deWK/JPMM1QAAbbvjTf+zUFUEGCPqvSj9IijwwTVPaO/5mAw== e=found last=8 s=8 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA3rrp5Lk2ewftAO3z5nG36OhfbjpB7XKpr9kgzVRYROM= priv=MC4CAQAwBQYDK2VwBCIEIDxxFhXb9jxcvIFcS1TLTN4bohHnXqVajuY8TODG5dMT msg=PHEWFdv2PFy8gVxLVMtM3huiEedepVqO5jxM4Mbl0xNcqFt1yQvS22NFttzVXhiHfe4caoFf+ZQWGh3WY9SbUg== sig=/+Sgwa1h5dueYC+7h5byNCLiah0kGXxtmni6RQV9Bwc2hzurbl/QcAINduZ9WEqZNwds5EcUeRsWAGidwZN/CQ== e=found last=8 s=9 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAVnMG6RGk0i5P3WqJ2aG9UK+M2ca/55Aea6g/+l7EUww= priv=MC4CAQAwBQYDK2VwBCIEIDW2QadQ+qZPFQAX1IuQEn7B6qSL9S+YNr39YcrUqXpu msg=tkGnUPqmTxUAF9SLkBJ+weqki/UvmDa9/WHK1Kl6bt9UABaiEWsrQtfYQXfSPsiQd9yBDR5pak47uCj15RAEsQ== sig=da8aZTRvOpgUsPborKnMR64rUxpfzK0rpe+bQHStE19ycwN64UqZ6ZwTpSd61wVXf7UOmsnduyiBGxDyH/KrDw== e=found last=8 s=10 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAhzR1lBSAxLgzh+GOtDL0SmEROPHyf830DoknO3rZSCg= priv=MC4CAQAwBQYDK2VwBCIEIOLG5d/aLchi6RU49063TRpIzFe0GEcGBojNcUQz0YQm msg=S7fc3vhT3HVYeueii0Kx3BCjnIkRHcf4aoMI3JkYSqBZRcTAQNtnXuzOBVbQ8BYNFEFVzk1OVlRiUoUR6P8z0Q== sig=bGDjgYraskpAMLfFreimXEEpLz3k6Y6raYj6CMe0g2PMTnXjTdlZZiAkZCxVWt2aYgR9Gi0K6ZbxP1Nqt9brBA== e=found last=8 s=11 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAvrWfI9fDJcar/1uHZc1ano51EwLz0IWUgfiq0MX3/M8= priv=MC4CAQAwBQYDK2VwBCIEIPiGUJusC4PuuuVHim7ESYTKCA+m+S0C9sPILIBphIRi msg=rAuD7rrlR4puxEmEyggPpvktAvbDyCyAaYSEYmkv5YsPb1jOtoWaSBe0SOxur/dSCZpc2JyPi4k7j6bdFdc7Xg== sig=rim4EnMXhZ+TOBWZAJqFnNiVC7PZvMSG21NHfILXtmmrUVtwGjE49RYKgXKQdS2nOtCUri3cIYlKpDx/q4mjAQ== e=found last=8 s=12 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA5aNMKVfRETU4dms585gbWhEaAZqd0vi0Ej8Ps9zmCB8= priv=MC4CAQAwBQYDK2VwBCIEIIstCfgUrcc4sLn1ZtzmathKJalmBl/IiYD7mwEALK20 msg=rcc4sLn1ZtzmathKJalmBl/IiYD7mwEALK20iBOFU0n3ttIytnsb5T/48qnXmEt8K3Imk5/5sHTV+QrtKt3Kmw== sig=JIfvFOG417/+2nB2E6wBvhEygUX0M20x+Mb/4iCFwWk7nqgx/PdBOtW2BEWNpQ4rL7pI4GDYoeyajiKH0gy3BA== e=found last=8 s=13 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAYYrBoQgHnuS3levk9v+0dHzjjgwrqbzr1md2BYet3SI= priv=MC4CAQAwBQYDK2VwBCIEIM82wQ8CANjO1CG/b1OTQaYbZ3YsHTYm+XsYep1W8GSF msg=+XjLwCOvHBXSd35Ir5r6HwxX1I572Q6fqS8Ox9m9Lr3GTYMWFmP8VBqRlB//wzVL5Hu7iILUcnUtSluICXJO8Q== sig=OTD+joRNVjBhAAkd/uWYPncrS/2W0VvMO/FYJfeHDDKkYt3lrf3N2vkeS8qz9Z/zQU1+KdtqRfvFzl3LgOhPDw== e=found last=8 s=14 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAIKBZnfaaVcEBa+FTJpmmHBcf4vcKcO4+5v/iXFHTpDA= priv=MC4CAQAwBQYDK2VwBCIEIGlMcS18gSEMcGEO0pMWxVuDjZVxdEcvojU+kcm+uKz3 msg=gSEMcGEO0pMWxVuDjZVxdEcvojU+kcm+uKz3DwyO/EHrm4tedZuam0lavgl5H9ofO8YSXRb5C2CmcNEU9clpaw== sig=RHIkpNTnWwMw6heqe4RWysE56S3KWuJ+ysaqS/ox33F8Q1BwSzdI8Ibw50hktTQh4cjJ4zo8R8M6jsz2eULaAg== e=found last=8 s=15 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAst0qEVaT9cx5EsTjMMxhbVioLL2SKylkinapAlQDZLQ= priv=MC4CAQAwBQYDK2VwBCIEIJS8U83Du3KYhZFU1epgqTPtXhg8IeZzTcPsbO2hiSe4 msg=C92G6vybK0/OB9IVLBiqs5edD3hzE59d2jKUvFPNw7tymIWRVNXqYKkz7V4YPCHmc03D7GztoYknuKwL6nT2Lw== sig=to6o3wB3LzyrSDLMlx0xtiD/n3xFvWDFhd+RcPtIWAhN0etBXzQ2/I9hMGPRIH8kiZR/EXX25iySlLjFCAe+Cw== e=found last=8 s=16 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAF9BYIgRPjgjjGcepOMo/AiqnqiVGqMSHpyHuONz3bR4= priv=MC4CAQAwBQYDK2VwBCIEIC6nATsPKaLuyByUlYebKymCbWfW68VERpxTrGuBCwlQ msg=LqcBOw8pou7IHJSVh5srKYJtZ9brxURGnFOsa4ELCVBtOlDCn7WU/PMKvzvaRXlYuePfKlexOuzBhjxWxQ4AAw== sig=ahGLVRQkrSRM9ZrBqAVqRZoBYedjDEIsvpzTbqa8KrSZsMAwt5q8OzkiyhKCyYxBcAc4XHSszkqw5inLN/pQDA== e=found last=9 s=0 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA2/2e6MYTlS/fclD5T/kdSX9oWCRGPmYsquX09bu+j4c= priv=MC4CAQAwBQYDK2VwBCIEIL+kLt0ceFxI48cdPWlA4W0TydbErsV+b4MILG+ybLc2 msg=v6Qu3Rx4XEjjxx09aUDhbRPJ1sSuxX5vgwgsb7JstzY/4lJOQ99xBJw/s/wFZEEV89wb7yzMH0qLfm/CY1k1AQ== sig=GlN+LGpJelxKsro0x4t7fXUrDmh7kmZywIo8Fts9y9+dIAHdOTnA2PA3z61VfbEEJYUej3cZa80Z+VDeNzrACA== e=found last=9 s=1 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA5LrjnzRFio/PIEWVRa/l2N9/r3k3lffCpvPId8IlBHU= priv=MC4CAQAwBQYDK2VwBCIEIFr9mVmLBHlMFusTtVzWhBG8xMK5zQmGvqiB/j1pFZHL msg=Wv2ZWYsEeUwW6xO1XNaEEbzEwrnNCYa+qIH+PWkVkctr8cmdBbMc2NuHMi9/TFAy9B/5MtpMmeQuI3phoLZn2Q== sig=9IudH4UABWyKIDvuf+Q3akxRoAvSoSs1YAcmTEysGygKIvuQeF4XPLCKVFoOwL4/znR/hFJ0AnaLdaw9xbQpBA== e=found last=9 s=2 in subShifted_NP", + "pub=MCowBQYDK2VwAyEALDhuzQrSuz5AEUvn/9FYng2aq00nrlvSxqyZJZs9tBI= priv=MC4CAQAwBQYDK2VwBCIEIAP0Zrcs2xicBhloCCdwgv0eP+kVkF3iW2ZyXEHgmISb msg=A/RmtyzbGJwGGWgIJ3CC/R4/6RWQXeJbZnJcQeCYhJuDhaaS5OBZrjdbJdzHqGd3LVOagaNSxkbsjz43n+mdBA== sig=3qXKA/IggPNDtIlHvjKSQl4eUwKd5f9aoqeTJ9Si9zzq/r7UGaFKCIlP7mBYcqZv7Xf33LXyaqxc3o4OBFBmDA== e=found last=9 s=3 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA/4uf/6NIOriyqDAMmAlVFMXvwfTgjMOoBYjs+a5P0oc= priv=MC4CAQAwBQYDK2VwBCIEIMuA+RdrWI5yIPOBFRfO8Lst9vBakrBC9DflgiMvujKg msg=y4D5F2tYjnIg84EVF87wuy328FqSsEL0N+WCIy+6MqAhTKXQovvWKFoYCZGQl+oG9ORLylitK82LNPBNhmX/Cw== sig=LnDenkVBWLSds2Dz90TRDBnSFuYoJQXSMj4ptCMfBeynlbJUstLTYpZA9m9uZZCPHl6nfm0J0p9sGYJp/zVkAQ== e=found last=9 s=4 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAiezuTEFbeHb4ImjB9avUZ/nA8mgsXkE+jy4MZ5oJ8ME= priv=MC4CAQAwBQYDK2VwBCIEIGR2rV16B/gWo2blA20GD3M20YwIwa+CcXB6o2qLy3Rn msg=ZHatXXoH+BajZuUDbQYPczbRjAjBr4JxcHqjaovLdGf/dXxC+gbaYgEuWlaoclAOBjtRBYRWeqVdsVuewV9baQ== sig=3DQSYaBxLr+a/L2B568XGFIaXS/QM9KTEwXmKEDeD8+3zUJ4IXCJdU7yyeG1727PX8lllDKgcpUrJtEA/jYFDg== e=found last=9 s=5 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAcapOHuRQJfvaPnaOn0sxRRTW4Qmwze27fX3VYrSbu5o= priv=MC4CAQAwBQYDK2VwBCIEINRL1nbSNhRX6cAQ3jOuhd5k8G/nloedR9226gmLgUUn msg=S9Z20jYUV+nAEN4zroXeZPBv55aHnUfdtuoJi4FFJy8Lfc72pNo6cyU3j3a54NhLFW7os1REBEgiHSZeu5Xnrw== sig=6vamBUAb7DRAbYNpDhnoKYbXrX73juRu9DKEbFu9AJvsrlWH1NiXaQ/EoRjE9qt3vAAZWhO1h+InAFfP170UBw== e=found last=9 s=6 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAvlgouF9o+BIa0+bSqyjxVHv8DYz7EXiuf/Mo6IuhaBY= priv=MC4CAQAwBQYDK2VwBCIEIApbBTashDtYAboqQbj8//vRgEE3l4JLCUKNouY7qzik msg=ClsFNqyEO1gBuipBuPz/+9GAQTeXgksJQo2i5jurOKQY+su/SXwQUwt5eZWhbOuhSatG7FR6hUAbNQC1EUvjgw== sig=i5/8rX8bQlxbOZOFa2Wg3HXg4ygclmXDnZ/3H9DwBLCgrCHqCp8nO+0vgqnbFG3thCGQie2z4P1mdUGwvg9XAA== e=found last=9 s=7 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAZuTZg2F7egDErwm9ru3QUUZnr+0LAhcp4LHbZSptgts= priv=MC4CAQAwBQYDK2VwBCIEIDsPm477mNXnfkMvE96DPJBm2NmmazyBGYinLp1E8IyI msg=Ow+bjvuY1ed+Qy8T3oM8kGbY2aZrPIEZiKcunUTwjIjkO89kMLWLpt0XDPV6pDX2ZPBgTAVS/uAA1uB8j/j+JA== sig=DBfVPPdm+KzlgtxddC0L4HzVvmCk9shkVem6fBKxfQVuSCobqS5b6nVGJU9iHwy1smcWcv3bN6/4EGILmd9LBg== e=found last=9 s=8 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAgQC2vVXNQTuxDzy9YGFD0MpmlTuV2ppV/h0tH9idkN0= priv=MC4CAQAwBQYDK2VwBCIEIJtoxPFBO2sScb71Hr2DbfzEkq5qTTzaWwI/g040oW43 msg=EnG+9R69g238xJKuak082lsCP4NONKFuN13bl69BcZNHGgPpPLvyXt3okmAIsuBIDdbLZKDLCVf+PK4Swpq7ug== sig=mwttA//XS/Wdm7uiw9hIceA2Wt1thjfP55u2d34QhP9abyQvrF9cEMBWpKo7IePZlYjYURHwSUoiA1bQ1nAHAA== e=found last=9 s=9 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAq16R7SY4zHqSbN1YqUCwTJGTceUfPgEw9XbGMXjZL2M= priv=MC4CAQAwBQYDK2VwBCIEIM0h61oL6U+2x1Zxp6IWztJbSnHcoVsGuLyXWwHBEIgs msg=IetaC+lPtsdWcaeiFs7SW0px3KFbBri8l1sBwRCILN7xT7qepRnWuE5triy6kjjMh2whg9oxZw+bwiembws1IA== sig=6tz5M1lAtk5H1NqEIM/Dpw6lG/Jtcf9HzDT1+LeY3fOoCIb6gVBHy25qY0SPRzQWX2HbnVYfPQq/nXmxTXrKAQ== e=found last=9 s=10 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAQB8bc9JfcTpXsHfspyQNHuVP7nYX84QNvGQMQepnXQE= priv=MC4CAQAwBQYDK2VwBCIEIHImrYbvFifg0hyWyaDVqLo2P3eRcBFhHL4t0d3ATOcu msg=UZ2K1Jg4CpmegQ7JTwzGhx5EwNBqsrNP6z1WXniKp1m3E8W7C63BG8WZ73aRVfBoSYPg9dOlG6mxcJ5cle6xCg== sig=aRepJNngISeBdgXQwp0XDK8/qPuQsIzT472Cv3lmMQOm1/flXFOObTx4ti1ypvdcjzqVtd+sUBVcxPzsSrmRCA== e=found last=9 s=11 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAl9AaTm7z4+4DiWdaAPFud+Hv6Aa5Jxs2jaOuDvF4t30= priv=MC4CAQAwBQYDK2VwBCIEIHbZctga5S0B42NKIyQqsGBOC40GI1NGB7tr3lAffJga msg=GuUtAeNjSiMkKrBgTguNBiNTRge7a95QH3yYGoUTh1cF791CXmJbyIol5NcRuzxIyDueFn5OYK3Ze7mS/mYqTg== sig=VXGhE3o6mO/Zh78K3Z3Lcs8/7fMMBCPU+CzRnteGPcXeJ2qpO6L35KIf0XDx5nY9Tkah8N3EOdcWr4d7gA57CA== e=found last=9 s=12 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAYNtC7mIFJzbH5BscQpBMRHpfBG6lawnVvH94GgMY0Qk= priv=MC4CAQAwBQYDK2VwBCIEIOLVcpGzikOrIi+ei+JlrJ/I8PkcbZ6ag2awevTNgJzz msg=yPD5HG2emoNmsHr0zYCc80k4Ie2c20n1wiX/Ki0KuBeDnxf2CkdQYzqxYh6LcZUYlk74t04VUwReiVjE2rTI1g== sig=HCrJZDl+4qRxut1p1JohrVxOiynq4c36GNEeKdMHJox3nmHbtj7i7opVwZWPS0cG3Qfgu303FiF/rEVBwY2nDQ== e=found last=9 s=13 in subShifted_NP", + "pub=MCowBQYDK2VwAyEArIx5QuNi8blTY8Y8nHKr3KkPyQE36qBOjFPuQpT8rVk= priv=MC4CAQAwBQYDK2VwBCIEIJ7WPauRIJmLPGEtDrBV8iXvjCsEaHenWO7QsivxwGoA msg=1j2rkSCZizxhLQ6wVfIl74wrBGh3p1ju0LIr8cBqACp5bgS/XV9ENJdisO05yEDGePDAj666zUyKyxnswwVYxA== sig=K6Xq5/z8Mg+tE8cB2hLCV8avYSzY28cfMti70nP9IYET9s5qKTDsNZ9OhobR4e5TN5EWAt3c86D8N8O3Dit8AA== e=found last=9 s=14 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAXqLF5YCe/8P3L3oDlinVgMoRXY7t22se79RPOxFWoNo= priv=MC4CAQAwBQYDK2VwBCIEIHD+hcwKq4bP2K3VjZL8BfXNNRJ+nuN5+8LRZ2s9Nr0f msg=Pal43Sb4LavCS7gzX3Ux7lkj0mscShmK2ia9qylM3AxWxwuvoH6fx1rVirBlUNxb0blT1u4Q0cGyGQimntC6MQ== sig=P/UjtY1ZuGH5fqlmyfq6XAhd2l4Og22vLf4bQ9ykQLf09LdF+o/AGA39ijjT5g+SOocffQQuNmPfBCUmmWxGCw== e=found last=9 s=15 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAOEAxBV3yl8WWPEb9pHVApWWayBfYLb5IqdYf26uWiu0= priv=MC4CAQAwBQYDK2VwBCIEIGmx55Ykg0bNw9GGMWflsjY7wjajw6giKITEpqNaHpKO msg=I9tk0/EC9Rkc1eJz2DiR5Am4Q/QgX3Gg1mOqfZ6SiQ+mkKDjhBDBIzKjk2o0hejD8zvBT0OUT+KCtF2wF0f2Bw== sig=wzqcrj2Ji+oIMZONjxK+T4PNG2e1Y7UYnjbgu2wJiI/5KLYQXR1MU9v2VLq0hB9nzSGNegbcxezdWeH4DiXPCw== e=found last=9 s=16 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAFQaUhfymR3LFT/Z9bKqO7WCbd50QQgst0lJKq9/0JeM= priv=MC4CAQAwBQYDK2VwBCIEILW+D5MYorzzwXsKfrVSV9S7ptVNwydnOku7PYBjjwjM msg=Oku7PYBjjwjMI5GMuqKjGkwOU+HWde0dC6e2dYR/yhGDIGffIWLULoGEUHAjKLNV5RsB26D6JRsg7lLiwz0Rng== sig=f5+BuLBHJIwSfKKuX6c2XrYeRCkbAp2lbpBziEXX+dRv8wT+Q2511YzpZS4dkzovW1DvFibhsnTtrQP80OebDg== e=found last=9 s=17 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAE/Z4qCZf6oeIHPVVWG+AMN/7hfF84KomkN0DPtjcu5U= priv=MC4CAQAwBQYDK2VwBCIEICpEqkRkem6SBSBDYSkw84xk3Q48gWiBi11aNw8C8P4Q msg=aIGLXVo3DwLw/hCfctR6nmBIqEo8LURISYsQm3YG2UH+CoE48HuqAJ7I+RW6BQ1PJyM9rmB/HqnpOHV755lZdQ== sig=niWBPhruKdRYBojP2RO/3idMKWzcNg8SsFvlxpnjxAF7yMtGoCqG8RGnsPQGmUtQXyCXXyG4IsXpUVxdz/XkCA== e=found last=9 s=18 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAp2itvPl+z8LZEbur+hJ0qthBmtbb0SABFfXYGei9Mt8= priv=MC4CAQAwBQYDK2VwBCIEIDtBd1vcebTMWI5jKpP4CSMbE4CMKDlN7frmxsPIsY5+ msg=t/ICSwiQdTB89r7Ybjt2TR0Vz0OLwORTUg7HsRs8WCNuj3tHuhIdb8Sl/XBuei3KRv8E+eRcyUDnyM/YFMkvFA== sig=ekG51XRwbjU+AGVBshsXoPtCuWX2RZ0OOeZ/J5yKCUwo7Px0VM9UN8j0P1/kVd1Tnf3avRzPepRkRgrKGrTxCQ== e=found last=9 s=19 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAgRp52AFYgvlP1JbkHz7p9N2qgcnlwZxEnPWZ/KaI9eI= priv=MC4CAQAwBQYDK2VwBCIEICvx6H2vp3hPWxGqnyIkXh8zsAJc8Joo4na+HNL6P8ex msg=JDVF4bKKKwb98m2gTJXDRKamziYwXX0PUZOuzjitk2zqQvzGrL9b9Wf1nZ/+g5vbSy9CQtSy9nuJ7AWLILI8NQ== sig=Et5DMmrTGzxU5STwmmnVNBT3fBIsngzwnrh5QU+KChbQf2HdaVKEsgd4EvoNcBGhDfrYEwV5ycpMZ+PxE3YjCQ== e=found last=9 s=20 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAGr4yocDhLIrOL6Fih/BfAUU+KklJrIMM3TpCnVzzgWE= priv=MC4CAQAwBQYDK2VwBCIEILPGgkNbQR0X9wWDolosXqSmu/jd8bH+fPDfoDPGaLo6 msg=3jrxs8aCQ1tBHRf3BYOiWixepKa7+N3xsf588N+gM8ZoujrbvUebmYrEleAtdlOr43swy/8MYLCkNz5GQ00axg== sig=jcwfGCuTTMn98NhLnEo0lmC9tfdp1mZpn/qa+ZgESuiEcKd/W+sWMoTnBssWFPpl5cK2zzhXa42Mo+6XqQyDDw== e=found last=9 s=21 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA5f2OsBUMpgJSBiBCud6CrDgOb8fnb377tHPMUAhpku8= priv=MC4CAQAwBQYDK2VwBCIEIPutBae7XSWWEAdKXgStcba2lAxKuj3EkZHfx1/8SDgq msg=seQGx5IulYVW6f6hBKu17sh+zWZB4QPl/yrUNOT7X7hDo6luCD9L7Oy4E6McgQgxG1jGrcNW61OwUrJCZ4ZRCQ== sig=ahmRLcvhyH0cJm9pMIYk8qGyjXLYDAH/KCQ4ab/K7+/CuuIP0ToudxGrS1JZ7/XDP6sQmwZTKDAr8X1Nf1oEDA== e=found last=9 s=22 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAfxAUfihFrxF+OoD7MdELWILMrfb/AvXVQRV4/WpZpy4= priv=MC4CAQAwBQYDK2VwBCIEIGRdw1PBTNr4L0Y/ggMNyJNnzpO7S3N3jBzVE0eauyun msg=HNUTR5q7K6eXuv6GnsgsOtlH4Jpd8I6JO0Uy+gGI59l7TZFkJbFseqoU9+sUT2w6TLZD2uKoIwC70VRKHhV+Ug== sig=Hj3XVCdcgrPql96WQz1pWC9+6/zZDMguskKjnatNbbe+SRhybK4jlH9Nrt1ZhcdgTvH9lKY4TQkkoTaAf7PhDQ== e=found last=9 s=23 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAzDtAtFRvYELDx1foLwQCUkNtmnUgJoejAlAntzrtpg8= priv=MC4CAQAwBQYDK2VwBCIEIGJ2eiKZBHCxD3BDtnqhjvtKmwyD11GUlDHa5zIUCLjj msg=LPUJGWzXpoaBYnZ6IpkEcLEPcEO2eqGO+0qbDIPXUZSUMdrnMhQIuOP0sNgKvE5pPd8fIdb136sseQCTxGcqqg== sig=m41sd5J7phr0zo8sA2JwvjTXvFeqKWmkEv3iGjA7jG1doexlb8tsaybfA87q304r/MbWmhnba9x9M8SmWSwYBQ== e=found last=9 s=24 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA0qsVQTGTq74sXPS5OLIUecO1pxPwfL1ajdjUqZGai1I= priv=MC4CAQAwBQYDK2VwBCIEIH7sYVrj8OvzYSWFpgEWtDDblIQ0QsI+SamGDyV+4keL msg=i4JPUhxAxLpbIlHkDRQJW1aXhZPiSciUQHk07NMeiClz1GCxXTlcoNTrHDnLpzNRVgXgbKCmDycFc3Jrwx5NZA== sig=wmo7yOCWzACbwNcs4rZHP5EO1br77Qlj6FuYxa0yINgVbkzjSUrQHsXm3w4PmIfmIKfKUHn51d5o0tvdWcmRCA== e=found last=9 s=25 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAnPVRZZBvdMr/6Ljg7698FsUe/AKz0S2jOwnTxRcSrY8= priv=MC4CAQAwBQYDK2VwBCIEIBG0ghMCkg8xEtqJvZ3Ep6326QHMjR98csLWqfSJ5tsN msg=U7wqAnTkfLP53Xt7eMEefyXAK5ajGzaS2oqOCdhDt++kEbSCEwKSDzES2om9ncSnrfbpAcyNH3xywtap9Inm2w== sig=/pPkRkGLs5RAM9bxB58TGeYKixXg3AnPFzmrMTbecK3PmGrSMmybD8Juc3/SOMlbndGdk+NoFBWrr4ZXwxQnCg== e=found last=9 s=26 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAZcVHB0GNr1ZlO/ytpOnSDIo/Cr6Mi6wg81NlOaPnzFI= priv=MC4CAQAwBQYDK2VwBCIEIAJLzZvYPnnDp4DmQ4ZNfun+5c7VdXfOT3gBKz6/LYKP msg=IFAoxlib8/GnBwJLzZvYPnnDp4DmQ4ZNfun+5c7VdXfOT3gBKz6/LYKPIzhIHD+OnsiKHjru01CnS60kqsca6Q== sig=Rfq7a2CeEmVskDOImTW22O37171rT73zgIQuOkjmfQvGmHSF0fnspAG8K5/9+rHc/HWinOl+3UfCDrRzEm/3AA== e=found last=9 s=27 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAziXMQbqrSktGT7LW6taCzNdW7XNbuuEqNAK40Rd/NJU= priv=MC4CAQAwBQYDK2VwBCIEILKtyuK9Uy3jVcMsK6/2ImFMn/6uDa5ebKPLnFdAMfbb msg=Arm1CatqrqQKhSGQiQ+4E6u/Sx2lQmzXSkcE+9zB51+EgLmognmpO0WC+7zF65FoSPeguNQJJj1g2KGZtNKyrQ== sig=5YMzgOk5WGGx5tkVNsuy8qBm0TP/X0su5eJ649NRrASrmtakL2XsyX94xzF9HY+nCLIU19P8mx+w2pf3x8urCw== e=found last=9 s=28 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAQ1kddGvQTMAgOjWas4On5RGX6CHYKq1Fv0Wea5cymh4= priv=MC4CAQAwBQYDK2VwBCIEICgWHAFL6sul67ikjzCPUKXyIs2UbLBxenNYVIie4fmz msg=ajyHSaNuFPZhSm9YEfKe8ceURcsv2CgWHAFL6sul67ikjzCPUKXyIs2UbLBxenNYVIie4fmzFyBB5/SkK02rWA== sig=RcTjC/OLHdV2Ibo0MHIpi7zsWrX4Fm3kibDwqLi0s7DZXeIQZKCJNRC9uMs8mSJVknS2ByYMnXR9VU3OKg7VCQ== e=found last=9 s=29 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAPdyeZEgaGZBTsMHVZ/iuF2dm7YddC2G0M6aI9Xr1hyY= priv=MC4CAQAwBQYDK2VwBCIEICiSKpY+iV1iRsSI1GNfJ9qsv/R50wCvd9qmVYA0BGt+ msg=ACdgOWUd8/aF09Eoe973ptmFo/YBU0LAaVKLj3jp2qLGh3egrIdPuH06xZY4NWmGXRqIPfdo63hiARet8hbnSQ== sig=7AV50j4LsmeSTR7fu4dyVE8DQZG/o0vIJFtfxECq42twOCkBkEe33tDdA/rflGk4P5KVgSn+Ft4acSV5rjnyBw== e=found last=9 s=30 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAFwl779AGyZOuTckZiLjkFjopLrDu3RqGGGFzCwl6QoE= priv=MC4CAQAwBQYDK2VwBCIEIECssVGO8t+3rbYsVzgeRAEfoyG6pOE5qrKe5KH5Ht/P msg=PCJz+NqJFFtOtAdj/3ke50Jny9/n/4IwE9/MbzaKIbnB2aNfeeK2+vHSZdTKtLnLIODU42R2ACradiIXSHmesQ== sig=8barku2yA5fI65ciRLnY123X6bLzQ5pfjYOv4r+fNjI+PNSF8CIHGT4t60c4Sn8kzxMKqPvr8q7jHTDoO9UZDQ== e=found last=9 s=31 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAux0QdGpHw7g5xdXeEP3c5F81QNgJ5lg0sGpvRl7su6w= priv=MC4CAQAwBQYDK2VwBCIEIMBlU7/jsfYSHUZczt37mf8VplawWGvjRGRoSizYNFTC msg=wGVTv+Ox9hIdRlzO3fuZ/xWmVrBYa+NEZGhKLNg0VMIdOvqggtBkBI8FHQ8IYmWRltIjayXMiLBNUIzUyTv5pQ== sig=1EhkdxeNI+UIRnuOxjMUqWaE2e21JCTG3nMKOaHOio4MFmuEaRAUzX+Izb+SxlGhGBotSsnynt7UcUfnzzKxAQ== e=found last=10 s=0 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAWgNXkDjSowfnL60s56uX4FbZVDlgCDOSFyk9iYTKvOo= priv=MC4CAQAwBQYDK2VwBCIEIEwifddis+k/GKVBNqU2wVvZOtdupq0IJ/mc6oue+wgc msg=TCJ912Kz6T8YpUE2pTbBW9k6126mrQgn+Zzqi577CBwnBPJIIjOThqnf5OuorZJk2BtZESWT9ERTUMwjDYTF2w== sig=2ROjbB3L3zVI/DJ919UtL2OYVRrn7S/tNv10Wx47j9n2sIfoDpasMfiR0DWaJucpD+3GNBUa7GydUlfvtlUiDg== e=found last=10 s=1 in subShifted_NP", + "pub=MCowBQYDK2VwAyEApIBh/FC3g4vIbMbcQWqYfj51K59JqWeofLR5b46fFpo= priv=MC4CAQAwBQYDK2VwBCIEIPWksiz5hqG6d8fYPc5rB9rcJb1pPhesvP59xFGjiix/ msg=9aSyLPmGobp3x9g9zmsH2twlvWk+F6y8/n3EUaOKLH9cyMeGoO3Z6r8URiSc5D8XpH75535z58yz9yd3d4p8gQ== sig=d2+ayYh6Y+P0gpNMac4eoAozdOucvUue4xM/8uthI+wmcF2fIIHl2j6T8xxqGaXC8T/SJtv2wcUHKSnemIKBDA== e=found last=10 s=2 in subShifted_NP", + "pub=MCowBQYDK2VwAyEADMWR/8jaXfLeDy9DPGZZ8nA1PkER6gZ3sdsIWs2PYO0= priv=MC4CAQAwBQYDK2VwBCIEIKsXIjNDeEupOj0wfbhVBSqjr4/gvBwK2D9lifr7+Kit msg=qxciM0N4S6k6PTB9uFUFKqOvj+C8HArYP2WJ+vv4qK1SwPdOkMcEzeuUzexl7ToCFjmJ3In2OoFgVX3kBmmgUQ== sig=RtFX/iwyi2Qi5qy3oYJflVKnYfYo7CSvfuoU7B7rkAQV74mpwRKnlt00QZQY7pfPRYSeWO6xnjVnhx1CkIOeDA== e=found last=10 s=3 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAmltWbwWUy9NMvrc5ToATVFcansSKjM9zhwA0L2cXbs0= priv=MC4CAQAwBQYDK2VwBCIEICDsiD0J2R2DSV4zWuruN4ShoebsIyOuCKk9a/TE9kns msg=IOyIPQnZHYNJXjNa6u43hKGh5uwjI64IqT1r9MT2Sewgw85DQNrKurEPBy/s6NKyvhyYqm/tZMeEqlkwrEFGHA== sig=YtS2X6KU/8g7T5JolSFimvm+ZfrikPci0ZpQ7n1Pmf2TJRyq8apLns3l83K6JuEYy9j5iwd1V1O3wWFRr/whDw== e=found last=10 s=4 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAxFjzJFwpBCi4vyiCldIe/wqLsdqUETPxG12bqgmFkBM= priv=MC4CAQAwBQYDK2VwBCIEIJP/WubHI4vay4+WNTEsCyQL4dfuc04ol8OrCeWALIyb msg=k/9a5scji9rLj5Y1MSwLJAvh1+5zTiiXw6sJ5YAsjJsooNj5n9Pk2Z5A1ONu6WAFSoacmqH38NQaLmrqE4+Q+w== sig=8noKM41S3mUrarvqUkJZqMEEgdD2TOy30AxT2H3Cuu8ajZI+RGZ2uLNkY0iU2uoFI9zWdB9fD4YyhCLlPOTtDg== e=found last=10 s=5 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAJNZiqeKDdEN/60h8/h5VNp5MKDiaV7SpLgWqJaVY9ZI= priv=MC4CAQAwBQYDK2VwBCIEIFZG+2ZDxTQ3ep3sjprWdi7+Zktw8wM9onUWsK82W5Dp msg=Vkb7ZkPFNDd6neyOmtZ2Lv5mS3DzAz2idRawrzZbkOn2titaNOGZoQ/DHJkx9xZymr2Iu6d8mrqyl//blHgyBw== sig=qomdS3eH8RXoTU7QdwBSve3eiPMFUyHYHDl/OH0rld8MPjwc2OR6rEZBkSWe0kJwsSgKEoiXllrLVXF0iihWCA== e=found last=10 s=6 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAY4loFosEnwKOt6nByzs7UToyZaVp95nnx/ypCsaLC7A= priv=MC4CAQAwBQYDK2VwBCIEICa6sOopZXCzd6RY8Boc2lsMljiMOCY1JXa92LXjEgh5 msg=urDqKWVws3ekWPAaHNpbDJY4jDgmNSV2vdi14xIIeWMKJzpqMngVxWu7+19eWN7hVPGup8gKFHOaMCTR2j4Fjg== sig=OBBtVEIGHkDZjJ9LcN2Vv8L1CnFAS0tcgz9MP3DqAFfrACxuk5AbBwzmEr+K7P0wxu6F45XqKEnxUCI6LOrWDg== e=found last=10 s=7 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAeK9TopfnLXAKfWAeucHPLjwuaOXBWTOrZpXne6RnlYI= priv=MC4CAQAwBQYDK2VwBCIEIClHNDhsdxEN3UXY6nGeEvhqWOzVLnrusNSs3HUKLixH msg=KUc0OGx3EQ3dRdjqcZ4S+GpY7NUueu6w1KzcdQouLEf6gSlD1mW/d2ukwkAZys2QwHGWGHWJBowJgs0zFsYUeA== sig=3YjGEsFc5P/Ml0cVptAQars21uZBZiDw4/dAiB3AMb7iagW3oWTIwfTsYMkdOmpupe84UzZiwMHRhfUMZKWrAA== e=found last=10 s=8 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAVJ0/i9GDUrDLGZ6k01UkPRG+MIGBGfgtPPqWNWHSJsQ= priv=MC4CAQAwBQYDK2VwBCIEIN+4iA4p/D8M0s4s1PNQc3bK0ld+TI+EFKOdIBmE7ajw msg=37iIDin8PwzSzizU81BzdsrSV35Mj4QUo50gGYTtqPAu+smYjGjUz9bvxAlSZH834FsmGJ8VKulF77YzwcqDSw== sig=EueCyMZ3Dyjmk34mzABhS5aLzfxMX0prekL8hHJo85AjAYyC6v+7VYIB8TnBWq0I8g387QlvOFC9Z2vjjph4CA== e=found last=10 s=9 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA5Ap0u1ciQAJyWF2Nq5AIgppaoh2tikn11CGXXov+pkI= priv=MC4CAQAwBQYDK2VwBCIEIHiE7at54NHRgiPom20p+8bRmwIj93XLHg7EDENNyTTJ msg=eITtq3ng0dGCI+ibbSn7xtGbAiP3dcseDsQMQ03JNMkhAl5a8B5Tzfm0R07U0VQDjD+4K+ZH6mAPpeVwxYffkQ== sig=abXqCrjr2zczXQMJI3X5aRnSfqNd2P8I/j1x60aoRHJ3ke1JAwkunAtuor3Pv1n2BacgudSIH5CgoPedAPNYCg== e=found last=10 s=10 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAmU+M8wIAbBzseJH6AocQ5ouvmZm+N5JJFH3mVEOWSYs= priv=MC4CAQAwBQYDK2VwBCIEINO0UKcc0pYvRneIxRVIO1gucLzB8ZVrJj53YD4v3TcV msg=wfGVayY+d2A+L903FRbUQjjFUyTuTxNJZatqoNdm68ojADcXOexkmSMcNwddx5uv7ZghLUH/rs2GKR0E7+b0rw== sig=NXtNaKqzTcGRCJLtK5TlcDm5yN1NQ0eT/3xd2jLB9ihDtHZqyjDlkZAeBVH1VTmliV+ctsXU2k0mf6hZsLVYCw== e=found last=10 s=11 in subShifted_NP", + "pub=MCowBQYDK2VwAyEATvalBvKSZF2CLacTUV2oqZ/tQawWM6mOoX0Qt6jobiY= priv=MC4CAQAwBQYDK2VwBCIEII8QkH7RnQEur4b8vWAdQjfr4ZCtJoERHA+EKwoHKWYK msg=jxCQftGdAS6vhvy9YB1CN+vhkK0mgREcD4QrCgcpZgqho/TgUxvni1x6eIjifowfmNZIeIfmJ478nY5O4h/c3A== sig=QqXC62L/1T4H7WA1xguUVOTpZ4Z14HbMZlP0cm/hpnT4ipRUr0/gwOupDWXbFSYvRVBzSUOABs9IpLK6eyALBQ== e=found last=10 s=12 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAQuOdKX7NCjyAr2WfI6glAjTJkm6YFcQgOBwOe8Zfh14= priv=MC4CAQAwBQYDK2VwBCIEIAADNaVQ6zc6sPtTswdQ920MO+sQEMpWDqqVBUn+/J5t msg=mVwVzMHeeZIdvFIG4AAV0f3UQs3uFBVBRLv/Nz/TLHxrFJg4TClE5m27/xUx79U3dusnivZj1qw2/CG2aI6W5Q== sig=t7pulOHLxrwo2rN9/Xs7kpbPSxJ7ldIfK04/tTMbI21n8ilbl9CNihqfLSEB1fQMOYoVIrQRbkS7UXOBO62hBg== e=found last=10 s=13 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAIGB9q0TI0EjvYJE0xmnfjLMBbNvkmZc48YvfSyD5t1M= priv=MC4CAQAwBQYDK2VwBCIEID+xjwfzzAzQgy2ZMj/dohIkP91iYaPsrY8nJQ1JVPVy msg=mXeb6WDx/ffkYl+k8ZEa3OO8EC4BU1ttg5Ffzhnd9gPBnZe0nqzcZ/frnb2owS5HKGaPe2KtpPDGUyrwMyUiCA== sig=5Szy+T0AVwP3OReBLswQkRd7FZeZS9DirCuYusJAVQ/J5ST62EzslmZLGqNRC3TRWiNWnf1ZTegwoADqys4DCg== e=found last=10 s=14 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA+5SpHKz060IU7R2fKBvb/0OSSAy+B2zcfGHF3wX+pso= priv=MC4CAQAwBQYDK2VwBCIEICa70pUdmdAeYJ377Yr4QPeQ4eq15J/TYDx7FavXkoZH msg=UKabTZtnA3+pEnpKFDFhLCKsqsU29DdyRDV9nxnDdtGOA43KIWjbrnw0GVpBbGq5+LBf149BGO/FVmk3pmg1nQ== sig=1KkibqBXoDD7yPsPBIoo9OYAfehIxGSQeGJCHJN/BkaWwg8fvbssFV5Wvym/yhGiwzP51cW/mRPEHyWN3YzeAQ== e=found last=10 s=15 in subShifted_NP", + "pub=MCowBQYDK2VwAyEASWAUAIKMRli73hlFdS+SfYVaY2O2mvFjlP3QZyFFfU8= priv=MC4CAQAwBQYDK2VwBCIEIGL2Zq9uE6wbeU3mni4G9N/Jtdf5dllhHWxqGLKHNTVi msg=Yq15SxXMxPgFbL9Tp4BJ0g0ixG/iDYmuM428jb/inM9xkf9U3u89UTUAepDPz7hhUCsoV4PslFuFNgm8wvvdYw== sig=vPp99xy9rXvppPm53Lzwdb9a5I/dnXWCc28Amc/+2HQ8q6LSVaGaeGyoRKu3oXRkdOeLuU8Vuo11ysF0VI3WBg== e=found last=10 s=16 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAm7GTBTu59TE3ME2yYAsuizLT8wiNzbDDhq5SSQNtceQ= priv=MC4CAQAwBQYDK2VwBCIEIM+vuHEBQv1bXpNvBwKopdPRwKHtUPla1SLitwxAcoJs msg=RsmOPmrNmidRL2lxILsqaZ+D+NvVsZSDBGmDxIgKoc6mi0lPyu1jLxImnXc1XhTl4D0QQs3680MqDfA+xn/5Aw== sig=Vm4aDOpe9aeMkSzuOO1iBEA1twTVlcVG3mdnxqM75ZGTmX7ugvyhsXXZkPLEssMMR3/x/q0nX/YVZ3g1lJjaCw== e=found last=10 s=17 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAILsX8HvDmkpEa+zCRZGJb/6Z3mufU1T0kq/T6rvvL44= priv=MC4CAQAwBQYDK2VwBCIEICTGgD/dVF9jkigtqmX93KCnKC/bZ+yF0iu/KJXxetXg msg=7MtH1b6741JithAnkIOSn/Cr+kGWle0y8WSrrwFE7Kd7aaBK5e0tP/mCou8IW5lRzoXlmZScF45r18PwRybPUg== sig=C6iHWrg7vF5CsKf39n3Y62HEkDfwhBkCmU2PF7LXETNfG2rC2sQP08R1/IxMhvcP5RXF4P+j5NL6FV9zQNmnBQ== e=found last=10 s=18 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAAYj8rMcj9OIWposfLgYxo2ASZ+Xeva2HCr5eVj1VexQ= priv=MC4CAQAwBQYDK2VwBCIEIJmNwAI0GHnyxlhtJ88peaatDsI0cuF4sOjvMlAL9HnH msg=SwGcJaxLsD3Xz7IZJMeY4qDGeYRNuAXiPHuz+yvLtpzyZTz9jVKM/5nmsqA5mY3AAjQYefLGWG0nzyl5pq0Owg== sig=xVouRLawmkwNdCEe0cb1Zq1iRXe3rOaCzTt77lBjtef1ydLsBdYiSsn2qLc7YQ0P/q/nVNeQdyTfI+PEU34QDA== e=found last=10 s=19 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA+y9C++IQH6G4gsmnknCaPuW7bvE2HiYeFvgxUqPjMIQ= priv=MC4CAQAwBQYDK2VwBCIEIBAyylmXg5OeHyjvCt8VhNSRuO6++hbQznxZi0cmPf/r msg=YUSSvW7TXl8W8CGSduvvuLiHi+9un6K/RqFx/FZV9B6Fyj692+k0ZgdcY5u2xRkfEvIWDXIyIaKRm5OCygPusg== sig=oTfnazs3nxm3gp9wDnDLJFTqqoSYd5OYy4MAwEz/CRauX4E/IpRdeRgjVnDowefqwR++TSXDSh9xtzficNHLDg== e=found last=10 s=20 in subShifted_NP", + "pub=MCowBQYDK2VwAyEArSi3AXaNkRPHypxuLMR7jQHLyPVjFkqU41e42TTdLpY= priv=MC4CAQAwBQYDK2VwBCIEIJx7/cPhFQ29P5Qhpt9aynj25MYwztuFbcLGaRCOfPtm msg=yjbhnHv9w+EVDb0/lCGm31rKePbkxjDO24VtwsZpEI58+2amiI5O2YYh2//rJO2JaSNFcoLEq/K/d3jlxZWY2Q== sig=ucl+6aWvUtau019zFEx3g6yyJ8xnt81wx0QggiWgXZ/KIlzxDZfCmKSuBXWs2z+JMYAGAHXPmJs5010T6a1CCw== e=found last=10 s=21 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAafJfuFf3UIAdiv2wGIemUGa1RgbHghD4Coaxha7J/0o= priv=MC4CAQAwBQYDK2VwBCIEIOnFAzAMwljD1XG3VNovAsm9W32DMiT5hKjtiGPkwzxV msg=1Ya3+AE9yAe28a9BL/lnP0LUEZPHJv8Bvw8TTcLduki58wCObPpiJATUvOqeBn7hZbuvg6dADLrMLY37k5bBTg== sig=1xVefKMGve0tUbqogRtn2aNoOST84SMfHUOxVyeYWGkXoWma4jnYehum6ivhpsgtHHgWKoYed3vHnyb4rFVpCA== e=found last=10 s=22 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA+Az8lWI0foVFrMvOn405qBfHiTP4GgQY4MvcJIdFxE8= priv=MC4CAQAwBQYDK2VwBCIEIP07z8xGJCqh4O8ytzNgyWeMebo/EWAhAL/TuAKIeLXD msg=YMlnjHm6PxFgIQC/07gCiHi1w/o76AqYclCbNI2amK1gfkixbG3MdoCXkvrI6KrldQ/2L2M+2z67D4rgMCm/nw== sig=eqbczU5T5QJGm0en0NCwe8Ud4XbWAAcGr9tfrriZBDvwJANNnqH+QzXf5LijwIvr5Y3ysEh2jC7WMUSII17LCQ== e=found last=10 s=23 in subShifted_NP", + "pub=MCowBQYDK2VwAyEArDuubupd4tl9bmE8sQNpZgnpMeCgFoIX0J+ejVslioM= priv=MC4CAQAwBQYDK2VwBCIEIMWWMegoyquM3Aujl9kSBDwEqkNk8hR2Qf7zKFaOfsRW msg=Qf7zKFaOfsRWFFuAVm+mRQmvwmdXcehfRqE9DMrymyuvwjscTUFurqW7DeHQFU9ibxGXD0/99+EOOlG9xnfNPA== sig=dkcMZ8VCLTgqG0tcNlg20tp26BVq1trCnYlDaZ7szisl8Gb+7GeTxjim4B0h2mKo+HV0MzFmmogZjpOV7NmwAQ== e=found last=10 s=24 in subShifted_NP", + "pub=MCowBQYDK2VwAyEATPZMWENxy4bN3j0V5GBhe5o3vErlzODfH1DeAuDlG9g= priv=MC4CAQAwBQYDK2VwBCIEIOO992AnIt0zR6cPY0uronFjK1K6eUpX3c1COwJjnteN msg=QjXLZlFa4733YCci3TNHpw9jS6uicWMrUrp5SlfdzUI7AmOe143nUDDc0fU+n19vojba2FvpOLgQhcxvt36Icg== sig=ACitAaoDGtqPrHb3HuU4ykO/rh4IPpXenkt6SqKDd0S5Iq+Vb6d59+4/HxWnLYtbznQtREfFanrNWqn7590gCQ== e=found last=10 s=25 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAQPUhLTnXEAhkC9hKHNaJfv/Wv9nAmw24lQIjjQ5rOHE= priv=MC4CAQAwBQYDK2VwBCIEIMugafCUiNbLejpUJAImaRjpG+co6sNnRWhd4PqF1sSr msg=iNbLejpUJAImaRjpG+co6sNnRWhd4PqF1sSrj6zgs7li74WP55krBJlaGzlueRHeYMPK2yP/yiybAfCg36FCAw== sig=zhBZSogafjtmyLqWolxZzbWxp7/oeNbwNnAXRtXfn2c+c7rMhEYvLlVQIUHhgY4huRn7kGweMhYlIVYbFCahAw== e=found last=10 s=26 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAUFW09uQiOrka+tW+ryZ0aua+LXTEq6/S+sxHaMFag/g= priv=MC4CAQAwBQYDK2VwBCIEIJYiCRquNypGktBXipg/okv8tnQwyT0FjVZkonl7BiTA msg=TZeIGnsnbt1vdKGeJ9yal2ZzHdouvV9cjXeN0oXieks2LnYJ4CrzyRfigRQbWvmDtQmNMI1cKVAltQgJHPo8lg== sig=Pr97Ne8m1jBD3c7yzqT8L2v5nBXsl7wIciMd2jqhQT1errMAMrNDq/dwY7R0iSwo8m7Rxt0b8xcKg4N/XzdcCQ== e=found last=10 s=27 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAROg+MgPJHSzgoveOSestls49vCR2r/3saBkpgEn9VO8= priv=MC4CAQAwBQYDK2VwBCIEIMuo75YlxZYOKFpLY3jfu/59Tv/ARKRsa+Xfhk8hP5vA msg=hdhZxzuZSDMQRMuo75YlxZYOKFpLY3jfu/59Tv/ARKRsa+Xfhk8hP5vAAsmsiGUiQ8LC4fPJNtg/vZaGLV1Iow== sig=nQrKIMq2UnXvp2Z4lR3HdaI9qhKC9bkHKMHfjtIryv+hyh6mEhEOSaqe0KisaBJFqEYDiQ93e55WwM/kKjE8Bg== e=found last=10 s=28 in subShifted_NP", + "pub=MCowBQYDK2VwAyEARoNeIdkOkA9PgM54OZF3zoSQsBjotQ6V6ZOrp0VhQI4= priv=MC4CAQAwBQYDK2VwBCIEIDn/sXCnlL4K2AURqXGwLifOJwJEIj1V150UrmER3GCN msg=93Ej5uHxBKjSQ6/jf3r55vymFfKMElaEHE4M0F2kC7Lh1za1T7A7hkklQ0X9iAFLQhFu+M5Yb2Yk4biqXqI1UA== sig=RLiX4rIYT2L7LYDV4B+FvVoFZo1Tmsut9Ixk9NBgtG0AnxKThiGujxlKQTpJrZOLimR5IJgnAJIK9ZwdlBMKAg== e=found last=10 s=29 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAb7cP38jSmHuse9y2qKAN3M1jmrkt/pY5SuGY69YgHxg= priv=MC4CAQAwBQYDK2VwBCIEILyiaUbSHLA8pgo5r3K/AQtKg5ZiNkyDhfmiJnpuSp/5 msg=Ob64XUxkjpSXq/D9HiBOMkdcJKBlnp85jc5SoyI7dCrQvKJpRtIcsDymCjmvcr8BC0qDlmI2TIOF+aImem5Knw== sig=LLq9k5Mibc//xXErCIJEyIqv6yuTmjHQpU7CH140bkFgJ9azakRo6MPMmW7mamwJu8sqNso/f0+PXQjtnwLtDg== e=found last=10 s=30 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAbiDs2BlW89BCO8Rw+R8KsGUOZfbgieEgUFkx6BMnZkk= priv=MC4CAQAwBQYDK2VwBCIEIGcvApOm225JZail57JWb/ANSdEqpuX0h1vzkZpqrYI1 msg=kZpqrYI1nFYMc1viGHXR3uWZYLzsW2ZoiwcFB7wzMVV1IsSSzvAnt6BIVUlG9rrkqExGHhav6sZjzXmL1suc1w== sig=9PSCThVrW9FeZIv29OFUIbYWuGiYqBaplYHYCg3tDvaJKxlYxtHyeFt2u5RjpdfgU091nrCJIiGNgULD3QX4Cw== e=found last=10 s=31 in subShifted_NP", + "pub=MCowBQYDK2VwAyEACPCRdUS7vBIKCcEZFG+lyHsf0oZUzVRLmYDjnDPWxCY= priv=MC4CAQAwBQYDK2VwBCIEIFKCfS19WvmB/x1/bB0O03Ry3a4IdT7tRNtNuZ1xZMNo msg=81KCfS19WvmB/x1/bB0O03Ry3a4IdT7tRNtNuZ1xZMNo+8M/8qLjqCMAJ/tLLl3ISCjXdbov+ngnyhYJLROAsw== sig=V23UC+oUz1xFiTztfGu9tXacSe+oNnkuLOJRD9IBi9jVogBge8lNCKYZXbWfyDQpa00Ea85gkB+W9CmLd7AqCQ== e=found last=10 s=32 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAse/oyjWhBgVL+c1yfW2tgy6Mze4Od0/aj55BYZdHUN0= priv=MC4CAQAwBQYDK2VwBCIEIAMduO8bTPzENp/2pnZCkr3G9ZgK5GZtCfc6BGiQ4/+V msg=Np/2pnZCkr3G9ZgK5GZtCfc6BGiQ4/+VXFQMMsczc3iVqIe/sMlvWlDoue0vsk7Ls4wVUa42pQmEV9Hpb/8F2w== sig=6jw80bqyRFMoYbowyc0arSLGsu/8gXHUd7ULY9yATnw/R1Ezc51dcfz21OvADewl04y57MDoURAXZMzBoIIeAQ== e=found last=10 s=33 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAkwZaHK2OmEg9nDS2fEhH0jySZp4ym2ImSwA5Du59Q+w= priv=MC4CAQAwBQYDK2VwBCIEIOzUSvfCCu2NwFtpyQ+o8oDewcv3HiPS2FxYFFd4HTxq msg=FK9ibFT1TlrXNr7PMuzUSvfCCu2NwFtpyQ+o8oDewcv3HiPS2FxYFFd4HTxq6sJ1qfhfQOsyPjpVVdvCadKxcw== sig=Kyx4EdP1dAB6dcLbwasd6TF0XBKhxZ1kbVfDsRlKmnvH0T/gI+4vgF3a73kTWRuM+Qb63PANpdCzWT/P9md9AA== e=found last=10 s=34 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAwoh+TTmZ0W/vI39R4Qu5ucgQeOol40imzxxmS0dsBvg= priv=MC4CAQAwBQYDK2VwBCIEIEESo2Qmvd1bmkqbGOdmcci4XMBBAE+98K2/ej/IalT3 msg=QA5LdHgBTzAdzPotQrVWQZauvWhSY8G/qSITYAXm1UD+XdoHWEszcknMilcAc1BzSW47IEiE5Xp3u/Tigao2Fg== sig=0tD4Ik8Eeed8LKqHMyNT3wmrjNzSmraou7CcGv1B+ApSTW31j9mmY7xWcEXNBKOkwqoIajv3ikULOTr9VGjZAQ== e=found last=10 s=35 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA0MRsfPjTQ9/Qjt5bUaW1AelU8ar9S3DLhtTdb/QgFW4= priv=MC4CAQAwBQYDK2VwBCIEIKtgQUtH+w5Bmh9/mgr1FcEtS19Ln4tM2FJU0zRUwAGc msg=YS+yuwowpP/csN/nPrbVSnoqNvy5iZ/lJjkQO2pGYQ7DBh2ZPKZSOZNLn9fMoFYieHdATLoRq2BBS0f7DkGaHw== sig=h7V8/IhSHHrk2P4nsbCHdZmOUpHaRzbinVJveAlAts7sjOfXpBolKAfJW5DYaLiG3/HKpj3gWMB3XbTkxvidBQ== e=found last=10 s=36 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAdltc1m9op7NtBhD8DiUDsdCo8RGgCV4RVmcsitC46U8= priv=MC4CAQAwBQYDK2VwBCIEIKT6CD15wZvMO1muFju2iN3WSZOkyQT0D087PNtQt+BC msg=e9E2vQd22CEEukrUKlC4LKsp9oalwqjDSmCi6hnQ4Rp/sseR53uqC9Xss6T6CD15wZvMO1muFju2iN3WSZOkyQ== sig=D8pu6y/fMXMYz6+i/ZYGPrWAs40DnpqdYyDujGsfSWuG7TP8vlF8nf6GUBkL4nDO6nGF74L0hZBaQA/vyPgYDw== e=found last=10 s=37 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAdeI8N23lQz1JHFWuHlMu2GH5A+nsi1pfC4BzcoOKthE= priv=MC4CAQAwBQYDK2VwBCIEIMeqNXRbTa4jZu4sPrm62eyaOn5y5GJJqoCWEDZ9Y06E msg=NKwyR4W+NyOf/kYKN6Ki2qOyTPGZJoFsk84W0d9EFXrtKcPVlEFwB8eqNXRbTa4jZu4sPrm62eyaOn5y5GJJqg== sig=uhYo0QnNZE+cComfoBlD1WYku+2nl3GiK+OyzVinqTi4r2gXhf4QZXv6ZIROnui421LbvvC9vfK9FZeFGSlCCw== e=found last=10 s=39 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAoSq5eyTr3kNT10mvJ8S8UjQENSz6znEUUuxKhFYIwhg= priv=MC4CAQAwBQYDK2VwBCIEINsTYnADtHminjp0FIROWN3+DRDFsSwqy0R0bAYn4WSV msg=2xNicAO0eaKeOnQUhE5Y3f4NEMWxLCrLRHRsBifhZJWa+3DvRrE2LxlGeH4zJz6aBoUrM8YpuBQjmwmfIwHcng== sig=ew5TDV1D0vOTHBQ6nqzFKx5HpfS2ae5KTBShicFOpvBmJ+s1EoKPfCx/mqna5oJ2NkPIIo6O9eUuL9orKZOjAA== e=found last=11 s=0 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAG8ouSZ/7LXBd477vksld8WNz7O34o8LMfmHs6YCGlWY= priv=MC4CAQAwBQYDK2VwBCIEIAUHG39AahFE6/B2O66aj6GN+AdvQyOX0OQLuGuBjIYT msg=BQcbf0BqEUTr8HY7rpqPoY34B29DI5fQ5Au4a4GMhhNl8Jku0MC4gKtMDShA9xezAP0nYMh5ZND+BzBbNAYLaQ== sig=U01DDCVp/O+KykUarWq/AF7H7yX1vD9eE2J3Cz7t/JbY6N6qlo8qpsA30XruKsNG0jtJmPYwoO67Cx9VoN6VCw== e=found last=11 s=1 in subShifted_NP", + "pub=MCowBQYDK2VwAyEATVN/R772H5+b5RCqt92zoia7L8LdurZWfibBqYr8EGQ= priv=MC4CAQAwBQYDK2VwBCIEIFFudG0a4mjFJEcuam66BYt0sFfuTW+SZrQs5zxffjfK msg=UW50bRriaMUkRy5qbroFi3SwV+5Nb5JmtCznPF9+N8qLCnVwnv1SltFGMMrBmVjKyGnjdd9HlwPdgqZpF6Bn3Q== sig=l4UAUFVDlhgaEMc17gjBB0fMQyBFd4ugn4EdnJU+GgdTLx5NpczzfEElp0aCwf7EUkOuvsZIp0DyixDEISBsCg== e=found last=11 s=2 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAkXdJvwjG9+/ouQK0IPda5Hq3nyEEzOjv02ze29YslRk= priv=MC4CAQAwBQYDK2VwBCIEIPkpRkgG/W55sMwGhgwbxNsQvKv2Of4eC1bMDDKhnCrQ msg=+SlGSAb9bnmwzAaGDBvE2xC8q/Y5/h4LVswMMqGcKtA/v4CE5QK5GyPT/WSgFk7M7GZlB2kLC+jXb8VsFvJaeg== sig=zUT0b6oc3zJ7IWmLQAcZ9LpAQB2fJbu0NKrvRp1DrRKOIAi1VylDMGewRiPeROsVxb2EWP7VvoAz9aROrtiADg== e=found last=11 s=3 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAybXDhjS9ylJE4HEuNYFKNEd+7FTGiKBiPCWQV05RfFc= priv=MC4CAQAwBQYDK2VwBCIEIPAXRyRhyU9iV98v9Q428MhmJNHo81ltiSYE7/t7QHIP msg=8BdHJGHJT2JX3y/1DjbwyGYk0ejzWW2JJgTv+3tAcg9sKl0iu43U6oPFR1o3BLKSiY8ERc3dPKI6R4X195f1mQ== sig=0HFf2XBrhN8h3Ad4IVLcMa4fvAV/G/yh8fOk/b+Ut/4r2Kf5yoNMO3Yq54wcZhCHwMFn1F45g0OKgP6WvT6gBQ== e=found last=11 s=4 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAtlgoIJTiEHXEFqsCbv+4Pq7mW3dBQ5O8rGm0aLl1K5w= priv=MC4CAQAwBQYDK2VwBCIEIFwzt/Xw0htkuU5LDU3zMe0Ktdgae/YFVUn2QN+COZZt msg=XDO39fDSG2S5TksNTfMx7Qq12Bp79gVVSfZA34I5lm0OV8PPWge4GRkJxVe28psMgzylwVFdrTrwCbPUh6KGhg== sig=63o6rO0IC6ZZHk6YGuVxRNHbbBIi+NJlmFwF92EmuBVNBD2fLqgg1XiiMJNH1NIiIrozjGxEtFFKGqYWVEZXCw== e=found last=11 s=5 in subShifted_NP", + "pub=MCowBQYDK2VwAyEArpLBMZr27tq6N2iuzMmbwo8p6ZiyKVBmwNMkSjG6UKE= priv=MC4CAQAwBQYDK2VwBCIEICAsKvlbR6xdXkRbJpyLIc2C8QV0V+NrmbAU/GIdGD47 msg=ICwq+VtHrF1eRFsmnIshzYLxBXRX42uZsBT8Yh0YPjsYOBX5cEfHrDqxCH0q6x4Zj8+y9m3HsrIYv3k1bq7ufA== sig=y4L6Gxi5pYCHP00NPzrHzQHq1kuJ/BfBpU/Eo6wGUlYtu3HAEsRm6+UnBvpfmX5Le5dpP6uoG0j+TUhJRtQmCg== e=found last=11 s=6 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAEyNgScytZXWE3yAm1SKkQFT6oMNgu/E0XVOcQc00Ius= priv=MC4CAQAwBQYDK2VwBCIEIGaTwqRXSZeUQ/qLVdVe16CeQm54z1Df1ABcUkjewGj1 msg=ZpPCpFdJl5RD+otV1V7XoJ5CbnjPUN/UAFxSSN7AaPWh02lTBbsz+90sYhgjjMZrxRSRJ/8NmFqQddRoEx+5OA== sig=M+KIPUx+EjpECrnDU2OKdW1AQ4yDlB9qBW9ALkT7OKy3lPR2+sBbMs9zfrflYTxrsN9Qrjus2eB/awP2NSRlAA== e=found last=11 s=7 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAUiyyLDOCa6aUArMAy6TKqdJdzDYlggws+LnnlsBNrT8= priv=MC4CAQAwBQYDK2VwBCIEICz8N7IJRlVnMxTgr699zMN9Ks31VBZYUl5WcR/xyd2i msg=LPw3sglGVWczFOCvr33Mw30qzfVUFlhSXlZxH/HJ3aLnmwcUFAoWnG2X/7BNs9z21WlAItGymU3nBwXppkfj5A== sig=iGY+nwLPTugNSmXZ8V90lYpk5G0XmwIIoXPUx/JV4QzKAEBqPAd6uuKkfOC18m0uZhr39DtGKe9P7QFSaJruDA== e=found last=11 s=8 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA9h3cR6GgOeBHPwO6GhNlNt3oU4waGPj9Ozn5cBbuTos= priv=MC4CAQAwBQYDK2VwBCIEIE9mJqmbekqUYYCnej3iN3+a7W55FNVHusnUj5J5V8SK msg=SpRhgKd6PeI3f5rtbnkU1Ue6ydSPknlXxIoM8mAbtmlRSaKRSk4+ISWVnd3scr+ogvgOWczoO0cDsTqU/JX5lQ== sig=+VNdt6OVsHTK5D30g43x0THTxdGu8jRhDkV7BDcduiIWAG++OSEZHZqcrj3J3rccXxaGevgRxurrnACu8gsdDg== e=found last=11 s=9 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAekDfJ151h101IOHeVIIUsyp1nkvOiMeETLeDvjnpZGQ= priv=MC4CAQAwBQYDK2VwBCIEIMXrLC7CAqujkB+DOKI5R2J75PgYMoiBnhDd+0RtHsOg msg=6ywuwgKro5AfgziiOUdie+T4GDKIgZ4Q3ftEbR7DoAIgAN367PQG8/AANNj/zbcnMi3+o1iOggV1m4WoslFOiw== sig=GFaUx4NVaoFMcSJeq8lA7O62sej6mt17IvFeJFFu+rkHYSJiu1uIFUb8ZvUVNI9VVMwKafHN/fCPqkEuii/SBw== e=found last=11 s=10 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAh9eF8gqEt4dJhSp8C+ne2HUem0ByZ1WtNZnPhgQgHYI= priv=MC4CAQAwBQYDK2VwBCIEIAqIB+LxnWuRud3/yKYu73FccOfitzXGD424UUQcMJX9 msg=iAfi8Z1rkbnd/8imLu9xXHDn4rc1xg+NuFFEHDCV/STnirQt8nC3Zho+rzSXTPYSuuwiOHcThJJC5iHGPlwZ2w== sig=djvx16+IdOSICTW+Nhd706C/4uPQh/5RxqzRznIfQasmJgT6FrNqEpCU80g+hgi2XBvecKRV9m0IYVGA8n71BQ== e=found last=11 s=11 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAPwoBU9rvqnFRD3bketRJkhV4Rc/UGL6D1Jm4Uxubp0I= priv=MC4CAQAwBQYDK2VwBCIEIM0k4HL0tSKZvOMYAIPjvEbB8hmTGkuo83P43LLFDisM msg=9LUimbzjGACD47xGwfIZkxpLqPNz+NyyxQ4rDIx2ntyWwTzisexjYT2IaZ13MdToCEeVASM9CnJWOkvtmKxg2w== sig=ho9rVh8N2K+fwzTZT5BWWBldIWiPy4Fyd4KHSCgIzwwhd58znOcfR4bcFLBpeuEEZyYf7HiUKBjtqsKTZR9dBQ== e=found last=11 s=12 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAnUmMTktlHnLOtCHmBBAYBVQYAQJECvh/s4qZbamEMZo= priv=MC4CAQAwBQYDK2VwBCIEIDdtgt5jo+RBro+kMfnLamZNAazOdITGnCL8mC0FuLZC msg=amZNAazOdITGnCL8mC0FuLZCuFWUwQIGkWtCkUvEN+5PNqTSkEwxfNKZZr3B5h9GBYjc6nCKsNug0ceFU+UnLQ== sig=DlnNapUlYuoP2ySm566/RwLLYH6rH29ClxEpbwPrAdvpQsBhIm5Q0HKSqFf9zp6sYk7EDswvTElFf+qKtqdsBg== e=found last=11 s=13 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAzZ0wrpc1Rh/wn+bG37ljxfzOylYxVfb+mNwGvIuee0A= priv=MC4CAQAwBQYDK2VwBCIEIFoaA2LX236KL3Ab1egfNwzyRqZoEb62BjuY5evuczgh msg=1aKLUwPV4jL/EZgNumZWIj8ey7bLJksH06wR5tmyVZ6FDeO8Vguy9T3+Najr0I2fQ9OjbYrvm2bHJ//FcdkfnQ== sig=iIa1t15nICpNfljsAP43K+ATS+BLB4Nrnf2mWGeHp5dyogQHEQvVRY2G/vkoT8ci5aL/ldMey/HwmdV4HshVCg== e=found last=11 s=14 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAjVD0t5J7h05f7qpmuUtzUcRb+1ZHZkqg5NSmBJOp9es= priv=MC4CAQAwBQYDK2VwBCIEIHdPLmH/OmXzuoJKNGzQ0qoc5AsDzeUzx2ZFOLCdSfx8 msg=zcGrRrFcKhv5p/PEnl9n5RURELmch3kiPt0qRG890RhBMwJA0lj7ctd/+npycrCtNwVQBaekZIVff7gh1i37Yw== sig=z6py/Ekwei4Szwy4X2Pr4g6xeO1GFQcqWaWBCtabpCiLdex61bsGKvcRMqDEmd2axhXEBKeUSzP7VYmfl3MBBg== e=found last=11 s=15 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA+UnkRLiO6mCYkOg29FC8Y+fstbGixc1z/DEiORk1iPo= priv=MC4CAQAwBQYDK2VwBCIEIPpB7mgU5KW/g4WhYxwgRBis55SPlLzaQtr4hawkYeEn msg=dgsErb/pkob0I858BB4+u/9nKcxkYZLBv35zuewmcb+dgM5mV4JRPfYuR8Dwgw/Ju/unJXHeTaTcApuQeZs3jw== sig=TTSlRKM9GkvLKCd7vP2aISg14qpWwp1lLInkdGou8SlMsOZ5fHK5s5mjz2KKjrbp6hOqxOgv+tJNAckoTF3cBA== e=found last=11 s=16 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA3O751fpTvUdJiuGzgJnHv5HbxXOzTezoNt2Zf1QaLXE= priv=MC4CAQAwBQYDK2VwBCIEIDSThXFq/T+8SRIRLXHvwTm6CFxbbw2cCLFp72/jcRkB msg=EkYObxsmAE21sR9FcUvWbbiSzLSDY2CX4Edgv1IHQR6TkRTdJbNp917t7U9u9yrOu2iVJ2gYvbRmbeOHGYqDRA== sig=1F57+WnGPg8bn/Nwdi/Aqg8yz63KprZANXNnQE/nLllq8r8ZGur5le4U2dqitTXlh8BeRSZmmGfS1AmKekKXCg== e=found last=11 s=17 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAZgPxEH2OFraGzJHQSRqrB+Z2B4DDH49WZWIvKgN1xIc= priv=MC4CAQAwBQYDK2VwBCIEIHu6hSeLgdxcOUybeWYSGP0sN6r6pNbMahEDIiwmdsQK msg=z/IVdKxi/OKt0AKnYHnutvQY3D7GPbvwEkA8qa4qxcD15AtyJCDDoJJuBOp6BWQxBIMJ9bXaJw+uJ37NQvYKYw== sig=MmIWIkV2bCaGWhziu7PAG8916RTwJZ5R56JbKs0FcOKVcdifBSpqPzLa9E2T6fGwiMVVNUtcbU/FpQVD2cdNAA== e=found last=11 s=18 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA4dAi5LjLYRviuHV/ilGciPpgDl4/farIkRc8XfOXUqU= priv=MC4CAQAwBQYDK2VwBCIEIP4F8J8OqWYQONbwAu182uM1Uv7flCDeCGihZmK4vqOA msg=/t+UIN4IaKFmYri+o4CjZm7aL3ZEMb2GN5+rw/a+bfOFA+RoObwTYpKJc0qFaax+pKs6kds36W3kO0Q+EuOrcg== sig=ScpLcq/EPOlWlxTRg8uwP6m9qjilJ+UVT8NUgGntkfwf8HuQf3h75eW8O/DBAZB3oklYQPwTEQDcY3HmrNajDA== e=found last=11 s=19 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAtnc7NRxJV6cS875kTBFdu4AVfevq+HknCH/EoyFKR8A= priv=MC4CAQAwBQYDK2VwBCIEINbjDYqnOoGt+iSJ+9vGUK0NkUJnlnO9T6HGuMZsFHm8 msg=iqc6ga36JIn728ZQrQ2RQmeWc71Poca4xmwUebzSpsWCmWOaerIoj4mpabxDuI6CLRU6gvlh8KSphkOrZ9+clA== sig=omn925A+YRgJxKTXPie5/UjOmg577a0P58+RvHF+NesBoJMNlQPf8MykYsbvOxEkS5SJP80LNi8kAiBwJAgnBQ== e=found last=11 s=20 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA/bCnD2Tqy9Z3HwubsdZg0H/JtQW9w9j3nzLPIKnUDTw= priv=MC4CAQAwBQYDK2VwBCIEINlYQ5b7yYkV0eirvZGwrmnuWRwItm7SDrRTvRrGKwh6 msg=3iWqTdaOjX2Emxt7M+OCdvAUaNA+0fv+bCfqHz7Thx9oKz55FR7ZWEOW+8mJFdHoq72RsK5p7lkcCLZu0g60Uw== sig=cvEmBdhhhIAyScYJPCqqSj2kYlb24wkNsZ6pIdRdno2ip0W9L+Yy8sClU3YJ5yk19VHOLpxdqbo1yOKNw4MXCg== e=found last=11 s=21 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAWFGYwbHXRSznEe7vN16FleGLCHJbjvTlk2nRbUWnc/w= priv=MC4CAQAwBQYDK2VwBCIEIKmvzQrLIsqONgH5uDEQ4DXDSYHeB56HJCEkFBvo4yyq msg=jjYB+bgxEOA1w0mB3geehyQhJBQb6OMsqh7LQx8u69S9fCb84qsuIGxLqsFYFwA2nTDIZ2Rz5op+KOFxW7+kHQ== sig=FyiQBjc2GY9nfs7+gtG4zDQJ/hSAEO3Xnx4HUeXL8aEYCxLk2nrniv4jVbHpFEqRLTkDxBXyR1lS1xlE1EcyDw== e=found last=11 s=22 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAyNWW08XJQMJGTef4U1M2+zx2JMQdhq+xZW2C66x+IjE= priv=MC4CAQAwBQYDK2VwBCIEIHtvlg87C4BX14EeAk1qfzHo9v3a/tfN2YIrX2+aG+ah msg=XEa1ENZ6cJhCk5xgKDtQu6TEjWq/mLx9PE1pzO3IFS919CUYykR7b5YPOwuAV9eBHgJNan8x6Pb92v7XzdmCKw== sig=2p5VoCmw6ZmBudLjk0/Nw6+l1fZVby1iAYA29VADydzUIU2HLGJ5SVM7HRh2MtHPqgsP13PB2M3zEg2levddDg== e=found last=11 s=23 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAhNOHVVOwBqIVamb7kpzXdegsl87Lbul5RkLE0VTDdxc= priv=MC4CAQAwBQYDK2VwBCIEIOPwNqbdQRn9DUpdePXAOW/vBuvww6t720kHiR4TG+KL msg=O8O5pYstV/sm/v9LuIeLjmhcifx2OVgplpa2JCOibPrR/CEC7F7FS3Fjr2AsgxC8iGFCrKYY6+nU1SldbwkaNg== sig=rJgoIz/UAkCya1UmmAjxdishO3wXLK5UouETTPeBJCPfkzJKDF9ie8F0mfE1EO59wZnccyV58nLDlzI90J3yBA== e=found last=11 s=24 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAmSTudAe6IzmxoKH1xXihjHBowtSwV9HC6+uyHBo9MRk= priv=MC4CAQAwBQYDK2VwBCIEINCL+VZRPhDCxyJTGugiiDGmvKGD9PVS3m48kzWAJe+k msg=XqYc2NelX0+SioPpz15yQqG9n+BCFH8HVaaO3Qer9NYHNKhGC+IMDUNxOWDpBbQYMII7FKWpzaADSDF6EuowQg== sig=6oZds8eNc5hvJcygOBwedkTTExxAQyfowdCX6x1HU3saFtiz7TVQdAOZEudZtJZ/tzrCW4LV2Tles75EvWXGBA== e=found last=11 s=25 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA0amF9189i17uQrNevhFwqfefjMnHfVmC0x2WiD8QW8I= priv=MC4CAQAwBQYDK2VwBCIEIAOm+WPRCQg39hauQFciuq84e16q4R8zRqQLI2JNUL6C msg=N/YWrkBXIrqvOHtequEfM0akCyNiTVC+glrgWVGgAnaTuNruB4qmkD4aBtrJ1nq3qlX0oRTmwe7PTHHkFHhv7A== sig=YxbpDE/siX3BVJDXDHhxsHB/ndVfsDpr0dXFS8FiJXG0B+7gl8cgoQIBncRhFpQzDWLQheUnljOoCv8+uiHsAA== e=found last=11 s=26 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAaoBumcp0+MUKaNa69BT7YfHJxpc+VFl7zbnkBG3glfg= priv=MC4CAQAwBQYDK2VwBCIEIF7UKbwTT21uGsjKQzrqbCNTkBZoQggLESvu8jfQgxQH msg=0yvgsQGuzmNH+pAhubmZ5AO/nTifjRuM1YAQ7L3jG8VphI9aLiEgAwA1s2AmoRSAiS6vfqgOk53sgbt2j/g6wA== sig=FAYCAJ5XPwNvfs0UIIAfcrpkCTj9pOPVVfymtdrUnV0iwnPOAtKyogDKwBOAaHdH/a1BAw0GRBxZmKuXCEb9DQ== e=found last=11 s=27 in subShifted_NP", + "pub=MCowBQYDK2VwAyEANXVau7nKQI4+48qecYoOq9RWgZOA7JLhHGpQEUAbzX8= priv=MC4CAQAwBQYDK2VwBCIEIEZ6q3O+ZDn+tC0twl5RGaCPsMgsbnSMp07qwsCp1aTy msg=Bief/lQVCRNRKoB0QVgtRnqrc75kOf60LS3CXlEZoI+wyCxudIynTurCwKnVpPIcKPVSPxZhOu9NDV3H6Xc/1w== sig=+WJlMSlsHmo+i815rJh279DnNbfBX0Bj5ToCnX6mRHut+aN1+7ZLeluTnz0wzUSmlsHTRMu4Ioj0Fbov39pBCg== e=found last=11 s=28 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA6Pc8LJjYWd4oDgeDSiolugltO/sycCPKuYe39lDZYFA= priv=MC4CAQAwBQYDK2VwBCIEIC1CxoLtSxtiDed5Ex4MOkhYt27AB8Wlwdh/R3ZQaGrq msg=Gcehmvuagq6skF4CWY5fxCFIXvZy3S1cGB5Y+C4681pFVMo435FpZmAA2uh6LULGgu1LG2IN53kTHgw6SFi3bg== sig=xgBcaisQf6y6u3RUqV+GCMsvynKJjlD4NXQ71Hl+L1/pPbo5glAZPFVfpRf/RxoCBMb2mB9lPvIBtEfQaWTOAw== e=found last=11 s=29 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAbWlMb1kKZlhWEzW8Rp+7h5a2w9qZM8JJ1pozkYlM2lc= priv=MC4CAQAwBQYDK2VwBCIEIA3yeiFQ0hfcl1ucAmRW7nNP871skASyaAAw2+hp46cc msg=5Wa8dKWfwLacthSEoM3q9ypM5KcYDnNR5aVy0JM7HGu6ULsdSaH7PmXKnvAT4kRifvdFY9Etl4ROBaY3yHyo+g== sig=IrJVF+m3Swu8uSOaXBwkTU49WpQl9MdLw1krsyqntb5t+DFOCzmK7gWRz0uKcn2SB1GaoGghpGltKzSbM5tlDg== e=found last=11 s=30 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAQ6og6ibUfeDsHoCfnyxQL9VNmnwU4S/Thze+etLtW+4= priv=MC4CAQAwBQYDK2VwBCIEIBI0ZcChMzwKN8f+S/ORLCS8yePgYBNERpmtTzCXRk1u msg=4IxkZhI0ZcChMzwKN8f+S/ORLCS8yePgYBNERpmtTzCXRk1uBDhdUwk+9/xPVJ6s6wkEU+c5aA5NJa3tCC6VGw== sig=m9uJT6+TnsEBXLSmYNWl6NzpFJCeuXCfjnctEOxGCI6Tg6XzQ3Z2Ve9TL5sJ6gtMev3jecsgqbSEDw3iKy3KDg== e=found last=11 s=31 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAWgKwgnXq1RaYHW78WVP01ONNZkpt1G1hR1Wkwqh6v7w= priv=MC4CAQAwBQYDK2VwBCIEIFOOa5s72Wxs5uBYlf0y4BaK0e2bn+Ijvr6ac9YwwJtE msg=Wle5cMJ8+QFXDr5vGfzggY7QHCz+Wy7HjSF4DT27QV1tkQ8va3jJxG3Ms90l/q6RgVvLJRcTRyxp5Cdhkj+qpw== sig=OBAJNPuoo68Z4/YXoweoLBFDtOcjU0KCoFBUW9xRpNzzNmzrWWRGDJCrMOEPyeQamzvHT0oFcpq3YQFtVbvDDA== e=found last=11 s=32 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAAfV0Am0LdqRUd3ElwIvybUcZdN968wTr79eE81BDq/w= priv=MC4CAQAwBQYDK2VwBCIEIHD/DbwqxSxlGf/eP+7ivHADN9jpdMLXiIFrX5zkVDxk msg=AzfY6XTC14iBa1+c5FQ8ZByKNy+brskAXWhm1pJrIOQfHVASrO3m570fYvE0Wp2OmUCaHZ6iw0MzUc6YdLx7Rw== sig=ijvUKhNPTdWrFIGN3LV6hj/IYPSZdWJhVrMDooZ9vKzzWoex5jkChfz1OA6VdDR6mzIcclGbk0ftjIpQVZkMDA== e=found last=11 s=33 in subShifted_NP", + "pub=MCowBQYDK2VwAyEABJZMiHwb4kWvdvMxhIKCaz9BenCp9fvQRnQ1qc9z73M= priv=MC4CAQAwBQYDK2VwBCIEIOmk4W4hftN0z4rgPDeDq6H1MUN6l2Guv3bf5+mg+o4c msg=v3bf5+mg+o4cLWzwbOgAyrXhDGDqF7m08jxNbeR/xSHQIlkegWybgJRDY/xpiQnyBAfoOW05IFBAY3tld06cmw== sig=KMHedglAtLxRfScpqaxdSaHWECytr2gidxqK7QufI8AthDt6t3TLZylTgcPWKa9fmsXQiItiX96OtK26rXUdBw== e=found last=11 s=34 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA60FdkcuwML+kAkLJr+BaJZxK76kAkcOm4oh/hWR3RsA= priv=MC4CAQAwBQYDK2VwBCIEICwXNnW/q/bDixbXVpYWWKg+Fbs0KucdNNq6tTqP7XHk msg=K1fn5zuC3cFP2AKCE2UG2jHMAhT1FWeW/yK7VSwXNnW/q/bDixbXVpYWWKg+Fbs0KucdNNq6tTqP7XHk6sK6PA== sig=2NJj+OnHsAmsLZzhPA5UZkGMlzsxgYz6ij/5pCtnGHWKCJGEEBnYXcOI26eJT9xBnc8gddvzcGy0AxPo2VvXDw== e=found last=11 s=35 in subShifted_NP", + "pub=MCowBQYDK2VwAyEALLAr1oDBMARd+cii5ZLJgijoCdsXWJHVFBsv/ymgDgw= priv=MC4CAQAwBQYDK2VwBCIEIGBasUJNh8Th7XmbHyvfYD0QJvuOYtkmRpngq+FFzhPH msg=Rpngq+FFzhPHcXbGnZvFuJXxryp6h3cOl1+KRcoxDSu+84Zk537f+V7h8yG2blLjBX2t45ErAX7Bq5MKIr2+Cg== sig=dJGvqvqcxNCoGBsGQRIbxUn/dJfx8IMqSr70U7/mi549YlTWZ9YYdtxHQnZCLac877oYTWjcWi59Vnp4Rlm9Bw== e=found last=11 s=36 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAOkdW1aB9tgks54LksoKsyHAuwlVXT1GLwRS0HnyzWbc= priv=MC4CAQAwBQYDK2VwBCIEIEaTAyMV8JdL/Zks+mL7lDGeP/wlRxVlQYLcRJvhph4f msg=X+Ior7wfvZQ+RLh/StMsASaDCBPrJDeYKwtCc9sAESKGEqgrSnCHLkHYPB+qPHNnmoXQe62ZrBZXkdRSRzUG4g== sig=kFB+cBqjj/5H9BO9pc09ObKxJZdI/mnI3JgoRZtjxxIxy1Q80D5l/+mfyr+usg2AfFKiR3MCnKABW4B4+b9BCg== e=found last=11 s=37 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAhBchleYYWoAyyhGIm0FKB/q9M436EBJ6BzhJrNcPM9o= priv=MC4CAQAwBQYDK2VwBCIEIIwYLRv6JMAxZV3nzenDVpvm1iOkvdYkgS/N6bpj88In msg=jBgtG/okwDFlXefN6cNWm+bWI6S91iSBL83pumPzwiei6305MYmem8cef11wBRr1V4wLlsdix7A4ohr94oILUw== sig=O78Hq5sTrpnPx8c4H0MkI1OURPHdxYJrcgt4n9ZVHXqJVq3wCet6jGvAjpIrl5TvcQvhb/NnKviLJj7yZaxmAw== e=found last=12 s=0 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAEcQrUuN0I1WbgDMUBRIBnZEoNJnYj5U4UqdwkliQtG8= priv=MC4CAQAwBQYDK2VwBCIEIHrlVodxJec3pdyUjd48lFBC5+WsK8DaBaOn+UhAR16/ msg=euVWh3El5zel3JSN3jyUUELn5awrwNoFo6f5SEBHXr9iHtb1Uz3gdfhIUXw4rvY1w9c40IbwwkFB5HIIdRVfdA== sig=kIEQN/VqhvCkty51hBsKf67PeQ+NZw0khDs22tPxQ1jd/m/KAbXyxbgK/41klKHfwgsx81szOTY+V4je8WSsBQ== e=found last=12 s=1 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAk7DIk4PsGRyTxWrPGGv7yD7ok7qKfu/WoSWo1x2WfG0= priv=MC4CAQAwBQYDK2VwBCIEIC3j4SFR1ltPozDesptNdjsEmbWKu1BE9+vTuR/MHDEK msg=LePhIVHWW0+jMN6ym012OwSZtYq7UET369O5H8wcMQpeID2KVDpeQqwT9WF1Y3me4Ok8PtoYQ3b+jMVTz426Kg== sig=wz5zdFuwGSHdOBpV26UYeiLPdiJ2wDvgb1yuU3j9JaPOb1O1kh0SRAcjME6YFHG0143JsPs3ZEphn/ItCJ05DQ== e=found last=12 s=2 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAWSYvJgbmgB/nkjElEWnl+CAOw8AyznweOjkJLTfAswc= priv=MC4CAQAwBQYDK2VwBCIEIFWcQDBPKUIWHlR+aocfPNyLuPOzIz1zNXhr+8Wp6ebi msg=VZxAME8pQhYeVH5qhx883Iu487MjPXM1eGv7xanp5uKYLd5V4IK1ClKHtGlsl5eBYClqVipzpJ5aZ6HnrJ7f3w== sig=+ekAGj3xtq5AroXAWs3mhKQqW5bML0n4AyXdEoTgPM2cuVpGp8gnqUNmZbvulqDwpl+ekAroSEfvR6M338hWCg== e=found last=12 s=3 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAOu8etn6e9uZVbSxD2EKFh0eso7NCIINBRogpm35w3DM= priv=MC4CAQAwBQYDK2VwBCIEIEbdXsWpw7wj2TA5YiG0WUJYKWf6pCO/gZBxwsw/9d8D msg=Rt1exanDvCPZMDliIbRZQlgpZ/qkI7+BkHHCzD/13wNOkJNvKTft0O/xnVVw0kxtkioATwozhKp/y7z/woNtIw== sig=9UgQ51bTPAmbKscCNLOllvQczuzQaHZp5apoDDmfx2oMbQfaGDLOktLVS984K00M1L6gXY8eZO+IS8Us89yOBg== e=found last=12 s=4 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAcqGT6+Wv/6hE+bmJC+70T3WPFqrKnE4xnvZRNUIinOw= priv=MC4CAQAwBQYDK2VwBCIEIFwVfGiBScul9fYIEzhE884aCu8tpqXKFyd8utYpg7Wc msg=XBV8aIFJy6X19ggTOETzzhoK7y2mpcoXJ3y61imDtZxxjVluNk1RO29tIagJv9xwlNBBFZwczIq08djSLaEDGg== sig=yY1OmgRf5o4wmPZ48bZz9OolfYQLGHGjzuHTa7vuD5jcWVeN1e7TP1GZqhNioCpn63zKNOamNEObg8QFnj8VBg== e=found last=12 s=5 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAy9wza62eZ4zfXZNz4vYULsHN7c9wGehzFkKFCuz/TeQ= priv=MC4CAQAwBQYDK2VwBCIEIGLHenWlkVrD/qwHU6Gfdiw351c9cYyqa/dn2htG0hS+ msg=Ysd6daWRWsP+rAdToZ92LDfnVz1xjKpr92faG0bSFL4erEkle1wOtx69icvCyh6Rpj+/kEKJ4Fq4HZ2OJrbcZQ== sig=VPBf+rC1j1B5CVysOjKaANAwbDuniG1jDpq6ySks5iiR7wg0QdltqxCAo8HVK6zwzyPe5znbXl5BcLKDTawrDA== e=found last=12 s=6 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAOwNIvU7CivMxXyYHVC7r2Gb7u/3CUwwh26GZfLGxoyY= priv=MC4CAQAwBQYDK2VwBCIEIATBJKtBM5Zuof3m/Ji52wdaEkIcH66cVjxpLeHgjgyh msg=BMEkq0Ezlm6h/eb8mLnbB1oSQhwfrpxWPGkt4eCODKFWFdJBCo6K5ac+9nKqMTCYxb7Eth30eqQn5YbYQ9hF4w== sig=8QWFQNg8/hlJS0Dw5eYYWieg7dc8EExU/6Y4N9O/7BYM5pF0IoFnN4Pl9vftvf7f+FnJa2AECqUFqPaya/NxBQ== e=found last=12 s=7 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA9TxXg58hrFBW0okBk6SM/AOSat2NVdEaCbNT4u99C2I= priv=MC4CAQAwBQYDK2VwBCIEIHUhNormCtAgBIotjC4DSIIj6A1YACzx/6aPCdthlKOT msg=dSE2iuYK0CAEii2MLgNIgiPoDVgALPH/po8J22GUo5PRP8V5sMBu6eY4NWiO6k8yhIML1BStoEPiyMF3/3wOTg== sig=+D0saXPzNR+fNhZyvp9QHK6PvGKEhMWJG1SmjyS5+s37qbyTREL0IvCz/jSYXmteMljenKOjYHGED6aAJkjSBw== e=found last=12 s=8 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAe28d69FxILp8b6KzWlBqLnFSNoSh+4+tJWS9G1gJdqk= priv=MC4CAQAwBQYDK2VwBCIEIMPYlhtun+xbK6IQKrksHm5MgBAx+diJ+Tmp+rklFt12 msg=2JYbbp/sWyuiECq5LB5uTIAQMfnYifk5qfq5JRbddtQRD1dxVRtXSKvHIOpfd4PVcubEZXIqPkIqVJ4yJ3oHew== sig=z5GqZR1OT+MqjOV5NMIKp/QJCJEJOjd5tiiO5OxyrOlTvG5vjo0wFgZRHWEnHplPXrUJv+SyVwXX6XXHqYM+DQ== e=found last=12 s=9 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAfrpt+SIgmM1Z5H5K67km6CV1dFABDmXM3msBbebGwOA= priv=MC4CAQAwBQYDK2VwBCIEIHeMBAnhleg/ZBCtC0n3cPhyA/BD3xqz7iDUoEP3C2kU msg=jAQJ4ZXoP2QQrQtJ93D4cgPwQ98as+4g1KBD9wtpFNomkINHDXGx1iKvOZqRHs/l2/ukm8OYhUl7D/d4ItXPsw== sig=nUVH2VgQsxXM74tnN3lFeT8Wo21IU8GjrvbWuKHP/0UTspeOVyojrJ7nL3xSn+Vmx35rVC3NjYnjkRGO3dVHDg== e=found last=12 s=10 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAq59eFtAit5utMnnIchLO4vkRkG9I1V+jts0cZlkftTo= priv=MC4CAQAwBQYDK2VwBCIEIIKkXym0UshKYcdg3it3GF8yw7vYSRD2ogg7xWWlbLfE msg=tFLISmHHYN4rdxhfMsO72EkQ9qIIO8VlpWy3xE/w4+DeY9jUZbcvCwRxSrZySbxHpc+PHBwJz5Zs/wwwGRzscQ== sig=XQ5kNnmC7EMpKVreNqCJUSSbmVU7zaylPt0mAzmvNb/Gh/gpOdlpp2sp6tGEJdqsUPJvaDEQWHpF1woPe7GSCw== e=found last=12 s=11 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAEgBNZg+/F7YqUiOosIiMTPbwgbmwx+VZhA2usZJpDhM= priv=MC4CAQAwBQYDK2VwBCIEIHFwkaUhkfSyj1m139gQmHQGky8GV7APk/q82yFTkwJ/ msg=72Bx3sS+7Ih7pDxZR3GuuzuOAI6O0TwmhNDuYxVPhfWgmETQaNb+h4xCoDp4pYrS9qmldO9XG8bcOe/QvwD0Sw== sig=7Tc5PNHwNu6VClY/WWIFih69Vw70I+ey2zG2LMcMkdcDW2cI/3L2RwF8pNxZ8xId9ipcoc7rMOzJKRPKCnm0Dg== e=found last=12 s=12 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAzSEhHVTBSJXVL6ndSB9FDAG1tBG+56ytwjtn/0p+vf0= priv=MC4CAQAwBQYDK2VwBCIEILro+JmIsgF6+zQYepj/EoMndRWRqIsz5boGpz3pSVBT msg=qIsz5boGpz3pSVBTeNtvJsnx5XKpoDobajj6MWCY4ryH7Miq8EpPS1IhyPQKD4S83cuMElty2S4kVQ5Oaq7ErA== sig=SpjrZbbZ3583S7CdW12BSzaeKB6hYW7ZawGoyFOevCkZuvkWwKMXt2rY2z2alk0eATZpcTfclSvnRucnokhQAg== e=found last=12 s=13 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAByp3P6JYmDM8RwYZUUkBsMPZNoWNoLx/GA2s9dY2Orw= priv=MC4CAQAwBQYDK2VwBCIEIFTkSi75F6WmBWSlhyO0gkq4WOvK8fnHtb3QdQHfQX3T msg=SE7Fz4LaIbLBRS2NaMQS88teCgS3wYhRmETMw6c44pbX0g/nQkD7BhzR0PESw5oykWLfagXEBaRIA7ZIzWb0og== sig=/s9AddtqoBd/qPBNovzYGvJzSQEFKUoW0wMRylh8Zpj/yEGHQn+0l2f/D/7BQwd1NiTZBASOhFBxS0rxkw90Bg== e=found last=12 s=14 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAgzT5ODy0HNJgl8tnJ9JGy5erXVFUdZm5eEFz3TCTIDI= priv=MC4CAQAwBQYDK2VwBCIEIEeMaQ/iAkrUNVdPr9M4z2vVmySgeD+EH1zlYnsY7rLH msg=1ZskoHg/hB9c5WJ7GO6yx4R1XRbKIJnq1vN/Ag7aRw5lp47q3gjiF3PE6SmI/BUrVX5fzwwEbx3oGdER/V5+7Q== sig=D+SjvzUwbvT0TrIcFQ48rF+zJi9PBu4wh99+Y1YWiys2R6PtkO7lUsONSjKoYc0KQ2AZOEq9nvfnhNOVLcIiAg== e=found last=12 s=15 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAADR3nXG4lYkmrSL69CfCLqknoVa+1nE7UBIHsDL4Bjc= priv=MC4CAQAwBQYDK2VwBCIEILR88F4HFpv+0XmsaI6VuHCjLIoQbXE62j32hkKZz8sv msg=vdTOyGSvc+fRE/TiBtOU1jp+YqbMTZLa23hovL7dQZ/NZ7AjaxbSSgKIPhn5GaFt/r/7Xh7GwwT+g2EPEnkBSA== sig=fNXGVjY2tsTrUKDVF2CDtTyoCGyQsBv56EZEm1ygMdhZsZVvtUO5/Xs0uLJteqsRtnnjo8iMyHjFKEMPppHICg== e=found last=12 s=16 in subShifted_NP", + "pub=MCowBQYDK2VwAyEABEk+afzT53ubmjwwVkh6L7zfJNAJ00cdEkgQWYq2TOo= priv=MC4CAQAwBQYDK2VwBCIEIOINSYJgPpvqxiekED0J/kUhKKB7XWI0rpSccp68GjXV msg=7gtKEeOXNEalky8z2p6BqleHI5mXm7HqfDQzVqS+oOIOM1BRwodGJ7C5QMn8JeG62JZ+2JzzNlDeqbD4XIlyyw== sig=9dyEmYvZaT+iUR5AieKOlA/6186sIjIngZnkKcKoavyaWijXmx2y/ehnXUDb1ZgUIirPYQb3yfMDyLGOYAD8DA== e=found last=12 s=17 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAgHPLClp52r1Cg27nDr2/nl4lIGN4YDgCQbjy8ZwjJRo= priv=MC4CAQAwBQYDK2VwBCIEIJvV4h88lZr5bAprZE9BGLw1dFJsYlSl7gX5d0eapkNv msg=pe4F+XdHmqZDb+S/2KAR37aF2Z1E4+EGGdc7S4qDrWnWsML2Vbw470uitfR5JoHvSW11ALHBjV9friJ3rR3skA== sig=VEayAgZ74Uqkb4chpPgizbwk9KmUh8HscUy32XOKR9mhwbiKROU0Wg/MbV5MhEa/f849ScA6Pz60NcHcYP6ICQ== e=found last=12 s=18 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAbcwTJkNVVVw1MqMH82GTPtdjufJimYY71qzht+5TRcs= priv=MC4CAQAwBQYDK2VwBCIEIAJTfkzWgCfLLhrL2a60QCD/jCVP42s4XlfqucSiFg/c msg=0Vav0mFrxllRRNacMq0rd6j0RMD0O0fbaGzCJHJq/h+/98zwCRV/fToJV98GRbuB3MMM0fI2YMXt9wDzaqETYg== sig=Z93qLppoai0wFBSweocO/4zrv2aqXkSp6V88pNYY/gIiYdl5BUWFdf+baH9MGARviGHzNP4uAFRpIUGLzOMMAw== e=found last=12 s=19 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAcsi5sXtYBZhgel6/z5+VBZBneP/uMl+t5oe3jNLnk/I= priv=MC4CAQAwBQYDK2VwBCIEIGTd0dyyKVXQ3OhQPVFCw3Idv9JGDvFvJWO0TAbTmo5B msg=Hiej/sMgdd0AQxiMHLP0+z85Tn9/Z6x2xMbZ1DyUR0VwvXN6gohA+YUwf5db2WMiI5mv/570yebqevVj7S24VA== sig=dTsEYo1DZCpb2I8ZhkDJR2vBqGY+2mM2WfDQkfKGhSoceyX8N4G5XcpuTJVQUCXBqJmW84onFs3VgN/z6NybDA== e=found last=12 s=20 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAPGf+KbYAETS5fKfUFQhnVqJBAq9sv0HfsGWtaaYGXTs= priv=MC4CAQAwBQYDK2VwBCIEIDFbfJVLt7WpMXf2NahwhJ7hSyMoNKQAsRC4BJ6Zbgna msg=Iyg0pACxELgEnpluCdqcT/ZqWmOJFl5L5eUV+HbSTuoRD+zMDIgH8YmmA0pT4leSQexiDHJzKM7L/jBLwL9ioA== sig=zHJjczaQAe859BkgsQ34tGtolc549PtFPxAcNyDrPczcYqw/xI+AubKDuEEWVL7fA3ut7WH2z5TEovnzDRwjBA== e=found last=12 s=21 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA1dNOEG9khJd9OZK4e3AtGdYDIRSm4p9ORxyyDQspyPM= priv=MC4CAQAwBQYDK2VwBCIEIKq8nuLOKGu1iSmnhvigTXDitUKKwCC4JGpTD7gt4RE+ msg=H9sTgaPIRmZyZgmyzIFEeyahDyAJ6soRv/ya+Gd/8gHkLNqFgH68d+qFxFS/KOKUVrcrrBax8oZeyJaIqrye4g== sig=vbRFaF/F3cjxpBK9UOoxU7CfW8myT9pOwpmowzrSW6Z4/jksLOgOhu8y3eS0wLI2sdiCcxNsRc+72wbRUNI8Bw== e=found last=12 s=22 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAvkhg/nHmcZV7j6d5d9eBb0McxMS0tyRo/LC5Br8bwas= priv=MC4CAQAwBQYDK2VwBCIEICnSKL5JeRIT51vv9BqlyFm5rvXZDrZ8BTDs2QiZ89JY msg=7+O3b2w2hQ+B7+RbhXRd9mxZ1yZ1cnu2Qs2wQ6StWdEVZIti+5wQOBItHELsTZjK4tfU+RlUzrV72wYWMYxStg== sig=fLLoIMZdM+ajRQM+8qliGs0GtLxeaEkMlGDUIHmIWJErTL16tSuVsuopKwFftI/7w4Mb5G0ArQvgqO76rN5+AA== e=found last=12 s=23 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAaTU5RBHx3Z/+eUOiDMMFSaJVJREPtEVXEUA7Ha7h4gM= priv=MC4CAQAwBQYDK2VwBCIEIGPMtAfM8KK03jWcf59KL585gAwAaXOLT1IDqNTf5tHE msg=YFVZg7grYJIa5mdYMwhjzLQHzPCitN41nH+fSi+fOYAMAGlzi09SA6jU3+bRxPVjqSzDMFFYCmrfva+/YACA7Q== sig=x6xuhCabQsn9At8pYNPfcw+dA0wxuvwgni8HtAIQ/OQhs1IFHEKd9bSMWvId9gJi5zCLae6hGAOGi1n0DcGqBg== e=found last=12 s=24 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAAhVCxVymvqjro7LfrreMrbogkrO7/+6tfLY2rKv0KV8= priv=MC4CAQAwBQYDK2VwBCIEIBmbi1tULIQsRBcN8qXOck/LiDIZ+Q9jpQtUorKQgdmL msg=V5BzvApphT+KQ11t3mBaLMhK89ycvaNO6261twxc2Tq1KgmedEFJlRZZ0iN4GZuLW1QshCxEFw3ypc5yT8uIMg== sig=plluH5rcyFIVKTmLA9fWRt9VN2Q67z5hJZM3SFM6vFTyPVmSLFYTmO4Dr7wrboB72mNj0tKSUOSWkk4xqFyWBw== e=found last=12 s=25 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAsEjQ1z4zhKB2vk7jQWqf7DG9s+hWBewTeVR9N1Xl6NY= priv=MC4CAQAwBQYDK2VwBCIEIAAGmJ/Ut4OPNydMp2yjuxG33fJV1ExBr1m8duKHrWJr msg=Qa9ZvHbih61ia8dE+tiVDZyJ12rRWB/LRfTOySyPzxFCAB7Kx2zxgMS50YPTWmwvFk/rb+NLWrsnfEsuEkGx5g== sig=XZMc00dL6taSzqUTf5yCUMaHJOCWz6VExja7fZ+ffYs/wZZSdgRuKxVNy7U67O6EkWr+yK3Zhb6ptRn0dJNfAg== e=found last=12 s=26 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAuTxaAr/GqBZSw1mb3fBm7RWgmmRWNeHo5CkVLe6HmA8= priv=MC4CAQAwBQYDK2VwBCIEIPMyou8Bz7SWN1ZUwBfomBnawXZYqyaKDlLK3eoEFg9e msg=VMAX6JgZ2sF2WKsmig5Syt3qBBYPXrvvZpYlPBb+z8anmVnnknZsC7FG6t+DoGYyorqjW0VshVnEDdAyAuadHA== sig=IbbHuYvaEyfBv3nbq7BbmdcrZsWR2L52o/FQlPymJXgus8/o38Q33oeaOPfI4diHuaxcpTRMnccDApBUFHm3Bg== e=found last=12 s=27 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA72Y4i9imNsFpihtsnEtcJZypaAfLl6FApiIE40bTRk8= priv=MC4CAQAwBQYDK2VwBCIEIGOvz9s/dTPYFrJx700S50NRx8MvyRCi8GMCQX7JBXmA msg=iM0VJrb/8SmnEQN3fo1nFq50XGmwM+bFXdSTuLmtdoDFJummQnLNNkNE+mOvz9s/dTPYFrJx700S50NRx8MvyQ== sig=id/6/3Be5l+IY7xhtv+SEt94GraKV2Aq9T5piursLVlZn8HGPYQO8s2DwTJavvJefF1h55UxMt5/8zOop4mFBw== e=found last=12 s=28 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAqum/xy7XEnUragS2+q0QcNUnvsc/UbmMTM13DIU2dKY= priv=MC4CAQAwBQYDK2VwBCIEIKnSOR47Lw/cOdYYzU7a69iM8LrxLt9L5+iQpPpLNjFl msg=yOlCeB87KbgQ3sQFMez8ee9cg/gptu1ZGGE73WH3Ud8ZfNErHqnSOR47Lw/cOdYYzU7a69iM8LrxLt9L5+iQpA== sig=NlIdnyNCuorPuz4/BOfpBOdPzOL4xGmaVm0v1UrtU1A5+7MAp1qEx6/J8tpIr1RO+ggbEfrHAGDLleyOURgzBA== e=found last=12 s=29 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAABJBurNCsFqvffm5w7toj6kQqCz0kEdkQ6cNSPNstak= priv=MC4CAQAwBQYDK2VwBCIEIFXIeIj4LeOGufbqVLTYD9X0e1Qc/QBZDGJEr0JmOKqf msg=WRgdqBcJ/VhszmTJhtct1H9VyHiI+C3jhrn26lS02A/V9HtUHP0AWQxiRK9CZjiqn7Njg/YLcb8qRJ4aswB+qA== sig=adfBri6DRHYJYq0D+kNrtfQksNO1gIqVSHu41BMOS5H+WtIux9Kiwmi06ug+QU2vUqYLiKUiU3tv7I5NMZdzAQ== e=found last=12 s=30 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAer+R+/MhPx+529LI7DMEwXtP0kBYZybawVuwzHHKABo= priv=MC4CAQAwBQYDK2VwBCIEIC9eTNAcJ+lfOq5WtpDxdnlqU5Ld6/nqi8QATR6dm5zC msg=b3KNI7MbQiuzGPG3iroM6FGlgsge+3iz1O3lkW5KT1JLjI+2i19UB7ugFxx6Uo0RRsKIhVJXur2Ela0vXkzQHA== sig=b/8yTU8nrM+/1IQZda/oYP+0ALEn3Fv/63aoyy4mgqSyPyn28s9P9nOipM+ZlCTQG0wsFzQPR3prLLo4/ocvBQ== e=found last=12 s=31 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAxmKXakHc6laMdWGM2d5Wlpf7DwXAv6eT8oW+8XyHyTE= priv=MC4CAQAwBQYDK2VwBCIEIKMe92+O1E6pgWqXWO67m51SCZiZWAmTkDvZQ4ZvXKqY msg=abjZIvKggedebpgwH6Me92+O1E6pgWqXWO67m51SCZiZWAmTkDvZQ4ZvXKqY4PtjP62H7QCCSa7W0ausMwAQFw== sig=x1Sa2Kzj5j9YFzy+kkOemFj4jjBjquzzgucvd91Am6AOrdSEHjbTEvqTfCCiBdLOQmcNs7QAEIcwCqJ33odABw== e=found last=12 s=32 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAOm/f4GgAU6v4HGFyuJ6utzgHd5ndu7Sj8hV09YQCZBw= priv=MC4CAQAwBQYDK2VwBCIEIIWo910mHMz5SZvJ3Pf6Ur3pDwZW6FYGWNjC41A3U1mm msg=GHOT9Z8iL2rYqWmGVH/lFvGBkMptl8o29UQDoDrdvRsL7kHXWHtRBEKXuSqJosbXJvUTAt6VprQ1/6lpUhnMrQ== sig=/93D6vOBC2zLzpbl0qZXlU4D0/6TquAQbvWn5ev49qOSlG4Bt36Tvy2QyO2e2ykHmcukEUm1VZdERj195SEnAw== e=found last=12 s=33 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAcb5sXPPlASBpW/ktOeflrTrIXEraMSnhj/rDt+2Ef2M= priv=MC4CAQAwBQYDK2VwBCIEIDinb5HklnHvKWaz3Bn7znaP6jCih+5oY3fSCft0Auxc msg=5y+9fCJerPKmMBOkGC8SpQQ4p2+R5JZx7ylms9wZ+852j+owoofuaGN30gn7dALsXE8hlKhE7FeFp5RP4IIFIg== sig=1nUjYLf0yJFkL44JBF8k8vE8tKnxG8oU2JH+Caz+6jA0+dKpPYU9PAJDLjLJ1G+79K+mfWxShWDHwz5nz8AkDw== e=found last=12 s=34 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAhzpqCQ7zeaVjYXCa+NfFveiVQj7REzfGfibsdxctt2M= priv=MC4CAQAwBQYDK2VwBCIEIFSI6qdw+6a0MJtnC94FDVfNhj+APexWWT6XCvuiVONL msg=hjUOxmkZLVW9EBuyqnlHgC/mTQpUiOqncPumtDCbZwveBQ1XzYY/gD3sVlk+lwr7olTjS8Yo3Ajm3xiS9D6VTQ== sig=ZguJwNwYXA3KIRvwPDZScF3tZJYpTQj6wzzdNREdR332AdUHDKfafix6WTg/OG7Hl0x8/gNeiLcv4M30yXABBw== e=found last=12 s=35 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAH3h6LU59C2qd8Y/F0zM9AQvrZp1cqbh8VM5+Jo1/UTs= priv=MC4CAQAwBQYDK2VwBCIEIONC7cA0fJPIsl479OKUBN9aLu0LNLvikx3LSMLt2eD+ msg=amhkiCvizzw7viO4dVlJj1HjQu3ANHyTyLJeO/TilATfWi7tCzS74pMdy0jC7dng/tnhFS0/HUFRc2gjdokR1Q== sig=+aYHktxTZz54KiU/6ctr+vRFKWVZb5yZWfXy7WYEgv1Lu/0nnPgyqLK3b5lQZfkHBoOlWbI6qIsqRTMCeNSTDw== e=found last=12 s=36 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAxEYCYCrM2BT1lZnfebc/HFV9Tw6Cz7zhX7ClbZ8/lYM= priv=MC4CAQAwBQYDK2VwBCIEIECinzCjANriRACYcU6DZg5m/Qhy3Ul03mhf9umVwVyH msg=QKKfMKMA2uJEAJhxToNmDmb9CHLdSXTeaF/26ZXBXIeyy3POthp4GRu+HPoxVH9y8rghurND78l1JHdaZjEetQ== sig=xzuJQ5Uww8J934wMxDUKSs9TWCiufj0wAAXOWo9av6TQ71g5uAesto/6iYIeXZ0mogqFtu1tKDQT80ICcSwkCg== e=found last=13 s=0 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA/xZ7RWNWIiCRfE8Oir/evregfQW8or6kla1hB8VM+rI= priv=MC4CAQAwBQYDK2VwBCIEIOWCNx1ah7MAPQ45lrOx6Gmj7KbTc/zbDVoDO2ARtSxI msg=5YI3HVqHswA9DjmWs7HoaaPsptNz/NsNWgM7YBG1LEiVSFizqSJd5Oy6pHWhBeDePs4JEnp2voRa1yMZKCMkiA== sig=i4f3bCYSVsrtECdShp0KjXihDT8Z4wQ3Lyo5hp571qmiumOGKb+nOpeB82DUMz355o03/t4vyF6qwS/Gv9dzCw== e=found last=13 s=1 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAlMQAiNvmyR4t7hSV/8Yk1hzGLKGe1SFlcPlZ0XGwP/4= priv=MC4CAQAwBQYDK2VwBCIEIL2o3zZaz7DYtCaK84BfsZTj/5YdXuuPoGyzjeZkfJcq msg=vajfNlrPsNi0JorzgF+xlOP/lh1e64+gbLON5mR8lypPaSnTsaBpTtGA4CY2SxtLPvA2Sfd2xyRPt2SMWSmYGg== sig=SZ3kgmTPczaBtp0pmX11PNGl7MMFjuFxpYN4NnVlrDKoGc0WtUsztLGBgsLWdHImzYFc+g5VdUgQLXbzTUA/Dw== e=found last=13 s=2 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAEVbkM3cSv4A+0GNHX6g/puvU9z3BjZ+eNxAlKb5PAGE= priv=MC4CAQAwBQYDK2VwBCIEILm1eTKsLq4tbThPDxGevWkQlzSMuCrd6sgp+bkjEY6E msg=ubV5Mqwuri1tOE8PEZ69aRCXNIy4Kt3qyCn5uSMRjoQmi1YmRwyXuWPKFwe11vndjf2L4kdpxi0do3TytOGgAw== sig=1DQlx3l4ZBFa6X+ns5Pw4cp8VDpyf2m+uSPuOTjjWac2I/PWMAbI5qdnzbyd/UTakMKAcYXnrSN63PZWHGd/CA== e=found last=13 s=3 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAOwTzFOxpKywgwQ2va+9gr44x5KbQGw3Jz2KyhiWRR/U= priv=MC4CAQAwBQYDK2VwBCIEINY+999DbIdnYvL+JTJpctuWm0kxLwJ1+TeS50Z2aHk/ msg=1j7330Nsh2di8v4lMmly25abSTEvAnX5N5LnRnZoeT9UCWDbMQG8dflMfvS4pyStSi2vzTgOMqwtmVN8H9IcTw== sig=cWVDnqag+qvpzgMzNaZnO0F4nSADwN3hKyk5RxlNZ/lamejBvvrR2sH95ICvI/+RnvyMBKGYpvfV/tdipkACDQ== e=found last=13 s=4 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA4gd5Yszd4KDokGPYfYuFukOh+nv9FgpQR7jIqx1qQ14= priv=MC4CAQAwBQYDK2VwBCIEIHSw6zDMaLhsdfW0pSVqewdhi4rJm2NDDH99yEdkDtFK msg=dLDrMMxouGx19bSlJWp7B2GLismbY0MMf33IR2QO0Urv2bMpGrDsI1m6c5wylBaxGTFomCDYKt6NzD6GTTn+gQ== sig=Y+fHprdODp1CyF2dVnB/F/xW3QKuGaG6d9fMoj88FB6eQMR2HloxQzda85324il3qqH4q423HSxpS31DhCi3BQ== e=found last=13 s=5 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAvPpM0Dhs1biJjQbZASXQ0wB0sMRkdl/RfVodbo6COfA= priv=MC4CAQAwBQYDK2VwBCIEIEm46Zf7/WsIvGTTopV+gujPW1DqwWYu6D1sGZA/UzBb msg=Sbjpl/v9awi8ZNOilX6C6M9bUOrBZi7oPWwZkD9TMFsql5lhoQox4RA6m3PhFQ8VHzDnFhR8z+N+vYY9muyppA== sig=vr0YFOf3UwN3Dwuppzdi5DAf/TaV6gpM/enB8OtBQEF8yxn0SC7rqrBl2aGrXC/Y9B5ORnXWFnIPj53+I0nJAA== e=found last=13 s=6 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAvnKYzsWm2JK1I153Zea8iGVslGihL9wz6xKdRnnrw0s= priv=MC4CAQAwBQYDK2VwBCIEIF5SNvBsB1DMLW44UjgvbbkKhtOfQLowxnv8RQbaqDOY msg=XlI28GwHUMwtbjhSOC9tuQqG059AujDGe/xFBtqoM5gf2/pvWMpIFa7Pa1nDo7D88tI9WQg0O56Bj+5KOn7whA== sig=zakYde4sm5Ax9EUwW9Av6TfUudlinKTZdPHNpAq3S5RJh0SfJeHFgIftuL9mQyMbx6Jhm6hVzWp1wO4BVHenCg== e=found last=13 s=7 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA9UvqVL90rABRd9so/FWqheyo10kOavrS5jrIl+Ua6jA= priv=MC4CAQAwBQYDK2VwBCIEIMP5+SXCoB6WnQlNMyPY4o/NrVFz1PzEbPfJSElWaG9k msg=w/n5JcKgHpadCU0zI9jij82tUXPU/MRs98lISVZob2TLa8GMyE5NYoAAb+x78jRGn5HbMF42s6bCG2ZzOwdMaw== sig=0KGFd9jfHNDaphagtFlG53gg0GChlSCbv7PDEXcG8kTBlmiWbfpWlkIX9gRxh04BW3tXYJpm3c0gfF0DI/6cAA== e=found last=13 s=8 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA2UquPENIT1af5odjWP8st7YTfH8daYf5dvYmi4lECx8= priv=MC4CAQAwBQYDK2VwBCIEIIlyMwoOArlA3lMYgHU8lkjQmSIBgz2gvu+RRMitO8cO msg=iXIzCg4CuUDeUxiAdTyWSNCZIgGDPaC+75FEyK07xw6eWXDB4OMCoMTkP3wIHj3r+81jmpX16PuIMcLwZzuzKg== sig=GPA2fdkckF+PguSYq3IjN8LSiIDSNVOl9Na3cCmhYEUzfV+4Z17O7cMzCik9NODdbf4e+jnXp/ND8yvrtuFQDw== e=found last=13 s=9 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAe8AjcDAjmDSgyYZ5rGSuq0WfNtvQtS0fuy/rU6dPEig= priv=MC4CAQAwBQYDK2VwBCIEIEpeczlUbNdpwkrCnuvSuAqzjCTBqImGjH5gxXBy5cYZ msg=Sl5zOVRs12nCSsKe69K4CrOMJMGoiYaMfmDFcHLlxhnlUJE+VBRNou81BkxMmlqpm7rq/h/lHgZN4Nc/cC6k2g== sig=bFUh8WU8v38wQGGY7x0t5QLKJax2vsJwUNP/EQd6sT8MkOofg++KUFVAlT7eedfD+JTxHvtbY6RMgqlh2kn0DQ== e=found last=13 s=10 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAAn8A4IVkDUj6vltuJ4zbzyse5ZyWhwFR4fEk50bWp6c= priv=MC4CAQAwBQYDK2VwBCIEIGQwCM7NO1hoeCCU6G8nmlmNDWeE7zBIHRatCw/2lRDv msg=zs07WGh4IJTobyeaWY0NZ4TvMEgdFq0LD/aVEO9HPacc9CrPejVhzFTRmZmSYD/Dv1q3SCfyYy+rP9CE1w/CwQ== sig=XkLQwEQMQGk96CExdexXRZOiXMkS/wq5JFyOV1iB97lK+wOXvCSs0GnFebuDq3sMrjDq+Kgdi+8mGuWwA0OkBw== e=found last=13 s=11 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAhM12kMba1FLqBNxPSIN13nCtLrzoXJIX2eLy0U9BOLk= priv=MC4CAQAwBQYDK2VwBCIEIEl+8fCKbfRsUem7XT0BBzr2mcEs7pVyrU6pSaPLDTYP msg=9GxR6btdPQEHOvaZwSzulXKtTqlJo8sNNg/JnphvQaH9rS5n+PQiuB7l1NRfoMomDKQk+rtDC980jyadcTnPfQ== sig=/873e+8ILSEkOPI7YRBT6XvXnSjl5Dec7otrN4L6Nq324kmpwwMMOXQ9Sf+j1/oKNtC5H/oIdCS0eE5ARilcAw== e=found last=13 s=12 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAU7SxiLqEeSPKJUMsp/9f/EDv9TkCgDgCLzUE2+fvIZA= priv=MC4CAQAwBQYDK2VwBCIEIDZjlQuulFxjkiFwwrg75Y2AIRXj5QBSqN1CJqcXctA0 msg=Fk4nHHZdu+gxNCb4WRs78ld488tLMMVrkiN3Hi/eDOXypooVIxC6DLIohzz4HSYOz0cexAByHjsmwiIlpLGf4w== sig=6rta5oSjlXvl6DvIDTxLwBs4pyilz6Y64hIpsuYBVEjK3pjy3J41mxPh3nxhjaD4b7GxZK8g1+C/4hZnBGomDQ== e=found last=13 s=13 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAlp9AdLnkZewJoVCuNAc8NGpMAHBNnUEHF0Maa67xTqc= priv=MC4CAQAwBQYDK2VwBCIEIAPJbOuybgdYeCU7CjyhhyEbFm5kaorPI8XnDOLekkdH msg=3PRTyMrpXc43GT4us7xSnyCeLB6lybE45lNukrrOd0+TqgRc7eSi0Mn43RCPrqVnM0FgpEsfkzKytTUVhSO4sw== sig=FeKSW4Vq+c4ji3GY5BERcfw5NmOgIq6o9rFie8ULUfSqeav39KEieyVVmjcLmzIfJWPygjZfu0wzZpiXu4fkCg== e=found last=13 s=14 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA2ib11ZBxDSqktjZPs9OflN0xuxGklld7sCNDSpteLIU= priv=MC4CAQAwBQYDK2VwBCIEIOk9mgtZA6k1PP4qOLS3yiu/x4MJ/UTC55/lt+lFjAZC msg=tLfKK7/Hgwn9RMLnn+W36UWMBkI8Q03YHZLgQL7ICq503FikVx9GNpVb96a8dfwQ0kPH6aHbI4lrvhPzbHQROg== sig=mzGmwcOrMT2EhDaV00UmX1ZVv9jK8pRwMakfHvLO8qZw1uk33eYJvvgYQ9vdo9f78/ng426EO6aftUHDMiCTAA== e=found last=13 s=15 in subShifted_NP", + "pub=MCowBQYDK2VwAyEADDLUi2p8YVzNZfiFyf+wCK9zzpep8yW35qsv73/vxUQ= priv=MC4CAQAwBQYDK2VwBCIEIEYNspdQoyfk364Ji75OWh91KlmaXuC+EkZZlHVpoxOt msg=5N+uCYu+TlofdSpZml7gvhJGWZR1aaMTrW4Bnpfim8eHy9CPA/5zERJGAf48wOl8dJRlE4a7vLfnftxB9FkbeA== sig=k0cDkkQED1wlR9so8/tgxtbkzxd+n2/xM03ah1T/WnTvJ5dD5bWw9GCBtEynEvgo2nomLQ5PurteuTKhm8mJAg== e=found last=13 s=16 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA1YFuSTCj7dfWRpipN1mQbKIgoP6CWi3e13iS7YsJzSE= priv=MC4CAQAwBQYDK2VwBCIEIL7DrQ6UWNHorJ2uAYkN3UDe4swZ4a6ZumT840rLfOAR msg=vsOtDpRY0eisna4BiQ3dQN7izBnhrpm6ZPzjSst84BGQvNr37eBB5ADLLvVZtUFVLNjVkAn3/gDAFVoe+JPZhw== sig=w8D+ivrF84UBp52qgcziVgBeEroDODgLlrMi260IIMac/8c3b8LQ9mM3G08p/7M1w6V41zgqDc/xumDrTr2eBw== e=found last=13 s=17 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAwxWNN+Hs3t8vgI/FOiuNP3KooTU0trS14Zi9b+J/IG8= priv=MC4CAQAwBQYDK2VwBCIEIHIBXkSoCHdlA6GEDvmsp39vn3FgqJmSzkaoLgTMf8AZ msg=WO1f9OBLHBkUAf8heQ4K20boQTYUnMJVO3lwvOYs0G6JNSrVKcGxx3cThbgi0CQYn8vhsiqNH+f8qoZkMuUw6Q== sig=XkxeVYNvYYgb3L4CHXWn1aRoBr6FH1V/lI8P7jlZOm2GcADEg+BC5XJHyWkV8RiFniTveCs79iXQGXp7we6kAg== e=found last=13 s=18 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAfPYSPfAeWD2rboqdKqjCafP5goRNA955JijOl7fAYMM= priv=MC4CAQAwBQYDK2VwBCIEIOQ13wHvbkWkfMjOBrcot+qjcCB2oNyByXHZ2ZqCaXHu msg=DAKJx5chFNVi8t9RFw0voIqmqLuDWdqMeI0WtF6UdSrTl8WoAkKjXMTmDHZwpwWZhB8y5TqzRbRryuYn7+qkqQ== sig=QPmPIcVmZGIuqlLq2z7kbiBWPG/KjqsRBvChELQwckoVthIfuRRDXMr66vhFCDELhXOtCyays5BkafVjkogyDw== e=found last=13 s=19 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAsTqBXfJId2wpuAhA/NzVvOkJev7hgajCWI+qxvdaJNo= priv=MC4CAQAwBQYDK2VwBCIEIAhyU50+k06WkaMJb9xVgWTrVZy4smSLnN1fUHzqaT0o msg=nT6TTpaRowlv3FWBZOtVnLiyZIuc3V9QfOppPSg+MTu2OcjGxNksoTTYgs/0d+/gFzcbEZpwtYpPB0R6dqaYTA== sig=N43LnuuUj02pAZlJeCaTaTW/iblHKbMcAiJEOCwPGtiGe88R7vA2FvI0RMN+ZXsAVpiLUxuEKDWaINIehXMZBw== e=found last=13 s=20 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA1VnYS2z3yWhvUnaEFleBKC63u2zCGKfNhPu/u9FZ6Xg= priv=MC4CAQAwBQYDK2VwBCIEIGe4PIT4c18zLs3nOzNBu+RTEpp6fqHaELKyTgdK+/bz msg=njQhDUT1ajZ8oU+Sl8QeTK5wganVeI7JLRURFKbTltvfMZsA+qNiyNcPc+6XGfef82e4PIT4c18zLs3nOzNBuw== sig=J8BZgOmVU/nqJpoL40yggpvrVoqknOGuZC0EjJagyIcXorWFcGHMpGTsN54sSe8c76v/AccnIwIbh6TiBUgVDw== e=found last=13 s=21 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAmXY88Wodwhonu9r8USHWyd8fOjgqnrccc10NB5UESnQ= priv=MC4CAQAwBQYDK2VwBCIEIGqut8fuTXKI+l9hLeMhpA9Xn4Bp69Up6NP8mHvmgVxU msg=ZsNBwyqw87SgSK9t45TknCh2/o9M5MxIaRQA8flEXFQvwIMyHM4ysYUdpXKQyd6auhqCbRcvAdevMCjKoRrEIw== sig=l2gBVpwfbBB0I3SJ910/ijqPeZaaU2BwftOj23urkv6Pne3W0N3sSkHDUnVbO1UtiAku3gbRns/q/umRvqnSAw== e=found last=13 s=22 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA0ZubSjEyeBRtcujJDTy2TUvb7gU0Q1uuInKWrjXmigw= priv=MC4CAQAwBQYDK2VwBCIEIBq+pj4BOB1+0tgpImbgDfp7Jv1tx3eXT1v1pLrIEWqO msg=ImbgDfp7Jv1tx3eXT1v1pLrIEWqO98vdqCtPQim/38KizJZtmudvRvTesY/X3babzGWZAMRX5IY30ESgTcP2Xw== sig=FcCOBsbGloAAWCDoZcsAE/Y6QVGcI+5K37DKbno1Xn534PW/ggKBi5OfUd7xPP985VjPOGjbVCeygLc+yM3mDw== e=found last=13 s=23 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAhjhieCvP4ot+CR1xhOQHJmZM4mcUPeZzGGQ8DPKK6ZA= priv=MC4CAQAwBQYDK2VwBCIEICMOOFYAEUL197ajXapejXex94f+j8lMpDQETE+Jbyzu msg=htgwES0zbzed8pThd4x1WAbgZ+5yYxefvPJcK8XMaxdDTTA/qa9xy/NQV2WMr7KHyss04SqR1xuFSDukPKYfiw== sig=oWmAzuYgJCjwbw2v3PUQ1p6c/g83ngjQBp8ndZpsNr16CGOZWffdIydp0w589Tr4NXbhrJ990zvmdxDUzimDDw== e=found last=13 s=24 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA/ww9LW9EPu6ap9JZyTdlfxhlhYI4v0u8qorI7G2UZbs= priv=MC4CAQAwBQYDK2VwBCIEIBm15B9m2VSK4ZWZQiuF+0WqPdlgJ8oIb3EMbsVzkXn8 msg=c9WoUgAK0iWH3jRxFPnTJVScRQ5hjILt27BbYlRzNYFYRV90QStwlpFd88esrC5ZVc9uRfAtPM3pjjW69hm15A== sig=J7TtssJltWU2hjaj9GqOpyRNDCX6yJplNP4f8cq3AJRI2Ly8DI1Jii8aBAHDyWAcnRvA+N9MBcD3HTyCWDz0DQ== e=found last=13 s=25 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAjoPuogLfEK1bVbvm76Bj9gCfa2ARy4zKWw6WQHf+J7M= priv=MC4CAQAwBQYDK2VwBCIEIGMM4f5U3scHStFaJWvoKY4kkUVR5b14L/OEtoioD+gx msg=X81Kw59EwGFq3W/5pxTl/m90H+1V3XnzgINANoaiZDq4t0ziY3Isb2XqBnKrnWA5NPJlTul6tFwHYExiLg3YJg== sig=tuL3avwptYMrrkyK/NHqya1+WU8lUzMXy4wyYK99QFEiEJ6HYVodsgcK6+FR26dgkmUonb9HRIlXTp81spRRAw== e=found last=13 s=26 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA6NSF4It/S8bNcev8cHaAeP2MSMGrHpbzWpUaIOfwMZQ= priv=MC4CAQAwBQYDK2VwBCIEIJzR54Ymy3zAYZqyVZpK2pfL3NJ6bl5R9leKSH/Gq9/V msg=a3RxzNAZPy1r3eVW3MXSYIeOB+4PKIohk7cR59Dh5bec0eeGJst8wGGaslWaStqXy9zSem5eUfZXikh/xqvf1Q== sig=wNFmm+Yh3sZkon/jFV/zVQP7JS6OxDEFvjUWIPOBejsQrN2iJjJ9fsB2WOQje5E4hYj0f16wld9saWGCJTvjCQ== e=found last=13 s=27 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA+stRpRotKBmDBpYDeeJZuNxZzpmNMoTZ6UfAqE2K3V4= priv=MC4CAQAwBQYDK2VwBCIEIP+1JQZtt/VzfaJ6U6sS9s0U328tueFmPIKMJvQKfJeX msg=bAV8y5Qe6dghH4fo5Z8ZghcpQQcxXoMzhnfkDpyIr53IreitTbOb51sjcqvsw7lyZcIDGbnRvekOt0EED3aLcw== sig=k+Oc2sEfv/UYEkjb1YIdQ341n7E2Spa+1i0jt0i0Y+i3f4h8TtOTCgPgpU9VKXE2+W9zrR5XRQhlsuvwdCFcCw== e=found last=13 s=28 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA1kWEIF7NAa571pSYKFP6/FoHC3UsFtDtS+Zn/tYlDas= priv=MC4CAQAwBQYDK2VwBCIEINti1RWeY9fWHB/JVKEg3lMk48YxHgADqUFa4zMxIT/G msg=IYP+q3L/qMvYj9Ct9PPyWhYTqWPQFR13ueKMITKsN6ShJZgHJM+N7uuaukhNxKplHlREnppQ22LVFZ5j19YcHw== sig=kCFBEtUEAxs+QXMRb6GmAN5v2QhvWCboWk38IiN0dY8EKWKSSlxfasBrUmLktV1lrZNl4tIvdjo4pl+j73NRCg== e=found last=13 s=29 in subShifted_NP", + "pub=MCowBQYDK2VwAyEABHFFkRu1a99IMjSNz0VSCJdT47/67h4td+/GP14//Yw= priv=MC4CAQAwBQYDK2VwBCIEICq2dhRzznDvtT2M/qSE5ahXyFzpK6DYCFaSAWEWqMur msg=CiMatKjjySsA1xOgKrZ2FHPOcO+1PYz+pITlqFfIXOkroNgIVpIBYRaoy6vHrMCp+s3TxKChHI1IJLQCFrJp2g== sig=04gI7/2bWvcgTGfXTisGn2/A2D6op0sddbR/jId9UpD5Z2XBSGsFSMkBcNf1zoPA3/Hb+FpSruHfi57t87MkDQ== e=found last=13 s=30 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA+Jb6J1+1hyheCbgCioYycSz0k656gIfhu4EfEUBVY2I= priv=MC4CAQAwBQYDK2VwBCIEINCly1IOGxydTAL43jRhRT675BL+sHbQzOZMElkwbLXN msg=Bx3Ixq43xi9PMhcOaNYngHHQpctSDhscnUwC+N40YUU+u+QS/rB20MzmTBJZMGy1zXe+zZJqpdY7mfJ0YR/G3Q== sig=nvl4c2hHz9ZymE+5jy65ztXduFh4ahdOzjAU7XXXUQozJL9YbAjrT93LFbRDdvqgMagGD+pottjpFVfu6DFaDw== e=found last=13 s=31 in subShifted_NP", + "pub=MCowBQYDK2VwAyEACOHnzv5ruwKgIv0NhYH7n6JMQv1BmDD5MYuJXo9eF5U= priv=MC4CAQAwBQYDK2VwBCIEIDGPwU7MVh2+peJSYgTINr65f0WvSuLZRtjMYh2JyiQU msg=tJOperaG//Z5+JsPTO8+KstuGLGOREOqJyDlYhphh5Wk0lJyWLGQWbuppUZ0mmfG3obzF7lo5ZP33Gi5JVQp4g== sig=iU6HlvfZFOKUXhPz+phCj1rGbO/8GENrpU1/VPTRdQYffgc/NcF0R9ZlSlD4xbfeb65nugZmHg432y5wz37eCA== e=found last=13 s=32 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAm28K7xP/coEXY69+BY5qdlHZbK39j/9xEeVwcLIC74o= priv=MC4CAQAwBQYDK2VwBCIEIG/+kcDtKkv+V6vCunYJrK2SbIlG+oBFXPXNb9vIRlX/ msg=Kkv+V6vCunYJrK2SbIlG+oBFXPXNb9vIRlX/7EDubge1ILVdZPRjlZz3Qjs75vb/rzt6M0Jp5PcGIAUiQ1mnfg== sig=U3cY7ZY60rcwfSFBM2Rn3ljR4laf633Dmdng7LgPXUt4e/CNeMUwk8iuyFYVJooiP+q98dWqxhwv+ucHFhWhDQ== e=found last=13 s=33 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA9BGgy7krNn6RpH0yaWPC1CSZBdKiQ9R1uNpHy+HWsMw= priv=MC4CAQAwBQYDK2VwBCIEIHSDZA/usvlnqN6Dc8v1S26j1nHRBoWeDCZGzYJdutrD msg=YsQ38VyTC6TBQL9CPaHil0xEuWkX1J2DELP+4B7HNiClPEc1oJsEQS/X2cpcHJYZRLxne8L19o90g2QP7rL5Zw== sig=SGST+Ph2sc0FmYxZRtz8w2bC09I2NqxkQipgIRtK/YNbQBY7/5GXN58Lkb5Rxfo4MRSPZpmCANrzUsGTEuAXAQ== e=found last=13 s=34 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAs4IP8oziqUpTza1762bPeIHKICM0uVGWmbqZIC9SXzU= priv=MC4CAQAwBQYDK2VwBCIEIDtlts9zxlcytnBZqrvVCP4RPwXDJri5cbHjwVq5tAqZ msg=Wrm0CpmXOGB8kBIuUTLjJMeDMCbBJuodnBWXpC8VxTI220CI4ayXKjg15QYig1YwM1E50LORBOunvhNa5CXF2Q== sig=CmWRt/hLECO0wAe1mVLOnL0MbDi+wcAtLcEMhqIcVhl4Uztz+kwGxSTfXghg/HJdjvkyDmsDvxlymLFAGcOvAw== e=found last=13 s=35 in subShifted_NP", + "pub=MCowBQYDK2VwAyEADKD+bv+zegZWgMNKvHoEQ5qsJa1+G7/WNnLNx/an/IY= priv=MC4CAQAwBQYDK2VwBCIEIKGmx/GfGnBASBsSyrH+9mcA79BKcjvQ9E1CEphb9q1d msg=KAZ+E28F8Vdk11K5L3zsykRP9LIlPzLGUa4Edh32ETMV6uBDrOvOER1XXBSFeagmtyCPv0oAwoRPoR36h9/LIg== sig=6srlsZwrDwPWS9xW1JDFuN/Fu3VssfSu+RQJe96YnfTM/PAZOaqiXoLYc4/Y11NC2g2B8F9t5rVPFGq9xscBCg== e=found last=13 s=36 in subShifted_NP", + "pub=MCowBQYDK2VwAyEArSpVjA5w7LCW7rdqW/K6+qHOgd8N2H/Q66eUmKFyOKE= priv=MC4CAQAwBQYDK2VwBCIEINC+UODfOpEFQuIEyA+fjhLXuoWA3W42JCf0RR8kOrLN msg=0L5Q4N86kQVC4gTID5+OEte6hYDdbjYkJ/RFHyQ6ss1Qfeccz5szjX/4eKg6FeUR3d/DIHcEV+zaQAOMUStHeg== sig=8+TwnBQzQgX7QA0K8IdOfFrdj14pFkb2TIma1mHGfLnX2Iy71/EeCgMac/Cp7VhTlmEg+fxlVARYmvBdvKamCw== e=found last=14 s=0 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAUrmA6SZe1nUZdYSfwll3c5SlP5l+Bx/tSpI036M2dbs= priv=MC4CAQAwBQYDK2VwBCIEIACru9rHDlUynZztpOj3CbrqzsL7/W3xEELplGv4qTKn msg=AKu72scOVTKdnO2k6PcJuurOwvv9bfEQQumUa/ipMqdxt+Vt7olnPDXKiEOYAQ07tYFKNIaimasOTU9G+7jg2Q== sig=eYzDo3KJnjopu9JYoxLmX4K4i/E9QOm/xbii1ov334xvMfqUHAxQh86x3texMkFMkjieJyKyemSkEQyUlV7jAA== e=found last=14 s=1 in subShifted_NP", + "pub=MCowBQYDK2VwAyEACCfYE0NMvS27KMTrDcGDXkpCRJgfGja59pvAEV0dMSk= priv=MC4CAQAwBQYDK2VwBCIEIF1CkkwLna1/YvpTsdHVoZxutGEahwNHvJEa69v81ppA msg=XUKSTAudrX9i+lOx0dWhnG60YRqHA0e8kRrr2/zWmkA3kkQTXwSVuiJIvIlb1KW4/aT+cMYlrhvf+MIMyoEI3w== sig=/9A7ftDF13H9Ud+HqB4UKyJ4iFkx20w+GOn9Px2pcGXBtI2lJ+yMIswHOhudqEw5iQlcDrkdXOgYVlZaaZKDCQ== e=found last=14 s=2 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAox5pJqmwwzwvJ7F25Pfg2pt3jkDiUOOLQxEtfngHVvU= priv=MC4CAQAwBQYDK2VwBCIEIGnCgE5Xgt2DSOpsVqDoFWOAhV7F0+3dA3RJIPu2d8Eq msg=acKATleC3YNI6mxWoOgVY4CFXsXT7d0DdEkg+7Z3wSr6YWcefb4OPhscmi1VetJkCltAV7SFi2KDachL51GarA== sig=r2lPx0IyrcqXmaNt+7IyBV7FYDhFPWR/nNQ2Jrn79/Zak6WxoMM/fZLXrHtRv4axcldImF/RQQ7ZkQmxdNXhDA== e=found last=14 s=3 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAHr7BzFwIlSraonHssOueXzQzl1oI3MdofgwBpAy4LCM= priv=MC4CAQAwBQYDK2VwBCIEIFds9tS6i66tuvmCKSYlManGPuTvQugih5MWPKRjzoi9 msg=V2z21LqLrq26+YIpJiUxqcY+5O9C6CKHkxY8pGPOiL2cFrEzYgLAW75V4NIIG9DrQMh90M8SIBQ+hy8vzgSUqQ== sig=OTMtvYqHUzmUDFbStGTqV5X7KFD/+JL91kYRLYWBWofMVnAdst2KwZuVxYSFNJNyh0aQGAijp8d4kUfFsqEECA== e=found last=14 s=4 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAH/3N3Bfdi7Z6wyE9HNzG1nyHsv7WjqKyFl88E4M22G4= priv=MC4CAQAwBQYDK2VwBCIEIPq9umF55WV3H/K4IFHcNHThlVowwht95Jr7/CydVsKA msg=+r26YXnlZXcf8rggUdw0dOGVWjDCG33kmvv8LJ1WwoCNmpyxkBxVDn1olXnJ0hPWLESV7RriF8I14Z02x245UQ== sig=h7+Wg1IhpMNxg9PJUIEW1IW/OGdFdBZOjDiDNrr1MbgcETH+i/J8YWV/RPAGRLvi1QlooYxoP5vH3NBaVN6YBw== e=found last=14 s=5 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAIp/klvM5Hd/ycnhGROLdVlMQUuA0WlH2ynpc09yeYPQ= priv=MC4CAQAwBQYDK2VwBCIEIGpFnW1yrCLaWhGR56YzDuzYh7/VhFrOte7qhJj4UCm6 msg=akWdbXKsItpaEZHnpjMO7NiHv9WEWs617uqEmPhQKbr7n4obJhO6tWLay3neIlH5jrH6imjATw721gbdbCdvQA== sig=lNg7ul+IjRHtEegWxbMtMJVjvVzsxtI7PHCyn803sYMtX54FxVQVkG12tHYqreXn+WbN22Gz9dlkCiGHxwSpAA== e=found last=14 s=6 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAXI2KPuYPVRaIa4w3QBTZZ/fJuqvnDjTzAi1lqc7NI/U= priv=MC4CAQAwBQYDK2VwBCIEILIN90CJhBrwHpxvZKt3xrAZ+wUWUk7hvJrqR6S0azSj msg=sg33QImEGvAenG9kq3fGsBn7BRZSTuG8mupHpLRrNKNgT9X3bSqR7V7XUuv6va8NZWdWL8SxmmQfk2VzY6S8JQ== sig=PtuqgEr/bYvG1nWBc4ra/vS6JMePDAYQF7ajDJrCMlXDlIDPeKAKtcsfxRH4ofLiXBw4WuGnDdsIaVker9d8Cg== e=found last=14 s=7 in subShifted_NP", + "pub=MCowBQYDK2VwAyEATS4Mla+2lh+RdQ1Ocu48PmWV/VM3Wr96KQfDMSyRIMA= priv=MC4CAQAwBQYDK2VwBCIEINmZvIojYq/TlvPypWsuBHUZGZH+7WnLEsUCJgzvGGir msg=2Zm8iiNir9OW8/Klay4EdRkZkf7tacsSxQImDO8YaKsGLMFpYdR2NU5cUqrumBqsbIm0O5EWg82kJrRjvjxHCQ== sig=cEZ9+cTPpPscbkjDq2tw7nknCfYLPiCyC3zV0C/9pkX4cfu9CiMahixL0ga67zHpxQD0J5PrFGx9mPhMkx0RBg== e=found last=14 s=8 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAg44T9uEqGa7QiI7Ju0GPSIIn9Jy2vFHscywQf33drVE= priv=MC4CAQAwBQYDK2VwBCIEIPN1TLnZn7tqLW64n2XtexGqtSrTcsqpMG2ffSFJQjBu msg=dUy52Z+7ai1uuJ9l7XsRqrUq03LKqTBtn30hSUIwbjZuc5ruFeV6hXCX4mWIUBEIY6tjlcWsbFyUOiuVYbbf2w== sig=4gnO3iXjpCv4a/u1UliaGcfvQDhjNc41I58iXt5YwYVUEPDZeLgmPxi44hkFRH3V2DEDNy353E2oOSRtDWA7AQ== e=found last=14 s=9 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAJO2TgZl45QJLSjUam4mWVPQ0h22q4uSlgrYOHbvv1cg= priv=MC4CAQAwBQYDK2VwBCIEICGOCk25WCik0HhVJ0fX/TKLeVBSam20TYwie/xbsRaf msg=uVgopNB4VSdH1/0yi3lQUmpttE2MInv8W7EWn2TUN8W8+zjC3YB0Sm7l5MCk1cjSm5y+jTbEA4f+7+PKYN9X5w== sig=Tvf77WmfrwdWSE5AfJsv0KileFIQsnCou4Crl3xor6Us3RG0IzUbFkLtZjot9ad5+3zcp3xN6lEHNCyulKaQBA== e=found last=14 s=10 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAcuKZD9MkL8m24IgvUHUqNy4m65ieSR+nWFESCPj0wNY= priv=MC4CAQAwBQYDK2VwBCIEIJYQxyjA93dZ6Y2BTsWQKODDYqT5veJQ7Et+8BNIPyh3 msg=lhDHKMD3d1npjYFOxZAo4MNipPm94lDsS37wE0g/KHcsNTFHXhbv6T/dB5aK3cBCYLjGpIKDbDFm9YWgQIIB6w== sig=slqwfNi5DJvcdz6LXGNABQFtVYeAznlruDNIwSqVKQulRqy+PdKTWNvsyMZb/32LrIejPzySYiBes0MvLXm2Bg== e=found last=14 s=11 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAgPw478gkjq/g+IidYjWQTpMFu9DdFu8wRQ1JUiAkBi4= priv=MC4CAQAwBQYDK2VwBCIEILkXuYOCJlzQKJ8Fwmu05DtiXJwmDrG3Nca8bPU+V5PT msg=uRe5g4ImXNAonwXCa7TkO2JcnCYOsbc1xrxs9T5Xk9NXRVPYtH+eTCEmspRHeI6B7C4wIFOZpBhq/OTQ5+9SuQ== sig=DohKFdYeN3vhyY6NJWOUzBYYsMVSIU6psNc8b5b9EreIYX2kDdlNPV0WhrEEr3/n4MLHsYcTZnNQp+42SPuWDA== e=found last=14 s=12 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAnHfXEmJ2wVuWTbT98vAhNTK1sD2prZQ2xaxlNhN6NDM= priv=MC4CAQAwBQYDK2VwBCIEINokiK7fOOZlcv5khot6gTzsnB4y9eEb71fWNHuzmvBe msg=/mSGi3qBPOycHjL14RvvV9Y0e7Oa8F6aRJ6FwNqfe1p1Q+sGhy0IKlOngJcqmrs+QHzOk5/ISSCJCHoS2p4gwQ== sig=Wg8mMPHAONYEKBtbX43K+TsvRbIr+E6EWUV8hutmxeSBbeuXYUX/4y4EqofqCS6cHvuSGmLUBYQUuTujDBOVDw== e=found last=14 s=13 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAsmQw4VC+O5aySltPDZpuyLJnIJOT9Jk2ycKrrGiUwGg= priv=MC4CAQAwBQYDK2VwBCIEIIc0vyKV9JO0RUZplWIFWRtgmtwBHgzVprlofSjnRAYh msg=K/RN+IQGEycN5IklrFYJx2aQNXDo3YF+rfhJ6z3MHTw8I8X3bSAJnP+amuWfuCE/EKHdOfeIVx+l7Ew22a9ZXQ== sig=CW0fgUaArksW3RYCgKl33glJ9lpNgVXGDDZs86cqwuzUEGCMBow+0Tz3EAUJgwJOYllIKYSVpNmh46SbwjfmDg== e=found last=14 s=14 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAikZTSHt8+kzMZfj8a02ytJlLnNqTt+rf99oFA/hKybY= priv=MC4CAQAwBQYDK2VwBCIEIFROjMUdRdKV6+fMX6smLk+1ao4mIvN1wUzQxN+jD502 msg=Lk+1ao4mIvN1wUzQxN+jD502fkSboYgOVesHz5fC3H8mMT8zHmQ6zJZeVxTbHLxWAMtMZI7GUXsYY05dU0Bjgg== sig=5f9GEI7zRHrHe2uPlg5OrvNORNp6lOe3FA2olhj9r9y6TjqGTQ312XyTFfRyECJ77phB0nqeG4oszG7uiXFcAQ== e=found last=14 s=15 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAv5BhJX9NY8XwGtTOcf4hQOGBCjoCGRdlj+k78pgt+9w= priv=MC4CAQAwBQYDK2VwBCIEIA86c/pn02koBdJUXMJexT0rDTbpUxDJpTGmHISws3vU msg=Nq0KyaFCnkylokAEirAUcgKt/v631+CU1LMNzoiGmMiAZwewq2kz3+n7+fuq38nTrco3zMagfvSmz4FIZsf9tw== sig=h1OcUwWK8Frv8X1AuCgoZlOJmsAdOfvASg+Vq4E1W9u2q0hokHEaGwN+sewjmLALieVfDOlfMN3QKxYfowMNAA== e=found last=14 s=16 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA0PXwb760cHNZCVG5o3KfzU8pITFcFSXDbi+qQDYk74Y= priv=MC4CAQAwBQYDK2VwBCIEIOnjvFAiRiwj26H9LYPDElxOxjFu9AcBLlgzkiLafQ8Y msg=5b/cNTSfKQSInXyW8Ys3E2oJ8GS3LND/Z61grfV2aHaYMOHunCnsStY3fHwEdeycBe8nVC9+sCksRxQ3udHf0A== sig=8NFnGKdMair7CqzSsLuFOVCUEvSHDjUVH4m5Bz3qr9mOcsl8xgeRs4Ro/KgbU2GJRugHnttocRWvsqIH4frLAA== e=found last=14 s=17 in subShifted_NP", + "pub=MCowBQYDK2VwAyEACZ7rrcDbw7MkE1xYZvOwrovPyCj1sgcKcXw5U/nqnHg= priv=MC4CAQAwBQYDK2VwBCIEIP9iHYQeTeC6clgwx2kpAP4LwUpPEjguhU8Oi2R2Tr8R msg=gTuUz+Sg7aG4SabALhqX52GK+p+zGyxufWtoLqLq62sUifbrtgj8F4czJIKb+FkIM/ORkDTFeB5AR/NhD4F5LA== sig=T0G7iltrMGbrbavuCtfFDBo+4pVhIdT+5qyZ8zn7YQeJJYT3lrtYJDKny9QYRxknOadayhrwjDc+fMT0zlxcDA== e=found last=14 s=18 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA/F8kUfM2pJRmMJRSV9Mir7XOJfQfQUZVQkB0oLnY/II= priv=MC4CAQAwBQYDK2VwBCIEIOyv9DdWii0/m6+Jzy4XoCeqdV3QeYJUsD3ZTzfVLw97 msg=LLyErFZqCsIemoY08F4ZBYx6SddkzGkjGmcBq15mlLzkkXe506LUnCZoNyxmSceompB+QrdOkYAOit0/Tqo8JA== sig=Ft3QMD16hHHV8//MHOyUmHD+WBgbdY5WPB402MjAMhEzY3RCqHIsm8eRt+K/rAx19tNMTfT3geRTeTcUTNN8AA== e=found last=14 s=19 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAfeKoj445Doqbk5QZNmd2K9QP9UaAAjsqx5XknzCJiNo= priv=MC4CAQAwBQYDK2VwBCIEIBN3kDoG/sN9i1GeoKxj7sQq1tjFadHLUVYN/sqC2qbA msg=Zn/K4fF+4QbrLyhdw0yi8FMO7oCdgJMD/M/5RrCnYNIPLsdiTmGnFRN3kDoG/sN9i1GeoKxj7sQq1tjFadHLUQ== sig=qeQYhXNfUoLjWzseUEJswO0qQcxmZdJkLYR39Uhf0CepSj6uP125rbyrNtqtEcqxrB88Cv459wBQ1qPzd4C0Bw== e=found last=14 s=20 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAHaCKjp8TZKIKE3RiV0D3xzfT5+pMRytajmm8WotxMwc= priv=MC4CAQAwBQYDK2VwBCIEIE0HVehlVLFBqmUlBmMrQeW7OyPtf6R2crpoPgIjp7/x msg=6R2sCH5OdA+fOPVfObSrKmrE+cTTcaJx+gNtj333/ZUgrGHkxZU+/hbV/fWVB6yLq4ZzW4QwfWX9v0by94bV2Q== sig=O0co8fmHsPmfEIBiQlw0vx7v5CopGE/1rWceOTgPiIZIvwCNRpj9S1VQRx2kxRv1LE/aIh9RBtfHmVWaFDR8Dg== e=found last=14 s=21 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAG85BbWZTVSSWWduYvGIulQp5XLQFgs+u7Wh//kaQHy4= priv=MC4CAQAwBQYDK2VwBCIEINsxUuFwQSd93SLgK0f1mZ/9sQjxjThULtgYf7xnI8Wy msg=GH+8ZyPFsgSo3ZJiEDC1JMGJ0v+Wml0arKsfZ9OcqDD+4u4fMDyx0QkyIkXufoUfsih0s8HN4iGJifLgNzzCBg== sig=ztVuYKKeKg2+J02hWuqlS+VGPE8l90V01DhwOfbQ3ag6pL8I0HPLofxDXIA/wo78U5p2I0GYWPvSfTeSBLz3Dw== e=found last=14 s=22 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA8QSGVDyHFgS9FCMWJl8TcRm6Uplx4ashpQBSt9maDIM= priv=MC4CAQAwBQYDK2VwBCIEILTSHyHMZTx/0ChAaBLAZAPnqha8dqxCi5tnFT0ElOYk msg=5nOKsEhXrErNncGBFlUitNIfIcxlPH/QKEBoEsBkA+eqFrx2rEKLm2cVPQSU5iSdrKYrJWG4Ozy7zCjo1zIMYw== sig=lsu1Lp++hvOu/fYf08XByAX6aMCk+M5rPE4xDbAhTYJPxIvOk4jLEiWiuIHZsb244byshoX/ZHAvQeDN1jD8Cw== e=found last=14 s=23 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAnNUwb2W/n2Dljqxg3ePBHWP+j/7KaJOY99Cv8XGwgeM= priv=MC4CAQAwBQYDK2VwBCIEICfItpQZvPV3pNXSzUlS7GCwfzuUhvRGv0kRWK3AX+YY msg=uN4608qRJ8i2lBm89Xek1dLNSVLsYLB/O5SG9Ea/SRFYrcBf5hjnOuFZbFDrWPiGYq9ofTr0bAJBCtkk7kfyjg== sig=HnS/m9WOhBLgrPV8W+is3zTZmI/0ruX4R+6Bu+YFXs/gEheFOdTjq34XZP1vqLc7I1eqjdRG/bAShWsWReUcCA== e=found last=14 s=24 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAS5AR1I0Dm0UENSWNm3EL/W+6Ey92G3XKC9qO/as3oGw= priv=MC4CAQAwBQYDK2VwBCIEIGqbGSBspJuPKs8wayqnx6fD19Y6OpP68H4z57FwgB9x msg=x6fD19Y6OpP68H4z57FwgB9xSl/G4z3COsFtZFB1KY2viBSWG5yN47kHfi6sJ+yvpZujPsbY+50fSMHf+DFULA== sig=eD27n4x+5PFxZNVK+Xvg09MPlcUCDhwFclFnzkWoi/+Fh7LQGLik0qHs9O+HZptU6E6lQiCvD8h0B84ByHzUAA== e=found last=14 s=25 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAg1/SoFTJGn9tzkYXB1sOieMwi3PaT2JJMizJQdFixds= priv=MC4CAQAwBQYDK2VwBCIEIDjAoxJoHScHL6KSSJVIDAjCgl4E8UgDtJn57YAx6hNH msg=rs86drHHBXUssV9pqGwycBLHHgYJl2YaYbnUTkqiOwndiN89cxsqGF/gfllou8DplgL9TAnAF0ph3vNh3yJtyw== sig=A4MaSxSQzw8de8p7kH2ENB6dWoDCPnTrgvk7WQQ1RLbQ3wVWqmPUbckTBrOlw0WODVXr2+EPrei3t93bhWd/Dg== e=found last=14 s=26 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAHx9xHm31qQbBuK/rIHdAI2i9Tc+DNCxWPFd6gjJ6MC8= priv=MC4CAQAwBQYDK2VwBCIEIKAnnzu7YXkU/5XV3PUICqh5iXUea8G2wkvfZrgHf0/p msg=h9bV141APtBjH6X2yRGoApRBzzQ7gmDZ7toxiNcATGAiRB+8a2uOco+yc6lxoST9DA7bazISV2IPIKw0flf28g== sig=5Emp63BKMxaoidDd1D+Z4eJ0ra97GL1/YVHaGwZp25wRuXg0TYKh03ZZdv79Qo7SSMywDX/2GB6jrXq/7+FXDQ== e=found last=14 s=27 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAC41msvvc8BsyUrFr1ei9dq1MeqoXyxkbK76OIPFyR+I= priv=MC4CAQAwBQYDK2VwBCIEINkCeYdXwD72aTZU/1GMQ647Gon6OG4wN/Ahd/pq92wH msg=igJZv+3ZAnmHV8A+9mk2VP9RjEOuOxqJ+jhuMDfwIXf6avdsB+xxcruKS3IbRPSltU4XB7DBsPF3B3JsGaym4A== sig=NtQlubz6vG1DooJxHT6ffkWqNsJGMWH4OznyQX3fHJvmKU9Ih9bX+ZrSmuqY2HT0YTFnSM/18l2TrBmH+qpqAQ== e=found last=14 s=28 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAFUEjNOcwiyht7WS7K1CYUg4qo/q1nrJsdNrx7RJ2Wdg= priv=MC4CAQAwBQYDK2VwBCIEIE4qJx1zsL5y7T35Ra2v/AFXrB3IVmyjipp7xCsF07yx msg=xUyrQgk8TMfvh65q4wCsrAJr3/MhRguGTJWWHHPpJr7Jce0VCmA58n8kg83/FoROKicdc7C+cu09+UWtr/wBVw== sig=etmmnB2cknmfBTbRvUEy2tF1RJ3sQxb2pM4nJaOs6FoC1l7+sDvOpOBY0g6AKgKxo4p3IEqvc8XyD5A73UxOAA== e=found last=14 s=29 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA0PMdNjMNCpOf3obup6fWiXn112pRaPhsNJZg0OPzIZU= priv=MC4CAQAwBQYDK2VwBCIEIGld0udu7pjSyOw2U7sWX7p304rhGsj3T7fING7sxv79 msg=Avw7hLn7OshU0ps54aztYKD98ixXxhxVoofx+1RfG7mbiGe3dWVgqts9Dj2Yh6wQfK3441lC/Dd1y21P4G2Ayg== sig=Rh7UYU7AzUWQ1G78MWaW8WeVsaWscRZ3XMAL1C0fBKTs1bHjuckpo5X5oBC54q/O1B8OtzPSwrf3W4gCwAjSAg== e=found last=14 s=30 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAFRpiqT6VYuLbdrrdiWnpYYw74zq68UhIJ1HhmuS8620= priv=MC4CAQAwBQYDK2VwBCIEIJyvVSzvwQu1vZzWWAlij84HmKMkzyXepfMlDrJD/Wiy msg=Yxdh7WvZhDL9533KBxdcg9rRlVPX2kOcr1Us78ELtb2c1lgJYo/OB5ijJM8l3qXzJQ6yQ/1osqKY7E4ESk/Q4g== sig=xq4GCxPoOYStspP15K/8B6gD9iES56nmVDKEk9y8WPzVYyC5YBSPszQUMMtFHZjMF4RokJei9L6CNw3EoIT/Bg== e=found last=14 s=31 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA9FKRQ6OVM95NU4P/Q5940GASqnOAfSzD5CuVJc6aZxM= priv=MC4CAQAwBQYDK2VwBCIEIDLK+c4+cMK/+sJKi9EB8QHNBKNmGLs0S9Bop6/hkB6S msg=0Ginr+GQHpJCGrkF/b6GgkO7jPyb7JDnjTm0YpIlawS6Pp3SrREWv5ThCpUd2trm5ySVlQp5gGGtmjRpAOkAdA== sig=1kpG+hNW865unFQUdnVdHL0F6H3jIFC4CCo0CYKml+wOJe0gSZ4nDI9ol8Rfmq/sALohss79h35b/rd+PQDdDQ== e=found last=14 s=32 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAWreZ+PD6f7dxNGNtoZOPY2Rt0IsBIJnzZSpoFgPkH1g= priv=MC4CAQAwBQYDK2VwBCIEIEW9pQDt2sw3513ox9rby15tT/kZjptFyCckJvkAlKRS msg=bdM5PP16ujRQdJXkBIgX/Zbm8pm/7W9FvaUA7drMN+dd6Mfa28tebU/5GY6bRcgnJCb5AJSkUnKbMJPB2oXxuQ== sig=55E5lhF+7fpIlYDYVinChpbnBHQqaq3ctLjdVpTlt7lU/jo7oMGXC67YEM3cp4H5TcwoY1iwkIsQTvnrb3qXCA== e=found last=14 s=33 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAeWKpkhqvJGaBNUHcGJERJ7jCKeJLPkgf3fFTr4taBl0= priv=MC4CAQAwBQYDK2VwBCIEIGdrR0LQGGbOgaw6UUnF3W1APi9qAeIxiC3Hlp5ne0B4 msg=WxwsPFNjTU5xP/bFOyBj475sdmxmvDhs9jx8R9m++3f7zj3gBsgKv6QDR5zwfAtwK5Zalkp76OIAwDGaqu2nRw== sig=CDPyyj9WRMQMC3M7ZV4iu9mjDNa03X5Yob/rICEZTN7/8LAbRuDzaUaB0uxJ6DzSBjmmQKAZc+iUjOA9+kKrCw== e=found last=14 s=34 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAafrjyw9TmjNAtcYY73p/PgSz0pD2vXNX84Yp7qPvF2I= priv=MC4CAQAwBQYDK2VwBCIEIJA+B7Wcg8xWHPmpEO6/DdGAkUZL2eTXI3BFTRgCO8VZ msg=HPmpEO6/DdGAkUZL2eTXI3BFTRgCO8VZ+b05LT8H2NDG38cvxSimvCE+4UibcfSRvwpq568qd/np2HYRF36eFw== sig=22FROfguVCamKxJIjuTblkoae9nkTRcQ7FN3gd+z3+GC6bTzBje3ZGsAbFlz/xUlMXd7T7j/jom7TzpMbx/QDw== e=found last=14 s=36 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAUC1rrJqYnJUlSjdtw/h7AiRrV35U2JgQZ2y64pkrw3A= priv=MC4CAQAwBQYDK2VwBCIEICIQjYVEZ7sX2zO0WIIt4vq6cJChxbyLRJXT7ZgZrH7X msg=IhCNhURnuxfbM7RYgi3i+rpwkKHFvItEldPtmBmsfteebevNrDJnaxeHi9b+eG1FzrNhLxkb2Qu+i24dz55q7Q== sig=/5siLluNHP7Zne7N6VKXd6MqzHx1n1rBF8hIdAHu/W9F5JCqv2u2OZrt9uVJGPNXuJwtYjCw2MDYtYDfkBAJBg== e=found last=15 s=0 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAK7mCAXGd7DY+OaKT8f4xkBeRzQQ6P7ghcHmCxKg4jQw= priv=MC4CAQAwBQYDK2VwBCIEIGCxM2IVsLPH0NS0iGdDRow0RDA8yore0g8L2GYGr0pk msg=YLEzYhWws8fQ1LSIZ0NGjDREMDzKit7SDwvYZgavSmQUTmsmi9z+bMdIo054TxoZBuniJLX1l0GztsVP8RALsw== sig=58iKbQtzv61RvW1Ksao3euioHPm769UQihSMgopALBaTQG69nbQpEyL2zsYoq35m562Ypnx9/mFq/uV0bj49Dg== e=found last=15 s=1 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAlB/IGlnaOpKHz3qpR/f7i83pbmxsvjt6RC8KLYIcEps= priv=MC4CAQAwBQYDK2VwBCIEIMajxYZbI891LtZscvF1rr5yUe6HZfGNjmTvR9vpQb0t msg=xqPFhlsjz3Uu1mxy8XWuvnJR7odl8Y2OZO9H2+lBvS1y2IjN+pAjgo7J9T56nTUdw6sDZOM0kf2NEM+297ibHw== sig=+LBpQtXaQabx8Be9or19wjlQITyiGMYBTAOOytsgw1MpGGMdq9/f+62kh8F9xjDRLBaXvE75v/V3CJLNNhbBDA== e=found last=15 s=2 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA+iDTbPH8T2ZcDU3mrEibgB7EuWuR3FQh9io3A2YUt8U= priv=MC4CAQAwBQYDK2VwBCIEIOPKqzzSFaUl2i5P5Qb7tKbwLp+7c7e7eeYwexzlWZx7 msg=48qrPNIVpSXaLk/lBvu0pvAun7tzt7t55jB7HOVZnHsUk1b+tisk/cUVzCAVFHKcgpE4yxjy8Jg49zG2o+0jIQ== sig=2LPcnKJ22GfGapX83qmZHGtGmbr/z/Q9VzooWWPvAmnFKg6fkL6+i6mOKCSYB5jGBbtYRcUMP54Ou62OhdccAw== e=found last=15 s=3 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAZsxt8mPXNweru97xumepOhY5AbbMEezJDaTEPMywgQw= priv=MC4CAQAwBQYDK2VwBCIEIF7GRVvIr5AL4KmMDJiO2VZ6M7rqmEkCgXPELMh1Qfrp msg=XsZFW8ivkAvgqYwMmI7ZVnozuuqYSQKBc8QsyHVB+unqEMArYvgAmmtDjuwh5n7n3EoypTj/CWsfXEDCbE+DtA== sig=S1XOmC3InxDBIaxu0XvokHhX2dnDDYgKBWfPS6QhHpBYxeoPHCIg7ZO+ouUzq8FXg8lyg5ZgY8wbiEH9GhimAw== e=found last=15 s=4 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAbK7yF2NavTh6lO6tyNbx55/sGchWhj9ecGPTnruOVig= priv=MC4CAQAwBQYDK2VwBCIEICG9OGZZdue1U3/4/GJ3gICwLnYF/6revXmqkzgtGtf3 msg=Ib04Zll257VTf/j8YneAgLAudgX/qt69eaqTOC0a1/dR4EAofxWxFlrs6k5ZqgwbQdm4huliGWK5ANXdCNvy0Q== sig=/1yj/DisQgb0r1+Sneiu7gmtdNb9a2JnVcOW4J8y88pLJUKSxHZFTqQF9W8hYXoUVoHYSyWUL3FBS8eM6u1hBA== e=found last=15 s=5 in subShifted_NP", + "pub=MCowBQYDK2VwAyEADMRod3pzq1twUtm+FmvR6kxgZ6Q24kQ83g5kf/5UICQ= priv=MC4CAQAwBQYDK2VwBCIEIBEgR5F50TrSj33KnNi+ApH+SuY+TZCmGBqU7rpU2rN2 msg=ESBHkXnROtKPfcqc2L4Ckf5K5j5NkKYYGpTuulTas3b8+AplIcjUFNBxSKDGenE7wLEu0RlQ8Y99F80jQwp2Mw== sig=en3wCT6xW5B8PC7RywJB5UcNLblIAY7qSe1K/QxqVcn8ozsipa+f3nr3jY+INJreOHUBfP8b8rESOKb8gSlvCg== e=found last=15 s=6 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAScwAAocf4+eGsN2fUEItodZP5Q6Lsd+X26DPLkLqe+Q= priv=MC4CAQAwBQYDK2VwBCIEIBk/m6QC9JIJIX2vDtGfnfn01zZgPJ1aCW366dYgfJUj msg=GT+bpAL0kgkhfa8O0Z+d+fTXNmA8nVoJbfrp1iB8lSOzSO5i9016mC4WHoiFr+5hGOEmSef45Pw2wwNaUVqOWw== sig=YduMLTPNPrkV5bh1ZJKft9/MnUQNLqseKnBib+FrfCCKdoEp76lsTNfRb2+0doyYMvtVIj7qTjrq3WBomLxMDQ== e=found last=15 s=7 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAj7UBug1B7Ut6/UAiZ0Bqbx79V+SeS/TObzAmma5ztLc= priv=MC4CAQAwBQYDK2VwBCIEIN0IMN/PYSPJWBN3hoWVMkICkPY6N8PtR3vcSBs5DtSN msg=3Qgw389hI8lYE3eGhZUyQgKQ9jo3w+1He9xIGzkO1I1G6JqWYplQJNH0pigQVjpHyy9kgBqd6MGsnMgW4HSWAw== sig=C7ckE5H1vLurQFqIkMPVRbTYIdV3th5iAIZHw5cdFdUbVTx0n+WE9NRZDzCwFKAfLd/JxevR9RBjlAcU46PVBQ== e=found last=15 s=8 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA1oNlJXlk2E48SmzxjRyuBYGwA1iJOA4hkurfmtSmKls= priv=MC4CAQAwBQYDK2VwBCIEIIYiRBXxijKkkKfrc/vTdSzLwboBTistMjAeAifnI2b1 msg=hiJEFfGKMqSQp+tz+9N1LMvBugFOKy0yMB4CJ+cjZvUe59xAFclfXuh9CUSR1THLHu4giYzvI9uzLuys1GlwiQ== sig=yIOvn7LBvnkiNzAtI3/GQln/qIbp0QROREHqxAUFQcxovWCiJkDIE4OlYpRPbzwG6+CwzF/zTSAZwvKcnxzhCw== e=found last=15 s=9 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAMyFRGOT27U4hXrLr3CN0WkvNG6yq7duXTxdy4PVjCbQ= priv=MC4CAQAwBQYDK2VwBCIEICSq/dZTvMjrr8Hg+eN0gK65gxyHlaYUe4r1U1sPihCx msg=JKr91lO8yOuvweD543SArrmDHIeVphR7ivVTWw+KELEQxZOwPb86WVJjBvd/ukTHdR7DZPo8VcT0l/ry34EHpA== sig=KFmo8ftzXVqSULCUMRUNhlBMfefmy+0VO8UMolvF+UOotV1JwkEEZOcmSyg9EWVKIXOMB68IfH1K2gXpHQxfAg== e=found last=15 s=10 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAKaDrKtijJqQNTGAs4SjXCDeppFhy/+4hw0EEcP7RDuQ= priv=MC4CAQAwBQYDK2VwBCIEIHvxvxcNZx3ZDWCrYkaKlas9jiasu8iH3H5FwBEIAb7Y msg=e/G/Fw1nHdkNYKtiRoqVqz2OJqy7yIfcfkXAEQgBvtjHAMJR1bUg1qnRH/1HhMbrLxLXGyfulx+F8cjJN1esvA== sig=sFTX3iyflKR5m2sR8rP6ewIsjZipzmf++c2JEeaok2Q39Mr6vk+9fjShgLxcFIFFgT231uefW/NuOaXM55zXBQ== e=found last=15 s=11 in subShifted_NP", + "pub=MCowBQYDK2VwAyEALXeyps1HGvnry/sfxJFQL74JB4fp364ZLci4sxY20ug= priv=MC4CAQAwBQYDK2VwBCIEIFHTuURvDUZMA5MZBkpI0yzpxlUnfiKV/heGDMn252uR msg=RG8NRkwDkxkGSkjTLOnGVSd+IpX+F4YMyfbna5EukDTld5Q1mSeSpmsVMgHydYkxP2UoedKRk5SnXRNau3LzDg== sig=Z9dj62fa58/n87NByueSsYTRqIVN4fDrPCboA4gn67LbwKvk+mxqW7q1VhuIbezE/zAqnR+gSHBcpqULXNIZCg== e=found last=15 s=12 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA6Dcj4MkHU4xBWLKFifU68MFEWCIF6SghDt6IqlLJmyU= priv=MC4CAQAwBQYDK2VwBCIEIGy4Ilmouhud5VXi0lORWHwOTQJtH6yqrfMdDKP+l15y msg=HQyj/pdectpV18BNI/oKscXVzA/U3FFazG3VudeNQPaqdYKTDgqj90+w39YgmEASEKHAiJFOgBwPCnW9u6nAgA== sig=QEL8y1Mi35lT/oOCeKKpXzl96RA2BBfMLDa0KLiuln4Z2+KR8qchRrIRfXXC9t1H7b2xmJNxYOuRPwXxQcTgDg== e=found last=15 s=13 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAmRhZw8oEnIrry5Z7Car8nId/RZIktNNM21PhHYcC42w= priv=MC4CAQAwBQYDK2VwBCIEIH/2eGpNDL9bt5u/YX/QdVPgipkSn2M4PKJbCGs6VNsF msg=azpU2wVQq8+ivBND+3koNl2tBg4PS0AH4uwQFxtJBPoh9RpJTfn7GFMyU7FMOqKFHuTjUCo2HIHvHTWh/axxNQ== sig=lGfSbaVhYfAin+eplZ4CAjyLEmUsjG7osizR3KuCxWTzFlldvUSsW+Gm35xZKMOauRZ+DkS2WvNTl/N5D6/BAQ== e=found last=15 s=14 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAJOtRlu0L9Bby3Lt6hGKO1ZKBu4ojLFtIsoXYzkqoZ1Q= priv=MC4CAQAwBQYDK2VwBCIEIJPwWgfC2F2+yHHEzn0EnuB1k0u2zf3JFni3uJessp+0 msg=BJ7gdZNLts39yRZ4t7iXrLKftJhRr8cU7oJi6R9tR6HL/5T/Ay6paA99m/5W4xOvnLXMLYyQMiIKWL19xpwl9Q== sig=XW0K1md1tEmNCBTpGoA3yRCB3Op21iusDK2AjsZNAn1QEv8sU0gfryAMsFcVNKBHfD/1O/rFhEnIilJCJzxmBQ== e=found last=15 s=15 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAPNyof7w3fkcXoGkxej+pRuOo/lZZl8llz+sFTC533pA= priv=MC4CAQAwBQYDK2VwBCIEIHepITUh/wU0rOsw+gj0nJDVBOP8NNcfPunnszWuOMD8 msg=9JyQ1QTj/DTXHz7p57M1rjjA/AXTdXJ42Q2agrQ2q6t2/QtKXw38ruzd+Cgn7BiQh34VobH1nI+U8iNs5Y478Q== sig=AjN4sKm3QzWhPmYxz2JaJnI+Lg8W+k6HisEd1zuUUgYtrN87ZU2WW32tV0kIUD9+BN67wc5kHxh+8SEPZavrBw== e=found last=15 s=16 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAzkHxJznPU9DJiucv1+2X0i26nE1i0mT/r1nJhYIN7wE= priv=MC4CAQAwBQYDK2VwBCIEILLR9xTLKQcYv2OZnMfsv+n5SqJa5negXoPMGnUTYGnr msg=wCqaHgQtGsfUQCmB0podKvnqPDPVffe+VledlvNK+WHilMWzUrhGIJxEOs+B9irK4Z2GlpeF5tegvEDotsBcgw== sig=PI7Zrpi35BOUYUSJRSLoByUb9qLm/SMmAHsUBqV0ctRDWbTZ8ykBhtVtJ3goYM7J9iF3shya0vWNN/S9/MJ6Dw== e=found last=15 s=17 in subShifted_NP", + "pub=MCowBQYDK2VwAyEASGSB0Fn4MOHyAzNSOjsrHujWhMdlF/Y5qUMTUElJ6q0= priv=MC4CAQAwBQYDK2VwBCIEICVS/lslhJXcd8QlVfmCc4pWYQqsLKD99ER6s3sje2i2 msg=cnsPsY/JS6jGU6EGMsR6gXe6J0H4Jl3LZoqzSJNKUmfL/CJ7T+H3Yqhr7FARs1Y3+imigLev/sc4drLSDO3ibw== sig=tJmNH9AY+YoAWCICSnEyaf8fqjM8du3jJRe0EmEtzcdZd6rB3SbW2yQp0wIHClZXd9OOP1srEvo8zJ74rfGqBA== e=found last=15 s=18 in subShifted_NP", + "pub=MCowBQYDK2VwAyEABRY1yzmzOJvB7iZubJVuf9F5YDn84009N7E4DrBQoLc= priv=MC4CAQAwBQYDK2VwBCIEIKw/q0wCL6AyKPnxq1zTPg+TSbhWXcRkhcOqBu3cWZIl msg=8c8ugaw/q0wCL6AyKPnxq1zTPg+TSbhWXcRkhcOqBu3cWZIl1o/ci9DU3ei+A0CkkTz/4GwCWK3rFm882vaGJA== sig=1naAyx2bkm+SE2S8tZ4iybhTm0TuAdjpSb2UzJrSShRSumNODc8/szccFsPYMJua8Fb+E0jqPHpO0ChRGtrLBQ== e=found last=15 s=19 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAsO6k+vQg7tnj3fZdu6CCQF9CW1s4rvb03pyQBV+2emU= priv=MC4CAQAwBQYDK2VwBCIEIMXKsUH14w6eQ5FZb/QBvsL92Cljl/yJO2wg+phHnhbJ msg=bCD6mEeeFsn6shSIMur/Wm9zCh6elj7Dz433t9O6i6QxXNnrcsPMKiL8o7K3ViU71Yp0/iy7vhZmVfIJ7MHb1Q== sig=GAyYNfKdvvj5RxuMlAAxk3MIEZ3u2zUCF8MXyWpHp9ncBAsr9kNNm1XdcXkBpE6hEXwo4bT8z22cJ3klL5upAQ== e=found last=15 s=20 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAa8VuSIFUJl5cRE4HESdgHI4Dd7es+GAUUHG/X2Qj738= priv=MC4CAQAwBQYDK2VwBCIEIK9ytpbI9HQAiPPTRPX+ex7kGQN93JnCSzrYP261js46 msg=O+C+O3R3/iT72dRyGCMVGFjYtyhHr8Q8YIKd2CWG+J5YHK1/d0RnotxKGbQogPY73Q8yE2/ps+4g+6oiU8fLhg== sig=eIuLHX6OfXEW5V88/1sE8m+wh61ONYtFtY68CvUpKoT8dP/j4xW1SfF0lfqDOQOWswHcaQhk34QFABAYZaP4Cg== e=found last=15 s=21 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAv8+pvop0Ta7Bp8y6uqmlKQSgxDFz8DFObSvPsLV/OVQ= priv=MC4CAQAwBQYDK2VwBCIEIK65NzFFWA2iSgg7W8Qy2e4//YiGET2D3oKUx8MDjxv9 msg=EqQtaCz7Ph9V7ArIxiQ1o6xGj2TYfKWrz7ilGT6CRKi82qCH64MJ4e6DFcEFqfno53vN9pcX/LU1lDeCTa65Nw== sig=czDhSbwPDX9AjPRzvpCWk+S1fabUjOKWxYaqw8m5mt2BYLWm/xWuX1U4lCfCoWU5NIcJvfXEt4aaSQdU4ZRZAA== e=found last=15 s=22 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAH2FcJ9705I7Sba+UcUq/XA5ArgXz70GE86SlYJsgMB4= priv=MC4CAQAwBQYDK2VwBCIEIHlOyKv+3w8wmLp0eDdLxGlfAxLkfuYRhksoIgQNMI0L msg=kRGWQLpyv/xvN/8bp+Mwl7cexrExDFTUZOHGAS3u3jhBW12JVjBs56nGsSrz3wRuBLsifJyzZmGSChIdppFJyg== sig=NnC8xpl6ZuWmYOsgoDkQgUOztz+4dOUc0gtUhxC24dXSa+WVWHk0C8QionrtqbQd5NaD1tvhMiMEhu7L7yzRDQ== e=found last=15 s=23 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAhYWF20bn1TJgI9nVojvNLxpCmUU6Bp5vn3lCoQrwWQk= priv=MC4CAQAwBQYDK2VwBCIEIKqmytRA9JqS+KTTzyoB1QNWBXUUh93QXKzXJsguNt9Q msg=ZuVwdmL4XE5tn3R4jO3MOuXQEMACch5lW/arbCVcwJw/dHSSFDX1IyL1aF4uXOD3upfBDVcTc6qsz/hYbkAUeA== sig=9ouJrxGKnXE6XoIbENg922fQPIt+JywB2BPxwRsR6OlaqBYStgbRPNf3bb9TeGyLDdYNLoSf7dZ70/5eBcjiCg== e=found last=15 s=24 in subShifted_NP", + "pub=MCowBQYDK2VwAyEADbuzqyVmVCtgx7sD8zb9rjdBy3PJJ5f+kad96WVwLXE= priv=MC4CAQAwBQYDK2VwBCIEIKlw0he26zOG8tEld4PqZQd6EKqdkX3jHDFA8iUTVa+d msg=MQiYzCzXzpuzJAef1LZ/DB6D5cLAoyTxC93ugrpOH+ngfEJ0qsp2VdPqXnYWfBnhYfNbdskoSh9EOvWEpQo2XA== sig=aw6nmXoLl7mdC2UpBflnvCRrlmy2UsnTZMdYyaB2z7qVOGMAEkLjLQJfV5Xv39GK+udw6idE/2gD1//jqf0hDw== e=found last=15 s=25 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAxtErD4XbST61k3wKl2AzQjn8djblZzhft3AwLDp3EZQ= priv=MC4CAQAwBQYDK2VwBCIEIGtv1M/fbNuz5mzZ4szo8wc1GG/yrAu0XHgXQ4vlux89 msg=98TeuUi+a2/Uz99s27PmbNnizOjzBzUYb/KsC7RceBdDi+W7Hz3rY+ZcledEX25EvQ+4qE09Rpl0MC5VBmvkZg== sig=5z4FYvwPVgFIjSRH+ZTiznPatOrhV+bhqFXv1rQUKAlnPcMB0YYyOq0hxU+4ql/qwJEIydp2YcEHr2qwRl2gDA== e=found last=15 s=26 in subShifted_NP", + "pub=MCowBQYDK2VwAyEApoWJ5QbgT9EsTYL3UsEcdyMvqzCzO8veSi69u481ztI= priv=MC4CAQAwBQYDK2VwBCIEIPqTbXezzGpUggAMJv8t+DVNdliF2nxn/2vDnK1X4o1Q msg=ApbV0RdPCmXpAOUADxiDFlpUVnBwv1UBDe9piYzMrJSHncHvaptndLrZs4wFGd/J2GVHGAFUNc17Ycci+pNtdw== sig=XUcaaMjNU9a2xg+CW+5CZhwu2gTCdM4l6TU/5eX7jlJx5ZXGMXWlMAJlw5ABVf4whhDWKOqJFp3ocNeWNWqhCQ== e=found last=15 s=27 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAIbYAP3Fo1tK++LG+2eJio8eM8bzBtwOAD0keqkXfOE0= priv=MC4CAQAwBQYDK2VwBCIEIPInJkgkuRvqRlVGwWtOPAuvi5Iq7V3+Qi5UnQ5tieTx msg=z4CI26cC34QV7Jt3j6R1l6znuFouxGSu81Z52tlVm64SabIXMtxevkTwKZhsAXc1KaG1uC/frnddJsrAqcmkVg== sig=LNGRpJSbkSoiqd9qOZLGH5l8/lhArVyrKafzN33eXSNn/ivekiIFFihhsJUuggHsKcO/FYVGtTumbVexXITdBg== e=found last=15 s=28 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAg9DBLBPolLjiRgg97rbXGtvBgg6rL/Bh7olb8Wrayp4= priv=MC4CAQAwBQYDK2VwBCIEIOM/uW95eFEFkGFxN/WsaWI9u9WkzWJ8VsgANgosmkvR msg=B1j00+gfooAPuj61aJk6/SiFDhvv3NN0YJrjP7lveXhRBZBhcTf1rGliPbvVpM1ifFbIADYKLJpL0V9EbSbToA== sig=UDVDheI9R7+eG12Jgmly0MNvcARbzXWdFF63GZ+UfsdkmxjT9dwwRDLyJjq8woS6Q95FJCRIbFayEgsYUq61DA== e=found last=15 s=29 in subShifted_NP", + "pub=MCowBQYDK2VwAyEANvRnMLBo6qzQ6VozhEweNezEzJC9OG39Z+++BsZqRYk= priv=MC4CAQAwBQYDK2VwBCIEIMEP/y4Ie3WP6qNqdGrcOrGMZkJB6gE5gMKHsFlMA2C1 msg=QIUNL4x3zaIeDdZxLa+SlIaEhFQCCTkcGXlYUrFnF0Dk8hcldfJu5QLFoHqym9DZ635m/6pBS/usceli0Syeug== sig=2M4yKpIpuB/EpT0okcwmJRlaI8KgqcciiMBRgZtfhX0f4oByHiTYgO/IuxdtXKyWaOhjA/F2U5awKuhy0Mx6Dg== e=found last=15 s=30 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAgmokf7oW1H+pFBLS4D4m0AxPQJLyH0QC94GmcEycikA= priv=MC4CAQAwBQYDK2VwBCIEIPlPHSQQH7iZdC2feUGAYnXcTcZhjBKfHD3jXIC0mkJ9 msg=ddxNxmGMEp8cPeNcgLSaQn2oXrcT7wQkwsJlZ4tXgrw11lvBbDGR+T5b7e6PG33dPpkezlPbL/H6Aj9TTmS+eg== sig=hLyXjs32r67cou3mo08c/ZXxsnk5tEMIiePjPEFEtxRIEM7YL0IlhmKAiKzTWX7+1+2HizWxp4TMIQls+cCKAg== e=found last=15 s=31 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA3t3wHEsYYdgKhp2i0HEW1Fcnt5pYBPpTsrGfddK8RMo= priv=MC4CAQAwBQYDK2VwBCIEIHxwN3rm97wsulvTSWKpfhq/uk5SPGaRuaO//7n4Y4Cm msg=eub3vCy6W9NJYql+Gr+6TlI8ZpG5o7//ufhjgKbqRqtx5gCkF14PaXUe8DBs+oEHQ7Lb8hHMCNonvXfsiHfbFA== sig=FujuTlPyuZ6ye+N/1+y9jbNJjihFCS2HHGNIQPBLHy/a5JQ/ma2iEu1dQRvy/9X8ApaRKV0+xOsmlk0Zg5FQDA== e=found last=15 s=32 in subShifted_NP", + "pub=MCowBQYDK2VwAyEA/gy2n68UztL4x3epQEPIklfOMK9t6k0Hg06V+igrrJ8= priv=MC4CAQAwBQYDK2VwBCIEILh/oxGMBqoe9T+9hnzuP+pa406OzjenfQd2rSQmazvU msg=EYwGqh71P72GfO4/6lrjTo7ON6d9B3atJCZrO9SyM3u95m2kRQkhPtB8EPrrbN+sSAY5v2+vMXwb+Hn0mAYjTw== sig=zO+8encogwn/U4SF91n//S/wNXR3pZrhU50v3nVy8eprI6AKcGF4T131Rk2bmrXdmtt6CaLkKQ9UP2GPohDfCg== e=found last=15 s=33 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAHtYhM7lFrRHW9FqjuSEdDZ1tctjede+MoV0R1UMtVVg= priv=MC4CAQAwBQYDK2VwBCIEIJD6PKp3MulK/B/Np+Cdu+Cfo6x2EPkJJliRnj1G9xs/ msg=Q/p5WuG23JyPgshQbo5YGam23fQ5OVqjC0fCzYVXRw+C9vDQdLODe5D6PKp3MulK/B/Np+Cdu+Cfo6x2EPkJJg== sig=t4XSeew/w5x52oghg7VR7yDP6cP2JkP+1qCbuYJyUNW/lmNKD16Tk3SWktl4o3HzmpQewS3lxx1vR2pKhkPqAw== e=found last=15 s=34 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAEI/536MsgF7aZ9O6hLaT2cGEwCIQRajWmvxE+iv+5Ig= priv=MC4CAQAwBQYDK2VwBCIEIE5+N8mBMqbcslWpsFiYUJLEbnKC1CZgwnql5scPhVqA msg=1CZgwnql5scPhVqAJy5QN89FfioiZlPgPcwVjCM2AgM5Frk3eACOherjcVcSUSth7u2NWh3IJGkOy+UgE6g3/w== sig=9iS9EP9mkQOoxQoGzcznIChrPQGdAA763KQjwnN5k4HmVBX/abYK5XIk6H+sfZ88Qq7VOFy8c1H1CwYb465AAg== e=found last=15 s=35 in subShifted_NP", + "pub=MCowBQYDK2VwAyEAvdP5ffItF2siN+QBywHeCpXDFhjxK7SZwT2MfjSoipU= priv=MC4CAQAwBQYDK2VwBCIEINx5YWaFb57Vnoqc93w5yK8TSWlY+7GEYVjpc2WkiPI/ msg=Ggwp5bmATPmRhoheAaYfJTYxkSrIXYcSTqxi3HlhZoVvntWeipz3fDnIrxNJaVj7sYRhWOlzZaSI8j9oTJ1ygA== sig=c5HoX+KDVG2wM7o0o4dKJUy/zczPaKDUcnWhsmP3d6evqfDbRNAQpLopFdO9dyfuEv1H1gn+qLQUVvZcuwLDDw== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEAhPw0vNPFREOs5U1MkD0yCWZ3WCOmwVSvN2jF1Oizqbk= priv=MC4CAQAwBQYDK2VwBCIEIP80+hG+p3eZq1Ez2fIwZVisdXlokktg+bLNtBeM/GQA msg=2I3ilxrJP/fye0bwPSNTluAceuuI6hS1a9t7J9YSlIX9WOwvrnoz2BUKVPkLpHmyEK7JHMDttj4l6BQiCOl//w== sig=kp9BeH0HbGR8wWV5vERw/tZtGHuYdpNvcUO7fyzEAp+avoeJFptyh7jzuvic/lcH8+W43kjvq2wn7t+Y4QOCAA== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEA6yB65NH24xZ3gPJpAf2oZiobm/CDOsW2mTA5NYHiu9Q= priv=MC4CAQAwBQYDK2VwBCIEIA8QPr2HS5Ph1RitdsIwIn6rAvIhxGzrI0iMNTQXdaOK msg=xaumAcR/MN99ugA1y5nJ/KZ89v2ubNtaOKMr85InQXbcd6tQUDJKVgi1s5E00FUzZNayymWz0FIZmpuB+B3D6A== sig=2Hh82APLUonf07pjWJPbqNkIvH0FKaGuqR6uZy0SolDLBOQRUUo19t6txaNjafroKvKivxp4BJZK//UZANV/AQ== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEAjzPeoBYWUh6lK8tL5zvJMe3quOc9DHDHqjaqmlQ9eCs= priv=MC4CAQAwBQYDK2VwBCIEIM/KKNbVtHGuvVjVRndMVx+uGHioSJfRTLV3mMT/qs0O msg=xoQTj8hSoCBUbsW5fls1TN4WIBm8+r9Q4dG8neWlAU5D0pb5V7PzbBUFJWeMN0nvqEZA2EOlmOckFJwvw4kbvg== sig=RvTiLTOBLVlUPXgblZ51/UkOE6Yen7x4M02mxNRnKQIQvRW6Xy3qME2Z0Am2zJnQUl5NzmX7bwYSxgxpmI88AQ== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEAOMqNF1zplUOboWpKGEScst68qibTpF7Ty7VY/uEvaNU= priv=MC4CAQAwBQYDK2VwBCIEIJJEH78Xa97lbOZ9O6bgZKJcrcU3smco0u0Px5GkGxTV msg=4RytsCg8AEt67XM/kkQfvxdr3uVs5n07puBkolytxTeyZyjS7Q/HkaQbFNVojP80jljxWzNLoGaGN7N1kr2qSg== sig=f9A3HtPy45UhJ3k5woskx1PE0Gkk9Lb3WJdwYlWLkvPR5U3U3twjEF7C7yTQ/GqOHDQPn/oRZjkr6BAezbrQAQ== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEAn2s7D0uz1lKQ3j1cJQXWJEJ0Wh8kfI024cBGrsoWS94= priv=MC4CAQAwBQYDK2VwBCIEIPvpiAgD9MjVzjq4GBEEvyJRG7qBtOA8LhyL8TxM9zxh msg=TPc8YdLsCNMm5JB7iuu+8qy8DRSFi0fGLIdlMQxyHKr52bnlHDKvhOXdJfm4MNi2nwnHKety6zzPKhdsz5N0AA== sig=k/NSvGBfyOC9cFSGbMk4VRRZAD26DZoYFTfPI1nqv26HRtzmyOPRUt1XUKVdlPCk9BWJKxMIOViE5fubQtr9Cg== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEARcA9TGMLvA1xCpTlIBTFBqX4BmnojWpbQrHqeuGtTUQ= priv=MC4CAQAwBQYDK2VwBCIEIFcykuAmQTTxkQFc39T6K/esqAVIzjf4BvD9w4Ahh1uh msg=K/esqAVIzjf4BvD9w4Ahh1uhbFnf3RWoWc5DBj2U1Wlr2XkEMiCIphy2Vb+nVG60fxCc0imaymlJcl3DaK1FIQ== sig=T2XgkyPeNG3Bcmss6YCOLZnVZmzP1bB/traUHj3kFdLx/auEXgaF9U0q2aELe2gejVOX4SODJ9KBHKcwNZMcBg== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEAEFWkTeyURoIn6Fdnr9db6WjB/JI4C1a93wJNXpE+n2g= priv=MC4CAQAwBQYDK2VwBCIEIJer93jUjXCZbxF8P9jpHcFh5/ERuJ9y1K0GUsg1rpA3 msg=Wi4GxXDWlO0X6fW7ceLYt9zsTRM/RODJRDt4+8iOqvV3Llhdd9bPhSNUX+5tURNUCmoimd3zQHNB7/fqwbmYhg== sig=bpus92mglDkcS+4xjQ+Ss5Ft1CwwIpULew8VxDr96oZkn7fUKd/qzvWB3bpPRLVZvDbn62DC/LnB+lXSy+MCBg== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEAIcToYs2BkuC7McB+khCggsYBK/z+V6bESJv1eUURkUw= priv=MC4CAQAwBQYDK2VwBCIEIMJVSyDIMf6tDX+3WusTQgjWUh0fHmZF6iW7u6u+gE5b msg=t1rrE0II1lIdHx5mReolu7urvoBOWzYTMa6Os5soq/7Qpkx03upSddEsdODq6HCFlmQFnFbohWP41Uz2lgBTtw== sig=a9y3fKIcCCZHwj7X/2MEewgV/Xv4pB9Zz8uXbEBaIGv1v07OfhOXpxxgyNVDmf4Vt82ZMz5i1W3TOnf9vaw2AQ== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEA+WkpaGYP1Cvz8vBKHJx04KpK9zvI8I2hTJWaGnDJE7M= priv=MC4CAQAwBQYDK2VwBCIEIET7Foh0nuhOMyT4pwuSE6YCWA54Xvec6sh+9uc2ePGW msg=USWDYo45MeZ+xhVE+xaIdJ7oTjMk+KcLkhOmAlgOeF73nOrIfvbnNnjxlt9BBgMDMjVHespfGh1nnVWNl5Smfg== sig=uC/wtzmLNI2UbMX9XT1oUMULIUjxNyVyqlrXkoqNg2MqrE6E5Gcz7DkhBQ/Ol/oTZOYXPFguXpWGqhcmPdmDAw== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEA0at7YQAiYd3RvIpYZeHUsNUbyD4rUIABSZyqSPPnXjY= priv=MC4CAQAwBQYDK2VwBCIEIExle8MpAA8rxusxmLjsBOb2+W1ICTbAKlCkmFX7qcNr msg=6l+NN69pJyLPhPHmX1oFxraO8QIpuDmQ+Uxle8MpAA8rxusxmLjsBOb2+W1ICTbAKlCkmFX7qcNrgJ31OoRIqQ== sig=zl36421pKuQEwy4ntSijob95iSlcogE3m9IfgmXLAM48qcj0949WG0ntxb2Dl586oHWBxzmeoFuq6fzUzQtQBg== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEAE0fGq8+sf4e5ickaVLPbQPgHBO+ZeaWtpK2higapw1M= priv=MC4CAQAwBQYDK2VwBCIEIG/IPZ4pMEkp6savNxRiP6quWDYQK+QphYwNjnkLYZBL msg=q2P8BeCMaOU0+waVNHyZYzyqlWE/2blKeAbHVkpa/Jm/51KUZapuwDEubITmJ9Z6RMenYnNe8sLIFUkrfKWkkA== sig=ZjKYto3cRI88GehOVcKB2QNkv8IdXZ3h+HtCHIvhF7GgpYjWARP9VI8zsUJW33uVo1Kp+5++TKqY/34+SqLUCA== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEAFMeh30CrxMMFUGihtrh1E7r2A50qRb8Jxm/1Z8peFMA= priv=MC4CAQAwBQYDK2VwBCIEIFFX9MW5r0TrFR+GweEl0UA2ecEVXapCRsJPcEPk+Xf2 msg=qpfc0g0cQGsgzFtZILynE9onlFFX9MW5r0TrFR+GweEl0UA2ecEVXapCRsJPcEPk+Xf2nFZ2cbWMkyFX5Ic6FQ== sig=bCT+JnzEdUpa6x0K+FnAPa1fnUhy4pmK5EAYs7ORaGs45qp62ENQUWj1BMn8ZpFAfUYV1tuGBhhua73MXB3jBA== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEAgKIrpZiZVMIQ3DmybKkOaOWEKOlkijaFC9tSdgZ+6mI= priv=MC4CAQAwBQYDK2VwBCIEIINS33IrrrEnxMCTDJEQ//g6WKEyEuCwVzp5uXoqQDmh msg=H2fmoXw40oSrSe3Fcx/YGCYR/RvtoE0xqxRalfjlWQDMmzi6Bog0of2dUZlmxI9iWaAsyrtIyVKwRN5Ujbxocg== sig=dwHERSdPaxQryZmDLnWub8m66a8wxZPuCuTKkOPmwZ5IuYWUl63iD3s+aoJfiJk8+xAlKlDtPUnGx+6fOzV4AQ== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEAVTk5x6SQaQHh7UH7zfBGl6U4+Txb+pOxqmPOIo8PyGI= priv=MC4CAQAwBQYDK2VwBCIEIJtw2GsoqhwCCtOgUtYXiYpUyWzo2XP9MDakoofhTCOk msg=AgrToFLWF4mKVMls6Nlz/TA2pKKH4UwjpBHkfNY7KkqtW18eIhEu1M7D+AnhdfnsQVkDczHBzFtuPgwaZ9xc7A== sig=ZPB3kbWf3G0ySlhg6Bvbxh4S28WvRAELGYf/v/T/hAwgMQ6Oq3pPiY93KUvDEe+80AAVInG37+dGKVT9RbioCg== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEAc4H7Rb8wDjfvj94WftKwolGe9mwglkEpUkiLR+Jty6A= priv=MC4CAQAwBQYDK2VwBCIEIKvCOCYg1Q7U4+fgMnRRYn3Lmht/xc55aM/WtBF4ZsJh msg=uaJtcfOWBY0KxeIXXV2vWCUB4vIcUC8TeEzWWWniuImpUU7wPZHsFWnf4XiUJar5+Am19TjeUfYIQK2QZh9dxg== sig=DBW8lV47/jBOCGxQUBdi2QUwkx6KeXFgcRsChQffiMhm/Unrqzk5zvhWbXPrSsinG9wyTmUz/h2M/GeCiirnAg== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEAxXas85OYbLLHbFEE9nW61ip2ov4wzmMm2zkUlsHhyOU= priv=MC4CAQAwBQYDK2VwBCIEIKarC8sbbYxXbGTaWwJjCxMX6MCKbDiIfdvCKblsmQd6 msg=E3zm8Nva7r1TcFRgXVOBVYxhG/3b822pblFZEdf03s4dbUqjx1qdA3tLUczSs7NuNmY+6t1Vnp3q70OYUtJTNg== sig=W5ItndbbkVnAWv3xoM/Bj7SvcQC4lErIKKRVd/d7jT090BREWsANppGc82oj17nshxVixxr+BxRRv36+a4IOAA== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEAlKpznUGJM4bQhLgPau5E6MQvqQnBCcvofDwkU5QhlRU= priv=MC4CAQAwBQYDK2VwBCIEICumaRhwUVQTUkSBfw5WtTNVajg+0w8HBRWZOB2FXDgi msg=7UkYLhNEfWfsBQDQVsYNNFaDDFRd1LNbyM9VNtNOe9ctGtYrpmkYcFFUE1JEgX8OVrUzVWo4PtMPBwUVmTgdhQ== sig=XA8nmvcN7v3nHMnSTtRo5Yy516C/ba0+gFdHGBj/tQ241veNGhQSB1lX8iHHtMnuEf+g9MebNCooXTTv4dbSAg== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEANg3t8r6SaUHzAkC3bSq3njFriUtFxo/HNr9f3cJjrtA= priv=MC4CAQAwBQYDK2VwBCIEIGpGaYZfVHakKwQqYoptONNYpQKvYIwvL8Vyj8vg3YuM msg=aYZfVHakKwQqYoptONNYpQKvYIwvL8Vyj8vg3YuMN6uGjDsal51/W8o7BK0nsSMc/XuQzHFgSonaZS50YAl76g== sig=XRPIQLqcqeZYZtd0OV/ugRKYT1aZKJmwS1wbIxRHjEdTgOSvLRexlEYh8xPrspcfPXh8FM6E70PSrk4+sGwvCg== e=infinite loop regression", + "pub=MCowBQYDK2VwAyEA69MJYVrwsGt5DugorT6VD7zSG3WQ4yOqXiRjUOP3LCQ= priv=MC4CAQAwBQYDK2VwBCIEIL2PFNE+QWZ53Ah9hoHeuEEEbw0Ew2ypwWts3l02nNOP msg=UG8S6ZNCvY8U0T5BZnncCH2Ggd64QQRvDQTDbKnBa2zeXTac04/SEviN0EcPRMD4b6uP03S9WDO2T2MYPkoXMw== sig=1Dgxn3qUqRaC+CMASAT16JtFBWL8qoF8SEBbQL8YYM/SPzN72c/7EbKCIUkdgrUD4iHVc2IHLCjHDeQPbSqnAw== e=infinite loop regression", + }; + + for (int i = 0; i != testCases.length; i++) + { + String test = testCases[i]; + String[] parts = test.split(" ", 5); + if (!parts[0].startsWith("pub=") || !parts[1].startsWith("priv=") || !parts[2].startsWith("msg=") || !parts[3].startsWith("sig=") || !parts[4].startsWith("e=")) + { + fail("invalid test case format; expected five parts (pub=, priv=, msg=, sig=, e=), but got " + test); + } + + byte[] x509PubBytes = Base64.decode(parts[0].substring("pub=".length())); + byte[] x509PrivBytes = Base64.decode(parts[1].substring("priv=".length())); + byte[] msg = Base64.decode(parts[2].substring("msg=".length())); + byte[] sig = Base64.decode(parts[3].substring("sig=".length())); + String error = parts[4].substring("e=".length()); + + byte[] pubBytes = Arrays.copyOfRange(x509PubBytes, 12, x509PubBytes.length); + byte[] privBytes = Arrays.copyOfRange(x509PrivBytes, 16, x509PrivBytes.length); + + Ed25519PublicKeyParameters pub = new Ed25519PublicKeyParameters(pubBytes); + Ed25519PrivateKeyParameters priv = new Ed25519PrivateKeyParameters(privBytes); + Ed25519PublicKeyParameters pubDerived = priv.generatePublicKey(); + + if (!Arrays.areEqual(pubDerived.getEncoded(), pub.getEncoded())) + { + fail("different derived public keys; expected=" + Hex.toHexString(pub.getEncoded()) + " derived=" + Hex.toHexString(pubDerived.getEncoded())); + } + + Signer signer = new Ed25519Signer(); + signer.init(true, priv); + signer.update(msg, 0, msg.length); + byte[] sigDerived = signer.generateSignature(); + + if (!Arrays.areEqual(sigDerived, sig)) + { + fail("different signatures of message; expected=" + Hex.toHexString(sig) + " actual=" + Hex.toHexString(sigDerived)); + } + + signer.init(false, pub); + signer.update(msg, 0, msg.length); + boolean shouldVerify = signer.verifySignature(sig); + + isTrue("signature verification failed for test vector: " + error, shouldVerify); + } + } } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/Ed448Test.java b/core/src/test/java/org/bouncycastle/crypto/test/Ed448Test.java index 4316fae005..5c1d8c36ce 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/Ed448Test.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/Ed448Test.java @@ -12,6 +12,7 @@ import org.bouncycastle.crypto.signers.Ed448phSigner; import org.bouncycastle.math.ec.rfc8032.Ed448; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -30,7 +31,8 @@ public static void main(String[] args) runTest(new Ed448Test()); } - public void performTest() throws Exception + public void performTest() + throws Exception { basicSigTest(); @@ -40,6 +42,8 @@ public void performTest() throws Exception testConsistency(Ed448.Algorithm.Ed448, context); testConsistency(Ed448.Algorithm.Ed448ph, context); } + + testRegressionInfiniteLoop(); } private void basicSigTest() @@ -48,9 +52,9 @@ private void basicSigTest() Ed448PrivateKeyParameters privateKey = new Ed448PrivateKeyParameters( Hex.decode( "6c82a562cb808d10d632be89c8513ebf" + - "6c929f34ddfa8c9f63c9960ef6e348a3" + - "528c8a3fcc2f044e39a3fc5b94492f8f" + - "032e7549a20098f95b")); + "6c929f34ddfa8c9f63c9960ef6e348a3" + + "528c8a3fcc2f044e39a3fc5b94492f8f" + + "032e7549a20098f95b")); Ed448PublicKeyParameters publicKey = new Ed448PublicKeyParameters( Hex.decode("5fd7449b59b461fd2ce787ec616ad46a" + "1da1342485a70e1f8a0ea75d80e96778" + @@ -76,7 +80,7 @@ private void basicSigTest() isTrue(signer.verifySignature(sig)); } - + private Signer createSigner(int algorithm, byte[] context) { switch (algorithm) @@ -97,7 +101,8 @@ private byte[] randomContext(int length) return context; } - private void testConsistency(int algorithm, byte[] context) throws Exception + private void testConsistency(int algorithm, byte[] context) + throws Exception { Ed448KeyPairGenerator kpg = new Ed448KeyPairGenerator(); kpg.init(new Ed448KeyGenerationParameters(RANDOM)); @@ -164,4 +169,1082 @@ private void testConsistency(int algorithm, byte[] context) throws Exception } } } + + private void testRegressionInfiniteLoop() + throws Exception + { + String[] testCases = new String[]{ + "pub=MEMwBQYDK2VxAzoAgZiVkEoqFULqfNRJUnq5Fu1OsZRExw1AxI5dAjzLFbcb+krjKjKA81DKnED3+iN6aQ7QlK2PsvGA priv=MEcCAQAwBQYDK2VxBDsEOeZPlP0NUeEuIOnJOE6PccUigEvDNtUtfWEyc27WyIgFwD2BqKGdJNHVHJe5Gws66Y9CMHZK54RCZg== msg=5k+U/Q1R4S4g6ck4To9xxSKAS8M21S19YTJzbtbIiAXAPYGooZ0k0dUcl7kbCzrpj0IwdkrnhEJm5l5p+g54eg== sig=RfExPil6ytaGVcLbC7Z+98YGgEceUtKP4YOkFQxKOcdzo92jTtgn24hZMhfJJfvUmPYW0L8w1F+AXpI+homRI5H99ZuSUBW9SoXGa3XeyHbH2cnB+gU1BYSJt418+K0WeluuaRotEoHkj2klG2vc/zUA e=found last=27 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAhnn8NJQ4lJeTojTiZY3QxFhsv3UlfCh7kUz6pC9le9EB9mqwOhZd4PUGtVDXvVMbEgWBqpSKS46A priv=MEcCAQAwBQYDK2VxBDsEOcuWqeEhJ89KpaG7GuUKJz+2k+CXSTrrTGIU+sKHHOETLcGrrvJBiOgTTfa+9CPv1V+UbUl9edhe5w== msg=y5ap4SEnz0qlobsa5QonP7aT4JdJOutMYhT6wocc4RMtwauu8kGI6BNN9r70I+/VX5RtSX152F7nnB7zQei8qQ== sig=dAKGHOOLmdiqdgBs2rvJlG7Xwn6cN+PpbhGbcEIczKdwxMzTJTc9sxlGXNT5TrfSl1hpuzuCoAGAsVSE0N9FmntBGfX+nJ3qSG5A7Zj0RsTuq8F9oalpMjWQw/CaQSDU5olgwHcz52OgekBivfI74iAA e=found last=27 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA515DzkzTyiFq0By7UCpcd/iGyTWm8n4eCZ5Lmgwqq8WeLXN69nTitfiRxEXR43PaQt20vaC4SB+A priv=MEcCAQAwBQYDK2VxBDsEOVZwRWJ1s60j0ExUJUf+4q7mWimTA3v78XoZ8SdvNGUhxPHcW32wnroI0e3Og7IAuxxZBcFYu+Zb6Q== msg=VnBFYnWzrSPQTFQlR/7iruZaKZMDe/vxehnxJ280ZSHE8dxbfbCeugjR7c6DsgC7HFkFwVi75lvpGpr8fzMKCQ== sig=Fs7BsuOmQAglqYnwtddH3//1xz8DQ/MFW8CxgNWSG9sOo4gpdc24T/0ORYEL+JWe/FD/oiuiHUoAQ79vTyoHZIhJCmozuzHB7Yk8Eu42egehlz2kYaJNVmcq2DuiVfWx5y6jzP3eYbpoXLs/oKqCfh4A e=found last=26 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAFFIH79iGjW4RppqmcrknuabK9ix9tKfEv0DoSJnK7obnAiQVECfLPhj+oTa0sMNEKDQaiEm2va2A priv=MEcCAQAwBQYDK2VxBDsEOSScY3x+NmvgStzAA7JXDNuMfXtyZsd5FFvyzumGmosWrg9KfoUOF0gzrwbc4ILpWif39MrQmBhQgA== msg=JJxjfH42a+BK3MADslcM24x9e3Jmx3kUW/LO6YaaixauD0p+hQ4XSDOvBtzggulaJ/f0ytCYGFCA9xNrnOgqUQ== sig=hvheMugthdwgTHlJqYFnDRBrYq4jJnY/0j6t8dIn6TWtmOg4ovtIrS9F0Tl4vZXVUo8KNnuyGvWA93+7jcMRXRq68qbyPx6fH2uYDm72/hSPAESu8LrZOgUvO+VxQR874H1PKdib402WEqv/Gg9ViwUA e=found last=27 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAbsdgKdEQ1sul8g8on0VqFpHDOUeNTkiNuMSqG0vIl+IznqqWSPAXUUBoq7k6ARX+6S3EUS8XFy2A priv=MEcCAQAwBQYDK2VxBDsEOcbZbtIQHwHdcmlNU4AS933i0kEoJ1tZt+bErVhsjmNQ32ybroh+f/LMAiCTYM1I/4JDbQLSb6mueA== msg=xtlu0hAfAd1yaU1TgBL3feLSQSgnW1m35sStWGyOY1DfbJuuiH5/8swCIJNgzUj/gkNtAtJvqa543uSJs2S+zg== sig=ekw6WqqH7Nt5zMdbOA4QrmmYsnrW+MgpiGljDPth45gI55wjs4bAxIBpSRFim9OPhKKOuovYzigAhTYKHeNCBouAmBgkdsmHJDUTE6oFDIOXYI6KEFSwNZTQ8izwcV+nEoSGtFCFTWUioXQkJnOhSxUA e=found last=27 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAcmhnjr0eGus/TMsrnhZvXRrIFbVPi9R1FLjwueY0AIXrH15mkdfreSVXBzwxwkK71SNQY/ZL8LIA priv=MEcCAQAwBQYDK2VxBDsEOenkZu/cy5G8gMHlJwaD6DI06gxHu7KVyfx5r+svT7kze5+bFYeeIZptlJ4YED6zjhsy/hCAxUoR0Q== msg=6eRm79zLkbyAweUnBoPoMjTqDEe7spXJ/Hmv6y9PuTN7n5sVh54hmm2UnhgQPrOOGzL+EIDFShHRUboKGmcuJg== sig=v0ShF3C6zpZlH1OEs/+2VtV045pefEr4mDYxHC9gwM7vIdNMduqv+ORTR/kfsO+rqr+aNsNi7XmASqLakn3Vbt4KSWYpguzpHtPF0h4ITs1WsPH4tfwxBEoR/FGqNaVdATRy6KIxLBOyHUf4UzanZBIA e=found last=27 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA1V5GjmIS9RvRthCq70wH7KT7W9QXaYHnjo+iJqMbh9qDU9O+KozH3zxGgrIb4lCogAzILmichasA priv=MEcCAQAwBQYDK2VxBDsEOY+z51GP/xLrgARJWwB+tDAmAKDFAR+eQ/JJ8LRZ6Yrk4B+kMM76wIF44e0H+FxOLOWUasLqQzqv5w== msg=j7PnUY//EuuABElbAH60MCYAoMUBH55D8knwtFnpiuTgH6QwzvrAgXjh7Qf4XE4s5ZRqwupDOq/n/NCGP+uv/A== sig=xPhIEJ7GaSmnz6yBJEh8vUfReqVYtrftCzwX8YbTyQZtoqVofQm+1ZKd61je3OUWI4bWfNCixT6AfI4pt2cJe3PE9N/DjfAZI0B6WleqQVmMVphcNBuMLb9KyuYrmZYAyCOTv8U7bqLzqPRFaSRQLhcA e=found last=26 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoArt2zBdtE07d3p1FA/U2u6LmaI4Sr+0qsVygHDqvhIobotKmJXCQTPqq8SfVl5EXLaWBf310RDc6A priv=MEcCAQAwBQYDK2VxBDsEOUkDZInSe8hUewSVDODlxf0IErKrmqBJcfFh52G73QWhLj1vH7NOgF/fC9KnZ318Qdgudl/3QT1vRQ== msg=SQNkidJ7yFR7BJUM4OXF/QgSsquaoElx8WHnYbvdBaEuPW8fs06AX98L0qdnfXxB2C52X/dBPW9F4U0VE85uvQ== sig=eOCfk68n2BDT6EPpvtc5GLTxo2guiiy4eT0Lw/sQr2glzO0r+WFaLnAhtH9AX6OmhaJvFyIHH1GA434ZqDn+aJpmk/jYldHtLH1wSsCm1VI1F75c6BAvDRIDpVtptVOEvI0+D6BQz640sVxtVRqk5SQA e=found last=27 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoArjp0KCuyGHeDpr+dc7F+AAtbfazXQIJVKiMqzz29IS4y4oY7BcefdpgmAf5jqzNjtxQ24t/ShwwA priv=MEcCAQAwBQYDK2VxBDsEOeSG+lyikZdnyutY2bFB3rFrsYOXNdWDEgJoQfoOET+q8IBsX8AveISGDBM3n/y6PklalbU3a8990Q== msg=5Ib6XKKRl2fK61jZsUHesWuxg5c11YMSAmhB+g4RP6rwgGxfwC94hIYMEzef/Lo+SVqVtTdrz33R3oiWFE2y+Q== sig=bs7/WGV1Rdq6rdIm+jQJR29uruw4ISePDFbvm+gZqYzjZquEPnAHawDwJ8qXL07WTWrm3pJJBhUA7EpcSb2SKlH3VEAy5TvCCJhaFMHCpLPJtxMAUwhGvL4JSp+ChUoszYdVx84gEk+7wLa5YjCZuhIA e=found last=26 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAwUu5MbjncRAg4DtlyPIlk2Kp0+vQFgObzQO5FWmf5k05ReW7K3XoXa9SD3pdmaSf9Lv3DAFYpU2A priv=MEcCAQAwBQYDK2VxBDsEOQd2sw/fIyaBlKc7N5lz7z9gejiWjXN49ug3N4Ey3PrIg+DzeKTGRQUPan5OJWurIgIVEzRsxH7SIQ== msg=B3azD98jJoGUpzs3mXPvP2B6OJaNc3j26Dc3gTLc+siD4PN4pMZFBQ9qfk4la6siAhUTNGzEftIhCpgczPuR8g== sig=xsB+vY7y8uGOtDkK731DpVtytNXSu/01HI/3CLZNrU80Im9VWOstb0Bx7IRAXxREPr7Yad+fo0oAVNLs9chh3nAKx0fA4IxKPin4R4P6WDEWh+YfMDzsLa7wrmoCq2Zazp64kiQEjk0hoAIjO/kD/xYA e=found last=27 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAMpVnXq53scujnvFZUGZAkbPpZRjv6PB1HUtqnZDHARwVlREGMDt5T353e7rgchm7DRw4baOBq34A priv=MEcCAQAwBQYDK2VxBDsEOQ842J5En8P0hcwVwRokVZ7Wv3bF6WcRZfi0g/PsAMIXwPn8DDSqQLDjTZGaJcsYoF1hMcxK0T0tbg== msg=DzjYnkSfw/SFzBXBGiRVnta/dsXpZxFl+LSD8+wAwhfA+fwMNKpAsONNkZolyxigXWExzErRPS1usySFpLUyxg== sig=2tL36Y9TEj9M4cIf5fGfB/ujkREMkazw3CG2r1Vng0u3w1acPtdZQEpC1fMn46zO89joc1wxXscAPDy8hoUpscekmZdaqpLlvBs9oNGcvwuonuC8Io11mP8YqlxTqOrOVyOZ6LjqYtlDbEFEp6/dPwcA e=found last=26 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAcnfkW4NjaWBvn72ZVV23vafJ2WC/5RX3oGsD90qedadMPwEqGSanvw7itysPmQJ/QVTIMpZGkuAA priv=MEcCAQAwBQYDK2VxBDsEOR2PvP00KafP3gVUwVzhDZ+GRMh5uY2pQNHFW6Qe4xrjwgUhjclnfdxaohxhyMwcjxl89HZVU0ioiQ== msg=HY+8/TQpp8/eBVTBXOENn4ZEyHm5jalA0cVbpB7jGuPCBSGNyWd93FqiHGHIzByPGXz0dlVTSKiJz+Z455qsMQ== sig=fu1a6on+zdYPw6CGepibQxS0VABDf4ihTjGFms/cxn8DsTCcoyElQbsj1DnaWZtjrkZTRZonsBaAf3qC4eTuNBdwQGN9rl2Fq6JXE50KO64TCvZq7i8G09frb5EznpwibBj5/eRpuFXfO873QUeTyisA e=found last=27 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAl4gxCreiBS0uWDhqOG57TSsX44rxwUpkfqzJ8j4BPOgpRBvIURJcQ1SbMNovZrEx50OdC+fw1NSA priv=MEcCAQAwBQYDK2VxBDsEOXJh+fT2exH/KVm2WJusOy1WN4qHEwclf4exbpGqUJQtwDBZ5r7hJDt6QrobpnKjzO1CzHqlqKCtnQ== msg=cmH59PZ7Ef8pWbZYm6w7LVY3iocTByV/h7FukapQlC3AMFnmvuEkO3pCuhumcqPM7ULMeqWooK2dHXFWH4YNzQ== sig=ypvSeR61KBMGo44yoppt3Rgw7Zw2oyLEZNUyzcpCQCl7C0tlpj5MFZMSLqNdx5IzahYG25/v9DOA3RgtcrQhLSgvZWFesc5iaaxLrb+ybD3+DyGY548J52YuxXfi81cqQSgKWpP2kM8zxkIlvf180DcA e=found last=26 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAQcX2/eajEGs6s8FRRRNdesX4wR20Wiseg7bccA6rlBmsfI165gUTbynD/B6+QOKH1eHq45Glh5wA priv=MEcCAQAwBQYDK2VxBDsEORpSHJsqnfgxarjFGgZFNcC5+XJp4TmFx4M26ENCZuhjNddqPFMBS0iuFq1y76QbXkCUjRu94CYIgw== msg=GlIcmyqd+DFquMUaBkU1wLn5cmnhOYXHgzboQ0Jm6GM112o8UwFLSK4WrXLvpBteQJSNG73gJgiDGCqlYQfPug== sig=GemEMDVr0QbJ/xGNFSUu9AtjBsZFOlsSAb1BokzRdxuKfBqKUTZAyD6jdJ9L3DQoHiV/E4eSvNcAro6BsVL3/zzPsjbfUBya0HsHePZfpSaruX4r0cT34ggaphdV+e5reoF4ijlpB7cDkyeCElR9CyAA e=found last=26 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAaRO77yJwuC3mdvWOeU74bs2RBArdrKgk1abcI4IbdssOSYKlxu6SsjhFu/NVEuBmzonnx2oyWLSA priv=MEcCAQAwBQYDK2VxBDsEOeAuFLzBnbwT0LuucrtlqXx8/0+dVatgpT+JMq3qyy8UcvxsXeXWDIYIb6cjDOVV99GydpVgONA8xA== msg=4C4UvMGdvBPQu65yu2WpfHz/T51Vq2ClP4kyrerLLxRy/Gxd5dYMhghvpyMM5VX30bJ2lWA40DzEpO4UWhJDxA== sig=8BRApKdGu7AOPTYJhduTp+ZLjAZRKnewWd6aM8vsQRVPJ1JKE1V/JXL+lSQdHfaH266FNgmvGOSAgTnkiqpa6S3oI62+fTkB/YLHSS0obgA4ZLx/13enJ2yfaPQta8WXGVWfWJWP+Jhze8T5+IcYeRsA e=found last=26 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA9j+NRCuIpeVRILKe62ubhhsKZxdUMh0OtQ0fop51MN609qg9qX3WsP4TjYWAVZ69MKfPlD/K4D2A priv=MEcCAQAwBQYDK2VxBDsEOcszViNOvqgdLnJ0ZegCBJaGnPFF00081A4pt0d/moRWnfq1j6nEDqD3ZLV8RDyyxP6JWOP2/WT+Eg== msg=yzNWI06+qB0ucnRl6AIEloac8UXTTTzUDim3R3+ahFad+rWPqcQOoPdktXxEPLLE/olY4/b9ZP4S+KFrEFD5vw== sig=rGIzh8Jmeo3VFLqPheaWwgxh/z+4UQNdLwlbkiWXbnLhRM/mX+KL1PKoaHcICGF72RvXNxHYk2uAG9t7Lpa7FTJPK71mpiZZou+gc0nHjFVnoA2EdbBq1fh2E35BPdN49iciO0CjmwGAJpXTYpzuDDMA e=found last=27 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoABpqdNL4pYviG8T7EwnBU2wuIX0Hh68q3tO+keC4Iwz9r6yVTSvYwitBtzZXXps0IEc6djpb/nLKA priv=MEcCAQAwBQYDK2VxBDsEOTCbmYW4XJPlaGpc9dRamLEsHytlLP4A4KGCsB/7BwDxBxGUinjXyYAjKFYsnwNaG48FWpxIkyjjKw== msg=MJuZhbhck+Voalz11FqYsSwfK2Us/gDgoYKwH/sHAPEHEZSKeNfJgCMoViyfA1objwVanEiTKOMrd4PpbG4SNQ== sig=E6NG9fyW6bPCFognNvFweQCqNKWEY7rY4lQVYb9EYzGM5EfTHO1d79f3TUOwWp3eYqd8a1NnoloAUTPj2sOv6snLRwdnrWR3aaaAJscWLd0Na++82SIDVGNtin7gUMzkjVDfUcmmG2BoSvM8qZuAGCgA e=found last=27 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAGuAEliEdqZpPXrRnlZ6di5b2/DniM/GlaTSJbLvQFwzWE5/x6dpJFUfw3sKIRGgoAji6udH/+ZiA priv=MEcCAQAwBQYDK2VxBDsEOVdJ2NhdXRt0hxuwuiit1u12zaDSWQV0ejcEfGxjkEpGOD5kgTFWZ9kFNj6MZviCqr3QB4VKYffhdQ== msg=V0nY2F1dG3SHG7C6KK3W7XbNoNJZBXR6NwR8bGOQSkY4PmSBMVZn2QU2Poxm+IKqvdAHhUph9+F1JhQUCAkTLg== sig=I0V5Oik45aAedV/NIi4hX+RRjBb7pdkKC9EeLKMiv3jINBWrNpYCGh0RI12W3Ia31LfZNqrsEFoAoiQLfqB/DIAY43zfiRsambMjUnyGI+Y3mJqr18dHQn9azromvHxYtuUmp9K2ceqR+X44UsT/Aj0A e=found last=27 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA7r30W9/z4F5kQWc2Upen+tRo9RidWuDDOq8yVNa72sgjCsZJhgInwapv2W/9O4/fBnjFnwYcqmwA priv=MEcCAQAwBQYDK2VxBDsEOaP1fS92daKp9NQZJ5Zac3Ts1+I5PZJmJshwpcttwhaN2aj8rkKxvonUuwi6SfriY8HOWm5Be3YE6g== msg=o/V9L3Z1oqn01BknllpzdOzX4jk9kmYmyHCly23CFo3ZqPyuQrG+idS7CLpJ+uJjwc5abkF7dgTqEHTKTM2pUQ== sig=/bvJH3E4LOvajAbaUrzmOXoPs6NzeTPhizI3RQmK1HQyDFVltIWW69i1Jzs2GXUJnXDGwnEE6QSAQSueyyBElClkndbDr+i3BPVNLXMD6gpgJIh2rAc1dxqRFBD93C6BRHx5B3wtesqA00PgjlaiqS8A e=found last=27 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAfVsHrLO4pqvKpKFh9MokO9rs9RQH9WzaoRhDD7xY/xmjY3Y1vT0uJYGB90ELSKq/cx50fjDqV8mA priv=MEcCAQAwBQYDK2VxBDsEORvtd+K44eD0Cxw2JjbKJbM+HGu8oe/gVpVLKqkehypIW7n2pUhn0p4L05m0L7PeoYi/UWBqImmO3A== msg=G+134rjh4PQLHDYmNsolsz4ca7yh7+BWlUsqqR6HKkhbufalSGfSngvTmbQvs96hiL9RYGoiaY7c3RKOuqpI6A== sig=lo6Wwa9MT0BLQefNqAiGFRPhfQPON3m6dDDeyynvtMmRyMsolzHkanmoWDNzPU2uZw234o9KU1MA6f8fq7kbTBJLsoMA0Us0WR+DTidn7zgw3IWSqj451RANL6jWxBRl3wsScvFAmhmkuqS2w+n02iYA e=found last=26 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoApPFQYj2Mh7sLd77pdTG83ctJZp+srgikgdVGtHV7q5kwCSJDCcAHEBDb1bDiXpJqwFyJudTc9uoA priv=MEcCAQAwBQYDK2VxBDsEORfTwIwCpQk+NNA5nQVMKn7XYOalpag/psGupSOt6JCx0hnwqbZquQQNytwXp6qX2dakLttzSSswSw== msg=F9PAjAKlCT400DmdBUwqftdg5qWlqD+mwa6lI63okLHSGfCptmq5BA3K3BenqpfZ1qQu23NJKzBLRh03Jc4OXQ== sig=5JYZQdYOb7lwm3J9bEGsMFl9uch6WIRdshubSOyaNBP/R+TTFaRVWlaH7koCSx0Ab9q4gYGKq5cAWFfTttcWT3hEu/ziOjLF6uffuYZ6ue+y+YiuzUtl4B664IfhiuLytlVJCCiFygt/duF5eqjvXQ8A e=found last=26 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA4Fe3M11Jb//a7ZXRMtXvmR59nkahuD/6z9lZilHGRIIG77cpiEZ61KwPF5KB1FKN2WyqtrERbkYA priv=MEcCAQAwBQYDK2VxBDsEOc+Ugy+i3gKBohdZRHciZAre2X/qy0ZiBnyduwh1xV2hlD3bqAu/yHmQ6fLGXE0n0S3Cq+TY57W62g== msg=z5SDL6LeAoGiF1lEdyJkCt7Zf+rLRmIGfJ27CHXFXaGUPduoC7/IeZDp8sZcTSfRLcKr5Njntbraaa8E8Sc20g== sig=X2b9cu5l5bzaacSLNHQWQbQghT9B16vc2ukWLEfn63Ye8f3nB5qJAv4yu5BxVukMKO97rzw1HSSAmcYAK7sG9XLOR0DBZk8OmbmJKDtsLEc2OBOL6SQPK4AGPTwPt1SkAK/8UD4f8eQutAz7oE/g6AQA e=found last=27 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAzjQ+8MSGU6w8beYCHNwkblvVAzgRD4bfc7ZbIALBFShF3ZBa/ml9domDaG7W6HUcs38vGWGjrFqA priv=MEcCAQAwBQYDK2VxBDsEOcYeuTk7RPdIVmRIqUGSFylWf4oU5k350sd7N3KFZof+6LeglVjXrk52tWNDepmwG6s1e1nmCIyQRw== msg=xh65OTtE90hWZEipQZIXKVZ/ihTmTfnSx3s3coVmh/7ot6CVWNeuTna1Y0N6mbAbqzV7WeYIjJBHCMYAx6tchg== sig=wO1obSahf7aSUQDJkANK3xBhuV+IZYuxvPTY3OBVJeGvSbSv+jKluQSEfcB2QmrbfjbBVeQC1uwAxboiZ9KhXiFfsg8ZyecAk6bGGerMoHrZUhu6+mwzL62sv9uoC9uWx+Sltwkn83DlV3iVkGaLIwEA e=found last=26 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAiJ+WiK5KnJ15u5VmgtlfbooCDFPLN+MPxQajmX9wf9jXYZOZLtd/zhnirLD2DPCueQY8ef4lxBUA priv=MEcCAQAwBQYDK2VxBDsEOVXzHroDaMbzTkYJwDOaPSVsNnkfiTC1iZp3nisUlqKFZQxW7n06tVPZSt1vQ7Kr7MKmOBkd4I76xA== msg=VfMeugNoxvNORgnAM5o9JWw2eR+JMLWJmneeKxSWooVlDFbufTq1U9lK3W9DsqvswqY4GR3gjvrEuf4WvJlg8A== sig=Gx37ALzn4oIpFO2st8AQ64DAdJR3wx6UDOaeXK1HcHWGAZjQhriuT/fQZ7v2yBYs+8Dp4QiFyNaAgDaoFcRJlcPVBOMScygQJcLF/BWwRUSMAHP25sTiDxAtiWDcMGOt0o9BpAJr6eo3hYja6I1Zrz0A e=found last=27 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA9hbuwtphQBr8Ty00m3GLFgyn/Q9oeE9NMNYgM/gcrjNWkWSATCJx7BgA3RYF90VfMRcUNrgCR2uA priv=MEcCAQAwBQYDK2VxBDsEOSUzv3U49bzdz97GYKI4tsDWXrpP0Xhaohy/HVlI1WsNjNabmWSzYy8Ic46ZmsH8jc3okkgtOxB7WQ== msg=JTO/dTj1vN3P3sZgoji2wNZeuk/ReFqiHL8dWUjVaw2M1puZZLNjLwhzjpmawfyNzeiSSC07EHtZOy0PxtK8uQ== sig=m0vSY4S6Wx+N2YS4auf5GpBthIXMIf78tIMntA3SUV/d5iy/fv7/yNfctz0WQJJJwmv17ckJYL4A6QXxDNTafUvXfhffVUYYLb+UqTpj5AvCXTwsFp9ZvszR82BJ16leKO0GlSbT53clA8NkyEy9YCAA e=found last=26 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA8NuTEeSbwGTl3IRr9Xn8Tj1Ma3r0Icw6O7nH6PEJnea6e/fGPp1Z2fGPTb4XIefDKWknCW/TZWeA priv=MEcCAQAwBQYDK2VxBDsEOcgdpOskbwI5NbwKlVwQBS5thN+3pvV0oumg5G1eUKWRpu/IMJBu6cpXNqJxuRSdndGxMIOLq625pQ== msg=yB2k6yRvAjk1vAqVXBAFLm2E37em9XSi6aDkbV5QpZGm78gwkG7pylc2onG5FJ2d0bEwg4urrbmlwBRLjsWq5w== sig=/sbcSVbL2l+CDemfJemx78t326mFMvpLNNxcyJtqsCTi3GqiMZyJuvznRXG5byQAPyKKDQjvShmABpZblmFq4tWlE/7mEEB0Pzb0pivhcLfg/UK6xdBI4qYU6c0LT3lwe/xCOWvqJ4vDUZZHO3dscTkA e=found last=27 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAcH3/X0gEViMWnugcutNIiTMEun7v9bRGuYYwpjEtMycpgZsu1CyajHp/VbzVube27dOVuNfUnueA priv=MEcCAQAwBQYDK2VxBDsEOWnuDqTBP+tRVdBeqs3IANV+QKI4KmNuQi0MQmMQPqv/hzDZksXY/2Af7jvC0JefW3C4gh0Mg3qwUA== msg=ae4OpME/61FV0F6qzcgA1X5AojgqY25CLQxCYxA+q/+HMNmSxdj/YB/uO8LQl59bcLiCHQyDerBQLrHHbC+7ug== sig=PKZCMEssQ8nbUQxhPzlw0s6+EjEdSv2rVLAN/658yu0jhiaro8sKtDEGV/voKeNXwqX7NETM8fgAhT3rW94FGjHjbZDSn41xiO3sBUEWq7EZ+A9efZfPJPfSZuLCVFVIpfqIngGlhfJCO6UC82Fw5QsA e=found last=26 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAOGDwDvXn81ziT5xILalvQZz9uug5DRiyX/du1qhb8uScd8FdT1yK1a0hXgJXofQG3C0IQuilks2A priv=MEcCAQAwBQYDK2VxBDsEOdv/BaSqZA30UNFtzewbTDMMNinfQzV2ldHcG7GxwXveyTl1tml4MNtk3CNx0w3SsQg2BYuPDSmrxw== msg=2/8FpKpkDfRQ0W3N7BtMMww2Kd9DNXaV0dwbsbHBe97JOXW2aXgw22TcI3HTDdKxCDYFi48NKavH99vHgJtnCg== sig=0IgrlAyj7VFbPPep16LHnbKtbvRGhQ5/9o4DxZSsxsW2BNWLas9NMp4arAfjdpPQPbUg5I6N0WeAcrk7l61VIMKjTNpdqzlFQTWD+6xUXVzSfq+t9G6QeErncjmDI0PmlfhbyrffNRXoTvukyEvDYgcA e=found last=25 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoARxIt7qDzz/zv8hdUhVZTlfzp1l8GeF23FTugbrkiA8Z6QecUq1YhTzBqwVGPwMN0nmE+SHxcv7GA priv=MEcCAQAwBQYDK2VxBDsEOTv89Y4GNcnoIwe2xjZ1S/uKdkv5mE4MD11GfOPwUIZj2H+youmAg35vhGiWSuhubhNXeOmrEPFOfA== msg=O/z1jgY1yegjB7bGNnVL+4p2S/mYTgwPXUZ84/BQhmPYf7Ki6YCDfm+EaJZK6G5uE1d46asQ8U58TRmYgdLETA== sig=TuBFmVCNEs8P251m26iXXTaHq6F7HyJu+oi847vgGxeZwmCBuUUthVDP7nUhfyhUB+oJgHrTTG6AvJDp04+BhEj5CPdO/tVkO88o658eHV8GEOzxEgx/afY2zq658S0NpRIehPlWuc3WtOAViQ5ByAQA e=found last=27 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAywAoGNiPkk86ininOVTAKhT7rLHI7g6f3oG10Tem+UrRXKpcWQ74aV9/EpKga9ev0BSunASoOjmA priv=MEcCAQAwBQYDK2VxBDsEOX/T5adh6unS+qMyyrG3hQd4htEsvSVnrUi4WZufrzrnhSKUKVOXXTuIrB/GNVjn/1Mw5ePUjylpBA== msg=f9Plp2Hq6dL6ozLKsbeFB3iG0Sy9JWetSLhZm5+vOueFIpQpU5ddO4isH8Y1WOf/UzDl49SPKWkEvVUlIdmRkQ== sig=Bk5STgBOhiARXA4ej15FvFlpCn2ZoFODlM/2SqPbcxEwKfDJ+2RTRgOp+E4SigP/lfZoFZjgPcEA2/ngoHGRTUUzHfgDDIaMm9D3XatSMskAHSBHJJfXPmzsHl2uXSV0/Mz/UbXiXvD8lN6YsBlhMCkA e=found last=27 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA+zbCepL0k3LucihSC4cgEUlqb5qlyBVniI00MxfUyk7XiYR90O00Qt6Nx6MivezUSMdYmpp4M4CA priv=MEcCAQAwBQYDK2VxBDsEOTPNUFITSWGDbRJN2uvjUS4PI/WC80fSFqfUNwa8csaFV6a00Bo3lQp1XIL9UB3kZWl5SMasuRzBRw== msg=M81QUhNJYYNtEk3a6+NRLg8j9YLzR9IWp9Q3BrxyxoVXprTQGjeVCnVcgv1QHeRlaXlIxqy5HMFHCv6LQxQRag== sig=JkxooMctW+TQWIGLpHMks9bJpujOryJDoE8ciYWFOORYO/OQXbEMU2LyPX/wMPeO0YMMpzZIcFsAM08SvOFm21CgH5OZzOiqoGkpmT4YdxhU2Ee0jq1V3LKloHaJsCuyeo2dMSphDiH83nYe2GxEySUA e=found last=25 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAnXzNeySkWkvNCpyzPvlFo7pebiEBIvZBbRDy82xeATwSj+TaDJmn44pG8qVab2VgJhOa4GWwmV8A priv=MEcCAQAwBQYDK2VxBDsEORMZn7q15K/2Zp/bP2SPXyRs/3hEJCoErRqL/Ytt+ZS71gt4QxmoA40SOed02Dg42A8S5rdXYKlnNQ== msg=ExmfurXkr/Zmn9s/ZI9fJGz/eEQkKgStGov9i235lLvWC3hDGagDjRI553TYODjYDxLmt1dgqWc1RZXuMprS9g== sig=6aObndh7bSpmomJZyOAsPLHEKViaqPySBpAFX5zSE+amwUiBTnkkwTE4+SWG/DIY3KrUPxi1XueAg0lBPQKbP6K6c9qbLLDMmV1O9Tnhm9ioXusjhovJ7vNLFcYPgOI2ov0uRUSmID1fB91vV9U4HRYA e=found last=26 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoABq8Mt2BEGyL2b3Hotasq9/r0ZBfzlF+ztBtnFCBN3JT21qRQTIuH9/UV4Wjm7kWXoXhLyFesmhaA priv=MEcCAQAwBQYDK2VxBDsEOaSkKCqP4SzY6wzruYa/EQwpraGSuci4TfiUBSPiufVW5S8oHlk8JkhKYzuBYbT+YGlXXism4ywASg== msg=pKQoKo/hLNjrDOu5hr8RDCmtoZK5yLhN+JQFI+K59VblLygeWTwmSEpjO4FhtP5gaVdeKybjLABKb1U4Kh0AGg== sig=HTEliiGwpAOTcA0JPbxRnKm+wpFl8ycFhOWdee/P3SnDDVTOsH5xvBX2gAJ7+wkkok4UemT9zeSAet3JCOe8gECX3cUHXhZWPJ5lQ0vjjzmZ21guXa7eWJqOl4pnAufpGS09TixD6lT5B7XMSuCyBBoA e=found last=25 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAqMX1wloMBK1XnPVSdQ8rZcwjbOVvFX1idlLvXv7omRH4da35CLKbO/Hgzew/qXml+MfrbspQ73sA priv=MEcCAQAwBQYDK2VxBDsEOb3bQbXtHp/JqLuhyb2I7gQV2sUap2dtX+MGu4QCUiBNJROc6ibfnGdUQCU5Wgx9kIhvNvOyygGIHw== msg=vdtBte0en8mou6HJvYjuBBXaxRqnZ21f4wa7hAJSIE0lE5zqJt+cZ1RAJTlaDH2QiG8287LKAYgfssFD4I5iAQ== sig=+kVkht/xdkVOW8CcSjAfuCmrcWvbF7atd+v2sVGvWidWrMdWqBIuPJgsF8kRTGCj10yHVOtUN1aAZnA/nUwfzLsuEV/pe+ZhH8Mi1EEkGLEUMXC+ziB7qjxHzOKO6eaqZkuSUI5J2bQlRg2W46uPQiUA e=found last=26 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAUL/SFcMnq8dcQ86Nr6kmDPDbab21ZaiAOgnvZGNHEftJvAY9re8/PS4CwISoWiGj6bO+oeC7WO0A priv=MEcCAQAwBQYDK2VxBDsEOTwzFYgNHJvBLSdVPuxeMXVzC71psC6VeG5vz5dE9aq2qTUlKqVDK5YcsYqBEkhM1KdMZ8yrNTfkag== msg=PDMViA0cm8EtJ1U+7F4xdXMLvWmwLpV4bm/Pl0T1qrapNSUqpUMrlhyxioESSEzUp0xnzKs1N+RqN46FwvuGfw== sig=yNxXCRbmOXPeMpZ8oI51wEjCCxQCeqlyllaeYYURRsg9z1CvZJT1fEoJwdTEqMUR/mj+xhJSM/KA3Rfjoo+tSZdbcqsBvtaG5TYlLYB992YW9yfFiO96/Z9sUu2+S36llxBJvyXZGFhb5UWtccDNryEA e=found last=25 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAb7WGT/R9LvlAW5O5LkIOu8DEsUOpiedWqQc2HFqHbcERi9zmrO+vn7J5tBH9Pji6uLpxjNVNTecA priv=MEcCAQAwBQYDK2VxBDsEOS2o0pCuV9eWBLlhobmDkfTn5PfgXPl1ncOirJMr6ME8t31Vi0vpABg9Y/mqiR+IpNIhdh/iuOOn1A== msg=LajSkK5X15YEuWGhuYOR9Ofk9+Bc+XWdw6KskyvowTy3fVWLS+kAGD1j+aqJH4ik0iF2H+K446fUfVdJr5ndNQ== sig=T/gdY5BgWBwEoaYhDTzr9RJ1C8XUoiL8oIbtDuO1G65tigAYKXq8qrKMc1gdKbKUv/iBInUSdauA26bWs3M5cydAYn1rk+hdcYdiGOkJAF68l1P+JmIfMa1O5V9/nvGFrKOj2W7SCoC2/iXyLfe4CDcA e=found last=26 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAKsOK7PepW+05fIy2I3vM7BtFM2L9k/ygjImA8B1sl2gAm1G0V80oTJb881GRrB5CnspczpbFZ28A priv=MEcCAQAwBQYDK2VxBDsEOWxNxl2FpP6kdavbhe122VkuYScpYD4bGm7TbjOqAhCq6LIB7yLBQ/vpbly8Mm3rdEe22khk8WXcLA== msg=bE3GXYWk/qR1q9uF7XbZWS5hJylgPhsabtNuM6oCEKrosgHvIsFD++luXLwybet0R7baSGTxZdwsZDcpGchFBw== sig=LvJrAZ44qQnMEZCeBfCL9/3mWFPyWX6cffOeAmXwmaeKYefueae308pvOiX432aoygqP0pxWBG6AsbDs+n17YHQgxv/mTi3MTrOZY9RNpT5W/B3mgQevqW3uQIPbjcYwTW+e1IEjtfS7dbDsy7hxmiQA e=found last=27 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAjaCt8xBHtDssrE7A/S/0xVBXgr9EV+GT4ge0fqrLWei60vzK40+Ji3dQj567NKB1qAxzMrRRJLyA priv=MEcCAQAwBQYDK2VxBDsEOUeO/aVbBT8M8PxyNQuP0isdAfvBb9S/kc0r1ueyOzwv7EaJZ3Imch5y+D7Z+sbQWoRJEpCfjgXsiw== msg=R479pVsFPwzw/HI1C4/SKx0B+8Fv1L+RzSvW57I7PC/sRolnciZyHnL4Ptn6xtBahEkSkJ+OBeyLiocVYw+e5A== sig=YcJ3InrqaoUKwfuqSRf1NU9YSc60Hlkeng+UdjUbiSc8hMc7eEjfzVerCOs7lwQOs+D2a29CboIAE/27aKohkIgCPKFGXjxfNbHBCLDE+gQMSY2g40sQ2woyKzQlAANg5akVvl8dyGQXrimudPLTABsA e=found last=26 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAjy5gTE5rGZA9aSyKk9Y1M096JQSEFvB63wZI5XnfIJtC4PW85359cMoGIdzd5rappgqF/osKp24A priv=MEcCAQAwBQYDK2VxBDsEOf1+cimNciS+LPdqk0a67LVVb5l9Q8fxEHmNqM9AMZlnzIzIH0sSr4Es9uSVa5EjuW+TRwZkvGS9nQ== msg=/X5yKY1yJL4s92qTRrrstVVvmX1Dx/EQeY2oz0AxmWfMjMgfSxKvgSz25JVrkSO5b5NHBmS8ZL2dmymGlCDinQ== sig=Nr6+LH6AwZAy+3u922ZvHFMjSJxnKIxcvpUvGsNxOQbn5g9OL8b6CFBLrrfiEB9NGhAY37o+EsMAUc0yce672oSSbBo+rbaHa0mpiIJDQ556h6NsXwKl92AntGgmZIylrFnYt90fERbdFo4RLTR7JQAA e=found last=25 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA22tw1JzmICBZ19L9UaHwGbmEUIo9jAPZcbyKW6xwlv7touBNVl62mrUUkJLWCf8voTeBnggHP9GA priv=MEcCAQAwBQYDK2VxBDsEOWZO/U6s94qbEDR+eysG34Y36F9dvOxbLaJCzbVbu62n/ogegSoK0TNIndwCy9tIKeTvV+PbFdj1Kg== msg=Zk79Tqz3ipsQNH57KwbfhjfoX1287FstokLNtVu7raf+iB6BKgrRM0id3ALL20gp5O9X49sV2PUqJ9cXiFdQoQ== sig=PfkWXg47XIwwZxaZzSVCjHq0gTwP/8nCrF0ZURRhSVFDyi2tasPAaNARXHo4zZPCqNbCBcMfuO2AWA7WsIaY2qAyKR3w9ftv1PYJsXxWDMbmZhYk0NavJo8Zv2tIdpBSFaXXQ1v5zAIYy1/ZXOl6rCYA e=found last=27 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWhTHH9QTQP8hxMR/tbQpLRPJopS1aveeDmkdh1ENjt8f4MRhu4exGDV4ajAOk5v/+j0R0tvQra8A priv=MEcCAQAwBQYDK2VxBDsEOUE3W2LE6Py9VSbPDNwNgcO8mzyLp05aTrCHMgzbEWWN37xGhFR3moxN6HSS3rBRIGjpR4aKdRTaYw== msg=QTdbYsTo/L1VJs8M3A2Bw7ybPIunTlpOsIcyDNsRZY3fvEaEVHeajE3odJLesFEgaOlHhop1FNpjEbZwnsukZw== sig=S6c+4m36qqqWxly1eKGZ8TWIzamifR1RIsGhXMfdCYXAR7KXaUt4y9oc9jDQKBop6HnBVCQagKEAHLAqImRSTswpANQ5Gip4MTOy9tQ0dKLV4vxgnA21ES/ofNjUVFHdQhoTQh9JiVKEqPJliofxWBgA e=found last=25 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAnhrKa48vr4t62alkewDt192cJKTcmNxG/PqtcW2AKLnmsdX3yYv/0ksNmCBVTmcWUAclzxIYvm6A priv=MEcCAQAwBQYDK2VxBDsEOY2DdqLiWKV6/qh9mjdW15DGTpZk4eCel6sPdZAWnTE4CtcqbKjnaFY05m6rFqfI3kjVMfB9FxHqnw== msg=jYN2ouJYpXr+qH2aN1bXkMZOlmTh4J6Xqw91kBadMTgK1ypsqOdoVjTmbqsWp8jeSNUx8H0XEeqfDlWpczLQHQ== sig=JeGc0yvoT2zrbO1hL3Ml02BStEtPOWDSxeUaqY6Hgr0lDT8t1KTI4gEdIuQvqbhdVWZPR9iBmTeASY2sHm5EtDz7HixLmNwA+YN2HEZKtioGX7Q51KRnBCZfzGA1GvD1ZxQ2bHwgFw/Nlgu479pbxQIA e=found last=25 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWSeFyQ7XoevL2Q5rg5pI/eUQXYjU0PnRsCN/fXH4oMACVFDbbNl9gXZC1njY+ZPv/cYdFhKXGhSA priv=MEcCAQAwBQYDK2VxBDsEOfChTyU4Tcg/NolyQc/5fG+sn5SNIf3HzojmfXUR2Yxk8eFUFZOUJT983W9+I3JdfcHV682XXOpgpw== msg=8KFPJThNyD82iXJBz/l8b6yflI0h/cfOiOZ9dRHZjGTx4VQVk5QlP3zdb34jcl19wdXrzZdc6mCnraRnDOaIBQ== sig=Ht1Xg9ZTYR0N0FfmXFVNEkT2h1AJjcxsl6vINhRJulW2dd2VMipDZHYa5E52j2F2Dmv7V+FKtWqALdC5cZ0xGP3Ro5j2rDL9lxy+VSAgy6wtOuIBTr4kPc8Kl6ndJ70wJyCEIidFlTvC9rE+Z5R98RMA e=found last=25 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAJQZfP7SRmZP89iJl0b2Vx5c35S46QDHr99nzJ70YvLvQwIgRqNjp5odZjmSYAQYrJlsXABrZWH+A priv=MEcCAQAwBQYDK2VxBDsEOYhPI8cYeyQm8kJSEHWHh8dnhY/8Q0STCZmw4r+a3SFofE2WzE/6KZAk+1Yg4ka60VH8lmkItwYEmA== msg=iE8jxxh7JCbyQlIQdYeHx2eFj/xDRJMJmbDiv5rdIWh8TZbMT/opkCT7ViDiRrrRUfyWaQi3BgSYiki4DbBRzg== sig=RkfRV+mcUN5qGSarscGSOpJETXgZZLzCOewwkKhyPGApV/9Yer+UcwVwaqj5dhFZN/HqebAhONkAA/0vARiUKtCFmGlFlmhGZAWmN6WLckuDSOW5rK/KBCk9tkU8rcaACKZHwG7DNZiLyZVX5aGhGDwA e=found last=25 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoArC+6X5b4DcbtxG5rgmJSFDQW29KFc6GoN9gwbzEVIfi2rkI1AZP5MhZHx4dwl1iJHHOJV4dG7aUA priv=MEcCAQAwBQYDK2VxBDsEOUxAOzGNQkzae8c8WdyCA+vo7Zd9rfALc09glf+rNqgcBByjEJwDhi+KRs6WPttEtoCPDZhYnV1+HA== msg=TEA7MY1CTNp7xzxZ3IID6+jtl32t8AtzT2CV/6s2qBwEHKMQnAOGL4pGzpY+20S2gI8NmFidXX4cVUoeOYy+cg== sig=/cHlo9R3Yod3oeDrsSZ2VCyiv8oH6VmQl4JTw5BVPtLODnGn0g+/HeSd+ZIayGzqOfHcE6zz60IARk6Vn7mvyPORFM//dCIJgoCZeJsTZSN6fcLgr/4YXCejtf4isVgCHakvI5NzstttwzxKGOPRMS4A e=found last=25 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAPXCt+cLZ+R/vNQnl5bm9VxDdSP87Gdxcc+NTf5TTfw6LeNpyNHF/XI4+TPqg1n36rkOhLxCoZ4yA priv=MEcCAQAwBQYDK2VxBDsEOZdJF0JEIhYTvkHuvDOzSjkqzicymk4Bsh8BTDyeFcqTjJRL3fKLnYFWtHcI4PUbRggt33jOd/d8jQ== msg=l0kXQkQiFhO+Qe68M7NKOSrOJzKaTgGyHwFMPJ4VypOMlEvd8oudgVa0dwjg9RtGCC3feM5393yNcgh/h1NPPQ== sig=NNvHO8P6EjUYnMpzaTNZyC+2J0BzCw9eGz7nHUfSQ+hrQ68rJR1XTlkH8/1/jHmgd2dpssStAFAAj29N0fSoRxm6xOKERByCNAztAMPVDJLdyw89uBxvNf28Xk66nFWgfWzHATS2HOpYlScsQtsKUjsA e=found last=25 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAh2wxr7WW9H/2/ikz2pUYD7t5Ta3ZW0sTz00Q2oUw1U9DSZiFuXF2Z31beKTJY9PNTHYlrv/c9suA priv=MEcCAQAwBQYDK2VxBDsEObCQSnVqMHsW0JMNkOM0+jQIhL8+PwBxwwvC4ngsb3VYbwgS0jLFiRshm72CE2uFm5Kd1jLoP8pmXQ== msg=sJBKdWowexbQkw2Q4zT6NAiEvz4/AHHDC8LieCxvdVhvCBLSMsWJGyGbvYITa4Wbkp3WMug/ymZdVAvCH7aWXw== sig=/D2vKRGgJ1a0GU1H4YVKn/vr9eTLFuKEpEMufRu85bV91csf7JXbUXeHAXIAp4doxa8SRePJPEKAZIJAyWvmFnLDMpEDpyqV1ZNFeBKU25fd/5iPB6kH6UFo2S+u3/8QVbiP98oSkAmUlbRBPEBWeiEA e=found last=25 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoArR/A6/wuM6IKhhAxzyk3zBia1BDOqDA1xKEz0+aF0DYonq/Mxltid9t49f5wl8OersadNsGweUOA priv=MEcCAQAwBQYDK2VxBDsEOTcsFa77WL7MRJ+6107dX/a6CP/fKsruOmsz3nhTe0U61dNAMz6J6yHK2iGVYoaIhYBbVk4bzNT4VQ== msg=NywVrvtYvsxEn7rXTt1f9roI/98qyu46azPeeFN7RTrV00AzPonrIcraIZVihoiFgFtWThvM1PhV2PoJeq4vaw== sig=Fui+RIJT3RLb8UTkPJl6GuFh25YYunboAQ+dWzAtVkxsDhovFdnmai+UpbvHAJGIw3onMbO+RA6AhunVn6tIdW17KjPpfDWNZ2iHSa2JKIaPNtNjF3ATaW5ZccjiPC44WLSRCWurMiNaYG9udl+qZTUA e=found last=25 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAXuSE5382pAP0wxCeAu56KT68jjwpoSjHOVqogGzEDh0mojmPb0bXV2hGp9mJ59cNvpMShfY6/j8A priv=MEcCAQAwBQYDK2VxBDsEOcLlohV9V1dYZSv1rl7XE9cNZEaBAPJVwukaO8XbT8jfFUOGZlgO1myXcBvl4XbTvQ6kC5SD3do6xA== msg=wuWiFX1XV1hlK/WuXtcT1w1kRoEA8lXC6Ro7xdtPyN8VQ4ZmWA7WbJdwG+XhdtO9DqQLlIPd2jrE0HXipLVa4w== sig=WAEBqGG7Bxcv5X6FzUGAOVRHDkPQdxH5ng4QslJ4gHQ7UxHbktsYmXFIPuZdBl5jtGky4NHMJw6A1vVNpSKz/4lW5gynBUav1E1w6Q733iwaKW7oI2ohjV81+9Arm67KIslHmPa3BPbroBz/UZd/cxUA e=found last=27 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAaE30nPcGew5RG4YeWtrA0xP6V3Ml0AztQ7M6l4Tha5JR1dHzsZRYys4SlV4IWx7Cb5vNKHGLx6CA priv=MEcCAQAwBQYDK2VxBDsEOc57hRn2lQLfqGOuxC4XFlsz1NQibGCLO2wFSPnn2uG5+jvpDi3csp79ySIahfkaeWfpk1ElZMO2og== msg=znuFGfaVAt+oY67ELhcWWzPU1CJsYIs7bAVI+efa4bn6O+kOLdyynv3JIhqF+Rp5Z+mTUSVkw7aildSy//pNRQ== sig=Mhlr1VSfkCWXRvzDiKCKkgetdTz58DMqHi3k2JmikS/4r8w/Px2X+WXCe3zougAEn6voaQEb74SAjNxiSpCnc3if2O7QN3ZJmNdHQdO8hV1L8cMTarzyD95RM4qmc4dyhCU/6hY90UvAJwcdWKocSAkA e=found last=27 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAvHrVSPYcmQ8BgNX4Dv4eIzYG4slU4FGgOegyzRjWm2kRhiX2PIxO6Vi8N82/iLhFMDMSXdGqVnkA priv=MEcCAQAwBQYDK2VxBDsEORwxLhyd+zzp6T5LUJizc987CUBjw0NkVE0lpWzEAnYWZhMM2STfsN+hdqAVSQRHJOcFG8kPvpRLOQ== msg=HDEuHJ37POnpPktQmLNz3zsJQGPDQ2RUTSWlbMQCdhZmEwzZJN+w36F2oBVJBEck5wUbyQ++lEs54LQuwqBXVQ== sig=ZTZMIGEazvo6QtfOA5LLqCCA5pwtFo84jV5tmi0daWr6/8MSCYoqsB/P4WppYaHcXApXp1sWQYAARLumWUchbLjAE3zAXXcjswpP0ezSytQoza8JsbxLWNit6JXDtjigdyJcoUjwlcBjBocFHlZnvxoA e=found last=26 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAtC9bfaZqHrUgN4PALTi0mWAHLUrInAuChgsunNl78dJbchV4XdzaBRlr8v6QspLIeJhfiPr3QJsA priv=MEcCAQAwBQYDK2VxBDsEOSp9nqdYD2PJaF0RrEXMr+kJWRw0m3SFdkJMjPlFcXo294RdYbnkWnHGQpNBMVSura8J9J15z9BMMQ== msg=Kn2ep1gPY8loXRGsRcyv6QlZHDSbdIV2QkyM+UVxejb3hF1hueRaccZCk0ExVK6trwn0nXnP0EwximxoHhp4Gg== sig=sTDlVqdRV5fg/sX1xMlCBhIbzLnEAuYg5W5zak3AQyau4BE+sZnh6R7ye//G/Q/gBuAKPxlVk+QAdyBmNRoxVRgoJ5qSRShGrMxp5YDmkTqhDgNEuOON9BEqXoLawPsh6QC5bZQApyDdlApoJol9qSgA e=found last=24 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAFIM777rsNvfmfh+wsaJ2VqfNStU+OWP+mnYjjLL3OMsIBjsdwoFjKBOVepRnNahOky5Z018vwyeA priv=MEcCAQAwBQYDK2VxBDsEOXyze29hh547Gk3Ok8BR4ER1mZOqWxOFx8joUsKc+jjTrn8AK9c0aREwc3it3qCyTHGrBe16rm0Pyw== msg=fLN7b2GHnjsaTc6TwFHgRHWZk6pbE4XHyOhSwpz6ONOufwAr1zRpETBzeK3eoLJMcasF7XqubQ/Lykvf41AlYw== sig=yzoEVOvY33+l9mdQ0uGSZ0cuaX6oM5tKE5db4V2qxbt3FzCAVbkYonE4ULVmfQ4KbLSdc0h4JxQAxG4zQqA+icEyaw0yvMVfEPfLpLJg1F+dfrrY8T292OnQRlfl3jOjW/ihDuevzDwrRf1SxkR8YyEA e=found last=24 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA2ACq27s4chtYQIwlmPRdaRCNPcpVIonK50FJPMYejbco8RXCuI8DMOlHB8ahx4TzAwsiQ6lm9v4A priv=MEcCAQAwBQYDK2VxBDsEOdsdat8udM03wfjloFejCSH9w53AZbRFTmdf/Ao+2ienleBGS3phUts20V8J5jdoCiYdB+f3ZfoelA== msg=2x1q3y50zTfB+OWgV6MJIf3DncBltEVOZ1/8Cj7aJ6eV4EZLemFS2zbRXwnmN2gKJh0H5/dl+h6UekTOQymwRg== sig=4a682EFm73iGIkpglMjeRvIBRli6LRYJk/32W9JnfdgvZ8FjxJ7E5r/LTEwfEKwirJ68Yza5opsA/W+B06xFvGq91tdeW6HrRXbWD7NEWYETmbVSbGzR6MEUWlxYdSA2eTTdImGubnVABchAfuk2lhIA e=found last=24 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA9T9iqE6lOBXOQ3XE0W7J1fQM4r+0g4LyZootplGpIEHGe+X6n+Nw2Ali+n8ixokeEzCSXt4mcpKA priv=MEcCAQAwBQYDK2VxBDsEOePpu2A0KkDo403jGp+q+gMrw12OPmYMOjth9bCl8OhFs9A4aUeKNWZ7jOlxZt/hiB2xF1LmAZv0Hw== msg=4+m7YDQqQOjjTeMan6r6AyvDXY4+Zgw6O2H1sKXw6EWz0DhpR4o1ZnuM6XFm3+GIHbEXUuYBm/QfTsL/D0RsmQ== sig=FIvBSNq3ulJDWOfYUU/hkZRE30umwWWhiuLKpAnHDG+kJ6RMQFVI23nZO4Are9KYuHevQXE6TKKAb8csh+XheDX/7wsCBDHwelUlLZEPLskD7MNVgpn6rNGGfGtcYbhwamD/2i/5P9iLeScvj0SNqh8A e=found last=25 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAOZQtHt6WI0h8lI9NXGwh9x3bPYMcA7Bbw4AGJaJ1RkZVv9ZLiic4ifgjPh/vjqRVfIMGuJzYrG4A priv=MEcCAQAwBQYDK2VxBDsEOfUBFfTzp6DFxVjzVPi2GUMiu8iqchDcsf4WCoBQJ9VTH0J6GUwYn6udxpx+qt7F00MNJKDHnCaItg== msg=9QEV9POnoMXFWPNU+LYZQyK7yKpyENyx/hYKgFAn1VMfQnoZTBifq53GnH6q3sXTQw0koMecJoi2VcpY3lkVvg== sig=u+1hiIgudvg9MdYI35Zl6FJalqiiP/W3mbhWQYvbpNTKUwgnjfcFaFolqdPJuQ6fJqNl7W5hD8wAQ06bJ7HIHgmvisAfUaAYQfGCMZBxpa+C7+kgUSuCawCCiCQWlqmklBA3BLRCckIpDbnB2QgIfTUA e=found last=24 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAtuyFq6SMZvPnkiEfCH+jB9UqjSrYHpSIOE0+9EOzHVn3RExlMgqo0Jf+pr9iLt6rs+A0Mem6gMgA priv=MEcCAQAwBQYDK2VxBDsEOby01MLlBxcroDMETNGo3D3/86TxvTGXxwkFj9mq5aZlG905jZ0m/6P7si2r7hFQJIT50DM1H/SPaQ== msg=vLTUwuUHFyugMwRM0ajcPf/zpPG9MZfHCQWP2arlpmUb3TmNnSb/o/uyLavuEVAkhPnQMzUf9I9p2afApmxOFg== sig=Lj14xgwyjhNONi72xf6DEt7/G8ood7WBmv1w2kYIfZ2OjmU1vNekg/dDN7NM1kNbs1xDl1e5krEAx0lOsBlWwzbyPiS7fuhl/f7OTOlRhUlYIE572zi8W4cm3AD7GVDWK9PrNOe+SH1z5S1j+l6YBQcA e=found last=25 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5X2lHOcsZ6VlIm1a8sP6GTajQ1Gwi0fsXaU2rYIrg3W+uZYNhhfWh1RNs4MBhhbRCvdMnl9PsquA priv=MEcCAQAwBQYDK2VxBDsEObZDnPYO+J5ALQ5NT5J9BvE1xPXFd6AvYaD1t1aul8V/Jfg0x62DIKi69TWI/WSpLsxR+WozV1w5Wg== msg=tkOc9g74nkAtDk1Pkn0G8TXE9cV3oC9hoPW3Vq6XxX8l+DTHrYMgqLr1NYj9ZKkuzFH5ajNXXDlagQo1fKjO/Q== sig=UJq0noKiKT4NomFZMdrbjEjoguXl2NSanlk3vKLnQLdmHlfVWBqsTndfLkVMofrl1cxLnQYedEEAAHlijLhT9Dz7hv+k0vbL896QvNyOJozum3pb4Ov75NTKJyXfgPoJJH4iVFPrTH33cq0/LIvIJi0A e=found last=24 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAJvKJ5cBAWBO8UpWI9ZGBBLdvs7W1dapRvdizFrFrDZq74m96A1JV32l8FsTJ1l3HLbFsSTITK2UA priv=MEcCAQAwBQYDK2VxBDsEOcecarvPdPAi0UPej5n9hmrNVofle8ldsmVc1j+Q2iiXk3CGYKFZDOEXHwBMUQ+7EsnNOj10/EYIBA== msg=x5xqu8908CLRQ96Pmf2Gas1Wh+V7yV2yZVzWP5DaKJeTcIZgoVkM4RcfAExRD7sSyc06PXT8RggEo00l6EFqKw== sig=IbjQFkQEBu5RwaQh3ngaDOCXil9z/8FuNhiKkjgfoNWmENYC1uMBTV8oprASY1a7Aj7kt945gjcA49yBqlRgvUVij1ebpZQrbtn8tjy0Df4N6EGV2wxXom9AsRIhqhsd9PJolTL708Dvr8hkJfYSLhYA e=found last=24 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWshCGSbbp52DYMcOluIXB8XK35VVOPpTLpaZQAdQvdMjXRC4sqZ3OlmHHxXjecwyL/3nqO1JiZsA priv=MEcCAQAwBQYDK2VxBDsEOXSaCXlY/XPI3nBCVOJcbvDsVoqaXBq6itvyeXCcY65nU611xZ8N+EU03YvPfZR+GAtFFD1THKBHXg== msg=dJoJeVj9c8jecEJU4lxu8OxWippcGrqK2/J5cJxjrmdTrXXFnw34RTTdi899lH4YC0UUPVMcoEde1SsWX77ykA== sig=dbjCP8a8zUkzffqW2qQ55TALxaQfbFqY/5/yIXq9nsw0PdkzcWhiRpy7LZ+DFlIXZWXl0kRdWtOA38xkbQYROTrPdkci+3gr38TIiRktag4CmmP3on4qNtioOOwW4kcduGlbLx+y4oTbk4W10bfhfxMA e=found last=24 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAuP0wDFhZfisaP5FMZ6/EdzM6LehnZ8laogWviRoH7mZ8t7Kx3ugJPf4wA3Oilqg24Uh8irqMbTqA priv=MEcCAQAwBQYDK2VxBDsEORxNCa+k6EszXWc5G6b0ifhw6TYvYnYo8NpbCr6lV/Ix2+VyDycE9NUyB2+bgHs8QjyfP43n5NGJ6g== msg=HE0Jr6ToSzNdZzkbpvSJ+HDpNi9idijw2lsKvqVX8jHb5XIPJwT01TIHb5uAezxCPJ8/jefk0YnqHfrcdXkX5A== sig=K2oIW36whU94A4yVI8TVpUckanOiyuSOHxObYjVvXrx0+v3aGTVeqayNKBdXjoOxIsP347qx46GAa47lB/BkQ+6QMVs6Z3vk8eJ9JI4yxg6nK8hgn7SSNDWfiqVVgxMq5cCFGnm0S+OeesHcIUfruSEA e=found last=24 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAT5Fy3QCrd3PswSm3rxnAuLdGOYRKo8xRhtPRzc8QP7QEdtM2xJGBuPQVFR2wO41KqjVYyomvAtcA priv=MEcCAQAwBQYDK2VxBDsEOScDmiAgxvDKaXWHshp2UjV2fmu8Lv0SPjg9JGsZVshgsSZKGfDbM0XP0uZj5m48Mjjwqre2FziPbA== msg=JwOaICDG8MppdYeyGnZSNXZ+a7wu/RI+OD0kaxlWyGCxJkoZ8NszRc/S5mPmbjwyOPCqt7YXOI9sfOmkdTYW9A== sig=RCyoSle5WbcqZzYzG6SNFfRVaapm9ZgatKa8vM5OUlSMmnbI+a4oyQloNym1K4fi0gBszS/TT8yAbk8Fd559Rs6bMOsb2wRkhJzdQPqGG0jyjBJMqaYNJUc1RU2x8q+D/rIfte7c+ZhHc0isPuUVfhQA e=found last=24 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAZpY9vLamaRdTO4rwxjrYhZt9A6auFu4xa7nI1lHM9FRtC3iQHV/9lhVL77izwGcwcUXeYNz+J4QA priv=MEcCAQAwBQYDK2VxBDsEOUYmodwSxRTdkm866XMoU1fg7FjjsyBNVMM4svnMpn5qRYkHxOYoGcIP9xrr7NRuMfgJL/Q0DwXNlQ== msg=Riah3BLFFN2SbzrpcyhTV+DsWOOzIE1Uwziy+cymfmpFiQfE5igZwg/3Guvs1G4x+Akv9DQPBc2VndzfR1ukcw== sig=vVs5XBOOJJMNXhfqCWNqz5E2Cmtafq+AJOkdSZEGSU9UXSOMzoE8vRhth5NzTChPlByayNfBDf6A2KCcqnE0YPlYF08fAFzrYfYR7rkYNZy+agNGv0URT5mnEURMqD7vgzZ3vZiofA8IuKz/4aEEixQA e=found last=24 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAKpe5fFpl+3treGBl7Kt7W/8PzGS2RuEvDL0w128NEcYf33R9nWYemykknIovkZNICE4cML4wDEmA priv=MEcCAQAwBQYDK2VxBDsEOcWifeL270utSTeet/UsMdlbmFZL9+a8i2q5WmOi+1c52Zw2XrVFqA/PdcIFWKr0fN94PSUKzJNoKQ== msg=xaJ94vbvS61JN5639Swx2VuYVkv35ryLarlaY6L7VznZnDZetUWoD891wgVYqvR833g9JQrMk2gpyVhb/auHow== sig=S+FLRElcvocsakyjDTjF3h66r1LZJ7WbJ5CuHmAsLGJrS5huZenwmnsq8ODIVeFv6gnKpA7hYRKAIcgT4NcpQJe1Gsc4lWL4KipPbwSyQ5FKJCDR+1W9ewkpsLBU5ESzOqi8jwjoCIB5gKfZK5m30S4A e=found last=24 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAK08f4O9EpkWzWpq1AKJhc13tID8ESO11Cfn7FxQB3FLnWAV11XOTqgPBMaugYDYM98l7/51wxLiA priv=MEcCAQAwBQYDK2VxBDsEOd3x1joUEt9gYRrDGP5FcOFrHs4TDl7mUKTtcSyxKjnurl8WDUl+6XgeMbqg9rkBya7YBxY0BiErQw== msg=3fHWOhQS32BhGsMY/kVw4WsezhMOXuZQpO1xLLEqOe6uXxYNSX7peB4xuqD2uQHJrtgHFjQGIStDe32xD9UDxw== sig=ohJZUJ97hlDs3ek+9xbNPfG7BjRnFLKK9mJEFm8JgQQU3Db+/h44SONVsexnnwVtn38J1ATxTvKAGpRBxZIZy4dLKiRb2bNM+eoGpzL5vC8+3p1lYLUa9Gp9PtlSIr2jfos8Mn4piqGCnWSYKl3yvCEA e=found last=24 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAf+IxRuk2cFH+IEwQBdCL7dhH5KIIHod32aOgZvDMMraSa6EdbiWWI2PwVRxS9MguWHZKJyOjv1YA priv=MEcCAQAwBQYDK2VxBDsEOXxOF+vZn4aZU7rMfKWP0jeiwLCDZI5SbVevPJmkEaVwRNWHK+53wdX0jlgXaLozZLt93VGZsNz0dQ== msg=fE4X69mfhplTusx8pY/SN6LAsINkjlJtV688maQRpXBE1Ycr7nfB1fSOWBdoujNku33dUZmw3PR13XDwhqnkAg== sig=ZnCKEM6GTcjg5n92xVHMEdnMaUQS6EdokVrjBIBKO4Qu0ZZxqFV9A2K0C3T+l5w6bgBHv8SRNNWAWMTFJKelU9XDqBrJxPT9KTas37quAfwO4NgvhBZuKTYYz4DHZALE8VbXrzD7g7/BgMv2KBPsVjMA e=found last=24 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAPPPBDxEmRsx9Mv2iGUPv/iYF/C+gEBMx2h9p9k8FH6nmqo3RTJO9gqdaBwZMFsZSR982dVqVvl6A priv=MEcCAQAwBQYDK2VxBDsEOfdeuLYN1mJYKuDHy72/s7hfoEyWJ3Lvm4aV/A0PRItuLgH6TBnLazP/HGNE45LfULLAn9Q0j1CahQ== msg=9164tg3WYlgq4MfLvb+zuF+gTJYncu+bhpX8DQ9Ei24uAfpMGctrM/8cY0Tjkt9QssCf1DSPUJqFzQp/STpx8g== sig=d3KgKwK4B0dOEGYm6+lDtdgd4HEwQ7zWoVSeTsmz6eaUGrbkdEBUD598iOqn64djE6h97cIJoCSA7sXyZP0aAfFB+uDnTKHC+o9Eg0T1s3M6Tgc+FCYy/OYaG4SJcmnHSNqlUD18Vx15IDPy+jgHVikA e=found last=24 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAXskZaFvFU7BMIzjxRedI0YFDZcw+GkhnB7pJcJgXLt6MTfSopjhBOfhJJKQzNHW135dWOx6hWYCA priv=MEcCAQAwBQYDK2VxBDsEOaMzHNCqUFevtqvUlh5uhMMkd+CrBYBXgcW123dbKel4cJtdLp+88H2OgeEsW3sDagF4mg8loHtvfw== msg=ozMc0KpQV6+2q9SWHm6EwyR34KsFgFeBxbXbd1sp6Xhwm10un7zwfY6B4SxbewNqAXiaDyWge29/eUh1slkJOA== sig=Z3t40m2XGfA0TXknG4bqdlxkY6FNnAIrz4Y0RjyXO2duTkrxBq9ozxPjJ3E8y2KfMAo8rkQGX+0ASU0VylvrFehMMk6kUhx8mVw4uzIxU10F2neNHR+BXxlKZ9ttiq70lC+Lraocee4F4JnLB2K4iAoA e=found last=23 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAdp4XIYapgQKHeQJRocW4BnktB5Xq2B0qwGz5iQhk0Ui908MDeNMxEI3jTTxxPPR5pXiUIHNmNNqA priv=MEcCAQAwBQYDK2VxBDsEOeSgZHjuzb0uZ9eUYKFk6HyM/kgaSxeHRI4qbupwLMzXNnDPs2VNQ5Fm2cJ0ELbFeG/f4tJVLFjd8A== msg=5KBkeO7NvS5n15RgoWTofIz+SBpLF4dEjipu6nAszNc2cM+zZU1DkWbZwnQQtsV4b9/i0lUsWN3wwmHsPXDRyw== sig=05qf+GAS2b23Hu1aBindcxuiUpF8yDJ4uu9BRKxtWDzTaZ87PGqpjZMYJ3KjtnPJMow1bnIauUuAOCOJfL5GbhP9K6xcpge54kKDRyIL5ZR3LkvFhJaXtVmEWszGOZsOUtmyjTOSt1wZSy8jGiSjFgIA e=found last=23 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAe2z2oxZf2ALNBqOZcSW0wcecBF4dnUFApgwMTKFUp5wBouT0TGKyAxftR66d/Dw+g/RFDge+O0KA priv=MEcCAQAwBQYDK2VxBDsEOSu5BQeazB5tV2CXyjFnA9TJmWL/fa6mxvYLn9uRoWykrTPoayvOEbpZj4GOdyaqV2icPOPfxuCHBg== msg=K7kFB5rMHm1XYJfKMWcD1MmZYv99rqbG9guf25GhbKStM+hrK84RulmPgY53JqpXaJw849/G4IcG4iQP1whjkA== sig=YXUQohq2KH2FtfCkpCjR3APYFaXTqXw/9lHtu2tFVBWnyhJ6oqKD3kXCIAwaDhR+xzGnBIkriFUAEJ7Aya92GJqKWLn7Qxav1Zxoga31GhklX7/mz5jUFI4yYVzuNHj/h6j/+R81qQQ4J4nVo5O9SA0A e=found last=23 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoApQCLxB9HZb8owpeZ1EKyUWqz1k4ywwLcAU7OVA2IRBQwHe054aKinphYpocPOsR/930Ou3xfx9CA priv=MEcCAQAwBQYDK2VxBDsEOcQI+qYifoHJGffFUpMHn+cBOsP9+wRNbsEX85sr6iVnUAT+AZzdfQjoGb0daCFOq8J1QOM6iz7/rQ== msg=xAj6piJ+gckZ98VSkwef5wE6w/37BE1uwRfzmyvqJWdQBP4BnN19COgZvR1oIU6rwnVA4zqLPv+ttATSYxFkBQ== sig=GqETvHNH+qKtROXXnTFFG1UQymtauG6kt7RuvfkQrLIGseZIbn/SlaKk7qUP7kDoahpmc4x/qf6AAQB8I9C3fDOoplWOdAw/ImL0RyGpRpZpKxjZALBQdBhDKlCPoSVNHyjgOythGCWm/bpLGM/kITYA e=found last=23 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoADeiE/NcjaOU8fvAidCHCDg0jtjrMAc1qt2UTM9XpOib8I4eMXZEy09nPON89zmVzyTk2fAz4qTqA priv=MEcCAQAwBQYDK2VxBDsEOS3uHRdlQRjKDMEA7mZUk034rLYuLmayXHpJYmoez2yS6ME+WPsZz7agk+kZ45oFNCXAhgZ9GqO5uQ== msg=Le4dF2VBGMoMwQDuZlSTTfisti4uZrJcekliah7PbJLowT5Y+xnPtqCT6RnjmgU0JcCGBn0ao7m5prHtk66BAw== sig=hFn2ORHBBHCf55Eb6aa+4xf7BtHmQeSzkEEV3V9U4DLofyX/1LBClnZ+jHytaU8awc4+GHewMUqAcG5keR9OfIEwgXaGkJhEKZcC+KuuG/QinRB+sRbQRu8bXIqEVIH9dwP/+ddCzvvo5EVbzZzsPxEA e=found last=24 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAcDZopI4WfVzq6br3c4HIapx3Ay0E+R4u0XThOsVEamn+RXqOCXX24aschPTOkrV/7adg+6b9AvCA priv=MEcCAQAwBQYDK2VxBDsEOf73EHWv4ZJi7NDfDmYdVUynmUx0YfcZgFIVx3//vQF3AXLCYFaBYoRkx/xyPGU9rHqVEXVvfB1UhA== msg=/vcQda/hkmLs0N8OZh1VTKeZTHRh9xmAUhXHf/+9AXcBcsJgVoFihGTH/HI8ZT2sepURdW98HVSEzk6wFj/x+Q== sig=iOn1ClRhR1gyC3E17FCkdZYOWBmPxPfkjfoLpxKUGJWiiICILzkU1FLjlWbplXLbTQ+qy74ki6SAcu5b3srBFIAs+2uya6f+xGhzaJsuCkqHgmlC7m0IjTTZVdSPr1pCDmMWeL3xiUlVkYJ+PIsv/zgA e=found last=23 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAR28gOd8+97T2GNAIi9FLbvGZOuE+khX2mUsNXkpjd2bFKCbk4X491fzVX/Iw3iMV9Zmyket/R6YA priv=MEcCAQAwBQYDK2VxBDsEOXuaug8709+pztlieM/7UhqJt7/JbPz5MMWODJwfFYR9heHdZXvlTMW5+sWX8BcLj9unsyEhfnkcBA== msg=e5q6DzvT36nO2WJ4z/tSGom3v8ls/PkwxY4MnB8VhH2F4d1le+VMxbn6xZfwFwuP26ezISF+eRwEdymFPBrI0A== sig=x2+2+zS9GfsBYLQG8M5LuGjBysq2aiVYH1ABz+LUcVA/64BbVqAzpNBv7c7ygwrFatzWBFk+ZkMA0GPrZmqoumgjtATOMaUxnE0JGLYZJk9L2dC/MOUoluL1dwuo7sxJ9loWW5YOy8+RtFZU54CfLRkA e=found last=23 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAbkzYn/Q5R6qsW48SHB88dVF0hKgxieSbYpjqum2AMufjupz1ikTCJxime3X8T4LEwahUVD2OMqSA priv=MEcCAQAwBQYDK2VxBDsEObMaUo05vJPehvoUz7WoOXPC3VFhx75OmbE5QfbH5ROxugJQmFNF/pDH6S7YASoSIl+s8y4mSlPa6Q== msg=sxpSjTm8k96G+hTPtag5c8LdUWHHvk6ZsTlB9sflE7G6AlCYU0X+kMfpLtgBKhIiX6zzLiZKU9rpGSVage71AA== sig=b7yxvs8fVuH2tP08b7j1QHVJT85i3dEAlAnya8RBuPHGYamSc8R15hUkWPGnl8blzF+YlmqHFJgAyjqCj4sIsVu0NgJIYByRY95AiUiBgXNmTwbXbpWoQpO0bhOpAoxqdgfqvDL/mu/gWJGJm0cT+AoA e=found last=23 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAXjiGE0LOVnjN6X4mcpZQKiNs3SRGSJnkmiYUqcV080vRz8P0JqlZgrBkFLycxckqYwIvElRhmjWA priv=MEcCAQAwBQYDK2VxBDsEOb3xsuy9Q2Xnej4IdSGln92AL0iT4AQqe6OujxidB7tfuF243DuV+OC3vE1n1XjqT+dUslnGwOrZ+w== msg=vfGy7L1DZed6Pgh1IaWf3YAvSJPgBCp7o66PGJ0Hu1+4XbjcO5X44Le8TWfVeOpP51SyWcbA6tn70er8KqLV0w== sig=7lPGVnH5++t9TDPih5umfkkOr9GjukHv6f7bM2e1satpIb041IMyW9tCi59dGuOeJq8VP3kQ+ayA+frPEbaUUScetOgBWWgmQ29xy6tzIY8DHF3dWGlpNBnSGFph87pYnD9V/rJ8blZver5vC5b5cikA e=found last=23 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoARrMSVa601qMd46EvQzz4abPzfVqfmr2vU9wqjjmCkKctbPhLOLW/cSt3nEAarMrXqHwb2oERbMwA priv=MEcCAQAwBQYDK2VxBDsEOa9dXO7fhblxMjts8YWLh0MnJETaaE/CAL0xhVws67VdYXBUclbIl5F5TdE/1yJVo3wgFLbmOX0Rhg== msg=r11c7t+FuXEyO2zxhYuHQyckRNpoT8IAvTGFXCzrtV1hcFRyVsiXkXlN0T/XIlWjfCAUtuY5fRGGIrLZOk9GFA== sig=K+KnjfeH29Y6UzIFyokm8CADQ5ZsGD0ntHBmZyKFuMK+i5dHjj/E6N0RV/+dAMYrYZ9COHWgCsEAo1vGwusJc9OgkQ9iynNmAaP1Om1X3FvlyR3Pg29txFjotpgdVd4nt/Bv8zkEgRwnLCWyzyx67B0A e=found last=27 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5M2bYbb12st0aakEb6Elkq7kh4BpZppGbiMk3Ba+MBjEmERPkLJ6d4G5gEXMj1PTrW7V7JIi3oGA priv=MEcCAQAwBQYDK2VxBDsEObN1QgYhBMTS/9dC1KMj4V8MLPLLbF8xNadweEQzn0ne4Cy8v5ryQo1/8wNvDb1Awytfa7e2g+zWPg== msg=s3VCBiEExNL/10LUoyPhXwws8stsXzE1p3B4RDOfSd7gLLy/mvJCjX/zA28NvUDDK19rt7aD7NY+SPlX2RawlQ== sig=UD3+onB4AC4R121Ew3M6uhGAGJMD7tVEqZim9yqAEcVk/stS6CYtdN651WC7mcb9J2yd+BhrPbUAhlL/6p6tJRPdFqTDZJmY3x5LrKzhPD4E4qaFIlm5vU+YbxA+ZeIqywr0JGx2rLJoHa5kLt6wQxwA e=found last=23 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAlqV7W8WOiiL91SI6xkJDkPCmLdBXM7RF58oCAoek5UYJ48TvP8WKo+hMHvCvjMqOlgicE+qv43oA priv=MEcCAQAwBQYDK2VxBDsEOdpgsoHKdIEMy3qY6Nhxd+xQCRzo423h3HhkBEjEjODdcbv4N49B2Qj6c9T/ErU/pVj0BPmwInJejQ== msg=2mCygcp0gQzLepjo2HF37FAJHOjjbeHceGQESMSM4N1xu/g3j0HZCPpz1P8StT+lWPQE+bAicl6Np3It0IxvOw== sig=Wv1xVlXmkcEJ0/556tHBJzOi4z2g2pZ4Je2UdhvrqZURqxqzYy9IzJ97VCnkzTyInCNfbYG6gOMAZqPoJVr7JXigL3U5XLfmq4yZ4fpHCnNitagjphPYiO1M7kp6IGGqvMby/DHn0b25qVXw16xkRBUA e=found last=23 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAq30EjRUn4iEbl0RpNpyx/K+JieW41F7WWcuqcuV6i56WvrqGxUqwqHf40i0fAmC/tmRKl8PxvgYA priv=MEcCAQAwBQYDK2VxBDsEOYVopxBvR6G2ghS1wbY0P5CMKVZgJU3icYmYYMGru2/KpRD9CbQEbPSg0mi/LlNIvjfJglGG7ZxYow== msg=hWinEG9HobaCFLXBtjQ/kIwpVmAlTeJxiZhgwau7b8qlEP0JtARs9KDSaL8uU0i+N8mCUYbtnFijVxGjdJWyJQ== sig=QmdF/xjNRkaeEm8wTJnzh8e2+mSR4u57yCU/9aoFq458WQRlUDauxS0q/73Ymh14Y+L3zm3WBZ0A7BJZ5nZYVxHfXnzCKYGysA78Q/htMFZWy5TLfKGg89LbFXsW/r+TfLJ6dlwEw8+qTdvrmOdNsx4A e=found last=22 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAGrk/pNQxn7T5YwGWNRu9SQCpJgWnQV9D+2Hp4bdmxlXluDTcvNsItFlvmvtwq5TwPvkkxzMnGsOA priv=MEcCAQAwBQYDK2VxBDsEOcw3iEY5zqoCEGU9iBKPJX1wjhOHIPQWXbPROAYaWACiENdfJpw2+LwObg1q2ZV9sMQJM4vDVTgtPA== msg=zDeIRjnOqgIQZT2IEo8lfXCOE4cg9BZds9E4BhpYAKIQ118mnDb4vA5uDWrZlX2wxAkzi8NVOC08SwcWbzurZg== sig=4jbZEcAHggeNdq9oD5y5K8KgIvbj8OSgsXteJebuk05N0LOuC5oYwJSqMVCIx5wFqfraN/VEzwYAZ/+/+G8C+eYpb9v5U1ZoaD83b7N+p+3gZKlz+6qjkszkwJbPa5S+T19zAxEMcnUlSBJX/V9ZrjQA e=found last=26 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAApe28XlHk90J1sjzLXmXimRFTsKF6LIRU73sGGejPaCDHJ9EJgNltPlleozE/MR0ah9RIl7quX6A priv=MEcCAQAwBQYDK2VxBDsEOdUE6MsdcLtTA3gKKdYziuRDBdAI9tMx6Bf+rQT848LQprEwuN/6ZlSC8wigej5z7iJbK1wza39U4Q== msg=1QToyx1wu1MDeAop1jOK5EMF0Aj20zHoF/6tBPzjwtCmsTC43/pmVILzCKB6PnPuIlsrXDNrf1ThaiSamS72TA== sig=9Pl8oVFqDHm+rTG0NPdxOlyM+qny4d06EBpkLtjogsvYb85qB2Vo7GOYIj4P8zHF0M7qOdsGVKEA7N0YzoElCc8BAWLN+9GRpgsC2YXSjpyH6OkD3Hd3owcWVJbA0GoZf49wnHSMt8WShp+WvGNQUQUA e=found last=24 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAnodQ38KxDm7BiqjZ85M4prnnlTZ4+lwltTcTGBe4rO/jVKNWVNglkbWOH5XU1MwSZcOQnH4AkIqA priv=MEcCAQAwBQYDK2VxBDsEOe55NkeorfF1fz08cQstdcmjvvo0YE4sS20k/gHO1u0738yrMtnKkySmjh0xH4awycZ6KVavmaA08w== msg=7nk2R6it8XV/PTxxCy11yaO++jRgTixLbST+Ac7W7TvfzKsy2cqTJKaOHTEfhrDJxnopVq+ZoDTzPoP6Nl/0eQ== sig=SGdCIwFT6KFU7F3x/c3Exu4LfWWM6njSeI4ZiJ1phwhkbEYP6JDmB4IGiHqxqRi26+0WP1EMESoAtV0UDrV0JymJZHEbhji29BmhWvsPmxObyMZ2ra3vU1yL15XrAP0ySNEAtGnjYhaVdpyrVP5xqwsA e=found last=24 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAYSm4ifAK0oGIgFkogiUAVWZB4WsyD30jd4JIG384lvkZzsDHGhKcaBYgM2LTqNB5p4DitES8qTuA priv=MEcCAQAwBQYDK2VxBDsEOV1luKD91lIXy+5Oudsb+uav+Zs07XGp4/mVRsNiRDjdBy65gtkuAwvvAiRjzS5G0ANbms8F4rPJHg== msg=XWW4oP3WUhfL7k652xv65q/5mzTtcanj+ZVGw2JEON0HLrmC2S4DC+8CJGPNLkbQA1uazwXis8keaUymKYP2ZQ== sig=QcgnVxuRr5fEI2BO2E5efwuHeUkFKJQknNaRjbNN1KMPd3w4bpOwdEtkH6ajJ5tUPRO00qPwqoiAzHLPgHW1p2JfDFZbvjcXDaAuq4+gC4PQRRdKykBcUFvSrIPts1WIA1rxm7ElsT4yZp9bo6u2szAA e=found last=23 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAlvBCZYQ5lvzLChSzb/Mh2xj3kIfPNAi/L0Fv34LJlCPJDM1IK3Aa0T0NH6QlWjMPVbzygVp7DySA priv=MEcCAQAwBQYDK2VxBDsEOSF0c5OykIl6JTY0Gza6PLuAp6srfbf2m7ZP3cQ+yg9NCHpa5mMhXx9P+SA+VCjVPybfKg+zyYXI6w== msg=IXRzk7KQiXolNjQbNro8u4Cnqyt9t/abtk/dxD7KD00IelrmYyFfH0/5ID5UKNU/Jt8qD7PJhcjrWVVTeZ0j6Q== sig=a9GAgi79DRehN+DhGjxKa5LYfIJHnmgPttr1sIANUkN5YlEAcCo8+1RGctICeyL2U4GWGT6KG5KAx3Tc6scbOgSR6EDupzOlPXQtJ+yg4MfxJv9plwCFfT+K9t0AsTcbE5qBmTes9bTpdIcdidyXJzQA e=found last=24 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWS8Yg66lAJBnz3XYk0k/GH4dLOYRhFSSHaNPSJZ6l4zg/qJvJ71sSjtvu0r2/YCxbD48yG7myDUA priv=MEcCAQAwBQYDK2VxBDsEOaXe3eOwGa2GPHZwnt4pgiDgqATwhHTzg+LIg9NRnFEOG4CudXVaZDmJdn1n5KgdjDMDsBKUA7Sreg== msg=pd7d47AZrYY8dnCe3imCIOCoBPCEdPOD4siD01GcUQ4bgK51dVpkOYl2fWfkqB2MMwOwEpQDtKt6c5d+DhA8Zw== sig=7ppONXIgxNUbKkVdPrETLPpqcLrcuH6xopxdb5rl2dFDDb0Eo8oofDT1VdT8A0pYPvtL0UYEVggAgYw/QpYioXOaZsvBqT7/aRPYSyD5w1MtbolWUTsGE+pwkOlAVOdSCKGs1R+iwj8pt2fok+NEDCAA e=found last=22 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA5n6tpqdeTIxXCoI1spKHWXWCkDhatQs6PBbgCJFHUEFoukSEARm9B9ud5F8gqtpBusLyIz/fhcQA priv=MEcCAQAwBQYDK2VxBDsEOREeNvT3Ko/9DJMJ2O+5dM9TgaimK04eiiUvwRMDRuKay2f10f2wgOgMCPMdqpy286AZh9DwXqYXlw== msg=ER429Pcqj/0MkwnY77l0z1OBqKYrTh6KJS/BEwNG4prLZ/XR/bCA6AwI8x2qnLbzoBmH0PBepheXxco0BOmiQA== sig=pdbb41AsVXIXTPL162eNWCqgpH99qbOCurjE4gnq8kTgbg6omDZAT97Mqr25oQTe+ZE+8LfUJUEAgKYTi+EkHo/erfSgSSdeiAtFllgb73NoxCUSZIUzBCRZqeeKuKLiACyNqAI7Rh2y1XaORGIhuTUA e=found last=25 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAB5bwZ8mhkgIsVEEjV9JB4Pt1lyMAB44IlLpuw9yAKp/SDnihKaWyvYxQ4eQ8o9ckHGCn1t/qLYOA priv=MEcCAQAwBQYDK2VxBDsEObDDUhTLfG9EgWi2Fs47sdkbCHPo5C51Dj330+5ezMAjEN89GVVvlCSetjgDz5fu5jLj0GJa7yMqAw== msg=sMNSFMt8b0SBaLYWzjux2RsIc+jkLnUOPffT7l7MwCMQ3z0ZVW+UJJ62OAPPl+7mMuPQYlrvIyoDTkm02WyvWA== sig=iu8bFJsZq0wKtHHBK7cEekAJlwC/0xpoIV2eg1tc5vrRC+Jyr8DiOrjD3vA/X1r2uQ8jjcOzEbwAzemNVGvWDeRjmMIBr/9pOYIyS42NXHdotOKTO+nNAEkv2dbX/QM/Cigh6FHHx318dv3b3ztY3TMA e=found last=22 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoADfDUEip0PS9DuatDmFdWkr9hlkExW0uQ19+bOhPikYG0YrJfEOfhKW6SGlqL7lEuawomnLgpPakA priv=MEcCAQAwBQYDK2VxBDsEOVKbDNv+JNvmBzDdrPHJjIKCRQAit/G9vhKqHM/cITdNKq7OXBmsf+PGdxtKPr1GvkHwevdbdmQbKw== msg=UpsM2/4k2+YHMN2s8cmMgoJFACK38b2+Eqocz9whN00qrs5cGax/48Z3G0o+vUa+QfB691t2ZBsrr0cNGcd4ew== sig=qACSMaIPNSVEJ2q/qTxrIHBlzCvg6hFx0bmeHSqqlD30lq8mri+szxDZ+Ma1HVz/nVizxKQlR/sA2ABV3ytaClKhXk/iIqTbxR3K6XOIGzOkLWAy/0Ei3e0HUicT/IRuTB84rAOXGno5gVPw+gqVqSAA e=found last=23 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA31Vw3TrI/khsdKVj3fw18/OuGJV2/nAQVwoY5D64NsAz5JUEkvi4zBiyhakngjZllBZxltoXlXsA priv=MEcCAQAwBQYDK2VxBDsEORdkZzYf5W1bhuxzWaKKd0O6bCnWyOqTYbe2L/0k7fynjFz/4XG3tAtCBHOSVFBTrbN3BXIAaorjvw== msg=F2RnNh/lbVuG7HNZoop3Q7psKdbI6pNht7Yv/STt/KeMXP/hcbe0C0IEc5JUUFOts3cFcgBqiuO/vBb5TPSH8g== sig=AIqRIowpQ6T9oZeE2v8iv3RwsZf1SM5pftq6N+wz/6YHhASLuoPsflIx5zTS6ao6ePfbmv3ZIOwARus0qegwCvAeS/Uu1bRkURkH2EN9EnaYYadOzXrcqOrZPUtNiQiLZXUg8FF5XSey/z2YdEvoXQoA e=found last=23 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAx6Xp6HPCWLg9h4Ir7C8848O4/Yat0BqVRPxyaPP7hU3UUZ2DoPw11ryUmEl+GeveKrs+HaNKJumA priv=MEcCAQAwBQYDK2VxBDsEOY/AXDgnwdb0rGkLo9oMW7svPBKMrlqMgX3yReWp8G75nW/ybvwas9R3/rVortmA3JhMy3HzVKqbMA== msg=j8BcOCfB1vSsaQuj2gxbuy88EoyuWoyBffJF5anwbvmdb/Ju/Bqz1Hf+tWiu2YDcmEzLcfNUqpswDmJnqEHBWQ== sig=EZVPi5KZZPqnVdkttX1SKw8kW8TbVFSJVVwQuy0yilZnjh5l5pg8KL7zjstmoXFP57u66TVvzugAvyAkTaqmylKm7jNzbsXwESN+FckbP43GfDpKkuVomv8rUIyPZesRs1Nn1K5rCFWoIA2+7lFvsSEA e=found last=22 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAtDFYwMNWf+irCs5oTvZ/t55nQ/bdJQwvY+dhm05UTGktTrFWY2KNQTpUxhoaQWUBJu7fDLOtNpGA priv=MEcCAQAwBQYDK2VxBDsEOYtTwq24XEwr3NhZT4OVOzffmYNMV7cTr6m5nMFQYqROluv1cKGQh2WRREIeHegHzQGg2+K5Ol+IrA== msg=i1PCrbhcTCvc2FlPg5U7N9+Zg0xXtxOvqbmcwVBipE6W6/VwoZCHZZFEQh4d6AfNAaDb4rk6X4isSDPnw6tVeQ== sig=Yf4BHNC4o0sMU61BI1uYpsOfQzOx8SrDBaI+11vkkpb4jdbQ2BzWKAcXFZKHFos5YxCKswdaWqSAF+wfUd+WYJmeGs7J5Db+m9Z/WY3a4bwH9dfwbSPjShXJyuWpGt0uGXBR0u6XDs9ucbWvbpz7aSEA e=found last=22 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA0smWnjsBC1NBmYoFkspyJpizc+vU9scyUJWU4YSPgXAF3be5PvCUZnCAMeyagVN/gnmZS++AUOQA priv=MEcCAQAwBQYDK2VxBDsEOQi+aAzUZyEFXWPMFthDxcC7zCAuyDAmPObGUuhJadM4+lSjSyYc4KMGL8iF/mjo5Gp0Az3fMHM4IQ== msg=CL5oDNRnIQVdY8wW2EPFwLvMIC7IMCY85sZS6Elp0zj6VKNLJhzgowYvyIX+aOjkanQDPd8wczghmy4RTZRMxg== sig=odXPK7ZctqDYvQjTfU02J7DLxoxPzfc51vf5rvfcyQ5u9wO6ipTwi8+29ox3GM6d76+YLdta+bsA7UScOnW2Nh3lW5RYkRm6Yxh7e/JKX8hygP9oX/W4E142y4rWmHHz0ia/3aihdKJdYj+mnQo5PTAA e=found last=23 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAurkU00eMdWqPcqScM+Jx2SHcBM0nY19C0Xpn0qls6tgy1TkwZ/1S8WzKdakzR1w1g5KtP3VJSMkA priv=MEcCAQAwBQYDK2VxBDsEOdV3eD2wO6zz3XTonQP/dSf4YU3QTpe4bDgv7yKzlmYgvIZuZBVfBVZu4ETdeJdVhmOOTcDzBZNCbw== msg=1Xd4PbA7rPPddOidA/91J/hhTdBOl7hsOC/vIrOWZiC8hm5kFV8FVm7gRN14l1WGY45NwPMFk0JvZZaRT3QPDQ== sig=+WdUloHys69zLnjq+xPwbAYlznm/vJa+xVAp2yXEILVUOlokkX9gSnwFJG9NUwXQBW4ID3lhC+4ATnvQwLDaSJv/uwkL4xklnaV6W1adn9VkPGllfS0twD7fg1WlGJwh7Sl8FIEt25jPpwFkQtxXDA4A e=found last=26 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAMAEC2bZrtsu5zWYl/yIaTRzdhO92aIz/TLuCKobk85vGtsZWn7+Q+oapHuVMBIK+f/wLy5yhl2SA priv=MEcCAQAwBQYDK2VxBDsEOVSK2wpaL43SanxIIuClLDalBt1j3vs3m3NMacbYGM5KWa/45tD/HCEBravJ0R3tU4TSXqGetZC4LQ== msg=VIrbClovjdJqfEgi4KUsNqUG3WPe+zebc0xpxtgYzkpZr/jm0P8cIQGtq8nRHe1ThNJeoZ61kLgtQlKLqk8obw== sig=GnL9scRKU+HXZ/iiHHwx9A2Mdgbbn9gGq3MPkdBlDGx7o1KQrayv20BSivxZnVOIoEfz8DOStk8A1YaeA8F31PDG9wK0xHNB48dMptggYUiG9wdrkfxzRRKSmx3LuzT4QtrnopE4Cjtchxk302toOj8A e=found last=22 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAHngW5pL4VhdMjE7LJstNoATtQuK5DGrMFT0ORxHVAW/5wA4W8Gfvw4Y69xKP/xAkyNWsag8LFw6A priv=MEcCAQAwBQYDK2VxBDsEOdRpmQGiLesYPtq3+ON9tecan1IIToeWA00fkmdd8TUMd2yzJW81TigbfEL93LfOQIYRMuZfKkBgSg== msg=1GmZAaIt6xg+2rf443215xqfUghOh5YDTR+SZ13xNQx3bLMlbzVOKBt8Qv3ct85AhhEy5l8qQGBKwFaq3sRftg== sig=n9UfZld+A6lXTmqrwR40gSgdlvFIvvPmr89wo69mFZs4r3IjuZaq9XY8abrdDwkeM0LG8lmVj3GAVK5BDF1mZm9bWDn76tUjke3mROO5TLUfM//UKq1Gai5jdPLcRAkiB9Gvc5l7uGByOn4HLxB5VBMA e=found last=22 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAmkCmK/b7TD10/qOCbaLl/3wZ+P4VTuGpJKCO7sZtpg4RGeRlbxiv2xzzo4Dt5ykDA1RQ1sNRYQ+A priv=MEcCAQAwBQYDK2VxBDsEOZan0/tXTtzcfDdQSeVv/SUPrpjscJuOyPFUHVo6SvHgXm+h2S1rKdJSKohmEPBJfqPo3xTyThfDhw== msg=lqfT+1dO3Nx8N1BJ5W/9JQ+umOxwm47I8VQdWjpK8eBeb6HZLWsp0lIqiGYQ8El+o+jfFPJOF8OHkxuo4EJnPA== sig=+65VcHiydI4TIavpVRjucS7ILSPbAjt+Lf7kU/XLJEU6xUW02K8kTS5aBzaUeuX4YTKQd289rXQAtpZjqSHKinGl/mjwVdyNT/1baLUltj9gYbVyekuSXHfdsIIHtArnwFd0WwZ92N9vpIrlG0BUxCAA e=found last=22 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAmiBaZr/XGS1HOmBJ79HWF4fQGCfW168M3ZJlau7BqHMf6EK3coREbJoajGMv9CZlJzaUv0twlKMA priv=MEcCAQAwBQYDK2VxBDsEOTkwZNIkeomCbUGLHHVaeC5A+Oi8XZFnx7Jqu0SezKKGyzt47m6s+qrVi+24AcYasQeCgCKyzJP76w== msg=OTBk0iR6iYJtQYscdVp4LkD46LxdkWfHsmq7RJ7MoobLO3jubqz6qtWL7bgBxhqxB4KAIrLMk/vr5+Mr1GjieA== sig=BMv22VQZrXuqa7PATSB/rXLOEoy8Evo+S4z9DuwtFUZyfznVof3qr6yYUj/Wo05a2QFMFyR97yeAYGa1odoDV0e1h5lNXsrQwXgjaeorZQqh5NlHYIVfTmAH6Ouh54m1P4IyMKZPY9ieAp5RKbtkETAA e=found last=22 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAMOhkaL60Aa3yoiAdtlMqc4hek7/s2e20p/lwvxsPt2Eg0gCAB5V/ymUdU5aiinAfY+oLfgB+E+aA priv=MEcCAQAwBQYDK2VxBDsEOTiHEvh89nAhN3vsBCNiu+RuJgPa+4ki+7kRvi8VgETBpzvlg6v0uwwCxkMjQ3gHYSxwUzkhu3qCog== msg=OIcS+Hz2cCE3e+wEI2K75G4mA9r7iSL7uRG+LxWARMGnO+WDq/S7DALGQyNDeAdhLHBTOSG7eoKiXQ0kTv91sg== sig=glzaTjRE5q9uhpnjO+zsm2cq0F5UODCKuT5nH5zo8XBlM3Nu/PEnhbM/rCtzekGABUNZTSbxHhCAbKCZh6Cg8H6giHBvaLPUMsQoGweqg0A7XrtFBiaUUV5pLS4K8+he05iVkhIskku6p4Sw64xpvz8A e=found last=25 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAHrjiL40T8+P9v0eybS5UI+iJjyyZockesIYleAMtVc+e1Ea7mG75btrHNkHgw2dKuyDrQYQorDAA priv=MEcCAQAwBQYDK2VxBDsEOT0GwH3dGvuBKzbjx/AB5n9oKSArEScmz9kymPmvctlGTgrapZmvazziunftbVyzM6MN7BVvd4yQgA== msg=PQbAfd0a+4ErNuPH8AHmf2gpICsRJybP2TKY+a9y2UZOCtqlma9rPOK6d+1tXLMzow3sFW93jJCAqEAn+Uqf7Q== sig=qJB8yuie8qYHp5AD8ujxHWpvxKrMRw6N5DTDSQEQcH+sPlS9Z3h+mBk7i2ct0tF3P5rHEhGuuSaA8vSNHSnH5xyF3iZvQdatA3gmbJWiRIaUIUmfHzKb1m6iaFBTQoS/PV8Dy2cOAM4n4E7nNwDydRQA e=found last=25 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAS4+BmXkFsidt9jcmiiqC3vlJc042dyNgouRiy+1gEGop9dK0eZK3uoTUiHNu9pcP7IYoy480cXqA priv=MEcCAQAwBQYDK2VxBDsEOTmNv4In7xlfErM+uOx44s4NNAS/urTxMNEREJ8Pn0NxZSLTfayWCmpxxShjo/yO+eSXF50WhqO6FA== msg=OY2/gifvGV8Ssz647Hjizg00BL+6tPEw0REQnw+fQ3FlItN9rJYKanHFKGOj/I755JcXnRaGo7oUBh214SlUvg== sig=f+zQ2zwKiOkqzQH7PjRD2XJELlvUWe+IuXutcepjDlnGpVB5XHatFbIHS5Nhsd9V1njIo6L5LhoA2ULD5G1gyNGRha0Nl6GavQQ8GkIDLBvV2BfR9njJOuh10z4xO9zxFw1uN+fNtTfzTBCybIYBojMA e=found last=22 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAFwl3yr+BZTKZ44uPGLbNGgFVwKY3Se9wL3RlASw0wV3B9mFZlEkWYR6pHJdHaAkWRrsOp8QxwMCA priv=MEcCAQAwBQYDK2VxBDsEOcsbATifUFSibtKt8VMT/jXwzfSZdlq1NOmUTO425SkEBWCA2VnNJ4b5bvRMKX8HGzR7vJuH6Jpgbw== msg=yxsBOJ9QVKJu0q3xUxP+NfDN9Jl2WrU06ZRM7jblKQQFYIDZWc0nhvlu9EwpfwcbNHu8m4fommBvHal+oZpbMg== sig=dbmB3qtIhw1tG8d4oq1tyeUQ/5+ZNP+wVDATwzUtnlWKKpGG2wjEMSOjB/Ka8qt/Z2FHBhca/FCAWt5ITbMRasZ1keM8SnBvFcEuVbJOSDrE30sJ/sD17NjXUkdNSypjfu5i+BzRpRFE0Wf04T6zvhUA e=found last=21 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoATDzuqRAdb+4IjIz9VOm3gVh/8V0w8cOEKbm8JAtp+PLiFzEASlQ7O3yrRDAyGdYSxSGlYhnTVceA priv=MEcCAQAwBQYDK2VxBDsEOSaqWHHbtayuJ4Rr059jUaEYMkKfGVSspWFQjtH03P08KA2RjS1RJd+iw25FTqglwgp0J6vYYa0nsg== msg=JqpYcdu1rK4nhGvTn2NRoRgyQp8ZVKylYVCO0fTc/TwoDZGNLVEl36LDbkVOqCXCCnQnq9hhrSeyvIprHu22GA== sig=KgblGAEyYszMBQezn5qoPAeLs/s0Pp6y5pEv/SxQzQATUgVWpr7XUYVqUPSjM5u+L1YNSAPN6AUAMDa3GIxScECluzpyRk42rbYA6+rNIGqIrLPG8MzNB6b5iTdeIu97Qc3NJVIx2gPCwqJiXVxQtToA e=found last=21 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAbLC7N8RW4ihSFRSOYZQSWM8T9za7pAr9D3GkDkB3rkcfgqElYWymDgnulStpn/UJkZxJwZUxcPMA priv=MEcCAQAwBQYDK2VxBDsEOW2flzUfIpYdlD88SBjbpuceJ85CejDpoihNiIWfcqtp6zdixkOcSwafqqHCmm3MReTPtfgb2rs8uw== msg=bZ+XNR8ilh2UPzxIGNum5x4nzkJ6MOmiKE2IhZ9yq2nrN2LGQ5xLBp+qocKabcxF5M+1+Bvauzy73hvIe729Gg== sig=fYCCW1Oixin07OoFQkbtwATrsHRdm1Vl6ySdrlnSVr6UHtCSDupD5K0RXvctTdq6ftR0n81sAnsAuey3uC1HyQ/P06gW4OeOrzweR6DLbmFqee3ACzYuMeteNO73eoC4ASW/KxCkOQVet95dyj29DgoA e=found last=22 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAfj005evobBESDYfGyVIdKZXNcdUgbr/ffMSTWb7Km7tNmli71E2KyIIca3VDoFU6B6U99IDGdWMA priv=MEcCAQAwBQYDK2VxBDsEOc2dOzqOQsrIczxKyKpBkHlZnIX7oAvKBdVuTinqD62DW503iIgNawgib5ghaWXvxHIzoL4UpJlSgg== msg=zZ07Oo5CyshzPErIqkGQeVmchfugC8oF1W5OKeoPrYNbnTeIiA1rCCJvmCFpZe/EcjOgvhSkmVKChVOsa6rcZw== sig=P5Fq8fX4t/Op7c2Uxcs9t2YyW7aKBoY5OPAeczEYkibNTShZs3d/WsLPflM2KJrLnDWWBCXIYJQAWazVn10SWuBEgmwuIgW+9u+mzqS97S9M24klGFdnwq7BCWjxcpvVbNuMBnTeHS/bUsXs/r2WKDoA e=found last=25 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAfazuILAunQV90LcwiYitA7m0WY4/9r3xEsI/O6xMw2UFBtqjZr6IZ8GdopDOo+RQXX/uY0yakS6A priv=MEcCAQAwBQYDK2VxBDsEOSQMV12pC3ReBye9xXHFS7d8rlhZiNf8NEOVuF6qd647daSvprju2hRQbLHa2WBYz9fxwknSxsk/Mw== msg=JAxXXakLdF4HJ73FccVLt3yuWFmI1/w0Q5W4Xqp3rjt1pK+muO7aFFBssdrZYFjP1/HCSdLGyT8z1uMouyPl9w== sig=pQ6xHkmx7wJ1E8F2Wg8PUS66MnbmiZr/gkhxtmtlLXZEn1oTh2WwEJeyUmaPJznGSiJvkzLw0FSAZ16yxDZeJRDUtVb4C0WHJNXXH5/YzrG6iV3rQA9z9KxsQW5am/Z6HEJP/if1tMtbvN0jKxiKCAYA e=found last=21 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoArVmBz5drHd1b+js1iENhf+Gw1tFGonxXYyDOxEezUe3pjk19MVUzI3XUKIePL6zCQ+7KiYeMWoyA priv=MEcCAQAwBQYDK2VxBDsEOSS0Sh1xJv1RhHJ281aVgR9XhLLN9fgR8rn3fjvf8eiGBDsWPFK/5TqmDME71aIZnsg4a5nNRslmgg== msg=JLRKHXEm/VGEcnbzVpWBH1eEss31+BHyufd+O9/x6IYEOxY8Ur/lOqYMwTvVohmeyDhrmc1GyWaCZve3meIrig== sig=qMPS6fsBFsVT0lvNhUVahmg+umw9REVQ/wIJYWIWRJPptOXBK79HiI2+a67xhDIKZedzXL82jpAA+YZ/lY5RwUlgLfNJDjRuEwtQwyfn5HqyjTOCVs3l5hrYRVhdJiBQT3Je7yHe4HTiiCdFVGhKrhUA e=found last=22 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoABh77HcxU1qpI23SByTP7Y/kAfHFgdw+Nyo69sQcVhPWnlaItx2w8tOqAy+KHUgxJTMrfX0bCFQQA priv=MEcCAQAwBQYDK2VxBDsEOcr2czkd51+DDcqbx/K7Xby9YF63Fd5+MGkWuuotr54pbUV6ellKD9+dPQKNFc6FEeLX5OCRaTfm+A== msg=yvZzOR3nX4MNypvH8rtdvL1gXrcV3n4waRa66i2vniltRXp6WUoP3509Ao0VzoUR4tfk4JFpN+b445WR4RKW9w== sig=DAIxQt4lR2Ovrwm7Ha2AHZt3E+v6E4HWYNJ0vmIIjVmis/homZ/+pPJSSjMwzekSIha4L5GhbIWADlqpsQ+21I8GbPfEXpIlqOXH8MAj1VmUEfkcGPb5/Hnn6nn39xWMKC09HQFUgh9TNBsJec4WMjcA e=found last=21 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoALh7MPQXsxZW4KbJtfofNYJ5sVoGqE3Xwy4nxlWYDBFGhYJX8tPp0HXyW7RxhmExZkQHYKZkWpSAA priv=MEcCAQAwBQYDK2VxBDsEObL6LCiexqrwAX11c4JbZu4r7SBT6PaMlqPxK9NvUrKm6K8yWqvDE35uAqrkOjapJLvdE80O0j/OSA== msg=svosKJ7GqvABfXVzgltm7ivtIFPo9oyWo/Er029SsqborzJaq8MTfm4CquQ6Nqkku90TzQ7SP85Ilc0JABsXLQ== sig=B2KCV3GUwrMyd05fawxIp9m0pOOH/M2BiZhMqDZIqLesrhPlfvbaHEHoFVgLO90Ol6ycS7ER5RyAqleAGCH4DQ9bg5KBniWXDbXR7P0jHcVylW+pogrd/UZtRx2Ahb/6VYsZxTgyC4su0r+/Es59LCwA e=found last=22 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAr4efpbsoaguktH8OeLCftHk6BvqgpDhDK0WRtpICFM/wUyLtgDvf0T2CLunJJoB0OK46ONNULduA priv=MEcCAQAwBQYDK2VxBDsEOQYlVugqyd1gx0j0lJM9qDLKsUopXopsdACEhluint9b+o4OCxUtYjDSqlpofDwD9vasyQ5L7R2iqA== msg=BiVW6CrJ3WDHSPSUkz2oMsqxSileimx0AISGW6Ke31v6jg4LFS1iMNKqWmh8PAP29qzJDkvtHaKoYyT7rlezlQ== sig=eMRbZbTozBuQm6rTm02hkHWzK8iXCOOxox7kDPfha6J9hUH+sOYvoPUtpcxtC8zt8qakhsUJ89gAefwq3/tdpjmGo8ZQFGpFgYdQVSCjoctOJ/j3eVzGKrhU/y/Z3BRXPTMfAGyc8iEzlCqX5ZrLBBMA e=found last=26 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAwQT4iS6kZ9gkEXJAILafy7Txd/vfvmpk2ND/zBLqqKAH9aIl31+baDTk6kgUfLF6CEz4m2q8xZqA priv=MEcCAQAwBQYDK2VxBDsEOVBedwf7Ubiva5GyVyl2BdWlf09xiwMI+Nlz2zA8N5MH2Q562EFgqKTirfawV5Z6wejusS321ivcyQ== msg=UF53B/tRuK9rkbJXKXYF1aV/T3GLAwj42XPbMDw3kwfZDnrYQWCopOKt9rBXlnrB6O6xLfbWK9zJnY1ztaNegg== sig=H2OQOLy2CBGYdxvWNY/v+YZ8bcSA3TzaDvMhn9KeiRdsBe8MNLFx5ny40sF/1S7JYPMEqvrWwMOAht+d+fcuqe5cpFkWXAP9tmDS5S0oHQedPK0xbXqw2dOHSFPTKendpsFKLWVfSD97QevfnrlF/QgA e=found last=23 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoADq7TvgXaEnj4Fy21xAy+449VOWXyYo6tMjL1n9xPATCCZXgiQ9zBbeQvwLrn2X7W2Hc529uX9a6A priv=MEcCAQAwBQYDK2VxBDsEORPjAT74uaemZ45SA6F6FagE36YN6DlZVfRJC/2Z/TYsAjvKQYWOstnRvNQKtAi5xQHLTYlekqs17g== msg=E+MBPvi5p6ZnjlIDoXoVqATfpg3oOVlV9EkL/Zn9NiwCO8pBhY6y2dG81Aq0CLnFActNiV6SqzXuUZIa1V28rw== sig=ORNNbz5BvzypBm32J+hX1Y65cjDkJdaspmq8WHHVGvdv2kQTEb56Yj6gTgKkLPvJm0Y7gt/wqNgAo7U2qonrrBySReVLHFGLhPN7lDzTyHV7tinqVVh1tS4caqZeyDp1Xfn9xFj8mVPt6UCoiyDOejQA e=found last=27 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAQEWeJ3N8qpN5ciPrXDPf6nYb1sTwFE5uSXSOOVCdDQzvONEtT/Nk1o/4zU7eDW9H6wDrgUoeB1GA priv=MEcCAQAwBQYDK2VxBDsEOViruV7fz4TblpSbZbea97MyNP0WtjB6G+sjJF3r1TORgwdmeKwHynJ+I36m4GjLDrMl8gyftSwfLg== msg=WKu5Xt/PhNuWlJtlt5r3szI0/Ra2MHob6yMkXevVM5GDB2Z4rAfKcn4jfqbgaMsOsyXyDJ+1LB8urGxYm9u4yA== sig=fdY8IVXha388l+q/EbdaN/rWlh9kd8x5S9VRvbold0HcLdScKInWQhkBjrFbA4sofL4BNpZ0++sAZOKFR4fU2ZSmcS0m1G30/IV6c8rQG48v3rDfqF6S8vT57NzNNUhiY+CNjYBKLxUjyteRRP07UD8A e=found last=26 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAiEp7QwAw0un8rMZbRvXYWSvpHMmYUEipXpi0uEsWO51dz4mKx64bpg7NPmcrIz2Y3QANcdRyatIA priv=MEcCAQAwBQYDK2VxBDsEOecSF6ZQfP3GK+WZcNGQFX1XOXYcmTUGBM5wIO9fWpFVPkWBDUQbbrJunynp489M1qdtofmSZ9ZtzQ== msg=5xIXplB8/cYr5Zlw0ZAVfVc5dhyZNQYEznAg719akVU+RYENRBtusm6fKenjz0zWp22h+ZJn1m3NW9FxwOegHw== sig=6Yu5IMvukjYE4Y3m96pcCk448VxnXYgkzX6+6+4BVrPONfKJWrkwZwCAn6P4B9sXOLRKNmZ0wceAj1coqx5oNEsfTvx1ShkzZpbgE4cqyuPl6quMyP8+58eGVcnAeCqTC3K+Q866FZG8RbsQ1OGBOB4A e=found last=25 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAYxZzv9JLeH6SNw3eB0cgpqNF8Q1QSjufGIQRonGD+yUd/10O/HMJ5L13sgAGvQVNJFe8fegHbDmA priv=MEcCAQAwBQYDK2VxBDsEOW03S36Kd75y/fDtWciP8zKDQc1o7DQcSWSP6wZVxSVwtDdo3d8dcSwygahdyS2MsYN5qsCK/zbt9A== msg=bTdLfop3vnL98O1ZyI/zMoNBzWjsNBxJZI/rBlXFJXC0N2jd3x1xLDKBqF3JLYyxg3mqwIr/Nu30QXjy/tFePQ== sig=bPuW8/FiiZsMscqIep7otJRrmwcQFzX3XtsB/z6BbHrxWfNcb94tSar8CFDNjSLi1Sw0mmDpmliADFggwsX9B9N3OiOvuXH2/PNyvvxWzUl2GfAIfbaZ9SgPhPGJahZHpZK+9AUiN6tmgTyGneF3pxkA e=found last=21 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA3UuOzUmp7h1Fv79JKcrboT5aeSwR4oueNNmtVe7C9DaXs1OB2vQlod4iGsMEyUrmRPJ3zKrGutqA priv=MEcCAQAwBQYDK2VxBDsEOQhH2tN0pw2ky5VsIAoCTC86QmWceCMaO2kk2Fad3utkY/xbrIcew+Z260gEqdgM6qzMrlvwLNinHA== msg=CEfa03SnDaTLlWwgCgJMLzpCZZx4Ixo7aSTYVp3e62Rj/Fushx7D5nbrSASp2AzqrMyuW/As2KcchAqZqGzAUA== sig=ksFFrDLL9qpilVHgDVEnhhay4g7qlob57aECU0tZAynmZFj+Mtb93QUiK95FbAcjwfLhdHTX9vqA/KVNdMSMNM8mMTLP4132vMICkL48a/t/jIuXJVlyb1y9F2Yk9dNBK3ySn5yn5baGr9XDSTo9dzYA e=found last=21 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoADcSKgWClFr6V2Ufd2FTqUtvMbjliJ8aW0GUY7RQ2lOv364veGEK/syqsFgYZTivnLxy7chFPmEwA priv=MEcCAQAwBQYDK2VxBDsEOQIHKj7IpRT9fv8OHn0xDqfsQYum/pWWUtv6UYulAf47KLSq3Fbue+fVltTl6UtG1Bh1iVnWLEGQhg== msg=AgcqPsilFP1+/w4efTEOp+xBi6b+lZZS2/pRi6UB/jsotKrcVu5759WW1OXpS0bUGHWJWdYsQZCG4xuy/ke3aA== sig=qCKyxt0h/dJzsOKxl1adzUaxiTyg+XxveHzJZpOTzf7pPlwuVon6Blp50bAOVoCBOguWANM/HeYAIFk7NUJDKUleyWEbOTwjmohWIpwrrxEsD0o42imfOOt/kIPG+UzxDoqyYTR6J6i8KZgJpo8WdjEA e=found last=21 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAIye6H9D9Ga8IZOZNiaksgXF8pw58NlZayJ6BPgjghCYoLL3Tgp6TO0dIWro+iJk62+7K4IX72l8A priv=MEcCAQAwBQYDK2VxBDsEOREHJ1feomkYvW/IajlmMhzv8ZFCNlEY/mXnBRkI0YfvIFdt6DfDmNbdx20RB0V0Jrv4OpNl6SYvPg== msg=EQcnV96iaRi9b8hqOWYyHO/xkUI2URj+ZecFGQjRh+8gV23oN8OY1t3HbREHRXQmu/g6k2XpJi8+qU8BF1KYHg== sig=r9tb2+ZmFBFxMI8SXUi2zyWTypsVtFNiyYEjxKXXnQSpbrq3IGJ3xw2PVHOCqpOZg3kUozJ8fjqA3FPUmeSXHFSG5FRsoe74j76Yy5WLOkSdfe6P1AvmjQ+1a5xsoPFYLGk3jKcYf7r4kO37c6HtQy8A e=found last=21 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAhckeTX3pV2n8Tb6OaBYtrVv5X6LlznAUJGNTXW5aJW+83d1GNfKRtCR9AXHxtpdc98sbmtOMEykA priv=MEcCAQAwBQYDK2VxBDsEOQ6vgD1tFaGJpYf9R0UDNCo8qXhMNUdASiZlYjyxF0QtinKKOwqSDBNqpJ6MmoVCz8dE4nFGAYoqqA== msg=Dq+APW0VoYmlh/1HRQM0KjypeEw1R0BKJmViPLEXRC2Kcoo7CpIME2qknoyahULPx0TicUYBiiqoiO33nEhhGg== sig=2znsouZNhw8WQKOJVHJQ1cFPrqWj3oviD1IAbleA/0AwEj+shqy9M+KTfYHsNg240WI6XHp7+HmAfI/nrlKfpgK1LaaTeM2MJBdqXVzb4PKzD9yAHD6TV3/vUuXf3UAgDEYpH5WtVs5uJP3L9X059g8A e=found last=24 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAsSwtZmipHH3Dkr52794i0D48JJdGNdSAmJUR/RUAK2GKn00ySW/mZi3UVsVJyLKO2ULCkFeiVXaA priv=MEcCAQAwBQYDK2VxBDsEOSSX4WGFcP8FvMAKhhcmeA8WnjsbF9/qQU1piLcKhveozFLrHAhVXLyRhHiXrppfvJLdHx5K7Rf1NA== msg=JJfhYYVw/wW8wAqGFyZ4DxaeOxsX3+pBTWmItwqG96jMUuscCFVcvJGEeJeuml+8kt0fHkrtF/U0DoqAohv1xw== sig=m1XDHBM+lTTaaJUBpIAQ6TAIpYRvVptBktenrRpm9ZULI3FgvIJPdA9heTWtV5MylqfXmP0ny7oAsVHYaTfeHD9GSLVSRAvzIlyUjkKsVt7NDd67DPED+UBqOcY7mtKlp05WjeJ/9c2hQOnk6fzYjyMA e=found last=21 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAVv4JJaO47VdAftlorZlVbd86HUt93Bv/WbT7yY3PcvUp2hHnHZh5CAj6CWNaoByBFRYxDKOx1T+A priv=MEcCAQAwBQYDK2VxBDsEOYa7nnY+xk/4M76sK+/M6x4R0RqBiRpmauRnuo5G0GwyprUKsfy4gW3ZXlRqsEZoR+aUeUo3xrCC+w== msg=hruedj7GT/gzvqwr78zrHhHRGoGJGmZq5Ge6jkbQbDKmtQqx/LiBbdleVGqwRmhH5pR5SjfGsIL7N41BvPMCxg== sig=C0sFEEUohBb4M44CERMN7DmQoVKFs9A4zQGYLjbnN3Hy+FUahL1/9TZzyWhfYewEc/J3T0LC1nyAY3slTPhkzEcXNPgTk8cn4ljY/oDUh8HQbp/ZDFXxUGq2a7UhLHx+ocsu337vLdk9OXJUM+uVaBkA e=found last=21 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAmaR9E5rEFU623CyhdcXSXas5xb3EK8/sM5J3XfS5uCZP1KXuHs1WNh0GXUKBWB/LH4awiJ6nzlEA priv=MEcCAQAwBQYDK2VxBDsEOR8wNQS8nKLW00Kee2RGrhZYamqpQeBuxN/3reb1YqO8l2MruNOZA7KISpp6W3kPAty+zFcxLsDuMg== msg=HzA1BLycotbTQp57ZEauFlhqaqlB4G7E3/et5vVio7yXYyu405kDsohKmnpbeQ8C3L7MVzEuwO4yk7veG3jMMw== sig=GaA37AWqdkl6T/KGtgV9WdubWPatGsMjUayzPmUf22O6Pv97O1NV47nVr2uqWLZPzlXchuGB8NoA9GhDP2Mwh3C6/fnZ2SiZmLQ50l8keHV/hgf/RFOX/ElX/R0WyoygSV3xA+iwHF1ldTHBdAC7fgoA e=found last=22 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAlcEkhFKjOq8zRFrMI3eTJtMpKA8uxm8LHwL7zJEpZWYQiJPxqglWKLldXrMBBTxt8FkTPqOrEkqA priv=MEcCAQAwBQYDK2VxBDsEOWXoNjtzFsP0/CJtHRXNtVv8c+TaY+QdKOYhJbuoM63Rmfjj3FGdcAdMoN67b/jF4HDDvOckknPVGg== msg=Zeg2O3MWw/T8Im0dFc21W/xz5Npj5B0o5iElu6gzrdGZ+OPcUZ1wB0yg3rtv+MXgcMO85ySSc9UaDk+tN7Sbag== sig=KUxGU6Xx15YhnfAnCgYBdzvGDGSJYHaQnzuPWtkFIokVycHG+qSZMWdg+VObgAX30C3iqrDJQP2Aht0GREne7N1F/dQs7OHldw8qGoDFqLWP4pSeSM8bx9S7enSS3QJi52d80a36tGI+ep4iw9+QPx0A e=found last=21 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoANZNPGKCwN5u/T3Pq0Tull5B2yU8wRuBDIDGVf3DEGF+Qb3QqERrL9lE5rm015nV8g/p4iIqWJLMA priv=MEcCAQAwBQYDK2VxBDsEOfFm/iLFe+KoiKwkvBJ8aQEtPRIgEXh7Pe+c2vGmjtGGB26Y5v9/W2xqCeL/9LgzW6OlvRthK7ItDw== msg=8Wb+IsV74qiIrCS8EnxpAS09EiAReHs975za8aaO0YYHbpjm/39bbGoJ4v/0uDNbo6W9G2Ersi0Pc7VXPyq3Zg== sig=9SSlfNDRyI18+Sb3crdeOYsR9apjEdSmut5FDTrqPP7dlW2eLeUIZYb105X8MDu8GT1LEzbMNg6ATVVhs81W8TyCq9DNv8aHmp6Zv9FIlfN6JwW+qYmsv6kuqi3R7roxk8Fgba5KXZY0JR2YoCQDxAIA e=found last=24 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAQXFQlUOFqxVlaOsgwncS1OVqForlVgyWzlgP+5Uvd5qfgXGt0woFg/9Kf3TyJl1x+rYjg7JLf7CA priv=MEcCAQAwBQYDK2VxBDsEOY9w2rTUPV8mBbVD2vn401h5PJw2K7oAAr5rVt/BnWkF1PrfeyTqwo/NS/xAiJ045IFir7n0a5RNPg== msg=j3DatNQ9XyYFtUPa+fjTWHk8nDYrugACvmtW38GdaQXU+t97JOrCj81L/ECInTjkgWKvufRrlE0+TKLdTWMvLQ== sig=wfm8KJhab2tsw1r5pZnMoqmZ4F51cWeH7NRNpYzsCdIbBrfQZAu42wrvHhJjMY1QtDPdaqVqHNiADogy+rb8BZV350MAQ4bULln//xparA5BFLrTA0wULN/Z7VOltDkTlsqUodgOWFTpp3S0yCcm0SsA e=found last=21 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAOkYtakSJIw8sAICb20yjJcp9SGlWhQJYPVTu6oH2l9duqIy4SxL9OyXXsYtAVyjsLTe993nV6f4A priv=MEcCAQAwBQYDK2VxBDsEOeAFKoPxS4/UVif/Z5kCT63s6NNTboPN0jaFOat6vdnl7/VPLnjsf7Yc8d8YTXB2YaZxXn2K6vFasQ== msg=4AUqg/FLj9RWJ/9nmQJPrezo01Nug83SNoU5q3q92eXv9U8ueOx/thzx3xhNcHZhpnFefYrq8VqxDNrASsnchA== sig=XRUI7NoHCvGKfLYAMytpxJWCh9+GTGuHz32hKiiD0L7WYMvQjO9RMb0XBRglMSZAvR4PMDJgBxqA+BiQ6JB4eQepz7t3WUEXfSA04/6Cq+dl6V3pvy8fEyMSVVpbBFCXmpDzvfrqCe2wnriNpF+XLjYA e=found last=20 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA+LtQ02o5JTn2g9UPDgBfMhNEAChLqAJSwqH7A0WFvCDgYgLNgGM01TPIep9umwcbYGs/EpVIdp4A priv=MEcCAQAwBQYDK2VxBDsEOeq4at9LqUFKmjwOUaz3AgBwbofRq/rWeLupnvrIQ6QD4ci9a1/q6FlubsHwVJAkCek4azuK59sVGw== msg=6rhq30upQUqaPA5RrPcCAHBuh9Gr+tZ4u6me+shDpAPhyL1rX+roWW5uwfBUkCQJ6ThrO4rn2xUbOWabkZTwbA== sig=4g6ag+eL+0Gl8tKCBD64FHShofg4pbt/Ajk59yvp+FItjw9wGD7XebrHyx6PCEsxtnZ0Q0lYFKSANFfvbKH6O8M9rmd4UoehVSB7OfAejPVV952Hp2q4xRf219EQlI6HXqPgsGF2VKSmEmdmWn70mRgA e=found last=21 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAwMg2tQF1CdacKfzVUWCRzjO4J0mDeh1FXXzHtCBfg1x05kEb9NdDVHCuUGTCpBU8a61oo0AcP/IA priv=MEcCAQAwBQYDK2VxBDsEOWf+QjxG5wplkbkUHW26mkHXk/Pw7zpeNzIGiosbyKYJ7vDsbY37kvAvrDWitexOV+jitkDL0cMO8g== msg=Z/5CPEbnCmWRuRQdbbqaQdeT8/DvOl43MgaKixvIpgnu8OxtjfuS8C+sNaK17E5X6OK2QMvRww7y74E2xSueAA== sig=M6dL4OCFZarEdECPy3BN+ZZtyLVNiwHVY0QyPmy6ftau2J80Pv9nkaQ+EAXYRwpkC7bHbjxviUMAR2atYyJ5WRbIY0/7RhnHB85cFtq+i1ozZfGybV++NLaG16eKRNrOHSCZvf18cCjYv2NFK96yQzcA e=found last=20 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAr7lmcD7a1ry0iaKyuhG+Jflv+5gHuRVR8xsuJnS7rb/isqpsu6DwO3i+wV879oQe1R6/spx7yXWA priv=MEcCAQAwBQYDK2VxBDsEORdSVKo8hB+JTo+pQuzyg4Stv5jw7789SKQ6oUCJWTgwnG99BNtCFx54L1rgS7BI+oPeHuIHq4GPSg== msg=F1JUqjyEH4lOj6lC7PKDhK2/mPDvvz1IpDqhQIlZODCcb30E20IXHngvWuBLsEj6g94e4gergY9KVvBLfkWDow== sig=6uN9VzTj7WiNVq6JH7C4hgLepkkYjqOY5UHwEb8H8lQ6pJ9t7K2qb54Zn8XNMpIOyu94N+WQaUcAWorX3hLosKkmEIJgT3AP2k0crddeT6/q8zoqU/+ftAaG3YoXMZ+/uDTeVOnlxBggLrI6tmiwWQ4A e=found last=20 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAriuEEX+b9AfLM613eZ+hOt06Lrts/zOy0QnjeT9An1cOyEHWPWnR1IGO7F1uNtUrCWXN6V+5al0A priv=MEcCAQAwBQYDK2VxBDsEObBaHYdbFk/3+D4WSzyHm07NCie54UqPbiFpGAlep3aKNfanp/tu7zx/WhAUro+zPm2QTSlbAZbSnw== msg=sFodh1sWT/f4PhZLPIebTs0KJ7nhSo9uIWkYCV6ndoo19qen+27vPH9aEBSuj7M+bZBNKVsBltKf0zY2cbm/tw== sig=vp1IZy8b4zujsjIQcp65hidZHXFl1Yr/B6VbvmqfqLMXMbbrO9zLYNfWG7GyBJ6cAAnrWniV1GyA8bl9YqXP30MPXxoByyfxN8tva9ZRuExdOUdCGSO5UZOhCVQF1ncKFRriLOXuXUfiK84THknnxyYA e=found last=21 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAIe9dlQt3uUuSjKNSQdiH4KJOk91oTFFGriPiCq/EWiwO7EjJVmHUz1CzU3mK7JV+07zl5SlcCc4A priv=MEcCAQAwBQYDK2VxBDsEOTxclqMplrQRja9Ehev0ijavNVAmhnV8qkrivkB5CRldP35lOMJ72sf2+Zfm8X0ORikWOoqPYK3Fgw== msg=PFyWoymWtBGNr0SF6/SKNq81UCaGdXyqSuK+QHkJGV0/fmU4wnvax/b5l+bxfQ5GKRY6io9grcWDeJjM3tuvtg== sig=f4Aq71/zWpj9dpWAg/lh5xRm1JCNY6XH8w0yjGRWcYcW0WkalCY6KVxIapYPQfNyt4OEvUxTp58Aylvr/EPiToWtvH93qCOrrh8yaMJ/g/QP3Q9SzB3S4gvtQNAdkf/xtLLb8xpnvtaxJJvVw9PrKwoA e=found last=22 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWkExplp1iwQKL3e4jiidF5rUsPESS+fcmddpGL+4uZ+BRBGN/PAVR8Mf4wgvlnHA0zx2HebkpTYA priv=MEcCAQAwBQYDK2VxBDsEOdzE6tjfQws7/oU6iJkOTHQzzPaahNV57E3NPyeELaFXFweSB+TBfGooXuezIKrnTBS6uLTJIQlqmg== msg=3MTq2N9DCzv+hTqImQ5MdDPM9pqE1XnsTc0/J4QtoVcXB5IH5MF8aihe57MgqudMFLq4tMkhCWqaWkSQQG/HxA== sig=Tt2cNrNGdI9r8adPqpsaAUV3qRASq9iz/tss2crHoNPdlWuuKyalG6NiZoauHR+7lYKkmgsbAXUA45O5baYs/58PQx5jPipFb4x3Vh4DYsBiZ8GAsCMPVUC4QSAOh4EOL/h0xdaFt+PO8uDbZe8K9hwA e=found last=20 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAOJA+a2im1iK0Bhl1nfgXMX8atUyPITyXMhcDxmo+h1iLLvfajjZWGESOBkq2QHD1fF468/SQ73kA priv=MEcCAQAwBQYDK2VxBDsEOcSbk98XJslUW3FD69Qr7rYb6Yr9hvLr3dOVff1cQTqdzF/ezM4uqyiI6YfVCAbTcc40HpN/WFp/Uw== msg=xJuT3xcmyVRbcUPr1Cvuthvpiv2G8uvd05V9/VxBOp3MX97Mzi6rKIjph9UIBtNxzjQek39YWn9T+2VDXtmO6A== sig=iwUCGLklcWnet7T4TkegFtsXH5UDg8Y1twkC6d3RVTas1Y2KTyQC9H2TtSJcpm+r7Tjz6K/VrA+Ad+NwGXvTAJ8dqn9M7OwJ2mTe5UkGUrEwG1cpa5p2Qx7Hxz8S0jsYo89kTtHHuEG0OdYZj7iUmAQA e=found last=20 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA264jtZg/SLil+f3cWjw+7F49vfYsTKJ3T/ccZyw5fiHVY2FvZMJ1BdLUYcpOKdfd46SVbNcPSSEA priv=MEcCAQAwBQYDK2VxBDsEObCkAdl9ZVFdRIvtnaBQY2G22CmXnQ0XTmPuJPykfcXtZPww68odAycBqxFuI8uOk1TiQ+CITM4mcA== msg=sKQB2X1lUV1Ei+2doFBjYbbYKZedDRdOY+4k/KR9xe1k/DDryh0DJwGrEW4jy46TVOJD4IhMziZwcOS6yV5Vxw== sig=i+IKlEdkxiS56zcT2FfLD3QuFzQmlEija+scrtS8n4pRZr1UpkLMi/TMyiqPBll62mM/qJz2PUwADRL3TqsOzLmDN4/ieWcveuQG2zb4tvtkoewIyIpAoHheC5bolAcdr1akGweUWyvf1NT3/sfxwzEA e=found last=20 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAvXUbNYR/6BkI4jsESONW+3w8qRd+DCp8a5KI2zsmw1yy7mgEOACTCOwQ54BG40tjzc1IXkTJLKGA priv=MEcCAQAwBQYDK2VxBDsEOQgxAJF7gl8ot/4yzniq7lJdBk4Jv5GWjc2nYfvM5dd54LhZHJayz691wNGHicBKMxE2chZC0gZnuw== msg=CDEAkXuCXyi3/jLOeKruUl0GTgm/kZaNzadh+8zl13nguFkclrLPr3XA0YeJwEozETZyFkLSBme7dVfvBCd6KQ== sig=N6Fz5aijQTyyk78LtytlL2SaUH9NR5H9XwDt/lYkjHO8mzDJ+zWrRj4+HUBfjPvmYX6/dGpxaqqA22LIOUN461HFrrI/Gymi+gbRgeSOxFBv5XVutczkpkMtVxtRchuVq/9aZG+n4khoGyi1H8Ts6S0A e=found last=21 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA3WuOi10sWJgsAxR7B0GhotKYcVT2HoMsLZwz71lRvOvrzgmOvGmXDvfcgzXTEURPNyiH+1I9LncA priv=MEcCAQAwBQYDK2VxBDsEOf9wKoo/teR2GPD21wHwRRyD/OzzY9tdRH972Rbpyhol8SXkxBP8uc5R1R+twU/XatlauY3frU5NHQ== msg=/3Aqij+15HYY8PbXAfBFHIP87PNj211Ef3vZFunKGiXxJeTEE/y5zlHVH63BT9dq2Vq5jd+tTk0dbxCtSFAzmA== sig=oCi9PF6FTbMp9IkF76bSbPBnSCqbUMJGwatQGRgYBoxjkZYd9Xg9IKs+9NiMXdWRcQ8iIafDzJkAspBYqLiuezJD8chT98Hh5jGz7ahzWcfpoHEvNHwSpba3rCBnn9cJC1Zm2/QUn0j7w4wtvomXzzQA e=found last=20 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAk6H0bCrEvMQ4nYy7S2nLnTno9jfjYHQg2/ubCp8mzLy1vJlrHw0tstVSyMEBzDTlnAQCgQ9UsvEA priv=MEcCAQAwBQYDK2VxBDsEORIP3/h2iKMb+4yxu3IUwCHwqsjH0qS0jmgqieulbqMFgDTuOLTstMMPX7gEZAS4yf8LgCvBMWtmXA== msg=Eg/f+HaIoxv7jLG7chTAIfCqyMfSpLSOaCqJ66VuowWANO44tOy0ww9fuARkBLjJ/wuAK8Exa2ZcQ/KK9/oJJg== sig=3qcHgW+y3cPPJQsT8wSLl8LuJ+wYKwjukqtjcuqPyYJzZClCz3EpyERYT5UtSksA4PRevWDGyimAiZohmff+CRuMzQPdr8UZ6TCuFRkx+k/thM+Ga3hfvXrBziBBHdr0n/4Bkz5TK+PC9SzdLlXLFiUA e=found last=20 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAuIWJsaJ1/7emBnUOZllRBGLMgo0rmJf3HSe9kgF9gF50wEJy7KFW8gUj4scC9aYp1nR/w4aXBRGA priv=MEcCAQAwBQYDK2VxBDsEORVr9oBbZWNrvQ3jGRf12Q1ZKMU0f2TCOWjaWKn+1M5/z0dRu8Qgv17c/B7/iJdkvUkSohUujZhq4g== msg=FWv2gFtlY2u9DeMZF/XZDVkoxTR/ZMI5aNpYqf7Uzn/PR1G7xCC/Xtz8Hv+Il2S9SRKiFS6NmGriN3GwFGbzEw== sig=RFWNbJsUIFqMPGD1/q9ChliudKZDamjPdapfnp7vA/aGP+Q4TYH1C+FJwGlX6OWUcdKyngqXK4yA0E2KiDJxu/EdfaHOuwCXN02H2A+nBybeqvKEUy28PVJBCjUC1BpYdcexHYUbXYDpphLi0UyRNwYA e=found last=22 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAN8SfT6hD4EvmFRxb7C0gE7F60twMb9dcNFbgcdMzSmW7EkFHTC36585Rl0zVNOD2SbsyZouCBW2A priv=MEcCAQAwBQYDK2VxBDsEOQV4yQDw/8pwjW6aPCuqcAEZyGSMljpIZCAENRilP71OWvODvW9s0JOI6NCU4byTymT7nPi4HbauMw== msg=BXjJAPD/ynCNbpo8K6pwARnIZIyWOkhkIAQ1GKU/vU5a84O9b2zQk4jo0JThvJPKZPuc+Lgdtq4zWFv+66ezLw== sig=v+MunUnDJbS1S6uPD2OKiXmJl6zGFi0kJdgLqjbqiNIxVt22R1gNpnVPCrgzB9tIVhqqbnuqRYgA/oh/LK+L69vkRCyszyo2rIqshWSUPaVlAax/Hq6gj27Wk/U175gtaIb6gGcUMvWyAzQAR6SfRQYA e=found last=25 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAgLr16p1dyMOXTZvnF5Q7SY4ne/lv/UUEXoAVNvCZdO6JebgGszTwhBYyLY8ZjedNsLseBCLxEHYA priv=MEcCAQAwBQYDK2VxBDsEOZvyuMZJo2BRltzOQ7z71Dxm2w8+1NUyHw3paekZmRErixc3VkO5r21F40G641FvkAI2z3h8oGN3bg== msg=m/K4xkmjYFGW3M5DvPvUPGbbDz7U1TIfDelp6RmZESuLFzdWQ7mvbUXjQbrjUW+QAjbPeHygY3dudGYJ6tXigw== sig=zltFfApek3jsx4dK8vM4FIRmIYB/J67bUtzSqbPVd6sdya+CFBa9EkA+1B3o4XI8qxHSuaiSkNyAoTFNfOKl670sIvN2DOx/r63DcnlWagtBiDoQ3GZZ4R6DgvKeuUfpS1cgQfaFh4Y4O5wUkZRUlT0A e=found last=24 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAiCMn3mYNZ7EWUCOmlx9KQWFQTcWQFCMFQX6GP2TkClVoGDcftMph68Jik+2/EiXvwxM0pHdwDeGA priv=MEcCAQAwBQYDK2VxBDsEOaciSxz4sHdb3SVbXEDOiAYyKRbUep9H5BQwJVhA3/cDycLucziLhz6xrXENJ1sW5JIrm5TKnEXJYQ== msg=pyJLHPiwd1vdJVtcQM6IBjIpFtR6n0fkFDAlWEDf9wPJwu5zOIuHPrGtcQ0nWxbkkiublMqcRclh6fl/mO18NQ== sig=AwCgpdlayS5Itb+RZI4CNMO6jhfzwJ85ULEyfpEhMPmcoY/a/A3YT1qfOQ1P4rvZbFvHX9u+L60Adxc+9wcnu9aaw8fWqHgAlrlmu0zCJ/8vkm+rRufRPvBk6kQuZ4t4CQ8o8/din8+Z2CzGQY2whRIA e=found last=20 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAZJM6zRTXdrdkSv3ti5s7l64yyXQsxx/JzXmt0wJKb4713u4Lm2HANAqdIXoigaesd8wXcU5tSYmA priv=MEcCAQAwBQYDK2VxBDsEOdvoZ2cQcgrHNkIy3J9A3Pp8GkYm/aML0rRNryvgp827FDyyqvCxtmlsAaAyODPPxJubaFUw5CJ89w== msg=2+hnZxByCsc2QjLcn0Dc+nwaRib9owvStE2vK+CnzbsUPLKq8LG2aWwBoDI4M8/Em5toVTDkInz3tZZ2L7gHsg== sig=pEjt6RR5uKwOQSamJ+ERRSWqFObCL3j8cnmnUrgVy5GUFzCl4D4rNFtcmlDregBCQbwyKIcHOtoAEM6ajoeJzZDEm5tg8MiNO5TKmdjMGQHG/ezsqVd8q4LY7e5x7T4/I21ijDvUjWyoXC7QJ/8ukxMA e=found last=24 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAh/LZX5EFQYglkzVFUGoQbum2T4C4iovpuC3wLzp+HoP5xGNdARwnDYzD9Mg5UC5/UHtB7GJADOUA priv=MEcCAQAwBQYDK2VxBDsEOZ1QY5UEXi9et70/ar1QNVpT4IkfRCTpxJ3GVj9+1YZVJzmMP0hWHrWFCy48PxfwVHAm+QqjnAx/iw== msg=nVBjlQReL163vT9qvVA1WlPgiR9EJOnEncZWP37VhlUnOYw/SFYetYULLjw/F/BUcCb5CqOcDH+LtACoY9HgNw== sig=G02BZ5LA2+vaN3sOwvFNYB6gy8jaLsqQKYVjzi3dfmmM+8AhcASF2q7kO42rhhCxJUd8n3b9x7IAHbDTpukq/jwjjIdqRb27Otox8BJCjVFzzxMqLCPoOpVjoGOZ5JxazLRAZB9w/zOf7LX1RowsfQcA e=found last=20 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAUb2ZIWDkoxDyNGTXQ4I4JprAb1bo40uswgPARhdBsw6WJh49WsL7zKtgEj455z6Gl5q5/MQrwWkA priv=MEcCAQAwBQYDK2VxBDsEOQUsQ5NQ3O2+oOYTs4XH7grZGpjV1PU7CnP0XXjmxe70YhDxltlYykxMGYDy3qiNjZWt1Sh6gHER7w== msg=BSxDk1Dc7b6g5hOzhcfuCtkamNXU9TsKc/RdeObF7vRiEPGW2VjKTEwZgPLeqI2Nla3VKHqAcRHvLuXsAZsNTg== sig=9A6GS+ueFnYlX6QzX81mrDZRpAqar4wAdILN1IPpTUSVqc5HiXAYGE35ZqaMnKnPka9F6K1IFWoAWrvSmEVzUWo7aMKwRmt5NTkRlbt+GfgQ38iW6rvnIyNIG+sBvNxO8XujAZbJqD03PJsNVi8KHRgA e=found last=21 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoADnOe576GsMo64I/WM04xTIsU8g19CZXRkqkZET6GhKhZE0PQ16backkhCoKLIdqtXkU9zg/LBY6A priv=MEcCAQAwBQYDK2VxBDsEOXMmPZm6TJdGmug57pikL/tpnmCzBlngXxdzaw7r8cVrVT/cVuVddqehiidCupw4uZujh9/r0l4D/Q== msg=cyY9mbpMl0aa6DnumKQv+2meYLMGWeBfF3NrDuvxxWtVP9xW5V12p6GKJ0K6nDi5m6OH3+vSXgP9pVI7FtZFOQ== sig=u0h3RluieIrIqGgkCfTdxeHaLWrZa8kqI3Ti0IeUtboypZJ7JfZ7DuVjkY8rtSTHfdcywFgjl3IAn6OQnh51wDniEIYk6Az61/xlBUtaCdVYZD8S5vY3sRF7OOwZaBhxdIlLWPU/RUEeytHg5PgC2jUA e=found last=25 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA+jc+4+asKW2XZizUS/DkbOeOS8PhkCgwH20CueZOcfD9quFD84kDaLoo6OZpP+/46wuvAt+JSVQA priv=MEcCAQAwBQYDK2VxBDsEOVdHW3ENL7fR7RDhA10AFFQQaSL/bADRDsRoet4+rpY6BR1/PyfObFa1AdSWcBQhmapnfC1RiUY0WQ== msg=V0dbcQ0vt9HtEOEDXQAUVBBpIv9sANEOxGh63j6uljoFHX8/J85sVrUB1JZwFCGZqmd8LVGJRjRZfWCKsNsB5g== sig=F+jkC1bulf7GPpJ4WSs4VsD5pEPADzrNaOzP1VEpYGfVT20X15uq39Wp69DQ65hTxD2sbHI7HBMAfhuSi5B2x4KdGqBfbcQABHw26Xl6n+2uvvnapOkOKp/dJaqJlpaaJpYdAXK8xcWGyA9az9EwrTwA e=found last=21 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAPBTpBmig4YcA+Q973hmwUZHuOi5DVZf3H1nsymrKjVqa3QyNLMDYuy2Tar3HuWoC9j3YI2BPGu6A priv=MEcCAQAwBQYDK2VxBDsEOZ7ja/E4RJPRo2gcTpzNcM45pbluJdwYvkZ7FwXH3GV2JZSfMOXrFMHjxBoGF2cwe6P3dBDpENWoGA== msg=nuNr8ThEk9GjaBxOnM1wzjmluW4l3Bi+RnsXBcfcZXYllJ8w5esUwePEGgYXZzB7o/d0EOkQ1agYL1aZEWLD4w== sig=xHK3nb00WflhpB58ksFh68GW+27tDy1qbWUgfu9VOrcbfjOu/bcNoKE3Xzunze14ONHptlaPFzAAxSJULoDEsijG9cOXJdpUpX8R5Z1z1IQdxuHq4pzHM/0msXOu4Ks0G6+i/SGjoCAjuwxcekN/NhcA e=found last=26 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA1iTMfku+wnpzmb+9I0yriUcKpJqejjz6gPjV5dCsIRGTGG/lcKE8M8beknKNddt5z+a4ymUD6qsA priv=MEcCAQAwBQYDK2VxBDsEOatqQXKZo48BjqGrXnsXBEGhgxCURwdG5LmjWYdrDlUmjJ7id2+H2WuCUbnJfstkXBHmzihZfLHI3g== msg=q2pBcpmjjwGOoateexcEQaGDEJRHB0bkuaNZh2sOVSaMnuJ3b4fZa4JRucl+y2RcEebOKFl8scjeJuoFRxqdKg== sig=hUkB2Rm9uFDI4tW3fkGIn77Je8q3R7mziH+2zwLGRQM56MTZObAhYCADzovXJL4uTg2MgDZOl5+ADQcnd3sJ12W7TO88mPxwOKxA/DfiBdct8/e32SgYDt5BBTWmPW3Qc6fa4ma86lQsX8qYEMHFdAoA e=found last=22 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAbfxLYH6rv8IfjvEh6U4IePUtBqKgz4PoIqD07jpJYnrnZgXhFQejU9hHXT2y7oDkJFlLZwir/3YA priv=MEcCAQAwBQYDK2VxBDsEOVOIr5yY/Cl6hhoUh8J7q8Dst23+ugK5e28eux9OdiIw0xXRlYi54xCNbb0qe2/43O0/fmLq4gNP1A== msg=U4ivnJj8KXqGGhSHwnurwOy3bf66Arl7bx67H052IjDTFdGViLnjEI1tvSp7b/jc7T9+YuriA0/Uj93uyYOBOQ== sig=3+nuf8dhc9ksDkjOaX0LZULTK7oSwspWGZ4MGShOWGiUrGqAnKJuNy2JtBq6ygkk87cHD9hqnZGAzovv4odIgt8Jmewf7h6Wvs+8H4TmnurHBu2Bz7TYX1Jj08BNnHKJ2gVQv9ob7vQeu0Np48GKNBAA e=found last=25 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA9PJ9h73qrbR1lC/MoI5Vt1hsjrN42ffI9jmzld2JmCR2hdZ9R+tmeJ1iYgbDQMURWq6kAS9UF0mA priv=MEcCAQAwBQYDK2VxBDsEOd3r2UphtZBd0qEvt6vRWwEp38tsDzOBtx/EumnumJXtcgAqK1laQv85jmuyx7/nZmM1KlFd3yctvA== msg=3evZSmG1kF3SoS+3q9FbASnfy2wPM4G3H8S6ae6Yle1yACorWVpC/zmOa7LHv+dmYzUqUV3fJy281S3w8FS9Hw== sig=iHA6/8sosbr7Mec7QHF5vn5MIyk38g2KHi7u7lIw7aME85thd4hpwi7lfuEtgA21Au8v3sQotn+Aw/HZo0I90CDNpJl5kvpE0hprVMJqj132dSnBV/E+zJopS5NIfx1PvKQSu2DrsxJ80UmIIz2p7xEA e=found last=20 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAIZDMxzWE6/GhZGIftnY9uuQXMzlmD9IAdC7IJegpQJWw+9i93/pLDAwo0EQ2RjlC93aHxA+WnbSA priv=MEcCAQAwBQYDK2VxBDsEOa9VAlzmFZghy5kQF7wnFhjWdEeqdNKGWqiKY7tAfRSE7bLXFxDQ1dYRtlK8hkG4nzDUDX16rpNw4Q== msg=r1UCXOYVmCHLmRAXvCcWGNZ0R6p00oZaqIpju0B9FITtstcXENDV1hG2UryGQbifMNQNfXquk3DhCJFofqJg/A== sig=vtWGIvDknbtHgAhOaTu9f7jbGXjmfUrVCQvzZlvQokteuD3wTNf0TNtaAU+EcO1MDw8diEJ+bACACxVYMJgxZee4zE9rmA/nQ7n8PoqRCMHvWn3HLqscZFdcNSyJkRJ5gYE0nGI+DGxe7stW9RmJxxMA e=found last=20 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoARZVAHaw60EdVVBqqcc2g6Q+YwVyHFKKvnVvERSyu4Z14H92dI8H3nAdBI0R/0Mmr8uTqxjik4EAA priv=MEcCAQAwBQYDK2VxBDsEObmJc+Pj1murdmsO39Au+F/lmWbovDPak0adzw5Cpcd3Wz4AWLfsNtBT0laIdvOPZGxlD306Dsu1DA== msg=uYlz4+PWa6t2aw7f0C74X+WZZui8M9qTRp3PDkKlx3dbPgBYt+w20FPSVoh2849kbGUPfToOy7UMOGinL/4RQg== sig=rRRQMyivIoZ3XCK2wUrww49vVm8OoYUfaovzVO80ynAel43Sr/Tp1ODKPicku+Z4mcKVlnMvUn6ANeLEYWJl6C0Ogn6CwfAKZp9CtSKfbKYCINfta0Tucb7NaAyjx8VSbTXW35Hx/LDxuMK6YRxyyTUA e=found last=20 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAE32XaykN4j5sYY2ptmLVUkXIdqj5qTQvPS36AYoXpx/5GzpnbLlCwBGYXyLN56mCALmeO/X0MngA priv=MEcCAQAwBQYDK2VxBDsEOfMeHZfUM3bax+F69/n8i1+/Ueo0DLDgbFZjSylY6cBbtcb3dPMBkBKLODTVpnN031Yrc0i7bPiGkQ== msg=8x4dl9QzdtrH4Xr3+fyLX79R6jQMsOBsVmNLKVjpwFu1xvd08wGQEos4NNWmc3TfVitzSLts+IaRmlw2elWjlQ== sig=Hcznej5Tw02Z4ur5EFd/LTAe0QIsvH52GQJ8j05PzCHz3pRGjJPHIGzoP5X7stI5l44vd+rUm/uAaLymfp2aN80+gsErTyPnVRxjbamMP64Q3GArpdJzlRNcM4xOYo/KqNRwcDm6xByYmhjVtpNLVSkA e=found last=19 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA2Xo4oeCsR5/1w0sBFfa+8Qy/gOkETl4hhz6eADFx5qnPVjwMDV+mxJxSjgM8WJqjeIMOOF7/w4kA priv=MEcCAQAwBQYDK2VxBDsEOftMIbz6BwZ3hfm8aUh9Ber6OiMj7MpgisrJYQsmTdsmCNywrwlzVJliZPiGa2Tdeo/Rok+OFviWHA== msg=+0whvPoHBneF+bxpSH0F6vo6IyPsymCKyslhCyZN2yYI3LCvCXNUmWJk+IZrZN16j9GiT44W+JYcRPLE5U/0YA== sig=aAcZ8k6kJ+WTgyCVxpxIiS+cuz8SapN0YehS0oQU53btSkEFRbemxUYSWKjH73B2F+j9+HTjpG4AVUu8RseoMhumHF3Mg+HO44lZE19ZH8X8NKAw1hY2X5PWXHDZRTSfBiUGzHIaOD21WP5Mh57nuQsA e=found last=23 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAqHuV7va6e3z64TR5d3YvjwYKTaO9w8AUp9LrKVfWCHHe9+EiOHIbiWfkY3kMmbBkkGj7+KMqBkEA priv=MEcCAQAwBQYDK2VxBDsEOWaKKVUDN8gw9JfQ139IZgmwPqTsBW+lhW3JLnVgJIjl9InG5roDony2YvJJwWP/2/hwO2D+OHy75g== msg=ZoopVQM3yDD0l9DXf0hmCbA+pOwFb6WFbckudWAkiOX0icbmugOifLZi8knBY//b+HA7YP44fLvmq9/6ipzuBA== sig=73mM8VemmbpTVyZ/kGirl5reNiO/JNii6dWfHxSUe/Mq9U2J/UWCApy4C07vDG6hfulb7R+8vquAamUtGrBrj5xH+F4Rsp0F4y+JhKL7Ks+9veQ7obEAjQwAYEdOrckmFgdqVY7iGGlYg+TOpT4UgwMA e=found last=22 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAOZZ2lQmPK+LnaQrCH8lKRBWhBoXPmiTDQgd7jBAiAV/YHgB/A7ZfF52ZIjUK2mBmUNToqkJ6I98A priv=MEcCAQAwBQYDK2VxBDsEOTjeWYJBP9zRlVA2kRCHdpVO+B+UY3EMq4KWEzMgKDwdh7V6s6MuEpi0DdWJIEJC0NngxJHqrnOEqQ== msg=ON5ZgkE/3NGVUDaREId2lU74H5RjcQyrgpYTMyAoPB2HtXqzoy4SmLQN1YkgQkLQ2eDEkequc4SpMrAcsqflIA== sig=JzCN2DEQg+KJmbEwqv5u80+y753rU8aUvRoylNnrvm/fbsbes9bwGcjocKdmd1ZSU6ZaoLx2W4IAbaU2XgkAL+/2EY5ECuSaiP56kk6z0Oy2rugf18O0D7Cpx+xAVFjI3+ozeNfojVpfDaKMzBGKoREA e=found last=19 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAjrG4tN4CSbvvGRl/58yxffsgxTnWj9sOdr6ZYU80PT7BoC+FjhKSgpljMlJG56obqNrOZlQdZDQA priv=MEcCAQAwBQYDK2VxBDsEOfn+T2Igw8dvmtF0u6R9a4943WtSGvQfp87+nU0QLkqAvdYohB/M257FfksP5w2av928fpGZj6LBpQ== msg=+f5PYiDDx2+a0XS7pH1rj3jda1Ia9B+nzv6dTRAuSoC91iiEH8zbnsV+Sw/nDZq/3bx+kZmPosGlpfeO+YdOqw== sig=T7MXsk6RwvEY36Z40GU6i3yO9/0lHGFd5YK9vmBgU5bcVWTQToGGRBFXnnA6PRRMWsq9MXKXEB8A6HG12Hwy9VeONZdaNyzl45bjR+o56zxrUoqnWSds2sQGqI+Sh67HASyw6EXaSa6hnTQJCTDvriAA e=found last=20 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAkfBsZhPW8SHYBbClynq6Vth679gzK+juIcKKrJzXyj/uvfDv7TQQyFCQBqcwIk8uvJ4DTc1ElacA priv=MEcCAQAwBQYDK2VxBDsEOdpQPYAad3bEt67L1tUfpnqCgRwNmOMwMfpyYi/SzLpT3qE8keZuvk/9GN9CWVOdal9XPJC/urYCzg== msg=2lA9gBp3dsS3rsvW1R+meoKBHA2Y4zAx+nJiL9LMulPeoTyR5m6+T/0Y30JZU51qX1c8kL+6tgLOHfbRdp0sEg== sig=aTzHp0FdBhoXNV8UUFqBzaufyHcpDgXbR6bGV1Ywl1oRCo0oDF/UVhFBqbsLUGBcoK+8+uMtd9UA60WMJfiDrJykRB5x6kNpfmzue1Dp40eyZM/XEV++o7nLo+wG4rP9//0emQ7WaZ6Zo6jeYEg5yhcA e=found last=19 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA1EFwgKG0zNorG+bZE4mpTqFsYc299zA8S9FKESoXFMaiE0H1TXza5LRr6VfbhZbD1oUjg9k/hvaA priv=MEcCAQAwBQYDK2VxBDsEOXo0Xnwx8MXUKuxdcNCliAsC214DbaNMsgle6VpR6MM4pG62otKflKwp8r979eXNzTQ2BoPxipNjrw== msg=ejRefDHwxdQq7F1w0KWICwLbXgNto0yyCV7pWlHowzikbrai0p+UrCnyv3v15c3NNDYGg/GKk2OvZiu9Po8jjg== sig=0vRx8acft+oSnoIcGDxV8DNcTlY0VwHzjCGbreGZAzX1Tnz8LPvqn8/144n01a91mqPqdkOMBZYANGIWMe6EVVxhHwReAuBkXyXN4G8TV6NqWiRBAk7IzMXgJ5dZtiiIOq98cUIIarI83fBfWCWxzQUA e=found last=20 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAgZxD+g+BVA9zW/rlG10DB3z66N+LOy93hzZ9eEmULXR7kZ/3zETPZ2U3f1jDil+kFGcW7GpNuMUA priv=MEcCAQAwBQYDK2VxBDsEOcasyC5lI5F1AvLcYv+N2GBkO3mlGA1SRrrcDq3QLlHzkpwrenAzotecPi6fmy5sMauRLisNKt0kbQ== msg=xqzILmUjkXUC8txi/43YYGQ7eaUYDVJGutwOrdAuUfOSnCt6cDOi15w+Lp+bLmwxq5EuKw0q3SRtqUb2r11eVw== sig=tubU0Cbc34/RExNjlBG5mL/2vK4lziuG68KuDweutC3tWDEUNz0rihovpJlzz1gNY/hcMn5NQmsAcnzMUiZEQfRUiInJbCI9duTNVvQDjy+5gAf0u2v1pePpvqTAb7Z13FFvJV/7jy+nKFb6OVuBlCYA e=found last=19 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAnN6Cn84g1I4FVkEx1/O0f3M6Wyqlv3bGGtS5omK2NcA6KN9NSu+nHHZxlV8/eeV4W4KzNggStjoA priv=MEcCAQAwBQYDK2VxBDsEOSDmLy1yuoOyHBi9yvbso5GhyiAR+JN4wr+r0A/6ViyJW0w/32ZGxmHPkQzieAxbdnCDkYJcpP7USg== msg=IOYvLXK6g7IcGL3K9uyjkaHKIBH4k3jCv6vQD/pWLIlbTD/fZkbGYc+RDOJ4DFt2cIORglyk/tRKpNDrecefKQ== sig=8h7+pMitaO2NzauHDo82VK88vlxFEVuu9s9P4u/K3EfaVf5h5/d0Jr1TrG21uldNxhEUMoc9LeeATi80cDvK9YqDqlFXJncS7QaD8vsreaz1Z9OC5D8EO2t87KRERdkYJzhYpA8wDdEEremb1cKVMwMA e=found last=23 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAGHqDG2/mVmi4Nw3Lo99cGxHKdUaI1ww8rcIi4ni5YwAYTRMGGQCvVHz4tjXpF92NPsHFVxYZmkeA priv=MEcCAQAwBQYDK2VxBDsEOQAZv9xKBWtq1f3oPDroU85qcAlgFk8qFTXElWUc2Oyter4GMXSZyn9xFxp6SXrgT8RJ+QEPa6zD8w== msg=ABm/3EoFa2rV/eg8OuhTzmpwCWAWTyoVNcSVZRzY7K16vgYxdJnKf3EXGnpJeuBPxEn5AQ9rrMPzLQVaBoDpVg== sig=0mjqOhYaxrUOWwecZ3dmd5dkXShMWwvnv6Rs5qVcpom1e8A0LC9ecIHcQyrm+K4lpNItm+FPD6wAUiOpBExJ1eHYyUJ1kcJsB7z9V679jPHJekOSv43L5uHAKL2g+sBCVeqVyf7a2POlLYwEddvSKjwA e=found last=21 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoACdazrEvZM/xoiXdwVG7QmE7VD3Ykn4Lp6m2aJhrgCLSHaG/fy2wC4m/4rsSZo4SsOwqtP2/XRi8A priv=MEcCAQAwBQYDK2VxBDsEOW84iU3k3hJUhQpP3QshemonFBbxzOQ9PGelVmkZPkC+KRofKY9EQoB0AE8nqsEczEtdOq5+xcvEmA== msg=bziJTeTeElSFCk/dCyF6aicUFvHM5D08Z6VWaRk+QL4pGh8pj0RCgHQATyeqwRzMS106rn7Fy8SYjJ8NidtRBQ== sig=wO7+yX3fVqyg97rTXuk2IN1Ni6w93BKB1GGbLudXdRbP3wfMArJ75jqc1eea6/1U4YwNE3cTMkYAZYfX6AwjvPrOSRUo1+GGBaY5j/a4OqO6TRQ0rpLclnp1yFJoCIHn9Iw+x3qvcxslGOSyQDnbwzAA e=found last=27 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoADvABfkxzXlQRtnh/2o+Dq4Dsz8TaMafcgv6O/1JnauTWw68+kQ1iJCZJ5Uw/XLrTQvnEKn/kFNOA priv=MEcCAQAwBQYDK2VxBDsEORQKoc7dfqaXVC4CSrx6VAOj26vQIHat0wW5T5uhUHsGO8n1DHJu/Z5pb18XdYpnEat5gF3h5uiHuA== msg=FAqhzt1+ppdULgJKvHpUA6Pbq9Agdq3TBblPm6FQewY7yfUMcm79nmlvXxd1imcRq3mAXeHm6Ie4ELsVxF2V4g== sig=awKRNikB6wxU3hFm7HN3GaSmAhVpSWfvCnoQK/cvy/5OHiCv3izCPTPCiXvP3jieZHy9OjWPvh8AiEp+Vugq5hZHnxYDVoCN+OEQMks3BvAGSPtRe/5Pg2QaqhPy17M0rs4/NPiNKvRug+qet/b7YCAA e=found last=20 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAIksuNKlOavKqrP8+d4Ayc0lvvfH2UIRag+SFoBJDF0r4tzBMddKLHIEMenI2wpYVdJgGWkh5YDYA priv=MEcCAQAwBQYDK2VxBDsEOUnDGPnKOFcwzsKRAHMztRULdwb4NfyyR1bHp0q2x0dz6OmzfJJbaAwbhYVETl8nqj6dVtcZiF8W5g== msg=ScMY+co4VzDOwpEAczO1FQt3Bvg1/LJHVsenSrbHR3Po6bN8kltoDBuFhUROXyeqPp1W1xmIXxbmb19ARt2wyA== sig=QMdHifUOFRbngXeuNJ2YrsbXlYivSo9QpMwdzlMDczf/SenITen/7JhOqG18f0O0x+I7zkJne/wAoEK/ysXosSNOj2iuAyI4TrmbyOYmxM7LGJMWxSbDEZ/Dqw553ai246wetXgmwxrdH1T1WkcrXSMA e=found last=20 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA8DjQwQol0koNLpFgje9/aD7XhupbumRYuqdfQxGzCVfgGpcoXmNRlhwkJY2nAWbIomO/wZcO0uuA priv=MEcCAQAwBQYDK2VxBDsEOcZhyisU1uGbW4a9yWbvoNUOLFKo/vgmOg6JjA03Ik+hDzXNz0ZHrVSEcVaeQ31dtuUdlw9thSY1wA== msg=xmHKKxTW4Ztbhr3JZu+g1Q4sUqj++CY6DomMDTciT6EPNc3PRketVIRxVp5DfV225R2XD22FJjXA0ll7FNHIMw== sig=rD0wzKiGKxsQeJVVnK448Tp6KOEibUKXNYbYkg90jU5RWGrT1mj3+d2zF9ktwH6K3CVHPF74xL2AvYVoQNl4zuf4mCM3wWefcZNOuYR2cktAHrjDgpdtXZXlGCw5YyzhuT8aBMiTCnf0oH90E2MDuhkA e=found last=19 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAa6bpPP3iOAFKutKMt3YB6tVZGa8MpFqPirAtqusZJrddNYHMRDC4Z5468cgXdopp2GUSer6zU6sA priv=MEcCAQAwBQYDK2VxBDsEOfPWx8CjmYGaZlQVKMzARuFAM+vlqzaBlAdAN1+1hXvL9iXjXjHCuZlPtYwUq1o7DRyqi4T2OMd0Ew== msg=89bHwKOZgZpmVBUozMBG4UAz6+WrNoGUB0A3X7WFe8v2JeNeMcK5mU+1jBSrWjsNHKqLhPY4x3QTyyKWPN2xyA== sig=TvC9ExgnAzHhw2nXJrkQwuZTWSeYXEegCTiqi3BF4ay0GHUz2CaUFgO6rOzI559NhBSWNuP+M7SAwsi7TlnPlnWXv8jh3iIoda2sa6b9BruzOGdjuqHWU01K5F2ZuQUNmiJ1RXfBJp1+O6HLABOeGhEA e=found last=19 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA9gAifn9J1dfXBsUkLHHCYN7Z1jd/vMRJuAP+BVqYMR17M0W66hn5j0tOdUUhGOGlsoAF065ZFPYA priv=MEcCAQAwBQYDK2VxBDsEOWwBeLRwWkBG9loa80MK7EsgB4rXAf7H17wk3XvCcTixwQ2y3Fx0fNMEeZK6/vmA/49Q2rmUicgVNQ== msg=bAF4tHBaQEb2WhrzQwrsSyAHitcB/sfXvCTde8JxOLHBDbLcXHR80wR5krr++YD/j1DauZSJyBU1mGiQkDLCMg== sig=fxMm22lcaojZMSGffLYnLWoWsNaTR1rxW9I5CW9FOZBo7HwTKzL7TjtIiUvbw9b0YBQIyp1+dpQA5ytH4swcPRNGTFdi5MVsxq3tuOjJdYeWcOCK4qoW1y+/vlMLx9lJXxwdEKHlJEQmEY5kOgbecjAA e=found last=25 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoApyxoTQDCGAB/faWE0F265jwXyxuN2LWm+jN/+saH2g9W8jpcaU+cnRuDhfO6ts9cmzjQWKhvtoGA priv=MEcCAQAwBQYDK2VxBDsEOYxDIm56AEXwu1hQocRoOTOfwxHA/nSO74DA7xCgXuvEDx3eRCDb80vQetZORNhn/EHHMBx9iZ9A7w== msg=jEMibnoARfC7WFChxGg5M5/DEcD+dI7vgMDvEKBe68QPHd5EINvzS9B61k5E2Gf8QccwHH2Jn0Dvw3m0lTwNoQ== sig=lR7rbni+Peeend85N2RIInTpde5bgT0NukMiMea9hQarFvRYum+JNWMrSNaUoraO/V+1F5IYIg8ARruSju1WvAO6BphLL1NgVFgS5VCy+l6oBDbH+9yq90aMRgdzEr0P+LhnahON8XfNJBbkLx7RfwwA e=found last=19 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5iLLy47l4+0xpL+6MVjpmIkfBaBYkG/JPIV2cJbs46Bp2h+sodGt8l7PEwaUAfi1oOg8Itq6MfoA priv=MEcCAQAwBQYDK2VxBDsEOTix6zskouM6lvq/Ie6ZLFmkUNNjQ6IyB4PnFVlvUn0IINzLgf82BvNboNj0PvNqO0y43+4986OXZg== msg=OLHrOySi4zqW+r8h7pksWaRQ02NDojIHg+cVWW9SfQgg3MuB/zYG81ug2PQ+82o7TLjf7j3zo5dmuOfLf3JZZA== sig=sc8u3akqY3mOp6KcFOJecJ5BIksiHzXH/R8L/vz+CaAgoPlfFvm+5WnkxUyyjiosSAFCT50N6hOA8jEses/iJ91TZYTwwNbUS6flAbipIquvaGP8yLKK/MgHIdZAcRfKg6IoKi/9sMxLZ9mk8ZZb0RAA e=found last=25 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAgxXFB1FYRn1aLattNITrBzHCN1Tcg60tiPN6m8UDyIsMZUzSbSfRUy3UgRh5Q5S4hsfCKF06DKsA priv=MEcCAQAwBQYDK2VxBDsEOUTfCH4vQYRzYXfSZ0OqM/S/S82xEUsguKNMy6vaOZ8PYdPZ1iMqxUvcCbUQoxzoiS8eB9rBOuSVcA== msg=RN8Ifi9BhHNhd9JnQ6oz9L9LzbERSyC4o0zLq9o5nw9h09nWIyrFS9wJtRCjHOiJLx4H2sE65JVwaNhkX6zttQ== sig=g0HehijesMyjtMSui0dDKVHaoyl67BKDSvAQyuO8bs1S4OUqfGTbjRU+F16prq3X+3qmoZsBY6cACNdrkIMzpp3t12dVP+OgOulkNmQJLjLO1BdJAgUnT2HLK7xeFkSk53h+GQb5P6e7OLfAY2D/xDQA e=found last=19 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAkOUR4IrUuH6XD3zvEdA5RGOR2J5EUNWGtUOMec9uLl7HtWnoVWxVp/Bf1LXAdA+nIyoGKjG2YPUA priv=MEcCAQAwBQYDK2VxBDsEOT3nwF37M4AbWbKuuSqy0+ZcWN8T+BFxpdFwSReXMEdocdB0k9te5bPvdj4osKZP38ICRaw1NNMCmw== msg=PefAXfszgBtZsq65KrLT5lxY3xP4EXGl0XBJF5cwR2hx0HST217ls+92Piiwpk/fwgJFrDU00wKby05FwGbSLA== sig=XG+xEpXbma3+9Ot5hRN6gRp7F+hFcIiajZlsV2MQ6mK+xf0FhgKw+0v1/31c2lhNpgbHrjN7VMKAlxOvvPoBJEEOGweDxVbNRLS9UJqMQdRwwNQM8hZZZoQfRiJPhc/ddZOm6rZclqIQu6MKBPLply4A e=found last=19 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAh6uqMpq3LkSQDOJ0LjpYeI8k/jWSrsnwd8Mr/jLc9DOSXtMBM44PDwqJdHNrRAJJkCiorrYOwhCA priv=MEcCAQAwBQYDK2VxBDsEOatMM99UUs/8lLTxKqyvAihyh4NtDMJ8CM6VJqoi6EiER2FTMC5xOG3ROAGjOcbXcAbMXcYLHeokuA== msg=q0wz31RSz/yUtPEqrK8CKHKHg20MwnwIzpUmqiLoSIRHYVMwLnE4bdE4AaM5xtdwBsxdxgsd6iS4M4yhktbO3Q== sig=N7G/gLc5bk57KE1g0yhb4XZzDLZBb91nJwfT2CLLUcysrRoP+VMYQanc3pLEzl14Ohi/N2gsrmeAQAa54TgTTjfXYB+vZTv3NfJXz83QaPfSr+WSgCp9s+rZtnLBzYyhkCZbRiNAWlF9HrQtrdIJqw0A e=found last=19 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWHQ+UGqtknhzT6WPCG37Er+Qx8u5Rx+18md/J90R1TFeDScAHFgaoy4qbQHfkTPR0k6f6DHBD4wA priv=MEcCAQAwBQYDK2VxBDsEOc4dtGze7HIkEAnnZVvIqoSaq/+PsTyMXT/Kgirux4efOkf4klPu1u52O7+sezp/q8VXCrKkAtHwjQ== msg=zh20bN7sciQQCedlW8iqhJqr/4+xPIxdP8qCKu7Hh586R/iSU+7W7nY7v6x7On+rxVcKsqQC0fCNFO5XFxuMQg== sig=OvBM1yf0ztz6s3L7dF7foQdaw28MvqgKvqBZukqJz9Z4dIxjubOwm7yPSnyPprPt4viI9AR/q72ADYiLhYrY1sJN1/09ATq0l7n6QbEozFwWcnXra2oBuwR2fPohPjqc3CbufOXcdvIyB602SFoA3CMA e=found last=19 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoASaV/Rp7bF8MCINwYu9Sm0ojWa98qznylAtB9VDBikUt2MDEKO9+Z8u1D88MbP76BG4HoSN4cj5aA priv=MEcCAQAwBQYDK2VxBDsEOS57zLP9BVY1Kwot5DMD+DE4qgNJcT/nE95YNPFF23xLj4WTD7H2NApxVjsYduHhALbiGLCFYXhsKQ== msg=LnvMs/0FVjUrCi3kMwP4MTiqA0lxP+cT3lg08UXbfEuPhZMPsfY0CnFWOxh24eEAtuIYsIVheGwpIxaDTrq03Q== sig=qyCzze3aURVV6ZpI0Z17QqH+/9KdJafcpsmdhJjbxxBfNSZL3vOy9d6xuLMgPEgfLYd2BJDWaG8A0ExcUY71Wc+eaP2w7bmnfApDFz3NqAeJHfch6sqpZZ5AHxVSIDJBCbxDVQiDO0TXi+Opx1mArBkA e=found last=19 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoASVrqqbjqz8YBNgW0q2+CgEieG+2cXzjKycTyWYXHHPEuQe3klLFzwJH8Fiz+r9m7KFi7IeSx+woA priv=MEcCAQAwBQYDK2VxBDsEOXUgH9tM0LnmLbcQzC2kBwlXEqj3yqo4XtqvtYoqrp/EpDE3093rEBe3zjvGG3HaeA3ItUDv4PCUnA== msg=dSAf20zQueYttxDMLaQHCVcSqPfKqjhe2q+1iiqun8SkMTfT3esQF7fOO8Ybcdp4Dci1QO/g8JScFg2NFl7OVg== sig=vDlM9yU8mGQMsOswOqHWLvowO4atcD188AwWY63gGyRZfwhRXMKBa0aDPn+s41SlsWIP4p8ImvyARCfRwtjIDPRUZ6yro4hYBVCK7DMhGLz5IhDtySsf3q2MEdQAEd2S0zcgeXReWrNjcB+ZaoCKzhcA e=found last=18 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAIhrmgHn/1smfP4pJuQk+2ohWQSrInIUYFpuszbLgKlF04AsVf0wT6JjmimUupa3LEquXDjXeT2SA priv=MEcCAQAwBQYDK2VxBDsEOQtvMr8kzMRaMbm+1juPdPJ6hqLuu1VF4k6Pn4luAOyzVcU6X9Uh0vPtjEgwCLlVU1kkv6p/UNmYIw== msg=C28yvyTMxFoxub7WO4908nqGou67VUXiTo+fiW4A7LNVxTpf1SHS8+2MSDAIuVVTWSS/qn9Q2Zgj24Qjhinxnw== sig=CDlEXj/32NKSK9m7CsnSZX6FWevhHiYA/9wgobzc4odr+V8j+3CBqJ803iytEXbxZfRxKb5r/cWAalzab+/Ad3PTa1+KLiYw2YPu8KpngH4fIHW/mQZeZtff1/zKI+rMPnDoxp/3fLHRFvXkPTEXIR8A e=found last=19 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoANBOvZGnsLyHTbUHLEhaj7I1CFUnpIFNHBwiOxraxEAzmQaAuCsdVMb2+nbygkw2e0ByiqqbtgEUA priv=MEcCAQAwBQYDK2VxBDsEOfL1FGEFnNlBxZWcvgMqQljZ/grzmAvsp4sHg+Drl1b+zvy11GsAgqhGO8DfNkSYtVI6R/Hl67I/QQ== msg=8vUUYQWc2UHFlZy+AypCWNn+CvOYC+yniweD4OuXVv7O/LXUawCCqEY7wN82RJi1UjpH8eXrsj9BZyA75RDRUA== sig=Up4PblPTXTGlsU81QLMJ53pUuj6PN/QPxoTKdxJzmXceVQqUNJpqRPwkZf2fH5HyFXOerGV5cwYAxinu4SNmUCiv7pjvktW3b2eYk5828P6EqBwzqwmKfjYJ2idWLtJe/zslaiMdwWjoxd8xnHQ1rg8A e=found last=19 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA2vOVe1Xzs8T4PHVsz7xxO0Cwa8MJ2eks5tpnOANPkj17uzAAiykvR1I6BO6FNnos++FMk1fD0G0A priv=MEcCAQAwBQYDK2VxBDsEOXZ1PrC4E1aeJ5W0XM0HWnq5Xc6fe/C1DR0IJ/Rj6Irn3lcb/veJGr+kIJ2X2ZyOCvR6Ea4Ux/F1sw== msg=dnU+sLgTVp4nlbRczQdaerldzp978LUNHQgn9GPoiufeVxv+94kav6QgnZfZnI4K9HoRrhTH8XWzsG+hPHfJuQ== sig=etyz6/knKcLc0SgVhDWYPq8hlfSVJ1f4mULbZJGLZ5wZvejHhY4g9onzRT4NygRIbXlFRRzFyuMAJY6yDxmYp4hsH/DEbfE39J/b0x+mrqUOijCDbvjci+7fCOlZpu/ZOCBMAbRQ0AVeN6YP7x3OBhgA e=found last=20 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAgD7fB0hnnCOsFGTV2h5lNgGpy7GteHflb9FIf8uq8YaM3IWvAAuME2OLJ9Llc0TFoVCivhSy4lYA priv=MEcCAQAwBQYDK2VxBDsEOaS4E47OQyt8TBOEHjRqfKU2dtvuBg3gJYGFggiTEIuKaDEDYk0CV+AJ4pdoOElTpsYTBcDXwcj4rA== msg=pLgTjs5DK3xME4QeNGp8pTZ22+4GDeAlgYWCCJMQi4poMQNiTQJX4Anil2g4SVOmxhMFwNfByPisaNQqdeafFw== sig=J5bx65RAk30HBdp/LdCWp3pbVrkb1v3YMS5d1uDOGPgIiR6tNBU7TKmcu4GNumstMK8z+wwjmUgAsUzq8i2LfoYNB4wSB84cKjUBjHV6Mb9anxIVopRU9gBF27o7QszeB85rB3Nm+YdsC+DSS0VViSYA e=found last=22 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoArqE+fQC9byzh5V/cyALAVZx4QFtCdu1Bbfjcj8tt7ocLBtiyLnKOGL60C4WXlwWaKcF1zxiBoFmA priv=MEcCAQAwBQYDK2VxBDsEOZw59cCnM9KMdE6WfroNHAkrdxvlg1ExFxbti8izlkFuV1QsXlYKU1Z8ILzOqNdfVluzZ5vAJYRdJA== msg=nDn1wKcz0ox0TpZ+ug0cCSt3G+WDUTEXFu2LyLOWQW5XVCxeVgpTVnwgvM6o119WW7Nnm8AlhF0kOv2z38+0kw== sig=4YYOiNGCSO9pngvdsFNp+R7qT8sPBK05Rt0e5S44SXU4sUeDoI1VHiK9e0we/L2EKBH235C9O1kAoUKbjuGStkiY4sN66tAjS6wCPrINmW2j7vxBQ4dRAwbUuvaPP7UMB1Ys6yr0kyUa512WkjohZB4A e=found last=19 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5AX08dhPiHHxQRACIFnRY6VZAuhlkEEQTgLwS7imPKN21MyTNbK2/0V/6o5I5IJkGBnKr07rKSkA priv=MEcCAQAwBQYDK2VxBDsEOX9MIDjb+KcF64/wfjIlEx4pIQ5nGJYVxlCm0htFO3IPTzW8+o9/5CVT8PXFqKlti5PzYmhB+vv6oA== msg=f0wgONv4pwXrj/B+MiUTHikhDmcYlhXGUKbSG0U7cg9PNbz6j3/kJVPw9cWoqW2Lk/NiaEH6+/qgevaLQU8X9w== sig=nIop4Ame4YvDx4t0JowJVK80Bdgmg8jldqEb6oEwz9YIJ3BN3h0/1tkS95s7xJLI0+hoBRJtQh6AMEds6Zre8wJ+UlugXkf9d8Bnb+fch4CfCOfT/FwdS5UCi1Mxhr3LocgzlVUTgbztqNTY7D8nlCAA e=found last=18 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAl0wLFPcfMz1hArXei7MpFOuK3Gp4Ib/4ctxQHEo2DLUeB24wJbC99ubzIRMk1Fj09kV5yrErz6+A priv=MEcCAQAwBQYDK2VxBDsEOWAuEHbmSZ/y0vHbYPTkjcv+mPbD3TYBy7sPnr+YrOsO3xohJL//AF2cOXb+kxUvbgxY2vXDMp44AQ== msg=YC4QduZJn/LS8dtg9OSNy/6Y9sPdNgHLuw+ev5is6w7fGiEkv/8AXZw5dv6TFS9uDFja9cMynjgB3opaEXevHw== sig=88JEMeAejFYTEYrAcj3BF03fyaXNbneRwq2lQT4krwdVJNZTwp4Y6NcQJTVzIcJ8nJ/Zb4viLmEA78EsLWvp1t9/KUXeU+6Hbs0WrQJI2KPWHOY1j1Gz3M0h8hZmNVOjHev907xm+wtEP7mBPuLT7jsA e=found last=18 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAzXbjVrYiFrYIh6zFMATwC0KQ0Gf3G4OS6T12aAEPJmhaU2HirY7rExITDDbFZqxVvnKJRYQnKkQA priv=MEcCAQAwBQYDK2VxBDsEOYSLXqIsW3q4av85m6W5xjyAWRb0yCS8MuhciWufs5os7JGa7EPjsVz2L0DGG95teKa4VWucaBiJiQ== msg=hIteoixberhq/zmbpbnGPIBZFvTIJLwy6FyJa5+zmizskZrsQ+OxXPYvQMYb3m14prhVa5xoGImJ6MHHl/ryMg== sig=klkaSymmcTDkTfIl7aRNeFBqQ8vZ6GYRl08VPJKIm+G66Lk+ywzGVDIvnnKe1pAIND8KrjdUWWIAus6Sy7Q/zeYcmSmuNm58MiZpJr1hDMuS4RgzQ0adXakc5+M91+I0JpIiw9z7ENfLjmBPjjSH7wUA e=found last=18 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAuLIKGmJI60O1PVQef9C/47P87XgJHritBR2br2RoqQ9jODNDbkEMVtfFlml7uZRpBi3rl3Km3egA priv=MEcCAQAwBQYDK2VxBDsEOenkb4RQUHfq1yyxUGK88B7F4uUTwuPR3FxxJ9rKKluP3zNi6D/HgAWJUlM/928oTAf3N/Gwjrk8ng== msg=6eRvhFBQd+rXLLFQYrzwHsXi5RPC49HcXHEn2soqW4/fM2LoP8eABYlSUz/3byhMB/c38bCOuTye24rrDAeXjw== sig=aZYgMWZvysyOWO1l5hg+tYxpgzxP5yonUDU+N7b6CdWuoFlME3yV+DTPk8jTR8uFxS3ZiX53bcEAKh44gDpWJwGOjOOZFh0y/pJ618ui8SyFIoK+fK7DfAEihQpI7IWiIA3cIOjaY6TFCMT8lcAmgy0A e=found last=18 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAerJwMTSiAfgk09woZTfm4jWI9Me1JcDf+FsTC9Za1LiGsE+SOdJsB5q5BuDX91mfQllBOp25UioA priv=MEcCAQAwBQYDK2VxBDsEOWy2lx8xhDaIPL5F8oktBqzuoX0bSHQ0mixZy3INKt/wsENXheiNeca5S0dZ8NBapmEeTGPaQ+Dm5Q== msg=bLaXHzGENog8vkXyiS0GrO6hfRtIdDSaLFnLcg0q3/CwQ1eF6I15xrlLR1nw0FqmYR5MY9pD4OblYLjYPCQK+w== sig=apY3DYpTb+MUAhYhtyRkTuIh0bYWN9MWL0eN5Gv3Hfs1Z3cFK/pQz5v1gQC1gwRA7Ndk8v+867OANGpSngfSuJnVliKiJxxTAuGWNMemmASpUcH/Fu35g9g1/Z5cMZvgbrhMHfQYfBLPPXMVBxe65REA e=found last=18 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAfwbIA4f07JeFMg0luuQR7/JApm2+OFYqZQfa+mfbUdwaIZB2BWB6KqMUXUVK4b+jxKo9rm38HV6A priv=MEcCAQAwBQYDK2VxBDsEOehZwd2zGz8OTqRkRaexpH8W/y5WsNBGZyiSsNC55goZw2+tMs97k1gxF5h31NXm8jFwvcd7OZ72fw== msg=6FnB3bMbPw5OpGRFp7Gkfxb/Llaw0EZnKJKw0LnmChnDb60yz3uTWDEXmHfU1ebyMXC9x3s5nvZ/Vb7CG3JYRg== sig=sLc35X7CSZdV8yC5D9MMZd6Ifg36WBdvImROA48t9i5e6Xqz1RJw6Pwno9MdPsjWRnvnCZ5iQNEAuwsNlVjTlie4SfQw89uRnMpFXoKU5y4PDCAY7KzHKVLKTUOD0iZJ3luBlYoxx/YFT0a5JpAv0ikA e=found last=27 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAk27KLvIY8+6mzeEvEl6vFfzjBfz2CPaIQP7QvheiwMYeMugEVBoc7PSgFac1x4FNicJRZykJ3NyA priv=MEcCAQAwBQYDK2VxBDsEOTSD6tBR1qHvJDW9tO5WRFClgyTD/wE0jX/+qh83VvDIuS9x49dSV+WfLGjVcAoH1mCO51F5bYLu/g== msg=NIPq0FHWoe8kNb207lZEUKWDJMP/ATSNf/6qHzdW8Mi5L3Hj11JX5Z8saNVwCgfWYI7nUXltgu7+9vhPzaOneQ== sig=aJzVygGPAQ4ZV3pVgolwwky2Ulj4RSkmv4VXyETXo3QyrK1pwFW4N67mLaHSlDS8YsWrfu3xmEuAK5IlriZecaVb+dBqIsOL9Si10FQiW94YSS8Zv4iEepwEbrWYgI3QuA75GfjFzcmmMm59OqglXDMA e=found last=22 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAhYVojMRffaZJCduKShfjU987AISUGYwsapC1+16FEBrQVheS6hdOurFarPjdg+lYT+rRxEuK5V6A priv=MEcCAQAwBQYDK2VxBDsEOai359+i7pRMtZaC7U7yQ22kYQuGRtq7Lc8D+fFoSxByHA2dsakq57m8gWU00G7J/gtrrvD3e9ENiQ== msg=qLfn36LulEy1loLtTvJDbaRhC4ZG2rstzwP58WhLEHIcDZ2xqSrnubyBZTTQbsn+C2uu8Pd70Q2Jm/NuDxIPTw== sig=bpdiY06WsU59ofeV7bzwzr9MCZ8zkVeGeppNJugnQV6qkmQgUExS1FE3bJX7zi0fIFY1AUfQ7OUAxOSx1ylKgDknC9RAnnXujFAqpskR7rpA5kOv5G/maMTC9Y9qUTzEi3pTLTnt1+hOT6K7MQkD4RcA e=found last=18 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAsDdHL/S9FzXPjAZt5GZcQ4PX9yGLx5e4sS2fOmv0Cqnq85ioqRIyvIo6kc7np1q2xqZw4gxqfX0A priv=MEcCAQAwBQYDK2VxBDsEORlJU9d6SbLoeNH7S5R45XkIVxOWmoa2l1oC2QCRTPa0CBpjUovpzVtOYuSqoFPbB5mfo1CtjPB76Q== msg=GUlT13pJsuh40ftLlHjleQhXE5aahraXWgLZAJFM9rQIGmNSi+nNW05i5KqgU9sHmZ+jUK2M8HvpZ4BrLq4abw== sig=i0bdaP4tqSsy/qj/g1L/z/E8pzvrD2VWm1G12cPd1YkA4b+0ZFBMK/PXv8uLaXHPNOp4jZO9DcKAHLIb4Wl+vNH2FBb+qPmfAjXml39yR+DQvUsqYSpWOYTEu3V1z7k+STAu/5KtK4ASJqPyhZLKvisA e=found last=18 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAwUdIWJlISc65cPpePcV0/LTp0p98Zc36fpVc9MX6unozWTznLR7Snr1vR29gXFzrrbx9mwKwTuEA priv=MEcCAQAwBQYDK2VxBDsEOUF5giYycQd5Nn/5SH1i+X03rEeQzkKYxGfnT03r8HP4KGSv2SFaxirchCznGxEB2fVRETHqplwmrg== msg=QXmCJjJxB3k2f/lIfWL5fTesR5DOQpjEZ+dPTevwc/goZK/ZIVrGKtyELOcbEQHZ9VERMeqmXCauVuOsNYpxNA== sig=rZblyRUBrukDxDQpLpf8Y0IknvpKUIsrlRUnpHYsanIXXLj99ZDWEcLuQ+5dP2z/TqpIljlPptIANwRSqH2+JO5rIFVZbz1Pi3S7JR3Ga2z+5cGmToQKsahxeCPh1uNvYb08v1nGqQykFGVA4E2X0hgA e=found last=23 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAfzcsgdQKIG8VTiMQ/f2FjPK867/sA/kjnYlOvQI6YoJL9AwV1Z94c/0fuQXl0A38AeHbJVdn6mCA priv=MEcCAQAwBQYDK2VxBDsEOU1CfDZX7WWyPLwMYLXQahYQj6bRxhdSBzZwUR2LI05gRuKSwdHlLrs0y+G84JjFyTsuNyFvqvw/mQ== msg=TUJ8NlftZbI8vAxgtdBqFhCPptHGF1IHNnBRHYsjTmBG4pLB0eUuuzTL4bzgmMXJOy43IW+q/D+Z4DemuZ9hYg== sig=Ln+mFrl7XiDzXeaZ8OTbqvJuPv+A0JdV8JNNklphoOWWylKIsQOD8rWQrqS9WlhR5LLsSEr6LcqATUwkRvrMDr6BugSy7xJQWOAMcxMDV8YxF7i1btivxP0Kc3hhY03vstlbpuIXFBQuvfLbqV3XBxIA e=found last=20 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAp/fLQYIQJufdgK1PBJk91N7A23SpzqRw+EAH6YpajJG2ok9X9QWzdtt/aMQn0f0ACv80TRfHW6KA priv=MEcCAQAwBQYDK2VxBDsEOQUnkB0UUbIyFZozyvg2njxsVdXcyGeHaa7cQc8xm1azYxRjuHb1lF9IOzFv745jVcMj5GhzSBk3Aw== msg=BSeQHRRRsjIVmjPK+DaePGxV1dzIZ4dprtxBzzGbVrNjFGO4dvWUX0g7MW/vjmNVwyPkaHNIGTcDlQxsU/XsrA== sig=6XSqnZ7mzDX+t443Xpr51t1PPScp2wiDXCiqXuR68qnrq2Kk5pb5fNzEbd366rRjDKQlQTb6yJeAOHtVNqZDvrS7kpfIo0lwifs08DtZhv82jjXo0R9fTySk8WvhyLYYH8yoa0U0gxCDHIdn5ynW2wIA e=found last=18 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAcNFPbipSp29ZLuliEbbWiShmc8C8eB6V+8OHeKDm00Z3DlDFt07yIMwS9n+OfL7iHXDj4Ud2JFMA priv=MEcCAQAwBQYDK2VxBDsEOTDx67hp1kMLij43vsu7RnXtgV3N2Q+addKU0urP28l2Dy2yll3r6EleNI55bz3u6nAt+5xAKzDtgg== msg=MPHruGnWQwuKPje+y7tGde2BXc3ZD5p10pTS6s/byXYPLbKWXevoSV40jnlvPe7qcC37nEArMO2Cks1NmiU+/Q== sig=0TWSKxj79Y3pMsaYwsrvifhr4DXEI0ZlBiKV8E83/FC3NJFrOvc0b6kh/PVDPK3ZyIJHmNI6Np0AM8rTijNLpqovxVvwiPcF2cRNWsMoMu1fn4Y46bC/R3FvfTrtvnNY6Cmp2qzcWj3pGdhrnnY6oTsA e=found last=26 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAjrsDbtWGCEqPBUxXERQENihD49JUq/Ecuew/lhqNVD+JT1XM72H6WuopcpX2iEVdYYS6O5MISj0A priv=MEcCAQAwBQYDK2VxBDsEOepqJzjfrrAKVRwvAal0sWa2CeuVc3vYUJ45Od+V11FKIKbV0zca6OBwg5PdKrA5wuELe4ttexGx7g== msg=6monON+usApVHC8BqXSxZrYJ65Vze9hQnjk535XXUUogptXTNxro4HCDk90qsDnC4Qt7i217EbHuBi6r+pqsGQ== sig=gmy2wEaXYPeIwcL8IOgn088NA3KrHajZU+3m2PymqZ3L4mqPx5ZISOgILwDjZaLRniZLjSLTzYYAaloRz0AEXqIc8MPA+tnx0UQ38HuGGa2l8NhS/pzl86hYxinxK3ra+JAJme+pHzOfg/HrlmABahsA e=found last=18 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoASFaz65nr7hUll0/2cIUJi8jKyGwQPpSYN4up2Yrt3TbrtjH1dDls2vDc8ciBqozuyETwNeq6hI+A priv=MEcCAQAwBQYDK2VxBDsEOcC6ftaMJk6ZzI5VVww+PTVOHUevhm+FtiLEINWBT4xNd1xdfE6Xyptc/1sN6Q+rYWsC7NNi5BXnGQ== msg=wLp+1owmTpnMjlVXDD49NU4dR6+Gb4W2IsQg1YFPjE13XF18TpfKm1z/Ww3pD6thawLs02LkFecZyueFMcyELA== sig=yMHjHYvmVAUL+RTd3Fkkr4JlA4kUMublgsrZ2Uv/Z/5z+lWIc/9R9o0244E1Dp8Y00vVvlUcBTMAgBZaO8fDGksuzU9h5JI7c07mH6VeokxP8JqAvNrSDZfXhY1b0xgiILE0pYWk7iimwwxxKzieaRQA e=found last=18 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAt2WkWjKIh4NkzA0eoofwlqCRHlOYUEgtQ+v6qMQhWAjVG8kF2o4kza+nHLctmDybq/60ZNmNpb+A priv=MEcCAQAwBQYDK2VxBDsEObfxZT1ttf/yWxpBRxqG0bbUm0Dme3oyDtgHFTT2zJjNCvFpkKDHaQH2XILJyBgNsqqsB0u4thEwww== msg=t/FlPW21//JbGkFHGobRttSbQOZ7ejIO2AcVNPbMmM0K8WmQoMdpAfZcgsnIGA2yqqwHS7i2ETDDta4zo6JPIQ== sig=WL97u/UA6KhoTwANDk1v2fAv3f6GOTRIwstKhjjH6poNH13UKCtZCOMPh0mSDb8a367C2XhQnfUAdi3dD/yB6MQBm+sPWtUYboHPwA6fTVLBkGZIbkPhNPsfYOgIlJnIq0ZFQi7XBvmdW1p44GKVPxwA e=found last=18 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5diy9Cpy79SkpFq0poCSxSOS2uwdtFbjNrMNHm0z5AhEJxSj2hudArrFI4ZH/DwOdXo8n28H+3AA priv=MEcCAQAwBQYDK2VxBDsEOf23LwOSOxCFA88jikUHnljMcpXLwP8t3YhDMW2X/kWPEyzKi+914p5+Mq0Vg6mCXdaW+Il0TyM8Kw== msg=/bcvA5I7EIUDzyOKRQeeWMxylcvA/y3diEMxbZf+RY8TLMqL73Xinn4yrRWDqYJd1pb4iXRPIzwr2z7YZA3LOg== sig=vnWimHIKgij/rp+3e3TQUEd/vTtpfXRLPtnnFKMeDeCTRJxXWyE0BHIkDbOFbcltIjWOClXjMN0AjLBBr1ZzqYanmXEm+8d/u1LcV8RCGNGwvYqYt17D39adn+48FNBuRvF947Ph1mZo5toBnbOjZycA e=found last=18 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAtmHEXzp/fdj/W8iXJXmMtejS4heUkB6Yae1c8N72oX3IO5CPicG7XBwoABrr8RzK6bLg49Bf2fuA priv=MEcCAQAwBQYDK2VxBDsEOU7mZjH8KdlS6YeZr2yt/HSVWIZ7dpab+OYN8sHEQsseiF+fgNmQe487WTfbIUUiw4MBuDW01iy2Cg== msg=TuZmMfwp2VLph5mvbK38dJVYhnt2lpv45g3ywcRCyx6IX5+A2ZB7jztZN9shRSLDgwG4NbTWLLYKckw7EFR4kA== sig=CktlhAQyk+kJghFsjVmSdPaBaMEg963vFUJIpGhSyA/nKJ+dDYcCtU0RCFtPezpYqn0bcRTZDdyAyEYIRcKtJb9TztOJjJKzpzQwRKpaeIaXW4OFsrKpWzB8U277aRKEqJGAYqH8/0vyZ7pwrE0IgzcA e=found last=19 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA9pIVzbcfhxScfDUQy5C/ETrt5a+BN5BhZXxCJNn3ZnTXoWKHJtJqun+dipZTkNbUP3ibomDUvlUA priv=MEcCAQAwBQYDK2VxBDsEOeYj6QZqYntJyQsYG3VBlJzfIU6YAjY9U9nnmfKHKb6h8oq6JYvod5y0QHSI3UNvWWuj34vxEsEfRA== msg=5iPpBmpie0nJCxgbdUGUnN8hTpgCNj1T2eeZ8ocpvqHyiroli+h3nLRAdIjdQ29Za6Pfi/ESwR9EdrFGZoPDuw== sig=guh71jr9uDBlQ7HO2KV5akajCUtsWHhsU84br6LphWr3KPIZIcYr130eiCiDwwgxDWXWtgC5V2+AsX3PnXI1IeBNXKyGFCu+2L51DO7f522+BhgNPLro6imjzF69TZDS4DzH2vi5oJw4tCzn64Y/2wcA e=found last=19 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoArRaPN4ueAA/offO29IfTbuJyrVi/Gr98icxUFqJrHapYARpup4rhNz5HGKEz+2Lm+iYc84W1oqeA priv=MEcCAQAwBQYDK2VxBDsEOR6aFxzjsO7EN1hat3lfVlnsTenAOzG5S9FPcgOZio4ciIMS221f0XhfqH1izsrf5beKALFhwDptng== msg=HpoXHOOw7sQ3WFq3eV9WWexN6cA7MblL0U9yA5mKjhyIgxLbbV/ReF+ofWLOyt/lt4oAsWHAOm2eFHzUIRVb5A== sig=7ba5Gpjlpo8DPCsUS1OnGFiqPJRUyhT7mjN90sCgI+Xm2wy3fzlilyBdRthXoiunGVa6AXfzJXyAwB9cxNIbbrJ8HrsH0ZTrvnByl6aOCbZvXnwGIjRwDIqfy1Rj6pNETLawhEw4xka1y8chZLDelgcA e=found last=18 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAS82x21DwiQ3tYSo06SkGqDTMJ8ujsG2NIdu3Yuyed0SAztQUWvGaoEIpWkK/aJ9qq5cOXPhCD5eA priv=MEcCAQAwBQYDK2VxBDsEOYi0Amr1I6+3Gy9pZ1hwl8xH1IIm3mPxSDSxVhT4VBdW6NElVywLCq9lDFSHTOwjkTFkIrQxUOOURQ== msg=iLQCavUjr7cbL2lnWHCXzEfUgibeY/FINLFWFPhUF1bo0SVXLAsKr2UMVIdM7CORMWQitDFQ45RFqsEXv0xxmg== sig=2EUv4fGPrbtj/ShOG2BGMrYJUnopcs5RrHgx8HE/TqfJjiLqL1iXZaAmW5b7F9VLMjqEEnJXQWIAtYXVENBP1MowMQtae6eoawZP+Ug2zTEoFFJ54grctS7ZFJXW3XS0SHjBx24/j8qklzj0RId/rxkA e=found last=17 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAr7CDHfJsbd0HnKsBjk5fFn6LBTnGmVm4Ky7HERbEHwOm+zBQEqSeK7ZEZ9c48w5lBPmV3a2UAb2A priv=MEcCAQAwBQYDK2VxBDsEOZpCEFZWs2PcYoMDp87VSV8iTZ31Bp1wJ6T3fZ6XqbvSYc+ixg6ogLNv/jamYlT6NMvr857aDW2a1Q== msg=mkIQVlazY9xigwOnztVJXyJNnfUGnXAnpPd9npepu9Jhz6LGDqiAs2/+NqZiVPo0y+vzntoNbZrVn+0R+XoQ5A== sig=ovGdzqhFegiVwcXRQ/aQcMcsvyDVQcngsHhjLq90pwHXiL7FOY2fhGJMeGJdhT2zHbYBFuLTggSA9cbbewFVRwqL+I1qZK8TLkKM5tbwEk4o/B6DQVIkmw/4UQMTjTeXzrKe6tuDSefD02lUjGVS7yIA e=found last=17 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAJPZkVsmoBXOlRv1UYrk/XPDiKJyJBhZt+MdXC0j43XG56QZgeIXCSstZP+vKTh109OJTx6L05o0A priv=MEcCAQAwBQYDK2VxBDsEObeH7bg8Vby6aznIYbMikA+so2QJf52c4Vu4rcYgNwbuhmQQr51XLcpR0lOcGqzFO/wqWNhNkAWaJg== msg=t4ftuDxVvLprOchhsyKQD6yjZAl/nZzhW7itxiA3Bu6GZBCvnVctylHSU5warMU7/CpY2E2QBZomqrvBVBhw6A== sig=yt+oAskPvrqtYfyRjPE0QGeKfd+Os5+t+WyiHG/N0leXcpfvbpAhhxIAZ4C+h/+2dbdw5bXBatqA/5ptXf9Zmk7ykfqk7Pu6YyX8Tonq/hwqoxJyqfnTYvkgo+moGQ7sIfaDl3OotR+16drm/IUiOBYA e=found last=23 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAGKZxzim/t2khGNyH7H/ycO0aAzvaQmQRiFkQypEZpeSkWIlCn1GPixjATZrfrdVsyugjtAsu9IqA priv=MEcCAQAwBQYDK2VxBDsEOYewUJ/wON8WkTkZVx7SVVgmbT7o0g1te/FKl6GrOb3LiMIC4fE9CSGHG/aSZ6wkDonq++Yd462suw== msg=h7BQn/A43xaRORlXHtJVWCZtPujSDW178UqXoas5vcuIwgLh8T0JIYcb9pJnrCQOier75h3jray7IQgrO5216A== sig=W5iNflLsH/3kQLDjPLi+RHxODnn9UUe4J/JM811E9glOsxOXOD+JdHPknHBeovOsXGMJxy2X1/sAwD+AuQyBrtQGCT4NOty8KzIChPgHuOZRKU/2QWCIWmWhv6Jza2BypZBNu1/+WZeSdWKrvmWwiykA e=found last=18 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAbF9Zv5R7jObki+7D7zAke1VSA/7BzPMfk4GdH9/Ogh0YIM3ETc+xtkqVgEcij9BMCpQyFuEpx64A priv=MEcCAQAwBQYDK2VxBDsEOdkFEV1VWl4uBmd2HxAP22HMZ08KKxJZ0vAAotQoMk/JCzouobRnDa/QkoKuv1ur2P+t9tnzpkw68Q== msg=2QURXVVaXi4GZ3YfEA/bYcxnTworElnS8ACi1CgyT8kLOi6htGcNr9CSgq6/W6vY/6322fOmTDrxhVHCd1bggw== sig=ERhjA34fzxCj/VIQj7H95Yg2hHYFWKJo4fg3zFDt2DBrCwJMSGaahPQyScNeOii656nr6REOnZaAOUvz/5w/1f7g4XFRj9kraYkuexJp5HPg4l4aClDYR6dM+mVw3drWID248i/zVUI2bKxrCkbk9gQA e=found last=17 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAmqwL5yeV7YlCba1Nr1EcNv0/SzMmOFteBESuAOABztMsG2YFTzXCsINDnJMaDS9pZe0p39lNVB+A priv=MEcCAQAwBQYDK2VxBDsEOVNW4khwrINOHLxmiewqW4Nv4ZwyoqB+tukdDDIjUKHB38CoJkuiuaj9KeTDF33g9GgNG3+yUBnWcA== msg=U1biSHCsg04cvGaJ7Cpbg2/hnDKioH626R0MMiNQocHfwKgmS6K5qP0p5MMXfeD0aA0bf7JQGdZwQJWEU4EnoA== sig=4bapDp6zhep+gq2yepyx9pBfhlIn4psk/c8eS4mo1Yx+oqLomESNpGa5AbGqWqR7j2hcrfuvLZ2AKSiI6A9eHfCRGQnRM/rtM7SVFzbn9ua6b1EESQ7XbzlrVOE5/+dz01z32uO7aDf7FqgAsarRtwUA e=found last=17 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAOv6VNwsD1lelGQt4qMOLNMgN0DwI1p0bvq2mexDPJGbL1gLe0UZsBquHuyv8nqqxBOeeTN8WUw0A priv=MEcCAQAwBQYDK2VxBDsEOVXYjbm/5X/4n85uYrUZXecKPvj5Kc5gCiIxfF/UkszqzUZEVuG0KbtP97/dbKlO7JAKPAUbVzfg3g== msg=VdiNub/lf/ifzm5itRld5wo++PkpzmAKIjF8X9SSzOrNRkRW4bQpu0/3v91sqU7skAo8BRtXN+DeSc6t2Bi4+w== sig=HfmwWqJ16tXizerpW6D65udqhYkPD4o1kVKpRZhH0s/A3L/601Fq39wm7saHD1JP5E5dwVLMc70AAaR+yTuE70zS5/7CrcUoJNYxurWFeKHQd7wfxWoi8cwcHQJmqRO8rEKCYDFiueaLg+JSm81awDsA e=found last=17 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAxjzUL7M3OTlfr2DvjS7GtyH9MO4RngfPhlOT+J/rQGtq0Q0+534eXecdjezQTz0EZ7k88FrTfdAA priv=MEcCAQAwBQYDK2VxBDsEOVdmlT3406icNvEKCDGNCkXT/ICJWCLJLUfHQpilWaAWVILM19heUZvO6AUHDDH4ja3eJVAiuI0cGA== msg=V2aVPfjTqJw28QoIMY0KRdP8gIlYIsktR8dCmKVZoBZUgszX2F5Rm87oBQcMMfiNrd4lUCK4jRwY6kHPS0lZYg== sig=5NUQVxkvj7Zf6xY2Xm3xv73Z/3PpZ5B6aJ715oZs11RofAChu25aOIFXVVGiv0UEyWg/wt2/bfYAwx6SWNhpwO+HMfGs6v4nkF3IvIIG/WwO+1NvICP8Oaa0At1sfGu+2eG0HIwYVhf10XzgE69PURgA e=found last=17 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA4OM5NR+iCkZXZH4OttcTs+xB0dsVy+KwGkVm003YA7ZjmMA0n3AYS1Lh6UOBG/K+T8P1wD9gJQMA priv=MEcCAQAwBQYDK2VxBDsEOVUBVylr1VYF1Sdjb+xKWe1VgbgBfEY1Ue2GMlUmHKND8d7LDwYAhsGCkaTg/s1cDlPIRoj24nTDcw== msg=VQFXKWvVVgXVJ2Nv7EpZ7VWBuAF8RjVR7YYyVSYco0Px3ssPBgCGwYKRpOD+zVwOU8hGiPbidMNz/6CaungheQ== sig=eelFtJkEQprADQ99nhWLN3hhTPWK+mwUHdBz3YWnNpZMc7EUU9WwGJ9fsp7lVCgwP48iWJCXp9AAAkQyrx8cmsPvAg+XEPgqRWm4AKZemPQBHSjlMWOwMDYrN/Z1RKVP6NLSfzV6J1mNRkkznsT6owgA e=found last=17 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAhUF6XxdiMl52Jw8PW6uyr8fc+QZQDCLjWLX7qjLbnC62EXqOH6hXBndMl+P5Nuci8VRnfh0MqI6A priv=MEcCAQAwBQYDK2VxBDsEOdZ7EAjXJoCjRofQv8W+O1NPSf75PEIueP2yniFACLnVs4Ah+7CZm8kPjt9MnRcAiFH14HNN9ALPkw== msg=1nsQCNcmgKNGh9C/xb47U09J/vk8Qi54/bKeIUAIudWzgCH7sJmbyQ+O30ydFwCIUfXgc030As+T4URphS+5rw== sig=VBdNR+ieEh6Oks5h+Apz8HbOzo236aqf2A3x/JF/Xsq81lPG8aGl6CQ7NpRTLgwYlIkgIacl9fgA6Cl2Ld2qe5f59BGjgiAXcBs4I/gRyJmZV4U0PZc+CyGayaofhbJL17eE7W82S3WFcDOVXghF3yEA e=found last=17 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAqVGGHybbBPKXDQTML+25BNJpEKWHR7ULPjt//4vYWsv+9fFs+4u2RU7n9Whbq49LaUAqow6gRMoA priv=MEcCAQAwBQYDK2VxBDsEOfOmWn5ByMhEUhmwP0ORYj1ijKBnTF6ArxKm1GqmbYixpmZi4ZxicMiGFh4VKKvoJe/KjYipCTe+Dg== msg=86ZafkHIyERSGbA/Q5FiPWKMoGdMXoCvEqbUaqZtiLGmZmLhnGJwyIYWHhUoq+gl78qNiKkJN74OyqsFuxdfxA== sig=wbGR532StVE0O2hA02cvY9aJaiaKjQymQafa5D3Om81/sQjrqctLRg5B3bU45yCP2bbOhFebQPKAXscVALeVDbznWDJ3fpwm+t8xtPbEmGmgsHlcsabyzohZIgo4FiJgLPRoFA774+kc3C/t7fUoszsA e=found last=17 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAjBF0agDyb/H9SAXc5ioVZMja47ANL0jYgY5r5QHTnY2nMPwQHKT7iQfCEEV3EVNgREnbzIE1eeAA priv=MEcCAQAwBQYDK2VxBDsEOf0FHwoerra9N+kaRpOqCulj8lHbjq2PeIHNesX2CbTPMGxYd/FdQJ3DYMB4KaQ2n0t3T2bQUar+Dg== msg=/QUfCh6utr036RpGk6oK6WPyUduOrY94gc16xfYJtM8wbFh38V1AncNgwHgppDafS3dPZtBRqv4OIMGubkPQiA== sig=XEZn3RvRUrG7x7LLXBHg+b3g5wPMZsVhCJQZ/7BSQWsLF/3197RxHi4XdxM8zGDNmlSOQK+tRWQACMEYuzsdoSh4jTV0YWglgLt5zrNZoTg/isStYhCm7qHlBYmwRHKNe4AEitGRYzasFIMBoAZYfysA e=found last=17 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAhzjfsbnVkXNuXEogUYbLinI7AIVVuBCI/BqSFZF8S/m+6PJyR2YeTeyJMKQlNH8wEVyAGG1bXw0A priv=MEcCAQAwBQYDK2VxBDsEOUgTI8lTnb/vPtdsAmLkoYWMpdFLmufCboxFl6HAgKb69A8MIcqUPZfRIwIJjmr+Nlf3kgksiE6lvA== msg=SBMjyVOdv+8+12wCYuShhYyl0Uua58JujEWXocCApvr0DwwhypQ9l9EjAgmOav42V/eSCSyITqW8EhGWpcjqCg== sig=D+71p/SCWSi1P15PJeloW9o/G9ql4sysFfbGO4qCkZTVuZhyWw4rw35i++ne79OlzLxeYUI0sOkAGbR00aJArAwNR/Lh43tzDYzlQR1rlLe2Rkl9f3Jw+bxmSy6jh84qBXUP3uXpZjSU0LWNQ5nsVzwA e=found last=17 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAoc8tZ77cBZnTNlw1AlwoElN+9GsOq2VcryImTBIwu83PaVHXUnVBJX8pa7dHpuXOO3JoLgq3RlyA priv=MEcCAQAwBQYDK2VxBDsEOfrYhtpKWuOtqfmvjrJdEGrDKF7TeqRKiFzzRvJueeMwzagGjcOKoh6sWxufCreW/Wry+vx1xFrT8g== msg=+tiG2kpa462p+a+Osl0QasMoXtN6pEqIXPNG8m554zDNqAaNw4qiHqxbG58Kt5b9avL6/HXEWtPyLcCallezng== sig=zdWyrccASn3+sDmFhJzpi3ZwmeqeYcvvwCobe67Gu467ZqBjuEjwil2SLpxdpQMbL9dKbjIZVeUAa9MTyJSQZNTg6ac0liKL/X6IVhfvdM3eS3DUD+eEu7tCw/feA8dy24Kp1GEsLSMswr3HaYCSazIA e=found last=17 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoACRe6jM9urBXbBugtGJKjDvHnApXczdUN0rb2JhkgmHTRYOyjYxnTJxD+TA4NMC91m9WabaxrliaA priv=MEcCAQAwBQYDK2VxBDsEOdwEA5Biv3k3MXJ9kbR0RgQcSuetMIqdGPnbupVW2jnRJJal7FQ/bi0bTQ4IgC+ikgLfSxzcP1ioNw== msg=3AQDkGK/eTcxcn2RtHRGBBxK560wip0Y+du6lVbaOdEklqXsVD9uLRtNDgiAL6KSAt9LHNw/WKg3N2A2uTypXQ== sig=84VL3b3yr6mtiX0OJ0uX9aMjGoyoyYZsMLsiZVC0mzhEL26KrnYMXV+WmHuovXH5tZWcQrvS7guAsmWz/Oh8bG2fddW29hB9WkgDZUgS5HNO9RnrQtLznkcf77Omv93PLOtLfelHJ+BgnDwWV+aFyA4A e=found last=16 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoACN2HnF6uuu2yjPrkaW4+53z6BRXpLmKLDl6GWidGiolwa3/hGKdiK+NRDhxk78oqPcu2u4rJ90yA priv=MEcCAQAwBQYDK2VxBDsEOfZ1nXTlPzw/2/F2k6FbBrI1brrtNlCOqWYiKpkAIF0b8AMsCmgbEalkYrww7GEAOMN8LM3YtLt5TA== msg=9nWddOU/PD/b8XaToVsGsjVuuu02UI6pZiIqmQAgXRvwAywKaBsRqWRivDDsYQA4w3wszdi0u3lM9zkAzAj5nA== sig=vWtTvIIFQnbYJ7q7qSo0vC422DB/uREqp+B3x8xgfHVenHP8TviaBkrns5ReStFGS87H0x8qJSAAOtbyjeIS8gBBSGASixDosPflU89MdsIzSenss2nbACQ45tWeHye77N6qmVkr3hDXw+wHjp1H3D8A e=found last=17 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAfTowz15El8lYZWn7lW5fAYjC1QL2ST9/rc+eI4zZtWEunMF+EH39bxc8VY+yFNLeBaLxiUkznNUA priv=MEcCAQAwBQYDK2VxBDsEOWY/bjK8Go1YS4pLGXatNssdPACRTdyyhbRu4gcC2cUW+K3vGt32Slu+NoDey147le7E22kmv9t1DQ== msg=Zj9uMrwajVhLiksZdq02yx08AJFN3LKFtG7iBwLZxRb4re8a3fZKW742gN7LXjuV7sTbaSa/23UN7opo5Pu3og== sig=oflhl/8xm9FuNOVtA0MIQQS5Rj9PsD70fNnh/8Ze2wbb9Ljv9Vw55QHizsZFyCbYV2AK3EYh6tIA9/+n/O319Au8NbDJyBMQWac5ISkgt81Zv8qcLLKAFkSzmDE+I09+rjzG6FAkNYluGHdJHalTXCIA e=found last=16 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA55UlVEs75o5TCxqGs7CVVFpoIwfb2rw7UfAie087TRehf6OmkeD2V77xxJOSLgRqJe13EzHHfJyA priv=MEcCAQAwBQYDK2VxBDsEOb94/mT5yzyOgZQBjX0wpbckGVzRgLf3tIPBVcn5b3+QT8jXywf4PPR3k2ZpMRf0uXRFtOsdxFSLRA== msg=v3j+ZPnLPI6BlAGNfTCltyQZXNGAt/e0g8FVyflvf5BPyNfLB/g89HeTZmkxF/S5dEW06x3EVItEFGVTapPHYw== sig=E/eqloJ84kyaKNlBs2MJX4zmdzIiX1+P7ugOkX6ytovCVS90RgFJCWGFV+ZmzbnMOhS95b/2DPMA2MEROncRU+IsNzwHptq25X7QlnI4a6Y4bxt+uo6/54Kx68vhON6DfHH0GgP0O3Xg7P6RGiJsORkA e=found last=18 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA62Ykt4knniyhV1yFpLXvrAg4F8VKqo8KDfmrUrdXm4lIbR4/B+i3AoKz4zvxWLnIpol1vgC30VmA priv=MEcCAQAwBQYDK2VxBDsEOTI/mfbN9xfb0ToyMYJ3SS7z7Df4nRTur7w/8ACegpRUhIzfwgKtAVDX8zbgtkdwRL67G6Rp8xeOZA== msg=Mj+Z9s33F9vROjIxgndJLvPsN/idFO6vvD/wAJ6ClFSEjN/CAq0BUNfzNuC2R3BEvrsbpGnzF45kwomG9GgzYg== sig=qweR1hfTlBzbJAVVq34rM1Tq7O6tRETFRoWcHvQrxeP/kT7vuexPwsuxizKbCR7yT3j6IA6SmIQAdbJ5ngpH5k3Ex8oiU8QRnLv/6GI+BCTTZsigPlbh9MhTspPxQPsSNi5sWItCY/qNoH9hSUXOHgsA e=found last=18 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoARvIg4rMmgf8Hmx467gmLO5Z/9tqD1QxjUUAjgCZUNpnVIqd5Re/f3RpzOGl+vrrFD4SxIULuwtYA priv=MEcCAQAwBQYDK2VxBDsEOWGcLbbe0UATA0bPmMI/0MlyLItizvQ3wQREvz6HL1DS6ZUWlFH/FgapJImcojW5IV1kziTxE+medA== msg=YZwttt7RQBMDRs+Ywj/QyXIsi2LO9DfBBES/PocvUNLplRaUUf8WBqkkiZyiNbkhXWTOJPET6Z50de7eKpPnwQ== sig=Z1hwUlnW9U/JV6HCC66fZKWZSVynbOL2kntNroy9PuA/3P07qwW7fhnqLrGjWavzDzNkK/+PH+GAPKBndXcnn9Je8haVT2htZVD0jaZgL50TFxlAHJv9jFsXd5ULR7PknifPOD6Ib84xvAN1ZdaduQ0A e=found last=17 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAcKJCYdas9tYL+bKEg5XmKNsokzE+WBITsP8OplSgx33Ep9FtSjpzSlWQVs6ATQqv3kI4NooZTTqA priv=MEcCAQAwBQYDK2VxBDsEOVJBr/gdvaCmp4Lcrysb26Sg1PJu4eIFI6OCpWPT8bVN9tKGE2UuVzjVq8NDr1Scx4qmYHE6B3MYoA== msg=UkGv+B29oKangtyvKxvbpKDU8m7h4gUjo4KlY9PxtU320oYTZS5XONWrw0OvVJzHiqZgcToHcxig35AQ9PGCng== sig=W9Zv/sUP8jFStbfZvqxecYTnHRBdq75d0zd/zFJii4RFRrOAHKsLUgx6BvLN9aVWe75IzBc7uk2AQ/fPpEP8P6R3slegnn6LklUfSh/Ayh4CMBxVKB2gBf8yuoHyElPGwnWFyeJNsxZT8p9TRX59zjkA e=found last=16 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAn/ezlvbDPCr6P8OQb9Geq/c0XI5sFgIzDQDhF8vSLDNWM62QhfPI8Cp/rS5VIy3xycbIFDrTDt0A priv=MEcCAQAwBQYDK2VxBDsEObug0d8Ig5oP9pO1SwohY9EGJWYLTOYlO4w5Lj/HOpMI3IBKUB9GP7B7gcHc+O8w9ecsPS3BeGpoNA== msg=u6DR3wiDmg/2k7VLCiFj0QYlZgtM5iU7jDkuP8c6kwjcgEpQH0Y/sHuBwdz47zD15yw9LcF4amg0owkTA6IplA== sig=abfp7srC1EaqN3q0c9nQ1HluRBs7iTzZJ8t7ROuMhNTTHcu0XM2WT+gZeeoCi+xfyZ4eI2ypq76AxDicIazoRhKbX6lMNd6SAyJ9rLN0FvjkPcVlghiU/ulnyDcGnFYzM/2QHb6bBJuecSYrFjCFQSgA e=found last=16 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAwAB5KonzvAI8kFCXQNh4fZefsPjdGFOHRblgIHhE+TdPP33uJSFBz4xlZGfZkPPK6pWMnuOcx3mA priv=MEcCAQAwBQYDK2VxBDsEOW1H6C7Lh6aGCRxIOBHWS45iJRulo2xsZ0LfUTboe439QPViMJBRzHJmSyMTzZap2RsOhvE2o+eVDQ== msg=bUfoLsuHpoYJHEg4EdZLjmIlG6WjbGxnQt9RNuh7jf1A9WIwkFHMcmZLIxPNlqnZGw6G8Taj55UNvXHLHf/oRQ== sig=RGiwU8pmufdusKm3do9Sva5Pv2CAAGQ4U/R7XaoGveQecYMMBCxFVGGRrY2oGTtpPBfMVBfyyK+A8erHcr4FzfnVaSOP+lLRIcZ88UgpYR4NzCqNnIV+K4DnttvM28d00ZJba8/JPd1jQE1N3XUmJjcA e=found last=17 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA35pJd+3URW+OhtlAnxVp0xOxLJ4L2Ld1jMKtpzDu3Bep1C/zDFD2OfXBRCUPM7sQMjDEhryjPLWA priv=MEcCAQAwBQYDK2VxBDsEOWrJoMdDqB55WIMCZUGD9+mCiqvtJBw/WW3PWeZt7IsOliRlQSQN0jriroTwCAkNiGjNUY7TNBDCbA== msg=asmgx0OoHnlYgwJlQYP36YKKq+0kHD9Zbc9Z5m3siw6WJGVBJA3SOuKuhPAICQ2IaM1RjtM0EMJsfJOYZiXJ7Q== sig=nP4STWXgzdTatEJJoE6ASGlJ4/tz+U4jlWbO/WAmL4+/89DDnK64N2hr+BZwu7MCqQSAUI5ACvkAPYCFiV3mdCbLN/a5w7CLDVw1ce7pvZa43GnVMnun0l40teHJvkrHW6W0TVs58ecO+nSGvKehCiMA e=found last=19 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAywa3rjMlIKdGtCFH/627rlKhPAS8F/cZV4FpHkrwT1p0vbETRxNGlkPlb0s1s5Q8XUOErL5yXvOA priv=MEcCAQAwBQYDK2VxBDsEOTiOU1FlELzztfF6O+2A+HfChzNtJIPF/uy1NImP2HWoOLej4bN8i1Lw386LA2N4bEOp1OwTm+fLxA== msg=OI5TUWUQvPO18Xo77YD4d8KHM20kg8X+7LU0iY/Ydag4t6Phs3yLUvDfzosDY3hsQ6nU7BOb58vEMznOhvwWbw== sig=LjUi/Wm1jogS+T2Mdyk6sjBdIiYs8kYtS0o9xsc4JTx5fs0P28pUHE1kgW0QW4OsBMNNHTaAcHSAS/j0M5aYsxhpEN/RF274GHLxbTMdVhkiqT7i7Za10pYN9owdhqeHnFlVB9EttI0C9aiLjFAkeiwA e=found last=17 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAIg3j4Gvjy86AONKVIQfWvQzANL1cXXZZvuKynv0xSWKCxPTm7oeWUqKrYVCoJQqi9iJQ0Mt+JmGA priv=MEcCAQAwBQYDK2VxBDsEOTHLrQQZECIZ4i0i+F/2IbY8SXDfPvoCyto4/yxlptrQGus6bwyfB87ZVNLVUFGrTZP3hyIda0D5YQ== msg=McutBBkQIhniLSL4X/YhtjxJcN8++gLK2jj/LGWm2tAa6zpvDJ8HztlU0tVQUatNk/eHIh1rQPlhgvNtTB++nw== sig=aY54EAqPw9aCWa7ZBgZJAm2WmJpkVSl5ptHr0ZQqNp6OYChp00fLmT7IyS/LL2Rxjyi9UFj0cy+Aa+uOWFqUWqqGUnIEawSTfJtc8S5ONxuQ90PRA8IT6zEFyqduBxE4c++XUT09Yolt6tGofkVw6z8A e=found last=16 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAHaO3KjpZ7rTEojaCfoa5B6GGFvxAIaK9D15eaqmO4xqaxbJg+YPaIKYp9dRVXl8JJSh8vGZZ9RsA priv=MEcCAQAwBQYDK2VxBDsEOQdhFnaelvvKdOnET1wm1LrMpuMVWg4LpThuC1WVsVB4mLOZVyT+Z52kMiJhojue5T6Wj+HjrEM7Uw== msg=B2EWdp6W+8p06cRPXCbUusym4xVaDgulOG4LVZWxUHiYs5lXJP5nnaQyImGiO57lPpaP4eOsQztT3FwDlSmaLQ== sig=DfHgRFMeflBk5gM41K8CUlCgBc1mQZ7884K6SlgsXx6Q2GleJElIlrSgsAyyerMM/ge7kZd8NAmAufuWuCSLQjZnQlfe/5GMb1TetV2e72hHzkwtR0THS/B0iDon8ciDL8ZnTxnrX/fkdGOU2j7Vtw8A e=found last=21 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAT+nOta4/+zd8mUQFVL51UecNeu1FG+u4kmf2gv4/0fYjhTJ1kBoNddMqhC6b1NfNNRvqtyPuaT8A priv=MEcCAQAwBQYDK2VxBDsEOf6JPBhl/KY/FNMEy86cj07jqhYiDWT3OJF0OAEAlahOmuyn5+VErT05SrtX9OcnVl681O7u/hsa1Q== msg=/ok8GGX8pj8U0wTLzpyPTuOqFiINZPc4kXQ4AQCVqE6a7Kfn5UStPTlKu1f05ydWXrzU7u7+GxrVajLWil1KOg== sig=lh1qCSkiNkdJlWdq4P3gTqyoQwZCZ5K4sd1LGkDO7FB7DSVzs9KGiEXbGTFg3vLCefHUJbSXKd4AsUITAkvD0U//MS6gCutBeuySewwsjzoTdjBzWUzGlXW2oUBrjo2mze/Fcpzpw+VWyI34na1XrgYA e=found last=24 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA/TYlnlKVLJq/BP9WWIDnQq6kDTwyZIsGMoJAiEe+xCcWLAH8G9XqO11uFNnGM5ZvjHFdlixhTbIA priv=MEcCAQAwBQYDK2VxBDsEOe2yZbfG8ZIQ/uT1FjSj4bNK39alB+NgHFJUsoQUz++aUkuWCevXIWJYk3D7Qxx4OxxXIipZK4pQiQ== msg=7bJlt8bxkhD+5PUWNKPhs0rf1qUH42AcUlSyhBTP75pSS5YJ69chYliTcPtDHHg7HFciKlkrilCJ6113msT7UQ== sig=xJLo0woC/8pb6sWLh2sl66rjc5lCtj/rrv38iTv+wQYVdNOpm5rx/HKhZGb98P6r7I/9V3cqi1KAvMILi3dxIhLwA+ZH36W5LVfbvSfexEXFjv3JejVSkuBUZLOJl3AxSINYuJGjZRlTOb6GzLgd3g4A e=found last=18 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAl+rFPWb3baZo7EByQWYHeGlInDsHbWa9mTyQgX8Xm4xVIyclZg6Y0mlKAiS/ag6wsXASmPX3GS8A priv=MEcCAQAwBQYDK2VxBDsEOYG0f+dp9+tkPO8zft9F7rSZFTEsD8xEKRN0YZy0otUbeAcrwLB2iyjC6lvptBliwQuL9rrHXtNo8g== msg=gbR/52n362Q87zN+30XutJkVMSwPzEQpE3RhnLSi1Rt4ByvAsHaLKMLqW+m0GWLBC4v2usde02jywRcAF0eW4g== sig=TLg9gQ2g4WcbBWYfxhzpFGwwNZytRvE8JW2CVjgakncABF9PwNacrOZxnJpYDT2NZ+LA5zq/5PMAskaJiZLUUHsyON8BfzZTvZsFgAHIAndd5wz8vo60UdHnSqIchjqVF5xC/STDbwOwvOTBK7PZQR4A e=found last=19 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA3iHPAie36F8ToCafOg/vh2t0qv4BNfR67f68t7y/pvx7b9zW17XA8j1jV1ycjXn4QYaWaEn7zbSA priv=MEcCAQAwBQYDK2VxBDsEOSVYYKqWGXLZbRtAJekOFvlXKj1wRuk3NSJFQMo22lQg2/0fpojnaBF934noRzNTHfEKQlFI2ReC2A== msg=JVhgqpYZctltG0Al6Q4W+VcqPXBG6Tc1IkVAyjbaVCDb/R+miOdoEX3fiehHM1Md8QpCUUjZF4LYeigrmnk7WA== sig=EZDZCbQ8V/3MkGBL97L/3MIggC/MXTr9GW/HVk6iIcH8n9xofsNEd6kTqz9oxcnfsRndk/gJu9GAxYcbWEqiNG80/rRX3xiGdSENImDAGoFZL7/GTZ5LVxzcdWfHI/+YX7lxth89MG7aM7PXVyB1wzUA e=found last=17 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAPu0z08E++ZFZVpsY2MBWvqyRpgSCvKds3DhBey0fsuRkIi4rjMm3EGCJOeSJ6yXFLPpEsJY16fAA priv=MEcCAQAwBQYDK2VxBDsEOcs2Iaq3tQGOQFc2NBSCEcl33oc985PoYBEXdhHb68KPZwe+c8w82ZwKr6ac94SdNc2ES9FmR1kOZw== msg=yzYhqre1AY5AVzY0FIIRyXfehz3zk+hgERd2Edvrwo9nB75zzDzZnAqvppz3hJ01zYRL0WZHWQ5nJ4SSS45erQ== sig=Aibt3tM6tXUHw5UlvQjpJEeS0KPWzZXHTsTQrIlOoY1WySlx1TwrwYbM02C6TzJ+mKBQmQ8QRX6AyTV2MfrWFOnZ1yUX3StKRWGouSTejRokdVtgTskhV2I0YprZeS54dLAvRfqY1r/S5FE4OSxm7g0A e=found last=17 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAG4skHCa8nTqmGo2YvCksX5A1Smgsm5Ja5f6wI0pHEgIQ9b18Du1KJBboNZKeaH501G1RalrtSCOA priv=MEcCAQAwBQYDK2VxBDsEOVINnazr3GARCvyq7/WgNFFuZUYPZ6vN2ljrEc+DcqOVOPhnV78eKRx1h6NYSIEA4XOIK+xylxvzfQ== msg=Ug2drOvcYBEK/Krv9aA0UW5lRg9nq83aWOsRz4Nyo5U4+GdXvx4pHHWHo1hIgQDhc4gr7HKXG/N9A9AmIhqBSw== sig=OIqT0Pc/H/OLIZ2zN11LDo2CNi9GJHoXeqh8f6WN/8Eqo09cb6t/u67cpz8zV0veVa+82UQQV56ALk1XfAp3yLcnJveg1PRdAQn1H3SFJryD78CnNXa5yG9taFrTMR4VhjWtCK7OC2ENgGp45dS4wgQA e=found last=16 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoABjhaMkGmgVxWmfL64mgMdzvdMKEDXnqRFqiVPfjSomPtOv8NcWAOgjtGuUWlAg2kVxcyvoMfn/iA priv=MEcCAQAwBQYDK2VxBDsEOaLMtkZxIr5FeNPsXDLk7mEDF18oKK/hP1MPNwdp6TTR7+6BiD+/D8VQLbNAPf9QeezRoTYwpQd3PA== msg=osy2RnEivkV40+xcMuTuYQMXXygor+E/Uw83B2npNNHv7oGIP78PxVAts0A9/1B57NGhNjClB3c8Lhog6gRtNw== sig=DAYJ/BYKa/6mZ1pWNWU+TBkv90Ji7ywhYW1tmu/R5lDSJEkJy/B7A4puOaSEzx65YE1FAF9bE3YAVWf7VvA2BMUjsSYEBI/M0vu03Vqiim/hhli/+tXtQVQElcSIygabgyJHGFKPxQDVCZAZiMHIWBQA e=found last=17 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoALzc6/zERjYTotZ4K74mRASGERuIIY9u9JkVJAJASPlNAgbDjVv/nM8rzfhFRghX1j8NgfsWeYr2A priv=MEcCAQAwBQYDK2VxBDsEOSzOkvhMobXk2bGddTGjuqTfwYmJt8SFiD2O9FoOg4YTOQZYSQs64DGbUWbn7R58B+Ucgkqk9b/qKg== msg=LM6S+EyhteTZsZ11MaO6pN/BiYm3xIWIPY70Wg6DhhM5BlhJCzrgMZtRZuftHnwH5RyCSqT1v+oq4VbBuvQX8g== sig=Zdu+8Fte13oxF+1Pov31trUfEbelI7QlIiQeNl1A7hSeXWqJshdMXJegOXiVi3IU/nzWTQmKrasA4UkdnIInCYidU2xBHRGsr7hDdMHv/UmyRrZVuHopi43EQlzdaAFKGnSCqiBt49vaoYM6nvD4TScA e=found last=16 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAzqD58XTYXLz36D2W/QJpWRwxyxAlev16FV7qykvsZvdwWOwa4PwlZmKF0Tz5YIFCmxPgkSDjLK0A priv=MEcCAQAwBQYDK2VxBDsEOXXbpTbdVbFejBseowJ2wF610CnwsJCa9hQLDjYEMgg/M3ittWT7ABAsbyB3JN56Yn5zXYopDtmi1A== msg=ddulNt1VsV6MGx6jAnbAXrXQKfCwkJr2FAsONgQyCD8zeK21ZPsAECxvIHck3npifnNdiikO2aLUiNdK1jSoUQ== sig=eejG9VXWuha8NjIoIIkfXWXn4YfQwn7xMLJ9aWnRH5SUqHdbmLNN4hP9k0HEFgc8YAEJ1WjVqT4AZPLvNWZXufBfO0FGlqwEecnD8W/gBCC5DW74T+Txmo3MO0tJJHCwsuNG+s3EIJZoiEDKLjGAACcA e=found last=16 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoABqKCQIfbS0GqfMmaHM186sRuk2KrJPaiYwNnu6RH9rTWCPC03H5b3iXW3ErYN6Ybhzp22LYjtjwA priv=MEcCAQAwBQYDK2VxBDsEOb4VxAw6/o6bzK4JVWssHionJVcfn34VBz/moidbQtjwcxEPNP6K0YJeNHHce5pmdzpIsUi5o8Axaw== msg=vhXEDDr+jpvMrglVayweKiclVx+ffhUHP+aiJ1tC2PBzEQ80/orRgl40cdx7mmZ3OkixSLmjwDFrXYBdB73rBw== sig=7RCLp4Y6s7VbvEJ6RbtyRZrQwSOPVgSaQoF4GfNVxGEbKUw3JxRB9E4upmO6P/a+wduUc9h5MTIAvR5jfQhNX60kfMF1AdZv+2fuJRq1f7Alw/62AdAE5pO1txFdv0z/rCOeCQSfE/A5rMmeJcLOVhUA e=found last=23 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAu8l5Jboq7sWEdbB+bAokEnxF5SVUJCNWlBb0LZoKzJgKe+/EvAV9E0QHSgwB1lHclC8amQpU0MOA priv=MEcCAQAwBQYDK2VxBDsEORjU85Q/qVYUyeLZ/6fZu+7IIkKTnz4uFqQ8EG6bkOgx2RXBNHZyftKyAIxTxf6R7Amd5N1dpizxdg== msg=GNTzlD+pVhTJ4tn/p9m77sgiQpOfPi4WpDwQbpuQ6DHZFcE0dnJ+0rIAjFPF/pHsCZ3k3V2mLPF25qGN6Ye57A== sig=WTZAgZ9Z5cEPrj6y9MIGeGdXD+0lmF48YWaF4nwP1I4QconlCFVEDSph0DlBLjdDrMALVrXEsLkAtdtLbjYEZb/yllZWnhQJtW6T6bCKOTKwcqK5jZv3w1SLJBVHol8zgA8otg4+rypIDbaEmdRdEhkA e=found last=16 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAh882SwgsB5J2ozu2xbEE5WqI3BL+UCmBZmPVdX+BgDz8VRRPqY2QDVPaZhObgMunRL3GJHMm74YA priv=MEcCAQAwBQYDK2VxBDsEOb+B/IM5txcRzp9OcxSDa+uW6inXIMKUqp4ASfHGwdav5csUfZtdCdHxN+mKI9QgmuoXILvMPN9tpw== msg=v4H8gzm3FxHOn05zFINr65bqKdcgwpSqngBJ8cbB1q/lyxR9m10J0fE36Yoj1CCa6hcgu8w8322nKXf1ZAf9zw== sig=zj4bGCOgweT2GvxLgLB+ImEBqE4IFW0psthGM8Sx6TYhC2nOgBniEwKjZdhliCvhlHMScjNoKlAAWAV57/jRsLq/9eZxqwi6qww2qMQeOHNYWm2DNY9qK3mo2wD6W69YWjuGF80BaWi20DMQa1BtdSIA e=found last=16 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAHefNxnRCHdbw0rsdCBdWxylmOehVGF+7kBbGpZ0+qneqx1WalmM9+jbyxbYS7UbvyreyrzlauLMA priv=MEcCAQAwBQYDK2VxBDsEOdK8cTeRwK2d/BQa6nihnaunef2HFX6ObMyWp1+vr1mHnK2Qh9PWTpc6tRMVq6jLT65T9WuS1RNaFg== msg=0rxxN5HArZ38FBrqeKGdq6d5/YcVfo5szJanX6+vWYecrZCH09ZOlzq1ExWrqMtPrlP1a5LVE1oWUiSzErvBzA== sig=l9E77JQSmqRIHtvT+8fmj7BjI44/KElpCf/GJJjrXmPVNYRVU/etatnXM9xqy7FBBcsh9z0iI7oAsZ7RhU8zBj+q9j/6uvjRepsWxrmpKbF+PF9DqdFj1O4+ebx3xTJU7VWp3fERnmqQ+B1Sd41WVRoA e=found last=19 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAZ0YKJliq76Poc5JXT3h+VM5guFTnfcvCf4y5l8RMj/Xp+rQWYdAPuLI9Aki8K58ofoLdB5nmjOKA priv=MEcCAQAwBQYDK2VxBDsEOTqH039AGbLDQJmxAW1czkCYw9pYBUApoud8bgvA0fbkv07/SG0FS7M3H7pJTlaE1B/DEVRgp5yhAA== msg=OofTf0AZssNAmbEBbVzOQJjD2lgFQCmi53xuC8DR9uS/Tv9IbQVLszcfuklOVoTUH8MRVGCnnKEAsP9OgV5hPA== sig=vDlK3Ws4L5p2pU4CtimfyOwwFgX1Akd2ru3mYTXykX/9ox2CUbA7ZoddYRC1R6jZnhD8oO+Pik+AyLl+RFtJArBEpbd0fB/5xSBC5/Q7iFYYINNol5TsftqF5VaEdpRarOcSsSJ870vOXRN5ug+2WycA e=found last=15 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAsMxm4KhAXX1eJXzWUMONbuROHEYd35O9EZ1sCMx5o/aaKLGDT7aZDGC5cd+/uax03zVHjEkRjFYA priv=MEcCAQAwBQYDK2VxBDsEOaqOy8uQ93dh53wN57dUOC/awp7mvoOM+o8NYk4ccUVcAEVALrzKpXR11cWuk3uey5wnJzSCPia6KA== msg=qo7Ly5D3d2HnfA3nt1Q4L9rCnua+g4z6jw1iThxxRVwARUAuvMqldHXVxa6Te57LnCcnNII+JrooSUlDpbWu7Q== sig=5v10lvaEYxS2xpcjA/I50dCs4tfrX44Aqo5US4ZOG1YutmOzjgGFCy4Ln3J8ve+sxFh/I7ml03eAYVSadp1V53Zwf2Z2GAndNDuQwV+/AhW7Wg+CxEOyibZLeaSLmEgCvQ0jqJyC2Lr5n2i74JFMWSgA e=found last=15 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA4LLqt6igN+01TlbcJtkaS9qwDEFWJrDmha9Fgoaqjmj6XDLo7koDqr+48/idHtRbaZmpgx+NxFIA priv=MEcCAQAwBQYDK2VxBDsEOYIG0ZNIj9n0jwvIWQTphzk74Q0OAHregiuyAx57FnLAdrD2GSd5YYDevTX9uPEDCxh5GJAjWxMbhg== msg=ggbRk0iP2fSPC8hZBOmHOTvhDQ4Aet6CK7IDHnsWcsB2sPYZJ3lhgN69Nf248QMLGHkYkCNbExuGBS5lxYOr1w== sig=btz+CRgkqgNVfMvCDtac/wetijz4IdNZDuRJp54nYViGqNLzVTgfsI7LDcK0jmo3kq6E+DsrKK4A7xnwK2GiBmEFJcIYbIVNY2/zJcFRcLweZnncDF6OjNZ8PrgrAzD1I4S1mYn+N1wEpCnCv6EJawQA e=found last=16 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoApT2D8aoC6OTidW0uAwo2gTtpt2fWwLblC6pMZfQY5XFClONV44zeRp5PGk+AVO/t1WQEcYRk2giA priv=MEcCAQAwBQYDK2VxBDsEOeuPGnerOPz3FFH2bEdTkIzolStZwejQO0tNmvCMfx1D6vP8wMFcVC5rBrqi/jZPjHHOFTjt8Vie9g== msg=648ad6s4/PcUUfZsR1OQjOiVK1nB6NA7S02a8Ix/HUPq8/zAwVxULmsGuqL+Nk+Mcc4VOO3xWJ72Uuz1tCt2LA== sig=kl6w2mo3N251O8H00lcGGe11b8oykhgvm32Un61QS8YDkKbYdBlk3I5sQe74/aE5PrFbSxfdCJeAaChz4udnc75jel9NnhhByMC0bhwM77twdW4jUWb7j9b3t5yAuSOE/ZhjNp5b3DUfUyXbUVzXgBsA e=found last=24 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAjdjfYO416KBdkNFumswHe7M2r9XeuNKoMvtacvJXgIug2jikqf8H7OwVwQHsMJ6+vuti4x0rW72A priv=MEcCAQAwBQYDK2VxBDsEOUe120f8pX9CNSjrIIrlfH+XuxsijyYIRGHBkqOML+5L+ftHlQqDehvET1HJucyuAQbitSPUQMYBhQ== msg=R7XbR/ylf0I1KOsgiuV8f5e7GyKPJghEYcGSo4wv7kv5+0eVCoN6G8RPUcm5zK4BBuK1I9RAxgGFk3rv35XwCg== sig=WFnNLSJntNl5RoqxTVUytAFACKjrxXqxShn4s40WYYGOHG6d4aYsskIRRO4OLBKTmXM6hp4P+lcA9PVBoyeV/GznmGmxlnWH4mKp9ZYaJ4yyIzVMfKTWupUjF2hvCaro6z61uvEyHLjd6v74ZQEeUSsA e=found last=18 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAQZfxOisrN7s3yD9yqTulokAZ2kEe0c4zyM+PByUx3lbG1c6M5Nv3xVKGOMNsDrsFhTHPgb0ReAIA priv=MEcCAQAwBQYDK2VxBDsEOUjmgK9uarakuO5YCoLGeKpsh4Sfmo1wVtz1Fo2+2AMUdUEkcTv7T0mMdy9vXkrkW4spb6abKvbssA== msg=SOaAr25qtqS47lgKgsZ4qmyHhJ+ajXBW3PUWjb7YAxR1QSRxO/tPSYx3L29eSuRbiylvppsq9uywmqV/aAwIYQ== sig=XzJSbhLBTSz2Umiiqu9YVC8kTm209EKmo0boLgNMrOvrGTMZzEEHS1/zT1CRcc0XUP2CmZugNLAAno+dmx5PAj7dkLQSDF1TBRYAOnqXBOEQe2ARnM+ECs0+h3gd1+mCt/byY+LGY8LPTdcf2p4WNRwA e=found last=16 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAeKq54r3/bZmfl7/LZWZMutwZuLNS9TCPU8o+Bqmn0tC9qQIyMR5RK2uu0RWYd7spsHbqUlZuF9MA priv=MEcCAQAwBQYDK2VxBDsEOcCc0egBNEymurXeg3jRRpnAIFY3XE6xZu4Spzr1P1OnhBHCI+rcEKj/8hMZgNCYuumz1+NULN05Qw== msg=wJzR6AE0TKa6td6DeNFGmcAgVjdcTrFm7hKnOvU/U6eEEcIj6twQqP/yExmA0Ji66bPX41Qs3TlDqS87ghWPYQ== sig=jHwEVnOS6FDF4oxj5n7lSXiy4lJMFIGwcjhnmIXL4Mop5a/ZF9ONCj+0luyM2CxcfS+Q+HOfqiEALKUWT7q+9gApVffImHqD28qeOx9/AFzrx1e73dBgROIQ31jFjdIplM65/vrai+D4IWRUYRRldTcA e=found last=15 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoASKo5baXqtB0c12551yM3Z9TzNZIjFYU9Pme4Q9vLwDXvQeJID0A8sRa4179dwpl+Wy7XPAqVLz0A priv=MEcCAQAwBQYDK2VxBDsEORc6EZdjJZ82JmGU+tndI+51CZl467wi9gFUFjScNwAwHL+ROopRMGsxOWiNCM5abWGo0gEe/m8MOA== msg=FzoRl2MlnzYmYZT62d0j7nUJmXjrvCL2AVQWNJw3ADAcv5E6ilEwazE5aI0IzlptYajSAR7+bww431x9klA1Eg== sig=OtHUbhtz8fd8lynDi7J3JJN4b5h8dgz2kzMiANKIxNoFtppd8Ck6mzzLdmgjhvXXf+N9jLN412yAi97Dzf86C/vKkb6uQF4zTHARLAoCBUJBmMDsIt3kOqVmadKnGMT7iICGaq+1nVyY38HjxaYCNRwA e=found last=21 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA9+ypLBl9VISjrb1ASliRxXiTJsbXP7qClV6yaHIxRSOzKfW2ScxbMw4h2kmibK5t9hNUTzFodvqA priv=MEcCAQAwBQYDK2VxBDsEOehGpmPVI9pRWBdx9335jOiVxeF9Cktmo7TZPONaYokBjDlwEgrYn0vxhziS5j2Ll8bltz6FMj7Ugg== msg=6EamY9Uj2lFYF3H3ffmM6JXF4X0KS2ajtNk841piiQGMOXASCtifS/GHOJLmPYuXxuW3PoUyPtSCdO2Ayv5SRw== sig=P5ZAO6MSaCkOZvGqHll9Ps/iU6YaJ5UN07xp8JJGJYAx3lyDP+hUW6GDUjeuEzAIAZdt4YLQ11YA/nud85xVOUkRhTrjyIimC0E92DR0pJWfgiRGimtpO3VvE4MEvBYiMmtqhATUV3sZnfnf0adzlBQA e=found last=16 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA/hDlzFYBpXZWtnJ4drHUyXVeXK4SQ6JGudZ9lX7QONIyppB5E7Yv07AIbZARhIWtYB1oBJUgZ/eA priv=MEcCAQAwBQYDK2VxBDsEOQyvFoaRD1i0u1O/LTNuH2lDd+j9BYKPsxK1Tf8XjllDQ9MivqnfYf2c+GqQskN+8SgGC0LMeL7tOA== msg=DK8WhpEPWLS7U78tM24faUN36P0Fgo+zErVN/xeOWUND0yK+qd9h/Zz4apCyQ37xKAYLQsx4vu04V9cP76ByKQ== sig=CYY/4GeFsnQGZTLKm6rQxZjKjcq7fP92JMpgVrBDVY4t1c0w4Gugw2Cms/In3x1FMrzl+/+K9LkAgqOHBT2Jjtt36/2wrwKgrgpz+1KTjgMnIOGEGSGRlolpTAsEZAcjRMC5yevdPryMsurub+i1vQUA e=found last=17 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoATL+YOf9bmo57NgRm4RVx9C18THE/NqBY3198Bfo9McCIMoRBDWH7LDZSSsuvpZBY2cVmFDsKwkAA priv=MEcCAQAwBQYDK2VxBDsEOZ14n0t4Q6mAfZgc4/SDiKRUmP1p2OLSX5ccpG89DdXwC5XEZqxJ5bbseTf/5Sb8PSWxNLZiNmufxw== msg=nXifS3hDqYB9mBzj9IOIpFSY/WnY4tJflxykbz0N1fALlcRmrEnltux5N//lJvw9JbE0tmI2a5/HDvtFYIreNA== sig=q5Lok0Nvp93ZcMAZasPBkpbsck8WJ5Icdmo8pilKw4CYNhVnM+ubxRvtG74aueyX15pYtrb+bjaAg79SC4sFviRWUUTYgdW4So7o9kIORM36zRTfPFsayjMM5ppE4+sy9SYlvzfN7Ub8aPvz/ZkPly8A e=found last=15 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAEEOYqrffZQnw0yoCxUuMW9/UBGL5CMgPv4NLN250DfZKiHDsKYwi+4mDnGY0BYsI3Je6jsT517MA priv=MEcCAQAwBQYDK2VxBDsEORrLxAn83XbJLOWZc0da5fSAe7+moO4+LERGaeDNqpO8PAJeJiIqNvfQFhldiRPUK7g1rXwGhqrFng== msg=GsvECfzddsks5ZlzR1rl9IB7v6ag7j4sREZp4M2qk7w8Al4mIio299AWGV2JE9QruDWtfAaGqsWehdtmd/jJoA== sig=rgoE9+8CGzq+R5PkBF84wHYfTeRkIXitCUKEhJDrPbk2VMOSVIYD1Fy9NUKQrGRWE15OCykwtDsAd+a2z5GorDzmeUhJtGpw1NL+NfASnTJfSWHRwUCxxgT6paxdQ9WeKa9MD6ggwUgfdmM5yUe9KgoA e=found last=15 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAoS8MArB0JzAL4kk8k+F4Lg9GveH1nur8UukK1FB58HsBE4x3j//TyQN5VnI9RZfx4wHdQ1m9D3wA priv=MEcCAQAwBQYDK2VxBDsEOT1N2sUAI6dg4tJPvIH+nhXAK6/u7r/Sm2D+TBQ/oCwz+TjqCm+bf35XEtUiRQGfddI6RC2RP2c/tA== msg=PU3axQAjp2Di0k+8gf6eFcArr+7uv9KbYP5MFD+gLDP5OOoKb5t/flcS1SJFAZ910jpELZE/Zz+0HgWoLZL9Mg== sig=SA5o+g8CiJVzAPEvasWDRbZNefvf68NPkLQkZhjdCgl9LQ2eO6lB6XYKu1qJLI/mnislZJXpmhuArapzDkIWSq2dSAHbAEay3SI7LuCsWMLxR1ph6tjElnFLX/2h6AqIJElTKv4RX40S+CPLg22I8wgA e=found last=15 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAbVbvEdRezMsDHjsSEb42AIu41xAxzMgESnS2sXlfOsiZsfnVTjU0W97ZVt0WVByf/RkA2A/355CA priv=MEcCAQAwBQYDK2VxBDsEOfZMC5CAnY5IyS7YjO67yCFvct6vtKEfoI9q/PDZ6TB9zQah4lYHY68JkjotP74VtCIfS8uP8i6F/Q== msg=9kwLkICdjkjJLtiM7rvIIW9y3q+0oR+gj2r88NnpMH3NBqHiVgdjrwmSOi0/vhW0Ih9Ly4/yLoX9m40QWAnLTg== sig=qOJQ4LC+eheb9onT6tl+4Tvc4mOWAlOAxntadyr+pKMJesFj1WjA0Dm0qB+JlfYI5zdqIfs1LZGA3zQcVWbBrjVSC4wYxl0yuStD8W4SnDcpN+0i6/WNlprLBl1/xPxNGhfOWuI9lUr7y9EIQYHoZSAA e=found last=16 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoATLPcMUohH74YtFdB//gl2t9gvB+ZM+0fNPztmO5bmmOhPwv5Fhso7EXLKme/hWMywuGHvOVM84AA priv=MEcCAQAwBQYDK2VxBDsEOZW69FICm53AsE2PaB0k5IdY0iYh4NH1ooAw9r3DpH80OA+rbPje77eUORdBk6hZGu1MxmfMY0AeSA== msg=lbr0UgKbncCwTY9oHSTkh1jSJiHg0fWigDD2vcOkfzQ4D6ts+N7vt5Q5F0GTqFka7UzGZ8xjQB5IylIMmlbQdw== sig=3FwgPe7fnW0WnYVt7SquHErpUW8DFCWhYOMHUZucykMUJ7FTFq5CeJadmxgyFmLLAdluA3WJRywAWXCg9KLSZAWgiOcUuvHsUs5oggrqSw4e90t7tzc04NfVqMD9Er1WFEnPABjwy200cMvwiSq1VwoA e=found last=15 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAsisnV0aAjPRfnGL+Bbu4BYAaFmDyboBx5zu96kzi70LbaAdzsbAy1TOYUE0BKi0mch5LlpflzvQA priv=MEcCAQAwBQYDK2VxBDsEOUWTSjPvu7xDfsAmxiE0JbfLyOU4ubdw0yPh3Y9ZYA/JPPle+feNgKkMIhoOPShjUR87huc0fu3PZg== msg=RZNKM++7vEN+wCbGITQlt8vI5Ti5t3DTI+Hdj1lgD8k8+V75942AqQwiGg49KGNRHzuG5zR+7c9mJBmTzm3Rfw== sig=7Y1GlrrFx++t4plXKcYPwu11TXZDixQuPbOgqYXQu0e2FOVwmEkboQQzn6L9YoshN6ZHPhSrziwA28uxJbX9/KcSco/syRWqEdCG0k+KralLwsgA68Db28r02oZC7Ui2Gel7nBhFk2+XNsHwHATVvSoA e=found last=16 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAAG2JW3Ks/3UpaaJdtJ00Mcd3z3fRm6kusJSj0GxuQa3SY3tMnTw5OEPDaptoc2P7IN4+C2dG4gSA priv=MEcCAQAwBQYDK2VxBDsEOaB0RX3QarLqEkog04NM7f2XhXD5mIz3q7vIK4Nkci79wkcVA310cHQB2H/OxoXPU+QaPh/cJrOlzg== msg=oHRFfdBqsuoSSiDTg0zt/ZeFcPmYjPeru8grg2RyLv3CRxUDfXRwdAHYf87Ghc9T5Bo+H9wms6XOKNC3qjPOgg== sig=9XDeXuHY1dg/9m8v2BUp/WKhgMup+YaSQpg+03tmK2z4Kj/PNSzQuneQyBzBKDDQx4rooLnzSwGAK3t7lomOIteFXryf9VzNMFOKX3FXDK5eeb3x03RL9osypB/TrKTDdsteqsWlF4YoSq0Jl5+F5SEA e=found last=15 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoANIpyFBPKzUJyZNuBBCF95TLR9lswwTNPKbbknZ6tH9/qaTBDKWDqu/2DYhf6bezA+BfAI1eVMDiA priv=MEcCAQAwBQYDK2VxBDsEOZnY8weTbePD2bYrBvdb7IacXwy62htpMCQA4KkSLq0J8cbDLCCyUT2FuNm3vX6mJfLyWg2dKWW6/g== msg=mdjzB5Nt48PZtisG91vshpxfDLraG2kwJADgqRIurQnxxsMsILJRPYW42be9fqYl8vJaDZ0pZbr+joy52/tC/w== sig=iRh098AqBs7p5LD8HIe/2giKJwyeaG3rg6DAGKyoVxplJa8qAqAFr3Qrp+jopzMUC1uV8PUKzXiAWij2XZuOY1wJFfymu7K1wdSjNuLKyHNsHwrJ4O3Hzk0U9joRbLXx166LXhCW0w7DU+Wd5OEBSh0A e=found last=15 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA619kAJsNGV4NSTAIAGZUKGn9PyIQq2jigu0LnZ0+hwjZozYSOqbayOLiQXAJYdJnDet+6T1h53KA priv=MEcCAQAwBQYDK2VxBDsEOb/xiW7iZQiQYlfgznNDCGOi0l+ZWIkSGCc54eAxpaaKXyhn8gxTtGwq+FvTqpSL5OI7c2lNgvfPuA== msg=v/GJbuJlCJBiV+DOc0MIY6LSX5lYiRIYJznh4DGlpopfKGfyDFO0bCr4W9OqlIvk4jtzaU2C98+4unEPgzEkJg== sig=GsSEeCyObDFP7x1j1X4V2/gz0kYiVwBVStv+6PDWzXxmfsWgJ8Sdhx2Qc/XwxS5ECFqa8n/nViKAtNGagNoz2GZ/+EH58qjAuGTH0v1yv+RL9cVoEqxUnuGUESOCY4S1k8t12cMas+fpE5Y7/dQf3ywA e=found last=14 s=1 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAbEFeCRGpxN9afgG86y9sKv6Nz9X8BfExyS4vceYnbAoxCzzjdOSsEY7Z0rY+uvR930pizLqv4i8A priv=MEcCAQAwBQYDK2VxBDsEOWWEtmlLRYg/yoepBYr1bYM9RQboqw4+vQpqaoiBCLUFugR25eDN1P0wswi8VRM71nUuTxnAcx/6og== msg=ZYS2aUtFiD/Kh6kFivVtgz1FBuirDj69CmpqiIEItQW6BHbl4M3U/TCzCLxVEzvWdS5PGcBzH/qic+/H8sQcSA== sig=YWN9pf9Hvw00UDRlOut488MMnvDvlQTlclEUKOB91EkPMxEuwAIxUySd3LjbxnhbATYmKXY8OHOAbRAuYcdiMg4hRG5Z4aY3fKkUv+bpgojmT6uy9+D75bDw2WGBlpguyw2eOq0oir/T99A9IUnsNxoA e=found last=15 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAhXwjNtmLP/d0eYeRJfMbh2H7Cfu4GZbpKN4SBnJdzhM3QJAfu1XCerdGwr/QzlOI1pjuPjwPkZ8A priv=MEcCAQAwBQYDK2VxBDsEOfrmVI2W/QFI8x3Ib4fcl38lrtNK+ztLjXMY1Dp2LZR8nu+yyrchNk7T/h4G5tHTst32w1lqPBARgA== msg=+uZUjZb9AUjzHchvh9yXfyWu00r7O0uNcxjUOnYtlHye77LKtyE2TtP+Hgbm0dOy3fbDWWo8EBGA6+5QcCualw== sig=eawwbDZ2wVO6y3k7rNoBcISa8sTOuNYoB0E3cBjrPBN1IK65V8VwhiubNKzDOWQXZxKlSedM+mGAXzVbmneh+OAPFjub+27WOKGRvqP2f91DWNJ4vCGaB5eL8FWtpYRnLtmH87QKvqTrzk8TzmxJNRoA e=found last=16 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoABs0enFxLDptic0LW8LT9uI9lfO00zA4KCKgJ9dmACqm3SivtKAwYwuPyQJGy2VeSkydWS9aS2o2A priv=MEcCAQAwBQYDK2VxBDsEOVOAAJWg5Vn0c0qcVUl/oqksq1ZcLcDRh4Oeq2+n7Td/nB8BlyL7k/OTOil0EO8KK5YJwoQKzCn8KA== msg=U4AAlaDlWfRzSpxVSX+iqSyrVlwtwNGHg56rb6ftN3+cHwGXIvuT85M6KXQQ7worlgnChArMKfwo/o5I4Nj7Yw== sig=X5plG8WpqjUuCrCvvWvtKBdLsjp44BghioikL542cPnAmdbvLXJ0fUp70YzYsx9HQGzwElr5nTwA9DlO2rarn2VdMtSn/nGBE6vIvPm2M8wMZpz8aM9kzIzdDzzbFbyaH0U4bo5SustAyP0v2flczD0A e=found last=15 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAyOecTV7zJinzeL6y1dRt5+y6DwYwj99CvsQ6jHJX8CDniHI39b9YfPa1vwdgMuMErSIQGkbnmzYA priv=MEcCAQAwBQYDK2VxBDsEOblJWoncSAdzX+VRAZGSdZBNydadJY3wZnlgoRjW32sqOLFo1iW136vyNxmK65Bw5aOOMT8PkXM01A== msg=uUlaidxIB3Nf5VEBkZJ1kE3J1p0ljfBmeWChGNbfayo4sWjWJbXfq/I3GYrrkHDlo44xPw+RczTUnbdZVAtgPg== sig=ePJGQoIj0SCu3lM8zItk0cmnDGfAIjFLbI0pjAmi3dPxeQB4rKwR8MuSg+Ec24maE0UuKcd9I8uA9UHLx5Brb1LVZtqAWptG+ykZva9T/NdHI448R6uWxK6OgSykR53BcqCTQtGFGTaNhbrBkbb33xQA e=found last=18 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAn61dgdtK7Tq5rv91fG5U8qU80USV3xYFz3AnlLFsrRjNVkjGMT3UMdU2N2SuFn4DjuBe7yGcO2eA priv=MEcCAQAwBQYDK2VxBDsEOWo0TcRijUdbA6XQErem4aVSKSS3QNVlFhLYzkkd1L9cfz/L/VHPirOvFAaG89W9aHijIuYAH4FIaQ== msg=ajRNxGKNR1sDpdASt6bhpVIpJLdA1WUWEtjOSR3Uv1x/P8v9Uc+Ks68UBobz1b1oeKMi5gAfgUhp3zQuH9oX4A== sig=2f4PqmULIMAK+Hycd3GJ8oDhQWl20gnK3xe3Jfvve064zTIGH3x4FtkgQ3Pn6n7ozd2Z4p6Q3ZsAKYAlGyktiCOF0ZloIyb1ENz4EcGpLpUE9SRTqm+9UMvyA21d4yViIPTZfDZ/ItiHWbn52aqjwS8A e=found last=15 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAt9aYhqMu34v08N/QBPPVXV9Rd+a5rrrCdIhQfmW/Z+f7DGseGkXVgvWwvn1AUFh2Ld6e6LWstrWA priv=MEcCAQAwBQYDK2VxBDsEOUmJyQLmXa7snBDEmUmY1Zyp45r2JZIc8ETfB2MBPd4TDwMXhGVDYrtHm4YQUVyWtIXZbe9wiyXZ+g== msg=SYnJAuZdruycEMSZSZjVnKnjmvYlkhzwRN8HYwE93hMPAxeEZUNiu0ebhhBRXJa0hdlt73CLJdn60rGXgE9VWQ== sig=yzicqobQEwEde05plEQuhKhIDnZETuLDnXg42AYezXsjbFheIj+XtCJRJ/U9w+YTd7uFqfJsGCmAAehWQc0h6LB6fKew92EpmQYDti7O16KA1CZgPJbYskClsoWzSwVJQeaSMJwbolEoUqPedzB5dzoA e=found last=24 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAskocm9KyclQXnQLwzokY5LYrhsOcWfTZYW+ZtpmRcHvkptWTPDEIw6kbPL+yiaG+EROPAQB8kyKA priv=MEcCAQAwBQYDK2VxBDsEOQv7XUCIIHnyViZK/MwAXFKtVho5S4mI84vN0AOtUcKZMVA7bLaj23lDKgtSVkbmqj3L+C1n4GnYpg== msg=C/tdQIggefJWJkr8zABcUq1WGjlLiYjzi83QA61RwpkxUDtstqPbeUMqC1JWRuaqPcv4LWfgadimz1EZ885gxA== sig=nWZanlI8lx5vLOo8EC8dG8j9s0HbuesNfQzw8bq22p+WhPNcq2pUSC6da1OvFwGYGLBHu3W2P46AfwXEGP/b1RBqj2Bs2Qq7xEBQ5LAz/L54T4F+17G5KVgnDw8h4xZdxxzoIXVw45FwB11cnZ5kMSkA e=found last=18 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA4aybARCp3EWnj2MfEbPjtDnTk24VQtC4YbkY39bCBEXGZTaptdORnRlBCenOKzM42s3j0vTaxbmA priv=MEcCAQAwBQYDK2VxBDsEOZwBMrFiB2SaVyWlUL4EUqq3XJ5p6h9tliN5xKXM7FGFOSn/Jy/mtnG1OUz8D+6+34Ot69IgcvwevA== msg=nAEysWIHZJpXJaVQvgRSqrdcnmnqH22WI3nEpczsUYU5Kf8nL+a2cbU5TPwP7r7fg63r0iBy/B6853/ef9z5ag== sig=Tdvo9TkmU48yV0+78vK+6COSUecHX3MPXiofJNbrA07mF47cm3Gy+4PGIBqoF4veDa/4oPeu+BuASJtlJS1do9DYU8MQUFC8sHOnBdYXtpV0cQCZVY/MJDGRBPWz843BTt62vwUPfqnVaOJ9sonbbiYA e=found last=14 s=1 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAX4YViSbNX/juzXRBCDMMeuIb0RHkzafhcf68jdCrcgHUr2CnPY03INZhIKli8W883OeIewVxp14A priv=MEcCAQAwBQYDK2VxBDsEOQhBOyA9+J7JMjNLA9ENwNCC+OZvi2bLOjZmRO7kD73UM50mQzeNpjC2Rz+BfvmFZZmJUnv6tbz75w== msg=CEE7ID34nskyM0sD0Q3A0IL45m+LZss6NmZE7uQPvdQznSZDN42mMLZHP4F++YVlmYlSe/q1vPvnvN8tk3o0Zw== sig=LPiYZmqvdybIVX0PU5/tbFbO80RtnhQwwVVR+stl6dvd1mxKiqvsHMTQiUcB4NBqgueoq8f/o9oAnR8585uDli27nRMz2nZO7Ri5SC0SXnu92DWObpQB0KlROfih4YpZnBPt5eynukSrCUTybyKd+DYA e=found last=14 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAXw33agG4LXoYuDyl2FLdqHtUlYb7/4h6nxGyo8EjT3vni+ZVLcOmo6LPGeJO92HbA3JRp4KDk9AA priv=MEcCAQAwBQYDK2VxBDsEOYLH48QjuvTPi0UfxMPViROf5zLyhL/Lu4AvFV3TDJGvP5n+hu2YjI8p7dEWMRruDQW8BW6ELEZjqA== msg=gsfjxCO69M+LRR/Ew9WJE5/nMvKEv8u7gC8VXdMMka8/mf6G7ZiMjynt0RYxGu4NBbwFboQsRmOoomQChXkLMA== sig=+duSEtYmVKaXZyJdOss8Ju3Vrl5CAfllkIFiOH2Rn+UNeNqnaoa3QgfH9MLeDMgiRuTYfAsVz1wAhN7RjmaM4NOSqiZi4xuGk29IZDLRLkLDfnonEnzeGv1JG+KYltx1LNc3/vgdOAC8h5ceOCGujQgA e=found last=21 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAYolacTbECdEqMXwxB70XzzdWvMwwIE0QIqefdEy0qEoXhXklFSvk14tNI192jVey7+W4SD1NjFUA priv=MEcCAQAwBQYDK2VxBDsEORyx4iZbXIEF69LezFiDggwWvdP6FqA7vofVTnEbbXe0ormrXKABnYlRNmDZVTYu7CRdXjpo3JyzBw== msg=HLHiJltcgQXr0t7MWIOCDBa90/oWoDu+h9VOcRttd7SiuatcoAGdiVE2YNlVNi7sJF1eOmjcnLMHJn3FVLj83w== sig=cRnCXUw16LSUWMox8KSsuJ+vOJunYSAbzO/iPOVPX5kBvbsKDIzAPj4XGV5rb59Z33lqSpIkkMUAVPn+qPVuwnfeGiVZ3LqWAbxzigpB7TOB6tdGUl6Od1KD7Qguvg1xXyot2BSvj7Xv5vZlEVwtYSoA e=found last=15 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoABtBjcAFs43ZewZ/vR+C9Bu0bUYqIRq2IOePDAU1V5rYQGRtFcezncpX7sWh7h7JmcmdlvPN74bkA priv=MEcCAQAwBQYDK2VxBDsEOV9Q4OSIjsw4YxtumvtiaG4bN4LY8wD6MGYn110roOdfdfZTyh2EnYbOM995poQzpjO3hS7TEfFjmw== msg=X1Dg5IiOzDhjG26a+2Jobhs3gtjzAPowZifXXSug51919lPKHYSdhs4z33mmhDOmM7eFLtMR8WObvdiHzbNzbA== sig=idyWeXB4gTe0xhdg7DDhtMdV7c6opJPM+zS1ymirKZaZuGRcyYbIEUHBCX5eQrW80mJ+3J1BtriAc0Aozmjwz8EZepkU+Q3O8Ks5d8UmGKzX/+u/UPmftKirsdd+RE27BKGFJp88ARmeN6pMy+LTBRAA e=found last=14 s=3 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAd8x7enbNJwrpHMhO3rD/xCxpYv99IaQDh2rhdxYvZZyKWpkxaV/yZdKPopB+9gZ2R3dOudIz3ZAA priv=MEcCAQAwBQYDK2VxBDsEOXZ+4HKyX9e+UJVsYkHhx8DG3jVtfiMSj5HhRqjtT6fG0+Ticz5t3xxfKujLb7jLoD0GpImM1RdnqQ== msg=dn7gcrJf175QlWxiQeHHwMbeNW1+IxKPkeFGqO1Pp8bT5OJzPm3fHF8q6MtvuMugPQakiYzVF2epxEWClUURGA== sig=GoyF5W7jrjtjJt5LLR4b710iuCLq33XHkA6ULqEbQHXuS8jfSfBpxJC3YV5lAZkMSYq0z1rw7C0A93Zbu3WB7rmJ00oDgH4LOxaTOmv99f4G6QhJZ21zXO8sKc3Doglu5t/icg8DO5XNJX3dlowwAhgA e=found last=14 s=4 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAoJj28UA+WYPmKc+mOmFOj6mN8DzGX7bpK1utEPdazYBRkEmjnKGOT3x4RW6QCWFxqUCN+UxPMl2A priv=MEcCAQAwBQYDK2VxBDsEOZ9Pabf8pfrLMScRugbYGWz58MelNoVmuLvfrg0hOJdO741XuvmqyadDmJsNzGce5RguYfYF0v25Vg== msg=n09pt/yl+ssxJxG6BtgZbPnwx6U2hWa4u9+uDSE4l07vjVe6+arJp0OYmw3MZx7lGC5h9gXS/blW3n7KhGd25w== sig=5v0iCUlgRBBW+XzrHSoBkV6tmV+WWf5Kuk/sLySrwGuhJcHWVKyfgcb8jYeZVCLxTub1lWI1LyyAfLjahDVZyTWyofU094D3xzOvJ4tHnZ1xYzCgryLhVfZs1ZTqpOxjReb/+foUEBqg1GCuFHkYjiQA e=found last=17 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAkHylBfXfVrg/vlFVs0+1tNvbjPQh89e9bqntsv1ySz+9bOIBNE2T5jo1mwhHK8ku4PAzKd7YAbkA priv=MEcCAQAwBQYDK2VxBDsEOZDY5bYuCPvqsnYN5784Thc3ypsbWMPv3sXcNr+4+r8jliwWWYQ8N6il4mGJh1lYJViIMLSOKx6MQg== msg=kNjlti4I++qydg3nvzhOFzfKmxtYw+/exdw2v7j6vyOWLBZZhDw3qKXiYYmHWVglWIgwtI4rHoxCrCkKPi2nrw== sig=vggSJir2gJIAL+XM0zGO+cm7vBYvCMIJix7azSRDmiE8NoMmbDOg/b8A8NrUJFhPx9QpJgSpfLSAHOGadIklxZ/dF81YaPdgrOVIvH/KiI/G41xhfYHM2JAZKPBgdAuOXURN+YwsRJ50S/JbQMsgJAEA e=found last=14 s=2 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAmvstzXVHgLeLTod3Yf/I2r/rABYbQ5D66SFw0SH6rohL8/cN2psSOdbnAx25qoFSCspMpGZ6psOA priv=MEcCAQAwBQYDK2VxBDsEOR2IOEJeggc8VdYckPvZGemNQLu65LdZNJZG7geYSbDxw415YnRNFzysP/tVBNiWnHz1BSarm3j55w== msg=HYg4Ql6CBzxV1hyQ+9kZ6Y1Au7rkt1k0lkbuB5hJsPHDjXlidE0XPKw/+1UE2JacfPUFJqubePnnacmGEm4Kfw== sig=nZ4K5Uuy5MgUhG5fVbMirtthd7sjRpFgUlbAeqDkXW4NRuvXxS0OIbEAdA4BUZP8yoxuGiCZIjQAWkTsjY8aKhn2dQpJQLbfUvQQ1lOzSy3GPfyXJ0t4tIbv5vAFW//E1KvM95lQgYdVirKjinvshjoA e=found last=26 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5wgeKP777dZAQONnPSniALrqbBeOlakmUGCNQ77RE86uz6juK34oeIuLC5E1VO4HirJysjT73NcA priv=MEcCAQAwBQYDK2VxBDsEOdMN4EDqmO9xtMG0xI77W97AvheWm9LqY11SkNU0R12wr3s5O3zgRr0xswXgRlc9BWm5aIhGzFdB9w== msg=0w3gQOqY73G0wbTEjvtb3sC+F5ab0upjXVKQ1TRHXbCvezk7fOBGvTGzBeBGVz0FabloiEbMV0H3m4u2UGHiiw== sig=44khzjy3j9L8poMhqtQfYT8HV1a0hnR7jZDyQ7abBNEoWaOBrnhBcPw+rUterw9dUK/TXz0hzQ0AVB6IgYjU413IizaufyaIUa/Srh7QTtiyfj1nSsth2pKpMtN6niUGuPjKPDjbB6oZqkINxLScwiwA e=found last=14 s=3 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAZpTBjqVnwGqS7+9ks0hXzcYaCTvA3r7bBrpLB8tn8M/pLpL3Z0NiSRsZ0E9Dr+FeQzU/4dld9nGA priv=MEcCAQAwBQYDK2VxBDsEOU519kYIztPXc9wKF+L8StNe79VEyDCL+22gDYMYPFKweMPjTq1g4O0Dt7dvM5nO68+VoBK2jkG97w== msg=TnX2RgjO09dz3AoX4vxK017v1UTIMIv7baANgxg8UrB4w+NOrWDg7QO3t28zmc7rz5WgEraOQb3vBAEkKUn5OA== sig=Eh6eJGsO3lkOlWGaYasUTsFqR2zH/h853gaJhg5g6yuH0J5qgbHQzd8zT4qkFHo6pDQzX3pA8v6AQ1u5+fi3Zsw/KWDtwKM/Wr20c16whilRbo6c5mOSnqRcO2nA9OR9UsM3BLew2swDq+Ihn/rc1hUA e=found last=14 s=0 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAa0MpXwvcyNnsfAuYT2a2yWctgM+cS7ls83010nXGKk9fp8Dzwsb9EP/Xf9o24jbdE6PWWigyEvmA priv=MEcCAQAwBQYDK2VxBDsEOb8zKC06RgzkwTE1cBnWLMFYw6GcEyd2j8fABBqw3i3w+KC/qJWJeofixPXWY+uyOwBHFfgnFAh78g== msg=vzMoLTpGDOTBMTVwGdYswVjDoZwTJ3aPx8AEGrDeLfD4oL+olYl6h+LE9dZj67I7AEcV+CcUCHvyGZDhvJd0pQ== sig=uKSSajmX0e2eL9HGUjtr1yqlzT23xAEEhZxLJlezcFwm3XLrNa9TIzssdhqByD3Y7GKwez41uWmAq3MN4OCq7Hadp3vmO24T8bIe62sbk+jPrnl4Qel58Rscdz6ER1Shh9Fy5WQRpzWNfPPi+o5DVz4A e=found last=14 s=5 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA0H/4fiqDsOmzDikk9W8UyLONX8b0afWXZ7WutuQb+tMj2lC41D9m7Nm00ej/TCKf4A+/2EcwCJSA priv=MEcCAQAwBQYDK2VxBDsEOXakDTAL9esdPsd4r3bnCrrQ3HIesZupXyWVOqpOfQfikQCsmJ6sTj74lq2nGWZrpgvxADP1Yscw5Q== msg=dqQNMAv16x0+x3ivducKutDcch6xm6lfJZU6qk59B+KRAKyYnqxOPviWracZZmumC/EAM/VixzDlx/VOymM2Xg== sig=G0+AZUA0T7SAuof40bNr1iMLoiS2gyBWpQfRxLJCW6V8Agvi4gzcJ4oXzPmLRcKdEFM5zIMrw6IAL58QYQCfoozGJD/AYCPJJILuXyEDV9eutKYbQlHXZDihgfpBFSvFvcqlAU6IplzwlynO704MdzcA e=found last=16 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAG3B67U3C748SB3yoOWrPCvAujMrd1JmvOk7QYMU1Jt4qfY+4Rxt/moDPcLFDRbt0KtGJklGWESyA priv=MEcCAQAwBQYDK2VxBDsEOY4rchoGxpWEvK9wbUahgIEdxDK5xiVgoftE2p+nwdmaGHSxnB/k3HcKbNweDEoLuinYPgyOaR37gQ== msg=jityGgbGlYS8r3BtRqGAgR3EMrnGJWCh+0Tan6fB2ZoYdLGcH+Tcdwps3B4MSgu6Kdg+DI5pHfuBIIP0INvcng== sig=DNuGLoMmiFN9pZ/nO+EFDCKesL4ck3QuC+RITaUHPPkbMzv4xykX5kxriNqBlL6WvzlFy3p8UaaAy+u/WOuEK4523FbW3bH8ZK8v8Cny+ZSgohKMjva91cso4WW7+XZySAngRcG5rzC0QCS+Z8NxMREA e=found last=14 s=0 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA/5+nkLpvoCYfQ60RUIlWtVZIujOza2LQGhM3gaHVOVmDQl00MEqpVlWvPWLhVXolIhiWd1v9Z9oA priv=MEcCAQAwBQYDK2VxBDsEOdVepr43uuEnqyVCug6RVxWjt/lm+76BTu23NoXasiVQLr7Yc4RJuQWTkocUzAgXI1Pvmi9dprjdMA== msg=1V6mvje64SerJUK6DpFXFaO3+Wb7voFO7bc2hdqyJVAuvthzhEm5BZOShxTMCBcjU++aL12muN0wKubwnoVNAQ== sig=xOyYIz3JaY5LhJHcavmGIWrAEk98hGb2ar3joKSqQkt1ZgBXv0kXhiTLoGh5YJAsfp+CbuRd/TuA1Ut5x0eQJFd7BJ8+6OVDfEXhXnkK3+8qlzzZmgoFwv4YJLKQ941LGciCxR5d5rwLdziWJXSgcCwA e=found last=15 s=6 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAFM3ZyNNTNDlPDr7d2S94VB+VgXKWVgfVi1uVDA1D6nnnmP7nvg+4fUpD1Yo6M4dphBAlomgBdwuA priv=MEcCAQAwBQYDK2VxBDsEOZfyhkVti1XjNq3V7+XgpNd9R4VhXrYmSREXhP1sHyVdL5Sy8aM9dvsXQnkjyQR1AAy51ezA6G73gg== msg=l/KGRW2LVeM2rdXv5eCk131HhWFetiZJEReE/WwfJV0vlLLxoz12+xdCeSPJBHUADLnV7MDobveCjLSGc1zhPA== sig=oHRA+cxcZS8WeDbPYwzJht65laJwrKeZhg5GWhT8YA16bcHUtSw77wPz7sSeeLSQDDhKdYAg3NAATFNFdRd8tmoU8tDe+KZ9eLpFJG2CTg21ELUqwmJmql+a1g8vuXdKsWakP52+5JpIlBe/v33mIxMA e=found last=14 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAJtxKV82llGYWkDx5xF18qYL4Cn3+tdMOh2LPQ2wzhjYy+ufuvm2xiG8GIz+yzbR25e9g6HBZbsGA priv=MEcCAQAwBQYDK2VxBDsEOZlxBtZqfl+dBr9ZjrqDyactOzATiwSc6DcvXy0NHowa3GgHneTSQVTzIB+wAcFaC4UZ6rup/cKxfQ== msg=mXEG1mp+X50Gv1mOuoPJpy07MBOLBJzoNy9fLQ0ejBrcaAed5NJBVPMgH7ABwVoLhRnqu6n9wrF9JeQiH/wxvg== sig=q6EY5UNTJlbz7azyvyGlrhzjHS+meObH+4ZconBRmRd6IELUa2h458g4qBMXcKvyRGU0gMIycakAL58rJ33hjIx2OPuIeDWC0UEAUAySnq/+nzMh7FuK5dLk9cGQ+evySj/TLIYfkLMWFfKOzsGrhDIA e=found last=14 s=2 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA6/H8XQNwmS97HxbHr9JOSoEV0ht00XGDuNXDV+2EMVER9ebvik7Xb6MerBmKIQbdS+DCd5n3UAWA priv=MEcCAQAwBQYDK2VxBDsEOZ9E6QYnB/ZYWvkB19evz+3jUgik5Kt4IJa8qxtdABwfaHiWxZP+S5Vcj6l1Nd48JFNjhFv559DWxQ== msg=n0TpBicH9lha+QHX16/P7eNSCKTkq3gglryrG10AHB9oeJbFk/5LlVyPqXU13jwkU2OEW/nn0NbFBZ2Jg9kucg== sig=q0vx38x3IIE64M/1JkcIhyJZ4oPKZAkwZRQgbB/LnffYz4D/ARpyUxgX6UCZ4FD14WgdD3EGsoAAr/y3g6V2ICr8l6ENRSIjOthoCok+4PSnqU2nvRmEmrUlpMzyrn/+a1dEBG3lbk0PWHvi86cFezwA e=found last=20 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAJJyOzzeSXg+2GF+N13oWyVEYmJ+EsBVdESA2yicSPGN919xuT3mntFfr28PUfN8gxPcbKVGcxNuA priv=MEcCAQAwBQYDK2VxBDsEOUP6VrFcTO7eReYWfdhpAcCSCvNPVVH/ZuahNKCGgCqIy9Z7ELs6clARjERRPcORpnaEi6BS/LZHpQ== msg=Q/pWsVxM7t5F5hZ92GkBwJIK809VUf9m5qE0oIaAKojL1nsQuzpyUBGMRFE9w5GmdoSLoFL8tkelrJgWrURcRQ== sig=osehLa7BCJcsr5OkZwW3SZ4ENokSMhPL1NXrnOxdZg5NnSQKlOukctJ6VdOiQujCH/VUznwUSv8A1ICvnFr/6Kh57a5aPacCfIK5rPKPARiTbf2PnmdHp0fkM7ERdfrJmomvXrzLbNupKNnSafa1CBIA e=found last=15 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoASBH4/HKrpCtdgWDs7+FrHDQ0MaV/5IFGOzQk3YFzPF/CZAqfeft1z+158nXTV4E1mR5k3plRZxKA priv=MEcCAQAwBQYDK2VxBDsEOZ51sHNx7WOeCEC4wKGiPSLAxtwax0XvwbosIZNkRc8tbAOz8TAQFInaLzmNGzSkQqfvTP3n8Wrq7w== msg=nnWwc3HtY54IQLjAoaI9IsDG3BrHRe/Buiwhk2RFzy1sA7PxMBAUidovOY0bNKRCp+9M/efxaurvC3L7CxsKsA== sig=Ja0B8ejroqyaIf9wl1V+6hP7AUYvP/Tgnw+fdODdxie7jflnhEN1JgppidKCtQmrx34Lr4pm1J2AvOM31Oshz8cImPISLI7ywP0UbcUp74zQmaTFWzBzYJ5KU11eNswa3APSaUUv7y/RKFsql6qs2CwA e=found 172 iterations", + "pub=MEMwBQYDK2VxAzoA0TOAEYFmmVhwsA6XVbdqU9uxozBluYkTniZprt+kRVIGOwUnrnnRuIRaKY3IAoqfnk+OB1YVF+AA priv=MEcCAQAwBQYDK2VxBDsEOXStaIGzIBwg81QvPWrTCFHWhTYOwdiXq0i1+TJc9P3xG7th/kcQ5kp9pflhx/ERCLSn3kusRTiZqg== msg=dK1ogbMgHCDzVC89atMIUdaFNg7B2JerSLX5Mlz0/fEbu2H+RxDmSn2l+WHH8REItKfeS6xFOJmqewbXL0oNVA== sig=Ifz3wx04icbzyqLlNuZclJHHjgBbSaUtHeW4QrQjdFMy3JS63a6UDSHGIwUUpm1LiVOcJxrvbqSAfEp1ECbbV9wg+KOl4E4YjREx8HRW9qMbNIGjWyC3vyGPPe4XqZElr9kMQ2N4Gjdt6u4yadmBUhsA e=found last=14 s=4 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoALqckGZ+oMTp4WDkAvZlhv8XLsjsx+Jb4IQxiH+5gJU7mu9QJaSY+QSNlrnFEXwvfHaAivq+mG7kA priv=MEcCAQAwBQYDK2VxBDsEOcrmNdWBbGK+MoLB4cYQKgrMZMqh+qC8lNVbivsPlqOcBtxMm0Xd72PaYSVg+d9Q2/U1t6klJiuFeg== msg=yuY11YFsYr4ygsHhxhAqCsxkyqH6oLyU1VuK+w+Wo5wG3EybRd3vY9phJWD531Db9TW3qSUmK4V6nbOmN5KLNQ== sig=OvjwknrZBlwLPtuhihsyUyGVvNxsf4FRp8+8bn1dNKUCaseAnnh2St6RDoxi1SVHhVkTFYX5OsaAKp9tDpxC2KwHZdc7JfXTm65yGQluSGNRFIm89DtKOqdJ5ZbFBPJztu3L7RsmVjVt3vgxUCZCui4A e=found last=14 s=5 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA7IHoWSidTFeNGuj3HYaLj7vgLYVIMAVuBwhWU7Oacn3xa+bc9t59X/Koui8GALr9oNzNZibaDxWA priv=MEcCAQAwBQYDK2VxBDsEOUA/oI6HQ88QVD+4hYJHoPskH9qrGBt1IyY1FHzW+3OtrvTazzeP3XUyY9oZAhUHcP+xCjH2LW5Etg== msg=QD+gjodDzxBUP7iFgkeg+yQf2qsYG3UjJjUUfNb7c62u9NrPN4/ddTJj2hkCFQdw/7EKMfYtbkS2B134ZQuu/Q== sig=Zt1UfB4tjJWwCDUTI0zxjMviFxPaLFTNQZeyA5/lhGD0EXZeXGoKXNgxR/8YyhFIeNqco/9z5/gArVL7b8JZ+DGb/h8e8bi79DHF9cMshB1657kVuIbwqarbqYO+XzeenOif6ujKovHQSfuSx4IynicA e=found 169 iterations", + "pub=MEMwBQYDK2VxAzoA4Jfz0nEelpWX+g3/o4mqa6EJG3dYpqAKz10zQQmFRrOlFfIaKEqDXFq8Ji65Qs5wQT5s1qUsI/QA priv=MEcCAQAwBQYDK2VxBDsEOQBHzY3WT+B5OziTYDFlxlbWcOyAWfsU+AdlugGsCaUHueDtkwkeLrbylEJu2VB8wpdBofiN3orXMw== msg=AEfNjdZP4Hk7OJNgMWXGVtZw7IBZ+xT4B2W6AawJpQe54O2TCR4utvKUQm7ZUHzCl0Gh+I3eitczy0mbH9n5EA== sig=k3MSnCejxfnAGGP/GNkTHHF7Xe+QAMJz30TJdMT3hpjDSMmJUMj1Bnfmjz/sPNkx8NCrdgASSKAA1KcXPm/k00YLOALHAaTjPoYR1TVHuhQSCcr08pjHa/3vt7Ry7PUC3okNswLnuplf8OiFqG8X+ysA e=found last=18 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAPipcTWkR/lxuKMJ0GvyXE7ZpH7cl1gR8HEyJnHnewZE1A5okwQqpIWLA8KOJ+xgogEZzdmusxwSA priv=MEcCAQAwBQYDK2VxBDsEOUlKEL42RLE6GK8U3JZABV3HQzGa/S3t9P2GXTkD16w3Taw9PyZTOy03ZCUMpAbiXZL9iu1b/hFKsw== msg=SUoQvjZEsToYrxTclkAFXcdDMZr9Le30/YZdOQPXrDdNrD0/JlM7LTdkJQykBuJdkv2K7Vv+EUqz9t2aBzejaA== sig=OwXl2Wg9H1JH62iY4UZLdVfwLzdoN1KEBzKL8HSmfJfud+Wd/r5RBMWxj1Q41K85z+oJm4Ep6n4Ai+8xWnFZ+CAji2cvy7WgRphunicMGuSS0IraAZ3Gh0Ie4G0hVOHLWiQixvcZjDInNBjqD9Ln5DEA e=found last=16 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoATKxl6+BByo9360eGKhjZIZVLVZ4cGgkHU0dMlrfAWyHOD9J6M69YnB7orKP5cjFRS+Mc4eAIf4WA priv=MEcCAQAwBQYDK2VxBDsEOXnQRSAACSRIfKxxwO5cXgfuP3cn3m9flDg812uPU+E0gLTnTJw6bf692mY7Di3/Paja4fGxNc3DFQ== msg=edBFIAAJJEh8rHHA7lxeB+4/dyfeb1+UODzXa49T4TSAtOdMnDpt/r3aZjsOLf89qNrh8bE1zcMVBBuPvNDkXA== sig=56aGOWlw9pUQePQquaNOUrCCMNLhRFURercZ82GoJYjOBeyK2DLFlPKpoY/FLmx5tSSy4MmhknAAWVEX2TBKon1fuowQe+NiZDMXB1qgKoFTrSvTOJWdW1rzn+NJFW4jZuiekOPB1YAVIWCtWxHWMioA e=found last=26 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAIaayhcVxzu/8/1/i8HFMEWqCogHcEbmFvXiw/EFpGUL7gXU7o4qEWz6BEWHLJRQd7KkAz2szccaA priv=MEcCAQAwBQYDK2VxBDsEOfhfx0/smiiri5yy5pPxWnI9RW1yYYHj5GZQLVBG+TKxc9cIzrmhl1d3700GD+j/Q8wifP/KT5am8Q== msg=+F/HT+yaKKuLnLLmk/Facj1FbXJhgePkZlAtUEb5MrFz1wjOuaGXV3fvTQYP6P9DzCJ8/8pPlqbxQGhiKY8ePA== sig=omx0xxsGFe9bTsYBLlKnIRKiNcUdGVCvX42uGSqpIz/Pt1XCUsnb+qhA7w0H/8CXMrGuLE08TLcAwKl0o1p1+KcTWp3iVh6AfXTLKAKDtrMD9e187zSRlJUtlZOGtkMead8wOwVPqjx7xEDIqyxWzAkA e=found 162 iterations", + "pub=MEMwBQYDK2VxAzoA2FJZga4c+yRTvVPuBoBKHpCT4vrx2CIQjpN27CJsQaHbhi1mNsgc+iXC+EwWtmn1uFhQJNGLzXQA priv=MEcCAQAwBQYDK2VxBDsEOcCm1WxSJSpywwLui7EbmWlfXzDgVD/BLIw7BOjHKTlEz1eMB4i5v1ZiKHP8C4WFOBt6icUDKzSUaA== msg=wKbVbFIlKnLDAu6LsRuZaV9fMOBUP8EsjDsE6McpOUTPV4wHiLm/VmIoc/wLhYU4G3qJxQMrNJRo/4ppv5n74A== sig=Kz/WO12E8ypl/yUlSXgPdMH88fCKlEWTpjFuB3xuL5cejvmYdPe3YxTXZgUKRbq2kZkvFNwWZJkA2C0AszUxzbLpwTum2fg51x3GjnIhWN2PE9hYw+r9hP4FKcdQyUYmvsg9uxq26/f8COgetZPnQj0A e=found 187 iterations", + "pub=MEMwBQYDK2VxAzoAoh7PzuShlwdgKKydN2TH6UDIEjcVcz9maVXIEpeKBGmWOhTCqhLwB3YhswVz52KwwZkk6athFTAA priv=MEcCAQAwBQYDK2VxBDsEOR398tHkQCJ9LUx1dlu1lR30abnxNl+A77PZmmfB4/Ygo1seG65F94oUmri92PRkp/B9TgDek45b1A== msg=Hf3y0eRAIn0tTHV2W7WVHfRpufE2X4Dvs9maZ8Hj9iCjWx4brkX3ihSauL3Y9GSn8H1OAN6TjlvUw0PzD1OgkQ== sig=Ov9mkGUpCMr77AJdYSL/FZ95LUxQF8PFgd6BKBEhj+2Zh+JCEu6J83V3l7KBiSi9KJX3NA/FIg2AtpjhueQrjvjr53UVQydMxxIit9dv4UsCLXzg0CXSyFoY05UuXDL07LFUYB/awqhvCNnY63zA8gkA e=found last=16 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAFL33Wx/u4WcHQSRq/Wcs7XdZAD2xrsuOGCfJ2hUrQP/DUCSRYnTtMlpJwiUa4mYEtIPiuZDHhyuA priv=MEcCAQAwBQYDK2VxBDsEOfOm875eFH6TtIgTUvF5WaAh2LBj6o235vRZYsGPQJ20fFKpNtW5+5ajCSd2JyzrWLmoO8dsnNKG5g== msg=86bzvl4UfpO0iBNS8XlZoCHYsGPqjbfm9FliwY9AnbR8Uqk21bn7lqMJJ3YnLOtYuag7x2yc0obm5abM8T+etw== sig=MBl4nmj+6dcV4DC8hsHZTb/oJfAdEzxBeItQHL4m8HIVnIurVCkIDvSEZ2ASUZ16GCpwt3mcNjoAhbWGOyZIN/CiGsshgR2Xctm3afSe4NXZSh20oYbnbWJYS91DbgYCGQbQrFOVmRXBY+R8YsgoTBwA e=found 163 iterations", + "pub=MEMwBQYDK2VxAzoAiUXW4URqK7UtJdw0RNUlJcYit0LGIggOpFA4x4+altLERia6/nqPdd13TJeeDExYULqBSYXYhw6A priv=MEcCAQAwBQYDK2VxBDsEOVwGuNGoYbNjTcKSkrLmB/gzY46fOcZR82PLW0qAuEXZt4r0xrG7TJDQ5Ya1wBQlXSpQUaDtgkjf4Q== msg=XAa40ahhs2NNwpKSsuYH+DNjjp85xlHzY8tbSoC4Rdm3ivTGsbtMkNDlhrXAFCVdKlBRoO2CSN/hJ7sgT/Vh0Q== sig=q912Qhhh2kJT3pbWaredNaDyz99pmK8nIcThB339ah1gg5xelcrQp5LmFNjTWwzJqgx3MjcwaOOAkJPuTMJQDhT4kByQqAt+VC/RLMOG8zyYg5yUhcq/T5y7b/fWJ63Tm5RS116AVvOhnX9MIlfHlC4A e=found last=20 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAgGt7ajX87GWW+6RwRLIiP8/Q6bJS1wmOLkXMRLHgSQ7XbkLHkSquFvB1eTwE28JdjCJTPHGHf5UA priv=MEcCAQAwBQYDK2VxBDsEOZjDx9VVPFKZ/o3uFcBZWMtO/ADgCzvdUdO9NgiWEcglff3ums4pWQ+9DXmXmB/x8gSUMB0gXfLgMw== msg=mMPH1VU8Upn+je4VwFlYy078AOALO91R0702CJYRyCV9/e6azilZD70NeZeYH/HyBJQwHSBd8uAzxampx2fxXw== sig=oj7O/NcltH2qBZXp77c1KlMhBc9bigaucWLxsDykbqcP6AuhbrJjkNJrM5fLOxxasVTd1FQgUUSAXrLYE3JFmn1/Xmjl/kbuYmse5hFA8RMG1DQEan8DKf6vAgRZwbwD5ITLHAexsY3hm7AEjTFj6ysA e=found last=14 s=7 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAJuqtbDEtNEI9o0lUE7tJJIdJ2A0mRS/5emJyL0A6K7xzPryk3X1rD1djKw42BpnPOwizOky5ehoA priv=MEcCAQAwBQYDK2VxBDsEOVneGg3ExxJsszz6iPTChT3JTNgO+sb0mABa/8CUKazY38rKK3/Gr6ByZrZJQpfSMW4w+uRMS2ffvw== msg=Wd4aDcTHEmyzPPqI9MKFPclM2A76xvSYAFr/wJQprNjfysorf8avoHJmtklCl9IxbjD65ExLZ9+/BYma2loiYA== sig=lS5JZ/K9SSX4fRPJja+21mcA53IOa1PZH1vDLJI4QLO3/Ym73wMz0ee91LWzqelDV3jXk95qBFQAKxbOSF4OOKbUamWhQ4wh8quaCJYrYfvbZ0Ics6O/zkp6F24z3Ik7THBrhG8gRXOm9G6uZ6bEkiMA e=found 158 iterations", + "pub=MEMwBQYDK2VxAzoA8AArJ85lZL0zyEGVJgGRIPnGLsppvLif+ErVw0w7uGz/ZlQHhgF/xoQhGpEtFGunpr1Hv2jrkDiA priv=MEcCAQAwBQYDK2VxBDsEOUHi4t7RumxohBafcuIzTRrOMAYgbrvv0nWOaugt7VBO2NAAYDHhh5R22a3SpajIn91jtQnbwL6+7w== msg=QeLi3tG6bGiEFp9y4jNNGs4wBiBuu+/SdY5q6C3tUE7Y0ABgMeGHlHbZrdKlqMif3WO1CdvAvr7vMuGfM7Bo2w== sig=d1CV0JoSbkO7426eiw3SDvM1cyZ1dKBPfLXS55TMnRt6GIFj2bBo0yRoV6nDKq21yTZ7q1cCpiKAXbrvXdSnviUxZ9D24k0j7Ru/Trnmw+DJsC9XuOIYQOoAWmKplbvms615rfr84UqqmWpPAV6bAyQA e=found 176 iterations", + "pub=MEMwBQYDK2VxAzoA3yo3onLA07aNaN0qtuCKqGkP35bPab3zfbCdSFu03CXi3ad4buKVnDo5o9I+C3GfxF054hX1G+SA priv=MEcCAQAwBQYDK2VxBDsEOc+N9yxhbxijrbYx0D3sqIac96AXXLD0NySA0ZrCWyltY/2knJMEpEKrMfg7aIujGQNCMZmpMUeKAw== msg=z433LGFvGKOttjHQPeyohpz3oBdcsPQ3JIDRmsJbKW1j/aSckwSkQqsx+Dtoi6MZA0IxmakxR4oDHE+vEuDmuQ== sig=LRoI5fAx7xL5L+udpt1WTXivmdpnDALWJoLgt4kAX0y2VxD4IDdkEaCSrPpKBkPyi9QHMX2+L6uA6aviK16VqJatsX+Qry9DjcEhPnre/e0/2PCvjRZ9SzySzzLZfRPlA0FjEvlVShL2OxAfJwk5vzsA e=found last=15 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAJi88vLEcpA5RoBxL8EIQhOZaLB3vGCNwjmHIpZ4wYN/SjsCfCVbmAda678Sf93W5LhtpCpEH7YOA priv=MEcCAQAwBQYDK2VxBDsEOS3FgWVCiF18+mPFaGIoZGbwUfygArrQ19DNT6IYW0XefSb6wI5yXkGcx3/ukM+GuA+cpXNBOpo5tw== msg=LcWBZUKIXXz6Y8VoYihkZvBR/KACutDX0M1PohhbRd59JvrAjnJeQZzHf+6Qz4a4D5ylc0E6mjm3cifPDSYXKA== sig=UWD/vwpsZ/wrWxqy1Zh93ObqWheO9lAAszegvM14xatV6t6fcdUxWWcz2UsxJVTYL/yQ/u7NYJsAZ8bOAPMBQwyWEqmk8D/emcQXoU6vSIAv+K6QnIw+vG04udYRUKBS/K325qFDDd6Sa8bEHygsjx8A e=found 178 iterations", + "pub=MEMwBQYDK2VxAzoAcV5nIrACuVpPAh5ZqL8dEszTeAkBWMj0R0yaxw9oswagOfZscPEN8TFgyryVyXP++21dTxTgetcA priv=MEcCAQAwBQYDK2VxBDsEOSzTePiwXJPf+wnLojFB7dxxezhRWvsaGSn2HFEhWNqvgNBfZHrxfFVryODmJDAmdQcFkUF0Ux704g== msg=LNN4+LBck9/7CcuiMUHt3HF7OFFa+xoZKfYcUSFY2q+A0F9kevF8VWvI4OYkMCZ1BwWRQXRTHvTiss+wkEiJMA== sig=l6Uf4dlJZexR7yoMvSZkpgXed20LzcfyVDhTRRawPhiSaGJxcEdj18I84ku5iMKtRq6bzIyYeuAA5cIjpiXjq97RzYlHtFG1sIbS+tiEMqqWhurZyl1ZEsAuwIrYZ5toPHxDAEG527GCrjnFsjW+tSUA e=found 157 iterations", + "pub=MEMwBQYDK2VxAzoAtbUYKn76MKte6c/0dBwdnN4YXlv/e4MX6yGDXH0rWkxkshzus/ZTkT3YXElMg+xuZRfNYW7z3UyA priv=MEcCAQAwBQYDK2VxBDsEObvYhuKlFEV+3xBwq0yUkAkcFlx16YzwkadgXyogDfLzlTC/w6MBMcC88ti7gPnINtaPaupamFGkpA== msg=u9iG4qUURX7fEHCrTJSQCRwWXHXpjPCRp2BfKiAN8vOVML/DowExwLzy2LuA+cg21o9q6lqYUaSkoo5N7fiB6g== sig=iS4jQy6wyyNxdiPSCGQn7Dg4XBNzlZ7mAO3V3NPYw60LtKWwm91lv0P0e0K5yucIN+1ZhNpy7VGAR6g23T5OdJJDduCWsNTZabt371lJ+xtYCtl4+kAUGqwluq/9eDo/kbARl7X+TKF6xiZojVPT3iQA e=found last=15 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAUL93ueBFZqY3BrNcRT0s2feIAHIgKhBc7pRflHlKT9Fy72pXzIi22nlrovRFS+/mx/nJ0214uUcA priv=MEcCAQAwBQYDK2VxBDsEOWoXjmzloV9BwceyTD7RLMN/vQb0i+Wj4n9svhQa1HeZWbVGmZgBJLc3Fq+5NH5bmy4Uhe9C5bQZdA== msg=jmzloV9BwceyTD7RLMN/vQb0i+Wj4n9svhQa1HeZWbVGmZgBJLc3Fq+5NH5bmy4Uhe9C5bQZdPdW9/KkoBLYJQ== sig=ISJavGqDu578bqUFnegNiSsN0PBrp7gXQgDo9GasGraQ9haQ3OSLjRe1MqFS9asySGsH284/dyYAfkAuE6YQekn2xoj4ZRNBQsQ1TmpaJxmVAR1cF4buU/6qKkhInS+2TKYgg9lB9N+qMLpTOLDpFBgA e=found last=23 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA/K/fzZMYIimSU8bBl/sg8Rh36hm1ntCVa4Et+5Ovhk5fnlEqku8xANrBsOWNMMy6K1nTOD0jq2gA priv=MEcCAQAwBQYDK2VxBDsEOb+lD1yizcdv5oaV8M3THp4/HXi+pxhM8GU92VVI/gQwi4L6T4W3m0/p7nRzPVS13YIcOSa2Fp0+VQ== msg=v6UPXKLNx2/mhpXwzdMenj8deL6nGEzwZT3ZVUj+BDCLgvpPhbebT+nudHM9VLXdghw5JrYWnT5VlaWsr4lyKg== sig=0oYgvQ+XoIIUL4tyyVWowxtL7T5aIKvoHmiVsbdLO6pBQKzPShO7SgcfaJfZDKJ6nuF+6bquwc4A/BADjxp8+W1nJEgzKoNmUrxIGs+Re14EkIw0wHZEsRAaeMTf1uP2QIliW/c1kOyF1WFHXT5MyTIA e=found 168 iterations", + "pub=MEMwBQYDK2VxAzoAbImmNC/bZTL3uh0rXxlPmuK5tMiHdaIey3pihhRSdcQvdkmQV3wH6R5dUOuhXQhiN/QXZIGQ7oqA priv=MEcCAQAwBQYDK2VxBDsEOdjrZH/OXvCs1JXxlSsrqAqawyc0kgpYjdd2j27FfsnVuuO7qrPzpef49gFK9W0cwkgKWhKRcyAA5g== msg=2Otkf85e8KzUlfGVKyuoCprDJzSSCliN13aPbsV+ydW647uqs/Ol5/j2AUr1bRzCSApaEpFzIADmwMbDibfr6w== sig=Wd+I6SiBIEnSLfHxqOVmyz5keUdnViwzPdCESWdv88UC9JhCJuEgbEgQsrak3FbZAUqFSDCuYZ+A2L91vXg4SfOTE9oN9MPkVKmfUHzbaMEGNYgOUJ0xZbqe8ArDiaLjkZLn/Ne8WDY+rZxE8YZbSSkA e=found 171 iterations", + "pub=MEMwBQYDK2VxAzoAbYKrwWFOmPKdp2EQu91fY6uNP5fCrH01+YFStSDLAcE30SgX72FAvE9HBnmWL5irEHUV1/8OW8CA priv=MEcCAQAwBQYDK2VxBDsEOa1ycLa1MZLQB33lChNg4xR9BF6yHwuyrLEnZmyAz2bHzBbjhTpFAQNnzttLIuHrxk0wAguwA/setA== msg=rXJwtrUxktAHfeUKE2DjFH0EXrIfC7KssSdmbIDPZsfMFuOFOkUBA2fO20si4evGTTACC7AD+x60kcor9wKmGQ== sig=2IdtJjl0LboPhAVreHyJYHmfnlrGG87K0m8b0bfRKD32dkkmUj5ot4GYDAdKnVxbuVZ6AM5GXIUAJi2i89D8EIuIKNcUrHn9hJdToyRgOCZh5ioy6UTPY6YGSPX9AGs3qyZDxw2r9sFn4olfrQ0r7xcA e=found 161 iterations", + "pub=MEMwBQYDK2VxAzoA57+V45XmUtpjx9mXtQ77BVJU7L2aaZv+euDL2+RczhangISVvZffxueEHj/lE/kAQiqVeYjyz/+A priv=MEcCAQAwBQYDK2VxBDsEOZzVydXJ8ychAiMZb9+yYwmnLEKRrtMBsz5X/j605li300IDg+A2zBeQHmVU6RhrxQ1p0QF1rqvcPQ== msg=1cnVyfMnIQIjGW/fsmMJpyxCka7TAbM+V/4+tOZYt9NCA4PgNswXkB5lVOkYa8UNadEBda6r3D2xmFTyUnh22A== sig=nZOO2bhrb0UoL3cZRGAawxQL8EzFhm3fQDf/FVZOaOUKE6zN4Nq//W2ZzbC1MgH8hoDpZkL1rfeAi0NvtHwoOulL1JrtUgubdNWAm3FUgthTuKMk4T8QvOoP1MevBK4Ib8nHB+6Nr+6CpWf4PTbuBDMA e=found last=14 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoANMM/DydAdBEVjaoXb+fI4unDfGI+JkTfibCtrApkShiXoAAT+twxqr4gXTA51XJEZswuX0hT9LUA priv=MEcCAQAwBQYDK2VxBDsEOfxDhn8lqgdjz+f7svYBA5lZAK3rCIhbAFK0mnplCKDTgoe1GlJ/Edq8iRs90pflXWleDo51MBEL0w== msg=/EOGfyWqB2PP5/uy9gEDmVkAresIiFsAUrSaemUIoNOCh7UaUn8R2ryJGz3Sl+VdaV4OjnUwEQvTwfSFvDSWgA== sig=dRgUaYbJAdu/buPJjsaocjllo+KLjKw6YhBsgxX9CT09APrM5M4o8rcp7Eogwma47d3D0s/ZP6eA3B6R3q1JeP8sqRRcgHlEvcHy+ytRL9LwfqYR1A6nk/WAVBFYrNeuuu98snmCwEwVEaGWT0XXlD0A e=found last=23 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoALhtQxj9sXJTlDYbNKnY5rbb+u8pgwF6aqp6bJyRc5BFRPgNyvCUfmF8vdAjN84LhELVsMS4QAeaA priv=MEcCAQAwBQYDK2VxBDsEOfF9SlNyxr7crhkIjdNk/2v9cwXV3g7oU++OyWWfOfd9K1TNcE6x4tsH5aqEDnkOrtsprNUD6sIXDQ== msg=8X1KU3LGvtyuGQiN02T/a/1zBdXeDuhT747JZZ85930rVM1wTrHi2wflqoQOeQ6u2yms1QPqwhcNGyfSzHsiHQ== sig=PNvDdMONCGEW/YVrauQkw4k0DsrL4nhMD2UUe/JS2sDjPH4cVLnU8eUtPkC9KYGWnoPPRttQWF8Apfh12UEf7VL9Xq/+2AhKgL1oSyEMjVz2q94L+OzAfq2RJtrQgOtidrchBiyhi2Gpx02XJv5lngMA e=found 170 iterations", + "pub=MEMwBQYDK2VxAzoALTMeav4sZNGAnaVsqxNC9NF43Xu2NuuZfdhJTgrhcqidZHU5RJ4ef23WohyeTRyl7qNu1ny056kA priv=MEcCAQAwBQYDK2VxBDsEObZsc1xH/MOlBYoDsIbMD8NpwJrJ41slyCdr8XhNcBrNWJRA5DgUpFyjZfO9VpOB5Q7F+Ny+eOuJoA== msg=tmxzXEf8w6UFigOwhswPw2nAmsnjWyXIJ2vxeE1wGs1YlEDkOBSkXKNl871Wk4HlDsX43L5464mgC/0bGPEAhQ== sig=7ML/FAoevUnBUgWEeE+ew1Pg7Z/9O9N/xLviXtE8toRY9AKozlv6C2aKA5UV5EkwRk7K2qYA2M0AJh8szPqFmvFNig138QwrZORcaS465/zZG/hxyaajZo/O3r6JZKbir7VhVeQ6p2yPjOkdBdhhohsA e=found 182 iterations", + "pub=MEMwBQYDK2VxAzoAfWQYBYuvElUgGCGNo1RjcBvsZoQw1NFtQOpNosZpSikkY7qQOfHuQkqgOl9+lmL7o7oFukxk+AkA priv=MEcCAQAwBQYDK2VxBDsEOdpsfpzD8WpyN1S3tfIyNuZ/8KpLYXa2cKgXlY9JEi8yVamEhxrUIVp70me82e5LymKiIvWbUWGE7g== msg=2mx+nMPxanI3VLe18jI25n/wqkthdrZwqBeVj0kSLzJVqYSHGtQhWnvSZ7zZ7kvKYqIi9ZtRYYTu/Roa5gLrMg== sig=HU3xFocCL+kKYqgIxP7037JS5+7gq7wHAxUHxxBzXy76nMSXZ/Mgp8kG9QpNv9E9QW9KNbJu8beA2DPyhFo+ATbBCN4bkEL7XHJwBzCpmHYkPzGCj4ZkFz8bzp5FdO9wp9kHG9NTCySJoK0E6W4ovQUA e=found last=19 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA+twCMHeEb6prLc4YcAgfoniUjMz58Z7Zg3gWcRvrOgq5fVUH5KzEVBQw82yjZDR2mAeU4HkZJXcA priv=MEcCAQAwBQYDK2VxBDsEOXElpfi/fvhLPFgxQanxx5i4ssipBqdcI8Z6yIAoW1ELB/pISWMKVhZ8dwNxPAieGBPTwoJ2kOMj9w== msg=JaX4v374SzxYMUGp8ceYuLLIqQanXCPGesiAKFtRCwf6SEljClYWfHcDcTwInhgT08KCdpDjI/co2AtkE72k9w== sig=tXIQDeIlMA945ThTruKvXnU3jhkxq3Uu318riqISuFjOWpujtVanrJHxS4YrHS5ArnA47zUn6QMAE8SYv8lYxA7LCepamXezSRRmzZj4hGb2YePgZ7R8X2fkMZMCAnB64pym4pC0nOrvC7xbCUsvPyMA e=found 156 iterations", + "pub=MEMwBQYDK2VxAzoAv/a6gc2YBK6J2+DrNLR3PuQmRD2IgejtFyCeJVCUc8EYRVUU/YAnPafJKQrjPM0KcFIbCl+RxRAA priv=MEcCAQAwBQYDK2VxBDsEOQ4hwgcGewKJ1/r6aunUxwArP5dYtrBcscF5bfOOLj4NMZPb73JClcTZGX22Voc8Irm8gLd2J2E6tg== msg=DiHCBwZ7AonX+vpq6dTHACs/l1i2sFyxwXlt844uPg0xk9vvckKVxNkZfbZWhzwiubyAt3YnYTq2agEPLz2Muw== sig=wh1WqiIHFl1I5tI5ZpU4O99kSbRpIvWGU6l5jIAOhHuhBsBjf5DX2bGpgW3lNrqUYn6MRQmI0CiAq6XQQDYJWOaj5l02fqb13o9tY/ngxvCYb7Y3l+0Bh2aoFVJ0OO0VKmP7wyyLdkRDbn29WK6fnToA e=found 167 iterations", + "pub=MEMwBQYDK2VxAzoAkNmJ5M6WFYUSOqNEp1Tu9LFy7F9/izmZC/JtFSisIOB2PNtliW9AO2ENFwMXYJpnNQPF5HOhiUaA priv=MEcCAQAwBQYDK2VxBDsEOeUsA5TgtBVde6Tpg/3CKo9dfyWrINHVF93NLC4GMpKU9eqXhYqtSa6ZZ3++mXBimAZbm7Yvhl9c4w== msg=A5TgtBVde6Tpg/3CKo9dfyWrINHVF93NLC4GMpKU9eqXhYqtSa6ZZ3++mXBimAZbm7Yvhl9c494IS0TYnIG7aA== sig=PXVchhnfBLc4JojnKN6fo5yH2Pyg0ngDJzV8GdVknwDvur0Z6C62EIAjeoNQ6Dutly+0wozDALaAU2iZezgHjj0g0BOzzTN4nlbA2WSzM4c7OBSnYFMNVy5xyL49vy4rUMaOUWy0X/cg+J0kRL6cWjEA e=found last=25 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAej+qXGswXOf5QrnFp4/kI3mlqjhaS2Zlqxi3wfv2cpjxYdSQGDJHbs0tecQW1yi/5IFIdtshjH+A priv=MEcCAQAwBQYDK2VxBDsEOSxQ1SgHUPTcEmYCucNF7LaGXJx8l+DDuQG5w0lQ1jYTzJXpDpKK07M12yy0Wo1G+FvvQkWNiNbGcg== msg=LFDVKAdQ9NwSZgK5w0XstoZcnHyX4MO5AbnDSVDWNhPMlekOkorTszXbLLRajUb4W+9CRY2I1sZyUaGM+Dn5TQ== sig=tQrzbgYYLCUTCrIn8X9tRGxnRYbropV3pLrtUTRaLvY+LopekFk3StcTVwwEGKdP7iw4GxvdRz2AYpFUyvUG29fADKFBMWXcuy/LFdqqIkY5iEOJxeSQC+exixOuDHP1YYZ2TnToStCIsuhk4rVY9RwA e=found last=14 s=6 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAuUrcvicwlmfbSuJDohoIoAAoCvPx1h3++T1FJ5bPkUVFZIks0q8Zz85UxSSgYvmw2sFNtJ1p7TsA priv=MEcCAQAwBQYDK2VxBDsEOYAHW9VVVD6INyREQq6BM1PZZBD5eWXKeeoETFZOsYpvuDY99Mu5+6AQvxsxKMBOYz4LsZkxDgjAaw== msg=gAdb1VVUPog3JERCroEzU9lkEPl5Zcp56gRMVk6xim+4Nj30y7n7oBC/GzEowE5jPguxmTEOCMBrG+BpXKxK1A== sig=uTHtoDPcUL66t/pMfYUvLQQYeJLBxz6r7YDCrIrMueZe1pf8rfXgBWKaRZ5Piwpvqnm5B7QbfKwAY1Aw/cUSfSGd7adxKjb1bFQQvWMDgeLtQZ8R/jge5QNVqhq/4WSMtWhlzimqrDLaqLTURy5cewkA e=found 175 iterations", + "pub=MEMwBQYDK2VxAzoAE3SDj8n/9eGpGhsG63JefwYgkmWIjDCsuFsTMNJLu7moe7XJ/i66Yoy9jCbzwM1gOD+x2tMzctWA priv=MEcCAQAwBQYDK2VxBDsEOdFnWx6UEr8QB5k/APzq++W38An3q8UDomPZcliwfdpbEHtl1FTPoiDiYV5ASuM5rCx3jDa1oODBwQ== msg=Z1selBK/EAeZPwD86vvlt/AJ96vFA6Jj2XJYsH3aWxB7ZdRUz6Ig4mFeQErjOawsd4w2taDgwcEdOPKHwXVjgw== sig=LIboKrfk5E2Ui7/8fhNIDLOO5O9STomnfCOq42rVNCN3vpLyLxtW2N3Lya785x2nM0dfltm1shoAh80UsOvysObv+pysXJNASk1NwUzuP8JNMxGIJWNWwjl8tWNvptnt3YkrSsLAGiBgD0e1augYyQcA e=found 160 iterations", + "pub=MEMwBQYDK2VxAzoAwCuFt2SjXXv6hncmv2Fn1tIXuzOugR1oNhIziWxy5MHJdKVIFvC1MUJjyOrnFtMuN53gTt/UsM6A priv=MEcCAQAwBQYDK2VxBDsEORN1sYdTXL+gKeftujU6lvFHMMlKHoCsvNe6JXVtcz9v6kATyIdiSCoiN4KBHb+zd5sSClMvV+u3rQ== msg=E3Wxh1Ncv6Ap5+26NTqW8UcwyUoegKy817oldW1zP2/qQBPIh2JIKiI3goEdv7N3mxIKUy9X67etD3o37CpXbQ== sig=4KlqshSblzPV626tERkeTe63d7rb2RONr6fvrqc1kfr3i/0wANAkSfiJBTmEGLShaLyxirk1D1EAAFW+CIuXwpeIQ4wtlageyMI2k3Q+ixn/H8fUdaQ+40Ar+LLBm4weCKVTSjeYt6MiXBxt1t+ohy8A e=found 166 iterations", + "pub=MEMwBQYDK2VxAzoAmCshBafbTwiLJWBGZt+tNkHOqEDNorGFlbsV3KfJGOa3dZ5kQFqxBl+cwRhpP32Vk7Mt4CjaQawA priv=MEcCAQAwBQYDK2VxBDsEOeteJ/muFZ5CqyjavAWM3P9F6amYPD/icN8ER1T6c9QkwgjeBqAd0U+oU728gMeAeCIRt2oB691Mvw== msg=Xif5rhWeQqso2rwFjNz/RempmDw/4nDfBEdU+nPUJMII3gagHdFPqFO9vIDHgHgiEbdqAevdTL/7AWv2ePo8lw== sig=bSaAeFnN4kXgEItepIn8oAucoM0+6M4ZVsVGo1YQhI9zZ/M/ROYDWxFG1goPdmUzGd63NV4k/loA5nwE+TBxdSem7iEx5uWtUdyUS21fjHArKrCoawdOgtqobK+vAENHfyXbn4kPuyzWN3OTZJ3t/RkA e=found last=14 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAnxl6WGboVKPC1iKJGZYrlapl44qzEe/d3NFmv9MpLFcoHkWFPfaJQB2LQE6J7ucjv4xtL+gmVQaA priv=MEcCAQAwBQYDK2VxBDsEOTf6x9+30J49aVZYrUe3J6FjEn+p0PPlps31bys1EHdvgqxlNApDJ/VpCHMXhHCg1lEWe2BoH3zLew== msg=N/rH37fQnj1pVlitR7cnoWMSf6nQ8+WmzfVvKzUQd2+CrGU0CkMn9WkIcxeEcKDWURZ7YGgffMt7G7c8CKGHBQ== sig=6o5kzQrENynD0JkvNzP50P5Ttb0WH/YCkZWTWAJ+CYBcrHFiEhuob0z5QAi62yiaikGJw80JHakAKowEIpulvR7N5VCe9acZlzmnxcLXRYypmQYzYZprguXQYc5h/Yq/Qyaa707tWv1fQo1vFb7e3wwA e=found last=15 s=7 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAfQr01pZtFLvyIJsh9LRFkJMOf6IOIEXxgoPWbyV0IN5N6R8TXvfbI/4wABbfYQzG2wgnJH7yp5YA priv=MEcCAQAwBQYDK2VxBDsEOSttnRhpeKXmU0aj16xGZD0UrE7MclYiHHisEbqsk4OT2hY2ALUelBeNF1+CUHf6GG1Gnln98211lA== msg=nRhpeKXmU0aj16xGZD0UrE7MclYiHHisEbqsk4OT2hY2ALUelBeNF1+CUHf6GG1Gnln98211lAM0D7oO9wH1iw== sig=6iau96XTQT8GMUqwmSFwqSBqOYSzcMvXuWpRi+IxwwFeczJ8U22Pt2CKy+650lpEppNwlVQtt8YAdtQAHE39ggULdhIfDCGpENGL1MhXgZtVUhYB1OSBPR/afEoIyMi16obFOWabrDPxD2Dp+dvc7iAA e=found last=26 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAGrOoi0uqAyLqHphNJMQ0CWb6/ZCF1dsh6o9qUtqSxNKWqDMfi+7PIxm6Lu/Hep9kmLB6RRzZdXsA priv=MEcCAQAwBQYDK2VxBDsEORakEHxqOsEx5iI5shEfizo4x7WwbrJpDFZyYiTTTNtNrM36E2zsatsE3qmOnY0qQ73ANKURU2CUIQ== msg=ajrBMeYiObIRH4s6OMe1sG6yaQxWcmIk00zbTazN+hNs7GrbBN6pjp2NKkO9wDSlEVNglCH+ZYVzt3JpHjdnPQ== sig=Z7EdInC8kcuFNs1/h27Ek9etepiIw8I/aGqtkOSOIppshHm6q24zRQ9Rl5YR8p9zbPqkPzQPYEUAUhV7JP64idGNFMl01yJLHFgCSv/fAvJa1crGFZ+OswR1sHsj7kf/B7HRndf38Pzn7DEaeeNaPQkA e=found 180 iterations", + "pub=MEMwBQYDK2VxAzoAv3lNC5EvzK3ehOz3a9p4jmBkQDLR9apAV43mzDe1jMnA5UDMd+Jd2Y9BLaCa1PsGE5iglSrkEESA priv=MEcCAQAwBQYDK2VxBDsEOWx02ciQzwB2XlyaJDHdJbAHjpcreLwP2uuR4R4uqKt5dcxXarSK5U/+5USggfR/Eb0hzGJgXyYirw== msg=dNnIkM8Adl5cmiQx3SWwB46XK3i8D9rrkeEeLqireXXMV2q0iuVP/uVEoIH0fxG9IcxiYF8mIq+RMU31JRV1Dw== sig=z0DH58c4xFUcnYJBco0BE82Q+aF6GXUZtjzaM1AAlkHXjhUdjiwQeeCM8Tth08fTkdp6Nhzi06gAreChn5KCQ27/w7wQ2QrgjzBhFlwO8HzBfmX9lbzTDkfGsnulR2Id1OpJYetENCZaiU5GhUFS9BMA e=found 155 iterations", + "pub=MEMwBQYDK2VxAzoAtwm2OwcySbeg2QWv76dSn/lrfUxFvvl081NE00LgJBv6ICnQ9ZvuycI6kyMoN4gNcoTO9MORv7KA priv=MEcCAQAwBQYDK2VxBDsEObLQj9hzyxiWYE1U4Oorw69J5Iboqdv4XyibHCFbvZVusfYIoxGaYhsNiDfevv6VOkjViBnJXNmmUw== msg=stCP2HPLGJZgTVTg6ivDr0nkhuip2/hfKJscIVu9lW6x9gijEZpiGw2IN96+/pU6SNWIGclc2aZT+UMsQOXmOQ== sig=Qn749bT6QPlZXXGgw2Wway8m9+rtH95tqEGbFh9ihSAXkoeDvbjJMm7/ENdNZ7bcgHVfxAN37GYAaFRqt7RRlBFGIO8i4bjzQ+l0GrQTxbW1Rfe0VoZEVhICBSvLOWd7h1IK9Gwv/z6Ac92WfLCPhDcA e=found last=27 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoALzfeU2Or1KH6U/BlJJFiSK8HdDjQ/JN5Yf3iZRF1gl+K+jTi+kJKdajnJ4KAHmiWVTSbxtE9CHMA priv=MEcCAQAwBQYDK2VxBDsEOSyN4ZYwhKDTlXcsXhnxFCMatSeRxC//Wf9HZniEYujEVm/kpqp0g0OhUHESlqLfgZhUecUWY6/QfQ== msg=jeGWMISg05V3LF4Z8RQjGrUnkcQv/1n/R2Z4hGLoxFZv5KaqdINDoVBxEpai34GYVHnFFmOv0H2aXFkuETCEhA== sig=dTr7EYnVl/jXYzNx/15R8r22I0QVkh9xy8fVKorfdHbr3lY1AoN0qU1hJHQD1IzwDgQAqmEvwqIAKPxB7GB+zv+N/grEPdjk3FsTD6mcppz71E7UvcUebtHMWPlnMvPIr5zgu25KDR5Gi/IqwCFTUD0A e=found 174 iterations", + "pub=MEMwBQYDK2VxAzoA7iT7mv1jX9t1mkYRa8t+6AeHIkSw/fisjtWWNRhwCf4MnivrqqNCi901QLQ0af0o4oCdpRKxTrQA priv=MEcCAQAwBQYDK2VxBDsEOfvLgQP927GG2h9OdT4QcgZr/TXAXhwvbD80yBUtOn5RMmO318rI67XICLBxFgLiTIoBuC0PJUjx4g== msg=+8uBA/3bsYbaH051PhByBmv9NcBeHC9sPzTIFS06flEyY7fXysjrtcgIsHEWAuJMigG4LQ8lSPHidUhuicdc7A== sig=5ZIZ7k1GQzpvIkIvzZJQjEOwb14pynekn+OgvF7TrLL2hbItoitQqryj5fl1qUkVPY0BzPRqv++AG2p+YgEGQX6i88u3X5wDatpKaqBsKmBEnElx1+s9Zyhwo9jbH02U7ayQK5RQrw2lyI+gG8qcyzMA e=found 179 iterations", + "pub=MEMwBQYDK2VxAzoAEXV2fLCP2slwN4Qu3WHwXqZrezhtDDU72XZ42mGnpvjeZRDtNZ6g1j0yPDpv4SM5VospHbmekCMA priv=MEcCAQAwBQYDK2VxBDsEOZTcNMUnSBVxyYEGinJX61i5boQHk0wo/JSyNVMF5Rwv26nPLGvLPqnCtdOBj9OIvnGHQuvtxuwHtQ== msg=NMUnSBVxyYEGinJX61i5boQHk0wo/JSyNVMF5Rwv26nPLGvLPqnCtdOBj9OIvnGHQuvtxuwHtWn6nziwQZVEUA== sig=4aL5bfUZsC97ga3f+7PCdC0Yz6a8Pe88yMZLydQzRz7XD/PLCQz/eI3Xt9nNcpIhn/jPqyi3fzoASrOqGm6ut2Wv9Ao9oBN1awseUjGv6LMLKbUpnYQyGsnLgY3RgVm6eIPRsa6iytLbFmNW0h50vRIA e=found 164 iterations", + "pub=MEMwBQYDK2VxAzoAsyfywVG/NslFPSLEZ/yCJzysWId/8j2HG4WC39Z6bcWsursSoeGbr4ZJIuIXEGCRGOg3a1dJ1uuA priv=MEcCAQAwBQYDK2VxBDsEOUXU1ejjdyJtjmlvNnF7Bb5HEC24FmTihiVoldLCClsoX8hLOGhRnrtJ5XBt0Jk9hFmLkk312MGgAA== msg=RdTV6ON3Im2OaW82cXsFvkcQLbgWZOKGJWiV0sIKWyhfyEs4aFGeu0nlcG3QmT2EWYuSTfXYwaAApFgtv1DR+w== sig=8KETHKUWau/X6akJZUTAtk7zkBnmpNyKyJsDSYEsYMIlSamL4wTx2rRLqR7Yqac1zGlwuxGY1gWAZVFLMy4nU6R7KhoZ4V2xmnIE6cLA/bwHKMBALiV/iBaRWS3B64fTjGUJ1iWgJHfRGB1jr3RL0gUA e=found 151 iterations", + "pub=MEMwBQYDK2VxAzoAyWd3gttciIDxHu658WkAcF4Ey7rpfg8D9YDRjvklehUiYYc9P4poQTdQDhnZEiqlTKMsQYuk+0GA priv=MEcCAQAwBQYDK2VxBDsEOfoSTHe8gSNi1Y4InbLjQKZiycNyYVKk5S6r/QeJolo/tdx8Jt6gaI4MtzoiwIufE0v9J8RwjwwJEg== msg=+hJMd7yBI2LVjgidsuNApmLJw3JhUqTlLqv9B4miWj+13Hwm3qBojgy3OiLAi58TS/0nxHCPDAkSFosawhklpg== sig=4aRoUJOkYws91WsTIixKGOsOb2HkYMMNqhNwagQcWrghia03quNymx04X/RyxcdrcbkYO9qwVEQADheQgnU/0B1zg9UO2NvIb/HdiyUkO5piJ0dugFfmWTN8+/PHRvFRieOlF5rHve3j368K6MYmFzgA e=found 189 iterations", + "pub=MEMwBQYDK2VxAzoAEcpmnZORdNdYJ6DHFDKQMnpgEZROZLRyvKogavyBL5nDKFZ9Jn2Zln2YFgNJmE+KO79rnHeVlc8A priv=MEcCAQAwBQYDK2VxBDsEOcdJ9IIvqRm7qZxl1IXwMwnHmP/ZIFRfL/LoXGmLSRzQsrVl5wZ+WST3z9XM2GgcFZvXqzahLxQWuA== msg=9IIvqRm7qZxl1IXwMwnHmP/ZIFRfL/LoXGmLSRzQsrVl5wZ+WST3z9XM2GgcFZvXqzahLxQWuEEOBAFTLhLIPw== sig=wye2wdE4UthH3Dj/0dwK8H+Ztn6bobQLXap96P8VrdhgXISmpuTKumBRFLOaQ4HXYiZfmBgfH7OAzXUg5/Hx+i7Re2Lyp59CN5YSP/Dz3pSjB3ISn7GCqdn40FmuFDMLuhMh3lt5FWZfwvhm+TB3XQAA e=found 188 iterations", + "pub=MEMwBQYDK2VxAzoAYYpGQL4r9BRcHvKXVuU7kcL/KqNY0qRTYFg+2c7eHLJQMg1xWvK1Y6VEegIEQ1ifha1VxrJv3fgA priv=MEcCAQAwBQYDK2VxBDsEOf7qsgBOuAnksngqr3sl60ktIfWz+4zNTQGDatoX5c/kn11Z/hwAnXCW/Dl32uFAIN9BK1KADm/Qmw== msg=6rIATrgJ5LJ4Kq97JetJLSH1s/uMzU0Bg2raF+XP5J9dWf4cAJ1wlvw5d9rhQCDfQStSgA5v0JtfVxYktZVeiA== sig=A5CwwU1pxAtM4zRYrOHUMRtYJRFEJZHu1iYbN21cEiQtKcNkZ2QLdA+2F4PbJn69ts3VjOxzJoCAvXt+Da7N6hGC+WzUJwQg4EtaPkoVRm8WLwxSkUYvS8tSse8GTdJ+dxIdmjTJTle2ggzNaINlYA4A e=found last=16 s=8 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAxOP/xq6ECuUxQLWv1IWz5mzZmhwqwEc0IRUoy83bE3P4CHixW1jKx0IzaeDn6J5j4EcYtLfRvwMA priv=MEcCAQAwBQYDK2VxBDsEOSmfCfjq5h57eJPIOagJlrKpC1d3SKnmQ/iwBJjR8hBE4d2j6FgmadfNlbHKHmobe1fRUwbPlb1lxA== msg=KZ8J+OrmHnt4k8g5qAmWsqkLV3dIqeZD+LAEmNHyEETh3aPoWCZp182Vscoeaht7V9FTBs+VvWXEoaPCnGjOPw== sig=PqCGae2YyUCexlvFU8eAKTsuTNEkzObbm4G6XyGOJqEd3p0i13HR8Brn3wtB7pqmDDqfgizlSg2ArUMgPxLOE+FjnTK+PA06E1rvdE0cEPkkhYIhYAK/aTgNsNBhGDVagfG7v7n5TnUThPfBwzwOxAYA e=found last=23 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA1CUfENN4Pvj1YEQWw1rb7E1bDZfNtbjHj/LnOr4M4Ge5qG2ggipgsOCSyRUOnpV2/H+jk+OuQi0A priv=MEcCAQAwBQYDK2VxBDsEOX4BNQVSSY/lsCSxzGCbHntpbu+m33fD+mXX2vpI/kZgNDe1XnF9dnQXILdkzQkZ3uUcRtraLmrE+g== msg=fgE1BVJJj+WwJLHMYJsee2lu76bfd8P6Zdfa+kj+RmA0N7VecX12dBcgt2TNCRne5RxG2touasT6n4LkmAvfig== sig=RrPymQJl7BsFYSWNYqDBAj3wcoe6UPjf8hdaFcIWPtX3nnvLor4knd7uGospurcUX+9pTY7DIQsAsg7S5Wkbp+srYNZZqtJOR7Mkw5ph+s/W1ziVTGI/fUxFoA0fi8z22tryhQ8kujrpQZsoBhBqQAIA e=found 173 iterations", + "pub=MEMwBQYDK2VxAzoApAjGMqYmylIijKT9aV1W7ef4SiY96Xja0ng9V+fPslD3xVu68AyJOCnLxhRkGXOMrTG5IxNCTF8A priv=MEcCAQAwBQYDK2VxBDsEOcCzOJ9T+hJbcS0/W1WkcMO2KtuJhJsSfvQSrmvS8AnjFKYA9oGTf+h1c+XQrpyRbTp6HztAVGtTUg== msg=OJ9T+hJbcS0/W1WkcMO2KtuJhJsSfvQSrmvS8AnjFKYA9oGTf+h1c+XQrpyRbTp6HztAVGtTUje0krjZJ5Bl4Q== sig=038Bc6djRenY04WttiLj01HZNLO+/0529jR3t9iDOi8GrYEIQiKHIFRA3hK/surGOerjqq+W3+qAl9DdD3yLroftzkcyy6TPvTSZatBe2HZOqy3S0QqcqytvwGRVtLb0g5/ZJp2VHZFNoB/8L69zZhgA e=found last=26 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAh5eRkRFrmpatlv79IyRo2Ew0deQZDTH8CDNNpmXA3BdjRQJsiZIVYdi6cqf7APDXq82gKY5Eiy4A priv=MEcCAQAwBQYDK2VxBDsEORSGE66s/36FRHQkHmERrc1OoRXnhmM+Gryf9gJXeBO+FL6RmYEb1PQktyF4lOqxJpLY0iGQasRDRw== msg=rqz/foVEdCQeYRGtzU6hFeeGYz4avJ/2Ald4E74UvpGZgRvU9CS3IXiU6rEmktjSIZBqxENHtTtmlMsnsnWyGQ== sig=ztnU34iuhMdqRXJX9oaNwTwt39R6lgfRvHDNzxmmODdQtIR0Vwx6DcYjMQOpJBC2j+wzLUS1KBSARU3B6QICB64Fjz2uejTMWRw10uHG9LJ3czFWKS7AlEIdTDNN+5lISfW0J2xomALDjiAqrYsp7zMA e=found 177 iterations", + "pub=MEMwBQYDK2VxAzoAx4Qudcx0VUHOjIuLCn/Q0HCVrcxk2l/jI+d+KDgVwZE+vETW/9UzlcfpueClC/u7UmZ8db4F7+IA priv=MEcCAQAwBQYDK2VxBDsEOceDjWxNHMbgWsOUj06dENIibBZLnQ+ntELVLOplOjgKMTEJKf1548pqa0Na2YZd9ln5rVP2tgPGXQ== msg=bE0cxuBaw5SPTp0Q0iJsFkudD6e0QtUs6mU6OAoxMQkp/XnjymprQ1rZhl32WfmtU/a2A8Zdtj2hnK5rOStfrA== sig=8yAzFKopFewB9gWiXQ6Rnbw5+bvQ5N/R8Z14FMXEKos9Rf9D4R3xKmeHCOWEusB1JS3wamEhOHkAgN7Gn1+ZnVUEuDtym6OvsXe3m2Vw/zjsoWUL9eGTiYiP5ZydISK4idEBoV0HiLkEMihwA/P+gQwA e=found last=24 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAYP5mZnwYMPy+odZB7N25vj+ds9Pd/IS/9D2/9nDGpEfBEst3eeipdZlxqybGT+MDJPykV0kkzG4A priv=MEcCAQAwBQYDK2VxBDsEOeYctGz0U1ecBkAUzdg+kveN1esd1/tFowefeMKW3G06JjrU5EtjsYCQqXITVk8djIH543tNWj/WLQ== msg=tGz0U1ecBkAUzdg+kveN1esd1/tFowefeMKW3G06JjrU5EtjsYCQqXITVk8djIH543tNWj/WLbuG/ON5Eob7pw== sig=bLzTrLvYl8Sa3I1GBcLGkLMJkMET3ik+/yDRjeKKTOJEVT1UzsCV/HoBrUH9Wq+abz/yJZjHHNcAxrpAuVOYUe9S3FsAZSPdYVtSNVKS+7rjMZmQHoa4GersnALFAgCLY+w+QQXiTRyiT4zNoSIrnBEA e=found last=25 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAaWpfREeaKpRR3n+0Y1wSt1vMt3RKZkZJ+U+FnY8RBV3laaMQHsxjWr+zjX10TeRkPKyW8rpCsG0A priv=MEcCAQAwBQYDK2VxBDsEObeQop5JXx7SoeZYym6XE2wYNaeE97BwAVqmZhy9JdZeRzjpEL7s21SiLcL7cPimibt0tOhpSKxmGQ== msg=nklfHtKh5ljKbpcTbBg1p4T3sHABWqZmHL0l1l5HOOkQvuzbVKItwvtw+KaJu3S06GlIrGYZbHgruZveyUBJpg== sig=4QjGKh4zu82ZcxRX7vy+MssFWi2yHsl9LzYG/IktsG2QcMbuf7xa7LPmrFNgRMkk/yaHfldcHagAlTd0Zcw5bkbcO2JblMXi4lH7V0Pt2Kz9ERS89ZDkqNPFK0iwzqH/OyAaooOOQMhgUgq+vhWibSUA e=found last=17 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAwJTARBZ0b/VlyTEWCrsyV0MUZmi+GoSQNsqk+EAzKoIMtpA+YwjKVzDGr1q2KpyV48woK55284mA priv=MEcCAQAwBQYDK2VxBDsEOZemHiSVUpL+ZCNk3UQ25XvnbNYtQ4QH1TFLXT4KtBrtnlVS9ya3wke5onNpQSJwkUJNPKmvaEnaRQ== msg=UpL+ZCNk3UQ25XvnbNYtQ4QH1TFLXT4KtBrtnlVS9ya3wke5onNpQSJwkUJNPKmvaEnaRS4PapCNifpTeRjxjQ== sig=KF/+U0FrFWt4vjb2lAF77K5gPw3NmRo0smvuXOLwhjZoVv8UASkehenJQWo+a7qHuXhR9UJau2cAHAJ/w7p5c7uCuQUwTn6sl1pNaugguByR9ABYSDBysHKg+jlirRBiLmNShRdG4J05DoPLEmdDiicA e=found last=21 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA2ty/XzjT5A+FNvNyQ2qV5XHWlcSFun1b2Ni77nVqnuIq5Q+k/GzghpHI8IKE/dscjbteGqNRPPkA priv=MEcCAQAwBQYDK2VxBDsEOXl68kJptsg/JfbOs0YeyNRi28jcDi0NLHec/aKVGvzte7Iy6kJmVoGzjAZcWlaCXWBfiZcpTWhK4w== msg=8kJptsg/JfbOs0YeyNRi28jcDi0NLHec/aKVGvzte7Iy6kJmVoGzjAZcWlaCXWBfiZcpTWhK44qTyWjugfms6w== sig=Txo+dlz0GVnhpkOAInxfuP1OzCvhK6927XgoO/FkF/CHFt4f61KUt4xZnn7P65uv0ZxOHlta76MAU2ohkqejz1ktSYKgdfarSDMcYG6V1EMmLnsfB5hyXRq8wkrEzEiJgBpXd8CPzqdWz8gYqPPZhQMA e=found 184 iterations", + "pub=MEMwBQYDK2VxAzoAPUDP9fmkCzMyRcdVeUQykqJXiDi7zfwEuKaEjcOT0rVbEAbkaX+JsN/iEcnWwnIJdlaD6K0bH9KA priv=MEcCAQAwBQYDK2VxBDsEOc5kwkz4wAtppHMBxrJioWTNGzpKmdHdPZ0Zj3hu2RcnHC8Q7a4LihkzpaeHbXUGZjz2zPOm4uRAaw== msg=TPjAC2mkcwHGsmKhZM0bOkqZ0d09nRmPeG7ZFyccLxDtrguKGTOlp4dtdQZmPPbM86bi5EBrnX/L0HMuS/zqPQ== sig=GSZMHbgu2TKdZHzVt6XMgHSCAJF7qoIwdh1MC3kDgD3dOoDHt7tn9RPb7YxW3eJK3tY4MEz1/miAXtT0sWIhyXzKk96iYnJ2h0hjoMMTPO8h09eriNar652Z/bXcW6B1CQL9U8DuLDQzeRRDyDdQaCEA e=found 181 iterations", + "pub=MEMwBQYDK2VxAzoAPRst9mM/FBrBLHKr7Ht79yIIIpdoC+cRgKD895/hmJC8C2OaswUs53XCPERZnPxVa8T1uGbNOkQA priv=MEcCAQAwBQYDK2VxBDsEOYUJSoF5ueDbgeDe8DoNBFuc071CMd4KDgxQobuwXBNVcm6Pg0ZdGHhWgRl724A1IpKbVotjEt3fCQ== msg=gXm54NuB4N7wOg0EW5zTvUIx3goODFChu7BcE1Vybo+DRl0YeFaBGXvbgDUikptWi2MS3d8JWfpwyfqnn1/tUQ== sig=JMS1Xz5NdfoxJzfdrRJ1v9QURib9OX4jMneTWAwBmAQbsP3b6h9F/r3noXD6Bdu3CxcujoZ0LR6AWVrT4Rc1ew7sFfGp8xEcJi6UOAF21ZmyeHtX9OKInDdeZXMRFX+ZhlgY6QnoBQXG8Q+P8cTgKxsA e=found 183 iterations", + "pub=MEMwBQYDK2VxAzoA6ef6NpgXV1wdsxje5eEnLqhBMxot8kRjUO6tvyabx0JVmB1pC3Yk/8ydvfBwllY82hzzsyPyDFoA priv=MEcCAQAwBQYDK2VxBDsEOUhWTQ3r4ElKxYrserD5+HAo4G5rybqcTOti930SZEkRko+oDcxUy+3xJSDMy76mwU+8J9DZ4sejlg== msg=DevgSUrFiux6sPn4cCjgbmvJupxM62L3fRJkSRGSj6gNzFTL7fElIMzLvqbBT7wn0Nnix6OWzLORHmxUF/ADJw== sig=GjNALmmhG1mY+kCKlrICC0Sc02/3KjWPECVXt9ir3TtleGRNzhvSq8DnEOmvbbKwCLmb+w7r2fyAz3YiKnWWUgh3mZFsmlE7X3je9aN9JgI+Dsq057KRL0bS6ompXA6rvXmA2ph3eIcdWwpI7KA6ixgA e=found last=20 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAdjLaxgh/RUD532V5oajhmS3mAb4MHW3CJgVut6FMwlUR5uVaVUE/WDL31a4t+me9LzHYuu6a5ZMA priv=MEcCAQAwBQYDK2VxBDsEOfto9QweOzTn3WqMjn5d96hEt0Bx3cIkvjwWCHrapBwD6cZNMHZohwVLc4AEhjJ+BCad6aH2Z5LYjQ== msg=NOfdaoyOfl33qES3QHHdwiS+PBYIetqkHAPpxk0wdmiHBUtzgASGMn4EJp3pofZnktiNK/pGNID83tgF+4M69g== sig=KCAXzLyX05RuxVaoYV2Tafey4SgOwDFc1h0zmdEZIwwl64sq/cgTjDs6/6jiQvh96VPWTWWrUzyAX2Ho6XEbvFsP4vBihIuVJVyvsgCP+OWamDXgwLLuGtkIZGNCVB22wFKz4+V1O7uWnWBVP+fjtjIA e=found last=22 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAmaYySPdRp9Flj5IlbFLN2gvgZg6cQFolfmU7Xs/5ljnFy2ARkNeYKOmZfQxv57MP9Ui0pZWPgv6A priv=MEcCAQAwBQYDK2VxBDsEOdsV2pshtvTgewyyp7QdYys07Vp0pO7Oei3U0YGSDCJ6s+rIcbEmur3CndVBBdLsIL15L79kgssQPA== msg=DLKntB1jKzTtWnSk7s56LdTRgZIMInqz6shxsSa6vcKd1UEF0uwgvXkvv2SCyxA8nUY8h4xqntRnE7l6Kt98CA== sig=jOmfIi4CjQkHqN35bRUBGXK+7uRNgqkbcWmjZ3upiqb2qLMWwT6TSEDDJxKeeI6sDvR1V6D9TPqARe7OG5jOO8NSu+Dbsjgm0EGq90In2EAY4UfWQEOj0jr4xwNZtEo7ceBnszBi8o5pEra0nY8rWxwA e=found last=14 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAU2014hYGcLd08hltcD/F6nfKKeAS9CUy+XqIcsoAj0lY7WQimmWI+94LMc8f/1ZGi1ccrwyzp7iA priv=MEcCAQAwBQYDK2VxBDsEOXrw/G0pHL/n5uYcWeen7amjSFVM5p+UKZLPiL7a0USJyjLcVuAR+NSEhe3WR1fvy6IGURW7wQbr8A== msg=5uYcWeen7amjSFVM5p+UKZLPiL7a0USJyjLcVuAR+NSEhe3WR1fvy6IGURW7wQbr8MzYn/AgsaTorWc8hMjZ1Q== sig=F2F9wNfmfNk/w1Kv/Eq7BH0qfxKbGpTOzrF/Iq/GYS2IGyLzXeiQC4BnNZ12Jl4PwWSngH22e84AGrzgMXbWTL7dY8IbV/leACXYU1a0huJHI8m4Yo+kVfLCMkIjioigDQ3TNGpXwMtk+A9Dq8roEgIA e=found last=24 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAiYj6jMUS3DWq0PIxeRMLPAt3OM0qKepsW58VdK/nsjuOLPH01RXfpaq6AtsdbZJU2Ox7uULXLegA priv=MEcCAQAwBQYDK2VxBDsEOUMZMesPdsoAi78kOWFTFXsv9iw7N9J0LI/wvMtQUjuAiU0bY6gRhMhW2jAnNDNjj4PUfA0t5Xyv9w== msg=OWFTFXsv9iw7N9J0LI/wvMtQUjuAiU0bY6gRhMhW2jAnNDNjj4PUfA0t5Xyv9wi6/E7jkq2UFgpHg2Uz8Qyd8g== sig=J8J5N2UQ6AV3iyXXN/n2tSi/PcLc0p7qXsXimaR6usQkBA+wZuVIQ0vgeFgZz0DZ8qIozLb1/70AFczaayiqxHg+o29pA5n9mWGqJoWr02RFoOEZtfwJdbgWtJagkFHrf6ARGNB9QBF3p6e7hEUTcQ0A e=found 186 iterations", + "pub=MEMwBQYDK2VxAzoACLmVzOIfifPw41Ni584yp5iiH2IU7O48234t6BVXoRKIOBGAIGrEZqk2qPE7d4OBn5ZtPtMVE64A priv=MEcCAQAwBQYDK2VxBDsEORme+x8Qk8Fgvht4apol429Ua2nMZnSjvogxRc1pQOuHRHC40l07xA+KcMWWyoPMPTbNY1EtMoRRIg== msg=GZ77HxCTwWC+G3hqmiXjb1RracxmdKO+iDFFzWlA64dEcLjSXTvED4pwxZbKg8w9Ns1jUS0yhFEiY2QcMlKpNA== sig=3wDj9glQGTM7YbTGh2uHPVEvCT+b1H/5C0ikybp3vJFoNyFuVEgPLWTD22T9o0FhBc/J4De4+dsAnuwCDf4FfsjqYZLmmBhcDfJUp4B/KGr9dg8GTdM3bhgmPTMP3ghtOQ9woQ5UiTVI//EldQDbJxAA e=found last=26 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAcj2qpMWNA5AuvuPahpq7Coe2ChPv1Xa7Xli0zUbbtF2+BwN5JVLrBmRMiQACziXdng0sZjbEHhqA priv=MEcCAQAwBQYDK2VxBDsEOYwXk8AMuVH1vpnLL3MsZarWHVWLIMDVfR+YSgbqBvr0CHA3fjj94n3Y865/OEgaXp8M4BX5Vyd7YQ== msg=F5PADLlR9b6Zyy9zLGWq1h1ViyDA1X0fmEoG6gb69AhwN344/eJ92POufzhIGl6fDOAV+Vcne2EH2kZqkpZXVQ== sig=mZzyajoZIFXnhnbJNCchPgJaSndvC9JQamc+bxfuxOiGzdXFp+cplO1hP4ZYsxn7qRakVICvNUiAkyNkZj/1jNkJ+TYimmTfd6A+3NqKsWg9XWeAmK9vtOejRHq29QlLZ9tg0pI/0bcrQzt+li06ujwA e=found 159 iterations", + "pub=MEMwBQYDK2VxAzoAjVdvNvceT65JMwfJtDD+EZOYDZ3mVY+vJFTqwQ8dnKXtPw+kolDayaTmcnKZCbkudVdWAgJVX2iA priv=MEcCAQAwBQYDK2VxBDsEORrv5FnPB6bYdee/NSjFOj/pHTRkDQW/jsEC5fQp+2R0k2XNxg7VIgo/5uOfjB2Y0nVdzOXdZ87U5g== msg=5FnPB6bYdee/NSjFOj/pHTRkDQW/jsEC5fQp+2R0k2XNxg7VIgo/5uOfjB2Y0nVdzOXdZ87U5sxpuvC0wc+Mnw== sig=NaSpZfcm/ggpAYsBaDCnSREo6RTjQFg8AN9Sf4l5/VZu3sdXR3184Gg3LnKcvfTw+p5KgWZhdvGAzD4nVo0nHDSql29CfV1bDrLkCe062a6RsqOjw5uRqVQo/a+ethfY9dQaeXd44Zh+KTc/OPr1fgcA e=found last=22 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoATBNgIOzv8LXD4kUIbrU/kOwQhsdijx42md/8omayeC3JHz/cwzznqRPZUQs+uKNX6n74hUa5pT+A priv=MEcCAQAwBQYDK2VxBDsEOZ+Fa1tHktdsr6H44bN2Dvna34JFVkP7b7ToXec0Kj54+mWEwRd/dNlEIFCaNlizwmxeAw/a2p2paA== msg=a1tHktdsr6H44bN2Dvna34JFVkP7b7ToXec0Kj54+mWEwRd/dNlEIFCaNlizwmxeAw/a2p2paEVWGrsXeGzaog== sig=chHBKUDd+PZJKvqaiNLy8kDsHX0kCPPcBf+Y6rG1Be0WcPcgndPq83hKmPl14sh8rn8e1QG8/IeAc67I8pduv9ht2hvmAceANusKhD2wA4M53EljlZsSzYWsNdQDwfHoXtP31Sm2Z1cOKpDV6zhAPzMA e=found last=14 s=8 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAbvDt4MTpNI8t15jFrTN6Q5nsLi60k1e5WQ6Rfd22Eob2QFXAT40cAxgsGIVrxhk/WBSlgC30rzSA priv=MEcCAQAwBQYDK2VxBDsEOeujlHOi1ISgQFMAqh1VsF69fGQ2lKnFLohn0t1rpUv8rSvG3Rc5wJqaTRwmVpOIVdbcl+nJKKmyGQ== msg=c6LUhKBAUwCqHVWwXr18ZDaUqcUuiGfS3WulS/ytK8bdFznAmppNHCZWk4hV1tyX6ckoqbIZvSsWIbxVjGsOAg== sig=atgLezVmwDnyg04fpSRK/L4Nt6OTTIvdZR7Na0ZRxisaVab5GwL6C0ToJyLSXpLWAee4ZHc6KYqAXIzIu9uz7GCgt1HhABneVEiqhyghJMqzVIH5L5pn4c51OqqgYNht8b15C+JjOKZklNdYcDDF9jcA e=found last=22 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAqyQRPnhFsIykNK9XEf5oImW8H3fj2kezda096is4PksFRJEYp1/ZYowGSAPARB0q7z0w4aQgSPaA priv=MEcCAQAwBQYDK2VxBDsEOWRdTGhoz0UqvQJrintrnjvQOBGF2JjLM1M5qBhpc3lBQ3nR6L4dZQpZ6/s9fr0aWB6CsRvqxJuJaQ== msg=XUxoaM9FKr0Ca4p7a5470DgRhdiYyzNTOagYaXN5QUN50ei+HWUKWev7PX69GlgegrEb6sSbiWkqW6LOJSyI8Q== sig=x2VRQx1Rko6Ps5D/E2pzRp0E3cLpBynJm0TO4ya0kR8hSQ5aBozArQSwWWwmj2fG3e5nISHJeLYA43HO+3u2I9pd/CsC60hSpGEJWfilALEwgWtGZNd5HuAzS9+2cbHUSxX+74VioUs8DPb0ajDwuigA e=found last=21 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAT0AihSNd+5IzNrnbCHvBXhTUKrEnhalgV6oMX3m0m7fNngBhqR3pla2tikBck3/In2AMcMRbYrwA priv=MEcCAQAwBQYDK2VxBDsEOV4LGYbKNFNGMxaXyv+bTUEZ1EzffLEiA1tgbmPw9m22WpqljZOqRfxTHttgl6zZP7bNBWA2S2U7Wg== msg=XgsZhso0U0YzFpfK/5tNQRnUTN98sSIDW2BuY/D2bbZamqWNk6pF/FMe22CXrNk/ts0FYDZLZTtahua9cv+4tA== sig=I3re6SeLTg8sWQEjRlLWvs4P6tm2KwhJ1yiJ+wPwxgwdHuXPEfgntbdGF6tLt6pWMZ7Onto6G4SAFcnWbyODgU0SsR16ISQQ5jgJ+WTqJDz0lvOBBvWxHsztv3xtPRAUguJAKRLOXeAikUrdo4BSxjgA e=found last=19 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAJVg8rlkB0hT+3pAINsJOWaivZevo1qJzZq4Rdfhu2xMAORiXZUGLbCkS/kwdg/k4bvEHh6BK41+A priv=MEcCAQAwBQYDK2VxBDsEOegdQHaPQp5NpZ/3AyJeoo5h5l7aZlKmKvB5Im2PZotRCpE0ES0o4qhIR/b1Flct+ksHw8nz3WDYNA== msg=QHaPQp5NpZ/3AyJeoo5h5l7aZlKmKvB5Im2PZotRCpE0ES0o4qhIR/b1Flct+ksHw8nz3WDYNGnz/lSKMVwlpA== sig=CidbsYTYG5wp3FbbOKyWJ7sOq1U4ZjCp6TENJC/3uCT22Rfl0UiNXiTVH3nlS6TZ7UPRnK50i28A4b0iiEY8pyqZpef56ohqLPkKaFPYSDveSRiBJ7MS252ibpmAvsQcOiB5q/36sbq59stsbBku5hoA e=found 185 iterations", + "pub=MEMwBQYDK2VxAzoAX+/Wik1TzNKlg7KRBRTAqF9wuxiZU28b59gp/2YBNU+D5lSBz4jFzb89Z53BSjHZwQIuX/+3zbiA priv=MEcCAQAwBQYDK2VxBDsEOS+M6iG1/5KRXgY6qAqmR2L9r8HByMZe6kOxh31TQRi/WTWLuAuK85HaVSRrP4heP0Aps+BNPkm7LA== msg=L4zqIbX/kpFeBjqoCqZHYv2vwcHIxl7qQ7GHfVNBGL9ZNYu4C4rzkdpVJGs/iF4/QCmz4E0+SbssvYMJ8wohTw== sig=pzbM8lEh8KAgL55awvgPgM4x1eJ7NfAyR6B7IiLdAqqsyKzUyhsvFu9dmKd0+W1hpjtxrpkBR7UAT3cVgltaEGDh4hguLrRIrhng5fJc3hRh+Z64Nt+qioK/DImfXT1LQ77wgHh40CTZ9I3+lynykzUA e=found last=23 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAVRrSYmr6xF6+JFFcvAahCNjg++BDiG+7C16Qnm/sf0VTh+f5FuoX2EScOEYFIHb0WXXbHoeMuVOA priv=MEcCAQAwBQYDK2VxBDsEOZ/IOCppiPGG1L5nVPgLGuZuLqxC/2CYIgXiRVk5xncTHmE8GavbD6PSaYKReqIi4etpPEjExl1bhA== msg=OCppiPGG1L5nVPgLGuZuLqxC/2CYIgXiRVk5xncTHmE8GavbD6PSaYKReqIi4etpPEjExl1bhMyrG+a9c3xebg== sig=XW50eLfH80aEcfpTTlkWZ3ntG3T+xYthACKJgS4VkmKpor2RqqorUihcbcucYbHS6ixEIp7Ty7mA0hbVySDo2rbCKbB8tQljQ2Oay47fPz8/g8gR7l5RZpUHn1DPFB0WGm2Tpk1RwqecN68hMvTGmwEA e=found last=16 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAVkxb//gSa8vSsjO/KmfI7lqDfE7h+EZZc02f34r4daa7kSVXYzlZyKb63SAHFYjusu+56f3xV3QA priv=MEcCAQAwBQYDK2VxBDsEOT31TsljTmD9ceIqlh2pf9yOM1jrH89EtPSMOr8ZkXqHVz0RAqmerwsVVOHipIZ+RpVwQsEHWhIcag== msg=TsljTmD9ceIqlh2pf9yOM1jrH89EtPSMOr8ZkXqHVz0RAqmerwsVVOHipIZ+RpVwQsEHWhIcajZEar9fcft1fQ== sig=VBskaJ1vXzOWiRaEI74vmcHpKN1z5CpK6rR6S4TgSCPUiT1kdsKhMTLVqtnW6iVyaJ/D6KjkP6sAQJNLEcNBHiEW5OL1uGdRn5ZRrZho4xh2qgR0jekeKV9QsacKMMgCZbx2nMonEP/jQAaRNB37RQ0A e=found 165 iterations", + "pub=MEMwBQYDK2VxAzoA0knIkjggTJ31NLCVM2+mHxAQEGeRN7Svc534o/tLlI0/o4zjq4tZIewEoLkrM/dqI3HAARJpXI+A priv=MEcCAQAwBQYDK2VxBDsEOTF3TZ+kBd+nmc+2vYGomm2B6qNuwkRzAB36605pXF8dTF0lIGaiz/rT4Z3QBXp5/OQzFlZ3OlRdzA== msg=Bd+nmc+2vYGomm2B6qNuwkRzAB36605pXF8dTF0lIGaiz/rT4Z3QBXp5/OQzFlZ3OlRdzLhOv0Np9VHt4/22sQ== sig=8xytufaZaEHegC2p2eOTRBb15cbYtWaCgxrAloiy1YeEoSyO6OI8GHK5pPiR+wyiq5QNKaQYhqCAIR0R42CPZ1sH6FP+5Tm87zbd+dlxkYfNPmdSunPOr2/sNEwTS/kU9VKxpHA3dpDuhk1C6jcBiSUA e=found last=16 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA3oukEljMoBGtfdfmUToCpn3RaPsyfYHucoCHUADc0ZnjQz7CNj1ZcIPFS2xIrTCHFZdnRX9c54wA priv=MEcCAQAwBQYDK2VxBDsEOSlZkvq/kH8yN1ct5kyJkJhtA1mDAH8sWHzfjegabVn+sW6dZQoQZh+LuoDVoeIm9By0ADRNkro7WQ== msg=WZL6v5B/MjdXLeZMiZCYbQNZgwB/LFh8343oGm1Z/rFunWUKEGYfi7qA1aHiJvQctAA0TZK6O1nQPwzMAyswEw== sig=h85ylqFYFHGQw2uB+JO4yiDIgpUHhbDtAWKtivMhBDiuM+AJBMoOZkBJpY5yQApVQhv/VaiOIPgAEd0rTdCPJwynqaRj4w3AJ4e7FkqZUXfJXCfNi4+/HABEFhi97FHRlFdkQ6Ri54w43WAX/IURPSQA e=found last=20 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA7N+7hXh6gwAts93fm66zZ1sNdpbfKWA+BO8o+FMkUC8rKhDhP4IbtXZh7VSSJvKOMLUjJl+/9yMA priv=MEcCAQAwBQYDK2VxBDsEOX6wt83i6WVFuyHvMWK3LiCHE0uZqDis5Ti3ozACD096u2gJLi2EsZIMW6cvVHdDtqjAKpz6xPLBRA== msg=frC3zeLpZUW7Ie8xYrcuIIcTS5moOKzlOLejMAIPT3q7aAkuLYSxkgxbpy9Ud0O2qMAqnPrE8sFE9TNS2x9VCw== sig=BQvQzGeL3uujnEicegduM1YnUoGP5Ba3gfPuI9ksyaYS0kP12VeViEE4EPc8467DlXpBVLZNsd+Ak2+sjh8kDRQcSSFIOBeV6SDzxHTwQx7ZOoANAR+gHEKyiMMKyO7TwyGmt8/VIea62di4l++76x4A e=found last=15 s=9 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAtvpja62OGHaBotz9PWUIfLBXPO3Wga5TDrOib3qM3sXkvIzi3ncTePKp+x9Wx8P+DwcjWGb66yqA priv=MEcCAQAwBQYDK2VxBDsEOdN0+tpUJqLm8eM+4tE+mf6scF6Ylo340ZoAvCwm3nWsi7yy+jIZ0VfWVNpgCiHrpZRR8H1TLf+KVw== msg=2lQmoubx4z7i0T6Z/qxwXpiWjfjRmgC8LCbedayLvLL6MhnRV9ZU2mAKIeullFHwfVMt/4pXuUP/D/EU9/Zmpg== sig=Qnx8gBBmIU/tG6ZeBNQXkNTirVgHv8RPaXWxhJqEhTWlK5DheBLl8ZUm8lLByfXA9mFymJDwfHAAasigguAwAC5M9JshisCo/JkQclKpZNRuZSUcaQLghIBz/j4sHRmJzwUXgjkExiPwEldVT3xowjoA e=found last=19 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAMa9tuXtyKhO11CFPwN4qIXkOp2if++QbDaMuGBg/iybpKdohOQsm6R1aflpD4OSQmAJs07s2LbmA priv=MEcCAQAwBQYDK2VxBDsEOe/Czi3R12zbuYJk+hwhnZvAooCqR+HMQIaqPzX+stwjalffLCCoOr9FoyJPnkwM527y368D3Z1nSw== msg=0dds27mCZPocIZ2bwKKAqkfhzECGqj81/rLcI2pX3ywgqDq/RaMiT55MDOdu8t+vA92dZ0v6LP7sx9DlqxWLUw== sig=zvLDvJ9FfC8hTIDqj/xiQJk80ABJrmJwMwfG/a/6QlT8cxQMJG+94J/1rK4qd2rrwZYKDIlC6NmANLe9nzmgw5RfnB870bbOmkU63DaxWRBluBkjAis5YIDDWPglwXgZ/FZHWCvm7gagIAfbsSqmUDQA e=found last=22 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAV3CuNH7089j3Goc+SUqgReVJCi6cLeoTZvEzIcCOUT/kA82y2EZYhIIQjpdBNjqR676AfeY5qXgA priv=MEcCAQAwBQYDK2VxBDsEOQXP2YtHT7KLcPXKbmAxgkQWnlnQ49vb/MOM4w4HTYraow1ve+Wo5YabiO84QyMVAYC92n3IRh4NzA== msg=cPXKbmAxgkQWnlnQ49vb/MOM4w4HTYraow1ve+Wo5YabiO84QyMVAYC92n3IRh4NzKv9QHjMPgzPnImn5EG6WQ== sig=zC/fMPIRBviLLFK4MEJjjjQCOgJbUwyAsHc09/sypO+f7X5FkuIcElVc4OguBSxWv/dJygxZRjQAaG9A8UDTQziXQr0X2GtWh18mysrtzeADH4skB7A0DyoDlDTA4X+vXKkEs4/1P0/JR5l0paRmGBwA e=found last=18 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAPwq7kxygFEDM1mjrKvswu9Nl1wZEQ99A/FQnlWw+O1mDGo4zNuD9qlYrsamTh2sttKF4vSYhMgsA priv=MEcCAQAwBQYDK2VxBDsEOfRdfGWStclAQxcqIn3Ujrg2qB+o0okYSB15yQ1UbD+675rFKUfyMpdZa/nvjH/DMUs45mB7GbsSOw== msg=KiJ91I64NqgfqNKJGEgdeckNVGw/uu+axSlH8jKXWWv574x/wzFLOOZgexm7Ejvll1AniXSXo2JpNvGj4RafXg== sig=SPtVtF90Zg3zgJ5vEi0VwrCEbeOMOqe2zj6gkGWX3PVrp3D/mhSSNx+Yto/a2HF0a2U7MfFZkrKAmvxaBsvkXyvK+9mejfq3UicybyKwKwVgbNKK39UD7tCPuvHwib3JSws2ZniWqTfK0hGRrBQqpDAA e=found last=16 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoADo+wkOqHpBQpsREimpJxFXqR/lGpqTZoiYxS/6GwkAg17+SDJssOodpv32+oX1/qkwZLGQr3oHaA priv=MEcCAQAwBQYDK2VxBDsEOYJPrLPDGAmsRqTllHkGhA+Mb5SM0Dp1CYL+czvHl07npTh+MnXwLh/QKcn0osbmyamIjmvYRbUa2g== msg=wxgJrEak5ZR5BoQPjG+UjNA6dQmC/nM7x5dO56U4fjJ18C4f0CnJ9KLG5smpiI5r2EW1Gtqf1BARICLkteEsxA== sig=V/Cc7HJFp08oBkQreZwVc2WuYPZWZ0J1DIRvxaOXPvfA5Ir6eCZV8lgPfAmdFairzveHdvsz2DCAeDXrnPnYaKEMhGEloFlitSKWyFnKbpREeEjdmZFp/QcF+gUOt/jkXbh71Bj9CkRYBSl6QfWfJzwA e=found last=21 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAJz4esbb3/1izABKafbOk0Qfqyy+J/cFqvJoX+czNDekHIO+z83hf4izS0F0TAeeuf4MGZq/4OJiA priv=MEcCAQAwBQYDK2VxBDsEOQhnk1J9KF2Wyo5PIGwnZFExC8cj/qYJmCmVYxecWttCwhq6BV5bcYZhG6Rnuj6rL3tfKihccmurJQ== msg=yo5PIGwnZFExC8cj/qYJmCmVYxecWttCwhq6BV5bcYZhG6Rnuj6rL3tfKihccmurJd+rRSHHABsV8WHHukNv3Q== sig=/+QoCBHiLXWIxY7Ztwb5zAK7CzXNvDlA2eLaAMcdShbUmg6mXT8GJpMVZtOAywqMPxWyVrR5m1+ABNs/NR1fJfrYh6ManTkVpAyrfNmrKiENSYRyh4rkEEtcdQZRWC87viuNcNGIzC7DtN7WRSf2DAQA e=found last=17 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA5Kg6g/HhR853pcvJpItIeXuseWGuhCrl0eZgTqidNDws495jz8WlCLsyDQdRMpSSMfgDHT3cTWSA priv=MEcCAQAwBQYDK2VxBDsEOavG23YBpQFTH53gz+CbFVpo5KiGcillXDVYYq0RwZmc37vSl/KRZM3lNEekYu2EmF2AnFm2QiE0AA== msg=Ux+d4M/gmxVaaOSohnIpZVw1WGKtEcGZnN+70pfykWTN5TRHpGLthJhdgJxZtkIhNAAHC/ASdFZIGH4HsogUrA== sig=HTPCtM00oPp2TRc1v4h6nx09ViBTM45zkid+obu3gOmaXQG/3XxRkqPDBbLJvmLHSYMoaMCyi5mAg3RP36FvVvEpXIYQkL5ygHVDEagM3b2xkJVpTgXNpYvWS+OlUQ/vUVFoVHHsLl4pclToDnvMcQ0A e=found last=17 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAAlGxO4BhYrKzPLm9HQpmOMJm8l6U9tFTyTKpJ7MD5a6j436lczgLzQFZRbchiJDzFTMM0/W6iNSA priv=MEcCAQAwBQYDK2VxBDsEOS9u0i2iTHs9F8t5MObuiS1L/wBh1oe4RrvrCwtYNMbOjhcpqxjyf4lJGpky1+0I735qIWscWWxKiw== msg=ez0Xy3kw5u6JLUv/AGHWh7hGu+sLC1g0xs6OFymrGPJ/iUkamTLX7QjvfmohaxxZbEqLVBYTvfJGdtKaUBE38g== sig=/g/la3VTh7BnmKWagIOavu9LvO1Ihv2oZnadJZlA8fX/wXaOOd0FdzzJquznvCX6jgq3qv/34EeANOlyd/f5ZaW0SZ/vjxBv9QyQ/AWc+r27i0ftLSXCxJ/zkk9JDVR0HJbxLDFXBq0W5F4LUuWaQjIA e=found last=15 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAErEqXX2n1wtNOezE/CYwRbTiXr/MSHGEWKpBCqh1onkNeBtprILd5BKMXuL5OwLvN3ARbf3iSECA priv=MEcCAQAwBQYDK2VxBDsEOYZmm+n61g/oMXU05zZ2xibZagYSM2FjpmwhQ1OKDlOi9y3lWzFjurqemYkLQDUcUFx4WhLLb9bM2A== msg=NnbGJtlqBhIzYWOmbCFDU4oOU6L3LeVbMWO6up6ZiQtANRxQXHhaEstv1szYQjAuirQQmGl0w8U9pM7lr2NjKQ== sig=cAhO+tWJzm0XB8JE3yJf1B4c7lP6KCt/Jdk8mRwg9HZY1zvuOwO8hy+8Ut7rjv5PJNjUoak7SK2AxSrWyzzgemGpWZHA0TlbOjI88Dl2X1FdL0s/K4NG+zIIwU27rFvkDBv8S4A+Z8A5iRGhpzQwIQIA e=found last=19 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAEEtj0SN3LcpXhgQqeboiU4ck/xbYS8JRjmQ9F8tH5qRpHdUx9DsZDZZliuVyrqvnpOyh443VTqqA priv=MEcCAQAwBQYDK2VxBDsEOfDwCaCZdSSbXWq5GPMKwDxwLzMjdAZeq3IJv2mQXJ8NKwhKKR9WUwSUM3yNCzhpXbe0OQ/3yZn6jw== msg=dAZeq3IJv2mQXJ8NKwhKKR9WUwSUM3yNCzhpXbe0OQ/3yZn6jyyIo5qEOXufjALf0yN1Lkzgio1U4llgrrh8Ow== sig=VP1J5qLV7+Sa0rZwGgZuNJERN/nn2Y5uoni2EE1g7/WOE8z1P4YxCapweIlzm1B1jveyQA13UR+AWomrU1mCiCfBX9UNyHxSxcRf56HcxsNnCD+PY1TVXa6ac2HrQy5vWsK/3VKkZDGBpUonKvCEIAwA e=found last=20 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAJ5ljqxcHCsx0+8nEpEZ6RHQZAct/eBg1rc7SIqUavZgLpoWmpRmU9lQat3vgJtI7Jvnh44GkBe+A priv=MEcCAQAwBQYDK2VxBDsEOSAwjEz1cbi0XTVcS3jOkJ4lw6Xh2CRgenSKZZhkXKPTAiRXTxhNFbdFh+RMZb+J9mA5yjKtheKkug== msg=dIplmGRco9MCJFdPGE0Vt0WH5Exlv4n2YDnKMq2F4qS6cW0XqBB4mww+GiLm/2D4bH9sUJJrQMmGbXGpLtWMbg== sig=jqnX+3rXNHfN2AawPwF6L132ubSu5hLU/SO1jJecGeaJPx9r4wn/6NTRn+kXuiQAecGSO7K7BHsA6nJDOjvfa3cptCV0k6210AOjXhj7Dis6JNGVVteZjyIKr2tk7D9QQqYxoVuIBl0NSmVW9adJIQIA e=found 195 iterations", + "pub=MEMwBQYDK2VxAzoAGKvaNG7NfPvtul6SsNhRXoWG7swAddXrf4p6b/EvQRNxFXgtyu4KN/kk7ev9kkDQQRP4PlKd4V2A priv=MEcCAQAwBQYDK2VxBDsEOWmOP0MOtuyKcU3F6M2P4Az42xNrDa2yd/ku8v8DEHWS/Iam3KkuK3ehGCMdowqxODYExS6HRiwCYw== msg=jj9DDrbsinFNxejNj+AM+NsTaw2tsnf5LvL/AxB1kvyGptypLit3oRgjHaMKsTg2BMUuh0YsAmOF9Hs+y8bPxw== sig=kf104gpFs7MfEvF8YAelAIWYbn3yDsISHvamUMp2RMUY9iLfnNATKWMFyBmoLui3Te746au8gvuAJ1s/DFRR0NzOdS1e7l8zvJFVIShfzptzVoiqRdtn+E7CWpds5rMkZfIpMcmqY9ywZgvMZ4dYnwwA e=found last=15 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAMMelfLAlcHVNzThwXy7Y+V+GPlj9xYlFYfxDP2TUzONuspZdFAU/B2jsBUJnE+B++Q9nE6SdIKAA priv=MEcCAQAwBQYDK2VxBDsEOWjyQHTyhPiKPApw/kspHThV4lHVGT7q5HV1miDUq8d6KIsEdDU8KzbL7qahsFeAa++xZ/cfxYOgfg== msg=8kB08oT4ijwKcP5LKR04VeJR1Rk+6uR1dZog1KvHeiiLBHQ1PCs2y+6mobBXgGvvsWf3H8WDoH6O6Xa797ozRg== sig=NxF/b7curRnNjpo2EMToseX6PlpdsH/SIu4MTDVU9JxpBvXIgsKdBXxksW/fY5oEJP0tXJy9sFWAmtI9USh1Gld1Ku1siqBmjnF9Tc1PgU2OeE90cACcWCvfWcQVWFIHjTI2KeWQMp+YekkDQUONixEA e=found last=21 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAAfeKRBcyJyuvI0+hmZjcCmSpkW1xQkmPREWDQf8RAxCxHfyOzGHmNC0Jg9x/4MR66RDCzY5S4seA priv=MEcCAQAwBQYDK2VxBDsEOT6cjh5WqCBv7kkhCYuLmkA2f4xqOFp93uMd7Ub/PmLrgopkVeqE6YOo/wHsuCRnXR+m+eMJkiTa0g== msg=PpyOHlaoIG/uSSEJi4uaQDZ/jGo4Wn3e4x3tRv8+YuuCimRV6oTpg6j/Aey4JGddH6b54wmSJNrSymsQeSGOYQ== sig=FyukK7as8qyjriCOhI+PAhYAukMDumwOgMXXW6J4hFzdrQa0bSezx7WpjY9Z0setlAAgnUAEiG0AmT8okUYiF1FMRJgHHf8587oH9L+/XqKWlUxHzxlDyQMy8sfy0dyOZGtZ757c9f/C08CpVhvD1BwA e=found last=25 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoALaITkHyucAnHKelBLCRu6lMbAFkozELMSmi0JBnu9v4LXIckeoLKSJE5qEg7EJnHZru06Rw1sN2A priv=MEcCAQAwBQYDK2VxBDsEOSB5/fNV6t7u37Fhdibo90k0/OKxh/Cbq6b6uF4UeNPe7fdimM998t7pvkMSIOLiJLpelxmv5jSmGg== msg=ef3zVere7t+xYXYm6PdJNPzisYfwm6um+rheFHjT3u33YpjPffLe6b5DEiDi4iS6XpcZr+Y0phqGm2+jUrNkfQ== sig=aFVvLWweTFn7z/ZWYkldFUDuDW6AEFTx3z5BcnDRE1bjDRnYaO1yokbIgCENYVSsev3nLQ8Sd0MAPlgopFduWBKvcqVl8/m9eHBk+sPwL4g2HExbtMM/E+heZHof/m3l9dNBrj+mzCviREtM+Now0DIA e=found last=16 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAMhWTtjBQzA/dOrd0unbfbJ6A/4HIx0kokS9USRjRnSSNK7ptKVJrX0VtufUmTGTQrdwzRLlqbwOA priv=MEcCAQAwBQYDK2VxBDsEOZgS+PWX5c/ZRdmxoM5pvBIGMs5mKMDLNvr7MulTt8r5qi4xm1tTP5XPAWt1VYiQ0IsZ5g/qUVAf/w== msg=9Zflz9lF2bGgzmm8EgYyzmYowMs2+vsy6VO3yvmqLjGbW1M/lc8Ba3VViJDQixnmD+pRUB//c7C03EWzoZrVMg== sig=HWEf9eGQruaJNbuKMwcPZDFw8DGNvO+AkbXsObOqO2JV2KC7b4KOHwzBZkW/MfbKIEGDD6s1opYAfqZ7ej1cjT8CGApiVjoym1pbqs9TFt1CRbPH4C4YOfilZa0vXuq6+pYIp+OqzMRRRiyRdAjsNigA e=found last=20 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAzNGX1L54UhPb0lyjfDdEMLAxWjwaIGbzW6hU3MmGe4LzAUhDJg0WNIwboZHjIUGb7Dt6V4CI7jYA priv=MEcCAQAwBQYDK2VxBDsEOVhjWYxy9qcKfLWQaBBrekinamnQ5knBjX6K2ZyENp6YVTag/HGEVqX8RrA2Vm93EhIm6PIABRrbvQ== msg=WYxy9qcKfLWQaBBrekinamnQ5knBjX6K2ZyENp6YVTag/HGEVqX8RrA2Vm93EhIm6PIABRrbvbwHhbpTIWhVpQ== sig=Avh3VYEjDWB9lamkAYha8FZccTlVyTUUXZ1UKkyKxo6QEFmlHkIrntsmKlnQLNjdA6iNeyOBVgoAS0iamlSl670EH9yqS4N+mePDkAnQKP5sTTvb/zNXg3CGk/GscN3IGHsyvg2rI6fJEFc+NLrdvzQA e=found last=23 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAV9dMahwCM0fTy4NTTU3FvIh+2YjgS3ZmII1hM87HBYgufYLXR76RPWxHKa/6Jq4EI+50Rw1DJfWA priv=MEcCAQAwBQYDK2VxBDsEOej/cWQDUB5CjOLI11sRA0SDqZjro8K+5+w4pjlmFwo8MzGjchOvSaiDhXQTu/uTD4QaVJ0Edkzg2Q== msg=6P9xZANQHkKM4sjXWxEDRIOpmOujwr7n7DimOWYXCjwzMaNyE69JqIOFdBO7+5MPhBpUnQR2TODZXS4T1d7BZg== sig=E1faXEr1jeYBo7Jq7vpjWspe0+pki9OZaZpYJ1K+mkX7m8JBsETh6CB4VQ9sovx0CB5XQZdAR+EA2CAy11RQA42/JmDmPaGqo7E9lcm4aAvocgcDSxqguP+sVPWSW6dbuc6m9iM6Ig4okyASCVC1HSoA e=found last=18 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAlvP4ofDiQ/ryRWaADuwAXG908Tor7df74dgLK1Q4uLocOIqDZDjcQ6zVIbLjX83Fmhtc4Yll1pgA priv=MEcCAQAwBQYDK2VxBDsEOfJSPuP/E/evtu9mrp+izsWEcUSFpVT0mU35NiArsal2YgtvM8uznXgp/ryI1rPuUtMDC9ISqsLRRA== msg=r7bvZq6fos7FhHFEhaVU9JlN+TYgK7GpdmILbzPLs514Kf68iNaz7lLTAwvSEqrC0USvChzuOC+LieWw+wO35w== sig=A63IFVJeyZCV0A5PLrIRnzvo1e5waBLqqTIKFA4T5NfUegIFEaopAcxA7JXR2Lk1vTc+uzeuzOSAopysJart1tVMp926W01XQW1KyAMkw/3nZzI3Q2VwzzBBUkEE+Uwb+ApECV6lZt5wTB5qKI2W4xYA e=found last=14 s=10 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAiVGm69qkXi564UaRUvAQhhAN9pI62iS012nmN9hXxL8ffrprE9mOuWk5MogcCf2cH0KdwhMdO4aA priv=MEcCAQAwBQYDK2VxBDsEORQGe453aOe2u+8pHglWnM88XzxBpCSn+9mW1hDplEJQQlGwlHmaTQAqaMayCsWJuq45FvQfS+7cBA== msg=e453aOe2u+8pHglWnM88XzxBpCSn+9mW1hDplEJQQlGwlHmaTQAqaMayCsWJuq45FvQfS+7cBKjFcHx1G3lleg== sig=mB3QYIL0/Ynmz5juQK9++ofWhXl/x3vW6F00UH0kKNZNtFkGIs8oXiPLbAh4abSSRw4IKQmnbFKAt/mwcpe2UmQ+Avxjen83QhMHxgYuB5mSoSqqrfcRFvtth2KbsUz+GG81Nu2s86dUJ3nVbPKPJjoA e=found 150 iterations", + "pub=MEMwBQYDK2VxAzoAnoWRSFVGmLwLC9pXkVp/uCn/B5+xO7+qCdUeaUTB5fGxesZqMstYWJY2YTeKlZ+u0jbkhRiVFCIA priv=MEcCAQAwBQYDK2VxBDsEOflb5VtGIs8SjHrc3YF7lDKtkpxKGYMgSpppcOnXmDWjQM53I5MKqPqQuIcFalk0OgPA0s/lpIZUsA== msg=W0YizxKMetzdgXuUMq2SnEoZgyBKmmlw6deYNaNAzncjkwqo+pC4hwVqWTQ6A8DSz+WkhlSwJX3TSV5OMcTrVQ== sig=KeQhsm9TwSJ7nSc7ge9e7pM9n0wfigRo6mw9Oc4jNgn+vj20kePZvmcs8uNISn2YVNNo2oJiafCAXPZtDD4RKjbYWUYqTqLe/Y2dy3j5b22+UJBaZQClRNm0+kTo1cPfPJxs+dpG1zPJHyJG1yDruRgA e=found last=15 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA/2NzNMf1OVMnxj8/VrOgO+TwF1LM9izAtZH4x2NRxyZu3NaiRG3ngUFrUchqQA3y5YHkLqXNKIAA priv=MEcCAQAwBQYDK2VxBDsEOZlmeO1NDoUFIqGOZOsZdvVD0MupwODZQt4/T3WtCNc9c28EO25PC8iP3gSUstLVYuBUObImPEYBnA== msg=7U0OhQUioY5k6xl29UPQy6nA4NlC3j9Pda0I1z1zbwQ7bk8LyI/eBJSy0tVi4FQ5siY8RgGcD7K5ky5Usb01cg== sig=3sNRAsvdL3QLYbNjjiHKiymT4g8NmyOJni6IvRf5Kox4AcO5gvMB1kxGJF+A5AJQmP1PH3de1foAw198jod0xh4kQQx0kGtTqSnnqVSTp9ohOwLH3+yp4+CE9gQ24zAde3Rb5gjtQzNEl3FUzfbdNgwA e=found last=23 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA1twsyUlc3Sao/UX7yKpYP2G/BL2j3FIHaz93BtLBLPEFkDZ8K/u2pecXSIsIi8mT7qPUs8gBTXkA priv=MEcCAQAwBQYDK2VxBDsEOcjIHM/yO856ks6eRDsck7ZeVJBTiSSpp0Pa8djL/iNLIwlhAqbXfCmMMln5DEJERQWD9J36g+/HNg== msg=yBzP8jvOepLOnkQ7HJO2XlSQU4kkqadD2vHYy/4jSyMJYQKm13wpjDJZ+QxCREUFg/Sd+oPvxzYc5i1azK55KA== sig=fqC1o7q4l4ZudwUrLPERvgNLzxZhaDqUUgi3jz9aFkwGk/PBt4A1tWnf4CKdpWXK9pyH0ZyKnmYAMRlp+HEGcUDxJt3rGa0cy0KQ/9NvLt16LoHHML3d/hum3IP+3sceaxN/aqaJOYPwNPbaWNl27hEA e=found last=23 s=18 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA2CCWInRItby/MpnXtSfIw8YO7p45IbTO7HalwqpQYV/aYMFeX2CYdOdzgKr5//bnTvr3HM0WYt0A priv=MEcCAQAwBQYDK2VxBDsEOforHWMemQMcfFnmvlv3Qv40Xciy8Sbn0fmVyL2LqqRUfuIKoc2PWc5R71riCVHrF9KUIP2Jl7oO/Q== msg=HWMemQMcfFnmvlv3Qv40Xciy8Sbn0fmVyL2LqqRUfuIKoc2PWc5R71riCVHrF9KUIP2Jl7oO/WhFerDn8aROyA== sig=yf1vSBkAdSZr0SGozJ2bSPBFU2hYiY8s0p/eh7NDi0HW5JnifZf0N/94imZrKGnnA1Dugqe0qC8AdnrPp+bdUXU4uZ8KuZh43BkYbEynJsOviVdXY3O7a1ijqKzs5/SqJmrR+e/Bl8zIvI83yb9lZRQA e=found 153 iterations", + "pub=MEMwBQYDK2VxAzoA9fylZZHiY7cLLUlBgbMqLUknxrSko+dARpxr4XnBBcEMMh7R8DhqXRKspo+pHnz1fRVHFnm25PWA priv=MEcCAQAwBQYDK2VxBDsEOcAN+ERRFswYsYez/CKZSeuDygkW7Bv+bVA9Vi6gGRq44FbA4L7q6ETapKy/O5eE/3Q3QatWZq2sTQ== msg=zBixh7P8IplJ64PKCRbsG/5tUD1WLqAZGrjgVsDgvuroRNqkrL87l4T/dDdBq1ZmraxN1FZvcpcaFYVMqZq8Bg== sig=/1Wlj3q7ITCtfBb/PbwE3cGC7d9qaRRXX8ujQwMIp0mdJmOSsqjkyHDyJv8AtH8dPfXHhsJZtR4AF6m9Fi4/qZp30aTWTxC09rkJkOKIysyaZm4N5q7uM6zqVlJ2r7MvHtE0UO9YRSwNnVhnSEnfrCoA e=found last=20 s=18 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAbUJmsQyN1LB2wdcDGMUijF+yJFs4+UxKT/bSdZAh46f9xnmssEk/SxMVDTOTuUYZzisbkTYmvvcA priv=MEcCAQAwBQYDK2VxBDsEOTWLX86rJidaNBG9j27Ll5X56FPnFRmE4EFUvbmOuBm8inJCeM5HNgny8dPEnfkJ6sz7CtozQAQC5g== msg=J1o0Eb2PbsuXlfnoU+cVGYTgQVS9uY64GbyKckJ4zkc2CfLx08Sd+QnqzPsK2jNABALmO8C8uz6ZoEBVwesCIA== sig=ENhSMwmEID6xB3l/DfM19sng246v0M6Hua8YFWRxm8W1f5tMhl72nqClbI9dFhUSGJQsbZ3sCZeAHLQDhfX5nMGupvblVn6BrvwrgGUVqdcM3exHawy0l8YMl7+QZunzjt2SCy4J5GBrAVaS/eT18T0A e=found 154 iterations", + "pub=MEMwBQYDK2VxAzoADcQmw0arXiw2o9m52eFH2me+LH7LH+Cu8NOnwkG5H8eLTzWL494PtkoroqGuY16XghE3cV6EcbwA priv=MEcCAQAwBQYDK2VxBDsEOZ0zLy0P9NTBYYH8q+fG3P3YhLMfZiKaNXLbSx5uNrs5HulMB5ZzsIaq3nlhZS2IJsyTQIoCtgEhIA== msg=D/TUwWGB/Kvnxtz92ISzH2YimjVy20sebja7OR7pTAeWc7CGqt55YWUtiCbMk0CKArYBISAjZFxsEagpQGfqFg== sig=Pbpq+1gl0k3CnpGEZrckCnAMf5Jxa8xa969Wi0jQ9gb8bkZHawush+ggXYPpkXAZ+OELX1a36GgABd9PlFrLvFsxwkI3nFXinDHAic+GAae6lAQy3W/4Z9wV3eBjNr6gnejBnyrfiQRemLoXCJI49D4A e=found last=22 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoASisPWJOzmpaLon0y65sDkBKt29/r9C0PZqV0K/SqO/7n3305r/7VYoIQLj0uVBhtBvjAQ0V/OgaA priv=MEcCAQAwBQYDK2VxBDsEOSZXKafaa9ttU0M5pV3BKs9uzR0qT6YxnohPBnL87eCy5hmwBUN4SAP3YxIOTmkp6j7sPpV5wBM4XQ== msg=XcEqz27NHSpPpjGeiE8Gcvzt4LLmGbAFQ3hIA/djEg5OaSnqPuw+lXnAEzhdHuOq5oI26a5HuVCGov342XsArw== sig=YjtJkDlR7aI9UBFP5gJOIFc2sqkDwQyHT4l5JxCnUGk8l26MAp569toJd4U0ArQmDVhNreKflIcAXU5FAn25tq5Qkmc1roxz1/8btrCl+dO+86bIQg1YFFrTKsM67gqkT4N0UESOgGv9MgTFQpqOfQgA e=found 142 iterations", + "pub=MEMwBQYDK2VxAzoASl75PWj+kClSYZYujNhcfy0fvXzpFuN4DLt3Hr59OCUWStiNim7PSEFefv+OVWTbPEAbuYRdwlQA priv=MEcCAQAwBQYDK2VxBDsEORWX8gAxodYFlx9r0ctuJC9UNhoIJrlsJL6MCytTMcLxTKK8e9psiTmv6GhHD9C1Q8JhtW8+QcZ9rg== msg=a9HLbiQvVDYaCCa5bCS+jAsrUzHC8UyivHvabIk5r+hoRw/QtUPCYbVvPkHGfa6pZM2eDU2cQb6a5r4caxX0oQ== sig=Rxmpl3HfGO2alKs25LWmzJo2rwnGYl142W3JsRLHNI3vJpw7296ZAwRuk3gJtZMJQwyvClJJUz4A+o2ddRXXG6W/YKN+eGO7GjGg9oHszf+vFYOmOcvjI+jNBg8T2ueR4Oi7/fInc9TixPHxT42PUwAA e=found 145 iterations", + "pub=MEMwBQYDK2VxAzoAPnEiHrUAdWxMmvM4RfGdj78oACDJnAiKf/iVtaP/bwBt5eLHARRIlnH8tPKcDwR6Zsc4ubhyoTCA priv=MEcCAQAwBQYDK2VxBDsEOclrSZhUXBSktiQe4QRvUxZuJVhT61+5k7arzF2SguBZBKFnQeytJ8swoq0vGPrl+tOPCvJPpN253g== msg=tiQe4QRvUxZuJVhT61+5k7arzF2SguBZBKFnQeytJ8swoq0vGPrl+tOPCvJPpN253oW4C7nPKDEbrDqPSSEecg== sig=NcJIAmSowCHotySIHwKeCCNYkPJEClKVoeID6vI38F5agCI58qEFyTfICMwNyQ5edavt2t0RC8iAYGzSTc1kJo2ciBAQM3K1hkdbGPh40BD3F4mkI0S08V5ItqyzxreXEJUFBsODvhS45xCJxJKGxS0A e=found last=26 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA1r1M6ksDZqGgWiPC8GRW9M+vSZm+e3Bopqhj809c6EgzzvdvJ9T3XhHQ/RGrhLoN8JlPgkkr5qUA priv=MEcCAQAwBQYDK2VxBDsEOVqi24vCjWRyX2MIvZIBvUrBZ3hNB8469MqU6EoG3piPvMyzfnq92puELpcrO7LReZXYB92JWmU+lA== msg=SsFneE0Hzjr0ypToSgbemI+8zLN+er3am4Qulys7stF5ldgH3YlaZT6Uw89UsvINSnlV7W9lgZ01ONIwAUh+yQ== sig=d2JL3Aluqr/zx5PlvYL6baOq/HEwoSJT01WfkD7C6R1AzZ3cqiqNTyi7xtGEx+DJq+ZzJBdQDyaAwLnVHRbLILVE4KUMxcFs7vW2gmd0v916+9LphHrugMAY5qAhIz3XSyheEQuro4vVWBhfD/mTdAEA e=found last=15 s=9 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoApvoiw0bcyv4+QcYzN4MLnajjTmvOL/9PtFbxJzgsMIHQNFK+K1nDcISsthPM2BpVf/UXdgjoNzYA priv=MEcCAQAwBQYDK2VxBDsEObJ7Pp3qXM9hVAGOtu7GDta//eAMZlnowd7x+jcsy8WK1HO9xDKaSY2BlqqwoUK07PqkR00EXCcnKA== msg=xg7Wv/3gDGZZ6MHe8fo3LMvFitRzvcQymkmNgZaqsKFCtOz6pEdNBFwnJyh5WD5qrlM+cmiidROHRu3/LWotqQ== sig=XmCrvVmNFy3K8HhOC3a97j4oIuLCVMRxBSX5+LC9y9w0hdHs+vBPOHI/tW3WI5ZQdAeePSj1Y0YAKvs2nfOn+3jOgrhZL13sMUuqidcrMNJfUX+5BXgcV6M1TeFB3SR/mhRi27bt0O35Aq/fPniTFA0A e=found last=15 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAqr0tKNx0fQ3OCycnFm7F60+D2pp11N4uk4viRGfzrbJBUNHLozM6yRO9gIGUa+aa0Y1f/bwX+iGA priv=MEcCAQAwBQYDK2VxBDsEOepOpB7pTynWoWXtIlFp+y+tPHDck2LgUZ3tmRfkiCocrNoKi+2WBC9eb3hs6xNrJF2gUb+wcw4Blg== msg=L608cNyTYuBRne2ZF+SIKhys2gqL7ZYEL15veGzrE2skXaBRv7BzDgGW9xN8BQ57GCXk0MhyPbSAo0mE2u74Rw== sig=qNcqsXDVHPFoJa6DgGveMgLqPFht8XdnZIaQaEfKE86UHwhwXJpxiMHv7FUD+UpbGreWynZ9bNwAwZVgv7gSGDT7im6Zyp38b49lBFQyAKl6bKwGC+IkbQIzMY5LBUCoZXYEEsGjqiKyjXGchjlXYhkA e=found last=23 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA/vT/qeDysT5F9zgDtpyWKV+hbysrPHLQt/pWS0TXIrpc9rzcWrb3qJZVaGjO7ezCbNRIOcfA46YA priv=MEcCAQAwBQYDK2VxBDsEOfASzHQHh4d6FF+7hga5ZrjCDq3cJ7NR9grk2gSeMoWWoefo75z+nzuxCHpF11izPQ8aKqfXdehhew== msg=X7uGBrlmuMIOrdwns1H2CuTaBJ4yhZah5+jvnP6fO7EIekXXWLM9Dxoqp9d16GF7t7v3eAQyQBLVIO5N6D3fFA== sig=vB40Q4EHD861eW1Pc1boZPT+dqhPEbeFhfuu4D9z9UdkzqkI9vZzQ+Y/0tbSWIDzuXo1WQYpr+OAHdGB521cHIgPgTkHuT3SyEhAgf1H0EDBhM9dbjzUNU7I/qJTM4GHj7jzZ8Fwnmb1GJ9hZhgH4RoA e=found 191 iterations", + "pub=MEMwBQYDK2VxAzoASyOtDczpmbkaaBDC3pvB09poUWmz5DpDkX/o1jBN/RFaRvHzEEKIJ8AxuEmgoMdaGaewsdpP94uA priv=MEcCAQAwBQYDK2VxBDsEOceoPAxTk4yA9Eaw3Zr5zEAQQhPgPuYOcVfSOySQQiSD76XcME6pMqD3eODccKXs7oASCIet1RTfGQ== msg=+cxAEEIT4D7mDnFX0jskkEIkg++l3DBOqTKg93jg3HCl7O6AEgiHrdUU3xmOYmdqUhY8og8tmdZflTGl0L3Wxw== sig=nxacjHNuea/II7xbUgwURmGdiZybALFXrZDw52yh58qxgFRAqgnU0fO7WjJuugD0xy6jdGOop8WAhzhwz+YfJMhwjUIFCQU0gMxONokD32qAY3xLiCYESl8iGrHmnoI8fN7jDpt59XOjhVYHGtygpDYA e=found 193 iterations", + "pub=MEMwBQYDK2VxAzoA8BMeSayVweKNw7CRE+Py2cedjEoikRhtqNvDBt35Fa8+2J9ha7sP9olPHOIosCCAR5Taa3vA/9aA priv=MEcCAQAwBQYDK2VxBDsEObg/KRocVEWne5+r6jprc14YkTCOSCyJhjjLc57m2IvbMWFnZ0R3nfdZJejGyxi+EHecm3+HcTtDEg== msg=MI5ILImGOMtznubYi9sxYWdnRHed91kl6MbLGL4Qd5ybf4dxO0MSiiu3+kIyMozQw/4baNISF+OiIR+qg1Y7Aw== sig=9NudJJgNYlDFqnuC0s2C0AVA0dNg9DSrp5BH6J4X1GvYP3YryHRdtmVt+ddYU26VxjiZVESNNfMA9dNgoc9ZVDemv8cWTfTyXq2BdoDNQHGUUmSrSaVQVHwy8bgrBeWy+QlGW+UjjWtmqE4XfyeCmBEA e=found 192 iterations", + "pub=MEMwBQYDK2VxAzoAnqm3LH9RyxtiTZ8xh0c2VNSg9RL0yuIX/B2PJ3oCEiL5L5YU++JvEHCuojhaNSdCZnnhaFSCi2wA priv=MEcCAQAwBQYDK2VxBDsEOTi6ZcD6B0cxMxPuGWJaLTWrv2qzSnVn8e3BB2yOHkh1HfQDA7u+0fOvD1+geyhDq6Pgg9wt0A8Bow== msg=OLplwPoHRzEzE+4ZYlotNau/arNKdWfx7cEHbI4eSHUd9AMDu77R868PX6B7KEOro+CD3C3QDwGjNU/T6xFELw== sig=0e3EbTzqR1jTRN6dPSQdLIwhBfLd9pJNjS1HZRLxUkhenB53AOys5QGuGVayqNmsGf0Gvf/SBy2AM2ug6v1k9JYNP6wVJjCuoKPpcrqlKBxKujNWGioIXjGMbUehltGQ7zFkcF0rq8hAJEfwxpxp3SQA e=found last=19 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWhIghNbDZQ3UHeAaV8VvnuyTQp+o505/MF/aKeAkpdihVNDEsy3SYPi/La403UtOEO1ceuQwn0SA priv=MEcCAQAwBQYDK2VxBDsEOThoiB0f81i7rz4ig5ikaeLSICxZ/QVBNHzwN+O+AcFjC7staz1DFEk5RbImujrCOmeH2t69X65l5g== msg=IoOYpGni0iAsWf0FQTR88DfjvgHBYwu7LWs9QxRJOUWyJro6wjpnh9revV+uZeZSXBh17ddPaMTKXsi+4woMfw== sig=KjsUQ2vdm4V4/fWRnLOZSArS/fhu3aUNOe4pwgjPhfcmY8peHYyogy7KhvPf1meLP0dDnpo0UpoA4G2GvHkLEYOHFYfywX2MUaJbYlxtcI1T5/SRk893Wz4BKYhQ9hfTnEYfFQb3LwbaaEzCpfFQEzEA e=found last=16 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAZKJNO6IyoYaXEpkb4Q2LUPC1qlJG/MV4GSsfE2SNgy3A4ax5Aii+dvl5JVgvt0iGTjnGzR1g76eA priv=MEcCAQAwBQYDK2VxBDsEOZi0Fgxeda931N9fqW/18N+QQIfYfKAxNFBqDDqZdjiyMd3OWPVUuW3TTl7lX1tsL+r1qu+arKj/xw== msg=XnWvd9TfX6lv9fDfkECH2HygMTRQagw6mXY4sjHdzlj1VLlt005e5V9bbC/q9arvmqyo/8egL5wwOGNk0TdPJQ== sig=KeCWFqQyysAZqRmNBXQHmOiq4Qjq27N0cVoqtm/fMMqSwXs5DvtMjMW/4sut9nTfaQ9R0aQN8q8AuklnHnTpRqUEFFIXbK3WgGzacjkUoNLb0ougyxe9tvFe9+Q0O/nlHYABLovmXLfM4lW9Qd4SvygA e=found last=20 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAXj5XlVeUHFwqw920A9cp5tzxrdRdDQXMSmn5x9+n7kwSBlU7vYduGUSl7StIEqhrt9czSbEi64KA priv=MEcCAQAwBQYDK2VxBDsEOaq6wfoYXTAEgkdq3xvebMqssEmgILSUvWx26vEIOYhrb4n551IKPWp1r8Uu3Aa8DItNZ5r0qmgXDw== msg=gkdq3xvebMqssEmgILSUvWx26vEIOYhrb4n551IKPWp1r8Uu3Aa8DItNZ5r0qmgXDzmjwShAP34UYh0A5ahlGA== sig=1JlzbvbwsqDV9jN4kfRoWFhW06mazziQI0LUcv9fyKhsyYkDYuLCLZVGepTAqbDm0up3bYw2RFWAzEQBxuDEAXM/ptYU1In+obJi7k3icLhzhhvet/BKuRdSfxzTKL9VG9lyuoSBvv/f9wUThs/s/DUA e=found last=27 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA/clIv7loBaBEEoGmND4SK+XQzhkryl5/+lnAZyVdsUzTeliv/ZryvDGpZzBPVIV1GbBEzosqCg2A priv=MEcCAQAwBQYDK2VxBDsEORElqfHpe7hUoyyLfcCZCHr+ibC8TGWEVNXzig2r2w6OZQodGqGgN616ObF0lmDIRJhKsCmxIidESw== msg=oyyLfcCZCHr+ibC8TGWEVNXzig2r2w6OZQodGqGgN616ObF0lmDIRJhKsCmxIidES1U33SM2TolCJ+txQZB9IQ== sig=a4f4LJ0SmjcOIkAn2SNz9qWrgmbLaaGOBB2E1mxEXC6KTSnXOAlsjy1vI0iMXWEYwKwR8hPJzxMApCXn5JClLKaBziCiuFeptK1ufTWmpY6Stm4xOin9oQcSc1DGd+xu0TIb3KkqMKTdEIatZpXx/CsA e=found last=19 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAK73F3oJLy5FB+eGNLYO+k+FvLVd3dJClSMzy+2oXfnrr51J53YZoO665trkQCDW0OcsNohgYd7kA priv=MEcCAQAwBQYDK2VxBDsEOad210DAb1gAVY/+P7v9q515x034sutKApOyOFdNmLPTBvGHeIafWegfCDLVl19S1j0vRePUXLZDCQ== msg=WABVj/4/u/2rnXnHTfiy60oCk7I4V02Ys9MG8Yd4hp9Z6B8IMtWXX1LWPS9F49RctkMJUf3pFinI0NtdrOAHDA== sig=nXXNNHDBNe8Ghd558KsSyL+WqJHzV8jA7dFxXbXYVZ0VOPYIxvf9aKqJRcw4S0/lCCPUy/WvUquArhp0HMBpf67iH6EHgLS3p/OKSeeZUWg1oF+uMlPpS7p9pDGSNcldhnZ+vILhisUeYwoeR6qZBgAA e=found last=27 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAaguBmw+9L6TUTOaB+UfkWO9HtesUGKPLPsZz7yhC0e3VqnpJ+0tpe+593GA1jbnS0jcFaMIqMqqA priv=MEcCAQAwBQYDK2VxBDsEOf5GpHwq7KniJgwvdxVORbZUuCQYvVAO8emkDzvkty52ul637AN4MNWITaHf0lHeuORiqTW0anCA5Q== msg=JgwvdxVORbZUuCQYvVAO8emkDzvkty52ul637AN4MNWITaHf0lHeuORiqTW0anCA5eH/kR/wux8XO6SZr057/Q== sig=sakMQ0mj1UQVhMpk6K+0vxS2E02ymuV808Mm0AiXrUlADScpOw3lWZb469c9h5r+QzJSaeHmkQeAlOgqjbNAviKpEkzHu4dgD0JbRfH68hEYRNrJ0asJi+r9AO/1q0GANs4rgSG2ADsRwoi8dCKpFD4A e=found last=16 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAcmXAChz6/6hufHNoZlRE2xN2D+3JKpDI3I2q9wDX4AP9BnprkLUZSMfFpaiO+TJWRIcllyavOsMA priv=MEcCAQAwBQYDK2VxBDsEOcEvxH8HnSp0le7+uW2UMh6qVHX7M8PFsdBvwSy6L9mA+yp/Ygn5fpNMeplc8hK0coJajPA9kMCdWw== msg=dJXu/rltlDIeqlR1+zPDxbHQb8Esui/ZgPsqf2IJ+X6TTHqZXPIStHKCWozwPZDAnVvAdnyKrfKFSZUHn1+fPg== sig=fv51KHg5N1U5Nq8NnIkla5tyWCz+sJLucrp+prfebfXjaUYb5VFWuZrTaV4gvjf33R4ZURpSXQGALp+VP5EdSlFWyB0PhC1Y1YBsGa9I9ysOfcF+/QyViMzwvWsO1dsfrq0GuSu5XUANU64VDhFv3SgA e=found last=22 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA68IAKIWqsqHDGmlyH3xjEpASsOZAHfa3CpKL3Wz5T/4GKf350XOHZqUfOqWPcXWR/NvsEcVCcBUA priv=MEcCAQAwBQYDK2VxBDsEOW2vC/DYkwc16LLGpTtWjYUzobE+0fzj63BFqvIEJ696fFyn9Dipkb29bz/3cR8NVrdb3Hbx/zThJA== msg=C/DYkwc16LLGpTtWjYUzobE+0fzj63BFqvIEJ696fFyn9Dipkb29bz/3cR8NVrdb3Hbx/zThJC3IsMSIaueEIg== sig=uNnNeXf7DzM5opIOkET1CeEGq41BgSbtXk5+gw+BEReOzUClM1ENVkPsaOSR698lfV3Guk0c4cQACBZTusWZJAfjwleuaclFYjxuM4gvRMUfzBe3Mx7DVi8+EWKOOXO9N+6i/xpiUUacBgNR27JNRAkA e=found last=18 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAY365+XQH1Dfaskx9by31wveWQIKVQdVROHXAwW4IST8xgMNOa6hv3OxSLU7//svJ0HQi+MEc+dmA priv=MEcCAQAwBQYDK2VxBDsEOflgodls4LNAe0zfm0An13JPRtLwoMOIJ8U0NC4TENls68lh8zLMbZrP0v9rQWDynDNxkdTEUv5ijA== msg=TN+bQCfXck9G0vCgw4gnxTQ0LhMQ2WzryWHzMsxtms/S/2tBYPKcM3GR1MRS/mKMWjCTcXomDX8hg0bD5Ce0Jw== sig=RHhaQ6MsnhczVGuz5YnNVAID/U3nCAE0GSyh3X+TIDmRiyMbmujquamUGYPRxeSvbax4TnzRMloAz52Y5xsLL7m9nlq5XxD/QDSQ1y8j8IKLl8Uw0dQfzZorxPuOn1vHijdgNrhW9R3GYHbpbYvIPhAA e=found last=15 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAmpnn+vvZCSTyawmRbZxxJqkpSmfd4fwtbcSK5Rf23K+FnNUW9mIf8eYPAfb771BjNTer6QR5QdkA priv=MEcCAQAwBQYDK2VxBDsEObmWoNn+/9bUbvM9qWXI3L6UnIRxo3uzSD+pk1G2gzQmpg3kb6HZfGJim+h8E5VZojytAf/dAOyCsA== msg=oNn+/9bUbvM9qWXI3L6UnIRxo3uzSD+pk1G2gzQmpg3kb6HZfGJim+h8E5VZojytAf/dAOyCsG1T/TUSC39TXg== sig=JPPZYJW3aGfF6jMTDu40HE15zsKVzh1b9oBxB23weaCeNFGzaGR+DPG2t+IUAmzd6e2rk2e6jGyAEjghk13hxA2SKt9tq77HU/sTulQBe5oNtQn7QCvzZGPJX5B3LtjuGb7iCWcoAh8PZrzsT98pQRoA e=found last=18 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAlzpVkORvpHCYpRG+0b8R9a118mK25Bj0/teLlFvoKLTwR4ikFeuGRb0xoZSqagmTgoqhs3soyDSA priv=MEcCAQAwBQYDK2VxBDsEObVJAHEdHRtbjnCPlqdHWQrqumHKj0ioMPP71pkOmNWobVOFsWGS1Mh0jaK8Lm5ZVslsX+fmmd3LTg== msg=W45wj5anR1kK6rphyo9IqDDz+9aZDpjVqG1ThbFhktTIdI2ivC5uWVbJbF/n5pndy04IZKAaqCbxqPCaYtIhIA== sig=HfH6TAn9/Wcu8DZPkV5VKSQj0XtJV8aR3g34bYpfFGf7lmhbusiNrsFUPDEqCww6PYbLREbSbeSA9O9Vlb5oGxfy8ArE4uCH3gpidJgoZLyLvivehflht3akpQnXQD8q7qmtBSPpjPONn/jQWPBMly8A e=found 194 iterations", + "pub=MEMwBQYDK2VxAzoAYoey95EkiazeZi7Sb7MJIVAKgnxEudjDBoaWj4hEEfMVVNUqi2tXdSJWJw4TO7rZqiOBBTRGqDoA priv=MEcCAQAwBQYDK2VxBDsEOT6XWQNMB896ReDcCp7XzSq8+nATSvydq+kogeEdpwB9JMoNJnCQ/r3xuSdu3mFmmeEo99sE6chaaQ== msg=WQNMB896ReDcCp7XzSq8+nATSvydq+kogeEdpwB9JMoNJnCQ/r3xuSdu3mFmmeEo99sE6chaaYlGZ2m/FIreWg== sig=bIx9sYL17sxg4LnrHSE4urSYpVF/IvbpLILuKc1kN7zeZDHCteWDg+4fVxFsKS51Dkx94DQoqKAAseHmqZjKrznIwgiS4yTpB5k1rK6pqj519RAW5+7JdHX0AkhkSl0gGJTCfquTZgoEeFx0MDJD7y4A e=found last=24 s=18 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAiMdW7QMt81LZdjEJfUyG3hsW6ABs44PaWYsEK9+rsAaOqKIFEdwsJr9t+a1kaUY6LTR0JFDtc04A priv=MEcCAQAwBQYDK2VxBDsEOWLfNhAMBrCYoAeBdHEujeOMMtEhQ7DBxmwgmnt1jyngmqRJkt6yS14Df0nbh2rH7gblZn3523mZeg== msg=NhAMBrCYoAeBdHEujeOMMtEhQ7DBxmwgmnt1jyngmqRJkt6yS14Df0nbh2rH7gblZn3523mZesir7JEDaygryg== sig=5tWz6Bb3XoYLTGSn1DRLj+MTbxMDxu40haPwMhx1LmsaWlNOoE+wM8ipRKzqjGQ8K/EuE1twy/mAuV6r/pxPHScAi+EV9EN9np40LP4uYgFUasFjUzUrPDSbjB+faeNA+xvciKzQSK4SYwhachG9OBkA e=found last=17 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAfMzpvoY+MHmW5Ku/dCQKIKMZZLFndBEQgE9jJswHYSD07jGOguwOJWsdcCSUyDOU7Z6Ozpdo7YqA priv=MEcCAQAwBQYDK2VxBDsEOWoWWSZCXCCh/z7e02Ffw/FhN6g8Vcg2jgnfM/gnYjAEq6XZ6u14xxEwzNk/YzBeLP/p5wHsFHSA6Q== msg=PFXINo4J3zP4J2IwBKul2erteMcRMMzZP2MwXiz/6ecB7BR0gOlz/utiUSYv8Iv4fRfE1E7iNXsm8T9aQPjJLg== sig=valf4bDx3/FcATwQCoDOanMzTPqp20ifBNGBHMoKCSbHRr6lE4A+gfe9mYz0RR7/b0PVWjCv4uiApho7MzpNB1kpO7H45uJhryGXK7ZA4f3/DSogtnyP9B5bWDMIr3FpRvGULcN+R+/NTpB6tC3UkjkA e=found last=14 s=10 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAVxqmTkE2cj8RFfnviAk5vR9ZiREsUrBhTZeel78N2ffRnRgWYpeDC4RYQGc/XRprAfT6muyHhIuA priv=MEcCAQAwBQYDK2VxBDsEOQVeU9Uxb0gyuriT5U58rA68Zj1dFod84qh2oohdD6P+5cQ7u/qnRnT3bdzDeyweo+SCkKZUwGByeQ== msg=Zj1dFod84qh2oohdD6P+5cQ7u/qnRnT3bdzDeyweo+SCkKZUwGByeQRBLSIdVrphc4JhNmfRS2R+091nWvDJaQ== sig=c6PkLpytnth8l437JSABb18JsSPd7+6KRuIY6Vsj8ECEdU3bIs6Bmi12JvlhvJigftGR3ADD0ssAN/+ymQ62KWc6DfFnCecAF/XKqAcMSZi9vC/kjoIitDplRgZhH2//U/2IoEOKPKfJtoDnjDUM5DwA e=found 152 iterations", + "pub=MEMwBQYDK2VxAzoAvTBNJr69v+/yWj/c00nNt4sjFYCqOXmLUdmWPPa9advYzUZ4cf+Z4VQig1aAIzi22rtuDmceT38A priv=MEcCAQAwBQYDK2VxBDsEOdomtQzFqYtkspMLpEKcByI6PSYFJsnmPaeGLDvU0enDQbDt+FAZZip5/+XoVDm3CShBNUJ8UFlvKw== msg=pEKcByI6PSYFJsnmPaeGLDvU0enDQbDt+FAZZip5/+XoVDm3CShBNUJ8UFlvK/Gk1abp5MPRLk0OGsdlMCLPyQ== sig=T9wLDw9pQNn2Hm8fLolqp1r1H2tCQB1FLLD0ZBQt4zF12lOn4v2CAyogSkk5CJys8Ia1uORgmQUAC7AgSejPn5XK1UaoCEZ7kS4UNEC3X0TPOAyqQuAsGKvgg+E1J6loPSz0lP2uHu5mBHe8UAKPLAIA e=found last=24 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAbp/EylnmLNaFSCuFbmcnlXs6/iZuh9taGULtvT756NefYTAJUehidzr6HLzDbMvqBi9cZUqpdmsA priv=MEcCAQAwBQYDK2VxBDsEOQrU7VpRi55m1Xb6a0aWHg3tkK1Q3/orePdX1wqZAznIGgGAC8ZW2tatMqsowcnPF6Y27IIUXh9LBQ== msg=Hg3tkK1Q3/orePdX1wqZAznIGgGAC8ZW2tatMqsowcnPF6Y27IIUXh9LBY6KhP+cftO/8VA6oefb9GmX6oH/Xg== sig=IyQFTj9P8LSle25ocWSHUGBatLXeQPwKMXFI9OzAoKjR32aK1Y8PAUry8ilRL3BqEElCPPIDJcqA7uP7R3iqIvYsLu/XUHPyeYqp7HsFCxsptD7yR/V2mlwAwHbME81o9TcpAwqoLI/lUAhdIdvNPA8A e=found last=14 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAUzR/yk+IxMjgrn5tbkFG4UQnp3XA30PfiB0DIuqfg05e38E55/C1QflQMxqHMgj/H8uo6jc9oD0A priv=MEcCAQAwBQYDK2VxBDsEOeIkJKv+FgVLMjQtFcdlaH/f6HT2eoaT6bpzOnxLrbifHRBFJye/zgPRfU1jeZ0h7SL44aChqtzYwA== msg=FcdlaH/f6HT2eoaT6bpzOnxLrbifHRBFJye/zgPRfU1jeZ0h7SL44aChqtzYwANOf9r1bfgBAD2opcft9l5lzw== sig=3swO1+tbrPYW/9AznxjGEzO+9FqIpbTh0jnm4sUETM4oyn2/X0r2RsvDWUNYAvxuf4+QeTMn/50AuK9TUvurhw0ONk1IauuUUTGfm8xqVTlQjnlgC2DVEJUJjY5eRFe82Vh2EU1rECCzO/Zi2llsLwEA e=found last=21 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAil7kbW2PIXwbG+gUeZf3/4NZ4e/rDUvnby+2S/ILt42SayRC5/VQ4hSKDu3znkQDy3t99zDK4JsA priv=MEcCAQAwBQYDK2VxBDsEOXrfWw9qNGukG7GUsYHNB/VxifwsrEl0lSz5Fe1BY18ns/77Qfi0nAxjOTX9ph0DM7iGa2gBhxFmnA== msg=QWNfJ7P++0H4tJwMYzk1/aYdAzO4hmtoAYcRZpxrYFj002fm0Dg7SkH7bzArVKJIA99PxwbSz/CflvPqBA2OcQ== sig=DsdqkBwzATQ/AifcF/sJcMyLR07Cyg0jH9EZZPubny7jxkIJe8wa8Kjvwm8WTkAoxewm7QNFE86AVMsmOWwYoi1VjUGXJewjIeJwQhQZPNJ0UNY0CHrGKGkN5/By4mZxdWDdTY9Z4E7A6ezA0YnRVBwA e=found last=17 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoATKz03mL+U9jWJDiO/lVaAjUtHFOKYiVS5Ea9ybyERfadUC3Y9apWjPKzjt6cr2q2t46xEFRIvrkA priv=MEcCAQAwBQYDK2VxBDsEOZfUc3Z6WsE5b1VnZ/udj6BaQFHUh5Sr2LfbFjGwBr+vvuWwlFrXSzMg03EUgUO8NnYa1tLdbpgBWQ== msg=2LfbFjGwBr+vvuWwlFrXSzMg03EUgUO8NnYa1tLdbpgBWS4BclkGA5lwP2GohFcP+ALWFjJdgmezQJ9evMGhQA== sig=uvQ/b1nVXJhFWqmERz7lVAs7bwIzBf3fHmTk5CxzRJPCc+hPRWRDDtlOHjLW7eAwtIwBDWW/ktKAaoa0hNDl9cVRrj4ozQkuLTtkDK7BfIWq/hqjPrvm+DMb1LOWYcqp4sPBo1p9J5xIaVa0a78vRCAA e=found last=18 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAYYTZuxQYjoJWfZnI4AQc0BlhucKHJns0mh0m8kLs0sx1LnxcD7896w5rebLuBXdq2FZvJw2E4LUA priv=MEcCAQAwBQYDK2VxBDsEOS2Agqb8Vfc5hy1T/vka6q5Qx5jMeOThCW4COA/mIzxzvCixsiWF0LnwfEq/dzC0VTPHedKyBTYAhQ== msg=D+YjPHO8KLGyJYXQufB8Sr93MLRVM8d50rIFNgCFBU2jLLucwwiVZsffc0W1/ue/UxlFax1XFlT7r3tKMW90hQ== sig=OkFpTX7YtTO97UbXd8ht95SWb+nZ9yT4xJ54df+rhCCjFlPZa59TMlQWf0q1glR0hhZ1eBFwn0gAvX45OPmmQXI/0G7uxDEB7WN74wtTpC8NC01fsrcQ4bP4xjorBW/b/olKXtKIVZSYLplWLoRCRQsA e=found last=21 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoALy5IrJEj8KDg77MwRhvbw0qcAth/DLb40ocHOd7kdvFsHvd+PlH43ctqATSLeisFLq3FFvhR130A priv=MEcCAQAwBQYDK2VxBDsEObg8DzwtARgDEbOi+OH6nrR8v/Ab0BUUCVBizxmHFaONYet1UnKgZxPwiGiQxYird6iKNIpiurgxyw== msg=63VScqBnE/CIaJDFiKt3qIo0imK6uDHLCPjw8C4JpdDH6UvtaUTkKcWHrtgF+Y2WuS+ymHJGb/rcx8pPXo6KOA== sig=BTy+upKdLnuSoHpOCZFe+XCV/EoAiphQBdT59brIWAhjNLSEaf1hM5FOyq/nJYhxYasr7t3djqsACKSB4qJuVkUY4ZT/zw+JnTJfu2BqPZ87G/eq1JZXrldDlSdl5VGTES8VpjxPskosgluMdDvz6yEA e=found 149 iterations", + "pub=MEMwBQYDK2VxAzoAKpBv80sguvuwGQ7hE5lYs3w9CYqwUVPznTnpCMx6iFL20RGSGRuBnUkI/2Wv5jZDV1GE3Qq5BZQA priv=MEcCAQAwBQYDK2VxBDsEOTOlVbP1MEv4azMVNHBsLB/BSwgo5jL3/t3RkAWcClQQwt/X3rqMKt4N+QipYX3mRzKuT6Hq+eBeFw== msg=CKlhfeZHMq5Poer54F4XTOkD45VRRMg5PkjBiE1MOsWT1XXXNkyq5kp6y1BvVaoiWPsgKQWZ4aRMNwGHXqxnww== sig=FZ1naDk9YzpLD55fjdhTQ7f55jEyUE8A9UjyMkphohqdBJny4PuomO0W2cgGtHl9aVY1IN+RoGYAFKQ6EBg0gfmdtoqU3O6lDOJ/kfr4c1Ed2JsfZmJcrvKzBPhH/8RZYQRlJdqRryCZmbCm5zfuTyoA e=found last=18 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAbJm8oxabMmNN7qorFHsEvAU4GJN5r4r+MzJIvHpYYFLhDMYRLcM5V9SA3abpcV18H7x/JEQVg4gA priv=MEcCAQAwBQYDK2VxBDsEOe1/aMf5aCZTNC3cHF1FT5AHdihTHM5eABHPUE8FcglGONROSDR+prHk7OmenI+/FNs7/B/6qu2grQ== msg=GB3pMx/LVaNQlD+S85vcF35uDORCqRqVPH+vmBtQlgAErQnQjPq4f2dKpeD7gYesk2YPoFZO7DdF+Zbc0WaNRQ== sig=ENsno1pFZqIXH6ayZ2JjzJBVeGP3TkZ8Cc8U0++EkA8lGMu0Hh/0i896H1VmIJ2E0xT/oLTLm8UAbTSw+q2zFSVKpCy1FhxmcZAbpaw/fyJZbRyYOtjMn2Gq5uoMTlemEN6LeS8qc1txr8VRjzr50BYA e=found last=19 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA19kIXQ9cb+HGi2tk8DgEBUgIeuv8ZLa8tD+R/zjewmvA9orG+nWVr6eJETyY40uVh/QtvATkpU6A priv=MEcCAQAwBQYDK2VxBDsEOUFxb6K0gJGk6TKepYx4t2zxElOyLoQfSkwbs6lhevVxMEiv84NHQ30LkFbOAyz09OhN6zw47xDNKA== msg=QXFvorSAkaTpMp6ljHi3bPESU7IuhB9KTBuzqWF69XEwSK/zg0dDfQuQVs4DLPT06E3rPDjvEM0oZn5DxYk+kw== sig=LexRpk4una71scmMNfwYeFUrp7VgrB7lSr5wEaFU+3ZpBJ/zUNpThelwxbCDyiiODZpcMzFGXuAAIIxok0Yc6efo5ehSeYPth8FUCi2tM1dw5y9H2VVLsSVS+YOWkxSgmuks/7mFhIhGWOXlKS4WqCkA e=found 148 iterations", + "pub=MEMwBQYDK2VxAzoA/tEBr6f52ufH0clkw1/eLs06X87UhmrTJr5nYuLNLMLvLhouIxBl7l0QgROytQBf2kNurJhg20kA priv=MEcCAQAwBQYDK2VxBDsEOeW6YN+3rZGjWpFr/ELJ/UXclAQk0iCMfPEt4I7Eb8CIQaVI+TvF8szXGZO1fX+VX5LCoQtzmI+Qig== msg=37etkaNakWv8Qsn9RdyUBCTSIIx88S3gjsRvwIhBpUj5O8XyzNcZk7V9f5VfksKhC3OYj5CKorpOqE2Lxne6oA== sig=EgZtdxm5Nk09YaIeS89kpb9E9e2R17C5AyPzd/mVaxXXRnCrvLAuqaPNJazt+C3L7JHjyrxKti8AMUySE+z5mTZnkPB1qKGJtgYDuDMSriBBIm/3uWJ2LqntrvLVnXqQXx7YuQoF18G4q5E8D1KCbTcA e=found last=20 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA7ii1p0jqfd8sNu77JodViAs67rJjuVgHsB9kbA0jcF+f0X4RdIot7En42+mYWDpRT/PieUPN8M6A priv=MEcCAQAwBQYDK2VxBDsEOf9ywK47sCB2hBF2eqcI3iVJKGTR3XuhjYmDWRqyRilqIJNOQ8bOqSV70JlvZStOKqwxxGtwanPtkw== msg=wK47sCB2hBF2eqcI3iVJKGTR3XuhjYmDWRqyRilqIJNOQ8bOqSV70JlvZStOKqwxxGtwanPtk2GE25o7+G3SCQ== sig=Lrbp3nEJfflv3/Y7XIl6/EotUIepzK6aAh9jgbE1TPCd9lHwyrUW/RQgdt3QRX5UJzNQKrCBJ3qA5mOzDgOh01ijfpqPSDV/ib0hBFeZj+38s3eFZ5pvpmc/0Difl9aUcvXF/8mSVnD9jM1e/3GUhiYA e=found last=16 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAryyZN9brQaCKmQrLw8vN+ddwxok4d6BuYVjg5xqQBmxiEJQdT+OT5kOb0zaIWcoXkbOLAGQ6pCQA priv=MEcCAQAwBQYDK2VxBDsEOYLHpSx1z585KRb9yJ5VnHDyC4RIEZcHdNYUdqji15aMBWqypjGcxC1La390SBfFd0vYtJs84bK5Fw== msg=x6Usdc+fOSkW/cieVZxw8guESBGXB3TWFHao4teWjAVqsqYxnMQtS2t/dEgXxXdL2LSbPOGyuRcXu3OasEoXSw== sig=WCN5J05lO9t/cmQk8GqMv6KrSONDay2t7GA4JGCNF3BVofpY17qWZyXYNPzz7LYsJpTbMIuwzbGAUAnofYE91Rn1/9TI0dyRcuYZby/r35ZMDUxDw03wui1005/p4gnvfWhJiYAl3hqon6eTnvmk3CkA e=found last=23 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAOPfjW16Q9FYu7w61lAOG3yxC8r2v7cR/eGBKE8PTjdwei/jfNSoUnVGuQpXF4rgT1jbAzWOg5ZsA priv=MEcCAQAwBQYDK2VxBDsEOazqhb0RxbX3lpvqTn+RnzStySui538lyHjLCI5baFUlkjP0CxiaK+FhdkxhaeD7vtn5yFyXSB/NFw== msg=rOqFvRHFtfeWm+pOf5GfNK3JK6LnfyXIeMsIjltoVSWSM/QLGJor4WF2TGFp4Pu+2fnIXJdIH80XXxGdYjM17w== sig=ssJQbBxPgSA6KofTXPlgWM65IOXbozcPnDcwn+LzxAMO3Ek6yGpZqxenQ0YVeY3a2LqIbfiTfbOAufzPgplpokwAUBefJaUCQJA6JVF5667h+pIBqtxo8ohYdEO4VzosCsvnVlo3fcljTdTHPHn3JRIA e=found last=14 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAD1gqnK3v3hoQJYQ+/RchsExadncRM57pZTsdWyZqUNVPXzJPvodjaiiUjfcXL9MqwVMED/zc5kEA priv=MEcCAQAwBQYDK2VxBDsEOUKs0f7IEa2TTS7CeVDcRm6ybOkUlcWyv7Lug5ukvPci+yeuis2qciLl+xCT3BiDuktR62niWrlHRg== msg=yBGtk00uwnlQ3EZusmzpFJXFsr+y7oObpLz3IvsnrorNqnIi5fsQk9wYg7pLUetp4lq5R0Y2NeGIX28/ES9/Fg== sig=HHG4uKqjwXl+Asxf4ziBJPwMtadBtI5+pkKSzAslqGuOiM1AR1cWZeZr/ZKOvl4CgoVSnQe3SEiAMjwSiuGJ4tO0SKvi54F1Dezz/d9dqcMuX7hOOAtqANisauQsHAmLftApruOs8WYZbM+z6Koajy8A e=found last=20 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAn+NIdnflj456kNyURxQxJdqtrWmIR2nH2PnI4A9zIJz6NwMtXcAwblPcUtwZhMwVOfHk2znkPAWA priv=MEcCAQAwBQYDK2VxBDsEOeHlsK6ShnUbmIwKHOYmOcGAw3MZWECmPlDRppvXCPLjADiBAR1C4/E2uzoETRDWbBUf29WSf4y6Rg== msg=sK6ShnUbmIwKHOYmOcGAw3MZWECmPlDRppvXCPLjADiBAR1C4/E2uzoETRDWbBUf29WSf4y6RkjG3cxnQO9Nsg== sig=Or7Exmi27HzKQx9AylGwVUejUQDZBS7evOQmq7HTFaSxinpRipv7JzPh9ueZUgUqjExM61k13agAb+yvXr+tQkNpNouszrWwJXZg2Sh/U5b95hS6ph6uQkqROb+Dg16K1NJzJI7BZt1SBs8j9tdz6zYA e=found last=22 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAjD8M7JgYAL8sz3RhAx3VAgEIZiLn52B7VtqL7Bda90H0WuFqKc/dUj1F5hjlUyeDI3kjPrxgriAA priv=MEcCAQAwBQYDK2VxBDsEOVUNchneCLuwHLNqTQdyfbbdX5ia7Z93+N7+3StBQeX0wzvBOd7uPtKT63h87YjAY/jEEzMIDtx5lw== msg=DXIZ3gi7sByzak0Hcn223V+Ymu2fd/je/t0rQUHl9MM7wTne7j7Sk+t4fO2IwGP4xBMzCA7ceZdiNUmYLicqYA== sig=bRjxZhqOWTCFGmx3ofhbqh8mW4Y2WeiOQa3gXnBTuCXB3omM9RmT+zcK4YmcUeVzJ3PZbGhnxYmA3Usvaam1850ZjOOnnbk0DjgTItZY9bErlLR2jex7iK1CtPlDhG9cWjpP2faQBvZfLd6ydqCr1yMA e=found last=24 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAORjHC3UtzXqnINCXdTGnu3UlS0emSe4YuoLm8GRmmKkQCpx9zGZG5BQrVl7dOq0VMTrcxYGzuEEA priv=MEcCAQAwBQYDK2VxBDsEOchgmbvJzlkT87xcedi7sjGOFFrslb1V/AfTyYENv5kSPr40aIn8T/7REm3WCCWrNM/Cba6sRYl0NQ== msg=XHnYu7IxjhRa7JW9VfwH08mBDb+ZEj6+NGiJ/E/+0RJt1gglqzTPwm2urEWJdDXrk9GUqW0xU74zq/YeklczAA== sig=/WH+yyGp8IM6cQTbFWlIhbeM8yOBoAzOeZrI1NBKgMEEEpo9lRfIQ/bCqsXR/zZaEI0iZ4egvmoAgK3th994s2ZDJlLK3qR8Xh+FbYuICn1akg9BXnFzSywqFwik/6wIMPYb+hpedYFZHQkWWKiWxy4A e=found last=15 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAyn/R3o7bry1UTHxN/bZZMPyVWcUGDFllWKuN4Uec9aCLQQB+m7srJqAH3M3+8gMnm6okosuwRGqA priv=MEcCAQAwBQYDK2VxBDsEOapba+UkI9GVJgZB7Dga4MaD9iqCgCFUcGCnaRp5vYooV8CdNjGx1zWHedpTiFiDKiw/inabkVflcw== msg=Qew4GuDGg/YqgoAhVHBgp2kaeb2KKFfAnTYxsdc1h3naU4hYgyosP4p2m5FX5XOUk6m3d9R2DMFLwD/XLZDJwQ== sig=Oe8vaTqXZZsbojQ6QZYZOaaeq2qzNEbXB1BhRpWKc5t4GavnXMWYpHM9BGYW9F5n7p2s56blDzGAxGlZVpYDMll3u+oc7IpjmDrd7fKAlmpA7YxrRY6POuoL1LZmrncr0ob5S3ydzaUTGKh6YfojcSIA e=found last=22 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAcUnB+XIhRmQK8MTIpHvd8G5PWSaMdFVgWXMbUwGryUAiTVBP4NciRanBm0N+Pw05PJqQglPOhM8A priv=MEcCAQAwBQYDK2VxBDsEOf/f3/ibAVUmRzqOOCO1A9gRgh4yRYWCnmkUn4f1/Ie9zD8Vss/8Vy9cNe45QmzYwlay7FSZlk2zUg== msg=AVUmRzqOOCO1A9gRgh4yRYWCnmkUn4f1/Ie9zD8Vss/8Vy9cNe45QmzYwlay7FSZlk2zUnVV/ddhbdaBF+OqNQ== sig=tTvBMDRbo3PHD6yJmQdOr6yu+oiqLvtZIETf5AI18tiGgWya3N+WpaQ9MUrFc6LXBmf8tMY7H1aAPeNnqre5pA1ozJReXDPbetX+ZbyEiwLzXxwIueCeN7cRB3ddOM3uInWFoWjHE8I+p1m3W8vJJTMA e=found 146 iterations", + "pub=MEMwBQYDK2VxAzoA8r7r5/9I92jwEjQ3YfUTCzl7rWgdO+olCZZhHw/9zxEVhSnYHUTox5pV1wtdFQzSDWeuMCO5+5UA priv=MEcCAQAwBQYDK2VxBDsEOeOepWhRwt8V49h9hp6esd1UYLlrEx6ekN0fsknID5eV9iwvziesRlJfscwxE2QkDgQC7PX3heX9pA== msg=YLlrEx6ekN0fsknID5eV9iwvziesRlJfscwxE2QkDgQC7PX3heX9pBUT5IE8cjdvfqu2sUTAh/cGFKMRrIXamg== sig=XI2vJmdrtXNFpkw/Emt7AegnWIFB2PyKpLQhWYpakAdhGawLzyTDu8L69/RYIPTCWPw3QaMagtkAuOoCU0D2gYXW05+f8iUdp4kmNAeweyUZkijPy4OfFTM+cntUgUDLcvQF+3D+yr/Aelfo1EYBPi8A e=found last=18 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAQRSSVoNjHWqmakUGKG7LZnw9qMf7EJ1DlAcwY1XFNkU+UnUcVff7RDpo5J+JL6HMZbMs2v5fr6uA priv=MEcCAQAwBQYDK2VxBDsEOc5ocmQ7yp2Yc8Ua6s0mGPElTaVsu7c6i6Kr5tuLrgECOaqI76yjvErSylvsXe/bsh5O4bVd2cIEgA== msg=zSYY8SVNpWy7tzqLoqvm24uuAQI5qojvrKO8StLKW+xd79uyHk7htV3ZwgSAmIvv3qP1JCd3m76LSPo6/lPInA== sig=/oRmNTpCoNjVydiB4YNpF3ejvgvzBScB8MB2cVYV5kNlk5IYs1XVK5a/yUO4DgXZJOB+n38Mr4yA4XTWpShk3LOOkxU2q5irrZDQlx/fZPbf8Hz6a9x88s48XEGyOZwfI+x3/57Z0PI1e4i/qIIrjTcA e=found last=26 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAmVxS26lHLjZa5P1u4lwJiPL5ebgWIwaREXB4w9ZiNvsa6e4K3jEz7KrWBAVOTk4060/3FGbmL8yA priv=MEcCAQAwBQYDK2VxBDsEOVQL4/oDlXef53AomQx9aY7o/XbxGkx7PMoBAw/n5JxPa+O6q06WoEEG4pG8YojnIHMteyG8kAaGSQ== msg=fWmO6P128RpMezzKAQMP5+ScT2vjuqtOlqBBBuKRvGKI5yBzLXshvJAGhkkGY5PkNcs2WiCr16PE9uffBOqYKg== sig=Y61d+d5kYnNG0T3b/7/Kh7e0431y85GPSKvyS8baP0zXB7Ky6EUihC1KDzGaQdhWN3t9hyd4M7sA7aOk1wZsbrEX7o/5V2ziZxPLXzXwgj9RZtZrSXL40G6d6qMLeP/xU6d96DIJhWBRTyfSsRM+gggA e=found last=17 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAplpCiZfdieSafHqSFgYzLqkD9c+Z3AqElRumzWjjggbXaWwWR9nAFHUKlfpYyiZTEgSwzPHjE28A priv=MEcCAQAwBQYDK2VxBDsEOcVPNk5zlR43xA2wkpWfU+IAmh4jx0bxwesnqQohO4H4uZd9ISBhJtJdoWjC4a1z36GsFRw9vVHb2w== msg=CiE7gfi5l30hIGEm0l2haMLhrXPfoawVHD29UdvbHa8uGPPJ51GLqrLgUJuVvFSReU/UtBaAoeKalxQxLd0QnQ== sig=aiT9IjVMm/Ji6/lSMpvoZ3+oLUEcIlkWIu/8Wh9jiq1NFWED9wloJFw4GAB8li6yl0RDZ3YY0rsAC+R7uu66adQO2uslB2ogtIR4OTrvyAPIop/P/eq69pk6ygIlBP/KxArzpbl7JYuO6dsVanlIzi8A e=found last=27 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA2PprHtVaWSQO+sorQURmL2eWqj6lAav0JgeFIGXev98tDLsgeRem9VY7Y16MeVqIN0AGm1X2rNOA priv=MEcCAQAwBQYDK2VxBDsEOVjEaKkkfv7nzMqlrYM/LiPF2ORPPnu2dSBwKLyMMXKZx0YiX5yZojJcR5ynJX6TrAaIaWLv3OPkIw== msg=cpnHRiJfnJmiMlxHnKclfpOsBohpYu/c4+QjDIJg37QxOZj6x/qIkF6whzpPp9m1+6xMV2tKCyD6O1m34UhVvg== sig=e7XApPxgRYEviTtD7RrkdRGEAk0dzP6gAlA/v3orPk5SbqLDxpoLXQxJ+7M9Nq1tDiI3a5q8SLSAmkHirQuSqYFTSGepaHekmIi31gtErMu5jGYiPLFq3I4YtddcobyfxSo3i5I5jXolQuM/Zm0YGj8A e=found last=27 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA0BwdJ3k/myOmTJbBBl18xHkysrsmLoAF+FN+MtMoxlPtVS9gfuxrkL0yHkUXRYlz/F/ciZVZMDuA priv=MEcCAQAwBQYDK2VxBDsEOZkP5BuHFnwpcANp7XheXVAFPR5TcGyU+RrhktCwuo5vI8yFj4x+A9ToHmPcYeHpPeFw6bACid59sw== msg=ktCwuo5vI8yFj4x+A9ToHmPcYeHpPeFw6bACid59s5DmxHpyR5tMTGTRvgGLKLYTQiH4UBBcO/pExd4uuFBJjg== sig=9iu064ZaXTk5cmtz93K1ybGpoqvRXzQFL7o+Mdg88JoSe6YT6dhoThurYxqyzz3OdLlzAPfbYeQAw6NJDgGvsXVfYNtFvO7HCYIZOSSDpzSI7s5VXetyAvSXA8R+MnmP6JO4tVg4x6Ym5fLa2GemYBUA e=found last=25 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoASXyf5d6EQhZJqYhkyeBCfAAalfwD6wwuYtzH57Jv5+mWmtv5rFwFgiBbZFuaUwD25vkAzgcuE0EA priv=MEcCAQAwBQYDK2VxBDsEOaVUyrDevXQGL0lADFpUvVgEkAH3tfhaVCECUD/iLBs1jnrSoejAAM3EBCpn1ay0HWv6N+mjb8UJ8A== msg=jnrSoejAAM3EBCpn1ay0HWv6N+mjb8UJ8EevJMb1dLH8hXObRuqpkUX7kZgEVLFXaUfkE2+dvVy2S5GXP3i2cg== sig=WMqJSivoFgZopKCAbxOo3pxX/y9Oiu4GE4ERxYe7QLZLz4/bmvzRIg1X2BgdZsszHlScVw3vlG2Aco6xrCPoEdO99Fr9t4MNw1fzA1oT3bQaKrRQmVX2SOukqKl03swiRKcIb/ZNjdouNUqIhT53qDQA e=found last=20 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAAovbgTMKVc+pbuKCR50BuOGoOBnxjYq6H2NrbdLmb7xv/t4jQG/1nsBNP12Y3hPZMItP01BttgmA priv=MEcCAQAwBQYDK2VxBDsEOVTM15iAWsG0UJnQ/NXbqnBskJ2mnKbBEC1gI+RyUwZ7hYJgMJc7gL/LXkZ8M9tL1J8LPcgqB7eIzQ== msg=v8teRnwz20vUnws9yCoHt4jNZhps5Gsi3EsSskPidGiITPzxYmhaGXbbxvf5/W+gVzZ4+tgyq2H8AHBHwjv6jQ== sig=ck1w9rZwjihFGaO6Kf76OZKRKPXB8fK94jkgGbbfoeu144zMQKyt7sQI1sUOrH9sWBBrWZMCv42AFA7alax+2Hs5guyikosOdHCWdxLKH9QjUdS9iPeHnaJN69Mimz0A3Z0q1AtNkok7AtDfGNM69gEA e=found last=16 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAVxqD3kXCO5RUi4rMki/ymciUxXfrMW0+T84DVFzaq85LwGcirFWrLaHCoeoSgSI+Y6zU1P5QByQA priv=MEcCAQAwBQYDK2VxBDsEOZ19RBrN48rVyXUWkk1r4W7EfImXNwSAdtFnpkLnt4K1ky2qnvmfjtlBUAk67XU25tkW8Go06A08Ow== msg=5tkW8Go06A08O1gJfCMw9IvzEjvZY9jeTT6XvmZ8vLT+aUxBVZ/VSscI4Vi+nnpD/91F2c8cwswuD9klIEemRQ== sig=WjfpziayvcvovNFfVDV5HgO7lLJQ53RklsgcpQKWKtX3Ovutpkz5oBrrmIo7Eyo1ZA0Agp5Hc0IAtzDK9dA2Rxf0Yo9sM3S7J3MWjeJFabtnpvacVUTOofGlD51d6c7WctuG4rCjYNlrjSm6MIydGCkA e=found last=27 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5unE3beTQjBV6uJoAqYss7nr2HhjVSce2AUJ4xVW9pI+cbC4U51Z8qWmBXaV9DBZCDWY0ZKIORGA priv=MEcCAQAwBQYDK2VxBDsEOYiwvyyf3rS5VS51xUpPaom3A0OOgy+DliLALscrDspJ+aShXkuW/7eFM5B7Xsljr4vtmVE31r2RrQ== msg=oV5Llv+3hTOQe17JY6+L7ZlRN9a9ka22h8yc8xyFI88r4FfiQMra3XULyavV5SZahm9pljmKQTZ19w8DOJmMyQ== sig=j+S4smCPYAAHudAmzt3yI/a+W2C9jUUUqpcce1y2F6IMEJcyj7nWdU6j4wq7ftC1vH1bQedQvCoAb9uNZjw+wmqVJcXo7wKNix/FGmQbg8bpq0cUJEH5SUXVuUZCQab9qKqvfw1WQ4aQc0umAWdO/zcA e=found last=15 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoACWGK1oCFhLgaRCtam9w5+L+dBW77T/Gjit+kPkCPoOjxYnjKAzoIBdxnvQ46jHfNFna3QqpOdvOA priv=MEcCAQAwBQYDK2VxBDsEOQBpUhCoC81JJd+pSgPl43lvSUiydYDE/q7S9UdgKBNajvZnzm1jpGP52yBDbrG4LU0WQoD1wRcz+Q== msg=+dsgQ26xuC1NFkKA9cEXM/lEgJEQgc1dzZE8y5Y76oeoizQK62775qBCfMRN2tJFTUqO70+rn4L6s49tuLye0Q== sig=hn1g2Ja2sVIEQUQhzgeWEDsCIJ6O8QfWmL8EFjqoVzvWs9QLOQv3avW4ezms8jvIhUKzGdWSUlOAPNXydDs9ThYWjjEI52wH4pO5r1NA6asruxAs66BINS/cPtbzEm/SXUPlqNbPDQnRAD+yoLvvOikA e=found last=14 s=12 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAOlUrk9XKEO79snFQTy9Yg/REoUB6DY1Oe6Bd9PjWeFPq8U/0so/2BLPWxuCbZ29JamtlHoVVljuA priv=MEcCAQAwBQYDK2VxBDsEOWJ5kLJbhRoOC27VDsI3+tC+fChzhYy6HUZk/DBgIAc47HsA6lMEkcYJTbdSr7N4s0uon4IUEN+NTg== msg=BJHGCU23Uq+zeLNLqJ+CFBDfjU4R8BWwRYMQZFm2/k1glKt3wiV6D7HfdU8wvxddItVb5+sAuYYGJruxoi2QSQ== sig=h1Io4Lc9UTQnjIQ7zlf8tJfowwH9TelHH3GfhkWxMA2DA402nn7aireccRgQEDPnw7W0FIxptvkASNdbDW6GzgQy2Dmzmx7uKBtrEdV6v/lHoZO/MD0PbS4DL7IzAUV0GVHLb0GYMw/ERFCkwSRvDScA e=found last=27 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAP5B+RqtAFLqQ4oD4vC+JiFYY2Qd28gtlUEl9tA2yOl0olsAHGdhOWMtBWsgLoMuwZf5hkY1HpiMA priv=MEcCAQAwBQYDK2VxBDsEOSs6IZgRjx4jzFWc7KeVDBh5wd3yDWFX6jCFxl3zWt9bCfkfDuDX+qAQTi7/BtJxoiqXa0z1CTWOSg== msg=jkpzeMafitU4XJy8lLmGEhqvdmRVy9xo1hvJ9TBzVj5fop1DOtQRqpBe1ksscYnRE7yAqLEyaucTSR+C2vgyCg== sig=U/2hcGSpNckkMGj+pVeKytYi7u/30FIaEiXLR5MecXMpAGNRGZB8gM5tV/ycOtjRcnNdEmXkBB+ANQ09fbNSE1fNgMwnxUed1P32J0ISP5K0tf4Jky084Tu5kt89Y8tkxylwY+ocAm9SeEBY3foe/BsA e=found last=15 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoApGhjnE/vmbugPDFuLkG2zqRnnWM9WxM27t9hyIbJSeL5Ju/oAn4zkV5JVpxmOE56HziPEnSWH3qA priv=MEcCAQAwBQYDK2VxBDsEObsII7T0X9YYv84SuFSpDH18AYGMoJotNdkb6SHwxMGzWX8qPI4MS9IKEHVlE6tuFChuwo3U9jxpwg== msg=8GsOi4MUURy+xFlnZtOOiughz/KjOwmMux1Ye1mBTIWZNiCB7kiLRT4aXaqt7o3BsRQEs4GGve66m2cvXdne1A== sig=Y4ZQh0sPIimEVgZaWj2Nyf872BoL2M1pObOzsAs9Iq2J8XwfmYTOytYwqTIDCQggbw1+2f5aIASAsP5sxcokCrgJgzJDJr89lm9OalNS4Vh/UTaBvswdBWqmFAevfL+O/M7O+1jg1uPgiGwtMOspqioA e=found last=19 s=11 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAvZ1j85PfP+1qSlWOksvll7L2ANnv5WQIMRKsEIVY3Pevch4uMsv8MEh3JMiL8uFMaSCwFEzKX5iA priv=MEcCAQAwBQYDK2VxBDsEOWjeXuA45SZTwje9fZ3nbD1RxXBNVeBKhD77rWBDdA9Ihjfhn5kE8YnuM3X2v9ZSTEqlqsmJsvzN5A== msg=OOUmU8I3vX2d52w9UcVwTVXgSoQ++61gQ3QPSIY34Z+ZBPGJ7jN19r/WUkxKparJibL8zeTgIu4ausJQIXJSew== sig=VPRSALrWqs/vqBRI/F0b1tGIqAqu+qhu1lbMcKGkhIAG4tgPA5fBpep7xce9ZRWiYpapJzHgdgQAiFqBooNkV9H68fb/StlvHeWODzSOqvn4sQTBaP/EVNlaxlvkPqFkK3NfhLL/9QekoGIkiNqQMSQA e=found last=17 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAUbrP8uxKtk+P848pb/Vrl80Kxo1ZeWe+taAI0nKIzFr0/CGiOwNoZeuZ7l9DDdbbKegkCqftJvGA priv=MEcCAQAwBQYDK2VxBDsEOS1K1HR2Z7Fpv9Q89Uop/LTd4Lo05oTEbD7TO37p2OkwxENWNYto679rgA5JDb0n/Kfmb8P6uaKbEA== msg=ab/UPPVKKfy03eC6NOaExGw+0zt+6djpMMRDVjWLaOu/a4AOSQ29J/yn5m/D+rmimxAcx5E3cU8hVXZG+Z0JtQ== sig=GeRB8zqvpeaoA84Mr1N54SY/cRHvJ6+WavwP95SLjGCt1TVcpxbO5CRxfdkMUynxpnlXsqrJlzOAB6daG0HJS59sp64gZApV1DH7ux4mcgSdt1yQhJqHDkExb0i3iV7D/l52MdLjR3KSbAJINLfYxggA e=found last=25 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAltMbD994aljRldJVdCbTV/v/HuaM9XMNThYFRsrSqG0UqWLKU/ZqJu0gxO26pWsgr8XlQGH0dU0A priv=MEcCAQAwBQYDK2VxBDsEOd0yDi0yvG6UdgmBgfngqGuvhlr77UBzhNU0/6PwCH3kuOeLjEc9766OuXYJWM9jEAvoag4OAtMK8w== msg=MrxulHYJgYH54Khrr4Za++1Ac4TVNP+j8Ah95Ljni4xHPe+ujrl2CVjPYxAL6GoODgLTCvMmq8d7RIBnEK11LQ== sig=PvCahuyoqE/tndrylXdQPferAiBPxVjomMQLyHzEcrwpbRcBrfMZtXEoC72dkA8D04ZeiZ+oFiMAW4mIohdQDulEV+tuO22x2BTfPg9QXWOIAJL4deudZSh1+41CQYDFkl5DbObaTaKC+YtE0N0EBBkA e=found 190 iterations", + "pub=MEMwBQYDK2VxAzoAL/Bt/k9zzDaIXtMBHgL9Oqg82mmOt9YtLiWTZRzUK6rKKidB1kthojztEKMWlPveI1XtrFTOaGMA priv=MEcCAQAwBQYDK2VxBDsEObTayo28NPgU9wtu4EF/DqcguBp8HlXQ2QEaSNF90cMsSCj3i+iXTVeagkdZOxSYyCTxzostBE36aQ== msg=+BT3C27gQX8OpyC4GnweVdDZARpI0X3RwyxIKPeL6JdNV5qCR1k7FJjIJPHOiy0ETfpp+7+wcWVhvR3nUT+Z1g== sig=6QspGe+XBBU/0+UZgfZpdktmDothWzU8XsR0TRoj/4BGAFZ/KI3fkTxo7iuFj4LZd7MMfipp+AsAqR4OLQ3AjuIDtwfsznJU4bOqLUywQfAVRWvph4QN/pzwpiCNTsWQztE603E+VgwdUwN6uEBGhzoA e=found last=20 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWzivRKOhmskORuI2CMReJ+3efA2fGCsL49z0wtJmQnM5H5T7UzObah93V4PHll4Axnpc44hFIRqA priv=MEcCAQAwBQYDK2VxBDsEOba89eEQHTRaAHctfCwIMexxlg6t6EPmxDeJyWdsBhCNHJQERwwLRaYrBk5VNyE5foHDPQB+kBm5Yw== msg=HTRaAHctfCwIMexxlg6t6EPmxDeJyWdsBhCNHJQERwwLRaYrBk5VNyE5foHDPQB+kBm5Y49luEhUcCoLf6xzxQ== sig=qRf5Ihij6vSGkFRfvJ5ZJD7ClsEahciUpL0nZuHItokhGQL73YXinTPX+HRxpA21k9J0gpxL+uiAY13yDEkTTuQuMDHmPD54VEGCbFjG5ZeIFkR1P/qnj74fo5ZYwu3AVzuRrOD6knt2RhShAHTW9RoA e=found last=19 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAl2mwVKuhB2bfEh/jjmtxsgxTnxTMz1RwSjD9yq/Rff8ZvQNB/lsh3O9VY0eeUkTSid8GUS588lOA priv=MEcCAQAwBQYDK2VxBDsEOSWiR3hryXn15+86u52aPVEmFBhKYWuO93vvGr6QVmWGb+2zZ0So8U8JXlSxJ48+yEul5Zm8pZcdXg== msg=7zq7nZo9USYUGEpha473e+8avpBWZYZv7bNnRKjxTwleVLEnjz7IS6Xlmbyllx1em+/pQeOMSgHm8tRA56pNYg== sig=fK4PTzCPl/6pxIV+k5NuROIMSMg42n6+bg10mAVKuV6Q8fy3Uo15XrgLBluWuWLlCpbXbd+mitsA53LbCNix3OA2sttye6wS2PMYS+QrBQ6o0AZVdkIqWBh8A7mySKAI6JcNysuISLCP3kgvLnAVOTEA e=found last=20 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWK3SdKW2vPN1+8HHnDVL186dHgG8Gzetd8+7K2AI8otScAK318JKta+bqOToTe84APYA5wdI7AwA priv=MEcCAQAwBQYDK2VxBDsEOccSrCn3Bd/kZ5eM/5NsguxTePUQiiYqQ9W0IVj1IRRRwu7TBbVUyiiBVL0IVV+lfO2vpAtmjTLAPw== msg=jP+TbILsU3j1EIomKkPVtCFY9SEUUcLu0wW1VMoogVS9CFVfpXztr6QLZo0ywD+/086oLQhd1etdgAqO/LM9hQ== sig=2Tea3eycAcALlq7vELUMXOt5bhjaWvAfOIqi0Kwih04svRO9+gcEY6/6QE6oXyNDZ9CrtuzQ398Ajmw+K+ePb8BMEmXIQsdGo6KQUJT6zNBtzX3xBSPLnOIRcVV7IZAUhYM98YKvglxLKnrmN9Kn/zoA e=found 143 iterations", + "pub=MEMwBQYDK2VxAzoAJGNle4K9PyMzatWV828nP1NBB2FoRGsoVGo6OU36l0Z3DK8mQUx4eNql6qRZc3IJzF8nUqPnLNmA priv=MEcCAQAwBQYDK2VxBDsEOalNISSnH4vI7+jOVAZU1bq5LvdLQePk4vlZr89HXVV42oaZh7Lv83RkBS84buD908aQUhB2R4MWLQ== msg=VAZU1bq5LvdLQePk4vlZr89HXVV42oaZh7Lv83RkBS84buD908aQUhB2R4MWLSrjYOr5v3NTEGAv9ix3XhVRCA== sig=aqXeBQhkCaR7tMYV2+s9kw063secFyGXHAlbuPppjufAO3Zdatlj3yOlHATdApARcashSu9UEZ0AElRNh5iuaj4PUeBQNeNgAatJ0ppXig2PWAKSjrTfguQAf6L7rAcMwzyCkl0lnff0fkzoh4/9HC0A e=found 147 iterations", + "pub=MEMwBQYDK2VxAzoAtMh1+yw0MNTPwd5zqz1xh5jfUdM1zpgUQK7tHCiqtgmEp5wfighANglnqTZHvVPWal+z7RjlD9WA priv=MEcCAQAwBQYDK2VxBDsEOcGJnwNys6NDwcsydhrX36Hok1j1LXRy+XmoS8Ldm8IWy2l75/uOGMuvO2msFPKpGrn2SpInYExfcA== msg=dhrX36Hok1j1LXRy+XmoS8Ldm8IWy2l75/uOGMuvO2msFPKpGrn2SpInYExfcPZjcUlBA4T9CltH2XgTOdrJ0w== sig=VSFL1RZYeUErc0GpG39jaMMryxg6mJM86X0/4hFn/K16AMtfcTultl3dCSicT2ATjPu+u/M75QuAhOV5uC531gGWc+U2jwI8B+rAvmvoLt4ONjB+ujMo6tHu9rMYWkBqvA1v9Q2VWYv2MZV9girZJwQA e=found last=14 s=11 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAIhGJLcDJ5yrAPsO8NvZ5W+3roHztuAJV0kcRuFSnraJuhcO/Iuj1CAnldki3uRWFzTS8U8qVcAWA priv=MEcCAQAwBQYDK2VxBDsEOSs2MZFT4C/pDTkrlxQSprqpZ4NdPy+oxWx4EL/Vtd1fSG0EHjLNo34neB0VXnFK9Pp8AOATJa35Aw== msg=OSuXFBKmuqlng10/L6jFbHgQv9W13V9IbQQeMs2jfid4HRVecUr0+nwA4BMlrfkDpi+oHHTYjECXLPGINU6g9Q== sig=37wKNtGJ3SL0qqUVTXTVFZ1I0va1Mh7eswrXzalV6Jc+bb0JKTGL4djJnBQBzf/7pD0aLkMrb1WA3YSyLv6bEQ2r1/DszGBW1SZ2i2H+8GB3eVpduj5/4PhQMwRbgChnGVTEvgT/WfBVApwwQyy82CIA e=found last=15 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAsfrwuNmbMnAKvo6tqxOLhPjBEL3IUUFtVecuKaHruG6mvl7CBQ0utYovC5BPW1+dl6303lSJmigA priv=MEcCAQAwBQYDK2VxBDsEOW2wRQJkmqWG5Ogi3AYm4EXnf+dSeZYJqIQu3hAPcVRM2vhEF/dQydEf/KvkoF2MUzdAyx6747FKiw== msg=lgmohC7eEA9xVEza+EQX91DJ0R/8q+SgXYxTN0DLHrvjsUqLYggv1gGtqVWW67ae4S2SLQiuHBZEkiETFv8Qlg== sig=OhPQ4LwMp3KAdxfP19v709E0P78aNdCD/g7S4bfWykcyHNhODpStYTYKVbw9sL5YD5tKe3ir31WAcKy8LCW6ubBXdE46ElDBpAcOWEF4MX9kVQfDxmRkMb6q8xUDnZhSNx6fFXPF6zXVX+ZGOZEt9RUA e=found last=20 s=19 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAqp6n8shW2EsIAnxno3x9ZL8x/jvcW3us/kkTPfGsxkwvc1lbwdaCwDTvVVMkdS9DtyKoox6q1EeA priv=MEcCAQAwBQYDK2VxBDsEOfJ/tg00Y7aKhoayxeEfmX6Vc3C1DWRB2PNHU0d7nrw8HJroB+1l+jPTJAp68VsWUdYaGJN209QNqQ== msg=7WX6M9MkCnrxWxZR1hoYk3bT1A2phHiYzx6MHqflyIGQboxCuwilTRLEH431ldRc3x0e/qRyylCYIKF7EarPHw== sig=BoN38PKhE7iqdtw85xY0ZO5j8MGk85nJayrGnucpupXrqr1kkeKkwhwlrnIZDrJm+f6BDEs2QtsA6qBg+c3nC5C9GB/QtkrzsZ6Yce37p/JV20C8M0JjrmnWcnkROjiLbnuJQ+RTc+JMlo2wvl66FgUA e=found last=16 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAWViUYAxxo2+Gd1urBjppN81Rme4Gg4VIlPTE+A1cT/P81PWcAJ8SIjF6PCqgymc393uXTa0FNSiA priv=MEcCAQAwBQYDK2VxBDsEOXz4zLVt/azDIzkHXrhbTY/iL9L0NFdHY84fyWy3Yn4dP2M9LdqcNJ7uncohs++BN6RkaDNSKn0Eyg== msg=Yz0t2pw0nu6dyiGz74E3pGRoM1IqfQTKuRkI6aR4lje8gL7ofk1Tv+Hq1480DOJkxLOg0eTfQwbwksgulbpX4Q== sig=MkYnIprxCfsvHIEozjl2PqA3SROL6eLGUHzWnaDvDzFZ8zXttCnNe7XFCFwfB8a2D/Ks4L/d+eyAPazCwsH80Kt8925FlxJS3byhleeM+rV+cSmdKLsb1JmZAtWyj+/WQ1l5bX2XjE+45N+3K18rTxoA e=found last=20 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAKkqzxSEED4rjJafQBhy4ihd84L0RNhaH9HZbMs6fQgerap4wkYRYiFu+PFTrKHB/FaNfwdDhY4kA priv=MEcCAQAwBQYDK2VxBDsEOeUpQg43gS5RWKCNy7djfWMCQrkTkNIqSLy6HafOMREtV9aXblLCI0iQYlWe+KYVqYXPnyqy3ZLEYg== msg=1pduUsIjSJBiVZ74phWphc+fKrLdksRijy1+tn2LlzRMa3BDeWRd7Lp7Z3zKWR8M/QmxjnhqX1wtaMivo8pTZg== sig=NBM3MTJd0L9Ad6/CmGLaX9VaSzjZW8L6+ni57m6mYcVxmon89AEi+gR9QWTQ9CRcS8LMLAm14aSAtBhxfMB69OS7vAsOJ1l5fx8bn0UJoR1Nd8b3EpgjyUs4MkGnsucCDe7xisSmyMIKoLzJKQav6xsA e=found last=22 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA0cv+RjraAC38s7g+4mDSGsYjLFmg3usf5XO/heZECu4sne6DEUeoHW+S8Givep1uHor6x95W9msA priv=MEcCAQAwBQYDK2VxBDsEOXaUttHvNqieJ07h3prptgZVmp1islJIMNrwn4G5/ABj4+ObIi3iSM48bKnG/axDRNxgRZwHnZb3vw== msg=rENE3GBFnAedlve/iTzY7R3q7tNplIfTd6M3KTkwYfT0rTIndnZ0vDhrwiNWdU7pmWHPwaqzwp4egGi/QNJxDQ== sig=ldIzVUW4vM2x7uZ0CLzdvAFn3JWLZoDJpjuYAXFV6S1PNMFvcNxUO1jpeqLYMwtF9kzRujowg8eAVo4SxwT7o+GeGQRFUAfVnb70o/tEgarnGfZy0KPA8icxJLo8i4MWZeEig0VEdnJzTasprkaHJwIA e=found last=27 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAiNscEfUroiwTwf6UlcSzZxYxGExSkK3S9boi3IM+rNe8+xO0jiIoloGbVNbEzzOdOwT3J7UMMJSA priv=MEcCAQAwBQYDK2VxBDsEOQT798b9C5tmoH5+vVbbE8fkHghTo18R1E46BHGYKdIHo9JeCPtO7cc8lpS7DCYAPUz2oVSWJft51Q== msg=lpS7DCYAPUz2oVSWJft51aZ+q9HnOa+ROTtnwhbCL0bmguKJmlizOGvw2JoYei1mEDLaG/ojrFtWPlc1kUxDpw== sig=cSRddpE7jNjecPDug4EwXiafQlGwRYIS+DJINRZrXMc8Pq5Z9+5M+iIhoX4K0x7PuYOdunbZDr4AFOI18B9T8GRgWg7C/1t4joaVe3fQk0qXyld2t4M80ksKCl+8qt5oD9W3NGzFE5MEn0dOdGZLriwA e=found last=20 s=18 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoANTdU0bOCQkfEIeFuQndim1Hf/CeJIFhXjJGOXwOxjhbXQ5mCoHREm2I9fZnkQR9KqyB1y1TwUwiA priv=MEcCAQAwBQYDK2VxBDsEOYXxbtKf+GsLm7zvRxbcrSpfJ48VowAEXe6dmInIfJwZRaI/YUr3Y6sB4qBM3kirzb77ftsunxPI0g== msg=2y6fE8jSSn4Fh2xhBcXasIZVxtV2/EXO5apcSQ6Ak088J/MBo7qZC6PrP6J66HbRpaxuBuAGjk/EGHLgi1+K/Q== sig=u6Cu7M7Mv2fkFuCxWKOSr1zheC76OtfB4w0cygor8LVc5vku0W5skkxlgSRe/Lb4NCNR+IF5k9eAYtJMBcoNQpmObnVYXQLVRAOb/vqoV9C8CazvbV0eWlxdooNjSuKhQ5YAF+tQy4KL2KQjF1ATZRYA e=found last=22 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAE2xMoLT5BDuiBVUfp94/Ehv2roCXoqcow1SkreWZTD3zG2U2Bv0GnkXIrYJYXQOF+yUCF0wq2H6A priv=MEcCAQAwBQYDK2VxBDsEOUVpIRIgg2OyLwZHRWxDnyR/ZYRHHehdcPwVOIX255icMfClYQR8cRy7Fx7z5ZsQDZNV+B3ZSd8HjQ== msg=hfbnmJwx8KVhBHxxHLsXHvPlmxANk1X4HdlJ3weNs7LQbgpowFH2NV5m2cXkkIdv5/1JPQfZMI+rd/PuuACDEA== sig=W1vfErTcXUPiB3/ulgnbtY7Jb55kC7PVIO3HiNyu32ZdMy3PXpsb0BKj3IhryuLtDv5kSTTSMloARlEIKWEHOfPAXZlM2pvL36SDYUi2Xdf1IyZSeUW3vdr3tgFxHCpz8vjXfPWQfv7vUZzvl2q6lCYA e=found last=14 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAacSlr6ROaVrCichSJezleZuKSsRmQ/+TY+xsyS926I2XDBZL9cQ5ZHnkm/3VlfOARwg+n1daAuuA priv=MEcCAQAwBQYDK2VxBDsEOeVbTaLT9Yx0YevzC7r2zI6n35LrH9qpAhofTupz59lWzPoXlR2mPaKwCOmOTpKkggDZ5Fmha+3Q5A== msg=KJfx4ElSMvArnl0uufnJDhiCnBLzW29lpPy6MVPPa2E44m1D6pG4HsyBMgO9bS5pYi+y5gDZnc5KMtJvTaFWKA== sig=nPafoVPeQYBfbGT8k+gdCWuUsEyupgNKR+l1yxiTNZeiNpR4ngpd9hchktqHCElbaqZUTciOFpkADLBoM6wiRJa/yhUyxaNwqxOw2HcfGj5fNTniq83ubDRb1giHvUFIUr4WtEmEWReRxR7qUkqE9DIA e=found last=14 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAPttu60QAj4OPqmZfVrxULZB7Z8g5iMswAktyvkv4JJWKQoVWiM7wJ6LxVYi+7nXcz/ppnlqx1GCA priv=MEcCAQAwBQYDK2VxBDsEOTM4u4O0/KkW4ZmDXtmDu5z3ppyRtWYpGkkvl32nOH6OR7mvnKHZvoDLhKZWnwTGXiLFVLvsB3bb4w== msg=WgGHRoGVAzLJyk7VJtzybh4Kce6+X7YU+BDAKT1RXI+3EM9Lx2KjxJIByfxtbwKu8H8uRVaflu+FV6Os9b/qWg== sig=R6wHTseVhpdP8VGJTdgM+RjpppFzeaxHfa27Bs8XEAPxdN/pvaWqkdGdPwVZex3sCkVMyEuy65eAL8z2N0wj3soxw96dYJhnS3c2M0pGbgpy0cW9+gXBcOabTDJqbltjdfw1PexrjnQuTWjgVujIhw4A e=found last=18 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAbjJcvWoXG/IPQTAB4qLXaz8Anpr3y+w/DcM7UnwgTO4AsbFqsQIrzYBtknOr7eiVBiZXwWb1PtwA priv=MEcCAQAwBQYDK2VxBDsEOYBSlZ3REE1Clob8jzeE7TSPfhea+OP7uN08r1fTAQv31zUhGIoZKTO9gihdKjhzHbQxIwhotjodcA== msg=+FMd7tr4DsfE7WcbldzPHx2ZSY0T628qFnJjlLRixIE8K/skhlvLqFDIl5iNu0x6YQyNuoCb6Uad4pbAPCajJw== sig=oQCb1+GrUkLIEMJkDoLc8GB+K4xqq57CWqDTsd4JXgQJD7tU9nP6o7mNaqy2byaGTX6riwk6HecA+/SJvZp9m0Ll1MKscTkKclWli8Aa9AFIF/cSrArJGdV2aHfpDuyZ54SZgZOpeJetF+/bVvOU4DsA e=found last=17 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAr1V12asHLXScuKmHdnhrgCtylCHdMl4KBvBF2L0JCjxdxjGmIfhBegvoCtkZSL7MGYxQq4DjdaEA priv=MEcCAQAwBQYDK2VxBDsEOWgFKtJ+Yb+XMcm9KIr5GFCNVDUOJExlK9TbppzN9aGVOuhm6eImMgUtu7rC6B5CmprvGKk5sIRaDw== msg=3MtP5kEfFT6lIGPuPAmXcqZUYIyta+6ezVVQz7i/YEWEtV8WHI9FLlM2ykUIhgRh1VWxrHqF3c6jOqvOvlyEnA== sig=dAeXaAOmFpUO5ZTLWbgt5CplxlTDrlwTSzFOYqsYmPXBvKLz4WLpRlSSDqfGjpyBzZUsuBylsfYAbOLi/sRmin2MLEZbc941jQ/cchfS7xerRmpoVxc3pZyndFo3sYWaKYtsulRDaHSmokkCKGmETBoA e=found 144 iterations", + "pub=MEMwBQYDK2VxAzoAYvmO4NqFawVFT1NKkB8XavLjMdQUhBdf08CTftyA9U4/M7oHct6SbWzbu77XbQKOzEAHpeJ9m1yA priv=MEcCAQAwBQYDK2VxBDsEOTX3sD0eZEHTvyIjGeyQB7FpPlkNHTuhIyz6Gg9R1s8LDqtOeP2NhH6AJaFB0FSyVYwVp0/sfP3eBw== msg=dyi3l2/z+tT46ssByViEjh6AqSjCBN8ZMhSJqjY56+5uNOqJglwJmblQttlUcpKg0zpFsx9f7mXFIPYg2R5/dw== sig=NYF6DlMvJFiDNUF2hQpYCX2UTQtDlIBTNujpyBjQ1dbbe+PhciMLKqYX4ltuaA9S5WPXdK+zi4yAqbW56TsbkxuZGYglh+ZzlC/ywtefcxQ12n9wAJNr2omo1xLk+CsK/REOOUI+j8K/C1KodCfoLzQA e=found last=24 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAVmteZu26YWbEpPrGYKZvCxRZH1QQLPo9VK9ot2XT37XT5vT7BPjEgxAW7pvIO3c+wPy3YTp2AZ0A priv=MEcCAQAwBQYDK2VxBDsEOWK93U0WEWcF2Rr1CumIK9hbKHY31Idi0JHFj0gsGd+Mn9IrQOF67bh7hnk6sBGcszjpQf5I/CNOAA== msg=I4pg1bZYmPkjitg68cN1kB7HSXOjp1uUxAvVPlH3CcCouSOICUDowz8dY4FHXl4VrXlQ5GhKceuS64HZLFRYKg== sig=4zntSHSmp/L9jfoqzdwDQeWrJdcm7zdvZWKQlKkTj05+BaW1q9XWDIDlEWP8KLxb7Ro3YKesO6YAcrx4eJsMOtBSZj0yyroB+iVvEwH6LBJ1LMBQZwoQV85hJluG0Y1sqJiwtNUgAF6xCYno0kaSbh8A e=found last=19 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAXDz6uEzFMg54Z//vGx5EOnvxuiAVBUI68i9C5Au3H03eRfLu1wfqfwWhoHH46Ww1MSZcVcmSXHqA priv=MEcCAQAwBQYDK2VxBDsEOZUkPaYtrxnGjPwUs69/nOiOP+lKmoodaqzf0yN8gtpFyPcp2RvwJ2jv92CLm7xThh44CzCfokuBHw== msg=g8VUf6Vk2ZHD4OqylQDveowf/uBMR9MYJAvKmVp88VXQdGBvY5XuDqFX00jhtjqLWUZxWIxQrMjP6JXddzX2QA== sig=/DsCLUxUztWWZa3FUSSfPdcGPMa7g4DMll6dMxzWHtPtJNjWlJ2CBpKnYGL4322fH9RhFBb+82aA/hWxmQLO44oOoY9QB0XEZQkz2bLlXNYH7rKBYCeMub4x2T8hqy0RHZw66Yzf/pm2x3Jg5PQcfQ8A e=found 199 iterations", + "pub=MEMwBQYDK2VxAzoA1DmXRxSmQebZ6yl/BTm9NcHa5whcUhQowISyxXoiLx9PzEsUMyhXp+cT+cHWD67dB7gsCNan8ZGA priv=MEcCAQAwBQYDK2VxBDsEOXFmhg9hacV8bODgZcsXYnnddOUpa0qkAbs1cZPTlbYDnjIfv3JbChwbA9lArO0KrVJEAQaHJViuJw== msg=xXxs4OBlyxdied105SlrSqQBuzVxk9OVtgOeMh+/clsKHBsD2UCs7QqtUkQBBoclWK4nDoMU5YX6Fdx2PvHLhA== sig=8a85b6l00bYG5nc5POPLE1XxtnhwelXm06V3iusfE2SW4k+fsRH7r+YmUbgXhx7pPJKpc1xqDZeAgyrqxQjl/Sp5p62oRfzSp6A4+GP38RMvo/LBeHrD6kdPmrtYI+vzmctuj6OVcswlPh+do2dq6xsA e=found last=15 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA3r53weQEmDVDZr3o+7dYiBEtVj5N5ulJ6GMIy9XHHxLsDKIZbCdhOVRmoz/J+9wZI2fvSZVK0o6A priv=MEcCAQAwBQYDK2VxBDsEOYLhq536UW4wuKnxK42MvK2joPw9GOF5iiOfGLBv4vrkvZaGRmcQfrlIPxNXjQgWk6rvHxMzYM+22A== msg=GOF5iiOfGLBv4vrkvZaGRmcQfrlIPxNXjQgWk6rvHxMzYM+22IQpeKepY9mJvsNC/cC0YNKG+ewES8D5C7ijQw== sig=MGYPJzzypPO/gQet3KZnmNQYpPw0BKeEbM8PvtIzAmYnD2DlVyL3dHdgc0N4oX4QEEAbk/y34wkAiaOOVH4YvwlJEUpJagyJV8w3IuMXXEwUnl+fGLVqD2IF+UEAQOjeksEhFUA5kmTBI+y5XZivLCYA e=found last=26 s=17 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAmeoBlYw4qt5+EUmUmp21lDXZ3A1/671yVYy2F62kZc23n8uM+gHTVgEU5I07cMWA6abuo2nYfLQA priv=MEcCAQAwBQYDK2VxBDsEOV+gtoPVNJ2cUp+PSO58bVfpEsnogSwcl1p7jX0LKOnbzfdWt6Ru0AElmxkDde6IqKks7mLKU2i6Zw== msg=l1p7jX0LKOnbzfdWt6Ru0AElmxkDde6IqKks7mLKU2i6Zz8E/OLaKkLeokKS2h/r3Kdlf9sfHsNoS6PWFSZbxg== sig=gzzINSh+Qy4PgRd34FWSoGCN+tfU9Ofqb0z/DnRuB2/y4kNM6gLUIaabp1UWiukUwedzdlzTQXCAXA6xchuDOXxf+tYIEDyiaSy25WOD/YA4Y7QdFFB9/FeTYnbAEZEwpLO3KJPRQGIm6HBejakfcDAA e=found last=21 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5hjDWQNOPtYgrgfzQM7MB0KwTnCuMI2wPZgGAsnn0c86pr85VqEGjrU6kiRx9qWaf0A4LDbExAOA priv=MEcCAQAwBQYDK2VxBDsEOaGPicMzDMrxF7xRa7cGswWxw4IOF8MyA2cJSZw7v+iuDD9kUeJWWj2rpS0bnm+H2g0jp9xosHItvw== msg=wzIDZwlJnDu/6K4MP2RR4lZaPaulLRueb4faDSOn3Giwci2/ygHc0ts52+Wn4Z+sszlRC0g0fj2E2/44AT47+Q== sig=rb3DKugjRRsGoR/Z4OwknmV34n8ihMRAoONm2vR20eB3iAkT+9HQhCSQ3e5t864PoewZ0tJ8GRqAxueus0LIZdVKE1Ws1l7yd+d/6wDZ2Mvdq2l4V4jc43wy//FGFrtKkO0LA8H/120BYSpe6Er8ii8A e=found last=15 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAtByCkKhbh+sDoFv97jkadCrZ7pTLb+Ohh2r19ZljENU4z86OzG175GdFiE/jHb8kmpDcqTthgEIA priv=MEcCAQAwBQYDK2VxBDsEOeHvJLwwYnkmfthiZmPuswRZXzdz3ToaCCZEI42kXqo6B+1jRenwdZbdDIcmVdvCU/xG5kIKmqAvkg== msg=N3PdOhoIJkQjjaReqjoH7WNF6fB1lt0MhyZV28JT/EbmQgqaoC+SyyXCSWbApeESPpcAPoI6vtRRUYpPftqIKg== sig=S47e8ULMMcPKp561IyquSHAOoFjd83LMWTiooczWAfw/Ki+iB+gxK4HUWo7rDPQE2iijAKC6w/aAMDg4lcFP4JAn9zsJ6IL5WKjJ9ev5kmhsoVY/CH4D4WjFwLivFfv0jZittleAo8PZsJSltAYLAhsA e=found last=23 s=19 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAusSlabtN4LActPsaTKKNCU0ee2iJbFNE68toFG1/H1E2Z6rAKKy0Gedx8gAPTeEMGZB5xVxa/WGA priv=MEcCAQAwBQYDK2VxBDsEOY2fRD02nuqALZC+lzL2IgtPT1+5qN4IgpID+ZPWvU9XQs9pfqW0HWhF1aytbTuboLcrdMKrFul8Gg== msg=Np7qgC2Qvpcy9iILT09fuajeCIKSA/mT1r1PV0LPaX6ltB1oRdWsrW07m6C3K3TCqxbpfBo37qOqxh2ou07b5A== sig=muB5O0Fyj7975IlKfBz49NtUdTgf/QT00BzB92slyoHi0+PWxYx7aGUe/31A3jSPD5HeL91pO6WAiGeycrYIKqh6cNPKnkcKZiFm8rzCF3TGXAPZRfNx5srlSSPwqUH/FrIYY7Ug9qoevFZ29grlDhcA e=found last=19 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAmv6MR96qPco6yzJBLLsqvDVBbfJAo7Ou/LpMeJg2WjrZSiQpHlU9LdNCHkYj62NgM/UUSYStcu0A priv=MEcCAQAwBQYDK2VxBDsEOUgzjGKZJvh70WhpOEFyLO59hudIYV7J/VvBb1Plg6lf8wp4QRC1Glr+N1IPG74BfyKzu3/d9qEsZw== msg=M4ximSb4e9FoaThBcizufYbnSGFeyf1bwW9T5YOpX/MKeEEQtRpa/jdSDxu+AX8is7t/3fahLGfDrYkE2+c7xA== sig=+eGy59SyfA+cCGGts3HncYObXw8TKRWAwtoJMJihvuuD4IsfCvk+A0MglpNOovkFs5Nwx9vd9ZGAgAPFw295rDZEe88J0rdBX56B4Ij0M8rLvPbMzckxTAj1T5bjlX7IVcrRVSfTowrPYJnFrVFzyyIA e=found last=17 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoALU4ac9qvd3gCuqEqUWWAtPxgHPNwaccjFfYQWsPBoTxYrE5IO7fxnjWppLzhkprZKR/7JxYerjMA priv=MEcCAQAwBQYDK2VxBDsEOX/RdjO0bA6PThA5jh/v4tLWQEOzQwJt5LnIj/gzeIjNK2ECGfpagpeDuKOGVIwhYMMqOPu4IYmXDQ== msg=WoKXg7ijhlSMIWDDKjj7uCGJlw1Zs12CtlUrXzyRFEGXbhL6IwAB0WbvmZGV69mg98aGgeMRqw7c0Hsc0JsNYA== sig=kDkdymXzLObaifMvoRibHgvV+Jp3CMltTFGIWPYrL7e4VXkjlcZF7HO5Whw0dRTtZF/XiKrIh9wAlb3Bk3uNKqqW9ry8RCA/d9rNuxcaxDt7o176mHVvvRQSZEVaEfCGPhp/M49c1xuckQ/Ul6HSnBUA e=found last=22 s=12 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoABdQpNaBFy+v3sR2HpBVRyY4pFsdskBBMcSU/j5iw2+/9ha4xQ1dZUpQhglK+X9dFC6vOzb+SzWCA priv=MEcCAQAwBQYDK2VxBDsEOa3KNeHqlbyHsAPkwIT6j4tMLGZbxy/NPvDabTK/c05V3SUtlmG4HSaYYU4NQdTvhi7Z3jHqjb0tVw== msg=5MCE+o+LTCxmW8cvzT7w2m0yv3NOVd0lLZZhuB0mmGFODUHU74Yu2d4x6o29LVcUYwGml9clDjUgzrd5ctwe0Q== sig=f8AP85ii6Ay1GOB8v4pGCTObJOuwiusHqbc2aJKL6Lsy/c3RbVZfV8nE9ibFIUMhAgWSEGGFfmcAfDhY4rU0yilSDnJaURg1W/DZGN5hhZXVwY4Pmnf6SbDEJdCiKESyM63JPvyQVwAdtybwA2/m/SIA e=found last=24 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAU5g2qVY7uZBcneSxXwedI6xb/h3B38AyA1MwauqS1vHaDETsZlrWrEzgFehPL+lqMH9BvpNTQ3YA priv=MEcCAQAwBQYDK2VxBDsEObLxE3aPPtGC6lt85HWIWwKVUMjnmLoCplvrEMcBu6poNeXWABzbGIQG9F2HsP10u9w3Hcp9dK7s7Q== msg=AqZb6xDHAbuqaDXl1gAc2xiEBvRdh7D9dLvcNx3KfXSu7O2kMxgNyCHmb4Y9nOn9CJYFYZ77wfXet+YZPvKwRA== sig=+crglZL5KEpkLWGXCPhlpkNJXgDATDec/nZenZ5S5e7IgQiF3HovCO6I86GMypqA9xC/dETdQ52ADavyU3hGqo0/4rG92OqCa2798y6wgfcc5j96vWgSWKqy6QQKWf/tAEHoB3RgtfLY10qF/tv9bTEA e=found last=23 s=13 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoADUxtj1TRyoKHXGnYkDAwR/tfnt17yaqVfhZ61VEgvHBS5JI53FCmvTTmtymIMawAl5euckJrXRAA priv=MEcCAQAwBQYDK2VxBDsEOcr5ICWImvgL96pNXBoj6U8fO5M7pIoaadV7zd9furXslpOSrHgfbSsjyMoWA5x9h2D07Ry+DULC+w== msg=KyPIyhYDnH2HYPTtHL4NQsL7VlNwg4Py+JSPfJN/cDVtUvug06VCNEOUepSZJ2TkV+V87dlYhk92S+Px3tJ3eA== sig=/hqpnxhi2qvoNT+FMzfuoSt+H/6hjQfDcwFy90E19iWkT4gTA2L8Lh54CaQZFK0gqYROioK7w5aAK656Z4KIfLj+5liBluzkfjCJzVj3VLRPdHRuxhQddhNdqvLhVgYxuQrpe7TTkNPh51hMtbgn9CgA e=found last=26 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA1dqnPlIm94g/qG5LCUehYpxlSC7OCmNfXMLTxBfxUzPjpxf2fgreaqssSSQP3+x9SGCqHwyqQVUA priv=MEcCAQAwBQYDK2VxBDsEOc5NrVT5IkR0gTg8hDQRmVSvXE2pT1qPyMEvGGI8EoXldXtzsrDbu7FyVvwWTq6n0Dg6Rzsb7Fyi9w== msg=c7Kw27uxclb8Fk6up9A4Okc7G+xcovdhrAdELX5sfU4eVmyJlbWOGYNfd9bYVBruNdHAQFll8C1pMJn64Hc27w== sig=1qqi9wiX49R0U69FP07i1WilMWPPxt/fuRSaysJUYebwV4auluFDRVB+qq9TaY9n1DIsbcA9O3cAXmSRgGxxPpo9M8XmtDvjZJBUzpQ8q6pI+YDrB/Zdu3iZttVLxk0yP1jTv+bWMryu9y7VBwHZkCcA e=found last=14 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAsSdNKBjAhaMYJb5GTJxFvu9RNZuVdognxP/3QqXaOjyEFDJkkDvJ2FBRA+RspsGbh/UhkkRAdFIA priv=MEcCAQAwBQYDK2VxBDsEOfwofgl9vsCAf2xsTHYhX6p5lTlOfi2wUDJVMkMCB8vGgqi50szqnUyZwAwGFqIKvbIunteaddA97A== msg=xoKoudLM6p1MmcAMBhaiCr2yLp7XmnXQPezxaMWtoBRv6hws5q/bc+eKBkl4CiWCyVnb0hcQ39r1ks0E47tdcw== sig=jH2Uy3cneYaOGabmlISkHWA3VReB3oxSeFZuIHscxyXG83mVnP2xlIwesWzMxX1ubznI1GAhQYcAkG5zC2IRrFUxmiv7snwxe4kzbCKROYWI5nFmO40m9J0SYo3je+CDUb3+6FEHjyDabJuZ7N/h3SgA e=found last=26 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoANwPAQ7w4MaWd8bBki8O/S9QMl28sIALYDYvHHVtMVSWFLomCEwE5S6fKcJl5rxN/pmCP/oai18aA priv=MEcCAQAwBQYDK2VxBDsEOaHiUi7U32ngUf6najNMtEfR0lhFFVgkBNZjA2AtaWulzNKow65s4w2j8ehzDysuS/xTNwUkL9uSYA== msg=NwUkL9uSYFiD6CelD988TXmoatiFTVhBQTcP37LBQviy7/3cLpCq6pn+34kTveKJjQ2q2Xz5Ost9sH1WIxpxiA== sig=CM51cPO08TbjNoQVjW+iSC7iM7qMpkpJFdaMs787OyjEEECCoyLiMVmr367pzMHBn9L+pHu4MmcA2zpwe5vZfYk6Acp8EtjEtarF7v0rXILdq9L9PXggZ7oug1f0lKHuaSf5F0Rla1xaylfjBokzZhkA e=found 196 iterations", + "pub=MEMwBQYDK2VxAzoAvbTQokJNBGQQZsPH4PzwbCoNLsiwSEiisRkbHP+we5S4De+e0eHvgXhoeo4ZaRt8nNJ+AZ5B47AA priv=MEcCAQAwBQYDK2VxBDsEOUb4F7Kcl8c4kEA+L0DHld50wXWh5VWD4Buu9qp0iD6q4G6dEMNKwXCNKTJCSPzMc5RWHv3RFnCd8g== msg=9qp0iD6q4G6dEMNKwXCNKTJCSPzMc5RWHv3RFnCd8qjOQz5YHbsJ0COkMxMwi8RqwX53/qUkbWgWtB1kImj5vA== sig=o/QLHI3jOmRwHBp0K6Jp5UDbZoxu1/MVNHTIOOWLiUgPqb4PZ2WfkGx+NQfkEO6O38s+KYG8Vs4AVp9tomdHKnUnZMNwyP5znS2a6ptHiYhnEnJ0Sab5LWhseowjp+uOmv+3srhL+QpmqKO8I/fyGD4A e=found last=15 s=17 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAR0a7HqLhkn2ZUrUQ1WfS7zKBSliTrFDBUDrKzpS1X1S9b90el4ex+oIr7ihQmfS3OqRDnhIaWVKA priv=MEcCAQAwBQYDK2VxBDsEObsyuU5q0MBx5idLg9rLyAh+7e0+3f1aC7YVYVlxrY6auqJbazviL3PwMdQWJP7RyWnTbrDJ1oHwPw== msg=4i9z8DHUFiT+0clp026wydaB8D/Kbjncdz1GYH6a6G0g44OMJxnKi11FsmtKo0ULxf9baGT41/8zDoU/KyAIkw== sig=HqwWsgtcN/T8PSXz1HR7wzKYQmsKNpZ62UrDy5qGgbH8eQO9yY9d8oukTWs7yTk1x2G48vD/G5mAFF9ZA3rtWumGsAsIF4weOx6hRkBh/Bi1PsQY1rt5gSKXaVZ6Fd3SSMOm/2iN/9VcznuhHsUEKAQA e=found last=24 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAy+6MGha+Apl4ORjRqp4X2Bb9hz6g5f7HB9cp0pAT6JsigOUh+0gzt5WjDy4/V8ROz53flloE7aAA priv=MEcCAQAwBQYDK2VxBDsEOdaBhXxt3zN5djjIRMziwZ9a6ofQCpGlK54bKjyj1oSNjTFBe3BWQt0Y8smiEwR8og3ve/+zfKJRFQ== msg=NP8gaL96IHkcJ+EjngmEBy3o1Z/hEZIkWQ0wirsuUNAf2m8KtTjjd7QDGZWU5PSj8ojdHsVs3cWJgy2s1ElPww== sig=bnFwTO8RRAWLIIVf/7/3I1VrrgJ3StqW3z/rsVMg/+1TWRAALHoFB8iaUBlb5mG5jTapsB6A1lsA7Cp4jOMH8/tgUiPIewkNMZjL07ypJ/tgd+D0cvXP+EPV4W2gXFthQX/JB60UMvz0a2E5JoFkTgsA e=found last=18 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAl/RRvUci5pxb2LDTHOwH0M0p0LscXzLXZal9bk9lFABj+MyhCex+vqgqD0oKVnkpEVWNfk7i3DuA priv=MEcCAQAwBQYDK2VxBDsEOdjn5sfyiWZ+L/zTHvcD9Ki/aSjvQzIlpO8G9lgUv+/pVUQxPmbuqCiI5YFHlLXRq7VfvxIdhOKnuw== msg=/qUJzqmlYzMdf6ptBa5Gu8i9lvAp4zI7wz2JOk9rd8dLg/pCiKwMIGn02AJa99GTJlxp8lFE4RcR7YG3l2/6ig== sig=DcTUL5pDKqqXw3xnwtBGiiMPb1N1IXc2VaRp6dOv8odkF/Lmbnnvu3KghdcaN5qoFGYi4W1A9RyAqteIAsgJ2yuyCbv0wGGJplsmQG069lvzjKtlLoVjR43FcgNrShRTHnKGk1KwoatkZVrik/rbKDgA e=found last=20 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAddTMB4MF3nqzmvPDZiJGNbDcb/DxlG0o7Hg77MA5lhkAOmcH+/T3FV25/VeREW3tBR0ZkntTAAqA priv=MEcCAQAwBQYDK2VxBDsEOaq8F10a3hxHM1bJ8mTV1q+ESSv2gdBQRKts7Lk0k46TPb9FJcHEJY7wWnUoqkgN4aKDg5JOU4/1Mg== msg=NecLGSmvzpgXJwMp6H8yDeKAeUrOvUIGphirTEZSp9/wKaKhjt/k8pFyIuBAnX++p4EXASSAuf+Vjwm1SpIoAA== sig=W7pzo/Z4L+t2tYISGon4IP4+HbesgbBc5IjHlU4vEX74srrV02YcvJZxr5HAccnPW/aQTmXHFnwAVtBULk1KKCOH29irfQJzD3RiwGRUyvqqWOjjqbK3XCkTaQX/3vsYIlz5Em3PP695Tac2DELwlQQA e=found last=21 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAebsxPDZtSm+PFTlOZNwZtRbTCZz7rN4l8kKLxTUGPjZyEH7f9yM0VB/NKJVxAj+hsNzfuGnt9dkA priv=MEcCAQAwBQYDK2VxBDsEOURYmIOujoeIZ/sSNMcjv/IpMjtQJoU075BMaE7Z0kqTlgNkVQNZ/adpCLqDQgu9qRNT/+pOc/5pKw== msg=vvlKPizzq/2ru9wbuz5+jyD4YO18BZ6lhtkKsvV9Y5xaWHvHHtbgmpiQcXGd2gi6ASkFaJb9/wIcilP0dsYrjg== sig=o4tT1niYl5XffEH0c8HzQVJR6SWL/hGSI7bWjhKmX4FD++LAX0A3ADgjT+tJQieiDmYNdNrFEcYAQXxDqtSPGKv+SvBLkyg5JxOe8l6kvmINPwE02NDkgsX0JqFC5QvzmScvkeXcfRZ+JtudXW/QszEA e=found last=15 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAtOGRoq0dt4m6y22Qc6RicurrC8zd0JvmS2uZ6StqVvvdI5vF4udr4LsZ8GDwPEATeDhU6Gmvt44A priv=MEcCAQAwBQYDK2VxBDsEOdeTju+p6TDvKldURlDYBWN7HVv7um6f6mjNFdpN2Aer7f2hx8sh2bSpHrFCmA1tG3n/We/9WIw3LQ== msg=mpwPVw3L2LUhgDvzqNFZKQAZE7iKlXUF+rnO8ZINLHkdhaeFbxRMdae83gqwNXSuwtExHOl94Hinuei+uUNFww== sig=230cPITLCzLNp+1oEtDS5F3g8JJ2UIBW9A1Rf3/HzMS99nIazPJhyEpsAzoPVL3ijRjTVmlgb6wAVD6zeHtj0HPghBZko6VLSmglhxz3iXiyoORg/czcrcyw9cRmfdiWQdJ2LgfcytQf5+jW3ygbRiYA e=found last=22 s=18 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAfNVu3UGhG8bBA0OTNryXjTWbRsUW3L1LGSrqfccGPF7EtTHAE+d0o0eS25uilH5ooXqpbvdTai0A priv=MEcCAQAwBQYDK2VxBDsEOZ0bpKIfjrrLdibz1eBSvK5g90DZYzG9518DuyCUtWCKS1rRs3HBXO5UDIJcMLs5zjvLY+PFO2tgoQ== msg=S2YLzrh/Kn6yQu2hRuwQZAcM2yT7MocZwHcdAQ9x3tIadLugOjbICwIdVofyR9b6vHF6zhh21lyeDitFW8uDng== sig=uDnAu28xUB2HgFkMy8ZZy40UwDPe/ceLUWG+TBLeA36hLA82bx/Kp7o/a2gxHxeIYruEjGTQrUGA7Qiu/MR3zdHocvpTtLJi3u5Zphlx55/JfFxj8P6V00fngk7XmMTaZZqdOeQIFSkzDHFWA32uNh4A e=found last=21 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAP5jh1iPR4YurvXLq5gR92JhiH2EiwTPLq/u8V61Cvb6VcmZGbHA/2lMQv41RspeiD9WDikIyyCgA priv=MEcCAQAwBQYDK2VxBDsEOVSWfjwT6XWZVg6Rz434Vq1vmMol6hzuw5LPtSCIWJAR5Jd86geTQq86VrYklcaTCaYIl88+n7pa5g== msg=hfnPHmJzp8o145krrM3CXQ0N5Bfo2bBH0KXNrbxBB+DBbXEQDLhy9F4/grucnD3+ehdwEOQqBOedBFkf/SNLfw== sig=7U5YkuPb/9cxW9o2ZozyNylGVSX+a/CTuS6Wh8QuLdYNQ4kghfuwWG/bn8PXvIFp+3Yp/wvMLHCAcJZSlAWy4fbwrLBGkGgWlmH+vi/y5u6uFwNZyiKVM4g2FqVQGYHXZ4u8ws1VPiqcYHDuIuWorT8A e=found last=18 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAXQvyIAYaCL7b9E0HqZn5q69gwpTeo+S/sK7rLihFL8tkCzRpNkNB9X8l0p4zbDaK95tnxPigDYkA priv=MEcCAQAwBQYDK2VxBDsEOV98DRgR/VkirfE0GsPNPmHj0s+oGSsUvwGmQrf5ZiGZmOJeot84ypakaGluqyLJ1keUl3nO+6EHnA== msg=lTbzNlkUsinLYbwdwPXCe7PkPsiQngsBkOfu7qRIBzU0cN5BIn6Wo2lV9/qA9tOgFPs4IUXiUn+eEP+oAl++rQ== sig=1xpTi70FiFh38/iXZtRj8X7MhyWGWhrMo8TmCgfKcaJ99/KuBYYuPSanYJwXchg9hkYF7zTePrSAy2kZrX9ea7IL28PJ58qW5suc0si3+11lKACwvEra6LBZ9qArKuRUf6EkA5ng6N6QvgKsuTChlxIA e=found 139 iterations", + "pub=MEMwBQYDK2VxAzoAd6qK9efQOvhRRZXjcMpfybY+ibn29lkqeqPZjmVfV1guEiCTAaCQslwtVUOeUdJNAe83PXCeclgA priv=MEcCAQAwBQYDK2VxBDsEOWctY/WSohQPIxQ8Am3m2mFd/fCk2Fb8w0WUDicoKxMbWmS0xCfYBZR5aa9yYJpV6HxAKI3qv3/pHw== msg=PAJt5tphXf3wpNhW/MNFlA4nKCsTG1pktMQn2AWUeWmvcmCaVeh8QCiN6r9/6R/7FN8sHihQ8kuysqTlvMJNoA== sig=eZRHXKAWHxobQ9n9kyOgDdsYLKeds8P6Y8GdApu9xhGQpXqMJqLRrtpR12g5OLIjk22AqPF+xtiAjhU59pNZYrP1R/4FIGkmdG6GeKn6Qzd44Ii9v9ILd24eQ387YBCy6YesgMj7tipjuRFoL2XUpQAA e=found last=27 s=18 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA2/Mo6vDnScLhXUBJ8Jep8X5OztHvnR7+rMRnzBginUamCNN1n5U+2ckVuvWFWb4l6kQTcFoZPUCA priv=MEcCAQAwBQYDK2VxBDsEOX68CfSvUGEnxppU9BDPB8AHGljPWVxlUGjHf/OjIm0g7xswLJx7XOQiM6cEQsPRgzhaoMe3IKoqOg== msg=EM8HwAcaWM9ZXGVQaMd/86MibSDvGzAsnHtc5CIzpwRCw9GDOFqgx7cgqio6PVBL9o3r1pG3fimcOpAZC3rJhw== sig=t96YsjStpS+n9RYtFNwmrP4O4G1Z9qbkzZ5oUcbM6jfjSxArZdQKTw+9FordNs3/zVqjFvDbD5sAYsKcLsurjQYjgm2xttc75cnycWhdUSiRCps1h2g67VQd9D2/3NrBAggIl7kRHM2qGVzp9S/s2hMA e=found last=18 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAIixossF2B/qalhJYae8uVQfQE+qZtWt/S1kYiWVJ+kUjhFGTENmSAjrltq3+mfif4BFALUlwLiyA priv=MEcCAQAwBQYDK2VxBDsEOcAT6cVxO9VzKLwIA27rpCg+eKx2hXZWfm9keelZilvqYTosH0D1nBE11s+Pn8oGgdtR+/2eku0rnw== msg=rHaFdlZ+b2R56VmKW+phOiwfQPWcETXWz4+fygaB21H7/Z6S7Suf2+eQxAYGdrVJMbBtFAmaoY/j69JH/nj8Kg== sig=CyLgCcbGmztfRpB9NshB5h03OAYBlHcBQFr8DfgNV0Qzy08oN/MZ2+tvGD076jZauRbRbQH84gQAeDG8lWsVjEkg05WK3lrc/4yjbO/2pXQGxPbR7RBBsZRO4I+UEPVhpS8YkuPzK9rZzKDDReivITwA e=found last=25 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAmzrTJTzRJEM5fJj6EWyvjAkiUWc/cF3HkHsKvoiQp1JHiex2SD8sttjPO6om1HaXzY4LsHM9W4OA priv=MEcCAQAwBQYDK2VxBDsEObujMWPGXFRpv/MxNK3OiUBtG4BwZWp8R/iirhBRkFL+3SmukMaxpeHUZA06p9EvczJEZMm042WwfQ== msg=6wCeXrLj+HEA85VO1eJRrnRlk7PBBssAn5MZ751Q5J0vmEUx4NwAVSCDEeaXlpONRTpSTZH9cuJuuqUUPS8+tQ== sig=bNHAEF7EaXhct1ULE1a8oQjKO4w59dxH5R8Aopsl84kEcmRFmNiV+Sy7y9F56d7JyjrHzOsNYNKAKvB/agT8BdFLRcB+L9tANBknZO1waUl4BaQehBbTQUyZykT53Q0nI5wyiyOc+LbY46VnBWKlyRYA e=found last=21 s=13 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAuXYHzSTBYkoMNXBiRax4KKMt/dgHoXUJLVOFBsz82Cnqlbw7UjYrT2Bai3GteELFXJqyR+uCUisA priv=MEcCAQAwBQYDK2VxBDsEOYavSoAdv6/NYwtDRfMS8E7BgEyICVw4bvh8DFy7gqGfGiRS44sZNtSpk4DDKLUrcE1U/JvkivIBag== msg=bvh8DFy7gqGfGiRS44sZNtSpk4DDKLUrcE1U/JvkivIBasPOlx6CnVb88L76H7lteQh7mTrclkxTOF8dt7CA3g== sig=POCrv98Z3INCB6Fs6wEkvk3QSZ2Ux1qvFkJhlG1lw9j7GnxkVlersPW1P3KcdyLHkFPUoixMSWiACgyRI4GfPP4C0c/w6es4m7mdDmbadeYRynrLje1j8N/oNOgv03Y1qF4FiljwGjmbByuVUDwYyxEA e=found last=20 s=17 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAwiySk6/6i/6R7WhKj/jEduU4dQBoqJ9gVsjeBQYZcn52xyhZtMPCNOO2YQz+JMkzHrv9B/dytYWA priv=MEcCAQAwBQYDK2VxBDsEOR4E9tDjtQT7hv0UPw7Xu2agYip8talC8yDkWmOnLbEFPagtDGatGcPFTxca+osWqUsLgyOURcj2XQ== msg=SwuDI5RFyPZd3HLC4cFVhVAmBAGLob8wD9zYB3tHamOmHm5cdbdLgd4WNOxKQfPM5LjEhUft1N9GGn0QvIYe9A== sig=4FOaKaG/ABgUNxLFIPKGfCiafQLvKL9ed4pRmDgBUMuKKTDj0iIahNQZTn2psxvlqS7NOJiVjLUAe1f3UFZU9grALDksqRBTc0QjTHyfABusBaU6o0weO/qwm3rv6C1qY0tmDLekUIghoWBioY4S0zsA e=found last=15 s=17 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoADBlDPlSAPJ6NVUvVcNeyL/ccYOjEPWD486ffljDRiXcFUKVxI/c1PP+JWtRWFkRvzdnepCDI/0AA priv=MEcCAQAwBQYDK2VxBDsEOdKRltXJ9FnO6KEujmUonK5eZn2NTiVFMp6rMU6M9Bf9jbKVweQCb5oGsiPeGbtZqa3D8l0HLgjIXw== msg=gfiwzfFahcMjv2q/88ndw20XCB35FicYMkfmAUK0AxLmHXp314MtssuJ2kSN9vU5tKTUWu3U+16Tx/fIOCNNzA== sig=m10YjVuegsKY5rBVxukK/yuQoRN+ZmjNNcwwreVKhY2kzy010nZIevjNl93ebVAuzq37uuG+qKaAHGNsWDUWBjJbMFTz1acQ8aKUoQoVrtw9ryJujlPOaGLPcXx01fuPM54poJ4WtT8D4s8ThAId4wYA e=found last=23 s=17 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAFiWxT9vwRe0dsSKEpcm2qZJ5tKutcer4ckVgNbNf31Kxi3Ao2mYXQmUurZ7r5efDQHJEEsSuhfcA priv=MEcCAQAwBQYDK2VxBDsEOU4BdCdv9jx0Y20mxyfsU8/3BGbhOBKQXsVWz1+bbJtRt6vpvSxSDIoLkto9qevNHY+Ki+dhdRRTAw== msg=dKM2heQzEuNPPzKpw0hOvdthaqJOVqRxG3LK4tJ5iUNZvW3F+dmFdl0phsxDWsOjn1TZx2ybBCcza2pgE024Fw== sig=G/7BbTHE80ItOkGbkHHdbZFVGYtMG7+Pl8r6hvZVvV+h50R8ZMtNYCsLP22ltZayMel+CPWkMq+A6yO02HFCnHXNITwOcbWCMiWy7k5ub18kvsqCBMx1aJU5N3vQe/StcrR8rzb8R/XXiSPslbdfrysA e=found last=21 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA0Tj+oJvlTKbVakc6D1qNCOHrW5sO5nh2HFv+ZUEzLIkbeybzR3rve5d+8/qwIca6W+PHO+Mz+4aA priv=MEcCAQAwBQYDK2VxBDsEOY67ckFfdjENnrU9izV7XQNhlJIBGR1GEJjlxh3bReHiRpwdPRDL3YkytzkxsUiO6dir0l6OREc0Ew== msg=CBCNYMWKB04K86Ml5999yusb/NE1wmRwjItUJ7peJ+VST4D00EJGQgxP/0Xjfk43xM8FHJuaxVsfIvzTaRQN1A== sig=0HaCr3Vdv89HG23VESZmfY2kEtOI65NjaBdCEdolXvvPZ+2Kom+TEpaHoDOQ1//8WpLsta+81OUAXxIAIWWH2hrXeaP2FnC/zr4eAhKfMhSUc8BceFqojOkMJW11er5ekE8BK9n8cOHbG/CpCDUsySYA e=found last=19 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAA0hVqR/FtKm1e6XKeqe6F6y3DL2tjyoZRCMFgUg4/7jsqmtiko5a3bmZM421sFumGib3b/NBwQ8A priv=MEcCAQAwBQYDK2VxBDsEOUD5SnJdpgOxTJQokBmLcA91UrkWHn0ImG6kGKz5YADUGfMK094MRo5ZNUmtnq5dqRlFd0dalIsaaA== msg=1FLjBDMOCH4Vd1BjYnokY0BM+e0froAz9AJn6EkSxV5x7u02GWS7Yyjvm+8zNruNERHXDKg831azeJWLaOdXdQ== sig=FBWJ5G8zR6TavwuOCN5Md/43LQ/z2PuCj40K078S+VkuhCwh0mZHCizeEPJaHPKGy6NHHZFf9NKAg74KM/GuaZB72/KSVYGzbxrz+IeKhJQjbt8MxU6eGlp3IJeedfV3lkjpx0quhB3gwSyvywS+zw8A e=found last=26 s=19 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAy17BsJSEoU5e9UbucUelU/I3iag/kvaOeXje7nG3WjP6frWJuDldlzphqWm8LX5H+jCGBIDuPNOA priv=MEcCAQAwBQYDK2VxBDsEOcuG8TW0ALH/G8DDkvCdN3CMr2ZFzbD+LirGqq20ZcEKVBBP0lJQVpOkIfzKznvCfAxXbus2P7dBHw== msg=OL5kFIgT4ZpNjHtzNw2m1erA06AZJ4WUhBviLjhPWmBMWky1Fe7lTjEAk5oGNPHFqZ/eDxA/+RgTemFuoVtIpQ== sig=iqk8H44pw1MztBZfUfB8jAzJL8rBKqsJ9FAx61kPYZrQr1RB3lYB5KZRQOfCQLRuX2cO1go+MbkA+8qDWwbdMicJ9fO6UGerS052cTpCzMZJdPgMia4o9pCVte+l8plcjUZ9MurzQFvHGIlO1c7IzxgA e=found 197 iterations", + "pub=MEMwBQYDK2VxAzoArkeOHPx4f8g70cI1Dfg4kRNbeJ4aODbtT+BxE2j/hbwI5B4OMKKmbLxdFh1ZXS10dOif50iQldoA priv=MEcCAQAwBQYDK2VxBDsEOY2dxhr9wmAYiQNKSKSO9dDt5G2q7slYUTUftvIB0sQO++CNnbKMGF2JnHbKa+Sjd7kwaiI5kg7Qhw== msg=tu1xa9JEMrUm1EQ/elykeXmawbrESI3qo9PdOpxoRPtCZffbUIMwHkEvWgJTbKJu19ADsYuEYqlrjEHNAKKfeg== sig=DkTVGmkR6eiU1eh5ZwG4N9K7ApjjAktneoi8zNTX+Sm4sR5ewZgiPUcyDEZnziA7Z3d3bHeVmOqAfHoh+ytgS7b4jqB7C21eOiMZNWnrBvI6wXkoutZRZ8UWww2HrWVktWEQSArvecb4wt1tQVo3gjIA e=found last=19 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA7C8t8qFjmKXd/CDmLChpSn8zVbOEFZOUCl5faTRu8dGioW7Lu9CQuUQymsgDXJd94tIbyMEemOqA priv=MEcCAQAwBQYDK2VxBDsEOevAU9r2IZfS55cshmACn/BiB902jHoQAfA5b1B8li3qSTneTuOFOIGGQJt0yQifTACBrrEA5RZtcA== msg=NpDCnhYnuhdu6lItU4ob1/IEw2NAkF3uzIC4SAf797Y4aaNnQg02scBJ5A0W4kRWPuuT0trxou3Ymg7w/WShDQ== sig=z1u0+P/gYiBZxmkwyzndF9AYFOgHJIQjdC36vhPiRt+re4VVQCk9Glyi4xErTPulnwvPuMSU0C+AxNjf6Qig3vd1RIGbeQhksfsBiYm5s/XlAF1QNGRKu1JCFO50LUDK21tZ+96HrhVQmzwW037vHCMA e=found last=24 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA13wi+s8vDqdSaM6FB2QeTjz2Btc6iRZ/T1NMAecbLPHdS50xPGRGKmKqP+lAh3gTLL7pkt700vQA priv=MEcCAQAwBQYDK2VxBDsEOZnc7DNyB4uyEx6FveC6AYxdxZ+fn4jiyfg7VmNYlGsQmI5fJjYISj2O7ni6tGS8CO4h15ga4hvn+w== msg=3qU5+vHHcTCcNYbEdHBNehlsPWuvfH60oZQbf/mQZw2mBFNjqooPtVjh7m1dLQltUU4Z1SoygFTk2zp1Teka3w== sig=U8i5PNc1lhCZ/LiLZmf5ZFHtvrFtcuZi8gs7eecJMd9LmDMHNtf5NgEAPAjy9taB8/B5T5KI8T4AF0LEGaIJz3VRM9bojrKvbTieeNTAq/9rFAW5hKxuDHAsB9nRCreM9Flx14U4+pKQNlYAC5c1MzkA e=found last=16 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAeHGbL/6XryRIQK0V5tq0Nq7la8Ob4zXaE78FJGbx/HiPdO+fGLxNgGXHDCDmFpai2vVOsZGtbUmA priv=MEcCAQAwBQYDK2VxBDsEOYKECUi69XkqPjU+jAORmKsLVccbOx6lT3SPxCXrNJTOV22JCHB8Pjtwom3HJZdnJ7h0srGLwXAYlw== msg=e1awEhONPnXybUkqEUu29ia163IWta0icUu0YF1eGrQecVJagsSjXlxLRlynaDnYmTfMOPy8acQ7I8jlm4Sc1g== sig=hGmryIw+PLlqVB9RvTzGSpCQe9O2M27VzhOmXqxItAcLEVVj14qaoCcqr1TGPd63lgm1MG6E3+IAQD0gMjRvYr1e5foIywDA3X9X9xGmciPQp1TljY3u4K/rogYSp+GvT1KThvEvzk0KLc6VPJCZaz0A e=found last=16 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoASUyzE0ly4onebmAa+7pcV5/GKNVeH9DHJ/UXg0OBCfpqjKpb7+CijMF27XxPgeqhRASJ4UHtoUWA priv=MEcCAQAwBQYDK2VxBDsEORQyeHcY/FV8EEll13fBREFHCUn5up7ByxUHPBtq4YKh4lygXXtluG5IX+bVHNhg4fcq7ne/n69QqQ== msg=HuXSIdfPX5FWe6nEwxlCCO2ZRLSg+37fJiOs1J+Xvsls3v+hEwTZ+W69+TlUQW17XeQ33G6Aryq/GC+x/Sg7Jw== sig=7qkxE9GOqr2xnYhFDHBefT2nDmSQ05FselP8IrzH2VrZ5xv+upzCP00Y/5nTXO9kq5lzq8f0hRkA0H1by+SKaQ585QWcOS0iiU2msKK0Y02fpE9mfQMPzAuL03830Ju3NmcgVSNCdTLKLJeq723TRD4A e=found last=24 s=17 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoABDxrqI1b9BNHk5OM6TPSU0mI7qlxYXGsHOEggTSvirnvpTb+2O+FaXjVt1kQvbKFrMizki3aAPUA priv=MEcCAQAwBQYDK2VxBDsEOXmOR3wyRpqlp72kTqdIlm0YGRXY+GBUZzH6w0VRMKTB6xTbHhAF+Qugi0EMoiWZQ7kiCE4c+3DDrg== msg=U9tD8lPndycQ2Jy0FQN7vyEgx++qASpCk2VaVgOMVLWT858WHX4v4TpGdG7rf3LMA68B+GFP1DBxOreokHzMUQ== sig=WauD77qAkwnYzsSf/yy4uRIPl990uuQqUP7gd3yIN4UldDuyhSs2azNWoh8FJyNOjkSLnjtDjE4AUzAs8LM6oFEOgqmtz7j4ta27/5Q4jAxAS0LWUIY2oRUnii7ynFL7jCN5/qXbiV9qos3ju72e2TwA e=found last=23 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA6i7ID1VaR9MFT8oNHCajn37A6JwXIwnLe+QMrmcWQk/vX5fxUXrIsi1f0kwfB3ij59LdnBDFQrEA priv=MEcCAQAwBQYDK2VxBDsEObkzcScEpzYWxRZP744a+R/xjIKzd5/qiW3RhExuLct2TTzJV3XnpcsCFNGxEeL5J6DEtRvnSbaG4w== msg=uAY5nh2yDthpJ2MhRPjXTIu2ZJeH6J3nPKKvhPmQUwYFr9GPmCn6ZgtF5HBeFXShLzg7PRKucTXATAhgfBMqCQ== sig=J6NjwOM4l1QuYnTLCDTyewAb2PczV7Nx4N4l9XE7Rtk/JZDAz6vGKV5vUvjJJSp9eQ/EMzGaD3aA3am7dhyFdtRfuNikc7k052DJiKAkFnrZUDNB227QfEEjLhLz7pdEeAP8JZN1yjdK+/t0/Gfx2TEA e=found last=17 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAPITU3r7adV1SbBddZBvT+LMSJB40hmwGMfdzR3Ul/+gTJRza1hOD+Wikx6Ql5QXPvLaOhMImCEkA priv=MEcCAQAwBQYDK2VxBDsEOf4NuIvbEqkTybGqJYPxHQh40aIeiVU0ibJIesUS/A73TV4ttjOSfnPvbUzMpIlfnhv/nQD0qGTfew== msg=i9sSqRPJsaolg/EdCHjRoh6JVTSJskh6xRL8DvdNXi22M5J+c+9tTMykiV+eG/+dAPSoZN972MMyIffBizG7DA== sig=12sJLr2HcqHKj/qreOSMqjyq6J47IddcoZv2DKjYCeYCQv5EUJQhPbZS7dVoWXiZhZ7lHt3OwaGAsn18454FvNXixHOHCzEsSV0qRP2DAfSQ/Zm/b6jE0I74YDF2X04LIeWKqqkllwoIiYkX6JqL2jUA e=found last=17 s=19 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAqhjFKsWeZneFKaSU6NpiYZOPuEqwTu2FkTzjfunbSDrXhOOFI//I5WpqYnvdXcwJjtA5YI/CmJcA priv=MEcCAQAwBQYDK2VxBDsEOV3r9F6INgk1RCHiV++u/l9/KcLUdZViIooe3H1XG+6B3KLDPeUXdJS1SGrn+0gbvXCxxUmhTCLCyQ== msg=Xev0Xog2CTVEIeJX767+X38pwtR1lWIiih7cfVcb7oHcosM95Rd0lLVIauf7SBu9cLHFSaFMIsLJn6TDDQPB8A== sig=bdRtZd49KMNh8Jwm6DcCT1d4Nww89eyl+daMjEuxvfZpTe2ZTNLMQYZq1glkdJQcqueXK/bwUSmAtyMtqDCTSY8lRYXQnSD8laSd59RDfcvXSTWzp+y9MOBPSnd2MfZ7KXEldt2FXUwtnn51lFzVLC8A e=found last=20 s=19 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAdUh2Jqi5QX3FmRBXJlx7AvY+wVX0KPnmzk+GqbdivS4nBbNIyCEag5tsA8JTmqXqlC1HKteJaSAA priv=MEcCAQAwBQYDK2VxBDsEOV9yQNIus0KFzwlWMHnn05tQSmNpQoRv1/s7NSV0iYVZi+r068KjRtae93PVtQ+GYSMLb1JegvAZaA== msg=ubNgj1dhMPeE2+nWtnrvhf7+onM7HlzaVJwmr+6gB2bHF3JJrQx8R2ScV9SjJaZeRPSa9iRpD4N96rvw8m011Q== sig=ryE/MKoEXt6xSf5AbMlLKumXNlez9eUU1dPHlRPOo5g3riHuKC3F+2lCL1tRUsipYZvPXDaNs98AY23+lrLTRG2yhRi5mDe6LX1bV7NeaYnFUA7N2IMxqg6JB62tiNz/3mTLYONwuu8f06s/5GfJ0z8A e=found last=23 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAmtwJ66XmHnBnHdZhn41VE1gnOG5smosQ0qgODkB+x9gJNAiAtm3EKvMEO9ILlkJFYyCxV/REFRSA priv=MEcCAQAwBQYDK2VxBDsEOYxkRqcG+1yqiK/uZEVgHqClOuT4O9lrUv+ixdRLmDrScBy65TU7llhQrvUWaotuf4npXjYO4LHEVQ== msg=2WtS/6LF1EuYOtJwHLrlNTuWWFCu9RZqi25/ieleNg7gscRV9HIbNSRZxEwnOAEt+T+u0yjSxlEjYcs6Rl4QIQ== sig=wvoZgmqwaeH/cynIoTafPdtnogdfCf1IZwm9iF2aC/FfadFi6trHLUct2j/sbCXrrEjewSIMg/uAhffGHdqLPY5+6GxGVMWKSFb7BfBZuPi1+gykCh8S4LVWy9hZ/TY+YcjDXBJN7AxVa0F+qlPT5jsA e=found last=22 s=20 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA4DX3nkDB4clZTvLWp00jiLRNeDXC7pY9Dqs9yw3Zuu+ABUoR6ZmhJPUSkVG/+bEMCrLjiILCFhqA priv=MEcCAQAwBQYDK2VxBDsEOWZoilnd+ilFhiRof5Z4PFtTSi33vmAYjbW9JcRdWhFI7Utrdob9sDxXfRV/oEuVus++IPLzor/wVw== msg=0aFm3FbAXggjGhiz8hs3t7iySZgfwCI4sKoLhK7bIQcpj/Cu6UBFbHXDHQPRZTcOovyq0YzBDo4BSJP3eCIgtw== sig=Kvyx3MqjBBAIcym0Vfg92BMciY0SQPeRCk3L0QHUGYF4qO9UnQoKjBCPsMMxkdCYDqqGFjXCIj2APx1FiBqKwcxddRvl9yUSOoZPIQ3C2NRg5KSIw6hDP6r5hsUI+4xcA3xcX6wbGnMHwlNWRGOeXBEA e=found last=25 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAKbm0p25KiqzogVuNWjCyfyeJhHr4Dd9P4O7U80o3AozmpfHIq7LX0PyM6NoBAjS5TZofH8RXHHKA priv=MEcCAQAwBQYDK2VxBDsEOZYfUjkQAYvVmk7Rx3iouewZB6kJcvhFkqFPCop4XkQveVY5Q9WAUCpOV/x1ZqS035I6z1SOxFSSxA== msg=vIijMflAyGJrOhgtCfcMzTr+VP4Xj1JmcnyClD72HiVT4D77rWZFzjc5xc0aPJIr3Ga3XW84EuD5BfKaGM6vDw== sig=r+GOG32Z4YloqoUdINeOWEPFxgfJhWg9/6sOXsPuFgT68tN034y6P2rYhPoXSedSV12M2hO4BY4AfqmVZfe7Y92iLlVGKjvKJPiv4g5XAQw0lDYBfOz47R0FAIw/UI6DwOL6awuM4cYn0aV9o5a0bSgA e=found last=23 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAwLkOFEWZ6b90SzCLm+Yq2TvXsK4ZsRRHduRUeMnqxBsoiKrNSk1cjpqvnEkrV6jyKyjSpHarz0gA priv=MEcCAQAwBQYDK2VxBDsEOW5ExwKB5MOSKK3scqhnY9CZsmvDk9ebQTrOXWg1q6+ALv5LqHXOcLuP5fjlmzoUZ9t6UWGZ2akXSA== msg=EFUKIv0bYtJPbtYcLsNLFjGjCwmYppoIP1m3qwRXPtbZ30QxcVlokMjZLh3tI5syqSY5Kj3HsV/g1EOEPkVqUw== sig=aLJYStJj6HemGZhKXO+8P+mKcu19o6AqMP0uK+UQOj2A6cF5Yi/A90a5uewD3+T68Vpa8Few3M0ATz7DZO2YizhN9iEVTcIime29MaVcjWIGb5shTXC/l6SpNNQweduS01o2YLtnmCZc5JvYDY6hzDYA e=found last=17 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAt4hC6xIRne2Z4Oo3wl5FLfsAPi5nIGIQXtfmWQDP1XgAVrezJBXOZOisBgvNMx3IebW6RF0UYcoA priv=MEcCAQAwBQYDK2VxBDsEOQWgsY65l1EoT7JHRWFIQwe8WbYFFdIaShXqeNC5mDULQ7ROcm7IZHFLDVpNDGlkV5lTDCqvsTD6PQ== msg=oLGOuZdRKE+yR0VhSEMHvFm2BRXSGkoV6njQuZg1C0O0TnJuyGRxSw1aTQxpZFeZUwwqr7Ew+j1JLxokpnA9gw== sig=hVpDFmSRZeurISKBfs5amkKUApQW9E2LQG0nPjetWIxfRba72L1D/tLdU8joqcP4b2cahseNmuSAeR0mY4H4Uzt62uETOe4RX43GfUliz533tSZSvXEBc1HPe+qz9XRO8z+mXuqMs0IqDkG+ycA3axYA e=found last=15 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA2ulu4yGBgXZCv0daOB9+delqCVkuKVw+j7NGoGP1MoQ1xEFCk7nRdwY3v3HDUA3CEbRlbYbV9ysA priv=MEcCAQAwBQYDK2VxBDsEOdhZqCd/P8EexFzhOnzHIfA06kNMwNXhT2CxGjgYNHgCkSO5WcBXHyp2+nDiwpMdrPcYqLWukKKVkg== msg=lZJzT/j8HgSZlr6ihX+Gv5Kk2F73Rb+WeSR7zJ2sh2pBzRWvyZe6eOBkAyabBH4RkMwg9aSzrzoF6mwzCv7oSg== sig=mfb/E9IBzc4C/5F6LFVwjSTkp0PmvLRmPrkdp1mJb58kbSdhuc/Xa1O73/dObJS/5qn07DVGG38Ar8f45o+DkJ9xTezOgcjJ2FZjUgHLM4jhtvy+MqBskNDqhTumcHZpCHP7b6dhCTsQQ8Dm4mO6SyAA e=found last=19 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAX+6fCYCJi78BIg1ajt+wICqO3TOugAfBrdL2BsIvyHEl/qvmEGsyFyvy6mr4hu//jYbsivvBQ7wA priv=MEcCAQAwBQYDK2VxBDsEOYTd3bYhyPRSdv+93LRptr67KIcdQPH7dHiQ9IHYR4OkGyHgFxNP0p2nNa5wmOqJUpaPn3wxcoAjlw== msg=Hp90mt0B+yHKQiNFq0cHPaWGqg2fz0OJBZzvsbAYDJeIkEEEp4CT+WfrVaxfXBCgQlvDB2631YhQyGzzr/P72g== sig=xYlhHUXRxenfGL3kdQ7N4xeQpTafxtYg+nAWhChDoVQA6evYiP+ijJGDRwY3nkr13MhNTR+rpRKAcC+rk9130qI+oAn9LLtV/GMItVde0LubnpoOqNwRf3xsAy//LSEci+dNn7e6VyEUGB0JJCcZ2x8A e=found last=23 s=20 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoATYgEH5gt9MVjbcwpPhXs+7lovgvwwVWZUz826wH+Gk3HKLdyNlECHs216Yxx1ZFTo75PuT5Pf92A priv=MEcCAQAwBQYDK2VxBDsEOePRdQRdgj9HSBNUc0ZYQ5oL7Y0nESwqdi87Y/gI5u4ttznjx1d/1b8k9kdeTRtnyjiSUl64iIxN3A== msg=RHcsTE5o+75CIH0qXKeuxf/9iVyojmEsf0yfZhcsDw6tIgvfSRhGmmWjjQ1XSL+ZwTDz6gNz5lp2lAd75F2v3w== sig=1NnYeM0E7KAds+ishyjf6BU4zdfyc2nekOhpjKDxZD6Mz7hXpE27dT8zCscQZr6H3vBmHKBO/scAfZgWkP3rJe1iMAMoAf9w7UmkldKgIpTfsrLp+YUHWnxXJNPxSEnQa8K3iSk+caB9tacoVU2WqTcA e=found last=18 s=18 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAxatQ0QyKzBjZZ1DGrRBAefkK0/V1+Vc4cXkgwGyhmihT1dOL6gs6m5Ze2SwwWqBHxJHee6qG81QA priv=MEcCAQAwBQYDK2VxBDsEOYdyo00k4K9aiIcyf49G/uGUOAt4L58dqAcJmyhxqXtO0h+eA163nFslTS/Att8EkNLPpR18SWhRFQ== msg=GwxuS3ovxbUQGK3TybTLt/CU8guTyuSpUKCXopa6zZW8YJsaSSj2ZygAKKP5I+iWA+g8zGhvY8DXxAVCg4/uBw== sig=/mnpuApfV7chcSuO/9+nIWBTXnXlbiM3Yp4pXhEZ7CnQgmeakQxYBgqAxvMksbHKi7d6raB2/zMAYFDnFeYp0CRxApAiFY9OKzrMrx2iAqRWCmHqqn5ZBNEXYn9bIkF5U3cHeD80/RMAcadv9vE4DToA e=found last=20 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA+uoR/QF+zdPwCbUOoUHsXnFnsrLZ74S8jKZVV5crpWJsku+LMOo1fuNRaErJPHdCNmxjE6P94lOA priv=MEcCAQAwBQYDK2VxBDsEOTAVIx6A99mNm4M7idUzC2JDZvGAdusXmQ3HW/s5SOkSchdTMPWZEkTM+Rwi24+rq+Tyd4Uyg5B47Q== msg=vWQcd+hWku+lEpo/tgAbUaQL4D1pchL8bmRXpaJ2pijqRluWiDOuc1W5z42I2dJAArUD14dsjZ/AOap8KDwiGg== sig=DyY+JHiXcSETy0dV5OWfE+vRo5EU+FC48B8UzgQp7sm5D6jhLS5jeXcAreeinkU96YpbaPu43AUA1tedLdAXvsszQmYWWas1h8snUJQki3vzwnLok85i7UxSMMSdQ4FqKohjYJ8LXXS5/GVDdEkkVS0A e=found last=26 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA4RGy+g6xdmzJPq5GPxw6+Ex7KwOX/vJtf7DdVy5XaXN51YHNkLqtnxOrkvSfsbKfRcAsynAYzCCA priv=MEcCAQAwBQYDK2VxBDsEOYWrgZmoGvYAQ3Q+imjMfBv1ClIl+Nb2S1B1tPUAxOyZMxtnslTE8ohpP0XzLJPrJmA8Bv1QPkeCig== msg=b6W95dzW+cYTZ/PgEbFNEK3p3YO7juZgKz5tuBDIZG/hZS7h2OijADWnX6go5Vwa/SDZT8gTsaPywsNRaun2Yw== sig=9GaDwHaNr2AnDiReINCpscY8sjkModKzOHkErPkCZGeMciQlPOiBoVFuHk6upJ6RlXE18+tnwYkAtuCEZxkE9TgYHPV6BnmD6AtpOtM/xoDF30nHbTJmaexRAsiyux2YfIh2uCtvVsBHhXh16dTc2jQA e=found last=16 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAZ1u4LZYOnoFFLb5L8dlBx9fCU5tBjCdyvbcMvkh/FUU5zcZ3DpTO/z7NtZQM/OEk7SsNIn9qYa2A priv=MEcCAQAwBQYDK2VxBDsEOVvvwSoI2hLliZ1OH9g+/8pKA8bG4mcdL7I+6NvwJNLeKUgetc0akwmvmVK9lGrf63feYjGb03Oqcg== msg=x+ZSg4pnYAwfaiosNycKlg6zyOidD9IxbbB5n4u/08QbY6WOJDi8HhMn/fUGJfz0DaEGg3OkVXS5L5xaaIspAg== sig=OmJLI4aNUdmeyop7H67otNH5Y4cJkhzyo3LT0BnBxljlnKM+f0M5NRxpyPZSNsgjzQLPKOF4PBWAy1OAI1wwsO+HX0j8/75zuga4SD07K9yFJScQZF7k0KCy8KRcjOKHBE1lVHA3ReEIQBvJA5yIzAoA e=found last=18 s=17 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA8DOyPHj3jHAkKVIMBvGvS3TMnOErLg4NJgnKRD8amQdB7wyUezPdp+EF1YMOA19UX/WJ9IubENkA priv=MEcCAQAwBQYDK2VxBDsEOdo85gQoay2rpL+C4TGB6RNYNthV4AraTWwwgHAmnwXob9KfE1mCj/8f/htHUUkT7K9Cj951S+6D/Q== msg=j9NJ4I1Cw+aWFeG07AILG7rtdG1Z6+05receKd7djn84X2m4TGUmJjrLcQ0DGz+EOZHWdjJZs2nYRnXjx1brAg== sig=E96zbmnskynKViPPdrm+xuup2kWRVCj/Na0T0NYqCN4TmauesE1nPe4efdssnCE024ASMxhqvneAKz623x+uTiaAGCiCBMXGqYxCERK4si2MtTU1hSTxd7q2EnOD3D+QtR4YkYFMBzw63xzr34J3vBcA e=found last=24 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAKJUennqR2Y1ZwfjzPhDepUjgyQ/dFB0J1DT3gqsD6VC+M/h3i73tSwwBJ/yyp6nuzYNYi0ydjZcA priv=MEcCAQAwBQYDK2VxBDsEOURVPXQptkHmNkVG+G3lX3vhygEo0M7Y5k8b1WWhdsdaMQxLPtDORh0C3xXky/8H+NPcAFhBcvub6Q== msg=RUb4beVfe+HKASjQztjmTxvVZaF2x1oxDEs+0M5GHQLfFeTL/wf409wAWEFy+5vpkOzWfJNd0HORzweYnY1jtg== sig=OyHe7in112rOc/J3+g+jfy1B8bqXUkVWt2kLMmLrzBZzP0yeLVTQ2proRdyEvqKbOZoTlugfM4QAIuaLRT+wyDEOJiuBkiVZEONJ3X3bYAGUefuScI7ZyWthuiG+ZbVSxE3nR8hqr8gwYV2tMc2EYw8A e=found 140 iterations", + "pub=MEMwBQYDK2VxAzoAENEFLX8K/aLuw7KCArn0wJoPRjwsROaw1Q5qpqwrdZvNvZZj1DK5Nzj8jbjhe2YNmILMTqr0aKoA priv=MEcCAQAwBQYDK2VxBDsEOa8kRS1pVAwC8AjXOIftd27e+mr2wnJtlkfkR0C8nd3Q/wiAbqW6oAx4lZq+bJfv16VSIwn1ZGvR6Q== msg=eJdGqBe864+4BUYajSWw9kH6PeaJU4efrw5ZJQBOrgwyjjdY1vK6tqd8kXN0MQViO5SgMGNLrIfpmsJM8SbwfA== sig=HTq6yr0Td43O3zvmCDluzgChbaGfW3HjShb3q+iHWgaueXjwMhLPQrtWj4f5eK+xS71Ls8tRtDEA91eft6wUCaQPJXb13Y88lT6/0vuv3xwEgCxccYuTKkcu3vDV33C/BlsmEE1UbDwzei35tiidGCAA e=found 201 iterations", + "pub=MEMwBQYDK2VxAzoAETfWlZ2kV8J5DMJ/UcecDZjsnvwlGfNjcu2EqhDsduHnQEFz2UXL4++LO29qzIbvE2iupZdwYKoA priv=MEcCAQAwBQYDK2VxBDsEOQF2qwvhc8tbhd+7rmNFcKwn+gidEmHkqXEBIXZZS0yivfnV6Y5ZK7NyyV73Jfzq75Vw9uBgNV2PXg== msg=5P67+/OIEwBjX6IlPv7LFh4NDFOI2FIUzakDmeTh07iOmCkCA8YGtZ7qNb8CSBTBOAA0BUqFePHH0rqO/S+hdw== sig=BA5T+DmI5PfLQFjBEwxKgrSVef5w9Npd8NSCrAl2q3K2cU5Q+IoRKS75DI92jLU2mceqPdffMn+ABNizUAv28dTbJbMjbyCOeVLUNKfrKfa4TFdkAGDPI5IIAcS/uOMl88r8RpKpLOO1WzxK/ZZF8AEA e=found last=22 s=17 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA2H0EzZ9vP16zovD9z/1kdF1tT6EhswY5A3mgqxWrbTGPUSB+a2n3uQ5P8tTzrBaHB+lZIaF+YP8A priv=MEcCAQAwBQYDK2VxBDsEOQSvpV6NIGj0ngDh6zTSl5SZAGh09uUUx1K6Gxca7b/YMFwv3OM52M/bODqVBJvcoPI6pD51/ysBcA== msg=KeSnUGml26s5EagwP0a4yvu2x7rHTSxUsuiL0B6KVdutdNm08TFp1kMgIEqjQlWZhZZ8TQQU2sD5+CB0ZEdNLg== sig=2ZeKPwhm2Qp56R4RW36VDfI8D1v+s59P68A+M7mKV0wwBugM5fZ9zE0baJxDuEGv72xqoQT8RyAAuHq5gJk0NSXosnCdKeBZU7o1Yyu1TrZiNO9jtL9NBDOCfNR+OoyH1MrxlXzt5zeqbMZePdmOIg0A e=found 200 iterations", + "pub=MEMwBQYDK2VxAzoAIxNZPuQ4qlj33QGK/vUFufnHd2oJoapbtUchM4eE/2BToymRhxMLF/Ulcv6Q/YaWF6lIN3k1z9+A priv=MEcCAQAwBQYDK2VxBDsEOXiQTGcxikT+YfbGn93QdiTN0aZuesMh+7YjaMXyhldFq/kw7gvzZtQi6IVoAfGLj0kj6YZRpnJkPA== msg=EmcQ5x29+A2iY5qUneP/j/Hu/e9cPyrMsSmKBRPQiLgCqQPbJFcGhzJ9DEYvmpGNl/lW4ELTfl3VgiahlqDzVg== sig=FUduo3wakIp+MmRbBtLbTvInu8ra4EwyL8eDxVoSOHg8LwqFe/TCOEHoSk2NRtMVpexMkhQ/reoAgBGl1MRC5Dvuip9VFT8WUaDVOCowC9pc7vDqH8Nra7LS+v4MGDcgAnIxC6tpJwc0jK5BoSM79gAA e=found 141 iterations", + "pub=MEMwBQYDK2VxAzoATHxNBd3QSi4ei1stPbXpdpzsBIoo7K4A5KKqq9Ofa4wCJsnXpCwAEGL1VMLi1LzROLOYkyAYIb+A priv=MEcCAQAwBQYDK2VxBDsEOSX60nVzai7U+SDwDplxI5jXgEoGGvV97+Jf9f8kvYP8tRkhj3yTwxwzXkBoaW5U8FnUdX8Tx77jlQ== msg=XUNTAKBEta6IUBG9HpVydP7q0mJe2gsIfwGZb8LKFCMZPx9h60KURJ9VUoxI5sU36Cmj69I2SRgYLLI/my9tuQ== sig=Vfd1c4LCKZ+kx7l0FGAC0xdeXVkNCsTzJQ6P+Cq6YIF7RJuqCLhaCoRBtf5hqE26WAIrfulVfbgA55IXOZu3xRuEJ+FYdEedsDfpYipYIXXeCT+cg3NBwNNew9PTkcS7W2uD0mcrUGGjNv6u58jhqRAA e=found last=18 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAJYcaC/UTfo/WXKtaOD5yU+sHTpg+FZsjBrzuuFdpI7DMdJF3eaiRFm3RfvZAg4gaYm9e6P/tzokA priv=MEcCAQAwBQYDK2VxBDsEOd53n6jpZbq1zNNsaFNwSQf55bk+mgE+JGSkL+4lLIOnpe7V1sFN9IrRQjVv/sEHvgsSIeLh8u4tCA== msg=s6pLpniTIS71mmG36nUZjXoaREWHziWFkokH3ep3T/gVAx2iYQJjWfTGSqc5QQrJKx1S2z4a89r+n13FXDgHTQ== sig=xekCfxviO2IlhzAkfDJhWVYpfE7IgfsmmxEVhkfzW1sI0LsgPi55r45AwyiswkDaVDr1GEtVYDaASMpUjj30ZPSU2KaQoBtIhULX/lSHFmEGoHCEl/PW9uRnmrhzBOsMAp0dENqG+pTvxZz6ffONkSYA e=found 137 iterations", + "pub=MEMwBQYDK2VxAzoAnujONpWhYo+N1v5ByGlQRr63je4JmZSCyxDQVfel10dzNuobpBhsKvuXe4K2b5X4+Rzap5GTH9sA priv=MEcCAQAwBQYDK2VxBDsEOd2VHQlSnP4ukdE7ZcA4d+ERKbmfllPECmSM2a9AQtK4FaPR2r9xyPuKA/+RkCxgfyWiB8zEx9DVqg== msg=54J2ZV5PQq1lVKwJnM25Xxpn7Q6JuSWfdG8E08AEcMSiY4s0FoQKV1n/Gw1Tj4ty77ytgVoD9iufB3n1icpAMw== sig=UhvBe1OllXrHU+OFhssCnhDRH44SydYfVMUxz90DCugB7rC/1jNIBLvGrIQ1HEPArI6xOPYKTy6AhsrDhblKCsBqAc/c/OvO3h3Fm1wTWG1lGjxUXQa+5Pwq/w8DcQa0cJ3t2OLeOZ7dpwXe1fohEQoA e=found last=23 s=17 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoABllkhStDUTBpbjrw9ouJxB55p+nQ7tZ19i5X0amFd0wQaLKzJW3mFWmBht+xVDoNBEdDeMaQwwUA priv=MEcCAQAwBQYDK2VxBDsEOcKhwyfjG9xkmIB2Zca6L2oSdaFXkdsfIr+pSL/ci82ICWOHDGxRM4LXBWwPb07i3mmTYRU+DhJ4yg== msg=yxdBDNaEKU5U2yo01NYVt5eAQdjItRYJHDM3X5tqCVJrjhJtZeVZgCaflY9Etw7Lx5AbJyBJrKvsU7ovsTpXmw== sig=A3zGxZ7wjElDJsqjJedTBe3keLFllH4JTb38Y713+zMLsvZasxDOgbnVb21gAApRybR2VJoI4OwAxEWWH2HXvnwVbaIa6Aklvvjwya6euw039dfk+6f+kFF0tsCtijFzu5znsLDkqopl5ANlSJikLDcA e=found last=22 s=14 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA6w0K7bhuLT0ZBKWhiJT9NPboDTz5Wm9CtDPYqFl9yeyxSe903FqZkCW9+O3GA8BdlwsVJWqpKsYA priv=MEcCAQAwBQYDK2VxBDsEORTAFmtu/f5ZdvL33SW6Uu1ZTV6uvr3AansQDiKgTVwRRnDtW00wOwOo9nR+UeEDxdp50IceqEuGnw== msg=hp/aOqZY/lyhEf8WXoLOq4rSGEtU14vmnLiogxZkJl0jITv3QPtSY4jVw6QAVe4A4NMudbt/D5JxT6frNNYamg== sig=t4yc8KuO67NVq7Z0GNutEGNJJvtzU4k2TzlU7ikUEvSsIRYsXxmP3aVGRJDkCUGK2UvPuUJRa7cAiT7T7VSfeE5j4XNWBT4MMgEk4ISxWgeixkxFEF32LBOlNineB0/ngPEvLW1UbIO61XzTkS1b1RgA e=found last=25 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAbBOtrkEzUSVxroEag6ooX3XUTq8seEBjR85sYHQUXb9mcYg4bV7MJMZ3MaOpACzMJUrppJKh1boA priv=MEcCAQAwBQYDK2VxBDsEOTH7i6balCDjUJs0RYQPKUMY1huodYf6GGOfN9jFYkVF2NDf8p4KFfZei/tSlYP3/TiullhEDoigXg== msg=F4UmT77lypNsguhnsyFg3tOOHA+gAP5dn94lEYQE6c+ezJacYIwiMAhePW/rWgcbduY2pVsJufewfWE1R9eqmg== sig=+1R1M7beyMSCzU9RpDtbJWgTCWHWO9l56IPnk/IAtu35gQnb63ntZ7IYvzUDb/rhFWdWKcOWyAcA5kDTr0F3oEoxAS6GENwRe3PnDEhxPA813HTghWNUNtTnl7M5MuA+AifWFjBnAJLUDm1wySlAjDwA e=found last=18 s=17 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA2gpTSq28FQwInEfryggTqyb87pO+TFoU0wfNXxVNXxi7H3dicw2x68vM7hQXtenbvVStXWNyxy+A priv=MEcCAQAwBQYDK2VxBDsEOTH/AZSStUJtPutLVOsvtHeogycuyUha2Iix3ZvccSX6XEqISH6x006rFsgudse4H33HkkmEYaRKxw== msg=/sjGDWHM6ZG4kkfPyirpqAZd+SDU+0brKCGWypmp+biFLAefa87tyMjp+UnmwwXEWVFGh7KglKSUgwt5z1+How== sig=bPtCvC2SkI323e2hM6/F1K+9lTkZxXEj+LTLKawMnOxZiQGaGYw5RwFYo4nl3sn4+t16AGI9HseAWRSmyrG6MFUr6OSZCVFfQXPj0JZjeLl0iwN0YD+aCTU0Qk9OM1K1M3+5JH2DP7tcT7ZN6caSSRwA e=found 138 iterations", + "pub=MEMwBQYDK2VxAzoAOTRrtUoN9KSdxXnntxSjU9F5o8acKgHhV4+8h5ID8kQmuLQ+y06QCjXHCLdl1pIgtd50DjN8g4sA priv=MEcCAQAwBQYDK2VxBDsEObSv7NdUuLC4wJWgMqhlPfjH2xa+5zE1tSEACth2Ky97frpN4YQNmvaWCOHsrZHVpMkJkCXLRm66YA== msg=ldNEqiGzPVZGjURrTWlRUOslBdBt6O16Zx2vxCx0/eqaSjwFpXwUJX2L42cjuqNm9vsnUL7WIJRgkuY35QUd/w== sig=FsPDducFCAjmoqwez9QYwjeTsFuqgv2Ag70aaMgRldsq+weR0taw+E5hl914EE4lknwVozhgf58Ajhi8LQij69ZaaDO1B98Ps8J1GrjQ4ATzRh8ifwhSsnnpcMnBCC2EtsrXXI+uLRWTuUltDjMLZDEA e=found last=22 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAs3H3zIx+TDPAI6Ud2IR6FACMa0WAD9rnz3eknGg9H27gYmWIrlgYrmQMgYPIJi2Uyi6vcGOHvdUA priv=MEcCAQAwBQYDK2VxBDsEOcbfP0ULapoVJrmAE2VIy/iXN0MhySm+BSPTpr0CNXLXbbn6OROrYvadVJTuILcSiVt4X3SIbnAxlw== msg=wJfMm6VjuUeGaLUZHVXkqwBI3Sh2t9lWZQM4I0SYX9/sb8Frjr1f6rY5rls+7tZzfMImlkhrhD7jjbVPJsBZow== sig=1fbHRV9Z92Xa9wJGwKDaSh84ko56a4aRzqe74Bd0KGpbvnwqfjoe22BCROk9lNwJOnc2eZn5TN4ABN7cAkbAQRRb5IH3IwQlrVTuH1CP1nFWzrQ/IAAhg8jztuS6WI2z9Ai6Pq8+BCQwCAiJih5QvS4A e=found last=16 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAt0w9KqOqh8Dom3ZR0fDNiF3zwRcONzyhN2XAtProgIf2ryzN9B4Z6nTClpvPvf027fHAF3UQFKMA priv=MEcCAQAwBQYDK2VxBDsEORo3c+9qhL+5A125+miuSeo37ZKVBM54sIfhlTbhX5hmBYBFFrzrKlQzWx42WlrdPy35EoWgomnIeQ== msg=2QnpjxEGc+dlsTCBUHCzuyrjdAL3x2RIW3u0X6X4GNcl5LlPc3bj+l1qfACn5KK41935mwjF15xR4CZsCkO81g== sig=KO38jmNK50Yz4WHAT1/wSWj2d/QZDzTvrV2j1/8lY8K/KXXv2PddmkfOq+yh/XGpiAUqyQuhbEqA8K7v5G5bXyU2IEXkds+ivPAk36hkB7z7QSzobJ0EQdPVKnhqPgXWaBJLWunZLdbbpsmLIGSxHxUA e=found last=16 s=17 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAbwXNkhp3D+1/v9p1stNBi2d5nC+/1ByaTrEPoVt+ttFKh+St23dJ7zxAwrGHZQbgNJmvzcWHyPuA priv=MEcCAQAwBQYDK2VxBDsEOSBcvzd3Ji4RWiBtKgOX8+2dRlZ2Wvn6enihTehIWXRYPPpMNC4rMt0hNcW53NHxa7kVkud4GEIa7A== msg=VnZa+fp6eKFN6EhZdFg8+kw0Lisy3SE1xbnc0fFruRWS53gYQhrs6/g/QRdn5p66JOXqbNKDtxJDYUfNhA4Pdw== sig=Adw2bK8aFSNjXTzWdSoQs4w7jHwSzP5JlxmV/fkCNZhGtpovPahDMzFLpvIedmDDtOwKLIAzKncARZKJQ3ooz+J1VnmEFCm45HfT3VGTz0AmvnDm8HVWdHxkPsZriXIO/oGUuo3rH+jXVEECDoN1dg4A e=found last=21 s=19 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAGPW8jidYy9GJEsj6yyCvpdbsC0GtzgFY4yOZmRGnPM7uO7Yj+2zKof16ccyManbhrrmzjvRFN+QA priv=MEcCAQAwBQYDK2VxBDsEOWjSEgu8RTjdqqVLycZJFSohNoPiSSl8MKnwrae6YKKtr0i6TL2St65oAw5pikeks/Ajvei7k2ZwJQ== msg=OK2LQQpbOgkudJSF+8PWr0LDK8HDeg0aJD5A6qnNG2dg+qvU3oqfapT2y7RPrYhfTehX1fIo243DgXAi1+R0aQ== sig=bw4f42l6tGBkzbnYLnM5k1hO62V58Vk0HBxsmvLIyUvpam6S9UG2TAKJckWZKEqjQHzKGfrFP84A+cDPmD8isnT1Dh2ivzzZgdQ+iJWfJwHK/y9UUDkKtFsHpRfSxeuQa79t/AV0i0imCSr7s/yxVREA e=found last=16 s=17 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAG9MYjl8f6QBkutQj4u1WI+oaM8zOSLzmNPYckkDl6Yeb8V6OElXe992+ldy/GGVFPdA515g6mccA priv=MEcCAQAwBQYDK2VxBDsEOU9wl6VZctt2KogSjr9cOCerPiYVQGAujynPOFDFMBKDLcVkKe3zr3K8eeBtNqzRx44UPawzF65rSg== msg=v1w4J6s+JhVAYC6PKc84UMUwEoMtxWQp7fOvcrx54G02rNHHjhQ9rDMXrmtKLcvR4qwgwXGHfWwXh87bEMni5w== sig=SMH123TZcjPor6iDCdOT+ua0g31Fls50u41nUEApkxcTyzVnVv58mLR3ZcKPnznLvPCHKHU/K5AA0wUtKEvqDvw0C9Opul6DCsx9HKVgVHHY9gch0QbTLKo5tHhhT6uaQN5ZJrfDxY5cvpkvLTPz4B4A e=found last=15 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWw7Y7KvPT8FHe8mpTvkq1ISbrwZyuQ41dKP+tqhCofM/3wJixrOLXI6ZJ1uN6OhHPGFh8ex9eKcA priv=MEcCAQAwBQYDK2VxBDsEOeb53BLy/ffTFtWH+JYwA+qS7KfrZo1uFYQ48IJb5tJixnrCV22N+ZKQYw16Smhq2syqflg/nUTltQ== msg=mFIIp/pFLA7Sc/Jj6DMkjMCS1ZIiAKlEO8QOK/49fi2UariP4N26YiNqGMzhtpgzZx+nvct7JHZHngnhWOR8qg== sig=7zguOfsWMN2HyAv3XP45u28Agh7YowE8hYo69gAyYqUM1YxqpyJyT67imwBvkqa2HRiyQZIJ/FmAK/ufntzAUJZtt+eKYETojPDKR2Iz/oxxnXMraQwX4ZLukeUJB4isadZTBa2H0c7zRtufa+uw4y4A e=found last=22 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoARhPppxgEfT46EHtgMFsDDeqeHc6Q90Tet4GPrviBLgRUl6B27fiHSf/umSk/2JKqMjDRfMkJv8+A priv=MEcCAQAwBQYDK2VxBDsEOQh2Zd5TDrSW5raFkMqA7My3DqKmzSAtr6bq/4TwppuTNws1oyp9AGcBEpGOXSXjqpVtkkEJgyg3Dg== msg=+m+WSLPy74+/wpnimlqQ/py/CUqCqYFkk0FHM8i20fz1w19AnLWz3e9/9/D34O+FJQbcfg2ta8ucHHGZxepNfQ== sig=R6F1k7Iu18Wm5dnq3EbMuaUQuSntNH1cWEklJ2uTOiidxV+OfyagrDTsXt1kRjMtis5YrX+RB/+A4pEkWwG9ZxjUp3FXWgDvIRhWiStESdWCkCRpDHN4wD6g3iQokKW0jA0cSzvkg4dLODRRNuiRRCwA e=found 134 iterations", + "pub=MEMwBQYDK2VxAzoAtUMIoXZTMK3ZTloqHG+41he7nBhE34XFI8KpjyvLbow6mnTWJOXxawWQ6h2GXvWH0wGIsi4DKqAA priv=MEcCAQAwBQYDK2VxBDsEOUCuWg7Jp4kMd/jMzc1RjfcZg/M7wKT3MH3iS6b5UPYkwtFW/RM4okpTX0uBsCyy11S9GRpSWCS55A== msg=+if/1ipw+ot8S4wfRrogDPmsTW0b6ZD9xZeFKKpCtckdemRI0Jinl4ZbdUuZjBz2iWa42XYC0ewdKHivcjV0mw== sig=Kamqh3tfiQUg1GgqZ2bcwNGzU6XN2DWRxpV8XHkguJ1/jA9sBfICXclwkjq8WNdpeOxd4uUV5guAeBVfzi4YqdQoIMW/3ia7ZdwNT48lmEYDCWDk1H8EhDJekKV7PEsEny1/sKga4yVxvMMv4EUd6iUA e=found last=27 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoARmbu150W6xIwybdQQNBZ3Kv/QMBNt0cy4cFsl3ZMbEgqErJJaUKDFb2ndX5az/RLq0So+12/QemA priv=MEcCAQAwBQYDK2VxBDsEOYoF3c1YTmQ+7y3izEzXkZBjObSUnXvZJ0GYMcRFwS+ZFUTnwamMKNHhcQ5F0Vio+J4Pubgm0rbEmA== msg=wAGotJdkIKSjlfUOaZM7h9ANc2gV4CGXvITZCsJ2KRVVrN6MINuiMDq877nZQeZOCQhx8ndxnwo5SGm8KUGipA== sig=uIvlJi3vXYG33u5gjyj6gNH1wKbsbhBku/sUWNhOsI1Q3W2GyQSmcKbXrLkPcRQmMa58sPC/8TEAFXN40/UfpLA85VUHFQPFSWXrfK0bKzaLOzp5X+L8geC6CLPxLGkW3OS2kDWueLVXzIXr2PGecysA e=found last=24 s=17 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAOW7fSAkbEgpCWoJBk+e/ZMOKtNcfcDfgfkDKzhhdiD/uh93/Lf5ZEMLuUGcWbx2S3vG7gukDixiA priv=MEcCAQAwBQYDK2VxBDsEOUK35+LCh9yMEh+d+Op3UPxVgm8k8xaLPdH3GC/ZiI/482MJ4KuY72giocJ2+HOYxZADRRH2u62Jcg== msg=0gBnbE4HKqcNFNb9GlXcGTePTEVdLdbXYxYIsX3RNlxG/2EtTQq7RFO8DnnzEiQr6jiu08GVj/yyndkAmtm3Zg== sig=ZWnSYqi39DU1I3Dq9p+lDPT5LOa//O96p9Nk7pTimaZuCPB9B8ahDQBEWeKyH6AnIwrvHpjT/BwARVVKJafMUgpPQjgrHj0WAaPXwUlGOiFKh1GAuLrn5EXrWL+6L4ondv4/DamqmAC4zrLpbwwW8xQA e=found last=23 s=18 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA3kyyVFsSZWt+hLV8BU0qV52ILT9UPUg9Sbw1ULiPtUTLDzLcrNE1p0EK9JeX7FsgO9HNBSPJlEiA priv=MEcCAQAwBQYDK2VxBDsEOWvdYJWomqlkhVMrcaceOKzykVfdwDmvBAyFzvYf8/MVzkND6IN5+wR9Q2XHzdNHyaZEOhQ2i2prMg== msg=/sJYpVTD7DsBbTYdKUnBANLQpGqjHlqVv9hRCAr6K73l+15SbPRvqupLvNBhV0AyNrKqqtKFigay/tgiw21QJg== sig=hS7tWQ6hT5+gSoy4O0djDCCqrPUig46VjIfxI5bEikRWihbWJTA436nFx9+mFgJ8CxxjExWoCRoAYoUFv7vziYPmZzkQgn2cLWvt9SM0vR/Q/4mWny5j6iUqDx7nHHi4fgJzR2GESEA4dRknntXxOT0A e=found last=25 s=17 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA/fAjMOyCMyi1eHVhB4xnIcG6HpGOdOpUAzhT3gz1/L2B9CV2Eo85zzCXUXpNeJsAvFyU3XhNlacA priv=MEcCAQAwBQYDK2VxBDsEOUhHvGJDg0L+DVjs5HBBvKrk69NE5YLT0nS/Xh7Imd8SQ7SUnrbKJYNrmmOQNdU9+iopygKaZiTREg== msg=plHKdxeV6Pn+uhauG4Z4sCUf9mDfnLb0mrY4DQ/FTC3NMHH/1OLa0FVOM561ar3A54JfhjG6EC7qxHNZKVPQUA== sig=YUJwChns4eFjvAW77+8rlO/b6/xLqfYgKwYcyVxmh380tFSzkRsTo4t43qdVUYcjBUHio87UUimAxp9vAWdeeTApa0bwQxLMcmmtD3i6yrrZSRQWPCxmxQnvep1SkbMSTobZB0Jb7V9ppmoVxU4pmAMA e=found last=25 s=17 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAzWVc6Z8+k/TVdYqe93wbMnk/lLb3lX4Cq+nXUMe71GhtrSgZmsBPD6xmisRSX/5taoFodQ3JvZgA priv=MEcCAQAwBQYDK2VxBDsEOXFMFygsursVbcsfnTmoL1Gt5iBP0LtzXNtanjtXZjU7tdtTLJS1MMGGEG54tRsd34ynxDZq/2oEcA== msg=PL4fSiNKJbh+E/QAqElGt8hHt/hExdzlOMDbs3z3+/rel+hMTbH4qu7RYtl2WuQ1sHts2ayFrPkgc8YZgOzKJA== sig=Ea/ymDM8ClMpT1St+x5bZEqPwmDZGL7g58ZrfqpGWJjynX4HMk8zycPjMLniwTqVTIgo37bvJlUAkOdwdKul8mdmdH886F7eysqLzU9M2uPEXZLB6IFGE47qgA3eb7bpyEwLmI26giyf0lqazdauFi8A e=found 198 iterations", + "pub=MEMwBQYDK2VxAzoAauYRXlPPtlfCM1f+ZdrXdDjyKuHvezr7UYP4r+KLrJdeQbHVOiYztxbUzhC71WQ/83aAHyoBn+yA priv=MEcCAQAwBQYDK2VxBDsEOVdcvfeSjzxjsYvgwEhR5FMGKhon3aVfnE7gUEIqF2m1xyjftJM72CWc3nb/Te9V6lGqp+fNxOExZg== msg=dKb44MLdgEtys27qNhM7VXDQCU9ijGLlhwsGL6vEcRMTthIbrOQE02+XWZBqaaFxn0jS/60Jt0SUNl6DcYvSbQ== sig=AfmXHFkKhfwvTBna3lOF/aophx5jf9+ok7H791y2CvLfaYuwVdHL9bVMQVCE1r8NYFYPbfDrXDMA/r3iOXA/vYbggkw2xGqDhRYA7u314hqs8G5yABGLPPA7IEryp/eJrB90iyQcrnIVMPGJIECGARoA e=found last=21 s=17 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAdD25OVp68hSZxMh0FmqngEeZkFPzzdkOMXUp99GV6/UNjojhdpEPrKCc4FS4CjqtvuLp3m2SBoYA priv=MEcCAQAwBQYDK2VxBDsEOczwB32oWTyKCQHuUckiZcN8dO7Xf66WeaOmm3frrPfP7CYfXx3SlPk2hPAlO5gceDVtoePpWLG6bA== msg=06uImONwIrAMPmrq6MZOzS5mL5HBZ35dwEEKWLNoMmaQ6JrfH9bsy4s85lDw+GAc6ewUFBicKdSJ6EEUqPXAYg== sig=1VFiqiCoXQWQIp+twIrOdAC8ZUC4EMBUfEp8mKOdM4Q6heqf/jjIriNeuhj5zzz1Fs8UENhaiZ6A46aqTNPuM7jTxuheEs74ete4xmLvjKhY2nAbh70JuPRGdTiwBn4V7uIozJ047/MVm9n5Lba9aj8A e=found last=21 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA/a7CkMZtv7RgMYnzoi1JRIYrob9VXQCKzrxtEd2+74Mb5lXdua8pN7TD0A1HJQnEVNB4A3ijCSUA priv=MEcCAQAwBQYDK2VxBDsEOeBJ6i+16r5dyWTmktk4WIClJTjUWit/Iyd/uk/mQpMnMmODOQfH9QF6H4k2mePTlMlZ+j7jBCej0A== msg=oZyaKnS3Qn/2pSkmJ0u4YdTNaGSgwejh5KHJA5ZoHmacK2WfMpLpg6DHu/pgIbS4JBcVXmwr9KvUy6y93upErA== sig=oUyaKUmW+LCJw8Ra+lc6fb9YeOl6OyY0uG4yRbBlAafFxI6Roam+Cfkns8UQlUN2X6pID2ncd+mA6YeAIjsclIsevZifGIxJC0FuQsR7udzThG9KVnPyX2dRk24UpKtRSzKwfY1LWHKgf33brMTKnCEA e=found last=19 s=19 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAb64uK4Jmt0OxZqeZePXH4f+ymBn+V2qPE8APreK590gkvPMT6xG0o57WT2gCti9QKQSoWab3H32A priv=MEcCAQAwBQYDK2VxBDsEOREkLAeZTDJymyA+RCtX6Alb00q1vakHS1ssc16FaMwwNVBEVxuVJjpbwbebKfynXoM1pRuN/IfYTw== msg=b3eoE/TQbcPBYq2FRZJjfd7v7eKXsf51OqIJcda/3faQojfgBeq2547d7+V38NJZWy8x62Aknb47PPsMl6zcQA== sig=YH1b4yCd+e9YG9d2IO7ozyIyJj/cau3PzcDEvzOau8s1dySS0UvlJftx3jRsNqNoCeHHysV9hMOAhCA89aClHNmW0Z0VtvC0LS7JUjCZmFYmJgpuqDSyMO605+6yiGdw7X1KoaYc1tuHrx8seILcViUA e=found last=25 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoABE3BDATL677cHKiRRfuV6VTNr32AeELeBDqJ5ZBg8F5n1xPL4sbzqZ5KReVuAowTxnIyXwACISkA priv=MEcCAQAwBQYDK2VxBDsEOXYe+khF2WhVk1NHOqemNiKdUjteyoRmRJMjDKWxvCLPb+Im7nW3D0hIjjdO9e5LEYd3Rr08kelqRA== msg=Ylav20Dda5YFITRdJ8U25h7FG9UjSaaofC8Yhe90aQB1T/r5Q7JjalIg55O+/wy8o9x+xUPGwk7vqC7pNjqBew== sig=b7uWgAHpjFvgJ0XNEONGy4Gi1HwnU5FFws2FgEu2Nal6fJI0QK8a2W80+inuBipjSc/nhpao4/qAh0iN7aBEbelsBCyTAvTL2aDNL0Nan8x53JuD0rHttG+91Bda7iuGfI3P51gP1ISUFYSHRlMY5hoA e=found last=19 s=17 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAuknDKnM+W/ZQ+0g/Rb5VvRmUX8nXLS1KvI7rHJMrQ8ITs7BTbcDPujFwJegK6Lnvyrd+GUunoHYA priv=MEcCAQAwBQYDK2VxBDsEObH0PlmjqHrt6lewJ9SmcTdtsaifxGQs5KMPVuuXYQXZFfRhrEjl1au3ZaHXffRHhr+mZ9YCwm9zMA== msg=0tXUjwmRomSCdJyyZindqLRgj8rST0n+udClCBJghCbfNp3Ro43WkMxTw0SFM/AzDZrbBNQfGIKfES3Apqf6YQ== sig=0ZdHEd/sqT/ZiNJNzdAvkvrsoNrJbZaYPijqqNRMfs2lTP9mJNvc3l+nWQmeSnukwclSyZ/KA+oAuLGY7DsO7/oh533glJbMbBdzMhqe9/oh9ocKqo6S9sRiaimMKIqRHijlmTg/4e5+18sTTR6bzgoA e=found last=23 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA6mYO/sIStO+FiD2Lb0/gqdbQ0YeNkhmTWe+Dn8wXsSuaCmmuAfZqmdkMBrz4+dPGCHtw4Ti+ts8A priv=MEcCAQAwBQYDK2VxBDsEOcYk9HtW67Qmos8A95o74wP0XSwmwghSOevpvJ/INq+tDy3n3gB2jabqtpBFSucnmE+dxjT0Nlpb9w== msg=SCv5cHvs3QsC+ZfoHXAp2geWXmJTZIHTOAQ4PN+fM1Y85gTQQJb2qEjV2D17Fk2t/exatCN/t7mc01lEm/L2Pg== sig=REmvLkevIbcYCDb3ZFIBFNc/ymo15VqfmZayglxEBRqrJCe9TjhiVlV0e8w7wBR24LiBtC0IHUsAg3Ydr55+a3ao95yPjOWjXP6URc6EyNU2hEdoPJf7DrjD30aLVxmEQ4YabGv9PIn4vkI291PaWzYA e=found last=20 s=22 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAygyO1URCPsy6F0kmGFfK1C0lbTlzvDoClXTwdV4G2RaAVecpKopzpns5DzV334cwUOr7z9F7+qAA priv=MEcCAQAwBQYDK2VxBDsEObpLamEE6JNHRoSQCwzq3CzICKSBFOpKfRxBglYJK++SpvZF328pyykY4TfMTvWnuQiXCwuxjT/hCQ== msg=Ih3XGZirLgH3+AFH1s2pRuNXaAfU7y4Vrw8C9Nv1P7MF2bDtCngS80nBiPXgjJiTGlhdqDJQVJq1UL1Gr9UoVQ== sig=V7R0yzDClRsjjTW+9tRLQ3XRTShHvBPP/Dg4mbeDCplSIkNCgITVGE9DhL6DDxqOdPPHRc1V9x2AsbKcggd6D22Kjw1mdeTYSrNeh9pP27zucRRd5Yqjj5WO52br90XR/13JGBgLNs++WnuT3rrDziEA e=found last=17 s=18 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAk0fQGGa2Zv1eXhhg7iywGGeLMb80IgUUIjPPOpJ/5SAIvBLpY3/bKPKmsda8qHRdygAHJvULQUAA priv=MEcCAQAwBQYDK2VxBDsEOanfrjfw9p/phsu2KrYdwkdMb6NacpiHM5Y1Aoc09+cJXsLxvM7jZytzbVYxEIqjDPZ44oDvqVA3/Q== msg=XRswFJ9sPEvhBjVvzz+YIdhYF+mOy882wPQAEm+Shq847ytVJ1ipmVrNZiBOL2tI1b7fUhCZlVy/MbzqjkgKhw== sig=chWfjGsbOtYVcuP1WIMH7OijZcmB6ZJwG9ZRVqDPpzg1kJXtncSZBY0anf9GDhRiJ5cEDuhmbLmAUyEA896DwjbP4m+GmIEkYMygpi7QTSdktbDPaXK4MGTz4EyOWIVoBE1uF8IGikHN7qlOWPtJFj0A e=found last=21 s=18 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAEHY2eVabIA5E5fYmrEBbsXC7TZAMnf1LSzfzx7x7/U/UHbY+AxZBld44dRx2jYJS91Ko0/4u6ZqA priv=MEcCAQAwBQYDK2VxBDsEOVuexfM6XvaSN6AhbdUs7nIcx3GrMzscrDF4Ukh2VUJG1BLld53KWG3xXe/1OIAHd4dH4nuYJZeMAg== msg=IQlEqSFTnOMtEeKgwWaZys+3wliCLFGO6hZZm+WbY9zbC2LCa1ScfLc2nT5xsvWoWA0RXM822RmHQSZrRWhsGw== sig=RN8ubWzJAUoZZOvwldqvCkhPgB7r9Y+wRHANGYyvlUVHc/SkEtl8K8Ff9a7xbIfIZUiUPX72mX2AZbKc7LTzD8G8HH4K7UniiKXb1IaYaS0gKToSSb6jx+4ldN/GS3qN6qMo7qR5JJdkBN/Q57OB/Q4A e=found last=17 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAXZCqJMCScAhrGhnzR9/kfWG28pCBppHAWsBaCKAeWTv02guDZNld/TPdseHnO4rRMUNzJ1OkQaCA priv=MEcCAQAwBQYDK2VxBDsEORIjcXeipU0eiUGYH+Pn3BrHLxgp9wF6K1h0/b81CE9wtvyt1cSkqD9TV+AxHxuDRtjKWQCuv/VMXQ== msg=+AR9GwSGQiYCYOUTD+O2zCE8JX+b5TBL8KmGGv+p3pcoQOZpsHYguFds1lmG9VsLncmOuey1m5xnDKquYJxGEg== sig=L03WOklWpudKNwB1Vlp3rP19WGgBqn2yxJRioVmPJUHGiOTK7+ho92GbMVGxItXYBFDqKFcHPJ+AqxhzPW1XGel7K3/o7BKwAlmWheCsyHw+iDd2a5CsttyCsCTvBa4vdfO3gia5M1i46fA8ZwsNDjIA e=found last=16 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA+cTzPmIf6RJ316MMVLN316CpDGLhkYUzalzy2/kUuiqViNHZ5JKO8d2PFknIOyU3qYe62tKT3/0A priv=MEcCAQAwBQYDK2VxBDsEOQnc2auE/YOgZYRb8CWcSHG9i5IL+x3hzAJ+luc5Du5HBI2vJGOWGvXd80MQlfZHZe6cAwpkxzJidQ== msg=8Zsf03LskaMN6ikMjNniG9/KOxDw7uc4eOKxXZAU/Wn7ByHm0D//XPWWVzPsXEWguvtJi/ffTv66k0jDFP7SsA== sig=qrpIMWyMbvb6mK1Qg+p26MIR+6wfgs3oVivSK97H54huc2o4mmet6pAWOD0FvLnINImYx/X0CAQAeaqJLALwTxH9oS0Ozf6T3pAz28ugxtwb0u9h9PMcC0ZzUV+F5QRZRY2DVhct+WxxzOdDWxsXizsA e=found last=16 s=20 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAupYFtFjsbkJCSntbM/xb4E1cJ7k4VJAiwsRCyASuZOU+UvolH3a69m3wIHm2qPj79ycxjBY5yH6A priv=MEcCAQAwBQYDK2VxBDsEOS9mC5CN6wXNreRkQrTS1TSdyTuwTVpHILHHatwHd8YQeAs+NdrQJVNxILzjJWydlEnoKw5OQOR3Cg== msg=+iCgbNMQmtAbOy5B7cdZQgR+I/llDIowhi5If0zPmBuSKmvx8D2xDyNiiYr8TjfeLMmWqnP+83w6kq1OwURHSA== sig=C5BZ9N+YvvQT2tGSWnuFmSK2VhXpZvFeDWJg0iSbu1roEJSqpMbEVWVox/5vUsx3s0llA8W/nRMAzDr7fSC3NHn/edlUOSVWoKYJ0OpIEzqo1bDbPk2M3jsgQhYhubwY+4r5s7IMq35VYoSXaifTFxMA e=found last=21 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAswU+CqRceyz3axsy6qDvDEgbH940bj2v99VUpzvDxxzwFYxTACxMaidgC5r/S02Ii4VNTUXd8kQA priv=MEcCAQAwBQYDK2VxBDsEOa/KzrJhYNVsSYGNCo+M/vl64KeuxA3KArl7e7DREJxXp8rhLHWsd5E3uKT5zcoKyWXJwuiNx/hNBw== msg=ecSk+oMs/pA31EajvsdGWgwhS4Gl0b24dSjP9AkMNzLQTQhI2iBTdzPttGVX+z6jwFeOgiLiDZShFVM5XymMVA== sig=lofIlawhytf/Fq/uXzslBq9KCTiPxra92Yv3/F5Va2jArefqn/Y+tWgrEypapw+PKGRpanIxiUSAP+CBI31ABYdcOe6OKtHZ2HjygBZZPCk6iYdtszlhZ2u47hJnNqgUq1qyOAC+UTpHeFKqEU7pDhwA e=found last=26 s=18 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA4s1B0b3eI2tpHpHG6KRW2zxgrbzff1Z0jQFNg/qL+5mJOD2y/bzx4PvZMbn/t0nRt/hNrMihah8A priv=MEcCAQAwBQYDK2VxBDsEOXS/XJUNZa/7yglpo5jPz9A/AxeICmwGuZHtG5xOmeO5LakOUipklKw5QJeHmeG3RLUuYg/8JBQW/Q== msg=rDlAl4eZ4bdEtS5iD/wkFBb9Ja1tQOrFZwUwqPUt2jwGBNfWpz7JG5PxiO7CImFTuaXY792Ui7InGIdcHfn2jA== sig=qVtNPPafL3U/xGYOwRBXJPlrd3nX5lkXH99g+RJFhm1RCjFqKueEcjWwpH4Zgah9cvdlm5/psv4AsyfWzK2Ta7AgGXWcj5CUHcxIwTjd36o9UnEODGFCgemmnj/lAbrdZ9MjPUhvdunLOoi0WEHtfBwA e=found last=14 s=14 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAN0OCf00epf/YB+084WTdDkPlyK09pN6/my8S/WUcS+sVz41ww2Zt/9GUO9NuQlyBPxJTBvUacUyA priv=MEcCAQAwBQYDK2VxBDsEOY1mKG0s00YboL85xhO2V8GeBifuUtosYHhCs0UQ5JLrP5QVeyHaRZrtUMkexFGSFZLq7iRAKlwmJA== msg=cCoKS5bKzz4xlq2CESrTHMkRyanbO0FCO6pt9bulaI95NInVZ7aGoDQyX7rNuR/oAbFYxWSUFCqlifXkut+DFg== sig=jAHQgQ9Rw7EwRsYL46Q3sQpyYVlWhAipWaYQsy3gU4VZJAvMRjIGH/TAVDKA21ulL2jaHZz9JHkAB3iqr5C3g/u1QIldja23X/OcF9fh0NT5plqfIpMFidwUEJDP2a3Mlq/R1fDZ2AqWhedfXPxXZTMA e=found last=19 s=18 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA//r+bdAqL6LBDhSomuUeNtdysQln8RUdnBJ5L2nnSZ2wZiWcDUPNpX1TndZpbZX5YSM4Ktm667kA priv=MEcCAQAwBQYDK2VxBDsEOY4cyyO6vCzQZnbfrgq8bQMuR2qXNFlPt8jnOdexDZeKj9hpu66FGJbaShk9uh27pVx9X5tUN1tN0A== msg=O/Zbv6rNNz7z21rxCTSDU6L2u6cNGSWuPUS/6AAq4okUN3xQ/IiCkwPlQSbTdotCWoula/ewy+BRA1bFE5Eh9A== sig=cfY/T1xhGAkD9pMUeacPTdpqj7/ugU5BfBHYjb8PSAzjiq03kZLs0PYZAzj4uC52BnnbXMaUut0AZB1nPRDzdNNq1MEowKvIMaIqoYGp64LltRvDsRJNvAXN09le+8l+IHfHRbUd6N2y7RCgRpKc3jYA e=found last=17 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAOlSEMTeYZ2Mp1Hm7PDkkrsMrNGMk0MlY6dLT9pzLae0C9XYNTqxgEPYU2l6q4nzvDzHZ2zrkcQyA priv=MEcCAQAwBQYDK2VxBDsEOZWvUJFhISNv1t5xVkGrN4YFzHor5LtSpcNzn9nJchmziLGmoqy0BE+fSOUdyiTd4IWyi8PoFZC45w== msg=A/DeZSalQmz1jsUCBNds4mlLlRxFHr8pFfuHQWyevXA8zN1UZO3RfecOWbK98VaNczxAsW3ijsLFC9ucPdoLcw== sig=QNmIMpDk5a4DaXX7fC61gt6bKCcSXXA7Za71p/S5yAXfY4WxBixmnt+tT1WnsB3ZxkmNDM6XqrUA/X3L3k94jc4uZyGYVJw55zkWNWgygu7hhD7eKAtIh9VbSoveMVikWi+sGEnDm/8F3+37WCzwsyUA e=found last=27 s=17 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAqBDATZSAS5v4PsyoC6okWFzI/Mew9aL2bF7Wxo9X3C7vyMfeZj2L0GodqNmkWqTtFUA8WVlPFUeA priv=MEcCAQAwBQYDK2VxBDsEOa8ZFHPRxvAqO8ej/SOkbK2dZU0P7KkkzRtjjocO0DwPIacrd7TGgi1Fs4ZUo6/DCf9jAdc00lp36Q== msg=iLUm5qT5Wx8LX//5BVnoBW7dfOzFMiwTCIQGSHii+nsDW5VHGn6UCjx1/BnjxsG8/rL1PfO8wGX9PUPvutHDuA== sig=KoWhS1UGXexaXd+vCzwV0ux/DR2hX6z3Bsb51F/GgIZo6U20y9+6NxG9Y4dbd3hw151FpBUC9jsAtvQWu8X8qBcTgpKqHtZdujQQwjVNbAmk0KlAa7SlV+wmx3ZMgyGZ8XSNPuVhCdCis0yqrgNuFQUA e=found last=26 s=17 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAMNqGdXZ7k4qvRX9AyDajA5oPubKk5XivLLdXAVGeMt/VwUCk1cea0VyBjyz+FYsYGjnKbi7HM/MA priv=MEcCAQAwBQYDK2VxBDsEOdZEEavHdR9SkFeE5aeFYEIqcouHEph57+0cE30QHRD6cm9LnOxx1YC/iKfFVcet3BmDeh08cwrW8w== msg=p4VgQipyi4cSmHnv7RwTfRAdEPpyb0uc7HHVgL+Ip8VVx63cGYN6HTxzCtbzqvL5U8ulSfc3AkQu+xlVKgye4g== sig=u3U49zCreZUwZdXMweAOAmRnlUNrImkTa+tcsG83ayYXf8VRhgH/6f+5foDcffz/LfRNTnhfNWiAr9Ux3iVlrPLvhrVCqre7yOHTTWFHigXtmVfC2+pMSH+8TEKarfv0PWLFpwJCJk+cUq2xRdwOmh0A e=found last=21 s=20 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAbitGvZKGxM3iy69hzNbFgp046xezXdX9TjL1R85uJMmtSfUjOowJtQX0JEVeNldOODQo6kxI87MA priv=MEcCAQAwBQYDK2VxBDsEOUuqQiIKDZOlXdQxfwwATCtjvucUtOe5v5EFIG53/Iwfa+lmbFHPvnF9rGxxqnOsHRiZVGE0IA8rPw== msg=3XtpoA2kmn3wPS8anFktRB2L82RYgK/VcFPLYPmFVWYmJ7ebH9b9rsvjTjczYMO0oivBmiPr8SwiYJjCnhEZxg== sig=FcLE1vyLbilbdgpfEIqF2mOMFySuSONKuPfwHEGL1HgqpMIljA/BuMgfq48YfnS7nqxFxSYr4yUAAShbMuB34/QUYYgV526HkE3Kb7RIvtVkMMDatSYJ8PAT2EjC91GZrCYizt98oCFeQDUb2cK7cwYA e=found last=22 s=19 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA2IQy2MV05CDdNoH5sMnNTQd4qcqce9DgRSogkbAj1QhAlkKlyowKv9hHFIkoVwFen6DHXvU32J4A priv=MEcCAQAwBQYDK2VxBDsEOSjeVZVn6bhFyfjAlOEolng77Sz848BlQ3R9bRkkB96BP4pynnvmCSHDxJGo9YhrNariYHLPnIxHJg== msg=BiB2iM7lfnHlFIMW52iS4eeiCPa9d496bS1Y2OqA/M5XTxA087cYuDs0JVM8JzY5dgE2yRBWqTPF33vUkQQvTA== sig=5/lx01T6VXeXwUp3klswxjMDSjkiVmAZmYaxXfDxr+y0WRc/yQr4qt4TjQbyjaxwzKaHNzztXDUAf+HpBGQ/iKY0UIf1pNYahb+MFxYk+J9hpq2pkfPJxzif5aOy4Hba2HHBeRlukNKgfsZnUNB2NS4A e=found last=26 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAkuH7tBxRhgjsEd4rh5rl7NOaHhE4LRM+xNa9DdLIkESvA0JvJhVPHKx1zUN7B7LdIck8KV4QI7kA priv=MEcCAQAwBQYDK2VxBDsEOdO9Ity+S/yKuo+UmqkniTWaWx5rBdEXVmKynwlIBobGT7sDaG/5S9yy3UYLR+SkPp9B4ISCDK80fw== msg=juQOP3GmFNVbu0XJUz9o7N+EiIp15Xtr4Ho1in1Ml2FYPWih2S9Gc3kK8HTueXWUclsfSgM71R7HEm37sU829Q== sig=j50v2Dr93YgZdh4tbW30NqGdXq34EXUibFBdmuZ6fdWTiBTU7Z9XpEF3D8OdPZy/E30PLgCNbxkAy9q25evvwYqHbjbwDtfwbkKKXbQBi4ebCD46kfNM0lsWfSXrjIkmb39sV/rF3EOrq6pBgq25fAIA e=found last=21 s=17 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAOvZz2jTZSO/+olsrqpPYhMDcNGS4Ze9NozWcxWC0SzEa/WRiRbP0/1Eb1D0hv/tx7/qQ5XSVJ2SA priv=MEcCAQAwBQYDK2VxBDsEOYgesa9sZW5G5FP3q/Xy7oFKJLigjl8wNRvuv92stnOFO3QXaelJqsD0o527JZ+sazwt3RQ3f4dhiw== msg=NYAlJydYRQesi8Ru8D9ynhI0ISkiuTZ4HV678IN1iCuMYa7sHujBrvknFthHuS+QQ5182X5H9X/O69SVWQXrKQ== sig=sRoMPcj5pBpFiz1NbN2T6V8hrosAzaxcYN18oDNEG0eA6B9MCxJ1YE1mOZG2OWJmJS6jG6vl242AZzoIFlUNw6XKr74W8iSuFKoTbXJ4oWVf40meTdv7Pxh3qvcYG7/0JDEIateU6KTXKW/mkX9GtwoA e=found last=21 s=18 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAksgCwDKAciJODYLiLaJZMWC/a+mqvHOe0GrV22LYHvpMbQHj1zzXLJ3XTBb8ND97V4xOTr9BAdeA priv=MEcCAQAwBQYDK2VxBDsEOfV7y//LBQr2YAozEfODKHp5jb3WhbiI2ON2YHSWDi6J5G8+2aE+sr1hlnK1/OT6lw/4k7u/U430qg== msg=DnX/aKr01JBr2m2jDuAVpiI595EmSUWFQSVK4w39RO0ZFA9c/ayKGEjXEEunsMwZvfg4w69TLgsUmrmx/fNROw== sig=dTafrcOsVcTlwVG2RD3q7K/DbzUMefDgOrythxhLTomEH5qdNV/RHK+nWbgu4/M8dLssYaDvFWWA9vhkYYdS8EjPPsMZ/lZ6FuZ3awWsR4dHZh8jM3xKNC05ABxuAqghipPgz3hOPjMoDceYS2xOHRMA e=found last=15 s=18 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAMewlNAYQPqyeG/SCLrTJzj0fLux/JE8cLoJfWfoGXkWMYjgpOfccR6RVOKzqmv5wykFLiBvArgIA priv=MEcCAQAwBQYDK2VxBDsEOcm889BUi0g9G010pbPc/in7TltQo0oZfpo3WD8+uomZb+53YP1l2+iXiT1mf68V56+yqlLfuS15Yg== msg=Rch5UAmXcVXJFoYwbCgrAM8C7WG9VrJdRPZjIDNTY0MKr59HaqN/AGfoqE47gaHeTTzmPFub+SepBnW48nU0Zw== sig=s13tzTgNciJ64+iaxotVqRDXNlF+fmQ3KcSoczWpWONDc2wV4q7rWmBhvpybHU6iqohgQAg+VrMANX4u4g9UIQcxxkeTSX7JXrI8rJM+iLyaMKIIklu+Sg522vO9VqKasZxxZQkQF/rp0NT95o3vKzgA e=found last=22 s=17 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoALCi1MWhd1ml6v4HRKNCs/DkWhisEfNS6WnDstpuOyoEefOvFK8PdWyhG/BolYxVUP13domEos3GA priv=MEcCAQAwBQYDK2VxBDsEOd3SioWxUTG0HIKbF5XKfis6PkBWk7uSQ7Lke3m6HmpPjuTWwwUUeyNcyk9mRC4dgYluvD4MqZbL2g== msg=18OCGtbzvpQepn6Pf4IsZ9Buf2qRNdnfNJIi5rKDkb7GpGoSJ5jKW/V25xDs4+7oytfkwdNQ4k+XdJk54IH7vQ== sig=3GNCNbD8RQ9P+E6wV5txsutDQJLtW/1/ewybVIy5HXyyDmWNpNuFm4Ly/iuntqia7oL1w6RVGkgAPorl3+2WqnZy2WgQUBCdpHpg7JTFg+fGEUux6Qba/A+ZuO0eFnbKGmDaRV8DzNSI3eppujw97TwA e=found last=23 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAGbnXqJZlGlsFQDLEAEhuMjHKuLHOu3enUZEAHNqNWY8J82U8ttJIiT8YbPv7HQtS8gf8CwIxaqKA priv=MEcCAQAwBQYDK2VxBDsEOSrBFmntdtxQMiX8dLZIBmwUlDWuM0jl/l9GssGo9+NQFYz0qdHtiT3s9yvJC5gCEdUVfDfoFNPeYA== msg=UDIl/HS2SAZsFJQ1rjNI5f5fRrLBqPfjUBWM9KnR7Yk97PcryQuYAhHVFXw36BTT3mBKqBcbtahb8LNRVw4Dpg== sig=B+plNiJ4bAFT4IfLvxxKN13DAZYkQEc1jnJndOp+H089vaNPo5OaM788HPw6P88fgDWWGDLgB8eAU7MoXe4tV2V3ykkS3EV1ZHR39AJQc3by4H5AkBFdztL+DjyVRwtrA2ldFb39ha0OP5ebhnsvFxQA e=found last=16 s=18 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAHtMp8XZ6kA8rnjUNTBmv+WPAU8l/Wa0rQAvar/axlSr42nEupJVPhailhCt+Dcp5B/igfmsFm1oA priv=MEcCAQAwBQYDK2VxBDsEOdmDBBrW4152M7uIs4/OyVX2AF3a3CCmteMhk025ho7RwiBHDPZhBmQdnZEc8kj/Ve8pABKOgFBx5g== msg=3G1FB4MbbvxdxnhCV8RoqLZknv3fewaSrZP4HwR3s6NRqesOzd0JFEStfZn9rura05O0ehqMZ7/X/plpn7hEaA== sig=OoI3SqPfgnPIO2+UGALQPe4rRh9HVrBSprvjXRlFvxR7ZSHOtV78ML3Eftmd8nnFjkvDG/uOg8YA8MWWLKYLSQyyanboRS5pxpJpx7VVT9W7D6eP0YzZjuN1dGVOdcUHJ5D7qZG5wI1ggw6fspbQSjYA e=found last=24 s=18 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAxO31ACpX0zQ6O+c8yY4lx/DbDYvvbGcK1X9/xLGNeN0Bmxp2qeYwVKeKSgrLWRTdOkEUpmOaogGA priv=MEcCAQAwBQYDK2VxBDsEOZVtKaF9rVJV6B3NH/mNEzVTthNjL1zKA4oW+RNqL/xdNwJm6HJys/hyEqOp4ssftGSOq/zTHy8okA== msg=0IuQ6+gZKCeFRT/HolRvX+sAj+Lz2s40NqUDpxQ+Ri53YHk4sn1ZvVhtsEs41Y5mXSaEt7nRQgqyQpHtBUT6Xw== sig=lnyoKt4OnNzjM+fA+Pmq3QOMhxjB1VEB+CsZo4Odz5xZxPWoBP6dq3E6beoCrieE5FwlOAnt+JCA5dM2qV/RdVvWMAmbnorh2K+nDsuTZHIqawfM1HfZh9rTr7UGQA9kbsauI3j8+D4aue1zk1lpGRIA e=found last=26 s=20 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA7jti0snBnT5qi4Mucb6qAT4DN744yAxZYLuk3g0t4Ylt5NiPhZcF8yIwoTg+HQr6oclR4GLmrXIA priv=MEcCAQAwBQYDK2VxBDsEObTiVrHHLpAGm6G+IYzaQlpYMvSwvRqu4kceHgoNh7rQudIPxpWJb9uTT6F1wo4ORSf8ikARM4LnZg== msg=GEm0OQ59gzpy0tpOSKDNpsDzIrRyM1YvuID8JVU5swnNkH7iOFVt7g8dIRvPVa+WiM1fIKNus94d08U1upMCDw== sig=pl/KeuVl+AdxRcPjUv+X7mf5TusTFURKG5jLuzbfYSe0g/1Twm6hYp+mCRFzfes1ZGkVFnit28kAOVZevM7cF9/YvNZ6FV9MoR9gRMs/VBPX3Vj6aSfu8Q2UGIhwjZuoCDgR7ke9KFHsX37GvlZrjxcA e=found last=16 s=18 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoALwhviWTzM7CQ2CFlU71GxGAF91Z7JyPcW3bo4amTtuEAqvL4PMSkmvfjIKBDJxEDZI/6N26DvwaA priv=MEcCAQAwBQYDK2VxBDsEOSmnwPnQeL4Q3+6PPrcpi1+kNr6qO0ak3kXme8ygsP4jq+gJNAzx6x2rS9iE7IQwQPkaG6sx84qJvg== msg=1T5qa8P/X6e3vJ8LWlfQF3+8StjgxyTD9Eo9pwb2DCkrslT9o8tFqWKi29lCSePDMt+CmdnWULxOyp2OfozXuQ== sig=q+D27XKj15wW8Awqz+ggjUYBnBUSObw7VcNbGDTkoVFWZJIdmNAiHSWGXZiU8DCYR3wMO9yLx/UAPp4j4QtHN76cuvlrKvR86zUX4pyXWy27dWADmvHp59GCOHZPeSeaixNjAdQNiGcV/+XNPWsVRQ4A e=found last=24 s=20 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAFy97zhTH5kI5BmpVWyaQuErchWwgR/6GklaKBpxmeMixkdZ5dluoB5orywuNJ6oHJTFpU0zWqSsA priv=MEcCAQAwBQYDK2VxBDsEOUELpmDKrDAC8C7SZeeG9ySixh3QvCKz5R/FKI6KbwEYFa3XMnzX0ZZZPT4vbyTJDXwEeNAgTxICXg== msg=5TPi4Jgek9l3pYpuTI0RH/HX3Yjlwf6tu8ZP295g40p37CbGBFmNhXgfukejnYZZEjz3nDw8R/IDXpU+3kq2tA== sig=uT4PzP7p7e4PO4BrxLToLgoiaSQRIWTHFjpKCJye/fqdMqff8W8q36FJlTnOeBGd1vv7da9pDjYA13AS8GmKxrn7qYs2fNnGDpdNpMAn143aX7G1mU5Z/mumK3kRil/OQR97eXKgq0zuK5/Pukcn2AYA e=found last=17 s=24 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAdcAzsfzTI8iqwBEdL8KnuESra6SRg59iDRFGX+27U+m0gsMzUWrUVIR43l8eJPqL95HxI1CHgH0A priv=MEcCAQAwBQYDK2VxBDsEOd5KlM3SgDGoiFxMEtaTs8K3ABoJFX3WQMixlZQY732QgV8HSriUYztAcp+kBO+FeKVwig4kQsWdlw== msg=kluX2cQnKs7gfEmMo3KOJEw5vCrswlZuUwVdXw/RHdBmVDBiqW+XYzU6in/qibziK7aWU4yRP3GaqSb5414+GA== sig=fXcmL7UMoRC1DMzwtp0cB+Nh85wcKbzyu0zxwv2K3P6iBerDiH7XCQhQleKom5/oUreWcTvcTDUAno/O88q6RESl56B14Fn1bpWOqXp5/pIOcOEF7MQ0VS8nh5uLTYq/sl3oj4qsHAg+OfWMtPyB0jYA e=found last=17 s=17 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAI9iSB/GK0Tb7Ptd8fxmqPDZItknaDM73JFEH14n07LqvWYX8JoqKeK3Z9Kz8xFB8SHr/pMMxRiiA priv=MEcCAQAwBQYDK2VxBDsEORyLI9uhl49al1qfA1a2LYSLUkZ5XfD7hNqx6O2FXzhvQ+yiL+CZ7/kBCzeO4w2qL456+qiNxeme8A== msg=MSvsu6+ajMarWCn3Qecl20QZQY9mCOkGZVIJDXFc6y+nmOWwRG4HdJGDb4bpxJbOCcql59RuNg7Hw3SxGH2ovA== sig=I837tPJtOAJ371feJsK6OwKuFMCI3I65agsJVSiVXLsbo8ajNExGLrJ0GqceSuBsz9+4JKKyflwAqCLtVYu5FSf1nuu/VfmmWzSorjtSz3vosSWGF+x6EKn0O/DBVbTQRJ7M4k1inlERVDE2MwzPPhAA e=found last=21 s=21 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAlUQBESzyC0lKF58tvreCOO5mx//f8FWbFwThTm4fQ0+qP6/NIv8t+BYTklHABunECI25VbFtC7sA priv=MEcCAQAwBQYDK2VxBDsEOSJCH66TYlK6ioFs7vjA/T40CH2tymEOGV/qdK3Fz9ldIVcv9b3sd8qZGbf6LeSxDeIdePztrD83Cw== msg=nc6gPfn5jD4Ld0Oad3MgCP2CNuNqpt7H0RtBASPZi5AaNClHzgjaP5s30c6cFHLiQ7w2iQWf27Wr8Ar5rVcgAQ== sig=zZVmyFoWsOvKnM9JGbqOIQXswfVauEXrTHDJCCSKU4TSAWSPbkDU0Jhi5sbn/kwJ8tE8sYT8lJ2ANY5EYbAx49A6fs0SA6Vwe2z/fbwsaTzOFqNquXspW4IgsSZ1vv9CVRJAhFDYYgN7VddQThWLAB8A e=found last=27 s=23 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAlMr/BEcQNwJN/e32P1BD8/wb/7ZaAGgCRK4PWWcRGTxrWG7i/gfxuE1H3E3sI8/BJtSGS5BbHbiA priv=MEcCAQAwBQYDK2VxBDsEORI6JltnbPnL9cmKVIYqyOL1ErXtH4CYW4WcKZsII4CkRy/u5/mG1rhPmE/mbXqMXun1GjuBGlS2Vw== msg=/yk2mCv7PQG1+uSWlWrdyihYsRguVVh5j38S4WzYg+pEcpYhjEds8SwaNlLEMpcB+rlGxpsb7O0BnRsPxydBYg== sig=lGVOVflLFDPGs2pRv712ZXaeNyuyI6H7ZhuYjqIqzQDeEgvq4rbkX6RrcpxXAT/3sBSN4u3i+ZaAekNvhKZHN7SyEXvCcjUGUjk3kG6R5MBd4woVta1OwlC2tLCwPL1Vufpy1bmSD76F3t1/jM3r6wYA e=found last=19 s=20 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA7hKG61WJaVDT+HiLWPDGM6IbkVCmXVmnneSGSWcLYAqyg/VSyW4n6M7milcB9aCtvgRQAZ/yas4A priv=MEcCAQAwBQYDK2VxBDsEOYNePAOtOjL6kq0L/fLLLqYAC6PZXsiM4aRwo3sNhLbmh2ZIShZ2ZMNpfViRxjbNIBaETyhHt4u1LA== msg=A606MvqSrQv98ssupgALo9leyIzhpHCjew2EtuaHZkhKFnZkw2l9WJHGNs0gFoRPKEe3i7UsuDMRA1shEGSjJQ== sig=40Wt7GBTq0nN5nh/sV5GFt54cDAO6zaF4FlVCqv/wDjXPw716tRTDNIe0aVIu0F0mB8AWMGIFEkAWF5PJI5mDROxSP/KjhdwU3/To5Hwvbm45MuyocLLMtgL4J52/78hK4G8hg8rDRbQXEHAIPbPqicA e=found last=24 s=19 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAjgznNPgzI0Er4aJ7JssrhmdaNFWrNvEQpkiwhnSzHnho5+aLSpXiD7R4LSM7JYAk0MoidAiHQCsA priv=MEcCAQAwBQYDK2VxBDsEOVRy234RGjxtI4El4kSrdqvkjQR7csFpa+lK+f8Gje9pLrYR+7PfnFls1q5H1F+sFxEic6hmNcBDMQ== msg=XAXjpZY48TBMY9TkZDU1XJbg69iqxYSfTwuypERLV2p2WsNDM8QoIGxm/W9L93LKi3E1IgIptbvdtGfBsCzjhA== sig=UX/zvuOswAHSL+NAykedGe24NgV1mtRlcVrDRCLpszpPIRaiYwveqMDCx3XDWRjn954CMZF7AzyA2QXaXhRR07uDA8ut0OLGaCwQYuDZ3GTy18h9dg10aBXOrkWsN3iKVv0st0uBpLw4XWpjLXMnvhEA e=found last=14 s=15 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAlmIuTgPx/OzOiIBJl+EJTYV6O/zkv6BF3B7clgkrRS5izUg1ac9bP9/D4A8fzkijawJho+tdpdCA priv=MEcCAQAwBQYDK2VxBDsEOYb4ISZtUIsDtJ0KOZ235+6Xnx0IF+XdXefhl2WHkW4NDigOrzP0Sp30d9y7g8i4n/M4KdfG39yESg== msg=QMw30i0G/GcP1IdN6woHI5oXUW+DREg/HA2SyclvRVZ2TEB1vzq2i4gqDLbbBdQDpVcvxga2GR/lWkhRgNTLLw== sig=TZYhtnJWxELfmR92uAaoyV91c7ZycKiiSl3IHMdkTe6bPiGxFJea910q8ttZEYXpl0oD7FeFdM4AbSMc30eSqHIDkNnMI6bWPHZxcm4bxS88V0FKW1oBxsiRjBcRpXTWpkHd/ZLvzjxRnahZrXQEhxYA e=found last=19 s=17 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAEo3+Yb/rW/jclbnoEBQBSXLAWh0lDKZN2GAbiwKBsgtA1qCYQp1O4v4tsRSwNTnRLI4pkVV5I6CA priv=MEcCAQAwBQYDK2VxBDsEOURpXl7r606KQRiHvAogyVgK8qmUv0UbQdNhipAVbG0nlxdnWNOVlcvp1y2PopYjAXpbDvR8r7jW9g== msg=q9tt3XErpKlzY5UeNyh62PZAM8aw6npPKJLgtI5SDuYIxrM3lzkmxMwbWLCbv5O2V7dBZZKLUsFta6IuMa4TqA== sig=CrN38aYp4KWLKlGW40yVUbqsf7pl7YaKgTIIUurPS30FiZZnA6dZj/KJ5nksH9EbkDtadWeVT04AGIwy2490UWYbCQejxiXDfzCzdOGMvwBs2iw9zBZGr/JcVSDXajaShNnyz9gU5Cb+2edgiTavTA8A e=found last=22 s=18 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAj33flTNATo9WZbjcr1z59AA2LxUAj+IxJUTn6WRxPosRH0fdBmVRgMYFPXoXTidd/RbpqpxbcPGA priv=MEcCAQAwBQYDK2VxBDsEObEGesXuuZfN0BxrVVqsUpyDZf6neh3PL3c9FD+9+G4pe0DhqPvhRAwTGMWO9xCrDg8QNbqH40PD5w== msg=oMjkHJBIO/BtrMtElC/gkhL32yDbsZEtcr00p/yorQ1h//ky+yKt6fE93uHpbA0PjGm/qf9inQSrJdwdQEq0pg== sig=GWMcB2SVJ3B0b0EOIx2ArqTiqGjlOHT7cA5qDETQOd/ow4VDqqjSN8sHJX7ZFxx+TS+TAwtFTsSAxSLd3gKnfXmsWu/FUbMc+VzoHR/CdKAW4UXY9MGJ5dz8yAMM9h6WaMjSFe6OKBrZISH13HLBlyoA e=found last=17 s=17 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAzDKq4afZGLAQns1pqu38k4Idd51xihaLgxT1i13QiLwsNSNFR3UB3JjvD3A47W0r40funajkMzIA priv=MEcCAQAwBQYDK2VxBDsEORP3eU1nr8UoPaGp1YD04cQQfl5aR9GKMiEmN30h73Utsoy48lbLEpVsnagKxelwj7s/wTCGx3XcCw== msg=3AstgT6ZRjuugKk6WCuVj3pvgXBwMxhtNM2DgrGzTCM+T6Ek7QimL7Ye6ofcnFPjqx6OKJdvkpCZEYB2ZLVoiw== sig=2Dhg4UgXGI7QVgSt88piYG7Il2VYkpiEXbkD0++Gjdy1r+L0rjhOfSt5syWFsd38APJpdNWi0r+A/dFOgZOA74XcgRJkNkJuLk19Lu9BDk5IGtA2QNQi9tk2sAEigVIYUwo29kIPKIKPgwLU1FCj5REA e=found last=17 s=22 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoATVdObvZ/z3dmqefkWYajTlWtjOtV1giCnUXNTyA//lHdujUlrXnlS9cDVPGQ5IfLlWpFea4bhzEA priv=MEcCAQAwBQYDK2VxBDsEOawBe/IAspzOwMwQz3VAzzEvWlLc4jKllBYtW4nf2x+htCWJjKNduX75x2XxBUp80j+Kie9PHFXfYw== msg=UaxwFFGA9BcyzdkGhrUaEA2QMBA+4U6bz9omV6OEe370xl+HTHWsSpO/YuHk+a0++Tul7/emTd9Kvy82s/sG2w== sig=/AeNv70J1muos5Dxuuo/FAMoUSsOzdpj7kh0m1H+b11cM/0n/d2Rdie7xJ4VU/35TkyO529liOmAHsMMLaNk0um5GHDkCuqBPqi8Ngb1i3JZRTtCFHswGzOpuuQJ/dVM4i8r8Bp1ziP5eujbTPQQBwcA e=found last=25 s=20 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAqLmW9bV1aMactoJIu5XinFcww5G1IQBQiV2jSPmcDJoqWdTs5buJ+UscN25kR4pskJ1j7owY1j0A priv=MEcCAQAwBQYDK2VxBDsEOXmj5b6TB5vSHM3VUqMWXSSObvaYPAXx68FGMGhr4ZKrrzc36fAaxu3W/D9kqlgyhCZRDDhZEn5Nfg== msg=TDHK8nBjj6yiFbEhRDTGEwq8dmC86i/e8QC+GsPDweTujT46jxVnfFtjoVIQitmYv4b51R3pNwVzTND8GFYZWQ== sig=Acw3us2AjxXqcO3G9rOnKEjEv8ODcEYWLDxUqsnqvL6N70vMIqqJId+tGKQlyP8qbI4L8hqeQHWARg+vawdiyhnjn3aaQQ0Hda1XsH2VWPHuuDgVAnv9ql1d4OpHjmF43vIEMRMNq9gI6diLVa1LNxAA e=found 203 iterations", + "pub=MEMwBQYDK2VxAzoAVkDhOFTRVEZKDs2b/ALsy9yAv/SN9pKCcVuqSUcsRcVGwR3Y37F+b3LlzEZ4eypezcJqFtATqa+A priv=MEcCAQAwBQYDK2VxBDsEOS6gzl8eHWu55rHOecjgbhYFw7t6yOobg8xvHVfdirN/vFxlGJn4K8KNky3urqq3hRY8xtpKjVFgHA== msg=8jSZd6chwMkQu7onUeHABXACHdjVY7Xz5x5Sk3MVGcHDuIh5N9UCjO8Wr4vn0JaWzPMzruQd8eI3o8Ht+wk/UA== sig=iIsGt5hNvtPCTpq1MRzBkcrJ2mOuOP3mr2BVsR4P/Iw36HDeg0Eoel3a8T3sdPmDX4DzWDsHfDaAWQ06rK3sAUNHsguBmya47wARanZ8TPpvzPrDvJyZvZJaHI6vCxQ1oXALedPSRAnAtAliHgbJfRgA e=found last=15 s=18 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoADEW6pOi+o8x7Xa9mcT5sMFTnYJrvA31yxg0oonmOXfLXzVqykal1JMnBiMrC8BhEmD2+OdZdBaWA priv=MEcCAQAwBQYDK2VxBDsEOSnWmAukjKw9qoKNaxiOYycZmLBg5A5DSrN4QuOC2j4tDwO7JE2PEFA3IISkgAzjt9Sz0OsdYN0OtQ== msg=WmsiFnKuj1Ygqkb7ttfOMXUmw+lVznZ17S2cmncuqpPW1qqjRZ09EP2+n0T8759rcd1PladPMMUrK7P5/+t2Sg== sig=BdN4w84t4zn0qv6K+Uy/GgNy231EvfJdAWr0moGhu0dDcndGaEBXG4MjRVHDGFHExjr7yyey87uAmEvjtV5FR1aMKA+z5D5MN6QHvZO7zWrg4/AYqM7vTOYA91HCocOMLachou/TXgX4ViY5KRvt1C0A e=found 135 iterations", + "pub=MEMwBQYDK2VxAzoAJu/noZ3TDN921P39e/HAqFLnQ1++yeFWz/FZWVGkUgMkoNFCV/V6CYVV3Z8GtjtblNexU6fX3okA priv=MEcCAQAwBQYDK2VxBDsEOdaarL2FzOLHkOTzhjUunuHgmt/+d+VRk/+YtDlGrV+SnDSMf4AJzFnj60Nm1YYKCk3lhKj261RMbQ== msg=mSE4hgpQ5DcJfJTsTcQVipiyoX0HXXjF9BykxtP6bmr2dE/vbReNZyd/pPLBXA+lMbmQJx+oxX80hHmjc/z9pA== sig=hBw1crgoOKuEGcuyqh2l86Ic3IfH2JwWIURSU+JMBuLe5dt0kebMGaf47mZIcW4gKJvjVUKNjJmAHf9+F/lIzcNB9z8Es5cpoREqR6WlcDR0sR2jgPr6WcY25XOoAuU6qiH5hlvxLEFS4BaBuqCs8R0A e=found last=27 s=21 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAhhXrcQlrSnpGZpdVjlCG3w3Bwwxgl2dS/pVwY2dg8W418BZeHmeu3b7HaFgYNMnG5IqWGo0StBuA priv=MEcCAQAwBQYDK2VxBDsEOUkPcCUPgqeB7QtzWSmzXwLZNhOAn3/+fjxEPu7OJ8s3DxmA0jxjIuuOfyCyThJ4KRowj47KCXcrQw== msg=TxLFqyxvg35Wiqg1aoWTab4CehHxuMHJbtdWGh5X9bOucTo319iEcXR/49wVVUKZeNbaRvq6OCVzGUszvsev7A== sig=yMYQ+Kkki8BXnL2EKsc90N0TzqoNQTGuMarPnGXnympmWBEr2v2ge6FURbLHVCwV3539cEVQiYWAY9nrmqvyMbacK84tkyIy7GfPDbDcuux8O9GTLokcjicI3uW6VG8uagP9q+IfNG/koUZDkntLQyIA e=found last=20 s=20 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA0sQYCmADUHSNYfA9mjMy98u7nOgrBXoxPgXMM8D6IxhIKN0m0v8UhEDnhXjKkKlSznDtNYPor9kA priv=MEcCAQAwBQYDK2VxBDsEOeGoEBsqunhw4a+ZmKFIuUYfZvbFDnyjPdD87bxLjAFSyYIb9S/bTdXWbsR5n1BbrJKe9sylBHN5GQ== msg=OewxmU6ERCFVNZD1JHQ+LfkDUt8Bsy7glFkkg70BNd2U17cawxUEdvmOdIVbUnRQ+KlS1XTnDasLHEC6pucI5A== sig=PnBDqEPJxWeXhdU1pZDtUyxBg31k1KdcVAfWIvtVuiegTHM9B8hOwB3wpFISqUbqs7VHp599NekAMpPFcPZs43LeFJa0mbDaEAjSqD1CjGfHePYu3QtqZLy9IrHKWGgNt0wygP58UNa8SPzHeKrSHjcA e=found 202 iterations", + "pub=MEMwBQYDK2VxAzoAqPpSuGNSB6Y68vConl966jmTEvWatF/1t8gO0cS+ZvDXDAKrOEE+QRhd0G+u60mqaSxuFfvAq+AA priv=MEcCAQAwBQYDK2VxBDsEOX+PLezpXVVKI+FZtvLuE14grjpYvYyeWKY9B3YdH6qE+LhdlJNnjRS9GppraajdRAEkJVGPgNd2ww== msg=ciVnpSzvZbfJe35uKgISXkAzWu6/ezHxLgmFhCKMP4wZX42Nf0xJYhHwbfbJfpYjE4LkY5JGw73SzGL+/puoJw== sig=XYHHO4X5ZTpOKMvtLur4cIBD9Ue523iIkn3fUJ1mgjK9Ou5hAyF6+jyY7r/qaaUneUwklslUx/8AQwn3gn+J29xfOGaOwjfcPuLXjLLL++zjBVHtqyCcuGl9g4wlcVXPO7e4Z06rX0Qd6UhfR9tjySoA e=found last=27 s=18 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAHSfNFXJuMECOIF57dY+mwIESCB7q3DJIgcuOkQTqRXtW+DBj7MfFvTznmGl35ig0Gbg1CDqdBVGA priv=MEcCAQAwBQYDK2VxBDsEOUm8eepug7p0kRzFVIlu4YcXKA1xDH0XLGSpKMJ2GhYLWihXvYLn9iktvzIIOlb+aZrnygSzQtiuGA== msg=o9oTn7X7nZ15Fy56UhUET6XKy/XqGfkhrgaf/q8abSFr3s6dstjzsIrHdGGfunmgxgaTbosNlAjmP/zKBD86yg== sig=TJPleHC5oZGI+0Q8PxsFO1KFJkZAwJH2XbtG5dlC4JFVEj5+IszRp/CfodbmqZsYlLNzgaGU04mAipctIY8s0i4UDmtATABZ3nOkuhYLIZ8nJtgJbe05RJTq0tiiC2/XRIVetq+pSHBxGZvx0WtXWB8A e=found last=23 s=19 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5FUyp07oHVjnzLH/Lyg5FVFx7WrhaBnDDSPFN4pjZaDqxWep9X8D+ImjkAe0qE52WqxquSVj+RyA priv=MEcCAQAwBQYDK2VxBDsEOU2XSK0yVMyZWnEl4JGkFt5gk4i17jv5HWw2/97B1v4/rwAjlwIm4gZzNZd93pV6nOcGMPBBbrQUbg== msg=2LQF8cPR/JLyuywB4i5+lXpDg4UEzMtNMYIOo5HMoBu6GI09DgRRWRapo8UzPthTfBIoL3TptoCEHrnquZtWNg== sig=BrC6Im9bHWZhru6e0t/ndybX625D0hYnGjkSB1hrtg3O+2LA4DpOlEHQxcwnXG7YH3v/0ksLd6eAdpHzkwhPp+8fkUlkZPI8s4mICps1bOksMTGetgCUDGVFma8iefDtjuRodBIpHcYF1ZFxaSWQ6SUA e=found last=26 s=21 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAhdlS6YAY283k2Ob1N+YZYIPCWMI/mfWc+ifSaCqSJR9h3kwP+5CaILiBkAvJrh+6KYB4WULS04+A priv=MEcCAQAwBQYDK2VxBDsEOTmsGrR/z+X6YjtRJ4wP11xIpq+3Lqyq7Bz9UsFHctheXjTXCead2n/txLXUkwkcSy5/gYpGHivoqw== msg=cS1951qzvg/suUzad6jhvHlsusHjvTnEMpky0yAyG9VoGIopimTIg8zgE1zmhRj12j5Ppm+g4j9EDS3Wn11uMA== sig=ybk4dJ16vBX9qePsvvCD+ghBw7ydWLLFcFHXxg+520BcOvYO0beS9k7zy/tpxN/RDQIO80zLq1CAr6TziMt3n/N1U6VATVmwh9ANH6T204MN98CvS0jiz7S92xtAYHwRUWW6nN0W4bwng0UVAyfoFTgA e=found last=18 s=19 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAYJQrIbH9yOUcFUO1gV0MDl2SFy2GVPnU9Qu94OSpxn9jqukElCgfbK9xRS+PSVhzI2VEWCZT2KiA priv=MEcCAQAwBQYDK2VxBDsEORL0tisy/MPZvDoCBnkd/+9dS9STriNZsDuIx9ZEbE8FbIDg2fb9ZWisFvzamndpu7w53B8f1umc5g== msg=uuf37T8tlz5keScYezJ4c10a9boJf/oSB5Mv4pJwPWfHQOee8Xexa6U6kGvDaXMlHidZVeiVdxUJYLrAiz2xzA== sig=MLzqYvNyjZbxO4tFveFK9jH+JV1AEUCiZK5sCS7ir6LtA/4BLUWiCjfZNfMZvNIe96uJfKO0WM6AaijbxIUIZyRCfFkr83Cgyc9Q6zecF23uZvrPFT61xzgetK1zOqQjlBtogptkL1XT6yKaI6n7hgkA e=found last=27 s=19 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAGJPbqLOs6pyEUbk+gz5yi2Gx+uKxMwP2Khb6UPRK5c7ZVSTLRC1i9vX+dujXdg3727sIilJjgBKA priv=MEcCAQAwBQYDK2VxBDsEOV+vL5ZOsAcPQ8uSVNT6rKjfafsApuGHAJqDZgk3fdsTst5nJ/A4x+PztNPeWuIYhBAjZPfIOPtb4w== msg=oGKlZepSQadEvzPganO8RFiCxZsJ0FCQiGzVCHJlVyWRBaXRFlSFMd4/CvTQMsLOFrH/7yA6JunskKhF9Crsvw== sig=5caU18EUs1Qsal6wjzuqySw8pHAmx0cRMKig5R8qhyLDgG/3BIVoci/U/DraxrGgsc52vesgt5gAc9beshm8VjuUo8aL4wVDfBC4l5ufdH5OhVjAM5/yApMxkQZg+7PoBg9KYZMVwMQi2VQjGCggJzUA e=found last=19 s=18 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAJNbexWimtatekhKyNgZid4hIZz7u/MD0YKLuEn0Rc88afjoHpO6mwSptfD1k9S/BVRTvJhYgzJsA priv=MEcCAQAwBQYDK2VxBDsEOSF0bEQxbT0svY9qyapiBTPujX8WC6yCb3wEUPCB55Jep4OsL129eEe6F3IUWOSk+d1NnkPiXjPE7g== msg=ts7UVYvPSMST8suoInZlSkcIUrAsGFlmS+6EN9luktbR4b7Odh86nss1lu1NFxqHTH5VrkdrywO3OkbvmoXlNQ== sig=CU7RqiGX5uWO9z4fwxM7XzbJ/AXjR3sDQ4a3kktX9VYdoptXpxTclIq2b79jso+FS88vqQyFhJ6A9plQLrHY4JmNdxExWIKcxLLGgu/rZkeqVOp78ZGwzqoCLm0dHIIlBhYWxWFrRQxrjbiDh/PfgxkA e=found last=17 s=18 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAO5CzswjGITCOcJS1zvfARE/pKZDpdkIeQoyZYH19uFwHNBMqSTcdn8Q5f9IYKHsFdamEIl1yfd8A priv=MEcCAQAwBQYDK2VxBDsEOWH3lTaEsK5HY5EPN54zNQ6WrXW8aPP+NSSp1r9g1i103ilhEbKseqmM1D7hDP9ryTTGDObekJ5R8g== msg=eqmM1D7hDP9ryTTGDObekJ5R8kd/wdPbdbFCQ1Ju6ut/8mknhdPtxSQss5r7OvPKi2hl3BMERZ+CLIOYHJ2qUQ== sig=HC5PFXbjpTtQnMpWsNHeUTgwH53qjoXZBGYRjMblcm3fb8o1dXQdrKbVCLwZcaoRqNWB1yvy3c0ACCeT7diW/d60V1z99cyCjzpVKtXg5K8dr4qpNUvOgwGHEkfY1TBgXdSN3GGwaMQgxXK6qbgV+y4A e=found last=16 s=19 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAWnZj74nJYskgqK1OOffluHkQjWtQn0Hfv41KxZZIUVmmbX+GufIGMPDqqGlEYE85VyuDvijfaK8A priv=MEcCAQAwBQYDK2VxBDsEOVw+JhV/3VGIr7TbWXds6+xgHwVqgmuy6Uu4/XSEw1LiPNYMiJX6w4fnKvfFnPtuf1Iaz2HBBxieIA== msg=AzvCWtMWPuj8VBC5sSh+HXPdGn+XgfwdMoMyv0hDHW5/+bP6ABUMrjm/JRHkk7GO0XROkpvZMJz7EHBEQwKIYQ== sig=luFO/brxeB8st2Mfun2ipBBkvLdRmC7+Irv1IbeUrywrB6+uCUOe9h5Yjqx4UFx6qLPt4c/Ubu+AlnS7olvC/N0PR8X3CKQC2nUKCN/EcHbDtpT7KvfEW1FR8ElExsYApu/NA7bJE8pGX6e5e5CxaiQA e=found 136 iterations", + "pub=MEMwBQYDK2VxAzoAzpJurZb9wnwuZuVhAYrJvRsFtCfAPCleqN/VffPybOmhrxd9hexO2mktcCoCQMDQkrFa16aCGZAA priv=MEcCAQAwBQYDK2VxBDsEOQ5t5qTSfcX1YwcSwPWe41T8bJ5hIGCayMpiAI2R5zwPAAQ2SwKHuoPMC76EfpMoQdD6x0/2MnPoeA== msg=syI3WoZNpcKfQIcah8CYxwpsKuEXyppidos6eYystSqLcV7OI9xsJP/GPNnv33oH9rR4X6FA4iEreRApZNi6Qg== sig=qvQNPhI+5nJuCH+syoFZkjTik/6iECE0yjG6U8e4BM93U+NzyGz+WHjiod1Hm1CYiidc99GpVvsACPPuRUXimixq3I4xmy5AXmFGYdmuB//ANaI25T+TQ1jJh2K6itBCLVCWQBM11OrukLi3oIjZwzEA e=found last=22 s=19 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA6omeUPtGyx1yrLodNk74Eg0ihigBIISZzbdpcyp0XfPFpUiMSZ9/OsE0c6DuQJT0AIe2n22K/r8A priv=MEcCAQAwBQYDK2VxBDsEOfzwGNswanchnswGBWnPvVybP6XRz0WwpXkdGG05Hpkdg7gVXOaC4EY/237ecbzZo4GGikEfMq9KwA== msg=X27x7i2+7pw02tWrUnncdH3y5SPpQ3k8C950iCyNaqIAcoV8O+g8NQQCBTa5pclfxjsR39BFrg4HvC+R54/IeQ== sig=BKjutl0Ee1DwwXAPl0mUYpedjLLlVWIbJU0qrxNOxBCATNtiNQEIdlFO7jskFga/BPWjuJoCWtKAB+eZH1wGxiPdrofDnqf+Lqb7jP5L6D2IC4RouspnqzXnJr9QhCe0SV+Jmjymqrmt4W0vt+UTSDsA e=found last=15 s=19 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAGkDXQe5+XM7OeY5kpWt0R2dEdsZzWrtOLrJXznSEyXF27OIEm4vd1pZlMGe0glInkB1GiXdugXKA priv=MEcCAQAwBQYDK2VxBDsEOW5Mmam/LqNOx9gDUe62ALCjFhoGiqnl1fuqmNNrBWdE7S7CPeZr9RlhBpz5QBZ1cs+G5ZrSleHaDA== msg=D9CyDTq57kuRvuesxR0eM/MFIN/77V9phiDl420hpOeGNN69Qxi86hPd2qYb+Fz56Wz8GQQQnNFV62kxOARFKw== sig=m1Hv0KYLep+iAl9jdKiRLnkOcFnfXMXwUmjnTKxVKbw/fYHdZzRYX1GMUtpYeHtT5oTeaByooVcAGOj51GNqc3AAJGsGx3DyTnceif8yI8TO4UMQhwMSyuZro+6RTehJDZcqB5rAbYzCXunJlkKP4D0A e=found last=20 s=17 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA7fd6g+eddrO25BoOU9XFXr+xPnjbsnEKsv9XxDHGH0p+dQomn4KUCgpDqDr5a3jQ9L1mfUn2IYYA priv=MEcCAQAwBQYDK2VxBDsEOeChtf/0D3zRh6s0W9wgJspGl9/aXQS7m1PlvQNIKMY+Drt+6bB0Ke6uYRkoY2Pvl7bh5GYyTzHNJw== msg=5bHuu6iYAabkvlVKD66NdyrrmpqBmpNoI2dB+8KAw0oPnl0UHKFx9aGDn0/8BLmJsTeYoLT0rMKZMQ3nBlp5qw== sig=n6QKn4MptScKrR06PtEKre/+OXKzu5xvBpL++Uq4mCCKCzU41Hnlg/9R36ypJOz53z1oR4l1wskAAdLfDWZPjenQrPjI9qKOtvT/5PvF9cDygHl7bgu8wVRx7qaO5AhF312d22l9baJ5qUIxCE7D5BQA e=found last=26 s=19 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAPMm+xEsTlVaPH11TSg8Vdbw/H+J5BAefOnM6OSbpQUyegjGJa5XhhEkbBndYEMpikKFl01T9VYoA priv=MEcCAQAwBQYDK2VxBDsEOT1RX4AjFWbIjJ6UDZWOXA0VGHoyykivEBo/d3jH8bZrhXkRr/t51R+iz2jG6aLD4T0htN2y5FeJGA== msg=JsN6SE7pD/WRqi5q3VqVwyLSgILsHt7Fi65kF9dpECfzX5XDl12NqATwBCMIo3tn5h05/AB7YM+P/arXVNnSzQ== sig=MyZhqp1uVU6EARxLeZAODYrN18rKsTtEPl0CQjEh60BmBd6418QTwOrCr199ihLdsjRkE+0QFHmAJGpZxYhLbRGFbcfZNqBxvq3jYUqYzGtcFlrLaCUyZ0aREIbz5m7aMAu0CWiG9mPU1w6e5w4mRggA e=found last=25 s=21 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAT8EjX/MKLdsG8kGN7Qe/MEUVzqVKW31JIIC/JiJZ0ONqCpeVYrv1wbWMMZBuS8gtxDtuvZ4/DP2A priv=MEcCAQAwBQYDK2VxBDsEOelpRr7LiYPt78Namlko1x4wAJFkZTKkvQKMQkbW/Tzrqpb1CBU/6XTio0Qa6fvRY7hw24T/sKzvbw== msg=xG2nz7m6uXR9/in7j8YCBIPsv8StNSOJ5WjoLZmUuJASstDQcBXx0KzQAgaPvxOajvR2vbon7AUEGbPpSS+deQ== sig=SgwFKgw6XctcwbyseoQ3U+hozNsjj9lWounR4RNIl2UgkKXq6RAY6BEfJJtHho9qocpphFlT7BQAA+SB4U12ERhGXRRnuh327SilzgpDc9K7HktfL7XhX/dI7aQ2llql9wgMFptXB6c1KCI+8OB1lQUA e=found last=27 s=17 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAEmzPc4sZbOutezx+mJxHzUHoMKJjQ1MRK+L2o/G/vVTQnb0q2RFJuDQor7CpSaDVun1R6He9+wsA priv=MEcCAQAwBQYDK2VxBDsEOY3ooiDYO1Al9HAUluA4nEDgVk4u+n2D+vGKEQflNGyy7h8MUVjHoU70KeL0JYQsAVT0EpYUZLit0A== msg=O1s4RPFuKYYH/WG/25CWB7wWv5aIMxq5x8GdjvPl2/KUBRZFUlT2m7EIMh8hr+NFRIYumTlbR650XhbEBBNU7A== sig=LqMa6eEGCOf4HpBz9QPu7hkqqiHYiWoebqFkGd3E8FC9PXkdo7RK0biRvdKs4PAVBZsIkuWPRWQA6ECZWHC6txV/vY9CzEGvRzxy54aUxpimI2vTmdFzLXiHmAozLg3E6D1zXwulkzEBKkoZdQXiox4A e=found last=19 s=19 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAkxTEobgiXr6Lf7HABWkKupFarn+MmPKyPRabEHPWbhIId76Se53w71Vx2as4KaJudK/Mi5xex6EA priv=MEcCAQAwBQYDK2VxBDsEOeT89STyw7ijSITNx9Ij5GnznYlFkpQP51o0dr7S1KmFlFrxq1mVol43s64IdjvkRgwwlvDMgcXt0g== msg=BS9NQ5/aUcBvGb3HH4VHDSNDzK+UcV6pDwy/YdSxv4X2V949jZda25AzJRc51Ga70AWUo1MD+VPPykvjKph3Aw== sig=YguRgiKTWfGYZoM03SIQUlDSbrzqRrFekeGPYFSX4pTsztiW1rzOWw2XUTw8YPZNQQT7w+pAsmYAOJ86HS/bYF1G2YvTQcNBPUDSF26XB90MhnYu5bJODHunr0YiQ0NyTDc6trFcus5e4T6DttqwNiIA e=found last=21 s=19 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAV0kfDVfUaEWrrz0M5AwiOknmZbL6I2zyQhgI7aW5+WUqiJxraDZElUmB+gf+AKfwarFYhEVffjyA priv=MEcCAQAwBQYDK2VxBDsEOVjfLkmOvyhZfwU/1CKTAqyN7Cs26YkMWt2HzO1r7rfX+mg4pv8kvAa8LBZI6djtbBTRFkuNQWaIxQ== msg=/csnHx5aMzfBoEJr9HU36otGadGHdPs6HhQsG43l84dHlwI57tpYojq5niZvsMmTGnvfmEjC07qBKmWDduqNYw== sig=cZ96uX0E+o19s36VmJ6AkGwaU2q5akX4wyDJ1u048SADOZylM9i2Nj12jtkyeU83zzZeWF5ssuAAlI7nx/w8pHpWRhbDCnPTu4aLYc8zH4/Yo407biO3YRGHdkbHoz+HoQIF7R8G6QEIwCbLELhOaxAA e=found last=23 s=22 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAY1MaOgGS9nAxaGOX5tNCYo1vquLLsxbR5HZao5d2leOnw4Z2iX+8lk4kz10Fe7nHirtZreW7AZMA priv=MEcCAQAwBQYDK2VxBDsEOcRNX2swFZcaOMbSLR2bT1ZBRrIPugEgr339+TrkE6JqUH+XJJBLE1pprTRL6OqIWbwL5rsglkI2Ug== msg=WV+Pk8tof6v+DGFKT/x5nTurUIqV2rcUe/d9agGBV42OV1gTVK3dsz5sRbOu/Yp+52k5LLhYX/v0QdWWKHfKPw== sig=/bixQ77lvahj0OScn2kVhlZY5/NH+vS2f1S5SAZUPFrXFfKINp7AGz5TmJYX6dt90Nvuu3znZLSAW2H9F8Ujfnfm3tQnC6eYNqFydI/etP6hTZTwWBWFa9BZ6GgSCr5LsLAxZ2XvEm1ncfbTLbGtaS4A e=found last=23 s=20 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA+3SK/8IGcyjQBMNPS1auf4T+9RCbVU7GN2ZrJ+Wkz3Ybtji9e9tTXgFdhMASYqnGuCz8xsTsZEkA priv=MEcCAQAwBQYDK2VxBDsEOQtAgNKWIW1+T1/4oL9CkiFNtld0CZWyBcScFLK4IqkN+JHuapLmms/+YhYnGxgWkFsGADVhAmtcjA== msg=kwrJgrGL6K9E04Tx1uY9Y9DaNybdGMHadGZ0e0UuMT8lhVguebsMIY7Buabhkh60F7e/oqLxgKxKTUdC/GsUcw== sig=mlTkqh5wtSiG00q23CUJC7aQRG1sPm/hQ3twGL2FdCgWYn1v0/YkpPJ87WiUGqCkcQz9I35gcfgA1nYGWR8ZYoG0h8q2MH6FCbHmgppj31TLtWSUhi3dXxtdLzE4qKEVS6Ic3SPYLU8WPKIryaOkmwIA e=found last=22 s=22 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAOT2WXg5VRHBKyI7ai/9Cla8RJ5AYrlpi3rAN9cgd1JSUgTNiY6FOHyuhmgcpKPfIhYewdeAGcZiA priv=MEcCAQAwBQYDK2VxBDsEOWo3iX5MT68KJAxAXa5QEe5C5DSUs7jnetx0H5K8pTZeJD4nKOm/XyQcHFMa9TlYP4v8PqbWXW81FQ== msg=GUBGb4H5lk1aNPYhQXPWz2u1GY1OFyiaxE03PdyqVbr+uhE3uJeBbW45YiaKdhkLojU2q8LHdqsO/A0l5XlYJQ== sig=L35eMSrW/fr9h/aoYNHAAcsyjhMAufi9FmnYoFxCOHhuIiNdkRhiQJ6d6+Pa1yaHYDP6r/GdSJsAfef4rTpVhIlcqCHbMlJR5te3uWn45EB3VnS4lr51RrW2y/sxnNEyYTDd4lIQ7xpub1NZluo4dwAA e=found last=26 s=18 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAaOYmeAzaLG0LI9MQOVh7Wmr1j3y8piWoGYEcHFGqghstqvlpeDKsw2NNjG1ukGA8oVZjY8iGqRsA priv=MEcCAQAwBQYDK2VxBDsEORDV58CL9p0X6m315e6Ekthq1HKNclVTKasQ5C36qjKq9y2dPJTtOMahLrjjj6QxK42pA/MTD1GzLg== msg=aLXK/qs5Uoo3CosrBkfh2Uf60Y+uEF5QcCAoyVrgehbdPIPcojJqmVdYvQ149IoYuqfXyBfnnBMY93xtuekDIQ== sig=uv0nvtEoAshvt/WkCbsB8/20AjjkqHkG6RQ++yUVEefnWvgR4Fjzs4pbqhoRwOY8grR8yed+rhiAx0sAl8+896UUUOdBJhTeQck1vSMyHl42b9ms7JCTfl6pcTWkVtrQ+qrSeGuxGWtzw4YkocS4ZAoA e=found last=18 s=20 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAwjcOZ/s9VbBFzCwOw7MS29Ix2uZE3wXldi6MVCgIn/KVYu1iQT8AJucVCFMs5kqihNRGqZA9I60A priv=MEcCAQAwBQYDK2VxBDsEOegWRIb+ueV1fWBHtZnbSUyA57oSjiepa7UxanV6BExx3eVJi/Y8snGCCrqSMvBBxTh2GrqKyBK8WA== msg=GAEP+n8n8vRkVji+xjq8xQ1PNT46imoRL/ZLR2/tSrgtZXTCGdoG6flRrJ3CwmqTHDJxo0CdTqP2JrpWtx4JZw== sig=tTem1NBoeAE0moH8aFmsc3grC7nhC2e2qgQtkpLf+iTZsdJgb64sz2XLvTo/ug8AXsPJTHu0Up2Afw5VBuC9kR79N5DtavZMPXkdF4qlsRFhXPV1iIg5ISj/alje28JF6LOQbHO8Lg0D+N6jSaQOdBwA e=found last=21 s=20 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA9M/dWHXN9TTKWiJTsobCRJrZcFQDHeecDmN1oSveZgsNyOdRloh3Q3DM36OBQ8QIEd197CkHIfmA priv=MEcCAQAwBQYDK2VxBDsEOWv9az+s5Yh9YKxhw3BBUCxO/fWj5H8j4DTuC0xnpHwlP8IyJ9HMn26tSP+xN59QAycE9HAKEoEWpA== msg=ludwujbER9TYRhFmWrFe++ggqbNOAYQcHqf34NqlldPquTGu09RA04Cm3awj663LWpaTX1bTjqeeQvufX7xQcA== sig=Vq75Cc9HP/tOwvd+1pR0DH4Ucpho3DXR2MMEPeuzdN6DjvAxNArdPjala2ENO1NeBhB0Vud+cZkA3wlCqmv2d88BJa1nm3x72RMPLv1BJOg2HQv/MICc50rinRNq0eAhSncsk8f66bKVjfbAfhTRYTUA e=found last=25 s=18 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAKcx5cg1N+SVsflZlfBTMgaTAG0pMJq/SLmI8XSl8B3134S+wrYWoKofk/OkW7NQlueRMPLtR+3aA priv=MEcCAQAwBQYDK2VxBDsEOd9grUuwt+SC+0QAU0YPPa5ERsToXftqFCyd+RcNv/nvHwSqPLpZpAcvTXpEzMVH7inT1FF57bmisw== msg=IfgO6a+JniUzQRXeoCKj53v/nQchz0L5pVYZgqP6kTt+b4CMIrcFEzRdzls3hlfvICsaVSBgZU3OSoa5JP5UBA== sig=XXbMHG46DrYMwfrZks+hSqEE3bqL/j3rtaKlngMj9z6U0T55CaiBdW1HY8kHLAfZ1UEHnO85dGuAiYpRmDAX95m8QWqUE7ZXFse7ZxUHzzwt/TNZ93k4VmN1v3IOMdChbbXBSmsubhtbWrLOIrU08yUA e=found last=15 s=26 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoATwJI4SEf6gbTmtfTsFjMRF6Vch8Nfp7V67uRPkVpR9mRRgVnwbhvbLdRdEZ1c2P48atvPkEjtBYA priv=MEcCAQAwBQYDK2VxBDsEOaB7OW39OrRFsPGTmNXv44lwfjXWFs1+/5LoRPeQrrLR52l4ZqydV8itD07c0Pv/XXCbI8W9dwMS4A== msg=DfJ44QtC/IqlinmBWw9wANz9GXiUSf9kdpLMQ/pBz7gPLiPlL1TeFQehgM81UGOlKWubQTRLlt8Fyi9Evl8T3A== sig=BiH4PkwfKh46obM/s02kvf/9GjVH1uW1jYi03Afh0QzvFEyt1kHTqR4lSV42ers+Xr61xGC+DpyA9pRsMM410zr2eAUoiE9ZeOmAgL6NInLLiwQlVwD/+Dmvvm/0K6uJIPHXzHek1u7/4JpJwkw+MScA e=found last=22 s=20 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA2lXTi9AzL8t6V6Z9W+rqyv3qfhQwarg1o/xtWa0I+QXH75zry1HKNL7MVOltbZFqPAjfBYFMFXIA priv=MEcCAQAwBQYDK2VxBDsEOaB50RK4i5V8F9QmZ0CteRGb9VHn9FaSSnWPkz8gAd/go9Zq3wtyxqqLXh/9aEyVbQLED1rfKzNiyQ== msg=5X+aXRMGaVzzbH2OIxpI2t3qpMalI0YOtHVK+L6B75Sd3nMwfZsTnnhOn7aHuYm3tkStsJ1rZyd0Xj+nzygU9A== sig=Du8Cx98ANlCYBCpaSONSGTysqMXVbQGwn5+2kFHD42mPQ/LLgCHMrSRSM60w+iuSXMmUqR+3c76Aw9xrIAY34fLu+iXzdwFZOKcVTHJVX8yVEqEPd92YMJabSwP0qgItTkSxVrspdY4gN21TU9eLAS8A e=found 133 iterations", + "pub=MEMwBQYDK2VxAzoABIOBKI6T2ukjf6SnL84sD14mSi42ITLoua5xmhXtPaB8J6dHj0UGRvRpuH6/JSPKa81LT91+pUiA priv=MEcCAQAwBQYDK2VxBDsEOS2XEb61cjC1M9p3zOU93BExWaf7Xp87qPVmejTx3kAs8oJsjFCz+n6OI6mNqABHpFfMmmqK1S4FUw== msg=6hWW/lYxEmxCSyVDEzcBU4zxm/ZxWKtVfWFSxE6g/fBNa3I7hHZZK0nFNP3LdPFUH8KBm0YIOHcNp4uTkvwfXA== sig=zlNgkD+O8Tb4PqKVL7UnK0tZ/KkX/EGtsMRnj4R/n/f5AC6Srk5eefcNupKdfsnQySQVZaMI/niAvNTw+3EAVaE2uHw0zDl3UPV+UhzJu7y2KOU+/okBwIQSsQB5FciByt+Tl2aa/ZhGS+4wxGjeeB0A e=found last=18 s=18 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAM90h0YKMGqbcXNmpuy33e9C4v/q8ePlLjR0NYPUV0z7Zl7NQw1gQaExBDtp3sLJWndCGeAjmbnUA priv=MEcCAQAwBQYDK2VxBDsEOSc8T62HOr0uuhP7sGZSvO5cfnc959xj1ASaJEqcQ131eHkRIhc5GkNBZnFGkMcDzzGpTcxWIBZVMg== msg=d4IyOyzCRSrfP0loFW5yXl94XqtwOTgfEHYVS25RsG5+KLAfk+Vb3IIfKStPFXeGqlb53FuLbUTKPHHto/2mug== sig=jNn+j4rJurjJRc33bXjWYn6Tj8gFfKKy0pBmtu3najAUOEG3kvgLNsZvwttH48n3/KtWoj3nn9QA3n1n1fuwv3qDB7outxljnCmD4i5L9OdK2E07NK8PHHn9rlAXgVQ2Oh/QMRfZXaH9yQqFej7dxikA e=found last=25 s=26 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAGnsoTpnLaeItrD/bjhujrYVtFMm6NEa1A2ZdfBia2R8IQeGbvD8SRy0sR3UNvZbAdVV9CMi5X+aA priv=MEcCAQAwBQYDK2VxBDsEOS+zBj8dtkQTdLTrQlaHu4JRNZ/Mks+x3/ffEA17/lCOpjWdM4wsP04ShSK7XXjoWirzifmt0FPJWw== msg=2rzwsEgTDATs2ymN1BP2BvcJZpo0IkhqngwTUvOkHdT6gDZ9gGD7kvtT98zw79NlefcL87J+6VyNANuwU8BRFw== sig=8pKKmxeDU7ZD/JeMTDegx6B8cFUbYGB1Ft8SrP7DWNXCZF3CZHU5bgG5mOb4LGMfxaVsYMAPRqGAk0xXFZ/jz6jwFXjbTV8FYWmxntmnW0On5LlWC2KNIjTLdWtqortOtQ7REQAH3F5aJD2UeQULUxgA e=found last=25 s=19 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAOn6C0+MvF3gJMDoKMYYGjPbkCPoXCC2rX8aY6P9A2QQQtgE8Qg8F6DxqHZYXg4mS8cM4A2GT/fEA priv=MEcCAQAwBQYDK2VxBDsEOdeS0DksDiFNvZ5m/04b4CVCTTKMRHkVgsHo52xkTwmBD8Tp9KymN7qt/oJATUHNFi1pQFfzk79+wQ== msg=blYYtq0XJcD2ghHcBXYKFeZSR5zKRDQ9vmXQDN2MYzNVLFPB3/m1DSCrS+b5c4WFUnRRLvn9hrPdOgcG/cC1DA== sig=MIRUxCMlqhGBHMmDkNxP+zHrOZHuwR0QUqQpqwQkuhFKDtocj15qvkO1oITPP1ULKMtaP5ZBgQGAWgTgaxZ5FtJQC1hSHl7GrucKI7TCYgvYg6MeEIyboMQSia7hgthmD60VTuG8GAqZg+PNSbO5ygoA e=found last=15 s=20 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoASdudRv9bm/GXtWb6QhAL6sD4luG8N60S/QuGXK1dAwJ3fjtRVQz7eK1PQPdUWEvDXzBYc4Z9YWqA priv=MEcCAQAwBQYDK2VxBDsEOSK5Au+Dj8vtuKF4efB32gdIUHlI9Uy1auHtwxRsL0/lpsdeFQITYFoKZ3FDW67SX1Om/v6YI7hVHA== msg=vDpgY1xIZuQ6T6ZfRrVrFgCrxTUKkH6naWzazguJMRsYCBcChzrNwf8sRCM6WO+nVWJldaezUifCE7aWvJf9Eg== sig=W9En22WufZsQyDvEKqRtbIPyKVeHgP5Jn1pk/OgXM7BqEpBq7ZLIoTZ79y4ciqnChOlmppkZnD6AWqJ799ZzspWFiKfrzmablbGi+uP24kJ1H+SGmdxGfJJpT44jY1dZEE8tTYQJwTuyf3f9xLLcpTwA e=found last=18 s=21 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAvU3IUuPi4um8sJZvsuO8eSG6WETCxLHgetjg8lXqJMKdeObSs9v12oKe8zuLmE9kTbPj9avy6AUA priv=MEcCAQAwBQYDK2VxBDsEObZDJ0FaUJUh7Srt93QHZmqUUydYKeW1YQeX0B40dTjwU2SX2VVnP2t4A4y9934OhOOr6TslnloEEA== msg=WrLQ5DwVuIyMR1jpegk98WqqqSLV8en0o/vBkb+qqiXaqMKTmJSg1SDGulNmfk6q6v33ZVCwg1zKcQQat0Emig== sig=6gMy1Lqkbv1QJDPgnzXKYGillwA/FVjqqDbkml+Dul/mJ2XcY7UjAvcModB+oYxeaN/bP5GihGcAq2941i0o+92D6EQNYAYOrGPxwCTwhYyGXUNVgYryOtIc73shc9Po87OMXr7A0w1IlweG9GhooQ0A e=found last=14 s=15 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAA5QPD9bmb780U+UKedVsd3qTyRt+PuWzYgsB6r5/jbwvOwVDBed+KF9ke2waXmTCnLRV0ycUneSA priv=MEcCAQAwBQYDK2VxBDsEOWrTDqWPtuJ/u15qYFd5+gf7vc2zArRhB1YcZBZAEy4eVvs1kPAL40M8Y8GmcI/JKF1fwl35KMqZdg== msg=lyBoY8GGj/ppKRCLXmXUnwrKcG9PvAaEuZ04ugeqbq4gIpakOagRClJv7z83g6mo6n419USB13+Om3Uk8LSeqQ== sig=7cvyaTv2pY60lx7p8cLj7hcC2/TnL3PiRooP+NFGUIZ24A02rMSDlb6YUtBCFUEijW1Eols9GjkA65jZuTfH89Rb9Y1N+MXiqJv1egtt21KQJVnqMOW6drHD/t57HLOqfKjv34MilAst4t3xeWXPahAA e=found last=25 s=20 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAP62NdVoJ3t7+mtmN+ouxiaChHXZsX3XA/UmIe5AIBsc0fwiomMn1qCjPUMJ2RUmtcIYkQC8Y0POA priv=MEcCAQAwBQYDK2VxBDsEOe52M7an9qgktTlZUJi3WLX8UlA/b0Ar8DD8qYoesAEoVy3cwrGW7OdOjWkBwNc3sNXv+RUYmG6qzw== msg=cigHzGa9wxsvlb2fbi8k1IcI6QO7pQYNPvfzRyvxRMwdc+EKfFPL949i3hjPP+Em2Uvpmj+tdsJCadQ0/YOeeA== sig=vsn1R+jpPGj6zfcrcZLejfb96GDK5A0/yBjUeaHXPBZmgIhwaaq8JqJKgHC6ybxujnfp8T+mFgQAHB/nLnchPQbST4+xaLkcr6ysdMmLVoHLI5mjqox0091ySadZC5ekfg7pKWCIFcvUORUMLt7zWjMA e=found last=17 s=19 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA9bHa+QMevZozcVq47QmgsZlCmUxX0j67KuvWVvEF0Ok12N5AU3vQs8xgWdA8z5bx62u2VjdrJs2A priv=MEcCAQAwBQYDK2VxBDsEOerGNGevxYMG23Fby3XRXi1cliuGS/2+vdeLgDFGoItJK5Om/ELQ7EOgoy94odJFgrJlvO9oM0Rhlg== msg=jWS9lqdoOMBewp3HiKiRfzktgpTswzy1M11EOBj3z9s2IT07HpOZNfwORy+HoSKqRDGXapAGc8tU3nFZwvzGOw== sig=a30C3AVOluIXZsJAtews68JI5+bCDmZLIGwwkoP7UuQroycqwexF84knDMRFhbd+iNdJsX4BhkuAkG89Ycg4YC2czowH9WmWQMk15FJBban9bc8wqUh6cwde2Nuri0v4ptnnekzWU+xaGwEJUsBQcj0A e=found last=27 s=19 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoACUTCL3z2dIFnvj9KaUqPVbyE7j5eeSdbWBAoK66yXotxQZLF72qA6elKfLhQQAokpCsDXfaoosoA priv=MEcCAQAwBQYDK2VxBDsEOdiR9SC63C1WEGXSvLXDsM8RBd5jKjt72QqgpVK52B2WmH5YCR+cRGGFqR+KHTrSHkBGEsulMDVYlw== msg=3/RtxM2i08HkrZ0zC6WVfX7ibvvlOcFHcLGfcDBlKS/iVQ500fvt5NXkiO6NljEAgXag1Zj+miJaOX1cBcV00A== sig=t9R9gGrdyoljlZUh84AHhbcWKLqJcqj2xo3H6bRDOzu6jVsq18ycgDp4SldzDt45HRy8UvjaqsIAiZST9J56hIY7dlQuiq6KwKPhmTyaObdp3/+v1hHAS72QR5GjTvQL1xKVKqZEU9ICYzmEwIQlwTMA e=found last=27 s=20 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAM9uKQY/BffxAFofPK8tnEO/ORnNcGIJglCzpq2M3zRz0FP/LU0KprkXBDHC0FyB/GfcQY7+9N42A priv=MEcCAQAwBQYDK2VxBDsEOYKztArfN+CrevpE5g2VMmRduvgKpc7OJJdhEQpOHxis4zwPFxe7Rl7rff7YQGjhYfC7sdNZx00W2A== msg=1Dw+by5vOgkiDlOEeWsrVg+f0iWmmnKPRNkTyw6Zd355muytl5CQsHct5zQBPmNiQNchrDGAx+rAnT0vRdiC/A== sig=gM4ii+c5F6396V4l7JIBmqpct6s72+QUl8vYlHfu225vwsXstgShLWKPOOJX08rmUNJiiaNpSYaAn4YXhSHW9JpzHcpzYjWh6WeAHAAWtDOgGt/J9aQzzPRqgzoPh6nTdGkFaZ4He2yTRCDjI/P8YAQA e=found last=27 s=20 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAPU4d5bVOeverX1You58LBAwk/GTMKDNuNQYv5Pmp7g8seosTBmOtX6xwnR55wrOz8hmQbBuyeE6A priv=MEcCAQAwBQYDK2VxBDsEOQruAVosxv3kGpQUw+g/WDbTaU+rEPVhQWMt4jwOUsrzfRgZZ+FtvZbUSiUuFP0n5hzSWiHkL4YM/g== msg=fFxDLUoS67yA5H5KuRyRtwSBsSAzHx5NPuDR2/JekXRzTj0dVHvzSVHa3wF9pXOhqmysbR9JCyWYBkeD4jg+bQ== sig=h0Qq2zYU7EJYmeOZwChFiwmJqnguNZ+oPKEFBqOSGoXl0dE0mQ+Klk19E94eEQFiFG4BT9RI2rGAvt9cJxJpc1nkLNBso41VTsklshi6QuVE/R+S5I7Zsc1rc7ylXOCSLD989vin7vNPeLwanxAntR8A e=found 131 iterations", + "pub=MEMwBQYDK2VxAzoAaoQ0S0obkyvLn78vkuQHwjC8KPfBxDKBxUj3HZFU+4rUUmDCE0dvUVLDoK84gcsCszurIZU2iQeA priv=MEcCAQAwBQYDK2VxBDsEOc3aW3Sjp3wDvutVCosueHRaNU07Q/gGzzALvHVEcOY7RGQMxeDvuC6cOVlJ4rXqKenaSZw4JVuJpw== msg=rLjOOn/OOMWpA8lkEE3wzSLS+ok8dt/5JrM7W2AG2PY9jMTded8kbfQUnJHeVe+Y2ZeGHB5qj/n6SDRG9JQ2fw== sig=bSV2g8Egw4qiOEen3HaJxEXBoYIXGAIOMjI6pky4+edMGf3N4Z2MStLx1a9szkLOMUNnwDgAVsaAE7+zZp2FIFGOT+pBqor93UifYqnn4y4TlEEeh2Bow1lOFU3h+MnwZ+yG/8Ey6YJgU+am3QI6gRsA e=found last=15 s=19 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5nUvjYoN5KT29B2CBIbcNtHorWa5Qbv7bxrl8LgHvNxyg9Y/A9wz9jkIo46s/0bFGFZ9kKRr9/6A priv=MEcCAQAwBQYDK2VxBDsEOQ142Nm28prUqmaB6YAlJyxY5u2zWBbEda9g+PwfsML335eK4hQuhFEMRhM0KTjn4edjFcU13u6pNQ== msg=0rnECeVczeq0KlGO51w0ePCwY7kjGzVLNBbQ4LuIJZucAVGZvfwjQhBV+ShmjzvQ26kU7qvKtSUlDZsxd3Zb4g== sig=w025B60TnciSs06FEY80U6nLtkatKyPKSSn4eTZFiKuRrrKWCAqaOs69vU3jfN4AaFFHzIhLmcsAtZEDjVNxL93l3RfcClDXLg3zKOg9U4phxrE5mByCfcR8NeQxrmYeaWul2D3r4zMuQofAmE8B5z8A e=found last=27 s=22 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoABsZ4UdSHoslERKgOPNg2KZ1GFYpC9NSfZrt+6NYdyZquVYDVq92gD1bFRFFv4xvlQNHms5f+dzSA priv=MEcCAQAwBQYDK2VxBDsEOchUpsloA4NKuqvoeR8FoAeLuxNdxMBUg9M3pgs+4tqwleWTS3hie+OY8naxiiApIeg5jgOh5hvPEA== msg=YuwaXDWtH5S74B39GOpWg06NTOPN9WMLhWbZdVQcntRqRue2B5rtMQyRjgIBenzf0nnX2KpNTkwWihf75q9row== sig=svtVcUtLO3Uv1Ug//ddYmVHMW748vDh+a7/DFZ7zXkQgcYOgTF0LLGX0IQN7iDHwe8pc8Bh6icWAeGCdhjfHfMVZbGj6i0qwBgtLqJZpG/ki98v7UcwaHX+fbOZMiGI764x1IFuFO+5BpmVFVksR/xcA e=found last=26 s=20 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAsv2ShhQeKDRmrRzKq3BQRqIP6x6w/Hbgt7Uk6IIuikiifLud+eCky5lV7J18VS6CglmqqUEqnIEA priv=MEcCAQAwBQYDK2VxBDsEOUFSslV7ggEr56xAROHR92lMN8MvBuO5cKginmMMG7qfetN687rgVZGh1mdbH2J6rvdz/98VkOyCOA== msg=y/Wlz13nsWKAtZyLhG5dAVLfBc7sPok1N+bVgza1t7O69Ql3UHMD5uaDUh8dXaOXpCebE7hzWeieFG5/1pOWcw== sig=7On8sPJOqrEjrklwaJ9lNRPmHeCrJWwGFuraWioYVuS45MHeNbQPEYXtXOYgd0sSvRhYMzbEKvaAHZiFNj2GHP2abxtZE5ZedJYKf1Zk7zWl0CTwBvRX6hncJQFXbx1ifEDC7r2+KFFPO+oFl/dYpDYA e=found 204 iterations", + "pub=MEMwBQYDK2VxAzoAkNybpV3N6UgetauxZAKbrc9WTZvr8ovfHivOPh+wZWJu/Z4PgMIyyWBGQXaTvJCcFZW61zwSO8KA priv=MEcCAQAwBQYDK2VxBDsEOUxB0rkbbOxwDOHoY7OZ/5KF3TiT9AcrTG94t8in7O91LAFkKOgjc2lG6aGxQHqnlOLImrMEcwu+Yg== msg=59KA8afO0CfWeH7zCGkHaiAFqraaNleSDqxRc9J7JIspWLt/nVUXPrfsc3p61HgnW9INwluEInzlGV3dBosJiw== sig=cGw2OF1gX+lCZ7h9rkNzKpYwenL6lcXs+apmInN7RSERUrxjk6FcJJfUssyIg1M0bebJ1Jqy5oqAstMp5PBSq6KZM61VeDDysmyQtpSQPO4yd7mfBX9Su7lyALLda7va7/GsNg38f4pRirp20S2qsCoA e=found last=16 s=19 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAtLkEQXnd4ul2e1hcYk4xqKUJ1kyOZBVB3AdECHooxsUhOk0JC+dc8ge52eKgzUu21SaefqUH8WMA priv=MEcCAQAwBQYDK2VxBDsEOcU6YUcWF4d6o1XALyNljh4zsuMcP0YpfPTxkw6h/NheodtAFYo7o9nhLe0rhfnmW3GumiqFQaChHA== msg=xMBCUChJzDd0M/u7CjEWCY0eCt2YiIerM8JCjdyxyrhr6nnW8ak53TrSJ61OigZrQgb2zEWevz4jcRj0SCgT1A== sig=riMTfCD6VazwZJO+KQWB0rBUTXgJ1+4mvJmWFxFpNywiDXkk956YZZextwLEUojISkd35Ra39NoAR94kqZ65VTiBzkCaF0qZTTZV3VmmQWmfIhkNm2n1OUIB+5R4wwfjbOMc/RZBF7fB2DFNQJrIJzgA e=found last=25 s=19 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA6AYGroALN1XFbI708Z6NR0OD1YbLsyUwpNBw9Kxf9yl4LKavhoatAzaf7KHau0ZVMB0kG378uIyA priv=MEcCAQAwBQYDK2VxBDsEOSOUXRjQcPADklz0O6H6TN367N4YlYSULZHVDbWF/qKOtzyFwV9pqrMF4XImOz9B6cc805QlV3j8Iw== msg=y4N7/f5wHAPk9enhXlAsRNepZ4oVZT+VchTzQsnO1ZV5M9Cwprow98DJ0OFSNSgMbvd/nBuBsSXnx2cdReTzag== sig=tA2BukKfpIhVDBHAkO9O61Zzd64hEqfWHJ1hFItccCIoJAy1QWJobWHN0ttz6ac6qcytU7AM0j+AdkM3/KT8zNvxgFPdNN5eBBCQmi+2o/D8pMurQgR2hS/Zi+dvOh9z1AaNW4Fh7U0ulG1Kixd9TxMA e=found 208 iterations", + "pub=MEMwBQYDK2VxAzoAfjecVKz/BjWcQztaAWDr8rH7QFZ7l/7leEotsYa/68szlpiid3mVF8d5L4QgCAsdORCYd0KgI7AA priv=MEcCAQAwBQYDK2VxBDsEOXQS3RA4TxqIjQH7aFz+qadhz0YmCL0nv2GcbCFLxA8uDrqsiigHEH1gQF9NTVJPxtd0WNZ7gRIxYw== msg=uxUqFk3n8go59R+/e8SsdduTMy0IPVPf/3khmRqHU3ivxhKL0F6EQcf8OVySZH/M4/uWMONU1MN/vUC6OM+G/g== sig=VWeAgEjmjuol55iH2flvs5HOztqT+YwXiPtlCHSIZqREjKi/gZ80/gLo76SBa9JURBCyLYH4IQ0AHzBI49uOWN1Al+anG1UUM7Ngu+TAVcBRTQRcnrwU0m09b2HOyiBAby3mfJrFBX8BILYhdmSmLy4A e=found last=25 s=18 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoApipYyOO8TkJpArmbwTsZF/akQlFBqJSskF4wi7bZfceG0H9mI5UoOgyjzwv73B4CCvqt4EfwT4cA priv=MEcCAQAwBQYDK2VxBDsEOQcF1ACd5viYCz/7Q9vjrbcjCiiZj3sI89hAd0jb66AvBdGw1WFIRgJ8eItJ43J7ykbcKFSaNLOZww== msg=hOI/noa4Ti4m6UppD0dCxjZrbn8Lk7hNN6ub55O3RNBKg8+ZG8WuUeVxeP9qDUMav84dqvlg/Ku4Dg2eZSs3Cg== sig=XUgWb+Aoi+oUO2qcHhdZ+9jZ3thw7NtZiHB1z3hi6fYHOQpBGgBla0oiK3O67Y0D4X2PzCC9X0YARVqPBdUuW5Wu69ufwKMmQF98t8ze9NQn6PcWaNVCoB742I1Ui03LapGRF5vn7XdwBJJYtSvcczAA e=found last=24 s=21 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAzVRZ7v/wn8Y9x1C1lN8w9Iz+oCygqgT4YN55ps31UttjRNWJG1dIOKml5fIv+tIzbSx8QhzX7baA priv=MEcCAQAwBQYDK2VxBDsEOcJOUeub/sAPmW2fE3SFypQ0C9rT9ljqORB7XlVcabYpjAg7BZKfPyuHKirtVY+7ojiX+FbyATYFRA== msg=76VPn7lWSjd8OtLQeBUV6oraiTKCrjxoysjt4Q3fW15E8Y+i3S7lLJe7YcFz1JGIpE1T63RuqDnRjbO+YIoL3A== sig=1L6Ce5+8xZjiAIxXqV+UqtczOzZiKqUOabMi3ngC0Z3zTy3Tw+qY0ADfS0YDbpZSjQHc2/HumYYAGXStskEf/Cc3WSqtopAa8zCrcI7v33RKZwqsfCN12k9K3gWZCa+VItYkCuajx+yyefyyTFIb3yMA e=found last=25 s=22 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAX/pFWEHzGU4Rb43VJurbz6C9nUt5absd6qeMNUypv0TTpGOvOC+wCXnWEu/1ma/moAxevLIziGyA priv=MEcCAQAwBQYDK2VxBDsEOaRQ+g4PU74nmnYusfcSxW+f1m6DdlpjVEjyNVBQgFeEDIgNqGJuOKr8QGY8OftR6dsb3rUrqsgkzQ== msg=XpU4bvBngboN1kkgBgFw+ZuMoY0eQW2udXyIjheaC+A4JUbLNDplLqPbDT4Pr0zDOgiYQ8EVyl66y3+K6zbOgg== sig=mg0SEYtRNJMwUKLbOUtLUpoObZ4lvEnvFXgly45mgHSJEZ3/zqqdwwgOF1JFJoi9XvvfrnLb38IAC/aJ111uJe2LL/280JxcEMzQVpcBc4atbidHXmD6+UFG3rSbsHWmZXeVIrhN3yeNZ4IoyUxG3z8A e=found last=25 s=24 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAj2Q7mNgN9U2FIamdOYtPg7AvG7V0vTi/W8FehRMiz+zjNo7g3jjjvHOIloB/Eh7uH0Ak/OFuqOcA priv=MEcCAQAwBQYDK2VxBDsEOTDszovOzfw2ck+zcMXMRZamjZm+0dn7MLOX9DdKZc72nffUqI6gwSnCf0W6WBmkrWnrw6dG9s9JwA== msg=xJcKnhivIcuCfI9m6wxMNMRqTA/7VAoCVyKbXAUocRVUlhD6jzxwWcUbHU/nURHwe/myDpHzAJskQEs7n1xhjQ== sig=wiUQmMTBoPyRoS0QH1k6/c+loTISJA1xU9PKQwxWMtVQ1613UOiGaCYsp0ioCjRsCWBSsffZZ0KAdjOTlcilny/8toGVrSckfFM6OzKAVK41IAb6LTqGKeb+lEgNRR+X0BYeYUXH2ZEmmU3FOBHSTCYA e=found last=18 s=19 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoATeBv5opvvpmNsMq6o2lPzRd4eRBiIJEAs+f2SwrdlE58F+MqSVsa12LUMnkP3JlRjZWYpieKQn8A priv=MEcCAQAwBQYDK2VxBDsEOTE47g+tg3u5ofo5Ek2jj5lP8e131yWcUqCgnVOTzDD8UqgHcQ+6n1uNOzf9FqdcMJp/sFy6vaFJZQ== msg=wuwqpBjTkwRHxhaRdhLAzYWyL6GyqUV3QVaavSRdx5eT9VrV/ypBqo6UsUdmHcRIRTOmsVn1OYGDmerzH5ntNw== sig=13Q3mSGVT4GfNHNjwueWfnsGsV+kIzcMUO8uTTvGDj1CTjOdFqmn84mdDv7VgiL3kYDx0pHxk/CAKseaaHW01CbbuJBQa3MmNgh2snQqr305uQ80eESuil9RA/cklDBoR2XurjIpZ+17ByMLiEfbxxYA e=found last=21 s=24 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA2lBs5T+mTvnWjjr4/CpEuYMd4tsoo0dgGAJBvs0Cxl7KhwQuW04Fgv96pkzr56qsAIIqBnNhwZ4A priv=MEcCAQAwBQYDK2VxBDsEOb4wcwZkGe0YhmjhvmJgTIAulTVXlSvIb9eInNJZiPt5rOBvWjQgEdTo1NUw+rFX4SqNPaGXTSGnJw== msg=G4/sYcfX9bHq2hAm0x2PYWpzQJyy915eZSfIXkSvcImrmDKTdiMpFlMm2btHAWfdiSgk9oYOH6+gD6e5mV3aHA== sig=dEg3LcAC7J8kiUOBOesaU66CXozk4zmY8jj+xUGVIcfpLL1sbyBRAglVRVIc57rMP3t5jBW8JQCAqLHIPp3uLI5M2re3fH4ao6DM++c0KUDThZZ8t/cdXtB24XQHgUW/tJdMw5ZnI4mm3QEw2a2XtTgA e=found last=14 s=16 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAZhP39O4k2LC300p5zC601Hxjjj+CAWvhnw/qkr4cuC21fwRFvfyp/sD8KZLqLSlnIAv0eASk8pWA priv=MEcCAQAwBQYDK2VxBDsEOQikIHocnvHYHX0pY51CdJU3a2HCjT3pOLO8yGfA89iCsjc+GHEmaAIN+2rcCpWjJB4Ghd1KxGfU6A== msg=MBvxlDltsIh3+bz6Z4szhCyhVma71Heh+FTQQkJwO5iZAfArOdlWB8WWCp6Uie4mr9eZcs696drfZ6cVXl5EpA== sig=/miXf1RdjO0fRI8Gr16H66Kbs6ZHl4dadXnjagxhTbDmzL0fkkYUXu2Lt9LGlfEGmDK/9Bwn2X6AZfbD8qaLTm6OH/cjY81aT882XotRQNtQ1E0iUUqZLvB+zEzUGpghXKUSPJxlO8zYiCVdQl18Fx4A e=found last=16 s=21 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA1QKDsV75/Zxy5/eA0p8/xX+dWd0TT9x55lNmEgexTWkNItKtayu8o/AIIaRhzGvxJBrZZJmIYBUA priv=MEcCAQAwBQYDK2VxBDsEOUWAYUx80XwigPXTeH98ntuQcWzYMNqEHbaw0tFgRo3LqM/bHZoEA/mIku97nb4NhWcR0HeCn8kvhg== msg=+J0WEPdFMkJrJZ0yT220n/R4omFKuqtV2RmwGVxafRkIBsjh4m4SfB21Mp8g197YJzX9IWI4tBsXsB9wBi/rhA== sig=pmwFGzY9xRIkvhrj2EE9yRL63AMDXETYjJFGdPH+NLPjRq3d7FMNJit8clpTLTAxD/267koi7X4AeLGyEd6r4fuqdOHyZmS95QnDkeq7pcbm0AIo98ySxHeA4RdaknIoQftQ4j2dptuUYXDfPnGEhQgA e=found last=23 s=26 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA5CAygKt26PhjkD5+AkcDj/2GRAYrYoPgrFNLHVWBECn5gD7BGL1NodU9TAKJpUj+TjBJlLlUS/aA priv=MEcCAQAwBQYDK2VxBDsEOYOKfPdNsyvdr9ksCBjcMQG3g+FIqE+xsyKkjS3U2oQyLoG1BK4fRJAKLpOfZooH0uHhucrHqnWrDQ== msg=+f+Ekucd4hagIzEZAHZmOkw6a3B3SHk4lG5rvt335gSqpeKKKvxSgpCZdgcbbN0gFbPk6ElsylxoPAHuQK6bNg== sig=ljuh9fpeqm2r4jTSU+jOyMTURXILPMfdEVorLbCHW25Vel7fh4bJcgjmPTBg9WBut4xVD0oE84+ANaI74TLD+YmQsn5VS63bw5xdSTu3Gt+Ni12GJUlvr2rrX+pPnwBFKhoopgfWSUsyFxvaJwQwhSYA e=found last=22 s=21 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWPWfYO7rXtknaGzq2/InN4sg1Q3+Xtw2s5xDd4745dg1kwm2sKz+ECS+MAUTLvSiZSP2fPwc7JUA priv=MEcCAQAwBQYDK2VxBDsEOetx7S8Zb9tsR3qoedsAUpiDcahgYDKX0F48OX1Q315r0UM4OYU5FnmrY3anz8d7kiJz/0moKqXjgQ== msg=L/aJxQGhOg7tlT6hCpcZ3i2qKiKTegpSTgk4IyQDLg/1RLfEIgwg4u8ToJdbNf8v2BydRqVimpnNjnOQDD2+Fg== sig=3OcrL4nCbNaJUG+rWOzoNcgHRzUtGYnWKYYmxEYvbHOAnvUjc/17bbT/S22M9V0BIW5/KVcIO5aAuykSuM7fUhPIMTNjXAcLMWbxtb6BvUCKTvHIuKmJagK9TdvywxfbqqgI6e8FqQJ0LzgBvNkUngoA e=found last=22 s=21 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAe5pJ3Xt48TaLJxn9d5fiVAErnJAkwjIG6dscXBalq7cBZ97yLQ5RY3DD/ulds36PUvQigBWNKPuA priv=MEcCAQAwBQYDK2VxBDsEORxoQJthrt2USmuQzQntaqP3sCKyUJgfp67MEm9/k2FmX/IMYm07c+RxuRxDwe9qugjoDmtpVOIi1w== msg=u06bj/0/nPc+vXaQL1xwYsHoIGY39dZEZC+aOSrLApkv/DSjVNg9Fdd2keTn7dUywOCyvnT2TXRzsbCp9gLuXQ== sig=bQ/yhubL/fBVTbMzW2tbkLYellhnyKjX+SsIsufcc0nWPcDF50VYdbiXzZqA/zjwu/wJaWGNJHSAhvZrOzPKGvWxKWWyvb2gzjNWJ1vdlz8MWuD4VL/Y+iBYC4GCSF5+ApEQdtaJsQlmojOUchnY0xIA e=found last=15 s=21 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAQpLE9fKHta+GDjKpyl2z1IJ6i6cy21MDdKns+ulh+kZyYVxa7/DqDZFNru3cxXN3caiJKPUfTBOA priv=MEcCAQAwBQYDK2VxBDsEOUExJ89RNGMMaMnRPMz1PwixamDhYqHVRkk/kvycayZSJA2zmsa4jiRr1GqyzNCuwrm/HV8jgww0jg== msg=tGwsQn7oYwtbqSZy5qOmvGCaAsFWLJO60g5IvOn3jg39cq/tZEtMSA1WL6K/sPW7h737aEJnymCzZuVHwzVxag== sig=uAHoswgUVS6EWkDzBqtAkZFRU4OvA7o9JVq50nNz8f+ltR2KVJLw4w8qKHtfvK4ZNCRpG7w9SZUAyBDCY7vqEktxvuVvtMnrdHO7ucoRLExqMTQ9t+AoF6YiGGPrrhYcPenwwTbtiXYxrz4t8EbA0yUA e=found last=17 s=20 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAz97ilD74dx7rU4edMiY4hgcJfk5LkYES9K3FioY5ljaaGstG9OfdNz7Z9LYnxcJZjwOtsrbIFkmA priv=MEcCAQAwBQYDK2VxBDsEOQsObxJrWiDhRzuUr7YXTJDMa4gO/Sz7IKsxOq5l3QQ5Gnd/Jrs+gLELlChWtrhJkCTr+1Mu4WrSaA== msg=qqp9Y+xsWEz5cYypy2EdST6Kb8znkpWFfOpm14hj2WZmQrGYfKptEhDfqBy9Dk4st4uj9XGdiIOuwZ9MWHnO8g== sig=13USar9R3byTe+eeuDuQJOJWhySGHThWXP5GOqsK7osm4c8QKlF0K3l+cqbX5j8j82u03w0lNayAm4mDhLdWsQz3XujUx/vGmBoTDXyQ6NEbkBD4133r9BWiNAEGRWI7WaV2Ao2ZrYIkerLHXtBHjgsA e=found 132 iterations", + "pub=MEMwBQYDK2VxAzoA2YqbXnEttvoJd2ixYFzoP7SPF0ANc4rWvXRVB+0dj0xMxm9dUzpo2+KWAfAvSO4s5rISQBytJtYA priv=MEcCAQAwBQYDK2VxBDsEOa3J3SwPWJyKBAh0duCdikJmtl6263vxxjy/2iYTA7yb7xYYSoi55zPwHvCZxW3W3WsgZACAaDHAhw== msg=nr64dHeciNM91W+3fwvtFYe+leUW/IEe0rDBvpoqhwb5/g7QHowEJRQTdDN5uH6Ua+wOFhp9IvmtmEcMS2AL6g== sig=jeS+N3u433ybIFMaMLEycARNxr0AtlImExAJ01nNWNvAJkh7z/IYmNdzW6ZBxufAEba4e9Nb5ceA+djZcsf5dGu4WxNw2ikDWuMwxMqwEWdcwaMrzx2E09DRIAOSyByHb/9UqpjH0J9VxIOw4mUH2zoA e=found last=27 s=22 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAXKUwRys2h/J07gjpBJp1ARpTTpq2yYNjzDcJZUvcXWT/NEJH2H+Y4XKdnT6LD1ccUw1wBb5voPqA priv=MEcCAQAwBQYDK2VxBDsEOas8Z+1zfLogD9nHPySQ7Y1180+XGLlDPlPwysaZ7cLub4L5t+lZX8hsOVQZaG52tj2iF9wB3BMy8Q== msg=JTcoJ1dTNoPdHko0CrvPfpJP1SzJk7WkeFkToTyaeC6fRSb2QV82q4JgVeKp08AW9Y6vDSqpLvS1JK6mDJavzw== sig=N9oY/Fw/WDGgWaMumG0ojeoKunzpGe0iAhEIDt36dqfwGqfWSW560OlVBBIRhvta8nXzA4WpDoiA2A3Fw+A6LuuGPlSHSxTRJMJNPdwk6PHpB//wNJLQajq4CQd5sISxbJliqqdisDpS6HW9up4BOCgA e=found last=24 s=21 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA0nbQCEIXVQT6XD0NzjLqGCrGSqz4VsLTBlYZfamxP4wClQpg0L2XIHRAK9urceRy53KD6/SJHgWA priv=MEcCAQAwBQYDK2VxBDsEOeyLILVkhtlRXDXB7188OaU/BKwU+DAf4Jx+l9nfJhxruNqTDEIkZalKP0JgVvWlBejsG8jXoLMGag== msg=vcJGxQbAzJ1KQHQlj3cK7FkhlNAddRRhTseTwBW08wpt+w2+YzQmf0pMFmgU9UkJk3BunFZenqwB4gvqRU8z4Q== sig=7xav5nE5K3ya3JVnLM+p8w+Niz0teM2qy7mOr1dXKjlyGA96vewtZp2Dh9BgRv4O1y2flJyswOaAGwFSXhA0fQooMApfSrLNCPb6pZfkV54TKR8Rl0XG3oJTu1Rcf3RO9RyYHtj6JpWfl1orxb765S0A e=found last=19 s=21 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoALPmhFKEWYMKLDg2H0X5cPTrtWNvfckrvsHHH4DdI8YijlenqqMhjROP2zAXBAUvh8nbWRscGf4mA priv=MEcCAQAwBQYDK2VxBDsEOa37yoaNCfLngtNn3TsfqYJEFlgJfRCuAV6DTjn1x26oHddFifFjw6+MmTpr1A3FnVQnzjcFFxTccg== msg=13nB5q4zHOUvnUDrCpgjlncZcnd+uTD0GbcEEoMV+hUN/uhiIx7VsI8J6cas6DSffw4M+kMGFqFNbLo+a51xiw== sig=SVCH+zuf1i7asNN6LIc07ExHZVOQ+WTc4Y70yGuCBJOXBmSPdnRW3bMhIt7KpWDOpJJ+Lkg2mnYARLQQEMM7+4ILJbWPh+gG7Z7mwOnrt2Vbq2xsdRqbyrYxEjs/eikC9PPYexUa2F3MWHgx0ys9ThgA e=found last=25 s=23 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAH317rpqqo+jyBDbHFQg6nKQZ5R106gIXWKbUeaY2lPDZDCOzGcxaBhAW3OqT4ExwDDfvCA8DVkEA priv=MEcCAQAwBQYDK2VxBDsEOW5jViDp378/swnZP5BDSJ41PR3HKoc4ai6JZrEk06A4mARspoCJgQi3rpXYs3D1SC7W+r3C1WcNPg== msg=aIRoEPO4CNe1lZa+6mcZ5jFcv6Hv7ucIRA4OP0lxzg6ot9JuKjRla1IIaqgU4Af0SL20t2bY0kaFwpYvsoj49g== sig=lVGyAvp5rzpIegEw8AA/LhgKESYd/heERiWc08XyOJm43NEyvcArKRYCHD45LSrDifaFFWguLAaAaOrr+woFCB5zMlQvcNhGenrKQQCNGL8IjWv2digD3D1sRiz49LXNSA/eqtBoH0j2v/gjPGgKKw0A e=found last=17 s=23 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAZrUjOO3ZUT4nwN+wIIQsbesgY50ut15mArJqmHqXXORxGI/7aDhrkNSRnGS3frS11/M1Fpb0RAQA priv=MEcCAQAwBQYDK2VxBDsEOQEtAaaVQC0AgHtstUmGMhauByzGp/syy4fNSiR+vtVU0byANMWQvviAGvzKOCqVopjWVLAm/2YcjQ== msg=nFDdRyOaMTdahzj5pNt7ALpG5YYwkwWnaKBN9I2wi06/QG19o0ck1E/M1cYgCkY5AadtrSfW9AIJiZvsXZF8+A== sig=ODe76NNU3+PDUpU7dxh7ny8ijQapo38jbpA0TcIkpRKKWsuAMZ8cR6Xzm+7mOjYNFvZnLj92FHGA0Qx8T0SGbBKMSb/zjpFMINJwr4KsZsEDjZp0afp550hkKdsBusPciCm/uiOuMppWeJGbySiKlzgA e=found last=19 s=21 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAssCjhBKKHH1RGi4nJoCopU1gIrR+uVprKiD3bznOhDt0RdTA4ALIw08cK9i2hhFdaFfC4+ADxYOA priv=MEcCAQAwBQYDK2VxBDsEOX0GnN07lE8pgbzzHTU2/Eq/2Qw1lgAe1ACZbFIt3M0dOzS+MhmA4eurn8xd0sbZ5cHuwgq3ptNTLA== msg=6zka8g+Aa3aZycMjWc7CFEs+hfQlX3a/w4ofrl0+WJT0Koz1f4E433yTHQZvT9BjI3ulTdHTIqKMZ3rGrun3jg== sig=tufC34N4C5b6qnipD2zXw2CIsPAMyolgqzZJZq6V2rECfeASwU65lEERqRkJUe8sHiYabSPOGIYAzKq0e2gOtu+zyEmOpoTzOFUQsN3fTjcJBngvLUiBHY1nyoLMe7kplSll4ZP9t7QtUq9ilf6aDg4A e=found last=15 s=20 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAeryWT5+Ipb6gnn8DbsIt2i8mMvYQvDxYR7IILHWeyV/ZApriof8BBZGcVBEWg1DsV8ZNuU0m4tuA priv=MEcCAQAwBQYDK2VxBDsEOQmpOCdpQ4e6puh7t46HKFPDF89SCd9yp29Z9EZoh4Ws4qF3UJHLI5NX0LBfkFvfTg6Gv4J3pFTejA== msg=XfraonZ5nWoIart3/OYvjopOr5OKeN48V+wvwiXNDKKxKamlPUl8VJxmk1mpQw1XUFNmvCF6K/XNRNNywd9dOw== sig=75AzH12gBrR/ihH0sKWK+cYemEvQwa7sYx95U3XJ2lLMS2WdiNBT6xD696NlZu3Z0bBpUqdsZ9KA2Jx68iYlqjnKceuy8VplXJ9M+iF/+wy3ASqezan16UZ7x44EgmIYoE5latjYQpou+XoQitwJJhQA e=found last=24 s=23 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoANkLhUJzNszsUatv8nO9Np9lO/mePgGCYZtS9Ln60WqhS+wjLTALxDZO8W0lKhY5Ga7e3AYqsa1cA priv=MEcCAQAwBQYDK2VxBDsEOSGTKkoiaKZgLERf2GtVahzWLRHIHa9+Xnq8X38yVm4SNB9INPazp3wVeKPz+cD2vNug+HFmysmmKg== msg=rBggMfR0g2OJhr1yiq6N6lYVwhztHACSHWHUACr5LAChTB54vD5xPXCZDmqgKfwsYQhZF1+g+N0/nH8Vqql6Ng== sig=PCuvfwuLpALO43oh/wt7+e0h5oBx1g7DuyfWexJVviPxD+CY2pY98xSMo8SkzHM+514GAr0yfIEAmBGpHi9HoEYYINbHhuk2VJM1QVTTXxt4OP5dvMWITvoiehrgu80xtMu1VRoO3O0lj/O+jnbiGjIA e=found last=25 s=25 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAqmD2YChCNHvGL7exTb1DYlAYPkSCvK9IjgUrhOuwh7ogX7iK8uOkKbE1YUZq2MW0trIiF2utMlwA priv=MEcCAQAwBQYDK2VxBDsEOdrpFt28maF63uIY04mvF8uyCxUlwMtlkYNEaoxJEXugNN0psWQWluJG0tay5nOKrV0zw8sQ/yraMw== msg=Uw3xHvnQA30EvwMKCjlXqXz3ij/4NINilTZnLzE0K9Q8MptS3OPR4d/QDwDybhGMCi8KeVxkruHrE/KzdK0mhA== sig=bp0W/AduUYIDHWyv7hK0K3Yb4oiO/G+Wq6IEFkQlC1HMyP360yYG5QhgOK4kPXM7R6L0zYafjEYAbMObJ+w1fbU8QfexlszyImqrdBU/6ZYqVChUO9T5crlJpFKKGu/g80sQAIrpufM6873/YKTBkCkA e=found last=24 s=20 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAFIb42Gu/ILxMIszdZSuscWlwDUZs2vcSy9FYv6sz1H30h/3SOZcjhjMzygzbDwDqIVBLJVWvx2qA priv=MEcCAQAwBQYDK2VxBDsEObe6/NC5yQfUKbVCyuZcIL8oWu3rMWgNffRkefNn45aJH3f2kpjYUSHiqOH1EBu/PfPq5uqyUjUMTQ== msg=QVb/MliQ3GH3UEpsGXuJnBkZHZc60K7pd+U5YmTKJCwoMaeuyZjvFJyYgnuLXh076fjQZbm3YdCbUlWIU0Lk7g== sig=ib+XTM5ow1CaX4nb17uLRBF6oiN30MbcdOOhEE1x2kFTZ49c8v5KCDgrLvAgV1lCtDMaNTAdA+gAfWEYj7UZkSEkDvR/wNV/bmbfNj4VmMlunTqL9U9MwhhUkTpGLACkQsv1mtjMWnnDPTXKXjAJaCIA e=found last=17 s=21 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAoRRGnhaq5qKGYXlqOi6hixSNKmxkcPasi4BiMmLt2Aj2mR19DusKSQZolYyj5fPRoWw53G3N9A6A priv=MEcCAQAwBQYDK2VxBDsEOSXhbKkLjT+woObSqEoE3HF2FdPSy+/nkiSGZazqlZOzgwqYKo5Qts/CDplgkOT5foCQHpYOMDQbtw== msg=sNAI5Q1FSwGegPPZmnwDfkPd4h58scy9KQokbe6Ff8FHZj74c0e4t3ySfq/pTKJJI8d6+WTltsDFmHHUmUlHaQ== sig=GDk9iAG5nbth6Ax/hvrKAaYE19ln3JP5MivrXcCJ1DqdPCseblt7GqqG54Vhe+BZarWaMLkkXC0ActuXNml+WdtjHBt4Qi7sOu/P8Iw5M7Tz3hJjzdckeTiNpMfL7y1fi9xgk7SWps1UqljmQ6Be5ygA e=found last=16 s=20 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoABvv4DraA1i3OJEx09auugR0W5QSRfuMeDCWX1giRvMICjzIZ9Oe7sLEEq32PD/GshUHrVarhwg0A priv=MEcCAQAwBQYDK2VxBDsEOdO++3Dcm+AxWMR+iLLWjdb36PgK3l9QVNN257jmShLSBlGuJdypazXFfunkNoDomjLlJ5NutqXC6g== msg=6aieb5wuNhM+a6hc3Dubr8njhh6sPERHUD094hEHBe6tU8JJwoXiEVo76uPG39pVthkUhxR1RmEmJpmTFW/xnQ== sig=NTw7fTxUNiM0iR1IuOMOT9zZcl6aZScsByJj1JOjYcvBZy7twgxIOsnsgjh4JCw8JZwjqoz3R/mA4gCv0giZmvSvvUXKIa2LRfdBNx6XkED+ve0IB+a1J1cHE32iJQDvGe70L3n38qWPU37bMXWUfCEA e=found last=24 s=19 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAx93YgZQJpdyZQdmPE4OhXa/KaOlinycEEtLwAumBlUit1ZzmQRFzwYANghor9fpqe17m2EyKWxCA priv=MEcCAQAwBQYDK2VxBDsEOZXNgy/Bpvej97Ov2ePMswfOo73+fSIfoVWb7UyBOUDj+QrynfQW6EeGa9scjzlLXmFZKr7+cWYtzQ== msg=4dhYnuy53X7fJz4h26tBXCs5UTbIUT7jIrAsCJPLrGssr8laSHIdzUuPS7QXNGyxVQcghfQBgo9QYG+nrV+ZtA== sig=bCEka6IC6ggnZva+Lyepq4pK8ad+F5aTCD4YB+WuCVDIZE7DMlVAKzCS3Erh828FVZM3DAO2TOwAohv9Z6nB6JOejQB1c16CV0ml0ie55up71g2CJnGLHfnyfuwldenBeDmMyGXPWrRDuH7dHlbKHTkA e=found last=18 s=22 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAY4kUnYO1y8o5ASN5605hC172l+tZx67C3M08n/vhAr+sbD5MD63Kqw31+6WijylaonseUcnIqhGA priv=MEcCAQAwBQYDK2VxBDsEOWdD8rRFl6InaEQqj0kXberF+KQ/h/kqdBpq6xKKt8vPf8tlmuUQTHlzOT4mHe1R686BO/5uYI17Vw== msg=PdvU143BsljYei22p7UUPIs8mTSnq+/UGinvd36E1kMPUoOFlQMz9btp4rnvxBHJfgWZyfTe04ogGpnXnkjNaA== sig=eus5SEU971pkM1bGE4jskA1kql40Xvq2D7BsTYOKfsJn9eWcfNbu3pTHJsYx9PHx4dW5DQsSmyaAUjiKQy4CABV9uj9uqNvOYVBKz4ctMqBQSRnhVp6/A18pz0uRoS1nmH+uXLo3fv6BCubEvzKWAzgA e=found last=18 s=25 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWW3vAlGaF9IL5sj5YIQmYASBV+2pTqKlTuk8N/u0DHjXYg3vIhAJH6MhG/JM1/BRcAH/BDGSGHaA priv=MEcCAQAwBQYDK2VxBDsEOcWmgcOMOrjiU2fkI45Yoxdpi/sDnyvWv7YqxZurGu8QcP71IDZxYkkv9Hzpz7iq0XfqpOCbyWS4vw== msg=D5zoTHOSGPpUDFhh9WL+C523X+B1TIDbJLFErdrYXsfGwA6oroQbhMosMRcV19SL1v7crQ9iLGpZDaTzrvUvfA== sig=3s2Cngvdf9W18ldyy+sve8R8ZoPJsEym8vZk/xtmNbOPqL/PwYo8/r3/IBAPgvWdvp3S6LZCmYKAI9eV9xDwhfgpXhO2s57Y+Bn014KS2itDwL36Wav713LC7zeW3bAVTMXRfQO1IPd1Vu8XFIqOxzAA e=found last=27 s=21 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAHUXG6NCzSezhQ5h1xKY8Cb2kMjqR1oldngvUsPKSMPg3u9d6vKm/bBxi+jCfR2H1sB1uGX2/TCyA priv=MEcCAQAwBQYDK2VxBDsEOXJjdC87Jn32ZQCRXFM9XASXhxhRyrpnFQ31YTPJFo/daFT+qZPorWTP3o8nIlK/y7Jpzsm+w9d4dA== msg=TpEZwQNHAKhoyHgKjAwsJp1Km3jtg3k5sGmf97dbclrZnj/YnJMTL3LY5SW3sOsz+FFiQLan8eWZgaTQ6Wnx9g== sig=rzxcG46Hvy7IFrX0jBO8435lnGNzHQJHN7ya1ZQbyqXC7thE4/+h86JLnZQYBt+ruURXxl4IH30Ap/pj2i5LO9dgqPStJwQz4AtHX8lE0+vRR7Dl4AQ6/h0H9R1RbQEgTGQSlko88J2Jelo8hWVsXhIA e=found last=23 s=24 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAxZAZ0u3SCDv1AIYcUV0rwBgD+eRWTBYUdVnKqS4U2vmVh2qQn5zlk7UqS8wxu5wRxMF+vEOVfjEA priv=MEcCAQAwBQYDK2VxBDsEOemMA4CMUopOD1b27T0d/jgzl7zqRiP3zfwxt/DXYsewqGlu0nqN2HWVoub4zhIZUyrR8jqTvyc5Qg== msg=05yYk+uDvQlsx5Aozx1i45y90jtqbTsyannw2u38UolReMH99Gu1OCBkJdT2Enkdl9x1+DfW1dxNNdQ538O4kQ== sig=hu/ZlLPR3jXm/uIhnbRBvZPn8pxJok6Wx76K5+hiE/CxuQ0m9WEkIChurIoi8Vb6NyGddzZgSzYA9CStj+Avvp8xdsp7Ue433RNI2KirNsA8yi8VtQUC3eXchU7lPomFxHUAhd6UNrN9+Myo8BoerAAA e=found last=18 s=20 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAnb9yXm7ff1oUocX8vYofqE7SKCUyf1O+4zVbNoVBrp4Du4Y2bEihmtlyHQdBKsoDYgEcPE4VY0+A priv=MEcCAQAwBQYDK2VxBDsEOeAW3MaAHkQEUZCuSjxcf+nuHoivqzYbNQLmrkTLtmcO94bQl4/Xe/8NccYtsiRb46PWfXRyWExRuQ== msg=XE+GPFQE2E5hqBLGnnyrHmXdCddqWmJAYirDsph3Q9t0CQ/d04pEfCimGcfZWlJidqJ72ANBUB9W13x+sXQbKA== sig=eB2fz5hH3SVRZNbDuzTa46MZpe+MhZuQXWkqJQhlci3m290zaF+Q7K2j0NbFGZNL/8I3tj7hXmmAu5Z/IqfMaHN2zGWFhgDHXd1gAAQhYhKfixpySqF0EryCIDPG3WRY+nKpS8zURN4FPfUH/8x2kBcA e=found last=23 s=21 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAEFIve3x41Nw0ihfpeE14hAqz1ei0Eaypy1qjEGBi/7POkwAyM3W1b+4Jnyqi+Te9u1rcvJYBXScA priv=MEcCAQAwBQYDK2VxBDsEOb1577MvcEjZLvkS8hPbmYEnokO1E+QLjW/D5AHCDzqPw3ZHTr/tDTypVmWMk/0tOX0Ez2HWEvFx9Q== msg=oMLI3Y0BK+5ZfCtFNzbRP7JyQHGlUGsYDZ0RDQxybk4B6uo49I6G0Hi/aR2QJ29opSWblajqkQH9BWszHO639g== sig=msBYN+8xNOquylJGm3DkY/YCmVx4kJLtzccse+rJDUXFWjIXlCo3TsxxbliDRFlSWUbGj7g7A1WA6CNhu1/5km1YmKZcUEH0pBWn0N4yB8TfIlM1HkKturaho1SduePrTn+DeXYK055gkd5qIHn51RkA e=found last=16 s=21 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAc954HYzbM1Q8uDt9es5xVYHT18TaCHTP62RbXUb2qMTDi9/lScAWm4UI92+YbBQOrsNnt8BjnZSA priv=MEcCAQAwBQYDK2VxBDsEOfHU5po3yu+P1/+rVKRa1VkkWLY+eSohZA0fXtV6tR698BkyWlIJ3wI9GS/xy2LHUweI+CQJ8OqSmw== msg=c+mEsbiiLh7tUFEvrRGc30X1he8GCfUaf7VunYv/SPSwnUzqsiUtwhkw7WzRuN/HkZ+NGIz1JfPgc9j+8rh7bw== sig=cZRQ0OKAURiBdYg5l71yNqt2BZr6ELmVRQ3kX1KPLheRsU49Zntd7LFmvwr+2Eh33eF+Z8aZrDwAU/vBRhfx23IKobf5+iIzFxeJV9B5A4oiwcC1ix6EZ7BDbPs4yuSfRr5oSGOo0aX/nuZKCH7KZTUA e=found last=16 s=23 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAZ0JpA9J7Oqq7AzYAY15pqe0MeQe6bbuLZbo8AD0o/knQsnnIbpex232+JJxN6BUFPxTzMwEt1Q6A priv=MEcCAQAwBQYDK2VxBDsEORsv18Yy7FdRpjk0ZqtaAPMuwO+Oq06pM/Rjfcz0XReRBpciAfuKIg+pa+5ydbDjPoPxlQEOnoqdeQ== msg=Ppza16EVZMaBKYgFjKVKvRS88JQDLYoRfyT9aea0e2UJ+P0hmk7QPxcd4Rkx/7s/MyBmiIUyA+iMeJTw392WKw== sig=/0OmxH+iKjwSNHjYhZgGVf+Fv2Y8/gYVXxvQK7uEi0xijv0D2zS++kHYRJBOMut2DLW5Z3ceMDuAfSFyyJ0mBJ8qGVjuPJfjA9nJWHNR2+QcwSke6fCFUENq3pGLCKAURiANHy3CvY3BC6/8Bpps+RMA e=found last=19 s=22 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA7/Ez8Y6usIB2yiPOKm0KJ2qvJ7ELRzv/LjbLDiWAgKcJ5Fc8PGMCUWWSqhHQCvZj6F84EMEnNo+A priv=MEcCAQAwBQYDK2VxBDsEOf9GuBVtGeZQq9HA1/97jzVRF1kEl24m3+1UaDLUlZUxPfpdLVjVN03TiuHtwH540mMIn15RH3j5nw== msg=yoaI5lmPni26xK/AIubvxzEK9qpehu0FSH+j1d4i0lnjcJVgT7fUR2ggIC2ht7edvKX9QOXdMvzqHBq613Zqhw== sig=e/XG1xMzAeYYJ39ccO4++ivlz0pKE7YDFxnnYBEQZniYoUYNqjHsMiKe3z23GOt10knc/ZZpMSoAf3NEvKi2KV/CJ8QjVnZiFOcAVgWlY42HnBZJypxlAQ7A1pchK6HrQLgKH+FhUvzEK+0/ER40Rg0A e=found last=19 s=20 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5RtmF/AjwC6Y7S2JC0qFZsa9gfItVfHZF86hCW4AccgOo+tVaDW/ErhSvy6rxXZS1JFS4FF5kQQA priv=MEcCAQAwBQYDK2VxBDsEOa3fobt48kggET5G0frtrvj7/Zf5rQ+JxacziBwmF3PNlFzFRA8r+o2E5nAm5f62N9lMH/A1re9+5Q== msg=orhdelVLvSNtA7u3zcNR+BjLLZUfq1ToFCXYieiAUI0DxFvtwQCvBLpoc29+7W8wcFeMk4yxSIwfRmUiOhKR6w== sig=Lcrd60dv7YyPCmBt66X5wRRzlPmS38Idlt/o9W7l4hdn1swuagkubVGzIxSFWAZG71l/25rFsg+Azle3167t8DhjmqPx7ElMJgJV+RQkn5p/vZRD1AuX5CurbkH/kqNCpvqkjDEyFUq0xrUKEiuxlDYA e=found last=16 s=24 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoApteeK/vmyCw9Oq86lyMUD+HwONXYBa3gaDM3g/yJrBEwWF4f0BW/y/ey/NalFKmpkWfCb7nDVikA priv=MEcCAQAwBQYDK2VxBDsEOWJdMv76kF4+euHMD9g1oc1MbgUnXtSRDd5R+trD9nWZz79X5PGTQ8R5VGl0MO67tRUCm5hj8PYkIw== msg=MLNsVEWTwblnBBu7ibjc6SzlZFLMH+CwcF3wmRvVSsVu3j794uKQpdSMDmkpAnT2ZTtlgZMJtuoHCNrkm2X5Mw== sig=81P2f833ZlpAyP4MEb7deZChtV672NpidU5wWq1o0Pruv0iPcWOrxBKjn8q3pRHlY5C7IVkdg8oAbzKj+0sf0248nlwEb9q5B6KwXFDPE04rku9MDz4eMObpuJTob1BiOGQa4a8D0GRidtK7QukgnhIA e=found last=17 s=24 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA76RtLUeGB7SpxMCiPpKlE+tAG59Qjg8DDIDrHcoTtSFfEl0/Pp/ASFZp4RIGiIgaKEY/e1RNHxEA priv=MEcCAQAwBQYDK2VxBDsEOVdLWGC2ynOjdv5tgeBVIOq1K6nENyxWabjsCH3LcEZYqH9odJ3aYdhul6nR/NQuH8R8UULGlPGOZw== msg=fHnwmTk8jbgjypQErDq0+LV9xud7YrBO+Edj6HaL8p72RPyosn34PHWm/WKBmJcyLTeK7v7TrJM44dn9YioWKQ== sig=U5MNlNHF3XauH5FQhBxwR46vaVAuaLwRMqSAeoP2Ujob8PM4ckoshkTjkn8khCbMvhBomcsflpOApZ0bpPcolsIZh4LZnH7czCElW9tbYuPvctJL3Dd6o4NFblb7TUg6S1B6g6uyksrbww661Bq/eAsA e=found last=19 s=23 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoATXQXxqz8PjC5Moa0Q4lI/gyQWe74jhkouUujwD17bhqTLHQjNRKEQ1+tcMANsW/SMDZh0J32BRmA priv=MEcCAQAwBQYDK2VxBDsEObqrvbTvNwwxE3tsfHSdqS0GiH+5AMprNGtvnv5+armMZdDGUpLrqJbuUJpzQVin0uQdop0jDfW0yg== msg=dDVsQ+as1HnbJJYHdvLrFBmvXT4z8wdY6S7TpRjvFPDrgOUZ63lwkSOUjqZVbEEWf+3GCfZaH6j/xiD1j239bw== sig=Trbkdw3ppg8Ghe+nCzNcbT5aSsQRd8D0fDwf6JlUq3167bv2MVs+1TbyL6dU7L6QHK08nlrulSOA6gz+jOVbVQFgziKwJtyK9IzxNg4NAEsQNkOaPLX56n7GmL/vUYnHKNIAlspa8BFn8rQol/jQ7xEA e=found last=17 s=22 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA4N+xId+Z7V9hq9ne45tvBIg6DVLOBCqyGO0bu2g/yomBcd1jd7oVA3vO4UQWBi0Orsz+TSZQJLGA priv=MEcCAQAwBQYDK2VxBDsEOf5Wa34ptSPIXH1XW+rgcqr4TvsQ1QkrorNWEDovV5eSNXiJWCDIkWqlneKKYJtVqFnCP9EeykJ7UQ== msg=Xdh1zAw/dCViYzlsN5z+27FmB6uNL7TetiWnsLXa1vzjiN20Pb8Oy2ioRgPHW5ByL4Ab7MC2pjtR0YvF8yA+oA== sig=UJ0xJnzXIfGKFS1RF+OU1rMkK+7KDkRYRUMH1ijwVA2AvPJLUXc+hxENBhOdO3yWPmaDBl15DDCA4Q7Sx0PiFwnWYFEVJDy0UHSWevR9BSYAvL/by/IFyeB5gjCPRzWzYQSNXt+YMdrHjENmaqbf0gYA e=found 205 iterations", + "pub=MEMwBQYDK2VxAzoAtr275DwWol/hBmB3xp8oTcCYhugpcyqUi79DPz6H5JywuT97sXnBG+IeEGSb9MNBBZQyCborVh+A priv=MEcCAQAwBQYDK2VxBDsEOSrS1Mwgs4wAQ9Phl+nf+cz+DfZkbA1QqDZTE8hF4VtRydAtUnQNrHYK5+7jTovU3kluGq/CcQgJhw== msg=6xVWopjO5MqCg5GINcdb4YbhzR0rpdPopLc9vVYATgyGvimo0nifXM9JPhOfWSD/2c5gZmB6W3FtI0uCAzoIVg== sig=8ONceHGNVnnMtS3smGHP2wtWZYiUofnZE9URjTvLImlWFy9casjROcFu9f0g0NzS2J14eSK+cMiABrN42r7xbma43ZSxohVh+Bqe4vSiVl//eDfOHRo71ZPlp5DmNvemTtdm8rjCep6iTSsnDYDcnzwA e=found last=23 s=21 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAkDyCY2EewqVfcrWsClShtmW3nr8bX2FaSxjAMNBK+Sf9WfjY0r7axj5tbsrUQw3BTb6zOGSYFJSA priv=MEcCAQAwBQYDK2VxBDsEOYHAOU5ndvb7/yOjwD2QibW3ZMiWSiWXogUZu63fO3IsV0OrqAj0GsSbl3z/CJiYAIhbsw8YP4wUqA== msg=o4ggKkPFx5i89aKNphpMZOVYrV07vjuf8rySnJEJRh+2xXaiqU3GG2nTLPZCiie4gyi1wK6BzrB2pfFJbGzhXg== sig=NW95XSXwmtU3iQRqDr0EvwPwyX6zyFKsyd4t5ZyFCd8r2E/H4JjwzN0oSq3X6VSTVS74TYnUx6iAvzQZZ6H90uroNeeeZAllgWPula7FowfqvYTkWzs3OXa4GYwPScF6DifxW3Mhvaq4PWXSQR5oUxUA e=found last=25 s=22 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA9gMZ1LESWNjpdSb+Lzmb6YQaeGaMp/kUB1pXvYyL9Sesj2Z6rN5mNj8/4GpXHqHY0C19URugRjqA priv=MEcCAQAwBQYDK2VxBDsEOet2OabqLTBnwQQyHqX6zGYfYZX36MdrxFeWrJ8momXd/F/uJCKrGv8zylrvxUm9STKLvR2V8JZzHg== msg=FRUQGhptMUSYIbXjhpD3avv11F5LQgS/Cb8dOfAq95kMTPtG/ROlr2LeRKF9/ZGMkCVxps+gN9G4EBSkyYU+oA== sig=Bp04AnizReKxjb+YXAenMx4S9AMQATlUfjf178EEWcRO27rbH6E/lcu6r146CcwEikUC3IwnRU4AZJIiwzcW4aaQuCym4zmAFwlsU36mMoZPs2GAOS0bt5TnCGTg/dDdDe6SC1Cfg6msZdSzmzPPVgYA e=found last=15 s=21 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA3AZlQNbXwQJD9HHfFCJmNuvVSfT8RHjDNAedxhOZi/VEY1UGpTqbt2u2hqYvbTGxGhhue0ADYNkA priv=MEcCAQAwBQYDK2VxBDsEOR1dwFx6NSm52lme24wbQIOBp61QTIKDSxzNxS2TF3BYyaJlGaawQhkn+LZD/bIkCTx60fkIGjmDVQ== msg=7dcIDjABbzjfUD4N+RwXWbUt5Zz+5FgoWYd5Thojw0bpdIEq6Kpf4smsl7t8sU7tFRwLZgfvdQKA97ecngkEnw== sig=sOMc2821Ote0owvGvD9g1Wb/wfu6O+prDBsxq7sHRPD3vm2SnC/Ej1sL/9M1uLmXo1D/3T1inKEA8x6KNIsBHTcuu70iv1tIOEQTH0ArkPbDPph/q5IeGaLiz5FMGBMx+bQ+zqQoERnYyeHqHneSMRIA e=found 207 iterations", + "pub=MEMwBQYDK2VxAzoARW1htLAQ3EsHpHDXwaM+WNGdHWO0H18Ygfo1z82nY5u222Ho8SDQeNm4HpfhTXz+oJ5Mu0tdOD8A priv=MEcCAQAwBQYDK2VxBDsEOSuoS3wOkYGc1dSwHwPxLteUQPyW3/knVoix4EJslBuAdbmiUUrn7ZyTZEPxQmagfneozA/3HSGX8Q== msg=3PPB0U3xf7KtMnQZxJ34b7dhF/RjEK/GXmXD2tUb4+TSYCdUucKOkUo1unTY6ZWbwIEX9ZhYS0vmWVsGUrrRNg== sig=DcXtXLungfnAS8/Gk9XGvgnGvhwwmAR2hqncPYHbbblHRdHFjMXtC2Vjw0OKUxyV9ryeWXHGv0yAo9dNw4SzZGUTLh8S+EEw8duYgCFzEGgJfDzHfcdLNr3IvEXJHjlOpXeKZayIxMeMniPr94QJwhAA e=found last=20 s=20 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAzbvBxM0UHYN9d4EjLM83SH1n5v45dlxoEfG2Rf66b1k9EEaMCPeroAZ1aOBd0XCbyY2SXVnVVj4A priv=MEcCAQAwBQYDK2VxBDsEOTUUFNmqbzWVzYl0rngF+yvrVQcU0rOmABZBReLHizrfnVi9FrIvqEpk1Y6RbandMssFznHruhRL+g== msg=9SsHgGYhHv4c2z8qBNsOCSUgpcB+a3hMk0tVk7qFbiz7LhKjTj4MuqibVCJSL1MoNBVaQuI6LQENNDmRH+MlGA== sig=sXKz7zj7+H8Ly5JsQpilQt+W5sZxRxjmRM5q1Zwx6bGNxzGL3Se+vMoCsIoJ3OunwrhgJrBdA9SAeAyJfgTpUj0PJds/DjAhATdotWnun8BsiCPpG0PrxRdnNQjKZgi6f+QwuOUX7lrTLTPY8j9BpjUA e=found last=19 s=25 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAVRaROORO8PWej/0jnIV+W2fwq/YHBD5qSC+X5leLIPeNSYX8U3u4m0cO2WFd3lrAHLORdfmTArCA priv=MEcCAQAwBQYDK2VxBDsEOZqRI9bP/8xeQ473MmMwfKXETMiOUBYitAUqevwsjqE5te0bz+QJEKpGQtcyFQKkPrwiU9INwPxtrw== msg=CjMLIldpLZBOnEwFFAtz3QZ4dH6Rwmg2mKKlxQ59B905UV7rS4BTj3ZoEX4y4/9Cchcv2QJu2ydDDSjUekbp/Q== sig=gzzedzhY2597gF4YzgrKdhrWeG8U213dyEi/FUonfank3ltl7Fvrp4zcTLV5JBxy3Ihrao6KX10AAiYeokaLSPdx/RGRCgE3FEGVxWjW6LUh4sJpUs30p6/OrrGKmIOO99e2k7L2ATtny1DkbJWh1z8A e=found last=20 s=21 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAzcGf3yPfTh35gObTix0BKmT8fLH0+hDvhrh9RvgTldG4n3plNhOxam4aaBl4RcB0znnxP9UK4OgA priv=MEcCAQAwBQYDK2VxBDsEOcZeV/sAf51a7lF5DmTb3qfuYRA8D7RzJjbizu5/sM2k2GzRj0cawfnslvz8l9rfYiQbKyA5z31JaA== msg=CqlaRTPFNjlVCtqmIzVlmjiKMXzJgkYTCPbuqmFyXRrDxoN3HKJveB48tyojGJGmJ85CiWnepoty/h1uoCD0/w== sig=/8eAII6p6buWiYnIGhiCrIkGEq0HMA5mZMXhwr/yOSaRMJFN7GU0fZxmWLowY0qiFfFZKGi96x+Ayp7nhus8clOafBj8OcPYY/GFh3kIaxccLQKRg19o9eiU0HWae6mxaJZkbE6FOQD3GpkpVuozbyMA e=found last=22 s=23 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAfG8NM6dWyP8qZlsiqCh3gUMjeenAXYSHd4yTlo40Q29H+60hrS+qflZEEyYXiVSdXfEGp/OpsmkA priv=MEcCAQAwBQYDK2VxBDsEOUEkB9z3Q0ZFjW9mUy5y4z6IqKVSOZVPc1n+j3jYAFB+B1wfcw1iBMhdrgeDv+NWm7dKs8TNv4Tk4w== msg=Mkw09w6UKXAM6acyD/AEpk65SVeVU3AdW1EHk7Yz2Soyk/C/7q1kygKK+XjKBx1SbvBWuoZoSS2o+w8nHFcntg== sig=VkJR/KLfI+beykZjOw3g0ZJM2WBO3Z4SVY5+ogWTCBkAaWs86femdsFBB5tJnQd8HunY1C2V3iIAhgl3Ass0YI+Ngq6ShvfiQs//Oje3lIXzj8GqNB3dBEiganyHTGzwb3T1XG3GuOUvk1t/FD2tCh0A e=found last=23 s=23 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAruItia6Jva5n0QtuA7yBZg3GKcBGz69RHJTwrvzC6L1Z9G8Epg40x9NM6KHseu0Nd3NsfXpoTL+A priv=MEcCAQAwBQYDK2VxBDsEOcbC9t+Vbhve/Bc5an/PZkDGCEJTsDwoGsWf0yfKUAUaGDbnjaVckNZH/tBgzHKcn+bO0fTKeYgvsQ== msg=4Xv1Zx7G6B7ZsULGTB7s76Fvh9Fpv4arh0MFTaXVV7qzo0RrBAuDN0rSHAXhFGQNn1ROXF0TBI3WVCH3xey+Vw== sig=z7c+rCuDrX82R34FwdqbgjoAYCo2ltL5cmMDOWagt3IpRZK/Pl6UrQ+RrJ7UVuQlksoghcZzpCcA28kf78I6aNpvAtywcUwQcQavGNX7Z+ncFwjO8OKwKQEF9frjFUMl0MydDvOlyoJZsjAut008NCkA e=found last=16 s=22 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoASpgsy2bMPYhbUz2282z5tvgNboAlPld+XxKMNyy25FtxkA//QHLNdJX0uef0mDyuKC4zA0zs4fqA priv=MEcCAQAwBQYDK2VxBDsEOY5dPy9Qt+3QyInHOchHlsuqwtIg/jsTnCZZC5R9CVYCdOCIWWor3J7wu6p9kRPCdr2IJKkDYulGRQ== msg=TVKwT05W+SqwUNCUvbx2M3UUrZoI2u2T9WXtM4niHQvO9hM1HkS3h1ES5CJe3XCN8UB730Pobk9u01dXricnPA== sig=vjDRteEYhTcip+TH0n0LmaGsy3uQDoSv6hst+X3JdtMLA4X65Ji2LV+q/WnPxmAKZ5D7Sr5DAr0AfR1RmMSVPJq7gqOCfnMLeBVtxzwtqq7FmInzizqYcYqd79K9QU6vwbs190GsyYLbDczrmK3I8AcA e=found last=22 s=22 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoATbNsyt4UFrb+0Dvz2oIPIJC3MSPgmB4HJkJFM81modXFQgmcAJEdZJTznEz25dsMpTf8RF0857mA priv=MEcCAQAwBQYDK2VxBDsEOQhX7D5Mvc15YF3+FGuG5VElqK5zAxgCQJFaDm4UvzO8dGJ5g7F/E6JrJvSwDJmH8MMj0k/o9viH4A== msg=lI6wzk5auCw8wgxWbHvxqk5mU/QH3bFhNOLOh8MrCVm14ETqW7TlIt+ZUP7KpikoYqbADVeKeu+NGpAnG6tiAQ== sig=ZNPXPFBCzXn3+99cl/8BR4NBLi7acEJSfprt9VMuXd7ZY7hdorrrcWvE6uoEvnx4XO9BNhjwAe+AWfyJdT6m8fMWjQO3sEznlwmmOONzfbmpcTCnzqy4pUR4Vx2InPK0gShOn6xOrQT2g04hEl78sCUA e=found last=23 s=22 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAQEhJPO9yKPR+4qE6OKTjJbBzoEfFeuadwlPdqK36h314K+6dDyH8CgSnoQLAM544ImVEp6KJPgqA priv=MEcCAQAwBQYDK2VxBDsEOQCLrtB5AlKw/RaXE++sxYBHC6r+Mfbapg0eu5LzyBQ89pmj3js1Ht7xfdPheEhJ6hpgsU3v47AQNg== msg=kG/iu9mIyHBbyac8tgBUwHIAppwQ8OaP5JrlnOItI6s7ji7GHIeof39F+AzAxJaDAZ/hVMbDjYuf3rn3WkMzCg== sig=ve4wLNCQCpb1+u3qLgNppbRjoV9FZ4LwJC6nDJ6+M3sAB5v2aEmWsmOm1h2qNqYXrZY+fqVjuy6A5xUtNrvBJliUXhW+6qgZ7pixS/dMoA9aEZ1ix/BTFIWZGuXh7Qnim1MV8w70SW1Gavp76lzCSCEA e=found last=23 s=23 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAl+952UZRKuVtwMUoSftNRVEMoKg4scY92c5Ip5trxsZJHOpNBa4tk2IPLaf0esDSd7/emn6CeWcA priv=MEcCAQAwBQYDK2VxBDsEOfYSDjquiOYg3hxEyMYPl3FHP+kPq4+8NPOsbC9cRCRP2z0QVemD1r/GyVNwL1THmATT1/Q/EkVn4A== msg=+uw8fM7o6ZaPlVEQKzXv3mlsBGB5hNGO8w6SdBGKAFs3IX2A+oEAqEIC53NIQS0TfbAwT0vpwlNdO1BW4FkznA== sig=ncj51GlwM5yuu7uPg0JzQlrXLnSJaCmr11zQHgags05vBRpu33gQxMMt/FlGjqSABr2R8980IEYAbwsjy94I1jrxX0vQe05TfYJj50uS1BaAjq2ntRTsLMDLGMuYeV/DZlV5vPTiZXraWQG9jIkstQYA e=found last=18 s=21 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAa7t6ZvTuTMcbwcE157n0lB51SGue4vu5Rhu00swvIQU4+BNlHDKCDBcU2k1B1ch71iJCEaa2RzKA priv=MEcCAQAwBQYDK2VxBDsEOV0KYQ/k6FPU5sqR1gLiFP+XDKnrPDROJvux8py69ZH2PqN181xu5wPH58/ydTMmmcLi5W9Mr9qP2g== msg=6LioBe6eb3srE4OOwVuzpkm8f5qcTU0wQAkautpVxxtwiUaG0BgYnnRQUKXgn/UhS4JilLbI0AdsX7aOogNioQ== sig=rW8KbWStHImIOMNcTLDu70dsJgLPYpzjvwNnWGaoDTVAOJnXw7cZICGMqwLSNs0NBlzxJuMpyg6A5m3aTQdU5tqI32ScRi2JMMg97cdsXObVDoDwJK13kLDbvO9Uc8KLmzBLhNTIRBug0c3nA9cfRAwA e=found last=20 s=24 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA24IFRVv6uFDLZaa/PPUR95t3CoQ8u6rPNbxPy9p8BtSt7D9YLNwHcIQMGLnaHJ2QpMV4VO4w3pgA priv=MEcCAQAwBQYDK2VxBDsEOTZnEhjgY0cxstPHitIA5OHPs1DClwx3TIvRz3nn66KjpcmBNJiiv2uzoMjJz6UNk4M+2tU8gxpckw== msg=BsKNh8TYSPllpBSHfnkjh+zDYtt5bieZEYDl6AqeY1kR2I6rG1S2q7WhMwzWKvmHu2/3Hx96LnGelYVJ94Hpew== sig=AUgCGwHSgj2OJCWN2O0SOb9+wri/bt2XWvfhlp4dwKBCov+dAt75heowZgAqtLsq/ouBkhqAa4SA5nVacCE37koBgaVu4YwVcs+k201sRS0xfkTTLnxRo342gVGuWpFOt953pezDEWiyfkdK5yQQPzMA e=found last=21 s=22 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAVg3LpQOO+/vz2o2geCXbad85UiGqh1clI4Ce9BpAYBjA5mbxDJMMrjN0MtbWFrQTlOTomSExU8qA priv=MEcCAQAwBQYDK2VxBDsEOdpfIxNBWikVAHDysipdwwDUAUb6/6OZ+YwA5tXsxpkIMSJJp1/XZ8/LBLCbZJ9P0skONYSczALb+Q== msg=d9PY8LzPtRsARaWqYVDL/6dVLVvtPAL9X2FWw7lDPga5Mng/AE+VTBp3E3E2pXk0/j7PkGTlo6SD4FMx1wrmZg== sig=e1TjieuRoPMvuWNKu6Ezmq8pQRUT2NbEooJRA/SVwD6SzwoS/pBUmc1fG4kSb+C8u/wM9g82pICA7MkZe/kOdYvdiNvFfa589P94ThXFWz20Sxfbn7SvaGrQiVTDvbUFnEzi31Hyy+w2LAYfgt71gCgA e=found last=26 s=23 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA+tzqsElYIJUib33o+gaFG0P47gPFB0zuG7WsRZt70En6KaGWuSjU6iv+P22pmuqyQtkOv+zd4+cA priv=MEcCAQAwBQYDK2VxBDsEOW/lhAaiby0vPTzdTnITFYlWfNlT3WQG8bSVgxsgy6oAQeFoAdNqigbV5JrFZWYSCW76m/U1uMG+ZA== msg=Ob8opz2glx0471uw4LzF9+33J0jdlNN/h9gxTGIaqDTHuNkpqaanCmtA4MsdIpZL6qQW9lAjXa2/kZCnQIfp3g== sig=Sj04r/I2jtNcIbkjtv79rZo6fH9c/j4/5o4CsiaMOSk/nKYQAwAO1kMpI9qeaM1QQnBuBS9rPLqA5j+7mh3VtIoZzLpZjVvl5cP1+XV3eAbSAwK0VO6zlOA1Ss9tHlPNmx+WDTjlyGjG9UgXFiL4cxAA e=found last=24 s=22 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAGk2ORkO3AnzVhUuUc0S1iGyZwg75dHQwvQwBYKe3ZunlvPgPz9EpLF5P0FH0aOC7zismBXZRb42A priv=MEcCAQAwBQYDK2VxBDsEOeSU9d0N//S2MbbgHQRDkqgg5sF48pVZ14iAk00j/S03fAaxsyUn/D3JsM3lEr1hY+OHYb4ze+XPIw== msg=jURp/EWat6+tDzV4vOZk8mVi2anyxButH5Zh6d8VvZollFq3tDRE/uLudGwqF01xzRBqeGhsFax+Ut4rO4rB1w== sig=kmwHU53cITu/UhR3dwoqgTZEY8WCd9MT+mpI4MYhpu/YoM/fa1B7me0Z+nySogV/f/S/Urd+e3qAaUOR4pb4dluFblQrezXIa4Z5f0TuF9ehB83JCm2g/GdjAfGz/oZK3Mw4vzffS8eeVMkiK0Z1kCgA e=found last=18 s=27 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAQwyOHuayufAcgnJ2vwsdu3II/6hmVAm9UaQ9QcYXjTSVrf3rx+M5ZIaOOHBMxLdV+4297qgoYzGA priv=MEcCAQAwBQYDK2VxBDsEOVBN/mHuHQYPXUceghNVynwvdmgPhF1asE1BYPl/sUicXovD70h7HQcR6d90dDodtyqg0GMPhVjGEQ== msg=DHfC8lf7WzeaKw8rVuFbLcJ//nbS1PJ8xl0hY/fBrcqi1G+X3wg1e9+yUWLE/imotKhwtWFyhhuaXr2ZtsGi1g== sig=4n2dIrTKPLItJ/YRTREUeyKeIQi6+xDicKSDowzX14azWnGnFHJCkcxwp4stgxcumoQUmkwk4M+ANux/ENSXSWvJj94wAR0LPj3LlH7Ik8TvcsqDhyAMscykz7H0b6KBTFImELgzbydE2jkmPMVk0DQA e=found 128 iterations", + "pub=MEMwBQYDK2VxAzoA4afFv2Q03UGcJNL4ZPcXC4u/Za5Hr2oKXvWN82ZWrrZ1JFUG9giMJwfvpl3Kc9Z6Rr2m7eVVCDiA priv=MEcCAQAwBQYDK2VxBDsEOc1badQF7SAjxen/bNEFntnSijeRsYD5xOiP6zXv8EIkumqMOgwnS5VhkdeSNIdl/4QzkYZSqMQNkw== msg=AXvJjjPQwiQJidIWSAmiGBDwnBzUYW45S7WPGfkCFakoVgFU0kBuW4YrnY+DRBlbqU2X51DJMl1XO8VOwvv+GQ== sig=KAdLvfg1wvDcXkMgUym0RxnWUrc3hmeZPMjRP1TENCDGXdN3DGzrSW7qfDGdhZcvzjexBJv+cOAAVyzbfmr68GZQvUo/VAFLtEdk6QR5oYhkZXFIiBvED9DjdCsVyefi6uGztT94gKAXdgbUqQm0XDwA e=found last=20 s=21 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA35uvsvjUhx9OeqjTQmNI22oKYxjWlYRxPlWH3Owuk/ySHzsb9MzAZyGzkUpLPdmn9nw/kHM6/LqA priv=MEcCAQAwBQYDK2VxBDsEOanScktQKapYu3MuDqc7/Ouoca9x4v8Ufz6Oao7WEXsJs/qEgaNIigysrBB+5zEFQqXHAy4D2JN9wg== msg=YXIUSRjiMZYtDrMXOUIyMeHP2iqW8r0/D+HcQmDuGnkHaYzwVOMQjmSDyjJOD7RFiFEWQCa2jWocKygxrwQsbw== sig=Fk1MqRh66p8D6zCJdiK9NSs2dXGth8eSa3l8WuHi1lJXnSm4Hlq5BPri25pyTtYkcIqSX1mLTIyAORB8jUNxSNPGRpJ+2YLQIw8zGDDpOE2IGkkKfU85qHlgwNrwTnlvyAuQSItglIMurLa3EicHxAQA e=found last=15 s=22 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAhzau/Cpt+waw74YPDEqHXAc1zwpO3QMlC3wzEmB/O7cPQjB8qKwQvDN1ScG53jbP745v2Ttw+ikA priv=MEcCAQAwBQYDK2VxBDsEOSfIy0D20TXAYYy1T2g7jXKVIPVrjGy4GW4FTMdL0DRM6jCyjwdw8Uu3B5M4TJUfEjTVf7wBd3uLtA== msg=6mFFHWNUtWGlYte5Bnh33FgWG71AEd+QSpoWsnGO0xTDlv2Djq6SUun4KTpE9ofIvtOUmLrOu/uCcimuVqsZKA== sig=kETu72JphmebkugiLI771iq5Bnh9Z5PCwQa9mpNl5mCPWwaUUdrb7+ib79uR0ljGlEJPBTKgO3eA/6jnsU3z3sowQaYdIM0NS9TxHkKfn5J/2Gnglxty2oxhYJJ+29niN9UzkWxd6i/Iji6m/5A2EgsA e=found last=17 s=20 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAhmEfxsEXdezBweaTXXBdhaDJsLGWP7ksEzW1q6Ezr7JUF0KRIeO4EKmqaXPBnaOJY4bMA/+xgfaA priv=MEcCAQAwBQYDK2VxBDsEOTe/RSw1r+R3S9CKYkh7SgF7326mmdsuApiWpNvCVoqyT0AMgrNkZdsRunhBgbYkGFwqlN0ZSS5yrA== msg=cqBD313fsvjiUBT8gc+CVoUT+7aRROgtsB9tiaWQqlKuwj7jrMqLvUHJ/NVHGgGuXU29V2nldPq4nVB6dwy7DQ== sig=tGtnPHtviAtlGSX5/TjHWaQcy7oKTbdyurDCMYJ0FgpEVqFbHQvjvZuKTMi/RRPc4b5E/xIqOcGA4hVRjKG8SDtNGpGwi1mU2mFIAO9MS2Nq9YGSd5su9DqCussBtdF4jsSA1BRtr+4nOOuwHywvQCQA e=found last=23 s=24 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAXnSkruFvadGsL0qyQHw2k65ZYHDmbXh6piY6fqQIjr/cgPUkjzGxQ9ZHmQMQsQPn8LDhv7Pl4TgA priv=MEcCAQAwBQYDK2VxBDsEOfBLBSxx5tNfq1L2Go/7wesLkXYTFTyKdCp+FCMnnomKj3S2z8rX8crJ2L3UATehx5QtSBTVqIlBuA== msg=MAAGDKNxypCUTZLKgLfKunGJK+MAAp2aWBzes1DvxV6Irxx1HBq7SYNYigDVwDJ+p0snNdF1vLiZxxhkvoNbzw== sig=w/V+hFQTPKp3jUK0pTVPITjkN8euRpQIAYOGAxcTQ2bo9zCu5dGkgAFtTv/MCwh/bHLVVTOgf3SAo/AqTP03MZv+2BEGiIRbNbHuP9w/BnyB+Rl+Mm14sTdMwdvjRLUapGgziwISVBlLITZFNRnSPQQA e=found last=17 s=21 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAMqZDBj0SC3zSf6inZVDAuMDfQtSlu84p/hOKSPUbnTrNK4GIGGmBtjrm3zCXueSAjdnqMpqmsUSA priv=MEcCAQAwBQYDK2VxBDsEOV2d/iytyk1i1e4NHc9rhTvDO4zO0uXgUghsj082GYFIRNb/UNBxPT1XV7a8+rJgD7jGxhu8J24NmA== msg=SX+nGyhZCXHB50QiVHVKApebcV7EWmmB7RelYG09/CDSSbKDluL/dfHbMPrb1aTRLWgRgkfvx93WEIN54eIk6Q== sig=Caf+ElU6Pd6+aAQsdFQWEh24EAFxI75t2J66n+/t7AtEC+mU2LqdEkvBRE2n00WoU1HVN7eXhjKA3BxeQVLu/UjlSqoy2EhQ2pPYlFv29Ot19qWullUYzwlegm9HckIPKSLyUIVCFdfias8bdLVMVj0A e=found 130 iterations", + "pub=MEMwBQYDK2VxAzoA0gjOKR6kXD56pwqoo45FMTPoJvgOosC4CVzkNc8LroOC0DR4zEaxF8TpKJXQuQ40dHGZIzEADGOA priv=MEcCAQAwBQYDK2VxBDsEOcpur8DsvRq4TcfWrs6UZGnfHOOijKX3d+cHXGk9vtXkO90/oznNfI8LeWixp4VyuQSFNxTSTK0Q+A== msg=0deQMlAqQ9ISZcWzLTjgwGPv45/JSRoyodNnrLWvbucismY68IBetB7P84Wq1q5aQJ8vtUJljTeUv4VOgIptnw== sig=jvKKgi+L+WLZ7R5F21EZZx3RSZ4GSKuVG577w510tu68J8/+mRG/UoatDm09SVBINKQ064HLrkwA8MgZDlKF9EAgU/CdR9w+QNIrAISMzcOsy7H0z2dRQB1PGQscHduq/+WKkwJhUDB5c1IzokqnbBEA e=found last=26 s=23 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoApeoxZSgMzZCCvtyURzZFvS09tZXmrW+X2ARIKPSZc9uAZHDeSTvFtmbu5NpGD1ToIXawWAezT4kA priv=MEcCAQAwBQYDK2VxBDsEOT/pGB9CE6kXj4XmBjQ5wdYI37SxuhzizQByQ9efmif5nbHnzvupd2cdueaUZ+2tttG86cijEK2TwQ== msg=xkKg9caOOIJZPIGUkCbLGBdojn1pBWs4cTkioDc3YlzH/7FCcuc2qGsbQsKFk6DAN7U4qqapDCSekb0HfYW9Rw== sig=OduLG5vWi401BYa8q7k5BxlM+aKDlChlSSn4du1dtfVeLcMo/Gd541SCUr8/QK+inHZICKRes2wA8rEDEpQNlADXAywsw020zhHGUVevYzb0jkoBhMwIcbdRpErjZ0yPS16qMfK8mCzEuazqcmRfmjwA e=found last=20 s=23 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoABwlrLFpJlVk8oBXtOU4r9JC+K9/pzrpcfDgJaUypuY1Yt3j1Sm62xGqkIc51Jkjq8DLswJQzxJmA priv=MEcCAQAwBQYDK2VxBDsEOXofx72dkiFBDZpgWwrvMELzjxfZckIQRGTvcdP2Hovndquy0zb/EHk9peZbdrrPHOVqniqw6c5jBA== msg=fVQY+2TkiWoEULI5J5tH77Y88nmZa3hiXNv2xfpGDC5fJBVncoc+jPfjzbnML6yq2S8OmGY5qhUTsG9cjCzURQ== sig=HfbUa5Ex5FvoGiRkT2a00RTqXbY0Lj8JbQpmw5I0HHUYy/0y8ZEXutimuWK5JTcie7gBTj3ZpRyAmyi8g92oNVejxTGCVAY59nHVPpucSpGFt5E7WVTLeyOpmTObHz2ImM5THHTb7/BPF6IUUWIZGwIA e=found last=25 s=21 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAKFQ8s3QK1UQsXWJX+9QkDWVB7qQ6Ed3uUfC3DP+5/3S2DmXoFumGXH3dJ8Ute3iPphC4niiCyyiA priv=MEcCAQAwBQYDK2VxBDsEOVcnQeuwsgNjNH1wne25KSCd3Ju/vEVUJPyaFbwLUGMiCBU/qK3xCvYs/CYq7pMI08nSyxXWyUVS1A== msg=Sls82zJg8cm5YRdvN00vnbpyle4ukB/UWS5O5rHxMbsMDK435TOXb1mSOtSKEnl9u/LgYeoME0VhH/ho2cTYug== sig=0n56ieQRHOJWUy1q7m79zJpWdmhueygR7h9DoUSTObh/iRWXWDCwoltFBk4OoSGbaaiubR8b5S+Ap/WBy7iN6dBvxeNTYPloBh772JBAZmj6ZzOdgDjXgmSbBm+NyBtEvSF6fcHl8CN0Pz+/Y7tbCjQA e=found last=16 s=26 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAFaR4usBZHjMU9uHTzeVtzRevEqw/GBxzPemlNcnoEfkvSdxuI5riTI6tTwS/it0see6gh5zfBnkA priv=MEcCAQAwBQYDK2VxBDsEOZ7TrtVx4M3dNC/vzmWp8ALjIlrzohvO7TQ2vjjihrMIY1sBVY/NN7d/NhvgLauKVo1LF4JaWaBVCQ== msg=7tmQp3X+5wj6F1ZYIPq1nTP2p9mLxq3w31NmQGNvOpmz3oRCeNgzw7qrmGFqZMabuH5uidLX9iuMcF2uQZsb4Q== sig=yx6u6n2YeUf11h1HjgX4LNQaUXaPaj9ptqLVuAtB0fQ/z4BH7CWWT3hZSoTgBZF4wEl3XPMbtN6A6RhYCxmyLUUO3/IzHvfNzlJev8QS1cPDry0S0diGzaY0XL07nIx6p/qHeR8Ns541TE0eytkfIRQA e=found last=18 s=22 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA3zYrQ5gB3J4oXfyoliEisxG0WAuiz4ZWJy2tvpXZPV9Qsv2fYJIzAVau5nq7iIAFXaecuRtGB6oA priv=MEcCAQAwBQYDK2VxBDsEOf5x93ahv+fFRCr3u63jeGWj4yhOWPdw5wmjj6JBsSHwvDSdEQmcrfIkw1c0eMgNF9qW7pSHi2vFBQ== msg=oZ9JNN2hUH+b1V/hP4k6aqkvOTfp4BQBR5gfnYIcy8CpQ9xC0EDwEgTHMRwme4P0Z4ztOq0eJ3iox1uHNfqKcg== sig=k5QmAM5F+jYYLYWYyPM7Xvl+KWh2HgPpk0o45a5zC2QceX3cEWDtSisJxhH4ncacExqOA1NmPCuAN1LGIjEEFrqQKvf6aaP32htHswkukqScTslSX58MdR0PaJ/n0z581LUlbR5Q3DTmLRX94P2PAgIA e=found last=22 s=24 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA6TQDbRA+Emb49F5Ub18xRUdBwWo99qh2x2gMHPdgAUELdbucGaVhoui5BIQDWpYrlohtoGPspm2A priv=MEcCAQAwBQYDK2VxBDsEOVy1/dRAQvgs+js9f4Y6nJZ7cxhyaQfPrL7WclNPUPM+k6Chq4VFyReFgUecGtxPgblY2Hxh3gbGaw== msg=K+jNS1ZCg8d06o4ejP+pgXtGTXBMrKOl55DMEPVf4zKG4kbvpU9yMNvp7VzU9gWXbxfBKWLKaMuro6TqF8VlfQ== sig=n60MyYEppNyJrPUum+3p2IHx42wq7mOFwHjO/SphAk/T2DNKZiqTeeRTTbDVMovOMSmdm9FpfXIALWGO56w0OlBeLQ27/X9xeHzr9Ro0kgHs8Wxo367fHiRv9NSE8pkdL9o8sPbpAsg4n6hT4IQkGQcA e=found last=21 s=21 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAeWLL+Wt0K+8s2eirZwNcgV3sooyNmMSSPIJrXjoMJN6NMVJ8amXul27QbhKhXWCqqIdsd6dKaLCA priv=MEcCAQAwBQYDK2VxBDsEOeHYeCMwAWzBPMsmiRy2YQTExUDA3MrSATFhwXCnCJaoKrIIf2oEdvTh81UeF8shTN7PTpusve7RNA== msg=nJcNCEqTO3A4qVfkol2usWNDzhiDReTJVZYS03/YgwNrrSvIZ9PEl6JkwGzbmh8dTU8VnNmCgFtqqQHKDyDX/w== sig=hJ9ZKtid9hUYoKhh6aHpt6YtxKJ9fvavnP9JOet4WaxJp7aNdD04oMqHXSE0j1mrMIS6RofFiMwA0OxZKXUe5Ij2/pc1+T1HC0FnPkMaZ23dFYofD4M7rz+Rs5ULNztquNCqeRh8Qyo+2QN2341vagsA e=found last=20 s=22 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAmXLBiUkY3WGz6ekoToivWFdB0yJR4St2HrKHDKYrxkKx37+ijh+HG6guTydaumaA9sqn8asPSEUA priv=MEcCAQAwBQYDK2VxBDsEOfysTilDfA0I6YlsbQkx5jb3CqhYGexOZijeRKUrWStOATf0QIQYuHfzLRJvF+s8gvNhKmvW05rtdQ== msg=z17RCwRmaZh4BVEzNUJ31SGqZZuIWFR+/VenC8ZI1XMP5zEchzeAfVHPBmepRukuZSocxv839zciZl4KDkXKUA== sig=btKc+O87iaZw/DwPtT6fSVtO/ZrEYEpCeh2ylpEEkDUX781yRcJERx6gaBDMkzOE5OIJUCnTMQmAs+w9RkuFnmFg/VRXR//6y8KhybvdqSkVzsrVWmXuByJLQxoinvbKvJ3VvSizKtvywnof8Y2pzzUA e=found 206 iterations", + "pub=MEMwBQYDK2VxAzoAHZKXZDuv8rlbprKc4+yonM0+/SIyL8hb9jgg55c9xhow0u6yhD4BjP8sO4gpaHiQ4TJJVD78TFmA priv=MEcCAQAwBQYDK2VxBDsEObmkQKh9WhfdQD4TYihzgCvSavC1eI4zA1fVuongIVLEE1dFU7n2vv6rC+0a2yo1OP0kmVQoXIBTiQ== msg=7YFiJjCAjjRrEWUtF8BfmsrdESqcdtr/WqTw7OiK0uBCw2KbRFM1/JShtIHnJGkfEpni3UEF1keD3u3jg8SqCQ== sig=aJwghfHVtSYzPqjh+LEISQ5lw8O4MeDdXQ8kAQtrB6R4YfmMRuzRSKCmTxtyuvMfM2QiQjQ3PBeA5CCG35rb0TBj2OVQNZtalLWDNTl7bSVgXFfUW8vOEed1oXAQH1SQuH7leQNA0VQLLnXYKc+wRQ4A e=found last=22 s=29 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAGuiyVtm2GTYnDt22vfISMpDbm0QkM64LdS3hnG9JVFe+LbfhqwdwMhPlAqjGdhEuMUvFDJMjMsoA priv=MEcCAQAwBQYDK2VxBDsEOaoTP7dJ1NEwrYnegmfJQKiSkWrkTd8GK8+RzUER2uB6Vz/64i3IOK98iHydQmxRbiGdOSBU2biL2w== msg=QdCmGkkWXGrrpQjxxmFHGBF8ZpnZ9gPaF+qRKx93HnqE5UufBU91angtymiS+WRIzZjHQZ9yMCwHYJ+YREb/yQ== sig=z+q4q3xr8yXsqzOIoMqGosaRxQ+sF6F5z0qkHT3XxryqPjzNmEM6WpePxy6OgwxX/+kDxJbdHZ6ACJSCoOHt21ojOqRxMxRBB4UMnHPiUr+l/8D38TdrJurljFtU0nTD1hOK6s551face6XWY12jtBgA e=found last=16 s=27 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAF+feKtxUi4U7jiDjleaAOKRx+KPGzXw4znSxyDg+rnaNvSBNVNnxsUpikKdpxB2ziFe+CWexph2A priv=MEcCAQAwBQYDK2VxBDsEOSZo5F8OaVlk2bKlIYuVe1AoWlnVspWPQYqkO3X4kScQG9yAZz3E0uebvr2iFCa2rXjS1tgPb+GO6A== msg=LbZ0PgdonxkFn/rECjesHujHodPSLssVitbzZBRJ28Y/tTL2rqOFQQmF0C+AEDMc1R62PKGtZlEPNwquvqcDwg== sig=ISsc4Yoa92suwSS1a+3Le9hOiItzTGp9QfvnFFntxqbF8mgr2VnhdfwDXLPZF/mN7PE4fRx0IPsAnG44RDjbCNjDcRKgPLWCZwaMXlaAvg1JqICa8w8OxjqzyRm8oJMlMGFCI00eK3MA3ahorqbyQSEA e=found last=15 s=23 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAZcael69l6nVPJUA3fV5t66ZE/9MeJlmIjaz6lL6XXVmhl8cn7rZm3zCVQQUNIKEBkNjjMiAo2EAA priv=MEcCAQAwBQYDK2VxBDsEOTCqnh3BZCr6EMrNoWSbi4FQfffNgpe4BVR8j+fYCIW+hAnRFmbYGiq4DMLPMKG5voCbDEaAofGqLA== msg=6AZOGjvnmZVLMJrPkO9/MbAb20RKtuI8pMTpv2my0xfmzRZFuaNfWFYM21pUby9vClEXQky1C1JVHSgQu8xnyg== sig=CoSZmP6nVr6URWmPfZnLfkjmBltO8/TWzbJAcUAQXnrKI8VRzIoUKdE+TqWIJX3mQxKLoTruoI+AVrTiB2Ni3pO4tasAIuEyH3ntkDPxO/hX4vmPc0jKM0IJUBft2RXUozFpMr9o8KGTxnzXVEW2CSYA e=found last=24 s=24 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA2ayGUojDrgripY2VHZbBbNk6YbErqgofjvmta+4LLSP/QQkdDM5zQpI71ED8lYXuzivsWjfIDHmA priv=MEcCAQAwBQYDK2VxBDsEOY43koxFggzJCXPTUI8kcQSW35t08UTauyUOa7FbAlZh4TlZO3gUFEPixYXt3nSJx10jrWgTcsRk+A== msg=s1oSFIrxU3bW5YEf5FHcw/GvhvpNHVgGhY+fOMVFsZvbfQjprRh2EL4G5tayVoyZ+mN4yIX02gAw5iCJWzctFg== sig=dIfulntyhevJR17JDL8NmNxohbIFrZmyXswvOaMTy/g5BmYXxD6kgj83fbVaUtLlHuh5KZJE1B+Aj7wxq67VK8d4gYEOkdd4LoY8QIwIp3pxY2MovRzcCIh5t4Oggjd0gr31jx3ek3SH5h0TJpF6HCoA e=found last=21 s=23 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA1X9OJZkl4XtlNrwmgvLHdCvaIQb4jAuERuuHdbLLzQIwl3XliVndikD8TOdwkD+2/AnxD63bQ0mA priv=MEcCAQAwBQYDK2VxBDsEOQtjr5il9VCvpUci+rt5yWCPrtAfdkstaWH7T7hL/gh73NKBJfLVmjzC8Lvp+RBnOgJOYJzK6vSSAQ== msg=/+DmblN5tKsjAsufAAZgf5h5mrXCz5n6a7polThzwpcYMakBEDvOZ3mZk19yYdMzecHPwnLfENtl5AUYT2Q6Fw== sig=Lm7g0i7lxlCSiQwWrHpT4OnoQ2sRILKT+PMSrt/L2Gd7bV2jXuFZjRjysBlZhbl7+xVRTzz6VqOAAAjA47ucQu/+fCNt0sdsBqCV0ZV3uarVFL9aE2YPv1P4BFXiZMt8AsdCOoW6XtingDaPreR+0RoA e=found last=26 s=22 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoABbO4cke7pDOFo4bNtiQNBTYQEOSD9GL6SOjwZOHGnMBWu2UBcz+m8ODvxdxQ2gj8W5c+HSp7fLMA priv=MEcCAQAwBQYDK2VxBDsEOWsztqyrBPedqRohhkQSuB6GxgFg4ke+OgAYOFta6vsyHOBRb6mUCYHR+83uyWNB8LL0pg10yKw6Dw== msg=nY6N+auY8Q4Mn30vvqrNk2bc4D+w+1xK5hp76A+wfdWHwsxMxF6RArrQQYIcbwH02vJ4qLpMRiYQo/rEnVlDWg== sig=RUJZz1YHXggd+oux29w5SeDplTuLLiZJu/haT5RuGcPvXs9LOoOGbUKsgX34V2/UlVy0uPxJ28WAlivNRWZrnq3x8CSw5WGH5P5UEgBgqq212KRyWM4uWgeN3ZAP8bdMPAkrTFXAV/hHI6PcfmitRBAA e=found last=15 s=22 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAZ1fgJ/tRS410b6VJ+4oEv65m6KBjfqc1n159gl05LPlt6Qz34lhBZAuMok9bT34X6xQLEgDJhZkA priv=MEcCAQAwBQYDK2VxBDsEObIm4NBaBAaqBLpgKZKETAOL7YLymYRYcSiz+rhghHv+QqkkAS7D+oPrw1LAMqxVshqGFlpc1q8n2A== msg=nwwEvFq0E8RUJcNlbgUwtPxlmKL9KK6E8QgVmeEj3DQ0O1Pfo6MYtr7WH0iaeP2ZZkBQHTMTpqwYs272BqyiEA== sig=XqgwIIdhKJBdTI3Vq7unEbk1Rbo7gtmsgoEvKGEX+XCQ8OVZpqRQmNNJP61P2W4b95TfNbc/N0OABqr+YhYn6fGH2C/tta/W0eQATVzE6jlAxpK3GrsMELRzHFXyJM0vHyva6MDvkECy4tsbMe83Ti0A e=found last=21 s=23 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoASVqSsYc2X7z/CcUm2lWz7G6Sn987Qe1wAYeI/DZVwlBxuiRpEi7MIAmKTmgz6OUATziqHGWzyxqA priv=MEcCAQAwBQYDK2VxBDsEObm4st1nyO3EDtAoRjxNtbofl2S+4kPZq+/Nm59kQIdCquaLVw6ulYkfIadH8xf2chCksv1xbTiTvg== msg=ERu0bgPhrgPqS9L4rS0yaEoV5CJIURinGnlL3u4kT8boWKj432mM1dQIhvSvKJ4FwFSnnocd0rMGTEvYtBT/ZA== sig=AgUwWhdK6CRzpYslcKLeglF0wAyIX0pFqKdQCbQzgER1QwJksBc4n323b2mpE7RldXSvxyXcZMwAW/JanBWagQU02eFNzDQgAEpgU3cNDY0Wrl1KlTuefnISHpLEv2xJz3ODYuNevcVDPm42+dIVNTUA e=found last=19 s=23 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA4dHRdgsVlYr5JxaM2sY/v4nR1FBgP/iywDJ/K+EyA0Oo03LsBceWKmyOrjDkpcT8I73IdAJmX5iA priv=MEcCAQAwBQYDK2VxBDsEOXVoxu4ux2ZtirerVZb6XLlMN9PFQCk3QeiPTya/09FJOQdxIBMs4WJ2hdDQJeWb68L0owvpkj7KJg== msg=bwI0fNH9QUXBR+Zrc6DZHStNvxismLizAQg2XE0MI3UKoPcZdUzRPmGQG9rsaPBPDhPKcqBEb4CTbQalvvbXbA== sig=DyYYwwxtnHDnVVh0ghgvuqTsIPD2EEC1gi2ds11dt/kxGWenSNZFmSOBwHTGimmlVDA+McKw6f4AbyzqUo66Kys22xmqqGRWKCGVzv742rdqcQpFQg/wupJA8VVpThinxmji/bijBfW0RpUJk96PjDMA e=found last=20 s=25 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA4irq+m1t+p2Ml4omiTP1nSz7GGaKSZ6y1CCzz5MBkdvm5g7ONi6p1wbeJ0r/eLrhm5FRd90Ij+MA priv=MEcCAQAwBQYDK2VxBDsEOaKFdEVtjVUwoolckBJeeJmmnMUidNokPBgj7049pMrsJmYG0Yd7/hBk7+UxPsSAzcoI1aUQtmweZw== msg=NvR2yXcX+oF7x6U8Le5tQ1O2301uW3rEAcvDX1pkVF37YbtXYR3x9oa8Cut2/nGysK0kcTJ5MOfDIHLrbuhT/g== sig=4ak4+E2Iagcd+NerfI1tZuo7quH0lpVZ7tgemI1nyxwTnQdNvjwl+snIAqBNdwEqryNAZ8Vrio8AiMC8DD+Qn894vqxf+TLqt0eZj2WXtfIL7TWOcUAWkvy1jI9eo8ndV1QmpyI86yK9gxVJKB5JwTkA e=found last=17 s=28 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAc+V2NODcjBP4aDXvrIIjuhidpOVAJYsEY4hITC1MizjOcDkJgz2FuLZ8Fop1HiqRfuqKBZnIooCA priv=MEcCAQAwBQYDK2VxBDsEOZeQSEHuYcrtU+5VnQbmhomAQ04V/MoIYUUXthH+QTM6pWTJkDjaWT8j4qxvD/yJRZHvoizdvoHIeA== msg=gS9S0dSuD2jP4j2pN4dyPXOoyJ9qbcmnEBVTHurq/kRXKBlb4ty9fjbbnbu3uMCFK5YOvNHOEfLXs4jyvvPwHA== sig=0zy2TcJjDp4od2eLSUw7p3BmBuZEdqTcxGht5rjk7n/k6sJ+eCkAEHKH2+6SMilusS90YtcCMrMA7DHsn0oyybLE+sdhVQYfJiU1AUjWAvh+n16c3TVoyKgtOF1021+bg5BXmj6dNf7xuF2RSOiWzg0A e=found last=16 s=22 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAdTp1hTbsOvKmF3ROLwxbTeAg3Q0jmhXhyqtjg1e4VzO5rvIlQwDQ0/3qR7hV5diu/Wv7UO7XMUQA priv=MEcCAQAwBQYDK2VxBDsEOTFG/h7A5FuWirt9BKtaS2EaT5ZieH9A2JLspy4BySbHSvyxHFXP0/aJuh1wnVGlafDgjFL8m/hmnQ== msg=Ez7nvb8eXmfZbMziah9vUViNcEDzvLazfljtFKxPdDV1cMN2G8SnON2jNjWBb4SD8snDZXgEmvytkkESrx/U7w== sig=Sd8QRdFInJRARylz+/NCQo9mY4AAUTCID13pMunwSp5OsoUHb5JrAcJ8bjMHDabgwEBpNoe5cz0AaCfgDoCzBIL4axDW+82bDuwyjkZja5bYvdz2MhlPWSxsdwUaQZ68W7eSCkDfig5y06yBqQSzGScA e=found last=24 s=22 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAFNIxd8MnI7tf0U4ahzH5/26lUmVmlo388dlv5QRfph9iFnigmZx3i2jLvK3y18A5J18kFmWsIlYA priv=MEcCAQAwBQYDK2VxBDsEOQdXMnETX82x1YQJ867dM3uUA3STXTeUzeawglJB1tY8SJA3pvQ5Jlm8CwxfOFW5E74blPyMQzKBzg== msg=1OCqosd3oRahEM3/szRaJorzk8kD00oecVXxtHxud88gpCWnuLFfZ1LZXK1oa5BLgi/yhCtmguhgD6Cb6kdNdA== sig=n0AIw43PMhAsJrYQZZ/5AH0gmSsb1lZFS6ZQtImxlspiX9McEkUhzA5b+vfnwXVWMaC15+KattuAGTj5GuF209E02JSCFE5iC9o4s1PlcNMJZKphVRg14BFL0KQG1F/KDVtIseKhjCZQgnl8kqj5vyQA e=found last=22 s=25 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAQ5PRM+pcdMDvdi+U8eHo/qY6S1VS5Y90vv4ZqdF97gTuboJTrgbByRmq9E6ff3m8CaQ6HiJ7C52A priv=MEcCAQAwBQYDK2VxBDsEOWHufrlq7c+maFllREJZOCoVXVbDk7F+hVozYYnX15mYKsM8B7ZJ9ifrdJTA3iz+EmQdHZxpXCS+Gg== msg=fFeaWplmudmWbeh/zvqMUVim76Ge5n42RF5hWutX4esumVyo/4edZMoNgd/pyJ1Giqy7+pUyXBwQsqtQJ5WlOQ== sig=yzocS/WqAkXZxseHoyuCFL9XYhpRt9IrgTqX1VDTsYlAtlNzr+EN5MF7Vsk5wicNLOqefPv/QlmAuFDgUv3VA2RVWoYBNnq28Obh/L4SyKbzfvN6dntgqWYzKwzj0JwGe/Rfl7CQJqAJXxS5MtVG6ygA e=found last=26 s=21 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAomE/GWOiDCSBPc/vEJTHwUHhbY3xi8zj+haCO/WEK7s7rv/8ZScHHAane85zgAXkXmeTCXlY1wcA priv=MEcCAQAwBQYDK2VxBDsEORJcy9zJZACoPwxK51VDzjVypqj4AaSYcabBKo0xpbwRMPQcEU5obREHs4BABJMrk4KhrCZoxFdgDg== msg=0UpxOb1VFoLIyv+di9YYWftemqRyRs4bKBQNaE1Kj3R7/+rGsmYeoXxKDVXfydeelu82GslpWxfuYVd6pVwLJQ== sig=gKYTnO7r6cRCyw2JFKNxrjG07i5RRQGDvd2fqlnzY2d0WqR9vLlqZ8WzON6e0WVHzc0QRKRgYKaAyvD7ZQzw8hKAzbC/atfCo29NaiEPypz8PRet6C1gwFZqkDSsf8k+bDrzWfwHDW8RyIDEMiGfkikA e=found last=18 s=23 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAdZWVR8wEz+40iBjBTBpZrbi+vLnfSPxnDotP23Yqsw+W1MfDq/yMuBTwDqLSoHYZ5VpXrZKFfRgA priv=MEcCAQAwBQYDK2VxBDsEOVOalig65uReNkEoxdzkkY2S+aR2Kffy6gQJ4E8GKBz0ykIHeHb+PJq1ESBqOD0Yp/97Z9eQQrP32g== msg=O7X3oxstBs6HXyp/2cq4wYkPuxKkyYTz/FYkmYrs1D9+1bgsHxZxtctmxDnp3NP7EhauF7ChL2RBTkGzIwaV0A== sig=FGkxOK3Sarvv/1FGJbULS1++zW1J1qnkba5x6Wol9i1L9d1nQsvI53vBN13ezuE/4XW+OKCXrHcAORyRi30o/q5cjAEfMcp6eVk/NKKaNC3MIl96MvFgIZ2eYuDWi1OCPcTcKxHMdwbJ7TBG01+PiCIA e=found last=15 s=24 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA5eemk/wMwzrsSF2UprZYvTdfhj7NksprFMVR93QnYwTtOItiRL/DPMygjt1bjFhypcKwPiMwdSeA priv=MEcCAQAwBQYDK2VxBDsEOSVZkEZmpIfkY1GOgNPagjKe1UHYMJgsQn75DS+GZzCM29B0AaaxQv/am9XZkQ0nsrQ0+oQIYc1PGg== msg=aUTFwPAViOOmMYWTKOA2LCcFzTSMV1U5Lp64jXJb0pkP9bL/yt6uXbvdvoRzJgHj63RE9qsdfW21G6zrtgRwbw== sig=JScwBySCiVePK5YGamtTuunn16lEnR6IXU0Uo5hXmYEUg3AT+MD/BuIO2fSnRvabmdLQezNjirGAwQ9nqVoV7iWtwSseBQS4h4E7m0I3Zm5q234AOXCaU9w11oxmYW5CdsYPgsjLonrxhCL0dE5CBQkA e=found last=26 s=22 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAgbcGC36jXmJtT/eWJA3lCh7UpAwOYC/Zj2p9AtATlKFiPQbvQLCsShDtDWYh9meIYc1qggA/G0CA priv=MEcCAQAwBQYDK2VxBDsEOawqlWD30Vfpah3iy9NgNqFMsm010jTAHFvpjuuoFwgeZrfuPsE5dF/UTGJgZ/MS0517nMtShYJ8XQ== msg=ipm55TycgV/qeClEtjCVlvwxkARfu62DBxsCwEBIHeyr7ZnX3PiZ33F6lKhCmL2wMmL2BuTV6OxOHebe+7Lf0Q== sig=sTkKyiuCHZhOlcpIo7+9rm/S7J7TExTWYvQM2xLaewNG8/GrT3eRNz8C33jJvZqthPhO9pEirt8AwLPfHGTyvfClymeWPZGMI2k0aOBgDh1ktof1nNn+XGWIG1WY9bPr0QYaevSBzPiJC/g0pJlARCUA e=found last=16 s=23 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAmUo+sdMj7W6YiW/6SacpONuD8oD93gF7w1wTFVdngdEhPMZPgm+7YNQCSt8Rsx271Y1wEObRUfeA priv=MEcCAQAwBQYDK2VxBDsEOQ6xZeuNuETrjZCdgchQIHAURt8sE+1uHAsXQdBhNy2+qo8vi05iSL1bK688+FmgfXlou3DV2cnAsw== msg=7XpMXUZI2uUY+oIbVYVnCM6+nvBcw3vIhubUBnK4maVS+QyvYMTs6wG7CfvALY9lIXRzhaoSveZE3bdeexcqoA== sig=dMqRjV7z20Arrm1MaYjU9DqDd1ho513ApiZ/l5QrGc1+nYp08YY5d/HyRSJ4XgqY7pODP0keHwKAWVyiue7VFoXfUHmzzsX2/Z+IjWvqR+rZ2h1tpD6NSfFg1TDm7m+fkWQwqDrbJ/vb2KQNyR6PABUA e=found last=20 s=23 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAVsOyq9Z5ZrZci8rDoUrC2zmJnjX/8tY8kvXTLaer+0eBXq4IpR0yTWkqKax02ncak4B0Govk4quA priv=MEcCAQAwBQYDK2VxBDsEOerZ11V2+/hSsdsHySy9YSkAktgtjnDmX5MMJExdzksB97Vi8bLyV6uis9vbZEQYg0+jXeM+3pOzJA== msg=rkWrslT7e6SJjX/MfMGOvc5OeY6Gh1LPyseNQq9aVFWxZ9hcGnUMpaZh38fqdeAJmo7l95+cKi+xCmhiAr7ZRw== sig=K3t6Xc8GiEe3qEncukMXaR3ao9BXyUtRO/UqCMEtaSoq2hN0UG72IF4N3uH46apfZz9pL9GGdFEA/YUC0DSmj6HTho2bEXon7iZxCbbIRG6ShD4804c8w5eR4xbt0gX/jHnmQwxdeTzGdoZv0IyDMw8A e=found last=17 s=23 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoATdJgh5quiURgKTSy1+2Vft76Q0rqiuUmgpLBxnZAAlmkHoMgJ+ba1IrAxyhF0e2tGg9HgqLIF4mA priv=MEcCAQAwBQYDK2VxBDsEOeuTX7BgTn4DGB/+kwAQ/RlpNKZEERYR41xclM+XO7aFYxOtuddLMUTxz3cPeB5W/6fzqHflSclL5Q== msg=zDhpDyjnZQIXmr0rJI43YJ8lPILskg7RmZt04ILXNZFMNA2xN9Bt4nCmsVY/1AgmrKGFAfswmcoBDADaj3ijgg== sig=q4CxmVVirV/wIMTbyZZ51JdccaFjG4usky3bxDAZw9EzK3VRcjhxlwDeZmfTui3px9otbkW2MMcAK6/cu6GLlsolGoRnR42xs0GF/ON2rH8n4GNcRa2qSxz0/oStssI3Xbg5bbRrugW5KCcDrDColSMA e=found last=16 s=24 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAeL/4fLpqMjSIobmri/C7sNp2uUq8+YNL6JalPs5CkIIVNU3cWiKVtK+8KvvafZ9ksMSLnZcSgK8A priv=MEcCAQAwBQYDK2VxBDsEOfCi3BC0i4IqzKfT3osX/hJHHdtLAsIy30/HnQBiPSAhPj/IbfzrWSTiJ0Iax9niaiLvDJWxHf0k0g== msg=yUbkKdGrldnQ5DPfpDRM/yRsY0hLRT9SBK8859+j/VZiFt384tBGoBUquTkipSSX1X9S8WlisD2hIw2yKMgl/Q== sig=X0fdCzdndkd1zppimg3bfFQt3A6BrDqnom0mmVlVZsQVbT45WicTsotM0zRDn28/IfRbnc8SkRYA6xGO5IIqABtiNLfe69iAOJejNO8tkaOiiU+Kccy9N7BbtUy+LPoJE6XEL1dHChUwwAAXflVt8ToA e=found last=25 s=23 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA9yyUXsjw0di5MJPG7EMyAPSbcYLyF3Nbybp575itVYWtz/NqOzpiigkz0wzu32sm87LYaym2x2MA priv=MEcCAQAwBQYDK2VxBDsEOZ4Y4uExFgmpEjfbcy2DZsOF0K30+KjQNKVfeCrscVzbt9IJo7xjGRA+qINiyK3IBV8b1f6MAgsfag== msg=uz/36lf7IG2fJqIYaRC8kulWPR2lVvzuGEITad/0uJYhITw38shyC1vrfruFN2ptJx7fltm5zjmqDo6FBqLeCQ== sig=EczxUxLtVd4OO/fiicyAEB2JwruubvTkGZbzwBs+qB7Ncfb0yEwxgqhAy7qyOuJ9iYJCq8uHJGeAvzZkIn0bepAZ2G5RjypWYHdMfoigv68O8q8zZ0R2GvF80jy0CTLXPvnfL4Q8qqthniCcNTSFRDQA e=found last=21 s=22 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAkYVW2J/Kgb0J2Fny4QUj42yEH/DnvLcPxdAqLnCKk6NUZtkYRQCGtvnJQ0kqZ1nEkF3y0P4VZQKA priv=MEcCAQAwBQYDK2VxBDsEOd4D3Kbx2bjzngniargaRc2bpRUvh3nWPZetjmRNw17qQ4+2C5CR8WWl87e5KEa0cWAaWmTErR7Eeg== msg=KwIIedprim9sBkyt4U5cnbWKuD9A0XK8H4G/1nW87KufiQVxAqn/Hbq6Qs7Aacm3G4Te+K5OXKnp+4Y7FPFm2w== sig=cE2+iBCse0arKzG/sBO3qdHI64a5A87mywhMDp/IU686cMzHfftfjbvY1Z3Lyd8iwBLREHjiAO0Aitq6nOhFyfpXv5EfuIVfH7OInyn83iYe1tcNx/gie2RQIb33V6TJxzXoPDNv+7phGeb6WV6+ri4A e=found last=14 s=16 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAAe6mbxUfMnQXdwU8MlWnxxz+88JaMPBpDu2uRQ3Pt532ypi6ci//bLpHhZe8Vdx1xx0dsTnQu5+A priv=MEcCAQAwBQYDK2VxBDsEObKHqdqej1pZegKf/+x3E735yY4lQ3eKi1KN9tIVGSB7bv/r9Z7VyZOY41SN2PW55u2jGd4vOg7PVA== msg=PyTRVql+XeNwGbFRvE8Jfiom1+Pl0DB5tl/vfY7BhJEA6Iarv13Z4VdfUd34M3PTQ/6Gt751w3aWMqkGXsIOWg== sig=Jt+kSyPOKAETPj2Qvd+3qcmxs9mHx3S/FnuE1kSiGIslKvNqaobQaJZIdM3OIayG6Z1nvnJ8vyEA6a/czcpXt/Qoih3Q4Yf+oRdffRk1gkat9od6zsu8v5FZvRJE+p6Ek1VtlZ1I/PCv6cC06dn5lCUA e=found last=22 s=26 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA1CfHkSF/Esx10HFxJInTWr3aRk7l/l85nHR5XJ4ssLBnx19HN3u3LFcgql3R3rKxDJbTs9ANUrqA priv=MEcCAQAwBQYDK2VxBDsEOc3nrzAqnLEZjBs0zUelEvZTTKnwKgWmj93bw9eEqHiOhDrhjkTYsidtx4Id5LnJS0SxDild0GR3Xg== msg=7EEzPLYTYxJJPoU5O7nm2PMVqVvZLnFU/ZkOqEtjFHZdxI4VwcxaOk9YlfpTpOngng/JZhvjXPeSC8KL3v591Q== sig=ZWSrPxUpBp0Qgqgh5XKgJnjlidVNMk+aJ8YkU3VUqU5vNVAp5vbblu4rndnUOLZL0qq3tbkvw/uAaHHeEEBytKOO0UsZTObyl3iIw7NqtL8fV1DpBvxmsYMMhOmzJLNOUk5nzUoDyDcxmklpHahjVhoA e=found last=21 s=28 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAHVnXYcz7R/mbfgCFR1aYWIZYtkKP8PHxh3MJeqjTKkglxKfw4YX07KpbPQi82o/wPhvhYFA9zZWA priv=MEcCAQAwBQYDK2VxBDsEOXfK/CFxwsiGL6J2CWuHfA4j8lea+hHPDw/bzUfe8zA34X61obxuqpcFMpp94nNJ38dffdtSxEra4A== msg=DaM/nTwfy+sP7bCoxyIakUdUa6Nc2z14Qs3XnKMWXERy+32Q3T8wAVFGNbuK3XeqDeVrvxIXLL0l4cdbgTy8Bw== sig=kTAgHcXQDj/DbqTxr6+2ER6+pm+lZcVv3wjQhnSOubDICMtKLeLgE5psxUfKPzZ0g1MVQ+fIQyIAVDJ6NXNXfFDBmPSaehTWShs4QHbHX+LQtOV+oI4uLpOjIMeU+7eARSiVAjVH502TyiIdufh7HxUA e=found last=27 s=24 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA8oI4ImnDW4NWZGmZLgDwTBTtkGHCFTzdsOSNMulK6maUh1M3QJ97ZGU+S1ycGtXfPVWVc4s26AaA priv=MEcCAQAwBQYDK2VxBDsEOen3cNViYL4cBudxfT+jfJvaYSyNcUHZL47BiG7cJGIuCQ7kBs3TFbKo9+0z7Zgg+W3V4YhIny8JKg== msg=yju24NiSjbDTVElT5qe3KepVK2p5smxsYXgz1bJxSbhYeBY4WIONBNtMBwXVTJhQxtrxR9HLJLLDf36c8vaTCg== sig=3lztNW25Cf9FSsjA952dtz325KMxU9PjNnXDdpL55lnOfxMJqhjlkFDYNN9DwWM6V53g55e2LSwAycEmPDE7gYjYYsJaU2yhsvY27HrMDbsiQs4Mxm8QiR64XbLFAFXsLiRKmTkBzwswCVeGkfEVCDcA e=found last=26 s=24 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoABZIdqAvebd1isIfm/k7LiGdWLFNo6mWzW2ijpuRjPSEhmBWbXG1tlOB2Et0Wy6/zEGWwWhwGNIaA priv=MEcCAQAwBQYDK2VxBDsEOWFLoUEoR5vKObzKbnb6jhRAaLew41ogwA/DOI3iIToIh9g4fzr3bCMEVkQtHBFLzlMBvfBQeUyMzA== msg=Gy/sl/og8oB1F86lRdCTbdkbaXGbH6GK6NjVALmg1lkq+rvpZZf/QWoDWBlX01O33q7OsSfDG3kU/ZXXhUQc0A== sig=CNxt4cf5YaiRMkA5S8E29MlMC0R1U/BfCvSSOjx1f4hyZDD343JkCa/sHlNHvr9NK/o/Veo19ieA0dNOuJfIkbyx8QEbHFg4f8FTsoSzi+qXoTiBL5Hov1QjB/lVXzGDFf7trGRI9S6pzxIrw+niTAkA e=found last=19 s=24 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAR/KDIdIN0VkirDpOwhRBZ8XeGvk0XpqmO3LbRC74dY+QTIibpvuWD0kYPfHB0NTFkxct3iwnI5OA priv=MEcCAQAwBQYDK2VxBDsEOUjUMyUH9psn/tGIcmMEDvAk9ZMYK6WByT5+D7wytlLhPbaaS1dpiIWQpI/+L/3dYdJ6Nae7qmB8iw== msg=VA1R6HMg0Rpsl+CjvobkGG6EdFYxwBUbVmtFMbxlJR0gVsf7ZLG+Vl+6UGcth6IoLy6e4G+Zo3ukI/5fx2r1nw== sig=TErUDISwNYn9DRu5bt0Mk8iV/njn6k6cWQKgFoxieZoWo1af2MByAZkZi36iw514AbnyNakUxk4A0aWO8s8BH5B6TODQrI5QoqkRM92OWrBFygOvKJzH3U2eJcgr+E4fsA4myc5Fmj0bsGVpNftxXAAA e=found last=19 s=22 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAvSnnVvsyU+Do8rwa0gza34N+EoqN+eBEINbEGZ1RmlIpyYfuOjKbf2QurjiavJwHiaIhO5OX5YEA priv=MEcCAQAwBQYDK2VxBDsEOT7x9KePI8xYwDAdeaIjZM0rBn0LVG+heXmO0ZVCEjwFwO2qbD2mdctjNvIy6CqJMg0b6kIyD1yKpw== msg=JC5NMa33YFKUkfVzqtiNpynkhwDZBuIgDWdPdssEmCPkUo0XxKPI5oaFdgxz3d2YosIHhX8QPJt2SWAGs8uoxg== sig=oaHXy//BairZzWgHn2wM5Q8hlQdAMmLe+LJ6qsVlte5xaJkcbaOgJyV5w6f6PbObi9bQpM6lWtkADD6QyUhLMou3OsHJHxz2mviPxUHHQHo5cyMnuqJdOgjmgTpUXJ6kC2rizpdT39B0OPS9vbhdJQwA e=found last=27 s=24 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAEIPsVzetc8EkjuUyLDHYJfhgRjQgiU0+d/r9exUcoDpX5MRDsTkUOibeA5mpSA6R4u7x96xsmgMA priv=MEcCAQAwBQYDK2VxBDsEORbSHzGh24MyC6Qh4vuF7Ww9ul0069CBpmE4ME46FGlhNLpglqe8r6Y4YBa/gAK47GWROCe8w9S8pw== msg=nV4tE6+1xMlFM7lQ/CvyBTx9U8pcawPUbf4Ly1ZsBWoiTUH666mg9qrNFQE4CPI4pM9x7FfMQ5ugRmqtoCgsgw== sig=n92FtRT/IE0XZduXRN0cTDhYRh0MT33CVuKS9Z/0U0cFxuHkz55j/bYDZ5RFpyTOSmzIgGGNtsIA9phT27o9dSJj6+eEevkhS6EeXA0xurufCo5zXbw0BJ2Ckc4t9JpW/0FAHfzXLUx1I/Q0pucHAREA e=found last=24 s=24 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAdBdAphNZ7QqDcT9wr8E8RuhFMOArg6Mu1ZXv7xgNSEahaYtuZ3aAVGmBEJz1VT6xVbs9R/wBdqOA priv=MEcCAQAwBQYDK2VxBDsEOd6i4gMQgHTS18+Uk6AFaTcABNDziWiep7685A9ZnXO6/JqumX9g2i62HJUpNgS/8EM7lQZgsPW32w== msg=TgvrrwqW7sQt5bcZ3aLSmNTNqO+20uD2XmLB4McNNTYhJapurS4+EwPQ6PIXJlIDOngcOxSuLxaAJGJjykAnoA== sig=rEzT+dwMCX5mSFe64PoUPp0nzp3DNNug8u1WPpMg+zmBF1ddn7liZapxjY6ZHBoMcboChcFyfMSAv8xsk8DuXM9M92jEYnUaETh3fQFRiDb92QGJSRdvCeaC4juqhS5hR9JW7BG4+HN/CGMZgVGbNxEA e=found last=24 s=23 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5opaVzVfG8RSWPTln4dp19Y0teXMDgeJQEyJDxgSksii5FvtawYBDWM/oZw+VoIbaXz24LyjpAgA priv=MEcCAQAwBQYDK2VxBDsEOXSHRmmj2LFPNZx8v09NaswhGwRD0x1kzKJZLEEW4+p57OXd7XZbBjjF739QEXvRXZZwsd1TMQZw+Q== msg=n3YGZPAQ/eTvLUUh2cWTFINga58FWSRN4mImghWBZ8TkUCooJC7nyHnSgD34nlDpTgNFkKw/05ChA2HuQpKJbA== sig=BlzTUEzm0rAm6r4MnGpy601SMv+pWp2YLWhQ0W6uvYBl36oC8kzglA3dU8/Ru2vMck7qfjygPteAvzFgwfxDm7CpcarDagjKluiyJCZRCyXcl5K5Ke29kPHvhlN3vSaGbsamxTjUtR56Pt+a094TvgoA e=found last=16 s=25 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAtyKMyC+oIrQRFrtrUePoV0YCMgrtpbw+hfab+Sk7Tty/rp6c1/0B3DTnV+fdTxQOa5mPBWhTlJiA priv=MEcCAQAwBQYDK2VxBDsEOe/pG32oiVp4vu2b4fbdwhEaOzzxHHxv9wlwvAnDBekwbdFN5QfjbkSZsXAKme7im7vHKJHFEqQSNA== msg=X+U/GIEJw0YeIuMwAj8C97CqgP2iVe9h1LxsQ6WMvwiXdyplqS8yNSvljAiBf15iDD6Jw1kMIUoVXn2vr/qggA== sig=OjblSUt7JK7hi5e1FD6e6mtuDtDvwxwFQEgmxCjbuxgpHkg3xwuP/UPLtzur6g83M3Z7jbkQUliA1FSg0UnqXnzFRzmtlGWgazArGriURRoBpYkoIuqF6VgZZEMRs8wzXSBvWUaJ0CnKdkIkfJpZTSIA e=found last=15 s=23 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAirocZsVuqKD15CwowjLDl89/h4csj6DOvVJ4WH55WBj03DXu+gQ8gNv9d34FwHwDeLxebFriphqA priv=MEcCAQAwBQYDK2VxBDsEORrDo6zqRaWCqEEMZAXBdxCGLXvqWzVPPCdGLKWA9svI+zT1Ur+o+HHwcIDm95+goOnNz6DsTauQ/w== msg=fJ/D2KBA4FesBltES3ZScR4gef0itKAQfNM7fa7R/V3dgfI1Wperz/sZSgvKW43YP7MW6LFFiaJePZQMuRWI7Q== sig=/r80MkWzpgCfsDFZvX10FJrwKxyneEocmv2gjt2bSqrIKKHiu7onzm0KnwWPnKBSVkQffiyXEgCADpZi8shJ4KdnqU/TKy44ymgIQkukBMO9zC1kOHxfwR80OJAnk1unHuLdRMhji8cInA86XJRVejQA e=found last=16 s=25 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAPnAH2puP/6qA9jnveR+iDhcei6FLWrzC9LLBlwecuS26B3bJaoG0OYCC/Ml6QXw6QI+7Ue3SKGaA priv=MEcCAQAwBQYDK2VxBDsEOZ2BYGFlomgvzDzfjNXdM+twDSaA830n1ykpWlsWleAo5+VTP8T47Sq0f5iDZfwtyv+rm9khmrtW4A== msg=IakKdzd1JmGjX50FXsrKG9FHKICmz9McApAECQVoYIXA9wB5tUmKnX1iWt0OylBvpxKs6+IwxFWJIi12LGTdSg== sig=i4Jyl2h9mWw35WiUYmW1JWmT1K6BjPiUI2IRJB5EYJPnOm3PBxK0Y1aHsyWmP6vqepWbSr6+sbQAHWU81PO89Y/q1qmuRrAg2sPzV6tifdcyRnyMgLN3CrejpAu8RxxUsoelg6i8CdbPVrO9lgkpqyQA e=found last=27 s=27 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoASUjcPLZf2yi4ef6aqcaaP3R2ocMplPzOluY7xPD03nBTJDdhBE3925wKVy+9z2+eSvOyh9WvAoaA priv=MEcCAQAwBQYDK2VxBDsEOWHC/Fa0ceCsLaMs501CNDcPXK3W7bGj6AcOFQtpHm65FIcpnPLw2vP8A8ndZWmp/xRx5IEd4JVelA== msg=yd1laan/FHHkgR3glV6UlfqR3z2mnhOj5LO9Xxk0ytl7coyU7hSMbuerxQuzLjQW+uNedowfj8a6EJYT620rHA== sig=CNXtVB3TzQ+u/u35E5W6Rug33xKNZ+Z1ePilj9nJnnHikffmizI+KQztu0eV63GqFF+DFJPDnWuAZ8s3573HQEcSQPxQeCJQsRPjGNRy54WNvCiiLv+bA9Yh8nHxZmVAUttnGTMaeBFpsM0Xnw54whUA e=found last=21 s=25 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoANbEivT7h1tB7JMhdqlwZwTpM7J7fMVRc9p0eiYxaj5US/9byiK+d5BekVPoJNC61aket4tI5y+8A priv=MEcCAQAwBQYDK2VxBDsEOY8yLyrbFKhEoX+8WFzj9CySMhg1hY5ieIqQJ3Rn03To5TZBLyUfgjcHsBT0tR50pUPK9+62gy9OaA== msg=Yjk6tTPJ2ulm/qPgfwfd+BBnmA7hQbf7Jn1/HhhJIL73gWRwLQuwmlFENkFgLA4ZLXFYc1sEYVAJMwpdF7YcPQ== sig=EJMu48dKk4DJlBl6iRi1ryMJKBPuGxBRCnMD3EdwuaqSzZGBOK0RhWWWermMy2EPcmHcryFFteGAgiWSSWwzwCr3Vj+GcI3ll114UZPDFo4ICl4ky6IYUciDNNAjOp0AE3FkQdvaYlJxdyzIvpCC4gMA e=found last=26 s=24 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAWcUTQpvfJPN5s4z3Mv7hiNOxO4Y2Pb3c+ZIfx+hoNsEspTL1n1M96U4th8d1Kdnu6EOdjRtmmrYA priv=MEcCAQAwBQYDK2VxBDsEOb+S+1e20DDdzRWmurQVpHcOzzSOxBh28JJhmOL8NVGnAhDacBtUSaGjpCIOEy+z0E0YfmFlF08w4Q== msg=29bJSs0XxIfv8Oem1FprJtXxeDy0ekRdCAaR2ND4CgY6Ahu916lBW2trTJtS1UcQ+xgaQ/KFFedXRrY+4jmFqg== sig=F8Ba2RboRS88rMMFvwT0tpMO0lQnOHXRrBT/+cGROV20JWs5X4ZF6FfqF9xf0hf3Mk9Pv86ZB8IA0kUYiNfDJWS+LXlf9JLZ5SQLf9TA291sjywm6ZCftxP0gWsvaWKed9oi2olp6l8UW0LU7LuSQiUA e=found last=18 s=25 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAdNYg2f/eC2RxvDH7k48A/7lTLOD3Kr4h39qCRFfUC3Redf/MiE0uY4qAaTzxQ2M7Oz/dglw5cT+A priv=MEcCAQAwBQYDK2VxBDsEOYN6aLwlVf6G5caSu0jQ31J7BmMrBxEY4qMFU+bfpOeMbnZyv+VL9MNJGBLe4elqLnCxYQjwmwLHEA== msg=i4xylrbe7cpiXIDrQnNUkajM5epi1j8yt42Q4/UHb2uR7YUkFBho+hrqWtglusdVlFkAw6QcqRCY0X06/TxNFg== sig=HtIuC6kWIW+zacrgtcH+4mzSWAW1qrSuFWqlguV8EPHOuda99u8m5qgC+esBIH7cMR2ykLM63o2Awvfw2nxGvlMVVmpbQLY8GEbRXi1IQp0XG7ZFDsQx+FtdQ17N14e/zHmOIVmQ088UQY2JA7oTnCUA e=found 211 iterations", + "pub=MEMwBQYDK2VxAzoAnnPjJ+CyEI/r0a2zEuSBuU0mnclLsRycHyvOtB1xh+OseLVjwnKq5NNusUNw2+3SSe7BV7alWFSA priv=MEcCAQAwBQYDK2VxBDsEOfC4Hz1d3GZpSsIGCDHrRcp4Nv6NKoT+QB2qPp3CYU2rvS462xYJRR6yTJmJFfHiFsR76Tfulc9HUQ== msg=NkKiullL1pH8HaaYEH7KcP2BFVzxxrmw4IujkuTh6LxY7w/JfOpcCbaxZB2u7/En/gzwpTk8S25PCOGls90Kwg== sig=d9mWJbROGQFmqY1H32NRzHW8JvLw8tYF9fwYtCl0/3p80zp7Yy1aP+9PmJhegrZkzOvtbixVOCWA/TCqnELOPVULm9RYgypq0WNijWxSt2sQqe681Fn6F1N8hon6XpJgIIDf/j5m1k8vk1UCtXzkhTkA e=found last=27 s=26 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAx2XVzGUWkYwyB9TYULwOBj9xbbXfou2WbAqKjMLFkiLwnr+617XRG+j2nX1Yt7WAPhXbnla8XdkA priv=MEcCAQAwBQYDK2VxBDsEORtWW4V30zWq0wifMIdF0Y072YctZ0G/M2i+g3JyJmEWDca0e7SXm7ikA3KX0cPWV8eiWCo5BZ8+lg== msg=Co/5gufJZdaHCA+PQFvjAMcIFTvFmmoEJ5ZsrubIOsquxHNzUdg2R+K2vtStvmyNDHVX3IeiK2i775bSuoFpDg== sig=S6ee7DAM9H38KCAJC6oHEKs0qFPrdVdcuPc8YKrADjICutIKAL7HIeBbtPR+BuylyZJJC31AKm0AHL/6HwJsk3hMNot/1JPpi4qd7x8aphPp6qgz+YhoWyB08UReeEzQgZRGp6XQCPbz/wVzmT4YpzUA e=found last=15 s=25 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAohgMGuHgfZQG2AS4IABkF9Wd3tWKtGpLopUeE7wkNEMkpxMiW0R2K50JpcJcjc44bVB6AQn/rdoA priv=MEcCAQAwBQYDK2VxBDsEObMQOkfR8Hd+i5sZkExV3mFHVfsEGzqIzjNt+uwMaQQvRS+mvTmz0UNebxnMdSe5eUqS+95ZOHBCSQ== msg=VmCrJzV5BdhyxfEsKYF7bP4kPDMvFmPtVkkGjvK4Z4cMIBhByHzumyBqPYq78SIstTK9OUldW3+ohgO+xAdfbw== sig=LplBKx4ULbo2ri97hV6tGVc15rDLehvbokV5kxFr/BE2xscQlt40CDnxaOnWPdsnZI0qwcBCR2CAAJZpW7QZ7jAm/wVgc9WtYlZeflBh+Io7hgloGkbn6cKIaH5tvvbbxqvbL2dKcMdoxIAEUVaiMikA e=found last=20 s=24 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoArY4wSiKI64+8DlpxFf3Lt7hHs8dajqeWhaJodsSGd5bpaJSJFrdSUKbM4r8oMWXJBgM9/1oObEYA priv=MEcCAQAwBQYDK2VxBDsEOQ/iQUE/ocA3MaoQqP49p10rUw80LWmFKMh+hIiNwkhLFxr6Gf7/Vy0jxeY1d2QFW4axr7RRCuR0mA== msg=MbfXCb7ISUyCJr8o/pVucmibp3gbQ8ey6S9FsLwKZwGwxC9i2Tn+q4EVaREgWB8vlmLoPfFd+agNVKUwYaMzpw== sig=AduoLqGpb7dMbpREci0bCOrgn2zXOzlfTp3I5GO94ai4afYeWA/Tl9AXbMXV60FiP4ys6jg/i98As7vy7yHKiJBz0a25dzJbZGStV78EjpPjwldu2SQJGrqqFSSo/nlYoEJjbfqFZAZLvfks6q94kxcA e=found last=18 s=23 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA7E2aGgWyqwtNXQIjuY6JwJmLlFwgFcO5NkchtmJyKSStUcE9HH+rGMEeQW/VnL+DdTZYMFQuyyEA priv=MEcCAQAwBQYDK2VxBDsEOVhTaKXol5grql99tsVdLD0pmKRbBhf4DD7n/dNEfoaOZrmzgDf8j+QRjs0N3Nrkn1RLNLJaY6EACA== msg=vGnaFKO/mRcppALJgBCYdsaoPgIkKn1R4b42V+M/HTwdthFJjBaSVD4ql6diGHQZxvaeG1aR3kViHc0rNVmWQw== sig=xSzqlmEdLfzYmCOp4FG4YboPs1lwtYRxPQBMfOMsa5TMi21eN3EpveYArcJArEFThkqYBl9U5cqA6tGye548u55M9AV0259pRXPTmr6M5qfG9JmJuVMDzOfnKb3hAoKYS+FN4pJm+hcDvjyKe6Du6z4A e=found last=21 s=27 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAqJXMo40rfnnDwF/WLKbV3VQ/zve3Sql+gFJ4GUWQjrc34P+KxPQNIaJXsEe4Z3DX7SWXnOrI2m4A priv=MEcCAQAwBQYDK2VxBDsEOfwBh5fbgJXwtY6sdaD9jz5JMKn14bv0ZjrhNYeAYs+0MLNaGg2XUOXFA5dlo6E8E0GUJZHQ9N5yMQ== msg=yyoObFNBx4EG4SRGZMGdESrtPYbTDvmSnbnqREw+vuTNfBUFrpl5hrgDw7VbjuBj/CZF/nhKA9tDpenJDjhWcg== sig=rH5WJgjr9txIOfFoTYtHJRTahcajzg527FV6f6iIegR6Swdrcm1CVC/U7XnvlDjQkLnfmfRooJIAx6JKrAJz1Iq+RFXvXJ/tQlhGWZp3DAfcARV1WPiTq02cjACHaGB29ou8dxVKvcVM6fTOZh7FHAcA e=found last=25 s=25 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAxL2zBc3PZe1egu3Vj5PD1vYJC/yg8VTCqJG5DphNuKecVdfzM7UZ2cMUF5/gZd4qrkAyAOJXTNAA priv=MEcCAQAwBQYDK2VxBDsEOTrG/sQ1qXkTipBAct/Qgsg2OzX++k6Fh7YI53T2CbAeZeB2GqDhG5j5/v0AaiIo0R5Q13mau/fqnw== msg=hRsa71toPymVSMqpCXRVstfgrKU+AMFFeauNnSk4yhTqJcIeHo+iLzszgRnUlK7C4FelV0VvCWzLYxzpV4jOSg== sig=p+p18QnGtyTpkeg4Q0kbxTxJh3W32I3CTlG2E7ZBuJDHsYU1nOUbzikybHlSdm2e3RtJLXEFmBUAKnLBYJrT3hQz6NgRrHpI/eAb8nWO8L+wm6HTgkB/Ak7KUACxRjFlEGdB+ymctjbtVNM3ekE0ZDoA e=found last=17 s=25 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA6whQFIqEZYROL4KK89bwNZWAs0xBlTwMpgLet5IHC3mZYXb45xA2voIMWk5sA0hA3j5QCLDoTQwA priv=MEcCAQAwBQYDK2VxBDsEOZ05ns9oZRAymXLiTKtmcjLVEYoKt46rZkBtuwmkWqXTvKv93mA2DA8NnIJepjFr7ljQVoUyPvlBTQ== msg=EG5J8XnEBJH7ZQCAkJZWF65fkQG2kJczOW4JcMOX9KzITbYXdWHVZTT1NpoFaZfiZbq3wtcz4C+t18B4jJLXhw== sig=x5MaBVx2E8sNLY7CIl33AldRHe4Sk7w0JEQCPQgToI41EoxBiVf0kJLL5VoeywglcuE2DlwIYFeAXCGa6GRYLoCqiGlteA3TNX6fUzhKCQ/lvKt48BEqwUOJes0BMOu0cEsyHFEQzpZzX6N258ai5hIA e=found last=21 s=33 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAuJtPFt3DoG7OtET4PRI/y8A/ZrihpJtnNKiEePpnFIYwqw0kBbJQb9KmT2doyFwnIM54SWrQOcEA priv=MEcCAQAwBQYDK2VxBDsEOYjWb7rer6mAecI4cNBhh+Pj5ZI7I4HfD9Amiv1LDNVQ8t5skhLU2tiaNMB7xqdx+MSqvMESCBFhrQ== msg=66zlTqMYZ7GRvLEKIaJVypcictbC5ah5/KNoS4TW28oUUlILvvkHAxbtjubvBNGVkFBOz/QAXcYErB0OoKrTDQ== sig=MTrXPkTIHqlkMitzJwjE8B1N+HgDbL62RT6Ol7M8jzaY6gHVdGDOKrP7zxGMynB6e7FOfFI1ie+Atc2XykQWKvWE2oSQqTnKZjcolXvFa0DrrFlW3GA8aPSxJsvfRUAUdghGnU3Gh74eVXfvopPZCBcA e=found last=22 s=24 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWRnCAVn5El+hZtgHUEFStIrE0AwYhg7Pu+j4cvUN8o7BO5NxHHtoIKAZ8rZztK8q80rAjZI1/roA priv=MEcCAQAwBQYDK2VxBDsEOfOx3NXSXMedd0nvbM8Z1oSGJRUzmVz9gGFoZnRCtw/JvEo5XdFd+gF9DVuHeHcx/et/sFya8YPOWg== msg=p+GE6vgUZAJzBaxU3mQidHUEOwimxiLcEV96NHlXwN9YgiUfbxcY9vs1UrPmeYHcgGJdSM6OO9EvrY30Z5Jvhw== sig=5DlAfNAvdxow5wEpWM2v1DoAJ6eMnqFW051thBuLEvdbG0lzgI5Jle47xm7oUOxuANYGxSOMV7wAdRfOiBQOAi1AKN0r7dwVk7ETI/C7Kb3ssccnUaSSWLY4TqK3iN1LxfX8Lg++nqqUHtnBi9NyaQgA e=found last=21 s=24 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAP0w4iyfab2Y/37yHcdxddeKaut6UwLgWt/n7UgZXMAfcTgwUZapn8CmlXdkuJXK4hnrm+/qDiu8A priv=MEcCAQAwBQYDK2VxBDsEOSsMaC5haNFvBAizLDswHhPxzObc4krga/o9SVdu5vaK+aurRtXTk3aDU1XVh4Vwd+rVqBRrthX4lg== msg=ccszAupl7RnUvIBetDA6gsPvkycXm/eojNwly28xJb0QLK+KZi4nv2mabplqWsb0p/+RD08YIxdWRQzCH7BAoA== sig=Zli7mPEjd6oCp3NcPLAUuGLlPCjIcWkziLcwj8jUOMBINzbAzf4l2ye4Iez7iXvkd5P22Z+n+fkA+nXqi20iGb2sT5Zgku864jmd/38YvlJQ/roGaeZUi4s54X/WN2r68EJ+j/ULHYFeQlwglYRIFjQA e=found last=22 s=23 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoARw7gj489xwkH2SUWDILgD4M6D3wp/4ho7pXbgkDmyIChEipyyxdeJXBaBT7Y9fs2zrYLPG8vrteA priv=MEcCAQAwBQYDK2VxBDsEOUlaQt5TubjT6ARox2CtRtLmwFhBESJWQ4pEKkg8qT9CuHlPgwDblAFdYFDkrxzG1v3hpYTeYjB3nw== msg=2sGZ2xk26dmUWHLhPv0w0KG0f/CVhbcGdYcVbvZvXmDSBXRcqooQH/SvV+aiBCZyVLjjpZWyoor2BbNF/dCqaQ== sig=eAQkZ4SRrJhWF4CurSKhGB124aLwhkj4wGYRVm3G884s743X7EshB5ZQlLg+Uo+HwSuwecTZMbwA+VHu5B6TEvJO5oGv4qu56OoOJ3qsKc+mtM9Y6L9PPBEbqlupxep/crR/6K/YOD29GcoFIMqVci4A e=found last=22 s=27 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAUi8quCwlVUpYB6DZ7W8+CcM9bYGfbyb86HPnw7ucIFUsIYT2nOTnE/xIvngcEkb9XgQNagyyvsuA priv=MEcCAQAwBQYDK2VxBDsEOVyVFCnWKFU/8y4KTLVmqWuts5ojpiBfUFweaXIPWF3x0SEHjF9cgzVWnZUUbqNueGWqnlsuXAsd1A== msg=0ihYBS/tuh8MwrDdCBKxygz35u3Kd31zXRzZ/QLiYzqzcrwwlOrSHPD82YaPEupU5t90/6x/wjyxvBazNlje2g== sig=UcgfyPBQCE9YtVB3iUouVhOSGpL30TWGwSn6alpwH5xbu9e0yp+no3XIAnBP17BLRG/RtnD4jhyAWv5pmrvdcAn8qsS4TD9/5uWVKm6hvr4S5Sg8+Zb6D9NC0wYiORsVCzijGGvE2h/iBp5j9t97GyMA e=found last=15 s=25 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoARGx43Orjpk77yeNiFVY4Htv7FV23P2vlHE4Ip7mPcbz2RgxF9st1ozg+XvMLPlj/9DHyZ2V+xWQA priv=MEcCAQAwBQYDK2VxBDsEOQDmJnYPoOMQSvQpqvBYQ9N1/yuUicU2mHTbLV5f4Hz8P5m5IsTca7FSKmihSrWSYOlRl/MbJM867g== msg=WyQGNVU8Z8ggI8D6F7Ng9XPO/XaV8gA0hTbwipWkE6yIVvBfp69JoYXnMur4Qt4jF0jh99GuOU11EeBBb8qP0Q== sig=Oh/JGihIHGsFcJbWao0ilZRWJ1K0D4GlEz2GQ5hdM7HsOFKZlUpBgrvEWvgjkXKaVWgbU++o/lwA+BxDugKN/fVFIkudPLyp6fviw89irlhp5Atxm7JecRTMttHa44kOX+F+u+m/90/T9tCalJrJaAAA e=found last=18 s=24 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAM9m07np6alOLSfCQGR9Z/D+/MYNn+yE7zUbh3mtjIhSdkbLEhG1ionGXGhJ6gfOUs+PXqcqQw+mA priv=MEcCAQAwBQYDK2VxBDsEOackYRAg3M/UrHwF791wHrCgNrI2zezTyVJwbZY+t+k8XyBYLeOHNTTNem2wiS1RHaTk+eePluROmA== msg=KUx2hnuRwiavhLifLlzKxTvQS9VSYCGHT2D0REaILMuH/GPchfk3+Yp3JyTF1JjZyQEQoJgWUsdN2gHLuzshIA== sig=PsHvXuQ+ADwpndT6Rm0bMHLT9QZSH6qKgjnhm0tWKCP6EULyYceioxDSTvHI/J7KcVxfV4E+bPAAuLHhvWEyV/qw9ZXX+1EycyM2pW7564IE/VrZ/WeE8sPlxTyU0VM0hjFFt2kiMWVIqtYKTFYFDhIA e=found last=25 s=24 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAu5MPMJQZkUxNxtxUINqPBUggG6mknY8Dq1GLlDMBsFXPoJT2SgQM3iw/MZqQtYlFcxyLXae9R4eA priv=MEcCAQAwBQYDK2VxBDsEOdcsBIRApPIbi8gpUqZSt7AzHCBaJ5EmhRHKTGborAdhQfPtubi8SfZIRQjIixcx8Go1P0tZP/gblA== msg=ZREvSeAi/KO3ZBeoXge8uvFGvJZPv+U17xZdx3BmauuMRyv8nMRP8qXWv6UUJ8Kgkex3vLNRh7z8zp+f2UFo1g== sig=CcvXFloPa9K7yZgIBYbbjmlJv+pNoOqWHo/aA5d4dHk4Dj9fK4JeiCehb08HAiCzuRth7GRgbyeAx/Twcm0NwWKhvYifLnDmQ8N3GaJq99Uv3a5pCBjSixT3pynV6e42+XEsFb0WwJba/jUJ95jakj8A e=found 209 iterations", + "pub=MEMwBQYDK2VxAzoAy5GWQk3JE5E1jUjxv0sQkN4MsfY/pOd2O9Xt0epCqaZ8/kDoiwA0wbhRGU40wQhUyhZl+QIRFCuA priv=MEcCAQAwBQYDK2VxBDsEOSpl2OW7YQe4h0taC4/LoOcIuje+mTNcv7tnTIc+dE4Bkg+oeh3NqlDT57Ic9AoKj+z8x11tiyF1nQ== msg=dKWV5dRiSTfepHt116QDD28Yolt0GQS9IygM9N0+wJ4XPpMaTdNciStPrXnOktYh4/X7tOkcInKmDbqa/+1hOA== sig=cSrWe955zXa4EFOd32YIj4QmVyvoCG3BUCf7Z3qOwMqx+OR6d0LnpjBMymVjkBH4PiF+JRG1+PCAG4p861T2Iyr5vKcTEpCoPFXiS8SojmJ3Zvkw0roNH9k1JLYerYOfMm6bfz5J37kE2ZXFM2LFih0A e=found last=27 s=23 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAQT0mR4WyPwq6MyNcI+FgNfB48fZscoSmaP7NtMbn7IocCXOPsi7xufGkf/nTiahGSE1vTz7LxPSA priv=MEcCAQAwBQYDK2VxBDsEOaBaXy4ylpC6XtIdJMXJMVTPUeU5En+UgM7xGKineoy5ErSjeS8txgbCROL8dCtPq3rfuxvoU36uJg== msg=Oy/bRD/fiKQv1Fi7doLqgSxFLlhDjYYE3mqurMzzPEMYNpBHfyPkiHgs8GCwmtqagnFooDowuwHJyts803Ki+Q== sig=45nCi8Dlbz30GI/F8ZOPXLIid/fYn0k74rT52ZQ1VmsZfmrBhelpSBoFj+98BXjNnJD/PnwRekSAWPsmkzpPBmmSO6grjSUcBU9JOUEU3ncq+XTYPlzrKk0oMpPisydh0I8srJmTPk7bk0jwVeClHTUA e=found last=17 s=25 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAbfQVRd9AMYKTrtjIUFuNyc2BYpbyvuQQN10jObYbS9WOqbZ7cLvvtlHeUf4dgFfAl9paffhgUScA priv=MEcCAQAwBQYDK2VxBDsEOfjOTbvlywlKu9BmAfqSqCik8yOENLKFsyQrmTt6F5JiZyDzFhJpoURdU0hZsxc7v/oWvtCwXL+kRw== msg=51AI3Q+qpWUROpokk+SeluLsjq59adCySVQXqQSjH2nVv8otMo0qPBPfe6NL65Cn+xw7H8KkCwFvrJUVOwkWaQ== sig=pJXY41IylXgfceB1r14PYCkqbrTVA1XOh8RTJQT9nhSgnJVv0xWMfU6NkWK+/hcli7PXxKqw+aUAF7jqkZOaMq49o0Iq1clEnf9e6kFIXRPJhNH2sJWaGjcpH7nNTx+v6ZTbjX3uCZBIA4JtzkXFcygA e=found last=20 s=27 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAyTjPAykmPP6Ysito7iCVyFGlFoCI1aa87ic167CRlCflbGsDTwbOeW1Lz/EmvDCbTJREfSLAZ0KA priv=MEcCAQAwBQYDK2VxBDsEORA/zX48l4LvtTGudbqw5Xg9kV6F0QJLM30DfIW2bwAo3zspyCbjjHyyi3YCopD2whXXKyvjJAmmKQ== msg=dq0a4c8sAaiyHc4Dt7BBNVNXY5FtY4lYWVB7bfUX2/pBSrpLUTiJM+Q742tAYLFZrKulwQn4ogyyVVGr9t5whg== sig=TmXLQmZUoy5PVTfCRExcpojBCcCbFi92aPaACu2Nzajfa7RG8sZ3enMFQaUolPEINF1rQ7Xr43AAAdZ4J4+I/+qFmnU6OjY6O+/V5F/+1WKlnRAQ+Y1OiVpzdlFG6W0lGoji8/jIoErnBUGjUnHyFxcA e=found 129 iterations", + "pub=MEMwBQYDK2VxAzoA98wI4/W1pH/jS5r7e+aviffaD1As4UmILheb1uge6jm02kGnn9qihfIjYOcHUiOWc7t1D0plnq2A priv=MEcCAQAwBQYDK2VxBDsEOZcuLUD9y2czS0nBeCOJzhAhnbr4bWnmvjxCICVJLVov8zyrgpd4CqP2fzGo0fxWta+QeggssU7NOg== msg=hhVqqDcHkFVviZIN/X8PMzxRF0MpHPNCraEWLGbCklGXwnm5JzvOf6Q2B2G6V8J7vYnWGb1vr/I4T/QvQ9y/UA== sig=+kCURkdiIrF1/jzF71ViUjpLY3rZLfzmnKnCTsUFlHq7Z70LMxOZ3kVL0fD/YFX/6kMLROEgrRQA7yHVuzxMu/iGxjQD+XQnepjH0uU6yqBleaiSWvGmCpbI0I8lacve4YrDrX7r4dxL0RGtk2MXcigA e=found last=17 s=36 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAgaIEK3jEhV+dpD5itqLTzF0Iw2VHOO85rmWCUKInNsM9AVMdjqRStjtxS1ov7csob47pobI206eA priv=MEcCAQAwBQYDK2VxBDsEOScQvXdhocR0fqC1lrRM7SyQzpqoFv7UqnNiq3sqlesO9iyi+kBEpycFQ9O/gNo2CNvzRIbtJtPIiw== msg=D1R2eQ/t39jGrxFsXK57xaPxoSXJdjjSQKiT2r1fmzYbl4CtP7VF/57wUss1F1lxyx7D3Ngt4zAKNeTXCmEE9w== sig=RZ+mmatttuOVzBnRzNmxhy1CVbl5iQzDPVojo+Za0Hi8aWJ4gg26mQ+SnYapFMT71FrKvWye0AQAy1IsSELmPa6dfQhFyjPmPh96HVgZDQyV34hHMaL2moUgzCubhlurb7T6B9dlEdBvdFLuCBN9KTYA e=found last=15 s=24 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAaZWucWTb8iZ5IfwxL0mrnVhITnJAWdPrjJmoekj2TwWtewJ1xYBYQj+70s81K0qwlSeOTuXld9kA priv=MEcCAQAwBQYDK2VxBDsEOSyftUCFiAyRwTlS6ZkLu5FOW9VBSnJ+TKDp+glY+auErWiR+XcgJfM6gXnKqglKlGZ4aQZmq3Kxmg== msg=ASTqxTETQZAIQQ6U+NHy1GP2YG4boXjNMIdVNn/VGJ60DqiYnLdW5yMeiq2NFPs/eVUzLbdykvz1C6Bc9SmWMQ== sig=QDhiKCVatcKxGVBlaom8IanHx8B5aHPSLEzzy8ofh9ohrOyzMEdqlv5kf9gDuvxqv9RVhOWSi6KAncJBXMnICHS+b5M1UeqRMjsI6fkdXwR77rFM+BF0N//v57pJPtvqqvLfxkC4o8XQj/fJA4qmOz4A e=found last=24 s=25 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAeJDeb/brTbG+aVtwfyFDli+CpcvS/t5wfTzRh9OpOtzBDCXcHqgPVNAnhl2kjzTBCddAxGX7SN2A priv=MEcCAQAwBQYDK2VxBDsEOR9QhtcAkWOsxlEduGI8NZlut94GfXNnvCMBA42i0waihTxpOtOuJ3fDlmWJUH12vQUg9n15uD/UPg== msg=aGk9vrRMGq9PKdGlQsYB3kKSQ74kdFzNr+6M/dCzDaTa8DP77/w+nMUKjib2ECab/MPS7852KwhpQppOmOkHEg== sig=npDD/sHMgO5uYavZe5mRfPselcUc9qskvF5n1nZwsnUOR65wtqU5Lt23i5I9QX3P0/q6gKPsuyEAHjZ/rn4ufUQl3xTmGw9I7nP3RM8gLGdVtS5D+YCTw7Im8hJeAFKdp4bNC/mSiue05boiBInbJAAA e=found last=18 s=24 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAEZwfvA9cDFPgk945H7Ju+jYVJpK1bmq5OLSHmOoml3cXCWHnAkU+1S1xMBKGODD/4XtXq2ciuxcA priv=MEcCAQAwBQYDK2VxBDsEOTBXgIZzd0Qq+HPcfQq8YWULDjD2+WwgflbOiojsHHKGcdM9QxGyxul8pxMYbkWlL2yvoTVAadbs8w== msg=Lnfpr+kWeRNxVDJuGa+8csc5n8svPYZXDccVnTmhFQLspzsbUELyjbd+L9meYvT8YV7xtHyamgGjpeBpe2OIYA== sig=vMc7Y8mSnUsnvItk4E8ROlumdj/VnuEfj5WS4QVyEFfpU4f35L2vYF+YnjDmxq8P1K6hSPn0CNaAxxaTJrjbdV0tix7ck+RbJC1HQ9uHvXDGYgXzoSsXGSLbKLujA7+AwFk6bFvizz9pod2xtEJnbAcA e=found last=20 s=25 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAnCZozdlVMtf7kyX4j+ixIJUDW3uJ2m4DYAPkcRG95JwXY8beEfG8rn9YwVnd9Xeu5RC5VdYQXHyA priv=MEcCAQAwBQYDK2VxBDsEObSDINQFpIvXXl+flZz5I5cd1+x6NnAIKGTCwog6wfCUbWrgYQjlmwgwY3CLdtSXe0DabTRVTXG3oA== msg=1ojkHnlheJFSre7WXA8NJGuyYqVtZd0M58zq7ut737k8xPoW3Sj3gYVzmqZAyW/hIwGXp4KOWaed2wwLrWf1NQ== sig=LeXrGxEUXRdEbBPH4TY8qSWo/6EQpbo733vyF9ecnQa4oNEgk7wU5ujHvALm6Mm2NdzcAosFvYcA0BPx0TnqDevxgPbDrgpMdbbcHuTSsXQSpAt1DKXmOP+LPB2opFakM4fa2Ds8wGDxu1q8Lsk9vz4A e=found last=22 s=25 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA4uxaiolcI76JiX2FBPU5OM222xmsH8lQhDH8z9bfEoGdDuNMWC4VQbE/9RAIN+B35qwlpIQRWA2A priv=MEcCAQAwBQYDK2VxBDsEOX5gwUdMKywUVhm7MCvWZamFT7ub42Zg5oSqZ1Jg4/tpCRRIiDIDWWmSkIndzop8eEP4y8NP+hJfEg== msg=hgTkvAyYB35NWU3R9/g0jaoBLQJRwNDNsBxcx+NY9LEIfzKYuVJ90cvyzTCAptmt1MjhkqFzndhkKqbaG7U5Bg== sig=2mQpr9v736cXmKPdw7qmkFG4kf0l1OlPpBFKDH0W2HCTNjY89RrAD844xQ4+/SF2+0sDPs3gsEmArHh78HXToaaDqz8pvntKZJZotrGuhsPeQNVWHK4b2yeKdeI2cWLGUoJW2Uxv/fZo/qcZEAjZFjMA e=found last=20 s=29 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAFIJxWXLipU95ONBhxIYR1YXXWQX2QcdDgUsW1MIZAFUUSf0yvD69E+oHVIKCCkPF5ZOekjUrU0sA priv=MEcCAQAwBQYDK2VxBDsEObhFM82pDSmAgbEvNeRGDt9RKoGFftCiQ8q7c+fNdonimKrKBaSshE7HXt8prd9+NyqKaeyWU07cNA== msg=pZUgZQLTL8XLAkmXFajBlO3SpgCKquIax5pKza79NMZEaI7UC/aucUqYlhbN1iKld5nUHG4XV7LQOSh/AUUj5w== sig=9k3v7dOsLWASQW+aWWoU7lzii+ns7UmmfofwrjYnc73t4qlTBOiKub+G0+8hhqd0RiJMzu8gkBSAz9uxCGsHIQXoYvDZiDw+HvAZ/5fBsUzZ5AA6VgtMyzd3r0ueY8cO8ba4bkFIppSxFdI7hurtRAIA e=found last=25 s=29 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoApWQJPi4Djhjd6BFy07gnpMQ+0YsnOCB61rtTWNAjcZrEx0NSglFN9Lk8NJpU2bY3IQ9GOPUloN8A priv=MEcCAQAwBQYDK2VxBDsEOTmmcMEBp4yB9HgY2mw6uz5FfG1FbFDwv70cuiaQkisTZHLSmrJsV4st2kcRjD1d7ZxJ2lRNb4/fVw== msg=EZDIMzWcQq9bsU3mSjlBz0l0eyttmZR7RwdeAUW5lP6RGwWsFvOxo3eDx2BKFoGVC0689Ci6fxzGbflBa6JgMg== sig=b69eqBXX5f5CN73TTQkJopCHtIYglUtKuIN0gMiwDeXx/Uz+j9WU5NsbBX2U0+kkbXsmE8I174qA0iWHUS82h75V0DXztnvXf4hAVD4rOF0n0nhxCw6kNTj28peA6I5Vj9LgUyDr3oczhpkGFaAbxg8A e=found last=27 s=25 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAiJKjvPiVSf7wZB1iAHxdpV9E3OHq08ZMgQvZe2gm2BbBrQWFD6e0VlNcX9vDFGu8afF3YQqbz1EA priv=MEcCAQAwBQYDK2VxBDsEOYcxtnPZi08G6QXU8OfLy62TYXs3mtTx1X6fvLOwbSzCwydBG8VLhkF3mfdCcq5CB/ZKWe5Rikt2CA== msg=Z1MSxB477BYCBjBq4EGnHmUsbqU368x6DcaJvJ9YYq2lkY5jLlT815flCBI+v3+iMSPnAIGuFUjIg43nEvpDJQ== sig=6SiIwj8C/vAYBXH665sziyyM+EUQFPXqRTU3jugIBUZkSVRMxncCF505OPR43jYCGr8A+DoFRIsATJ1yzt/QVT31SpfvaMioMHuJJrDYPRaeapHeh6PQ1ab02zKY+8KIouO3RiVytlquAlkxlg9QghkA e=found last=24 s=26 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAXZ3Szs4fIxTh9U9ht3gJJd+liRrfbk5VA87l5mnHXfZKajtttZmXYQAAh9ibNCbgMo5z3h3BB2GA priv=MEcCAQAwBQYDK2VxBDsEOfE02r/uIz/VkN9rJFgZF++TJNP2w0YoskMbmEvLXoneUjSLsBC36QnRl6inuH5pvlsKbPYX/dgiag== msg=MB9sGUISvYkYvEZbtsiiA1WILfTOnezHRaVV6gU3dXXia5ELtasFLOsq9DTzUro7N+aXR8WlygyfIlPX8IGltg== sig=jET1M7kLGgHHpx8OGvp3P6X03L9MwbDbNtbAjyTGLnC3nwecJvnSOLuKbIIU3FMoOoATBuKC6n2AnUTFX/AyjJ2F+qvPQvCZQFCYLgoRkVkR16X+qBPz8PcsAdFpuZpIkJRmYGStwX4NvtG8IK3GKj4A e=found last=17 s=26 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAftXNwQnvoCoh5O7ztk3d3vyAefAkEavF2EZ2IKA4SRkETk2D15WgDA83A8PBXbLtjfVH3aKI5ZYA priv=MEcCAQAwBQYDK2VxBDsEOWUxgQkyXUQksSh0/w9hZ3pgBKtek2LbDoTw8xWiuX2Q8GJSI+/3VEVRmgpHWso7Vn7bpgTbLSsBdQ== msg=0cdBPWT8aPjcMa2gLJes1KKDBe4cIFHP7VcEJMY+WZh7HFtyOCfPI5+ZHcLEVj+EKC2ctlEgw+2nqX64xKinpQ== sig=s2XZK6KWWmk6SpRvIce9xYHb4Bs51Jny8OGROAPaaz9E81qjiRIrwuoLpGkiv07Jh+4CPH+UjAiA7Um3QcBj/ul/BTx2gWHo4LidQoBqYR+0i2BXU+Deiwvp/+/9vZqNT8rnUjh3gLA23K3DijtHzgoA e=found 210 iterations", + "pub=MEMwBQYDK2VxAzoAPJysi+15VaL0Mcw7bleNA2hkdEvCSHlfHlx7DoCtw735h2vsRwbY73Rv9rbR/1FERCq9A04kLoGA priv=MEcCAQAwBQYDK2VxBDsEOXioXd30m9bjVGkHQIOxOU+JrvdbcVMKou1DS5w51sScoUBg855vB2sYzxWrGO3LMoad1LYvjlbUMg== msg=fqx969XoZi8BXDzleGqPglbfXY+YKT8B8HEn7u1k49zar47ZeDiQOYMO+AftLmycdh1HnzgvSdvE+1SAmSCKyw== sig=BfBpb06wYxwoY5RRDJ0M9zz8j1JG3S1fGr81MZzNvXGrIvzEg/PmMgtL+2XNgcDUedSSe4Y4vLcAoBCLk0AH18dMF0ogY3utNcc8GLP4W01uYYvel6zeK3+MJIC7uwDUKwOJdOwM1HY3i9D0gIWn+yMA e=found last=26 s=26 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAiJ/K8la2BfxCNwd1iRx1uCyVWSqu/JmYcmtI9djKkKluvHSvcIdYqCSBKwc6EAnlMb2lLSvUMQmA priv=MEcCAQAwBQYDK2VxBDsEOe8Yv7vsJib33W6sAizaHeqIcVIzwmnstfZLmK09QSWgvBaX5xR2NLZSR/rFI2ywS2AttNjyvRrgug== msg=sGg3qRo/Tl/kEmuBh1nuFEDolphrCUlqRixzELOlo8UXhJ+U+vdF3Z5FJDIYnobcfuG4vuvUM2BARKdifcOK2g== sig=a43TfJkZI9qcsJ6VgjTNYT80RDXNZMfZgwMgYWP6VlyfUSvT5K7zUXuyoO5r5qAEdEMLgJEO0Q4AXNdbwvwKAMxBa++nmH7oS5T2wqfBeIU4IhTUGscQK7odbDuqYo4/iG++FlPV63PSXHj5gEyYZDcA e=found last=21 s=25 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoABPj11mmzxmCHg9DkORDpnntxKI2xD1RJ7pea9L7wC3PVfCWm9a8LxPcQRLIXMaBgTWEkXd+DW5CA priv=MEcCAQAwBQYDK2VxBDsEOfVE6DEUgI9+qFygCCe4F2x2lc5Erp2kZQvgzRP1gnnAwhIQ7plLRAbCCM7z/BIgEMZZZpLWJyGG9w== msg=Dd9V1GrRsGBXqwedG4iHxh1XxgYFyvL0E7OxonCustRwFC8Ls5Ll76KEwL9D58kAEQaXqWE8lPyLO0bQcWbH8w== sig=H3riUVqzeQzb1gVT/hUePFEWC6J6rL05DWggTs4KRKHr+a1bBDk3Bu/HqQOcGuFLy9x7WywLxyQAEL2/Ci7z+N5w3zPghJLqU0UXjGwGod89sVgOVefy1z80u8jHOdVcWup/Fn22RDsC8wdMqwCmux0A e=found last=17 s=26 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAL858ZojxkuVh+JrrjGvmd2X4hIMCJUujX5ENFjhY7+gdA19FBsO7R75hl/yUm0okU9io0J+3HEIA priv=MEcCAQAwBQYDK2VxBDsEObMOAaS2WNdcpbrI2xofjMGn390GWJ6Lxh3eoTSW1EQZjuavemuC8+Cr3Fdl0vy+/XBuo0WfN8sRdg== msg=LTODIG1eROZmuOa8jonox/13cQEhcoRaS4wssN0JgERIPabtjlgyJSgCl4HncJuLyk+5DY3WfeE3K0/h3dPljw== sig=K7+DZv1DBasMdvatgnuWBRTEZa5cBWT18gn5mhGK8eiX7cE54Qyw1FG1yOUffkJstqtaC1ZlRZ8AFspCFwr78+Mp+ix6rZxyjh8JY1yxHaYOjfm2x35xHB+1WjWjAnjQnXU6sTqOFeyLFa34bxrP3ykA e=found last=20 s=27 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA9qOrbk3sxhobWSu2MmIBjCkDpXL2YcZpk94spz/3k1OwcJyDCnNURGgSOKrz1IXS9ahjxAL3M2kA priv=MEcCAQAwBQYDK2VxBDsEOazH4mNHeTtnKuGSJbipub13MGMIWQlQHFpilnf/t1XieyfG35dyADH/Q3OJEYT/mTh3xAaDrlRvKA== msg=Cr7KLdy+ybSO/Kjr7J1+7wV5gsCO3mlVBf2ao6hZn+TL3uuKHrlZnY5IAJfIDr2zPykbBcMQ7lQS/dcoO5SHXw== sig=0764FgVtiLMKHuzBI3dTEGzNxEs1zZJcwF3VSJT5CL5SklFGoU5slW2Ru42L/Hc5lNQw11+6zfaA8JzcQHJOvl6pFMpf3cTysOWJt4WgsPjwJFAxSaIYTAq4+WmN+Df9p/yH3i6jz4Lcs11KaSVRsxYA e=found last=22 s=28 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA1PjWkLLOaM0N9qtbz4H6OgMfIuut/fXs4jUb/ubin2fM+w2t7L44RoHNsR3qYIVpjWrVfY/XPn4A priv=MEcCAQAwBQYDK2VxBDsEOei0pGuYP67Ry1R375i/qclmaDgynAv9EyN+q+yllSh8odUb34GCSWC8Sm/tNczvOc38wBvBG5+eHg== msg=tWUzqEgQ9PHROXdlryraW9hvuGJuumnFaEaviPd85FHoDPRQ3+gZdv2L7EEiWUpX9Q57Z8eBw4/4lMY9o47XLw== sig=pIM+wEC2oqkynJ4f4IvCitbN62wzuLH+EfecDCFWKSoL79FB4zvcJ4MgSY147fp8tko1yqxLkvsABgn6rjtIFoP/3K1sN7JcUGiEUTH1a+PvKlVOmCP/0uzrmlUpeD4vOJ63eGDnoBF5CXuDeBpmVSUA e=found 127 iterations", + "pub=MEMwBQYDK2VxAzoAa8UPd8T5RvpdXlbzh3sM42rdOCoGLAcFpbet16AcasfuQp/AWQ4P6Chp1+TpjyWkOeAdL5F67/EA priv=MEcCAQAwBQYDK2VxBDsEOaP2QGwunqNDY3muYDpBY+64JPsKJ6shjMhweptqRY0Lg7H1iqRaRtMr1MhxBN+4Kp4VIj62Q7XA0Q== msg=0boR7v0BBbgrXHVPly6s8Xrq65pVKiBIBUD7p74vPk9ynuD98+sBI5u9q7x3QlyFC5FnX1eSwWLtlU4KUeWQJg== sig=ry4zOt/J8WoT5GW68LhiuvTmp8gAd0UCoUAplOmFNFSkVQaMbw7/VtwRP6+n4bwbZ/DMJHpW2sIAVvhHqKwMpF9PUgpJvvCU/XM3WAnqq341P/jOJkzZOcIxXEp4QbToJVdabwoydbnT21mmHUhQzgkA e=found last=27 s=25 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAvIGUR3zYIQxqksCIBkQSykubbiI2xeJD2Eyoe/detg/0wotNSOK4dTaubfSYy7eAH0++jfWLxNsA priv=MEcCAQAwBQYDK2VxBDsEOQ6MnfgF2YkKcDB6aKeu+aPXiucw8yalGjJ82CXBWVeKOVh9rP77ohhkOZ0z5Qj0xd6P1uquiDDH+Q== msg=tlfdtz4QK3Up6vPfNhq8XzmTuzk/qbbwYd/tiVwMo5MzK52mLqDPU6hLyQWtdFUcftpVJLikT+0Zt69OUy22bA== sig=NLectELX6XuGM1zYVDdODz6gr5NfxRFpoBUbtasvOjTpSKyB49Amauz+Lf4Kk4hpPhMhZBmxrlkA3P+pLOgcNyUIEQWMaGjpbEjrVehwFJDIRe2+AgK8y8MkvS/wm5Uz8J+ND1V8j3KRD/j+lhnwkxoA e=found last=18 s=26 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoADOQ6jgXNUOm9+Q/Ae+ajR9ZWal9giJV1FkJmdImeqsK7joO+lPE7Q3l/QwFemOxzx8Oz4RErYC2A priv=MEcCAQAwBQYDK2VxBDsEOQ2Jhl3Lnp3Ktyftmtq9qWekzO2fALJkNBfqTT7uyDNNfLWdrUEHgt2RSrsV5ENay9CN6WVzUO3a5A== msg=Vvm8ytcOShQJ6w8E9+2PObfcJc9LBGC4SnRmy7BKteyW3UYoKrGz0HPU5KgFW7YlRLnHwY8NP08aUWPx6/IFOQ== sig=mYJQC5ptrhwJre9Q8CqzxnIhaG1N9+TrtxFa2FechKvNX2znkoVxfsM8eWNipypejoQEDn25KKSAFV3XzTD9ZiiXuM+uirtEaXSLjDjzmhVFTvLRBVmvoxmPGXkUfNmPmgxNOlXRFGamxDSHrUG0yDQA e=found 213 iterations", + "pub=MEMwBQYDK2VxAzoAXUIX4IEtC6SAvUlVXspQ931MHjufqzC7RR4vb5v7FNuy698KbGnCJbeuRgeX0+PxTgop9AQjca2A priv=MEcCAQAwBQYDK2VxBDsEOYrxfYKrKWGShIabGgvynt6byPUAbMk2Hdl+0CgknvXcFmaw4M5AIjTss9oDugmUOjkJAdp6wJpANA== msg=rbYyIch8Sin31ZJxbmnM40CAiv2WyrL2auui7lgeazZwFAa/910QPJcctUvwaXQMsfCPsSz0a7zbM2l35xHyuw== sig=sw7pryFEjdTOdUFGrHPDg2eFOJlCQ2sMJK4O4r/Qkao9tgNvujxJe6ZuVajeIlSjP5A2ikc2neIAnQhi5t5rs1qfRuAvpBegD/WBOcu7SAKkBc0uFb/qCP/gv+CqHcuJRYxQqpdQl77jk9/un3VBAx4A e=found last=19 s=25 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAqi94umVf4WIdPcRv/7Ran7musCCIfmtpOMYLxaNQG+lsGpfOryJhkKl87BUfhQbQehz8LVq4mdwA priv=MEcCAQAwBQYDK2VxBDsEOSNyPWzVCQJ3FdefZ6b0T2ds9ur54/rFqE/I4L8NEM42OfGdqd+iV/apG8qLa1b/xz8Jj6qzCjXUYQ== msg=6tAfNAy0EqHZ95fXiil3SgaFJSZY5JMazz3THBP6AuI/MJSQ4/P2/NM8VeW1PT7Fi4zavShvACC3TGI/oGt3sA== sig=xAa/ra8T97UnE9jpPIujKh74+zg3dvA6SiDkF/7qyJDtpjKE8vQOeQEAmVKT3/NZikj3dmP+sWWAvrQUp6K7WfpNX2kGYvXN2wbdQyV+cifzAfzDPvyyyIFTC+Za20rmH406clfEn9ywZEDNFK7oTjkA e=found last=15 s=26 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAteUExLoaBng/RikLTriW0pkfPnH3KpUE5V2s2GrQ3j49swBPpj/6nd8WlvqCxRBtmZbAPiuZKlmA priv=MEcCAQAwBQYDK2VxBDsEOQpsTsWQ1lnD9iK/o5VEJ/1L2yHl3D8oiZbjvmVX1p1Ym9Z+gkVx+Fe49SMi78CL4tOaqBmFj+bKcA== msg=ONJwqONyhe0hI7gXoNg7sX6SsI18/udsjIjRRpRuvtPE2UNmfoGwqfBHv4qkXC6LKdXMrwOXLgw66+TFc1bhag== sig=Vt923Gh0PtHg/YapeWqVABY/JvAFisjEGNNvREnuV0CRlLNd5O8qBgpNihrSe9p7cU1Bi7Ufl0wAMQWkhtyn1out/x8gZ5fkW5BsPL5bRYs4R/XgaVM/qVB+56mSHC3Vhqxf3qIfZYG1PQ/zQaWmBgQA e=found last=23 s=25 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAggiXCrl+l87eUsvcab9QnS3+kGGA3Lv+KokaQjnvqH29v7UjgDyJeIFNp2qiJVXs6KhSRq3eay6A priv=MEcCAQAwBQYDK2VxBDsEOdfQCLrr5X6gLEKN+i1IFtTMN0U6gKJuLXF2+IVLBl43Brcms/Os9S7TwqBaEXj7002j73h2XftmIA== msg=CpAAgiI3l7TOvsyUGAUIxGV8JMGl1CWQhx3jYxgSYzuqgpXexx0Rx0QJhoKB5OJljtyNyW6lSYHWfvKta+6w7A== sig=aBzniq2eyhF8a0jz0MlKTXPO4T4IiwNMvKXlWe9/tV44clBvWbUMgVtg690bJYceO12mhIdtSmcAARa7QpOdLOmlFe8pfp/0UNMYRxpPyjeIqPbMK6xHi3cNv9LyjsEWPZ+5SAdqk8zuFmGxEoabIx0A e=found last=24 s=25 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA8qk/fJv3V44nS3Xa4tinaf/QpN8G2EitQ85TIApEh0jZCgQLi3UsIZRehp3jn8kMWvDm5geIJ72A priv=MEcCAQAwBQYDK2VxBDsEOR88avD52a5F7Bccg2OSrWnLZig32rvS5ggQVGWk3Hr8Oi1+5Hm4jhudKVMhvU3XLuzP1TuK5jePVg== msg=Omo/w5GjzxircM5ech8AL4BWdwWFqKZR88lwL5ayBvZQ/BiWXcCTOgn0GXs7zK700XSxc4VHsa1NcLkPZmE7TA== sig=nYhR5UUvRkAqtkSQzUUmgmJ5KeBY/jWS0ev6c0XEruDSR+55k3JFJuWr9brCKXerH0zeVQvOyy+AtoCuWSGdvA5BK62JKnHDZfA3Juim21yymIRBPdtdKpkojGMnqYSS5NRhT2kjRzSZZhccHiUvgiMA e=found last=23 s=26 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAvA3mLEn5X/R2NVc8HWNeRLBMR9dEv59pdUUdnrhLV44F5GD2TNbQvIAsECIqC/Z9Tg23zCqEMRmA priv=MEcCAQAwBQYDK2VxBDsEOToaBIGMDQwYDvCHyYh0wFprTawQrnE6t8G70sbkPuYj6iJWrjVpnpVpU89EU6oFP4G5DvsYZxxY4w== msg=d4ruc7g9Su6MjbkqHtOQt2e/HVYgZp0LgbGexCXEvCBwv6tau2BAk0TVp18/EjnmvdUVt9fhoOheb4y4rZMpkQ== sig=X9tpe2YiQ0/YTNsmMu35/lazW2b5npG6M4z+6l8vuDKwtr8ZzWls7Nzo6mZRVOtm50yglmXtz4eAoX0RPLMp0UktDl9x5IHeS8Zxl60gU3hLdTsQ7xL+H147FgJEEeyytXtBtMT23ff+kP/aQWNVVx4A e=found last=25 s=30 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA3dLFkOqT0tUiVTEQwLfLhTNBcPxdALoMtpIFLMIP6VJCG7dahI8bSwnJl+cgQqHlwffbLRUf4AiA priv=MEcCAQAwBQYDK2VxBDsEObOVAJNXVpvwYD+WfqrGhGpWTzRKojHyxEEkIQ2SdRfGzCns9O7qdHfCbFLgMHPa26He0X1Y+GEwdA== msg=3ufCFyLjQAzkqY1QJjZG5uwLQ+gR2m3Vlr6nO1kbdB1UIRYgjNCtECW8p0DzhVbAV81ewetULGupCgLumGG45Q== sig=aClDo5S+Nijjjt/Ik4MCtp4RQt6y1fAwE1TKgH66iA2J19tpK4e26DowcYlXfoRSWhjN1JF1o+QAMs+8yr6pqxY/xEl26emmaoV63knpGr706q9u9hBjVUs2WGN/iZ4AUmY94MGpU/3P2kIPxmYpRRkA e=found last=16 s=27 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAyHghR2FCLqhw/StrpAdu+JRCzkdu4xaGwQfVd5o5pPhe+VpCHVkNwgu4LLr8QZJzYeN6FfdMK0QA priv=MEcCAQAwBQYDK2VxBDsEOcZewyNbD2XQ2keLfAFSHdEG7SLr+wwsay/862HqvZruBcYwlMRd0cgeuVnKHo9i3+LAYlYsWep90Q== msg=W0aPE0sRJ13Qdhr2M+rjcrTki9b/Ii7/3L426++yCbN8qZ+m3jxg+5TVFBvDU1BhWFdO4yAPRju5UeBxYzAM7Q== sig=Pt4d0I0EDEX8ebMU9mYZZ+70x6g371C6dKgMyejunFwLCfvjzAQfAeqIluBSURP5Zl9pEROlO9mAqiXn+6tz5yh25priXAPw4xZ2Ochwzz2Ad47gGhxBJdALn8WjnPr4UtydCd/jngfV5Lza7bVWzhAA e=found last=25 s=28 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoARnX050PD9ITihOlZ4Xs9lmalpywWP8P27d0D0oSAlBAzvT1WaVEWNR6r+rXONiFz9mn8GBVHqJSA priv=MEcCAQAwBQYDK2VxBDsEOZeEH/n+hLk1wFLW6rpZtV01ht/D3fXY0bwVE52qGr/eausgaEVcOJhzQAU9QRCCN5uhRLc8ryE63g== msg=/tolfURlYe4inVoE5j1mEbJ810OEuMMpP3aiMNVKFi9dnu0BovWWthavKDxgpKvtrBC3xZm0b/hwY9DC8QJbYA== sig=CJYOm+8iNaO6XEQM6KK9OReyMAVaPTD9m71V4cfdQ1WCcsj8Y/tep41a+jRlFMyDsQQx+IMSwlgAMkqOuL/fR2jneWBqSsWneMNTJ4LBdQEP2POewUpWT54+XTZJhhtmbTk2aX3F5m0LN1ocnLZ6qRcA e=found last=20 s=26 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAT9nz4tSvIcn0t7M6vnUajhnDgJvEP+rOHJMnSRyAkSrjLcLVbhr6aw44TvzwRlpM9K2vwdGiOhqA priv=MEcCAQAwBQYDK2VxBDsEOWKQK9cMJazCSAbntq6PYwQTvD64bDNx5b9PXl8Uvf7ZAz2pCRRkvJ2KDRmZfZDD5FcibhhKHU+RVQ== msg=BM6GtC2yM54ItsURLZSU9g6BhkRMXr6GQlCrdMz0VNoHt5QYYyVV52l3Oylpb1g3zoZJI5Ql9jcj3UMhaYU2hg== sig=CQptH3cics4zTz3c1fvr5wJrZ7la3TsLt+rTJwSCh4GF8xh94CTG2r8ODj5ID2VxXrbBRrvEHVuAUmUeUxuzdMb5JGTf8quesjMEczx2sOc8Egn5CQnQO3vJvPFsKB0IyGhEnVlELK5vW6HDIBnW8zwA e=found last=19 s=24 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAveS86TXGAkcgzM8ifon0Eky3WQ5r+CTtN8xe1X6iOUHjc29vD1Kuw3OUafb+YtD3xzGqCrt77eUA priv=MEcCAQAwBQYDK2VxBDsEOeBy6v8vhacvbiiTKTYk5hsI2ZssWY/h3mP1AsWQpFrvgQuzEhubGd43tf0+dhDz4oG2v+B4mRNJNA== msg=U9UiOtpFAmwBrLURlBicqMCBRZB72Nke6612w5Z+WlcNay8PYED/24OotyEFUHriKp9aGXKPiUBndk2cECVgMw== sig=X+6bCgwAeYfmNb/H1ySvMEF/P/HRpT7gr2mU1QApWlf1vPhHBsc40weekkktkVOqrrz3655Yi/MAZnNV+HOdooDe3vz7B8exLiBKLSJJ13ttgwPrkdz5eCNshWoU8IXBj5lioVyoel2kndyaLLcFBw0A e=found last=26 s=25 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAHlX2CR+lvUk1oeICtq+tXelKazTfsMmfYDUtUwSXqWnqWvpSvxric933W1mTWmOTTi2rB4t1sYYA priv=MEcCAQAwBQYDK2VxBDsEOd/Pv3csU47EiO1FPKjpRXqFz2k40tfSzBtuPCvlvr12HmeRZmZYQCn+So3336Mks7ywsbfUrHt29Q== msg=3CcO1K1JdIZvZSAG9R1q9qTYQ8Md/nwSMIVaPq5ytzJlA6DW1v4TFcz0wngcj5bZGgpF74HUQFZkShmlaUU/AQ== sig=AS80Aiil7HWWp6aeLYCOLD8wHu3hFFo8QNRIBNtfbO5JCHe4Dzat2KtkqTUzZFM4UKqNkusHMRYAs0LaZBy0TYF1EDguCPOXmg7QK9XOXXM8OFpZ5U+4fjOjaEVwvNhwZhI72RGPqphT3sHYuhFxKh4A e=found last=17 s=29 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA3KouKLeSILHaB1YlS0+r9cxInvQFR5m9Ve03lxCHrDbSGP6+nGhA8hbwgDEu+9uvVgz0ltldxuYA priv=MEcCAQAwBQYDK2VxBDsEOSEutdd7bQzZLmklPTKolSUxoFV+5T80jyL5wrMXON17EP5WDSYp1qqls0djxS6PbfvsbmQ3fo/93g== msg=5YcYkon+et3TGBL8hdhj6OGZpcmNi1l/RiKmzfQk1/xJcemjTyOEJaRk/pBPtwEQj6m7FJSkT0XLNQDxLbfTWg== sig=CLwDjZMZUy3dHUDTO5NR+a6MuM54RhUY96AswiqbMdyaCsoHy/JTlmcSNJHiyGpzakc+2WjsviyAvQ3TgDjNoKxQadweTXtr3NN1xUYBoU/lsp1UgyMk1ahNrkYbHD7nCR3TjrW+n2Lk5o+LhX/0oQAA e=found last=23 s=25 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAolAvq2VtZG+1nfSxwYdFzQ5ay/y+kP8XgXlnFiC6qrPiSt5G+BPwGliPL+SSeXMatMI9/r3BqjMA priv=MEcCAQAwBQYDK2VxBDsEOXEGofRO7mdtEtRkJcBOdAx7/DrFdRnCbLIsAx9IDxpJ01XsW6Xmidgouh4BnU/Oaud11gO+le8H9A== msg=F8IZ/zjzMRDKUh9l8WYfHV+pKC44oL5Irv6gHvWeJg/OxoIdFjHus0LXQfaH7EFn4fN+kxtX73TcO2PT0aLZOA== sig=2DQrKWtfvldbRiaN7sHKpOd8gr2DcHHjc+Q3PlMKmXs6Z3TbuExOH7LGGqZXezygOR9wJH+l5FaAAHSOWivFJ2TfJXjCCZ7XQVo/FtUFnEdKt7s7EiFjNMoSOFKNTnFVPq8yzTxMiII/pfUBc4K7LC8A e=found last=20 s=26 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAce92lmRsjJDEW2vQ6ZxebWk/qgfeDka/v3hGkW/yNXtFH74zx14UOsSR3jSaD08hr4JWxJLEZI0A priv=MEcCAQAwBQYDK2VxBDsEOdCcpU3JXU/LTVLSD7L1h7za/4RG4vQdSpgjt5JlRwok4vuwhNOlG1GZXpftoWMMPlxesnVQ3SE+EQ== msg=tE0es7doJgOoZJpwGXiTe+dJgXqkO0u53VSSTbRN2G/gnFU/sAbVboe9sB3QgVLZDmgHipEibtK4pPT6L7E4hQ== sig=Nx1nhwW/6yHCIKg5t/5Y4dEtmFmTcrd+XZJqq4HoBgcJOg+2n1vJq5cSrAH0piGHW1ezGX0iMhSAa0VHNMMt8wGPctFOo+5jCNmAJ4GXvom31Od5lNNdIWpdUUSMBgAsphkmiBppG5mxTD3ZOzpPixEA e=found last=21 s=28 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA8Nu9Fv0HvD0SgaKIYB8W5kuLzFIH8HWHH3uBLRMQlbIuwB8LdpfJpCpOYXsQSjlLkPOTnC/T388A priv=MEcCAQAwBQYDK2VxBDsEOX/b+vPS5/f5+BP+B0X8T1GAreRon3YD1sPXH5SZBf2QNyRiJOcUDfa4C40+X8BwTGBthavyacVqpg== msg=MWwisy9jD9obMmX28V027KGOfUSUwOa0bvv8j/7CZdDL+RSBndyQFgq7zSVcGSM3YoRDfsxAkUA0owub4VJfXQ== sig=GrJJmRaYD2xkGDFQ8WR5YzgJ0ZlbqvFXAyi5STviUR1OD+4yeMrmSJwWosc7AopkM8Rs86xjHGwAT5NOonQk8xFK4/mi4LFiu+74+X7mk61+EkAwNf8iL1q72n1deoVJSjYZN+WF/qlFAQBLYNjUvTAA e=found last=18 s=26 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAA+HWEB68xQSYwYJbaNXICD3omYMfrLvdwktCPwVy71+usagR0Kl0h/LpLx99B8yrfDJ2Fkh07zsA priv=MEcCAQAwBQYDK2VxBDsEOTSHOyq/BHEPkZy1ei478whPSYl3RMg0mymYanSLPVNyjo9hDFalWGM8mYi8Snh+Kgq9HD5byD9ENQ== msg=xyvRkhy6ODCOlzh/67tkc5LNJVJdvV3VmpL/PpQehDhJPdwXRg/arYu2zBUVpZ3IonFmcSc1+RNACGEofgtJ7A== sig=u/k/jpTz6LSH7D4GbYPESculatBvGQO4Uno4e74PZjcEp4WyvexG77xtXnqk2fAsg4SzdpCQLHsAtZdB4wvKQSYgE+efpM+5vJUwECN4aIofR0Q/BA3595j/z8NTb26BZX73TGjoVPoivp+trUaNsA8A e=found last=15 s=27 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAgU9K0ISvj7AMag2JqPHxmfyfW3IXZFwQJxvHIphxRXBC7TwVlc/nxTIr070B3vML5N99y04feocA priv=MEcCAQAwBQYDK2VxBDsEOR+QUu7ISL6V6wzI8ZkDVKOYCtfTwKC+1MgwkQi5N55EVSvon1KJY68lx5ND6X2Y7dI5WdL4BgKxxw== msg=EFKwMv2iqTzu173Zpu/9Zz7PqZpBSSyYUO43Mk9WoRM9ZWy6UPEJWJIKVRYcQMbgMMUQB+YACA+Ivw/wHwkPaw== sig=Sl8g/WFZJJ3nqBA1ZfODjO7heEwHyJLRgcp8zfu6IX9/MmnuGz380YSZeIrQSUWBEVekib0I3uyAJpnzLOW6BMLJ9vy0CyDoR0LUtJHvYeYdCiZV0Qbzy9nKaVBMComWj2barVclz7SH2XSrLFECRSMA e=found last=24 s=26 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAwcziY0Yd5nJCFngBSjqkD+nQvWO4F+XANhpQpW1W9DQxbQkBh2J93I4dNwf0wGNzUfPIla5YUPEA priv=MEcCAQAwBQYDK2VxBDsEOVzaK9lNWmuk50T7Ry5FawJmDUzJ0eu7upiGBmcVAn548tq48/V3Dfl5ZWMSJuyA23kPkzrJsf/u8Q== msg=7+WO25N+cDQD4J8kxSFR47OC5jAkej65i/7U6XlbkUNXhy4w0PefyjeWUZYnLV4uEGVNRXb4NhNWhM1wj7CvZQ== sig=9hnDYp99WBPUyVeIx5DUKadRwQfFYUl5GM54FTkBI8g9zsVThZ0cV1P/Rl+baXPELlECKQmIPG4A1emeYiG+fhj5hVHMkKAmcHKoJIMq9S6yrSpg8m9la/B+qqeD46JmfCuPbWxco3UXkTV9xJPAWT4A e=found 125 iterations", + "pub=MEMwBQYDK2VxAzoA+ITVf0xusPE9AIvZUtWfknYiA+YH1x8jZjZBTE6Tm0KOrFqmm07T6JIDzumGm/gvR6B8SvQcgXUA priv=MEcCAQAwBQYDK2VxBDsEOdFOPdrCR3KdCsCWYm8fjdSohNTMxeym9KqENrsQ2TxdyzNxsakS7CdNIvuhVtH9n5molr72WGYBkQ== msg=hJQ2gzpa1+DlkX6DannPlGuryVw0wX+nQudDE8lNHTu93159BXfNrB9BihY1g0YRo5qbC9aMTnT8vH1f6luLgQ== sig=aGZAJrV/zQacjX2L7J/+HaMWAYip7BZilHmAai4dpHw/2FqSgr/d6H8panJfdJ8FE6dgQ+aALviArx7jcA3V2gvtzw9Or8Fej0pQ97bRdUahIsIf+YmvgWH8QsWNvex4ceiP7fUq3Fu0BEG+kfAjoysA e=found last=18 s=28 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAXiTaWLGX8q5dOil27Y/cPDRIEDJ1bde6Q5Tn1kj2xj+vx1du2ogSn6dAxuIPCzEcgdDggoVMoUsA priv=MEcCAQAwBQYDK2VxBDsEOURZte5ndyMm7I3ri87MF5zf1i+5r64gesuGc4h92++OyxCC6salc5uglKlFy9IXwhpaMtDIoUpTVQ== msg=E2StlKuzbQANv8itFrN6xJCwJcDClzN5WyrY3y6dFo++UthwtDzBXhCHTxGWJGJJh8KBhhwSLz4p8DZ8kpSdEw== sig=W9blKQmlv27kWBjF0QZfjoTWZSGwyGnRPMsFWS1a7z0AQt/Ui/QvVkbu9NQiLSKZHAC2/SwdCB6ARWvu2M5WatZCFMl6fEuOcNORa4IDYRYpBvw/ev9vRHL1H9UJXFLLp/gTAZU1AcUJc04D7AeyCQkA e=found last=18 s=31 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAw73SZvyesCUj2ok1fzCSM7xh5f26Z8ioLrVsYyclWPtGOIUeoVi4yQWIZF5Zb/YLsoMfdQ3uZxAA priv=MEcCAQAwBQYDK2VxBDsEOUn+AxQeG8SVdcBhbUsIRNW5TkmEv7qj+glYGsLpUJDv1TN7PVb6DHDAIY9UHfm2FRTZR0fBQby0PA== msg=ZjfLZ/y9zgkVZzUJuXacZOJ6Uam8fBcYTin6c/MZYRe61B3esnuCOeqFhqASXVcj+tpss1aItWNUMPphR69VXw== sig=g/YtUHIxFEdVGHjW81A++bosuSn81C2j7gT0cuijF43zKPTx83fEtIMcmwIQSnn28yq63EA2/6wAtomQ3RIxc8RalRcUc9YPs/YpWjkEFLYch8NIV2f1Tv9peFn/66CtI739ezaJwFU2+A1PO21oIhsA e=found last=26 s=25 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAW9/+COxyHwfDhTMB84ErbFhXCg9UvxIJOEZjdnjmIcFjG7io/UkVJq62Rw0dzoTXFcm7x7v2IuGA priv=MEcCAQAwBQYDK2VxBDsEOcvnJWdkyxg0mGfJXj6XvMpBO6TR20pNMa8BPOPIUF2sOi8g0NccSP4YOT8y66PBvkR6PJhGnnpYpQ== msg=HzjvizYTacPS6e8m9LYTRFx2+oFRrviJXkL/c6f8qW/Z3/woxjCznQjPLEeArcdtYeWJYsI9YZTws+YXLvHJNw== sig=TV821DM+68jU83qg+BAdZv/fZ2erfT2d5oEDdO2uMXV7jL3c1oW6lkCgz5+9Jn/tt953yL/xwseAGi4yuypSphzvdx3PVuwKRPhlY6qpMTIr/SzWvFZTAtoEdpY3tIeQOltUxz/I7GydXAt+ANsRlToA e=found last=24 s=29 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAgx2JDycpW5nTKfgUVoFUqocqewbW3rycBiHpnsFd6J8cFqOc5ks/36AQKf1NGqIourg8N2eW3FoA priv=MEcCAQAwBQYDK2VxBDsEOaXwdvbU6ticdLim2Q0FEYadH1AfNOlCB06PWtg8Nnlkicm1B/M1C5GrBbADlTchOEcDm29U/W1/Mg== msg=hA8SjM6LQCbpsViwgdC37Gbyqr4sq+Hx+w/427XCSqabJbOypG8GcjDBidqZUjqH0fJsf3JUHvoNwrlTNVmnXw== sig=lfrkmsekdYfxm6CLukuNOeMUNcUIwOWmR9O9o3LPidTDYaCAwPmWLHXSOdCIKz7FHbZDdSo0S40A5iiEiO8TcJrYPHYHRHave4bB0wrv7S/oDT0pee2l70a0lz6t0lS4u2JHoIjjwDhWMgqVN1PAfSsA e=found last=25 s=27 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoADuQWRgI+niy/IDKriSH9aXL1BhMi2iuTexLzePyU2KUdJerZS9wxKscNULRtoJNHRzVrmDPtcTQA priv=MEcCAQAwBQYDK2VxBDsEOYlu07dn3Ur/eAbqZlDBUee71Y+9f8UhF2BQLwD5+kojGeW5BaPU7/jyKBIQYqPLUAWBVfOnLUw+4Q== msg=0h6zWC4DILQL1mQ9tl/xD9W9NinDViY8SQp81HW37ZgKpCD5ifB9S1a2weFONi1P6tIVIKtiDMojKBKU11ETSg== sig=U5i5GMxNyx5B18a07ydLA3adRe3g4dyLCN3MlzltCI2IOqnZ1EkRaou/wzBa4dQTSe8W9MPK4l6ARO/Uw35i4XRFtboRvzSmnPqwLEz5nhAoJoY0cbuifXU2KMQhD4jJmBZ5MAhNSLkXXR49mSZvAyYA e=found last=19 s=27 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAI4U2li3YTgqavHDdbjNFjLBGsTI0gDwGgkSnt9jGBViDzeZEwA7LUgP33z+8teGrxS9BikAlx8yA priv=MEcCAQAwBQYDK2VxBDsEOaa0Rj2B4tU6NnDyueiaoTRCCltewTI1nsvpWAFg6iub/q4ioA/T8sxAWcbEvntaAHiZKRm6fkMkNA== msg=wxrmdtdjzf0S+VplySnkOm+lV4Dia9iIm3KKEMBMGuaaGYlf6FCRfT9F0UcUpPzfEt636ziv/hKiWB6jUu6dAQ== sig=My5Dk1LEhAjpsltmfTqH49ZscqUOK7VtX6bjYW6EkDMvRQOXMf7N0t5olJ8BDZTvXstvVPX55d0A97OdvMGZ/v5QvfscNRsPZnFkaR4r/OZfDLRl7acEvGHwsOl5A38nODyOLF7ycEnI5Wg1qT5pmSUA e=found last=17 s=28 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAcOSehC71Pja49oZFTXrqWz9IJiX4QLdMqHgafU7sVA4pRE7JwjEvZS7bYsw8K2Kiqzs9LmGs9xWA priv=MEcCAQAwBQYDK2VxBDsEOacWJcx+rloLZz1h30YFqgSDiPWrooMIEXND6YdKsSON/qxCpaUPxupkGuXTjV8skgNqoxX6rg9SOw== msg=L7/7L9C02eEYs4UyoB/0iICr/dpau9a6AHc/axhpXnImKg9pVhl9iuLVlztvkVtIxgRJcl3tLhttF+rrwX2zeQ== sig=nH/IvtocwcMsgANQnHpAwgIBfNg4qN9Yhe4R0iPmsz3PiQ72/TTjZY8W11TLQVGKgsJUQULMuryAsIdjt9sG35am3Z8t5Shi/kck7qk1RwW8Ak/8Bqj+MH/5+dFw0t3zorA3UZT6iY6IBVkZldivizwA e=found last=27 s=26 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAt6r0s+NWX+clMtQdT8d139KdJ3ZafNnzmzweJL8+u/AlWyFttXLjULWFQD6/KlzUIXYDpN54YDAA priv=MEcCAQAwBQYDK2VxBDsEOTWXU3mugLPD48W5SS1H4U+xuTWMa2/xSQHeqL/rDD1HtU4ua7x6tJGpw0m2P0/TeOZuOdOMR8yUaw== msg=LujKpTXuTq5MYT3oAubjPqtas5NOn2tDc2mmXGMhPWNi4tURRVPxM8p/1zU5+Xe4p6g4r13rbwlyXj75CFskQw== sig=bpibIXEBic/HhhJEokISojOm+QoQlX7CNx2aW+UuJlLMPPTjsdf6qPNaTfIk6Rlb6U6vtWrekmGAZl4+Sozfmsx7TgXooN1fUGeqCS+5sx83qdx2eOgCIZ3slDluVRojDpWjLIyuSA1qeUGkiS+6LjIA e=found last=21 s=26 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAUE0UxWxZm3PXmgudRCTHeUQubloT0jr+2H9Fc3blBL3yqz1c7r1Lw1pmUrCB8pnfK+X9Pdq9g7kA priv=MEcCAQAwBQYDK2VxBDsEOUoE+peRqtzrhGhsJedHfWgxmA3scZ9uipat4pbZiO7IRuWhabm/d4s2jtpnvKiXj6xM/E51sJwsYQ== msg=Do7HCqeLQh5ImXD2U7umOhqhKVL4bG4YZ6xYurIbSkUhd/PDidBpO5hckVD/vaL7+tXxtbRBv8R8dAUaLBUZKw== sig=7252Z44Psr1dw91xZhkn+EHovkC1Rfq0Izoq1JI70r9F1b1VDB26n+H85zybWmEEYtDCKvT94uyAuHi4UOQpXNsnwWAYxw55n6dnnEBsvSXvzbUm+8X0tc+I+lBfH4mmX9ygFVkcxZFPVD8h6a/xCBsA e=found 212 iterations", + "pub=MEMwBQYDK2VxAzoAonuP23Lm66n1XndEQ1InPrP/aev/R/fiBF2jI7AGr48PPHEev2TqZez8/Bpqda5i1awbTRwa1G8A priv=MEcCAQAwBQYDK2VxBDsEOUbR4lewhbLYkLH7ZNodyPvFopCJ117mb+ZpprPKKguITXYpGT3FkUufJFfZrYEdKo45MNihrNrgKw== msg=h2n7ZYKQcg9yk8N0o6oudqNkUvWkg/nnrASShftDn2oA6MyCW39ZMagk8ePpwIbCOtcqhYipnyRaZ2d+JXbQTg== sig=8S5BVOC7SI4Bkq7XA2LC7Ywi/2rf9Lu2Q5yj1H5goc7S7ATjG1vz9/EnSOPCJ6CSCT6xdKVcQOqA8jzNz+HmS20pn3ccuVnAMBkbWg4tfvmBnwbAIzVliDRcS/aOzIHog3L3xDGPwme3i4sRndEbtQAA e=found last=24 s=27 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAuYLHMlWHSJKpBCLWnKIihILacKadOvXtt/GJWU9sMNt1qPiguQO4z9OLb46hiMyzi9C+xLuNleiA priv=MEcCAQAwBQYDK2VxBDsEOWBqYzcCxJr3RmZ0O0vmsl57RbsIbKixGMOZq/kAoK0VDD6gbZL63GvcYmRmG6unaxUuUv668/OMlg== msg=jZQImbdAZYf6HkRsfC38ObURGZQiHXIsMAFgTzPn1FzTicmvSzpCG+4rdvpqWtq17m6v0wIbrIFeiVposivQ9Q== sig=0Ml2x1Q695t1xUCfY0Cm5x3WOft+cnY7wmesk6H9nyKZNf/qTENu/TrcTp7NI3i8/d/B98h3XWAAGtNBl7GbRMAon2+Kw/6tCR5daSHnvLGl1p04BnLGzvRIhnTHoYcp0QWeUhhw994iJp9mD3WmTTAA e=found last=19 s=34 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAYIWEQ40XaM6tBvgLBlczEwkmNcneYVnSTNFm6KG4L9ZdYycKvDI4Ulypyrf15barl2IQYGdEDzIA priv=MEcCAQAwBQYDK2VxBDsEOURN53h5YFM3vfz9Nc6+YmEpxS/IhsQuccWHgjuujMaEQk9zfYB9gsjtTZSBDoGLcaE7CBBjE9oGiA== msg=HGMj2y/t/4T2SdsysAVuT7f622Qaf+xW2aOFQvMdbN9r8LtHbahtTTFvOyhNXW7cjNyVvL8TVEyxmjHWngUiyA== sig=nFekEkcODWUoUYWzUWTRZYQ0XCvJ9qwjLrCRpScvi8kCtyQJGQl6lRGZasGyjGcqiB0cQeCJ2TyAcW01QqFSsGfFofp4dc8S2102hVypK5afc1HnC9+jNz1zS0Xya06uZMH+wx/SgUaotEecvICtDQcA e=found last=19 s=32 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAI9dXoi4FikuceMPexhngWJgeFHs/t1R/82R4iYyCn3VFeDn8dgPDI/cw8QgV+ZS45XWNCNgmdOeA priv=MEcCAQAwBQYDK2VxBDsEOYyEu6fvQqthjTjUICrIIRm6KUXtTnbZ9p+XkFBk7dbFWMXn7OG2uu1PVHSOiz0u1kw9nReLOadniw== msg=4ZvRt0uvVi/O1K0Wqhbdbc9VMve4WDkgFbNbsYB9XDw1Eau8PY8jxjyos9O7ZVEFa3s3NVQLkwcaxLIc8tEfAw== sig=4LgCsgn0xbvLbv3rvMcvzSXpYYsiAQlc3Sq2pw5TXo3ukJBT4uPxhxguvKIbFDuQRh9Y6b4oxbUANq3iziWoGFIVwEvg3o1HxEzehT1ukuXQEn83JYsrBcz3uKq5QqRUyB1dh53OT/6A3zrIKksOoxcA e=found last=21 s=29 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoASjHqamv7VTAQbth6ZjQnLP2pnolTW+mojImdDtzLv4VDh+88AdmF12m1T4Mi6sQQI9BhnILAd7wA priv=MEcCAQAwBQYDK2VxBDsEOewL0HPNIkdwMYIWKMY7RPy2KraEWb7F0PNz1Fxa5E5KtTMtGU1v8lN3vtIM9nncA7x75qSPJU6YgA== msg=W+n3NlA2QCFzbAGjaZcwa9e0TK3RT5jmsKJ+T3o2b+eFlOy6VhQmNfdZYRn8y6do+wszFza8h8yCQzzcwebhDw== sig=MJHMdfIOZVqwmVhhqJE32Az2PgzbygEfpznyvXpMxw2C7obo4Fy+X0R0EWU533/O85a86kTor9sAb7Hw4PoKhI3eAZ6Kc4OhqUfmKmwD0XpzUPcBQ0sgArkFAEpz5PxYPHzjAdvuot55gAAwkCJzESgA e=found last=21 s=26 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoABzQXEKTFrEh2TC2KJrJ6RrEURMaFnx7fA0CZyjdjpEMB7xVb//O1pQwgdRQ6jcgmystqk5FymPYA priv=MEcCAQAwBQYDK2VxBDsEOTPT7qeB8FkWYt+mONMic76W1pmy0X7icicEpe1BsN1slqD2F1Qbuoqx9CoSUR0np27kfDizhFq5hA== msg=TMHYD8SliZEuWyJSsc2IdFzBmyak35eahZkcaso6VAPmhRpaP2Al64LOpLbN3AFjL+zCnsOfSXyaVfkOYcZlUw== sig=R9yRuisG4gCX3MEgRWCEAWx36mZRr+qgSYvjsqazJvtOx+NWaokiz5QGa6sBfsCBJwDU67uQL2EALxpcGANWd/8wp1hk01/7CRI/KOpNRE5R/3OlQewhOukt2PSPYxQw5o7iQdB+X/X014me5W0/KQ0A e=found last=24 s=30 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA942guNEhfqEzd1oLkuOu8m9NcTkfr0pKw48me81PSSsxOzYjjmwr6Ebq+xZpJ0pX8GNje4RwPciA priv=MEcCAQAwBQYDK2VxBDsEOVoHQXz8kzRxO1kTcTKijAOYj+YptXkCwVtEJ8noh0EWvTLBg+u3Ue4jwtBU2Yn+37PC/iYOmWIiIA== msg=p+5zwluN7V9/ESMaxWIpz21qazjafUl6hjnjhyG57qbeJCCStx4LXk1WWQr8WtcPP7EhSB/X3UfmRvJxe/66Vg== sig=pTbkcw89mFNUtS60nhm2NcNftyM/X99TILw5hByTNB70eEdNSCPVm8e+rosRb2buAEMA9kJ/NmqA4VDKt84UkwElzwzFqYESruv/ztNMr3zJadbZCyTFgvDre1wXHoZtRyOeH8EPYo0JC6jA2HowqxkA e=found last=16 s=28 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAPOyt3oV6aOz9jRLJxJvka9W8S93Z42YSy7nY9uhbWzpVtVP0zTc9UyRhPf+sZQGhcqG9N4z+WL2A priv=MEcCAQAwBQYDK2VxBDsEOft07/DLp93TB3q9WtZFxhVnB83fL5+q5qZqlnWDEQ4Sd6Lzuh0RyLrzbUb+VxHZeJntw20WXJ8w9A== msg=V4peADkcMqSfqAq83aN2dp0rac68zMWZwOYUjrGIOzxWJqzzG/OIbvydRTuYN2m/j5CwvBkH1YXVSoTnAeWdDA== sig=jJmFwTKHRrC1FSzIUeKv7HtI/CdZx+oj9r+1apOAhO2GUfVvaOoBuJPrnUlesqkrw3lkysRJMrCAp6AlWFHz0nYbTOkeaEGdRxRCZ+QswefiMoZNiV/cJLBHtSsd9oqZFjOxX44NJcvJ/WfeJBhsviQA e=found last=22 s=26 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAmpZY3bybwclotMnzS2gG5edD9hbwC+2Mb8rvogfXUFgLlO9SdroxnZPj+kuWMwzBu9wQ7EpRtV+A priv=MEcCAQAwBQYDK2VxBDsEOTQ3ouyR1DTEkOlg8N9pNFxh0gUeFM0dT9zSyFbuvEMSerP00VRet2p2k3rsh1Gu1sMC/SQoX2fugA== msg=pGMCwUqVaCIh6YJ0B7e1jZXyoXXAA9ymrWeTXXcceIAp/89uJZSZiF23WbqF2VCIISgFiZXnGJG5Qp8foZugPw== sig=i2ZhdtGT5Kdk7pkscQwXiZvenbaW+18jqChGWv/8s09IcU8rugf/gx5FcmOzhG1foGz77dCp0YSAehEl5gdmK5cTTIFRKCSv/s3IqWYaGqTyscAWwn1eXwDXYV/HxEeQg7Vv8iBsCEwxGMSpeeqIKC0A e=found last=23 s=27 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA9I9GUmAlZ15IGCBE0uy8e6D2pHwrOnknpvaUtmHZ/fGlu+Zw++HCi53N+TGNCEPb8R59P/lj1vIA priv=MEcCAQAwBQYDK2VxBDsEOQV0t+X9hmztpWn/ZUT55ct4Rq6f6U8EIRx8p4QRch6aOqZCRoB1wjK9QkmJCvV7SF5li1O1HAqm2A== msg=Wx/Q5xTdqvheFJXzHj/VudMWq5RD6hG1Qi6SP0rqbJyUnZyAw+Y5SjzKOIXDPDvtgL66rtumH0JICXZyIwJI0A== sig=7OusNpTKNq0nUlqmcufV7X0m7EnNC6m1uiM5tCIH9LAYEbFv1n0bgXLZDqbDXVSqUvkyDQStnbIA/tpRd++f7t6laCmFB1iLDSWoxHfwgClTKOIZshjtfzaQAVwPPzL+nb4r89QXgJbylJEPKX6jYQsA e=found last=18 s=28 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAvSzEjbHckF9oAGKx2JMY68LGYZ7usF8AQnYFp1DPT885m8BlrBQ945MjCar5tE0k0f8sxOPeRzyA priv=MEcCAQAwBQYDK2VxBDsEOfNdMJnWq4Z7elBaxEyllRs1XRNCn8Y9Zj69sMr26PU9Gah98oie96/kFGdVt8Yziqfd9oo9fJwsjg== msg=dHQJTGxhSCv/rSqtfLF2BIsB9+urnhAcByxLxAAWISiTvZ8I80QX1IyE8PCR9lKfF+0cqsLhbPbgZtRgg0NppQ== sig=2UoiOuqExRZsGO3OfTZFUv+5iAAXy8rrY2hdUAD5qGIpbcLSLPqxvzozE6EDWVkm/3LVuawhBCEAP8GS/QYBB4xEBMCgNkLSZpWWsb4KvJyCeFqXOuWSkVOwVQvkiHgm5YYKQ9wXA8Ao2JGBGiOKDhcA e=found last=26 s=27 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAItDmyEJd0SXNL3GHtekHwdRiBRkBp79yI/FDTM/x2LUrkLAf7xQAsU0NXPHtee8b0e4mtGV29kiA priv=MEcCAQAwBQYDK2VxBDsEOV+DUJ6004Wey9mYolkWFDSAoIOBDW/QbdnHfAgq/Xpa2on+5X4BtIsDRZ/OFji/EinxU2S0lag/og== msg=WvdgH8c2u2bT+zlwkY52oRREG8UWdBL/5kNksG39UiZVHYStDUquyrOzGtay/gdzJeah0zxdvwyVOekCU7waww== sig=2m/HLI3mkIdrciJsGxAviVpCxpGf/spjRx/J9pd7Mto/Is7FFqYhlM8vxALc3mcbSpfGGZM/nIaABIb2vVyAUms4+nBozPvL5KNHcygUQvLnH9BuVeIYY6jLW8pbs1ZsK5/8Pvn2G67rvT+GADevoQYA e=found last=25 s=26 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAi4xLbRNntef3gTXu99Wjpskgb8rjqGINLQ2lfQ9R79zm3gp3oeJ6/8dNytaLS2AXY8nF8P+BvbyA priv=MEcCAQAwBQYDK2VxBDsEOSpxepGwzBujoOEzmrZU1SJhkH3P2nKiveq6sioq0VuRS+RILKByWZIjQJwKezqwofueKwHeBiyaDQ== msg=TQaGvbt1b4n9FyQgVZuKTRGsASfr5AUMhKwo2dulVBX+rFXZtX2zd5vzx8tZ9Cm6FpjcWFajkhaOFiGKywhSaw== sig=W5wZYLJGrZi4KCmvi6KJMCE2P+Waf15HTakNXHrRWOU9Br3qb5Ye3c00AhPCuFb0Eyc47dLw2x+AzIv5V6lsjdX9ZClZ80i8ARec1WzmRUETtD9PE6bRFiQVnhDF7JMgZCEhi6BvDJt3eTrtNoC4hxQA e=found last=24 s=28 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA6OX+wbU6VYzXA/f9oD4QmU8BTj/3ofY7SQO+nWNj8hB3tG51oVT3Xndh6kQh4s7woCxKJNGutI4A priv=MEcCAQAwBQYDK2VxBDsEOW2pBOa2f1KJ07rn8UXwVjJsWJ6EcOSQzV+XRk+sgAkFUFxoDij3Xv8qPic283DU0XbAAyghPtUldA== msg=xM878uzK/lFG7nGma/TgmIu6f2b5aJTehMZfClY/CeouIeR3CRgjIuVEENIVRtCjrsiLRmjI5KkvV/0tKbl1mw== sig=qiF/j3xXYQoJy++9LKQ91nz6F3xGuH01xDIy8L+eNQS/G9MZY7xGBMkkeLk5SvXOuE7+VckPLFEAUXJOsghgpe38yS8ZDpNfkiw85y5ecdyaD3CYBRCmDmUwXnLxDLEVlgroefNNVvp0jtSQd2LO9ygA e=found last=19 s=28 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAbq+uvUtP3KqwA96C2nyhtx23zk2dqHXV5BPDDiKDhIHySxrPyy3PXiKrcw/BVteVE5j7rac7+TAA priv=MEcCAQAwBQYDK2VxBDsEOfZiCsjBzhCQlVyjUp7cUGvqqVEa3W9Tkue3PqQ9f0dGZzs4wHXWY/CbgxnvLFVx0qFlarj7U+klzA== msg=myerLjJgEKf9BWizAYAy/xK1VGrcVxIRkCGZ2UbwPTXXKahNxpPjuzIVXxAlaz7pe1X45+///kLRoqUF9qBdwg== sig=Zen7oT1jCNHY7oO4mLa2qHbXUahq2bjp4z8/HpS/0wDc/T1K5TSs3dfysY4zmMHMJSs1xPSr1AAAEgYZNS0bUX22WjN46uxJq7wmHz57FIsvjRlwYB33BkDQXLnTUVt2TZdwKwVzgfqSlTEU7khNZCQA e=found last=26 s=28 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAuv7Axzj4qwCEzv/Tp11NWdp60NkapcGrhHlFkL3fHeGNu6D8+p0nia3nA1lHQQ+qQZmckw+SBDKA priv=MEcCAQAwBQYDK2VxBDsEOVz7jwwdiiPT+cP4NIQpZ0iGeAf7qip64J5KgjEcjpJi5jYc0XhEcNY+QHeE2fyquMedCsWHGrpF6g== msg=4f3nwSVJwBo/Zwfu5Y40VngRVEaImmNtUSXcFNMjlhQGrr6Yp58sxJgxkn0r4LNfZNc3dyHLxhGGx8b30tZ6kg== sig=YCDjpMPiuH0uGHKqWeUkTGsYmD/DrgWPRgwvrkeG3QTC/0w00zdty2L6DWNLtv6nwqe8apWMc7sAwZtbVbeOBeGI+BOHFDJv3cq2vmps8kp6n0kY5OrdsDZn2fCfWLipE1DOSE9QKLcXTmAxhZVhbh0A e=found last=25 s=33 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAtbYUHrg9xhJ0jCrcVqdetDG7Mn4/QQDTZwkDgoChSltnQ007zH7Cf1piF1Fzt5yMqlgzKIq+u4QA priv=MEcCAQAwBQYDK2VxBDsEOUje0lD01a5levwe/NshSWwZyCX6tsqhdq10C1+8IQNLhQiyxRKkSMPI6iI7r+rMIgtQRwhscctVJQ== msg=mH0edlDnjhRhG8u8kHtcJzxfJlq0PO6IWfXV8t/XWWZCC/d2+GfX3k8vA9UozNOXe1FQcE9MltnJ7JF88k+2SQ== sig=T8VlbpxhjS0nQVEFGSI7yiYzttaSwJhupaSSkWuY/dsbDT89icqo50/RmkYfbJnjt7BB0W+k6vuAZTioXt0PivEYk5vgdRbXg68R46/ZQD61HR4tliSiB4LihpAC6bHyz3w4CZ/W/Sx0KZz6fUGsPBMA e=found 126 iterations", + "pub=MEMwBQYDK2VxAzoAYdEQFyFKNjGVhnvbiEyqVNvc6XdMJ4rmTAdIZrHUq3rt0mfRJN2RmEJjL+3AstveMG4j68hZHOeA priv=MEcCAQAwBQYDK2VxBDsEOVIvAvux5ltpGRf1ILak3qTp3qm4g4DjLCjpqrdaU73NCYN6XxpT2ezze5PD7hTtCoSGwnE+f/Htdw== msg=tTTOCEeWcYRtGLkHRpOETIBAvwZdHrguX3iM9ChHtieV+PRNIZ3ncw2vilaLWdbBLrPMQ60MJx84sQuMAhX/+w== sig=20pXjoJ0X7sepfg1oEbBIDvYhqpwP5/qUiv8ti4I4NGQbSp43NgtEcvHQ1daotbTBGpvQvgyjGmASEnbZkB+ZBnUc6sAI1u/M5joTNwf+1ffd5+X+EKJnptn8XuVQYcMGim19Wd8YIvwbSISe95nMhUA e=found last=18 s=29 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAnXeAVgl2rvOokMHToAZfQOVl8C9dZJq8o8IwXRbC++1GKllbygNi8Dy7mLb5YbJDLsJGttFM5bYA priv=MEcCAQAwBQYDK2VxBDsEOdEI05ZLwDJbLmZKzmnilHdh+dTegSF7On4zu2ICjFQGh2L5dVGs6ecsqkPqg6rych4nH7Gdj1IDPA== msg=zqP9mfzYvnCYxG/TFBKbXsoNf3MuL3/TkD494iEKE6L+9cit59PqkMu4HwY5T3Hgydk0pympbo3Cs61i4Kdh5w== sig=VvZFyYtXmWIIJGhRMTpDsL/y2FUnuli7XTv7ZAtHRaVOb3mzRHxCUJU5D65CMEqHX+wzh3Cn8icAPOD4kEjMMLNrMUuz8v3JAfSpe975Bkt30VR9qSMNKK2yeLeLzjfxdByDJbIDgufUGlFv4e+H8h0A e=found last=19 s=26 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoACnonN2K1PZeiEvr2c8jvf1jlruycFZ7ba2DCtk+NU7pBpBkJkvMOF9Vw9GqvPYsjbxVGIgVY2lCA priv=MEcCAQAwBQYDK2VxBDsEObWwcP5cj3/WpdYkF6PWu7Z/QWlYIx29FnVylx/Ene51tiunj2Wj8wxSmws1EcyAwcAty0vPHypoCg== msg=//55tsea6sdPctg93JhzO4bm6iIioM1Ko4OfF+xnI+GB6Wvpxb17pSz9M45yWzuXM2FiqRZqSNSoDU1mLBKbaA== sig=NO+HY/6yYToqFzYeausbNmvQT9RHmlc8HVlanTgP1oTdBxdnVmikne9+eaAHYa2LiNhBB8zhw6UA33bqlpHJOYRIKACEKGokzgY1gX0xEc2BasrDSBFv3x1MLLUo9W7sJ1BnEjY2WRmWYwc8MNnkgwcA e=found last=18 s=30 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAsyaMpnpEiE73QSAVi1x6mij98MILQJYeAOJR0fS0ga99h1mf9iLMOyhZYo/H3XsdJFAl4F7/WLuA priv=MEcCAQAwBQYDK2VxBDsEOa8zCHlXFX+3yRZUagEoRECOjN9sPCERgRU/763eXzpc4F5vhBTvdTUNjEhPgywpQW6gqj4vn+QvEw== msg=1Nz7412QsYqFgvAN/4WvK+w6clMC/8IuYH/8sqc/gGswNuH+0zEY8f/5yEzHmuR7NLacL+bOm8WLZZ+I16DYSw== sig=ilcT7WjlEWPNuirbiRUjArpZQN9XW4P05tOMJs3gCFZrTgM8j5DRBMNDS1sZEsyYgUDlmD0BbD2AmEUwCQHbpnayaXEMYF8smMEKu7AeVe+Ndc+ff2qia2UOuihIE4YbBUcmvVGetHVPS+Hxv06dVwYA e=found last=24 s=29 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAEGd/DKERzReD3R2//QhfOyD7dsx7mPROgZsbU9htKJp8HbXW9jasNieJA5790LUjLbAE+xIHU8OA priv=MEcCAQAwBQYDK2VxBDsEOZxd3gOuCXPQhwbSPlHoE6HszFu1RPGfYLmss8D9lA3owtkWnWl9jP/cWhJcmLOLmDiNVPJyCIr+vA== msg=8Z4tseAG6kWyhZmVhrLOU26p8sQOkb5HtZfHusha3y2rpN9RQmOCajkrwIj8PtOoVeKurHCaJ+FlQwV/+sVhIg== sig=+VBC2iVedQBgOCueXCUB8QWV+olDsO8Cz83RJFXVLiolGhZN/YkY+dwfggpS82bcj1Z+tK+w+P2Aphit54a+9qnCj0w/zmbr1vMcWgOBWjVWP3vyZKBydvgTJzCHomIDxtpqqHjjmScYS5x/6bYCXjUA e=found last=19 s=26 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAsQYfE3wCqOGYeZRIuGWZPLnxfNZxZmBrI/ULzE7MBFKxNa9h+eiU21Ywsx88wu4JNF3wbOqIvYUA priv=MEcCAQAwBQYDK2VxBDsEOZjacAOAFoM5Nk22wQiA8hzM8ZcQW3Cd7vZWgSe/u3i8BXbETdtPkX4RPMcPPsosRkqC1WMP2Z8rUQ== msg=VgtvzMsEpKAlHxKCbA+NNaq4piBrc9urWb/95KjYNf+MMlFNPPzZ4qrRUZ809FVAo4CPRgfMu8tjU9BepaGFhg== sig=moyEiH8ojFRqB57hHO4+BtnShxUwKGnoF6nv1ezbI/ABjmnx2Dgo4rWegrvDlhRu5Bw4bv13/KGACKP/kobFUIV3aKO5mdaGyqc16nkCJLy7VUzRLdaD9k+EbPn/hgflRF9raWPyjZKFewzK+FHMHRcA e=found last=24 s=27 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAxqbPu7xzEdBFVeCraiAvmzjF+fCAQMUcrNdaEoM479NawVCCbf6t2DPTZBrcN2o7U+Tgv1Md/bQA priv=MEcCAQAwBQYDK2VxBDsEOYl9frFfNXXSzSTnKKHb/Y2jll3QIeX9bgC9Qlc6d9hpFKxzCm1dRyfXF76K7ZQvo29N9TGcbo5w3A== msg=toDaJFfjbZ7eQX0N5S2gLtKNQrwg7CQ1g4e5n1QSiV9zP2wITLKmcqakZI5xXST5OUav5Rwwgh1vBQtZz/IpFg== sig=OnYbPEIT/SssJDu1xAjd9qdnYZYYz55Uf3+eJvyCS6cnlNTqVbc4dBRmgZP8/Tf993XI6iS/C4wA6xFaqbzUYaUWKhb7+n2lQqxyT6Mfo6bCX2SEGlWiPkXZNE0Pksnrap1B1A6kXyg8afVySureEzAA e=found last=22 s=28 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAe64NqPsAI7CCgrDiGnyPJsRJmhIajC/96+sNqz0GCjrbHQe95FUk4rYiaAYaASs06ACojwP0YiOA priv=MEcCAQAwBQYDK2VxBDsEObbJr8ICGs997+IKovuOByUk7PXL1O7buoK7jL5KxT642sGTPGn+Ax/9jqnikA6eiQMG0XXagGNzWQ== msg=LTNNgz+cBtb8ZhYj5ZalZX7Q0z+sd/7YvdYEvvF1YMOw8pw13GTcIeZK8qum80HzJaOxCyc+v3chAUsUfitwew== sig=gY9wxwHRaPA4gadN5+BfhDEzwjbLAzvPjxHCU+OeVkMsOwqbogogGzuLIAfr1pqhlQiCKrzNmxMAeYl0+vcqpkGI4L81CQBwXNGYxH59ZZDkDl6qQ0N7YhLZ0nwj6yZD98iePUsbXUUPcJY0J/HuxgAA e=found last=16 s=26 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAkXpqqqtq23e+U28rjuOu//wsLklT9Onb45YXO4S8LI89Kdw1C813N6MkICosYf+IX1L4kLuMs3GA priv=MEcCAQAwBQYDK2VxBDsEOcxUEFdJ/tt1MwmOsPrfsTCWQcbDFXnloN8F0SY/isRivQyOaFcqOxkFEXMkcOIi0YS4IOV3qVUR1A== msg=FP05YjXswiLulY+10S/f5y4vHiQo1ffDUWYKoldJ/A4Tn3PSikvQxQ/7M93Z9oJK45oFkzNJnIUvuPMzTmncCQ== sig=tYb/VPnp/jtUY2ezG1BjmHKFK0vLwpqf3Kl7E/6Eej/AJh+jkkVGXzJKvml7Pi4kwBb7HvlCDOyApJu8lfCRsgmU8nCaRtnc1ujjAMj/o8k8eF/zy82MXSz5RTfFf9K+ODAMtJZwd3qGUXUhcnG0rxwA e=found last=20 s=28 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5AdRIfL+Zy83VQmNMHeN1xYiXfW5TzDgcYNpKG19/l3gbTUGhAfM9e+n79rpvlW1o1dKNFLjqBaA priv=MEcCAQAwBQYDK2VxBDsEOV0q4exTad9bfnMbUjBh5711/CPgNwvY/G9w0Uqq49vpxj5ZbibQL2+qhO/WyFyE/hCJIAzNPyL2Rw== msg=WAn2RXljnkOzsQ0yrZcHQU8iujzzJS9sC2VNWK7TMtF+9SsBSZSsHahbgpWQJ5jQTaEkXsStQNSGi4+ZC7iZvA== sig=Z2cJw7iha339wOKHtfRDIQQfvwYO1f1zpwbmLDb9qHNPB+bCWniegC6NGuIM2Qz26JJfQonjDsYATIqcK/YXfnJE26jL4L7gFq79cH1IiIlrlmnlNEfzLSJkJi7j7+CfbqsBQ+jv8pVMKdQzQWwADx0A e=found last=23 s=27 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA/8jW1FiimgQPY9Boa2d/yXwwQDZQAHLdkP9LHIHJYS8g14KgrFHxVR/IiHjqhWfG27vH06iRVQKA priv=MEcCAQAwBQYDK2VxBDsEOa4P+Fct6F3AkE3GgoFn27ryTJ4TaLxVvuYO4Zzx3O8pla0LoXP4DcX7yxdnjZKjy7+0fko1iMaq0w== msg=1ryicMYTGrYfc/4NMmN/XEpCVGYaMkREMNWckRDXqDie6MA0t7W+pcPpdOYANaahQOKwQFo15CtE+qVClU+YZw== sig=OxCFGWgePNPWulcVujm1q881dnmQr20ZHfEvtYYmo+99KJV1BtkitzKRFH58QhhlJcOJI7/HS9UAkZlHNIz7cReByLf+TZLpDvW8EvBWlEMZz8baenNml9LnKFmgZZmmzPucjE9ux1yUntwu49bolywA e=found last=26 s=30 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAUgxweh0EShntmrUsJGBIH7jmsHegrg0hGnsXoj6kTqwk/FZNiAhu/srwRrnWR6a9uzOA8oKVmbMA priv=MEcCAQAwBQYDK2VxBDsEOd4qxY8HxChS4QbtAXUpVv1T58M+PcSlkZOUl6WNy6JhI3FWTO+aaJQeUbZTI1r2SB4xKLSCK6HeNg== msg=DYn1rXAdcjEAReCQjnE2bu3GF1OP9FlObprHdLMt3x8w+G/Cds5b4jItCrVXW2fhdednAS1nEJ9Ybb9RqR5qQA== sig=Nhbt/jju8kiIo8VPA8YtQkyMdqAfeUZbDW9rZ7P78RMg2HB2QTvaPyJQN53EJfjfmJXIqhXCKJiApVqyGVolHbkm6D1iwqeFiyKdCZpYdp1hk6np5N83gk3P5bzcPNRv5eKgnvMYXWb/GAZQi5m3lxQA e=found last=20 s=29 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAvmdauLMocPrdOOr3XNwH1B0b6cfvsvB+pixN6dde1faF6hqw6FlYqwLOCwobhCxi8qYI8DzzpISA priv=MEcCAQAwBQYDK2VxBDsEOdGGqX/mEWvzkqZuJ7zDYUQ+eS5VN7uA4BOt1iNa3qrfGAp79M7EfyBR9K7cMrBc3eqMYDnXNkKSGQ== msg=32fY+zlagAACjbe/vz+7TDcJo27xofo+WnW6mT1UyzPoZHTAcM8dJOjAJk0G8JTgC56iBuUoNX8LhriDNjmEvw== sig=tHCYb7Keb6fegTZCTmvv4lOr2QFLfoamB5/jVMsoyzeketLSf6tF3UDJCeN22d6zi99BEis3hyEAkULPCp54+Zggs35uDYR9wqdeVmcipGh2pS7DC5CY94Dy2VucCCzcy2Vi0dPq1FB1vR8O/Rl9xwEA e=found last=27 s=28 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA6aieOpXnd+U4l5B15JOIsbpxm6L3yaL6DtpDRR0Hj/sAdbt9rr9vJD9IzYRZexrqOj6782iUmjIA priv=MEcCAQAwBQYDK2VxBDsEOSb/QLH5zQ++z2CFdyBpok43smnBnsuDyEtIzlROKPYsW6XNYtG5ropiDCC1iE2jvHy30P4EXTp2DA== msg=YbexUtT8vejIiO16nBUhxCsLmtmruU66WImPj5/FWFCfMjNI0Eqybe3vw+EB22VYV+qTmmWoA52T0NVafe9wiw== sig=TQm7jVhkV+c+STxliPAtlaxk0oc3M6Jgw+9vNMB+nDh0oM+H/D4CtRepgAd9On7noDe6NkscHJ0AE9zy3usBqNnUxkBmJ3QMFtRh8muvDuukHox0487oUgauGLZKDhiqXjR+x3cVkD8NSmVW/l/ROCwA e=found last=22 s=27 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAfl6lDhhJD/Ltoyyp88bzU9lEnvkqwjAnS+V3UfysNs0k4fQawavJ3RWAM9Ie4z1s18Wn1ur41bCA priv=MEcCAQAwBQYDK2VxBDsEOdDGaFMSrvVfEyVGRp58eUmQSz4s4bnhGV2EqMLrQlXhhBGJQNa26PhY+DgtercR2v4q2Y0e4AzVQQ== msg=8ezVLEjr0YqsuPAx0oPRrAIyk8FxJ182kDlE5nZSX94+ocCn4V6fS+d2wsskkqBMfK4KwGS+Fw9E5mwxx5k2Jg== sig=ocpWT1iwUCQs4IkvHmbedmr1fLizLM4M7xcBLfy1o60/CRBqPH3SnlcWBh9/14IRumFQy8Fd5o0ATPUY3oYVpF/SiWwfOEG3ArVUk0bEs0uDVtzSCYdiBvpm3/kbfY6xaMmKL50SlbSq5D0LZSqy1AoA e=found last=26 s=29 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA+aBIWlDMBfX/r6+eUWdgQp+nVYVVmWEMeJkuU8IWiEdCfxk+p0H8t0r58EVy02r0aSaiDs33+Q8A priv=MEcCAQAwBQYDK2VxBDsEOUHt8m246V+gXok6nLkxBNzlttgAz2/DB+US6p0a2TnZNil59gYTDS64mz9O9aluSKTo/Y1/wJAoIw== msg=uVK1XyaMt1A48Mcle78uLcilcyPBklM4S6dd8imRyGadMU4Mj5yIDXeq6YiBxMGus/iy8cC/u0Zy6fFKpzkYJA== sig=/8EecIej0R5U0vN6baBmIXaaB9GYG8WP/ljkEQSExQJwMPUfjbPYP5oNk5VdmWnMHhVuSPAsR5GANjTtyKLifDNYCQCOPccCkF3bairQg0BxunGgIDsoajk5mVuPtahDRD06t7jPS5sF/koMk8NzdxwA e=found last=27 s=31 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAJ0SzYsSZGNrEqlNxcRC0j3V21v0EZAvgMWTaFIQlCK2T5HIDJwuWiWkySMdKCNfiHbiOCzpueusA priv=MEcCAQAwBQYDK2VxBDsEOeEQSH3hHC0XSdFoxcVdzdiE4cJVa966Z3v4xbSfvcTGHi5lVos4vVVije0EnesOWL+BqQ1w9Va69A== msg=1hkxaOUfFe1QH0EfP+EuqmZz8C0/UeaC7OU21cxCtjwFLFZK/nOmK6cG4uazTI91Qdophfvp5yhsCubEeeOy7g== sig=+2eyYs/LndsMv4A4MLULkQcE/HqqXUfcQqVfWoguMgQ/e1gE1ELWnd5bmwSGOS3nIq3toDvhi4mAdJEJAAFjZu5uwVHcVv9V0lW+7FY7eAcr+MIeembLTo2oWYS0+Fm5JE2HOHCl3JdG8U2Bz19IzwoA e=found last=23 s=28 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAaBrMxRgkcLq7RfwIK4IbkaNChtPp4VN4uY4pc5Rcb3lJlFRzfiNRZUxjXUXDFwECmUm8WJxcDQaA priv=MEcCAQAwBQYDK2VxBDsEOTzNAwpTYbXHam/FZxvyb4ojXDP2eicKg7U1XkrA86NeSnfPlKenyCHIEqO77zvcC2UleV4qGH021A== msg=wsM1JsR39C6fFCG/9GLWWzhS0daTNQspJn17MexuHgEjGrsM+ZQ4oiDeO+eYAfnRjxk038D0fQjzj4mbmdmUpA== sig=gnNVU/+M7jo/CvRkIL+39FVTcaz7Bi5wraESca/BA0++pd/0IuYFSSx3Dm/KcAj0l5d4wIlrVUWAJsORvueCIkHi1VA3Ct2mnJODiSqLmBRJFEo8KmG+DCHwvzKJHFCZocNIPeXS8trxE7pT7vWY/Q4A e=found last=25 s=32 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAlent6oufJLIAY17WciUn/VfQYli6s1lCZv1doG9bnQ0b/4yS2ANR2GqXZGLhN89t0a9kqTw5zBWA priv=MEcCAQAwBQYDK2VxBDsEOS5P/ZjOrYjlN9jE5XIoxDgH/uqBFLQo9f3Rh9+H6sQiUQpc0h6psJRwuEKal5RA+OiMNGlMyLwwvA== msg=OsdLh6j56Y1AnhTcACS94BnigCgKQDCK/FXFrXvBiH8xgLqyFqeVe09YSLzLEtF7eX88FHQA/lGFpO+bJNTH9g== sig=MFoJPiym2u5h2EpEwt9Hulu1r8AEl2xF8bHa2E+Q81uoWE5LB2LaQkpipLPZBV9AWcy0gFWHmSOAkr0s11ON1wcQ8dutDb6MBpmGUYDYLraP6qMUztfLRcAlpeYlsNp+3Au4JEiKu28B1yBfY6R6oAoA e=found last=19 s=27 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoASwCp08CAtVmWuYPtQ3xF6QznEwrfDeGK5p96J7E8fnpZp+qAxHUzAFPFAacDznl6UUMPRRNckkwA priv=MEcCAQAwBQYDK2VxBDsEOaxALf2MvwFofI18ZiiXAIo+JYiQfmyFwUhF5L9QYHOOtKK5ve4wilOiI6fTnPFbMHXzn/STh6UGOw== msg=825TFx4U4QIFm67v20B8T9fCTSU4vES6VvQR2X1uJ45kDn+Urk+B/9J4VFieYThmISO20lgoQ8XRe+UghSa+Yg== sig=J99ZvPNULI4u/1kXkkXjBAxydf7kE0D1atc3wrR9+WD8MR+SsHHWtUB0spvVhkYwL6j8KO9/IluAcoq718ALsq9fLnJW4PhJontiB4Zd2Zr1oP1/dxo+EkvvMSVw3rkqUjW1myT4DAkRc58+qoTsfjgA e=found last=25 s=29 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA4RdDibu+tEvOXHpcmDb7FxejZ6aIMm+rEYGwAa3Tjw5K30KUZnrtc1FpeNgjqnXIMTKupuVRSnaA priv=MEcCAQAwBQYDK2VxBDsEOeY6A/fpIr4Uoezu5wXfShgesvEBk5EWzxU8GNN1DrqQYN8yaFOup1Kh7abuOt6FyIvmjuiq/sD2cQ== msg=aWYRAioUqubFLfEMvxJT/js7Xw06P5LmBN3kqFFio62/W+dZSHXEoUW39hikfcj+9Qw948FdnweZCBST3ItY2Q== sig=YY2s+2+SbWKDultKxh/RtbNJ2kqUx96pwLY8n9Kyoek2MhNTyJYXiv8txUULC4gXqf4T5a4/kr2APLXhF9VZWT11ETqGCH8PsUfMNsPNhkEkixW9Pv1v0rI7xFO3rnB2UToqwFgGFcIe/5FfWVOa7wAA e=found last=21 s=27 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA3RjNnHa+VqPI8Xazf4s73FKeltQtjS2tlZJWDNNrHE6H4D+JCLZ3gIxz3+n7ft56MUBBYKS4awAA priv=MEcCAQAwBQYDK2VxBDsEOcU7aq1/g6I7bCsIGX+dKmKLuwBKWe71wAvrvBTqIhUKqbLlWJkgdbALUjqDWpr+SpvU882wr4oiyw== msg=tmgswFqetNx4TPGTbz+Mz9pCasoRAgYkwTFQdstZXY7/P1viAGdxvb7C/g/gBtf5ycwEkLJDhySPT18hdPXSNA== sig=kCoVh96Usg7M2Tc0nYamKtbK8hesrQg8KSKuCQcAPh/1ehdUkKXluRxYmIIFlVeTpH7jdJxKGJyAELDRSTRISJzPJsUqLySOi10UeFHggZ+XEXybPkIJTybfAzfkTzip61R/n7W1ixsQnOB3DJsmpj4A e=found last=26 s=26 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA88WEcYdznwwYQb5z/EuvuopJaOqsb6FUSddPUk+5dJ9c09WtLXeWakmDme6zVnGiXRAhaeXgcIAA priv=MEcCAQAwBQYDK2VxBDsEOauQBMDgE14IkKGQCI1dT9RKt6B3Wy2YD5BAmrUX4QKScGM9507LyqyfCIJDSEhhzxlUxveUtlTRFw== msg=fJGR0B6NWPCUa5kDwQMYsS0LhJWDmJHSi1Z/+s8wbQ7z37rYa9Xqr6adB0JnQlserfvUItYTx+DPr7HnHWFIYw== sig=sd0yKm3pGLTf7kQ9Nrm/nruwNjaG9lH7/H1PFtt9nhmas8JAffyncQbQQhhmGKJeRkFfzEEi4R0A5sGhbqxKZCPUrCMflyB2y5Hs+WogrlVz4E82R1ZUuSlpg0fwBHUbnpZzlqEPtQKYvJ+jYfAF+yEA e=found last=27 s=29 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAwJIys+LFfSmecNB+G5ebK8+uWQJ0qErgLeDz21nx6OY3aiwq0LsDnndf8F5C4yIb4MNypMOO4UCA priv=MEcCAQAwBQYDK2VxBDsEOQ/yuzBFr4ZJpH9ZKPtmAAuL9eamsv+lUe5WQgsMPjoMz3RDPyGOvO2xnsSGSlZfurOHQ86MkXJHwg== msg=l6tzMRkUfGcbYYbgzUUTXCOly1ltnaBymwedC8UJE38sbGAM/id5OCwZNbS8UdtNWx+TVnSJI/o4tCB+1edlfA== sig=DH/wZgZmjplDVzxtYPgGROhZM50DA3Sns/MoIsNujqFiGxIIp3Xy+xaT7zx6KDGRyVXwtRBZsRGAqti4MbfYPhXccwM0cGIDl2d0YikR/juxG51tgEjJ/PiOQVzetBp8FS+VJ6TiNP16AuM1RqVi7hoA e=found last=23 s=28 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA4Ot/LuRimY6VI3b9+unNcp8Ils19NZ/p2P5TXnbIDZcG7vBP0KGF3TdX6j8UufYnXeq1DRfyF2cA priv=MEcCAQAwBQYDK2VxBDsEOdpBfqkPP47L9VqFGGUxWev7ZhnFIxAVmj7gRr/joRA77MdDHM2V8nz+dpqlw/lnCYx+8naaj3LAeA== msg=cZ0yOs51qz5hJSzo89vBJV9FJYa9AXGBskhV5Mgz9Krq9Y3LfoU9TpOgkNPiNnbMdm6hOtJmlbEp8nCL8+j9mg== sig=ZjFTH3sP4LCaNdKsAhs1jN865LKzhVdHkHS3jRfn9NyJ/t4F8pXcvoxFLS16O9mhtjyHF2SNxsKAwHmeBp7JQ5PgGVIfHgZDSYbGTY6ggUbGzludDpeduq1UXujLP1dkNwGL1F8gw+i4LaW0+JVUIREA e=found last=26 s=28 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA9F20eTDl04xWCJVVq+Q5Fq9LHc3S3t76PtMF5dtax8R5FRMXJOVFRj8ah61sSauNaMFDJLLiPVaA priv=MEcCAQAwBQYDK2VxBDsEOVM3E0nGCcBDZfMxL5AG/gEXAYCtAtx1u+Aua4lB1pI32kX6+/1PLg8KnxTVWGoFZqE449UOS7oRAA== msg=fxFwc9aW76f+fqg9ekVDaJT0jR0QT1KSHMoMIK09qbZazscrSBS6NCrDlMcQoECMky+X2/QqhgE9QqWAm5wkKQ== sig=BfdTIA0HtGUXQzVBNs2iLBXAT0rAo6JpgF2OhUJsM/rfcAh6IpwRa6ZEUk+lUyV+mScZ81EqsrQAXttENvS9G9vKpHKwdN3BNj7hy/tJLZl+mJGuGO4e1daYvQFZ0WT08FihRqaSb35AhELG9rSODwIA e=found last=19 s=29 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA7yKjwxhtF2jXWg/oAubhwwYq9zznQak/N4FcUhlROWyGsn4usv+rn7y5UeqaWkiN0qgDwfHj/zMA priv=MEcCAQAwBQYDK2VxBDsEOa5fErWxbgqbVGPCXX5Tn0NTFM2F5ER86+ltsLZ4i00N5c4L7FIKlU48hWwYl2w4euordsWRevBBEQ== msg=wxXELY/LaGzh5TBI7EMQu8vrf+T3/vMI7s6T0Ag7H64/dpv2zjCZIIq2iEVxegGF6L66dai9JCJMzAiQrxw1Ig== sig=dIz365iO26iZzTqOYr9RIQLleptxngukiwknIeCdRHJOMTgCUdADvuM9MXZCvgET1f1LOEzvOdkAh0VGA/uRCz8xOu0tPTvBnSwix9Tlpefxswlu2PX6mbn1auz35YEMKjrlZlbkQRHuB6u4wltF6yIA e=found last=15 s=27 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAAICA+8OSUHmUwZUfuqLwDXryNbuVtDqiRe/5xMLcWmBjanotW9dQRXH3PpasRPmNkrP154RzXmkA priv=MEcCAQAwBQYDK2VxBDsEOZvan9zBYBMaAeUmkAr9nDNghZ6nJ6OWaI788JuzbT+3e7zsWXUNT5XkrMOc6GR31EgU0z5ekq+4sQ== msg=niqVqv6qD+Ez7viPk+lpozLn1uvU3X3wylL8NTTrxbkSQZmfzM7uY7fP3YGkrvGT2FeQZcJLL7Jb0BKoww/izw== sig=4aH/w7RvOa6IGzBYcNDV2KTyDZOmi91jAC4bUazYMeh4UlyM0ez6psv2lGugbfJdKwevFnDgn+MAEefdxon85OV6vorhwTvQhfoM8TddR8uEFdEJUqq9smWvcbBiAOid+E0r4lkhxDGpaoT6G8xjYyAA e=found last=17 s=27 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA4tTGFtoTYGGQSXb7dlJrf6qJzf54domCrKXRFj4kNy9r8psPGb1d5liyhyf6TA58/E+VQXlspfCA priv=MEcCAQAwBQYDK2VxBDsEOfTdxXw5Z2ZVuH5T/lyHIRih5E/Z8qy0uteXQZQar63cU1D/OXHxDWvkzZtO2xPTzZrrxR6+1FZy4Q== msg=/YTDjGQHogTIvu9u6FvxhArrcUCkrx+mB1C7Bxkcr75nSQdHDBBVg6JcmgCCeA4M8NxVWhzjI0d9NohAuxmK1Q== sig=RIpGAnfMDWf/4lJjMT0tbI0NPNJtjQIkiSghTvNL/zUM6WuxzeIMvsfIgjPckP9ujbcaI9hCWRUAVnpppdcW0AmIhb8qFmXWmIy0VhnCH2dVXH5vvaq7L0ykBg1rasRUF1fTmXs8hE6c/gUz4ZDGWQ8A e=found last=20 s=28 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA5QcWhpwiLZ6UxqPBqJMfhOOybllE28b5SEqq7U5qnLZbsVCJN1Zs/VbD1EINyEJTmWZ2rXw9GVkA priv=MEcCAQAwBQYDK2VxBDsEOazgV2F2FxT6lPkEDa7VOQWajYNirM596VZx7/yakEwDFeX/x+/ejIQvvMksmd+Ga7coCjb0SINtTw== msg=6n4u+Ti2O0v8warwzpR7qsLHBur2USc1Ig/3GlbPf/1tWnDWMIJ+sVaSWW+hYKTlWART3y1Q0ck8LIboyceNug== sig=7j2AMhS7+mmctxiHM3SfPrCtRl1hC9GIA1KGiOheiBhqUESIbZZxCqVsZnp269so49pGg9ZiudQAhTF4ak1ngOuYkVHNPHuRTAcd7gaeHmpOEmsRZtmDTO4eNGCyoCgkSYNNN8wudqZ1VcGvyfKvqAQA e=found last=15 s=28 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoATQtZMKa6gOvcudHKmqXdMSvw3VuqzXp+HpILlFH5YqX7W0fDid4i2kSaTP1HEe38aUrMQSH7hTIA priv=MEcCAQAwBQYDK2VxBDsEOTYb9DurZNszQV3eIY0xDI2WWYRat20pZ4jahP6dZgmwW4R+vX7eIbZ6xqjMGMj1+1ngVei4Jwc+Sg== msg=h9+eGHaS2ivmvh7/za7RD0MSwzJC6qF8TNEVxopaloPmaxE4lCi7zdzNdk177EjU7Xdvrs58xP7ngbW565DQIQ== sig=XD5ey2VnkuNThkG9rqajA4xNiovNyNlNxwGb9San6s70bSPrNvQhjXpe5A6lv/BtLoNX74sVvrsAYxu680SGRoZi0dP1Q/3PCNdd2e5K8JL28P09142D6ykHRfDGcobtKFQA/RUQ8VNWTxxl1LZKRxoA e=found last=19 s=31 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA9Wr7pfCQd68DbBPPNqxKDNqCyinmotYQVCiSEKdZWKry6oykPthoXcffjcJ8/XHpSpo0z0S/YIyA priv=MEcCAQAwBQYDK2VxBDsEOeN1XPD70aC4ewJNrmo6+yJ2cjWj5tnEPVFBcmuBaz9lJSL7CXEDhOvnEK4MtjUsJ6CxK/pXM01+fw== msg=kPt6BXBXVyT1kgsaFVBXT42lD8vQeYg28wSqyC9VmkSoV+IEt8c1gvMoq339ITv1WbDcWHiBeOp/14l7iEOtDA== sig=VmfqvpF6gfym7yE+IXEHHZ7fVDnUN+DZMK7Lwn0oSpXv7qCNrup64eEXAM0AOQT0X3Ee+s7S/OuAKRRrynusyuEPHtE2tyjTFpTrmxSF1A67jf2UpoeU5+lDENJ2uZXUSvQgUSKyPMUGRIG+V+E/kC4A e=found 122 iterations", + "pub=MEMwBQYDK2VxAzoAXmFqhwAeW8gffGxbvmTlnh93f87YF9LNkQmyFElXwAioY/ZZpyla04YgK/QYqcOiu/+tISETO7wA priv=MEcCAQAwBQYDK2VxBDsEOZQFckjFI2wSvqfdmcKTsXXY7CxhElaNpjGQ5Qw4C5O2PpxNrjvxJ8hHYJiZhUyUzzUA/OYkJDve+w== msg=TuLnS/IyEmjZ3R20y0auk7kSYl1gzBRhlUVxD5UD8g0h5pLadUukX1Lo0loIwCxMzGSJy4ALGu/B0qfH+yItJg== sig=gX8Qp5iiq6OsvengdQsAXa4PZZSYoygIW8bA/Cn5McCPtX3twK9lvsMVK7k3tqR++pq9tyZE7o6AElNNLRMoQaQ1XOUwgqbM1HmrDTs2O4s8NLik54lIRkWsXO4tXz/zYgs0+1rfFuQG7aPQPZYpqA4A e=found last=25 s=31 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA/TGY/mKQYsrUNgRmQUHASXcSQ/EiHuF5GBXOv4G0Nq5Qv18Ingc1ZQ4VWucp7D5uI/nEyz/m39EA priv=MEcCAQAwBQYDK2VxBDsEOdzex8YdaXR9cVQSn1wm+vy3usShwFiVQoujZqo0AyKiiUJH/p3BH55tqiPFLdrc/8HGGEokXa+j3A== msg=3JoHoJEPH0jC3Sc0Uj+bLmRCbT70/n4D2ov5hRn8oZaZI+7R6gRllbGvJXt3PDOCsAzRKiOyUgD7vS+FtnJHgA== sig=WDQ+8fI5ZJTha5T/auYZnLtvm6A9tQJ0RKGY4u3m3zcdKyMUEPIzZG+BQvH9kloRHtanzfo2WvOAWg7zwB02gTYbzfQ8SR9DH0rM73ahcdW+h5/OsSYEqPYCLani7akR/LV+CkJk/nSMse/wSASkXT0A e=found last=25 s=27 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAltcWWkcjZ4Wlpbl1CxaZmotDbdCMYGidRVOy3UjmfwlG74siEZVC215cdzPRtDyaGsE4sO10h6GA priv=MEcCAQAwBQYDK2VxBDsEOZeu+3JKV8kZpjSZE2rZ5ezcEgLH4LU+3F7Iap5SNwf3nOIyNbpbVcd6gvoOoS4Fa+NzECOQPTTeUw== msg=l6MHtfLVliv418VO+5DOB8d8Cag0W1ams6vsuUI2BWc6wdRjP8XIZMDcz7K8mJYU6pRS1RJ99Wyv5YIFZZE4gg== sig=4/hByUZtDWdzx0/LtdfsXN9T8s+dF1Ua3rLYbDGi0iYAMVfgYz4ZZwZVrpnsbT9HEz61pN5pDCMAQEaUhjBFYc2Qh5nALUsH73KPR7AY3WJdg3FpAsxNqYr4MyaMo3L3dCBxUKYqQTmH0hdnojHyUikA e=found last=26 s=27 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA1B0uGrbms/3tVkZdR/Vh6zjwq7rSiSdM6L564YA9qZy+1vD6yB8GYWlgZ+MtydTMgHQn/C6+ZGoA priv=MEcCAQAwBQYDK2VxBDsEOW8zcc/KLYDOPXZQL8K3LDgDreTQqX10fQdoXOu/JmTFEosGZPyIxAW2TvTYbXHZ/6IQFaR556Je7Q== msg=FXKzHTP+r1mU2eUGHjlsChn7LdrEp5tPvWy+fhJRrgOKqEK3oouxObcIBpOBpf7HQtL0JWukOP3gTw7JeN4TKQ== sig=jW9e5O5Vh8ijyc5jINHN1OMoPM0jX8t7XHhPnD+55I6j+5zyAA0X5j/cUQcRCUfgg36D6Rwra1WANpylSpPUwQhvl6SDGzEUqJ2oeGHEPZZQsgEVtuzhs09faB0uTa8zr6duYO0SneBOoVUEEwxQLg0A e=found last=23 s=30 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAwVBFAPb4YooxvUDjCPrVDPT8Ajc9AAcXJVLkz6uJy9p7RWCfJXIsev1SWzW5qgX8p7437N7JHmyA priv=MEcCAQAwBQYDK2VxBDsEOXlgPFGd/UgGU7gRH+AW0+W700jiksH8NnglM++lVv9hJTzcok5mW9YO/9yRC9RumLGkSp51hnHhXQ== msg=48SjyAvcb5B2iU1qP3MoTkuioXLEw4w1bd/ssWeUvQfxmoyWVXfAIOJUD1hbAUIZMg2/w5QsI511IvwpGXjyCw== sig=TUpHDFeXNyPfAr4/yo/uWdRZcZzOxVxkWor8UFCdlwysXOXkgqoCJ/ZV+F2GoYT+k6OrPhb4M3aAmhbRqEeczR0YR4jmmF38WxwRZUv0AlqWlWZz426AxG+jWgS87cJUiQR/mw8Yvgashs9WKovdGhUA e=found last=19 s=28 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAGO27tZNDCnaY7uJZUhfBqrfsEGtBx+zuQHLNHyfY+82/zDBMCUKHqUnPSW2RDZhmdQakCh/Ioj2A priv=MEcCAQAwBQYDK2VxBDsEOZBsPtVu767Ogk4V7wuvBjsfOk3S4kCZMMN5U29MYdz+JAxDPUAw20zHQGvW47Iz1bGHPCqlcsGwnw== msg=BZJ1RWZveIYWcbLO4Cl2SXe4udM42cEfAIwNhOZ9Lbo26FUSDj78bfbTs6Q4q/lxP3AAon60fzFBwjZLUDkwLQ== sig=LjIEWByNKqnYp63jlQrXnlXY+PE+trJ8wn4bwE0ivFYZaRUE7cXs0sCL42R7gcljdg2D7lc19XYAyHuNTptHp2TIZmYSFY5+nuH07/ADG2+P/ShYSEUkuPzpp2zzTJUQIxmB4nCrzhY6thx5UiVuOyQA e=found last=25 s=33 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAIRiJOjE/MgZ5lY1Z38uW3AVuSEnrBUs3MOnii1Tnwc6u8WoL8X/DEfjoGg4inZstpbkZkJRwEhcA priv=MEcCAQAwBQYDK2VxBDsEOb/Ho6LYQ5XTvOR1kg7J4ujwVTfm0ieOz75qAdd7nXkP0ICXp3NnnQuPxaY82Qrj/F8aendWTMgvfA== msg=WZeYlVFz104XZBF5LbTDpoUIHESQsN4avflx3o7SXZ6Kyci5E74hMNiBkqpjvvyqF3u8CBVNhjx5310+srLFbg== sig=sW2hzCQmTSZV78QQbuwrs32SOG77OXIMaslt1I351zSjYtxCO+DtTcJMmY8ejYQd9YOULt65kpkAWHIzH6rIjH3SiQ8UIeJU5i4QK1GHB5w/IzBrwJJp/Z7ACzYAkkgW9E159Li1feDsxJEQ3Ig31gYA e=found last=24 s=30 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAEzUzozZl+RMnCaPgdNpwKL5bycMD/9SPuMONt1xOkW+vXiIOpA/x9ECxz83lzRY8jMkERjHUD96A priv=MEcCAQAwBQYDK2VxBDsEOeZ/hON6o37on0iFoqienAnAIGOTSWDM7xLPlUEtfy0+GHw7Y/UFOdvpMmGbKn6ZOktrlnbQBYkl9Q== msg=B3rbZYusEeRICM68QL76wXEunU3KIHhUR+H8QL0MBY/omYHa0MaqW380+f6rrK86Ltsacq39kS1hIxJzcjNa+A== sig=qaj/oJqZGETwDYuGBnod7+1zIInVheu3GM5OopA0Pwjt6pIzrmHeqXuW0AM+FNS95yxGE8+wRN0ANE/M/kSP2mYq/a/CnHm64atK7G2hwnTU4CTojkFAdRN9QE8N054p3NrnxHQSjH8pTUtTct1YwQcA e=found last=16 s=28 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAZFhQAJJFpNuKVG6QGZcloJrgz60IM7OQGjHwWmC/Mg8LBcbnsiRs+lanBKHEItROd7oUCdKBrYGA priv=MEcCAQAwBQYDK2VxBDsEOfIYh8PIG3wE9OODSiG21R5Ge6zI2tTzkRFLLZIYrVwYIMEWaNpvO53JblmNE2ui7iEFZuxsWFK+SA== msg=SGJMlaoN1FbLlz6WddmaDuWr/wnf1HK4cHy3uWHwmvPCTANyVX5omazdla4pm0MICvt3w/EGLrhSj2KPBYmcQg== sig=Kq3Sy6F9AcwufV1Y0yeq3KVsfyAwPoKqMPjy3Hy/JqSpEXBqhr+2e1jlpt86kHptV7LoE2EIzeIAleJhlDXXawSMGcoJZM2MM8WkiWJhaJYqEBjeK4zRSo7buyFKVo/nAQb6zj6pyr8ZwPblMp4qFQIA e=found 216 iterations", + "pub=MEMwBQYDK2VxAzoA9o491YwGuReuOE/i1BudkHHlltV14+dZRBnFEP8Ar/C9fLxqdabArT34qxnhx90fCK8Qj9bXxU2A priv=MEcCAQAwBQYDK2VxBDsEOfsy4CxcGkSmXXNj4Yt6SX3w6P2KDvToPIT5USXBfaVPqXaVp2L/GPKsfdU8y6MjxlnaDAP6Nn8Xgw== msg=WTDHTE8NQtynOE7lPXc4jb+WNtF+quEnYPMyh6EumuEXUaM7lZvLLVAnJuODYjeiSfFHgPafxBpk7WOldcNabw== sig=/kW3wzfyavdJ3q4YYD874CI3YSVAdlYHDLM1eJtgisaczQGLKEj4jAKRvwgfGNMzk48Nb8F4riEA1JsY0rqzbc0ezKOCq1ZsBIVi5nEoolxl59Ibo/tF3351ae97J4aWyb4Hp9+z1lTK2KefJe9MigoA e=found last=19 s=29 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAqpBfyvp42Zb0aVhwcrUE3Su58oemoQ6XkZMLx+prNvaJfH/HyXTW8auzGd6Zymgebodn+30q3DkA priv=MEcCAQAwBQYDK2VxBDsEOVnG87syHDjitafNhTl1w7KfDDfu0MVsC+PyGF2tSxs2wcchEVpWVu1r5Sg8DQc84EdpqTokEJuKNQ== msg=UWqVeeSglkyGGAnUVmCzNA55C6nxelMMYqhCobAEkNvyAjGCqXzCVCE25QafI9fh/NnFPZZY80tjVFD/48Mm8Q== sig=9tlH6Khf1NLO2lfcGjXhXG/CEJLdt0a7OE3AWyqM8C1bWhuwvnFMg9YjcjC/xOc71TGSsgjCspsAoh/2l3DNTvTFdif3wd9FSJd+od5l83X0FEEUtR5Co2BvJRugVpnJtX+GVUTLcz94IyPNepCsqD0A e=found last=17 s=27 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAvHo5tznOZHRWYyFrSZDIgeLsYfkR+QtQwor12vzNwNHFlYM6tOFWC18o+HkL48hiOovrhXZTuNKA priv=MEcCAQAwBQYDK2VxBDsEOZXlagCREkuEfNKD185gddlFOK1wa6yvw+uvGMo2j/d7ise2BWBq6fhfXro6YWyEgDneS6ObULoq0w== msg=yU45nRrQxHcRMshEc4aW2wXg/tsbmrzF5PzDQagcHa9Jih+3PMKcjEPZzhwWeSj6OSCVP2Dxjk0RtoMFtEd87A== sig=ynZbLrgsWvR+scuNT6GxmEyknB8/quLd3uU+4Zer0kLwWta9PT8fn5OuBd2T0Sg7J4PeD3WgAa6AQN1pNhsdd/fwOeM21ENxCYYebqbFRNjq5EqsK1I1Iy0XwiBHNLBGGTIbJxsoEecMKOngn3JW0SsA e=found last=21 s=30 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAgGF/hK5WWzTxKrpL6iO0VTETRDKuBVc9esxLKy90tO9EKPZmtvxQAOQ2lk6AuGzxUrLAQLAHbu+A priv=MEcCAQAwBQYDK2VxBDsEOUMa9ltV4IQgbz8cyZymdDp5/PI7dkdNplton16vJ1ovvkUNKqYlWaouwCK1CGmybuR10q88Oju3GQ== msg=euDJGiZNeMr4qT7rAK9y6/nVEMvBApZklB1uJcfPqSTov9LC9gj67HqR2acWDw0j6t92LpkraXs5wWAUpk28gw== sig=5uBoCjcho6lBHeD81ddY3Go7CJD7hS4ailWts84DgKSwI72zTumdNsrFHY3Jqlhr/0t/ClgIVkeA27/N/g8mvNZx90C+MfIqnT4fvHWYidrWLVaYJuE6h3VIl2/pfs8hETLdUHci1KLoDQUWrt6VFz4A e=found last=23 s=29 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAjm88DOVuaSsemJ1Z+PnnSP663lAWRYxCsmxIDpCB4M0OM7lcYQtUoofMvnFWRva+87IXVA9USZGA priv=MEcCAQAwBQYDK2VxBDsEOYNnpipIr3g0kagE5PazYqQj/W12AySaVh7cJKz/ybi5TXPDl03myIkcvOsoteC99ykFtuwyJIEK+w== msg=qL6mkINzB2hcEbAvSbAjI/8TxQKmJEHSpmuaZeRgBnm5xbwuFAMKu/8Um0qt7klSjUfzKRAW/Y4ixOqj9qrJMQ== sig=mjF4ltnI6hi1GoSlO7ag+c8zpGzj6muW788xdrIdGRfunND2zbmcRrOiJgrJMzpleh4yXnqEeY0AmajGxwV/gjc5RVR0jWly4cVGBKik/+2ldq8bzAN8TMDJzRNeqMQzvtC+nmh4EBc2EexEWpfTfSAA e=found 215 iterations", + "pub=MEMwBQYDK2VxAzoAGlcXgs/IHulZ/WTgDGDNcS+CyD5udLK3atLWVpYVZopvuxxO3kLMFXrIGVUFs/IfOltlTeQES7uA priv=MEcCAQAwBQYDK2VxBDsEOcR4uC1kOv292DzfPcFgXNTStMfzuydr+bAAfHdd9H9w5rHKsV4M0z+KPjRJ4pydaVqq7PnA7IQUYg== msg=8H9ZSIQSkG1FSoC/FQUW3CAA0tvUCjCfdkQZ8j5iaCcIhetwZ0/O2n8774ZNtrFpSgQBPRwqMht2nYlBF3g+Tw== sig=hHEhloQFqTouP0tgiAjIj9jw5QA7O1aqZV1uyREWqP3xtGV9pXf74ht2YVBArapu/JkKGngstMcACxG7V1l6HxnVUBvniK7q8AsWvynm8yrhrwFO4qZzl0WAbTGraXOYTUcj9/KJaoZ36DBomZZh9RAA e=found last=24 s=28 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5QfRPjZ2aBdnc0ipmyMOXnpH0v/9447GuLUbp3H9qAApquqLjr4/0UekSr8mQxmRSwIBq6afgbaA priv=MEcCAQAwBQYDK2VxBDsEObNUjThWtpDUKXJ1R7jj1b4NJXWyWOhzjRRsQ8cnGo+7OelTLRvulhdwJdm71Q62Hlb6bUqY53fsfQ== msg=pZeY+WrQQrZByJ9MwdTEWejk9+4wFla0ibO7uyZr2LuQvTZ7AFGZtI/ZRw0jvjfElb1xfQUDrgUlt81u/Phw6Q== sig=UaVX70VFyar8RqOj8e4dqbBqNL9wbZrqrTcgZ9O1E95Xf3Bge0s1ph2P5mWSO0Xd2q83CDFF1OGArzOab1dCBe4zx1u8abelM0O3EAex/HtQXHkj8g56sP16W8KDFnEcLmbeCAFMhywkGxJRJukUsw0A e=found last=22 s=30 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAkq5yzu7qbAHEqPnYt5kqkSn62rRb/SyQYced5dy2zv3VMJBoGSJoDZPyFzqsx+QYpeVbKg2nNrGA priv=MEcCAQAwBQYDK2VxBDsEOaw1P+39AiZzJ3zGiG7BiF9bJwfCjezut8MZxDxkhO0ZX8DJAU5lOl4TDmtbgOU1OkTz9Bcjw0fOZA== msg=SM7QHfhnCoigx2IWH1F4ZgLVTpFLVvS60ZISqYxygVFCpeAhMvWpRv1oBXkVia4fR1xl8FLyIECGIYQfTT41+Q== sig=sxVKzZntc4FoFdGh8XUbRXkXW54A1wT1bT0RBupupT6D2AyD0GrhcFTxsh6ABMm7Yf8vGldS+ZwAmhzgKzk4+e9333r5w+WJUjGbQaraopOAG63iahP+7K4mBaBhUtiGamSNfCjNGp107q0RedRhKAYA e=found 214 iterations", + "pub=MEMwBQYDK2VxAzoA3qXzkODBHljXKdad+YGBo8cWkbRD7zhklJ08vg9QRWIddN5nNXHn3kK8Tr8StBv+GmgO+MmT8J2A priv=MEcCAQAwBQYDK2VxBDsEOf/svq/cbwcRJB9sdh5RefOKpRaeSDC19h8MSxtI2ObdMWwrLbN8f4oCvnBSoWovJgzPM3jyALmp2g== msg=IpHHtbxt5Lz6aDb8fW8PbAg8KjlqflJN27hcHxrZmpAmxMMcNkRBsUY71u4a7NCgcS57GvhJcOWgZnr0iGUg8g== sig=/YQc/vkusY1sJ2C5wm/HCCwA4qxvz0ZutnRzVX4k3AtWrBSqxk+vW/tZ5RL4NK/KhB7DaZT8vw4Abb9Xiv6HFaLMf1jCa+5rPuJteNs5AhHFLCD0nABTY8OyHF/Qq4N6magHmaxGIMUdMuGJJORGozIA e=found last=26 s=29 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAAoEybAbRQ4/2UbhBExhI4qBwr0E10nCEb26EmoYrbJMuSw0BYpi30q9maytJyuBQV2qj+HSHrxwA priv=MEcCAQAwBQYDK2VxBDsEOVej2v5wJsdQ7Ut7sNVK4WFH2rlbwmz8O2SppeCYh7ltA/rQO+G8kq85RYgJ7DvHiEXvFVCiQN7Hfw== msg=p7oChTuXor4Ri+KTu4kjKo6RG+VIJ6uzTq1QsTc9oiCN/43bCTHFzRFaj0m5E4+32HrdVBoTwNcxzVUzTjPljw== sig=7tjKuMxnn9xy0KGh7fZD+j12d66fWwRYK2o364htJ29hvOG6xHdoycrdXS1TWiGRs6BDepUNE3uAeSs2MBMSRTzDbAzOYeklw0SAkcDTSvD5+udI5J2oSh+raeQdfZPgNGjZV7Dw/34PNMgY4ArSvCIA e=found last=27 s=27 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAXNxreAEKCuwddkGW29/VFX28QoTyGY56XrIOvAuqahL356btdB7v/0c+Uuep523n02IuZez71HIA priv=MEcCAQAwBQYDK2VxBDsEOcRW8z459NB8wZJUp3wOEkA6oWDr86vk+gcmhOvdw6T0cjKGeieKFF48+K2yXtvIDE/oabuz9xAatw== msg=F2RinXjwo6NJ2ZPd77aMUwFxytHQao5uYeD3aqGtK+jFXrh8JAychnX7qZ4n7vrbiAg5IRF+2ez58/mgbVFgHw== sig=WFMX1OkOt2eTMbpobQmkas/ojLBy4XLq3JDMcIpDxi6TgEsyydq3fhRUGeXPQOq2MItjTe2qtxWAAflL/RBVUFL1tp8G7uzA60Ol1EQcqLiIayYTTN266DQ8Zo79yZmkhNvM3EQP4WYtRL+LH5iplAMA e=found last=20 s=33 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoApzHRLYJD9lssuZD78DH+jOugBnghcmTv3IlXaeJyrW7WtQwpOJy8osoWjaUz+IRak2fF/n5p/WiA priv=MEcCAQAwBQYDK2VxBDsEOQ10DfQRh3PMIn7rMINLZRMsbcOQD6/hEyZ2R5ZmNlekJFTPNpxcw4aKT74jnEEq+l0nDb+ljouzfA== msg=DZGm8EmEwuCpFxxnVgNve3pfY2hRitV7UBt4INSNIiIlYd/30v9y75u79HS3iAJHt6UjO8VHdz02Tn+G/SoX9w== sig=yNgIL74Pvvjv3/279p+RhMu30oi3kVwU9HJRX3AtGnwfTYV/E/pciD6YqucXxYE1f7gHxNFBA4mASvp+Mi/+OSS0fuQGFUdEdk/INHG6jJRCoBbS5mn/8O3NWkavNMv5QJJyb0fmrF+zPlfY8D6QuyIA e=found last=21 s=31 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA4KDWvJx6eGoo6Jx3iNnfL1KvoNNhF5est4XeUjrRhzo8QUh1bqN0rU/oXYEcLRrA4rjIh1AsqaAA priv=MEcCAQAwBQYDK2VxBDsEOThQQulKdVhLlcQuxfrcUFsGyL3q1Kt/cc0/LagX7rlxqFw1rncWoZ0qLtGyNlOp1stV3yTrzw6t3w== msg=T22xk4SUdAZMtaKmfwAeEFklJpKJ5IVhbC7cOMi0xBQ6J8/imJzBmyA4dW8si60vl0kJ8J7UaOOHY3qOv/O1bw== sig=UCBhZIh2+Yi1TllCB+9SGp1s684/JYQk7hAlmEUS1wk6z2HnNFubNHzZ3cIRey/s9rCy67KOsgMACs5miZkKAJyxIV+sLLhRUBabgcNDW7kTOiR8iNAvvm4TSI2uHr3We7otXlnn2mSNRIr1JY9IKgMA e=found last=21 s=29 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAk8Z5SftUO/rtr1lj77eHEyA/KxwiJe/dxiYB6LOqi5zcdNN/GFL6+Wje72ixcVbZn9ZOKae3M7MA priv=MEcCAQAwBQYDK2VxBDsEOR6mCYL02fQWBkim6Jo1gAbZ+XEADEjyMMgK7aY0aM10BWni1/KjnvNXTeNtnV+v8KfFRxzEKTu7lA== msg=o/z5FqufkTJA/5jZ4QSyEnB5rR6mCYL02fQWBkim6Jo1gAbZ+XEADEjyMMgK7aY0aM10BWni1/KjnvNXTeNtnQ== sig=BeW63iHDuLhyNNWFDceIDb3yZ5aHc/Dfd7nGVvI0l27KVgrQKlZRw8937s54OINwWfp2B/uQNFOApxD//XmNe9j8QQqo2NwWQInRE/YwU1TkgOZXTiVoHGZ+axmZLlKacbj6vpycNsx5g4QGeG0LNAwA e=found last=18 s=30 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoASB3gFDs8K+fmTCp2T+2v8jora3l3FFfZ6vCxXl+aonvBd7zrnjAt54A6o9+5UXffvimBKktBcsUA priv=MEcCAQAwBQYDK2VxBDsEOaGRpLsntDmKaNMrBakVkIZhMXRoa2Zc9M554nEPi0q0PrOwn8tOVF2R+oRTBfOV/cOYh6q1gtCNCQ== msg=xiWCcOnGUDqkfbeTRx+siuR+NrGlhV+JO7TcrCE6cQ2FHzEK/HRCIGIjoey5ezwcFcmZdVSpVYPu66ITgp1vqQ== sig=uNcen6M5E7FYrC35cTAELZV1pEzxzc9Na/IUDqf1EK7NkNs9rzAdj0uIWZoW4KYph+rLgm+ZUGwA0GQdqFUQLJZm3GoqkYpx5vo6WgG9lvN3xZW8zlne4VNdPVpWWyBIqd01ICOP6UyNi1lripQuphQA e=found last=16 s=32 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAXfJ6RQfm+4qMYt1yBUt0Fdj3SVNDnbPYGH42DDJgZyPW3HJTUg3kqwnOuBAzsPjYI1Jtivo8BjqA priv=MEcCAQAwBQYDK2VxBDsEOYBAFg6c+Gqu1InFJwX+0z/SZK5vGXgqiZ61Mo1xjML1zcX9qFCwCOtX+aQ+PNLC5SX8Wp26VEde7w== msg=SUdZs0BcbXUuWMsUtbT6VN1u2VmuLyrleN36ItD1K1FiRQlVZ+mqvJl57NelcagQLsRnVVQcJSm911eDRzISpQ== sig=e+5AFbUm5/kLnSaT63j2Ifi4hkDLCYro41z0WOJlNq6sW/ZyK5OPh5zLouf04/NL8GbtOgLng/AAeWWhiree1o8ZXPqCotUcAZqM6LgUZyXNFnNUgT3mSd5fA4plopWDQ2ulU/AivoNKV9v0Pp/YRSoA e=found last=16 s=30 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAucynSYCGAVztIppIrH9Gm5vLqfMfbE2AuURBbcbWNgPncg1rc5oGH/OPvU0CZVLcaP7wGa8scPKA priv=MEcCAQAwBQYDK2VxBDsEOc9VxNN+6F+8Je5PXlrRTrC3G7AuMNkKHuFapPk+XsyhlFkC/JcWbBs85v64++cogR8gDMgckt/ATQ== msg=vA+EKZxSErF4pwl8KXeeXRQu8mqFcmPJACddowqs5A2k9Dx2+C/66AgnaskoBCkvLzTC/s7cigaQmxvoaUacVw== sig=2r8kMjyIwYV1K5qAhMTezWNfX7S6KGKTBQOHrv/iYrL3gh/VK+wDBhDtqlM5lbNTgKclqy6x1hyAXiDxZcwhCEohfJwhzyhTJUMBRmu9IkptMrMOaLXceUlJjbch48I0fOj2WiudYmEItH5imCzjcA0A e=found last=23 s=30 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAnTu+uRQ9AEuDujQ0CViPxS/lMdWCfOJZkyT6EtTi/rc2gJcFgwdjmnRu+eAIBtSEbEg02GnV8CyA priv=MEcCAQAwBQYDK2VxBDsEOYwQBFdzy74hYlUat+Ow/b93s1ywMXzvlspxjP/yfTQkZmscye0j/MYyw0OP4Xcxk2fAYPZ4WaeORw== msg=KgiUjoKU2PAimOF80eeg39cSTyUzum+uOedOZHayv38C3pnTdDJ6E9zaHnTnUHTnYQ17USRGNjXy6sPqfkLQkQ== sig=nh89NWuT/loq1lDo4oXCnhWugIGRLg9uengUNJInEpg+fQorXWgzlmLXyWUwwOk1eUPYDEUIu9QAyIswALznmDNKH5Y0fbTDk8qwL8RCEZp19xzaD+/Zb7mO9g8/3hnsbcJ6eVBbaH2j5mBJF7ihEDkA e=found last=26 s=35 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAJi4jtHZWFLpaZLeJc0OuJyo8o7eLAH5V+5Mf9nQZw8OPBo5W0VrwArV0TnMJMqTGdi5C0Ee2XdIA priv=MEcCAQAwBQYDK2VxBDsEOSo8lpD/B3R1LVNt4SY4i0b6JF/VJpuF1+F+ng3SwpasHp1hBpCfuCPOQNkrXkiOHLDEP08GC8+R/w== msg=tB3LNeo7/lNoHuiRMhYOymFhqSQ0Cw1Hfdw+anMltFH3dwDHXQgRKY4HC84ygzqxTif9eoQ+Wm0tGsZzyBmdCA== sig=BGwlj95YKntmUsody6D4Br9kNmWXJbylQsSy69uf2fRA9laNuN6v1xLFaXn/qwCEukShM1f4XVsA6Z3sCdmr8gvOW6cPFwE3mPMd4scLjCnp6JRAJda/9hvitPBDgQdJDVvEtjq5BS9n7anjiPwbNQ4A e=found last=16 s=32 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoALVa0P1LWYB/cgzXPhm2e3UPdnuWqe3T6W4Rr/A3yoU/amF2mGEsFXAXW/93eZ/y6OCg9UBX2Av4A priv=MEcCAQAwBQYDK2VxBDsEOaVSdW4w8687maNSzBS3GAGoYRDuORl1GrkoI7HunMMDvY7xcFqA0viw5WkOQ1rgo3R8Nfq7Y0FLqg== msg=Wb+JqsTUcGh3PDwxkxnczqXA5+StdkzjlRaMx1fIkjhEf67ClL6zXK5tFpdbKp4MlA4+psfsKa62A/AZDuPDtg== sig=TtO/obZACC9GQQWVdsjBVCG+nHBu1sd0qKO/6fp+gobjxwo9ppSSD4o+IDFsPTUFDseVEibIvWCA2FqOBRx4RgOe8M68XdA+yL/bWht+YhOoVGIxWcVhpepDILW31/na9/aG8tIbCqZf80QwOu843hAA e=found last=21 s=31 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAXkMfafuhtlrUpAz5apR+NZnG/57hkt1c49ovQGB5vZ47ZKfp0Iq+a5FKJREYrfOdicctREdM3U8A priv=MEcCAQAwBQYDK2VxBDsEOfQ5hPwQSDk6t7ej1Tr9FQBAUuGRMPBuQEcY4WuvtUXja0m0zKzgHigS7VeD/d0T5ScFxV9el28vwQ== msg=IDExtJC/xsEXaUwO4Hi4XwTFim+8HKY2+DVVa+CgozrYr391jmPsPI/UZhm6kSMIRbvo8jIoThSvY51DmiZFJQ== sig=avGkVqlm/KLl+dWNgIPJbWY9gerVLEoY4GtA1hnglQTtYTkAH1hr5kec4YEXFf7ytONLXH1XxPoAxekTukxFLW/0aeSoPLRbsYmiiEc6xT12Z0lq5hU/kYIzngBPe6cXHK/D1JXvIR/QtIQ5waf60iYA e=found last=22 s=30 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAxyzNnT0PQwdO/8w4IgRY2qdOHbSllp1h7WaNcAmii53+JjUXlVAUb/7lMxg4GH7hlsPIW80PwHCA priv=MEcCAQAwBQYDK2VxBDsEObIvZxJ26R4/YkPjjAnm2VaWncWGxprldwHiSmTc5AfBKZtxHYl6KWNyI357cY9gMgdkUUPc5rm0Qg== msg=j70qRfrseGPX1drlby8vaZObVx9yi0kH6/HGtBh4zDAUrKe/AAto8jOLHnR+k5euAkI7BNwxEoj2C43AMRC7nA== sig=2LmzMLz08KNXoRbAsW7IGx60sijqVd6KYlLHQpamR+rJkNLMkMm30idkMh0yzJlHEqX4KcIgszEAfqsfdFCjFQmSUyha9fTMZhV25B2G5lVkl5j9QL23wCLN+OPHTr17eCSKmLB3a9mCi/uHitnQ/zkA e=found last=19 s=31 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAfqr245RSmVoMFWUuWBiNuCRZ+oykmsk9AsmXF5cjfXDNBepZaeQILtmnnj97xwDNL6tNBzseHSGA priv=MEcCAQAwBQYDK2VxBDsEOaiTW/2zDRbdnZLeoa57dIFctHkbU4tba6CqfFdMhPUs9vxEZCFNyc+brSUjK+q49KfgXOT1kFNpSA== msg=fxFMBdHbtIfOTg9M/NpZEpPveZZKXb55MWd+wRJmi/32c+xY3dXeiLb7MehAxxYnC/MhopfUGsGxgmMCzb+Fbg== sig=E5nPIgYoKOoyMYfAh4BS6Gj1LNOomTjKEpaCXhZMjgoKHxaM2QZSIPtyrIvDaNgXtaB3m+ZL5s8Ae8iUoEqI6Dp74KcxzTygSd/kS1nroIUwRHodKy2to2LLBRI5JBDFcHHgYqeKzIOwL+miD4s5mA4A e=found last=25 s=28 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoACyz2+RPQS826HcKbD+gR8Oj+d7M400SdpYXQ0lMWlBVT0KEGqg6cS2ZMNOvWMvJyQNEEogqrwkoA priv=MEcCAQAwBQYDK2VxBDsEOVsr2NppPJb2hpztdlB4IWLrD/enmOP+NwtITLvvikKUUHZq5mSeK6ZWc6VpxL0VHEk/govETgvYEw== msg=X/jXAY5tkHBqi27f05RC0hCxGegZ4o3IQwPpP/jU5Ut3tBqTSsmR3XIwmGbnbeJLZdjeo5PoVI6RVNUhjlKQ6w== sig=QaZCD7fASg9V+11f6AGrVS48Q/wMZ7WLFKQg7t0mC/tGKeBAyeNUsckVu9gZM2JFmWsVLm2UarAACr7ft+rTt22Esi13SPxGSCFHNSkiHAgOLcwFmOi3nfREgYJQB/8KKcUaLVQIiRKkhzmOoT3qeSUA e=found last=16 s=29 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAMiz09cSmVct8L4zAbV58ZAx/QDXOAJnVVlP5ZaGwToNquI2fiBQxYJViFgdzlJGKtYYXXubXOFiA priv=MEcCAQAwBQYDK2VxBDsEOVaoryXsVJ/U8j+aMVSLNssrMEEuiH61V+LYgXmP7uxUJTrF+RBQnAPG782t+hpcgsqxwJf00iwmeg== msg=ujRKVaq1D/X9sz2sMqe0lwIbmzmEDAiXLVC5jY3N4+kw1RJAZi3jL72Q0/U00y//azm56cM+u6zCb8eqm9lCQw== sig=qUWHDsFafhmv06CNEdEBxKl+GzcSd6eGl2jz4Jbo1lbejmfxZFlygJ7GmH2BAH2wrT4bMCRB/tMAsoYmXgP5PvT3Urg5599TSDiUkbWP5x+SbpIJaVBQM7Ht9nJHVp/Va1G2gm4tgcw2ERgR6ooIhRkA e=found 123 iterations", + "pub=MEMwBQYDK2VxAzoAM2ps0FQSkuWmqjz6HaHVhPv0TfFp/IHxBPKggBiSzPJC9iwZI2eBMgHkEvLoNQNahsKMA2n0rxeA priv=MEcCAQAwBQYDK2VxBDsEOaUSKol+CcO8C/xdT4OKz9JXioS9Qohep5ZIw4mb/LcpPHVo059vy568/evr95P8u8sBUbZYu2PRiQ== msg=AXsRsCQnhArPf1CT0X+4R6auo2dP2627og/c1mKgyY073/HORErAdntRferENOEc3JvMWaBBt0ehm6rI08VcKw== sig=g3zU9F/SkcnLYceIlcvP9JFx6G1eF1M6yKVWh7mwL6X158IayS3gtSsp/7kFeMN/AFdoOoNMtUsASXbQ38ACYf3Mol3gqm7pI1eZXFZLyY5qR/kpIeboe24s/0HjMqkDpaSoLm8w1K4OBz/DkqEXLQIA e=found last=16 s=30 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAt/U/lE+Ye1eYBlUZwt4m5Eu6gmd9cUtA0Zxgj+nyDmYSse1Uhn+PtCrFrCtL4ozVP0wVe/N02tSA priv=MEcCAQAwBQYDK2VxBDsEORBuHqpq/HqHstR3fcAOp7S85iuy4hx2npo4W1QA3WeBxQLpvN1aol6qkEzT5JZyhLy+4RW6oCSjsQ== msg=W8Wt60AaLBc+UG6muIETmlUIrzoLbRFQ/pevQDEUCefAMcDDPrmrJQIHFpbyswGfbRlGv2oh1BIrPn6v7wWt3Q== sig=uXOjJZoAl7oSrS19jlE49/wtIhgaU1xICjcCbLv55CDrYYHgZ45GOTFkjV/QzYh139DhRvLDVj2ARSnr8z/1Hd/Vkj0bLcsMTkZ6lTBab8C88Fj333cVfWcJ78dePFEBABC1HjZM+VK5YezM/+f/EyoA e=found last=18 s=32 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAc2xR44B2YITt5U5oY/S+oLlhgf4i63h1pRvCtx+o84hgoSa4h7taMIheJI+c7h1mvOko9ApFxRYA priv=MEcCAQAwBQYDK2VxBDsEOQDYE5NDODEDyPG6rtNYCbFKLHOdG3cJ5mADBKwqdY8bND0aVugEeQc7P8kK4e1rdaebmA6x9WFqtw== msg=sJzNrs6zF+I+/9oXSLEtYgxitvUw4ztN4L2qs78MwlTzUPAzEZ/z7ksb2XMmVN9wTFNHrbPDrRMShJXW18NssA== sig=NJBIBQsK9cStUOlGgxWG3oZX0VGoKafyTAE08NMA3j2Zuj0Bv504CsMewpNWinWQ57t+VqaGUtGALpmrgy79I5yAuUa2HcL7Duc0W6qHWShYzXJPYVcbHzP7xBXU3L8K+CnNz1lhdFPUvem7Wa1kJz0A e=found last=17 s=30 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAkooTtoRFmwwsZr3gPfrd0N6SizHceNx704QbcV5fOyWSm0fSZl84TSXB6ib970lHf7umKUWlTr+A priv=MEcCAQAwBQYDK2VxBDsEOdhgbvLg/Rxi4YzZbSQVPPO+HhjgsqNUrt16dp6rcZEFID0dGPzVw18WYad8ZwQCAkyW607wBnPJ1g== msg=z4mgC1yaXemf8LLmEn/z1ORLeeRABGMYM0bQcWYtSsSOqtTZHfAEKaQn0R/4bDfKE0AYjYirVlZx/1rRhx2PLg== sig=1ECwyt1Ae8c+n1qW0ey8Xj6zpkoesrGCJjx9W2/Tf02Ol0FIQWdEZ4GdsrskAJacYE4yOuPV97eAQ3r2a/Tn7TixECNC8A+K1VBDca92Cpbpl3DIpBBje0pWqbvcGUjlWfETugYYoqpX6/6RQsmprQwA e=found last=26 s=30 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAsB70sHFiRc4zX5b1Z2joO+Q5hpJFh2YID8lqrslZGy5RcPuX49u7Z8VPgXxmum8SHH9/ErG4DMcA priv=MEcCAQAwBQYDK2VxBDsEOfx+tXN0Y0ZNLFdXGIyxFP74ZAxOkfbqKQPx/ti3NffB7rSldpwh+1bnfpBjiIm7qvuTv/LVZXjslw== msg=eUWwPOr5jelb2LnQE3CTyw8yisqqEoMRBRgE1H9KGxb4/Bd4ddhi42qg87uXlb3G/Fgx9fideflxRv6HkMA5Pw== sig=VEXclZ1iaew2MKEf8dWdes/4QenUtYLdQ9afLZmmkb7R9guaddU5QwZGf6uE0CGfVDoN0hp4wvmAAIxUZmAnEsa5c1/X5hBVXYXdYyfh0fkA41dTu7sW+qv1xj1LpBjWAp71xyVCaJwI5YtFEZCiZTQA e=found last=21 s=30 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAwMMcLKqNfL9r5JuHQ39FsqCVCzWzFITcfHdPCQOmzxpR9olLJNMOtrpNfCnPTGt1RKgMyfjRtVgA priv=MEcCAQAwBQYDK2VxBDsEORrBLO5NlczxQ6308W1PJRSd/Gai3Noksrukc7nXztutuhqirdbEdfjh5bTZuc+HRo7JfpKxuo1uTw== msg=41Y5rA49YTlnRs/hvQogCrZ091I7ZTx9wR7DTdASdsv1Psf1ywf2cXUAquoNGEtRnni0gQqDTUiKz++6x0ZztQ== sig=AHR886H+zV/UrXCW93XhxkoRiyzylEBrEaVgpYvW39/6R17UWJW96zeWQou//hCf5DSUbxV14VEAkeUdtPCTjdIxG1Ptnu72AaWNBO4gxYSVIZnYOmkJuNRcpiqlCqtp+43ebFyeNg60JGAAOc+azg0A e=found last=22 s=29 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAbpxSIg3Sr5YQVIGAEJRxjrlhZjiPWgmSk9mTcvP5ix6NDeaHzPsmokmilIN61BkHfPGGjol5C/gA priv=MEcCAQAwBQYDK2VxBDsEOdbyUwsrRzMsvXo5ULaR1tE/YL6XQfaqRIPwcT7YuwSoQWOpekLfSj75G6sL5eCzkvrdc4tmcNdi+g== msg=EG6kjm9k8QKWzzKItUyzYUid5Itr+CjK0L64LnXUkyezL5RQTg11Aff+cdr+9yBAaoVG+5+oWxpc5TZTa82/Lg== sig=VlpgEn87VdU/p3enS0IT98RnRZlKWWRaGK4d/1tJ1YEhkHM21Cb35zLWcyJLPlHB1jXpJckF+6UA4qTOCbYhE+Ox3VkbXmFHTUEfYVaQCqMm/pjda2lS6QrbMdkN/ruNz+b/gFWmkesOpRhbSO7r7A0A e=found last=27 s=29 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAsyyiWaAYZ6E0hwLpoDylPTjIAZPQIMZ/wx76sSFeNGiJSdtICT7dCX3+e2wMN6mE9iXqg2BjxZKA priv=MEcCAQAwBQYDK2VxBDsEOWep33Wf8XFncMbsV3miHekV44RAFCDYpTCHQX9SMICXHc7lDE7UEW95/t2ITbDH912dHYBF4unS3Q== msg=rL+YkHKrtrwpzqG17PoGahrcmjnFr4nj5ecHOKcdtpj+J6liluTIVO8VRgT9x37A3Cl6PpmPu151Sf4pD72tCA== sig=l/K0P+rOeUcGxNyUDFc3bVzf2txTYFjoATKXVjNWvqQqiQfAauCU9wMjSfTxqIyITZUlc524pZoA4AxO/gr4g+J96ynTReuD+m75ZYw4mTI024IzsRzEYPMxeEUbQPCQObzyoAJtL9mVTO+iyMrZIRcA e=found last=18 s=29 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA8j/9W36My4BYTxRJQtSg4yEhTiKAzKCkq8BXqr8lDMPyQJ3jymJyDUCq6KspzI5GVjO39yYIYjKA priv=MEcCAQAwBQYDK2VxBDsEOblhxuzVzlPOJQcQZg2nOJI0Y1sS57Bg7oq0FzSzh7rEdumoa/iWdTyZTrnHqvJ30vDN2hSNkerE9A== msg=TbFwE0yvpowxg77Cz08FW3eD8Nt4HHn17pbq+1RZDAwIFnsNQGk2wlKBpcfIAk3BE/zx3EHZR7pTiAe349b2IQ== sig=zJEGp+Gk+n6S0EL0ktg6ZpDONbO/TCk0/pionbnVv5wBaqI1179m04Zp2FMIxVqKuDPYiSSvat4AqzDGlqnQWfr+CYTUgkVE12F4/Bd6kAVYi2mKVK+9/MrInT329xiAc81BGWgOPf59sZE4dE2OCDAA e=found last=18 s=27 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoALP1t5iprbiA5Ldxe1iLdratUz0iS+OkrnybTTqDnGnEmQZGmgaMslL/16eP6EJk4yNQdvLukpLSA priv=MEcCAQAwBQYDK2VxBDsEOamziuKFMxy/IyI5Pkpm2Btkmjql1l3fKp95VkBKKpyagfSgDTfI7ujRXw/Key1DFncOmjQy7zxnag== msg=SP7E6wakjrquY+N+rD0jPBtZekgzzP5vTUtIRR3iyKY8fTOhiaQMA/1ErIEVprXzuMHL80pB2AJISGKWKhm7jw== sig=Y+17vS9xO1ZmHy2DLUwBQ5ezD/eKUJZfubg2sNLp7wL4icAFSBuFcR9YmS8IkHQNBeEqbNPzb/WAFGUYUY150YuYWCxV2VIMq0x5FCZ69axifL1VFq81nqquZztOZFN2qfXbjqwM4KqtMZLrvLELswkA e=found last=27 s=28 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAPDtUJLc+WGodOXmRtUkTJJsquVI1fxkbbw/i1/bV7nbfx0anSS/IOJBqbwkjbDFfkaZj28UCODCA priv=MEcCAQAwBQYDK2VxBDsEObjfZV+plxbhba3kJT9AEDU8YeF9VHlZxn9cp/Vm5OqA7Gs/fd40VFOt0TcU73AQ2kGmf+Fqh23cbw== msg=6dyJ3ak2iBstLvl9Vf3JQXwzB1KqUe1LcF/wN5WNvNnRR7TAqWrYwft9Y3gUlExRTwp/cf6rDjXCi+aHuD+KBQ== sig=TOGko0FxQJ5+kmsmURdr9+PAC8jbGmcvzHPhGHdJ6VJ5l6RgaDSAomKNtpx4ZmeAuIKugghcQTgAHNQzJfYtuCPtM8Jnz2F5Iup2i1CPhVE9zbgshNFKgULopL8trD8SeP2q/0GEK972rnUk3A3tKQ8A e=found last=27 s=30 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoADN63UYfbhbRkNT91J0N4cMCrAPwLN45q6/grjwEB0FLKS2LFHMPTb1lBDZFBSpm593HqWLCOQ8aA priv=MEcCAQAwBQYDK2VxBDsEORdF0ofl9MyU94hkcUkbyeUc5tUR76sN9MbA3dxa5XKB1TH6KpOMKNnC3/Vnv+gkAGpP2Lp/ZhRV0g== msg=rX26hls4EVcI7fQD8g9LbWIgj6M2sBu2SZCpHHnfZOOFiLn0/YaKu9Kq+FIfgtj/VUhrOBC7wEcjaUjeKwWgig== sig=y2xMZn1g0jFjL8Y6Wd6eWm42cgprUP+Qz1RK1VO/VPO2fYTdnJFVtzPiRtFAeKdu75MisOuAojcAQhHJsFovtM1dzM7DDi0CoiK1b42YkURgAzx4ty+vjiAfgtF95mvvW30D66yJk8lA77TIXiMf0joA e=found 124 iterations", + "pub=MEMwBQYDK2VxAzoAHSl1o+zfGRRSQ1cQ7khAyCv6DI1N/S2im+salqCCTvBEM1grC1MUzBr3Gx0qd0Iykj6HihXjXbOA priv=MEcCAQAwBQYDK2VxBDsEOX+eX0n7fFoRlfQKmclJWd3gFcmGQyZmfWGZ2UZZn08Bt7V9G3fFzDJrUa4z2SKdWlydliv4C4eJNw== msg=JVm3gGHogwAMyn3m+7hOETOv+iXGRdNklAd0ot/110O6XtY7LLHqiMLfIzjZQqHoz65Y4W2ajp0Mr0qHfzbuDQ== sig=5zGX4m+hpyfhvL4kH4erwp7iRnzZNsuCHE7oQI+mIU2WMhB8gLQFthhrrgRCMEZAZ5BJQzdcXquAjam1V36cVqZzB+ZvsdfvkkUUmFYp+DDwfz5JOykvIaPq0tnif1otekxpfFJJCZVXvyYyMOEY3BQA e=found last=26 s=32 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAw+DkXnbpB/ZccEc3Q1u7kZNGa50zFfWm46gXrS3fiXU42I2jL4uN5zMPC3eZ3XqLhMgFH3Of7s4A priv=MEcCAQAwBQYDK2VxBDsEOa605SAfczAk1ggtT8VlrRM7bv2jPDdp9xeizWtL7P06egwnigX7I9v9F9TtQYs1cno9BeviArvLTA== msg=ZF2i2V/anX/NOBg6L5x3vTdQESfk3xuLjg2XHJklQHcjGpPHyufsI+0zYF4im8jr9EJ4E2J50L7TeOKAsUH7lw== sig=rOEbjB8D9aOx+t+TaDbTZNGdoiuaecUvutDeV8z4ySr5Oksm7mE4mpKhgFyT/27i6O1EfgRpTOiAGUny0OjXYhuilGRjebCb9TiWZNBJ8rNBoxtj12Emly71+S/bRbNL3l4bCvG/ntXpqPTKpOO95CsA e=found last=24 s=31 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA2qIfIgYjUGwrm3j9JpfnKZ5KiT+S7K9CJu6H5FcBdsfc3fx/+/VR+yzSlJnU0jLYsAzHsrQzFEOA priv=MEcCAQAwBQYDK2VxBDsEOXZdolUBW+rJPRP8u+/IyHAUnzwyPAS4D8JnJXwhDSnUau1UgeDHt1HtTYjfjk8AMrRRhg0aaTiWLQ== msg=gTjXAP4UzG56oPd+pIoc/3rL91pNc81ECGzwLuIT1zmC3bs0HyHW0eiPiFAaH2wqCrb1w0YsTj3WVMEH9Sjw0g== sig=DNbaonwA9+xq6LglnjVgif2nfVd6TSe27X3xahaDI3pnG2bcW3vC3WAaK7C3rEtQx9MKT3bCHVkAMpxIFv4YzlnI3MQsTE5T8Y1HLPQb58O0QQBbUby35pBD069ZZn9otg9HVXOfvZrgezjk8b6q5SUA e=found last=22 s=32 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAVc7owYropYikjDSsaB4szN7T4x+oRimfPlSVDW3NWQcFnw5TXSM2E11wYdQ783T6jZ1YlISRV+6A priv=MEcCAQAwBQYDK2VxBDsEObi99BvIbxISTyiwQBJ94Iq7zzme/V18aKQcGj8jaYzyAkzQK8pszXIbamEghlXTMDrrAAEu3PmgjA== msg=qT59YFa5OdvUBRS5GydDLYO2dnWlvvukBEffydZQXEzDf5OSHA+BWO1yl0EdQmyDJvo/h+nYQsS4aGiPjlCyLA== sig=bSc6Cu/0s3LQkQbLtR3s9uxAy1N21kguUFJYrnr4PEPHuMvMOUJEs73XMjN5xsoOSGNAES7Y1TeAGtP1owlHIMeDveTJdTrs5b4srnoVWkm6cHna1BNiBEdJACZ0w5kQJtgZHqAN10tWJEjjPz+KJgEA e=found last=20 s=30 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAUQILKF0f8rL93PWgRLLygibCUrcUKmO2WfrOeRMKKsXKDl2EjA11mAkyMAxDUrxVvmezHtJj8SaA priv=MEcCAQAwBQYDK2VxBDsEOSNag5Uiv3m9Yp46+nUOh8Qn2PBQa7JVBBXl46EcDrgha1nWA5/1XopMgzJIKkr6MiTf6Ka7SVTmXQ== msg=pcLEyjZyqMNDONm85afOk/bHkgvrnfaBv4Ja5BxbLCbSeM2lyj0Ivb7TNJqmHKAJlf4UhRBu2JudU73uNhbvcw== sig=jRy8kWRW89h2jJ//lDVm3P6B23URMBKIYOo0KOSTn0NltoBAM2LNcmlp9hf7oUFMMMvFoHuG4G2AyVl+4MVkgtFqEyuQEFDrg9uv4rHaAyKS+tq0B4TPEWS0gt972wq30xym46iSGylISJtaDON8PycA e=found last=24 s=33 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAA3wIBJV+jCYx8i48+f/WeefmKWmm4GY5nfIW4uWmKm2U532YscVnKE+KANRTtk/iVjHqfLz72lYA priv=MEcCAQAwBQYDK2VxBDsEObKlJFq2WvJFv6YKRVhYdcoDybbbNLflYAtVP1Hvvtm3vcnvCOP1oZ6pmDiVZkVaKDTEUkwbAXDL6g== msg=TeNZv+1wyaAzYt5j87qOPJH9gpWzzdvqCwTEO8NS/k84XjtuwT0T93rMQhUmcw4TeK48an7UZmIam7CvEnfxRQ== sig=vC4mcQT3Ff9xzYXgANW+Ob0wqE+5PagwxQHGWZRsN4EICPcie3ZiPaxD4ZpukeEHdMhw14Gj4m4AtSUY/i1+dNXu6mKoATYyPWB1yJhcIF2NcmjKkGatl2gGyoXV9PEmKUZW4mqnY8xqVazyNb1JBTsA e=found last=16 s=29 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoATJ4A1Cz0dkbpw+nN6owzWmLxc2FUycM6JApXxCuQgooySMUXXyjiMJfvP6d3vQOXize5J35OIiGA priv=MEcCAQAwBQYDK2VxBDsEOZc2MrlEZe37YDCDHf6LslSxBq83yM3prprViqjinqANRPVyWz1dxXpvhyTQUBKoSs3N5ayliE2pDg== msg=08wUGMkQ/eP15+fYWvByEXufMSFga0RJcTlIzwtktAE4iz6ObcVGeidcXWPgLj0g6JT+RoEpY0SFiSXvYlsxXA== sig=eWN+EaBzGHN3aVqxKbsK4IQ60TDxRwCp0c874PqKPbKoQnRAKi/khXnRWJVkgx77Fwmo7YIQWCUACaCLdzX8T1Ecyfcotq1fiCOv8+moTUM+u3nN7Em+070gVwb4Hv3ISKvU9nJhl9626pdJ41cQVygA e=found last=18 s=32 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA2+ukUgf2wZO4Uv3LmuHnRULyC6SkTPre5OTYpUyrAiu1zgHLXOBv6isR+x9UP15ZQinV63UEHUIA priv=MEcCAQAwBQYDK2VxBDsEOa2utg9l4ulrOfD/p4vY9D3cRISHyrochzg6s+cEVBvGewnN9tHjvG1THUTtRe3CK8VIfYOEE8tIEw== msg=SIBJePHokinNbs7Dtbuccbk9JnDR6b5Qx/2qolsT3k3/BcNKiXlkpaD+EhBj9yZ6AVxebWCiEhR/ra/eOq/arA== sig=mR3Ees8NjSxbbqB0V2t8hpVRmhsn7Z7ktQh3IwDmdI+ffwBJdNy5sTKXGz2aAvqHBwEgt2P+RYAAW59G7iFH7zPy9tHfFC2KBr1/4zVPMjJ+FCphmpP3Mg6l/7PNsPmoMJgaQoZEcX0e3K6Tmm55JxAA e=found last=16 s=33 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAGE/PGAKzyQw5QF0ktLOV/WUyjoXLE1DlfkF2Bp136FmRcGOtYDJZeSekETyF+7U3LjK/14LfI/AA priv=MEcCAQAwBQYDK2VxBDsEObsMsVGzC5ndTmSqD8CI634lzh3eeFhkwadwEJ9MfjJltvCwZ3OHWX/xXSUYeE/jFn5taXfTBDZBYw== msg=v5YGQPPgOE4J7B3GErhK9gPUsz4CgQHkvmCpO4kgBM675y0CGDCNxUNlbujPRQPFQtdYwO5+gwGxFbwrLxVMkw== sig=Bc+gxF8RfsF7M9XrOvYgEHkKqFTJexbbzp4YxonKIfkW8yG129dAihtfCKkLUEFi6WDQaBKKzfoAqGEnjk+Ck8+m+GbC8Q4X+C8RmSr2feecYY9YPHvZqYldlY6hn57AAhEzn+FhkT/PRyV6eNQiUDkA e=found last=19 s=30 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA7WECMg6rRohfDMWcY17BfKaHVlCyFpoeTcJUlknMxTiQIrdhgwSeEpkDlITY7FhiRMREer05cE+A priv=MEcCAQAwBQYDK2VxBDsEOez88B2EUU8NaNBqmr+mD8+XBJCx22OXw69Fcm7CKpTEgQOUuQCnKTAUj73Uz/8DZ4dlxl68nIwKag== msg=0CPg/+LEdwZpORap8mhiu2PC84CWaof6l60X1iY8VjReWCeeD48kYDnDVpnEsUtTlScMGTCklE0xjlaWFwxf8w== sig=jhN7mM4RPSACI1jExSuOnz9bojcCj9qquJ/kfffnsZiNXqa0sIAGkHU2wgnzpvm03GI/oK8xZxMA4Hf2+oGp14JxKZwb9svfzRsC/DYNYUgMu174C8eyC5JHub+91J55o8XjlTe7Fvo5DEUHYcq1Nj4A e=found last=24 s=31 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAa/rQtU4lzMyrv7b2n97kY6lJXZcbFvVoPvcdhQjgcxVCsOp371U6ruvpqgkm61jLebuCKg5zgA0A priv=MEcCAQAwBQYDK2VxBDsEOfJlLW69SeqCxWCNLbtU2ugGRuQNNWCZTmTokMVS/waC5dYIpdz42tGC/sCAi1spSmsYdRtUWckolA== msg=iEsTPTqu+nMg/ejxEl+5cPTTDVZIKHTzWx9Cg5V1Yw/k5h9zWOPmrG3YJCl3ZeOrfWndeAg8+zKac/EpNopKVA== sig=m2U4uj9HOqtwmbrbsCFQekPpqkU+v8BzgBanwbsODfCOAr7yhBZRo7I96cG+NYFfViMFS769wbAA8uJg/9FnXPpo5m1VAGIIB1aY/1oos5vB6knbsPHSK5yDqvDZ9Cvf1iOl6wc8+4NhpAgMlXg1EjUA e=found last=20 s=34 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoABIO6bwKMAIURj1zmQFwCQ99s/S+kCAEwpC4kDcB3/oqBHehpbr7LoeX9Rqn/oSZvgm0SU1GVxJGA priv=MEcCAQAwBQYDK2VxBDsEOQnQkBQuV6JAORECAtWigj0p7sDY6kYTAq4NG8WWA/iGXCZKj8N5pmUjC0Ttmi1lQg+JkMPxw388UA== msg=DWr5+8fmCuAcgI12VYJiMksl8SsURVql4HckcR5aW9uQn45pcOlRlPp0pO7G6eu3WT/btKluAwcEun2PytTVLA== sig=lpzyb55kvZVPmeJq9L0sKcX1BWAaxtviysNlnX1z0X9ZmdSCo7sFiFHqdJkzxsIyu6Yd46iTZTQA9Fp9ALCb4TXHO9usQpigAshlb8RFnNcPabFe7xYPeNcOtxgBmGWfeWWD+6oV+NH7XvglslyfpA8A e=found last=23 s=31 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAUsrURx+JkSY5Tkxo7OgpPJC1lcMCiALuxFgVSXWKgLs6GyZNMUc/pbAgbSqN6a8RpHwN3xhR/YIA priv=MEcCAQAwBQYDK2VxBDsEOeP+Qjg98PVat//eve8ssttMWqq6FcKohV1Iq4116Kqi8bKedHZIioJUoxzYmsLlbbULzKMQJveIVQ== msg=bgLZJeohd7t5UQ243uwyOo8ycSrPt99oAnG2/Rr1SxrJTzU/DSk3YhtJNKhaMxt6IAGommr2WEmbvc+7Mz3Rpw== sig=q1pDdC2Aqg6vPQy2uzx8m7NysYJ9U81tXGP2zOHGLyNAiBlQ1cXfVkuiP1CA1JUDyS42eOjrbE+AE1AFKrD04jZd0VCaqQQzNZK9onE0R65SCCpXHWr0mZsb9vDG8XJPkpwkBzi2kB81gMZqQxzoOTYA e=found last=17 s=30 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAAdSv0vBskPPFMx2B2btSwSiPA7CJdfD+P9inIotUsjlQ/1FCjdLUANoXYVf1iga4+sufspaQB7wA priv=MEcCAQAwBQYDK2VxBDsEOawOE1TAqPcYIB6MJ9oHmnB6ege8/J14FxhoR7QJOZ1zjvkofLDC9tSjA5B1Ks52x16DlSFqGylDVw== msg=++M0pNYqS5PuOyFjayiLmnxmhYbenkmsqW7no1bqcrgKDwL7UFIA6T8N71OwTPGLKw5WHu6HCrrd2bxsGobzIA== sig=xOZn6/swFWYIfNLRvH/e96N1Oi0fZ5v/dJWO5fke3q3go+2sePMP6cATTo+AgBEq1P9ot08kBiuA23YmEn6R4giXp86JfY9FRAbkQA2mk8OBJcR9/6pdJqJpKTdKyLZ1hZA5pUDZn+q7lJa4yGEe1RIA e=found last=22 s=32 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA8JXlCDbPOZCh3HWxQw2HGK4VeTV7gOKcQYI6pwwEM/9RBadjqcNuRbDc4aj0PS/dihAxQ2nwjC0A priv=MEcCAQAwBQYDK2VxBDsEOZYQUiydeouf7fUP+cuJjky7kUT9lrMo69Zh+IYYy/Eh5oLP7WQmB9BvwI5ruOnJT9vhkPSgSIU7LA== msg=xJnwFHDFPOk0DhA1awomHsuD7s02yG14EshaK87yZoROejXw+ait+E7lGZqgeTpN3VCpcouMjvTHxa6eZrh9Eg== sig=r3EtMQAwxRxbuNldngXcqqQDiS/V5KJrehX4j0xbyUwQhwOhAUM8nIiL4mD8GcDDqO2QsAfNrpMADdR1LfGR+sz0yUb6r+kPHfoaKusb5BHVCQ/B4SpMOgnuN5sJY/Xv4OIzCm5KJcOZd2R1UOIZiD4A e=found last=16 s=31 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA5goEoei4VmPmP7+XchK/xHF+8oXNk0RKW695MGhSzkmRlDmN0tAFm+SUw1MYlCuYIRAdNgVphRQA priv=MEcCAQAwBQYDK2VxBDsEOV29Nc3hg/DmMMllZ5necwYawGRtvMNPd+T8lhyHgNHhVHaginCwz1Zp3613FimPkcAoaNaRcr13lg== msg=NP15VRvFqZ1jklUYnQPviBwtbnvUyH8UI8RwOn0cLm/V06I2f+UmJG9i1UVBijWrSoqGIxfqazBSCIEwyVhNAg== sig=JV9KyPPHI7OWkf3f6u/+oJh5RjK97Eddj/GWtU1LqIZMQCthkEpBgZL0IZ9UtvcUIMu4/jUyzU8AY5xkfSip611Fr85hxXNGov1eB+vL66ZKNn+2ReunFHSa+nQFQ/UADDvVXK18q3OjufA8daCl2wkA e=found last=26 s=31 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA+6UZKzeyDym2XU9DIZF1CG0uKHJuaKpw+mJ0FDv/PM8xb7/lYkJmr/4gwp03l/ItRhvXf/P45GaA priv=MEcCAQAwBQYDK2VxBDsEObj2IptnQUTCLWyRHli9VgqTk14U5y5DCJkHY5kS/pvNbNiUymfDiutkCX8UKHip2dKwbE07EQ/wRw== msg=4JV2qTbTze4vC1F3XatdFf2d6UiOVrvfl5dZ+v2UMQF828UqTeQkiwQBFdymQKxef64h5DFUdCynnuAh7mvRNQ== sig=OjRFO1LZUrikO72s5xwcMnZ66dH4ib2XXDDz7SSdDcnwb+kVwxe+ePfkX1/zgGAPj/tv5jxhOrAA8Fy7pjhkRXhwny5tjF1wOwicbsPdUbT4rtB8YpFxSAooHf/VWfcnFjyp8z7xECbiGHmKKdju0RgA e=found last=27 s=30 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAJTy6Zz3TPhwfuwA0LsPlKUyajxT5dIdeHurLidS7fPjzbANjrmSr5A8rL5NZWiIkj8C2k40R0iiA priv=MEcCAQAwBQYDK2VxBDsEOXk+Wv/IZk08Bf/yWy+/OjtK6UelKFHu4DKM5recpw3DLF67eBYzA4SkwR4WTblVN5VlbkrKWyy2RA== msg=nGfs0OdeLWKCcqBSPsjOLHpIFhSXTLIFmz6VK5GQrmxfK7GvE0U1nsq9l8PamfRiOj6mB6hrRl4TB502/Q/tVA== sig=gkv39hq+8BxbPpYxTeHx0atFZBKLgmY5JnXJAKzAxQgVsjrwYlTX23IkrDPFVdXunWFmtsLATyQAhuAAoaE5LdsPwimQEv7wrdRJvMVCRz8QSTBvWy5oTfV4EPwvv3w938o4OadOFxAAkS3uXOcIWjEA e=found last=19 s=39 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAUcTxQAhnSpt55b3kAU6wiFx8wFM0Kycnm25Qzxo8HTTXrsqBpuUs5MEJoviBtzpG/qSjsAdVs9GA priv=MEcCAQAwBQYDK2VxBDsEOb/b5Un+KBGZftPX03tsxi6rpVmvKIfUkqFqhFBjy7iXcrBRF2ArWeSx7Kqv/VdebSeXUHh/PpHWbA== msg=EiyPGaMd4z8DbbLksxopAd3uLo6dsstjx7a8qP7yOFnWs23OmOK6c63dLqOeDtzfXQBBjTbrriu+7+eRnTUq3w== sig=QQhjJXgqAfocim/IJzXGdOolg5qnL5gD6L57rvvfFMtyK6+WIkub8Id7nKbBLnJolAYNanutssUAsUAcpXiiu81hvoc7xrp3KjsdVlObleTTmVQtHlRHa8pn+XXY01eMwSlEdlyYHGHq0TWh34inHjYA e=found last=20 s=31 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoArjlIXkdseoKDzoBrAHpUCWjJF6KbvO7oD5ZBtrKLId/xsNyeJllGFBj82HGHyfSOnru/XEalCKyA priv=MEcCAQAwBQYDK2VxBDsEOYUfr/NXvDkopB1Z/xwEmi5+6PzdG+0EVwtjQlniCwDb8sSFlFXsEfFJ7CNBXpljcU7fIW7YsIkKgQ== msg=DZoKA0DY2yLaANppl12u/oLGDUqHoXsGMMV4UV885WPYJKEa2XnvVzjCFRA00MXoRInQCn4VOIr13B9mQI6ihw== sig=4Mhc1Z8uXrg9XAdzYIApFf3kbULScaXiTkbvchBBcYKC+2iDzzD8fLK4vd5XYY0wPR9r/cNrNdQAIXJTnyan5f7zPaHGUuUG9TJlFIUMPIELkKNdSxi5rWL7OL62a5QgiKsvMgro++K0thyyJGpEEAEA e=found last=20 s=31 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAae+v3gXugfdYnbmCy661xDJU0hmd25/sshIaXT59kndK3sUw9Vl1yNhPP1YNB44a48qCV3bfoPCA priv=MEcCAQAwBQYDK2VxBDsEOYoYrHKFY6SMltZG0dE512SMB+3SrPVVJ/LDmZ8qWm/02KmBrD1sYv/C5rE+b6ZfuxCpndmw3MCzEA== msg=/paBof8rx2RQG9WlVdsTgmtPNHvc6KHBjCiphGUZG9Vp8Mo48kT96mZ+rOcOlbacIl4mzXuwKtw9xGVx57p7KQ== sig=EgrAC+dvpPUMcbbIK2hP6XQj0FuxAcopgZdDuwGWAUfuWBTEUoD1ZzvVE0MKOk3LeWpi/g6ZpvEA52qTmFcSL6+mTmnmlJextIGPk2uI99R9llzQqMkkLprZNWmoz8SNexzeYLw/M7BcLZHcHORxsDYA e=found last=22 s=31 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAu8m0RnCXaNgy9R3fJ9VsRyc2FpvU3XjQ2/B3Fu48ymMkfci10bQprmnPJ8msYDGI4w1VkAz9zkEA priv=MEcCAQAwBQYDK2VxBDsEOdUf/jyIGvO6f1N9tW7YISL2yOfDNPPdJxEak2hi/olXsy3PzhCJKSDyL73tiUXfxaS5uUQFZ31m9g== msg=V8UebbDS5kGefNTiixtACKEj/YsDjvsyV09cmqCP/Lrf/7YnBdhsrtEGJkwg4Qohw9WWkbo6ixnrROF5NIFIKA== sig=8+KRqvq5y11fZlT0n+iLsdh2wsmwXcLofYMUS91qVwU8ygBifoH+dQNUOOD8BwE9WoZ+SKORNpmA3KMYWKF3jUR0NXTz/LFo5TbkdF5Glsy47+k+y1TMGVY5s0n8Mn5AoQv2HmvWHXyKvkoAqi/sWQUA e=found last=25 s=32 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAt2WF190tB5PjnP4yDz3QhyOKbfDzcaz+Ju528CkqaPRZP0GN1ISqmQKLCV1IK8hVaYwmQF0Y9quA priv=MEcCAQAwBQYDK2VxBDsEOZ6UdFmMUZ6z4iVD9q9MZny59nypHDd5e/gZKKb9hSjZfGT6r/CyRVb/hJVPDLXOZ1AwVBghJgJsLA== msg=oYUpwe+76v9xVrnBvIqLXmPJCJkfHY7wfjq5H8t2SbRltyviwlC2EHvN8/tNvUoW4nOdMxB73PDsh1pcFJuJPg== sig=aLAHef1qjFfa3BvmG7Rm26tfBtN+P0ukUBPX9rvLLrGgSl8OvXDpocIiqI4WQV+nqk5A75qOopiAg+bFxP1vIFiGQ1gygpfTapNeepq11hXYFrvndixl3ib7eo64YHSUuvPmZHZyrkOM8FDVpTILeBwA e=found last=19 s=33 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAobMuck2WcR4/5Hu+d553b8xk+wV1N/rnoDA0h+EEJGJX5YVZ6MGmJFneS4uajd0Z/nia8Bv0J9cA priv=MEcCAQAwBQYDK2VxBDsEOfz8TvLDfO7LVnAAHYRFPqmXNxPcHVMhoV6a+8989G3sLMoxT4NCkGCwhr1w9La5ESVDcftFYzuxOQ== msg=wPPAseEtOf+Y5rqPrEjX1qLJP4a2fcQZnGnUI+Md7USXlRIWKdiJaljws+NCHyEpTwea8XJaEJfpCC7rKdToAw== sig=0sgO1ArmVAHRovu28e933i4/ohBsGnqjuXdGOZOFaTkGOEHJV/HK2m1th+JUMrTW01cezqZ6YQqAqmRc+kXrb3l9h6oRxp2mSvxOgqekYliq6dvUv6NyNh3sClKFs7V24bkoeJTvFo8Z0mnmpS4/8hQA e=found last=17 s=29 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAEgN+AcaJA7F3981BNxNLFc582tVduZPIzyXZJUffC3DSy7aJ2PwMkWTeeks+8r4SZnwc60+cN6qA priv=MEcCAQAwBQYDK2VxBDsEOSIa6SvJR8r6elxvl41hqdXqlE2UcDT0DT/HpV9BGUdlw4ge/nD7Ix/x9YSRbpwzwREEOf49yP+NeQ== msg=NIC++8XfLuyfd1irB0kV//ttm+TyZULgqLX9bM/5DFUryOSJEXePhwCilgvLbXuvqT4lchTyg+AwVHvZ0XC0uQ== sig=EPTT94T0ksq8y+mMqDMyYe+oH53weDHJLwr3aJSMtqSTDbZEXZo5IX11gLIrnhNAWtnnpctIBOSAluNhnQbDsRlh3/qgiNtvIIDQoC0x2334vDumPnxjqRBYV5s0pLkNdFGy4tulbpauP0eiUM0tvhQA e=found last=20 s=32 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAKUem7fxaPwsBTYa6WcdX9gs1soko1IcOXr3aDl3Qzm+HctfRC1hLxmvvOSslDoTp87ajbsl1J9UA priv=MEcCAQAwBQYDK2VxBDsEOeAyLyDpVC+mW+8HcQpo6y2d8JXYYzNhrc/ZqfcbUbZV23mrGo2AJyx2Cdxn5ro038piaM9OFQG1BQ== msg=44IM52dDFN1wQrqtwxojCnxHEqwkyL4vEG+PU+xGL7IjhMp0Z5UTrXXZMMW/8Tj0qlkoixs4K/m3Xz4Up3vz0w== sig=iYaJWuTOMjPOiZwg0lOMgI28aJcJwOFqSMbJqbF2jTnDqIyhxup0AU//LAsQeQSHx2dFKhTewdeA/02cITeYQWdDMltxgztBz9ZCECYeFuJYgx/tAf68/dssCmIpceRwUOo8a1SVDg+rJ9xnno6vQjoA e=found last=27 s=36 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAKXdS1/a9mm2CY7fCH+vJiatWAhCf/oOJIs1KT95OAW03v7dMYyhfQZw8V1wIeRuIN8eoONDJPaEA priv=MEcCAQAwBQYDK2VxBDsEOZ7CKSy0mLFsVlz0j0uEWOnls0hC409U0avWkVjG6L3xfk5zwfeM8EJzzNR3iym7vsyhImdp3khovQ== msg=dZzxIn8dkBqdgXAPPvg0a+Nurf9QybFRM5gX4q7NfQnEshTUdau9WmH1JHdZfEiDFppGoJO7LgKQ4fidtJs9wA== sig=lc9pQCqWEph8bkvXYwkIFvJrKqkGAnEiWGj1HdSEDKaRbRm5uaJSwpxbf7US4l9YO6PGjnuL3FeAfNp8YIapVt7CukWJZzqiPPsikKeKD82+9IZZ+X49oi49UpKudObg8JjVLfVoSR/GejhRuUrtcTMA e=found last=23 s=33 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAeoUk8jhRd9RrjYRpSHDc4NlvyYU/gJmQQU5qcvmzl5IF/ExNP6Uu98uaPNeXjHVqRS0ns3Kpj/8A priv=MEcCAQAwBQYDK2VxBDsEOTsioO5SZQtTDOiXhkaN2b/03bPOrpvdwO8sdF6xBwaZhwSqD4CmZ/AjQ+ykPbi8rp1LUL1MkCQQwQ== msg=HwrLGrsgkk3a8tJBBRPs8jYuBzb/xAKHtnvvmiofCrqu3B3vlPwJYoW5h+aOvOn97xpegFQ8SM3QlWmLvV8t4A== sig=6TiQjBGZprOPPkSk5EgrJn5UzHKx3FZH3iqEksc5cda8kTNXuAV5haKsEE5J8z5kMBMO2jNTcGOA7s5dPkStLNcG0jz3uJ41vdsAuRvXakJfii3MHpXcmslJmLmrlh++YG0R458xLBRTmie+L8jH/jUA e=found last=16 s=34 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA1boWIazvwR9+g0rV/2DcNxs0fKYMDLChjKdhq+cNwWXjkyPPDbJsWYXojHSJ7K3vMbUiY7H9LreA priv=MEcCAQAwBQYDK2VxBDsEOfzx74t9pqFJEfACptDdQtxuJSCEi9qCVD3p/lnXi3gB7lmBCrW/UsMBQNd8WugVloua5OCtyagbLg== msg=/ijPvZ8Uez3LiPdGJcyGVdkrVG1BNcl1rt6c4E40FX9LzoUX11yF1n2Sxnhg1PE63ZP8XMcxZZ+ACSgaCZ68EQ== sig=ZUxhKY0oc0CSGzRfDxgsVXiLhbWgZzb3V3IR2QxLyTVQbVb44yKphT+ZIGc38tQl94RKOEoP+pqAZa2fWRfYFL01d9my/AufdDD4EaEiRTNt7Yb4NfeHtmNN1AymD2SELSRsp28wXDzqVK0QuSpsPB8A e=found last=18 s=34 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoACMSCvfAn+B4ZO9XpJ7PKGV2ubj8orxveCap0iEONyYD6NafrrV3zn0jxaKuXa4CuFR6VFMdzcncA priv=MEcCAQAwBQYDK2VxBDsEOSN8gjbZA+ZTyREfjuTGuO0ug/iW09lvmWwsPIufGIeUMGcPHZIthGi60XZPW40lRmk3SVEDhAT+Tg== msg=usYim8w+np0aKoghUuTI3Y4dJQ48r/TvkOe0d7K7DUuU4qA6NDotrVRrGuDXFZ/MqNkTPKzWQvlWcbyrIyveWA== sig=6EoKrvHnL2Bo8lK5M7WX0RWURWBb0lzYoEaoalDL8PM56rgiSVDPb8ycHl3/2r1kNxZH5SQcPxUAkXyefVaC0u8Sej8rpp8kJt6IkcAGfUZCN1Y5X8sFbb+cPHa8eswVZuktKfJdQwzMziLkmOubtBgA e=found last=17 s=31 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAuDYI64c+G8ra+or+1T5kaVaJoeB8FGr9zrM6P+rSMGiw1czhSW3OeuxFpAG8a9e+n09RS9sW4xsA priv=MEcCAQAwBQYDK2VxBDsEOV79c7La75d58wm1GVFzf8Ftmhoz1jA8H9OJL+mT57suv+Q6cMXlhyVrnLHUDVIU8qpLfZC8Gjza+Q== msg=faEIlc3hf9nEIuSQj40s4gOhUyidmNfu48N4fsGryIpDOn1Gy3VhfS0V3XewxRzVjAb5HBvBH0g1AIQhuNvFTA== sig=Wbzxs9JNhVaqt1Ktdp9jPQfTbT/+Rfe+jtzVQUmhIzEsAS9nyff/16Y6F441IoY+AsRqowHxPp6AdyHPhMJ4qAOIofBXAfpce8Dy7ODjien1BHSTmQihy1z/bdRgdx91Ukn/ps8/zYfOq0at0pk18SEA e=found last=23 s=29 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAnW/riA6Ac2+uFfMsYJ99/wh8c/UNexdQC27Af+r1hX3zX5VW6HqBuB6o7JgGTl9Vgq+vgqXZBOOA priv=MEcCAQAwBQYDK2VxBDsEOQ2jqyN7bHlT3o6nmN9J4LYzDgmcjIb4pf+Hyeswnf4aph3j37t9gYj0k0CDn4zM0s5tYa7izoFW6w== msg=PUfWe7I0XGVethir7SFn8EtZSGxUjtfw2tM6kyn72F8P2YCZDEdX/smPCGFYuPXY4G/aCvSzXTVPDooalSGu5Q== sig=t18545jXtWnGDAJmQr3hyE9OChphy6iOKcGxq/n26zxqI+WTgbAuToBV00q6sMRd42RAQHiEL5uAbrKv74QrlMkBTC2c9MMRqP3RsY5QAcUVI095bJQgMVMMd6XfYmffDoW/nd4sxI3i8ncnviRU3gEA e=found 218 iterations", + "pub=MEMwBQYDK2VxAzoA0tFMeYtJRV9bycPfOknEej+fMeDdqyLhNv6R4Ga7cqNjnAUtgYCPDEx99L3dXeYGkIKL5IclWGCA priv=MEcCAQAwBQYDK2VxBDsEOeDCTLhncn/xk5mwEKodtnnYeNZvVdLMImAmP/5KUtCra0CoReq18jgIRshDX+KEj4sShTaxrMpMzQ== msg=iJADT8+WAp6IBOzOShtFt9yGKmQDhhoSz5fnqA8sJKQgFCaC2ebnk14XuqZHd3t3mcPU0E1TA3o/oUERStozBQ== sig=aNYXgH3OFXBn0a4J6e4hlYKjsHeGEjIq+UHqyveSz27VG+bwlnxV9fqId9jE0VFadhXbyj8ozyeAhpmVgcRYMa3rWmS0BFXfqm3LbwRkwXYYAhYQ1nKDnuvz8yy9U2GRPggRevTdw44teycHAdhvMDAA e=found last=19 s=32 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAfjfVKWRiZI6WMfFPFzqZbmkkPYiNHhBkoN4feeTIzlFu9ba6gXXKPHQ/95eHBibvc5O9j/ncLTGA priv=MEcCAQAwBQYDK2VxBDsEOSsoWOvliMPktQxsZ3Wp4JPDMIlbIaX3fDWQ7J3bPwWorWnMyIywr2NcLImszbQYvbGVjAt3Tb2P7w== msg=pJfDnwyoYF1qYmQTEQlUzd3qIelMbMw6os4AV6K6sZNiwh84D+/GcgsI1uaq8TG6cYTgNUCxDOufqyg6fjVydw== sig=BSy43sjZQQ/kdWVAx+UBGMaRM6/K8/Ree295hc3fHt9jBfDA9uVCkearlWBZ9lRP0ODDP5+3kCMAtCWXV1kSi4I7T7BTHhDl3OGowoixuLhiMU4KkYeCoQaR2MYb+72i2nc7dM2zLj59luBPdMignwQA e=found last=20 s=30 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAdKL3X07Fhvfua1Eyum7B7JPM6R1u1dEr2xnYFqfkV1tDrZRx5fC6bcJgBu4LAbwJA8vCq2xLP70A priv=MEcCAQAwBQYDK2VxBDsEOTRaoCCmqNxjGRmEKajrvQV3Yi5v7aHDxClWzd/ZTmgbbeeDbYCdt40Bg56oXG8n/hUOZdrQePmapw== msg=S08Iedj49xrabOyT2MiU+CZXQq7I6Dh9Om5j2UhUAdOYjeGufNBJeWtgJ9qs2zk8rQVsLPyCQ4+mhjsdCWl10w== sig=ww8asU3horElc30ApSb32BF/eXM8pRHkQk31PPk6rJxWUSx4yUciIRARwFqQsUmM4o0fsN4nTTcAX+ij2uTom//ztDmtJZnBDGkmOnBK95zkaDBWX1C1QhEa051gnRY77Ec0zgXltEA7h2EtgYjGHzsA e=found 223 iterations", + "pub=MEMwBQYDK2VxAzoAtbdidYl+f8CyKgKKAoLYMWR/tIZ9WFxHmNuw91Vc289vr8FInEXb2jixUkJXLz5BUbbry4u5KO4A priv=MEcCAQAwBQYDK2VxBDsEOVt5/zURh2jN3YX+RtP0giulGWgrFX0Iq18Du1VEzK8j+5aBTtCnawXADgMsu6CevUsh1Yu9n3G+Eg== msg=vKRzj9XTkU3XNFEV0JDyKnnNvR9XNV7ZB9V7Zl7/ijLC8A24MVKhlgjhbw32WCfUj4lmzmkW98bBcuSSKtODog== sig=Zy29uKA3lrV+j1OQxGRvw6/0DzSrVHMu/NC74wG0nDJY83UmxlFZlc7YYQrpQbs1hfAkiMReqIUAOWZeIP8nOOqfmfgSpg8/dfNN2Pb40PHu58cP9CFhKxn2MSVGlJ+2Jte4qLqv+raZZ4+Mi5osIzgA e=found last=27 s=31 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAChsUhuwhqvh+ZHVtGmYuzvzLQpnkIre/sGacMrdJh9ba6aHWEQzc904yEXXkT4XHRgqEbBYEGiAA priv=MEcCAQAwBQYDK2VxBDsEOWR+XQG4yR8mK+HH0ZMa+FX0/0t9NmZxD4tvPuRlrSTzwLcUSZ8cIxRKCys6OBw/ZKewrkDpCqfCMQ== msg=Oq0LGiyihIk82mMQ4lcsrcn8AfmILUYD2vPWFd3uzhWzgKwo1KxodWKk4Jb2qt/XHWw7uXqVLe9DYNrPhbx4CQ== sig=R452JniCLItjvwAmcSdWSLO0nSdqo6971anDlG/7EI78kMGDsvAWdj4DSu+gJm8UnRmLISJiE2UAWkKRPkr9iHjbeQKIZAcnIIfJ4Xqoi4E7E41G3wuS7alotzKW9unuqzX4LaMuBi9XXY7/gG10YzAA e=found last=15 s=31 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAEtMeaMAhbZHT4hQF3xpsuJ1Qj3FdHkXm84bxAUAKqdH/CYCGlgQ3nltAds5zxY2fa3ubmZpYN9YA priv=MEcCAQAwBQYDK2VxBDsEOcwJSEoGu4xwvsAEUE6kUaM3o/cE963g/FkpR5nCcP1udVBEs3vlguufNHCw2iQO+X9C2cKPmMh+wg== msg=oJiQNUBmJMmh8kAzaCcm3p0Nw+Q6n3al4M5l3743EEjaJnyiD7rvKDg4Tc5dGBwMEIUAZ+54IAthPdZL5Jn5kw== sig=EuzCOcMcHpc2nXqdkjOnQl9wp0UhE226W+K3cld5fHbQtxNrVg1F7kf4GTLxq4cV56cvbphJmf6AtA4ePEbSivZljPzfxkh1+WfckPnLN2MD000ncQAQW78VJUtm7x4TxJJtiqe4d23II+/PWsq8bg0A e=found last=22 s=31 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA9ixKg3BGCL1Txr2BkYATjcXCFUKyg0U53Q+fHjG78T3yssKHuxBJ26MPB+yDK//rcK3Y3Dh8+oEA priv=MEcCAQAwBQYDK2VxBDsEOWtQxNjoRpfSbSuc3z6I1/QwT7js7fi/1ZesFfZNAYVyC+QNPQsNMLl/Zkf7kQX7uAezpHNd+J8Fkw== msg=UkGXnLc+IUX670e31Cn53WHh8CbB7hoHciX2/SkNvY2WiA+cYf9smEPjEew0Ox8UtdnRVR0tKqlPqlSMQlBsiA== sig=73wzxhhMQiUBU0pkhL1m9X3wWMyqJmnLWlN19/HxIDLinbfKfnSFfTSVptV1P5tZ/v7OUNrIkPQA94RRbjkPdcRVSFcyq/YIywQLhqbuADfS++8K57h1MHl2JzKhlpqZfEdCPSOdY5eEfCwwd5Y7HwEA e=found last=27 s=32 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAwrZfrsYW7khNng+cqZKGgVumT15L24dwYPICVD/aOiU12OB4afWXR3lo49pgb/ACuGNv0+EHDMgA priv=MEcCAQAwBQYDK2VxBDsEObqClbYv+jh0UEY1jPx0ag832HA0qGD2YHHc8XnsIhI1HSt4Fo7+ISCpPABIfDlMhjARJYxi5OM8HA== msg=wjS6P9+a1uqgFDrRAyALJg4fIK/QR5hnbVgqP/1umrz+2mWYHnruv1sXFpTtvAxbw5aa1/FwexAF4FwK1w5lIw== sig=ICT1H+i9byx9JFhyaIpweYDA+1MsXFjKKk8eHiVan+7F5pRoGoV8ITgcEe+FbOQxbzWmTAFih+gApJiBBvfYQt0O9+N7yyb4fZiVQh2N7fH8MYPDQWe/bYYroKF2qmLdTx9A1lCFVg+PuA/kw7fgBAoA e=found 219 iterations", + "pub=MEMwBQYDK2VxAzoAjWsDFLPrw0pk+knAfm+wxa95OPNMbAuMS2HAUXAJ/dtPUkykn3XsY6SMUTDQzfsSTZD4e1f7Hl0A priv=MEcCAQAwBQYDK2VxBDsEOT2Hl84P4X83D8RR3Q30p5zEQAOTdp7N0wBoLBVkFspU+PpSaVXN7/pEIdQIjvjWyixokLEtRBd4JQ== msg=3tSDwknKkRfEVLQIhxXLE2pmm8RhZkQBg/3MlUWqCZm3+rVIwD/B5d4WFzIH5WNM7nPjS6eeAzRnOV6apWGdxw== sig=rkvvqpCv9SKpa1oJqkv1c9B5uZ+5fRcY2TGDOkaA/4341uA374H+fKedtVRIFQzDIrrn2lBoxysAwDkLfPuA8bYyn9wkl3Pbit5l0ryezmC08FjQYvwcSPKEdT7fSaoAWYZM0A6S7772vHl4ElZc1wkA e=found last=16 s=33 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA6IkkrpH0eDbW3ALyDbU98JN1AYg4HiyywM03I1+UwVuXxkdnHuVGfdGNCmvL23ANm0Pcb/OA4LWA priv=MEcCAQAwBQYDK2VxBDsEOagEHY/KFkhx/HeMA//i3eAzfNGQRRnpOfw2IqEMWlZ5/Sd1RRPAtmHvb4pWIiM+JdV1Z/86fgLa6g== msg=oWwtaAe23QLUFlsYiFRz5Y4I9g8WW1FtA8V0KU0gN18Oh3CuZnVKbEajKGFoUyC+1VVm+YrmfpDOIOq/bpOCRQ== sig=MQi28BnFCjQpUV9w/hl8yfdHd9kT/epz5WqktLdiLQNB/WmndXRZpaQZrFNl+oVgi+D/ByS+x+MAJUM/hav5eiPmpl0ErhMgwquiQeowuJzGULZdk2onZ+2GqjNUrrcBqt9X7KKbQhS+UUEx58kfKSMA e=found last=18 s=31 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAdqRkZj/otKxzqfd5kbDSFIGAX82c4ltuD8LlWLwDhzLiPUBmeDFLP1Ykod9JqeYLRPztLsCBu20A priv=MEcCAQAwBQYDK2VxBDsEOSCwA8FJAA2lo3iaCgSXIU6EtWbj321Lp4G4hlngI9lvD5z7egF+S7CMkVHHcNFuhEtMAWuwhksFSg== msg=kfZIV5Pu7BLu+ebHHzz7QK1fLYq2uiOk5n2wV4d9Bz5Zttbqh0zyCa0dGNVkfmf2DiYZtIPasEmhjQy7Ej/J9Q== sig=vmeAVPoQWtOk/rfD0IcfdDRGAujVqEbQCuENhkHGU+htFZxFUHX7LEbNBuG/UTsqCjC665xrHF2AtmS5ZZOOU1kcpkA5oSd65xXIZ4wnLBI6FWqW2jzuIiHwXCnVvicUl4JViDDquiKz4faNw9Mf4wwA e=found last=26 s=40 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAxt5HY9UGwew3+0zJk33xPSR1ybD9+8M6RBCUBEjB0lGj2Yq/eHvGexvDZb84KGI8xsLkCLOGS+OA priv=MEcCAQAwBQYDK2VxBDsEOctq6dTR7f4RPpcdSzYztmkXac4en0nvQiJSA8koMm/adBruuSfH2lyj6J+wYbtc42m/3PmKLEY3oA== msg=n2ae+UHDZWWXR/8+4bV2z0CoFfJxpkOH6eYyK4Ey+tDqlAwGrza3mXmdHtdIPN855hDXAb06izcwpJU5N39pJQ== sig=Szv6xK5C1v4U7XJ6b2FAkKnlsbBVBR6KXL2IuJj6/cWwKgD9wbAwdr7h9IERlfhGVtk7wnRYEK2AfITblN7oEXL5OwofyAdaVA6h3jftkdbaBLqVOcB1E94PWM3P54RdFyGMv8vEmftQL4QmyCYvxSgA e=found last=25 s=30 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAdtPNyDqvphpWorXqJ2eIKSp9vBaw13odzgODodmMuilueW8I2OGCvbWF2VQObSSCMbDja7UtjmkA priv=MEcCAQAwBQYDK2VxBDsEOeqRPGmPxvMnHGqcMt5W/In9KDolV3QzSztjulVZdSyXY2O/iCH4ananB0CFJOK0Sm/CrOQ3hlwrVA== msg=joYMRLff1//2DBbS/dzP51Grzj3Al841P1SU+muwY/zrotD6sFifTSZgrTjiYzZo0nWIIS0jXEsHInfj+PGLPQ== sig=5hMyp9S11OpcI4oLqua08ec7+4UlQRxY1InDBw+1Vh7YZvfXu63PUg+Phv+9Q6YMsJ1ZFfWwsL0AUDMkYxcsLw67JeBe++fn1EIu1WUYjPNg4M7XWrgKa1mak/vVINEk5f8ojDXDvMMmJixb46NCLh0A e=found last=25 s=31 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAg4yzYGyGkfEa8uPPwibaRFRqJpzLkGgMc2Z4W7IQVr+jFD/ocOj1/83dEGtkRXcIsEO7XzSCAJOA priv=MEcCAQAwBQYDK2VxBDsEOXbVRi+023NyM36oWEm5aZZO5yI78XSdDls0taLdNmN5oIS2g8UPVo7/pmhiCbPuTJtqr1g41ODUXA== msg=RTD2C6uOozkPMqgIT9vHv2Xg/POWcenH/vfvsj339wvRYEUIXmEQjfEZ8Hm8CfMPBuVSpcwJVIh857C9C1SOXw== sig=us3MAwci+WI6t2sGjODsc23hJUiQsT/RmO8oQXDu1JFpMU6i6pQ5ELwPShZr8SeMOL9dpFtALLwAoeGYEVtByx2Z4ehsgwlbjQggj6tuqwKrsgWNRJU1GRB+U/S/nzHfbZGuw13EPlzdGDObZdR7fBAA e=found last=21 s=34 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAhuYQPHJ1zfVmv4Uq8Z/GD6n0q4lIQ4mc7WXPtqKRVArTM24czqE3q09VZ7SKHYp6bvXaIfMHf+yA priv=MEcCAQAwBQYDK2VxBDsEOZDDtxMWtwE4+bxA00rx//wLGNHpz3PoATmTTjz7xdXzPWCu0eUwccTvdQMiQLX9eUDeOfLgt1m20w== msg=Wqruv5A+e6JVXrhwllZIBRAllEH1DNj76g/QN/HgzHg048nnU+/CUCG3RJzsdLMKGu1yWgzVKlaWlsdnrALw5Q== sig=vvvv64SDCkbh3BSnPZTm/SnbX3GOljLzzsTA5K0bfplGo7DYNKpPZWGLCTr/s5ApQWzHYXmbBIEAh+9XUqSGLqFf0XFwz+rjFv/qZL3A36L+g4ZDMWKegn0wIEJUQU9K3Uu++Ulsj/rD+7aFz0mwuDkA e=found last=23 s=32 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAGkE6uM8dqjBGkbq9SFsQiMGQ9palJfkPMTRmOamfYp0RcXtv19+fIzhBjOJjClhFrPHlKuVdSDAA priv=MEcCAQAwBQYDK2VxBDsEORLz8uQk6g/oV2NaBn4whJGXqdXsebnhff76ntH0NVbCMCBfWpzRTSG6bpt80+0qe4SF55e8nLXPuA== msg=tp5QFMfyLWT6MYewgzcViKO7ABKIf2SJ8OJ02vdmJ/7sBORe0ASohIIGkUn228D3XhC3l6YjRXFI6/USnaJLJw== sig=P9fg4W7D38VVs6oCDYKwE2pZdGH1UX9ETtx4rwytt6s+VyjBi4DU6UIe0HWx95+vWjHXez3igWcAVvDIndrtnMrCKAAHAGXT6j9Szz/+HO0Pg4CQd3RlzWuOXNQ+YTVdl3DvgLNMcQ/qPAn0osfyBzkA e=found last=24 s=32 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAmm/hNL98IVpLLeG9Ixej5OnaDp4NFQGM5xBYEHzIy9DJcXia1I+73gnkUa75VV33qPe+0ZEt5LiA priv=MEcCAQAwBQYDK2VxBDsEOZZxtMkukFA8FZkUNlCWm6rE8Mm/LwE8NBySys/v0O46rprnuKwkQAJsjZukAtUAdTCruidVKosuUw== msg=qn2Foo/OPnf/15armYepqLg4O8UsaZCHsIIzS9U8J+ZxLrNECY8B8HnjUd26iD+bgobMp1CVj3V9zCjavRSeNg== sig=QhxRZvp+DhsjlTJS7C6w22dpZajrej/wh9RmnekHIpol1Vlgrnsrx/u3nfGEKWujm/lGZnkoZQyA0PTIJIQfIhLm/1F12uIKTdeWfPjkrR/jk4g/cepl4J84Zn5FAruTRfLavmQUORDaCvtjuiXjOA4A e=found last=15 s=30 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAtXtqxWgaRpShYXzoXo+A3djYDFu+hyZUfyl13ydulEfm83fY0MQjQkl8DqPZWnFtcLz/TBfkxcMA priv=MEcCAQAwBQYDK2VxBDsEOfW7Bec9UrllksKwlFylLMCBk9W2zDYDimN4Sp8HE/WSVxRVeZROaLXw4IYls7sxdslInkzRu9dowA== msg=mU69oLJkYrJiN0WB4WvQMgSND0RdC3iLsz93DcZJ+9/51le23ZP37/iWI4mcasJz8Fa+t3kp5XA7rpsv2gswAQ== sig=IGTaXi9paWqtDGpYpdRBFwP16vi0eBjOC4GS1rt8kmXj0ECyM3/Y6Hr+TyzJ+kyBYLZ3Z/k08TyArwbpEerYX9f0eMImPwXnbg6s+WnHw+Ni623kEO09Wc/UB23hyRsB+Z1QPLHrMNKmfX1j3ThijD0A e=found last=25 s=35 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoA4m9VA71e/Kwz10BQPy7tmTvWjfFeJ3hvVmdeltx1V+T9snUGn9XXV0alKd1HdlmOOf38rCeAH2iA priv=MEcCAQAwBQYDK2VxBDsEOT86w7llyLNRNKroJFCXfKS6PDPQ8MVnSGqOGw9sxrkBNemYVCyz+JqRib0RsbU5b5aDJ/KasaOLiQ== msg=/5Tgvatz3Y6ABVaqz9GGxqMjcgQCZw1i7CZ5fywPE2qL+4oXPegK3Q+rOAdrDWHzalKnT03FG3EcyCqQC5siqA== sig=oNjpl8PvZ/QkGvzb4CFqhrknc6UqL8c/Un72CM/0D0mgQj6zL9Dm9jwvkvfnmEYTfLku9biVG40AZvUwLaRg+K4xFhnGZD+S6YlVA/9wHE2cncjG0eiYkJcsSLBQ03PQJhBtZN1668sBIxto2SKsiAAA e=found last=26 s=32 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAWJ7aMjgvigONWzj9iPwZWmxmj0WUjxLowTXbtu4AFIzg2AndbNqThZQBQAxNmcvIdwUSEB5KhVyA priv=MEcCAQAwBQYDK2VxBDsEOZR8Vnczc4t/aG7YGLW0yRiA8QreKZ9FWB+DK5d1e5CIPdSdeHoKEN4+9KL9IBMT/38xSXUGwCaWCg== msg=bnwzIYL4L9PH4BY2D7DiuE1XRJlf8RmRfTiKiS/cpr75E2/E8RaVz7Qw4Qp3aaBb3Fa8+yn+MqSJ90jZaOVQBg== sig=4mbiOaAhk7VQkysQ+vxSVi2kOHjnP1OO7+Dha8O7s/8h2RTVIA7MK4aPg/bVldQO4oUm2f36srwAmj/oELX58iJx2+C1Jny9kdwCyBBBXvyIrIsBAiMKjywnOYfBcLN6oSGKNzUNR+HtN1PnCfoCLAMA e=found last=15 s=32 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAKFw+Jp1/lVnX0V8CXnOs+wTl0hbg7Psi5jrsers5TXZsjX0hAUz2qQHHoWsH7jLxz0Z6N3iciNYA priv=MEcCAQAwBQYDK2VxBDsEOTQj7i9Xx4B1QP/2nCh2sMtUxxytjwbSBvxuFYP9W1lVHp1thtYXk/1mbWoLe9yPqT2ac3AxqX+mHg== msg=aAk0U6XMxB1ENA4VL8traR9uGTtiVzTo6zpLTSqcAUoloUeUerQWSicxNmiHe2N8+yU+3TY/w86SNx0OVtHgrg== sig=QI8frdGaDDrWSP9s5dQmvPJkWKvAD69132bcVK6NR7r0RNtQ7r8fLTc5jCumyzdzfrORICFRF10AbayzEOp1VV5lJ8/Y/slJU250u4gnrlcOEtQ2F/HxxYvUXeDoLi8FpMdoa5CBN54VMeCAJ6wzlBYA e=found last=23 s=31 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAABQoOOUG5zd2dLpTCzzQF6S5anfUzOgPEGsIE8fBag6HMNhM8RlkPa/4WHPP4rEW5O6AVLGSkSyA priv=MEcCAQAwBQYDK2VxBDsEOXu80FzkZK2weCayA44/KTJ1um1HQ+NIuK73XGd3lJFtIJXjmms2RcWxbTpA9FY2ahZ9SlZYE4iZOg== msg=uC0+GwbgZFxCXlOVGEkWysXz/HFbZ2viiSQAuEshbMEogc/zuY2+XA/Gz0WhvTan58cXPoqcZnKPnE3QwhjIgA== sig=c42abL1TmMDykiEuhUHbxmmbKN8tmmfmdxgN2M3HOSK707zXy1x5xtC9tPcoiEmMz2PDJfpb/XIA2Nz1Y5hck4xvJ+1Cl1kMfshC0YaUkTvtPo5GgLQffu9EP2BVmFNxp+LdNPeTeEWeQxdn3Nt35iAA e=found last=16 s=38 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAajrI1Jyca5IDojHFG+i42w897kZ8hr7MnCIoq4R5wDiDIGaPWMHErNhrY97q6V/RtKbcXVyxd0GA priv=MEcCAQAwBQYDK2VxBDsEOUgLIuS0YkJbN6EyUiSVaAhQHYFLm/EvJpPI0JhVzYPzToT32ah2bYg0uZ1PBIPRk6fcCl7dy0Z3jw== msg=8W5eWe7spgpgr7bxzC60cDfrBdkXX++vYhUtFG8nTTjzdDf0rSjr31GaT7rlYumzdyrPqUMvUZ77HeBvyrbVqQ== sig=82RCoR69OIR2I0tsYSdn2IFktBHbpCspMEjJJK+WZoGC+nBj6XVRY0XzwS12iF9y4hlhk975MiGA9EJtAbNKt/SIkRAwBYa0y3oAAMJhP4gfMQVMc/IaHobwgl7hpGlXHbEXuZKshNg1v4VqRrtTGAsA e=found last=18 s=36 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAIIBQcfsPo0jEm6YhpxUiguw1tI7DIJxSmzqaCUkXd3htUIYq+h+MzkgHlNL2UzEzrKKHpPWJRWKA priv=MEcCAQAwBQYDK2VxBDsEOSphCjqH9KIbhDIOZi1vGftasEFkXsD+pTCZjOybp5KspLQ9smV2MmmA+a5jdO/ZbW7PkoB1fCcw1A== msg=SYrmwRG1BBAiZlBjF+jWjb/h5sJFF5q+gZY6EV+U79QIyDP5+jVcf1uRLIbMWCtKUJwEz2ymATc0zduyh7ExjQ== sig=vBMaX42RzXhtdHuH57RHl+y3Gr/StK9o3wcW4VOpkxozGGA/8v0UtS9Ogv8cSRSHXsoZ5Z6uivSAfWwGCPaV5RL0FBQL8885nwUkKzDADLybCKeggCy8Nh9jOo8dy9qZ34RE5qRz+8+lEsRaLt1yyz0A e=found last=26 s=31 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAD3g26G8SomfWErF2UbYFiA1jBI7PoALuMblIgwVyl2nX5THC5qtFaZWIT8ZI6JwEr1FUzYCgI8oA priv=MEcCAQAwBQYDK2VxBDsEOfatUla2PCCtYN9rGwr5IC492VFxjSdFqQhaMg6wS9PuB3zN/+NJPE+NwnEfTh1jkz3KUiS6E3KT5g== msg=HTrwOmgaAisdl/75WDLS0oAB9p0iX+HJu/HLxJZqQn1GthD1v2skl+PFCg2Z19pIrhhrz3CA9lrWvTX+I8tqBQ== sig=zMU0SYJQr93ltpQ38vf/NizTfHFtMLfPAQ8qO2Uk9AhHHO1jlASRlQ7G2pyNOqPXkH66ZXS9hhiA7fbYB4r9Mo504zZJYzbKp5KA5BNVidzy8+Mb7NxHCopznD4uIqv8UG9GKjeeUPBCr3kiEHm0ITwA e=found last=21 s=32 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAr5baI8/+iANSdofiCvYZmbQU7M0yOtjIPKf/GZkqv0LLkSXEjwDfIQ3Z/s0qUTsUZ2R1ujIXbO4A priv=MEcCAQAwBQYDK2VxBDsEOVk5OVZQKorsqjGXEQoJJ1kdjQMlEMWawVp8yqqwYQv9L9l8VQtrO64FKk0bRBYA6yIWi/auOPGLkw== msg=xmSEwpC/UQG1ytHnX+ko2tmPX4hQwjBTT+s2WU5hDME6HhLeBQmcwGHTc+4lg/+XquRCHmjH4alXRZ2gCnqihw== sig=530fJ0yzCsuVUseTf00fuKS6y52LoGEGKY15AfOo0AjG40SkEPaM4wupXSRFqdQtXufgUcvy2bcADG4yBRd6u4FV8QmtrfxIaiHn6shzwoxU7dqFV/LmZ7S95Kk2FWo/x7ITfYnv4+H5r9CNGO9gHCEA e=found 217 iterations", + "pub=MEMwBQYDK2VxAzoAhjsz1GlBB9sgthmMXR0FHPhf69PxDA8Tlth+sgVevINfN1UN0Jwc1DWqA4a9O0B2UzQk65VePNaA priv=MEcCAQAwBQYDK2VxBDsEOXJwTstltDy7fwPUp/fONTLFNi9vkccNx0WUPSO3xDgp/mKbE0CRm+Lhk/Wa5tRcDGk2DyHW6RcV0A== msg=DvmotGB2Rq2BCq0Zecm81UZwwDEAtCToMlCWZjyTMzaKmgBZl+YbArKVWoSdEUStMKVb67tuEMblo1GHNiq4Ng== sig=EADNkiQ/wqh/dLsVrC/Fd45sdXJ9lVMp5mJbnV+wn6AzdKAgZzK+JM6OTx6vrMVWO7+rm6zecp+Aif6aKVz0lLPlAJuicgUwk3O4zSnTDbEqEx2dD2jtm8+CWvlB5nDMp5Tm+x6F4VoNiRGwP2f36zUA e=found last=15 s=29 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAt+k2sSlFzkMzt4/YQH92hCY3WWcnc7rQxyG7HGVFzTkLyMgfHWCLS/Zz5bFD92iYVshPMkxPVAKA priv=MEcCAQAwBQYDK2VxBDsEOQnQHr2nVTlksT7gxNWVfThPlgs4rXjCKhI3XG31uACVq73o8zY9r9cvZU5RWRkImX1dY5cOT5+o9g== msg=ebNJ8O0XPruILIhY8SEYGNTe3mZuYhwoFw3YadhAon5iF6M2vpdaky8dsRCEwc+MfdBbELFqVpw8MQKqwFy//w== sig=V6N4MiKHUXdnaFOAjHGhZDwZqszIYHKUOYtb8eLFwkvQWK0WJlrHIhG+NONEYjeha9Jry/xo1GOAGXUqrzqfGQBrboYOsTcYTTlIVjFf6IU8sNEtBPvoiIynaJPeGv1FnCISRq7a9aQeuiuhBZjYrzUA e=found last=20 s=32 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAVILcBaSDWon86wqvVFQiyeC0fF/CExdklcIV2nL/aRzkPBTHhLpgsD41KgFeu3A+avnSwRs4IWyA priv=MEcCAQAwBQYDK2VxBDsEOe3Ba2YJffX6y6MjV3CxgfjjZWAVP7FUUodw87j+G7c9LKKLHeuTOjBO1kk/eyp9SfCpIY+8MxIWiA== msg=KwJKEayYCXy9oEkHtDK58DmZ0wzlbx+5wzBdLYX+lFcBUB8F1zAHHxZOIu/gd5k971aOl+cAzRiP5sJ2w6KKGw== sig=NEWgYgMY0P/zPp9KV2CcGpD4P109Qvr7yW+yAq6/8Ciz3LzGaw2ybqc4GXKvYz2aymcwF0imCtmALxMnh2XbUV+1gD8u0aOnEUdUKmqP0ZobalZQGvTmavr1GsBHa6Z5WEFmjitzUGoBZvipldmMMSIA e=found last=21 s=35 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAulAa7/mFzUkjMqwKicvOZ5HF6iYI5Tbi3R2oceBYhvieX9uO/BFPixIB7uEnoct3YCnb7cxErIKA priv=MEcCAQAwBQYDK2VxBDsEOZGidl4/00yWhG7CAjp7iIws9kr7T7D/NvOZOKtGYvyoh7EbEaUlTlc2IRBUT1peFLpCl1vOkZRuXA== msg=KbM67DnjAaxQ9/SOILzGPpaSCKH83pCsdCtE2MTvOGPlk69uByucDpMLQIKhPEBnJCkfFgDiksIQPCT/yTHjcQ== sig=kKhG/we4N7ZHBepliSV6WjNuXL19ueqUptuHoSA5GfUnWjKLkTOwKTcIEpKSjh0iEpZO4izuZA6AsUqPXJzSvc9uEtFvK9jiMVk5BhrCGpiz1cP56O8OOi+mBgqTRsmhn/vygeOEt1Fka2Lo5XQ2BAEA e=found last=18 s=33 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAwodHrjBMXoztmniYb4g1yJ3+dVRsMILaN9L25VOmiBDMoP4VJLG/s48y65g15zeIlnvnI/FzdhWA priv=MEcCAQAwBQYDK2VxBDsEOUUhMmhUUqPGThfIaP4Y8uQr++pbJG0nH+wJQp2fRMYYvzZol3kPbMP96UqkUKHtZNg91CSMZRQ+Og== msg=FpwEpGkLTuCK4qXZBv35LLJFXnCTwjIye2vIINtxhqyBQyl9Cs1gV/Q8HgoXhNCplX4hBRrEXv9k9xGm1tWaLw== sig=jO2NpCgRN52/kp3YvajSYkSEPlRHDOhPl0F6eKAcYmYeyIjFwRo32tR4v9V79E3OznPW0UtExRuAk9kPKu6prStM6+ftapO+Y5dJWmXLrewtps8RPzAoiz9DiiSKlUVHfTYf+Gj4tF4iykDcoX3w/y4A e=found last=27 s=32 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAGVF+pM4kdFF5ZBqkKp9O/c2De+kMDH4y8wv973VRRc1cFKpIYeIXQt0LCM46KoTD8i6xcJ6IseUA priv=MEcCAQAwBQYDK2VxBDsEOVNavFia97xqag7r1ibi/y3drFmP+mTF5CaQo3OILdGOcW1aR5+z0O37JBfefpBG0KafDnacds43Bw== msg=7gQZcOPFK6kLicp6dru5mvY/w+JdGtULYciti3Ob9n04kEbtiH0KdEH4/XtulavkkveSn90BWBPRIypdKOmg6A== sig=4rx9J3zw32S1DHMhba508i/bJXIWNcc+5JBP3zDU+Ya9N5qxAhDE1aKbTx9yZNsPWPNGALJTKggATBGObM+ZDgU9Sp5dc0h15OcIccyAaQhOSil8s3JuijinBPa5/s3Muw7NWozUnziocVtD8k5YCzAA e=found last=17 s=31 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAUq5IRTWOTcdVekcdVrHn0dDvfDbutOCTYeXqd6lR8EJGT9QXuoTFLDcF5okRg22nrEqJqGXC4PwA priv=MEcCAQAwBQYDK2VxBDsEOZdA1/F2wdRtF/aCeMduLYuazOFpTBwmdzeUT63p9EItMDWEHwfOaX1kPwmP59LxyAFaltuU6vO5RQ== msg=0s2CayaR/IyLU+xFvk4ZZVH0yPGXpTasDHOU9oQV6+oEEZHyhjnY4u1MZU36xNNJ9t+pgtajBlnlMvqlVHR6NQ== sig=rglY9PssRPcNsvaft34HLOSzG3vQFI4ABAVZ/mXJ61f4jqd12PMAlh7cgzUBtOcjpcfR6+Rv7wUAw7OUzy5NKCmx11P2nd0Qbxx+wr6XX2eHrqU0H6xVrqPJyRPOKtLN9QuA/8XK0PxVxOB9hojWbiUA e=found last=15 s=28 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoApLOx16z61YS0x/OtwR4JoDm3pml4bKXp7/uK4AYNc0ArfUA1xa5iDYJmZHRTPQyhiDtCeuVVyZ6A priv=MEcCAQAwBQYDK2VxBDsEOazl5jYlESX14C36rjCva2bKGSrP1N4YB99MiEmKdO2V/y10fwUyi1jCXrYkHO+QTF0Ac0WrsT6SRA== msg=wGw9KMeMXIHawe4anWYv5p5uTKCejx23rqnCfZrGvQxCju34BWKAm2duC84X/wpx/LtppgNaiToaHUcfSmyTuA== sig=ck0vfxQ0R8snLbSyIXtKJoL1mP5OEmUPcQUkroomUYzxw/fFxrKB6Rlf0QWmfNZEp/baiObKmI6AbJJhbgahilzZSq/RY+T5hFrfYdPnXl53Q00zmN0Nr/UfcxfOEJNJav42Sq3D9oDnazjxekAUyx4A e=found last=20 s=34 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAqJ/g4QNf8P3w0Xg87hBUhSJ69MkmHwgJk3jxYtiLAJhlf4HBc5KMuPNZsob8r6tCTrKPA/Wnl0+A priv=MEcCAQAwBQYDK2VxBDsEOX6RvhjveBxw/5fzLtgWUo7gF7gmXmIa7ew1zsZ7zRs6oAntQY1NYDuY5D7oAwcKxM9Y7ARux5b2UQ== msg=r8C4uxbRpikuVUjK2YaIcEbnNrBQxDHEUebgc4NofhgAZ+VKcNG8ocPDAtDAyi6AjDVbugqJlpZB30O4u6zwXw== sig=1G4HMz+RjI+LCTkifCy6nCLb8sPTw+FCaPSpqDB3FSIkUPe7mo/HuZD8MiG7oJRN4dTWaqlDIjqAtkxevR9C5ZIW/LYRe989pQU1ds7F4PAkY+WHsoUnEKWgbEGIGGdyX9ty6A9sJA4g+eG9Rsa4XQgA e=found last=17 s=32 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAUKVuy8V5JA7Ql0Fo93HxSNQQKUtnl1nnqdTHgUe6CTAKIborLwEhN7cXMrePVZrppeh08TIxphoA priv=MEcCAQAwBQYDK2VxBDsEOSeYWs+QnMlxXSI/escK0iM6NHx63JifDAD3DLGZhhkzwpvsbHbcXUUttZ1Pmd3VTMBqu7IchOFS4A== msg=pcK9TiWpzcpJwn2zeI2BAshKqw0TCHVn+MHXcw9zpan5K2E4Mr6W+NhXBr/bM6o8jAdukcR0z2bb2ARCk56AxA== sig=pYAEeLaWD07knIk8kGMWshKj5NiSMl00vhJ/5uSlSMTttEAkmDNdSiPNplHMtJ/joce4ynSIaXwAUgyuRVcrpE5o0o4q+4/RTi6AvYdQkbFZMpamR7jSIv90SQWdbs43PuXoIbhRBTuTrWzd8sdEYiIA e=found last=27 s=35 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAc4J4meeIGm5teqolxTotQ/kjvknKGoyVXDd/lR3pH5cH6B7A+Z45Xzw0usClnCZyFtQSdIDDlU8A priv=MEcCAQAwBQYDK2VxBDsEOSR0HJou5hpooWIn0t60/GKasMx9tFSf3RoyQtFn6LQxYvc0JWcCuNuwJPVwXuo9wnki4eqPFCA8Zw== msg=PPrrsQFbPEufUKCsSv76/ExFTYF/eTAjTaXgcuGGCjlY90F4beU8aW97zV4yq/sz5YGfPnjm0v82DJC15Z8xxQ== sig=JSfWUc4B8n8Kvj6AWroWd8ZeKPrwwIpPmRoib+/vZWESKDpdulK8vW9nkHT6qoF81hW72M/uBZwAn1Vm28iGmcdJb0WuJJy+5vP02W7DmFuDoSOmslIrLBU5w7mxXj9cUn0Cf9xCBn7+NYq79g1MejcA e=found last=15 s=29 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAG4gTAhHS5uod05LCNcOwGqX1ikolIqWu4HnTj7EZokWFVWwB0pkAbd/+ZcD4yr3Q2HZOClf8hY+A priv=MEcCAQAwBQYDK2VxBDsEOewdHwYLiN7Q3wE49wOBNJRsytK6Mq7thlcfxi2tPwXqK6TRSr4dnthd2Uhvm9lAcdNwSpQqhR6b2g== msg=ZZG9umyOIDj1roTGkwoVKhi9moWkxam5SyeQTXUgTMvhCpaz+l403Rd/PG9r6m62MlOmp1T/L909cVMJO26vvg== sig=9y3EZmWkWpzPFYWLRR1sc3Fs7741BiPTNipttD1ikDnnlp/gneQO5USqbADGeSyG5TW9KwFNZbqAP7lVPMQMCB8oofr1goGzEt+LwiTv9b0TUDogmSHwYVJs9a538WC6dKn7fBq9PeTUCyW4opHPUS4A e=found last=16 s=31 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA9pnRBuFAnWamWPPdypRhvvQcc4sNxmr9c3n/2r6EuNcUINJo+UX8o1zPb8zLZlH1TJzB8BIUFP2A priv=MEcCAQAwBQYDK2VxBDsEOZcit8eS7vh1WQHWFaBdQ2UtUQDU57yTkifc3qXNDokwNg3vOQqPXUagktvORknBCJKc60ASrFGwHA== msg=Qg47VfmaDzqlIxoZ+2usEqBXVbNLXIR3awnRaPmpWTTwEJmiqiyid++Y6NmOIY8VtQOC0ALd2CVbxjQ0uUUDmg== sig=SsI+Sdzu2EQtRMejz2JuAASg0PlINtac5GTcJYHLuQKQBm31TX6q7HrOZKVddmPZQE+sVFKoni2ApYWdNJYkWYqMnw3Fu1f+Ya2osKSStT9xIejr29TH9UVxHZ0Pjm0iV3vQieWMs60Tx3YH64CeXwgA e=found last=19 s=30 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA21ixR8pqT0CSNjXO1WxKLAlkLss3XoswS6lBRcoELZItvYOXYlmwG8Marli8EwdlUj1y/e4wDeQA priv=MEcCAQAwBQYDK2VxBDsEOe1zi+dV1my5ujZ3vRuRI273SLcjBHGDzJLpISzBed4RDW1PN4Pdrv2jk1GKl99NMk3c0wLFKlGTzA== msg=PP5xAyZMvXnLMTTYNPKefo3pE9l6R2IHzscBa4H9yK11RJZW/JySvbjOa1fT0jEBtGcXp7NCmVvUpwtKY3FTzA== sig=/2a58hmWCSIOXjP7unHLE2iA13hQ5u+0DwOQYjE+qMUJEUeef6IgryijubVQTiQ4thBTgRdi51MADUPAW4nrtxt6NvkXvlmjkKtfjDLmj4Pwvq2aX/ztN3WKHO/ZZF1Px0/tiMd+I8OvPKTkDxZKKg0A e=found last=19 s=33 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAGeH/+sLVVjTr4wiwWZWFmuJjr1O+gKSnCqk2Sz0zwqXSpvM7HXLoZKbTmESdonoeePDRe4dc5ooA priv=MEcCAQAwBQYDK2VxBDsEOWnGFfKZNPI3dLhkSyy6jpwrddRjzyVW0nPQjeY/heJJz4Ig6nvn+bHF9YFgW5FE/pwvhAN2HbGm9g== msg=7cFi/gQH7xWnu1Ap7BmPwu7MpW1myu/0Iw42xW7wiZLNnEl6ETTSys3gcpY19q8AyPbS50CAzRkILfOwcBk8ZA== sig=QzcaCEFYM2mNU1MkM2GWoApAMpUodzQRXMLAWv7/+7AflOX9yJnGMgPYim1i6c+nFPH+XUwSyPoAfLcmpQzOfTYGBB3YfgLMsRX/o7zuOg044MnUihVAhXknhKXatsFjSDAKiIwFeeVVZqi9pR7NZisA e=found last=21 s=32 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAJ1x4GRPK0s3VF/Kpd/q0ho2nyX/1QHhW6z6hDEEjbvGt9v4uZWsu61BB7UOIfJC7lveyuGJljVgA priv=MEcCAQAwBQYDK2VxBDsEOaJCHWdCPodkapjEEC3vpBxpskX4JCq0HbIEG3PIEquZIwHrk6dA+IUCvnhqfa+bwoBsS1yVr7rutQ== msg=lnarK/d90dQw4EdvsiXRRecB5/3O12SvSw7oAzjbIXvN8G9SuYNPG+siz5wy5yc6zUMd4ivSErPxEi53viGrug== sig=d58T2Xai2mj53ysF2sveZEzjmga04JRBHoM52Uxoe9xE43IjDk67Bv40WtX+D9vhZepWB8giw2QA26ApoZBeCBgiZThkxnCa4RQxI/JkSbh1/Ka9W6GNJ860dZS+FfZsJhI3zL6K5RwCa+OPAl6flwwA e=found 121 iterations", + "pub=MEMwBQYDK2VxAzoA0TvA49qAAuGMYbGVDcm7zV7bObh3KmzmqKu+pnDTxqsZHELLDPbHWZ2Mt3NiQkzo8snN0VoAC6+A priv=MEcCAQAwBQYDK2VxBDsEOYocE4KALBjx383x8it677YwNG6ULwPoZsy9Dyb2V5c6a9ecLKGaR2/P3ikzQ1BJSTWCjxuBYChdcA== msg=C6uGSc4my5sc1b5KD0yzf8pvAugs9TX1zAn/UoaGBtQ+PbTERPZo0gUkFaJpzi7pAylYWEPbypATSCu9VzZ1bA== sig=5R8zBpHcMTrjxKPKQHfmOMX/0pLI6ikVtPNDAnnMN95Arep+AUrOvTD/AdhCqFbYQ2HfSLyj1HyA1/uCkOuxLIWB6Q/PEknObXSSGos/OW2VOPZwzS2wnsDl9Df6Pe1CQoywOdW2bWeyKjtyeOffjSYA e=found last=26 s=33 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAuENBggn7f3u0IyjKLoWBgNcyW9k7/SF0HbdimUKQJExJV7F7HQOyCCNVsPdVEQBBbQzznB4bPeaA priv=MEcCAQAwBQYDK2VxBDsEOc9xVr0rIxIyOpon/KwfGdAOMlshcr41rNZjphlVaCSB1iIrHQ4wrjsZ+h9REaSWpJ5s9Ksf9WKL0w== msg=kDQGWVXNvahPn3Rd3V+C1yTosn7TS/jCq4mcsXCXwcqLOye95FXLYWh6+8koMFrpy3QC+t6btoy+2zm41JToOw== sig=8fd5Vuk+z3hDe6oyuPcxMks0Q9ylutXLVkHXkYdKo3oroNCGGddLfJfUguKb+6Iz+CuZxWzifAEAmOr48bu/YgB+hnL4pGkUZugyo/CyVSkmpX5Eb7O2dyOEXqucftefutrCHP4C1+je45N6DqZtkyAA e=found last=24 s=32 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAMl450MCopDKQsEXd4b1U88znZzWc6UjNYBJJ5sDLQsufLY/gYhNEpIlWgpIahwaTEdH0fjinWTQA priv=MEcCAQAwBQYDK2VxBDsEOUEYV/45lZUrFGk+hjnbeiDPQL/83rXcjLtKBRuAqpRIVLTt/uzXDPAzUstBwGGFlHttEAc078L8qw== msg=8KLaRHr+9luLuGq0K3sgfn1+79E66+HrHsnPu/B6nUpIu8JKXLwR1AgiKIrYrKSqZc1cuhQJZMI9N9SW+V/6TA== sig=eL4YPCVzDIUM0fx+N7MqDZaPY7OZN2lU04NZAdmpRQDX9WkXokuwBrEuFvTOwuJM/Ydh+rQmH7qAvqjO29CZI1R7Zv4ltEfviKlNISiAaO0qZdeMADQWKYPX/B/QDAC852JbIIEtEAemRrQwkduXCwYA e=found last=22 s=33 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA573btSSbaybdztah73t5LrfjEORPNbgsOu0/ZeO0HsqlXHYlQruWoAtoa8/N/x9xQsBX1HjzxncA priv=MEcCAQAwBQYDK2VxBDsEOS6E7Vfi734RWXf6Xz4Yrhmm/Nr8o+eh7G+rRCm7xQt8Ecd2B8XDItDRnbEo7bUB6qiT9vM88yRJdA== msg=tS7X22+OgLy/G4J3F8mqBg8OBvna5Vg1aN3uUKEFvm0VhSbD4rlJCkgIXy+ONaQdyq/4oUCtVhD5LpS2tf6ndA== sig=t0pS+98EaOXQCwwl7NAVnD939GkxireAZhXYvlUsGzw4G3ZbPxBemAtqaXZX6XcXlKBYvjeicnuADfWm4lA2tL7SjSABfb8VfMhu3ieBnSRG4gp/gHz+t7ksgxpe4yQrGqB2alfRX9n56gKZDc6rsi0A e=found 120 iterations", + "pub=MEMwBQYDK2VxAzoAQ9NflEtCllQdc+A3xSh+iHvi2zLM2ycSMWU4PZCjKtZ0fB0JYchkkXENpEh+Kl30bk8w7HrP1l6A priv=MEcCAQAwBQYDK2VxBDsEOQ2mSo7cDmgMZCuzYFBwEAxjQvQM4cl6COo7EU5Ld7BSANEKaC/7A5pzoPMJ/tO+mrwEnX24y+xPbQ== msg=Zd+GFlhel1ymFG+iUZgV4mjTZXLVFdAaiz68MtJ446zDHJfwScEAG2Av28+xh4Ox/IEaZnx4XnZ4NJ8Yzl1TBQ== sig=AZ93IuKRI/qr/XyL92HT2HwwD7GTrx8RTXTgwYFytcPIMlYByvNm9ZM029b6pepOwF33DFkM2o4AyikPzOMv/hFOAo9XT+YBHzk33BRMioS4sytzCYdZG1H8bDKukAxR39XwCM3Bx1b98FwiBqF2HjMA e=found last=25 s=36 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAf62n94Rpz+QXA9y0N2Wm0DyS5JkCCLZtfXzTDHa9NunS4tTIZQaPSuQ6V0uYSsw9zMyyzjHhUUOA priv=MEcCAQAwBQYDK2VxBDsEOZ+KhNkw8/7696bx1pnp1rVCPqdiarUVIYfSZVhq1fUlYNL414RCuhdUbt32l9NaexDjjOYXx2Wixg== msg=IJ64czHpTUo5Y5hJJ8KUF6EXQGOUqHt2pipaSd1YGtI1K+dy2Il8RLFx96lrEMQl+ioIVQvvxTB/RZ75a9lYXw== sig=Vxb9Q4IzAMHA0scCG8hRZLTOAPWQyOkN1/lY3M7YDbGcS0W2EG/UlR86PfNrW9bNzGD+y1w6layAy1YOrZ6sfyZoofn/x+U0jwYMpbw/LMGV0XuXshCu9hd3Np+8RGpR5l/bGcP8pxhG6z3UE6RJhwQA e=found last=19 s=34 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoA3yITBoCG/wtDJDNLiRvNPpeKWGjracmeKrwtb1SXOLgk2AibF2JzazjX5QAlg3++a2AArbMHpSAA priv=MEcCAQAwBQYDK2VxBDsEOdR64c1XQ47KP7IcIDkjprQQeRKIWzj5gfYDcoExw+aIQmxJk5NcPkh2rUsfgbDNq67/ICeKQqNU3w== msg=oirK/UXccmACP1hCe3tIm1mob4uweNwscS4PywZ950UlX/29JRXwoTAyqpROO/FeiHqe1l06Lk/glW64B/1lag== sig=/3CYxD6WVJaugYZvP0iP+Fgsst7xZHY+hgHbPRxn5AeezC5uc10GhVwo+TouGDOsdMYFQHjBiD6ApOWaJOjERWffLg6FCZyEe8fOgNbnumYp1aMO46/NJei1HqNIZufg3W2ym+T4SLcdn7dxAbVf8QcA e=found last=25 s=36 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAYwhB5Vg9eU+kcqNkXCnN+MWurbNsp6mSRzOyoQMOIwMskEJJruUhCzbnBmIXRkl3sYkiNVEcxv8A priv=MEcCAQAwBQYDK2VxBDsEOT50tAUTvflML4JnKvHBWG3PAX/y/Ld9N0pBzZuYRZtEFXP/Pp3m9zSPacXxo/gwutny9p9DHDUZSA== msg=qhwh7bSWZp3HFZODTNUR+ptNSR4mySYiYEByw+pln1NM3fAtr1Zqgpyv/JNg6vX+Ze0xZiqy4WO6pTWIZMOaLw== sig=kwcT35Tnum7Px20ZPIq5Rj9A+d8oEVK5CDc0yuPDVxubKV1tF89LN4Ffa8SVXe14kPBKsur+apSAsa1XBDJdhxLAQm43E4bnCWKgXZfFGdRVY53EQ6KxpJEpr1geG4CNWDm54jaX4rbnRHXcmbRpnRMA e=found last=27 s=33 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAii4Pnugi6fdrvCg0v0Tr4O4cpvsejrpxrUgbFA9C0qFfIzReArEho4Lj5PBP2RGta4aQ59wfRx+A priv=MEcCAQAwBQYDK2VxBDsEOf7xCFwbgaPBG99Ie6Hv+7c+c+nDLPhtudSgTB2XH1p18TncC+06ng3gQx/prc4Sc8xqdxOlivXk7A== msg=hIJRPz26zBKGOUNyGqaCXvsxFUwvCE+LjvXBV8kVh1qgW2Zf/32VwhNNodFXqnTsZ8GPFp405ur/XJjUq/jN9g== sig=MDVK4VfP8YTzTsCsjvu3Hb4gLT2dP5usQPyEOdwRzvbAZop+lBUKJWtiUt4Dgt4MMwTkkHpA+L8APjjb0AofdMSS8xmYq4EmW4s1/4XLNd08ytvItvExG1FGoG4g4Cyh5nmavzTyeuZDFaRapFqFFSQA e=found last=23 s=32 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAclJpk2GIlQgu/cTr5Ydt7oboJFRDZTXtRI1+Z3ziPTl9N8Krsp991a0u9CVaRUa9KlGwVEaimWAA priv=MEcCAQAwBQYDK2VxBDsEOaXj2iO0tgr+r0NGAQjVeM9D4UtO0opzTDrB07phdrG/iOf5ewU3f2UIAf0KvcJubdiy9CL/Ko2v8A== msg=V9hz/ZC763KgvL6g+HJLawEcpjVrpe1W+WU4j+7kDBF1yOCkwm+q8VVmZg6uVjdN/1YPcAlT1V/wpiENEZY+5A== sig=d0h+mhTrsksYkwg3wGLx/9tMwEkIRVcVU1D+GuIQXV22q4kJcBbR1MqejEx5aNhX0x0SZAcFNuYAp1GOgA83EtWVOsdXGKNlqBgC2dS6q91aFWkx6BWfliMgtwHFNaQ2LAw2IAtpgQFPqFILBKIWyAMA e=found last=18 s=35 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAUUN8YLlaMRvSh5No5lhzZEWWXenj5s/xYahQ36Wi7h6WA9fftEh1Dzqg/Ahp3dJ4JK1jK0U1RKgA priv=MEcCAQAwBQYDK2VxBDsEOdH8ajmonAv3c/ttJN+dzOsCOyOkegEv+nxyMj4Smi0M+GMg70OR8xYRxD6tAa/2a+zDAQYEWu9fNg== msg=kPcDcqX5HKxYMr4Ib0IwDY7YmfqLLxScWe8uVelCEFrBbkTGcU0MMR+GLJ/KX+UjV12cw0piV0jeVpywuRef7g== sig=GYAjudVq7b3amLCblFF547qphAT1+79DHgAGA5odg1RYxOOsKgjN7Mpk8vmPnzEnOGrPaBSWebEAdLjNbPmUYhfUxFwqrdF8mWFaNyRy9etONkkZ34NKOd4/VJbqJ7KgWXkcdHNG5Xe+8E+M73ATmTAA e=found last=20 s=33 in subShifted_NP", + "pub=MEMwBQYDK2VxAzoAHDFVC+LSl0eBbc2R8U7XERNn2IghiFvVuowduSSHsASZBXBiVMujpsSBI5CkYLMw8wA5e8Of+ioA priv=MEcCAQAwBQYDK2VxBDsEOX4x/IJAwLMkZbs0gRwKy9hzZYqpslcA5RGCooEHXFZPY1Ct7cvmARbH+W0+o4Rk1MY/ffT4QK3Tog== msg=kmM34GXThQA/skDKDXetReU28jnAFvSW6zTXJiXR1VL0D+Gllog6KjUjej8/Xtdh1tbq7h6jOIa87rVRImRH1w== sig=dLYgl8cicjOpNPvbDxxa5N+WQmrQ+WGFVudWH15jVNzdYei2NWrfpRCf0+8H3FUtcXQh02fAUCEAXir8V8Q1oHlK32saXFdLs0vSFKLCY9na0luVEPuMdNW0NVlJPJxHV75jKwyWO58rI6JHL6Gx1AcA e=found last=23 s=35 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAGRn/O5NyCFjzKog9IPRh7G7mD5tejb4XOnBnseg1W7H5hcT8AyIAV2U9z8ekJfu9kdyrmlGf4KUA priv=MEcCAQAwBQYDK2VxBDsEOfrAdWFSKVghyArZjuG/sJnR+oYyO9kzxYu3pbqQQqCRHe37XRRCosY23HAsL9JvQMW11xAy4h9Enw== msg=/JrIENe1/CNVlfDMWBaUjCv9WT/6A8op8syjB/AtezRno6I4HqlagZAnIHnUCoz3cQgfOm5lIrp3B/5gCOi1Dw== sig=Rtr8jfKYNfFY3h9DeusHycfJKpIw0Ob4OYy3zSk2u0dNTv6kK0X7j6H+nvps5SNsbxkdcmb5JaKAPvqCwlDHtzSkGlNLMqCbrA3zn7ap/sVJz0KriZgN2LkZmSjNQLzIY6xHXodlyta2JE2iGuCbgy0A e=found last=21 s=33 in addShifted_NP", + "pub=MEMwBQYDK2VxAzoAk6TbBisa2S0/rC6zKE3mKFC4If2yJZ3P9V/LNPhh8R1ch5Ugn13v8vDjqotXSmxwBHDIGtu1wRiA priv=MEcCAQAwBQYDK2VxBDsEOZV5u73XH2owfeYVPY9p9usxM2HKPMT3fRIaxq+WB601FGy/z6Q4ByRnrNahAbjt5C02xqH0uWF0yA== msg=vkkXHvYZOYAo8psXZDjY/uTXYpe7RiuhhaLo8VGPhHmcg0akrJfUAyLyuGVWpgeR7dkiN58qFL6Arw8CLyEU8A== sig=h4UndzbUyfve20M8qaX+e0vCwEVXaNeDxLRe1izwA3Zn6kWYJkaXWnihxwifXg9JP0PFWGzZOjaAF6MSnkVUM8m2AuXt4iRgTTi3D9y3yjHfDwwPzW4iuQj521plOBgLWQ73AY7K+ARFY0WEyLo3fQcA e=found last=20 s=36 in subShifted_NP", + }; + + for (int i = 0; i != testCases.length; i++) + { + String test = testCases[i]; + String[] parts = test.split(" ", 5); + if (!parts[0].startsWith("pub=") || !parts[1].startsWith("priv=") || !parts[2].startsWith("msg=") || !parts[3].startsWith("sig=") || !parts[4].startsWith("e=")) + { + fail("invalid test case format; expected five parts (pub=, priv=, msg=, sig=, e=), but got " + test); + } + + byte[] x509PubBytes = Base64.decode(parts[0].substring("pub=".length())); + byte[] x509PrivBytes = Base64.decode(parts[1].substring("priv=".length())); + byte[] msg = Base64.decode(parts[2].substring("msg=".length())); + byte[] sig = Base64.decode(parts[3].substring("sig=".length())); + String error = parts[4].substring("e=".length()); + + byte[] pubBytes = Arrays.copyOfRange(x509PubBytes, 12, x509PubBytes.length); + byte[] privBytes = Arrays.copyOfRange(x509PrivBytes, 16, x509PrivBytes.length); + + Ed448PublicKeyParameters pub = new Ed448PublicKeyParameters(pubBytes); + Ed448PrivateKeyParameters priv = new Ed448PrivateKeyParameters(privBytes); + Ed448PublicKeyParameters pubDerived = priv.generatePublicKey(); + + if (!Arrays.areEqual(pubDerived.getEncoded(), pub.getEncoded())) + { + fail("different derived public keys; expected=" + Hex.toHexString(pub.getEncoded()) + " derived=" + Hex.toHexString(pubDerived.getEncoded())); + } + + Signer signer = new Ed448Signer(new byte[0]); + signer.init(true, priv); + signer.update(msg, 0, msg.length); + byte[] sigDerived = signer.generateSignature(); + + if (!Arrays.areEqual(sigDerived, sig)) + { + fail("different signatures of message; expected=" + Hex.toHexString(sig) + " actual=" + Hex.toHexString(sigDerived)); + } + + signer.init(false, pub); + signer.update(msg, 0, msg.length); + boolean shouldVerify = signer.verifySignature(sig); + + isTrue("signature verification failed for test vector: " + error, shouldVerify); + } + } } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/ElephantTest.java b/core/src/test/java/org/bouncycastle/crypto/test/ElephantTest.java index 16d8d4a132..f9a4c388d0 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/ElephantTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/ElephantTest.java @@ -106,7 +106,7 @@ private void testVectors(ElephantEngine.ElephantParameters pbp, String filename) map.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("Elephant AEAD pass"); + // System.out.println("Elephant AEAD pass"); } private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, int blocksize) @@ -380,7 +380,7 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, { fail(aeadBlockCipher.getAlgorithmName() + ": Splitting input of plaintext should output the same ciphertext"); } - System.out.println(aeadBlockCipher.getAlgorithmName() + " test Exceptions pass"); + // System.out.println(aeadBlockCipher.getAlgorithmName() + " test Exceptions pass"); } private void testParameters(ElephantEngine isap, int keySize, int ivSize, int macSize) @@ -397,7 +397,7 @@ private void testParameters(ElephantEngine isap, int keySize, int ivSize, int ma { fail(isap.getAlgorithmName() + ": mac bytes of " + isap.getAlgorithmName() + " is not correct"); } - System.out.println(isap.getAlgorithmName() + " test Parameters pass"); + // System.out.println(isap.getAlgorithmName() + " test Parameters pass"); } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/GCMSIVTest.java b/core/src/test/java/org/bouncycastle/crypto/test/GCMSIVTest.java index e5d15acdfe..0c02a960fd 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/GCMSIVTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/GCMSIVTest.java @@ -14,6 +14,9 @@ public class GCMSIVTest extends SimpleTest { + @SuppressWarnings("InlineTrivialConstant") + private static final String EMPTY = ""; + public String getName() { return "GCM-SIV"; @@ -106,7 +109,6 @@ void testSIVCipher(final GCMSIVBlockCipher pCipher, */ static class AESGCMSIV128Test1 { - private static final String EMPTY = ""; private static final String KEY_1 = "01000000000000000000000000000000"; private static final String NONCE_1 = "030000000000000000000000"; private static final String DATA_8 = "0100000000000000"; @@ -206,7 +208,6 @@ void testTheCipher(final GCMSIVTest pTest) */ static class AESGCMSIV128Test3 { - private static final String EMPTY = ""; private static final String KEY_1 = "e66021d5eb8e4f4066d4adb9c33560e4"; private static final String KEY_2 = "36864200e0eaf5284d884a0e77d31646"; private static final String KEY_3 = "aedb64a6c590bc84d1a5e269e4b47801"; @@ -271,7 +272,6 @@ void testTheCipher(final GCMSIVTest pTest) */ static class AESGCMSIV256Test1 { - private static final String EMPTY = ""; private static final String KEY_1 = "01000000000000000000000000000000" + "00000000000000000000000000000000"; private static final String NONCE_1 = "030000000000000000000000"; private static final String DATA_8 = "0100000000000000"; @@ -371,7 +371,6 @@ void testTheCipher(final GCMSIVTest pTest) */ static class AESGCMSIV256Test3 { - private static final String EMPTY = ""; private static final String KEY_1 = "e66021d5eb8e4f4066d4adb9c33560e4" + "f46e44bb3da0015c94f7088736864200"; private static final String KEY_2 = "bae8e37fc83441b16034566b7a806c46" + "bb91c3c5aedb64a6c590bc84d1a5e269"; private static final String KEY_3 = "6545fc880c94a95198874296d5cc1fd1" + "61320b6920ce07787f86743b275d1ab3"; @@ -436,7 +435,6 @@ void testTheCipher(final GCMSIVTest pTest) */ static class AESGCMSIV256Test4 { - private static final String EMPTY = ""; private static final String KEY_1 = "00000000000000000000000000000000" + "00000000000000000000000000000000"; private static final String NONCE_1 = "000000000000000000000000"; private static final String DATA_1 = "00000000000000000000000000000000" + "4db923dc793ee6497c76dcc03a98e108"; diff --git a/core/src/test/java/org/bouncycastle/crypto/test/GCMTest.java b/core/src/test/java/org/bouncycastle/crypto/test/GCMTest.java index f13456c9fa..f1037c25a1 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/GCMTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/GCMTest.java @@ -7,6 +7,7 @@ import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.modes.GCMBlockCipher; +import org.bouncycastle.crypto.modes.GCMModeCipher; import org.bouncycastle.crypto.modes.gcm.BasicGCMMultiplier; import org.bouncycastle.crypto.modes.gcm.GCMMultiplier; import org.bouncycastle.crypto.modes.gcm.Tables4kGCMMultiplier; @@ -14,6 +15,8 @@ import org.bouncycastle.crypto.modes.gcm.Tables8kGCMMultiplier; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; import org.bouncycastle.util.Times; import org.bouncycastle.util.encoders.Hex; @@ -23,273 +26,273 @@ * Test vectors from "The Galois/Counter Mode of Operation (GCM)", McGrew/Viega, Appendix B */ public class GCMTest - extends SimpleTest + extends SimpleTest { - private static final String[][] TEST_VECTORS = new String[][] { - { - "Test Case 1", - "00000000000000000000000000000000", - "", - "", - "000000000000000000000000", - "", - "58e2fccefa7e3061367f1d57a4e7455a", - }, - { - "Test Case 2", - "00000000000000000000000000000000", - "00000000000000000000000000000000", - "", - "000000000000000000000000", - "0388dace60b6a392f328c2b971b2fe78", - "ab6e47d42cec13bdf53a67b21257bddf", - }, - { - "Test Case 3", - "feffe9928665731c6d6a8f9467308308", - "d9313225f88406e5a55909c5aff5269a" - + "86a7a9531534f7da2e4c303d8a318a72" - + "1c3c0c95956809532fcf0e2449a6b525" - + "b16aedf5aa0de657ba637b391aafd255", - "", - "cafebabefacedbaddecaf888", - "42831ec2217774244b7221b784d0d49c" - + "e3aa212f2c02a4e035c17e2329aca12e" - + "21d514b25466931c7d8f6a5aac84aa05" - + "1ba30b396a0aac973d58e091473f5985", - "4d5c2af327cd64a62cf35abd2ba6fab4", - }, - { - "Test Case 4", - "feffe9928665731c6d6a8f9467308308", - "d9313225f88406e5a55909c5aff5269a" - + "86a7a9531534f7da2e4c303d8a318a72" - + "1c3c0c95956809532fcf0e2449a6b525" - + "b16aedf5aa0de657ba637b39", - "feedfacedeadbeeffeedfacedeadbeef" - + "abaddad2", - "cafebabefacedbaddecaf888", - "42831ec2217774244b7221b784d0d49c" - + "e3aa212f2c02a4e035c17e2329aca12e" - + "21d514b25466931c7d8f6a5aac84aa05" - + "1ba30b396a0aac973d58e091", - "5bc94fbc3221a5db94fae95ae7121a47", - }, - { - "Test Case 5", - "feffe9928665731c6d6a8f9467308308", - "d9313225f88406e5a55909c5aff5269a" - + "86a7a9531534f7da2e4c303d8a318a72" - + "1c3c0c95956809532fcf0e2449a6b525" - + "b16aedf5aa0de657ba637b39", - "feedfacedeadbeeffeedfacedeadbeef" - + "abaddad2", - "cafebabefacedbad", - "61353b4c2806934a777ff51fa22a4755" - + "699b2a714fcdc6f83766e5f97b6c7423" - + "73806900e49f24b22b097544d4896b42" - + "4989b5e1ebac0f07c23f4598", - "3612d2e79e3b0785561be14aaca2fccb", - }, - { - "Test Case 6", - "feffe9928665731c6d6a8f9467308308", - "d9313225f88406e5a55909c5aff5269a" - + "86a7a9531534f7da2e4c303d8a318a72" - + "1c3c0c95956809532fcf0e2449a6b525" - + "b16aedf5aa0de657ba637b39", - "feedfacedeadbeeffeedfacedeadbeef" - + "abaddad2", - "9313225df88406e555909c5aff5269aa" - + "6a7a9538534f7da1e4c303d2a318a728" - + "c3c0c95156809539fcf0e2429a6b5254" - + "16aedbf5a0de6a57a637b39b", - "8ce24998625615b603a033aca13fb894" - + "be9112a5c3a211a8ba262a3cca7e2ca7" - + "01e4a9a4fba43c90ccdcb281d48c7c6f" - + "d62875d2aca417034c34aee5", - "619cc5aefffe0bfa462af43c1699d050", - }, - { - "Test Case 7", - "00000000000000000000000000000000" - + "0000000000000000", - "", - "", - "000000000000000000000000", - "", - "cd33b28ac773f74ba00ed1f312572435", - }, - { - "Test Case 8", - "00000000000000000000000000000000" - + "0000000000000000", - "00000000000000000000000000000000", - "", - "000000000000000000000000", - "98e7247c07f0fe411c267e4384b0f600", - "2ff58d80033927ab8ef4d4587514f0fb", - }, - { - "Test Case 9", - "feffe9928665731c6d6a8f9467308308" - + "feffe9928665731c", - "d9313225f88406e5a55909c5aff5269a" - + "86a7a9531534f7da2e4c303d8a318a72" - + "1c3c0c95956809532fcf0e2449a6b525" - + "b16aedf5aa0de657ba637b391aafd255", - "", - "cafebabefacedbaddecaf888", - "3980ca0b3c00e841eb06fac4872a2757" - + "859e1ceaa6efd984628593b40ca1e19c" - + "7d773d00c144c525ac619d18c84a3f47" - + "18e2448b2fe324d9ccda2710acade256", - "9924a7c8587336bfb118024db8674a14", - }, - { - "Test Case 10", - "feffe9928665731c6d6a8f9467308308" - + "feffe9928665731c", - "d9313225f88406e5a55909c5aff5269a" - + "86a7a9531534f7da2e4c303d8a318a72" - + "1c3c0c95956809532fcf0e2449a6b525" - + "b16aedf5aa0de657ba637b39", - "feedfacedeadbeeffeedfacedeadbeef" - + "abaddad2", - "cafebabefacedbaddecaf888", - "3980ca0b3c00e841eb06fac4872a2757" - + "859e1ceaa6efd984628593b40ca1e19c" - + "7d773d00c144c525ac619d18c84a3f47" - + "18e2448b2fe324d9ccda2710", - "2519498e80f1478f37ba55bd6d27618c", - }, - { - "Test Case 11", - "feffe9928665731c6d6a8f9467308308" - + "feffe9928665731c", - "d9313225f88406e5a55909c5aff5269a" - + "86a7a9531534f7da2e4c303d8a318a72" - + "1c3c0c95956809532fcf0e2449a6b525" - + "b16aedf5aa0de657ba637b39", - "feedfacedeadbeeffeedfacedeadbeef" - + "abaddad2", - "cafebabefacedbad", - "0f10f599ae14a154ed24b36e25324db8" - + "c566632ef2bbb34f8347280fc4507057" - + "fddc29df9a471f75c66541d4d4dad1c9" - + "e93a19a58e8b473fa0f062f7", - "65dcc57fcf623a24094fcca40d3533f8", - }, - { - "Test Case 12", - "feffe9928665731c6d6a8f9467308308" - + "feffe9928665731c", - "d9313225f88406e5a55909c5aff5269a" - + "86a7a9531534f7da2e4c303d8a318a72" - + "1c3c0c95956809532fcf0e2449a6b525" - + "b16aedf5aa0de657ba637b39", - "feedfacedeadbeeffeedfacedeadbeef" - + "abaddad2", - "9313225df88406e555909c5aff5269aa" - + "6a7a9538534f7da1e4c303d2a318a728" - + "c3c0c95156809539fcf0e2429a6b5254" - + "16aedbf5a0de6a57a637b39b", - "d27e88681ce3243c4830165a8fdcf9ff" - + "1de9a1d8e6b447ef6ef7b79828666e45" - + "81e79012af34ddd9e2f037589b292db3" - + "e67c036745fa22e7e9b7373b", - "dcf566ff291c25bbb8568fc3d376a6d9", - }, - { - "Test Case 13", - "00000000000000000000000000000000" - + "00000000000000000000000000000000", - "", - "", - "000000000000000000000000", - "", - "530f8afbc74536b9a963b4f1c4cb738b", - }, - { - "Test Case 14", - "00000000000000000000000000000000" - + "00000000000000000000000000000000", - "00000000000000000000000000000000", - "", - "000000000000000000000000", - "cea7403d4d606b6e074ec5d3baf39d18", - "d0d1c8a799996bf0265b98b5d48ab919", - }, - { - "Test Case 15", - "feffe9928665731c6d6a8f9467308308" - + "feffe9928665731c6d6a8f9467308308", - "d9313225f88406e5a55909c5aff5269a" - + "86a7a9531534f7da2e4c303d8a318a72" - + "1c3c0c95956809532fcf0e2449a6b525" - + "b16aedf5aa0de657ba637b391aafd255", - "", - "cafebabefacedbaddecaf888", - "522dc1f099567d07f47f37a32a84427d" - + "643a8cdcbfe5c0c97598a2bd2555d1aa" - + "8cb08e48590dbb3da7b08b1056828838" - + "c5f61e6393ba7a0abcc9f662898015ad", - "b094dac5d93471bdec1a502270e3cc6c", - }, - { - "Test Case 16", - "feffe9928665731c6d6a8f9467308308" - + "feffe9928665731c6d6a8f9467308308", - "d9313225f88406e5a55909c5aff5269a" - + "86a7a9531534f7da2e4c303d8a318a72" - + "1c3c0c95956809532fcf0e2449a6b525" - + "b16aedf5aa0de657ba637b39", - "feedfacedeadbeeffeedfacedeadbeef" - + "abaddad2", - "cafebabefacedbaddecaf888", - "522dc1f099567d07f47f37a32a84427d" - + "643a8cdcbfe5c0c97598a2bd2555d1aa" - + "8cb08e48590dbb3da7b08b1056828838" - + "c5f61e6393ba7a0abcc9f662", - "76fc6ece0f4e1768cddf8853bb2d551b", - }, - { - "Test Case 17", - "feffe9928665731c6d6a8f9467308308" - + "feffe9928665731c6d6a8f9467308308", - "d9313225f88406e5a55909c5aff5269a" - + "86a7a9531534f7da2e4c303d8a318a72" - + "1c3c0c95956809532fcf0e2449a6b525" - + "b16aedf5aa0de657ba637b39", - "feedfacedeadbeeffeedfacedeadbeef" - + "abaddad2", - "cafebabefacedbad", - "c3762df1ca787d32ae47c13bf19844cb" - + "af1ae14d0b976afac52ff7d79bba9de0" - + "feb582d33934a4f0954cc2363bc73f78" - + "62ac430e64abe499f47c9b1f", - "3a337dbf46a792c45e454913fe2ea8f2", - }, - { - "Test Case 18", - "feffe9928665731c6d6a8f9467308308" - + "feffe9928665731c6d6a8f9467308308", - "d9313225f88406e5a55909c5aff5269a" - + "86a7a9531534f7da2e4c303d8a318a72" - + "1c3c0c95956809532fcf0e2449a6b525" - + "b16aedf5aa0de657ba637b39", - "feedfacedeadbeeffeedfacedeadbeef" - + "abaddad2", - "9313225df88406e555909c5aff5269aa" - + "6a7a9538534f7da1e4c303d2a318a728" - + "c3c0c95156809539fcf0e2429a6b5254" - + "16aedbf5a0de6a57a637b39b", - "5a8def2f0c9e53f1f75d7853659e2a20" - + "eeb2b22aafde6419a058ab4f6f746bf4" - + "0fc0c3b780f244452da3ebf1c5d82cde" - + "a2418997200ef82e44ae7e3f", - "a44a8266ee1c8eb0c8b5d4cf5ae9f19a", - }, + private static final String[][] TEST_VECTORS = new String[][]{ + { + "Test Case 1", + "00000000000000000000000000000000", + "", + "", + "000000000000000000000000", + "", + "58e2fccefa7e3061367f1d57a4e7455a", + }, + { + "Test Case 2", + "00000000000000000000000000000000", + "00000000000000000000000000000000", + "", + "000000000000000000000000", + "0388dace60b6a392f328c2b971b2fe78", + "ab6e47d42cec13bdf53a67b21257bddf", + }, + { + "Test Case 3", + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + + "86a7a9531534f7da2e4c303d8a318a72" + + "1c3c0c95956809532fcf0e2449a6b525" + + "b16aedf5aa0de657ba637b391aafd255", + "", + "cafebabefacedbaddecaf888", + "42831ec2217774244b7221b784d0d49c" + + "e3aa212f2c02a4e035c17e2329aca12e" + + "21d514b25466931c7d8f6a5aac84aa05" + + "1ba30b396a0aac973d58e091473f5985", + "4d5c2af327cd64a62cf35abd2ba6fab4", + }, + { + "Test Case 4", + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + + "86a7a9531534f7da2e4c303d8a318a72" + + "1c3c0c95956809532fcf0e2449a6b525" + + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + + "abaddad2", + "cafebabefacedbaddecaf888", + "42831ec2217774244b7221b784d0d49c" + + "e3aa212f2c02a4e035c17e2329aca12e" + + "21d514b25466931c7d8f6a5aac84aa05" + + "1ba30b396a0aac973d58e091", + "5bc94fbc3221a5db94fae95ae7121a47", + }, + { + "Test Case 5", + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + + "86a7a9531534f7da2e4c303d8a318a72" + + "1c3c0c95956809532fcf0e2449a6b525" + + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + + "abaddad2", + "cafebabefacedbad", + "61353b4c2806934a777ff51fa22a4755" + + "699b2a714fcdc6f83766e5f97b6c7423" + + "73806900e49f24b22b097544d4896b42" + + "4989b5e1ebac0f07c23f4598", + "3612d2e79e3b0785561be14aaca2fccb", + }, + { + "Test Case 6", + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + + "86a7a9531534f7da2e4c303d8a318a72" + + "1c3c0c95956809532fcf0e2449a6b525" + + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + + "abaddad2", + "9313225df88406e555909c5aff5269aa" + + "6a7a9538534f7da1e4c303d2a318a728" + + "c3c0c95156809539fcf0e2429a6b5254" + + "16aedbf5a0de6a57a637b39b", + "8ce24998625615b603a033aca13fb894" + + "be9112a5c3a211a8ba262a3cca7e2ca7" + + "01e4a9a4fba43c90ccdcb281d48c7c6f" + + "d62875d2aca417034c34aee5", + "619cc5aefffe0bfa462af43c1699d050", + }, + { + "Test Case 7", + "00000000000000000000000000000000" + + "0000000000000000", + "", + "", + "000000000000000000000000", + "", + "cd33b28ac773f74ba00ed1f312572435", + }, + { + "Test Case 8", + "00000000000000000000000000000000" + + "0000000000000000", + "00000000000000000000000000000000", + "", + "000000000000000000000000", + "98e7247c07f0fe411c267e4384b0f600", + "2ff58d80033927ab8ef4d4587514f0fb", + }, + { + "Test Case 9", + "feffe9928665731c6d6a8f9467308308" + + "feffe9928665731c", + "d9313225f88406e5a55909c5aff5269a" + + "86a7a9531534f7da2e4c303d8a318a72" + + "1c3c0c95956809532fcf0e2449a6b525" + + "b16aedf5aa0de657ba637b391aafd255", + "", + "cafebabefacedbaddecaf888", + "3980ca0b3c00e841eb06fac4872a2757" + + "859e1ceaa6efd984628593b40ca1e19c" + + "7d773d00c144c525ac619d18c84a3f47" + + "18e2448b2fe324d9ccda2710acade256", + "9924a7c8587336bfb118024db8674a14", + }, + { + "Test Case 10", + "feffe9928665731c6d6a8f9467308308" + + "feffe9928665731c", + "d9313225f88406e5a55909c5aff5269a" + + "86a7a9531534f7da2e4c303d8a318a72" + + "1c3c0c95956809532fcf0e2449a6b525" + + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + + "abaddad2", + "cafebabefacedbaddecaf888", + "3980ca0b3c00e841eb06fac4872a2757" + + "859e1ceaa6efd984628593b40ca1e19c" + + "7d773d00c144c525ac619d18c84a3f47" + + "18e2448b2fe324d9ccda2710", + "2519498e80f1478f37ba55bd6d27618c", + }, + { + "Test Case 11", + "feffe9928665731c6d6a8f9467308308" + + "feffe9928665731c", + "d9313225f88406e5a55909c5aff5269a" + + "86a7a9531534f7da2e4c303d8a318a72" + + "1c3c0c95956809532fcf0e2449a6b525" + + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + + "abaddad2", + "cafebabefacedbad", + "0f10f599ae14a154ed24b36e25324db8" + + "c566632ef2bbb34f8347280fc4507057" + + "fddc29df9a471f75c66541d4d4dad1c9" + + "e93a19a58e8b473fa0f062f7", + "65dcc57fcf623a24094fcca40d3533f8", + }, + { + "Test Case 12", + "feffe9928665731c6d6a8f9467308308" + + "feffe9928665731c", + "d9313225f88406e5a55909c5aff5269a" + + "86a7a9531534f7da2e4c303d8a318a72" + + "1c3c0c95956809532fcf0e2449a6b525" + + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + + "abaddad2", + "9313225df88406e555909c5aff5269aa" + + "6a7a9538534f7da1e4c303d2a318a728" + + "c3c0c95156809539fcf0e2429a6b5254" + + "16aedbf5a0de6a57a637b39b", + "d27e88681ce3243c4830165a8fdcf9ff" + + "1de9a1d8e6b447ef6ef7b79828666e45" + + "81e79012af34ddd9e2f037589b292db3" + + "e67c036745fa22e7e9b7373b", + "dcf566ff291c25bbb8568fc3d376a6d9", + }, + { + "Test Case 13", + "00000000000000000000000000000000" + + "00000000000000000000000000000000", + "", + "", + "000000000000000000000000", + "", + "530f8afbc74536b9a963b4f1c4cb738b", + }, + { + "Test Case 14", + "00000000000000000000000000000000" + + "00000000000000000000000000000000", + "00000000000000000000000000000000", + "", + "000000000000000000000000", + "cea7403d4d606b6e074ec5d3baf39d18", + "d0d1c8a799996bf0265b98b5d48ab919", + }, + { + "Test Case 15", + "feffe9928665731c6d6a8f9467308308" + + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + + "86a7a9531534f7da2e4c303d8a318a72" + + "1c3c0c95956809532fcf0e2449a6b525" + + "b16aedf5aa0de657ba637b391aafd255", + "", + "cafebabefacedbaddecaf888", + "522dc1f099567d07f47f37a32a84427d" + + "643a8cdcbfe5c0c97598a2bd2555d1aa" + + "8cb08e48590dbb3da7b08b1056828838" + + "c5f61e6393ba7a0abcc9f662898015ad", + "b094dac5d93471bdec1a502270e3cc6c", + }, + { + "Test Case 16", + "feffe9928665731c6d6a8f9467308308" + + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + + "86a7a9531534f7da2e4c303d8a318a72" + + "1c3c0c95956809532fcf0e2449a6b525" + + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + + "abaddad2", + "cafebabefacedbaddecaf888", + "522dc1f099567d07f47f37a32a84427d" + + "643a8cdcbfe5c0c97598a2bd2555d1aa" + + "8cb08e48590dbb3da7b08b1056828838" + + "c5f61e6393ba7a0abcc9f662", + "76fc6ece0f4e1768cddf8853bb2d551b", + }, + { + "Test Case 17", + "feffe9928665731c6d6a8f9467308308" + + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + + "86a7a9531534f7da2e4c303d8a318a72" + + "1c3c0c95956809532fcf0e2449a6b525" + + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + + "abaddad2", + "cafebabefacedbad", + "c3762df1ca787d32ae47c13bf19844cb" + + "af1ae14d0b976afac52ff7d79bba9de0" + + "feb582d33934a4f0954cc2363bc73f78" + + "62ac430e64abe499f47c9b1f", + "3a337dbf46a792c45e454913fe2ea8f2", + }, + { + "Test Case 18", + "feffe9928665731c6d6a8f9467308308" + + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + + "86a7a9531534f7da2e4c303d8a318a72" + + "1c3c0c95956809532fcf0e2449a6b525" + + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + + "abaddad2", + "9313225df88406e555909c5aff5269aa" + + "6a7a9538534f7da1e4c303d2a318a728" + + "c3c0c95156809539fcf0e2429a6b5254" + + "16aedbf5a0de6a57a637b39b", + "5a8def2f0c9e53f1f75d7853659e2a20" + + "eeb2b22aafde6419a058ab4f6f746bf4" + + "0fc0c3b780f244452da3ebf1c5d82cde" + + "a2418997200ef82e44ae7e3f", + "a44a8266ee1c8eb0c8b5d4cf5ae9f19a", + }, }; public String getName() @@ -304,14 +307,69 @@ public void performTest() throws Exception runTestCase(TEST_VECTORS[i]); } + randomTests(); outputSizeTests(); testExceptions(); + testResetBehavior(); } + + private void testResetBehavior() throws Exception + { + GCMBlockCipher gcm = new GCMBlockCipher(createAESEngine()); + SecureRandom rnd = new SecureRandom(); + + int[] ivLens = new int[]{10,12,16}; + for (int i = 0; i != ivLens.length; i++) + { + int ivLen = ivLens[i]; + int[] kss = new int[]{16, 24, 32}; + for (int j = 0; j != kss.length; j++) + { + int ks = kss[j]; + byte[] key = new byte[ks]; + byte[] iv = new byte[ivLen]; + + rnd.nextBytes(key); + rnd.nextBytes(iv); + gcm.init(true, new ParametersWithIV(new KeyParameter(key), iv)); + + byte[] msg = new byte[1024]; + rnd.nextBytes(msg); + + byte[] ct = new byte[gcm.getOutputSize(msg.length)]; + + int l = gcm.processBytes(msg, 0, msg.length, ct, 0); + gcm.doFinal(ct, l); + + // + // Set up decrypt and do it before and after a reset. + // + gcm.init(false, new ParametersWithIV(new KeyParameter(key), iv)); + + byte[] outPreReset = new byte[msg.length]; + l = gcm.processBytes(ct, 0, ct.length, outPreReset, 0); + gcm.doFinal(outPreReset, l); + + gcm.reset(); + byte[] outPostReset = new byte[msg.length]; + l = gcm.processBytes(ct, 0, ct.length, outPostReset, 0); + gcm.doFinal(outPostReset, l); + + isTrue("before / after reset decryptions not the same", Arrays.areEqual(outPreReset, outPostReset)); + isTrue("decryption not same as message", Arrays.areEqual(msg, outPostReset)); + + } + + } + + } + + protected BlockCipher createAESEngine() { - return new AESEngine(); + return AESEngine.newInstance(); } private void testExceptions() throws InvalidCipherTextException @@ -323,8 +381,7 @@ private void testExceptions() throws InvalidCipherTextException gcm = new GCMBlockCipher(new DESEngine()); fail("incorrect block size not picked up"); - } - catch (IllegalArgumentException e) + } catch (IllegalArgumentException e) { // expected } @@ -334,8 +391,7 @@ private void testExceptions() throws InvalidCipherTextException gcm.init(false, new KeyParameter(new byte[16])); fail("illegal argument not picked up"); - } - catch (IllegalArgumentException e) + } catch (IllegalArgumentException e) { // expected } @@ -345,20 +401,19 @@ private void testExceptions() throws InvalidCipherTextException byte[] P = Strings.toByteArray("Hello world!"); byte[] buf = new byte[100]; - GCMBlockCipher c = new GCMBlockCipher(createAESEngine()); + GCMModeCipher c = GCMBlockCipher.newInstance(AESEngine.newInstance()); AEADParameters aeadParameters = new AEADParameters(new KeyParameter(new byte[16]), 128, new byte[16]); c.init(true, aeadParameters); c.processBytes(P, 0, P.length, buf, 0); c.doFinal(buf, 0); - + try { c.doFinal(buf, 0); fail("no exception on reuse"); - } - catch (IllegalStateException e) + } catch (IllegalStateException e) { isTrue("wrong message", e.getMessage().equals("GCM cipher cannot be reused for encryption")); } @@ -367,15 +422,14 @@ private void testExceptions() throws InvalidCipherTextException { c.init(true, aeadParameters); fail("no exception on reuse"); - } - catch (IllegalArgumentException e) + } catch (IllegalArgumentException e) { isTrue("wrong message", e.getMessage().equals("cannot reuse nonce for GCM encryption")); } } private void runTestCase(String[] testVector) - throws InvalidCipherTextException + throws InvalidCipherTextException { for (int macLength = 12; macLength <= 16; ++macLength) { @@ -384,7 +438,7 @@ private void runTestCase(String[] testVector) } private void runTestCase(String[] testVector, int macLength) - throws InvalidCipherTextException + throws InvalidCipherTextException { int pos = 0; String testName = testVector[pos++]; @@ -409,16 +463,16 @@ private void runTestCase(String[] testVector, int macLength) } private void runTestCase( - GCMMultiplier encM, - GCMMultiplier decM, - String testName, - byte[] K, - byte[] IV, - byte[] A, - byte[] P, - byte[] C, - byte[] T) - throws InvalidCipherTextException + GCMMultiplier encM, + GCMMultiplier decM, + String testName, + byte[] K, + byte[] IV, + byte[] A, + byte[] P, + byte[] C, + byte[] T) + throws InvalidCipherTextException { byte[] fa = new byte[A.length / 2]; byte[] la = new byte[A.length - (A.length / 2)]; @@ -431,21 +485,21 @@ private void runTestCase( } private void runTestCase( - GCMMultiplier encM, - GCMMultiplier decM, - String testName, - byte[] K, - byte[] IV, - byte[] A, - byte[] SA, - byte[] P, - byte[] C, - byte[] T) - throws InvalidCipherTextException + GCMMultiplier encM, + GCMMultiplier decM, + String testName, + byte[] K, + byte[] IV, + byte[] A, + byte[] SA, + byte[] P, + byte[] C, + byte[] T) + throws InvalidCipherTextException { AEADParameters parameters = new AEADParameters(new KeyParameter(K), T.length * 8, IV, A); - GCMBlockCipher encCipher = initCipher(encM, true, parameters); - GCMBlockCipher decCipher = initCipher(decM, false, parameters); + GCMModeCipher encCipher = initCipher(encM, true, parameters); + GCMModeCipher decCipher = initCipher(decM, false, parameters); checkTestCase(encCipher, decCipher, testName, SA, P, C, T); encCipher = initCipher(encM, true, parameters); checkTestCase(encCipher, decCipher, testName + " (reused)", SA, P, C, T); @@ -457,29 +511,28 @@ private void runTestCase( { encCipher.init(true, keyReuseParams); fail("no exception"); - } - catch (IllegalArgumentException e) + } catch (IllegalArgumentException e) { isTrue("wrong message", "cannot reuse nonce for GCM encryption".equals(e.getMessage())); } } - private GCMBlockCipher initCipher(GCMMultiplier m, boolean forEncryption, AEADParameters parameters) + private GCMModeCipher initCipher(GCMMultiplier m, boolean forEncryption, AEADParameters parameters) { - GCMBlockCipher c = new GCMBlockCipher(createAESEngine(), m); + GCMModeCipher c = GCMBlockCipher.newInstance(AESEngine.newInstance(), m); c.init(forEncryption, parameters); return c; } private void checkTestCase( - GCMBlockCipher encCipher, - GCMBlockCipher decCipher, - String testName, - byte[] SA, - byte[] P, - byte[] C, - byte[] T) - throws InvalidCipherTextException + GCMModeCipher encCipher, + GCMModeCipher decCipher, + String testName, + byte[] SA, + byte[] P, + byte[] C, + byte[] T) + throws InvalidCipherTextException { byte[] enc = new byte[encCipher.getOutputSize(P.length)]; if (SA != null) @@ -536,7 +589,7 @@ private void checkTestCase( } private void randomTests() - throws InvalidCipherTextException + throws InvalidCipherTextException { SecureRandom srng = new SecureRandom(); srng.setSeed(Times.nanoTime()); @@ -548,7 +601,7 @@ private void randomTests() } private void randomTests(SecureRandom srng, GCMMultiplier m) - throws InvalidCipherTextException + throws InvalidCipherTextException { for (int i = 0; i < 10; ++i) { @@ -557,7 +610,7 @@ private void randomTests(SecureRandom srng, GCMMultiplier m) } private void randomTest(SecureRandom srng, GCMMultiplier m) - throws InvalidCipherTextException + throws InvalidCipherTextException { int kLength = 16 + 8 * (Math.abs(srng.nextInt()) % 3); byte[] K = new byte[kLength]; @@ -580,7 +633,7 @@ private void randomTest(SecureRandom srng, GCMMultiplier m) srng.nextBytes(IV); AEADParameters parameters = new AEADParameters(new KeyParameter(K), 16 * 8, IV, A); - GCMBlockCipher cipher = initCipher(m, true, parameters); + GCMModeCipher cipher = initCipher(m, true, parameters); byte[] C = new byte[cipher.getOutputSize(P.length)]; int predicted = cipher.getUpdateOutputSize(P.length); @@ -669,7 +722,7 @@ private void outputSizeTests() byte[] IV = new byte[16]; AEADParameters parameters = new AEADParameters(new KeyParameter(K), 16 * 8, IV, A); - GCMBlockCipher cipher = initCipher(null, true, parameters); + GCMModeCipher cipher = initCipher(null, true, parameters); if (cipher.getUpdateOutputSize(0) != 0) { @@ -704,7 +757,7 @@ private static int nextInt(SecureRandom rand, int n) { if ((n & -n) == n) // i.e., n is a power of 2 { - return (int)((n * (long)(rand.nextInt() >>> 1)) >> 31); + return (int) ((n * (long) (rand.nextInt() >>> 1)) >> 31); } int bits, value; diff --git a/core/src/test/java/org/bouncycastle/crypto/test/GMacTest.java b/core/src/test/java/org/bouncycastle/crypto/test/GMacTest.java index 1a10a8a090..29a96c09f2 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/GMacTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/GMacTest.java @@ -7,6 +7,7 @@ import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -104,13 +105,13 @@ public void performTest() { TestCase testCase = TEST_VECTORS[i]; - Mac mac = new GMac(new GCMBlockCipher(new AESEngine()), testCase.getTag().length * 8); + Mac mac = new GMac(GCMBlockCipher.newInstance(AESEngine.newInstance()), testCase.getTag().length * 8); CipherParameters key = new KeyParameter(testCase.getKey()); mac.init(new ParametersWithIV(key, testCase.getIv())); testSingleByte(mac, testCase); - mac = new GMac(new GCMBlockCipher(new AESEngine()), testCase.getTag().length * 8); + mac = new GMac(GCMBlockCipher.newInstance(AESEngine.newInstance()), testCase.getTag().length * 8); mac.init(new ParametersWithIV(key, testCase.getIv())); testMultibyte(mac, testCase); } @@ -125,13 +126,13 @@ private void testInvalidMacSize(int size) { try { - GMac mac = new GMac(new GCMBlockCipher(new AESEngine()), size); + GMac mac = new GMac(GCMBlockCipher.newInstance(AESEngine.newInstance()), size); mac.init(new ParametersWithIV(null, new byte[16])); fail("Expected failure for illegal mac size " + size); } catch (IllegalArgumentException e) { - if (!e.getMessage().startsWith("Invalid value for MAC size")) + if (!Strings.toLowerCase(e.getMessage()).startsWith("invalid value for mac size")) { fail("Illegal mac size failed with unexpected message"); } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/GOST3410Test.java b/core/src/test/java/org/bouncycastle/crypto/test/GOST3410Test.java index 63afd4dff8..cb25e1fc66 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/GOST3410Test.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/GOST3410Test.java @@ -7,7 +7,6 @@ import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; @@ -27,6 +26,7 @@ import org.bouncycastle.crypto.util.PrivateKeyInfoFactory; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; diff --git a/core/src/test/java/org/bouncycastle/crypto/test/GSKKDFTest.java b/core/src/test/java/org/bouncycastle/crypto/test/GSKKDFTest.java index 30264ff1dd..f22b45b78f 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/GSKKDFTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/GSKKDFTest.java @@ -18,7 +18,7 @@ public String getName() public void performTest() throws Exception { - GSKKFDGenerator gen = new GSKKFDGenerator(new SHA256Digest()); + GSKKFDGenerator gen = new GSKKFDGenerator(SHA256Digest.newInstance()); byte[] key = new byte[16]; @@ -30,7 +30,7 @@ public void performTest() gen.generateBytes(key, 0, key.length); areEqual(Hex.decode("d5934f681ad1e860981eb1792af68e20"), key); - gen = new GSKKFDGenerator(new SHA256Digest()); + gen = new GSKKFDGenerator( SHA256Digest.newInstance()); gen.init(new GSKKDFParameters(Hex.decode("0102030405060708090a"), 2, Hex.decode("27252622"))); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/Grain128Test.java b/core/src/test/java/org/bouncycastle/crypto/test/Grain128Test.java index 9b648b183f..64ede1a738 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/Grain128Test.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/Grain128Test.java @@ -109,4 +109,8 @@ private void mismatch(String name, String expected, byte[] found) fail("mismatch on " + name, expected, new String(Hex.encode(found))); } + public static void main(String[] args) + { + runTest(new Grain128Test()); + } } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/HKDFGeneratorTest.java b/core/src/test/java/org/bouncycastle/crypto/test/HKDFGeneratorTest.java index 951351740a..f4524ec2bf 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/HKDFGeneratorTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/HKDFGeneratorTest.java @@ -5,6 +5,7 @@ import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.generators.HKDFBytesGenerator; import org.bouncycastle.crypto.params.HKDFParameters; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -33,7 +34,7 @@ public void performTest() { // === A.1. Test Case 1 - Basic test case with SHA-256 === - Digest hash = new SHA256Digest(); + Digest hash = SHA256Digest.newInstance(); byte[] ikm = Hex .decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"); byte[] salt = Hex.decode("000102030405060708090a0b0c"); @@ -56,7 +57,7 @@ public void performTest() // === A.2. Test Case 2 - Test with SHA-256 and longer inputs/outputs // === { - Digest hash = new SHA256Digest(); + Digest hash = SHA256Digest.newInstance(); byte[] ikm = Hex.decode("000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f" @@ -99,7 +100,7 @@ public void performTest() // setting info to null generates an empty byte array as info // structure - Digest hash = new SHA256Digest(); + Digest hash = SHA256Digest.newInstance(); byte[] ikm = Hex .decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"); byte[] salt = new byte[0]; @@ -262,32 +263,92 @@ public void performTest() // (salt defaults to HashLen zero octets) // this test is identical to test 7 in all ways bar the IKM value + { + Digest hash = new SHA1Digest(); + byte[] ikm = Hex + .decode("2adccada18779e7c2077ad2eb19d3f3e731385dd"); + byte[] info = new byte[0]; + int l = 255 * hash.getDigestSize(); + byte[] okm = new byte[l]; - Digest hash = new SHA1Digest(); - byte[] ikm = Hex - .decode("2adccada18779e7c2077ad2eb19d3f3e731385dd"); - byte[] info = new byte[0]; - int l = 255 * hash.getDigestSize(); - byte[] okm = new byte[l]; + HKDFParameters params = HKDFParameters.skipExtractParameters(ikm, info); - HKDFParameters params = HKDFParameters.skipExtractParameters(ikm, info); + HKDFBytesGenerator hkdf = new HKDFBytesGenerator(hash); + hkdf.init(params); + hkdf.generateBytes(okm, 0, l); - HKDFBytesGenerator hkdf = new HKDFBytesGenerator(hash); - hkdf.init(params); - hkdf.generateBytes(okm, 0, l); + int zeros = 0; + for (int i = 0; i < hash.getDigestSize(); i++) + { + if (okm[i] == 0) + { + zeros++; + } + } - int zeros = 0; - for (int i = 0; i < hash.getDigestSize(); i++) - { - if (okm[i] == 0) + if (zeros == hash.getDigestSize()) { - zeros++; + fail("HKDF failed generator test " + 102); } } - if (zeros == hash.getDigestSize()) { - fail("HKDF failed generator test " + 102); + // CMS_CEK_HKDF_SHA256 B.1 + // IKM = c702e7d0a9e064b09ba55245fb733cf3 + // + // The AES-128-CGM AlgorithmIdentifier: + // algorithm=2.16.840.1.101.3.4.1.6 + // parameters=GCMParameters: + // aes-nonce=0x5c79058ba2f43447639d29e2 + // aes-ICVlen is ommited; it indicates the DEFAULT of 12 + // + // DER-encoded AlgorithmIdentifier: + // 301b0609608648016503040106300e040c5c79058ba2f43447639d29e2 + // + // OKM = 2124ffb29fac4e0fbbc7d5d87492bff3 + Digest hash = new SHA256Digest(); + byte[] ikm = Hex.decode("c702e7d0a9e064b09ba55245fb733cf3"); + byte[] salt = Strings.toByteArray("The Cryptographic Message Syntax"); + byte[] info = Hex.decode("301b0609608648016503040106300e040c5c79058ba2f43447639d29e2"); + byte[] okm = Hex.decode("2124ffb29fac4e0fbbc7d5d87492bff3"); + byte[] genOkm = new byte[okm.length]; + + HKDFParameters params = new HKDFParameters(ikm, salt, info); + + HKDFBytesGenerator hkdf = new HKDFBytesGenerator(hash); + hkdf.init(params); + hkdf.generateBytes(genOkm, 0, genOkm.length); + + compareOKM(8, genOkm, okm); + } + + { + // CMS_CEK_HKDF_SHA256 B.1 + // + // IKM = c702e7d0a9e064b09ba55245fb733cf3 + // + // The AES-128-CBC AlgorithmIdentifier: + // algorithm=2.16.840.1.101.3.4.1.2 + // parameters=AES-IV=0x651f722ffd512c52fe072e507d72b377 + // + // DER-encoded AlgorithmIdentifier: + // 301d06096086480165030401020410651f722ffd512c52fe072e507d72b377 + // + // OKM = 9cd102c52f1e19ece8729b35bfeceb50 + Digest hash = new SHA256Digest(); + byte[] ikm = Hex.decode("c702e7d0a9e064b09ba55245fb733cf3"); + byte[] salt = Strings.toByteArray("The Cryptographic Message Syntax"); + byte[] info = Hex.decode("301d06096086480165030401020410651f722ffd512c52fe072e507d72b377"); + byte[] okm = Hex.decode("9cd102c52f1e19ece8729b35bfeceb50"); + byte[] genOkm = new byte[okm.length]; + + HKDFParameters params = new HKDFParameters(ikm, salt, info); + + HKDFBytesGenerator hkdf = new HKDFBytesGenerator(hash); + hkdf.init(params); + hkdf.generateBytes(genOkm, 0, genOkm.length); + + compareOKM(9, genOkm, okm); } } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/HPKETestVectors.java b/core/src/test/java/org/bouncycastle/crypto/test/HPKETestVectors.java index 2a206d02dc..7f3c12579b 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/HPKETestVectors.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/HPKETestVectors.java @@ -233,7 +233,7 @@ public void testVectors() psk_id = Hex.decode((String)buf.get("psk_id")); } - System.out.println("test case: " + count); + //System.out.print.println("test case: " + count); // System.out.println("mode: " + mode + " kemID: " + kem_id + " kdfID: " + kdf_id + " aeadID: " + aead_id); HPKE hpke = new HPKE(mode, kem_id, kdf_id, aead_id); @@ -406,7 +406,7 @@ public void testVectors() } } } - System.out.println("testing successful!"); + //System.out.print.println("testing successful!"); } } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/HashCommitmentTest.java b/core/src/test/java/org/bouncycastle/crypto/test/HashCommitmentTest.java index ed83c64e74..8ca3434590 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/HashCommitmentTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/HashCommitmentTest.java @@ -26,11 +26,11 @@ public void performBasicTest() { byte[] data = Hex.decode("4e6f77206973207468652074696d6520666f7220616c6c20"); - Committer committer = new HashCommitter(new SHA256Digest(), new SecureRandom()); + Committer committer = new HashCommitter(SHA256Digest.newInstance(), new SecureRandom()); Commitment c = committer.commit(data); - committer = new HashCommitter(new SHA256Digest(), new SecureRandom()); + committer = new HashCommitter(SHA256Digest.newInstance(), new SecureRandom()); if (!committer.isRevealed(c, data)) { @@ -76,11 +76,11 @@ public void performGeneralTest() { byte[] data = Hex.decode("4e6f77206973207468652074696d6520666f7220616c6c20"); - Committer committer = new GeneralHashCommitter(new SHA256Digest(), new SecureRandom()); + Committer committer = new GeneralHashCommitter(SHA256Digest.newInstance(), new SecureRandom()); Commitment c = committer.commit(data); - committer = new GeneralHashCommitter(new SHA256Digest(), new SecureRandom()); + committer = new GeneralHashCommitter(SHA256Digest.newInstance(), new SecureRandom()); if (!committer.isRevealed(c, data)) { diff --git a/core/src/test/java/org/bouncycastle/crypto/test/ISAPTest.java b/core/src/test/java/org/bouncycastle/crypto/test/ISAPTest.java index e155c79e38..88574af391 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/ISAPTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/ISAPTest.java @@ -113,7 +113,7 @@ private void testVectors(String filename, IsapType isapType) map.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println(filename + " pass"); + //System.out.print.println(filename + " pass"); } private void testVectors() @@ -154,7 +154,7 @@ private void testVectors() map.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("ISAP Hash pass"); + //System.out.print.println("ISAP Hash pass"); } private void testExceptions(Digest digest, int digestsize) @@ -182,7 +182,7 @@ private void testExceptions(Digest digest, int digestsize) { //expected } - System.out.println(digest.getAlgorithmName() + " test Exceptions pass"); + //System.out.print.println(digest.getAlgorithmName() + " test Exceptions pass"); } private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, int blocksize) @@ -453,7 +453,7 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, { fail(aeadBlockCipher.getAlgorithmName() + ": Splitting input of plaintext should output the same ciphertext"); } - System.out.println(aeadBlockCipher.getAlgorithmName() + " test Exceptions pass"); + //System.out.print.println(aeadBlockCipher.getAlgorithmName() + " test Exceptions pass"); } private void testParameters(ISAPEngine isap, int keySize, int ivSize, int macSize) @@ -470,7 +470,7 @@ private void testParameters(ISAPEngine isap, int keySize, int ivSize, int macSiz { fail(isap.getAlgorithmName() + ": mac bytes of " + isap.getAlgorithmName() + " is not correct"); } - System.out.println(isap.getAlgorithmName() + " test Parameters pass"); + //System.out.print.println(isap.getAlgorithmName() + " test Parameters pass"); } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/ISO9796Test.java b/core/src/test/java/org/bouncycastle/crypto/test/ISO9796Test.java index cb21207d18..ddd5696a4e 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/ISO9796Test.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/ISO9796Test.java @@ -794,7 +794,7 @@ private void doTest13() RSAKeyParameters privParams = new RSAKeyParameters(true, modulus, privExp); AsymmetricBlockCipher rsaEngine = new RSABlindedEngine(); - Digest digest = new SHA256Digest(); + Digest digest = SHA256Digest.newInstance(); // set challenge to all zero's for verification byte[] challenge = new byte[8]; @@ -842,7 +842,7 @@ private void doTest13() signer.reset(); - digest = new SHA256Digest(); + digest = SHA256Digest.newInstance(); // NOTE setting implit to false does not actually do anything for verification !!! signer = new ISO9796d2Signer(rsaEngine, digest, false); @@ -975,7 +975,7 @@ private void doFullMessageTest() // set challenge to all zero's for verification byte[] challenge = new byte[8]; - ISO9796d2PSSSigner pssSign = new ISO9796d2PSSSigner(new RSAEngine(), new SHA256Digest(), 20, true); + ISO9796d2PSSSigner pssSign = new ISO9796d2PSSSigner(new RSAEngine(), SHA256Digest.newInstance(), 20, true); pssSign.init(true, privParams); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/KDF1GeneratorTest.java b/core/src/test/java/org/bouncycastle/crypto/test/KDF1GeneratorTest.java index 62f9997f86..ed0cce33c1 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/KDF1GeneratorTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/KDF1GeneratorTest.java @@ -2,9 +2,9 @@ import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.DerivationFunction; -import org.bouncycastle.crypto.digests.ShortenedDigest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.digests.ShortenedDigest; import org.bouncycastle.crypto.generators.KDF1BytesGenerator; import org.bouncycastle.crypto.params.ISO18033KDFParameters; import org.bouncycastle.util.encoders.Hex; @@ -46,9 +46,9 @@ public KDF1GeneratorTest() public void performTest() { - checkMask(1, new KDF1BytesGenerator(new ShortenedDigest(new SHA256Digest(), 20)), seed1, mask1); + checkMask(1, new KDF1BytesGenerator(new ShortenedDigest(SHA256Digest.newInstance(), 20)), seed1, mask1); checkMask(2, new KDF1BytesGenerator(new SHA1Digest()), seed2, mask2); - checkMask(3, new KDF1BytesGenerator(new ShortenedDigest(new SHA256Digest(), 20)), seed3, mask3); + checkMask(3, new KDF1BytesGenerator(new ShortenedDigest(SHA256Digest.newInstance(), 20)), seed3, mask3); try { diff --git a/core/src/test/java/org/bouncycastle/crypto/test/KDF2GeneratorTest.java b/core/src/test/java/org/bouncycastle/crypto/test/KDF2GeneratorTest.java index 84a435a696..d12c33319e 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/KDF2GeneratorTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/KDF2GeneratorTest.java @@ -55,9 +55,9 @@ public KDF2GeneratorTest() public void performTest() { - checkMask(1, new KDF2BytesGenerator(new ShortenedDigest(new SHA256Digest(), 20)), seed1, mask1); - checkMask(2, new KDF2BytesGenerator(new ShortenedDigest(new SHA256Digest(), 20)), seed2, mask2); - checkMask(3, new KDF2BytesGenerator(new SHA256Digest()), seed2, adjustedMask2); + checkMask(1, new KDF2BytesGenerator(new ShortenedDigest(SHA256Digest.newInstance(), 20)), seed1, mask1); + checkMask(2, new KDF2BytesGenerator(new ShortenedDigest(SHA256Digest.newInstance(), 20)), seed2, mask2); + checkMask(3, new KDF2BytesGenerator(SHA256Digest.newInstance()), seed2, adjustedMask2); checkMask(4, new KDF2BytesGenerator(new SHA1Digest()), seed2, sha1Mask); checkMask(5, new KDF2BytesGenerator(new SHA1Digest()), seed3, mask3); checkMask(6, new KDF2BytesGenerator(new SHA1Digest()), seed4, mask4); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/LEATest.java b/core/src/test/java/org/bouncycastle/crypto/test/LEATest.java index 6b13f85ce1..e60e9e8720 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/LEATest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/LEATest.java @@ -222,12 +222,12 @@ else if (comment.indexOf("CTR") >= 0 || comment.indexOf("CBC") >= 0) if (comment.indexOf("CBC") >= 0) { - engine = new CBCBlockCipher(new LEAEngine()); + engine = CBCBlockCipher.newInstance(new LEAEngine()); } else { // CTR - engine = new SICBlockCipher(new LEAEngine()); + engine = SICBlockCipher.newInstance(new LEAEngine()); } if (line.endsWith("Encrypt")) { diff --git a/core/src/test/java/org/bouncycastle/crypto/test/MGF1GeneratorTest.java b/core/src/test/java/org/bouncycastle/crypto/test/MGF1GeneratorTest.java index e7e99fe209..696d3c1857 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/MGF1GeneratorTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/MGF1GeneratorTest.java @@ -41,9 +41,9 @@ public class MGF1GeneratorTest public void performTest() { - checkMask(1, new MGF1BytesGenerator(new ShortenedDigest(new SHA256Digest(), 20)), seed1, mask1); + checkMask(1, new MGF1BytesGenerator(new ShortenedDigest(SHA256Digest.newInstance(), 20)), seed1, mask1); checkMask(2, new MGF1BytesGenerator(new SHA1Digest()), seed2, mask2); - checkMask(3, new MGF1BytesGenerator(new ShortenedDigest(new SHA256Digest(), 20)), seed3, mask3); + checkMask(3, new MGF1BytesGenerator(new ShortenedDigest(SHA256Digest.newInstance(), 20)), seed3, mask3); try { diff --git a/core/src/test/java/org/bouncycastle/crypto/test/NISTCTSTest.java b/core/src/test/java/org/bouncycastle/crypto/test/NISTCTSTest.java index 567d676a8b..b1febcd4ca 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/NISTCTSTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/NISTCTSTest.java @@ -79,7 +79,7 @@ private void testCTS( private void testExceptions() throws InvalidCipherTextException { - BufferedBlockCipher engine = new NISTCTSBlockCipher(NISTCTSBlockCipher.CS1, new AESEngine()); + BufferedBlockCipher engine = new NISTCTSBlockCipher(NISTCTSBlockCipher.CS1, AESEngine.newInstance()); CipherParameters params = new KeyParameter(new byte[engine.getBlockSize()]); engine.init(true, params); @@ -136,28 +136,28 @@ public String getName() public void performTest() throws Exception { - testCTS(1, NISTCTSBlockCipher.CS1, new AESEngine(), new ParametersWithIV(key, iv), singleBlock, singleOut); - testCTS(2, NISTCTSBlockCipher.CS2, new AESEngine(), new ParametersWithIV(key, iv), singleBlock, singleOut); - testCTS(3, NISTCTSBlockCipher.CS3, new AESEngine(), new ParametersWithIV(key, iv), singleBlock, singleOut); + testCTS(1, NISTCTSBlockCipher.CS1, AESEngine.newInstance(), new ParametersWithIV(key, iv), singleBlock, singleOut); + testCTS(2, NISTCTSBlockCipher.CS2, AESEngine.newInstance(), new ParametersWithIV(key, iv), singleBlock, singleOut); + testCTS(3, NISTCTSBlockCipher.CS3, AESEngine.newInstance(), new ParametersWithIV(key, iv), singleBlock, singleOut); - testCTS(4, NISTCTSBlockCipher.CS1, new AESEngine(), new ParametersWithIV(key, iv), twoBlock, cs1TwoBlockOut); - testCTS(5, NISTCTSBlockCipher.CS2, new AESEngine(), new ParametersWithIV(key, iv), twoBlock, cs2TwoBlockOut); - testCTS(6, NISTCTSBlockCipher.CS3, new AESEngine(), new ParametersWithIV(key, iv), twoBlock, cs3TwoBlockOut); + testCTS(4, NISTCTSBlockCipher.CS1, AESEngine.newInstance(), new ParametersWithIV(key, iv), twoBlock, cs1TwoBlockOut); + testCTS(5, NISTCTSBlockCipher.CS2, AESEngine.newInstance(), new ParametersWithIV(key, iv), twoBlock, cs2TwoBlockOut); + testCTS(6, NISTCTSBlockCipher.CS3, AESEngine.newInstance(), new ParametersWithIV(key, iv), twoBlock, cs3TwoBlockOut); - testCTS(7, NISTCTSBlockCipher.CS1, new AESEngine(), new ParametersWithIV(key, iv), notQuiteTwo, cs1NotQuiteTwoBlockOut); - testCTS(8, NISTCTSBlockCipher.CS2, new AESEngine(), new ParametersWithIV(key, iv), notQuiteTwo, cs2NotQuiteTwoBlockOut); - testCTS(9, NISTCTSBlockCipher.CS3, new AESEngine(), new ParametersWithIV(key, iv), notQuiteTwo, cs3NotQuiteTwoBlockOut); + testCTS(7, NISTCTSBlockCipher.CS1, AESEngine.newInstance(), new ParametersWithIV(key, iv), notQuiteTwo, cs1NotQuiteTwoBlockOut); + testCTS(8, NISTCTSBlockCipher.CS2, AESEngine.newInstance(), new ParametersWithIV(key, iv), notQuiteTwo, cs2NotQuiteTwoBlockOut); + testCTS(9, NISTCTSBlockCipher.CS3, AESEngine.newInstance(), new ParametersWithIV(key, iv), notQuiteTwo, cs3NotQuiteTwoBlockOut); byte[] aes128b = Hex.decode("aafd12f659cae63489b479e5076ddec2f06cb58faafd12f6"); byte[] aesIn1b = Hex.decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f"); byte[] aesOut1b = Hex.decode("6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04"); - testCTS(10, NISTCTSBlockCipher.CS3, new AESEngine(), new ParametersWithIV(new KeyParameter(aes128b), Hex.decode("aafd12f659cae63489b479e5076ddec2")), aesIn1b, aesOut1b); + testCTS(10, NISTCTSBlockCipher.CS3, AESEngine.newInstance(), new ParametersWithIV(new KeyParameter(aes128b), Hex.decode("aafd12f659cae63489b479e5076ddec2")), aesIn1b, aesOut1b); byte[] aes128c = Hex.decode("aafd12f659cae63489b479e5076ddec2"); byte[] aesOut1c = Hex.decode("0af33c005a337af55a5149effc5108eaa1ea87de8a8556e8786b8f230da64e56"); - testCTS(11, NISTCTSBlockCipher.CS3, new AESEngine(), new ParametersWithIV(new KeyParameter(aes128c), Hex.decode("aafd12f659cae63489b479e5076ddec2")), aesIn1b, aesOut1c); + testCTS(11, NISTCTSBlockCipher.CS3, AESEngine.newInstance(), new ParametersWithIV(new KeyParameter(aes128c), Hex.decode("aafd12f659cae63489b479e5076ddec2")), aesIn1b, aesOut1c); testExceptions(); } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/OAEPTest.java b/core/src/test/java/org/bouncycastle/crypto/test/OAEPTest.java index 866783237f..848f058adb 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/OAEPTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/OAEPTest.java @@ -24,9 +24,7 @@ import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.crypto.util.PrivateKeyFactory; -import org.bouncycastle.crypto.util.PrivateKeyInfoFactory; import org.bouncycastle.crypto.util.PublicKeyFactory; -import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Strings; @@ -798,7 +796,7 @@ public void performTest() throws Exception // // OAEP - public encrypt, private decrypt, differing hashes // - AsymmetricBlockCipher cipher = new OAEPEncoding(new RSAEngine(), new SHA256Digest(), new SHA1Digest(), new byte[10]); + AsymmetricBlockCipher cipher = new OAEPEncoding(new RSAEngine(), SHA256Digest.newInstance(), new SHA1Digest(), new byte[10]); cipher.init(true, new ParametersWithRandom(pubParam, new SecureRandom())); @@ -818,7 +816,7 @@ public void performTest() throws Exception } } - cipher = new OAEPEncoding(new RSAEngine(), new SHA1Digest(), new SHA256Digest(), new byte[10]); + cipher = new OAEPEncoding(new RSAEngine(), new SHA1Digest(), SHA256Digest.newInstance(), new byte[10]); cipher.init(true, new ParametersWithRandom(pubParam, new SecureRandom())); @@ -843,7 +841,7 @@ public void performTest() throws Exception AsymmetricKeyParameter pri2048 = PrivateKeyFactory.createKey(encPri2048); input = Strings.toByteArray("OAEP SHA-256 Test"); - cipher = new OAEPEncoding(new RSAEngine(), new SHA256Digest()); + cipher = new OAEPEncoding(new RSAEngine(), SHA256Digest.newInstance()); cipher.init(true, new ParametersWithRandom(pub2048, new FixedSecureRandom(encPub2048))); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/OCBTest.java b/core/src/test/java/org/bouncycastle/crypto/test/OCBTest.java index 7c1e6421ff..1ac98a14a0 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/OCBTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/OCBTest.java @@ -201,7 +201,7 @@ private void runTestCase(String testName, String[] testVector, int macLengthBits private BlockCipher createUnderlyingCipher() { - return new AESEngine(); + return AESEngine.newInstance(); } private AEADBlockCipher createOCBCipher() diff --git a/core/src/test/java/org/bouncycastle/crypto/test/OpenBSDBCryptTest.java b/core/src/test/java/org/bouncycastle/crypto/test/OpenBSDBCryptTest.java index cf1f1c75c8..72cf053575 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/OpenBSDBCryptTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/OpenBSDBCryptTest.java @@ -2,6 +2,7 @@ import java.security.SecureRandom; import java.util.ArrayList; +import java.util.List; import org.bouncycastle.crypto.generators.OpenBSDBCrypt; import org.bouncycastle.util.Arrays; @@ -156,7 +157,7 @@ public void testPermutations() } - ArrayList permutations = new ArrayList(); + List permutations = new ArrayList(); permute(permutations, buf, 0, buf.length - 1); for (int i = 0; i != permutations.size(); i++) @@ -199,7 +200,7 @@ private void swap(byte[] buf, int i, int j) buf[j] = b; } - private void permute(ArrayList permutation, byte[] a, int l, int r) + private void permute(List permutation, byte[] a, int l, int r) { if (l == r) { diff --git a/core/src/test/java/org/bouncycastle/crypto/test/OpenSSHKeyParsingTests.java b/core/src/test/java/org/bouncycastle/crypto/test/OpenSSHKeyParsingTests.java index 4de35bc6ee..40e4b26b4f 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/OpenSSHKeyParsingTests.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/OpenSSHKeyParsingTests.java @@ -294,7 +294,6 @@ public void testECDSA_curvesFromSSHKeyGen() doECSigTest(new ECPublicKeyParameters(q, privKey.getParameters()), privKey); } - for (int i = 0; i != pairs.length; i++) { String[] pair = pairs[i]; @@ -335,6 +334,14 @@ public void testECDSA_curvesFromSSHKeyGen() } + private void testFido2Keys() + { + // P-256 ECDSA Key + byte[] decode = Base64.decode("AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBPnfX2RzzEvD5CEX/0G3LLXrDWjrir9jZ2omSoxNyNT44cSiOP2v/WodnYpQdJsLIZn5bGNI0UxzxTuFzdizrWkAAAAEc3NoOg=="); + + CipherParameters xpubSpec = OpenSSHPublicKeyUtil.parsePublicKey(decode); + } + private void doECSigTest(CipherParameters pubSpec, CipherParameters privSpec) { ECDSASigner signer = new ECDSASigner(); @@ -470,6 +477,7 @@ public void performTest() testRSA(); testED25519(); testFailures(); + testFido2Keys(); } public void testRSA() diff --git a/core/src/test/java/org/bouncycastle/crypto/test/PSSTest.java b/core/src/test/java/org/bouncycastle/crypto/test/PSSTest.java index 726154039f..e6fcb3b967 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/PSSTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/PSSTest.java @@ -297,7 +297,7 @@ public void performTest() // // loop test - sha-256 and sha-1 // - eng = new PSSSigner(new RSAEngine(), new SHA256Digest(), new SHA1Digest(), 20); + eng = new PSSSigner(new RSAEngine(), SHA256Digest.newInstance(), new SHA1Digest(), 20); failed = 0; data = new byte[DATA_LENGTH]; @@ -335,7 +335,7 @@ private void fixedSaltTest() { byte[] data = Hex.decode("010203040506070809101112131415"); - PSSSigner eng = new PSSSigner(new RSAEngine(), new SHA256Digest(), new SHA1Digest(), Hex.decode("deadbeef")); + PSSSigner eng = new PSSSigner(new RSAEngine(), SHA256Digest.newInstance(), new SHA1Digest(), Hex.decode("deadbeef")); eng.init(true, prv8); @@ -354,7 +354,7 @@ private void fixedSaltTest() } // test failure - eng = new PSSSigner(new RSAEngine(), new SHA256Digest(), new SHA1Digest(), Hex.decode("beefbeef")); + eng = new PSSSigner(new RSAEngine(), SHA256Digest.newInstance(), new SHA1Digest(), Hex.decode("beefbeef")); eng.init(false, pub8); @@ -371,7 +371,7 @@ private void shakeFixedSaltTest() { byte[] data = Hex.decode("010203040506070809101112131415"); - PSSSigner eng = new PSSSigner(new RSAEngine(), new SHA256Digest(), new SHAKEDigest(128), Hex.decode("deadbeef")); + PSSSigner eng = new PSSSigner(new RSAEngine(), SHA256Digest.newInstance(), new SHAKEDigest(128), Hex.decode("deadbeef")); eng.init(true, new ParametersWithRandom(prv8, new FixedSecureRandom(data))); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/ParallelHashTest.java b/core/src/test/java/org/bouncycastle/crypto/test/ParallelHashTest.java index e4639bb918..05080caf2d 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/ParallelHashTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/ParallelHashTest.java @@ -1,5 +1,6 @@ package org.bouncycastle.crypto.test; +import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.ParallelHash; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; @@ -22,7 +23,7 @@ public String getName() public void performTest() throws Exception { - ParallelHash pHash = new ParallelHash(128, new byte[0], 8); + ParallelHash pHash = new ParallelHash(128, new byte[0], 8); byte[] data = Hex.decode("00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27"); pHash.update(data, 0, data.length); @@ -116,6 +117,7 @@ public void performTest() isTrue("oops!", Arrays.areEqual(Hex.decode("6b3e790b330c889a204c2fbc728d809f19367328d852f4002dc829f73afd6bcefb7fe5b607b13a801c0be5c1170bdb794e339458fdb0e62a6af3d42558970249"), res)); testEmpty(); + testClone(); } private void testEmpty() @@ -133,9 +135,38 @@ private void testEmpty() isTrue(Arrays.areEqual(Hex.decode("13C4"), res)); } - public static void main( - String[] args) - { - runTest(new ParallelHashTest()); - } + private void testClone() + { + Digest digest = new ParallelHash(256, Strings.toByteArray("Parallel Data"), 12); + byte[] input = Hex.decode("00 01 02 03 04 05 06 07 08 09 0A 0B 10 11 12 13 14 15 16 17 18 19 1A 1B 20 21 22 23 24 25 26 27 28 29 2A 2B 30 31 32 33 34 35 36 37 38 39 3A 3B 40 41 42 43 44 45 46 47 48 49 4A 4B 50 51 52 53 54 55 56 57 58 59 5A 5B"); + byte[] expected = Hex.decode("69 D0 FC B7 64 EA 05 5D D0 93 34 BC 60 21 CB 7E 4B 61 34 8D FF 37 5D A2 62 67 1C DE C3 EF FA 8D 1B 45 68 A6 CC E1 6B 1C AD 94 6D DD E2 7F 6C E2 B8 DE E4 CD 1B 24 85 1E BF 00 EB 90 D4 38 13 E9"); + byte[] resBuf = new byte[expected.length]; + + digest.update(input, 0, input.length / 2); + + // clone the Digest + Digest d = new ParallelHash((ParallelHash)digest); + + digest.update(input, input.length / 2, input.length - input.length / 2); + digest.doFinal(resBuf, 0); + + if (!areEqual(expected, resBuf)) + { + fail("failing clone vector test", Hex.toHexString(expected), new String(Hex.encode(resBuf))); + } + + d.update(input, input.length / 2, input.length - input.length / 2); + d.doFinal(resBuf, 0); + + if (!areEqual(expected, resBuf)) + { + fail("failing second clone vector test", Hex.toHexString(expected), new String(Hex.encode(resBuf))); + } + } + + public static void main( + String[] args) + { + runTest(new ParallelHashTest()); + } } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/PhotonBeetleTest.java b/core/src/test/java/org/bouncycastle/crypto/test/PhotonBeetleTest.java index 10d372565e..c6c9b53f62 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/PhotonBeetleTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/PhotonBeetleTest.java @@ -83,7 +83,7 @@ private void testVectorsHash() map.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("PhotonBeetle Hash pass"); + //System.out.print.println("PhotonBeetle Hash pass"); } private void testVectors(PhotonBeetleEngine.PhotonBeetleParameters pbp, String filename) @@ -147,7 +147,7 @@ private void testVectors(PhotonBeetleEngine.PhotonBeetleParameters pbp, String f map.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("PhotonBeetle AEAD pass"); + //System.out.print.println("PhotonBeetle AEAD pass"); } private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, int blocksize) @@ -420,7 +420,7 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, { fail(aeadBlockCipher.getAlgorithmName() + ": Splitting input of plaintext should output the same ciphertext"); } - System.out.println(aeadBlockCipher.getAlgorithmName() + " test Exceptions pass"); + //System.out.print.println(aeadBlockCipher.getAlgorithmName() + " test Exceptions pass"); } private void testParameters(PhotonBeetleEngine pb, int keySize, int ivSize, int macSize) @@ -437,7 +437,7 @@ private void testParameters(PhotonBeetleEngine pb, int keySize, int ivSize, int { fail(pb.getAlgorithmName() + ": mac bytes of " + pb.getAlgorithmName() + " is not correct"); } - System.out.println(pb.getAlgorithmName() + " test Parameters pass"); + //System.out.print.println(pb.getAlgorithmName() + " test Parameters pass"); } @@ -466,7 +466,7 @@ private void testExceptions(Digest digest, int digestsize) { //expected } - System.out.println(digest.getAlgorithmName() + " test Exceptions pass"); + //System.out.print.println(digest.getAlgorithmName() + " test Exceptions pass"); } private void mismatch(String name, String expected, byte[] found) diff --git a/core/src/test/java/org/bouncycastle/crypto/test/Poly1305Test.java b/core/src/test/java/org/bouncycastle/crypto/test/Poly1305Test.java index f5f6869b09..e8990084e7 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/Poly1305Test.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/Poly1305Test.java @@ -133,7 +133,7 @@ private void testCase(int i) } else { - mac = new Poly1305(new AESEngine()); + mac = new Poly1305(AESEngine.newInstance()); mac.init(new ParametersWithIV(new KeyParameter(tc.key), tc.nonce)); } mac.update(tc.message, 0, tc.message.length); @@ -155,7 +155,7 @@ private void testSequential() byte[] out = new byte[16]; int c = 0; - final Mac mac = new Poly1305(new AESEngine()); + final Mac mac = new Poly1305(AESEngine.newInstance()); for (int loop = 0; loop < 13; loop++) { len = 0; @@ -234,7 +234,7 @@ private void testReset() byte[] out = new byte[16]; // Generate baseline - Mac poly = new Poly1305(new AESEngine()); + Mac poly = new Poly1305(AESEngine.newInstance()); poly.init(new ParametersWithIV(new KeyParameter(k), new byte[16])); poly.update(m, 0, m.length); @@ -280,7 +280,7 @@ private void testInit() gen.init(new KeyGenerationParameters(new SecureRandom(), 256)); byte[] k = gen.generateKey(); - Mac poly = new Poly1305(new AESEngine()); + Mac poly = new Poly1305(AESEngine.newInstance()); poly.init(new ParametersWithIV(new KeyParameter(k), new byte[16])); try diff --git a/core/src/test/java/org/bouncycastle/crypto/test/RSADigestSignerTest.java b/core/src/test/java/org/bouncycastle/crypto/test/RSADigestSignerTest.java index 799966c82f..717807e2f7 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/RSADigestSignerTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/RSADigestSignerTest.java @@ -50,8 +50,8 @@ public void performTest() throws Exception checkNullDigest(rsaPublic, rsaPrivate, new SHA1Digest(), X509ObjectIdentifiers.id_SHA1); checkDigest(rsaPublic, rsaPrivate, new SHA224Digest(), NISTObjectIdentifiers.id_sha224); - checkDigest(rsaPublic, rsaPrivate, new SHA256Digest(), NISTObjectIdentifiers.id_sha256); - checkNullDigest(rsaPublic, rsaPrivate, new SHA256Digest(), NISTObjectIdentifiers.id_sha256); + checkDigest(rsaPublic, rsaPrivate, SHA256Digest.newInstance(), NISTObjectIdentifiers.id_sha256); + checkNullDigest(rsaPublic, rsaPrivate, SHA256Digest.newInstance(), NISTObjectIdentifiers.id_sha256); checkDigest(rsaPublic, rsaPrivate, new SHA384Digest(), NISTObjectIdentifiers.id_sha384); checkDigest(rsaPublic, rsaPrivate, new SHA512Digest(), NISTObjectIdentifiers.id_sha512); checkDigest(rsaPublic, rsaPrivate, new SHA512tDigest(224), NISTObjectIdentifiers.id_sha512_224); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/SCryptTest.java b/core/src/test/java/org/bouncycastle/crypto/test/SCryptTest.java index 2be3b9a01a..3be0f9642a 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/SCryptTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/SCryptTest.java @@ -3,6 +3,7 @@ import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.List; import org.bouncycastle.crypto.generators.SCrypt; import org.bouncycastle.test.TestResourceFinder; @@ -80,7 +81,7 @@ public void testPermutations() } - ArrayList permutations = new ArrayList(); + List permutations = new ArrayList(); permute(permutations, buf, 0, buf.length - 1); for (int i = 0; i != permutations.size(); i++) @@ -112,7 +113,7 @@ private void swap(byte[] buf, int i, int j) buf[j] = b; } - private void permute(ArrayList permutation, byte[] a, int l, int r) + private void permute(List permutation, byte[] a, int l, int r) { if (l == r) { diff --git a/core/src/test/java/org/bouncycastle/crypto/test/SHA256DigestTest.java b/core/src/test/java/org/bouncycastle/crypto/test/SHA256DigestTest.java index 8a35ce42b2..84903bb9d1 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/SHA256DigestTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/SHA256DigestTest.java @@ -32,7 +32,7 @@ public class SHA256DigestTest SHA256DigestTest() { - super(new SHA256Digest(), messages, digests); + super(SHA256Digest.newInstance(), messages, digests); } public void performTest() @@ -44,12 +44,12 @@ public void performTest() protected Digest cloneDigest(Digest digest) { - return new SHA256Digest((SHA256Digest)digest); + return SHA256Digest.newInstance(digest); } protected Digest cloneDigest(byte[] encodedState) { - return new SHA256Digest(encodedState); + return SHA256Digest.newInstance(encodedState); } public static void main( diff --git a/core/src/test/java/org/bouncycastle/crypto/test/SHA256HMacTest.java b/core/src/test/java/org/bouncycastle/crypto/test/SHA256HMacTest.java index 82ab1dc71c..595f00ec39 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/SHA256HMacTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/SHA256HMacTest.java @@ -52,7 +52,7 @@ public String getName() public TestResult perform() { - HMac hmac = new HMac(new SHA256Digest()); + HMac hmac = new HMac(SHA256Digest.newInstance()); byte[] resBuf = new byte[hmac.getMacSize()]; for (int i = 0; i < messages.length; i++) diff --git a/core/src/test/java/org/bouncycastle/crypto/test/SM2SignerTest.java b/core/src/test/java/org/bouncycastle/crypto/test/SM2SignerTest.java index ca133d7fc2..6273448f8e 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/SM2SignerTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/SM2SignerTest.java @@ -17,10 +17,8 @@ import org.bouncycastle.crypto.generators.SM2KeyPairGenerator; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; -import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ParametersWithID; import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.crypto.signers.ECDSASigner; import org.bouncycastle.crypto.signers.SM2Signer; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECCurve; @@ -158,6 +156,13 @@ private void doSignerTest(String curveName, Digest d, String ident, String msg, private void doSignerTest(ECDomainParameters domainParams, Digest d, String ident, String msg, String x, String nonce, String r, String s) throws Exception + { + implSignerTest(domainParams, d, ident, msg, x, nonce, r, s); + implSignerTestReuse(domainParams, d, ident, msg, x); + } + + private void implSignerTest(ECDomainParameters domainParams, Digest d, String ident, String msg, String x, String nonce, String r, String s) + throws Exception { byte[] idBytes = Strings.toByteArray(ident); byte[] msgBytes = Strings.toByteArray(msg); @@ -185,6 +190,40 @@ private void doSignerTest(ECDomainParameters domainParams, Digest d, String iden isTrue("verification failed", signer.verifySignature(sig)); } + private void implSignerTestReuse(ECDomainParameters domainParams, Digest d, String ident, String msg, String x) + throws Exception + { + byte[] idBytes = Strings.toByteArray(ident); + byte[] msgBytes = Strings.toByteArray(msg); + AsymmetricCipherKeyPair kp = generateKeyPair(domainParams, x); + + SM2Signer signer = new SM2Signer(d); + + signer.init(true, new ParametersWithID(kp.getPrivate(), idBytes)); + signer.update(msgBytes, 0, msgBytes.length); + byte[] sig1 = signer.generateSignature(); + + signer.update(msgBytes, 0, msgBytes.length); + byte[] sig2 = signer.generateSignature(); + + signer.update((byte)0x00); + signer.reset(); + signer.update(msgBytes, 0, msgBytes.length); + byte[] sig3 = signer.generateSignature(); + + signer.init(false, new ParametersWithID(kp.getPublic(), idBytes)); + signer.update(msgBytes, 0, msgBytes.length); + isTrue("verification failed", signer.verifySignature(sig1)); + + signer.update(msgBytes, 0, msgBytes.length); + isTrue("verification failed", signer.verifySignature(sig2)); + + signer.update((byte)0x00); + signer.reset(); + signer.update(msgBytes, 0, msgBytes.length); + isTrue("verification failed", signer.verifySignature(sig3)); + } + private void doVerifyBoundsCheck() throws IOException { diff --git a/core/src/test/java/org/bouncycastle/crypto/test/SRP6Test.java b/core/src/test/java/org/bouncycastle/crypto/test/SRP6Test.java index 2409faff51..aa424729c2 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/SRP6Test.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/SRP6Test.java @@ -14,6 +14,7 @@ import org.bouncycastle.crypto.generators.DHParametersGenerator; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.SRP6GroupParameters; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -48,8 +49,8 @@ public void performTest() throws Exception private void rfc5054AppendixBTestVectors() throws Exception { - byte[] I = "alice".getBytes("UTF8"); - byte[] P = "password123".getBytes("UTF8"); + byte[] I = Strings.toUTF8ByteArray("alice"); + byte[] P = Strings.toUTF8ByteArray("password123"); byte[] s = Hex.decode("BEB25379D1A8581EB5A727673A2441EE"); BigInteger N = SRP6StandardGroups.rfc5054_1024.getN(); BigInteger g = SRP6StandardGroups.rfc5054_1024.getG(); @@ -168,14 +169,14 @@ private void testMutualVerification(SRP6GroupParameters group) throws CryptoExce random.nextBytes(s); SRP6VerifierGenerator gen = new SRP6VerifierGenerator(); - gen.init(group, new SHA256Digest()); + gen.init(group, SHA256Digest.newInstance()); BigInteger v = gen.generateVerifier(s, I, P); SRP6Client client = new SRP6Client(); - client.init(group, new SHA256Digest(), random); + client.init(group, SHA256Digest.newInstance(), random); SRP6Server server = new SRP6Server(); - server.init(group, v, new SHA256Digest(), random); + server.init(group, v, SHA256Digest.newInstance(), random); BigInteger A = client.generateClientCredentials(s, I, P); BigInteger B = server.generateServerCredentials(); @@ -197,7 +198,7 @@ private void testClientCatchesBadB(SRP6GroupParameters group) random.nextBytes(s); SRP6Client client = new SRP6Client(); - client.init(group, new SHA256Digest(), random); + client.init(group, SHA256Digest.newInstance(), random); client.generateClientCredentials(s, I, P); @@ -230,11 +231,11 @@ private void testServerCatchesBadA(SRP6GroupParameters group) random.nextBytes(s); SRP6VerifierGenerator gen = new SRP6VerifierGenerator(); - gen.init(group, new SHA256Digest()); + gen.init(group, SHA256Digest.newInstance()); BigInteger v = gen.generateVerifier(s, I, P); SRP6Server server = new SRP6Server(); - server.init(group, v, new SHA256Digest(), random); + server.init(group, v, SHA256Digest.newInstance(), random); server.generateServerCredentials(); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/SimpleTestTest.java b/core/src/test/java/org/bouncycastle/crypto/test/SimpleTestTest.java index 11e491d79e..701b2a0797 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/SimpleTestTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/SimpleTestTest.java @@ -20,7 +20,7 @@ public void testCrypto() { result.getException().printStackTrace(); } - fail(result.toString()); + fail(i+" -> "+ result.toString()); } } } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/SparkleTest.java b/core/src/test/java/org/bouncycastle/crypto/test/SparkleTest.java index dd60ad5515..76ead9d8fe 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/SparkleTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/SparkleTest.java @@ -8,21 +8,26 @@ import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.digests.SparkleDigest; import org.bouncycastle.crypto.engines.SparkleEngine; -import org.bouncycastle.crypto.modes.AEADCipher; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.test.TestResourceFinder; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; public class SparkleTest extends SimpleTest { + public static void main(String[] args) + { + runTest(new SparkleTest()); + } + public String getName() { return "Sparkle"; @@ -31,196 +36,426 @@ public String getName() public void performTest() throws Exception { - SparkleEngine sparkle = new SparkleEngine(SparkleEngine.SparkleParameters.SCHWAEMM128_128); - testExceptions(sparkle, sparkle.getKeyBytesSize(), sparkle.getIVBytesSize(), sparkle.getBlockSize()); - testParameters(sparkle, 16, 16, 16); - sparkle = new SparkleEngine(SparkleEngine.SparkleParameters.SCHWAEMM192_192); - testExceptions(sparkle, sparkle.getKeyBytesSize(), sparkle.getIVBytesSize(), sparkle.getBlockSize()); - testParameters(sparkle, 24, 24, 24); - sparkle = new SparkleEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_128); - testExceptions(sparkle, sparkle.getKeyBytesSize(), sparkle.getIVBytesSize(), sparkle.getBlockSize()); - testParameters(sparkle, 16, 32, 16); - sparkle = new SparkleEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_256); - testExceptions(sparkle, sparkle.getKeyBytesSize(), sparkle.getIVBytesSize(), sparkle.getBlockSize()); - testParameters(sparkle, 32, 32, 32); - testExceptions(new SparkleDigest(SparkleDigest.SparkleParameters.ESCH256), 32); - testExceptions(new SparkleDigest(SparkleDigest.SparkleParameters.ESCH384), 48); - testVectors(SparkleEngine.SparkleParameters.SCHWAEMM128_128, "128_128"); - testVectors(SparkleEngine.SparkleParameters.SCHWAEMM192_192, "192_192"); - testVectors(SparkleEngine.SparkleParameters.SCHWAEMM256_128, "128_256"); - testVectors(SparkleEngine.SparkleParameters.SCHWAEMM256_256, "256_256"); - testVectorsHash(SparkleDigest.SparkleParameters.ESCH256, "256"); - testVectorsHash(SparkleDigest.SparkleParameters.ESCH384, "384"); - } - - - private void testVectors(SparkleEngine.SparkleParameters pbp, String filename) + testBufferingEngine_SCHWAEMM128_128(); + testBufferingEngine_SCHWAEMM192_192(); + testBufferingEngine_SCHWAEMM256_128(); + testBufferingEngine_SCHWAEMM256_256(); + + testExceptionsDigest_ESCH256(); + testExceptionsDigest_ESCH384();; + + testExceptionsEngine_SCHWAEMM128_128(); + testExceptionsEngine_SCHWAEMM192_192(); + testExceptionsEngine_SCHWAEMM256_128(); + testExceptionsEngine_SCHWAEMM256_256(); + + testParametersDigest_ESCH256(); + testParametersDigest_ESCH384(); + + testParametersEngine_SCHWAEMM128_128(); + testParametersEngine_SCHWAEMM192_192(); + testParametersEngine_SCHWAEMM256_128(); + testParametersEngine_SCHWAEMM256_256(); + + testVectorsDigest_ESCH256(); + testVectorsDigest_ESCH384(); + + testVectorsEngine_SCHWAEMM128_128(); + testVectorsEngine_SCHWAEMM192_192(); + testVectorsEngine_SCHWAEMM256_128(); + testVectorsEngine_SCHWAEMM256_256(); + } + + public void testBufferingEngine_SCHWAEMM128_128() throws Exception + { + implTestBufferingEngine(SparkleEngine.SparkleParameters.SCHWAEMM128_128); + } + + public void testBufferingEngine_SCHWAEMM192_192() throws Exception + { + implTestBufferingEngine(SparkleEngine.SparkleParameters.SCHWAEMM192_192); + } + + public void testBufferingEngine_SCHWAEMM256_128() throws Exception + { + implTestBufferingEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_128); + } + + public void testBufferingEngine_SCHWAEMM256_256() throws Exception + { + implTestBufferingEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_256); + } + + public void testExceptionsDigest_ESCH256() throws Exception + { + implTestExceptionsDigest(SparkleDigest.SparkleParameters.ESCH256); + } + + public void testExceptionsDigest_ESCH384() throws Exception + { + implTestExceptionsDigest(SparkleDigest.SparkleParameters.ESCH384); + } + + public void testExceptionsEngine_SCHWAEMM128_128() throws Exception + { + implTestExceptionsEngine(SparkleEngine.SparkleParameters.SCHWAEMM128_128); + } + + public void testExceptionsEngine_SCHWAEMM192_192() throws Exception + { + implTestExceptionsEngine(SparkleEngine.SparkleParameters.SCHWAEMM192_192); + } + + public void testExceptionsEngine_SCHWAEMM256_128() throws Exception + { + implTestExceptionsEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_128); + } + + public void testExceptionsEngine_SCHWAEMM256_256() throws Exception + { + implTestExceptionsEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_256); + } + + public void testParametersDigest_ESCH256() throws Exception + { + implTestParametersDigest(SparkleDigest.SparkleParameters.ESCH256, 32); + } + + public void testParametersDigest_ESCH384() throws Exception + { + implTestParametersDigest(SparkleDigest.SparkleParameters.ESCH384, 48); + } + + public void testParametersEngine_SCHWAEMM128_128() throws Exception + { + implTestParametersEngine(SparkleEngine.SparkleParameters.SCHWAEMM128_128, 16, 16, 16); + } + + public void testParametersEngine_SCHWAEMM192_192() throws Exception + { + implTestParametersEngine(SparkleEngine.SparkleParameters.SCHWAEMM192_192, 24, 24, 24); + } + + public void testParametersEngine_SCHWAEMM256_128() throws Exception + { + implTestParametersEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_128, 16, 32, 16); + } + + public void testParametersEngine_SCHWAEMM256_256() throws Exception + { + implTestParametersEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_256, 32, 32, 32); + } + + public void testVectorsDigest_ESCH256() throws Exception + { + implTestVectorsDigest(SparkleDigest.SparkleParameters.ESCH256, "256"); + } + + public void testVectorsDigest_ESCH384() throws Exception + { + implTestVectorsDigest(SparkleDigest.SparkleParameters.ESCH384, "384"); + } + + public void testVectorsEngine_SCHWAEMM128_128() throws Exception + { + implTestVectorsEngine(SparkleEngine.SparkleParameters.SCHWAEMM128_128, "128_128"); + } + + public void testVectorsEngine_SCHWAEMM192_192() throws Exception + { + implTestVectorsEngine(SparkleEngine.SparkleParameters.SCHWAEMM192_192, "192_192"); + } + + public void testVectorsEngine_SCHWAEMM256_128() throws Exception + { + implTestVectorsEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_128, "128_256"); + } + + public void testVectorsEngine_SCHWAEMM256_256() throws Exception + { + implTestVectorsEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_256, "256_256"); + } + + private static SparkleDigest createDigest(SparkleDigest.SparkleParameters sparkleParameters) + { + return new SparkleDigest(sparkleParameters); + } + + private static SparkleEngine createEngine(SparkleEngine.SparkleParameters sparkleParameters) + { + return new SparkleEngine(sparkleParameters); + } + + private void implTestBufferingEngine(SparkleEngine.SparkleParameters sparkleParameters) throws Exception { - SparkleEngine Sparkle = new SparkleEngine(pbp); - CipherParameters params; - InputStream src = TestResourceFinder.findTestResource("crypto/sparkle", "LWC_AEAD_KAT_" - + filename + ".txt"); + Random random = new Random(); + + int plaintextLength = 256; + byte[] plaintext = new byte[plaintextLength]; + random.nextBytes(plaintext); + + SparkleEngine sparkle0 = createEngine(sparkleParameters); + initEngine(sparkle0, true); + + byte[] ciphertext = new byte[sparkle0.getOutputSize(plaintextLength)]; + random.nextBytes(ciphertext); + + int ciphertextLength = sparkle0.processBytes(plaintext, 0, plaintextLength, ciphertext, 0); + ciphertextLength += sparkle0.doFinal(ciphertext, ciphertextLength); + + byte[] output = new byte[ciphertextLength]; + + // Encryption + for (int split = 1; split < plaintextLength; ++split) + { + SparkleEngine sparkle = createEngine(sparkleParameters); + initEngine(sparkle, true); + + random.nextBytes(output); + + int length = sparkle.processBytes(plaintext, 0, split, output, 0); + + if (0 != sparkle.getUpdateOutputSize(0)) + { + fail(""); + } + + length += sparkle.processBytes(plaintext, split, plaintextLength - split, output, length); + length += sparkle.doFinal(output, length); + + if (!Arrays.areEqual(ciphertext, 0, ciphertextLength, output, 0, length)) + { + fail("encryption failed with split: " + split); + } + } + + // Decryption + for (int split = 1; split < ciphertextLength; ++split) + { + SparkleEngine sparkle = createEngine(sparkleParameters); + initEngine(sparkle, false); + + random.nextBytes(output); + + int length = sparkle.processBytes(ciphertext, 0, split, output, 0); + + if (0 != sparkle.getUpdateOutputSize(0)) + { + fail(""); + } + + length += sparkle.processBytes(ciphertext, split, ciphertextLength - split, output, length); + length += sparkle.doFinal(output, length); + + if (!Arrays.areEqual(plaintext, 0, plaintextLength, output, 0, length)) + { + fail("decryption failed with split: " + split); + } + } + } + + private void implTestExceptionsDigest(SparkleDigest.SparkleParameters sparkleParameters) + { + SparkleDigest sparkle = createDigest(sparkleParameters); + + try + { + sparkle.update(new byte[1], 1, 1); + fail(sparkle.getAlgorithmName() + ": input for update is too short"); + } + catch (DataLengthException e) + { + //expected + } + + try + { + sparkle.doFinal(new byte[sparkle.getDigestSize() - 1], 2); + fail(sparkle.getAlgorithmName() + ": output for dofinal is too short"); + } + catch (OutputLengthException e) + { + //expected + } + } + + private void implTestVectorsDigest(SparkleDigest.SparkleParameters sparkleParameters, String filename) + throws Exception + { + Random random = new Random(); + SparkleDigest sparkle = createDigest(sparkleParameters); + InputStream src = TestResourceFinder.findTestResource("crypto/sparkle", "LWC_HASH_KAT_" + filename + ".txt"); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); String line; - byte[] rv; HashMap map = new HashMap(); while ((line = bin.readLine()) != null) { int a = line.indexOf('='); if (a < 0) { -// if (!map.get("Count").equals("34")) -// { -// continue; -// } - byte[] key = Hex.decode(map.get("Key")); - byte[] nonce = Hex.decode(map.get("Nonce")); - byte[] ad = Hex.decode(map.get("AD")); - byte[] pt = Hex.decode(map.get("PT")); - byte[] ct = Hex.decode(map.get("CT")); - params = new ParametersWithIV(new KeyParameter(key), nonce); - Sparkle.init(true, params); - Sparkle.processAADBytes(ad, 0, ad.length); - rv = new byte[Sparkle.getOutputSize(pt.length)]; - int len = Sparkle.processBytes(pt, 0, pt.length, rv, 0); - Sparkle.doFinal(rv, len); - if (!areEqual(rv, ct)) + byte[] ptByte = Hex.decode((String)map.get("Msg")); + byte[] expected = Hex.decode((String)map.get("MD")); + + byte[] hash = new byte[sparkle.getDigestSize()]; + + sparkle.update(ptByte, 0, ptByte.length); + sparkle.doFinal(hash, 0); + if (!areEqual(hash, expected)) { - mismatch("Keystream " + map.get("Count"), (String)map.get("CT"), rv); + mismatch("Keystream " + map.get("Count"), (String)map.get("MD"), hash); } -// else -// { -// System.out.println("Keystream " + map.get("Count") + " pass"); -// } - Sparkle.reset(); - Sparkle.init(false, params); - //Decrypt - Sparkle.processAADBytes(ad, 0, ad.length); - rv = new byte[pt.length]; - len = Sparkle.processBytes(ct, 0, ct.length, rv, 0); - Sparkle.doFinal(rv, len); - byte[] pt_recovered = new byte[pt.length]; - System.arraycopy(rv, 0, pt_recovered, 0, pt.length); - if (!areEqual(pt, pt_recovered)) + + if (ptByte.length > 1) { - mismatch("Reccover Keystream " + map.get("Count"), (String)map.get("PT"), pt_recovered); + int split = random.nextInt(ptByte.length - 1) + 1; + sparkle.update(ptByte, 0, split); + sparkle.update(ptByte, split, ptByte.length - split); + sparkle.doFinal(hash, 0); + if (!areEqual(hash, expected)) + { + mismatch("Keystream " + map.get("Count"), (String)map.get("MD"), hash); + } } - Sparkle.reset(); - map.clear(); + map.clear(); } else { map.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("Sparkle AEAD pass"); } - private void testVectorsHash(SparkleDigest.SparkleParameters sparkleParameters, String filename) + private void implTestVectorsEngine(SparkleEngine.SparkleParameters pbp, String filename) throws Exception { - SparkleDigest Sparkle = new SparkleDigest(sparkleParameters); - InputStream src = TestResourceFinder.findTestResource("crypto/sparkle", "LWC_HASH_KAT_" + filename + ".txt"); + Random random = new Random(); + SparkleEngine sparkle = createEngine(pbp); + InputStream src = TestResourceFinder.findTestResource("crypto/sparkle", "LWC_AEAD_KAT_" + + filename + ".txt"); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); String line; - byte[] ptByte; HashMap map = new HashMap(); while ((line = bin.readLine()) != null) { int a = line.indexOf('='); if (a < 0) { -// if (!map.get("Count").equals("3")) -// { -// continue; -// } - Sparkle.reset(); - ptByte = Hex.decode((String)map.get("Msg")); - Sparkle.update(ptByte, 0, ptByte.length); - byte[] hash = new byte[Sparkle.getDigestSize()]; - Sparkle.doFinal(hash, 0); - if (!areEqual(hash, Hex.decode((String)map.get("MD")))) + byte[] key = Hex.decode(map.get("Key")); + byte[] nonce = Hex.decode(map.get("Nonce")); + byte[] ad = Hex.decode(map.get("AD")); + byte[] pt = Hex.decode(map.get("PT")); + byte[] ct = Hex.decode(map.get("CT")); + + CipherParameters parameters = new ParametersWithIV(new KeyParameter(key), nonce); + + // Encrypt { - mismatch("Keystream " + map.get("Count"), (String)map.get("MD"), hash); + sparkle.init(true, parameters); + + byte[] rv = new byte[sparkle.getOutputSize(pt.length)]; + random.nextBytes(rv); // should overwrite any existing data + + sparkle.processAADBytes(ad, 0, ad.length); + int len = sparkle.processBytes(pt, 0, pt.length, rv, 0); + len += sparkle.doFinal(rv, len); + + if (!areEqual(rv, 0, len, ct, 0, ct.length)) + { + mismatch("Keystream " + map.get("Count"), (String)map.get("CT"), rv); + } } -// else -// { -// System.out.println("Keystream " + map.get("Count") + " pass"); -// } + + // Decrypt + { + sparkle.init(false, parameters); + + byte[] rv = new byte[sparkle.getOutputSize(ct.length)]; + random.nextBytes(rv); // should overwrite any existing data + + sparkle.processAADBytes(ad, 0, ad.length); + int len = sparkle.processBytes(ct, 0, ct.length, rv, 0); + len += sparkle.doFinal(rv, len); + + if (!areEqual(rv, 0, len, pt, 0, pt.length)) + { + mismatch("Reccover Keystream " + map.get("Count"), (String)map.get("PT"), rv); + } + } + map.clear(); - Sparkle.reset(); } else { map.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("Sparkle Hash pass"); } - private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, int blocksize) + private void implTestExceptionsEngine(SparkleEngine.SparkleParameters sparkleParameters) throws Exception { - CipherParameters params; + SparkleEngine sparkle = createEngine(sparkleParameters); + + int keysize = sparkle.getKeyBytesSize(), ivsize = sparkle.getIVBytesSize(); + int offset; byte[] k = new byte[keysize]; byte[] iv = new byte[ivsize]; byte[] m = new byte[0]; - byte[] c1 = new byte[aeadBlockCipher.getOutputSize(m.length)]; - params = new ParametersWithIV(new KeyParameter(k), iv); + CipherParameters params = new ParametersWithIV(new KeyParameter(k), iv); try { - aeadBlockCipher.processBytes(m, 0, m.length, c1, 0); - fail(aeadBlockCipher.getAlgorithmName() + " need to be initialed before processBytes"); + sparkle.processBytes(m, 0, m.length, null, 0); + fail(sparkle.getAlgorithmName() + " need to be initialized before processBytes"); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected } try { - aeadBlockCipher.processByte((byte)0, c1, 0); - fail(aeadBlockCipher.getAlgorithmName() + " need to be initialed before processByte"); + sparkle.processByte((byte)0, null, 0); + fail(sparkle.getAlgorithmName() + " need to be initialized before processByte"); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected } try { - aeadBlockCipher.reset(); - fail(aeadBlockCipher.getAlgorithmName() + " need to be initialed before reset"); + sparkle.reset(); + fail(sparkle.getAlgorithmName() + " need to be initialized before reset"); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected } try { - aeadBlockCipher.doFinal(c1, m.length); - fail(aeadBlockCipher.getAlgorithmName() + " need to be initialed before dofinal"); + sparkle.doFinal(null, m.length); + fail(sparkle.getAlgorithmName() + " need to be initialized before dofinal"); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected } try { - aeadBlockCipher.getMac(); - aeadBlockCipher.getAlgorithmName(); - aeadBlockCipher.getOutputSize(0); - aeadBlockCipher.getUpdateOutputSize(0); + sparkle.getMac(); + sparkle.getOutputSize(0); + sparkle.getUpdateOutputSize(0); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected - fail(aeadBlockCipher.getAlgorithmName() + " functions can be called before initialisation"); + fail(sparkle.getAlgorithmName() + " functions can be called before initialization"); } + Random rand = new Random(); int randomNum; while ((randomNum = rand.nextInt(100)) == keysize) ; @@ -229,8 +464,8 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, byte[] iv1 = new byte[randomNum]; try { - aeadBlockCipher.init(true, new ParametersWithIV(new KeyParameter(k1), iv)); - fail(aeadBlockCipher.getAlgorithmName() + " k size does not match"); + sparkle.init(true, new ParametersWithIV(new KeyParameter(k1), iv)); + fail(sparkle.getAlgorithmName() + " k size does not match"); } catch (IllegalArgumentException e) { @@ -238,8 +473,8 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, } try { - aeadBlockCipher.init(true, new ParametersWithIV(new KeyParameter(k), iv1)); - fail(aeadBlockCipher.getAlgorithmName() + "iv size does not match"); + sparkle.init(true, new ParametersWithIV(new KeyParameter(k), iv1)); + fail(sparkle.getAlgorithmName() + "iv size does not match"); } catch (IllegalArgumentException e) { @@ -248,67 +483,67 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, try { - aeadBlockCipher.init(true, new AEADParameters(new KeyParameter(k), 0, iv)); - fail(aeadBlockCipher.getAlgorithmName() + " wrong type of CipherParameters"); + sparkle.init(true, new AEADParameters(new KeyParameter(k), 0, iv)); + fail(sparkle.getAlgorithmName() + " wrong type of CipherParameters"); } catch (IllegalArgumentException e) { //expected } - aeadBlockCipher.init(true, params); + sparkle.init(true, params); + byte[] c1 = new byte[sparkle.getOutputSize(m.length)]; try { - aeadBlockCipher.doFinal(c1, m.length); + sparkle.doFinal(c1, m.length); } catch (Exception e) { - fail(aeadBlockCipher.getAlgorithmName() + " allows no input for AAD and plaintext"); + fail(sparkle.getAlgorithmName() + " allows no input for AAD and plaintext"); } - byte[] mac2 = aeadBlockCipher.getMac(); + byte[] mac2 = sparkle.getMac(); if (mac2 == null) { - fail(aeadBlockCipher.getAlgorithmName() + ": mac should not be empty after dofinal"); + fail("mac should not be empty after dofinal"); } if (!areEqual(mac2, c1)) { - fail(aeadBlockCipher.getAlgorithmName() + ": mac should be equal when calling dofinal and getMac"); + fail("mac should be equal when calling dofinal and getMac"); } - - aeadBlockCipher.reset(); - aeadBlockCipher.processAADByte((byte)0); - byte[] mac1 = new byte[aeadBlockCipher.getOutputSize(0)]; - aeadBlockCipher.doFinal(mac1, 0); + sparkle.init(true, params); + sparkle.processAADByte((byte)0); + byte[] mac1 = new byte[sparkle.getOutputSize(0)]; + sparkle.doFinal(mac1, 0); if (areEqual(mac1, mac2)) { - fail(aeadBlockCipher.getAlgorithmName() + ": mac should not match"); + fail("mac should not match"); } - aeadBlockCipher.reset(); - aeadBlockCipher.processBytes(new byte[blocksize + 1], 0, blocksize + 1, new byte[blocksize + 1], 0); + sparkle.init(true, params); + sparkle.processByte((byte)0, null, 0); try { - aeadBlockCipher.processAADByte((byte)0); - fail(aeadBlockCipher.getAlgorithmName() + ": processAADByte(s) cannot be called after encryption/decryption"); + sparkle.processAADByte((byte)0); + fail("processAADByte(s) cannot be called after encryption/decryption"); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected } try { - aeadBlockCipher.processAADBytes(new byte[]{0}, 0, 1); - fail(aeadBlockCipher.getAlgorithmName() + ": processAADByte(s) cannot be called once only"); + sparkle.processAADBytes(new byte[]{0}, 0, 1); + fail("processAADByte(s) cannot be called once only"); } - catch (IllegalArgumentException e) + catch (IllegalStateException e) { //expected } - aeadBlockCipher.reset(); + sparkle.reset(); try { - aeadBlockCipher.processAADBytes(new byte[]{0}, 1, 1); - fail(aeadBlockCipher.getAlgorithmName() + ": input for processAADBytes is too short"); + sparkle.processAADBytes(new byte[]{0}, 1, 1); + fail("input for processAADBytes is too short"); } catch (DataLengthException e) { @@ -316,17 +551,19 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, } try { - aeadBlockCipher.processBytes(new byte[]{0}, 1, 1, c1, 0); - fail(aeadBlockCipher.getAlgorithmName() + ": input for processBytes is too short"); + sparkle.processBytes(new byte[]{0}, 1, 1, c1, 0); + fail("input for processBytes is too short"); } catch (DataLengthException e) { //expected } + sparkle.init(true, params); try { - aeadBlockCipher.processBytes(new byte[blocksize + 1], 0, blocksize + 1, new byte[blocksize + 1], blocksize >> 1); - fail(aeadBlockCipher.getAlgorithmName() + ": output for processBytes is too short"); + int need = sparkle.getUpdateOutputSize(64); + sparkle.processBytes(new byte[64], 0, 64, new byte[need], 1); + fail("output for processBytes is too short"); } catch (OutputLengthException e) { @@ -334,160 +571,190 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, } try { - aeadBlockCipher.doFinal(new byte[2], 2); - fail(aeadBlockCipher.getAlgorithmName() + ": output for dofinal is too short"); + sparkle.doFinal(new byte[2], 2); + fail("output for dofinal is too short"); } - catch (DataLengthException e) + catch (OutputLengthException e) { //expected } - mac1 = new byte[aeadBlockCipher.getOutputSize(0)]; - mac2 = new byte[aeadBlockCipher.getOutputSize(0)]; - aeadBlockCipher.reset(); - aeadBlockCipher.processAADBytes(new byte[]{0, 0}, 0, 2); - aeadBlockCipher.doFinal(mac1, 0); - aeadBlockCipher.reset(); - aeadBlockCipher.processAADByte((byte)0); - aeadBlockCipher.processAADByte((byte)0); - aeadBlockCipher.doFinal(mac2, 0); + implTestExceptionsGetUpdateOutputSize(sparkle, false, params, 100); + implTestExceptionsGetUpdateOutputSize(sparkle, true, params, 100); + + mac1 = new byte[sparkle.getOutputSize(0)]; + mac2 = new byte[sparkle.getOutputSize(0)]; + sparkle.init(true, params); + sparkle.processAADBytes(new byte[]{0, 0}, 0, 2); + sparkle.doFinal(mac1, 0); + sparkle.init(true, params); + sparkle.processAADByte((byte)0); + sparkle.processAADByte((byte)0); + sparkle.doFinal(mac2, 0); if (!areEqual(mac1, mac2)) { - fail(aeadBlockCipher.getAlgorithmName() + ": mac should match for the same AAD with different ways of inputing"); + fail("mac should match for the same AAD with different ways of inputing"); } - byte[] c2 = new byte[aeadBlockCipher.getOutputSize(10)]; - byte[] c3 = new byte[aeadBlockCipher.getOutputSize(10) + 2]; + byte[] c2 = new byte[sparkle.getOutputSize(10)]; + byte[] c3 = new byte[sparkle.getOutputSize(10) + 2]; byte[] aad2 = {0, 1, 2, 3, 4}; byte[] aad3 = {0, 0, 1, 2, 3, 4, 5}; byte[] m2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; byte[] m3 = {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; byte[] m4 = new byte[m2.length]; - aeadBlockCipher.reset(); - aeadBlockCipher.processAADBytes(aad2, 0, aad2.length); - int offset = aeadBlockCipher.processBytes(m2, 0, m2.length, c2, 0); - aeadBlockCipher.doFinal(c2, offset); - aeadBlockCipher.reset(); - aeadBlockCipher.processAADBytes(aad3, 1, aad2.length); - offset = aeadBlockCipher.processBytes(m3, 1, m2.length, c3, 1); - aeadBlockCipher.doFinal(c3, offset + 1); + sparkle.init(true, params); + sparkle.processAADBytes(aad2, 0, aad2.length); + offset = sparkle.processBytes(m2, 0, m2.length, c2, 0); + sparkle.doFinal(c2, offset); + sparkle.init(true, params); + sparkle.processAADBytes(aad3, 1, aad2.length); + offset = sparkle.processBytes(m3, 1, m2.length, c3, 1); + sparkle.doFinal(c3, offset + 1); byte[] c3_partial = new byte[c2.length]; System.arraycopy(c3, 1, c3_partial, 0, c2.length); if (!areEqual(c2, c3_partial)) { - fail(aeadBlockCipher.getAlgorithmName() + ": mac should match for the same AAD and message with different offset for both input and output"); + fail("mac should match for the same AAD and message with different offset for both input and output"); } - aeadBlockCipher.reset(); - aeadBlockCipher.init(false, params); - aeadBlockCipher.processAADBytes(aad2, 0, aad2.length); - offset = aeadBlockCipher.processBytes(c2, 0, c2.length, m4, 0); - aeadBlockCipher.doFinal(m4, offset); + sparkle.init(false, params); + sparkle.processAADBytes(aad2, 0, aad2.length); + offset = sparkle.processBytes(c2, 0, c2.length, m4, 0); + sparkle.doFinal(m4, offset); if (!areEqual(m2, m4)) { - fail(aeadBlockCipher.getAlgorithmName() + ": The encryption and decryption does not recover the plaintext"); + fail("The encryption and decryption does not recover the plaintext"); } - c2[c2.length - 1] ^= 1; - aeadBlockCipher.reset(); - aeadBlockCipher.init(false, params); - aeadBlockCipher.processAADBytes(aad2, 0, aad2.length); - offset = aeadBlockCipher.processBytes(c2, 0, c2.length, m4, 0); + sparkle.init(false, params); + sparkle.processAADBytes(aad2, 0, aad2.length); + offset = sparkle.processBytes(c2, 0, c2.length, m4, 0); try { - aeadBlockCipher.doFinal(m4, offset); - fail(aeadBlockCipher.getAlgorithmName() + ": The decryption should fail"); + sparkle.doFinal(m4, offset); + fail("The decryption should fail"); } - catch (IllegalArgumentException e) + catch (InvalidCipherTextException e) { //expected; } - byte[] m7 = new byte[blocksize * 2]; - for (int i = 0; i < m7.length; ++i) - { - m7[i] = (byte)rand.nextInt(); - } - byte[] c7 = new byte[aeadBlockCipher.getOutputSize(m7.length)]; + byte[] m7 = new byte[32 + rand.nextInt(32)]; + rand.nextBytes(m7); + + sparkle.init(true, params); + byte[] c7 = new byte[sparkle.getOutputSize(m7.length)]; byte[] c8 = new byte[c7.length]; byte[] c9 = new byte[c7.length]; - aeadBlockCipher.init(true, params); - aeadBlockCipher.processAADBytes(aad2, 0, aad2.length); - offset = aeadBlockCipher.processBytes(m7, 0, m7.length, c7, 0); - aeadBlockCipher.doFinal(c7, offset); - aeadBlockCipher.reset(); - aeadBlockCipher.processAADBytes(aad2, 0, aad2.length); - offset = aeadBlockCipher.processBytes(m7, 0, blocksize, c8, 0); - offset += aeadBlockCipher.processBytes(m7, blocksize, m7.length - blocksize, c8, offset); - aeadBlockCipher.doFinal(c8, offset); - aeadBlockCipher.reset(); - int split = rand.nextInt(blocksize * 2); - aeadBlockCipher.processAADBytes(aad2, 0, aad2.length); - offset = aeadBlockCipher.processBytes(m7, 0, split, c9, 0); - offset += aeadBlockCipher.processBytes(m7, split, m7.length - split, c9, offset); - aeadBlockCipher.doFinal(c9, offset); + sparkle.processAADBytes(aad2, 0, aad2.length); + offset = sparkle.processBytes(m7, 0, m7.length, c7, 0); + sparkle.doFinal(c7, offset); + + sparkle.init(true, params); + sparkle.processAADBytes(aad2, 0, aad2.length); + offset = sparkle.processBytes(m7, 0, m7.length / 2, c8, 0); + offset += sparkle.processBytes(m7, m7.length / 2, m7.length - m7.length / 2, c8, offset); + sparkle.doFinal(c8, offset); + + sparkle.init(true, params); + int split = rand.nextInt(m7.length - 1) + 1; + sparkle.processAADBytes(aad2, 0, aad2.length); + offset = sparkle.processBytes(m7, 0, split, c9, 0); + offset += sparkle.processBytes(m7, split, m7.length - split, c9, offset); + sparkle.doFinal(c9, offset); + if (!areEqual(c7, c8) || !areEqual(c7, c9)) { - fail(aeadBlockCipher.getAlgorithmName() + ": Splitting input of plaintext should output the same ciphertext"); + fail("Splitting input of plaintext should output the same ciphertext"); } - System.out.println(aeadBlockCipher.getAlgorithmName() + " test Exceptions pass"); } - private void testParameters(SparkleEngine isap, int keySize, int ivSize, int macSize) + private void implTestExceptionsGetUpdateOutputSize(SparkleEngine sparkle, boolean forEncryption, + CipherParameters parameters, int maxInputSize) { - if (isap.getKeyBytesSize() != keySize) - { - fail(isap.getAlgorithmName() + ": key bytes of " + isap.getAlgorithmName() + " is not correct"); - } - if (isap.getIVBytesSize() != ivSize) - { - fail(isap.getAlgorithmName() + ": iv bytes of " + isap.getAlgorithmName() + " is not correct"); - } - if (isap.getOutputSize(0) != macSize) + sparkle.init(forEncryption, parameters); + + int maxOutputSize = sparkle.getUpdateOutputSize(maxInputSize); + + byte[] input = new byte[maxInputSize]; + byte[] output = new byte[maxOutputSize]; + + for (int inputSize = 0; inputSize <= maxInputSize; ++inputSize) { - fail(isap.getAlgorithmName() + ": mac bytes of " + isap.getAlgorithmName() + " is not correct"); + sparkle.init(forEncryption, parameters); + + int outputSize = sparkle.getUpdateOutputSize(inputSize); + if (outputSize > 0) + { + try + { + sparkle.processBytes(input, 0, inputSize, output, maxOutputSize - outputSize + 1); + fail("output for processBytes is too short"); + } + catch (OutputLengthException e) + { + //expected + } + } + else + { + sparkle.processBytes(input, 0, inputSize, null, 0); + } } - System.out.println(isap.getAlgorithmName() + " test Parameters pass"); } - private void testExceptions(Digest digest, int digestsize) + private void implTestParametersDigest(SparkleDigest.SparkleParameters sparkleParameters, int digestSize) { - if (digest.getDigestSize() != digestsize) + SparkleDigest sparkle = createDigest(sparkleParameters); + + if (sparkle.getDigestSize() != digestSize) { - fail(digest.getAlgorithmName() + ": digest size is not correct"); + fail(sparkle.getAlgorithmName() + ": digest size is not correct"); } + } - try + private void implTestParametersEngine(SparkleEngine.SparkleParameters sparkleParameters, int keySize, int ivSize, + int macSize) + { + SparkleEngine sparkle = createEngine(sparkleParameters); + + if (sparkle.getKeyBytesSize() != keySize) { - digest.update(new byte[1], 1, 1); - fail(digest.getAlgorithmName() + ": input for update is too short"); + fail("key bytes of " + sparkle.getAlgorithmName() + " is not correct"); } - catch (DataLengthException e) + if (sparkle.getIVBytesSize() != ivSize) { - //expected + fail("iv bytes of " + sparkle.getAlgorithmName() + " is not correct"); } - try + + CipherParameters parameters = new ParametersWithIV(new KeyParameter(new byte[keySize]), new byte[ivSize]); + + sparkle.init(true, parameters); + if (sparkle.getOutputSize(0) != macSize) { - digest.doFinal(new byte[digest.getDigestSize() - 1], 2); - fail(digest.getAlgorithmName() + ": output for dofinal is too short"); + fail("getOutputSize of " + sparkle.getAlgorithmName() + " is incorrect for encryption"); } - catch (DataLengthException e) + + sparkle.init(false, parameters); + if (sparkle.getOutputSize(macSize) != 0) { - //expected + fail("getOutputSize of " + sparkle.getAlgorithmName() + " is incorrect for decryption"); } - System.out.println(digest.getAlgorithmName() + " test Exceptions pass"); } - private void mismatch(String name, String expected, byte[] found) { fail("mismatch on " + name, expected, new String(Hex.encode(found))); } - public static void main(String[] args) + private static void initEngine(SparkleEngine sparkle, boolean forEncryption) { - runTest(new SparkleTest()); + int keySize = sparkle.getKeyBytesSize(); + int ivSize = sparkle.getIVBytesSize(); + int macSize = keySize * 8; + + AEADParameters parameters = new AEADParameters(new KeyParameter(new byte[keySize]), macSize, new byte[ivSize], null); + sparkle.init(forEncryption, parameters); } } - - diff --git a/core/src/test/java/org/bouncycastle/crypto/test/TupleHashTest.java b/core/src/test/java/org/bouncycastle/crypto/test/TupleHashTest.java index ad9866effa..0ed9d3d1c4 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/TupleHashTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/TupleHashTest.java @@ -1,5 +1,6 @@ package org.bouncycastle.crypto.test; +import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.TupleHash; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; @@ -100,6 +101,39 @@ public void performTest() isTrue("oops!", !Arrays.areEqual(Hex.decode("45 00 0B E6 3F 9B 6B FD 89 F5 47 17 67 0F 69 A9 BC 76 35 91 A4 F0 5C 50 D6 88 91 A7 44 BC C6 E7 D6 D5 B5 E8 2C 01 8D A9 99 ED 35 B0 BB 49 C9 67 8E 52 6A BD 8E 85 C1 3E D2 54 02 1D B9 E7 90 CE"), res)); isTrue("oops!", Arrays.areEqual(Hex.decode("0c59b11464f2336c34663ed51b2b950bec743610856f36c28d1d088d8a2446284dd09830a6a178dc752376199fae935d86cfdee5913d4922dfd369b66a53c897"), res)); + + testClone(); + } + + private void testClone() + { + Digest digest = new TupleHash(256, Strings.toByteArray("My Tuple App")); + byte[] expected = Hex.decode("45 00 0B E6 3F 9B 6B FD 89 F5 47 17 67 0F 69 A9 BC 76 35 91 A4 F0 5C 50 D6 88 91 A7 44 BC C6 E7 D6 D5 B5 E8 2C 01 8D A9 99 ED 35 B0 BB 49 C9 67 8E 52 6A BD 8E 85 C1 3E D2 54 02 1D B9 E7 90 CE"); + byte[] resBuf = new byte[expected.length]; + + digest.update(Hex.decode("000102"), 0, 3); + digest.update(Hex.decode("101112131415"), 0, 6); + + // clone the Digest + Digest d = new TupleHash((TupleHash)digest); + + digest.update(Hex.decode("202122232425262728"), 0, 9); + + digest.doFinal(resBuf, 0); + + if (!areEqual(expected, resBuf)) + { + fail("failing clone vector test", Hex.toHexString(expected), new String(Hex.encode(resBuf))); + } + + d.update(Hex.decode("202122232425262728"), 0, 9); + + d.doFinal(resBuf, 0); + + if (!areEqual(expected, resBuf)) + { + fail("failing second clone vector test", Hex.toHexString(expected), new String(Hex.encode(resBuf))); + } } public static void main( diff --git a/core/src/test/java/org/bouncycastle/crypto/test/WhirlpoolDigestTest.java b/core/src/test/java/org/bouncycastle/crypto/test/WhirlpoolDigestTest.java index 542e6e6b6b..d7e1aaa96d 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/WhirlpoolDigestTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/WhirlpoolDigestTest.java @@ -1,11 +1,10 @@ package org.bouncycastle.crypto.test; import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.WhirlpoolDigest; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; -import org.bouncycastle.util.test.SimpleTest; /** * ISO vector test for Whirlpool @@ -81,7 +80,7 @@ private void performStandardVectorTest(String testTitle, byte[] inputBytes, private void doPerformTest(String testTitle, byte[] inputBytes, String resultsAsHex) { String resStr = createHexOutputFromDigest(inputBytes); - if (!resultsAsHex.equals(resStr.toUpperCase())) + if (!resultsAsHex.equals(Strings.toUpperCase(resStr))) { fail(testTitle, resultsAsHex, resStr); } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/XoodyakTest.java b/core/src/test/java/org/bouncycastle/crypto/test/XoodyakTest.java index 0a78756f7c..268f417830 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/XoodyakTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/XoodyakTest.java @@ -78,7 +78,7 @@ private void testVectorsHash() map.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("Xoodyak Hash pass"); +// System.out.println("Xoodyak Hash pass"); } private void testVectors() @@ -140,7 +140,7 @@ private void testVectors() map.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("Xoodyak AEAD pass"); +// System.out.println("Xoodyak AEAD pass"); } private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, int blocksize) @@ -413,7 +413,7 @@ private void testExceptions(AEADCipher aeadBlockCipher, int keysize, int ivsize, { fail(aeadBlockCipher.getAlgorithmName() + ": Splitting input of plaintext should output the same ciphertext"); } - System.out.println(aeadBlockCipher.getAlgorithmName() + " test Exceptions pass"); +// System.out.println(aeadBlockCipher.getAlgorithmName() + " test Exceptions pass"); } private void testParameters(XoodyakEngine isap, int keySize, int ivSize, int macSize) @@ -430,7 +430,7 @@ private void testParameters(XoodyakEngine isap, int keySize, int ivSize, int mac { fail(isap.getAlgorithmName() + ": mac bytes of " + isap.getAlgorithmName() + " is not correct"); } - System.out.println(isap.getAlgorithmName() + " test Parameters pass"); +// System.out.println(isap.getAlgorithmName() + " test Parameters pass"); } @@ -459,7 +459,7 @@ private void testExceptions(Digest digest, int digestsize) { //expected } - System.out.println(digest.getAlgorithmName() + " test Exceptions pass"); +// System.out.println(digest.getAlgorithmName() + " test Exceptions pass"); } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/cavp/CAVPReader.java b/core/src/test/java/org/bouncycastle/crypto/test/cavp/CAVPReader.java index 596c2d498f..7d8cdabbab 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/cavp/CAVPReader.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/cavp/CAVPReader.java @@ -109,7 +109,7 @@ static Mac createPRF(Properties config) final Mac prf; if (config.getProperty("PRF").matches("CMAC_AES\\d\\d\\d")) { - BlockCipher blockCipher = new AESEngine(); + BlockCipher blockCipher = AESEngine.newInstance(); prf = new CMac(blockCipher); } else if (config.getProperty("PRF").matches("CMAC_TDES\\d")) @@ -129,7 +129,7 @@ else if (config.getProperty("PRF").matches("HMAC_SHA224")) } else if (config.getProperty("PRF").matches("HMAC_SHA256")) { - Digest digest = new SHA256Digest(); + Digest digest = SHA256Digest.newInstance(); prf = new HMac(digest); } else if (config.getProperty("PRF").matches("HMAC_SHA384")) diff --git a/core/src/test/java/org/bouncycastle/crypto/test/speedy/MacThroughputTest.java b/core/src/test/java/org/bouncycastle/crypto/test/speedy/MacThroughputTest.java index 8249fd18c5..81401c3966 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/speedy/MacThroughputTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/speedy/MacThroughputTest.java @@ -6,7 +6,7 @@ import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.digests.SHA1Digest; -import org.bouncycastle.crypto.engines.AESFastEngine; +import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.engines.NullEngine; import org.bouncycastle.crypto.generators.Poly1305KeyGenerator; import org.bouncycastle.crypto.macs.CMac; @@ -59,11 +59,11 @@ public static void main(String[] args) testMac(new HMac(new SHA1Digest()), new KeyParameter(generateNonce(20)), 3); testMac(new SkeinMac(SkeinMac.SKEIN_512, 128), new KeyParameter(generateNonce(64)), 2); testMac(new SipHash(), new KeyParameter(generateNonce(16)), 1); - testMac(new CMac(new AESFastEngine()), new KeyParameter(generateNonce(16)), 3); - testMac(new GMac(new GCMBlockCipher(new AESFastEngine())), new ParametersWithIV(new KeyParameter( + testMac(new CMac(AESEngine.newInstance()), new KeyParameter(generateNonce(16)), 3); + testMac(new GMac(new GCMBlockCipher(AESEngine.newInstance())), new ParametersWithIV(new KeyParameter( generateNonce(16)), generateNonce(16)), 5); testMac(new Poly1305(new NullEngine(16)), new ParametersWithIV(generatePoly1305Key(), generateNonce(16)), 1); - testMac(new Poly1305(new AESFastEngine()), new ParametersWithIV(generatePoly1305Key(), generateNonce(16)), 1); + testMac(new Poly1305(AESEngine.newInstance()), new ParametersWithIV(generatePoly1305Key(), generateNonce(16)), 1); testMac(new Poly1305Reference(new NullEngine(16)), new ParametersWithIV(generatePoly1305Key(), generateNonce(16)), 1); } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/speedy/ThreefishReferenceEngine.java b/core/src/test/java/org/bouncycastle/crypto/test/speedy/ThreefishReferenceEngine.java index a702f3b92c..5d8e9b3245 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/speedy/ThreefishReferenceEngine.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/speedy/ThreefishReferenceEngine.java @@ -69,7 +69,7 @@ public void init(boolean forEncryption, TweakableBlockCipherParameters params) // TODO: Remove some of the NPEs that can be avoided in the Params // classes if ((params.getKey() == null) || (params.getKey().getKey() == null) - || (params.getKey().getKey().length != blocksize)) + || (params.getKey().getKeyLength() != blocksize)) { throw new IllegalArgumentException("Threefish key must be same size as block (%d bytes)" + blocksize); } diff --git a/core/src/test/java/org/bouncycastle/crypto/test/speedy/ThroughputTest.java b/core/src/test/java/org/bouncycastle/crypto/test/speedy/ThroughputTest.java index 7c090f8a60..a5e3aa6bf2 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/speedy/ThroughputTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/speedy/ThroughputTest.java @@ -4,7 +4,7 @@ import java.security.SecureRandom; import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.engines.AESFastEngine; +import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.engines.ThreefishEngine; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.TweakableBlockCipherParameters; @@ -38,7 +38,7 @@ public static void main(String[] args) // speedTestCipher(new Skein3FishEngine(), input); // speedTestCipher(new ThreefishEngine(ThreefishEngine.BLOCKSIZE_1024), input); // speedTestCipher(new ThreefishReferenceEngine(), input); - speedTestCipher(new AESFastEngine(), input); + speedTestCipher(AESEngine.newInstance(), input); // speedTestCipher(new TwofishEngine(), input); // speedTestCipher(new BlowfishEngine(), input); } diff --git a/core/src/test/java/org/bouncycastle/i18n/test/LocalizedMessageTest.java b/core/src/test/java/org/bouncycastle/i18n/test/LocalizedMessageTest.java index 5cbc7a43da..e75e59cd0b 100644 --- a/core/src/test/java/org/bouncycastle/i18n/test/LocalizedMessageTest.java +++ b/core/src/test/java/org/bouncycastle/i18n/test/LocalizedMessageTest.java @@ -13,6 +13,8 @@ import org.bouncycastle.i18n.MissingEntryException; import org.bouncycastle.i18n.filter.HTMLFilter; import org.bouncycastle.i18n.filter.TrustedInput; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Hex; public class LocalizedMessageTest extends TestCase { @@ -29,6 +31,7 @@ public class LocalizedMessageTest extends TestCase private static final String missingTestId = "missing"; private static final String filterTestId = "filter"; private static final String utf8TestId = "utf8"; + private static final String NNBSP = Strings.fromUTF8ByteArray(Hex.decode("e280af")); /* * Test method for 'org.bouncycastle.i18n.LocalizedMessage.getEntry(String, @@ -60,7 +63,7 @@ public void testGetEntry() msg = new LocalizedMessage(TEST_RESOURCE, timeTestId, args); assertEquals("It's 1:12:00 PM GMT at Aug 17, 2006.", msg.getEntry( "text", Locale.ENGLISH, TimeZone.getTimeZone("GMT")) - .replace("Greenwich Mean Time", "GMT")); + .replace("Greenwich Mean Time", "GMT").replace(NNBSP, " ")); // NOTE: Older JDKs appear to use '.' as the time separator for German locale assertEquals("Es ist 13:12 Uhr GMT am 17.08.2006.", msg.getEntry( "text", Locale.GERMAN, TimeZone.getTimeZone("GMT")) @@ -73,15 +76,15 @@ public void testGetEntry() msg.setFilter(new HTMLFilter()); assertEquals("It's 1:12:00 PM GMT at Aug 17, 2006.", msg.getEntry( "text", Locale.ENGLISH, TimeZone.getTimeZone("GMT")) - .replace("Greenwich Mean Time", "GMT")); + .replace("Greenwich Mean Time", "GMT").replace(NNBSP, " ")); // NOTE: Older JDKs appear to use '.' as the time separator for German locale assertEquals("Es ist 13:12 Uhr GMT am 17.08.2006.", msg.getEntry( "text", Locale.GERMAN, TimeZone.getTimeZone("GMT")) .replace("13.12", "13:12") - .replace(":00 Mittlere Greenwich-Zeit", " Uhr GMT")); + .replace(":00 Mittlere Greenwich-Zeit", " Uhr GMT").replace(NNBSP, " ")); // test number - args = new Object[] { new TrustedInput(new Float(0.2)) }; + args = new Object[] { new TrustedInput(new Float(0.2f)) }; msg = new LocalizedMessage(TEST_RESOURCE, "number", args); assertEquals("20%", msg.getEntry("text", Locale.ENGLISH, TimeZone.getDefault())); @@ -186,5 +189,4 @@ public void testLocalizedArgs() assertEquals("Can't find entry noname in resource file org.bouncycastle.i18n.test.I18nTestMessages.", e.getMessage()); } } - } diff --git a/core/src/test/java/org/bouncycastle/math/ec/rfc7748/test/X25519Test.java b/core/src/test/java/org/bouncycastle/math/ec/rfc7748/test/X25519Test.java index 380a111bba..7959952922 100644 --- a/core/src/test/java/org/bouncycastle/math/ec/rfc7748/test/X25519Test.java +++ b/core/src/test/java/org/bouncycastle/math/ec/rfc7748/test/X25519Test.java @@ -49,19 +49,19 @@ public void testECDH() for (int i = 1; i <= 100; ++i) { // Each party generates an ephemeral private key, ... - RANDOM.nextBytes(kA); - RANDOM.nextBytes(kB); + X25519.generatePrivateKey(RANDOM, kA); + X25519.generatePrivateKey(RANDOM, kB); // ... publishes their public key, ... - X25519.scalarMultBase(kA, 0, qA, 0); - X25519.scalarMultBase(kB, 0, qB, 0); + X25519.generatePublicKey(kA, 0, qA, 0); + X25519.generatePublicKey(kB, 0, qB, 0); // ... computes the shared secret, ... - X25519.scalarMult(kA, 0, qB, 0, sA, 0); - X25519.scalarMult(kB, 0, qA, 0, sB, 0); + boolean rA = X25519.calculateAgreement(kA, 0, qB, 0, sA, 0); + boolean rB = X25519.calculateAgreement(kB, 0, qA, 0, sB, 0); // ... which is the same for both parties. - assertTrue("ECDH #" + i, Arrays.areEqual(sA, sB)); + assertTrue("ECDH #" + i, rA == rB && Arrays.areEqual(sA, sB)); } } diff --git a/core/src/test/java/org/bouncycastle/math/ec/rfc7748/test/X448Test.java b/core/src/test/java/org/bouncycastle/math/ec/rfc7748/test/X448Test.java index aa27baf903..93f63c9dc2 100644 --- a/core/src/test/java/org/bouncycastle/math/ec/rfc7748/test/X448Test.java +++ b/core/src/test/java/org/bouncycastle/math/ec/rfc7748/test/X448Test.java @@ -50,19 +50,19 @@ public void testECDH() for (int i = 1; i <= 100; ++i) { // Each party generates an ephemeral private key, ... - RANDOM.nextBytes(kA); - RANDOM.nextBytes(kB); + X448.generatePrivateKey(RANDOM, kA); + X448.generatePrivateKey(RANDOM, kB); // ... publishes their public key, ... - X448.scalarMultBase(kA, 0, qA, 0); - X448.scalarMultBase(kB, 0, qB, 0); + X448.generatePublicKey(kA, 0, qA, 0); + X448.generatePublicKey(kB, 0, qB, 0); // ... computes the shared secret, ... - X448.scalarMult(kA, 0, qB, 0, sA, 0); - X448.scalarMult(kB, 0, qA, 0, sB, 0); + boolean rA = X448.calculateAgreement(kA, 0, qB, 0, sA, 0); + boolean rB = X448.calculateAgreement(kB, 0, qA, 0, sB, 0); // ... which is the same for both parties. - assertTrue("ECDH #" + i, Arrays.areEqual(sA, sB)); + assertTrue("ECDH #" + i, rA == rB && Arrays.areEqual(sA, sB)); } } diff --git a/core/src/test/java/org/bouncycastle/math/ec/rfc8032/test/Ed25519Test.java b/core/src/test/java/org/bouncycastle/math/ec/rfc8032/test/Ed25519Test.java index 2a46ee9df4..64a8232e68 100644 --- a/core/src/test/java/org/bouncycastle/math/ec/rfc8032/test/Ed25519Test.java +++ b/core/src/test/java/org/bouncycastle/math/ec/rfc8032/test/Ed25519Test.java @@ -36,7 +36,7 @@ public void testEd25519Consistency() for (int i = 0; i < 10; ++i) { - RANDOM.nextBytes(sk); + Ed25519.generatePrivateKey(RANDOM, sk); Ed25519.PublicPoint publicPoint = Ed25519.generatePublicKey(sk, 0); Ed25519.encodePublicPoint(publicPoint, pk, 0); @@ -95,7 +95,7 @@ public void testEd25519ctxConsistency() for (int i = 0; i < 10; ++i) { - RANDOM.nextBytes(sk); + Ed25519.generatePrivateKey(RANDOM, sk); Ed25519.PublicPoint publicPoint = Ed25519.generatePublicKey(sk, 0); Ed25519.encodePublicPoint(publicPoint, pk, 0); @@ -155,7 +155,7 @@ public void testEd25519phConsistency() for (int i = 0; i < 10; ++i) { - RANDOM.nextBytes(sk); + Ed25519.generatePrivateKey(RANDOM, sk); Ed25519.PublicPoint publicPoint = Ed25519.generatePublicKey(sk, 0); Ed25519.encodePublicPoint(publicPoint, pk, 0); @@ -443,7 +443,7 @@ public void testPublicKeyValidationFull() for (int i = 0; i < 10; ++i) { - RANDOM.nextBytes(sk); + Ed25519.generatePrivateKey(RANDOM, sk); Ed25519.generatePublicKey(sk, 0, pk, 0); assertTrue(Ed25519.validatePublicKeyFull(pk, 0)); } @@ -498,7 +498,7 @@ public void testPublicKeyValidationPartial() for (int i = 0; i < 10; ++i) { - RANDOM.nextBytes(sk); + Ed25519.generatePrivateKey(RANDOM, sk); Ed25519.generatePublicKey(sk, 0, pk, 0); assertTrue(Ed25519.validatePublicKeyPartial(pk, 0)); } diff --git a/core/src/test/java/org/bouncycastle/math/ec/rfc8032/test/Ed448Test.java b/core/src/test/java/org/bouncycastle/math/ec/rfc8032/test/Ed448Test.java index d78afc768c..c08a5985fb 100644 --- a/core/src/test/java/org/bouncycastle/math/ec/rfc8032/test/Ed448Test.java +++ b/core/src/test/java/org/bouncycastle/math/ec/rfc8032/test/Ed448Test.java @@ -37,7 +37,7 @@ public void testEd448Consistency() for (int i = 0; i < 10; ++i) { - RANDOM.nextBytes(sk); + Ed448.generatePrivateKey(RANDOM, sk); Ed448.PublicPoint publicPoint = Ed448.generatePublicKey(sk, 0); Ed448.encodePublicPoint(publicPoint, pk, 0); @@ -97,7 +97,7 @@ public void testEd448phConsistency() for (int i = 0; i < 10; ++i) { - RANDOM.nextBytes(sk); + Ed448.generatePrivateKey(RANDOM, sk); Ed448.PublicPoint publicPoint = Ed448.generatePublicKey(sk, 0); Ed448.encodePublicPoint(publicPoint, pk, 0); @@ -516,7 +516,7 @@ public void testPublicKeyValidationFull() for (int i = 0; i < 10; ++i) { - RANDOM.nextBytes(sk); + Ed448.generatePrivateKey(RANDOM, sk); Ed448.generatePublicKey(sk, 0, pk, 0); assertTrue(Ed448.validatePublicKeyFull(pk, 0)); } @@ -569,7 +569,7 @@ public void testPublicKeyValidationPartial() for (int i = 0; i < 10; ++i) { - RANDOM.nextBytes(sk); + Ed448.generatePrivateKey(RANDOM, sk); Ed448.generatePublicKey(sk, 0, pk, 0); assertTrue(Ed448.validatePublicKeyPartial(pk, 0)); } diff --git a/core/src/test/java/org/bouncycastle/math/ec/test/ECAlgorithmsTest.java b/core/src/test/java/org/bouncycastle/math/ec/test/ECAlgorithmsTest.java index 20b8d323c0..3cd053206a 100644 --- a/core/src/test/java/org/bouncycastle/math/ec/test/ECAlgorithmsTest.java +++ b/core/src/test/java/org/bouncycastle/math/ec/test/ECAlgorithmsTest.java @@ -5,8 +5,12 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Set; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECPoint; @@ -15,10 +19,6 @@ import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - public class ECAlgorithmsTest extends TestCase { private static final int SCALE = 4; @@ -34,7 +34,7 @@ public void testSumOfMultiplies() // TODO Ideally, mark this test not to run by default public void testSumOfMultipliesComplete() { - ArrayList x9s = getTestCurves(); + List x9s = getTestCurves(); Iterator it = x9s.iterator(); while (it.hasNext()) { @@ -53,7 +53,7 @@ public void testSumOfTwoMultiplies() // TODO Ideally, mark this test not to run by default public void testSumOfTwoMultipliesComplete() { - ArrayList x9s = getTestCurves(); + List x9s = getTestCurves(); Iterator it = x9s.iterator(); while (it.hasNext()) { @@ -140,9 +140,9 @@ private BigInteger getRandomScalar(X9ECParameters x9) return new BigInteger(x9.getN().bitLength(), RND); } - private ArrayList getTestCurves() + private List getTestCurves() { - ArrayList x9s = new ArrayList(); + List x9s = new ArrayList(); Set names = new HashSet(AllTests.enumToList(ECNamedCurveTable.getNames())); names.addAll(AllTests.enumToList(CustomNamedCurves.getNames())); @@ -166,7 +166,7 @@ private ArrayList getTestCurves() return x9s; } - private void addTestCurves(ArrayList x9s, X9ECParameters x9) + private void addTestCurves(List x9s, X9ECParameters x9) { ECCurve curve = x9.getCurve(); diff --git a/core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java b/core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java index f53c98287c..68fd639784 100644 --- a/core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java +++ b/core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java @@ -196,6 +196,25 @@ private void implTestAdd(ECPoint[] p, ECPoint infinity) } } + public void testLargeMInF2m() + { + int m = 2048; + int k1 = 1; + BigInteger aTpb = new BigInteger("1000", 2); + BigInteger bTpb = new BigInteger("1001", 2); + BigInteger n = new BigInteger("23"); + BigInteger h = new BigInteger("1"); + + try + { + ECCurve.F2m curve = new ECCurve.F2m(m, k1, aTpb, bTpb, n, h); + } + catch (IllegalArgumentException e) + { + assertEquals("field size out of range: 2048", e.getMessage()); + } + } + /** * Calls implTestAdd() for Fp and * F2m. diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/lms/HSSTests.java b/core/src/test/java/org/bouncycastle/pqc/crypto/lms/HSSTests.java index f5e12d8af8..b262701d99 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/lms/HSSTests.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/lms/HSSTests.java @@ -74,7 +74,7 @@ public void testHssKeySerialisation() public void testHSSVector_1() throws Exception { - ArrayList blocks = loadVector("testcase_1.txt"); + List blocks = loadVector("testcase_1.txt"); HSSPublicKeyParameters publicKey = HSSPublicKeyParameters.getInstance(blocks.get(0)); byte[] message = blocks.get(1); @@ -92,7 +92,7 @@ public void testHSSVector_2() throws Exception { - ArrayList blocks = loadVector("testcase_2.txt"); + List blocks = loadVector("testcase_2.txt"); HSSPublicKeyParameters publicKey = HSSPublicKeyParameters.getInstance(blocks.get(0)); byte[] message = blocks.get(1); @@ -108,13 +108,13 @@ public void testHSSVector_2() } - private ArrayList loadVector(String vector) + private List loadVector(String vector) throws Exception { InputStream inputStream = TestResourceFinder.findTestResource("pqc/crypto/lms", vector); BufferedReader bin = new BufferedReader(new InputStreamReader(inputStream)); String line; - ArrayList blocks = new ArrayList(); + List blocks = new ArrayList(); StringBuffer sw = new StringBuffer(); while ((line = bin.readLine()) != null) { @@ -416,7 +416,7 @@ else if (line.startsWith("Signature:")) { HSSSignature signatureFromVector = HSSSignature.getInstance(encodedSigFromVector, d); signatureFromVector.equals(sig); - System.out.println(); + // System.out.println(); } @@ -726,7 +726,7 @@ public void testSharding() HSS.generateSignature(keyPair, "Cats".getBytes()); - System.out.println(); + // System.out.println(); } @@ -867,7 +867,7 @@ public void nextBytes(byte[] bytes) ctr++; } - //System.out.println(ctr); + //// System.out.println(ctr); fail(); } catch (ExhaustedPrivateKeyException ex) diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/lms/TypeTests.java b/core/src/test/java/org/bouncycastle/pqc/crypto/lms/TypeTests.java index 32eee23f3b..4c656cdb18 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/lms/TypeTests.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/lms/TypeTests.java @@ -26,7 +26,7 @@ public void testTypeForType() } { - Object o = new HSSPublicKeyParameters(0, null); + Object o = new HSSPublicKeyParameters(0, new LMSPublicKeyParameters(null, null, null, null)); assert (o == HSSPublicKeyParameters.getInstance(o)); } diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/AllTests.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/AllTests.java index 526788b2cb..ee98f569b0 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/AllTests.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/AllTests.java @@ -34,11 +34,10 @@ public static Test suite() suite.addTestSuite(CMCEVectorTest.class); suite.addTestSuite(FrodoVectorTest.class); suite.addTestSuite(SABERVectorTest.class); - suite.addTestSuite(SIKEVectorTest.class); suite.addTestSuite(NTRUTest.class); suite.addTestSuite(NTRUParametersTest.class); suite.addTestSuite(FalconTest.class); - suite.addTestSuite(CrystalsKyberTest.class); + suite.addTestSuite(MLKEMTest.class); suite.addTestSuite(CrystalsDilithiumTest.class); suite.addTestSuite(NTRULPRimeTest.class); suite.addTestSuite(SNTRUPrimeTest.class); @@ -46,6 +45,7 @@ public static Test suite() suite.addTestSuite(HQCTest.class); suite.addTestSuite(RainbowVectorTest.class); suite.addTestSuite(GeMSSTest.class); + suite.addTestSuite(XWingTest.class); suite.addTestSuite(AllTests.SimpleTestTest.class); return new BCTestSetup(suite); diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/BIKETest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/BIKETest.java index b1a8edccab..f1ca00279a 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/BIKETest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/BIKETest.java @@ -82,7 +82,7 @@ public void testVectors() continue; } - System.out.println("test case: " + count); + // System.out.println("test case: " + count); byte[] seed = Hex.decode((String)buf.get("seed")); // seed for bike secure random byte[] pk = Hex.decode((String)buf.get("pk")); // public key byte[] sk = Hex.decode((String)buf.get("sk")); // private key @@ -134,7 +134,7 @@ public void testVectors() buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("Testing successful!"); + // System.out.println("Testing successful!"); } } } diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/CMCEVectorTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/CMCEVectorTest.java index 5162ec5a49..b5f4ef3480 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/CMCEVectorTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/CMCEVectorTest.java @@ -75,7 +75,7 @@ public void testVectors() for (int fileIndex = 0; fileIndex != files.length; fileIndex++) { String name = files[fileIndex]; - System.out.println("testing: " + name); + // System.out.println("testing: " + name); InputStream src = TestResourceFinder.findTestResource("pqc/crypto/cmce", name); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); @@ -98,7 +98,7 @@ public void testVectors() { continue; } - System.out.println("test case: " + count); + // System.out.println("test case: " + count); byte[] seed = Hex.decode((String)buf.get("seed")); // seed for cmce secure random byte[] pk = Hex.decode((String)buf.get("pk")); // public key byte[] sk = Hex.decode((String)buf.get("sk")); // private key @@ -151,7 +151,7 @@ public void testVectors() } - System.out.println("testing successful!"); + // System.out.println("testing successful!"); } } diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/CrystalsDilithiumTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/CrystalsDilithiumTest.java index d0c4762a01..99275515d2 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/CrystalsDilithiumTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/CrystalsDilithiumTest.java @@ -1,6 +1,7 @@ package org.bouncycastle.pqc.crypto.test; import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.security.SecureRandom; @@ -15,6 +16,10 @@ import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPrivateKeyParameters; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumSigner; +import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; +import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; +import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; +import org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory; import org.bouncycastle.test.TestResourceFinder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; @@ -23,80 +28,101 @@ public class CrystalsDilithiumTest extends TestCase { - - /* - count = 0 - seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 - mlen = 33 - msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 - pk = 1C0EE1111B08003F28E65E8B3BDEB037CF8F221DFCDAF5950EDB38D506D85BEFD9FDE3A496F75819F0A20D0441DC7830B4AA1CB8ECFC91BA0EEC3AFB6744E477B4E6EC3FDAE75048FFEBAABEA8E822117D5787F79070EA88287CE3CD5011FD8D93AB7E8B51F26116BF9B6D21C03F88BFEC488876F4D075A142D4E784D734407511F992069353F1DB67ACF73034A468A118588062111D320E00BCFF6DC63573FCED1E96AAEBA6452E3C7ACD19181F9B814BA19D39B4BAB5496DC055426E7EA461AF55D5B9FE97F9DF7E253203C1F9E152E96D75F9D9A84F5C263EC8C250440ADC986F4E36414C703B3E05426B28B7065950DA6D0E0B2C60AC3672DB6F3C78447DB7C20915770EA6FCE81DAB5339C1D5AF82A5D3324099DF56516A07DB7C0FC64383805C65F2B02FBCFCE63E93C4BF09409F9F0F77E73DA3B0019F2057E4CD7CFF0E5745EF18C3FD766E01747A64D415FC9789ABFA62284E11C7FF05D0548D973F679559A6A3AAD77ED5132D0150C014C3EC3A395F017E7ACFE3EABFCA44910CA06FF33542ECCE6241974742357D37F5C284BF0FE1A74B50C073551372133AF2DD41E21BAFC9C590EE6EBC4ACE731EF566156CA03755DC493C137028AF3B3DE5B00BD6CB3D9A87D0151F887C6768BC6CA02A94FB2086551A0F89BA26154E9D4506AD9FAF39F5723E234E06CFDED69D4EE4146B73E5DC1E4152A2A3159D73DBC833D3D417CD5CF7FB3DC7745CEED4DC0F5B1C6D6B69C1764157EA43DF9DBB442EFA39D1D0162E87C2D30C5012FD16D869C8A1FCBB45EDCC8E1813B2B190A961F9FC86591D3ABC5388AF678FF03DA78B7CC0F6185721C0DF33CC906435225DF2611002DF120E83566532292DEA3D8ACD109A0DFFAB3B0B43012796DB5B50683FB4C2D250DAB76AAE35A48E8C8D4A5CC154759745F0A1230F6CA9DD9C99E2F80EDC83304CE01E98F6C9489529A822F90033C228315EB2FCC8DBA382ED4301E07607A5B076C725F124994F18A997D2C5BBF9A324605265108ACBF4610FA1C3374408850A0864E2B61017EBEC1FBAB89DE3AB1B93CE4918B9E2C9E3FE456758062A9F882B283318271F4B9552FCF32624A9FDAA44C65C60E2B3648BEF1F17D0B7C74869EE0B53C4A62A24845DCEA5BCBF93B92E4C26648584E33479282E6C8B1D8FE21181BD9CF75F8A961724D4C4309779F1F1B775D254F70BD1769CC7C0EDD2A95FE5C9D84B16F7C54D85CCE4C8A182810809ED81E97D074884EEDF401CCACDAEAD82C14D06B68AEA6CE14B861B0CFD16090CBBF469C5E084314C0D8D3960EA06A3426D8B3FE762E00D09BDA374F3AE2CBEDE2838FF89D81DEB3013090E44199AED604963EAF919914CE04F207AC82CD4351FEF7B2D94393066FE4D44E3CC5952E75EB6F3714058915DE0EE184D8C55300F576A8B82A863E81AF33417BD4CFC94E7A61263B39F01F6E2E70748B6E5E59CF6CA01B0028C93BBBCEBC548F987F10755BF33CA585CB41CF578DF5FFE37924E3C2C072ED1DAC9162176972971E79B62FB208F1A73BF0361E2993DCCCD3110C34D839D18DD43A5E8F0D941E99ADCF441405F32107671B2D8B2244F7BA92DCED587A210FE8FF43C616ACB5E766E6AF2CEB03599BA3DE376EB5735EF16143953D1FDDB7E9F2874B0D6083DD7EC4386AE003F51CCF2D21EF6059163C5152174423F57119D0FCE627D763D81C10AA1329F74C8D445437BA6718A33DB6E79375172B2AE3591821978D520824E2D2FF898B7F4C867FF462722BC07EADAD389A910B6F65429DA129735FE049E3ECB3889F6047CF2BD2A88D50A651B3235D2480E1DA5A35247FA76C831736399D37E8D033C1D051C9B6A99AB80B1313FA24C5C59766E6C51A38FE9F1186A767EEBD0D88001AE0246CD4EBE2C979DE82C30BBDB98B4744F11F9E639EDDD8C194D7911201A8FA745991B4D8A5709B62A21B63B9762913D36CE995C2D6B79151E8D83838CD1F38840A9417255DD166B7A3584499003FB625611404C95B960DF0DB1BCF1574B0965DBD834EE148117D5E05A7CC7CC1A865618A2BE4854DB8935CDA1E68BD8D09E72F0AC9053C882C4ABA4004A614D10505300B6176CA1F324E22E7824299F9C40755B71D82B679547F06AD48BE66D68072C9390233C933F80A14F8D4A6B0B4E1970E1ACC1BEA7F5D3BE224448F857BAB68AEFA6D8CB819B64294A12997916CDBF56E9A8D002DD065F12C61823F4FC214508232E431F0B6898475BB5DD0D7D528E840C22809AF7E15363724A613ACCFBE2B37438C159CE14CB0C98BFD499C08DAC0CF45D821CC2FA47319B6FB4CED7E5985EC8274DE09071D3C10DA5BF9E522B01CE91D66B91795D3D22C00483454275DD2BBDD7C2DCC4A167E5D7FCDBB9F6208CD4C9A485FAAEB809A7711DAC2865CED4306474B22B4448F85DF33417F3FACE1C05D42703ED313042A05DE0362740130188ECB445BB255DC76EE8443F733117F8351F17603175554FEB00B7FF54D80786F305CDE18CD5EC56EC0962A3E04482DCE3622D040D24C40F2E8A14A447659D6C561F2FFEE68F8D3DE511B23E8B172A01A3EDA4D3780E74C677244330E9AEFF019FE07BE3D33F322F9CE2214B9D9CFF99D05A59E47551432AE76F4CD4F8DD51520FFE811B4B93CD6219C81B63B1D627785C2A0FC22E3AEA86CEEE1F7FBC4EFCB46DDFBCD88A02F3B4E67C5FF2E8DC68BF16C74699BBB628902F72C3DEBC8BF5DF706D47A605A107DAA0014139CE40F0D46D8D6DC7 - sk = 1C0EE1111B08003F28E65E8B3BDEB037CF8F221DFCDAF5950EDB38D506D85BEF394D1695059DFF40AE256C5D5EDABFB69F5F40F37A588F50532CA408A8168AB1E64F146427543D8C36B3B65226769A22911A5A313EAC17C4ABA25284514FC61335780833022316433765807578714524810173154483652641333022302614737052210781265061858507754618580548533018706647518267737733500270312878821580714026734320616250617371010311453681523024650348143708371825508406086017625831312827001718481667317861073723557447151010112110662742120835462285131388164886833510476026118315742500742440642515861365613777118478050862437064068527631150135623216841417724084830878575438508636854268450568437024007161784543800612705826206765211121483880678147555021222855231084503701364318005376837650246531507600625331251200541606324235241507731457033476564312318033365167587141304111715546812605373423882432783371222817481812013632764751028032268650876553563338104474858543012431808386438538308412704646463346461068070602375516825741152882201577858333134315582840316360106481480464368461757213631657465221517713205106646831646714728313555147332818260731554368708032843262416053205202367725828181085426785155280007282271831120868377244420548647205350861738627124677510852763340373432115424065402345080041772846273616868078152467106825545816362764180571244255708045106636115858630465207053275021822428371023852752844203300172311140215768838476231851352521084382555567411445467278546586170430758800684551353478138120800843156221466031560016368563673618080045554337312584031148042036733018271556065603440514434554851122376451064337325382338062451617081541167173200853260404371068037376070864087000352457148262203505356660372180137103710365278432824642320476423840000674364565226217665212413887347650843121701647146540387244177741376785521641117316050482604148474663803351558017351262133622227106345601657207785483272483156167834564057686734583525352081556548103205334016607423715016325334667270811118243732131154424082613775046710080261386850712837526672242308021005015520483744377116420123167107823808071011246825824018158518742085382583106675131252852765256031478162138153470422610571556744682005455051484113038302414747156272021653210303873603486751766527214217262576653612111216874845403342683544406813605031081743567506346184755758586544840762318670343367586667732075171036052737241220173887544032263062135418368155773200100365185741860214443341023755635875026188641851762415850711803541515742425854563545155707638677240017678386862588177508612360606507333506605275024724336451354552554148604216431563331655676070342677080760553063501337707701374572745128728364747780273036442310552415431163146533631211846312638837626748351386351783125814478856084801427164775364735466055660523700464031105550453648423406611175526158521573573156158778744503872054561166220446141461830006866406004737442250560104577350748702663748684802632852635811304428683261106188260700733862552715534532142573231221878655672567467472814454641577410780605613161540446347533077616250133841474266705206708125431777701522218250013173169DB8086B122701706AE49B99305EE6D016F16F9FACC1F835298B41E21664206005CEB981A35F18651CDB90E68C1F950B059F73D6D3143A1F47AA21D80A05FAF5D3A40F67148D3A89A9FDA80364D57C7B8F68058A25D08498D9A9C378C98185DB13259159CAC4769C34A08023A3388C3505406FB21C69EEC12DAC95A3C9BA61185237F0FF1E0E05F1A6F5A0C09090100665A1AD3AFB1076847B232EEEA78409BD9055DB57C1B31E28A01D09999035BDFC657A61040103ECEBDC793409733734D9342CC5A069E070C2421DDE11C49E172DBE7FEAF9DEDDFB3DA5DAA6B3DD13200B09042E144EEA951B43DA48153C1F1D5C07FCF473FA7F321E72534577C895151B46E48331DDE61DA45F8609AC59581814666E1658B49114524BA3840C6BC5596551AEF42412C8AACCDD8EF69E46380E6DEF60FD91228B99CB511D68EF6631748A0548083A215445EC54693471A831042CF41D09AF898119B0FC646E484539C8C32D5DC24F9439D33EEEA033A4081550FDB0B08923DBA5D44A1A876FE7EE4320BF02F9BE26F418F309FA11FCD0C864A7AA34115083C1EA775345AC0548C877C685EA8C91B924AF4F607EF37A0208E21309AB6D0F2F8A4EAA0451FF4A47E6F482958D81A166A6A08A6A10FC8F9ADA42B64A12B9357D598A3664E9DF13755C10FFD7177E594DFCBCFB5D11B6ADB1607445479A5DB1AD8CA6D915F89795D240CBEDFAD2539D10518E53CC450D6FC5385AD6D76B7830F13828120645E3A0A5DCDEAF15F1968E64B3B1CEAF536CAA2953D161C75528C3FA8493E0C177AE807CED37648A82C9BE8BA970296D543F6FBD6724A99A68D2F68C1FD333F9DEF8526DB7836455B313E6BC366178C9C57721601EC0335054F067B78E663A058DBDA1C12D80A392F89C0AD9E2A3B2EA17E9C9A3B14D176822EEAC5FB5FF7D4C87D76080D2D42D9AA4C951F4CAF11A244EDA711D120A2EA321D1551D86CA9265E9CD5FA9591D880E403B6844F051DC04879972C863B97C72B409C19D5EBEE8AB58C6E7B3938A68A9CAD75D80C6FFC4F22254FF4420C606AD120CC20346A7E7324E78C862E0DEE161A64F44917DB0C38C1F79C969220D202F8802D0F9D7ABFB2DE434B1C53DABB57575EEBBBF31CFB2924872FA01473B3976AEADC99699B13820FA0868F2C9FD0D352E2593273CD621B1974FFA6187FA05C4118D4517C934151C1FA34BEC3ED3639598CBA24E28229CE9FD3B1DB4969C12EE49E18B36CE2B9145AAC75428DFFA145302F41D9E3394F38D3F3C0334C4774F1E94296DE36DC6E430E4C0A537E68BDD41AF0421193B16AB1891FA836CBC367B403705ABA5D2F9F2A4C2F275EC010B2EAB84095A569DBAE4457CC2AC1CFEB1EDA43C3E2819273C487ACBEBFA0A0ED1CC4667A6F577F62DFB1BC8FEAFD86D90108E16B8B0E6C2678686C928A668BB9857FFB28DE90545CD4437DD32CCCCC6ED58FB46FBF85E0AEC0C814E536245252B8029F0A2AB44B9027A7E35A941FA113C8D82974EA22DF02D84E5328CEA83D12D399C7F0259055F4B3AD707E7B3E537B93DEA1A066BDC775FC7D1A6F0FE29DDAFA9A7DA630A467EF6CBF5CCDFFD79F1C8BB6BB3882035C73CDF7ECFFB53C712A7C7EAA59765EFA960BF21E25A6703FB304F07739FEBC63F496B13CCAA077338A0B9A976A9F0FC5742D85C4AF401A4CE341B47BE2594FF7E3019A0E064535F9D9395CC74A6A6F00E0C4E3530A7FE9310CE30B6922D04FDE0AA749CC3FDEDB4D8708C1F6968BBEDDDD5833B299D79D61428180099B0A946A5D79085DF7F872CBDD219E6B8EF8B8AB5C1A149E6E15EF2828654FABEC249AFAAC4DC0B3B542334162FB09800B6C36CC90F2A106558BAE2198FA7D1E2D730DE46E355AEA93248E53AB21B518EC99D5F3B021196A0F614A46B9475621234733A28A465CC5A7FD432C3625812AABBB42D2D9CBEF16CBED9367202B02894D06BB801BDA8472B9918B7D724E36557DBE6B7633A5FD22D0E336E5557AFC018C812E9E6A35BFD8C60AB382E14FF51142B2D2C75A767F32413BA38487558F9345CBE6FD1D6B78C2E622F3B976230F99D6CBAF0BBD14949510A52644EF3F3078865037A1C10F47B59546699E1BD539C7DDCC03F71A0158EA9F0178E187BB6D49440DF2B10630FBE2FEB5097E47F285711CA6F835A10D3AA75C03C4184C03EF3075D49DCB2177ABD53AD7399D290EA691D647329056340E8C836E9750FD881DCE309D309A95B82492D4BDC15ECF8C7F5D3B9DD275548512DB5EF80CD409ED32B5148B82BF240A7DC72A18523D808B7A4F9E254799E17278FA88DAEBC944632E83F8609D681AB463513023D67CD51B153F0962912DD64AB8F6529DC22AA89E572A7F89CB97A8F4509319D223BB29974951716FD3177140A31EA20048BAF0FCA230CEF21967ABD83309A4FF7E35E88784DCA77AC079020EC0CA6DDEFBCBB7E317329314665D7C51F631F681B600364E47574F252BAD6396B3F5B17ADC220966A93CE8F315A2F83068D2EA06952E6EBD802473A2264EFA405B3E491BE776C50406E1150C56B894CF864546B0C7A65E3F1A2BEFEF2A9990BAFE70B6CA9F91A8F3DD21307A39A2AFBDFBDE9B7CA3D7828B13F49DECD729C0039E94EBB7B4BDA09B3505529A12CB1E2FD79B9E5087CD7C3BC05F7CFFBBA932A7BFF8E67555FEE0304D890313F86E1892569E2D6F14A89938717AAA3A32AD1167150299C21820ABD70FF902B004C6DE91C1C0B40706442AF531EC490B012750BCB4877935A7E54031702BB988EB3F92914CDBD42979AD7D27B2233EC1279D05493B12D3F5FBB7757536021B5F4CD932B480E40CBAE50D232E0A2EFFE0E8CB58808669199F0830872F369738682F846F6DEAD095BFFCD670A4A9CD142396C58506EA7A68B21ABDCC19CCC06F6DA55C885A855C456680CD4477BCA2BBA9153DCAEE682655B74ECA6F7E44C3BFE1E2D457491ED1BC64E1CF6CE18CF44A0166D1B244480882C1B35CEA703158E18C7EC6E0CF827D5504A45AE61152309BC8A18A52C0E7699A87C4E31C6911A8305351555B2971C94602B70E670AA30B90734EC1DAAD03A30A96F5847C5C3F7973CF4572D166C51D1E94A50A4C1C894A205F8ECB34E80F84CA8DC31A429D5600596179D1093E2A389CCFE9C0402EE49551710FFC25BDBE478F39F2063F31F75D7432ECA1C59EBD8F46D86A092DB12F810FA911C20D4CC1E425C543DC64577E44D84F422D9661E3D35921350D6F7099C5425E509E1458A0500AE5EB4CC6BB50626D0130F09361717A95919AED35592FA4ABE7B2BD4F999422151E63D4ED00CC751A5867977F15E482EFA01E5CCC44064F5B9FFE29AFFE626C4D5170ADA1DF027AB4179608C4093CCE2C409308CD898371A49FBEA2A2F2BA13BDEBAC1F4159F4B0368FB21D70A9D7931D7EFF934E6C544E13B7B73D465576C6E81FD6D5FD94393E80242F9420ACC0ED353EF18CA070F5E9A285AC4BCBAB19A38356F557B070E17AE5CF1F1BED42601E89C8C4C - smlen = 3326 - sm = B055B0E17610BF54B33B96098D796E98F7899F4856CBC8D704F9D7778C1877F1E124BF62A0D17F013BE4340FD57B4FA6222D9CDB9028E8B02B926E1554D145F44798AAC2FAA2033C4AEFB6CCB6CFE5C2A6238EE79C5CC2F0E804BED17F75C1F3994DD7E7A0F2A7034C0C8C9864804057E2E557673FDFD664356FABD051F9075B3400A0C7E84559553EDF989BFFD2112B29602203066BDEA78435EBC6E3818CC92D61BCC125A8575B5A8AEE4225FB9C62483F3ED1185A6A96822E5EFC1BA7CD8D5FD8CC187D2A2669CADF58FAD66289794C96485B2C4645C7D3D35684B7429B5EF315457699BE8030BC3DEB8166602AC54819824883A246C8A1A34FC89B2FE0329B5CA05D4E14B6DFFC2144606AB360BB3B8AC5A178998B46218181CAC8DE4C294830D49D8F00EC12C3D3AC7B4A2C301758E68A5681177FF2A75D1D4BF1C926880B34B728F7C32E406099D95AB44892F748AAFEB55B26BE317512B0377DBE891AC5456A924C36839BC801DB2AC5B7110A9BAF4C3C49D005393CDFFAD4F9686120F4FDE0168A9E458E729F4B0AE1A4C4124CA34DF5B63BC2E7CBEE01A38D31A0ED8D3C4C3803C3C24C5CADEBE3E91A8D2E1BFCF0508A2788D89DFEA20FD63818B83960A6CF930872B95785575088CF7E8B63A1895A8C1C77A84CB9CC6BD1D5FA939677AF17EEBE2D2EE684C66015F1BB142A727779580DA1BC5E975AA56EF5D77A8407E506A5DEEEA5E8B0797F10646005648022213CCB86A77DF5D7B316E85D55B9DA0FDFD5F23552DD47CCFA964AC39EE684BD63793BB7DCAB69BE7ED94D8DDBA185E80A7AAEE74E878F50A213F3B4FFB66E6D34A39C0AAE2B1D61366FE403539C69A088751F56901A10BC442313A35C2D835476D0FAD447C770080FA41BF38D685FB31B11A7D2E6FB52673D168723E68908C0672A0F36E25A199E17A6FE5B8B825B96EAB7AB4B7D8381DBC50031A5F2E09E4BE871533ADC5D08D009429BBF5C86F8120D095C8EECBEF3E099DE618D4377241B50369EDE51AA74AB966589E2C687D6C09FAC9C6D6C5461F5A63008E9835FF4B5BD4265F1128C092C27D4DA508FD4F50EFA74A73157059A4B2F41FE8BF967167969B93BF5204584269032429E3577704BDF689800DD8BDE826B74CEF510A1E087023F0926E97F37926B16EF786C37EC21F2407104D3954A7A07C30DE2D6788402D71A562EA54C79B4197D202C97725D2D8B7E7332F3FF1A6FAD49A4C00CD1A447651B8E08D8506BCA823E10EF4116E6CF49675C4330A1DE1908DDB59F7EA5F89C94CE500F82B43CE789158473B9E07905D8E8615EDEF021383FC31D618C5CE625653B40C21BD7E0BC783D93BEC1B7A5B4BBC6C281B7775547390EF3D30E277399369308D8A1CDC2E1DBD6F158970AC2AC5C2C9481975B809580C0EA89912C0766F45830A8963FBB7E17D84385175A6E0754683CBFBBA6364594F6B5005C15BD5F85732B5A63F26267AB17048C6199200019ADD6A4D1ACD0405C387666E87111B9825AFB9751CD3F9D8A45C6B208D2D333B6C59F98BCF284C854CF7D4F6754FD75EE068C88678EE7565B47B36E68A1FD7BB60E2A8E0DF7127020F5C6277B3EE058773F9BBF1DC2E398BC301202121C699C00379D8350099626F9092365924008B1A9CD9F8787822BEE961ABA239CDCB418E93860EF348A5E9645389A0A878D394F365AEBFE280BEE6874A3054CD98CBD8716662804729FD46FCEA9C4CF929F2F120006CEBCC0BF75692D63C044635D1A1DB61AD1789415E5F2242B7400A8A79368ED602C336492F270345BE98B2DD6EA8E4C53ACA36E3C9BA288F27586134CF0B5CA9BA1EEDF20D1AB4F2D08F3B042DB89DECFFDD23854F35120ADDE1603335D568DA95891CF3AB21D9AFAF66C286C1300019CA9BAF2FF3F6725230C4B269892F7A3DFD6EAB74C314A86F8B47EAE49F419E4A2917B984FE9A00332AFB7A56E5E675223AECC503420AF8B39FAA920E3ADA1A43CE7BD1F7DF2301C9027CC1CE5666EB0936210AFA59E10F307CA1F7863EDD6C3BB8F5D63C0CF0EA8F06EF08CCC24C14F295DD286FD9F4E7102109D53FF5EFF4A01DCAAD5FB6055A0703CD471B20B5FA4560BDEAA1313C7647AE756AE8591579EA5120E09D6794840629B9FEFEFC20DB594BADCD129EC491C3CF75AB40C472AD22C2DEDBC77BA2671C843486560DC765231BF5FDCDBCC77C8300F9D2B53EC3446D82F087B89BD992F7AB0A780B5388118BBF17CCBEC2D196F3EDC478FB947D8302B040A60D0BAB85C1C5C474EAB41E064410695C60E1ACEE79E137D702E4A313968A557B97CE64331888B5289CCB37A6625E52273711B846458D5D8BA1AE4965378CBE918BF0F4BEEE1BD08FECC6606D2F3970C874B0A09C410E0C7D3D6004D93F06FBC258F964A9619B2C6CA28A3A2529BF44FB9F244382CBEF993C418A3880F8D5FBA41F05824F4F33B24B886D115B819816C9B7DB51F2AA0CC6B01B6AB211FAD55284CDC045247859059BD36887F3AE2B6CF7F87EC2DF3C89D43D27E5E4888BAE65B6924FA5DF0B2ED44E3E3794B6890F933F9FBA7A789FC63CEB74360D4AC9C64F10CFC0AB374C712A3CC6C876B22F6D9FEF1C387BF6BDE75792AF9094EC17EB8B55D355FF0AE9D62111AD8A3CBA4F5663D94A38A43E352979DB3DFDF32988534CD45FD436E699C467F6DDD5076B4E5F7F382AF45D3170F25B54150D64D35A81855F4B22BAC9FA17DEFAD73B14B15840E0870DAF5B92A30D237BF0C08CB8C9EBD4159D3BB2D474E3E106CC468E6A24335124810F486A6473C26A5D783264FD8A3685C09D4EF77BD9A9A5C0B578C95E7CAA34ECE46F8483747EE584DBB2D972076D763B0B550E2CAE8349E0609F14F0A8F5110CAA4CDABDD4440AD169C2ABE86EE1C680D6E94882964D870CFEF70A4F4C04B49CC4A4FF6D4B9E36918C18A6D5C4AF47CCF09FF64C77AE3BFBCFA504E169EABB306951A28AFF2FAB7A5BA476F5650BC7DA192D4B0EBFAABABE772EDE2A1071D5C4FC33C2525E40D082FA935BD32FF2506B3A131E31581B6C944C25F2D81755C39D3BFC0C6DE93E35557AB1CF3472B4A32980986A31F882873521938D8BFFE97369FE29746ACFC8F12DEEE0E9AC3E167602022434358F9DC33B2D4408FD08954F9745A0BD65BC77EE8BEA71BFA7640C135ED19CC2F1C22E0D6B02DA6DF24DB05A6480DB45227DCC97ADCECB3917F086C6E98083A212D54DC4B810F689C4F9843D2FB9F5726B87664CD322C28B6F1E01FA91AB3502FAC01AFCF52C9B3D2AA20E1B385EF470CB33078198B5C4395A0329CB10F9A4E96F43E51161FAAE190EB8C3969CEC2977B08F68D24EFCE566511FEB654CC5FA1FE67571F58D848BE7C564AF566390639F81692A7B7C0F9F5AD85B82F6A832C9DA52B6A47D23F9ECFAD449983C939654658B10ADDC0B4AADBB7B85EA602DA7617D1B4A45D86B8D09D2C5A402A6758E06AAA154AD096678CBDD9CA6F5D92B0D738501E18C1DCD268DE01120059482DFCD12B9BF26E1CF3B09970C43CF5620CA8D4E2FD31E5A89EF8DD9317E6CF55B3FB19C072E9D5DDB974EF6082711E9915D3434E7D34E7C325A8D92B66B083DFD6CFD162FD6665DF9ABF188F2DC583FDFABC997D7870E911D3C5EB5BDF80BA8DE6C46C88E049D39E2FA296CBE069CA69494F890887679CB3B0E6043D02B8F24A3F1483C94781B6B01AF801606399C3AC62603D86F7D52955C3125958C04D572A34634CD2367358A86AD2B481B326F2F89D4B4DC094E98918B5AED8F4EBA49C56172B1651B660B87047BA652A640CA7B069971FA2A66C019567C38B7F5D2621E7CB4BAA4140EF5BB491960D80F50101A004E079F5B51F394B029E3EBFBDFC33594E95F6A37BC4F6A329B5C1D8E04145403D33A5C704B343518231B08646E4DA9D5A4ECABCF50F2B3921E85A84C409A1F627EE0F6EB1B1B9A9FCCA9CBD65CEA90088797DF7510B861B86CA4E998AF075949B167CBD66BCBE4C5130347D877CE5A8479F4D56D398146CE2F1A785428DDDEDAD66AAB287CAAE59142435561A401B50934392D4329C3C21AE48328653E3AE575E181DB389BE439716F6E3F3E2DC61E4ECCFE548AB7D715EAB49CFD7641DC37F5C0C0C34965C06A156705F986958791A59CD5B4890D9A1B1CF08541A7A93D065DCF3B9F6C513C0279437D4BDBE627140D294632639B746891CA970DF6D7321F1A913AD9BED3FE0BC02AFBB8720B742EB409EB82C66967F60EBF4CEE2508EF7F7035B7FC7D9178E73EDA0529BCC9EB20B9CD774C564882DD57CCFB54663CFA81B914E14C4D7D74BCE139B7EC53EA61B0BF0DB61C73A7A95F596E128ECA7A8C9EB92C2944EF564943EDACFD48A5A8BDC7D0FABFAB6DAD3C5FEEEB139818C8573A7BD7506B18BFCE2BA15105B7CEC83096C8CAE99FBE5EA2C10F1BCF3F15826A0D8ECA97C42BB17CB9BED219A8CDA9A5762857EFBA43B7F34157AEB492F81D2EA156FF49912A4049BE93E12A226295D8F685C89BDA3831EB73BE4657DBE3B09C09D1DAF944C2664E9BDE9174198FE3DBAE4DE0945229EDDF5961B2F3D719FABAEB9BBD0D63F6B74F147709CB2C5CDDD253541A2D4DBFE2F619FB6C0D80D1D3D849398BDF1FBFE000000000000000000000B0F161D232DD81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 - */ - public void testDilithium() + public void testKeyGen() throws IOException { - String seed = "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"; - String pk = "1C0EE1111B08003F28E65E8B3BDEB037CF8F221DFCDAF5950EDB38D506D85BEFD9FDE3A496F75819F0A20D0441DC7830B4AA1CB8ECFC91BA0EEC3AFB6744E477B4E6EC3FDAE75048FFEBAABEA8E822117D5787F79070EA88287CE3CD5011FD8D93AB7E8B51F26116BF9B6D21C03F88BFEC488876F4D075A142D4E784D734407511F992069353F1DB67ACF73034A468A118588062111D320E00BCFF6DC63573FCED1E96AAEBA6452E3C7ACD19181F9B814BA19D39B4BAB5496DC055426E7EA461AF55D5B9FE97F9DF7E253203C1F9E152E96D75F9D9A84F5C263EC8C250440ADC986F4E36414C703B3E05426B28B7065950DA6D0E0B2C60AC3672DB6F3C78447DB7C20915770EA6FCE81DAB5339C1D5AF82A5D3324099DF56516A07DB7C0FC64383805C65F2B02FBCFCE63E93C4BF09409F9F0F77E73DA3B0019F2057E4CD7CFF0E5745EF18C3FD766E01747A64D415FC9789ABFA62284E11C7FF05D0548D973F679559A6A3AAD77ED5132D0150C014C3EC3A395F017E7ACFE3EABFCA44910CA06FF33542ECCE6241974742357D37F5C284BF0FE1A74B50C073551372133AF2DD41E21BAFC9C590EE6EBC4ACE731EF566156CA03755DC493C137028AF3B3DE5B00BD6CB3D9A87D0151F887C6768BC6CA02A94FB2086551A0F89BA26154E9D4506AD9FAF39F5723E234E06CFDED69D4EE4146B73E5DC1E4152A2A3159D73DBC833D3D417CD5CF7FB3DC7745CEED4DC0F5B1C6D6B69C1764157EA43DF9DBB442EFA39D1D0162E87C2D30C5012FD16D869C8A1FCBB45EDCC8E1813B2B190A961F9FC86591D3ABC5388AF678FF03DA78B7CC0F6185721C0DF33CC906435225DF2611002DF120E83566532292DEA3D8ACD109A0DFFAB3B0B43012796DB5B50683FB4C2D250DAB76AAE35A48E8C8D4A5CC154759745F0A1230F6CA9DD9C99E2F80EDC83304CE01E98F6C9489529A822F90033C228315EB2FCC8DBA382ED4301E07607A5B076C725F124994F18A997D2C5BBF9A324605265108ACBF4610FA1C3374408850A0864E2B61017EBEC1FBAB89DE3AB1B93CE4918B9E2C9E3FE456758062A9F882B283318271F4B9552FCF32624A9FDAA44C65C60E2B3648BEF1F17D0B7C74869EE0B53C4A62A24845DCEA5BCBF93B92E4C26648584E33479282E6C8B1D8FE21181BD9CF75F8A961724D4C4309779F1F1B775D254F70BD1769CC7C0EDD2A95FE5C9D84B16F7C54D85CCE4C8A182810809ED81E97D074884EEDF401CCACDAEAD82C14D06B68AEA6CE14B861B0CFD16090CBBF469C5E084314C0D8D3960EA06A3426D8B3FE762E00D09BDA374F3AE2CBEDE2838FF89D81DEB3013090E44199AED604963EAF919914CE04F207AC82CD4351FEF7B2D94393066FE4D44E3CC5952E75EB6F3714058915DE0EE184D8C55300F576A8B82A863E81AF33417BD4CFC94E7A61263B39F01F6E2E70748B6E5E59CF6CA01B0028C93BBBCEBC548F987F10755BF33CA585CB41CF578DF5FFE37924E3C2C072ED1DAC9162176972971E79B62FB208F1A73BF0361E2993DCCCD3110C34D839D18DD43A5E8F0D941E99ADCF441405F32107671B2D8B2244F7BA92DCED587A210FE8FF43C616ACB5E766E6AF2CEB03599BA3DE376EB5735EF16143953D1FDDB7E9F2874B0D6083DD7EC4386AE003F51CCF2D21EF6059163C5152174423F57119D0FCE627D763D81C10AA1329F74C8D445437BA6718A33DB6E79375172B2AE3591821978D520824E2D2FF898B7F4C867FF462722BC07EADAD389A910B6F65429DA129735FE049E3ECB3889F6047CF2BD2A88D50A651B3235D2480E1DA5A35247FA76C831736399D37E8D033C1D051C9B6A99AB80B1313FA24C5C59766E6C51A38FE9F1186A767EEBD0D88001AE0246CD4EBE2C979DE82C30BBDB98B4744F11F9E639EDDD8C194D7911201A8FA745991B4D8A5709B62A21B63B9762913D36CE995C2D6B79151E8D83838CD1F38840A9417255DD166B7A3584499003FB625611404C95B960DF0DB1BCF1574B0965DBD834EE148117D5E05A7CC7CC1A865618A2BE4854DB8935CDA1E68BD8D09E72F0AC9053C882C4ABA4004A614D10505300B6176CA1F324E22E7824299F9C40755B71D82B679547F06AD48BE66D68072C9390233C933F80A14F8D4A6B0B4E1970E1ACC1BEA7F5D3BE224448F857BAB68AEFA6D8CB819B64294A12997916CDBF56E9A8D002DD065F12C61823F4FC214508232E431F0B6898475BB5DD0D7D528E840C22809AF7E15363724A613ACCFBE2B37438C159CE14CB0C98BFD499C08DAC0CF45D821CC2FA47319B6FB4CED7E5985EC8274DE09071D3C10DA5BF9E522B01CE91D66B91795D3D22C00483454275DD2BBDD7C2DCC4A167E5D7FCDBB9F6208CD4C9A485FAAEB809A7711DAC2865CED4306474B22B4448F85DF33417F3FACE1C05D42703ED313042A05DE0362740130188ECB445BB255DC76EE8443F733117F8351F17603175554FEB00B7FF54D80786F305CDE18CD5EC56EC0962A3E04482DCE3622D040D24C40F2E8A14A447659D6C561F2FFEE68F8D3DE511B23E8B172A01A3EDA4D3780E74C677244330E9AEFF019FE07BE3D33F322F9CE2214B9D9CFF99D05A59E47551432AE76F4CD4F8DD51520FFE811B4B93CD6219C81B63B1D627785C2A0FC22E3AEA86CEEE1F7FBC4EFCB46DDFBCD88A02F3B4E67C5FF2E8DC68BF16C74699BBB628902F72C3DEBC8BF5DF706D47A605A107DAA0014139CE40F0D46D8D6DC7"; - String sk = "1C0EE1111B08003F28E65E8B3BDEB037CF8F221DFCDAF5950EDB38D506D85BEF394D1695059DFF40AE256C5D5EDABFB69F5F40F37A588F50532CA408A8168AB1E64F146427543D8C36B3B65226769A22911A5A313EAC17C4ABA25284514FC61335780833022316433765807578714524810173154483652641333022302614737052210781265061858507754618580548533018706647518267737733500270312878821580714026734320616250617371010311453681523024650348143708371825508406086017625831312827001718481667317861073723557447151010112110662742120835462285131388164886833510476026118315742500742440642515861365613777118478050862437064068527631150135623216841417724084830878575438508636854268450568437024007161784543800612705826206765211121483880678147555021222855231084503701364318005376837650246531507600625331251200541606324235241507731457033476564312318033365167587141304111715546812605373423882432783371222817481812013632764751028032268650876553563338104474858543012431808386438538308412704646463346461068070602375516825741152882201577858333134315582840316360106481480464368461757213631657465221517713205106646831646714728313555147332818260731554368708032843262416053205202367725828181085426785155280007282271831120868377244420548647205350861738627124677510852763340373432115424065402345080041772846273616868078152467106825545816362764180571244255708045106636115858630465207053275021822428371023852752844203300172311140215768838476231851352521084382555567411445467278546586170430758800684551353478138120800843156221466031560016368563673618080045554337312584031148042036733018271556065603440514434554851122376451064337325382338062451617081541167173200853260404371068037376070864087000352457148262203505356660372180137103710365278432824642320476423840000674364565226217665212413887347650843121701647146540387244177741376785521641117316050482604148474663803351558017351262133622227106345601657207785483272483156167834564057686734583525352081556548103205334016607423715016325334667270811118243732131154424082613775046710080261386850712837526672242308021005015520483744377116420123167107823808071011246825824018158518742085382583106675131252852765256031478162138153470422610571556744682005455051484113038302414747156272021653210303873603486751766527214217262576653612111216874845403342683544406813605031081743567506346184755758586544840762318670343367586667732075171036052737241220173887544032263062135418368155773200100365185741860214443341023755635875026188641851762415850711803541515742425854563545155707638677240017678386862588177508612360606507333506605275024724336451354552554148604216431563331655676070342677080760553063501337707701374572745128728364747780273036442310552415431163146533631211846312638837626748351386351783125814478856084801427164775364735466055660523700464031105550453648423406611175526158521573573156158778744503872054561166220446141461830006866406004737442250560104577350748702663748684802632852635811304428683261106188260700733862552715534532142573231221878655672567467472814454641577410780605613161540446347533077616250133841474266705206708125431777701522218250013173169DB8086B122701706AE49B99305EE6D016F16F9FACC1F835298B41E21664206005CEB981A35F18651CDB90E68C1F950B059F73D6D3143A1F47AA21D80A05FAF5D3A40F67148D3A89A9FDA80364D57C7B8F68058A25D08498D9A9C378C98185DB13259159CAC4769C34A08023A3388C3505406FB21C69EEC12DAC95A3C9BA61185237F0FF1E0E05F1A6F5A0C09090100665A1AD3AFB1076847B232EEEA78409BD9055DB57C1B31E28A01D09999035BDFC657A61040103ECEBDC793409733734D9342CC5A069E070C2421DDE11C49E172DBE7FEAF9DEDDFB3DA5DAA6B3DD13200B09042E144EEA951B43DA48153C1F1D5C07FCF473FA7F321E72534577C895151B46E48331DDE61DA45F8609AC59581814666E1658B49114524BA3840C6BC5596551AEF42412C8AACCDD8EF69E46380E6DEF60FD91228B99CB511D68EF6631748A0548083A215445EC54693471A831042CF41D09AF898119B0FC646E484539C8C32D5DC24F9439D33EEEA033A4081550FDB0B08923DBA5D44A1A876FE7EE4320BF02F9BE26F418F309FA11FCD0C864A7AA34115083C1EA775345AC0548C877C685EA8C91B924AF4F607EF37A0208E21309AB6D0F2F8A4EAA0451FF4A47E6F482958D81A166A6A08A6A10FC8F9ADA42B64A12B9357D598A3664E9DF13755C10FFD7177E594DFCBCFB5D11B6ADB1607445479A5DB1AD8CA6D915F89795D240CBEDFAD2539D10518E53CC450D6FC5385AD6D76B7830F13828120645E3A0A5DCDEAF15F1968E64B3B1CEAF536CAA2953D161C75528C3FA8493E0C177AE807CED37648A82C9BE8BA970296D543F6FBD6724A99A68D2F68C1FD333F9DEF8526DB7836455B313E6BC366178C9C57721601EC0335054F067B78E663A058DBDA1C12D80A392F89C0AD9E2A3B2EA17E9C9A3B14D176822EEAC5FB5FF7D4C87D76080D2D42D9AA4C951F4CAF11A244EDA711D120A2EA321D1551D86CA9265E9CD5FA9591D880E403B6844F051DC04879972C863B97C72B409C19D5EBEE8AB58C6E7B3938A68A9CAD75D80C6FFC4F22254FF4420C606AD120CC20346A7E7324E78C862E0DEE161A64F44917DB0C38C1F79C969220D202F8802D0F9D7ABFB2DE434B1C53DABB57575EEBBBF31CFB2924872FA01473B3976AEADC99699B13820FA0868F2C9FD0D352E2593273CD621B1974FFA6187FA05C4118D4517C934151C1FA34BEC3ED3639598CBA24E28229CE9FD3B1DB4969C12EE49E18B36CE2B9145AAC75428DFFA145302F41D9E3394F38D3F3C0334C4774F1E94296DE36DC6E430E4C0A537E68BDD41AF0421193B16AB1891FA836CBC367B403705ABA5D2F9F2A4C2F275EC010B2EAB84095A569DBAE4457CC2AC1CFEB1EDA43C3E2819273C487ACBEBFA0A0ED1CC4667A6F577F62DFB1BC8FEAFD86D90108E16B8B0E6C2678686C928A668BB9857FFB28DE90545CD4437DD32CCCCC6ED58FB46FBF85E0AEC0C814E536245252B8029F0A2AB44B9027A7E35A941FA113C8D82974EA22DF02D84E5328CEA83D12D399C7F0259055F4B3AD707E7B3E537B93DEA1A066BDC775FC7D1A6F0FE29DDAFA9A7DA630A467EF6CBF5CCDFFD79F1C8BB6BB3882035C73CDF7ECFFB53C712A7C7EAA59765EFA960BF21E25A6703FB304F07739FEBC63F496B13CCAA077338A0B9A976A9F0FC5742D85C4AF401A4CE341B47BE2594FF7E3019A0E064535F9D9395CC74A6A6F00E0C4E3530A7FE9310CE30B6922D04FDE0AA749CC3FDEDB4D8708C1F6968BBEDDDD5833B299D79D61428180099B0A946A5D79085DF7F872CBDD219E6B8EF8B8AB5C1A149E6E15EF2828654FABEC249AFAAC4DC0B3B542334162FB09800B6C36CC90F2A106558BAE2198FA7D1E2D730DE46E355AEA93248E53AB21B518EC99D5F3B021196A0F614A46B9475621234733A28A465CC5A7FD432C3625812AABBB42D2D9CBEF16CBED9367202B02894D06BB801BDA8472B9918B7D724E36557DBE6B7633A5FD22D0E336E5557AFC018C812E9E6A35BFD8C60AB382E14FF51142B2D2C75A767F32413BA38487558F9345CBE6FD1D6B78C2E622F3B976230F99D6CBAF0BBD14949510A52644EF3F3078865037A1C10F47B59546699E1BD539C7DDCC03F71A0158EA9F0178E187BB6D49440DF2B10630FBE2FEB5097E47F285711CA6F835A10D3AA75C03C4184C03EF3075D49DCB2177ABD53AD7399D290EA691D647329056340E8C836E9750FD881DCE309D309A95B82492D4BDC15ECF8C7F5D3B9DD275548512DB5EF80CD409ED32B5148B82BF240A7DC72A18523D808B7A4F9E254799E17278FA88DAEBC944632E83F8609D681AB463513023D67CD51B153F0962912DD64AB8F6529DC22AA89E572A7F89CB97A8F4509319D223BB29974951716FD3177140A31EA20048BAF0FCA230CEF21967ABD83309A4FF7E35E88784DCA77AC079020EC0CA6DDEFBCBB7E317329314665D7C51F631F681B600364E47574F252BAD6396B3F5B17ADC220966A93CE8F315A2F83068D2EA06952E6EBD802473A2264EFA405B3E491BE776C50406E1150C56B894CF864546B0C7A65E3F1A2BEFEF2A9990BAFE70B6CA9F91A8F3DD21307A39A2AFBDFBDE9B7CA3D7828B13F49DECD729C0039E94EBB7B4BDA09B3505529A12CB1E2FD79B9E5087CD7C3BC05F7CFFBBA932A7BFF8E67555FEE0304D890313F86E1892569E2D6F14A89938717AAA3A32AD1167150299C21820ABD70FF902B004C6DE91C1C0B40706442AF531EC490B012750BCB4877935A7E54031702BB988EB3F92914CDBD42979AD7D27B2233EC1279D05493B12D3F5FBB7757536021B5F4CD932B480E40CBAE50D232E0A2EFFE0E8CB58808669199F0830872F369738682F846F6DEAD095BFFCD670A4A9CD142396C58506EA7A68B21ABDCC19CCC06F6DA55C885A855C456680CD4477BCA2BBA9153DCAEE682655B74ECA6F7E44C3BFE1E2D457491ED1BC64E1CF6CE18CF44A0166D1B244480882C1B35CEA703158E18C7EC6E0CF827D5504A45AE61152309BC8A18A52C0E7699A87C4E31C6911A8305351555B2971C94602B70E670AA30B90734EC1DAAD03A30A96F5847C5C3F7973CF4572D166C51D1E94A50A4C1C894A205F8ECB34E80F84CA8DC31A429D5600596179D1093E2A389CCFE9C0402EE49551710FFC25BDBE478F39F2063F31F75D7432ECA1C59EBD8F46D86A092DB12F810FA911C20D4CC1E425C543DC64577E44D84F422D9661E3D35921350D6F7099C5425E509E1458A0500AE5EB4CC6BB50626D0130F09361717A95919AED35592FA4ABE7B2BD4F999422151E63D4ED00CC751A5867977F15E482EFA01E5CCC44064F5B9FFE29AFFE626C4D5170ADA1DF027AB4179608C4093CCE2C409308CD898371A49FBEA2A2F2BA13BDEBAC1F4159F4B0368FB21D70A9D7931D7EFF934E6C544E13B7B73D465576C6E81FD6D5FD94393E80242F9420ACC0ED353EF18CA070F5E9A285AC4BCBAB19A38356F557B070E17AE5CF1F1BED42601E89C8C4C"; + String[] files = new String[]{ + "keyGen_ML-DSA-44.txt", + "keyGen_ML-DSA-65.txt", + "keyGen_ML-DSA-87.txt", + }; - NISTSecureRandom random = new NISTSecureRandom(Hex.decode(seed), null); + DilithiumParameters[] params = new DilithiumParameters[]{ + DilithiumParameters.dilithium2, + DilithiumParameters.dilithium3, + DilithiumParameters.dilithium5, + }; - DilithiumKeyPairGenerator keyGen = new DilithiumKeyPairGenerator(); + TestSampler sampler = new TestSampler(); + for (int fileIndex = 0; fileIndex != files.length; fileIndex++) + { + String name = files[fileIndex]; + // System.out.println("testing: " + name); + InputStream src = TestResourceFinder.findTestResource("pqc/crypto/dilithium/acvp", name); + BufferedReader bin = new BufferedReader(new InputStreamReader(src)); - keyGen.init(new DilithiumKeyGenerationParameters(random, DilithiumParameters.dilithium3)); + String line = null; + HashMap buf = new HashMap(); + while ((line = bin.readLine()) != null) + { + line = line.trim(); - AsymmetricCipherKeyPair keyPair = keyGen.generateKeyPair(); + if (line.startsWith("#")) + { + continue; + } + if (line.length() == 0) + { + if (buf.size() > 0) + { + byte[] seed = Hex.decode((String)buf.get("seed")); + byte[] pk = Hex.decode((String)buf.get("pk")); + byte[] sk = Hex.decode((String)buf.get("sk")); - assertTrue(Arrays.areEqual(Hex.decode(sk), ((DilithiumPrivateKeyParameters)keyPair.getPrivate()).getPrivateKey())); - DilithiumPublicKeyParameters dPub = (DilithiumPublicKeyParameters)keyPair.getPublic(); - assertTrue(Arrays.areEqual(Hex.decode(pk), Arrays.concatenate(dPub.getRho(), dPub.getT1()))); - } + DilithiumParameters parameters = params[fileIndex]; - public void testRNG() - { - String temp = "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"; - byte[] seed = Hex.decode(temp); + DilithiumKeyPairGenerator kpGen = new DilithiumKeyPairGenerator(); + DilithiumKeyGenerationParameters genParam = new DilithiumKeyGenerationParameters(new SecureRandom(), parameters); + // + // Generate keys and test. + // + kpGen.init(genParam); + AsymmetricCipherKeyPair kp = kpGen.internalGenerateKeyPair(seed); - NISTSecureRandom r = new NISTSecureRandom(seed, null); + DilithiumPublicKeyParameters pubParams = (DilithiumPublicKeyParameters)PublicKeyFactory.createKey( + SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo((DilithiumPublicKeyParameters)kp.getPublic())); + DilithiumPrivateKeyParameters privParams = (DilithiumPrivateKeyParameters)PrivateKeyFactory.createKey( + PrivateKeyInfoFactory.createPrivateKeyInfo((DilithiumPrivateKeyParameters)kp.getPrivate())); - String testBytesString = "7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2D"; - byte[] testBytes = Hex.decode(testBytesString); + assertTrue(name + ": public key", Arrays.areEqual(pk, pubParams.getEncoded())); + assertTrue(name + ": secret key", Arrays.areEqual(sk, privParams.getEncoded())); - byte[] randBytes = new byte[testBytes.length]; - r.nextBytes(randBytes); + } + buf.clear(); - assertTrue(Arrays.areEqual(randBytes, testBytes)); - } + continue; + } - public void testVectors() - throws Exception + int a = line.indexOf("="); + if (a > -1) + { + buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); + } + } + // System.out.println("testing successful!"); + } + } + public void testSigGen() throws IOException { String[] files = new String[]{ - "PQCsignKAT_Dilithium2.rsp", - "PQCsignKAT_Dilithium3.rsp", - "PQCsignKAT_Dilithium5.rsp", - "PQCsignKAT_Dilithium2-AES.rsp", - "PQCsignKAT_Dilithium3-AES.rsp", - "PQCsignKAT_Dilithium5-AES.rsp" + "sigGen_ML-DSA-44.txt", + "sigGen_ML-DSA-65.txt", + "sigGen_ML-DSA-87.txt", }; - DilithiumParameters[] parameters = new DilithiumParameters[]{ - DilithiumParameters.dilithium2, - DilithiumParameters.dilithium3, - DilithiumParameters.dilithium5, - DilithiumParameters.dilithium2_aes, - DilithiumParameters.dilithium3_aes, - DilithiumParameters.dilithium5_aes + DilithiumParameters[] params = new DilithiumParameters[]{ + DilithiumParameters.dilithium2, + DilithiumParameters.dilithium3, + DilithiumParameters.dilithium5, }; TestSampler sampler = new TestSampler(); - for (int fileindex = 0; fileindex < files.length; fileindex++) + for (int fileIndex = 0; fileIndex != files.length; fileIndex++) { - String name = files[fileindex]; - System.out.println("testing: " + name); - InputStream src = TestResourceFinder.findTestResource("pqc/crypto/dilithium", name); + String name = files[fileIndex]; + // System.out.println("testing: " + name); + InputStream src = TestResourceFinder.findTestResource("pqc/crypto/dilithium/acvp", name); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); + String line = null; HashMap buf = new HashMap(); while ((line = bin.readLine()) != null) @@ -111,109 +137,103 @@ public void testVectors() { if (buf.size() > 0) { - String count = (String)buf.get("count"); - if (sampler.skipTest(count)) + boolean deterministic = !buf.containsKey("rnd"); + byte[] sk = Hex.decode((String)buf.get("sk")); + byte[] message = Hex.decode((String)buf.get("message")); + byte[] signature = Hex.decode((String)buf.get("signature")); + byte[] rnd = null; + if(!deterministic) { - continue; + rnd = Hex.decode((String)buf.get("rnd")); } - System.out.println("test case: " + count); - - byte[] seed = Hex.decode((String)buf.get("seed")); // seed for Dilithium secure random - byte[] pk = Hex.decode((String)buf.get("pk")); // public key - byte[] sk = Hex.decode((String)buf.get("sk")); // private key - byte[] sm = Hex.decode((String)buf.get("sm")); // signed message - int sm_len = Integer.parseInt((String)buf.get("smlen")); - byte[] msg = Hex.decode((String)buf.get("msg")); // message - int m_len = Integer.parseInt((String)buf.get("mlen")); - - NISTSecureRandom random = new NISTSecureRandom(seed, null); - - // keygen - DilithiumKeyGenerationParameters kparam = new DilithiumKeyGenerationParameters(random, parameters[fileindex]); - DilithiumKeyPairGenerator kpg = new DilithiumKeyPairGenerator(); - kpg.init(kparam); - - AsymmetricCipherKeyPair ackp = kpg.generateKeyPair(); - DilithiumPublicKeyParameters dPub = (DilithiumPublicKeyParameters)ackp.getPublic(); - byte[] respk = Arrays.concatenate(dPub.getRho(), dPub.getT1()); - // System.out.println("pk = "); - // Helper.printByteArray(pk); - byte[] ressk = ((DilithiumPrivateKeyParameters)ackp.getPrivate()).getEncoded(); - - //keygen - assertTrue(name + " " + count + " public key", Arrays.areEqual(respk, pk)); - assertTrue(name + " " + count + " secret key", Arrays.areEqual(ressk, sk)); + + DilithiumParameters parameters = params[fileIndex]; + + DilithiumPrivateKeyParameters privParams = new DilithiumPrivateKeyParameters(parameters, sk, null); // sign DilithiumSigner signer = new DilithiumSigner(); - DilithiumPrivateKeyParameters skparam = (DilithiumPrivateKeyParameters)ackp.getPrivate(); - signer.init(true, skparam); + signer.init(true, privParams); + byte[] sigGenerated; + if(!deterministic) + { + sigGenerated = signer.internalGenerateSignature(message, rnd); + } + else + { + sigGenerated = signer.generateSignature(message); + } + assertTrue(Arrays.areEqual(sigGenerated, signature)); + } + buf.clear(); + + continue; + } + + int a = line.indexOf("="); + if (a > -1) + { + buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); + } + } + // System.out.println("testing successful!"); + } + } + public void testSigVer() throws IOException + { + String[] files = new String[]{ + "sigVer_ML-DSA-44.txt", + "sigVer_ML-DSA-65.txt", + "sigVer_ML-DSA-87.txt", + }; + + DilithiumParameters[] params = new DilithiumParameters[]{ + DilithiumParameters.dilithium2, + DilithiumParameters.dilithium3, + DilithiumParameters.dilithium5, + }; + + TestSampler sampler = new TestSampler(); + for (int fileIndex = 0; fileIndex != files.length; fileIndex++) + { + String name = files[fileIndex]; + // System.out.println("testing: " + name); + InputStream src = TestResourceFinder.findTestResource("pqc/crypto/dilithium/acvp", name); + BufferedReader bin = new BufferedReader(new InputStreamReader(src)); + + String line = null; + HashMap buf = new HashMap(); + while ((line = bin.readLine()) != null) + { + line = line.trim(); + + if (line.startsWith("#")) + { + continue; + } + if (line.length() == 0) + { + if (buf.size() > 0) + { + boolean testPassed = Boolean.parseBoolean((String)buf.get("testPassed")); + String reason = buf.get("reason"); + byte[] pk = Hex.decode((String)buf.get("pk")); + byte[] sk = Hex.decode((String)buf.get("sk")); + byte[] message = Hex.decode((String)buf.get("message")); + byte[] signature = Hex.decode((String)buf.get("signature")); + + DilithiumParameters parameters = params[fileIndex]; + + DilithiumPublicKeyParameters pubParams = new DilithiumPublicKeyParameters(parameters, pk); + DilithiumPrivateKeyParameters privParams = new DilithiumPrivateKeyParameters(parameters, sk, null); - byte[] sigGenerated = signer.generateSignature(msg); - byte[] attachedSig = Arrays.concatenate(sigGenerated, msg); - // verify DilithiumSigner verifier = new DilithiumSigner(); - DilithiumPublicKeyParameters pkparam = dPub; - verifier.init(false, pkparam); - - boolean vrfyrespass = verifier.verifySignature(msg, sigGenerated); - sigGenerated[3]++; // changing the signature by 1 byte should cause it to fail - boolean vrfyresfail = verifier.verifySignature(msg, sigGenerated); - - // print results - /* - System.out.println("--Keygen"); - boolean kgenpass = true; - if (!Arrays.areEqual(respk, pk)) { - System.out.println(" == Keygen: pk do not match"); - kgenpass = false; - } - if (!Arrays.areEqual(ressk, sk)) { - System.out.println(" == Keygen: sk do not match"); - kgenpass = false; - } - if (kgenpass) { - System.out.println(" ++ Keygen pass"); - } else { - System.out.println(" == Keygen failed"); - return; - } - - System.out.println("--Sign"); - boolean spass = true; - if (!Arrays.areEqual(ressm, sm)) { - System.out.println(" == Sign: signature do not match"); - spass = false; - } - if (spass) { - System.out.println(" ++ Sign pass"); - } else { - System.out.println(" == Sign failed"); - return; - } - - System.out.println("--Verify"); - if (vrfyrespass && !vrfyresfail) { - System.out.println(" ++ Verify pass"); - } else { - System.out.println(" == Verify failed"); - return; - } - */ - // AssertTrue - - //sign - // System.out.println("attached Sig = "); - // Helper.printByteArray(attachedSig); - // System.out.println("sm = "); - // Helper.printByteArray(sm); - assertTrue(name + " " + count + " signature", Arrays.areEqual(attachedSig, sm)); - //verify - assertTrue(name + " " + count + " verify failed when should pass", vrfyrespass); - assertFalse(name + " " + count + " verify passed when should fail", vrfyresfail); + verifier.init(false, pubParams); + boolean ver = verifier.verifySignature(message, signature); + assertEquals("expected " + testPassed + " " + reason, ver, testPassed); } buf.clear(); @@ -225,13 +245,206 @@ public void testVectors() { buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } - - } - System.out.println("testing successful!"); + // System.out.println("testing successful!"); } } + public void testDilithium() + { + String seed = "70CEFB9AED5B68E018B079DA8284B9D5CAD5499ED9C265FF73588005D85C225C"; + String pk = "D2FD03F3A1B7F635AF9F34D580A98F524C735BD5BA2355DC6E035BD21765580CBB111923F194A7CC8A7BB2EBC5C0E71AA637CC800E6103B850A539B2A39E1B6D713E5DB8314C9AE1F8BF8A38F06AFB9D73B161B0FFE3A4891706AE26D54FFB496DF8DC0F1983509500C9ABBD28E59B3FCDABBDADABD45EC31499378BDE849E7C1F19B7044D67E05106D7136D95380D5605D4465D877557065DF0A75D3C28542F40FEED42EC7E280637B083D988BCA5F6394E02396C4676184FB63318DAFAF5BBDDE00E308FE84019C2340A3F3E1C0865624970711283356AE14BD6B94D1C9AE188DE1A8A2CA824A8EAE2FE6AFB38D83A2D99996AB21FE3E84C0BE6B6DA08879B677374FA7C691B13D40FA9D4CC26B2288D5A8C9A43724381004D61B0D57FF400314C8E30EE796AF10F7EE21BF13D08180465ABC72EDDB080C6A07184E3EEDC47C19AA7F09D1F3309E183A2BD9B0573DDE474A81BA4F78D0C523D0C04F90060FD571A35C037E079C5E210D7390DF568F2E2F03CE44420C82F3FE69EB9B48EE90962D6B0F24440648F71EDB241EE6566FC1A64CABF66BE6FECBCB1387C82A7BC202D9E367998E2A291AF0CD1570677FE8D63A3285A2EA6EB29AF9DC1AEC1C36C4706B12BAA20839692F286A6E0321468F7479345C4D52FBDB2F06725B554B89E2492612681ACEBC6C7BADA9225818DBC35D64C22C48BFF80A730D0716DFAC99DFD5B8992611D0C93EE90BDB260022AFE25D913E06EFFB59CB1F8A60CBFA5AB2F459A16F467E989525E0A37EBE56E833FDE55DB9D1530ADCF45846DF281E47CAA1E0A27EFDE2107D354CEA0F6A454692F04CD838EBDD46E191E5D9C11839A2C3F488A4FC7CD265A7B5D32B08CBDBFAB9D2CCD76222C8EE37DDCBD2AA063ED861473A6454CAEA377850B1A2B9DDBBCB374FAB5B12F351C8E5888872E5CD1F60A4FAE1FF837D192C22BEB41EE6FA392FCDF4550FF46B5CE906D017EF3077DF132300D8BBFA9BB03C75E79E2F04C284AD06A44399649C3E2A2A8D1EFE9B7A4E0C271047AB75908BFF7DF9E30ECA547745BAE23A86FF9A8B58C2538B88B866401076902DC5F0BD761687B49EAFE36D350CBEDFDD36C121CF23786BFCF7E47076496EAB6BBDA774049C2EBABE2DE99C4C24F2DB73684015B373977496760CF9AC23D8B623133DB2DE10D73FA6AD1C6DAC8434F28C6E251CE7293CFF3F3B61EFCB5A435123670F29846A13DF3EE712604461F1BAB8F4EBC836DE058978AE734396A98081B35CC98188A86949C99270D4709854C5B35B17F48A373134C814CC8A0F3E2FA807F2A918530907864778282D75E03A41B2504EED816A417A3AC6BA16080C39B7310192002A728F7F20395009A9E16767CE1971F5DE7D229A50613369E4382045A8E81901F4DBA8102F3D413FE35B326A874F233B719A7137600D35D33AEB6B7259624083AA968730C8F78292AD28F14EEABE660835984FE69EF23DEC8C327C0EB0B882D587E1EC433DA85C9FD1E0A34994DEA240C854452D18C30F496E49EC904B602E0F5062EDCDA03280A53B4313574CC2C0D5471BC9613BDFD6641F5BD127BAB5B5EB3D499A33114048220E819F8EE12CA922C8F17D9C9F51AD5BD6883B10E6AA2483BA49DC547DA7686151344F4E9099B38E430B5226B059832CF03DB48FB02DBA4E61593DC4576360491890E53EC0E6AC73CF32B25D823B38456E286505A541E5AEEE96B1914F5F76687CE2B0160227ABED77993594BCD831366206D75714082F1C46F1F4439AC81A57AF31C81C555307A070FFA94E0479B784BBD88A60CD4C7CFD94E6AFE02F6B21F72AF0DCD6609D40C965C14E5F2389183E53DE930F7DE1D44215CF49144844E8B87F78A7F132AEFE22BE80B4E3A05EE3A68CCF609EF44047402E4493046E6F9C767FF8A75E28B3CE077FDE7E7EED313B5BF7E460127CA8182E9BC794C0DFA730FB920080575A751B5CAEC85A109B4422BA266743F0D032BDA8F1CA6248CDB917530DF1302A5F8C18DC642D52478C98C12A3F16EF2B62B4F59EA1BB58DE7B65B3C7153CE6DA5E4950746F80E087A0E3586D097791BF36DEF865D68591D39D0903773EEA962147F34704138B54DF7924CDD8C333DB5E1A409CCB2B34E2C3C8C7FDD3FD8D012CBF382AAA85E83A12F235A2D147D035B7B28B34B6F57949F322482A7D4D3B15045C420D5ADDC7F0E69B4DC1CBA58B01D872480B06A260D827D891B13C4C5CA50C748DE3C771BE61E9AA170165CB01F4BF5DA27A7791D3AD3F6267B4CB4E61B28FA1708418D932DFC4161880C5D3B17A9663A9061FA8F1804315850FE4E7306C882B38227E867F80872CDC1944D472615EA4900EF7D270B881D4130F56C5CC980D92A47ADA6657EB6F37A385D2D8CC993E1442EB05281853636991E34AADC68954D04E7ADEF76BF880F059B0CBB55D915A4B123E2F1339A073CBFBC409BEFF6400AE096D5AE18EC42CFFAD5B4980FA35BF03413ADB5D7E6876AC355D1C9ED70CA2B973954D12B3CDD76AC6835DB96003ED8C4E288B71FD77DBAA7635720E12AE0A317DE808C664E317F55275791F3245CA4FE5D4D41077FC150A6E403D5A208E46EADBE8F2CFB8AF472F4A0CEAC015219478E6B86C958CF86525B7485C1734C7EF00E90683FFF5DBD0A7D413A855021026A1B32013A4616CBCD3700ACBC705BE3EFBA625C69A025267BCE9D135E3F5B5CC8C43956407E84B6663103E29C242035551AE797F56C6374BE0C798C0CF398F1ED"; + String sk = "D2FD03F3A1B7F635AF9F34D580A98F524C735BD5BA2355DC6E035BD21765580CE38D1C14F6467C35A9F380D27DE61F7C75031569EA2EC8260EEE9105261B7FE160C91344B0C6764C204E5B8D424650BEC06B9E2E625AF07E23F4950CA24FB4D6EC2C8B3A717C9311EB87279FE25E311F48B8256501F6463412B50DBC89A869BA2241112648400738730212442544575483725033356258423201621183610245665648356120845260685045655512724747212125402221428117650306426152134325243382121135623332074786223150837084264345645148311486246686743371366726014707721161588558387183806701657870647785600288534846622583548804744012574371077544387121142208887223588746148553716773822822741403577328718380781434875207647401607561060861322146156542670820841073130361028650452612166833552584735354526517106000385777812426804146432667410603554128333725230677821516317300087526584634638808846451112405321011181864782241003855754210468343733880078343787413576232688065864853483551585074460588700772013100875488142084166115605685115808058863018286131417220168171786585310622852822615043142885431780580115045688233663636406515244767064536422686750635413347851217808387655142313887566205174085281417213812608124414575018287101002132557042172427861117005304772132030216744315771455710541665741524024371512055116783678252533566424613702232740007068187175780286801721004275522864253158176308640831143305382735303723568704541157314123164326663562151508210302338172127102314227577283771627506887214187313030150715862866288868603270146172271385381703388681378810486573016523140830756821032312850065081630675766511601417121255564811411328826207476424482324775326081758115637483551478685666681732021367522746683445700666477204722285687124702480702542301257137367536005268153335820613732408717615224260185343116457761761566876606554781033631421832160155580423842031312343625273082812547513544126735001001838574424013036127812626811887435120627127515610222281118141666638208675561240065461127440345858781007852572885722222550840041260836462878467805022820771360751443687864313877737355412700540708286880045383432281006435486766501775761275438162403343453887216614704841431466587845820225457315213203024880801371255432720568652468040616835054533737272220680825508472867422361680075518121784448115645071105815511010471621075861187800527264521743234076486730776364875131638468745363842354661048363385214842038251103357468016433402070353221275733465833387438517503660880258758088316360182132261568741110331413053416726535501334808710264868845271442358803557705484287055888683862521827261177885176773005771117851106563570287401340012653451205467518807033356622620070232687726311133333814170622861514731302546511761580741613737061400548877756777665316726666887643583104875706764700436358605203442736486123721610624208608323540355557300610365342714158662558016531018261135468246132583477050060156021168545303687336418886334252015833423288568177555148481201581385041471835707545554552827313602123268321382587028585344867273428418220883610214161712415748852510260736761266172132360325411011226660161632642605186351585131425384566627833354507646508025434157357825430282384745701567517747803152750000947BCA93C27D584E2C66EAC9C7640C1CA217EEF66DABBCB260B4C34300FA051357820F57392544982FD11057DE233E6D2DD84972A7E47D4DBA99BC30CF8F2AD5A2C0243195ED2730FFA92D227D153095972D4B3447FFAC45A23EB41CBC87CDD1250A8A478B0F7A1D5B39AA2206E48645584FE7BF7A13168F482765E57BB924AC6D9A11369F4A6AFFCD169B7D75129B35D5134A31761BB8355AEEED27E201A06313013E307A01A73AEA7955C0578C8C5E5A1A2D2FA4593FACD904C62040BDB9F329933536BF8D81C4256BAAE8723FD4DC66BB5E7F9CA49031A193ECECBB5DC390EC6D5513C79A052B3FD43612FB7375315D8091F79BAB1318F17854561BC93AE0E5CD6D131E562C8114810C939AE563AA10B47CE4484317F34ABD02D0CCAD58DD29BCF657BBD9254B01CA9726091938ED32054B37DD617240F4434C1A4A8711AA3A399A8A5388330B7059ECCBB6B1B9CF7187ADF10B0C9171D3C0F6E2D460A419247672E3B9FEA2C95910BF2FB6A5D61F257453B07AFB64B0BA2758BCD735751F2D53515E236FE8A5B4393B80BF06DF97BDC6380087E6AA8DDE6E098111A7343FCDD1E903708E637EBF28323CDA6B9405810EDCFB3691149ECF224C50F8DF92A94AA4770A0E91466194BB0E27BF1CABF16ADFD351220033F76F5925557BCF9634E9461359621D80B4BBAD7E2A6E432DC43B126CA42AB88AA88F0A84AF58029C99A0248F0C454071F35B831FED1254D6F4E2720485786215F7C7F0C4ED15FA853CD3AA07259B39240A82135C2923A72B876FABB3F0F2C09613DE39D459A07C14E7BA437D8041491FCEC1433404BAD1DA9EE9471E17CB691B2A353710C9FFA4E5178112027764EB7DE809C3E1F1FA4178A5D4DC9EE27857EFF26B91711FC144D5A775B8B50D5DB939BA3207680C242FC821947F934C8DAEE203563D28606BE624A32901932DAE85712AF6C8016026927E9B8129574BE3CB1E95332B052707AC8AA8F435E88B7E568D4987C6AC0E902B0609A02D91B3F5FD3FD901DDD0DB9873BD7C71ED921D4577A78C4FCC9BF075203D38F5E76E74F277484E057B6189004131B0C9B1A155294D1CD3D5208E266901D7D314FACCE7E2AA584583A11E4D7C21B94A32E508EDDBBD7A65AA86B4FDFA6BC285D4CFF53926C7173FBE1F89CC303234B878C6B8101F58AC8D3E5E1BF5AB6B26297CC97B95954AABDB25BE008A3F47E56487B00D3DEDA890D92C83957FEAC6B8291AF65959E1D1FCA3BD196E9FC9E67E0607094822E5B4191DB96824B9F03F2EF57F5238BA7E1E84ED55B7DFF3D6C2C1273692A9A19272166130DB89FC67DC94DB614E3E82BA3A3512B012D51FB486B5A3150B78E724E2A12DE07D8671FBA2DA7FD5D147208FC3AF653E6520FC40871AF2177E65CBD0EAF304217B367A665F224CAEDFE93006AC1E14BCD67A88D171F3D8F3E358A71926BA3E5C239A531263EC9437BF2A033B8B55B2C0CB6E7E97316E22DF77CAD910D20EECE1C50910A5CC32ADAB09377550F92D5BB1F4C07F4A2822338E2CFF5348DF77CF8EF8E6657DED1E0CE058E3CCFBF39B3F166E303D33C3556C9AC8ECB3DF7C74AB36D0F2794441BA9808827B578FB5C29E494E21539AD3AB2B41BF161D7F69589D4524C54C89B486F75D252F541CC63B9E706D64A1289A2306C595363CB6FBEF0A1B5B17AB5B1794BF27036F64EAF0BD430DD58D80010CCDADA4A5A3A1E41A6FBF129D73779A37AE5C8D6841A9993C51E364E04FAC8E25A4E6872F6C860FA265C1C4426AD9C21D26DA8C278546ADCD831F2B8B26D4E1F670623D95C8362DA662D1FF0AB687503F328DE095810EDE12B49EAD1533519558C1E940B46E4EDB027BE9DA2039B25DCF7357E19E5416AE268C14FB3A8BABCB3D23F70CC9D59681C5D833AC22E653D86E22CE822540755D8D243C15213D076C6B26436DDC07C7E001347B0CB8783DFEFEDF275FEC4792686734007F0FF8540811C2AFE6CA151420532FA5526A1074C3D789F2932DE42E3ACFBF94760F426D96CF033FA49E2F458F9A9C2E71DACFE009DD9C3F3C8AB3282D6F383B981C82D6364F0E4BDB2AF6A95BA61F474150CAD7233F8903DF972DBB0328C0CB9D0CCBEF883D2E6ADD180ECA1B662FC1D2DBBDDB3634219E1EFF38B1E52875356C03EADE942055F483504BBBCB4302A417CF6D328ED793B1A3C0969B7B3418F50AB39F83C5666C90E38356F7F9D494A6DCB63D67C34E3D14A4E15596497926C8568D8EC3DBD9C2E82C385BCFB8D9674863BD4FBF1757DB447BF804AE950147C91FBF9AA17891044CCAA73B45528597462CED751D015EBBA9E2B7CDCBE6DC05AA9EAE0C86848A3475BB1C5744F5903EE4A842A469CC181271F245AD70D02A4837863B296B4ADB4E8D03D82B64AA11DD31CDF21EDF1DFE3276C4DBC877E35B15FB2835EC3A1C453168A38CA8E563CF3E9A00736CD5CFBD2841D10F94AD55799C2927E5461B28BAC5174D0CE3F8F7CD7609FBC8DA0C38CC21695CEDAD12F8D2E64951A8996E510D6D52797C5BA0EB4AFA6BF2CC43DA09DE3179E899BD7188B32A98A499D372F3707CED479B0981CB50C0C0539CF7E3100B720E466652A4F499C2BA3A17F5232268730B962BC572C0DE96E8C9E28F7E3532C2224196AA9E27688DD050D7CB7854FB3C35F9C62EFB10DA84833F29BB1BE5EF3B533638EEF743D8119DDC290BDF08B6F0F9E4E1E13446C53ED69805DA26908A15DF1C48E009EC1253BD5A5898EBB5121CC24904C8B10E24E680E565985076FDA11D13FFDFA4DB28AC9F0AEA2F81FD7ED4DCA8D3B2E3848B4D6046F6E0DE3A4F683F25E0605E84B36F483C404EF899CB3FCCBE8CB2A6F0A7E10B1948CD4F93F181555F661D31D426808BBF9F66FD60D649269CA3FE991B22428C37AD2A08680F747CC0360CCD373DC6A9F43A66470E014E72B3D8C38E020442D8AAB974E6049374145B04CB7F3044AAC1EFDAB2A18BB464D4F2F2D8143974C95EEE856D59EC00288ED43FF5CC8803006C995514A2CC9CA622B61BCD75EC51C202A917105B4A4BED1B80146831DCED07EFD2ED25739F54096911B150D3077CCD731A0361682725D53803F8FCEAA83919291EDB4493EC84CCE1D0F82A679236EAD1002AE8018CAC9FDBD246FF093D803C0DE3326A57907B0DD6B01D081458C75728C600829928890A56AAAFEFCF7423B70A6D86B415B8358DD044ABEE00B9C9795FC8F61A64686DF5F876A8F33061599AE830F7EB4C4BFF875F4A936C403C5D160DE5D33CAEE40FB718DDA4478AC6F51C59C2155254BD77671118411E2609D000306FC9507004A31E8957EA40C2564B83C3ABB71A87C11BD18D7891C449DBBE79B4A4FB048307CE0E812B2C68ECAB77FD1111526AB0817306CEBCB0497C552431CE15E4AB52283F679480D69DDDE1F2579CFDBE0BCA95FC5B2DB0C5CC76A31950F5116AAE5F02D46710E4257A75FDEDF2F47CE37C203E7F24D3C9179713C5D807C296149A75CCB444F0C6F6ABDD2DBB2985FE267482858A1E"; + + SecureRandom random = new SecureRandom(); + + DilithiumKeyPairGenerator keyGen = new DilithiumKeyPairGenerator(); + + keyGen.init(new DilithiumKeyGenerationParameters(random, DilithiumParameters.dilithium3)); + + AsymmetricCipherKeyPair keyPair = keyGen.internalGenerateKeyPair(Hex.decode(seed)); + + assertTrue(Arrays.areEqual(Hex.decode(sk), ((DilithiumPrivateKeyParameters)keyPair.getPrivate()).getEncoded())); + DilithiumPublicKeyParameters dPub = (DilithiumPublicKeyParameters)keyPair.getPublic(); + assertTrue(Arrays.areEqual(Hex.decode(pk), dPub.getEncoded())); + } + + public void testRNG() + { + String temp = "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"; + byte[] seed = Hex.decode(temp); + + NISTSecureRandom r = new NISTSecureRandom(seed, null); + + String testBytesString = "7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2D"; + byte[] testBytes = Hex.decode(testBytesString); + + byte[] randBytes = new byte[testBytes.length]; + r.nextBytes(randBytes); + + assertTrue(Arrays.areEqual(randBytes, testBytes)); + } + + public void testVectors() + throws Exception + { + //Disabled OLD KATs + +// String[] files = new String[]{ +// "PQCsignKAT_Dilithium2.rsp", +// "PQCsignKAT_Dilithium3.rsp", +// "PQCsignKAT_Dilithium5.rsp", +// }; +// +// DilithiumParameters[] parameters = new DilithiumParameters[]{ +// DilithiumParameters.dilithium2, +// DilithiumParameters.dilithium3, +// DilithiumParameters.dilithium5, +// }; +// +// TestSampler sampler = new TestSampler(); +// for (int fileindex = 0; fileindex < files.length; fileindex++) +// { +// String name = files[fileindex]; +// // System.out.println("testing: " + name); +// InputStream src = TestResourceFinder.findTestResource("pqc/crypto/dilithium", name); +// BufferedReader bin = new BufferedReader(new InputStreamReader(src)); +// String line = null; +// HashMap buf = new HashMap(); +// while ((line = bin.readLine()) != null) +// { +// line = line.trim(); +// +// if (line.startsWith("#")) +// { +// continue; +// } +// if (line.length() == 0) +// { +// if (buf.size() > 0) +// { +// String count = (String)buf.get("count"); +// if (sampler.skipTest(count)) +// { +// continue; +// } +// // System.out.println("test case: " + count); +// +// byte[] seed = Hex.decode((String)buf.get("seed")); // seed for Dilithium secure random +// byte[] pk = Hex.decode((String)buf.get("pk")); // public key +// byte[] sk = Hex.decode((String)buf.get("sk")); // private key +// byte[] sm = Hex.decode((String)buf.get("sm")); // signed message +// int sm_len = Integer.parseInt((String)buf.get("smlen")); +// byte[] msg = Hex.decode((String)buf.get("msg")); // message +// int m_len = Integer.parseInt((String)buf.get("mlen")); +// +// NISTSecureRandom random = new NISTSecureRandom(seed, null); +// +// // keygen +// DilithiumKeyGenerationParameters kparam = new DilithiumKeyGenerationParameters(random, parameters[fileindex]); +// DilithiumKeyPairGenerator kpg = new DilithiumKeyPairGenerator(); +// kpg.init(kparam); +// +// AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); +// +// DilithiumPublicKeyParameters pubParams = (DilithiumPublicKeyParameters)PublicKeyFactory.createKey( +// SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo((DilithiumPublicKeyParameters)kp.getPublic())); +// DilithiumPrivateKeyParameters privParams = (DilithiumPrivateKeyParameters)PrivateKeyFactory.createKey( +// PrivateKeyInfoFactory.createPrivateKeyInfo((DilithiumPrivateKeyParameters)kp.getPrivate())); +// +// assertTrue(name + " " + count + " public key", Arrays.areEqual(pk, pubParams.getEncoded())); +// assertTrue(name + " " + count + " secret key", Arrays.areEqual(sk, privParams.getEncoded())); +// +// // sign +// DilithiumSigner signer = new DilithiumSigner(); +// DilithiumPrivateKeyParameters skparam = (DilithiumPrivateKeyParameters)kp.getPrivate(); +// +// signer.init(true, skparam); +// +// byte[] sigGenerated = signer.generateSignature(msg); +// byte[] attachedSig = Arrays.concatenate(sigGenerated, msg); +// +// // verify +// DilithiumSigner verifier = new DilithiumSigner(); +// DilithiumPublicKeyParameters pkparam = pubParams; +// verifier.init(false, pkparam); +// +// boolean vrfyrespass = verifier.verifySignature(msg, sigGenerated); +// sigGenerated[3]++; // changing the signature by 1 byte should cause it to fail +// boolean vrfyresfail = verifier.verifySignature(msg, sigGenerated); +// +// // print results +// /* +// // System.out.println("--Keygen"); +// boolean kgenpass = true; +// if (!Arrays.areEqual(respk, pk)) { +// // System.out.println(" == Keygen: pk do not match"); +// kgenpass = false; +// } +// if (!Arrays.areEqual(ressk, sk)) { +// // System.out.println(" == Keygen: sk do not match"); +// kgenpass = false; +// } +// if (kgenpass) { +// // System.out.println(" ++ Keygen pass"); +// } else { +// // System.out.println(" == Keygen failed"); +// return; +// } +// +// // System.out.println("--Sign"); +// boolean spass = true; +// if (!Arrays.areEqual(ressm, sm)) { +// // System.out.println(" == Sign: signature do not match"); +// spass = false; +// } +// if (spass) { +// // System.out.println(" ++ Sign pass"); +// } else { +// // System.out.println(" == Sign failed"); +// return; +// } +// +// // System.out.println("--Verify"); +// if (vrfyrespass && !vrfyresfail) { +// // System.out.println(" ++ Verify pass"); +// } else { +// // System.out.println(" == Verify failed"); +// return; +// } +// */ +// // AssertTrue +// +// //sign +// // // System.out.println("attached Sig = "); +// // Helper.printByteArray(attachedSig); +// // // System.out.println("sm = "); +// // Helper.printByteArray(sm); +// +// assertTrue(name + " " + count + " signature", Arrays.areEqual(attachedSig, sm)); +// +// //verify +// assertTrue(name + " " + count + " verify failed when should pass", vrfyrespass); +// assertFalse(name + " " + count + " verify passed when should fail", vrfyresfail); +// +// } +// buf.clear(); +// +// continue; +// } +// +// int a = line.indexOf("="); +// if (a > -1) +// { +// buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); +// } +// +// +// } +// // System.out.println("testing successful!"); +// } + } + public void testDilithiumRandom() { byte[] msg = Strings.toByteArray("Hello World!"); diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/CrystalsKyberTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/CrystalsKyberTest.java deleted file mode 100644 index 58406d62e5..0000000000 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/CrystalsKyberTest.java +++ /dev/null @@ -1,259 +0,0 @@ -package org.bouncycastle.pqc.crypto.test; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.security.SecureRandom; -import java.util.HashMap; - -import junit.framework.Assert; -import junit.framework.TestCase; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.SecretWithEncapsulation; -import org.bouncycastle.crypto.util.DEROtherInfo; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKEMExtractor; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKEMGenerator; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKeyGenerationParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKeyPairGenerator; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberPrivateKeyParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberPublicKeyParameters; -import org.bouncycastle.pqc.crypto.util.PQCOtherInfoGenerator; -import org.bouncycastle.test.TestResourceFinder; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.encoders.Hex; - -public class CrystalsKyberTest - extends TestCase -{ - public void testPrivInfoGeneration() - throws IOException - { - SecureRandom random = new SecureRandom(); - PQCOtherInfoGenerator.PartyU partyU = new PQCOtherInfoGenerator.PartyU(KyberParameters.kyber512, new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), Hex.decode("beef"), Hex.decode("cafe"), random); - - byte[] partA = partyU.getSuppPrivInfoPartA(); - - PQCOtherInfoGenerator.PartyV partyV = new PQCOtherInfoGenerator.PartyV(KyberParameters.kyber512, new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), Hex.decode("beef"), Hex.decode("cafe"), random); - - byte[] partB = partyV.getSuppPrivInfoPartB(partA); - - DEROtherInfo otherInfoU = partyU.generate(partB); - - DEROtherInfo otherInfoV = partyV.generate(); - - Assert.assertTrue(Arrays.areEqual(otherInfoU.getEncoded(), otherInfoV.getEncoded())); - } - - public void testKyber() - { - /* - count = 0 - seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 - pk = D22302CBD3399FACC630991FC8F28BDB4354762541527678BCF61F65C241146C426D23B9BFAA6B7DF18C97F20C1B6125BF874B1D89475852C448215DB0EB7737F91480E8CEBD9A0871574F5AB62D9020175EC6927CA0B54C09818E42CF92A383172422C7DC1831D63B0C295DE75159DB8034E9E07F7B0B910C3C1E5FB66B3DC523F1FA6EB4910CB89A6C17562C83AB4C18D0CD7E0796592A372AA409B1C557347CCACDC4644A119064D06DD474929D1C6FB4D686E5491CE4BC89A30BB4B8C41BCE5157DFC1360823B1AB618C14B10F98C25067398EA7018C278A4B3DF31334D603B2044EF187CD9BC6CE42725BD962C264983E9E18155A8B9C47143D70460A26A56FE7658C1F150348C6087EF758AD167887860A007A5FC37358D43B5EBEE820ACEA474F0AC07B76802866199C61231D5C747C93774D2C1E0C1C67E6C81B82752173E125BAF39B4FD19A4F453DC57976B1D97FE6996992BBB65B7CB25D077BBAA6A13322899AF659CF1B3558C1B5001154B625809ED89AEEBB89E6EA7D67F723D045AB05715C42355DA6A5C8DD39C8ABE3037751A01ED1C7374919F3121B5A52C53D1487316769F80721DEEAAAD3C90F76E7AE9E12BA92B32B5FD457E3C752C2650DFB885771CB77AC3C785A8C562E6A1C63C2A55EA47CF8B90EB8225C123C346452566235B2F31823A33521E087937A345D8D663EEAA05658917BBAA008C2E335F8850A90A326D0E66432F44CEB8289E4ECB2D12958E984072ECACB88E1348FF0B55654ACBA5B54971CBAEBA88EC4B91A94C37192FA982BECB9F3DA421603B61A51BC8E36CBD053851C77B1B926B17A272AA9023246B02B3ED47F66A00BD5684823634E7CE58CF8F306E35B1E5322824D904801F0A2FA7C2BC9C252B0A56B7BA2AB0F636021745A70A9A43E2B0A8D615970B65309624B5184BCC30B911679AEDD76025FE3908FD67897B0CF4BE5A6F5413D7DD98564B23E42A93E4AA8821CD45054C643EDC1158DB6B3DEB13FB5A51EBD1A8A78B87225A7338E101104C4A220D9BDEDD48C85A1C2DAE781A80C40E13B87EAC73A764201C9B760CCFB1AE392699C7039D27C39362B27B8FC6F07A8A3D4410F1547C48A9997F62C61074452EF1515F8A649EBCA9437205A4E8A61606B41DAF6834D671F4D852C0C9C4096611648C6A3170678B1537CC1828D93580C9E5849A9653175ACB753F2BE7437BE45F6C603E485F2EC301BB42B6C37C225D7495A584AE231890AB5C8C35C268CF4BBB0213C096019319561A8A6947637AA40D006B415BB2CFA2237E0890B6A3BC134ABF8F6585E108D15940F91F4BF5B0C818055B21DEA6E63B553988C47F4B94E7CF800A493B4734705EDC56A4B6021C629500675876804CF0B951F038A5C7FE58E89774EF2992FD7C63099D352A7D21560B788B405709861817E59A96B3A3A83CBA803B16934331071905BBEC6532900155D8AC88CB32E4E21A3BD3A03FDEC325A51CD2773964E6784FCF1853737AA64EB67564727272661ABF84313A57A44B123C65509CFB7A6F6641CDCC3B57FE628C7B8192DB44FFBF5796A8613B1FA126F6076883C783DC24E2A4464C40B3A41CA70AE87620866CF4FCB2BD204BF5C283812BA056AC0C345E379C4BA24D750901279BB2F3A16F612BFADB35703332C7C136F68EAB6755C66B6A4AD1AABA7B768A58ACAACC10A459A1CC8EF29377BC200E4D315A30A6BCC3256F9734D06E9779CAA5442A9A16069081377C76E75154368072DC446ED6C8B8E622A21E383CF9BA1FB434E2ECC81E7B78CEE986B8FF798AB18CF9634543546284EDA2A26B47F05B735BCDB1202220076DC8B4E4B9F853533C8F6C7FF38817BA49712835785F17F14CA01D0C1C1E98810FE0B36E5B427157B9418449CEDD641A4293C85C32700102ACEC22EBAD98ED160A5F027BD4CDA57F1F3720A12C134654DD5E73F829676495390D0E7929D6034E9C55F7D55BA658BC587988E8AF94960F6CFB8D5AF7A0021535A6E25E437D49A780698BE22AC9953949F571B85A685725F8207A2B0AE849B601AB91B159B3DF4A154C2041E776070AFC42969322380917C97510799F3149131477E16663D3174C7C1CAEA788535C6C005A64F2868631B31B66E205FD38C1D84542D0F1B578F58C9BF5A0FAEAB6AB6494893053165EAFD465FC64A0C5F8F3F9003489415899D59A543D8208C54A3166529B53922 - sk = 07638FB69868F3D320E5862BD96933FEB311B362093C9B5D50170BCED43F1B536D9A204BB1F22695950BA1F2A9E8EB828B284488760B3FC84FABA04275D5628E39C5B2471374283C503299C0AB49B66B8BBB56A4186624F919A2BA59BB08D8551880C2BEFC4F87F25F59AB587A79C327D792D54C974A69262FF8A78938289E9A87B688B083E0595FE218B6BB1505941CE2E81A5A64C5AAC60417256985349EE47A52420A5F97477B7236AC76BC70E8288729287EE3E34A3DBC3683C0B7B10029FC203418537E7466BA6385A8FF301EE12708F82AAA1E380FC7A88F8F205AB7E88D7E95952A55BA20D09B79A47141D62BF6EB7DD307B08ECA13A5BC5F6B68581C6865B27BBCDDAB142F4B2CBFF488C8A22705FAA98A2B9EEA3530C76662335CC7EA3A00777725EBCCCD2A4636B2D9122FF3AB77123CE0883C1911115E50C9E8A94194E48DD0D09CFFB3ADCD2C1E92430903D07ADBF00532031575AA7F9E7B5A1F3362DEC936D4043C05F2476C07578BC9CBAF2AB4E382727AD41686A96B2548820BB03B32F11B2811AD62F489E951632ABA0D1DF89680CC8A8B53B481D92A68D70B4EA1C3A6A561C0692882B5CA8CC942A8D495AFCB06DE89498FB935B775908FE7A03E324D54CC19D4E1AABD3593B38B19EE1388FE492B43127E5A504253786A0D69AD32601C28E2C88504A5BA599706023A61363E17C6B9BB59BDC697452CD059451983D738CA3FD034E3F5988854CA05031DB09611498988197C6B30D258DFE26265541C89A4B31D6864E9389B03CB74F7EC4323FB9421A4B9790A26D17B0398A26767350909F84D57B6694DF830664CA8B3C3C03ED2AE67B89006868A68527CCD666459AB7F056671000C6164D3A7F266A14D97CBD7004D6C92CACA770B844A4FA9B182E7B18CA885082AC5646FCB4A14E1685FEB0C9CE3372AB95365C04FD83084F80A23FF10A05BF15F7FA5ACC6C0CB462C33CA524FA6B8BB359043BA68609EAA2536E81D08463B19653B5435BA946C9ADDEB202B04B031CC960DCC12E4518D428B32B257A4FC7313D3A7980D80082E934F9D95C32B0A0191A23604384DD9E079BBBAA266D14C3F756B9F2133107433A4E83FA7187282A809203A4FAF841851833D121AC383843A5E55BC2381425E16C7DB4CC9AB5C1B0D91A47E2B8DE0E582C86B6B0D907BB360B97F40AB5D038F6B75C814B27D9B968D419832BC8C2BEE605EF6E5059D33100D90485D378450014221736C07407CAC260408AA64926619788B8601C2A752D1A6CBF820D7C7A04716203225B3895B9342D147A8185CFC1BB65BA06B4142339903C0AC4651385B45D98A8B19D28CD6BAB088787F7EE1B12461766B43CBCCB96434427D93C065550688F6948ED1B5475A425F1B85209D061C08B56C1CC069F6C0A7C6F29358CAB911087732A649D27C9B98F9A48879387D9B00C25959A71654D6F6A946164513E47A75D005986C2363C09F6B537ECA78B9303A5FA457608A586A653A347DB04DFCC19175B3A301172536062A658A95277570C8852CA8973F4AE123A334047DD711C8927A634A03388A527B034BF7A8170FA702C1F7C23EC32D18A2374890BE9C787A9409C82D192C4BB705A2F996CE405D85A4C1A1AB9B6AEB49CCE1C2F8A97C3516C72A00A46263BAA696BF25727719C3216423618FF33380934A6C10545C4C5C5155B12486181FC7A2319873978B6A2A67490F8256BD2196FE1792A4C00077B812EAE8BED3572499684AB3371876761E450C9F9D2768A36806D7AB2046C91F17599E9AC592990808DCD7B4D0919072F14EC361773B7252444C323C308326F4A30F8680D2F748F56A132B82674ED0184620B82AD2CB182C97B481626647491290A011CC73828685A8C367A5B9CF8D621B0D5C1EFF03172758BD004978C251CD51342228989CAE6332AC486437CB5C57D4307462865253BE217B3515C73DF405B7F28217AD0B8CF60C2FFFAA0A0048B1FB4ACDCDC38B5250CFEC356A6DE26CFA7A588FDC86F98C854AC64C7BFAA96F5A32CC0610934BAA6A586B9A2054F13BA274174AA0D2B3A81B96A940666F789B5A6BCDC0A6A0178A0C9A02578A493F6EEA0D2E6C13951C9F249A5E8DD71DD49A742D451F1ABBA19AF8C547855E0AFC728E90ABB499C9BEEB766F4729CDA22263E324D22302CBD3399FACC630991FC8F28BDB4354762541527678BCF61F65C241146C426D23B9BFAA6B7DF18C97F20C1B6125BF874B1D89475852C448215DB0EB7737F91480E8CEBD9A0871574F5AB62D9020175EC6927CA0B54C09818E42CF92A383172422C7DC1831D63B0C295DE75159DB8034E9E07F7B0B910C3C1E5FB66B3DC523F1FA6EB4910CB89A6C17562C83AB4C18D0CD7E0796592A372AA409B1C557347CCACDC4644A119064D06DD474929D1C6FB4D686E5491CE4BC89A30BB4B8C41BCE5157DFC1360823B1AB618C14B10F98C25067398EA7018C278A4B3DF31334D603B2044EF187CD9BC6CE42725BD962C264983E9E18155A8B9C47143D70460A26A56FE7658C1F150348C6087EF758AD167887860A007A5FC37358D43B5EBEE820ACEA474F0AC07B76802866199C61231D5C747C93774D2C1E0C1C67E6C81B82752173E125BAF39B4FD19A4F453DC57976B1D97FE6996992BBB65B7CB25D077BBAA6A13322899AF659CF1B3558C1B5001154B625809ED89AEEBB89E6EA7D67F723D045AB05715C42355DA6A5C8DD39C8ABE3037751A01ED1C7374919F3121B5A52C53D1487316769F80721DEEAAAD3C90F76E7AE9E12BA92B32B5FD457E3C752C2650DFB885771CB77AC3C785A8C562E6A1C63C2A55EA47CF8B90EB8225C123C346452566235B2F31823A33521E087937A345D8D663EEAA05658917BBAA008C2E335F8850A90A326D0E66432F44CEB8289E4ECB2D12958E984072ECACB88E1348FF0B55654ACBA5B54971CBAEBA88EC4B91A94C37192FA982BECB9F3DA421603B61A51BC8E36CBD053851C77B1B926B17A272AA9023246B02B3ED47F66A00BD5684823634E7CE58CF8F306E35B1E5322824D904801F0A2FA7C2BC9C252B0A56B7BA2AB0F636021745A70A9A43E2B0A8D615970B65309624B5184BCC30B911679AEDD76025FE3908FD67897B0CF4BE5A6F5413D7DD98564B23E42A93E4AA8821CD45054C643EDC1158DB6B3DEB13FB5A51EBD1A8A78B87225A7338E101104C4A220D9BDEDD48C85A1C2DAE781A80C40E13B87EAC73A764201C9B760CCFB1AE392699C7039D27C39362B27B8FC6F07A8A3D4410F1547C48A9997F62C61074452EF1515F8A649EBCA9437205A4E8A61606B41DAF6834D671F4D852C0C9C4096611648C6A3170678B1537CC1828D93580C9E5849A9653175ACB753F2BE7437BE45F6C603E485F2EC301BB42B6C37C225D7495A584AE231890AB5C8C35C268CF4BBB0213C096019319561A8A6947637AA40D006B415BB2CFA2237E0890B6A3BC134ABF8F6585E108D15940F91F4BF5B0C818055B21DEA6E63B553988C47F4B94E7CF800A493B4734705EDC56A4B6021C629500675876804CF0B951F038A5C7FE58E89774EF2992FD7C63099D352A7D21560B788B405709861817E59A96B3A3A83CBA803B16934331071905BBEC6532900155D8AC88CB32E4E21A3BD3A03FDEC325A51CD2773964E6784FCF1853737AA64EB67564727272661ABF84313A57A44B123C65509CFB7A6F6641CDCC3B57FE628C7B8192DB44FFBF5796A8613B1FA126F6076883C783DC24E2A4464C40B3A41CA70AE87620866CF4FCB2BD204BF5C283812BA056AC0C345E379C4BA24D750901279BB2F3A16F612BFADB35703332C7C136F68EAB6755C66B6A4AD1AABA7B768A58ACAACC10A459A1CC8EF29377BC200E4D315A30A6BCC3256F9734D06E9779CAA5442A9A16069081377C76E75154368072DC446ED6C8B8E622A21E383CF9BA1FB434E2ECC81E7B78CEE986B8FF798AB18CF9634543546284EDA2A26B47F05B735BCDB1202220076DC8B4E4B9F853533C8F6C7FF38817BA49712835785F17F14CA01D0C1C1E98810FE0B36E5B427157B9418449CEDD641A4293C85C32700102ACEC22EBAD98ED160A5F027BD4CDA57F1F3720A12C134654DD5E73F829676495390D0E7929D6034E9C55F7D55BA658BC587988E8AF94960F6CFB8D5AF7A0021535A6E25E437D49A780698BE22AC9953949F571B85A685725F8207A2B0AE849B601AB91B159B3DF4A154C2041E776070AFC42969322380917C97510799F3149131477E16663D3174C7C1CAEA788535C6C005A64F2868631B31B66E205FD38C1D84542D0F1B578F58C9BF5A0FAEAB6AB6494893053165EAFD465FC64A0C5F8F3F9003489415899D59A543D8208C54A3166529B539228A39E87D531F3527C207EDCC1DB7FADDCF9628391879B335C707839A0DB051A88626ED79D451140800E03B59B956F8210E556067407D13DC90FA9E8B872BFB8F - ct = A6AF29D5F5B80BD130F518BADDD6C8F17545413D860FB3DE451979EBFA5E4E3112C7C0ADF99824BB526F2C3550748ED0E134F0457A7C61F9F526F002BAADC03FC13E38131219513C3EDE061661E74F603C4FCF7951C8E52C9C213B0D22D9293663D669A6B58ED8FCEFCF8249D7BB5298F55761445B2B83CE7F005CB04248AEC8BDA22FD2D42AA766322014EA038CC32C55C8E4B9E28EC9119F527341E4F66A035121073B85DE6706DA19E0838A9F33B719A68F039B664DC002659EABFC398679AA7009CE0CD01CDAFB6CD2A26FE4101672C98FF58F7C47D5BDA2906653B3A6F9651F7A121EA77EA74723FAE5B873F9BB7B664F0C8A93831EF9D51C7CC1EF44AC0E55A55CA76D137FE9B75F40509CEF156E5AD18F9FB999680008E547D55EECD5B4D1CB1D9F076CEC21501C7402509ECB77AFB2CB9A61340A8BD1514C6E71B4AA45E47EC37512271B911F8FB46C9082C9DF07204ABB5A50E6E3647A8AD4D8D5D7BFF19C8A509308BCFB895536D045CA2B97CB16A29BB7181CAD0509DDB91735028EBA8C31D74BD275EAA65B5340B3A43FBFE0B3061D6BAE7E75B7098CDABE91D4B31E36C9AA7A8298862AD63C8FD282E03B460B3AB464CE0F27B1C3D11155ACAA011EB9E2AE3E6DDA07D6F491737CBCE9B05F9BC56BE20E8D326BA132C57FB235161144519CDF40560FBE279BDE411E112531F826D6AB10D4547350ADD2A9DE8D62C2AC82CABE6815646F4DC9742BB0C2A3F77EC7B46C6B537605FA31798CD89281221A33DFB9796E644305630332C2CB931408AB481A16D953F6BEAE3891D6D9AC1FAB38222D9271872D9D0CADB91ABE9B4E265F75C6E5E829E146C3D8CE1E9D12E0D129801957F46B0D2DBE1F749B1D08E2345F6239A731342EB75B0CF1BF411749BC2CAF2810B788C6B7238B4D3DA2D6315CE9542E24404F145755A30AB851E4445841BD33F716A586884888ECC6BC6498AA32919AE81D20C26973C2BD54582A0F6AD98ABFD2627E15690A727E69F581DD2A7127982A90E33E2D4A03FE339142C7E44C326AC46ED395A225D3033389917328B45316B1585A01B2C304B2944E903ABBB3EC5619441CFC8965A446DF75DEFA80C6E15ADBD506B7AB2DE12DDA9BC81441CFC89052E2E5808F7126C6FD3AC6AC8081258A84A09AE50F6CD7CC0F4AF336FD1D643E99079996268C2D32D909F22E3504F07FBB563196D4312FDDB9335D5C1D36E8C5EEA2278DBA23B94D193C947CC41CA993DC7DB1396340AD9C4FE687DD7B8D0C7A5120AE0204F2C665BD5F473D644C7FF26BFFBA7A36980830702128A7E661D677A092A36E7428A4139FB29B0095CC11086F447D2A9EF6C9B161F189C6299E084CB7AA00FAF787797BFB069FBC087FDE26252A1664F19C5A8A22EC5EE1AEB076357B7DC37E6B0F1520F958F7851BACB92C89FD114A72FEAC54652D45B09E1AE7651ABD164BCD537D58FA39D3EC8ACDCDF98425005862FA59692DE162B77E6297C66233348408A8AB695CE2F2728DB9FBE27E958967EC5974767C5A66023074B4A71AFD264AD2890E970A1F31D6E3311B736F9F9488793DDC88F23458064254C82A1D9E59EAD2FCEC40B430687C4B7E28960926AFCACC9BD756A71088C78450E20A2E980AEDE9EBEDFE7FABD6ABFE96F934C4B02C01CA194D01B73C25D5997039D3FCD0F099521F70CAEE69110AC1FC5A99917AD752FC96ADFAD7186D0A7C9CFE5601C07514EA6448D661C57AA20242103C4276A070A489A4CB6BCA0F9ECC4379FB220215FD91F81019D5B0AE619358B52468F272C178E3A74CF6775AA924FE329C3175D9E4C3E21AB9EC836EDC3ACAB2E3891EE8DEDA515D39AF9B8DDD0EE7B0164F805C3835F6D2BABDB30EAB4756E7EC7F829ECE01E8EADFBBED12FC283B3D4C69F575E7F80417689FDFCFC7BE27EE3B8CDF57AAEBEC4A95B7E5BB585B85227F7C32BE30DB3E65E42E30DCF5A5FA073DBA399D942F2222ADB9B9898102AFE5432EDC7F04AE34A8FEC2D81CB49A9A9B43814CE71D97F726E2B1E8F64B50E65DFB4816E12E82A3197484A4E9BBA4D2D69E3F19D0B75C21E2BFFE9FC0C98CF48A3AAF08D467F72687DF0178174B7897F734349B181ECA86A598A0C5E8C25946F24DC5572BD324A40458A788E5137F3C7A7C97FC9F12A3C463A8FE9449101CCE966D7C009323932998D56EF430C73BC24F5D95F737858DDC4F32C013 - ss = B10F7394926AD3B49C5D62D5AEB531D5757538BCC0DA9E550D438F1B61BD7419 - */ - String temp = "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"; - String expectedPubKey = "D22302CBD3399FACC630991FC8F28BDB4354762541527678BCF61F65C241146C426D23B9BFAA6B7DF18C97F20C1B6125BF874B1D89475852C448215DB0EB7737F91480E8CEBD9A0871574F5AB62D9020175EC6927CA0B54C09818E42CF92A383172422C7DC1831D63B0C295DE75159DB8034E9E07F7B0B910C3C1E5FB66B3DC523F1FA6EB4910CB89A6C17562C83AB4C18D0CD7E0796592A372AA409B1C557347CCACDC4644A119064D06DD474929D1C6FB4D686E5491CE4BC89A30BB4B8C41BCE5157DFC1360823B1AB618C14B10F98C25067398EA7018C278A4B3DF31334D603B2044EF187CD9BC6CE42725BD962C264983E9E18155A8B9C47143D70460A26A56FE7658C1F150348C6087EF758AD167887860A007A5FC37358D43B5EBEE820ACEA474F0AC07B76802866199C61231D5C747C93774D2C1E0C1C67E6C81B82752173E125BAF39B4FD19A4F453DC57976B1D97FE6996992BBB65B7CB25D077BBAA6A13322899AF659CF1B3558C1B5001154B625809ED89AEEBB89E6EA7D67F723D045AB05715C42355DA6A5C8DD39C8ABE3037751A01ED1C7374919F3121B5A52C53D1487316769F80721DEEAAAD3C90F76E7AE9E12BA92B32B5FD457E3C752C2650DFB885771CB77AC3C785A8C562E6A1C63C2A55EA47CF8B90EB8225C123C346452566235B2F31823A33521E087937A345D8D663EEAA05658917BBAA008C2E335F8850A90A326D0E66432F44CEB8289E4ECB2D12958E984072ECACB88E1348FF0B55654ACBA5B54971CBAEBA88EC4B91A94C37192FA982BECB9F3DA421603B61A51BC8E36CBD053851C77B1B926B17A272AA9023246B02B3ED47F66A00BD5684823634E7CE58CF8F306E35B1E5322824D904801F0A2FA7C2BC9C252B0A56B7BA2AB0F636021745A70A9A43E2B0A8D615970B65309624B5184BCC30B911679AEDD76025FE3908FD67897B0CF4BE5A6F5413D7DD98564B23E42A93E4AA8821CD45054C643EDC1158DB6B3DEB13FB5A51EBD1A8A78B87225A7338E101104C4A220D9BDEDD48C85A1C2DAE781A80C40E13B87EAC73A764201C9B760CCFB1AE392699C7039D27C39362B27B8FC6F07A8A3D4410F1547C48A9997F62C61074452EF1515F8A649EBCA9437205A4E8A61606B41DAF6834D671F4D852C0C9C4096611648C6A3170678B1537CC1828D93580C9E5849A9653175ACB753F2BE7437BE45F6C603E485F2EC301BB42B6C37C225D7495A584AE231890AB5C8C35C268CF4BBB0213C096019319561A8A6947637AA40D006B415BB2CFA2237E0890B6A3BC134ABF8F6585E108D15940F91F4BF5B0C818055B21DEA6E63B553988C47F4B94E7CF800A493B4734705EDC56A4B6021C629500675876804CF0B951F038A5C7FE58E89774EF2992FD7C63099D352A7D21560B788B405709861817E59A96B3A3A83CBA803B16934331071905BBEC6532900155D8AC88CB32E4E21A3BD3A03FDEC325A51CD2773964E6784FCF1853737AA64EB67564727272661ABF84313A57A44B123C65509CFB7A6F6641CDCC3B57FE628C7B8192DB44FFBF5796A8613B1FA126F6076883C783DC24E2A4464C40B3A41CA70AE87620866CF4FCB2BD204BF5C283812BA056AC0C345E379C4BA24D750901279BB2F3A16F612BFADB35703332C7C136F68EAB6755C66B6A4AD1AABA7B768A58ACAACC10A459A1CC8EF29377BC200E4D315A30A6BCC3256F9734D06E9779CAA5442A9A16069081377C76E75154368072DC446ED6C8B8E622A21E383CF9BA1FB434E2ECC81E7B78CEE986B8FF798AB18CF9634543546284EDA2A26B47F05B735BCDB1202220076DC8B4E4B9F853533C8F6C7FF38817BA49712835785F17F14CA01D0C1C1E98810FE0B36E5B427157B9418449CEDD641A4293C85C32700102ACEC22EBAD98ED160A5F027BD4CDA57F1F3720A12C134654DD5E73F829676495390D0E7929D6034E9C55F7D55BA658BC587988E8AF94960F6CFB8D5AF7A0021535A6E25E437D49A780698BE22AC9953949F571B85A685725F8207A2B0AE849B601AB91B159B3DF4A154C2041E776070AFC42969322380917C97510799F3149131477E16663D3174C7C1CAEA788535C6C005A64F2868631B31B66E205FD38C1D84542D0F1B578F58C9BF5A0FAEAB6AB6494893053165EAFD465FC64A0C5F8F3F9003489415899D59A543D8208C54A3166529B53922"; - String expectedPrivKey = "07638FB69868F3D320E5862BD96933FEB311B362093C9B5D50170BCED43F1B536D9A204BB1F22695950BA1F2A9E8EB828B284488760B3FC84FABA04275D5628E39C5B2471374283C503299C0AB49B66B8BBB56A4186624F919A2BA59BB08D8551880C2BEFC4F87F25F59AB587A79C327D792D54C974A69262FF8A78938289E9A87B688B083E0595FE218B6BB1505941CE2E81A5A64C5AAC60417256985349EE47A52420A5F97477B7236AC76BC70E8288729287EE3E34A3DBC3683C0B7B10029FC203418537E7466BA6385A8FF301EE12708F82AAA1E380FC7A88F8F205AB7E88D7E95952A55BA20D09B79A47141D62BF6EB7DD307B08ECA13A5BC5F6B68581C6865B27BBCDDAB142F4B2CBFF488C8A22705FAA98A2B9EEA3530C76662335CC7EA3A00777725EBCCCD2A4636B2D9122FF3AB77123CE0883C1911115E50C9E8A94194E48DD0D09CFFB3ADCD2C1E92430903D07ADBF00532031575AA7F9E7B5A1F3362DEC936D4043C05F2476C07578BC9CBAF2AB4E382727AD41686A96B2548820BB03B32F11B2811AD62F489E951632ABA0D1DF89680CC8A8B53B481D92A68D70B4EA1C3A6A561C0692882B5CA8CC942A8D495AFCB06DE89498FB935B775908FE7A03E324D54CC19D4E1AABD3593B38B19EE1388FE492B43127E5A504253786A0D69AD32601C28E2C88504A5BA599706023A61363E17C6B9BB59BDC697452CD059451983D738CA3FD034E3F5988854CA05031DB09611498988197C6B30D258DFE26265541C89A4B31D6864E9389B03CB74F7EC4323FB9421A4B9790A26D17B0398A26767350909F84D57B6694DF830664CA8B3C3C03ED2AE67B89006868A68527CCD666459AB7F056671000C6164D3A7F266A14D97CBD7004D6C92CACA770B844A4FA9B182E7B18CA885082AC5646FCB4A14E1685FEB0C9CE3372AB95365C04FD83084F80A23FF10A05BF15F7FA5ACC6C0CB462C33CA524FA6B8BB359043BA68609EAA2536E81D08463B19653B5435BA946C9ADDEB202B04B031CC960DCC12E4518D428B32B257A4FC7313D3A7980D80082E934F9D95C32B0A0191A23604384DD9E079BBBAA266D14C3F756B9F2133107433A4E83FA7187282A809203A4FAF841851833D121AC383843A5E55BC2381425E16C7DB4CC9AB5C1B0D91A47E2B8DE0E582C86B6B0D907BB360B97F40AB5D038F6B75C814B27D9B968D419832BC8C2BEE605EF6E5059D33100D90485D378450014221736C07407CAC260408AA64926619788B8601C2A752D1A6CBF820D7C7A04716203225B3895B9342D147A8185CFC1BB65BA06B4142339903C0AC4651385B45D98A8B19D28CD6BAB088787F7EE1B12461766B43CBCCB96434427D93C065550688F6948ED1B5475A425F1B85209D061C08B56C1CC069F6C0A7C6F29358CAB911087732A649D27C9B98F9A48879387D9B00C25959A71654D6F6A946164513E47A75D005986C2363C09F6B537ECA78B9303A5FA457608A586A653A347DB04DFCC19175B3A301172536062A658A95277570C8852CA8973F4AE123A334047DD711C8927A634A03388A527B034BF7A8170FA702C1F7C23EC32D18A2374890BE9C787A9409C82D192C4BB705A2F996CE405D85A4C1A1AB9B6AEB49CCE1C2F8A97C3516C72A00A46263BAA696BF25727719C3216423618FF33380934A6C10545C4C5C5155B12486181FC7A2319873978B6A2A67490F8256BD2196FE1792A4C00077B812EAE8BED3572499684AB3371876761E450C9F9D2768A36806D7AB2046C91F17599E9AC592990808DCD7B4D0919072F14EC361773B7252444C323C308326F4A30F8680D2F748F56A132B82674ED0184620B82AD2CB182C97B481626647491290A011CC73828685A8C367A5B9CF8D621B0D5C1EFF03172758BD004978C251CD51342228989CAE6332AC486437CB5C57D4307462865253BE217B3515C73DF405B7F28217AD0B8CF60C2FFFAA0A0048B1FB4ACDCDC38B5250CFEC356A6DE26CFA7A588FDC86F98C854AC64C7BFAA96F5A32CC0610934BAA6A586B9A2054F13BA274174AA0D2B3A81B96A940666F789B5A6BCDC0A6A0178A0C9A02578A493F6EEA0D2E6C13951C9F249A5E8DD71DD49A742D451F1ABBA19AF8C547855E0AFC728E90ABB499C9BEEB766F4729CDA22263E324D22302CBD3399FACC630991FC8F28BDB4354762541527678BCF61F65C241146C426D23B9BFAA6B7DF18C97F20C1B6125BF874B1D89475852C448215DB0EB7737F91480E8CEBD9A0871574F5AB62D9020175EC6927CA0B54C09818E42CF92A383172422C7DC1831D63B0C295DE75159DB8034E9E07F7B0B910C3C1E5FB66B3DC523F1FA6EB4910CB89A6C17562C83AB4C18D0CD7E0796592A372AA409B1C557347CCACDC4644A119064D06DD474929D1C6FB4D686E5491CE4BC89A30BB4B8C41BCE5157DFC1360823B1AB618C14B10F98C25067398EA7018C278A4B3DF31334D603B2044EF187CD9BC6CE42725BD962C264983E9E18155A8B9C47143D70460A26A56FE7658C1F150348C6087EF758AD167887860A007A5FC37358D43B5EBEE820ACEA474F0AC07B76802866199C61231D5C747C93774D2C1E0C1C67E6C81B82752173E125BAF39B4FD19A4F453DC57976B1D97FE6996992BBB65B7CB25D077BBAA6A13322899AF659CF1B3558C1B5001154B625809ED89AEEBB89E6EA7D67F723D045AB05715C42355DA6A5C8DD39C8ABE3037751A01ED1C7374919F3121B5A52C53D1487316769F80721DEEAAAD3C90F76E7AE9E12BA92B32B5FD457E3C752C2650DFB885771CB77AC3C785A8C562E6A1C63C2A55EA47CF8B90EB8225C123C346452566235B2F31823A33521E087937A345D8D663EEAA05658917BBAA008C2E335F8850A90A326D0E66432F44CEB8289E4ECB2D12958E984072ECACB88E1348FF0B55654ACBA5B54971CBAEBA88EC4B91A94C37192FA982BECB9F3DA421603B61A51BC8E36CBD053851C77B1B926B17A272AA9023246B02B3ED47F66A00BD5684823634E7CE58CF8F306E35B1E5322824D904801F0A2FA7C2BC9C252B0A56B7BA2AB0F636021745A70A9A43E2B0A8D615970B65309624B5184BCC30B911679AEDD76025FE3908FD67897B0CF4BE5A6F5413D7DD98564B23E42A93E4AA8821CD45054C643EDC1158DB6B3DEB13FB5A51EBD1A8A78B87225A7338E101104C4A220D9BDEDD48C85A1C2DAE781A80C40E13B87EAC73A764201C9B760CCFB1AE392699C7039D27C39362B27B8FC6F07A8A3D4410F1547C48A9997F62C61074452EF1515F8A649EBCA9437205A4E8A61606B41DAF6834D671F4D852C0C9C4096611648C6A3170678B1537CC1828D93580C9E5849A9653175ACB753F2BE7437BE45F6C603E485F2EC301BB42B6C37C225D7495A584AE231890AB5C8C35C268CF4BBB0213C096019319561A8A6947637AA40D006B415BB2CFA2237E0890B6A3BC134ABF8F6585E108D15940F91F4BF5B0C818055B21DEA6E63B553988C47F4B94E7CF800A493B4734705EDC56A4B6021C629500675876804CF0B951F038A5C7FE58E89774EF2992FD7C63099D352A7D21560B788B405709861817E59A96B3A3A83CBA803B16934331071905BBEC6532900155D8AC88CB32E4E21A3BD3A03FDEC325A51CD2773964E6784FCF1853737AA64EB67564727272661ABF84313A57A44B123C65509CFB7A6F6641CDCC3B57FE628C7B8192DB44FFBF5796A8613B1FA126F6076883C783DC24E2A4464C40B3A41CA70AE87620866CF4FCB2BD204BF5C283812BA056AC0C345E379C4BA24D750901279BB2F3A16F612BFADB35703332C7C136F68EAB6755C66B6A4AD1AABA7B768A58ACAACC10A459A1CC8EF29377BC200E4D315A30A6BCC3256F9734D06E9779CAA5442A9A16069081377C76E75154368072DC446ED6C8B8E622A21E383CF9BA1FB434E2ECC81E7B78CEE986B8FF798AB18CF9634543546284EDA2A26B47F05B735BCDB1202220076DC8B4E4B9F853533C8F6C7FF38817BA49712835785F17F14CA01D0C1C1E98810FE0B36E5B427157B9418449CEDD641A4293C85C32700102ACEC22EBAD98ED160A5F027BD4CDA57F1F3720A12C134654DD5E73F829676495390D0E7929D6034E9C55F7D55BA658BC587988E8AF94960F6CFB8D5AF7A0021535A6E25E437D49A780698BE22AC9953949F571B85A685725F8207A2B0AE849B601AB91B159B3DF4A154C2041E776070AFC42969322380917C97510799F3149131477E16663D3174C7C1CAEA788535C6C005A64F2868631B31B66E205FD38C1D84542D0F1B578F58C9BF5A0FAEAB6AB6494893053165EAFD465FC64A0C5F8F3F9003489415899D59A543D8208C54A3166529B539228A39E87D531F3527C207EDCC1DB7FADDCF9628391879B335C707839A0DB051A88626ED79D451140800E03B59B956F8210E556067407D13DC90FA9E8B872BFB8F"; - - byte[] seed = Hex.decode(temp); - - NISTSecureRandom random = new NISTSecureRandom(seed, null); - - KyberKeyPairGenerator keyGen = new KyberKeyPairGenerator(); - - keyGen.init(new KyberKeyGenerationParameters(random, KyberParameters.kyber1024)); - - AsymmetricCipherKeyPair keyPair = keyGen.generateKeyPair(); - // System.out.print("public key = "); - // Helper.printByteArray(((KyberPublicKeyParameters) keyPair.getPublic()).getPublicKey()); - assertTrue(Arrays.areEqual(Hex.decode(expectedPubKey), ((KyberPublicKeyParameters)keyPair.getPublic()).getPublicKey())); - - // System.out.print("secret Key = "); - // Helper.printByteArray(((KyberPrivateKeyParameters) keyPair.getPrivate()).getPrivateKey()); - assertTrue(Arrays.areEqual(Hex.decode(expectedPrivKey), ((KyberPrivateKeyParameters)keyPair.getPrivate()).getEncoded())); - - KyberKEMGenerator kemGen = new KyberKEMGenerator(random); - - SecretWithEncapsulation secretEncap = kemGen.generateEncapsulated(keyPair.getPublic()); - - String expectedSharedSecret = "B10F7394926AD3B49C5D62D5AEB531D5757538BCC0DA9E550D438F1B61BD7419"; - - // System.out.print("Shared secret = "); - // Helper.printByteArray(secretEncap.getSecret()); - assertTrue(Arrays.areEqual(Hex.decode(expectedSharedSecret), secretEncap.getSecret())); - - String expectedCipherText = "A6AF29D5F5B80BD130F518BADDD6C8F17545413D860FB3DE451979EBFA5E4E3112C7C0ADF99824BB526F2C3550748ED0E134F0457A7C61F9F526F002BAADC03FC13E38131219513C3EDE061661E74F603C4FCF7951C8E52C9C213B0D22D9293663D669A6B58ED8FCEFCF8249D7BB5298F55761445B2B83CE7F005CB04248AEC8BDA22FD2D42AA766322014EA038CC32C55C8E4B9E28EC9119F527341E4F66A035121073B85DE6706DA19E0838A9F33B719A68F039B664DC002659EABFC398679AA7009CE0CD01CDAFB6CD2A26FE4101672C98FF58F7C47D5BDA2906653B3A6F9651F7A121EA77EA74723FAE5B873F9BB7B664F0C8A93831EF9D51C7CC1EF44AC0E55A55CA76D137FE9B75F40509CEF156E5AD18F9FB999680008E547D55EECD5B4D1CB1D9F076CEC21501C7402509ECB77AFB2CB9A61340A8BD1514C6E71B4AA45E47EC37512271B911F8FB46C9082C9DF07204ABB5A50E6E3647A8AD4D8D5D7BFF19C8A509308BCFB895536D045CA2B97CB16A29BB7181CAD0509DDB91735028EBA8C31D74BD275EAA65B5340B3A43FBFE0B3061D6BAE7E75B7098CDABE91D4B31E36C9AA7A8298862AD63C8FD282E03B460B3AB464CE0F27B1C3D11155ACAA011EB9E2AE3E6DDA07D6F491737CBCE9B05F9BC56BE20E8D326BA132C57FB235161144519CDF40560FBE279BDE411E112531F826D6AB10D4547350ADD2A9DE8D62C2AC82CABE6815646F4DC9742BB0C2A3F77EC7B46C6B537605FA31798CD89281221A33DFB9796E644305630332C2CB931408AB481A16D953F6BEAE3891D6D9AC1FAB38222D9271872D9D0CADB91ABE9B4E265F75C6E5E829E146C3D8CE1E9D12E0D129801957F46B0D2DBE1F749B1D08E2345F6239A731342EB75B0CF1BF411749BC2CAF2810B788C6B7238B4D3DA2D6315CE9542E24404F145755A30AB851E4445841BD33F716A586884888ECC6BC6498AA32919AE81D20C26973C2BD54582A0F6AD98ABFD2627E15690A727E69F581DD2A7127982A90E33E2D4A03FE339142C7E44C326AC46ED395A225D3033389917328B45316B1585A01B2C304B2944E903ABBB3EC5619441CFC8965A446DF75DEFA80C6E15ADBD506B7AB2DE12DDA9BC81441CFC89052E2E5808F7126C6FD3AC6AC8081258A84A09AE50F6CD7CC0F4AF336FD1D643E99079996268C2D32D909F22E3504F07FBB563196D4312FDDB9335D5C1D36E8C5EEA2278DBA23B94D193C947CC41CA993DC7DB1396340AD9C4FE687DD7B8D0C7A5120AE0204F2C665BD5F473D644C7FF26BFFBA7A36980830702128A7E661D677A092A36E7428A4139FB29B0095CC11086F447D2A9EF6C9B161F189C6299E084CB7AA00FAF787797BFB069FBC087FDE26252A1664F19C5A8A22EC5EE1AEB076357B7DC37E6B0F1520F958F7851BACB92C89FD114A72FEAC54652D45B09E1AE7651ABD164BCD537D58FA39D3EC8ACDCDF98425005862FA59692DE162B77E6297C66233348408A8AB695CE2F2728DB9FBE27E958967EC5974767C5A66023074B4A71AFD264AD2890E970A1F31D6E3311B736F9F9488793DDC88F23458064254C82A1D9E59EAD2FCEC40B430687C4B7E28960926AFCACC9BD756A71088C78450E20A2E980AEDE9EBEDFE7FABD6ABFE96F934C4B02C01CA194D01B73C25D5997039D3FCD0F099521F70CAEE69110AC1FC5A99917AD752FC96ADFAD7186D0A7C9CFE5601C07514EA6448D661C57AA20242103C4276A070A489A4CB6BCA0F9ECC4379FB220215FD91F81019D5B0AE619358B52468F272C178E3A74CF6775AA924FE329C3175D9E4C3E21AB9EC836EDC3ACAB2E3891EE8DEDA515D39AF9B8DDD0EE7B0164F805C3835F6D2BABDB30EAB4756E7EC7F829ECE01E8EADFBBED12FC283B3D4C69F575E7F80417689FDFCFC7BE27EE3B8CDF57AAEBEC4A95B7E5BB585B85227F7C32BE30DB3E65E42E30DCF5A5FA073DBA399D942F2222ADB9B9898102AFE5432EDC7F04AE34A8FEC2D81CB49A9A9B43814CE71D97F726E2B1E8F64B50E65DFB4816E12E82A3197484A4E9BBA4D2D69E3F19D0B75C21E2BFFE9FC0C98CF48A3AAF08D467F72687DF0178174B7897F734349B181ECA86A598A0C5E8C25946F24DC5572BD324A40458A788E5137F3C7A7C97FC9F12A3C463A8FE9449101CCE966D7C009323932998D56EF430C73BC24F5D95F737858DDC4F32C013"; - - assertTrue(Arrays.areEqual(Hex.decode(expectedCipherText), secretEncap.getEncapsulation())); - - KyberKEMExtractor kemExtract = new KyberKEMExtractor((KyberPrivateKeyParameters)keyPair.getPrivate()); - - byte[] decryptedSharedSecret = kemExtract.extractSecret(secretEncap.getEncapsulation()); - - assertTrue(Arrays.areEqual(Hex.decode(expectedSharedSecret), decryptedSharedSecret)); - } - - public void testRNG() - { - String temp = "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"; - byte[] seed = Hex.decode(temp); - NISTSecureRandom r = new NISTSecureRandom(seed, null); - byte[] testBytes = new byte[48]; - r.nextBytes(testBytes); - - String randBytesString = "7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E47"; - byte[] randBytes = Hex.decode(randBytesString); - - assertTrue(Arrays.areEqual(randBytes, testBytes)); - } - - public void testParameters() - throws Exception - { - assertEquals(128, KyberParameters.kyber512.getSessionKeySize()); - assertEquals(192, KyberParameters.kyber768.getSessionKeySize()); - assertEquals(256, KyberParameters.kyber1024.getSessionKeySize()); - } - - public void testVectors() - throws Exception - { - KyberParameters[] params = new KyberParameters[]{ - KyberParameters.kyber512, - KyberParameters.kyber768, - KyberParameters.kyber1024, - KyberParameters.kyber512_aes, - KyberParameters.kyber768_aes, - KyberParameters.kyber1024_aes, - }; - - String[] files = new String[]{ - "kyber512.rsp", - "kyber768.rsp", - "kyber1024.rsp", - "kyber512aes.rsp", - "kyber768aes.rsp", - "kyber1024aes.rsp", - }; - - TestSampler sampler = new TestSampler(); - for (int fileIndex = 0; fileIndex != files.length; fileIndex++) - { - String name = files[fileIndex]; - System.out.println("testing: " + name); - InputStream src = TestResourceFinder.findTestResource("pqc/crypto/kyber", name); - BufferedReader bin = new BufferedReader(new InputStreamReader(src)); - - String line = null; - HashMap buf = new HashMap(); - while ((line = bin.readLine()) != null) - { - line = line.trim(); - - if (line.startsWith("#")) - { - continue; - } - if (line.length() == 0) - { - if (buf.size() > 0) - { - String count = (String)buf.get("count"); - if (sampler.skipTest(count)) - { - continue; - } - System.out.println("test case: " + count); - - byte[] seed = Hex.decode((String)buf.get("seed")); // seed for Kyber secure random - byte[] pk = Hex.decode((String)buf.get("pk")); // public key - byte[] sk = Hex.decode((String)buf.get("sk")); // private key - byte[] ct = Hex.decode((String)buf.get("ct")); // ciphertext - byte[] ss = Hex.decode((String)buf.get("ss")); // session key - - NISTSecureRandom random = new NISTSecureRandom(seed, null); - KyberParameters parameters = params[fileIndex]; - - KyberKeyPairGenerator kpGen = new KyberKeyPairGenerator(); - KyberKeyGenerationParameters genParam = new KyberKeyGenerationParameters(random, parameters); - // - // Generate keys and test. - // - kpGen.init(genParam); - AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); - - KyberPublicKeyParameters pubParams = (KyberPublicKeyParameters)(KyberPublicKeyParameters)kp.getPublic(); - KyberPrivateKeyParameters privParams = (KyberPrivateKeyParameters)(KyberPrivateKeyParameters)kp.getPrivate(); - - assertTrue(name + " " + count + ": public key", Arrays.areEqual(pk, pubParams.getPublicKey())); - assertTrue(name + " " + count + ": secret key", Arrays.areEqual(sk, privParams.getPrivateKey())); - - // KEM Enc - KyberKEMGenerator KyberEncCipher = new KyberKEMGenerator(random); - SecretWithEncapsulation secWenc = KyberEncCipher.generateEncapsulated(pubParams); - byte[] generated_cipher_text = secWenc.getEncapsulation(); - assertTrue(name + " " + count + ": kem_enc cipher text", Arrays.areEqual(ct, generated_cipher_text)); - byte[] secret = secWenc.getSecret(); - assertTrue(name + " " + count + ": kem_enc key", Arrays.areEqual(ss, 0, secret.length, secret, 0, secret.length)); - - // KEM Dec - KyberKEMExtractor KyberDecCipher = new KyberKEMExtractor(privParams); - - byte[] dec_key = KyberDecCipher.extractSecret(generated_cipher_text); - - assertTrue(name + " " + count + ": kem_dec ss", Arrays.areEqual(ss, 0, dec_key.length, dec_key, 0, dec_key.length)); - assertTrue(name + " " + count + ": kem_dec key", Arrays.areEqual(dec_key, secret)); - // } - // catch (AssertionError e) { - // System.out.println("Failed assertion error."); - // System.out.println(); - - // System.out.println(); - // continue; - // } - } - buf.clear(); - - continue; - } - - int a = line.indexOf("="); - if (a > -1) - { - buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); - } - } - System.out.println("testing successful!"); - } - } - - public void testKyberRandom() - { - SecureRandom random = new SecureRandom(); - KyberKeyPairGenerator keyGen = new KyberKeyPairGenerator(); - - keyGen.init(new KyberKeyGenerationParameters(random, KyberParameters.kyber1024)); - - for (int i = 0; i != 1000; i++) - { - AsymmetricCipherKeyPair keyPair = keyGen.generateKeyPair(); - - KyberKEMGenerator kemGen = new KyberKEMGenerator(random); - - SecretWithEncapsulation secretEncap = kemGen.generateEncapsulated(keyPair.getPublic()); - - KyberKEMExtractor kemExtract = new KyberKEMExtractor((KyberPrivateKeyParameters)keyPair.getPrivate()); - - byte[] decryptedSharedSecret = kemExtract.extractSecret(secretEncap.getEncapsulation()); - - assertTrue(Arrays.areEqual(secretEncap.getSecret(), decryptedSharedSecret)); - } - } -} diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/FalconTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/FalconTest.java index 5449918a36..5126132033 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/FalconTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/FalconTest.java @@ -15,6 +15,10 @@ import org.bouncycastle.pqc.crypto.falcon.FalconPrivateKeyParameters; import org.bouncycastle.pqc.crypto.falcon.FalconPublicKeyParameters; import org.bouncycastle.pqc.crypto.falcon.FalconSigner; +import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; +import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; +import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; +import org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory; import org.bouncycastle.test.TestResourceFinder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; @@ -40,7 +44,7 @@ public void testVectors() for (int fileindex = 0; fileindex < files.length; fileindex++) { String name = files[fileindex]; - System.out.println("testing: " + name); + // System.out.println("testing: " + name); InputStream src = TestResourceFinder.findTestResource("pqc/crypto/falcon", name); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); String line = null; @@ -62,7 +66,7 @@ public void testVectors() { continue; } - System.out.println("test case: " + count); + // System.out.println("test case: " + count); byte[] seed = Hex.decode((String)buf.get("seed")); // seed for Falcon secure random byte[] pk = Hex.decode((String)buf.get("pk")); // public key @@ -78,9 +82,15 @@ public void testVectors() FalconKeyGenerationParameters kparam = new FalconKeyGenerationParameters(random, parameters[fileindex]); FalconKeyPairGenerator kpg = new FalconKeyPairGenerator(); kpg.init(kparam); - AsymmetricCipherKeyPair ackp = kpg.generateKeyPair(); - byte[] respk = ((FalconPublicKeyParameters)ackp.getPublic()).getH(); - byte[] ressk = ((FalconPrivateKeyParameters)ackp.getPrivate()).getEncoded(); + AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); + + FalconPublicKeyParameters pubParams = (FalconPublicKeyParameters)PublicKeyFactory.createKey( + SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo((FalconPublicKeyParameters)kp.getPublic())); + FalconPrivateKeyParameters privParams = (FalconPrivateKeyParameters)PrivateKeyFactory.createKey( + PrivateKeyInfoFactory.createPrivateKeyInfo((FalconPrivateKeyParameters)kp.getPrivate())); + + byte[] respk = pubParams.getH(); + byte[] ressk = privParams.getEncoded(); //keygen assertTrue(name + " " + count + " public key", Arrays.areEqual(respk, 0, respk.length, pk, 1, pk.length)); @@ -88,7 +98,7 @@ public void testVectors() // sign FalconSigner signer = new FalconSigner(); - ParametersWithRandom skwrand = new ParametersWithRandom(ackp.getPrivate(), random); + ParametersWithRandom skwrand = new ParametersWithRandom(kp.getPrivate(), random); signer.init(true, skwrand); byte[] sig = signer.generateSignature(msg); // reconstruct test vector signature @@ -102,7 +112,7 @@ public void testVectors() // verify FalconSigner verifier = new FalconSigner(); - FalconPublicKeyParameters pkparam = (FalconPublicKeyParameters)ackp.getPublic(); + FalconPublicKeyParameters pkparam = (FalconPublicKeyParameters)kp.getPublic(); verifier.init(false, pkparam); boolean vrfyrespass = verifier.verifySignature(msg, sig); sig[11]++; // changing the signature by 1 byte should cause it to fail @@ -128,7 +138,7 @@ public void testVectors() } - System.out.println("testing successful!"); + // System.out.println("testing successful!"); } } diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/FrodoVectorTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/FrodoVectorTest.java index e0d030135d..1e6c6d7ef6 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/FrodoVectorTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/FrodoVectorTest.java @@ -15,6 +15,10 @@ import org.bouncycastle.pqc.crypto.frodo.FrodoParameters; import org.bouncycastle.pqc.crypto.frodo.FrodoPrivateKeyParameters; import org.bouncycastle.pqc.crypto.frodo.FrodoPublicKeyParameters; +import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; +import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; +import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; +import org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory; import org.bouncycastle.test.TestResourceFinder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; @@ -58,7 +62,7 @@ public void testVectors() for (int fileIndex = 0; fileIndex != files.length; fileIndex++) { String name = files[fileIndex]; - System.out.println("testing: " + name); + // System.out.println("testing: " + name); InputStream src = TestResourceFinder.findTestResource("pqc/crypto/frodo", name); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); @@ -81,7 +85,7 @@ public void testVectors() { continue; } - System.out.println("test case: " + count); + // System.out.println("test case: " + count); byte[] seed = Hex.decode((String)buf.get("seed")); // seed for nist secure random byte[] pk = Hex.decode((String)buf.get("pk")); // public key @@ -100,8 +104,10 @@ public void testVectors() kpGen.init(genParams); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); - FrodoPublicKeyParameters pubParams = (FrodoPublicKeyParameters) kp.getPublic(); - FrodoPrivateKeyParameters privParams = (FrodoPrivateKeyParameters) kp.getPrivate(); + FrodoPublicKeyParameters pubParams = (FrodoPublicKeyParameters)PublicKeyFactory.createKey( + SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo((FrodoPublicKeyParameters)kp.getPublic())); + FrodoPrivateKeyParameters privParams = (FrodoPrivateKeyParameters)PrivateKeyFactory.createKey( + PrivateKeyInfoFactory.createPrivateKeyInfo((FrodoPrivateKeyParameters)kp.getPrivate())); assertTrue(name + " " + count + ": public key", Arrays.areEqual(pk, pubParams.getPublicKey())); assertTrue(name + " " + count + ": secret key", Arrays.areEqual(sk, privParams.getPrivateKey())); @@ -134,7 +140,7 @@ public void testVectors() buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("testing successful!"); + // System.out.println("testing successful!"); } } } diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/GeMSSTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/GeMSSTest.java index 970476020c..83f9ab196b 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/GeMSSTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/GeMSSTest.java @@ -29,9 +29,6 @@ public void testVectors() throws Exception { -// String testcipher = "fgemss256";//key generation fail - -// String testcipher = "dualmodems256";//key generation fail String files = "dualmodems256.rsp fgemss256.rsp dualmodems192.rsp fgemss192.rsp fgemss128.rsp dualmodems128.rsp " + "redgemss128.rsp bluegemss128.rsp gemss128.rsp cyangemss128.rsp whitegemss128.rsp magentagemss128.rsp " + "bluegemss192.rsp gemss192.rsp redgemss192.rsp whitegemss192.rsp cyangemss192.rsp magentagemss192.rsp " + @@ -46,7 +43,7 @@ public void testVectors() InputStream src = TestResourceFinder.findTestResource("pqc/crypto/gemss", name); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); String testcase = name.replace(".rsp", ""); - System.out.println("Testing on " + testcase); + // System.out.println("Testing on " + testcase); String line = null; HashMap buf = new HashMap(); while ((line = bin.readLine()) != null) @@ -85,7 +82,7 @@ public void testVectors() // kpGen.init(new GeMSSKeyGenerationParameters(random, parameters)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); - //System.out.println("Key generation complete for case " + buf.get("count")); + //// System.out.println("Key generation complete for case " + buf.get("count")); //GeMSSPublicKeyParameters pubParams =new GeMSSPublicKeyParameters(parameters, pk); GeMSSPublicKeyParameters pubParams = (GeMSSPublicKeyParameters)kp.getPublic(); GeMSSPrivateKeyParameters privParams = (GeMSSPrivateKeyParameters)kp.getPrivate(); @@ -96,14 +93,14 @@ public void testVectors() // { // if (sk[i] != SK[i]) // { -// System.out.println(i + " " + sk[i] + " " + SK[i]); +// // System.out.println(i + " " + sk[i] + " " + SK[i]); // } // } // for (i = 0; i < pk.length; ++i) // { // if (pk[i] != PK[i]) // { -// System.out.println(i + " " + pk[i] + " " + PK[i]); +// // System.out.println(i + " " + pk[i] + " " + PK[i]); // } // } assertTrue(name + " " + count + ": public key", Arrays.areEqual(pk, pubParams.getEncoded())); @@ -117,19 +114,19 @@ public void testVectors() ParametersWithRandom skwrand = new ParametersWithRandom(kp.getPrivate(), random); signer.init(true, skwrand); byte[] sigGenerated = signer.generateSignature(msg); - //System.out.println("Sig generation complete for case " + buf.get("count")); + //// System.out.println("Sig generation complete for case " + buf.get("count")); signer.init(false, pubParams); // for (i = 0; i < sigGenerated.length; ++i) // { // if (sigExpected[i] != sigGenerated[i]) // { -// System.out.println(i + " " + sigExpected[i] + " " + sigGenerated[i]); +// // System.out.println(i + " " + sigExpected[i] + " " + sigGenerated[i]); // } // } assertTrue(name + " " + count + ": signature verify", signer.verifySignature(msg, Arrays.copyOfRange(sigExpected, 0, sigGenerated.length))); //assertTrue(name + " " + count + ": signature verify", signer.verifySignature(msg, sigExpected)); assertTrue(name + " " + count + ": signature gen match", Arrays.areEqual(sigExpected, sigGenerated)); - System.out.println(testcase + " case " + buf.get("count") + " pass"); + // System.out.println(testcase + " case " + buf.get("count") + " pass"); // System.err.println(Hex.toHexString(sigExpected)); // System.err.println(Hex.toHexString(attachedSig)); //assertTrue(name + " " + count + ": signature gen match", Arrays.areEqual(sigExpected, attachedSig)); diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/HQCTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/HQCTest.java index 5b7fcd90f9..bb4fd1b538 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/HQCTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/HQCTest.java @@ -56,9 +56,9 @@ public void testVectors() TestSampler sampler = new TestSampler(); for (int fileIndex = 0; fileIndex < files.length; fileIndex++) { - System.out.println("Working Directory = " + System.getProperty("user.dir")); + // System.out.println("Working Directory = " + System.getProperty("user.dir")); String name = files[fileIndex]; - System.out.println("testing: " + name); + // System.out.println("testing: " + name); InputStream src = TestResourceFinder.findTestResource("pqc/crypto/hqc", name); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); @@ -83,7 +83,7 @@ public void testVectors() { continue; } - System.out.println("test case: " + count); + // System.out.println("test case: " + count); byte[] seed = Hex.decode((String)buf.get("seed")); // seed for bike secure random byte[] pk = Hex.decode((String)buf.get("pk")); // public key @@ -135,7 +135,7 @@ public void testVectors() buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("Testing successful!"); + // System.out.println("Testing successful!"); } } } diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/HSSTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/HSSTest.java index 5c2db123d2..e6d5b9a2a8 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/HSSTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/HSSTest.java @@ -20,6 +20,34 @@ public class HSSTest extends TestCase { + public void testOneLevelKeyGenAndSign() + throws Exception + { + byte[] msg = Strings.toByteArray("Hello, world!"); + AsymmetricCipherKeyPairGenerator kpGen = new HSSKeyPairGenerator(); + + kpGen.init(new HSSKeyGenerationParameters( + new LMSParameters[]{ + new LMSParameters(LMSigParameters.lms_sha256_n32_h5, LMOtsParameters.sha256_n32_w4) + }, new SecureRandom())); + + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + + HSSSigner signer = new HSSSigner(); + + signer.init(true, kp.getPrivate()); + + byte[] sig = signer.generateSignature(msg); + + signer.init(false, kp.getPublic()); + + assertTrue(signer.verifySignature(msg, sig)); + + HSSPublicKeyParameters hssPubKey = (HSSPublicKeyParameters)kp.getPublic(); + + hssPubKey.generateLMSContext(sig); + } + public void testKeyGenAndSign() throws Exception { @@ -45,6 +73,31 @@ public void testKeyGenAndSign() assertTrue(signer.verifySignature(msg, sig)); } + public void testHssKeyGenAndSign() + throws Exception + { + byte[] msg = Strings.toByteArray("Hello, world!"); + AsymmetricCipherKeyPairGenerator kpGen = new HSSKeyPairGenerator(); + + kpGen.init(new HSSKeyGenerationParameters( + new LMSParameters[]{ + new LMSParameters(LMSigParameters.lms_sha256_n24_h5, LMOtsParameters.sha256_n24_w4), + new LMSParameters(LMSigParameters.lms_sha256_n24_h5, LMOtsParameters.sha256_n24_w4) + }, new SecureRandom())); + + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + + HSSSigner signer = new HSSSigner(); + + signer.init(true, kp.getPrivate()); + + byte[] sig = signer.generateSignature(msg); + + signer.init(false, kp.getPublic()); + + assertTrue(signer.verifySignature(msg, sig)); + } + public void testKeyGenAndUsage() throws Exception { diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/LMSTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/LMSTest.java index fe0af447df..3a6484a5c0 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/LMSTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/LMSTest.java @@ -13,12 +13,14 @@ import org.bouncycastle.pqc.crypto.lms.LMSKeyPairGenerator; import org.bouncycastle.pqc.crypto.lms.LMSParameters; import org.bouncycastle.pqc.crypto.lms.LMSPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.lms.LMSPublicKeyParameters; import org.bouncycastle.pqc.crypto.lms.LMSSigner; import org.bouncycastle.pqc.crypto.lms.LMSigParameters; import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Hex; public class LMSTest extends TestCase @@ -45,6 +47,50 @@ public void testKeyGenAndSign() assertTrue(signer.verifySignature(msg, sig)); } + public void testKeyGenAndSignSha256_192() + throws Exception + { + byte[] msg = Strings.toByteArray("Hello, world!"); + AsymmetricCipherKeyPairGenerator kpGen = new LMSKeyPairGenerator(); + + kpGen.init(new LMSKeyGenerationParameters( + new LMSParameters(LMSigParameters.lms_sha256_n24_h5, LMOtsParameters.sha256_n24_w4), new SecureRandom())); + + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + + LMSSigner signer = new LMSSigner(); + + signer.init(true, kp.getPrivate()); + + byte[] sig = signer.generateSignature(msg); + + signer.init(false, kp.getPublic()); + + assertTrue(signer.verifySignature(msg, sig)); + } + + public void testKeyGenAndSignShake256_192() + throws Exception + { + byte[] msg = Strings.toByteArray("Hello, world!"); + AsymmetricCipherKeyPairGenerator kpGen = new LMSKeyPairGenerator(); + + kpGen.init(new LMSKeyGenerationParameters( + new LMSParameters(LMSigParameters.lms_shake256_n24_h5, LMOtsParameters.shake256_n24_w4), new SecureRandom())); + + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + + LMSSigner signer = new LMSSigner(); + + signer.init(true, kp.getPrivate()); + + byte[] sig = signer.generateSignature(msg); + + signer.init(false, kp.getPublic()); + + assertTrue(signer.verifySignature(msg, sig)); + } + public void testKeyGenAndSignTwoSigsWithShard() throws Exception { @@ -116,4 +162,128 @@ public void testKeyGenAndSignTwoSigsWithShard() assertTrue(signer.verifySignature(msg1, sig1)); } + + public void test_shouldRecogniseInvalidSignature() + throws Exception + { + byte[] lmsPub = Hex.decode( + "0000001800000010D88330CA119BBFF43228CD435B63966089A997C6083CC2AF9BFE4A9789888694EC2A92883B36015A"); + byte[] msg = Hex.decode("900E8860388B34E30A103184F8EA198CC8B397AD5D7D99C554B966B3D18E938754B77F8252642A17A6F75CEA0945D4385BC37B75ED67C20F90DAC462A3DADB67FB3BC9CC23754F43298515208C2AA0181C098DACF58EC21D84A2F7A2A8539CBB17E915AA5EF042E9707104B08546B1887D6CB54096F25010E527BD655EBFB52D"); + byte[] sig = Hex.decode("00AFBA640000001030734BD0D2A048BAFE3FDDE5828D5D1431A6B02B9BC4F428266277D400CB1DD82E8939940D4E4835825088D6B5ED893B285E1136E39F06BD41DDA933847B6B0E2CDDDEFC7B2041BB75D10CD9904D6665A03C9BFA82989BEB903F0E8B8ECB2BC8C356CCB55225B6D0ED03EDD57B28ACC7911397FAE097F7B8BB888464FA56DC5D18483C5406A9FB51B361ACD45025304210A7031D18CC692F62797F0BB1682DC424DC309616D26C2FFF12DB9B7AC9BED9E35FC31D6113422D14EED59078AA29CE5E0C02F63D3CCBC870F1D5BA65C16DD42D2A373D51ED384307F9C412F7D6B4B7ED7A1C3EDD749BCCFDAEE66F1922249F9DF3EEB3452481B20DF8C63576680F27FE727AD7207389F9335844F8AEE3B8F31DB99D317174F04A133D4E011F352C74E1B3A5D2CA921D03A395B917FD486BC8C59E06C1BB1F49BF1556DCE070C3E94FD14877AC84A86A83C868F5E2307141972A7F7C6823C1A7ED9DEE07B10E0C9C6D65D004B3E841ADD1C3DE4CBBEBA9701B40DAD2D6016A88B68EF76F974B6942B4F13388A47131BC41F4BADAAABA37965EBE1566A921A7BDA4960F77638B5145AE6A8BCCBB96C0D9A433DB2AE60F85CD43963A12BD555786F887794C8734A3C329E85138958DCB5AF95C0E430220514525F65CCDB2DF360546CDE80525739DEEC5947F25A8F9F5FE7CB775A73112367D7C171EBDC9164568AF4F40399B7FA170A7F145A98E03955A3226E2946510E763B56AA619B46325E98B5E7CB5AC07E1ED42A010ECC807BDF4C6809908B8E7C03734B8A979A89A63FEC1F9C6F3878A73954E8C4A1C1914A2356D82A4F4804EEDE288A75BF755654F26AC4955428E9FE81289E0A55B2AF7BA235C98ACD89485EE04DCDC337228FF1B0C465C5FA7456FB1DCEB6D2DFF6C95431E6600000015EDED6089F9AA257DE3C3FD6E9AFB511E2A344A5DB043D5C6CE97D8648C4B125EAC8DD85036291DAF73F32CFAD7FEB07297DDFBECF0471EDC2908C3BE91A4DCB8CF532C9F37E5A4E704A1196405C71115FC622BD51F993D44D3116B0CA31D538E4249B54A67D13C8A02B5434C761B04CE43224D252079231EA031164C8BC3D51F5634FE881C6A0376FA5F0A9FFC5BD6F0118847CC793BCB57CC9C4D4602B0234CD03B8D3C259AF1B3A70C312070D3E8762BBECA5B3E951B3F29C51B6C1A75D7606B89653E9E0148C3FE095752FDC65D3AA2C854240ABE63440204C29BBF4C81D6D87D2FB522CCA245E03132DBA4DC49E193387C7E127C40A7F9B4995752DB1EB347DD5E1FE00203C78AC297E87F56C0F8C581ECBA774CC55BBD03EF335390F7E04CDA220220D1B4870379598583C057327053F7179D3802501E01162D5DB837B344E428443DCAE9B00FE01DF67627BAEBCD60D44A9B21EC0B6576E50DAB72CD0D55A7023391B393311B3B256A3BC42045208E118847F12633FB1890D78F0A8CD5614075A02046215D850112D111414906394FB2096E414AA90591857486945BF57D30706D2491C00796599E7DC1CB7504BAC7A7C7BA5CF0195AAE8162422DCE061C907DBD21A26BE844D6251AECA33DEC28F57C2A0C38D3D4E2894B5B7F9393AD52849D531E7EA95C6D19483FDA55DD9A9E3A4028BB6C7B90A7FD1B65B4EBCC12AFEEA0382E24CDD3261DCDC1E7A9A4227FE76C11EA73EDE79F8E332727767484123500EC3D82256843503DD771B0BE626D7BBDD2AE838A166032F8ACC635B4B9FEED9A31EFFCC87320D969FC0FE3890DBE40268922D12ABE"); + + LMSPublicKeyParameters pup = LMSPublicKeyParameters.getInstance(lmsPub); + LMSSigner lmsSigner = new LMSSigner(); + + lmsSigner.init(false, pup); + + assertFalse(lmsSigner.verifySignature(msg, sig)); + } + + public void test_should_verify_sha256_n24_w1() + throws Exception + { + byte[] lmsPub = Hex.decode( + "0000000A00000005BB9C1B5FCF1286C41F7DCDE9FB53A539C7E3E5EEF5FAB878BD36C04EAB54DEF7CC258C32A842C4FD"); + byte[] msg = Hex.decode("1BCC459B62CDA60458092ABF9BA110DEDC38B6CD819FDA8AEB7ABF935919F60FD73D6F4108CD86243D317802EE46392E7FC50BF3D7A80D8A0D4E68E8F1E336D00C1905D4CF90A4E82B8D758E29E8D85462B17790E90328DD123ED1ACB5B2B2B3C0A2EAC79A9BDFF655F5F600851FC8DEFA1E9AA397F672F6E0A06FAE86F9DD22"); + byte[] sig = Hex.decode("00000001000000052EDE1C14648A2B009E21AE1BC181BDCA54818914475BB58F40C5E602EEB4BB6E33E4256BD64008876E9C8691209C372D5A7A770A1CB819A1758CDD6BEBA1402B58DAA45DFF0DE3F7C15789925D6E8E86577872F879721FC6F07937E88646E417E9320FA1BDED37DC6C5346160170F9D4A0E8E47EA5A2C3D025A5D53E8A7BD87D1827FD421701C775323AB4274679BBD038C438A05E1AB7B91875D4B5BDE3E3E4D26B60141AE8B6349E0380E63D7E6B3A6B2B5CD1BF54A8B89DA615324222009107A131D1AA7F84D1771916C68AE6D477365D2030C2DB69F51D0B4D14FE482A03D204E33DF679040FA2246D9528DEA205841CA6F327696E370AED4A96C965A8E7677BECE391847287D44F3DC6C3334779AF3F4941C3F43550A0D4638A050BB90F587AB06CEB7431F486251F61356C8E7FF318DB2027A825EA89B8547BB346F1A7E0013173DE85357A6232871D3AED6E503B4CB8272F7F0BA004CD9E918A660B7E8114FAF3CC7D9F4FE69F5435C0E6A5BFF5BB63C0BD575775764B73C21F0F2931F3EE9AE58D0B924530601D01E6C2A2AB21BA0312722EB94D5651337E9055DE1F1B8EA9CBC993E2BD202251F9F1B76054F0B495EC6C32725B663E95C82D5003CAA34EB69A7D2A4901766945195CBFFBE72B940B2A6BA12F56BC4AA62D5961DDB97B564B7855EF2BCD686D34FCF0C8DE3B0EC6CDD3A4FB21EC53AA7016BEF53F8F3915B8990129E2F67E51FEE3909B8083915022664F196A662ABBF3DF24C63C207CF53358A2CD5C7EEB297B71208F81A641316F251445C015DE363A2F8AC5AA4B5BEC50C6B1768668FE2B0B858820D27F99742CBF5675FFC6CC9E33A4A3795D8CAFF83726F31C780EB9971E75E46C55FEFD081C3FF6784F7D0C9566E4ED92EFB23E4B5A0514DC5D1104E8845C1F58D0B0A2A2F69E04E66119BA96F480E11831751AE7FE6369330A79FDF5006ACA4717496C023055F5366092ED9835F6F57BB4601654BCF4AFD8CAA305ABCEEE0CD154346F146F188177CB2B203D220C24CF5D1E77912A0F01D8F883055A18C3222A2CF4E34FEBF3660D12B97675D9A4B6382C85674DFE2B660A99C24C2227BA0B96CDFAEEBC8EFA0718E473A4BCBD70ECBE840FAADE55B18299AFA9118FC27F482B69417EFAADD0710CFBCF3CA12F400FDBA3E8BD377FACF38B01A5A07187BA93CA52AB0B49F510A2953C16C888A1F18C129988DD6F4637DB7CA561A9A03229BA2C4B0EC13D2590241BFDC68D8F5038089A35592799AEB37D99E81A374EC78668FBB1E38546671A017AF33022F531C3185BE1092D59D17FB56F4CF1489799F0480B6FF521967F652B46AF7E94FC64602AFF2B8F6A73882BD0452C4A1AC68B4BCBE0C3702768A5D602A24ACFEF51A0B053C1E66D4D1C64CFD8EA8FF76AFB35A152485FFF64EDF6FB18CBBDE7E88CF30A4F76B0C12B71D0F3A3BBABF8A32DE6A60F59E28FEAB4A3B874D7B746099286152B2CCA4B2C3F98ED665B9FA1243649A2B0F10DCF10C26521A7A8C875B234003B57E90243D74B677313C3F1BA7CCD4D0B42ED7EA79D50178F29CD432F423C101705E291535B02DC1BC9694236B4C628EE0D45BB0FE06E4E450D63D457D71C0BFC2FC70A66DA02DC437A75652AD8833A0D2D328F5C8993EF07EA64E2A17BF2F1792078C2D7031CBE17E53509B9CC9EC44CDB6C01211CC97001ECFEC24DC71C14609158A79BE8BBDF1DE0AFFE73C30DF6F5A5392ED60F02033C7CA03DE232D4B0C7F5190A47D07EFA1AEDD5ADE1B0B086BF8F540B9B2E29E3E670D4538053830864AE03813C0FD1B667CC91416A64220E5B8B5C43454E7AEDFD22E68987598F21D4FAB24953A3216A12FD55F73168EE98E0E7391A69A5FA6418520B0C78B816FE846B15743886C5B0B582B43F264147040A3D2646B0686D5280A9F20DB9E6B4B918CCDB760060F33F6E4F9A3F90ADDC9CAC3D9D77E0D0AB479FE710BED79D150A290B037BA0071592A896E90980444C66B0ADE9852657140226F4C5E97919CC9561AA72EDEAAAAA610B8767DF3A2DC3FE844E98B37D26C8277C9103278CD655BB8E9453ED8AD61A54359F80E51F0E65B09A0E515C3D001209B1592CA87C87DE853E7905765718755124CC04B7C9F972BE8F731FFA87F541423E767C33A7D52B7219CAF53DAC8EB5852FCC91B01315A6211E789ADFC5716C8D4EBBD95B39975EC7B88DD282109AC71D4676F2EA1F9743E619D58BCCDBF837BAB74C4AC846D4BF6C8AB77151B42FBABB887AFBA87F74EEBECECC8C45ECA8FE26EC9CFA3C89DFA62F8BA39087B81F76E929B8B5112E8457EA42C9516E2BF3466427EC0F7572774B11BD626CC12ADEBC0238A932B75CE9FF9900F332D1818E5C0451A1CE7A74EF063E8F371E2183ACDF0C38B1DB098320F6BBA960B80A6925C6BDE61EAD96BEA847F776266A9EE226858E02AD785DC4F12E5287B389BEAE8B4C77B77480D1A5F357BF62AA41EF06FD859B178D17CFC6DEE117FCC8645F2CB5D666A589570643D4C1B5D44DF1552E3FF401B26D70C6C26C400914DBC63157380B8211B6EE9A713B05FAF7AB70D16E2BFBEECA75BC28BA7EE82D4B646D863DA5B77FCF3BA7121123267B0031647724E4A5B9593D922D5590991DC90A19EA4D9E5A567BB3DE3959EF1BA47FC29A9A331E34A3C3D4BDA1936F98C1AC3B006BD1528BEC0A60CA472ADE66D2FBAF7727FDF72BE2D5E93120308C16DA6E508442A2B6C22CFE7A43A58AF3FAD55FBDC8BFCC26CAEF4CB3DF62BC9A63263CAD84CCD47B2299D471173184988249837B59A2D99B7A6B05A3656EE32F1AC52B975682F1EC6FB132433F75C6BB1E7CDC7679340AC991706CBBACE6D8137C18E83C2A74BA5B80D7D5530362C0BF2BDBF62B6FC71CD01AB2C0E512A7B53624C58FCE7F7ED7D27DE9C5585DD76BE3C9A09E943D1A3A6BA6A3CF01AE47CC29ED201CD19CAAD15149F39791520E6235B8F3442F614E2880DF4BC7FA89478EA1930FDC9CAE7042E3BFDE540BB3C7E7B263B759094EA52DA3710FA7850F031F47DF4DF8B2466D608049D142CCD492E6CEDAC0BBE15ABD20082DF14E7CBAE77B80EC1C7077EE2BF31214AAE833CFD392246F947F76C35FCF6598C35F37020C0C9BB8E7FF67F2259CADEFF5F468B5CAAFC810541D332FB132DC8900D6C1415B71E5D6E9BD9A2A91E7CE41FA20CCE431399F20224DE076A88829DF8BC857A4E0D5819DEE384B15AF08A6D66CEB3DDFF9108D66D75EB321CCC3D8909951451B34DFE78E721A7151696AF3227203EDDC88B44BE7E2C3AD01BED76CF209C01D5C1E218F995F1486F0B86CBD6826CF0F11D605FE8273BDBE2259F54083F7F937273BF00983F072DFE4064F9A47124CE53BEE19F287882F27FE309D2DE0AA89EFEA412843C0853D4C437A6DB8E2F54BA6D5BE0E93467375B1D03449E0FE865D81E890D237744CAECDEB97707E00C4E255486A739E4A0E89971ACCFF973951E0EFF6CD1DC0DA0E5DC7A6BF60798A6998EA57790D01AF63312C096D5141E5E8A72CB62FD6E451E054F58FB13B8848FA6C5D020D5F35D4D1A920248003A478417C8F28AA44E7C327147BA1EBF1A600689913008F118CBD5517D4D2F1A6EB238D9C6D9F9E27ECA0552192BAC389C79BE528D03769D8232C53933099F5711E2FD7DB50614201E8F06636BC2B2B3C6AF7FA731565578E57ED4DACE821F8B06E147EA5FA050F913F6D6EA242DA02F32D229DC10D79069662376FEF772359FE3AB538D095E2FAB48AE7A048F5ACA53FEFB9367ECEBAB12738FDA5C9C70ACC17328BD1EA2CCE1185F11C6308EDE61BA5B0901B2A78D57178333A6095E3A2FBAE9CFE4B4BA8036D1E551A21A9BFD1265A6F8F4ACD40FCF32D1AE7B626D553C51242A3223AF016E41D55D7D632E5DBE3CA4FC0DD4B608F8F532D6011945471481498D0B04CD9F7099BBF73798518D6AD8E4D326D5D1306ADD455033872FDC9F4B459D7440113654ED4E4AFD1CA292ACCC776CB98FB9C2767EF51221AB148C9D7F7D6D8499EA6863BA7AED43A4F0A9EDDD6490EC60FA2F86A3BF4848479E70ABD8E2DCD0B763662A775C5B5A1AB26BEAB6E2B9E827E76D2373093CDB428BEF2998D2AFBE147392A2372BDD8926267AA87CABB51C031D53DDBC2B90ECEDCF36CC6A3167D77C13304E6307464EF527B793B89D27D6E71D5D6BC85F270FB8D9546531A314DFBED1CB6F70740BE4BC9BCD9BCE0C1D119C8259858F2532F674E6F5E1151989BE61BEAEACC57D36317ADA9A79C45B4175638D57A45CA53CA475298B561C36BB727833322182BD1C149FED8957820120117CEE99D2C2392E8AEB13B4D6EF25D87CE7CB223CCCB7E89E61A970B81BE9353098219AB439E7EA8ED239D79E261F3F7B87A9F0EA7BB0DA82BF314C4D4CD553973E7411037AB50EDB330C132CBB69D5A9883DAFF081961D7C1D49B1EFC33982992967AFD90BD8A65C816281FD62779E5B9C82796D4251EB503ECF4B292168F72267655E0694285E28FB0D6282A8DBEEB807D252950AB85DC9ADD61CD2CD49CCAC2C74D1803B59DCE91AAC667E81D924D967A47796D53CBF46A192C5A8E91489B67F37E4554FDC0537B9323DC2CDF4EF3297CA8A2F7DC9FCA65D981C7F18E00CE9D35C18EFB8B70444CC6013E0F22F391C0202183A2DE02A59D356C1CF2E55D65EED1FBE6C719F66A92B2E425B320407D2668CDEF4CEEEB7679424A5C1404C88198F22370BA33090BD25F568F6FB9AC3A933A4FF68AC9BCCBA5EE7B0831D5648B126BA9190B284F2630128AA64247D805DDF7E882C2AF1342E49824C70035550E20B755EBFE5600B8FB1472306848A8D4D1E3B79A941AE0C8E9529F3716B855677C949DE3148908D15EE1DA69BEAB409427B5471EA2BD9308A4264D24D2A60AADA5CCEBB88D7F4EADF77189E29E19E3A2348B1D074FB22BA71E682F631EAFF35CC7E56C236E708C18C7C57CC6FEBEA18C486D625D2B4AD69C51A479F22CBF9540F3FB9CB3CBEA8702BC6845E9EBC0F35C630B87FDFF16694F3019E0BD1BD9886660FD91AD0F49C25C8DCD4099B5D8E4B24BD102AF7D65C6F51EDC8D262DF3629811EADFB4EA5FF27CE5CA7B6DC0DDADE55E5452FCFD5C3E33D19D3E66C4929C6FAFFA17753AD40C74E2986CB8C17AB45ADECF8BB7AFC9F7F240063A4D5D864340A79AEE28B333D9B26E28441157C96F533068FCD4649A2E3203691268ED8A67701D5CD48F01B1543A27BE04A57015F5B4A52FF16D3E0F33C9E138966383C4CA5B52A812F9515F39E5DBA852D4F9252F497014241A18277D9838641C7D3C387187ABDA9ABC631B314B94F362397BFDEE023028AE83C389B2606D10B45A27CB0122106FA4F6978BF751104CC87B2C51CDEF8A174D77F9134E66068F6EF406D9662542F8FD776E489375EAD90DAA6ECB9A643CB769A0AE13A38C20DFE7B00B4951F5E8F8FDBDCD3ADADAD6714A787E71277DA5BF11E8E40E0BADF926A03C2176951BA0E79CE5BD6D505801FBFC663B5F78117BC6D9BFB81FB5AED66A297B21619100689BF9B2C140FC04399BB9ADD387522667780CCD8FFDCEB0E0EAF40091363420E70700471732BA76B82CA5FF609BB2867EBB18E6731FB376E0ED0B1A16E04D710A3B73D9D9A994A9A48105E72016F61C0DCDA3A4BFD7AB8E4D49452040C526082D63C47D2A7B8B6B04A607143F7A4F6970DE903BCE024B380CCB388580DA345F6089B93853309A77135A2AA98BB269DA7C47513DE8E39CA249739F0F805E6C19268E2902FBEF02104FE10B3026251D13F469D1544A7428E248133E1B08713075620DB81D982740DD784A449FD5D5598CD15F5B4B0AF73D9182190EED53273B4AAB3E07455FB577CE5DBA27F63A349D86665DAC82D3349127E27854C125C717CFDD3326D92C62C362734FB0107AB1DCDC960052E1FC796F72AD793B3023F32AD38E58B65AD46D6C1387DC425D33DCA3DAF153E71CE60A126C13594B2B79592735DBA631323D28C15E46BEFD2A1406055F0881C188F4912F2952EE51852FD5F0665567F66B0AFA1865292CDDD239161F7221F43379D4CB650D3CB3095C547A4171C32A9067239BB1D77CFEA8DD915AF62468BAC13F62E90D15D5420666215951094E54F6A1AB51944F93939943663E927997EBF2FBFD3D4EFB04D2D616D7E99942281595282EBBA23181E1C55FACA1217D06B931088D0EC446B1DEB281BFB1365457B8F8E28F4C1F2C840AA76383EF8A92053866E48F2E64E8C3FFE6AD84A5633B97A8BD775CDBCDF8D23D2CEFAF401B7E6236471618D63BC2C2FA3E0EFB6884CCB5DE0A16A31FDE0EB47BF811AFB138D2107CD49783F5A9DA214247258828759E44E8AEF92A7AA26A95081B6741DE9C15A5DCE127197396AFB5C93B0458C0F106181636789F327207A49FB23D037F0A7188A7E63DA968007119D6F918671951F77E03D121A2F31B0AE38AFE2AB2F0EE993A2D2CF49C531E66BE4CCD86B28CE4DAF9D3E71307CA87AE56F60B93B286E7828657BB6265FADB82A1BE5772E7F5E89BA2866C16400A2E0EF744830D644F7F976118CCE238EBB0B5564F6AEB37A9051EB4EECDFD7E51266FD14B56B66DEF1182C3FBEFA0DD2DAF7209FCE80A5C28B7A842CC0D376636B165079D68A53E3380EEAAF19624B334A7E95FC317A0123C670F97DAF9F38BEB80250DF03BC462F3740A864604C2D29B749458AA5389625645B06D90BCF7139267261E7294527FA96DFEA0018AEF0E053361F6E0BC6AD99E25C54E375AD32ADD2A0C45659027D4EF052A65D857B6A055F16092DB8BD226BA199512459089E0340000000A4C5E553CA23432A03396418B3C2F073F1F172FA526BF63EC88FA128DA3218BE6EB95396C602275A47D45C569A85A358F26AC695649C5053445CD90C56C05392810806D86F7BDDB4E4D2ABE9932D083F18F2A50C17294B7F865EA8ED09F17DBD884EC26100EB3C2CD06E4598F054CC09E21979B9D80CE0599"); + + LMSPublicKeyParameters pup = LMSPublicKeyParameters.getInstance(lmsPub); + validateSig(pup, sig, msg); + } + + public void test_should_verify_shake_n24_w1() + throws Exception + { + byte[] lmsPub = Hex.decode( + "000000180000000DE188C16F2640A361227C63532B1003E806038B1ADF081AFD9D4C2C5702BAE427DCA7FD40D8135830"); + byte[] msg = Hex.decode("37965CE6378A0EAC5FF4180AFE4D08A23047F9781540263FBC5488F2760D2247032827FB45D6688370BBF25FA1A9D401350EE3D63714045E91A2BDA00E7E685153BAB4D34E3DB1141E318C199FB7E27AF49771DF5F7501B7FB7639F7EB86B5FDD591178324C898A6ED434B39CCFFD5CB99A926C37C3EE36A3DD89BE7E49F5769"); + byte[] sig = Hex.decode("003A808F0000000D409AB9BD0993BAD6FDD74779682B06AF517E6236449EBD40C51496C6534AE146ED6528BEFB3028A50089A33411E7B916520E6FD07FC51317FD990F184426A38F97CF78BCFB3BA46A287FF9EA892E9308E745F01BD4494854D0E9243A6EE139BF39E42CAC8EB568D3285ABCDDF6FB18E071B6A383455B8C2DEE94E88A5ED961274BD98CC4D293B869320FF22BCA1B69ACE337B7A1A1EC9179131023F8BCAC112DEB3B146D4409A99674D3C3F7D52B9FFD59A459F778F4E0E3AB91B5BE5289EDD47A7CEEA0A7B368F3637BAD33741AB3FD60E2B4842415ACCBF3B9A516CDC870DAA840C35D71DC3D3C6F5FCEE2FFEB6BFD2EABB34B01263E3C963867BBDBB8726B7204B1C78D3A4137CBEA598DB8277AF03EAFEC7D1342A874E4311430D796AC7EDC6608C5F91ED17E6B7087FAED38B940AC1E456749AFD4A6EC17F22BBFEC18473E1ACDD3D55CD0480941009C5CEBE49CA7671DCF0544AE6FEF13DCEE911C6D525E2CF6CFD0AA6CF20754328FD75FE271A79F10999715613F7BFA3E07BE783C61B65DE252D56B98455366410545710747623A26F7AF365F00DCE90948ABE79C98C58226378CFEA7B5FE479B4978201C3C172478E90EAB0B5D1F3B08B515FD08F7D30B3E08084174ECE5DAFBE6382E5B157D171E26408276DE527D088505FCD02E24E86745AD9CB97A09D799DADA00E9DE7E92B7333AF5A84A3FE7F935307EBAF6E7281D2E67F886368972D8EEE2BC518650C0660634E01D440FDE0BAAD232F2997AAF887647A557A5E6D91583EF9B061F36002F36724EE08939148C33C5DF83F9972C3F511D522740D0282762DC08D2F6A9CC3D5CEB8EA9A2DF8F9C2D8D675986E4396FD46F692BA3DE864969C63596BE105500FCC27EC15D33365ADFA5BACAFD6CF9C88ECD55947DB233D74A7CA711E4AB93BB48CA326B0944DA3BD4EB70DA3770C3BA8A5BC3BA96263E16394877EFAC613FB9AB5644F9744080548732804028A89F762EC4613545DE4AEE7306511ECBCDB02A35B771729953DD00250F4656ADC0EF1015C5FAC92D770158A5537BA54EA8205EDED7D9D703DC66CF5146AAE9B8259640B24B75C3FF1DB2B7474770C608C8B7248E8707967C1F5020AD74AF18BCD0BBE3824258F6ED47865DF2732572E137C87320366F251A13C8310241B216567B1D85D4FA76999AF64CBA131BEEB54F5DD56CE6F2477AE76A1F9755B57FD6A376F3E3BAD965F877C656A4BD7F071FE867F5C1DCAAC69FCD2A1C362B7CB9304A315C800F7E5F012E438CE2DB8D6C9613E2D13CCF2D703E659491A08B21A9C472F45931A0F3F2643C5E7EB4B8F0983AD44BBA5B6D7FA6A03ED4D0AE492F749329AB8688260258A260946014EB983E4AC62588707617BAC78E1E87CDB9204C1E86BB6715BF28F323DE120B6F684C827EFFBBCE7ACDC97ABC6B59BC87AB4A8F23CE5ABAA1B783B53EE8C1BA700A6FE847BC890A118FFA314E9F7DC905283BB02A84172D92CD2DA566B9A095DFBBBEA10CAEC6A989861536AF1804F5C30E9BD0F1AB4E8B5166A2A1348F58C5968FF9EB23519271941FF5D62FF83079CBA0BAC2C6C4A9B141CAD2838CB6FCD04644813FB7FD12E7D9E9B719DB33DA9DCE4A9178CAA8472805D199AAB655DC9B9D7F0BB47DF07A10850D42E0C8555144E6F02EC87FCABFB896BD144770FD98E426972B5FDD37C0A44F453AAFDA66605E8F78FB79AAE1A8923DDEA6EE979DB6576A9B962B92C0C1FCC8D1B2C774CDC50CFE6AC19BB4D058C533F4BFF795E0314385B58631A60D3F12F34543439D364A5DF5A8AB153DBC60A587D85F3B805885591232F31A2B972CCF5658A9993047F64E4B259EBC0D525DB23FAE95F0DF7296F1B35ED479CB124A18808133C48387CF79FA63408B0367DFF0522B161D2588DB5CEE667F435109DBF14CA9FD4A408B4EA0995EA1CEBDFAC320680B23D4EB50DF75F3A4263A8ABD88E5AD3A62DF7ACC6E2CFEB583A4DA5F919BE8FCD85D16D36791784B50EED2F072E23CB62741AF1680B62BF880C18F1231DD91A55D7ACB61FD6A34348F4311394B39C26E19154EC04F01A622C66CC528069BEA5E5D807342FCB31E2DE474D60E11EAF0B9E24F8F06DF72DC68EEFCAE17FA9A3704FEA8196675E2E0FF287DB1E025877B08005B7A0B1E96BFDD54C5F90C5803E3E552151244C03CCEFDC43689740E24981109898F5CDE4C16E4B29D074B73ACBFC4B288F7512F5580B04AAE0385AF1C2AF1FF4BAF4D8D8410F8DC2D0506755DD5C5BC0F7CC21DEFADA8AE32A59B790AAA2826681C7DD30AE0C723C3906E52720C2C61C7AAF162A833FF45A6710BE122019391E2DB6C3AF5985B2F905808A0ACB7EAC5F4C5D462D2E67D0596B15C58CE2228187DB68C06E2C56F2228CD8B9B9DF74C7D4FDA7B99499E49495FCDD275C4D5A48C4AAAA54C4D6A91A1DA40601933F97A7C843BF59F5F773F656362709F564815516D8A97AB17BA92A7C8300A572D8F8A71463EC446FB00A8D8459A030495D2C7F83FB48CD665CC750318BC6F1F79C9A8B5F515B0F7C6F9DE926824E6DBBE96F175B6FF0369DD0FD5EFC91A256A88D5D3E825065EAFFA98ED51470BE4DBFDABFFFA7351C8D779933C362FF41E3CF387AFF42841B208B1572AF015A08A3D7AE69D476660AB6E49247DB1A5FCB9E09F0804A3D72F1178F443BA64F8764BC4AF4746F815817623D91AF3403203AF89A5A8F60F8063AA481712EEC3E9E4BD1025725E068272C4742AB874D5AB2434A49450F9BC4BA581D582FDFF785AE4E663EFA3C9DC4AA63FF22CB96875C43FC9E19B33ECAA1AA6B6AB670EDDB843D7D218F7A3A26F10618AF43E246C3649034733F5EE86DB8BB2DA5BDF0B61B6BED4A8F774A07F62057758899537BCD46656231C2F470A9D382362CCB8ED747C25F1473C74A661A346202449F5B55EB65A68FCBE250F187BFA2B599AE7677DD8F27DF7369257F90435099D3D0E663626CBB9848CEF2115844A930DBDA36876A36C8469139EB25C660251E7E4B370EFC52CD046B01B8901C359A492F91D3B14388200F3470934E851887D49A9021A3129E9B7A0D83DF5E24B98906487E32004BB57FA4DE6A3FBCB2AC67D2428711ED5DB076396DECA297137FF2D33A61E8596248A0268F5776AF906E7F0744B684707F2C0E54B5B3FE59404FC999BE10CF5802533352584CACE95AA5B97AD04BD9685B43B2AB01663E181618010DDDA4C0EF5B10F4D50E96559EBDB6694BEEF2F299BA092C55470FF744F7AFE524E04447918B2600BFC68657CA79D3E453E85FA68E61F72B72A8123814ED0BA121205F13586DE25B66C3B824C6561DAD2F1145FE4D735EE76EA177D1F44242AE1D62D9B4845F45B44532F3CAFBEDD8F404BFA04736E8CB8F6A4002A7985BEC7360CBD2416416321C258CCBC70CF63ECE7766C9F6A1054588DD9DC74C5AEFE2821E97D72F4E232E35BB8A9DCBCF693976C3405D8BF95DE16AB807B0AB74A9CDB765F550FBFBFE1FCACC9DDB01A673BDED3A45491B4E525D6FF036E1FB8B3281F06FD0ED9932AF00B7353580B80CFC704DC242A9BB936302ED3DE804577E204E8FEE73932C291193BE50292B52916B7B68294B1CCB36C04AE7BEB29433AC458F526D9BAF304B136682EB5B6890F76D269A19C4D6D4B0073DE9055F48F3C4C60C97C4283DEBE41EEBF77CFD60AF50FA47D342EC8F529256DC66B38D3D03975C0B0A721F8D013A2721256D17EA524E17709B188B9453A8EAFBA9E3BDD6DE828BBA69F9BA4DC773C1715EDF9AB917CB22FEC219F35816BD9F2506882E4FF68FA6088FFA97AC402FFC07547283C4397C176CEDF72745064713CA1F3E71936D1E03A7BFC1F5E2F29F105337EACAB2E137BA86482517D04E3585C961AD0F2349E44BEB99CF8281FD6BB550A13CD691C47A11B0FAF99E187835BC603B67FC8CC1D87CD4DB11A4248A3730AD1DD3FF801BCB211F484DE41B1DD080169CC022FE7B793AF4C73952860B0866DA41A1A76B1BD6C7EC0E8FCE01129026194F74CAAEE3621578E45CE3A318F08CD2AB3A51269707875A0D23DF959860144E63578568D94F2821981EECBD4D40E3605F968B491D522A6A5E52969D7E020C8D7103FE7B001BBA75658A32DB147AF4B7C4BFAE5134640539BEA2CBD6B5F0C0FB3393CEDC3BAF5A3249810E47702CA6FEA5A124E933A4F6689FA8FA4C5E0AFCB87BBAC3AA09E55656CB922924A62A976C339EF163BF59D628118312A7B8F166EF92C6390134A5763A9EF62233BFAADF35E161C93163C0B65F9B09F56F6F9C3A650EBDAB88DE5B5DDE673605D71A5CCD0DC70FC77E575E0B9234834351FEAD0DC5D39B3E02689E0DBA7A37594CABD585587985A7B3077E61ABB026570D77DD1512E44A68113E86A569B5BC4CF68997B8E2ED2FACE7AA787CE10CD16CBDD5DD8DC85014B3583DBB3F0DC0A927579A9BE5F0937A1D92CCE62858DAF027F7CC88AE3430C9C0B3ACE11FC0CBB0E3B58FD6C69A6E03A5D79A3EE6ED649EF28A4FFF7EBF0A04C26E30E911DE0F42935D00181DB8AFB7C066E0B739A20AEF725816728F144FA4AE04179905CBD6B69443DE46D0D2BFB556685C11BC1D14D782592705CE89D26725D29D33643813F7A8FFC3237D2633D0C5BA210C5099EBD4B0DEA523FFFBE43A2F76E82130B8E0972B9F3419D6B4CFBE627AA547D4C811178638E104C7A4F17577A6BB0ED7B44CE7191BDBDAB14FA86DBCF82238DBA89A3DFC309F4A6FF6088FDF55BA4F24D7F78B5CAA625C2EE0B820148FDEE9D224A6A6483952281B1A27B7A7B0D7CF1DACF9EA607C35F4F4E5DF12C3531BB4FCF03D69EF7F26415C5AF7D4D8A3B5D5A58E68621C97789BB91E522ECA4499FFA6FFCAE2CE89A339CB290957386BBAA96479CD1FF4C1F9B81267B0DA71E8320CA31E56648DC369093C259E1B8A09A0F9A154CC3FC69CCD4B6C4BDF661F00A10BF6F49216A69AEA2ABCCA9891DDA801C3C93AF35000C51375A417BBD071D5C2C1C999D428126EC0D3590B7613AE2E683BAB3E68C176488424964027DBE633AB33F175827E7AEBF6A85C8A24DE63E6DA473829FE05C32C3BAC64FFB32EF5B5DFF18FC2B69AA8E78D6241A62E63DF19DE90523E01BDBD64D85E349E8C002B3C115067F70AE6ECF56A8B74CAC450B7476B236FF50904A3B3FFB0F021722F6FF13603B153D4236476A921784D88FFB3E26436E10BE441BF9FA6443203C67356903D01281051547776484FA38C68DD30A30466427B4C74A30E8C315D9454B7A9DAD7FCEFAD4B266A8A0F400D78B6A247CD80A4E9745A9B03E258AF019BD1ACC46BC322C5CE74F3861BF49A2A44F74EF7A676109378ACBFBC0AB0128F358EC1CADB9E22408DA5A05EA61B048BCFDDF6DAE2D20BD67B6F0350B6F40F3DF8F2A7842102FA096EB6C04B773CDDE83F2B21255E2A7A6D8D75B69541AAB744CC2D5E76D947DBE83151826455FCC185E5658A98C66CFDDB446934B53681BA51C0B4C1DB19D4A19602DB53E591D589187076E674F915E680580EAE077D3B2CF5F9343654A02EA1967201664C0E0C0298A3624196C8151E5706926EEFC79DF82FAF4A47E67449F0C9ECB91866F2CFF0BA8423787EAA415A69F2A2BDACA67BF05666D08A2058AA0A6012035ABB9C46CCF1B8AE95476B25FAC406270AD1C2DC48F762676D37B9543236C7B382C761FF12B7E5B738F8B266444AE1C718C09CF598482AB0DBAB8107ABA6FC465938C9CB1F305A0FC4EE7E3991D674C0F5E0C99E335CE6F1F2AD45FD617FED27E6F7090CDF228168DDD94CA396B47F10DB14A32FCF45A7AE7EE3B480E9FED7555DF608F5A2F9E89252C411D186BB5A6C30E47C6896138A6F1197795BA793C161029FBC6926030910E9D8D64C8482C282ABFFE81592CD13CD65C569A1E23E68C983C462A9950E15362BFA4AAAF78E86CC27171CE12DD7E018019A565E70611FE2288243AFF78FD27A08555F698AA1D809BE529A9537EE737C7903286A1AD5898A25E26E259095BA572B007066E1356921B023F8A17E288AB16D902F9F550599C6060A02FF09D05A70DDF74A5FB44ADD74780C233C978127DE646E00702F2F6C70816C1D281ABACB19F88FE5066A7B58A9B675FBE224A4AA6BEB692CCD62065A7368169E3C022F1383DAB6075690633B15DCF6E4BE6912F63E3EE58A860C2E139199101175ECE852F3AD5B91F56A417CC04B3F20E1DF1FAFF4CACD88153A9A9A84EA07415B3824FC8C5DAD91D2A9D373DAC5B1EA968297DE3889AD3E45EDF401201C04B3FFFE64C866C0B995A92C0247EAF49DF7C358730801E1158132EA5876D049B3185326BDFDD796ABA930F64716D21308AAC87AF5FEEAED35D1BC5EDAB2F079600ACD31F6786729CB36B545AA45A5F91EA6E14CDA7697129D0F6F6AE1A31D5D72E934273C965D0FCF5A27F68B3D29A2A46047B42708D999905D0CDC8DB052B362CA39F91D23257C1DC7B65C7D341689A8C8E1C5DD49C21776FFF0BDFDE54B8B87EEECE9062739E216D28EB86112F2F26F892BF64599E9F8B708FF9759C8B516EFA52D306C993D907E230CAA5365200A6504BF5A804636AAB43D74488E627ECB4AFFDC6B9270970C0FD556F1DE2B5E4154C539AF1064206D030ADE2B6E95D7C46AF08C6FAC6545FC10425AAA37B18540C05072FC7A1797466D5B38F7291DD21FD3811F92C550EA3F53A94ACF23A8B7543244C3065D216732A0E6A160784DD96A3D74DCD4B762FF06BC5E2D2892366345593B8FCD8DDE7F4AFC731AF8A3B77CE5EE98BBCB8001DFCA8B5CC282B0ECAF9E2682397CCE86E9865DA379236643C128E000000187D14B68025915B5F25949A569969578748E2058F65678698DE19D5D2707A3FBB54FA854935F833555CB69396C4A11E9880B7F991498D3077099632D19AD407F2FF1ADDFF5885D4F0FD3EFA9F5869BD0793B96DFA730C6F0EA1BD63E05FAFB084BEB80F549740EA4A9032E534DCCF469BFCDAFE5D58C1B41832102BBC0C5BE6945AB3662C239CA66AB4FFD8A679AE2E9C67749CE6E578D969CFB3405F7E71569797D759FCA5C1D3F8C8F17787D70DBF05F72734822A393DD3C4B123DF4BF9E984B420E35EACF645DE1D401CC5E5D6E32C9D15DAD80CBD493E74E7B75094983D077DD4046E530BC181D958CDE3BD77E2F71C1868DF461A048F603FD6ADF4C802250DD1AF6EE962A4B6FA8CD347FE9B662CB70AAC271E77356A0465CE6A2FDE7658FECCD1C582E4E733F98F12FF0DBF560070032E73B4BB14B106AB6D4E4F2C02D074368194468BB788975F77C806004ED8D6D5AF2A9A27CA8EB774037A9B505E25EF66AB692A27E2918427466646888A606DD71B6786FF109B0C3FEF6667B67A7C6034FEC2371F59EFE4231406A5CA61851DCF92FE76004BC838124273D253CCCAE3C077C3204490B20200CC283B5425C8C138313B4331638CC48E330C052C2902147A3F82CEA7C7344455234EF48791ACCF50965B6ECFE24AFE070004F1A9FE58FBE691FC8DD81AFB8ABD89272E033E590DD14C1B59BB38BFD3E6D9EADD250A944F8F2D68AC48EF0E59E6FA56C44F88F5E00DE8ACB300EB15DE2B3EDEBCDD731C934D64A4B321F3225BEB8010B5027DB3FF655E63ACB6B51C3B242B58AFEA6E379199A356BD83A28EFFAA8C9BBE3AB9519D409923525E34F0"); + + LMSPublicKeyParameters pup = LMSPublicKeyParameters.getInstance(lmsPub); + validateSig(pup, sig, msg); + } + + public void test_should_verify_shake_n24_w2() + throws Exception + { + byte[] lmsPub = Hex.decode( + "000000170000000E5AB18087CB8CBE2C7884853AC5FB8E6E59EAA74E7DCD418FC0B4545BF12FC894B163C438C7B993D2"); + byte[] msg = Hex.decode("E95E2F0D429AC1A228DFE1F4D11675562A9DE1AA22AEC7E769F8609E2467083BC9382017FBAD3AFF52B1B91F7DEC31B6099F6F3F5A85060A762BBA7C991353E1FF5FE003CC7FF699DC3C3028B83E122475FAB27849089BAA3BED97F147163B82D9725E8F10A7B0BC17B947F52F41F70D1D0193D5952D535DEFF0AB7D3B0E5224"); + byte[] sig = Hex.decode("000459150000000E562823BD69497DC096C8DCF8DF74BAB93F3B4F7EDBAC174EA411A2279FA65295D82F397A0F84D830A9F8FAB22C3CBF52294452432A4769355B9188B38EB2C85FD315FC1208A05F06B5B8FFD7C10E6EBE103C5A1F18FEF97FAADF7400D71C2A2375ABAE2755A8895A159B9DD0CE15764D9F4A4EFE2E7BA471AC99793EE5F66C79743783015B51A72CEF3AD4F3EF34293C80863AC4526B97F22E21B2E11C5D24CDC04A8CA61BAFF3AC14CD12D3B040C8995A49B16A1C64CBB1AF22937688E776F0E0FF5B936E912615AD36F55ED573889C7C05634A923167FA5218738B6359F6016D3FE80A1F8A32426CD9D6C4871C6BFAA7650F1C7D139BF1AA2B5BD2B9211723D1592845D760A8E2448892B800273A2438854624707C60EB36AF2235B1E1C0911B05BDA5BB8C16E846910EAC51BAE0478A594DCDC335D939C1F1788EBFC99BBF9E903CDE01ABAB1E9E28047E380851012B1FF596A544A98574A72494DB6D7771017AC5127724AB596DAFC30B4643D590184FCCA3C118CC96D606C962C9807A16EF208D5849FC9287C4A7801803810D3DF028F17BA7BC6C09630E841FDB9B51DDDF909AF09BBF8B4F0120F962F6AB35F7B462E6C9E0C560E6FF530C417BC4E0E0B70BF1FB2F16E6903D9B15F940655E964078AA5F3406E70A20FFF375D8D0B0EB8218D265C9FBF185CB0C815BD50DD99A32992CF1D69660C690A4CB7EF4E27639B5E84061E7A37658570E06594CF45914B1D6FB36C1F6074326BE75E3110DB8787FD227902B93E56ED313FD08E43D6E5E8DC0236CABE0A8EED16CFF6228213DBB5875F6C129AF747A0843860690CF2C5F3FC090F0BACD70B918B40D90EF30D83828B5325EB930B0B755CFDEB227EB455B9AE2302C76B02334B419DB5812328D354A5DFD529CE6F062AA95179A226B06B041516BF9E3639BF8A1856C2E5174DEC88F5363BE1427645435C5D508EEA10B239F5988A0CB9672CF5B30961C626A498C170549D3BBB409DE88F9C5D8018DE2CDF938812F4DF5FAF91EC438CB770B76F8373A230E731A6A331F9376331EB3B6F105A1550FC1B8F69E4DC1C8BB11B740B5FA9070DD2640F5AF80852A8FBEC12825A0EEAB93E0E57EAE511B141FEEE4B11ECF0E9CAC764E08372291D73C99B7EAAC4327D9DF85D5336E6DC1BE662F7C7E07D37A479D963028E10F2D7F98516CBB0A017D3BFB95CE9558C65AE2623AEBBCAD409590289E53990C8029BB78FA1F03A480B74AF4C2F782A538999CB21DCF8DAD41BADECC2451D40BCE0B2C7BC32C38FDC119E055853C00E58BC50E0155AAC80FE6AD4391E94497417CE29FAFAC3B9C7EFF053CCF7D95641863D6F689F16B306C44E2492EA9DD8907E7ECB6FA0ECDE555B3AD1D5DF94526BAD2D57D9C639B2A482054A0598A4385F2D586EAB8D89E6CACB2214D1B5CA6806F7B3E0428E9129319A3F92BD4481AAEE820C41F79090775EDDBF862DE5C170F9C582D2CBA5FBA02373853A157094E1897FD476096E7522BA9D806D4A5C6B27729ECF38AAFD5EC6424E12DA2950F294BB9174880A843635F37773209F54E6BE92DF682D4F78A2D05BEBC6DC27E305BD31D94E75138856DAEB5B62F32FD70EAF3A2B2760EA2A43A8182651AFDE85BED1440ED8A9D26197319C3CA76798CF0497A76AAED4E98062AF8439D3B4EB298C4660DE1821530AEB73BBCF4D44F4550BFE87A5A17DA48DF7977EAE61D8480EA368C4A971CD05A260A2F596E9651782531531BD98DAD3C85F71EC58AB321C4CA1E6A26DC64466A080CEFBC108E0AF434FFFD65D51209ADB356976485523E59907245E79D21DFE74084C73DD5290F18527B5905B202963992758ACE41ADBF8F0988C4D185ABADFC98B25A5B1DB614B5A88E2A27B75CEF4416962FC366DA1557A7D6C5E2654D5300020FEB409D2CA6E53C3D5AB6F09015C60FD7B8C6E58692FDD3A6B05616FC485FF12410C49BF031F3BCC517F0D2F21DF4A86C000C0313FA3180D502F0A61B780C782D59D3C6B6458F6D86D7C18320D3543EF4533EDCEE82628EB411481D82166CDDEB9E65EEF053C327AA73C13763F889E80299D9F925CD7D4964FAFAAA796E811C5794277E33199191EE50D0E6E1C5AC27E746D6C32E7EDBE3ED772009D2F317424A799325984B44D019BA87139F06C91B678D9B58B3EA8B0235CAD7197D304B44A733D93CDE76D64595729C84D730B48368148999003873E40338752C460B4E7DCE2E1D04B7C8BFDC1BDDAC8D03C540A1192BC9011A08AD5BDD52E856D8AE2492F7644A5F212BB35607AC7B5E625074FF28D72E9DA179551A04A01506DABBADB14C2496CC6C0CEBFDDBCC39F3B5FC56C3778594F2DB804CFDA033F07E1DD9CB906ADE6D9FA215324AE9023CCF41C4BB06A4B9D09F3EECD45E9CC20FEB77DECB91B8D21E5E8E3001DB88187B3D451F915115A38F31317C1839730E4441ED309E5D51580A8EBB72672BC283B2D908A80A50E7CC2E4CBBE78687A0E83DFCF835EA441253F0C843EB01C953AB22E4AA8988C27D4207DBB1FEDCAD719C6FF839CFE15BD9D05CA61C3C0674F7089ADA5B85FD28184F24F09AC02F8A5B7B919F341B27B8F8143C4CA0E62BDA8678AD4731DB7A44B686E9C3CDFE64743FB88F0EFD21BB8E184B8F322ECDAA30D83471D785FEBF8B321BD47470A1010C175400B208E31ADB354DE2461CF23320E6F8B4AEEB9C35827085F2CE4D983B13D57C5268E29DA6D1155B7FFEC621CC0320ED1E41B81DC712B94C6AC0CB21E51A0B356DC2C9647052573D114203FEB57E48DB1508A3D530EE8E9D3D393E71CA72BBEE3934E5539E63DA7B51E31CD2A8469E06ED13C77FC05EC212A3B37093C9A8C2D66C952A347573870FBAD8865D9660A47A3B482D4930AE245EDB5F1D373DC293E1BD9EED01C79F9B090EB0131CA236A93C3989DAC5B30DBA1F0AB26DA805839C789BB74392485FC9B46DAE7DE98FA082E0A436FCC9CB2CD481FC625DFB6A2709455C693D5292E4E5C46CA9835E9D16F1E5D167968792BD89FFB42036E2611CF183380CC2015E85864FCD1340692C431ED54C6A54AC6DDAAAD79BBAB1DB0274EB852F646F3628C2AA880BF6082111607C38B6E35AF633A802BE7221FE7BF5F9F2A3447D229994613E548D80ECE807F504BB491851E866E7D910F32873DEC85D6F5099359657967E32AC70C57ABA8F9A7E45B9D80E12E7895764EE2ABBE081A62214A637680AEF17593E2D7AB057217A1941267E73F8FDA9B3D5DD9D2D6F874041DE41460F44F84CFA264EEBB939E1FB87ECB1C4E0F8671448956A76626AAA9DDF76E5CFC2CC83DFECD874AEE2F9D42E178C112E93C9468F5FAB27D7E1E0A364A215E25BCB230B9EEB844B80C62C2CDF9145379AA0F76D07155D1A2214E2D43368B0256325A266A98632ADE9F897B52294B43B5AAFD087C31772CE0E55FA32C7FD467A8110281803E81A4E0000001713C9D996AC9EC1518D4ACB08C00395221795B6024553C53AE08F21CA02C91E5D00D7FC1EC7FE6B441DB6F3AF4E1D54D9ED280EECD3C8FF4E3216DC1E59EC850502AB1C3F48B86B1599C47001AFE0E400745D07986C8B9B367EC9E08B1C36557C97A89BE099554DF248A5C7B1020F8F6AF009E86513974CA7B5E2BB57B172956C0542C09D75ADFB1F4F9A3E90B6FD4F840211C41175A28B166D3C8565B8761B42B38E8E81FE763D50AE2400AE6FCDF489340DF451EFF36AE265D335EB56240DA6FC7962DA822D6458C20D813BA657F806D81FA5A871C79A888B1C11F8866C27E96104130FA68C24C56F650C20174454115CC3E896429A47032FE77042B02580258A3DD837CC5CDFF7A82C5F5B4DC751BF5BF455C8A8D3403A96B680F0E73FE3A36F5612E6A26407E73F873E890E01451C3BFAB3B5CE147083CE53CF659A8D522B432B4EE4009ACCF60132D3EEC6B03A598581EEF5D9086E601DCA67E9237BE39DEA8BCA8B4424508592F9397ED0A78955E242DC7BCB5DAF4DE3CCC920A34CDD3060CEC6701C412AC92683D9661DD7AB9D9A4CF5EE088B50C3A72311FAEBD33475CD17340F3899EF8D863FF9E566A462BB0EB415D0C8B2003CD6EBC50626403012FF997CA69D4AC7BEEFE591E19F00EEE46A2A026101939B82F59A07DEEFDB032D"); + + LMSPublicKeyParameters pup = LMSPublicKeyParameters.getInstance(lmsPub); + validateSig(pup, sig, msg); + } + + public void test_should_verify_shake_n24_w4() + throws Exception + { + byte[] lmsPub = Hex.decode( + "000000150000000F054479157C09EB7E34A7916BF4C034E24F02017B1465BE851833CB98DB4D7F8BDAADAE44FF2071BB"); + byte[] msg = Hex.decode("34A6368F588463E30473D6AEA5F2A00DAF793569ED56264209B3FDEAFDD9A8A4DCB0B82EAC503F2A939ABDCE273F3D246DF3E62791E4DCECD4E3E098AFF67DC141FDEEE3160E0096A1C74DCA43FA25E94BADE07A9BEAA2CA93CF3CADE7E0F1E16500C84D2989D14E6E821234AF70BC1090C779A1D8E2C20A4A176CE85C6E18B3"); + byte[] sig = Hex.decode("000001140000000F610AF02360FC98234DEA82F7ABFBE4D7172D1472B5AA50EE293C8137FD43508400233BD5F3CE2656C12FDFC2235D7BF081AB8D6444DD41B9FA393362C0A7DD8737880AECB9503C95AD5A02FC1E10BCEC808CA381972A282245BEC9FD146947E0E6E55F417A2851D48A1EA235D2268E84E87BB254477528C70F16AF8F9060D483777A586080E072B6333463D033F3636DCF738A8EBC25D39A0922A53346E9C16A66F4F3086BAA8EEFDE0236BAE1C2AD34175FF7902A0623BC7E70C7399D28134CA7845BCF2503B729ED7DA7DDEE5C67183883BB3BD819777CBB6CECEA92412C1660310ED4860F242F380B86202764C0658293BC3A8582F18F3D1AD17328EE3EDF91E2483A6F4C4B2F80B19C949DAFC1EABBF989185E5F84D9B0C20F00BB4299CB600A5E7A113A0B7C51C413ADCC91237625FE2B101C563AFD92CFAA2CB46635871FD1F53EECB75F1B34C016F1C5B3681A3E78BB99006AA207B694FEA2EF248AFC76A8DD493BF75A5F2B04D791014429DA4B45AD29943FD1A63F4DB14DA8C66651EA066177B425D01F8A7085E1CCC7A8F03690292C1217A94EB10329222BFFE29DECA42C57353CB2EF5870F2280E30C4FA336D5EFEBDDE938A81EC79A35A55814E4FCDCDC281FDB38319ADCB579F3983050556AC8B18CE1F23F7563D7393CF5A19D993955AE9D481D24855CEB03B7083C087DEBE441CB3D779702BDB6F123DAC4D3520CF787FACC9C1FB9EA9F4A16173822FF65DF93F657B3D16113CBB6A9AF37E4FB6FD3161FB8F20BA6B57FBE787AE8F8DE22B1A14FD5BA3DCADD8F3B73479086EE09814503D60C95709886B066C6A93DBA5C42F507CDD4DCA930A1806000D8F3F5B13C70F807EB4CA6C47FAB4014FE69D7CD6EFC1176E075B4B5F849EA48EF124E0AFBEB97FE6A00B0ECBD91D118ACF34F963E716362B6DBED5175BBEDF5BB8ACCBA80C2B1D3B2906D49CF27380406062947D5869669A524FD1AFBA970541921D6A7E7B849905699ED414CFEED47414BE208895E352AF7A8D6ECC3C0903F5F9748B0B2A6A7E333789F063DD522E7473C518CD0E4AF6F7286332A9E4EC3A33E01B3809E7B3C64525F8FB65E22FDE422FD9BF3D491CA2FCC43A8558C1AD0DE7092AE4CF5F87F5B7E871C32C2F0E70E07BCBDC3062F50630F1EDEDE66337404D3A5968139276A6034A2326F27BB22310A109A3E3DD40E20F34FD2E6716304D946441BE5227867D316D687955B975D4E19476C70103865AB935E8CB347EDCE783E9DDE38C84E277E9FCAF0B0F6B37F6E2CE17D36EB2DEBD43521A5AAA2475FF851C02617B4F9EE62687497BD62CFDC553A89DFAF553C70D20B4EBA42600D343649ECD45D1F6EF2E2F42592A9D7B90ABBCFD64A1E742F1C3C000D13ED0ED5B66AF879342CC24A44E2B84E400D0298E9923306F6D4832DF847E37F79E58457B3BA5FF4E46B41419E8F7D884311EDDA47B6575EF3571513FA24D9FAC2596707234D67127C60145F18E669B2F1BF06BD27572F56B539EA61A6CA98DB4347F3E89D482C17A963B6E8148870F18B8C9DA51216925C86A0C9FBDE75F13663C236A041463B40FD187FDCA53E6823EA55A4BBE9062AA45535F5EABAD2BC23777882E0F0C71E4E0881598D86B0F588DB9C90550B587D5B33A8D9B33980B03247E722843EB54C94E5E18A22B3326FBA8FE917C3048EBADD2CC415B49EC754504A689B96C86E6AB15A7A315A6041EA71960992DEE40E36A23D28AC8682D3C7E977D3EE295D8E92900000015675208ED60F2C8D6FC359396B44719BE9615452BCB68F35A7FBB1FF9335A421AADE038D188A1941D16FCF525958E678BCE6D17682CBAD986AB6AE78CD1ED56D1530DAB56EF8AE0FCEE2CB7882F55D1233046A38E21F7EB8C4F8E9C60F2DC692E562C113E2A5058AF5F319CFB5C0F9F344CB3219313A70CEE7C2D82AF77B0418AC61411A87A20B01EB39931457CB2946C551EF17E0021669A3658F71B37E1D7B7647EC6E08444E9B7AEE8789D79276CE53AE47734002F1E1E2D426C95E454E1B3F4FE2B2E3F12EB1CE541D4021E294F3C31C79A2A2D8E8652A371D3302D8EC4C987557836C9809210D167CFE47EDA0AAD"); + + LMSPublicKeyParameters pup = LMSPublicKeyParameters.getInstance(lmsPub); + validateSig(pup, sig, msg); + } + + public void test_should_verify_shake_n24_w8() + throws Exception + { + byte[] lmsPub = Hex.decode( + "00000016000000104A90A81A143279659797B572866CAD245B3E55268DDF686AAE7BB9A5E77304A0C8220ECB42BD0088"); + byte[] msg = Hex.decode("0B2A3604599F2675E41098DF4EF0A570270FD86C3531E33F6C7AF3820F8BE2C1D0F4138657244ECA0AB02CF32CCEA7BD0EEC561EC9DFAA1FB08D29A86930261103C4AEF5ADB35D7D2DA24CDF5093CC95225DB3369CE6867EEAC139B4A27C6C56907D86F964CA1BC123F2044F5E94E0EA42CB24D687B68E8ABD13C0C974807032"); + byte[] sig = Hex.decode("00002F9C0000001063557BCA0E9BEF9B863138BF1701A277520C6E7E020AC0ECC0877DA741B5F21B93A98EBA55DDA341B24CE7AA336204AE0144BA4716E3304B66BEA54FB3D4177078727A5420BDA5F3E2D0F9C643CDA3B38FCF8DD3E02D169C0A8B3797BD013B6C28F26A8C2993F7712B0DA09929FF80A2CA21A6E4949558ECE114826DF6F3D8C620A1323C2CC8DCF79F917A2FF891B8B375465A77D67ED9486B4FA4F27F022E66CE076F8C908FB2BDD822B1F890E68AE57DD28CBC8943F67B74D1A3D074CB41F32658C563AF59AF583B488DBB34F52622E2359AB0805E1F4E2769C2AC4DDC3595018EE4C27799BBF3C30987263F5CAF5566E7581CCE73B1652D6BE4F8E1F6A55E00FC4F263132A025507F342B914152F9A5DC05E0EB980637C19A250B8CDBC7B68266695FC803DE027121C635438C1408CEBCD9FAD46586EEF23FEA11A724B5F515600BAF951EC8617DDB3E5FAF5D13314266F4C0F3429327E46A580213134954C4971E53B45B322CC7FF003D1C7716DBB5CE34BA8778DB8E09F399A7A99FAF402EE97F6C007FB1647DB87B0D5AE05165BA192D32AA33E3246C85D02ED388333F02BB96217C2DCC45F01791907A78FF52DF69337F3AB4D0F2515752CF75960BBBBC09020651738495AE0C5A159040E07293FDB98B8665E82166D15F5960D3A58988E9466DE59ACF4D724D254BE72820FE9A8E634B351D4B8C07E911D23FC8B0E87684BFE54C50444665FBC0FA6430D61A8BB24E2AC08BB8A7BB39866C61D5180D6F0D1DB0411A923F5050FE3E2CF2CD0692A9593EBB2D0C71221AFF04AA489218A0A5451273B2D1EB136B1758B77CC113186A2319313C06489ABE3CE22B932D2010716A06F1DC76F0BF519C16248D21544447E1FB7A002EFB39F8CC38968E1907E8DEBE076656762A0000001648AB38A35FF650BBEE245BE96EB43AC44A4C8B03D1F33CA59025C728C5703088A157BF9CDFBDDDA49E46F8A2606217C8C3AD12E68BAF369E40E24C05297383583A88DDE17F34D7347C46C6CB400239A0DE9DA2197A178C6551D563FB6A12BBE4F6524CB80B3DCFA75052DD0969C453132F7BB1636CE1B221434309D860ADBAFA86620A9778E03DE506E0C56F1D4E024B66643F2E4AE2065619575483F31ECA4DD7FA2D81180DBB9DCFE60CE660051751A4958F1683EFC5622DCD25613463F27CBD31E67FA1A84DCAEBE12787509EF6F9FEBFA83CE35A2DF445E59F60A097BEE4BE0D58068F6DA39800045458DA799ED07EE05309DF9D62D1869662A975101D1C4004B301CBE12B98DEECF2B07F3C9D0FDDE64181D4C568DD34655EE9C514576F422992E80AC9F4BE79A068F44042487B454948B58F474037C06F6973142109D1028127765236E4EB93DB6CF02D09281C8A0C690339B25BE4ED52A0D47367BCB5A77957A932FDA1A0"); + + LMSPublicKeyParameters pup = LMSPublicKeyParameters.getInstance(lmsPub); + validateSig(pup, sig, msg); + } + + public void test_should_verify_shake_n24_w2_2() + throws Exception + { + byte[] lmsPub = Hex.decode( + "000000140000000EF45E0A263A79A7304D94B38738FA7E8AF4D7503DCC65163326FBF7AC0C8C938B2D1324456FB956D7"); + byte[] msg = Hex.decode("2EB454D4116CECF6A6CF72BEFDDCB5B6204E5689BF8901B5926692BA04BC7EBC8EC21E2B4645C99F85C9E4D9A3A855594D019264DC1C034DE09B1ADA0B71C08BA81567533503B8B2B232A5C3D6E150AC409D2CC54727D2F616532FFEF87CD12B8CBBBBF45596F779C6D98BAF121AA010991256DC9C4D46640ABCEA2C7D7E8C3E"); + byte[] sig = Hex.decode("000000010000000E31D755A2CAB086F5FA0FEADE2EB40D95FE51D049A4EF92BFC8A1C8C35AB5F53BA4FBA7159FBD49FB92D31E9E9C46C4ABBCEC9B5FC30AE94BA57F1069B189BA8014BCC57F34C7313D40C709600C45626A92E59976156A60778625891835AD009AC535AD6330376467113C40FA2C205C39BDDF64295C6ABFDCF492BDC17894EF07E697A420EB68CF91CEA8D7E35A05E5678F4F5A6A6CB9A51D11BBCE52493B9B6522CCC360ECB1B5994E695B98145FCD952341ED0FDB2847E77B82ED72921178BE12BEA40EECB0639C483AC78958F940A674E7A9A998D44B4FC854A303C2BD22738579D1D6F3F05A1018DB195906C2A56EF46A59D793C5F3FF41BF7C6A94B33FB905C21542D19EBC3AADB87ACF1D591323FDAD0A46C6E3C89765BE90709197F9B3421E6B5CEAAA4F9B28708CAF2CFC474277EB6E7C92270CE06D7948AF4EAAE482FEF2C14ABB25CC97B9CC3232C83C86315EE61949450FBE1CCF9B73A6AAEBED983E765726563A16E119FFC746DD02FFB33E434656488F5E89E322726E10F498F3BA5E40A3B2ADB97523AFF313FBCA7C953A1BF91266E6F6C86689DD95F7130EB037FB32ECC525C9A925567B3EB0C2A8CF1C008B03C60B2F8FA3762791D424F65B576E133E833B9B551546298825470B72D50089F8C9881EA7528653F2FE38734212BD03A4B2032E79365016671459515B7A0495944479EF9D8FA34E00F20CBC6CE25707E84A4926590AD87B5DF82F5930A4F9212CD0469AD55495EBEA029E12847B67FCA1857E26CF51C2F803A6B35A06DDEAC58F8D774ACE41B9765E7F950DA906709D0EAD10660458C8409C779B4A6F17E8D2262D56C727DBC57100F21FF105A83D3867D2B18147291D79E5536BD8FC2F130E6B16E7326B96D79011C38B16A983459E0B448B4AD2A004ADC38088D005F9ADEC41796E3BF1ED724A28FFA49CE287F20C894A46DA7CEBDB8AF829D32094405ECAE9A7150CCCB4D4E11E73A99CD5894880E1B6C4553A329B5788F80020E1517E64F8C1FC48CD11A3FF1CDF2E7A409B7EAA9F9DCF17855648C325C4E5AFFD9873CC49EC6C18FE592A4A1587D9EABE7DEDA216706EC699E39C7BA838DE01408EA74F8A00C9331BBC3997F7C2229E9B3C92CFD53A20D170A20D1F7EF5178315DF64265181C109689B78BF5EAC05795EB9C45C7D5ABA5B6CCFFA042A3C7D8C4B9131DEB8F665F4C01C898AC8431BB5E3B5A0872FC0929E21F66A1A92147CBC4D1975C19EB527CEE7AD046C111BFEA353AD3D8F8F5185C1E10126AE8B0FA77E10C94070EB4AF81990BCBBBFAB3C1B5036C2B5302E87B1C92A734FBBC5E79DF9AF356A0405789B166F256A5D0D0058FC32F3367EF48A29F1717FBF808D0CE1EF93E5000A4FFE711342834C03508F86DC31F55328D684B918684860E292FD15C718747A4791F11270D81EB71D0F69FE3B18A3222151125D3705FA6438510712DB2C40F776B2D81DEEF8104DBFE15C2D4B5293D6C99C734BA99B0EBFB2759B815D84F986C898051939B78E66A1E731A7F123E181F7A272FB1B8851C9B3720C3D863894A1C0AD23A0F26F72C842DCA2502C1A9987C73C9C8A1DA8B5499F0DD24E5251581718673088B65BABAAA9A235D5A49BA67A575FD632B48F48AD7E723440C5BE15BDC94897C0D1A4C1100BB6F2DBB579BA38D8FBADCAEF73A52ACEEA062A4961EF60BB73235CCD5FDD0FE99BB3E74F8473B4061FDE91CDB7E590FBEA7CDF50AA6D22986D7DE635CDC0CFFCC2F13A8222B4A6FAECED2602984CE9BB0274B059A4E4D6CBA5F4D77053FBB498772E871DC25CCF4A94AFB87F7D04C3BDF2C61D0E4216357096813E610401B440527779915CB63186DAB8F906C21252AA0BCDC263424AEC2EE33870D6D927CDA2D7D078B4B57230882F6DB6ECB2DEB273277159B3D49CAE0C7E464CA2987AC6C9FED3B57686161899E87024E079A6AEA7EE532FC1E45E84C9CA2133EEDD86D385A8FAF6A580EF62C43A551196DD18806CFF5D561C73DD29BDC2D48426E16DAB827567641B33A62EA82826E65866DF9B645DB4263C9B521AA9D403D1EEB5398E9820998516ED119A9146669BE98DC3759C094A953AE4FC1A9E645384639E88B58113971FB2B209C0F9DD5DD4F0725F0BBCC52FB1D2D98B91B980F9FD5C57860174EAF90E08A1D2F25FB12FF82071A8890DF59569EE3CEFA6BE0F43132D811FFF44E6C49D70F58E91DE03929557151155B8DD1C6A2C831E01F83C1F26052F3BC4BBE985C71A47FB41CF1A52D961E6092E9801E0116DA5E699A13A86B982ADD22427868114A062E9A55767A205B1054A7C75E9CAFA96C0C8A6AD02EE826BD3DE79DAADBD8C0FA37133768A2075394EA10491B208231F4645C991F6E15C1C73CA7AAE2C5C8C1412DA69B575F0F53AC4647D887AECA56B375570ECB2F97F100955F56FC4F40E5E0B84124EC857B1720057ABA1CE592315D0FD659B0BB403B5D5E662C44069DCB6277189C734402F8B7169EB457B8D6F6BCEFB77943D4D23F7155A0F0D33D2395CC900D7E3AC8D9AD2A341AA108EF9E16C31273714447587C98179B8C5D0449C6041983EE5F44DA3A53C56EE4F29D8EF491BF4B1D217EFD61FAAEB3714A5567C4A1607186B97F36264AF6E97BDFD32B36821B780C314D230708EB6384CF9ADAFCDEF44716E221510CF956A238E80F44F131CB523AA97FB335694753693909B55A9B39FF7A8DCA4581D35BAF87A62F42184BBBD6854CB9723F5ADBFE7A6229BE516F1727A8D95ABAC64796B857A39391AE648DC45F7F3F4C39449F7D70209489A1AAC18AAD3BF618DC2A0B6981619D7B36B2787E260602CE5F326C82C0CF6F9902A0315D501503D79A525348C18DB0BF94345E2C25CF2B5DCE32B9951D5A5D700637A9DF892E8E80B9B80FDD6E137A56AE3511CDF1D0BB3B1880BB58E40F015856D01937347E5CAAA3DADD6C579FE9CDC44222350C00BB946F6E5FDFF82C16C1BB23B2657263A00D4AE864D349A671D571A39AA80F1CF0A6979B944A1667E2AE217615BDBED3035BBA0607E096EF52ABCD3783B5C4DD11FF8E6AE5ACD465870253A5A847A37005837E0090E7E7497D7DB470FFD5728988E615610826B35D0800110ED76EB7AD10E0CC4E810929F3EC6BED6C2B5553202B4A34E0B2D7396FD5949A0A1EDA72DC7F22D5169615A8B467339ED521BEF34FF129E4E2A7DA421A0470E8787278F75579E8AFFC5AC4A089EDBA4C8DD72D4C4B1C1AFE86B7637663B81E63C1D57BE2760645A0CF40E796ED24CABE60BBAB2B66B25B62E24F0386B0A9FFBA481480D9762A4954CD89FCE01DEDE0FA3C70EF45798995446CE41044D59BFBCFF753A298161A5B912E2399C3AA237F1231247D2E17388406A0669D8FF31A719A18F6314750C95E9A66874DDC9FE9075815FE3EC4DDED0C636C090E024173A4DA4BF4301716434FB829AA971EB36DEC0A55500000014E4CDB5EC4182BD3C77EA1AF9A071D2FDBEAB9146FC4FA25CDDF308297C97F2094CCA4C4A2721BAF19B32906412BD062EB870C846C35BE01623704CC3EE555C1F7A68188D5059B1A44448103DC28661F0EAC5EF5E396C036DCDDBFB1A626ED6D6AB294B738CCE71D2C8547081D319854734D871B0EAD97E81"); + + LMSPublicKeyParameters pup = LMSPublicKeyParameters.getInstance(lmsPub); + + validateSig(pup, sig, msg); + } + + public void test_should_verify_shake_n32_w8() + throws Exception + { + byte[] lmsPub = Hex.decode( + "000000130000000C972FE777D40FE1EFD97603A62733CD1CD2D6F13C54A085F23017BBD46965C0853ABC363FABCED9119A26337A306A7B88"); + byte[] msg = Hex.decode("901F4B2AD9C744E3818519BD93C0578AC9AA6FE2B3BC3FE35EA569847C1FE797D240D846C2BFAD1FD72A784F46F393B1C1035170AEA0A569650DE986E71B0EF9D560B02772198D1B1A1E825926A5F1482C509F8A18BDF782674A5F4FDBC83D59839EF4373BBF01618D6A2DA5220DB4C55CC54F25759297C997ECE7737A1B8648"); + byte[] sig = Hex.decode("01BEA7690000000C85018B7FBF611F91DBFACC1B753B62F70652C4D50E2304209B56B2796B1F640845C5DC51829CB63C945637C786C63C5C6FF2246FA8C4F3ACABAF9CFC988486C99ABE9603E434D84EDE0A792A910870C32E0AA3C8A75E354F253F15A2D614DF441082663A96B7BDE3A3F1DFE06A98AC4AB4F104929A7E2E4EE8092B9209B0D9D0EF8A3CE9108692737B4116176C53264D4C69FBFD6669033B596065FE540BF0CF02E7F814EF821FAA5D06CF3C5C258A95A74939CEC696AB12ACBE7D2C1828249EB1AB2866B95BA1BB54BADA4E0BDC4C2F85B922B6E78793BE654F12F6C47DCB2A6505601BEE6EAD8A54CA4EAE6F778433C19FF61A6D9277DE3AE206F8C56D86839360AB4E07C1FA39D04303306967E41480C817CF1A0A9E1E731EB725138A7C6DD2D19D03AEF13032846AD0B55BCD0949B2CF48B8144F0DB17848BB957DDFB1FACD6234435D48012720F78BA6AC44531D5F98694D7C590FC69BCD332246DA9D522B423E5D2956C8A742F9E00327806B4D443EE4DF953BFDF5213FC791240326AB1D842FABCEA8896669B602AAFCCE63CC9D1AA12DE6E5E40F268F2B3AA53E10D892E3440AB8FC55D5ED743CA6E08B8615832AD3E8E30A68445DAF88F7262A6D308069627293376A30911BBB3674D099DE2DA8B700E66112EE98FA00A3C883B1FF614A685B108FE310EBF5D4FCDB457717E0287D6A3DBD71CD2B3D8B24865831291D7A4139FC36549A32EB9495A11CE6C39363528922923C5F11FCE3DC62AE05F8BA557896B28E7A280B84C7F5FBB0F6C9EB101EF95016662B8BA1856C40BA0FB074BB9136D497D90C280DFC3D4D3DF702EE22C1DED8656FE1068CB312DBA589F8529B192C3AE46BD63CCA9DBA00A9001198298E33064A187EDDBB3844469424868BC36CC54B67A427AE716616FC5EA856B6FCC08D3DCD293EC12927CC4C8E6B5A3043A03CA7DFAAADEEABDA6E5CF3D70B3F82E0132A84561FE182AAC77D180D6F787BD99BA1E1C4C4FD8CE7513A4E2446D48994BD7D58C79923B282BE71E4591812AB6D1C55A09BBF995909FAB9932668EFB3C30F123D3AA463B473037A36770325A25F401B32E6A1195D559B73EE53EA4C59BB402C21EC3CBD91B225CD059A1A9D32BBC720FD7549F0E2369F4093121A0B079D3BE5E4248EA97677FF16AFDC6193F898ADD87CD603965FDFF5887DBE29DC8E4F7CC6A7D90C9CB090AFDFCDE260CBFBE773FAAD9B59A5E8338FB918498BB333DA1877A7D1343B5903353F7AC8B79980FB062BE0D8F4DE892C647A47B1FCC058C3FA1539928854A86B7B48CA66A61B8AB79F3F4D8925D9E7472A10D3500509904A9D014ACE9B987AF34E4A893F7A87E1E52E90A0A20CD5D9D07522A4E1E6FA5D2A5A7E333D8084068A26E3758C132C111DFBA3061AA3CDBB4D0D563A3073815A1FF99FFCE701CA90747D8060C91937A3E2A0AE7781385179723EE95302C0C77C5BA2433C5B13D90B27100BAEC47C3C22C4942FF4C94543D86FB50CD6B3C551944AACB833AA76F27F6A120CB7531D6D04568CB50CB92F5EC35E8B9080E171367FD49F07B728AB210A2D1B845B92E7000000136B31C160A7BEFC143EE9A4DB1234C3BF42E11D0BE58BE77A9DBA08E9863C4737A363A15DF0D3D699365A6BAFEFDFA12DF37EC7FFE1AD91F0F0E2849F2E2207E804E244A81211B1FF8242DA525F45AAC685C0CEA936984D848376834065250025AEA126EA4C1138FD4C7AFC2C7698108A767A953EF7CDE4998FFF65B4FD4D21251F2E91411D121B6E025B6BDF6A4819AF9E094C511CD558CF65CB818A2B8EAD0936BEFDF0775C1F0A3BB67C81170C0B35F0818C747E01BF97C88FD70A93AEDE476B07BD76D4211A6650FA7485B0A985010C14A9A05776DCA4F9E8442AD1D99C57A4760342B925A0510D4132B504AB7AEB9A8FC3F43BD3CBD0EC08AAB1543C2DEAEA41FBEBAA3B18E59D5300822C2AD4ACB651FD16ADC158B9D07B3A63A6045AC0C3A9BDF37B3DF5A6186DC7EA543FFE995B6FC1C0BDEC121326A10AB866B15E9E59F8EEC40E13AEFA8B455C6093C2D0FB919BE4E3CC70A484A26DE71F11264D3E1BFD153C744EEAFFF8AFE6B08C9FF11363CCFDDA59A690A9CAB0743505A1AA99397AE4410EEA5718F003C846332F1976067224574C716A07B896668902E9701D431BF91B3E3A8CDE1E1E6680538E2BB6845D2405E7319D1731D48A40BA818BD42B1D00BA0AC6914D4E80DE31766C32C03DA53DBD20F8E773F84A79829919CA1B7FCB7CDDAD1F1710B23D19897F30E1752BF9A805A657D0CF762FE3174D450C8090A4442CAE229919C80E39550E32FF9741FD02CFF3C012E77722125D3252E144F5F6AE985324254A1582FF06F5EE565815CD0C9B820593B481C8CE3BB1CA01E51E35E8664FAF0A13ABA483B8E478DE4DD04F3CFB8A180CDC04BD2367037038CB027E146485EBE2E425AD9DC60AF5DFC1746E60265546C0B1B0513B5D047C3320A69619548D1F5143592034260B0A1777DA81C080637F4FE2DDFB94CDBFD1C09344FF72A661474721B0EEC6B52E812A8F81613EC4088F28B95F3B0D94F419AE0627121F05337872642EECE6529AE7DB49AB9A38A62AC80DD2241FA61F1A80536D75F519CA0F0145E77B9C682C47EA9D88B5CA609C1E915C37B667099FC61A15E7109DFBF24BF067271B2025C6473AB268E385CF103B0149F41F2141F312F531E4"); + + LMSPublicKeyParameters pup = LMSPublicKeyParameters.getInstance(lmsPub); + + validateSig(pup, sig, msg); + } + + public void test_should_verify_shake_n32_w1() + throws Exception + { + byte[] lmsPub = Hex.decode( + "0000001100000009747BBE12A6157879FF4FD22FEBCDB557661035CE843BBFD05D1D83E97F9635762D6E274278F02129E3E6E2E012859F1E"); + byte[] msg = Hex.decode("DDABE5B8C14869E4B912CFABE87998D626B47E608D6250946CD6D5815DB5F38DC4D7F77BFF6C12D02C86CC9A9B6F33EAF76E025F90BA3CD527E425D318966A86AC6A1A1C648F4428130F1AC937777992AAEE17C73BA0F8DEF45C0B449525DF474F04121501DDD80F353EFF899830313229BAF9F8DDBA8ABF801CFA3C9E7A6713"); + byte[] sig = Hex.decode("0000311A0000000952DD96FC53E40A9F4BC7EA5BF637C097A57384F0663BE885CDEFF9CA8AF258370F09B7C85CDF4773452AF60343D02F51CAF05FA06F83D77B4031D32CC6D05E2CDA6AADA444B1C58ABFD9AF25B60124DD2FF7B051AEE9212DB3BA3B65E9960FA49E5B01BCCAEB576D28CDFCEFBA6EF152546485E2E242BCF3C12624B22AB28185E7091B6C0DFDBFD2C3D356A785975414312300D1E6291A603C5DC29C1B25EEF149B6DA75C3D20633441DD010BEE918F039A2BD56EB4A7C1A8E002D8FA9C6C4FD1090040E3399477ACDA67ADAB1A8A4D32C6D19A1C2BBE75D093994CDAEA3252F6079CC1FCC3A6DC94178B58A31235EE52E4C825B07C82C8EEB1FCE218988B889E77017C4BD6F292A6566F5CBD8F00A1156666AA55A93852C478436E7B6C8F1DCCE8414F584F2051DAAF2841D0FAE0AB1285F1163E0C1BD143373321081231B22D4AC1F94247F490A2D1C72336F267DCDB4314D3DFAAFC4C19C83C19F6976475BA2B1D6A415B63D6E02383F8E207DB024DB10729FC9C73E512BDFD7B62D07D05DE4B153535E8B66C4AC114C03819EA39EB6C93E682044B1C60ED732A1ED8661438A6568A9D8B3D7CC0E0FDCA2D960EC223FEB2FB20479C75A5CF282BA7A722FFBC297582267AE65BC1FF14929F8CA77FB068B97DC258A798D3FC69464FB808E258D39E9F027E503D89A7A9DA7346E8DF695177A8567603E37458A77344C56D6897E4900BD17769E3869DB2C68819527C43B6813B10AC024F72811E154F9A8688F00AB549597BCC15AE5B050409C72168197974FB18A77AD8BAFD9983FBD3428EED40F0641914800431548DDBABBDC0FAB12D826EF8025410A0849A1591CC823B44AEFA11DF73C8670274A31DB11EB975229CED2AA6CB18F0B5B0FF6DF2AA3D064186FD75E93871C3385899FB93B989C59D4161BFBACD249AB5ABB1311FDD9337C0A278162B1A042538970DED88B56659079AD332BAD360AD4FDAF895F399EDED428374918B6A028A03E6FA91ED86A3D1282CB85A9CF8C038D9EB094854C919468F374EE3C3156A2469643F5E1A5A53D1F168FC225116944AAADDA902DDF74EAC2583B1C7A3C584B9BA95FF37244BDF429D1EED00F6E6474704E6AF36E4FB52A43A9B8EC4D2633BE686F1B2C1E3697EA4C4316380513DDFA2F6426D0E485F70AEE39208F3C685F9DDB7DCD059944FCC83D2A55FE59933412F65B816CC1618C584EEC8024254093E20AE97820894D64CB5F78BC2A29B8F1FCDECC8EC1F612029AD465C36BE0872EA94E07A654FB11226F79BD86297195ADD70E93EF3D44B4E132BE5A4A0C6E14BA5518408A549420E8FFC6970E72E22D7953241755D556D7C61C03065E58E89183367CBA98C9080A872BA948A7386FB2647A2272D09B84ED3E84873A4A4452A824D044DDDA74BAD4A14E19BA4F95EC606B291729AF057470E4A1C1F23DFDD8F436BE595B52052A649879C557CCA7A912FCDF6CC19A75DCA05463F98D581F726C60FFD9334FEBAFD512C846C171211069F865E7107E2F144FEC970F2AC7D729A347DAE279BF2B0AB2EB1D614509F3DC409DF59F4F070F24329358B3E9DA8D55E88A9C993507FF7E6547271F6D745846C3683176B066D6B5601774793C1998B5364A7AED6DEE1D10A6B640E09C93470B8F224859D66A922D6B43E044C02E547F511025E0379D2E7CEE8DA593F31C5DA0581B4F81271474DA124E8B890A68068BF4D166C29C04E756C98E0795B41736531B298786918B28DC972D6200FF53E2675EBBCE85C6B2196BAE7B12E18E724DA75262149C86329A3AB9F2E9811D5A521B010A0038EBCF67D146C36A8C19B3EA75FAC90FF0253E767954460BD533A2A9FC11FF253B8AC90D1CDA3E423B8A0779FFD3C99F8E48387E2D4DF4F58F0A39B64D176D1A728D08B8ACDE7FB95D8E5DFAF3C75BA4592C9397CF4F3DB4BC0C89B762CDE36E8F2E3B2BDE9C61625847949C93748CDC74D9D0EECBF0CE74820025ED6E5BEA0F1AD859A1AEB8A46772368B73DABE5D85280D7451788CEF8A8B2245AF36BFC07866BDDF43300443BDCCB81BB295082764F928B4B9F616BDE74EF47122C21285BE6B0FB7B118E66A8367677F981284B493506B258E230150EA6A4252AEF37BE771F9A3678EB56AA7DE787A2CBC7FFA3B221ED1AA3165CABCF39ADBD91BC199A226F02819DB44ECA17D2EC6F74BBD08DE84E27BB0DA0CE5FB838B955B16B9EF4FB9224F558FED474368DE479D1209AA029A8D5296571C863B6C6D1D0ED91F4C4F96A7C6FBD8E4BF00AAC214D7266655FE0092BACDFB8B755D44C74DA32E04B4ED3DA8466A4F28679BF0AC6F520F45836C4D4CD9922F170E98C999049816C6172F98BBB8505F663D6708D221783F02257ADC2EBFBDC4EB8F6E9333991BF6145AB4F4AAD1F3A276C975F183FB4C0A718F01C00197E4EDBD2EEBB9846DAAFCA14234917775CAE6401B8429E51004CEBF0F82E160DBA8C71065DE77AE34ADA1FABACC2882A9B6B07AFBB233E27620508F89C39304878F9386754801364E34BAEE0C84F61E403145898B46D8CCB46A83739381CE192C2BE23F56671AFAFEEA57B41AC213FCCC17768A5B2E2E670A16645F2E75B49140E49A1FA453BF7366A88F7A54ACBC6E8B700787327F631097DB7897B2D01E30D1764043B5ECC1B9782DFCCCF27AD9ABC6A1A7C34A6F101C2FAD29751F55676D9B0779BF96490CB89ADAF6C1DFD09E25C545B8867449C0D77B13DE71C83EAA64C3B62D03100F88344C6DE26269911052FF9AC458E2BCB14CC0D5791CA7136EF7FC5F49A321CBD71D414AD05E2F74F8C6A31B84148F793522265BBBBC818E2866929111B57918750CB09241B57438857472E3ECDD8FB00AEA0BCDE629B08AA2468D01D7A41ADF4257CED61E0D883D5E647B2261A9842BEE976EC14D8C9A5C94549287264A87C5BBE62B4AB1DEDB2056C662515FA59F95F1F73899A4D2BB25D6E05D85A299AB2859E04B4843F2BDE850025578429D4D3CCE37239AFD0346DC808FC14C0E82D14693F83D7CE6C1637B79652820A26A0E06B681166778C8FDE79F752F6C49897C8A5F35C3204E5F413843111D1FC56494B78C95E60A8B18E3353DD6BB0BBE3FEEB4A8A2365F40D24045C02B7579343F8AD58F96FAE17C6E4F0258923A94177E439B6AE1A1AD6A4FA7B3845CF5379345312A9421FC54EB14E94DE4E03F1CEEAFEEB91D276C04C35B09F267899D063D4A92C52A8E7F4A50CD3013937316DB538AA9D1FFBDCF10734563B44E0FEE8A763E1A8BDE960B2DE2FF2A872B87523C416058B6986E905710493DE4DD4AA382E36CCC3C7649E9498F410975A89F92FE543D8C7B4DEB6F91C76EA825D003DDCB9AD7CC5E4FA798271574A0AD8D0B8AC94819AC62D0DF98A80EE926270CB84305DAC94E8BA106BFAF9CF7C38E8C876842D9F8993C31A87B664DE7096608B9B31989C57743FFFEAC484F74BE49C7813D4D6175CA01B416D099A70EC05D1FE4EFDE10FC5ED3DE79ED22885C248A06C7B67DC6EC01AB7BF550000F2CD52AEE34D824BFE9A96B12379363F9B557E28495EA979012A8B93B08DBA296BEAF8FC69523B52D2CE640B867D1E9C01B8E3E99D3325EA6AFB5F255436ABCA27DFC0AE7B25FA2ACD5977523682EDBDB98A80536D4C222CBE2EE1CE48A2B49E7BDFB0E7E9C2FBFD2EE789A3C0CD8EDB5A27CB8C1E6E569AC70C062A4F4718A93FFC9E1F7A60CFA209C48D304F5B21B74B36CB8E4011E4EA813305A0908DE1F5B6E5970AE81C055DC75E43564A0EB0A9C0791311CD67DF4DA1C14F7F322E45CA1FC5A3BC6F92260349EA1F2D9DC35BCC1F3444DBFC4BBE54EC7ACA6E7C82661FF60BC47131CC368B06B96C87A132CD9F2C56ADDDA673D41238C114EFF765B2AAB915EE26F4240A76004C14248119C0097282245AB410ED3180A6BE3EC851B77150497AD8E478FE8BAF8C3218DCEFBEA141784F93B361A7039CB1AFA305537E41D7232181D5D3D83A357C0C9987E6134E19C3C155791A35969881C77218BF721B39CB98601ADD773DA256A32BAF29CF6E30CC11129FF7848F19EA43ABDCBCAEBD0441460E7EA0BBF6D1DEF00935A0B305749137DA8E7774CA30A54997832693589E6ACCF461F1CEDD5C3648738F87F12B70D79A90FD2BD8125ADD14D58B56BBB06498B4F77FCEA60CCD53A113873010920ED8459CC91F19304E50693EE63F114B23E6057B67AA87F11C326CD2DEF9B77213B69A7B5A32F5A3D5325DA18E66250EA70A5D0B345561FF8C13A3989D56AC676DCDD950EE9E6A2050C9E78B95DCE80D3D4EF383F3DFD3CF01A876C6EAE02012B43990E21BBC03ADDDC64D9D665AC8C9B3407D00C6BF6A0AC558C261D18F715B53EE02719A2C458CEF92D7A8F81E090365A9D593427BFFE4259E6BED46E7A3C45840865C300A23D3BBC787975852A79D248299888587AEBFAE09D8FC873D9708C7C37A577C5B45FE46D2A37D3E2AB6155BF23E7079F39D4B94A8644C8157505BFF98A9C6045ED689FB0A36205E8F1C49DAE5CC7E403299EC0D8921D12EAEA703A7FBCC4A990775C08B674394B0073DDD0C1347FFBC8E2FA9C0F9E321E6E78CE5BF4BF513A4972AC87D691389D08621DB73FE7BE858674840B0CEF7E541C611729EB9F91C012803B9CFFBE96E9F198D7090F5CBE3796AE3414F31D899F3A18800E8DBDCBDB1C4F06713CE80F142515B9DA59B42180015DF7DBB17AE1FAD0E97784F604A46D49459A3050AC4659C6142FD226CCFC0B96733FD31958EF70DAE54815E5D7E694BE995483BE57F37093834A963434142978D6A87A50C1384F4C5B39D7FF1A6B7B13A41CC88F47FD1A12E66163FA7411C6A18F3BF64D6D567CF0AA4608CCFAFDFC6252D899B78908BBFDC6F6F37B0FBBAB8D0FC8A0D04BD23BA3AFAB03789963743958A5CBEA0A82DD7148ED9F99B08640ADE7C00E243B7B367A818A6252CF9FE5A7C4D7CAC2BE34712F72EEE09069CBE283599A98FC314C7C66803280AB8DF1D06D20A6181285BF705FE5E64F10B1A747A810BEB16D1143A0BAD75509DF0FC84C6463B8E04B23436DDC747096047D1430C5276FEF15489D4ED30BB46E220A73142B3F479A403A356D87966022C30D2D274AB6FA9D3613663EDD00B0297F3EEBE2BF9AA05D37F53107BF9780F3A52BEA488D87E3621CBD8A2184E4F158AF83EC9354F502D46424093A1F043E6464320DB1A2801EF3EBC77D8B209D2E6C003FB4184B6D07F6986A201447024F844DBB1A1B0088F0944FCD9F917C6C3898B0585ABCA5318B4FAC2D567EE22E6EF576D05F837AF6FCAD2ED5D9EE8828501A1EF28B66F1C5EBB93A74827E25D1DE81CE764D269FBA0C4D4142960090671BB08E2A4CF6FA7902F54DEEA604555049B820B40DDDE914D38DA6C02C788A0C32C83D0060A84B77E5772B2F34418B5D45C55624E76AAC4A72A22EBCCB1D70BFBC180F6E69BE4E4B235EB476194012A0ACCB368D8933D43AE072D7D3B6C5C69722FDEF93D1579B63B5E97BB1EE8E532B6B12265B76AC97B095B26F197281199B75EE4A42D13B2E4326D6A133D0E2D31A213C2A227AFF7EF1A125F7B109766E08AEDDCD95CE76C4F9581B908D7AD61C13EB231F1E4373823FF8804A87472EE3255C513E48BFDCFD84643CA35427A01C50BCCE3DBF92D1B386641FC53AA3088ADB972D9A8284769B3AF6DF45157C4FAC869C3C2F9FB41539CE08A23B3FDD5C638329A9FF3CCFBF97CF31F3752F1DA4F8AE6F68777338ABA4DD74F6D0E2B41CC3F7196D7B42AB2B576D400363EC73F92F491D7F5341BB0ADAE4F28003C1FC889D2CDCA1E5B737DC701FFEFFDCF9D758411D610DBC994BD29F271140BB2F10A70CE373EE2E2C507F3F6A3B7AF9FE7B9A9788E3FF00D3B61BED24C5CCBC05FC7E168D418076F535162ADAFB071D4A03FA390108C3195163853620BBE389ABCF478DC9D3BF016F8DA6FDC8A42A41C68EBA40909FBE4B299F2CA3BB92E5A3BF8F6A333E90754F6B1B986053E82CB84635D02A49BC7F906D607CCBAAB8C00B7D00DDC5AB798CC5B2AC548789C55F5E8A11E36D82BBEA46D89703582263B0E51D7BE93C395C74680C7F91937050FB36F91EB0ED6BC69D1766A6FF6B4F63D3ABE81757F4662657B0C6FD5D6055656E9BC5860A1BCE1EA8516B92A1C91A30F17A0098399912113913DB3E0D8DB210B4A849383BAC10908BB34A8C4CFC389EC9B554373CACCC0BDBF6EADBB98F8E234B56DBB915CB05F7BFE12CAA308037B14421FC78146BB7D0A431F1C48D6464D693969CAB900E556DB22600058A3C7D892488389E95F6EAF47A2149271ADB0B2F899BFDF7D8AD90D255BC16ABA7A89981784C832ADF17846E80BE03D91AD04E435C22AE837DB91B138A17D3A2848F43DB72329E2426C6AEF8464B70D076CF33E1F2491BCAC5A73130A92D470A27EADFC3D27B9BA7BE3C41BA19A22C221FC5406639CC17CF4774B72EC3966981645C0465B8BB642213748D9D8577312570B1B6E6330F0008EF7B9EF14181B021A7E4D6F2F7C3C851B575202E95A1EB629BB445C862BD3D8B685AAC120B68702B185C40EF4C6D476808457BDFB2D9240FC68EE394A5C7BDDF2D6F94A712CD23B1244D264C951B1F255DBCDB73824A090848DF23F6BF81C09D08B22C39D2F5E5D0DDF25DE1AEF8BF582AF8B63C336A94951222F9BCBA5F6378A5DCF3A0EDF099182F139B78D9B4FF36FADA90A6B81ECCB1433145C8B2EE134C40D8A62EE5D93581ED4357EB438911984222710C73E00E0EDFCC4496C3C5AD9B8108C739919B47B0DA2190729061BD231968755F9FA20E9592328A1D38D6E163F90674EE5DDDE399047DFD8D9DEDE9C8B4C400F679715F94E280A82E656120A7C07397BD45699B592B47BB46E5900DBF960E9CD2FDBF7E42EC03132ADBC4ABE84B5AB5B99C25A970680DFCE0EB5D80E9CFD322B3ACEB482E9E4E41E94D115E32FA59DB80DE5DE5F7A0961EBE503E910D04C8348CA0643B0CBCDF3EDE408521ECC0E3C51D2F7A585B7D0C932219CE10DB7D379B7ADA72E140FE2FB874A2B8A9F3AE9DCDA72997EA250D89AE01A1D068C3CF45999C41A64B9BCA2580E2E908861AFE20B8E2EAEEB681B999198947AA1A8C40868B768ACB27667309C2D8EB23FEA15BB913F578E7E68DD46902BBED322D6522C636A34BAEF8D1A90F276F2E9731B8FE52EC138A77B1419AD55E76EB7582772C0F52E92D626FF35C2C1DCFDF2D06097A1D11AFB229D6243FEBDDFDD8661A8C0099E57FED15872B03C64DADE274BFF9BB0FFFBCFFE39DCBCF4907765424904FDB45AE1685C661DDE3105D9B654601945D1B203593A244C96104E23FA67A348C55A47D0D29BD3834212692AAB1D202C806D27F2212A5A8B0A70A9C69FB3F484BA018BE45029ED18F6147A0DB6DD6222C227A6E65055805075EFD205DE6E6C9381F4C8B27AC3ECD2E6824CB173964294AEADC29A50B82C72ABF8E20A8EAA722FD60A68DA2BCB97DD3AA64942A1D36057BD66768FFE73DC004A09D8410C94CBE4DEFC198F8D7727B5486A87FB4B8C349AED75184EA870B878A1977612CCA52BFF2C3D1D4BB2F362118DA2F0E2069434EC1809145B878A5F8FC908A3D5C26BD9B7721FC94CF20BD9003F4226CB3A1E082C4B6D313AE3EF5864FEE44C37AF446C12BE60003EA632A581FCDD92ED6E4B71A3E0660F35C2708FFE81A1D87EA58A66CCFED6D1EEAEE92233404C55B94BF53E1B14AF54C9685B2746569BC6916E526589710881FA533DBF303055224909F547CCBB2B0CB084F07DB6BDB5CE21B3E4AB8F898C1EF41349C3EFFBBA1E06DBF90CA1F6A8C52403DC8752FDA0E394E9CA917FBF6C93B81174DD8724105D44C3DE8A6ECEDD821CD21A126311B94D20AEFF994DD606D37DC9FF109C130037CAA06EDC7E9575D22E0DC773566196FE6D939868BAF108827CDD2751EC6C79ABDAF9B13DBE8457ECFFD1DBFB8417E6051E1284244EFD8FA8674EFEBC872A6A5EE2F953CB2B4CC79871A0CC35A8128BF9297C8DE3DE2EB340001239660E4B4283B9A731F00339ADC3487DC9D6663D9FCD14A3F51874A20F06EDD43A2F51DEB1EC3FEBA2A2EAD966394179E5DFD052F368C30D6A624E127BC8D669E04A2755E6FA23FE63F89EC6CF429978FA798AEA92F11D26438A744D9295AB5C5893EEA9F4581C5F6D2F714E849D73F2CD28B97CF0E65D30FA3BE012819DFFE0ED03FD0E7585E04E6FC26D351A32D78CE6C73A7F6B8DD3749D466C64A9A6DECDB6F2CC8E08A036814369D8EB62093038CA2071542664F2FD404D3708E4986148D83A220757A561101BAC4291A7709F2FFFF3F58BDD204F52CF99BE94BF785DA56D14A2DAFF3034C8B100804AB3F770404C61EE3B94D5E1A0E777FEE2335838A16FFDA4864EFE6E7279C8843A741C72C14D22B6DBCC25E98BDFEADCCC7644FD6A0013DEDCCF2A41FA662D35AFF87B2A9A6E520A273F789EA078972833901B7AB992B5B15E5CEE61B8A3DE3FC6889212EA3D3D036F2E4E20C6B4BA48985286268A8A2ED1A3999A9DB45F204064609B01399E5B3ADC938D3D4A382A387BBF6EEAA9FFDC74E766A17E43E47EE3926C8EAD5890B90E8F999F53F5769F2FF70F3C8A925ACEEDD1628505BD5BBE4C5AB16B8495B1D1C94919300CBB37787630CB18F0014FD4B3C6EB861EEFFE30D49C63AE6E7126A3B4627AED08AE12989B60816A65E8BC2EFAD36C5ACCFC56FD00ED46DF05452A8B2904D215E82B54CEE9B3174628D48B89B78DB4DE765E45D43B01967D3088B80D73091BEEA082DB9B335B2E736B3F7D8EF13F7B2B6C478737B86F82150170588CD5CC1833191F0DD59634B8F931B9CD5196D8C3A2FF3F5D8B47EB0D811197757A2DD3E01C5414FD3557F9B65C683130C0E5D8ED861F78C3C46B7A531535BC7B0D63990F1B1E1B7545B278F355BD84AB17538BB09D6AD1AF260F87266178B01C55DD99A02D7FC090C81AD3C71FF350F21C7E8D47C24CBD270D256C3F5C8892C4F6E0B164DCBF9F7A8638F100BDAA74809FE8CB9739896DDD7A4A2319000575010BE77A56A6E38E56563CE5B7F84C227D5C8AF8DB7E52AA65B3D6ED1B8C0456B8A0B27CBF918703977F0B14C41A855A776067A99D07EC16BCE384F24FB0AC8C114A57557958C56C522804D350CA628B7216598261EE17826398440B0BABDB8A5D33686796CBB5D92C5F2A61C52EA4118E9C3114AE909937C80BAEE2A1615625ED6510A21F38A21C6937BF4E2A8146A834D00F0A0B92D9548E36E426673DB303EBB3014C8517E5FFC5E7C129DC85DB8295469A909A5E30A70FC005953C1EE798288457D1A44613803E7877BB1F9EE4BD655B3BACC7DBB262099439BD651864833A08F5029CD9BE1CFBEDE6D3E41E592E76BA026FA4CD452B35E26EE5F22E639414AAC8A5EB39D9F6328CE0A005D6B219A33A87035654C82DCFAE8ACCD7E8DF2DBE6F90BE0C3D92D7330D2B13A8F670FEAC799D4F363FAB14DB819A4F2DA5C1A625FA727ADBE95F584659294D0F5263DF841F844C801D88F8F3C8651F3BAB8C57BDA7A975A25ABD890148DE6FF5BA0A5FE2629BC075DC256A13FEBBA0C9141F1816C2A723328C647A27BC9C3C40FC6C3AD6DE0C0A128EB3FB4572D373A4D1FD6418B7941F4491C9E80E075D79CCF5C410CD258FB98046DC4D44B292EA522314254C2FF3B3E03646352B238D96B779E06625C9E0CE3025C43854B2DC5A9CBCD164D1891D48297AFFF53CC8A415745157C77B86FD7D18BF72D1B3782FE05B993695BFD185680915B1548F607430FA198523F679AC6054D2A1F5CD7C4288088A1E06FFA0DABCC625701BA121DF5E7B325275062016575BC57D41BB201731EF316D77BB005704E1206D61FBD3940AC6B88B856306DFAF482B7BFF58ACF2F48BA949401291E925813AE305578237657FD1272029C8EDB7B746DD97B063A748DD27B3D127F11DE4CA095BF65198783F38FF0178BD9DE2613D09BD82F40E6261B1C6E1D783C90918D8346B73653F8394DDAA4225C8194F727A3E5B5889363290499402C3D5A25782B9CD6F445C782767D07B9581BEE9BEF27772DA3A9D3F4EA979736FF8FBA7CFD316C9DB70E009275B94F6618A149F6CEAFF0043811002D8EBC02AC8CD27E666234BBEC4532CC1E56FE2CD60A3A5899CC2F705B7CEB8D1CF926AA6B22E8D6E6DC9591D335F59C452FF0E9DE1D3CE3E2059232C2B20CA082F882A7D580038F75E83717151F1B664F047E8C3D67782200B65B3C168D8EF63936670DABC4163E4C2EC4CABCBBA17BA551854A22469B1438665473819F5FD513AE1609234CB32738E13F2505B12B6445BE0A2702BCB0C83D3EB6B6132AB99F1E5D85883141BC7A728CADF4DCA75EE10DA77B7E76098DF23A94A14263253548C9B52636A5B450C6B768A4323A11B1BA1D9B5AFCAE2C2F16F4CD12F93A3E699216A0DA59C5A786A060B13A8D6979E1AD0E3C677B4FC7B9A95C064ABD49B774259DB60327324CA794626EB78028834173B9DDC44CC8436B96872F3360DF52694E144510F6E6DE8802A8388BE71959824F9D1E4910DD8262DA9F2DB2164603544C7360A9D34CEE8CEC1DC0CCCBA0DCD04B5AA34A025BE887657C0FAF54D5B816CE727EE6C580569B5575DAAF097BC001A0AA8576BD79B501E86F8D76478DFBE049833F13B9BC582B190929D7235F1C6F4006F98F95DCC6ADE891A975B3DCE565906949CCCA81C7C349F1A836726775E2180E61288D072C4B241677224490EA6C4EB198F47FCB8A5033945B917DB7A2DDD78030BF20A61454B7D34762E7F1CC605A1F110B7E3B71AB51368979383E63BA15019F588BCC9A6CA4CF31560B183630FB3C72307792349FF9854C50BC5496D04C83968739150CFEDE73BA1D14270B435D3279EC44DEA35A54EBBE8E510A96600E6E7C716C520E36A6BE39F4AE6E2CB3E1E308B3850BE07FCEC9D6194F736C4E76DB331FF635780F3F01CE22483ED9AA4306EC02DC5D93173E25FCAC18F22A9F7D561EDB2F991157D5B3955AC1B8BF9C9711D16EE270BD1C1063C13A97225F7183F9E79DF127D95B57FF7AAA1806BEF90A69A2098E4380FF41B9F49BEBEF163843499FD7A7E1C11448E2AF7FCFC75EE12FE7B0E52FF564B3D933A30A4CF2B6F61D429E26486A486A2216867EC27C1E09B0E7B91601D8CF8D9AEEF9C21611704A03EE133E889900B5B844B14684FAF3C1B0CA90BD29BDA01AE2ADA810ECBFFBA4E049E57FAD602F52E44CDA8DB83BB2EDE93013CA0B93F8A96F2F10E86EA2B97544A9FBD4BC552905239F68862CF0BB1DB58F2DB72494843AA6E02CCB511C8033E3E0C81CC5AAD37B6ABF50A6FFF01479F62CE75EFE8B10CFF11198C796466D5E88F82DD34AF6B7B053E57CF434D343EF797A8ADA19FD54CBEA5269C4CC98A4BA08A84F0F3FD99C9EFECC52C809DDA5C8D7EAF07E3F04F522C1E391F66095B0BECE865B687457608287271354EB93AA7696735A953874E6ACA9FDA6A0FB6CB09F2047862076FF26F585CF7A153E4B7D0B8C44F5090D6B306DC353E527EF3D640415D0D26F66597576DF563930D2D56292A79D407E180D6CAE2D09BAF5399827161BA7709F94838B2F2A54E3F609070CFBD07F125ED3FCCAFF31055E7E5D490D71F1A7933BD1DE69F7A4FB90F55D3BB5D24D65D93F139E460707FCBEFF7BC576AD569425EDA6DBB9C5447BBDA584D6E917429EA97753D77FC5617002AA5AD59199EAC87D6BCD014BABA2AA4C540F04CFF6688E55D73CFE243866EA513B708640704667F5D57F07197DFB543A846B57BE678A981231CC31307D9757BC74424A7384965C0206A6EA6D38C51708BDFE14AADF9098F5A70453687D7B34C63BA049D6C76F7D8BF27A4BC1ADE1E69FE8A3A4C0940546164C779E5CC8A87C1846172E995F63CD13000E911659553887D1A1D30970FB8BC4CB945E62F15640C4FCD17C6816E3EFBFAA6597583B6E5438AE90AF1FDEFF8006F233F15BBAB11C4A7798826B92EBF413921BDD5A6AA6A4955515488D52640942321700000011C0FA3E14FEAE4083E11A1F1CF9D2838E320F200E7BB540EBEEA4112178CF61D30C30AC84ABBCF974D68351778A9237C5046B257A6DD13912889EE7A319348592AB8BF53033D9861F701275E75F6D4D131DCC07B103544E20803A7668E9A73D8462645460DD7591F7C176EA2854A90BC6D00BE11D4929703C1A3358EAEB7A8963198DE33243AF991589AAC9697677EA08466CC44186CBAC009254051E00F117DDC6045C8D47D351D50B8CA60B75B9E1B06F30102F1941C22FA02C93E818A7BA4299A663B730FB9A66F331B394CDABFDF38294CA7B6E9A18E8BC146BEE4811C3E621C544BF9DC211663D23B883D93AD0A35FA6EB13985111F7DDE724934BD8DAFD16EC1B94136592E8ED70F0D5853059D89657630EBBC6C4A31E7BCB995B9B70D558FCFEF9E0DD455E0641180470B7C568410FD5D2377252E975F738B9E0DCE7059B6718741793FABD2601E0F4711F4FBAA3E0C24B214FD0A9F828851D427901BA5959C1E1454766995EA5D57A474A0DEA12D0D8B4837B435A503DEE193E0E295E0442DAB2AA09A4F97DB027E64777167B7BEABEB9F57A9791581935131BBEB3B877B4B8CF761CDBF46A7FA5315E86D5C6C6AADE19645229E639C8CEFDE810A8FD1B9D12C90379E42E0F406E64784D9146C175C3B630847664AB7D311348F9E1BA"); + + LMSPublicKeyParameters pup = LMSPublicKeyParameters.getInstance(lmsPub); + + validateSig(pup, sig, msg); + } + + private void validateSig(LMSPublicKeyParameters lmsPub, byte[] sig, byte[] msg) + { + LMSSigner lmsSigner = new LMSSigner(); + + lmsSigner.init(false, lmsPub); + + assertTrue(lmsSigner.verifySignature(msg, sig)); + } } diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/MLKEMTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/MLKEMTest.java new file mode 100644 index 0000000000..67cce6918a --- /dev/null +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/MLKEMTest.java @@ -0,0 +1,530 @@ +package org.bouncycastle.pqc.crypto.test; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.security.SecureRandom; +import java.util.HashMap; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.crypto.util.DEROtherInfo; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyPairGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; +import org.bouncycastle.pqc.crypto.util.PQCOtherInfoGenerator; +import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; +import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; +import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; +import org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory; +import org.bouncycastle.test.TestResourceFinder; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; + +public class MLKEMTest + extends TestCase +{ + public void testKeyGen() throws IOException + { + MLKEMParameters[] params = new MLKEMParameters[]{ + MLKEMParameters.ml_kem_512, + MLKEMParameters.ml_kem_768, + MLKEMParameters.ml_kem_1024, + }; + + String[] files = new String[]{ + "keyGen_ML-KEM-512.txt", + "keyGen_ML-KEM-768.txt", + "keyGen_ML-KEM-1024.txt", + }; + + TestSampler sampler = new TestSampler(); + for (int fileIndex = 0; fileIndex != files.length; fileIndex++) + { + String name = files[fileIndex]; + // System.out.println("testing: " + name); + InputStream src = TestResourceFinder.findTestResource("pqc/crypto/kyber/acvp", name); + BufferedReader bin = new BufferedReader(new InputStreamReader(src)); + + String line = null; + HashMap buf = new HashMap(); + while ((line = bin.readLine()) != null) + { + line = line.trim(); + + if (line.startsWith("#")) + { + continue; + } + if (line.length() == 0) + { + if (buf.size() > 0) + { + byte[] z = Hex.decode((String)buf.get("z")); + byte[] d = Hex.decode((String)buf.get("d")); + byte[] ek = Hex.decode((String)buf.get("ek")); + byte[] dk = Hex.decode((String)buf.get("dk")); + + MLKEMParameters parameters = params[fileIndex]; + + + MLKEMKeyPairGenerator kpGen = new MLKEMKeyPairGenerator(); + MLKEMKeyGenerationParameters genParam = new MLKEMKeyGenerationParameters(new SecureRandom(), parameters); + // + // Generate keys and test. + // + kpGen.init(genParam); + AsymmetricCipherKeyPair kp = kpGen.internalGenerateKeyPair(d, z); + + MLKEMPublicKeyParameters pubParams = (MLKEMPublicKeyParameters)PublicKeyFactory.createKey( + SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo((MLKEMPublicKeyParameters)kp.getPublic())); + MLKEMPrivateKeyParameters privParams = (MLKEMPrivateKeyParameters)PrivateKeyFactory.createKey( + PrivateKeyInfoFactory.createPrivateKeyInfo((MLKEMPrivateKeyParameters)kp.getPrivate())); + + assertTrue(name + ": public key", Arrays.areEqual(ek, pubParams.getEncoded())); + assertTrue(name + ": secret key", Arrays.areEqual(dk, privParams.getEncoded())); + + } + buf.clear(); + + continue; + } + + int a = line.indexOf("="); + if (a > -1) + { + buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); + } + } + // System.out.println("testing successful!"); + } + } + public void testEncapDecap_encapsulation() throws IOException + { + MLKEMParameters[] params = new MLKEMParameters[]{ + MLKEMParameters.ml_kem_512, + MLKEMParameters.ml_kem_768, + MLKEMParameters.ml_kem_1024, + }; + + String[] files = new String[]{ + "encapDecap_encapsulation_ML-KEM-512.txt", + "encapDecap_encapsulation_ML-KEM-768.txt", + "encapDecap_encapsulation_ML-KEM-1024.txt", + }; + + TestSampler sampler = new TestSampler(); + for (int fileIndex = 0; fileIndex != files.length; fileIndex++) + { + String name = files[fileIndex]; + // System.out.println("testing: " + name); + InputStream src = TestResourceFinder.findTestResource("pqc/crypto/kyber/acvp", name); + BufferedReader bin = new BufferedReader(new InputStreamReader(src)); + + String line = null; + HashMap buf = new HashMap(); + while ((line = bin.readLine()) != null) + { + line = line.trim(); + + if (line.startsWith("#")) + { + continue; + } + if (line.length() == 0) + { + if (buf.size() > 0) + { + byte[] m = Hex.decode((String)buf.get("m")); + byte[] c = Hex.decode((String)buf.get("c")); + byte[] k = Hex.decode((String)buf.get("k")); + String reason = buf.get("reason"); + byte[] ek = Hex.decode((String)buf.get("ek")); + byte[] dk = Hex.decode((String)buf.get("dk")); + + MLKEMParameters parameters = params[fileIndex]; + + MLKEMPublicKeyParameters pubKey = new MLKEMPublicKeyParameters(parameters, ek); + MLKEMPrivateKeyParameters privKey = new MLKEMPrivateKeyParameters(parameters, dk); + + + + MLKEMPublicKeyParameters pubParams = (MLKEMPublicKeyParameters)PublicKeyFactory.createKey( + SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo((MLKEMPublicKeyParameters)pubKey)); + MLKEMPrivateKeyParameters privParams = (MLKEMPrivateKeyParameters)PrivateKeyFactory.createKey( + PrivateKeyInfoFactory.createPrivateKeyInfo((MLKEMPrivateKeyParameters)privKey)); + + // KEM Enc + MLKEMGenerator KyberEncCipher = new MLKEMGenerator(new SecureRandom()); + SecretWithEncapsulation secWenc = KyberEncCipher.internalGenerateEncapsulated(pubParams, m); + byte[] generated_cipher_text = secWenc.getEncapsulation(); + + //assertTrue(name + " " + count + ": kem_enc cipher text", Arrays.areEqual(ct, generated_cipher_text)); + byte[] secret = secWenc.getSecret(); + assertTrue(name + ": c", Arrays.areEqual(c, generated_cipher_text)); + assertTrue(name + ": k", Arrays.areEqual(k, 0, secret.length, secret, 0, secret.length)); + + } + buf.clear(); + + continue; + } + + int a = line.indexOf("="); + if (a > -1) + { + buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); + } + } + // System.out.println("testing successful!"); + } + } + public void testEncapDecap_decapsulation() throws IOException + { + MLKEMParameters[] params = new MLKEMParameters[]{ + MLKEMParameters.ml_kem_512, + MLKEMParameters.ml_kem_768, + MLKEMParameters.ml_kem_1024, + }; + + String[] files = new String[]{ + "encapDecap_decapsulation_ML-KEM-512.txt", + "encapDecap_decapsulation_ML-KEM-768.txt", + "encapDecap_decapsulation_ML-KEM-1024.txt", + }; + + TestSampler sampler = new TestSampler(); + for (int fileIndex = 0; fileIndex != files.length; fileIndex++) + { + String name = files[fileIndex]; + // System.out.println("testing: " + name); + InputStream src = TestResourceFinder.findTestResource("pqc/crypto/kyber/acvp", name); + BufferedReader bin = new BufferedReader(new InputStreamReader(src)); + + String line = null; + HashMap buf = new HashMap(); + while ((line = bin.readLine()) != null) + { + line = line.trim(); + + if (line.startsWith("#")) + { + continue; + } + if (line.length() == 0) + { + if (buf.size() > 0) + { + byte[] c = Hex.decode((String)buf.get("c")); + byte[] k = Hex.decode((String)buf.get("k")); + String reason = buf.get("reason"); + byte[] ek = Hex.decode((String)buf.get("ek")); + byte[] dk = Hex.decode((String)buf.get("dk")); + + MLKEMParameters parameters = params[fileIndex]; + + MLKEMPublicKeyParameters pubKey = new MLKEMPublicKeyParameters(parameters, ek); + MLKEMPrivateKeyParameters privKey = new MLKEMPrivateKeyParameters(parameters, dk); + + + + MLKEMPublicKeyParameters pubParams = (MLKEMPublicKeyParameters)PublicKeyFactory.createKey( + SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo((MLKEMPublicKeyParameters)pubKey)); + MLKEMPrivateKeyParameters privParams = (MLKEMPrivateKeyParameters)PrivateKeyFactory.createKey( + PrivateKeyInfoFactory.createPrivateKeyInfo((MLKEMPrivateKeyParameters)privKey)); + + + MLKEMExtractor KyberDecCipher = new MLKEMExtractor(privParams); + + byte[] dec_key = KyberDecCipher.extractSecret(c); + + assertTrue(name + ": dk", Arrays.areEqual(dec_key, k)); + + } + buf.clear(); + + continue; + } + + int a = line.indexOf("="); + if (a > -1) + { + buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); + } + } + // System.out.println("testing successful!"); + } + } + public void testModulus() throws IOException + { + MLKEMParameters[] params = new MLKEMParameters[]{ + MLKEMParameters.ml_kem_512, + MLKEMParameters.ml_kem_768, + MLKEMParameters.ml_kem_1024, + }; + + String[] files = new String[]{ + "ML-KEM-512.txt", + "ML-KEM-768.txt", + "ML-KEM-1024.txt", + }; + + TestSampler sampler = new TestSampler(); + for (int fileIndex = 0; fileIndex != files.length; fileIndex++) + { + String name = files[fileIndex]; + // System.out.println("testing: " + name); + InputStream src = TestResourceFinder.findTestResource("pqc/crypto/kyber/modulus", name); + BufferedReader bin = new BufferedReader(new InputStreamReader(src)); + + String line = null; + while ((line = bin.readLine()) != null) + { + line = line.trim(); + line = line.trim(); + byte[] key = Hex.decode(line); + MLKEMParameters parameters = params[fileIndex]; + + + MLKEMPublicKeyParameters pubParams = (MLKEMPublicKeyParameters) PublicKeyFactory.createKey( + SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(new MLKEMPublicKeyParameters(parameters, key))); + + // KEM Enc + SecureRandom random = new SecureRandom(); + MLKEMGenerator KyberEncCipher = new MLKEMGenerator(random); + try + { + SecretWithEncapsulation secWenc = KyberEncCipher.generateEncapsulated(pubParams); + byte[] generated_cipher_text = secWenc.getEncapsulation(); + fail(); + } + catch (Exception ignored) + { + } + } + } + } + + public void testPrivInfoGeneration() + throws IOException + { + SecureRandom random = new SecureRandom(); + PQCOtherInfoGenerator.PartyU partyU = new PQCOtherInfoGenerator.PartyU(MLKEMParameters.ml_kem_512, new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), Hex.decode("beef"), Hex.decode("cafe"), random); + + byte[] partA = partyU.getSuppPrivInfoPartA(); + + PQCOtherInfoGenerator.PartyV partyV = new PQCOtherInfoGenerator.PartyV(MLKEMParameters.ml_kem_512, new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), Hex.decode("beef"), Hex.decode("cafe"), random); + + byte[] partB = partyV.getSuppPrivInfoPartB(partA); + + DEROtherInfo otherInfoU = partyU.generate(partB); + + DEROtherInfo otherInfoV = partyV.generate(); + + Assert.assertTrue(Arrays.areEqual(otherInfoU.getEncoded(), otherInfoV.getEncoded())); + } + + public void testKyber() + { + byte[] z = Hex.decode("99E3246884181F8E1DD44E0C7629093330221FD67D9B7D6E1510B2DBAD8762F7"); + byte[] d = Hex.decode("49AC8B99BB1E6A8EA818261F8BE68BDEAA52897E7EC6C40B530BC760AB77DCE3"); + String expectedPubKey = "A04184D4BC7B532A0F70A54D7757CDE6175A6843B861CB2BC4830C0012554CFC5D2C8A2027AA3CD967130E9B96241B11C4320C7649CC23A71BAFE691AFC08E680BCEF42907000718E4EACE8DA28214197BE1C269DA9CB541E1A3CE97CFADF9C6058780FE6793DBFA8218A2760B802B8DA2AA271A38772523A76736A7A31B9D3037AD21CEBB11A472B8792EB17558B940E70883F264592C689B240BB43D5408BF446432F412F4B9A5F6865CC252A43CF40A320391555591D67561FDD05353AB6B019B3A08A73353D51B6113AB2FA51D975648EE254AF89A230504A236A4658257740BDCBBE1708AB022C3C588A410DB3B9C308A06275BDF5B4859D3A2617A295E1A22F90198BAD0166F4A943417C5B831736CB2C8580ABFDE5714B586ABEEC0A175A08BC710C7A2895DE93AC438061BF7765D0D21CD418167CAF89D1EFC3448BCBB96D69B3E010C82D15CAB6CACC6799D3639669A5B21A633C865F8593B5B7BC800262BB837A924A6C5440E4FC73B41B23092C3912F4C6BEBB4C7B4C62908B03775666C22220DF9C88823E344C7308332345C8B795D34E8C051F21F5A21C214B69841358709B1C305B32CC2C3806AE9CCD3819FFF4507FE520FBFC27199BC23BE6B9B2D2AC1717579AC769279E2A7AAC68A371A47BA3A7DBE016F14E1A727333663C4A5CD1A0F8836CF7B5C49AC51485CA60345C990E06888720003731322C5B8CD5E6907FDA1157F468FD3FC20FA8175EEC95C291A262BA8C5BE990872418930852339D88A19B37FEFA3CFE82175C224407CA414BAEB37923B4D2D83134AE154E490A9B45A0563B06C953C3301450A2176A07C614A74E3478E48509F9A60AE945A8EBC7815121D90A3B0E07091A096CF02C57B25BCA58126AD0C629CE166A7EDB4B33221A0D3F72B85D562EC698B7D0A913D73806F1C5C87B38EC003CB303A3DC51B4B35356A67826D6EDAA8FEB93B98493B2D1C11B676A6AD9506A1AAAE13A824C7C08D1C6C2C4DBA9642C76EA7F6C8264B64A23CCCA9A74635FCBF03E00F1B5722B214376790793B2C4F0A13B5C40760B4218E1D2594DCB30A70D9C1782A5DD30576FA4144BFC8416EDA8118FC6472F56A979586F33BB070FB0F1B0B10BC4897EBE01BCA3893D4E16ADB25093A7417D0708C83A26322E22E6330091E30152BF823597C04CCF4CFC7331578F43A2726CCB428289A90C863259DD180C5FF142BEF41C7717094BE07856DA2B140FA67710967356AA47DFBC8D255B4722AB86D439B7E0A6090251D2D4C1ED5F20BBE6807BF65A90B7CB2EC0102AF02809DC9AC7D0A3ABC69C18365BCFF59185F33996887746185906C0191AED4407E139446459BE29C6822717644353D24AB6339156A9C424909F0A9025BB74720779BE43F16D81C8CC666E99710D8C68BB5CC4E12F314E925A551F09CC59003A1F88103C254BB978D75F394D3540E31E771CDA36E39EC54A62B5832664D821A72F1E6AFBBA27F84295B2694C498498E812BC8E9378FE541CEC5891B25062901CB7212E3CDC46179EC5BCEC10BC0B9311DE05074290687FD6A5392671654284CD9C8CC3EBA80EB3B662EB53EB75116704A1FEB5C2D056338532868DDF24EB8992AB8565D9E490CADF14804360DAA90718EAB616BAB0765D33987B47EFB6599C5563235E61E4BE670E97955AB292D9732CB8930948AC82DF230AC72297A23679D6B94C17F1359483254FEDC2F05819F0D069A443B78E3FC6C3EF4714B05A3FCA81CBBA60242A7060CD885D8F39981BB18092B23DAA59FD9578388688A09BBA079BC809A54843A60385E2310BBCBCC0213CE3DFAAB33B47F9D6305BC95C6107813C585C4B657BF30542833B14949F573C0612AD524BAAE69590C1277B86C286571BF66B3CFF46A3858C09906A794DF4A06E9D4B0A2E43F10F72A6C6C47E5646E2C799B71C33ED2F01EEB45938EB7A4E2E2908C53558A540D350369FA189C616943F7981D7618CF02A5B0A2BCC422E857D1A47871253D08293C1C179BCDC0437069107418205FDB9856623B8CA6B694C96C084B17F13BB6DF12B2CFBBC2B0E0C34B00D0FCD0AECFB27924F6984E747BE2A09D83A8664590A8077331491A4F7D720843F23E652C6FA840308DB4020337AAD37967034A9FB523B67CA70330F02D9EA20C1E84CB8E5757C9E1896B60581441ED618AA5B26DA56C0A5A73C4DCFD755E610B4FC81FF84E21"; + String expectedPrivKey = "8C8B3722A82E550565521611EBBC63079944C9B1ABB3B0020FF12F631891A9C468D3A67BF6271280DA58D03CB042B3A461441637F929C273469AD15311E910DE18CB9537BA1BE42E98BB59E498A13FD440D0E69EE832B45CD95C382177D67096A18C07F1781663651BDCAC90DEDA3DDD143485864181C91FA2080F6DAB3F86204CEB64A7B4446895C03987A031CB4B6D9E0462FDA829172B6C012C638B29B5CD75A2C930A5596A3181C33A22D574D30261196BC350738D4FD9183A763336243ACED99B3221C71D8866895C4E52C119BF3280DAF80A95E15209A795C4435FBB3570FDB8AA9BF9AEFD43B094B781D5A81136DAB88B8799696556FEC6AE14B0BB8BE4695E9A124C2AB8FF4AB1229B8AAA8C6F41A60C34C7B56182C55C2C685E737C6CA00A23FB8A68C1CD61F30D3993A1653C1675AC5F0901A7160A73966408B8876B715396CFA4903FC69D60491F8146808C97CD5C533E71017909E97B835B86FF847B42A696375435E006061CF7A479463272114A89EB3EAF2246F0F8C104A14986828E0AD20420C9B37EA23F5C514949E77AD9E9AD12290DD1215E11DA274457AC86B1CE6864B122677F3718AA31B02580E64317178D38F25F609BC6C55BC374A1BF78EA8ECC219B30B74CBB3272A599238C93985170048F176775FB19962AC3B135AA59DB104F7114DBC2C2D42949ADECA6A85B323EE2B2B23A77D9DB235979A8E2D67CF7D2136BBBA71F269574B38888E1541340C19284074F9B7C8CF37EB01384E6E3822EC4882DFBBEC4E6098EF2B2FC177A1F0BCB65A57FDAA89315461BEB7885FB68B3CD096EDA596AC0E61DD7A9C507BC6345E0827DFCC8A3AC2DCE51AD731AA0EB932A6D0983992347CBEB3CD0D9C9719797CC21CF0062B0AD94CAD734C63E6B5D859CBE19F0368245351BF464D7505569790D2BB724D8659A9FEB1C7C473DC4D061E29863A2714BAC42ADCD1A8372776556F7928A7A44E94B6A25322D03C0A1622A7FD261522B7358F085BDFB60758762CB901031901B5EECF4920C81020A9B1781BCB9DD19A9DFB66458E7757C52CEC75B4BA740A24099CB56BB60A76B6901AA3E0169C9E83496D73C4C99435A28D613E97A1177F58B6CC595D3B2331E9CA7B57B74DC2C5277D26F2FE19240A55C35D6CFCA26C73E9A2D7C980D97960AE1A04698C16B398A5F20C35A0914145CE1674B71ABC6066A909A3E4B911E69D5A849430361F731B07246A6329B52361904225082D0AAC5B21D6B34862481A890C3C360766F04263603A6B73E802B1F70B2EB00046836B8F493BF10B90B8737C6C548449B294C47253BE26CA72336A632063AD3D0B48C8B0F4A34447EF13B764020DE739EB79ABA20E2BE1951825F293BEDD1089FCB0A91F560C8E17CDF52541DC2B81F972A7375B201F10C08D9B5BC8B95100054A3D0AAFF89BD08D6A0E7F2115A435231290460C9AD435A3B3CF35E52091EDD1890047BCC0AABB1ACEBC75F4A32BC1451ACC4969940788E89412188946C9143C5046BD1B458DF617C5DF533B052CD6038B7754034A23C2F7720134C7B4EACE01FAC0A2853A9285847ABBD06A3343A778AC6062E458BC5E61ECE1C0DE0206E6FE8A84034A7C5F1B005FB0A584051D3229B86C909AC5647B3D75569E05A88279D80E5C30F574DC327512C6BBE8101239EC62861F4BE67B05B9CDA9C545C13E7EB53CFF260AD9870199C21F8C63D64F0458A7141285023FEB829290872389644B0C3B73AC2C8E121A29BB1C43C19A233D56BED82740EB021C97B8EBBA40FF328B541760FCC372B52D3BC4FCBC06F424EAF253804D4CB46F41FF254C0C5BA483B44A87C219654555EC7C163C79B9CB760A2AD9BB722B93E0C28BD4B1685949C496EAB1AFF90919E3761B346838ABB2F01A91E554375AFDAAAF3826E6DB79FE7353A7A578A7C0598CE28B6D9915214236BBFFA6D45B6376A07924A39A7BE818286715C8A3C110CD76C02E0417AF138BDB95C3CCA798AC809ED69CFB672B6FDDC24D89C06A6558814AB0C21C62B2F84C0E3E0803DB337A4E0C7127A6B4C8C08B1D1A76BF07EB6E5B5BB47A16C74BC548375FB29CD789A5CFF91BDBD071859F4846E355BB0D29484E264DFF36C9177A7ACA78908879695CA87F25436BC12630724BB22F0CB64897FE5C41195280DA04184D4BC7B532A0F70A54D7757CDE6175A6843B861CB2BC4830C0012554CFC5D2C8A2027AA3CD967130E9B96241B11C4320C7649CC23A71BAFE691AFC08E680BCEF42907000718E4EACE8DA28214197BE1C269DA9CB541E1A3CE97CFADF9C6058780FE6793DBFA8218A2760B802B8DA2AA271A38772523A76736A7A31B9D3037AD21CEBB11A472B8792EB17558B940E70883F264592C689B240BB43D5408BF446432F412F4B9A5F6865CC252A43CF40A320391555591D67561FDD05353AB6B019B3A08A73353D51B6113AB2FA51D975648EE254AF89A230504A236A4658257740BDCBBE1708AB022C3C588A410DB3B9C308A06275BDF5B4859D3A2617A295E1A22F90198BAD0166F4A943417C5B831736CB2C8580ABFDE5714B586ABEEC0A175A08BC710C7A2895DE93AC438061BF7765D0D21CD418167CAF89D1EFC3448BCBB96D69B3E010C82D15CAB6CACC6799D3639669A5B21A633C865F8593B5B7BC800262BB837A924A6C5440E4FC73B41B23092C3912F4C6BEBB4C7B4C62908B03775666C22220DF9C88823E344C7308332345C8B795D34E8C051F21F5A21C214B69841358709B1C305B32CC2C3806AE9CCD3819FFF4507FE520FBFC27199BC23BE6B9B2D2AC1717579AC769279E2A7AAC68A371A47BA3A7DBE016F14E1A727333663C4A5CD1A0F8836CF7B5C49AC51485CA60345C990E06888720003731322C5B8CD5E6907FDA1157F468FD3FC20FA8175EEC95C291A262BA8C5BE990872418930852339D88A19B37FEFA3CFE82175C224407CA414BAEB37923B4D2D83134AE154E490A9B45A0563B06C953C3301450A2176A07C614A74E3478E48509F9A60AE945A8EBC7815121D90A3B0E07091A096CF02C57B25BCA58126AD0C629CE166A7EDB4B33221A0D3F72B85D562EC698B7D0A913D73806F1C5C87B38EC003CB303A3DC51B4B35356A67826D6EDAA8FEB93B98493B2D1C11B676A6AD9506A1AAAE13A824C7C08D1C6C2C4DBA9642C76EA7F6C8264B64A23CCCA9A74635FCBF03E00F1B5722B214376790793B2C4F0A13B5C40760B4218E1D2594DCB30A70D9C1782A5DD30576FA4144BFC8416EDA8118FC6472F56A979586F33BB070FB0F1B0B10BC4897EBE01BCA3893D4E16ADB25093A7417D0708C83A26322E22E6330091E30152BF823597C04CCF4CFC7331578F43A2726CCB428289A90C863259DD180C5FF142BEF41C7717094BE07856DA2B140FA67710967356AA47DFBC8D255B4722AB86D439B7E0A6090251D2D4C1ED5F20BBE6807BF65A90B7CB2EC0102AF02809DC9AC7D0A3ABC69C18365BCFF59185F33996887746185906C0191AED4407E139446459BE29C6822717644353D24AB6339156A9C424909F0A9025BB74720779BE43F16D81C8CC666E99710D8C68BB5CC4E12F314E925A551F09CC59003A1F88103C254BB978D75F394D3540E31E771CDA36E39EC54A62B5832664D821A72F1E6AFBBA27F84295B2694C498498E812BC8E9378FE541CEC5891B25062901CB7212E3CDC46179EC5BCEC10BC0B9311DE05074290687FD6A5392671654284CD9C8CC3EBA80EB3B662EB53EB75116704A1FEB5C2D056338532868DDF24EB8992AB8565D9E490CADF14804360DAA90718EAB616BAB0765D33987B47EFB6599C5563235E61E4BE670E97955AB292D9732CB8930948AC82DF230AC72297A23679D6B94C17F1359483254FEDC2F05819F0D069A443B78E3FC6C3EF4714B05A3FCA81CBBA60242A7060CD885D8F39981BB18092B23DAA59FD9578388688A09BBA079BC809A54843A60385E2310BBCBCC0213CE3DFAAB33B47F9D6305BC95C6107813C585C4B657BF30542833B14949F573C0612AD524BAAE69590C1277B86C286571BF66B3CFF46A3858C09906A794DF4A06E9D4B0A2E43F10F72A6C6C47E5646E2C799B71C33ED2F01EEB45938EB7A4E2E2908C53558A540D350369FA189C616943F7981D7618CF02A5B0A2BCC422E857D1A47871253D08293C1C179BCDC0437069107418205FDB9856623B8CA6B694C96C084B17F13BB6DF12B2CFBBC2B0E0C34B00D0FCD0AECFB27924F6984E747BE2A09D83A8664590A8077331491A4F7D720843F23E652C6FA840308DB4020337AAD37967034A9FB523B67CA70330F02D9EA20C1E84CB8E5757C9E1896B60581441ED618AA5B26DA56C0A5A73C4DCFD755E610B4FC81FF84E21D2E574DFD8CD0AE893AA7E125B44B924F45223EC09F2AD1141EA93A68050DBF699E3246884181F8E1DD44E0C7629093330221FD67D9B7D6E1510B2DBAD8762F7"; + + SecureRandom random = new SecureRandom(); + MLKEMKeyPairGenerator keyGen = new MLKEMKeyPairGenerator(); + + keyGen.init(new MLKEMKeyGenerationParameters(random, MLKEMParameters.ml_kem_1024)); + + AsymmetricCipherKeyPair keyPair = keyGen.internalGenerateKeyPair(d, z); + assertTrue(Arrays.areEqual(Hex.decode(expectedPubKey), ((MLKEMPublicKeyParameters)keyPair.getPublic()).getEncoded())); + + assertTrue(Arrays.areEqual(Hex.decode(expectedPrivKey), ((MLKEMPrivateKeyParameters)keyPair.getPrivate()).getEncoded())); + + MLKEMGenerator kemGen = new MLKEMGenerator(random); + + byte[] message = Hex.decode("59C5154C04AE43AAFF32700F081700389D54BEC4C37C088B1C53F66212B12C72"); + + SecretWithEncapsulation secretEncap = kemGen.internalGenerateEncapsulated(keyPair.getPublic(), message); + + String expectedSharedSecret = "5CF38F578AC4AE95FBFED574B3D8EBF7CB1DC9074F22277360E36D775347C058"; + + assertTrue(Arrays.areEqual(Hex.decode(expectedSharedSecret), secretEncap.getSecret())); + + String expectedCipherText = "8B9FE419250C5FB0463C8181FCF7CEC777136B738E015EBA31067AA4A8C378BBAC0121B88214F1AEB866E4F33C277099E09B4BF7E21CDDA30B5B32C18B0E9660C30601D85DAEC07AAF4B343EC5516FA501DD63088B999FB9A414C6CA593806C08CD4C775139BF0F0BF3676D773EDD56E616A13830D5F5FE35E515DBC84E43AAD0167D57E60A9DE30886ACD3F7F2006CAC26A7A07B4DADBEDFBED7F305764386AAD726D5B2BF14A376BAD8B4896688491733FB34E6EDEA10BFD5E448541CB6E69E3D87DF190AFA7FF62577775BAACEA444A6128A20200251D8FA759DC60FDA6A9730CFFE4997FE7EBCDD1644AE2D55290A4074CDD2CE53C18D22BC33671E68727A9B5A2FEAFB114A8045D96A56981E200A09661375987625ACC233EDE817AF1DEEAA21C7C4377423E73C5AF9BFF58A49DE6DAFD07A3E3BABD891F62BBA41D1856B8BC502CC86EE115A3598431E2B54AB0C5EACC3CE6A03090925C1FD5A251B00576763A963994A7A23EE12EBFC1B994F93C6144178F0BEF88245CE77CD32EF651826A6090AF561A5864DEC2A51D846F1F48F88B4B55F58C2373E0F67BDC95DC23A43E8546232A7B234E49F5226A3A63BDBCED7240FC81C2DB68AAEB2671A2FD231997BF8839C63A7F41F15E7242821D42E80BBC0F43FA9E353DE8B25ED8FFC242EB512C6A5260919AAE89A11176532BCCC762A520A37AEC4E7209AA81CEE0DD4ADD932C47EB8100BE98AA1DEEA9EA698115ADCED950A6C536D19AEB325CEA8C5245C0A2281533FB90809DC2BE90567EBE6AE229FE09B44DA2182585EA694D8A9AB33EBC24B44E09BD510F34B4140E1FB41162F9415F2D9106A0CEA00A26ED0920021F4E5BCFB3DABF5850DAB22B2E889D9611FBE06D0C899708EB5E5FAD2FBBE0D5C0BDE080F8E760EDFA037D55DA77F0F39591BF5B050C905FA538B7228E238A290DF340778DCBD6BE40A3B1DD455FB27ADBE176AEF6CC295BEA570BDC221BA14002E3B113B0EF237452FBC9F1AEC42E0D2B33F19832DB0A6171CAEB0B30EEAD3A54B704B761C7D4AFEA8F6AFC15156666A081C43AEB2E04FEECEF8AABA4049BD78B120B9ABA86A60342A0CF806411C473C26C4BE1540E3312388BCBC8523BA73F40EA28D5564274F3661D7ACAA0F1E8D0F28DCF6B501329963E6857FDB2AAE873A7D9D6C14821F6C0B6AA50AC449075CD6F2A256C5A05959DAB5A5912CC8E8F8B9F59941BFCCE6A28CBA74A20382B1FD3382D056547D5BC5EF4AAE62F96F038C595A4F901D6AE790F8978292AD1CC3A1E800B71A5BBE84533646655E3752FBD6B02B97B204E75D28A34C2F990FB8E8CD31CE6E683FA7E67DA03367E8D47DC626F060FBA2D0425004CAC2A61D982D2E3D85008624B45DB022CF51BA265B5E974712A9372EECAC0EA272B2FC56EBED0D32105521BA2C4A8FE0C678CE4E45902C7BA9D510BD47B2B5F931DD732F27DE9B42FD4AA39EAC765283A9965EE97C0D88E23EFA6F718242C67770B87BF8832858C1D13FC520870BD34F2B9C6FBFD1A528B744F814C93F4F4E87108316FE2AB06E02292DEA7FCF6FEFB17BF5AA7376A4A9BDB7C49BF709EB1E05D60EF14CD85A75239B97BCA9A6A3CC1B28F28979D612431BAAC1ACEE5EF62776B4D51B7EB0F63DF507760097223CA903E16E02DEB7FCABFBEC26DAEDC0ED4CC55726BDC31D1775112EF3C35D1DF928C6EB7830D8CA6570CB5CE348E3F26DDE864F20E5BE7B99E264EBC0E9D8DE9C6E4B7FE3CFBE673833CF7E8B3081529062CB6815C7C0766822B3B31E56BA1FC73FE3DED4B5D435BFCE2F2997C1D4B9CE293220DD461103BE084BF12076372668A69836769C1F6D8C32E2C7BC2E7D66714C814793A2970C90DD94DF14C89C60DD35B52A14778E137E750CE83AC3AAB667FCBDCBA38B7FA6D1C6BF7B99D957078176D9779A09F84B75FBC2A11769EF65532B09ACA4C9A3766B4A1FC717F94648FB8B8D9363E54F1C4201C075C18B1EAE098B83598089585ED9DC06B96E2D1C96DC738086EBBC26C3193B64139E1FC1DFB22A17893506EF7B35792B4EB00196693686EB5DEB3CEB436DD16D2D92A0FD31F468AF8662040F5257BFA0F14991C0D560999EEF775178D14955ADF091DD797AC1FDCEC7776055271C0F130562D0B0A6749B159DD0DB9AC69271AC719B83B683CE8B32342AC4AB257B0F8083C8CC86338AFA4D386C9848F413ED0"; + + assertTrue(Arrays.areEqual(Hex.decode(expectedCipherText), secretEncap.getEncapsulation())); + + MLKEMExtractor kemExtract = new MLKEMExtractor((MLKEMPrivateKeyParameters)keyPair.getPrivate()); + + byte[] decryptedSharedSecret = kemExtract.extractSecret(secretEncap.getEncapsulation()); + + assertTrue(Arrays.areEqual(Hex.decode(expectedSharedSecret), decryptedSharedSecret)); + } + + public void testRNG() + { + String temp = "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"; + byte[] seed = Hex.decode(temp); + NISTSecureRandom r = new NISTSecureRandom(seed, null); + byte[] testBytes = new byte[48]; + r.nextBytes(testBytes); + + String randBytesString = "7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E47"; + byte[] randBytes = Hex.decode(randBytesString); + + assertTrue(Arrays.areEqual(randBytes, testBytes)); + } + + public void testParameters() + throws Exception + { + assertEquals(256, MLKEMParameters.ml_kem_512.getSessionKeySize()); + assertEquals(256, MLKEMParameters.ml_kem_768.getSessionKeySize()); + assertEquals(256, MLKEMParameters.ml_kem_1024.getSessionKeySize()); + } + + public void testVectors() + throws Exception + { + //Disabled OLD KATs +// KyberParameters[] params = new KyberParameters[]{ +// KyberParameters.kyber512, +// KyberParameters.kyber768, +// KyberParameters.kyber1024, +// }; +// +// String[] files = new String[]{ +// "kyber512.rsp", +// "kyber768.rsp", +// "kyber1024.rsp", +// }; +// +// TestSampler sampler = new TestSampler(); +// for (int fileIndex = 0; fileIndex != files.length; fileIndex++) +// { +// String name = files[fileIndex]; +// // System.out.println("testing: " + name); +// InputStream src = TestResourceFinder.findTestResource("pqc/crypto/kyber", name); +// BufferedReader bin = new BufferedReader(new InputStreamReader(src)); +// +// String line = null; +// HashMap buf = new HashMap(); +// while ((line = bin.readLine()) != null) +// { +// line = line.trim(); +// +// if (line.startsWith("#")) +// { +// continue; +// } +// if (line.length() == 0) +// { +// if (buf.size() > 0) +// { +// String count = (String)buf.get("count"); +// if (sampler.skipTest(count)) +// { +// continue; +// } +// // System.out.println("test case: " + count); +// +// byte[] seed = Hex.decode((String)buf.get("seed")); // seed for Kyber secure random +// byte[] pk = Hex.decode((String)buf.get("pk")); // public key +// byte[] sk = Hex.decode((String)buf.get("sk")); // private key +// byte[] ct = Hex.decode((String)buf.get("ct")); // ciphertext +// byte[] ss = Hex.decode((String)buf.get("ss")); // session key +// +// NISTSecureRandom random = new NISTSecureRandom(seed, null); +// KyberParameters parameters = params[fileIndex]; +// +// byte[] coins = new byte[64]; +// random.nextBytes(coins); +// KyberKeyPairGenerator kpGen = new KyberKeyPairGenerator(); +// KyberKeyGenerationParameters genParam = new KyberKeyGenerationParameters(new FixedSecureRandom(coins), parameters); +// // +// // Generate keys and test. +// // +// kpGen.init(genParam); +// AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); +// +// KyberPublicKeyParameters pubParams = (KyberPublicKeyParameters)PublicKeyFactory.createKey( +// SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo((KyberPublicKeyParameters)kp.getPublic())); +// KyberPrivateKeyParameters privParams = (KyberPrivateKeyParameters)PrivateKeyFactory.createKey( +// PrivateKeyInfoFactory.createPrivateKeyInfo((KyberPrivateKeyParameters)kp.getPrivate())); +// +// assertTrue(name + " " + count + ": public key", Arrays.areEqual(pk, pubParams.getEncoded())); +// assertTrue(name + " " + count + ": secret key", Arrays.areEqual(sk, privParams.getEncoded())); +// +// // KEM Enc +// KyberKEMGenerator KyberEncCipher = new KyberKEMGenerator(random); +// SecretWithEncapsulation secWenc = KyberEncCipher.generateEncapsulated(pubParams); +// byte[] generated_cipher_text = secWenc.getEncapsulation(); +// +// //assertTrue(name + " " + count + ": kem_enc cipher text", Arrays.areEqual(ct, generated_cipher_text)); +// byte[] secret = secWenc.getSecret(); +// assertTrue(name + " " + count + ": kem_enc key", Arrays.areEqual(ss, 0, secret.length, secret, 0, secret.length)); +// +// // KEM Dec +// KyberKEMExtractor KyberDecCipher = new KyberKEMExtractor(privParams); +// +// byte[] dec_key = KyberDecCipher.extractSecret(generated_cipher_text); +// +// assertTrue(name + " " + count + ": kem_dec ss", Arrays.areEqual(ss, 0, dec_key.length, dec_key, 0, dec_key.length)); +// assertTrue(name + " " + count + ": kem_dec key", Arrays.areEqual(dec_key, secret)); +// // } +// // catch (AssertionError e) { +// // // System.out.println("Failed assertion error."); +// // // System.out.println(); +// +// // // System.out.println(); +// // continue; +// // } +// } +// buf.clear(); +// +// continue; +// } +// +// int a = line.indexOf("="); +// if (a > -1) +// { +// buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); +// } +// } +// // System.out.println("testing successful!"); +// } + } + + public void testKyberRandom() + { + SecureRandom random = new SecureRandom(); + MLKEMKeyPairGenerator keyGen = new MLKEMKeyPairGenerator(); + + keyGen.init(new MLKEMKeyGenerationParameters(random, MLKEMParameters.ml_kem_1024)); + + for (int i = 0; i != 1000; i++) + { + AsymmetricCipherKeyPair keyPair = keyGen.generateKeyPair(); + + MLKEMGenerator kemGen = new MLKEMGenerator(random); + + SecretWithEncapsulation secretEncap = kemGen.generateEncapsulated(keyPair.getPublic()); + + MLKEMExtractor kemExtract = new MLKEMExtractor((MLKEMPrivateKeyParameters)keyPair.getPrivate()); + + byte[] decryptedSharedSecret = kemExtract.extractSecret(secretEncap.getEncapsulation()); + + assertTrue(Arrays.areEqual(secretEncap.getSecret(), decryptedSharedSecret)); + } + } +} diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRULPRimeTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRULPRimeTest.java index 89dd907dff..774c6e59f1 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRULPRimeTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRULPRimeTest.java @@ -16,6 +16,7 @@ import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePublicKeyParameters; import org.bouncycastle.test.TestResourceFinder; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; public class NTRULPRimeTest @@ -41,8 +42,8 @@ public void testKEM() for (int i = 0; i != paramList.length; i++) { NTRULPRimeParameters paramSpec = paramList[i]; - System.out.println("**** Parameter Spec - '" + paramSpec.getName().toUpperCase() + "' ****"); - InputStream resource = TestResourceFinder.findTestResource(resourcePath, paramSpec.getName().toLowerCase() + ".rsp"); + // System.out.println("**** Parameter Spec - '" + paramSpec.getName().toUpperCase() + "' ****"); + InputStream resource = TestResourceFinder.findTestResource(resourcePath, Strings.toLowerCase(paramSpec.getName()) + ".rsp"); BufferedReader resourceReader = new BufferedReader(new InputStreamReader(resource)); String line; @@ -67,31 +68,31 @@ public void testKEM() continue; } - System.out.println("Running Test-" + count + " ..."); + // System.out.println("Running Test-" + count + " ..."); NISTSecureRandom random = new NISTSecureRandom(seed, null); NTRULPRimeKeyPairGenerator keyPairGenerator = new NTRULPRimeKeyPairGenerator(); keyPairGenerator.init(new NTRULPRimeKeyGenerationParameters(random, paramSpec)); AsymmetricCipherKeyPair keyPair = keyPairGenerator.generateKeyPair(); assertTrue(Arrays.areEqual(pk, ((NTRULPRimePublicKeyParameters)keyPair.getPublic()).getEncoded())); - System.out.println("- Public Key matched ..."); + // System.out.println("- Public Key matched ..."); assertTrue(Arrays.areEqual(sk, ((NTRULPRimePrivateKeyParameters)keyPair.getPrivate()).getEncoded())); - System.out.println("- Private Key matched ..."); + // System.out.println("- Private Key matched ..."); NTRULPRimeKEMGenerator kemGenerator = new NTRULPRimeKEMGenerator(random); SecretWithEncapsulation secretEncapsulation = kemGenerator.generateEncapsulated(keyPair.getPublic()); assertTrue(Arrays.areEqual(ct, secretEncapsulation.getEncapsulation())); - System.out.println("- Encapsulation Cipher Text matched ..."); + // System.out.println("- Encapsulation Cipher Text matched ..."); byte[] secret = secretEncapsulation.getSecret(); assertTrue(Arrays.areEqual(ss, 0, secret.length, secret, 0, secret.length)); - System.out.println("- Encapsulation Shared Secret matched ..."); + // System.out.println("- Encapsulation Shared Secret matched ..."); NTRULPRimeKEMExtractor kemExtractor = new NTRULPRimeKEMExtractor((NTRULPRimePrivateKeyParameters)keyPair.getPrivate()); byte[] decryptedSecret = kemExtractor.extractSecret(ct); assertTrue(Arrays.areEqual(secret, decryptedSecret)); - System.out.println("- Decapsulation Shared Secret matched ..."); + // System.out.println("- Decapsulation Shared Secret matched ..."); } resource.close(); diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRUParametersTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRUParametersTest.java index 96e05c9158..e1f2a9096a 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRUParametersTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRUParametersTest.java @@ -11,11 +11,13 @@ public class NTRUParametersTest public void testParameters() throws Exception { - assertEquals(128, NTRUParameters.ntruhps2048509.getSessionKeySize()); - assertEquals(192, NTRUParameters.ntruhps2048677.getSessionKeySize()); + assertEquals(256, NTRUParameters.ntruhps2048509.getSessionKeySize()); + assertEquals(256, NTRUParameters.ntruhps2048677.getSessionKeySize()); assertEquals(256, NTRUParameters.ntruhps4096821.getSessionKeySize()); + assertEquals(256, NTRUParameters.ntruhps40961229.getSessionKeySize()); - assertEquals(192, NTRUParameters.ntruhrss701.getSessionKeySize()); + assertEquals(256, NTRUParameters.ntruhrss701.getSessionKeySize()); +// assertEquals(256, NTRUParameters.ntruhrss1373.getSessionKeySize()); } public void testHpsParameters() @@ -48,7 +50,7 @@ public void testHpsParameters() // kem_ciphertext_bytes assertEquals(699, hps2048509.ntruCiphertextBytes()); // kem_shared_key_bytes - category 1 - assertEquals(128, hps2048509.sharedKeyBytes() * 8); + assertEquals(256, hps2048509.sharedKeyBytes() * 8); // prf_key_bits assertEquals(256, hps2048509.prfKeyBytes() * 8); } @@ -81,7 +83,7 @@ public void testHrssParameters() // kem_ciphertext_bytes assertEquals(1138, hrss701.ntruCiphertextBytes()); // kem_shared_key_bytes - category 3 - assertEquals(192, hrss701.sharedKeyBytes() * 8); + assertEquals(256, hrss701.sharedKeyBytes() * 8); // prf_key_bits assertEquals(256, hrss701.prfKeyBytes() * 8); } diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRUTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRUTest.java index 27619566f9..7624329cca 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRUTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRUTest.java @@ -8,12 +8,11 @@ import junit.framework.Assert; import junit.framework.TestCase; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.crypto.util.DEROtherInfo; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.pqc.crypto.ntru.NTRUKEMExtractor; import org.bouncycastle.pqc.crypto.ntru.NTRUKEMGenerator; import org.bouncycastle.pqc.crypto.ntru.NTRUKeyGenerationParameters; @@ -37,19 +36,27 @@ public class NTRUTest NTRUParameters.ntruhps2048509, NTRUParameters.ntruhps2048677, NTRUParameters.ntruhps4096821, - NTRUParameters.ntruhrss701 + NTRUParameters.ntruhps40961229, + NTRUParameters.ntruhrss701, + NTRUParameters.ntruhrss1373 }; + private final String[] katBase = { "ntruhps2048509", "ntruhps2048677", "ntruhps4096821", - "ntruhrss701" + "ntruhps40961229", + "ntruhrss701", + "ntruhrss1373" }; + private final String[] katFiles = { "PQCkemKAT_935.rsp", "PQCkemKAT_1234.rsp", "PQCkemKAT_1590.rsp", - "PQCkemKAT_1450.rsp" + "PQCkemKAT_2366.rsp", + "PQCkemKAT_1450.rsp", + "PQCkemKAT_2983.rsp" }; public void testPrivInfoGeneration() @@ -77,6 +84,7 @@ public void testPQCgenKAT_kem() for (int i = 0; i < this.params.length; i++) { NTRUParameters param = params[i]; + InputStream src = TestResourceFinder.findTestResource("pqc/crypto/ntru/" + katBase[i], katFiles[i]); List kats = NTRUKAT.getKAT(src); diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/NewHopeTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/NewHopeTest.java index c8ce5677fb..a9ca786ca7 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/NewHopeTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/NewHopeTest.java @@ -3,11 +3,11 @@ import java.io.IOException; import java.security.SecureRandom; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.util.DEROtherInfo; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.pqc.crypto.ExchangePair; import org.bouncycastle.pqc.crypto.newhope.NHAgreement; import org.bouncycastle.pqc.crypto.newhope.NHExchangePairGenerator; diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/PicnicVectorTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/PicnicVectorTest.java index 394d7e4eba..5d048aff09 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/PicnicVectorTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/PicnicVectorTest.java @@ -95,7 +95,7 @@ public void testVectors() for (int fileIndex = 0; fileIndex != files.length; fileIndex++) { String name = files[fileIndex]; - System.out.println("testing: " + name); + // System.out.println("testing: " + name); InputStream src = TestResourceFinder.findTestResource("pqc/crypto/picnic", name); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); @@ -118,7 +118,7 @@ public void testVectors() { continue; } - System.out.println("test case: " + count); + // System.out.println("test case: " + count); byte[] seed = Hex.decode((String)buf.get("seed")); // seed for picnic secure random int mlen = Integer.parseInt((String)buf.get("mlen")); // message length byte[] msg = Hex.decode((String)buf.get("msg")); // message @@ -127,7 +127,7 @@ public void testVectors() int smlen = Integer.parseInt((String)buf.get("smlen")); // signature length byte[] sigExpected = Hex.decode((String)buf.get("sm")); // signature -// System.out.println("message: " + Hex.toHexString(msg)); +// // System.out.println("message: " + Hex.toHexString(msg)); NISTSecureRandom random = new NISTSecureRandom(seed, null); PicnicParameters parameters = params[fileIndex]; @@ -144,8 +144,8 @@ public void testVectors() PicnicPublicKeyParameters pubParams = (PicnicPublicKeyParameters) PublicKeyFactory.createKey(SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(kp.getPublic())); PicnicPrivateKeyParameters privParams = (PicnicPrivateKeyParameters) PrivateKeyFactory.createKey(PrivateKeyInfoFactory.createPrivateKeyInfo(kp.getPrivate())); -// System.out.println("pk = " + Hex.toHexString(pubParams.getEncoded()).toUpperCase()); -// System.out.println("sk = " + Hex.toHexString(privParams.getEncoded()).toUpperCase()); +// // System.out.println("pk = " + Hex.toHexString(pubParams.getEncoded()).toUpperCase()); +// // System.out.println("sk = " + Hex.toHexString(privParams.getEncoded()).toUpperCase()); assertTrue(name + " " + count + ": public key", Arrays.areEqual(pk, pubParams.getEncoded())); assertTrue(name + " " + count + ": secret key", Arrays.areEqual(sk, privParams.getEncoded())); @@ -161,9 +161,9 @@ public void testVectors() byte[] sigGenerated = signer.generateSignature(msg); byte[] attachedSig = Arrays.concatenate(Pack.intToLittleEndian(sigGenerated.length), msg, sigGenerated); -// System.out.println("expected:\t" + Hex.toHexString(sigExpected)); -// System.out.println("generated:\t" + Hex.toHexString(sigGenerated)); -// System.out.println("attached:\t" + Hex.toHexString(attachedSig)); +// // System.out.println("expected:\t" + Hex.toHexString(sigExpected)); +// // System.out.println("generated:\t" + Hex.toHexString(sigGenerated)); +// // System.out.println("attached:\t" + Hex.toHexString(attachedSig)); assertEquals(name + " " + count + ": signature length", smlen, attachedSig.length); @@ -184,7 +184,7 @@ public void testVectors() buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("testing successful!"); + // System.out.println("testing successful!"); } } diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/RainbowVectorTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/RainbowVectorTest.java index cdd5cdca99..8de315b7a1 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/RainbowVectorTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/RainbowVectorTest.java @@ -47,7 +47,7 @@ public void testVectors() for (int fileIndex = 0; fileIndex != files.length; fileIndex++) { String name = files[fileIndex]; - System.out.println("testing: " + name); + // System.out.println("testing: " + name); InputStream src = TestResourceFinder.findTestResource("pqc/crypto/rainbow", name); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); @@ -71,7 +71,7 @@ public void testVectors() continue; } - System.out.println("test case: " + count); + // System.out.println("test case: " + count); byte[] seed = Hex.decode((String)buf.get("seed")); // seed for Rainbow secure random int mlen = Integer.parseInt((String)buf.get("mlen")); // message length byte[] msg = Hex.decode((String)buf.get("msg")); // message @@ -108,9 +108,9 @@ public void testVectors() byte[] sigGenerated = signer.generateSignature(msg); byte[] attachedSig = Arrays.concatenate(msg, sigGenerated); - //System.out.println("expected:\t" + Hex.toHexString(sigExpected).toUpperCase().substring(msg.length*2, sigExpected.length*2)); - //System.out.println("generated:\t" + Hex.toHexString(sigGenerated).toUpperCase()); - //System.out.println("attached:\t" + Hex.toHexString(attachedSig).toUpperCase()); + //// System.out.println("expected:\t" + Hex.toHexString(sigExpected).toUpperCase().substring(msg.length*2, sigExpected.length*2)); + //// System.out.println("generated:\t" + Hex.toHexString(sigGenerated).toUpperCase()); + //// System.out.println("attached:\t" + Hex.toHexString(attachedSig).toUpperCase()); signer.init(false, kp.getPublic()); @@ -128,7 +128,7 @@ public void testVectors() buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); } } - System.out.println("testing successful!"); + // System.out.println("testing successful!"); } } diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/SABERVectorTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/SABERVectorTest.java index 99b5735d85..ce5f0d1ea7 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/SABERVectorTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/SABERVectorTest.java @@ -84,7 +84,7 @@ public void testVectors() for (int fileIndex = 0; fileIndex != files.length; fileIndex++) { String name = files[fileIndex]; - System.out.println("testing: " + name); + // System.out.println("testing: " + name); InputStream src = TestResourceFinder.findTestResource("pqc/crypto/saber", name); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); @@ -107,7 +107,7 @@ public void testVectors() { continue; } - System.out.println("test case: " + count); + // System.out.println("test case: " + count); byte[] seed = Hex.decode((String)buf.get("seed")); // seed for SABER secure random byte[] pk = Hex.decode((String)buf.get("pk")); // public key @@ -162,7 +162,7 @@ public void testVectors() } - System.out.println("testing successful!"); + // System.out.println("testing successful!"); } } diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/SIKEVectorTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/SIKEVectorTest.java deleted file mode 100644 index b02dabe22a..0000000000 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/SIKEVectorTest.java +++ /dev/null @@ -1,169 +0,0 @@ -package org.bouncycastle.pqc.crypto.test; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.HashMap; - -import junit.framework.TestCase; -import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.SecretWithEncapsulation; -import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; -import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; -import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; -import org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEKEMExtractor; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEKEMGenerator; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEKeyGenerationParameters; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEKeyPairGenerator; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEParameters; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEPrivateKeyParameters; -import org.bouncycastle.pqc.legacy.crypto.sike.SIKEPublicKeyParameters; -import org.bouncycastle.test.TestResourceFinder; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.encoders.Hex; - -public class SIKEVectorTest - extends TestCase -{ - public void testParameters() - throws Exception - { - assertEquals(128, SIKEParameters.sikep434.getSessionKeySize()); - assertEquals(128, SIKEParameters.sikep434_compressed.getSessionKeySize()); - assertEquals(192, SIKEParameters.sikep503.getSessionKeySize()); - assertEquals(192, SIKEParameters.sikep503_compressed.getSessionKeySize()); - assertEquals(192, SIKEParameters.sikep610.getSessionKeySize()); - assertEquals(192, SIKEParameters.sikep610_compressed.getSessionKeySize()); - assertEquals(256, SIKEParameters.sikep751.getSessionKeySize()); - assertEquals(256, SIKEParameters.sikep751_compressed.getSessionKeySize()); - } - - public void testVector() - throws Exception - { - boolean full = System.getProperty("test.full", "false").equals("true"); - full = true; //todo: remove - - String[] files; - if(full) - { - files = new String[]{ - "PQCkemKAT_374.rsp", //434 - "PQCkemKAT_434.rsp", //503 - "PQCkemKAT_524.rsp", //610 - "PQCkemKAT_644.rsp", //751 - "PQCkemKAT_350.rsp", //434 compressed - "PQCkemKAT_407.rsp", //503 compressed - "PQCkemKAT_491.rsp", //610 compressed - "PQCkemKAT_602.rsp", //751 compressed - }; - } - else - { - files = new String[]{ - "PQCkemKAT_374.rsp", - "PQCkemKAT_350.rsp", //compressed - }; - } - - SIKEParameters[] params = new SIKEParameters[]{ - SIKEParameters.sikep434, - SIKEParameters.sikep503, - SIKEParameters.sikep610, - SIKEParameters.sikep751, - SIKEParameters.sikep434_compressed, - SIKEParameters.sikep503_compressed, - SIKEParameters.sikep610_compressed, - SIKEParameters.sikep751_compressed, - }; - - TestSampler sampler = new TestSampler(); - - for (int fileIndex = 0; fileIndex != files.length; fileIndex++) - { - String name = files[fileIndex]; - System.out.println("testing: " + name); - InputStream src = TestResourceFinder.findTestResource("pqc/crypto/sike", name); - BufferedReader bin = new BufferedReader(new InputStreamReader(src)); - - String line = null; - HashMap buf = new HashMap(); - while ((line = bin.readLine()) != null) - { - line = line.trim(); - - if (line.startsWith("#")) - { - continue; - } - if (line.length() == 0) - { - if (buf.size() > 0) - { - String count = (String)buf.get("count"); - if (sampler.skipTest(count)) - { - continue; - } - System.out.println("test case: " + count); - byte[] seed = Hex.decode((String)buf.get("seed")); // seed for sike secure random - byte[] pk = Hex.decode((String)buf.get("pk")); // public key - byte[] sk = Hex.decode((String)buf.get("sk")); // private key - byte[] ct = Hex.decode((String)buf.get("ct")); // ciphertext - byte[] ss = Hex.decode((String)buf.get("ss")); // session key - - NISTSecureRandom random = new NISTSecureRandom(seed, null); - SIKEParameters parameters = params[fileIndex]; - - SIKEKeyPairGenerator kpGen = new SIKEKeyPairGenerator(); - SIKEKeyGenerationParameters genParam = new SIKEKeyGenerationParameters(random, parameters); - // - // Generate keys and test. - // - kpGen.init(genParam); - AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); - -// SIKEPublicKeyParameters pubParams = (SIKEPublicKeyParameters) kp.getPublic(); - SIKEPublicKeyParameters pubParams = (SIKEPublicKeyParameters) PublicKeyFactory.createKey(SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo((SIKEPublicKeyParameters)kp.getPublic())); -// SIKEPrivateKeyParameters privParams = (SIKEPrivateKeyParameters) kp.getPrivate(); - SIKEPrivateKeyParameters privParams = (SIKEPrivateKeyParameters) PrivateKeyFactory.createKey(PrivateKeyInfoFactory.createPrivateKeyInfo((SIKEPrivateKeyParameters)kp.getPrivate())); - - assertTrue(name + " " + count + ": public key", Arrays.areEqual(pk, pubParams.getPublicKey())); - assertTrue(name + " " + count + ": secret key", Arrays.areEqual(sk, privParams.getPrivateKey())); - - // KEM Enc - SIKEKEMGenerator sikeEncCipher = new SIKEKEMGenerator(random); - SecretWithEncapsulation secWenc = sikeEncCipher.generateEncapsulated(pubParams); - byte[] generated_cipher_text = secWenc.getEncapsulation(); - - assertTrue(name + " " + count + ": kem_enc cipher text", Arrays.areEqual(ct, generated_cipher_text)); - byte[] secret = secWenc.getSecret(); - - assertTrue(name + " " + count + ": kem_enc key", Arrays.areEqual(ss, secret)); - - // KEM Dec - SIKEKEMExtractor sikeDecCipher = new SIKEKEMExtractor(privParams); - - byte[] dec_key = sikeDecCipher.extractSecret(generated_cipher_text); - - assertTrue(name + " " + count + ": kem_dec ss", Arrays.areEqual(dec_key, ss)); - assertTrue(name + " " + count + ": kem_dec key", Arrays.areEqual(dec_key, secret)); - } - buf.clear(); - - continue; - } - - int a = line.indexOf("="); - if (a > -1) - { - buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); - } - - - } - System.out.println("testing successful!"); - } - } -} diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/SLHDSATest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/SLHDSATest.java new file mode 100644 index 0000000000..ae60abf028 --- /dev/null +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/SLHDSATest.java @@ -0,0 +1,511 @@ +package org.bouncycastle.pqc.crypto.test; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import junit.framework.TestCase; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAKeyPairGenerator; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAPublicKeyParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSASigner; +import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; +import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; +import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; +import org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory; +import org.bouncycastle.test.TestResourceFinder; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; + +public class SLHDSATest + extends TestCase +{ + public void testKeyGen() throws IOException + { + String[] files = new String[]{ + "keyGen_SLH-DSA-SHA2-128s.txt", + "keyGen_SLH-DSA-SHA2-192f.txt", + "keyGen_SLH-DSA-SHAKE-192s.txt", + "keyGen_SLH-DSA-SHAKE-256f.txt", + }; + + SLHDSAParameters[] params = new SLHDSAParameters[]{ + SLHDSAParameters.sha2_128s, + SLHDSAParameters.sha2_192f, + SLHDSAParameters.shake_192s, + SLHDSAParameters.shake_256f, + }; + + TestSampler sampler = new TestSampler(); + for (int fileIndex = 0; fileIndex != files.length; fileIndex++) + { + String name = files[fileIndex]; + // System.out.println("testing: " + name); + InputStream src = TestResourceFinder.findTestResource("pqc/crypto/slhdsa/acvp", name); + BufferedReader bin = new BufferedReader(new InputStreamReader(src)); + + String line = null; + HashMap buf = new HashMap(); + while ((line = bin.readLine()) != null) + { + line = line.trim(); + + if (line.startsWith("#")) + { + continue; + } + if (line.length() == 0) + { + if (buf.size() > 0) + { + byte[] skSeed = Hex.decode((String)buf.get("skSeed")); + byte[] skPrf = Hex.decode((String)buf.get("skPrf")); + byte[] pkSeed = Hex.decode((String)buf.get("pkSeed")); + byte[] pk = Hex.decode((String)buf.get("pk")); + byte[] sk = Hex.decode((String)buf.get("sk")); + + SLHDSAParameters parameters = params[fileIndex]; + + SLHDSAKeyPairGenerator kpGen = new SLHDSAKeyPairGenerator(); + SLHDSAKeyGenerationParameters genParam = new SLHDSAKeyGenerationParameters(new SecureRandom(), parameters); + // + // Generate keys and test. + // + kpGen.init(genParam); + AsymmetricCipherKeyPair kp = kpGen.internalGenerateKeyPair(skSeed, skPrf, pkSeed); + + SLHDSAPublicKeyParameters pubParams = (SLHDSAPublicKeyParameters)PublicKeyFactory.createKey( + SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo((SLHDSAPublicKeyParameters)kp.getPublic())); + SLHDSAPrivateKeyParameters privParams = (SLHDSAPrivateKeyParameters)PrivateKeyFactory.createKey( + PrivateKeyInfoFactory.createPrivateKeyInfo((SLHDSAPrivateKeyParameters)kp.getPrivate())); + + assertTrue(name + ": public key", Arrays.areEqual(pk, pubParams.getEncoded())); + assertTrue(name + ": secret key", Arrays.areEqual(sk, privParams.getEncoded())); + + } + buf.clear(); + + continue; + } + + int a = line.indexOf("="); + if (a > -1) + { + buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); + } + } + // System.out.println("testing successful!"); + } + } + public void testSigGen() throws IOException + { + + String[] files = new String[]{ + "sigGen_SLH-DSA-SHA2-192s.txt", + "sigGen_SLH-DSA-SHA2-256f.txt", + "sigGen_SLH-DSA-SHAKE-128f.txt", + "sigGen_SLH-DSA-SHAKE-192s.txt", + "sigGen_SLH-DSA-SHAKE-256f.txt", + }; + + SLHDSAParameters[] params = new SLHDSAParameters []{ + SLHDSAParameters.sha2_192s, + SLHDSAParameters.sha2_256f, + SLHDSAParameters.shake_128f, + SLHDSAParameters.shake_192s, + SLHDSAParameters.shake_256f, + }; + + TestSampler sampler = new TestSampler(); + for (int fileIndex = 0; fileIndex != files.length; fileIndex++) + { + String name = files[fileIndex]; + // System.out.println("testing: " + name); + InputStream src = TestResourceFinder.findTestResource("pqc/crypto/slhdsa/acvp", name); + BufferedReader bin = new BufferedReader(new InputStreamReader(src)); + + String line = null; + HashMap buf = new HashMap(); + while ((line = bin.readLine()) != null) + { + line = line.trim(); + + if (line.startsWith("#")) + { + continue; + } + if (line.length() == 0) + { + if (buf.size() > 0) + { + boolean deterministic = !buf.containsKey("additionalRandomness"); + byte[] sk = Hex.decode((String)buf.get("sk")); + int messageLength = Integer.parseInt((String)buf.get("messageLength")); + byte[] message = Hex.decode((String)buf.get("message")); + byte[] signature = Hex.decode((String)buf.get("signature")); + byte[] rnd = null; + + if(!deterministic) + { + rnd = Hex.decode((String)buf.get("additionalRandomness")); + } + + SLHDSAParameters parameters = params[fileIndex]; + + SLHDSAPrivateKeyParameters privParams = new SLHDSAPrivateKeyParameters(parameters, sk); + + // sign + SLHDSASigner signer = new SLHDSASigner(); + + signer.init(true, privParams); + byte[] sigGenerated = signer.internalGenerateSignature(message, rnd); + assertTrue(Arrays.areEqual(sigGenerated, signature)); + } + buf.clear(); + + continue; + } + + int a = line.indexOf("="); + if (a > -1) + { + buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); + } + } + // System.out.println("testing successful!"); + } + } + public void testSigVer() throws IOException + { + String[] files = new String[]{ + "sigVer_SLH-DSA-SHA2-192s.txt", + "sigVer_SLH-DSA-SHA2-256f.txt", + "sigVer_SLH-DSA-SHAKE-128f.txt", + "sigVer_SLH-DSA-SHAKE-192s.txt", + "sigVer_SLH-DSA-SHAKE-256f.txt", + }; + + SLHDSAParameters[] params = new SLHDSAParameters[]{ + SLHDSAParameters.sha2_192s, + SLHDSAParameters.sha2_256f, + SLHDSAParameters.shake_128f, + SLHDSAParameters.shake_192s, + SLHDSAParameters.shake_256f, + }; + + TestSampler sampler = new TestSampler(); + for (int fileIndex = 0; fileIndex != files.length; fileIndex++) + { + String name = files[fileIndex]; + // System.out.println("testing: " + name); + InputStream src = TestResourceFinder.findTestResource("pqc/crypto/slhdsa/acvp", name); + BufferedReader bin = new BufferedReader(new InputStreamReader(src)); + + String line = null; + HashMap buf = new HashMap(); + while ((line = bin.readLine()) != null) + { + line = line.trim(); + + if (line.startsWith("#")) + { + continue; + } + if (line.length() == 0) + { + if (buf.size() > 0) + { + boolean testPassed = Boolean.parseBoolean((String)buf.get("testPassed")); + boolean deterministic = !buf.containsKey("additionalRandomness"); + String reason = buf.get("reason"); + + byte[] pk = Hex.decode((String)buf.get("pk")); + byte[] sk = Hex.decode((String)buf.get("sk")); + byte[] message = Hex.decode((String)buf.get("message")); + byte[] signature = Hex.decode((String)buf.get("signature")); + + byte[] rnd = null; + if(!deterministic) + { + rnd = Hex.decode((String)buf.get("additionalRandomness")); + } + + SLHDSAParameters parameters = params[fileIndex]; + + SLHDSAPublicKeyParameters pubParams = new SLHDSAPublicKeyParameters(parameters, pk); + SLHDSAPrivateKeyParameters privParams = new SLHDSAPrivateKeyParameters(parameters, sk); + + + SLHDSASigner verifier = new SLHDSASigner(); + verifier.init(false, pubParams); + boolean ver = verifier.internalVerifySignature(message, signature); + assertEquals("expected " + testPassed + " " + reason, ver, testPassed); + } + buf.clear(); + + continue; + } + + int a = line.indexOf("="); + if (a > -1) + { + buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); + } + } + // System.out.println("testing successful!"); + } + } +// public void testVectors() +// throws Exception +// { +// String files = +// " sha2-128f-simple.rsp sha2-192f-simple.rsp sha2-256f-simple.rsp shake-128f-simple.rsp" + +// " shake-192f-simple.rsp shake-256f-simple.rsp " + +// " sha2-128s-simple.rsp sha2-192s-simple.rsp" + +// " sha2-256s-simple.rsp shake-128s-simple.rsp shake-192s-simple.rsp shake-256s-simple.rsp"; +// +// TestSampler sampler = new TestSampler(); +// +// String[] fileList = splitOn(files, ' '); +// //long startTime = System.currentTimeMillis(); +// for (int i = 0; i != fileList.length; i++) +// { +// String name = fileList[i]; +// InputStream src = TestResourceFinder.findTestResource("pqc/crypto/slhdsa", "subset_" + name); +// BufferedReader bin = new BufferedReader(new InputStreamReader(src)); +// // System.out.println(name); +// String line = null; +// HashMap buf = new HashMap(); +// while ((line = bin.readLine()) != null) +// { +// line = line.trim(); +// +// if (line.startsWith("#")) +// { +// continue; +// } +// if (line.length() == 0) +// { +// if (buf.size() > 0) +// { +// String count = (String)buf.get("count"); +// byte[] sk = Hex.decode((String)buf.get("sk")); +// byte[] pk = Hex.decode((String)buf.get("pk")); +// byte[] msg = Hex.decode((String)buf.get("msg")); +// byte[] sigExpected = Hex.decode((String)buf.get("sm")); +// byte[] oprR = Hex.decode((String)buf.get("optrand")); +// +// if (sampler.skipTest(count)) +// { +// continue; +// } +// +// SLHDSAKeyPairGenerator kpGen = new SLHDSAKeyPairGenerator(); +// SecureRandom random = new FixedSecureRandom(sk); +// +// SLHDSAParameters parameters; +// +// String[] nameParts = splitOn(name, '-'); +// boolean sha2 = nameParts[0].equals("sha2"); +// boolean shake = nameParts[0].equals("shake"); +// boolean haraka = nameParts[0].equals("haraka"); +// int size = Integer.parseInt(nameParts[1].substring(0, 3)); +// boolean fast = nameParts[1].endsWith("f"); +// boolean slow = nameParts[1].endsWith("s"); +// boolean simple = nameParts[2].equals("simple.rsp"); +// boolean robust = nameParts[2].equals("robust.rsp"); +// if (robust) +// { +// continue; +// } +// if (haraka) +// { +// continue; +// } +// +// StringBuffer b = new StringBuffer(); +// if (sha2) +// { +// b.append("sha2"); +// } +// else if (shake) +// { +// b.append("shake"); +// } +// else +// { +// throw new IllegalArgumentException("unknown digest"); +// } +// +// b.append("_"); +// b.append(size); +// +// if (fast) +// { +// b.append("f"); +// } +// else if (slow) +// { +// b.append("s"); +// } +// else +// { +// throw new IllegalArgumentException("unknown speed"); +// } +// +// if (robust) +// { +// if (b.indexOf("haraka") < 0) +// { +// b.append("_robust"); +// } +// } +// else if (simple) +// { +// if (b.indexOf("haraka") >= 0) +// { +// b.append("_simple"); +// } +// } +// else +// { +// throw new IllegalArgumentException("unknown complexity"); +// } +// +// +// parameters = (SLHDSAParameters)SLHDSAParameters.class.getField(b.toString()).get(null); +// +// // +// // Generate keys and test. +// // +// kpGen.init(new SLHDSAKeyGenerationParameters(random, parameters)); +// AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); +// +// SLHDSAPublicKeyParameters pubParams = (SLHDSAPublicKeyParameters)kp.getPublic(); +// SLHDSAPrivateKeyParameters privParams = (SLHDSAPrivateKeyParameters)kp.getPrivate(); +// +// // FIXME No OIDs for simple variants of SPHINCS+ +// if (name.indexOf("-simple") < 0) +// { +// pubParams = (SLHDSAPublicKeyParameters)PublicKeyFactory.createKey( +// SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(pubParams)); +// privParams = (SLHDSAPrivateKeyParameters)PrivateKeyFactory.createKey( +// PrivateKeyInfoFactory.createPrivateKeyInfo(privParams)); +// } +// +//// System.err.println(Hex.toHexString(pubParams.getEncoded())); +//// System.err.println(Hex.toHexString(Arrays.concatenate(pubParams.getParameters().getEncoded(), pk))); +// assertTrue(name + " " + count + ": public key", Arrays.areEqual(pk, pubParams.getEncoded())); +// assertTrue(name + " " + count + ": secret key", Arrays.areEqual(sk, privParams.getEncoded())); +// +// // +// // Signature test +// // +// +// SLHDSASigner signer = new SLHDSASigner(); +// +// signer.init(true, new ParametersWithRandom(privParams, new FixedSecureRandom(oprR))); +// +// byte[] sigGenerated = signer.generateSignature(msg); +// byte[] attachedSig = Arrays.concatenate(sigGenerated, msg); +// +// +// signer.init(false, pubParams); +// +// assertTrue(name + " " + count + ": signature verify", signer.verifySignature(msg, Arrays.copyOfRange(sigExpected, 0, sigGenerated.length))); +// +//// System.err.println(Hex.toHexString(sigExpected)); +//// System.err.println(Hex.toHexString(attachedSig)); +// assertTrue(name + " " + count + ": signature gen match", Arrays.areEqual(sigExpected, attachedSig)); +// +// } +// buf.clear(); +// +// continue; +// } +// +// int a = line.indexOf("="); +// if (a > -1) +// { +// buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); +// } +// } +// src.close(); +// } +// //System.err.println(System.currentTimeMillis() - startTime); +// } + + + public void testBasicKeyGenerationSha2128sSimple() + { + byte[] skSeed = Hex.decode("2F896D61D9CD9038CA303394FADAA22A"); + byte[] skPrf = Hex.decode("24AC5EC1D86A989CA2196C3C8632419C"); + byte[] pkSeed = Hex.decode("1A05A42FE300E87B16AEE116CB2E2363"); + byte[] pk = Hex.decode("1A05A42FE300E87B16AEE116CB2E236358E2C3E62632C9DE03D08A535A0EB7E7"); + byte[] sk = Hex.decode("2F896D61D9CD9038CA303394FADAA22A24AC5EC1D86A989CA2196C3C8632419C1A05A42FE300E87B16AEE116CB2E236358E2C3E62632C9DE03D08A535A0EB7E7"); + + SLHDSAParameters parameters = SLHDSAParameters.sha2_128s; + + SLHDSAKeyPairGenerator kpGen = new SLHDSAKeyPairGenerator(); + SLHDSAKeyGenerationParameters genParam = new SLHDSAKeyGenerationParameters(new SecureRandom(), parameters); + // + // Generate keys and test. + // + kpGen.init(genParam); + AsymmetricCipherKeyPair kp = kpGen.internalGenerateKeyPair(skSeed, skPrf, pkSeed); + + SLHDSAPublicKeyParameters pubParams = (SLHDSAPublicKeyParameters)kp.getPublic(); + SLHDSAPrivateKeyParameters privParams = (SLHDSAPrivateKeyParameters)kp.getPrivate(); + + assertTrue("public key", Arrays.areEqual(pk, pubParams.getEncoded())); + assertTrue("secret key", Arrays.areEqual(sk, privParams.getEncoded())); + } + + public void testBasicKeyGenerationShake256128fSimpleSign() + { + byte[] sk = Hex.decode("DADB023900B157BAEDFF38B4BDE4B308C83A26A11170274E7E35CD3935AEAF07119231DA3849A12477373395D264043DA6CECC80D20A2E15A3622ABFFC221FC8"); + byte[] message = Hex.decode("3048BDE7F28C0414CC318C90048F23AFECF079866C34858521192E1684F37F0BC5D2C8585E9BF753626F6E853779D41C15BDA83DEF79DBF8A11B82EAE066833AB6C409D8AC386C942D69FF482D26A1A4030F7C082E36CFCEAA7491CB2F25BD61B79BACD91DD72C91C5D673BE48866D33E6B20F9DC83BD5639D27B0D8CA326AA1"); + byte[] signature = Hex.decode("EA52B3F889F36866D485BE712C5A7EE6FB696EFA6F5BBCB9E4FF1820FE0C580BE5786FE8A773E1AFCD353B106EECD84D65C3BF4259089B54DCC0557911FDCA8323AF0839686975D2D6AD148572D173E8D8EE8DE5E8A709D11B29E84C8ADD4E373985310F4C09F346086765B90888B94704014171AE30F65CCEE69DBC2603C0FF3D662DD0E18E0B0C69A457C5B46B3062B1A5F690EA5AA84D33C92C571D5C4156C2A96F07E66816F8453697381C93571BF7072F697152F191482CD1C73C41F2C190B59C06EFF4F4E806E832FE18F3D298F8CFBFC5E7529D3E35187289DAC000EAC6C563E456A6CFF491D90778E577476B34ECEB3193BDCEAF720E368E4D56A88634AD6FA3FA25CC09194D53AA00F9044B087727F99B4FFE61C6171CBCB424AF6DF373C58F73FF229D8DC557CBED5C6E8EF908A9DC07D2D62FFBF791B689D5356ECF67F3658A8EF845A4E8F6275B7FE44555742C2BAD4ED740D10186DE0E6CE9FC75144599F070C8F8704ECB99CA9DA9ECAC449E0170A8FD1B48DA791DE2D376CCD3C13B99FDBDE0495AAD3B4D3D6F955D51917A649262810E80467D177B29CA85FC96B93CEBC78A4E318DAA1EF00CE6D5B73BF41196CC7AA8B4D247CD1B0CA2C494DCC8591EFBFD18F5FACFC765CDA4EF6990AA7FD26696A440F992774DD952E144D3E349CDA3312E2D4A60AAE010743023AFFB20C0CAF9F4DF9697D20341B46EEB60F3C5993794E8D443C3457DA31E6F37DB4C7CCBEE86C491250AF781F81F3247CF94EE61B6EC9C493B6501AFAF2A1A41F776D4C74F2ED7F17DA149B540322D38EDF6214BF9D1575957A2ED1D0C54A20F661BA39CE2658223422A8AA5A8B6078A226C9E68C5A43674918A067A1103CAD71A9899B53B398358FD076DCA90251CC28977827FBFBBE71D9CCF0D333D95BA1F270CED5676648F5E19800622E1A0E893F9FCFE9065F216C7ED9A17F6320F866F3A95979DE3285E294987BC65D3A099E978E29C9F72ECC14020A228E587D3569D8454F3BCC8E5DBE8EA6062D4A24B1A9DCC20BB34BE1EF6C25F77E9EED6334CF6F4763CBAF5819C145D8326E558447768B7895A7F4C4CA5647A112AF1292F6F46DF796573AD3B76C2062921C252B7979119BE9309E104BAD3F643DC1433DCA48E3FF43C49B95ACC4E9941448892BB2BFC61A22F7EE5D29C9789F69612B1B3503CB324587D4CF882F40F20A46598C636D75327DD35E7132C88B91EBDD44F511E360EF6D086613F383CA4F70914E09CDFA544413A95159B3AE724FB2017F2F3ABE8AD4E64926AE797533931AF66C91DAAA46AA9AA9B331EE116EBFC57E7AF4D4466AEC4785FB72D1692E149C8EBB35140F1BD61A78495D85E5DF64EA74134E941310C59E51506408F74F1435B67701A7A76F472309A6F0B0097C8BAE4F86368CC7A93B66B8CDDF893EF10201A246D1C6E4F386FE727E27495A9735B667FFC5752818030E51250D1646AD69EC8D46628BDCF450F1165CC60211A439C8CACB48F9309FC1C992385343D821FE68BED569A972676128D338956578DF73A9186238F3FB8B1DFCC2357C3444EE25756DFC2B39135117B63D6CA4113FAD133913DB7924A7BDBD417F42D3B61BE442C451BE0B6B7BC58AB8A2A2738D1679E3B6E0F25DE923B242EADC95525D71672D527BE64BFE88956DDBAE1EE124056332AB20F8806C2F3A3F1292B099C7502CE94AEE45BFC85410CF68EF739A34565E6D337F4240C265A006CE8FE77FA10FB795155B31CBDBB22647E3F71D1EE798C3D7713652EDE11C9425E5EC06BA430A58FE95C14F08A87D0DC5E654F69A306FDA04FEE8B8162190517CAA7DDD644B6F5BD55F3670678E0CC8232F436A965EBD4FE7487E58CBD61E38DB2A31A95A9605DD40371D3D4F4C3F056E86145061B91A98F20C57EA2D38C9B332538B3E0F9C2BB204FCE003A79F09B71BF9B51D18D566C47B6A4150B974138C440DFB2F994E138A0F41F3BD3D4F2CB61A27CA36531E858968A851513946C00287C1369024AC4E3C46888EB97F7208FFB0CF0B7EE6D808AA09D7BC21300F300CCC2D75592F331A97DD69DBF3B58AFD9ACAD269C3829D8E77A4ABB0020FDD37A2CAA2BAF71584B1AD79BF8DEAE8D2ED1BFB38D04C437A83BDA779C2ECB3D2FB2DEEBBE1D6FFA1F7C524642997F482A3AE472EA925D11E7A06DEEBD272F3D16658B810124DC45DFAD77C3350901E571FE138869883716A4D1EC4A44CCA76EA6A5C1A72972751992C39A5A3EEC5C0E148FC0130C104F7B5DAC8340A88E6D371023237B64B203EB03DE0F91DA7EB0612D2C185C3F33D6678B25C39FD459DFA0B3B96D7BADFA2984B73E164AC507C898FAA55ECC3D086FA6FD28D9C93EEB053F5AF51A6A261EBF50ED3729FEEABA7178313FBD39EC1D010F4A831D088214D50262AC5975F1F34DBF791E9C72C48B6C7E9FB841579211007C336DAA46DE84954CD99E1B97CBE5CE34889ACC6861EBF2A63FB7745DAC42E0EAB5A7C7AB95B1C9D1BAB6D7AE20037988D65F973884E0816151392691405D5E52197438C39AFDA66532C7279F5B9B58B85112BF2C03A76FB54FE5EACFC5F12C3C47820E99647CDCDBBACEBC200B28B4D707EA257F37F1CE5047D2AB0E02948E1BDF126866D76EC48DD6271A2ECFB68040B31BFE6563AC34456BC66C10CEACDA74F3F92983AC1F8250B87D2D925592E3280C46A71CF16E4FEEEDBD53C240164943794F9D9471EAC03D15A5EE0DC1914A9D5C50E3D2AA165513C9BFA1560F04E06EBDE94C22E62932588A68C7A8B65223BC55B6FE75DA29874E4673AA3CA66217B1284AE0CD9C1C605556CB68156B833549146E98D76E0725A41F44B13F8249A19C169FC6F396F0152129A2C2ECC6609653644C4731E92B4AFA4516676D22A5BF0F263CB8430D40015046C41444380F80C2371E4F6EC825E19E5EB0FD2D2F07975687ED64C16684AC969D446F925689D468347DC3B96A6C5F715B8A69D60705E22ED45FF8598D3185DDAAF0F0E611A9337CA54B5C822F785E06A2BBB48ED9EBA9B39B7BB91482F27CF22781695754733278058E682D0BA140C0830902E7A12D6AE7C2FE603816DD1AF08CADB1D18C2FB3BBE22121F74898AEB1D55B04F300E8396519A41DA60259DDEB533E8EC3712B8FD07DA650E819E8EE0CB165863175E3FC70E81EF729F839769BC34727F5354395A479886B1B2D446DCB48EC2384EAEDFB9023B5C29FB8ADDB416EDF03DA9BF50CE8397DFF31EE52EAC25F482CD28C84A4B430654590BBB9401539302F23B914C62203BBB7AB7C709A08F8C707D2F9ADC49EAD6A0C6A1997F2818534248AF1FC0BFBBA33729675EDA0B0709CC1F6187EAE1F599E025966905F1D357FF7ABF118B1E7FF2186AA724869535AFA8AED869FD0F929C8AD3B73F01571C614E4CFEB80A9132F8ED8F65C67A6DF8685F1D2F457A9E40D0CDF005D7A6BF4560308A342E933B05549E40BA87E2A4559D4123C45E3238F40A91726B3018A59DE1CB116BF1B99E56FC42EA720A9276D42078F18C98BBBC2DB597B852542C8ABBB14CFCAC2E56D82BC403F321FEA9F60DF76B0FD5CC2F49AA3FF99DC46432EFD2DFE33DC6287BB140AEA5C3C582B9E4A7DA0A1FEF384A568AB86FF624086BD22CAE972580208B73AC88DE300A5792DFDB9516C113D42996DBA0A925B67774CE060D334239605F4E9F616619959568C7325AEBC8BB0CD5A60D312E130C33372760C2820192D87FC2AF2FB151FF63D2819FE51916916A13B883C478FBF6A33D1EAFEF08402F80E6E6D2F88001F96FF84E5CB81E4CB61AC804D733179175706FDD637925B6764001ADB6616A1F8D83262CDD40B505679699D85EC960E136D3D0DB3EA6FE22D38994D3ECCCC974982EC868066D98798551EB7E42825684AFB2AF7190E81BAD9F6CB426DBBBC0BE7231DCC9D3BFF065AF0BE5772FEB8A9FB1AC87AAC2EE9B0ADC2E86EF239E208D58B36DCA7A6F13B79363B5E5891A11927C5B7925F4157D28F27E59AF3F24373734EB10EC734F57624810B81E8A77C48546E8485E08274451AFB84A58F1B0F13B5DCA38DB9037F37870657E1379C26F47D4D45C80513069F0C08585F9778700F88D8EEADA57B4D3EF3DB100D889CCCD9433561F7A05FCCE05220509253C42E1710F08ECDE1AD49584B07F9A1FD17B11ED48E8900BF00FFCC1822A68336914F223DD80449DD980D74DD1BF5EA269A4725D549E249ED5604BE51F7369EE3366C65EF5F0311683CD5652583B5B9552472F1146BDD2DE068BA5D4C1702185CD34450F3B015C5952C8458C4D5345C9081CB1044B76EC63EBD725D38FAB0E111A11FC7CC130CBF3E9BC97FAE14F78BA4C97F60879660788DAE01A394372B2CFF17C93F3DA92B213C4BD00084602E7AFB11CAB263979B4CE9EAE5BB03C89EE41D546266BC371BE33E28AC3E43C52F66F823BB31DF5C97EAB4584B31D9CC2F662B78DD387811B90D3577CAB2DF90CA1AE12C20B8DFA7958C8FDA63AA6EBCF5E27492FD2219CA016ECEAE59095C9ED097BBFE985E3A6AAD24A0A8BC1D5D1E85FBB3F87944F6BC3010F39ED5062290FC826DBD5EF8592EFC084B7B45C17BE0A22792E48577D14335DD17F88BAD9D50F3B83D4373F37BDC88ED5D39FBF2B807AB33A05B229DECACA01269CDCA999AE5E5ECF4E6D18B5AE41201FEF3B83EB64358670C981F8B1D0F33930CF62F907C761103C6A5B0AB19524EF0EFC74837A1EDF14657E31929BC63DCC07EEE1581B47A790C86542EBB3D04A091C59E5636ED8CFDFBC3631819CE9915245815E2D3E127EBABECC5E4DA38F4CEA5CC9968A3D23A95970FEB49FC74C4B0C1B85BADBCA2827F55A556D6EFA23B5DE174567456984690CE9235012D13355F2CA9C43CD5E59A84400321E299D6507B90496C52D8DC48A2166B00E2726AD75090B74F288B2704C52E7A197DF10A3D4AC8292694C83DB9DA54415A98AF542C7C299572661EBF426DF387473B877CA2A71993F3F682AE25C13901B048395E66F09C69C43E3990668682EC4424497422D38E79B617F806F22B0E393007D9586D3CCA274F750E2D5ACBF5245972AC34A40787730FAF2BF004BE36AB098C5486EFD95A977A8675A9A904FE79CE8810A3D1A629BE0B51CD8ED3C72019081988FB22FC8B2311D0F91C37883378EFF1D8786846931D96EBC29CE0D2DE42EBCF20AB46CE9259C83BB86997B5E7275B8A9A5A81E65E4D6BC19D6E9C7806E2D15E5EC7BC6026295D52AC66D183099D8543CDD50FB5614BBFFD99ECAC7B5019C4D94F8EDB1BEB4343D1A22C898CF2132C897A669F255DB9884374451D4A29F0F92791D2229BC29230906120A98EF5484D55440243E1DBE547AA96BC0F578444FEB41620935E276B58A46B2A96049BCBE2AAAEC8C23578C8A0903BDFAB0EE272CBB59315E06201C3D633AB6F974E779D68AC4F35BE9C1F02624EEB780681BECD1BEC79F9480D1FEC5780DF79DB98FC392403AA4BDC47FD71DC3E76FDEBF58CD3B0472A96927F25922138C7C5DBC56CBD16744BA9FF8046BAD134AD90416263B52C3B61C3781981E35AE6E5000FC715093A34DF7C4A06987F87B4304E98222613BB5812DF652C0CFD8421B21567ADC5FDE09D3FE88AE109CFA32647680A6EEE3B5E2DA4054B61FA7ECBA7F94322514F71432BFDDD4ACB92E578BC2656AC7C0C8BCE6FD9C88144842545A6C56EF91DEE1EE62A70996CE2090F8D1665A9AE4DE52BB1E803FFFF708F551BAF664A6AB44DB8ACAF1740AF077A34EB02401286B67F31D89B17D40A1FD2CA38E197276039A64FBA2F5833108D587715ADD5285EC0914EE382042402B2C2E884873EE1DE429025683D512545047DA3AE7B36B4D1E96EE93DC1544B25A8AA7319697A653258642D22151AA37CE86D88CA85644A42457794DB0012A851194B94D58681261BF84819DD7CD3B71D85A0A407C8385A4A854610D882793C93C30526D67420B28B17E998473C3769E442D13B9B664DEC623AAD0DB5BDBB606F8E123B4B8AE037242EEAFEE8D94594761A85851AF740E3F4DAC75FD35D5FDA1B50D591BCF7C22FFB190497AF417F6A0E406EC22CCAFF1D1369F54B8193C93182A738ED6EF261779B785258F65BF093DB76190DD01C5D9A5F59BE7B1F93A34E86EB44B664F6063B7B08D53CA0B0D5CA926D449E1895D576F9955E215413456B5A02AFB7C14D56666298A2EA581576B8D275C3D02BB57D8C4FB3C71AEA31786E3948D0039DF67473A1135B94AEEAFA47FED3590AFBFE67854113D396A577C01128E91EB55028FD0C46724A6BE94F2472A37417A9DC44EBE7A5859E3FAB39AD38BD8BB5C462A0E57CEB14D3C8499B343B2ACF2AE1D003A32E99328D0689D787D4E067660A16E6A2C3022BECFC5885F85757230641AF0428006C1B2EC617DF866487022B356474959F2771C3053D9B6F56FFAEC6D970EEF014B427D5CB4F3F852BE64F8F54364DD82FFF47B13763ED931949731D6757EC1AC30C004A343EDBD6C5E48A7F311E40AC9FF9BB3DECB12F7AA5396EF949EF98275E624CB4ACEE6184D13D80A96D535B21FC59C9616E0E9E34E6858DD8DCCE39ACF505836462A255E2D58B0534BBD5B0A8BCD45226C178A70909C7A1EE44A003C733469103E6A114581250E8B823DE56FC9A08B4A54A28F572E3AAF59E6FDB3E6DBDB59553CC5B5E2E3094BDA6C8C97A58DCDE2B5AB6C1318AC6C796F31CE5CC1427F245572B730C26C993D8E3550F954869D82871DC8A3E903B7747ACC6D476EA7501D7973171DFFE8EFEA2345D7C9ED011F09BA6D2E8B992EE3D67439154699597627ACE5CB65B471F24D38673DC452E909D855C803C6923E0EC11E1F2A06C2A975C4B539FEF387AF7AF427B5A9501162EAAC8D2B55760FCD9FAAD2A4642BB42B85E7C58971B7F1DFE2B82D794DDE694C094B31717D90ACF61060B8B5F293B7CE68EC0CD2EB10FA43AEC8E604FDF3B0465A79F007D9DA481BF9590840EE0EE30D1A1687150E799459D1B8DE5A7FF92F43E0A298529797C4EBC7AB4320A87BAA208CC6E0A622AB9B67F9014F132B2D4A59E2729F218A8DBDF9147335336FB7A973A506133DEF843AD600533B325F5BF06095E49B00CFB078096E2D931F9541F18CF7F5B4AA716BF40F870AFFCC4EC2C64A073C6A7F8BE0A1969DA10173085384A484253AE426C46D42A14FDD8A0D555204A05A44845F6066715EFE2BA1C7B30CF95C60179986952DFB8094289C0977C7B737C7A1FA3945DC457EFF5961768E61D745F9CA4AB78FE5ADF254521B3149FE985D869E2AD7724D2AD9861175138E6853881A39A8EC1673849059F30A4DDAF671C537F296729ADA9CF7D86171C6C797FA6EB4D23F659BAB36D67F9FAA8505F26DE850FB97445C5670863BCFDE31F466E61ECF2FFE9E6314688F91D9F97D6641414A7908925EB4DF057E96133CB8E2C49E055E5137442A8F87AAF32E7F77034F438F1EC849A1549BF4E22155EACB038BBF3F6458EDDBEFEE5BF3D89975BF1A329B975F6E8CB9ED8020A19CFC57D527589219F4344E1619A1C85DD6E67DE3DF935E6FEE20FDC4579BD303E5D95EE5B509B58A3D6899B7397C2AF3E45D52FBFED35D8AD82B1FCC5EF76264453F64D8153994B05DA5B0AE4D428335F34AFA2C5AE108ACA9D50E78DB42D972A7C87EC8FE8BF524806232C1559596539C9416DCE518F96DF5649F7807448C53D927E0B02F880BFC9714C4C0438B95AE79645B209A2EC117387B83BC429EFDCD4BD41EDABE0E1D2B1BBA7B0932C234B3D3FE30E948684049CB197D82C035ED3A1D60579C3F9DB849A68CBC2968D7114D7F7CBF58E7E02D6C1633BBEDFC53C960E52B6136AD5620C25D2F898FE5F367B00720FD3D718EBA657666787F50CFF06725D4545C8E9C5686A57C0B6AD672088CCA2F4864951B164514082D5BBBDD3390C26206B4403BFD98365D4912751EEE910B75FAE27C4D5334B69E3C4618165CB68E45DC92F8906052FBE511EBD577B30FFFD48E1E9522D10C9D4C2B796F66363C621456A168866517E55A077833844DBFB1D6AEF0DED29BF88F9F76D22E71703F193057DE08C4A3DD711324CD6F886845E730C55E6829BCFEA1F97BF3CAE94D1552044F11ACCBACDA4A34941E012E0C67D4348B25C20474D04BBAC4B6396CA3DAAFD45D00A8905F9124DD0729BE16864A6DB768A28893F4EC57683C4A49173D0049FC915A8577DB9EABBC7172469775478A2E973F90086E363986703692BB416CBE0B422A9BD4E21DF8B105C97FA01EDF7E735A56C5928301D4EEC1C85A59A0DB6AB6886E1726B7AA4884A807230B4CA2DBB45EA7F1512AE9F53FBFAED6930D3A38F430E3115E277F41D4AA0F4DBBE84B0412C3C962C8AE43D74C07E1F35527DC8431CF67098527317A4F205FDCDD2C5B6F8462A93455310EB5C8B5E6FCFCFD4E6AFD0D4A7381B955CAFA1CE2CC87FAFD939B4C87B75EFFC1EA171EA07A275DC23327E1EB972AE3A42EEAE319595F3DEC76F097FB91EDCEEA10CE82554FA69E4D72BC5C408056018CC421DBF252905B89DAC81E4827F1EECDE696C465201CA1E7FCB6E84F645128A743552647D1E524E79EE09CC9806C027048C7BDAF7C5D033D1AF1F2F832520E4599FFFDE257E46F606B6A96D762E93CE9F29ADFD0067CBD454C170224BC19E164972A08D6BFD3EABBD92A9ACD009E13E70F194FE8E16761DDA54F7B2319335F7B11513159CC13D699A256A236431D02F19A554E24635928AEB0C06AAA03DC40C863D6D9483A6CDD22CBB79F82A78E581941D143AA02F8316B06A3526CF62BDB5B0084AFB00642DB9EF335C32D90709440631DA39AB38193EFC4A091AFE7EEE2A3AD4C7284388553B4A388B8BEE6144C1C32190F1BA3E5181B029036BA23D632C90E0662438CFB26696BFE0DE8517A77E3321818CD97F8B89C0F52646EA58A17E044BE611D7A8378083B8D5EBBA5D4DAA8114F0673FF60388FBCD98F3D302385E760073B5E30AD141504CCC9CBCB91304BF02917FD1B5B0EB68D1D85B559A26F9A585B16A0E8FED0C000272E2487D8D21332F55B5FDA26D35C34C8E702410728139FA558A79D4FB2841509890B73AF96B993D4873D0121053AA2208A22DEDFEE805C4EAB14DF41489A74E42E1B6DC4693AD13553B3993731DB74188C50CEC97C488410E6355733F17CD0F611D6EA991C69F53AA65B43EDE46447669E630F9AD8B643BE8020949554A2C04844D9CB085981FAFAEDA58402359C10CCB103C6662C6DFF41C451EDBE3DC741DC46846AAB0A3FD27D92425D41B5305ECD8D7BC8F623710A43372515BFBD02F1805F96C3492D8744DA31B00F8C4277E2F65AC664C926D6DB00ADE6DB114DBF7CD580FDC371921ACA774B284AE968836056609199F38EA68C626C07CFE19B7BA2397D863083FAFE9E81BA5E4CEAFCB4B283CD1B4982B98791AAAEF031C9FB8D65DC242050D9A133B64DB5E57C3BD8842D3ECB1B50019D3FEF411613C1D5199F2A00990A3C6AAF0A343F0F30A5AAAFA0E1DDD37CB684288DF1410112174B0B137A4B9B6026F0BE67B8ECE5A7D4344C7C333A60405978710A2F95E34FC4C2FD4ECDE5422D5392512E7B04F27D8A5BA2DA7FF837484BEC3C17E26E5DC3DC6C9D16A03141F41C1E87F358AD555E50A366FE7F6A661ECBA6405CD82744A5F658A31D88C3D73303F0541CB2014622CEC76543BB292D07A9FE683158D2D6251FAB3B6A43F7F34BADDD285EF76B2EB51E80A6BCF6ACC767695FD3E1A4F33BADCF8F09D9F205D2555BC3D4333CB16B0FDA573A390E78C05E7ECF0170204099F8E8A0DE58F9EBFF7ACBE5339C7FB01803CF1ECC3C023D6DA93DAE2C0307A7055CE5570A6A1E76D24E4313CFE81C7EECB6746544AC159241D464747502D6347D8553FC39485FD027659EFDC34AE3420C6F55F6E8A58F97703241F42EF87F9C8C3C26C46F97F50B9AD368439B2AA7EA6F92241601253E792A9F4F9869D3F66812F920C8090975398D723DFDF12075743146694C54A65EA381161C6712082E4D9107B7DC74A3AA02A3851B2285595F637CB65FC613086831A0F526FDC793F675693E225CCF3FBEE7F483E85ECD8FF9A5D290FDD24294F6A113D4070FDA80C4E05DEF2DAD2888699A6B091075D9DDF1DDE3D8E02A22651FD829582CA3B69098ED42A81BACD9AD5FE12177B52A165E72D85F4E1AE5D5A8F3337039E8CAE5FDDFEFF0247F8ED66FC8D54B05ACC5B11E4988A0C9A98FD41C34D64B3D2DEDBEF8D8435411F81DA7CD8BEEE8845417F5608B78E017800EFAFD22D38B60E133616DEBC47386D8B64A3D5D72530CA31B8B28C78FEBD37107BA9E9B15E1DCFB6B31A38BF9687C094E3C9937080DA337DC12A60CFABBEE179F8C0D19780CBE6DFC7A205F42096589E851BFADCBAAF020E569D0BD56282B5F6E1B776E66FEFCF11A29363F6A32B8E11BA54F044FFC450F24C14FA6CCB4656AD8C82B8D105B83E31EA8D5C9F0FAD6B82554EBDCECDA6D8BD7D7B6B00D28E8E4D16849490A446880D4DBE7BC709C7CF034C72F3CB1A8DCD11CDD18C1C58DF373C10F30AF7C8B3496C455A68E89223FEEDE94427EA777741C5240035F8C94633438BC020495012F414A3D61F69C4CD0184A70D199F761EA9C6CA86275C4BBB635477D420A49F516182E21ECCC927D68D3BA8C2C1BF0857426F217A5CAE3838858D80EE875FC381EEC855AD6741DF673F487A960CCF8B9522B2A85C696E63904078FE2B37D0AF5DD2FEADC37F71206AF58D3A2F5831EB78B48049A0BB69913D8F2F1BC1D1684CFFD088ABE0B87405612F98BC085FBA626C553187ED83D9758F68C4E8D122AFE832CB1BF75F4B9E5705A68A5AE91C5C78C61E4BDF607D933312AC3DF74E01D5A9E2AAFF3043AACD7EE898B2149B758CC2323CABA9A976E65DCCD56F7C39B13AEBED82AE2F93C1478AB1C649041E2DD32ECD8A8D0FBA92AF72A6A9B9749D13CF534A539311CB7E10A93F065CF4880526129F01034A962FFD20FB76245F79088B015ABABB0AE7E29A222CE2AFC046AC1EDDFE0AFA5983A4A3688ACA58D9B333493328BA4E093617ABD338954205B2D067770B91D18D64821E87D8781D52F20E096B44505E4F2823C364BEB696FCD6CF8A5F607862DF370FDBF502801984FAE20CB0AD4C2844E6E6EF5BF6DC33918810A30E10072BA5F51F933ED174E20FC1D810958A4ABEC116265C0BEF2E5888EE43CBB34D2117848BCD07C08F5D4B09CA16212741F2D43D2558F19A3019519082B4DC39F37AAA278439C3E5C44894965CB34EA5B4D16C90A4291F5114488B5643F7A906B175D3C153620DC6126210C600A0974469573B891CEB02B374B71D3BA534006F9CB891C49EDD0CE2E311FDB9DE14B770AD5FCFC85681A0B3992EC20DC7F81E61DE318EBC66DB2EDD42B2B540F91EF0689C5E02C5E5A1E0F113E435F30B61CBED530E82B9B46F8F6A28F14E6D9C0BD17B3DB9AFD2273500EDA1531D854D88981FF88EC342DE7FCEE9B7206EB34213F42FD4C254F49C90E47EE413B698CCACD02882DCB955E0C08CA4936A3BA3CC07A03A29C9D5A1C43D8FC6840C53ECB80F17F3BCEA0B298B81806B732F917CD6A6135C0DB7848F0C2BF46EFA4FE7381BBC47A32F7CF02C46B02BC11BDE7F18FDDA7AC854994C4D8FB8F6FF4F8F4EBC1B4E4FA511F6C78AA5C367B91236B92F7AE47B85A6DD7CAE2826C26D79403B29921BDDABA218BF9331188C2D6212E8BDEAD88EB9797F5916D492F098C6B24AF4022EDF6DD12306EC8B2F9FAF6979DB1D805FF54B2DC161CA3E3A1DEC12A35D65DC055941A3F76CCAD59E5593C0A69F56EC3C34461D9BE3823CA52C3808AE4A0CF5A40B8B0E99E89893794AFC7E1A020DD3B7370655265BD601ADE1EAEA97F24DA21C8CEFFE3C270888C78A03CF5288943EA38927DBF090588E59D3A44E49D70E0634D8E70BA03CE28D0B234F07F3E0C94FB4F40129B1D2261ADCF2F001BDA749AEEA9D07A156E8DF29D734D17FEA92A6A6F13AC58C927EBA415F5794F24FA5540175F74D879A2E0F38F89B660BE5BB4FAE56C7E44494C7F69804DE20F48FC51DCED12C82143CF491117B7097E3F897AF4BAE2AD3C3E8A38DF9B9569DB4D67E3C20F4FB5BAC779414384E8D91341D8A23F75E93F9B635D095E60E6E9496CADC878A3A887D22032D712517995E5FE71FF804FAFC9C74FAA7E2412192CE27B25DA96926A17B844B32BFC59D17154C1032532CEA955CCD00208CD729B78223AFAF986E8D26DD99E2D59F27C81C9DC85E613CA934EC8B996FA214F94920E3FEB5C495F5C715C11FDD97A6A4DF73D4D99E1102F0A044E27A49489B910043FAA71EF985405A110869202682284216D86A1401EE029ECF0D85E4779D744E06974D989BD562593FF6DCB8A00F73ECA411D98C0ACADFA02EFEA493A0B80F09F0A727C2BB5186B84264C6FB60C59D37660F16FC4C721CD19CB81A3ED62CC73EA382CEE9ADCDB8AAEB6C1B95F0B536161A16FB41797BABBAB6186579CB8A10F7594A2E071232632619D290B40EF5000F5606A525E5E9DDA2FDFE0E660BC17DBD2E4936468DBD52EA7DC5A05BE1979D5CE884D7B0AF950E519A5BE92552A61601DD2913E01F6BE8D3D7BA8F586D7D1362B9CE757FE2F926C09A2EFB81B3E114905B0A0A20468204806208C3424E6AD9BAA8BA3371BFBE1BEECDD061E1E0A13934410A471B4B4BCBFB41C7871801CFD3463B8EA5ED697720A54DA04ED22F9248D74E3C110095698CB564D9F3CDE75A93359F52BEFE94E0A7FAF1FAED01AF84F4302007AE04835E326DADFABAF6235A8CBE1CF41E31D6D6D7D6D360516EF9795F2E03F3911A161CE3E8EB5E9E904671F00C8A3B852A4498CBEA83D6285A4FB414D628B123C84E95DA3DAB4BE232173065771F1647390AE3C5938E955F93562A9B7AF67E2F6E8754840D1649DA13C752887F26BC68E7B30C69F5BBC66B8D43F70B4C81BF678FE83E1E893B3B0A2363A86F808C85CDBAED1733A85132BFE5E175F87B4091578B08F980077E58DE792DF9005834359139FB085FB1BF92956B3A2D76D905599AE00CD1E97599A6D2F05C722BB5F13DC581DAB6A41899D68DD7A6B315DB21B6BB890EE26C45EF980C2AAA5D75D56A0EC0B73A77EFB883F4E62A6E5E7CF58ABF11C59D76E38B4ED61619007A9DC18F21CD977D2B157AE9B22481C586801BC3F92D1493E8C501A6555648D278B12ADA547263025FA95A93B34015F04EA8B37BD39783E1B9567FF484FF5E719D42904D0299D613B93DBC8B99218626BBF52C4E4D68E4F65125A8491E59A461331E1B404F7BF879B13B70FF726BB80E7832ABA8E072F1437EC4E5CA106C6863D063FA9B7BACFFB24BD32AA6D624F30A5A2943AC7A085069137D3F62BA22962D9D9AAE00D2BBFF35F723B3EA698A2AC3692C48A4130697952EF8691CCEBE20A9EE6B33648186B45C1E9EC5D26B456B78E37E18007C14478CB46AB05176FED3B6CAA8F129E5D92A15522AE226CDD335FBBC32C4F6E40B2CA71B4ADFBA1D62BD5ED5FBBA50E0D8F4EC21D22555CA7866A9E504147A802823CADFC900AA92A6B94DCEF9A32A868446D5567F331EC8D3B9B855794134D367A1EF978CD079FB7214DABCF8F78310F7A3145FD7374D5931858970830C350686E9C4BC93432E26A86A576B526CAF28BFFEDA36A4A5B016BAC3FF4B68D09B881F4E6BE62FDDE77517FCAB64DA19339AD97BC7082F037697660D25BDA758E6B3911F830C1EAA8577445948431A0B4F055CC3EBA94C8B6B4E1178FF80FACFD5D949304D56F3ACCD35DECE845C824833BE7E3CB2403F3C74602CC90396542A0269127DFB739A318C606258D943C5DEC6B1F1CE3ACF0CD948D9F17AA2C0C3C7542ABFFA36C3CC46FA44397646C468737955B3EF20436CA9103E7D0FEBDD42133A1E0CA779E9A90C61009324B2480DA8C2ADB1D031D6A1E916F115B6125F7E6D0EC1C0DA7A18ADB8328F492E05C081FA9D423E962C1154A430196B22D155005CBB3C915B5A8909902E09BC1A7229AC7A901E032033BCF8F482D3128F1D55363234AB6840110D3F755995F428D97A4FEE849537AF2F8026489010FBAD6892561DDC452C15420AEF20998CD6FF379646AB6A2C0A0302ABB294EF252D6CD051CDDBD15514A98B576FEE4BAD5ECF207B99198ABE05563A4BE3693CA7A87C3468666FF174C55E82D8EE5266E51B6AAEDF06AEFE78CDC6DB7F2332E0749FC23E2BB08F975A63A404592F88CA0B4D988A30CBA49B323CAB8C1059DCCCBFE5422C8E68889762C1ED645891AFDD3150DFE89E13BF851008ED32F356B97CF846C86FA52D16293A6CDDEC8923D5D4E9F6CC0B311147BF18A5C612D4B318AEC20F6C4686D7930E932C758ECE9051021AAD99085758459DFED5CD9C1DB2E531B6E6265BC4463A96E56E275AB466BF5E13CA5B3470AE225AE8FB2CAD575F3753CB248DD2F06F7D22A50CF52F351138B1C08E9BFD71FDF1D576C2BE12C7C6143DEB38121E76883CB63AAA310EA3D82F5B221C3EBCEDE0EF870569FF52FDF1EAD73068DB36C1888D98AC03D085CAEF954DA724AA94DC4091BC90C014D5AD24580B8FE4B0FF16E8D21B17441B1395A15D7C18855F5778F448E0C87F83FE55282629754186BA12E6352B7BC9BD3AF81896BDD768EDA2BF8CE5FA3B265434BC56B76833386E0D1ABEB6EBE505125771D52632CE44A1B75D0069E864F806E2D94C60FDD78E518F1764E5F5CEC2F42CA796B88834B0C66C683529371D307DCFF220C27DCE8D38B94DE7EA17C80B66946F18160E5CBAC59594A8FE4542B7F06121810E3D06C468D167F93D698A5763B242B14A5B2DCA11AF7292E1D061B5C444BD34158125440314E11FCE408704F408C73D3B16D2FF57A7D4F975EC8F1C4D0709CB670FE42D075E6DAB45C00BB7C39CADDB4809BCDE731AB578A6EDC4E896D409FE3FF067DB341615B82A786516DC6CAB0AA5DD259946B40F00B865333D6AE0FAC263F32E947180942E2282A5868CC297BF0079632DBD2886795162ABDD153F1DD2F4B411BA2EC90FC968BDD73DBEAECB3FBBA04ACC9E6FD3FE9DB8654076A0450A0EE05479F82C8A82F5034D0D36D634292C6904AFC589ACF55F9A4B2837234156D9DD4E33AF4C93EC34C73F97E9AE1D6FB6386A55DA95916D8AA7461FAA2C90D512A168E19F99CF22438F0513EE97761AC759FFE5F739E2048DBA4C39E63365B1FA95904F78EF9175EAB9696316B153D1B98AE51442C05500AE2B9B6C82729D06398B39EF7A0101AD4D606E713AEC004EA270FE6519EA9472B9EC6D7FE5DCA5B34C233D12057FA7715BE8AF1C7AE4D929E1766B25928989057524898469D55A368F4B1004784382F17BA0720F56AC818C8DEAF6DF2BEBFC5BAF51B5FAE1DC77FBCFCE778E63820E029C48DF80FE6D8942874C82597750FD8BA00868E317DC40FBF6894935154C566526FA5E4BC6B2BBEA71C7494A50389A33DDCBBB890FFB878B887DA1F0F17848AD4CB0C68E95D7A4A66F22511CBFE54E2DE4D7DFC1129F4808BC155A7FD6A8011B2C43A89CDE183EC441D631A9EAD43460B2B69FA6BDD5AB32B5FDAF128567AC5BD4807F610637CFA667E375D912F26911C3B586AA2866B150EE05B93566EB4EE2E853504D18F023706D038618A341812FAE1634B70BAA33C9040BB877F4CF07BA7A49D6D96E9ABC0D1C9E8DC9F4946B008355737D7DDA12EC6C8E1A9CB45CA66DF94B61BDCD12C49E6E6BA51516D875C49911A231EEC5BE6EAEB4244359D4B7C9447964B2053658E916CD9538B21A3EA00F287A985ADC5114A0CCB15ABC46C854CEF0BCE191CB525C3C282391F2E9149636D602EBBF884E097F9BB90C5331D12DB7F0FD40CB699D89FECCDC7410C7E2B6C7AE95C119A0CDF8AF8F384BE13C23DEB2598A06B054394267D61D891C02BA6612959A0EA3D1A28F85312E379A0367C95F0E24615154227FA2500BA3548BBBA46F81A740D23944213F4F48D654C6F6AF41ECF4796515AE92CEA08D80CF2DA7C70B3413C451825E2F7B83D0EA99C3A4979688E223971D8C8B9A8F8228520B113D9F6137C0DE9CA060B3189E699E088FB8AE9FBCA602FDE791347F5E29A71D3BD5FB290EA42F5AC8F0528C65D53A0EE7EBCDB93DE18C6CF427BE8DD392AB146CC46E04028507D9F666903A836947E6F2B0206AF6E4E618F133683E977EEC6D929798A3ABF18C38E6A28FC1581DA524D5F6EA9BF7BE47AA785090979A12D4E965F40E2D3A568E768D7AC02879DF2B0B0176ECBDED2D2F3227355C125CDECDD61C91282FBB2F5B76404E8D73AE05F74B9B7B9FCAF8020AA53688FB99727A64A39292B06F4115DD64AC8BB2DD8584B4A42CFC94A13D4592180621D89855318FB9C47E7B556EC6DEFEF1D6D7A86607F2AB676BDFA8B8C03D0A892E5A9898FA94FA5B2386649EE75491414455A0FF1078320593CE6CCC8F087ED6EFD0997698852804AC62647DB4E01881453C056A91AB77439DEF983574DB19C96CD404FF23ED0D87DE78452FFBDEA9DD0648FE7A32EB3CA85122FCBC8D309E0B6AE349A56AAF04314373D870DF994D733D9137BCDF3517314E7F282A709C4CE8893C695832BE19AD83779C0622EF4E525A991E8E1F0F1FB339E6314318FCFBDE16A1EF5BFC32B51D8EC9F7071C83EEBE4E6081DC20441DA02F718976B4B5DDDAB192D6962CF92DC3F31EF59FAD3EB803CE2F875457A4496D0896DC385811540E44230EC05BF2B3E33BB88EB4BDE7D3FC7EB1F62FB54D3C642E2D1E8308A24C2324C18F27C0E00BECB195A1CBF15A32C4172D6A48DD7A72677BBC0695583E12AF7A4E6499A43904715CCEDD7761C6E999F422C88753671C355A9EDF273D3EF9149C64B5109A551476174C6EE74D1FC43C511FB5DE28CBB13FDAC58AB50DC98A9A0EC0F373BC381F5A6226DFE4C56F68063B59C7F3A36EE2EDE311A0ADBA653A51313A06C3B78C36EF0E82CEE7DBE2C68397E3A1F9DFF85E7DD89C95FF300C8951351DB52E17F3E449D2236D6687BEF754948E50845B05D033684663A432734807D594C080ADD589832CA0D6E51BBFB624A903D13B68703831238C94464F5E1C1D9720F0E56DC2358763C3191EC86C97357A4FD94CD5C0BAA6D144090DE4D37D1A89CD8BBB7B1BE9AB0F774F1024E64C46943BEDEA1B5D6403F2324158B158614C33B277D92277DF64E45F4896B5C880B91B3371F679257A0FD29B583FBCC758B77902A8A97E245B57FF05C1DEB84D17F49447958BF92202710B8F3AF33D39EE01784F6B7757D321CC8F4951231FB0A435958494B7869C5F387F3EF17807F90706D20A194C5F69C3783678B92BFBE92F52093BB2E88C04DCCBE300E78F0C8730E12A1EC5C44BFF9D1DEEA05C33DC80BE1669CD4C8E65891641258F61D390140724DE13C62B1C8660D070EA7C2BE929489D0B3260EE359E3D346745862B565CF03FA43A85B49A1D0A1A9EA43BD6D1A3F4495442504D4249195CCDD107769ACC5D73FA0299D4E0873A15596E5D01DF624BFC9C11166148C727AA2B1CD50C497E085858AD6BE8E3CBE9D11859CF70B237D90B2231D47A55485ECBBD5FF2C32F1FF8636452B1774C068C7AC5C891A671E6686B29B696CECA78A261F20CD88EB41F7E8F64EFAF7E108EBAE4EFDF02EABB7D6C0ADBDBAB27E3180EC19B95015F362DB1FE92BEB5F225D632B92006719900B7EA8C4C75DB970ADE06906C0BABCE5E1955CCABA581F96B870A5F05D4A8CCE7F620F79EFF9B7FEB471688F571D059B36B93F0C74CCF67948326B14160830F5C402108067D7B5A02C23EA2DCB4A42DA29DED563384EE91A22F364D4E49B58A08570B7C9D20F380349005968D8CBD8FE1208F124AFCE3BC0540994AA8ABB777C4F8FFC80B22FEEB888F9D089178D71F836E0253CB75A3575031A098ADA28597F597C8DF5C7C57F1654606C043C7654CD8621BA14BA09E71EAAD10FE8BA1DE3E7AC177BBB0CF48169E02FC84A4BBC4BC3DA9033C3B54AEFDC2F85B437B631E0CF2642EECAC95617F1EBBF4B5DA1CE90F4D8DC28B09A06970749A20E8248AFFB376D1F9AF7C0319C8A3C141BBFD3EB002A66F5A5869A0B8F371AFC89320A9F34F3FBE2B523D347D257B7DDA78C27479D2E297FD0D79D4DD0B59001C1D3460D7E2EEF2394A6CD98116FFE326BA575732DF12497249B3D43FAB93D145B41F2A5C557C0BB66BF9D5B50DD44CAA61EBE2C6BDDC15E1677B43F472501E8210E6DCE0292746E2AE2CD299F75CB222C39193588862332F77831943D9609857241F5722E52E55CB64AE57FD2C4DAB0A40BB23B28E8607AABFDF43328F7C91C1E205D41B0E6C9798A4F491F94E056D324A19ADEE1FEEDFFA68F49CC33AB97985CF9CC56EB88538943580338022EBD5341D4B7BA131B29B5E6A1348598F3983000D32EACF6354AC20D9E6E5FD3219AAE1B79585F9C1150DCDC97D1E42D493D167E7A31581C01CDCB237ECC1317FFF8EC02414FF29980C2943611FC5F64F0B797DFC0B3C000B0C25A28E6A1882F45892C3428196E5195EF6CF44446E921C6619A4494FE00FF96CBC83B048691D288362DFED850B01AC3B2651EEFC45EBFB741C87A98EAD95F1A3281EB20B52EFC5EF26CC38361D9F078B4DA27FF711342DF984B1F932A67819580051A6DEB3B55CFF0835C4648B8EA22B8962D22D1D5F2F72B77BB39312C0AD0381BBB81F6BF874D6A34F1FE0B01AD1D5D8BBA8EB537DBBBB14E9650A414AB0E0C7AD9526880E2127898FFD626C14E0F3DF32D111CA19133E3675DF7E8B96A6D8FB50AC32400AA6AB8148E92D4EC5FA01EB53049084AB73F0F47814738CE60400CB9F4CAA4E20427B791EB3EAF976053DA0958E10DEF7499D58A1337AC6318A3B969EFA175FD88C8F9E18BCC6C489A09B8FFF8035E8B2A4152CD464A5DF52EC0595D2A51B466DADBD444974B96075D954DA46885890DA5F182120B9F8A80F43AB072A3FDE7270E1A2050B6676139EE1110E73834AC98CC3E83964281B25526BD2D58A2BE80FB4872B4851128CF2DA8BA9464C353109194ED0CF7BDC851C06AF96E7DCA691C84FDFB86971DDCBB8E7C4CD2DD3AAB23B5D324926DA586E63DD8E830E86B2F13E054CA0A1BBE5527C233F0B5FE597659919157826D2456A1153C97B9C4B75A8EA8255609BE21FE12CBD4B71E5AB6DB9E233EB8D38139857C5F46E9C593B0E976152A6F5E8AD838028E5960A4A80B284DDFD83E9A4ABCA646DDFAA7F2D40C5DBA2B1EE5167A7D1603FCA615C2EA96AF6E3FD35F8901CF7E0DB719AEC247AE020F380B5114EA497141CB91E46F666EB3495F89F255FA2025B42FDC9A6962611D97C23EB46BDA45F2688FCCDED26AD52ECC6F0EF31AECDE9BE3B8B0CB7891B28083DB4B1640B9B9FDE964E766806554E19AF0CBF4BB81AB2E867C5B3686AD5DEFA1A7416054681F5D721BC0EB26CA87DB7BDB36FC132411EC385224FB22CF781D9E2A98C8C376FC543C87A0A052528D7C015AB320A46FC8036F8DE22AC778A9367A8157DC5C0B6D33562A01A427D1AEF7936BDF5FB44E6DCA3418FC5A3F335C784C856C6DC9FF9990C04C506E33EA2DDA0B38331A38DEF0B8DE5FC81E426736E5D1D27B5203EB8FE4FF13F037BB9C19133E1D530DF0CDF661AE7E0572F0EE8624DC00C5C75BE6E7C62F459378F9E598D6C79B825796FF90E3B900F1508583161EA030212591A60F6D12F6B0B4DBF0FFB772FFD6B79B9EDB5FB80404E7504766B8AE5E6C373D7490932F4FBBB94CAB3B30521A4E3C9FA2FF600343CFE3FC718978383A0511DE4B63BFC6037440AC11A90D0B4B8DCB30472975695BCC3BADAA4DF99D2182A76C87EE3895408BC29E528D1D970915950B1DC068000AE2519758C0C1908463D60A531B6855AFFFFFDE6DEAF67DE484C582773C542C08EC75D87A29208AD23722709D6F3BB61477FD1651E064A4CBB8EDFB5C1C2F15B31E770B99CDEE5D0EC1B4EBE79DBAFB96B8B3136C17B0211CAE9829A49EDD689FB39D986D5B5C35021EB5E36241FC3AA3C8AD0B67090C05819C2FB5AA74E6C2745E989EAFB9F64519ED4C77A3117F5ABC2C8FD5288EE3D55AD5136A6FD9D38EA12BAA4C576BB87C15AD0E238ADFA626CBAED74B40A5FC81988134B28E190E5C04977A02A9FED86BA505984A19C61BE03A49AB2AD28572A9A196611E03D21F445A6F690DC8358F5D4CEC7E42FE9BEBD071FC198F61A8F7E85349DBCA130EAF138787FFBF92844C1D8CD736760C54886B3781E8C683F54FCD7C1CA75C0567A9FDED4D64EC98AE9FABF0D41DD3094CF714F4F8D0F3CE6F1B0ED651784B18FC0BDC87AEDF24CE6B9702A3F78BE6A2CD2E5010108BCF5C7FBACAFE05D9A0407FCA1D95C6CE262CE70FE3923D35D59B29E27EF412DB81976234BA75BF5BFF81471A69839AD6D2B6CDB1470DD4A90E6798F4E464606B777C506B5B74348CE957F878D8985C24D64DE28088DEC4ED9DE68B01D7786539973AB526EAC403AEA89D2E400CDE608669B4CAA6005F56FB07D9E95FFCEDAD0FF933759D8386082B9499BB9FC10537856B51D747355637C6D29E6DFC8F223A007314F1183D7F9D0516FF4B1BF6DC9A2C6F20D7772392D83E9795B6CD82A45DE10C952D684EBAA828046437A814470044E139BF505E76CBE98C1623E15B9A28944474AD07932F057E22B3F1B2A98BE4A101D082886C4D2B757C6A62D26340662812A4C690B11AACB3F09F358815F1E977A1A24A575A76EDD235129F97917A70D26BCC2A61F5262374F647D913DDBD14C3AA1840C42AB2F562F5CE944D2CDE53F9482F5620360DAC190CB763F434548C51D9510C640927E89C461C9E7BBB0B55510BA4593F059182A7FB391E1E417413E54ED632002B5D8C05CEBB142EE6D31C88BA2B0F87E61462393EC3D568B1B6B3661FB8F610E694AB324387CBAD03AF8EB2A353042F5B97838EB1313939D319566CBD33B721559747407B7F6EB1CB60083D22AFA548A2C3843D3952905FADE717348DE4A32B8A004AF6396B1D4E1187527AB259775EB17E142C40A326474953C135799C5DA28D683F7BB328D101706862B50407A0651C21A1F07A7D79D275B3D8D46B32AAF28ABF5E92829ED713F004702C91BA035D369AA860892E54D01AFBCB86B23C01636648828A9D3C42FDF699CAA8AED7A87606FA31FAE021AA8CD6213FD331A6492A57F790F8C4D8652BC097C868A61685232C1FD00BA3230D1C19C0773C7BF9C1FA22DE0F8E036923F58403BED7E9E8CC209166C1CC53FB8D147E17E384808AF2C9E9BF91398EFBAA83BB6A40BF41D1BD8938684E804845D00B8F031D02F00717C6AC9EE7D56F3233C2CA3F096C88F13A87ECB67D406A8A99443EF8CCB1C9E1FE15A0AF367B95D89E7F71520BBF9BA4AAA530CAC03A1148D3EE7168E4E91AA9E6D12FC53C0BE2C3B9396A5A386F8ECEBC4C6C16384CF89F1E934D9FC17553638C3DB09486AC7600054A4A227C0FBE8C1D26A9347253447B9A982BC842F7D6DA56F296BECE64D2DEB4ED2F2DE79E19D44429A7EEB0B6B2C8E9CB90ADA3A569F75A74F91A0C4E5242020F03F372BCB5CCFB555BDAEFD2B34657F45FD24C9E062113C9E9D6290799EE2ABAFB9243F6EF4F548DB65B223508CA4A7C54EB81D9C49539A1BCC9589490B5421F0FACD38B8EC0F529556A292A4D608B28306DC465804DF6E8D7A7EE5BCD5561B068951F156F3C0D7015493EABD1B32B917D16FED4352DEB23F9BAAC0E3576550C347178C95BC5362E0657F80E36E5BFB4A416E4D6B8E6BEFD285B21C44C6F1EAD2DD59BE34F7AA479014BA1903732EAF7361BADFD2FA49BEB13F43D209778D5A1DF220B6029D038BB971497D89C205C25188C79D4A96ADA64B84929EEFD221B75908CFBC8D55696B0EC64BC154CFFC3361E68F0AC5918DA9B4F61D411CDC1282F64E2B6CA6FF86DB7492B18FABC2DB37F8DAD83C2B68E884A862B0F925E92FFD7937C404BFB60B16728DBD494059A4757759F452BACB4AF094B4EDC3057DCC214DD6482D44859383A5A2A878C72E60EC22BDFB07F84E735C56571F13258FE26AFB2C62014183ECCC7593B62069D129FD00EE94207BF14A18EE1CE2F736DE6C5EBA8D520EAC681156CFEBE3BED052DFCBBCB42D7A51D5C2A172E2EE3925EC94D59374BF4B0AAB6629745BDF27568F5DFF954B36FE9232BCB75A59B67D11E37BA87A6F7FF346A446C3AD3060D2CF299F05D3D52ABAFE61C1F4D1FB1B912F784ECC290CFB371F19E5D647A7A62C16D7412875B346322D30969945E6A215AB1F62D6998D1A3724D725ADB797EF5CA441F5E2BAC539D35AB3E645720105D8B565CD0CE83AEA6D60016A61141FF30938F24682A74961C9119FBBEB6C7CA95DA9163A3331B29AE63D76A22584449732FEDCA022C5A2AA87AE66F67AEAD257D4DC8F7F37881872211E97EE4A42BAD633F56E31EC3BF7C94011ECE846D804EA1AC7B3121960DC84C6A42D921A2A2DFE9FDDFA7A70F241412AAC4066747FCD008B21A9127075C256EF29658D2DBDBE8C0DF52C82B34992F8B49391DEA0A18B4DFE8CAAAD9C99CBD06FC60DD990402F2F4B07BA2FAABDC135B866E5E3BD32D3E0EB104E4A757142F43A80847FB563BB80FB84DBA2CC3BDC0393AAE483AC6A2A5E4E0CB19A1D3C8E49077045B0622F671D6E70717BF15BF4E915C7650F95CF15B524E1CA071A2A51D8801BF75A805CC04A724092E2BE55F9D8039CFB2E6D6AF800CDDBF7F8CCB9938F927086A7625D6903364A2B84F37D85BF6AD16559A3C8B187239B13030442287EC2A1AC3A0D2DA3AB0EBF37D62E00C42D98270DFC43E917A74BC201C60D94DE904F8A625D0178359EBE711556F3670806F8D07D8D05129748C28CBF4F117AD30094197527E00320D325DD4CB3C351A4BF33E5D8576B744AD59E722606D38509B395F2B6A2A03792551C1C0F9E5F26116C2D4268B1DBB750DC114787BDE9E1174D8C3F8999C4EFAF84F253D1B9AACCA6CBE1DAD25C861208180836FA572F324A899DDE228BCCADB545B644FB288717954EFF6CCD0260162101047564F6BEF5BB2843FEB8C280C5CD99C7D951052B102CEF3F136868809BC1E634DCE9F67D8CF6A6E86A0690696C3096858395CB10143579E35B81E18BA7D712E3D4A398BF14E534087142FCDD39773402D0943B97E9F8C4E214D53DC37A9D5F25DFF856BF9165C964619F278E591E67C418A6785FB9EBB5D19C67156520F5D6636B47D3F83808829AEB2A02CCFCEB0EC4B4D7DAD2A84D7028A926856CDAA9D6111BBB53EA997D023B1E019268E9D9D9BB1BBCC352D86DB733387683F383B6FF3E45357C49CF5013EDEB94A950923FFF3177B82BDFABBC6959E590020654E1A71918E14B490E18495FA6C86AE5BA8D4B148A34B5158531B4EF78BE7F8509EB008A6B1DE3C69D90BE27471D1D57272152EE892B28114A6A80BDAE2F3683C0A842D2DD12335BCD72F4C63CF89C787D4F8A676AC91E27E19E20F01CFA02274E7EEE466558974F0691BA1B17C8D8EE210CBC309595E5A6BF2E289016AC4672D320C81EC79C35E8C20A93C95F09D9FEEC643F040E044784248238E081A48DC56A5BD7F64D1875976897F058157D70BEE8DAE543FD8F354D9C8DF1F9DE9FC519039892A88F7D3833C45086CB726F979E9728F82AC196E3790F3F6B8D4F251E6934603DFCE34159EEBE64BA6D30BF1B58F213ECF55775A9FE4E17E67A4295D567DEDDEA81CD775014E4D503ACE722FF885DDE34CDA4944CF9E035586B3F2C5A00BFA26FD640CAF364D32FBBE37814F808C0D727D85DC444388BE6DD1181B952DE85D8F2EF4B147631CA55740A20FE7E4BDB5DCBB141C29D6DE17F0B67F42BF8C14F13E2B7E51234EBF26091627CB4E8F65D536CCC98A08121C770DDFEB41C08FEFDEEC559815732A586AB079D43343D8BF7706B7F86A48A6AFEF04F72DADB42FAD88FFE9A02183532758AE2309892E93F699C6C2B0AE17E7EA414BE39FCF3C9CF20275F408486815F7F47811B4561D094F10057C8D2F56C73BE80530B72E2C4F1D9C3E21E35EB5FC7FBEBD2F8C0CE722A3E010B39EFB3C62730C6C7FDCA0B310716E0B39312621147C1CE9FF21E80A8E696AA0283A6159D29B6CADDB903FAA63B0E067F87C66609D06DCCA80DEBB814AC211748D5C7C4"); + byte[] rnd = Hex.decode("934CEDC78C6F657E3BF6120E38EBB228"); + + SLHDSAParameters parameters = SLHDSAParameters.shake_128f; + + SLHDSAPrivateKeyParameters privParams = new SLHDSAPrivateKeyParameters(parameters, sk); + + // sign + SLHDSASigner signer = new SLHDSASigner(); + + signer.init(true, privParams); + byte[] sigGenerated = signer.internalGenerateSignature(message, rnd); + assertTrue(Arrays.areEqual(sigGenerated, signature)); + } + + private static String[] splitOn(String input, char c) + { + String s = input.trim(); + List l = new ArrayList(); + + int idx = s.indexOf(c); + while (idx > 0) + { + l.add(s.substring(0, idx)); + s = s.substring(idx + 1).trim(); + idx = s.indexOf(c); + } + + if (s.length() > 0) + { + l.add(s); + } + + return (String[])l.toArray(new String[0]); + } +} diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/SNTRUPrimeTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/SNTRUPrimeTest.java index 390708a0e4..f10d8dd235 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/SNTRUPrimeTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/SNTRUPrimeTest.java @@ -16,6 +16,7 @@ import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimePublicKeyParameters; import org.bouncycastle.test.TestResourceFinder; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; public class SNTRUPrimeTest @@ -40,8 +41,8 @@ public void testKEM() for (int i = 0; i != paramList.length; i++) { SNTRUPrimeParameters paramSpec = paramList[i]; - System.out.println("**** Parameter Spec - '" + paramSpec.getName().toUpperCase() + "' ****"); - InputStream resource = TestResourceFinder.findTestResource(resourcePath, paramSpec.getName().toLowerCase() + ".rsp"); + // System.out.println("**** Parameter Spec - '" + paramSpec.getName().toUpperCase() + "' ****"); + InputStream resource = TestResourceFinder.findTestResource(resourcePath, Strings.toLowerCase(paramSpec.getName()) + ".rsp"); BufferedReader resourceReader = new BufferedReader(new InputStreamReader(resource)); String line; @@ -67,7 +68,7 @@ public void testKEM() { continue; } - System.out.println("Running Test-" + count + " ..."); + // System.out.println("Running Test-" + count + " ..."); NISTSecureRandom random = new NISTSecureRandom(seed, null); SNTRUPrimeKeyPairGenerator keyPairGenerator = new SNTRUPrimeKeyPairGenerator(); @@ -75,24 +76,24 @@ public void testKEM() AsymmetricCipherKeyPair keyPair = keyPairGenerator.generateKeyPair(); assertTrue(Arrays.areEqual(pk, ((SNTRUPrimePublicKeyParameters)keyPair.getPublic()).getEncoded())); - System.out.println("- Public Key matched ..."); + // System.out.println("- Public Key matched ..."); assertTrue(Arrays.areEqual(sk, ((SNTRUPrimePrivateKeyParameters)keyPair.getPrivate()).getEncoded())); - System.out.println("- Private Key matched ..."); + // System.out.println("- Private Key matched ..."); SNTRUPrimeKEMGenerator kemGenerator = new SNTRUPrimeKEMGenerator(random); SecretWithEncapsulation secretEncapsulation = kemGenerator.generateEncapsulated(keyPair.getPublic()); assertTrue(Arrays.areEqual(ct, secretEncapsulation.getEncapsulation())); - System.out.println("- Encapsulation Cipher Text matched ..."); + // System.out.println("- Encapsulation Cipher Text matched ..."); byte[] secret = secretEncapsulation.getSecret(); assertTrue(Arrays.areEqual(ss, 0, secret.length, secret, 0, secret.length)); - System.out.println("- Encapsulation Shared Secret matched ..."); + // System.out.println("- Encapsulation Shared Secret matched ..."); SNTRUPrimeKEMExtractor kemExtractor = new SNTRUPrimeKEMExtractor((SNTRUPrimePrivateKeyParameters)keyPair.getPrivate()); byte[] decryptedSecret = kemExtractor.extractSecret(ct); assertTrue(Arrays.areEqual(ss, 0, decryptedSecret.length, decryptedSecret, 0, decryptedSecret.length)); - System.out.println("- Decapsulation Shared Secret matched ..."); + // System.out.println("- Decapsulation Shared Secret matched ..."); } resource.close(); diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/SphincsPlusTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/SphincsPlusTest.java index 4fb290d257..4ad3b88542 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/SphincsPlusTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/SphincsPlusTest.java @@ -35,14 +35,14 @@ public class SphincsPlusTest public void testVectors() throws Exception { - String files = "sha2-128f-robust.rsp sha2-192f-robust.rsp sha2-256f-robust.rsp shake-128f-robust.rsp shake-192f-robust.rsp" + - " shake-256f-robust.rsp sha2-128f-simple.rsp sha2-192f-simple.rsp sha2-256f-simple.rsp shake-128f-simple.rsp" + - " shake-192f-simple.rsp shake-256f-simple.rsp sha2-128s-robust.rsp sha2-192s-robust.rsp sha2-256s-robust.rsp" + - " shake-128s-robust.rsp shake-192s-robust.rsp shake-256s-robust.rsp sha2-128s-simple.rsp sha2-192s-simple.rsp" + + String files = + " sha2-128f-simple.rsp sha2-192f-simple.rsp sha2-256f-simple.rsp shake-128f-simple.rsp" + + " shake-192f-simple.rsp shake-256f-simple.rsp " + + " sha2-128s-simple.rsp sha2-192s-simple.rsp" + " sha2-256s-simple.rsp shake-128s-simple.rsp shake-192s-simple.rsp shake-256s-simple.rsp" + - " haraka-128f-robust.rsp haraka-192s-robust.rsp haraka-128f-simple.rsp haraka-192s-simple.rsp" + - " haraka-128s-robust.rsp haraka-256f-robust.rsp haraka-128s-simple.rsp haraka-256f-simple.rsp" + - " haraka-192f-robust.rsp haraka-256s-robust.rsp haraka-192f-simple.rsp haraka-256s-simple.rsp"; + " haraka-128f-simple.rsp haraka-192s-simple.rsp" + + " haraka-128s-simple.rsp haraka-256f-simple.rsp" + + " haraka-192f-simple.rsp haraka-256s-simple.rsp"; TestSampler sampler = new TestSampler(); @@ -53,7 +53,7 @@ public void testVectors() String name = fileList[i]; InputStream src = TestResourceFinder.findTestResource("pqc/crypto/sphincs_plus", "subset_" + name); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); - System.out.println(name); + // System.out.println(name); String line = null; HashMap buf = new HashMap(); while ((line = bin.readLine()) != null) @@ -131,11 +131,17 @@ else if (slow) if (robust) { - // nothing. + if (b.indexOf("haraka") < 0) + { + b.append("_robust"); + } } else if (simple) { - b.append("_simple"); + if (b.indexOf("haraka") >= 0) + { + b.append("_simple"); + } } else { @@ -154,10 +160,19 @@ else if (simple) SPHINCSPlusPublicKeyParameters pubParams = (SPHINCSPlusPublicKeyParameters)kp.getPublic(); SPHINCSPlusPrivateKeyParameters privParams = (SPHINCSPlusPrivateKeyParameters)kp.getPrivate(); + // FIXME No OIDs for simple variants of SPHINCS+ + if (name.indexOf("-simple") < 0) + { + pubParams = (SPHINCSPlusPublicKeyParameters)PublicKeyFactory.createKey( + SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(pubParams)); + privParams = (SPHINCSPlusPrivateKeyParameters)PrivateKeyFactory.createKey( + PrivateKeyInfoFactory.createPrivateKeyInfo(privParams)); + } + // System.err.println(Hex.toHexString(pubParams.getEncoded())); // System.err.println(Hex.toHexString(Arrays.concatenate(pubParams.getParameters().getEncoded(), pk))); - assertTrue(name + " " + count + ": public key", Arrays.areEqual(Arrays.concatenate(pubParams.getParameters().getEncoded(), pk), pubParams.getEncoded())); - assertTrue(name + " " + count + ": secret key", Arrays.areEqual(Arrays.concatenate(privParams.getParameters().getEncoded(), sk), privParams.getEncoded())); + assertTrue(name + " " + count + ": public key", Arrays.areEqual(pk, pubParams.getEncoded())); + assertTrue(name + " " + count + ": secret key", Arrays.areEqual(sk, privParams.getEncoded())); // // Signature test @@ -202,15 +217,15 @@ public void testBasicKeyGeneration() SPHINCSPlusKeyPairGenerator kpGen = new SPHINCSPlusKeyPairGenerator(); SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4792F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFD45542B7F6AF778742E0F4479175084AA488B3B74340678AAD111491E7E52F6F1D726DAF2A4E75CAFB60D034B6E912B26BE68464B0095D60D")); - kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_256f)); + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_256f_robust)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); SPHINCSPlusPublicKeyParameters pubParams = (SPHINCSPlusPublicKeyParameters)kp.getPublic(); SPHINCSPlusPrivateKeyParameters privParams = (SPHINCSPlusPrivateKeyParameters)kp.getPrivate(); - assertTrue(Arrays.areEqual(Arrays.concatenate(pubParams.getParameters().getEncoded(), Hex.decode("3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5")), pubParams.getEncoded())); - assertTrue(Arrays.areEqual(Arrays.concatenate(privParams.getParameters().getEncoded(), Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4792f267aafa3f87ca60d01cb54f29202a3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5")), privParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5"), pubParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4792f267aafa3f87ca60d01cb54f29202a3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5"), privParams.getEncoded())); SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(pubParams); PrivateKeyInfo privInfo = PrivateKeyInfoFactory.createPrivateKeyInfo(privParams); @@ -218,17 +233,17 @@ public void testBasicKeyGeneration() pubParams = (SPHINCSPlusPublicKeyParameters)PublicKeyFactory.createKey(pubInfo.getEncoded()); privParams = (SPHINCSPlusPrivateKeyParameters)PrivateKeyFactory.createKey(privInfo.getEncoded()); - assertTrue(Arrays.areEqual(Arrays.concatenate(pubParams.getParameters().getEncoded(), Hex.decode("3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5")), pubParams.getEncoded())); - assertTrue(Arrays.areEqual(Arrays.concatenate(privParams.getParameters().getEncoded(), Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4792f267aafa3f87ca60d01cb54f29202a3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5")), privParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5"), pubParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4792f267aafa3f87ca60d01cb54f29202a3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5"), privParams.getEncoded())); } public void testBasicKeyImportSimpleSign() { - SPHINCSPlusPublicKeyParameters pubParams = new SPHINCSPlusPublicKeyParameters(SPHINCSPlusParameters.sha2_128f, Hex.decode("b505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8")); - SPHINCSPlusPrivateKeyParameters privParams = new SPHINCSPlusPrivateKeyParameters(SPHINCSPlusParameters.sha2_128f, Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8")); + SPHINCSPlusPublicKeyParameters pubParams = new SPHINCSPlusPublicKeyParameters(SPHINCSPlusParameters.sha2_128f_robust, Hex.decode("b505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8")); + SPHINCSPlusPrivateKeyParameters privParams = new SPHINCSPlusPrivateKeyParameters(SPHINCSPlusParameters.sha2_128f_robust, Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8")); - assertTrue(Arrays.areEqual(Arrays.concatenate(pubParams.getParameters().getEncoded(), Hex.decode("b505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8")), pubParams.getEncoded())); - assertTrue(Arrays.areEqual(Arrays.concatenate(privParams.getParameters().getEncoded(), Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8")), privParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("b505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8"), pubParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8"), privParams.getEncoded())); byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); @@ -253,7 +268,7 @@ public void testBasicSignature() SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3" + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")); - kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.sha2_128f)); + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.sha2_128f_robust)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); @@ -284,7 +299,7 @@ public void testDeterministicSignature() SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3" + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")); - kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.sha2_128f)); + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.sha2_128f_robust)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); @@ -316,15 +331,15 @@ public void testBasicKeyGenerationShake256128fSimple() SecureRandom random = new FixedSecureRandom(Hex.decode( "7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4766BA69D8560A9F84846AD8B765390C84")); - kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_128f_simple)); + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_128f)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); SPHINCSPlusPublicKeyParameters pubParams = (SPHINCSPlusPublicKeyParameters)kp.getPublic(); SPHINCSPlusPrivateKeyParameters privParams = (SPHINCSPlusPrivateKeyParameters)kp.getPrivate(); - assertTrue(Arrays.areEqual(Arrays.concatenate(pubParams.getParameters().getEncoded(), Hex.decode("b505d7cfad1b497499323c8686325e47afbc007ba1e2b4a138f03aa9a6195ac8")), pubParams.getEncoded())); - assertTrue(Arrays.areEqual(Arrays.concatenate(privParams.getParameters().getEncoded(), Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e47afbc007ba1e2b4a138f03aa9a6195ac8")), privParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("b505d7cfad1b497499323c8686325e47afbc007ba1e2b4a138f03aa9a6195ac8"), pubParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e47afbc007ba1e2b4a138f03aa9a6195ac8"), privParams.getEncoded())); } public void testBasicKeyGenerationShake256128fSimpleSign() @@ -334,7 +349,7 @@ public void testBasicKeyGenerationShake256128fSimpleSign() SecureRandom random = new FixedSecureRandom(Hex.decode( "7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4766BA69D8560A9F84846AD8B765390C84")); - kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_128f_simple)); + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_128f)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); @@ -366,15 +381,15 @@ public void testBasicKeyGenerationShake256128fRobust() SecureRandom random = new FixedSecureRandom(Hex.decode( "7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E47354D75735F16E03DEC94D1F5B00C213D")); - kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_128f)); + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_128f_robust)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); SPHINCSPlusPublicKeyParameters pubParams = (SPHINCSPlusPublicKeyParameters)kp.getPublic(); SPHINCSPlusPrivateKeyParameters privParams = (SPHINCSPlusPrivateKeyParameters)kp.getPrivate(); - assertTrue(Arrays.areEqual(Arrays.concatenate(pubParams.getParameters().getEncoded(), Hex.decode("b505d7cfad1b497499323c8686325e4714be46e5b92237d09a0ea8a0404033a6")), pubParams.getEncoded())); - assertTrue(Arrays.areEqual(Arrays.concatenate(privParams.getParameters().getEncoded(), Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4714be46e5b92237d09a0ea8a0404033a6")), privParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("b505d7cfad1b497499323c8686325e4714be46e5b92237d09a0ea8a0404033a6"), pubParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4714be46e5b92237d09a0ea8a0404033a6"), privParams.getEncoded())); } public void testBasicKeyGenerationShake256128fRobustSign() @@ -384,7 +399,7 @@ public void testBasicKeyGenerationShake256128fRobustSign() SecureRandom random = new FixedSecureRandom(Hex.decode( "7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E47354D75735F16E03DEC94D1F5B00C213D")); - kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_128f)); + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_128f_robust)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/XMSSMTPrivateKeyTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/XMSSMTPrivateKeyTest.java index b9fe45f4be..c426801035 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/XMSSMTPrivateKeyTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/XMSSMTPrivateKeyTest.java @@ -12,6 +12,7 @@ import org.bouncycastle.pqc.crypto.xmss.XMSSParameters; import org.bouncycastle.pqc.crypto.xmss.XMSSPrivateKeyParameters; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Base64; /** @@ -27,11 +28,8 @@ public void testPrivateKeySerialisation() XMSSParameters params = new XMSSParameters(10, new SHA256Digest()); - byte[] output = Base64.decode(new String(stream).getBytes("UTF-8")); - - + byte[] output = Base64.decode(Strings.toUTF8ByteArray(stream)); //Simple Exploit - try { new XMSSPrivateKeyParameters.Builder(params).withPrivateKey(output).build(); diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/XWingTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/XWingTest.java new file mode 100644 index 0000000000..8568691939 --- /dev/null +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/XWingTest.java @@ -0,0 +1,85 @@ +package org.bouncycastle.pqc.crypto.test; + +import junit.framework.TestCase; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.pqc.crypto.xwing.XWingKEMExtractor; +import org.bouncycastle.pqc.crypto.xwing.XWingKEMGenerator; +import org.bouncycastle.pqc.crypto.xwing.XWingKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.xwing.XWingKeyPairGenerator; +import org.bouncycastle.pqc.crypto.xwing.XWingPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.xwing.XWingPublicKeyParameters; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.FixedSecureRandom; + +public class XWingTest + extends TestCase +{ + public void testKEM() + throws Exception + { + String temp = "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"; + String expectedSecret = "81b50581e5f7390675d542802e84f717fa3b87b5391217869e00eb54ba679a00"; + + byte[] seed = Hex.decode(temp); + + NISTSecureRandom random = new NISTSecureRandom(seed, null); + + byte[] coins = new byte[96]; + random.nextBytes(coins); + + XWingKeyPairGenerator keyGen = new XWingKeyPairGenerator(); + + keyGen.init(new XWingKeyGenerationParameters(new FixedSecureRandom(coins))); + + AsymmetricCipherKeyPair keyPair = keyGen.generateKeyPair(); + + XWingKEMGenerator kemGen = new XWingKEMGenerator(random); + + SecretWithEncapsulation secretEncap = kemGen.generateEncapsulated(keyPair.getPublic()); + + byte[] sharedSecret = secretEncap.getSecret(); + + assertTrue(Arrays.areEqual(Hex.decode(expectedSecret), sharedSecret)); + + XWingKEMExtractor kemExtract = new XWingKEMExtractor((XWingPrivateKeyParameters)keyPair.getPrivate()); + + byte[] decryptedSharedSecret = kemExtract.extractSecret(secretEncap.getEncapsulation()); + + assertTrue(Arrays.areEqual(Hex.decode(expectedSecret), decryptedSharedSecret)); + } + + public void testKeyEncoding() + throws Exception + { + byte[] pubEnc = Hex.decode("a72c2d9c843ee9f8313ecc7f86d6294d59159d9a879a542e260922adf999051cc45200c9ffdb60449c49465979272367c083a7d6267a3ed7a7fd47957c219327f7ca73a4007e1627f00b11cc80573c15aee6640fb8562dfa6b240ca0ad351ac4ac155b96c14c8ab13dd262cdfd51c4bb5572fd616553d17bdd430acbea3e95f0b698d66990ab51e5d03783a8b3d278a5720454cf9695cfdca08485ba099c51cd92a7ea7587c1d15c28e609a81852601b0604010679aa482d51261ec36e36b8719676217fd74c54786488f4b4969c05a8ba27ca3a77cce73b965923ca554e422b9b61f4754641608ac16c9b8587a32c1c5dd788f88b36b717a46965635deb67f45b129b99070909c93eb80b42c2b3f3f70343a7cf37e8520e7bcfc416aca4f18c7981262ba2bfc756ae03278f0ec66dc2057696824ba6769865a601d7148ef6f54e5af5686aa2906f994ce38a5e0b938f239007003022c03392df3401b1e4a3a7ebc6161449f73374c8b0140369343d9295fdf511845c4a46ebaab6ca5492f6800b98c0cc803653a4b1d6e6aaed1932bacc5fefaa818ba502859ba5494c5f5402c8536a9c4c1888150617f80098f6b2a99c39bc5dc7cf3b5900a21329ab59053abaa64ed163e859a8b3b3ca3359b750ccc3e710c7ac43c8191cb5d68870c06391c0cb8aec72b897ac6be7fbaacc676ed66314c83630e89448c88a1df04aceb23abf2e409ef333c622289c18a2134e650c45257e47475fa33aa537a5a8f7680214716c50d470e3284963ca64f54677aec54b5272162bf52bc8142e1d4183fc017454a6b5a496831759064024745978cbd51a6cedc8955de4cc6d363670a47466e82be5c23603a17bf22acdb7cc984af08c87e14e27753cf587a8ec3447e62c649e887a67c36c9ce98721b697213275646b194f36758673a8ed11284455afc7a8529f69c97a3c2d7b8c636c0ba55614b768e624e712930f776169b01715725351bc74b47395ed52b25a1313c95164814c34c979cbdfab85954662cab485e75087a98cc74bb82ca2d1b5bf2803238480638c40e90b43c7460e7aa917f010151fab1169987b372abb59271f7006c24e60236b84b9ddd600623704254617fb498d89e58b0368bcb2103e79353eb587860c1422e476162e425bc2381db82c6592737e1dd602864b0167a71ec1f223305c02fe25052af2b3b5a55a0d7a2022d9a798dc0c5874a98702aaf4054c5d80338a5248b5b7bd09c53b5e2a084b047d277a861b1a73bb51488de04ef573c85230a0470b73175c9fa50594f66a5f50b4150054c93b68186f8b5cbc49316c8548a642b2b36a1d454c7489ac33b2d2ce6668096782a2c1e0866d21a65e16b585e7af8618bdf3184c1986878508917277b93e10706b1614972b2a94c7310fe9c708c231a1a8ac8d9314a529a97f469bf64962d820648443099a076d55d4cea824a58304844f99497c10a25148618a315d72ca857d1b04d575b94f85c01d19bef211bf0aa3362e7041fd16596d808e867b44c4c00d1cda3418967717f147d0eb21b42aaee74ac35d0b92414b958531aadf463ec6305ae5ecaf79174002f26ddecc813bf32672e8529d95a4e730a7ab4a3e8f8a8af979a665eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b539227001e4f285d5113a537f141fa23cb2770845ac28fc9d70df557415f3bc00e735"); + byte[] privEnc = Hex.decode("07638fb69868f3d320e5862bd96933feb311b362093c9b5d50170bced43f1b536d9a204bb1f22695950ba1f2a9e8eb828b284488760b3fc84faba04275d5628e39c5b2471374283c503299c0ab49b66b8bbb56a4186624f919a2ba59bb08d8551880c2befc4f87f25f59ab587a79c327d792d54c974a69262ff8a78938289e9a87b688b083e0595fe218b6bb1505941ce2e81a5a64c5aac60417256985349ee47a52420a5f97477b7236ac76bc70e8288729287ee3e34a3dbc3683c0b7b10029fc203418537e7466ba6385a8ff301ee12708f82aaa1e380fc7a88f8f205ab7e88d7e95952a55ba20d09b79a47141d62bf6eb7dd307b08eca13a5bc5f6b68581c6865b27bbcddab142f4b2cbff488c8a22705faa98a2b9eea3530c76662335cc7ea3a00777725ebcccd2a4636b2d9122ff3ab77123ce0883c1911115e50c9e8a94194e48dd0d09cffb3adcd2c1e92430903d07adbf00532031575aa7f9e7b5a1f3362dec936d4043c05f2476c07578bc9cbaf2ab4e382727ad41686a96b2548820bb03b32f11b2811ad62f489e951632aba0d1df89680cc8a8b53b481d92a68d70b4ea1c3a6a561c0692882b5ca8cc942a8d495afcb06de89498fb935b775908fe7a03e324d54cc19d4e1aabd3593b38b19ee1388fe492b43127e5a504253786a0d69ad32601c28e2c88504a5ba599706023a61363e17c6b9bb59bdc697452cd059451983d738ca3fd034e3f5988854ca05031db09611498988197c6b30d258dfe26265541c89a4b31d6864e9389b03cb74f7ec4323fb9421a4b9790a26d17b0398a26767350909f84d57b6694df830664ca8b3c3c03ed2ae67b89006868a68527ccd666459ab7f056671000c6164d3a7f266a14d97cbd7004d6c92caca770b844a4fa9b182e7b18ca885082ac5646fcb4a14e1685feb0c9ce3372ab95365c04fd83084f80a23ff10a05bf15f7fa5acc6c0cb462c33ca524fa6b8bb359043ba68609eaa2536e81d08463b19653b5435ba946c9addeb202b04b031cc960dcc12e4518d428b32b257a4fc7313d3a7980d80082e934f9d95c32b0a0191a23604384dd9e079bbbaa266d14c3f756b9f2133107433a4e83fa7187282a809203a4faf841851833d121ac383843a5e55bc2381425e16c7db4cc9ab5c1b0d91a47e2b8de0e582c86b6b0d907bb360b97f40ab5d038f6b75c814b27d9b968d419832bc8c2bee605ef6e5059d33100d90485d378450014221736c07407cac260408aa64926619788b8601c2a752d1a6cbf820d7c7a04716203225b3895b9342d147a8185cfc1bb65ba06b4142339903c0ac4651385b45d98a8b19d28cd6bab088787f7ee1b12461766b43cbccb96434427d93c065550688f6948ed1b5475a425f1b85209d061c08b56c1cc069f6c0a7c6f29358cab911087732a649d27c9b98f9a48879387d9b00c25959a71654d6f6a946164513e47a75d005986c2363c09f6b537eca78b9303a5fa457608a586a653a347db04dfcc19175b3a301172536062a658a95277570c8852ca8973f4ae123a334047dd711c8927a634a03388a527b034bf7a8170fa702c1f7c23ec32d18a2374890be9c787a9409c82d192c4bb705a2f996ce405da72c2d9c843ee9f8313ecc7f86d6294d59159d9a879a542e260922adf999051cc45200c9ffdb60449c49465979272367c083a7d6267a3ed7a7fd47957c219327f7ca73a4007e1627f00b11cc80573c15aee6640fb8562dfa6b240ca0ad351ac4ac155b96c14c8ab13dd262cdfd51c4bb5572fd616553d17bdd430acbea3e95f0b698d66990ab51e5d03783a8b3d278a5720454cf9695cfdca08485ba099c51cd92a7ea7587c1d15c28e609a81852601b0604010679aa482d51261ec36e36b8719676217fd74c54786488f4b4969c05a8ba27ca3a77cce73b965923ca554e422b9b61f4754641608ac16c9b8587a32c1c5dd788f88b36b717a46965635deb67f45b129b99070909c93eb80b42c2b3f3f70343a7cf37e8520e7bcfc416aca4f18c7981262ba2bfc756ae03278f0ec66dc2057696824ba6769865a601d7148ef6f54e5af5686aa2906f994ce38a5e0b938f239007003022c03392df3401b1e4a3a7ebc6161449f73374c8b0140369343d9295fdf511845c4a46ebaab6ca5492f6800b98c0cc803653a4b1d6e6aaed1932bacc5fefaa818ba502859ba5494c5f5402c8536a9c4c1888150617f80098f6b2a99c39bc5dc7cf3b5900a21329ab59053abaa64ed163e859a8b3b3ca3359b750ccc3e710c7ac43c8191cb5d68870c06391c0cb8aec72b897ac6be7fbaacc676ed66314c83630e89448c88a1df04aceb23abf2e409ef333c622289c18a2134e650c45257e47475fa33aa537a5a8f7680214716c50d470e3284963ca64f54677aec54b5272162bf52bc8142e1d4183fc017454a6b5a496831759064024745978cbd51a6cedc8955de4cc6d363670a47466e82be5c23603a17bf22acdb7cc984af08c87e14e27753cf587a8ec3447e62c649e887a67c36c9ce98721b697213275646b194f36758673a8ed11284455afc7a8529f69c97a3c2d7b8c636c0ba55614b768e624e712930f776169b01715725351bc74b47395ed52b25a1313c95164814c34c979cbdfab85954662cab485e75087a98cc74bb82ca2d1b5bf2803238480638c40e90b43c7460e7aa917f010151fab1169987b372abb59271f7006c24e60236b84b9ddd600623704254617fb498d89e58b0368bcb2103e79353eb587860c1422e476162e425bc2381db82c6592737e1dd602864b0167a71ec1f223305c02fe25052af2b3b5a55a0d7a2022d9a798dc0c5874a98702aaf4054c5d80338a5248b5b7bd09c53b5e2a084b047d277a861b1a73bb51488de04ef573c85230a0470b73175c9fa50594f66a5f50b4150054c93b68186f8b5cbc49316c8548a642b2b36a1d454c7489ac33b2d2ce6668096782a2c1e0866d21a65e16b585e7af8618bdf3184c1986878508917277b93e10706b1614972b2a94c7310fe9c708c231a1a8ac8d9314a529a97f469bf64962d820648443099a076d55d4cea824a58304844f99497c10a25148618a315d72ca857d1b04d575b94f85c01d19bef211bf0aa3362e7041fd16596d808e867b44c4c00d1cda3418967717f147d0eb21b42aaee74ac35d0b92414b958531aadf463ec6305ae5ecaf79174002f26ddecc813bf32672e8529d95a4e730a7ab4a3e8f8a8af979a665eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b53922d4ec143b50f01423b177895edee22bb739f647ecf85f50bc25ef7b5a725dee86b505d7cfad1b497499323c8686325e4792f267aafa3f87ca60d01cb54f29202a38784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b743406786a"); + String temp = "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"; + String expectedSecret = "e5015e7e9b71e3a0436b159a042b14cb5b63435eee3b8db95f1e8fcce44632a8"; + + byte[] seed = Hex.decode(temp); + + NISTSecureRandom random = new NISTSecureRandom(seed, null); + + byte[] coins = new byte[96]; + random.nextBytes(coins); + + XWingPublicKeyParameters publicKey = new XWingPublicKeyParameters(pubEnc); + XWingPrivateKeyParameters privKey = new XWingPrivateKeyParameters(privEnc); + + XWingKEMGenerator kemGen = new XWingKEMGenerator(random); + + SecretWithEncapsulation secretEncap = kemGen.generateEncapsulated(publicKey); + + byte[] sharedSecret = secretEncap.getSecret(); + + assertTrue(Arrays.areEqual(Hex.decode(expectedSecret), sharedSecret)); + + XWingKEMExtractor kemExtract = new XWingKEMExtractor(privKey); + + byte[] decryptedSharedSecret = kemExtract.extractSecret(secretEncap.getEncapsulation()); + + assertTrue(Arrays.areEqual(Hex.decode(expectedSecret), decryptedSharedSecret)); + } +} diff --git a/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McElieceCipherTest.java b/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McElieceCipherTest.java index b3791ef63c..d86e9ce266 100644 --- a/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McElieceCipherTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McElieceCipherTest.java @@ -55,7 +55,7 @@ public void performTest() for (int k = 1; k <= numPassesEncDec; k++) { - System.out.println("############### test: " + k); + // System.out.println("############### test: " + k); // initialize for encryption mcEliecePKCSDigestCipher.init(true, param); @@ -88,8 +88,8 @@ public void performTest() } else { - System.out.println("test okay"); - System.out.println(); + // System.out.println("test okay"); + // System.out.println(); } } diff --git a/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McElieceFujisakiCipherTest.java b/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McElieceFujisakiCipherTest.java index 5d2349158d..b2ad2f8e7d 100644 --- a/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McElieceFujisakiCipherTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McElieceFujisakiCipherTest.java @@ -50,7 +50,7 @@ public void performTest() for (int k = 1; k <= numPassesEncDec; k++) { - System.out.println("############### test: " + k); + // System.out.println("############### test: " + k); // initialize for encryption mcElieceFujisakiDigestCipher.init(true, param); @@ -85,8 +85,8 @@ public void performTest() } else { - System.out.println("test okay"); - System.out.println(); + // System.out.println("test okay"); + // System.out.println(); } } diff --git a/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McElieceKobaraImaiCipherTest.java b/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McElieceKobaraImaiCipherTest.java index a09892d76f..35ffc0ecf2 100644 --- a/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McElieceKobaraImaiCipherTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McElieceKobaraImaiCipherTest.java @@ -107,7 +107,7 @@ public void performTest() for (int k = 1; k <= numPassesEncDec; k++) { - System.out.println("############### test: " + k); + // System.out.println("############### test: " + k); // initialize for encryption mcElieceKobaraImaiDigestCipher.init(true, param); @@ -141,8 +141,8 @@ public void performTest() } else { - System.out.println("test okay"); - System.out.println(); + // System.out.println("test okay"); + // System.out.println(); } } diff --git a/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McEliecePointchevalCipherTest.java b/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McEliecePointchevalCipherTest.java index 2571ffdf8a..fd4c2a4956 100644 --- a/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McEliecePointchevalCipherTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/legacy/crypto/test/McEliecePointchevalCipherTest.java @@ -48,7 +48,7 @@ public void performTest() for (int k = 1; k <= numPassesEncDec; k++) { - System.out.println("############### test: " + k); + // System.out.println("############### test: " + k); // initialize for encryption mcEliecePointchevalDigestCipher.init(true, param); @@ -82,8 +82,8 @@ public void performTest() } else { - System.out.println("test okay"); - System.out.println(); + // System.out.println("test okay"); + // System.out.println(); } } diff --git a/core/src/test/java/org/bouncycastle/util/io/pem/test/AllTests.java b/core/src/test/java/org/bouncycastle/util/io/pem/test/AllTests.java index 323441b5b5..e1916cc1e4 100644 --- a/core/src/test/java/org/bouncycastle/util/io/pem/test/AllTests.java +++ b/core/src/test/java/org/bouncycastle/util/io/pem/test/AllTests.java @@ -12,14 +12,37 @@ import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.test.PrintTestResult; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.io.pem.PemHeader; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemReader; import org.bouncycastle.util.io.pem.PemWriter; +import static org.bouncycastle.util.io.pem.PemReader.LAX_PEM_PARSING_SYSTEM_PROPERTY_NAME; + public class AllTests extends TestCase { + private static final String blob1 = + "-----BEGIN BLOB-----\r\n" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\r\n" + + "-----END BLOB-----\r\n"; + + private static final String blob2 = + "-----BEGIN BLOB----- \r\n" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\r\n" + + "-----END BLOB----- \r\n"; + + private static final String blob3 = + " -----BEGIN BLOB-----\r\n" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\r\n" + + "-----END BLOB-----\r\n"; + + private static final String blob4 = + "-----BEGIN BLOB-----\r\n" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\r\n" + + " -----END BLOB-----\r\n"; + public void testPemLength() throws IOException { @@ -54,6 +77,81 @@ public void testMalformed() assertNull(rd.readPemObject()); } + public void testRegularBlob() + throws IOException + { + PemReader rd = new PemReader(new StringReader(blob1)); + + PemObject obj = rd.readPemObject(); + + assertEquals("BLOB", obj.getType()); + assertTrue(Arrays.areEqual(new byte[64], obj.getContent())); + } + + public void testRegularBlobTrailing() + throws IOException + { + PemReader rd = new PemReader(new StringReader(blob2)); + + PemObject obj = rd.readPemObject(); + + assertEquals("BLOB", obj.getType()); + assertTrue(Arrays.areEqual(new byte[64], obj.getContent())); + } + + public void testRegularBlobBeginFault() + throws IOException + { + PemReader rd = new PemReader(new StringReader(blob3)); + + PemObject obj = rd.readPemObject(); + + assertNull(rd.readPemObject()); + } + + public void testRegularBlobEndFault() + throws IOException + { + PemReader rd = new PemReader(new StringReader(blob4)); + + try + { + PemObject obj = rd.readPemObject(); + } + catch (IOException e) + { + assertEquals("-----END BLOB----- not found", e.getMessage()); + } + } + + public void testRegularBlobEndLaxParsing() + throws IOException + { + String original = System.setProperty(LAX_PEM_PARSING_SYSTEM_PROPERTY_NAME, "true"); + PemReader rd = new PemReader(new StringReader(blob4)); + + PemObject obj; + try + { + obj = rd.readPemObject(); + } + finally + { + if (original != null) + { + System.setProperty(LAX_PEM_PARSING_SYSTEM_PROPERTY_NAME, original); + } + else + { + System.clearProperty(LAX_PEM_PARSING_SYSTEM_PROPERTY_NAME); + } + } + + assertEquals("BLOB", obj.getType()); + assertTrue(Arrays.areEqual(new byte[64], obj.getContent())); + + } + private void lengthTest(String type, List headers, byte[] data) throws IOException { @@ -75,8 +173,8 @@ public static void main(String[] args) public static Test suite() { - TestSuite suite = new TestSuite("Lightweight PQ Crypto Tests"); + TestSuite suite = new TestSuite("PEM Tests"); suite.addTestSuite(AllTests.class); return suite; } -} \ No newline at end of file +} diff --git a/core/src/test/java/org/bouncycastle/util/utiltest/ArraysTest.java b/core/src/test/java/org/bouncycastle/util/utiltest/ArraysTest.java index 40367d52dc..927f2ae3d9 100644 --- a/core/src/test/java/org/bouncycastle/util/utiltest/ArraysTest.java +++ b/core/src/test/java/org/bouncycastle/util/utiltest/ArraysTest.java @@ -11,4 +11,17 @@ public void testConcatenate() assertNull(Arrays.concatenate((byte[])null, (byte[])null)); assertNull(Arrays.concatenate((int[])null, (int[])null)); } + + public void testCopyOfRange() + { + try + { + Arrays.copyOfRange(new byte[10], 5, 2); + fail("no exception"); + } + catch (Exception e) + { + assertEquals("5 > 2", e.getMessage()); + } + } } diff --git a/core/src/test/jdk1.1/org/bouncycastle/crypto/test/AESTest.java b/core/src/test/jdk1.1/org/bouncycastle/crypto/test/AESTest.java new file mode 100644 index 0000000000..5cb706dc3b --- /dev/null +++ b/core/src/test/jdk1.1/org/bouncycastle/crypto/test/AESTest.java @@ -0,0 +1,549 @@ +package org.bouncycastle.crypto.test; + +import java.security.SecureRandom; + +import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.BufferedBlockCipher; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.DefaultBufferedBlockCipher; +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.engines.AESEngine; +import org.bouncycastle.crypto.modes.CBCBlockCipher; +import org.bouncycastle.crypto.modes.CFBBlockCipher; +import org.bouncycastle.crypto.modes.CTRModeCipher; +import org.bouncycastle.crypto.modes.OFBBlockCipher; +import org.bouncycastle.crypto.modes.SICBlockCipher; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; + +/** + * Test vectors from the NIST standard tests and Brian Gladman's vector set + * + * https://fp.gladman.plus.com/cryptography_technology/rijndael/ + */ +public class AESTest + extends CipherTest +{ + private static final byte[] tData = Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114F3F6752AE8D7831138F041560631B1145A01020304050607"); + private static final byte[] outCBC1 = Hex.decode("a444a9a4d46eb30cb7ed34d62873a89f8fdf2bf8a54e1aeadd06fd85c9cb46f021ee7cd4f418fa0bb72e9d07c70d5d20"); + private static final byte[] outCBC2 = Hex.decode("585681354f0e01a86b32f94ebb6a675045d923cf201263c2aaecca2b4de82da0edd74ca5efd654c688f8a58e61955b11"); + private static final byte[] outSIC1 = Hex.decode("82a1744e8ebbd053ca72362d5e570326e0b6fdaf824ab673fbf029042886b23c75129a015852913790f81f94447475a0"); + private static final byte[] outSIC2 = Hex.decode("146cbb581d9e12c3333dd9c736fbb93043c92019f78580da48f81f80b3f551d58ea836fed480fc6912fefa9c5c89cc24"); + private static final byte[] outCFB1 = Hex.decode("82a1744e8ebbd053ca72362d5e5703264b4182de3208c374b8ac4fa36af9c5e5f4f87d1e3b67963d06acf5eb13914c90"); + private static final byte[] outCFB2 = Hex.decode("146cbb581d9e12c3333dd9c736fbb9303c8a3eb5185e2809e9d3c28e25cc2d2b6f5c11ee28d6530f72c412b1438a816a"); + private static final byte[] outOFB1 = Hex.decode("82a1744e8ebbd053ca72362d5e5703261ebf1fdbec05e57b3465b583132f84b43bf95b2c89040ad1677b22d42db69a7a"); + private static final byte[] outOFB2 = Hex.decode("146cbb581d9e12c3333dd9c736fbb9309ea4c2a7696c84959a2dada49f2f1c5905db1f0cec3a31acbc4701e74ab05e1f"); + + static SimpleTest[] tests = + { + new BlockCipherVectorTest(0, AESEngine.newInstance(), + new KeyParameter(Hex.decode("80000000000000000000000000000000")), + "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), + new BlockCipherVectorTest(1, AESEngine.newInstance(), + new KeyParameter(Hex.decode("00000000000000000000000000000080")), + "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), + new BlockCipherMonteCarloTest(2, 10000, AESEngine.newInstance(), + new KeyParameter(Hex.decode("00000000000000000000000000000000")), + "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), + new BlockCipherMonteCarloTest(3, 10000, AESEngine.newInstance(), + new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), + "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), + new BlockCipherVectorTest(4, AESEngine.newInstance(), + new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), + new BlockCipherMonteCarloTest(5, 10000, AESEngine.newInstance(), + new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), + "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), + new BlockCipherVectorTest(6, AESEngine.newInstance(), + new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), + new BlockCipherMonteCarloTest(7, 10000, AESEngine.newInstance(), + new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), + "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), + new BlockCipherVectorTest(8, AESEngine.newInstance(), + new KeyParameter(Hex.decode("80000000000000000000000000000000")), + "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), + new BlockCipherVectorTest(9, AESEngine.newInstance(), + new KeyParameter(Hex.decode("00000000000000000000000000000080")), + "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), + new BlockCipherMonteCarloTest(10, 10000, AESEngine.newInstance(), + new KeyParameter(Hex.decode("00000000000000000000000000000000")), + "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), + new BlockCipherMonteCarloTest(11, 10000, AESEngine.newInstance(), + new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), + "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), + new BlockCipherVectorTest(12, AESEngine.newInstance(), + new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), + new BlockCipherMonteCarloTest(13, 10000, AESEngine.newInstance(), + new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), + "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), + new BlockCipherVectorTest(14, AESEngine.newInstance(), + new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), + new BlockCipherMonteCarloTest(15, 10000, AESEngine.newInstance(), + new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), + "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), + new BlockCipherVectorTest(16, AESEngine.newInstance(), + new KeyParameter(Hex.decode("80000000000000000000000000000000")), + "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), + new BlockCipherVectorTest(17, AESEngine.newInstance(), + new KeyParameter(Hex.decode("00000000000000000000000000000080")), + "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), + new BlockCipherMonteCarloTest(18, 10000, AESEngine.newInstance(), + new KeyParameter(Hex.decode("00000000000000000000000000000000")), + "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), + new BlockCipherMonteCarloTest(19, 10000, AESEngine.newInstance(), + new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), + "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), + new BlockCipherVectorTest(20, AESEngine.newInstance(), + new KeyParameter(Hex.decode("000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), + new BlockCipherMonteCarloTest(21, 10000, AESEngine.newInstance(), + new KeyParameter(Hex.decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), + "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), + new BlockCipherVectorTest(22, AESEngine.newInstance(), + new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), + new BlockCipherMonteCarloTest(23, 10000, AESEngine.newInstance(), + new KeyParameter(Hex.decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), + "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168") + }; + + private BlockCipher _engine = AESEngine.newInstance(); + + public AESTest() + { + super(tests, AESEngine.newInstance(), new KeyParameter(new byte[16])); + } + + public String getName() + { + return "AES"; + } + + private void testNullSIC() + throws InvalidCipherTextException + { + BufferedBlockCipher b = new DefaultBufferedBlockCipher(SICBlockCipher.newInstance(AESEngine.newInstance())); + KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); + + b.init(true, new ParametersWithIV(kp, new byte[16])); + + byte[] out = new byte[b.getOutputSize(tData.length)]; + + int len = b.processBytes(tData, 0, tData.length, out, 0); + + len += b.doFinal(out, len); + + if (!areEqual(outSIC1, out)) + { + fail("no match on first nullSIC check"); + } + + b.init(true, new ParametersWithIV(null, Hex.decode("000102030405060708090a0b0c0d0e0f"))); + + len = b.processBytes(tData, 0, tData.length, out, 0); + + len += b.doFinal(out, len); + + if (!areEqual(outSIC2, out)) + { + fail("no match on second nullSIC check"); + } + } + + private void testNullCBC() + throws InvalidCipherTextException + { + BufferedBlockCipher b = new DefaultBufferedBlockCipher(new CBCBlockCipher(AESEngine.newInstance())); + KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); + + b.init(true, new ParametersWithIV(kp, new byte[16])); + + byte[] out = new byte[b.getOutputSize(tData.length)]; + + int len = b.processBytes(tData, 0, tData.length, out, 0); + + len += b.doFinal(out, len); + + if (!areEqual(outCBC1, out)) + { + fail("no match on first nullCBC check"); + } + + b.init(true, new ParametersWithIV(null, Hex.decode("000102030405060708090a0b0c0d0e0f"))); + + len = b.processBytes(tData, 0, tData.length, out, 0); + + len += b.doFinal(out, len); + + if (!areEqual(outCBC2, out)) + { + fail("no match on second nullCBC check"); + } + } + + private void testNullOFB() + throws InvalidCipherTextException + { + BufferedBlockCipher b = new DefaultBufferedBlockCipher(new OFBBlockCipher(AESEngine.newInstance(), 128)); + KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); + + b.init(true, new ParametersWithIV(kp, new byte[16])); + + byte[] out = new byte[b.getOutputSize(tData.length)]; + + int len = b.processBytes(tData, 0, tData.length, out, 0); + + len += b.doFinal(out, len); + + if (!areEqual(outOFB1, out)) + { + fail("no match on first nullOFB check"); + } + + b.init(true, new ParametersWithIV(null, Hex.decode("000102030405060708090a0b0c0d0e0f"))); + + len = b.processBytes(tData, 0, tData.length, out, 0); + + len += b.doFinal(out, len); + + if (!areEqual(outOFB2, out)) + { + fail("no match on second nullOFB check"); + } + } + + private void testNullCFB() + throws InvalidCipherTextException + { + BufferedBlockCipher b = new DefaultBufferedBlockCipher(new CFBBlockCipher(AESEngine.newInstance(), 128)); + KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); + + b.init(true, new ParametersWithIV(kp, new byte[16])); + + byte[] out = new byte[b.getOutputSize(tData.length)]; + + int len = b.processBytes(tData, 0, tData.length, out, 0); + + len += b.doFinal(out, len); + + if (!areEqual(outCFB1, out)) + { + fail("no match on first nullCFB check"); + } + + b.init(true, new ParametersWithIV(null, Hex.decode("000102030405060708090a0b0c0d0e0f"))); + + len = b.processBytes(tData, 0, tData.length, out, 0); + + len += b.doFinal(out, len); + + if (!areEqual(outCFB2, out)) + { + fail("no match on second nullCFB check"); + } + } + + private boolean areEqual(byte[] a, int aOff, byte[] b, int bOff) + { + for (int i = bOff; i != b.length; i++) + { + if (a[aOff + i - bOff] != b[i]) + { + return false; + } + } + + return true; + } + + private void skipTest() + { + CipherParameters params = new ParametersWithIV(new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), Hex.decode("00000000000000000000000000000000")); + CTRModeCipher engine = SICBlockCipher.newInstance(AESEngine.newInstance()); + + ((BlockCipher)engine).init(true, params); + + SecureRandom rand = new SecureRandom(); + byte[] plain = new byte[50000]; + byte[] cipher = new byte[50000]; + + rand.nextBytes(plain); + engine.processBytes(plain, 0, plain.length, cipher, 0); + + byte[] fragment = new byte[20]; + + ((BlockCipher)engine).init(true, params); + + engine.skip(10); + + if (engine.getPosition() != 10) + { + fail("skip position incorrect - 10 got " + engine.getPosition()); + } + + engine.processBytes(plain, 10, fragment.length, fragment, 0); + + if (!areEqual(cipher, 10, fragment, 0)) + { + fail("skip forward 10 failed"); + } + + engine.skip(1000); + + if (engine.getPosition() != 1010 + fragment.length) + { + fail("skip position incorrect - " + (1010 + fragment.length) + " got " + engine.getPosition()); + } + + engine.processBytes(plain, 1010 + fragment.length, fragment.length, fragment, 0); + + if (!areEqual(cipher, 1010 + fragment.length, fragment, 0)) + { + fail("skip forward 1000 failed"); + } + + engine.skip(-10); + + if (engine.getPosition() != 1010 + 2 * fragment.length - 10) + { + fail("skip position incorrect - " + (1010 + 2 * fragment.length - 10) + " got " + engine.getPosition()); + } + + engine.processBytes(plain, 1010 + 2 * fragment.length - 10, fragment.length, fragment, 0); + + if (!areEqual(cipher, 1010 + 2 * fragment.length - 10, fragment, 0)) + { + fail("skip back 10 failed"); + } + + engine.skip(-1000); + + if (engine.getPosition() != 60) + { + fail("skip position incorrect - " + 60 + " got " + engine.getPosition()); + } + + engine.processBytes(plain, 60, fragment.length, fragment, 0); + + if (!areEqual(cipher, 60, fragment, 0)) + { + fail("skip back 1000 failed"); + } + + long pos = engine.seekTo(1010); + + if (pos != 1010) + { + fail("position incorrect - " + 1010 + " got " + pos); + } + + engine.processBytes(plain, 1010, fragment.length, fragment, 0); + + if (!areEqual(cipher, 1010, fragment, 0)) + { + fail("seek to 1010 failed"); + } + + ((BlockCipher)engine).reset(); + + for (int i = 0; i != 5000; i++) + { + engine.skip(i); + + if (engine.getPosition() != i) + { + fail("skip forward at wrong position"); + } + + engine.processBytes(plain, i, fragment.length, fragment, 0); + + if (!areEqual(cipher, i, fragment, 0)) + { + fail("skip forward i failed: " + i); + } + + if (engine.getPosition() != i + fragment.length) + { + fail("cipher at wrong position: " + engine.getPosition() + " [" + i + "]"); + } + + engine.skip(-fragment.length); + + if (engine.getPosition() != i) + { + fail("skip back at wrong position"); + } + + engine.processBytes(plain, i, fragment.length, fragment, 0); + + if (!areEqual(cipher, i, fragment, 0)) + { + fail("skip back i failed: " + i); + } + + ((BlockCipher)engine).reset(); + } + } + + private void ctrCounterTest() + { + CipherParameters params = new ParametersWithIV(new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), Hex.decode("000000000000000000000000000000")); + CTRModeCipher engine = SICBlockCipher.newInstance(AESEngine.newInstance()); + + ((BlockCipher)engine).init(true, params); + + SecureRandom rand = new SecureRandom(); + byte[] cipher = new byte[256 * 16 + 1]; + byte[] plain = new byte[256 * 16]; + + rand.nextBytes(plain); + engine.processBytes(plain, 0, plain.length, cipher, 0); + + ((BlockCipher)engine).init(true, params); + + plain = new byte[256 * 16 + 1]; + ((BlockCipher)engine).init(true, params); + + try + { + engine.processBytes(plain, 0, plain.length, cipher, 0); + fail("out of range data not caught"); + } + catch (IllegalStateException e) + { + if (!"Counter in CTR/SIC mode out of range.".equals(e.getMessage())) + { + fail("wrong exception"); + } + } + } + + private void testLastByte() + throws Exception + { + CTRModeCipher cipher = SICBlockCipher.newInstance(AESEngine.newInstance()); + byte[] iv = new byte[15]; + byte[] key = new byte[16]; + + Arrays.fill(iv, (byte)0x0a); + ((BlockCipher)cipher).init(true, new ParametersWithIV(new KeyParameter(key), iv)); + + int lastBlock = 255; // the last block + cipher.seekTo((lastBlock * 16)); + + + for (int t = 0; t < 15; t++) // the last byte + { + cipher.returnByte((byte)0x00); + } + + // + // This should return the last byte + // + cipher.returnByte((byte)0); + + // + // This should fail. + // + try + { + cipher.returnByte((byte)0); + fail("should not succed"); + } + catch (Exception ex) + { + isEquals(ex.getMessage(), "Counter in CTR/SIC mode out of range."); + } + } + + private void ctrFragmentedTest() + throws InvalidCipherTextException + { + CTRModeCipher engine = SICBlockCipher.newInstance(AESEngine.newInstance()); + KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")); + + byte[] out = new byte[tData.length]; + + for (int fragmentLength = 1; fragmentLength < 16; ++fragmentLength) + { + byte[] fragment = new byte[fragmentLength]; + ((BlockCipher)engine).init(true, new ParametersWithIV(kp, new byte[16])); + + int inPos = 0, outPos = 0; + do + { + int num = Math.min(fragmentLength, tData.length - inPos); + System.arraycopy(tData, inPos, fragment, 0, num); + outPos += engine.processBytes(fragment, 0, num, out, outPos); + inPos += num; + } + while (inPos < tData.length); + + if (!areEqual(outSIC1, out)) + { + fail("no match for fragmented check: " + fragmentLength); + } + } + } + + public void performTest() + throws Exception + { + super.performTest(); + + byte[] keyBytes = new byte[16]; + + _engine.init(true, new KeyParameter(keyBytes)); + + // + // init tests + // + try + { + byte[] dudKey = new byte[6]; + + _engine.init(true, new KeyParameter(dudKey)); + + fail("failed key length check"); + } + catch (IllegalArgumentException e) + { + // expected + } + + try + { + byte[] iv = new byte[16]; + + _engine.init(true, new ParametersWithIV(null, iv)); + + fail("failed parameter check"); + } + catch (IllegalArgumentException e) + { + // expected + } + + testNullCBC(); + testNullSIC(); + testNullOFB(); + testNullCFB(); + + skipTest(); + ctrCounterTest(); + ctrFragmentedTest(); + testLastByte(); + } + + public static void main( + String[] args) + { + runTest(new AESTest()); + } +} diff --git a/core/src/test/jdk1.3/org/bouncycastle/asn1/test/InputStreamTest.java b/core/src/test/jdk1.3/org/bouncycastle/asn1/test/InputStreamTest.java index facdaf511d..c5ef11c513 100644 --- a/core/src/test/jdk1.3/org/bouncycastle/asn1/test/InputStreamTest.java +++ b/core/src/test/jdk1.3/org/bouncycastle/asn1/test/InputStreamTest.java @@ -76,7 +76,7 @@ public void performTest() } // TODO Test data has length issues too; needs to be reworked -// testWithByteArray(classCast1, "unknown object encountered: class org.bouncycastle.asn1.DLApplicationSpecific"); +// testWithByteArray(classCast1, "unknown object encountered: class org.bouncycastle.asn1.DLTaggedObjectParser"); testWithByteArray(classCast2, "unknown object encountered: class org.bouncycastle.asn1.DLTaggedObjectParser"); testWithByteArray(classCast3, "unknown object encountered in constructed OCTET STRING: class org.bouncycastle.asn1.DLTaggedObject"); diff --git a/core/src/test/jdk1.3/org/bouncycastle/crypto/test/Ed25519Test.java b/core/src/test/jdk1.3/org/bouncycastle/crypto/test/Ed25519Test.java new file mode 100644 index 0000000000..120eb3a2f5 --- /dev/null +++ b/core/src/test/jdk1.3/org/bouncycastle/crypto/test/Ed25519Test.java @@ -0,0 +1,162 @@ +package org.bouncycastle.crypto.test; + +import java.security.SecureRandom; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.Signer; +import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator; +import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters; +import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; +import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; +import org.bouncycastle.crypto.signers.Ed25519Signer; +import org.bouncycastle.crypto.signers.Ed25519ctxSigner; +import org.bouncycastle.crypto.signers.Ed25519phSigner; +import org.bouncycastle.math.ec.rfc8032.Ed25519; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; + +public class Ed25519Test + extends SimpleTest +{ + private static final SecureRandom RANDOM = new SecureRandom(); + + public String getName() + { + return "Ed25519"; + } + + public static void main(String[] args) + { + runTest(new Ed25519Test()); + } + + public void performTest() + throws Exception + { + basicSigTest(); + + for (int i = 0; i < 10; ++i) + { + testConsistency(Ed25519.Algorithm.Ed25519, null); + + byte[] context = randomContext(RANDOM.nextInt() & 255); + testConsistency(Ed25519.Algorithm.Ed25519ctx, context); + testConsistency(Ed25519.Algorithm.Ed25519ph, context); + } + + } + + private void basicSigTest() + throws Exception + { + Ed25519PrivateKeyParameters privateKey = new Ed25519PrivateKeyParameters( + Hex.decode("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60")); + Ed25519PublicKeyParameters publicKey = new Ed25519PublicKeyParameters( + Hex.decode("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a")); + + byte[] sig = Hex.decode("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"); + + Signer signer = new Ed25519Signer(); + + signer.init(true, privateKey); + + isTrue(areEqual(sig, signer.generateSignature())); + + signer.init(false, publicKey); + + isTrue(signer.verifySignature(sig)); + } + + private Signer createSigner(int algorithm, byte[] context) + { + switch (algorithm) + { + case Ed25519.Algorithm.Ed25519: + return new Ed25519Signer(); + case Ed25519.Algorithm.Ed25519ctx: + return new Ed25519ctxSigner(context); + case Ed25519.Algorithm.Ed25519ph: + return new Ed25519phSigner(context); + default: + throw new IllegalArgumentException("algorithm"); + } + } + + private byte[] randomContext(int length) + { + byte[] context = new byte[length]; + RANDOM.nextBytes(context); + return context; + } + + private void testConsistency(int algorithm, byte[] context) + throws Exception + { + Ed25519KeyPairGenerator kpg = new Ed25519KeyPairGenerator(); + kpg.init(new Ed25519KeyGenerationParameters(RANDOM)); + + AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); + Ed25519PrivateKeyParameters privateKey = (Ed25519PrivateKeyParameters)kp.getPrivate(); + Ed25519PublicKeyParameters publicKey = (Ed25519PublicKeyParameters)kp.getPublic(); + + byte[] msg = new byte[RANDOM.nextInt() & 255]; + RANDOM.nextBytes(msg); + + Signer signer = createSigner(algorithm, context); + signer.init(true, privateKey); + signer.update(msg, 0, msg.length); + byte[] signature = signer.generateSignature(); + + Signer verifier = createSigner(algorithm, context); + + { + verifier.init(false, publicKey); + verifier.update(msg, 0, msg.length); + boolean shouldVerify = verifier.verifySignature(signature); + + if (!shouldVerify) + { + fail("Ed25519(" + algorithm + ") signature failed to verify"); + } + } + + { + byte[] wrongLengthSignature = Arrays.append(signature, (byte)0x00); + + verifier.init(false, publicKey); + verifier.update(msg, 0, msg.length); + boolean shouldNotVerify = verifier.verifySignature(wrongLengthSignature); + + if (shouldNotVerify) + { + fail("Ed25519(" + algorithm + ") wrong length signature incorrectly verified"); + } + } + + if (msg.length > 0) + { + boolean shouldNotVerify = verifier.verifySignature(signature); + + if (shouldNotVerify) + { + fail("Ed25519(" + algorithm + ") wrong length failure did not reset verifier"); + } + } + + { + byte[] badSignature = Arrays.clone(signature); + badSignature[(RANDOM.nextInt() >>> 1) % badSignature.length] ^= 1 << (RANDOM.nextInt() & 7); + + verifier.init(false, publicKey); + verifier.update(msg, 0, msg.length); + boolean shouldNotVerify = verifier.verifySignature(badSignature); + + if (shouldNotVerify) + { + fail("Ed25519(" + algorithm + ") bad signature incorrectly verified"); + } + } + } +} diff --git a/core/src/test/jdk1.3/org/bouncycastle/crypto/test/Ed448Test.java b/core/src/test/jdk1.3/org/bouncycastle/crypto/test/Ed448Test.java new file mode 100644 index 0000000000..a217e8ab69 --- /dev/null +++ b/core/src/test/jdk1.3/org/bouncycastle/crypto/test/Ed448Test.java @@ -0,0 +1,172 @@ +package org.bouncycastle.crypto.test; + +import java.security.SecureRandom; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.Signer; +import org.bouncycastle.crypto.generators.Ed448KeyPairGenerator; +import org.bouncycastle.crypto.params.Ed448KeyGenerationParameters; +import org.bouncycastle.crypto.params.Ed448PrivateKeyParameters; +import org.bouncycastle.crypto.params.Ed448PublicKeyParameters; +import org.bouncycastle.crypto.signers.Ed448Signer; +import org.bouncycastle.crypto.signers.Ed448phSigner; +import org.bouncycastle.math.ec.rfc8032.Ed448; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; + +public class Ed448Test + extends SimpleTest +{ + private static final SecureRandom RANDOM = new SecureRandom(); + + public String getName() + { + return "Ed448"; + } + + public static void main(String[] args) + { + runTest(new Ed448Test()); + } + + public void performTest() + throws Exception + { + basicSigTest(); + + for (int i = 0; i < 10; ++i) + { + byte[] context = randomContext(RANDOM.nextInt() & 255); + testConsistency(Ed448.Algorithm.Ed448, context); + testConsistency(Ed448.Algorithm.Ed448ph, context); + } + + } + + private void basicSigTest() + throws Exception + { + Ed448PrivateKeyParameters privateKey = new Ed448PrivateKeyParameters( + Hex.decode( + "6c82a562cb808d10d632be89c8513ebf" + + "6c929f34ddfa8c9f63c9960ef6e348a3" + + "528c8a3fcc2f044e39a3fc5b94492f8f" + + "032e7549a20098f95b")); + Ed448PublicKeyParameters publicKey = new Ed448PublicKeyParameters( + Hex.decode("5fd7449b59b461fd2ce787ec616ad46a" + + "1da1342485a70e1f8a0ea75d80e96778" + + "edf124769b46c7061bd6783df1e50f6c" + + "d1fa1abeafe8256180")); + + byte[] sig = Hex.decode("533a37f6bbe457251f023c0d88f976ae" + + "2dfb504a843e34d2074fd823d41a591f" + + "2b233f034f628281f2fd7a22ddd47d78" + + "28c59bd0a21bfd3980ff0d2028d4b18a" + + "9df63e006c5d1c2d345b925d8dc00b41" + + "04852db99ac5c7cdda8530a113a0f4db" + + "b61149f05a7363268c71d95808ff2e65" + + "2600"); + + Signer signer = new Ed448Signer(new byte[0]); + + signer.init(true, privateKey); + + isTrue(areEqual(sig, signer.generateSignature())); + + signer.init(false, publicKey); + + isTrue(signer.verifySignature(sig)); + } + + private Signer createSigner(int algorithm, byte[] context) + { + switch (algorithm) + { + case Ed448.Algorithm.Ed448: + return new Ed448Signer(context); + case Ed448.Algorithm.Ed448ph: + return new Ed448phSigner(context); + default: + throw new IllegalArgumentException("algorithm"); + } + } + + private byte[] randomContext(int length) + { + byte[] context = new byte[length]; + RANDOM.nextBytes(context); + return context; + } + + private void testConsistency(int algorithm, byte[] context) + throws Exception + { + Ed448KeyPairGenerator kpg = new Ed448KeyPairGenerator(); + kpg.init(new Ed448KeyGenerationParameters(RANDOM)); + + AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); + Ed448PrivateKeyParameters privateKey = (Ed448PrivateKeyParameters)kp.getPrivate(); + Ed448PublicKeyParameters publicKey = (Ed448PublicKeyParameters)kp.getPublic(); + + byte[] msg = new byte[RANDOM.nextInt() & 255]; + RANDOM.nextBytes(msg); + + Signer signer = createSigner(algorithm, context); + signer.init(true, privateKey); + signer.update(msg, 0, msg.length); + byte[] signature = signer.generateSignature(); + + Signer verifier = createSigner(algorithm, context); + + { + verifier.init(false, publicKey); + verifier.update(msg, 0, msg.length); + boolean shouldVerify = verifier.verifySignature(signature); + + if (!shouldVerify) + { + fail("Ed448(" + algorithm + ") signature failed to verify"); + } + } + + { + byte[] wrongLengthSignature = Arrays.append(signature, (byte)0x00); + + verifier.init(false, publicKey); + verifier.update(msg, 0, msg.length); + boolean shouldNotVerify = verifier.verifySignature(wrongLengthSignature); + + if (shouldNotVerify) + { + fail("Ed448(" + algorithm + ") wrong length signature incorrectly verified"); + } + } + + if (msg.length > 0) + { + boolean shouldNotVerify = verifier.verifySignature(signature); + + if (shouldNotVerify) + { + fail("Ed448(" + algorithm + ") wrong length failure did not reset verifier"); + } + } + + { + byte[] badSignature = Arrays.clone(signature); + badSignature[(RANDOM.nextInt() >>> 1) % badSignature.length] ^= 1 << (RANDOM.nextInt() & 7); + + verifier.init(false, publicKey); + verifier.update(msg, 0, msg.length); + boolean shouldNotVerify = verifier.verifySignature(badSignature); + + if (shouldNotVerify) + { + fail("Ed448(" + algorithm + ") bad signature incorrectly verified"); + } + } + } + +} diff --git a/core/src/test/jdk1.3/org/bouncycastle/pqc/crypto/test/SphincsPlusTest.java b/core/src/test/jdk1.3/org/bouncycastle/pqc/crypto/test/SphincsPlusTest.java new file mode 100644 index 0000000000..15edf3d6b1 --- /dev/null +++ b/core/src/test/jdk1.3/org/bouncycastle/pqc/crypto/test/SphincsPlusTest.java @@ -0,0 +1,446 @@ +package org.bouncycastle.pqc.crypto.test; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import junit.framework.TestCase; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusKeyPairGenerator; +import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusParameters; +import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusPublicKeyParameters; +import org.bouncycastle.pqc.crypto.sphincsplus.SPHINCSPlusSigner; +import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; +import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; +import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; +import org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory; +import org.bouncycastle.test.TestResourceFinder; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.FixedSecureRandom; + +public class SphincsPlusTest + extends TestCase +{ + public void testVectors() + throws Exception + { + String files = + " sha2-128f-simple.rsp sha2-192f-simple.rsp sha2-256f-simple.rsp shake-128f-simple.rsp" + + " shake-192f-simple.rsp shake-256f-simple.rsp " + + " sha2-128s-simple.rsp sha2-192s-simple.rsp" + + " sha2-256s-simple.rsp shake-128s-simple.rsp shake-192s-simple.rsp shake-256s-simple.rsp" + + " haraka-128f-simple.rsp haraka-192s-simple.rsp" + + " haraka-128s-simple.rsp haraka-256f-simple.rsp" + + " haraka-192f-simple.rsp haraka-256s-simple.rsp"; + + TestSampler sampler = new TestSampler(); + + String[] fileList = splitOn(files, ' '); + //long startTime = System.currentTimeMillis(); + for (int i = 0; i != fileList.length; i++) + { + String name = fileList[i]; + InputStream src = TestResourceFinder.findTestResource("pqc/crypto/sphincs_plus", "subset_" + name); + BufferedReader bin = new BufferedReader(new InputStreamReader(src)); + System.out.println(name); + String line = null; + HashMap buf = new HashMap(); + while ((line = bin.readLine()) != null) + { + line = line.trim(); + + if (line.startsWith("#")) + { + continue; + } + if (line.length() == 0) + { + if (buf.size() > 0) + { + String count = (String)buf.get("count"); + byte[] sk = Hex.decode((String)buf.get("sk")); + byte[] pk = Hex.decode((String)buf.get("pk")); + byte[] msg = Hex.decode((String)buf.get("msg")); + byte[] sigExpected = Hex.decode((String)buf.get("sm")); + byte[] oprR = Hex.decode((String)buf.get("optrand")); + + if (sampler.skipTest(count)) + { + continue; + } + + SPHINCSPlusKeyPairGenerator kpGen = new SPHINCSPlusKeyPairGenerator(); + SecureRandom random = new FixedSecureRandom(sk); + + SPHINCSPlusParameters parameters; + + String[] nameParts = splitOn(name, '-'); + boolean sha2 = nameParts[0].equals("sha2"); + boolean shake = nameParts[0].equals("shake"); + boolean haraka = nameParts[0].equals("haraka"); + int size = Integer.parseInt(nameParts[1].substring(0, 3)); + boolean fast = nameParts[1].endsWith("f"); + boolean slow = nameParts[1].endsWith("s"); + boolean simple = nameParts[2].equals("simple.rsp"); + boolean robust = nameParts[2].equals("robust.rsp"); + + StringBuffer b = new StringBuffer(); + if (sha2) + { + b.append("sha2"); + } + else if (shake) + { + b.append("shake"); + } + else if (haraka) + { + b.append("haraka"); + } + else + { + throw new IllegalArgumentException("unknown digest"); + } + + b.append("_"); + b.append(size); + + if (fast) + { + b.append("f"); + } + else if (slow) + { + b.append("s"); + } + else + { + throw new IllegalArgumentException("unknown speed"); + } + + if (robust) + { + if (b.toString().indexOf("haraka") < 0) + { + b.append("_robust"); + } + } + else if (simple) + { + if (b.toString().indexOf("haraka") >= 0) + { + b.append("_simple"); + } + } + else + { + throw new IllegalArgumentException("unknown complexity"); + } + + + parameters = (SPHINCSPlusParameters)SPHINCSPlusParameters.class.getField(b.toString()).get(null); + + // + // Generate keys and test. + // + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, parameters)); + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + + SPHINCSPlusPublicKeyParameters pubParams = (SPHINCSPlusPublicKeyParameters)kp.getPublic(); + SPHINCSPlusPrivateKeyParameters privParams = (SPHINCSPlusPrivateKeyParameters)kp.getPrivate(); + + // FIXME No OIDs for simple variants of SPHINCS+ + if (name.indexOf("-simple") < 0) + { + pubParams = (SPHINCSPlusPublicKeyParameters)PublicKeyFactory.createKey( + SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(pubParams)); + privParams = (SPHINCSPlusPrivateKeyParameters)PrivateKeyFactory.createKey( + PrivateKeyInfoFactory.createPrivateKeyInfo(privParams)); + } + +// System.err.println(Hex.toHexString(pubParams.getEncoded())); +// System.err.println(Hex.toHexString(Arrays.concatenate(pubParams.getParameters().getEncoded(), pk))); + assertTrue(name + " " + count + ": public key", Arrays.areEqual(pk, pubParams.getEncoded())); + assertTrue(name + " " + count + ": secret key", Arrays.areEqual(sk, privParams.getEncoded())); + + // + // Signature test + // + + SPHINCSPlusSigner signer = new SPHINCSPlusSigner(); + + signer.init(true, new ParametersWithRandom(privParams, new FixedSecureRandom(oprR))); + + byte[] sigGenerated = signer.generateSignature(msg); + byte[] attachedSig = Arrays.concatenate(sigGenerated, msg); + + + signer.init(false, pubParams); + + assertTrue(name + " " + count + ": signature verify", signer.verifySignature(msg, Arrays.copyOfRange(sigExpected, 0, sigGenerated.length))); + +// System.err.println(Hex.toHexString(sigExpected)); +// System.err.println(Hex.toHexString(attachedSig)); + assertTrue(name + " " + count + ": signature gen match", Arrays.areEqual(sigExpected, attachedSig)); + + } + buf.clear(); + + continue; + } + + int a = line.indexOf("="); + if (a > -1) + { + buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); + } + } + src.close(); + } + //System.err.println(System.currentTimeMillis() - startTime); + } + + public void testBasicKeyGeneration() + throws IOException + { + SPHINCSPlusKeyPairGenerator kpGen = new SPHINCSPlusKeyPairGenerator(); + SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4792F267AAFA3F87CA60D01CB54F29202A3E784CCB7EBCDCFD45542B7F6AF778742E0F4479175084AA488B3B74340678AAD111491E7E52F6F1D726DAF2A4E75CAFB60D034B6E912B26BE68464B0095D60D")); + + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_256f_robust)); + + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + + SPHINCSPlusPublicKeyParameters pubParams = (SPHINCSPlusPublicKeyParameters)kp.getPublic(); + SPHINCSPlusPrivateKeyParameters privParams = (SPHINCSPlusPrivateKeyParameters)kp.getPrivate(); + + assertTrue(Arrays.areEqual(Hex.decode("3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5"), pubParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4792f267aafa3f87ca60d01cb54f29202a3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5"), privParams.getEncoded())); + + SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(pubParams); + PrivateKeyInfo privInfo = PrivateKeyInfoFactory.createPrivateKeyInfo(privParams); + + pubParams = (SPHINCSPlusPublicKeyParameters)PublicKeyFactory.createKey(pubInfo.getEncoded()); + privParams = (SPHINCSPlusPrivateKeyParameters)PrivateKeyFactory.createKey(privInfo.getEncoded()); + + assertTrue(Arrays.areEqual(Hex.decode("3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5"), pubParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4792f267aafa3f87ca60d01cb54f29202a3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5"), privParams.getEncoded())); + } + + public void testBasicKeyImportSimpleSign() + { + SPHINCSPlusPublicKeyParameters pubParams = new SPHINCSPlusPublicKeyParameters(SPHINCSPlusParameters.sha2_128f_robust, Hex.decode("b505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8")); + SPHINCSPlusPrivateKeyParameters privParams = new SPHINCSPlusPrivateKeyParameters(SPHINCSPlusParameters.sha2_128f_robust, Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8")); + + assertTrue(Arrays.areEqual(Hex.decode("b505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8"), pubParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8"), privParams.getEncoded())); + + byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); + + SPHINCSPlusSigner signer = new SPHINCSPlusSigner(); + + signer.init(true, new ParametersWithRandom(privParams, new FixedSecureRandom(Hex.decode("33b3c07507e4201748494d832b6ee2a6")))); + + byte[] sig = signer.generateSignature(msg); + byte[] attachedSig = Arrays.concatenate(sig, msg); + + byte[] expected = Hex.decode("b77b5397031e67eb585dba86b10b710b9729f44d1c00335014a674bed98b2569712954fc906b9ea4a9b2bffc37157e4973b56bc31f42619e38d67e37057da076b694ffe6c973ddda2526d5cb9056ec5b0d15901d3cc712f659f19113281a7dfc88a202189a2a770e79233bd3c89fa28cdd45e68b90f23a6f50a31da75590e3b4cb38baba4415235517099b467d0fcd54954b0653a995b035ffe418c1e7ba589380899556d1c9b3125d1f95e5827cfccf27aab6c28c990ca63292f465ccb268b16bb4440edbeaf88b4441fefb233921c87a06efbd2555e18abcaf0698261dd38c9b8ce8e06fb685388d1efdeed30b4f89248f953b168d909a58cba1f6cd879d548b5ed0c99c2273c31307d85666a7aaa5220ec159024ba387b9a0d49a6fec92c345db70cf5e2f387dbfbd20a92846db29c718140eee861c57f7354a1b9f837b714e95801e1f9ec57b805078aa0007d13773ceeb5ae4a5d2033ce802e05743990c71953838e960022cbcc1a117db4d74c70f68600926f6678b7c413e4074870ab6594078f2235ccc77f5bb4261daae596d0cc949528ebb1d05a30e200bb10627038d7ecec177eca4d98d3744d78c0027deeff398a3ee55d25cb03d49340c2f8b9313e74733b8affc7a332472f71131f598701bf2d152a2c5ebe294235fd17c6deca8cf749f675ba246561c2e65594113a69920da467988b9cf9f5039d9dba8044ac5b32ebf6d40887743d5fd8fb40b14777c9542da410d0a1288a25399192932ff83d2eb754bb7de80f9a3f81e0656ec2029f933e5f317cf695af96d900d20ec6ce8cae703084b326ba133c170f502f5cef25b11f2336b37db164992c2aac51a6877f440eb92c30dfd359cad0c1b8d412d8669a1e89f361713c1c7fb0af32888cf536d25314c90bf84e18fb6794e7ece3579d5faa9b001484f867445abf841365638c0616436102800e4762ba2d770386f35d0465b9f951fec7ee0a9e71f2fde1b13fab4ede6a66598cc4f01db107afbb361f9030d25424326708804159089f5135ff7431f4b7ef1644c0162f136dabfd3f4d66cbfaa474da07dd75dedfeb8639e3dc8260973d27f940286053ee1cf8c014013c56d4792c0126062086812d22dafa38ec0076cae11f8280af11e1c3a5b51e6e82bbe1df2c6c06fc03b77e0d47a91c4959acafdeaa4466b5f19f6b13af4c8de4cda8dada9cd8bb1eb8aceb911841c6a4808553f906312fd63c1a54945e2fb2683c20ee47dd98f4638f9c60e0bbcb9f352dff272f6e292c18598d3279089ada457f93850d7d5024023fb8db95b7a3ab994a80dcbfa1120cfca74bcf16bc6b68693b093af58f4df469b96a1c16cdd2feefe0cfbd0b8de6695dde07b1dff288fd314a469f55db6b8e997757e391bfe4eaa88deda15b01688c4aad9af5aea2fed0e09a11b048d04188327bd49e0f33046fe5d8383f6c639d5c852936cdb20e7616cecbde2984d6119a9eec0c8532a39fde133739e1790434002cb57d6657456be6110d0289c06f1b5960269b6fea99a2ff67cb5f0dabc55dab8f72402759754c80c82825c639dd4c6c47e7529c7128c26cc908680583800cd6b7263e0baca09eafaad078339e4ed2fd5b91d13c01ba168254687adc787438e72d5249dd3816fe572bbcdccdce4b259b93b1a59ba4ded18eb4bce856de66e7867b7bc7bba3dee1af7d752b33bdc9cd61b41abea88fd415a81b3f4fde9435a5588d43376aa34a7a5c654248567bf045c4fe2c5ee4f713e070a4b4b7f7caa0ef31d0b3de5c81ba893c3efd197dd83ed5c92529383fc7d4d2f2cbdee3cfeddb939ec200e8ba37a2d74a3ce6948df5c2a09c3d668ae56835210532669fa824f6183d3daf1be6c6de9b8b0dcb83c6db66f00e421145d0d0887a167408ed86d5ba25cae25f0b95305ae718b7c203985c67c6529c6e9bff744abbf3da6b0188c808ec24b3e3301ea2b5c191b97d37c1c92ef94560549a2a7a7e8a7b00ca03a7eee4ff7b1e01e39eeb1897304b22f5e2e05b277e8b9a387ddbea2b759ea738b12d0a3ddd5a8026e7baa58701e2fe41a9ead6eddeacf0f7b543367dfd86e8be30e2053b5e336a850dbeb62ca85a254f9f564d551cae6bd2b8ef5b8255f650c015110ad3a01d2d3414032b6d6b3e3ad4b0ec542bd615ade98f06dddb732ba6f76cb4597c35069b2cb689e965609671ff629278806983c92b2d206f7cb139eb8e9c0c219ddf758d5b58e1a0ce27475fdc246d744e3b238ddbcf35fe965f97f7559d6c34f137e08d8b737f564fc04e00146483306408caa1e42c566a4106c13d5dbefea3d901b94ffd2cf14d30885d47144e6b63d58685904db1d18faadac0eb80f3d8403fe1b78807c4f6fe4b677a61812533a59e34de32655e78ce8c3cc2e8e01100ab04511738fbaa9e1bd26b3a4443d352ddebd5dbf3bd15bab146b20936b5b5ce4c3032a2d89a20daa9596451798cdb70bdd539bc9c3c396efba34a3c2cc276b4dd9763633393be3c4c76cd54a4b88d2f93f220d70f1f252223fba93a97f560935e0a5388b643796e65c2c360faed55ac20ebe59fdaf3c84652ace1abe52ef4dca01fd737a3d1cf345b14d6e12e7151dcdb85c83c902925d3e2a643b9d9a9ec4ad4f6a905491612394edbd8e3d0e159a5980b4237b450c71e1d068d6162b28eddee2c9b8a9d43f8ffaee9dd4b12df4998b8b9f4bff94f7aa2d1380fa27c8de29fad5b128cc0cde45222cdcd9d6468907ff2a49418cee5d535a85dcbf2171cfd99fbf7ff253f5d0c442b0bb99d638f3cb0aa455c2c948ee99197fd3231c20c917c9816057507acf5e25d5ffa8b518e50c8246f5fd57cf3bc918efa39ebc8a85139f887e396a2b69a39c3c3b60a6225ddfbbdafdce824be479f3fee0dd74ee751726e1490c37802e1208d4398a20ca3f9474e0b7e88fdaee462fa56a49f2b5912a6c6c31e0d49a70a75f6a7fd125600885745cce6bcb97955d7d71f62258318202afc4ef0cb3575b7d5fc85036fc8c05a1c41a9e95bfd86094a25a1c7150e1b7b3cf04efac3c4754c7d385061ad92eb88f722a4b422efb86bdc73e8d580b7d034c73dc0cd627d5698ce3ab3d5d26564325b6607dc3d3225045d75276fee30709e3a3556aaf104894c00e4622209e5ea290d119ef6abe807fbed1c75e0a28514138d346d891e364f8b66aae317885edd7a6267dbf0bd24355f3783c3a630391c4992a53d1fd7a9a3d6917f81c2eae5ad51dbb580e109c93b3f6ef521d921b9c6dc9a23a1f3707a81e777d5c4eefa00ed05e520333088c7236ca47e8a3c26874fdf28e46b0a6243c19efeb9ca8db26fcb5b23753974c0337efd22cd1d7cd4f565fff0c2c202ae92876c679514a3ad6e635219e24df04e683a6663ee01d8e5484f13a1bae303285cb5fef0e216a786e2cf2de22463000bd2ea0610692b0867fc99dac92e30e6419590e0ec1ba9e019a9adc764a634cc644f0eef532b562a6441fb38af94269bc3dbcf21ebc934217d7578edaccc69f096fb1317586e1879761593b0f5ecb6c9ccdcbaf3225284e228ed65e9bed58a1155d9314c0f59bd0a81fdb275fc435b5315e27721b3bb010bfb79426ec630bbc2e6c86c78bc929dafbcc99aa68428b692b3ba27361127ca3f767b022d69eae04dcb0749e83654f4e38b5fcfbee6cc85d44dbf7322bc3c948b4b2d8e243f47b987d4936c6c7b04b68c272e9572db02d21be567fb92775562bafe686c5d27c84344f777206252695a6269b67265a9d8e9efbc4f1c6e142062c5addbd1d7f0684e69d00cf76d397beede5e1289b35cd933f0c73544d3053f28c6bd69a35d66f252ff0dd5093c51b415affd9dc12f123405e388a8a8e7bf623b487d21c4d61bc19a01d3aaefc0b0f2a058ce3df837111d3ddd1c6b671761d38faf282f4ac19c51e31ea9b4845e7ff92d072f8fcbfcc71dcb3373ebb8998ed88804a82ce4df08a16efdc8daf107247a8c29abb1de728f2f169230e562e149514b170b556414bb5a57a97867eb2275b742f72bd7e99765a4fa4b4ec3d4f144e7eb064acd664dfaefa50a42c6eeb454644fb2c58c19e43c8cc3bc63f73f9dbb54aea2f1af54a82326a0b5d7dcc0a1f5fd4427579ee9a8fd11abec77a99641f6306750211cd270b68049e18630c9a8de7f1b81495720459b0544a0f7557635873ccd0739176296ba2ac88638b39506ef0abab8e609e5f2d3fae18fad79d63ffce20ec18de5b7a20e29555381e71c7d78c2a23e26e60bb89736ac0f487529dbba530166a283c3d6b809bb253c4bae2fe1573a95c54202b3a3cfd508de5946748f31b9bd93127d56cb59b30508d4c6af98a68c6a0960bc34bc100444973141cbc304d22022c78c936d23c29f978c05ef52671a2e0399ab2818a72699e1c227ecb9fa8082cae430172bbed14bc4d4325eac06c3dba1d9a9631f85b93405f8f1819df155935d20d910702decd638c56a1a0eaa09eba95fd7ccef463b8670a365baff0b1b49a9c344de385d7acfbf2d972f35a1efc5338c3690a287f504b86f53e1646d936375708554f835afe2e66849c128ba0fa6fa240d98faa293fb7375de3fa898334eb98bd4e6bc7a08e45a70b26710d92f544af27b6c9bed3ed748994fe26b7a1365f13e18740a4acefbbeff6bddb8fafa3261c27c2298f4e9a77d5d19cb5b9ebb371cb89cb37ee12fd39480f85072c3ce24487aa8f638233ab1b17aeb89fc3e0e6efc9a47db1e5c01ad9d66f030e2681f7d6b08f1ccb164ab091ee57d5626700d26ef813c807d399383d569bb274d01c02540ceb3a02b503ec68f62bc06f50e5f1505bbad87bb4edd84e193b957f8f7d1f75a71fda2e9426a395d444acb30e5d8bfac5484518c5db31fc05e82b05e8de4fbba4aa8d8fe090a5070d44d0eba0b18555eb2c30888a18921cc4236b6c0727e89bdefe15ba5b4fac9842625977151a677c84841f10e66af5d90c69bee4b7cbafb7591a048b1a406a384dde6dee737a3a65d1cbc78a8c58adf429cbb7928580a92b747d22e75fca419ad7f15a6efb5b61d19364e93171870189a2f60db90b12fa8452740eaf3dd6841e50ed3187e0cbd721139dc11aac761c9d2697c190fb78fbc6bbb45009afc75f42806d1007c3de9a4012e1d265921953502f6f1a3be76bc01e1653506fbeae79bfc666a2ce36da259834c5632fff3f72b7bec63554caaed996a4d4b0342ffc82ffd39de68bd942210dde2f6fce548b52e56781810749f284418ac13f44cb2c75c797547d26e138317761ad932adfa45c65775247b7ee83607bae60d8cc7d8e4bbfd63c58cbcb4f2a1fecbe2f01ae589a2a4a04b85b49004b47fc20d146db3cf3f785b70bf7c9fff8a23b250143cbe74c5eedb3d3339e5f5afffe4ea77539611ac9cd470026652554a0819f6db9a9b90b42996ef848f59ddefe5eb20e86afb56753e23468bea8387027bc0b4b88fe1becd59b7b9b86a47270fe44cc9275c35330b95aeab0b2ef0ce967c9fac24a54178a8560c8bfd389f8919733001767c1372264af30fb9aeed6cd2eb0355fb59edde9f31a29b72f45291cbab6e664d25b7ec07c0eab272c8f2de139b94b7888244f8df510404476dba4b746b9f4156b50176b814d21f5f921b77238ef9f24a3e8914a8c1bf6c3f62053a2ba97b3657cb3f1d773f97202a4be9e2e6b429ff5e313ba23f56db04efd47e0ec8d4e94d08d775df14967bbbcfe135d9812826e359384a5a2ae5b5ebb1975ac68e8c62e7c2de394fd5e7c3ee3cb81096be684485701172f0bc1e4af21e6a2beef267de52be8cd3bebe7eeb22a120f7e6028b481f6ed64624d106f6347c095099c86e95a8c4592cbe7da9bf7accb43ffa79f93a9e27859026f4e2e13677996834c29005680fb3c705edb5a9364586ee3886557c41cbbf2153edbe62e7ade7e769cab65f98502934b07e86e4972522e4891d937a9db2ce6143505bddd414b9e5c70e2e064cbb4f5db9428845aca240916e0f3974dc858c9157a1ef2382e2d297984aceb5512567ea5b7eb9048fa7053d5f2de4e7c6a505199a1f3eb1f2f679e966fb0c2f981b24f602850d372b18eef6414c0eed50954abcb91269495dbe7b4c3580c3e7fd0b0e4743f2fb52c4c8e13cf0cf1e2094685adfcb59367d3b686c03642d998f483f5ead7ffddfec18122b5348fd561ee8b665f93bba3837f106fdeefcff03d90ae167664583bd0970495d2c5c698aeb6ca934a4a8635fc27ecf605483f7463b2b64085cd0369ae3293df986c9f78c8e441cd800fbabc21d17a2252c70ef82d4f305278b159acdf0a62d1d1c32bca8fb3198ab01798a2aed8569db05d721eaed4776d024044270cc8957f01abea7d37617ff9c6eacaf7d5457ecc4f5c0d2baaa2b698b382aab9f5ee5c06164ffa4e4364d56f7baf44689fd3b99b0196db4eed4cc6e46ad8f3bcdbf40233eb75e019659a032f09540088e3edc95b02b780751bd314d6e5a9e3a10b3cedc4381ac1d601e3d2e715c402eb3487a474cfe3cad055c1a5593a978c928728270e5193b11fa3442f149086487a263e6612719d5dae60e49cbcb16bccc43e12d0df2bb5d08dd53e3d73d7bb3f774863c36e03409b8b585e20d8cd09bf38c6b0f5900d4d2aa93569b87a8fa9fe81addd9a094d5dd24c7479f8b4e13d68975731190670af02e5ee060fdcad842ac73519b8d9572cc4383c2e28a42d0d63394a4b88cf6d382b050f21efb1dbc9ee710d09feb464faa673ba2f319a5644e8aa37bd883ce1b1d62771df8c52b928f58ae0142a7db22436247e2ba9e1e257d952eb2884586a0b8c78af43a2ba928ee8e9a57de5e9a3c622c0993d5f8b35103d332ed84f3c856d8d289a4501fc0ea2023fcea1d0a5c945af886a5d8eed2c182d3f559a4788d1387d7417b37e5767a1070041570043ea99fd026f7cb6148cc261c1368e4cc1da9a180aea3e4b49ad2ccaf75007f42d381ab345d52c75e8c3e237f938c90ecaf4a57af3bc3b990c071bf4a9c4464cde801c4fdb9f667a8fe4196d13b1677db3e273a4519b5abb965aade5cfd42b28e8379ada1636105cf6a7b6e3ec276f2d4ad1c1abee7f084e7098b6535028e5b6e58f5b90f13a9e52d6101fe50b58e2d95e9287a8a4595521780ed2c29dd873537243ea0020eeddb775a9ec334260821f44ce10c22fb12dd95cbd228e0991069345cd4670c72a48e908b75e84da8a44c2899f9462cc932943058dcd0b23b0ef0c1e5f07059ea7deb4ed5dc3a39196c75a4acdfa04184d237f852a0f2129e1dc20d59653e78b4758338e85398d47850fabca5ca7271724ad65064160c61cd3c8df00c9ebefbfae455af427deaa339a2b8973ec47f8f640bb2edc2ef7bc7783ce05cb008d525251bf80fc262a80dc27abe0e80675b3b2afc69a31378324ccc8a8aaf3faf8007971cf8caffd066f487ad44f78acc4aa17c20112144f94a7418a692f3dde011badafd6d5b96e7bdadde3506d95e866b9f74a3f1a9238df900566b44f06d07dee7d4f2a813c2a441eaf27d2a2e3687d85ce447ef2bfa577a537f5353fca51511fcda1c18e3bcda9726258120a0bf30673f3b6d5bf1b2bde36d2a3d9598da0ad6cf2a0cf90205f6decb514604e8001cae824ab75c9cf637e66434e7afecf5f497bc3fa78e6478e7120185af82e675c651c68eb48c5b29b6cb983261b9e2a53def469210a9186fb469ad80c720079bae746042116e0dacd94774306dd764e83ce6b387bbfeab6d9392f2f3bda9a5f565b873861bea8f1771cef6dec27fed9a9a34a7a87765f1d937ca048c3250f5cbba5946420cdf4f2ec69dda96f10bad7b1dbcd68876724086d3fc1f030e71e077de6dc4c0ca92a535e344ec33076aae12a63175f80e1ef95af19ec88f8cffb527422d6ef3e67e3b3178fad746076e68dee1bfc10d95b33b73bdf1fb486104cfcc80aadec620cc438338bdbb93a2bd48eedc92e3562ba4b9bd67bdff768d78c83934ca3ce49c2439c1ee38144d42ff6d0e77fa54d0c684c0f5d2f05a976a7fbebf5241d04b37e4d4040fde9693a34daab9a3e22a375c6c2eb2f5296cb4b1d6f220991a5e68b777445889b9e762ccf6e3809ef5e8ec49f7c7e2f8f7cecaf833bce3004bf98693de2de64fb070aaf958d282348ff980a5879beb9f1bedc137e2478c0f68a75cb20d0689b26cc2f6640100d76fc25f5f0edd410ba3d9a4fa4cf92fabb3ddb00c4b66718ea99159087d1d9e2820e87213526d64fd22b3e2d6749e4a988fb76a1bc290706e882493d858de6f4efadd487d377e6f6f4267a2cb5a42a388065e76517346314c67769a57d850c0f7eebb7eb274fa3b5612c3bafdbbe1536626e7d06913e6251f12b0387d82640a40a86f140b870fec3385950a69d6fc91bc9fb77de6578aa4635a9857004eb50aad28925606d585d20ad74862ae386934f905c47c1c2d044af45ceb15be4fa1ce2df00bbe16768bfbb2236ec62ba2d6f546f5273a2797a20bbe55b266b8b79872e73df7113f9aefbf0cb6caeae02e3b587a5b7d6bc55279b566985676a6ab0bafa36038872371fb7678fce0db6792b76ac08e5f598196c30c8749b2ffbae466d90faf0dc24ba7e29eb783ca57a2bf5c8fe7c8ee4478b6acd3c2f96e15a62722dd4d96dbd598bacfae505f422c2e32e24684cbf6e5d0829001c89c2ec32d9e2fea38faf0a6fbb6afa43f066f7f48c50e8301ba4bc6e1c71ec0669d27b746118e5e40a0cdf8e2f71aa81a1c75c323ec8b7d047841a20c7b92fe759942c79fcd3ae7fbafc97fd0d9f3320ca7849f631a196644e75bf560a72ea1cc08ea6a5a70487320f9b89ed1dca36487196fc88dc4f3c98d2f501a0b8e2161abfbe89400b523f202d1bb0b022eac2481dcb3efb987aa536195371048125f807c90bae718a3f73fdce794bf671e3df3c779d5f95b830d27325744d60085451b090551cd846c8e028366adf212dbd85b7cecdf854dad81121e7ace0f1b0dfe89d22ec49324700d5db66ccf0b8ee398dfd70b86cc315833e2a7db3936b1e276efa033155bfb2f8e64e4cfba8a5d5b956a03e2543796fe4b3476920fd3613c1e056eb299a02d3aba3ba2ef66948bccd530abf5bb37e8da9725de25896184635d7f1f4af44f073d124e2fe7988af57861b9ae0a90015395c429dc18f5ee90c0765d3995487178b71b427f152c37da2cfe14036d6137d97937746352cfb481a913b25c106d4fde9f614074af05626487f61d349d6fd0712a24fe9c56b5f5ab1b8386365237b3c864d4e017424940251eb2d54bfc58e0106a06999f3ef4b88a845f99b44ad5cc967456481048ce71f7bb08902de93b358cfcfa3f0ca9333c6c83aa77ba8b8762013f5cae34e7b2676990c01fdc5f619f1975ecbd40b6a6371ec3a4af3842794a093ac1c9b73355cbc5933ebba0aad104a6798eb6dad32425629fafc0db8bccd2b1f84db338f8828ff1783b633239c589eaa9fa1f045126a5c816cac8414c19d177d7a0b3da01815f9962ea0a0841cd1b428ac38050061a879fbda1345649f66703b7c7dc05c4c6941a72fe5a81379efabef69ef1f6473717c870dad980a4f5a2751eefc71a17dfd6728e7f0c293ba9f855d0bfa33e8c1fdca2b22898fcbae89bcf1038de58533c183bdaab094d537275b92ee0f38b46f01818ef4fb9156ae6485e11103e7cc4c21bbcbd2720fb61147c8fc739d323a25d1309b336cee39be4a354f93a4275b6fe153ab6f5f44b6caa7197039e23b6ba2c83660e7de0f73f939450c15f18ee31f8c095a0d9445a39912bdcfe95380cc39b483a6613c5f0bddb5ba6d56410eeff4d0d96d5d39202d1b789f33aa84e39b6d93b12f8aaf7836aa1ec792fa3178dd61dcd421e55b587451564d14ea3fec931b4198af45d66c98885c84376817ebe1ee08fc4c5cc7054409ac4e9745445c2a3fc8083f1c00c94b3ee2ce606c54373905e90fbc67ffaaa37c32b2df6d0758e2f0e661f40a21c939296d4ed4b1562742d00d4129cfef64862a1fc3c1eb910dcff20b08eda8ae77a4d8a8fd74ef5307de90d6fedecd89d11953ec718081f447446568e5e963e4f41f4b8311373205918e0d88fff9de755a59cf04b2d860146aac7d49ed9878d8756e4c86f1eeb83e15d4de9ba4a619a9c51e770b433c4519cb8ab6ad562da2f448ea4561e13eae4371e71b0cec593f69f3114323f30c7a74cee253bad994ac3610c557963ef49e64fe725e98a006e71d59b1ee395319e7e8ed414067440a457e90d2ec467c432e24012e74ea74a3652819909da7036bfba4a138eed2fa312b5f1eb6de40d5ed2d74266c220542fe4d85556220fb74c8d9510327faf768a047c3083482ad95ab1f47f09aa7391be806f6dc2016bf039f60815cb8b9e1469552020ff775c7c4ff246780fb5904835fcd02c8e902fa66b85cb2375228e4d24b208836399807aab7159f3f1976f28bd9f3e10a90caebdf8e63312b00fef5999d3e185067c56fa4ae4d607ed425d55337d95388cdef8cbf9881b07d431b423c41c9628948ffedb17e36ebb929bc5ba7af780518461ac6749d97247a253e343efdbf390f29acd98ac87ab83436fdbdc3dfc2a385f1ecc3ddffb206962525cb42c8154b19196ef7918b2e664edffb3a90f8c1da300a3b03850fd3451affb0f70a022abf7ee6212855bcda138c79aafa54f2ddbb54580f0b209feeb17ef20ca0fc9af2be68a9b0b67e8df93da7aeaadbb602c7fe9ae1ef1083b03ba089feda1dd797e9d4e7ebce47b6e49e584e3d36f1330809d4eb5ecd255c9af74c618ab061b4a8748714bc3c82386c53ff675a7e91fa0bb1b118a22fd31f88a2b3e4121b39d029261a93e3de1f0abb800cede0d4ee338a31e469a853ac338ec7a3ede7b5337a261ab470717587cc1d82595d1d29feb5810b405613dd396be3594df9fcf52c7f463e10bf2daf9e6c1a391a25884a05ee6a2ccc9813caecfdc82711efae4b860df67b8ac62bc6da2d521313b8c62d40e570befe2742a5fabe714a18b792cb73af258b5d57e0d74be479ff99f12a5308a7e4fcc3014a82980d47bf34b889d40ac2155310f8587c8a6c7308573cae57d8145be9fe7c6ccbe902c56f2ccb5428a6ac05493385e5e80e549b08ca310ba64c60ae359e19a8c2528faf15daa0501c1e784c37d8c77f19247e7742592aeb8f58c1281e75cc659d15f73c3d594da7c1f3d4894281fc0a364c84e7bc48c967e13dae8d636b392da1af132ea10aa6f792ec138ba67a530f498d365d5fdc0a5de1875b5c09d0ebbd53b315de4c1d8e90645327162f3bf15aff817da2f7d2f3bde107edbfb92466814c6d68fbce140914c16aa2a98a9a368f2c4be38cb26baa64e736ed3661dda53cf843fd6634526b8a69f1ec4e3c67de5004d80ff5cdb2dd05f69e9eca5912f03e094a60fb58b307abd439a1fcbf69d574d3e81c0057effc725c8807ffff4a37f087d85be48a28c158fe8c7f6c483cbed13e7aef1e1f2b579d5bf49469147eb9d764c14b04a305c39d754de5b933b7553f2d3e2c02786f6db6a251e1505e0ef5f8345c5411e9038b61aea75a4179b68e4b1bcb3b914dfb671adb00864dfdfded512b3a146cd11f8f586576bcae37f8f36fdd45c698252fbad57da2baba8153d442926a5225b94c3a680e3c0f162d1f37491a15d6cc7dff1795aced01679142418911ea0eeac548d844ce52210900a181099ad554f8357cb2581f83e94b343c90d2623c8ad36b8dc245a0356c041009826b0a5ff9f75e58800d0386039814279dd2ad9fc79bfa6214512a6ca21768c0138c2f6341c52d2bd13a6598bb0ece7f11055f4f3f9eba5d8de596c275f995371211a6ba1a6d02981c1ae2de3f9726044c56ca74c711f30a956777555b4b98a70555271b20ca1ffbc58ecd43162a24e75ca29ccc272fb1c6bcc9247ea23242d056268b0335d53b707ea48b8fe8eb6a2ca77cba6189ea6747fdd4dd99d572502b2a3dc5fad6e913901a51b9e466a9a043edc69f8f773147954c757200b538753e6d2ee0c63496a8827c8b9e051e2bbf092171bd508e9eb88f68f2076dc1c7a34c1539ce9bb5a9b9604bdff7806393edf44fa21a42cf9735643d2a4fae46363da61f899899c1a8a9a8e0d6fcacf0c0f016dfc491f0350bf3bffd8a0ff8c226b2427bc161a661fe4721081c74d0b71699dd858d2da2c896f5fe51ec432ca5ee396d6e7aeceb6309d30fd79dbf2831e75c7e6f20e9b0287b25644436b62003f812218a6ef02f3c49a0896a1cb286922494f29c1f58de65fdf8e32bd5e972311065ad45479b640e494d9e0874db53b4e08f8e478dd919479f6aa3eca43863f31836c879c763087642bcb231c88ecde7fba0ac3a6fd803256cccd4d29f581734570cd48d3468dd31e9e51695e2e21b224da3fe63c34b8ae52efd8076a81bdf3fcea4bb5b1afcb280c5004d71fb181bec19f1776e94591856973bb31d3b79a8b0976213e876ef9383707da61302f5c835ddd4353e30645602b66fdd495fffa64eedcc181a0f8ee950dc83555089d6d6950253ba083d7156f7ae07deb57a25164a68e076a798f1b0b3650843b4cc818fda3c98b38670cddc53c85c6f452edb99f3811b774fb09f8e258f0b5b09a0f753873bbf0606f6f26f2acf9458fb76810dafa36e77fab8b75cde898e35bddfafaf9788a35f4034d31df099429b5d85a0f7dbbde40384c540ce99c7fdb4ae7b5d865d292bbfbb0ad2adc2ee48f0c551c14950edd97c2a3ddb047b813a3e3be52049956d37e9cbd8816e666ad3886f8700ae41f2fde041f706559e95d38ae5c9da47b1f570a809d0206d67562de3a1e8bfebb619d8394320f713b272988f41ac27b4f7f5483af72096544d42bbc81bd28eb55254b4eac3edf617f94c1a09a736ed086c8f1092df4a4e195a5e61660923963de43b1203d49bd1f27515950b17d858e97c2af537494267210548faa8713466064f61dff4b2408a87bf8ace61b870d7ed7bddf7284f4b0ab8d85e08ef42cb00725e969078a01e4483ea7bcc5f20992a015444367650975d64ff2093477efc3d7fa2de52c1eca53cf8986d7b81ef6807cb062172139fdc855d206c16d5795b6f75605e7bc0d59c63efba4252d008c732f1c1ebe58b37126a77192ec52fff6d3715c559f4e789fefa2772bcc917236e7cfdc1467f46ead4227e4f97f7c425e3129497c55e77375b682a4576f0fd2194ae4dcd4484d0f8f4ea974155163ce87627179eab5791e219320488bd2721585e3e96841802f66205f22094d9218c9bf347c8868af2e00e691741f65e8df5b75d2db2ceeb0813bf7a3ba5c5e974a7c40915081b5abb08832ae870dbbdb42f87feb970ba0269f65673be2bca56b585339db162606197f584823fb6e532499382b77c6b386f2de41b0a427f83194658a04d98cf2040bb9d66c7832e109a236aa8f2a22f9d2c5b2a2e0d35dfe764f346aa03816e2d3ba0b24cb63082eec815960c88c455f340d4082c0c413f80c266f7bba8183cb2e44f48c701c482e465a71632a0df36f1032807b074d481d2c3d5dd2695f29274e8d28cafb709550a38fc3f5b70b09623eac0c9afa78d988736f172fb35950f439397da60ab8297dc013d9b7f82272396d2e1c3ac25071d8174da48444fedb9406a2cad751d20d833e82b89bdc5e2a149c87b704c4d13b1360ce36661214d364ad83e6da6f514dd6fef42f4e077e6bb2d3525f058bcf390c6e353140dbb4143872973106a00e46a749aeaa153f5b8e3c81535282eb3ab589f683ffca562bd44069312754d7cab341e2619f3560753b9b113874863c5b010fcba02e96c13ca58a0e82c348fc0e2696b64db2c62a6a36d74c557c3ede7c483898ade2090483a8be28f19d654f3aa371ef60f8e4f0b9fd3febe37b3bce3dedb2aae0314b96e6c2b2a034c636d038b2de6c202386646140f6a06f2bb3ba77f5cc584cc81865143de4183fec60859d88e91bdfa9fff10401d854448813b9880c7d677bc68472488cc80ba534a5376b21f80cc46b6579722bfdb59258ca8f31383ffd10fbad0990549dc663c6cd18bae014b906835a34d0b22041e47bd0d955bed52c09219721532782f594504f125769e8f186567d60de6c99307144e41a36cfd46c8da4c3bcf5a9fd129db21d9d9ec80ef1cf67b1af813f3621751aed640eb2a0a2564759e05d444a9c92602fc7521e1efc8914f3b7826f848829fdc11c3e20f1e9d695b3447f823691c080df7fabb66cc06dc8976345e81a148a56b7d34f09b97f43e59bf5d1c8cda4082f54fc886fe92f674ee706a0ae1c8a0d4a0620686e3d287576f5d848ddda55376616dbc05e508c246d5643d2a97a0016dfd80611db1be4cd5b350be1846f974be25daf5555968bed5c93ea8a16217639197bbf9d50a7cc57bf5577e4e2604328df08ea48a7f2a44b47a6bbab43fde8e37fd5dec0427d373ec2408d782a8caa30f180343cddadd034000e159ce04499a2ae2efcf55a54d19420d87a5b03868fa48b19ff7a3ac81ffb7dfe3b9554b8ae4653a4bc51383df06079e95f6e553e5680a47b218801233219ff86120b472f133d89d3c1be40f53126892db21d8128d30d9a67ca4958d21265b8a3835f060f4f499146417425d322990807ce86476da924127fab38ab2ea7813ba54bd2737246714b4a0a17fc014a4084b73aafb935a6da065658cfe436eadfad99fa6b92246ea1ffc9c0e9743506aa05f5df68d43deb5265ce6d8c1f79a69657d1b52fd8ef0078fe77f2a26532ce84a5b5a22ad457ebbc953e17b2cb47feec209025f54049dbea1fd79bf39462c265f2f0c27d5b842dfcea1fd173c6883547c20883c74e6778abd2f1ef2df9c69aca084329c946b2ead40ee4f1708f439c5686fbac228dbef69d080b95e996a09b8180e756d67a1693c6b1cfa4ce7916ee4aafe7cea281d2c6bbfc756d476e2dd965fbcc924215daa33d5f284078dab0bf52353523f46f286081a098325793deeb5b86db938a8721399160a9f250ebec36e63237a041568130d8ae7f2f80bc433a6bb174852d171abb144d17e18aaeb74175be20d056570b632b0cf13c5da162acfde4b884ec7d7888823503e96cb5633048098431cc91f26f3d293d3b925b18fecac4f95b2f544966b95afe2f0451b6315ac4777944116bc3bb6342857c06719e1a0a698ba3c1d49ef4fe5d35e92fcba73a5940087ab4fe58c9b17db43362a061db31b4a14a1fb1020a717ef27ab424a1f65998dc5c221e39238dd993782e4a1654b34e4e66b485defcf4359d835c5f7d7c5477a57c556e2f6c7a18bf18a0dfde8f2acea81a47cfd1976328322ab0e71d6c0de2fa88430bc6d69e1eef8ed700ea578ca9d304c53475780940aa2192843a45dd60409c19d97a21897a1ff20003554936e3a76a173da88166060fbd3cf83aa562f0a7478e031072b8895a7cf5e1bef24989655033ba12362986e1e3f67483c7619028fe40edfdcc4c5444b6fd0ab26b8a87d51b88118f4ff73766ba7c3685c63b7bed819104f70cabbc29de5701c5cce446658773a0f3c8d530e9336f7c728ef9b600f2d1ba20cb545cfadf756c1d77d1d66641938e35ebdad460341ec1e466dcac0bcb6ddd6a462f77c328d982dafccb26a14f2698939f392d1d26558a4ca94353a32e1130a40fb73d43bea8cb9ab8b98cd393e24df88bc8659508c3f31b6a8d6930ad292478f581576260c2a9b4692f2e9d3381b9dc4ee04bfd5d80740e64260d5cc69b9e48a2995a1279256144e7356d553a8e1652110ed808d30fd4506de4f826b036cc265a22afb372fc63e4715d1b43179c5a56bdbe92c4e7b7a4315494721fddf4bdd06c9b491feb4e9999883ca4a42b8c7bd84a59c25e065fbe4c9e485a36459e9481a048970e3c38ac871e16d558978a3dcf1ce48641d20dba8137f684ba2b218cf1da4a983b593567b9699adc94e1ff6e4f0284b2b8512fb3d7f5e200f99ba3494bcb3568828d682de2b28cf7a72d8c71d3327ef00eecf006daaeeca5e25a87b4fefb5cb20a1dee822e498e2b8abd9012fddd063ce938d7779882f576509d2b4e73caa0c2ad571aaf8aecb794c35e39b634f937661db46ce2f82306cbe3641aafcaccc0dbb4612a98b47993008ce759c5f6b7db6151d67f33a37e031722999310b50143697e8babdbcab9e1621bfc5ee99bebe750758420b58da87f9e16bf37bacc9d038f0539c8530d60080322547c4bc043e3303a7f1a6f2d0f0f888641f47be539c5fd73954adee29b52713406a3ef8a384d7fcb5da4c54c44d8af5ed61b0f162160151b66104749b7b8ff3e37fb58a39defdde38948180a0bc12c79ca354b557556402df71b1f0785e2593caed9808bd392c7d452e4161427d6cee64ac772fa978f4c2e0bb73f51c37f39acbdd9453e766b2946300760c1194eb3440f509fd3fd389e3b4c4b78af2eee613e5aea840488548a70c736ca2fba306084ce708c1adba13e7ad303df3b4a8b371395bca34253d4ca3ef79a7f03c6feb203c99f13f8a760aa9f204f1aaad1ff3dbd2fd644fa94f1c63f9f39ec48a7099c5eb47a7994a60e01638a9ee78028c64182e1bb6bf71f669d76c185f66152f4bd4498ca85e40ae9f5367b66016beb65c2b0e8a89d47cb4587bda2590aa21cd69f3431eadaf4b660a2bf89b577821e17d194b2d37553c29ddcc2f5e39cf3c36506c2ad36875dd2d68825c57164fc25f9341e679d2d7ec0002e5c0a2cb4ecc861df2466e223681f3db199b7b1e11eb24c2edaac854d9b2929db74788f8be7d5d0697e0d8c9cd21cddc45db44e4c5c6379309f5685deeb060a2afd4f80d200c80e4ba1aabe06bf99f1ff2188fc6861a178d830f02a0aedb8c5b8d98319b80b4c91211be418eb7cda8ba7946b81cfd89d510192c56fe5af00f01eaec7554c7bcc7d7bd13cbef42ae195709f461af2006ad661baf251b4f2a5e69a4216814d853d348b3881c3609e3f16bb8653a4f5ae3d7f8af302ea35dabf794cb3c62b382b70fb4fff89f50f846d7d08c50c0690486abb3783a1505ac4b54258910d8c1562ddcb25c5692c938cceced62c0f03bea47f44c93eca3bd910eebb98b881e7412f01fc7ebaee7e6738b547ce8e9de2e9f024a91885f76a166ba0d30b56888a1ce202b12e4c09e084fe2b2412b0d86a2869cd8607328a0ed7fea478a551df672dd80fed385ce048782540ee0f387c8d32874d4fb2b38bed64c08a7761ba86c7ea0f2d496fedcad314553f29643c6d6f9722c3c4ec67937a482ebb68964a589b30180fbf3a60c7a89483673b3c5ff1568ac3ec468a233bf696e768789b8e3bb92dfa391baea1851898764e94d8e0591e7256c92e3b70012aaa4d76b6aa6792a8d266e3f0d8a07f90690bd0fbca3fe0b0c08aecdcaf1bf2157a0ba9c4cf9728991b2d0ae0e19abbf42951125486932630b5efeb6c9bbec6c3bd32811ac226d96c4676fd5d79dbb07e315bdad503b940a3afa963019f56cb8544964ca71c68d070897870bfd0b42e412c759dd764eeceb53d8786fe0a159c7f02ab4da1995d9396c0509a53e7d3e7dac99ffe577f57723020bdb673c0eef7db135aa84c8dfef8ed8cae4d62beba61121a5df71ceecd5d99f1ca80bece5e288c758eda15286a085cdb2f144c247bc600fa30909097693945651da0083f9ee9502f8292f9f738905ac0fd0d96463b6a43dea79f9a03680d26bc80effa139135e9d0b7ee981c91a25cda6095ab21f5ab97f07943646bed426251bd9fd62e2d1bd80371b979d2fb3ec9d63348f34b33ae16399c6094121d9cd241b217b6fe5241c01a53e2bf30fd9057b8dafc99cdf19960f62ebc89b1950be59ef98aa8981983c8d46bf538e2c01a8a54cce3b8fbd09fe137b63c100745f8ce5aaf97b8d162399750ac7ab7a813f2d489c5307000f108da926317f866e7c7b1c54322c3ef4aa2320a574b8978f6ab9de2f5624d04ea00e5bcbae5b69bd7f261e329c181e48f371ff718898c158c3eeec3770788a377f48bb0710969d01f47caf9c59f3cb4b1fdd38f945b832d837042f51afb22752e5fe4744a28a24b2f7c429c50c1fbdffd0aab23f8c30fb83df2d606c9b771cb27ed7abb18e36bd7eada3e04fff2c695462117541971431dca56a2afeddf92896a6d6e26c3ae5f1d7558dd7e16ebb60c6b0ef13897b6edae11daffbfc8216c40c13cee2a11c4035f3312bdd03ea975b3806f34150395153b32e1aacacdaac7f46a1f579b86d96cc0dd349de5d589e97ba808e264406606285586d680292b07f437cd758ad174e5b9df967b69c6f0a5db80c604d5399a7ae1820daf5b3173101430b88b22380ffde73bbb04cafa6a259698dfed1d4c896dab4f43a901e33515f892cc474cb7a4e337a3e446a986e2120800e53c726343106cc6fa65687c9831015d8be90065d518d02e52d20f7f5ad10763cb6edd3cb9534fc0cd8a5ad14e319b386261df741f39756f2a3ccd263271da46b1029b5e5ca753515024bb50a4727e0eb75b0c1d93719cfbf7c96b0c3fa3e07bbc4af3910e3b01b97434358d1c74c73058577b02a59316dd78e676a7d7019cc81aa4defab4195fd0f2289a191698f21a6b96f1b92a35339199e6ebcde89591c862173bb260892fbd8f0b179f91519a76aad1d5f50378c61e677adf69026f346ba83437e818960da9390f5c00fedb9b56fa9586900cf2657e13ebe3abc7e86b37e5314c6a759d1b021c89094c581a1edb7885036df6f45b29d314cda8b34c2dbed35f84cb885ec80dbd8058418642cf8a7274347934a3309b557fda7b49691c855f8fea36f2b7f38a03ce7cd4922341993debc889daa2456539ba973e98474d4ccb294b4d63d9c00fb5ec198fd5da439cccd89c6843830785a6ee1cb7397ad6e208b014841667e9ee9df47e94e217aa58cbc52b15906a1051a3a574330e28d83cd9986e20b68a49a40f8eb128f020c2df1a6448e66fb1c5216276cd42b371b400d4ae51f063d9fe42c3a93231ac8b50ad24744eb4b44ed11064bb35aa16da9caede48f56d3e8f648e67b84b2a19921999994c42a59973e844a33edd67c8bf494bdc8718137ea82e55164af30bd38f5c47a59601a91574ec612ac5a8fc56eaf96141784d8f8fe59133cc39b3c76771971dbd5cddcc6b63d20bcace1d56cf95734b32c7ceb77577395d87c9f884885c92db28b343cdec25675b7fbc93640d7b11d319730af1b4414e3c5697e83ef24f9563fb45553a0fdf5f6ef449585615f3af6394288827289b1b1901aca8b81502c5b5c4081ac914047158595a5694fd6fa4b0a832828d4d60fa8bcbf48be1f792e5f7588fa0ca41f204ede8c56c8f4191e2fbae744d0a7e4232d1c53a3644170f832efe82723b50e2a79bde332edaea3e425a4646004ba98f3cf9fc19fd23af7ff3e1c8cd23e0983acb22d9d11a6d882785a0b3bf238697ce14b231a2935af1f1e294d43bae6e8b1df1d038d99462fe53e61b79a3c1ec3ca8bb7b720c427047fc2d2e3426047975162252bad1d00425afa3d4c2d3460b0e36c335b8400493bfcf5be7f4ad773b1cdfd1f560e1d53a457f901c1a58a648dc972f34ed9fa18ae7375a0633a68407b2849eafac02df9c28f299923fd55d8974ff5070a5d1a31cb96104d89c909b510b9aede6c9a529a9f74acde2a5b7d8f73d5270bf6203beaa88e71840c3953b06b6b5fe6f43a13bc1520a2079db18e26c89018c394f8f3b1d4e6529744e889cfb5df5d9e81e4806aafe904d6b81accce5c1d2c6ba8f3b740bd080a496c94b4c50c61c4efd2d2e49b7e435529ab77b8cc974d49649135f3b94d6fd224b94a5315343bf162430fcfab5857adf2be6579ef5689a3470509e927cd716b90529c68776afdf3afeee316017e33a1e759abd7d4d4b05faa8066feca343e99db2d9db4236c094d77f9176b275e11306dfd7d306255ad4eef0b74aeec64ba1f5b96ea0e38dcca3a9f7776af5c3ab7903a301fba182cc969d3500980dea8c71dde6dbdde8cd06141ec8587b4b8cad2060927a910628bf9908da84b0e6b25a361d6ba8bc68d1bba60071175d6c257893e421914448f49cd299e5ac91cd86725115a500de7d7862bf7a5067e1b7c2dba9696029950a28b00b61e57fde02e6ca8bff3d0529e82f2cf203a047c0a163617c4a6556c35d71bfa86559647b6e38f158bb99af519f47a51a30843fdf06d287d05591aa392126af65074fb01f7778f8346d983287432002b98b6bf9a58f428ad02fe46289deaf8ae065ea8929e34f5ca42b0811847cd6750004604547636918b72bee8cd001a42908e3317addddbd46eb198d72ea3b5874553abc33bb2e1f733585b4a4dd1fa2cbe1d2eb70a9b7d137c90b5aed63db4f4e2e45fad81f865427134c3f482d358cef2c821e34d85aec90f45088eec523c174ae1e7e86311f0b7c6c9f27550a32d93e05ddd4f85aeee27a9b2cbce548321bc5afc25bf7a6ae3b5b6dc385e398f9baab593e9da0d3b7d7341bcc054d2b8dc67ac89c6f290357570f81226b2871456fe3ed29bd55b9db4e6e4077fe5bd58a6e3b846beccff6cb2fc57f66076aefdb9e72ad0daa7d3faea861a160de98d91b57c17fbe729bc3e213640edb54c7986e5bad11cd606f636c56fb2dd22d63cb931612844d0ddd68f4ac628d6aeb83d4a87c07729a3be8705cc0a5172ef93891fb7ab5be09f5df836003c5b9e1b599cf9514b51094e838230ae2701ed2f2230b0127932d260d2b010992a3e3121d7a3d50357febd311512d4debfeda8562219f10ece6d76b10f04b67d713122f790aa97d071baa6d1f6f2a4125a30cfd2963754a08c7d5ab4b747bc13ca503059e5c10d0c359e237fc582e750537d8ecb04318e6c4db35d727b29a37ce56e812de82778995df40d3ce628ca8fa8f78eebd71d48e47996a70fc8f2694c7b8a33f49a6dee3ec0974e6134ac2b514dcbc8c2603e90cc872d1fd6f86f61832e445856b0fe66cd822dc99a3dac666b7fd8f8ef0ec00347600ac01c4bcd6c786cc3ee075bc3e520dedf2a7c3b2d11bafdd77931aa6be5a736f40e16665925eafee386bb219f42cc3d130033d049c95c5830450028d36d97b56d577e3e4b115fecf29831dc47b547e3830799c787cdc3c49fe04c84da3a7f2d5a8143a0ae7bee6c15998288e14e11ee669a46e07014c827c3ad44f84c483b81d93b63f5ac2dab4500678789f71abfffd336f24a8ca8b5351cbf06b23a20545432725b8bbb178cfee7975c89f0ded3e9be159db624748632b72c98cab4dc3515db0e559ae2bdd5e11486e866ab388c40e7a34add6d4a9fcda95a1cbd944356fa81efb9bb7c7a88fe92cf7568d9d065956a8a75a190f9c1086956ed10ec63b6014b4855d789fa0b0fbd41794bc6c6904447bb45f10d1ccaed311aa8ec74f2338c494580f2a8197c72ec72be26dc98040ef046b6ba184a5f170f897c38061480bdb8f3b5f1d2d1da537215b0239591eeffca21786b93fc42590989dc478cfeb50c80471b1e1313448b59c81a06e46836c89a72463e09b956de8438211719a6490e7f1fcdd2bfe95e9d8fd76fc74965ec3605cc0133608f26c1d69d8e636c6f5bfd7824fcbca7124f07aa601d54e9250611e65aed2f69cb6ed9f6071daac0be1922b662aacfa7c22051b3953c97fdcc6fc400111aca97b19b28bb2614cc61d3d875d27b82d73c09fcf29ff936b46c8eecbaeaa6ccae08a23ec5330424087a2960e64c688e6a7f8b6ba6100e1605bba923c4dbd532bf6353cdae7e46d30299900c23581faab86ddd3e8ad57657fd8674deba30c6acb6b36332bca701774a86e11f227fc65f958de5ec2042bf5dcdcbfc5a184a163e9ec81e4d832fb42f0430b27a9bf7138f646e646be7a3ea1c8c188e470249166bd6620d1f02fbd0d27abbc357349b76ecb17dc128b59f11045706042af0ebf0c4322ab7c507bd65b80068315eb090d1281b7755cf571885046c6ac0bd9b3f3004f8eec8488227b7820b29a4283db93a3cc7c93750166d55e9eb979100d4702a53d7548dae7c0b06faaf1857186d19732531fad901b0eaef50064556d2c9d65d4b8917a895a2d86feee765b54e8734771b43ebaf59c561c8b4fbd2c763b01f7797a6fca91b362a2bd45249563dde1eec7b23d0093c63f08d86fa75f66f45a9a7623aec153960666749d1943691b6536a9ddee7f92dc2471a1abcd9532cce3e716b6439ac928abaf3f7b4883a68c817393844c25f33a41f27790b800e1106ed82b56b56cab1b308c2606e3fcd460510a13ee80f57a30095003c2417f6816f14dee17b2926ef1650a6faacdd3181937b8058ed76bf5e869bcc9c8b01e9a528d559f78cb574d5f4c4912e7a8c4d2157b23a82db0545728fe5f4f27e75886e710f83b607d9925c7461358fd1f5aafe598b1f0794a340bc4e232c55372b2913ede045e7c2250247ce05a6aa7b58e425f2ed9e66095cdb756a8b846e1c91c2f2f55b0ddce9cd637ccd8412753445d2eb21dbc6db4e6059ca022d7c21cf47f3b646bedd5f626f42ab1247372c0e248839cdcf44c3bdd3f824d33b0fee7d9f5a66ec001762692ef667c263f59aacb7f3dfdb44224ce0049008b2bffc9b26636a8c0d4ab48a95691b24a6e805d9285b5a25a3d5a623c2ee585672a4d86cea9baad531951294393757d8e3d6939baa3d075b38c511dfd8fa746f7b21da0f6a5d91126a983a5feafa19e3852c40c4c8ac37da8058bf8edd948f459bdfb6557de291e86d9e1a5dd080196c050b1909a1cfcb812aa6785313b40d3574c2d06001b802eaa4e191b1fb22ce5416b366947b8750758eea112139aab6335cf9e80c98622b012a6833b770fcd3f9a3d4ac32a6b7a33d2cbcb16e8bb8eb79f05a77f459bfb61895ee2f5f8d5f6570ae2b5fd14e576a45e1e0eae5035a5b635c2e55019f32f1dbb2c6a4fb06b3683620bc9a5cf96f6de27858f99a06f0059b274c8154ee11be53b514df8ce57084bfc7d1032d6d01a8046a96d6a46755b45be3984941c1c7ef945b33157c48f9ecf6615596561f3df29660f05e78c9f200ae4e4161d0297c9d5a19ffc791706c9a15fe8828afd456269913bca88201c2742adf928f4ba8c5bed78fce63675336c54016e4acadc2c40e8b60dd0ad9db3ea4d8d4346d68ef41290b7cf842e2c69c0c41f2d050589a04765910ac0c2fe13b711a9b5a3b372a2cb5d79ca54b98e6d2f8c085e53e29e0e4f0311f02719968a72c5cc98bb16a9686ea5d4bb991f91d7f01f5ca2a56fc0d5c40a5bbc1e6ff0fafe400d7e809671f865b19e07db280b155fef8fc04b79a0aa33ff79e422b9a7aafba3204e79020cedfc24b85252b4ef7d0fe1f8428bdfc29957851b44daa36120bbbfd4155a8b41ad9526c64d0ec6745d4fa691065f157a9e200a10148b9f4d47d8e35229a408113bf60f1b90f2ecf77474f63398fd631f3f1644728efc6c891d83f5cbad59019809b4f0ec7a54c119785b9ecf8c16346a643c96e12eabbcd67341705832e999668c26dbd28464ba7010bfbf1a51758c79c89f325c26075f3626f97ac6fa914d8871977ccd7846323cd687aefed6edbe2881d639b3bf9f14d195790b7f55304104f5a7dea1a5590ffe170acc395fd5cfa4f6e6f9b09312862f333614bdf81223378565d8c2e7421e23bc4e3c50a2cd7f8dc588463987598d4bffc5584c96ba16337abe2537361f0642044cf109c5ceaecb2e94f2b8a04952adbdacc809821e42ce1e0f63a6c305d42805254624733c429ab8648e85b73b76d5b8cf4715e65d55166426202aa7ac5b810bbd1db39bb5b25d32b4571b8ee338e05017dee145adfd0e8bb03f9dc00d803c76feb61c204140a450f145d299dcd49578cd5117e2f8c5e3b63019edc8a48221d9e1ef296d979ec1ff02d2a3fc3da4e797d8f7835d1e8454440d557e3f3c6ea17904e7ed801a7c836ef9ce2b77a5849956ed1c3c9764f3da9c416f33a298ec12d28ad56513ed856ba38302f04b452f9d1aad4a5c130ec792e45a34b4092b6749ee8ccc73098641b988e77d2ffa328c8ef8f0bfaf208c1cf3f685801d4eb5f061fd8df7bf01475d9b112cac342581c09ff9bba4d77950ea8130bef8e07428cc081791b7df20742058297ef6a4adbc158555ff011a9aac07e8dc2938bbe6e543e25c9806ae86d0023a4cb51d81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac8"); + assertTrue(Arrays.areEqual(expected, attachedSig)); + + signer.init(false, pubParams); + + assertTrue(signer.verifySignature(msg, sig)); + } + + public void testBasicSignature() + { + SPHINCSPlusKeyPairGenerator kpGen = new SPHINCSPlusKeyPairGenerator(); + SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3" + + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")); + + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.sha2_128f_robust)); + + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + + SPHINCSPlusPublicKeyParameters pubParams = (SPHINCSPlusPublicKeyParameters)kp.getPublic(); + SPHINCSPlusPrivateKeyParameters privParams = (SPHINCSPlusPrivateKeyParameters)kp.getPrivate(); + + byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); + + SPHINCSPlusSigner signer = new SPHINCSPlusSigner(); + + signer.init(true, new ParametersWithRandom(privParams, new FixedSecureRandom(Hex.decode("33b3c07507e4201748494d832b6ee2a6")))); + + byte[] sig = signer.generateSignature(msg); + byte[] attachedSig = Arrays.concatenate(sig, msg); + + byte[] expected = Hex.decode("b77b5397031e67eb585dba86b10b710b9729f44d1c00335014a674bed98b2569712954fc906b9ea4a9b2bffc37157e4973b56bc31f42619e38d67e37057da076b694ffe6c973ddda2526d5cb9056ec5b0d15901d3cc712f659f19113281a7dfc88a202189a2a770e79233bd3c89fa28cdd45e68b90f23a6f50a31da75590e3b4cb38baba4415235517099b467d0fcd54954b0653a995b035ffe418c1e7ba589380899556d1c9b3125d1f95e5827cfccf27aab6c28c990ca63292f465ccb268b16bb4440edbeaf88b4441fefb233921c87a06efbd2555e18abcaf0698261dd38c9b8ce8e06fb685388d1efdeed30b4f89248f953b168d909a58cba1f6cd879d548b5ed0c99c2273c31307d85666a7aaa5220ec159024ba387b9a0d49a6fec92c345db70cf5e2f387dbfbd20a92846db29c718140eee861c57f7354a1b9f837b714e95801e1f9ec57b805078aa0007d13773ceeb5ae4a5d2033ce802e05743990c71953838e960022cbcc1a117db4d74c70f68600926f6678b7c413e4074870ab6594078f2235ccc77f5bb4261daae596d0cc949528ebb1d05a30e200bb10627038d7ecec177eca4d98d3744d78c0027deeff398a3ee55d25cb03d49340c2f8b9313e74733b8affc7a332472f71131f598701bf2d152a2c5ebe294235fd17c6deca8cf749f675ba246561c2e65594113a69920da467988b9cf9f5039d9dba8044ac5b32ebf6d40887743d5fd8fb40b14777c9542da410d0a1288a25399192932ff83d2eb754bb7de80f9a3f81e0656ec2029f933e5f317cf695af96d900d20ec6ce8cae703084b326ba133c170f502f5cef25b11f2336b37db164992c2aac51a6877f440eb92c30dfd359cad0c1b8d412d8669a1e89f361713c1c7fb0af32888cf536d25314c90bf84e18fb6794e7ece3579d5faa9b001484f867445abf841365638c0616436102800e4762ba2d770386f35d0465b9f951fec7ee0a9e71f2fde1b13fab4ede6a66598cc4f01db107afbb361f9030d25424326708804159089f5135ff7431f4b7ef1644c0162f136dabfd3f4d66cbfaa474da07dd75dedfeb8639e3dc8260973d27f940286053ee1cf8c014013c56d4792c0126062086812d22dafa38ec0076cae11f8280af11e1c3a5b51e6e82bbe1df2c6c06fc03b77e0d47a91c4959acafdeaa4466b5f19f6b13af4c8de4cda8dada9cd8bb1eb8aceb911841c6a4808553f906312fd63c1a54945e2fb2683c20ee47dd98f4638f9c60e0bbcb9f352dff272f6e292c18598d3279089ada457f93850d7d5024023fb8db95b7a3ab994a80dcbfa1120cfca74bcf16bc6b68693b093af58f4df469b96a1c16cdd2feefe0cfbd0b8de6695dde07b1dff288fd314a469f55db6b8e997757e391bfe4eaa88deda15b01688c4aad9af5aea2fed0e09a11b048d04188327bd49e0f33046fe5d8383f6c639d5c852936cdb20e7616cecbde2984d6119a9eec0c8532a39fde133739e1790434002cb57d6657456be6110d0289c06f1b5960269b6fea99a2ff67cb5f0dabc55dab8f72402759754c80c82825c639dd4c6c47e7529c7128c26cc908680583800cd6b7263e0baca09eafaad078339e4ed2fd5b91d13c01ba168254687adc787438e72d5249dd3816fe572bbcdccdce4b259b93b1a59ba4ded18eb4bce856de66e7867b7bc7bba3dee1af7d752b33bdc9cd61b41abea88fd415a81b3f4fde9435a5588d43376aa34a7a5c654248567bf045c4fe2c5ee4f713e070a4b4b7f7caa0ef31d0b3de5c81ba893c3efd197dd83ed5c92529383fc7d4d2f2cbdee3cfeddb939ec200e8ba37a2d74a3ce6948df5c2a09c3d668ae56835210532669fa824f6183d3daf1be6c6de9b8b0dcb83c6db66f00e421145d0d0887a167408ed86d5ba25cae25f0b95305ae718b7c203985c67c6529c6e9bff744abbf3da6b0188c808ec24b3e3301ea2b5c191b97d37c1c92ef94560549a2a7a7e8a7b00ca03a7eee4ff7b1e01e39eeb1897304b22f5e2e05b277e8b9a387ddbea2b759ea738b12d0a3ddd5a8026e7baa58701e2fe41a9ead6eddeacf0f7b543367dfd86e8be30e2053b5e336a850dbeb62ca85a254f9f564d551cae6bd2b8ef5b8255f650c015110ad3a01d2d3414032b6d6b3e3ad4b0ec542bd615ade98f06dddb732ba6f76cb4597c35069b2cb689e965609671ff629278806983c92b2d206f7cb139eb8e9c0c219ddf758d5b58e1a0ce27475fdc246d744e3b238ddbcf35fe965f97f7559d6c34f137e08d8b737f564fc04e00146483306408caa1e42c566a4106c13d5dbefea3d901b94ffd2cf14d30885d47144e6b63d58685904db1d18faadac0eb80f3d8403fe1b78807c4f6fe4b677a61812533a59e34de32655e78ce8c3cc2e8e01100ab04511738fbaa9e1bd26b3a4443d352ddebd5dbf3bd15bab146b20936b5b5ce4c3032a2d89a20daa9596451798cdb70bdd539bc9c3c396efba34a3c2cc276b4dd9763633393be3c4c76cd54a4b88d2f93f220d70f1f252223fba93a97f560935e0a5388b643796e65c2c360faed55ac20ebe59fdaf3c84652ace1abe52ef4dca01fd737a3d1cf345b14d6e12e7151dcdb85c83c902925d3e2a643b9d9a9ec4ad4f6a905491612394edbd8e3d0e159a5980b4237b450c71e1d068d6162b28eddee2c9b8a9d43f8ffaee9dd4b12df4998b8b9f4bff94f7aa2d1380fa27c8de29fad5b128cc0cde45222cdcd9d6468907ff2a49418cee5d535a85dcbf2171cfd99fbf7ff253f5d0c442b0bb99d638f3cb0aa455c2c948ee99197fd3231c20c917c9816057507acf5e25d5ffa8b518e50c8246f5fd57cf3bc918efa39ebc8a85139f887e396a2b69a39c3c3b60a6225ddfbbdafdce824be479f3fee0dd74ee751726e1490c37802e1208d4398a20ca3f9474e0b7e88fdaee462fa56a49f2b5912a6c6c31e0d49a70a75f6a7fd125600885745cce6bcb97955d7d71f62258318202afc4ef0cb3575b7d5fc85036fc8c05a1c41a9e95bfd86094a25a1c7150e1b7b3cf04efac3c4754c7d385061ad92eb88f722a4b422efb86bdc73e8d580b7d034c73dc0cd627d5698ce3ab3d5d26564325b6607dc3d3225045d75276fee30709e3a3556aaf104894c00e4622209e5ea290d119ef6abe807fbed1c75e0a28514138d346d891e364f8b66aae317885edd7a6267dbf0bd24355f3783c3a630391c4992a53d1fd7a9a3d6917f81c2eae5ad51dbb580e109c93b3f6ef521d921b9c6dc9a23a1f3707a81e777d5c4eefa00ed05e520333088c7236ca47e8a3c26874fdf28e46b0a6243c19efeb9ca8db26fcb5b23753974c0337efd22cd1d7cd4f565fff0c2c202ae92876c679514a3ad6e635219e24df04e683a6663ee01d8e5484f13a1bae303285cb5fef0e216a786e2cf2de22463000bd2ea0610692b0867fc99dac92e30e6419590e0ec1ba9e019a9adc764a634cc644f0eef532b562a6441fb38af94269bc3dbcf21ebc934217d7578edaccc69f096fb1317586e1879761593b0f5ecb6c9ccdcbaf3225284e228ed65e9bed58a1155d9314c0f59bd0a81fdb275fc435b5315e27721b3bb010bfb79426ec630bbc2e6c86c78bc929dafbcc99aa68428b692b3ba27361127ca3f767b022d69eae04dcb0749e83654f4e38b5fcfbee6cc85d44dbf7322bc3c948b4b2d8e243f47b987d4936c6c7b04b68c272e9572db02d21be567fb92775562bafe686c5d27c84344f777206252695a6269b67265a9d8e9efbc4f1c6e142062c5addbd1d7f0684e69d00cf76d397beede5e1289b35cd933f0c73544d3053f28c6bd69a35d66f252ff0dd5093c51b415affd9dc12f123405e388a8a8e7bf623b487d21c4d61bc19a01d3aaefc0b0f2a058ce3df837111d3ddd1c6b671761d38faf282f4ac19c51e31ea9b4845e7ff92d072f8fcbfcc71dcb3373ebb8998ed88804a82ce4df08a16efdc8daf107247a8c29abb1de728f2f169230e562e149514b170b556414bb5a57a97867eb2275b742f72bd7e99765a4fa4b4ec3d4f144e7eb064acd664dfaefa50a42c6eeb454644fb2c58c19e43c8cc3bc63f73f9dbb54aea2f1af54a82326a0b5d7dcc0a1f5fd4427579ee9a8fd11abec77a99641f6306750211cd270b68049e18630c9a8de7f1b81495720459b0544a0f7557635873ccd0739176296ba2ac88638b39506ef0abab8e609e5f2d3fae18fad79d63ffce20ec18de5b7a20e29555381e71c7d78c2a23e26e60bb89736ac0f487529dbba530166a283c3d6b809bb253c4bae2fe1573a95c54202b3a3cfd508de5946748f31b9bd93127d56cb59b30508d4c6af98a68c6a0960bc34bc100444973141cbc304d22022c78c936d23c29f978c05ef52671a2e0399ab2818a72699e1c227ecb9fa8082cae430172bbed14bc4d4325eac06c3dba1d9a9631f85b93405f8f1819df155935d20d910702decd638c56a1a0eaa09eba95fd7ccef463b8670a365baff0b1b49a9c344de385d7acfbf2d972f35a1efc5338c3690a287f504b86f53e1646d936375708554f835afe2e66849c128ba0fa6fa240d98faa293fb7375de3fa898334eb98bd4e6bc7a08e45a70b26710d92f544af27b6c9bed3ed748994fe26b7a1365f13e18740a4acefbbeff6bddb8fafa3261c27c2298f4e9a77d5d19cb5b9ebb371cb89cb37ee12fd39480f85072c3ce24487aa8f638233ab1b17aeb89fc3e0e6efc9a47db1e5c01ad9d66f030e2681f7d6b08f1ccb164ab091ee57d5626700d26ef813c807d399383d569bb274d01c02540ceb3a02b503ec68f62bc06f50e5f1505bbad87bb4edd84e193b957f8f7d1f75a71fda2e9426a395d444acb30e5d8bfac5484518c5db31fc05e82b05e8de4fbba4aa8d8fe090a5070d44d0eba0b18555eb2c30888a18921cc4236b6c0727e89bdefe15ba5b4fac9842625977151a677c84841f10e66af5d90c69bee4b7cbafb7591a048b1a406a384dde6dee737a3a65d1cbc78a8c58adf429cbb7928580a92b747d22e75fca419ad7f15a6efb5b61d19364e93171870189a2f60db90b12fa8452740eaf3dd6841e50ed3187e0cbd721139dc11aac761c9d2697c190fb78fbc6bbb45009afc75f42806d1007c3de9a4012e1d265921953502f6f1a3be76bc01e1653506fbeae79bfc666a2ce36da259834c5632fff3f72b7bec63554caaed996a4d4b0342ffc82ffd39de68bd942210dde2f6fce548b52e56781810749f284418ac13f44cb2c75c797547d26e138317761ad932adfa45c65775247b7ee83607bae60d8cc7d8e4bbfd63c58cbcb4f2a1fecbe2f01ae589a2a4a04b85b49004b47fc20d146db3cf3f785b70bf7c9fff8a23b250143cbe74c5eedb3d3339e5f5afffe4ea77539611ac9cd470026652554a0819f6db9a9b90b42996ef848f59ddefe5eb20e86afb56753e23468bea8387027bc0b4b88fe1becd59b7b9b86a47270fe44cc9275c35330b95aeab0b2ef0ce967c9fac24a54178a8560c8bfd389f8919733001767c1372264af30fb9aeed6cd2eb0355fb59edde9f31a29b72f45291cbab6e664d25b7ec07c0eab272c8f2de139b94b7888244f8df510404476dba4b746b9f4156b50176b814d21f5f921b77238ef9f24a3e8914a8c1bf6c3f62053a2ba97b3657cb3f1d773f97202a4be9e2e6b429ff5e313ba23f56db04efd47e0ec8d4e94d08d775df14967bbbcfe135d9812826e359384a5a2ae5b5ebb1975ac68e8c62e7c2de394fd5e7c3ee3cb81096be684485701172f0bc1e4af21e6a2beef267de52be8cd3bebe7eeb22a120f7e6028b481f6ed64624d106f6347c095099c86e95a8c4592cbe7da9bf7accb43ffa79f93a9e27859026f4e2e13677996834c29005680fb3c705edb5a9364586ee3886557c41cbbf2153edbe62e7ade7e769cab65f98502934b07e86e4972522e4891d937a9db2ce6143505bddd414b9e5c70e2e064cbb4f5db9428845aca240916e0f3974dc858c9157a1ef2382e2d297984aceb5512567ea5b7eb9048fa7053d5f2de4e7c6a505199a1f3eb1f2f679e966fb0c2f981b24f602850d372b18eef6414c0eed50954abcb91269495dbe7b4c3580c3e7fd0b0e4743f2fb52c4c8e13cf0cf1e2094685adfcb59367d3b686c03642d998f483f5ead7ffddfec18122b5348fd561ee8b665f93bba3837f106fdeefcff03d90ae167664583bd0970495d2c5c698aeb6ca934a4a8635fc27ecf605483f7463b2b64085cd0369ae3293df986c9f78c8e441cd800fbabc21d17a2252c70ef82d4f305278b159acdf0a62d1d1c32bca8fb3198ab01798a2aed8569db05d721eaed4776d024044270cc8957f01abea7d37617ff9c6eacaf7d5457ecc4f5c0d2baaa2b698b382aab9f5ee5c06164ffa4e4364d56f7baf44689fd3b99b0196db4eed4cc6e46ad8f3bcdbf40233eb75e019659a032f09540088e3edc95b02b780751bd314d6e5a9e3a10b3cedc4381ac1d601e3d2e715c402eb3487a474cfe3cad055c1a5593a978c928728270e5193b11fa3442f149086487a263e6612719d5dae60e49cbcb16bccc43e12d0df2bb5d08dd53e3d73d7bb3f774863c36e03409b8b585e20d8cd09bf38c6b0f5900d4d2aa93569b87a8fa9fe81addd9a094d5dd24c7479f8b4e13d68975731190670af02e5ee060fdcad842ac73519b8d9572cc4383c2e28a42d0d63394a4b88cf6d382b050f21efb1dbc9ee710d09feb464faa673ba2f319a5644e8aa37bd883ce1b1d62771df8c52b928f58ae0142a7db22436247e2ba9e1e257d952eb2884586a0b8c78af43a2ba928ee8e9a57de5e9a3c622c0993d5f8b35103d332ed84f3c856d8d289a4501fc0ea2023fcea1d0a5c945af886a5d8eed2c182d3f559a4788d1387d7417b37e5767a1070041570043ea99fd026f7cb6148cc261c1368e4cc1da9a180aea3e4b49ad2ccaf75007f42d381ab345d52c75e8c3e237f938c90ecaf4a57af3bc3b990c071bf4a9c4464cde801c4fdb9f667a8fe4196d13b1677db3e273a4519b5abb965aade5cfd42b28e8379ada1636105cf6a7b6e3ec276f2d4ad1c1abee7f084e7098b6535028e5b6e58f5b90f13a9e52d6101fe50b58e2d95e9287a8a4595521780ed2c29dd873537243ea0020eeddb775a9ec334260821f44ce10c22fb12dd95cbd228e0991069345cd4670c72a48e908b75e84da8a44c2899f9462cc932943058dcd0b23b0ef0c1e5f07059ea7deb4ed5dc3a39196c75a4acdfa04184d237f852a0f2129e1dc20d59653e78b4758338e85398d47850fabca5ca7271724ad65064160c61cd3c8df00c9ebefbfae455af427deaa339a2b8973ec47f8f640bb2edc2ef7bc7783ce05cb008d525251bf80fc262a80dc27abe0e80675b3b2afc69a31378324ccc8a8aaf3faf8007971cf8caffd066f487ad44f78acc4aa17c20112144f94a7418a692f3dde011badafd6d5b96e7bdadde3506d95e866b9f74a3f1a9238df900566b44f06d07dee7d4f2a813c2a441eaf27d2a2e3687d85ce447ef2bfa577a537f5353fca51511fcda1c18e3bcda9726258120a0bf30673f3b6d5bf1b2bde36d2a3d9598da0ad6cf2a0cf90205f6decb514604e8001cae824ab75c9cf637e66434e7afecf5f497bc3fa78e6478e7120185af82e675c651c68eb48c5b29b6cb983261b9e2a53def469210a9186fb469ad80c720079bae746042116e0dacd94774306dd764e83ce6b387bbfeab6d9392f2f3bda9a5f565b873861bea8f1771cef6dec27fed9a9a34a7a87765f1d937ca048c3250f5cbba5946420cdf4f2ec69dda96f10bad7b1dbcd68876724086d3fc1f030e71e077de6dc4c0ca92a535e344ec33076aae12a63175f80e1ef95af19ec88f8cffb527422d6ef3e67e3b3178fad746076e68dee1bfc10d95b33b73bdf1fb486104cfcc80aadec620cc438338bdbb93a2bd48eedc92e3562ba4b9bd67bdff768d78c83934ca3ce49c2439c1ee38144d42ff6d0e77fa54d0c684c0f5d2f05a976a7fbebf5241d04b37e4d4040fde9693a34daab9a3e22a375c6c2eb2f5296cb4b1d6f220991a5e68b777445889b9e762ccf6e3809ef5e8ec49f7c7e2f8f7cecaf833bce3004bf98693de2de64fb070aaf958d282348ff980a5879beb9f1bedc137e2478c0f68a75cb20d0689b26cc2f6640100d76fc25f5f0edd410ba3d9a4fa4cf92fabb3ddb00c4b66718ea99159087d1d9e2820e87213526d64fd22b3e2d6749e4a988fb76a1bc290706e882493d858de6f4efadd487d377e6f6f4267a2cb5a42a388065e76517346314c67769a57d850c0f7eebb7eb274fa3b5612c3bafdbbe1536626e7d06913e6251f12b0387d82640a40a86f140b870fec3385950a69d6fc91bc9fb77de6578aa4635a9857004eb50aad28925606d585d20ad74862ae386934f905c47c1c2d044af45ceb15be4fa1ce2df00bbe16768bfbb2236ec62ba2d6f546f5273a2797a20bbe55b266b8b79872e73df7113f9aefbf0cb6caeae02e3b587a5b7d6bc55279b566985676a6ab0bafa36038872371fb7678fce0db6792b76ac08e5f598196c30c8749b2ffbae466d90faf0dc24ba7e29eb783ca57a2bf5c8fe7c8ee4478b6acd3c2f96e15a62722dd4d96dbd598bacfae505f422c2e32e24684cbf6e5d0829001c89c2ec32d9e2fea38faf0a6fbb6afa43f066f7f48c50e8301ba4bc6e1c71ec0669d27b746118e5e40a0cdf8e2f71aa81a1c75c323ec8b7d047841a20c7b92fe759942c79fcd3ae7fbafc97fd0d9f3320ca7849f631a196644e75bf560a72ea1cc08ea6a5a70487320f9b89ed1dca36487196fc88dc4f3c98d2f501a0b8e2161abfbe89400b523f202d1bb0b022eac2481dcb3efb987aa536195371048125f807c90bae718a3f73fdce794bf671e3df3c779d5f95b830d27325744d60085451b090551cd846c8e028366adf212dbd85b7cecdf854dad81121e7ace0f1b0dfe89d22ec49324700d5db66ccf0b8ee398dfd70b86cc315833e2a7db3936b1e276efa033155" + + "bfb2f8e64e4cfba8a5d5b956a03e2543796fe4b3476920fd3613c1e056eb299a02d3aba3ba2ef66948bccd530abf5bb37e8da9725de25896184635d7f1f4af44f073d124e2fe7988af57861b9ae0a90015395c429dc18f5ee90c0765d3995487178b71b427f152c37da2cfe14036d6137d97937746352cfb481a913b25c106d4fde9f614074af05626487f61d349d6fd0712a24fe9c56b5f5ab1b8386365237b3c864d4e017424940251eb2d54bfc58e0106a06999f3ef4b88a845f99b44ad5cc967456481048ce71f7bb08902de93b358cfcfa3f0ca9333c6c83aa77ba8b8762013f5cae34e7b2676990c01fdc5f619f1975ecbd40b6a6371ec3a4af3842794a093ac1c9b73355cbc5933ebba0aad104a6798eb6dad32425629fafc0db8bccd2b1f84db338f8828ff1783b633239c589eaa9fa1f045126a5c816cac8414c19d177d7a0b3da01815f9962ea0a0841cd1b428ac38050061a879fbda1345649f66703b7c7dc05c4c6941a72fe5a81379efabef69ef1f6473717c870dad980a4f5a2751eefc71a17dfd6728e7f0c293ba9f855d0bfa33e8c1fdca2b22898fcbae89bcf1038de58533c183bdaab094d537275b92ee0f38b46f01818ef4fb9156ae6485e11103e7cc4c21bbcbd2720fb61147c8fc739d323a25d1309b336cee39be4a354f93a4275b6fe153ab6f5f44b6caa7197039e23b6ba2c83660e7de0f73f939450c15f18ee31f8c095a0d9445a39912bdcfe95380cc39b483a6613c5f0bddb5ba6d56410eeff4d0d96d5d39202d1b789f33aa84e39b6d93b12f8aaf7836aa1ec792fa3178dd61dcd421e55b587451564d14ea3fec931b4198af45d66c98885c84376817ebe1ee08fc4c5cc7054409ac4e9745445c2a3fc8083f1c00c94b3ee2ce606c54373905e90fbc67ffaaa37c32b2df6d0758e2f0e661f40a21c939296d4ed4b1562742d00d4129cfef64862a1fc3c1eb910dcff20b08eda8ae77a4d8a8fd74ef5307de90d6fedecd89d11953ec718081f447446568e5e963e4f41f4b8311373205918e0d88fff9de755a59cf04b2d860146aac7d49ed9878d8756e4c86f1eeb83e15d4de9ba4a619a9c51e770b433c4519cb8ab6ad562da2f448ea4561e13eae4371e71b0cec593f69f3114323f30c7a74cee253bad994ac3610c557963ef49e64fe725e98a006e71d59b1ee395319e7e8ed414067440a457e90d2ec467c432e24012e74ea74a3652819909da7036bfba4a138eed2fa312b5f1eb6de40d5ed2d74266c220542fe4d85556220fb74c8d9510327faf768a047c3083482ad95ab1f47f09aa7391be806f6dc2016bf039f60815cb8b9e1469552020ff775c7c4ff246780fb5904835fcd02c8e902fa66b85cb2375228e4d24b208836399807aab7159f3f1976f28bd9f3e10a90caebdf8e63312b00fef5999d3e185067c56fa4ae4d607ed425d55337d95388cdef8cbf9881b07d431b423c41c9628948ffedb17e36ebb929bc5ba7af780518461ac6749d97247a253e343efdbf390f29acd98ac87ab83436fdbdc3dfc2a385f1ecc3ddffb206962525cb42c8154b19196ef7918b2e664edffb3a90f8c1da300a3b03850fd3451affb0f70a022abf7ee6212855bcda138c79aafa54f2ddbb54580f0b209feeb17ef20ca0fc9af2be68a9b0b67e8df93da7aeaadbb602c7fe9ae1ef1083b03ba089feda1dd797e9d4e7ebce47b6e49e584e3d36f1330809d4eb5ecd255c9af74c618ab061b4a8748714bc3c82386c53ff675a7e91fa0bb1b118a22fd31f88a2b3e4121b39d029261a93e3de1f0abb800cede0d4ee338a31e469a853ac338ec7a3ede7b5337a261ab470717587cc1d82595d1d29feb5810b405613dd396be3594df9fcf52c7f463e10bf2daf9e6c1a391a25884a05ee6a2ccc9813caecfdc82711efae4b860df67b8ac62bc6da2d521313b8c62d40e570befe2742a5fabe714a18b792cb73af258b5d57e0d74be479ff99f12a5308a7e4fcc3014a82980d47bf34b889d40ac2155310f8587c8a6c7308573cae57d8145be9fe7c6ccbe902c56f2ccb5428a6ac05493385e5e80e549b08ca310ba64c60ae359e19a8c2528faf15daa0501c1e784c37d8c77f19247e7742592aeb8f58c1281e75cc659d15f73c3d594da7c1f3d4894281fc0a364c84e7bc48c967e13dae8d636b392da1af132ea10aa6f792ec138ba67a530f498d365d5fdc0a5de1875b5c09d0ebbd53b315de4c1d8e90645327162f3bf15aff817da2f7d2f3bde107edbfb92466814c6d68fbce140914c16aa2a98a9a368f2c4be38cb26baa64e736ed3661dda53cf843fd6634526b8a69f1ec4e3c67de5004d80ff5cdb2dd05f69e9eca5912f03e094a60fb58b307abd439a1fcbf69d574d3e81c0057effc725c8807ffff4a37f087d85be48a28c158fe8c7f6c483cbed13e7aef1e1f2b579d5bf49469147eb9d764c14b04a305c39d754de5b933b7553f2d3e2c02786f6db6a251e1505e0ef5f8345c5411e9038b61aea75a4179b68e4b1bcb3b914dfb671adb00864dfdfded512b3a146cd11f8f586576bcae37f8f36fdd45c698252fbad57da2baba8153d442926a5225b94c3a680e3c0f162d1f37491a15d6cc7dff1795aced01679142418911ea0eeac548d844ce52210900a181099ad554f8357cb2581f83e94b343c90d2623c8ad36b8dc245a0356c041009826b0a5ff9f75e58800d0386039814279dd2ad9fc79bfa6214512a6ca21768c0138c2f6341c52d2bd13a6598bb0ece7f11055f4f3f9eba5d8de596c275f995371211a6ba1a6d02981c1ae2de3f9726044c56ca74c711f30a956777555b4b98a70555271b20ca1ffbc58ecd43162a24e75ca29ccc272fb1c6bcc9247ea23242d056268b0335d53b707ea48b8fe8eb6a2ca77cba6189ea6747fdd4dd99d572502b2a3dc5fad6e913901a51b9e466a9a043edc69f8f773147954c757200b538753e6d2ee0c63496a8827c8b9e051e2bbf092171bd508e9eb88f68f2076dc1c7a34c1539ce9bb5a9b9604bdff7806393edf44fa21a42cf9735643d2a4fae46363da61f899899c1a8a9a8e0d6fcacf0c0f016dfc491f0350bf3bffd8a0ff8c226b2427bc161a661fe4721081c74d0b71699dd858d2da2c896f5fe51ec432ca5ee396d6e7aeceb6309d30fd79dbf2831e75c7e6f20e9b0287b25644436b62003f812218a6ef02f3c49a0896a1cb286922494f29c1f58de65fdf8e32bd5e972311065ad45479b640e494d9e0874db53b4e08f8e478dd919479f6aa3eca43863f31836c879c763087642bcb231c88ecde7fba0ac3a6fd803256cccd4d29f581734570cd48d3468dd31e9e51695e2e21b224da3fe63c34b8ae52efd8076a81bdf3fcea4bb5b1afcb280c5004d71fb181bec19f1776e94591856973bb31d3b79a8b0976213e876ef9383707da61302f5c835ddd4353e30645602b66fdd495fffa64eedcc181a0f8ee950dc83555089d6d6950253ba083d7156f7ae07deb57a25164a68e076a798f1b0b3650843b4cc818fda3c98b38670cddc53c85c6f452edb99f3811b774fb09f8e258f0b5b09a0f753873bbf0606f6f26f2acf9458fb76810dafa36e77fab8b75cde898e35bddfafaf9788a35f4034d31df099429b5d85a0f7dbbde40384c540ce99c7fdb4ae7b5d865d292bbfbb0ad2adc2ee48f0c551c14950edd97c2a3ddb047b813a3e3be52049956d37e9cbd8816e666ad3886f8700ae41f2fde041f706559e95d38ae5c9da47b1f570a809d0206d67562de3a1e8bfebb619d8394320f713b272988f41ac27b4f7f5483af72096544d42bbc81bd28eb55254b4eac3edf617f94c1a09a736ed086c8f1092df4a4e195a5e61660923963de43b1203d49bd1f27515950b17d858e97c2af537494267210548faa8713466064f61dff4b2408a87bf8ace61b870d7ed7bddf7284f4b0ab8d85e08ef42cb00725e969078a01e4483ea7bcc5f20992a015444367650975d64ff2093477efc3d7fa2de52c1eca53cf8986d7b81ef6807cb062172139fdc855d206c16d5795b6f75605e7bc0d59c63efba4252d008c732f1c1ebe58b37126a77192ec52fff6d3715c559f4e789fefa2772bcc917236e7cfdc1467f46ead4227e4f97f7c425e3129497c55e77375b682a4576f0fd2194ae4dcd4484d0f8f4ea974155163ce87627179eab5791e219320488bd2721585e3e96841802f66205f22094d9218c9bf347c8868af2e00e691741f65e8df5b75d2db2ceeb0813bf7a3ba5c5e974a7c40915081b5abb08832ae870dbbdb42f87feb970ba0269f65673be2bca56b585339db162606197f584823fb6e532499382b77c6b386f2de41b0a427f83194658a04d98cf2040bb9d66c7832e109a236aa8f2a22f9d2c5b2a2e0d35dfe764f346aa03816e2d3ba0b24cb63082eec815960c88c455f340d4082c0c413f80c266f7bba8183cb2e44f48c701c482e465a71632a0df36f1032807b074d481d2c3d5dd2695f29274e8d28cafb709550a38fc3f5b70b09623eac0c9afa78d988736f172fb35950f439397da60ab8297dc013d9b7f82272396d2e1c3ac25071d8174da48444fedb9406a2cad751d20d833e82b89bdc5e2a149c87b704c4d13b1360ce36661214d364ad83e6da6f514dd6fef42f4e077e6bb2d3525f058bcf390c6e353140dbb4143872973106a00e46a749aeaa153f5b8e3c81535282eb3ab589f683ffca562bd44069312754d7cab341e2619f3560753b9b113874863c5b010fcba02e96c13ca58a0e82c348fc0e2696b64db2c62a6a36d74c557c3ede7c483898ade2090483a8be28f19d654f3aa371ef60f8e4f0b9fd3febe37b3bce3dedb2aae0314b96e6c2b2a034c636d038b2de6c202386646140f6a06f2bb3ba77f5cc584cc81865143de4183fec60859d88e91bdfa9fff10401d854448813b9880c7d677bc68472488cc80ba534a5376b21f80cc46b6579722bfdb59258ca8f31383ffd10fbad0990549dc663c6cd18bae014b906835a34d0b22041e47bd0d955bed52c09219721532782f594504f125769e8f186567d60de6c99307144e41a36cfd46c8da4c3bcf5a9fd129db21d9d9ec80ef1cf67b1af813f3621751aed640eb2a0a2564759e05d444a9c92602fc7521e1efc8914f3b7826f848829fdc11c3e20f1e9d695b3447f823691c080df7fabb66cc06dc8976345e81a148a56b7d34f09b97f43e59bf5d1c8cda4082f54fc886fe92f674ee706a0ae1c8a0d4a0620686e3d287576f5d848ddda55376616dbc05e508c246d5643d2a97a0016dfd80611db1be4cd5b350be1846f974be25daf5555968bed5c93ea8a16217639197bbf9d50a7cc57bf5577e4e2604328df08ea48a7f2a44b47a6bbab43fde8e37fd5dec0427d373ec2408d782a8caa30f180343cddadd034000e159ce04499a2ae2efcf55a54d19420d87a5b03868fa48b19ff7a3ac81ffb7dfe3b9554b8ae4653a4bc51383df06079e95f6e553e5680a47b218801233219ff86120b472f133d89d3c1be40f53126892db21d8128d30d9a67ca4958d21265b8a3835f060f4f499146417425d322990807ce86476da924127fab38ab2ea7813ba54bd2737246714b4a0a17fc014a4084b73aafb935a6da065658cfe436eadfad99fa6b92246ea1ffc9c0e9743506aa05f5df68d43deb5265ce6d8c1f79a69657d1b52fd8ef0078fe77f2a26532ce84a5b5a22ad457ebbc953e17b2cb47feec209025f54049dbea1fd79bf39462c265f2f0c27d5b842dfcea1fd173c6883547c20883c74e6778abd2f1ef2df9c69aca084329c946b2ead40ee4f1708f439c5686fbac228dbef69d080b95e996a09b8180e756d67a1693c6b1cfa4ce7916ee4aafe7cea281d2c6bbfc756d476e2dd965fbcc924215daa33d5f284078dab0bf52353523f46f286081a098325793deeb5b86db938a8721399160a9f250ebec36e63237a041568130d8ae7f2f80bc433a6bb174852d171abb144d17e18aaeb74175be20d056570b632b0cf13c5da162acfde4b884ec7d7888823503e96cb5633048098431cc91f26f3d293d3b925b18fecac4f95b2f544966b95afe2f0451b6315ac4777944116bc3bb6342857c06719e1a0a698ba3c1d49ef4fe5d35e92fcba73a5940087ab4fe58c9b17db43362a061db31b4a14a1fb1020a717ef27ab424a1f65998dc5c221e39238dd993782e4a1654b34e4e66b485defcf4359d835c5f7d7c5477a57c556e2f6c7a18bf18a0dfde8f2acea81a47cfd1976328322ab0e71d6c0de2fa88430bc6d69e1eef8ed700ea578ca9d304c53475780940aa2192843a45dd60409c19d97a21897a1ff20003554936e3a76a173da88166060fbd3cf83aa562f0a7478e031072b8895a7cf5e1bef24989655033ba12362986e1e3f67483c7619028fe40edfdcc4c5444b6fd0ab26b8a87d51b88118f4ff73766ba7c3685c63b7bed819104f70cabbc29de5701c5cce446658773a0f3c8d530e9336f7c728ef9b600f2d1ba20cb545cfadf756c1d77d1d66641938e35ebdad460341ec1e466dcac0bcb6ddd6a462f77c328d982dafccb26a14f2698939f392d1d26558a4ca94353a32e1130a40fb73d43bea8cb9ab8b98cd393e24df88bc8659508c3f31b6a8d6930ad292478f581576260c2a9b4692f2e9d3381b9dc4ee04bfd5d80740e64260d5cc69b9e48a2995a1279256144e7356d553a8e1652110ed808d30fd4506de4f826b036cc265a22afb372fc63e4715d1b43179c5a56bdbe92c4e7b7a4315494721fddf4bdd06c9b491feb4e9999883ca4a42b8c7bd84a59c25e065fbe4c9e485a36459e9481a048970e3c38ac871e16d558978a3dcf1ce48641d20dba8137f684ba2b218cf1da4a983b593567b9699adc94e1ff6e4f0284b2b8512fb3d7f5e200f99ba3494bcb3568828d682de2b28cf7a72d8c71d3327ef00eecf006daaeeca5e25a87b4fefb5cb20a1dee822e498e2b8abd9012fddd063ce938d7779882f576509d2b4e73caa0c2ad571aaf8aecb794c35e39b634f937661db46ce2f82306cbe3641aafcaccc0dbb4612a98b47993008ce759c5f6b7db6151d67f33a37e031722999310b50143697e8babdbcab9e1621bfc5ee99bebe750758420b58da87f9e16bf37bacc9d038f0539c8530d60080322547c4bc043e3303a7f1a6f2d0f0f888641f47be539c5fd73954adee29b52713406a3ef8a384d7fcb5da4c54c44d8af5ed61b0f162160151b66104749b7b8ff3e37fb58a39defdde38948180a0bc12c79ca354b557556402df71b1f0785e2593caed9808bd392c7d452e4161427d6cee64ac772fa978f4c2e0bb73f51c37f39acbdd9453e766b2946300760c1194eb3440f509fd3fd389e3b4c4b78af2eee613e5aea840488548a70c736ca2fba306084ce708c1adba13e7ad303df3b4a8b371395bca34253d4ca3ef79a7f03c6feb203c99f13f8a760aa9f204f1aaad1ff3dbd2fd644fa94f1c63f9f39ec48a7099c5eb47a7994a60e01638a9ee78028c64182e1bb6bf71f669d76c185f66152f4bd4498ca85e40ae9f5367b66016beb65c2b0e8a89d47cb4587bda2590aa21cd69f3431eadaf4b660a2bf89b577821e17d194b2d37553c29ddcc2f5e39cf3c36506c2ad36875dd2d68825c57164fc25f9341e679d2d7ec0002e5c0a2cb4ecc861df2466e223681f3db199b7b1e11eb24c2edaac854d9b2929db74788f8be7d5d0697e0d8c9cd21cddc45db44e4c5c6379309f5685deeb060a2afd4f80d200c80e4ba1aabe06bf99f1ff2188fc6861a178d830f02a0aedb8c5b8d98319b80b4c91211be418eb7cda8ba7946b81cfd89d510192c56fe5af00f01eaec7554c7bcc7d7bd13cbef42ae195709f461af2006ad661baf251b4f2a5e69a4216814d853d348b3881c3609e3f16bb8653a4f5ae3d7f8af302ea35dabf794cb3c62b382b70fb4fff89f50f846d7d08c50c0690486abb3783a1505ac4b54258910d8c1562ddcb25c5692c938cceced62c0f03bea47f44c93eca3bd910eebb98b881e7412f01fc7ebaee7e6738b547ce8e9de2e9f024a91885f76a166ba0d30b56888a1ce202b12e4c09e084fe2b2412b0d86a2869cd8607328a0ed7fea478a551df672dd80fed385ce048782540ee0f387c8d32874d4fb2b38bed64c08a7761ba86c7ea0f2d496fedcad314553f29643c6d6f9722c3c4ec67937a482ebb68964a589b30180fbf3a60c7a89483673b3c5ff1568ac3ec468a233bf696e768789b8e3bb92dfa391baea1851898764e94d8e0591e7256c92e3b70012aaa4d76b6aa6792a8d266e3f0d8a07f90690bd0fbca3fe0b0c08aecdcaf1bf2157a0ba9c4cf9728991b2d0ae0e19abbf42951125486932630b5efeb6c9bbec6c3bd32811ac226d96c4676fd5d79dbb07e315bdad503b940a3afa963019f56cb8544964ca71c68d070897870bfd0b42e412c759dd764eeceb53d8786fe0a159c7f02ab4da1995d9396c0509a53e7d3e7dac99ffe577f57723020bdb673c0eef7db135aa84c8dfef8ed8cae4d62beba61121a5df71ceecd5d99f1ca80bece5e288c758eda15286a085cdb2f144c247bc600fa30909097693945651da0083f9ee9502f8292f9f738905ac0fd0d96463b6a43dea79f9a03680d26bc80effa139135e9d0b7ee981c91a25cda6095ab21f5ab97f07943646bed426251bd9fd62e2d1bd80371b979d2fb3ec9d63348f34b33ae16399c6094121d9cd241b217b6fe5241c01a53e2bf30fd9057b8dafc99cdf19960f62ebc89b1950be59ef98aa8981983c8d46bf538e2c01a8a54cce3b8fbd09fe137b63c100745f8ce5aaf97b8d162399750ac7ab7a813f2d489c5307000f108da926317f866e7c7b1c54322c3ef4aa2320a574b8978f6ab9de2f5624d04ea00e5bcbae5b69bd7f261e329c181e48f371ff718898c158c3eeec3770788a377f48bb0710969d01f47caf9c59f3cb4b1fdd38f945b832d837042f51afb22752e5fe4744a28a24b2f7c429c50c1fbdffd0aab23f8c30fb83df2d606c9b771cb27ed7abb18e36bd7eada3e04fff2c695462117541971431dca56a2afeddf92896a6d6e26c3ae5f1d7558dd7e16ebb60c6b0ef13897b6edae11daffbfc8216c40c13cee2a11c4035f3312bdd03ea975b3806f34150395153b32e1aacacdaac7f46a1f579b86d96cc0dd349de5d589e97ba808e264406606285586d680292b07f437cd758ad174e5b9df967b69c6f0a5db80c604d5399a7ae1820daf5b3173101430b88b22380ffde73bbb04cafa6a259698dfed1d4c896dab4f43a901e33515f892cc474cb7a4e337a3e446a986e2120800e53c726343106cc6fa65687c9831015d8be90065d518d02e52d20f7f5ad10763cb6edd3cb9534fc0cd8a5ad14e319b386261df741f39756f2a3ccd263271da46b1029b5e5ca753515024bb50a4727e0eb75b0c1d93719cfbf7c96b0c3fa3e07bbc4af3910e3b01b97434358d1c74c73058577b02a59316dd78e676a7d7019cc81aa4defab4195fd0f2289a191698f21a6b96f1b92a35339199e6ebcde89591c862173bb260892fbd8f0b179f91519a76aad1d5f50378c61e677adf69026f346ba83437e818960da9390f5c00fedb9b56fa9586900cf2657e13ebe3abc7e86b37e5314c6a759d1b021c89094c581a1edb7885036df6f45b29d314cda8b34c2dbed35f84cb885ec80dbd8058418642cf8a7274347934a3309b557fda7b49691c855f8fea36f2b7f38a03ce7cd4922341993debc889daa2456539ba973e98474d4ccb294b4d63d9c00fb5ec198fd5da439cccd89c6843830785a6ee1cb7397ad6e208b014841667e9ee9df47e94e217aa58cbc52b15906a1051a3a574330e28d83cd9986e20b68a49a40f8eb128f020c2df1a6448e66fb1c5216276cd42b371b400d4ae51f063d9fe42c3a93231ac8b50ad24744eb4b44ed11064bb35aa16da9caede48f56d3e8f648e67b84b2a19921999994c42a59973e844a33edd67c8bf494bdc8718137ea82e55164af30bd38f5c47a59601a91574ec612ac5a8fc56eaf96141784d8f8fe59133cc39b3c76771971dbd5cddcc6b63d20bcace1d56cf95734b32c7ceb77577395d87c9f884885c92db28b343cdec25675b7fbc93640d7b11d319730af1b4414e3c5697e83ef24f9563fb45553a0fdf5f6ef449585615f3af6394288827289b1b1901aca8b81502c5b5c4081ac914047158595a5694fd6fa4b0a832828d4d60fa8bcbf48be1f792e5f7588fa0ca41f204ede8c56c8f4191e2fbae744d0a7e4232d1c53a3644170f832efe82723b50e2a79bde332edaea3e425a4646004ba98f3cf9fc19fd23af7ff3e1c8cd23e0983acb22d9d11a6d882785a0b3bf238697ce14b231a2935af1f1e294d43bae6e8b1df1d038d99462fe53e61b79a3c1ec3ca8bb7b720c427047fc2d2e3426047975162252bad1d00425afa3d4c2d3460b0e36c335b8400493bfcf5be7f4ad773b1cdfd1f560e1d53a457f901c1a58a648dc972f34ed9fa18ae7375a0633a68407b2849eafac02df9c28f299923fd55d8974ff5070a5d1a31cb96104d89c909b510b9aede6c9a529a9f74acde2a5b7d8f73d5270bf6203beaa88e71840c3953b06b6b5fe6f43a13bc1520a2079db18e26c89018c394f8f3b1d4e6529744e889cfb5df5d9e81e4806aafe904d6b81accce5c1d2c6ba8f3b740bd080a496c94b4c50c61c4efd2d2e49b7e435529ab77b8cc974d49649135f3b94d6fd224b94a5315343bf162430fcfab5857adf2be6579ef5689a3470509e927cd716b90529c68776afdf3afeee316017e33a1e759abd7d4d4b05faa8066feca343e99db2d9db4236c094d77f9176b275e11306dfd7d306255ad4eef0b74aeec64ba1f5b96ea0e38dcca3a9f7776af5c3ab7903a301fba182cc969d3500980dea8c71dde6dbdde8cd06141ec8587b4b8cad2060927a910628bf9908da84b0e6b25a361d6ba8bc68d1bba60071175d6c257893e421914448f49cd299e5ac91cd86725115a500de7d7862bf7a5067e1b7c2dba9696029950a28b00b61e57fde02e6ca8bff3d0529e82f2cf203a047c0a163617c4a6556c35d71bfa86559647b6e38f158bb99af519f47a51a30843fdf06d287d05591aa392126af65074fb01f7778f8346d983287432002b98b6bf9a58f428ad02fe46289deaf8ae065ea8929e34f5ca42b0811847cd6750004604547636918b72bee8cd001a42908e3317addddbd46eb198d72ea3b5874553abc33bb2e1f733585b4a4dd1fa2cbe1d2eb70a9b7d137c90b5aed63db4f4e2e45fad81f865427134c3f482d358cef2c821e34d85aec90f45088eec523c174ae1e7e86311f0b7c6c9f27550a32d93e05ddd4f85aeee27a9b2cbce548321bc5afc25bf7a6ae3b5b6dc385e398f9baab593e9da0d3b7d7341bcc054d2b8dc67ac89c6f290357570f81226b2871456fe3ed29bd55b9db4e6e4077fe5bd58a6e3b846beccff6cb2fc57f66076aefdb9e72ad0daa7d3faea861a160de98d91b57c17fbe729bc3e213640edb54c7986e5bad11cd606f636c56fb2dd22d63cb931612844d0ddd68f4ac628d6aeb83d4a87c07729a3be8705cc0a5172ef93891fb7ab5be09f5df836003c5b9e1b599cf9514b51094e838230ae2701ed2f2230b0127932d260d2b010992a3e3121d7a3d50357febd311512d4debfeda8562219f10ece6d76b10f04b67d713122f790aa97d071baa6d1f6f2a4125a30cfd2963754a08c7d5ab4b747bc13ca503059e5c10d0c359e237fc582e750537d8ecb04318e6c4db35d727b29a37ce56e812de82778995df40d3ce628ca8fa8f78eebd71d48e47996a70fc8f2694c7b8a33f49a6dee3ec0974e6134ac2b514dcbc8c2603e90cc872d1fd6f86f61832e445856b0fe66cd822dc99a3dac666b7fd8f8ef0ec00347600ac01c4bcd6c786cc3ee075bc3e520dedf2a7c3b2d11bafdd77931aa6be5a736f40e16665925eafee386bb219f42cc3d130033d049c95c5830450028d36d97b56d577e3e4b115fecf29831dc47b547e3830799c787cdc3c49fe04c84da3a7f2d5a8143a0ae7bee6c15998288e14e11ee669a46e07014c827c3ad44f84c483b81d93b63f5ac2dab4500678789f71abfffd336f24a8ca8b5351cbf06b23a20545432725b8bbb178cfee7975c89f0ded3e9be159db624748632b72c98cab4dc3515db0e559ae2bdd5e11486e866ab388c40e7a34add6d4a9fcda95a1cbd944356fa81efb9bb7c7a88fe92cf7568d9d065956a8a75a190f9c1086956ed10ec63b6014b4855d789fa0b0fbd41794bc6c6904447bb45f10d1ccaed311aa8ec74f2338c494580f2a8197c72ec72be26dc98040ef046b6ba184a5f170f897c38061480bdb8f3b5f1d2d1da537215b0239591eeffca21786b93fc42590989dc478cfeb50c80471b1e1313448b59c81a06e46836c89a72463e09b956de8438211719a6490e7f1fcdd2bfe95e9d8fd76fc74965ec3605cc0133608f26c1d69d8e636c6f5bfd7824fcbca7124f07aa601d54e9250611e65aed2f69cb6ed9f6071daac0be1922b662aacfa7c22051b3953c97fdcc6fc400111aca97b19b28bb2614cc61d3d875d27b82d73c09fcf29ff936b46c8eecbaeaa6ccae08a23ec5330424087a2960e64c688e6a7f8b6ba6100e1605bba923c4dbd532bf6353cdae7e46d30299900c23581faab86ddd3e8ad57657fd8674deba30c6acb6b36332bca701774a86e11f227fc65f958de5ec2042bf5dcdcbfc5a184a163e9ec81e4d832fb42f0430b27a9bf7138f646e646be7a3ea1c8c188e470249166bd6620d1f02fbd0d27abbc357349b76ecb17dc128b59f11045706042af0ebf0c4322ab7c507bd65b80068315eb090d1281b7755cf571885046c6ac0bd9b3f3004f8eec8488227b7820b29a4283db93a3cc7c93750166d55e9eb979100d4702a53d7548dae7c0b06faaf1857186d19732531fad901b0eaef50064556d2c9d65d4b8917a895a2d86feee765b54e8734771b43ebaf59c561c8b4fbd2c763b01f7797a6fca91b362a2bd45249563dde1eec7b23d0093c63f08d86fa75f66f45a9a7623aec153960666749d1943691b6536a9ddee7f92dc2471a1abcd9532cce3e716b6439ac928abaf3f7b4883a68c817393844c25f33a41f27790b800e1106ed82b56b56cab1b308c2606e3fcd460510a13ee80f57a30095003c2417f6816f14dee17b2926ef1650a6faacdd3181937b8058ed76bf5e869bcc9c8b01e9a528d559f78cb574d5f4c4912e7a8c4d2157b23a82db0545728fe5f4f27e75886e710f83b607d9925c7461358fd1f5aafe598b1f0794a340bc4e232c55372b2913ede045e7c2250247ce05a6aa7b58e425f2ed9e66095cdb756a8b846e1c91c2f2f55b0ddce9cd637ccd8412753445d2eb21dbc6db4e6059ca022d7c21cf47f3b646bedd5f626f42ab1247372c0e248839cdcf44c3bdd3f824d33b0fee7d9f5a66ec001762692ef667c263f59aacb7f3dfdb44224ce0049008b2bffc9b26636a8c0d4ab48a95691b24a6e805d9285b5a25a3d5a623c2ee585672a4d86cea9baad531951294393757d8e3d6939baa3d075b38c511dfd8fa746f7b21da0f6a5d91126a983a5feafa19e3852c40c4c8ac37da8058bf8edd948f459bdfb6557de291e86d9e1a5dd080196c050b1909a1cfcb812aa6785313b40d3574c2d06001b802eaa4e191b1fb22ce5416b366947b8750758eea112139aab6335cf9e80c98622b012a6833b770fcd3f9a3d4ac32a6b7a33d2cbcb16e8bb8eb79f05a77f459bfb61895ee2f5f8d5f6570ae2b5fd14e576a45e1e0eae5035a5b635c2e55019f32f1dbb2c6a4fb06b3683620bc9a5cf96f6de27858f99a06f0059b274c8154ee11be53b514df8ce57084bfc7d1032d6d01a8046a96d6a46755b45be3984941c1c7ef945b33157c48f9ecf6615596561f3df29660f05e78c9f200ae4e4161d0297c9d5a19ffc791706c9a15fe8828afd456269913bca88201c2742adf928f4ba8c5bed78fce63675336c54016e4acadc2c40e8b60dd0ad9db3ea4d8d4346d68ef41290b7cf842e2c69c0c41f2d050589a04765910ac0c2fe13b711a9b5a3b372a2cb5d79ca54b98e6d2f8c085e53e29e0e4f0311f02719968a72c5cc98bb16a9686ea5d4bb991f91d7f01f5ca2a56fc0d5c40a5bbc1e6ff0fafe400d7e809671f865b19e07db280b155fef8fc04b79a0aa33ff79e422b9a7aafba3204e79020cedfc24b85252b4ef7d0fe1f8428bdfc29957851b44daa36120bbbfd4155a8b41ad9526c64d0ec6745d4fa691065f157a9e200a10148b9f4d47d8e35229a408113bf60f1b90f2ecf77474f63398fd631f3f1644728efc6c891d83f5cbad59019809b4f0ec7a54c119785b9ecf8c16346a643c96e12eabbcd67341705832e999668c26dbd28464ba7010bfbf1a51758c79c89f325c26075f3626f97ac6fa914d8871977ccd7846323cd687aefed6edbe2881d639b3bf9f14d195790b7f55304104f5a7dea1a5590ffe170acc395fd5cfa4f6e6f9b09312862f333614bdf81223378565d8c2e7421e23bc4e3c50a2cd7f8dc588463987598d4bffc5584c96ba16337abe2537361f0642044cf109c5ceaecb2e94f2b8a04952adbdacc809821e42ce1e0f63a6c305d42805254624733c429ab8648e85b73b76d5b8cf4715e65d55166426202aa7ac5b810bbd1db39bb5b25d32b4571b8ee338e05017dee145adfd0e8bb03f9dc00d803c76feb61c204140a450f145d299dcd49578cd5117e2f8c5e3b63019edc8a48221d9e1ef296d979ec1ff02d2a3fc3da4e797d8f7835d1e8454440d557e3f3c6ea17904e7ed801a7c836ef9ce2b77a5849956ed1c3c9764f3da9c416f33a298ec12d28ad56513ed856ba38302f04b452f9d1aad4a5c130ec792e45a34b4092b6749ee8ccc73098641b988e77d2ffa328c8ef8f0bfaf208c1cf3f685801d4eb5f061fd8df7bf01475d9b112cac342581c09ff9bba4d77950ea8130bef8e07428cc081791b7df20742058297ef6a4adbc158555ff011a9aac07e8dc2938bbe6e543e25c9806ae86d0023a4cb51d81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac8"); + assertTrue(Arrays.areEqual(expected, attachedSig)); + + signer.init(false, pubParams); + + assertTrue(signer.verifySignature(msg, sig)); + } + + public void testDeterministicSignature() + { + SPHINCSPlusKeyPairGenerator kpGen = new SPHINCSPlusKeyPairGenerator(); + SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3" + + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")); + + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.sha2_128f_robust)); + + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + + SPHINCSPlusPublicKeyParameters pubParams = (SPHINCSPlusPublicKeyParameters)kp.getPublic(); + SPHINCSPlusPrivateKeyParameters privParams = (SPHINCSPlusPrivateKeyParameters)kp.getPrivate(); + + byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); + + SPHINCSPlusSigner signer = new SPHINCSPlusSigner(); + + signer.init(true, privParams); + + byte[] sig = signer.generateSignature(msg); + byte[] attachedSig = Arrays.concatenate(sig, msg); + + byte[] expected = Hex.decode("e8a1883716841afecbd6f9bd8648bbf86ab3badcb227b624633d51913eb337e07b68834818c993532f90581ff8e26477449fc5f0fb37c9d8462bee7d3f5825316afbd4c9a2a266d71d7f8ba4db064c665e02e7aa0d1ba9bac5d0ac0934db69fa09fc85234a701887cfc0af912c7b5d3186c0489e593fff2e9b5c79a0a77ac312aac4049d29ad57db8e86cec1c1264e819c5083bd03b4ac44b94be97756e2e4b491947a2103b371c1b54940bba71cbb7f9bbcc8eb90dac25795d1148fdbdc3cacef7945bf9744c966cb73cde15b98721440d2fce6294e77c39bb2cc37738bb2c2ec45a8d64a7fdda31c2a5f38e9cf17afe942470f1227e05b907ada0564ff9cc0e1154b1459f4a4b21485d901582c2cabd443635262c6a899e774e27d7428d980c77e2d42c15bf9f45b702462dce170042b696598fa8a850beed7517f717cb48fc98c8634296e3b8572284717fa5248eaca46c8b20670c31347b919d6569d351e4ba30595a5adbf887c8e971aed2dcceb4593ad18db1e5f9226ae82366e5c99c44e22ea292912d00aa6c53670bf6ed0e969c56a95015b8c5e0641885b4ceaf45bd2d90d5b93f5b0f63a8798a572935e2300319aa40e6435441b611149750638e3894e66e7c3ffc6a4f1cb37456a7c82b05e2b6d16f8365f05391f25539b835159ba9b775e85abda82d16d6b7b626f76bd2e98cb31b82ba8f18f0309c41677c2b4f5e822f255dffe17d21e7ecd421cecdb7e6a3f88e4d76fa0eeb3d7e9677c0c983223d029a025a147399ce72a13572edb7d2689b361993a06492df19fc5391a1e6e89d4d81cb5c3eaf1396941f9a51b8897cdf725ae8669f2b4b9435277ba13899a8f1805b77fddf5bd6b2d6dddf02a185d10f3196c571ab246bb8e3e1fc97b0b0b4e1c3e2186f6839b615c210613c4c3c7fd922d1907fedf6631bf3d1ca99914ad5c9fd34ca51ae4093e2a925c6a967b2c2e8c97fdf73d8dc3c6fb36ae587e50e0b31455f618811162c30ecbe1e2528d325a8c75afb13cceff548863c535bb6f72779fc150b74d33b4f98f7dca144fa554318cf48863fdaf16c73ab14e5c00580ff227803b1c8c383713bffb6144ae7b02f0cc1113fe2f57b72b93edc1e0c363ad4745e5a96bc61b2ebfe5fe1fe6008e734fa9382c0b818834e22611433ca213cf090c5af84a318cdfd038d8cf6936479d5b35dacc30be7b92e13920c0f80e5a6365ffa3b0c35ee637a4e861817b10b6c6b8f6532124c45289ddd027365e86e76b57ac42b6c15abff1b0426d1456299f9585b16aa0301d333837e751db28c0e3ef942d577655b70219353954384b649dbb4cfd8754d80250fe9ed859ab8d51e6c663ab32bc6c5972620214f3e08b3275829e1e97a19e2795ee39a43e56c1adab144951ef5b1cc1512eb250625d7bc18165a20e588f03075a524c0cac05c5da810632680e05516815c5b32262eb5b3b54851477edd61ce14d3238c3d02f4518d809887a49d148e84cdf7e50e0c06d82b41e152a5151a576c69fbc812c327d440b41edb75c02ab444ebc7da11143e440cfbda9c6c7916264b95692029e4c1bcbe56c55bcb2af6530131147de4a1b384b46179bce044dc104a3131ade59e4a1556e665d6ae0ba1bfcb433215d6b9d5be7b023045b0b49490685808b1a545577abc9abfd069aacd33863c2f5d0daf41b4c5af5224803f248356ca7c1269315c1bc4cf8256cda2e1dd2b1f227b7032ac29acf80732120ea3f9aa07945b602810e8aeafccea49d32e5050f248f72f3fc839962ae0e1443b46b586fbb48a2aae82cca180d580312f918ed208a2b6a493cd63b881a75e321a5622bf47314877bcdc9474019b5c64152e003d857b9eac87b3ea6c8f378592078326a4cb16d66caae17694b306ec4965f85a064175763ac9d4b457be3609188ccbeea07087f5051c66b5ca51fd88fb91a1dcc3f93ebb7840645283595fd3c4148bd62e8dcf0c5da4b89492222106228717ec8b473f7505defcf6da41c8e31965c76a067604da9f031f0b34235d7ef587748ba03cac0f104ebd1d29a44e0ac96c85359550a115aed8a8f15536032b6fbf4ac8239eb94391b2f66d7f001114457a938e5877f0eae1ad36ff6a853d96ebd8d5e44391e83a940fe538dfe2caaebcf7b6110cf4e51617f3619480c3396d7c9d2af597e113acdd794cf81de24a21285f4ca9bf56df99e02587bf89674e7db2a1a06cbc217940fda6248befcb93a3f947234e59ab6b03333932c015dba3c88092f362d0baac5c5b9f2d9d5a829dd3ad4644e0cde89d4d8df4d547187d66179f7b350112c4c004e6afc97fc97793530be06c13737386ba92b13cce0c0b6cb6b0aa0d82000d674d1998f05b271643ba85f7da6304dbb6f530d2c80c40c3e2f925b87d32603e377b3a9ac486e0f0186c191f4648fbb8e230f192185498e3e09e82d321a9a6058c553419e21c3ddbf147c2ed88f99398a7eba4db3a7ea39b45693285c4d6d6c8a1eb8e7bc0ed937838afd59d003d69623f6cc6740f2a7b1808073fc7638960d649256026d9b714d903719ac7959405eed2a22e4a9d72e33ab6f0aa5d07be4783b4ddf36af1b4d4c78585cfce80738b9c1225660f5e16d9de5c9ac285d24db80c9680525d419b626435fafebbb683c9b36bdc1cfc185cfe87b6ae93a14e3d63db6688f300154f288484c07c97d82f438fb9281afe6254170ea6d8037108d8984e88872f1c9072eaa46ed6ba426282ddf6365f010323e176e11309a3d80be22f8aba5cf93dbff8658665a9d2e3b428e05218d9da73aa0324f9500732920cb278bce651e21816c61376d1cf6d2899f02423b33be6a8217c217dc42b1f97abf8f63ebfc367b4fbf0f158a32cb2aac06616446a9773f6501692cbbab803074b5c026cb3b8ab7f48d6e5818e668198cc958b8acfd6469e8b835aca0e5bfa5a8f301ffdea73c8693f6c656cfa411e7efab0842da13aa7132db26176c792fd1a99c79551ab99482be3674bd2e37fcd8e0701f2a9cc801b56e717c8186cae04287fc741296e97c5563c4b64e7d36b76cfb41ff3ef32c5c88a4dc09ff91a215d157fcae725f7da8801e72086e3f063529eac6a11d4845c1eb0bd5845801cf9cc35deb27d7bdbb67055f641b9f4bfaacc0af6124853cee6cc3a858c1b102fde6da1d245390d6a6db8492b1142fc09b90d8c985ddd2a82e9e79355a070eccdcf125ba45a2543d473cab41cd9ec464b77fd57c54dd5b346f954b1c2acd37841f29f9b7dfa767fd029bddfbd0cd3aa285540a3943c6d1018f4cf87fd7c17fbbc65016d5668d2b90e01f3176218160ef5241caaf3bbd747c81da560d1debe3dc258197740839f93ca6eb41e7e635340e9de07aac1b24c5f48182d0bdee3672097d2ae48960224038c8fd710845d0927f647dbe09062c586842d31e1018950a3e16ea5d209402367badae58d2344d169cdc05f5a47f86903d18902ef3bed7d3deea961bc2e8e7019d77005ff88be637ed0977354b26ca98a7c0dd436af45341626540e050d7f4f03b703f254e32bd9a3d2f93997052732773c2274cd1a26da956105c5fa59dbfb002efbc28d3cca08f91f0fa76289a1f68decc6f943cad337f710e26e8287ced6a35b3c4a5b2598162fe2412cc2d44b49948f383403c23ec22c585e95f91063202da0755205bb592fbd345e10bf1b545187a7c14aa88106bfc37bc05dafa17f0e2bb8edc2179b3093bb1cd955beb621d2e222b39af3cc1ed26c7067012b4fdea539c983e1481b70dea56506a3ad912257cd7cd58da4cacfd4370a0dd292c319f23ee3ead9695bfe91c7e83bd846bc186b1703061a9d4a69eb961ba06415d4dfaf2cfe839337a6efa0e6b4f4a23c700f678e517a64e8a0c1eb28c6044440f203d9eac89c8b7d406a076bcabdce36195119001022e640155df8ef46241ea50204df095b96deeb70c2306cea56794e9729b3fe27e114a95344ad4d033175decb92e0ac3a88a16e5ba32f8c94853764fc7aeb16591cd3cdeb84b24ef6827a341355e7efe0ef360991a20e6ae77a04d66bee1da160f14ceeadabb7844e3baec99a057202d80f41c01c6f59d6affe7497b137f93e377e3b9f6df995df70480098c46a85e5b9d9b3fb7d4b7c6f4c72e1ea8fc442f92d4d74b41ce026aa5ecfac54ca2b4f45995799330082e0b558f18c5e31e698c67f2e82dca0ed3540f8493f8176b9163633481d4a444ce792b1b5b7c1f390853aad64979678de457086d7b7a0c0230ee0d0c269322812d5e7dc8e6e1e03dc0c977e81a6ac37b328af654ab070c6b073e3d0194046e9e91898e8459b90faba6e0c5a14a764d919db650c798aaf27ef1ef87a62b3b5d0b69a5abd7ea8e12e19a74754deadbcd82867ee271340c0687e7091091585e1163da7ac9655c91a62da7850478d2283fb6946306834f2e56025d863044b564818de7b43a7d895bc3b260f4d8c55fdcb09d8d01d11631e7409e3dffa027be768340e5a1a71c518396906b1ae32b44b08f6c0b54ca53c7e73375713656815e503a799205ef9b6753d177794c753ec2a067421a13272d09131fe37d212c19790d707c327146823e7442b56bca450f3de89888637e0dc249c2e42c6d6d47a6a49a27dad3aa5b543a0130d7d34f6310bbf8aca6e514be50e2cadc80a7133545d56bfe06a017191e5dd5ed598ba52bee9752896c65fcd4bcb9de79f7a89d781dd47601df7445e23104f2d7f9341d6c1e833247b1f5b56721255d2616e6edf75aee159735f15a70a170dcced4f0d029800b6462fe50379eec7119530650b4606ddd7721e568e52a934ea14565168c45cc0b4e540149badcdc1f70e3079f2adfc8ffa44333c88c5e875e64377780a23573a6f009d8f8d8bd3a2ec814f9a5636f19dedd93b0ab1f70a4b6666520d7b060925c95c2725ee065f52fd09b2f3b2b89201de0174ec755680cbba3e5828298a054bcdefa112aa739c554f847069ec6f4bc30c099c67eb930a68d20a01e5c68d12b9f1b1f3c557fc9ddbe6083aaa884880c95721c85ab22cbb5980bba49c708edeac69a95f7e0e70c9a75fe011411a1ee730f2f6699ae74708608ce6f33435efa0b31379f6c8bc2494dbe7145eb70f6d4d46f8d7827071c49d55c487f9fbfe1a56a7db761cf3d314205a18866b872aa8b9f4b68a930dca64e8fc294b6d59eefe25cfc1008689c78a1e90bca877ce9f46aa05f81e66a415092ef9bafff8d4732b12976b925bd83439e547e3df349eaac385d674bb2672e23290e5db0784ebabb24bed7831e9965c2db3dc8db4ca4c3525b3b132439fd0de7fd1480e2e697c2165e1a27b646898c1af610276c6f58fbc84104a345783be38749ae3f968c980e368b6c7943fcd5a3fdff44f4a44ee55cfd7f94d0eac235dad9296e979f32d5ee4fd624aaca794bf5cc30584e505382b852b880f6aff7da68d4c7970dab6d5510036bb453a7462d7cef59fa78d03de0ba69b266685dc2f17ce8e8a6c23e465175b352c977eacd5fc611d55a03dbb46a831e5016ea28329373d40cba6414193641f75e27a5099676670634008678c3b5d1f14e688a1196b08e4dd855611e56fb74146876ee12b6d7992dc34bfaf68462322e0f169e61b127c00b9c8817cdb59bc675387f671e913d64662128134932a50d8cb6f49a13646fcb10e2c3f1c8c517c5296d1285660549d1bc0ade7c03354749ea811002a9cf526100e264a6f9506c563211e56a811d8ee8eb8e2e917512d9bd38c0c1f51c6968cdb10b9d526d19f4762636bfd9353f904cee43d28b31f6a65266f46e0af9e7882aeed238450a985b493bcaceaf8eef545c93eb6b7a264dc278fd621c338f7dceddd29f68c20625619374410db7d45563e2d90341c475a5df5a5f8dccf3c648072e205adba8327eb36b9d2f0e7dc5ae59933063ef105538974bd47f11379566342c07461f6fce54bd2ddae8004824e93eb63cbe950663d88c31b9cf20e4abfdc1892405b4879cb32ce9c6eee7f93da5e7955d4c04b04cd13bb4ff3f13ee1ced444b80c92bd18d8c122f43020bb423a15142932bf522d9df402a29087bca975a852865ae27a9989a5921ad4345cb4a64f7e9f6aedb0217604a11b3eab8b4adaf2b9f527fc108b3a6d94bf6d0ecc63a237a70489041d1d499316396d67b5b8c73f6e6b91d0a6af32914fbfd860087ef4d14ca4553cea4781cb9b075e47a9fac71c38779892c87a21ebd942a596be33fa3f8473e869d99213782866fe8ad4a79d4d2dcee9abdd53de125a179af9bda9a8b8fa9092ea6ef17b6260da9099ffb1cda671fcc364ad5e40bb4028115be8833c9c6ee381e64c20d1ef056cb5132a04dbebadf2e62f8c545808f685f8f08e817558f27ac120970d6fb1250ae469d33f181ce62aa6a150fec671bc669427151da2e8de1f010c572a000172ca2a140ffd253a48c612c413eac55e9087817b42a468e929e116f4e33a63df26934e2478e806a583493c985f75c4edac0280317bfdb572f1ae1452aa26f3076e7e48fc91a253d689dfa76bb46b199abbfd6c5533da987747dbe90a4c9a8ca664661d8f09df9a2b6648e2b7185f459084f35a3d56f773da2bfc70b1d7ab0ddea709362afb0435c6e6f6a58d0cc42da9a884d76123b6df031accef92a77b67a906abe90abd54ffd358bd9aa977f926a71bc46a5d9b13ee0e4b761771ca5538601cbc7204463f3bc3821e06738acd83cbaf7571abbf032e9607ab7be96baee4ba563932f172ddee5d6adfa4c01b21439e8fa80101847ae4cf5ba289d46fd65545a45fb7f4186e02cf9a0aa2841bacd3c463d6f23ac88514c9039987671fdb263621b4ce663c7838dea4568905a5f1fa3ee4d82f222579ce278e145785c5403bcb37825d3f787ed3f4a657c7d06a77c31afdd33f4042d6baffa3898da308a9a2f367203bf5e6afa82a6d5c428cd8b8bfbf98a505cdd24282867d89d7dcc7ff7f56cfbfe6ed07ebb3fa36ce68ff1cbd2141a656a7e62ddd90e5fe72308c5a2a3a5f198bed49e4b7d373ae4920ea0ba52b3c9d8bd9fa45a655bbad9ebfc64f06a759a79d97f0693f73d25700a7aa7dad283b88c9d62d07951642561911f11e1c7bd760c9a021cbab298b0bddbccf828a2d203a10e36b7dc7d5f40df67c226a9a423f8e42a62a3e91b3ce9524e0bf9d2d18e07e1d0fcfb8c67693168871de6b5e683c0dcf46e95ce63b5887d2538f76078121a5cf124f2f0c06226387fe22be207b8b966b59f12a702bfbd6b00ba9b6d9ce2beec702e262af32ecdbf54811850c51ce03544087d7b0a292a87e0ae406e772bcfb02c84c513e05836ce62116a2e21920bd219d49d0d888156577204b6222e1b017a9bf5f6d57f43011ec2631a6323ee0238e89d0cb2b20b504c485f8a2a001e79d3ef7f56b71e8fd30add6013dddd984a2b5ceed885afd9b59bc639fb2dbc5903acb55bb2612e4bb7606f5431d864a12770f0cda1ab87a9323a40a8db68214aad3a00e3fcbf12d2327e33c658f629edb36355de41e91bc9ab3f4ae43dc43c7f457a28f51eb1e27a34db532a4a869242848dc23399572f4a02d07a52c58e8829d1c1a6e2cd123707240e1abf62f737ece64cfca027b31ff67d9dd567d4ca309f18a91d27a40fd2a4c1bb9297ac329222675d533d048d27909acd0d562589c137d6c0b4534ed1488eebc2e823eaecc1de95f120d2fa5292257c6c0e00b4352fe3da2880d08b7e4594770d2d0c8c5f2ffbc349b7555739226e5fc3c1f1e4effe5072f1fd8a6eb1bedfa334dfd7c6bed3580f5209773d7c1c133d26b758b7132436810f27f497b7470ea735fec626eb95b9d301ce012c8f61aa4db918c38baf9d52c67c0b2add59693bfed42a4e0263a7edcf473a481ee870260f3e8b22a42a820be4b65e797b801a86e2693a3d9364f687aff0a7177a6a3d35c535239585688255a2e378de152b88133be4a0524ad6ab72b539006e21f67cbe460ac56fb696174b87cff050b2c577b59c0c4b1677e5e325ea0b7d89d68a2438d9a2dcdfd898b05327bc8a8fb9c7df586c7659ed64de3032bce462832304726aa0f842cc12a4872172bbb364b5cb7e5d24eeb2d332d15bfafa591c9616363d945f14ff46c6b98ccbdc8e949a5647312fee2b8fdcf3ecbff2d7e259ef14d5beaa0cafdc81d8434afa394ca66769d230811330f7b1f68b6be89ac987a45904fc4e853134d5d3a6a140fb56a5e8decc3c37d98cfe3a9b43928f2e01efe9518a6bb7749dca1d7ae8089ee2e3861151c260c5a484e2f563c518bdffe45b2488cdd8e9e965aeab01bf894192b5987f1e96e18f75266e21e72c5a728ed2995a1605b33e8ecb21a9d56d25938730d6936c701a49a155eecb39075e4da05849c67dae2f2ad40962837ccd03743cc331e1b09dbba32ccffd77895201999664638a2b035fb346d2a65b3236253874cf6fd250666f68fa517328abf9014dc8545736eefbe2649140510f9e669b2e28bed80f2618898bd2eeffa0fb5e7f962f685d42a7f694255a33335842dd5f7f48969252a35edf0f8e6920ae85fd2836f89d358c3e451ef5c843c071230" + + "a2fe30ec1efac1e58fb506267a50043fe6b9b0aedaae9208520d7285bffa2857d0c7d276e9b7523a1c22b8889c5295b5a539387d6738b996964071e25841edee21f1884ef73fe4c1fafa393dbeb0a6bcb56598762c554ac650797c90fccf5973fca168c3a9ccf0570a791c80be4840039083318589138f566ed5a0222e4af8ff3a3569e4dd5914644208b2289e790f15e5b4c3daf9d4033b4e1c77c878fee8493e5b0f6f4a4ff5657922c0642a7fef854e5a1620af30d8804abc4315cffb8e271991353556fd2e957c235e028c2afbf0a2c35a998cfe3c87f1e9bf0da9bfa73a67e5a6f3ab73c9ffd554c82fe52b742a25587d43fe6675915f2e509a7f0c6566196f4c5aae24bd495579026328a85f668f685466fdf7f76a8becd25b2cbbac3efb8306b2691451414407ee41fa1471055a2ab02f5ec99b2c612d0d1cd16f1af866e773d6aec53ed2dda0fb6bb140b766c0b3a0f8e6012b7d67554e7c7a1876f51d0cffbee1fc1a11d46257bfca462c7a9c17a4f872476b9aebe991846fcd10c431beba46f02cb0376a632c4b6e8b10cae1eff3d96224886c1d885a8c46d9dc80e6a5edcde5d436b902cb0565be77baad995411199151f5ea61ac1d7ca5014fc2ebc01a8cb9d1e7662dd93f253eee23f474bf3a25285c4e992a0f77e7c707a412d50e5a04f49f1069a9b810f2ddc9ec9f468c389279b75bddc6beaeaacee970c768a05e1ca667a796cc4a5acf756401959738079b0578a61a80c1329ab59bdd2bc62fa98178b3acb2972d47539d7b97bdae13a81be76eac592537d096902a248eddcc8200030df3f9a2963ae7c8a3a86e83595940810a619b063d9bc6fc0cb75035e988acac64480f5a1a31a787855d8a83013919a793d4de679a6810208aae6835ba9aae843e6cde97ec57296398ec3c128891f3c7e44f3fe0c9779350f66f55ec3be94f9eed53dc6ebfbe53ed427cc44089a70100e605f554f9410bbbf77adbad858ce214f06ab334228b8f894fb7a9b2e3b4b53baa67fd4311fb910c424cdc486e6739cd432a711f570699a903c52a7071c2948a5c6c9d125abadccd242e24c2871e83d7c048dd2da6a476466a9ec31a35a652c06be1eaea5b6820e87f880d9b2faf5c2a7e60355e4a941e1b748fba735d0e75dfec06c6a9f2e57f12171ec9d6c69c0fbe3c6808324175ab324efaba125a22cecb55d7be793e6799d6a8c2a64774ecf894b09ee626146d46ee5b6875e74459751e16b62a4feabc675d887910cea345bdd470fca4229237d4ff79b7673a974bac5da0cd2f3df6ecd0c21ea039acb0cfc74472a7a97a2116d3250f183d0e427228a9602fe6d39497b02713c61e478b5c1dc68aa0d1e0294d7a5bd9bf4b8182d2cbaa1b9455c2cd2ee1120c83166d6f2dddf1311f40168fbad45b1c7afab59b95077540e64b638c159dda711a35e0bcfbcdc89f8ee8da56d7dfa2e23f39e8dfca2033783a3380c031deef512177f7128400ca8f49d8cdcac9ee38a5f86b8ff90664418509fee67e383bfbb478d7434ff7a6f50f6b4a279be9ab33b7270658f129e4f56526f32b38887eeeb13e2b068bca0914e730397ce5003d181f777b45744bc43fd05141178878e2f2705017b4616d23ea244d54aadc74c4d8ef3cbca173964a50521b13cf235c4348930f1c7d17552bf9f89c988f977ed6078fbda9f23d81e117404fac83961b7d23a91c7de2a5aeaeedc8ebaee2f0f76d9327e81a1f23fddc05cc577e4c0dbfed207bea589963c00c96ad79f2360d470e3304ad86d203e1c24738973b46bf04609f1f744dd1975c0c7f7f4e7a337bffbe7c9e83fba1c69c6e18287f3afa2d3996ffc1bd5193ce2b52444fdcdb0b19f701297d88d0fa29962cec5d2ef399feafe95db1f5e8c3c645ae63750de0406d519710dbeaaeef4139aa1b9687f4cf3ff77cf42acc00833bded8e853cfe5ffb8a369800b227fdeaaf6f54c182aa21d1398b29016cc7d468424beef0f5babde8ec7b1b7259b0fa178d98a5e2e2a6f100fc9b2dcc4ee5ea49b240bac283c9e4657eaee6a3f266b7f091d30e96666c14f1285a8671d02656a3e5583d4a4850da032e27bc13845a807b36a974593b1d232bc7742f3f20d1111781746deb4ea6ac95653a1acdf4f649bc060044d3224147133b44bd88fb13caebc41b36f7e48ec97b21e405ec941b270960837be1d49179664567d1ee2342cef5f9e4a559c7b27aa5aeb094a60845308aaa9c2afe5fd4cb808a44e4b6211111a69b40862e530247320863b7fd37fa77e69f05e05a8c43b51d3dbbaf3c715e5c348abfcfc5673f8c21a8126c762325ae3cffae51ffd43cee880f480006b7ef63e3a9ac33e6389466ef1a0b0e67e47537db6bf0f4950f735df6cd81ac960084df5f17d827ab400c074f8fc09bc5353bdd8cd17c6dec09842e7fdfe283f7f33133b33b704da89184ac05b9f98f0b64a5a437647107438cbacb161b6ec97814f56928e800ae519efd7129bfbcbcd4b305a9c703ec4c2b7fc685030e741f951e182da0e0297f99b28a1adec735e4a8b571e79035b78513b6ec12d815323fda7ed61353c52d490186450359c7fda3b45258bf276ee655cebb8bb23b20067bb914cfa50510832e93be450dfb9b7938d3e9888632938ba8d52760169055359373a558a7e2db3e3f7d31476c638a263c48b02f73131c737be93f29b9d9612b6d91434a26e6bce2b536a16d866985ad835a995781cb72680b8a5ab806da807bc77b9ab0f5cc39e845e2be7599db544dccf61c214b998469e8e7e568db4d171b66eddcecfcbc74535753a1b430c91c64e4ef97fbb70bc2468173d0362940a1379d90b358806eb49c2632398b2572b3d821cb12c0fc32c68106d6357b26ea2cce6c6fa8e1a17bda0fa64820c450752483cd066900f36ecbfc34b100799756296d7e46e48c5c48d38cdf333b98a8c7aa1adc2b02b58a0189f2cd046a18d1778192d98cd9510b40fb35350361fc4c3e917ac19c372f196e52c976c083ed500b4238f636fe21b9f3c362bd2556b16e45f67de52aa2e8f08d92bc19fd18a0030591df154df34ef121eac4ab0cba5b5fe8920c4c3f3a63a20f439ea9dcda4ec0d7601fe8849aff4f5d4d5552cab4c73b34d41543551fe1008032d101fe1d94ab4943256471f4bd06eff1f9593afab9fa8cd534d88258936cc593785464f4546b268f6adfd878911497d035a60a0e6c68b5884d76bb4898ad59c41160321b83d40a364cb427699c201ad78852a22eaaef3d5ceaf9de365018b271e16abf0ff5819345ed4764b70b88decf41c15dd243d81cc599a2fef2a3befb2949f2ab244fbcd412432ad3600eb5d92d116ba618f8730a477debcb3280d8b1dc04bed8b360ec7bb47b9cae89d25e702db37c5b583fd72c3f0c08a1495f75f15982a9931fca16b5b1ef1868c50a855116e6e0f49495ef82705f3a3c8d834d1725f0f0506060c2cc37e148f78f020fc701424fe46a5159e3a73dc834433d244568bbae114f475e5e60c13f47e9e14db1d21d451d2c5f39c39af0b60651d059a899af0181ba0b4c7fd5a7e1416adfb9f5381b24ce947b7d09a27a264acf7f0fa28d9db6f6f277d86e94ed96a4a53cbd3a7fe099d7177c2d6ec783314e08947f6811d60f069a1e65663b93f9aba00dd7de119c550181262340a88b316c191cff1c7b43d936a466c0226a5968c2e84ca61faf9a32cb3170fb8d105d25b3952395426d28531797154875af2cd089f7505dfa742c83a9fd15ea57427767df5db894e58f7e026eb4d126067eca69c7c2440d9e12486c63957013961c24359f94f5c1dc239bf532998ca339b3f0053961fa7b71c3c2a614d4b8a821b5e1a5544c4d079e71a43a7965c34e981a1c5460b25b6831979883e48f76c7ed34c844406cf5268936c01c3faf13a235b72444b9d7a701fa9a495231fcd8b8ed89ff2993e7a0241f8ff77e71badc7f0c471024a240f4824da0ace63db199ded2e6f3953c43cec3f5d60394f546eeac40331aa3f466af470311bff164fc90b00995228cda7e239b354a10269904304436ffc6f42c17e9b9ffe9a946c205fc0add8103e12e342b4542062ca0083c286a0be8ad469885fa7171c5526e2baa153c8cb43d33e9b1db7c635827ecd26041aa632829acbe53c38f63462e4d7a308f299efd555294be0894ecebd3a11d4242e1aef59cf77768197b77282aa0dd81d9085f87daf6bba680e40aa252629e2668d87eaf38be0e5399c95eccf3af5ef5b6b9d9da27251b8375343aba5406c6ae8f78d2311828bac89fad2291433cd2ee74ffb81fee1a3170ed32305ee77b1ecd22c7dc6b7b5b400d42917275058a2be78bcd1d79a661aee6ade1ce17fb1cbdbafbe2dffd3884dd87e14e36fd4a27a5c64d4f970541a75af417dadc969e6bb5f29415070e1078071472b5e043361e5747809bcb83af5cc5bb17b03ec564ed1349b563563233760c4553b0ce46a6adde8b4f1cbcf0cc33ccf6d8ec8551144992a0f530b012ec11e28de9a3564096637e590d549b8264c3aa1284270a9310496fea8d53024853bf30801c657fc2439f0446b3de62e556754805a5618eb99e3ff6acc52c898900a565139dc593c4b2a37fa9e212b646d9f4c7fbb204c2401ea0d838a806dc26c067a390f202bd3446cfda0a569c1cbd99be00c125ff13e330bf7b67f8e489c2191d73a74d3cdebf0bbc20ceb4c024bed7069d261cf7418fd07d305b03dec683dea3e3ad4f1ef8df8073f720be0761ba4c6473ae3e8344f76e7e7530258aae63b0b183b0d364ff7b53d35bb0182f8cb56bd550a5148737a1e7520cdfa5b11f0caa70390ad04d0e98664d47af518d6972fd4f803e5b395a68a3e08df1ae70e0aec356075f616c8a60502d45fdd6444ac5ed5d37d2f6083caf91fc5d9851e636ceb095169d44bb865387a60ff46a277ab2f9f6d8160f09d051bb581c3daafd79cc8d2d307335a7505573d2ef74d0f66ab4a432488c215b6b72faa1b672c5805f0e3265583947fea3f20e6b1f10b4dd717c0ce3088fafebc16d48ad74ee4cf5e059164700d3f50df68f2fb8d8b932918ec820c0de00eda4caf332a1139924cb9549c265339495fa248164c422fd6a31337a78320c8c31193101a9ef7202fe0ce9d30521ac08f0f71b3fe100625ff22cf651ee9494101ffa3b4e8c8c360bf03ce35a6c00e3a0a7f024f9757b4914cead8b17a52669fc31bb92efae1513aaa3c109916ea7c025298036cbc91c69b7a53d5774c1c28c9356e33caf4a5d6e9809bc11de2b3bb3f0d2573f8c28c8320b8a397ee9e384dbcad1d8a99d70cadc1c337d6c9c2207fed9f62963c46c866c79fdd4abaee40b62ab54b942dc2da4cd87dc404b742eaec64ccd087d2b60e06b1396765390f6f8c254bba3b0d5bc015100a67319fd198fb2850586b63d2d2b728d47aef097893178195064925954678bf2d7e5e31bc10ab8a315a0289c8152e7ce3051df782d81b7c49e4f171f1de5255b87d4801b0842318f60dda27545eb0c8797f77eec5a064d166da02f04faf7d809219fdb082abb41e0a59eb0c8eb4e7f2a260aebe453c59fb18794fe1bf21eb9eb330740081873e0d674f026d261f82b8262c2979a6c8b17a7cedc89a737f7a5a43e68f513a9c0cb084fb4723d230864186c8e465db6eff89efabc81c7b511453503847d69efcd625afee62118c8172fac335c0218adaa22e0b6b7a205e1cb0ec4dd27c769fd626eda9952cc2887c3e4e7c2586977e7145bd175ca45ad507a6ddfeffda0555ebe142cffc93ff70623f8fde34f24c6f9d654671bd784bb31fd0dc11da9bfe4577408527ec385d71ea1d3b739101083594e4e63f4156eb6c37541555344073f25e39cdc7a39c5a659f560c9ceab686cfea58fb62a1fa4c7aa3a35d91d4ff284706054615d0782bbb6dfb3b07a5fc80df69f1292556f2ff044d1728be0a4604118386c199a19d467bcf118b5b07b4a52181c73d6bda19f8952683c56b61fcf096067f00e47cd106626aa6e3806a80ceeb33acdd8ae7390252c815629473d79abfa9368e0c6c546624a60b011715b87fb8d5cc9a1f028f1079ade65b35291bb0b1fa5f02b6072a40a78275e2ec4784e41d16fd83357ab084935f6d7896788ce7cba108896c0e865b303fed152a8ec3c664f4b135739a671d3a8335b1960a1727d451c85f0e5562fa021088eb45a7f694371d16c21f7b136b9642e817cad5135901de9122756bb776eac02b894d04e198ae881e0af62b79dab09db20311c83e69852ee7b5c13a546714dbceb221b0440af333c3c4344f4fc324c301a60d1f183e7330f110ed3596e253fa8c693063f5f9599faa778b1afbe68eb2f832af2a6acb250d7236e956d0fd56eded2ee11caa420a2687fdf82a74785366aa22e916d75ad1597ea3d2f9a0c5b6d07a4d557a931022bbdd36b4bbc75e97c3fda081facc8cc0782f902771166d34c8ea91147d1c7b7ec857881fdd5425581f1d027ffd2108ee15a9b81196b29059a5791850f6f330b47bc5c7180db701fa81da7030cfda8e60f12a69172bac1651b7392a0927b93b28b42b5d2e9d590e736bfad55993d97cb1b79a1f519591e2c528bfbd0e5504189719b9cf4f7b0d155734cd43800daf07357d653f73370a02618bae488201846aacb31565b5b23e7aa818e70b5ece5dfe1cbeb945e449f3d425065925505e62a8bd5ea20f21667ba834d8cc52026857cf176677a658c7db9e27b0e0e0c479031960b9b3f6d06026e2d87c60c7135bfd63b9dcb2c00e46e5f042393ba7ff958ee8fa72c2c9e9594bb2fa9162c38688dd77c3ff7695303ce3fc79953453e2e2c7fe02628e53c52036297c0c2ac5f4630919bd359bb69225eca419c6a6c89c071d6716c6ec0093fc65712c2e7dd0be6ef7c7417aaecc60f83088b64bc0f247d038e921cf6fd1e47a59da17d62ed646fcc502aceed35870eebcf10881cf0ff712c302bb4e7eeca684b49fc90de7e12bd211ce2e0421d698c59ac3984d71d9b02164fe9cbe95966c4da5f8c4800fdccb6bc09e4056af229619ab9ab723ef6592c6bbf83fcc20dabf9f49511c4311a1a97cacfc030604334583e6f5ab08654ab43d9392722f40a41dfbd6035a5edc25fbe72ec02ac6775795a1fefa99c18948f548be1a636ebd24b697b0a59c00071b73a90511911d27c0b00926a79902d859a40d7f0a77488dcf5af259e818d05d186b0474a4425ec3abeadbe310922acf1ec22a615874764511bf80d16bbedfcf837323283c84971f9bcdcac612942fd12dbd1beb8f6b658da42f50863366552738016491073e24ec7ed6f429706ae4b90816471af4031be4e492c8c2a08ff1680e3d3d934f2e0a3e42cdf7214e3ef59af7b39842988a1f4cad45ad0ad419d0382f766560b861959132e76806ed08d5322da000d39845feaf455bc306af95a7684eea71b4ac31a972220ea22f029977030314b9a4b21f8c402b0bf2f41da5bd721179d7672ae77f48f9f682ffdf5bab3588cf8a49d31c002b7adb4434cfc5a05488ef8f26ac80dc153fabd6cebe61a04c2428aa04e037c977441b1bb93ed431c914ade76b0c08cc887e3d590f1e2a50308fa3c54b22d92f9b8ac39d485cb84eb6ffa0a51718693f58aad932695e169b7e41a4f4ce021362241472d13e2ef0c569110fa5f0d05f244e3e6f9b8a706817fa592b2f9117e8c2defa18ebfd1563cbe348c4f8de0a16e7acd71735a657f75ff196605d4ea3fbb120e954701c8c59e0bfeeee38f7312307ebcee061b4226d3eda9aad6eb31d460a0d3552e156f3e86489dff4a03791be54a6925ee5b07d0545896106bc847bdd561146ef646aa91b879f0de706c740bfdb5d1c3a732b640731436a62c431187e775b4880a0b2275a312a894779212407be25031e403d9f36cbfe07418dff4dd9fa6379d110416697ee0c114d113c6f99e04cc37286c3d6851c5ccf781250e5d3049d93d1917723751d8672639f0bb854f87564af445ac5cb47a1fd35864b6ae446eb1e4806a6f3bc9e4ca4bd191cf9d4b56530735b16254b920afa2415329f673bf921e849f0aa7b8c51f0e5b40756d04c19a1eff8b622965ecacf183bb07b2b4572630f97f6eadda879bc0fffbbc4bff7ed1e5aca9a847de2129a3c935c278af6c29eebcf58a1e6cf093aa44aca35c1bafa6e2a361218b000ff4a2a49c65e64c12344d94c5040d1e737f8bd78bf015ecbfea6ce19574837c5471dd660e673dbd703eae068521ac27f570786a952e37d4ef425607ad60fe45b09a228f18ee664d04652ee2cbb488d42a0c9faaf50f867afa41f1b68aa9d7967f15adda81deb18c00f29ea8a5e0775381cf931f58caacb54a7ac41db043747a218927fbebff95aa1520e136f366088a0c006a2fe6b61070626e0c083ede8c423acfdd70d0de04927a5d2f481d4cbd2485c5bc7aa22f6fe226be46be4a9dfa6d10253675bf0760f3131a11e169dcc62f4338fdc35ce0280f23483c2ccd2ed854b3666f6e8c02ca15be940edcb11e996a84a61db5b0f68fc6703a0aed9866396e26895aae65bde6d50f573ba0a6e45a6671bea93700223b866360ec5baeef69294666acacd89acf029fd7e66b37d0d1fdd9aa0a69a827c6506edd8e48a771cbd698b868de3d4d4440348f97a0ab76709d57139a1da8f1b9543252bb8778eb2f5be0ed17756e4ae806e341741dc992dd2f06608eadeb4cd819ac791f0d30901e622bafee36b5409c091193e4c0f5a5db5c516cfd9e40496cf91773e6d87817f639f8d47385df3a43a2bef3705c25f636414f9c2887a782bd786b7b1cde6793907b15eed4e9486c991f21e3a02f7d48dd9366ff8760d95a46751cf1d32c2e72515f36e0d98ad9a5f81a70c06d5c4560868c6d1990def3b94475b76664381f722fdabe739066c58370aa03a28aa5bd00432177b74d70f4cb53ab7f3a5459e99e1b430d1dd547c273214dbed7c3cdc673a0f5b924a860cce78aa1e8cca714b5f28471368e2fb5f41d2e72e6967e20adbcd5006dd31f644b4439ecfd62541f69d5c9810ca00df676a284d4646923f76dd4846d7f289d29cf3dd9770cc4fc2a2fda158264538584aabd66d28f71018252892b545992ddcdf4a40fa2f3a909abfe0da2e722178d70e83ccd21477581af360c93d33531b095951804c15f2dbb80d48a9db7ea9900edef9651f758c97683eaee8e61c0c88d30c4969920aa732c57f8c5a1aa2834b9f9c3285267dc4e56a381633d466a64b2085abfa052b13d812a6873efe6f2544650186fea789d6924599bc06046f151931d7b6b614b836a1246b8ae7ce4614563ecb68cf9a57cd3731f89e1a73951a2ace26289a366529a987592d18d4d326fd0a9f289a6a9517d4e33de1736ea2f9c5e2c52493378bfd5b4fb643eb17fa154728e29ddc1b2d6fea380205692aac60d3916ec163777a6fbf2fb8cdf840e09f910e29c85727812a62dc3a3a39afdc2ea167a5449e12c2ce1371a32d57ce5802cda1f28254f0d9c544080622df00e2c094011ea97e34edd702de6a84c1b156da47667699b63ada7d58c202fbc2f540c8d4fbf8cdc95f9b102257fac1f2f8ce5bfd2f50e99f7282d2463208c08b106782a1ebd4a135ae1afcb54319972689303d6a524307e29114a50cdb2f8c94fb0f204f637a16fea8261ae51ac33b3b1ab498213636b9c7f855b9a46308ffa1f8b6c8b25a2b6065920f9a20833f9c097b8f48dae00ff898d7d462e55dab5aa07f9d1396504b8e42eecec392fca1f64c30305e02602f5b454c4a562bb17aab60970d440d913b8db0aae3383e1f3f013d7019e3e9d69147810546b1dc6fd68c9f47ac3c4a67972b854055f4706ae4861e584aa855d42e4b5dfd61fd9d6673beb5801d2e31bd7dd78091d474d7ade651dbe5ea208360be3ef1aeebd9e38681768c0783193d1c4474f913a2b4c395ed725ba539a6d6a0ad31015248c84805bf0cd35449653e8801a6a397f228d385e8cc8da401fbc8c111de9dde1257c0cae82220202870abc1a1112b807287b06d08f9d33ff02e81a19fd66f02ce48b71524b5a5177f80b3674105d56234bf717bf682f63943f9a6464638053561b78db54aeb6525035b39a01e610249af2c0b5f2b3b799f14f8c0ee76b66f09ac685ed9ba4678268441d14a22a4a65fd3d7d72816af4d842bdcef9bd20ecbbb42c6b6fd6668bcb0cc8c99fe5a30ae7ee5c850bec2d6296f91c2c1976fa55a4c9cbdaaebdc8f718475951affbe88c3af773953001c08ae069e1cf40bb9799f569954b33c3f4330c74652f088ab669c8b7cd93c5557be761764be9e85b0f07439d28b8e9977586922dfe4c287bdc4122fbe6378923c86bc586fb547b1012f92b2a75047f7a48f88e1730408bf53a6b6ea2c905d1807916be1e0288294cc466ee73f909ead23f31ef36b61e5df581f382c81aabc761f45547288621d16ba21e52c14b92c93e276c22f2b4ce5106928cdd0cdeb67dcdf8ef98db1a701e9f196a2cf3353a27bdcfd5ea32f8cb53795c40beaec2e33bb3ceeb980688709a6f875a2ea891367aa7b1d5b5de2f90d717d2efea3a3ab71777d1f4c7d758487f2114f5ad4062b31b08fefd3edda89982138e4185ed9f4cdd122761389e06bd4eabf217d4197b3fa1a0691a96f7b1ea33624e528132c104b25f0440236ee38df45c1581a68d1fb44e1bf29c3a191cc95ecc2fe09c38c78bba281cf51d51f06a22ea1cd6476b077c6deca2c278606fe8d6efd65dcf9fcbb7e984d75e69ee6e1989427c510034fd4501f75ffbaaf813bbbeb148dd1019d45e2e6ad33a22304f9cbcc54b78c8c3ce958f8a75a2a777f092dbe3b88344f84d93dc9bbec0aa9287a9859c740dd4dd7bf28e5222cabd4a525260a94996ab21d70c4c82ae42d7c802dc9e7377be23b15e5c13872b0a49ce3894c60bd1aa235fcff8d4af6fb85656376a5fd0409fc4b33419f9a4f70462baa3534bb8ed68b8ca471adf0e11d5ba51d4b614b678231e3036fbd5c632d956298ea9fe845727486896056d0c03ccdd1c9e8a9a60473db4e6face0c4edd3d0353fc588e24e6b428050f18974d8c85c7cbe95dab305b6720dc14c21b1550743e335263c756399ff8091f48da7cdfd9e1fe4790cb337e8db7640f2916fb910bce94e76c9dba93ce0c72c297c340c76da7895a75729b2e103646d91170978de2abb1544927d473113947c2fc1e048cc08bde0fe3e5e0afb144fde4fb7328545b05b100e432ed26d16e435fe4d6c0a4413a8041614569ccaf741e8d3e4eac01490c890fa924792a080750f582a538afcb5851be494f8bfb0649287fd01b5fe10f7402ec63899c67ba5c2d377683425d4b079b62e13e6debe7d6cfaf1f7e8f6def16902a725e89840eeef41fb54d74e97777a31e5275cbe2c6b49428cc11c34a334f967c3be7c8228b77029e494a7f30f0f774f9d7b3ac9cbb0792e5af1b1cc7bf8250b879a558fe1dcf0e47f9eed867580bed13bf0880693a1eac8eefa43ad554f64f8c07aebb280f71112a168c320b4a2cb757c2f0aba3f7168c4dc1ad9a95a959ebee8c4057eb6a67df2d80a815291ab340fe4e1c7edc4ea32ef97eddc3a1806d4da1edc07ab7362a215be04c47d9d204f644ac4463a9aca3b6620cae9842a2c4140c724fd7f73ea8a7adb19143907af6e3850a5851334062cace2722124fa72935979ddda0aaf71b3d0cb11b3ef12e955e87ce03bef2f686354b8023b45933787146beb2844f6bbb3e4e6278270b700e73b3b2c4513a9e8de1fbc15ca0f7b76f5386acddeb400452b6fe7e60d109ddf62a3404b1b3738de303d0e824796e1737c35e1077af37d5f8d915c8ab71a16635c60e18d76b3c9280d876a34fb0973b87ffc3d4761075e1f30a2be34621baf1c73cdffc7f965e590a63ad34897c27047df2140c976b62c7cc9f02fcefd07d9c0ce7ddeee9cc6dd7b20245a7a08268e2246044e84474969e1eb63930f495750917bc0975a0c65feb4d5a1d87a2ea7e1508cb2436f319adccc4618bf5bc1885d0e1fd3f254d5779037ecca9649879f1236cfd843bc832c2a7c2d79e6775fffa67da8bb582e400b36a5b95a7efd3bc6d33dacc0e2588c713fdb46c87095b629294efa9f197784766cbc697b84c874ff109705f2c0b6c2570b3d90f5b85d84a5e1ab2a037136d187e37a7cb33b406b3011fa3897e649ee63ab76022db7dd2d0eb1b7ae97088b19634ff9970bc1cedd6d20f5c67772e8096c634a7dade70f5f92710e41ee9d8dc3515d7d1d73a8a6190e1db33e2066bd26a9e828a1b8f90f7ff12a2f23627f75fea4164c19ec1ac04b942e6f2013bfe2c2e43c2b57f3b21024429b468c6d1a1dff7540614abd4bc82d5d9b059bde8b1031f96cda606fe9e94136b4290bd046c5e2818ecda86bb7e1fef74caebae4d090b6a58e12edfe52362a681dc64e378ab008550c883fa84b062b778fe2db472f32ca3fb2f74df7be06ef0a85f2fa019260c5cc1e66d7fe6d6962bf8762e9149a689749f3b871e88e5a8d4a61490dc8c701dc8ca3e920067613e907f5c736d68c792672895b47e9e797d0253bec32b9d5a79e0a433e1601d5e5072b7660b5ebed7e67bc95a6223176625290382192efaff0436ff1c704e9f76e1c64d83fed9472197a6bc000bcc24d02e5400efee09bc5881aee9bc801826cde13fc6d22a0a9dbfe4cb171c9528a0240b8ded6f922c77de1360939fa0bbe4fb82c3105f22c90040958b1cfad71423aa7fc3624e0d22a4e9da57e3dc09950a599266fa71c0841f80764e96a096e1ce4ad161c0cb5348bb5248513b4740748d10b423b9cbc95cbe6ae43040a5eed2ae2cfc7eb34081595ab6b2dd1fd7480089ee2e8fbcd06c6dc43a3243c9c4450f05c28559df8c0fc41cadb644854825662d1475c00dcec00818b746a286dc12acc5175a04d0ab685b48c76b40bd0790afa606be65e6c7df5e027f8bbd6979f00a08cb985b68a64f1604e6386715a4aa242d8176e43f6d8147dd64377a4f44d24fa3ed06323746207d95bf6323b61b42f4903d32f6235a77f98c25ce6ebe8d5f8b76d689267ecffe9c32b7dde34c7f43da41ce215456f1423572b78b116af081226c54eb0fcd8272890ea4ff1ccf91614c309cace805da498eb7b538f2f5e08d99f46d1f57981c5d8488301fd00d11f484e13c00bab448bdace012d2951db621aea02e2a1efd5638931f55faaa0c62e9a3d25ee26ef6a57ff22836b331e9d4d9179d5297972891bcdfeb695e9d296e61798456f9c7ace85c8e767211c5b586eaa114c74dcbcaaf8acc932707f42c775032e1f771428bb60c6fbca0e34e17a20ff52f4616516c60ff59a0b81f9908faae30985bb3126f98fd57aefe7e5b62098f47f35be80891ce4f9c4c6991b817128e3917b91d6fddb764b19e9e705c9fc3b45d1bb4fd4e0e06aabb40ca9f276f618e98856fa6eefb1646070e7504247df6dace32b472aa7dc41e633f086ab7d4ff34874c544d07d5679e7a8ac5f36672cf59ccadcf0c002e9f9322ca34a1691690a06b2f6dc2dd5d1b705490c8bd3acadea5d4e7dde44bfde584a62bfc85ad067be0e3a733e27ce017cac0230bfa5c53bf423dbd2f02ef0b95678a215afdd0480d0f1d7a1c709398e3448eb7b7c77c33570dfe545a81c6984c1bf19584953641daa62be86c17ae3b0c39daa12e0ddc5c40998f64abea505af6ac562d79d5f33cc19954348b0ed03028e71f6ee00962b0a3cbfc3ed78e92b58da538e8d4f65699a96bc41987f1b13aeaeb6fabab6b9bc9bb9e30ebb96a7a5817b73061d368a356f3d332e77da5e0f16d5f4fd981c132ca92cf6f6ad0f6ddbbb8f20912c4cb8a806e3386f39b7c5f668763366d01a4d69b5b0516b1b8b0930e7211cc060ef0d0de91e49656ffa28cb3ba42f4c2a31892eb91effff5f607b3bbcbc61733e8eff2680547ba75f37d4a7a6fd49019dabd5844aa2077dc5783919beb2c0a1f2601eaacc0ef67d61a70a8c9c248de2af03294e86f555ec59ac8c86d78a35c450ee80d7bab2b72761412cb54250b27aa3dd40b23532ecb3a14fd7fb6d0ab584a3677f6b1a373a1400100439edb5e011c9595daaa69fbccbdd1621f8ea08f21d4ba9dec01f2b75b6579f5010bf6538de8240a266eefd7e2fc9f2096c23465b5d545627737f162f8c5691c0eb07fe59879d55fad9174ada4043b9ccca80e2c9919d005e339f71802c6e64107e5d939921989642da4e3a24ee3d58ef82e99a54a4d4b2c732d114a823d6edafede047b8877713abd0a37da3086c64abd0cfbb2914d41fbcb6c33daf9405e371dca44f9b085bd7ce80ce5dc10847111cb72a6fa0ddc4d4f5fa7284c4becc389936cddbd759338701adaddcdc68be01cff14f472d30aea3189ae4dce09afbdc6d41405e16dce2f667bfba5600d7cbdec3d4d30041544dd461fa876c085c15de206ea8a00b90f89b5b010622d246b63a11dd57780c09e6e66288141e5191c9aa4d3887989cf2960b5f7d7d0a00b4fafe80691e335e8836cafefb784c05c4c13542d47123df54b71503998f750520e6226690a6d0e933adad8555f519c8e08d4835ff8826d9e975ced67b2084b5f20c5e2e2de0f32bd0cb3bc760174c9e3d383a4d45af9505d2c1cd4ea892cb0190d0ec47f1269623937425aa3725366ac712f7e30358de56b757912fbab0e73dd0d5672f0e23ae501930c7cd82b10dcd41815ce7135b8013e8a5ef854dca11b7c984d9da15547820604df6d0e30b896da0ab8329306220a4d095c610566196961f840733f872dec575ae58c11cf507248d3a5a017bef3c939bd05b789a41fa6d0ee0e41b72e62aedefd033cceae2e13404eaf2f3ba109c6cdb10cfa8b4e6a78ac3ee7978a273c999bca8a58930f4914044ba6605638ef5dff33b6b4b1fc7cd76ce502060affcb5232760f8aecf01825c14e3d1c0332b98a01747965b8e62c1cba3a865754aeeffc1a3fe38683a0ae89f7320b1ba314f1bc5dc2b47b094ba9242e7473245e6feb8e5fa63699f320c755e4b81f8fdc22d277d62d50bf1ac0a33047b7ef43c9eaad8376e3049b7a772cd5a21fa3a1358efa46857699cdf4e26ca3541f8a508b9f4baead07e9b8522081461f3a965547dbb7a43cd53f804419bb9ecccd7e0be09f69b07d320d52db53be1be2f6b4dc4ff8b7665681e9ba4cc8b6ac989bac9002a15913d0600e7100cd086494fb0d44da52a13627adb6089d8634288b08e9843ce090e79c37a286d9facda1126adc9bcac24faf62650f793407c36bb71a4e26526c7c84521aef3a7c702773ec2e4d9648a2269d86002a11325dd8eebabd321a4f6478cb670b8fc5b1ec5346b58e57915a776dd1830854a81f2716b089a336d3c4c9bde6337c9ebb94f269d9990028c04fb12ca59c2eb490470e33534d8efb250b518d7e2b23d515a716905e8e5200343adb21ee504195f282c913534a76452a49c76b8f5c33a8a174f5052dc3db943565e6fccbc36e7951a1063c8410a454b7fad8e54a021340062d2fdf94981dd6d88995014a11a7dbe244b401ff88d6f780ae1c0945d4fd88c2c3426296bc2c80d81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac8"); + assertTrue(Arrays.areEqual(expected, attachedSig)); + + signer.init(false, pubParams); + + assertTrue(signer.verifySignature(msg, sig)); + } + + public void testBasicKeyGenerationShake256128fSimple() + { + SPHINCSPlusKeyPairGenerator kpGen = new SPHINCSPlusKeyPairGenerator(); + + SecureRandom random = new FixedSecureRandom(Hex.decode( + "7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4766BA69D8560A9F84846AD8B765390C84")); + + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_128f)); + + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + + SPHINCSPlusPublicKeyParameters pubParams = (SPHINCSPlusPublicKeyParameters)kp.getPublic(); + SPHINCSPlusPrivateKeyParameters privParams = (SPHINCSPlusPrivateKeyParameters)kp.getPrivate(); + + assertTrue(Arrays.areEqual(Hex.decode("b505d7cfad1b497499323c8686325e47afbc007ba1e2b4a138f03aa9a6195ac8"), pubParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e47afbc007ba1e2b4a138f03aa9a6195ac8"), privParams.getEncoded())); + } + + public void testBasicKeyGenerationShake256128fSimpleSign() + { + SPHINCSPlusKeyPairGenerator kpGen = new SPHINCSPlusKeyPairGenerator(); + + SecureRandom random = new FixedSecureRandom(Hex.decode( + "7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4766BA69D8560A9F84846AD8B765390C84")); + + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_128f)); + + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + + SPHINCSPlusPublicKeyParameters pubParams = (SPHINCSPlusPublicKeyParameters)kp.getPublic(); + SPHINCSPlusPrivateKeyParameters privParams = (SPHINCSPlusPrivateKeyParameters)kp.getPrivate(); + + byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); + + SPHINCSPlusSigner signer = new SPHINCSPlusSigner(); + + signer.init(true, new ParametersWithRandom(privParams, new FixedSecureRandom(Hex.decode("33b3c07507e4201748494d832b6ee2a6")))); + + byte[] sig = signer.generateSignature(msg); + byte[] attachedSig = Arrays.concatenate(sig, msg); + + byte[] expected = Hex.decode("07eb19e7d838d71ef66b8263b5d1f8ecd2efd33ed07448479b4797fba5216cddcb44fa323ab9607d20c58772c8df4ab618d33a938535045c76508cdda022d93f1f53f0ee23e84c8dfd7e8035604949c6ea48881490c73ffbbd9846a4eb5f6bba4c57c26d6eb552cb549098669d3ad21964c8d1096237bcdaef80246f3d970ad789aa982ffb3413a5a8ca8e1bb5e64f609133aa50c95667d6d7645660723e0db4e34fd4f7e7cf72465f84cdd635d3fa5ddb3e76c591f48f8aa9e09c12c8bca5e5696747b28a3a842559421439c04be1ee6140f91c54b17f2dc3eef4b357e37669a7c411d6be56b4315f49c090497dfe2581aa23488354284fbc75c8aa7939023c6bc4035b914b303c50eb47dfb0e5f7c324d0d5e4bc32e0855cbe169c030e77ce5bc9bb3bda52b4dc83bbf2fc5e5d34c86f48ba5d828e4bf9270c1d3907bd10c68488cce4784c90f7598ba6639ddf5896e33eae8e0346bd84a9d6164895101e15ca808433d6cabc6f096254b225166990ab05bfc56e356d22dbb096baae26037c4059c078b03f1a454f3c42f1143b25e5166f7dd68a7f7e97300ebf35e8516e9800fc4aec46c628ae415eae03d0d88673ed0b6c8729fa3cc8b48e7e8700cf6c0427a714c16c1ada0e4061b199402ffb22763dfef58383d4654d11363f31fbb7dfb1872419547fc4275e2e807f8a7a4def2a2320be3b2a064e21180187dd5afeb63724801e50524f16ed350df41bfea9aac34ae862842817ca7db96daf5994a36c1592259961ecd5deccf4dd8ac8ccd16031836a58d9ba0571707c5a246be1dbd7afbba8d828afdc2273c60fd3a66f4252095b44300b0646a715ad810810a1db103f43c88b3b312d33d02e6b2f889c310fd7591c7933bf987c2fc58a8f2e7dc4ab498883096ce9f0904bc1fe93a4157b72f77f2bdd8ef295f777c7408add81e901b20d372d822ac91e87c1248b1ed1ebd9bd27f37eba0ad57a4f6a140e24792ef1d69231f28575cd7857e0aa789699d620f866f402e63ff6fe1d462bdd21099799825e52f0c977068f4af39b253e8453132de071f2c785a4c70b6c7623570534edc1cd87e1b65e56e3ff874503101bb763c1f6f59276f905924d0869ce9c603e509f127b01e589b2bc187877bc9138113fc52c18ed57bf03436ffb460ba03bbe51dee2d62f602655fb05687d2cb06a24728e9caaa8bac9db4d130ee95bd6033dce8620c714892c3c3f77d25192698bf57cbe62e0842fdc12b591449e2d0861293cbce88bec378c0cae81697aaac26865e7f774e7d4dada842b422543735bd260b75c447e01d19261dd7cc218a743afb6b5361ce02c911e503bc2ead2c4c6131db0c64052d8c0ea97b26042bef20f65c34c9cda1e0b3fc185cc5960af78863151ef48b897cd58f75ca32aa3888b71a401cc24ebcbe3c443469bb04215886e3810a09a7be206691faa8d03616ac21d4d7281fdfd8af529f4e137411d463c11d08e84e6e715fdde60f6229d96c10d219cc59d40fef7384938442122ab330129ff3ec32c2df7b44c150dd6be50c589457d722828c51b93e374827d23e23fea793c01a0c0187ca95531a7bf236158de18de453c95c2f669ffe87a0d155893296a04b9598a3cf3408ba1246f01c8491e718f0edf229da5e79b1867185911a203ec31303f0bdc8a9205baab40f54851bbc72e4c8641cc36e4af705255af3ee44f6720927d7950762bfad39fb5d1f5645a2fd5016cacc136957c060a4d2c8ec6e82462b348abc2fbd6413ffc383fa046db7ecaebaf30ea6325224762fc82775f6981e3444bede850d8cd02a92ea3fbcbde49c4290f99710ae93d2c5a209fe775cc3fde3a0c3118a74e70803e20687913a21311e0b714ce6a7dbe2fd523633c040e2e8b6a0d807aa7d51fbeb816157270d78e251016809e0eafece9391ebfcefb413898bea612f4884a27c6a49778e85ed517eb44ceb9dd3f0d0968053775e8d554357bf676f3b113d70e93414b868e17716ca582aaebf4f5f29365bb9f88b0bd9b1cbddd27e8d2287d6b4a051081be7a66cb015a98624b6812b669e70c9382c5a75cb8e6d49e346d252505b3adc61025fbd7054b6f8160eca46fa84c10b68bdc1b257596229d506457895e9553b153d63c5dcd061eefb2c8de12855ccff35c7bc6638d67200dd12056bddbe0bc103459e2fbffee706d8a9ab7e8b4ebcf47a9f30d77af96c3a4b603e30e9991296ad5f43b8f2cd9da912a0f79e2273a16df1deed09e438e199cce62819c6edf3613a1441f6e496bd02c6d0276101514798464e9aa36d8408f976cecead4e8fe27ede0c87ae61bb5d663b7d1bca5b874cf4ef72c1d9785e443722d92b7e5806039a817c76ef4a60f98daeb634d9d889bda3a1d1d086edfc40aff43ce22fe0451a1fdcaea9f48107a6b0e76b243d8c2885188075f91c81832f3b1fe5a406dca04adbefc1acc96b09e58a1acb01f5e2f4417251e7009cf9eaa28f2715dfcb64163db747309cd6d59aa2112af5082add942a6a1983858c11b0d8666c88525d967714c10d99bd3cbe400d4ec21b97b22f848acaeb4abed40ce6969ed90b02567efa208f89f9335c97ffdc51059dc979b32dbc2392f37e01f91ce94a17e936b836a9cad68169c7d8b73874569f8f40e78fe5ca8a7d5ff9486ab1ffb09d79fb97eab437cacee52c95f0a6d7d67527ab1d65ae6ee44dd1379915c8f65b5a229993ff4c3483af67dced2c1c644e7b7a910f598d51bf699b050a6be94631ed07a73b6dc38cd4036af554909c1e6725291f6406e1fbec7405ec4910d04fa326e2f37e61f834179c080a2d9a030d41bfc3f84612e046fa3a6add79a9e53f62d46da6899c8b2ec2dfcbacd18e53eb37fa65e446f74c801ef4202eb683e2fb93e2e8bf6a694fb6533850f081402241a9be10d502c3ea28e99bd33a854119c916b891528590dffeaffa182a4d6044190b165ba78475d3fb738c0c19e0eba507e2ff73d4e55f1e879e5b33b577bc3b5efa39e8b07ab56030d8621067ee1d0d2b6b578026d29b24410fbd21d44f26db696fd79b4f7c39e52fa71a17a5edbb341cac5a393d73c20aff8e44b75ce2668d3035ee73312a496ef7e7be43c4615a740d0ff9807480482341e0a6c6e80751badbb70267aa58722b9d0f017ecf17a1f797b363ecde0142dff2d242b983347699a79f7f66588df87f1f52e27b16ed2100efa7c7e2cdd7dd1df92366d1ea9c33c2e35ede25b2f4fff04ae955bef1b02deab05e378fa4fb66970221362e878598363e6b47c21d58764097f570707b91f12b15dd5c72f43570dcd2fbcf63e471d7d8c18b079b5835dca28732a3c42eb1514d1e5782a645822326ad771d72ba68830479eccd604465d63ee0ac37130cde9e17bff47111f49d79aa448b3976b17a8ded13832ad41437101389063fc89353d6a95f37319ccf66091ac58c286a1e1bc987103fdcd7b201b320853988cde734d36e68fdd1ceed5c9dd1d036c392c91834d5f7c564e4c5da836ef2a1a5f5bd1ef2d0e2258476d08970be46046539d77f9a0778d9c653874258940c4674e77fd4f01aae0e48c4616002609e4e109395581dbc3f33d1bf21d07f67a0e4267c60cfbfbfbf20135dd72910cec5d375c449310a9636bf59d90531d1c6ae06505085afa464307443e36b2654b453d60471ff86b4bfff90c98bdeb385e069723d17eee0c0ab141797a49827abff2391f6b4b8f7662a5f2344eda6478c2fb0f0bda249110cd03692e7f9f9a9dc006de9fab8df8de70fee7f2e04894d00e24c3ae309d27e114bac535a2740aedceffdff6f6b112d76a432830762b89e9ff2080e03402a9bf96f60f11e767a2cca95358dd019922d18c74add9d535ab88fcc950dca1a86bb88c4b6fe3328da293b7136cd008d269f3af92583751a0873f8b4c3d93e788ccdbaa0f2d990049191935b6d9a4010d3d9c1ee940cf607ba5b4957213a61caa8da27f7a4a6716043dbc7619cca81a8d5446006352a915b74a350c0856472ea870bf4506f187a5103409a87600fcf4307bcb54eefa9bfa2b1822abd4717a7d90ddfc80b1ce6452ee94fe4df4f6c7dc15fddfded3b444679dfa4b188d741f66ef10b5a36c608e6f33c3a1a9bc4fb94d141b9215ec84db4d4ce9de47dd11d88bf6c22cae984cbc4f81297a96674c648cf6e916d640fa160c9e0b9deec9aebec90e6acf012a9d6344ffcfa9a6871f4a7ec796d48c2c9aa4b0f2aeb262c513948370fe9ba5ca56c41b36f49697fda285ce774268375ca055792a0328ddf539104f5c76e4fc34f0f4a7afda71b0b6fa329b6ba1cfae5de692eee989c44931eacfafaebff6617a5c022b39d8fa6b326a3b2d1cb22931a5b91b6d41ca6f0a44e73e7bc359a3a4dd9740fbcb6491fe1cc0f03002f4ffc5af237ad27b0f5ad8944e391f7164586e5074872d922acd06c6ef859a965d3ffe15a39d15000cfc612cd6a44f5d1710cd2a3cb2c8ad3c4a1744368d98356bc55a14dbece4f7add4480bacd8fb70d9a3e1f5a4f1ba0b5ef260852d569e14bc243e2d37ebb979a02d4552b886d10fc543dbc27a2e4eb194f93aef7f52ed7a3736d8bb8525f1348a2d97742fa9428c8c7409b770669d92af4412c0eafe7351704e5b8314806faa955769f98da96b59191bc7b16a2b74a9602607c0b6c562f550154bb289f91e5bd34ed3b82d1c001dacc759008b19dbf7d75ee93139d4d4ccb6b95ebab6e1a1f289c04e64658f0e87d5f6b1387a3543c9fe0647eb6834532fe4c64542a172da933f7df48bcec4d68218dc49662a32573755a2985940e83709f0609f6ffce009f023e95e63406a366ecff23f6ae928e7d533e942125eb23bbc4557f8b9b75a5f752052f1ad2d73db639ad8353ddc76709c1922f8f982903cf57d495b6582e3d61c62ac401315261300ccbee070465ecd116ca3b02b6cf21392118a5bb722b33bdf447f1754e89c9e33e8ac48e798cfcf09f1144a537419e537504df81090a61428c092cbc1a13d8ee1160fa99c3db43a0703eb7a4806c61de696c76844996085aaccd7b76d1a0f46d2b0ad3e28c7285aa9dc11ea5ca5aac42fb211a1b079786f688266ff9d7af5ae7fb4838d0219846a13e02aaeb62ceff4a1012fd1c3c1b455442561f64f5db6f6cf3b6fb7728501eea757eee0d4d42617c8b0bbb84a6abf1e234ab293ad120b7cb8be424cdb822f93950f666d8de1ff6badc9146ebd6ce2378a356b0a6edce361c96175d1cfd0288c16d6d286c73967246e78238277685960307c6ba96a12d6b7e315960bf1fa30afba382cb9c8c15dd9457c1e6e3f7f37d5bd3ed6e64af2274ea80d90a33426e2b8491f35c5292cd24eb29e632403b031f64fca8287af1e8dee8f26828793e87fabdecc7fd11be7ef1d335ec5aefa1c8305b4e819222b22237aff967cba49308917073a6bea505bc122f5fd99775e23cd381c50f1c6164529af5f0f4bec8991a19e269471fa971dbf7efa7e890290c06ea911a047b5d1e4c76aac0e697560b5f8316c4c0b7cc54ad55ad3852c3efee2e4f2d91f7408c27da014d188f8640651f9d18dba99a22fdcce14df709ea052a917c840240e5386f1a361e0502966a7698a506aea38698d1bd28f36ad728e042061fdc387b9ccbb4e7566c32939da6851c982881a8eb925ba052fa0b7efe81a2f4e7b28e48260ae28456c1f110b6e31f87f2122fcd8946a5d965059f73ae98320ea2e022c6a0dc60ab21d5662700db22834ec67734cb6a3116b7005b56d326502c42954e16c65d09af49eca7254a61fe8ab329a2a0583cfcab1e40ef54e44b42fd349b9dff179473ce1af62fe96b239560400cbb8605c79adedcb38aaa76392195fb6f37a92f92f1e5d12e32bb327f32bc2bcd6655c25c1842e8375493b5415c0af2c0b4ac566b7a7c1325f5e4f7160e093ea00ef8811ca63b65abdbe7901d7757d0cbb8fbe300e7e0451b1d17f5987567be996b996fb75d70c9d477a31be7f107b5a47720042bd4f333c58d501e197c3811309c033382db2f61b66602b9ad20bf56797cade8d3200d57bb9ebfa86f44542a9d42ea0fc3fc6d951e6951278b114c5e6fa2041db624e8d7f43003fc808a61b0b64a707b118e1e46cbcef43d9d8505b0fbad9793602e030c010751416ccfa7ea5f84695fa7b81037d9df505e785ff1ee96780611157dc08d0cbe9169f54623174983e2a23975eda931e537db69124c0713393ae2999b4f6528a2959d4cc44916acd49f28d8f279a907494eb883770b8a8d61d005d2a724768958560568905291c52da232483a75d197c3a632ae80d1358b1bda6d9faeac46938e65c076051201c4c7c8660e3db8d06c56d2a9caaba97278522ad5bdd2a30fe1d4d32623773543976f56f3c6ef1cc9bcf8b16538277693c04119a335d2d83a730bdc161eaa766569342ab92b36fc4956526acb4be8bb8d527af63207387c9da2fa26e6df8bd2cd42aaa9a3b569312b972dea8b4068986f6d996a1b8dc7b56578e2a7803f61c480b545ab95b0e1342e6cc5b9637e3c2679752c736c1e8b237509636473127b59c35b449d79f79f97832ff5bd14fcc251ee1aabdf419918a62e2df33da300c12e7634a3fed4361f229f06bd1dd007945712bb2decec60aa877231f93000766e70dae07865ff416a492da1944a0411d83a36f3eec11be27851659751239685cbbe23436fb2f867f3b7ad667919e81052c62f7ee560eb840a9955d4ade9f6eed1c02aa2323f351bfd6d57f9218b2dcbc78ec139402ebf49a6296677a13b5fbe9ad83244ec4f89f7335eefbae2e93a58bf5782124ce4f8b32d5d5b669dfc8b2a1d5dad77235bfffb57feffa4203b3fe74a3bc31482f0be187d68caf1904f2c1952b8d8bdad3a363f4b0382f767a3713c4e1a08f8dc4d39abd8ccf448614fddd32362554a1b8d9a187af7846c8d36e796fc9691c491e367b6df7671228692c2d7e950fd408d9c367680eca9847bbdcd4f34cf4fd9477fe916e9b87ce3405285eb28a03ed38e3519eb4881bcc0574036252e8e44d9b20836ac3e1e240e144415e958a49ebbd552ccc4fee8d0f0278d794c66ddcec64773bc6df293cf26a3d756369ad6510261245ab9fc6bb05faf7c30ec9862d7686c8babd1acd9a59ca8206ab3c90a9da2b424924b0dc72fe1c16e74f65df13ee7732aa0b6f85bc7ed28265ee1e9e4d3d980bf6970ea74440b13c7585be6d9423c317e483f5ac9434e382e4990012bf0cb4f81bde09d715cf9de420e610daa02861929b3689660ccf082445e8039f04d5b5d4cab0394e6694c0f4a281995b479b8a98ca4a42357b048e24693a087e723f5b237cbd2ea0f1d2eadcf0f0642261e46fc6c7eee42d5db0a2db18df09511f1c230e543e6dd9a8d5de658e6ea9bc4052c6369394db0c6d89ba8abeececbc872795fd21b540767d9182bba786c1b4f9f12fbc651ade9fcbfb79fae9605f228fdb1442191b6e82872efb727e6868888306eefe1c7de161ae1c3398e31daa1d16068f7110481be32cfa640633ba407610fa105808eaab6f631a5858666a94e04744d7a4baf3c37710b204afa536c17d188736f33fd874f3ef86503e20fe9fe4dbe34ff29ce4c33b22f3336fa3a0046691069399c14467cdae752c57364ca8fab9ffefac2d05015f21c2e0b9ab568d5e3bbcc03f573cf693b3192c73dcdb297caec77b000f4130facba4f52a845c56b82ce708fdcaa90f9ddfb83fa74ad036ae203f626fb786a630e6eca9bab8b1921e500000fdde798065d46deb8ea1889ebe2a0bf86cc3b1a1ecc6683681c4d87321e0ab124078b78ccedf5a845d3144e4ad200b32b5933e6c72e692e74a2e39fc909b487f9c25f24f4364fef5f121a339212fa03e93b9a33b546dd4b3c1256d31ab19d0f164cecee630b128cb4be49f4f1382beb57cdd9e24d8f719acd9f1715f961a1729aa5e33be7db30fe5b2e791cbcf1f8a44fcac4e32c043464cce941bd16a96104866f52e76903b7f2c1906da118aeb2c51ba7cda85f1ff05a2b932d58a51a83d0467de48e611a1c5b2611c5086fed70cc48de01be9fe68f069804930c409c970b094451086e66bfe82291232c06f2489d6cb22dcb174b63656993b95ec1f6c03a177c6261208828a24ff945bf4ea2d5fdacd9447291950c59c42ec548eaf55117938769a6555a86147ccf0940e892ab7af8a67c82c016c81eddb5fd66669fbf73262c624ab05efaaa2003818a146f9c6c566fa40917ece19280510eae8c1b70eba7a016153974e6ee76ee7d82ce37141fbffcb8b9bdfeb7d1d44cfad2578765813fb231e9e64cd0ec7b179c615513248aa27dbb700d84cbc9813134ea54dc0aaa9d9f2ce287193f0c7f6232b4d6470eb5055f25eeec2ae1cc6b0f76e7e52e02fb3dc1e0fcd4135a28f07c5e8d0d98718f183bd401662c293501d41b51859f17d31a12fcfec4e067507ea2d5f268e72e92420236eab5e63c698781c8e027e9e50b7209f6f5f9f59077e8c6a5dfb1564ef0920aa86f00cf041c492dd7851ca62c2c889d4c014111dccebe8ccbaeded0c2a5198a8df084131e4671c12319b59d175efdf901efa95c973f21536ea3e6bf79a9570717152e0553a71600e3eb0509b6fc07d36386a91ff66c795f388986e2e8c40ead5bc879ca89249c6c876e91db6044c718940f11a82b0fc0611cc9776722ab039a2337c22436aaa0e201cadb356c33cf4eb54e8c5e25b3a17ba45605e5a05fe2d3830c9976327aebca4d1840df2564e8954c9d226b5211144469ad954998dc82106e4497fceb7f7cb657a467d3715f54d2b2c4c82e55af037819be21f2a055700ef984f49070fad5501058b18492401359e1111b42c90b638413b5c8ace7dd696569f0b07471caf0ceb3b9c1d46f5d63ae989b3e286ddd675beab96449818fa573f5074b2bad96f59235b7eada3d08c37fa24608be97f34c2c72780310a4ec5a03494bc682b02d0e65aba0ecdd7e3365f46aaccd36d7a2e6a28e2a7a52b4074998a34825c29ea980a8fd00b906758cc1ea5e729c9ffae6df27b0d168ec2de65648ae9d2e56c369a34c6a4640ae4a55a4b7e8df97c6c8b3d5fb31209204d238486991a333022e6ddf7c8144f670a33bd934e2bfac7e503874381c7c5bffdaf252756263896508ee3d281c336bb91bbf2b70371548da6fec13bf66d10966761abc8b796033e90b7b778a5496442911967fa8fa6e3f5ae7efedc154daf0e5a432665057fe04879034c3d044e6d5f122d76870f7c0ba3f52fd1967af858cff702e6f94162f3875054fc6111a7181b893db570d9a5d41aa5136edf3d6cb9c1e433eb8b25d681529b95089a2e51488fb9968fdc11c99abea22efb0e9cdcf8350ba731e1708bd3539af7182eb00f7b6ea491aad93198254644775f39fc29b4fe00003993fed2880b7278bd4685644b7b107cbb8607b5cb996257ae2e8320f04157d7b5683b929589f5f0c3761a4c69107d86bf5197f93855c4e971f3a96b78db48bfae224a20ffbe13d5c993d2a45afd7b68af7ef8c80cbde64bb873c337dd3cc761ddbaefdc39fed49f56649217bd667c210bc648ddf79d4dab4adcae0be2d98b2781437f65bdb5f9d17213c9e049adc24dcf979562de975e3b9f3c14996fabb9b8d709d0679d32c97d5df124781ff814587039986bdde8981219f2884155dd84ff459238fb4fc04bdc0a167b58f1d08be70ac35666354786f8c7464d796b4335b859e0bffb641a641b6fd50a32eea862d16c9980b3d5039623daf1d754685cced59d39a27593f995982c082deb92d3676fe5d82bf7692358a03a363ea1110ad38820440749d59b43c8f556c297bb93cd3512c157222b2091405ddc196ecf4449981721b97ec69ac051c814d27441864b22fd4ba48cfebb119b3f3343d2a60f4b6213329d74757ffdd314ab849638e08530f3e0b5cb24e969ca38e1d94fbd8e0a26de324b6c174d168b79e1ee9ebbdded1a901f77ac287f1251b00455dfa00fb260afdbdb51c78c9e73e4a13536d21b8786a3b802990d59b0c620d384a099e39e74e09df337f9354450c9b38b2614ae75d202dc1102f468a9e38e800f78291e9743e1834f71162c2d53b755b9844bc351a1d8622a22bdabd236633799311bc7e7056f10450e00dedfbc3ebe3eeb7b772013fc765c1287d860f270b378fb2d8b733ebb3e38fa3e7b6246e5eb5ffd4ba3b957e8075d931e976a81e4b085188f97bdb1b90de8f2f5445beba3316a822873c54a6f5aa6d3519db6d9de88189fab6e0779436676217ce6efc31d62e77275cc6400e6d770748babe24c82cb47a55e8fde1bb501f9f59c18bf999aae1f9919b1bc2eaf70b2a4320b3ac3fdd77e5b8efa5e675df120f3afc921e9f594fd64b4b24948da1af11e6d3b715444bcab58e006b8a91a8144466a5982df663421e6af45c7a4db67c830b05458408c6ee41a8590ceec0c5663d5d65ca35fda76bbf7465efa76cfb23d7db44efeb1b7c76d4b8b672cecef224c01b49d500c3ec0781426768a36d811e9797080f47bc184ff17027b9a58fe18cbe3c8eb442e9d19f4a928cdd365873e30d8b820cda211c991b2f6019a7ead11357910fc4781f24b915280b77ecf9b8f09cc85e539f55937b55c1cbe7709c3aa5ec26587b18a22b2a7201e9b1b379205d40ee64d7d26a9b6657eb6a4026859af4df23bb5092b9a8ef8b783698c3d44b7cdd54e0675888129f53429ebbb7948f5bf9f32dc28a126b76ea4cbab75a4881eb023e92881412f7cd9dd58399f5b100158f9345483a1515b7d7f77797f279b20fbd83f2907dd2a2171eceb1297ac333b31e65b57dfcbaca1e1b04ee28e89e8c938f6dbe5a7f14c2c5e98e77497b3e4758a51f2dbab5ddd38bea9c87756afc89641118f7d94b898d432f95df37321db3ffb4664e021f5640cbe5a51fe0dda3e734207f941f5ec4649dfd5d956811d716b6fb556342d58306bdb7bc1cd929c747ddb4b90afe3c6e6b4ce7a7fb7db5c5ec52653440c7af513529d9f7efded73a33a1565740bfbf35dbca95480263661a445ac2286386fe80b69fc8d74663cf587a9e5589decdf1c6b8a088b37daacbf95f55e6f4eb13f104f2739e90356da9d4e3e9dda87f23fe0c060409596bad760461dd2546eeb85d98e351416a35840582cac50b07ed59f18f1c30cd7ba954d31a84ecf9cd853d0c9b9b22a52aa83baaa2d04631e15dd32b8aac0cd36389e5730ef7bf42a82b92d7c8ce00a8089468380159faf1e643eef9f6b2948013ae4a63453a70ca96f2310572b8d474da66e9d3f4bc3951b8d0a8267166f952851a0bcd1231b362043cb8b52ec10d2584ae25c2f1635b9835c8d8567c5683d606e26e92b163c14fdc7ee9ea67444dad2b14b7d77738639119f986770582aa1ed89c944bf9a2e868303407c1aed39a1e277e7456cffcc53a427f67c5a9ae5ac42161c3203c8e44a8599d309e14334c76146da72495a2ace327fa0064f77b1d52b2b27c032513bfd744c7997deb73a20c46ec8db2a8f570ac03cc56c45c5edd01d42981264e30984dbffc7e7b25b4ca4bc94a5189e0ce6c256efdbe923c928c55ce3004a10fe8798f0e5c61f2695f53772bfe0fc8ae02e8e44aea21f013633f4c92a03b7c0ac63c29e2161f193505f6c61708da62dc3e683239ba7467bbc2c10466fb112f501f9f9a9984662143a1262f2a087e3717ac19194d3dafd04308a163e38fc25a6214bdf775ae714cd55a72a75df2db8659dc21483ba3816f519e39fd8283a55a107aa638d9d96087696849d960c206219c10a43fd9dae6abcbf65def1cc48aee6a18ee27d2d8a627590c4a6f6d2c8ca8ab3a5d6f6e5fbee239e8ff57ae18294cbd4b27a9ec9ad4dc46b52f7f6c275d7d1c75d563d8dd935a6754ff9789b7c1e255b89c6a126b4236b387dd1f1afe379445f5cc443e1a8049e5137c6fb45d4832af99da931a3abc48cf7de32c1b5433242598e1d7b17c1203744f5e9de84cb2463e8d5211adc4529e4f92ec06337d34b1bd41a7381adcb2968c142b434b0c0ac7194e32f7f76cb5ac48c36856327140e2f1edf947076a816784229733264298eb0169ccfd68e0299c5a62fa7b76deed0786e06bb2de46f309ce36eda9e9f0dc42ffb3661ac2dbabeb195ec26f335d580fc76e9bcd48cd2d472ffebdf4e103a862eb01d55779f579ce961958e6fbe89c738c6e517d941006b4576f8d1360bd418d472ed4b6be7a8a422ee14dec7f725580dfaa8a9ce7b2103c56fe9421734974db1df720763755241d5190b6ab3e6b3e3e4659b360331da1181503c251e02a5c12b4bf24de9af8d72456f9c397662d0594c512328e95ce2860562271496d072e521e1dca1ecaf21290dd15ab16edd633fbc25061414d0b15091f3a1e24e8f8a847713eb900e45c980740076eae61fe25339a20dd46594d05983fe8b19f5f319e1ff908a797c2d67a49596ae8eec3d961bee4da090f8053118933c34f520a6eff2fb7b66cf3af87d21d6708389fbbb645a37835689a9e91a7d58febc598dc82c2e30d14c86dbd849190cbe0d77c6d47da8c97f8ced748dc53baa4c167696ffe8ee61e1d456250e2229c66a5d327d2ada490dd92aa06ffcecba57d402d1a05d3b743087527c9af999d952b498a3a52482bd947fc6781c95002edc7a07bfbbfdb86aac13cac3fb375d6c1626838a0f301fa3dfd66e48ecf0c9ec30c55512cdf2bdc9bdee714f086ac2f7cd66ead9d48c62aa56314413c85a94d9b73ceb85f722327efdbe8fc005fb29f74feed6ae75c435e527b1ee20be088311bd5db8d8906759139f4f1adfbdcb6ee11d5d9715052ba5fa243f59f4c61b4acd3c859cc1a2f60f60e4f173fa73e52a785a022b242171757e44fdbfad5b54fe46f3ceebcd60e9ba5261d49318fec95e60fe5914e995737c8f470ae6268c0c8d6a6f4d3797b414d7844d2cde35a1dc92dc110b2fa9cc8241783dc3f56c78fa48285762801e4ecb8aa26cf11bf277a5fb769a2d20c03a499fd0ef6b81ad5f107aa1d54d2a42fc6a61ef75cbffc2261a97e29777ffa811008cb7a448dbc2c79bb4a90993f9c0b9da20ee0d2b8d64a0408cdddb12e01e9ec1cb91d052babd766a38a8604051407e3216a1ac0ffa6f9bdd837ea27e583e257216ed020a44461fb063efdd946b8bb887a9e929905c049af41b644c943c44e3b71d2368f25c35c44463a73681545b12444fb7c2ed4387b81392b72d5a08002214c93a0f3ddb564c3ddd66ff4bda1a4a809bca9d5bceaac74e98bf159f2e15f01f78f9411fe33e88bd23bb2c6589c018b5ef09810cf2210eca0cf88d30f5543daf69e659fee7ab51b27e5f86d8395306a0189f00b80f06a44eb86bbf63821d34e8b0f4b8897af61e88870dc44fe9dba8250359d04f41b2fafbad0d61471ddda25f104e903f46369af45867f8e4eaa9cc6d254694e7c7db9b591994e4151a98f0082e33b4c905e0ecfbdc1efababaa766cc1417ae96295b262e4307312d01488ca4dfdbe82a045ca3d13b2981f8e9c11d534a7f70a6395d6afdeef7c065a9d58693afd73ca7a6c5b0dc7de014a9e52eccf09cbda328a99b08bbdabbc1cf86536a9f3a4f9193d5b035a0117a8c8f3bf2c01b2309e32bca59b4bd879aca2beabb201f417fb239fbd804a331fc1e9fd3195a5555a83d80c49dac524f5bd8d6d13ba0493321e0a4a7b7e1ac245fe51b8193d996d19e2861a2743aa5d4b6fe94387b0cc0304ad34261b079e6efb7fe4122d9fbe50d5ed77f81116fe845739e822fb97c0d7e82655c11ad075e82b51563c38d7a9e27ed59ea657c8daff922ed6c97259b1f80d3ed264a060b3ed0fd5340bf5b7a9790dddf4f788d0eddc1d71caf1916198b6c2b88bb3f2e9391be1a9079d740e6e06bc7f68167196741a16ae0b1f096d263c1d57854d055d6dc5acf8af3ee929175b1625df2968b6954af433777f215c898cb6affd4ea29a762def7b23b90c192f78bf06eb1f2ed5b348f9c31861834f39bbbf45195fc51f33b30833c37620936ba584b4971568e8666cfddc0e78fe52d7adde904b2740768d20ace5bd5d556e65a701cce82ed76e6c0554349f39e1d4f45dcf6e1388f0dbd717d7548c8c074d34d0e09eb79d63bef01f8cbe2284902d90df866ce92987ea4f5c5ff3b9448970a8293127d4119b62b155948697c5b28995176d6623fc957b133cb28ec224a357892f1d84017643cc9f14d188aa1922ad8ada01e0add3ddc97ed371ea3420fc294dc73fd440333dc6908940b13a93338f43ca135b49e7fb654904ae54c4887d170af831f6f2a25180f87e2c30e09711c8c1c62ca0bb129a43ad78ce319bbf22419b96a673bf47bcd083fb15e2513446450e031a5324cea8e2ab317e45c3cdfa315523c88272af5b44dc9dbfa82ea5e73082d304654e4acda2b0dd27884ea5db98feeb0ea2d87afcad6bc22f8dfac7363121adc3e6160c53503b86d00a69fcfcf43dd651da233a9d7992a926a19c84c78902694cd2e81c68ad7d079841cf8fd993e2ecd00d156aaf8ea1c0dbfc11717a07e0702a2bb1b87ee138f555935502eb29bec93c2cfce66ad6c9e9f8379969a869225d53fe229a6201a6f4807db69c4299cd9954a3479ab9a6acca722449846fc0564413f1825a87cffa0c322aa8ef468e946dbbb18d552182e1d006d75794aec43039d58b7326c08bff5f983f34aeaac15a097aaf8f656a030ded23022e89164cf982b2a422f34b5cd80ebaafb294d875a8e59b9fb4ba6801c84c893a5b3fd6e30662ca68a2bb2c94506404df5abd94e9a6074adeb0cee045089dbbb60935fd8d6de78f1f132803ecc5e1ccfcd8989e2d06a1d1538a329d7faf069d94104e9f943d0af19923a28254cff628d762a33a4ebdf8ee9ccaa1189ad7c077df95955e0fa134b7fec8aeea3f9c6d90b174ce60fb929daa82da4b6cfe430bc749384254db21ff61599aa165ec95813e46dcb7385f4e8c372fcd8da135363e517db2e94dd587c9aaec8ee25d25ec3eeb8c7aa2168de8c2bafcd4c10d2c069b19b0438274f5fcf0663901695a3a77fd0c05ced7f05df29573e15bf21234807df7060407568eef8c71d8c1cd13d314f24206a3db3d11f5af1a3488015a9558d1a3b771432e50c462936ef6fc3b7b3fd8cb3434c5b3321b7ab82cfa54212cd15e85d2d7a8154c0475798f68175a81cf454529b7f08160fd15b9aa6064a2a0fa7b432baca3d326f000181b962da9847a499dd52e71e5816e5a11995ae9dc61bd5392f0850be25425f296f44b085ee7ab23ece55b4e197b2d19919dce938e6db063e5c529be569c001541080c8b2f6a979b137883fd871b8d6c61b4bc0a64a1a5be462b50e6686ba94a8a26e900a1c300a06256312f209bf20de9c46af092841a033035eee677ac7c971871d48fdd4eb097dc2cdb0ff0551c390c3daeb3a7a75a8d2fae37f6961c56493e7a91f2f1c0c7821a193f2ddfc4a483f695edd46b03e922474cb487f1ed7dcf1d9a156b80cda4b8a93816f773d2806a26efd7f504384c622ce7ff9dc70dd59f59a86c18605f60f199b0620d13873f5e67ba20a7d8399e0afc92776d590197ca6001143c1f8373f844b7ad5d690ed0313a5a4bcd89a37096e8a6fe8cb0e6a22b9e630af8ad49d2d2b9a8be53a75abf7e9eac22355a422f0e12d940ad33aa6ef65c7becd5ea5a9e05b10a54afb94dd25607c8618e86be40989f43ff21850f4619d37363876b3f9157e4a482e10e725efcbf63510c1594b25ed44c074850ef8f4f4623becd651dbee24729af5876da3523cc171be7b47965236f028d46b8018a5fc3c70248b6f4a7f6e9b5a83dc7964e38164ae7f417ee7a414eaf4670eb1a46cbfd6aa4bccb6ca8fff9b64f24bf62e12ab616cf7da3d9045383c4394b5bd7c9565e5f408b6eab844945c62f585437b13d70a0f2b0078a1c1c1e3d9060a240cfc2f8d88e4f12982220167f2cff876ab88d53108fa4cbd2187618f3965634d30d4ec62c5b941ce283eb96446e100d4c61aca2b9a0a2093a40fc9b12dc6efc89666888c98ea19368b4b893ba7e910bfc24bb6eeac0d2c44c5763162c23a44acd1c935044f17b578720a3e3f32a59f4618ece4d21172581138195022cc65f0f4196ccee3c620de035e5827c6c1eb82e2e86bafbb9a7c133209db33d877a2c4baf5994cec9b9866f720b16eb0a15e20dac0a1a4e8fbdbb7890ef562a0359c1f604fbd7f614ed1162a0c290bdb7ae1ebd6a7679dd81518870588826880a830b0cbbbb4a8cebc26822aeb0e14a8181875a81900d5ebb40fd467eb3b89226afd27ce540cf1980074299a27f8e78fa2d7f90daa13744f7dbbacd2f21662f3b15ad6ef74ef75e937ea437317a846c937b000e74dd1935044c3241c3a0bb2748cc46416c6e5b28c04ec55271a8a16dded47df3c3cd8762b6a248d54a8e0cff94a8751a4e06d459a54c9c6dd02c8c64a49be4adfdc2901af48641aef11b5160dac2aec4ab70f6401b0c044427666ded842b46f131941401fb3790d9314e5a02b4ac30a8938298b826d8cf4be9a32c997fb063f9eccea77d0ec8bb7b13e005397baa3b97e227488fc79c48f68d3d2b9d03cdfe246d444eeb32b77d9ed73ea9bd4e3e29827d69007fd85767e76c54e9ed42a00f6c4651ddb6ea8786c6768f2b18c74ad52d3f4186829e18ef2cdc994f12fd2771c2653500d5933af2029d23c7472045b37d549152eab9335d2d307573b1168b920d91f1f3205b1bc0c4942599c0113f785bc09b58016d670a2e8281e0dd63ea5335e1f506baa788e85fc06b35d3260b789d413816b5e48fe0ecc56b962f10edaa1407ff1e4985b7f3cb4146e6793229af3b60ab389a164d407b564b56b7310a2f0780cfb1b8654d79376e54bd22247e5ae80032338b0dc291d13da272c154cd8294f8cb8477cfc2e8c5cc3b841166bf2281ec376d7027db700705fa8eca0e26ecbf47927979367ee73f07e55320df2cd6b704406c1d36797597886424933bbccc58828187b6787287910cf258a5670e0090ce1044899596cdaaf1100707731e2467447c3d14420104861421e706204839a3d04688629ce09cfafc8590fa3bcb31b6c37d2f70ef24213d8f146d1515d173cb6935632ccd6058091fa98bf89a722af9698b954fb4e700046688c6f6696698c516de7aba878703a9a23b5d9dbdd63e0924f7428695cb168850cc8ae51843854c43bd482b19136efaa2fb3c0fb370f2d81f05354e97921c642e3669ff7c14f8a0b18e87caacf24c3095d9b8aac41dbdf0dc1633ab87a6e9d599b424a9c5c3aaf65b527508cc0ce238d7985672b09b8382882b783c453d694f9a2b2de5da8d1b713d1a3ddc5b36ea0a5e7955418e532474547b8310d76cbd1b40cd6fb336d44d7bf1c346accb6cc6326304834ee7fcec6121903abbe8f41e1024f58b4605040c63b3308e619116f1e827d25a7d6b337ed955b4616c9b757a479572b61f56aacb2773ca2b75a06d96590d9302bd7f5279f60821f9e21452a4c6d4b3ab62906d1617000df0b51599579e91ab0a7622437d798bfeefb00739f5c82c4ca395652c8f2a0c7f00915eabb952713745d609347e876b2f733e3fb00b4278f90cca8aa4d9c55acfdbed4a904b91f07d51ab7fa2b77b0f22c767b71cb86a6f8e2c169c50a29e733bf3dca895421cf4df672630753f897a0ad8a0e5606c97b096ca7d577ad3bc237a4ef53756d9d3369786616426524579e7bcfe27d1a622c11953202b091956bc3c5527b7530c080034caa2a45a21c32dac704e7b7ef4f3193bf0a36ba8961fd27cf44b7b1042def689bea2f5191c0c6369504078449260015b54c9a238fb54abaded8df118762d3a9ace989438bc25332a3de358f35f4c94d8eb58ffd9a88f935d6362ece8d838f1588b075ae74913f17a25bb7e1c3e00b62962515b1714c1fd23c07dd46ea7b7ec200560628fc5807e49f955a1ed06dfb24ebe211bc4effa334293532883abab142a72636bb0d915587931ce6079249a89b684ec3abc82ae6435f620d927857a47a0c29e3516548ea9a275a9fd68acf0c23f8c225bf9ddf1d88e533bba106178458a46adaf48d9085750404b80e65a12ce34679f8dd9361576c203cc86fdc48022b93d3d0d3355c6c1dd9b5c016bd3167ced0bfd3f21b2864cd4ddcba4a12df520f479ccb7b9a9717de050dc76a3df65a3fc37ea3003a38a4e01c752bf6b2d82e21191e4f956c0b2382a8a9efd07977c122acb5bb2a5973d3427d803d9869779502bbc92a21442e3b5de4d49d805b3a1a63e78dbd13dbe687d24e8db6dabf1968b1cf7df77b5a5b5424ad7c0167465edd0d7858d69d381d8d25c7aabdfe74dfdd146e177d4a9b3f4c8b82efed54b91201b7bb62642de20faf948bf200d8ab885ed2a8a944bbe20dcd0e736e890e72a4fd6f80784c6cb6a992d553cc9266df472292cf8189da1a10578f77c067e843676b4aa24cdd839b715eda9cfec1b005dc9b15b123eb7bd8eea57b80e2eede9944ed7e54b190bc9b2681e3da25ddac421b247e0fd72b48e72b98b4ae1e8bc31f9a6b5c0b033fbe0a894a2df5748f55d4d6e0fc9d60161f878e27bb7f8dd127d9d6cdbcd3524b450f528de8cbbb413113fc35c04f728798ddf4925cfd6d7d66f695fdfbdfb8a2d14cbc10571e3b300051f62579c7234586b19860b5e1cd080d4746837f6cce14ef0ae9f2eb08f7989a580e0799bf1bebbbea1a17ea9521cdd1b1a31f793984471c6d389bd24536fe977998ceb42ce01e9b789881593f76b806763d87b6732c81f636d694309b2a97a337a4a7f8d7b84aff98ba88e20207f8702c31f2c072e73102bdc4dab7a8a536e34bf808e789ef03ac2817a1396419688109ad4c56c3e36272c07570f7a5ba756fd143c3750f23d767ef71309a4d6912fd9017d179353e798c04516c35eaf7d2c8f7cc18a72fe3e131ad6db0c43512be43f22799dd34e0956b909990905182a2e6f45bd84223b727a45ffe596224d97c48dda603b3a96ccbe46ef7124e649b155d3fc35e24e9b57db83c1c9be73bb1335afd3cf92f12100c7b97627c7c2eb2cd789bb8be04b225b079c16819a25200e8d734772db33d3e1fedbe72d00ecdefd6e6e5cd1813ade7bbff3bf1267e25ff98d69635adefbddae6a047445f5ce00627ce46d8420d87ab2317135b010524ef4d10525c28eab8c2c161d07951a4771ce708b42bf15cdc7094c8bf70ef0c45fa74a7f26ca5be6b25c1b1abc25e5a89fd93e4df19cb25c54ca6ab3845e7405e583968abcd1b30afe1759d63181545f5f1ecbde94fa3d0e3022f0cee71554fc51140c8ec1b90d3e3b4e966e4cafaf6db2a154d19210dafeb2a9dfd4c10d0ce48784fda86f1298e619acbb3c5a5464de8d9ae6ffb0a745db5c1d3848218d3d55cd4b26076b1430e84411cc9a7c46f92f19671285e84c593243e669851685dd9d3fe4bc21a4fb32e3695544a859cf8ffa459181e7fb7dd2f140e5e2640acc1187eb38db4e20c486e52ceff423ab9fc798c4073a36018e29affe6d5466afc6dd7c184b732e86a53171cb50f0c17237c24b071b70e3d108325b54197849c1323cdd960c711e9eb36f1a0ebb864d600a3070b5de8488fdd104785e4cd0a22ccefba25bc178fcbebd61c59a4f6b1651bf20907ad06fb653edcc3857e097222b39b90675459f1ac59cab63fd06f48cf187a3f897b19477945e470ce2390622658d831ea7ef7facf0cae92826ffe1a2a7eb4be0aad3fb9828b4eae0e1948952b80db99f5340b1e28539e09440144a21e22b9e6673882f8618b4cfd201047a78db9f9466b67cf97ed4ebb81cb4d9a01e7dad01b521ba5820f954297c5663a85581ba7c01512e600f96a15d33be6120a454f8fe9ebcd0d1caa8f8e080b1be48e9df542910b7b085c44bf1885ddad30bba22da989ad36997f13a975a97d63dbc46e4b103aeb73cbf7c4f28ac0f548267b79388390403dc8ed4d249a2446ea5b9b0c204b1bf68cb46797466bcde73bc10fe7ce9d5859d44e5b90895b5b6b3b25aa89fc14af046295f0c14da9bc151a0cf0942d221410931962a739044f0efc5a6160ce5bcba8988e0c079f73c53be6e9182f771b143ae5307d3bdeb9a7fe1d28be54000f2b3c02e518c87b9ec878463ebeffbf3d1910e0359c42aeddcbb161082c71eec262e0da9445586177c4b440635d1c9b8af83c276a0374290145c0d899485a77ca9a3a6caee9952993016ce46f8a239b638370d01b43df6d3dc4477bb478342f90b3ec23fb279091eb1301ae97eff0b8ebfaf07c8cd409da3bc472f51dd37249f64655329ef4750c1c66c54e84e2f6469cd3228a1e55de55d03218189e81475feab302bfaf1a6c53a3faa50ab17b627bd45a9ba2587cfded84ec99e89e803a84b5d21f9001111a495e5866467018d463313465ce7ba73a071eeb83e8df4c97597e7585988a30c499ae321c6b6e9780ee3ff84bdb199b6bc905171c53608b084daff0f42bb61bb72780d3456b652ded654675df91e4a79a7924c78076281e9445d5d60524847e170df4c887f2e31a18ed55b215bcc27dbe0de127359bd0c8459860bc2d1deb3b46832c23d54f08b43bac14d468b5dabd51bb2c2ab9fdeb5626fcf865bda54712e882a3cb5f328ffbc6cc4c1f184cebb0d4e39f4123981e7f2ca026918b7fecb7913662cf8e29dddec0079a33ed226c73afe8d4039497aceb7eed111a175393e72c4d090a27ff9283cc5bd8969c8f239b295104d6bcb585324273bff58e09481053ce7d5cd882aa34c5f038326105beb85662272bed3fb9a9361a483ef6eb67dc53181589c3f63d4553984464a3c31f9bd940a0559152487f3e8eb0998f54cb4c66f732d05e5fb4f20a4b398bc84d7b10e0a60af06e2ca42d8e759aa4046765374625b57c5db49fb517853a7f57d14f626ef49d10adfedf87530671dedbf28e34bcf356e363c82a21bc1ef8c4cdb01ada71950d003a05c46985c9f4604c89f7824ecd7bf65d6e0ae88b4f07da8736aee9acb918e4e7b21d25468a9b6130689582cfee12dbb84d9199b75dd395cceef94354d2b28435094347b9c6fc72203d54fd235319b24a9ba867d67dd7b33f791397f7f306c063f7b08bf5f1db9737b16df1c97efca69104f2bb76259927ae6ad45db596ad5dc925b78417494c4eccfab88d6a0d4e88da0ed836f70df9388138ab7972a75381ede6a519768692e09cccb5c2fe15ec16d22354cb15d1a12df61f37295e1f687ad508ec8481cb5e6836fe15aad26a299a585d11c5fa5cb2a9614b622ea0a25f0f51ece3c4d8df40c9782bd0edfd6122c355916fddee2b446ff3f4a9320b2799dd9dbfdb1151c357ef75291e022cc5427348cb366de5f691bb33db8ad38f1e13002d500957b643449cd35140474959e60234a75f3154241d95314967eae69e895db608ebd708d7a92de2b691ba8229b4bbc7cdba57c5a19bbe6205d623277eac4058761d480ac171f03a73639199d2df7897e860bbf9fe83e9d26cfa10536de1fc022bfbccba5a34eb9b910df9aedfeeb98a9d882c09da7966c066f23f1f05f936a33df9a7d569ec678ec0e5a3f4326647439d080e253c416b5c375c5507a9f6397ef745fbf1de6a314692db99822ab883aa92c1b70581ecb2ddcbf6b8050a6391fa1d850caa2211df019ce7d9051659a250a27b93bd137fb682977bab22e718937ad32b97313efd3a38ad0cfdb10dc823f0ff49a1e2761e773940280a6731f8275914a707fdbc6b01117eebeb0a6385ada776ecadb469577f4c5ec6081f02215a36f2e8a183d6a126dd29cbb1317557f30db5593b75d1cde48631a750ed4050f7aa3547e812fd2515bc8ff85452eaf2a4903abaa99fdad2607bed5061f02fefc70c6221a1dcf5663afc183a140ad5d600b9a7fccb0037eea5705918464c059937e0e525252372fea1fb2ab59b8e838ac2afca220a636ebeaabf2f0adc00dad47c68f3548defeeb65e0ce8f350dc143cfd2ecd99681f74122cb08bbc73a97afaa3c641cda585d65dc0eeb7d6f8ccdcccb9e08fc34ef2a6fcd9ba4ffe17a83f7ea3f76b662aa829451b78083e99a52d0d86a5509ec634e12b87cc22913a984429dad57d7ba33969a7b2ce213c7bae9cc641a403a0e9f9f1e6d43971a4d8e41bf3c9d756be99a42ef46bbec4fcb0ef951d12a63e1ef5cd8e4ccca00ea75b66eee04ce16f02ecef1e321ec8eb9a1338944396843339ef065ff9df68a11028907f45f906cd87350f1db279d4b10d599b0bbe3ce1c5747ff3812ea5c242e76e67ae977f449263c8ea38dbacd48af0913b27cd7f84b20b02ba6d50760281f6e85828e4d974cb0a73efab92a5330a22ad00c85504e5514392e8fa22e3e7aa3df1bcd6d0d56afbe20df04d1908d7445f03d9a5b2234db0c0c8a2924cecb2fb2b9a329040fe3b3cf52589e118eb75de1c3a02596c0159cdfcf840cfa682b2548863d9ab34f3d82f73cbe78897e40adbd96f9240e1b4a51a0d22e58dddda4dbbf90c1037f3b631777dd9f870b017b337697b38906f68f6299efc5026e9c774903bc8a8a85a2f0fde95dc7c20c1b4540c495569bd9d7539ae53d7e2df5d214d1eaa85e7b551f7752e98401ca38337e21a9857e346b6cfde9e80789a0515808246c610a2e9f8c288f24b7628ecc98dc6b2848b0098d0e44e1531c8676448cd2d393835ebed828b78e2ae820ba3d954590adce7e1c227259903796280312eb16f00b12d7c30f09a683884fa3b2dbae9e47593f16ed7f3ef4704a7093404670646b3eeb062f9be55af5244b7f0315b273c3320cb9343e9251dd00efa991fe9a34fb10c1dbb95215654dde8ad0ebf922ecaac3ea60d209da466c9c99b86539909c331442fdf233bd8d2ea77ab9053d676c95d249df72f20a8adc25792aa9faca94f65c0841d43a585099b2b36eb9b2be76396ca5cd6bed0bb4357a5ee6f5385343b2a3d12caebdb836cea569031a5793c38580e1575a5282e5f2b376c542c13b81fe1a1681714c635aa5e1f643c616131b8436958775c1ffbb3c8a02a8dbcd7175e4be9d5a4ad252ff9a3d4a9a5e5554ce2e0c9d2f9c3ec2389ec2dedbcb2b734fe8afb95b5e83312bb220e35ef3e00cca7935d0294dac42946e09802de574257ca7f4390d78f21360e3ab6b181590e87855ead08448d4df6cef788e8822931bf9cf265f0a2ee8d029a3d1f8a4f795a9b60b77b52d2f551129468ae2b12764d7109e2cbbba8ee837c2a3dbf2fd88d2154493e502b6bf7a0747814160b68b72dd1824fbad318c2ba12fa16a5934f5a390f4aba1808dc60fc5cde8484bb431105aab788588d243c18c33b05029b7c84c0d643600ed8c1d250e883bd524a83614859b0e025549b18c03d2894f37b9c584e0b371212d68bcfed60b18570b0cf63645c808286b9765725754e4f751daf403815182b21c4b301183e2799f6bc144f16f98a96bafffc8b0b63b505762e2f66e9dcb44802d04d80ca8b33731d7b62da025ab83b4430ceb4cdd0de2433c396227e90f0dbd0c827826f9209a7672846b78bacdb935a271f3f18be486952826c29edd709d910edca1a8fb598712a3776ddece903f247a88e4247a093b5db0aa8fbc51572263f12063bdc8da8140843f581dabf765fcfce299ce315e67e7c965d51dabfc2ad5eb72426e0c43d60551e1c56170ca73f89b6782c4027b5ecbd7ea87d611e82c3bf54cce971a60a719be00e3c81b60e7b375c1532852cef9dafb88a130b218ac0f4c232c8418120e14eef266c2299f640c73b09f70779771c226fa4c3b8b00d52a195e2671201379e5245d5dce08df4ab4cbb9c2478d9b96f32413453988c875299c5e4a315623de8acb3f4f3039d2d7395a424c7c998fe270b6a21214ac1bde4730fd8e991dff3d38120bdc8223003a5a524e04a2fb9ba7ffbc2570076bf2a378e7c8f97f2ca4c74c4aa2b6b2a8eac571053b9553a8a96a6bd83bf665d473c742b6b69cfebb8763af518a716c180a41c2a66e6f5394cc8262779200c3279995a5d7452c25b864a9c8ea424e1334262871b2af99859cf79f71a256ec6f580068359dbd704ba65c4926132f39b723bd145c88479d7154e5f561aa0919217174be0204b0e85f8ecb3850ada9412e69dd919873ae9d2849ba615eb46d7b0ee036f2dd81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac8"); + assertTrue(Arrays.areEqual(expected, attachedSig)); + + signer.init(false, pubParams); + + assertTrue(signer.verifySignature(msg, sig)); + } + + + public void testBasicKeyGenerationShake256128fRobust() + { + SPHINCSPlusKeyPairGenerator kpGen = new SPHINCSPlusKeyPairGenerator(); + + SecureRandom random = new FixedSecureRandom(Hex.decode( + "7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E47354D75735F16E03DEC94D1F5B00C213D")); + + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_128f_robust)); + + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + + SPHINCSPlusPublicKeyParameters pubParams = (SPHINCSPlusPublicKeyParameters)kp.getPublic(); + SPHINCSPlusPrivateKeyParameters privParams = (SPHINCSPlusPrivateKeyParameters)kp.getPrivate(); + + assertTrue(Arrays.areEqual(Hex.decode("b505d7cfad1b497499323c8686325e4714be46e5b92237d09a0ea8a0404033a6"), pubParams.getEncoded())); + assertTrue(Arrays.areEqual(Hex.decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4714be46e5b92237d09a0ea8a0404033a6"), privParams.getEncoded())); + } + + public void testBasicKeyGenerationShake256128fRobustSign() + { + SPHINCSPlusKeyPairGenerator kpGen = new SPHINCSPlusKeyPairGenerator(); + + SecureRandom random = new FixedSecureRandom(Hex.decode( + "7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E47354D75735F16E03DEC94D1F5B00C213D")); + + kpGen.init(new SPHINCSPlusKeyGenerationParameters(random, SPHINCSPlusParameters.shake_128f_robust)); + + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + + SPHINCSPlusPublicKeyParameters pubParams = (SPHINCSPlusPublicKeyParameters)kp.getPublic(); + SPHINCSPlusPrivateKeyParameters privParams = (SPHINCSPlusPrivateKeyParameters)kp.getPrivate(); + + byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); + + SPHINCSPlusSigner signer = new SPHINCSPlusSigner(); + + signer.init(true, new ParametersWithRandom(privParams, new FixedSecureRandom(Hex.decode("33b3c07507e4201748494d832b6ee2a6")))); + + byte[] sig = signer.generateSignature(msg); + byte[] attachedSig = Arrays.concatenate(sig, msg); + + byte[] expected = Hex.decode("07eb19e7d838d71ef66b8263b5d1f8ecb3c75a5a8cce9174bef2da68e240f0b51034f5be32805476360a52ec07b9a85d655e9755c20b537d3958f3cf04bd9e4cccee4f739e44115497616a6b3f0f22de4430e08b3fba3e1c1f8274b4f26443f3d2f48fb56a16bf1cde1a41c047a466c97dfc395d00b66b85490d845925a13a45aae6810338c3665515cf755e31db4a2f81de06cda0fbb20a49d127695c4736d2aaba5381d5bbf2281228f8320872c64496622fc46d98e05db717d3e9d29eb897d0320cb13e5615b47cd81ab33fff16740e07f42702c20ac13006f2dc23c90d577d05b68a49259d0b2444d572f9536d50f36fd600ecce283c69ecfeade51d3a7db80c90370fa14e67567a29408e1df8268e73263fb4d60bc7e3e64e6280d9af1efe1fd8af08dfb6765a77f8f32b880ccde82d029fc5a32a940909a7aef2d7eea7b74c4a4ce06404e5757cde913901f3505bcea64e3f635d037370d2a0d0f71698023c06a8f97bd2dbcb19f6f4d1e04d1d88bcf9cc6e415eec899f379eadb2442ee3accb045b6df9db5e82f9f202bebbf9182e2f9493b5c705ebb1c0237ec4795a601f7a6e8ef99958e39bacf377c8566e01c26b9e6df4df43b7320eed4a06fb9e96a52a58ffadab4576dfba63c008b3ff69a118c019603ade1535cac3b3bc12bf257d0d3037074047b55363e3cd7a05d077302c6a2977d194fc18cba4400bf88770018e1b7faaee6182c3ab71bf0e9f99beb6f2b39167dc426cd4d7eaeca4bdc8621a984f85d7a05c4ceef94411562af45afecf3c351b3d4037a419276b323bb67460a77b394d1324ef3eb59e9e0fd2cccc813cd9cf7c80d226d5704926d609f9ac071d8910c833d8d69465e183951d2497e197e8f3db32d980edd00dc2997aaa1b600a5e3e621601a5029c2a92e498721c7e0ee9ed1a1226157b340f0ebbb181b4fdfa4cd5eeafdec9664a9426085dd7a2ddbe8bf7065c05520862d7881bee24b2d333b9522df21da194e99cf284700b35fe18baa678f1138a7e69cd26cac7bba4b18bb122bfd3174bfa6ced29c43be1794f3dc07d2b38419cfdd34aca4838b4470325243645d3aa5f2adbf57e6bdc1edaa62f0ec0a6ad67892f87c6bfd892a62039f273b0405a9f70e614e7fea358b4f2ce16847eabed36bab4a95bc0395fce442911c89c3eb6e1713094a4f9b9f3a56a9de81c4ddec2cebea46071ce577fe158f2a1d5466ce896fd74da7b78a5d2422ab94d8b2deccb823a630404274c57429ca88e52856ec36bf14605b3f88a2f159f91fa83982a4016f69493f4d9c01a149f4235f01826bdddf03973b980c351c961e1bd0cfbf45f15aec3b592d96543f7977cb8d4b45fccae486839e116eee6e532e157ca8982dbb75e755adca35a5652d6cce141009921724da0b2f5f1e88ebb42428111478a15600ec8e4c2d223c09c97b33607b05e984e7217a55f7776b3f9bc8936578f5efe4562dea3d1982424a62427403fcb2ad30b9ad8a808cfcd028e41bc2811d2fb597861d2ae696c8e6d49a9d85d95666db86ee26030876f1edff540c5cbe8e2a9ea38862d670359df6bcd6df7406d2cb23d9fb770d806a08c27002383d0204a20ec69178607820e43ac818f8c91019adf5ea3e691574148f2f5d678c94191982f18368878399c50b744aee6420224cbb4deb08a797bfd56aa3efe4fa54f5c5ff573ac1b6ac64a8edb9a1f16bce8d578ec0f5d36e86de7a31af23e6b1505f8da0fce9a587b5808e29f9c5532a75b69fc05c6f2c1c8c4d12455e43e8db661c66a33cb29edd065f33ff1157c6c72ac9526bc2dc8ecdee4b6ff949de5fb58103685a5c8346a7e201f74675e790318ed6a07ad567273a64e3893721794eab2cd9ca3d78648363ca63efbb1aca57cbbff3b38ac584a301d21f40c6d3e6bc661d4d4f96cd162eec8b2275a1a9536bb8fe4e8e3631600f6721e8c7e881366958fe0c394bb8c2e0df90aee731859c67abd043cb1e8dde8bcc928ad211aeb6c32825dfad9dfbe19f5240ba60aa6b6092557e05901dd03b6db67f3f12e99e46fa702671946b493a480ec4c13beba645b19c5a71d03a24a141645df8c85a1cb2e5a55bc9b25b29288fb48d854e5c206d6f5056c04c92f2df9a6e649aa7446a8fbbc013a08232999443e18f1ecc6aae31648b8261e5bc4d7afbe234807b2d6ffa226a1c7911b840648358763f90dcf9f774b130f21c0c00f4072f1f27d4a801fc3e835facafc8395bffa2bf0c510d5832da5e3e23d389a360644c86efd26a5050b5a92b83d65aa44967283d992868a232536ee4527c735091c10714b8f20a2297df62c1f51631c28ee6985a9df0c3a872722efead3d66b0ff04ef9038d2018fe066e4ac35f92654ff27cbbf1cf5d067c42f02267854a8c04a6defa3291af7585ed7deabc92479d908c91e605cabec5b7cbfd75caf2cdb1c88490ca136d7b55380ab1620ba1ca583d32e89d8667797c46956fd1c5abe7da361d67b02f7fdf59e540d73931ec578d936e3e3df909ddd8084dea2df604f1b90c2c112170de71681e359e31b1a915c1bc2a272bf26c381d119e488d9c78df4d7c4fecd275bb1e47db459f6627f7da5d24a14c4426ebb01377999a7ebfb8bbbbb11bac17e03ab860ee4cd5bd5e6196479abc369a47cc2c16e73d55bec5fc9397e03c0bbad28540990b5d6a6efdc3a7c9e23466f71cd1a92765017d6b4229da2351e95c85a70915dad1bb9c08396164a636f7e355c62f71c9c1b2f0afe2d1469c35e3b3ae7aac6b35bafd27f4cd6d6949eca4a8f7fa88c2f28083be3d3dda1f993541ca773c3ba449cc14d6d9ffe7e318e8887cdd1d3afc642747f762272b9465182d064e64be43131dae34d38bb35b182caf998cf918aad00bd09d5986e105c1b0f020dc1af4b483994146a8a39526ce49e00ca00695b406e962328eddf3b5599099735ff54677f8a6e0e6358dffdce841804f43651897726c128dc45ef912750a238e78db4cfc94dae2dd29acc6f7a2bdda993223a234ca7afc56e53dd749762487498c10b9da3f5f0e0c8e24eb4219ed1363989df4f33b67c0833f78ca30d380502248e4f7a29f8662f932fa90ff64b0a0d6babff78f963c274641f51a2274e070552d67735593f7b766ed198c74d54ea4bfc764968a18994c469eaa6aafea8b6912d4371f8175481d0b5d483710749c4a6d86e8071ede3aee45fce49247976662ce5e121866cf9af13039531617e29098d792b08d5b63097b83ee04bf7758b2b9df256cba121d74d6ed78e7367fdfa0555dba4b61b27982cf60ceb3674d4f7bcb0adba3b1ee2a32bbf98f820e7935982b765531e5b84b7dc64f5f22bb9e59181684cf9730babe6fe38bd4a159cebde33dc35b8ca7ed6cff60d844b5c1134cbd4ac1bcbf04f5054e0d58e2cbd2f16316e64a6720754d2f7873d7012f0823cc3594535309ac799a6783a987a2619ea7ca725d1c123afa310b0dae14696a8c4edc71cbc19f9f8c4273509a8475b4446512ab2c988fb6eef7aa08a5b3a1959e0ace5eb074fac96911694604c8db2d69ff1d43efbcbe673fd7d6db2524208d0ee61aab93aa17512b68bdb5733925b4c0168d3158ae9463344636a478e80e4ba0d97de982690bb54b9a94f16543d0793ae8df38f5f174c495dbee47eb98fc2dea600b080c9b2b7446801c7a3c5dffac1cf78de97508ccff81eb00ee58d9dfad9fe8184c05bfcfa958850bc57a4ea9a863f35abf032af0f264ee45f3ab11fb8b5c187d315791417a7fc490b0ea387e0d0d1c572b5d6c5146f64cf630532f3691e59e9f53f69615b4dc8988aca0db505c470c7f7dfdb36a267698e9705460870e31f1a24da92a91b7ada77dfa1875dbbd8907c34e6ab31bcc9cc23283e4cc6135cc994208793d8b271b4ff1f043e5c5ad9c9d532768a868d92c992e8893edc086028ee55e0bfc6030a83f2bffd8bc0646d616d9c11c1bc1bd5d37a923650bf4eb8379f9db1816a5716c1c76bb029709011e5d9cc4db2cd6dc9371a6a65fe1f5e9b41eec83514f96c323502d4b14ca15eb6e31b2980b45f00640c24af432da58f37edd34fd731fb8f491e10fd6d685291ea846396230d5989dd3f3f85621869ce58f36dce76777146cf7d6bd5471c8ddb9ed03dad3e57da8839846a9fd8528674b28726c66597b5e9cc22c607cda425126eefd88583a63e1dd456269fc261dc080ad9f4ea8f50186ba8a69b02861456fbeae17151cea196785379154ca5c250749161b2bec25fef7d4547b91bb5fa0d75cf5937201da21c1fda64d75a357b001228c0fb25c25edbcf9ea679fd2d578d9f8fe70bb3a02860413135a1b2ab4935f0c603855da794a3169ca206bade4c7b1606b2817468e09978c2dadcb0de366272bc4313409fbca4578304ce416e79290c30581bc8785c2a5b4d80269198c7b5d90e7e8bd35759334b3e70acaa6b240ec74c21ec488c9e311f331209853c57f66e0b0fc8ec0c9f33c7259c13a5546365878a2c6fc16b3e7cf3464a5c27a9248b707deb38903ddfb4517c20be4fb1c0dab8a75c8abab0613ef04122bc65fed14d2aa0371352fe7b5026f15d61ac950daceff9a69229308f1dccb829fe3d1595316cd57b8f09e031584ca2cbbdbf1933c4acdb8b3b58853947ad27e6ecab7f61f537d7417819649b015590c7ab5b15fd94107575102ce1c6bcfdfa713140289313821786eef96729dd8eb27ddab98519c7148445a42502f7c7889e0e7736487d829ce46acfd685ce2593b4a9aba3e2be26d63c8ba071747e74a0e3c7accdc1244660c3017036efb38b83e847a72bd4801d2951a4a21c165ede0b9a4b8adbcdfd2c57f31b8d90dccdc09b148a9e15739719a72cfe432f6aa0c0decff213a68dadf6037c836174dbdb07b945bd834da403a84cc7ce4f9344771dcf503288552e5b9a8971a0807a51000edf2c62df4164b281de0c20d75bad71b736fc823e6852af06f52c4a7152cf3c7dea700cbc6fd766bdc17c282864d9e902bb05388582fba3dd51e45cd89310bfad85883c9676464a04e2966499e5d1cfec1c7acb2264219e5c1d3e732656b760c354bb3637d63369e951894c9f4bc13d3ed6f935a82eb65b687646ce04daf93a6f617bc789a8de14ac1281d1ab3a86347c844e4f378646984fcb92e9a3aba1a4a2a58ef926bd096f8038cef4a5003d0c766fee76f1e1fd24b73ee469fcebc2630b5b61e24fa80819d0c6da6150859c6be122b97142b5a85509a0eadfd853307aa5fae1dac276b515fdbb71ad5e29e481392334c9bccd365db88e04692794578692b003b22d5e41d5534954f31c3cbe849a83c1f4a27b0605d6f5fcc469132da267c343f05cf03c54cf0c2c9e13e3aa33eaf0c89fe85c88d0556c331337b77a98374db59861deedddb07349437c89bb2921a2fb24c57ffee844ba09f7d8c4808922106a5c6783e275c9e2600ff58284919ef924fa6e5e4cf3f05bd087af998174dadc2c2d53982d48c3cfdee5700150259194d9222da67cb9e4c874c4e2f16a61ca666f6d85358727b5d34f9514f2b3c94fa4d1e94fef0d3085780a2357b7b4b7d466e8beb5031af6ef7505f9c3d7644929fdaf31a60f906efab783a4598b7c18459c9273dfa90dfb8eebdf8a5c09119bc962552628e494033452d1ace703fa16f8038ad5b4f13205beca166fe0bf666ec5bf07044163f077892594cd25dba2544251cf151584b6b05d01b615a3a435210ad2df2bcf71c455bf9f37b8405a951229b51cfb458bf74077c76b3742efc54cdfc05b33220661a52e7201b75946d052c27600b8d097969314902035385a5e231f51647d368b77506fcd0188e2a833f0e7f05bfa68dc72fe0b30fa31d88885c4001e380eced45c3d29a0c2095dc2a15b488c54fc229417d2a5b7f70df295e6efe387b0e4f3dfb0be54cb6d71e8da6ffa08965667424feb92026a1bfa326268c422c6c37f26c60df32aea741391b10c9181d9ae74766fccae32d07b97c47ee7c5c507ec330a62e9bfca5eddc8584cca2a7f50e67a3f247d48fb0c123091a3a9bb0ef34155af4e8f00313ee56df54c6911e4189aab5b039e532f59aac304e2ad1daeaa416db83d28c93a72fc5f6da31a38ac65a2866ffa2f93b3454cf7dc6ccc29ea99993cc34f04a1164c0b71844933594623faf2ac630fc54e43c45f9bffdd3b938ae2aaecc19231cb40ab272ae0a0ee73a8678b3638a49ccbbdcd1fe210ec43c60afa958e70ee344690173ef7a2e991656371a2a9aa569f500c35a3c110ec55c661f34b1a6b10a9faa2443f87971ee09dcba49cb1b31cceb5353e1486a5d90a60711b276008468df5544254b39636a829126639daa4eb7244bd67b1f093e02a433719f21db74433c976e6af6f9c073b217b294ba2f2ddd843dd409c3833b2c1890ebbc5a7bb445158fe936119d2d367eb4cc634a5c39724055c7e26eb215f473797e3785658d1e34c79a693197f51e822273d0807dc25a32c74f6fb396fdee5cdaebecf154a1d093b18715a05467947e31629cb36502a5910bdfc63c94436d3e5aa2d06e1d469290df1fa5e92c610d2ef3910ffb4983100c21ff3ebe06fab18ea06a8181f610cfd156eb566908efd0d834ad7d679d2a516bd2d20bb9bf766885387c86f00df9c2a9306884833e386241c8fc875846e6565005949cc3065525628e6af24c05736aade1b933e700eb105dae6ee8ded902e34d9a57d8428949a81dfb0cd2ab5850f860d7d6910131960266fde6eed77f268f8e1b55f40cfea2a6243033d631d7eb5371304dd39bff262d139de79c9ae8817935a04e433e5e363f8bf32ff42f41bb97e12a87df66ab3817d4fc8d85e6b85bd2f0b1fd99c698d635b8d038052001f313b1c78d155e3c4dfe27aa9718fb24018ba69c585b2f3405ae66d916b69afb1eb1ca33922f56a39c13227307dd92b092dc7076bd7c4f5ab14bab31f295082cd5082cd6ca4567d71d0f33c27e9b51ed005a24de8fb1af3b48917f96af89b827ee4568c92fa77a1d61f3e1112863b7c38725ed7090a67b8c0e7ac812a6ec44dfd413b9825a4320cd092d7544791e94913ad63cc56b80231dddd1369a013fe68e1a40e0c4372d30037c26d4721678d9e751be086d2126f49303cd3290d686686d24ce894e6ab40b5b1a1346cdb114554e7bfa33b302a927907ec38913bbb7ab0b1ac5b2956e8d84d4362bec453ecd959b21dab4c26c2ada507bf92078d07e1c5894bb10415d82f3916850433c75f74b776b7099f724225ad61180c8227cb4de74a280468eec5dc747e00d36d998bd2825595d820eb163846278bdeef262894813e2971c7b07426844791ad24f6ed93fbb4ab7095b17ee13843e077b3865fce51e75b5d8dbd2c68ca66c07ea53437c8a774a33e8b343b0cf1d57bddf01506592c51c25ea6a5801fbc8be584f8b58a7fed58e69a42cd46034051dc9d02b7507067751a14c8c71e7b88d0a26bda81dde376df74c031b9390c7dba820017d49f0e3eea608af5b40db998bba8f4bcc3e321f0ff6b787b372c65b046c55d31b063cb7c3aa8ded49261d69ee0caa6b5c3d067573eb7b78699ecce3f89fe4d909b0d0d7399a967e1eb98274b69d6f23f3bc6a071f37bbc922930c73a2a1d131daaad21ee6c6f4896b179f3ab5b30a4dff66308f49048c76480760e2a864788a91f7dfc61a0bd0ca3f6cff01e780e698b9e3d126e72a50c2b16b97d72cc3e3ffaa0839a5022d0d339d005e80b565a43c6734e299c619da99c70083e8cd13f3e6ad5f6ce814b7f0539fcd467013fb6cfc666b23d50dfee6573a51454b296363d0064d079022b92a5bfdfe1033afefdfc7a96825d5d75a4c65c92248e59b191075651ef1b2057b0fb82fa6bd62c860c3791e9074336efae3e9d3840e1d286a4d07c4021347975b65d7446f980795dbb4b00d8ccd92a67347b36a9c767a820dc1f3f9f14a099b298720317f31f17ab9aa4cc0bc0e320df44031c9de5f2c9975d5585f1f6f93a56ed465a1180790aec83212236ea84e3a85f3be50781e4b300c5b047f0e6bfc692b6888081a43263ee4178f63022f4eff9313b153e115558916b2ed0858cd99d65123e59b9508f44d0564f61d1e71b174128633ed4c06f7c240e4db9f15627d1242954344c8337ddc0b9bf5cc3f3f849e1c58f9c9f8fbbae88e034bb9d0f9c6fb700d3f3c81eee70f589ea35034c966f6d0da30a61a1772b0e12b1cacd27ac27006955c313eb656c9ae0823fd039406a1a4f59ab53a29b4345bcecb8cb68194962afaa9589cdf7bd2ffb385cdd8a37bd66273d87b68eb272decde294d8797c51755bbb1ce98ef75ef6ea3fe0b9e90cb0cbbbddc101d502af9271aca6f1c001c54443d4068e8ac02893ef78ff60d7454276a1a96ce8be1ef4c27376e02dcc5413f08b2d5dd5762ef491e0ab191f288e6f3fb34a58ca6f50c5fa1a01d844862fa8a5dbb372a472a29a7ed8653d08d39a9dd18aad0c7439039bd33852918ca011a029ac178a2a815226e8e8b90c6ce7e2ed3d43c121c0bcb322e0f4cc33aa05dc516df6048a65bdb3906e138e0ee8686f1c54391640f95912aeb4662b81a113b8de8e8a5b65851f96f97e678b000e6b13bc6819b93a29deb3199fc372a53ac5d23ba3e730c28d705ca2427cc87578142990eb1fd26bb17bf26392ad03ea93cf40f359e5a631c112f25bfa32f74e572604fba53e5b73110ea9b42b7e60411f10b9656c5d944a9e9a3c2eece349b890e5f830711bd129d1dcd5f41e7782d8fa70460f56d13971ae7e9fb3e91ce913dbf7e44a9901f5c713bc481b9ed20f3f1e4855367caeb4705398839403cc631b72364a46916d30fb02966da979c9ea5aac7bcf97da339fdc08c4e00396f96692e62f9c6986fff9f46958699e4e96c5a77260a01f828b206234e4504c5f8c3275441a86fc9a90043db5443775727583950dcc568506a86bbc0a20c3fd05a942cd217ea8bcb2afa05946d60101ee220430cb116d6f3364416b50cb33e55f9e55743c80efa6bc1efc1cf64a4c85f60fb7da88db2ca24b13323198ab20c80c6b90626bd514d945ba959ae5fa5d2b008dfeb63cd334649253bdee147b0a873648a99ca615ece456e6d85080234c4398c02ad9a5e2c5abad1074070b294d9b16ad8c71dfee9b894a3a203e87efde97a322e83b0ad0bc04287e5693ffc0dd51c9542219dbaea1dda7199e56fc03898e956f5850dae83c4bd91263269c2499e283e55fe11102385d6dcaf235f7d3aca38837148e61eea3608b641296117b8256c87f41e130ee5ed0b612aaa4530fb679081edd3a935a29a66e4636cd886aea80b44c5c125536252c2c614b391a21bf598283b581a6831d58607db09fd87d8e0f0964432ff0206d9f0bf29f48e82b54818c7830064e7364b8622d228148d2c61faa377896eacf8621e04e84cb9e5c29c56920a3e7c4133e6b60eaacea1badbd922c672987bed670b47e2294632a7ff313684675966f132207c17946381498cb2cb9e9e11b6911308c2c6ab8d115e155a9a65faae099cc5eb2a140a222556c4069a08bf0181c55e994a6c59f6a3fce26bcbd4ddedb5ff9f1fdb6c4a622d08c19941d4f6a49730296af0475cc071cee25044ad0a59a88538c3004f88309b8bf56c479b7057973a07921492043a2e0362c2c5a44b1e1f1960ddff1764b8d4e612fa0156e3ae712c03febea5342419ed55cae6b02ac635b1db68ae489368eafa943bbae10af93312dbd6317806b7e4685ef78b0109fdf5688f0f0c8670c17b8320a0d2521dc3d8ef9d5590c8431ca1e95b770cb88189d75f26f448a3e7d60f44405824ba82cc48daa805c423edf2d2cebe504872a4011c23adf45dc3b6c253e9c568efcd0f89ea398b11a117b86e5c72f13f0ff3e5f58c24c50d50d73c9a208f09399586c3b85177ada1eb97a4e10da649466e3078f26c3624cea2f8e43ac2ed00fc8e3215f812317bbdd065beed93e0c27ed828a9f7c53fcf4c7c5711735aa12ceafac04d1b720fb898d1b629eda2e2a208c7defca6676eca88913fbeb57d2529f9b28c269d62d8b863763ee3221686e04aa97964033529247d7fc471540d6110b5576d4b5007c699697b240a21b4eb69aa3e3c250c51c4152e16bc5afb4ad37904c68597403e6d7d3e22b4ee2ab08ea52be8ad814a84c9846ffe0e7f55c22f4b2bae688a984aaed56d19b1fe1ccebae2c39b0bfc8cc233ef9c8425896fabe75556277e3312f34f9b3352396c37e6304f25ace940abaf0559039dce13295b8dbcbbb31c7832650ad9b1f75f4f3619f8278c202e1aa8f3098faead539097ee595a10e651f4c6413641a69118f9b04ef64d807d6973469fbd6195d41bd74f5581df027104198177ece36bcc9fca295d8574b6d1409f4f0d5886619d9b05b7d0e64565616cc63e14448e9e38ce53dd6606dfcc57ce9ffeedab387fbc65081c81c31141d88e8d7a13edf29bba7d7b3afc009b91f69802e7d50bcc5437f3c2365e5e9d51726cce848ca9361e7414d2d03b373a7a6c8d31e11935840aac042d427915541a813c75af0790dfd420c74ca573e9682e68dc89ee80ec24ee929f2f75ab4b08e50a5ca9fc162d394e8130295d816d058c51903e5c570f76b8071db68d82c26ca7944d279ba8a665c1c033586aa07dfafb7746d124ded53579fefe34035d76bd6c6c135e96271c3dd41e897e98dbc699400b13849ab978e50641fa1fe80defd2fbc77e625e884741ee44ec86fda946c2e63296b8395668ea9c4528845aea9a73010dbb9550cf8504833716db1f6202aca0fa5d666588111a6726c01fef920ff854b2be31e95e0dc0c26bed005438bb9bbee6d91fa9ed02b1542fbf2c0459ec18fc6153a07248fcad7e2c4081f3aaf467f0da26b0fb9d5ed91ebb4979df5acaa3f88764bd1548347cf9302974481715fd6e7ebcf28ebc5d396a3e6c758a3ba8607154ae7b8416903feb584479e7baef58babd64ab81579a02877563856d536ddd38b50ee270c4b754d53ccb72b58f455d434eb17dc98b63ad37c622d44bdc4c8d42b2e3945b55250e1d296a83b47d0816e9ee9220bbb7bd21c7d7dac5929c65d31659c0490ca5f38d3cecb0b49f5c01c5d8a28746ac65a65f2f36cf4c91cc1c252a56b8c5e92974b9d91abf14f2f66f6737d19823672966ec445cbad25d26df2daac5f90bb05bb72197f327483ebb5de37e6f23370f04cb9ce6676a2d8649d7464e70e7fa3dc0bfe2a45b47e83fa782f6d07b94bb6846fc726648aa835af5df505f997206d4a380e24ce1f0f13145980e0e60f822cd650e6aa5301a8b1b928da1444569bf78b0588d5887ee42f09c44a6233f98fb74c8a29b7dd632bb10ec0caf78ad08e70a163e0e59d643055d8b6c77eac7d50206104fc77df8cf358736eeee07d147f55cc6e109c659af83d4ad22326bd92f53af9771f346e9efb5420ff36262087e0857bf68e589ec75ff47d4add188647b7a2307d67755bb2ca3bd036a722169cf3bf4de44409c9fee6bb3b3ed0659ad207f56f6a5f9bd2d2dfe2c337790ed83c39ea08f5b701761fba1c56abbba62288ec2b9f01e7cdee931926cbeed0ac0af449ac419a8abde9a20e5dbcc2bd9eb5fcb2b162b598e8a741f7656cb5c8fd251f09922be85ce6958de2a1f36ba3d9dfbe7eed7f660f7d28347cea72983413b8f81f57b69761a3bb3f7af730e1ad34a28ee3237f3553673d8da7b0e525a317db7b9cc959f061942508366de5a5c025d1de3e60e8f4f91a581c69feb4ab5f60eec9891397f6a9b63593691a7ae02cca693f3eb866eda8f2c2aa9cf4e533208c29b73982fd8667911fd6a4317fad0d8e0860c8c562f8ba6f6f25ccb313a26b2a3e495ac35f53681bd85e912168792c4a3136168189b395dc04c057faddabfad25f556f72f2a1c031d8d891dfe6c368e4c265a7970b512ff4c6636042f4ecb88d95723924b192b50d26d3fd5282006a3276b765614884a18a299cc712806c26ad9b45e369fe2e23798e03a62b378e5780958c728670d8675c6247801475e322edfd57a7770cccc62d1c7e951337c8b4f8e87cf362c7f844a8dfaa2756ced374f1d923878c4fa6c42c0bd5338e9b1dd3335a4ba753d30e5cafa404d4829f032cecb5258a48bd4eef786b027f93de0006affd41be2f710448168f491180ecd493911f6b4f82e123d9a85a2af8d5470eaa285be41c71cc3ef92d5902102fc74e6028c1d633eaabe06488b8d28ad98a97a25ef3127c2b6edaf86243db9ad68e2f7e5a857f2b3c2fc079d234b2f05e023b6704a4e3b76e2c6d076250bda44e439eaa1ca4d89d0bd93bdd2e270fe1b9bb68f4b26169f0b2ce1697a148baaa894ae8565e6bb50def8285ef22fa689fa64e408f5c2dea265e6c634c653f2054bb8172b83b056570db14edd56a6ae73fb910124de2645ba3d77202d2c497c067a5c5dfd6d6268ebef73a9193fa2a7558d8f9c837ca034375b938cffb1bd1962e1ba673e9b9a471bdea7073460e218493bcd89b8db7d08db57b2df304f4ff1b540b6fe00a66392f9fc9d392c90f00566f862880b886fc60a79ad69761a8a48e9bd76d853542b15ee771750b26e69445aa362ca5e1b2077e9e2f68e064dc1b032c9b0e81408aea1f36457ee45feb43f36b68707b7db4329f815cd9264c4426cfac90845176b45cbd154ce4d6c4fe6d4762765e2434967ea43b6f824d3e4e38754361139bd75f45829b8b51c4761434039ec431176b23b2c41ebf5aef1bd673cbab6219b0f7733a95528ac60f5e1e5511b5ff161def464bd57e60daa2d388c9d6b0df9ea586312d1e9e565b7a1e9ed75fb2e1a22363ae62d34de32579cbabbc206cdbd2305e4a57ae884f48756c034eb58cc78778709a54b0bd78ed7303eaefc19cdbc89bd168e92f4cba2a1c1ad2f3c76748292ab0c957197b53e533836d2732f4d07760999a181bc63fcfaec71b3aedf829491be8e6634899a04e16a42c3853268e419410353f902940e06261312863dab14544023f7aae24a2decaef4899d3830a73dca1f78789c8137944bc6a0bb5c459e830dba1bc892adb860fc172511de3b992cea440e608629aa19a89230bc882c4f1bccbaef0502138bf19d1f85cdc1b2f2e2d3a0b86acee232ef07761007abc9f032a1584226119e1d3355768b0c79de797cd2673d85b1896d03a685fb92d3844cc3410a8fe95f660b34badfacbb400d9e74927fa12299085c0013f9db26e7e4730657b34513468f631923748e486eeff792d91cc1fa49a0f4831749fca2f7e90cbfb9ad1d6f744ab0a70ec050213f013d214be30988e7142b87996d3603aa71458afe03c34ffd128755f9da0efd02b0be74cfc7c352126c26bbbacc22a4e9f8e7c54b7f82c1a92aac5732fa660d4b87b81011ada8704bf042c9c3cce684a9f26a858654d9532f9deeb2a21c9f49f97718d973f5d4a7db29517ed97d53e8fbc79ca0fc3785bba430946dff26447bb386d3ea2eb33e4a06f5936c9828628329826d69667f90ca833acbd09300a66f72dd7b0b3b25bfc5fcb368749279b35da8a094230a9099b258e96b053b8cd71ddd38d27538264fcb014d9bcc5087161165123af8751dfc78306861fffa562ada37097647af4c97c8931edd17a57beacf1bccd9c19ab77713545698f82fe06be0db715626d2f5d3cc26ca335f0e8f1c39f8bf19fb273f27e460ca3c76700ea7d7f3af450d83aaab75769e8c3900f7300195b3aa14867cd8b3545ba0f229ce1d6c4daea4332e81a09c22bb4f25ca65f5ef92236d0be6cf82680891fa0661782911e2994aa340faf8259978255245af42f4e874116d4d5bff848484fc91402bc213078244c06dcc7644b517313e6d7182228495965fda2056d8a3121e8e24f41d53fe67f2d38c9e64656af2d322c060db14d512642599b78b8d641cac08b19232d6daba8cbe3344d0a9cbc5cba4af5bed9e4eb99e7b4466c4c3597568ea85f9f58478472c77b482762cb67e6dafba3e601c67abd832e050551e50332e5f50d4ac5933a2d6f0d3a5d13b52487e0a7ba2135062f8def1a16ad81087191a67ef4bb72ae2c7f638c36ba8813fff1c2b3fe30e6f5251e43552f8183b7c257ff431757ec2e99d3c44fa6b899953035c54e6beab27945d99963ff55e13e9bd957696d9d3547fe507a28f221932c1d3424b12677c526650dba9319fa19db405a9f0124106bea4090fca7da292ef76977bf923a2d2b94cdf1428b2ecab57602db125a56bf0942acf26e2f8aee539f231fd6da8c80ff384e2cad440b9a37cb2f85f62f06338bea9538beb63eec290fc99a9c2d67017483a0396cd99415c471037e686f74a22cd605412f5442133a54e7ee618ab3bff32af9a402fd4ad6e96e6a3eabfdcf143f86107b73a395a967ed79bad251db8549141322b5d6283cede318e9d3561288c0774c60454ee7c4e144e623f6b0f14f5a927f04d4f5a2bfacc611d79efe06f7f0139dad377d0a7d618a9b7d1449e43ae59f410b9c1a3af0e3aa83d1b17f7c1fd13343f0a0bdec05ea12a97cd2a59ece2064ee260ad0fa1ca825635dde7956aab8f11c0327051086048eecddecbba33af92230e451c7325c0cdf85dede08e23ccfcb79e0900a669b58c77caec7b1c2d40f2769a52333407830bf266462ef16b0a97d0985635cffeb0a2e2828077f204f3772923c726ae3542a10b5aa5f3d6c3d1c6f2db3b8173f452f53eb3acbca44b7f46c528872f4158e1b80a5334cdc03a0b86ac1c363d776ea92a7beff0f510a1e2a208baa91ba424c0e5622aa4058adf82489eb042f56ac15ec6c8c15298f76e18b3a85dc9ad12022d3961539a5d63adeb1175ceba2d70eb15a8f8994b55ffee1d2856fdfb1cc65d0527a32c0be2167db2d479576ae3b7fac0ac8a946e2f9a74b0011890594112e5e8b744c3713526aab972a6324caff20ba1f9f872b9d859a01c95bd0a87e2a2ee7b668b3f096c2b09e346bdbba9718a1a644d5dda54d78904f1b681767a76c90366992cc8ae25f3d3cec9431e26c11699e4d469a7f9c420987eb5d655d7b02167419215e2cd0513dfcfd592c2da68faf55c9eb2d7b2703dba16903320d3d0adca318d20e427bb8202abf02f6447730faefe5f813b8138a6eee5cfae4680adce3516f9498fcb52f63cc2405a74274db6ff66ffb51579f880764282d9785ab9fc86097e0ca0e5704bb160ebbb0af980b2fcde5c6d22f755b635f1912a499a71876414a7870ef3e273016cd8a64e08a3af7ad444cb5d53eef893e731ab0f630b4876a7c12510a6c1ba785c8f335e257685aabdcf5396ab0078983a35b0c15b238388f0701080c7d5a60cb6bc3b49a7666957b68eb395dec737f77233a7f70249b0747bf83cdb1f1fe240d3d7aeb9757be2678b07501176bc176b1e0783e43ec7665af7e7a24eda81ac24e959df75602aabbe6c16c78d43d977a32cad41fd707d7c0eff936a00b87ec7379086c305681bab44686e3af96e5009115dd4225d79bfb03488e6c354589ba4dce00241ed78f480538555b53784d32d24802f4215147810a77ef2afc3bdc4bb9b2258b4754fe8a0d1e2ac8ac374b8cd17a83bf78619d607b64cac861c04b49635bdfaa8d7fe1f86960b1a7c829e0fa4044fe511440d9376c3bef009b5aeb6102a05c3f5cd6a203856880b1e2285a09441ad6e99a5d1fa8c5fa772a7c6178a18db7d0f423ea6b67bb67cd2e798b9ff17f52cc5b69e9ed540f3e82e81f2ae4a3a89fd3f8bc8ffea256ea256540d932830b434094e417ea30d7b443c5de1260915170c58e526276de8058c276e1c66690070fd6297145073d14bd0b8650d19679c13fd41e30b91b7c9d71d5355140f957ec4b5176aaf5e06cdea03f9f6503e0d11e67e3d53a145cd065852f792d85660c2045af022129d8949feb7e4b571a4f1c0272f91510f3641e86387b7971111db62055462301b71e41249d3860f4aa671c147859922b9aaffe4515fa9b810928a6cf6eb31bc859222ec68e0bde9c7d95f7f35746cbba68f5b82aef284df6df1bfc5291f4974bb2c6f53a6b4de06565d26bf8e844818219ee9c1663fc9a3d15347cf704f3bc8c3b16d6ed5a0499ab631dad17b385db67f5ee8b95d5408f737282c2401e436d8a3ebd29b96e30c58c14b3febbc64a104f04f76692c03c46e3ba4275e77b1b02abfbe1939addfd57fc95664166e2db6299525fcfb37d5f74597a27cc97abd07ec2151c9ad3651456100ff0236ef2e179a75f70c62c7d5ddf076bf58dd8a085999068a16c4983216d4db959eb141f7489dd08cf4c095b6637a5f3dcad23ed9bb8a814d165305567cb589a01eaf58cd4dfdc6255e9c443c29d26bde4e9cef30d11db5665d0a79bba44e3cc202fd834ffab5963db6d1daf38b86e158abd1894f6e39af445e88fb338bd2b98d7af690a068773129fefe0cf6d1538c2fab51c5fa54dc9522572456352aa45605b71b04ec3bd85b4f6a39c66070a4869d575805efe3270ccc0e7c3cd8e8a97873537c9c492e267e965ccf67d94659e822b798fc443cf4214d26ec071d981ab63181b20cf827732dbfe2452dac746b1de8f767ec305e1159d74291a787440ea2a7514a852ce73d9bfae5c33434bda2c1c2a682d356368e89754ee694a75fb1e4e9b140e2a325c28469085931f00e0439bd8a7c358d7430cc45032de5b7d1ea9f7536b64dd58754e352925fcb88d0c86a866da3838e301324f3106559dfcafecdac74e2815c6b50ca3909795e060393d66e92d668b73e43d4da0b8e22863f7d105a442879e899c65bce913b2656634303f0b85602fb676e17d8efb9e05a24b14a1a79e4ed9cb133351314ab8ebe7f5489c220ad4a2ded294925bc6ebb146f786c48c1ff9b11ef6b055e89564ef0716d5460950ac820ba76cf29ede2ba7efb41a1678c9624e52920643366e664ec931362063f594eac59a7fb1949bca3d58f21d261302e802270936382df26c14c291866a4fa1341bc9ca95e38810cf6505891dfe7e552775eb8785f20722691372f6ff95a0d1df07487b22b80694dc74a8fe528a17d299720c37878876a042648f47edc2afda778bd1aed75ec313e4a40c5ebdcd9a2828ed50656096aed39468f39dd46c915f7fdc466792208fec4705ae82e538c327936f80314a506a0a0d950f5e035e845bbb339363d4318ac4d29d4050ee1eacc3d7d4823088451273929e00ff2a1dfebc77c7e48ea609036625680804e562af231965786d52884e531ecfff2a8cd0511ff6cb3d5c8f118b324d23498c54ad5517522f629e34d345afc76b9fd979fa245f5a95ae0cd51ba121bad92e3a7bf9cd28ebdc857565a64bb6e693f09da3db0af9175ffe528d683b031dc77fcbd2abea875d4909d11f5a1fad162e7ccace955e7bda4643746d32c1234caed4a4084e8899e19e01e8fdcf2f0b0109dea1c73a272faaffcb9b93e761c805c64a33283f4763b742100d2a08f368cf6f1853cf7e8500d95ddad853f766561a7bd3b1cbe938e9540c685c2698a0b25c06c6e5e0dcc27ee079ab2337be8bb84f4fbfd064d7cc6a220a1154ce43395b2a3465ef876502d3ce5470e090a1493d81bfa87a153078495abea5c95710d0ea7ad0c34b33c053353bafd372ebb5b75d0d26e15568784ae013f9949f216f9a130235d4a7022021f76d70e34abe85b11cffcfd42dcff0b98f3a5c3aed63b1ead24b6830ff16992bb61882e62f923ef4aa611bea3df43d7ae450fb4496d300da091794953a8b0b70e23d612804b477abc19207ee909b0b88f8f3bf4ccc34dbd49d2f528b3b1d99058718a3e7079080676ef3dc7ee7d76e0b4d1ee68da4cf6d09850fe055df013dad5d09b96edd0cd8e3c5d6e5d43f94b8199449f6d693b31c089fd443257affc9339e11b577017453e797930b7e37547ed6bdd06cacc2babb3331099dea2fee24d588cc7fc5f0659e7beaa8a4a88ab25a2d3cb18d18240af9c8f168b80f5a3a697b943ad7229b4bd978954a58beb202865d124436fd63bfd9938801fd1376fe16da2f5fa7287e219ca0a6687ac9ca76f0ba52d1b29d126ae56c786c04e3fa4d4f3b9fabfc7095c007dcf35f3aaf5503d5750fb62f8ab91ccb70eb8943ac8b3de7110a57737a261f42a023e1545c999192e12c88807169ce515b3df4c69e95665973b596bfe057767f570b74aa503080a66774640b25642c4b00dca3f4167e5a7481d3555dc46d96d6d7e3e214e39c3c422405d19a568f04c5229d56a49d8dd5f55cc74a702f99aefa33c29a7d15c971c91081d9a93cd2d0037cfe96f1ba965c0a78071527b8021189a866909010bfa9a0925581075f6f7eb6fe7f0b58bfe18a67211b0356c80c8f5fa7e21cbb28142e4dc0a08635911034155645563b2b2b5d7e5a47600d2fccb3fef331b75ea36de55f6eb7ac1f726ba825d7bcd83c4c3fd0362ff51509eb9af46c8f129ebf6c8ad63cd126bddcddb145b5549552ffe846bb2af1638e049c6e0be469f5701ceb7c8a889dcaa3995cb920d938c617ee376389736ae12430a96467a3843b8e6f871607d68af31fa4da8adf70d35a5a6bc0f813612106945d7a0c427cbc169860c59e760c618c04b670e412eb78bb1de21bb70b1e26f40d19c7e674e3a831a8e28b55a36feb4716f61ac5302ef6702c0204f599a968ceba45f47375ac17e7ed939ca61c6108d77b669a80ffccfbf4fd41e8ab39603579cc88351816e111b6480953f2ca88991f944c3ddc7788843276e03c16ec8d1d69cdc5786609e2d45c146f4af9a2c7a5e88ce9d7232ff35036290fe947151fc6d86bd412e5d5a1e3221913d58a3d83e2034ed60b38d65651223eb7ab57ef89e813898d49f1de808c92470a1a310cf701ba1fbb4d8ce0064f9c3857a6505942bf960918e3798dc05aad2811be2a9e42a1fc4d41fe935c5ec39040b9401116208ede462dd383b398d29872e0eb544f1ae74b3bd76bc654c6e14835de1983769f65619301cf31c978563f6146188d05cf340965fd9318872ef09b75989d69f444a8816ae9ffdc6286316a9d62cf1b00ea6712927710dfec3985b63876d53e93e1532efbc3a428482dfc67e0ec9175e577ba15067a0604ae24b50c13cfd3d2e6ee9351bb7a7d841366f64a0f06e4f2b9080ec4f31895b8a0ec6aa850c3b51c6d61dd4547abe777a895e4449014e2ae084c46a1cf8f92f34559511136f4914fdfa53f43c424ebc2e8f6d7dc7b99acf6520d7326a3febdef9957acf6871f79f1f97d04604b2516b7ddfcb152c2dafeb0af4c5d1961b44378eaddc32ce2b296bb4f8f70f998f61e151faef9074b489e4827aa11e24e955490544df36c222bc88159630c79b48dbe0cdd4e6786feba932d8f809e290f1a5c6059520e8986240ca2b040bc0630460ee0f415501693132d788cc47034552ff07a7068f838d8816921d9b90a480a303652aeeb9aa5a0cba2bb89e8f0477e46ba18a88a975ef6a1588dbb792b6751d88d8dcc2c190761be040c77dd265594e7a47a2486a339fd6c2bf0b38403491ef5120be6970823c1b8804352cb9118b60af65bac2d308547cf8a2a3a2dd612f5bd6495fc19a926555427d408b9a05f7ac1d4298abd8cbe975aae2cfdf2acc66a7ac06c6c2e6ffcdb7427f7127e2a15967eda9d1f6b1efb174a5454df33ebf31834d2e475a924e6359b92b0f58653de279dcb7bfa4674220bf52191ec044fc5d03ec5e9275205d8ae0be15a271b502db9d0a5bddd6157a6be27609e2c6146b983265e3dee9a2db24857f4297d3560aec0e6b20e57cba8ae31f93b853b07bd0ccb1e7597d8766d47e6ec2b62e8e47addeb517a6ceb281037f037606bd53bf7b4d9fee34a3163eb47b3719db6d18f9180214c5e05f48b77068e44325a9e726071b5a4991e43abdb48114f05586ea08bbaf65b1d5ac1a66fef935c3930a65769d28d45bcb5a0908d50d264daccacd14946c5fe830c1953daf239196b6e37c40ef69eb841744f4c602cfa1e75b3262c78fbb69dfd4a321899b498064f09feb7854537c4460867c26743f3c13383a27f566bb21c947a43dd3fb26bdf348938ab320a9739349866e1199b7c2aaa494db21f6af165ff41473a7753b89c2deda9cb2cc67590a7cbb1caebbe38a29ded5223c5a13cd9cc817f973a73cd3732b748a3a49958f2306acbe8c683c3683e574e3fe821dbd78cca9049c90927232279e01dd7753abaa1e4953b8db835916727f9da3fa21026aee406b9648cf453f72ada2cfec1885959f49c3adfdd2d6c8807e34ba4bb21981ec3e7fdcd07c264a038b642d7f6feb6f37a8ebf634c355b157d01f37b37481248e810be8b6c5865be9ac5c08fc3199c9827d537afc44da4ec05c83eb15b0babc485f99c68336771d0d381e32e1a286e706293ec641ca7b34f595daeaa8782e8fd2dd46761831599b6f30c39619fa7c94314811353c55bd7397b944d42034b30d21af7ed501f8d673547ca5a66d78c112fe53b7c95447f1cc420c178bd137d00f848b8c314af94d91f2d38e8b80062f4a964a72be261b4ff4d98146ce0ee9187f51faaab797718c39f310ce7eb8cf9088fa94a25c5b9ddcc6e73a23bc601191569327fc40c661293203bb341b2a05e6174fdc5708fed37ffd0d460d9b40c4cf38b84f28354885c632205e63aa148d40dce59d35b964693196df0b23e6e59da13f4ee51a5a2fbda2a46b26d2c1023ad3049e43d259f00090eb5ca462c0382fecccfb3bc8fa9a17369c382b9044edffbabd296e0f6f64325ce985d3d3de0a78093cef4265058e34435f1475f4d338c26d5ed488ec5bde3dc9f44e4bb5bb359b4142290090c8d477ca4e2017f58f5a363f41ee42975afa382f56ec43169ce6d3a354bd5e81bdd494e6bc207c54b2dd0131004155f9b23ccf5cbaa9c4a7c2003a7ce2c258b3fa0cd591c4444c81e24a96b89f3e0596b060ed75b3a666b147480bf685d009f9f343b4c31c3bf574dd9f588a723d69a92d1aba7ffd9c93fbe0c70bb5986a7f6db5abb06e01fa0639cba18624aee98811f7763347e752251c6ac7b7190fceb7de2689e5df43843a37644dd65bc827d71dcdfb479b45000986cb2099bda849b5c24c8f463c91a7aa8a02cc783cb1b7b7b77aeee46371dfb1f3285d1ebf42e079fca054530285fe0aedd28af7d3ae6675cd0d953ee1c9ed561e36a94ea30e4280c8db625a509886fb389a9918083e809a984bfe3638cfc74641416e46f70061d6d608b46080f0617f863e4caeb12b5fde3c2f4eedf8d63927c198b369d0d443dcc3d434c2a5c9fe673739265595430aa1f16ada43d10da16c5308dc22f9dae651daf948f03dbdbeadd96fff5385f27e817c920567a6076ef2a1696d848afec50fc1135e0c24b91978a67295be95de58abe17d933e1c92a945363cf31128159c4fce97abc494542ccd7e53e1cfbb9b0aba3a1876541661315072f8fe7e1edc76d3e21f77efcb8efc6b3047167cb931fc1fb49ba710797fcea7ab135c9d2e93cfdfdd081dbc6beecbd2e5850a1850a9a7dd19607d1a77148e597c4c1a0fb3b0c69df4eb06bdda38834b0fb1e2612644a3364976779848a6fcd4f60c4797896df4002dcd56ef7bfe51d5de9100b15e147786b4430368d73421897d405e29aa336d2e8edc8d7c4111996f9ba294a46b66de7078f3a0ba5c1d3607acecadf590bbd0ec78ae6563c3c05a5f12af3ee7d5e2b59105c51cbda2255d96d809a374f1525ccc87f7f560843282414ea107f7e507f45a6207e2f424ae7f7be774457f3ddedb11a19edc5470bdb6bfe28f5acc6bdcb180be427e373dacc2a4decab3965c6c8c12ca0b7f36e41b80a749f677a6da7c978be1d08adae4c41221fb2e8985e70710698e4e4bafa4e454815afc6706dca5650b399ed65eda7686e4d2e9226e5a7ad597dedafda00245d67ea10b3e0577e22f7d425a99520555df240b1ce422e5814f691c3953baa4968a090072490b470137bdfd36f1a69fe56f67891b67a109be900e5b3956125748eeb261e9a59aff43e78cb7d1c78678f8de1664cd24620d17f7b08eea1ecdf3989dd0bd6cbe65f656e0666e1d4b9da534fd31c32bce0ce09a88730f98eb60ce0404e5d9e7c679684197634199e5fc87904090033c5f4227c05a21323b9ca6a967935315a93e5c62b2c9d93fb77875adee72d1dfa1ff0c54e99f95f51ea72161a5d342baf43b444544a82041f70626a27bdf490bf663e0bd0c02c3e58b3aad8f09dd7179105e165c1e00cd668ee55e68046824db6e87ab8c8039e2f2151d3ffc90e8ef3d396dc29a822c83136227f6af5f4c8a4629e556101884d1838121a5cdde8b7da9757739f1508ff9013e6f4cc5ece012c0dcfe837e4c0b3e61b5c39ea60a1ef53c2350e639489715c26ab4af845d1937e3e55956aa124132fbd4bd983ab8a2f18568f8099dc1c41c93ee65f1c7d983d7bd68286af18f4fb833f14ed193fc6d4c6ce8bea7a3b770c308daedede36512587e172bc23a1b39f71f4aabab7ab6e4f471f47671e3fa015fcf6c0c690e96c8303a7f3d8c71443e6643cd1e3173eaa761dc87af37b390171c017dcd4c4459d8a661a6f087bce7435f64c9045e14053280074d2e8a4e2a105bad2c486540d90fff8e9565b0b827da9de8006b8c8b3ef4a2300b8eb02fd71281dac3efbdd66b251ebde24af780a8d8030381d3a127db273af5a98058f5cd90e45aae57ea90180bcae4e31fff2fc82443c1fa423f8311f2091faa96834b818cd7333003b8dc465b1dd30a80551ef4e896d7c2c61d21954ad7a14da4047af387a53836e06bad7c3284fefac431830934924196050d95ff65bdc1753acfdb4daa24be60ee2b9a61edb4dd52b8ce92e8188151aa544c38357a0850f1b8c0a5e87ba835c02314f0c6333a896d8d336802209e4b2d3c383516a381f316e46bb0e7b61dc1a7c076907090f03caa5de2edea21fefcd094aee704f54272f4da7a24a28fcad1083fb6fa0d0a98a398ef0f5eee704e2a244452d2d549144c4daaf1bf13b36aa141d145991b93e08fca049565928d7c5dbaf5f3130f54c9904521d122484c452fbd35e7342f698736f4bafe6504c9d1ee5a1db7048bfd49b94de09d035cba130d33116e1a64fa1e306daac7b4b80e9972ca3855b1094cd20110314a390533b82b466bf69398085e8c09127561123063dc0f4aa777c43f0bf3dbf1e434407b830bf92e93794431dd112153887ecfef20e47da9f426ca4379fd646f737eea3dede46844423d8a5ca52ce1b2b9128d6786d95a0de0a16f9f628a0f0b69b918216c1c050f0f3cd0ce34511cea09c0131b3fbcc228c0e89aedf5bdb717bbad0eda7fe7df2857590b5a6ff253562220b9af892aa63c2f69ee26dd63dd85b2e44ac4ce5a200997826f201cf799ed7f80addb06bc21d3c1a6752db79c80e2bcc42f1ba0f8c5e2701858c22e01867189a80efb812b0b1ea07441c98b90710484a1d5f614ab100606a9766579ffbc51df549aed9d93b877fae5322b44034e6771cc3b997bd8efcee3d15740f5259c29284005c88d9a845260c73ac79fe631fe8163c0233eeff32c2e768864e1bf2ec9f068108e9407e757e8ec76442e8e9c6fdec2bcbcdc9ff6b5040a97385759bfb488f87bf33a892e8c7d62fa18af0119ef51205578e86ef06880892653cbba2da5311c622ebeb1736fd591d45a8897153e0e4d83cbd9ee8dc622f3e6ead71de075186c8ab124fd3c8d8414f6f2551bcd0142032d4a290562f04c8f1754ee9e184fbe4f919a570910522e6705b451f622949ccf50fb2cfefcc845dc8f524bd31f115be6e3d01d24482ff6e415ecac4482ff8d4256255a81c388d9cb7df0251294b7e3eba909139a3bbdab78e0a5d40b8288ac2ed3df65747cc917a1f464b71ee8d7ef6c65992e785a4fe866ecf4ab2c3a4fd5dc95357bb87d444ecaea98f8493eec11630a75238d90a9e43290b232d625b6a3d36cd9b0db3e20072f8d9da1b0c9e5854c762593bca31fc58a1c324396c9f1b4428dd743420fc6214b5c46757e3f180a7c3bf4db5d7452c25b864a9c8ea424e13342628751a451988b8c8ca882e4d50ac95054e569db92b7200a0025b6a5c9ba1c25e975a81fbb63f235c94ebe56a3a7c10d015e63787dca099fa1a50f1206f5037b9208f64256e5dc14f42e741ad67f7fff6deed81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac8"); + assertTrue(Arrays.areEqual(expected, attachedSig)); + + signer.init(false, pubParams); + + assertTrue(signer.verifySignature(msg, sig)); + } + + private static String[] splitOn(String input, char c) + { + String s = input.trim(); + List l = new ArrayList(); + + int idx = s.indexOf(c); + while (idx > 0) + { + l.add(s.substring(0, idx)); + s = s.substring(idx + 1).trim(); + idx = s.indexOf(c); + } + + if (s.length() > 0) + { + l.add(s); + } + + return (String[])l.toArray(new String[0]); + } +} diff --git a/core/src/test/jdk1.4/org/bouncycastle/crypto/test/CCMTest.java b/core/src/test/jdk1.4/org/bouncycastle/crypto/test/CCMTest.java new file mode 100644 index 0000000000..8f82bcb9ec --- /dev/null +++ b/core/src/test/jdk1.4/org/bouncycastle/crypto/test/CCMTest.java @@ -0,0 +1,354 @@ +package org.bouncycastle.crypto.test; + +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.engines.AESEngine; +import org.bouncycastle.crypto.engines.DESEngine; +import org.bouncycastle.crypto.modes.CCMBlockCipher; +import org.bouncycastle.crypto.params.AEADParameters; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; + +/** + * First four test vectors from + * NIST Special Publication 800-38C. + */ +public class CCMTest + extends SimpleTest +{ + private byte[] K1 = Hex.decode("404142434445464748494a4b4c4d4e4f"); + private byte[] N1 = Hex.decode("10111213141516"); + private byte[] A1 = Hex.decode("0001020304050607"); + private byte[] P1 = Hex.decode("20212223"); + private byte[] C1 = Hex.decode("7162015b4dac255d"); + private byte[] T1 = Hex.decode("6084341b"); + + private byte[] K2 = Hex.decode("404142434445464748494a4b4c4d4e4f"); + private byte[] N2 = Hex.decode("1011121314151617"); + private byte[] A2 = Hex.decode("000102030405060708090a0b0c0d0e0f"); + private byte[] P2 = Hex.decode("202122232425262728292a2b2c2d2e2f"); + private byte[] C2 = Hex.decode("d2a1f0e051ea5f62081a7792073d593d1fc64fbfaccd"); + private byte[] T2 = Hex.decode("7f479ffca464"); + + private byte[] K3 = Hex.decode("404142434445464748494a4b4c4d4e4f"); + private byte[] N3 = Hex.decode("101112131415161718191a1b"); + private byte[] A3 = Hex.decode("000102030405060708090a0b0c0d0e0f10111213"); + private byte[] P3 = Hex.decode("202122232425262728292a2b2c2d2e2f3031323334353637"); + private byte[] C3 = Hex.decode("e3b201a9f5b71a7a9b1ceaeccd97e70b6176aad9a4428aa5484392fbc1b09951"); + private byte[] T3 = Hex.decode("67c99240c7d51048"); + + private byte[] K4 = Hex.decode("404142434445464748494a4b4c4d4e4f"); + private byte[] N4 = Hex.decode("101112131415161718191a1b1c"); + private byte[] A4 = Hex.decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"); + private byte[] P4 = Hex.decode("202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"); + private byte[] C4 = Hex.decode("69915dad1e84c6376a68c2967e4dab615ae0fd1faec44cc484828529463ccf72b4ac6bec93e8598e7f0dadbcea5b"); + private byte[] T4 = Hex.decode("f4dd5d0ee404617225ffe34fce91"); + + // + // long data vector + // + private byte[] C5 = Hex.decode("49b17d8d3ea4e6174a48e2b65e6d8b417ac0dd3f8ee46ce4a4a2a509661cef52528c1cd9805333a5cfd482fa3f095a3c2fdd1cc47771c5e55fddd60b5c8d6d3fa5c8dd79d08b16242b6642106e7c0c28bd1064b31e6d7c9800c8397dbc3fa8071e6a38278b386c18d65d39c6ad1ef9501a5c8f68d38eb6474799f3cc898b4b9b97e87f9c95ce5c51bc9d758f17119586663a5684e0a0daf6520ec572b87473eb141d10471e4799ded9e607655402eca5176bbf792ef39dd135ac8d710da8e9e854fd3b95c681023f36b5ebe2fb213d0b62dd6e9e3cfe190b792ccb20c53423b2dca128f861a61d306910e1af418839467e466f0ec361d2539eedd99d4724f1b51c07beb40e875a87491ec8b27cd1"); + private byte[] T5 = Hex.decode("5c768856796b627b13ec8641581b"); + + public void performTest() + throws Exception + { + CCMBlockCipher ccm = new CCMBlockCipher(AESEngine.newInstance()); + + checkVectors(0, ccm, K1, 32, N1, A1, P1, T1, C1); + checkVectors(1, ccm, K2, 48, N2, A2, P2, T2, C2); + checkVectors(2, ccm, K3, 64, N3, A3, P3, T3, C3); + + ivParamTest(0, ccm, K1, N1); + + // + // 4 has a reduced associated text which needs to be replicated + // + byte[] a4 = new byte[65536]; // 524288 / 8 + + for (int i = 0; i < a4.length; i += A4.length) + { + System.arraycopy(A4, 0, a4, i, A4.length); + } + + checkVectors(3, ccm, K4, 112, N4, a4, P4, T4, C4); + + // + // long data test + // + checkVectors(4, ccm, K4, 112, N4, A4, A4, T5, C5); + + // decryption with output specified, non-zero offset. + ccm.init(false, new AEADParameters(new KeyParameter(K2), 48, N2, A2)); + + byte[] inBuf = new byte[C2.length + 10]; + byte[] outBuf = new byte[ccm.getOutputSize(C2.length) + 10]; + + System.arraycopy(C2, 0, inBuf, 10, C2.length); + + int len = ccm.processPacket(inBuf, 10, C2.length, outBuf, 10); + byte[] out = ccm.processPacket(C2, 0, C2.length); + + if (len != out.length || !isEqual(out, outBuf, 10)) + { + fail("decryption output incorrect"); + } + + // encryption with output specified, non-zero offset. + ccm.init(true, new AEADParameters(new KeyParameter(K2), 48, N2, A2)); + + int inLen = len; + inBuf = outBuf; + outBuf = new byte[ccm.getOutputSize(inLen) + 10]; + + len = ccm.processPacket(inBuf, 10, inLen, outBuf, 10); + out = ccm.processPacket(inBuf, 10, inLen); + + if (len != out.length || !isEqual(out, outBuf, 10)) + { + fail("encryption output incorrect"); + } + + // + // exception tests + // + + try + { + ccm.init(false, new AEADParameters(new KeyParameter(K1), 32, N2, A2)); + + ccm.processPacket(C2, 0, C2.length); + + fail("invalid cipher text not picked up"); + } + catch (InvalidCipherTextException e) + { + // expected + } + + try + { + ccm = new CCMBlockCipher(new DESEngine()); + + fail("incorrect block size not picked up"); + } + catch (IllegalArgumentException e) + { + // expected + } + + try + { + ccm.init(false, new KeyParameter(K1)); + + fail("illegal argument not picked up"); + } + catch (IllegalArgumentException e) + { + // expected + } + + // For small number of allowed blocks, validate boundary + // conditions are properly handled. Zero and greater will + // fail as size bound is a strict inequality. + // Runs Java 4 out of memory +// int[] offsets = new int[]{-10, -2, -1, 0, 1, 10}; +// int[] ns = new int[]{13, 12}; +// for (int i = 0; i != ns.length; i++) +// { +// int n_len = ns[i]; +// for (int j = 0; j != offsets.length; j++) +// { +// int offset = offsets[j]; +// try +// { +// ccm.init(true, new AEADParameters(new KeyParameter(K1), 128, new byte[n_len])); +// +// // Encrypt up to 2^(8q) + offset. Note that message length +// // must be strictly less than 2^(8q) so offset=0 will not +// // work (per SP 800-38C Section A.1 Length Requirements). +// int q = 15 - n_len; +// int size = 1 << (8*q); +// inBuf = new byte[size + offset]; +// +// outBuf = new byte[ccm.getOutputSize(inBuf.length)]; +// len = ccm.processPacket(inBuf, 0, inBuf.length, outBuf, 0); +// +// if (offset >= 0) { +// fail("expected to fail to encrypt boundary bytes n=" + n_len + "size=" + size + " offset=" + offset); +// } else { +// // Decrypt should also succeed if encryption succeeded. +// ccm.init(false, new AEADParameters(new KeyParameter(K1), 128, new byte[n_len])); +// out = ccm.processPacket(outBuf, 0, outBuf.length); +// +// if (out.length != inBuf.length || !Arrays.areEqual(inBuf, out)) +// { +// fail("encryption output incorrect"); +// } +// } +// } +// catch (Exception e) +// { +// if (offset < 0) { +// fail("unexpected failure to encrypt boundary bytes n=" + n_len + " offset=" + offset + " msg=" + e.getMessage()); +// } +// } +// } +// } + + AEADTestUtil.testReset(this, new CCMBlockCipher(AESEngine.newInstance()), new CCMBlockCipher(AESEngine.newInstance()), new AEADParameters(new KeyParameter(K1), 32, N2)); + AEADTestUtil.testTampering(this, ccm, new AEADParameters(new KeyParameter(K1), 32, N2)); + AEADTestUtil.testOutputSizes(this, new CCMBlockCipher(AESEngine.newInstance()), new AEADParameters( + new KeyParameter(K1), 32, N2)); + AEADTestUtil.testBufferSizeChecks(this, new CCMBlockCipher(AESEngine.newInstance()), new AEADParameters( + new KeyParameter(K1), 32, N2)); + } + + private boolean isEqual(byte[] exp, byte[] other, int off) + { + for (int i = 0; i != exp.length; i++) + { + if (exp[i] != other[off + i]) + { + return false; + } + } + + return true; + } + + private void checkVectors( + int count, + CCMBlockCipher ccm, + byte[] k, + int macSize, + byte[] n, + byte[] a, + byte[] p, + byte[] t, + byte[] c) + throws InvalidCipherTextException + { + byte[] fa = new byte[a.length / 2]; + byte[] la = new byte[a.length - (a.length / 2)]; + System.arraycopy(a, 0, fa, 0, fa.length); + System.arraycopy(a, fa.length, la, 0, la.length); + + checkVectors(count, ccm, "all initial associated data", k, macSize, n, a, null, p, t, c); + checkVectors(count, ccm, "subsequent associated data", k, macSize, n, null, a, p, t, c); + checkVectors(count, ccm, "split associated data", k, macSize, n, fa, la, p, t, c); + checkVectors(count, ccm, "reuse key", null, macSize, n, fa, la, p, t, c); + } + + private void checkVectors( + int count, + CCMBlockCipher ccm, + String additionalDataType, + byte[] k, + int macSize, + byte[] n, + byte[] a, + byte[] sa, + byte[] p, + byte[] t, + byte[] c) + throws InvalidCipherTextException + { + KeyParameter keyParam = (k == null) ? null : new KeyParameter(k); + + ccm.init(true, new AEADParameters(keyParam, macSize, n, a)); + + byte[] enc = new byte[c.length]; + + if (sa != null) + { + ccm.processAADBytes(sa, 0, sa.length); + } + + int len = ccm.processBytes(p, 0, p.length, enc, 0); + + len += ccm.doFinal(enc, len); + + if (!areEqual(c, enc)) + { + fail("encrypted stream fails to match in test " + count + " with " + additionalDataType); + } + + ccm.init(false, new AEADParameters(keyParam, macSize, n, a)); + + byte[] tmp = new byte[enc.length]; + + if (sa != null) + { + ccm.processAADBytes(sa, 0, sa.length); + } + + len = ccm.processBytes(enc, 0, enc.length, tmp, 0); + + len += ccm.doFinal(tmp, len); + + byte[] dec = new byte[len]; + + System.arraycopy(tmp, 0, dec, 0, len); + + if (!areEqual(p, dec)) + { + fail("decrypted stream fails to match in test " + count + " with " + additionalDataType, + new String(Hex.encode(p)), new String(Hex.encode(dec))); + } + + if (!areEqual(t, ccm.getMac())) + { + fail("MAC fails to match in test " + count + " with " + additionalDataType); + } + } + + private void ivParamTest( + int count, + CCMBlockCipher ccm, + byte[] k, + byte[] n) + throws InvalidCipherTextException + { + byte[] p = Strings.toByteArray("hello world!!"); + + ccm.init(true, new ParametersWithIV(new KeyParameter(k), n)); + + byte[] enc = new byte[p.length + 8]; + + int len = ccm.processBytes(p, 0, p.length, enc, 0); + + len += ccm.doFinal(enc, len); + + ccm.init(false, new ParametersWithIV(new KeyParameter(k), n)); + + byte[] tmp = new byte[enc.length]; + + len = ccm.processBytes(enc, 0, enc.length, tmp, 0); + + len += ccm.doFinal(tmp, len); + + byte[] dec = new byte[len]; + + System.arraycopy(tmp, 0, dec, 0, len); + + if (!areEqual(p, dec)) + { + fail("decrypted stream fails to match in test " + count); + } + } + + public String getName() + { + return "CCM"; + } + + public static void main( + String[] args) + { + runTest(new CCMTest()); + } +} diff --git a/docs/releasenotes.html b/docs/releasenotes.html index e86414e01b..d3f60c7e14 100644 --- a/docs/releasenotes.html +++ b/docs/releasenotes.html @@ -18,10 +18,213 @@

    1.0 Introduction

    2.0 Release History

    -

    2.1.1 Version

    +

    2.1.1 Version

    +Release: 1.79
    +Date:      2024, TBD. +

    2.1.2 Defects Fixed

    +
      +
    • Leading zeroes were sometimes dropped from Ed25519 signatures leading to verification errors in the PGP API. This has been fixed.
    • +
    +

    2.1.3 Additional Features and Functionality

    +
      +
    • BCJSSE: Added support for security property "jdk.tls.server.defaultDHEParameters" (disabled in FIPS mode).
    • +
    + +

    2.2.1 Version

    +Release: 1.78.1
    +Date:      2024, 18th April. +

    2.2.2 Defects Fixed

    +
      +
    • The new dependency of the the PGP API on the bcutil jar was missing from the module jar, the OSGi manifest, and the Maven POM. This has been fixed.
    • +
    • Missing exports and duplicate imports have been added/removed from the OSGi manifests.
    • +
    • The OSGi manifests now have the same bundle IDs as 1.77 and lock down dependencies to the equivalent variations.
    • +
    • A check in the X.509 Extensions class preventing the parsing of empty extensions has been removed.
    • +
    + +

    2.3.1 Version

    +Release: 1.78
    +Date:      2024, 7th April. +

    2.3.2 Defects Fixed

    +
      +
    • Issues with a dangling weak reference causing intermittent NullPointerExceptions in the OcspCache have been fixed.
    • +
    • Issues with non-constant time RSA operations in TLS handshakes have been fixed.
    • +
    • Issue with Ed25519, Ed448 signature verification causing intermittent infinite loop have been fixed.
    • +
    • Issues with non-constant time ML-KEM implementation ("Kyber Slash") have been fixed.
    • +
    • Align ML-KEM input validation with FIPS 203 IPD requirements.
    • +
    • Make PEM parsing more forgiving of whitespace to align with RFC 7468 - Textual Encodings of PKIX, PKCS, and CMS Structures.
    • +
    • Fix CCM length checks with large nonce sizes (n=12, n=13).
    • +
    • EAC: Fixed the CertificateBody ASN.1 type to support an optional Certification Authority Reference in a Certificate Request.
    • +
    • ASN.1: ObjectIdentifier (also Relative OID) parsing has been optimized and the contents octets for both types are now limited to 4096 bytes.
    • +
    • BCJSSE: Fixed a missing null check on the result of PrivateKey.getEncoded(), which could cause issues for HSM RSA keys.
    • +
    • BCJSSE: When endpoint identification is enabled and an SSL socket is not created with an explicit hostname (as happens with HttpsURLConnection), hostname verification could be performed against a DNS-resolved IP address. This has been fixed.
    • +
    • The missing module import of java.logging to the provider module has been added.
    • +
    • GOST ASN.1 public key alg parameters are now compliant with RFC 9215.
    • +
    • An off-by-one error in the encoding for EccP256CurvePoint for ITS has been fixed.
    • +
    • PEM Parser now enforces PEM headers to start at the beginning of the line to be meaningful.
    • +
    +

    2.3.3 Additional Features and Functionality

    +
      +
    • An implementation of MLS (RFC 9420 - The Messaging Layer Security Protocol) has been added as a new module.
    • +
    • NTRU now supports NTRU-HPS4096-1229 and NTRU-HRSS-1373.
    • +
    • Improvements to PGP support, including Camellia key wrapping and Curve25519, Curve448 key types (including XDH with HKDF).
    • +
    • Added initial support for ML-KEM in TLS.
    • +
    • Added XWing hybrid KEM construction (X25519 + ML-KEM-768).
    • +
    • Introduced initial KEMSpi support (NTRU, SNTRU Prime) for JDK 21+.
    • +
    • Introduced initial composite signature support for X509 Certificates.
    • +
    • PKCS#12 now supports PKCS12-AES256-AES128, PKCS12-AES256-AES128-GCM, PKCS12-DEF-AES256-AES128, and PKCS12-DEF-AES256-AES128-GCM.
    • +
    • The default type for the KeyStore.getInstance("PKCS12", "BC") can now be set using the org.bouncycastle.pkcs12.default system/security property.
    • +
    • The PGP SExpParser will now handle Ed25519 and Ed448 keys.
    • +
    • Dilithium and Kyber key encoding updated to latest Draft RFCs (draft-ietf-lamps-dilithium-certificates and draft-ietf-lamps-kyber-certificates)
    • +
    • Support has been added for encryption key derivation using HKDF in CMS - see draft-housley-lamps-cms-cek-hkdf-sha256.
    • +
    • X500Name now recognises jurisdiction{C,ST,L} DNs.
    • +
    • CertPathValidationContext and CertificatePoliciesValidation now include implementations of Memoable.
    • +
    • The Composite post-quantum signatures implementation has been updated to the latest draft draft-ounsworth-pq-composite-sigs.
    • +
    +

    2.3.4 Notes.

    +
      +
    • Both versions of NTRUPrime have been updated to produce 256 bit secrets in line with Kyber. This should also bring them into line with other implementations such as those used in OpenSSH now.
    • +
    • BCJSSE: The boolean system property 'org.bouncycastle.jsse.fips.allowRSAKeyExchange" now defaults to false. All RSA +key exchange cipher suites will therefore be disabled when the BCJSSE provider is used in FIPS mode, unless this system +property is explicitly set to true.
    • +
    • OSGi compatibility should now be much improved.
    • +
    • SignedMailValidator now includes a more general rollback method for locating the signature's trust anchor for use when the first approach fails.
    • +
    • The PKCS12 store using GCM does not include the PKCS#12 MAC so no longer includes use of the PKCS#12 PBE scheme and only uses PBKDF2.
    • +
    • In keeping with the current set of experimental OIDs for PQC algorithms, OIDs may have changed to reflect updated versions of the algorithms.
    • +
    +

    2.3.5 Security Advisories.

    +

    +Release 1.78 deals with the following CVEs: +

    +
      +
    • CVE-2024-29857 - Importing an EC certificate with specially crafted F2m parameters can cause high CPU usage during parameter evaluation.
    • +
    • CVE-2024-30171 - Possible timing based leakage in RSA based handshakes due to exception processing eliminated.
    • +
    • CVE-2024-30172 - Crafted signature and public key can be used to trigger an infinite loop in the Ed25519 verification code.
    • +
    • CVE-2024-34447 - When endpoint identification is enabled in the BCJSSE and an SSL socket is not created with an explicit hostname (as happens with HttpsURLConnection), hostname verification could be performed against a DNS-resolved IP address. This has been fixed.
    • +
    + +

    2.4.1 Version

    +Release: 1.77
    +Date:      2023, November 13th +

    2.4.2 Defects Fixed

    +
      +
    • Using an unescaped '=' in an X.500 RDN would result in the RDN being truncated silently. The issue is now detected and an exception is thrown.
    • +
    • asn1.eac.CertificateBody was returning certificateEffectiveDate from getCertificateExpirationDate(). This has been fixed to return certificateExpirationDate.
    • +
    • DTLS: Fixed retransmission in response to re-receipt of an aggregated ChangeCipherSpec.
    • +
    • (D)TLS: Fixed compliance for supported_groups extension. Server will no longer negotiate an EC cipher suite using a default curve when the ClientHello includes +the supported_groups extension but it contains no curves in common with the server. Similarly, a DH cipher suite will not be negotiated when the ClientHello includes +supported_groups, containing at least one FFDHE group, but none in common with the server.
    • +
    • IllegalStateException was being thrown by the Ed25519/Ed448 SignatureSpi. This has been fixed.
    • +
    • TLS: class annotation issues that could occur between the BC provider and the TLS API for the GCMParameterSpec class when the jars were loaded on the boot class path have been addressed.
    • +
    • Attempt to create an ASN.1 OID from a zero length byte array is now caught at construction time.
    • +
    • Attempt to create an X.509 extension block which is empty will now be blocked cause an exception.
    • +
    • IES implementation will now accept a null ParameterSpec if no nonce is needed.
    • +
    • An internal method in Arrays was failing to construct its failure message correctly on an error. This has been fixed.
    • +
    • HSSKeyPublicParameters.generateLMSContext() would fail for a unit depth key. This has been fixed.
    • +
    +

    2.4.3 Additional Features and Functionality

    +
      +
    • BCJSSE: Added org.bouncycastle.jsse.client.omitSigAlgsCertExtension and org.bouncycastle.jsse.server.omitSigAlgsCertExtension boolean system properties +to control (for client and server resp.) whether the signature_algorithms_cert extension should be omitted if it would be identical to signature_algorithms. +Defaults to true, the historical behaviour.
    • +
    • The low-level HPKE API now allows the sender to specify an ephemeral key pair.
    • +
    • Support has been added for the delta-certificate requests in line with the current Chameleon Cert draft from the IETF.
    • +
    • Some accommodation has been added for historical systems to accommodate variations in the SHA-1 digest OID for CMS SignedData.
    • +
    • TLS: the TLS API will now try "RSAwithDigestAndMFG1" as well as the newer RSAPSS algorithm names when used with the JCA.
    • +
    • TLS: RSA key exchange cipher suites are now disabled by default.
    • +
    • Support has been added for PKCS#10 requests to allow certificates using the altSignature/altPublicKey extensions.
    • +
    +

    2.4.4 Notes.

    +
      +
    • Kyber and Dilithium have been updated according to the latest draft of the standard. Dilithium-AES and Kyber-AES have now been removed. Kyber now produces 256 bit secrets for all parameter sets (in line with the draft standard).
    • +
    • NTRU has been updated to produce 256 bit secrets in line with Kyber.
    • +
    • SPHINCS+ can now be used to generate certificates in line with those used by (Open Quantum Safe) OQS.
    • +
    • Falcon object identifiers are now in line with OQS as well.
    • +
    • PQC CMS SignedData now defaults to SHA-256 for signed attributes rather than SHAKE-256. This is also a compatibility change, but may change further again as the IETF standard for CMS is updated.
    • +
    + +

    2.5.1 Version

    +Release: 1.76
    +Date:      2023, July 29th +

    2.5.2 Defects Fixed

    +
      +
    • Service allocation in the provider could fail due to the lack of a permission block. This has been fixed.
    • +
    • JceKeyFingerPrintCalculator has been generalised for different providers by using "SHA-256" for the algorithm string.
    • +
    • BCJSSE: Fixed a regression in 1.74 (NullPointerException) that prevents a BCJSSE server from negotiating TLSv1.1 or earlier.
    • +
    • DTLS: Fixed server support for client_certificate_type extension.
    • +
    • Cipher.unwrap() for HQC could fail due to a miscalculation of the length of the KEM packet. This has been fixed.
    • +
    • There was exposure to a Java 7 method in the Java 5 to Java 8 BCTLS jar which could cause issues with some TLS 1.2 cipher suites running on older JVMs. This is now fixed.
    • +
    +

    2.5.3 Additional Features and Functionality

    +
      +
    • BCJSSE: Following OpenJDK, finalizers have been removed from SSLSocket subclasses. Applications should close sockets and not rely on garbage collection.
    • +
    • BCJSSE: Added support for boolean system property "jdk.tls.client.useCompatibilityMode" (default "true").
    • +
    • DTLS: Added server support for session resumption.
    • +
    • JcaPKCS10CertificationRequest will now work with EC on the OpenJDK provider.
    • +
    • TimeStamp generation now supports the SHA3 algorithm set.
    • +
    • The SPHINCS+ simple parameters are now fully supported in the BCPQC provider.
    • +
    • Kyber, Classic McEliece, HQC, and Bike now supported by the CRMF/CMS/CMP APIs.
    • +
    • Builder classes have been add for PGP ASCII Armored streams allowing CRCs and versions to now be optional.
    • +
    • An UnknownPacket type has been added to the PGP APIs to allow for forwards compatibility with upcoming revisions to the standard.
    • +
    + +

    2.6.1 Version

    +Release: 1.75
    +Date:      2023, June 21st +

    2.6.2 Defects Fixed

    +
      +
    • Several Java 8 method calls were accidentally introduced in the Java 5 to Java 8 build. The affected classes have been refactored to remove this.
    • +
    • (D)TLS: renegotiation after resumption now fixed to avoid breaking connection.
    • +
    +

    2.6.3 Notes.

    +
      +
    • The ASN.1 core package has had some dead and retired methods cleaned up and removed.
    • +
    + +

    2.7.1 Version

    +Release: 1.74
    +Date:      2023, June 12th +

    2.7.2 Defects Fixed

    +
      +
    • AsconEngine: Fixed a buffering bug when decrypting across multiple processBytes calls (ascon128a unaffected).
    • +
    • Context based sanity checking on PGP signatures has been added.
    • +
    • The ParallelHash clone constructor was not copying all fields. This is now fixed.
    • +
    • The maximimum number of blocks for CTR/SIC modes was 1 block less than it should have been. This is now fixed.
    • +
    +

    2.7.3 Additional Features and Functionality

    +
      +
    • The PGP API now supports wildcard key IDs for public key based data encryption.
    • +
    • LMS now supports SHA256/192, SHAKE256/192, and SHAKE256/256 (the additional SP 8000-208 parameter sets).
    • +
    • The PGP API now supports V5 and V6 AEAD encryption for encrypted data packets.
    • +
    • The PGP examples have been updated to reflect key size and algorithm changes that have occurred since they were first written (10+ years...).
    • +
    • (D)TLS: A new callback 'TlsPeer.notifyConnectionClosed' will be called when the connection is closed (including by failure).
    • +
    • BCJSSE: Improved logging of connection events and include unique IDs in connection-specific log messages.
    • +
    • BCJSSE: Server now logs the offered cipher suites when it fails to select one.
    • +
    • BCJSSE: Added support for SSLParameters namedGroups and signatureSchemes properties (can also be used via BCJSSE extension API in earlier Java versions).
    • +
    • DTLS: The initial handshake re-send time is now configurable by overriding 'TlsPeer.getHandshakeResendTimeMillis'.
    • +
    • DTLS: Added support for connection IDs per RFC 9146.
    • +
    • DTLS: Performance of DTLSVerifier has been improved so that it can reasonably be used for all incoming packets.
    • +
    • Initial support has been added for A Mechanism for Encoding Differences in Paired Certificates.
    • +
    • The PGP API now supports parsing, encoding, and fingerprinting of V6 EC/EdEC keys.
    • +
    • A thread safe verifier API has been added to the PGP API to support multi-threaded verification of certifications on keys and user IDs.
    • +
    • The number of keys/sub-keys in a PGPKeyRing can now be found by calling PGPKeyRing.size().
    • +
    • The PQC algorithms LMS/HSS, SPHINCS+, Dilithium, Falcon, and NTRU are now supported directly by the BC provider.
    • +
    +

    2.7.4 Notes.

    +
      +
    • The now defunct PQC SIKE algorithm has been removed, this has also meant the removal of its resource files so the provider is now quite a bit smaller.
    • +
    • As a precaution, HC128 now enforces a 128 bit IV, previous behaviour for shorter IVs can be supported where required by padding the IV to the 128 bits with zero.
    • +
    • PGP encrypted data generation now uses integrity protection by default. Previous behaviour for encrypted data can be supported where required by calling PGPDataEncryptorBuilder.setWithIntegrityPacket(false) when data encryption is set up.
    • +
    • There are now additional sanity checks in place to prevent accidental mis-use of PGPSignature objects. If this change causes any issues, you might want to check what your code is up to as there is probably a bug.
    • +
    +

    2.7.5 Security Advisories.

    +
      +
    • CVE-2023-33201 - this release fixes an issue with the X509LDAPCertStoreSpi where a specially crafted certificate subject could be used to try and extract extra information out of an LDAP server with wild-card matching enabled.
    • +
    + +

    2.8.1 Version

    Release: 1.73
    Date:      2023, April 8th -

    2.1.2 Defects Fixed

    +

    2.8.2 Defects Fixed

    • BCJSSE: Instantiating a JSSE provider in some contexts could cause an AccessControl exception. This has been fixed.
    • The EC key pair generator can generate out of range private keys when used with SM2. A specific SM2KeyPairGenerator has been added to the low-level API and is used by KeyPairGenerator.getInstance("SM2", "BC"). The SM2 signer has been updated to check for out of range keys as well..
    • @@ -42,7 +245,7 @@

      2.1.2 Defects Fixed

    • IPAddress has been written to provide stricter checking and avoid the use of Integer.parseInt().
    • A Java 7 class snuck into the Java 5 to Java 8 build. This has been addressed.
    -

    2.1.3 Additional Features and Functionality

    +

    2.8.3 Additional Features and Functionality

    • The Rainbow NIST Post Quantum Round-3 Candidate has been added to the low-level API and the BCPQC provider (level 3 and level 5 parameter sets only).
    • The GeMSS NIST Post Quantum Round-3 Candidate has been added to the low-level API.
    • @@ -69,37 +272,38 @@

      2.1.3 Additional Features and Functionality

    • A general purpose PQCOtherInfoGenerator has been added which supports all Kyber and NTRU.
    • An implementation of HPKE (RFC 9180 - Hybrid Public Key Encryption) has been added to the light-weight cryptography API.
    -

    2.1.4 Security Advisory.

    +

    2.8.4 Security Advisories.

    • The PQC implementations have now been subject to formal review for secret leakage and side channels, there were issues in BIKE, Falcon, Frodo, HQC which have now been fixed. Some weak positives also showed up in Rainbow, Picnic, SIKE, and GeMSS - for now this last set has been ignored as the algorithms will either be updated if they reappear in the Signature Round, or deleted, as is already the case for SIKE (it is now in the legacy package). Details on the group responsible for the testing can be found in the CONTRIBUTORS file.
    • +
    • For at least some ECIES variants (e.g. when using CBC) there is an issue with potential malleability of a nonce (implying silent malleability of the plaintext) that must be sent alongside the ciphertext but is outside the IES integrity check. For this reason the automatic generation of nonces with IED is now disabled and they have to be passed in using an IESParameterSpec. The current advice is to agree on a nonce between parties and then rely on the use of the ephemeral key component to allow the nonce (rather the so called nonce) usage to be extended.
    -

    2.1.5 Notes.

    +

    2.8.5 Notes.

    • Most test data files have now been migrated to a separate project bc-test-data which is also available on github. If you clone bc-test-data at the same level as the bc-java project the tests will find the test data they require.
    • There has been further work to make entropy collection more friendly in container environments. See DRBG.java for details. We would welcome any further feedback on this as we clearly cannot try all situations first hand.
    -

    2.2.1 Version

    +

    2.9.1 Version

    Release: 1.72.2, 1.72.3
    Date:      2022, November 20th -

    2.2.2 Defects Fixed

    +

    2.9.2 Defects Fixed

    • PGP patch release - fix for OSGI and version header in 1.72.1 jar file.
    -

    2.3.1 Version

    +

    2.10.1 Version

    Release: 1.72.1
    Date:      2022, October 25th -

    2.3.2 Defects Fixed

    +

    2.10.2 Defects Fixed

    • PGP patch release - fix for regression in OpenPGP PGPEncryptedData.java which could result in checksum failures on correct files.
    -

    2.4.1 Version

    +

    2.11.1 Version

    Release: 1.72
    Date:      2022, September 25th -

    2.4.2 Defects Fixed

    +

    2.11.2 Defects Fixed

    • There were parameter errors in XMSS^MT OIDs for XMSSMT_SHA2_40/4_256 and XMSSMT_SHA2_60/3_256. These have been fixed.
    • There was an error in Merkle tree construction for the Evidence Records (ERS) implementation which could result in invalid roots been timestamped. ERS now produces an ArchiveTimeStamp for each data object/group with an associated reduced hash tree. The reduced hash tree is now calculated as a simple path to the root of the tree for each record.
    • @@ -107,7 +311,7 @@

      2.4.2 Defects Fixed

    • A tagging calculation error in GCMSIV which could result in incorrect tags has been fixed.
    • Issues around Java 17 which could result in failing tests have been addressed.
    -

    2.4.3 Additional Features and Functionality

    +

    2.11.3 Additional Features and Functionality

    • BCJSSE: TLS 1.3 is now enabled by default where no explicit protocols are supplied (e.g. "TLS" or "Default" SSLContext algorithms, or SSLContext.getDefault() method).
    • BCJSSE: Rewrite SSLEngine implementation to improve compatibility with SunJSSE.
    • @@ -137,22 +341,22 @@

      2.4.3 Additional Features and Functionality

    • Support has been added to the PKCS#12 implementation for the Oracle trusted certificate attribute.
    • Performance of our BZIP2 classes has been improved.
    -

    2.4.4 Notes

    +

    2.11.4 Notes

    Keep in mind the PQC algorithms are still under development and we are still at least a year and a half away from published standards. This means the algorithms may still change so by all means experiment, but do not use the PQC algoritms for anything long term.

    The legacy "Rainbow" and "McEliece" implementations have been removed from the BCPQC provider. The underlying classes are still present if required. Other legacy algorithm implementations can be found under the org.bouncycastle.pqc.legacy package.

    -

    2.4.5 Security Notes

    +

    2.11.5 Security Notes

    The PQC SIKE algorithm is provided for research purposes only. It should now be regarded as broken. The SIKE implementation will be withdrawn in BC 1.73.

    -

    2.5.1 Version

    +

    2.12.1 Version

    Release: 1.71
    Date:      2022, March 31st. -

    2.5.2 Defects Fixed

    +

    2.12.2 Defects Fixed

    • In line with GPG the PGP API now attempts to preserve comments containing non-ascii UTF-8 characters.
    • An accidental partial dependency on Java 1.7 has been removed from the TLS API.
    • @@ -166,7 +370,7 @@

      2.5.2 Defects Fixed

    • An accidental regression introduced by a fix for another issue in PKIXCertPathReviewer around use of the AuthorityKeyIdentifier extension and it failing to match a certificate uniquely when the serial number field is missing has been fixed.
    • An error was found in the creation of TLS 1.3 Export Keying Material which could cause compatibility issues. This has been fixed.
    -

    2.5.3 Additional Features and Functionality

    +

    2.12.3 Additional Features and Functionality

    • Support has been added for OpenPGP regular expression signature packets.
    • Support has been added for OpenPGP PolicyURI signature packets.
    • @@ -196,16 +400,16 @@

      2.5.3 Additional Features and Functionality

    • ASN.1 object support has been added for the Lightweight Certificate Management Protocol (CMP), currently in draft.
    • A HybridValueParamterSpec class has been added for use with KeyAgreement to support SP 800-56C hybrid (so classical/post-quantum) key agreement.
    -

    2.5.4 Notes

    +

    2.12.4 Notes

    • The deprecated QTESLA implementation has been removed from the BCPQC provider.
    • The submission update to SPHINCS+ has been added. This changes the generation of signatures - particularly deterministic ones.
    -

    2.6.1 Version

    +

    2.13.1 Version

    Release: 1.70
    Date:      2021, November 29th. -

    2.6.2 Defects Fixed

    +

    2.13.2 Defects Fixed

    • Blake 3 output limit is enforced.
    • The PKCS12 KeyStore was relying on default precedence for its key Cipher implementation so was sometimes failing if used from the keytool. The KeyStore class now makes sure it uses the correct Cipher implementation.
    • @@ -219,7 +423,7 @@

      2.6.2 Defects Fixed

    • The lack of close() in the ASN.1 Dump command line utility was triggering false positives in some code analysis tools. A close() call has been added.
    • PGPPublicKey.getBitStrength() now properly recognises EdDSA keys.
    -

    2.6.3 Additional Features and Functionality

    +

    2.13.3 Additional Features and Functionality

    • Missing PGP CRC checksums can now be optionally ignored using setDetectMissingCRC() (default false) on ArmoredInputStream.
    • PGPSecretKey.copyWithNewPassword() now has a variant which uses USAGE_SHA1 for key protection if a PGPDigestCalculator is passed in.
    • @@ -258,15 +462,15 @@

      2.6.3 Additional Features and Functionality

    • The JcePKCSPBEOutputEncryptorBuilder now supports SCRYPT with ciphers that do not have algorithm parameters (e.g. AESKWP).
    • Support is now added for certificates using ETSI TS 103 097, "Intelligent Transport Systems (ITS)" in the bcpkix package.
    -

    2.6.4 Notes.

    +

    2.13.4 Notes.

    • While this release should maintain source code compatibility, developers making use of some parts of the ASN.1 library will find that some classes need recompiling. Apologies for the inconvenience.
    -

    2.7.1 Version

    +

    2.14.1 Version

    Release: 1.69
    Date:      2021, June 7th. -

    2.7.2 Defects Fixed

    +

    2.14.2 Defects Fixed

    • Lightweight and JCA conversion of Ed25519 keys in the PGP API could drop the leading byte as it was zero. This has been fixed.
    • Marker packets appearing at the start of PGP public key rings could cause parsing failure. This has been fixed.
    • @@ -286,7 +490,7 @@

      2.7.2 Defects Fixed

    • Fix various conversions and interoperability for XDH and EdDSA between BC and SunEC providers.
    • TLS: Prevent attempts to use KeyUpdate mechanism in versions before TLS 1.3.
    -

    2.7.3 Additional Features and Functionality

    +

    2.14.3 Additional Features and Functionality

    • GCM-SIV has been added to the lightweight API and the provider.
    • Blake3 has been added to the lightweight API.
    • @@ -327,24 +531,24 @@

      2.7.3 Additional Features and Functionality

    • BCJSSE: Key managers now support EC credentials for use with TLS 1.3 ECDSA signature schemes (including brainpool).
    • TLS: Add TLS 1.3 support for brainpool curves per RFC 8734.
    -

    2.7.4 Notes

    +

    2.14.4 Notes

    • There is a small API change in the PKIX package to the DigestAlgorithmIdentifierFinder interface as a find() method that takes an ASN1ObjectIdentifier has been added to it. For people wishing to extend their own implementations, see DefaultDigestAlgorithmIdentifierFinder for a sample implementation.
    • A version of the bcmail API supporting Jakarta Mail has now been added (see bcjmail jar).
    • Some work has been done on moving out code that does not need to be in the provider jar. This has reduced the size of the provider jar and should also make it easier for developers to patch the classes involved as they no longer need to be signed. bcpkix and bctls are both dependent on the new bcutil jar.
    -

    2.8.1 Version

    +

    2.15.1 Version

    Release: 1.68
    Date:      2020, December 21st. -

    2.8.2 Defects Fixed

    +

    2.15.2 Defects Fixed

    • Some BigIntegers utility methods would fail for BigInteger.ZERO. This has been fixed.
    • PGPUtil.isKeyRing() was not detecting secret sub-keys in its input. This has been fixed.
    • The ASN.1 class, ArchiveTimeStamp was insisting on a value for the optional reducedHashTree field. This has been fixed.
    • BCJSSE: Lock against multiple writers - a possible synchronization issue has been removed.
    -

    2.8.3 Additional Features and Functionality

    +

    2.15.3 Additional Features and Functionality

    • BCJSSE: Added support for system property com.sun.net.ssl.requireCloseNotify. Note that we are using a default value of 'true'.
    • BCJSSE: 'TLSv1.3' is now a supported protocol for both client and server. For this release it is only enabled by default for the 'TLSv1.3' SSLContext, but can be explicitly enabled using 'setEnabledProtocols' on an SSLSocket or SSLEngine, or via SSLParameters.
    • @@ -355,10 +559,10 @@

      2.8.3 Additional Features and Functionality

    -

    2.9.1 Version

    +

    2.16.1 Version

    Release: 1.67
    Date:      2020, November 1st. -

    2.9.2 Defects Fixed

    +

    2.16.2 Defects Fixed

    • BCJSSE: SunJSSE compatibility fix - override of getChannel() removed and 'urgent data' behaviour should now conform to what the SunJSSE expects.
    • Nested BER data could sometimes cause issues in octet strings. This has been fixed.
    • @@ -370,7 +574,7 @@

      2.9.2 Defects Fixed

    • Zero length data would cause an unexpected exception from RFC5649WrapEngine. This has been fixed.
    • OpenBSDBcrypt was failing to handle some valid prefixes. This has been fixed.
    -

    2.9.3 Additional Features and Functionality

    +

    2.16.3 Additional Features and Functionality

    • Performance of Argon2 has been improved.
    • Performance of Noekeon has been improved.
    • @@ -388,15 +592,15 @@

      2.9.3 Additional Features and Functionality

    • Mode name checks in Cipher strings should now make sure an improper mode name always results in a NoSuchAlgorithmException.
    • In line with changes in OpenSSL, the OpenSSLPBKDF now uses UTF-8 encoding.
    -

    2.9.4 Security Advisory

    +

    2.16.4 Security Advisory

    • As described in CVE-2020-28052, the OpenBSDBCrypt.checkPassword() method had a flaw in it due to a change for BC 1.65. BC 1.66 is also affected. The issue is fixed in BC 1.67. If you are using OpenBSDBCrypt.checkPassword() and you are using BC 1.65 or BC 1.66 we strongly advise moving to BC 1.67 or later.
    -

    2.10.1 Version

    +

    2.17.1 Version

    Release: 1.66
    Date:      2020, July 4th. -

    2.10.2 Defects Fixed

    +

    2.17.2 Defects Fixed

    • EdDSA verifiers now reset correctly after rejecting overly long signatures.
    • BCJSSE: SSLSession.getPeerCertificateChain could throw NullPointerException. This has been fixed.
    • @@ -413,7 +617,7 @@

      2.10.2 Defects Fixed

    • For a few values the cSHAKE implementation would add unnecessary pad bytes where the N and S strings produced encoded data that was block aligned. This has been fixed.
    • There were a few circumstances where Argon2BytesGenerator might hit an unexpected null. These have been removed.
    -

    2.10.3 Additional Features and Functionality

    +

    2.17.3 Additional Features and Functionality

    • The qTESLA signature algorithm has been updated to v2.8 (20191108).
    • BCJSSE: Client-side OCSP stapling now supports status_request_v2 extension.
    • @@ -432,15 +636,15 @@

      2.10.3 Additional Features and Functionality

    • Performance of the Base64 encoder has been improved.
    • The PGPPublicKey class will now include direct key sigantures when checking for key expiry times.
    -

    2.10.4 Notes

    +

    2.17.4 Notes

    The qTESLA update breaks compatibility with previous versions. Private keys now include a hash of the public key at the end, and signatures are no longer interoperable with previous versions.

    -

    2.11.1 Version

    +

    2.18.1 Version

    Release: 1.65
    Date:      2020, March 31st. -

    2.11.2 Defects Fixed

    +

    2.18.2 Defects Fixed

    • DLExternal would encode using DER encoding for tagged SETs. This has been fixed.
    • ChaCha20Poly1305 could fail for large (>~2GB) files. This has been fixed.
    • @@ -452,7 +656,7 @@

      2.11.2 Defects Fixed

    • BCJSSE: Choice of credentials and signing algorithm now respect the peer's signature_algorithms extension properly.
    • BCJSSE: KeyManager for KeyStoreBuilderParameters no longer leaks memory.
    -

    2.11.3 Additional Features and Functionality

    +

    2.18.3 Additional Features and Functionality

    • LMS and HSS (RFC 8554) support has been added to the low level library and the PQC provider.
    • SipHash128 support has been added to the low level library and the JCE provider.
    • @@ -466,10 +670,10 @@

      2.11.3 Additional Features and Functionality

    • TLS: DSA in JcaTlsCrypto now falls back to stream signing to work around NoneWithDSA limitations in default provider.
    -

    2.12.1 Version

    +

    2.19.1 Version

    Release: 1.64
    Date:      2019, October 7th. -

    2.12.2 Defects Fixed

    +

    2.19.2 Defects Fixed

    • OpenSSH: Fixed padding in generated Ed25519 private keys.
    • Validation of headers in PemReader now looks for tailing dashes in header.
    • @@ -477,7 +681,7 @@

      2.12.2 Defects Fixed

    • Some compatibility issues around the signature encryption algorithm field in CMS SignedData and the GOST algorithms have been addressed.
    • GOST3410-2012-512 now uses the GOST3411-2012-256 as its KDF digest.
    -

    2.12.3 Additional Features and Functionality

    +

    2.19.3 Additional Features and Functionality

    • PKCS12: key stores containing only certificates can now be created without the need to provide passwords.
    • BCJSSE: Initial support for AlgorithmConstraints; protocol versions and cipher suites.
    • @@ -490,20 +694,20 @@

      2.12.3 Additional Features and Functionality

    • Support for Java 11's NamedParameterSpec class has been added (using reflection) to the EC and EdEC KeyPairGenerator implementations.
    -

    2.12.4 Removed Features and Functionality

    +

    2.19.4 Removed Features and Functionality

    • Deprecated ECPoint 'withCompression' tracking has been removed.
    -

    2.12.5 Security Advisory

    +

    2.19.5 Security Advisory

    • A change to the ASN.1 parser in 1.63 introduced a regression that can cause an OutOfMemoryError to occur on parsing ASN.1 data. We recommend upgrading to 1.64, particularly where an application might be parsing untrusted ASN.1 data from third parties.
    -

    2.13.1 Version

    +

    2.20.1 Version

    Release: 1.63
    Date:      2019, September 10th. -

    2.13.2 Defects Fixed

    +

    2.20.2 Defects Fixed

    • The ASN.1 parser would throw a large object exception for some objects which could be safely parsed. This has been fixed.
    • GOST3412-2015 CTR mode was unusable at the JCE level. This has been fixed.
    • @@ -522,7 +726,7 @@

      2.13.2 Defects Fixed

    • It is now possible to specify different S-Box parameters for the GOST 28147-89 MAC.
    -

    2.13.3 Additional Features and Functionality

    +

    2.20.3 Additional Features and Functionality

    • QTESLA is now updated with the round 2 changes. Note: the security catergories, and in some cases key generation and signatures, have changed. For people interested in comparison, the round 1 version is now moved to org.bouncycastle.pqc.crypto.qteslarnd1 - this package will be deleted in 1.64. Please keep in mind that QTESLA may continue to evolve.
    • Support has been added for generating Ed25519/Ed448 signed certificates.
    • @@ -535,10 +739,10 @@

      2.13.3 Additional Features and Functionality

    • The valid path for EST services has been updated to cope with the characters used in the Aruba clearpass EST implementation.
    -

    2.14.1 Version

    +

    2.21.1 Version

    Release: 1.62
    Date:      2019, June 3rd. -

    2.14.2 Defects Fixed

    +

    2.21.2 Defects Fixed

    • DTLS: Fixed infinite loop on IO exceptions.
    • DTLS: Retransmission timers now properly apply to flights monolithically.
    • @@ -555,7 +759,7 @@

      2.14.2 Defects Fixed

    • CertificateFactory now enforces presence of PEM headers when required.
    • A performance issue with RSA key pair generation that was introduced in 1.61 has been mostly eliminated.
    -

    2.14.3 Additional Features and Functionality

    +

    2.21.3 Additional Features and Functionality

    • Builders for X509 certificates and CRLs now support replace and remove extension methods.
    • DTLS: Added server-side support for HelloVerifyRequest.
    • @@ -576,10 +780,10 @@

      2.14.3 Additional Features and Functionality

    • Support for the Ethereum flavor of IES has been added to the lightweight API.
    -

    2.15.1 Version

    +

    2.22.1 Version

    Release: 1.61
    Date:      2019, February 4th. -

    2.15.2 Defects Fixed

    +

    2.22.2 Defects Fixed

    • Use of EC named curves could be lost if keys were constructed via a key factory and algorithm parameters. This has been fixed.
    • RFC3211WrapEngine would not properly handle messages longer than 127 bytes. This has been fixed.
    • @@ -600,7 +804,7 @@

      2.15.2 Defects Fixed

    • Several parsing issues related to the processing of CMP PKIPublicationInfo have been fixed.
    • The ECGOST curves for id-tc26-gost-3410-12-256-paramSetA and id-tc26-gost-3410-12-512-paramSetC had incorrect co-factors. These have been fixed.
    -

    2.15.3 Additional Features and Functionality

    +

    2.22.3 Additional Features and Functionality

    • The qTESLA signature algorithm has been added to PQC light-weight API and the PQC provider.
    • The password hashing function, Argon2 has been added to the lightweight API.
    • @@ -624,15 +828,15 @@

      2.15.3 Additional Features and Functionality

    • SM2 in public key cipher mode has been added to the provider API.
    • The BCFKSLoadStoreParameter has been extended to allow the use of certificates and digital signatures for verifying the integrity of BCFKS key stores.
    -

    2.15.4 Removed Features and Functionality

    +

    2.22.4 Removed Features and Functionality

    • Deprecated methods for EC point construction independent of curves have been removed.
    -

    2.16.1 Version

    +

    2.23.1 Version

    Release: 1.60
    Date:      2018, June 30 -

    2.16.2 Defects Fixed

    +

    2.23.2 Defects Fixed

    • Base64/UrlBase64 would throw an exception on a zero length string. This has been fixed.
    • Base64/UrlBase64 would throw an exception if there was whitespace in the last 4 characters. This has been fixed.
    • @@ -653,7 +857,7 @@

      2.16.2 Defects Fixed

    • In some situations the use of sm2p256v1 would result in "unknown curve name". This has been fixed.
    • CMP PollReqContent now supports multiple certificate request IDs.
    -

    2.16.3 Additional Features and Functionality

    +

    2.23.3 Additional Features and Functionality

    • TLS: Extended CBC padding is now optional (and disabled by default).
    • TLS: Now supports channel binding 'tls-server-end-point'.
    • @@ -681,16 +885,16 @@

      2.16.3 Additional Features and Functionality

    • Support has been added for the German BSI KAEG Elliptic Curve key agreement algorithm with X9.63 as the KDF to the JCE.
    • Support has been added for the German BSI KAEG Elliptic Curve session key KDF to the lightweight API.
    -

    2.16.4 Security Related Changes and CVE's Addressed by this Release

    +

    2.23.4 Security Related Changes and CVE's Addressed by this Release

    • CVE-2018-1000180: issue around primality tests for RSA key pair generation if done using only the low-level API.
    • CVE-2018-1000613: lack of class checking in deserialization of XMSS/XMSS^MT private keys with BDS state information.
    -

    2.17.1 Version

    +

    2.24.1 Version

    Release: 1.59
    Date:      2017, December 28 -

    2.17.2 Defects Fixed

    +

    2.24.2 Defects Fixed

    • Issues with using PQC based keys with the provided BC KeyStores have now been fixed.
    • ECGOST-2012 public keys were being encoded with the wrong OID for the digest parameter in the algorithm parameter set. This has been fixed.
    • @@ -704,7 +908,7 @@

      2.17.2 Defects Fixed

    • An off-by-one error for the max N check for SCRYPT has been fixed. SCRYPT should now be compliant with RFC 7914.
    • ASN1GeneralizedTime will now accept a broader range of input strings.
    -

    2.17.3 Additional Features and Functionality

    +

    2.24.3 Additional Features and Functionality

    • GOST3410-94 private keys encoded using ASN.1 INTEGER are now accepted in private key info objects.
    • SCRYPT is now supported as a SecretKeyFactory in the provider and in the PKCS8 APIs
    • @@ -723,15 +927,15 @@

      2.17.3 Additional Features and Functionality

    • A DEROtherInfo generator for key agreement using NewHope as the source of the shared private info has been added that can be used in conjunction with regular key agreement algorithms.
    • RFC 7748: Added low-level implementations of X25519 and X448.
    -

    2.17.4 Security Related Changes and CVE's Addressed by this Release

    +

    2.24.4 Security Related Changes and CVE's Addressed by this Release

    • CVE-2017-13098 ("ROBOT"), a Bleichenbacher oracle in TLS when RSA key exchange is negotiated. This potentially affected BCJSSE servers and any other TLS servers configured to use JCE for the underlying crypto - note the two TLS implementations using the BC lightweight APIs are not affected by this.
    -

    2.18.1 Version

    +

    2.25.1 Version

    Release: 1.58
    Date:      2017, August 18 -

    2.18.2 Defects Fixed

    +

    2.25.2 Defects Fixed

    • NewHope and SPHINCS keys are now correctly created off certificates by the BC provider.
    • Use of the seeded constructor with SecureRandom() and the BC provider in first position could cause a stack overflow error. This has been fixed.
    • @@ -745,7 +949,7 @@

      2.18.2 Defects Fixed

    • A race condition that could occur inside the HybridSecureRandom on reseed and result in an exception has been fixed.
    • DTLS now supports records containing multiple handshake messages.
    -

    2.18.3 Additional Features and Functionality

    +

    2.25.3 Additional Features and Functionality

    • An implementation of GOST3410-2012 has been added to light weight API and the JCA provider.
    • Support for ECDH GOST3410-2012 and GOST3410-2001 have been added. The CMS API can also handle reading ECDH GOST3410 key transport messages.
    • @@ -765,16 +969,16 @@

      2.18.3 Additional Features and Functionality

    • The new TLS API now supports RFC 7633 - X.509v3 TLS Feature Extension (e.g. "must staple"), enabled in default clients.
    • TLS exceptions have been made more directly informative.
    -

    2.18.4 Removed Features and Functionality

    +

    2.25.4 Removed Features and Functionality

    • Per RFC 7465, removed support for RC4 in the new TLS API.
    • Per RFC 7568, removed support for SSLv3 in the new TLS API.
    -

    2.19.1 Version

    +

    2.26.1 Version

    Release: 1.57
    Date:      2017, May 11 -

    2.19.2 Defects Fixed

    +

    2.26.2 Defects Fixed

    • A class cast exception for master certification removal in PGPPublicKey.removeCertification() by certification has been fixed.
    • GOST GOFB 28147-89 mode had an edge condition concerning the incorrect calculation of N4 (see section 6.1 of RFC 5830) affecting about 1% of IVs. This has been fixed.
    • @@ -791,7 +995,7 @@

      2.19.2 Defects Fixed

    • EC FixedPointCombMultiplier avoids 'infinity' point in lookup tables, reducing timing side-channels.
    • Reuse of a Blake2b digest with a call to reset() rather than doFinal() could result in incorrect padding being introduced and the wrong digest result produced. This has been fixed.
    -

    2.19.3 Additional Features and Functionality

    +

    2.26.3 Additional Features and Functionality

    • ARIA (RFC 5794) is now supported by the provider and the lightweight API.
    • ARIA Key Wrapping (RFC 5649 style) is now supported by the provider and the lightweight API.
    • @@ -801,23 +1005,23 @@

      2.19.3 Additional Features and Functionality

    • A test client for EST which will interop with the 7030 test server at http://testrfc7030.com/ has been added to the general test module in the current source tree.
    • The BCJSSE provider now supports SSLContext.getDefault(), with very similar behaviour to the SunJSSE provider, including checks of the relevant javax.net.ssl.* system properties and auto-loading of jssecacerts or cacerts as the default trust store.
    -

    2.19.4 Security Related Changes

    +

    2.26.4 Security Related Changes

    • The default parameter sizes for DH and DSA are now 2048. If you have been relying on key pair generation without passing in parameters generated keys will now be larger.
    • Further work has been done on preventing accidental re-use of a GCM cipher without first changing its key or iv.
    -

    2.20.1 Version

    +

    2.27.1 Version

    Release: 1.56
    Date:      2016, December 23 -

    2.20.2 Defects Fixed

    +

    2.27.2 Defects Fixed

    • See section 2.15.4 for Security Defects.
    • Using unknown status with the ASN.1 CertStatus primitive could result in an IllegalArgumentException on construction. This has been fixed.
    • A potentional NullPointerException in a precomputation in WNafUtil has been removed.
    • PGPUtil.getDecoderStream() would throw something other than an IOException for empty and very small data. This has been fixed.
    -

    2.20.3 Additional Features and Functionality

    +

    2.27.3 Additional Features and Functionality

    • Support for the explicit setting of AlgorithmParameters has been added to the JceCMSContentEncryptorBuilder and the JceCMSMacCaculatorBuilder classes to allow configuration of the session cipher/MAC used.
    • EC, ECGOST3410, and DSTU4145 Public keys are now validated on construction in the JCA/JCE and the light weight API.
    • @@ -833,7 +1037,7 @@

      2.20.3 Additional Features and Functionality

    • SHA-3 support has been added to BcDefaultDigestProvider.
    • A higher level TLS API and JSSE provider have been added to the project.
    -

    2.20.4 Security Related Changes and CVE's Addressed by this Release

    +

    2.27.4 Security Related Changes and CVE's Addressed by this Release

    • It is now possible to configure the provider to only import keys for specific named curves.
    • Work has been done to improve the "constant time" behaviour of the RSA padding mechanisms.
    • @@ -852,15 +1056,15 @@

      2.20.3 Additional Features and Functionality

    • CVE-2016-1000346: Other party DH public key not fully validated. This can cause issues as invalid keys can be used to reveal details about the other party's private key where static Diffie-Hellman is in use. As of this release the key parameters are checked on agreement calculation.
    • CVE-2016-1000352: ECIES allows the use of unsafe ECB mode. This algorithm is now removed from the provider.
    -

    2.20.5 Security Advisory

    +

    2.27.5 Security Advisory

    • We consider the carry propagation bugs fixed in this release to have been exploitable in previous releases (1.51-1.55), for static ECDH, to reveal the long-term key, per "Practical realisation and elimination of an ECC-related software bug attack", Brumley et.al.. The most common case of this would be the non-ephemeral ECDH ciphersuites in TLS. These are not enabled by default in our TLS implementations, but they can be enabled explicitly by users. We recommend that users DO NOT enable static ECDH ciphersuites for TLS.
    -

    2.21.1 Version

    +

    2.28.1 Version

    Release: 1.55
    Date:      2016, August 18 -

    2.21.2 Defects Fixed

    +

    2.28.2 Defects Fixed

    • Issues with cloning of blake digests with salts and personalisation strings have been fixed.
    • The JceAsymmetricValueDecryptor in the CRMF package now attempts to recognise a wider range of parameters for the key wrapping algorithm, rather than relying on a default.
    • @@ -881,7 +1085,7 @@

      2.21.2 Defects Fixed

    • Trying to use of non-default parameters for OAEP in CRMF would resort to the default parameter set. This has been fixed.
    • If the BC provider was not registered, creating a CertificateFactory would cause a new provider object to be created. This has been fixed.
    -

    2.21.3 Additional Features and Functionality

    +

    2.28.3 Additional Features and Functionality

    • The DANE API has been updated to reflect the latest standard changes.
    • The signature algorithm SPHINCS-256 has been added to the post-quantum provider (BCPQC). Support is in place for SHA-512 and SHA3-512 (using trees based around SHA512_256 and SHA3_256 respectively).
    • @@ -899,10 +1103,10 @@

      2.21.3 Additional Features and Functionality

    • Additional search methods have been added to PGP public and secret key rings.
    -

    2.22.1 Version

    +

    2.29.1 Version

    Release: 1.54
    Date:      2015, December 29 -

    2.22.2 Defects Fixed

    +

    2.29.2 Defects Fixed

    • Blake2b-160, Blake2b-256, Blake2b-384, and Blake2b-512 are now actually in the provider and an issue with cloning Blake2b digests has been fixed.
    • PKCS#5 Scheme 2 using DESede CBC is now supported by the PKCS#12 implementation.
    • @@ -911,7 +1115,7 @@

      2.22.2 Defects Fixed

    • It turns out, after advice one way and another that the NESSIE test vectors for Serpent are now what should be followed and that the vectors in the AES submission are regarded as an algorithm called Tnepres. The Serpent version now follows the NESSIE vectors, and the Tnepres cipher has been added to the provider and the lightweight API for compatibility.
    • Problems with DTLS record-layer version handling were resolved, making version negotiation work properly.
    -

    2.22.3 Additional Features and Functionality

    +

    2.29.3 Additional Features and Functionality

    • Camellia and SEED key wrapping are now supported for CMS key agreement
    • The BC TLS/DTLS code now includes a non-blocking API.
    • @@ -921,19 +1125,19 @@

      2.22.3 Additional Features and Functionality

    • Support has been added to the CMS API for PKCS#7 ANY type encapsulated content where the encapsulated content is not an OCTET STRING.
    • PSSSigner in the lightweight API now supports fixed salts.
    -

    2.22.4 Security Advisory

    +

    2.29.4 Security Advisory

    • (D)TLS 1.2: Motivated by CVE-2015-7575, we have added validation that the signature algorithm received in DigitallySigned structures is actually one of those offered (in signature_algorithms extension or CertificateRequest). With our default TLS configuration, we do not believe there is an exploitable vulnerability in any earlier releases. Users that are customizing the signature_algorithms extension, or running a server supporting client authentication, are advised to double-check that they are not offering any signature algorithms involving MD5.
    -

    2.22.5 Notes

    +

    2.29.5 Notes

    If you have been using Serpent, you will need to either change to Tnepres, or take into account the fact that Serpent is now byte-swapped compared to what it was before.

    -

    2.23.1 Version

    +

    2.30.1 Version

    Release: 1.53
    Date:      2015, October 10 -

    2.23.2 Defects Fixed

    +

    2.30.2 Defects Fixed

    • The BC JCE cipher implementations could sometimes fail when used in conjunction with the JSSE and NIO. This has been fixed.
    • PGPPublicKey.getBitStrength() always returned 0 for EC keys. This has been fixed.
    • @@ -958,7 +1162,7 @@

      2.23.2 Defects Fixed

    • Some decidedly odd argument casting in the PKIXCertPathValidator has been fixed to throw an InvalidAlgorithmParameterException.
    • Presenting an empty array of certificates to the PKIXCertPathValidator would cause an IndexOutOfRangeException instead of a CertPathValidatorException. This has been fixed.
    -

    2.23.3 Additional Features and Functionality

    +

    2.30.3 Additional Features and Functionality

    • It is now possible to specify that an unwrapped key must be usable by a software provider in the asymmetric unwrappers for CMS.
    • A Blake2b implementation has been added to the provider and lightweight API.
    • @@ -974,15 +1178,15 @@

      2.23.3 Additional Features and Functionality

    • The PKCS#12 key store will now garbage collect orphaned certificates on saving.
    • Caching for ASN.1 ObjectIdentifiers has been rewritten to make use of an intern method. The "usual suspects" are now interned automatically, and the cache is used by the parser. Other OIDs can be added to the cache by calling ASN1ObjectIdentifier.intern().
    -

    2.23.4 Notes

    +

    2.30.4 Notes

    It turns out there was a similar, but different, issue in Crypto++ to the BC issue with ECIES. Crypto++ 6.0 now offers a corrected version of ECIES which is compatible with that which is now in BC.

    -

    2.24.1 Version

    +

    2.31.1 Version

    Release: 1.52
    Date:      2015, March 2 -

    2.24.2 Defects Fixed

    +

    2.31.2 Defects Fixed

    • GenericSigner in the lightweight API would fail if the digest started with a zero byte, occasionally causing a TLS negotiation to fail. This has been fixed.
    • Some BC internal classes expected the BC provider to be accessible within the provider. This has been fixed.
    • @@ -999,7 +1203,7 @@

      2.24.2 Defects Fixed

    • A badly formed issuer in a X.509 certificate could cause a null pointer exception in X509CertificateHolder.toString(). This has been fixed.
    • CMSSignedData.verifySignatures() could fail on a correct counter signature due to a mismatch of the SID. This has been fixed.
    -

    2.24.3 Additional Features and Functionality

    +

    2.31.3 Additional Features and Functionality

    • The CMP support class CMPCertificate restricted the types of certificates that could be added. A more flexible method has been introduced to allow for other certificate types.
    • Support classes have be added for DNS-based Authentication of Named Entities (DANE) to the PKIX distribution.
    • @@ -1027,15 +1231,15 @@

      2.24.3 Additional Features and Functionality

    • Support for some JDK1.5+ language features has finally made its way into the repository.
    • A load store parameter, PKCS12StoreParameter, has been added to support DER only encoding of PKCS12 key stores.
    -

    2.24.4 Security Advisory

    +

    2.31.4 Security Advisory

    • The CTR DRBGs would not populate some bytes in the requested block of random bytes if the size of the block requested was not an exact multiple of the block size of the underlying cipher being used in the DRBG. If you are using the CTR DRBGs with "odd" keysizes, we strongly advise upgrading to this release, or contacting us for a work around.
    -

    2.25.1 Version

    +

    2.32.1 Version

    Release: 1.51
    Date:      2014, July 28 -

    2.25.2 Defects Fixed

    +

    2.32.2 Defects Fixed

    • The AEAD GCM AlgorithmParameters object was unable to return a GCMParameterSpec object. This has been fixed.
    • Cipher.getIV() was returning null for AEAD mode ciphers. This has been fixed.
    • @@ -1050,7 +1254,7 @@

      2.25.2 Defects Fixed

    • PKCS#12 files containing keys/certificates with empty attribute sets attached to them no longer cause an ArrayIndexOutOfBoundsException to be thrown.
    • Issues with certificate verification and server side DTLS/TLS 1.2 have now been fixed.
    -

    2.25.3 Additional Features and Functionality

    +

    2.32.3 Additional Features and Functionality

    • The range of key algorithm names that will be interpreted by KeyAgreement.generateSecret() has been expanded for ECDH derived algorithms in the provider. A KeyAgreement of ECDHwithSHA1KDF can now be explicitly created.
    • ECIES now supports the use of IVs with the underlying block cipher and CBC mode in both the lightweight and the JCE APIs.
    • @@ -1077,17 +1281,17 @@

      2.25.3 Additional Features and Functionality

    • Full support is now provided for client-side auth in the D/TLS server code.
    • Compatibility issues with some OSGI containers have been addressed.
    -

    2.25.4 Notes

    +

    2.32.4 Notes

    • Support for NTRUSigner has been deprecated as the algorithm has been withdrawn.
    • Some changes have affected the return values of some methods. If you are migrating from an earlier release, it is recommended to recompile before using this release.
    • There has been further clean out of deprecated methods in this release. If your code has previously been flagged as using a deprecated method you may need to change it. The OpenPGP API is the most heavily affected.
    -

    2.26.1 Version

    +

    2.33.1 Version

    Release: 1.50
    Date:      2013, December 3 -

    2.26.2 Defects Fixed

    +

    2.33.2 Defects Fixed

    • The DualECSP800DRBG sometimes truncated the last block in the generated stream incorrectly. This has been fixed.
    • Keys produced from RSA certificates with specialised parameters would lose the parameter settings. This has been fixed.
    • @@ -1101,7 +1305,7 @@

      2.26.2 Defects Fixed

    • Default RC2 parameters for 40 bit RC2 keys in CMSEnvelopedData were encoding incorrectly. This has been fixed.
    • In case of a long hash the DSTU4145 implementation would sometimes remove one bit too much during truncation. This has been fixed.
    -

    2.26.3 Additional Features and Functionality

    +

    2.33.3 Additional Features and Functionality

    • Additional work has been done on CMS recipient generation to simplify the generation of OAEP encrypted messages and allow for non-default parameters.
    • OCB implementation updated to account for changes in draft-irtf-cfrg-ocb-03.
    • @@ -1121,7 +1325,7 @@

      2.26.3 Additional Features and Functionality

    • The JDK 1.5+ provider will now recognise and use GCMParameterSpec if it is run in a 1.7 JVM.
    • Client side support and some server side support has been added for TLS/DTLS 1.2.
    -

    2.26.4 Notes

    +

    2.33.4 Notes

    • org.bouncycastle.crypto.DerivationFunction is now a base interface, the getDigest() method appears on DigestDerivationFunction.
    • Recent developments at NIST indicate the SHA-3 may be changed before final standardisation. Please bare this in mind if you are using it.
    • @@ -1131,10 +1335,10 @@

      2.26.4 Notes

    • ECDH support for OpenPGP should still be regarded as experimental. It is still possible there will be compliance issues with other implementations.
    -

    2.27.1 Version

    +

    2.34.1 Version

    Release: 1.49
    Date:      2013, May 31 -

    2.27.2 Defects Fixed

    +

    2.34.2 Defects Fixed

    • Occasional ArrayOutOfBounds exception in DSTU-4145 signature generation has been fixed.
    • The handling of escaped characters in X500 names is much improved.
    • @@ -1145,7 +1349,7 @@

      2.27.2 Defects Fixed

    • PEMParser would throw a NullPointerException if it ran into explicit EC curve parameters, it would also throw an Exception if the named curve was not already defined. The parser now returns X9ECParmameters for explicit parameters and returns an ASN1ObjectIdentifier for a named curve.
    • The V2TBSCertListGenerator was adding the wrong date type for CRL invalidity date extensions. This has been fixed.
    -

    2.27.3 Additional Features and Functionality

    +

    2.34.3 Additional Features and Functionality

    • A SecretKeyFactory has been added that enables use of PBKDF2WithHmacSHA.
    • Support has been added to PKCS12 KeyStores and PfxPdu to handle PKCS#5 encrypted private keys.
    • @@ -1174,16 +1378,16 @@

      2.27.3 Additional Features and Functionality

    • A basic commitment package has been introduced into the lightweight API containing a digest based commitment scheme.
    • It is now possible to set the NotAfter and NotBefore date in the CRMF CertificateRequestMessageBuilder class.
    -

    2.27.4 Notes

    +

    2.34.4 Notes

    • The NTRU implementation has been moved into the org.bouncycastle.pqc package hierarchy.
    • The change to PEMParser to support explicit EC curves is not backward compatible. If you run into a named curve you need to use org.bouncycastle.asn1.x9.ECNamedCurveTable.getByOID() to look the curve up if required.
    -

    2.28.1 Version

    +

    2.35.1 Version

    Release: 1.48
    Date:      2013, February 10 -

    2.28.2 Defects Fixed

    +

    2.35.2 Defects Fixed

    • Occasional key compatibility issues in IES due to variable length keys have been fixed.
    • PEMWriter now recognises the new PKCS10CertificationRequest object.
    • @@ -1194,7 +1398,7 @@

      2.28.2 Defects Fixed

    • The BC SSL implementation has been modified to deal with the "Lucky Thirteen" attack.
    • A regression in 1.47 which prevented key wrapping with regular symmetric PBE algorihtms has been fixed.
    -

    2.28.3 Additional Features and Functionality

    +

    2.35.3 Additional Features and Functionality

    • IES now supports auto generation of ephemeral keys in both the JCE and the lightweight APIs.
    • A new class PEMParser has been added to return the new CertificateHolder and Request objects introduced recently.
    • @@ -1209,10 +1413,10 @@

      2.28.3 Additional Features and Functionality

    • T61String now uses UTF-8 encoding by default rather than a simple 8 bit transform.
    -

    2.29.1 Version

    +

    2.36.1 Version

    Release: 1.47
    Date:      2012, March 30 -

    2.29.2 Defects Fixed

    +

    2.36.2 Defects Fixed

    • OpenPGP ID based certifications now support UTF-8. Note: this may mean that some old certifications no longer validate - if this happens a retry can be added using by converting the ID using Strings.fromByteArray(Strings.toByteArray(id)) - this will strip out the top byte in each character.
    • IPv4/IPv6 parsing in CIDR no longer assumes octet boundaries on a mask.
    • @@ -1229,7 +1433,7 @@

      2.29.2 Defects Fixed

    • Check of DH parameter L could reject some valid keys. This is now fixed.
    -

    2.29.3 Additional Features and Functionality

    +

    2.36.3 Additional Features and Functionality

    • Support is now provided via the RepeatedKey class to enable IV only re-initialisation in the JCE layer. The same effect can be acheived in the light weight API by using null as the key parameter when creating a ParametersWithIV object.
    • CRMF now supports empty poposkInput.
    • @@ -1249,15 +1453,15 @@

      2.29.3 Additional Features and Functionality

    • The J2ME lcrypto release now includes higher level classes for handling PKCS, CMS, CRMF, CMP, EAC, OpenPGP, and certificate generation.
    -

    2.29.4 Other notes

    +

    2.36.4 Other notes

    Okay, so we have had to do another release. The issue we have run into is that we probably didn't go far enough in 1.46, but we are now confident that moving from this release to 2.0 should be largely just getting rid of deprecated methods. While this release does change a lot it is relatively straight forward to do a port and we have a porting guide which explains the important ones. The area there has been the most change in is the ASN.1 library which was in bad need of a rewrite after 10 years of patching. On the bright side the rewrite did allow us to eliminate a few problems and bugs in the ASN.1 library, so we have some hope anyone porting to it will also have similar benefits. As with 1.46 the other point of emphasis has been making sure interface support is available for operations across the major APIs, so the lightweight API or some local role your own methods can be used instead for doing encryption and signing.

    -

    2.30.1 Version

    +

    2.37.1 Version

    Release: 1.46
    Date:      2011, February 23 -

    2.30.2 Defects Fixed

    +

    2.37.2 Defects Fixed

    • An edge condition in ECDSA which could result in an invalid signature has been fixed.
    • Exhaustive testing has been performed on the ASN.1 parser, eliminating another potential OutOfMemoryException and several escaping run time exceptions.
    • @@ -1266,7 +1470,7 @@

      2.30.2 Defects Fixed

    • DERGeneralizedTime.getDate() would produce incorrect results for fractional seconds. This has been fixed.
    • PSSSigner would produce incorrect results if the MGF digest and content digest were not the same. This has been fixed.
    -

    2.30.3 Additional Features and Functionality

    +

    2.37.3 Additional Features and Functionality

    • A null genTime can be passed to TimeStampResponseGenerator.generate() to generate timeNotAvailable error responses.
    • Support has been added for reading and writing of openssl PKCS#8 encrypted keys.
    • @@ -1283,7 +1487,7 @@

      2.30.3 Additional Features and Functionality

    • PGP public subkeys can now be separately decoded and encoded.
    • An IV can now be passed to an ISO9797Alg3Mac.
    -

    2.30.4 Other notes

    +

    2.37.4 Other notes

    Baring security patches we expect 1.46 will be the last of the 1.* releases. The next release of BC will be version 2.0. For this reason a lot of things in 1.46 that relate to CMS have been deprecated and @@ -1300,29 +1504,29 @@

    2.30.4 Other notes

  • The X509Name class will utlimately be replacde with the X500Name class, the getInstance() methods on both these classes allow conversion from one type to another.
  • The org.bouncycastle.cms.RecipientId class now has a collection of subclasses to allow for more specific recipient matching. If you are creating your own recipient ids you should use the constructors for the subclasses rather than relying on the set methods inherited from X509CertSelector. The dependencies on X509CertSelector and CertStore will be removed from the version 2 CMS API.
  • -

    2.31.1 Version

    +

    2.38.1 Version

    Release: 1.45
    Date:      2010, January 12 -

    2.31.2 Defects Fixed

    +

    2.38.2 Defects Fixed

    • OpenPGP now supports UTF-8 in file names for literal data.
    • The ASN.1 library was losing track of the stream limit in a couple of places, leading to the potential of an OutOfMemoryError on a badly corrupted stream. This has been fixed.
    • The provider now uses a privileged block for initialisation.
    • JCE/JCA EC keys are now serialisable.
    -

    2.31.3 Additional Features and Functionality

    +

    2.38.3 Additional Features and Functionality

    • Support for EC MQV has been added to the light weight API, provider, and the CMS/SMIME library.
    -

    2.31.4 Security Advisory

    +

    2.38.4 Security Advisory

    • This version of the provider has been specifically reviewed to eliminate possible timing attacks on algorithms such as GCM and CCM mode.
    -

    2.32.1 Version

    +

    2.39.1 Version

    Release: 1.44
    Date:      2009, October 9 -

    2.32.2 Defects Fixed

    +

    2.39.2 Defects Fixed

    • The reset() method in BufferedAsymmetricBlockCipher is now fully clearing the buffer.
    • Use of ImplicitlyCA with KeyFactory and Sun keyspec no longer causes NullPointerException.
    • @@ -1338,7 +1542,7 @@

      2.32.2 Defects Fixed

    • PKIXCertPathReviewer.getTrustAnchor() could occasionally cause a null pointer exception or an exception due to conflicting trust anchors. This has been fixed.
    • Handling of explicit CommandMap objects with the generation of S/MIME messages has been improved.
    -

    2.32.3 Additional Features and Functionality

    +

    2.39.3 Additional Features and Functionality

    • PEMReader/PEMWriter now support encrypted EC keys.
    • BC generated EC private keys now include optional fields required by OpenSSL.
    • @@ -1354,24 +1558,24 @@

      2.32.3 Additional Features and Functionality

    • Support for raw signatures has been extended to RSA and RSA-PSS in the provider. RSA support can be used in CMSSignedDataStreamGenerator to support signatures without signed attributes.
    -

    2.33.1 Version

    +

    2.40.1 Version

    Release: 1.43
    Date:      2009, April 13 -

    2.33.2 Defects Fixed

    +

    2.40.2 Defects Fixed

    • Multiple countersignature attributes are now correctly collected.
    • Two bugs in HC-128 and HC-256 related to sign extension and byte swapping have been fixed. The implementations now pass the latest ecrypt vector tests.
    • X509Name.hashCode() is now consistent with equals.
    -

    2.33.3 Security Advisory

    +

    2.40.3 Security Advisory

    • The effect of the sign extension bug was to decrease the key space the HC-128 and HC-256 ciphers were operating in and the byte swapping inverted every 32 bits of the generated stream. If you are using either HC-128 or HC-256 you must upgrade to this release.
    -

    2.34.1 Version

    +

    2.41.1 Version

    Release: 1.42
    Date:      2009, March 16 -

    2.34.2 Defects Fixed

    +

    2.41.2 Defects Fixed

    • A NullPointer exception which could be result from generating a diffie-hellman key has been fixed.
    • CertPath validation could occasionally mistakenly identify a delta CRL. This has been fixed.
    • @@ -1384,7 +1588,7 @@

      2.34.2 Defects Fixed

    • Multiplication by negative powers of two is fixed in BigInteger.
    • OptionalValidity now encodes correctly.
    -

    2.34.3 Additional Features and Functionality

    +

    2.41.3 Additional Features and Functionality

    • Support for NONEwithECDSA has been added.
    • Support for Grainv1 and Grain128 has been added.
    • @@ -1395,10 +1599,10 @@

      2.34.3 Additional Features and Functionality

    • Support for the SRP-6a protocol has been added to the lightweight API.
    -

    2.35.1 Version

    +

    2.42.1 Version

    Release: 1.41
    Date:      2008, October 1 -

    2.35.2 Defects Fixed

    +

    2.42.2 Defects Fixed

    • The GeneralName String constructor now supports IPv4 and IPv6 address parsing.
    • An issue with nested-multiparts with postamble for S/MIME that was causing signatures to fail verification has been fixed.
    • @@ -1409,7 +1613,7 @@

      2.35.2 Defects Fixed

    • Standard name "DiffieHellman" is now supported in the provider.
    • Better support for equality tests for '#' encoded entries has been added to X509Name.
    -

    2.35.3 Additional Features and Functionality

    +

    2.42.3 Additional Features and Functionality

    • Camellia is now 12.5% faster than previously.
    • A smaller version (around 8k compiled) of Camellia, CamelliaLightEngine has also been added.
    • @@ -1420,10 +1624,10 @@

      2.35.3 Additional Features and Functionality

    • Support for reading and extracting personalised certificates in PGP Secret Key rings has been added.
    -

    2.36.1 Version

    +

    2.43.1 Version

    Release: 1.40
    Date:      2008, July 12 -

    2.36.2 Defects Fixed

    +

    2.43.2 Defects Fixed

    • EAX mode ciphers were not resetting correctly after a doFinal/reset. This has been fixed.
    • The SMIME API was failing to verify doubly nested multipart objects in signatures correctly. This has been fixed.
    • @@ -1439,7 +1643,7 @@

      2.36.2 Defects Fixed

    • The '+' character can now be escaped or quoted in the constructor for X509Name, X509Prinicipal.
    • Fix to regression from 1.38: PKIXCertPathValidatorResult.getPublicKey was returning the wrong public key when the BC certificate path validator was used.
    -

    2.36.3 Additional Features and Functionality

    +

    2.43.3 Additional Features and Functionality

    • Galois/Counter Mode (GCM) has been added to the lightweight API and the JCE provider.
    • SignedPublicKeyAndChallenge and PKCS10CertificationRequest can now take null providers if you need to fall back to the default provider mechanism.
    • @@ -1447,15 +1651,15 @@

      2.36.3 Additional Features and Functionality

    • Unnecessary local ID attributes on certificates in PKCS12 files are now automatically removed.
    • The PKCS12 store types PKCS12-3DES-3DES and PKCS12-DEF-3DES-3DES have been added to support generation of PKCS12 files with both certificates and keys protected by 3DES.
    -

    2.36.4 Additional Notes

    +

    2.43.4 Additional Notes

    • Due to problems for some users caused by the presence of the IDEA algorithm, an implementation is no longer included in the default signed jars. Only the providers of the form bcprov-ext-*-*.jar now include IDEA.
    -

    2.37.1 Version

    +

    2.44.1 Version

    Release: 1.39
    Date:      2008, March 29 -

    2.37.2 Defects Fixed

    +

    2.44.2 Defects Fixed

    • A bug causing the odd NullPointerException has been removed from the LocalizedMessage class.
    • IV handling in CMS for the SEED and Camellia was incorrect. This has been fixed.
    • @@ -1469,7 +1673,7 @@

      2.37.2 Defects Fixed

    • A decoding issue with a mis-identified tagged object in CertRepMessage has been fixed.
    • \# is now properly recognised in the X509Name class.
    -

    2.37.3 Additional Features and Functionality

    +

    2.44.3 Additional Features and Functionality

    • Certifications associated with user attributes can now be created, verified and removed in OpenPGP.
    • API support now exists for CMS countersignature reading and production.
    • @@ -1484,10 +1688,10 @@

      2.37.3 Additional Features and Functionality

    • Support has been added to the provider for the VMPC MAC.
    -

    2.38.1 Version

    +

    2.45.1 Version

    Release: 1.38
    Date:      2007, November 7 -

    2.38.2 Defects Fixed

    +

    2.45.2 Defects Fixed

    • SMIME signatures containing non-standard quote-printable data could be altered by SMIME encryption. This has been fixed.
    • CMS signatures that do not use signed attributes were vulnerable to one of Bleichenbacher's RSA signature forgery attacks. This has been fixed.
    • @@ -1501,7 +1705,7 @@

      2.38.2 Defects Fixed

    • Overwriting entities in a PKCS#12 file was not fully compliant with the JavaDoc for KeyStore. This has been fixed.
    • TlsInputStream.read() could appear to return end of file when end of file had not been reached. This has been fixed.
    -

    2.38.3 Additional Features and Functionality

    +

    2.45.3 Additional Features and Functionality

    • Buffering in the streaming CMS has been reworked. Throughput is now usually higher and the behaviour is more predictable.
    • It's now possible to pass a table of hashes to a CMS detached signature rather than having to always pass the data.
    • @@ -1512,10 +1716,10 @@

      2.38.3 Additional Features and Functionality

    • CertPathReviewer has better handling for problem trust anchors.
    • Base64 encoder now does initial size calculations to try to improve resource usage.
    -

    2.39.1 Version

    +

    2.46.1 Version

    Release: 1.37
    Date:      2007, June 15 -

    2.39.2 Defects Fixed

    +

    2.46.2 Defects Fixed

    • The ClearSignedFileProcessor example for OpenPGP did not take into account trailing white space in the file to be signed. This has been fixed.
    • @@ -1529,7 +1733,7 @@

      2.39.2 Defects Fixed

    • The default private key length in the lightweght API for generated DiffieHellman parameters was absurdly small, this has been fixed.
    • Cipher.getParameters() for PBEwithSHAAndTwofish-CBC was returning null after intialisation. This has been fixed.
    -

    2.39.3 Additional Features and Functionality

    +

    2.46.3 Additional Features and Functionality

    • The block cipher mode CCM has been added to the provider and light weight API.
    • The block cipher mode EAX has been added to the provider and light weight API.
    • @@ -1548,10 +1752,10 @@

      2.39.3 Additional Features and Functionality

    • The JCE provider now supports RIPEMD160withECDSA.
    -

    2.40.1 Version

    +

    2.47.1 Version

    Release: 1.36
    Date:      2007, March 16 -

    2.40.2 Defects Fixed

    +

    2.47.2 Defects Fixed

    • DSA key generator now checks range and keysize.
    • Class loader issues with i18n classes should now be fixed.
    • @@ -1565,7 +1769,7 @@

      2.40.2 Defects Fixed

    • Some surrogate pairs were not assembled correctly by the UTF-8 decoder. This has been fixed.
    • Alias resolution in PKCS#12 is now case insensitive.
    -

    2.40.3 Additional Features and Functionality

    +

    2.47.3 Additional Features and Functionality

    • CMS/SMIME now supports basic EC KeyAgreement with X9.63.
    • CMS/SMIME now supports RFC 3211 password based encryption.
    • @@ -1581,10 +1785,10 @@

      2.40.3 Additional Features and Functionality

    • DSASigner now handles long messages. SHA2 family digest support for DSA has been added to the provider.
    -

    2.41.1 Version

    +

    2.48.1 Version

    Release: 1.35
    Date:      2006, December 16 -

    2.41.2 Defects Fixed

    +

    2.48.2 Defects Fixed

    • Test data files are no longer in the provider jars.
    • SMIMESignedParser now handles indefinite length data in SignerInfos.
    • @@ -1599,7 +1803,7 @@

      2.41.2 Defects Fixed

    • The IESEngine could incorrectly encrypt data when used in block cipher mode. This has been fixed.
    • An error in the encoding of the KEKRecipientInfo has been fixed. Compatability warning: this may mean that versions of BC mail prior to 1.35 will have trouble processing KEK messages produced by 1.35 or later.
    -

    2.41.3 Additional Features and Functionality

    +

    2.48.3 Additional Features and Functionality

    • Further optimisations to elliptic curve math libraries.
    • API now incorporates a CertStore which should be suitable for use with LDAP.
    • @@ -1621,10 +1825,10 @@

      2.41.3 Additional Features and Functionality

    • PGP packet streams can now be closed off using close() on the returned stream as well as closing the generator.
    -

    2.42.1 Version

    +

    2.49.1 Version

    Release: 1.34
    Date:      2006, October 2 -

    2.42.2 Defects Fixed

    +

    2.49.2 Defects Fixed

    • Endianess of integer conversion in KDF2BytesGenerator was incorrect. This has been fixed.
    • Generating critical signature subpackets in OpenPGP would result in a zero packet tag. This has been fixed. @@ -1636,7 +1840,7 @@

      2.42.2 Defects Fixed

    • PGP Identity strings were only being interpreted as ASCII rather than UTF-8. This has been fixed.
    • CertificateFactory.generateCRLs now returns a Collection rather than null.
    -

    2.42.3 Additional Features and Functionality

    +

    2.49.3 Additional Features and Functionality

    • An ISO18033KDFParameters class had been added to support ISO18033 KDF generators.
    • An implemention of the KDF1 bytes generator algorithm has been added. @@ -1656,16 +1860,16 @@

      2.42.3 Additional Features and Functionality

    • Performance of the prime number generation in the BigInteger library has been further improved.
    • In line with RFC 3280 section 4.1.2.4 DN's are now encoded using UTF8String by default rather than PrintableString.
    -

    2.42.4 Security Advisory

    +

    2.49.4 Security Advisory

    • If you are using public exponents with the value three you *must* upgrade to this release, otherwise it will be possible for attackers to exploit some of Bleichenbacher's RSA signature forgery attacks on your applications.
    -

    2.43.1 Version

    +

    2.50.1 Version

    Release: 1.33
    Date:      2006, May 3 -

    2.43.2 Defects Fixed

    +

    2.50.2 Defects Fixed

    • OCSPResponseData was including the default version in its encoding. This has been fixed.
    • BasicOCSPResp.getVersion() would throw a NullPointer exception if called on a default version response. This has been fixed. @@ -1674,7 +1878,7 @@

      2.43.2 Defects Fixed

    • ArmoredInputStream was not closing the underlying stream on close. This has been fixed.
    • Small base64 encoded strings with embedded white space could decode incorrectly using the Base64 class. This has been fixed.
    -

    2.43.3 Additional Features and Functionality

    +

    2.50.3 Additional Features and Functionality

    • The X509V2CRLGenerator now supports adding general extensions to CRL entries.
    • A RoleSyntax implementation has been added to the x509 ASN.1 package, and the AttributeCertificateHolder class now support the IssuerSerial option. @@ -1682,10 +1886,10 @@

      2.43.3 Additional Features and Functionality

    • DERUTF8String now supports surrogate pairs.
    -

    2.44.1 Version

    +

    2.51.1 Version

    Release: 1.32
    Date:      2006, March 27 -

    2.44.2 Defects Fixed

    +

    2.51.2 Defects Fixed

    • Further work has been done on RFC 3280 compliance.
    • The ASN1Sequence constructor for SemanticsInformation would sometimes throw a ClassCastException on reconstruction an object from a byte stream. This has been fixed. @@ -1702,7 +1906,7 @@

      2.44.2 Defects Fixed

    • OpenPGP clear text signatures containing '\r' as line separators were not being correctly canonicalized. This has been fixed.
    -

    2.44.3 Additional Features and Functionality

    +

    2.51.3 Additional Features and Functionality

    • The ASN.1 library now includes classes for the ICAO Electronic Passport.
    • Support has been added to CMS and S/MIME for ECDSA. @@ -1711,16 +1915,16 @@

      2.44.3 Additional Features and Functionality

    • Support has been added for repeated attributes in CMS and S/MIME messages.
    • A wider range of RSA-PSS signature types is now supported for CRL and Certificate verification.
    -

    2.44.4 Possible compatibility issue

    +

    2.51.4 Possible compatibility issue

    • Previously elliptic curve keys and points were generated with point compression enabled by default. Owing to patent issues in some jurisdictions, they are now generated with point compression disabled by default.
    -

    2.45.1 Version

    +

    2.52.1 Version

    Release: 1.31
    Date:      2005, December 29 -

    2.45.2 Defects Fixed

    +

    2.52.2 Defects Fixed

    • getCriticalExtensionOIDs on an X.509 attribute certificate was returning the non-critical set. This has been fixed.
    • Encoding uncompressed ECDSA keys could occasionally introduce an extra leading zero byte. This has been fixed. @@ -1733,7 +1937,7 @@

      2.45.2 Defects Fixed

      This has been fixed.
    • OIDs with extremely large components would sometimes reencode with unnecessary bytes in their encoding. The optimal DER encoding will now be produced instead.
    -

    2.45.3 Additional Features and Functionality

    +

    2.52.3 Additional Features and Functionality

    • The SMIME package now supports the large file streaming model as well.
    • Additional ASN.1 message support has been added for RFC 3739 in the org.bouncycastle.x509.qualified package. @@ -1742,10 +1946,10 @@

      2.45.3 Additional Features and Functionality

    • CertPathValidator has been updated to better support path validation as defined in RFC 3280.
    -

    2.46.1 Version

    +

    2.53.1 Version

    Release: 1.30
    Date:      2005, September 18 -

    2.46.2 Defects Fixed

    +

    2.53.2 Defects Fixed

    • Whirlpool was calculating the wrong digest for 31 byte data and could throw an exception for some other data lengths. This has been fixed.
    • AlgorithmParameters for IVs were returning a default of RAW encoding of the parameters when they should have been returning an @@ -1757,7 +1961,7 @@

      2.46.2 Defects Fixed

    • KEKIdentifier would not handle OtherKeyAttribute objects correctly. This has been fixed.
    • GetCertificateChain on a PKCS12 keystore would return a single certificate chain rather than null if the alias passed in represented a certificate not a key. This has been fixed.
    -

    2.46.3 Additional Features and Functionality

    +

    2.53.3 Additional Features and Functionality

    • RSAEngine no longer assumes keys are byte aligned when checking for out of range input.
    • PGPSecretKeyRing.removeSecretKey and PGPSecretKeyRing.insertSecretKey have been added. @@ -1768,10 +1972,10 @@

      2.46.3 Additional Features and Functionality

    • Both the lightweight API and the provider now support the Camellia encryption algorithm.
    -

    2.47.1 Version

    +

    2.54.1 Version

    Release: 1.29
    Date:      2005, June 27 -

    2.47.2 Defects Fixed

    +

    2.54.2 Defects Fixed

    • HMac-SHA384 and HMac-SHA512 were not IETF compliant. This has been fixed.
    • The equals() method on ElGamalKeyParameters and DHKeyParameters in the lightweight API would sometimes @@ -1782,7 +1986,7 @@

      2.47.2 Defects Fixed

    • ISO9796 signatures for full recovered messsages could incorrectly verify for similar messages in some circumstances. This has been fixed.
    • The occasional problem with decrypting PGP messages containing compressed streams now appears to be fixed.
    -

    2.47.3 Additional Features and Functionality

    +

    2.54.3 Additional Features and Functionality

    • Support has been added for the OIDs and key generation required for HMac-SHA224, HMac-SHA256, HMac-SHA384, and HMac-SHA512. @@ -1790,16 +1994,16 @@

      2.47.3 Additional Features and Functionality

    • The provider and the lightweight API now support the GOST-28147-94 MAC algorithm.
    • Headers are now settable for PGP armored output streams.
    -

    2.47.4 Notes

    +

    2.54.4 Notes

    • The old versions of HMac-SHA384 and HMac-SHA512 can be invoked as OldHMacSHA384 and OldHMacSHA512, or by using the OldHMac class in the lightweight API.
    -

    2.48.1 Version

    +

    2.55.1 Version

    Release: 1.28
    Date:      2005, April 20 -

    2.48.2 Defects Fixed

    +

    2.55.2 Defects Fixed

    • Signatures on binary encoded S/MIME messages could fail to validate when correct. This has been fixed.
    • getExtensionValue() on CRL Entries were returning the encoding of the inner object, rather than the octet string. This has been fixed. @@ -1813,7 +2017,7 @@

      2.48.2 Defects Fixed

    • Filetype for S/MIME compressed messages was incorrect. This has been fixed.
    • BigInteger class can now create negative numbers from byte arrays.
    -

    2.48.3 Additional Features and Functionality

    +

    2.55.3 Additional Features and Functionality

    • S/MIME now does canonicalization on non-binary input for signatures.
    • Micalgs for the new SHA schemes are now supported. @@ -1824,7 +2028,7 @@

      2.48.3 Additional Features and Functionality

    • Support has been added for the creation of ECDSA certificate requests.
    • The provider and the light weight API now support the WHIRLPOOL message digest.
    -

    2.48.4 Notes

    +

    2.55.4 Notes

    • Patches for S/MIME binary signatures and canonicalization were actually applied in 1.27, but a couple of days after the release - if the class CMSProcessableBodyPartOutbound is present in the package org.bouncycastle.mail.smime you have the patched 1.27. We would recommend upgrading to 1.28 in any case @@ -1832,10 +2036,10 @@

      2.48.4 Notes

    • GOST private keys are probably not encoding correctly and can be expected to change.
    -

    2.49.1 Version

    +

    2.56.1 Version

    Release: 1.27
    Date:      2005, February 20 -

    2.49.2 Defects Fixed

    +

    2.56.2 Defects Fixed

    • Typos in the provider which pointed Signature algorithms SHA256WithRSA, SHA256WithRSAEncryption, SHA384WithRSA, SHA384WithRSAEncryption, SHA512WithRSA, and SHA512WithRSAEncryption at the PSS versions of the algorithms have been fixed. The correct names for the PSS algorithms are SHA256withRSAandMGF1, SHA384withRSAandMGF1, and SHA512withRSAandMGF1.
    • X509CertificateFactory failed under some circumstances to reset properly if the input stream being passed @@ -1849,7 +2053,7 @@

      2.49.2 Defects Fixed

    • TSP TimeStampToken was failing to validate time stamp tokens with the issuerSerial field set in the ESSCertID structure. This has been fixed.
    • Path validation in environments with frequently updated CRLs could occasionally reject a valid path. This has been fixed.
    -

    2.49.3 Additional Features and Functionality

    +

    2.56.3 Additional Features and Functionality

    • Full support has been added for the OAEPParameterSpec class to the JDK 1.5 povider.
    • Full support has been added for the PSSParameterSpec class to the JDK 1.4 and JDK 1.5 providers. @@ -1860,7 +2064,7 @@

      2.49.3 Additional Features and Functionality

    • The CertPath support classes now support PKCS #7 encoding.
    • Point compression can now be turned off when encoding elliptic curve keys.
    -

    2.49.4 Changes that may affect compatibility

    +

    2.56.4 Changes that may affect compatibility

    • org.bouncycastle.jce.interfaces.ElGamalKey.getParams() has been changed to getParameters() to avoid clashes with a JCE interface with the same method signature. @@ -1870,10 +2074,10 @@

      2.49.4 Changes that may affect compatibility

      were using these previously you should use SHA256WithRSAAndMGF1, SHA384WithRSAAndMGF1, or SHA512WithRSAAndMGF1.
    -

    2.50.1 Version

    +

    2.57.1 Version

    Release: 1.26
    Date:      2005, January 15 -

    2.50.2 Defects Fixed

    +

    2.57.2 Defects Fixed

    • The X.509 class UserNotice assumed some of the optional fields were not optional. This has been fixed.
    • BCPGInputStream would break on input packets of 8274 bytes in length. This has been fixed. @@ -1882,7 +2086,7 @@

      2.50.2 Defects Fixed

    • ASN1Sets now properly sort their contents when created from scratch.
    • A bug introduced in the CertPath validation in the last release which meant some certificate paths would validate if they were invalid has been fixed.
    -

    2.50.3 Additional Features and Functionality

    +

    2.57.3 Additional Features and Functionality

    • Support for JDK 1.5 naming conventions for OAEP encryption and PSS signing has been added.
    • Support for Time Stamp Protocol (RFC 3161) has been added. @@ -1892,15 +2096,15 @@

      2.50.3 Additional Features and Functionality

    • PBEWithMD5AndRC2, PBEWithSHA1AndRC2 now generate keys rather than exceptions.
    • The BigInteger implementation has been further optimised to take more advantage of the Montgomery number capabilities.
    -

    2.50.4 JDK 1.5 Changes

    +

    2.57.4 JDK 1.5 Changes

    • The JDK 1.5 version of the provider now supports the new Elliptic Curve classes found in the java.security packages. Note: while we have tried to preserve some backwards compatibility people using Elliptic curve are likely to find some minor code changes are required when moving code from JDK 1.4 to JDK 1.5 as the java.security APIs have changed.
    -

    2.51.1 Version

    +

    2.58.1 Version

    Release: 1.25
    Date:      2004, October 1 -

    2.51.2 Defects Fixed

    +

    2.58.2 Defects Fixed

    • In some situations OpenPGP would overread when a stream had been broken up into partial blocks. This has been fixed. @@ -1922,7 +2126,7 @@

      2.51.2 Defects Fixed

    • Parsing a message with a zero length body with SMIMESigned would cause an exception. This has been fixed.
    • Some versions of PGP use zeros in the data stream rather than a replication of the last two bytes of the iv as specified in the RFC to determine if the correct decryption key has been found. The decryption classes will now cope with both.
    -

    2.51.3 Additional Features and Functionality

    +

    2.58.3 Additional Features and Functionality

    • Support for extracting signatures based on PGP user attributes has been added to PGPPublicKey. @@ -1942,10 +2146,10 @@

      2.51.3 Additional Features and Functionality

    • OID components of up to 2^63 bits are now supported.
    -

    2.52.1 Version

    +

    2.59.1 Version

    Release: 1.24
    Date:      2004, June 12 -

    2.52.2 Defects Fixed

    +

    2.59.2 Defects Fixed

    • OpenPGP Secret key rings now parse key rings with user attribute packets in them correctly.
    • OpenPGP Secret key rings now parse key rings with GPG comment packets in them. @@ -1962,17 +2166,17 @@

      2.52.2 Defects Fixed

    • An encoding error introduced in 1.23 which affected generation of the KeyUsage extension has been fixed.
    -

    2.52.3 Additional Features and Functionality

    +

    2.59.3 Additional Features and Functionality

    • PKCS12 keystore now handles single key/certificate files without any attributes present.
    • Support for creation of PGPKeyRings incorporating sub keys has been added.
    • ZeroPadding for encrypting ASCII data has been added.
    -

    2.53.1 Version

    +

    2.60.1 Version

    Release: 1.23
    Date:      2004, April 10 -

    2.53.2 Defects Fixed

    +

    2.60.2 Defects Fixed

    • Reading a PGP Secret key file would sometimes cause a class cast exception. This has been fixed.
    • PGP will now read SecretKeys which are encrypted with the null algorithm. @@ -1987,7 +2191,7 @@

      2.53.2 Defects Fixed

    • X509Name class will now print names with nested pairs in component sets correctly.
    • RC4 now resets correctly on doFinal.
    -

    2.53.3 Additional Features and Functionality

    +

    2.60.3 Additional Features and Functionality

    • PGP V3 keys and V3 signature generation is now supported.
    • Collection classes have been added for representing files of PGP public and secret keys. @@ -2006,10 +2210,10 @@

      2.53.3 Additional Features and Functionality

    • DERGeneralizedTime getTime() method now handles a broader range of input strings.
    -

    2.54.1 Version

    +

    2.61.1 Version

    Release: 1.22
    Date:      2004, February 7 -

    2.54.2 Defects Fixed

    +

    2.61.2 Defects Fixed

    • Generating DSA signatures with PGP would cause a class cast exception, this has been fixed.
    • PGP Data in the 192 to 8383 byte length would sometimes be written with the wrong length header. This has been fixed. @@ -2019,7 +2223,7 @@

      2.54.2 Defects Fixed

    • PSS signature verification would fail approximately 0.5 % of the time on correct signatures. This has been fixed.
    • Encoding of CRL Distribution Points now always works.
    -

    2.54.3 Additional Features and Functionality

    +

    2.61.3 Additional Features and Functionality

    • Additional methods for getting public key information have been added to the PGP package.
    • Some support for user attributes and the image attribute tag has been added. @@ -2027,10 +2231,10 @@

      2.54.3 Additional Features and Functionality

    • Support for ElGamal encryption/decryption has been added to the PGP package.
    -

    2.55.1 Version

    +

    2.62.1 Version

    Release: 1.21
    Date:      2003, December 6 -

    2.55.2 Defects Fixed

    +

    2.62.2 Defects Fixed

    • The CertPath validator would fail for some valid CRLs. This has been fixed.
    • AES OIDS for S/MIME were still incorrect, this has been fixed. @@ -2038,17 +2242,17 @@

      2.55.2 Defects Fixed

    • The J2ME BigInteger class would sometimes go into an infinite loop generating prime numbers. This has been fixed.
    • DERBMPString.equals() would throw a class cast exception. This has been fixed.
    -

    2.55.3 Additional Features and Functionality

    +

    2.62.3 Additional Features and Functionality

    • PEMReader now handles public keys.
    • OpenPGP/BCPG should now handle partial input streams. Additional methods for reading subpackets off signatures.
    • The ASN.1 library now supports policy qualifiers and policy info objects.
    -

    2.56.1 Version

    +

    2.63.1 Version

    Release: 1.20
    Date:      2003, October 8 -

    2.56.2 Defects Fixed

    +

    2.63.2 Defects Fixed

    • BigInteger toString() in J2ME/JDK1.0 now produces same output as the Sun one.
    • RSA would throw a NullPointer exception with doFinal without arguments. This has been fixed. @@ -2058,7 +2262,7 @@

      2.56.2 Defects Fixed

    • AES OIDS were incorrect, this has been fixed.
    • In some cases BC generated private keys would not work with the JSSE. This has been fixed.
    -

    2.56.3 Additional Features and Functionality

    +

    2.63.3 Additional Features and Functionality

    • Support for reading/writing OpenPGP public/private keys and OpenPGP signatures has been added.
    • Support for generating OpenPGP PBE messages and public key encrypted messages has been added. @@ -2066,10 +2270,10 @@

      2.56.3 Additional Features and Functionality

    • Addition of a Null block cipher to the light weight API.
    -

    2.57.1 Version

    +

    2.64.1 Version

    Release: 1.19
    Date:      2003, June 7 -

    2.57.2 Defects Fixed

    +

    2.64.2 Defects Fixed

    • The PKCS12 store would throw an exception reading PFX files that had attributes with no values. This has been fixed.
    • RSA Private Keys would not serialise if they had PKCS12 bag attributes attached to them, this has been fixed. @@ -2077,7 +2281,7 @@

      2.57.2 Defects Fixed

    • ASN1 parser would sometimes mistake an implicit null for an implicit empty sequence. This has been fixed.
    -

    2.57.3 Additional Features and Functionality

    +

    2.64.3 Additional Features and Functionality

    • S/MIME and CMS now support the draft standard for AES encryption.
    • S/MIME and CMS now support setable key sizes for the standard algorithms. @@ -2089,10 +2293,10 @@

      2.57.3 Additional Features and Functionality

      in order to find algorithms.
    -

    2.58.1 Version

    +

    2.65.1 Version

    Release: 1.18
    Date:      2003, February 8 -

    2.58.2 Defects Fixed

    +

    2.65.2 Defects Fixed

    • DESKeySpec.isParityAdjusted in the clean room JCE could go into an infinite loop. This has been fixed. @@ -2103,7 +2307,7 @@

      2.58.2 Defects Fixed

    • Seeding with longs in the SecureRandom for the J2ME and JDK 1.0, only used 4 bytes of the seed value. This has been fixed.
    -

    2.58.3 Additional Features and Functionality

    +

    2.65.3 Additional Features and Functionality

    • The X.509 OID for RSA is now recognised by the provider as is the OID for RSA/OAEP.
    • Default iv's for DES are now handled correctly in CMS. @@ -2115,10 +2319,10 @@

      2.58.3 Additional Features and Functionality

      Sun BigInteger library.
    -

    2.59.1 Version

    +

    2.66.1 Version

    Release: 1.17
    Date:      2003, January 8 -

    2.59.2 Defects Fixed

    +

    2.66.2 Defects Fixed

    • Reuse of an CMSSignedObject could occasionally result in a class cast exception. This has been fixed. @@ -2129,7 +2333,7 @@

      2.59.2 Defects Fixed

    • The DERObject constructor in OriginatorIdentifierOrKey was leaving the id field as null. This has been fixed.
    -

    2.59.3 Additional Functionality and Features

    +

    2.66.3 Additional Functionality and Features

    • RC2 now supports the full range of parameter versions and effective key sizes. @@ -2149,10 +2353,10 @@

      2.59.3 Additional Functionality and Features

      string to OID conversion.
    -

    2.60.1 Version

    +

    2.67.1 Version

    Release: 1.16
    Date:      2002, November 30 -

    2.60.2 Defects Fixed

    +

    2.67.2 Defects Fixed

    • CRLS were only working for UTC time constructed Time objects, this has been fixed. @@ -2166,7 +2370,7 @@

      2.60.2 Defects Fixed

      to throw a NullPointerException at the wrong time.
    • Macs now clone correctly in the clean room JCE.
    -

    2.60.3 Additional Functionality and Features

    +

    2.67.3 Additional Functionality and Features

    • PGPCFB support has been added to the provider and the lightweight API.
    • There are now three versions of the AESEngine, all faster than before, @@ -2184,10 +2388,10 @@

      2.60.3 Additional Functionality and Features

      and to support multiple recipients/signers.
    -

    2.61.1 Version

    +

    2.68.1 Version

    Release: 1.15
    Date:      2002, September 6 -

    2.61.2 Defects Fixed

    +

    2.68.2 Defects Fixed

    • The base string for the oids in asn1.x509.KeyPurposeId was incorrect. This has been fixed. @@ -2210,7 +2414,7 @@

      2.61.2 Defects Fixed

      The local name now takes precedence.
    • ReasonFlags now correctly encodes.
    -

    2.61.3 Additional Functionality and Features

    +

    2.68.3 Additional Functionality and Features

    • The PKCS12 key store now handles key bags in encryptedData bags.
    • The X509NameTokenizer now handles for '\' and '"' characters. @@ -2219,10 +2423,10 @@

      2.61.3 Additional Functionality and Features

    • Both the provider and the lightweight library now support a basic SIC mode for block ciphers.
    -

    2.62.1 Version

    +

    2.69.1 Version

    Release: 1.14
    Date:      2002, June 17 -

    2.62.2 Defects Fixed

    +

    2.69.2 Defects Fixed

    • there was a bug in the BigInteger right shifting for > 31 bit shifts. This has been fixed. @@ -2243,7 +2447,7 @@

      2.62.2 Defects Fixed

    • asn1.x509.ExtendedKeyUsage used to throw a null pointer exception on construction. This has been fixed.
    -

    2.62.3 Additional Functionality and Features

    +

    2.69.3 Additional Functionality and Features

    • The BigInteger library now uses Montgomery numbers for modPow and is substantially faster. @@ -2257,10 +2461,10 @@

      2.62.3 Additional Functionality and Features

      object identifiers.
    -

    2.63.1 Version

    +

    2.70.1 Version

    Release: 1.13
    Date:      2002, April 19 -

    2.63.2 Defects Fixed

    +

    2.70.2 Defects Fixed

    • The TBSCertificate object in the ASN.1 library now properly implements the Time object, rather returning UTC time. @@ -2269,7 +2473,7 @@

      2.63.2 Defects Fixed

    • toByteArray in the big integer class was not always producing correct results for negative numbers. This has been Fixed.
    -

    2.63.3 Additional Functionality and Features

    +

    2.70.3 Additional Functionality and Features

    • The key to keySpec handling of the secret key factories has been improved.
    • There is now a SMIME implementation and a more complete CMS @@ -2284,10 +2488,10 @@

      2.63.3 Additional Functionality and Features

      length certificate chains for signing keys.
    -

    2.64.1 Version

    +

    2.71.1 Version

    Release: 1.12
    Date:      2002, February 8 -

    2.64.2 Defects Fixed

    +

    2.71.2 Defects Fixed

    • The ASN.1 library was unable to read an empty set object. This has been fixed.
    • Returning sets of critical and non-critical extensions on X.509 certificates could result in a null pointer exception if the certificate had no extensions. This has been fixed. @@ -2306,7 +2510,7 @@

      2.64.2 Defects Fixed

    • the IV algorithm parameters class would improperly throw an exception on initialisation. This has been fixed.
    -

    2.64.3 Additional Functionality and Features

    +

    2.71.3 Additional Functionality and Features

    • The AESWrap ciphers will now take IV's.
    • The DES-EDEWrap algorithm described in https://www.ietf.org/internet-drafts/draft-ietf-smime-key-wrap-01.txt is now supported. @@ -2320,10 +2524,10 @@

      2.64.3 Additional Functionality and Features

      for details).
    -

    2.65.1 Version

    +

    2.72.1 Version

    Release: 1.11
    Date:      2001, December 10 -

    2.65.2 Defects Fixed

    +

    2.72.2 Defects Fixed

    • X9.23 padding of MACs now works correctly with block size aligned data.
    • Loading a corrupted "UBER" key store would occasionally cause the @@ -2349,7 +2553,7 @@

      2.65.2 Defects Fixed

      extensions. This has been fixed.
    • The NetscapeCert type bits were reversed! This has been fixed.
    -

    2.65.3 Additional Functionality and Features

    +

    2.72.3 Additional Functionality and Features

    • The lightweight API and the JCE provider now support ElGamal.
    • X509Principal, and X509Name now supports the "DC" attribute and the @@ -2363,7 +2567,7 @@

      2.65.3 Additional Functionality and Features

    • Elliptic curve routines now handle uncompressed points as well as the compressed ones.
    -

    2.65.4 Other changes

    +

    2.72.4 Other changes

    • As the range of public key types supported has expanded the getPublicKey method on the SubjectPublicKeyInfo class is not always going to work. The @@ -2371,10 +2575,10 @@

      2.65.4 Other changes

      throws an IOException if there is a problem.
    -

    2.66.1 Version

    +

    2.73.1 Version

    Release: 1.10
    Date:      2001, October 20 -

    2.66.2 Defects Fixed

    +

    2.73.2 Defects Fixed

    • The PKCS12 Key Store now interoperates with the JDK key tool. Note: this does mean the the key name passed to the setKeyEntry calls has become significant. @@ -2382,7 +2586,7 @@

      2.66.2 Defects Fixed

      has been fixed.
    • The ASN.1 input streams now handle zero-tagged zero length objects correctly.
    -

    2.66.3 Additional Functionality and Features

    +

    2.73.3 Additional Functionality and Features

    • The JCE Provider and the lightweight API now support Serpent, CAST5, and CAST6.
    • The JCE provider and the lightweight API now has an implementation of ECIES. @@ -2392,10 +2596,10 @@

      2.66.3 Additional Functionality and Features

    • Support for the generation of PKCS10 certification requests has been added.
    -

    2.67.1 Version

    +

    2.74.1 Version

    Release: 1.09
    Date:      2001, October 6 -

    2.67.2 Defects Fixed

    +

    2.74.2 Defects Fixed

    • failure to pass in an RC5 parameters object now results in an exception at the upper level of the JCE, rather than falling over in the lightweight @@ -2408,7 +2612,7 @@

      2.67.2 Defects Fixed

    • In some cases the ASN.1 library wouldn't handle implicit tagging properly. This has been fixed.
    -

    2.67.3 Additional Functionality and Features

    +

    2.74.3 Additional Functionality and Features

    • Support for RC5-64 has been added to the JCE.
    • ISO9796-2 signatures have been added to the JCE and lightweight API. @@ -2432,10 +2636,10 @@

      2.67.3 Additional Functionality and Features

      resource hungry and faster - whether it's fast enough remains to be seen!
    -

    2.68.1 Version

    +

    2.75.1 Version

    Release: 1.08
    Date:      2001, September 9 -

    2.68.2 Defects Fixed

    +

    2.75.2 Defects Fixed

    • It wasn't possible to specify an ordering for distinguished names in X509 certificates. This is now supported. @@ -2446,7 +2650,7 @@

      2.68.2 Defects Fixed

    • The netscape certificate request class wouldn't compile under JDK 1.1. This has been fixed.
    -

    2.68.3 Additional Functionality and Features

    +

    2.75.3 Additional Functionality and Features

    • ISO 9796-1 padding is now supported with RSA in the lightweight API and the JCE. @@ -2460,10 +2664,10 @@

      2.68.3 Additional Functionality and Features

      this is fixed.
    -

    2.69.1 Version

    +

    2.76.1 Version

    Release: 1.07
    Date:      2001, July 9 -

    2.69.2 Defects Fixed

    +

    2.76.2 Defects Fixed

    • It turned out that the setOddParity method in the DESParameter class was indeed doing something odd but not what was intended. This is now @@ -2474,10 +2678,10 @@

      2.69.2 Defects Fixed

      have a look in org.bouncycastle.jce.provider.JDKKeyStore lines 201-291.
    -

    2.70.1 Version

    +

    2.77.1 Version

    Release: 1.06
    Date:      2001, July 2 -

    2.70.2 Defects Fixed

    +

    2.77.2 Defects Fixed

    • Diffie-Hellman keys are now properly serialisable as well as encodable. @@ -2499,17 +2703,17 @@

      2.70.2 Defects Fixed

    • Resetting and resusing HMacs in the lightweight and heavyweight libraries caused a NullPointer exception. This has been fixed.
    -

    2.70.3 Additional Functionality

    +

    2.77.3 Additional Functionality

    • ISO10126Padding is now recognised explicitly for block ciphers as well.
    • The Blowfish implementation is now somewhat faster.
    -

    2.70.1 Version

    +

    2.78.1 Version

    Release: 1.05
    Date:      2001, April 17 -

    2.70.2 Defects Fixed

    +

    2.78.2 Defects Fixed

    • The DESEDE key generator can now be used to generate 2-Key-DESEDE keys as well as 3-Key-DESEDE keys. @@ -2520,22 +2724,22 @@

      2.70.2 Defects Fixed

    • The ASN.1 library was skipping explicitly tagged objects of zero length. This has been fixed.
    -

    2.70.3 Additional Functionality

    +

    2.78.3 Additional Functionality

    • There is now an org.bouncycastle.jce.netscape package which has a class in for dealing with Netscape Certificate Request objects.
    -

    2.70.4 Additional Notes

    +

    2.78.4 Additional Notes

    Concerning the PKCS12 fix: in a few cases this may cause some backward compatibility issues - if this happens to you, drop us a line at feedback-crypto@bouncycastle.org and we will help you get it sorted out.

    -

    2.70.1 Version

    +

    2.79.1 Version

    Release: 1.04
    Date:      2001, March 11 -

    2.70.2 Defects Fixed

    +

    2.79.2 Defects Fixed

    • Signatures generated by other providers that include optional null parameters in the AlgorithmIdentifier are now handled correctly by the @@ -2564,7 +2768,7 @@

      2.70.2 Defects Fixed

      hash table when the hash table constructor was called. This has been fixed.
    -

    2.70.3 Additional Functionality

    +

    2.79.3 Additional Functionality

    • Added Elliptic Curve DSA (X9.62) - ECDSA - to provider and lightweight library. @@ -2576,10 +2780,10 @@

      2.70.3 Additional Functionality

    • The certificate generators now support ECDSA and DSA certs as well.
    -

    2.70.1 Version

    +

    2.80.1 Version

    Release: 1.03
    Date:      2001, January 7 -

    2.70.2 Defects Fixed

    +

    2.80.2 Defects Fixed

    • CFB and OFB modes when specified without padding would insist on input being block aligned. When specified without padding CFB and OFB now behave in a compatible @@ -2589,29 +2793,29 @@

      2.70.2 Defects Fixed

      length as the plain text.
    -

    2.70.1 Version

    +

    2.81.1 Version

    Release: 1.02
    Date:      2000, November 7 -

    2.70.2 Defects Fixed

    +

    2.81.2 Defects Fixed

    • The RSA key pair generator occasionally produced keys 1 bit under the requested size. This is now fixed.
    -

    2.70.1 Version

    +

    2.82.1 Version

    Release: 1.01
    Date:      2000, October 15 -

    2.70.2 Defects Fixed

    +

    2.82.2 Defects Fixed

    • Buffered ciphers in lightweight library were not resetting correctly on a doFinal. This has been fixed.
    -

    2.71.1 Version

    +

    2.83.1 Version

    Release: 1.00
    Date:      2000, October 13 -

    2.71.2 Defects Fixed

    +

    2.83.2 Defects Fixed

    • JDK1.2 version now works with keytool for certificate generation. @@ -2626,7 +2830,7 @@

      2.71.2 Defects Fixed

    • Some DES PBE algorithms did not set the parity correctly in generated keys, this has been fixed.
    -

    2.71.3 Additional functionality

    +

    2.83.3 Additional functionality

    • Argument validation is much improved. diff --git a/gradle.properties b/gradle.properties index de166998ff..bd57b2ce2f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,6 @@ -org.gradle.jvmargs=-Xmx2g \ No newline at end of file +org.gradle.jvmargs=-Xmx2g +version=1.79-SNAPSHOT +maxVersion=1.80 +org.gradle.java.installations.auto-detect=false +org.gradle.java.installations.auto-download=false +org.gradle.java.installations.fromEnv=BC_JDK8,BC_JDK11,BC_JDK17,BC_JDK21 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..afba109285 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..3499ded5c1 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 index 1b6c787337..65dcd68d65 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,10 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' @@ -143,12 +143,16 @@ fi if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -205,6 +209,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 107acd32c4..93e3f59f13 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/jmail/build.gradle b/jmail/build.gradle new file mode 100644 index 0000000000..27115d6d79 --- /dev/null +++ b/jmail/build.gradle @@ -0,0 +1,118 @@ + +plugins { + id "biz.aQute.bnd.builder" version "7.0.0" +} + +jar.archiveBaseName = "bcjmail-$vmrange" + +sourceSets { + main { + java { + srcDirs = ['build/src/main/java'] + } + } + + java9 { + java { + srcDirs = ['src/main/jdk1.9'] + } + } + +} + +dependencies { + implementation project(':prov') + implementation project(':util') + implementation project(':pkix') + + implementation group: 'jakarta.mail', name: 'jakarta.mail-api', version: '2.0.1' + implementation group: 'jakarta.activation', name: 'jakarta.activation-api', version: '2.0.0' + implementation files("$bc_prov") + implementation files("$bc_util") + implementation files("$bc_pkix") + implementation project(path: ':core') + + java9Implementation files("$bc_prov") + java9Implementation files("$bc_util") + java9Implementation files("$bc_pkix") + java9Implementation files(sourceSets.main.output.classesDirs) { + builtBy compileJava + } +} + +task copyTask(type: Copy) { + duplicatesStrategy = 'include' + from '../mail/src/main/java' + from 'src/main/java' + into 'build/src/main/java' + filter { String line -> (line.contains('javax.mail') || line.contains('javax.activation')) ? line.replace('javax.mail', 'jakarta.mail').replace('javax.activation', 'jakarta.activation') : line } +} + +compileJava.dependsOn(copyTask) + + +compileJava { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + targetCompatibility = 1.8; + sourceCompatibility = 1.8; +} + + +compileJava9Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + sourceCompatibility = 9 + targetCompatibility = 9 + options.compilerArgs += [ + '--module-path', "$bc_prov${File.pathSeparator}$bc_util${File.pathSeparator}$bc_pkix${File.pathSeparator}${rootProject.projectDir}/libs/jakarta.mail-2.0.1.jar${File.pathSeparator}${rootProject.projectDir}/libs/jakarta.activation-api-2.0.0.jar" + ] + options.sourcepath = files(['build/src/main/java', 'src/main/jdk1.9']) + +} + + +jar { + from sourceSets.main.output + into('META-INF/versions/9') { + from sourceSets.java9.output + } + String v = "${rootProject.extensions.ext.bundle_version}" + manifest.attributes('Multi-Release': 'true') + manifest.attributes('Bundle-Name': 'bcjmail') + manifest.attributes('Bundle-SymbolicName': 'bcjmail') + manifest.attributes('Bundle-RequiredExecutionEnvironment': 'JavaSE-1.8') + manifest.attributes('Export-Package': "org.bouncycastle.mail.*;version=${v}") + manifest.attributes('Import-Package': "java.*;resolution:=optional,javax.*;resolution:=optional,jakarta.*;resolution:=optional,!org.bouncycastle.mail.*,org.bouncycastle.*;version=\"[${v},${maxVersion})\"") + manifest.attributes('Bundle-Version': "${v}") +} + +task sourcesJar(type: Jar) { + archiveBaseName = jar.archiveBaseName + archiveClassifier = 'sources' + from sourceSets.main.allSource + into('META-INF/versions/9') { + from sourceSets.java9.allSource + } +} + +sourcesJar.dependsOn(copyTask) + +task javadocJar(type: Jar, dependsOn: javadoc) { + archiveBaseName = jar.archiveBaseName + archiveClassifier = 'javadoc' + from javadoc.destinationDir +} + +artifacts { + archives jar + archives javadocJar + archives sourcesJar +} + +test { + forkEvery = 1; + maxParallelForks = 8; +} diff --git a/libs/activation-1.1.1-sources.jar b/libs/activation-1.1.1-sources.jar new file mode 100644 index 0000000000..911b4965fc Binary files /dev/null and b/libs/activation-1.1.1-sources.jar differ diff --git a/libs/activation.jar b/libs/activation-1.1.1.jar similarity index 100% rename from libs/activation.jar rename to libs/activation-1.1.1.jar diff --git a/libs/jakarta.activation-api-2.0.0-sources.jar b/libs/jakarta.activation-api-2.0.0-sources.jar new file mode 100644 index 0000000000..aed03b7ffa Binary files /dev/null and b/libs/jakarta.activation-api-2.0.0-sources.jar differ diff --git a/libs/jakarta.mail-2.0.1-sources.jar b/libs/jakarta.mail-2.0.1-sources.jar new file mode 100644 index 0000000000..d389244f42 Binary files /dev/null and b/libs/jakarta.mail-2.0.1-sources.jar differ diff --git a/libs/javax.mail-1.4.7-sources.jar b/libs/javax.mail-1.4.7-sources.jar new file mode 100644 index 0000000000..dfa8cb6a97 Binary files /dev/null and b/libs/javax.mail-1.4.7-sources.jar differ diff --git a/libs/javax.mail-1.4.7.jar b/libs/javax.mail-1.4.7.jar new file mode 100644 index 0000000000..87f5d9fcc5 Binary files /dev/null and b/libs/javax.mail-1.4.7.jar differ diff --git a/libs/junit-4.13.2-sources.jar b/libs/junit-4.13.2-sources.jar new file mode 100644 index 0000000000..c6b46f6ea7 Binary files /dev/null and b/libs/junit-4.13.2-sources.jar differ diff --git a/libs/junit-4.13.2.jar b/libs/junit-4.13.2.jar new file mode 100644 index 0000000000..6da55d8b85 Binary files /dev/null and b/libs/junit-4.13.2.jar differ diff --git a/libs/junit.jar b/libs/junit.jar deleted file mode 100644 index 3a7fc266c3..0000000000 Binary files a/libs/junit.jar and /dev/null differ diff --git a/libs/mail.jar b/libs/mail.jar deleted file mode 100644 index e6f7083248..0000000000 Binary files a/libs/mail.jar and /dev/null differ diff --git a/libs/unboundid-ldapsdk-6.0.8-sources.jar b/libs/unboundid-ldapsdk-6.0.8-sources.jar new file mode 100644 index 0000000000..51c54bb1c4 Binary files /dev/null and b/libs/unboundid-ldapsdk-6.0.8-sources.jar differ diff --git a/libs/unboundid-ldapsdk-6.0.8.jar b/libs/unboundid-ldapsdk-6.0.8.jar new file mode 100644 index 0000000000..29c975582b Binary files /dev/null and b/libs/unboundid-ldapsdk-6.0.8.jar differ diff --git a/mail/build.gradle b/mail/build.gradle index a5f5fc62aa..398c62af48 100644 --- a/mail/build.gradle +++ b/mail/build.gradle @@ -1,23 +1,87 @@ +plugins { + id "biz.aQute.bnd.builder" version "7.0.0" +} + +jar.archiveBaseName = "bcmail-$vmrange" + +sourceSets { + java9 { + java { + srcDirs = ['src/main/jdk1.9'] + } + } +} + dependencies { - implementation project(':core') + implementation project(':prov') implementation project(':util') implementation project(':pkix') - implementation project(':prov') implementation group: 'javax.mail', name: 'mail', version: '1.4' + implementation files("$bc_prov") + implementation files("$bc_util") + implementation files("$bc_pkix") + implementation project(path: ':core') + + java9Implementation files("$bc_prov") + java9Implementation files("$bc_util") + java9Implementation files("$bc_pkix") + java9Implementation files(sourceSets.main.output.classesDirs) { + builtBy compileJava + } } -jar.archiveBaseName = "bcmail-$vmrange" +compileJava { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + targetCompatibility = 1.8; + sourceCompatibility = 1.8; +} + + +compileJava9Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + sourceCompatibility = 9 + targetCompatibility = 9 + options.compilerArgs += [ + '--module-path', "${bc_prov}${File.pathSeparator}${bc_util}${File.pathSeparator}${bc_pkix}" + ] + + options.sourcepath = files(['src/main/java', 'src/main/jdk1.9']) +} + + +jar { + from sourceSets.main.output + into('META-INF/versions/9') { + from sourceSets.java9.output + } + String v = "${rootProject.extensions.ext.bundle_version}" + manifest.attributes('Multi-Release': 'true') + manifest.attributes('Bundle-Name': 'bcmail') + manifest.attributes('Bundle-SymbolicName': 'bcmail') + manifest.attributes('Bundle-RequiredExecutionEnvironment': 'JavaSE-1.8') + manifest.attributes('Export-Package': "org.bouncycastle.mail.*;version=${v}") + manifest.attributes('Import-Package': "java.*;resolution:=optional,javax.*;resolution:=optional,!org.bouncycastle.mail.*,org.bouncycastle.*;version=\"[${v},${maxVersion})\"") + manifest.attributes('Bundle-Version': "${v}") +} task sourcesJar(type: Jar) { - archiveBaseName = jar.archiveBaseName - classifier = 'sources' - from sourceSets.main.allSource + archiveBaseName = jar.archiveBaseName + archiveClassifier = 'sources' + from sourceSets.main.allSource + into('META-INF/versions/9') { + from sourceSets.java9.allSource + } } + task javadocJar(type: Jar, dependsOn: javadoc) { archiveBaseName = jar.archiveBaseName - classifier = 'javadoc' + archiveClassifier = 'javadoc' from javadoc.destinationDir } @@ -27,3 +91,7 @@ artifacts { archives sourcesJar } +test { + forkEvery = 1; + maxParallelForks = 8; +} diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMECompressed.java b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMECompressed.java index 2fca936603..54a6281a37 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMECompressed.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMECompressed.java @@ -1,10 +1,6 @@ package org.bouncycastle.mail.smime; -import java.io.IOException; -import java.io.InputStream; - import javax.mail.MessagingException; -import javax.mail.Part; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimePart; @@ -20,25 +16,11 @@ public class SMIMECompressed { MimePart message; - private static InputStream getInputStream( - Part bodyPart) - throws MessagingException - { - try - { - return bodyPart.getInputStream(); - } - catch (IOException e) - { - throw new MessagingException("can't extract input stream: " + e); - } - } - public SMIMECompressed( MimeBodyPart message) throws MessagingException, CMSException { - super(getInputStream(message)); + super(SMIMEUtil.getInputStream(message)); this.message = message; } @@ -47,7 +29,7 @@ public SMIMECompressed( MimeMessage message) throws MessagingException, CMSException { - super(getInputStream(message)); + super(SMIMEUtil.getInputStream(message)); this.message = message; } diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMECompressedGenerator.java b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMECompressedGenerator.java index 9c40a5d5f4..b68a97c1e6 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMECompressedGenerator.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMECompressedGenerator.java @@ -109,14 +109,7 @@ public MimeBodyPart generate( OutputCompressor compressor) throws SMIMEException { - try - { - message.saveChanges(); // make sure we're up to date. - } - catch (MessagingException e) - { - throw new SMIMEException("unable to save message", e); - } + SMIMEUtil.messageSaveChanges(message); return make(makeContentBodyPart(message), compressor); } diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMECompressedParser.java b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMECompressedParser.java index 23214a4d8c..8833633bc9 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMECompressedParser.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMECompressedParser.java @@ -1,11 +1,6 @@ package org.bouncycastle.mail.smime; -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; - import javax.mail.MessagingException; -import javax.mail.Part; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimePart; @@ -21,30 +16,6 @@ public class SMIMECompressedParser { private final MimePart message; - private static InputStream getInputStream( - Part bodyPart, - int bufferSize) - throws MessagingException - { - try - { - InputStream in = bodyPart.getInputStream(); - - if (bufferSize == 0) - { - return new BufferedInputStream(in); - } - else - { - return new BufferedInputStream(in, bufferSize); - } - } - catch (IOException e) - { - throw new MessagingException("can't extract input stream: " + e); - } - } - public SMIMECompressedParser( MimeBodyPart message) throws MessagingException, CMSException @@ -71,7 +42,7 @@ public SMIMECompressedParser( int bufferSize) throws MessagingException, CMSException { - super(getInputStream(message, bufferSize)); + super(SMIMEUtil.getInputStream(message, bufferSize)); this.message = message; } @@ -88,7 +59,7 @@ public SMIMECompressedParser( int bufferSize) throws MessagingException, CMSException { - super(getInputStream(message, bufferSize)); + super(SMIMEUtil.getInputStream(message, bufferSize)); this.message = message; } diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEEnveloped.java b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEEnveloped.java index bf7a7ff4a6..ae9d0d67f8 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEEnveloped.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEEnveloped.java @@ -1,10 +1,6 @@ package org.bouncycastle.mail.smime; -import java.io.IOException; -import java.io.InputStream; - import javax.mail.MessagingException; -import javax.mail.Part; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimePart; @@ -20,25 +16,11 @@ public class SMIMEEnveloped { MimePart message; - private static InputStream getInputStream( - Part bodyPart) - throws MessagingException - { - try - { - return bodyPart.getInputStream(); - } - catch (IOException e) - { - throw new MessagingException("can't extract input stream: " + e); - } - } - public SMIMEEnveloped( MimeBodyPart message) throws MessagingException, CMSException { - super(getInputStream(message)); + super(SMIMEUtil.getInputStream(message)); this.message = message; } @@ -47,7 +29,7 @@ public SMIMEEnveloped( MimeMessage message) throws MessagingException, CMSException { - super(getInputStream(message)); + super(SMIMEUtil.getInputStream(message)); this.message = message; } diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEEnvelopedGenerator.java b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEEnvelopedGenerator.java index c1c0a9f60e..e431726567 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEEnvelopedGenerator.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEEnvelopedGenerator.java @@ -160,14 +160,7 @@ public MimeBodyPart generate( OutputEncryptor encryptor) throws SMIMEException { - try - { - message.saveChanges(); // make sure we're up to date. - } - catch (MessagingException e) - { - throw new SMIMEException("unable to save message", e); - } + SMIMEUtil.messageSaveChanges(message); return make(makeContentBodyPart(message), encryptor); } diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEEnvelopedParser.java b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEEnvelopedParser.java index 95849472f6..223d0a7cc7 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEEnvelopedParser.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEEnvelopedParser.java @@ -1,11 +1,8 @@ package org.bouncycastle.mail.smime; -import java.io.BufferedInputStream; import java.io.IOException; -import java.io.InputStream; import javax.mail.MessagingException; -import javax.mail.Part; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimePart; @@ -21,30 +18,6 @@ public class SMIMEEnvelopedParser { private final MimePart message; - private static InputStream getInputStream( - Part bodyPart, - int bufferSize) - throws MessagingException - { - try - { - InputStream in = bodyPart.getInputStream(); - - if (bufferSize == 0) - { - return new BufferedInputStream(in); - } - else - { - return new BufferedInputStream(in, bufferSize); - } - } - catch (IOException e) - { - throw new MessagingException("can't extract input stream: " + e); - } - } - public SMIMEEnvelopedParser( MimeBodyPart message) throws IOException, MessagingException, CMSException @@ -71,7 +44,7 @@ public SMIMEEnvelopedParser( int bufferSize) throws IOException, MessagingException, CMSException { - super(getInputStream(message, bufferSize)); + super(SMIMEUtil.getInputStream(message, bufferSize)); this.message = message; } @@ -88,7 +61,7 @@ public SMIMEEnvelopedParser( int bufferSize) throws IOException, MessagingException, CMSException { - super(getInputStream(message, bufferSize)); + super(SMIMEUtil.getInputStream(message, bufferSize)); this.message = message; } diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEGenerator.java b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEGenerator.java index faf73187d0..120693d0b9 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEGenerator.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEGenerator.java @@ -1,13 +1,14 @@ package org.bouncycastle.mail.smime; import java.io.IOException; -import java.security.NoSuchAlgorithmException; -import java.security.Provider; +//import java.security.NoSuchAlgorithmException; +//import java.security.Provider; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; -import javax.crypto.KeyGenerator; +import javax.activation.DataHandler; +//import javax.crypto.KeyGenerator; import javax.mail.Header; import javax.mail.MessagingException; import javax.mail.Multipart; @@ -126,15 +127,12 @@ protected MimeBodyPart makeContentBodyPart( throws SMIMEException { MimeBodyPart content = new MimeBodyPart(); - + // // add the headers to the body part. // try { - message.removeHeader("Message-Id"); - message.removeHeader("Mime-Version"); - // JavaMail has a habit of reparsing some content types, if the bodypart is // a multipart it might be signed, we rebuild the body part using the raw input stream for the message. try @@ -155,7 +153,7 @@ protected MimeBodyPart makeContentBodyPart( content.setContent(message.getContent(), message.getContentType()); - content.setDataHandler(message.getDataHandler()); + content.setDataHandler(new DataHandler(message.getDataHandler().getDataSource())); extractHeaders(content, message); } @@ -180,53 +178,65 @@ private void extractHeaders(MimeBodyPart content, MimeMessage message) { Header hdr = (Header)e.nextElement(); - content.addHeader(hdr.getName(), hdr.getValue()); - } - } - - protected KeyGenerator createSymmetricKeyGenerator( - String encryptionOID, - Provider provider) - throws NoSuchAlgorithmException - { - try - { - return createKeyGenerator(encryptionOID, provider); - } - catch (NoSuchAlgorithmException e) - { - try + // normalise some headers + if (hdr.getName().equals("Message-Id")) { - String algName = (String)BASE_CIPHER_NAMES.get(encryptionOID); - if (algName != null) - { - return createKeyGenerator(algName, provider); - } + content.addHeader("Message-ID", hdr.getValue()); } - catch (NoSuchAlgorithmException ex) + else if (hdr.getName().equals("Mime-Version")) { - // ignore + content.addHeader("MIME-Version", hdr.getValue()); } - if (provider != null) + else { - return createSymmetricKeyGenerator(encryptionOID, null); + content.addHeader(hdr.getName(), hdr.getValue()); } - throw e; } } - private KeyGenerator createKeyGenerator( - String algName, - Provider provider) - throws NoSuchAlgorithmException - { - if (provider != null) - { - return KeyGenerator.getInstance(algName, provider); - } - else - { - return KeyGenerator.getInstance(algName); - } - } +// protected KeyGenerator createSymmetricKeyGenerator( +// String encryptionOID, +// Provider provider) +// throws NoSuchAlgorithmException +// { +// try +// { +// return createKeyGenerator(encryptionOID, provider); +// } +// catch (NoSuchAlgorithmException e) +// { +// try +// { +// String algName = (String)BASE_CIPHER_NAMES.get(encryptionOID); +// if (algName != null) +// { +// return createKeyGenerator(algName, provider); +// } +// } +// catch (NoSuchAlgorithmException ex) +// { +// // ignore +// } +// if (provider != null) +// { +// return createSymmetricKeyGenerator(encryptionOID, null); +// } +// throw e; +// } +// } +// +// private KeyGenerator createKeyGenerator( +// String algName, +// Provider provider) +// throws NoSuchAlgorithmException +// { +// if (provider != null) +// { +// return KeyGenerator.getInstance(algName, provider); +// } +// else +// { +// return KeyGenerator.getInstance(algName); +// } +// } } diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMESigned.java b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMESigned.java index 9f2793986b..fd8698cc04 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMESigned.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMESigned.java @@ -3,7 +3,6 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStream; import java.security.AccessController; import java.security.PrivilegedAction; @@ -61,25 +60,6 @@ public class SMIMESigned Object message; MimeBodyPart content; - private static InputStream getInputStream( - Part bodyPart) - throws MessagingException - { - try - { - if (bodyPart.isMimeType("multipart/signed")) - { - throw new MessagingException("attempt to create signed data object from multipart content - use MimeMultipart constructor."); - } - - return bodyPart.getInputStream(); - } - catch (IOException e) - { - throw new MessagingException("can't extract input stream: " + e); - } - } - static { final MailcapCommandMap mc = (MailcapCommandMap)CommandMap.getDefaultCommandMap(); @@ -112,7 +92,7 @@ public SMIMESigned( MimeMultipart message) throws MessagingException, CMSException { - super(new CMSProcessableBodyPartInbound(message.getBodyPart(0)), getInputStream(message.getBodyPart(1))); + super(new CMSProcessableBodyPartInbound(message.getBodyPart(0)), SMIMEUtil.getInputStreamNoMultipartSigned(message.getBodyPart(1))); this.message = message; this.content = (MimeBodyPart)message.getBodyPart(0); @@ -132,7 +112,7 @@ public SMIMESigned( String defaultContentTransferEncoding) throws MessagingException, CMSException { - super(new CMSProcessableBodyPartInbound(message.getBodyPart(0), defaultContentTransferEncoding), getInputStream(message.getBodyPart(1))); + super(new CMSProcessableBodyPartInbound(message.getBodyPart(0), defaultContentTransferEncoding), SMIMEUtil.getInputStreamNoMultipartSigned(message.getBodyPart(1))); this.message = message; this.content = (MimeBodyPart)message.getBodyPart(0); @@ -150,7 +130,7 @@ public SMIMESigned( Part message) throws MessagingException, CMSException, SMIMEException { - super(getInputStream(message)); + super(SMIMEUtil.getInputStreamNoMultipartSigned(message)); this.message = message; diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMESignedGenerator.java b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMESignedGenerator.java index 1c221dd431..3d359848eb 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMESignedGenerator.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMESignedGenerator.java @@ -79,25 +79,25 @@ public class SMIMESignedGenerator extends SMIMEGenerator { - public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId(); - public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId(); - public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId(); - public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId(); - public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId(); - public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId(); - public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId(); - public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId(); - public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId(); - public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId(); - - public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId(); - public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId(); - public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); - public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId(); - public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId(); - public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId(); - public static final String ENCRYPTION_ECGOST3410_2012_256 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256.getId(); - public static final String ENCRYPTION_ECGOST3410_2012_512 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512.getId(); + public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId(); + public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId(); + public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId(); + public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId(); + public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId(); + public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId(); + public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId(); + public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId(); + public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId(); + public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId(); + + public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId(); + public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId(); + public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); + public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId(); + public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId(); + public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId(); + public static final String ENCRYPTION_ECGOST3410_2012_256 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256.getId(); + public static final String ENCRYPTION_ECGOST3410_2012_512 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512.getId(); private static final String CERTIFICATE_MANAGEMENT_CONTENT = "application/pkcs7-mime; name=smime.p7c; smime-type=certs-only"; private static final String DETACHED_SIGNATURE_TYPE = "application/pkcs7-signature; name=smime.p7s; smime-type=signed-data"; @@ -156,15 +156,15 @@ public Object run() } private final String defaultContentTransferEncoding; - private final Map micAlgs; + private final Map micAlgs; - private List certStores = new ArrayList(); - private List crlStores = new ArrayList(); - private List attrCertStores = new ArrayList(); - private List signerInfoGens = new ArrayList(); - private List _signers = new ArrayList(); - private List _oldSigners = new ArrayList(); - private Map _digests = new HashMap(); + private List certStores = new ArrayList(); + private List crlStores = new ArrayList(); + private List attrCertStores = new ArrayList(); + private List signerInfoGens = new ArrayList(); + private List _signers = new ArrayList(); + private List _oldSigners = new ArrayList(); + private Map _digests = new HashMap(); /** * base constructor - default content transfer encoding 7bit @@ -176,7 +176,7 @@ public SMIMESignedGenerator() /** * base constructor - default content transfer encoding explicitly set - * + * * @param defaultContentTransferEncoding new default to use. */ public SMIMESignedGenerator( @@ -200,7 +200,7 @@ public SMIMESignedGenerator( * base constructor - default content transfer encoding explicitly set * * @param defaultContentTransferEncoding new default to use. - * @param micAlgs a map of ANS1ObjectIdentifiers to strings hash algorithm names. + * @param micAlgs a map of ANS1ObjectIdentifiers to strings hash algorithm names. */ public SMIMESignedGenerator( String defaultContentTransferEncoding, @@ -218,7 +218,7 @@ public SMIMESignedGenerator( public void addSigners( SignerInformationStore signerStore) { - Iterator it = signerStore.getSigners().iterator(); + Iterator it = signerStore.getSigners().iterator(); while (it.hasNext()) { @@ -227,7 +227,6 @@ public void addSigners( } /** - * * @param sigInfoGen */ public void addSignerInfoGenerator(SignerInfoGenerator sigInfoGen) @@ -255,19 +254,19 @@ public void addAttributeCertificates( private void addHashHeader( StringBuffer header, - List signers) + List signers) { - int count = 0; - + int count = 0; + // // build the hash header // - Iterator it = signers.iterator(); - Set micAlgSet = new TreeSet(); - + Iterator it = signers.iterator(); + Set micAlgSet = new TreeSet(); + while (it.hasNext()) { - Object signer = it.next(); + Object signer = it.next(); ASN1ObjectIdentifier digestOID; if (signer instanceof SignerInformation) @@ -290,12 +289,12 @@ private void addHashHeader( micAlgSet.add(micAlg); } } - + it = micAlgSet.iterator(); - + while (it.hasNext()) { - String alg = (String)it.next(); + String alg = (String)it.next(); if (count == 0) { @@ -328,8 +327,8 @@ private void addHashHeader( } private MimeMultipart make( - MimeBodyPart content) - throws SMIMEException + MimeBodyPart content) + throws SMIMEException { try { @@ -344,8 +343,8 @@ private MimeMultipart make( // // build the multipart header // - StringBuffer header = new StringBuffer( - "signed; protocol=\"application/pkcs7-signature\""); + StringBuffer header = new StringBuffer( + "signed; protocol=\"application/pkcs7-signature\""); List allSigners = new ArrayList(_signers); @@ -355,7 +354,7 @@ private MimeMultipart make( addHashHeader(header, allSigners); - MimeMultipart mm = new MimeMultipart(header.toString()); + MimeMultipart mm = new MimeMultipart(header.toString()); mm.addBodyPart(content); mm.addBodyPart(sig); @@ -372,7 +371,7 @@ private MimeMultipart make( * at this point we expect our body part to be well defined - generate with data in the signature */ private MimeBodyPart makeEncapsulated( - MimeBodyPart content) + MimeBodyPart content) throws SMIMEException { try @@ -405,24 +404,17 @@ public Map getGeneratedDigests() } public MimeMultipart generate( - MimeBodyPart content) + MimeBodyPart content) throws SMIMEException { return make(makeContentBodyPart(content)); } public MimeMultipart generate( - MimeMessage message) + MimeMessage message) throws SMIMEException { - try - { - message.saveChanges(); // make sure we're up to date. - } - catch (MessagingException e) - { - throw new SMIMEException("unable to save message", e); - } + SMIMEUtil.messageSaveChanges(message); return make(makeContentBodyPart(message)); } @@ -435,36 +427,29 @@ public MimeMultipart generate( * message. */ public MimeBodyPart generateEncapsulated( - MimeBodyPart content) + MimeBodyPart content) throws SMIMEException { return makeEncapsulated(makeContentBodyPart(content)); } public MimeBodyPart generateEncapsulated( - MimeMessage message) + MimeMessage message) throws SMIMEException { - try - { - message.saveChanges(); // make sure we're up to date. - } - catch (MessagingException e) - { - throw new SMIMEException("unable to save message", e); - } + SMIMEUtil.messageSaveChanges(message); return makeEncapsulated(makeContentBodyPart(message)); } - /** + /** * Creates a certificate management message which is like a signed message with no content * or signers but that still carries certificates and CRLs. * * @return a MimeBodyPart containing the certs and CRLs. */ public MimeBodyPart generateCertificateManagement() - throws SMIMEException + throws SMIMEException { try { @@ -489,11 +474,11 @@ private class ContentSigner { private final MimeBodyPart content; private final boolean encapsulate; - private final boolean noProvider; + private final boolean noProvider; ContentSigner( MimeBodyPart content, - boolean encapsulate) + boolean encapsulate) { this.content = content; this.encapsulate = encapsulate; @@ -505,28 +490,28 @@ protected CMSSignedDataStreamGenerator getGenerator() { CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); - for (Iterator it = certStores.iterator(); it.hasNext();) + for (Iterator it = certStores.iterator(); it.hasNext(); ) { gen.addCertificates((Store)it.next()); } - for (Iterator it = crlStores.iterator(); it.hasNext();) + for (Iterator it = crlStores.iterator(); it.hasNext(); ) { gen.addCRLs((Store)it.next()); } - for (Iterator it = attrCertStores.iterator(); it.hasNext();) + for (Iterator it = attrCertStores.iterator(); it.hasNext(); ) { gen.addAttributeCertificates((Store)it.next()); } - for (Iterator it = signerInfoGens.iterator(); it.hasNext();) + for (Iterator it = signerInfoGens.iterator(); it.hasNext(); ) { gen.addSignerInfoGenerator((SignerInfoGenerator)it.next()); } gen.addSigners(new SignerInformationStore(_oldSigners)); - + return gen; } @@ -537,31 +522,9 @@ private void writeBodyPart( { if (SMIMEUtil.isMultipartContent(bodyPart)) { - Object content = bodyPart.getContent(); - Multipart mp; - if (content instanceof Multipart) - { - mp = (Multipart)content; - } - else - { - mp = new MimeMultipart(bodyPart.getDataHandler().getDataSource()); - } - - ContentType contentType = new ContentType(mp.getContentType()); - String boundary = "--" + contentType.getParameter("boundary"); - - SMIMEUtil.LineOutputStream lOut = new SMIMEUtil.LineOutputStream(out); - - Enumeration headers = bodyPart.getAllHeaderLines(); - while (headers.hasMoreElements()) - { - lOut.writeln((String)headers.nextElement()); - } - - lOut.writeln(); // CRLF separator - - SMIMEUtil.outputPreamble(lOut, bodyPart, boundary); + Multipart mp = SMIMEUtil.getMultipart(bodyPart); + String boundary = "--" + new ContentType(mp.getContentType()).getParameter("boundary"); + SMIMEUtil.LineOutputStream lOut = SMIMEUtil.writeMultipartContentBodyPart(out, bodyPart, boundary); for (int i = 0; i < mp.getCount(); i++) { @@ -589,9 +552,9 @@ public void write(OutputStream out) try { CMSSignedDataStreamGenerator gen = getGenerator(); - + OutputStream signingStream = gen.open(out, encapsulate); - + if (content != null) { if (!encapsulate) @@ -610,7 +573,7 @@ public void write(OutputStream out) content.writeTo(signingStream); } } - + signingStream.close(); _digests = gen.getGeneratedDigests(); diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMESignedParser.java b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMESignedParser.java index 40ed710d2a..964aa5c270 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMESignedParser.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMESignedParser.java @@ -67,25 +67,6 @@ public class SMIMESignedParser Object message; MimeBodyPart content; - private static InputStream getInputStream( - Part bodyPart) - throws MessagingException - { - try - { - if (bodyPart.isMimeType("multipart/signed")) - { - throw new MessagingException("attempt to create signed data object from multipart content - use MimeMultipart constructor."); - } - - return bodyPart.getInputStream(); - } - catch (IOException e) - { - throw new MessagingException("can't extract input stream: " + e); - } - } - private static File getTmpFile() throws MessagingException { @@ -224,7 +205,7 @@ public SMIMESignedParser( File backingFile) throws MessagingException, CMSException { - super(digCalcProvider, getSignedInputStream(message.getBodyPart(0), defaultContentTransferEncoding, backingFile), getInputStream(message.getBodyPart(1))); + super(digCalcProvider, getSignedInputStream(message.getBodyPart(0), defaultContentTransferEncoding, backingFile), SMIMEUtil.getInputStreamNoMultipartSigned(message.getBodyPart(1))); this.message = message; this.content = (MimeBodyPart)message.getBodyPart(0); @@ -251,7 +232,7 @@ public SMIMESignedParser( Part message) throws MessagingException, CMSException, SMIMEException { - super(digCalcProvider, getInputStream(message)); + super(digCalcProvider, SMIMEUtil.getInputStreamNoMultipartSigned(message)); this.message = message; @@ -283,7 +264,7 @@ public SMIMESignedParser( File file) throws MessagingException, CMSException, SMIMEException { - super(digCalcProvider, getInputStream(message)); + super(digCalcProvider, SMIMEUtil.getInputStreamNoMultipartSigned(message)); this.message = message; diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEToolkit.java b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEToolkit.java index 4f0f7e8363..939dcc1e58 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEToolkit.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEToolkit.java @@ -36,14 +36,14 @@ public class SMIMEToolkit /** * Base constructor. - * - * @param digestCalculatorProvider provider for any digest calculations required. + * + * @param digestCalculatorProvider provider for any digest calculations required. */ public SMIMEToolkit(DigestCalculatorProvider digestCalculatorProvider) { this.digestCalculatorProvider = digestCalculatorProvider; } - + /** * Return true if the passed in message (MimeBodyPart or MimeMessage) is encrypted. * @@ -75,7 +75,7 @@ public boolean isSigned(Part message) * Return true if the passed in MimeMultipart is a signed one. * * @param message message of interest - * @return true if the multipart has an attached signature, false otherwise. + * @return true if the multipart has an attached signature, false otherwise. * @throws MessagingException on a message processing issue. */ public boolean isSigned(MimeMultipart message) @@ -87,10 +87,10 @@ public boolean isSigned(MimeMultipart message) /** * Return true if there is a signature on the message that can be verified by the verifier. * - * @param message a MIME part representing a signed message. + * @param message a MIME part representing a signed message. * @param verifier the verifier we want to find a signer for. * @return true if cert verifies message, false otherwise. - * @throws SMIMEException on a SMIME handling issue. + * @throws SMIMEException on a SMIME handling issue. * @throws MessagingException on a basic message processing exception */ public boolean isValidSignature(Part message, SignerInformationVerifier verifier) @@ -140,7 +140,7 @@ private boolean isAtLeastOneValidSigner(SMIMESignedParser s, SignerInformationVe while (it.hasNext()) { - SignerInformation signer = (SignerInformation)it.next(); + SignerInformation signer = (SignerInformation)it.next(); if (signer.verify(verifier)) { @@ -154,10 +154,10 @@ private boolean isAtLeastOneValidSigner(SMIMESignedParser s, SignerInformationVe /** * Return true if there is a signature on the message that can be verified by verifier.. * - * @param message a MIME part representing a signed message. + * @param message a MIME part representing a signed message. * @param verifier the verifier we want to find a signer for. * @return true if cert verifies message, false otherwise. - * @throws SMIMEException on a SMIME handling issue. + * @throws SMIMEException on a SMIME handling issue. * @throws MessagingException on a basic message processing exception */ public boolean isValidSignature(MimeMultipart message, SignerInformationVerifier verifier) @@ -179,7 +179,7 @@ public boolean isValidSignature(MimeMultipart message, SignerInformationVerifier /** * Extract the signer's signing certificate from the message. * - * @param message a MIME part/MIME message representing a signed message. + * @param message a MIME part/MIME message representing a signed message. * @param signerInformation the signer information identifying the signer of interest. * @return the signing certificate, null if not found. */ @@ -199,14 +199,7 @@ public X509CertificateHolder extractCertificate(Part message, SignerInformation s = new SMIMESignedParser(digestCalculatorProvider, message); } - Collection certCollection = s.getCertificates().getMatches(signerInformation.getSID()); - - Iterator certIt = certCollection.iterator(); - if (certIt.hasNext()) - { - return (X509CertificateHolder)certIt.next(); - } - return null; + return getX509CertificateHolder(s, signerInformation); } catch (CMSException e) { @@ -218,10 +211,23 @@ public X509CertificateHolder extractCertificate(Part message, SignerInformation } } + private static X509CertificateHolder getX509CertificateHolder(SMIMESignedParser s, SignerInformation signerInformation) + throws CMSException + { + Collection certCollection = s.getCertificates().getMatches(signerInformation.getSID()); + + Iterator certIt = certCollection.iterator(); + if (certIt.hasNext()) + { + return (X509CertificateHolder)certIt.next(); + } + return null; + } + /** * Extract the signer's signing certificate from Multipart message content. * - * @param message a MIME Multipart part representing a signed message. + * @param message a MIME Multipart part representing a signed message. * @param signerInformation the signer information identifying the signer of interest. * @return the signing certificate, null if not found. */ @@ -230,16 +236,7 @@ public X509CertificateHolder extractCertificate(MimeMultipart message, SignerInf { try { - SMIMESignedParser s = new SMIMESignedParser(digestCalculatorProvider, message); - - Collection certCollection = s.getCertificates().getMatches(signerInformation.getSID()); - - Iterator certIt = certCollection.iterator(); - if (certIt.hasNext()) - { - return (X509CertificateHolder)certIt.next(); - } - return null; + return getX509CertificateHolder(new SMIMESignedParser(digestCalculatorProvider, message), signerInformation); } catch (CMSException e) { @@ -250,13 +247,18 @@ public X509CertificateHolder extractCertificate(MimeMultipart message, SignerInf /** * Produce a signed message in multi-part format with the second part containing a detached signature for the first. * - * @param message the message to be signed. + * @param message the message to be signed. * @param signerInfoGenerator the generator to be used to generate the signature. * @return the resulting MimeMultipart * @throws SMIMEException on an exception calculating or creating the signed data. */ public MimeMultipart sign(MimeBodyPart message, SignerInfoGenerator signerInfoGenerator) throws SMIMEException + { + return getSMIMESignedGenerator(signerInfoGenerator).generate(message); + } + + private static SMIMESignedGenerator getSMIMESignedGenerator(SignerInfoGenerator signerInfoGenerator) { SMIMESignedGenerator gen = new SMIMESignedGenerator(); @@ -271,13 +273,13 @@ public MimeMultipart sign(MimeBodyPart message, SignerInfoGenerator signerInfoGe gen.addSignerInfoGenerator(signerInfoGenerator); - return gen.generate(message); + return gen; } /** * Produce a signed message in encapsulated format where the message is encoded in the signature.. * - * @param message the message to be signed. + * @param message the message to be signed. * @param signerInfoGenerator the generator to be used to generate the signature. * @return a BodyPart containing the encapsulated message. * @throws SMIMEException on an exception calculating or creating the signed data. @@ -285,28 +287,15 @@ public MimeMultipart sign(MimeBodyPart message, SignerInfoGenerator signerInfoGe public MimeBodyPart signEncapsulated(MimeBodyPart message, SignerInfoGenerator signerInfoGenerator) throws SMIMEException { - SMIMESignedGenerator gen = new SMIMESignedGenerator(); - - if (signerInfoGenerator.hasAssociatedCertificate()) - { - List certList = new ArrayList(); - - certList.add(signerInfoGenerator.getAssociatedCertificate()); - - gen.addCertificates(new CollectionStore(certList)); - } - - gen.addSignerInfoGenerator(signerInfoGenerator); - - return gen.generateEncapsulated(message); + return getSMIMESignedGenerator(signerInfoGenerator).generateEncapsulated(message); } /** * Encrypt the passed in MIME part returning a new encrypted MIME part. * - * @param mimePart the part to be encrypted. - * @param contentEncryptor the encryptor to use for the actual message content. - * @param recipientGenerator the generator for the target recipient. + * @param mimePart the part to be encrypted. + * @param contentEncryptor the encryptor to use for the actual message content. + * @param recipientGenerator the generator for the target recipient. * @return an encrypted MIME part. * @throws SMIMEException in the event of an exception creating the encrypted part. */ @@ -323,9 +312,9 @@ public MimeBodyPart encrypt(MimeBodyPart mimePart, OutputEncryptor contentEncryp /** * Encrypt the passed in MIME multi-part returning a new encrypted MIME part. * - * @param multiPart the multi-part to be encrypted. - * @param contentEncryptor the encryptor to use for the actual message content. - * @param recipientGenerator the generator for the target recipient. + * @param multiPart the multi-part to be encrypted. + * @param contentEncryptor the encryptor to use for the actual message content. + * @param recipientGenerator the generator for the target recipient. * @return an encrypted MIME part. * @throws SMIMEException in the event of an exception creating the encrypted part. */ @@ -346,9 +335,9 @@ public MimeBodyPart encrypt(MimeMultipart multiPart, OutputEncryptor contentEncr /** * Encrypt the passed in MIME message returning a new encrypted MIME part. * - * @param message the multi-part to be encrypted. - * @param contentEncryptor the encryptor to use for the actual message content. - * @param recipientGenerator the generator for the target recipient. + * @param message the multi-part to be encrypted. + * @param contentEncryptor the encryptor to use for the actual message content. + * @param recipientGenerator the generator for the target recipient. * @return an encrypted MIME part. * @throws SMIMEException in the event of an exception creating the encrypted part. */ @@ -365,11 +354,11 @@ public MimeBodyPart encrypt(MimeMessage message, OutputEncryptor contentEncrypto /** * Decrypt the passed in MIME part returning a part representing the decrypted content. * - * @param mimePart the part containing the encrypted data. + * @param mimePart the part containing the encrypted data. * @param recipientId the recipient id in the date to be matched. - * @param recipient the recipient to be used if a match is found. + * @param recipient the recipient to be used if a match is found. * @return a MIME part containing the decrypted content or null if the recipientId cannot be matched. - * @throws SMIMEException on an exception doing the decryption. + * @throws SMIMEException on an exception doing the decryption. * @throws MessagingException on an exception parsing the message, */ public MimeBodyPart decrypt(MimeBodyPart mimePart, RecipientId recipientId, Recipient recipient) @@ -377,17 +366,7 @@ public MimeBodyPart decrypt(MimeBodyPart mimePart, RecipientId recipientId, Reci { try { - SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(mimePart); - - RecipientInformationStore recipients = m.getRecipientInfos(); - RecipientInformation recipientInformation = recipients.get(recipientId); - - if (recipientInformation == null) - { - return null; - } - - return SMIMEUtil.toMimeBodyPart(recipientInformation.getContent(recipient)); + return getMimeBodyPart(recipientId, recipient, new SMIMEEnvelopedParser(mimePart)); } catch (CMSException e) { @@ -399,14 +378,28 @@ public MimeBodyPart decrypt(MimeBodyPart mimePart, RecipientId recipientId, Reci } } + private static MimeBodyPart getMimeBodyPart(RecipientId recipientId, Recipient recipient, SMIMEEnvelopedParser m) + throws SMIMEException, CMSException + { + RecipientInformationStore recipients = m.getRecipientInfos(); + RecipientInformation recipientInformation = recipients.get(recipientId); + + if (recipientInformation == null) + { + return null; + } + + return SMIMEUtil.toMimeBodyPart(recipientInformation.getContent(recipient)); + } + /** * Decrypt the passed in MIME message returning a part representing the decrypted content. * - * @param message the message containing the encrypted data. + * @param message the message containing the encrypted data. * @param recipientId the recipient id in the date to be matched. - * @param recipient the recipient to be used if a match is found. + * @param recipient the recipient to be used if a match is found. * @return a MIME part containing the decrypted content, or null if the recipientId cannot be matched. - * @throws SMIMEException on an exception doing the decryption. + * @throws SMIMEException on an exception doing the decryption. * @throws MessagingException on an exception parsing the message, */ public MimeBodyPart decrypt(MimeMessage message, RecipientId recipientId, Recipient recipient) @@ -414,17 +407,7 @@ public MimeBodyPart decrypt(MimeMessage message, RecipientId recipientId, Recipi { try { - SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(message); - - RecipientInformationStore recipients = m.getRecipientInfos(); - RecipientInformation recipientInformation = recipients.get(recipientId); - - if (recipientInformation == null) - { - return null; - } - - return SMIMEUtil.toMimeBodyPart(recipientInformation.getContent(recipient)); + return getMimeBodyPart(recipientId, recipient, new SMIMEEnvelopedParser(message)); } catch (CMSException e) { diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEUtil.java b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEUtil.java index af7ce53854..e52697204f 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEUtil.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/SMIMEUtil.java @@ -1,5 +1,6 @@ package org.bouncycastle.mail.smime; +import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FilterOutputStream; @@ -16,6 +17,7 @@ import javax.mail.Part; import javax.mail.internet.ContentType; import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; @@ -33,18 +35,18 @@ public class SMIMEUtil public static boolean isMultipartContent(Part part) throws MessagingException { - String partType = Strings.toLowerCase(part.getContentType()); + String partType = Strings.toLowerCase(part.getContentType()); return partType.startsWith(MULTIPART); } static boolean isCanonicalisationRequired( - MimeBodyPart bodyPart, - String defaultContentTransferEncoding) + MimeBodyPart bodyPart, + String defaultContentTransferEncoding) throws MessagingException { - String[] cte = bodyPart.getHeader("Content-Transfer-Encoding"); - String contentTransferEncoding; + String[] cte = bodyPart.getHeader("Content-Transfer-Encoding"); + String contentTransferEncoding; if (cte == null) { @@ -58,7 +60,8 @@ static boolean isCanonicalisationRequired( return !contentTransferEncoding.equalsIgnoreCase("binary"); } - static class LineOutputStream extends FilterOutputStream + static class LineOutputStream + extends FilterOutputStream { private static byte newline[]; @@ -72,11 +75,11 @@ public void writeln(String s) { try { - byte abyte0[] = getBytes(s); + byte abyte0[] = Strings.toByteArray(s); super.out.write(abyte0); super.out.write(newline); } - catch(Exception exception) + catch (Exception exception) { throw new MessagingException("IOException", exception); } @@ -89,33 +92,18 @@ public void writeln() { super.out.write(newline); } - catch(Exception exception) + catch (Exception exception) { throw new MessagingException("IOException", exception); } } - static + static { newline = new byte[2]; newline[0] = 13; newline[1] = 10; } - - private static byte[] getBytes(String s) - { - char ac[] = s.toCharArray(); - int i = ac.length; - byte abyte0[] = new byte[i]; - int j = 0; - - while (j < i) - { - abyte0[j] = (byte)ac[j++]; - } - - return abyte0; - } } /** @@ -182,7 +170,7 @@ static void outputPostamble(LineOutputStream lOut, MimeBodyPart part, int count, if (line.startsWith(boundary)) { boundaries--; - + if (boundaries == 0) { break; @@ -194,7 +182,7 @@ static void outputPostamble(LineOutputStream lOut, MimeBodyPart part, int count, { lOut.writeln(line); } - + in.close(); if (boundaries != 0) @@ -264,51 +252,28 @@ private static String readLine(InputStream in) { return null; } - + return b.toString(); } static void outputBodyPart( OutputStream out, - boolean topLevel, - BodyPart bodyPart, - String defaultContentTransferEncoding) + boolean topLevel, + BodyPart bodyPart, + String defaultContentTransferEncoding) throws MessagingException, IOException { if (bodyPart instanceof MimeBodyPart) { - MimeBodyPart mimePart = (MimeBodyPart)bodyPart; - String[] cte = mimePart.getHeader("Content-Transfer-Encoding"); - String contentTransferEncoding; + MimeBodyPart mimePart = (MimeBodyPart)bodyPart; + String[] cte = mimePart.getHeader("Content-Transfer-Encoding"); + String contentTransferEncoding; if (isMultipartContent(mimePart)) { - Object content = bodyPart.getContent(); - Multipart mp; - if (content instanceof Multipart) - { - mp = (Multipart)content; - } - else - { - mp = new MimeMultipart(bodyPart.getDataHandler().getDataSource()); - } - - ContentType contentType = new ContentType(mp.getContentType()); - String boundary = "--" + contentType.getParameter("boundary"); - - SMIMEUtil.LineOutputStream lOut = new SMIMEUtil.LineOutputStream(out); - - Enumeration headers = mimePart.getAllHeaderLines(); - while (headers.hasMoreElements()) - { - String header = (String)headers.nextElement(); - lOut.writeln(header); - } - - lOut.writeln(); // CRLF separator - - outputPreamble(lOut, mimePart, boundary); + Multipart mp = SMIMEUtil.getMultipart(mimePart); + String boundary = "--" + new ContentType(mp.getContentType()).getParameter("boundary"); + SMIMEUtil.LineOutputStream lOut = SMIMEUtil.writeMultipartContentBodyPart(out, mimePart, boundary); for (int i = 0; i < mp.getCount(); i++) { @@ -345,7 +310,7 @@ static void outputBodyPart( } if (!contentTransferEncoding.equalsIgnoreCase("base64") - && !contentTransferEncoding.equalsIgnoreCase("quoted-printable")) + && !contentTransferEncoding.equalsIgnoreCase("quoted-printable")) { if (!contentTransferEncoding.equalsIgnoreCase("binary")) { @@ -381,10 +346,10 @@ static void outputBodyPart( // Write headers // LineOutputStream outLine = new LineOutputStream(out); - for (Enumeration e = mimePart.getAllHeaderLines(); e.hasMoreElements();) + for (Enumeration e = mimePart.getAllHeaderLines(); e.hasMoreElements(); ) { String header = (String)e.nextElement(); - + outLine.writeln(header); } @@ -393,7 +358,7 @@ static void outputBodyPart( OutputStream outCRLF; - + if (base64) { outCRLF = new Base64CRLFOutputStream(out); @@ -403,7 +368,7 @@ static void outputBodyPart( outCRLF = new CRLFOutputStream(out); } - byte[] buf = new byte[BUF_SIZE]; + byte[] buf = new byte[BUF_SIZE]; int len; while ((len = inRaw.read(buf, 0, buf.length)) > 0) @@ -433,17 +398,17 @@ static void outputBodyPart( * return the MimeBodyPart described in the raw bytes provided in content */ public static MimeBodyPart toMimeBodyPart( - byte[] content) + byte[] content) throws SMIMEException { return toMimeBodyPart(new ByteArrayInputStream(content)); } - + /** * return the MimeBodyPart described in the input stream content */ public static MimeBodyPart toMimeBodyPart( - InputStream content) + InputStream content) throws SMIMEException { try @@ -457,7 +422,7 @@ public static MimeBodyPart toMimeBodyPart( } static FileBackedMimeBodyPart toWriteOnceBodyPart( - CMSTypedStream content) + CMSTypedStream content) throws SMIMEException { try @@ -478,7 +443,7 @@ static FileBackedMimeBodyPart toWriteOnceBodyPart( * return a file backed MimeBodyPart described in {@link CMSTypedStream} content. */ public static FileBackedMimeBodyPart toMimeBodyPart( - CMSTypedStream content) + CMSTypedStream content) throws SMIMEException { try @@ -490,19 +455,19 @@ public static FileBackedMimeBodyPart toMimeBodyPart( throw new SMIMEException("IOException creating tmp file:" + e.getMessage(), e); } } - + /** * Return a file based MimeBodyPart represented by content and backed * by the file represented by file. - * + * * @param content content stream containing body part. - * @param file file to store the decoded body part in. + * @param file file to store the decoded body part in. * @return the decoded body part. * @throws SMIMEException */ public static FileBackedMimeBodyPart toMimeBodyPart( - CMSTypedStream content, - File file) + CMSTypedStream content, + File file) throws SMIMEException { try @@ -518,10 +483,10 @@ public static FileBackedMimeBodyPart toMimeBodyPart( throw new SMIMEException("can't create part: " + e, e); } } - + /** * Return a CMS IssuerAndSerialNumber structure for the passed in X.509 certificate. - * + * * @param cert the X.509 certificate to get the issuer and serial number for. * @return an IssuerAndSerialNumber structure representing the certificate. */ @@ -557,7 +522,8 @@ public void writeTo(OutputStream out) } } - static class Base64CRLFOutputStream extends FilterOutputStream + static class Base64CRLFOutputStream + extends FilterOutputStream { protected int lastb; protected static byte newline[]; @@ -626,4 +592,108 @@ public void writeln() newline[1] = '\n'; } } + + static InputStream getInputStream( + Part bodyPart, + int bufferSize) + throws MessagingException + { + try + { + InputStream in = bodyPart.getInputStream(); + + if (bufferSize == 0) + { + return new BufferedInputStream(in); + } + else + { + return new BufferedInputStream(in, bufferSize); + } + } + catch (IOException e) + { + throw new MessagingException("can't extract input stream: " + e); + } + } + + static Multipart getMultipart(MimeBodyPart bodyPart) + throws MessagingException, IOException + { + Object content = bodyPart.getContent(); + Multipart mp; + if (content instanceof Multipart) + { + mp = (Multipart)content; + } + else + { + mp = new MimeMultipart(bodyPart.getDataHandler().getDataSource()); + } + return mp; + } + + static LineOutputStream writeMultipartContentBodyPart(OutputStream out, MimeBodyPart bodyPart, String boundary) + throws MessagingException, IOException + { + + LineOutputStream lOut = new LineOutputStream(out); + + Enumeration headers = bodyPart.getAllHeaderLines(); + while (headers.hasMoreElements()) + { + lOut.writeln((String)headers.nextElement()); + } + + lOut.writeln(); // CRLF separator + + outputPreamble(lOut, bodyPart, boundary); + return lOut; + } + + static InputStream getInputStreamNoMultipartSigned( + Part bodyPart) + throws MessagingException + { + try + { + if (bodyPart.isMimeType("multipart/signed")) + { + throw new MessagingException("attempt to create signed data object from multipart content - use MimeMultipart constructor."); + } + + return bodyPart.getInputStream(); + } + catch (IOException e) + { + throw new MessagingException("can't extract input stream: " + e); + } + } + + static InputStream getInputStream( + Part bodyPart) + throws MessagingException + { + try + { + return bodyPart.getInputStream(); + } + catch (IOException e) + { + throw new MessagingException("can't extract input stream: " + e); + } + } + + static void messageSaveChanges(MimeMessage message) + throws SMIMEException + { + try + { + message.saveChanges(); // make sure we're up to date. + } + catch (MessagingException e) + { + throw new SMIMEException("unable to save message", e); + } + } } diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/examples/CreateSignedMail.java b/mail/src/main/java/org/bouncycastle/mail/smime/examples/CreateSignedMail.java index 1dcf44872a..eb41cfd335 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/examples/CreateSignedMail.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/examples/CreateSignedMail.java @@ -32,9 +32,9 @@ import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; +import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.bc.BcX509ExtensionUtils; import org.bouncycastle.cert.jcajce.JcaCertStore; @@ -62,7 +62,7 @@ static AuthorityKeyIdentifier createAuthorityKeyId( { SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(pub.getEncoded()); - return new AuthorityKeyIdentifier(info); + return new BcX509ExtensionUtils().createAuthorityKeyIdentifier(info); } static SubjectKeyIdentifier createSubjectKeyId( @@ -91,12 +91,12 @@ static X509Certificate makeCertificate( X509v3CertificateBuilder v3CertGen = new JcaX509v3CertificateBuilder(new X500Name(issDN), BigInteger.valueOf(serialNo++), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), new X500Name(subDN), subPub); v3CertGen.addExtension( - X509Extension.subjectKeyIdentifier, + Extension.subjectKeyIdentifier, false, createSubjectKeyId(subPub)); v3CertGen.addExtension( - X509Extension.authorityKeyIdentifier, + Extension.authorityKeyIdentifier, false, createAuthorityKeyId(issPub)); diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/examples/CreateSignedMultipartMail.java b/mail/src/main/java/org/bouncycastle/mail/smime/examples/CreateSignedMultipartMail.java index 20d1b3ea37..1befe30b32 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/examples/CreateSignedMultipartMail.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/examples/CreateSignedMultipartMail.java @@ -31,7 +31,7 @@ import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute; import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.X509Extension; +import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; @@ -71,12 +71,12 @@ static X509Certificate makeCertificate( X509v3CertificateBuilder v3CertGen = new JcaX509v3CertificateBuilder(new X500Name(issDN), BigInteger.valueOf(serialNo++), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), new X500Name(subDN), subPub); v3CertGen.addExtension( - X509Extension.subjectKeyIdentifier, + Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(subPub)); v3CertGen.addExtension( - X509Extension.authorityKeyIdentifier, + Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(issPub)); diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/examples/ValidateSignedMail.java b/mail/src/main/java/org/bouncycastle/mail/smime/examples/ValidateSignedMail.java index 996540927c..79b4b80f2c 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/examples/ValidateSignedMail.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/examples/ValidateSignedMail.java @@ -31,10 +31,10 @@ import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; import org.bouncycastle.cms.SignerInformation; -import org.bouncycastle.i18n.ErrorBundle; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.mail.smime.validator.SignedMailValidator; -import org.bouncycastle.x509.PKIXCertPathReviewer; +import org.bouncycastle.pkix.jcajce.PKIXCertPathReviewer; +import org.bouncycastle.pkix.util.ErrorBundle; /** * An Example that reads a signed mail and validates its signature. Also @@ -148,12 +148,14 @@ public static void verifySignedMail(MimeMessage msg, PKIXParameters param) { ErrorBundle errMsg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.sigValid"); + errMsg.setClassLoader(SignedMailValidator.class.getClassLoader()); System.out.println(errMsg.getText(loc)); } else { ErrorBundle errMsg = new ErrorBundle(RESOURCE_NAME, "SignedMailValidator.sigInvalid"); + errMsg.setClassLoader(SignedMailValidator.class.getClassLoader()); System.out.println(errMsg.getText(loc)); // print errors System.out.println("Errors:"); diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/handlers/HandlerUtil.java b/mail/src/main/java/org/bouncycastle/mail/smime/handlers/HandlerUtil.java new file mode 100644 index 0000000000..fa1bf41260 --- /dev/null +++ b/mail/src/main/java/org/bouncycastle/mail/smime/handlers/HandlerUtil.java @@ -0,0 +1,87 @@ +package org.bouncycastle.mail.smime.handlers; + +import java.awt.datatransfer.DataFlavor; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.activation.ActivationDataFlavor; +import javax.activation.DataContentHandler; +import javax.activation.DataSource; +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; + +import org.bouncycastle.mail.smime.SMIMEStreamingProcessor; + +class HandlerUtil +{ + + static void writeFromInputStream(InputStream obj, OutputStream os) + throws IOException + { + int b; + InputStream in = obj; + + if (!(in instanceof BufferedInputStream)) + { + in = new BufferedInputStream(in); + } + + while ((b = in.read()) >= 0) + { + os.write(b); + } + + in.close(); + } + + static void writeFromBarrInputStreamSMIMESTreamProcessor(Object obj, OutputStream os) + throws IOException + { + if(obj instanceof byte[]) + { + os.write((byte[])obj); + } + else if (obj instanceof InputStream) + { + writeFromInputStream((InputStream)obj, os); + } + else if (obj instanceof SMIMEStreamingProcessor) + { + SMIMEStreamingProcessor processor = (SMIMEStreamingProcessor)obj; + + processor.write(os); + } + else + { + throw new IOException("unknown object in writeTo " + obj); + } + } + + static void writeFromMimeBodyPart(MimeBodyPart obj, OutputStream os) + throws IOException + { + try + { + obj.writeTo(os); + } + catch (MessagingException ex) + { + throw new IOException(ex.getMessage()); + } + } + + static Object getTransferData(DataContentHandler handler, ActivationDataFlavor adf, DataFlavor df, DataSource ds) + throws IOException + { + if (adf.equals(df)) + { + return handler.getContent(ds); + } + else + { + return null; + } + } +} diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/handlers/PKCS7ContentHandler.java b/mail/src/main/java/org/bouncycastle/mail/smime/handlers/PKCS7ContentHandler.java index 471c4bd8fb..27e2104f4f 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/handlers/PKCS7ContentHandler.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/handlers/PKCS7ContentHandler.java @@ -1,19 +1,14 @@ package org.bouncycastle.mail.smime.handlers; import java.awt.datatransfer.DataFlavor; -import java.io.BufferedInputStream; import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; import javax.activation.ActivationDataFlavor; import javax.activation.DataContentHandler; import javax.activation.DataSource; -import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; -import org.bouncycastle.mail.smime.SMIMEStreamingProcessor; - public class PKCS7ContentHandler implements DataContentHandler { @@ -39,15 +34,8 @@ public Object getTransferData( DataFlavor df, DataSource ds) throws IOException - { - if (_adf.equals(df)) - { - return getContent(ds); - } - else - { - return null; - } + { + return HandlerUtil.getTransferData(this, _adf, df, ds); } public DataFlavor[] getTransferDataFlavors() @@ -63,50 +51,11 @@ public void writeTo( { if (obj instanceof MimeBodyPart) { - try - { - ((MimeBodyPart)obj).writeTo(os); - } - catch (MessagingException ex) - { - throw new IOException(ex.getMessage()); - } - } - else if (obj instanceof byte[]) - { - os.write((byte[])obj); - } - else if (obj instanceof InputStream) - { - int b; - InputStream in = (InputStream)obj; - - if (!(in instanceof BufferedInputStream)) - { - in = new BufferedInputStream(in); - } - - while ((b = in.read()) >= 0) - { - os.write(b); - } - - in.close(); - } - else if (obj instanceof SMIMEStreamingProcessor) - { - SMIMEStreamingProcessor processor = (SMIMEStreamingProcessor)obj; - - processor.write(os); + HandlerUtil.writeFromMimeBodyPart((MimeBodyPart)obj, os); } else { - // TODO it would be even nicer if we could attach the object to the exception - // as well since in deeply nested messages, it is not always clear which - // part caused the problem. Thus I guess we would have to subclass the - // IOException - - throw new IOException("unknown object in writeTo " + obj); + HandlerUtil.writeFromBarrInputStreamSMIMESTreamProcessor(obj, os); } } } diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/handlers/multipart_signed.java b/mail/src/main/java/org/bouncycastle/mail/smime/handlers/multipart_signed.java index 6070f25a4c..7fba22651c 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/handlers/multipart_signed.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/handlers/multipart_signed.java @@ -1,7 +1,6 @@ package org.bouncycastle.mail.smime.handlers; import java.awt.datatransfer.DataFlavor; -import java.io.BufferedInputStream; import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStream; @@ -17,17 +16,17 @@ import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMultipart; -import org.bouncycastle.mail.smime.SMIMEStreamingProcessor; import org.bouncycastle.mail.smime.SMIMEUtil; +import org.bouncycastle.util.Strings; -public class multipart_signed - implements DataContentHandler +public class multipart_signed + implements DataContentHandler { private static final ActivationDataFlavor ADF = new ActivationDataFlavor(MimeMultipart.class, "multipart/signed", "Multipart Signed"); - private static final DataFlavor[] DFS = new DataFlavor[] { ADF }; - - public Object getContent(DataSource ds) - throws IOException + private static final DataFlavor[] DFS = new DataFlavor[]{ADF}; + + public Object getContent(DataSource ds) + throws IOException { try { @@ -38,29 +37,22 @@ public Object getContent(DataSource ds) return null; } } - - public Object getTransferData(DataFlavor df, DataSource ds) - throws IOException - { - if (ADF.equals(df)) - { - return getContent(ds); - } - else - { - return null; - } + + public Object getTransferData(DataFlavor df, DataSource ds) + throws IOException + { + return HandlerUtil.getTransferData(this, ADF, df, ds); } - - public DataFlavor[] getTransferDataFlavors() + + public DataFlavor[] getTransferDataFlavors() { return DFS; } - - public void writeTo(Object obj, String _mimeType, OutputStream os) + + public void writeTo(Object obj, String _mimeType, OutputStream os) throws IOException { - + if (obj instanceof MimeMultipart) { try @@ -72,36 +64,9 @@ public void writeTo(Object obj, String _mimeType, OutputStream os) throw new IOException(ex.getMessage()); } } - else if(obj instanceof byte[]) - { - os.write((byte[])obj); - } - else if (obj instanceof InputStream) - { - int b; - InputStream in = (InputStream)obj; - - if (!(in instanceof BufferedInputStream)) - { - in = new BufferedInputStream(in); - } - - while ((b = in.read()) >= 0) - { - os.write(b); - } - - in.close(); - } - else if (obj instanceof SMIMEStreamingProcessor) - { - SMIMEStreamingProcessor processor = (SMIMEStreamingProcessor)obj; - - processor.write(os); - } else { - throw new IOException("unknown object in writeTo " + obj); + HandlerUtil.writeFromBarrInputStreamSMIMESTreamProcessor(obj, os); } } @@ -132,7 +97,7 @@ private void outputBodyPart( return; } - MimeBodyPart mimePart = (MimeBodyPart)bodyPart; + MimeBodyPart mimePart = (MimeBodyPart)bodyPart; if (SMIMEUtil.isMultipartContent(mimePart)) { @@ -227,7 +192,8 @@ private static String readLine(InputStream in) return b.toString(); } - private static class LineOutputStream extends FilterOutputStream + private static class LineOutputStream + extends FilterOutputStream { private static byte newline[]; @@ -241,11 +207,11 @@ public void writeln(String s) { try { - byte abyte0[] = getBytes(s); + byte abyte0[] = Strings.toUTF8ByteArray(s); super.out.write(abyte0); super.out.write(newline); } - catch(Exception exception) + catch (Exception exception) { throw new MessagingException("IOException", exception); } @@ -258,7 +224,7 @@ public void writeln() { super.out.write(newline); } - catch(Exception exception) + catch (Exception exception) { throw new MessagingException("IOException", exception); } @@ -270,20 +236,5 @@ public void writeln() newline[0] = 13; newline[1] = 10; } - - private static byte[] getBytes(String s) - { - char ac[] = s.toCharArray(); - int i = ac.length; - byte abyte0[] = new byte[i]; - int j = 0; - - while (j < i) - { - abyte0[j] = (byte)ac[j++]; - } - - return abyte0; - } } } diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/handlers/x_pkcs7_signature.java b/mail/src/main/java/org/bouncycastle/mail/smime/handlers/x_pkcs7_signature.java index a58fd53107..da8cb6c72f 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/handlers/x_pkcs7_signature.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/handlers/x_pkcs7_signature.java @@ -8,7 +8,6 @@ import javax.activation.ActivationDataFlavor; import javax.activation.DataContentHandler; import javax.activation.DataSource; -import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; public class x_pkcs7_signature @@ -38,15 +37,8 @@ public Object getContent(DataSource _ds) public Object getTransferData(DataFlavor _df, DataSource _ds) throws IOException - { - if (ADF.equals(_df)) - { - return getContent(_ds); - } - else - { - return null; - } + { + return HandlerUtil.getTransferData(this, ADF, _df, _ds); } public DataFlavor[] getTransferDataFlavors() @@ -59,14 +51,7 @@ public void writeTo(Object _obj, String _mimeType, OutputStream _os) { if (_obj instanceof MimeBodyPart) { - try - { - ((MimeBodyPart)_obj).writeTo(_os); - } - catch (MessagingException ex) - { - throw new IOException(ex.getMessage()); - } + HandlerUtil.writeFromMimeBodyPart((MimeBodyPart)_obj, _os); } else if (_obj instanceof byte[]) { @@ -74,13 +59,7 @@ else if (_obj instanceof byte[]) } else if (_obj instanceof InputStream) { - int b; - InputStream in = (InputStream)_obj; - - while ((b = in.read()) >= 0) - { - _os.write(b); - } + HandlerUtil.writeFromInputStream((InputStream)_obj, _os); } else { diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/validator/SignedMailValidator.java b/mail/src/main/java/org/bouncycastle/mail/smime/validator/SignedMailValidator.java index 98c20e46be..a6c99488de 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/validator/SignedMailValidator.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/validator/SignedMailValidator.java @@ -59,13 +59,13 @@ import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; -import org.bouncycastle.i18n.ErrorBundle; -import org.bouncycastle.i18n.filter.TrustedInput; -import org.bouncycastle.i18n.filter.UntrustedInput; import org.bouncycastle.mail.smime.SMIMESigned; +import org.bouncycastle.pkix.jcajce.CertPathReviewerException; +import org.bouncycastle.pkix.jcajce.PKIXCertPathReviewer; +import org.bouncycastle.pkix.util.ErrorBundle; +import org.bouncycastle.pkix.util.filter.TrustedInput; +import org.bouncycastle.pkix.util.filter.UntrustedInput; import org.bouncycastle.util.Integers; -import org.bouncycastle.x509.CertPathReviewerException; -import org.bouncycastle.x509.PKIXCertPathReviewer; public class SignedMailValidator { @@ -169,7 +169,7 @@ else if (message.isMimeType("application/pkcs7-mime") } else { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.noSignedMessage"); throw new SignedMailValidatorException(msg); } @@ -215,7 +215,7 @@ else if (message.isMimeType("application/pkcs7-mime") throw (SignedMailValidatorException)e; } // exception reading message - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.exceptionReadingMessage", new Object[]{e.getMessage(), e, e.getClass().getName()}); throw new SignedMailValidatorException(msg, e); @@ -258,7 +258,7 @@ protected void validateSignatures(PKIXParameters pkixParam) } catch (CertStoreException cse) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.exceptionRetrievingSignerCert", new Object[]{cse.getMessage(), cse, cse.getClass().getName()}); errors.add(msg); @@ -273,14 +273,14 @@ protected void validateSignatures(PKIXParameters pkixParam) validSignature = signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert.getPublicKey())); if (!validSignature) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.signatureNotVerified"); errors.add(msg); } } catch (Exception e) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.exceptionVerifyingSignature", new Object[]{e.getMessage(), e, e.getClass().getName()}); errors.add(msg); @@ -296,7 +296,7 @@ protected void validateSignatures(PKIXParameters pkixParam) Attribute attr = atab.get(PKCSObjectIdentifiers.id_aa_receiptRequest); if (attr != null) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.signedReceiptRequest"); notifications.add(msg); } @@ -309,7 +309,7 @@ protected void validateSignatures(PKIXParameters pkixParam) Date signTime = getSignatureTime(signer); if (signTime == null) // no signing time was found { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.noSigningTime"); notifications.add(msg); signTime = pkixParam.getDate(); @@ -327,14 +327,14 @@ protected void validateSignatures(PKIXParameters pkixParam) } catch (CertificateExpiredException e) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.certExpired", new Object[]{new TrustedInput(signTime), new TrustedInput(cert.getNotAfter())}); errors.add(msg); } catch (CertificateNotYetValidException e) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.certNotYetValid", new Object[]{new TrustedInput(signTime), new TrustedInput(cert.getNotBefore())}); errors.add(msg); @@ -373,7 +373,7 @@ protected void validateSignatures(PKIXParameters pkixParam) review.init(certPath, usedParameters); if (!review.isValidCertPath()) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.certPathInvalid"); errors.add(msg); } @@ -383,7 +383,7 @@ protected void validateSignatures(PKIXParameters pkixParam) catch (GeneralSecurityException gse) { // cannot create cert path - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.exceptionCreateCertPath", new Object[]{gse.getMessage(), gse, gse.getClass().getName()}); errors.add(msg); @@ -401,7 +401,7 @@ protected void validateSignatures(PKIXParameters pkixParam) else // no signer certificate found { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.noSignerCert"); errors.add(msg); results.put(signer, new ValidationResult(null, false, errors, @@ -478,7 +478,7 @@ else if (key instanceof DSAPublicKey) } if (keyLength != -1 && keyLength <= shortKeyLength) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.shortSigningKey", new Object[]{Integers.valueOf(keyLength)}); notifications.add(msg); @@ -488,7 +488,7 @@ else if (key instanceof DSAPublicKey) long validityPeriod = cert.getNotAfter().getTime() - cert.getNotBefore().getTime(); if (validityPeriod > THIRTY_YEARS_IN_MILLI_SEC) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.longValidity", new Object[]{new TrustedInput(cert.getNotBefore()), new TrustedInput(cert.getNotAfter())}); notifications.add(msg); @@ -498,7 +498,7 @@ else if (key instanceof DSAPublicKey) boolean[] keyUsage = cert.getKeyUsage(); if (keyUsage != null && !keyUsage[0] && !keyUsage[1]) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.signingNotPermitted"); errors.add(msg); } @@ -516,7 +516,7 @@ else if (key instanceof DSAPublicKey) && !extKeyUsage .hasKeyPurposeId(KeyPurposeId.id_kp_emailProtection)) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.extKeyUsageNotPermitted"); errors.add(msg); } @@ -524,7 +524,7 @@ else if (key instanceof DSAPublicKey) } catch (Exception e) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.extKeyUsageError", new Object[]{ e.getMessage(), e, e.getClass().getName()} ); @@ -538,7 +538,7 @@ else if (key instanceof DSAPublicKey) if (certEmails.isEmpty()) { // error no email address in signing certificate - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.noEmailInCert"); errors.add(msg); } @@ -557,7 +557,7 @@ else if (key instanceof DSAPublicKey) } if (!equalsFrom) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.emailFromCertMismatch", new Object[]{ new UntrustedInput( @@ -570,7 +570,7 @@ else if (key instanceof DSAPublicKey) } catch (Exception e) { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.certGetEmailError", new Object[]{ e.getMessage(), e, e.getClass().getName()} ); @@ -626,6 +626,14 @@ private static List findCerts(List certStores, X509CertSelector selector) { CertStore store = (CertStore)it.next(); Collection coll = store.getCertificates(selector); + // sometimes the subjectKeyIdentifier in a TA certificate, even when the authorityKeyIdentifier is set. + // where this happens we role back to a simpler match to make sure we've got all the possibilities. + if (coll.isEmpty() && selector.getSubjectKeyIdentifier() != null) + { + X509CertSelector certSelector = (X509CertSelector)selector.clone(); + certSelector.setSubjectKeyIdentifier(null); + coll = store.getCertificates(certSelector); + } result.addAll(coll); } return result; @@ -854,7 +862,7 @@ public ValidationResult getValidationResult(SignerInformation signer) { // the signer is not part of the SignerInformationStore // he has not signed the message - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, + ErrorBundle msg = createErrorBundle( "SignedMailValidator.wrongSigner"); throw new SignedMailValidatorException(msg); } @@ -961,10 +969,25 @@ public boolean isValidSignature() } } - private static TBSCertificate getTBSCert(X509Certificate cert) throws CertificateEncodingException { return TBSCertificate.getInstance(cert.getTBSCertificate()); } + + private static ErrorBundle createErrorBundle(String id) + { + ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, id); + msg.setClassLoader(SignedMailValidator.class.getClassLoader()); + + return msg; + } + + private static ErrorBundle createErrorBundle(String id, Object[] arguments) + { + ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, id, arguments); + msg.setClassLoader(SignedMailValidator.class.getClassLoader()); + + return msg; + } } diff --git a/mail/src/main/java/org/bouncycastle/mail/smime/validator/SignedMailValidatorException.java b/mail/src/main/java/org/bouncycastle/mail/smime/validator/SignedMailValidatorException.java index 06f1461828..696e4e6180 100644 --- a/mail/src/main/java/org/bouncycastle/mail/smime/validator/SignedMailValidatorException.java +++ b/mail/src/main/java/org/bouncycastle/mail/smime/validator/SignedMailValidatorException.java @@ -1,7 +1,7 @@ package org.bouncycastle.mail.smime.validator; -import org.bouncycastle.i18n.ErrorBundle; -import org.bouncycastle.i18n.LocalizedException; +import org.bouncycastle.pkix.util.ErrorBundle; +import org.bouncycastle.pkix.util.LocalizedException; public class SignedMailValidatorException extends LocalizedException { diff --git a/mail/src/test/java/org/bouncycastle/mail/smime/test/AllTests.java b/mail/src/test/java/org/bouncycastle/mail/smime/test/AllTests.java index 9a751b4083..65305772f1 100644 --- a/mail/src/test/java/org/bouncycastle/mail/smime/test/AllTests.java +++ b/mail/src/test/java/org/bouncycastle/mail/smime/test/AllTests.java @@ -53,6 +53,7 @@ public static Test suite() suite.addTestSuite(SMIMECompressedTest.class); suite.addTestSuite(SMIMEMiscTest.class); suite.addTestSuite(SMIMEToolkitTest.class); + suite.addTestSuite(MailGeneralTest.class); return new BCTestSetup(suite); } diff --git a/mail/src/test/java/org/bouncycastle/mail/smime/test/CMSTestUtil.java b/mail/src/test/java/org/bouncycastle/mail/smime/test/CMSTestUtil.java index 5e41b063b9..61950472a5 100644 --- a/mail/src/test/java/org/bouncycastle/mail/smime/test/CMSTestUtil.java +++ b/mail/src/test/java/org/bouncycastle/mail/smime/test/CMSTestUtil.java @@ -445,7 +445,7 @@ public static X509Certificate makeOaepCertificate(KeyPair subKP, String _subDN, return _cert; } - private static JcaContentSignerBuilder makeContentSignerBuilder(PublicKey issPub) + static JcaContentSignerBuilder makeContentSignerBuilder(PublicKey issPub) { JcaContentSignerBuilder contentSignerBuilder; if (issPub instanceof RSAPublicKey) @@ -498,7 +498,7 @@ public static X509CRL makeCrl(KeyPair pair) private static final X509ExtensionUtils extUtils = new X509ExtensionUtils(new SHA1DigestCalculator()); - private static AuthorityKeyIdentifier createAuthorityKeyId( + static AuthorityKeyIdentifier createAuthorityKeyId( PublicKey _pubKey) throws IOException { @@ -519,7 +519,7 @@ static SubjectKeyIdentifier createSubjectKeyId( return extUtils.createSubjectKeyIdentifier(SubjectPublicKeyInfo.getInstance(_pubKey.getEncoded())); } - private static BigInteger allocateSerialNumber() + static BigInteger allocateSerialNumber() { BigInteger _tmp = serialNumber; serialNumber = serialNumber.add(BigInteger.ONE); diff --git a/mail/src/test/java/org/bouncycastle/mail/smime/test/DummyCertPathReviewer.java b/mail/src/test/java/org/bouncycastle/mail/smime/test/DummyCertPathReviewer.java index 5229825d41..264665f9af 100644 --- a/mail/src/test/java/org/bouncycastle/mail/smime/test/DummyCertPathReviewer.java +++ b/mail/src/test/java/org/bouncycastle/mail/smime/test/DummyCertPathReviewer.java @@ -1,6 +1,6 @@ package org.bouncycastle.mail.smime.test; -import org.bouncycastle.x509.PKIXCertPathReviewer; +import org.bouncycastle.pkix.jcajce.PKIXCertPathReviewer; public class DummyCertPathReviewer extends PKIXCertPathReviewer { diff --git a/mail/src/test/java/org/bouncycastle/mail/smime/test/MailGeneralTest.java b/mail/src/test/java/org/bouncycastle/mail/smime/test/MailGeneralTest.java new file mode 100644 index 0000000000..82f853576a --- /dev/null +++ b/mail/src/test/java/org/bouncycastle/mail/smime/test/MailGeneralTest.java @@ -0,0 +1,1551 @@ +package org.bouncycastle.mail.smime.test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.security.KeyStore; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Security; +import java.security.cert.CertPath; +import java.security.cert.CertStore; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateFactory; +import java.security.cert.CollectionCertStoreParameters; +import java.security.cert.PKIXParameters; +import java.security.cert.TrustAnchor; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; + +import javax.crypto.Cipher; +import javax.mail.Address; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.InternetHeaders; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; + +import junit.framework.TestCase; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DERIA5String; +import org.bouncycastle.asn1.DERSet; +import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.DERUTF8String; +import org.bouncycastle.asn1.cms.Attribute; +import org.bouncycastle.asn1.cms.AttributeTable; +import org.bouncycastle.asn1.cms.CMSAttributes; +import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; +import org.bouncycastle.asn1.cms.Time; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; +import org.bouncycastle.asn1.smime.SMIMECapability; +import org.bouncycastle.asn1.smime.SMIMECapabilityVector; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralNames; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaCRLStore; +import org.bouncycastle.cert.jcajce.JcaCertStore; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.cms.CMSAlgorithm; +import org.bouncycastle.cms.CMSEnvelopedDataGenerator; +import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator; +import org.bouncycastle.cms.KeyTransRecipientId; +import org.bouncycastle.cms.RecipientId; +import org.bouncycastle.cms.RecipientInformation; +import org.bouncycastle.cms.RecipientInformationStore; +import org.bouncycastle.cms.SignerInfoGenerator; +import org.bouncycastle.cms.SignerInformation; +import org.bouncycastle.cms.SignerInformationStore; +import org.bouncycastle.cms.SignerInformationVerifier; +import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; +import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; +import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; +import org.bouncycastle.cms.jcajce.JceKeyAgreeEnvelopedRecipient; +import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientId; +import org.bouncycastle.cms.jcajce.JceKeyAgreeRecipientInfoGenerator; +import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; +import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId; +import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; +import org.bouncycastle.cms.jcajce.ZlibCompressor; +import org.bouncycastle.cms.jcajce.ZlibExpanderProvider; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.mail.smime.CMSProcessableBodyPart; +import org.bouncycastle.mail.smime.CMSProcessableBodyPartOutbound; +import org.bouncycastle.mail.smime.SMIMECompressed; +import org.bouncycastle.mail.smime.SMIMECompressedGenerator; +import org.bouncycastle.mail.smime.SMIMECompressedParser; +import org.bouncycastle.mail.smime.SMIMEEnveloped; +import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator; +import org.bouncycastle.mail.smime.SMIMEEnvelopedParser; +import org.bouncycastle.mail.smime.SMIMEException; +import org.bouncycastle.mail.smime.SMIMESigned; +import org.bouncycastle.mail.smime.SMIMESignedGenerator; +import org.bouncycastle.mail.smime.SMIMESignedParser; +import org.bouncycastle.mail.smime.SMIMEToolkit; +import org.bouncycastle.mail.smime.SMIMEUtil; +import org.bouncycastle.mail.smime.examples.CreateCompressedMail; +import org.bouncycastle.mail.smime.examples.CreateEncryptedMail; +import org.bouncycastle.mail.smime.examples.CreateLargeCompressedMail; +import org.bouncycastle.mail.smime.examples.CreateLargeEncryptedMail; +import org.bouncycastle.mail.smime.examples.CreateLargeSignedMail; +import org.bouncycastle.mail.smime.examples.CreateSignedMail; +import org.bouncycastle.mail.smime.examples.CreateSignedMultipartMail; +import org.bouncycastle.mail.smime.examples.ReadCompressedMail; +import org.bouncycastle.mail.smime.examples.ReadEncryptedMail; +import org.bouncycastle.mail.smime.examples.ReadLargeCompressedMail; +import org.bouncycastle.mail.smime.examples.ReadLargeEncryptedMail; +import org.bouncycastle.mail.smime.examples.ReadLargeSignedMail; +import org.bouncycastle.mail.smime.examples.ReadSignedMail; +import org.bouncycastle.mail.smime.examples.SendSignedAndEncryptedMail; +import org.bouncycastle.mail.smime.examples.ValidateSignedMail; +import org.bouncycastle.mail.smime.util.CRLFOutputStream; +import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart; +import org.bouncycastle.mail.smime.validator.SignedMailValidator; +import org.bouncycastle.openssl.PEMKeyPair; +import org.bouncycastle.openssl.PEMParser; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; +import org.bouncycastle.util.Store; + +public class MailGeneralTest + extends TestCase +{ + public static void main(String[] args) + throws Exception + { + MailGeneralTest test = new MailGeneralTest(); + test.setUp(); + test.testSignedMessageVerificationMultipart(); + test.testExamples(); + test.testParser(); + test.testCompressedSHA1WithRSA(); + test.testSelfSignedCert(); + test.testSHA1WithRSAEncapsulatedParser(); + test.testSHA1WithRSA(); + test.testDESEDE3Encrypted(); + test.testParserDESEDE3Encrypted(); + test.testIDEAEncrypted(); + test.testRC2Encrypted(); + test.testCASTEncrypted(); + test.testAES128Encrypted(); + test.testAES192Encrypted(); + test.testAES256Encrypted(); + test.testSubKeyId(); + test.testDotNetEncMailMatch(); + test.testAES128(); + test.testAES192(); + test.testAES256(); + test.testCapEncrypt(); + test.testTwoRecipients(); + test.testKDFAgreements(); + } + + private static final String BC = BouncyCastleProvider.PROVIDER_NAME; + + static MimeBodyPart msg; + private static String _signDN; + private static KeyPair _signKP; + static String _origDN; + static KeyPair _origKP; + private static String _reciDN; + private static KeyPair _reciKP; + private static X509Certificate _reciCert; + static X509Certificate _origCert; + + private static String _reciDN2; + private static KeyPair _reciKP2; + private static X509Certificate _reciCert2; + + private static KeyPair _origEcKP; + private static KeyPair _reciEcKP; + private static X509Certificate _reciEcCert; + private static KeyPair _reciEcKP2; + private static X509Certificate _reciEcCert2; + static X509Certificate _signCert; + + private static boolean _initialised = false; + + protected interface TestExceptionOperation + { + void operation() + throws Exception; + } + + protected Exception testException(String failMessage, String exceptionClass, TestExceptionOperation operation) + { + try + { + operation.operation(); + fail(failMessage); + } + catch (Exception e) + { + if (failMessage != null) + { + assertTrue(e.getMessage(), e.getMessage().contains(failMessage)); + } + assertTrue(e.getClass().getName().contains(exceptionClass)); + return e; + } + return null; + } + + public void setUp() + throws Exception + { + if (!_initialised) + { + if (Security.getProvider("BC") == null) + { + Security.addProvider(new BouncyCastleProvider()); + } + + _initialised = true; + + msg = SMIMETestUtil.makeMimeBodyPart("Hello world!\n"); + + _signDN = "O=Bouncy Castle, C=AU"; + _signKP = CMSTestUtil.makeKeyPair(); + + _origDN = "O=Bouncy Castle, C=AU"; + _origKP = CMSTestUtil.makeKeyPair(); + _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _origKP, _origDN); + + _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; + _reciKP = CMSTestUtil.makeKeyPair(); + _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _origKP, _origDN); + + _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); + + _reciDN2 = "CN=Fred, OU=Sales, O=Bouncy Castle, C=AU"; + _reciKP2 = CMSTestUtil.makeKeyPair(); + _reciCert2 = CMSTestUtil.makeCertificate(_reciKP2, _reciDN2, _signKP, _signDN); + + _origEcKP = CMSTestUtil.makeEcDsaKeyPair(); + _reciEcKP = CMSTestUtil.makeEcDsaKeyPair(); + _reciEcCert = CMSTestUtil.makeCertificate(_reciEcKP, _reciDN, _signKP, _signDN); + _reciEcKP2 = CMSTestUtil.makeEcDsaKeyPair(); + _reciEcCert2 = CMSTestUtil.makeCertificate(_reciEcKP2, _reciDN2, _signKP, _signDN); + } + } + + private MimeMessage loadMessage(String name) + throws MessagingException, FileNotFoundException + { + Session session = Session.getDefaultInstance(System.getProperties(), null); + + return new MimeMessage(session, getClass().getResourceAsStream(name)); + } + + private X509Certificate loadCert(String name) + throws Exception + { + return (X509Certificate)CertificateFactory.getInstance("X.509", BC).generateCertificate(getClass().getResourceAsStream(name)); + } + + private PrivateKey loadKey(String name) + throws Exception + { + return new JcaPEMKeyConverter().setProvider("BC").getKeyPair((PEMKeyPair)(new PEMParser(new InputStreamReader(getClass().getResourceAsStream(name)))).readObject()).getPrivate(); + } + + public void testHeaders() + throws Exception + { + MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); + + SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); + gen.setBerEncodeRecipients(true); + gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); + + // + // generate a MimeBodyPart object which encapsulates the content + // we want encrypted. + // + + MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); + + assertEquals("application/pkcs7-mime; name=\"smime.p7m\"; smime-type=enveloped-data", mp.getHeader("Content-Type")[0]); + assertEquals("attachment; filename=\"smime.p7m\"", mp.getHeader("Content-Disposition")[0]); + assertEquals("S/MIME Encrypted Message", mp.getHeader("Content-Description")[0]); + } + + public void testDESEDE3Encrypted() + throws Exception + { + MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); + String algorithm = SMIMEEnvelopedGenerator.DES_EDE3_CBC; + + verifyAlgorithm(algorithm, msg); + } + + public void testParserDESEDE3Encrypted() + throws Exception + { + MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); + String algorithm = SMIMEEnvelopedGenerator.DES_EDE3_CBC; + + verifyParserAlgorithm(algorithm, msg); + } + + public void testIDEAEncrypted() + throws Exception + { + if (isPresent("IDEA")) + { + MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); + String algorithm = SMIMEEnvelopedGenerator.IDEA_CBC; + + verifyAlgorithm(algorithm, msg); + } + } + + private boolean isPresent(String algorithm) + throws Exception + { + try + { + Cipher.getInstance(algorithm, BC); + + return true; + } + catch (NoSuchAlgorithmException e) + { + return false; + } + } + + public void testRC2Encrypted() + throws Exception + { + MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); + String algorithm = SMIMEEnvelopedGenerator.RC2_CBC; + + verifyAlgorithm(algorithm, msg); + } + + public void testCASTEncrypted() + throws Exception + { + MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); + String algorithm = SMIMEEnvelopedGenerator.CAST5_CBC; + + verifyAlgorithm(algorithm, msg); + } + + public void testAES128Encrypted() + throws Exception + { + MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); + String algorithm = SMIMEEnvelopedGenerator.AES128_CBC; + + verifyAlgorithm(algorithm, msg); + } + + public void testAES192Encrypted() + throws Exception + { + MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); + String algorithm = SMIMEEnvelopedGenerator.AES192_CBC; + + verifyAlgorithm(algorithm, msg); + } + + public void testAES256Encrypted() + throws Exception + { + MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); + String algorithm = SMIMEEnvelopedGenerator.AES256_CBC; + + verifyAlgorithm(algorithm, msg); + } + + public void testSubKeyId() + throws Exception + { + MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); + + SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); + + // + // create a subject key id - this has to be done the same way as + // it is done in the certificate associated with the private key + // + MessageDigest dig = MessageDigest.getInstance("SHA1", BC); + dig.update(SubjectPublicKeyInfo.getInstance(_reciCert.getPublicKey().getEncoded()).getPublicKeyData().getBytes()); + + + gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(dig.digest(), _reciCert.getPublicKey()).setProvider(BC)); + + // + // generate a MimeBodyPart object which encapsulates the content + // we want encrypted. + // + + MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); + + SMIMEEnveloped m = new SMIMEEnveloped(mp); + + dig.update(SubjectPublicKeyInfo.getInstance(_reciCert.getPublicKey().getEncoded()).getPublicKeyData().getBytes()); + + RecipientId recId = new KeyTransRecipientId(dig.digest()); + + RecipientInformationStore recipients = m.getRecipientInfos(); + RecipientInformation recipient = recipients.get(recId); + + MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC))); + + SMIMETestUtil.verifyMessageBytes(msg, res); + } + + public void testDotNetEncMailMatch() + throws Exception + { + MimeMessage message = loadMessage("dotnet_encrypted_mail.eml"); + + SMIMEEnveloped env = new SMIMEEnveloped(message); + + RecipientInformationStore store = env.getRecipientInfos(); + + assertNotNull(store.get(new JceKeyTransRecipientId(loadCert("dotnet_enc_cert.pem")))); + } + + public void testAES128() + throws Exception + { + MimeMessage message = loadMessage("test128.message"); + + SMIMEEnveloped env = new SMIMEEnveloped(message); + + RecipientInformationStore store = env.getRecipientInfos(); + + RecipientInformation recipInfo = store.get(new JceKeyTransRecipientId(loadCert("cert.pem"))); + + assertNotNull(recipInfo); + + byte[] content = recipInfo.getContent(new JceKeyTransEnvelopedRecipient(loadKey("key.pem"))); + + assertTrue(org.bouncycastle.util.Arrays.areEqual(NewSMIMEEnvelopedTest.testMessage, content)); + } + + public void testAES192() + throws Exception + { + MimeMessage message = loadMessage("test192.message"); + + SMIMEEnveloped env = new SMIMEEnveloped(message); + + RecipientInformationStore store = env.getRecipientInfos(); + + RecipientInformation recipInfo = store.get(new JceKeyTransRecipientId(loadCert("cert.pem"))); + + assertNotNull(recipInfo); + + byte[] content = recipInfo.getContent(new JceKeyTransEnvelopedRecipient(loadKey("key.pem"))); + + assertTrue(org.bouncycastle.util.Arrays.areEqual(NewSMIMEEnvelopedTest.testMessage, content)); + } + + public void testAES256() + throws Exception + { + MimeMessage message = loadMessage("test256.message"); + + SMIMEEnveloped env = new SMIMEEnveloped(message); + + RecipientInformationStore store = env.getRecipientInfos(); + + RecipientInformation recipInfo = store.get(new JceKeyTransRecipientId(loadCert("cert.pem"))); + + assertNotNull(recipInfo); + + byte[] content = recipInfo.getContent(new JceKeyTransEnvelopedRecipient(loadKey("key.pem"))); + + assertTrue(org.bouncycastle.util.Arrays.areEqual(NewSMIMEEnvelopedTest.testMessage, content)); + } + + public void testCapEncrypt() + throws Exception + { + MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); + + SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); + + // + // create a subject key id - this has to be done the same way as + // it is done in the certificate associated with the private key + // + MessageDigest dig = MessageDigest.getInstance("SHA1", BC); + + dig.update(_reciCert.getPublicKey().getEncoded()); + + gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(dig.digest(), _reciCert.getPublicKey()).setProvider(BC)); + + // + // generate a MimeBodyPart object which encapsulates the content + // we want encrypted. + // + MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC, 40).setProvider(BC).build()); + + SMIMEEnveloped m = new SMIMEEnveloped(mp); + + dig.update(_reciCert.getPublicKey().getEncoded()); + + RecipientId recId = new KeyTransRecipientId(dig.digest()); + + RecipientInformationStore recipients = m.getRecipientInfos(); + RecipientInformation recipient = recipients.get(recId); + + MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC))); + + SMIMETestUtil.verifyMessageBytes(msg, res); + } + + public void testTwoRecipients() + throws Exception + { + MimeBodyPart _msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); + + SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); + + gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); + gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert2).setProvider(BC)); + + // + // generate a MimeBodyPart object which encapsulates the content + // we want encrypted. + // + MimeBodyPart mp = gen.generate(_msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC, 40).setProvider(BC).build()); + + SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(mp); + assertNotNull(m.getEncryptedContent()); + RecipientId recId = getRecipientId(_reciCert2); + + RecipientInformationStore recipients = m.getRecipientInfos(); + RecipientInformation recipient = recipients.get(recId); + + FileBackedMimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContentStream(new JceKeyTransEnvelopedRecipient(_reciKP2.getPrivate()).setProvider(BC))); + + SMIMETestUtil.verifyMessageBytes(_msg, res); + + m = new SMIMEEnvelopedParser(mp); + + res.dispose(); + + recId = getRecipientId(_reciCert); + + recipients = m.getRecipientInfos(); + recipient = recipients.get(recId); + + res = SMIMEUtil.toMimeBodyPart(recipient.getContentStream(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC))); + + SMIMETestUtil.verifyMessageBytes(_msg, res); + + res.dispose(); + } + + private void verifyAlgorithm( + String algorithmOid, + MimeBodyPart msg) + throws Exception + { + SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); + + gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); + + // + // generate a MimeBodyPart object which encapsulates the content + // we want encrypted. + // + + MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(algorithmOid)).setProvider(BC).build()); + SMIMEEnveloped m = new SMIMEEnveloped(mp); + RecipientId recId = getRecipientId(_reciCert); + + RecipientInformationStore recipients = m.getRecipientInfos(); + RecipientInformation recipient = recipients.get(recId); + + MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC))); + + SMIMETestUtil.verifyMessageBytes(msg, res); + } + + private void verifyParserAlgorithm( + String algorithmOid, + MimeBodyPart msg) + throws Exception + { + SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); + + gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); + + // + // generate a MimeBodyPart object which encapsulates the content + // we want encrypted. + // + + MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(algorithmOid)).setProvider(BC).build()); + SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(mp); + RecipientId recId = getRecipientId(_reciCert); + + RecipientInformationStore recipients = m.getRecipientInfos(); + RecipientInformation recipient = recipients.get(recId); + + MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC))); + + SMIMETestUtil.verifyMessageBytes(msg, res); + } + + private RecipientId getRecipientId( + X509Certificate cert) + throws IOException, CertificateEncodingException + { + RecipientId recId = new JceKeyTransRecipientId(cert); + + return recId; + } + + public void testKDFAgreements() + throws Exception + { + MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington"); + + doTryAgreement(msg, CMSAlgorithm.ECDH_SHA1KDF, true); + doTryAgreement(msg, CMSAlgorithm.ECDH_SHA224KDF, true); + doTryAgreement(msg, CMSAlgorithm.ECDH_SHA256KDF, true); + doTryAgreement(msg, CMSAlgorithm.ECDH_SHA384KDF, true); + doTryAgreement(msg, CMSAlgorithm.ECDH_SHA512KDF, true); + + doTryAgreement(msg, CMSAlgorithm.ECCDH_SHA1KDF, true); + doTryAgreement(msg, CMSAlgorithm.ECCDH_SHA224KDF, true); + doTryAgreement(msg, CMSAlgorithm.ECCDH_SHA256KDF, true); + doTryAgreement(msg, CMSAlgorithm.ECCDH_SHA384KDF, true); + doTryAgreement(msg, CMSAlgorithm.ECCDH_SHA512KDF, true); + + doTryAgreement(msg, CMSAlgorithm.ECMQV_SHA1KDF, true); + doTryAgreement(msg, CMSAlgorithm.ECMQV_SHA224KDF, true); + doTryAgreement(msg, CMSAlgorithm.ECMQV_SHA256KDF, true); + doTryAgreement(msg, CMSAlgorithm.ECMQV_SHA384KDF, true); + doTryAgreement(msg, CMSAlgorithm.ECMQV_SHA512KDF, true); + + doTryAgreement(msg, CMSAlgorithm.ECDH_SHA1KDF, false); + doTryAgreement(msg, CMSAlgorithm.ECDH_SHA224KDF, false); + doTryAgreement(msg, CMSAlgorithm.ECDH_SHA256KDF, false); + doTryAgreement(msg, CMSAlgorithm.ECDH_SHA384KDF, false); + doTryAgreement(msg, CMSAlgorithm.ECDH_SHA512KDF, false); + + doTryAgreement(msg, CMSAlgorithm.ECCDH_SHA1KDF, false); + doTryAgreement(msg, CMSAlgorithm.ECCDH_SHA224KDF, false); + doTryAgreement(msg, CMSAlgorithm.ECCDH_SHA256KDF, false); + doTryAgreement(msg, CMSAlgorithm.ECCDH_SHA384KDF, false); + doTryAgreement(msg, CMSAlgorithm.ECCDH_SHA512KDF, false); + + doTryAgreement(msg, CMSAlgorithm.ECMQV_SHA1KDF, false); + doTryAgreement(msg, CMSAlgorithm.ECMQV_SHA224KDF, false); + doTryAgreement(msg, CMSAlgorithm.ECMQV_SHA256KDF, false); + doTryAgreement(msg, CMSAlgorithm.ECMQV_SHA384KDF, false); + doTryAgreement(msg, CMSAlgorithm.ECMQV_SHA512KDF, false); + } + + private void doTryAgreement(MimeBodyPart data, ASN1ObjectIdentifier algorithm, boolean berEncodeRecipientSet) + throws Exception + { + SMIMEEnvelopedGenerator edGen = new SMIMEEnvelopedGenerator(); + + edGen.addRecipientInfoGenerator(new JceKeyAgreeRecipientInfoGenerator(algorithm, + _origEcKP.getPrivate(), _origEcKP.getPublic(), + CMSAlgorithm.AES128_WRAP).addRecipient(_reciEcCert).setProvider(BC)); + edGen.setBerEncodeRecipients(berEncodeRecipientSet); + MimeBodyPart res = edGen.generate( + data, + new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); + + SMIMEEnveloped ed = new SMIMEEnveloped(res); + + assertNotNull(ed.getEncryptedContent()); + + assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); + + RecipientInformationStore recipients = ed.getRecipientInfos(); + + IssuerAndSerialNumber issuerAndSerialNumber = SMIMEUtil.createIssuerAndSerialNumberFor(_reciCert); + assertEquals(_reciCert.getSerialNumber(), issuerAndSerialNumber.getSerialNumber().getValue()); + assertEquals(new X500Name(_signDN), issuerAndSerialNumber.getName()); + confirmDataReceived(recipients, data, _reciEcCert, _reciEcKP.getPrivate(), BC); + confirmNumberRecipients(recipients, 1); + } + + private static void confirmDataReceived(RecipientInformationStore recipients, + MimeBodyPart expectedData, X509Certificate reciCert, PrivateKey reciPrivKey, String provider) + throws Exception + { + RecipientId rid = new JceKeyAgreeRecipientId(reciCert); + + RecipientInformation recipient = recipients.get(rid); + assertNotNull(recipient); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + expectedData.writeTo(bOut); + + byte[] actualData = recipient.getContent(new JceKeyAgreeEnvelopedRecipient(reciPrivKey).setProvider(provider)); + assertEquals(true, Arrays.equals(bOut.toByteArray(), actualData)); + } + + private static void confirmNumberRecipients(RecipientInformationStore recipients, int count) + { + assertEquals(count, recipients.getRecipients().size()); + } + + public void testSHA1WithRSA() + throws Exception + { + MimeMultipart smm = generateMultiPartRsa("SHA1withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); + SMIMESigned s = new SMIMESigned(smm); + Session session = Session.getDefaultInstance(System.getProperties(), null); + MimeMessage message = s.getContentAsMimeMessage(session); + assertEquals(message.getContent(), msg.getContent()); + assertEquals(((MimeMultipart)s.getContentWithSignature()).getBodyPart(0).getContent(), msg.getContent()); + verifyMessageBytes(msg, s.getContent()); + + verifySigners(s.getCertificates(), s.getSignerInfos()); + + CMSProcessableBodyPartOutbound pbpo = new CMSProcessableBodyPartOutbound(smm.getBodyPart(0)); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + pbpo.write(bOut); + assertEquals("Hello world!\r\n", new MimeBodyPart(new ByteArrayInputStream(bOut.toByteArray())).getContent()); + assertEquals("Hello world!\n", ((MimeBodyPart)pbpo.getContent()).getContent()); + + CMSProcessableBodyPart pbp = new CMSProcessableBodyPart(smm.getBodyPart(0)); + + bOut = new ByteArrayOutputStream(); + pbp.write(bOut); + assertEquals("Hello world!\n", new MimeBodyPart(new ByteArrayInputStream(bOut.toByteArray())).getContent()); + assertEquals("Hello world!\n", ((MimeBodyPart)pbp.getContent()).getContent()); + + pbpo = new CMSProcessableBodyPartOutbound(smm.getBodyPart(0), "binary"); + bOut = new ByteArrayOutputStream(); + CRLFOutputStream cOut = new CRLFOutputStream(bOut); + pbpo.write(cOut); + assertEquals("Hello world!\r\n", new MimeBodyPart(new ByteArrayInputStream(bOut.toByteArray())).getContent()); + assertEquals("Hello world!\n", ((MimeBodyPart)pbpo.getContent()).getContent()); + + final MimeBodyPart sig = new MimeBodyPart(); + + sig.setContent(new byte[100], "application/pkcs7-signature; name=smime.p7s; smime-type=signed-data"); + sig.addHeader("Content-Type", "application/pkcs7-signature; name=smime.p7s; smime-type=signed-data"); + sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7s\""); + sig.addHeader("Content-Description", "S/MIME Cryptographic Signature"); + sig.addHeader("Content-Transfer-Encoding", "base64"); + StringBuffer header = new StringBuffer("signed; protocol=\"application/pkcs7-signature\""); + + List allSigners = new ArrayList(); + + + allSigners.add(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC) + .setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator()).build("SHA1withRSA", _signKP.getPrivate(), _signCert)); + + addHashHeader(header, allSigners); + + final MimeMultipart mm = new MimeMultipart(header.toString()); + MimeBodyPart part1 = createTemplate("text/html", "7bit"); + MimeBodyPart part2 = createTemplate("text/xml", "7bit"); + mm.addBodyPart(part1); + mm.addBodyPart(part2); + + final MimeMessage mimeMessage = makeMimeMessage(mm); + final SMIMEToolkit toolkit = new SMIMEToolkit(new BcDigestCalculatorProvider()); + final SignerInformationVerifier singerInformation = new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(_signCert); + testException("CMS processing failure:", "SMIMEException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + toolkit.isValidSignature(mm, singerInformation); + } + }); + + testException("CMS processing failure:", "SMIMEException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + toolkit.isValidSignature(mimeMessage, singerInformation); + } + }); + + MimeBodyPart res = generateEncapsulated(); + + SMIMESigned smimeSigned = new SMIMESigned(res); + + final SignerInformation signerInformation = (SignerInformation)smimeSigned.getSignerInfos().getSigners().iterator().next(); + testException("CMS processing failure:", "SMIMEException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + toolkit.extractCertificate(mm, signerInformation); + } + }); + + testException("CMS processing failure:", "SMIMEException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + toolkit.extractCertificate(mimeMessage, signerInformation); + } + }); + + testException("CMS processing failure:", "SMIMEException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + toolkit.decrypt(mimeMessage, new JceKeyTransRecipientId(_reciCert), new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); + } + }); + + testException("CMS processing failure:", "SMIMEException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + toolkit.decrypt(sig, new JceKeyTransRecipientId(_reciCert), new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); + } + }); + + + +// s = new SMIMESigned(mm); +// +// s.getContentAsMimeMessage(session); +// s.getContent(); + } + + private MimeBodyPart createTemplate(String contentType, String contentTransferEncoding) + throws UnsupportedEncodingException, MessagingException + { + byte[] content = "\n\n \n\n\n".getBytes("US-ASCII"); + + InternetHeaders ih = new InternetHeaders(); + ih.setHeader("Content-Type", contentType); + ih.setHeader("Content-Transfer-Encoding", contentTransferEncoding); + + return new MimeBodyPart(ih, content); + } + + private MimeMultipart generateMultiPartRsa(String algorithm, MimeBodyPart msg, Map micalgs) + throws Exception + { + return generateMultiPartRsa(algorithm, msg, null, micalgs); + } + + private MimeMultipart generateMultiPartRsa( + String algorithm, + MimeBodyPart msg, + Date signingTime, + Map micalgs) + throws Exception + { + List certList = new ArrayList(); + + certList.add(_signCert); + certList.add(_origCert); + + Store certs = new JcaCertStore(certList); + + Store crls = new JcaCRLStore(new ArrayList()); + + ASN1EncodableVector signedAttrs = generateSignedAttributes(); + + if (signingTime != null) + { + signedAttrs.add(new Attribute(CMSAttributes.signingTime, new DERSet(new Time(signingTime)))); + signedAttrs.add(new Attribute(PKCSObjectIdentifiers.id_aa_receiptRequest, new DERSet(new DERUTF8String("Request")))); + } + + SMIMESignedGenerator gen = new SMIMESignedGenerator(micalgs); + + gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC) + .setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(signedAttrs))).build(algorithm, _signKP.getPrivate(), _signCert)); + gen.addCertificates(certs); + gen.addCRLs(crls); + + MimeBodyPart mimeBodyPart = gen.generateEncapsulated(msg); + assertNotNull(mimeBodyPart.getContent()); + + return gen.generate(msg); + } + + private void verifyMessageBytes(MimeBodyPart a, MimeBodyPart b) + throws Exception + { + ByteArrayOutputStream bOut1 = new ByteArrayOutputStream(); + + a.writeTo(bOut1); + bOut1.close(); + + ByteArrayOutputStream bOut2 = new ByteArrayOutputStream(); + + b.writeTo(bOut2); + bOut2.close(); + + assertEquals(true, Arrays.equals(bOut1.toByteArray(), bOut2.toByteArray())); + } + + private void verifySigners(Store certs, SignerInformationStore signers) + throws Exception + { + Collection c = signers.getSigners(); + Iterator it = c.iterator(); + + while (it.hasNext()) + { + SignerInformation signer = (SignerInformation)it.next(); + Collection certCollection = certs.getMatches(signer.getSID()); + + Iterator certIt = certCollection.iterator(); + X509CertificateHolder certHolder = (X509CertificateHolder)certIt.next(); + + assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(certHolder))); + } + } + + private ASN1EncodableVector generateSignedAttributes() + { + ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); + SMIMECapabilityVector caps = new SMIMECapabilityVector(); + + caps.addCapability(SMIMECapability.dES_EDE3_CBC); + caps.addCapability(SMIMECapability.rC2_CBC, 128); + caps.addCapability(SMIMECapability.dES_CBC); + + signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); + + return signedAttrs; + } + + public void testSHA1WithRSAEncapsulatedParser() + throws Exception + { + testException("attempt to create signed data object from multipart content - use MimeMultipart constructor.", "MessagingException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), loadMessage("qp-soft-break.eml")); + } + }); + + testException("attempt to create signed data object from multipart content - use MimeMultipart constructor.", "MessagingException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new SMIMESigned(loadMessage("qp-soft-break.eml")); + } + }); + + MimeBodyPart res = generateEncapsulatedRsa("SHA1withRSA", msg); + SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(), res); + assertNotNull(s.getContentWithSignature()); + FileBackedMimeBodyPart content = (FileBackedMimeBodyPart)s.getContent(); + + verifyMessageBytes(msg, content); + + content.dispose(); + + verifySigners(s.getCertificates(), s.getSignerInfos()); + + s.close(); + } + + private MimeBodyPart generateEncapsulatedRsa(String sigAlg, MimeBodyPart msg) + throws Exception + { + List certList = new ArrayList(); + + certList.add(_signCert); + certList.add(_origCert); + + Store certs = new JcaCertStore(certList); + + ASN1EncodableVector signedAttrs = generateSignedAttributes(); + + SMIMESignedGenerator gen = new SMIMESignedGenerator(); + + gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build(sigAlg, _signKP.getPrivate(), _signCert)); + gen.addCertificates(certs); + + return gen.generateEncapsulated(msg); + } + + public void testSelfSignedCert() + throws Exception + { + String signDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; + KeyPair signKP = CMSTestUtil.makeDsaKeyPair(); + ArrayList altnames = new ArrayList(); + altnames.add("test@bouncycastle.org"); + X509Certificate signCert = makeCertificate(signKP, signDN, signKP, signDN, false, "test@bouncycastle.org"); + + // check basic path validation + Set trustanchors = new HashSet(); + TrustAnchor ta = new TrustAnchor(signCert, null); + trustanchors.add(ta); + + X509Certificate rootCert = ta.getTrustedCert(); + + // init cert stores + List certStores = new ArrayList(); + List certList = new ArrayList(); + certList.add(rootCert); + CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList)); + certStores.add(store); + + // first path + CertPath path = SignedMailValidator.createCertPath(rootCert, trustanchors, certStores); + + assertTrue("path size is not 1", path.getCertificates().size() == 1); + + // check message validation + certList = new ArrayList(); + + certList.add(signCert); + + Store certs = new JcaCertStore(certList); + + Properties props = System.getProperties(); + final Session session = Session.getDefaultInstance(props, null); + + + Address fromUser = new InternetAddress("\"Eric H. Echidna\""); + Address toUser = new InternetAddress("example@bouncycastle.org"); + + final PKIXParameters params = new PKIXParameters(trustanchors); + params.setRevocationEnabled(false); + + MimeMessage message = loadMessage("dotnet_encrypted_mail.eml"); + + SMIMEEnveloped env = new SMIMEEnveloped(message); + + RecipientInformationStore ristore = env.getRecipientInfos(); + + assertNotNull(ristore.get(new JceKeyTransRecipientId(loadCert("dotnet_enc_cert.pem")))); + final MimeMessage msg = new MimeMessage(session); + + // Create a MimeMessage + MimeMessage mimeMessage = new MimeMessage(session); + + // Set the content type to "application/pkcs7-mime" + mimeMessage.setHeader("Content-Type", "application/pkcs7-mime"); + + // Set other necessary properties and content for the MimeMessage + mimeMessage.setSubject("Your Subject"); + mimeMessage.setFrom(new InternetAddress("sender@example.com")); + mimeMessage.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress("recipient@example.com")); + mimeMessage.setText("Your message content"); + msg.setFrom(fromUser); + msg.setRecipient(Message.RecipientType.TO, toUser); + + final SMIMESignedGenerator gen = new SMIMESignedGenerator(); + ASN1EncodableVector signedAttrs = generateSignedAttributes(); + + signedAttrs.add(new Attribute(PKCSObjectIdentifiers.id_aa_receiptRequest, new DERSet(new DERUTF8String("Request")))); + + assertNotNull(gen.generate(mimeMessage)); + testException("exception getting message content.", "SMIMEException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + gen.generateEncapsulated(new MimeMessage(session)); + } + }); + + gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC") + .setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(signedAttrs))).build("SHA1withDSA", signKP.getPrivate(), signCert)); + gen.addCertificates(certs); + + MimeMultipart signedMsg = gen.generate(mimeMessage); + msg.setContent(signedMsg, signedMsg.getContentType()); + + msg.setHeader("Sender", "sender@bouncycastle.org"); + msg.saveChanges(); + SignedMailValidator validator = new SignedMailValidator(msg, params); + SignerInformation signer = (SignerInformation)validator + .getSignerInformationStore().getSigners().iterator().next(); + + assertEquals(1, validator.getCertsAndCRLs().getCertificates(null).size()); + assertEquals(0, validator.getCertsAndCRLs().getCRLs(null).size()); + + SignedMailValidator.ValidationResult res = validator.getValidationResult(signer); + assertEquals(1, res.getCertPath().getCertificates().size()); + assertEquals(2, res.getUserProvidedCerts().size()); + assertTrue(res.isVerifiedSignature()); + assertTrue(res.isValidSignature()); + + testException("Malformed content..", "SignedMailValidatorException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + MimeMessage message = loadMessage("dotnet_encrypted_mail.eml"); + new SignedMailValidator(message, params); + } + }); + + testException("MimeMessage message is not a signed message.", "SignedMailValidatorException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new SignedMailValidator(new MimeMessage(session), params); + } + }); + + final MimeMessage mm = new MimeMessage(session); + mm.setFrom(fromUser); + mm.setRecipient(Message.RecipientType.TO, toUser); + mm.setContent(message, signedMsg.getContentType()); + mm.setHeader("Sender", "sender@bouncycastle.org"); + + //mm.saveChanges() must throw exception + testException("unable to save message", "SMIMEException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new SMIMECompressedGenerator().generate(mm, new ZlibCompressor()); + } + }); + + testException("unable to save message", "SMIMEException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new SMIMEEnvelopedGenerator().generate(mm, new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC).setProvider("BC").build()); + } + }); + + testException("unable to save message", "SMIMEException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new SMIMESignedGenerator().generate(mm); + } + }); + + testException("unable to save message", "SMIMEException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new SMIMESignedGenerator().generateEncapsulated(mm); + } + }); + + testException("unknown object in writeTo ", "IOException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + mm.writeTo(new ByteArrayOutputStream()); + } + }); + } + + public static X509Certificate makeCertificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN, boolean _ca, String subjectAltName) + throws GeneralSecurityException, IOException, OperatorCreationException + { + + PublicKey subPub = subKP.getPublic(); + PrivateKey issPriv = issKP.getPrivate(); + PublicKey issPub = issKP.getPublic(); + + X509v3CertificateBuilder v3CertGen = new JcaX509v3CertificateBuilder( + new X500Name(_issDN), + CMSTestUtil.allocateSerialNumber(), + new Date(System.currentTimeMillis()), + new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), + new X500Name(_subDN), + subPub); + + JcaContentSignerBuilder contentSignerBuilder = CMSTestUtil.makeContentSignerBuilder(issPub); + + v3CertGen.addExtension( + Extension.subjectKeyIdentifier, + false, + CMSTestUtil.createSubjectKeyId(subPub)); + + v3CertGen.addExtension( + Extension.authorityKeyIdentifier, + false, + CMSTestUtil.createAuthorityKeyId(issPub)); + + v3CertGen.addExtension( + Extension.basicConstraints, + false, + new BasicConstraints(_ca)); + + GeneralNames collection = new GeneralNames(new GeneralName(1, new DERIA5String(subjectAltName))); + + ASN1EncodableVector vector = new ASN1EncodableVector(); + vector.add(new DERTaggedObject(1, collection)); + v3CertGen.addExtension(Extension.subjectAlternativeName, false, collection); + + X509Certificate _cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(v3CertGen.build(contentSignerBuilder.build(issPriv))); + + _cert.checkValidity(new Date()); + _cert.verify(issPub); + + return _cert; + } + + public void testCompressedSHA1WithRSA() + throws Exception + { + List certList = new ArrayList(); + + certList.add(_origCert); + certList.add(_signCert); + + Store certs = new JcaCertStore(certList); + + ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); + SMIMECapabilityVector caps = new SMIMECapabilityVector(); + + caps.addCapability(SMIMECapability.dES_EDE3_CBC); + caps.addCapability(SMIMECapability.rC2_CBC, 128); + caps.addCapability(SMIMECapability.dES_CBC); + + signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); + final Session session = Session.getDefaultInstance(System.getProperties(), null); + MimeMessage mimeMessage = new MimeMessage(session); + + // Set the content type to "application/pkcs7-mime" + mimeMessage.setHeader("Content-Type", "application/pkcs7-mime"); + + // Set other necessary properties and content for the MimeMessage + mimeMessage.setSubject("Your Subject"); + mimeMessage.setFrom(new InternetAddress("sender@example.com")); + mimeMessage.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress("recipient@example.com")); + mimeMessage.setText("Your message content"); + + SMIMESignedGenerator gen = new SMIMESignedGenerator(); + gen.setContentTransferEncoding("base64"); + assertNotNull(gen.generateEncapsulated(mimeMessage)); + gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", _origKP.getPrivate(), _origCert)); + + gen.addCertificates(certs); + + SMIMECompressedGenerator cgen = new SMIMECompressedGenerator(); + + MimeBodyPart cbp = cgen.generate(mimeMessage, new ZlibCompressor()); + + SMIMECompressed cm = new SMIMECompressed(cbp); + + testException("can't extract input stream:", "MessagingException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new SMIMECompressed(new MimeMessage(session)); + } + }); + + MimeMessage mimeMessage1 = new MimeMessage(session, new ByteArrayInputStream(cm.getContent(new ZlibExpanderProvider()))); + assertEquals(mimeMessage1.getContent(), mimeMessage.getContent()); + + SMIMECompressedParser sc = new SMIMECompressedParser(cbp, 1024); + assertEquals(sc.getCompressedContent(), cm.getCompressedContent()); + + + } + + public void testExamples() + throws Exception + { + PKCS12FileCreator.main(null); + CreateCompressedMail.main(null); + CreateEncryptedMail.main(new String[]{"id.p12", "hello world"}); + CreateLargeCompressedMail.main(new String[]{"id.p12"}); + CreateLargeEncryptedMail.main(new String[]{"id.p12", "hello world", "encrypted.message"}); + CreateLargeSignedMail.main(new String[]{"id.p12"}); + CreateSignedMail.main(null); + CreateSignedMultipartMail.main(null); + ReadCompressedMail.main(null); + ReadEncryptedMail.main(new String[]{"id.p12", "hello world"}); + ReadLargeCompressedMail.main(new String[]{"id.p12", "hello world"}); + ReadLargeEncryptedMail.main(new String[]{"id.p12", "hello world", "encrypted.message"}); + ReadLargeSignedMail.main(null); + ReadSignedMail.main(null); + + KeyStore ks = KeyStore.getInstance("PKCS12", "BC"); + ks.load(new FileInputStream("id.p12"), "hello world".toCharArray()); + + Enumeration e = ks.aliases(); + String keyAlias = null; + + while (e.hasMoreElements()) + { + String alias = (String)e.nextElement(); + + if (ks.isKeyEntry(alias)) + { + keyAlias = alias; + } + } + + SendSignedAndEncryptedMail.main(new String[]{"id.p12", "hello world", keyAlias, "smtp.gmail.com", "recipient@example.com"}); + ValidateSignedMail.main(null); + } + + public void testParser() + throws Exception + { + final Session session = Session.getDefaultInstance(System.getProperties(), null); + final MimeMessage mimeMessage = new MimeMessage(session); + testException("can't extract input stream:", "MessagingException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new SMIMEEnveloped(mimeMessage); + } + }); + + testException("can't extract input stream:", "MessagingException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new SMIMESigned(mimeMessage); + } + }); + + testException("can't extract input stream:", "MessagingException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new SMIMECompressedParser(mimeMessage, 0); + } + }); + } + + public void testSignedMessageVerificationMultipart() + throws Exception + { + final SMIMEToolkit toolkit = new SMIMEToolkit(new BcDigestCalculatorProvider()); + + MimeMultipart smm = generateMultiPartRsa("SHA1withRSA", msg, SMIMESignedGenerator.RFC3851_MICALGS); + + assertTrue(toolkit.isValidSignature(smm, new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(_signCert))); + + MimeMessage body = makeMimeMessage(smm); + + assertTrue(toolkit.isValidSignature(body, new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(_signCert))); + + final MimeMessage mimeMessage = new MimeMessage(Session.getDefaultInstance(System.getProperties(), null)); + +// mimeMessage.setHeader("Content-Type", "multipart/signed"); +// testException("Parsing failure: ", "SMIMEException", new TestExceptionOperation() +// { +// @Override +// public void operation() +// throws Exception +// { +// toolkit.isValidSignature(mimeMessage, new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(_signCert)); +// } +// }); +// +// testException("Parsing failure: ", "SMIMEException", new TestExceptionOperation() +// { +// @Override +// public void operation() +// throws Exception +// { +// toolkit.extractCertificate(mimeMessage, null); +// } +// }); +// +// testException("Parsing failure: ", "SMIMEException", new TestExceptionOperation() +// { +// @Override +// public void operation() +// throws Exception +// { +// toolkit.decrypt(mimeMessage, new JceKeyTransRecipientId(_reciCert), new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); +// +// } +// }); + } + + private MimeMessage makeMimeMessage(MimeMultipart mm) + throws MessagingException, IOException + { + Properties props = System.getProperties(); + Session session = Session.getDefaultInstance(props, null); + + Address fromUser = new InternetAddress("\"Eric H. Echidna\""); + Address toUser = new InternetAddress("example@bouncycastle.org"); + + MimeMessage body = new MimeMessage(session); + body.setFrom(fromUser); + body.setRecipient(Message.RecipientType.TO, toUser); + body.setSubject("example message"); + body.setContent(mm, mm.getContentType()); + body.saveChanges(); + + return body; + } + + private void addHashHeader( + StringBuffer header, + List signers) + { + int count = 0; + + // + // build the hash header + // + Iterator it = signers.iterator(); + Set micAlgSet = new TreeSet(); + Map micAlgs = SMIMESignedGenerator.STANDARD_MICALGS; + while (it.hasNext()) + { + Object signer = it.next(); + ASN1ObjectIdentifier digestOID; + + if (signer instanceof SignerInformation) + { + digestOID = ((SignerInformation)signer).getDigestAlgorithmID().getAlgorithm(); + } + else + { + digestOID = ((SignerInfoGenerator)signer).getDigestAlgorithm().getAlgorithm(); + } + + String micAlg = (String)micAlgs.get(digestOID); + + if (micAlg == null) + { + micAlgSet.add("unknown"); + } + else + { + micAlgSet.add(micAlg); + } + } + + it = micAlgSet.iterator(); + + while (it.hasNext()) + { + String alg = (String)it.next(); + + if (count == 0) + { + if (micAlgSet.size() != 1) + { + header.append("; micalg=\""); + } + else + { + header.append("; micalg="); + } + } + else + { + header.append(','); + } + + header.append(alg); + + count++; + } + + if (count != 0) + { + if (micAlgSet.size() != 1) + { + header.append('\"'); + } + } + } + + private MimeBodyPart generateEncapsulated() + throws CertificateEncodingException, OperatorCreationException, SMIMEException + { + List certList = new ArrayList(); + + certList.add(_signCert); + certList.add(_origCert); + + Store certs = new JcaCertStore(certList); + + SMIMESignedGenerator gen = new SMIMESignedGenerator(); + + gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).build("SHA1withRSA", _signKP.getPrivate(), _signCert)); + + gen.addCertificates(certs); + + return gen.generateEncapsulated(msg); + } +} diff --git a/mail/src/test/java/org/bouncycastle/mail/smime/test/NewSMIMEEnvelopedTest.java b/mail/src/test/java/org/bouncycastle/mail/smime/test/NewSMIMEEnvelopedTest.java index bd87265662..643de5aa24 100644 --- a/mail/src/test/java/org/bouncycastle/mail/smime/test/NewSMIMEEnvelopedTest.java +++ b/mail/src/test/java/org/bouncycastle/mail/smime/test/NewSMIMEEnvelopedTest.java @@ -73,7 +73,7 @@ public class NewSMIMEEnvelopedTest private static boolean _initialised = false; - private static final byte[] testMessage = Base64.decode( + static final byte[] testMessage = Base64.decode( "TUlNRS1WZXJzaW9uOiAxLjANCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOyANCglib3VuZGFye" + "T0iLS0tLT1fUGFydF8wXzI2MDM5NjM4Ni4xMzUyOTA0NzUwMTMyIg0KQ29udGVudC1MYW5ndWFnZTogZW" + "4NCkNvbnRlbnQtRGVzY3JpcHRpb246IEEgbWFpbCBmb2xsb3dpbmcgdGhlIERJUkVDVCBwcm9qZWN0IHN" + diff --git a/mail/src/test/java/org/bouncycastle/mail/smime/test/PKCS12FileCreator.java b/mail/src/test/java/org/bouncycastle/mail/smime/test/PKCS12FileCreator.java new file mode 100644 index 0000000000..ff31c936b0 --- /dev/null +++ b/mail/src/test/java/org/bouncycastle/mail/smime/test/PKCS12FileCreator.java @@ -0,0 +1,355 @@ +package org.bouncycastle.mail.smime.test; + +import java.io.FileOutputStream; +import java.math.BigInteger; +import java.security.KeyFactory; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Security; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.util.Date; + +import org.bouncycastle.asn1.DERBMPString; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.X500NameBuilder; +import org.bouncycastle.asn1.x500.style.BCStyle; +import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.X509v1CertificateBuilder; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; +import org.bouncycastle.cert.jcajce.JcaX509v1CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; + +/** + * Example of how to set up a certificate chain and a PKCS 12 store for + * a private individual using the KeyStore API - obviously you'll need to generate your own keys, + * and you may need to add a NetscapeCertType extension or add a key + * usage extension depending on your application, but you should get the + * idea! As always this is just an example... + */ +class PKCS12FileCreator +{ + static char[] passwd = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; + + /** + * we generate the CA's certificate + */ + public static Certificate createMasterCert( + PublicKey pubKey, + PrivateKey privKey) + throws Exception + { + // + // signers name + // + String issuer = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate"; + + // + // subjects name - the same as we are self signed. + // + String subject = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate"; + + // + // create the certificate - version 1 + // + X509v1CertificateBuilder v1Bldr = new JcaX509v1CertificateBuilder(new X500Name(issuer), BigInteger.valueOf(1), + new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30)), + new X500Name(subject), pubKey); + + X509CertificateHolder certHldr = v1Bldr.build(new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC").build(privKey)); + + X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHldr); + + cert.checkValidity(new Date()); + + cert.verify(pubKey); + + PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)cert; + + // + // this is actually optional - but if you want to have control + // over setting the friendly name this is the way to do it... + // + bagAttr.setBagAttribute( + PKCSObjectIdentifiers.pkcs_9_at_friendlyName, + new DERBMPString("Bouncy Primary Certificate")); + + return cert; + } + + /** + * we generate an intermediate certificate signed by our CA + */ + public static Certificate createIntermediateCert( + PublicKey pubKey, + PrivateKey caPrivKey, + X509Certificate caCert) + throws Exception + { + // + // subject name builder. + // + X500NameBuilder nameBuilder = new X500NameBuilder(); + + nameBuilder.addRDN(BCStyle.C, "AU"); + nameBuilder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); + nameBuilder.addRDN(BCStyle.OU, "Bouncy Intermediate Certificate"); + nameBuilder.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org"); + + // + // create the certificate - version 3 + // + X509v3CertificateBuilder v3Bldr = new JcaX509v3CertificateBuilder(caCert, BigInteger.valueOf(2), + new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30)), + nameBuilder.build(), pubKey); + + // + // extensions + // + JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); + + v3Bldr.addExtension( + Extension.subjectKeyIdentifier, + false, + extUtils.createSubjectKeyIdentifier(pubKey)); + + v3Bldr.addExtension( + Extension.authorityKeyIdentifier, + false, + extUtils.createAuthorityKeyIdentifier(caCert)); + + v3Bldr.addExtension( + Extension.basicConstraints, + true, + new BasicConstraints(0)); + + X509CertificateHolder certHldr = v3Bldr.build(new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC").build(caPrivKey)); + + X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHldr); + + cert.checkValidity(new Date()); + + cert.verify(caCert.getPublicKey()); + + PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)cert; + + // + // this is actually optional - but if you want to have control + // over setting the friendly name this is the way to do it... + // + bagAttr.setBagAttribute( + PKCSObjectIdentifiers.pkcs_9_at_friendlyName, + new DERBMPString("Bouncy Intermediate Certificate")); + + return cert; + } + + /** + * we generate a certificate signed by our CA's intermediate certificate + */ + public static Certificate createCert( + PublicKey pubKey, + PrivateKey caPrivKey, + PublicKey caPubKey) + throws Exception + { + // + // signers name table. + // + X500NameBuilder issuerBuilder = new X500NameBuilder(); + + issuerBuilder.addRDN(BCStyle.C, "AU"); + issuerBuilder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); + issuerBuilder.addRDN(BCStyle.OU, "Bouncy Intermediate Certificate"); + issuerBuilder.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org"); + + // + // subjects name table. + // + X500NameBuilder subjectBuilder = new X500NameBuilder(); + + subjectBuilder.addRDN(BCStyle.C, "AU"); + subjectBuilder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); + subjectBuilder.addRDN(BCStyle.L, "Melbourne"); + subjectBuilder.addRDN(BCStyle.CN, "Eric H. Echidna"); + subjectBuilder.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org"); + + // + // create the certificate - version 3 + // + X509v3CertificateBuilder v3Bldr = new JcaX509v3CertificateBuilder(issuerBuilder.build(), BigInteger.valueOf(3), + new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30)), + subjectBuilder.build(), pubKey); + + // + // extensions + // + JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); + + v3Bldr.addExtension( + Extension.subjectKeyIdentifier, + false, + extUtils.createSubjectKeyIdentifier(pubKey)); + + v3Bldr.addExtension( + Extension.authorityKeyIdentifier, + false, + extUtils.createAuthorityKeyIdentifier(caPubKey)); + + X509CertificateHolder certHldr = v3Bldr.build(new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC").build(caPrivKey)); + + X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHldr); + + cert.checkValidity(new Date()); + + cert.verify(caPubKey); + + PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)cert; + + // + // this is also optional - in the sense that if you leave this + // out the keystore will add it automatically, note though that + // for the browser to recognise the associated private key this + // you should at least use the pkcs_9_localKeyId OID and set it + // to the same as you do for the private key's localKeyId. + // + bagAttr.setBagAttribute( + PKCSObjectIdentifiers.pkcs_9_at_friendlyName, + new DERBMPString("Eric's Key")); + bagAttr.setBagAttribute( + PKCSObjectIdentifiers.pkcs_9_at_localKeyId, + extUtils.createSubjectKeyIdentifier(pubKey)); + + return cert; + } + + public static void main( + String[] args) + throws Exception + { + Security.addProvider(new BouncyCastleProvider()); + + // + // personal keys + // + RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( + new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), + new BigInteger("11", 16)); + + RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( + new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), + new BigInteger("11", 16), + new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), + new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), + new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), + new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), + new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), + new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); + + // + // intermediate keys. + // + RSAPublicKeySpec intPubKeySpec = new RSAPublicKeySpec( + new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16), + new BigInteger("ffff", 16)); + + + RSAPrivateCrtKeySpec intPrivKeySpec = new RSAPrivateCrtKeySpec( + new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16), + new BigInteger("ffff", 16), + new BigInteger("7deb1b194a85bcfd29cf871411468adbc987650903e3bacc8338c449ca7b32efd39ffc33bc84412fcd7df18d23ce9d7c25ea910b1ae9985373e0273b4dca7f2e0db3b7314056ac67fd277f8f89cf2fd73c34c6ca69f9ba477143d2b0e2445548aa0b4a8473095182631da46844c356f5e5c7522eb54b5a33f11d730ead9c0cff", 16), + new BigInteger("ef4cede573cea47f83699b814de4302edb60eefe426c52e17bd7870ec7c6b7a24fe55282ebb73775f369157726fcfb988def2b40350bdca9e5b418340288f649", 16), + new BigInteger("97c7737d1b9a0088c3c7b528539247fd2a1593e7e01cef18848755be82f4a45aa093276cb0cbf118cb41117540a78f3fc471ba5d69f0042274defc9161265721", 16), + new BigInteger("6c641094e24d172728b8da3c2777e69adfd0839085be7e38c7c4a2dd00b1ae969f2ec9d23e7e37090fcd449a40af0ed463fe1c612d6810d6b4f58b7bfa31eb5f", 16), + new BigInteger("70b7123e8e69dfa76feb1236d0a686144b00e9232ed52b73847e74ef3af71fb45ccb24261f40d27f98101e230cf27b977a5d5f1f15f6cf48d5cb1da2a3a3b87f", 16), + new BigInteger("e38f5750d97e270996a286df2e653fd26c242106436f5bab0f4c7a9e654ce02665d5a281f2c412456f2d1fa26586ef04a9adac9004ca7f913162cb28e13bf40d", 16)); + + // + // ca keys + // + RSAPublicKeySpec caPubKeySpec = new RSAPublicKeySpec( + new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), + new BigInteger("11", 16)); + + RSAPrivateCrtKeySpec caPrivKeySpec = new RSAPrivateCrtKeySpec( + new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16), + new BigInteger("11", 16), + new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16), + new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16), + new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16), + new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16), + new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16), + new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16)); + + + + // + // set up the keys + // + KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); + PrivateKey caPrivKey = fact.generatePrivate(caPrivKeySpec); + PublicKey caPubKey = fact.generatePublic(caPubKeySpec); + PrivateKey intPrivKey = fact.generatePrivate(intPrivKeySpec); + PublicKey intPubKey = fact.generatePublic(intPubKeySpec); + PrivateKey privKey = fact.generatePrivate(privKeySpec); + PublicKey pubKey = fact.generatePublic(pubKeySpec); + + Certificate[] chain = new Certificate[3]; + + chain[2] = createMasterCert(caPubKey, caPrivKey); + chain[1] = createIntermediateCert(intPubKey, caPrivKey, (X509Certificate)chain[2]); + chain[0] = createCert(pubKey, intPrivKey, intPubKey); + + // + // add the friendly name for the private key + // + PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; + + // + // this is also optional - in the sense that if you leave this + // out the keystore will add it automatically, note though that + // for the browser to recognise which certificate the private key + // is associated with you should at least use the pkcs_9_localKeyId + // OID and set it to the same as you do for the private key's + // corresponding certificate. + // + JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); + + bagAttr.setBagAttribute( + PKCSObjectIdentifiers.pkcs_9_at_friendlyName, + new DERBMPString("Eric's Key")); + bagAttr.setBagAttribute( + PKCSObjectIdentifiers.pkcs_9_at_localKeyId, + extUtils.createSubjectKeyIdentifier(pubKey)); + + // + // store the key and the certificate chain + // + KeyStore store = KeyStore.getInstance("PKCS12", "BC"); + + store.load(null, null); + + // + // if you haven't set the friendly name and local key id above + // the name below will be the name of the key + // + store.setKeyEntry("Eric's Key", privKey, null, chain); + + FileOutputStream fOut = new FileOutputStream("id.p12"); + + store.store(fOut, passwd); + + fOut.close(); + } +} diff --git a/mail/src/test/java/org/bouncycastle/mail/smime/test/SignedMailValidatorTest.java b/mail/src/test/java/org/bouncycastle/mail/smime/test/SignedMailValidatorTest.java index 77a596e125..0e05c976f6 100644 --- a/mail/src/test/java/org/bouncycastle/mail/smime/test/SignedMailValidatorTest.java +++ b/mail/src/test/java/org/bouncycastle/mail/smime/test/SignedMailValidatorTest.java @@ -39,15 +39,19 @@ import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; -import org.bouncycastle.i18n.ErrorBundle; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.mail.smime.validator.SignedMailValidator; +import org.bouncycastle.pkix.jcajce.PKIXCertPathReviewer; +import org.bouncycastle.pkix.util.ErrorBundle; import org.bouncycastle.util.Store; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Base64; -import org.bouncycastle.x509.PKIXCertPathReviewer; +import org.bouncycastle.util.encoders.Hex; public class SignedMailValidatorTest extends TestCase { + private static final String NNBSP = Strings.fromUTF8ByteArray(Hex.decode("e280af")); + static String TEST_TRUST_ACHOR = "validator.root.crt"; static byte[] multiEmailCert = Base64.decode( @@ -317,7 +321,7 @@ public void testSelfSignedCert() SignedMailValidator.ValidationResult res = validator.getValidationResult(signer); -// assertTrue(res.isVerifiedSignature()); + assertTrue(res.isVerifiedSignature()); assertTrue(res.isValidSignature()); } @@ -457,7 +461,7 @@ private void assertContainsMessage(List msgList, String messageId, { found = true; assertEquals(text, message.getText(Locale.ENGLISH, TimeZone - .getTimeZone("GMT")).replace("Greenwich Mean Time", "GMT")); + .getTimeZone("GMT")).replace("Greenwich Mean Time", "GMT").replaceAll(NNBSP, " ")); break; } } diff --git a/mail/src/test/jdk1.4/org/bouncycastle/mail/smime/test/SignedMailValidatorTest.java b/mail/src/test/jdk1.4/org/bouncycastle/mail/smime/test/SignedMailValidatorTest.java deleted file mode 100644 index 627d60b110..0000000000 --- a/mail/src/test/jdk1.4/org/bouncycastle/mail/smime/test/SignedMailValidatorTest.java +++ /dev/null @@ -1,540 +0,0 @@ -package org.bouncycastle.mail.smime.test; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.security.KeyPair; -import java.security.Security; -import java.security.cert.CertPath; -import java.security.cert.CertStore; -import java.security.cert.CertificateFactory; -import java.security.cert.CollectionCertStoreParameters; -import java.security.cert.PKIXParameters; -import java.security.cert.TrustAnchor; -import java.security.cert.X509CRL; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Properties; -import java.util.Set; -import java.util.TimeZone; - -import javax.mail.Address; -import javax.mail.Message; -import javax.mail.Session; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; -import org.bouncycastle.test.PrintTestResult; -import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.cert.jcajce.JcaCertStore; -import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; -import org.bouncycastle.cms.SignerInformation; -import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; -import org.bouncycastle.i18n.ErrorBundle; -import org.bouncycastle.mail.smime.SMIMESignedGenerator; -import org.bouncycastle.mail.smime.validator.SignedMailValidator; -import org.bouncycastle.util.Store; -import org.bouncycastle.util.encoders.Base64; -import org.bouncycastle.x509.PKIXCertPathReviewer; - -public class SignedMailValidatorTest extends TestCase -{ - static String TEST_TRUST_ACHOR = "validator.root.crt"; - - static byte[] multiEmailCert = Base64.decode( - "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdmVENDQkdXZ0F3SUJB" - + "Z0lCR2pBTkJna3Foa2lHOXcwQkFRc0ZBRENCdnpFTE1Ba0dBMVVFQmhNQ1Ew" - + "Z3gKQ3pBSkJnTlZCQWdUQWxwSU1ROHdEUVlEVlFRSEV3WmFkWEpwWTJneEZ6" - + "QVZCZ05WQkFvVERsQnlhWFpoVTNCbwpaWEpsSUVGSE1SNHdIQVlEVlFRTERC" - + "VkVaWFpsYkc5d2JXVnVkQ0FtSUZSbGMzUnBibWN4TkRBeUJnTlZCQU1NCksx" - + "QnlhWFpoVTNCb1pYSmxJRWx1ZEdWeWJXVmthV0Z5ZVNCRFpYSjBhV1pwWTJG" - + "MFpTQmJWRVZUVkYweEl6QWgKQmdrcWhraUc5dzBCQ1FFV0ZHbHVabTlBY0hK" - + "cGRtRnpjR2hsY21VdVkyOXRNQjRYRFRFM01EWXlPREE0TkRjdwpNRm9YRFRN" - + "M01EWXlPREE0TkRjd01Gb3dnZDB4Q3pBSkJnTlZCQVlUQWtOSU1Rc3dDUVlE" - + "VlFRSUV3SmFTREVQCk1BMEdBMVVFQnhNR1duVnlhV05vTVJjd0ZRWURWUVFL" - + "RXc1UWNtbDJZVk53YUdWeVpTQkJSekVlTUJ3R0ExVUUKQ3d3VlJHVjJaV3h2" - + "Y0cxbGJuUWdKaUJVWlhOMGFXNW5NVGd3TmdZSktvWklodmNOQVFrQkZpbGti" - + "MjFoYVc0dApZMjl1Wm1sa1pXNTBhV0ZzYVhSNUxXRjFkR2h2Y21sMGVVQmla" - + "V3RpTG1Ob0lERTlNRHNHQ1NxR1NJYjNEUUVKCkFSWXVaRzl0WVdsdUxXTnZi" - + "bVpwWkdWdWRHbGhiR2wwZVMxaGRYUm9iM0pwZEhsQVptRnRhV3g1TFc1bGRD" - + "NWoKYURDQ0FpSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnSVBBRENDQWdvQ2dn" - + "SUJBTWJmNEh2a0lYUHpta1BTR09JbApxZ0FhdWlOYVVNdGNPSFlvWnBrS2dt" - + "ekVsdk4xNnk5enYyZUNkdThnTGNaT3FXT2ZNNmkzY0Z6T1N0bEIxL2lDClM4" - + "Vks2ekJmRUgrcDlBbFBCaFVKMDBrbjRESVNXSmRiV25pWXM2clo2cWtpTjZi" - + "aHV6V3k5YTVsZkM0c3Q2UisKN0lVcWJwaGxQSUU5OEhJbmQxV01ieTZKYWV0" - + "WHNZbW5Sb1Mxd29Fblg5U1BDdXBSK1dzbmtOemtRTFFhMGJYaApVZ3ZmR0Zh" - + "VTJwWXBLdXdvN3BsdHBZQzJjVENtVmFJR05rVmJWVGFsYktub0VoNVgrelRq" - + "U2oxSWJLaVdIVmNMCjJGTkxoS1hBS1loRGNXd2llVVd0S281T2JrWTZWRzVj" - + "dnU0OVozc1llUkkzNnZwY0NNTklvRzFJWlQ1bnhhVmYKKzlaRTM0WllOV3Y4" - + "RHZXOFdHZzc4RmkxS1dzanlCajN0SDk3Q3lIZnRsdFl3U3REVXllaGZHUytp" - + "aTBteUVWSwpzQ1BiQmwvOU82VHhISWZNRDVuTjlGeFZSZENrdTM5U1hmK29R" - + "K3pNdEE0eEtyc3JLVm9RUGZvNDhYaW5HMStICmxZWW1HL01SYTkzZHFCd1ov" - + "ZEUrRnZLZ2hmU003bVRPTEhPa0YxL0RzQnRJb0s4YmMrRDBIVHhZbWlsbFRj" - + "Vm0KbFkrVnArRHdtdStRVXlvOFU5UmU3Q0ZOOGs5RlVtc2hORTcyRDkvNytM" - + "NmI0Smt0ZTQvdXlzOGVIYnVoRXBnNQphTVMySHRjSkRJL25LbEE2TjFWZjVx" - + "aVlaVnIrUkRPZmxmS3ZHdnVGcFFMcjhWUUFONFUzalhOaVVIRGI2ek9rCms5" - + "UWdpV2REWDJrTFRTeldubnI5ZDFYTkFnTUJBQUdqWkRCaU1Bd0dBMVVkRXdF" - + "Qi93UUNNQUF3Q3dZRFZSMFAKQkFRREFnYkFNQk1HQTFVZEpRUU1NQW9HQ0Nz" - + "R0FRVUZCd01FTUJFR0NXQ0dTQUdHK0VJQkFRUUVBd0lGSURBZApCZ2xnaGtn" - + "Qmh2aENBUTBFRUJZT1VISnBkbUZUY0dobGNtVWdRMEV3RFFZSktvWklodmNO" - + "QVFFTEJRQURnZ0lCCkFONjF2Sy9taFhCc3NHZEpxTGszVjBOK3BJOFRRc3ps" - + "RU5pbzJTQ25kSTZyejhRRzFnUVBRZjRIaCtIZUNpWFYKNVlIcHAxMjdZVXlR" - + "Y1hiK3JYc3lSQXM0SWd6TWZyK3dmTWY5NVdianQ1QWRVR21XdFdwV2pkajBo" - + "YmlROGJmMwprU3Y4TnR6ZVhKTHBOYS9YK0NRYy9vRm1qeHZ1ZDJXczVzZG1S" - + "Uno2VUlKVFJoT2t4SFErTVlqL1NlTFFIQWU3CkQzaFV5NE9iVnlBU3VLaHpH" - + "MnExYm9mSnBKZHByZVNSMll2a2JQRW9FRlZSd2NQTXNPMFdGRmpCSGlHbVln" - + "aTEKd21qTnlzak8wZ0lwNnpMUzNSSUErd1llRHJVVnEzSnRya0RJZnZkL2tS" - + "T2UvcUFlcDB3THRReGFoSEFOSk80UAo5ZmxtV1F6bENMRlFoTUZibFl2Nis1" - + "NVVDeDhvRkVJTmUvaWF1VUlZME54WXZWclBMREwwVFhSR3grdVFsVVJaCkZi" - + "SUpBYzBTUW1SWXlHVkdnb1pUbVhHd0FjemNLWk5XZzd6NTk5TXBidW13ejJZ" - + "T2RTekRncjV0MHpGQUhDRG8KanRuUnRudVRYMkxvK1UwaWF6RlZhNVYrbDVs" - + "QjNIdFpXOWJkKy9ZSVo5K3YyZWpOS3M4UzZjQW1DRkFmVWpkUgpvWEJQUVdP" - + "Tmx6MjdGOXc3ajc5dmlNUHVES0ZtOU9LdmhQdVQvdWVaOGJCNmRYMlh3aTNw" - + "RTM1dWdRK05NT1crCnFUSkZSNDhyVzFvRkYxNTdxNXFzU2ovK3lqQlZpejRL" - + "YWlDakVKRDR4RE1UNzAzQytsTGZyamk3KzR2Z3ZIV0IKbHNCVS9jWkVoeFdu" - + "VjJQaHRsR3g2M2s2OThYeU03eWFCcDUvdHZuL2xSY0cKLS0tLS1FTkQgQ0VS" - + "VElGSUNBVEUtLS0tLQo="); - - public void testShortKey() throws Exception - { - String message = "validator.shortKey.eml"; - PKIXParameters params = createDefaultParams(); - SignedMailValidator.ValidationResult result = doTest(message, params); - - assertTrue(result.isValidSignature()); - assertContainsMessage(result.getNotifications(), - "SignedMailValidator.shortSigningKey", - "Warning: The signing key is only 512 bits long."); - } - - public void testKeyUsage() throws Exception - { - String message = "validator.keyUsage.eml"; - PKIXParameters params = createDefaultParams(); - SignedMailValidator.ValidationResult result = doTest(message, params); - - assertTrue(result.isVerifiedSignature()); - assertTrue(result.getCertPathReview().isValidCertPath()); - assertFalse(result.isValidSignature()); - - assertContainsMessage( - result.getErrors(), - "SignedMailValidator.signingNotPermitted", - "The key usage extension of signer certificate does not permit using the key for email signatures."); - } - - public void testMultiEmail() throws Exception - { - CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); - - Set addresses = SignedMailValidator.getEmailAddresses((X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(multiEmailCert))); - - assertTrue(addresses.contains("domain-confidentiality-authority@family-net.ch")); - assertTrue(addresses.contains("domain-confidentiality-authority@bekb.ch ")); - } - - public void testExtKeyUsage() throws Exception - { - String message = "validator.extKeyUsage.eml"; - PKIXParameters params = createDefaultParams(); - SignedMailValidator.ValidationResult result = doTest(message, params); - - assertTrue(result.isVerifiedSignature()); - assertTrue(result.getCertPathReview().isValidCertPath()); - assertFalse(result.isValidSignature()); - - assertContainsMessage( - result.getErrors(), - "SignedMailValidator.extKeyUsageNotPermitted", - "The extended key usage extension of the signer certificate does not permit using the key for email signatures."); - } - - public void testNoEmail() throws Exception - { - String message = "validator.noEmail.eml"; - PKIXParameters params = createDefaultParams(); - SignedMailValidator.ValidationResult result = doTest(message, params); - - assertTrue(result.isVerifiedSignature()); - assertTrue(result.getCertPathReview().isValidCertPath()); - assertFalse(result.isValidSignature()); - - assertContainsMessage( - result.getErrors(), - "SignedMailValidator.noEmailInCert", - "The signer certificate is not usable for email signatures: it contains no email address."); - } - - public void testNotYetValid() throws Exception - { - String message = "validator.notYetValid.eml"; - PKIXParameters params = createDefaultParams(); - SignedMailValidator.ValidationResult result = doTest(message, params); - - assertTrue(result.isVerifiedSignature()); - assertFalse(result.isValidSignature()); - assertContainsMessage(result.getErrors(), - "SignedMailValidator.certNotYetValid", - "The message was signed at Aug 28, 2006 3:04:01 PM GMT. But the certificate is not valid before Dec 28, 2006 2:19:31 PM GMT."); - - PKIXCertPathReviewer review = result.getCertPathReview(); - assertFalse(review.isValidCertPath()); - assertContainsMessage( - review.getErrors(0), - "CertPathReviewer.certificateNotYetValid", - "Could not validate the certificate. Certificate is not valid until Dec 28, 2006 2:19:31 PM GMT."); - } - - public void testExpired() throws Exception - { - String message = "validator.expired.eml"; - PKIXParameters params = createDefaultParams(); - SignedMailValidator.ValidationResult result = doTest(message, params); - - assertTrue(result.isVerifiedSignature()); - assertFalse(result.isValidSignature()); - assertContainsMessage(result.getErrors(), - "SignedMailValidator.certExpired", - "The message was signed at Sep 1, 2006 9:08:35 AM GMT. But the certificate expired at Sep 1, 2006 8:39:20 AM GMT."); - - PKIXCertPathReviewer review = result.getCertPathReview(); - assertFalse(review.isValidCertPath()); - assertContainsMessage( - review.getErrors(0), - "CertPathReviewer.certificateExpired", - "Could not validate the certificate. Certificate expired on Sep 1, 2006 8:39:20 AM GMT."); - } - - public void testRevoked() throws Exception - { - String message = "validator.revoked.eml"; - PKIXParameters params = createDefaultParams(); - List crlList = new ArrayList(); - crlList.add(loadCRL("validator.revoked.crl")); - CertStore crls = CertStore.getInstance("Collection",new CollectionCertStoreParameters(crlList)); - params.addCertStore(crls); - params.setRevocationEnabled(true); - - SignedMailValidator.ValidationResult result = doTest(message, params); - - assertTrue(result.isVerifiedSignature()); - assertFalse(result.isValidSignature()); - - PKIXCertPathReviewer review = result.getCertPathReview(); - assertFalse(review.isValidCertPath()); - assertContainsMessage( - review.getErrors(0), - "CertPathReviewer.certRevoked", - "The certificate was revoked at Sep 1, 2006 9:30:00 AM GMT. Reason: Key Compromise."); - } - - public void testLongValidity() throws Exception - { - String message = "validator.longValidity.eml"; - PKIXParameters params = createDefaultParams(); - - SignedMailValidator.ValidationResult result = doTest(message, params); - - assertTrue(result.isVerifiedSignature()); - assertTrue(result.isValidSignature()); - - assertContainsMessage(result.getNotifications(), - "SignedMailValidator.longValidity", - "Warning: The signing certificate has a very long validity period: from Sep 1, 2006 11:00:00 AM GMT until Aug 8, 2106 11:00:00 AM GMT."); - } - - public void testSelfSignedCert() - throws Exception - { - MimeBodyPart baseMsg = SMIMETestUtil.makeMimeBodyPart("Hello world!\n"); - String signDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; - KeyPair signKP = CMSTestUtil.makeKeyPair(); - X509Certificate signCert = CMSTestUtil.makeV1Certificate(signKP, signDN, signKP, signDN); - - // check basic path validation - Set trustanchors = new HashSet(); - TrustAnchor ta = new TrustAnchor(signCert, null); - trustanchors.add(ta); - - X509Certificate rootCert = ta.getTrustedCert(); - - // init cert stores - List certStores = new ArrayList(); - List certList = new ArrayList(); - certList.add(rootCert); - CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList)); - certStores.add(store); - - // first path - CertPath path = SignedMailValidator.createCertPath(rootCert, trustanchors, certStores); - - assertTrue("path size is not 1", path.getCertificates().size() == 1); - - // check message validation - certList = new ArrayList(); - - certList.add(signCert); - - Store certs = new JcaCertStore(certList); - - SMIMESignedGenerator gen = new SMIMESignedGenerator(); - - gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").build("SHA1withRSA", signKP.getPrivate(), signCert)); - gen.addCertificates(certs); - - MimeMultipart signedMsg = gen.generate(baseMsg); - - Properties props = System.getProperties(); - Session session = Session.getDefaultInstance(props, null); - - // read message - MimeMessage msg = new MimeMessage(session); - - Address fromUser = new InternetAddress("\"Eric H. Echidna\""); - Address toUser = new InternetAddress("example@bouncycastle.org"); - - msg.setFrom(fromUser); - msg.setRecipient(Message.RecipientType.TO, toUser); - msg.setContent(signedMsg, signedMsg.getContentType()); - - msg.saveChanges(); - - PKIXParameters params = new PKIXParameters(trustanchors); - params.setRevocationEnabled(false); - - SignedMailValidator validator = new SignedMailValidator(msg, params); - SignerInformation signer = (SignerInformation) validator - .getSignerInformationStore().getSigners().iterator().next(); - - SignedMailValidator.ValidationResult res = validator.getValidationResult(signer); - - assertTrue(res.isVerifiedSignature()); - assertTrue(res.isValidSignature()); - } - -// TODO: this test needs to be replaced, unfortunately it was working due to a bug in -// trust anchor extension handling -// public void testCorruptRootStore() throws Exception -// { -// String message = "validator.validMail.eml"; -// Set trustanchors = new HashSet(); -// trustanchors.add(getTrustAnchor(TEST_TRUST_ACHOR)); -// trustanchors.add(getTrustAnchor("validator.fakeRoot.crt")); -// PKIXParameters params = new PKIXParameters(trustanchors); -// params.setRevocationEnabled(false); -// -// SignedMailValidator.ValidationResult result = doTest(message, params); -// -// assertTrue(result.isVerifiedSignature()); -// assertFalse(result.isValidSignature()); -// -// PKIXCertPathReviewer review = result.getCertPathReview(); -// -// assertFalse(review.isValidCertPath()); -// assertContainsMessage(review.getErrors(-1), -// "CertPathReviewer.conflictingTrustAnchors", -// "Warning: corrupt trust root store: There are 2 trusted public keys for the CA \"CN=SignedMailValidatorTest Root, C=CH\" - please ensure with CA which is the correct key."); -// } - - public void testCircular() throws Exception - { - String message = "circular.eml"; - PKIXParameters params = createDefaultParams(); - SignedMailValidator.ValidationResult result = doTest(message, params); - - assertTrue(result.isVerifiedSignature()); - assertFalse(result.isValidSignature()); - assertFalse(result.getCertPathReview().isValidCertPath()); - assertTrue("cert path size", result.getCertPathReview().getCertPathSize() > 2); - } - - public void testExtendedReviewer() throws Exception - { - try - { - // Get a Session object with the default properties. - Properties props = System.getProperties(); - Session session = Session.getDefaultInstance(props, null); - - // read message - MimeMessage msg = new MimeMessage(session, getClass().getResourceAsStream("validator.shortKey.eml")); - - SignedMailValidator validator = new SignedMailValidator(msg, createDefaultParams(), String.class); - fail(); - } - catch (IllegalArgumentException e) - { - assertTrue(e.getMessage().startsWith("certPathReviewerClass is not a subclass of")); - } - - // Get a Session object with the default properties. - Properties props = System.getProperties(); - Session session = Session.getDefaultInstance(props, null); - - // read message - MimeMessage msg = new MimeMessage(session, getClass().getResourceAsStream("validator.shortKey.eml")); - - SignedMailValidator validator = new SignedMailValidator(msg, createDefaultParams(), DummyCertPathReviewer.class); - SignerInformation sInfo = (SignerInformation) validator.getSignerInformationStore().getSigners().iterator().next(); - SignedMailValidator.ValidationResult result = validator.getValidationResult(sInfo); - - assertTrue(result.isValidSignature()); - assertContainsMessage(result.getNotifications(), - "SignedMailValidator.shortSigningKey", - "Warning: The signing key is only 512 bits long."); - } - - public void testCreateCertPath() throws Exception - { - // load trust anchor - Set trustanchors = new HashSet(); - TrustAnchor ta = getTrustAnchor("certpath_root.crt"); - trustanchors.add(ta); - - X509Certificate rootCert = ta.getTrustedCert(); - X509Certificate interCert1 = loadCert("certpath_inter1.crt"); - X509Certificate interCert2 = loadCert("certpath_inter2.crt"); - X509Certificate endCert1 = loadCert("certpath_end1.crt"); - X509Certificate endCert2 = loadCert("certpath_end2.crt"); - - // init cert stores - List certStores = new ArrayList(); - List certList = new ArrayList(); - certList.add(interCert1); - certList.add(interCert2); - CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList)); - certStores.add(store); - - // first path - CertPath path = SignedMailValidator.createCertPath(endCert1, trustanchors, certStores); - assertTrue("path size is not 3", path.getCertificates().size() == 3); - assertEquals("different end certificate", path.getCertificates().get(0), endCert1); - assertEquals("different intermediate certificate", path.getCertificates().get(1), interCert1); - assertEquals("different root certificate", path.getCertificates().get(2), rootCert); - - // second path - path = SignedMailValidator.createCertPath(endCert2, trustanchors, certStores); - assertTrue("path size is not 3", path.getCertificates().size() == 3); - assertEquals("different end certificate", path.getCertificates().get(0), endCert2); - assertEquals("different intermediate certificate", path.getCertificates().get(1), interCert2); - assertEquals("different root certificate", path.getCertificates().get(2), rootCert); - } - - private SignedMailValidator.ValidationResult doTest(String message, - PKIXParameters params) throws Exception - { - // Get a Session object with the default properties. - Properties props = System.getProperties(); - Session session = Session.getDefaultInstance(props, null); - - // read message - MimeMessage msg = new MimeMessage(session, getClass().getResourceAsStream(message)); - - SignedMailValidator validator = new SignedMailValidator(msg, params); - SignerInformation signer = (SignerInformation) validator - .getSignerInformationStore().getSigners().iterator().next(); - return validator.getValidationResult(signer); - } - - private void assertContainsMessage(List msgList, String messageId, - String text) throws Exception - { - Iterator it = msgList.iterator(); - boolean found = false; - while (it.hasNext()) - { - ErrorBundle message = (ErrorBundle) it.next(); - if (message.getId().equals(messageId)) - { - found = true; - assertEquals(text, message.getText(Locale.ENGLISH, TimeZone - .getTimeZone("GMT"))); - break; - } - } - assertTrue("Expected message not found!", found); - } - - private PKIXParameters createDefaultParams() throws Exception - { - Set trustanchors = new HashSet(); - trustanchors.add(getTrustAnchor(TEST_TRUST_ACHOR)); - PKIXParameters defParams = new PKIXParameters(trustanchors); - defParams.setRevocationEnabled(false); - - return defParams; - } - - private TrustAnchor getTrustAnchor(String trustcert) throws Exception - { - X509Certificate cert = loadCert(trustcert); - if (cert != null) - { - byte[] ncBytes = cert - .getExtensionValue(Extension.nameConstraints.getId()); - - if (ncBytes != null) - { - ASN1Encodable extValue = JcaX509ExtensionUtils - .parseExtensionValue(ncBytes); - return new TrustAnchor(cert, extValue.toASN1Primitive().getEncoded(ASN1Encoding.DER)); - } - return new TrustAnchor(cert, null); - } - return null; - } - - private X509Certificate loadCert(String certfile) throws Exception - { - X509Certificate cert = null; - InputStream in = getClass().getResourceAsStream(certfile); - - CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); - cert = (X509Certificate) cf.generateCertificate(in); - return cert; - } - - private X509CRL loadCRL(String crlfile) throws Exception - { - X509CRL crl = null; - InputStream in = this.getClass().getResourceAsStream(crlfile); - - CertificateFactory cf = CertificateFactory.getInstance("x.509", "BC"); - crl = (X509CRL) cf.generateCRL(in); - return crl; - } - - public void setUp() - { - if (Security.getProvider("BC") == null) - { - Security - .addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); - } - } - - public static void main(String[] args) throws Exception - { - PrintTestResult.printResult( junit.textui.TestRunner.run(suite())); - } - - public static Test suite() throws Exception - { - TestSuite suite = new TestSuite("SignedMailValidator Tests"); - - suite.addTestSuite(SignedMailValidatorTest.class); - - return suite; - } - -} diff --git a/core/src/main/java/org/bouncycastle/asn1/util/Dump.java b/misc/src/main/java/org/bouncycastle/asn1/examples/Dump.java similarity index 90% rename from core/src/main/java/org/bouncycastle/asn1/util/Dump.java rename to misc/src/main/java/org/bouncycastle/asn1/examples/Dump.java index eb83b7ac49..a02ad50ab4 100644 --- a/core/src/main/java/org/bouncycastle/asn1/util/Dump.java +++ b/misc/src/main/java/org/bouncycastle/asn1/examples/Dump.java @@ -1,4 +1,4 @@ -package org.bouncycastle.asn1.util; +package org.bouncycastle.asn1.examples; import java.io.FileInputStream; @@ -7,7 +7,7 @@ /** * Command line ASN.1 Dump utility. *

      - * Usage: org.bouncycastle.asn1.util.Dump [-v] ber_encoded_file + * Usage: org.bouncycastle.asn1.examples.Dump [-v] ber_encoded_file *

      */ public class Dump diff --git a/mls/build.gradle b/mls/build.gradle index 2f6bbdf02d..fa6aee3f13 100644 --- a/mls/build.gradle +++ b/mls/build.gradle @@ -1,28 +1,32 @@ -buildscript { - repositories { - mavenCentral() - } - dependencies { - // ASSUMES GRADLE 2.12 OR HIGHER. Use plugin version 0.7.5 with earlier - // gradle versions -// classpath 'com.google.protobuf:protobuf-gradle-plugin:2.6.1' - } -} - plugins { +// OSGI + id "biz.aQute.bnd.builder" version "7.0.0" // Provide convenience executables for trying out the examples. id 'application' id 'com.google.protobuf' version '0.9.4' // Generate IntelliJ IDEA's .idea & .iml project files - id 'idea' +// id 'idea' } apply plugin: 'java' apply plugin: 'com.google.protobuf' -def grpcVersion = '1.58.0' // CURRENT_GRPC_VERSION -def protocVersion = '3.22.3' +sourceSets { + + main { + java { + srcDirs 'build/generated/source/proto/main/grpc' + srcDirs 'build/generated/source/proto/main/java' + } + } + + java9 { + java { + srcDirs = ['src/main/jdk1.9'] + } + } +} dependencies { implementation project(':core') @@ -30,18 +34,69 @@ dependencies { implementation project(':pkix') implementation project(':prov') - implementation "io.grpc:grpc-protobuf:${grpcVersion}" - implementation "io.grpc:grpc-services:${grpcVersion}" - implementation "io.grpc:grpc-stub:${grpcVersion}" - compileOnly "org.apache.tomcat:annotations-api:6.0.53" - runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}" + //Provided + implementation(files("../test/libs/annotations-api-6.0.53.jar")) +// implementation(files("../test/libs/protobuf-java-util-3.22.3.jar")) + implementation(files("../test/libs/guava-32.0.1-android.jar")) + implementation(files("../test/libs/grpc-stub-1.58.0.jar")) + implementation(files("../test/libs/protobuf-java-3.22.3.jar")) + implementation(files("../test/libs/grpc-api-1.58.0.jar")) + implementation(files("../test/libs/grpc-protobuf-lite-1.58.0.jar")) + implementation(files("../test/libs/failureaccess-1.0.1.jar")) + implementation(files("../test/libs/grpc-protobuf-1.58.0.jar")) - implementation "com.google.protobuf:protobuf-java-util:${protocVersion}" + //Compile + compileOnly(files("../test/libs/grpc-services-1.58.0.jar")) + + //Runtime + runtimeOnly(files("../test/libs/grpc-netty-shaded-1.58.0.jar")) + runtimeOnly(files("../test/libs/grpc-core-1.58.0.jar")) + runtimeOnly(files("../test/libs/perfmark-api-0.26.0.jar")) + + //Download jars online +// implementation "io.grpc:grpc-protobuf:${grpcVersion}" +// implementation "io.grpc:grpc-services:${grpcVersion}" +// implementation "io.grpc:grpc-stub:${grpcVersion}" +// compileOnly "org.apache.tomcat:annotations-api:6.0.53" +// runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}" +// implementation "com.google.protobuf:protobuf-java-util:${protocVersion}" + + java9Implementation files("$bc_prov") + java9Implementation files("$bc_util") + java9Implementation files("$bc_pkix") + java9Implementation files(sourceSets.main.output.classesDirs) { + builtBy compileJava + } +} + +def grpcVersion = '1.58.0' // CURRENT_GRPC_VERSION +def protocVersion = '3.22.3' + + +checkstyleMain { + source = fileTree('src/main/java') } compileJava { + sourceCompatibility = 1.8 + targetCompatibility = 1.8 + options.errorprone.disableWarningsInGeneratedCode = true - options.errorprone.errorproneArgs = [ "-Xep:IgnoredPureGetter:OFF"] + options.errorprone.errorproneArgs = ["-Xep:IgnoredPureGetter:OFF"] + options.errorprone.errorproneArgs.add("-XepExcludedPaths:.*/build/generated/.*") +} + +compileJava9Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + sourceCompatibility = 9 + targetCompatibility = 9 + options.compilerArgs += [ + '--module-path', "${bc_prov}${File.pathSeparator}${bc_util}${File.pathSeparator}${bc_pkix}" + ] + + options.sourcepath = files(['src/main/java', 'src/main/jdk1.9']) } protobuf { @@ -60,21 +115,12 @@ protobuf { } } -sourceSets { - main { - java { - srcDirs 'build/generated/source/proto/main/grpc' - srcDirs 'build/generated/source/proto/main/java' - } - } -} +jar.archiveBaseName = "bcmls-$vmrange" + startScripts.enabled = false -// Creates start scripts for a class name and adds it to the distribution. The -// base class name is used to name the task and scripts. For example, passed -// the class io.grpc.examples.helloworld.HelloWorldClient, it creates the task -// helloWorldClient with script name hello-world-client. +// Creates start scripts for a class name and adds it to the distribution. def createStartScripts(String mainClassName) { String bareName = mainClassName.substring(mainClassName.lastIndexOf('.') + 1); String taskName = bareName.uncapitalize(); @@ -92,6 +138,52 @@ def createStartScripts(String mainClassName) { } } +extractIncludeProto { + dependsOn(":prov:jar",":util:jar") +} + +extractIncludeTestProto { + dependsOn(":prov:jar",":util:jar") +} + createStartScripts('org.bouncycastle.mls.client.impl.MLSClient') -createStartScripts('io.grpc.examples.helloworld.HelloWorldClient') -createStartScripts('io.grpc.examples.helloworld.HelloWorldServer') \ No newline at end of file + +jar { + from sourceSets.main.output + into('META-INF/versions/9') { + from sourceSets.java9.output + } + + String packages = 'org.bouncycastle.mls.*' + String v = "${rootProject.extensions.ext.bundle_version}" + manifest.attributes('Multi-Release': 'true') + manifest.attributes('Bundle-Name': 'bcmls') + manifest.attributes('Bundle-SymbolicName': 'bcmls') + manifest.attributes('Bundle-RequiredExecutionEnvironment': 'JavaSE-1.8') + manifest.attributes('Export-Package': "${packages};version=${v}") + manifest.attributes('Import-Package': "java.*;resolution:=optional,javax.*;resolution:=optional,!${packages},org.bouncycastle.*;version=\"[${v},${maxVersion})\"") + manifest.attributes('Bundle-Version': "${v}") +} + +task sourcesJar(type: Jar) { + archiveBaseName = jar.archiveBaseName + archiveClassifier = 'sources' + from sourceSets.main.allSource + duplicatesStrategy = DuplicatesStrategy.INCLUDE + into('META-INF/versions/9') { + from sourceSets.java9.allSource + } +} + + +task javadocJar(type: Jar, dependsOn: javadoc) { + archiveBaseName = jar.archiveBaseName + archiveClassifier = 'javadoc' + from javadoc.destinationDir +} + +artifacts { + archives jar + archives javadocJar + archives sourcesJar +} diff --git a/mls/src/main/java/org/bouncycastle/mls/GroupKeySet.java b/mls/src/main/java/org/bouncycastle/mls/GroupKeySet.java index 9d52c61e5f..297f8dcda0 100644 --- a/mls/src/main/java/org/bouncycastle/mls/GroupKeySet.java +++ b/mls/src/main/java/org/bouncycastle/mls/GroupKeySet.java @@ -1,11 +1,5 @@ package org.bouncycastle.mls; -import org.bouncycastle.mls.TreeKEM.LeafIndex; -import org.bouncycastle.mls.TreeKEM.NodeIndex; -import org.bouncycastle.mls.codec.ContentType; -import org.bouncycastle.mls.crypto.MlsCipherSuite; -import org.bouncycastle.mls.crypto.Secret; - import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.InvalidParameterException; @@ -13,7 +7,14 @@ import java.util.List; import java.util.Map; -public class GroupKeySet { +import org.bouncycastle.mls.TreeKEM.LeafIndex; +import org.bouncycastle.mls.TreeKEM.NodeIndex; +import org.bouncycastle.mls.codec.ContentType; +import org.bouncycastle.mls.crypto.MlsCipherSuite; +import org.bouncycastle.mls.crypto.Secret; + +public class GroupKeySet +{ final MlsCipherSuite suite; final int secretSize; // We store a commitment to the encryption secret that was used to create this structure, so that we can compare @@ -25,24 +26,35 @@ public class GroupKeySet { Map applicationRatchets; - public GroupKeySet(MlsCipherSuite suite, TreeSize treeSize, Secret encryptionSecret) throws IOException, IllegalAccessException { + public GroupKeySet(MlsCipherSuite suite, TreeSize treeSize, Secret encryptionSecret) + throws IOException, IllegalAccessException + { this.suite = suite; this.secretSize = suite.getKDF().getHashLength(); this.encryptionSecretCommit = encryptionSecret.deriveSecret(suite, "commitment"); this.secretTree = new SecretTree(treeSize, encryptionSecret); - this.handshakeRatchets = new HashMap<>(); - this.applicationRatchets = new HashMap<>(); + this.handshakeRatchets = new HashMap(); + this.applicationRatchets = new HashMap(); } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GroupKeySet that = (GroupKeySet) o; + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + GroupKeySet that = (GroupKeySet)o; return secretSize == that.secretSize && suite.equals(that.suite) && encryptionSecretCommit.equals(that.encryptionSecretCommit); } - void initRatchets(LeafIndex sender) throws IOException, IllegalAccessException { + void initRatchets(LeafIndex sender) + throws IOException, IllegalAccessException + { Secret leafSecret = secretTree.get(sender); Secret handshakeRatchetSecret = leafSecret.expandWithLabel(suite, "handshake", new byte[]{}, secretSize); @@ -55,48 +67,52 @@ void initRatchets(LeafIndex sender) throws IOException, IllegalAccessException { applicationRatchets.put(sender, applicationRatchet); } - public KeyGeneration get(ContentType contentType, LeafIndex sender, int generation, byte[] reuseGuard) throws IOException, IllegalAccessException + public KeyGeneration get(ContentType contentType, LeafIndex sender, int generation, byte[] reuseGuard) + throws IOException, IllegalAccessException { HashRatchet chain; switch (contentType) { - case APPLICATION: - chain = applicationRatchet(sender); - break; - case PROPOSAL: - case COMMIT: - chain = handshakeRatchet(sender); - break; - default: - return null; + case APPLICATION: + chain = applicationRatchet(sender); + break; + case PROPOSAL: + case COMMIT: + chain = handshakeRatchet(sender); + break; + default: + return null; } KeyGeneration keys = chain.get(generation); ApplyReuseGuard(reuseGuard, keys.nonce); return keys; } - public KeyGeneration get(ContentType contentType, LeafIndex sender, byte[] reuseGuard) throws IOException, IllegalAccessException + + public KeyGeneration get(ContentType contentType, LeafIndex sender, byte[] reuseGuard) + throws IOException, IllegalAccessException { HashRatchet chain; switch (contentType) { - case APPLICATION: - chain = applicationRatchet(sender); - break; - case PROPOSAL: - case COMMIT: - chain = handshakeRatchet(sender); - break; - default: - return null; + case APPLICATION: + chain = applicationRatchet(sender); + break; + case PROPOSAL: + case COMMIT: + chain = handshakeRatchet(sender); + break; + default: + return null; } KeyGeneration keys = chain.next(); ApplyReuseGuard(reuseGuard, keys.nonce); return keys; } + private void ApplyReuseGuard(byte[] guard, byte[] nonce) { for (int i = 0; i < guard.length; i++) @@ -105,30 +121,37 @@ private void ApplyReuseGuard(byte[] guard, byte[] nonce) } } - public void erase(ContentType contentType, LeafIndex sender, int generation) throws IOException, IllegalAccessException + public void erase(ContentType contentType, LeafIndex sender, int generation) + throws IOException, IllegalAccessException { switch (contentType) { - case APPLICATION: - applicationRatchet(sender).erase(generation); - break; - case PROPOSAL: - case COMMIT: - handshakeRatchet(sender).erase(generation); - break; + case APPLICATION: + applicationRatchet(sender).erase(generation); + break; + case PROPOSAL: + case COMMIT: + handshakeRatchet(sender).erase(generation); + break; } } - public HashRatchet handshakeRatchet(LeafIndex sender) throws IOException, IllegalAccessException { - if (!handshakeRatchets.containsKey(sender)) { + public HashRatchet handshakeRatchet(LeafIndex sender) + throws IOException, IllegalAccessException + { + if (!handshakeRatchets.containsKey(sender)) + { initRatchets(sender); } return handshakeRatchets.get(sender); } - public HashRatchet applicationRatchet(LeafIndex sender) throws IOException, IllegalAccessException { - if (!applicationRatchets.containsKey(sender)) { + public HashRatchet applicationRatchet(LeafIndex sender) + throws IOException, IllegalAccessException + { + if (!applicationRatchets.containsKey(sender)) + { initRatchets(sender); } return applicationRatchets.get(sender); @@ -147,7 +170,7 @@ public class SecretTree public SecretTree(TreeSize treeSizeIn, Secret encryptionSecret) { treeSize = treeSizeIn; - secrets = new HashMap<>(); + secrets = new HashMap(); secrets.put(NodeIndex.root(treeSize), encryptionSecret); } @@ -156,7 +179,9 @@ protected boolean hasLeaf(LeafIndex sender) return sender.value() < treeSize.leafCount(); } - public Secret get(LeafIndex leaf) throws IOException, IllegalAccessException { + public Secret get(LeafIndex leaf) + throws IOException, IllegalAccessException + { final byte[] leftLabel = "left".getBytes(StandardCharsets.UTF_8); final byte[] rightLabel = "right".getBytes(StandardCharsets.UTF_8); @@ -169,18 +194,22 @@ public Secret get(LeafIndex leaf) throws IOException, IllegalAccessException { dirpath.add(0, leafNode); dirpath.add(rootNode); int curr = 0; - for (; curr < dirpath.size(); curr++) { - if (secrets.containsKey(dirpath.get(curr))) { + for (; curr < dirpath.size(); curr++) + { + if (secrets.containsKey(dirpath.get(curr))) + { break; } } - if (curr > dirpath.size()) { + if (curr > dirpath.size()) + { throw new InvalidParameterException("No secret found to derive leaf key"); } // Derive down - for (; curr > 0; curr--) { + for (; curr > 0; curr--) + { NodeIndex currNode = dirpath.get(curr); NodeIndex left = currNode.left(); NodeIndex right = currNode.right(); @@ -194,12 +223,15 @@ public Secret get(LeafIndex leaf) throws IOException, IllegalAccessException { Secret leafSecret = secrets.get(leafNode); // Forget the secrets along the direct path - for (NodeIndex i : dirpath) { - if (i.equals(leafNode)) { + for (NodeIndex i : dirpath) + { + if (i.equals(leafNode)) + { continue; } - if (secrets.containsKey(i)) { + if (secrets.containsKey(i)) + { secrets.get(i).consume(); secrets.remove(i); } @@ -209,22 +241,26 @@ public Secret get(LeafIndex leaf) throws IOException, IllegalAccessException { } } - public class HashRatchet { + public class HashRatchet + { final int keySize; final int nonceSize; Secret nextSecret; int nextGeneration; Map cache; - HashRatchet(Secret baseSecret) { + HashRatchet(Secret baseSecret) + { keySize = suite.getAEAD().getKeySize(); nonceSize = suite.getAEAD().getNonceSize(); nextGeneration = 0; nextSecret = baseSecret; - cache = new HashMap<>(); + cache = new HashMap(); } - public KeyGeneration next() throws IOException, IllegalAccessException { + public KeyGeneration next() + throws IOException, IllegalAccessException + { Secret key = nextSecret.deriveTreeSecret(suite, "key", nextGeneration, keySize); Secret nonce = nextSecret.deriveTreeSecret(suite, "nonce", nextGeneration, nonceSize); Secret secret = nextSecret.deriveTreeSecret(suite, "secret", nextGeneration, secretSize); @@ -239,24 +275,31 @@ public KeyGeneration next() throws IOException, IllegalAccessException { return generation; } - public KeyGeneration get(int generation) throws IOException, IllegalAccessException { - if (cache.containsKey(generation)) { + public KeyGeneration get(int generation) + throws IOException, IllegalAccessException + { + if (cache.containsKey(generation)) + { return cache.get(generation); } - if (nextGeneration > generation) { + if (nextGeneration > generation) + { throw new InvalidParameterException("Request for expired key"); } - while (nextGeneration < generation) { + while (nextGeneration < generation) + { next(); } return next(); } - public void erase(int generation) { - if (cache.containsKey(generation)) { + public void erase(int generation) + { + if (cache.containsKey(generation)) + { cache.get(generation).consume(); cache.remove(generation); } diff --git a/mls/src/main/java/org/bouncycastle/mls/KeyGeneration.java b/mls/src/main/java/org/bouncycastle/mls/KeyGeneration.java index 3dedaa29ad..84e4ddf7b5 100644 --- a/mls/src/main/java/org/bouncycastle/mls/KeyGeneration.java +++ b/mls/src/main/java/org/bouncycastle/mls/KeyGeneration.java @@ -1,15 +1,17 @@ package org.bouncycastle.mls; -import org.bouncycastle.mls.crypto.Secret; - import java.util.Arrays; -public class KeyGeneration { +import org.bouncycastle.mls.crypto.Secret; + +public class KeyGeneration +{ public final int generation; public final byte[] key; public final byte[] nonce; - public KeyGeneration(int generation, Secret key, Secret nonce) { + public KeyGeneration(int generation, Secret key, Secret nonce) + { this.generation = generation; this.key = key.value().clone(); this.nonce = nonce.value().clone(); @@ -19,15 +21,23 @@ public KeyGeneration(int generation, Secret key, Secret nonce) { } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - KeyGeneration that = (KeyGeneration) o; + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + KeyGeneration that = (KeyGeneration)o; return generation == that.generation && Arrays.equals(key, that.key) && Arrays.equals(nonce, that.nonce); } - void consume() { - Arrays.fill(key, (byte) 0); - Arrays.fill(nonce, (byte) 0); + void consume() + { + Arrays.fill(key, (byte)0); + Arrays.fill(nonce, (byte)0); } } diff --git a/mls/src/main/java/org/bouncycastle/mls/KeyScheduleEpoch.java b/mls/src/main/java/org/bouncycastle/mls/KeyScheduleEpoch.java index aaa56f0d91..1b09b2d9d6 100644 --- a/mls/src/main/java/org/bouncycastle/mls/KeyScheduleEpoch.java +++ b/mls/src/main/java/org/bouncycastle/mls/KeyScheduleEpoch.java @@ -1,33 +1,37 @@ package org.bouncycastle.mls; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.List; + import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.hpke.HPKEContext; import org.bouncycastle.crypto.hpke.HPKEContextWithEncapsulation; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.mls.codec.MLSOutputStream; +import org.bouncycastle.mls.codec.PreSharedKeyID; import org.bouncycastle.mls.crypto.MlsCipherSuite; import org.bouncycastle.mls.crypto.Secret; -import org.bouncycastle.mls.codec.PreSharedKeyID; import org.bouncycastle.util.Arrays; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.List; - -public class KeyScheduleEpoch { - public static class PSKWithSecret { +public class KeyScheduleEpoch +{ + public static class PSKWithSecret + { public PreSharedKeyID id; public Secret secret; - public PSKWithSecret(PreSharedKeyID id, Secret secret) { + public PSKWithSecret(PreSharedKeyID id, Secret secret) + { this.id = id; this.secret = secret; } } - public byte[] receiveExternalInit(byte[] kemOut) throws IOException + public byte[] receiveExternalInit(byte[] kemOut) + throws IOException { // do export (private key) final int L = suite.getKDF().getHashLength(); @@ -37,7 +41,8 @@ public byte[] receiveExternalInit(byte[] kemOut) throws IOException return ctx.export(labelData, L); } - public static class JoinSecrets { + public static class JoinSecrets + { // Cached values private final MlsCipherSuite suite; // Public values @@ -48,19 +53,24 @@ public static class JoinSecrets { public Secret welcomeNonce; private Secret memberSecret; // Held to derive further secrets - static class PSKLabel implements MLSOutputStream.Writable { + static class PSKLabel + implements MLSOutputStream.Writable + { PreSharedKeyID id; short index; short count; - public PSKLabel(PreSharedKeyID id, short index, short count) { + public PSKLabel(PreSharedKeyID id, short index, short count) + { this.id = id; this.index = index; this.count = count; } @Override - public void writeTo(MLSOutputStream stream) throws IOException { + public void writeTo(MLSOutputStream stream) + throws IOException + { stream.write(id); stream.write(index); stream.write(count); @@ -83,15 +93,19 @@ public void writeTo(MLSOutputStream stream) throws IOException { V V psk_[n-1] --> Extract --> ExpandWithLabel --> Extract = psk_secret_[n] */ - public static Secret pskSecret(MlsCipherSuite suite, List psks) throws IOException { + public static Secret pskSecret(MlsCipherSuite suite, List psks) + throws IOException + { Secret pskSecret = Secret.zero(suite); - if (psks == null || psks.isEmpty()) { + if (psks == null || psks.isEmpty()) + { return pskSecret; } short index = 0; - short count = (short) psks.size(); - for (PSKWithSecret psk : psks) { + short count = (short)psks.size(); + for (PSKWithSecret psk : psks) + { PSKLabel label = new PSKLabel(psk.id, index, count); byte[] pskLabel = MLSOutputStream.encode(label); index += 1; @@ -120,16 +134,11 @@ public static Secret pskSecret(MlsCipherSuite suite, List psks) t joiner_secret */ -// public static JoinSecrets forMember(CipherSuite suite, Secret initSecret, Secret commitSecret, List psks, byte[] context) throws IOException -// { -// Secret preJoinerSecret = Secret.extract(suite, initSecret, commitSecret); -// Secret joinerSecret = preJoinerSecret.expandWithLabel(suite, "joiner", context, suite.getKDF().getHashLength()); -// return new JoinSecrets(suite, joinerSecret, psks); -// } - // todo change to - public static JoinSecrets forMember(MlsCipherSuite suite, Secret initSecret, Secret commitSecret, Secret pskSecret, byte[] context) throws IOException { + public static JoinSecrets forMember(MlsCipherSuite suite, Secret initSecret, Secret commitSecret, Secret pskSecret, byte[] context) + throws IOException + { Secret preJoinerSecret = Secret.extract(suite, initSecret, commitSecret); - Secret joinerSecret = preJoinerSecret.expandWithLabel(suite,"joiner", context, suite.getKDF().getHashLength()); + Secret joinerSecret = preJoinerSecret.expandWithLabel(suite, "joiner", context, suite.getKDF().getHashLength()); return new JoinSecrets(suite, joinerSecret, pskSecret); } @@ -151,7 +160,9 @@ public static JoinSecrets forMember(MlsCipherSuite suite, Secret initSecret, Sec V epoch_secret */ - public JoinSecrets(MlsCipherSuite suite, Secret joinerSecret, List psks) throws IOException { + public JoinSecrets(MlsCipherSuite suite, Secret joinerSecret, List psks) + throws IOException + { this.suite = suite; this.joinerSecret = joinerSecret; this.memberSecret = Secret.extract(suite, joinerSecret, pskSecret(suite, psks)); @@ -161,7 +172,10 @@ public JoinSecrets(MlsCipherSuite suite, Secret joinerSecret, List psk) throws IOException + public static Secret welcomeSecret(MlsCipherSuite suite, byte[] joinerSecret, List psk) + throws IOException { Secret pskSecret = JoinSecrets.pskSecret(suite, psk); Secret extract = new Secret(suite.getKDF().extract(joinerSecret, pskSecret.value())); return extract.deriveSecret(suite, "welcome"); } - public static KeyScheduleEpoch forCreator(MlsCipherSuite suite, byte[] groupContext) throws IOException, IllegalAccessException + + public static KeyScheduleEpoch forCreator(MlsCipherSuite suite, byte[] groupContext) + throws IOException, IllegalAccessException { SecureRandom random = new SecureRandom(); byte[] initSecret = new byte[suite.getKDF().getHashLength()]; @@ -276,26 +300,35 @@ public static KeyScheduleEpoch forCreator(MlsCipherSuite suite, byte[] groupCont JoinSecrets joinerSecret = JoinSecrets.forMember(suite, new Secret(initSecret), Secret.zero(suite), new Secret(new byte[0]), groupContext); // TreeSize size = TreeSize.forLeaves(1); // return joinerSecret.complete(size, groupContext); - return KeyScheduleEpoch.joiner(suite, joinerSecret.joinerSecret.value(), new ArrayList<>(), groupContext); + return KeyScheduleEpoch.joiner(suite, joinerSecret.joinerSecret.value(), new ArrayList(), groupContext); } - public static KeyScheduleEpoch forCreator(MlsCipherSuite suite) throws IOException, IllegalAccessException { + + public static KeyScheduleEpoch forCreator(MlsCipherSuite suite) + throws IOException, IllegalAccessException + { SecureRandom rng = new SecureRandom(); return forCreator(suite, rng); } + public static KeyScheduleEpoch forCreator(MlsCipherSuite suite, SecureRandom rng) - throws IOException, IllegalAccessException { + throws IOException, IllegalAccessException + { byte[] epochSecret = new byte[suite.getKDF().getHashLength()]; rng.nextBytes(epochSecret); TreeSize treeSize = TreeSize.forLeaves(1); return new KeyScheduleEpoch(suite, treeSize, new Secret(epochSecret)); } - public static KeyScheduleEpoch forExternalJoiner(MlsCipherSuite suite, TreeSize treeSize, ExternalInitParams externalInitParams, Secret commitSecret, List psks, byte[] context) throws IOException, IllegalAccessException { - return JoinSecrets.forMember(suite, externalInitParams.initSecret, commitSecret, JoinSecrets.pskSecret(suite, psks), context).complete(treeSize, context); //TODO external: pskSecret OR new byte [0] + public static KeyScheduleEpoch forExternalJoiner(MlsCipherSuite suite, TreeSize treeSize, ExternalInitParams externalInitParams, Secret commitSecret, List psks, byte[] context) + throws IOException, IllegalAccessException + { + return JoinSecrets.forMember(suite, externalInitParams.initSecret, commitSecret, JoinSecrets.pskSecret(suite, psks), context).complete(treeSize, context); } - public JoinSecrets startCommit(Secret commitSecret, List psks, byte[] context) throws IOException { - return JoinSecrets.forMember(suite, initSecret, commitSecret, JoinSecrets.pskSecret(suite, psks), context);//TODO: pskSecret OR new byte [0] + public JoinSecrets startCommit(Secret commitSecret, List psks, byte[] context) + throws IOException + { + return JoinSecrets.forMember(suite, initSecret, commitSecret, JoinSecrets.pskSecret(suite, psks), context); } /* @@ -340,7 +373,8 @@ public KeyScheduleEpoch copy() return new KeyScheduleEpoch(suite, initSecret, senderDataSecret, exporterSecret, confirmationKey, membershipKey, resumptionPSK, epochAuthenticator, encryptionSecret, externalSecret, externalKeyPair, groupKeySet, joinerSecret); } - public static KeyScheduleEpoch joiner(MlsCipherSuite suite, byte[] joinerSecret, List psks, byte[] context) throws IOException, IllegalAccessException + public static KeyScheduleEpoch joiner(MlsCipherSuite suite, byte[] joinerSecret, List psks, byte[] context) + throws IOException, IllegalAccessException { TreeSize size = TreeSize.forLeaves(1); JoinSecrets joinSecrets = new JoinSecrets(suite, new Secret(joinerSecret), psks); @@ -349,7 +383,8 @@ public static KeyScheduleEpoch joiner(MlsCipherSuite suite, byte[] joinerSecret, } // ONLY USED BY EXTERNAL JOINER - public KeyScheduleEpoch(MlsCipherSuite suite) throws IOException, IllegalAccessException + public KeyScheduleEpoch(MlsCipherSuite suite) + throws IOException, IllegalAccessException { this.suite = suite; this.initSecret = new Secret(new byte[0]); @@ -364,7 +399,10 @@ public KeyScheduleEpoch(MlsCipherSuite suite) throws IOException, IllegalAccessE this.encryptionSecret = new Secret(new byte[0]); this.groupKeySet = null; } - public KeyScheduleEpoch(MlsCipherSuite suite, TreeSize treeSize, Secret epochSecret) throws IOException, IllegalAccessException { + + public KeyScheduleEpoch(MlsCipherSuite suite, TreeSize treeSize, Secret epochSecret) + throws IOException, IllegalAccessException + { this.suite = suite; this.initSecret = epochSecret.deriveSecret(suite, "init"); this.senderDataSecret = epochSecret.deriveSecret(suite, "sender data"); @@ -381,7 +419,9 @@ public KeyScheduleEpoch(MlsCipherSuite suite, TreeSize treeSize, Secret epochSec this.groupKeySet = new GroupKeySet(suite, treeSize, encryptionSecret); } - public KeyScheduleEpoch(MlsCipherSuite suite, TreeSize treeSize, Secret joinerSecret, Secret pskSecret, byte[] context) throws IOException, IllegalAccessException { + public KeyScheduleEpoch(MlsCipherSuite suite, TreeSize treeSize, Secret joinerSecret, Secret pskSecret, byte[] context) + throws IOException, IllegalAccessException + { this.suite = suite; Secret memSecret = Secret.extract(suite, joinerSecret, pskSecret); @@ -403,10 +443,12 @@ public KeyScheduleEpoch(MlsCipherSuite suite, TreeSize treeSize, Secret joinerSe } - public KeyScheduleEpoch next(TreeSize treeSize, byte[] externalInit, Secret commitSecret, List psks, byte[] context) throws IOException, IllegalAccessException + public KeyScheduleEpoch next(TreeSize treeSize, byte[] externalInit, Secret commitSecret, List psks, byte[] context) + throws IOException, IllegalAccessException { Secret currInitSecret = initSecret; - if (externalInit != null) { + if (externalInit != null) + { currInitSecret = new Secret(externalInit); } @@ -414,22 +456,31 @@ public KeyScheduleEpoch next(TreeSize treeSize, byte[] externalInit, Secret comm return joinSecrets.complete(treeSize, context); } - public byte[] MLSExporter(String label, byte[] context, int length) throws IOException + public byte[] MLSExporter(String label, byte[] context, int length) + throws IOException { - return exporterSecret.deriveSecret(suite, label).expandWithLabel(suite, "exported", suite.hash(context), length).value(); + return exporterSecret.deriveSecret(suite, label).expandWithLabel(suite, "exported", suite.hash(context), length).value(); } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - KeyScheduleEpoch that = (KeyScheduleEpoch) o; + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + KeyScheduleEpoch that = (KeyScheduleEpoch)o; // XXX(RLB): There no easy way to compare externalKeyPair values, so we skip that. // XXX(RLB): In general, we could probably be more parsimonious here. return suite.equals(that.suite) && initSecret.equals(that.initSecret) && senderDataSecret.equals(that.senderDataSecret) && exporterSecret.equals(that.exporterSecret) && confirmationKey.equals(that.confirmationKey) && membershipKey.equals(that.membershipKey) && resumptionPSK.equals(that.resumptionPSK) && epochAuthenticator.equals(that.epochAuthenticator) && groupKeySet.equals(that.groupKeySet); } - public AsymmetricKeyParameter getExternalPublicKey() { + public AsymmetricKeyParameter getExternalPublicKey() + { return externalKeyPair.getPublic(); } } diff --git a/mls/src/main/java/org/bouncycastle/mls/TranscriptHash.java b/mls/src/main/java/org/bouncycastle/mls/TranscriptHash.java index 6f853b1f2b..f4433be57d 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TranscriptHash.java +++ b/mls/src/main/java/org/bouncycastle/mls/TranscriptHash.java @@ -1,12 +1,12 @@ package org.bouncycastle.mls; +import java.io.IOException; + import org.bouncycastle.mls.codec.AuthenticatedContent; import org.bouncycastle.mls.codec.MLSOutputStream; import org.bouncycastle.mls.crypto.MlsCipherSuite; import org.bouncycastle.util.Arrays; -import java.io.IOException; - public class TranscriptHash { @@ -42,35 +42,43 @@ public TranscriptHash(MlsCipherSuite suite, byte[] confirmed, byte[] interim) this.interim = interim; } - static public TranscriptHash fromConfirmationTag(MlsCipherSuite suite, byte[] confirmed, byte[] confirmationTag) throws IOException + static public TranscriptHash fromConfirmationTag(MlsCipherSuite suite, byte[] confirmed, byte[] confirmationTag) + throws IOException { TranscriptHash out = new TranscriptHash(suite, confirmed.clone(), new byte[0]); out.updateInterim(confirmationTag); return out; } + public TranscriptHash copy() { return new TranscriptHash(suite, confirmed, interim); } - public void update(AuthenticatedContent auth) throws IOException + public void update(AuthenticatedContent auth) + throws IOException { updateConfirmed(auth); updateInterim(auth); } - public void updateConfirmed(AuthenticatedContent auth) throws IOException + public void updateConfirmed(AuthenticatedContent auth) + throws IOException { byte[] transcript = Arrays.concatenate(interim, auth.getConfirmedTranscriptHashInput()); confirmed = suite.hash(transcript); } - public void updateInterim(AuthenticatedContent auth) throws IOException + + public void updateInterim(AuthenticatedContent auth) + throws IOException { byte[] transcript = Arrays.concatenate(confirmed, auth.getInterimTranscriptHashInput()); interim = suite.hash(transcript); } - public void updateInterim(byte[] confirmationTag) throws IOException + + public void updateInterim(byte[] confirmationTag) + throws IOException { MLSOutputStream stream = new MLSOutputStream(); stream.writeOpaque(confirmationTag); diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafIndex.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafIndex.java index 4e7b8ad9e1..cb0be1adb1 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafIndex.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafIndex.java @@ -1,61 +1,68 @@ package org.bouncycastle.mls.TreeKEM; -import org.bouncycastle.mls.TreeSize; -import org.bouncycastle.mls.codec.MLSInputStream; -import org.bouncycastle.mls.codec.MLSOutputStream; - import java.io.IOException; -import java.util.Objects; import java.util.List; +import java.util.Objects; import java.util.Vector; +import org.bouncycastle.mls.TreeSize; +import org.bouncycastle.mls.codec.MLSInputStream; +import org.bouncycastle.mls.codec.MLSOutputStream; + public class LeafIndex - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { protected int value; - - - //TODO: make a setter for value - //TODO: make this an int not a long? - public int value() { + public int value() + { return value; } - public LeafIndex(int valueIn) { + public LeafIndex(int valueIn) + { value = valueIn; } - public LeafIndex(NodeIndex valueIn) { - value = (int) (valueIn.value() >>> 1); + + public LeafIndex(NodeIndex valueIn) + { + value = (int)(valueIn.value() >>> 1); } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object o) + { + if (this == o) + { return true; } - if (o == null || getClass() != o.getClass()) { + if (o == null || getClass() != o.getClass()) + { return false; } - LeafIndex leafIndex = (LeafIndex) o; + LeafIndex leafIndex = (LeafIndex)o; return value == leafIndex.value; } @Override - public int hashCode() { + public int hashCode() + { return Objects.hash(value); } - public NodeIndex commonAncestor(LeafIndex other) { - if (this.equals(other)) { + public NodeIndex commonAncestor(LeafIndex other) + { + if (this.equals(other)) + { return new NodeIndex(this); } long k = 0; long xv = (new NodeIndex(this)).value(); long yv = (new NodeIndex(other)).value(); - while (xv != yv) { + while (xv != yv) + { xv >>= 1; yv >>= 1; k += 1; @@ -63,26 +70,30 @@ public NodeIndex commonAncestor(LeafIndex other) { long prefix = xv << k; long stop = (1L << (k - 1)); - return new NodeIndex( prefix + stop - 1); + return new NodeIndex(prefix + stop - 1); } - public List directPath(TreeSize size) { - List d = new Vector<>(); + public List directPath(TreeSize size) + { + List d = new Vector(); NodeIndex n = new NodeIndex(this); NodeIndex r = NodeIndex.root(size); - if (n.equals(r)) { + if (n.equals(r)) + { return d; } NodeIndex p = n.parent(); - while (!p.equals(r)) { + while (!p.equals(r)) + { d.add(p); p = p.parent(); } // Include the root unless this is a one-member tree - if (!n.equals(r)) { + if (!n.equals(r)) + { d.add(p); } @@ -90,12 +101,15 @@ public List directPath(TreeSize size) { } @SuppressWarnings("unused") - public LeafIndex(MLSInputStream stream) throws IOException + public LeafIndex(MLSInputStream stream) + throws IOException { - value = (int) stream.read(int.class); + value = (int)stream.read(int.class); } + @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(value); } diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafNode.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafNode.java index 38fcf0c8ba..78e825e507 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafNode.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafNode.java @@ -1,21 +1,21 @@ package org.bouncycastle.mls.TreeKEM; -import org.bouncycastle.mls.crypto.MlsCipherSuite; -import org.bouncycastle.mls.protocol.Group; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import org.bouncycastle.mls.codec.Capabilities; import org.bouncycastle.mls.codec.Credential; import org.bouncycastle.mls.codec.CredentialType; import org.bouncycastle.mls.codec.Extension; import org.bouncycastle.mls.codec.MLSInputStream; import org.bouncycastle.mls.codec.MLSOutputStream; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import org.bouncycastle.mls.crypto.MlsCipherSuite; +import org.bouncycastle.mls.protocol.Group; public class LeafNode - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { MlsCipherSuite suite; byte[] encryption_key; @@ -68,14 +68,15 @@ public List getExtensions() } public LeafNode( - MlsCipherSuite suite, - byte[] encryption_key, - byte[] signature_key, - Credential credential, - Capabilities capabilities, - LifeTime lifeTime, - List extensions, - byte[] sigSk) throws Exception + MlsCipherSuite suite, + byte[] encryption_key, + byte[] signature_key, + Credential credential, + Capabilities capabilities, + LifeTime lifeTime, + List extensions, + byte[] sigSk) + throws Exception { this.suite = suite; this.encryption_key = encryption_key; @@ -83,7 +84,7 @@ public LeafNode( this.credential = credential; this.capabilities = capabilities; //TODO: grease this.lifeTime = lifeTime; - this.extensions = new ArrayList<>(extensions); //TODO: grease + this.extensions = new ArrayList(extensions); //TODO: grease this.leaf_node_source = LeafNodeSource.KEY_PACKAGE; //TODO: check sign(suite, sigSk, toBeSigned(null, -1)); @@ -93,31 +94,33 @@ public LeafNode() { } - public LeafNode(MLSInputStream stream) throws IOException + public LeafNode(MLSInputStream stream) + throws IOException { encryption_key = stream.readOpaque(); signature_key = stream.readOpaque(); - credential = (Credential) stream.read(Credential.class); - capabilities = (Capabilities) stream.read(Capabilities.class); - leaf_node_source = LeafNodeSource.values()[(byte) stream.read(byte.class)]; + credential = (Credential)stream.read(Credential.class); + capabilities = (Capabilities)stream.read(Capabilities.class); + leaf_node_source = LeafNodeSource.values()[(byte)stream.read(byte.class)]; switch (leaf_node_source) { - case KEY_PACKAGE: - lifeTime = (LifeTime) stream.read(LifeTime.class); - break; - case UPDATE: - break; - case COMMIT: - parent_hash = stream.readOpaque(); - break; + case KEY_PACKAGE: + lifeTime = (LifeTime)stream.read(LifeTime.class); + break; + case UPDATE: + break; + case COMMIT: + parent_hash = stream.readOpaque(); + break; } - extensions = new ArrayList<>(); + extensions = new ArrayList(); stream.readList(extensions, Extension.class); signature = stream.readOpaque(); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(encryption_key); stream.writeOpaque(signature_key); @@ -126,14 +129,14 @@ public void writeTo(MLSOutputStream stream) throws IOException stream.write(leaf_node_source); switch (leaf_node_source) { - case KEY_PACKAGE: - stream.write(lifeTime); - break; - case UPDATE: - break; - case COMMIT: - stream.writeOpaque(parent_hash); - break; + case KEY_PACKAGE: + stream.write(lifeTime); + break; + case UPDATE: + break; + case COMMIT: + stream.writeOpaque(parent_hash); + break; } stream.writeList(extensions); stream.writeOpaque(signature); @@ -148,7 +151,9 @@ public Credential getCredential() { return credential; } - public byte[] toBeSigned(byte[] groupId, int leafIndex) throws IOException + + public byte[] toBeSigned(byte[] groupId, int leafIndex) + throws IOException { MLSOutputStream stream = new MLSOutputStream(); stream.writeOpaque(encryption_key); @@ -158,25 +163,25 @@ public byte[] toBeSigned(byte[] groupId, int leafIndex) throws IOException stream.write(leaf_node_source); switch (leaf_node_source) { - case KEY_PACKAGE: - stream.write(lifeTime); - break; - case UPDATE: - break; - case COMMIT: - stream.writeOpaque(parent_hash); - break; + case KEY_PACKAGE: + stream.write(lifeTime); + break; + case UPDATE: + break; + case COMMIT: + stream.writeOpaque(parent_hash); + break; } stream.writeList(extensions); switch (leaf_node_source) { - case KEY_PACKAGE: - break; - case UPDATE: - case COMMIT: - stream.writeOpaque(groupId); - stream.write(leafIndex); - break; + case KEY_PACKAGE: + break; + case UPDATE: + case COMMIT: + stream.writeOpaque(groupId); + stream.write(leafIndex); + break; } return stream.toByteArray(); } @@ -192,7 +197,6 @@ public boolean verifyExtensionSupport(List extensions) public boolean verifyLifetime() { - //TODO: check if (leaf_node_source != LeafNodeSource.KEY_PACKAGE) { return true; @@ -201,7 +205,8 @@ public boolean verifyLifetime() return lifeTime.verify(); } - public boolean verify(MlsCipherSuite suite, byte[] tbs) throws IOException + public boolean verify(MlsCipherSuite suite, byte[] tbs) + throws IOException { if (getCredentialType() == CredentialType.x509) { @@ -211,7 +216,8 @@ public boolean verify(MlsCipherSuite suite, byte[] tbs) throws IOException return suite.verifyWithLabel(signature_key, "LeafNodeTBS", tbs, signature); } - public LeafNode forCommit(MlsCipherSuite suite, byte[] groupId, LeafIndex leafIndex, byte[] encKeyIn, byte[] parentHash, Group.LeafNodeOptions options, byte[] sigPriv) throws Exception + public LeafNode forCommit(MlsCipherSuite suite, byte[] groupId, LeafIndex leafIndex, byte[] encKeyIn, byte[] parentHash, Group.LeafNodeOptions options, byte[] sigPriv) + throws Exception { LeafNode clone = copyWithOptions(encKeyIn, options); clone.leaf_node_source = LeafNodeSource.COMMIT; @@ -221,7 +227,9 @@ public LeafNode forCommit(MlsCipherSuite suite, byte[] groupId, LeafIndex leafIn return clone; } - public LeafNode forUpdate(MlsCipherSuite suite, byte[] groupId, LeafIndex leafIndex, byte[] encKeyIn, Group.LeafNodeOptions options, byte[] sigPriv) throws Exception + + public LeafNode forUpdate(MlsCipherSuite suite, byte[] groupId, LeafIndex leafIndex, byte[] encKeyIn, Group.LeafNodeOptions options, byte[] sigPriv) + throws Exception { LeafNode clone = copyWithOptions(encKeyIn, options); clone.leaf_node_source = LeafNodeSource.UPDATE; @@ -231,7 +239,8 @@ public LeafNode forUpdate(MlsCipherSuite suite, byte[] groupId, LeafIndex leafIn return clone; } - private void sign(MlsCipherSuite suite, byte[] sigPriv, byte[] tbs) throws Exception + private void sign(MlsCipherSuite suite, byte[] sigPriv, byte[] tbs) + throws Exception { byte[] sigPub = suite.serializeSignaturePublicKey(suite.deserializeSignaturePrivateKey(sigPriv).getPublic()); if (!Arrays.equals(sigPub, signature_key)) @@ -266,6 +275,7 @@ public LeafNode copyWithOptions(byte[] encKeyIn, Group.LeafNodeOptions options) return clone; } + public LeafNode copy(byte[] encKeyIn) { LeafNode clone = new LeafNode(); @@ -273,19 +283,19 @@ public LeafNode copy(byte[] encKeyIn) clone.signature_key = this.signature_key.clone(); clone.credential = this.credential; clone.capabilities = this.capabilities; - clone.leaf_node_source = this.leaf_node_source; + clone.leaf_node_source = this.leaf_node_source; switch (clone.leaf_node_source) { - case KEY_PACKAGE: - clone.lifeTime = this.lifeTime; - break; - case UPDATE: - break; - case COMMIT: - clone.parent_hash = this.parent_hash.clone(); - break; + case KEY_PACKAGE: + clone.lifeTime = this.lifeTime; + break; + case UPDATE: + break; + case COMMIT: + clone.parent_hash = this.parent_hash.clone(); + break; } - clone.extensions = new ArrayList<>(this.extensions); + clone.extensions = new ArrayList(this.extensions); clone.signature = this.signature.clone(); return clone; } @@ -302,7 +312,7 @@ public boolean equals(Object o) return false; } - LeafNode leafNode = (LeafNode) o; + LeafNode leafNode = (LeafNode)o; //TODO: check other variables? diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafNodeHashInput.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafNodeHashInput.java index a78c921099..ef66136df8 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafNodeHashInput.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafNodeHashInput.java @@ -1,10 +1,10 @@ package org.bouncycastle.mls.TreeKEM; +import java.io.IOException; + import org.bouncycastle.mls.codec.MLSInputStream; import org.bouncycastle.mls.codec.MLSOutputStream; -import java.io.IOException; - public class LeafNodeHashInput implements MLSInputStream.Readable, MLSOutputStream.Writable { @@ -18,13 +18,16 @@ public LeafNodeHashInput(LeafIndex leafIndex, LeafNode leafNode) } @SuppressWarnings("unused") - public LeafNodeHashInput(MLSInputStream stream) throws IOException + public LeafNodeHashInput(MLSInputStream stream) + throws IOException { - leafIndex = (LeafIndex) stream.read(LeafIndex.class); - leafNode = (LeafNode) stream.readOptional(LeafIndex.class); + leafIndex = (LeafIndex)stream.read(LeafIndex.class); + leafNode = (LeafNode)stream.readOptional(LeafIndex.class); } + @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(leafIndex); stream.writeOptional(leafNode); diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafNodeSource.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafNodeSource.java index ba05e9de4a..b22be57178 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafNodeSource.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LeafNodeSource.java @@ -1,17 +1,17 @@ package org.bouncycastle.mls.TreeKEM; +import java.io.IOException; + import org.bouncycastle.mls.codec.MLSInputStream; import org.bouncycastle.mls.codec.MLSOutputStream; -import java.io.IOException; - public enum LeafNodeSource - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { - RESERVED((byte) 0), - KEY_PACKAGE((byte) 1), - UPDATE((byte) 2), - COMMIT((byte) 3); + RESERVED((byte)0), + KEY_PACKAGE((byte)1), + UPDATE((byte)2), + COMMIT((byte)3); final byte value; @@ -21,7 +21,8 @@ public enum LeafNodeSource } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(value); } diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LifeTime.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LifeTime.java index ee8ec38e8c..f94396e824 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LifeTime.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/LifeTime.java @@ -1,23 +1,26 @@ package org.bouncycastle.mls.TreeKEM; -import org.bouncycastle.mls.codec.MLSInputStream; -import org.bouncycastle.mls.codec.MLSOutputStream; - import java.io.IOException; import java.time.Instant; import java.time.temporal.ChronoField; +import org.bouncycastle.mls.codec.MLSInputStream; +import org.bouncycastle.mls.codec.MLSOutputStream; + public class LifeTime - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { private final long not_before; private final long not_after; + @SuppressWarnings("unused") - public LifeTime(MLSInputStream stream) throws IOException + public LifeTime(MLSInputStream stream) + throws IOException { - not_before = (long) stream.read(long.class); - not_after = (long) stream.read(long.class); + not_before = (long)stream.read(long.class); + not_after = (long)stream.read(long.class); } + public LifeTime() { //TODO: should be Long.MAX_VALUE but this might interfere up testing with test vectors using unsigned long @@ -28,8 +31,10 @@ public LifeTime() this.not_before = 0; this.not_after = -1; } + @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(not_before); stream.write(not_after); diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/Node.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/Node.java index ea340aa660..15c6a270e5 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/Node.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/Node.java @@ -1,13 +1,13 @@ package org.bouncycastle.mls.TreeKEM; +import java.io.IOException; + import org.bouncycastle.mls.codec.MLSInputStream; import org.bouncycastle.mls.codec.MLSOutputStream; import org.bouncycastle.mls.codec.NodeType; -import java.io.IOException; - public class Node - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { NodeType nodeType; LeafNode leafNode; @@ -17,21 +17,22 @@ public byte[] getParentHash() { switch (nodeType) { - case leaf: - return leafNode.parent_hash; - case parent: - return parentNode.parentHash; + case leaf: + return leafNode.parent_hash; + case parent: + return parentNode.parentHash; } return null; } + public byte[] getPublicKey() { switch (nodeType) { - case leaf: - return leafNode.encryption_key; - case parent: - return parentNode.encryptionKey; + case leaf: + return leafNode.encryption_key; + case parent: + return parentNode.encryptionKey; } return null; } @@ -41,6 +42,7 @@ public Node(LeafNode leafNode) nodeType = NodeType.leaf; this.leafNode = leafNode; } + public Node(ParentNode parentNode) { nodeType = NodeType.parent; @@ -48,32 +50,34 @@ public Node(ParentNode parentNode) } @SuppressWarnings("unused") - public Node(MLSInputStream stream) throws IOException + public Node(MLSInputStream stream) + throws IOException { - this.nodeType = NodeType.values()[(byte) stream.read(byte.class)]; + this.nodeType = NodeType.values()[(byte)stream.read(byte.class)]; switch (nodeType) { - case leaf: - leafNode = (LeafNode) stream.read(LeafNode.class); - break; - case parent: - parentNode = (ParentNode) stream.read(ParentNode.class); - break; + case leaf: + leafNode = (LeafNode)stream.read(LeafNode.class); + break; + case parent: + parentNode = (ParentNode)stream.read(ParentNode.class); + break; } } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(nodeType); switch (nodeType) { - case leaf: - stream.write(leafNode); - break; - case parent: - stream.write(parentNode); - break; + case leaf: + stream.write(leafNode); + break; + case parent: + stream.write(parentNode); + break; } } } diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/NodeIndex.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/NodeIndex.java index 5de4fa7b88..a1631638fa 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/NodeIndex.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/NodeIndex.java @@ -1,72 +1,87 @@ package org.bouncycastle.mls.TreeKEM; -import org.bouncycastle.mls.TreeSize; - import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Vector; -public class NodeIndex { +import org.bouncycastle.mls.TreeSize; + +public class NodeIndex +{ private final long value; - public long value() { + public long value() + { return value; } - public NodeIndex(long valueIn) { + public NodeIndex(long valueIn) + { value = valueIn; } - public NodeIndex(LeafIndex leaf) { + public NodeIndex(LeafIndex leaf) + { value = 2 * leaf.value(); } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object o) + { + if (this == o) + { return true; } - if (o == null || getClass() != o.getClass()) { + if (o == null || getClass() != o.getClass()) + { return false; } - NodeIndex nodeIndex = (NodeIndex) o; + NodeIndex nodeIndex = (NodeIndex)o; return value == nodeIndex.value; } - public static NodeIndex root(TreeSize size) { + public static NodeIndex root(TreeSize size) + { return new NodeIndex((1L << size.depth()) - 1); } @Override - public int hashCode() { + public int hashCode() + { return Objects.hash(value); } - public long level() { + public long level() + { return Long.numberOfTrailingZeros(~value); } - public boolean isLeaf() { + public boolean isLeaf() + { return value % 2 == 0; } - public boolean isBelow(NodeIndex other) { + public boolean isBelow(NodeIndex other) + { long lx = level(); long ly = other.level(); - return (lx <= ly) && (value >> (ly+1)) == (other.value >> (ly+1)); + return (lx <= ly) && (value >> (ly + 1)) == (other.value >> (ly + 1)); } - public NodeIndex parent() { + public NodeIndex parent() + { long k = level(); - return new NodeIndex((value | (1L << k)) & ~(1L << (k+1))); + return new NodeIndex((value | (1L << k)) & ~(1L << (k + 1))); } - public NodeIndex left() { - if (isLeaf()) { + public NodeIndex left() + { + if (isLeaf()) + { return this; } @@ -74,8 +89,10 @@ public NodeIndex left() { return new NodeIndex(value ^ (0x01L << (k - 1))); } - public NodeIndex right() { - if (isLeaf()) { + public NodeIndex right() + { + if (isLeaf()) + { return this; } @@ -97,6 +114,7 @@ public NodeIndex sibling() { return sibling(parent()); } + public NodeIndex sibling(NodeIndex ancestor) { NodeIndex l = ancestor.left(); @@ -109,20 +127,21 @@ public NodeIndex sibling(NodeIndex ancestor) return l; } - public List copath(TreeSize size) throws Exception + public List copath(TreeSize size) + throws Exception { List d = directPath(size); if (d.isEmpty()) { - return new ArrayList<>(); + return new ArrayList(); } d.add(0, this); d.remove(d.size() - 1); - List cp = new ArrayList<>(); - for (NodeIndex n: d) + List cp = new ArrayList(); + for (NodeIndex n : d) { cp.add(n.sibling()); } @@ -130,14 +149,15 @@ public List copath(TreeSize size) throws Exception return cp; } - private List directPath(TreeSize size) throws Exception + private List directPath(TreeSize size) + throws Exception { if (value >= size.width()) { throw new Exception("!!!Request for dirpath outside of tree!!!"); } - List d = new Vector<>(); + List d = new Vector(); NodeIndex r = NodeIndex.root(size); if (this.equals(r)) { diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/OptionalNode.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/OptionalNode.java index f7c44196af..71d124c3c1 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/OptionalNode.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/OptionalNode.java @@ -1,13 +1,13 @@ package org.bouncycastle.mls.TreeKEM; +import java.io.IOException; + import org.bouncycastle.mls.codec.MLSInputStream; import org.bouncycastle.mls.codec.MLSOutputStream; import org.bouncycastle.mls.codec.NodeType; -import java.io.IOException; - public class OptionalNode - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { public static OptionalNode blankNode() { @@ -45,13 +45,17 @@ public ParentNode getParentNode() { return node.parentNode; } + @SuppressWarnings("unused") - public OptionalNode(MLSInputStream stream) throws IOException + public OptionalNode(MLSInputStream stream) + throws IOException { - node = (Node) stream.readOptional(Node.class); + node = (Node)stream.readOptional(Node.class); } + @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOptional(node); } diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/ParentHashInput.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/ParentHashInput.java index 4d5ca8ee9a..641ac770e4 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/ParentHashInput.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/ParentHashInput.java @@ -1,19 +1,20 @@ package org.bouncycastle.mls.TreeKEM; +import java.io.IOException; + import org.bouncycastle.mls.codec.MLSInputStream; import org.bouncycastle.mls.codec.MLSOutputStream; -import java.io.IOException; - public class ParentHashInput - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { byte[] encryptionKey; byte[] parentHash; byte[] originalSiblingTreeHash; @SuppressWarnings("unused") - public ParentHashInput(MLSInputStream stream) throws IOException + public ParentHashInput(MLSInputStream stream) + throws IOException { encryptionKey = stream.readOpaque(); parentHash = stream.readOpaque(); @@ -28,7 +29,8 @@ public ParentHashInput(byte[] encryptionKey, byte[] parentHash, byte[] originalS } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(encryptionKey); stream.writeOpaque(parentHash); diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/ParentNode.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/ParentNode.java index 327dc66755..0492a5f368 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/ParentNode.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/ParentNode.java @@ -1,14 +1,14 @@ package org.bouncycastle.mls.TreeKEM; -import org.bouncycastle.mls.codec.MLSInputStream; -import org.bouncycastle.mls.codec.MLSOutputStream; - import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.bouncycastle.mls.codec.MLSInputStream; +import org.bouncycastle.mls.codec.MLSOutputStream; + public class ParentNode - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { protected byte[] encryptionKey; byte[] parentHash; @@ -18,19 +18,22 @@ public ParentNode(byte[] encryptionKey, byte[] parentHash, List unmer { this.encryptionKey = encryptionKey.clone(); this.parentHash = parentHash.clone(); - this.unmerged_leaves = new ArrayList<>(unmerged_leaves); + this.unmerged_leaves = new ArrayList(unmerged_leaves); } + @SuppressWarnings("unused") - public ParentNode(MLSInputStream stream) throws IOException + public ParentNode(MLSInputStream stream) + throws IOException { encryptionKey = stream.readOpaque(); parentHash = stream.readOpaque(); - unmerged_leaves = new ArrayList<>(); + unmerged_leaves = new ArrayList(); stream.readList(unmerged_leaves, LeafIndex.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(encryptionKey); stream.writeOpaque(parentHash); diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/ParentNodeHashInput.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/ParentNodeHashInput.java index 4b2edf97dc..4ad31bfccd 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/ParentNodeHashInput.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/ParentNodeHashInput.java @@ -1,12 +1,12 @@ package org.bouncycastle.mls.TreeKEM; +import java.io.IOException; + import org.bouncycastle.mls.codec.MLSInputStream; import org.bouncycastle.mls.codec.MLSOutputStream; -import java.io.IOException; - public class ParentNodeHashInput - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { ParentNode parentNode; byte[] leftHash; @@ -20,15 +20,17 @@ public ParentNodeHashInput(ParentNode parentNode, byte[] leftHash, byte[] rightH } @SuppressWarnings("unused") - public ParentNodeHashInput(MLSInputStream stream) throws IOException + public ParentNodeHashInput(MLSInputStream stream) + throws IOException { - parentNode = (ParentNode) stream.readOptional(ParentNode.class); + parentNode = (ParentNode)stream.readOptional(ParentNode.class); leftHash = stream.readOpaque(); rightHash = stream.readOpaque(); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOptional(parentNode); stream.writeOpaque(leftHash); diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/TreeHashInput.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/TreeHashInput.java index 90eba00bb5..54a1b1f14b 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/TreeHashInput.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/TreeHashInput.java @@ -1,13 +1,13 @@ package org.bouncycastle.mls.TreeKEM; +import java.io.IOException; + import org.bouncycastle.mls.codec.MLSInputStream; import org.bouncycastle.mls.codec.MLSOutputStream; import org.bouncycastle.mls.codec.NodeType; -import java.io.IOException; - public class TreeHashInput - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { NodeType nodeType; LeafNodeHashInput leafNode; @@ -24,37 +24,41 @@ public static TreeHashInput forLeafNode(LeafNodeHashInput leafNode) { return new TreeHashInput(NodeType.leaf, leafNode, null); } + public static TreeHashInput forParentNode(ParentNodeHashInput parentNode) { return new TreeHashInput(NodeType.parent, null, parentNode); } + @SuppressWarnings("unused") - public TreeHashInput(MLSInputStream stream) throws IOException + public TreeHashInput(MLSInputStream stream) + throws IOException { - nodeType = NodeType.values()[(byte) stream.read(byte.class)]; + nodeType = NodeType.values()[(byte)stream.read(byte.class)]; switch (nodeType) { - case leaf: - leafNode = (LeafNodeHashInput) stream.read(LeafNodeHashInput.class); - break; - case parent: - parentNode = (ParentNodeHashInput) stream.read(ParentNodeHashInput.class); - break; + case leaf: + leafNode = (LeafNodeHashInput)stream.read(LeafNodeHashInput.class); + break; + case parent: + parentNode = (ParentNodeHashInput)stream.read(ParentNodeHashInput.class); + break; } } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(nodeType); switch (nodeType) { - case leaf: - stream.write(leafNode); - break; - case parent: - stream.write(parentNode); - break; + case leaf: + stream.write(leafNode); + break; + case parent: + stream.write(parentNode); + break; } } } diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/TreeKEMPrivateKey.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/TreeKEMPrivateKey.java index 24c16e11f9..970514f3eb 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/TreeKEMPrivateKey.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/TreeKEMPrivateKey.java @@ -1,20 +1,21 @@ package org.bouncycastle.mls.TreeKEM; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.mls.TreeSize; import org.bouncycastle.mls.codec.HPKECiphertext; import org.bouncycastle.mls.codec.UpdatePath; import org.bouncycastle.mls.crypto.MlsCipherSuite; import org.bouncycastle.mls.crypto.Secret; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import static org.bouncycastle.mls.TreeKEM.Utils.removeLeaves; public class TreeKEMPrivateKey @@ -44,8 +45,8 @@ public TreeKEMPrivateKey(MlsCipherSuite suite, LeafIndex index) { this.suite = suite; this.index = index; - pathSecrets = new HashMap<>(); - privateKeyCache = new HashMap<>(); + pathSecrets = new HashMap(); + privateKeyCache = new HashMap(); } public TreeKEMPrivateKey copy() @@ -63,14 +64,18 @@ public static TreeKEMPrivateKey solo(MlsCipherSuite suite, LeafIndex index, Asym priv.privateKeyCache.put(new NodeIndex(index), leafPriv); return priv; } - public static TreeKEMPrivateKey create(TreeKEMPublicKey pub, LeafIndex from, Secret leafSecret) throws Exception + + public static TreeKEMPrivateKey create(TreeKEMPublicKey pub, LeafIndex from, Secret leafSecret) + throws Exception { TreeKEMPrivateKey priv = new TreeKEMPrivateKey(pub.suite, from); - priv.implant(pub, new NodeIndex(from), leafSecret);//todo check + priv.implant(pub, new NodeIndex(from), leafSecret); return priv; } + public static TreeKEMPrivateKey joiner(TreeKEMPublicKey pub, LeafIndex index, AsymmetricCipherKeyPair leafPriv, - NodeIndex intersect, Secret pathSecret) throws Exception + NodeIndex intersect, Secret pathSecret) + throws Exception { TreeKEMPrivateKey priv = new TreeKEMPrivateKey(pub.suite, index); @@ -83,42 +88,50 @@ public static TreeKEMPrivateKey joiner(TreeKEMPublicKey pub, LeafIndex index, As return priv; } - public void dump() throws IOException + public String dump() + throws IOException { + StringBuilder sb = new StringBuilder(); for (NodeIndex node : - pathSecrets.keySet()) + pathSecrets.keySet()) { setPrivateKey(node, true); } - System.out.println("Tree (priv)"); - System.out.println(" Index: " + (new NodeIndex(index)).value()); + sb.append("Tree (priv)").append(Strings.lineSeparator()); + sb.append(" Index: ").append((new NodeIndex(index)).value()).append(Strings.lineSeparator()); - System.out.println(" Secrets: "); + sb.append(" Secrets: ").append(Strings.lineSeparator()); for (NodeIndex n : pathSecrets.keySet()) { Secret pathSecret = pathSecrets.get(n); Secret nodeSecret = pathSecret.deriveSecret(suite, "node"); AsymmetricCipherKeyPair sk = suite.getHPKE().deriveKeyPair(nodeSecret.value()); - - System.out.println(" " + n.value() - + " => " + Hex.toHexString(pathSecret.value(), 0, 4) - + " => " + Hex.toHexString(suite.getHPKE().serializePublicKey(sk.getPublic()), 0, 4)); + // -DM Hex.toHexString + // -DM Hex.toHexString + sb.append(" ").append(n.value()) + .append(" => ").append(Hex.toHexString(pathSecret.value(), 0, 4)) + .append(" => ").append(Hex.toHexString(suite.getHPKE().serializePublicKey(sk.getPublic()), 0, 4)) + .append(Strings.lineSeparator()); } - System.out.println(" Cached key pairs: "); - for (NodeIndex n: privateKeyCache.keySet()) + sb.append(" Cached key pairs: ").append(Strings.lineSeparator()); + for (NodeIndex n : privateKeyCache.keySet()) { AsymmetricCipherKeyPair sk = privateKeyCache.get(n); - System.out.println(" " + n.value() + " => " + Hex.toHexString(suite.getHPKE().serializePublicKey(sk.getPublic()), 0, 4)); + // -DM Hex.toHexString + sb.append(" ").append(n.value()).append(" => ") + .append(Hex.toHexString(suite.getHPKE().serializePublicKey(sk.getPublic()), 0, 4)) + .append(Strings.lineSeparator()); } + return sb.toString(); } public void truncate(TreeSize size) { - NodeIndex ni = new NodeIndex(new LeafIndex((int) (size.leafCount() - 1))); - List toRemove = new ArrayList<>(); + NodeIndex ni = new NodeIndex(new LeafIndex((int)(size.leafCount() - 1))); + List toRemove = new ArrayList(); for (NodeIndex n : pathSecrets.keySet()) { if (n.value() > ni.value()) @@ -143,7 +156,8 @@ public void setLeafKey(byte[] leafSkBytes) privateKeyCache.put(n, leafSk); } - public void decap(LeafIndex from, TreeKEMPublicKey pub, byte[] context, UpdatePath path, List except) throws Exception + public void decap(LeafIndex from, TreeKEMPublicKey pub, byte[] context, UpdatePath path, List except) + throws Exception { // find decap target NodeIndex ni = new NodeIndex(index); @@ -155,7 +169,7 @@ public void decap(LeafIndex from, TreeKEMPublicKey pub, byte[] context, UpdatePa int dpi = 0; NodeIndex overlapNode = null; - ArrayList res = new ArrayList<>(); + ArrayList res = new ArrayList(); for (dpi = 0; dpi < dp.parents.size(); dpi++) { if (ni.isBelow(dp.parents.get(dpi))) @@ -197,16 +211,16 @@ public void decap(LeafIndex from, TreeKEMPublicKey pub, byte[] context, UpdatePa HPKECiphertext ct = path.getNodes().get(dpi).getEncryptedPathSecret().get(resi); Secret pathSecret = new Secret(suite.decryptWithLabel( - suite.getHPKE().serializePrivateKey(priv.getPrivate()), - "UpdatePathNode", - context, - ct.getKemOutput(), - ct.getCiphertext()) + suite.getHPKE().serializePrivateKey(priv.getPrivate()), + "UpdatePathNode", + context, + ct.getKemOutput(), + ct.getCiphertext()) ); implant(pub, overlapNode, pathSecret); - if(!consistent(pub)) + if (!consistent(pub)) { throw new Exception("TreeKEMPublicKey inconsistant with TreeKEMPrivateKey"); } @@ -217,7 +231,8 @@ private boolean havePrivateKey(NodeIndex n) return pathSecrets.containsKey(n) || privateKeyCache.containsKey(n); } - public final boolean consistent(TreeKEMPublicKey other) throws IOException + public final boolean consistent(TreeKEMPublicKey other) + throws IOException { if (suite.getSuiteID() != other.suite.getSuiteID()) { @@ -238,7 +253,6 @@ public final boolean consistent(TreeKEMPublicKey other) throws IOException } byte[] pub = optNode.getPublicKey(); AsymmetricCipherKeyPair priv = privateKeyCache.get(key); - // todo maybe i have to initilize the public keys for testing if (!Arrays.equals(pub, suite.getHPKE().serializePublicKey(priv.getPublic()))) { return false; @@ -247,7 +261,8 @@ public final boolean consistent(TreeKEMPublicKey other) throws IOException return true; } - protected AsymmetricCipherKeyPair setPrivateKey(NodeIndex n, boolean isConst) throws IOException + protected AsymmetricCipherKeyPair setPrivateKey(NodeIndex n, boolean isConst) + throws IOException { AsymmetricCipherKeyPair priv = getPrivateKey(n); if (priv != null && !isConst) @@ -256,7 +271,9 @@ protected AsymmetricCipherKeyPair setPrivateKey(NodeIndex n, boolean isConst) th } return priv; } - private AsymmetricCipherKeyPair getPrivateKey(NodeIndex n) throws IOException + + private AsymmetricCipherKeyPair getPrivateKey(NodeIndex n) + throws IOException { if (privateKeyCache.containsKey(n)) { @@ -271,7 +288,8 @@ private AsymmetricCipherKeyPair getPrivateKey(NodeIndex n) throws IOException return suite.getHPKE().deriveKeyPair(nodeSecret.value()); } - private void implant(TreeKEMPublicKey pub, NodeIndex start, Secret pathSecret) throws Exception + private void implant(TreeKEMPublicKey pub, NodeIndex start, Secret pathSecret) + throws Exception { FilteredDirectPath fdp = pub.getFilteredDirectPath(start); Secret secret = new Secret(pathSecret.value()); @@ -291,7 +309,6 @@ private void implant(TreeKEMPublicKey pub, NodeIndex start, Secret pathSecret) t public Secret getSharedPathSecret(LeafIndex to) { - //TODO: make a triplet class NodeIndex n = index.commonAncestor(to); if (!pathSecrets.containsKey(n)) { diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/TreeKEMPublicKey.java b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/TreeKEMPublicKey.java index 1ef197a34a..162297e572 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeKEM/TreeKEMPublicKey.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeKEM/TreeKEMPublicKey.java @@ -1,26 +1,27 @@ package org.bouncycastle.mls.TreeKEM; +import java.io.IOException; +import java.security.InvalidParameterException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.mls.TreeSize; -import org.bouncycastle.mls.crypto.MlsCipherSuite; -import org.bouncycastle.mls.protocol.Group; import org.bouncycastle.mls.codec.HPKECiphertext; import org.bouncycastle.mls.codec.MLSInputStream; import org.bouncycastle.mls.codec.MLSOutputStream; import org.bouncycastle.mls.codec.UpdatePath; import org.bouncycastle.mls.codec.UpdatePathNode; +import org.bouncycastle.mls.crypto.MlsCipherSuite; import org.bouncycastle.mls.crypto.Secret; +import org.bouncycastle.mls.protocol.Group; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; -import java.io.IOException; -import java.security.InvalidParameterException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import static org.bouncycastle.mls.TreeKEM.Utils.removeLeaves; class FilteredDirectPath @@ -31,16 +32,17 @@ class FilteredDirectPath public FilteredDirectPath clone() { FilteredDirectPath fdp = new FilteredDirectPath(); - fdp.parents = (ArrayList) parents.clone(); - fdp.resolutions = (ArrayList>) resolutions.clone(); + fdp.parents = (ArrayList)parents.clone(); + fdp.resolutions = (ArrayList>)resolutions.clone(); return fdp; } public FilteredDirectPath() { - this.parents = new ArrayList<>(); - this.resolutions = new ArrayList<>(); + this.parents = new ArrayList(); + this.resolutions = new ArrayList>(); } + public void reverse() { Collections.reverse(parents); @@ -50,7 +52,7 @@ public void reverse() } public class TreeKEMPublicKey - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { MlsCipherSuite suite; TreeSize size; @@ -69,23 +71,26 @@ public TreeSize getSize() return size; } - public static TreeKEMPublicKey clone(TreeKEMPublicKey other) throws IOException + public static TreeKEMPublicKey clone(TreeKEMPublicKey other) + throws IOException { - TreeKEMPublicKey tree = (TreeKEMPublicKey) MLSInputStream.decode(MLSOutputStream.encode(other), TreeKEMPublicKey.class); + TreeKEMPublicKey tree = (TreeKEMPublicKey)MLSInputStream.decode(MLSOutputStream.encode(other), TreeKEMPublicKey.class); tree.setSuite(other.suite); tree.setHashAll(); return tree; } - public TreeKEMPublicKey(MlsCipherSuite suite) throws IOException + + public TreeKEMPublicKey(MlsCipherSuite suite) + throws IOException { this.suite = suite; - hashes = new HashMap<>(); - nodes = new ArrayList<>(); - treeHashCache = new HashMap<>(); - exceptCache = new HashMap<>(); + hashes = new HashMap(); + nodes = new ArrayList(); + treeHashCache = new HashMap(); + exceptCache = new HashMap(); size = TreeSize.forLeaves(0); - while(size.width() < nodes.size()) + while (size.width() < nodes.size()) { size = TreeSize.forLeaves(size.leafCount() * 2); } @@ -95,17 +100,19 @@ public TreeKEMPublicKey(MlsCipherSuite suite) throws IOException nodes.add(OptionalNode.blankNode()); } } + @SuppressWarnings("unused") - public TreeKEMPublicKey(MLSInputStream stream) throws IOException + public TreeKEMPublicKey(MLSInputStream stream) + throws IOException { - hashes = new HashMap<>(); - nodes = new ArrayList<>(); - treeHashCache = new HashMap<>(); - exceptCache = new HashMap<>(); + hashes = new HashMap(); + nodes = new ArrayList(); + treeHashCache = new HashMap(); + exceptCache = new HashMap(); stream.readList(nodes, OptionalNode.class); size = TreeSize.forLeaves(1); - while(size.width() < nodes.size()) + while (size.width() < nodes.size()) { size = TreeSize.forLeaves(size.leafCount() * 2); } @@ -115,8 +122,10 @@ public TreeKEMPublicKey(MLSInputStream stream) throws IOException nodes.add(OptionalNode.blankNode()); } } + @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { LeafIndex cut = new LeafIndex((int)size.leafCount() - 1); while (cut.value > 0 && nodeAt(cut).isBlank()) @@ -131,63 +140,70 @@ public void setSuite(MlsCipherSuite suite) this.suite = suite; } - public void dumpHashes() + public String dumpHashes() { + StringBuilder sb = new StringBuilder(); for (NodeIndex n : hashes.keySet()) { - System.out.print(n.value() + " : "); - System.out.println(Hex.toHexString(hashes.get(n))); + sb.append(n.value()).append(" : "); + // -DM Hex.toHexString + sb.append(Hex.toHexString(hashes.get(n))).append(Strings.lineSeparator()); } + return sb.toString(); } - public void dump() + + public String dump() { - System.out.println("Tree:"); + StringBuilder sb = new StringBuilder(); + sb.append("Tree:").append(Strings.lineSeparator()); for (int i = 0; i < size.width(); i++) { NodeIndex index = new NodeIndex(i); - System.out.printf(" %03d : ", i); + sb.append(String.format(" %03d : ", i)); if (!nodeAt(index).isBlank()) { byte[] pkRm = nodeAt(index).node.getPublicKey(); - System.out.print(Hex.toHexString(pkRm, 0, 4)); + // -DM Hex.toHexString + sb.append(Hex.toHexString(pkRm, 0, 4)); } else { - System.out.print(" "); + sb.append(" "); } - System.out.print(" | "); + sb.append(" | "); for (int j = 0; j < index.level(); j++) { - System.out.print(" "); + sb.append(" "); } if (!nodeAt(index).isBlank()) { - System.out.print("X"); + sb.append("X"); if (!index.isLeaf()) { ParentNode parent = nodeAt(index).getParentNode(); - System.out.print(" ["); + sb.append(" ["); for (LeafIndex u : parent.unmerged_leaves) { - System.out.print(u.value + ", "); + sb.append(u.value).append( ", "); } - System.out.print("]"); + sb.append("]"); } } else { - System.out.print("_"); + sb.append("_"); } - System.out.println(); + sb.append(Strings.lineSeparator()); } - System.out.println("nodeCount: " + nodes.size()); + sb.append("nodeCount: ").append(nodes.size()).append(Strings.lineSeparator()); + return sb.toString(); } - //TODO: include leaf node options - public TreeKEMPrivateKey update(LeafIndex from, Secret leafSecret, byte[] groupId, byte[] sigPriv, Group.LeafNodeOptions options) throws Exception + public TreeKEMPrivateKey update(LeafIndex from, Secret leafSecret, byte[] groupId, byte[] sigPriv, Group.LeafNodeOptions options) + throws Exception { // Grab information about the sender OptionalNode leafNode = nodeAt(from); @@ -202,13 +218,13 @@ public TreeKEMPrivateKey update(LeafIndex from, Secret leafSecret, byte[] groupI // Encrypt path secrets to the copath, forming a stub UpdatePath with no // encryptions - ArrayList pathNodes = new ArrayList<>(); - for (NodeIndex n: dp.parents) + ArrayList pathNodes = new ArrayList(); + for (NodeIndex n : dp.parents) { Secret pathSecret = priv.pathSecrets.get(n); AsymmetricCipherKeyPair nodePriv = priv.setPrivateKey(n, false); - pathNodes.add(new UpdatePathNode(suite.getHPKE().serializePublicKey(nodePriv.getPublic()), new ArrayList<>())); + pathNodes.add(new UpdatePathNode(suite.getHPKE().serializePublicKey(nodePriv.getPublic()), new ArrayList())); } // Update and re-sign the leaf_node @@ -228,21 +244,22 @@ public TreeKEMPrivateKey update(LeafIndex from, Secret leafSecret, byte[] groupI return priv; } - public UpdatePath encap(TreeKEMPrivateKey priv, byte[] context, List except) throws Exception + public UpdatePath encap(TreeKEMPrivateKey priv, byte[] context, List except) + throws Exception { FilteredDirectPath dp = getFilteredDirectPath(new NodeIndex(priv.index)); - List pathNodes = new ArrayList<>(); + List pathNodes = new ArrayList(); for (int i = 0; i < dp.parents.size(); i++) { NodeIndex n = dp.parents.get(i); - List res = (List) dp.resolutions.get(i).clone(); + List res = (List)dp.resolutions.get(i).clone(); removeLeaves(res, except); Secret pathSecret = priv.pathSecrets.get(n); AsymmetricCipherKeyPair nodePriv = priv.setPrivateKey(n, false); - List cts = new ArrayList<>(); - for (NodeIndex nr: res) + List cts = new ArrayList(); + for (NodeIndex nr : res) { byte[] nodePub = nodeAt(nr).node.getPublicKey(); byte[][] ctAndEnc = suite.encryptWithLabel(nodePub, "UpdatePathNode", context, pathSecret.value()); @@ -255,7 +272,8 @@ public UpdatePath encap(TreeKEMPrivateKey priv, byte[] context, List return new UpdatePath(newLeaf, pathNodes); } - public byte[] getRootHash() throws Exception + public byte[] getRootHash() + throws Exception { NodeIndex r = NodeIndex.root(size); if (!hashes.containsKey(r)) @@ -266,7 +284,8 @@ public byte[] getRootHash() throws Exception return hashes.get(r); } - public void merge(LeafIndex from, UpdatePath path) throws Exception + public void merge(LeafIndex from, UpdatePath path) + throws Exception { nodeAt(from).node = new Node(path.getLeafNode()); @@ -288,7 +307,7 @@ public void merge(LeafIndex from, UpdatePath path) throws Exception parentHash = ph[i + 1]; } - nodeAt(n).node = new Node(new ParentNode(path.getNodes().get(i).getEncryptionKey(), parentHash, new ArrayList<>())); + nodeAt(n).node = new Node(new ParentNode(path.getNodes().get(i).getEncryptionKey(), parentHash, new ArrayList())); } clearHashPath(from); @@ -314,7 +333,8 @@ public boolean hasLeaf(LeafIndex index) return !nodeAt(index).isBlank(); } - protected FilteredDirectPath getFilteredCommonDirectPath(LeafIndex leaf1, LeafIndex leaf2) throws Exception + protected FilteredDirectPath getFilteredCommonDirectPath(LeafIndex leaf1, LeafIndex leaf2) + throws Exception { FilteredDirectPath xPath = getFilteredDirectPath(new NodeIndex(leaf1)); FilteredDirectPath yPath = getFilteredDirectPath(new NodeIndex(leaf2)); @@ -338,7 +358,8 @@ protected FilteredDirectPath getFilteredCommonDirectPath(LeafIndex leaf1, LeafIn return commonPath; } - protected FilteredDirectPath getFilteredDirectPath(NodeIndex index) throws Exception + protected FilteredDirectPath getFilteredDirectPath(NodeIndex index) + throws Exception { FilteredDirectPath fdp = new FilteredDirectPath(); List cp = index.copath(size); @@ -362,7 +383,7 @@ protected FilteredDirectPath getFilteredDirectPath(NodeIndex index) throws Excep public LeafNode getLeafNode(LeafIndex index) { OptionalNode node = nodeAt(index); - if(!node.isLeaf()) + if (!node.isLeaf()) { return null; } @@ -375,9 +396,9 @@ public ArrayList resolve(NodeIndex index) boolean atLeaf = (index.level() == 0); if (!nodeAt(index).isBlank()) { - ArrayList out = new ArrayList<>(); + ArrayList out = new ArrayList(); out.add(index); - if(index.isLeaf()) + if (index.isLeaf()) { return out; } @@ -392,9 +413,9 @@ public ArrayList resolve(NodeIndex index) return out; } - if(atLeaf) + if (atLeaf) { - return new ArrayList<>(); + return new ArrayList(); } ArrayList l = resolve(index.left()); @@ -426,6 +447,7 @@ public LeafIndex allocateLeaf() } return index; } + public LeafIndex addLeaf(LeafNode leaf) { LeafIndex index = new LeafIndex(0); @@ -519,7 +541,7 @@ public void blankPath(LeafIndex index) NodeIndex ni = new NodeIndex(index); nodeAt(ni).node = null; for (NodeIndex n : - index.directPath(size)) + index.directPath(size)) { nodeAt(n).node = null; } @@ -543,7 +565,7 @@ OptionalNode nodeAt(NodeIndex n) { return OptionalNode.blankNode(); } - return nodes.get((int) n.value()); + return nodes.get((int)n.value()); } public void truncate() @@ -558,7 +580,7 @@ public void truncate() LeafIndex index = new LeafIndex((int)size.leafCount() - 1); while (index.value > 0) { - if(!nodeAt(index).isBlank()) + if (!nodeAt(index).isBlank()) { break; } @@ -566,7 +588,7 @@ public void truncate() index.value--; } - if(nodeAt(index).isBlank()) + if (nodeAt(index).isBlank()) { nodes.clear(); return; @@ -575,31 +597,33 @@ public void truncate() // Remove the right subtree until the tree is of minimal size while (size.leafCount() / 2 > index.value) { - //TODO: better way of clearing from index to end nodes.subList(nodes.size() / 2, nodes.size()).clear(); size = TreeSize.forLeaves(size.leafCount() / 2); } } - public void setHashAll() throws IOException + + public void setHashAll() + throws IOException { NodeIndex r = NodeIndex.root(size); getHash(r); } - private byte[][] parentHashes(LeafIndex from, FilteredDirectPath fdp, List nodes) throws Exception + private byte[][] parentHashes(LeafIndex from, FilteredDirectPath fdp, List nodes) + throws Exception { NodeIndex fromNode = new NodeIndex(from); FilteredDirectPath dp = fdp.clone(); // removing root from fdp - dp.parents.remove(dp.parents.size()-1); - dp.resolutions.remove(dp.resolutions.size()-1); + dp.parents.remove(dp.parents.size() - 1); + dp.resolutions.remove(dp.resolutions.size() - 1); // special case of one-leaf tree if (!fromNode.equals(NodeIndex.root(size))) { dp.parents.add(0, fromNode); - dp.resolutions.add(0, new ArrayList<>()); + dp.resolutions.add(0, new ArrayList()); } if (dp.parents.size() != nodes.size()) @@ -617,7 +641,7 @@ private byte[][] parentHashes(LeafIndex from, FilteredDirectPath fdp, List()); + ParentNode parentNode = new ParentNode(nodes.get(i).getEncryptionKey(), lastHash, new ArrayList()); lastHash = getParentHash(parentNode, s); ph[i] = lastHash; @@ -626,7 +650,9 @@ private byte[][] parentHashes(LeafIndex from, FilteredDirectPath fdp, List>> 1)-1); + int start = (int)((stride >>> 1) - 1); for (int p = start; p < width; p += stride) { @@ -688,7 +718,7 @@ public boolean verifyParentHash() throws IOException private boolean hasParentHash(NodeIndex child, byte[] targetParentHash) { ArrayList res = resolve(child); - for (NodeIndex n: res) + for (NodeIndex n : res) { if (Arrays.equals(nodeAt(n).node.getParentHash(), targetParentHash)) { @@ -698,11 +728,11 @@ private boolean hasParentHash(NodeIndex child, byte[] targetParentHash) return false; } - private byte[] originalTreeHash(NodeIndex index, List parentExcept) throws IOException + private byte[] originalTreeHash(NodeIndex index, List parentExcept) + throws IOException { - List except = new ArrayList<>(); - //TODO: check adding sequence - for (LeafIndex i: parentExcept) + List except = new ArrayList(); + for (LeafIndex i : parentExcept) { NodeIndex n = new NodeIndex(i); if (n.isBelow(index)) @@ -710,7 +740,7 @@ private byte[] originalTreeHash(NodeIndex index, List parentExcept) t except.add(i); } } - boolean haveLocalChanges = ! except.isEmpty(); + boolean haveLocalChanges = !except.isEmpty(); // If there are no local changes, then we can use the cached tree hash if (!haveLocalChanges) @@ -744,31 +774,17 @@ private byte[] originalTreeHash(NodeIndex index, List parentExcept) t // specified `except` list, removing the `except` list from // `unmerged_leaves`. ParentNodeHashInput parentHashInput = new ParentNodeHashInput( - null, - originalTreeHash(index.left(), except), - originalTreeHash(index.right(), except) + null, + originalTreeHash(index.left(), except), + originalTreeHash(index.right(), except) ); if (!nodeAt(index).isBlank()) { parentHashInput.parentNode = nodeAt(index).getParentNode(); - //TODO: check which one runs faster (assuming the latter) - List unmergedOriginal = new ArrayList<>(parentHashInput.parentNode.unmerged_leaves); + List unmergedOriginal = new ArrayList(parentHashInput.parentNode.unmerged_leaves); parentHashInput.parentNode.unmerged_leaves.removeAll(except); -// int end = parentHashInput.parentNode.unmerged_leaves.size(); -// for (LeafIndex leaf: parentHashInput.parentNode.unmerged_leaves) -// { -// if (except.contains(leaf)) -// { -// end--; -// } -// else -// { -// break; -// } -// } -// parentHashInput.parentNode.unmerged_leaves = parentHashInput.parentNode.unmerged_leaves.subList(0, end); hash = suite.hash(MLSOutputStream.encode(TreeHashInput.forParentNode(parentHashInput))); @@ -781,25 +797,27 @@ private byte[] originalTreeHash(NodeIndex index, List parentExcept) t } - } treeHashCache.put(index, hash); exceptCache.put(index, except.size()); return hash; } - private byte[] originalParentHash(NodeIndex parent, NodeIndex sibling) throws IOException + + private byte[] originalParentHash(NodeIndex parent, NodeIndex sibling) + throws IOException { ParentNode parentNode = nodeAt(parent).getParentNode(); - byte[] siblingHash = originalTreeHash(sibling, parentNode.unmerged_leaves); + byte[] siblingHash = originalTreeHash(sibling, parentNode.unmerged_leaves); return suite.hash(MLSOutputStream.encode(new ParentHashInput( - parentNode.encryptionKey, - parentNode.parentHash, - siblingHash + parentNode.encryptionKey, + parentNode.parentHash, + siblingHash ))); } - public byte[] getHash(NodeIndex index) throws IOException + public byte[] getHash(NodeIndex index) + throws IOException { if (hashes.containsKey(index)) { @@ -820,11 +838,11 @@ public byte[] getHash(NodeIndex index) throws IOException else { ParentNodeHashInput input = new ParentNodeHashInput( - null, - getHash(index.left()), - getHash(index.right()) + null, + getHash(index.left()), + getHash(index.right()) ); - if(!node.isBlank()) + if (!node.isBlank()) { input.parentNode = node.getParentNode(); } diff --git a/mls/src/main/java/org/bouncycastle/mls/TreeSize.java b/mls/src/main/java/org/bouncycastle/mls/TreeSize.java index 6239dd93ec..464a401dfa 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TreeSize.java +++ b/mls/src/main/java/org/bouncycastle/mls/TreeSize.java @@ -1,29 +1,35 @@ package org.bouncycastle.mls; -public class TreeSize { +public class TreeSize +{ private final long leafCount; private final long depth; - private TreeSize(long leafCount, long depth) { + private TreeSize(long leafCount, long depth) + { this.leafCount = leafCount; this.depth = depth; } - public static TreeSize forLeaves(long leafCount) { + public static TreeSize forLeaves(long leafCount) + { assert leafCount >= 0; long depth = Long.SIZE - Long.numberOfLeadingZeros(leafCount - 1); return new TreeSize(leafCount, depth); } - public long depth() { + public long depth() + { return depth; } - public long leafCount() { + public long leafCount() + { return leafCount; } - public long width() { + public long width() + { return (1L << (depth + 1)) - 1; } } diff --git a/mls/src/main/java/org/bouncycastle/mls/client/KeyPackageWithSecrets.java b/mls/src/main/java/org/bouncycastle/mls/client/KeyPackageWithSecrets.java index f7fb6ed93f..6c2ec372c9 100644 --- a/mls/src/main/java/org/bouncycastle/mls/client/KeyPackageWithSecrets.java +++ b/mls/src/main/java/org/bouncycastle/mls/client/KeyPackageWithSecrets.java @@ -3,11 +3,12 @@ import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.mls.codec.KeyPackage; -public class KeyPackageWithSecrets { - AsymmetricCipherKeyPair initKeyPair; // HPKE key pair - AsymmetricCipherKeyPair encryptionKeyPair; // HPKE key pair - AsymmetricCipherKeyPair signatureKeyPair; // sig key pair - KeyPackage keyPackage; +public class KeyPackageWithSecrets +{ + AsymmetricCipherKeyPair initKeyPair; // HPKE key pair + AsymmetricCipherKeyPair encryptionKeyPair; // HPKE key pair + AsymmetricCipherKeyPair signatureKeyPair; // sig key pair + KeyPackage keyPackage; public KeyPackageWithSecrets(AsymmetricCipherKeyPair initKeyPair, AsymmetricCipherKeyPair encryptionKeyPair, AsymmetricCipherKeyPair signatureKeyPair, KeyPackage keyPackage) { diff --git a/mls/src/main/java/org/bouncycastle/mls/client/MLSClientImpl.java b/mls/src/main/java/org/bouncycastle/mls/client/MLSClientImpl.java index 5154456862..201e34a78d 100644 --- a/mls/src/main/java/org/bouncycastle/mls/client/MLSClientImpl.java +++ b/mls/src/main/java/org/bouncycastle/mls/client/MLSClientImpl.java @@ -1,5 +1,13 @@ package org.bouncycastle.mls.client; +import java.io.IOException; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import com.google.protobuf.ByteString; import com.google.protobuf.MessageOrBuilder; import io.grpc.Status; @@ -33,21 +41,14 @@ import org.bouncycastle.mls.protocol.Group; import org.bouncycastle.util.Pack; -import java.io.IOException; -import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import static org.bouncycastle.mls.crypto.MlsCipherSuite.ALL_SUPPORTED_SUITES; import static org.bouncycastle.mls.protocol.Group.NORMAL_COMMIT_PARAMS; public class MLSClientImpl extends MLSClientGrpc.MLSClientImplBase { - class CachedGroup { + class CachedGroup + { Group group; boolean encryptHandshake; Group.MessageOptions messageOptions; @@ -59,7 +60,7 @@ public CachedGroup(Group group, boolean encryptHandshake) { this.group = group; this.encryptHandshake = encryptHandshake; - this.messageOptions = new Group.MessageOptions(encryptHandshake, new byte [0], 0); + this.messageOptions = new Group.MessageOptions(encryptHandshake, new byte[0], 0); } public void resetPending() @@ -68,17 +69,21 @@ public void resetPending() pendingGroupID = -1; } } - class CachedJoin { + + class CachedJoin + { KeyPackageWithSecrets kpSecrets; Map externalPsks; public CachedJoin(KeyPackageWithSecrets kpSecrets) { this.kpSecrets = kpSecrets; - this.externalPsks = new HashMap<>(); + this.externalPsks = new HashMap(); } } - class CachedReinit { + + class CachedReinit + { KeyPackageWithSecrets kpSk; Group.Tombstone tombstone; boolean encryptHandshake; @@ -90,49 +95,48 @@ public CachedReinit(KeyPackageWithSecrets kpSk, Group.Tombstone tombstone, boole this.encryptHandshake = encryptHandshake; } } - Map groupCache = new HashMap<>(); - Map joinCache = new HashMap<>(); - Map reinitCache = new HashMap<>(); - Map signerCache = new HashMap<>(); + + Map groupCache = new HashMap(); + Map joinCache = new HashMap(); + Map reinitCache = new HashMap(); + Map signerCache = new HashMap(); @FunctionalInterface - public interface Function{ - void run() throws Exception; + public interface Function + { + void run() + throws Exception; } + @FunctionalInterface - public interface FunctionWithState{ - void run(CachedGroup g) throws Exception; + public interface FunctionWithState + { + void run(CachedGroup g) + throws Exception; } - private static String getCallerMethodName() { + private static String getCallerMethodName() + { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); return stackTrace[3].getMethodName(); } private static void catchWrap(Function f, StreamObserver observer) { -// System.out.println("Executing function: " + getCallerMethodName()); try { f.run(); } catch (Exception e) { - System.out.println(e.getMessage()); - for (StackTraceElement elm: e.getStackTrace()) - { - System.out.println(elm); - } -// System.exit(0); observer.onError(Status.INTERNAL.withDescription(e.getMessage()).asException()); } } + private void stateWrap(FunctionWithState f, MessageOrBuilder request, StreamObserver observer) { -// System.out.println("Executing function: " + getCallerMethodName()); - - int stateID = (int) request.getField(request.getDescriptorForType().findFieldByName("state_id")); + int stateID = (int)request.getField(request.getDescriptorForType().findFieldByName("state_id")); CachedGroup group = loadGroup(stateID); if (group == null) { @@ -144,11 +148,6 @@ private void stateWrap(FunctionWithState f, MessageOrBuilder request, Stream } catch (Exception e) { - System.out.println(e.getMessage()); - for (StackTraceElement elm: e.getStackTrace()) - { - System.out.println(elm); - } observer.onError(Status.INTERNAL.withDescription(e.getMessage()).asException()); } } @@ -173,7 +172,8 @@ private CachedGroup loadGroup(int stateID) return groupCache.get(stateID); } - private int storeJoin(KeyPackageWithSecrets kpSecrets) throws IOException + private int storeJoin(KeyPackageWithSecrets kpSecrets) + throws IOException { MlsCipherSuite suite = kpSecrets.keyPackage.getSuite(); int joinID = 0x07FFFFFF & Pack.littleEndianToInt(suite.refHash(MLSOutputStream.encode(kpSecrets.keyPackage), "MLS 1.0 KeyPackage Reference"), 0); @@ -207,7 +207,8 @@ private byte[] loadSigner(int signerID) return signerCache.get(signerID); // returns private signature key } - private int storeReinit(KeyPackageWithSecrets kpSk, Group.Tombstone tombstone, boolean encryptHandshake) throws IOException + private int storeReinit(KeyPackageWithSecrets kpSk, Group.Tombstone tombstone, boolean encryptHandshake) + throws IOException { MlsCipherSuite suite = kpSk.keyPackage.getSuite(); int reinitID = 0x07FFFFFF & Pack.littleEndianToInt(suite.refHash(MLSOutputStream.encode(kpSk.keyPackage), "MLS 1.0 KeyPackage Reference"), 0); @@ -239,7 +240,8 @@ private CachedGroup findState(byte[] groupID, long epoch) return result; } - private KeyPackageWithSecrets newKeyPackage(MlsCipherSuite suite, byte[] identity) throws Exception + private KeyPackageWithSecrets newKeyPackage(MlsCipherSuite suite, byte[] identity) + throws Exception { AsymmetricCipherKeyPair initKeyPair = suite.getHPKE().generatePrivateKey(); AsymmetricCipherKeyPair encryptionKeyPair = suite.getHPKE().generatePrivateKey(); @@ -247,34 +249,33 @@ private KeyPackageWithSecrets newKeyPackage(MlsCipherSuite suite, byte[] identit Credential cred = Credential.forBasic(identity); LeafNode leafNode = new LeafNode( - suite, - suite.getHPKE().serializePublicKey(encryptionKeyPair.getPublic()), - suite.serializeSignaturePublicKey(sigKeyPair.getPublic()), - cred, - new Capabilities(), - new LifeTime(), - new ArrayList<>(), - suite.serializeSignaturePrivateKey(sigKeyPair.getPrivate()) + suite, + suite.getHPKE().serializePublicKey(encryptionKeyPair.getPublic()), + suite.serializeSignaturePublicKey(sigKeyPair.getPublic()), + cred, + new Capabilities(), + new LifeTime(), + new ArrayList(), + suite.serializeSignaturePrivateKey(sigKeyPair.getPrivate()) ); KeyPackage kp = new KeyPackage( - suite, - suite.getHPKE().serializePublicKey(initKeyPair.getPublic()), - leafNode, - new ArrayList<>(), - suite.serializeSignaturePrivateKey(sigKeyPair.getPrivate()) + suite, + suite.getHPKE().serializePublicKey(initKeyPair.getPublic()), + leafNode, + new ArrayList(), + suite.serializeSignaturePrivateKey(sigKeyPair.getPrivate()) ); return new KeyPackageWithSecrets(initKeyPair, encryptionKeyPair, sigKeyPair, kp); - //TODO: cache transactions? - // return key package as byte string/array? } - private LeafIndex findMember(TreeKEMPublicKey tree, byte[] id) throws Exception + private LeafIndex findMember(TreeKEMPublicKey tree, byte[] id) + throws Exception { //find member LeafNode leaf; LeafIndex index; - for (int i = 0; i < tree.getSize().leafCount() ; i++) + for (int i = 0; i < tree.getSize().leafCount(); i++) { index = new LeafIndex(i); leaf = tree.getLeafNode(index); @@ -290,55 +291,56 @@ private LeafIndex findMember(TreeKEMPublicKey tree, byte[] id) throws Exception throw new Exception("Unknown member identity"); } - private Proposal proposalFromDescription(MlsCipherSuite suite, byte[] groupID, TreeKEMPublicKey tree, MlsClient.ProposalDescription desc) throws Exception + private Proposal proposalFromDescription(MlsCipherSuite suite, byte[] groupID, TreeKEMPublicKey tree, MlsClient.ProposalDescription desc) + throws Exception { SecureRandom random = new SecureRandom(); switch (desc.getProposalType().toStringUtf8()) { - case "add": - MLSMessage kp = (MLSMessage) MLSInputStream.decode(desc.getKeyPackage().toByteArray(), MLSMessage.class); - return Proposal.add(kp.keyPackage); - - case "remove": - LeafIndex removedIndex = findMember(tree, desc.getRemovedId().toByteArray()); - return Proposal.remove(removedIndex); - - case "externalPSK": - byte[] externalPskID = desc.getPskId().toByteArray(); - byte[] extNonce = new byte[suite.getKDF().getHashLength()]; - random.nextBytes(extNonce); - PreSharedKeyID extPskID = PreSharedKeyID.external(externalPskID, extNonce); - return Proposal.preSharedKey(extPskID); - - case "resumptionPSK": - long epoch = desc.getEpochId(); - byte[] resNonce = new byte[suite.getKDF().getHashLength()]; - PreSharedKeyID resPskID = PreSharedKeyID.resumption(ResumptionPSKUsage.APPLICATION, groupID, epoch, resNonce); - return Proposal.preSharedKey(resPskID); - - case "groupContextExtensions": - case "reinit": - List extList = new ArrayList<>(); - for (int i = 0; i < desc.getExtensionsCount(); i++) - { - Extension ext = new Extension(desc.getExtensions(i).getExtensionType(), desc.getExtensions(i).getExtensionData().toByteArray()); - extList.add(ext); - } + case "add": + MLSMessage kp = (MLSMessage)MLSInputStream.decode(desc.getKeyPackage().toByteArray(), MLSMessage.class); + return Proposal.add(kp.keyPackage); + + case "remove": + LeafIndex removedIndex = findMember(tree, desc.getRemovedId().toByteArray()); + return Proposal.remove(removedIndex); + + case "externalPSK": + byte[] externalPskID = desc.getPskId().toByteArray(); + byte[] extNonce = new byte[suite.getKDF().getHashLength()]; + random.nextBytes(extNonce); + PreSharedKeyID extPskID = PreSharedKeyID.external(externalPskID, extNonce); + return Proposal.preSharedKey(extPskID); + + case "resumptionPSK": + long epoch = desc.getEpochId(); + byte[] resNonce = new byte[suite.getKDF().getHashLength()]; + PreSharedKeyID resPskID = PreSharedKeyID.resumption(ResumptionPSKUsage.APPLICATION, groupID, epoch, resNonce); + return Proposal.preSharedKey(resPskID); + + case "groupContextExtensions": + case "reinit": + List extList = new ArrayList(); + for (int i = 0; i < desc.getExtensionsCount(); i++) + { + Extension ext = new Extension(desc.getExtensions(i).getExtensionType(), desc.getExtensions(i).getExtensionData().toByteArray()); + extList.add(ext); + } - if (desc.getProposalType().toStringUtf8().equals("reinit")) - { - return Proposal.reInit( - desc.getGroupId().toByteArray(), - ProtocolVersion.mls10, - MlsCipherSuite.getSuite((short) desc.getCipherSuite()), - extList - ); - } - // groupContextExtensions - return Proposal.groupContextExtensions(extList); + if (desc.getProposalType().toStringUtf8().equals("reinit")) + { + return Proposal.reInit( + desc.getGroupId().toByteArray(), + ProtocolVersion.mls10, + MlsCipherSuite.getSuite((short)desc.getCipherSuite()), + extList + ); + } + // groupContextExtensions + return Proposal.groupContextExtensions(extList); - default: - throw new IllegalStateException("Unknown proposal-by-value type: " + desc.getProposalType().toString()); + default: + throw new IllegalStateException("Unknown proposal-by-value type: " + desc.getProposalType().toString()); } } @@ -356,20 +358,28 @@ private void removeGroup(int stateID) * @param responseObserver */ private void nameImpl(MlsClient.NameRequest request, StreamObserver responseObserver) - { + { MlsClient.NameResponse response = MlsClient.NameResponse.newBuilder() - .setName("BouncyCastle") - .build(); + .setName("BouncyCastle") + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } + } @Override public void name(MlsClient.NameRequest request, StreamObserver responseObserver) { - catchWrap(() -> nameImpl(request, responseObserver), responseObserver); + catchWrap(new Function() + { + @Override + public void run() + throws Exception + { + nameImpl(request, responseObserver); + } + }, responseObserver); } /** @@ -381,9 +391,9 @@ public void name(MlsClient.NameRequest request, StreamObserver responseObserver) - { + { MlsClient.SupportedCiphersuitesResponse.Builder builder = MlsClient.SupportedCiphersuitesResponse.newBuilder() - .clearCiphersuites(); + .clearCiphersuites(); for (short id : ALL_SUPPORTED_SUITES) { @@ -393,11 +403,20 @@ private void supportedCiphersuitesImpl(MlsClient.SupportedCiphersuitesRequest re MlsClient.SupportedCiphersuitesResponse response = builder.build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void supportedCiphersuites(MlsClient.SupportedCiphersuitesRequest request, StreamObserver responseObserver) { - catchWrap(() -> supportedCiphersuitesImpl(request, responseObserver), responseObserver); + catchWrap(new Function() + { + @Override + public void run() + throws Exception + { + supportedCiphersuitesImpl(request, responseObserver); + } + }, responseObserver); } /** @@ -410,7 +429,7 @@ public void supportedCiphersuites(MlsClient.SupportedCiphersuitesRequest request */ public void createGroupImpl(MlsClient.CreateGroupRequest request, StreamObserver responseObserver) - throws Exception + throws Exception { byte[] groupID = request.getGroupId().toByteArray(); MlsCipherSuite suite = MlsCipherSuite.getSuite((short)request.getCipherSuite()); @@ -421,46 +440,56 @@ public void createGroupImpl(MlsClient.CreateGroupRequest request, StreamObserver Credential cred = Credential.forBasic(identity); LeafNode leafNode = new LeafNode( - suite, - suite.getHPKE().serializePublicKey(leafKeyPair.getPublic()), - suite.serializeSignaturePublicKey(sigKeyPair.getPublic()), - cred, - new Capabilities(), - new LifeTime(), - new ArrayList<>(), - suite.serializeSignaturePrivateKey(sigKeyPair.getPrivate()) + suite, + suite.getHPKE().serializePublicKey(leafKeyPair.getPublic()), + suite.serializeSignaturePublicKey(sigKeyPair.getPublic()), + cred, + new Capabilities(), + new LifeTime(), + new ArrayList(), + suite.serializeSignaturePrivateKey(sigKeyPair.getPrivate()) ); Group group = new Group( - groupID, - suite, - leafKeyPair, - suite.serializeSignaturePrivateKey(sigKeyPair.getPrivate()), - leafNode.copy(leafNode.getEncryptionKey()), - new ArrayList<>() + groupID, + suite, + leafKeyPair, + suite.serializeSignaturePrivateKey(sigKeyPair.getPrivate()), + leafNode.copy(leafNode.getEncryptionKey()), + new ArrayList() ); int stateId = storeGroup(group, request.getEncryptHandshake()); MlsClient.CreateGroupResponse response = MlsClient.CreateGroupResponse.newBuilder() - .setStateId(stateId) - .build(); + .setStateId(stateId) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); } -@Override + + @Override public void createGroup(MlsClient.CreateGroupRequest request, StreamObserver responseObserver) { - catchWrap(() -> createGroupImpl(request, responseObserver), responseObserver); + catchWrap(new Function() + { + @Override + public void run() + throws Exception + { + createGroupImpl(request, responseObserver); + } + }, responseObserver); } /** * @param request * @param responseObserver */ - private void createKeyPackageImpl(MlsClient.CreateKeyPackageRequest request, StreamObserver responseObserver) throws Exception + private void createKeyPackageImpl(MlsClient.CreateKeyPackageRequest request, StreamObserver responseObserver) + throws Exception { - MlsCipherSuite suite = MlsCipherSuite.getSuite((short)request.getCipherSuite()); + MlsCipherSuite suite = MlsCipherSuite.getSuite((short)request.getCipherSuite()); byte[] identity = request.getIdentity().toByteArray(); KeyPackageWithSecrets kpSecrets = newKeyPackage(suite, identity); @@ -468,27 +497,37 @@ private void createKeyPackageImpl(MlsClient.CreateKeyPackageRequest request, Str int joinID = storeJoin(kpSecrets); MlsClient.CreateKeyPackageResponse response = MlsClient.CreateKeyPackageResponse.newBuilder() - .setInitPriv(ByteString.copyFrom(suite.getHPKE().serializePrivateKey(kpSecrets.initKeyPair.getPrivate()))) - .setEncryptionPriv(ByteString.copyFrom(suite.getHPKE().serializePrivateKey(kpSecrets.encryptionKeyPair.getPrivate()))) - .setSignaturePriv(ByteString.copyFrom(suite.serializeSignaturePrivateKey(kpSecrets.signatureKeyPair.getPrivate()))) - .setKeyPackage(ByteString.copyFrom(MLSOutputStream.encode(MLSMessage.keyPackage(kpSecrets.keyPackage)))) - .setTransactionId(joinID) - .build(); + .setInitPriv(ByteString.copyFrom(suite.getHPKE().serializePrivateKey(kpSecrets.initKeyPair.getPrivate()))) + .setEncryptionPriv(ByteString.copyFrom(suite.getHPKE().serializePrivateKey(kpSecrets.encryptionKeyPair.getPrivate()))) + .setSignaturePriv(ByteString.copyFrom(suite.serializeSignaturePrivateKey(kpSecrets.signatureKeyPair.getPrivate()))) + .setKeyPackage(ByteString.copyFrom(MLSOutputStream.encode(MLSMessage.keyPackage(kpSecrets.keyPackage)))) + .setTransactionId(joinID) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void createKeyPackage(MlsClient.CreateKeyPackageRequest request, StreamObserver responseObserver) { - catchWrap(() -> createKeyPackageImpl(request, responseObserver), responseObserver); + catchWrap(new Function() + { + @Override + public void run() + throws Exception + { + createKeyPackageImpl(request, responseObserver); + } + }, responseObserver); } /** * @param request * @param responseObserver */ - private void joinGroupImpl(MlsClient.JoinGroupRequest request, StreamObserver responseObserver) throws Exception + private void joinGroupImpl(MlsClient.JoinGroupRequest request, StreamObserver responseObserver) + throws Exception { CachedJoin join = loadJoin(request.getTransactionId()); if (join == null) @@ -496,54 +535,64 @@ private void joinGroupImpl(MlsClient.JoinGroupRequest request, StreamObserver 0) + if (ratchetTreeBytes.length > 0) { - ratchetTree = (TreeKEMPublicKey) MLSInputStream.decode(ratchetTreeBytes, TreeKEMPublicKey.class); + ratchetTree = (TreeKEMPublicKey)MLSInputStream.decode(ratchetTreeBytes, TreeKEMPublicKey.class); ratchetTree.setSuite(welcomeMsg.getCipherSuite()); } MlsCipherSuite suite = welcome.getSuite(); Group group = new Group( - suite.getHPKE().serializePrivateKey(join.kpSecrets.initKeyPair.getPrivate()), - join.kpSecrets.encryptionKeyPair, - suite.serializeSignaturePrivateKey(join.kpSecrets.signatureKeyPair.getPrivate()), - join.kpSecrets.keyPackage, - welcome, - ratchetTree, - join.externalPsks, - new HashMap<>() + suite.getHPKE().serializePrivateKey(join.kpSecrets.initKeyPair.getPrivate()), + join.kpSecrets.encryptionKeyPair, + suite.serializeSignaturePrivateKey(join.kpSecrets.signatureKeyPair.getPrivate()), + join.kpSecrets.keyPackage, + welcome, + ratchetTree, + join.externalPsks, + new HashMap() ); byte[] epochAuthenticator = group.getEpochAuthenticator(); int stateID = storeGroup(group, request.getEncryptHandshake()); MlsClient.JoinGroupResponse response = MlsClient.JoinGroupResponse.newBuilder() - .setStateId(stateID) - .setEpochAuthenticator(ByteString.copyFrom(epochAuthenticator)) - .build(); + .setStateId(stateID) + .setEpochAuthenticator(ByteString.copyFrom(epochAuthenticator)) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void joinGroup(MlsClient.JoinGroupRequest request, StreamObserver responseObserver) { - catchWrap(() -> joinGroupImpl(request, responseObserver), responseObserver); + catchWrap(new Function() + { + @Override + public void run() + throws Exception + { + joinGroupImpl(request, responseObserver); + } + }, responseObserver); } /** * @param request * @param responseObserver */ - private void externalJoinImpl(MlsClient.ExternalJoinRequest request, StreamObserver responseObserver) throws Exception + private void externalJoinImpl(MlsClient.ExternalJoinRequest request, StreamObserver responseObserver) + throws Exception { - MLSMessage groupInfoMsg = (MLSMessage) MLSInputStream.decode(request.getGroupInfo().toByteArray(), MLSMessage.class); + MLSMessage groupInfoMsg = (MLSMessage)MLSInputStream.decode(request.getGroupInfo().toByteArray(), MLSMessage.class); GroupInfo groupInfo = groupInfoMsg.groupInfo; MlsCipherSuite suite = groupInfo.getSuite(); @@ -554,29 +603,29 @@ private void externalJoinImpl(MlsClient.ExternalJoinRequest request, StreamObser Credential cred = Credential.forBasic(identity); LeafNode leafNode = new LeafNode( - suite, - suite.getHPKE().serializePublicKey(leafKeyPair.getPublic()), - suite.serializeSignaturePublicKey(sigKeyPair.getPublic()), - cred, - new Capabilities(), - new LifeTime(), - new ArrayList<>(), - suite.serializeSignaturePrivateKey(sigKeyPair.getPrivate()) + suite, + suite.getHPKE().serializePublicKey(leafKeyPair.getPublic()), + suite.serializeSignaturePublicKey(sigKeyPair.getPublic()), + cred, + new Capabilities(), + new LifeTime(), + new ArrayList(), + suite.serializeSignaturePrivateKey(sigKeyPair.getPrivate()) ); KeyPackage kp = new KeyPackage( - suite, - suite.getHPKE().serializePublicKey(initKeyPair.getPublic()), - leafNode, - new ArrayList<>(), - suite.serializeSignaturePrivateKey(sigKeyPair.getPrivate()) + suite, + suite.getHPKE().serializePublicKey(initKeyPair.getPublic()), + leafNode, + new ArrayList(), + suite.serializeSignaturePrivateKey(sigKeyPair.getPrivate()) ); byte[] ratchetTreeBytes = request.getRatchetTree().toByteArray(); TreeKEMPublicKey ratchetTree = null; if (ratchetTreeBytes.length > 0) { - ratchetTree = (TreeKEMPublicKey) MLSInputStream.decode(ratchetTreeBytes, TreeKEMPublicKey.class); + ratchetTree = (TreeKEMPublicKey)MLSInputStream.decode(ratchetTreeBytes, TreeKEMPublicKey.class); ratchetTree.setSuite(suite); } @@ -596,7 +645,6 @@ private void externalJoinImpl(MlsClient.ExternalJoinRequest request, StreamObser } if (ratchetTree != null) { - //TODO: check if it should be a deep copy outTree = TreeKEMPublicKey.clone(ratchetTree); } else if (outTree == null) @@ -626,7 +674,7 @@ else if (outTree == null) } } // Install PSKs - Map externalPSKs = new HashMap<>(); + Map externalPSKs = new HashMap(); for (int i = 0; i < request.getPsksCount(); i++) { MlsClient.PreSharedKey psk = request.getPsks(i); @@ -640,30 +688,39 @@ else if (outTree == null) random.nextBytes(leafSecret); Group.GroupWithMessage gwm = Group.externalJoin( - new Secret(leafSecret), - sigKeyPair, - kp, - groupInfo, - ratchetTree, - new Group.MessageOptions(false, new byte[0], 0),// encrypt should be false for external join! - removeIndex, - externalPSKs + new Secret(leafSecret), + sigKeyPair, + kp, + groupInfo, + ratchetTree, + new Group.MessageOptions(false, new byte[0], 0),// encrypt should be false for external join! + removeIndex, + externalPSKs ); int stateID = storeGroup(gwm.group, false); MlsClient.ExternalJoinResponse response = MlsClient.ExternalJoinResponse.newBuilder() - .setStateId(stateID) - .setCommit(ByteString.copyFrom(MLSOutputStream.encode(gwm.message))) - .setEpochAuthenticator(ByteString.copyFrom(gwm.group.getEpochAuthenticator())) - .build(); + .setStateId(stateID) + .setCommit(ByteString.copyFrom(MLSOutputStream.encode(gwm.message))) + .setEpochAuthenticator(ByteString.copyFrom(gwm.group.getEpochAuthenticator())) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void externalJoin(MlsClient.ExternalJoinRequest request, StreamObserver responseObserver) { - catchWrap(() -> externalJoinImpl(request, responseObserver), responseObserver); + catchWrap(new Function() + { + @Override + public void run() + throws Exception + { + externalJoinImpl(request, responseObserver); + } + }, responseObserver); } /** @@ -674,12 +731,13 @@ public void externalJoin(MlsClient.ExternalJoinRequest request, StreamObserver responseObserver) throws Exception + private void groupInfoImpl(CachedGroup entry, MlsClient.GroupInfoRequest request, StreamObserver responseObserver) + throws Exception { boolean inlineTree = !request.getExternalTree(); MLSMessage groupInfo = entry.group.getGroupInfo(inlineTree); MlsClient.GroupInfoResponse.Builder builder = MlsClient.GroupInfoResponse.newBuilder() - .setGroupInfo(ByteString.copyFrom(MLSOutputStream.encode(groupInfo))); + .setGroupInfo(ByteString.copyFrom(MLSOutputStream.encode(groupInfo))); if (!inlineTree) { builder.setRatchetTree(ByteString.copyFrom(MLSOutputStream.encode(entry.group.getTree()))); @@ -688,11 +746,21 @@ private void groupInfoImpl(CachedGroup entry, MlsClient.GroupInfoRequest request MlsClient.GroupInfoResponse response = builder.build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void groupInfo(MlsClient.GroupInfoRequest request, StreamObserver responseObserver) { - stateWrap(group -> groupInfoImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + groupInfoImpl(group, request, responseObserver); + } + }, request, responseObserver); + } /** @@ -700,74 +768,104 @@ public void groupInfo(MlsClient.GroupInfoRequest request, StreamObserver responseObserver) - { + { MlsClient.StateAuthResponse response = MlsClient.StateAuthResponse.newBuilder() - .setStateAuthSecret(ByteString.copyFrom(entry.group.getEpochAuthenticator())) - .build(); + .setStateAuthSecret(ByteString.copyFrom(entry.group.getEpochAuthenticator())) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void stateAuth(MlsClient.StateAuthRequest request, StreamObserver responseObserver) { - stateWrap(group -> stateAuthImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + stateAuthImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void exportImpl(CachedGroup entry, MlsClient.ExportRequest request, StreamObserver responseObserver) throws IOException + private void exportImpl(CachedGroup entry, MlsClient.ExportRequest request, StreamObserver responseObserver) + throws IOException { String label = request.getLabel(); byte[] context = request.getContext().toByteArray(); int size = request.getKeyLength(); byte[] secret = entry.group.getKeySchedule().MLSExporter(label, context, size); MlsClient.ExportResponse response = MlsClient.ExportResponse.newBuilder() - .setExportedSecret(ByteString.copyFrom(secret)) - .build(); + .setExportedSecret(ByteString.copyFrom(secret)) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void export(MlsClient.ExportRequest request, StreamObserver responseObserver) { - stateWrap(group -> exportImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + exportImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void protectImpl(CachedGroup entry, MlsClient.ProtectRequest request, StreamObserver responseObserver) throws Exception + private void protectImpl(CachedGroup entry, MlsClient.ProtectRequest request, StreamObserver responseObserver) + throws Exception { MLSMessage ct = entry.group.protect( - request.getAuthenticatedData().toByteArray(), - request.getPlaintext().toByteArray(), - 0 + request.getAuthenticatedData().toByteArray(), + request.getPlaintext().toByteArray(), + 0 ); MlsClient.ProtectResponse response = MlsClient.ProtectResponse.newBuilder() - .setCiphertext(ByteString.copyFrom(MLSOutputStream.encode(ct))) - .build(); + .setCiphertext(ByteString.copyFrom(MLSOutputStream.encode(ct))) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void protect(MlsClient.ProtectRequest request, StreamObserver responseObserver) { - stateWrap(group -> protectImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + protectImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void unprotectImpl(CachedGroup entry, MlsClient.UnprotectRequest request, StreamObserver responseObserver) throws Exception + private void unprotectImpl(CachedGroup entry, MlsClient.UnprotectRequest request, StreamObserver responseObserver) + throws Exception { - MLSMessage ct = (MLSMessage) MLSInputStream.decode(request.getCiphertext().toByteArray(), MLSMessage.class); + MLSMessage ct = (MLSMessage)MLSInputStream.decode(request.getCiphertext().toByteArray(), MLSMessage.class); // Locate the right epoch to decrypt with byte[] groupID = entry.group.getGroupID(); @@ -789,24 +887,34 @@ private void unprotectImpl(CachedGroup entry, MlsClient.UnprotectRequest request byte[] pt = authAndPt[1]; MlsClient.UnprotectResponse response = MlsClient.UnprotectResponse.newBuilder() - .setAuthenticatedData(ByteString.copyFrom(aad)) - .setPlaintext(ByteString.copyFrom(pt)) - .build(); + .setAuthenticatedData(ByteString.copyFrom(aad)) + .setPlaintext(ByteString.copyFrom(pt)) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void unprotect(MlsClient.UnprotectRequest request, StreamObserver responseObserver) { - stateWrap(group -> unprotectImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + unprotectImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void storePSKImpl(MlsClient.StorePSKRequest request, StreamObserver responseObserver) throws StatusException + private void storePSKImpl(MlsClient.StorePSKRequest request, StreamObserver responseObserver) + throws StatusException { MlsClient.StorePSKResponse response = MlsClient.StorePSKResponse.newBuilder().build(); int id = request.getStateOrTransactionId(); @@ -832,130 +940,190 @@ private void storePSKImpl(MlsClient.StorePSKRequest request, StreamObserver responseObserver) { - catchWrap(() -> storePSKImpl(request, responseObserver), responseObserver); + catchWrap(new Function() + { + @Override + public void run() + throws Exception + { + storePSKImpl(request, responseObserver); + } + }, responseObserver); } /** * @param request * @param responseObserver */ - private void addProposalImpl(CachedGroup entry, MlsClient.AddProposalRequest request, StreamObserver responseObserver) throws Exception + private void addProposalImpl(CachedGroup entry, MlsClient.AddProposalRequest request, StreamObserver responseObserver) + throws Exception { - MLSMessage keyPackage = (MLSMessage) MLSInputStream.decode(request.getKeyPackage().toByteArray(), MLSMessage.class); + MLSMessage keyPackage = (MLSMessage)MLSInputStream.decode(request.getKeyPackage().toByteArray(), MLSMessage.class); MLSMessage message = entry.group.add(keyPackage.keyPackage, entry.messageOptions); MlsClient.ProposalResponse response = MlsClient.ProposalResponse.newBuilder() - .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) - .build(); + .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void addProposal(MlsClient.AddProposalRequest request, StreamObserver responseObserver) { - stateWrap(group -> addProposalImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + addProposalImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void updateProposalImpl(CachedGroup entry, MlsClient.UpdateProposalRequest request, StreamObserver responseObserver) throws Exception + private void updateProposalImpl(CachedGroup entry, MlsClient.UpdateProposalRequest request, StreamObserver responseObserver) + throws Exception { AsymmetricCipherKeyPair leafSk = entry.group.getSuite().getHPKE().generatePrivateKey(); Proposal update = entry.group.updateProposal(leafSk, new Group.LeafNodeOptions()); MLSMessage message = entry.group.update(update, entry.messageOptions); MlsClient.ProposalResponse response = MlsClient.ProposalResponse.newBuilder() - .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) - .build(); + .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void updateProposal(MlsClient.UpdateProposalRequest request, StreamObserver responseObserver) { - stateWrap(group -> updateProposalImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + updateProposalImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void removeProposalImpl(CachedGroup entry, MlsClient.RemoveProposalRequest request, StreamObserver responseObserver) throws Exception + private void removeProposalImpl(CachedGroup entry, MlsClient.RemoveProposalRequest request, StreamObserver responseObserver) + throws Exception { LeafIndex removedIndex = findMember(entry.group.getTree(), request.getRemovedId().toByteArray()); MLSMessage message = entry.group.remove(removedIndex, entry.messageOptions); MlsClient.ProposalResponse response = MlsClient.ProposalResponse.newBuilder() - .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) - .build(); + .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void removeProposal(MlsClient.RemoveProposalRequest request, StreamObserver responseObserver) { - stateWrap(group -> removeProposalImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + removeProposalImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void externalPSKProposalImpl(CachedGroup entry, MlsClient.ExternalPSKProposalRequest request, StreamObserver responseObserver) throws Exception + private void externalPSKProposalImpl(CachedGroup entry, MlsClient.ExternalPSKProposalRequest request, StreamObserver responseObserver) + throws Exception { byte[] pskID = request.getPskId().toByteArray(); MLSMessage message = entry.group.preSharedKey(pskID, entry.messageOptions); MlsClient.ProposalResponse response = MlsClient.ProposalResponse.newBuilder() - .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) - .build(); + .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void externalPSKProposal(MlsClient.ExternalPSKProposalRequest request, StreamObserver responseObserver) { - stateWrap(group -> externalPSKProposalImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + externalPSKProposalImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void resumptionPSKProposalImpl(CachedGroup entry, MlsClient.ResumptionPSKProposalRequest request, StreamObserver responseObserver) throws Exception + private void resumptionPSKProposalImpl(CachedGroup entry, MlsClient.ResumptionPSKProposalRequest request, StreamObserver responseObserver) + throws Exception { MLSMessage message = entry.group.preSharedKey(entry.group.getGroupID(), request.getEpochId(), entry.messageOptions); MlsClient.ProposalResponse response = MlsClient.ProposalResponse.newBuilder() - .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) - .build(); + .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void resumptionPSKProposal(MlsClient.ResumptionPSKProposalRequest request, StreamObserver responseObserver) { - stateWrap(group -> resumptionPSKProposalImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + resumptionPSKProposalImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void groupContextExtensionsProposalImpl(CachedGroup entry, MlsClient.GroupContextExtensionsProposalRequest request, StreamObserver responseObserver) throws Exception + private void groupContextExtensionsProposalImpl(CachedGroup entry, MlsClient.GroupContextExtensionsProposalRequest request, StreamObserver responseObserver) + throws Exception { - List extList = new ArrayList<>(); + List extList = new ArrayList(); for (int i = 0; i < request.getExtensionsCount(); i++) { Extension ext = new Extension(request.getExtensions(i).getExtensionType(), request.getExtensions(i).getExtensionData().toByteArray()); @@ -965,23 +1133,33 @@ private void groupContextExtensionsProposalImpl(CachedGroup entry, MlsClient.Gro MLSMessage message = entry.group.groupContextExtensions(extList, entry.messageOptions); MlsClient.ProposalResponse response = MlsClient.ProposalResponse.newBuilder() - .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) - .build(); + .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void groupContextExtensionsProposal(MlsClient.GroupContextExtensionsProposalRequest request, StreamObserver responseObserver) { - stateWrap(group -> groupContextExtensionsProposalImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + groupContextExtensionsProposalImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void commitImpl(CachedGroup entry, MlsClient.CommitRequest request, StreamObserver responseObserver) throws Exception + private void commitImpl(CachedGroup entry, MlsClient.CommitRequest request, StreamObserver responseObserver) + throws Exception { int byRefSize = request.getByReferenceCount(); for (int i = 0; i < byRefSize; i++) @@ -995,15 +1173,15 @@ private void commitImpl(CachedGroup entry, MlsClient.CommitRequest request, Stre } // create by value proposals - List byValue = new ArrayList<>(); + List byValue = new ArrayList(); for (int i = 0; i < request.getByValueCount(); i++) { MlsClient.ProposalDescription desc = request.getByValue(i); Proposal proposal = proposalFromDescription( - entry.group.getSuite(), - entry.group.getGroupID(), - entry.group.getTree(), - desc + entry.group.getSuite(), + entry.group.getGroupID(), + entry.group.getTree(), + desc ); byValue.add(proposal); } @@ -1015,24 +1193,23 @@ private void commitImpl(CachedGroup entry, MlsClient.CommitRequest request, Stre byte[] leafSecret = new byte[entry.group.getSuite().getKDF().getHashLength()]; random.nextBytes(leafSecret); Group.GroupWithMessage gwm = entry.group.commit( - new Secret(leafSecret), - new Group.CommitOptions(byValue, inlineTree, forcePath, null), - entry.messageOptions, - new Group.CommitParameters(NORMAL_COMMIT_PARAMS) + new Secret(leafSecret), + new Group.CommitOptions(byValue, inlineTree, forcePath, null), + entry.messageOptions, + new Group.CommitParameters(NORMAL_COMMIT_PARAMS) ); byte[] commitBytes = MLSOutputStream.encode(gwm.message); gwm.message.wireFormat = WireFormat.mls_welcome; byte[] welcomeBytes = MLSOutputStream.encode(gwm.message); - //TODO: check if entry.group should/shouldn't be replaced by commit() int nextID = storeGroup(gwm.group, entry.encryptHandshake); entry.pendingCommit = commitBytes; entry.pendingGroupID = nextID; MlsClient.CommitResponse.Builder builder = MlsClient.CommitResponse.newBuilder() - .setCommit(ByteString.copyFrom(commitBytes)) - .setWelcome(ByteString.copyFrom(welcomeBytes)); + .setCommit(ByteString.copyFrom(commitBytes)) + .setWelcome(ByteString.copyFrom(welcomeBytes)); if (!inlineTree) { @@ -1041,26 +1218,36 @@ private void commitImpl(CachedGroup entry, MlsClient.CommitRequest request, Stre responseObserver.onNext(builder.build()); responseObserver.onCompleted(); - } -@Override + } + + @Override public void commit(MlsClient.CommitRequest request, StreamObserver responseObserver) { - stateWrap(group -> commitImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + commitImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void handleCommitImpl(CachedGroup entry, MlsClient.HandleCommitRequest request, StreamObserver responseObserver) throws Exception + private void handleCommitImpl(CachedGroup entry, MlsClient.HandleCommitRequest request, StreamObserver responseObserver) + throws Exception { // Handle our own commits with caching byte[] commitBytes = request.getCommit().toByteArray(); if (entry.pendingCommit != null && Arrays.equals(commitBytes, entry.pendingCommit)) { MlsClient.HandleCommitResponse response = MlsClient.HandleCommitResponse.newBuilder() - .setStateId(entry.pendingGroupID) - .build(); + .setStateId(entry.pendingGroupID) + .build(); entry.resetPending(); responseObserver.onNext(response); @@ -1094,24 +1281,34 @@ else if (entry.pendingGroupID != -1) int nextID = storeGroup(next, entry.encryptHandshake); MlsClient.HandleCommitResponse response = MlsClient.HandleCommitResponse.newBuilder() - .setStateId(nextID) - .setEpochAuthenticator(ByteString.copyFrom(epochAuthenticator)) - .build(); + .setStateId(nextID) + .setEpochAuthenticator(ByteString.copyFrom(epochAuthenticator)) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void handleCommit(MlsClient.HandleCommitRequest request, StreamObserver responseObserver) { - stateWrap(group -> handleCommitImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + handleCommitImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void handlePendingCommitImpl(CachedGroup entry, MlsClient.HandlePendingCommitRequest request, StreamObserver responseObserver) throws Exception + private void handlePendingCommitImpl(CachedGroup entry, MlsClient.HandlePendingCommitRequest request, StreamObserver responseObserver) + throws Exception { if (entry.pendingCommit == null || entry.pendingGroupID == -1) { @@ -1127,17 +1324,26 @@ private void handlePendingCommitImpl(CachedGroup entry, MlsClient.HandlePendingC byte[] epochAuthenticator = next.group.getEpochAuthenticator(); MlsClient.HandleCommitResponse response = MlsClient.HandleCommitResponse.newBuilder() - .setStateId(nextID) - .setEpochAuthenticator(ByteString.copyFrom(epochAuthenticator)) - .build(); + .setStateId(nextID) + .setEpochAuthenticator(ByteString.copyFrom(epochAuthenticator)) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void handlePendingCommit(MlsClient.HandlePendingCommitRequest request, StreamObserver responseObserver) { - stateWrap(group -> handlePendingCommitImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + handlePendingCommitImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** @@ -1148,13 +1354,14 @@ public void handlePendingCommit(MlsClient.HandlePendingCommitRequest request, St * @param request * @param responseObserver */ - private void reInitProposalImpl(CachedGroup entry, MlsClient.ReInitProposalRequest request, StreamObserver responseObserver) throws Exception + private void reInitProposalImpl(CachedGroup entry, MlsClient.ReInitProposalRequest request, StreamObserver responseObserver) + throws Exception { byte[] groupID = request.getGroupId().toByteArray(); ProtocolVersion version = ProtocolVersion.mls10; - MlsCipherSuite suite = MlsCipherSuite.getSuite((short) request.getCipherSuite()); + MlsCipherSuite suite = MlsCipherSuite.getSuite((short)request.getCipherSuite()); - List extList = new ArrayList<>(); + List extList = new ArrayList(); for (int i = 0; i < request.getExtensionsCount(); i++) { Extension ext = new Extension(request.getExtensions(i).getExtensionType(), request.getExtensions(i).getExtensionData().toByteArray()); @@ -1163,23 +1370,33 @@ private void reInitProposalImpl(CachedGroup entry, MlsClient.ReInitProposalReque MLSMessage message = entry.group.reinit(groupID, version, suite, extList, entry.messageOptions); MlsClient.ProposalResponse response = MlsClient.ProposalResponse.newBuilder() - .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) - .build(); + .setProposal(ByteString.copyFrom(MLSOutputStream.encode(message))) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void reInitProposal(MlsClient.ReInitProposalRequest request, StreamObserver responseObserver) { - stateWrap(group -> reInitProposalImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + reInitProposalImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void reInitCommitImpl(CachedGroup entry, MlsClient.CommitRequest request, StreamObserver responseObserver) throws Exception + private void reInitCommitImpl(CachedGroup entry, MlsClient.CommitRequest request, StreamObserver responseObserver) + throws Exception { boolean inlineTree = !request.getExternalTree(); boolean forcePath = request.getForcePath(); @@ -1199,37 +1416,48 @@ private void reInitCommitImpl(CachedGroup entry, MlsClient.CommitRequest request SecureRandom random = new SecureRandom(); byte[] leafSecret = new byte[entry.group.getSuite().getKDF().getHashLength()]; random.nextBytes(leafSecret); - Group.CommitOptions commitOptions = new Group.CommitOptions(new ArrayList<>(), inlineTree, forcePath, null); + Group.CommitOptions commitOptions = new Group.CommitOptions(new ArrayList(), inlineTree, forcePath, null); Group.TombstoneWithMessage twm = entry.group.reinitCommit(leafSecret, commitOptions, entry.messageOptions); // cache the reinit LeafNode leaf = entry.group.getTree().getLeafNode(entry.group.getIndex()); byte[] identity = leaf.getCredential().getIdentity(); - KeyPackageWithSecrets kpSk = newKeyPackage(twm.getSuite(), identity);; + KeyPackageWithSecrets kpSk = newKeyPackage(twm.getSuite(), identity); + ; int reinitID = storeReinit(kpSk, twm, entry.encryptHandshake); byte[] commitBytes = MLSOutputStream.encode(twm.getMessage()); MlsClient.CommitResponse response = MlsClient.CommitResponse.newBuilder() - .setCommit(ByteString.copyFrom(commitBytes)) - .build(); + .setCommit(ByteString.copyFrom(commitBytes)) + .build(); entry.pendingCommit = commitBytes; entry.pendingGroupID = reinitID; responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void reInitCommit(MlsClient.CommitRequest request, StreamObserver responseObserver) { - stateWrap(group -> reInitCommitImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + reInitCommitImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void handlePendingReInitCommitImpl(CachedGroup entry, MlsClient.HandlePendingCommitRequest request, StreamObserver responseObserver) throws Exception + private void handlePendingReInitCommitImpl(CachedGroup entry, MlsClient.HandlePendingCommitRequest request, StreamObserver responseObserver) + throws Exception { if (entry.pendingCommit == null || entry.pendingGroupID == -1) { @@ -1245,25 +1473,35 @@ private void handlePendingReInitCommitImpl(CachedGroup entry, MlsClient.HandlePe } MlsClient.HandleReInitCommitResponse response = MlsClient.HandleReInitCommitResponse.newBuilder() - .setReinitId(reinitID) - .setKeyPackage(ByteString.copyFrom(MLSOutputStream.encode(MLSMessage.keyPackage(reinit.kpSk.keyPackage)))) - .setEpochAuthenticator(ByteString.copyFrom(reinit.tombstone.getEpochAuthenticator())) - .build(); + .setReinitId(reinitID) + .setKeyPackage(ByteString.copyFrom(MLSOutputStream.encode(MLSMessage.keyPackage(reinit.kpSk.keyPackage)))) + .setEpochAuthenticator(ByteString.copyFrom(reinit.tombstone.getEpochAuthenticator())) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void handlePendingReInitCommit(MlsClient.HandlePendingCommitRequest request, StreamObserver responseObserver) { - stateWrap(group -> handlePendingReInitCommitImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + handlePendingReInitCommitImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void handleReInitCommitImpl(CachedGroup entry, MlsClient.HandleCommitRequest request, StreamObserver responseObserver) throws Exception + private void handleReInitCommitImpl(CachedGroup entry, MlsClient.HandleCommitRequest request, StreamObserver responseObserver) + throws Exception { //TODO: Reinit proposal must be provided by reference for now if (request.getProposalCount() != 1) @@ -1277,7 +1515,7 @@ private void handleReInitCommitImpl(CachedGroup entry, MlsClient.HandleCommitReq throw new Exception("Commit included among proposals"); } - MLSMessage commit = (MLSMessage) MLSInputStream.decode(request.getCommit().toByteArray(), MLSMessage.class); + MLSMessage commit = (MLSMessage)MLSInputStream.decode(request.getCommit().toByteArray(), MLSMessage.class); Group.Tombstone tombstone = entry.group.handleReinitCommit(commit); // Cache the reinit @@ -1288,25 +1526,35 @@ private void handleReInitCommitImpl(CachedGroup entry, MlsClient.HandleCommitReq int reinitID = storeReinit(kpSk, tombstone, entry.encryptHandshake); MlsClient.HandleReInitCommitResponse response = MlsClient.HandleReInitCommitResponse.newBuilder() - .setReinitId(reinitID) - .setKeyPackage(ByteString.copyFrom(MLSOutputStream.encode(MLSMessage.keyPackage(kpSk.keyPackage)))) - .setEpochAuthenticator(ByteString.copyFrom(tombstone.getEpochAuthenticator())) - .build(); + .setReinitId(reinitID) + .setKeyPackage(ByteString.copyFrom(MLSOutputStream.encode(MLSMessage.keyPackage(kpSk.keyPackage)))) + .setEpochAuthenticator(ByteString.copyFrom(tombstone.getEpochAuthenticator())) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void handleReInitCommit(MlsClient.HandleCommitRequest request, StreamObserver responseObserver) { - stateWrap(group -> handleReInitCommitImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + handleReInitCommitImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void reInitWelcomeImpl(MlsClient.ReInitWelcomeRequest request, StreamObserver responseObserver) throws Exception + private void reInitWelcomeImpl(MlsClient.ReInitWelcomeRequest request, StreamObserver responseObserver) + throws Exception { // Load the reinit CachedReinit reinit = loadReinit(request.getReinitId()); @@ -1316,10 +1564,10 @@ private void reInitWelcomeImpl(MlsClient.ReInitWelcomeRequest request, StreamObs } // Import the KeyPackages - List keyPackages = new ArrayList<>(); + List keyPackages = new ArrayList(); for (int i = 0; i < request.getKeyPackageCount(); i++) { - MLSMessage message = (MLSMessage) MLSInputStream.decode(request.getKeyPackage(i).toByteArray(), MLSMessage.class); + MLSMessage message = (MLSMessage)MLSInputStream.decode(request.getKeyPackage(i).toByteArray(), MLSMessage.class); keyPackages.add(message.keyPackage); } @@ -1330,21 +1578,21 @@ private void reInitWelcomeImpl(MlsClient.ReInitWelcomeRequest request, StreamObs byte[] leafSecret = new byte[suite.getKDF().getHashLength()]; Group.GroupWithMessage gwm = reinit.tombstone.createWelcome( - reinit.kpSk.encryptionKeyPair, - suite.serializeSignaturePrivateKey(reinit.kpSk.signatureKeyPair.getPrivate()), - reinit.kpSk.keyPackage.getLeafNode(), - keyPackages, - leafSecret, - new Group.CommitOptions(null, inlineTree, forcePath, null) + reinit.kpSk.encryptionKeyPair, + suite.serializeSignaturePrivateKey(reinit.kpSk.signatureKeyPair.getPrivate()), + reinit.kpSk.keyPackage.getLeafNode(), + keyPackages, + leafSecret, + new Group.CommitOptions(null, inlineTree, forcePath, null) ); byte[] welcomeData = MLSOutputStream.encode(gwm.message); // Store the resulting state int stateID = storeGroup(gwm.group, reinit.encryptHandshake); MlsClient.CreateSubgroupResponse.Builder builder = MlsClient.CreateSubgroupResponse.newBuilder() - .setStateId(stateID) - .setWelcome(ByteString.copyFrom(welcomeData)) - .setEpochAuthenticator(ByteString.copyFrom(gwm.group.getEpochAuthenticator())); + .setStateId(stateID) + .setWelcome(ByteString.copyFrom(welcomeData)) + .setEpochAuthenticator(ByteString.copyFrom(gwm.group.getEpochAuthenticator())); if (!inlineTree) { @@ -1353,18 +1601,28 @@ private void reInitWelcomeImpl(MlsClient.ReInitWelcomeRequest request, StreamObs responseObserver.onNext(builder.build()); responseObserver.onCompleted(); - } -@Override + } + + @Override public void reInitWelcome(MlsClient.ReInitWelcomeRequest request, StreamObserver responseObserver) { - catchWrap(() -> reInitWelcomeImpl(request, responseObserver), responseObserver); + catchWrap(new Function() + { + @Override + public void run() + throws Exception + { + reInitWelcomeImpl(request, responseObserver); + } + }, responseObserver); } /** * @param request * @param responseObserver */ - private void handleReInitWelcomeImpl(MlsClient.HandleReInitWelcomeRequest request, StreamObserver responseObserver) throws Exception + private void handleReInitWelcomeImpl(MlsClient.HandleReInitWelcomeRequest request, StreamObserver responseObserver) + throws Exception { // Load the reinit CachedReinit reinit = loadReinit(request.getReinitId()); @@ -1374,40 +1632,49 @@ private void handleReInitWelcomeImpl(MlsClient.HandleReInitWelcomeRequest reques } // Process the welcome - MLSMessage welcome = (MLSMessage) MLSInputStream.decode(request.getWelcome().toByteArray(), MLSMessage.class); + MLSMessage welcome = (MLSMessage)MLSInputStream.decode(request.getWelcome().toByteArray(), MLSMessage.class); byte[] ratchetTreeBytes = request.getRatchetTree().toByteArray(); TreeKEMPublicKey ratchetTree = null; if (ratchetTreeBytes.length > 0) { - ratchetTree = (TreeKEMPublicKey) MLSInputStream.decode(ratchetTreeBytes, TreeKEMPublicKey.class); + ratchetTree = (TreeKEMPublicKey)MLSInputStream.decode(ratchetTreeBytes, TreeKEMPublicKey.class); ratchetTree.setSuite(welcome.getCipherSuite()); } Group group = reinit.tombstone.handleWelcome( - reinit.kpSk.initKeyPair, - reinit.kpSk.encryptionKeyPair, - reinit.kpSk.signatureKeyPair, - reinit.kpSk.keyPackage, - welcome, - ratchetTree + reinit.kpSk.initKeyPair, + reinit.kpSk.encryptionKeyPair, + reinit.kpSk.signatureKeyPair, + reinit.kpSk.keyPackage, + welcome, + ratchetTree ); // Store the resulting group int stateID = storeGroup(group, reinit.encryptHandshake); MlsClient.JoinGroupResponse response = MlsClient.JoinGroupResponse.newBuilder() - .setStateId(stateID) - .setEpochAuthenticator(ByteString.copyFrom(group.getEpochAuthenticator())) - .build(); + .setStateId(stateID) + .setEpochAuthenticator(ByteString.copyFrom(group.getEpochAuthenticator())) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void handleReInitWelcome(MlsClient.HandleReInitWelcomeRequest request, StreamObserver responseObserver) { - catchWrap(() -> handleReInitWelcomeImpl(request, responseObserver), responseObserver); + catchWrap(new Function() + { + @Override + public void run() + throws Exception + { + handleReInitWelcomeImpl(request, responseObserver); + } + }, responseObserver); } /** @@ -1418,18 +1685,19 @@ public void handleReInitWelcome(MlsClient.HandleReInitWelcomeRequest request, St * @param request * @param responseObserver */ - private void createBranchImpl(CachedGroup entry, MlsClient.CreateBranchRequest request, StreamObserver responseObserver) throws Exception + private void createBranchImpl(CachedGroup entry, MlsClient.CreateBranchRequest request, StreamObserver responseObserver) + throws Exception { // Import KeyPackages - List keyPackages = new ArrayList<>(); + List keyPackages = new ArrayList(); for (int i = 0; i < request.getKeyPackagesCount(); i++) { - MLSMessage message = (MLSMessage) MLSInputStream.decode(request.getKeyPackages(i).toByteArray(), MLSMessage.class); + MLSMessage message = (MLSMessage)MLSInputStream.decode(request.getKeyPackages(i).toByteArray(), MLSMessage.class); keyPackages.add(message.keyPackage); } // Import extensions - List extList = new ArrayList<>(); + List extList = new ArrayList(); for (int i = 0; i < request.getExtensionsCount(); i++) { Extension ext = new Extension(request.getExtensions(i).getExtensionType(), request.getExtensions(i).getExtensionData().toByteArray()); @@ -1450,22 +1718,22 @@ private void createBranchImpl(CachedGroup entry, MlsClient.CreateBranchRequest r random.nextBytes(leafSecret); Group.GroupWithMessage gwm = entry.group.createBranch( - groupID, - kpSK.encryptionKeyPair, - kpSK.signatureKeyPair, - kpSK.keyPackage.getLeafNode(), - extList, - keyPackages, - leafSecret, - new Group.CommitOptions(null, inlineTree, forcePath, null) + groupID, + kpSK.encryptionKeyPair, + kpSK.signatureKeyPair, + kpSK.keyPackage.getLeafNode(), + extList, + keyPackages, + leafSecret, + new Group.CommitOptions(null, inlineTree, forcePath, null) ); int nextID = storeGroup(gwm.group, entry.encryptHandshake); MlsClient.CreateSubgroupResponse.Builder builder = MlsClient.CreateSubgroupResponse.newBuilder() - .setStateId(nextID) - .setWelcome(ByteString.copyFrom(MLSOutputStream.encode(gwm.message))) - .setEpochAuthenticator(ByteString.copyFrom(gwm.group.getEpochAuthenticator())); + .setStateId(nextID) + .setWelcome(ByteString.copyFrom(MLSOutputStream.encode(gwm.message))) + .setEpochAuthenticator(ByteString.copyFrom(gwm.group.getEpochAuthenticator())); if (!inlineTree) { @@ -1474,18 +1742,28 @@ private void createBranchImpl(CachedGroup entry, MlsClient.CreateBranchRequest r responseObserver.onNext(builder.build()); responseObserver.onCompleted(); - } -@Override + } + + @Override public void createBranch(MlsClient.CreateBranchRequest request, StreamObserver responseObserver) { - stateWrap(group -> createBranchImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + createBranchImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void handleBranchImpl(CachedGroup entry, MlsClient.HandleBranchRequest request, StreamObserver responseObserver) throws Exception + private void handleBranchImpl(CachedGroup entry, MlsClient.HandleBranchRequest request, StreamObserver responseObserver) + throws Exception { CachedJoin join = loadJoin(request.getTransactionId()); if (join == null) @@ -1493,38 +1771,47 @@ private void handleBranchImpl(CachedGroup entry, MlsClient.HandleBranchRequest r throw Status.INVALID_ARGUMENT.withDescription("Unknown transaction ID").asException(); } - MLSMessage welcome = (MLSMessage) MLSInputStream.decode(request.getWelcome().toByteArray(), MLSMessage.class); + MLSMessage welcome = (MLSMessage)MLSInputStream.decode(request.getWelcome().toByteArray(), MLSMessage.class); byte[] ratchetTreeBytes = request.getRatchetTree().toByteArray(); TreeKEMPublicKey ratchetTree = null; if (ratchetTreeBytes.length > 0) { - ratchetTree = (TreeKEMPublicKey) MLSInputStream.decode(ratchetTreeBytes, TreeKEMPublicKey.class); + ratchetTree = (TreeKEMPublicKey)MLSInputStream.decode(ratchetTreeBytes, TreeKEMPublicKey.class); ratchetTree.setSuite(welcome.getCipherSuite()); } Group group = entry.group.handleBranch( - join.kpSecrets.initKeyPair, - join.kpSecrets.encryptionKeyPair, - join.kpSecrets.signatureKeyPair, - join.kpSecrets.keyPackage, - welcome, - ratchetTree + join.kpSecrets.initKeyPair, + join.kpSecrets.encryptionKeyPair, + join.kpSecrets.signatureKeyPair, + join.kpSecrets.keyPackage, + welcome, + ratchetTree ); int stateID = storeGroup(group, entry.encryptHandshake); MlsClient.HandleBranchResponse response = MlsClient.HandleBranchResponse.newBuilder() - .setStateId(stateID) - .setEpochAuthenticator(ByteString.copyFrom(group.getEpochAuthenticator())) - .build(); + .setStateId(stateID) + .setEpochAuthenticator(ByteString.copyFrom(group.getEpochAuthenticator())) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void handleBranch(MlsClient.HandleBranchRequest request, StreamObserver responseObserver) { - stateWrap(group -> handleBranchImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + handleBranchImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** @@ -1535,49 +1822,60 @@ public void handleBranch(MlsClient.HandleBranchRequest request, StreamObserver responseObserver) throws Exception + private void newMemberAddProposalImpl(MlsClient.NewMemberAddProposalRequest request, StreamObserver responseObserver) + throws Exception { - MLSMessage groupInfoMsg = (MLSMessage) MLSInputStream.decode(request.getGroupInfo().toByteArray(), MLSMessage.class); + MLSMessage groupInfoMsg = (MLSMessage)MLSInputStream.decode(request.getGroupInfo().toByteArray(), MLSMessage.class); GroupInfo groupInfo = groupInfoMsg.groupInfo; MlsCipherSuite suite = groupInfo.getSuite(); KeyPackageWithSecrets kpSk = newKeyPackage(suite, request.getIdentity().toByteArray()); - byte[] initSk = suite.getHPKE().serializePrivateKey(kpSk.initKeyPair.getPrivate()); + byte[] initSk = suite.getHPKE().serializePrivateKey(kpSk.initKeyPair.getPrivate()); byte[] encryptionSk = suite.getHPKE().serializePrivateKey(kpSk.encryptionKeyPair.getPrivate()); byte[] signatureSk = suite.serializeSignaturePrivateKey(kpSk.signatureKeyPair.getPrivate()); MLSMessage proposal = Group.newMemberAdd( - groupInfo.getGroupID(), - groupInfo.getEpoch(), - kpSk.keyPackage, - kpSk.signatureKeyPair + groupInfo.getGroupID(), + groupInfo.getEpoch(), + kpSk.keyPackage, + kpSk.signatureKeyPair ); int joinID = storeJoin(kpSk); MlsClient.NewMemberAddProposalResponse response = MlsClient.NewMemberAddProposalResponse.newBuilder() - .setInitPriv(ByteString.copyFrom(initSk)) - .setEncryptionPriv(ByteString.copyFrom(encryptionSk)) - .setSignaturePriv(ByteString.copyFrom(signatureSk)) - .setProposal(ByteString.copyFrom(MLSOutputStream.encode(proposal))) - .setTransactionId(joinID) - .build(); + .setInitPriv(ByteString.copyFrom(initSk)) + .setEncryptionPriv(ByteString.copyFrom(encryptionSk)) + .setSignaturePriv(ByteString.copyFrom(signatureSk)) + .setProposal(ByteString.copyFrom(MLSOutputStream.encode(proposal))) + .setTransactionId(joinID) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void newMemberAddProposal(MlsClient.NewMemberAddProposalRequest request, StreamObserver responseObserver) { - catchWrap(() -> newMemberAddProposalImpl(request, responseObserver), responseObserver); + catchWrap(new Function() + { + @Override + public void run() + throws Exception + { + newMemberAddProposalImpl(request, responseObserver); + } + }, responseObserver); } /** * @param request * @param responseObserver */ - private void createExternalSignerImpl(MlsClient.CreateExternalSignerRequest request, StreamObserver responseObserver) throws Exception + private void createExternalSignerImpl(MlsClient.CreateExternalSignerRequest request, StreamObserver responseObserver) + throws Exception { MlsCipherSuite suite = MlsCipherSuite.getSuite((short)request.getCipherSuite()); AsymmetricCipherKeyPair sigSk = suite.generateSignatureKeyPair(); @@ -1588,29 +1886,39 @@ private void createExternalSignerImpl(MlsClient.CreateExternalSignerRequest requ int signerID = storeSigner(suite.serializeSignaturePrivateKey(sigSk.getPrivate())); MlsClient.CreateExternalSignerResponse response = MlsClient.CreateExternalSignerResponse.newBuilder() - .setExternalSender(ByteString.copyFrom(MLSOutputStream.encode(extSender))) - .setSignerId(signerID) - .build(); + .setExternalSender(ByteString.copyFrom(MLSOutputStream.encode(extSender))) + .setSignerId(signerID) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void createExternalSigner(MlsClient.CreateExternalSignerRequest request, StreamObserver responseObserver) { - catchWrap(() -> createExternalSignerImpl(request, responseObserver), responseObserver); + catchWrap(new Function() + { + @Override + public void run() + throws Exception + { + createExternalSignerImpl(request, responseObserver); + } + }, responseObserver); } /** * @param request * @param responseObserver */ - private void addExternalSignerImpl(CachedGroup entry, MlsClient.AddExternalSignerRequest request, StreamObserver responseObserver) throws Exception + private void addExternalSignerImpl(CachedGroup entry, MlsClient.AddExternalSignerRequest request, StreamObserver responseObserver) + throws Exception { byte[] extSender = request.getExternalSender().toByteArray(); - List extList = new ArrayList<>(entry.group.getExtensions()); - List extSenders = new ArrayList<>(); + List extList = new ArrayList(entry.group.getExtensions()); + List extSenders = new ArrayList(); for (Extension ext : extList) { if (ext.extensionType == ExtensionType.EXTERNAL_SENDERS) @@ -1618,32 +1926,42 @@ private void addExternalSignerImpl(CachedGroup entry, MlsClient.AddExternalSigne extSenders = ext.getSenders(); } } - extList = new ArrayList<>(); - extSenders.add((ExternalSender) MLSInputStream.decode(extSender, ExternalSender.class)); + extList = new ArrayList(); + extSenders.add((ExternalSender)MLSInputStream.decode(extSender, ExternalSender.class)); extList.add(Extension.externalSender(extSenders)); MLSMessage proposal = entry.group.groupContextExtensions(extList, entry.messageOptions); MlsClient.ProposalResponse response = MlsClient.ProposalResponse.newBuilder() - .setProposal(ByteString.copyFrom(MLSOutputStream.encode(proposal))) - .build(); + .setProposal(ByteString.copyFrom(MLSOutputStream.encode(proposal))) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void addExternalSigner(MlsClient.AddExternalSignerRequest request, StreamObserver responseObserver) { - stateWrap(group -> addExternalSignerImpl(group, request, responseObserver), request, responseObserver); + stateWrap(new FunctionWithState() + { + @Override + public void run(CachedGroup group) + throws Exception + { + addExternalSignerImpl(group, request, responseObserver); + } + }, request, responseObserver); } /** * @param request * @param responseObserver */ - private void externalSignerProposalImpl(MlsClient.ExternalSignerProposalRequest request, StreamObserver responseObserver) throws Exception + private void externalSignerProposalImpl(MlsClient.ExternalSignerProposalRequest request, StreamObserver responseObserver) + throws Exception { byte[] groupMsgData = request.getGroupInfo().toByteArray(); - MLSMessage groupMsg = (MLSMessage) MLSInputStream.decode(groupMsgData, MLSMessage.class); + MLSMessage groupMsg = (MLSMessage)MLSInputStream.decode(groupMsgData, MLSMessage.class); GroupInfo groupInfo = groupMsg.groupInfo; MlsCipherSuite suite = groupInfo.getSuite(); @@ -1651,7 +1969,7 @@ private void externalSignerProposalImpl(MlsClient.ExternalSignerProposalRequest long epoch = groupInfo.getEpoch(); byte[] treeData = request.getRatchetTree().toByteArray(); - TreeKEMPublicKey tree = (TreeKEMPublicKey) MLSInputStream.decode(treeData, TreeKEMPublicKey.class); + TreeKEMPublicKey tree = (TreeKEMPublicKey)MLSInputStream.decode(treeData, TreeKEMPublicKey.class); // Look up the signer byte[] sigPriv = loadSigner(request.getSignerId()); @@ -1663,7 +1981,7 @@ private void externalSignerProposalImpl(MlsClient.ExternalSignerProposalRequest byte[] sigPub = suite.serializeSignaturePublicKey(suite.deserializeSignaturePrivateKey(sigPriv).getPublic()); // Look up the signer index of this signer - List extSenders = new ArrayList<>(); + List extSenders = new ArrayList(); for (Extension ext : groupInfo.getGroupContext().getExtensions()) { if (ext.extensionType == ExtensionType.EXTERNAL_SENDERS) @@ -1689,16 +2007,25 @@ private void externalSignerProposalImpl(MlsClient.ExternalSignerProposalRequest MLSMessage signedProposal = MLSMessage.externalProposal(suite, groupID, epoch, proposal, sigIndex, sigPriv); MlsClient.ProposalResponse response = MlsClient.ProposalResponse.newBuilder() - .setProposal(ByteString.copyFrom(MLSOutputStream.encode(signedProposal))) - .build(); + .setProposal(ByteString.copyFrom(MLSOutputStream.encode(signedProposal))) + .build(); responseObserver.onNext(response); responseObserver.onCompleted(); - } -@Override + } + + @Override public void externalSignerProposal(MlsClient.ExternalSignerProposalRequest request, StreamObserver responseObserver) { - catchWrap(() -> externalSignerProposalImpl(request, responseObserver), responseObserver); + catchWrap(new Function() + { + @Override + public void run() + throws Exception + { + externalSignerProposalImpl(request, responseObserver); + } + }, responseObserver); } /** @@ -1709,7 +2036,8 @@ public void externalSignerProposal(MlsClient.ExternalSignerProposalRequest reque * @param request * @param responseObserver */ - private void freeImpl(MlsClient.FreeRequest request, StreamObserver responseObserver) throws StatusException + private void freeImpl(MlsClient.FreeRequest request, StreamObserver responseObserver) + throws StatusException { int stateID = request.getStateId(); if (!groupCache.containsKey(stateID)) @@ -1721,10 +2049,19 @@ private void freeImpl(MlsClient.FreeRequest request, StreamObserver responseObserver) { - catchWrap(() -> freeImpl(request, responseObserver), responseObserver); + catchWrap(new Function() + { + @Override + public void run() + throws Exception + { + freeImpl(request, responseObserver); + } + }, responseObserver); } } diff --git a/mls/src/main/java/org/bouncycastle/mls/client/MLSServer.java b/mls/src/main/java/org/bouncycastle/mls/client/MLSServer.java index 352220f1d8..8238abbaff 100644 --- a/mls/src/main/java/org/bouncycastle/mls/client/MLSServer.java +++ b/mls/src/main/java/org/bouncycastle/mls/client/MLSServer.java @@ -1,17 +1,18 @@ package org.bouncycastle.mls.client; +import java.io.IOException; + import io.grpc.Server; import io.grpc.ServerBuilder; -import java.io.IOException; - public class MLSServer { - public static void main(String[] args) throws IOException, InterruptedException + public static void main(String[] args) + throws IOException, InterruptedException { Server server1 = ServerBuilder.forPort(12346) - .addService(new MLSClientImpl()) - .build(); + .addService(new MLSClientImpl()) + .build(); server1.start(); server1.awaitTermination(); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/AuthenticatedContent.java b/mls/src/main/java/org/bouncycastle/mls/codec/AuthenticatedContent.java index 69ee0a6423..b50ab735b6 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/AuthenticatedContent.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/AuthenticatedContent.java @@ -1,11 +1,11 @@ package org.bouncycastle.mls.codec; -import org.bouncycastle.mls.crypto.MlsCipherSuite; - import java.io.IOException; +import org.bouncycastle.mls.crypto.MlsCipherSuite; + public class AuthenticatedContent - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { WireFormat wireFormat; @@ -31,42 +31,40 @@ public byte[] getConfirmationTag() { return auth.confirmation_tag; } - public byte[] getConfirmedTranscriptHashInput() throws IOException + + public byte[] getConfirmedTranscriptHashInput() + throws IOException { return MLSOutputStream.encode(new ConfirmedTranscriptHashInput(wireFormat, content, auth.signature)); } - public byte[] getInterimTranscriptHashInput() throws IOException + + public byte[] getInterimTranscriptHashInput() + throws IOException { return MLSOutputStream.encode(new InterimTranscriptHashInput(auth.confirmation_tag)); } - public AuthenticatedContent(WireFormat wireFormat, FramedContent content, FramedContentAuthData auth) + public AuthenticatedContent(WireFormat wireFormat, FramedContent content, FramedContentAuthData auth) throws Exception { this.wireFormat = wireFormat; this.content = content; this.auth = auth; - //TODO move elsewhere? - if (auth.contentType == ContentType.COMMIT && auth.confirmation_tag == null) - { - //TODO -// throw new MissingConfirmationTag() - } - if (auth.contentType == ContentType.APPLICATION) { if (wireFormat != WireFormat.mls_private_message) { -// throw new UnencryptedApplicationMessage() + throw new Exception("Unencrypted application message"); } else if (content.sender.senderType != SenderType.MEMBER) { -// throw new Exception("sender must be a member") + throw new Exception("sender must be a member"); } } } - public static AuthenticatedContent sign(WireFormat wireFormat, FramedContent content, MlsCipherSuite suite, byte[] sigPriv, byte[] groupContext) throws Exception + public static AuthenticatedContent sign(WireFormat wireFormat, FramedContent content, MlsCipherSuite suite, byte[] sigPriv, byte[] groupContext) + throws Exception { if (wireFormat == WireFormat.mls_public_message && content.contentType == ContentType.APPLICATION) @@ -79,10 +77,11 @@ public static AuthenticatedContent sign(WireFormat wireFormat, FramedContent con return new AuthenticatedContent(wireFormat, content, auth); } - public boolean verify(MlsCipherSuite suite, byte[] sigPub, byte[] context) throws IOException + public boolean verify(MlsCipherSuite suite, byte[] sigPub, byte[] context) + throws IOException { if (wireFormat == WireFormat.mls_public_message && - content.contentType == ContentType.APPLICATION) + content.contentType == ContentType.APPLICATION) { return false; } @@ -92,21 +91,24 @@ public boolean verify(MlsCipherSuite suite, byte[] sigPub, byte[] context) throw } @SuppressWarnings("unused") - public AuthenticatedContent(MLSInputStream stream) throws IOException + public AuthenticatedContent(MLSInputStream stream) + throws IOException { - this.wireFormat = WireFormat.values()[(short) stream.read(short.class)]; - content = (FramedContent) stream.read(FramedContent.class); + this.wireFormat = WireFormat.values()[(short)stream.read(short.class)]; + content = (FramedContent)stream.read(FramedContent.class); auth = new FramedContentAuthData(stream, content.contentType); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(wireFormat); stream.write(content); stream.write(auth); } } + class ConfirmedTranscriptHashInput implements MLSInputStream.Readable, MLSOutputStream.Writable { @@ -120,16 +122,19 @@ public ConfirmedTranscriptHashInput(WireFormat wireFormat, FramedContent content this.content = content; this.signature = signature; } + @SuppressWarnings("unused") - public ConfirmedTranscriptHashInput(MLSInputStream stream) throws IOException + public ConfirmedTranscriptHashInput(MLSInputStream stream) + throws IOException { - this.wireFormat = WireFormat.values()[(short) stream.read(short.class)]; - content = (FramedContent) stream.read(FramedContent.class); + this.wireFormat = WireFormat.values()[(short)stream.read(short.class)]; + content = (FramedContent)stream.read(FramedContent.class); signature = stream.readOpaque(); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(wireFormat); stream.write(content); @@ -148,13 +153,15 @@ public InterimTranscriptHashInput(byte[] confirmation_tag) } @SuppressWarnings("unused") - public InterimTranscriptHashInput(MLSInputStream stream) throws IOException + public InterimTranscriptHashInput(MLSInputStream stream) + throws IOException { confirmation_tag = stream.readOpaque(); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(confirmation_tag); } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/Capabilities.java b/mls/src/main/java/org/bouncycastle/mls/codec/Capabilities.java index a62e350a1c..f3b7a98bd7 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/Capabilities.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/Capabilities.java @@ -1,18 +1,18 @@ package org.bouncycastle.mls.codec; -import org.bouncycastle.mls.crypto.MlsCipherSuite; - import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.bouncycastle.mls.crypto.MlsCipherSuite; + public class Capabilities - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { - static private final Short[] DEFAULT_SUPPORTED_VERSIONS = { ProtocolVersion.mls10.value }; + static private final Short[] DEFAULT_SUPPORTED_VERSIONS = {ProtocolVersion.mls10.value}; static private final short[] DEFAULT_SUPPORTED_CIPHERSUITES = MlsCipherSuite.ALL_SUPPORTED_SUITES; - static private final Short[] DEFAULT_SUPPORTED_CREDENTIALS = { CredentialType.basic.value, CredentialType.x509.value}; + static private final Short[] DEFAULT_SUPPORTED_CREDENTIALS = {CredentialType.basic.value, CredentialType.x509.value}; List versions; List cipherSuites; List extensions; @@ -26,25 +26,26 @@ public List getExtensions() public Capabilities() { - //TODO: make default to support all versions = Arrays.asList(DEFAULT_SUPPORTED_VERSIONS); - cipherSuites = new ArrayList<>(); + cipherSuites = new ArrayList(); for (short suite : DEFAULT_SUPPORTED_CIPHERSUITES) { cipherSuites.add(suite); } - extensions = new ArrayList<>(); - proposals = new ArrayList<>(); + extensions = new ArrayList(); + proposals = new ArrayList(); credentials = Arrays.asList(DEFAULT_SUPPORTED_CREDENTIALS); } + @SuppressWarnings("unused") - Capabilities(MLSInputStream stream) throws IOException + Capabilities(MLSInputStream stream) + throws IOException { - versions = new ArrayList<>(); - cipherSuites = new ArrayList<>(); - extensions = new ArrayList<>(); - proposals = new ArrayList<>(); - credentials = new ArrayList<>(); + versions = new ArrayList(); + cipherSuites = new ArrayList(); + extensions = new ArrayList(); + proposals = new ArrayList(); + credentials = new ArrayList(); stream.readList(versions, short.class); stream.readList(cipherSuites, short.class); stream.readList(extensions, short.class); @@ -53,7 +54,8 @@ public Capabilities() } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeList(versions); stream.writeList(cipherSuites); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/Certificate.java b/mls/src/main/java/org/bouncycastle/mls/codec/Certificate.java index a2b54b00d8..85c7cac352 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/Certificate.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/Certificate.java @@ -3,17 +3,19 @@ import java.io.IOException; public class Certificate - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { byte[] cert_data; - Certificate(MLSInputStream stream) throws IOException + Certificate(MLSInputStream stream) + throws IOException { cert_data = stream.readOpaque(); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(cert_data); } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/Commit.java b/mls/src/main/java/org/bouncycastle/mls/codec/Commit.java index 54b9d7603e..ed685266ad 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/Commit.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/Commit.java @@ -5,7 +5,7 @@ import java.util.List; public class Commit - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { List proposals; UpdatePath updatePath; @@ -34,7 +34,7 @@ public byte[] validityExternal() // The Commit MUST NOT include any proposals by reference, since an external // joiner cannot determine the validity of proposals sent within the group - for (ProposalOrRef p: proposals) + for (ProposalOrRef p : proposals) { if (p.type == ProposalOrRefType.REFERENCE) { @@ -64,20 +64,22 @@ public byte[] validityExternal() public Commit() { - this.proposals = new ArrayList<>(); + this.proposals = new ArrayList(); } @SuppressWarnings("unused") - Commit(MLSInputStream stream) throws IOException + Commit(MLSInputStream stream) + throws IOException { - proposals = new ArrayList<>(); - stream.readList(proposals ,ProposalOrRef.class); + proposals = new ArrayList(); + stream.readList(proposals, ProposalOrRef.class); - updatePath = (UpdatePath) stream.readOptional(UpdatePath.class); + updatePath = (UpdatePath)stream.readOptional(UpdatePath.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeList(proposals); stream.writeOptional(updatePath); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/ContentType.java b/mls/src/main/java/org/bouncycastle/mls/codec/ContentType.java index 0613e3d3a7..8358a6efb5 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/ContentType.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/ContentType.java @@ -3,12 +3,12 @@ import java.io.IOException; public enum ContentType - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { - RESERVED((byte) 0), - APPLICATION((byte) 1), - PROPOSAL((byte) 2), - COMMIT((byte) 3); + RESERVED((byte)0), + APPLICATION((byte)1), + PROPOSAL((byte)2), + COMMIT((byte)3); final byte value; @@ -18,13 +18,15 @@ public enum ContentType } @SuppressWarnings("unused") - ContentType(MLSInputStream stream) throws IOException + ContentType(MLSInputStream stream) + throws IOException { - this.value = (byte) stream.read(byte.class); + this.value = (byte)stream.read(byte.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(value); } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/Credential.java b/mls/src/main/java/org/bouncycastle/mls/codec/Credential.java index 694506380c..8cb2b985c5 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/Credential.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/Credential.java @@ -5,7 +5,7 @@ import java.util.List; public class Credential - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { CredentialType credentialType; @@ -16,6 +16,7 @@ public CredentialType getCredentialType() { return credentialType; } + public byte[] getIdentity() { return identity; @@ -23,7 +24,7 @@ public byte[] getIdentity() static public Credential forBasic(byte[] identity) { - return new Credential(CredentialType.basic, identity, new ArrayList<>()); + return new Credential(CredentialType.basic, identity, new ArrayList()); } public Credential(CredentialType credentialType, byte[] identity, List certificates) @@ -32,10 +33,12 @@ public Credential(CredentialType credentialType, byte[] identity, List(); - stream.readList(certificates, Certificate.class); - break; + case basic: + identity = stream.readOpaque(); + break; + case x509: + certificates = new ArrayList(); + stream.readList(certificates, Certificate.class); + break; } } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { if (Grease.isGrease(credentialType.value) == -1) { @@ -69,12 +73,12 @@ public void writeTo(MLSOutputStream stream) throws IOException } switch (credentialType) { - case basic: - stream.writeOpaque(identity); - break; - case x509: - stream.writeList(certificates); - break; + case basic: + stream.writeOpaque(identity); + break; + case x509: + stream.writeList(certificates); + break; } } } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/CredentialType.java b/mls/src/main/java/org/bouncycastle/mls/codec/CredentialType.java index 30c0103e69..a16fd32566 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/CredentialType.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/CredentialType.java @@ -3,26 +3,26 @@ import java.io.IOException; public enum CredentialType - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { - RESERVED((short) 0), - basic((short) 1), - x509((short) 2), - GREASE_0((short) 0x0A0A), - GREASE_1((short) 0x1A1A), - GREASE_2((short) 0x2A2A), - GREASE_3((short) 0x3A3A), - GREASE_4((short) 0x4A4A), - GREASE_5((short) 0x5A5A), - GREASE_6((short) 0x6A6A), - GREASE_7((short) 0x7A7A), - GREASE_8((short) 0x8A8A), - GREASE_9((short) 0x9A9A), - GREASE_A((short) 0xAAAA), - GREASE_B((short) 0xBABA), - GREASE_C((short) 0xCACA), - GREASE_D((short) 0xDADA), - GREASE_E((short) 0xEAEA); + RESERVED((short)0), + basic((short)1), + x509((short)2), + GREASE_0((short)0x0A0A), + GREASE_1((short)0x1A1A), + GREASE_2((short)0x2A2A), + GREASE_3((short)0x3A3A), + GREASE_4((short)0x4A4A), + GREASE_5((short)0x5A5A), + GREASE_6((short)0x6A6A), + GREASE_7((short)0x7A7A), + GREASE_8((short)0x8A8A), + GREASE_9((short)0x9A9A), + GREASE_A((short)0xAAAA), + GREASE_B((short)0xBABA), + GREASE_C((short)0xCACA), + GREASE_D((short)0xDADA), + GREASE_E((short)0xEAEA); final short value; @@ -32,15 +32,16 @@ public enum CredentialType } @SuppressWarnings("unused") - CredentialType(MLSInputStream stream) throws IOException + CredentialType(MLSInputStream stream) + throws IOException { - this.value = (short) stream.read(short.class); + this.value = (short)stream.read(short.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { - //TODO write grease? stream.write(value); } } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/Extension.java b/mls/src/main/java/org/bouncycastle/mls/codec/Extension.java index f8219af71f..3a58e85189 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/Extension.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/Extension.java @@ -1,13 +1,13 @@ package org.bouncycastle.mls.codec; -import org.bouncycastle.mls.TreeKEM.TreeKEMPublicKey; - import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.bouncycastle.mls.TreeKEM.TreeKEMPublicKey; + public class Extension - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { public ExtensionType extensionType; public byte[] extension_data; @@ -17,9 +17,10 @@ public Extension(ExtensionType extensionType, byte[] extension_data) this.extensionType = extensionType; this.extension_data = extension_data; } + public Extension(int extensionType, byte[] extension_data) { - short extType = (short) extensionType; + short extType = (short)extensionType; if (Grease.isGrease(extType) == -1) { this.extensionType = ExtensionType.values()[extType]; @@ -31,14 +32,16 @@ public Extension(int extensionType, byte[] extension_data) this.extension_data = extension_data; } - static public Extension externalSender(List list) throws IOException + static public Extension externalSender(List list) + throws IOException { MLSOutputStream stream = new MLSOutputStream(); stream.writeList(list); return new Extension(ExtensionType.EXTERNAL_SENDERS, stream.toByteArray()); } - public byte[] getExternalPub() throws IOException + public byte[] getExternalPub() + throws IOException { if (extensionType == ExtensionType.EXTERNAL_PUB) { @@ -50,9 +53,10 @@ public byte[] getExternalPub() throws IOException } @SuppressWarnings("unused") - Extension(MLSInputStream stream) throws IOException + Extension(MLSInputStream stream) + throws IOException { - short extType = (short) stream.read(short.class); + short extType = (short)stream.read(short.class); if (Grease.isGrease(extType) == -1) { this.extensionType = ExtensionType.values()[extType]; @@ -64,39 +68,35 @@ public byte[] getExternalPub() throws IOException this.extension_data = stream.readOpaque(); } - public List getSenders() throws IOException + public List getSenders() + throws IOException { if (extensionType == ExtensionType.EXTERNAL_SENDERS) { - List senders = new ArrayList<>(); + List senders = new ArrayList(); MLSInputStream stream = new MLSInputStream(extension_data); stream.readList(senders, ExternalSender.class); return senders; } return null; } - public TreeKEMPublicKey getRatchetTree() throws IOException + + public TreeKEMPublicKey getRatchetTree() + throws IOException { if (extensionType == ExtensionType.RATCHET_TREE) { - return (TreeKEMPublicKey) MLSInputStream.decode(extension_data, TreeKEMPublicKey.class); + return (TreeKEMPublicKey)MLSInputStream.decode(extension_data, TreeKEMPublicKey.class); } return null; } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { -// if (Grease.isGrease(extensionType.value) == -1) -// { - stream.write(extensionType); - stream.writeOpaque(extension_data); -// } -// else -// { -// //TODO: check should we write grease? -// } - + stream.write(extensionType); + stream.writeOpaque(extension_data); } } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/ExtensionType.java b/mls/src/main/java/org/bouncycastle/mls/codec/ExtensionType.java index 5e867f52bb..cd96df99fd 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/ExtensionType.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/ExtensionType.java @@ -3,29 +3,29 @@ import java.io.IOException; public enum ExtensionType - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { - RESERVED((short) 0), - APPLICATION_ID((short) 1), - RATCHET_TREE((short) 2), - REQUIRED_CAPABILITIES((short) 3), - EXTERNAL_PUB((short) 4), - EXTERNAL_SENDERS((short) 5), - GREASE_0((short) 0x0A0A), - GREASE_1((short) 0x1A1A), - GREASE_2((short) 0x2A2A), - GREASE_3((short) 0x3A3A), - GREASE_4((short) 0x4A4A), - GREASE_5((short) 0x5A5A), - GREASE_6((short) 0x6A6A), - GREASE_7((short) 0x7A7A), - GREASE_8((short) 0x8A8A), - GREASE_9((short) 0x9A9A), - GREASE_A((short) 0xAAAA), - GREASE_B((short) 0xBABA), - GREASE_C((short) 0xCACA), - GREASE_D((short) 0xDADA), - GREASE_E((short) 0xEAEA); + RESERVED((short)0), + APPLICATION_ID((short)1), + RATCHET_TREE((short)2), + REQUIRED_CAPABILITIES((short)3), + EXTERNAL_PUB((short)4), + EXTERNAL_SENDERS((short)5), + GREASE_0((short)0x0A0A), + GREASE_1((short)0x1A1A), + GREASE_2((short)0x2A2A), + GREASE_3((short)0x3A3A), + GREASE_4((short)0x4A4A), + GREASE_5((short)0x5A5A), + GREASE_6((short)0x6A6A), + GREASE_7((short)0x7A7A), + GREASE_8((short)0x8A8A), + GREASE_9((short)0x9A9A), + GREASE_A((short)0xAAAA), + GREASE_B((short)0xBABA), + GREASE_C((short)0xCACA), + GREASE_D((short)0xDADA), + GREASE_E((short)0xEAEA); final short value; @@ -35,13 +35,15 @@ public enum ExtensionType } @SuppressWarnings("unused") - ExtensionType(MLSInputStream stream) throws IOException + ExtensionType(MLSInputStream stream) + throws IOException { - this.value = (short) stream.read(short.class); + this.value = (short)stream.read(short.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { // if (value == GREASE.value) // { @@ -49,7 +51,7 @@ public void writeTo(MLSOutputStream stream) throws IOException // } // else // { - stream.write(value); + stream.write(value); // } } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/ExternalSender.java b/mls/src/main/java/org/bouncycastle/mls/codec/ExternalSender.java index 13b3369901..70fafe2e94 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/ExternalSender.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/ExternalSender.java @@ -3,7 +3,7 @@ import java.io.IOException; public class ExternalSender - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { byte[] signatureKey; Credential credential; @@ -19,13 +19,16 @@ public ExternalSender(byte[] signatureKey, Credential credential) this.credential = credential; } - public ExternalSender(MLSInputStream stream) throws IOException + public ExternalSender(MLSInputStream stream) + throws IOException { signatureKey = stream.readOpaque(); - credential = (Credential) stream.read(Credential.class); + credential = (Credential)stream.read(Credential.class); } + @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(signatureKey); stream.write(credential); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/FramedContent.java b/mls/src/main/java/org/bouncycastle/mls/codec/FramedContent.java index 640085cf33..a2a921b715 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/FramedContent.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/FramedContent.java @@ -3,7 +3,7 @@ import java.io.IOException; public class FramedContent - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { byte[] group_id; long epoch; @@ -51,40 +51,43 @@ public byte[] getAuthenticated_data() return authenticated_data; } - public byte[] getContentBytes() throws IOException + public byte[] getContentBytes() + throws IOException { switch (contentType) { - case APPLICATION: - return application_data; - case PROPOSAL: - return MLSOutputStream.encode(proposal); - case COMMIT: - return MLSOutputStream.encode(commit); - default: - return null; + case APPLICATION: + return application_data; + case PROPOSAL: + return MLSOutputStream.encode(proposal); + case COMMIT: + return MLSOutputStream.encode(commit); + default: + return null; } } + @SuppressWarnings("unused") - public FramedContent(MLSInputStream stream) throws IOException + public FramedContent(MLSInputStream stream) + throws IOException { group_id = stream.readOpaque(); - epoch = (long) stream.read(long.class); - sender = (Sender) stream.read(Sender.class); + epoch = (long)stream.read(long.class); + sender = (Sender)stream.read(Sender.class); authenticated_data = stream.readOpaque(); - contentType = ContentType.values()[(byte) stream.read(byte.class)]; + contentType = ContentType.values()[(byte)stream.read(byte.class)]; switch (contentType) { - case APPLICATION: - application_data = stream.readOpaque(); - break; - case PROPOSAL: - proposal = (Proposal) stream.read(Proposal.class); - break; - case COMMIT: - commit = (Commit) stream.read(Commit.class); - break; + case APPLICATION: + application_data = stream.readOpaque(); + break; + case PROPOSAL: + proposal = (Proposal)stream.read(Proposal.class); + break; + case COMMIT: + commit = (Commit)stream.read(Commit.class); + break; } } @@ -99,16 +102,18 @@ public FramedContent(byte[] group_id, long epoch, Sender sender, byte[] authenti this.proposal = proposal; this.commit = commit; } - public static FramedContent rawContent(byte[] group_id, long epoch, Sender sender, byte[] authenticated_data, ContentType content_type, byte[] contentBytes) throws IOException + + public static FramedContent rawContent(byte[] group_id, long epoch, Sender sender, byte[] authenticated_data, ContentType content_type, byte[] contentBytes) + throws IOException { switch (content_type) { - case APPLICATION: - return application(group_id, epoch, sender, authenticated_data, contentBytes); - case PROPOSAL: - return proposal(group_id, epoch, sender, authenticated_data, contentBytes); - case COMMIT: - return commit(group_id, epoch, sender, authenticated_data, contentBytes); + case APPLICATION: + return application(group_id, epoch, sender, authenticated_data, contentBytes); + case PROPOSAL: + return proposal(group_id, epoch, sender, authenticated_data, contentBytes); + case COMMIT: + return commit(group_id, epoch, sender, authenticated_data, contentBytes); } return null; } @@ -118,18 +123,21 @@ public static FramedContent application(byte[] group_id, long epoch, Sender send return new FramedContent(group_id, epoch, sender, authenticated_data, application_data, ContentType.APPLICATION, null, null); } - public static FramedContent proposal(byte[] group_id, long epoch, Sender sender, byte[] authenticated_data, byte[] proposal) throws IOException + public static FramedContent proposal(byte[] group_id, long epoch, Sender sender, byte[] authenticated_data, byte[] proposal) + throws IOException { - return new FramedContent(group_id, epoch, sender, authenticated_data, null, ContentType.PROPOSAL, (Proposal) MLSInputStream.decode(proposal, Proposal.class), null); + return new FramedContent(group_id, epoch, sender, authenticated_data, null, ContentType.PROPOSAL, (Proposal)MLSInputStream.decode(proposal, Proposal.class), null); } - public static FramedContent commit(byte[] group_id, long epoch, Sender sender, byte[] authenticated_data, byte[] commit) throws IOException + public static FramedContent commit(byte[] group_id, long epoch, Sender sender, byte[] authenticated_data, byte[] commit) + throws IOException { - return new FramedContent(group_id, epoch, sender, authenticated_data, null, ContentType.COMMIT, null, (Commit) MLSInputStream.decode(commit, Commit.class)); + return new FramedContent(group_id, epoch, sender, authenticated_data, null, ContentType.COMMIT, null, (Commit)MLSInputStream.decode(commit, Commit.class)); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(group_id); stream.write(epoch); @@ -139,17 +147,17 @@ public void writeTo(MLSOutputStream stream) throws IOException switch (contentType) { - case RESERVED: - break; - case APPLICATION: - stream.writeOpaque(application_data); - break; - case PROPOSAL: - stream.write(proposal); - break; - case COMMIT: - stream.write(commit); - break; + case RESERVED: + break; + case APPLICATION: + stream.writeOpaque(application_data); + break; + case PROPOSAL: + stream.write(proposal); + break; + case COMMIT: + stream.write(commit); + break; } } } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/Grease.java b/mls/src/main/java/org/bouncycastle/mls/codec/Grease.java index a18e79e885..cc0a0aec87 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/Grease.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/Grease.java @@ -5,48 +5,50 @@ public class Grease { static short[] grease = new short[]{0x0A0A, 0x1A1A, 0x2A2A, 0x3A3A, 0x4A4A, 0x5A5A, 0x6A6A, 0x7A7A, - (short) 0x8A8A, (short) 0x9A9A, (short) 0xAAAA, (short) 0xBABA, (short) 0xCACA, (short) 0xDADA, (short) 0xEAEA}; + (short)0x8A8A, (short)0x9A9A, (short)0xAAAA, (short)0xBABA, (short)0xCACA, (short)0xDADA, (short)0xEAEA}; + public static short getGrease() { Random random = new Random(); return grease[random.nextInt(15)]; } + public static short isGrease(short type) { switch (type) { - case 0x0A0A: - return 0; - case 0x1A1A: - return 1; - case 0x2A2A: - return 2; - case 0x3A3A: - return 3; - case 0x4A4A: - return 4; - case 0x5A5A: - return 5; - case 0x6A6A: - return 6; - case 0x7A7A: - return 7; - case (short) 0x8A8A: - return 8; - case (short) 0x9A9A: - return 9; - case (short) 0xAAAA: - return 10; - case (short) 0xBABA: - return 11; - case (short) 0xCACA: - return 12; - case (short) 0xDADA: - return 13; - case (short) 0xEAEA: - return 14; - default: - return -1; + case 0x0A0A: + return 0; + case 0x1A1A: + return 1; + case 0x2A2A: + return 2; + case 0x3A3A: + return 3; + case 0x4A4A: + return 4; + case 0x5A5A: + return 5; + case 0x6A6A: + return 6; + case 0x7A7A: + return 7; + case (short)0x8A8A: + return 8; + case (short)0x9A9A: + return 9; + case (short)0xAAAA: + return 10; + case (short)0xBABA: + return 11; + case (short)0xCACA: + return 12; + case (short)0xDADA: + return 13; + case (short)0xEAEA: + return 14; + default: + return -1; } } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/GroupContext.java b/mls/src/main/java/org/bouncycastle/mls/codec/GroupContext.java index 2232c076e3..404ab78e24 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/GroupContext.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/GroupContext.java @@ -1,12 +1,12 @@ package org.bouncycastle.mls.codec; -import org.bouncycastle.mls.crypto.MlsCipherSuite; - import java.io.IOException; import java.util.ArrayList; +import org.bouncycastle.mls.crypto.MlsCipherSuite; + public class GroupContext - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { ProtocolVersion version = ProtocolVersion.mls10; @@ -41,25 +41,28 @@ public GroupContext(MlsCipherSuite ciphersuite, byte[] groupID, long epoch, byte this.epoch = epoch; this.treeHash = treeHash; this.confirmedTranscriptHash = confirmedTranscriptHash; - this.extensions = new ArrayList<>(extensions); + this.extensions = new ArrayList(extensions); } + @SuppressWarnings("unused") - public GroupContext(MLSInputStream stream) throws Exception + public GroupContext(MLSInputStream stream) + throws Exception { - this.version = ProtocolVersion.values()[(short) stream.read(short.class)]; - this.ciphersuite = (short) stream.read(short.class); + this.version = ProtocolVersion.values()[(short)stream.read(short.class)]; + this.ciphersuite = (short)stream.read(short.class); this.suite = MlsCipherSuite.getSuite(ciphersuite); this.groupID = stream.readOpaque(); - this.epoch = (long) stream.read(long.class); + this.epoch = (long)stream.read(long.class); this.treeHash = stream.readOpaque(); this.confirmedTranscriptHash = stream.readOpaque(); - this.extensions = new ArrayList<>(); + this.extensions = new ArrayList(); stream.readList(extensions, Extension.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(version); stream.write(ciphersuite); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/GroupInfo.java b/mls/src/main/java/org/bouncycastle/mls/codec/GroupInfo.java index 1699496cce..786d9ece63 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/GroupInfo.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/GroupInfo.java @@ -1,18 +1,18 @@ package org.bouncycastle.mls.codec; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.mls.TreeKEM.LeafIndex; import org.bouncycastle.mls.TreeKEM.LeafNode; import org.bouncycastle.mls.TreeKEM.TreeKEMPublicKey; import org.bouncycastle.mls.crypto.MlsCipherSuite; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - public class GroupInfo - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { GroupContext groupContext; List extensions; @@ -44,22 +44,26 @@ public byte[] getGroupID() { return groupContext.groupID; } + public long getEpoch() { return groupContext.epoch; } + public MlsCipherSuite getSuite() { return groupContext.suite; } + public GroupInfo(GroupContext groupContext, List extensions, byte[] confirmationTag) { this.groupContext = groupContext; - this.extensions = new ArrayList<>(extensions); + this.extensions = new ArrayList(extensions); this.confirmationTag = confirmationTag; } - private byte[] toBeSigned() throws IOException + private byte[] toBeSigned() + throws IOException { MLSOutputStream stream = new MLSOutputStream(); stream.write(groupContext); @@ -69,7 +73,8 @@ private byte[] toBeSigned() throws IOException return stream.toByteArray(); } - public boolean verify(MlsCipherSuite suite, TreeKEMPublicKey tree) throws Exception + public boolean verify(MlsCipherSuite suite, TreeKEMPublicKey tree) + throws Exception { LeafNode leaf = tree.getLeafNode(signer); if (leaf == null) @@ -78,23 +83,28 @@ public boolean verify(MlsCipherSuite suite, TreeKEMPublicKey tree) throws Except } return verify(suite, leaf.getSignatureKey()); } - public boolean verify(MlsCipherSuite suite, byte[] pub) throws IOException + + public boolean verify(MlsCipherSuite suite, byte[] pub) + throws IOException { return suite.verifyWithLabel(pub, "GroupInfoTBS", toBeSigned(), signature); } + @SuppressWarnings("unused") - GroupInfo(MLSInputStream stream) throws IOException + GroupInfo(MLSInputStream stream) + throws IOException { - groupContext = (GroupContext) stream.read(GroupContext.class); - extensions = new ArrayList<>(); + groupContext = (GroupContext)stream.read(GroupContext.class); + extensions = new ArrayList(); stream.readList(extensions, Extension.class); confirmationTag = stream.readOpaque(); - signer = new LeafIndex((int) stream.read(int.class)); + signer = new LeafIndex((int)stream.read(int.class)); signature = stream.readOpaque(); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(groupContext); stream.writeList(extensions); @@ -103,7 +113,8 @@ public void writeTo(MLSOutputStream stream) throws IOException stream.writeOpaque(signature); } - public void sign(TreeKEMPublicKey tree, LeafIndex signerIndex, AsymmetricCipherKeyPair sk) throws Exception + public void sign(TreeKEMPublicKey tree, LeafIndex signerIndex, AsymmetricCipherKeyPair sk) + throws Exception { LeafNode leaf = tree.getLeafNode(signerIndex); if (leaf == null) diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/GroupSecrets.java b/mls/src/main/java/org/bouncycastle/mls/codec/GroupSecrets.java index fe3a3a23a1..8e3491d264 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/GroupSecrets.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/GroupSecrets.java @@ -5,7 +5,7 @@ import java.util.List; public class GroupSecrets - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { public byte[] joiner_secret; @@ -16,19 +16,22 @@ public GroupSecrets(byte[] joiner_secret, PathSecret path_secret, List(psks); + this.psks = new ArrayList(psks); } + @SuppressWarnings("unused") - GroupSecrets(MLSInputStream stream) throws IOException + GroupSecrets(MLSInputStream stream) + throws IOException { joiner_secret = stream.readOpaque(); - path_secret = (PathSecret) stream.readOptional(PathSecret.class); - psks = new ArrayList<>(); + path_secret = (PathSecret)stream.readOptional(PathSecret.class); + psks = new ArrayList(); stream.readList(psks, PreSharedKeyID.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(joiner_secret); stream.writeOptional(path_secret); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/HPKECiphertext.java b/mls/src/main/java/org/bouncycastle/mls/codec/HPKECiphertext.java index 57059bacc5..106fc0da18 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/HPKECiphertext.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/HPKECiphertext.java @@ -3,7 +3,7 @@ import java.io.IOException; public class HPKECiphertext - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { byte[] kem_output; byte[] ciphertext; @@ -23,15 +23,18 @@ public HPKECiphertext(byte[] kem_output, byte[] ciphertext) this.kem_output = kem_output; this.ciphertext = ciphertext; } + @SuppressWarnings("unused") - HPKECiphertext(MLSInputStream stream) throws IOException + HPKECiphertext(MLSInputStream stream) + throws IOException { kem_output = stream.readOpaque(); ciphertext = stream.readOpaque(); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(kem_output); stream.writeOpaque(ciphertext); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/KeyPackage.java b/mls/src/main/java/org/bouncycastle/mls/codec/KeyPackage.java index db8cc29334..2d6ccc643a 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/KeyPackage.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/KeyPackage.java @@ -1,16 +1,16 @@ package org.bouncycastle.mls.codec; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.mls.TreeKEM.LeafNode; import org.bouncycastle.mls.TreeKEM.LeafNodeSource; import org.bouncycastle.mls.crypto.MlsCipherSuite; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - public class KeyPackage - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { ProtocolVersion version; @@ -31,11 +31,14 @@ public byte[] getInitKey() { return init_key; } + public MlsCipherSuite getSuite() { return suite; } - public boolean verify() throws IOException + + public boolean verify() + throws IOException { // Verify the inner leaf node if (!leaf_node.verify(suite, leaf_node.toBeSigned(new byte[0], -1))) @@ -59,7 +62,8 @@ public boolean verify() throws IOException return suite.verifyWithLabel(leaf_node.getSignatureKey(), "KeyPackageTBS", toBeSigned(), signature); } - private byte[] toBeSigned() throws IOException + private byte[] toBeSigned() + throws IOException { MLSOutputStream stream = new MLSOutputStream(); stream.write(version); @@ -70,33 +74,37 @@ private byte[] toBeSigned() throws IOException return stream.toByteArray(); } - public KeyPackage(MlsCipherSuite suite, byte[] init_key, LeafNode leaf_node, List extensions, byte[] sigSk) throws IOException, CryptoException + public KeyPackage(MlsCipherSuite suite, byte[] init_key, LeafNode leaf_node, List extensions, byte[] sigSk) + throws IOException, CryptoException { this.version = ProtocolVersion.mls10; this.cipher_suite = suite.getSuiteID(); this.suite = suite; this.init_key = init_key.clone(); this.leaf_node = leaf_node.copy(leaf_node.getEncryptionKey()); - this.extensions = new ArrayList<>(extensions); + this.extensions = new ArrayList(extensions); //sign(sigSk) this.signature = suite.signWithLabel(sigSk, "KeyPackageTBS", toBeSigned()); } + @SuppressWarnings("unused") - KeyPackage(MLSInputStream stream) throws Exception + KeyPackage(MLSInputStream stream) + throws Exception { - this.version = ProtocolVersion.values()[(short) stream.read(short.class)]; - cipher_suite = (short) stream.read(short.class); + this.version = ProtocolVersion.values()[(short)stream.read(short.class)]; + cipher_suite = (short)stream.read(short.class); suite = MlsCipherSuite.getSuite(cipher_suite); init_key = stream.readOpaque(); - leaf_node = (LeafNode) stream.read(LeafNode.class); - extensions = new ArrayList<>(); + leaf_node = (LeafNode)stream.read(LeafNode.class); + extensions = new ArrayList(); stream.readList(extensions, Extension.class); signature = stream.readOpaque(); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(version); stream.write(cipher_suite); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/MLSInputStream.java b/mls/src/main/java/org/bouncycastle/mls/codec/MLSInputStream.java index c5100427bc..b18292281e 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/MLSInputStream.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/MLSInputStream.java @@ -7,8 +7,10 @@ import java.lang.reflect.InvocationTargetException; import java.util.List; -public class MLSInputStream { - public interface Readable { +public class MLSInputStream +{ + public interface Readable + { /* This interface is used as a marker, because Java interfaces cannot require the presence of specific constructors or static factory methods. An attempt @@ -18,42 +20,55 @@ public interface Readable { You may want to apply @SuppressWarnings("unused") to this constructor, since the compiler won't pick up uses via this class. */ - } - - static class SliceableStream extends ByteArrayInputStream { - public SliceableStream(byte[] buf) { + } + + static class SliceableStream + extends ByteArrayInputStream + { + public SliceableStream(byte[] buf) + { super(buf); } - public SliceableStream(byte[] buf, int pos, int size) { + public SliceableStream(byte[] buf, int pos, int size) + { super(buf, pos, size); } - byte[] readAll(int size) throws IOException { + byte[] readAll(int size) + throws IOException + { byte[] data = new byte[size]; if (size == 0) { return data; } int length = super.read(data); - if (length != data.length) { + if (length != data.length) + { throw new IOException("Attempt to read beyond end of buffer"); } return data; } - byte peek() throws IOException { + byte peek() + throws IOException + { mark(1); int val = read(); reset(); - if (val == -1) { + if (val == -1) + { throw new IOException("Attempt to peek past end of buffer"); } - return (byte) val; + return (byte)val; } - SliceableStream slice(int size) throws IOException { - if (size > available()) { + SliceableStream slice(int size) + throws IOException + { + if (size > available()) + { throw new IOException("Attempt to read past end of buffer"); } @@ -63,112 +78,168 @@ SliceableStream slice(int size) throws IOException { SliceableStream stream; - public MLSInputStream(byte[] data) { + public MLSInputStream(byte[] data) + { stream = new SliceableStream(data); } - MLSInputStream(SliceableStream stream) { this.stream = stream; } + MLSInputStream(SliceableStream stream) + { + this.stream = stream; + } - public static Object decode(byte[] data, Class targetClass) throws IOException { + public static Object decode(byte[] data, Class targetClass) + throws IOException + { MLSInputStream stream = new MLSInputStream(data); return stream.read(targetClass); } - public Object read(Class targetClass) throws IOException { - if (targetClass == Boolean.class) { + public Object read(Class targetClass) + throws IOException + { + if (targetClass == Boolean.class) + { return readBoolean(); - } else if (targetClass == Byte.class || targetClass == byte.class) { - return (byte) readInt(1); - } else if (targetClass == Short.class || targetClass == short.class) { - return (short) readInt(2); - } else if (targetClass == Integer.class || targetClass == int.class) { - return (int) readInt(4); - } else if (targetClass == Long.class || targetClass == long.class) { + } + else if (targetClass == Byte.class || targetClass == byte.class) + { + return (byte)readInt(1); + } + else if (targetClass == Short.class || targetClass == short.class) + { + return (short)readInt(2); + } + else if (targetClass == Integer.class || targetClass == int.class) + { + return (int)readInt(4); + } + else if (targetClass == Long.class || targetClass == long.class) + { return readInt(8); - } else if (Readable.class.isAssignableFrom(targetClass)) { + } + else if (Readable.class.isAssignableFrom(targetClass)) + { return readReadable(targetClass); } throw new IllegalArgumentException("Target type cannot be decoded"); } - byte peek() throws IOException { + byte peek() + throws IOException + { return stream.peek(); } - boolean readBoolean() throws IOException { - switch ((byte) readInt(1)) { - case 0: return false; - case 1: return true; - default: throw new IOException("Invalid boolean value"); + boolean readBoolean() + throws IOException + { + switch ((byte)readInt(1)) + { + case 0: + return false; + case 1: + return true; + default: + throw new IOException("Invalid boolean value"); } } - long readInt(byte[] data) { + long readInt(byte[] data) + { long out = 0; - for (byte b : data) { + for (byte b : data) + { out <<= 8; out |= (b & 0xff); } return out; } - long readInt(int size) throws IOException { + long readInt(int size) + throws IOException + { return readInt(stream.readAll(size)); } - public Object readOptional(Class targetClass) throws IOException { + public Object readOptional(Class targetClass) + throws IOException + { boolean present = readBoolean(); - if (!present) { + if (!present) + { return null; } return read(targetClass); } - public Object readArray(Class elemClass) throws IOException { + public Object readArray(Class elemClass) + throws IOException + { - int length = (int) readInt(4); + int length = (int)readInt(4); // If this is a byte array, read directly - if (elemClass == Byte.class) { + if (elemClass == Byte.class) + { return stream.readAll(length); } // Otherwise, recursively decode entries Object val = Array.newInstance(elemClass, length); - for (int i = 0; i < length; i++) { + for (int i = 0; i < length; i++) + { Object elem = read(elemClass); Array.set(val, i, elem); } return val; } - public byte[] readOpaque() throws IOException { - Varint size = (Varint) read(Varint.class); + public byte[] readOpaque() + throws IOException + { + Varint size = (Varint)read(Varint.class); return stream.readAll(size.value); } - public void readList(List list, Class elemClass) throws IOException { - Varint size = (Varint) read(Varint.class); + public void readList(List list, Class elemClass) + throws IOException + { + Varint size = (Varint)read(Varint.class); MLSInputStream dec = new MLSInputStream(stream.slice(size.value)); list.clear(); - while (dec.stream.available() > 0) { - list.add((E) dec.read(elemClass)); + while (dec.stream.available() > 0) + { + list.add((E)dec.read(elemClass)); } stream.skip(size.value); } - private Object readReadable(Class targetClass) throws IOException { - try{ + private Object readReadable(Class targetClass) + throws IOException + { + try + { Constructor constructor = targetClass.getDeclaredConstructor(MLSInputStream.class); return constructor.newInstance(this); - } catch (NoSuchMethodException | IllegalAccessException e) { + } + catch (NoSuchMethodException e) + { throw new IOException("Readable class does not have a public MLSInputStream constructor"); - } catch (InvocationTargetException e) { + } + catch (IllegalAccessException e) + { + throw new IOException("Readable class does not have a public MLSInputStream constructor"); + } + catch (InvocationTargetException e) + { throw new IOException("InvocationTargetException: " + e.getCause().getMessage()); - } catch (InstantiationException e) { + } + catch (InstantiationException e) + { throw new IOException("InstantiationException: " + e.getMessage()); } } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/MLSMessage.java b/mls/src/main/java/org/bouncycastle/mls/codec/MLSMessage.java index 3173a24cb8..5591c74d2a 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/MLSMessage.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/MLSMessage.java @@ -1,14 +1,13 @@ package org.bouncycastle.mls.codec; +import java.io.IOException; + import org.bouncycastle.mls.TreeKEM.LeafIndex; import org.bouncycastle.mls.crypto.MlsCipherSuite; -import org.bouncycastle.mls.crypto.MlsCipherSuite; import org.bouncycastle.util.Pack; -import java.io.IOException; - public class MLSMessage - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { public ProtocolVersion version; public WireFormat wireFormat; @@ -24,36 +23,36 @@ public MLSMessage(WireFormat wireFormat) this.wireFormat = wireFormat; } - static public MLSMessage externalProposal(MlsCipherSuite suite, byte[] groupID, long epoch, Proposal proposal, int signerIndex, byte[] sigSk) throws Exception + static public MLSMessage externalProposal(MlsCipherSuite suite, byte[] groupID, long epoch, Proposal proposal, int signerIndex, byte[] sigSk) + throws Exception { - //TODO check new byte[0] or null switch (proposal.getProposalType()) { - case ADD: - case REMOVE: - case PSK: - case REINIT: - case GROUP_CONTEXT_EXTENSIONS: - break; - case EXTERNAL_INIT: - case UPDATE: - default: - throw new Exception("External proposal has invalid type"); + case ADD: + case REMOVE: + case PSK: + case REINIT: + case GROUP_CONTEXT_EXTENSIONS: + break; + case EXTERNAL_INIT: + case UPDATE: + default: + throw new Exception("External proposal has invalid type"); } FramedContent content = FramedContent.proposal( - groupID, - epoch, - Sender.forExternal(signerIndex), - new byte[0], - MLSOutputStream.encode(proposal) + groupID, + epoch, + Sender.forExternal(signerIndex), + new byte[0], + MLSOutputStream.encode(proposal) ); AuthenticatedContent auth = AuthenticatedContent.sign( - WireFormat.mls_public_message, - content, - suite, - sigSk, - new byte[0] + WireFormat.mls_public_message, + content, + suite, + sigSk, + new byte[0] ); MLSMessage message = new MLSMessage(WireFormat.mls_public_message); message.publicMessage = PublicMessage.protect(auth, suite, new byte[0], new byte[0]); @@ -68,59 +67,62 @@ static public MLSMessage keyPackage(KeyPackage keyPackage) message.keyPackage = keyPackage; return message; } + @SuppressWarnings("unused") - public MLSMessage(MLSInputStream stream) throws IOException + public MLSMessage(MLSInputStream stream) + throws IOException { - this.version = ProtocolVersion.values()[(short) stream.read(short.class)]; - this.wireFormat = WireFormat.values()[(short) stream.read(short.class)]; + this.version = ProtocolVersion.values()[(short)stream.read(short.class)]; + this.wireFormat = WireFormat.values()[(short)stream.read(short.class)]; switch (wireFormat) { - case RESERVED: - break; - case mls_public_message: - this.publicMessage = (PublicMessage) stream.read(PublicMessage.class); - break; - case mls_private_message: - this.privateMessage = (PrivateMessage) stream.read(PrivateMessage.class); - break; - case mls_welcome: - this.welcome = (Welcome) stream.read(Welcome.class); - break; - case mls_group_info: - this.groupInfo = (GroupInfo) stream.read(GroupInfo.class); - break; - case mls_key_package: - this.keyPackage = (KeyPackage) stream.read(KeyPackage.class); - break; + case RESERVED: + break; + case mls_public_message: + this.publicMessage = (PublicMessage)stream.read(PublicMessage.class); + break; + case mls_private_message: + this.privateMessage = (PrivateMessage)stream.read(PrivateMessage.class); + break; + case mls_welcome: + this.welcome = (Welcome)stream.read(Welcome.class); + break; + case mls_group_info: + this.groupInfo = (GroupInfo)stream.read(GroupInfo.class); + break; + case mls_key_package: + this.keyPackage = (KeyPackage)stream.read(KeyPackage.class); + break; } } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(version); stream.write(wireFormat); switch (wireFormat) { - case RESERVED: - break; - case mls_public_message: - stream.write(publicMessage); - break; - case mls_private_message: - stream.write(privateMessage); - break; - case mls_welcome: - stream.write(welcome); - break; - case mls_group_info: - stream.write(groupInfo); - break; - case mls_key_package: - stream.write(keyPackage); - break; + case RESERVED: + break; + case mls_public_message: + stream.write(publicMessage); + break; + case mls_private_message: + stream.write(privateMessage); + break; + case mls_welcome: + stream.write(welcome); + break; + case mls_group_info: + stream.write(groupInfo); + break; + case mls_key_package: + stream.write(keyPackage); + break; } } @@ -128,55 +130,57 @@ public ContentType getContentType() { switch (wireFormat) { - case mls_public_message: - return publicMessage.content.getContentType(); - case mls_private_message: - return privateMessage.content_type; - case mls_welcome: - break; - case mls_group_info: - break; - case mls_key_package: - break; + case mls_public_message: + return publicMessage.content.getContentType(); + case mls_private_message: + return privateMessage.content_type; + case mls_welcome: + break; + case mls_group_info: + break; + case mls_key_package: + break; } return null; } + public MlsCipherSuite getCipherSuite() { switch (wireFormat) { - case mls_public_message: - case mls_private_message: - case mls_group_info: - break; - case mls_welcome: - return welcome.suite; - case mls_key_package: - return keyPackage.suite; + case mls_public_message: + case mls_private_message: + case mls_group_info: + break; + case mls_welcome: + return welcome.suite; + case mls_key_package: + return keyPackage.suite; } return null; } + public long getEpoch() { switch (wireFormat) { - case mls_public_message: - return publicMessage.content.epoch; - case mls_private_message: - return privateMessage.epoch; - case mls_welcome: - case mls_group_info: - case mls_key_package: - default: - //TODO: change and throw - return -1; + case mls_public_message: + return publicMessage.content.epoch; + case mls_private_message: + return privateMessage.epoch; + case mls_welcome: + case mls_group_info: + case mls_key_package: + default: + //TODO: change and throw + return -1; } } } class AuthenticatedContentTBM - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { FramedContentTBS contentTBS; FramedContentAuthData auth; @@ -186,14 +190,18 @@ public AuthenticatedContentTBM(FramedContentTBS contentTBS, FramedContentAuthDat this.contentTBS = contentTBS; this.auth = auth; } + @SuppressWarnings("unused") - public AuthenticatedContentTBM(MLSInputStream stream) throws IOException + public AuthenticatedContentTBM(MLSInputStream stream) + throws IOException { - contentTBS = (FramedContentTBS) stream.read(FramedContentTBS.class); - auth = (FramedContentAuthData) stream.read(FramedContentAuthData.class); + contentTBS = (FramedContentTBS)stream.read(FramedContentTBS.class); + auth = (FramedContentAuthData)stream.read(FramedContentAuthData.class); } + @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(contentTBS); stream.write(auth); @@ -215,33 +223,33 @@ public FramedContentAuthData(ContentType contentType, byte[] signature, byte[] c switch (contentType) { - case RESERVED: - case APPLICATION: - case PROPOSAL: - break; - case COMMIT: - //TODO - this.confirmation_tag = confirmation_tag; - // MAYBE MAKE THIS A FUNCTION IN FRAMED CONTENT - break; + case RESERVED: + case APPLICATION: + case PROPOSAL: + break; + case COMMIT: + this.confirmation_tag = confirmation_tag; + break; } } - public FramedContentAuthData(MLSInputStream stream, ContentType contentType) throws IOException + public FramedContentAuthData(MLSInputStream stream, ContentType contentType) + throws IOException { this.contentType = contentType; signature = stream.readOpaque(); - //TODO CHECK ITS NOT OPAQUE if (contentType == ContentType.COMMIT) { confirmation_tag = stream.readOpaque(); } } + @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(signature); - if(contentType == ContentType.COMMIT) + if (contentType == ContentType.COMMIT) { stream.writeOpaque(confirmation_tag); } @@ -262,57 +270,63 @@ public FramedContentTBS(WireFormat wireFormat, FramedContent content, GroupConte this.content = content; switch (content.sender.senderType) { - case MEMBER: - case NEW_MEMBER_COMMIT: - this.context = context; - break; + case MEMBER: + case NEW_MEMBER_COMMIT: + this.context = context; + break; } } - public FramedContentTBS(WireFormat wireFormat, FramedContent content, byte[] context) throws IOException + + public FramedContentTBS(WireFormat wireFormat, FramedContent content, byte[] context) + throws IOException { this.wireFormat = wireFormat; this.content = content; switch (content.sender.senderType) { - case MEMBER: - case NEW_MEMBER_COMMIT: - this.context = (GroupContext) MLSInputStream.decode(context, GroupContext.class); - break; - default: - break; + case MEMBER: + case NEW_MEMBER_COMMIT: + this.context = (GroupContext)MLSInputStream.decode(context, GroupContext.class); + break; + default: + break; } } + @SuppressWarnings("unused") - public FramedContentTBS(MLSInputStream stream) throws IOException + public FramedContentTBS(MLSInputStream stream) + throws IOException { - this.version = ProtocolVersion.values()[(short) stream.read(short.class)]; - this.wireFormat = WireFormat.values()[(short) stream.read(short.class)]; - this.content = (FramedContent) stream.read(FramedContent.class); + this.version = ProtocolVersion.values()[(short)stream.read(short.class)]; + this.wireFormat = WireFormat.values()[(short)stream.read(short.class)]; + this.content = (FramedContent)stream.read(FramedContent.class); switch (content.sender.senderType) { - case MEMBER: - case NEW_MEMBER_COMMIT: - this.context = (GroupContext) stream.read(GroupContext.class); - break; - case EXTERNAL: - case NEW_MEMBER_PROPOSAL: - break; + case MEMBER: + case NEW_MEMBER_COMMIT: + this.context = (GroupContext)stream.read(GroupContext.class); + break; + case EXTERNAL: + case NEW_MEMBER_PROPOSAL: + break; } } + @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(version); stream.write(wireFormat); stream.write(content); switch (content.sender.senderType) { - case MEMBER: - case NEW_MEMBER_COMMIT: - stream.write(context); - break; - default: - break; + case MEMBER: + case NEW_MEMBER_COMMIT: + stream.write(context); + break; + default: + break; } } } @@ -332,22 +346,26 @@ public SenderData(LeafIndex leafIndex, int generation, byte[] reuseGuard) this.generation = generation; this.reuseGuard = reuseGuard; } + @SuppressWarnings("unused") - SenderData(MLSInputStream stream) throws IOException + SenderData(MLSInputStream stream) + throws IOException { - sender = (LeafIndex) stream.read(LeafIndex.class); - generation = (int) stream.read(int.class); + sender = (LeafIndex)stream.read(LeafIndex.class); + generation = (int)stream.read(int.class); reuseGuard = Pack.intToBigEndian((int)stream.read(int.class)); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(sender); stream.write(generation); stream.write(Pack.bigEndianToInt(reuseGuard, 0)); } } + class SenderDataAAD implements MLSInputStream.Readable, MLSOutputStream.Writable { @@ -361,17 +379,20 @@ public SenderDataAAD(byte[] group_id, long epoch, ContentType contentType) this.epoch = epoch; this.contentType = contentType; } + @SuppressWarnings("unused") - SenderDataAAD(MLSInputStream stream) throws IOException + SenderDataAAD(MLSInputStream stream) + throws IOException { group_id = stream.readOpaque(); - epoch = (long) stream.read(long.class); - this.contentType = ContentType.values()[(byte) stream.read(byte.class)]; + epoch = (long)stream.read(long.class); + this.contentType = ContentType.values()[(byte)stream.read(byte.class)]; } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(group_id); stream.write(epoch); @@ -391,45 +412,48 @@ class PrivateMessageContent FramedContentAuthData auth; byte[] padding; - PrivateMessageContent(MLSInputStream stream, ContentType contentType) throws IOException + PrivateMessageContent(MLSInputStream stream, ContentType contentType) + throws IOException { switch (contentType) { - case APPLICATION: - application_data = stream.readOpaque(); - break; - case PROPOSAL: - proposal = (Proposal) stream.read(Proposal.class); - break; - case COMMIT: - commit = (Commit) stream.read(Commit.class); - break; + case APPLICATION: + application_data = stream.readOpaque(); + break; + case PROPOSAL: + proposal = (Proposal)stream.read(Proposal.class); + break; + case COMMIT: + commit = (Commit)stream.read(Commit.class); + break; } - auth = (FramedContentAuthData) stream.read(FramedContentAuthData.class); + auth = (FramedContentAuthData)stream.read(FramedContentAuthData.class); padding = stream.readOpaque(); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { switch (contentType) { - case APPLICATION: - stream.writeOpaque(application_data); - break; - case PROPOSAL: - stream.write(proposal); - break; - case COMMIT: - stream.write(commit); - break; + case APPLICATION: + stream.writeOpaque(application_data); + break; + case PROPOSAL: + stream.write(proposal); + break; + case COMMIT: + stream.write(commit); + break; } stream.write(auth); stream.writeOpaque(padding); } } + class PrivateContentAAD implements MLSInputStream.Readable, MLSOutputStream.Writable { @@ -445,16 +469,20 @@ public PrivateContentAAD(byte[] group_id, long epoch, ContentType content_type, this.content_type = content_type; this.authenticated_data = authenticated_data.clone(); } + @SuppressWarnings("unused") - PrivateContentAAD(MLSInputStream stream) throws IOException + PrivateContentAAD(MLSInputStream stream) + throws IOException { group_id = stream.readOpaque(); - epoch = (long) stream.read(long.class); - content_type = ContentType.values()[(byte) stream.read(byte.class)]; + epoch = (long)stream.read(long.class); + content_type = ContentType.values()[(byte)stream.read(byte.class)]; authenticated_data = stream.readOpaque(); } + @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(group_id); stream.write(epoch); @@ -476,14 +504,18 @@ public EncryptedGroupSecrets(byte[] new_member, HPKECiphertext encrypted_group_s this.new_member = new_member; this.encrypted_group_secrets = encrypted_group_secrets; } + @SuppressWarnings("unused") - EncryptedGroupSecrets(MLSInputStream stream) throws IOException + EncryptedGroupSecrets(MLSInputStream stream) + throws IOException { new_member = stream.readOpaque(); - encrypted_group_secrets = (HPKECiphertext) stream.read(HPKECiphertext.class); + encrypted_group_secrets = (HPKECiphertext)stream.read(HPKECiphertext.class); } + @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(new_member); stream.write(encrypted_group_secrets); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/MLSOutputStream.java b/mls/src/main/java/org/bouncycastle/mls/codec/MLSOutputStream.java index 124dcefe39..4b07d8c506 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/MLSOutputStream.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/MLSOutputStream.java @@ -3,87 +3,121 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; -public class MLSOutputStream { - public interface Writable { - void writeTo(MLSOutputStream stream) throws IOException; +public class MLSOutputStream +{ + public interface Writable + { + void writeTo(MLSOutputStream stream) + throws IOException; } final ByteArrayOutputStream stream; - public MLSOutputStream() { + public MLSOutputStream() + { stream = new ByteArrayOutputStream(); } - public static byte[] encode(Object val) throws IOException { + public static byte[] encode(Object val) + throws IOException + { MLSOutputStream stream = new MLSOutputStream(); stream.write(val); return stream.toByteArray(); } - public void write(Object val) throws IOException { + public void write(Object val) + throws IOException + { Class valClass = val.getClass(); - if (valClass == Boolean.class) { - writeBoolean((boolean) val); + if (valClass == Boolean.class) + { + writeBoolean((boolean)val); return; - } else if (valClass == Byte.class) { + } + else if (valClass == Byte.class) + { writeInt((byte)val, 1); return; - } else if (valClass == Short.class) { + } + else if (valClass == Short.class) + { writeInt((short)val, 2); return; - } else if (valClass == Integer.class) { + } + else if (valClass == Integer.class) + { writeInt((int)val, 4); return; - } else if (valClass == Long.class) { + } + else if (valClass == Long.class) + { writeInt((long)val, 8); return; - } else if (Writable.class.isAssignableFrom(valClass)) { - ((Writable) val).writeTo(this); + } + else if (Writable.class.isAssignableFrom(valClass)) + { + ((Writable)val).writeTo(this); return; } throw new IllegalArgumentException("Target type cannot be encoded"); } - public byte[] toByteArray() { + public byte[] toByteArray() + { return stream.toByteArray(); } - void writeBoolean(boolean val) { + void writeBoolean(boolean val) + { writeInt((val) ? 1 : 0, 1); } - private void writeInt(long val, int len) { - for (int i = 0; i < len; i++) { + private void writeInt(long val, int len) + { + for (int i = 0; i < len; i++) + { byte b = (byte)(val >> (8 * (len - i - 1))); stream.write(b); } } - public void writeOptional(Object val) throws IOException { + public void writeOptional(Object val) + throws IOException + { writeBoolean(val != null); - if (val != null) { + if (val != null) + { write(val); } } - public void writeArray(T[] val) throws IOException { + public void writeArray(T[] val) + throws IOException + { write(val.length); // write(new Varint(val.length)); - for (T x : val) { + for (T x : val) + { write(x); } } - public void writeOpaque(byte[] val) throws IOException { + public void writeOpaque(byte[] val) + throws IOException + { write(new Varint(val.length)); stream.write(val); } - public void writeList(Iterable val) throws IOException { + public void writeList(Iterable val) + throws IOException + { // Pre-encode content MLSOutputStream content = new MLSOutputStream(); - for (T x : val) { + for (T x : val) + { content.write(x); } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/NodeType.java b/mls/src/main/java/org/bouncycastle/mls/codec/NodeType.java index e7533ebdde..dca67b0569 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/NodeType.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/NodeType.java @@ -3,11 +3,11 @@ import java.io.IOException; public enum NodeType - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { - RESERVED((byte) 0), - leaf((byte) 1), - parent((byte) 2); + RESERVED((byte)0), + leaf((byte)1), + parent((byte)2); final byte value; @@ -17,13 +17,15 @@ public enum NodeType } @SuppressWarnings("unused") - NodeType(MLSInputStream stream) throws IOException + NodeType(MLSInputStream stream) + throws IOException { - this.value = (byte) stream.read(byte.class); + this.value = (byte)stream.read(byte.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(value); } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/PSKType.java b/mls/src/main/java/org/bouncycastle/mls/codec/PSKType.java index 0608b143e1..811b8d2611 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/PSKType.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/PSKType.java @@ -2,24 +2,31 @@ import java.io.IOException; -public enum PSKType implements MLSInputStream.Readable, MLSOutputStream.Writable { - REFERENCE((byte) 0), - EXTERNAL((byte) 1), - RESUMPTION((byte) 2); +public enum PSKType + implements MLSInputStream.Readable, MLSOutputStream.Writable +{ + REFERENCE((byte)0), + EXTERNAL((byte)1), + RESUMPTION((byte)2); final byte value; - PSKType(byte value) { + PSKType(byte value) + { this.value = value; } @SuppressWarnings("unused") - PSKType(MLSInputStream stream) throws IOException { - this.value = (byte) stream.read(byte.class); + PSKType(MLSInputStream stream) + throws IOException + { + this.value = (byte)stream.read(byte.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException { + public void writeTo(MLSOutputStream stream) + throws IOException + { stream.write(value); } } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/PathSecret.java b/mls/src/main/java/org/bouncycastle/mls/codec/PathSecret.java index 446fbc9366..1f9988193f 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/PathSecret.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/PathSecret.java @@ -3,7 +3,7 @@ import java.io.IOException; public class PathSecret - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { byte[] path_secret; @@ -16,14 +16,17 @@ public PathSecret(byte[] path_secret) { this.path_secret = path_secret; } + @SuppressWarnings("unused") - PathSecret(MLSInputStream stream) throws IOException + PathSecret(MLSInputStream stream) + throws IOException { path_secret = stream.readOpaque(); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(path_secret); } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/PreSharedKeyID.java b/mls/src/main/java/org/bouncycastle/mls/codec/PreSharedKeyID.java index 176ac94c93..d2069f09d2 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/PreSharedKeyID.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/PreSharedKeyID.java @@ -1,26 +1,32 @@ package org.bouncycastle.mls.codec; -import org.bouncycastle.mls.crypto.Secret; - import java.io.IOException; import java.util.Arrays; -public class PreSharedKeyID implements MLSInputStream.Readable, MLSOutputStream.Writable { +import org.bouncycastle.mls.crypto.Secret; - public static class External { +public class PreSharedKeyID + implements MLSInputStream.Readable, MLSOutputStream.Writable +{ + + public static class External + { public final Secret externalPSKID; - public External(byte[] externalPSKID) { + public External(byte[] externalPSKID) + { this.externalPSKID = new Secret(externalPSKID); } } - public static class Resumption { + public static class Resumption + { public final ResumptionPSKUsage resumptionPSKUsage; public final byte[] pskGroupID; public final long pskEpoch; - public Resumption(ResumptionPSKUsage resumptionPSKUsage, byte[] pskGroupID, long pskEpoch) { + public Resumption(ResumptionPSKUsage resumptionPSKUsage, byte[] pskGroupID, long pskEpoch) + { this.resumptionPSKUsage = resumptionPSKUsage; this.pskGroupID = pskGroupID; this.pskEpoch = pskEpoch; @@ -32,63 +38,72 @@ public Resumption(ResumptionPSKUsage resumptionPSKUsage, byte[] pskGroupID, long public final Resumption resumption; public final byte[] pskNonce; - PreSharedKeyID(PSKType pskType, External external, Resumption resumption, byte[] pskNonce) { + PreSharedKeyID(PSKType pskType, External external, Resumption resumption, byte[] pskNonce) + { this.pskType = pskType; this.external = external; this.resumption = resumption; this.pskNonce = pskNonce; } - public static PreSharedKeyID external(byte[] externalPSKID, byte[] pskNonce) { + public static PreSharedKeyID external(byte[] externalPSKID, byte[] pskNonce) + { External external = new External(externalPSKID); return new PreSharedKeyID(PSKType.EXTERNAL, external, null, pskNonce); } - public static PreSharedKeyID resumption(ResumptionPSKUsage resumptionPSKUsage, byte[] pskGroupID, long pskEpoch, byte[] pskNonce) { + public static PreSharedKeyID resumption(ResumptionPSKUsage resumptionPSKUsage, byte[] pskGroupID, long pskEpoch, byte[] pskNonce) + { Resumption resumptionVal = new Resumption(resumptionPSKUsage, pskGroupID, pskEpoch); return new PreSharedKeyID(PSKType.RESUMPTION, null, resumptionVal, pskNonce); } @SuppressWarnings("unused") - public PreSharedKeyID(MLSInputStream stream) throws IOException { - this.pskType = PSKType.values()[(byte) stream.read(byte.class)]; - - switch (this.pskType) { - case EXTERNAL: - byte[] externalPSKID = stream.readOpaque(); - external = new External(externalPSKID); - resumption = null; - break; - - case RESUMPTION: - ResumptionPSKUsage resumptionPSKUsage = ResumptionPSKUsage.values()[(byte) stream.read(byte.class)]; - byte[] pskGroupID = stream.readOpaque(); - long pskEpoch = (long) stream.read(long.class); - - external = null; - resumption = new Resumption(resumptionPSKUsage, pskGroupID, pskEpoch); - break; - - default: - throw new IOException("Invalid PSKType"); + public PreSharedKeyID(MLSInputStream stream) + throws IOException + { + this.pskType = PSKType.values()[(byte)stream.read(byte.class)]; + + switch (this.pskType) + { + case EXTERNAL: + byte[] externalPSKID = stream.readOpaque(); + external = new External(externalPSKID); + resumption = null; + break; + + case RESUMPTION: + ResumptionPSKUsage resumptionPSKUsage = ResumptionPSKUsage.values()[(byte)stream.read(byte.class)]; + byte[] pskGroupID = stream.readOpaque(); + long pskEpoch = (long)stream.read(long.class); + + external = null; + resumption = new Resumption(resumptionPSKUsage, pskGroupID, pskEpoch); + break; + + default: + throw new IOException("Invalid PSKType"); } pskNonce = stream.readOpaque(); } @Override - public void writeTo(MLSOutputStream stream) throws IOException { + public void writeTo(MLSOutputStream stream) + throws IOException + { stream.write(pskType); - switch (pskType) { - case EXTERNAL: - stream.writeOpaque(external.externalPSKID.value()); - break; - - case RESUMPTION: - stream.write(resumption.resumptionPSKUsage); - stream.writeOpaque(resumption.pskGroupID); - stream.write(resumption.pskEpoch); - break; + switch (pskType) + { + case EXTERNAL: + stream.writeOpaque(external.externalPSKID.value()); + break; + + case RESUMPTION: + stream.write(resumption.resumptionPSKUsage); + stream.writeOpaque(resumption.pskGroupID); + stream.write(resumption.pskEpoch); + break; } stream.writeOpaque(pskNonce); @@ -107,7 +122,7 @@ public boolean equals(Object o) return false; } - PreSharedKeyID pskid = (PreSharedKeyID) o; + PreSharedKeyID pskid = (PreSharedKeyID)o; if (pskid.pskType != pskType) { return false; @@ -115,10 +130,10 @@ public boolean equals(Object o) switch (pskType) { - case EXTERNAL: - return Arrays.equals(pskid.external.externalPSKID.value(), external.externalPSKID.value()); - case RESUMPTION: - return Arrays.equals(pskid.resumption.pskGroupID, resumption.pskGroupID) && (pskid.resumption.pskEpoch == resumption.pskEpoch); + case EXTERNAL: + return Arrays.equals(pskid.external.externalPSKID.value(), external.externalPSKID.value()); + case RESUMPTION: + return Arrays.equals(pskid.resumption.pskGroupID, resumption.pskGroupID) && (pskid.resumption.pskEpoch == resumption.pskEpoch); } return false; diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/PrivateMessage.java b/mls/src/main/java/org/bouncycastle/mls/codec/PrivateMessage.java index 2027546c27..49203cd6e3 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/PrivateMessage.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/PrivateMessage.java @@ -1,5 +1,7 @@ package org.bouncycastle.mls.codec; +import java.io.IOException; + import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.mls.GroupKeySet; import org.bouncycastle.mls.KeyGeneration; @@ -8,11 +10,8 @@ import org.bouncycastle.mls.crypto.MlsCipherSuite; import org.bouncycastle.util.Arrays; -import java.io.IOException; -import java.security.SecureRandom; - public class PrivateMessage - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { byte[] group_id; long epoch; @@ -30,19 +29,21 @@ public PrivateMessage(byte[] group_id, long epoch, ContentType content_type, byt this.encrypted_sender_data = encrypted_sender_data; this.ciphertext = ciphertext; } + @SuppressWarnings("unused") - PrivateMessage(MLSInputStream stream) throws IOException + PrivateMessage(MLSInputStream stream) + throws IOException { group_id = stream.readOpaque(); - epoch = (long) stream.read(long.class); - content_type = ContentType.values()[(byte) stream.read(byte.class)]; + epoch = (long)stream.read(long.class); + content_type = ContentType.values()[(byte)stream.read(byte.class)]; authenticated_data = stream.readOpaque(); encrypted_sender_data = stream.readOpaque(); ciphertext = stream.readOpaque(); } static public PrivateMessage protect(AuthenticatedContent auth, MlsCipherSuite suite, GroupKeySet keys, byte[] senderDataSecretBytes, int paddingSize) - throws IOException, IllegalAccessException, InvalidCipherTextException + throws IOException, IllegalAccessException, InvalidCipherTextException { // Get KeyGeneration from the secret tree LeafIndex index = auth.content.sender.sender; @@ -52,58 +53,54 @@ static public PrivateMessage protect(AuthenticatedContent auth, MlsCipherSuite s // Encrypt the content byte[] contentPt = serializeContentPt(auth.content, auth.auth, paddingSize); -// if (contentPt.length < 512) -// { -// contentPt = Arrays.concatenate(contentPt, new byte[512 - contentPt.length]);//TODO CHECK -// } -// System.out.println("serialized_private_content: " + Hex.toHexString(contentPt)); PrivateContentAAD contentAAD = new PrivateContentAAD( - auth.content.group_id, - auth.content.epoch, - auth.content.contentType, - auth.content.authenticated_data + auth.content.group_id, + auth.content.epoch, + auth.content.contentType, + auth.content.authenticated_data ); byte[] contentCt = suite.getAEAD().seal( - keyGen.key, - keyGen.nonce, - MLSOutputStream.encode(contentAAD), - contentPt + keyGen.key, + keyGen.nonce, + MLSOutputStream.encode(contentAAD), + contentPt ); // Encrypt the sender data LeafIndex senderIndex = auth.content.sender.sender; SenderData senderDataPt = new SenderData( - senderIndex, - keyGen.generation, - reuseGuard + senderIndex, + keyGen.generation, + reuseGuard ); SenderDataAAD senderDataAAD = new SenderDataAAD( - auth.content.group_id, - auth.content.epoch, - auth.content.contentType + auth.content.group_id, + auth.content.epoch, + auth.content.contentType ); KeyGeneration senderDataKeys = KeyScheduleEpoch.senderDataKeys(suite, senderDataSecretBytes.clone(), contentCt); byte[] senderDataCt = suite.getAEAD().seal( - senderDataKeys.key, - senderDataKeys.nonce, - MLSOutputStream.encode(senderDataAAD), - MLSOutputStream.encode(senderDataPt) + senderDataKeys.key, + senderDataKeys.nonce, + MLSOutputStream.encode(senderDataAAD), + MLSOutputStream.encode(senderDataPt) ); return new PrivateMessage( - auth.content.group_id, - auth.content.epoch, - auth.content.contentType, - auth.content.authenticated_data, - senderDataCt.clone(), - contentCt.clone() + auth.content.group_id, + auth.content.epoch, + auth.content.contentType, + auth.content.authenticated_data, + senderDataCt.clone(), + contentCt.clone() ); } - //TODO: change senderDataSecretBytes to Secret class? - public AuthenticatedContent unprotect(MlsCipherSuite suite, GroupKeySet keys, byte[] senderDataSecretBytes) throws IOException, InvalidCipherTextException, IllegalAccessException + + public AuthenticatedContent unprotect(MlsCipherSuite suite, GroupKeySet keys, byte[] senderDataSecretBytes) + throws Exception { // Decrypt and parse the sender data @@ -112,13 +109,13 @@ public AuthenticatedContent unprotect(MlsCipherSuite suite, GroupKeySet keys, by SenderDataAAD senderDataAAD = new SenderDataAAD(group_id, epoch, content_type); byte[] senderDataPt = suite.getAEAD().open( - senderKeys.key, - senderKeys.nonce, - MLSOutputStream.encode(senderDataAAD), - encrypted_sender_data + senderKeys.key, + senderKeys.nonce, + MLSOutputStream.encode(senderDataAAD), + encrypted_sender_data ); - SenderData senderData = (SenderData) MLSInputStream.decode(senderDataPt, SenderData.class); + SenderData senderData = (SenderData)MLSInputStream.decode(senderDataPt, SenderData.class); //Cannot Process Message from self! if (!keys.hasLeaf(senderData.sender)) @@ -131,43 +128,43 @@ public AuthenticatedContent unprotect(MlsCipherSuite suite, GroupKeySet keys, by PrivateContentAAD contentAAD = new PrivateContentAAD(group_id, epoch, content_type, authenticated_data); byte[] contentPtBytes = suite.getAEAD().open( - contentKeys.key, - contentKeys.nonce, - MLSOutputStream.encode(contentAAD), - ciphertext + contentKeys.key, + contentKeys.nonce, + MLSOutputStream.encode(contentAAD), + ciphertext ); - //TODO: check if erase is working properly also check when to erase keys.erase(content_type, senderData.sender, senderData.generation); // Parse Content FramedContent content = new FramedContent( - group_id, - epoch, - Sender.forMember(senderData.sender), - authenticated_data, - null, - content_type, - null, - null + group_id, + epoch, + Sender.forMember(senderData.sender), + authenticated_data, + null, + content_type, + null, + null ); FramedContentAuthData auth = new FramedContentAuthData( - content_type, - null, - null + content_type, + null, + null ); deserializeContentPt(contentPtBytes, content, auth); return new AuthenticatedContent( - WireFormat.mls_private_message, - content, - auth + WireFormat.mls_private_message, + content, + auth ); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(group_id); stream.write(epoch); @@ -177,59 +174,61 @@ public void writeTo(MLSOutputStream stream) throws IOException stream.writeOpaque(ciphertext); } - private void deserializeContentPt(byte[] contentPt, FramedContent content, FramedContentAuthData auth) throws IOException + private void deserializeContentPt(byte[] contentPt, FramedContent content, FramedContentAuthData auth) + throws IOException { MLSInputStream stream = new MLSInputStream(contentPt); switch (content_type) { - case APPLICATION: - content.application_data = stream.readOpaque(); - break; - case PROPOSAL: - content.proposal = (Proposal) stream.read(Proposal.class); - break; - case COMMIT: - content.commit = (Commit) stream.read(Commit.class); - break; + case APPLICATION: + content.application_data = stream.readOpaque(); + break; + case PROPOSAL: + content.proposal = (Proposal)stream.read(Proposal.class); + break; + case COMMIT: + content.commit = (Commit)stream.read(Commit.class); + break; } auth.signature = stream.readOpaque(); switch (content_type) { - case APPLICATION: - case PROPOSAL: - break; - case COMMIT: - auth.confirmation_tag = stream.readOpaque(); - break; + case APPLICATION: + case PROPOSAL: + break; + case COMMIT: + auth.confirmation_tag = stream.readOpaque(); + break; } //TODO: read padding? } - static private byte[] serializeContentPt(FramedContent content, FramedContentAuthData auth, int paddingSize) throws IOException + + static private byte[] serializeContentPt(FramedContent content, FramedContentAuthData auth, int paddingSize) + throws IOException { MLSOutputStream stream = new MLSOutputStream(); switch (content.contentType) { - case APPLICATION: - stream.writeOpaque(content.application_data); - break; - case PROPOSAL: - stream.write(content.proposal); - break; - case COMMIT: - stream.write(content.commit); - break; + case APPLICATION: + stream.writeOpaque(content.application_data); + break; + case PROPOSAL: + stream.write(content.proposal); + break; + case COMMIT: + stream.write(content.commit); + break; } stream.writeOpaque(auth.signature); switch (content.contentType) { - case APPLICATION: - case PROPOSAL: - break; - case COMMIT: - stream.writeOpaque(auth.confirmation_tag); - break; + case APPLICATION: + case PROPOSAL: + break; + case COMMIT: + stream.writeOpaque(auth.confirmation_tag); + break; } - //TODO: write padding; return Arrays.concatenate(stream.toByteArray(), new byte[paddingSize]); } } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/Proposal.java b/mls/src/main/java/org/bouncycastle/mls/codec/Proposal.java index 0a840c6455..35b5b9dae4 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/Proposal.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/Proposal.java @@ -1,15 +1,15 @@ package org.bouncycastle.mls.codec; -import org.bouncycastle.mls.TreeKEM.LeafIndex; -import org.bouncycastle.mls.TreeKEM.LeafNode; -import org.bouncycastle.mls.crypto.MlsCipherSuite; - import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.bouncycastle.mls.TreeKEM.LeafIndex; +import org.bouncycastle.mls.TreeKEM.LeafNode; +import org.bouncycastle.mls.crypto.MlsCipherSuite; + public class Proposal - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { ProposalType proposalType; Add add; @@ -59,13 +59,14 @@ public LeafNode getLeafNode() { switch (proposalType) { - case ADD: - return add.keyPackage.leaf_node; - case UPDATE: - return update.leafNode; + case ADD: + return add.keyPackage.leaf_node; + case UPDATE: + return update.leafNode; } return null; } + public ProposalType getProposalType() { return proposalType; @@ -83,10 +84,11 @@ public Proposal(ProposalType proposalType, Add add, Update update, Remove remove this.groupContextExtensions = groupContextExtensions; } - public Proposal(MLSInputStream stream) throws IOException + public Proposal(MLSInputStream stream) + throws IOException { - short propType = (short) stream.read(short.class); - if(Grease.isGrease(propType) == -1) + short propType = (short)stream.read(short.class); + if (Grease.isGrease(propType) == -1) { proposalType = ProposalType.values()[propType]; } @@ -96,138 +98,145 @@ public Proposal(MLSInputStream stream) throws IOException } switch (proposalType) { - case ADD: - add = (Add) stream.read(Add.class); - break; - case UPDATE: - update = (Update) stream.read(Update.class); - break; - case REMOVE: - remove = (Remove) stream.read(Remove.class); - break; - case PSK: - preSharedKey = (PreSharedKey) stream.read(PreSharedKey.class); - break; - case REINIT: - reInit = (ReInit) stream.read(ReInit.class); - break; - case EXTERNAL_INIT: - externalInit = (ExternalInit) stream.read(ExternalInit.class); - break; - case GROUP_CONTEXT_EXTENSIONS: - groupContextExtensions = (GroupContextExtensions) stream.read(GroupContextExtensions.class); - break; + case ADD: + add = (Add)stream.read(Add.class); + break; + case UPDATE: + update = (Update)stream.read(Update.class); + break; + case REMOVE: + remove = (Remove)stream.read(Remove.class); + break; + case PSK: + preSharedKey = (PreSharedKey)stream.read(PreSharedKey.class); + break; + case REINIT: + reInit = (ReInit)stream.read(ReInit.class); + break; + case EXTERNAL_INIT: + externalInit = (ExternalInit)stream.read(ExternalInit.class); + break; + case GROUP_CONTEXT_EXTENSIONS: + groupContextExtensions = (GroupContextExtensions)stream.read(GroupContextExtensions.class); + break; } } - //TODO: this looks so bad, make this cleaner - // maybe inheritance? - public static Proposal add(KeyPackage newMember) throws IOException + public static Proposal add(KeyPackage newMember) + throws IOException { return new Proposal(ProposalType.ADD, - new Add(newMember), null, null, null, null, null, null); + new Add(newMember), null, null, null, null, null, null); } public static Proposal update(LeafNode leafNode) { return new Proposal(ProposalType.UPDATE, null, - new Update(leafNode), null, null, null, null, null); + new Update(leafNode), null, null, null, null, null); } public static Proposal remove(LeafIndex removed) { - return new Proposal(ProposalType.REMOVE,null, null, - new Remove(removed), null, null, null, null); + return new Proposal(ProposalType.REMOVE, null, null, + new Remove(removed), null, null, null, null); } public static Proposal preSharedKey(PreSharedKeyID pskID) { - return new Proposal(ProposalType.PSK,null, null, null, - new PreSharedKey(pskID), null, null, null); + return new Proposal(ProposalType.PSK, null, null, null, + new PreSharedKey(pskID), null, null, null); } + public static Proposal reInit(byte[] group_id, ProtocolVersion version, MlsCipherSuite cipherSuite, List extensions) { - return new Proposal(ProposalType.REINIT,null, null, null, null, - new ReInit(group_id, version, cipherSuite, extensions), null, null); + return new Proposal(ProposalType.REINIT, null, null, null, null, + new ReInit(group_id, version, cipherSuite, extensions), null, null); } public static Proposal externalInit(byte[] kemOutput) { - return new Proposal(ProposalType.EXTERNAL_INIT,null, null, null, null, null, - new ExternalInit(kemOutput), null); + return new Proposal(ProposalType.EXTERNAL_INIT, null, null, null, null, null, + new ExternalInit(kemOutput), null); } public static Proposal groupContextExtensions(List extensions) { - return new Proposal(ProposalType.GROUP_CONTEXT_EXTENSIONS,null, null, null, null, null, null, - new GroupContextExtensions(extensions)); + return new Proposal(ProposalType.GROUP_CONTEXT_EXTENSIONS, null, null, null, null, null, null, + new GroupContextExtensions(extensions)); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(proposalType); switch (proposalType) { - case ADD: - stream.write(add); - break; - case UPDATE: - stream.write(update); - break; - case REMOVE: - stream.write(remove); - break; - case PSK: - stream.write(preSharedKey); - break; - case REINIT: - stream.write(reInit); - break; - case EXTERNAL_INIT: - stream.write(externalInit); - break; - case GROUP_CONTEXT_EXTENSIONS: - stream.write(groupContextExtensions); - break; + case ADD: + stream.write(add); + break; + case UPDATE: + stream.write(update); + break; + case REMOVE: + stream.write(remove); + break; + case PSK: + stream.write(preSharedKey); + break; + case REINIT: + stream.write(reInit); + break; + case EXTERNAL_INIT: + stream.write(externalInit); + break; + case GROUP_CONTEXT_EXTENSIONS: + stream.write(groupContextExtensions); + break; } } public static class Add - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { public KeyPackage keyPackage; - public Add(KeyPackage keyPackage) throws IOException + public Add(KeyPackage keyPackage) + throws IOException { -// this.keyPackage = keyPackage; - this.keyPackage = (KeyPackage) MLSInputStream.decode(MLSOutputStream.encode(keyPackage), KeyPackage.class); // TODO CHANGE + this.keyPackage = (KeyPackage)MLSInputStream.decode(MLSOutputStream.encode(keyPackage), KeyPackage.class); } + @SuppressWarnings("unused") - Add(MLSInputStream stream) throws IOException + Add(MLSInputStream stream) + throws IOException { - keyPackage = (KeyPackage) stream.read(KeyPackage.class); + keyPackage = (KeyPackage)stream.read(KeyPackage.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(keyPackage); } } public static class Update - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { LeafNode leafNode; + @SuppressWarnings("unused") - public Update(MLSInputStream stream) throws IOException + public Update(MLSInputStream stream) + throws IOException { - leafNode = (LeafNode) stream.read(LeafNode.class); + leafNode = (LeafNode)stream.read(LeafNode.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(leafNode); } @@ -244,7 +253,7 @@ public LeafNode getLeafNode() } public static class Remove - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { public LeafIndex removed; @@ -252,31 +261,37 @@ public Remove(LeafIndex removed) { this.removed = removed; } + @SuppressWarnings("unused") - public Remove(MLSInputStream stream) throws IOException + public Remove(MLSInputStream stream) + throws IOException { - removed = (LeafIndex) stream.read(LeafIndex.class); + removed = (LeafIndex)stream.read(LeafIndex.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(removed); } } public static class PreSharedKey - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { public PreSharedKeyID psk; + @SuppressWarnings("unused") - PreSharedKey(MLSInputStream stream) throws IOException + PreSharedKey(MLSInputStream stream) + throws IOException { - psk = (PreSharedKeyID) stream.read(PreSharedKeyID.class); + psk = (PreSharedKeyID)stream.read(PreSharedKeyID.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(psk); } @@ -288,7 +303,7 @@ public PreSharedKey(PreSharedKeyID psk) } public static class ReInit - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { byte[] group_id; ProtocolVersion version; @@ -324,19 +339,22 @@ public ReInit(byte[] group_id, ProtocolVersion version, MlsCipherSuite cipherSui this.cipherSuite = suite.getSuiteID(); this.extensions = extensions; } + @SuppressWarnings("unused") - ReInit(MLSInputStream stream) throws Exception + ReInit(MLSInputStream stream) + throws Exception { group_id = stream.readOpaque(); - version = ProtocolVersion.values()[(short) stream.read(short.class)]; - cipherSuite = (short) stream.read(short.class); + version = ProtocolVersion.values()[(short)stream.read(short.class)]; + cipherSuite = (short)stream.read(short.class); suite = MlsCipherSuite.getSuite(cipherSuite); - extensions = new ArrayList<>(); + extensions = new ArrayList(); stream.readList(extensions, Extension.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(group_id); stream.write(version); @@ -346,17 +364,20 @@ public void writeTo(MLSOutputStream stream) throws IOException } public static class ExternalInit - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { public byte[] kemOutput; + @SuppressWarnings("unused") - ExternalInit(MLSInputStream stream) throws IOException + ExternalInit(MLSInputStream stream) + throws IOException { kemOutput = stream.readOpaque(); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(kemOutput); } @@ -368,24 +389,27 @@ public ExternalInit(byte[] kemOutput) } public static class GroupContextExtensions - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { public GroupContextExtensions(List extensions) { - this.extensions = new ArrayList<>(); + this.extensions = new ArrayList(); this.extensions.addAll(extensions); } public List extensions; + @SuppressWarnings("unused") - GroupContextExtensions(MLSInputStream stream) throws IOException + GroupContextExtensions(MLSInputStream stream) + throws IOException { - extensions = new ArrayList<>(); + extensions = new ArrayList(); stream.readList(extensions, Extension.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeList(extensions); } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/ProposalOrRef.java b/mls/src/main/java/org/bouncycastle/mls/codec/ProposalOrRef.java index ba9016e25a..994e75ccac 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/ProposalOrRef.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/ProposalOrRef.java @@ -3,12 +3,12 @@ import java.io.IOException; public class ProposalOrRef - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { ProposalOrRefType type; Proposal proposal; - byte[] reference; // TODO ProposalRef + byte[] reference; public ProposalOrRefType getType() { @@ -30,43 +30,48 @@ static public ProposalOrRef forRef(byte[] ref) { return new ProposalOrRef(ProposalOrRefType.REFERENCE, null, ref); } + static public ProposalOrRef forProposal(Proposal proposal) { return new ProposalOrRef(ProposalOrRefType.PROPOSAL, proposal, null); } + public ProposalOrRef(ProposalOrRefType type, Proposal proposal, byte[] reference) { this.type = type; this.proposal = proposal; this.reference = reference; } + @SuppressWarnings("unused") - ProposalOrRef(MLSInputStream stream) throws IOException + ProposalOrRef(MLSInputStream stream) + throws IOException { - this.type = ProposalOrRefType.values()[(byte) stream.read(byte.class)]; + this.type = ProposalOrRefType.values()[(byte)stream.read(byte.class)]; switch (type) { - case PROPOSAL: - proposal = (Proposal) stream.read(Proposal.class); - break; - case REFERENCE: - reference = stream.readOpaque(); - break; + case PROPOSAL: + proposal = (Proposal)stream.read(Proposal.class); + break; + case REFERENCE: + reference = stream.readOpaque(); + break; } } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(type); switch (type) { - case PROPOSAL: - stream.write(proposal); - break; - case REFERENCE: - stream.writeOpaque(reference); - break; + case PROPOSAL: + stream.write(proposal); + break; + case REFERENCE: + stream.writeOpaque(reference); + break; } } } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/ProposalOrRefType.java b/mls/src/main/java/org/bouncycastle/mls/codec/ProposalOrRefType.java index bba8a4cdb0..261cc81ff0 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/ProposalOrRefType.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/ProposalOrRefType.java @@ -3,11 +3,11 @@ import java.io.IOException; public enum ProposalOrRefType - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { - RESERVED((byte) 0), - PROPOSAL((byte) 1), - REFERENCE((byte) 2); + RESERVED((byte)0), + PROPOSAL((byte)1), + REFERENCE((byte)2); final byte value; @@ -15,14 +15,17 @@ public enum ProposalOrRefType { this.value = value; } + @SuppressWarnings("unused") - ProposalOrRefType(MLSInputStream stream) throws IOException + ProposalOrRefType(MLSInputStream stream) + throws IOException { - this.value = (byte) stream.read(byte.class); + this.value = (byte)stream.read(byte.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(value); } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/ProposalType.java b/mls/src/main/java/org/bouncycastle/mls/codec/ProposalType.java index 840a3b17f7..df6f31b2b5 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/ProposalType.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/ProposalType.java @@ -3,31 +3,31 @@ import java.io.IOException; public enum ProposalType - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { - RESERVED((short) 0), - ADD((short) 1), - UPDATE((short) 2), - REMOVE((short) 3), - PSK((short) 4), - REINIT((short) 5), - EXTERNAL_INIT((short) 6), - GROUP_CONTEXT_EXTENSIONS((short) 7), - GREASE_0((short) 0x0A0A), - GREASE_1((short) 0x1A1A), - GREASE_2((short) 0x2A2A), - GREASE_3((short) 0x3A3A), - GREASE_4((short) 0x4A4A), - GREASE_5((short) 0x5A5A), - GREASE_6((short) 0x6A6A), - GREASE_7((short) 0x7A7A), - GREASE_8((short) 0x8A8A), - GREASE_9((short) 0x9A9A), - GREASE_A((short) 0xAAAA), - GREASE_B((short) 0xBABA), - GREASE_C((short) 0xCACA), - GREASE_D((short) 0xDADA), - GREASE_E((short) 0xEAEA); + RESERVED((short)0), + ADD((short)1), + UPDATE((short)2), + REMOVE((short)3), + PSK((short)4), + REINIT((short)5), + EXTERNAL_INIT((short)6), + GROUP_CONTEXT_EXTENSIONS((short)7), + GREASE_0((short)0x0A0A), + GREASE_1((short)0x1A1A), + GREASE_2((short)0x2A2A), + GREASE_3((short)0x3A3A), + GREASE_4((short)0x4A4A), + GREASE_5((short)0x5A5A), + GREASE_6((short)0x6A6A), + GREASE_7((short)0x7A7A), + GREASE_8((short)0x8A8A), + GREASE_9((short)0x9A9A), + GREASE_A((short)0xAAAA), + GREASE_B((short)0xBABA), + GREASE_C((short)0xCACA), + GREASE_D((short)0xDADA), + GREASE_E((short)0xEAEA); final short value; ProposalType(short value) @@ -36,13 +36,15 @@ public enum ProposalType } @SuppressWarnings("unused") - ProposalType(MLSInputStream stream) throws IOException + ProposalType(MLSInputStream stream) + throws IOException { - this.value = (short) stream.read(short.class); + this.value = (short)stream.read(short.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { // if (value == GREASE.value) // { diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/ProtocolVersion.java b/mls/src/main/java/org/bouncycastle/mls/codec/ProtocolVersion.java index 2587bf4322..228f4885ba 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/ProtocolVersion.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/ProtocolVersion.java @@ -3,10 +3,10 @@ import java.io.IOException; public enum ProtocolVersion - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { - RESERVED((short) 0), - mls10((short) 1); + RESERVED((short)0), + mls10((short)1); final short value; ProtocolVersion(short value) @@ -15,7 +15,8 @@ public enum ProtocolVersion } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(value); } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/PublicMessage.java b/mls/src/main/java/org/bouncycastle/mls/codec/PublicMessage.java index fab00d7f44..cb8ed08ec4 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/PublicMessage.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/PublicMessage.java @@ -1,41 +1,43 @@ package org.bouncycastle.mls.codec; +import java.io.IOException; + import org.bouncycastle.mls.crypto.MlsCipherSuite; import org.bouncycastle.mls.crypto.Secret; import org.bouncycastle.util.Arrays; -import java.io.IOException; - public class PublicMessage - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { FramedContent content; FramedContentAuthData auth; byte[] membership_tag; @SuppressWarnings("unused") - public PublicMessage(MLSInputStream stream) throws IOException + public PublicMessage(MLSInputStream stream) + throws IOException { - content = (FramedContent) stream.read(FramedContent.class); + content = (FramedContent)stream.read(FramedContent.class); auth = new FramedContentAuthData(stream, content.contentType); switch (content.sender.senderType) { - case RESERVED: - case EXTERNAL: - case NEW_MEMBER_PROPOSAL: - case NEW_MEMBER_COMMIT: - break; - case MEMBER: - membership_tag = stream.readOpaque(); - break; + case RESERVED: + case EXTERNAL: + case NEW_MEMBER_PROPOSAL: + case NEW_MEMBER_COMMIT: + break; + case MEMBER: + membership_tag = stream.readOpaque(); + break; } } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(content); stream.write(auth); @@ -43,14 +45,14 @@ public void writeTo(MLSOutputStream stream) throws IOException switch (content.sender.senderType) { - case RESERVED: - case EXTERNAL: - case NEW_MEMBER_PROPOSAL: - case NEW_MEMBER_COMMIT: - break; - case MEMBER: - stream.writeOpaque(membership_tag); - break; + case RESERVED: + case EXTERNAL: + case NEW_MEMBER_PROPOSAL: + case NEW_MEMBER_COMMIT: + break; + case MEMBER: + stream.writeOpaque(membership_tag); + break; } } @@ -61,31 +63,33 @@ public PublicMessage(FramedContent content, FramedContentAuthData auth, byte[] m this.auth = auth; switch (content.sender.senderType) { - case RESERVED: - case NEW_MEMBER_COMMIT: - case EXTERNAL: - case NEW_MEMBER_PROPOSAL: - break; - case MEMBER: - this.membership_tag = membership_tag; - break; + case RESERVED: + case NEW_MEMBER_COMMIT: + case EXTERNAL: + case NEW_MEMBER_PROPOSAL: + break; + case MEMBER: + this.membership_tag = membership_tag; + break; } } static public PublicMessage protect(AuthenticatedContent authContent, MlsCipherSuite suite, - byte[] membershipKeyBytes, byte[] groupContextBytes) throws IOException + byte[] membershipKeyBytes, byte[] groupContextBytes) + throws IOException { PublicMessage pt = new PublicMessage(authContent.content, authContent.auth, null); if (pt.content.sender.senderType == SenderType.MEMBER) { -// System.out.println("groupcontextbytes: " + Hex.toHexString(groupContextBytes)); - GroupContext context = (GroupContext) MLSInputStream.decode(groupContextBytes, GroupContext.class); + GroupContext context = (GroupContext)MLSInputStream.decode(groupContextBytes, GroupContext.class); Secret membershipKey = new Secret(membershipKeyBytes); pt.membership_tag = pt.membershipMac(suite, membershipKey, context); } return pt; } - public AuthenticatedContent unprotect(MlsCipherSuite suite, Secret membership_key, GroupContext context) throws IOException + + public AuthenticatedContent unprotect(MlsCipherSuite suite, Secret membership_key, GroupContext context) + throws Exception { if (content.sender.senderType == SenderType.MEMBER) { @@ -99,13 +103,14 @@ public AuthenticatedContent unprotect(MlsCipherSuite suite, Secret membership_ke return new AuthenticatedContent(WireFormat.mls_public_message, content, auth); } - public byte[] membershipMac(MlsCipherSuite suite, Secret membershipKey, GroupContext context) throws IOException + public byte[] membershipMac(MlsCipherSuite suite, Secret membershipKey, GroupContext context) + throws IOException { // MAC(membership_key, AuthenticatedContentTBM) FramedContentTBS tbs = new FramedContentTBS( - WireFormat.mls_public_message, - content, - context); + WireFormat.mls_public_message, + content, + context); AuthenticatedContentTBM tbm = new AuthenticatedContentTBM(tbs, auth); Secret ikm = new Secret(MLSOutputStream.encode(tbm)); Secret membership_tag = Secret.extract(suite, membershipKey, ikm); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/ResumptionPSKUsage.java b/mls/src/main/java/org/bouncycastle/mls/codec/ResumptionPSKUsage.java index e1ba224515..7b25da3814 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/ResumptionPSKUsage.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/ResumptionPSKUsage.java @@ -2,25 +2,32 @@ import java.io.IOException; -public enum ResumptionPSKUsage implements MLSInputStream.Readable, MLSOutputStream.Writable { - RESERVED((byte) 0), - APPLICATION((byte) 1), - REINIT((byte) 2), - BRANCH((byte) 3); +public enum ResumptionPSKUsage + implements MLSInputStream.Readable, MLSOutputStream.Writable +{ + RESERVED((byte)0), + APPLICATION((byte)1), + REINIT((byte)2), + BRANCH((byte)3); final byte value; - ResumptionPSKUsage(byte value) { + ResumptionPSKUsage(byte value) + { this.value = value; } @SuppressWarnings("unused") - ResumptionPSKUsage(MLSInputStream stream) throws IOException { - this.value = (byte) stream.read(byte.class); + ResumptionPSKUsage(MLSInputStream stream) + throws IOException + { + this.value = (byte)stream.read(byte.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException { + public void writeTo(MLSOutputStream stream) + throws IOException + { stream.write(value); } } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/Sender.java b/mls/src/main/java/org/bouncycastle/mls/codec/Sender.java index e9afc51c3a..05a1e22303 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/Sender.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/Sender.java @@ -1,11 +1,11 @@ package org.bouncycastle.mls.codec; -import org.bouncycastle.mls.TreeKEM.LeafIndex; - import java.io.IOException; +import org.bouncycastle.mls.TreeKEM.LeafIndex; + public class Sender - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { SenderType senderType; LeafIndex sender; @@ -30,14 +30,17 @@ public static Sender forNewMemberCommit() { return new Sender(SenderType.NEW_MEMBER_COMMIT, null, -1); } + public static Sender forNewMemberProposal() { return new Sender(SenderType.NEW_MEMBER_PROPOSAL, null, -1); } + public static Sender forMember(LeafIndex sender) { return new Sender(SenderType.MEMBER, sender, -1); } + public static Sender forExternal(int senderIndex) { return new Sender(SenderType.EXTERNAL, null, senderIndex); @@ -49,40 +52,43 @@ public Sender(SenderType senderType, LeafIndex sender, int sender_index) this.sender = sender; this.sender_index = sender_index; } + @SuppressWarnings("unused") - public Sender(MLSInputStream stream) throws IOException + public Sender(MLSInputStream stream) + throws IOException { - this.senderType = SenderType.values()[(byte) stream.read(byte.class)]; + this.senderType = SenderType.values()[(byte)stream.read(byte.class)]; switch (senderType) { - case MEMBER: - sender = (LeafIndex) stream.read(LeafIndex.class); - break; - case EXTERNAL: - sender_index = (int) stream.read(int.class); - break; - case NEW_MEMBER_PROPOSAL: - case NEW_MEMBER_COMMIT: - break; + case MEMBER: + sender = (LeafIndex)stream.read(LeafIndex.class); + break; + case EXTERNAL: + sender_index = (int)stream.read(int.class); + break; + case NEW_MEMBER_PROPOSAL: + case NEW_MEMBER_COMMIT: + break; } } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(senderType); switch (senderType) { - case MEMBER: - stream.write(sender); - break; - case EXTERNAL: - stream.write(sender_index); - break; - case NEW_MEMBER_PROPOSAL: - case NEW_MEMBER_COMMIT: - break; + case MEMBER: + stream.write(sender); + break; + case EXTERNAL: + stream.write(sender_index); + break; + case NEW_MEMBER_PROPOSAL: + case NEW_MEMBER_COMMIT: + break; } } } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/SenderType.java b/mls/src/main/java/org/bouncycastle/mls/codec/SenderType.java index 2566a91046..45abc2554c 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/SenderType.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/SenderType.java @@ -3,13 +3,13 @@ import java.io.IOException; public enum SenderType - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { - RESERVED((byte) 0), - MEMBER((byte) 1), - EXTERNAL((byte) 2), - NEW_MEMBER_PROPOSAL((byte) 3), - NEW_MEMBER_COMMIT((byte) 4); + RESERVED((byte)0), + MEMBER((byte)1), + EXTERNAL((byte)2), + NEW_MEMBER_PROPOSAL((byte)3), + NEW_MEMBER_COMMIT((byte)4); final byte value; @@ -19,7 +19,8 @@ public enum SenderType } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(value); } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/UpdatePath.java b/mls/src/main/java/org/bouncycastle/mls/codec/UpdatePath.java index 4caccaf4cb..93afc4e115 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/UpdatePath.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/UpdatePath.java @@ -1,13 +1,13 @@ package org.bouncycastle.mls.codec; -import org.bouncycastle.mls.TreeKEM.LeafNode; - import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.bouncycastle.mls.TreeKEM.LeafNode; + public class UpdatePath - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { LeafNode leaf_node; List nodes; @@ -26,22 +26,26 @@ public UpdatePath clone() { return new UpdatePath(leaf_node, nodes); } + public UpdatePath(LeafNode leaf_node, List nodes) { // this.leaf_node = leaf_node; this.leaf_node = leaf_node.copy(leaf_node.getEncryptionKey()); - this.nodes = new ArrayList<>(nodes); + this.nodes = new ArrayList(nodes); } + @SuppressWarnings("unused") - UpdatePath(MLSInputStream stream) throws IOException + UpdatePath(MLSInputStream stream) + throws IOException { - leaf_node = (LeafNode) stream.read(LeafNode.class); - nodes = new ArrayList<>(); + leaf_node = (LeafNode)stream.read(LeafNode.class); + nodes = new ArrayList(); stream.readList(nodes, UpdatePathNode.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(leaf_node); stream.writeList(nodes); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/UpdatePathNode.java b/mls/src/main/java/org/bouncycastle/mls/codec/UpdatePathNode.java index 9bc2a80c9d..dfbbb1c93c 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/UpdatePathNode.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/UpdatePathNode.java @@ -5,7 +5,7 @@ import java.util.List; public class UpdatePathNode - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { byte[] encryption_key; @@ -26,16 +26,19 @@ public UpdatePathNode(byte[] encryption_key, List encrypted_path this.encryption_key = encryption_key; this.encrypted_path_secret = encrypted_path_secret; } + @SuppressWarnings("unused") - UpdatePathNode(MLSInputStream stream) throws IOException + UpdatePathNode(MLSInputStream stream) + throws IOException { encryption_key = stream.readOpaque(); - encrypted_path_secret = new ArrayList<>(); + encrypted_path_secret = new ArrayList(); stream.readList(encrypted_path_secret, HPKECiphertext.class); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(encryption_key); stream.writeList(encrypted_path_secret); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/Varint.java b/mls/src/main/java/org/bouncycastle/mls/codec/Varint.java index f78fdd93fe..43c566a0be 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/Varint.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/Varint.java @@ -2,7 +2,9 @@ import java.io.IOException; -public class Varint implements MLSInputStream.Readable, MLSOutputStream.Writable { +public class Varint + implements MLSInputStream.Readable, MLSOutputStream.Writable +{ static final int HEADER_OFFSET = 6; static final int HEADER_1 = 0x00; static final int HEADER_2 = 0x4000; @@ -13,39 +15,52 @@ public class Varint implements MLSInputStream.Readable, MLSOutputStream.Writable public final int value; - public Varint(int value) { + public Varint(int value) + { this.value = value; } @SuppressWarnings("unused") - public Varint(MLSInputStream stream) throws IOException { + public Varint(MLSInputStream stream) + throws IOException + { int prefix = stream.peek() & 0xff; int logSize = prefix >>> HEADER_OFFSET; int size = 1 << logSize; - switch (size) { - case 1: - value = HEADER_1 ^ (int)(byte) stream.read(byte.class); - break; - case 2: - value = HEADER_2 ^ (int)(short) stream.read(short.class); - break; - case 4: - value = HEADER_4 ^ (int) stream.read(int.class); - break; - default: - throw new IOException("Invalid varint header"); + switch (size) + { + case 1: + value = HEADER_1 ^ (int)(byte)stream.read(byte.class); + break; + case 2: + value = HEADER_2 ^ (int)(short)stream.read(short.class); + break; + case 4: + value = HEADER_4 ^ (int)stream.read(int.class); + break; + default: + throw new IOException("Invalid varint header"); } } @Override - public void writeTo(MLSOutputStream stream) throws IOException { - if (value <= MAX_1) { + public void writeTo(MLSOutputStream stream) + throws IOException + { + if (value <= MAX_1) + { stream.write((byte)(HEADER_1 | value)); - } else if (value <= MAX_2) { + } + else if (value <= MAX_2) + { stream.write((short)(HEADER_2 | value)); - } else if (value <= Varint.MAX_4) { + } + else if (value <= Varint.MAX_4) + { stream.write(HEADER_4 | value); - } else { + } + else + { throw new IOException("Varint is too big to encode"); } } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/Welcome.java b/mls/src/main/java/org/bouncycastle/mls/codec/Welcome.java index 57fbef1bbe..3006bd3a1b 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/Welcome.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/Welcome.java @@ -1,18 +1,18 @@ package org.bouncycastle.mls.codec; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.mls.KeyGeneration; import org.bouncycastle.mls.KeyScheduleEpoch; import org.bouncycastle.mls.crypto.MlsCipherSuite; import org.bouncycastle.mls.crypto.Secret; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - public class Welcome - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { short cipher_suite; @@ -29,13 +29,14 @@ public MlsCipherSuite getSuite() return suite; } - public Welcome(MlsCipherSuite suite, byte[] joinerSecret, List psks, byte[] groupInfo) throws IOException, InvalidCipherTextException + public Welcome(MlsCipherSuite suite, byte[] joinerSecret, List psks, byte[] groupInfo) + throws IOException, InvalidCipherTextException { this.cipher_suite = suite.getSuiteID(); this.suite = suite; this.joinerSecret = new Secret(joinerSecret); // Cache the list of PSK IDs - this.psks = new ArrayList<>(); + this.psks = new ArrayList(); for (KeyScheduleEpoch.PSKWithSecret psk : psks) { this.psks.add(psk.id); @@ -44,22 +45,23 @@ public Welcome(MlsCipherSuite suite, byte[] joinerSecret, List(); + this.secrets = new ArrayList(); } - public int find(KeyPackage kp) throws IOException + public int find(KeyPackage kp) + throws IOException { - byte[] ref = suite.refHash(MLSOutputStream.encode(kp),"MLS 1.0 KeyPackage Reference"); + byte[] ref = suite.refHash(MLSOutputStream.encode(kp), "MLS 1.0 KeyPackage Reference"); for (int i = 0; i < secrets.size(); i++) { - if(Arrays.equals(ref, secrets.get(i).new_member)) + if (Arrays.equals(ref, secrets.get(i).new_member)) { return i; } @@ -67,7 +69,8 @@ public int find(KeyPackage kp) throws IOException return -1; } - public void encrypt(KeyPackage kp, Secret pathSecret) throws IOException, InvalidCipherTextException + public void encrypt(KeyPackage kp, Secret pathSecret) + throws IOException, InvalidCipherTextException { GroupSecrets gs = new GroupSecrets(joinerSecret.value(), null, psks); @@ -79,25 +82,27 @@ public void encrypt(KeyPackage kp, Secret pathSecret) throws IOException, Invali MlsCipherSuite suite = kp.suite; byte[][] ctAndEnc = suite.encryptWithLabel(kp.init_key, "Welcome", encrypted_group_info, gsBytes); secrets.add( - new EncryptedGroupSecrets( - suite.refHash(MLSOutputStream.encode(kp),"MLS 1.0 KeyPackage Reference"), - new HPKECiphertext(ctAndEnc[1], ctAndEnc[0]) - ) + new EncryptedGroupSecrets( + suite.refHash(MLSOutputStream.encode(kp), "MLS 1.0 KeyPackage Reference"), + new HPKECiphertext(ctAndEnc[1], ctAndEnc[0]) + ) ); } - public GroupInfo decrypt(byte[] joinerSecret, List psks) throws IOException, InvalidCipherTextException + public GroupInfo decrypt(byte[] joinerSecret, List psks) + throws IOException, InvalidCipherTextException { KeyGeneration keyAndNonce = getGroupInfoKeyNonce(joinerSecret, psks); byte[] groupInfoData = suite.getAEAD().open( - keyAndNonce.key, - keyAndNonce.nonce, - new byte[0], - encrypted_group_info); - return (GroupInfo) MLSInputStream.decode(groupInfoData, GroupInfo.class); + keyAndNonce.key, + keyAndNonce.nonce, + new byte[0], + encrypted_group_info); + return (GroupInfo)MLSInputStream.decode(groupInfoData, GroupInfo.class); } - private KeyGeneration getGroupInfoKeyNonce(byte[] joinerSecret, List psks) throws IOException + private KeyGeneration getGroupInfoKeyNonce(byte[] joinerSecret, List psks) + throws IOException { Secret welcomeSecret = KeyScheduleEpoch.welcomeSecret(suite, joinerSecret, psks); Secret key = welcomeSecret.expandWithLabel(suite, "key", new byte[0], suite.getAEAD().getKeySize()); @@ -105,25 +110,28 @@ private KeyGeneration getGroupInfoKeyNonce(byte[] joinerSecret, List(); + secrets = new ArrayList(); stream.readList(secrets, EncryptedGroupSecrets.class); encrypted_group_info = stream.readOpaque(); } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(cipher_suite); stream.writeList(secrets); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/WireFormat.java b/mls/src/main/java/org/bouncycastle/mls/codec/WireFormat.java index e2056d8627..0307013edb 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/WireFormat.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/WireFormat.java @@ -3,14 +3,14 @@ import java.io.IOException; public enum WireFormat - implements MLSInputStream.Readable, MLSOutputStream.Writable + implements MLSInputStream.Readable, MLSOutputStream.Writable { - RESERVED((short) 0), - mls_public_message((short) 1), - mls_private_message((short) 2), - mls_welcome((short) 3), - mls_group_info((short) 4), - mls_key_package((short) 5); + RESERVED((short)0), + mls_public_message((short)1), + mls_private_message((short)2), + mls_welcome((short)3), + mls_group_info((short)4), + mls_key_package((short)5); final short value; @@ -20,7 +20,8 @@ public enum WireFormat } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.write(value); } diff --git a/mls/src/main/java/org/bouncycastle/mls/crypto/MlsAead.java b/mls/src/main/java/org/bouncycastle/mls/crypto/MlsAead.java index 3a9faa39a1..f12a3999f3 100644 --- a/mls/src/main/java/org/bouncycastle/mls/crypto/MlsAead.java +++ b/mls/src/main/java/org/bouncycastle/mls/crypto/MlsAead.java @@ -8,7 +8,9 @@ public interface MlsAead int getNonceSize(); - byte[] open(byte[] key, byte[] nonce, byte[] aad, byte[] pt) throws InvalidCipherTextException; + byte[] open(byte[] key, byte[] nonce, byte[] aad, byte[] pt) + throws InvalidCipherTextException; - byte[] seal(byte[] key, byte[] nonce, byte[] aad, byte[] pt) throws InvalidCipherTextException; + byte[] seal(byte[] key, byte[] nonce, byte[] aad, byte[] pt) + throws InvalidCipherTextException; } diff --git a/mls/src/main/java/org/bouncycastle/mls/crypto/MlsCipherSuite.java b/mls/src/main/java/org/bouncycastle/mls/crypto/MlsCipherSuite.java index 6312b51a55..40c7e20983 100644 --- a/mls/src/main/java/org/bouncycastle/mls/crypto/MlsCipherSuite.java +++ b/mls/src/main/java/org/bouncycastle/mls/crypto/MlsCipherSuite.java @@ -1,5 +1,8 @@ package org.bouncycastle.mls.crypto; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Digest; @@ -14,12 +17,11 @@ import org.bouncycastle.mls.crypto.bc.BcMlsKdf; import org.bouncycastle.mls.crypto.bc.BcMlsSigner; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - public class MlsCipherSuite { - public static class GenericContent implements MLSOutputStream.Writable { + public static class GenericContent + implements MLSOutputStream.Writable + { private byte[] label; private byte[] content; @@ -31,14 +33,17 @@ public GenericContent(String label, byte[] content) } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(label); stream.writeOpaque(content); } } - public static class RefHash implements MLSOutputStream.Writable { + public static class RefHash + implements MLSOutputStream.Writable + { public byte[] label; public byte[] value; @@ -50,7 +55,8 @@ public RefHash(byte[] label, byte[] value) } @Override - public void writeTo(MLSOutputStream stream) throws IOException + public void writeTo(MLSOutputStream stream) + throws IOException { stream.writeOpaque(label); stream.writeOpaque(value); @@ -66,22 +72,22 @@ public void writeTo(MLSOutputStream stream) throws IOException public static final short MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448 = 0x0006; public static final short MLS_256_DHKEMP384_AES256GCM_SHA384_P384 = 0x0007; - public static final MlsCipherSuite BCMLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 = new MlsCipherSuite(MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519, new BcMlsSigner(MlsSigner.ed25519), new BcMlsKdf(new SHA256Digest()), new BcMlsAead(HPKE.aead_AES_GCM128), new HPKE(HPKE.mode_base, HPKE.kem_X25519_SHA256, HPKE.kdf_HKDF_SHA256, HPKE.aead_AES_GCM128)); - public static final MlsCipherSuite BCMLS_128_DHKEMP256_AES128GCM_SHA256_P256 = new MlsCipherSuite(MLS_128_DHKEMP256_AES128GCM_SHA256_P256, new BcMlsSigner(MlsSigner.ecdsa_secp256r1_sha256), new BcMlsKdf(new SHA256Digest()), new BcMlsAead(HPKE.aead_AES_GCM128), new HPKE(HPKE.mode_base, HPKE.kem_P256_SHA256, HPKE.kdf_HKDF_SHA256, HPKE.aead_AES_GCM128)); + public static final MlsCipherSuite BCMLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 = new MlsCipherSuite(MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519, new BcMlsSigner(MlsSigner.ed25519), new BcMlsKdf(new SHA256Digest()), new BcMlsAead(HPKE.aead_AES_GCM128), new HPKE(HPKE.mode_base, HPKE.kem_X25519_SHA256, HPKE.kdf_HKDF_SHA256, HPKE.aead_AES_GCM128)); + public static final MlsCipherSuite BCMLS_128_DHKEMP256_AES128GCM_SHA256_P256 = new MlsCipherSuite(MLS_128_DHKEMP256_AES128GCM_SHA256_P256, new BcMlsSigner(MlsSigner.ecdsa_secp256r1_sha256), new BcMlsKdf(new SHA256Digest()), new BcMlsAead(HPKE.aead_AES_GCM128), new HPKE(HPKE.mode_base, HPKE.kem_P256_SHA256, HPKE.kdf_HKDF_SHA256, HPKE.aead_AES_GCM128)); public static final MlsCipherSuite BCMLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519 = new MlsCipherSuite(MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519, new BcMlsSigner(MlsSigner.ed25519), new BcMlsKdf(new SHA256Digest()), new BcMlsAead(HPKE.aead_CHACHA20_POLY1305), new HPKE(HPKE.mode_base, HPKE.kem_X25519_SHA256, HPKE.kdf_HKDF_SHA256, HPKE.aead_CHACHA20_POLY1305)); - public static final MlsCipherSuite BCMLS_256_DHKEMX448_AES256GCM_SHA512_Ed448 = new MlsCipherSuite(MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448, new BcMlsSigner(MlsSigner.ed448), new BcMlsKdf(new SHA512Digest()), new BcMlsAead(HPKE.aead_AES_GCM256), new HPKE(HPKE.mode_base, HPKE.kem_X448_SHA512, HPKE.kdf_HKDF_SHA512, HPKE.aead_AES_GCM256)); - public static final MlsCipherSuite BCMLS_256_DHKEMP521_AES256GCM_SHA512_P521 = new MlsCipherSuite(MLS_256_DHKEMP521_AES256GCM_SHA512_P521, new BcMlsSigner(MlsSigner.ecdsa_secp521r1_sha512), new BcMlsKdf(new SHA512Digest()), new BcMlsAead(HPKE.aead_AES_GCM256), new HPKE(HPKE.mode_base, HPKE.kem_P521_SHA512, HPKE.kdf_HKDF_SHA512, HPKE.aead_AES_GCM256)); - public static final MlsCipherSuite BCMLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448 = new MlsCipherSuite(MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448, new BcMlsSigner(MlsSigner.ed448), new BcMlsKdf(new SHA512Digest()), new BcMlsAead(HPKE.aead_CHACHA20_POLY1305), new HPKE(HPKE.mode_base, HPKE.kem_X448_SHA512, HPKE.kdf_HKDF_SHA512, HPKE.aead_CHACHA20_POLY1305)); - public static final MlsCipherSuite BCMLS_256_DHKEMP384_AES256GCM_SHA384_P384 = new MlsCipherSuite(MLS_256_DHKEMP384_AES256GCM_SHA384_P384, new BcMlsSigner(MlsSigner.ecdsa_secp384r1_sha384), new BcMlsKdf(new SHA384Digest()), new BcMlsAead(HPKE.aead_AES_GCM256), new HPKE(HPKE.mode_base, HPKE.kem_P384_SHA348, HPKE.kdf_HKDF_SHA384, HPKE.aead_AES_GCM256)); + public static final MlsCipherSuite BCMLS_256_DHKEMX448_AES256GCM_SHA512_Ed448 = new MlsCipherSuite(MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448, new BcMlsSigner(MlsSigner.ed448), new BcMlsKdf(new SHA512Digest()), new BcMlsAead(HPKE.aead_AES_GCM256), new HPKE(HPKE.mode_base, HPKE.kem_X448_SHA512, HPKE.kdf_HKDF_SHA512, HPKE.aead_AES_GCM256)); + public static final MlsCipherSuite BCMLS_256_DHKEMP521_AES256GCM_SHA512_P521 = new MlsCipherSuite(MLS_256_DHKEMP521_AES256GCM_SHA512_P521, new BcMlsSigner(MlsSigner.ecdsa_secp521r1_sha512), new BcMlsKdf(new SHA512Digest()), new BcMlsAead(HPKE.aead_AES_GCM256), new HPKE(HPKE.mode_base, HPKE.kem_P521_SHA512, HPKE.kdf_HKDF_SHA512, HPKE.aead_AES_GCM256)); + public static final MlsCipherSuite BCMLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448 = new MlsCipherSuite(MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448, new BcMlsSigner(MlsSigner.ed448), new BcMlsKdf(new SHA512Digest()), new BcMlsAead(HPKE.aead_CHACHA20_POLY1305), new HPKE(HPKE.mode_base, HPKE.kem_X448_SHA512, HPKE.kdf_HKDF_SHA512, HPKE.aead_CHACHA20_POLY1305)); + public static final MlsCipherSuite BCMLS_256_DHKEMP384_AES256GCM_SHA384_P384 = new MlsCipherSuite(MLS_256_DHKEMP384_AES256GCM_SHA384_P384, new BcMlsSigner(MlsSigner.ecdsa_secp384r1_sha384), new BcMlsKdf(new SHA384Digest()), new BcMlsAead(HPKE.aead_AES_GCM256), new HPKE(HPKE.mode_base, HPKE.kem_P384_SHA348, HPKE.kdf_HKDF_SHA384, HPKE.aead_AES_GCM256)); public static final short[] ALL_SUPPORTED_SUITES = { - MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519, - MLS_128_DHKEMP256_AES128GCM_SHA256_P256, - MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519, - MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448, - MLS_256_DHKEMP521_AES256GCM_SHA512_P521, - MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448, - MLS_256_DHKEMP384_AES256GCM_SHA384_P384 + MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519, + MLS_128_DHKEMP256_AES128GCM_SHA256_P256, + MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519, + MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448, + MLS_256_DHKEMP521_AES256GCM_SHA512_P521, + MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448, + MLS_256_DHKEMP384_AES256GCM_SHA384_P384 }; private final short suiteID; @@ -101,26 +107,27 @@ public MlsCipherSuite(short id, MlsSigner signer, MlsKdf kdf, MlsAead aead, HPKE this.hpke = hpke; } - static public MlsCipherSuite getSuite(short id) throws Exception + static public MlsCipherSuite getSuite(short id) + throws Exception { switch (id) { - case MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519: - return BCMLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; - case MLS_128_DHKEMP256_AES128GCM_SHA256_P256: - return BCMLS_128_DHKEMP256_AES128GCM_SHA256_P256; - case MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519: - return BCMLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519; - case MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448: - return BCMLS_256_DHKEMX448_AES256GCM_SHA512_Ed448; - case MLS_256_DHKEMP521_AES256GCM_SHA512_P521: - return BCMLS_256_DHKEMP521_AES256GCM_SHA512_P521; - case MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448: - return BCMLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448; - case MLS_256_DHKEMP384_AES256GCM_SHA384_P384: - return BCMLS_256_DHKEMP384_AES256GCM_SHA384_P384; - default: - throw new Exception("Unkown ciphersuite id"); + case MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519: + return BCMLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + case MLS_128_DHKEMP256_AES128GCM_SHA256_P256: + return BCMLS_128_DHKEMP256_AES128GCM_SHA256_P256; + case MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519: + return BCMLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519; + case MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448: + return BCMLS_256_DHKEMX448_AES256GCM_SHA512_Ed448; + case MLS_256_DHKEMP521_AES256GCM_SHA512_P521: + return BCMLS_256_DHKEMP521_AES256GCM_SHA512_P521; + case MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448: + return BCMLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448; + case MLS_256_DHKEMP384_AES256GCM_SHA384_P384: + return BCMLS_256_DHKEMP384_AES256GCM_SHA384_P384; + default: + throw new Exception("Unkown ciphersuite id"); } } @@ -136,7 +143,7 @@ public AsymmetricCipherKeyPair generateSignatureKeyPair() public byte[] serializeSignaturePublicKey(AsymmetricKeyParameter key) { - return signer.serializePublicKey(key); + return signer.serializePublicKey(key); } public byte[] serializeSignaturePrivateKey(AsymmetricKeyParameter key) @@ -149,17 +156,20 @@ public AsymmetricCipherKeyPair deserializeSignaturePrivateKey(byte[] priv) return signer.deserializePrivateKey(priv); } - public byte[] signWithLabel(byte[] priv, String label, byte[] content) throws IOException, CryptoException + public byte[] signWithLabel(byte[] priv, String label, byte[] content) + throws IOException, CryptoException { return signer.signWithLabel(priv, label, content); } - public boolean verifyWithLabel(byte[] pub, String label, byte[] content, byte[] signature) throws IOException + public boolean verifyWithLabel(byte[] pub, String label, byte[] content, byte[] signature) + throws IOException { return signer.verifyWithLabel(pub, label, content, signature); } - public byte[] refHash(byte[] value, String label) throws IOException + public byte[] refHash(byte[] value, String label) + throws IOException { RefHash refhash = new MlsCipherSuite.RefHash(label.getBytes(StandardCharsets.UTF_8), value); byte[] refhashBytes = MLSOutputStream.encode(refhash); @@ -169,7 +179,9 @@ public byte[] refHash(byte[] value, String label) throws IOException digest.doFinal(out, 0); return out; } - public byte[] hash(byte[] value) throws IOException + + public byte[] hash(byte[] value) + throws IOException { byte[] out = new byte[kdf.getHashLength()]; digest.update(value, 0, value.length); @@ -177,7 +189,8 @@ public byte[] hash(byte[] value) throws IOException return out; } - public byte[] decryptWithLabel(byte[] priv, String label, byte[] context, byte[] kem_output, byte[] ciphertext) throws IOException, InvalidCipherTextException + public byte[] decryptWithLabel(byte[] priv, String label, byte[] context, byte[] kem_output, byte[] ciphertext) + throws IOException, InvalidCipherTextException { GenericContent encryptContext = new GenericContent(label, context); byte[] encryptContextBytes = MLSOutputStream.encode(encryptContext); @@ -186,7 +199,8 @@ public byte[] decryptWithLabel(byte[] priv, String label, byte[] context, byte[] return hpke.open(kem_output, kp, encryptContextBytes, "".getBytes(), ciphertext, null, null, null); } - public byte[][] encryptWithLabel(byte[] pub, String label, byte[] context, byte[] plaintext) throws IOException, InvalidCipherTextException + public byte[][] encryptWithLabel(byte[] pub, String label, byte[] context, byte[] plaintext) + throws IOException, InvalidCipherTextException { GenericContent encryptContext = new GenericContent(label, context); byte[] encryptContextBytes = MLSOutputStream.encode(encryptContext); @@ -205,6 +219,7 @@ public MlsKdf getKDF() { return kdf; } + public MlsAead getAEAD() { return aead; diff --git a/mls/src/main/java/org/bouncycastle/mls/crypto/MlsKdf.java b/mls/src/main/java/org/bouncycastle/mls/crypto/MlsKdf.java index 16c8087f12..da0f40e9f5 100644 --- a/mls/src/main/java/org/bouncycastle/mls/crypto/MlsKdf.java +++ b/mls/src/main/java/org/bouncycastle/mls/crypto/MlsKdf.java @@ -1,9 +1,9 @@ package org.bouncycastle.mls.crypto; -import org.bouncycastle.crypto.Digest; - import java.io.IOException; +import org.bouncycastle.crypto.Digest; + public interface MlsKdf { int getHashLength(); @@ -14,6 +14,7 @@ public interface MlsKdf byte[] expand(byte[] prk, byte[] info, int length); - byte[] expandWithLabel(byte[] secret, String label, byte[] context, int length) throws IOException; + byte[] expandWithLabel(byte[] secret, String label, byte[] context, int length) + throws IOException; } diff --git a/mls/src/main/java/org/bouncycastle/mls/crypto/MlsSigner.java b/mls/src/main/java/org/bouncycastle/mls/crypto/MlsSigner.java index 978e86762f..3bcf23b398 100644 --- a/mls/src/main/java/org/bouncycastle/mls/crypto/MlsSigner.java +++ b/mls/src/main/java/org/bouncycastle/mls/crypto/MlsSigner.java @@ -1,11 +1,11 @@ package org.bouncycastle.mls.crypto; +import java.io.IOException; + import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import java.io.IOException; - public interface MlsSigner { int ecdsa_secp256r1_sha256 = 3; @@ -15,10 +15,17 @@ public interface MlsSigner int ed448 = 8; AsymmetricCipherKeyPair generateSignatureKeyPair(); + byte[] serializePublicKey(AsymmetricKeyParameter key); + byte[] serializePrivateKey(AsymmetricKeyParameter key); - byte[] signWithLabel(byte[] priv, String label, byte[] content) throws IOException, CryptoException; - boolean verifyWithLabel(byte[] pub, String label, byte[] content, byte[] signature) throws IOException; + + byte[] signWithLabel(byte[] priv, String label, byte[] content) + throws IOException, CryptoException; + + boolean verifyWithLabel(byte[] pub, String label, byte[] content, byte[] signature) + throws IOException; + AsymmetricCipherKeyPair deserializePrivateKey(byte[] priv); AsymmetricKeyParameter deserializePublicKey(byte[] pub); diff --git a/mls/src/main/java/org/bouncycastle/mls/crypto/Secret.java b/mls/src/main/java/org/bouncycastle/mls/crypto/Secret.java index 7d3f68758b..a8dc5274fd 100644 --- a/mls/src/main/java/org/bouncycastle/mls/crypto/Secret.java +++ b/mls/src/main/java/org/bouncycastle/mls/crypto/Secret.java @@ -1,34 +1,45 @@ package org.bouncycastle.mls.crypto; -import org.bouncycastle.mls.codec.MLSOutputStream; - import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Arrays; -public class Secret { +import org.bouncycastle.mls.codec.MLSOutputStream; + +public class Secret +{ byte[] value; Secret[] parents; - public Secret(byte[] value) { + public Secret(byte[] value) + { this.value = value; this.parents = null; } - private Secret(byte[] value, Secret[] parents) { + private Secret(byte[] value, Secret[] parents) + { this.value = value; this.parents = parents; } - public static Secret zero(MlsCipherSuite suite) { + public static Secret zero(MlsCipherSuite suite) + { return new Secret(new byte[suite.getKDF().getHashLength()]); } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Secret secret = (Secret) o; + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + Secret secret = (Secret)o; return Arrays.equals(value, secret.value) && Arrays.equals(parents, secret.parents); } @@ -38,74 +49,93 @@ public int hashCode() return Arrays.hashCode(value); } - public final byte[] value() { + public final byte[] value() + { return value; } - public boolean isConsumed() { + public boolean isConsumed() + { return value == null && parents == null; } - public void consume() { - if (isConsumed()) { + public void consume() + { + if (isConsumed()) + { return; } // Zeroize this secret - Arrays.fill(value, (byte) 0); + Arrays.fill(value, (byte)0); value = null; // Consume any linked parents - if (parents != null) { - for (Secret parent : parents) { + if (parents != null) + { + for (Secret parent : parents) + { parent.consume(); } parents = null; } } - public static Secret extract(MlsCipherSuite suite, Secret salt, Secret ikm) { + public static Secret extract(MlsCipherSuite suite, Secret salt, Secret ikm) + { byte[] prk = suite.getKDF().extract(salt.value(), ikm.value()); - return new Secret(prk, new Secret[] {salt, ikm}); + return new Secret(prk, new Secret[]{salt, ikm}); } - public Secret expand(MlsCipherSuite suite, String label, int length) { + public Secret expand(MlsCipherSuite suite, String label, int length) + { byte[] labelData = label.getBytes(StandardCharsets.UTF_8); byte[] derivedSecret = suite.getKDF().expand(value, labelData, length); - return new Secret(derivedSecret, new Secret[] {this}); + return new Secret(derivedSecret, new Secret[]{this}); } - public static class KDFLabel implements MLSOutputStream.Writable { + public static class KDFLabel + implements MLSOutputStream.Writable + { public short length; public byte[] label; public byte[] context; - KDFLabel(short length, String label, byte[] context) { + KDFLabel(short length, String label, byte[] context) + { this.length = length; this.label = ("MLS 1.0 " + label).getBytes(StandardCharsets.UTF_8); this.context = context; } @Override - public void writeTo(MLSOutputStream stream) throws IOException { + public void writeTo(MLSOutputStream stream) + throws IOException + { stream.write(length); stream.writeOpaque(label); stream.writeOpaque(context); } } - public Secret expandWithLabel(MlsCipherSuite suite, String label, byte[] context, int length) throws IOException { - KDFLabel kdfLabelStr = new KDFLabel((short) length, label, context); + public Secret expandWithLabel(MlsCipherSuite suite, String label, byte[] context, int length) + throws IOException + { + KDFLabel kdfLabelStr = new KDFLabel((short)length, label, context); byte[] kdfLabel = MLSOutputStream.encode(kdfLabelStr); byte[] derivedSecret = suite.getKDF().expand(value, kdfLabel, length); - return new Secret(derivedSecret, new Secret[] {this}); + return new Secret(derivedSecret, new Secret[]{this}); } - public Secret deriveSecret(MlsCipherSuite suite, String label) throws IOException { - return expandWithLabel(suite, label, new byte[] {}, suite.getKDF().getHashLength()); + public Secret deriveSecret(MlsCipherSuite suite, String label) + throws IOException + { + return expandWithLabel(suite, label, new byte[]{}, suite.getKDF().getHashLength()); } - public Secret deriveTreeSecret(MlsCipherSuite suite, String label, int generation, int length) throws IOException { + public Secret deriveTreeSecret(MlsCipherSuite suite, String label, int generation, int length) + throws IOException + { return expandWithLabel(suite, label, MLSOutputStream.encode(generation), length); } } diff --git a/mls/src/main/java/org/bouncycastle/mls/crypto/bc/BcMlsAead.java b/mls/src/main/java/org/bouncycastle/mls/crypto/bc/BcMlsAead.java index 5d01afdfdd..39fdddd6b2 100644 --- a/mls/src/main/java/org/bouncycastle/mls/crypto/bc/BcMlsAead.java +++ b/mls/src/main/java/org/bouncycastle/mls/crypto/bc/BcMlsAead.java @@ -23,37 +23,39 @@ public BcMlsAead(short aeadId) switch (aeadId) { - case HPKE.aead_AES_GCM128: - case HPKE.aead_AES_GCM256: - cipher = new GCMBlockCipher(new AESEngine()); - break; - case HPKE.aead_CHACHA20_POLY1305: - cipher = new ChaCha20Poly1305(); - break; - case HPKE.aead_EXPORT_ONLY: - break; + case HPKE.aead_AES_GCM128: + case HPKE.aead_AES_GCM256: + cipher = new GCMBlockCipher(new AESEngine()); + break; + case HPKE.aead_CHACHA20_POLY1305: + cipher = new ChaCha20Poly1305(); + break; + case HPKE.aead_EXPORT_ONLY: + break; } } + public int getKeySize() { switch (aeadId) { - case HPKE.aead_AES_GCM128: - return 16; - case HPKE.aead_AES_GCM256: - case HPKE.aead_CHACHA20_POLY1305: - return 32; + case HPKE.aead_AES_GCM128: + return 16; + case HPKE.aead_AES_GCM256: + case HPKE.aead_CHACHA20_POLY1305: + return 32; } return -1; } + private int getTagSize() { switch (aeadId) { - case HPKE.aead_AES_GCM128: - case HPKE.aead_AES_GCM256: - case HPKE.aead_CHACHA20_POLY1305: - return 16; + case HPKE.aead_AES_GCM128: + case HPKE.aead_AES_GCM256: + case HPKE.aead_CHACHA20_POLY1305: + return 16; } return -1; } @@ -62,19 +64,20 @@ public int getNonceSize() { switch (aeadId) { - case HPKE.aead_AES_GCM128: - case HPKE.aead_AES_GCM256: - case HPKE.aead_CHACHA20_POLY1305: - return 12; + case HPKE.aead_AES_GCM128: + case HPKE.aead_AES_GCM256: + case HPKE.aead_CHACHA20_POLY1305: + return 12; } return -1; } - public byte[] open(byte[] key, byte[] nonce, byte[] aad, byte[] ct) throws InvalidCipherTextException + public byte[] open(byte[] key, byte[] nonce, byte[] aad, byte[] ct) + throws InvalidCipherTextException { CipherParameters params = new ParametersWithIV(new KeyParameter(key), nonce); cipher.init(false, params); - if(aad != null) + if (aad != null) { cipher.processAADBytes(aad, 0, aad.length); } @@ -85,7 +88,9 @@ public byte[] open(byte[] key, byte[] nonce, byte[] aad, byte[] ct) throws Inval len += cipher.doFinal(pt, len); return pt; } - public byte[] seal(byte[] key, byte[] nonce, byte[] aad, byte[] pt) throws InvalidCipherTextException + + public byte[] seal(byte[] key, byte[] nonce, byte[] aad, byte[] pt) + throws InvalidCipherTextException { CipherParameters params = new ParametersWithIV(new KeyParameter(key), nonce); cipher.init(true, params); diff --git a/mls/src/main/java/org/bouncycastle/mls/crypto/bc/BcMlsKdf.java b/mls/src/main/java/org/bouncycastle/mls/crypto/bc/BcMlsKdf.java index 81079af274..d133e18951 100644 --- a/mls/src/main/java/org/bouncycastle/mls/crypto/bc/BcMlsKdf.java +++ b/mls/src/main/java/org/bouncycastle/mls/crypto/bc/BcMlsKdf.java @@ -1,20 +1,21 @@ package org.bouncycastle.mls.crypto.bc; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.generators.HKDFBytesGenerator; import org.bouncycastle.crypto.params.HKDFParameters; import org.bouncycastle.mls.codec.MLSOutputStream; import org.bouncycastle.mls.crypto.MlsKdf; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - public class BcMlsKdf implements MlsKdf { private final HKDFBytesGenerator kdf; - public BcMlsKdf(Digest digest) { + public BcMlsKdf(Digest digest) + { kdf = new HKDFBytesGenerator(digest); } @@ -31,25 +32,29 @@ public int getHashLength() } @Override - public byte[] extract(byte[] salt, byte[] ikm) { + public byte[] extract(byte[] salt, byte[] ikm) + { byte[] out = kdf.extractPRK(salt, ikm); kdf.getDigest().reset(); return out; } @Override - public byte[] expand(byte[] prk, byte[] info, int length) { + public byte[] expand(byte[] prk, byte[] info, int length) + { byte[] okm = new byte[length]; kdf.init(HKDFParameters.skipExtractParameters(prk, info)); kdf.generateBytes(okm, 0, okm.length); kdf.getDigest().reset(); return okm; } + @Override - public byte[] expandWithLabel(byte[] secret, String label, byte[] context, int length) throws IOException + public byte[] expandWithLabel(byte[] secret, String label, byte[] context, int length) + throws IOException { MLSOutputStream stream = new MLSOutputStream(); - stream.write((short) length); + stream.write((short)length); stream.writeOpaque(("MLS 1.0 " + label).getBytes(StandardCharsets.UTF_8)); stream.writeOpaque(context); byte[] kdfLabel = stream.toByteArray(); diff --git a/mls/src/main/java/org/bouncycastle/mls/crypto/bc/BcMlsSigner.java b/mls/src/main/java/org/bouncycastle/mls/crypto/bc/BcMlsSigner.java index a40cd3b449..64a91b4683 100644 --- a/mls/src/main/java/org/bouncycastle/mls/crypto/bc/BcMlsSigner.java +++ b/mls/src/main/java/org/bouncycastle/mls/crypto/bc/BcMlsSigner.java @@ -1,5 +1,9 @@ package org.bouncycastle.mls.crypto.bc; +import java.io.IOException; +import java.math.BigInteger; +import java.security.SecureRandom; + import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Signer; @@ -37,10 +41,6 @@ import org.bouncycastle.mls.crypto.MlsSigner; import org.bouncycastle.util.encoders.Hex; -import java.io.IOException; -import java.math.BigInteger; -import java.security.SecureRandom; - public class BcMlsSigner implements MlsSigner { @@ -55,54 +55,54 @@ public BcMlsSigner(int sigID) ECCurve curve; switch (sigID) { - case ecdsa_secp256r1_sha256: - signer = new DSADigestSigner(new ECDSASigner(), new SHA256Digest()); - curve = new SecP256R1Curve(); - domainParams = new ECDomainParameters( - curve, - curve.createPoint( - new BigInteger(1, Hex.decode("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296")), - new BigInteger(1, Hex.decode("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5")) - ), - curve.getOrder(), - curve.getCofactor(), - Hex.decode("c49d360886e704936a6678e1139d26b7819f7e90") - ); - break; - case ecdsa_secp521r1_sha512: - signer = new DSADigestSigner(new ECDSASigner(), new SHA512Digest()); - curve = new SecP521R1Curve(); - domainParams = new ECDomainParameters( - curve, - curve.createPoint( - new BigInteger("c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", 16), - new BigInteger("11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 16) - ), - curve.getOrder(), - curve.getCofactor(), - Hex.decode("d09e8800291cb85396cc6717393284aaa0da64ba") - ); - break; - case ecdsa_secp384r1_sha384: - signer = new DSADigestSigner(new ECDSASigner(), new SHA384Digest()); - curve = new SecP384R1Curve(); - domainParams = new ECDomainParameters( - curve, - curve.createPoint( - new BigInteger(1, Hex.decode("aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7")), - new BigInteger(1, Hex.decode("3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f")) - ), - curve.getOrder(), - curve.getCofactor(), - Hex.decode("a335926aa319a27a1d00896a6773a4827acdac73") - ); - break; - case ed25519: - signer = new Ed25519Signer(); - break; - case ed448: - signer = new Ed448Signer(new byte[0]); - break; + case ecdsa_secp256r1_sha256: + signer = new DSADigestSigner(new ECDSASigner(), new SHA256Digest()); + curve = new SecP256R1Curve(); + domainParams = new ECDomainParameters( + curve, + curve.createPoint( + new BigInteger(1, Hex.decode("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296")), + new BigInteger(1, Hex.decode("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5")) + ), + curve.getOrder(), + curve.getCofactor(), + Hex.decode("c49d360886e704936a6678e1139d26b7819f7e90") + ); + break; + case ecdsa_secp521r1_sha512: + signer = new DSADigestSigner(new ECDSASigner(), new SHA512Digest()); + curve = new SecP521R1Curve(); + domainParams = new ECDomainParameters( + curve, + curve.createPoint( + new BigInteger("c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", 16), + new BigInteger("11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 16) + ), + curve.getOrder(), + curve.getCofactor(), + Hex.decode("d09e8800291cb85396cc6717393284aaa0da64ba") + ); + break; + case ecdsa_secp384r1_sha384: + signer = new DSADigestSigner(new ECDSASigner(), new SHA384Digest()); + curve = new SecP384R1Curve(); + domainParams = new ECDomainParameters( + curve, + curve.createPoint( + new BigInteger(1, Hex.decode("aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7")), + new BigInteger(1, Hex.decode("3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f")) + ), + curve.getOrder(), + curve.getCofactor(), + Hex.decode("a335926aa319a27a1d00896a6773a4827acdac73") + ); + break; + case ed25519: + signer = new Ed25519Signer(); + break; + case ed448: + signer = new Ed448Signer(new byte[0]); + break; } } @@ -111,26 +111,26 @@ public AsymmetricCipherKeyPair generateSignatureKeyPair() SecureRandom random = new SecureRandom(); switch (sigID) { - case ecdsa_secp256r1_sha256: - case ecdsa_secp521r1_sha512: - case ecdsa_secp384r1_sha384: - ECKeyPairGenerator pGen = new ECKeyPairGenerator(); - ECKeyGenerationParameters genParam = new ECKeyGenerationParameters( - domainParams, - random); - pGen.init(genParam); - return pGen.generateKeyPair(); - case ed448: - Ed448KeyPairGenerator kpg448 = new Ed448KeyPairGenerator(); - kpg448.init(new Ed448KeyGenerationParameters(random)); - return kpg448.generateKeyPair(); + case ecdsa_secp256r1_sha256: + case ecdsa_secp521r1_sha512: + case ecdsa_secp384r1_sha384: + ECKeyPairGenerator pGen = new ECKeyPairGenerator(); + ECKeyGenerationParameters genParam = new ECKeyGenerationParameters( + domainParams, + random); + pGen.init(genParam); + return pGen.generateKeyPair(); + case ed448: + Ed448KeyPairGenerator kpg448 = new Ed448KeyPairGenerator(); + kpg448.init(new Ed448KeyGenerationParameters(random)); + return kpg448.generateKeyPair(); - case ed25519: - Ed25519KeyPairGenerator kpg25519 = new Ed25519KeyPairGenerator(); - kpg25519.init(new Ed25519KeyGenerationParameters(random)); - return kpg25519.generateKeyPair(); - default: - throw new IllegalStateException("invalid sig algorithm"); + case ed25519: + Ed25519KeyPairGenerator kpg25519 = new Ed25519KeyPairGenerator(); + kpg25519.init(new Ed25519KeyGenerationParameters(random)); + return kpg25519.generateKeyPair(); + default: + throw new IllegalStateException("invalid sig algorithm"); } } @@ -138,16 +138,16 @@ public byte[] serializePublicKey(AsymmetricKeyParameter key) { switch (sigID) { - case ecdsa_secp256r1_sha256: - case ecdsa_secp521r1_sha512: - case ecdsa_secp384r1_sha384: - return ((ECPublicKeyParameters)key).getQ().getEncoded(false); - case ed448: - return ((Ed448PublicKeyParameters)key).getEncoded(); - case ed25519: - return ((Ed25519PublicKeyParameters)key).getEncoded(); - default: - throw new IllegalStateException("invalid sig algorithm"); + case ecdsa_secp256r1_sha256: + case ecdsa_secp521r1_sha512: + case ecdsa_secp384r1_sha384: + return ((ECPublicKeyParameters)key).getQ().getEncoded(false); + case ed448: + return ((Ed448PublicKeyParameters)key).getEncoded(); + case ed25519: + return ((Ed25519PublicKeyParameters)key).getEncoded(); + default: + throw new IllegalStateException("invalid sig algorithm"); } } @@ -156,16 +156,16 @@ public byte[] serializePrivateKey(AsymmetricKeyParameter key) switch (sigID) { - case ecdsa_secp256r1_sha256: - case ecdsa_secp521r1_sha512: - case ecdsa_secp384r1_sha384: - return ((ECPrivateKeyParameters)key).getD().toByteArray(); - case ed448: - return ((Ed448PrivateKeyParameters)key).getEncoded(); - case ed25519: - return ((Ed25519PrivateKeyParameters)key).getEncoded(); - default: - throw new IllegalStateException("invalid sig algorithm"); + case ecdsa_secp256r1_sha256: + case ecdsa_secp521r1_sha512: + case ecdsa_secp384r1_sha384: + return ((ECPrivateKeyParameters)key).getD().toByteArray(); + case ed448: + return ((Ed448PrivateKeyParameters)key).getEncoded(); + case ed25519: + return ((Ed25519PrivateKeyParameters)key).getEncoded(); + default: + throw new IllegalStateException("invalid sig algorithm"); } } @@ -173,83 +173,87 @@ public AsymmetricKeyParameter deserializePublicKey(byte[] pub) { switch (sigID) { - case ecdsa_secp256r1_sha256: - case ecdsa_secp521r1_sha512: - case ecdsa_secp384r1_sha384: - ECPoint G = domainParams.getCurve().decodePoint(pub); - return new ECPublicKeyParameters(G, domainParams); - case ed25519: - return new X25519PublicKeyParameters(pub); - case ed448: - return new X448PublicKeyParameters(pub); - default: - throw new IllegalStateException("Unknown mode"); + case ecdsa_secp256r1_sha256: + case ecdsa_secp521r1_sha512: + case ecdsa_secp384r1_sha384: + ECPoint G = domainParams.getCurve().decodePoint(pub); + return new ECPublicKeyParameters(G, domainParams); + case ed25519: + return new X25519PublicKeyParameters(pub); + case ed448: + return new X448PublicKeyParameters(pub); + default: + throw new IllegalStateException("Unknown mode"); } } + public AsymmetricCipherKeyPair deserializePrivateKey(byte[] priv) { switch (sigID) { - case ecdsa_secp256r1_sha256: - case ecdsa_secp521r1_sha512: - case ecdsa_secp384r1_sha384: - BigInteger d = new BigInteger(1, priv); - ECPrivateKeyParameters ec = new ECPrivateKeyParameters(d, domainParams); + case ecdsa_secp256r1_sha256: + case ecdsa_secp521r1_sha512: + case ecdsa_secp384r1_sha384: + BigInteger d = new BigInteger(1, priv); + ECPrivateKeyParameters ec = new ECPrivateKeyParameters(d, domainParams); - ECPoint Q = new FixedPointCombMultiplier().multiply(domainParams.getG(), ec.getD()); - return new AsymmetricCipherKeyPair(new ECPublicKeyParameters(Q, domainParams), ec); - case ed25519: - Ed25519PrivateKeyParameters ed25519 = new Ed25519PrivateKeyParameters(priv); - return new AsymmetricCipherKeyPair(ed25519.generatePublicKey(), ed25519); - case ed448: - Ed448PrivateKeyParameters ed448 = new Ed448PrivateKeyParameters(priv); - return new AsymmetricCipherKeyPair(ed448.generatePublicKey(), ed448); - default: - throw new IllegalStateException("invalid sig algorithm"); + ECPoint Q = new FixedPointCombMultiplier().multiply(domainParams.getG(), ec.getD()); + return new AsymmetricCipherKeyPair(new ECPublicKeyParameters(Q, domainParams), ec); + case ed25519: + Ed25519PrivateKeyParameters ed25519 = new Ed25519PrivateKeyParameters(priv); + return new AsymmetricCipherKeyPair(ed25519.generatePublicKey(), ed25519); + case ed448: + Ed448PrivateKeyParameters ed448 = new Ed448PrivateKeyParameters(priv); + return new AsymmetricCipherKeyPair(ed448.generatePublicKey(), ed448); + default: + throw new IllegalStateException("invalid sig algorithm"); } } - public byte[] signWithLabel(byte[] priv, String label, byte[] content) throws IOException, CryptoException + public byte[] signWithLabel(byte[] priv, String label, byte[] content) + throws IOException, CryptoException { MlsCipherSuite.GenericContent signContent = new MlsCipherSuite.GenericContent(label, content); byte[] signContentBytes = MLSOutputStream.encode(signContent); switch (sigID) { - case ecdsa_secp256r1_sha256: - case ecdsa_secp521r1_sha512: - case ecdsa_secp384r1_sha384: - BigInteger d = new BigInteger(1, priv); - signer.init(true, new ECPrivateKeyParameters(d, domainParams)); - break; - case ed25519: - signer.init(true, new Ed25519PrivateKeyParameters(priv)); - break; - case ed448: - signer.init(true, new Ed448PrivateKeyParameters(priv)); - break; + case ecdsa_secp256r1_sha256: + case ecdsa_secp521r1_sha512: + case ecdsa_secp384r1_sha384: + BigInteger d = new BigInteger(1, priv); + signer.init(true, new ECPrivateKeyParameters(d, domainParams)); + break; + case ed25519: + signer.init(true, new Ed25519PrivateKeyParameters(priv)); + break; + case ed448: + signer.init(true, new Ed448PrivateKeyParameters(priv)); + break; } signer.update(signContentBytes, 0, signContentBytes.length); return signer.generateSignature(); } - public boolean verifyWithLabel(byte[] pub, String label, byte[] content, byte[] signature) throws IOException + + public boolean verifyWithLabel(byte[] pub, String label, byte[] content, byte[] signature) + throws IOException { MlsCipherSuite.GenericContent signContent = new MlsCipherSuite.GenericContent(label, content); byte[] signContentBytes = MLSOutputStream.encode(signContent); switch (sigID) { - case ecdsa_secp256r1_sha256: - case ecdsa_secp521r1_sha512: - case ecdsa_secp384r1_sha384: - ECPoint G = domainParams.getCurve().decodePoint(pub); - signer.init(false, new ECPublicKeyParameters(G, domainParams)); - break; - case ed25519: - signer.init(false, new Ed25519PublicKeyParameters(pub)); - break; - case ed448: - signer.init(false, new Ed448PublicKeyParameters(pub)); - break; + case ecdsa_secp256r1_sha256: + case ecdsa_secp521r1_sha512: + case ecdsa_secp384r1_sha384: + ECPoint G = domainParams.getCurve().decodePoint(pub); + signer.init(false, new ECPublicKeyParameters(G, domainParams)); + break; + case ed25519: + signer.init(false, new Ed25519PublicKeyParameters(pub)); + break; + case ed448: + signer.init(false, new Ed448PublicKeyParameters(pub)); + break; } signer.update(signContentBytes, 0, signContentBytes.length); return signer.verifySignature(signature); diff --git a/mls/src/main/java/org/bouncycastle/mls/protocol/Group.java b/mls/src/main/java/org/bouncycastle/mls/protocol/Group.java index 75659859ee..bc24424546 100644 --- a/mls/src/main/java/org/bouncycastle/mls/protocol/Group.java +++ b/mls/src/main/java/org/bouncycastle/mls/protocol/Group.java @@ -1,5 +1,15 @@ package org.bouncycastle.mls.protocol; +import java.io.IOException; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.mls.GroupKeySet; import org.bouncycastle.mls.KeyScheduleEpoch; @@ -43,16 +53,6 @@ import org.bouncycastle.mls.crypto.MlsCipherSuite; import org.bouncycastle.mls.crypto.Secret; -import java.io.IOException; -import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - public class Group { @@ -67,6 +67,7 @@ public GroupWithMessage(Group group, MLSMessage message) this.message = message; } } + public class Tombstone { //const @@ -97,21 +98,22 @@ public Tombstone(Group group, Proposal.ReInit reinit) resumptionPsk = group.keySchedule.resumptionPSK.value(); } - public GroupWithMessage createWelcome(AsymmetricCipherKeyPair encSk, byte[] sigSk, LeafNode leafNode, List keyPackages, byte[] leafSecret, CommitOptions options) throws Exception + public GroupWithMessage createWelcome(AsymmetricCipherKeyPair encSk, byte[] sigSk, LeafNode leafNode, List keyPackages, byte[] leafSecret, CommitOptions options) + throws Exception { // Create new empty group with the appropriate PSK Group newGroup = new Group( - reinit.getGroupID(), - reinit.getSuite(), - encSk, - sigSk, - leafNode, - reinit.getExtensions() + reinit.getGroupID(), + reinit.getSuite(), + encSk, + sigSk, + leafNode, + reinit.getExtensions() ); newGroup.resumptionPSKs.put(new EpochRef(priorGroupID, priorEpoch), resumptionPsk); // Create Add proposals - List proposals = new ArrayList<>(); + List proposals = new ArrayList(); for (KeyPackage kp : keyPackages) { proposals.add(newGroup.addProposal(kp)); @@ -125,31 +127,33 @@ public GroupWithMessage createWelcome(AsymmetricCipherKeyPair encSk, byte[] sigS // Commit the Add and PSK proposals CommitOptions opts = new CommitOptions( - proposals, - options.inlineTree, - options.forcePath, - options.leafNodeOptions + proposals, + options.inlineTree, + options.forcePath, + options.leafNodeOptions ); GroupWithMessage gwm = newGroup.commit(new Secret(leafSecret), opts, new MessageOptions(), new CommitParameters(ResumptionPSKUsage.REINIT)); gwm.message.wireFormat = WireFormat.mls_welcome; return gwm; } - public Group handleWelcome(AsymmetricCipherKeyPair initSk, AsymmetricCipherKeyPair encSk, AsymmetricCipherKeyPair sigSk, KeyPackage keyPackage, MLSMessage welcome, TreeKEMPublicKey tree) throws Exception + + public Group handleWelcome(AsymmetricCipherKeyPair initSk, AsymmetricCipherKeyPair encSk, AsymmetricCipherKeyPair sigSk, KeyPackage keyPackage, MLSMessage welcome, TreeKEMPublicKey tree) + throws Exception { - Map resumptionPsks = new HashMap<>(); + Map resumptionPsks = new HashMap(); resumptionPsks.put(new EpochRef(priorGroupID, priorEpoch), resumptionPsk); - MlsCipherSuite suite = welcome.getCipherSuite(); // TODO DONT SERIALIZE KEYS + MlsCipherSuite suite = welcome.getCipherSuite(); Group newGroup = new Group( - suite.getHPKE().serializePrivateKey(initSk.getPrivate()), - encSk, - suite.serializeSignaturePrivateKey(sigSk.getPrivate()), - keyPackage, - welcome.welcome, - tree, - new HashMap<>(), - resumptionPsks + suite.getHPKE().serializePrivateKey(initSk.getPrivate()), + encSk, + suite.serializeSignaturePrivateKey(sigSk.getPrivate()), + keyPackage, + welcome.welcome, + tree, + new HashMap(), + resumptionPsks ); if (newGroup.suite.getSuiteID() != reinit.getSuite().getSuiteID()) @@ -165,6 +169,7 @@ public Group handleWelcome(AsymmetricCipherKeyPair initSk, AsymmetricCipherKeyPa return newGroup; } } + public class TombstoneWithMessage extends Tombstone { @@ -187,6 +192,7 @@ public TombstoneWithMessage(Group group, Proposal.ReInit reinit, MLSMessage mess public static final short EXTERNAL_COMMIT_PARAMS = 1; public static final short RESTART_COMMIT_PARAMS = 2; public static final short REINIT_COMMIT_PARAMS = 3; + static public class CommitParameters { short paramID; @@ -197,16 +203,18 @@ static public class CommitParameters // Restart ResumptionPSKUsage allowedUsage; - public CommitParameters(short paramID) - { - this.paramID = paramID; - } + public CommitParameters(short paramID) + { + this.paramID = paramID; + } + public CommitParameters(KeyPackage joinerKeyPackage, Secret forceInitSecret) { this.paramID = EXTERNAL_COMMIT_PARAMS; this.joinerKeyPackage = joinerKeyPackage; this.forceInitSecret = forceInitSecret; } + public CommitParameters(short paramID, KeyPackage joinerKeyPackage, Secret forceInitSecret, ResumptionPSKUsage allowedUsage) { this.paramID = paramID; @@ -221,6 +229,7 @@ public CommitParameters(ResumptionPSKUsage reinit) allowedUsage = reinit; } } + public static class MessageOptions { boolean encrypt = false; @@ -239,6 +248,7 @@ public MessageOptions(boolean encrypt, byte[] authenticatedData, int paddingSize this.paddingSize = paddingSize; } } + public static class LeafNodeOptions { Credential credential; @@ -271,6 +281,7 @@ public LeafNodeOptions(Credential credential, Capabilities capabilities, List extraProposals; @@ -280,10 +291,11 @@ public static class CommitOptions public CommitOptions() { - this.extraProposals = new ArrayList<>(); + this.extraProposals = new ArrayList(); this.leafNodeOptions = new LeafNodeOptions(); } + public CommitOptions(List extraProposals, boolean inlineTree, boolean forcePath, LeafNodeOptions leafNodeOptions) { this.extraProposals = extraProposals; @@ -299,6 +311,7 @@ public CommitOptions(List extraProposals, boolean inlineTree, boolean } } } + class JoinersWithPSKS { List joiners; @@ -310,7 +323,8 @@ public JoinersWithPSKS(List joiners, List>> 32)); + result = 31 * result + (int)(epoch ^ (epoch >>> 32)); return result; } } + Map externalPSKs; private Map resumptionPSKs; private long epoch; @@ -363,8 +378,7 @@ public int hashCode() private GroupKeySet keys; private MlsCipherSuite suite; private LeafIndex index; - private byte[] identitySk; // TODO: maybe make this AsymmetricCipherKeyPair -// private ArrayList proposalQueue; + private byte[] identitySk; private ArrayList pendingProposals; private CachedUpdate cachedUpdate; @@ -378,6 +392,7 @@ public MlsCipherSuite getSuite() { return suite; } + public ArrayList getExtensions() { return extensions; @@ -392,6 +407,7 @@ public TreeKEMPublicKey getTree() { return tree; } + public long getEpoch() { return epoch; @@ -407,19 +423,20 @@ public LeafIndex getIndex() return index; } - public MLSMessage getGroupInfo(boolean inlineTree) throws Exception + public MLSMessage getGroupInfo(boolean inlineTree) + throws Exception { GroupInfo groupInfo = new GroupInfo( - new GroupContext( - suite, - groupID, - epoch, - tree.getRootHash(), - transcriptHash.getConfirmed(), - extensions - ), - new ArrayList<>(), - keySchedule.confirmationTag(transcriptHash.getConfirmed()) + new GroupContext( + suite, + groupID, + epoch, + tree.getRootHash(), + transcriptHash.getConfirmed(), + extensions + ), + new ArrayList(), + keySchedule.confirmationTag(transcriptHash.getConfirmed()) ); byte[] externalPub = suite.getHPKE().serializePublicKey(keySchedule.getExternalPublicKey()); @@ -443,7 +460,8 @@ public Group() { } - public Group(AsymmetricCipherKeyPair sigSk, GroupInfo groupInfo, TreeKEMPublicKey tree) throws Exception + public Group(AsymmetricCipherKeyPair sigSk, GroupInfo groupInfo, TreeKEMPublicKey tree) + throws Exception { this.suite = groupInfo.getSuite(); this.groupID = groupInfo.getGroupID().clone(); @@ -451,39 +469,41 @@ public Group(AsymmetricCipherKeyPair sigSk, GroupInfo groupInfo, TreeKEMPublicKe this.tree = TreeKEMPublicKey.clone(importTree(groupInfo.getGroupContext().getTreeHash(), tree, groupInfo.getExtensions())); this.treePriv = new TreeKEMPrivateKey(suite, new LeafIndex(0));// check this should be null this.transcriptHash = TranscriptHash.fromConfirmationTag(this.suite, groupInfo.getGroupContext().getConfirmedTranscriptHash(), groupInfo.getConfirmationTag()); - this.extensions = new ArrayList<>(groupInfo.getGroupContext().getExtensions()); + this.extensions = new ArrayList(groupInfo.getGroupContext().getExtensions()); this.keySchedule = new KeyScheduleEpoch(this.suite); this.index = new LeafIndex(0); this.identitySk = suite.serializeSignaturePrivateKey(sigSk.getPrivate()); - this.pendingProposals = new ArrayList<>(); - this.resumptionPSKs = new HashMap<>(); - this.externalPSKs = new HashMap<>(); + this.pendingProposals = new ArrayList(); + this.resumptionPSKs = new HashMap(); + this.externalPSKs = new HashMap(); this.keys = null; } + // Create a new group public Group( - byte[] groupID, - MlsCipherSuite suite, - AsymmetricCipherKeyPair encSk, - byte[] sigSk, - LeafNode leafNode, - List extensions - ) throws Exception + byte[] groupID, + MlsCipherSuite suite, + AsymmetricCipherKeyPair encSk, + byte[] sigSk, + LeafNode leafNode, + List extensions + ) + throws Exception { this.suite = suite; this.groupID = groupID.clone(); this.epoch = 0; tree = new TreeKEMPublicKey(suite); this.transcriptHash = new TranscriptHash(suite); - this.extensions = new ArrayList<>(); + this.extensions = new ArrayList(); this.extensions.addAll(extensions); this.index = new LeafIndex(0); this.identitySk = sigSk.clone(); - this.pendingProposals = new ArrayList<>(); - this.externalPSKs = new HashMap<>(); - this.resumptionPSKs = new HashMap<>(); + this.pendingProposals = new ArrayList(); + this.externalPSKs = new HashMap(); + this.resumptionPSKs = new HashMap(); index = tree.addLeaf(leafNode); tree.setHashAll(); @@ -502,37 +522,37 @@ public Group( } // Creates a group from a welcome message + /** - * - * @param initSk HPKE private key - * @param leafSk HPKE private key for leaf node - * @param sigSk signature private key - * @param keyPackage key package - * @param welcome welcome - * @param treeIn public kem tree (optional) - * @param externalPsks map of external psks + * @param initSk HPKE private key + * @param leafSk HPKE private key for leaf node + * @param sigSk signature private key + * @param keyPackage key package + * @param welcome welcome + * @param treeIn public kem tree (optional) + * @param externalPsks map of external psks * @param resumptionPsks map of resumptions psks * @throws Exception */ public Group( - byte[] initSk, - AsymmetricCipherKeyPair leafSk, - byte[] sigSk, - KeyPackage keyPackage, - Welcome welcome, - TreeKEMPublicKey treeIn, - Map externalPsks, - Map resumptionPsks + byte[] initSk, + AsymmetricCipherKeyPair leafSk, + byte[] sigSk, + KeyPackage keyPackage, + Welcome welcome, + TreeKEMPublicKey treeIn, + Map externalPsks, + Map resumptionPsks ) - throws Exception + throws Exception { - pendingProposals = new ArrayList<>(); + pendingProposals = new ArrayList(); suite = welcome.getSuite(); epoch = 0; identitySk = sigSk; - externalPSKs = new HashMap<>(); + externalPSKs = new HashMap(); externalPSKs.putAll(externalPsks); - this.resumptionPSKs = new HashMap<>(); + this.resumptionPSKs = new HashMap(); this.resumptionPSKs.putAll(resumptionPsks); int kpi = welcome.find(keyPackage); @@ -573,7 +593,7 @@ public Group( transcriptHash = new TranscriptHash(suite, groupInfo.getGroupContext().getConfirmedTranscriptHash().clone(), null); transcriptHash.updateInterim(groupInfo.getConfirmationTag()); - extensions = new ArrayList<>(); // TODO: Check to clone? + extensions = new ArrayList(); extensions.addAll(groupInfo.getGroupContext().getExtensions()); // Create the TreeKEMPrivateKey @@ -610,14 +630,17 @@ public Group( } } - public Group handle(byte[] mlsMessageBytes, Group cachedGroup) throws Exception + public Group handle(byte[] mlsMessageBytes, Group cachedGroup) + throws Exception { return handle(mlsMessageBytes, cachedGroup, null); } - public Group handle(byte[] mlsMessageBytes, Group cachedGroup, CommitParameters expectedParams) throws Exception + + public Group handle(byte[] mlsMessageBytes, Group cachedGroup, CommitParameters expectedParams) + throws Exception { - MLSMessage msg = (MLSMessage) MLSInputStream.decode(mlsMessageBytes, MLSMessage.class); - if (msg.version != ProtocolVersion.mls10) //TODO: do check in MLSMessage? + MLSMessage msg = (MLSMessage)MLSInputStream.decode(mlsMessageBytes, MLSMessage.class); + if (msg.version != ProtocolVersion.mls10) { throw new Exception("Unsupported version"); } @@ -625,22 +648,22 @@ public Group handle(byte[] mlsMessageBytes, Group cachedGroup, CommitParameters AuthenticatedContent auth; switch (msg.wireFormat) { - case mls_public_message: - auth = msg.publicMessage.unprotect(suite, keySchedule.membershipKey, getGroupContext()); - if (auth == null)//TODO: remove this? - { - throw new Exception("Membership tag failed to verify"); - } - break; - case mls_private_message: - auth = msg.privateMessage.unprotect(suite, keys, keySchedule.senderDataSecret.value()); - if (auth == null) - { - throw new Exception("PrivateMessage decryption failure"); - } - break; - default: - throw new Exception("Invalid wire format"); + case mls_public_message: + auth = msg.publicMessage.unprotect(suite, keySchedule.membershipKey, getGroupContext()); + if (auth == null) + { + throw new Exception("Membership tag failed to verify"); + } + break; + case mls_private_message: + auth = msg.privateMessage.unprotect(suite, keys, keySchedule.senderDataSecret.value()); + if (auth == null) + { + throw new Exception("PrivateMessage decryption failure"); + } + break; + default: + throw new Exception("Invalid wire format"); } if (!verifyAuth(auth)) { @@ -650,7 +673,8 @@ public Group handle(byte[] mlsMessageBytes, Group cachedGroup, CommitParameters } - public Group handle(AuthenticatedContent auth, Group cachedGroup, CommitParameters expectedParams) throws Exception + public Group handle(AuthenticatedContent auth, Group cachedGroup, CommitParameters expectedParams) + throws Exception { // Validate the GroupContent FramedContent content = auth.getContent(); @@ -667,25 +691,25 @@ public Group handle(AuthenticatedContent auth, Group cachedGroup, CommitParamete // Dispatch on content type switch (content.getContentType()) { - case PROPOSAL: - // Proposals get queued, do not result in a state transition - cacheProposal(auth); - return null; - case COMMIT: - // Commits are handled in the remainder of this method - break; - default: - // Any other content type in this method is an error - throw new Exception("Invalid content type"); + case PROPOSAL: + // Proposals get queued, do not result in a state transition + cacheProposal(auth); + return null; + case COMMIT: + // Commits are handled in the remainder of this method + break; + default: + // Any other content type in this method is an error + throw new Exception("Invalid content type"); } switch (content.getSender().getSenderType()) { - case MEMBER: - case NEW_MEMBER_COMMIT: - break; - default: - throw new Exception("Invalid commit sender type"); + case MEMBER: + case NEW_MEMBER_COMMIT: + break; + default: + throw new Exception("Invalid commit sender type"); } LeafIndex sender = null; @@ -771,19 +795,19 @@ public Group handle(AuthenticatedContent auth, Group cachedGroup, CommitParamete next.tree.merge(senderLocation, path); byte[] ctx = MLSOutputStream.encode(new GroupContext( - next.suite, - next.groupID, - next.epoch + 1, - next.tree.getRootHash(), - next.transcriptHash.getConfirmed(), - next.extensions + next.suite, + next.groupID, + next.epoch + 1, + next.tree.getRootHash(), + next.transcriptHash.getConfirmed(), + next.extensions )); next.treePriv.decap( - senderLocation, - next.tree, - ctx, - path, - joinersWithPSKS.joiners + senderLocation, + next.tree, + ctx, + path, + joinersWithPSKS.joiners ); commitSecret = next.treePriv.getUpdateSecret().value().clone(); } @@ -805,26 +829,27 @@ public Group handle(AuthenticatedContent auth, Group cachedGroup, CommitParamete } - private CommitParameters inferCommitType(LeafIndex sender, List proposals, CommitParameters expectedParams) throws Exception + private CommitParameters inferCommitType(LeafIndex sender, List proposals, CommitParameters expectedParams) + throws Exception { // If an expected type was provided, validate against it - if(expectedParams != null) + if (expectedParams != null) { boolean specifically = false; switch (expectedParams.paramID) { - case NORMAL_COMMIT_PARAMS: - specifically = (sender != null) && validateNormalCachedProposals(proposals, sender); - break; - case EXTERNAL_COMMIT_PARAMS: - specifically = (sender == null) && validateExternalCachedProposals(proposals); - break; - case RESTART_COMMIT_PARAMS: - specifically = (sender != null) && validateRestartCachedProposals(proposals, expectedParams.allowedUsage); - break; - case REINIT_COMMIT_PARAMS: - specifically = (sender != null) && validateReInitCachedProposals(proposals); - break; + case NORMAL_COMMIT_PARAMS: + specifically = (sender != null) && validateNormalCachedProposals(proposals, sender); + break; + case EXTERNAL_COMMIT_PARAMS: + specifically = (sender == null) && validateExternalCachedProposals(proposals); + break; + case RESTART_COMMIT_PARAMS: + specifically = (sender != null) && validateRestartCachedProposals(proposals, expectedParams.allowedUsage); + break; + case REINIT_COMMIT_PARAMS: + specifically = (sender != null) && validateReInitCachedProposals(proposals); + break; } if (!specifically) { @@ -849,14 +874,15 @@ private CommitParameters inferCommitType(LeafIndex sender, List } - public GroupWithMessage createBranch(byte[] groupID, AsymmetricCipherKeyPair encryptionKeyPair, AsymmetricCipherKeyPair signatureKeyPair, LeafNode leafNode, List extList, List keyPackages, byte[] leafSecret, CommitOptions commitOptions) throws Exception + public GroupWithMessage createBranch(byte[] groupID, AsymmetricCipherKeyPair encryptionKeyPair, AsymmetricCipherKeyPair signatureKeyPair, LeafNode leafNode, List extList, List keyPackages, byte[] leafSecret, CommitOptions commitOptions) + throws Exception { // Create a new empty group with the appropriate PSK - Group newGroup = new Group(groupID, suite, encryptionKeyPair,suite.serializeSignaturePrivateKey(signatureKeyPair.getPrivate()), leafNode, extensions); + Group newGroup = new Group(groupID, suite, encryptionKeyPair, suite.serializeSignaturePrivateKey(signatureKeyPair.getPrivate()), leafNode, extensions); newGroup.resumptionPSKs.put(new EpochRef(this.groupID, this.epoch), this.keySchedule.resumptionPSK.value().clone()); // Create Add proposals - List proposals = new ArrayList<>(); + List proposals = new ArrayList(); for (KeyPackage kp : keyPackages) { proposals.add(newGroup.addProposal(kp)); @@ -870,30 +896,31 @@ public GroupWithMessage createBranch(byte[] groupID, AsymmetricCipherKeyPair enc // Commit the Add and PSK proposals CommitOptions opts = new CommitOptions( - proposals, - commitOptions.inlineTree, - commitOptions.forcePath, - commitOptions.leafNodeOptions + proposals, + commitOptions.inlineTree, + commitOptions.forcePath, + commitOptions.leafNodeOptions ); GroupWithMessage gwm = newGroup.commit(new Secret(leafSecret), opts, new MessageOptions(), new CommitParameters(ResumptionPSKUsage.BRANCH)); gwm.message.wireFormat = WireFormat.mls_welcome; return gwm; } - public Group handleBranch(AsymmetricCipherKeyPair initSk, AsymmetricCipherKeyPair encSk, AsymmetricCipherKeyPair sigSk, KeyPackage keyPackage, MLSMessage welcome, TreeKEMPublicKey tree) throws Exception + public Group handleBranch(AsymmetricCipherKeyPair initSk, AsymmetricCipherKeyPair encSk, AsymmetricCipherKeyPair sigSk, KeyPackage keyPackage, MLSMessage welcome, TreeKEMPublicKey tree) + throws Exception { - Map resumptionPsks = new HashMap<>(); + Map resumptionPsks = new HashMap(); resumptionPsks.put(new EpochRef(this.groupID, this.epoch), this.keySchedule.resumptionPSK.value().clone()); Group branchGroup = new Group( - suite.getHPKE().serializePrivateKey(initSk.getPrivate()), - encSk, - suite.serializeSignaturePrivateKey(sigSk.getPrivate()), - keyPackage, - welcome.welcome, - tree, - new HashMap<>(), - resumptionPsks + suite.getHPKE().serializePrivateKey(initSk.getPrivate()), + encSk, + suite.serializeSignaturePrivateKey(sigSk.getPrivate()), + keyPackage, + welcome.welcome, + tree, + new HashMap(), + resumptionPsks ); if (branchGroup.suite.getSuiteID() != suite.getSuiteID()) @@ -909,7 +936,8 @@ public Group handleBranch(AsymmetricCipherKeyPair initSk, AsymmetricCipherKeyPai } - public Tombstone handleReinitCommit(MLSMessage commitMessage) throws Exception + public Tombstone handleReinitCommit(MLSMessage commitMessage) + throws Exception { // Verify the signature and process the commit AuthenticatedContent auth = unprotectToContentAuth(commitMessage); @@ -933,14 +961,14 @@ public Tombstone handleReinitCommit(MLSMessage commitMessage) throws Exception } public static GroupWithMessage externalJoin(Secret leafSecret, - AsymmetricCipherKeyPair sigSk, - KeyPackage keyPackage, - GroupInfo groupInfo, - TreeKEMPublicKey tree, - MessageOptions msgOptions, - LeafIndex removePrior, - Map psks) - throws Exception + AsymmetricCipherKeyPair sigSk, + KeyPackage keyPackage, + GroupInfo groupInfo, + TreeKEMPublicKey tree, + MessageOptions msgOptions, + LeafIndex removePrior, + Map psks) + throws Exception { // Create a preliminary group Group initialGroup = new Group(sigSk, groupInfo, tree); @@ -964,12 +992,13 @@ public static GroupWithMessage externalJoin(Secret leafSecret, // Insert an ExternalInit proposal CommitOptions options = new CommitOptions(); KeyScheduleEpoch.ExternalInitParams extParams = new KeyScheduleEpoch.ExternalInitParams( - suite, suite.getHPKE().deserializePublicKey(extPub)); + suite, suite.getHPKE().deserializePublicKey(extPub)); options.extraProposals.add(Proposal.externalInit(extParams.getKEMOutput())); // Evict a prior appearance if required - if (removePrior != null) { + if (removePrior != null) + { Proposal remove = initialGroup.removeProposal(removePrior); options.extraProposals.add(remove); } @@ -988,10 +1017,11 @@ public static GroupWithMessage externalJoin(Secret leafSecret, return gwm; } - public GroupWithMessage commit(Secret leafSecret, CommitOptions commitOptions, MessageOptions msgOptions, CommitParameters params) throws Exception + public GroupWithMessage commit(Secret leafSecret, CommitOptions commitOptions, MessageOptions msgOptions, CommitParameters params) + throws Exception { Commit commit = new Commit(); - List joiners = new ArrayList<>(); + List joiners = new ArrayList(); for (CachedProposal cached : pendingProposals) { if (cached.proposal.getProposalType() == ProposalType.ADD) @@ -1047,7 +1077,7 @@ public GroupWithMessage commit(Secret leafSecret, CommitOptions commitOptions, M // KEM new entropy to the group and the new joiners Secret commitSecret = Secret.zero(suite); - List pathSecrets = new ArrayList<>(); + List pathSecrets = new ArrayList(); for (int i = 0; i < joinersWithpsks.joiners.size(); i++) { pathSecrets.add(null); @@ -1062,12 +1092,12 @@ public GroupWithMessage commit(Secret leafSecret, CommitOptions commitOptions, M } TreeKEMPrivateKey newPriv = next.tree.update(next.index, leafSecret, next.groupID, identitySk, leafNodeOptions); GroupContext ctx = new GroupContext( - next.suite, - next.groupID, - next.epoch + 1, - next.tree.getRootHash(), - next.transcriptHash.getConfirmed(), - next.extensions + next.suite, + next.groupID, + next.epoch + 1, + next.tree.getRootHash(), + next.transcriptHash.getConfirmed(), + next.extensions ); byte[] ctxBytes = MLSOutputStream.encode(ctx); UpdatePath path = next.tree.encap(newPriv, ctxBytes, joinersWithpsks.joiners); @@ -1098,16 +1128,16 @@ public GroupWithMessage commit(Secret leafSecret, CommitOptions commitOptions, M // Complete the GroupInfo and form the Welcome next.tree.setHashAll(); GroupInfo groupInfo = new GroupInfo( - new GroupContext( - next.suite, - next.groupID, - next.epoch, - next.tree.getRootHash(), - next.transcriptHash.getConfirmed(), - next.extensions - ), - new ArrayList<>(), - confirmationTag + new GroupContext( + next.suite, + next.groupID, + next.epoch, + next.tree.getRootHash(), + next.transcriptHash.getConfirmed(), + next.extensions + ), + new ArrayList(), + confirmationTag ); if (commitOptions != null && commitOptions.inlineTree) { @@ -1115,24 +1145,22 @@ public GroupWithMessage commit(Secret leafSecret, CommitOptions commitOptions, M } groupInfo.sign(next.tree, next.index, suite.deserializeSignaturePrivateKey(next.identitySk)); - //TODO: should have a way to retrieve joiner secret from key schedule Welcome welcome = new Welcome(suite, - next.keySchedule.getJoinerSecret().value(), - joinersWithpsks.psks, - MLSOutputStream.encode(groupInfo)); + next.keySchedule.getJoinerSecret().value(), + joinersWithpsks.psks, + MLSOutputStream.encode(groupInfo)); for (int i = 0; i < joiners.size(); i++) { welcome.encrypt(joiners.get(i), pathSecrets.get(i)); } -// this.replace(next); //TODO: return instead of replace - //TODO: separate welcome and commit message commitMessage.welcome = welcome; return new GroupWithMessage(next, commitMessage); } - public TombstoneWithMessage reinitCommit(byte[] leafSecret, CommitOptions commitOptions, MessageOptions messageOptions) throws Exception + public TombstoneWithMessage reinitCommit(byte[] leafSecret, CommitOptions commitOptions, MessageOptions messageOptions) + throws Exception { Proposal reinitProposal = null; if (pendingProposals.size() == 1) @@ -1156,23 +1184,24 @@ else if (commitOptions != null && commitOptions.extraProposals.size() == 1) return new TombstoneWithMessage(gwm.group, reinit, gwm.message); } - static public MLSMessage newMemberAdd(byte[] groupID, long epoch, KeyPackage newMember, AsymmetricCipherKeyPair sigSk) throws Exception + static public MLSMessage newMemberAdd(byte[] groupID, long epoch, KeyPackage newMember, AsymmetricCipherKeyPair sigSk) + throws Exception { MlsCipherSuite suite = newMember.getSuite(); Proposal proposal = Proposal.add(newMember); FramedContent content = FramedContent.proposal( - groupID, - epoch, - Sender.forNewMemberProposal(), - new byte[0], - MLSOutputStream.encode(proposal) + groupID, + epoch, + Sender.forNewMemberProposal(), + new byte[0], + MLSOutputStream.encode(proposal) ); AuthenticatedContent contentAuth = AuthenticatedContent.sign( - WireFormat.mls_public_message, - content, - suite, - suite.serializeSignaturePrivateKey(sigSk.getPrivate()), - null + WireFormat.mls_public_message, + content, + suite, + suite.serializeSignaturePrivateKey(sigSk.getPrivate()), + null ); MLSMessage message = new MLSMessage(WireFormat.mls_public_message); @@ -1180,19 +1209,22 @@ static public MLSMessage newMemberAdd(byte[] groupID, long epoch, KeyPackage new return message; } - public MLSMessage protect(byte[] applicationData, byte[] pt, int paddingSize) throws Exception + public MLSMessage protect(byte[] applicationData, byte[] pt, int paddingSize) + throws Exception { Group.MessageOptions msgOptions = new Group.MessageOptions(true, applicationData, paddingSize); AuthenticatedContent contentAuth = sign( - Sender.forMember(index), - pt, - msgOptions.authenticatedData, - msgOptions.encrypt + Sender.forMember(index), + pt, + msgOptions.authenticatedData, + msgOptions.encrypt ); return protect(contentAuth, msgOptions.paddingSize); } - public byte[][] unprotect(MLSMessage ct) throws Exception + + public byte[][] unprotect(MLSMessage ct) + throws Exception { AuthenticatedContent auth = unprotectToContentAuth(ct); if (!verifyAuth(auth)) @@ -1200,7 +1232,7 @@ public byte[][] unprotect(MLSMessage ct) throws Exception throw new Exception("Message signature failed to verify"); } - if(auth.getContent().getContentType() != ContentType.APPLICATION) + if (auth.getContent().getContentType() != ContentType.APPLICATION) { throw new Exception("Unprotected of handshake message"); } @@ -1215,24 +1247,26 @@ public byte[][] unprotect(MLSMessage ct) throws Exception return authAndContent; } - private boolean verifyAuth(AuthenticatedContent auth) throws Exception + private boolean verifyAuth(AuthenticatedContent auth) + throws Exception { switch (auth.getContent().getSender().getSenderType()) { - case MEMBER: - return verifyInternal(auth); - case EXTERNAL: - return verifyExternal(auth); - case NEW_MEMBER_PROPOSAL: - return verifyNewMemberProposal(auth); - case NEW_MEMBER_COMMIT: - return verifyNewMemberCommit(auth); - default: - throw new Exception("Invalid sender type"); + case MEMBER: + return verifyInternal(auth); + case EXTERNAL: + return verifyExternal(auth); + case NEW_MEMBER_PROPOSAL: + return verifyNewMemberProposal(auth); + case NEW_MEMBER_COMMIT: + return verifyNewMemberCommit(auth); + default: + throw new Exception("Invalid sender type"); } } - private boolean verifyInternal(AuthenticatedContent auth) throws Exception + private boolean verifyInternal(AuthenticatedContent auth) + throws Exception { LeafNode leaf = tree.getLeafNode(auth.getContent().getSender().getSender()); if (leaf == null) @@ -1242,7 +1276,8 @@ private boolean verifyInternal(AuthenticatedContent auth) throws Exception return auth.verify(suite, leaf.getSignatureKey(), MLSOutputStream.encode(getGroupContext())); } - private boolean verifyExternal(AuthenticatedContent auth) throws Exception + private boolean verifyExternal(AuthenticatedContent auth) + throws Exception { Sender extSender = auth.getContent().getSender(); Extension sendersExt = null; @@ -1256,11 +1291,12 @@ private boolean verifyExternal(AuthenticatedContent auth) throws Exception List senders = sendersExt.getSenders(); return auth.verify(suite, - senders.get(extSender.getSenderIndex()).getSignatureKey(), - MLSOutputStream.encode(getGroupContext())); + senders.get(extSender.getSenderIndex()).getSignatureKey(), + MLSOutputStream.encode(getGroupContext())); } - private boolean verifyNewMemberProposal(AuthenticatedContent auth) throws Exception + private boolean verifyNewMemberProposal(AuthenticatedContent auth) + throws Exception { Proposal proposal = auth.getContent().getProposal(); Proposal.Add add = proposal.getAdd(); @@ -1268,7 +1304,8 @@ private boolean verifyNewMemberProposal(AuthenticatedContent auth) throws Except return auth.verify(suite, pub, MLSOutputStream.encode(getGroupContext())); } - private boolean verifyNewMemberCommit(AuthenticatedContent auth) throws Exception + private boolean verifyNewMemberCommit(AuthenticatedContent auth) + throws Exception { Commit commit = auth.getContent().getCommit(); UpdatePath path = commit.getUpdatePath(); @@ -1276,7 +1313,8 @@ private boolean verifyNewMemberCommit(AuthenticatedContent auth) throws Exceptio return auth.verify(suite, pub, MLSOutputStream.encode(getGroupContext())); } - private AuthenticatedContent unprotectToContentAuth(MLSMessage msg) throws Exception + private AuthenticatedContent unprotectToContentAuth(MLSMessage msg) + throws Exception { if (msg.version != ProtocolVersion.mls10) { @@ -1285,93 +1323,102 @@ private AuthenticatedContent unprotectToContentAuth(MLSMessage msg) throws Excep AuthenticatedContent auth = null; switch (msg.wireFormat) { - case mls_public_message: - auth = msg.publicMessage.unprotect(suite, keySchedule.membershipKey, getGroupContext()); - if (auth == null) - { - throw new Exception("Membership tag failed to verify"); - } - break; - case mls_private_message: - auth = msg.privateMessage.unprotect(suite, keys, keySchedule.senderDataSecret.value()); - if (auth == null) - { - throw new Exception("PrivateMessage decryption failure"); - } - break; - case mls_welcome: - case mls_group_info: - case mls_key_package: - throw new Exception("Invalid wire format"); + case mls_public_message: + auth = msg.publicMessage.unprotect(suite, keySchedule.membershipKey, getGroupContext()); + if (auth == null) + { + throw new Exception("Membership tag failed to verify"); + } + break; + case mls_private_message: + auth = msg.privateMessage.unprotect(suite, keys, keySchedule.senderDataSecret.value()); + if (auth == null) + { + throw new Exception("PrivateMessage decryption failure"); + } + break; + case mls_welcome: + case mls_group_info: + case mls_key_package: + throw new Exception("Invalid wire format"); } return auth; } - public MLSMessage add(KeyPackage keyPackage, MessageOptions msgOptions) throws Exception + + public MLSMessage add(KeyPackage keyPackage, MessageOptions msgOptions) + throws Exception { AuthenticatedContent contentAuth = sign( - Sender.forMember(index), - addProposal(keyPackage), - msgOptions.authenticatedData, - msgOptions.encrypt + Sender.forMember(index), + addProposal(keyPackage), + msgOptions.authenticatedData, + msgOptions.encrypt ); -// System.out.println(Hex.toHexString(MLSOutputStream.encode(contentAuth))); return protect(contentAuth, msgOptions.paddingSize); } - public MLSMessage update(Proposal update, MessageOptions msgOptions) throws Exception + + public MLSMessage update(Proposal update, MessageOptions msgOptions) + throws Exception { AuthenticatedContent contentAuth = sign( - Sender.forMember(index), - update, - msgOptions.authenticatedData, - msgOptions.encrypt + Sender.forMember(index), + update, + msgOptions.authenticatedData, + msgOptions.encrypt ); return protect(contentAuth, msgOptions.paddingSize); } - public MLSMessage groupContextExtensions(List extensions, MessageOptions msgOptions) throws Exception + + public MLSMessage groupContextExtensions(List extensions, MessageOptions msgOptions) + throws Exception { if (!extensionsSupported(extensions)) { throw new Exception("Unsupported extensions"); } AuthenticatedContent contentAuth = sign( - Sender.forMember(index), - Proposal.groupContextExtensions(extensions), - msgOptions.authenticatedData, - msgOptions.encrypt + Sender.forMember(index), + Proposal.groupContextExtensions(extensions), + msgOptions.authenticatedData, + msgOptions.encrypt ); return protect(contentAuth, msgOptions.paddingSize); } - public MLSMessage remove(LeafIndex removeIndex, MessageOptions msgOptions) throws Exception + + public MLSMessage remove(LeafIndex removeIndex, MessageOptions msgOptions) + throws Exception { // leaf for roster Proposal remove = Proposal.remove(leafForRoster(removeIndex)); AuthenticatedContent contentAuth = sign( - Sender.forMember(index), - remove, - msgOptions.authenticatedData, - msgOptions.encrypt + Sender.forMember(index), + remove, + msgOptions.authenticatedData, + msgOptions.encrypt ); return protect(contentAuth, msgOptions.paddingSize); } - public MLSMessage reinit(byte[] groupID, ProtocolVersion version, MlsCipherSuite suite, List extList, MessageOptions msgOptions) throws Exception + public MLSMessage reinit(byte[] groupID, ProtocolVersion version, MlsCipherSuite suite, List extList, MessageOptions msgOptions) + throws Exception { // reinitProposal Proposal reinit = Proposal.reInit(groupID, version, suite, extList); AuthenticatedContent contentAuth = sign( - Sender.forMember(index), - reinit, - msgOptions.authenticatedData, - msgOptions.encrypt + Sender.forMember(index), + reinit, + msgOptions.authenticatedData, + msgOptions.encrypt ); return protect(contentAuth, msgOptions.paddingSize); } - public MLSMessage preSharedKey(byte[] externalPskId, MessageOptions msgOptions) throws Exception + public MLSMessage preSharedKey(byte[] externalPskId, MessageOptions msgOptions) + throws Exception { if (!externalPSKs.containsKey(new Secret(externalPskId))) { @@ -1383,14 +1430,16 @@ public MLSMessage preSharedKey(byte[] externalPskId, MessageOptions msgOptions) PreSharedKeyID pskId = PreSharedKeyID.external(externalPskId, nonce); AuthenticatedContent contentAuth = sign( - Sender.forMember(index), - Proposal.preSharedKey(pskId), - msgOptions.authenticatedData, - msgOptions.encrypt + Sender.forMember(index), + Proposal.preSharedKey(pskId), + msgOptions.authenticatedData, + msgOptions.encrypt ); return protect(contentAuth, msgOptions.paddingSize); } - public MLSMessage preSharedKey(byte[] groupID, long epoch, MessageOptions msgOptions) throws Exception + + public MLSMessage preSharedKey(byte[] groupID, long epoch, MessageOptions msgOptions) + throws Exception { if (epoch != this.epoch && !resumptionPSKs.containsKey(new EpochRef(groupID, epoch))) { @@ -1402,15 +1451,16 @@ public MLSMessage preSharedKey(byte[] groupID, long epoch, MessageOptions msgOpt PreSharedKeyID pskId = PreSharedKeyID.resumption(ResumptionPSKUsage.APPLICATION, groupID, epoch, nonce); AuthenticatedContent contentAuth = sign( - Sender.forMember(index), - Proposal.preSharedKey(pskId), - msgOptions.authenticatedData, - msgOptions.encrypt + Sender.forMember(index), + Proposal.preSharedKey(pskId), + msgOptions.authenticatedData, + msgOptions.encrypt ); return protect(contentAuth, msgOptions.paddingSize); } - private LeafIndex leafForRoster(LeafIndex index) throws Exception + private LeafIndex leafForRoster(LeafIndex index) + throws Exception { int nonBlankLeaves = 0; for (int i = 0; i < tree.getSize().leafCount(); i++) @@ -1429,7 +1479,8 @@ private LeafIndex leafForRoster(LeafIndex index) throws Exception throw new Exception("Invalid roster index"); } - public Proposal updateProposal(AsymmetricCipherKeyPair leafSk, LeafNodeOptions leafOptions) throws Exception + public Proposal updateProposal(AsymmetricCipherKeyPair leafSk, LeafNodeOptions leafOptions) + throws Exception { LeafNode leaf = tree.getLeafNode(index); LeafNode newLeaf = leaf.forUpdate(suite, groupID, index, suite.getHPKE().serializePublicKey(leafSk.getPublic()), leafOptions, identitySk); @@ -1439,10 +1490,11 @@ public Proposal updateProposal(AsymmetricCipherKeyPair leafSk, LeafNodeOptions l return update; } - private Proposal addProposal(KeyPackage keyPackage) throws Exception + private Proposal addProposal(KeyPackage keyPackage) + throws Exception { //TODO: Check that validity of the signed key package - if(!keyPackage.verify()) + if (!keyPackage.verify()) { throw new Exception("Invalid signature on key package"); } @@ -1454,24 +1506,25 @@ private Proposal addProposal(KeyPackage keyPackage) throws Exception return Proposal.add(keyPackage); } - private MLSMessage protect(AuthenticatedContent contentAuth, int paddingSize) throws Exception + private MLSMessage protect(AuthenticatedContent contentAuth, int paddingSize) + throws Exception { - MLSMessage message = new MLSMessage(contentAuth.getWireFormat()); //TODO: change pretect to return MLSMessage instead + MLSMessage message = new MLSMessage(contentAuth.getWireFormat()); switch (contentAuth.getWireFormat()) { - case mls_public_message: - message.publicMessage = PublicMessage.protect(contentAuth, suite, keySchedule.membershipKey.value(), MLSOutputStream.encode(getGroupContext())); - return message; - case mls_private_message: - message.privateMessage = PrivateMessage.protect(contentAuth, suite, keys, keySchedule.senderDataSecret.value(), paddingSize); - return message; - default: - throw new Exception("Malformed AuthenticatedContent"); + case mls_public_message: + message.publicMessage = PublicMessage.protect(contentAuth, suite, keySchedule.membershipKey.value(), MLSOutputStream.encode(getGroupContext())); + return message; + case mls_private_message: + message.privateMessage = PrivateMessage.protect(contentAuth, suite, keys, keySchedule.senderDataSecret.value(), paddingSize); + return message; + default: + throw new Exception("Malformed AuthenticatedContent"); } } - //TODO: check if innerContent should be mlsMessage or commit - private AuthenticatedContent sign(Sender sender, Commit innerContent, byte[] authenticatedData, boolean encrypt) throws Exception + private AuthenticatedContent sign(Sender sender, Commit innerContent, byte[] authenticatedData, boolean encrypt) + throws Exception { FramedContent content = FramedContent.rawContent(groupID, epoch, sender, authenticatedData, ContentType.COMMIT, MLSOutputStream.encode(innerContent)); WireFormat wireFormat = encrypt ? WireFormat.mls_private_message : WireFormat.mls_public_message; @@ -1479,14 +1532,17 @@ private AuthenticatedContent sign(Sender sender, Commit innerContent, byte[] aut return authContent; } - private AuthenticatedContent sign(Sender sender, Proposal innerContent, byte[] authenticatedData, boolean encrypt) throws Exception + private AuthenticatedContent sign(Sender sender, Proposal innerContent, byte[] authenticatedData, boolean encrypt) + throws Exception { FramedContent content = FramedContent.rawContent(groupID, epoch, sender, authenticatedData, ContentType.PROPOSAL, MLSOutputStream.encode(innerContent)); WireFormat wireFormat = encrypt ? WireFormat.mls_private_message : WireFormat.mls_public_message; AuthenticatedContent authContent = AuthenticatedContent.sign(wireFormat, content, suite, identitySk, MLSOutputStream.encode(getGroupContext())); return authContent; } - private AuthenticatedContent sign(Sender sender, byte[] innerContent, byte[] authenticatedData, boolean encrypt) throws Exception + + private AuthenticatedContent sign(Sender sender, byte[] innerContent, byte[] authenticatedData, boolean encrypt) + throws Exception { FramedContent content = FramedContent.rawContent(groupID, epoch, sender, authenticatedData, ContentType.APPLICATION, innerContent); WireFormat wireFormat = encrypt ? WireFormat.mls_private_message : WireFormat.mls_public_message; @@ -1495,7 +1551,7 @@ private AuthenticatedContent sign(Sender sender, byte[] innerContent, byte[] aut } private Proposal preSharedKeyProposal(Secret externalPskID) - throws Exception + throws Exception { if (!externalPSKs.containsKey(externalPskID)) { @@ -1508,7 +1564,8 @@ private Proposal preSharedKeyProposal(Secret externalPskID) return Proposal.preSharedKey(PreSharedKeyID.external(externalPskID.value(), nonce)); } - private Proposal removeProposal(LeafIndex removed) throws Exception + private Proposal removeProposal(LeafIndex removed) + throws Exception { if (!tree.hasLeaf(removed)) { @@ -1518,21 +1575,23 @@ private Proposal removeProposal(LeafIndex removed) throws Exception return Proposal.remove(removed); } - private void updateEpochSecrets(byte[] commitSecret, List psks, byte[] forceInitSecret) throws Exception + private void updateEpochSecrets(byte[] commitSecret, List psks, byte[] forceInitSecret) + throws Exception { byte[] ctx = MLSOutputStream.encode(new GroupContext( - suite, - groupID, - epoch, - tree.getRootHash(), - transcriptHash.getConfirmed(), - extensions + suite, + groupID, + epoch, + tree.getRootHash(), + transcriptHash.getConfirmed(), + extensions )); keySchedule = keySchedule.next(tree.getSize(), forceInitSecret, new Secret(commitSecret), psks, ctx); keys = keySchedule.getEncryptionKeys(tree.getSize()); } - private JoinersWithPSKS apply(List proposals) throws Exception + private JoinersWithPSKS apply(List proposals) + throws Exception { applyUpdate(proposals); applyRemove(proposals); @@ -1551,9 +1610,10 @@ private JoinersWithPSKS apply(List proposals) throws Exception return new JoinersWithPSKS(joinerLocs, psks); } - private void applyUpdate(List proposals) throws Exception + private void applyUpdate(List proposals) + throws Exception { - for (CachedProposal cached: proposals) + for (CachedProposal cached : proposals) { if (cached.proposal.getProposalType() != ProposalType.UPDATE) { @@ -1609,9 +1669,10 @@ private boolean extensionsSupported(List exts) return true; } - private void applyGCE(List proposals) throws Exception + private void applyGCE(List proposals) + throws Exception { - for (CachedProposal cached: proposals) + for (CachedProposal cached : proposals) { if (cached.proposal.getProposalType() != ProposalType.GROUP_CONTEXT_EXTENSIONS) { @@ -1625,13 +1686,15 @@ private void applyGCE(List proposals) throws Exception { throw new Exception("Unsupported extensions in GroupContextExtensions"); } - extensions = new ArrayList<>(cached.proposal.getGroupContextExtensions().extensions); + extensions = new ArrayList(cached.proposal.getGroupContextExtensions().extensions); } } - private List applyPSK(List proposals) throws Exception + + private List applyPSK(List proposals) + throws Exception { - List pskIDs = new ArrayList<>(); - for (CachedProposal cached: proposals) + List pskIDs = new ArrayList(); + for (CachedProposal cached : proposals) { if (cached.proposal.getProposalType() != ProposalType.PSK) { @@ -1642,10 +1705,11 @@ private List applyPSK(List propo } return resolve(pskIDs); } + private List applyAdd(List proposals) { - List locations = new ArrayList<>(); - for (CachedProposal cached: proposals) + List locations = new ArrayList(); + for (CachedProposal cached : proposals) { if (cached.proposal.getProposalType() != ProposalType.ADD) { @@ -1655,16 +1719,18 @@ private List applyAdd(List proposals) } return locations; } - private void applyRemove(List proposals) throws Exception + + private void applyRemove(List proposals) + throws Exception { - for (CachedProposal cached: proposals) + for (CachedProposal cached : proposals) { if (cached.proposal.getProposalType() != ProposalType.REMOVE) { continue; } - if(!tree.hasLeaf(cached.proposal.getRemove().removed)) + if (!tree.hasLeaf(cached.proposal.getRemove().removed)) { throw new Exception("Attempt to remove non-member"); } @@ -1673,26 +1739,26 @@ private void applyRemove(List proposals) throws Exception } } - private Group successor() throws IOException + private Group successor() + throws IOException { Group next = new Group(); - //TODO: check which needs to be deep copied - next.externalPSKs = new HashMap<>(externalPSKs); - next.resumptionPSKs = new HashMap<>(); + next.externalPSKs = new HashMap(externalPSKs); + next.resumptionPSKs = new HashMap(); next.resumptionPSKs.putAll(resumptionPSKs); next.epoch = epoch; next.groupID = groupID.clone(); next.transcriptHash = transcriptHash.copy(); - next.extensions = new ArrayList<>(); + next.extensions = new ArrayList(); next.extensions.addAll(extensions); - next.keySchedule = keySchedule; // check + next.keySchedule = keySchedule; next.tree = TreeKEMPublicKey.clone(tree); next.treePriv = treePriv.copy(); - next.keys = keys; // check + next.keys = keys; next.suite = suite; next.index = index; next.identitySk = identitySk.clone(); - next.pendingProposals = new ArrayList<>(); + next.pendingProposals = new ArrayList(); next.cachedUpdate = cachedUpdate; next.resumptionPSKs.put(new EpochRef(groupID, epoch), keySchedule.resumptionPSK.value().clone()); @@ -1707,17 +1773,17 @@ private boolean pathRequired(List proposals) { return true; } - for (CachedProposal cached: proposals) + for (CachedProposal cached : proposals) { switch (cached.proposal.getProposalType()) { - case UPDATE: - case REMOVE: - case EXTERNAL_INIT: - case GROUP_CONTEXT_EXTENSIONS: - return true; - default: - break; + case UPDATE: + case REMOVE: + case EXTERNAL_INIT: + case GROUP_CONTEXT_EXTENSIONS: + return true; + default: + break; } } return false; @@ -1728,12 +1794,13 @@ public byte[] getEpochAuthenticator() return keySchedule.epochAuthenticator.value(); } - private void cacheProposal(AuthenticatedContent auth) throws Exception + private void cacheProposal(AuthenticatedContent auth) + throws Exception { byte[] ref = suite.refHash(MLSOutputStream.encode(auth), "MLS 1.0 Proposal Reference"); // check if ref is already in the queue - for (CachedProposal cached: pendingProposals) + for (CachedProposal cached : pendingProposals) { if (Arrays.equals(cached.proposalRef, ref)) { @@ -1752,31 +1819,31 @@ private void cacheProposal(AuthenticatedContent auth) throws Exception { throw new Exception("Invalid proposal"); } - //TODO: check if ref should be recalculated pendingProposals.add(new CachedProposal(ref, proposal, senderLocation)); } - private boolean validateProposal(LeafIndex sender, Proposal proposal) throws IOException + private boolean validateProposal(LeafIndex sender, Proposal proposal) + throws IOException { switch (proposal.getProposalType()) { - case UPDATE: - return validateUpdate(sender, proposal.getUpdate()); - case ADD: - return validateKeyPackage(proposal.getAdd().keyPackage); - case REMOVE: - return validateRemove(proposal.getRemove()); - case PSK: - return validatePSK(proposal.getPreSharedKey()); - case REINIT: - return validateReinit(proposal.getReInit()); - case EXTERNAL_INIT: - return validateExternalInit(proposal.getExternalInit()); - case GROUP_CONTEXT_EXTENSIONS: - return validateGCE(proposal.getGroupContextExtensions()); - default: - return false; + case UPDATE: + return validateUpdate(sender, proposal.getUpdate()); + case ADD: + return validateKeyPackage(proposal.getAdd().keyPackage); + case REMOVE: + return validateRemove(proposal.getRemove()); + case PSK: + return validatePSK(proposal.getPreSharedKey()); + case REINIT: + return validateReinit(proposal.getReInit()); + case EXTERNAL_INIT: + return validateExternalInit(proposal.getExternalInit()); + case GROUP_CONTEXT_EXTENSIONS: + return validateGCE(proposal.getGroupContextExtensions()); + default: + return false; } } @@ -1799,10 +1866,12 @@ private boolean validateGCE(Proposal.GroupContextExtensions gce) } return true; } + private boolean validateExternalInit(Proposal.ExternalInit ext) { return ext.kemOutput.length == suite.getHPKE().getEncSize(); } + private boolean validateReinit(Proposal.ReInit reInit) { // Check that the version and CipherSuite are ones we support @@ -1821,26 +1890,27 @@ private boolean validateReinitProposals(List proposals) hasReinit = hasReinit || cached.proposal.getProposalType() == ProposalType.REINIT; hasDisallowed = hasDisallowed || cached.proposal.getProposalType() != ProposalType.REINIT; } - return hasReinit && !hasDisallowed; + return hasReinit && !hasDisallowed; } + private boolean validatePSK(Proposal.PreSharedKey psk) { switch (psk.psk.pskType) { - case EXTERNAL: - // External PSKs are allowed if we have the corresponding secret - return externalPSKs.containsKey(psk.psk.external.externalPSKID); - case RESUMPTION: - // Resumption PSKs are allowed only with usage 'application', and only if we - // have the corresponding secret. - PreSharedKeyID.Resumption res = psk.psk.resumption; - if (res.resumptionPSKUsage != ResumptionPSKUsage.APPLICATION) - { - return false; - } - return (res.pskEpoch == epoch) || resumptionPSKs.containsKey(new EpochRef(res.pskGroupID, res.pskEpoch)); - default: + case EXTERNAL: + // External PSKs are allowed if we have the corresponding secret + return externalPSKs.containsKey(psk.psk.external.externalPSKID); + case RESUMPTION: + // Resumption PSKs are allowed only with usage 'application', and only if we + // have the corresponding secret. + PreSharedKeyID.Resumption res = psk.psk.resumption; + if (res.resumptionPSKUsage != ResumptionPSKUsage.APPLICATION) + { return false; + } + return (res.pskEpoch == epoch) || resumptionPSKs.containsKey(new EpochRef(res.pskGroupID, res.pskEpoch)); + default: + return false; } } @@ -1849,13 +1919,13 @@ private boolean validateRemove(Proposal.Remove remove) // We mark self-removes invalid here even though a resync Commit will // sometimes cause them. This is OK because this method is only called from // the normal proposal list validation method, not the external commit one. - //TODO: check if tree size leafCount or tree size Width boolean in_tree = (remove.removed.value() < tree.getSize().leafCount()) && tree.hasLeaf(remove.removed); boolean not_me = remove.removed.value() != index.value(); return in_tree && not_me; } - private boolean validateKeyPackage(KeyPackage keyPackage) throws IOException + private boolean validateKeyPackage(KeyPackage keyPackage) + throws IOException { // Verify that the ciphersuite and protocol version of the KeyPackage match // those in the GroupContext. @@ -1863,7 +1933,6 @@ private boolean validateKeyPackage(KeyPackage keyPackage) throws IOException // Verify that the signature on the KeyPackage is valid using the public key // in leaf_node.credential. - //TODO: check why these are false: valid_signature and leaf_node_valid boolean valid_signature = keyPackage.verify(); // Verify that the leaf_node of the KeyPackage is valid for a KeyPackage @@ -1876,7 +1945,9 @@ private boolean validateKeyPackage(KeyPackage keyPackage) throws IOException return (correct_ciphersuite && valid_signature && leaf_node_valid && distinct_keys); } - private boolean validateUpdate(LeafIndex sender, Proposal.Update update) throws IOException + + private boolean validateUpdate(LeafIndex sender, Proposal.Update update) + throws IOException { LeafNode leaf = tree.getLeafNode(sender); if (leaf == null) @@ -1887,7 +1958,8 @@ private boolean validateUpdate(LeafIndex sender, Proposal.Update update) throws return validateLeafNode(update.getLeafNode(), LeafNodeSource.UPDATE, sender); } - private boolean validateLeafNode(LeafNode leafNode, LeafNodeSource requiredSource, LeafIndex index) throws IOException + private boolean validateLeafNode(LeafNode leafNode, LeafNodeSource requiredSource, LeafIndex index) + throws IOException { //TODO: Check all verifications are covered in (https://www.ietf.org/archive/id/draft-ietf-mls-protocol-20.html#section-7.3) @@ -1901,13 +1973,13 @@ private boolean validateLeafNode(LeafNode leafNode, LeafNodeSource requiredSourc byte[] tbs; switch (requiredSource) { - case UPDATE: - case COMMIT: - tbs = leafNode.toBeSigned(groupID, index.value()); - break; - default: - tbs = leafNode.toBeSigned(null, -1); - break; + case UPDATE: + case COMMIT: + tbs = leafNode.toBeSigned(groupID, index.value()); + break; + default: + tbs = leafNode.toBeSigned(null, -1); + break; } boolean isSignatureValid = leafNode.verify(suite, tbs); @@ -1921,7 +1993,7 @@ private boolean validateLeafNode(LeafNode leafNode, LeafNodeSource requiredSourc // = leafNode.verifyExtensionSupport(extensions); // Verify the lifetime - boolean isLifetimeValid = leafNode.verifyLifetime(); // TODO: check if needed (RECOMMENDED) + boolean isLifetimeValid = leafNode.verifyLifetime(); //TODO: @@ -1955,7 +2027,6 @@ private boolean validateLeafNode(LeafNode leafNode, LeafNodeSource requiredSourc } - //TODO: // Verify that the extensions in the LeafNode are supported // by checking that the ID for each extension in the extensions field is listed in the @@ -1967,24 +2038,26 @@ private boolean validateLeafNode(LeafNode leafNode, LeafNodeSource requiredSourc } return (isCorrectSource && isSignatureValid && isLifetimeValid && supportsAllExtensions - && isUniqueSigKey && isUniqueEncKey && mutualCredentialSupport && supportsGroupExtensions); + && isUniqueSigKey && isUniqueEncKey && mutualCredentialSupport && supportsGroupExtensions); } - private boolean validateCachedProposals(List proposals, LeafIndex commitSender, CommitParameters params) throws IOException + private boolean validateCachedProposals(List proposals, LeafIndex commitSender, CommitParameters params) + throws IOException { switch (params.paramID) { - case NORMAL_COMMIT_PARAMS: - return validateNormalCachedProposals(proposals, commitSender); - case EXTERNAL_COMMIT_PARAMS: - return validateExternalCachedProposals(proposals); - case RESTART_COMMIT_PARAMS: - return validateRestartCachedProposals(proposals, params.allowedUsage); - case REINIT_COMMIT_PARAMS: - return validateReInitCachedProposals(proposals); + case NORMAL_COMMIT_PARAMS: + return validateNormalCachedProposals(proposals, commitSender); + case EXTERNAL_COMMIT_PARAMS: + return validateExternalCachedProposals(proposals); + case RESTART_COMMIT_PARAMS: + return validateRestartCachedProposals(proposals, params.allowedUsage); + case REINIT_COMMIT_PARAMS: + return validateReInitCachedProposals(proposals); } return false; } + private boolean validateReInitCachedProposals(List proposals) { // Check that the list contains a ReInit proposal @@ -2001,6 +2074,7 @@ private boolean validateReInitCachedProposals(List proposals) return has_reinit && !has_disallowed; } + private boolean validateRestartCachedProposals(List proposals, ResumptionPSKUsage allowedUsage) { // Check that the list has exactly one resumption PSK proposal with the @@ -2030,9 +2104,10 @@ private boolean validateRestartCachedProposals(List proposals, R } return acceptable_psks && foundAllowed; } - private boolean validateNormalCachedProposals(List proposals, LeafIndex commitSender) throws IOException + + private boolean validateNormalCachedProposals(List proposals, LeafIndex commitSender) + throws IOException { - //TODO: use Java 8 streams? // It contains an individual proposal that is invalid as specified in Section // 12.1. boolean has_invalid_proposal = false; @@ -2054,21 +2129,21 @@ private boolean validateNormalCachedProposals(List proposals, Le // leaf. If the committer has received multiple such proposals they SHOULD // prefer any Remove received, or the most recent Update if there are no // Removes. - Set updatedOrRemoved = new HashSet<>(); + Set updatedOrRemoved = new HashSet(); boolean has_dup_update_remove = false; for (CachedProposal cached : proposals) { LeafIndex leafIndex; switch (cached.proposal.getProposalType()) { - case UPDATE: - leafIndex = cached.sender; - break; - case REMOVE: - leafIndex = cached.proposal.getRemove().removed; - break; - default: - continue; + case UPDATE: + leafIndex = cached.sender; + break; + case REMOVE: + leafIndex = cached.proposal.getRemove().removed; + break; + default: + continue; } if (updatedOrRemoved.contains(leafIndex)) { @@ -2082,7 +2157,7 @@ private boolean validateNormalCachedProposals(List proposals, Le // It contains multiple Add proposals that contain KeyPackages that represent // the same client according to the application (for example, identical // signature keys). - List signatureKeys = new ArrayList<>(); + List signatureKeys = new ArrayList(); boolean has_dup_signature_key = false; for (CachedProposal cached : proposals) { @@ -2095,7 +2170,7 @@ private boolean validateNormalCachedProposals(List proposals, Le boolean areEqual = false; for (byte[] sig : signatureKeys) { - if(Arrays.equals(sig, signatureKey)) + if (Arrays.equals(sig, signatureKey)) { areEqual = true; break; @@ -2117,8 +2192,7 @@ private boolean validateNormalCachedProposals(List proposals, Le // It contains multiple PreSharedKey proposals that reference the same // PreSharedKeyID. - //TODO: how to compare PSK id - List pskids = new ArrayList<>(); + List pskids = new ArrayList(); boolean has_dup_psk_id = false; for (CachedProposal cached : proposals) { @@ -2142,7 +2216,7 @@ private boolean validateNormalCachedProposals(List proposals, Le { if (cached.proposal.getProposalType() == ProposalType.GROUP_CONTEXT_EXTENSIONS) { - gceCount++; + gceCount++; } } boolean has_multiple_gce = (gceCount > 1); @@ -2178,27 +2252,27 @@ private boolean validateNormalCachedProposals(List proposals, Le // uniqueness of encryption keys across the Adds and Updates in this list of // proposals. The keys have already been checked to be distinct from any keys // already in the tree. - List encKeys = new ArrayList<>(); + List encKeys = new ArrayList(); boolean has_dup_enc_key = false; for (CachedProposal cached : proposals) { byte[] encKey; switch (cached.proposal.getProposalType()) { - case ADD: - encKey = cached.proposal.getAdd().keyPackage.getLeafNode().getEncryptionKey().clone(); - break; - case UPDATE: - encKey = cached.proposal.getUpdate().getLeafNode().getEncryptionKey().clone(); - break; - default: - continue; + case ADD: + encKey = cached.proposal.getAdd().keyPackage.getLeafNode().getEncryptionKey().clone(); + break; + case UPDATE: + encKey = cached.proposal.getUpdate().getLeafNode().getEncryptionKey().clone(); + break; + default: + continue; } boolean areEqual = false; for (byte[] key : encKeys) { - if(Arrays.equals(key, encKey)) + if (Arrays.equals(key, encKey)) { areEqual = true; break; @@ -2214,10 +2288,11 @@ private boolean validateNormalCachedProposals(List proposals, Le } return !(has_invalid_proposal || has_self_update || has_self_remove || - has_dup_update_remove || has_dup_signature_key || has_dup_psk_id || - has_multiple_gce || has_reinit || has_external_init || - has_dup_enc_key); + has_dup_update_remove || has_dup_signature_key || has_dup_psk_id || + has_multiple_gce || has_reinit || has_external_init || + has_dup_enc_key); } + private boolean validateExternalCachedProposals(List proposals) { int extInitCount = 0; @@ -2228,18 +2303,18 @@ private boolean validateExternalCachedProposals(List proposals) switch (cached.proposal.getProposalType()) { - case EXTERNAL_INIT: - extInitCount++; - break; - case REMOVE: - removeCount++; - break; - case PSK: - noDisallowed = noDisallowed && validatePSK(cached.proposal.getPreSharedKey()); - break; - default: - noDisallowed = false; - break; + case EXTERNAL_INIT: + extInitCount++; + break; + case REMOVE: + removeCount++; + break; + case PSK: + noDisallowed = noDisallowed && validatePSK(cached.proposal.getPreSharedKey()); + break; + default: + noDisallowed = false; + break; } } boolean hasOneExtInit = (extInitCount == 1); @@ -2250,35 +2325,37 @@ private boolean validateExternalCachedProposals(List proposals) private List mustResolve(List proposals, LeafIndex sender) { - List out = new ArrayList<>(); + List out = new ArrayList(); for (ProposalOrRef id : proposals) { switch (id.getType()) { - case PROPOSAL: - out.add(new CachedProposal(new byte[0], id.getProposal(), sender)); - break; - case REFERENCE: - for (CachedProposal cached : pendingProposals) + case PROPOSAL: + out.add(new CachedProposal(new byte[0], id.getProposal(), sender)); + break; + case REFERENCE: + for (CachedProposal cached : pendingProposals) + { + if (Arrays.equals(cached.proposalRef, id.getReference())) { - if (Arrays.equals(cached.proposalRef, id.getReference())) - { - out.add(cached); - break; - } + out.add(cached); + break; } - break; + } + break; } } return out; } - private GroupContext getGroupContext() throws Exception + private GroupContext getGroupContext() + throws Exception { return new GroupContext(suite, groupID, epoch, tree.getRootHash(), transcriptHash.getConfirmed(), extensions); } - private TreeKEMPublicKey importTree(byte[] treeHash, TreeKEMPublicKey external, List extensions) throws Exception + private TreeKEMPublicKey importTree(byte[] treeHash, TreeKEMPublicKey external, List extensions) + throws Exception { // Check if extensions contain a ratchet tree TreeKEMPublicKey outTree = null; @@ -2292,7 +2369,6 @@ private TreeKEMPublicKey importTree(byte[] treeHash, TreeKEMPublicKey external, } if (external != null) { - //TODO: check if it should be a deep copy outTree = external; } else if (outTree == null) @@ -2315,35 +2391,36 @@ else if (outTree == null) return outTree; } - private List resolve(List psks) throws Exception + private List resolve(List psks) + throws Exception { - List out = new ArrayList<>(); + List out = new ArrayList(); for (PreSharedKeyID psk : psks) { switch (psk.pskType) { - case EXTERNAL: - if (!externalPSKs.containsKey(psk.external.externalPSKID)) - { - throw new Exception("Unknown external PSK"); - } - out.add(new KeyScheduleEpoch.PSKWithSecret(psk, new Secret(externalPSKs.get(psk.external.externalPSKID).clone()))); - break; - case RESUMPTION: - if (psk.resumption.pskEpoch == epoch) - { - out.add(new KeyScheduleEpoch.PSKWithSecret(psk, keySchedule.resumptionPSK)); - } - else + case EXTERNAL: + if (!externalPSKs.containsKey(psk.external.externalPSKID)) + { + throw new Exception("Unknown external PSK"); + } + out.add(new KeyScheduleEpoch.PSKWithSecret(psk, new Secret(externalPSKs.get(psk.external.externalPSKID).clone()))); + break; + case RESUMPTION: + if (psk.resumption.pskEpoch == epoch) + { + out.add(new KeyScheduleEpoch.PSKWithSecret(psk, keySchedule.resumptionPSK)); + } + else + { + EpochRef key = new EpochRef(psk.resumption.pskGroupID, psk.resumption.pskEpoch); + if (!resumptionPSKs.containsKey(key)) { - EpochRef key = new EpochRef(psk.resumption.pskGroupID, psk.resumption.pskEpoch); - if (!resumptionPSKs.containsKey(key)) - { - throw new Exception("Unknown resumption PSK"); - } - out.add(new KeyScheduleEpoch.PSKWithSecret(psk, new Secret(resumptionPSKs.get(key).clone()))); + throw new Exception("Unknown resumption PSK"); } - break; + out.add(new KeyScheduleEpoch.PSKWithSecret(psk, new Secret(resumptionPSKs.get(key).clone()))); + } + break; } } return out; diff --git a/mls/src/main/jdk1.9/module-info.java b/mls/src/main/jdk1.9/module-info.java new file mode 100644 index 0000000000..836725fd4c --- /dev/null +++ b/mls/src/main/jdk1.9/module-info.java @@ -0,0 +1,14 @@ +module org.bouncycastle.mls +{ + requires java.logging; + requires org.bouncycastle.provider; + requires org.bouncycastle.util; + requires org.bouncycastle.pkix; + + exports org.bouncycastle.mls; + exports org.bouncycastle.mls.client; + exports org.bouncycastle.mls.protocol; + exports org.bouncycastle.mls.codec; + exports org.bouncycastle.mls.crypto; + exports org.bouncycastle.mls.crypto.bc; +} diff --git a/mls/src/test/java/org/bouncycastle/mls/test/AllTests.java b/mls/src/test/java/org/bouncycastle/mls/test/AllTests.java new file mode 100644 index 0000000000..9a9147c48d --- /dev/null +++ b/mls/src/test/java/org/bouncycastle/mls/test/AllTests.java @@ -0,0 +1,46 @@ +package org.bouncycastle.mls.test; + +import junit.extensions.TestSetup; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.bouncycastle.test.PrintTestResult; + +public class AllTests + extends TestCase +{ + public static void main(String[] args) + { + PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); + } + + public static Test suite() + { + TestSuite suite = new TestSuite("MLS Tests"); + + suite.addTestSuite(ClientVectorTest.class); + suite.addTestSuite(MessageProtectionTest.class); + suite.addTestSuite(VectorTest.class); + + return new BCTestSetup(suite); + } + + static class BCTestSetup + extends TestSetup + { + public BCTestSetup(Test test) + { + super(test); + } + + protected void setUp() + { + + } + + protected void tearDown() + { + + } + } +} diff --git a/mls/src/test/java/org/bouncycastle/mls/test/ClientVectorTest.java b/mls/src/test/java/org/bouncycastle/mls/test/ClientVectorTest.java index 41e0451fed..4b96ccc867 100644 --- a/mls/src/test/java/org/bouncycastle/mls/test/ClientVectorTest.java +++ b/mls/src/test/java/org/bouncycastle/mls/test/ClientVectorTest.java @@ -1,26 +1,27 @@ package org.bouncycastle.mls.test; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; + import junit.framework.TestCase; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.mls.TreeKEM.TreeKEMPublicKey; -import org.bouncycastle.mls.crypto.MlsCipherSuite; -import org.bouncycastle.mls.protocol.Group; import org.bouncycastle.mls.codec.MLSInputStream; import org.bouncycastle.mls.codec.MLSMessage; import org.bouncycastle.mls.codec.PreSharedKeyID; +import org.bouncycastle.mls.crypto.MlsCipherSuite; import org.bouncycastle.mls.crypto.Secret; +import org.bouncycastle.mls.protocol.Group; +import org.bouncycastle.test.TestResourceFinder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Stack; - public class ClientVectorTest extends TestCase { @@ -71,12 +72,12 @@ private void runPassiveClientTest(String filename) InputStream src = TestResourceFinder.findTestResource("mls/passiveClient/", filename); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); String line; - HashMap buf = new HashMap<>(); - Stack readingStack = new Stack<>(); + HashMap buf = new HashMap(); + Stack readingStack = new Stack(); int count = 0; - ArrayList externalPSKs = new ArrayList<>(); - List proposals = new ArrayList<>(); + ArrayList externalPSKs = new ArrayList(); + List proposals = new ArrayList(); class Epoch { List proposals; @@ -85,12 +86,12 @@ class Epoch public Epoch(List proposals, byte[] commit, byte[] epoch_authenticator) { - this.proposals = new ArrayList<>(proposals); + this.proposals = new ArrayList(proposals); this.commit = commit; this.epoch_authenticator = epoch_authenticator; } } - List epochs = new ArrayList<>(); + List epochs = new ArrayList(); while((line = bin.readLine())!= null) @@ -112,7 +113,7 @@ public Epoch(List proposals, byte[] commit, byte[] epoch_authenticator) { // try // { - System.out.print("test case: " + count); + // System.out.print("test case: " + count); short cipherSuite = Short.parseShort(buf.get("cipher_suite")); byte[] key_package = Hex.decode(buf.get("key_package")); byte[] signature_priv = Hex.decode(buf.get("signature_priv")); @@ -134,7 +135,7 @@ public Epoch(List proposals, byte[] commit, byte[] epoch_authenticator) MlsCipherSuite suite = MlsCipherSuite.getSuite(cipherSuite); AsymmetricCipherKeyPair leafKeyPair = suite.getHPKE().deserializePrivateKey(encryption_priv, null); - Map externalPsks = new HashMap<>(); + Map externalPsks = new HashMap(); for (PreSharedKeyID ext : externalPSKs) { externalPsks.put(ext.external.externalPSKID, ext.pskNonce); @@ -167,7 +168,7 @@ public Epoch(List proposals, byte[] commit, byte[] epoch_authenticator) welcomeMsg.welcome, tree, externalPsks, - new HashMap<>() + new HashMap() ); assertTrue(Arrays.areEqual(group.getEpochAuthenticator(), initial_epoch_authenticator)); @@ -188,7 +189,7 @@ public Epoch(List proposals, byte[] commit, byte[] epoch_authenticator) epochs.clear(); buf.clear(); count++; - System.out.println(" PASSED"); + // System.out.println(" PASSED"); // } // catch (Exception e) // { diff --git a/mls/src/test/java/org/bouncycastle/mls/test/MessageProtectionTest.java b/mls/src/test/java/org/bouncycastle/mls/test/MessageProtectionTest.java index 811411b20f..4d594cee3b 100644 --- a/mls/src/test/java/org/bouncycastle/mls/test/MessageProtectionTest.java +++ b/mls/src/test/java/org/bouncycastle/mls/test/MessageProtectionTest.java @@ -1,13 +1,24 @@ package org.bouncycastle.mls.test; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; + import junit.framework.TestCase; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.digests.SHA384Digest; +import org.bouncycastle.crypto.digests.SHA512Digest; +import org.bouncycastle.crypto.hpke.HPKE; import org.bouncycastle.mls.GroupKeySet; import org.bouncycastle.mls.TreeKEM.LeafIndex; import org.bouncycastle.mls.TreeSize; import org.bouncycastle.mls.codec.AuthenticatedContent; import org.bouncycastle.mls.codec.ContentType; +import org.bouncycastle.mls.codec.Extension; import org.bouncycastle.mls.codec.FramedContent; import org.bouncycastle.mls.codec.GroupContext; import org.bouncycastle.mls.codec.MLSInputStream; @@ -18,20 +29,25 @@ import org.bouncycastle.mls.codec.Sender; import org.bouncycastle.mls.codec.WireFormat; import org.bouncycastle.mls.crypto.MlsCipherSuite; +import org.bouncycastle.mls.crypto.MlsSigner; import org.bouncycastle.mls.crypto.Secret; +import org.bouncycastle.mls.crypto.bc.BcMlsAead; +import org.bouncycastle.mls.crypto.bc.BcMlsKdf; +import org.bouncycastle.mls.crypto.bc.BcMlsSigner; +import org.bouncycastle.test.TestResourceFinder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.HashMap; +import static org.bouncycastle.mls.crypto.MlsCipherSuite.MLS_128_DHKEMP256_AES128GCM_SHA256_P256; +import static org.bouncycastle.mls.crypto.MlsCipherSuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; +import static org.bouncycastle.mls.crypto.MlsCipherSuite.MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519; +import static org.bouncycastle.mls.crypto.MlsCipherSuite.MLS_256_DHKEMP384_AES256GCM_SHA384_P384; +import static org.bouncycastle.mls.crypto.MlsCipherSuite.MLS_256_DHKEMP521_AES256GCM_SHA512_P521; +import static org.bouncycastle.mls.crypto.MlsCipherSuite.MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448; +import static org.bouncycastle.mls.crypto.MlsCipherSuite.MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448; public class MessageProtectionTest extends TestCase - { short cipher_suite; byte[] group_id; @@ -111,7 +127,7 @@ private void protect(byte[] content, MLSMessage message) throws Exception } - private FramedContent unprotect(MLSMessage message) throws IOException, IllegalAccessException, InvalidCipherTextException + private FramedContent unprotect(MLSMessage message) throws Exception { AuthenticatedContent auth; switch (message.wireFormat) @@ -139,6 +155,35 @@ private GroupKeySet getKeys() throws IOException, IllegalAccessException return new GroupKeySet(suite, treeSize, encryptedSecret); } + private MlsCipherSuite createNewSuite(short id) + { + switch (id) + { + case MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519: + return new MlsCipherSuite(MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519, new BcMlsSigner(MlsSigner.ed25519), new BcMlsKdf(new SHA256Digest()), new BcMlsAead(HPKE.aead_AES_GCM128), new HPKE(HPKE.mode_base, HPKE.kem_X25519_SHA256, HPKE.kdf_HKDF_SHA256, HPKE.aead_AES_GCM128)); + + case MLS_128_DHKEMP256_AES128GCM_SHA256_P256: + return new MlsCipherSuite(MLS_128_DHKEMP256_AES128GCM_SHA256_P256, new BcMlsSigner(MlsSigner.ecdsa_secp256r1_sha256), new BcMlsKdf(new SHA256Digest()), new BcMlsAead(HPKE.aead_AES_GCM128), new HPKE(HPKE.mode_base, HPKE.kem_P256_SHA256, HPKE.kdf_HKDF_SHA256, HPKE.aead_AES_GCM128)); + + case MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519: + return new MlsCipherSuite(MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519, new BcMlsSigner(MlsSigner.ed25519), new BcMlsKdf(new SHA256Digest()), new BcMlsAead(HPKE.aead_CHACHA20_POLY1305), new HPKE(HPKE.mode_base, HPKE.kem_X25519_SHA256, HPKE.kdf_HKDF_SHA256, HPKE.aead_CHACHA20_POLY1305)); + + case MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448: + return new MlsCipherSuite(MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448, new BcMlsSigner(MlsSigner.ed448), new BcMlsKdf(new SHA512Digest()), new BcMlsAead(HPKE.aead_AES_GCM256), new HPKE(HPKE.mode_base, HPKE.kem_X448_SHA512, HPKE.kdf_HKDF_SHA512, HPKE.aead_AES_GCM256)); + + case MLS_256_DHKEMP521_AES256GCM_SHA512_P521: + return new MlsCipherSuite(MLS_256_DHKEMP521_AES256GCM_SHA512_P521, new BcMlsSigner(MlsSigner.ecdsa_secp521r1_sha512), new BcMlsKdf(new SHA512Digest()), new BcMlsAead(HPKE.aead_AES_GCM256), new HPKE(HPKE.mode_base, HPKE.kem_P521_SHA512, HPKE.kdf_HKDF_SHA512, HPKE.aead_AES_GCM256)); + + case MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448: + return new MlsCipherSuite(MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448, new BcMlsSigner(MlsSigner.ed448), new BcMlsKdf(new SHA512Digest()), new BcMlsAead(HPKE.aead_CHACHA20_POLY1305), new HPKE(HPKE.mode_base, HPKE.kem_X448_SHA512, HPKE.kdf_HKDF_SHA512, HPKE.aead_CHACHA20_POLY1305)); + + case MLS_256_DHKEMP384_AES256GCM_SHA384_P384: + return new MlsCipherSuite(MLS_256_DHKEMP384_AES256GCM_SHA384_P384, new BcMlsSigner(MlsSigner.ecdsa_secp384r1_sha384), new BcMlsKdf(new SHA384Digest()), new BcMlsAead(HPKE.aead_AES_GCM256), new HPKE(HPKE.mode_base, HPKE.kem_P384_SHA348, HPKE.kdf_HKDF_SHA384, HPKE.aead_AES_GCM256)); + + } + return null; + } + public void testMessageProtection() @@ -157,7 +202,7 @@ public void testMessageProtection() { if (buf.size() > 0) { - System.out.println("test case: " + count); + // System.out.println("test case: " + count); cipher_suite = Short.parseShort(buf.get("cipher_suite")); group_id = Hex.decode(buf.get("group_id")); epoch = Long.parseLong(buf.get("epoch")); @@ -177,7 +222,7 @@ public void testMessageProtection() application = Hex.decode(buf.get("application")); application_priv = Hex.decode(buf.get("application_priv")); - suite = MlsCipherSuite.getSuite(cipher_suite); + suite = createNewSuite(cipher_suite); AsymmetricCipherKeyPair sigKeyPair = suite.deserializeSignaturePrivateKey(signature_priv); byte[] sigPubBytes = suite.serializeSignaturePublicKey(sigKeyPair.getPublic()); @@ -193,7 +238,7 @@ public void testMessageProtection() epoch, tree_hash, confirmed_transcript_hash, - new ArrayList<>() + new ArrayList() ); groupContextBytes = MLSOutputStream.encode(groupContext); @@ -242,6 +287,7 @@ public void testMessageProtection() FramedContent commitPubProtectedUnprotected = unprotect(commitPub); assertTrue(Arrays.areEqual(commitPubProtectedUnprotected.getContentBytes(), commit)); + suite = createNewSuite(cipher_suite); // reset AEAD protect(commit, commitPriv); // commitPriv = commitPrivProtected FramedContent commitPrivProtectedUnprotected = unprotect(commitPriv); assertTrue(Arrays.areEqual(commitPrivProtectedUnprotected.getContentBytes(), commit)); diff --git a/mls/src/test/java/org/bouncycastle/mls/test/VectorTest.java b/mls/src/test/java/org/bouncycastle/mls/test/VectorTest.java index fb6ca193b8..64030598b3 100644 --- a/mls/src/test/java/org/bouncycastle/mls/test/VectorTest.java +++ b/mls/src/test/java/org/bouncycastle/mls/test/VectorTest.java @@ -1,43 +1,47 @@ package org.bouncycastle.mls.test; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import junit.framework.TestCase; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.mls.*; import org.bouncycastle.mls.GroupKeySet; +import org.bouncycastle.mls.KeyGeneration; +import org.bouncycastle.mls.KeyScheduleEpoch; +import org.bouncycastle.mls.TranscriptHash; import org.bouncycastle.mls.TreeKEM.LeafIndex; import org.bouncycastle.mls.TreeKEM.LeafNode; import org.bouncycastle.mls.TreeKEM.NodeIndex; import org.bouncycastle.mls.TreeKEM.TreeKEMPrivateKey; import org.bouncycastle.mls.TreeKEM.TreeKEMPublicKey; -import org.bouncycastle.mls.crypto.MlsCipherSuite; -import org.bouncycastle.mls.protocol.Group; +import org.bouncycastle.mls.TreeSize; import org.bouncycastle.mls.codec.AuthenticatedContent; import org.bouncycastle.mls.codec.Commit; +import org.bouncycastle.mls.codec.Extension; import org.bouncycastle.mls.codec.GroupContext; import org.bouncycastle.mls.codec.GroupInfo; import org.bouncycastle.mls.codec.GroupSecrets; import org.bouncycastle.mls.codec.MLSInputStream; +import org.bouncycastle.mls.codec.MLSMessage; import org.bouncycastle.mls.codec.MLSOutputStream; import org.bouncycastle.mls.codec.PathSecret; +import org.bouncycastle.mls.codec.PreSharedKeyID; import org.bouncycastle.mls.codec.Proposal; import org.bouncycastle.mls.codec.UpdatePath; import org.bouncycastle.mls.codec.WireFormat; +import org.bouncycastle.mls.crypto.MlsCipherSuite; import org.bouncycastle.mls.crypto.Secret; -import org.bouncycastle.mls.codec.MLSMessage; -import org.bouncycastle.mls.codec.PreSharedKeyID; +import org.bouncycastle.mls.protocol.Group; +import org.bouncycastle.test.TestResourceFinder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Pack; import org.bouncycastle.util.encoders.Hex; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import static org.bouncycastle.mls.crypto.MlsCipherSuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; public class VectorTest @@ -67,7 +71,7 @@ public void testTreeMath() { if (buf.size() > 0) { - System.out.println("test case: " + count); + // System.out.println("test case: " + count); long n_leaves = Long.parseLong((String)buf.get("n_leaves")); long n_nodes = Long.parseLong((String)buf.get("n_nodes")); long root = Long.parseLong((String)buf.get("root")); @@ -80,8 +84,8 @@ public void testTreeMath() NodeIndex n = new NodeIndex(i); // ignoring null value checks - assertEquals(left.get(i) == -1 ? i : left.get(i), n.left().value()); - assertEquals(right.get(i) == -1 ? i : right.get(i), n.right().value()); + assertEquals((long)(left.get(i) == -1 ? i : left.get(i)), n.left().value()); + assertEquals((long)(right.get(i) == -1 ? i : right.get(i)), n.right().value()); assertEquals(parent.get(i) == -1 ? n.parent().value() : parent.get(i), n.parent().value()); assertEquals(sibling.get(i) == -1 ? n.sibling().value() : sibling.get(i), n.sibling().value()); } @@ -155,7 +159,7 @@ public void testCryptoBasics() { if (buf.size() > 0) { - System.out.println("test case: " + count); + // System.out.println("test case: " + count); short cipherSuite = Short.parseShort(buf.get("cipherSuite")); String refHash_label = buf.get("refHash_label"); byte[] refHash_value = Hex.decode(buf.get("refHash_value")); @@ -299,7 +303,7 @@ public LeafInfo(int generation, byte[] application_key, byte[] application_nonce { if (buf.size() > 0) { - System.out.println("test case: " + count); + //System.out.println("test case: " + count); short cipher_suite = Short.parseShort(buf.get("cipher_suite")); byte[] encryption_secret = Hex.decode(buf.get("encryption_secret")); byte[] sender_data_secret = Hex.decode(buf.get("sender_data_secret")); @@ -416,7 +420,7 @@ public void testKeySchedule() { if (buf.size() > 0) { - System.out.println("test case: " + count); + // System.out.println("test case: " + count); buf.clear(); bufEpoch.clear(); count++; @@ -477,7 +481,7 @@ public void testKeySchedule() epochCount, tree_hash, confirmed_transcript_hash, - new ArrayList<>() + new ArrayList() ); // Verify that group context matches the provided group_context value byte[] groupContextBytes = MLSOutputStream.encode(groupContext); @@ -562,12 +566,12 @@ public PSK(byte[] psk_id, byte[] psk, byte[] psk_nonce) { if (buf.size() > 0) { - System.out.println("test case: " + count); + // System.out.println("test case: " + count); short cipher_suite = Short.parseShort(buf.get("cipher_suite")); byte[] psk_secret = Hex.decode(buf.get("psk_secret")); MlsCipherSuite suite = MlsCipherSuite.getSuite(cipher_suite); - List pskList = new ArrayList<>(); + List pskList = new ArrayList(); for (PSK psk : psks) { PreSharedKeyID external = PreSharedKeyID.external(psk.psk_id, psk.psk_nonce); @@ -636,7 +640,7 @@ public void testTranscriptHashes() { if (buf.size() > 0) { - System.out.println("test case: " + count); + // System.out.println("test case: " + count); short cipherSuite = Short.parseShort(buf.get("cipher_suite")); byte[] confirmation_key = Hex.decode(buf.get("confirmation_key")); byte[] authenticated_content = Hex.decode(buf.get("authenticated_content")); @@ -682,7 +686,7 @@ public void testWelcome() { if (buf.size() > 0) { - System.out.println("test case: " + count); + // System.out.println("test case: " + count); short cipherSuite = Short.parseShort(buf.get("cipher_suite")); byte[] init_priv = Hex.decode(buf.get("init_priv")); byte[] key_package = Hex.decode(buf.get("key_package")); @@ -711,7 +715,7 @@ public void testWelcome() int kpi = welcomeMessage.welcome.find(kpMessage.keyPackage); assertTrue(kpi != -1); GroupSecrets groupSecrets = welcomeMessage.welcome.decryptSecrets(kpi, init_priv); - GroupInfo groupInfo = welcomeMessage.welcome.decrypt(groupSecrets.joiner_secret, new ArrayList<>()); + GroupInfo groupInfo = welcomeMessage.welcome.decrypt(groupSecrets.joiner_secret, new ArrayList()); boolean verified = groupInfo.verify(suite, signer_pub); assertTrue(verified); @@ -720,7 +724,7 @@ public void testWelcome() KeyScheduleEpoch keySchedule = KeyScheduleEpoch.joiner( suite, groupSecrets.joiner_secret, - new ArrayList<>(), + new ArrayList(), MLSOutputStream.encode(groupContext)); @@ -754,7 +758,7 @@ public void testTreeOperations() throws Exception if (buf.size() > 0) { - System.out.println("test case: " + count); + // System.out.println("test case: " + count); byte[] tree_before = Hex.decode(buf.get("tree_before")); byte[] proposal = Hex.decode(buf.get("proposal")); int proposal_sender = Integer.parseInt(buf.get("proposal_sender")); @@ -812,10 +816,10 @@ public void testTreeValidation() InputStream src = TestResourceFinder.findTestResource("mls/testVectors/", "tree-validation.txt"); BufferedReader bin = new BufferedReader(new InputStreamReader(src)); String line; - HashMap buf = new HashMap<>(); - ArrayList hashes = new ArrayList<>(); - ArrayList> resolution = new ArrayList<>(); - ArrayList temp = new ArrayList<>(); + HashMap buf = new HashMap(); + ArrayList hashes = new ArrayList(); + ArrayList> resolution = new ArrayList>(); + ArrayList temp = new ArrayList(); int count = 0; while((line = bin.readLine())!= null) @@ -825,7 +829,7 @@ public void testTreeValidation() { if (buf.size() > 0) { - System.out.println("test case: " + count); + // System.out.println("test case: " + count); short cipherSuite = Short.parseShort(buf.get("cipher_suite")); byte[] treeBytes = Hex.decode(buf.get("tree")); byte[] group_id = Hex.decode(buf.get("group_id")); @@ -982,12 +986,12 @@ public UpdatePathInfo(LeafIndex sender, UpdatePath updatePath, List HashMap buf = new HashMap(); HashMap bufleaf = new HashMap(); - ArrayList privateLeaves = new ArrayList<>(); - ArrayList plPathSecrets = new ArrayList<>(); + ArrayList privateLeaves = new ArrayList(); + ArrayList plPathSecrets = new ArrayList(); HashMap bufPaths = new HashMap(); - ArrayList updatePaths = new ArrayList<>(); - ArrayList upPathSecrets = new ArrayList<>(); + ArrayList updatePaths = new ArrayList(); + ArrayList upPathSecrets = new ArrayList(); int count = 0; @@ -1011,7 +1015,7 @@ public UpdatePathInfo(LeafIndex sender, UpdatePath updatePath, List { if (buf.size() > 0 && reading.equals(prevReading)) { - System.out.println("test case: " + count); + // System.out.println("test case: " + count); short cipher_suite = Short.parseShort(buf.get("cipher_suite")); byte[] confirmed_transcript_hash = Hex.decode(buf.get("confirmed_transcript_hash")); long epoch = Long.parseLong(buf.get("epoch")); @@ -1039,8 +1043,8 @@ public UpdatePathInfo(LeafIndex sender, UpdatePath updatePath, List } // Import private keys - Map treePrivs = new HashMap<>(); - Map sigPrivs = new HashMap<>(); + Map treePrivs = new HashMap(); + Map sigPrivs = new HashMap(); for (LeafPrivateInfo info : privateLeaves) { @@ -1077,7 +1081,7 @@ public UpdatePathInfo(LeafIndex sender, UpdatePath updatePath, List epoch, treeAfter.getRootHash(), confirmed_transcript_hash, - new ArrayList<>() + new ArrayList() ); byte[] ctx = MLSOutputStream.encode(groupContext); @@ -1089,7 +1093,7 @@ public UpdatePathInfo(LeafIndex sender, UpdatePath updatePath, List continue; } TreeKEMPrivateKey priv = treePrivs.get(to).copy(); - priv.decap(from, treeAfter, ctx, path, new ArrayList<>()); + priv.decap(from, treeAfter, ctx, path, new ArrayList()); assertTrue(Arrays.areEqual(priv.getUpdateSecret().value(), info.commitSecret)); @@ -1106,7 +1110,7 @@ public UpdatePathInfo(LeafIndex sender, UpdatePath updatePath, List byte[] sigPriv = sigPrivs.get(from); TreeKEMPrivateKey newSenderPriv = encapTree.update(from, new Secret(leafSecret), group_id, sigPriv, new Group.LeafNodeOptions()); - UpdatePath newPath = encapTree.encap(newSenderPriv, ctx, new ArrayList<>()); + UpdatePath newPath = encapTree.encap(newSenderPriv, ctx, new ArrayList()); assertTrue(tree.verifyParentHash(from, path)); for (int i = 0; i < encapTree.getSize().leafCount(); i++) @@ -1118,7 +1122,7 @@ public UpdatePathInfo(LeafIndex sender, UpdatePath updatePath, List } TreeKEMPrivateKey priv = treePrivs.get(to).copy(); - priv.decap(from, encapTree, ctx, newPath, new ArrayList<>()); + priv.decap(from, encapTree, ctx, newPath, new ArrayList()); assertTrue(Arrays.areEqual(priv.getUpdateSecret().value(), newSenderPriv.getUpdateSecret().value())); } @@ -1224,7 +1228,7 @@ public void testMessages() throws Exception if (buf.size() > 0) { - System.out.println("test case: " + count); + // System.out.println("test case: " + count); byte[] mls_welcome = Hex.decode(buf.get("mls_welcome")); byte[] mls_group_info = Hex.decode(buf.get("mls_group_info")); byte[] mls_key_package = Hex.decode(buf.get("mls_key_package")); diff --git a/mls/src/test/java/org/bouncycastle/test/PrintTestResult.java b/mls/src/test/java/org/bouncycastle/test/PrintTestResult.java new file mode 100644 index 0000000000..2cca70b227 --- /dev/null +++ b/mls/src/test/java/org/bouncycastle/test/PrintTestResult.java @@ -0,0 +1,36 @@ +package org.bouncycastle.test; + + +import java.util.Enumeration; + +import junit.framework.TestResult; + +public class PrintTestResult +{ + public static void printResult(TestResult result) + { + Enumeration e = result.failures(); + if (e != null) + { + while (e.hasMoreElements()) + { + System.out.println(e.nextElement()); + } + } + + e = result.errors(); + if (e != null) + { + while (e.hasMoreElements()) + { + System.out.println(e.nextElement()); + } + } + + if (!result.wasSuccessful()) + { + System.exit(1); + } + } +} + diff --git a/mls/src/test/java/org/bouncycastle/mls/test/TestResourceFinder.java b/mls/src/test/java/org/bouncycastle/test/TestResourceFinder.java similarity index 97% rename from mls/src/test/java/org/bouncycastle/mls/test/TestResourceFinder.java rename to mls/src/test/java/org/bouncycastle/test/TestResourceFinder.java index 4a222c3da0..14214bafae 100644 --- a/mls/src/test/java/org/bouncycastle/mls/test/TestResourceFinder.java +++ b/mls/src/test/java/org/bouncycastle/test/TestResourceFinder.java @@ -1,4 +1,4 @@ -package org.bouncycastle.mls.test; +package org.bouncycastle.test; import java.io.File; import java.io.FileInputStream; diff --git a/mod_test_ext.sh b/mod_test_ext.sh index 7df220cdf0..3a323d5868 100644 --- a/mod_test_ext.sh +++ b/mod_test_ext.sh @@ -77,7 +77,7 @@ do --add-exports org.bouncycastle.provider/org.bouncycastle.internal.asn1.cms=ALL-UNNAMED \ --add-exports org.bouncycastle.provider/org.bouncycastle.internal.asn1.bsi=ALL-UNNAMED \ --add-exports org.bouncycastle.provider/org.bouncycastle.internal.asn1.eac=ALL-UNNAMED \ - -cp "$testJar:libs/junit.jar:libs/mail.jar:libs/activation.jar" \ + -cp "$testJar:libs/junit-4.13.2.jar:libs/javax.mail-1.4.7.jar:libs/activation-1.1.1.jar" \ -Dbc.test.data.home=core/src/test/data \ $i diff --git a/mod_test_prov.sh b/mod_test_prov.sh index 3e67e5bffb..b0905160bf 100644 --- a/mod_test_prov.sh +++ b/mod_test_prov.sh @@ -76,7 +76,7 @@ do --add-exports org.bouncycastle.provider/org.bouncycastle.internal.asn1.cms=ALL-UNNAMED \ --add-exports org.bouncycastle.provider/org.bouncycastle.internal.asn1.bsi=ALL-UNNAMED \ --add-exports org.bouncycastle.provider/org.bouncycastle.internal.asn1.eac=ALL-UNNAMED \ - -cp "$testJar:libs/junit.jar:libs/mail.jar:libs/activation.jar" \ + -cp "$testJar:libs/junit-4.13.2.jar:libs/javax.mail-1.4.7.jar:libs/activation-1.1.1.jar" \ -Dbc.test.data.home=core/src/test/data \ $i diff --git a/osgi_scan.sh b/osgi_scan.sh new file mode 100755 index 0000000000..cdfb607b25 --- /dev/null +++ b/osgi_scan.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e + +if ! command -v osgiscanner &> /dev/null +then + echo "osgiscanner not on path" + exit 1 +fi + +export script_loc=$( cd -- "$( dirname -- "$0" )" &> /dev/null && pwd ) +cd $script_loc + +export BCHOME=`pwd` + +osgiscanner -f osgi_scan.xml diff --git a/osgi_scan.xml b/osgi_scan.xml new file mode 100644 index 0000000000..9191223e24 --- /dev/null +++ b/osgi_scan.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + +
      + + + + + + + + +
      + +
      + +
      + +
      + +
      + + + + + \ No newline at end of file diff --git a/pg/build.gradle b/pg/build.gradle index 3c22c50b32..9791956838 100644 --- a/pg/build.gradle +++ b/pg/build.gradle @@ -1,19 +1,86 @@ + +plugins { + id "biz.aQute.bnd.builder" version "7.0.0" +} + +sourceSets { + java9 { + java { + srcDirs = ['src/main/jdk1.9'] + } + } +} + + dependencies { implementation project(':core') implementation project(':prov') + implementation project(':util') + + java9Implementation project(':prov') + java9Implementation project(':util') + java9Implementation files(sourceSets.main.output.classesDirs) { + builtBy compileJava + } + + testImplementation group: 'junit', name: 'junit', version: '4.13.2' +} + +compileJava { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + targetCompatibility = 1.8; + sourceCompatibility = 1.8; +} + + +compileJava9Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + sourceCompatibility = 9 + targetCompatibility = 9 + options.compilerArgs += [ + '--module-path', "${bc_prov}${File.pathSeparator}${bc_util}" + ] + + options.sourcepath = files(['src/main/java', 'src/main/jdk1.9']) } + jar.archiveBaseName = "bcpg-$vmrange" + task sourcesJar(type: Jar) { - archiveBaseName = jar.archiveBaseName - classifier = 'sources' - from sourceSets.main.allSource + archiveBaseName = jar.archiveBaseName + archiveClassifier = 'sources' + from sourceSets.main.allSource + exclude("**/*.so") + into('META-INF/versions/9') { + from sourceSets.java9.allSource + } } +jar { + from sourceSets.main.output + into('META-INF/versions/9') { + from sourceSets.java9.output + } + String v = "${rootProject.extensions.ext.bundle_version}" + manifest.attributes('Multi-Release': 'true') + manifest.attributes('Bundle-RequiredExecutionEnvironment': 'JavaSE-1.8') + manifest.attributes('Bundle-Name': 'bcpg') + manifest.attributes('Bundle-SymbolicName': 'bcpg') + manifest.attributes('Export-Package': "org.bouncycastle.{apache|bcpg|gpg|openpgp}.*;version=${v}") + manifest.attributes('Import-Package': "java.*;resolution:=optional,javax.*;resolution:=optional,!org.bouncycastle.{apache|bcpg|gpg|openpgp|}.*,org.bouncycastle.*;version=\"[${v},${maxVersion})\"") + manifest.attributes('Bundle-Version': "${v}") +} + + task javadocJar(type: Jar, dependsOn: javadoc) { archiveBaseName = jar.archiveBaseName - classifier = 'javadoc' + archiveClassifier = 'javadoc' from javadoc.destinationDir } @@ -23,3 +90,9 @@ artifacts { archives sourcesJar } +test { + forkEvery = 1; + maxParallelForks = 8; + maxHeapSize = "3g"; +} + diff --git a/pg/src/main/j2me/org/bouncycastle/openpgp/PGPPublicKey.java b/pg/src/main/j2me/org/bouncycastle/openpgp/PGPPublicKey.java index 229df26273..3ced9181e2 100644 --- a/pg/src/main/j2me/org/bouncycastle/openpgp/PGPPublicKey.java +++ b/pg/src/main/j2me/org/bouncycastle/openpgp/PGPPublicKey.java @@ -337,11 +337,12 @@ public long getKeyID() */ public byte[] getFingerprint() { - byte[] tmp = new byte[fingerprint.length]; - - System.arraycopy(fingerprint, 0, tmp, 0, tmp.length); - - return tmp; + return Arrays.clone(fingerprint); + } + + public boolean hasFingerprint(byte[] fingerprint) + { + return Arrays.areEqual(this.fingerprint, fingerprint); } /** diff --git a/pg/src/main/j2me/org/bouncycastle/openpgp/PGPPublicKeyRing.java b/pg/src/main/j2me/org/bouncycastle/openpgp/PGPPublicKeyRing.java index 03ad6b7a24..d16478feb3 100644 --- a/pg/src/main/j2me/org/bouncycastle/openpgp/PGPPublicKeyRing.java +++ b/pg/src/main/j2me/org/bouncycastle/openpgp/PGPPublicKeyRing.java @@ -15,7 +15,6 @@ import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.TrustPacket; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; -import org.bouncycastle.util.Arrays; /** * Class to hold a single master public key and its subkeys. @@ -135,7 +134,7 @@ public PGPPublicKey getPublicKey(byte[] fingerprint) { PGPPublicKey k = (PGPPublicKey)keys.get(i); - if (Arrays.areEqual(fingerprint, k.getFingerprint())) + if (k.hasFingerprint(fingerprint)) { return k; } diff --git a/pg/src/main/j2me/org/bouncycastle/openpgp/PGPSecretKeyRing.java b/pg/src/main/j2me/org/bouncycastle/openpgp/PGPSecretKeyRing.java index 1263dbcc9d..6248c51a1a 100644 --- a/pg/src/main/j2me/org/bouncycastle/openpgp/PGPSecretKeyRing.java +++ b/pg/src/main/j2me/org/bouncycastle/openpgp/PGPSecretKeyRing.java @@ -20,7 +20,6 @@ import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; -import org.bouncycastle.util.Arrays; /** * Class to hold a single master secret key and its subkeys. @@ -185,7 +184,7 @@ public PGPPublicKey getPublicKey(byte[] fingerprint) { PGPPublicKey k = (PGPPublicKey)keys.get(i); - if (Arrays.areEqual(fingerprint, k.getFingerprint())) + if (k.hasFingerprint(fingerprint)) { return k; } @@ -262,7 +261,7 @@ public PGPSecretKey getSecretKey(byte[] fingerprint) { PGPSecretKey k = (PGPSecretKey)keys.get(i); - if (Arrays.areEqual(fingerprint, k.getPublicKey().getFingerprint())) + if (k.getPublicKey().hasFingerprint(fingerprint)) { return k; } diff --git a/pg/src/main/java/org/bouncycastle/apache/bzip2/CBZip2OutputStream.java b/pg/src/main/java/org/bouncycastle/apache/bzip2/CBZip2OutputStream.java index c638d7212f..6160b4c50b 100644 --- a/pg/src/main/java/org/bouncycastle/apache/bzip2/CBZip2OutputStream.java +++ b/pg/src/main/java/org/bouncycastle/apache/bzip2/CBZip2OutputStream.java @@ -441,12 +441,13 @@ private void writeRun() boolean closed = false; - protected void finalize() - throws Throwable - { - close(); - super.finalize(); - } + // as of Java 13 this is a very bad idea +// protected void finalize() +// throws Throwable +// { +// close(); +// super.finalize(); +// } public void close() throws IOException diff --git a/pg/src/main/java/org/bouncycastle/bcpg/AEADAlgorithmTags.java b/pg/src/main/java/org/bouncycastle/bcpg/AEADAlgorithmTags.java index a98f14d96d..924f9c1b9f 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/AEADAlgorithmTags.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/AEADAlgorithmTags.java @@ -1,8 +1,31 @@ package org.bouncycastle.bcpg; +/** + * AEAD Algorithm IDs. + * Crypto-Refresh (OpenPGP) defines IDs 1 through 3, while LibrePGP only defines 1 and 2. + * Further, the use of AEAD differs between C-R and LibrePGP. + * + * @see + * Crypto-Refresh: AEAD Algorithms + * @see + * LibrePGP - Encryption Modes + */ public interface AEADAlgorithmTags { - int EAX = 1; // EAX (IV len: 16 octets, Tag len: 16 octets) - int OCB = 2; // OCB (IV len: 15 octets, Tag len: 16 octets) - int GCM = 3; // GCM (IV len: 12 octets, Tag len: 16 octets) + /** + * EAX with 16-bit nonce/IV and 16-bit auth tag length. + */ + int EAX = 1; + /** + * OCB with 15-bit nonce/IV and 16-bit auth tag length. + * C-R compliant implementations MUST implement OCB. + */ + int OCB = 2; + /** + * GCM with 12-bit nonce/IV and 16-bit auth tag length. + * OpenPGP only. + */ + int GCM = 3; + + // 100 to 110: Experimental algorithms } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/AEADEncDataPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/AEADEncDataPacket.java index 4afec2cf13..227276d938 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/AEADEncDataPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/AEADEncDataPacket.java @@ -5,15 +5,20 @@ import org.bouncycastle.util.Arrays; /** - * Packet representing AEAD encrypted data. At the moment this appears to exist in the following + * Packet representing non-standard, LibrePGP OCB (AEAD) encrypted data. At the moment this appears to exist in the following * expired draft only, but it's appearing despite this. + * For standardized, interoperable OpenPGP AEAD encrypted data, see {@link SymmetricEncIntegrityPacket} of version + * {@link SymmetricEncIntegrityPacket#VERSION_2}. * - * @ref https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-rfc4880bis-04#section-5.16 + * @see + * LibrePGP - OCB Encrypted Data Packet */ public class AEADEncDataPacket extends InputStreamPacket implements AEADAlgorithmTags, BCPGHeaderObject { + public static final int VERSION_1 = 1; + private final byte version; private final byte algorithm; private final byte aeadAlgorithm; @@ -21,28 +26,36 @@ public class AEADEncDataPacket private final byte[] iv; public AEADEncDataPacket(BCPGInputStream in) + throws IOException + { + this(in, false); + } + + public AEADEncDataPacket(BCPGInputStream in, + boolean newPacketFormat) throws IOException { - super(in); + super(in, AEAD_ENC_DATA, newPacketFormat); version = (byte)in.read(); - if (version != 1) + if (version != VERSION_1) { - throw new IllegalArgumentException("wrong AEAD packet version: " + version); + throw new UnsupportedPacketVersionException("wrong AEAD packet version: " + version); } algorithm = (byte)in.read(); aeadAlgorithm = (byte)in.read(); chunkSize = (byte)in.read(); - iv = new byte[getIVLength(aeadAlgorithm)]; + iv = new byte[AEADUtils.getIVLength(aeadAlgorithm)]; in.readFully(iv); } public AEADEncDataPacket(int algorithm, int aeadAlgorithm, int chunkSize, byte[] iv) { - super(null); - this.version = 1; + super(null, AEAD_ENC_DATA); + + this.version = VERSION_1; this.algorithm = (byte)algorithm; this.aeadAlgorithm = (byte)aeadAlgorithm; this.chunkSize = (byte)chunkSize; @@ -79,7 +92,7 @@ public byte[] getAAData() return createAAData(getVersion(), getAlgorithm(), getAEADAlgorithm(), getChunkSize()); } - private static byte[] createAAData(int version, int symAlgorithm, int aeadAlgorithm, int chunkSize) + public static byte[] createAAData(int version, int symAlgorithm, int aeadAlgorithm, int chunkSize) { byte[] aaData = new byte[5]; diff --git a/pg/src/main/java/org/bouncycastle/bcpg/AEADUtils.java b/pg/src/main/java/org/bouncycastle/bcpg/AEADUtils.java index 6c10b4a3d3..504a657152 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/AEADUtils.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/AEADUtils.java @@ -13,7 +13,7 @@ private AEADUtils() * @param aeadAlgorithmTag AEAD algorithm identifier * @return length of the IV */ - static int getIVLength(int aeadAlgorithmTag) + public static int getIVLength(int aeadAlgorithmTag) { switch (aeadAlgorithmTag) { @@ -34,7 +34,7 @@ static int getIVLength(int aeadAlgorithmTag) * @param aeadAlgorithmTag AEAD algorithm identifier * @return length of the auth tag */ - static int getAuthTagLength(int aeadAlgorithmTag) + public static int getAuthTagLength(int aeadAlgorithmTag) { switch (aeadAlgorithmTag) { @@ -46,4 +46,28 @@ static int getAuthTagLength(int aeadAlgorithmTag) throw new IllegalArgumentException("Invalid AEAD algorithm tag: " + aeadAlgorithmTag); } } + + /** + * Split a given byte array containing
      m
      bytes of key and
      n-8
      bytes of IV into + * two separate byte arrays. + *
      m
      is the key length of the cipher algorithm, while
      n
      is the IV length of the AEAD algorithm. + * Note, that the IV is filled with
      n-8
      bytes only, the remainder is left as 0s. + * Return an array of both arrays with the key and index 0 and the IV at index 1. + * + * @param messageKeyAndIv
      m+n-8
      bytes of concatenated message key and IV + * @param cipherAlgo symmetric cipher algorithm + * @param aeadAlgo AEAD algorithm + * @return array of arrays containing message key and IV + */ + public static byte[][] splitMessageKeyAndIv(byte[] messageKeyAndIv, int cipherAlgo, int aeadAlgo) + { + int keyLen = SymmetricKeyUtils.getKeyLengthInOctets(cipherAlgo); + int ivLen = AEADUtils.getIVLength(aeadAlgo); + byte[] messageKey = new byte[keyLen]; + byte[] iv = new byte[ivLen]; + System.arraycopy(messageKeyAndIv, 0, messageKey, 0, messageKey.length); + System.arraycopy(messageKeyAndIv, messageKey.length, iv, 0, ivLen - 8); + + return new byte[][]{messageKey, iv}; + } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ArmoredInputStream.java b/pg/src/main/java/org/bouncycastle/bcpg/ArmoredInputStream.java index 0fed984a78..817829d128 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/ArmoredInputStream.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/ArmoredInputStream.java @@ -24,7 +24,7 @@ public class ArmoredInputStream extends InputStream { - /* + /** * set up the decoding table. */ private static final byte[] decodingTable; @@ -57,6 +57,7 @@ public class ArmoredInputStream decodingTable['/'] = 63; } + /** * decode the base 64 encoded input data. * @@ -128,11 +129,12 @@ else if (in3 == '=') */ private boolean detectMissingChecksum = false; + private final CRC24 crc; + InputStream in; boolean start = true; byte[] outBuf = new byte[3]; int bufPtr = 3; - CRC24 crc = new FastCRC24(); boolean crcFound = false; boolean hasHeaders = true; String header = null; @@ -171,6 +173,7 @@ public ArmoredInputStream( { this.in = in; this.hasHeaders = hasHeaders; + this.crc = new FastCRC24(); if (hasHeaders) { @@ -179,7 +182,25 @@ public ArmoredInputStream( start = false; } - + + private ArmoredInputStream( + InputStream in, + Builder builder) + throws IOException + { + this.in = in; + this.hasHeaders = builder.hasHeaders; + this.detectMissingChecksum = builder.detectMissingCRC; + this.crc = builder.ignoreCRC ? null : new FastCRC24(); + + if (hasHeaders) + { + parseHeaders(); + } + + start = false; + } + public int available() throws IOException { @@ -367,7 +388,10 @@ public int read() parseHeaders(); } - crc.reset(); + if (crc != null) + { + crc.reset(); + } start = false; } @@ -435,12 +459,15 @@ else if (newLineFound && c == '-') crcFound = true; - int i = ((outBuf[0] & 0xff) << 16) - | ((outBuf[1] & 0xff) << 8) - | (outBuf[2] & 0xff); - if (i != crc.getValue()) + if (crc != null) { - throw new ArmoredInputException("crc check failed in armored message"); + int i = ((outBuf[0] & 0xff) << 16) + | ((outBuf[1] & 0xff) << 8) + | (outBuf[2] & 0xff); + if (i != crc.getValue()) + { + throw new ArmoredInputException("crc check failed in armored message"); + } } return read(); @@ -482,15 +509,18 @@ else if (newLineFound && c == '-') bufPtr = decode(c, readIgnoreSpace(), readIgnoreSpace(), readIgnoreSpace(), outBuf); - if (bufPtr == 0) + if (crc != null) { - crc.update3(outBuf, 0); - } - else - { - for (int i = bufPtr; i < 3; ++i) + if (bufPtr == 0) + { + crc.update3(outBuf, 0); + } + else { - crc.update(outBuf[i] & 0xFF); + for (int i = bufPtr; i < 3; ++i) + { + crc.update(outBuf[i] & 0xFF); + } } } } @@ -572,10 +602,74 @@ public void close() * The default value is false (ignore missing CRC checksums). If the behavior is set to true, * an {@link IOException} will be thrown if a missing CRC checksum is encountered. * - * @param detectMissing ignore missing CRC sums + * @param detectMissing false if ignore missing CRC sums, true for exception + * @deprecated use Builder class for configuring this. */ public void setDetectMissingCRC(boolean detectMissing) { this.detectMissingChecksum = detectMissing; } + + public static Builder builder() + { + return new Builder(); + } + + public static class Builder + { + private boolean hasHeaders = true; + private boolean detectMissingCRC = false; + private boolean ignoreCRC = false; + + private Builder() + { + + } + + /** + * Enable or disable header parsing (default value true). + * + * @param hasHeaders true if headers should be expected, false otherwise. + * @return the current builder instance. + */ + public Builder setParseForHeaders(boolean hasHeaders) + { + this.hasHeaders = hasHeaders; + + return this; + } + + /** + * Change how the stream should react if it encounters missing CRC checksum. + * The default value is false (ignore missing CRC checksums). If the behavior is set to true, + * an {@link IOException} will be thrown if a missing CRC checksum is encountered. + * + * @param detectMissingCRC false if ignore missing CRC sums, true for exception + */ + public Builder setDetectMissingCRC(boolean detectMissingCRC) + { + this.detectMissingCRC = detectMissingCRC; + + return this; + } + + /** + * Specifically ignore the CRC if in place (this will also avoid the cost of calculation). + * + * @param ignoreCRC true if CRC should be ignored, false otherwise. + * @return the current builder instance. + */ + public Builder setIgnoreCRC(boolean ignoreCRC) + { + this.ignoreCRC = ignoreCRC; + + return this; + } + + public ArmoredInputStream build(InputStream inputStream) + throws IOException + { + return new ArmoredInputStream(inputStream, this); + } + } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ArmoredOutputStream.java b/pg/src/main/java/org/bouncycastle/bcpg/ArmoredOutputStream.java index 678231f66b..aa957720ad 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/ArmoredOutputStream.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/ArmoredOutputStream.java @@ -3,10 +3,13 @@ import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.bouncycastle.util.Strings; @@ -22,7 +25,13 @@ public class ArmoredOutputStream extends OutputStream { public static final String VERSION_HDR = "Version"; + public static final String COMMENT_HDR = "Comment"; + public static final String MESSAGE_ID_HDR = "MessageID"; + public static final String HASH_HDR = "Hash"; + public static final String CHARSET_HDR = "Charset"; + public static final String DEFAULT_VERSION = "BCPG v@RELEASE_NAME@"; + private static final byte[] encodingTable = { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', @@ -97,28 +106,26 @@ private static void encode3(OutputStream out, byte[] data) out.write(encodingTable[d3 & 0x3f]); } - OutputStream out; - byte[] buf = new byte[3]; - int bufPtr = 0; - CRC24 crc = new FastCRC24(); - int chunkCount = 0; - int lastb; + OutputStream out; + byte[] buf = new byte[3]; + int bufPtr = 0; + CRC24 crc = new FastCRC24(); + int chunkCount = 0; + int lastb; - boolean start = true; - boolean clearText = false; - boolean newLine = false; + boolean start = true; + boolean clearText = false; + boolean newLine = false; - String nl = Strings.lineSeparator(); + String nl = Strings.lineSeparator(); - String type; - String headerStart = "-----BEGIN PGP "; - String headerTail = "-----"; - String footerStart = "-----END PGP "; - String footerTail = "-----"; + String type; + String headerStart = "-----BEGIN PGP "; + String headerTail = "-----"; + String footerStart = "-----END PGP "; + String footerTail = "-----"; - String version = "BCPG v@RELEASE_NAME@"; - - Hashtable> headers = new Hashtable>(); + final Hashtable> headers = new Hashtable>(); /** * Constructs an armored output stream with {@link #resetHeaders() default headers}. @@ -126,7 +133,7 @@ private static void encode3(OutputStream out, byte[] data) * @param out the OutputStream to wrap. */ public ArmoredOutputStream( - OutputStream out) + OutputStream out) { this.out = out; @@ -135,15 +142,15 @@ public ArmoredOutputStream( nl = "\r\n"; } - setHeader(VERSION_HDR, version); + setHeader(VERSION_HDR, DEFAULT_VERSION); } /** * Constructs an armored output stream with default and custom headers. * - * @param out the OutputStream to wrap. + * @param out the OutputStream to wrap. * @param headers additional headers that add to or override the {@link #resetHeaders() default - * headers}. + * headers}. */ public ArmoredOutputStream( OutputStream out, @@ -162,13 +169,31 @@ public ArmoredOutputStream( } } + ArmoredOutputStream(OutputStream out, Builder builder) + { + this(out); + if (!builder.computeCRCSum) + { + crc = null; + } + this.headers.clear(); + + Map> headerMap = builder.headers; + for (String key : headerMap.keySet()) + { + this.headers.put(key, headerMap.get(key)); + } + } + /** * Set an additional header entry. Any current value(s) under the same name will be * replaced by the new one. A null value will clear the entry for name. * - * @param name the name of the header entry. + * @param name the name of the header entry. * @param value the value of the header entry. + * @deprecated use appropriate methods in {@link Builder} instead. */ + @Deprecated public void setHeader( String name, String value) @@ -195,7 +220,10 @@ public void setHeader( /** * Remove all headers. + * + * @deprecated use appropriate methods in {@link Builder} instead. */ + @Deprecated public void clearHeaders() { headers.clear(); @@ -205,9 +233,11 @@ public void clearHeaders() * Set an additional header entry. The current value(s) will continue to exist together * with the new one. Adding a null value has no effect. * - * @param name the name of the header entry. + * @param name the name of the header entry. * @param value the value of the header entry. + * @deprecated use appropriate methods in {@link Builder} instead */ + @Deprecated public void addHeader( String name, String value) @@ -228,7 +258,10 @@ public void addHeader( /** * Reset the headers to only contain a Version string (if one is present) + * + * @deprecated use {@link Builder#clearHeaders()} instead. */ + @Deprecated public void resetHeaders() { List versions = headers.get(VERSION_HDR); @@ -243,17 +276,19 @@ public void resetHeaders() /** * Start a clear text signed message - backwards compatibility. + * * @param hashAlgorithm hash algorithm */ public void beginClearText( int hashAlgorithm) throws IOException { - beginClearText(new int[] { hashAlgorithm }); + beginClearText(new int[]{hashAlgorithm}); } /** * Start a clear text signed message. + * * @param hashAlgorithms hash algorithms */ public void beginClearText( @@ -267,48 +302,52 @@ public void beginClearText( String hash; switch (hashAlgorithm) { - case HashAlgorithmTags.SHA1: - hash = "SHA1"; - break; - case HashAlgorithmTags.SHA256: - hash = "SHA256"; - break; - case HashAlgorithmTags.SHA384: - hash = "SHA384"; - break; - case HashAlgorithmTags.SHA512: - hash = "SHA512"; - break; - case HashAlgorithmTags.SHA3_256: - hash = "SHA3-256"; - break; - case HashAlgorithmTags.SHA3_512: - hash = "SHA3-512"; - break; - case HashAlgorithmTags.MD2: - hash = "MD2"; - break; - case HashAlgorithmTags.MD5: - hash = "MD5"; - break; - case HashAlgorithmTags.RIPEMD160: - hash = "RIPEMD160"; - break; - case HashAlgorithmTags.SHA224: - hash = "SHA224"; - break; - default: - throw new IOException("unknown hash algorithm tag in beginClearText: " + hashAlgorithm); + case HashAlgorithmTags.MD5: + hash = "MD5"; + break; + case HashAlgorithmTags.SHA1: + hash = "SHA1"; + break; + case HashAlgorithmTags.RIPEMD160: + hash = "RIPEMD160"; + break; + case HashAlgorithmTags.MD2: + hash = "MD2"; + break; + case HashAlgorithmTags.SHA256: + hash = "SHA256"; + break; + case HashAlgorithmTags.SHA384: + hash = "SHA384"; + break; + case HashAlgorithmTags.SHA512: + hash = "SHA512"; + break; + case HashAlgorithmTags.SHA224: + hash = "SHA224"; + break; + case HashAlgorithmTags.SHA3_256: + case HashAlgorithmTags.SHA3_256_OLD: + hash = "SHA3-256"; + break; + case HashAlgorithmTags.SHA3_384: // OLD + hash = "SHA3-384"; + break; + case HashAlgorithmTags.SHA3_512: + case HashAlgorithmTags.SHA3_512_OLD: + hash = "SHA3-512"; + break; + case HashAlgorithmTags.SHA3_224: + hash = "SHA3-224"; + break; + default: + throw new IOException("unknown hash algorithm tag in beginClearText: " + hashAlgorithm); } - sb.append("Hash: ").append(hash).append(nl); + sb.append(HASH_HDR).append(": ").append(hash).append(nl); } sb.append(nl); - for (int i = 0; i != sb.length(); i++) - { - out.write(sb.charAt(i)); - } - + write(sb.toString()); clearText = true; newLine = true; lastb = 0; @@ -324,24 +363,14 @@ private void writeHeaderEntry( String value) throws IOException { - for (int i = 0; i != name.length(); i++) - { - out.write(name.charAt(i)); - } - - out.write(':'); - out.write(' '); - - out.write(Strings.toUTF8ByteArray(value)); - - for (int i = 0; i != nl.length(); i++) - { - out.write(nl.charAt(i)); - } + write(name); + write(": "); + write(value); + write(nl); } public void write( - int b) + int b) throws IOException { if (clearText) @@ -370,8 +399,8 @@ public void write( if (start) { - boolean newPacket = (b & 0x40) != 0; - int tag = 0; + boolean newPacket = (b & 0x40) != 0; + int tag = 0; if (newPacket) { @@ -397,25 +426,10 @@ public void write( type = "MESSAGE"; } - for (int i = 0; i != headerStart.length(); i++) - { - out.write(headerStart.charAt(i)); - } - - for (int i = 0; i != type.length(); i++) - { - out.write(type.charAt(i)); - } - - for (int i = 0; i != headerTail.length(); i++) - { - out.write(headerTail.charAt(i)); - } - - for (int i = 0; i != nl.length(); i++) - { - out.write(nl.charAt(i)); - } + write(headerStart); + write(type); + write(headerTail); + write(nl); if (headers.containsKey(VERSION_HDR)) { @@ -425,37 +439,33 @@ public void write( Enumeration e = headers.keys(); while (e.hasMoreElements()) { - String key = e.nextElement(); + String key = e.nextElement(); if (!key.equals(VERSION_HDR)) { List values = headers.get(key); - for (Iterator it = values.iterator(); it.hasNext();) + for (Iterator it = values.iterator(); it.hasNext(); ) { writeHeaderEntry(key, it.next()); } } } - for (int i = 0; i != nl.length(); i++) - { - out.write(nl.charAt(i)); - } - + write(nl); start = false; } if (bufPtr == 3) { - crc.update3(buf, 0); + if (crc != null) + { + crc.update3(buf, 0); + } encode3(out, buf); bufPtr = 0; if ((++chunkCount & 0xf) == 0) { - for (int i = 0; i != nl.length(); i++) - { - out.write(nl.charAt(i)); - } + write(nl); } } @@ -478,56 +488,240 @@ public void close() { if (bufPtr > 0) { - for (int i = 0; i < bufPtr; ++i) + if (crc != null) { - crc.update(buf[i] & 0xFF); + for (int i = 0; i < bufPtr; ++i) + { + crc.update(buf[i] & 0xFF); + } } encode(out, buf, bufPtr); } - for (int i = 0; i != nl.length(); i++) + write(nl); + + if (crc != null) { - out.write(nl.charAt(i)); + out.write('='); + + int crcV = crc.getValue(); + + buf[0] = (byte)(crcV >>> 16); + buf[1] = (byte)(crcV >>> 8); + buf[2] = (byte)crcV; + + encode3(out, buf); + write(nl); } - out.write('='); - int crcV = crc.getValue(); + write(footerStart); + write(type); + write(footerTail); + write(nl); - buf[0] = (byte)(crcV >>> 16); - buf[1] = (byte)(crcV >>> 8); - buf[2] = (byte)crcV; + out.flush(); - encode3(out, buf); + type = null; + start = true; + } + } + + private void write(String string) + throws IOException + { + out.write(Strings.toUTF8ByteArray(string)); + } + + public static Builder builder() + { + return new Builder(); + } + + public static class Builder + { + private final Map> headers = new HashMap>(); + private boolean computeCRCSum = true; + + private Builder() + { + + } + + public ArmoredOutputStream build(OutputStream outputStream) + { + return new ArmoredOutputStream(outputStream, this); + } + + /** + * Set a
      Version:
      header. + * Note: Adding version headers to ASCII armored output is discouraged to minimize metadata. + * + * @param version version + * @return builder + */ + public Builder setVersion(String version) + { + return setSingletonHeader(VERSION_HDR, version); + } + + /** + * Replace the
      Comment:
      header field with the given comment. + * If the comment contains newlines, multiple headers will be added, one for each newline. + * If the comment is
      null
      , then the output will contain no comments. + * + * @param comment comment + * @return builder + */ + public Builder setComment(String comment) + { + return replaceHeader(COMMENT_HDR, comment); + } - for (int i = 0; i != nl.length(); i++) + /** + * Replace the
      MessageID:
      header field with the given messageId. + * + * @param messageId message ID + * @return builder + */ + public Builder setMessageId(String messageId) + { + return replaceHeader(MESSAGE_ID_HDR, messageId); + } + + /** + * Replace the
      Charset:
      header with the given value. + * + * @param charset charset + * @return builder + */ + public Builder setCharset(String charset) + { + return replaceHeader(CHARSET_HDR, charset); + } + + /** + * Add the given value as one or more additional
      Comment:
      headers to the already present comments. + * If the comment contains newlines, multiple headers will be added, one for each newline. + * If the comment is
      null
      , this method does nothing. + * + * @param comment comment + * @return builder + */ + public Builder addComment(String comment) + { + return addHeader(COMMENT_HDR, comment); + } + + /** + * Set and replace the given header value with a single-line header. + * If the value is
      null
      , this method will remove the header entirely. + * + * @param key header key + * @param value header value + * @return builder + */ + private Builder setSingletonHeader(String key, String value) + { + if (value == null || value.trim().length() == 0) + { + this.headers.remove(key); + } + else { - out.write(nl.charAt(i)); + String trimmed = value.trim(); + if (trimmed.contains("\n")) + { + throw new IllegalArgumentException("Armor header value for key " + key + " cannot contain newlines."); + } + this.headers.put(key, Collections.singletonList(value)); } + return this; + } - for (int i = 0; i != footerStart.length(); i++) + /** + * Add a header, splitting it into multiple headers if required (newlines). + * + * @param key key + * @param value value + * @return builder + */ + private Builder addHeader(String key, String value) + { + if (value == null || value.trim().length() == 0) { - out.write(footerStart.charAt(i)); + return this; } - for (int i = 0; i != type.length(); i++) + List values = headers.get(key); + if (values == null) { - out.write(type.charAt(i)); + values = new ArrayList(); + headers.put(key, values); } - for (int i = 0; i != footerTail.length(); i++) + // handle multi-line values + String trimmed = value.trim(); + for (String line : trimmed.split("\n")) { - out.write(footerTail.charAt(i)); + String lineTrim = line.trim(); + if (lineTrim.length() == 0) + { + continue; + } + values.add(lineTrim); } + return this; + } - for (int i = 0; i != nl.length(); i++) + /** + * Replace all header values for the given key with the given value. + * If the value is
      null
      , existing headers for the given key are removed. + * The value is split into multiple headers if it contains newlines. + * + * @param key key + * @param value value + * @return builder + */ + private Builder replaceHeader(String key, String value) + { + if (value == null || value.trim().length() == 0) { - out.write(nl.charAt(i)); + return this; } - out.flush(); + List values = new ArrayList(); - type = null; - start = true; + // handle multi-line values + String trimmed = value.trim(); + for (String line : trimmed.split("\n")) + { + String lineTrim = line.trim(); + if (lineTrim.length() == 0) + { + continue; + } + values.add(lineTrim); + } + + headers.put(key, values); + return this; + } + + public Builder clearHeaders() + { + headers.clear(); + return this; + } + + /** + * Enable calculation and inclusion of the CRC check sum (default is true). + * @param doComputeCRC true if CRC to be included, false otherwise. + * @return the current builder instance. + */ + public Builder enableCRC(boolean doComputeCRC) + { + this.computeCRCSum = doComputeCRC; + return this; } } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/BCPGInputStream.java b/pg/src/main/java/org/bouncycastle/bcpg/BCPGInputStream.java index 3ac9d8c833..c0cca6ab57 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/BCPGInputStream.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/BCPGInputStream.java @@ -11,7 +11,8 @@ * Stream reader for PGP objects */ public class BCPGInputStream - extends InputStream implements PacketTags + extends InputStream + implements PacketTags { /** * If the argument is a {@link BCPGInputStream}, return it. @@ -29,19 +30,19 @@ public static BCPGInputStream wrap(InputStream in) return new BCPGInputStream(in); } - InputStream in; - boolean next = false; - int nextB; + InputStream in; + boolean next = false; + int nextB; - boolean mNext = false; - int mNextB; + boolean mNext = false; + int mNextB; public BCPGInputStream( - InputStream in) + InputStream in) { this.in = in; } - + public int available() throws IOException { @@ -113,9 +114,9 @@ public int read( } public void readFully( - byte[] buf, - int off, - int len) + byte[] buf, + int off, + int len) throws IOException { if (Streams.readFully(this, buf, off, len) < len) @@ -131,7 +132,7 @@ public byte[] readAll() } public void readFully( - byte[] buf) + byte[] buf) throws IOException { readFully(buf, 0, buf.length); @@ -141,7 +142,6 @@ public void readFully( * Obtains the tag of the next packet in the stream. * * @return the {@link PacketTags tag number}. - * * @throws IOException if an error occurs reading the tag from the stream. */ public int nextPacketTag() @@ -151,7 +151,7 @@ public int nextPacketTag() { try { - nextB = in.read(); + nextB = this.read(); } catch (EOFException e) { @@ -176,12 +176,13 @@ public int nextPacketTag() /** * Reads the next packet from the stream. + * * @throws IOException */ public Packet readPacket() throws IOException { - int hdr = this.read(); + int hdr = this.read(); if (hdr < 0) { @@ -193,35 +194,20 @@ public Packet readPacket() throw new IOException("invalid header encountered"); } - boolean newPacket = (hdr & 0x40) != 0; - int tag = 0; - int bodyLen = 0; - boolean partial = false; + boolean newPacket = (hdr & 0x40) != 0; + int tag = 0; + int bodyLen = 0; + boolean partial = false; if (newPacket) { tag = hdr & 0x3f; - - int l = this.read(); - - if (l < 192) - { - bodyLen = l; - } - else if (l <= 223) + boolean[] flags = new boolean[3]; + bodyLen = StreamUtil.readBodyLen(this, flags); + partial = flags[StreamUtil.flag_partial]; + if (partial && bodyLen < 512) { - int b = this.read(); - - bodyLen = ((l - 192) << 8) + (b) + 192; - } - else if (l == 255) - { - bodyLen = (this.read() << 24) | (this.read() << 16) | (this.read() << 8) | this.read(); - } - else - { - partial = true; - bodyLen = 1 << (l & 0x1f); + throw new IOException("First chunk of partial body MUST have a length of at least 512 octets."); } } else @@ -236,10 +222,10 @@ else if (l == 255) bodyLen = this.read(); break; case 1: - bodyLen = (this.read() << 8) | this.read(); + bodyLen = StreamUtil.read2OctetLength(this); break; case 2: - bodyLen = (this.read() << 24) | (this.read() << 16) | (this.read() << 8) | this.read(); + bodyLen = StreamUtil.read4OctetLength(this); break; case 3: partial = true; @@ -249,7 +235,7 @@ else if (l == 255) } } - BCPGInputStream objStream; + BCPGInputStream objStream; if (bodyLen == 0 && partial) { @@ -260,63 +246,63 @@ else if (l == 255) objStream = new BCPGInputStream( new BufferedInputStream(new PartialInputStream(this, partial, bodyLen))); } - + switch (tag) { case RESERVED: - return new InputStreamPacket(objStream); + return new ReservedPacket(objStream, newPacket); case PUBLIC_KEY_ENC_SESSION: - return new PublicKeyEncSessionPacket(objStream); + return new PublicKeyEncSessionPacket(objStream, newPacket); case SIGNATURE: - return new SignaturePacket(objStream); + return new SignaturePacket(objStream, newPacket); case SYMMETRIC_KEY_ENC_SESSION: - return new SymmetricKeyEncSessionPacket(objStream); + return new SymmetricKeyEncSessionPacket(objStream, newPacket); case ONE_PASS_SIGNATURE: - return new OnePassSignaturePacket(objStream); + return new OnePassSignaturePacket(objStream, newPacket); case SECRET_KEY: - return new SecretKeyPacket(objStream); + return new SecretKeyPacket(objStream, newPacket); case PUBLIC_KEY: - return new PublicKeyPacket(objStream); + return new PublicKeyPacket(objStream, newPacket); case SECRET_SUBKEY: - return new SecretSubkeyPacket(objStream); + return new SecretSubkeyPacket(objStream, newPacket); case COMPRESSED_DATA: - return new CompressedDataPacket(objStream); + return new CompressedDataPacket(objStream, newPacket); case SYMMETRIC_KEY_ENC: - return new SymmetricEncDataPacket(objStream); + return new SymmetricEncDataPacket(objStream, newPacket); case MARKER: - return new MarkerPacket(objStream); + return new MarkerPacket(objStream, newPacket); case LITERAL_DATA: - return new LiteralDataPacket(objStream); + return new LiteralDataPacket(objStream, newPacket); case TRUST: - return new TrustPacket(objStream); + return new TrustPacket(objStream, newPacket); case USER_ID: - return new UserIDPacket(objStream); + return new UserIDPacket(objStream, newPacket); case USER_ATTRIBUTE: - return new UserAttributePacket(objStream); + return new UserAttributePacket(objStream, newPacket); case PUBLIC_SUBKEY: - return new PublicSubkeyPacket(objStream); + return new PublicSubkeyPacket(objStream, newPacket); case SYM_ENC_INTEGRITY_PRO: - return new SymmetricEncIntegrityPacket(objStream); + return new SymmetricEncIntegrityPacket(objStream, newPacket); case MOD_DETECTION_CODE: - return new ModDetectionCodePacket(objStream); + return new ModDetectionCodePacket(objStream, newPacket); case AEAD_ENC_DATA: - return new AEADEncDataPacket(objStream); + return new AEADEncDataPacket(objStream, newPacket); case PADDING: - return new PaddingPacket(objStream); + return new PaddingPacket(objStream, newPacket); case EXPERIMENTAL_1: case EXPERIMENTAL_2: case EXPERIMENTAL_3: case EXPERIMENTAL_4: - return new ExperimentalPacket(tag, objStream); + return new ExperimentalPacket(tag, objStream, newPacket); default: - throw new IOException("unknown packet type encountered: " + tag); + return new UnknownPacket(tag, objStream, newPacket); } } /** - * @deprecated use skipMarkerAndPaddingPackets * @return the tag for the next non-marker/padding packet * @throws IOException on a parsing issue. + * @deprecated use skipMarkerAndPaddingPackets */ public int skipMarkerPackets() throws IOException @@ -326,6 +312,7 @@ public int skipMarkerPackets() /** * skip any marker and padding packets found in the stream. + * * @return the tag for the next non-marker/padding packet * @throws IOException on a parsing issue. */ @@ -334,7 +321,7 @@ public int skipMarkerAndPaddingPackets() { int tag; while ((tag = nextPacketTag()) == PacketTags.MARKER - || tag == PacketTags.PADDING) + || tag == PacketTags.PADDING) { readPacket(); } @@ -350,20 +337,20 @@ public void close() /** * a stream that overlays our input stream, allowing the user to only read a segment of it. - * + *

      * NB: dataLength will be negative if the segment length is in the upper range above 2**31. */ private static class PartialInputStream extends InputStream { - private BCPGInputStream in; - private boolean partial; - private int dataLength; + private BCPGInputStream in; + private boolean partial; + private int dataLength; PartialInputStream( - BCPGInputStream in, - boolean partial, - int dataLength) + BCPGInputStream in, + boolean partial, + int dataLength) { this.in = in; this.partial = partial; @@ -392,32 +379,13 @@ public int available() private int loadDataLength() throws IOException { - int l = in.read(); - - if (l < 0) + boolean[] flags = new boolean[3]; + dataLength = StreamUtil.readBodyLen(in, flags); + if (flags[StreamUtil.flag_eof]) { return -1; } - - partial = false; - if (l < 192) - { - dataLength = l; - } - else if (l <= 223) - { - dataLength = ((l - 192) << 8) + (in.read()) + 192; - } - else if (l == 255) - { - dataLength = (in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); - } - else - { - partial = true; - dataLength = 1 << (l & 0x1f); - } - + partial = flags[StreamUtil.flag_partial]; return dataLength; } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/BCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/BCPGKey.java index 9a01936ba7..1a1f5e2031 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/BCPGKey.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/BCPGKey.java @@ -11,7 +11,8 @@ public interface BCPGKey /** * Return the base format for this key - in the case of the symmetric keys it will generally * be raw indicating that the key is just a straight byte representation, for an asymmetric - * key the format will be PGP, indicating the key is a string of MPIs encoded in PGP format. + * key the format will be PGP, indicating the key is a string of MPIs or octets + * encoded in PGP format. * * @return "RAW" or "PGP" */ diff --git a/pg/src/main/java/org/bouncycastle/bcpg/BCPGOutputStream.java b/pg/src/main/java/org/bouncycastle/bcpg/BCPGOutputStream.java index aef21a17e0..d4432920d0 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/BCPGOutputStream.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/BCPGOutputStream.java @@ -28,14 +28,14 @@ public static BCPGOutputStream wrap(OutputStream out) return new BCPGOutputStream(out); } - OutputStream out; - private boolean useOldFormat; - private byte[] partialBuffer; - private int partialBufferLength; - private int partialPower; - private int partialOffset; - - private static final int BUF_SIZE_POWER = 16; // 2^16 size buffer on long files + OutputStream out; + private PacketFormat packetFormat; + private byte[] partialBuffer; + private int partialBufferLength; + private int partialPower; + private int partialOffset; + + private static final int BUF_SIZE_POWER = 16; // 2^16 size buffer on long files /** * Base constructor - generate a PGP protocol encoding with old-style packets whenever @@ -44,43 +44,51 @@ public static BCPGOutputStream wrap(OutputStream out) * @param out output stream to write encoded data to. */ public BCPGOutputStream( - OutputStream out) + OutputStream out) { - this(out, false); + this(out, PacketFormat.ROUNDTRIP); } /** - * Base constructor specifying whether or not to use packets in the new format + * Base constructor specifying whether to use packets in the new format * wherever possible. * - * @param out output stream to write encoded data to. + * @param out output stream to write encoded data to. * @param newFormatOnly true if use new format packets, false if backwards compatible preferred. */ public BCPGOutputStream( - OutputStream out, - boolean newFormatOnly) + OutputStream out, + boolean newFormatOnly) + { + this(out, newFormatOnly ? PacketFormat.CURRENT : PacketFormat.ROUNDTRIP); + } + + public BCPGOutputStream( + OutputStream out, + PacketFormat packetFormat) { this.out = out; - this.useOldFormat = !newFormatOnly; + this.packetFormat = packetFormat; } /** * Create a stream representing an old style partial object. - * + * * @param tag the packet tag for the object. */ public BCPGOutputStream( - OutputStream out, - int tag) + OutputStream out, + int tag) throws IOException { this.out = out; + this.packetFormat = PacketFormat.LEGACY; this.writeHeader(tag, true, true, 0); } - + /** * Create a stream representing a general packet. - * + * * @param out * @param tag * @param length @@ -88,14 +96,15 @@ public BCPGOutputStream( * @throws IOException */ public BCPGOutputStream( - OutputStream out, - int tag, - long length, - boolean oldFormat) + OutputStream out, + int tag, + long length, + boolean oldFormat) throws IOException { this.out = out; - + this.packetFormat = oldFormat ? PacketFormat.LEGACY : PacketFormat.CURRENT; + if (length > 0xFFFFFFFFL) { this.writeHeader(tag, false, true, 0); @@ -109,93 +118,69 @@ public BCPGOutputStream( this.writeHeader(tag, oldFormat, false, length); } } - + /** - * * @param tag * @param length * @throws IOException */ public BCPGOutputStream( - OutputStream out, - int tag, - long length) + OutputStream out, + int tag, + long length) throws IOException { this.out = out; - + this.packetFormat = PacketFormat.CURRENT; + this.writeHeader(tag, false, false, length); } - + /** * Create a new style partial input stream buffered into chunks. - * - * @param out output stream to write to. - * @param tag packet tag. + * + * @param out output stream to write to. + * @param tag packet tag. * @param buffer size of chunks making up the packet. * @throws IOException */ public BCPGOutputStream( - OutputStream out, - int tag, - byte[] buffer) + OutputStream out, + int tag, + byte[] buffer) throws IOException { this.out = out; + this.packetFormat = PacketFormat.CURRENT; this.writeHeader(tag, false, true, 0); - + this.partialBuffer = buffer; - - int length = partialBuffer.length; - + + int length = partialBuffer.length; + for (partialPower = 0; length != 1; partialPower++) { length >>>= 1; } - + if (partialPower > 30) { throw new IOException("Buffer cannot be greater than 2^30 in length."); } - + this.partialBufferLength = 1 << partialPower; this.partialOffset = 0; } - - private void writeNewPacketLength( - long bodyLen) - throws IOException - { - if (bodyLen < 192) - { - out.write((byte)bodyLen); - } - else if (bodyLen <= 8383) - { - bodyLen -= 192; - - out.write((byte)(((bodyLen >> 8) & 0xff) + 192)); - out.write((byte)bodyLen); - } - else - { - out.write(0xff); - out.write((byte)(bodyLen >> 24)); - out.write((byte)(bodyLen >> 16)); - out.write((byte)(bodyLen >> 8)); - out.write((byte)bodyLen); - } - } - + private void writeHeader( - int tag, - boolean oldPackets, - boolean partial, - long bodyLen) + int tag, + boolean oldPackets, + boolean partial, + long bodyLen) throws IOException { - int hdr = 0x80; - + int hdr = 0x80; + if (partialBuffer != null) { partialFlush(true); @@ -206,7 +191,7 @@ private void writeHeader( if (tag <= 0xF && oldPackets) { hdr |= tag << 2; - + if (partial) { this.write(hdr | 0x03); @@ -221,16 +206,12 @@ private void writeHeader( else if (bodyLen <= 0xffff) { this.write(hdr | 0x01); - this.write((byte)(bodyLen >> 8)); - this.write((byte)(bodyLen)); + StreamUtil.write2OctetLength(this, (int)bodyLen); } else { this.write(hdr | 0x02); - this.write((byte)(bodyLen >> 24)); - this.write((byte)(bodyLen >> 16)); - this.write((byte)(bodyLen >> 8)); - this.write((byte)bodyLen); + StreamUtil.writeBodyLen(this, bodyLen); } } } @@ -238,25 +219,25 @@ else if (bodyLen <= 0xffff) { hdr |= 0x40 | tag; this.write(hdr); - + if (partial) { partialOffset = 0; } else { - this.writeNewPacketLength(bodyLen); + StreamUtil.writeNewPacketLength(out, bodyLen); } } } - + private void partialFlush( - boolean isLast) + boolean isLast) throws IOException { if (isLast) { - writeNewPacketLength(partialOffset); + StreamUtil.writeNewPacketLength(out, partialOffset); out.write(partialBuffer, 0, partialOffset); } else @@ -264,37 +245,36 @@ private void partialFlush( out.write(0xE0 | partialPower); out.write(partialBuffer, 0, partialBufferLength); } - + partialOffset = 0; } - + private void writePartial( - byte b) + byte b) throws IOException { if (partialOffset == partialBufferLength) { partialFlush(false); } - + partialBuffer[partialOffset++] = b; } - + private void writePartial( - byte[] buf, - int off, - int len) + byte[] buf, + int off, + int len) throws IOException { if (partialOffset == partialBufferLength) { partialFlush(false); } - + if (len <= (partialBufferLength - partialOffset)) { System.arraycopy(buf, off, partialBuffer, partialOffset, len); - partialOffset += len; } else { @@ -302,7 +282,7 @@ private void writePartial( off += partialBufferLength - partialOffset; len -= partialBufferLength - partialOffset; partialFlush(false); - + while (len > partialBufferLength) { System.arraycopy(buf, off, partialBuffer, 0, partialBufferLength); @@ -312,12 +292,12 @@ private void writePartial( } System.arraycopy(buf, off, partialBuffer, 0, len); - partialOffset += len; } + partialOffset += len; } - + public void write( - int b) + int b) throws IOException { if (partialBuffer != null) @@ -329,11 +309,11 @@ public void write( out.write(b); } } - + public void write( - byte[] bytes, - int off, - int len) + byte[] bytes, + int off, + int len) throws IOException { if (partialBuffer != null) @@ -345,35 +325,79 @@ public void write( out.write(bytes, off, len); } } - + + /** + * Write a packet to the stream. + * @param p packet + * @throws IOException + */ public void writePacket( - ContainedPacket p) + ContainedPacket p) throws IOException { p.encode(this); } + /** + * Write a packet to the stream. + * The packet will use the old encoding format if {@link #packetFormat} is {@link PacketFormat#LEGACY}, otherwise + * it will be encoded using the new packet format. + * @param tag packet tag + * @param body packet body + * @throws IOException + */ void writePacket( - int tag, - byte[] body) + int tag, + byte[] body) throws IOException { - this.writeHeader(tag, useOldFormat, false, body.length); + this.writeHeader(tag, packetFormat == PacketFormat.LEGACY, false, body.length); this.write(body); } + /** + * Write a packet. + * The packet format will be chosen primarily based on {@link #packetFormat}. + * If {@link #packetFormat} is {@link PacketFormat#CURRENT}, the packet will be encoded using the new format. + * If it is {@link PacketFormat#LEGACY}, the packet will use old encoding format. + * If it is {@link PacketFormat#ROUNDTRIP}, then the format will be determined by objectPrefersNewPacketFormat. + * + * @param objectPrefersNewPacketFormat whether the packet prefers to be encoded using the new packet format + * @param tag packet tag + * @param body packet body + * @throws IOException + */ + void writePacket( + boolean objectPrefersNewPacketFormat, + int tag, + byte[] body) + throws IOException + { + boolean oldPacketFormat = packetFormat == PacketFormat.LEGACY || + (packetFormat == PacketFormat.ROUNDTRIP && !objectPrefersNewPacketFormat); + this.writeHeader(tag, oldPacketFormat, false, body.length); + this.write(body); + } + + /** + * Write a packet, forcing the packet format to be either old or new. + * @param tag packet tag + * @param body packet body + * @param oldFormat if true, old format is forced, else force new format + * @throws IOException + */ void writePacket( - int tag, - byte[] body, - boolean oldFormat) + int tag, + byte[] body, + boolean oldFormat) throws IOException { this.writeHeader(tag, oldFormat, false, body.length); this.write(body); } - + public void writeObject( - BCPGObject o) + BCPGObject o) throws IOException { o.encode(this); @@ -387,11 +411,11 @@ public void flush() { out.flush(); } - + /** * Finish writing out the current packet without closing the underlying stream. */ - public void finish() + public void finish() throws IOException { if (partialBuffer != null) @@ -401,7 +425,7 @@ public void finish() partialBuffer = null; } } - + public void close() throws IOException { @@ -409,4 +433,5 @@ public void close() out.flush(); out.close(); } + } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/CompressedDataPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/CompressedDataPacket.java index 7239d91eec..accd96445c 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/CompressedDataPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/CompressedDataPacket.java @@ -11,10 +11,18 @@ public class CompressedDataPacket int algorithm; CompressedDataPacket( - BCPGInputStream in) + BCPGInputStream in) + throws IOException + { + this(in, false); + } + + CompressedDataPacket( + BCPGInputStream in, + boolean newPacketFormat) throws IOException { - super(in); + super(in, COMPRESSED_DATA, newPacketFormat); algorithm = in.read(); } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/CompressionAlgorithmTags.java b/pg/src/main/java/org/bouncycastle/bcpg/CompressionAlgorithmTags.java index 431f4bc480..3bf91b6a10 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/CompressionAlgorithmTags.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/CompressionAlgorithmTags.java @@ -1,7 +1,14 @@ package org.bouncycastle.bcpg; /** - * Basic tags for compression algorithms + * Basic tags for compression algorithms. + * + * @see + * RFC4880 - Compression Algorithms + * @see + * LibrePGP - Compression Algorithms + * @see + * Crypto-Refresh - Compression Algorithms */ public interface CompressionAlgorithmTags { diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ContainedPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/ContainedPacket.java index c7fcd86e95..8f87a96af7 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/ContainedPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/ContainedPacket.java @@ -8,20 +8,34 @@ /** * Basic type for a PGP packet. */ -public abstract class ContainedPacket +public abstract class ContainedPacket extends Packet implements Encodable { - public byte[] getEncoded() + + ContainedPacket(int packetTag) + { + this(packetTag, false); + } + + ContainedPacket(int packetTag, boolean newPacketFormat) + { + super(packetTag, newPacketFormat); + } + + public byte[] getEncoded() throws IOException { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - BCPGOutputStream pOut = new BCPGOutputStream(bOut); - - pOut.writePacket(this); + return getEncoded(PacketFormat.ROUNDTRIP); + } + public byte[] getEncoded(PacketFormat format) + throws IOException + { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, format); + pOut.writePacket(this); pOut.close(); - return bOut.toByteArray(); } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/DSAPublicBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/DSAPublicBCPGKey.java index 440e936e95..4af368d31a 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/DSAPublicBCPGKey.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/DSAPublicBCPGKey.java @@ -1,6 +1,6 @@ package org.bouncycastle.bcpg; -import java.io.*; +import java.io.IOException; import java.math.BigInteger; /** diff --git a/pg/src/main/java/org/bouncycastle/bcpg/DSASecretBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/DSASecretBCPGKey.java index 3316683d0c..bcb1d302fd 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/DSASecretBCPGKey.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/DSASecretBCPGKey.java @@ -1,6 +1,6 @@ package org.bouncycastle.bcpg; -import java.io.*; +import java.io.IOException; import java.math.BigInteger; /** diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ECDHPublicBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/ECDHPublicBCPGKey.java index 90c0e152ce..b0d83b7684 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/ECDHPublicBCPGKey.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/ECDHPublicBCPGKey.java @@ -7,7 +7,17 @@ import org.bouncycastle.math.ec.ECPoint; /** - * base class for an ECDH Public Key. + * Base class for an ECDH Public Key. + * This type is for use with {@link PublicKeyAlgorithmTags#ECDH}. + * The specific curve is identified by providing an OID. + * Regarding X25519, X448, consider the following: + * Modern implementations use dedicated key types {@link X25519PublicBCPGKey}, {@link X448PublicBCPGKey} along with + * dedicated algorithm tags {@link PublicKeyAlgorithmTags#X25519}, {@link PublicKeyAlgorithmTags#X448}. + * If you want to be compatible with legacy applications however, you should use this class instead. + * Note though, that for v6 keys, {@link X25519PublicBCPGKey} or {@link X448PublicBCPGKey} MUST be used for X25519, X448. + * + * @see + * Crypto-Refresh - Algorithm-Specific Parts for ECDH Keys */ public class ECDHPublicBCPGKey extends ECPublicBCPGKey @@ -26,7 +36,7 @@ public ECDHPublicBCPGKey( super(in); int length = in.read(); - byte[] kdfParameters = new byte[length]; + byte[] kdfParameters = new byte[length]; if (kdfParameters.length != 3) { throw new IllegalStateException("kdf parameters size of 3 expected."); @@ -122,7 +132,12 @@ private void verifySymmetricKeyAlgorithm() case SymmetricKeyAlgorithmTags.AES_192: case SymmetricKeyAlgorithmTags.AES_256: break; - + case SymmetricKeyAlgorithmTags.CAMELLIA_128: + case SymmetricKeyAlgorithmTags.CAMELLIA_192: + case SymmetricKeyAlgorithmTags.CAMELLIA_256: + //RFC 5581 s3: Camellia may be used in any place in OpenPGP where a symmetric cipher + // is usable, and it is subject to the same usage requirements + break; default: throw new IllegalStateException("Symmetric key algorithm must be AES-128 or stronger."); } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ECDSAPublicBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/ECDSAPublicBCPGKey.java index cf0965185a..87bfa6f334 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/ECDSAPublicBCPGKey.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/ECDSAPublicBCPGKey.java @@ -7,7 +7,11 @@ import org.bouncycastle.math.ec.ECPoint; /** - * base class for an ECDSA Public Key. + * Base class for an ECDSA Public Key. + * This type is used with {@link PublicKeyAlgorithmTags#ECDSA} and the curve is identified by providing an OID. + * + * @see + * Crypto-Refresh - Algorithm-Specific Parts for ECDSA Keys */ public class ECDSAPublicBCPGKey extends ECPublicBCPGKey diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ECPublicBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/ECPublicBCPGKey.java index 38e1b0e4a9..b0631e3766 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/ECPublicBCPGKey.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/ECPublicBCPGKey.java @@ -8,7 +8,8 @@ import org.bouncycastle.math.ec.ECPoint; /** - * base class for an EC Public Key. + * Base class for an EC Public Key. + * For subclasses, see {@link ECDHPublicBCPGKey}, {@link ECDSAPublicBCPGKey} or {@link EdDSAPublicBCPGKey}. */ public abstract class ECPublicBCPGKey extends BCPGObject diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ECSecretBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/ECSecretBCPGKey.java index c595fa4b5f..a5b498f985 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/ECSecretBCPGKey.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/ECSecretBCPGKey.java @@ -4,7 +4,24 @@ import java.math.BigInteger; /** - * base class for an EC Secret Key. + * Base class for an EC Secret Key. + * This type is for use with {@link PublicKeyAlgorithmTags#ECDH} or {@link PublicKeyAlgorithmTags#ECDSA}. + * The specific curve is identified by providing an OID. + * Regarding X25519, X448, consider the following: + * ECDH keys using curve448 are unspecified. + * ECDH secret keys using curve25519 use big-endian MPI encoding, contrary to {@link X25519SecretBCPGKey} which uses + * native encoding. + * Modern implementations use dedicated key types {@link X25519SecretBCPGKey}, {@link X448SecretBCPGKey} along with + * dedicated algorithm tags {@link PublicKeyAlgorithmTags#X25519}, {@link PublicKeyAlgorithmTags#X448}. + * If you want to be compatible with legacy applications however, you should use this class instead. + * Note though, that for v6 keys, {@link X25519SecretBCPGKey} or {@link X448SecretBCPGKey} MUST be used for X25519, X448. + * + * @see + * Crypto-Refresh - Algorithm-Specific Parts for ECDH Keys + * @see + * Crypto-Refresh - Algorithm-Specific Parts for ECDSA Keys + * @see + * Crypto-Refresh - Curve25519Legacy ECDH Secret Key Material (deprecated) */ public class ECSecretBCPGKey extends BCPGObject diff --git a/pg/src/main/java/org/bouncycastle/bcpg/Ed25519PublicBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/Ed25519PublicBCPGKey.java new file mode 100644 index 0000000000..14507dca2c --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/Ed25519PublicBCPGKey.java @@ -0,0 +1,31 @@ +package org.bouncycastle.bcpg; + +import java.io.IOException; + +/** + * Public key of type {@link PublicKeyAlgorithmTags#Ed25519}. + * This type was introduced with Crypto-Refresh and can be used with v4, v6 keys. + * Note however, that legacy implementations might not understand this key type yet. + * For a key type compatible with legacy v4 implementations, see {@link EdDSAPublicBCPGKey} with + * {@link PublicKeyAlgorithmTags#EDDSA_LEGACY}. + * + * @see + * Crypto-Refresh - Algorithm-Specific Part for Ed25519 Keys + */ +public class Ed25519PublicBCPGKey + extends OctetArrayBCPGKey +{ + // 32 octets of the native public key + public static final int LENGTH = 32; + + public Ed25519PublicBCPGKey(BCPGInputStream in) + throws IOException + { + super(LENGTH, in); + } + + public Ed25519PublicBCPGKey(byte[] key) + { + super(LENGTH, key); + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/Ed25519SecretBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/Ed25519SecretBCPGKey.java new file mode 100644 index 0000000000..56f7bb815d --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/Ed25519SecretBCPGKey.java @@ -0,0 +1,31 @@ +package org.bouncycastle.bcpg; + +import java.io.IOException; + +/** + * Secret key of type {@link PublicKeyAlgorithmTags#Ed25519}. + * This type was introduced with Crypto-Refresh and can be used with v4, v6 keys. + * Note however, that legacy implementations might not understand this key type yet. + * For a key type compatible with legacy v4 implementations, see {@link EdDSAPublicBCPGKey} with + * {@link PublicKeyAlgorithmTags#EDDSA_LEGACY}. + * + * @see + * Crypto-Refresh - Algorithm-Specific Part for Ed25519 Keys + */ +public class Ed25519SecretBCPGKey + extends OctetArrayBCPGKey +{ + // 32 octets of the native secret key + public static final int LENGTH = 32; + + public Ed25519SecretBCPGKey(BCPGInputStream in) + throws IOException + { + super(LENGTH, in); + } + + public Ed25519SecretBCPGKey(byte[] key) + { + super(LENGTH, key); + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/Ed448PublicBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/Ed448PublicBCPGKey.java new file mode 100644 index 0000000000..426f9d909c --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/Ed448PublicBCPGKey.java @@ -0,0 +1,32 @@ +package org.bouncycastle.bcpg; + +import java.io.IOException; + +/** + * Public key of type {@link PublicKeyAlgorithmTags#Ed448}. + * This type was introduced with Crypto-Refresh and can be used with v4, v6 keys. + * Note however, that legacy implementations might not understand this key type yet. + * For a key type compatible with legacy v4 implementations, see {@link EdDSAPublicBCPGKey} with + * {@link PublicKeyAlgorithmTags#EDDSA_LEGACY}. + * + * @see + * Crypto-Refresh - Algorithm-Specific Part for Ed448 Keys + */ +public class Ed448PublicBCPGKey + extends OctetArrayBCPGKey +{ + // 57 octets of the native public key + public static final int LENGTH = 57; + + public Ed448PublicBCPGKey(BCPGInputStream in) + throws IOException + { + super(LENGTH, in); + } + + public Ed448PublicBCPGKey(byte[] key) + { + super(LENGTH, key); + } + +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/Ed448SecretBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/Ed448SecretBCPGKey.java new file mode 100644 index 0000000000..76ac630b64 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/Ed448SecretBCPGKey.java @@ -0,0 +1,31 @@ +package org.bouncycastle.bcpg; + +import java.io.IOException; + +/** + * Secret key of type {@link PublicKeyAlgorithmTags#Ed448}. + * This type was introduced with Crypto-Refresh and can be used with v4, v6 keys. + * Note however, that legacy implementations might not understand this key type yet. + * For a key type compatible with legacy v4 implementations, see {@link EdDSAPublicBCPGKey} with + * {@link PublicKeyAlgorithmTags#EDDSA_LEGACY}. + * + * @see + * Crypto-Refresh - Algorithm-Specific Part for Ed448 Keys + */ +public class Ed448SecretBCPGKey + extends OctetArrayBCPGKey +{ + // 57 octets of the native secret key + public static final int LENGTH = 57; + + public Ed448SecretBCPGKey(BCPGInputStream in) + throws IOException + { + super(LENGTH, in); + } + + public Ed448SecretBCPGKey(byte[] key) + { + super(LENGTH, key); + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/EdDSAPublicBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/EdDSAPublicBCPGKey.java index 32767ba152..9bbcf710b4 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/EdDSAPublicBCPGKey.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/EdDSAPublicBCPGKey.java @@ -7,7 +7,14 @@ import org.bouncycastle.math.ec.ECPoint; /** - * base class for an EdDSA Public Key. + * Base class for an EdDSA Public Key. + * Here, the curve is identified by an OID and the key is MPI encoded. + * This class is used with {@link PublicKeyAlgorithmTags#EDDSA_LEGACY} only and MUST NOT be used with v6 keys. + * Modern OpenPGP uses dedicated key types: + * For {@link PublicKeyAlgorithmTags#Ed25519} see {@link Ed25519PublicBCPGKey} instead. + * For {@link PublicKeyAlgorithmTags#Ed448} see {@link Ed448PublicBCPGKey} instead. + * @see + * Crypto-Refresh - Algorithm-Specific Parts for EdDSALegacy Keys (deprecated) */ public class EdDSAPublicBCPGKey extends ECPublicBCPGKey diff --git a/pg/src/main/java/org/bouncycastle/bcpg/EdSecretBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/EdSecretBCPGKey.java index 084ce8cd16..6862fc6298 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/EdSecretBCPGKey.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/EdSecretBCPGKey.java @@ -4,7 +4,14 @@ import java.math.BigInteger; /** - * base class for an Edwards Curve Secret Key. + * Base class for an Edwards Curve (EdDSA) Secret Key. + * This class is used with {@link PublicKeyAlgorithmTags#EDDSA_LEGACY} only and MUST NOT be used with v6 keys. + * Modern OpenPGP uses dedicated key types: + * For {@link PublicKeyAlgorithmTags#Ed25519} see {@link Ed25519SecretBCPGKey} instead. + * For {@link PublicKeyAlgorithmTags#Ed448} see {@link Ed448SecretBCPGKey} instead. + * + * @see + * Crypto-Refresh - Algorithm-Specific Parts for EdDSALegacy Keys (deprecated) */ public class EdSecretBCPGKey extends BCPGObject diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ElGamalPublicBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/ElGamalPublicBCPGKey.java index c5347a605f..600778dfb7 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/ElGamalPublicBCPGKey.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/ElGamalPublicBCPGKey.java @@ -1,6 +1,6 @@ package org.bouncycastle.bcpg; -import java.io.*; +import java.io.IOException; import java.math.BigInteger; /** diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ElGamalSecretBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/ElGamalSecretBCPGKey.java index 0354ecf790..6b8a1d73ef 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/ElGamalSecretBCPGKey.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/ElGamalSecretBCPGKey.java @@ -1,6 +1,6 @@ package org.bouncycastle.bcpg; -import java.io.*; +import java.io.IOException; import java.math.BigInteger; /** diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ExperimentalPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/ExperimentalPacket.java index 78887e84a2..b787b02ba9 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/ExperimentalPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/ExperimentalPacket.java @@ -10,9 +10,21 @@ public class ExperimentalPacket extends ContainedPacket implements PublicKeyAlgorithmTags { - private int tag; private byte[] contents; - + + /** + * + * @param in + * @throws IOException + */ + ExperimentalPacket( + int tag, + BCPGInputStream in) + throws IOException + { + this(tag, in, false); + } + /** * * @param in @@ -20,16 +32,21 @@ public class ExperimentalPacket */ ExperimentalPacket( int tag, - BCPGInputStream in) + BCPGInputStream in, + boolean newPacketFormat) throws IOException { - this.tag = tag; + super(tag, newPacketFormat); + this.contents = in.readAll(); } + /** + * @deprecated use getPacketTag(); + */ public int getTag() { - return tag; + return getPacketTag(); } public byte[] getContents() @@ -41,6 +58,6 @@ public void encode( BCPGOutputStream out) throws IOException { - out.writePacket(tag, contents); + out.writePacket(hasNewPacketFormat(), getPacketTag(), contents); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/FingerprintUtil.java b/pg/src/main/java/org/bouncycastle/bcpg/FingerprintUtil.java new file mode 100644 index 0000000000..6e258c623f --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/FingerprintUtil.java @@ -0,0 +1,115 @@ +package org.bouncycastle.bcpg; + +import org.bouncycastle.util.Pack; + +public class FingerprintUtil +{ + + /** + * Derive a 64 bit key-id from a version 6 OpenPGP fingerprint. + * For v6 keys, the key-id corresponds to the left-most 8 octets of the fingerprint. + * + * @param v6Fingerprint 32 byte fingerprint + * @return key-id + */ + public static long keyIdFromV6Fingerprint(byte[] v6Fingerprint) + { + return longFromLeftMostBytes(v6Fingerprint); + } + + /** + * Derive a 64 bit key-id from a version 5 LibrePGP fingerprint. + * For such keys, the key-id corresponds to the left-most 8 octets of the fingerprint. + * + * @param v5Fingerprint 32 byte fingerprint + * @return key-id + */ + public static long keyIdFromLibrePgpFingerprint(byte[] v5Fingerprint) + { + return longFromLeftMostBytes(v5Fingerprint); + } + + /** + * Derive a 64 bit key-id from a version 4 OpenPGP fingerprint. + * For v4 keys, the key-id corresponds to the right-most 8 octets of the fingerprint. + * + * @param v4Fingerprint 20 byte fingerprint + * @return key-id + */ + public static long keyIdFromV4Fingerprint(byte[] v4Fingerprint) + { + return longFromRightMostBytes(v4Fingerprint); + } + + /** + * Convert the left-most 8 bytes from the given array to a long. + * + * @param bytes bytes + * @return long + */ + public static long longFromLeftMostBytes(byte[] bytes) + { + return readKeyID(bytes); + } + + /** + * Convert the right-most 8 bytes from the given array to a long. + * + * @param bytes bytes + * @return long + */ + public static long longFromRightMostBytes(byte[] bytes) + { + return readKeyID(bytes, bytes.length - 8); + } + + /** + * Read a key-ID from the first 8 octets of the given byte array. + * @param bytes byte array + * @return key-ID + */ + public static long readKeyID(byte[] bytes) + { + return readKeyID(bytes, 0); + } + + /** + * Read a key-ID from 8 octets of the given byte array starting at offset. + * @param bytes byte array + * @param offset offset + * @return key-ID + */ + public static long readKeyID(byte[] bytes, int offset) + { + if (bytes.length < 8) + { + throw new IllegalArgumentException("Byte array MUST contain at least 8 bytes"); + } + return Pack.bigEndianToLong(bytes, offset); + } + + /** + * Write the key-ID encoded as 8 octets to the given byte array, starting at index offset. + * @param keyID keyID + * @param bytes byte array + * @param offset starting offset + */ + public static void writeKeyID(long keyID, byte[] bytes, int offset) + { + if (bytes.length - offset < 8) + { + throw new IllegalArgumentException("Not enough space to write key-ID to byte array."); + } + Pack.longToBigEndian(keyID, bytes, offset); + } + + /** + * Write the key-ID to the first 8 octets of the given byte array. + * @param keyID keyID + * @param bytes byte array + */ + public static void writeKeyID(long keyID, byte[] bytes) + { + writeKeyID(keyID, bytes, 0); + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/HashAlgorithmTags.java b/pg/src/main/java/org/bouncycastle/bcpg/HashAlgorithmTags.java index eb0a114344..2a6b987838 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/HashAlgorithmTags.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/HashAlgorithmTags.java @@ -1,32 +1,113 @@ package org.bouncycastle.bcpg; /** - * basic tags for hash algorithms + * Basic tags for hash algorithms. + * + * @see + * RFC4880 - Hash Algorithms + * @see + * LibrePGP - Hash Algorithms + * @see + * Crypto-Refresh - Hash Algorithms */ public interface HashAlgorithmTags { - int MD5 = 1; // MD5 - int SHA1 = 2; // SHA-1 - int RIPEMD160 = 3; // RIPE-MD/160 - int DOUBLE_SHA = 4; // Reserved for double-width SHA (experimental) - int MD2 = 5; // MD2 - int TIGER_192 = 6; // Reserved for TIGER/192 - int HAVAL_5_160 = 7; // Reserved for HAVAL (5 pass, 160-bit) - - int SHA256 = 8; // SHA-256 - int SHA384 = 9; // SHA-384 - int SHA512 = 10; // SHA-512 - int SHA224 = 11; // SHA-224 - int SHA3_256 = 12; // SHA3-256 - int SHA3_512 = 14; // SHA3-512 + /** + * MD5. + * Implementations MUST NOT use this to generate signatures. + * Implementations MUST NOT use this as a hash function in ECDH KDFs. + * Implementations MUST NOT generate packets with this hash function in an S2K KDF. + * Implementations MUST NOT use this hash function in an S2K KDF to decrypt v6+ packets. + */ + int MD5 = 1; + /** + * SHA-1. + * Implementations MUST NOT use this to generate signatures. + * Implementations MUST NOT use this as a hash function in ECDH KDFs. + * Implementations MUST NOT generate packets with this hash function in an S2K KDF. + * Implementations MUST NOT use this hash function in an S2K KDF to decrypt v6+ packets. + */ + int SHA1 = 2; + /** + * RIPEMD-160. + * Implementations MUST NOT use this to generate signatures. + * Implementations MUST NOT use this as a hash function in ECDH KDFs. + * Implementations MUST NOT generate packets with this hash function in an S2K KDF. + * Implementations MUST NOT use this hash function in an S2K KDF to decrypt v6+ packets. + */ + int RIPEMD160 = 3; + /** + * Reserved for double-width SHA (experimental). + */ + int DOUBLE_SHA = 4; + /** + * Reserved for MD2. + */ + int MD2 = 5; + /** + * Reserved for TIGER/192. + */ + int TIGER_192 = 6; + /** + * Reserved for HAVAL (5 pass, 160-bit). + */ + int HAVAL_5_160 = 7; + /** + * SHA2-256. + * Compliant implementations MUST implement. + */ + int SHA256 = 8; + /** + * SHA2-384. + */ + int SHA384 = 9; + /** + * SHA2-512. + */ + int SHA512 = 10; + /** + * SHA2-224. + */ + int SHA224 = 11; + /** + * SHA3-256. + */ + int SHA3_256 = 12; + /** + * SHA3-512. + */ + int SHA3_512 = 14; + /** + * Reserved for MD4. + * @deprecated non-standard + */ int MD4 = 301; - int SHA3_224 = 312; // SHA3-224 - int SHA3_256_OLD = 313; //SHA3-256 - int SHA3_384 = 314; // SHA3-384 - int SHA3_512_OLD = 315; // SHA3-512 + /** + * Reserved for SHA3-224. + * @deprecated non-standard + */ + int SHA3_224 = 312; + /** + * Reserved for SHA3-256. + * @deprecated non-standard + */ + int SHA3_256_OLD = 313; + /** + * Reserved for SHA3-384. + * @deprecated non-standard + */ + int SHA3_384 = 314; + /** + * Reserved for SHA3-512. + * @deprecated non-standard + */ + int SHA3_512_OLD = 315; - - int SM3 = 326; // SM3 + /** + * Reserved for SM3. + * @deprecated non-standard + */ + int SM3 = 326; } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/HashUtils.java b/pg/src/main/java/org/bouncycastle/bcpg/HashUtils.java new file mode 100644 index 0000000000..b4576391b6 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/HashUtils.java @@ -0,0 +1,53 @@ +package org.bouncycastle.bcpg; + +public class HashUtils +{ + + /** + * Return the length of the salt per hash algorithm, used in OpenPGP v6 signatures. + * + * @see + * Salt Size declarations + * @param hashAlgorithm hash algorithm tag + * @return size of the salt for the given hash algorithm in bytes + */ + public static int getV6SignatureSaltSizeInBytes(int hashAlgorithm) + { + switch (hashAlgorithm) + { + case HashAlgorithmTags.SHA256: + case HashAlgorithmTags.SHA224: + case HashAlgorithmTags.SHA3_256: + case HashAlgorithmTags.SHA3_256_OLD: + return 16; + case HashAlgorithmTags.SHA384: + return 24; + case HashAlgorithmTags.SHA512: + case HashAlgorithmTags.SHA3_512: + case HashAlgorithmTags.SHA3_512_OLD: + return 32; + default: + throw new IllegalArgumentException("Salt size not specified for Hash Algorithm with ID " + hashAlgorithm); + } + } + + /** + * Return true, if the encountered saltLength matches the value the specification gives for the hashAlgorithm. + * + * @param hashAlgorithm hash algorithm tag + * @param saltSize encountered salt size + * @return true if the encountered size matches the spec + * @implNote LibrePGP allows for zero-length signature salt values, so this method only works for IETF OpenPGP v6. + */ + public boolean saltSizeMatchesSpec(int hashAlgorithm, int saltSize) + { + try + { + return saltSize == getV6SignatureSaltSizeInBytes(hashAlgorithm); + } + catch (IllegalArgumentException e) // Unknown algorithm or salt size is not specified for the hash algo + { + return false; + } + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/InputStreamPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/InputStreamPacket.java index 493b908353..2dfb9b87af 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/InputStreamPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/InputStreamPacket.java @@ -8,9 +8,29 @@ public class InputStreamPacket { private BCPGInputStream in; + // it's unlikely this is being used, but just in case we'll mark + // unknown inputs as reserved. public InputStreamPacket( BCPGInputStream in) { + super(RESERVED); + + this.in = in; + } + + InputStreamPacket( + BCPGInputStream in, + int packetTag) + { + this(in, packetTag, false); + } + + InputStreamPacket( + BCPGInputStream in, + int packetTag, + boolean newPacketFormat) + { + super(packetTag, newPacketFormat); this.in = in; } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/LiteralDataPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/LiteralDataPacket.java index 6612f8f1e7..2b1a196a51 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/LiteralDataPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/LiteralDataPacket.java @@ -16,10 +16,18 @@ public class LiteralDataPacket long modDate; LiteralDataPacket( - BCPGInputStream in) + BCPGInputStream in) + throws IOException + { + this(in, false); + } + + LiteralDataPacket( + BCPGInputStream in, + boolean newPacketFormat) throws IOException { - super(in); + super(in, LITERAL_DATA, newPacketFormat); format = in.read(); int l = in.read(); @@ -35,7 +43,7 @@ public class LiteralDataPacket fileName[i] = (byte)ch; } - modDate = ((long)in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); + modDate = StreamUtil.readTime(in); if (modDate < 0) { throw new IOException("literal data truncated in header"); @@ -55,7 +63,7 @@ public int getFormat() */ public long getModificationTime() { - return modDate * 1000L; + return modDate; } /** diff --git a/pg/src/main/java/org/bouncycastle/bcpg/MPInteger.java b/pg/src/main/java/org/bouncycastle/bcpg/MPInteger.java index ebd2261502..286ab2ab34 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/MPInteger.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/MPInteger.java @@ -1,6 +1,6 @@ package org.bouncycastle.bcpg; -import java.io.*; +import java.io.IOException; import java.math.BigInteger; /** @@ -15,7 +15,7 @@ public MPInteger( BCPGInputStream in) throws IOException { - int length = (in.read() << 8) | in.read(); + int length = StreamUtil.read2OctetLength(in); byte[] bytes = new byte[(length + 7) / 8]; in.readFully(bytes); @@ -43,11 +43,8 @@ public void encode( BCPGOutputStream out) throws IOException { - int length = value.bitLength(); - - out.write(length >> 8); - out.write(length); - + StreamUtil.write2OctetLength(out, value.bitLength()); + byte[] bytes = value.toByteArray(); if (bytes[0] == 0) diff --git a/pg/src/main/java/org/bouncycastle/bcpg/MarkerPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/MarkerPacket.java index 027eb9c000..dad7658e3f 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/MarkerPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/MarkerPacket.java @@ -5,24 +5,34 @@ /** * Basic type for a marker packet */ -public class MarkerPacket +public class MarkerPacket extends ContainedPacket -{ +{ // "PGP" - - byte[] marker = { (byte)0x50, (byte)0x47, (byte)0x50 }; - + + byte[] marker = {(byte)0x50, (byte)0x47, (byte)0x50}; + + public MarkerPacket( + BCPGInputStream in) + throws IOException + { + this(in, false); + } + public MarkerPacket( - BCPGInputStream in) + BCPGInputStream in, + boolean newPacketFormat) throws IOException { - in.readFully(marker); + super(MARKER, newPacketFormat); + + in.readFully(marker); } - + public void encode( - BCPGOutputStream out) + BCPGOutputStream out) throws IOException { - out.writePacket(MARKER, marker); + out.writePacket(hasNewPacketFormat(), MARKER, marker); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ModDetectionCodePacket.java b/pg/src/main/java/org/bouncycastle/bcpg/ModDetectionCodePacket.java index 812e9374f3..2fcef653da 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/ModDetectionCodePacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/ModDetectionCodePacket.java @@ -1,6 +1,6 @@ package org.bouncycastle.bcpg; -import java.io.*; +import java.io.IOException; /** * basic packet for a modification detection code packet. @@ -9,11 +9,21 @@ public class ModDetectionCodePacket extends ContainedPacket { private byte[] digest; - + + ModDetectionCodePacket( + BCPGInputStream in) + throws IOException + { + this(in, false); + } + ModDetectionCodePacket( - BCPGInputStream in) + BCPGInputStream in, + boolean newPacketFormat) throws IOException - { + { + super(MOD_DETECTION_CODE, newPacketFormat); + this.digest = new byte[20]; in.readFully(this.digest); } @@ -21,7 +31,9 @@ public class ModDetectionCodePacket public ModDetectionCodePacket( byte[] digest) throws IOException - { + { + super(MOD_DETECTION_CODE); + this.digest = new byte[digest.length]; System.arraycopy(digest, 0, this.digest, 0, this.digest.length); @@ -40,6 +52,6 @@ public void encode( BCPGOutputStream out) throws IOException { - out.writePacket(MOD_DETECTION_CODE, digest, false); + out.writePacket(hasNewPacketFormat(), MOD_DETECTION_CODE, digest); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/OctetArrayBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/OctetArrayBCPGKey.java new file mode 100644 index 0000000000..483d41729b --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/OctetArrayBCPGKey.java @@ -0,0 +1,67 @@ +package org.bouncycastle.bcpg; + +import java.io.IOException; +import org.bouncycastle.util.Arrays; + +/** + * Public/Secret BCPGKey which is encoded as an array of octets rather than an MPI. + */ +public abstract class OctetArrayBCPGKey + extends BCPGObject + implements BCPGKey +{ + private final byte[] key; + + OctetArrayBCPGKey(int length, BCPGInputStream in) + throws IOException + { + key = new byte[length]; + in.readFully(key); + } + + OctetArrayBCPGKey(int length, byte[] key) + { + if (key.length != length) + { + throw new IllegalArgumentException("unexpected key encoding length: expected " + length + " bytes, got " + key.length); + } + this.key = new byte[length]; + System.arraycopy(key, 0, this.key, 0, length); + } + + /** + * return the standard PGP encoding of the key. + * + * @see org.bouncycastle.bcpg.BCPGKey#getEncoded() + */ + @Override + public byte[] getEncoded() + { + try + { + return super.getEncoded(); + } + catch (IOException e) + { + return null; + } + } + + @Override + public String getFormat() + { + return "PGP"; + } + + @Override + public void encode(BCPGOutputStream out) + throws IOException + { + out.write(key); + } + + public byte[] getKey() + { + return Arrays.clone(key); + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/OnePassSignaturePacket.java b/pg/src/main/java/org/bouncycastle/bcpg/OnePassSignaturePacket.java index d923019dbe..9953b752b5 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/OnePassSignaturePacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/OnePassSignaturePacket.java @@ -1,42 +1,112 @@ package org.bouncycastle.bcpg; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.io.Streams; + import java.io.ByteArrayOutputStream; import java.io.IOException; /** - * generic signature object + * One-Pass-Signature packet. + * OPS packets are used to enable verification of signed messages in one-pass by providing necessary metadata + * about the signed data up front, so the consumer can start processing the signed data without needing + * to process the signature packet at the end of the data stream first. + * + * There are two versions of this packet currently defined. + * Version 3 OPS packets are used with {@link SignaturePacket SignaturePackets} of version 3 and 4. + * Version 6 OPS packets are used with {@link SignaturePacket SignaturePackets} of version 6. + * It is not clear to me, which version of the OPS packet is intended to be used with version 5 signatures. + * + * @see + * Definition of version 3 OPS packets in RFC4880 + * @see + * Definition of version 3 and 6 OPS packets in crypto-refresh + * @see + * Definition of version 3 and 6 OPS packets in librepgp */ public class OnePassSignaturePacket extends ContainedPacket { - private int version; - private int sigType; - private int hashAlgorithm; - private int keyAlgorithm; - private long keyID; - private int isContaining; - + public static final int VERSION_3 = 3; + public static final int VERSION_6 = 6; + + private final int version; + private final int sigType; + private final int hashAlgorithm; + private final int keyAlgorithm; + private final long keyID; + private final byte[] fingerprint; + private final byte[] salt; + private final int isContaining; + + /** + * Parse a {@link OnePassSignaturePacket} from an OpenPGP packet input stream. + * @param in OpenPGP packet input stream + * @throws IOException when the end of stream is prematurely reached, or when the packet is malformed + */ + OnePassSignaturePacket( + BCPGInputStream in) + throws IOException + { + this(in, false); + } + OnePassSignaturePacket( - BCPGInputStream in) + BCPGInputStream in, + boolean newPacketFormat) throws IOException { + super(ONE_PASS_SIGNATURE, newPacketFormat); + version = in.read(); sigType = in.read(); hashAlgorithm = in.read(); keyAlgorithm = in.read(); - - keyID |= (long)in.read() << 56; - keyID |= (long)in.read() << 48; - keyID |= (long)in.read() << 40; - keyID |= (long)in.read() << 32; - keyID |= (long)in.read() << 24; - keyID |= (long)in.read() << 16; - keyID |= (long)in.read() << 8; - keyID |= in.read(); - + + if (version == VERSION_3) + { + keyID = StreamUtil.readKeyID(in); + fingerprint = null; + salt = null; + } + else if (version == VERSION_6) + { + int saltLen = in.read(); + if (saltLen < 0) + { + throw new IOException("Version 6 OPS packet has invalid salt length."); + } + salt = new byte[saltLen]; + in.readFully(salt); + + fingerprint = new byte[32]; + in.readFully(fingerprint); + + keyID = FingerprintUtil.keyIdFromV6Fingerprint(fingerprint); + } + else + { + Streams.drain(in); + throw new UnsupportedPacketVersionException("Unsupported OnePassSignature packet version encountered: " + version); + } + isContaining = in.read(); } - + + /** + * Create a version 3 {@link OnePassSignaturePacket}. + * Version 3 OPS packets are used with version 3 and version 4 {@link SignaturePacket SignaturePackets}. + * + * To create an OPS packet for use with a version 6 {@link SignaturePacket}, + * see {@link OnePassSignaturePacket#OnePassSignaturePacket(int, int, int, byte[], byte[], boolean)}. + * + * @param sigType signature type + * @param hashAlgorithm hash algorithm tag + * @param keyAlgorithm public key algorithm tag + * @param keyID id of the signing key + * @param isNested if false, there is another OPS packet after this one, which applies to the same data. + * it true, the corresponding signature is calculated also over succeeding additional OPS packets. + */ public OnePassSignaturePacket( int sigType, int hashAlgorithm, @@ -44,14 +114,58 @@ public OnePassSignaturePacket( long keyID, boolean isNested) { - this.version = 3; + super(ONE_PASS_SIGNATURE); + + this.version = VERSION_3; this.sigType = sigType; this.hashAlgorithm = hashAlgorithm; this.keyAlgorithm = keyAlgorithm; this.keyID = keyID; + this.fingerprint = null; + this.salt = null; this.isContaining = (isNested) ? 0 : 1; } - + + /** + * Create a version 6 {@link OnePassSignaturePacket}. + * + * @param sigType signature type + * @param hashAlgorithm hash algorithm tag + * @param keyAlgorithm public key algorithm tag + * @param salt random salt. The length of this array depends on the hash algorithm in use. + * @param fingerprint 32 octet fingerprint of the (v6) signing key + * @param isNested if false, there is another OPS packet after this one, which applies to the same data. + * it true, the corresponding signature is calculated also over succeeding additional OPS packets. + */ + public OnePassSignaturePacket( + int sigType, + int hashAlgorithm, + int keyAlgorithm, + byte[] salt, + byte[] fingerprint, + boolean isNested) + { + super(ONE_PASS_SIGNATURE); + + this.version = VERSION_6; + this.sigType = sigType; + this.hashAlgorithm = hashAlgorithm; + this.keyAlgorithm = keyAlgorithm; + this.salt = salt; + this.fingerprint = fingerprint; + this.isContaining = (isNested) ? 0 : 1; + keyID = FingerprintUtil.keyIdFromV6Fingerprint(fingerprint); + } + + /** + * Return the packet version. + * @return version + */ + public int getVersion() + { + return version; + } + /** * Return the signature type. * @return the signature type @@ -62,7 +176,8 @@ public int getSignatureType() } /** - * return the encryption algorithm tag + * Return the ID of the public key encryption algorithm. + * @return public key algorithm tag */ public int getKeyAlgorithm() { @@ -70,7 +185,8 @@ public int getKeyAlgorithm() } /** - * return the hashAlgorithm tag + * Return the algorithm ID of the hash algorithm. + * @return hash algorithm tag */ public int getHashAlgorithm() { @@ -78,16 +194,37 @@ public int getHashAlgorithm() } /** - * @return long + * Return the key-id of the signing key. + * @return key id */ public long getKeyID() { return keyID; } + /** + * Return the version 6 fingerprint of the issuer. + * Only for version 6 packets. + * @return 32 bytes issuer fingerprint + */ + public byte[] getFingerprint() + { + return Arrays.clone(fingerprint); + } + + /** + * Return the salt used in the signature. + * Only for version 6 packets. + * @return salt + */ + public byte[] getSalt() + { + return Arrays.clone(salt); + } + /** * Return true, if the signature contains any signatures that follow. - * An bracketing OPS is followed by additional OPS packets and is calculated over all the data between itself + * A bracketing OPS is followed by additional OPS packets and is calculated over all the data between itself * and its corresponding signature (it is an attestation for encapsulated signatures). * * @return true if encapsulating, false otherwise @@ -98,7 +235,9 @@ public boolean isContaining() } /** - * + * Encode the contents of this packet into the given packet output stream. + * + * @param out OpenPGP packet output stream */ public void encode( BCPGOutputStream out) @@ -112,19 +251,22 @@ public void encode( pOut.write(hashAlgorithm); pOut.write(keyAlgorithm); - pOut.write((byte)(keyID >> 56)); - pOut.write((byte)(keyID >> 48)); - pOut.write((byte)(keyID >> 40)); - pOut.write((byte)(keyID >> 32)); - pOut.write((byte)(keyID >> 24)); - pOut.write((byte)(keyID >> 16)); - pOut.write((byte)(keyID >> 8)); - pOut.write((byte)(keyID)); - + if (version == VERSION_3) + { + StreamUtil.writeKeyID(pOut, keyID); + } + else if (version == VERSION_6) + { + pOut.write(salt.length); + pOut.write(salt); + pOut.write(fingerprint); + } + pOut.write(isContaining); pOut.close(); - out.writePacket(ONE_PASS_SIGNATURE, bOut.toByteArray()); + out.writePacket(hasNewPacketFormat(), ONE_PASS_SIGNATURE, bOut.toByteArray()); } + } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/Packet.java b/pg/src/main/java/org/bouncycastle/bcpg/Packet.java index b233fd56ed..697683c14c 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/Packet.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/Packet.java @@ -5,5 +5,59 @@ public class Packet implements PacketTags { + private final int packetTag; + private final boolean newPacketFormat; + // for API compatibility + public Packet() + { + this(RESERVED); + } + + Packet(int packetTag) + { + this(packetTag, false); + } + + Packet(int packetTag, boolean newPacketFormat) + { + this.packetTag = packetTag; + this.newPacketFormat = newPacketFormat; + } + + /** + * Return the tag of the packet. + * + * @return packet tag + */ + public final int getPacketTag() + { + return packetTag; + } + + /** + * Return true, if this instance of a packet was encoded using the new packet format. + * If the packet was encoded using the old legacy format, return false instead. + * + * @return true if new packet format encoding is used + */ + public boolean hasNewPacketFormat() + { + return newPacketFormat; + } + + /** + * Returns whether the packet is to be considered critical for v6 implementations. + * Packets with tags less or equal to 39 are critical. + * Tags 40 to 59 are reserved for unassigned, non-critical packets. + * Tags 60 to 63 are non-critical private or experimental packets. + * + * @see + * Packet Tags + * @return true if the packet is critical, false otherwise. + */ + public boolean isCritical() + { + return getPacketTag() <= 39; + } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/PacketFormat.java b/pg/src/main/java/org/bouncycastle/bcpg/PacketFormat.java new file mode 100644 index 0000000000..61f62d0340 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/PacketFormat.java @@ -0,0 +1,26 @@ +package org.bouncycastle.bcpg; + +/** + * OpenPGP Packet Header Length Format. + * + * @see + * OpenPGP Packet Headers + */ +public enum PacketFormat +{ + /** + * Always use the old (legacy) packet format. + */ + LEGACY, + + /** + * Always use the current (new) packet format. + */ + CURRENT, + + /** + * Let the individual packet decide the format (see {@link Packet#hasNewPacketFormat()}). + * This allows to round-trip packets without changing the packet format. + */ + ROUNDTRIP +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/PaddingPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/PaddingPacket.java index 2d70cfd173..6f3c128bf7 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/PaddingPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/PaddingPacket.java @@ -12,13 +12,23 @@ public class PaddingPacket private final byte[] padding; public PaddingPacket(BCPGInputStream in) + throws IOException + { + this(in, true); + } + + public PaddingPacket(BCPGInputStream in, boolean newPacketFormat) throws IOException { + super(PADDING, newPacketFormat); + padding = Streams.readAll(in); } public PaddingPacket(byte[] padding) { + super(PADDING, true); + this.padding = padding; } @@ -29,6 +39,10 @@ public PaddingPacket(int octetLen, SecureRandom random) private static byte[] randomBytes(int octetCount, SecureRandom random) { + if (octetCount <= 0) + { + throw new IllegalArgumentException("Octet count MUST NOT be 0 nor negative."); + } byte[] bytes = new byte[octetCount]; random.nextBytes(bytes); return bytes; @@ -43,6 +57,6 @@ public byte[] getPadding() public void encode(BCPGOutputStream pOut) throws IOException { - pOut.writePacket(PacketTags.PADDING, padding); + pOut.writePacket(hasNewPacketFormat(), PacketTags.PADDING, padding); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyAlgorithmTags.java b/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyAlgorithmTags.java index ed06f600f4..f6aadbc957 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyAlgorithmTags.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyAlgorithmTags.java @@ -1,33 +1,101 @@ package org.bouncycastle.bcpg; /** - * Public Key Algorithm tag numbers + * Public Key Algorithm IDs. + * + * @see + * https://www.rfc-editor.org/rfc/rfc4880.html#section-9.1 + * @see + * https://www.ietf.org/archive/id/draft-koch-librepgp-00.html#name-public-key-algorithms + * @see + * https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-public-key-algorithms */ public interface PublicKeyAlgorithmTags { + /** + * RSA encryption/signing algorithm. + */ int RSA_GENERAL = 1; // RSA (Encrypt or Sign) + /** + * Deprecated tag for encrypt-only RSA. + * MUST NOT be generated. + * @deprecated use {@link #RSA_GENERAL} instead. + */ int RSA_ENCRYPT = 2; // RSA Encrypt-Only + /** + * Deprecated tag for sign-only RSA. + * MUST NOT be generated. + * @deprecated use {@link #RSA_GENERAL} instead. + */ int RSA_SIGN = 3; // RSA Sign-Only + /** + * Encrypt-only ElGamal. + */ int ELGAMAL_ENCRYPT = 16; // Elgamal (Encrypt-Only), see [ELGAMAL] + /** + * DSA. + */ int DSA = 17; // DSA (Digital Signature Standard) /** - * @deprecated use ECDH + * Deprecated tag for ECDH. + * @deprecated use {@link #ECDH} instead. + */ + int EC = 18; // Misnamed constant + /** + * Elliptic curve Diffie-Hellman. + */ + int ECDH = 18; // Elliptic Curve Diffie-Hellman + /** + * Elliptic curve digital signing algorithm. + */ + int ECDSA = 19; // Elliptic Curve Digital Signing Algorithm + /** + * Reserved tag for sign+encrypt ElGamal. + * MUST NOT be generated. + * An implementation MUST NOT generate ElGamal signatures. + * @deprecated use {@link #ELGAMAL_ENCRYPT} instead. + */ + int ELGAMAL_GENERAL = 20; // Reserved Elgamal (Encrypt or Sign) + /** + * Reserved tag for IETF-style S/MIME Diffie-Hellman. */ - int EC = 18; // Reserved for Elliptic Curve - int ECDH = 18; // Reserved for Elliptic Curve (actual algorithm name) - int ECDSA = 19; // Reserved for ECDSA - int ELGAMAL_GENERAL = 20; // Elgamal (Encrypt or Sign) int DIFFIE_HELLMAN = 21; // Reserved for Diffie-Hellman (X9.42, as defined for IETF-S/MIME) /** - * @deprecated use Ed25519 or Ed448 + * Misnamed tag for legacy EdDSA. + * @deprecated use {@link #EDDSA_LEGACY} instead. + */ + int EDDSA = 22; // EdDSA - (internet draft, but appearing in use); misnamed constant + /** + * Legacy EdDSA (curve identified by OID). + * MUST NOT be used with v6 keys (use {@link #Ed25519}, {@link #Ed448} instead). */ - int EDDSA = 22; // EdDSA - (internet draft, but appearing in use) int EDDSA_LEGACY = 22; // new name for old EDDSA tag. - - int X25519 = 25; - int X448 = 26; - int Ed25519 = 27; - int Ed448 = 28; + /** + * Reserved tag for AEDH. + */ + int AEDH = 23; // Reserved + /** + * Reserved tag for AEDSA. + */ + int AEDSA = 24; // Reserved + /** + * X25519 encryption algorithm. + * C-R compliant implementations MUST implement support for this. + */ + int X25519 = 25; // X25519 + /** + * X448 encryption algorithm. + */ + int X448 = 26; // X448 + /** + * Ed25519 signing algorithm. + * C-R compliant implementations MUST implement support for this. + */ + int Ed25519 = 27; // new style Ed25519 + /** + * Ed448 signing algorithm. + */ + int Ed448 = 28; // new style Ed448 int EXPERIMENTAL_1 = 100; int EXPERIMENTAL_2 = 101; diff --git a/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyEncSessionPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyEncSessionPacket.java index 162ee6f38e..b75dc5e4c3 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyEncSessionPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyEncSessionPacket.java @@ -9,51 +9,91 @@ /** * basic packet for a PGP public key */ -public class PublicKeyEncSessionPacket - extends ContainedPacket implements PublicKeyAlgorithmTags +public class PublicKeyEncSessionPacket + extends ContainedPacket + implements PublicKeyAlgorithmTags { - private int version; - private long keyID; - private int algorithm; - private byte[][] data; + /** + * Version 3 PKESK packet. + * Used only with {@link SymmetricEncIntegrityPacket#VERSION_1 V1 SEIPD} or {@link SymmetricEncDataPacket SED} packets. + */ + public static final int VERSION_3 = 3; + + /** + * Version 6 PKESK packet. + * Used only with {@link SymmetricEncIntegrityPacket#VERSION_2 V2 SEIPD} packets. + */ + public static final int VERSION_6 = 6; + + private int version; // v3, v6 + private long keyID; // v3 + private int algorithm; // v3, v6 + private byte[][] data; // v3, v6 + private int keyVersion; // v6 + private byte[] keyFingerprint; // v6 PublicKeyEncSessionPacket( - BCPGInputStream in) + BCPGInputStream in) + throws IOException + { + this(in, false); + } + + PublicKeyEncSessionPacket( + BCPGInputStream in, + boolean newPacketFormat) throws IOException - { + { + super(PUBLIC_KEY_ENC_SESSION, newPacketFormat); + version = in.read(); - if (version != 3) + + if (version == VERSION_3) + { + keyID = StreamUtil.readKeyID(in); + } + else if (version == VERSION_6) + { + int keyInfoLen = in.read(); + if (keyInfoLen == 0) + { + // anon recipient + keyVersion = 0; + keyFingerprint = new byte[0]; + } + else + { + keyVersion = in.read(); + keyFingerprint = new byte[keyInfoLen - 1]; + in.readFully(keyFingerprint); + } + } + else { throw new UnsupportedPacketVersionException("Unsupported PGP public key encrypted session key packet version encountered: " + version); } - - keyID |= (long)in.read() << 56; - keyID |= (long)in.read() << 48; - keyID |= (long)in.read() << 40; - keyID |= (long)in.read() << 32; - keyID |= (long)in.read() << 24; - keyID |= (long)in.read() << 16; - keyID |= (long)in.read() << 8; - keyID |= in.read(); - + + // common between v3 and v6 algorithm = in.read(); - + switch (algorithm) { case RSA_ENCRYPT: case RSA_GENERAL: data = new byte[1][]; - + data[0] = new MPInteger(in).getEncoded(); break; case ELGAMAL_ENCRYPT: case ELGAMAL_GENERAL: data = new byte[2][]; - + data[0] = new MPInteger(in).getEncoded(); data[1] = new MPInteger(in).getEncoded(); break; case ECDH: + case X448: + case X25519: data = new byte[1][]; data[0] = Streams.readAll(in); @@ -61,14 +101,24 @@ public class PublicKeyEncSessionPacket default: throw new IOException("unknown PGP public key algorithm encountered"); } + } - + + /** + * Create a new V3 PKESK packet. + * + * @param keyID ID of the recipient key, 0 for anonymous + * @param algorithm public key algorithm + * @param data session data + */ public PublicKeyEncSessionPacket( - long keyID, - int algorithm, - byte[][] data) + long keyID, + int algorithm, + byte[][] data) { - this.version = 3; + super(PUBLIC_KEY_ENC_SESSION); + + this.version = VERSION_3; this.keyID = keyID; this.algorithm = algorithm; this.data = new byte[data.length][]; @@ -78,47 +128,150 @@ public PublicKeyEncSessionPacket( this.data[i] = Arrays.clone(data[i]); } } - + + /** + * Create a new V6 PKESK packet. + * + * @param keyVersion version of the key + * @param keyFingerprint fingerprint of the key + * @param algorithm public key algorithm + * @param data session data + */ + public PublicKeyEncSessionPacket( + int keyVersion, + byte[] keyFingerprint, + int algorithm, + byte[][] data) + { + + super(PUBLIC_KEY_ENC_SESSION); + + this.version = VERSION_6; + this.keyVersion = keyVersion; + this.keyFingerprint = Arrays.clone(keyFingerprint); + this.algorithm = algorithm; + this.data = new byte[data.length][]; + + for (int i = 0; i < data.length; i++) + { + this.data[i] = Arrays.clone(data[i]); + } + } + + /** + * Create a new V3 PKESK packet. + * + * @param keyID ID of the recipient key, 0 for anonymous + * @param algorithm public key algorithm + * @param data session data + */ + public static PublicKeyEncSessionPacket createV3PKESKPacket( + long keyID, + int algorithm, + byte[][] data) + { + return new PublicKeyEncSessionPacket(keyID, algorithm, data); + } + + /** + * Create a new V6 PKESK packet. + * + * @param keyVersion version of the key + * @param keyFingerprint fingerprint of the key + * @param algorithm public key algorithm + * @param data session data + */ + public static PublicKeyEncSessionPacket createV6PKESKPacket( + int keyVersion, + byte[] keyFingerprint, + int algorithm, + byte[][] data) + { + return new PublicKeyEncSessionPacket(keyVersion, keyFingerprint, algorithm, data); + } + + /** + * Return the version of this PKESK packet. + * + * @return version + */ public int getVersion() { return version; } - + + /** + * Return the id of the recipient key. + * V3 PKESK only. TODO: Add conversion from fingerprint to key-id for V6 PKESK? + * + * @return key id + */ public long getKeyID() { return keyID; } - + + /** + * Return the fingerprint of the recipient key. + * If the recipient key is anonymous, this method returns an empty array. + * V6 PKESK packet only. + * + * @return key fingerprint + */ + public byte[] getKeyFingerprint() + { + return Arrays.clone(keyFingerprint); + } + + /** + * Return the version number of the recipient key. + * If the recipient key is anonymous, this method returns 0. + * V6 PKESK packet only. + * + * @return key version + */ + public int getKeyVersion() + { + return keyVersion; + } + + /** + * Return the public key algorithm of the recipient key. + * + * @return public key algorithm + */ public int getAlgorithm() { return algorithm; } - + public byte[][] getEncSessionKey() { return data; } public void encode( - BCPGOutputStream out) + BCPGOutputStream out) throws IOException { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - BCPGOutputStream pOut = new BCPGOutputStream(bOut); - - pOut.write(version); - - pOut.write((byte)(keyID >> 56)); - pOut.write((byte)(keyID >> 48)); - pOut.write((byte)(keyID >> 40)); - pOut.write((byte)(keyID >> 32)); - pOut.write((byte)(keyID >> 24)); - pOut.write((byte)(keyID >> 16)); - pOut.write((byte)(keyID >> 8)); - pOut.write((byte)(keyID)); - + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut); + + pOut.write(version); + + if (version == VERSION_3) + { + StreamUtil.writeKeyID(pOut, keyID); + } + else if (version == VERSION_6) + { + pOut.write(keyFingerprint.length + 1); + pOut.write(keyVersion); + pOut.write(keyFingerprint); + } + pOut.write(algorithm); - + for (int i = 0; i != data.length; i++) { pOut.write(data[i]); @@ -126,6 +279,6 @@ public void encode( pOut.close(); - out.writePacket(PUBLIC_KEY_ENC_SESSION , bOut.toByteArray()); + out.writePacket(hasNewPacketFormat(), PUBLIC_KEY_ENC_SESSION, bOut.toByteArray()); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyPacket.java index e053cc0125..8b7ff932c8 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyPacket.java @@ -5,32 +5,166 @@ import java.util.Date; /** - * basic packet for a PGP public key + * Base class for OpenPGP public (primary) keys. + * The public key packet holds the public parameters of an OpenPGP key pair. + * An OpenPGP certificate (transferable public key) consists of one primary key and optionally multiple subkey packets. + * + * @see + * rfc4880 - Public-Key Packet + * @see + * C-R - Public-Key Packet + * @see + * LibrePGP - Public-Key Packet */ -public class PublicKeyPacket - extends ContainedPacket implements PublicKeyAlgorithmTags +public class PublicKeyPacket + extends ContainedPacket + implements PublicKeyAlgorithmTags { - private int version; - private long time; - private int validDays; - private int algorithm; - private BCPGKey key; - + /** + * OpenPGP v3 keys are deprecated. + * They can only be used with RSA. + * + * @see + * C-R - Version 3 Public Keys + */ + public static final int VERSION_3 = 3; + /** + * OpenPGP v4 keys are (at the time of writing) widely used, but are subject to some attacks. + * + * @see + * C-R - Version 4 Public Keys + */ + public static final int VERSION_4 = 4; + /** + * Non-Standard LibrePGP introduced v5, which is only supported by a subset of vendors. + */ + public static final int LIBREPGP_5 = 5; + /** + * OpenPGP v6 keys are newly introduced. + * + * @see + * C-R - Version 6 Public Keys + */ + public static final int VERSION_6 = 6; + + private int version; + // Creation time of the key stored as seconds since epoch + private long time; + private int validDays; + private int algorithm; + private BCPGKey key; + + /** + * Parse a {@link PublicKeyPacket} from an OpenPGP {@link BCPGInputStream}. + * The packet format is remembered as {@link PacketFormat#LEGACY}. + * @param in packet input stream + * @throws IOException + */ PublicKeyPacket( - BCPGInputStream in) + BCPGInputStream in) + throws IOException + { + this(in, false); + } + + /** + * Parse a {@link PublicKeyPacket} from an OpenPGP {@link BCPGInputStream}. + * If

      newPacketFormat
      is true, the packet format is remembered as {@link PacketFormat#CURRENT}, + * otherwise as {@link PacketFormat#LEGACY}. + * @param in packet input stream + * @param newPacketFormat new packet format + * @throws IOException + */ + PublicKeyPacket( + BCPGInputStream in, + boolean newPacketFormat) throws IOException - { + { + this(PUBLIC_KEY, in, newPacketFormat); + } + + /** + * Parse a {@link PublicKeyPacket} or {@link PublicSubkeyPacket} from an OpenPGP {@link BCPGInputStream}. + * If
      keyTag
      is {@link #PUBLIC_KEY}, the packet is a primary key. + * If instead it is {@link #PUBLIC_SUBKEY}, it is a subkey packet. + * The packet format is remembered as {@link PacketFormat#LEGACY}. + * @param keyTag packet type ID + * @param in packet input stream + * @throws IOException + */ + PublicKeyPacket( + int keyTag, + BCPGInputStream in) + throws IOException + { + this(keyTag, in, false); + } + + /** + * Parse a {@link PublicKeyPacket} or {@link PublicSubkeyPacket} from an OpenPGP {@link BCPGInputStream}. + * If
      keyTag
      is {@link #PUBLIC_KEY}, the packet is a primary key. + * If instead it is {@link #PUBLIC_SUBKEY}, it is a subkey packet. + * If
      newPacketFormat
      is true, the packet format is remembered as {@link PacketFormat#CURRENT}, + * otherwise as {@link PacketFormat#LEGACY}. + * @param keyTag packet type ID + * @param in packet input stream + * @param newPacketFormat packet format + * @throws IOException if the key packet cannot be parsed + * + * @see + * C-R - Version 3 Public Keys + * @see + * C-R - Version 4 Public Keys + * @see + * C-R - Version 6 Public Keys + * @see + * LibrePGP - Public-Key Packet Formats + */ + PublicKeyPacket( + int keyTag, + BCPGInputStream in, + boolean newPacketFormat) + throws IOException + { + super(keyTag, newPacketFormat); + version = in.read(); - time = ((long)in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); - - if (version <= 3) + if (version < 2 || version > VERSION_6) { - validDays = (in.read() << 8) | in.read(); + throw new UnsupportedPacketVersionException("Unsupported Public Key Packet version encountered: " + version); } - + + time = StreamUtil.read4OctetLength(in); + + if (version == 2 || version == VERSION_3) + { + validDays = StreamUtil.read2OctetLength(in); + } + algorithm = (byte)in.read(); + long keyOctets = -1; + + if (version == LIBREPGP_5 || version == VERSION_6) + { + // TODO: Use keyOctets to be able to parse unknown keys + keyOctets = StreamUtil.read4OctetLength(in); + } + + parseKey(in, algorithm, keyOctets); + } + + /** + * Parse algorithm-specific public key material. + * @param in input stream which read just up to the public key material + * @param algorithmId public key algorithm ID + * @param optLen optional: Length of the public key material. -1 if not present. + * @throws IOException if the pk material cannot be parsed + */ + private void parseKey(BCPGInputStream in, int algorithmId, long optLen) + throws IOException + { - switch (algorithm) + switch (algorithmId) { case RSA_ENCRYPT: case RSA_GENERAL: @@ -47,92 +181,182 @@ public class PublicKeyPacket case ECDH: key = new ECDHPublicBCPGKey(in); break; + case X25519: + key = new X25519PublicBCPGKey(in); + break; + case X448: + key = new X448PublicBCPGKey(in); + break; case ECDSA: key = new ECDSAPublicBCPGKey(in); break; case EDDSA_LEGACY: key = new EdDSAPublicBCPGKey(in); break; + case Ed25519: + key = new Ed25519PublicBCPGKey(in); + break; + case Ed448: + key = new Ed448PublicBCPGKey(in); + break; default: + if (version == VERSION_6 || version == LIBREPGP_5) + { + // with version 5 & 6, we can gracefully handle unknown key types, as the length is known. + key = new UnknownBCPGKey((int) optLen, in); + break; + } throw new IOException("unknown PGP public key algorithm encountered: " + algorithm); } } - + + /** + * Construct version 4 public primary key packet. + * + * @param algorithm public key algorithm id + * @param time creation time + * @param key key object + * @deprecated use versioned {@link #PublicKeyPacket(int, int, Date, BCPGKey)} instead + */ + @Deprecated + public PublicKeyPacket( + int algorithm, + Date time, + BCPGKey key) + { + this(VERSION_4, algorithm, time, key); + } + /** - * Construct version 4 public key packet. - * - * @param algorithm - * @param time - * @param key + * Construct an OpenPGP public primary key packet. + * @param version packet version + * @param algorithm public key algorithm id + * @param time creation time + * @param key key object */ public PublicKeyPacket( - int algorithm, - Date time, - BCPGKey key) + int version, + int algorithm, + Date time, + BCPGKey key) { - this.version = 4; + this(PUBLIC_KEY, version, algorithm, time, key); + } + + /** + * Construct an OpenPGP public key packet. + * If
      keyTag
      is {@link #PUBLIC_KEY}, the packet is a primary key. + * If instead it is {@link #PUBLIC_SUBKEY}, it is a subkey packet. + * @param keyTag public key packet type ID + * @param version packet version + * @param algorithm public key algorithm id + * @param time creation time + * @param key key object + */ + PublicKeyPacket(int keyTag, int version, int algorithm, Date time, BCPGKey key) + { + super(keyTag); + + this.version = version; this.time = time.getTime() / 1000; this.algorithm = algorithm; this.key = key; } - + + /** + * Return the packet version. + * @return packet version + */ public int getVersion() { return version; } - + + /** + * Return the {@link PublicKeyAlgorithmTags algorithm id} of the public key. + * @return algorithm id + */ public int getAlgorithm() { return algorithm; } - + + /** + * Only for v3 keys - The time in days since the keys creation, during which the key is valid. + * + * @return v3 key validity period in days since creation. + * @deprecated v4 and v6 keys instead signal their expiration time via the + * {@link org.bouncycastle.bcpg.sig.KeyExpirationTime} signature subpacket. + */ public int getValidDays() { return validDays; } - + + /** + * Return the keys creation time. + * @return creation time of the key + */ public Date getTime() { return new Date(time * 1000); } - + + /** + * Return the key object. + * @return key + */ public BCPGKey getKey() { return key; } - - public byte[] getEncodedContents() + + /** + * Return the encoded packet contents without the packet frame. + * @return encoded packet contents + * @throws IOException + */ + public byte[] getEncodedContents() throws IOException { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - BCPGOutputStream pOut = new BCPGOutputStream(bOut); - + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut); + pOut.write(version); - - pOut.write((byte)(time >> 24)); - pOut.write((byte)(time >> 16)); - pOut.write((byte)(time >> 8)); - pOut.write((byte)time); - - if (version <= 3) + + StreamUtil.writeTime(pOut, time); + + if (version <= VERSION_3) { - pOut.write((byte)(validDays >> 8)); - pOut.write((byte)validDays); + StreamUtil.write2OctetLength(pOut, validDays); } - + pOut.write(algorithm); - + + if (version == VERSION_6 || version == LIBREPGP_5) + { + StreamUtil.write4OctetLength(pOut, key.getEncoded().length); + } + pOut.writeObject((BCPGObject)key); pOut.close(); return bOut.toByteArray(); } - + + /** + * Encode the packet to the OpenPGP {@link BCPGOutputStream}. + * If the {@link BCPGOutputStream} packet format is set to {@link PacketFormat#ROUNDTRIP}, the result + * of {@link #hasNewPacketFormat()} determines, which packet format is used to encode the packet. + * Otherwise, the {@link BCPGOutputStream} dictates which format to use. + * @param out packet output stream + * @throws IOException + */ public void encode( - BCPGOutputStream out) + BCPGOutputStream out) throws IOException { - out.writePacket(PUBLIC_KEY, getEncodedContents()); + out.writePacket(hasNewPacketFormat(), getPacketTag(), getEncodedContents()); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/PublicSubkeyPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/PublicSubkeyPacket.java index 32bb9e4835..4c93e8b2eb 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/PublicSubkeyPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/PublicSubkeyPacket.java @@ -9,32 +9,53 @@ public class PublicSubkeyPacket extends PublicKeyPacket { + + PublicSubkeyPacket( + BCPGInputStream in) + throws IOException + { + this(in, false); + } + PublicSubkeyPacket( - BCPGInputStream in) + BCPGInputStream in, + boolean newPacketFormat) throws IOException { - super(in); + super(PUBLIC_SUBKEY, in, newPacketFormat); } /** - * Construct version 4 public key packet. + * Construct version 4 public sub-key packet. * * @param algorithm * @param time * @param key + * @deprecated use versioned {@link #PublicSubkeyPacket(int, int, Date, BCPGKey)} instead */ + @Deprecated public PublicSubkeyPacket( int algorithm, Date time, BCPGKey key) { - super(algorithm, time, key); + this(VERSION_4, algorithm, time, key); } - - public void encode( - BCPGOutputStream out) - throws IOException + + /** + * Construct a public sub-key packet. + * + * @param version + * @param algorithm + * @param time + * @param key + */ + public PublicSubkeyPacket( + int version, + int algorithm, + Date time, + BCPGKey key) { - out.writePacket(PUBLIC_SUBKEY, getEncodedContents()); + super(PUBLIC_SUBKEY, version, algorithm, time, key); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/RSAPublicBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/RSAPublicBCPGKey.java index c8c30b2938..e9bb82c792 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/RSAPublicBCPGKey.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/RSAPublicBCPGKey.java @@ -1,7 +1,7 @@ package org.bouncycastle.bcpg; import java.math.BigInteger; -import java.io.*; +import java.io.IOException; /** * base class for an RSA Public Key. diff --git a/pg/src/main/java/org/bouncycastle/bcpg/RSASecretBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/RSASecretBCPGKey.java index 4ab0543420..45399296a7 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/RSASecretBCPGKey.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/RSASecretBCPGKey.java @@ -1,6 +1,6 @@ package org.bouncycastle.bcpg; -import java.io.*; +import java.io.IOException; import java.math.BigInteger; import org.bouncycastle.util.BigIntegers; diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ReservedPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/ReservedPacket.java new file mode 100644 index 0000000000..bc766b6864 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/ReservedPacket.java @@ -0,0 +1,15 @@ +package org.bouncycastle.bcpg; + +public class ReservedPacket + extends InputStreamPacket +{ + public ReservedPacket(BCPGInputStream in) + { + this(in, false); + } + + public ReservedPacket(BCPGInputStream in, boolean newPacketFormat) + { + super(in, RESERVED, newPacketFormat); + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/S2K.java b/pg/src/main/java/org/bouncycastle/bcpg/S2K.java index 9833ec433c..5d93e1d80f 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/S2K.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/S2K.java @@ -10,13 +10,39 @@ /** * Parameter specifier for the PGP string-to-key password based key derivation function. - *

      - * In iterated mode, S2K takes a single byte iteration count specifier, which is converted to an - * actual iteration count using a formula that grows the iteration count exponentially as the byte - * value increases. - *

      - * e.g. 0x01 == 1088 iterations, and 0xFF == 65,011,712 iterations. - *

      + * There are different S2K modes: + *
        + *
      • + * In {@link #SIMPLE} mode, a single iteration of the hash algorithm is performed to derived a key + * from the given passphrase. + * This mode is deprecated and MUST NOT be generated. + *
      • + *
      • + * The {@link #SALTED} mode is like {@link #SIMPLE}, but uses an additional salt value. + * This mode is deprecated and MUST NOT be generated. + *
      • + *
      • + * In {@link #SALTED_AND_ITERATED} mode, S2K takes a single byte iteration count specifier, which is converted to an + * actual iteration count using a formula that grows the iteration count exponentially as the byte + * value increases. + * e.g. 0x01 == 1088 iterations, and 0xFF == 65,011,712 iterations. + *
      • + *
      • + * The {@link #SALTED_AND_ITERATED} mode uses both iteration and a salt value. + * This mode is recommended for applications that want to stay backwards compatible. + *
      • + *
      • + * The new {@link #ARGON_2} mode does key derivation using salted Argon2, which is a memory-hard hash algorithm. + * This mode is generally recommended over {@link #SALTED_AND_ITERATED}. + *
      • + *
      + * + * @see + * rfc4880 - String-to-Key (S2K) Specifiers + * @see + * C-R - String-to-Key (S2K) Specifier + * @see + * LibrePGP - String-to-Key (S2K) Specifiers */ public class S2K extends BCPGObject @@ -24,27 +50,64 @@ public class S2K private static final int EXPBIAS = 6; /** - * Simple key generation. A single non-salted iteration of a hash function + * Simple key generation. A single non-salted iteration of a hash function. + * This method is deprecated to use, since it can be brute-forced when used + * with a low-entropy string, such as those typically provided by users. + * Additionally, the usage of Simple S2K can lead to key and IV reuse. + * Therefore, in OpenPGP v6, Therefore, when generating an S2K specifier, + * an implementation MUST NOT use Simple S2K. + * + * @deprecated use {@link #SALTED_AND_ITERATED} or {@link #ARGON_2} instead. */ public static final int SIMPLE = 0; + /** - * Salted key generation. A single iteration of a hash function with a (unique) salt + * Salted key generation. A single iteration of a hash function with a (unique) salt. + * This method is deprecated to use, since it can be brute-forced when used + * with a low-entropy string, such as those typically provided by users. + * Therefore, in OpenPGP v6, an implementation SHOULD NOT generate a Salted S2K, + * unless the implementation knows that the input string is high-entropy. + * + * @deprecated use {@link #SALTED_AND_ITERATED} or {@link #ARGON_2} instead. */ public static final int SALTED = 1; + /** - * Salted and iterated key generation. Multiple iterations of a hash function, with a salt + * Salted and iterated key generation. Multiple iterations of a hash function, with a salt. + * This method MAY be used if {@link #ARGON_2} is not available. */ public static final int SALTED_AND_ITERATED = 3; + /** * Memory-hard, salted key generation using Argon2 hash algorithm. + * @see Argon2Params */ public static final int ARGON_2 = 4; + /** + * GNU S2K extension. + * @see GNUDummyParams + */ public static final int GNU_DUMMY_S2K = 101; + /** + * Do not store the secret part at all. + * @see GNUDummyParams + */ public static final int GNU_PROTECTION_MODE_NO_PRIVATE_KEY = 1; + + /** + * A stub to access smartcards. + * @see GNUDummyParams + */ public static final int GNU_PROTECTION_MODE_DIVERT_TO_CARD = 2; + /** + * The (GnuPG) internal representation of a private key. + * @see GNUDummyParams + */ + public static final int GNU_PROTECTION_MODE_INTERNAL = 3; + int type; int algorithm; byte[] iv; @@ -54,6 +117,12 @@ public class S2K int parallelism; int memorySizeExponent; + /** + * Parse an S2K specifier from an OpenPGP packet input stream. + * @param in packet input stream + * @throws IOException + * @throws UnsupportedPacketVersionException if an unsupported S2K type is encountered + */ S2K( InputStream in) throws IOException @@ -110,7 +179,7 @@ public class S2K public S2K( int algorithm) { - this.type = 0; + this.type = SIMPLE; this.algorithm = algorithm; } @@ -124,7 +193,7 @@ public S2K( int algorithm, byte[] iv) { - this.type = 1; + this.type = SALTED; this.algorithm = algorithm; this.iv = iv; } @@ -141,7 +210,7 @@ public S2K( byte[] iv, int itCount) { - this.type = 3; + this.type = SALTED_AND_ITERATED; this.algorithm = algorithm; this.iv = iv; @@ -238,7 +307,14 @@ public static S2K gnuDummyS2K(GNUDummyParams parameters) } /** - * Gets the {@link HashAlgorithmTags digest algorithm} specified. + * Gets the S2K specifier type. + * + * @see #SIMPLE + * @see #SALTED + * @see #SALTED_AND_ITERATED + * @see #ARGON_2 + * + * @return type */ public int getType() { @@ -247,6 +323,9 @@ public int getType() /** * Gets the {@link HashAlgorithmTags hash algorithm} for this S2K. + * Only used for {@link #SIMPLE}, {@link #SALTED}, {@link #SALTED_AND_ITERATED} + * + * @return hash algorithm */ public int getHashAlgorithm() { @@ -255,6 +334,15 @@ public int getHashAlgorithm() /** * Gets the iv/salt to use for the key generation. + * The value of this field depends on the S2K {@link #type}: + *
        + *
      • {@link #SIMPLE}:
        null
      • + *
      • {@link #SALTED}: 8 octets
      • + *
      • {@link #SALTED_AND_ITERATED}: 8 octets
      • + *
      • {@link #ARGON_2}: 16 octets
      • + *
      + * + * @return IV */ public byte[] getIV() { @@ -263,6 +351,9 @@ public byte[] getIV() /** * Gets the actual (expanded) iteration count. + * Only used for {@link #SALTED_AND_ITERATED}. + * + * @return iteration count */ public long getIterationCount() { @@ -274,7 +365,7 @@ public long getIterationCount() } /** - * Return the number of passes - only Argon2 + * Return the number of passes - only Argon2. * * @return number of passes */ @@ -284,7 +375,12 @@ public int getPasses() } /** - * Gets the protection mode - only if GNU_DUMMY_S2K + * Gets the protection mode - only if GNU_DUMMY_S2K. + * + * @see #GNU_PROTECTION_MODE_NO_PRIVATE_KEY + * @see #GNU_PROTECTION_MODE_DIVERT_TO_CARD + * + * @return GNU dummy-s2k protection mode */ public int getProtectionMode() { @@ -292,7 +388,7 @@ public int getProtectionMode() } /** - * Gets the degree of parallelism - only if ARGON_2 + * Gets the degree of parallelism - only if ARGON_2. * * @return parallelism */ @@ -302,7 +398,7 @@ public int getParallelism() } /** - * Gets the memory size exponent - only if ARGON_2 + * Gets the memory size exponent - only if ARGON_2. * * @return memory size exponent */ @@ -311,6 +407,11 @@ public int getMemorySizeExponent() return memorySizeExponent; } + /** + * Encode the packet into the given {@link BCPGOutputStream}. + * @param out packet output stream + * @throws IOException + */ public void encode( BCPGOutputStream out) throws IOException @@ -379,6 +480,8 @@ private void writeOneOctetOrThrow(BCPGOutputStream out, int val, String valName) /** * Parameters for Argon2 S2K. + * @see + * C-R - Argon2 */ public static class Argon2Params { @@ -414,7 +517,7 @@ public Argon2Params(SecureRandom secureRandom) * * @param passes number of iterations, must be greater than 0 * @param parallelism number of lanes, must be greater 0 - * @param memSizeExp exponent for memory consumption, must be between 3+ceil(log_2(p)) and 31 + * @param memSizeExp exponent for memory consumption, must be between
      3 + âŚlogâ‚‚p⌉
      and
      31
      * @param secureRandom secure random generator to initialize the salt vector */ public Argon2Params(int passes, int parallelism, int memSizeExp, SecureRandom secureRandom) @@ -428,7 +531,7 @@ public Argon2Params(int passes, int parallelism, int memSizeExp, SecureRandom se * @param salt 16 bytes of random salt * @param passes number of iterations, must be greater than 0 * @param parallelism number of lanes, must be greater 0 - * @param memSizeExp exponent for memory consumption, must be between 3+ceil(log_2(p)) and 31 + * @param memSizeExp exponent for memory consumption, must be between
      3 + âŚlogâ‚‚p⌉
      and
      31
      */ public Argon2Params(byte[] salt, int passes, int parallelism, int memSizeExp) { @@ -450,12 +553,12 @@ public Argon2Params(byte[] salt, int passes, int parallelism, int memSizeExp) } this.parallelism = parallelism; - // log_2(p) = log_e(p) / log_e(2) + // logâ‚‚p = logâ‚‘p / logâ‚‘2 double log2_p = Math.log(parallelism) / Math.log(2); // see https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-05.html#section-3.7.1.4-5 if (memSizeExp < (3 + Math.ceil(log2_p)) || memSizeExp > 31) { - throw new IllegalArgumentException("Memory size exponent MUST be between 3+ceil(log_2(parallelism)) and 31"); + throw new IllegalArgumentException("Memory size exponent MUST be between 3 + âŚlogâ‚‚(parallelism)⌉ and 31"); } this.memSizeExp = memSizeExp; } @@ -468,7 +571,7 @@ public Argon2Params(byte[] salt, int passes, int parallelism, int memSizeExp) */ public static Argon2Params universallyRecommendedParameters() { - return new Argon2Params(1, 4, 21, new SecureRandom()); + return new Argon2Params(1, 4, 21, CryptoServicesRegistrar.getSecureRandom()); } /** @@ -480,7 +583,7 @@ public static Argon2Params universallyRecommendedParameters() */ public static Argon2Params memoryConstrainedParameters() { - return new Argon2Params(3, 4, 16, new SecureRandom()); + return new Argon2Params(3, 4, 16, CryptoServicesRegistrar.getSecureRandom()); } /** @@ -539,6 +642,9 @@ public int getMemSizeExp() /** * Parameters for the {@link #GNU_DUMMY_S2K} method. + * + * @see + * GNU extensions to the S2K algorithm */ public static class GNUDummyParams { @@ -570,6 +676,16 @@ public static GNUDummyParams divertToCard() return new GNUDummyParams(GNU_PROTECTION_MODE_DIVERT_TO_CARD); } + /** + * Factory method for a GNU Dummy S2K indicating an internal private key. + * + * @return params + */ + public static GNUDummyParams internal() + { + return new GNUDummyParams(GNU_PROTECTION_MODE_INTERNAL); + } + /** * Return the GNU Dummy S2K protection method. * diff --git a/pg/src/main/java/org/bouncycastle/bcpg/SecretKeyPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/SecretKeyPacket.java index 3a378a8636..78b010482e 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/SecretKeyPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/SecretKeyPacket.java @@ -1,35 +1,149 @@ package org.bouncycastle.bcpg; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.io.Streams; + /** - * basic packet for a PGP secret key + * Base class for OpenPGP secret (primary) keys. */ public class SecretKeyPacket extends ContainedPacket implements PublicKeyAlgorithmTags { + /** + * S2K-usage octet indicating that the secret key material is unprotected. + */ public static final int USAGE_NONE = 0x00; + + /** + * S2K-usage octet indicating that the secret key material is protected using malleable CFB. + * Malleable-CFB-encrypted keys are vulnerable to corruption attacks + * that can cause leakage of secret data when the secret key is used. + * + * @see + * KlĂ­ma, V. and T. Rosa, + * "Attack on Private Signature Keys of the OpenPGP Format, + * PGP(TM) Programs and Other Applications Compatible with OpenPGP" + * @see + * Bruseghini, L., Paterson, K. G., and D. Huigens, + * "Victory by KO: Attacking OpenPGP Using Key Overwriting" + * @deprecated Use of MalleableCFB is deprecated. + * For v4 keys, use {@link #USAGE_SHA1} instead. + * For v6 keys use {@link #USAGE_AEAD} instead. + */ public static final int USAGE_CHECKSUM = 0xff; + + /** + * S2K-usage octet indicating that the secret key material is protected using a cipher in CFB mode. + * CFB-encrypted keys are vulnerable to corruption attacks that can + * cause leakage of secret data when the secret key is use. + * + * @see + * KlĂ­ma, V. and T. Rosa, + * "Attack on Private Signature Keys of the OpenPGP Format, + * PGP(TM) Programs and Other Applications Compatible with OpenPGP" + * @see + * Bruseghini, L., Paterson, K. G., and D. Huigens, + * "Victory by KO: Attacking OpenPGP Using Key Overwriting" + */ public static final int USAGE_SHA1 = 0xfe; - public static final int USAGE_AEAD = 0xfd; + /** + * S2K-usage octet indicating that the secret key material is protected using an AEAD scheme. + * This usage protects against above-mentioned attacks. + * Passphrase-protected secret key material in a v6 Secret Key or + * v6 Secret Subkey packet SHOULD be protected with AEAD encryption + * unless it will be transferred to an implementation that is known + * to not support AEAD. + * Users should migrate to AEAD with all due speed. + */ + public static final int USAGE_AEAD = 0xfd; + private PublicKeyPacket pubKeyPacket; private byte[] secKeyData; private int s2kUsage; private int encAlgorithm; + private int aeadAlgorithm; private S2K s2k; private byte[] iv; /** - * @param in + * Parse a primary OpenPGP secret key packet from the given OpenPGP {@link BCPGInputStream}. + * The packet format is remembered as {@link PacketFormat#LEGACY}. + * @param in packet input stream + * @throws IOException + */ + SecretKeyPacket( + BCPGInputStream in) + throws IOException + { + this(SECRET_KEY, in); + } + + /** + * Parse a primary OpenPGP secret key packet from the given OpenPGP {@link BCPGInputStream}. + * If
      newPacketFormat
      is true, the packet format will be remembered as {@link PacketFormat#CURRENT}, + * otherwise as {@link PacketFormat#LEGACY}. + * @param in packet input stream + * @param newPacketFormat current or legacy packet format * @throws IOException */ SecretKeyPacket( - BCPGInputStream in) + BCPGInputStream in, + boolean newPacketFormat) throws IOException { + this(SECRET_KEY, in, newPacketFormat); + } + + /** + * Parse a {@link SecretKeyPacket} or {@link SecretSubkeyPacket} from the given OpenPGP {@link BCPGInputStream}. + * The return type depends on the
      keyTag
      : + * {@link PacketTags#SECRET_KEY} means the result is a {@link SecretKeyPacket}. + * {@link PacketTags#SECRET_SUBKEY} results in a {@link SecretSubkeyPacket}. + * The packet format will be remembered as {@link PacketFormat#LEGACY}. + * @param keyTag packet type ID + * @param in packet input stream + * @throws IOException + */ + SecretKeyPacket( + int keyTag, + BCPGInputStream in) + throws IOException + { + this(keyTag, in, false); + } + + /** + * Parse a {@link SecretKeyPacket} or {@link SecretSubkeyPacket} from an OpenPGP {@link BCPGInputStream}. + * The return type depends on the
      keyTag
      : + * {@link PacketTags#SECRET_KEY} means the result is a {@link SecretKeyPacket}. + * {@link PacketTags#SECRET_SUBKEY} results in a {@link SecretSubkeyPacket}. + * + * @param keyTag packet type ID + * @param in packet input stream + * @param newPacketFormat packet format + * @throws IOException if the secret key packet cannot be parsed + * + * @see + * C-R - Secret-Key Packet Formats + * @see + * LibrePGP - Secret-Key Packet Formats + * @see + * Hardware-Backed Secret Keys + */ + SecretKeyPacket( + int keyTag, + BCPGInputStream in, + boolean newPacketFormat) + throws IOException + { + super(keyTag, newPacketFormat); + if (this instanceof SecretSubkeyPacket) { pubKeyPacket = new PublicSubkeyPacket(in); @@ -39,43 +153,97 @@ public class SecretKeyPacket pubKeyPacket = new PublicKeyPacket(in); } + int version = pubKeyPacket.getVersion(); s2kUsage = in.read(); - if (s2kUsage == USAGE_CHECKSUM || s2kUsage == USAGE_SHA1) + int conditionalParameterLength = -1; + if (version == PublicKeyPacket.LIBREPGP_5 || + (version == PublicKeyPacket.VERSION_6 && s2kUsage != USAGE_NONE)) + { + // TODO: Use length to parse unknown parameters + conditionalParameterLength = in.read(); + } + + if (s2kUsage == USAGE_CHECKSUM || s2kUsage == USAGE_SHA1 || s2kUsage == USAGE_AEAD) { encAlgorithm = in.read(); - s2k = new S2K(in); } else { encAlgorithm = s2kUsage; } + if (s2kUsage == USAGE_AEAD) + { + aeadAlgorithm = in.read(); + } + if (version == PublicKeyPacket.VERSION_6 && (s2kUsage == USAGE_SHA1 || s2kUsage == USAGE_AEAD)) + { + int s2KLen = in.read(); + byte[] s2kBytes = new byte[s2KLen]; + in.readFully(s2kBytes); - if (!(s2k != null && s2k.getType() == S2K.GNU_DUMMY_S2K && s2k.getProtectionMode() == 0x01)) + // TODO: catch UnsupportedPacketVersionException gracefully + s2k = new S2K(new ByteArrayInputStream(s2kBytes)); + } + else { - if (s2kUsage != 0) + if (s2kUsage == USAGE_CHECKSUM || s2kUsage == USAGE_SHA1 || s2kUsage == USAGE_AEAD) { - if (encAlgorithm < 7) - { - iv = new byte[8]; - } - else + s2k = new S2K(in); + } + } + if (s2kUsage == USAGE_AEAD) + { + iv = new byte[AEADUtils.getIVLength(aeadAlgorithm)]; + Streams.readFully(in, iv); + } + else + { + boolean isGNUDummyNoPrivateKey = s2k != null + && s2k.getType() == S2K.GNU_DUMMY_S2K + && s2k.getProtectionMode() == S2K.GNU_PROTECTION_MODE_NO_PRIVATE_KEY; + if (!(isGNUDummyNoPrivateKey)) + { + if (s2kUsage != USAGE_NONE && iv == null) { - iv = new byte[16]; + if (encAlgorithm < 7) + { + iv = new byte[8]; + } + else + { + iv = new byte[16]; + } + in.readFully(iv, 0, iv.length); } - in.readFully(iv, 0, iv.length); } } - - this.secKeyData = in.readAll(); + + if (version == PublicKeyPacket.LIBREPGP_5) + { + long keyOctetCount = ((long) in.read() << 24) | ((long) in.read() << 16) | ((long) in.read() << 8) | in.read(); + if (s2kUsage == USAGE_CHECKSUM || s2kUsage == USAGE_NONE) + { + // encoded keyOctetCount does not contain checksum + keyOctetCount += 2; + } + this.secKeyData = new byte[(int) keyOctetCount]; + in.readFully(secKeyData); + } + else + { + this.secKeyData = in.readAll(); + } } /** - * @param pubKeyPacket - * @param encAlgorithm - * @param s2k - * @param iv - * @param secKeyData + * Construct a {@link SecretKeyPacket}. + * Note:
      secKeyData
      needs to be prepared by applying encryption/checksum beforehand. + * @param pubKeyPacket pubkey packet corresponding to this secret key packet. + * @param encAlgorithm algorithm id of the symmetric key algorithm that was used to encrypt the secret key material + * @param s2k s2k identifier for deriving a key from a passphrase + * @param iv IV that was used to encrypt the secret key material + * @param secKeyData encrypted/checksum'd secret key material */ public SecretKeyPacket( PublicKeyPacket pubKeyPacket, @@ -84,69 +252,188 @@ public SecretKeyPacket( byte[] iv, byte[] secKeyData) { - this.pubKeyPacket = pubKeyPacket; - this.encAlgorithm = encAlgorithm; + this(SECRET_KEY, pubKeyPacket, encAlgorithm, s2k, iv, secKeyData); + } - if (encAlgorithm != SymmetricKeyAlgorithmTags.NULL) - { - this.s2kUsage = USAGE_CHECKSUM; - } - else - { - this.s2kUsage = USAGE_NONE; - } + /** + * Construct a {@link SecretKeyPacket} or {@link SecretSubkeyPacket}. + * Note:
      secKeyData
      needs to be prepared by applying encryption/checksum beforehand. + * @param keyTag packet type ID + * @param pubKeyPacket pubkey packet corresponding to this secret key packet. + * @param encAlgorithm algorithm id of the symmetric key algorithm that was used to encrypt the secret key material + * @param s2k s2k identifier for deriving a key from a passphrase + * @param iv IV that was used to encrypt the secret key material + * @param secKeyData encrypted/checksum'd secret key material + */ + SecretKeyPacket( + int keyTag, + PublicKeyPacket pubKeyPacket, + int encAlgorithm, + S2K s2k, + byte[] iv, + byte[] secKeyData) + { + this(keyTag, pubKeyPacket, encAlgorithm, 0, encAlgorithm != SymmetricKeyAlgorithmTags.NULL ? USAGE_CHECKSUM : USAGE_NONE, s2k, iv, secKeyData); + } - this.s2k = s2k; - this.iv = iv; - this.secKeyData = secKeyData; + /** + * Construct a {@link SecretKeyPacket} or {@link SecretSubkeyPacket}. + * Note:
      secKeyData
      needs to be prepared by applying encryption/checksum beforehand. + * @param pubKeyPacket pubkey packet corresponding to this secret key packet. + * @param encAlgorithm algorithm id of the symmetric key algorithm that was used to encrypt the secret key material + * @param s2kUsage octet indicating, how the secert key material was protected + * @param s2k s2k identifier for deriving a key from a passphrase + * @param iv IV that was used to encrypt the secret key material + * @param secKeyData encrypted/checksum'd secret key material + */ + public SecretKeyPacket( + PublicKeyPacket pubKeyPacket, + int encAlgorithm, + int s2kUsage, + S2K s2k, + byte[] iv, + byte[] secKeyData) + { + this(SECRET_KEY, pubKeyPacket, encAlgorithm, 0, s2kUsage, s2k, iv, secKeyData); } + /** + * Construct a {@link SecretKeyPacket} or {@link SecretSubkeyPacket}. + * Note:
      secKeyData
      needs to be prepared by applying encryption/checksum beforehand. + * @param pubKeyPacket pubkey packet corresponding to this secret key packet. + * @param encAlgorithm algorithm id of the symmetric key algorithm that was used to encrypt the secret key material + * @param aeadAlgorithm AEAD algorithm scheme used to protect the secret key material with + * @param s2kUsage octet indicating how the secret key material was encrypted + * @param s2k s2k identifier for deriving a key from a passphrase + * @param iv IV that was used to encrypt the secret key material + * @param secKeyData encrypted/checksum'd secret key material + */ public SecretKeyPacket( PublicKeyPacket pubKeyPacket, int encAlgorithm, + int aeadAlgorithm, + int s2kUsage, + S2K s2k, + byte[] iv, + byte[] secKeyData) + { + this(SECRET_KEY, pubKeyPacket, encAlgorithm, aeadAlgorithm, s2kUsage, s2k, iv, secKeyData); + } + + /** + * Construct a {@link SecretKeyPacket} or {@link SecretSubkeyPacket}. + * Note:
      secKeyData
      needs to be prepared by applying encryption/checksum beforehand. + * @param keyTag packet type ID + * @param pubKeyPacket pubkey packet corresponding to this secret key packet. + * @param encAlgorithm algorithm id of the symmetric key algorithm that was used to encrypt the secret key material + * @param aeadAlgorithm AEAD algorithm scheme used to protect the secret key material with + * @param s2kUsage octet indicating how the secret key material was encrypted + * @param s2k s2k identifier for deriving a key from a passphrase + * @param iv IV that was used to encrypt the secret key material + * @param secKeyData encrypted/checksum'd secret key material + */ + SecretKeyPacket( + int keyTag, + PublicKeyPacket pubKeyPacket, + int encAlgorithm, + int aeadAlgorithm, int s2kUsage, S2K s2k, byte[] iv, byte[] secKeyData) { + super(keyTag); + this.pubKeyPacket = pubKeyPacket; this.encAlgorithm = encAlgorithm; + this.aeadAlgorithm = aeadAlgorithm; this.s2kUsage = s2kUsage; this.s2k = s2k; - this.iv = iv; + this.iv = Arrays.clone(iv); this.secKeyData = secKeyData; + + if (s2k != null && s2k.getType() == S2K.ARGON_2 && s2kUsage != USAGE_AEAD) + { + throw new IllegalArgumentException("Argon2 is only used with AEAD (S2K usage octet 253)"); + } + + if (pubKeyPacket.getVersion() == PublicKeyPacket.VERSION_6) + { + if (s2kUsage == USAGE_CHECKSUM) + { + throw new IllegalArgumentException("Version 6 keys MUST NOT use S2K usage USAGE_CHECKSUM"); + } + } } + /** + * Return the algorithm ID of the symmetric key algorithm that was used to encrypt the secret key material. + * @return symmetric key enc algorithm id + */ public int getEncAlgorithm() { return encAlgorithm; } + /** + * Return the algorithm ID of the AEAD algorithm that was used to protect the secret key material. + * @return aead algorithm id + */ + public int getAeadAlgorithm() + { + return aeadAlgorithm; + } + + /** + * Return the S2K usage mode indicating how the secret key material is protected. + * @return s2k usage + */ public int getS2KUsage() { return s2kUsage; } + /** + * Return the IV that was used to protect the secret key material. + * @return IV + */ public byte[] getIV() { - return iv; + return Arrays.clone(iv); } + /** + * Return the S2K identifier describing, how to derive the symmetric key to protect the secret key material with. + * @return s2k identifier + */ public S2K getS2K() { return s2k; } + /** + * Return the public key packet corresponding to the secret key packet. + * @return public key packet + */ public PublicKeyPacket getPublicKeyPacket() { return pubKeyPacket; } + /** + * Return the encrypted/checksum'd secret key data. + * @return secret key data + */ public byte[] getSecretKeyData() { return secKeyData; } + /** + * Return the encoded packet content without packet frame. + * @return encoded packet contents + * @throws IOException + */ public byte[] getEncodedContents() throws IOException { @@ -157,19 +444,28 @@ public byte[] getEncodedContents() pOut.write(s2kUsage); - if (s2kUsage == USAGE_CHECKSUM || s2kUsage == USAGE_SHA1) - { - pOut.write(encAlgorithm); - pOut.writeObject(s2k); - } - - if (iv != null) + // conditional parameters + byte[] conditionalParameters = encodeConditionalParameters(); + if (pubKeyPacket.getVersion() == PublicKeyPacket.LIBREPGP_5 || + (pubKeyPacket.getVersion() == PublicKeyPacket.VERSION_6 && s2kUsage != USAGE_NONE)) { - pOut.write(iv); + pOut.write(conditionalParameters.length); } + pOut.write(conditionalParameters); + // encrypted secret key if (secKeyData != null && secKeyData.length > 0) { + if (pubKeyPacket.getVersion() == PublicKeyPacket.LIBREPGP_5) + { + int keyOctetCount = secKeyData.length; + // v5 keyOctetCount does not include checksum octets + if (s2kUsage == USAGE_CHECKSUM || s2kUsage == USAGE_NONE) + { + keyOctetCount -= 2; + } + StreamUtil.write4OctetLength(pOut, keyOctetCount); + } pOut.write(secKeyData); } @@ -178,10 +474,48 @@ public byte[] getEncodedContents() return bOut.toByteArray(); } + private byte[] encodeConditionalParameters() + throws IOException + { + ByteArrayOutputStream conditionalParameters = new ByteArrayOutputStream(); + boolean hasS2KSpecifier = s2kUsage == USAGE_CHECKSUM || s2kUsage == USAGE_SHA1 || s2kUsage == USAGE_AEAD; + + if (hasS2KSpecifier) + { + conditionalParameters.write(encAlgorithm); + if (s2kUsage == USAGE_AEAD) + { + conditionalParameters.write(aeadAlgorithm); + } + byte[] encodedS2K = s2k.getEncoded(); + if (pubKeyPacket.getVersion() == PublicKeyPacket.VERSION_6) + { + conditionalParameters.write(encodedS2K.length); + } + conditionalParameters.write(encodedS2K); + } + if (iv != null) + { + // since USAGE_AEAD and other types that use an IV are mutually exclusive, + // we use the IV field for both v4 IVs and v6 AEAD nonces + conditionalParameters.write(iv); + } + + return conditionalParameters.toByteArray(); + } + + /** + * Encode the packet into the given {@link BCPGOutputStream}. + * If the packet output stream has {@link PacketFormat#ROUNDTRIP} set, the packet format to encode the packet length + * with depends on the result of {@link #hasNewPacketFormat()}. + * Otherwise, the packet output stream dictates the packet format. + * @param out packet output stream + * @throws IOException + */ public void encode( BCPGOutputStream out) throws IOException { - out.writePacket(SECRET_KEY, getEncodedContents()); + out.writePacket(hasNewPacketFormat(), getPacketTag(), getEncodedContents()); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/SecretSubkeyPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/SecretSubkeyPacket.java index 42edd01bd2..910d7b2f5b 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/SecretSubkeyPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/SecretSubkeyPacket.java @@ -5,54 +5,92 @@ /** * basic packet for a PGP secret key */ -public class SecretSubkeyPacket +public class SecretSubkeyPacket extends SecretKeyPacket { /** - * - * @param in + * Parse a secret subkey packet from an input stream. + * + * @param in input stream * @throws IOException */ SecretSubkeyPacket( - BCPGInputStream in) + BCPGInputStream in) throws IOException - { - super(in); + { + this(in, false); + } + + SecretSubkeyPacket( + BCPGInputStream in, + boolean newPacketFormat) + throws IOException + { + super(SECRET_SUBKEY, in, newPacketFormat); } - /** - * - * @param pubKeyPacket - * @param encAlgorithm - * @param s2k - * @param iv - * @param secKeyData + * Create a secret subkey packet. + * If the encryption algorithm is NOT {@link SymmetricKeyAlgorithmTags#NULL}, + * the {@link #USAGE_SHA1} will be used as S2K usage, otherwise the key will be + * unencrypted ({@link #USAGE_NONE}). + * + * @param pubKeyPacket public subkey packet + * @param encAlgorithm encryption algorithm + * @param s2k s2k identifier + * @param iv optional iv for the encryption algorithm + * @param secKeyData secret key data */ public SecretSubkeyPacket( - PublicKeyPacket pubKeyPacket, - int encAlgorithm, - S2K s2k, - byte[] iv, - byte[] secKeyData) + PublicKeyPacket pubKeyPacket, + int encAlgorithm, + S2K s2k, + byte[] iv, + byte[] secKeyData) { - super(pubKeyPacket, encAlgorithm, s2k, iv, secKeyData); + super(SECRET_SUBKEY, pubKeyPacket, encAlgorithm, s2k, iv, secKeyData); } - + + /** + * Create a secret subkey packet. + * + * @param pubKeyPacket public subkey packet + * @param encAlgorithm encryption algorithm + * @param s2kUsage s2k usage + * @param s2k s2k identifier + * @param iv optional iv for the encryption algorithm + * @param secKeyData secret key data + */ public SecretSubkeyPacket( - PublicKeyPacket pubKeyPacket, - int encAlgorithm, - int s2kUsage, - S2K s2k, - byte[] iv, - byte[] secKeyData) + PublicKeyPacket pubKeyPacket, + int encAlgorithm, + int s2kUsage, + S2K s2k, + byte[] iv, + byte[] secKeyData) { - super(pubKeyPacket, encAlgorithm, s2kUsage, s2k, iv, secKeyData); + this(pubKeyPacket, encAlgorithm, 0, s2kUsage, s2k, iv, secKeyData); } - - public void encode( - BCPGOutputStream out) - throws IOException + + /** + * Create a secret subkey packet. + * + * @param pubKeyPacket public subkey packet + * @param encAlgorithm encryption algorithm + * @param aeadAlgorithm aead algorithm + * @param s2kUsage s2k usage + * @param s2K s2k identifier + * @param iv optional iv for the AEAD algorithm or encryption algorithm + * @param secKeyData secret key data + */ + public SecretSubkeyPacket( + PublicKeyPacket pubKeyPacket, + int encAlgorithm, + int aeadAlgorithm, + int s2kUsage, + S2K s2K, + byte[] iv, + byte[] secKeyData) { - out.writePacket(SECRET_SUBKEY, getEncodedContents()); + super(SECRET_SUBKEY, pubKeyPacket, encAlgorithm, aeadAlgorithm, s2kUsage, s2K, iv, secKeyData); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/SignaturePacket.java b/pg/src/main/java/org/bouncycastle/bcpg/SignaturePacket.java index 5e3eac35b0..47505bf15a 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/SignaturePacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/SignaturePacket.java @@ -5,17 +5,25 @@ import java.io.IOException; import java.util.Vector; +import org.bouncycastle.bcpg.sig.IssuerFingerprint; import org.bouncycastle.bcpg.sig.IssuerKeyID; import org.bouncycastle.bcpg.sig.SignatureCreationTime; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Pack; import org.bouncycastle.util.io.Streams; /** * generic signature packet */ -public class SignaturePacket +public class SignaturePacket extends ContainedPacket implements PublicKeyAlgorithmTags { + public static final int VERSION_2 = 2; + public static final int VERSION_3 = 3; + public static final int VERSION_4 = 4; // https://datatracker.ietf.org/doc/rfc4880/ + public static final int VERSION_5 = 5; // https://datatracker.ietf.org/doc/draft-koch-librepgp/ + public static final int VERSION_6 = 6; // https://datatracker.ietf.org/doc/draft-ietf-openpgp-crypto-refresh/ + private int version; private int signatureType; private long creationTime; @@ -27,161 +35,277 @@ public class SignaturePacket private SignatureSubpacket[] hashedData; private SignatureSubpacket[] unhashedData; private byte[] signatureEncoding; - + private byte[] salt; // v6 only + + SignaturePacket( + BCPGInputStream in) + throws IOException + { + this(in, false); + } + SignaturePacket( - BCPGInputStream in) + BCPGInputStream in, + boolean newPacketFormat) throws IOException { + super(SIGNATURE, newPacketFormat); + version = in.read(); - - if (version == 3 || version == 2) + switch (version) { - int l = in.read(); - - signatureType = in.read(); - creationTime = (((long)in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read()) * 1000; - keyID |= (long)in.read() << 56; - keyID |= (long)in.read() << 48; - keyID |= (long)in.read() << 40; - keyID |= (long)in.read() << 32; - keyID |= (long)in.read() << 24; - keyID |= (long)in.read() << 16; - keyID |= (long)in.read() << 8; - keyID |= in.read(); - keyAlgorithm = in.read(); - hashAlgorithm = in.read(); + case VERSION_2: + case VERSION_3: + parseV2_V3(in); + break; + case VERSION_4: + case VERSION_5: + parseV4_V5(in); + break; + case VERSION_6: + parseV6(in); + break; + default: + Streams.drain(in); + throw new UnsupportedPacketVersionException("unsupported version: " + version); } - else if (version == 4) + } + + /** + * Parse a version 2 or version 3 signature. + * @param in input stream which already skipped over the version number + * @throws IOException if the packet is malformed + * + * @see + * Version 3 packet format + */ + private void parseV2_V3(BCPGInputStream in) + throws IOException + { + int l = in.read(); // length l MUST be 5 + + signatureType = in.read(); + creationTime = StreamUtil.readTime(in); + + keyID = StreamUtil.readKeyID(in); + keyAlgorithm = in.read(); + hashAlgorithm = in.read(); + + // left 16 bits of the signed hash value + fingerPrint = new byte[2]; + in.readFully(fingerPrint); + + parseSignature(in); + } + + /** + * Parse a version 4 or version 5 signature. + * The difference between version 4 and 5 is that a version 5 signature contains additional metadata. + * @param in input stream which already skipped over the version number + * @throws IOException if the packet is malformed + * + * @see + * Version 4 packet format + * @see + * Version 5 packet format + */ + private void parseV4_V5(BCPGInputStream in) + throws IOException + { + signatureType = in.read(); + keyAlgorithm = in.read(); + hashAlgorithm = in.read(); + + parseSubpackets(in); + + // left 16 bits of the signed hash value + fingerPrint = new byte[2]; + in.readFully(fingerPrint); + + parseSignature(in); + } + + /** + * Parse a version 6 signature. + * Version 6 signatures do use 4 octet subpacket area length descriptors and contain an additional salt value + * (which may or may not be of size 0, librepgp and crypto-refresh are in disagreement here). + * @param in input stream which already skipped over the version number + * @throws IOException if the packet is malformed + * + * @see + * Version 6 packet format + */ + private void parseV6(BCPGInputStream in) + throws IOException + { + signatureType = in.read(); + keyAlgorithm = in.read(); + hashAlgorithm = in.read(); + + parseSubpackets(in); + + // left 16 bits of the signed hash value + fingerPrint = new byte[2]; + in.readFully(fingerPrint); + + int saltSize = in.read(); + salt = new byte[saltSize]; + in.readFully(salt); + + parseSignature(in); + } + + /** + * Parse the hashed and unhashed signature subpacket areas of the signature. + * Version 4 and 5 signature encode the area length using 2 octets, while version 6 uses 4 octet lengths instead. + * + * @param in input stream which skipped to after the hash algorithm octet + * @throws IOException if the packet is malformed + */ + private void parseSubpackets(BCPGInputStream in) + throws IOException + { + + Vector vec = readSignatureSubpacketVector(in); + hashedData = new SignatureSubpacket[vec.size()]; + + for (int i = 0; i != hashedData.length; i++) { - signatureType = in.read(); - keyAlgorithm = in.read(); - hashAlgorithm = in.read(); - - int hashedLength = (in.read() << 8) | in.read(); - byte[] hashed = new byte[hashedLength]; - - in.readFully(hashed); - - // - // read the signature sub packet data. - // - SignatureSubpacket sub; - SignatureSubpacketInputStream sIn = new SignatureSubpacketInputStream( - new ByteArrayInputStream(hashed)); - - Vector v = new Vector(); - while ((sub = sIn.readPacket()) != null) - { - v.addElement(sub); - } - - hashedData = new SignatureSubpacket[v.size()]; - - for (int i = 0; i != hashedData.length; i++) + SignatureSubpacket p = vec.elementAt(i); + if (p instanceof IssuerKeyID) { - SignatureSubpacket p = (SignatureSubpacket)v.elementAt(i); - if (p instanceof IssuerKeyID) - { - keyID = ((IssuerKeyID)p).getKeyID(); - } - else if (p instanceof SignatureCreationTime) - { - creationTime = ((SignatureCreationTime)p).getTime().getTime(); - } - - hashedData[i] = p; + keyID = ((IssuerKeyID)p).getKeyID(); } - - int unhashedLength = (in.read() << 8) | in.read(); - byte[] unhashed = new byte[unhashedLength]; - - in.readFully(unhashed); - - sIn = new SignatureSubpacketInputStream( - new ByteArrayInputStream(unhashed)); - - v.removeAllElements(); - while ((sub = sIn.readPacket()) != null) + else if (p instanceof SignatureCreationTime) { - v.addElement(sub); + creationTime = ((SignatureCreationTime)p).getTime().getTime(); } - - unhashedData = new SignatureSubpacket[v.size()]; - - for (int i = 0; i != unhashedData.length; i++) + + hashedData[i] = p; + } + + vec = readSignatureSubpacketVector(in); + unhashedData = new SignatureSubpacket[vec.size()]; + + for (int i = 0; i != unhashedData.length; i++) + { + SignatureSubpacket p = vec.elementAt(i); + if (p instanceof IssuerKeyID) { - SignatureSubpacket p = (SignatureSubpacket)v.elementAt(i); - if (p instanceof IssuerKeyID) - { - keyID = ((IssuerKeyID)p).getKeyID(); - } - - unhashedData[i] = p; + keyID = ((IssuerKeyID)p).getKeyID(); } + + unhashedData[i] = p; + } + + setIssuerKeyId(); + setCreationTime(); + } + + private Vector readSignatureSubpacketVector(BCPGInputStream in) + throws IOException + { + int hashedLength; + if (version == 6) + { + hashedLength = StreamUtil.read4OctetLength(in); } else { - Streams.drain(in); + hashedLength = StreamUtil.read2OctetLength(in); + } + byte[] hashed = new byte[hashedLength]; + + in.readFully(hashed); + + // + // read the signature sub packet data. + // + SignatureSubpacket sub; + SignatureSubpacketInputStream sIn = new SignatureSubpacketInputStream( + new ByteArrayInputStream(hashed)); - throw new UnsupportedPacketVersionException("unsupported version: " + version); + Vector vec = new Vector(); + while ((sub = sIn.readPacket()) != null) + { + vec.addElement(sub); } - - fingerPrint = new byte[2]; - in.readFully(fingerPrint); - + return vec; + } + + /** + * Parse the algorithm-specific signature encoding. + * Ed25519 and Ed448 do not populate the signature MPInteger field, but instead read the raw signature to + * signatureEncoding directly. + * + * @param in input stream which skipped the head of the signature + * @throws IOException if the packet is malformed + */ + private void parseSignature(BCPGInputStream in) + throws IOException + { switch (keyAlgorithm) { - case RSA_GENERAL: - case RSA_SIGN: - MPInteger v = new MPInteger(in); - - signature = new MPInteger[1]; - signature[0] = v; - break; - case DSA: - MPInteger r = new MPInteger(in); - MPInteger s = new MPInteger(in); - - signature = new MPInteger[2]; - signature[0] = r; - signature[1] = s; - break; - case ELGAMAL_ENCRYPT: // yep, this really does happen sometimes. - case ELGAMAL_GENERAL: - MPInteger p = new MPInteger(in); - MPInteger g = new MPInteger(in); - MPInteger y = new MPInteger(in); - - signature = new MPInteger[3]; - signature[0] = p; - signature[1] = g; - signature[2] = y; - break; - case ECDSA: - case EDDSA_LEGACY: - MPInteger ecR = new MPInteger(in); - MPInteger ecS = new MPInteger(in); - - signature = new MPInteger[2]; - signature[0] = ecR; - signature[1] = ecS; - break; - default: - if (keyAlgorithm >= PublicKeyAlgorithmTags.EXPERIMENTAL_1 && keyAlgorithm <= PublicKeyAlgorithmTags.EXPERIMENTAL_11) - { - signature = null; - signatureEncoding = Streams.readAll(in); - } - else - { - throw new IOException("unknown signature key algorithm: " + keyAlgorithm); - } + case RSA_GENERAL: + case RSA_SIGN: + MPInteger v = new MPInteger(in); + + signature = new MPInteger[1]; + signature[0] = v; + break; + case DSA: + MPInteger r = new MPInteger(in); + MPInteger s = new MPInteger(in); + + signature = new MPInteger[2]; + signature[0] = r; + signature[1] = s; + break; + case ELGAMAL_ENCRYPT: // yep, this really does happen sometimes. + case ELGAMAL_GENERAL: + MPInteger p = new MPInteger(in); + MPInteger g = new MPInteger(in); + MPInteger y = new MPInteger(in); + + signature = new MPInteger[3]; + signature[0] = p; + signature[1] = g; + signature[2] = y; + break; + case Ed448: + signatureEncoding = new byte[org.bouncycastle.math.ec.rfc8032.Ed448.SIGNATURE_SIZE]; + in.readFully(signatureEncoding); + break; + case Ed25519: + signatureEncoding = new byte[org.bouncycastle.math.ec.rfc8032.Ed25519.SIGNATURE_SIZE]; + in.readFully(signatureEncoding); + break; + case ECDSA: + case EDDSA_LEGACY: + + MPInteger ecR = new MPInteger(in); + MPInteger ecS = new MPInteger(in); + + signature = new MPInteger[2]; + signature[0] = ecR; + signature[1] = ecS; + break; + default: + if (keyAlgorithm >= PublicKeyAlgorithmTags.EXPERIMENTAL_1 && keyAlgorithm <= PublicKeyAlgorithmTags.EXPERIMENTAL_11) + { + signature = null; + signatureEncoding = Streams.readAll(in); + } + else + { + throw new IOException("unknown signature key algorithm: " + keyAlgorithm); + } } } - + /** * Generate a version 4 signature packet. - * + * * @param signatureType * @param keyAlgorithm * @param hashAlgorithm @@ -202,10 +326,10 @@ public SignaturePacket( { this(4, signatureType, keyID, keyAlgorithm, hashAlgorithm, hashedData, unhashedData, fingerPrint, signature); } - + /** * Generate a version 2/3 signature packet. - * + * * @param signatureType * @param keyAlgorithm * @param hashAlgorithm @@ -223,10 +347,10 @@ public SignaturePacket( MPInteger[] signature) { this(version, signatureType, keyID, keyAlgorithm, hashAlgorithm, null, null, fingerPrint, signature); - + this.creationTime = creationTime; } - + public SignaturePacket( int version, int signatureType, @@ -238,6 +362,8 @@ public SignaturePacket( byte[] fingerPrint, MPInteger[] signature) { + super(SIGNATURE); + this.version = version; this.signatureType = signatureType; this.keyID = keyID; @@ -253,7 +379,67 @@ public SignaturePacket( setCreationTime(); } } - + + public SignaturePacket( + int version, + int signatureType, + long keyID, + int keyAlgorithm, + int hashAlgorithm, + SignatureSubpacket[] hashedData, + SignatureSubpacket[] unhashedData, + byte[] fingerPrint, + byte[] signatureEncoding, + byte[] salt) + { + super(SIGNATURE); + + this.version = version; + this.signatureType = signatureType; + this.keyID = keyID; + this.keyAlgorithm = keyAlgorithm; + this.hashAlgorithm = hashAlgorithm; + this.hashedData = hashedData; + this.unhashedData = unhashedData; + this.fingerPrint = fingerPrint; + this.signatureEncoding = Arrays.clone(signatureEncoding); + this.salt = Arrays.clone(salt); + if (hashedData != null) + { + setCreationTime(); + } + } + + public SignaturePacket( + int version, + int signatureType, + long keyID, + int keyAlgorithm, + int hashAlgorithm, + SignatureSubpacket[] hashedData, + SignatureSubpacket[] unhashedData, + byte[] fingerPrint, + MPInteger[] signature, + byte[] salt) + { + super(SIGNATURE); + + this.version = version; + this.signatureType = signatureType; + this.keyID = keyID; + this.keyAlgorithm = keyAlgorithm; + this.hashAlgorithm = hashAlgorithm; + this.hashedData = hashedData; + this.unhashedData = unhashedData; + this.fingerPrint = fingerPrint; + this.signature = signature; + this.salt = Arrays.clone(salt); + if (hashedData != null) + { + setCreationTime(); + } + } + /** * get the version number */ @@ -261,7 +447,7 @@ public int getVersion() { return version; } - + /** * return the signature type. */ @@ -269,7 +455,7 @@ public int getSignatureType() { return signatureType; } - + /** * return the keyID * @return the keyID that created the signature. @@ -288,73 +474,89 @@ public byte[] getFingerPrint() return Arrays.clone(fingerPrint); } + /** + * Return the signature's salt. + * Only for v6 signatures. + * @return salt + */ + public byte[] getSalt() + { + return salt; + } + /** * return the signature trailer that must be included with the data * to reconstruct the signature - * + * * @return byte[] */ public byte[] getSignatureTrailer() { byte[] trailer = null; - - if (version == 3 || version == 2) + + if (version == VERSION_3 || version == VERSION_2) { trailer = new byte[5]; - + long time = creationTime / 1000; - + trailer[0] = (byte)signatureType; - trailer[1] = (byte)(time >> 24); - trailer[2] = (byte)(time >> 16); - trailer[3] = (byte)(time >> 8); - trailer[4] = (byte)(time); + Pack.intToBigEndian((int)time, trailer, 1); } - else + else if (version == VERSION_4 || version == VERSION_5 || version == VERSION_6) { ByteArrayOutputStream sOut = new ByteArrayOutputStream(); - + SignatureSubpacket[] hashed = this.getHashedSubPackets(); try { sOut.write((byte)this.getVersion()); sOut.write((byte)this.getSignatureType()); sOut.write((byte)this.getKeyAlgorithm()); sOut.write((byte)this.getHashAlgorithm()); - + ByteArrayOutputStream hOut = new ByteArrayOutputStream(); - SignatureSubpacket[] hashed = this.getHashedSubPackets(); - + + for (int i = 0; i != hashed.length; i++) { hashed[i].encode(hOut); } - + byte[] data = hOut.toByteArray(); - - sOut.write((byte)(data.length >> 8)); - sOut.write((byte)data.length); + if (version != VERSION_6) + { + StreamUtil.write2OctetLength(sOut, data.length); + } + else + { + StreamUtil.write4OctetLength(sOut, data.length); + } sOut.write(data); - + byte[] hData = sOut.toByteArray(); - + sOut.write((byte)this.getVersion()); sOut.write((byte)0xff); - sOut.write((byte)(hData.length>> 24)); - sOut.write((byte)(hData.length >> 16)); - sOut.write((byte)(hData.length >> 8)); - sOut.write((byte)(hData.length)); + if (version == VERSION_5) + { + StreamUtil.write8OctetLength(sOut, hData.length); + } + else + { + StreamUtil.write4OctetLength(sOut, hData.length); + } } catch (IOException e) { throw new RuntimeException("exception generating trailer: " + e); } - + trailer = sOut.toByteArray(); } - + return trailer; } - + /** * return the encryption algorithm tag */ @@ -362,7 +564,7 @@ public int getKeyAlgorithm() { return keyAlgorithm; } - + /** * return the hashAlgorithm tag */ @@ -370,10 +572,12 @@ public int getHashAlgorithm() { return hashAlgorithm; } - + /** * return the signature as a set of integers - note this is normalised to be the * ASN.1 encoding of what appears in the signature packet. + * Note, that Ed25519 and Ed448 returns null, as the raw signature is stored in signatureEncoding only. + * For those, use {@link #getSignatureBytes()} instead. */ public MPInteger[] getSignature() { @@ -414,94 +618,69 @@ public SignatureSubpacket[] getHashedSubPackets() { return hashedData; } - + public SignatureSubpacket[] getUnhashedSubPackets() { return unhashedData; } - + /** * Return the creation time of the signature in milli-seconds. - * + * * @return the creation time in millis */ public long getCreationTime() { return creationTime; } - + public void encode( BCPGOutputStream out) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); - + pOut.write(version); - - if (version == 3 || version == 2) + + if (version == VERSION_3 || version == VERSION_2) { pOut.write(5); // the length of the next block - + long time = creationTime / 1000; - + pOut.write(signatureType); - pOut.write((byte)(time >> 24)); - pOut.write((byte)(time >> 16)); - pOut.write((byte)(time >> 8)); - pOut.write((byte)time); - - pOut.write((byte)(keyID >> 56)); - pOut.write((byte)(keyID >> 48)); - pOut.write((byte)(keyID >> 40)); - pOut.write((byte)(keyID >> 32)); - pOut.write((byte)(keyID >> 24)); - pOut.write((byte)(keyID >> 16)); - pOut.write((byte)(keyID >> 8)); - pOut.write((byte)(keyID)); - + StreamUtil.writeTime(pOut, time); + + StreamUtil.writeKeyID(pOut, keyID); + pOut.write(keyAlgorithm); pOut.write(hashAlgorithm); } - else if (version == 4) + else if (version == VERSION_4 || version == VERSION_5 || version == VERSION_6) { pOut.write(signatureType); pOut.write(keyAlgorithm); pOut.write(hashAlgorithm); - - ByteArrayOutputStream sOut = new ByteArrayOutputStream(); - - for (int i = 0; i != hashedData.length; i++) - { - hashedData[i].encode(sOut); - } - - byte[] data = sOut.toByteArray(); - - pOut.write(data.length >> 8); - pOut.write(data.length); - pOut.write(data); - + + ByteArrayOutputStream sOut = new ByteArrayOutputStream(); + writeSignatureSubpacketArray(sOut, pOut, hashedData); sOut.reset(); - - for (int i = 0; i != unhashedData.length; i++) - { - unhashedData[i].encode(sOut); - } - - data = sOut.toByteArray(); - - pOut.write(data.length >> 8); - pOut.write(data.length); - pOut.write(data); + writeSignatureSubpacketArray(sOut, pOut, unhashedData); } else { throw new IOException("unknown version: " + version); } - + pOut.write(fingerPrint); + if (version == VERSION_6) + { + pOut.write(salt.length); + pOut.write(salt); + } + if (signature != null) { for (int i = 0; i != signature.length; i++) @@ -516,7 +695,28 @@ else if (version == 4) pOut.close(); - out.writePacket(SIGNATURE, bOut.toByteArray()); + out.writePacket(hasNewPacketFormat(), SIGNATURE, bOut.toByteArray()); + } + + private void writeSignatureSubpacketArray(ByteArrayOutputStream sOut, BCPGOutputStream pOut, SignatureSubpacket[] array) + throws IOException + { + for (int i = 0; i != array.length; i++) + { + array[i].encode(sOut); + } + + byte[] data = sOut.toByteArray(); + + if (version == VERSION_6) + { + StreamUtil.write4OctetLength(pOut, data.length); + } + else + { + StreamUtil.write2OctetLength(pOut, data.length); + } + pOut.write(data); } private void setCreationTime() @@ -531,6 +731,49 @@ private void setCreationTime() } } + /** + * Iterate over the hashed and unhashed signature subpackets to identify either a {@link IssuerKeyID} or + * {@link IssuerFingerprint} subpacket to derive the issuer key-ID from. + * The issuer {@link IssuerKeyID} and {@link IssuerFingerprint} subpacket information is "self-authenticating", + * as its authenticity can be verified by checking the signature with the corresponding key. + * Therefore, we can also check the unhashed signature subpacket area. + */ + private void setIssuerKeyId() + { + if (keyID != 0L) + { + return; + } + + for (SignatureSubpacket p : hashedData) + { + if (p instanceof IssuerKeyID) + { + keyID = ((IssuerKeyID) p).getKeyID(); + return; + } + if (p instanceof IssuerFingerprint) + { + keyID = ((IssuerFingerprint) p).getKeyID(); + return; + } + } + + for (SignatureSubpacket p : unhashedData) + { + if (p instanceof IssuerKeyID) + { + keyID = ((IssuerKeyID) p).getKeyID(); + return; + } + if (p instanceof IssuerFingerprint) + { + keyID = ((IssuerFingerprint) p).getKeyID(); + return; + } + } + } + public static SignaturePacket fromByteArray(byte[] data) throws IOException { diff --git a/pg/src/main/java/org/bouncycastle/bcpg/SignatureSubpacket.java b/pg/src/main/java/org/bouncycastle/bcpg/SignatureSubpacket.java index 8fc1721140..737a41b437 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/SignatureSubpacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/SignatureSubpacket.java @@ -59,32 +59,11 @@ public void encode( if (isLongLength) { out.write(0xff); - out.write((byte)(bodyLen >> 24)); - out.write((byte)(bodyLen >> 16)); - out.write((byte)(bodyLen >> 8)); - out.write((byte)bodyLen); + StreamUtil.writeBodyLen(out, bodyLen); } else { - if (bodyLen < 192) - { - out.write((byte)bodyLen); - } - else if (bodyLen <= 8383) - { - bodyLen -= 192; - - out.write((byte)(((bodyLen >> 8) & 0xff) + 192)); - out.write((byte)bodyLen); - } - else - { - out.write(0xff); - out.write((byte)(bodyLen >> 24)); - out.write((byte)(bodyLen >> 16)); - out.write((byte)(bodyLen >> 8)); - out.write((byte)bodyLen); - } + StreamUtil.writeNewPacketLength(out, bodyLen); } if (critical) diff --git a/pg/src/main/java/org/bouncycastle/bcpg/SignatureSubpacketInputStream.java b/pg/src/main/java/org/bouncycastle/bcpg/SignatureSubpacketInputStream.java index 963616b736..7f34ca073b 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/SignatureSubpacketInputStream.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/SignatureSubpacketInputStream.java @@ -14,6 +14,7 @@ import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.bcpg.sig.NotationData; import org.bouncycastle.bcpg.sig.PolicyURI; +import org.bouncycastle.bcpg.sig.PreferredAEADCiphersuites; import org.bouncycastle.bcpg.sig.PreferredAlgorithms; import org.bouncycastle.bcpg.sig.PrimaryUserID; import org.bouncycastle.bcpg.sig.RegularExpression; @@ -67,33 +68,17 @@ public int read() public SignatureSubpacket readPacket() throws IOException { - int l = this.read(); - int bodyLen = 0; - - if (l < 0) + boolean[] flags = new boolean[3]; + int bodyLen = StreamUtil.readBodyLen(this, flags); + if (flags[StreamUtil.flag_eof]) { return null; } - - boolean isLongLength = false; - - if (l < 192) - { - bodyLen = l; - } - else if (l <= 223) - { - bodyLen = ((l - 192) << 8) + (in.read()) + 192; - } - else if (l == 255) - { - isLongLength = true; - bodyLen = (in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); - } - else + else if (flags[StreamUtil.flag_partial]) { throw new IOException("unexpected length header"); } + boolean isLongLength = flags[StreamUtil.flag_isLongLength]; int tag = in.read(); @@ -164,8 +149,9 @@ else if (l == 255) case PREFERRED_COMP_ALGS: case PREFERRED_HASH_ALGS: case PREFERRED_SYM_ALGS: - case PREFERRED_AEAD_ALGORITHMS: return new PreferredAlgorithms(type, isCritical, isLongLength, data); + case PREFERRED_AEAD_ALGORITHMS: + return new PreferredAEADCiphersuites(isCritical, isLongLength, data); case KEY_FLAGS: return new KeyFlags(isCritical, isLongLength, data); case POLICY_URL: diff --git a/pg/src/main/java/org/bouncycastle/bcpg/StreamUtil.java b/pg/src/main/java/org/bouncycastle/bcpg/StreamUtil.java index 8247977d71..3f7df33323 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/StreamUtil.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/StreamUtil.java @@ -4,11 +4,14 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.nio.channels.FileChannel; +import org.bouncycastle.util.Arrays; + class StreamUtil { - private static final long MAX_MEMORY = Runtime.getRuntime().maxMemory(); + private static final long MAX_MEMORY = Runtime.getRuntime().maxMemory(); /** * Find out possible longest length, capped by available memory. @@ -28,7 +31,7 @@ else if (in instanceof FileInputStream) try { FileChannel channel = ((FileInputStream)in).getChannel(); - long size = (channel != null) ? channel.size() : Integer.MAX_VALUE; + long size = (channel != null) ? channel.size() : Integer.MAX_VALUE; if (size < Integer.MAX_VALUE) { @@ -48,4 +51,167 @@ else if (in instanceof FileInputStream) return (int)MAX_MEMORY; } + + static void writeNewPacketLength(OutputStream out, long bodyLen) + throws IOException + { + if (bodyLen < 192) + { + out.write((byte)bodyLen); + } + else if (bodyLen <= 8383) + { + bodyLen -= 192; + + out.write((byte)(((bodyLen >> 8) & 0xff) + 192)); + out.write((byte)bodyLen); + } + else + { + out.write(0xff); + writeBodyLen(out, bodyLen); + } + } + + static void writeBodyLen(OutputStream out, long bodyLen) + throws IOException + { + out.write((byte)(bodyLen >> 24)); + out.write((byte)(bodyLen >> 16)); + out.write((byte)(bodyLen >> 8)); + out.write((byte)bodyLen); + } + + static void writeKeyID(BCPGOutputStream pOut, long keyID) + throws IOException + { + pOut.write((byte)(keyID >> 56)); + pOut.write((byte)(keyID >> 48)); + pOut.write((byte)(keyID >> 40)); + pOut.write((byte)(keyID >> 32)); + pOut.write((byte)(keyID >> 24)); + pOut.write((byte)(keyID >> 16)); + pOut.write((byte)(keyID >> 8)); + pOut.write((byte)(keyID)); + } + + static long readKeyID(BCPGInputStream in) + throws IOException + { + long keyID = (long)in.read() << 56; + keyID |= (long)in.read() << 48; + keyID |= (long)in.read() << 40; + keyID |= (long)in.read() << 32; + keyID |= (long)in.read() << 24; + keyID |= (long)in.read() << 16; + keyID |= (long)in.read() << 8; + return keyID | in.read(); + } + + static void writeTime(BCPGOutputStream pOut, long time) + throws IOException + { + StreamUtil.write4OctetLength(pOut, (int)time); + } + + static long readTime(BCPGInputStream in) + throws IOException + { + return (long)read4OctetLength(in) * 1000L; + } + + static void write2OctetLength(OutputStream pOut, int len) + throws IOException + { + pOut.write(len >> 8); + pOut.write(len); + } + + static int read2OctetLength(InputStream in) + throws IOException + { + return (in.read() << 8) | in.read(); + } + + static void write4OctetLength(OutputStream pOut, int len) + throws IOException + { + pOut.write(len >> 24); + pOut.write(len >> 16); + pOut.write(len >> 8); + pOut.write(len); + } + + static int read4OctetLength(InputStream in) + throws IOException + { + return (in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); + } + + static int flag_eof = 0; + static int flag_isLongLength = 1; + static int flag_partial = 2; + /** + * Note: flags is an array of three boolean values: + * flags[0] indicates l is negative, flag for eof + * flags[1] indicates (is)longLength = true + * flags[2] indicate partial = true + */ + static int readBodyLen(InputStream in, boolean[] flags) + throws IOException + { + Arrays.fill(flags, false); + int l = in.read(); + int bodyLen = -1; + if (l < 0) + { + flags[flag_eof] = true; + } + if (l < 192) + { + bodyLen = l; + } + else if (l <= 223) + { + bodyLen = ((l - 192) << 8) + (in.read()) + 192; + } + else if (l == 255) + { + flags[flag_isLongLength] = true; + bodyLen = StreamUtil.read4OctetLength(in); + } + else + { + flags[flag_partial] = true; + bodyLen = 1 << (l & 0x1f); + } + return bodyLen; + } + + static void write8OctetLength(OutputStream pOut, long len) + throws IOException + { + pOut.write((int) (len >> 56)); + pOut.write((int) (len >> 48)); + pOut.write((int) (len >> 40)); + pOut.write((int) (len >> 32)); + pOut.write((int) (len >> 24)); + pOut.write((int) (len >> 16)); + pOut.write((int) (len >> 8)); + pOut.write((int) len); + } + + static long read8OctetLength(InputStream in) + throws IOException + { + return ((long) in.read() << 56) | + ((long) in.read() << 48) | + ((long) in.read() << 40) | + ((long) in.read() << 32) | + ((long) in.read() << 24) | + ((long) in.read() << 16) | + ((long) in.read() << 8) | + ((long) in.read()); + } + } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/SymmetricEncDataPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/SymmetricEncDataPacket.java index b7e7015edc..90cf34ece3 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/SymmetricEncDataPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/SymmetricEncDataPacket.java @@ -10,14 +10,21 @@ public class SymmetricEncDataPacket implements BCPGHeaderObject { public SymmetricEncDataPacket( - BCPGInputStream in) + BCPGInputStream in) { - super(in); + this(in, false); + } + + public SymmetricEncDataPacket( + BCPGInputStream in, + boolean newPacketFormat) + { + super(in, SYMMETRIC_KEY_ENC, newPacketFormat); } public SymmetricEncDataPacket() { - super(null); + super(null, SYMMETRIC_KEY_ENC); } @Override diff --git a/pg/src/main/java/org/bouncycastle/bcpg/SymmetricEncIntegrityPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/SymmetricEncIntegrityPacket.java index de9952a82c..79bc42357c 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/SymmetricEncIntegrityPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/SymmetricEncIntegrityPacket.java @@ -1,7 +1,10 @@ package org.bouncycastle.bcpg; +import java.io.EOFException; import java.io.IOException; +import org.bouncycastle.util.Arrays; + /** * A symmetric key encrypted packet with an associated integrity check code. */ @@ -9,22 +12,82 @@ public class SymmetricEncIntegrityPacket extends InputStreamPacket implements BCPGHeaderObject { - int version; + /** + * Version 1 SEIPD packet. + * Used only with {@link SymmetricKeyEncSessionPacket#VERSION_4} or {@link PublicKeyEncSessionPacket#VERSION_3}. + */ + public static final int VERSION_1 = 1; + + /** + * Version 2 SEIPD packet. + * Used only with {@link SymmetricKeyEncSessionPacket#VERSION_6} or {@link PublicKeyEncSessionPacket#VERSION_6}. + */ + public static final int VERSION_2 = 2; + + int version; // V1, V2 + int cipherAlgorithm; // V2 + int aeadAlgorithm; // V2 + int chunkSize; // V2 + byte[] salt; // V2 SymmetricEncIntegrityPacket( - BCPGInputStream in) + BCPGInputStream in) + throws IOException + { + this(in, false); + } + + SymmetricEncIntegrityPacket( + BCPGInputStream in, + boolean newPacketFormat) throws IOException { - super(in); + super(in, SYM_ENC_INTEGRITY_PRO, newPacketFormat); version = in.read(); + + // V2 packet has additional fields + if (version == VERSION_2) + { + cipherAlgorithm = in.read(); + aeadAlgorithm = in.read(); + chunkSize = in.read(); + salt = new byte[32]; + if (in.read(salt) != salt.length) + { + throw new EOFException("Premature end of stream."); + } + } } + /** + * @deprecated use createVersion1Packet() + */ public SymmetricEncIntegrityPacket() { - super(null); + super(null, SYM_ENC_INTEGRITY_PRO); + + version = VERSION_1; + } + + private SymmetricEncIntegrityPacket(int version, int algorithm, int aeadAlgorithm, int chunkSize, byte[] salt) + { + super(null, SYM_ENC_INTEGRITY_PRO); + this.version = version; + this.cipherAlgorithm = algorithm; + this.aeadAlgorithm = aeadAlgorithm; + this.chunkSize = chunkSize; + this.salt = Arrays.clone(salt); + } - version = 1; + public static SymmetricEncIntegrityPacket createVersion1Packet() + { + return new SymmetricEncIntegrityPacket(); + } + + public static SymmetricEncIntegrityPacket createVersion2Packet(int algorithm, int aeadAlgorithm, int chunkSize, byte[] salt) + { + return new SymmetricEncIntegrityPacket(VERSION_2, algorithm, aeadAlgorithm, chunkSize, salt); } public int getVersion() @@ -43,5 +106,79 @@ public void encode(BCPGOutputStream bcpgOut) throws IOException { bcpgOut.write(getVersion()); + + if (version == VERSION_2) + { + bcpgOut.write(cipherAlgorithm); + bcpgOut.write(aeadAlgorithm); + bcpgOut.write(chunkSize); + bcpgOut.write(salt); + } + } + + /** + * Return the cipher algorithm. + * V2 SEIPD packet only. + * + * @return cipher algorithm + */ + public int getCipherAlgorithm() + { + return cipherAlgorithm; + } + + /** + * Return the AEAD algorithm. + * V2 SEIPD packet only. + * + * @return AEAD algorithm + */ + public int getAeadAlgorithm() + { + return aeadAlgorithm; + } + + /** + * Return the chunksize for the AEAD construction. + * V2 SEIPD packet only. + * + * @return chunksize + */ + public int getChunkSize() + { + return chunkSize; + } + + /** + * Return the AEAD additional authenticated data, which is also used as HKDF info. + * V2 SEIPD packet only. + * + * @return aadata + */ + public byte[] getAAData() + { + return createAAData(getVersion(), getCipherAlgorithm(), getAeadAlgorithm(), getChunkSize()); + } + + public static byte[] createAAData(int version, int cipherAlgorithm, int aeadAlgorithm, int chunkSize) + { + return new byte[]{ + (byte)(0xC0 | PacketTags.SYM_ENC_INTEGRITY_PRO), + (byte)(version & 0xff), + (byte)(cipherAlgorithm & 0xff), + (byte)(aeadAlgorithm & 0xff), + (byte)(chunkSize & 0xff) + }; + } + + /** + * Return the salt used to derive the message key. + * V2 SEIPD packet only. + * + * @return salt + */ + public byte[] getSalt() + { + return Arrays.copyOf(salt, salt.length); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/SymmetricKeyAlgorithmTags.java b/pg/src/main/java/org/bouncycastle/bcpg/SymmetricKeyAlgorithmTags.java index 4004b31bd2..1b576ccd87 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/SymmetricKeyAlgorithmTags.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/SymmetricKeyAlgorithmTags.java @@ -1,22 +1,75 @@ package org.bouncycastle.bcpg; /** - * Basic tags for symmetric key algorithms + * Basic tags for symmetric key algorithms. + * + * @see + * RFC4880 - Symmetric-Key Algorithms + * @see + * LibrePGP - Symmetric-Key Algorithms + * @see + * Crypto-Refresh - Symmetric-Key Algorithms */ public interface SymmetricKeyAlgorithmTags { - int NULL = 0; // Plaintext or unencrypted data - int IDEA = 1; // IDEA [IDEA] - int TRIPLE_DES = 2; // Triple-DES (DES-EDE, as per spec -168 bit key derived from 192) - int CAST5 = 3; // CAST5 (128 bit key, as per RFC 2144) - int BLOWFISH = 4; // Blowfish (128 bit key, 16 rounds) [BLOWFISH] - int SAFER = 5; // SAFER-SK128 (13 rounds) [SAFER] - int DES = 6; // Reserved for DES/SK - int AES_128 = 7; // Reserved for AES with 128-bit key - int AES_192 = 8; // Reserved for AES with 192-bit key - int AES_256 = 9; // Reserved for AES with 256-bit key - int TWOFISH = 10; // Reserved for Twofish - int CAMELLIA_128 = 11; // Reserved for Camellia with 128-bit key - int CAMELLIA_192 = 12; // Reserved for Camellia with 192-bit key - int CAMELLIA_256 = 13; // Reserved for Camellia with 256-bit key + /** + * Plaintext or unencrypted data. + */ + int NULL = 0; + /** + * IDEA. + */ + int IDEA = 1; + /** + * Triple-DES (DES-EDE, as per spec - 168-bit key derived from 192). + */ + int TRIPLE_DES = 2; + /** + * CAST5 (128-bit key, as per RFC 2144). + */ + int CAST5 = 3; + /** + * Blowfish (128-bit key, 16 rounds). + */ + int BLOWFISH = 4; + /** + * Reserved for SAFER-SK128 (13 rounds). + */ + int SAFER = 5; + /** + * Reserved for DES/SK. + */ + int DES = 6; + /** + * AES with 128-bit key. + */ + int AES_128 = 7; + /** + * AES with 192-bit key. + */ + int AES_192 = 8; + /** + * AES with 256-bit key. + */ + int AES_256 = 9; + /** + * Twofish with 256-bit key. + */ + int TWOFISH = 10; + /** + * Camellia with 128-bit key. + */ + int CAMELLIA_128 = 11; + /** + * Camellia with 192-bit key. + */ + int CAMELLIA_192 = 12; + /** + * Camellia with 256-bit key. + */ + int CAMELLIA_256 = 13; + + // 100 to 110: Private/Experimental algorithms + + // 253, 254, 255 reserved to avoid collision with secret key encryption } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/SymmetricKeyEncSessionPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/SymmetricKeyEncSessionPacket.java index cdc58e4d1c..93d01dc76b 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/SymmetricKeyEncSessionPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/SymmetricKeyEncSessionPacket.java @@ -1,46 +1,238 @@ package org.bouncycastle.bcpg; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.EOFException; import java.io.IOException; /** * Basic type for a symmetric encrypted session key packet */ -public class SymmetricKeyEncSessionPacket +public class SymmetricKeyEncSessionPacket extends ContainedPacket { - private int version; - private int encAlgorithm; - private S2K s2k; - private byte[] secKeyData; - + /** + * Version 4 SKESK packet. + * Used only with {@link SymmetricEncIntegrityPacket#VERSION_1 V1 SEIPD} or {@link SymmetricEncDataPacket SED} packets. + */ + public static final int VERSION_4 = 4; + + /** + * Version 5 SKESK packet. + * Used only with {@link AEADEncDataPacket AED} packets. + */ + public static final int VERSION_5 = 5; + + /** + * Version 6 SKESK packet. + * Used only with {@link SymmetricEncIntegrityPacket#VERSION_2 V2 SEIPD} packets. + */ + public static final int VERSION_6 = 6; + + private int version; // V4, V5, V6 + private int encAlgorithm; // V4, V5, V6 + private S2K s2k; // V4, + // array for exposing raw S2K parameters. Useful for forwards compat. + private byte[] s2kBytes; // Makes only sense for v6, since there we have a counter + private byte[] secKeyData; // V4, V5, V6 + private int aeadAlgorithm; // V5, V6 + private byte[] iv; // V5, V6 + private byte[] authTag; // V5, V6 + public SymmetricKeyEncSessionPacket( - BCPGInputStream in) + BCPGInputStream in) + throws IOException + { + this(in, false); + } + public SymmetricKeyEncSessionPacket( + BCPGInputStream in, + boolean newPacketFormat) throws IOException { + super(SYMMETRIC_KEY_ENC_SESSION, newPacketFormat); + version = in.read(); - if (version != 4) + if (version == VERSION_4) + { + encAlgorithm = in.read(); + + s2k = new S2K(in); + + this.secKeyData = in.readAll(); + } + else if (version == VERSION_5 || version == VERSION_6) + { + // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.3.2-3.2 + // SymAlg + AEADAlg + S2KCount + S2K + IV + int next5Fields5Count = in.read(); + encAlgorithm = in.read(); + aeadAlgorithm = in.read(); + + // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.3.2-3.5 + int s2kOctetCount = in.read(); + + //TODO: use this line to replace the following code? + s2k = new S2K(in); +// s2kBytes = new byte[s2kOctetCount]; +// in.readFully(s2kBytes); +// try +// { +// s2k = new S2K(new ByteArrayInputStream(s2kBytes)); +// } +// catch (UnsupportedPacketVersionException e) +// { +// +// // We gracefully catch the error. +// } + + int ivLen = next5Fields5Count - 3 - s2kOctetCount; + iv = new byte[ivLen]; // also called nonce + if (in.read(iv) != iv.length) + { + throw new EOFException("Premature end of stream."); + } + + int authTagLen = AEADUtils.getAuthTagLength(aeadAlgorithm); + authTag = new byte[authTagLen]; + + // Read all trailing bytes + byte[] sessKeyAndAuthTag = in.readAll(); + // determine session key length by subtracting auth tag + this.secKeyData = new byte[sessKeyAndAuthTag.length - authTagLen]; + + System.arraycopy(sessKeyAndAuthTag, 0, secKeyData, 0, secKeyData.length); + System.arraycopy(sessKeyAndAuthTag, secKeyData.length, authTag, 0, authTagLen); + } + else { throw new UnsupportedPacketVersionException("Unsupported PGP symmetric-key encrypted session key packet version encountered: " + version); } - encAlgorithm = in.read(); - s2k = new S2K(in); + } + + /** + * Create a v4 SKESK packet. + * + * @param encAlgorithm symmetric encryption algorithm + * @param s2k s2k specifier + * @param secKeyData encrypted session key + */ + public static SymmetricKeyEncSessionPacket createV4Packet( + int encAlgorithm, + S2K s2k, + byte[] secKeyData) + { + return new SymmetricKeyEncSessionPacket(encAlgorithm, s2k, secKeyData); + } + + /** + * Create a v5 SKESK packet. + * + * @param encAlgorithm symmetric encryption algorithm + * @param aeadAlgorithm aead algorithm + * @param iv initialization vector + * @param s2k s2k specifier + * @param secKeyData encrypted session key + * @param authTag authentication tag + */ + public static SymmetricKeyEncSessionPacket createV5Packet( + int encAlgorithm, + int aeadAlgorithm, + byte[] iv, + S2K s2k, + byte[] secKeyData, + byte[] authTag) + { + return new SymmetricKeyEncSessionPacket(VERSION_5, encAlgorithm, aeadAlgorithm, iv, s2k, secKeyData, authTag); + } - this.secKeyData = in.readAll(); + /** + * Create a v6 SKESK packet. + * + * @param encAlgorithm symmetric encryption algorithm + * @param aeadAlgorithm aead algorithm + * @param s2k s2k specifier + * @param iv initialization vector + * @param secKeyData encrypted session key + * @param authTag authentication tag + */ + public static SymmetricKeyEncSessionPacket createV6Packet( + int encAlgorithm, + int aeadAlgorithm, + byte[] iv, + S2K s2k, + byte[] secKeyData, + byte[] authTag) + { + return new SymmetricKeyEncSessionPacket(VERSION_6, encAlgorithm, aeadAlgorithm, iv, s2k, secKeyData, authTag); } + /** + * Create a v4 SKESK packet. + * + * @param encAlgorithm symmetric encryption algorithm + * @param s2k s2k + * @param secKeyData encrypted session key + * @deprecated use createVersion4Packet() + */ public SymmetricKeyEncSessionPacket( - int encAlgorithm, - S2K s2k, - byte[] secKeyData) + int encAlgorithm, + S2K s2k, + byte[] secKeyData) { - this.version = 4; + super(SYMMETRIC_KEY_ENC_SESSION); + + this.version = VERSION_4; this.encAlgorithm = encAlgorithm; this.s2k = s2k; this.secKeyData = secKeyData; } - + + /** + * Create a v5 or v6 SKESK packet. + * + * @param encAlgorithm symmetric encryption algorithm + * @param aeadAlgorithm aead algorithm + * @param iv initialization vector + * @param s2k s2k specifier + * @param secKeyData encrypted session key + * @param authTag authentication tag + */ + private SymmetricKeyEncSessionPacket( + int version, + int encAlgorithm, + int aeadAlgorithm, + byte[] iv, + S2K s2k, + byte[] secKeyData, + byte[] authTag) + { + super(SYMMETRIC_KEY_ENC_SESSION); + + this.version = version; + this.encAlgorithm = encAlgorithm; + this.aeadAlgorithm = aeadAlgorithm; + this.s2k = s2k; + this.secKeyData = secKeyData; + + int expectedIVLen = AEADUtils.getIVLength(aeadAlgorithm); + if (expectedIVLen != iv.length) + { + throw new IllegalArgumentException("Mismatched AEAD IV length. " + + "Expected " + expectedIVLen + ", got " + iv.length); + } + this.iv = iv; + + int expectedAuthTagLen = AEADUtils.getAuthTagLength(aeadAlgorithm); + if (expectedAuthTagLen != authTag.length) + { + throw new IllegalArgumentException("Mismatched AEAD AuthTag length. " + + "Expected " + expectedAuthTagLen + ", got " + authTag.length); + } + this.authTag = authTag; + } + /** * @return int */ @@ -72,25 +264,101 @@ public int getVersion() { return version; } - + + /** + * Return the AEAD algorithm tag. + * V5 packet only. + * + * @return aead algorithm + */ + public int getAeadAlgorithm() + { + return aeadAlgorithm; + } + + /** + * Return the IV for the AEAD mode. This is also called nonce. + * V5 packet only. + * + * @return iv + */ + public byte[] getIv() + { + return iv; + } + + /** + * Return the authentication tag for the AEAD mode. + * V5 packet only. + * + * @return AEAD auth tag + */ + public byte[] getAuthTag() + { + return authTag; + } + + public byte[] getAAData() + { + return createAAData(getVersion(), getEncAlgorithm(), getAeadAlgorithm()); + } + + public static byte[] createAAData(int version, int encAlgorithm, int aeadAlgorithm) + { + byte[] aaData = new byte[4]; + aaData[0] = (byte)(0xC0 | PacketTags.SYMMETRIC_KEY_ENC_SESSION); + aaData[1] = (byte)(version & 0xff); + aaData[2] = (byte)(encAlgorithm & 0xff); + aaData[3] = (byte)(aeadAlgorithm & 0xff); + return aaData; + } + public void encode( - BCPGOutputStream out) + BCPGOutputStream out) throws IOException { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - BCPGOutputStream pOut = new BCPGOutputStream(bOut); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut; + if (version == 4) + { + pOut = new BCPGOutputStream(bOut); + } + else + { + pOut = new BCPGOutputStream(bOut, true); + } pOut.write(version); - pOut.write(encAlgorithm); - pOut.writeObject(s2k); - - if (secKeyData != null && secKeyData.length > 0) + if (version == VERSION_4) { - pOut.write(secKeyData); + pOut.write(encAlgorithm); + pOut.writeObject(s2k); + + if (secKeyData != null && secKeyData.length > 0) + { + pOut.write(secKeyData); + } + } + else if (version == VERSION_5 || version == VERSION_6) + { + int s2kLen = s2k.getEncoded().length; + int count = 1 + 1 + 1 + s2kLen + iv.length; + pOut.write(count); // len of 5 following fields + pOut.write(encAlgorithm); + pOut.write(aeadAlgorithm); + pOut.write(s2kLen); + pOut.writeObject(s2k); + pOut.write(iv); + + if (secKeyData != null && secKeyData.length > 0) + { + pOut.write(secKeyData); + } + pOut.write(authTag); } pOut.close(); - out.writePacket(SYMMETRIC_KEY_ENC_SESSION, bOut.toByteArray()); + out.writePacket(hasNewPacketFormat(), SYMMETRIC_KEY_ENC_SESSION, bOut.toByteArray()); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/SymmetricKeyUtils.java b/pg/src/main/java/org/bouncycastle/bcpg/SymmetricKeyUtils.java new file mode 100644 index 0000000000..36b6021dd6 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/SymmetricKeyUtils.java @@ -0,0 +1,40 @@ +package org.bouncycastle.bcpg; + +public class SymmetricKeyUtils + implements SymmetricKeyAlgorithmTags +{ + public static int getKeyLengthInBits(int algorithm) + { + switch (algorithm) + { + case NULL: + throw new IllegalArgumentException("NULL is no encryption algorithm."); + case DES: + return 64; + case IDEA: + case CAST5: + case BLOWFISH: + case SAFER: + case AES_128: + case CAMELLIA_128: + return 128; + + case TRIPLE_DES: + case AES_192: + case CAMELLIA_192: + return 192; + + case AES_256: + case TWOFISH: + case CAMELLIA_256: + return 256; + default: + throw new IllegalArgumentException("unknown symmetric algorithm: " + algorithm); + } + } + + public static int getKeyLengthInOctets(int algorithm) + { + return (getKeyLengthInBits(algorithm) + 7) / 8; + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/TrustPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/TrustPacket.java index 16dbabe6d4..db920ec297 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/TrustPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/TrustPacket.java @@ -10,11 +10,21 @@ public class TrustPacket extends ContainedPacket { byte[] levelAndTrustAmount; - + + public TrustPacket( + BCPGInputStream in) + throws IOException + { + this(in, false); + } + public TrustPacket( - BCPGInputStream in) + BCPGInputStream in, + boolean newPacketFormat) throws IOException { + super(TRUST, newPacketFormat); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int ch; @@ -29,6 +39,8 @@ public TrustPacket( public TrustPacket( int trustCode) { + super(TRUST); + this.levelAndTrustAmount = new byte[1]; this.levelAndTrustAmount[0] = (byte)trustCode; @@ -43,6 +55,6 @@ public void encode( BCPGOutputStream out) throws IOException { - out.writePacket(TRUST, levelAndTrustAmount); + out.writePacket(hasNewPacketFormat(), TRUST, levelAndTrustAmount); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/UnknownBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/UnknownBCPGKey.java new file mode 100644 index 0000000000..27eefece3e --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/UnknownBCPGKey.java @@ -0,0 +1,21 @@ +package org.bouncycastle.bcpg; + +import java.io.IOException; + +/** + * Key class for unknown/unsupported OpenPGP key types. + */ +public class UnknownBCPGKey + extends OctetArrayBCPGKey +{ + public UnknownBCPGKey(int length, BCPGInputStream in) + throws IOException + { + super(length, in); + } + + public UnknownBCPGKey(int length, byte[] key) + { + super(length, key); + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/UnknownPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/UnknownPacket.java new file mode 100644 index 0000000000..5f11541625 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/UnknownPacket.java @@ -0,0 +1,37 @@ +package org.bouncycastle.bcpg; + +import java.io.IOException; + +import org.bouncycastle.util.Arrays; + +public class UnknownPacket + extends ContainedPacket +{ + private final byte[] contents; + + public UnknownPacket(int tag, BCPGInputStream in) + throws IOException + { + this(tag, in, false); + } + + public UnknownPacket(int tag, BCPGInputStream in, boolean newPacketFormat) + throws IOException + { + super(tag, newPacketFormat); + this.contents = in.readAll(); + } + + public byte[] getContents() + { + return Arrays.clone(contents); + } + + @Override + public void encode( + BCPGOutputStream out) + throws IOException + { + out.writePacket(hasNewPacketFormat(), getPacketTag(), contents); + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/UserAttributePacket.java b/pg/src/main/java/org/bouncycastle/bcpg/UserAttributePacket.java index 7b391ed965..d0b099cfb7 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/UserAttributePacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/UserAttributePacket.java @@ -11,11 +11,21 @@ public class UserAttributePacket extends ContainedPacket { private UserAttributeSubpacket[] subpackets; - + + public UserAttributePacket( + BCPGInputStream in) + throws IOException + { + this(in, false); + } + public UserAttributePacket( - BCPGInputStream in) + BCPGInputStream in, + boolean newPacketFormat) throws IOException { + super(USER_ATTRIBUTE, newPacketFormat); + UserAttributeSubpacketInputStream sIn = new UserAttributeSubpacketInputStream(in); UserAttributeSubpacket sub; @@ -36,6 +46,8 @@ public UserAttributePacket( public UserAttributePacket( UserAttributeSubpacket[] subpackets) { + super(USER_ATTRIBUTE); + this.subpackets = subpackets; } @@ -55,6 +67,6 @@ public void encode( subpackets[i].encode(bOut); } - out.writePacket(USER_ATTRIBUTE, bOut.toByteArray()); + out.writePacket(hasNewPacketFormat(), USER_ATTRIBUTE, bOut.toByteArray()); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/UserAttributeSubpacket.java b/pg/src/main/java/org/bouncycastle/bcpg/UserAttributeSubpacket.java index f372399dba..a661a146a5 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/UserAttributeSubpacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/UserAttributeSubpacket.java @@ -64,10 +64,7 @@ else if (bodyLen <= 8383 && !forceLongLength) else { out.write(0xff); - out.write((byte)(bodyLen >> 24)); - out.write((byte)(bodyLen >> 16)); - out.write((byte)(bodyLen >> 8)); - out.write((byte)bodyLen); + StreamUtil.writeBodyLen(out, bodyLen); } out.write(type); diff --git a/pg/src/main/java/org/bouncycastle/bcpg/UserAttributeSubpacketInputStream.java b/pg/src/main/java/org/bouncycastle/bcpg/UserAttributeSubpacketInputStream.java index 2b1ed0d195..dfc33988f6 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/UserAttributeSubpacketInputStream.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/UserAttributeSubpacketInputStream.java @@ -10,111 +10,97 @@ * reader for user attribute sub-packets */ public class UserAttributeSubpacketInputStream - extends InputStream implements UserAttributeSubpacketTags + extends InputStream + implements UserAttributeSubpacketTags { - InputStream in; - + InputStream in; + public UserAttributeSubpacketInputStream( - InputStream in) + InputStream in) { this.in = in; } - + public int available() throws IOException { return in.available(); } - + public int read() throws IOException { return in.read(); } - + private void readFully( - byte[] buf, - int off, - int len) + byte[] buf, + int off, + int len) throws IOException { if (len > 0) { - int b = this.read(); - + int b = this.read(); + if (b < 0) { throw new EOFException(); } - + buf[off] = (byte)b; off++; len--; } - + while (len > 0) { - int l = in.read(buf, off, len); - + int l = in.read(buf, off, len); + if (l < 0) { throw new EOFException(); } - + off += l; len -= l; } } - + public UserAttributeSubpacket readPacket() throws IOException { - int l = this.read(); - int bodyLen = 0; - boolean longLength = false; - - if (l < 0) + boolean[] flags = new boolean[3]; + int bodyLen = StreamUtil.readBodyLen(this, flags); + if (flags[StreamUtil.flag_eof]) { return null; } - - if (l < 192) - { - bodyLen = l; - } - else if (l <= 223) + else if (flags[StreamUtil.flag_partial]) { - bodyLen = ((l - 192) << 8) + (in.read()) + 192; - } - else if (l == 255) - { - bodyLen = (in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); - longLength = true; + throw new IOException("unrecognised length reading user attribute sub packet"); } - else + boolean longLength = flags[StreamUtil.flag_isLongLength]; + + int tag = in.read(); + + if (tag < 0) { - throw new IOException("unrecognised length reading user attribute sub packet"); + throw new EOFException("unexpected EOF reading user attribute sub packet"); } - int tag = in.read(); + byte[] data = new byte[bodyLen - 1]; - if (tag < 0) - { - throw new EOFException("unexpected EOF reading user attribute sub packet"); - } - - byte[] data = new byte[bodyLen - 1]; + this.readFully(data, 0, data.length); - this.readFully(data, 0, data.length); - - int type = tag; + int type = tag; - switch (type) - { - case IMAGE_ATTRIBUTE: - return new ImageAttribute(longLength, data); - } + switch (type) + { + case IMAGE_ATTRIBUTE: + return new ImageAttribute(longLength, data); + } - return new UserAttributeSubpacket(type, longLength, data); + return new UserAttributeSubpacket(type, longLength, data); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/UserIDPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/UserIDPacket.java index 5c30df5d35..7256e1466b 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/UserIDPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/UserIDPacket.java @@ -13,22 +13,36 @@ public class UserIDPacket implements UserDataPacket { private byte[] idData; - + + public UserIDPacket( + BCPGInputStream in) + throws IOException + { + this(in, false); + } + public UserIDPacket( - BCPGInputStream in) + BCPGInputStream in, + boolean newPacketFormat) throws IOException { + super(USER_ID, newPacketFormat); + this.idData = in.readAll(); } public UserIDPacket( String id) { + super(USER_ID); + this.idData = Strings.toUTF8ByteArray(id); } public UserIDPacket(byte[] rawID) { + super(USER_ID); + this.idData = Arrays.clone(rawID); } @@ -61,6 +75,6 @@ public void encode( BCPGOutputStream out) throws IOException { - out.writePacket(USER_ID, idData); + out.writePacket(hasNewPacketFormat(), USER_ID, idData); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/X25519PublicBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/X25519PublicBCPGKey.java new file mode 100644 index 0000000000..a0db01b01e --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/X25519PublicBCPGKey.java @@ -0,0 +1,31 @@ +package org.bouncycastle.bcpg; + +import java.io.IOException; + +/** + * Public key of type {@link PublicKeyAlgorithmTags#X25519}. + * This type was introduced with Crypto-Refresh and can be used with v4, v6 keys. + * Note however, that legacy implementations might not understand this key type yet. + * For a key type compatible with legacy v4 implementations, see {@link ECDHPublicBCPGKey} with + * {@link PublicKeyAlgorithmTags#ECDH}. + * + * @see + * Crypto-Refresh - Algorithm-Specific Part for X25519 Keys + */ +public class X25519PublicBCPGKey + extends OctetArrayBCPGKey +{ + // 32 octets of the native public key + public static final int LENGTH = 32; + + public X25519PublicBCPGKey(BCPGInputStream in) + throws IOException + { + super(LENGTH, in); + } + + public X25519PublicBCPGKey(byte[] key) + { + super(LENGTH, key); + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/X25519SecretBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/X25519SecretBCPGKey.java new file mode 100644 index 0000000000..17043353af --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/X25519SecretBCPGKey.java @@ -0,0 +1,33 @@ +package org.bouncycastle.bcpg; + +import java.io.IOException; + +/** + * Secret key of type {@link PublicKeyAlgorithmTags#X25519}. + * This type was introduced with Crypto-Refresh and can be used with v4, v6 keys. + * Note however, that legacy implementations might not understand this key type yet. + * For a key type compatible with legacy v4 implementations, see {@link ECSecretBCPGKey} with + * {@link PublicKeyAlgorithmTags#ECDH}. + * Note: Contrary to {@link ECSecretBCPGKey} using {@link PublicKeyAlgorithmTags#ECDH}, which uses big-endian + * MPI encoding to encode the secret key material, {@link X25519SecretBCPGKey} uses native little-endian encoding. + * + * @see + * Crypto-Refresh - Algorithm-Specific Part for X25519 Keys + */ +public class X25519SecretBCPGKey + extends OctetArrayBCPGKey +{ + // 32 octets of the native secret key + public static final int LENGTH = 32; + + public X25519SecretBCPGKey(BCPGInputStream in) + throws IOException + { + super(LENGTH, in); + } + + public X25519SecretBCPGKey(byte[] key) + { + super(LENGTH, key); + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/X448PublicBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/X448PublicBCPGKey.java new file mode 100644 index 0000000000..6881b276ba --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/X448PublicBCPGKey.java @@ -0,0 +1,31 @@ +package org.bouncycastle.bcpg; + +import java.io.IOException; + +/** + * Public key of type {@link PublicKeyAlgorithmTags#X448}. + * This type was introduced with Crypto-Refresh and can be used with v4, v6 keys. + * Note however, that legacy implementations might not understand this key type yet. + * For a key type compatible with legacy v4 implementations, see {@link ECDHPublicBCPGKey} with + * {@link PublicKeyAlgorithmTags#ECDH}. + * + * @see + * Crypto-Refresh - Algorithm-Specific Part for X448 Keys + */ +public class X448PublicBCPGKey + extends OctetArrayBCPGKey +{ + // 56 octets of the native public key + public static final int LENGTH = 56; + + public X448PublicBCPGKey(BCPGInputStream in) + throws IOException + { + super(LENGTH, in); + } + + public X448PublicBCPGKey(byte[] key) + { + super(LENGTH, key); + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/X448SecretBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/X448SecretBCPGKey.java new file mode 100644 index 0000000000..8bcf0332e1 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/X448SecretBCPGKey.java @@ -0,0 +1,31 @@ +package org.bouncycastle.bcpg; + +import java.io.IOException; + +/** + * Secret key of type {@link PublicKeyAlgorithmTags#X448}. + * This type was introduced with Crypto-Refresh and can be used with v4, v6 keys. + * Note however, that legacy implementations might not understand this key type yet. + * For a key type compatible with legacy v4 implementations, see {@link ECDHPublicBCPGKey} with + * {@link PublicKeyAlgorithmTags#ECDH}. + * + * @see + * Crypto-Refresh - Algorithm-Specific Part for X448 Keys + */ +public class X448SecretBCPGKey + extends OctetArrayBCPGKey +{ + // 56 octets of the native secret key + public static final int LENGTH = 56; + + public X448SecretBCPGKey(BCPGInputStream in) + throws IOException + { + super(LENGTH, in); + } + + public X448SecretBCPGKey(byte[] key) + { + super(LENGTH, key); + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/sig/Exportable.java b/pg/src/main/java/org/bouncycastle/bcpg/sig/Exportable.java index 476b4eaec4..e5160edf72 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/sig/Exportable.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/sig/Exportable.java @@ -8,23 +8,7 @@ */ public class Exportable extends SignatureSubpacket -{ - private static byte[] booleanToByteArray( - boolean value) - { - byte[] data = new byte[1]; - - if (value) - { - data[0] = 1; - return data; - } - else - { - return data; - } - } - +{ public Exportable( boolean critical, boolean isLongLength, @@ -37,11 +21,11 @@ public Exportable( boolean critical, boolean isExportable) { - super(SignatureSubpacketTags.EXPORTABLE, critical, false, booleanToByteArray(isExportable)); + super(SignatureSubpacketTags.EXPORTABLE, critical, false, Utils.booleanToByteArray(isExportable)); } public boolean isExportable() { - return data[0] != 0; + return Utils.booleanFromByteArray(data); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/sig/Features.java b/pg/src/main/java/org/bouncycastle/bcpg/sig/Features.java index 1f5668c629..e47bcc1e9e 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/sig/Features.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/sig/Features.java @@ -8,19 +8,27 @@ public class Features { /** * Identifier for the Modification Detection (packets 18 and 19) + * Symmetrically Encrypted Integrity Protected Data packet version 1. */ public static final byte FEATURE_MODIFICATION_DETECTION = 0x01; + /** * Identifier for the AEAD Encrypted Data Packet (packet 20) and version 5 * Symmetric-Key Encrypted Session Key Packets (packet 3) */ public static final byte FEATURE_AEAD_ENCRYPTED_DATA = 0x02; + /** * Identifier for the Version 5 Public-Key Packet format and corresponding new * fingerprint format */ public static final byte FEATURE_VERSION_5_PUBLIC_KEY = 0x04; + /** + * Symmetrically Encrypted Integrity Protected Data packet version 2. + */ + public static final byte FEATURE_SEIPD_V2 = 0x08; + private static final byte[] featureToByteArray(byte feature) { byte[] data = new byte[1]; @@ -59,6 +67,11 @@ public boolean supportsModificationDetection() return supportsFeature(FEATURE_MODIFICATION_DETECTION); } + public boolean supportsSEIPDv2() + { + return supportsFeature(FEATURE_SEIPD_V2); + } + /** * Returns if a particular feature is supported. */ diff --git a/pg/src/main/java/org/bouncycastle/bcpg/sig/IssuerFingerprint.java b/pg/src/main/java/org/bouncycastle/bcpg/sig/IssuerFingerprint.java index 8432acb5e7..e294a10fb2 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/sig/IssuerFingerprint.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/sig/IssuerFingerprint.java @@ -1,5 +1,7 @@ package org.bouncycastle.bcpg.sig; +import org.bouncycastle.bcpg.FingerprintUtil; +import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; import org.bouncycastle.util.Arrays; @@ -36,4 +38,21 @@ public byte[] getFingerprint() { return Arrays.copyOfRange(data, 1, data.length); } + + public long getKeyID() + { + if (getKeyVersion() == PublicKeyPacket.VERSION_4) + { + return FingerprintUtil.keyIdFromV4Fingerprint(getFingerprint()); + } + if (getKeyVersion() == PublicKeyPacket.LIBREPGP_5) + { + return FingerprintUtil.keyIdFromLibrePgpFingerprint(getFingerprint()); + } + if (getKeyVersion() == PublicKeyPacket.VERSION_6) + { + return FingerprintUtil.keyIdFromV6Fingerprint(getFingerprint()); + } + return 0; + } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/sig/IssuerKeyID.java b/pg/src/main/java/org/bouncycastle/bcpg/sig/IssuerKeyID.java index 737914cdfe..7b72728bb4 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/sig/IssuerKeyID.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/sig/IssuerKeyID.java @@ -1,5 +1,6 @@ package org.bouncycastle.bcpg.sig; +import org.bouncycastle.bcpg.FingerprintUtil; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; @@ -13,16 +14,7 @@ protected static byte[] keyIDToBytes( long keyId) { byte[] data = new byte[8]; - - data[0] = (byte)(keyId >> 56); - data[1] = (byte)(keyId >> 48); - data[2] = (byte)(keyId >> 40); - data[3] = (byte)(keyId >> 32); - data[4] = (byte)(keyId >> 24); - data[5] = (byte)(keyId >> 16); - data[6] = (byte)(keyId >> 8); - data[7] = (byte)keyId; - + FingerprintUtil.writeKeyID(keyId, data); return data; } @@ -43,9 +35,6 @@ public IssuerKeyID( public long getKeyID() { - long keyID = ((long)(data[0] & 0xff) << 56) | ((long)(data[1] & 0xff) << 48) | ((long)(data[2] & 0xff) << 40) | ((long)(data[3] & 0xff) << 32) - | ((long)(data[4] & 0xff) << 24) | ((data[5] & 0xff) << 16) | ((data[6] & 0xff) << 8) | (data[7] & 0xff); - - return keyID; + return FingerprintUtil.readKeyID(data); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/sig/KeyExpirationTime.java b/pg/src/main/java/org/bouncycastle/bcpg/sig/KeyExpirationTime.java index 14ecfd3831..e618720b59 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/sig/KeyExpirationTime.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/sig/KeyExpirationTime.java @@ -9,19 +9,15 @@ public class KeyExpirationTime extends SignatureSubpacket { + /** + * @deprecated Will be removed + */ protected static byte[] timeToBytes( long t) { - byte[] data = new byte[4]; - - data[0] = (byte)(t >> 24); - data[1] = (byte)(t >> 16); - data[2] = (byte)(t >> 8); - data[3] = (byte)t; - - return data; + return Utils.timeToBytes(t); } - + public KeyExpirationTime( boolean critical, boolean isLongLength, @@ -29,14 +25,14 @@ public KeyExpirationTime( { super(SignatureSubpacketTags.KEY_EXPIRE_TIME, critical, isLongLength, data); } - + public KeyExpirationTime( boolean critical, long seconds) { - super(SignatureSubpacketTags.KEY_EXPIRE_TIME, critical, false, timeToBytes(seconds)); + super(SignatureSubpacketTags.KEY_EXPIRE_TIME, critical, false, Utils.timeToBytes(seconds)); } - + /** * Return the number of seconds after creation time a key is valid for. * @@ -44,8 +40,6 @@ public KeyExpirationTime( */ public long getTime() { - long time = ((long)(data[0] & 0xff) << 24) | ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff); - - return time; + return Utils.timeFromBytes(data); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/sig/PreferredAEADCiphersuites.java b/pg/src/main/java/org/bouncycastle/bcpg/sig/PreferredAEADCiphersuites.java new file mode 100644 index 0000000000..1ed5ae9001 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/sig/PreferredAEADCiphersuites.java @@ -0,0 +1,216 @@ +package org.bouncycastle.bcpg.sig; + +import org.bouncycastle.bcpg.AEADAlgorithmTags; +import org.bouncycastle.bcpg.SignatureSubpacketTags; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; + +public class PreferredAEADCiphersuites + extends PreferredAlgorithms +{ + + private final Combination[] algorithms; + + /** + * AES-128 + OCB is a MUST implement and is therefore implicitly supported. + * + * @see + * Crypto-Refresh § 5.2.3.15. Preferred AEAD Ciphersuites + */ + private static final Combination AES_128_OCB = new Combination(SymmetricKeyAlgorithmTags.AES_128, AEADAlgorithmTags.OCB); + + /** + * Create a new PreferredAEADAlgorithms signature subpacket from raw data. + * + * @param critical whether the subpacket is critical + * @param isLongLength whether the subpacket uses long length encoding + * @param data raw data + */ + public PreferredAEADCiphersuites(boolean critical, boolean isLongLength, byte[] data) + { + super(SignatureSubpacketTags.PREFERRED_AEAD_ALGORITHMS, critical, isLongLength, requireEven(data)); + this.algorithms = parseCombinations(data); + } + + /** + * Create a new PreferredAEADAlgorithm signature subpacket. + * + * @param critical whether the subpacket is critical + * @param combinations list of combinations, with the most preferred option first + */ + public PreferredAEADCiphersuites(boolean critical, Combination[] combinations) + { + this(critical, false, encodeCombinations(combinations)); + } + + /** + * Unmarshall a byte array into a list of algorithm combinations. + * + * @param data marshalled bytes + * @return unmarshalled list + */ + private static Combination[] parseCombinations(byte[] data) + { + Combination[] algorithms = new Combination[data.length / 2]; + for (int i = 0; i < algorithms.length; i++) + { + algorithms[i] = new Combination( + data[i * 2], + data[i * 2 + 1]); + } + return algorithms; + } + + /** + * Marshall the list of combinations into a byte array. + * + * @param combinations list of algorithm combinations + * @return marshalled byte array + */ + private static byte[] encodeCombinations(Combination[] combinations) + { + byte[] encoding = new byte[combinations.length * 2]; + for (int i = 0; i < combinations.length; i++) + { + Combination combination = combinations[i]; + encoding[i * 2] = (byte)(combination.getSymmetricAlgorithm() & 0xff); + encoding[i * 2 + 1] = (byte)(combination.getAeadAlgorithm() & 0xff); + } + return encoding; + } + + /** + * Return true, if the given algorithm combination is supported (explicitly or implicitly). + * + * @param combination combination + * @return true, if the combination is supported, false otherwise + */ + public boolean isSupported(Combination combination) + { + return contains(combination, getAlgorithms()); + } + + private static boolean contains(Combination combination, Combination[] combinations) + { + for (int i = 0; i != combinations.length; i++) + { + Combination supported = combinations[i]; + if (supported.equals(combination)) + { + return true; + } + } + return false; + } + + /** + * Return AEAD algorithm preferences. The most preferred option comes first. + * This method returns the combinations as they are listed in the packet, possibly excluding implicitly supported + * combinations. + * + * @return explicitly supported algorithm combinations + */ + public Combination[] getRawAlgorithms() + { + Combination[] copy = new Combination[algorithms.length]; + System.arraycopy(algorithms, 0, copy, 0, algorithms.length); + return copy; + } + + /** + * Returns AEAD algorithm preferences, including implicitly supported algorithm combinations. + * + * @return all supported algorithm combinations + */ + public Combination[] getAlgorithms() + { + if (!contains(AES_128_OCB, algorithms)) + { + // AES128 + OCB is MUST implement and implicitly supported + Combination[] withImplicitOptionAppended = new Combination[algorithms.length + 1]; + System.arraycopy(algorithms, 0, withImplicitOptionAppended, 0, algorithms.length); + withImplicitOptionAppended[algorithms.length] = AES_128_OCB; + return withImplicitOptionAppended; + } + + return getRawAlgorithms(); + } + + private static byte[] requireEven(byte[] encodedCombinations) + { + if (encodedCombinations.length % 2 != 0) + { + throw new IllegalArgumentException("Even number of bytes expected."); + } + return encodedCombinations; + } + + /** + * Algorithm combination of a {@link SymmetricKeyAlgorithmTags} and a {@link AEADAlgorithmTags}. + */ + public static class Combination + { + private final int symmetricAlgorithm; + private final int aeadAlgorithm; + + /** + * Create a new algorithm combination from a {@link SymmetricKeyAlgorithmTags} and a {@link AEADAlgorithmTags}. + * + * @param symmetricAlgorithmTag symmetric algorithm tag + * @param aeadAlgorithmTag aead algorithm tag + */ + public Combination(int symmetricAlgorithmTag, int aeadAlgorithmTag) + { + this.symmetricAlgorithm = symmetricAlgorithmTag; + this.aeadAlgorithm = aeadAlgorithmTag; + } + + /** + * Return the symmetric algorithm tag. + * + * @return symmetric algorithm + */ + public int getSymmetricAlgorithm() + { + return symmetricAlgorithm; + } + + /** + * Return the AEAD algorithm tag. + * + * @return aead algorithm + */ + public int getAeadAlgorithm() + { + return aeadAlgorithm; + } + + @Override + public boolean equals(Object o) + { + if (o == null) + { + return false; + } + + if (this == o) + { + return true; + } + + if (!(o instanceof Combination)) + { + return false; + } + + Combination other = (Combination)o; + return getSymmetricAlgorithm() == other.getSymmetricAlgorithm() + && getAeadAlgorithm() == other.getAeadAlgorithm(); + } + + @Override + public int hashCode() + { + return 13 * getSymmetricAlgorithm() + 17 * getAeadAlgorithm(); + } + } +} diff --git a/pg/src/main/java/org/bouncycastle/bcpg/sig/PrimaryUserID.java b/pg/src/main/java/org/bouncycastle/bcpg/sig/PrimaryUserID.java index eff6e90d92..53ac5ec829 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/sig/PrimaryUserID.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/sig/PrimaryUserID.java @@ -8,23 +8,7 @@ */ public class PrimaryUserID extends SignatureSubpacket -{ - private static byte[] booleanToByteArray( - boolean value) - { - byte[] data = new byte[1]; - - if (value) - { - data[0] = 1; - return data; - } - else - { - return data; - } - } - +{ public PrimaryUserID( boolean critical, boolean isLongLength, @@ -37,11 +21,11 @@ public PrimaryUserID( boolean critical, boolean isPrimaryUserID) { - super(SignatureSubpacketTags.PRIMARY_USER_ID, critical, false, booleanToByteArray(isPrimaryUserID)); + super(SignatureSubpacketTags.PRIMARY_USER_ID, critical, false, Utils.booleanToByteArray(isPrimaryUserID)); } public boolean isPrimaryUserID() { - return data[0] != 0; + return Utils.booleanFromByteArray(data); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/sig/Revocable.java b/pg/src/main/java/org/bouncycastle/bcpg/sig/Revocable.java index 86f4cef462..8ac92b50f1 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/sig/Revocable.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/sig/Revocable.java @@ -8,23 +8,7 @@ */ public class Revocable extends SignatureSubpacket -{ - private static byte[] booleanToByteArray( - boolean value) - { - byte[] data = new byte[1]; - - if (value) - { - data[0] = 1; - return data; - } - else - { - return data; - } - } - +{ public Revocable( boolean critical, boolean isLongLength, @@ -37,11 +21,11 @@ public Revocable( boolean critical, boolean isRevocable) { - super(SignatureSubpacketTags.REVOCABLE, critical, false, booleanToByteArray(isRevocable)); + super(SignatureSubpacketTags.REVOCABLE, critical, false, Utils.booleanToByteArray(isRevocable)); } public boolean isRevocable() { - return data[0] != 0; + return Utils.booleanFromByteArray(data); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/sig/SignatureCreationTime.java b/pg/src/main/java/org/bouncycastle/bcpg/sig/SignatureCreationTime.java index 220de3cbf6..deeebae46c 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/sig/SignatureCreationTime.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/sig/SignatureCreationTime.java @@ -11,20 +11,16 @@ public class SignatureCreationTime extends SignatureSubpacket { + /** + * @deprecated Will be removed + */ protected static byte[] timeToBytes( Date date) { - byte[] data = new byte[4]; - long t = date.getTime() / 1000; - - data[0] = (byte)(t >> 24); - data[1] = (byte)(t >> 16); - data[2] = (byte)(t >> 8); - data[3] = (byte)t; - - return data; + long t = date.getTime() / 1000; + return Utils.timeToBytes(t); } - + public SignatureCreationTime( boolean critical, boolean isLongLength, @@ -32,18 +28,17 @@ public SignatureCreationTime( { super(SignatureSubpacketTags.CREATION_TIME, critical, isLongLength, data); } - + public SignatureCreationTime( boolean critical, Date date) { super(SignatureSubpacketTags.CREATION_TIME, critical, false, timeToBytes(date)); } - + public Date getTime() { - long time = ((long)(data[0] & 0xff) << 24) | ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff); - + long time = Utils.timeFromBytes(data); return new Date(time * 1000); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/sig/SignatureExpirationTime.java b/pg/src/main/java/org/bouncycastle/bcpg/sig/SignatureExpirationTime.java index 27ebd49009..4065985018 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/sig/SignatureExpirationTime.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/sig/SignatureExpirationTime.java @@ -9,19 +9,15 @@ public class SignatureExpirationTime extends SignatureSubpacket { + /** + * @deprecated Will be removed + */ protected static byte[] timeToBytes( - long t) + long t) { - byte[] data = new byte[4]; - - data[0] = (byte)(t >> 24); - data[1] = (byte)(t >> 16); - data[2] = (byte)(t >> 8); - data[3] = (byte)t; - - return data; + return Utils.timeToBytes(t); } - + public SignatureExpirationTime( boolean critical, boolean isLongLength, @@ -29,21 +25,19 @@ public SignatureExpirationTime( { super(SignatureSubpacketTags.EXPIRE_TIME, critical, isLongLength, data); } - + public SignatureExpirationTime( boolean critical, long seconds) { - super(SignatureSubpacketTags.EXPIRE_TIME, critical, false, timeToBytes(seconds)); + super(SignatureSubpacketTags.EXPIRE_TIME, critical, false, Utils.timeToBytes(seconds)); } - + /** * return time in seconds before signature expires after creation time. */ public long getTime() { - long time = ((long)(data[0] & 0xff) << 24) | ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff); - - return time; + return Utils.timeFromBytes(data); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/sig/Utils.java b/pg/src/main/java/org/bouncycastle/bcpg/sig/Utils.java new file mode 100644 index 0000000000..95cbe0cba8 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/bcpg/sig/Utils.java @@ -0,0 +1,67 @@ +package org.bouncycastle.bcpg.sig; + +import org.bouncycastle.util.Pack; + +class Utils +{ + /** + * Convert the given boolean value into a one-entry byte array, where true is represented by a 1 and false is a 0. + * mentioned in https://github.com/bcgit/bc-java/pull/1575/ + * @param value + * @return byte array + */ + static byte[] booleanToByteArray(boolean value) + { + byte[] data = new byte[1]; + + if (value) + { + data[0] = 1; + } + return data; + } + + /** + * Convert a one-entry byte array into a boolean. + * If the byte array doesn't have one entry, or if this entry is neither a 0 nor 1, this method throws an + * {@link IllegalArgumentException}. + * A 1 is translated into true, a 0 into false. + * + * @param bytes byte array + * @return boolean + */ + static boolean booleanFromByteArray(byte[] bytes) + { + if (bytes.length != 1) + { + throw new IllegalStateException("Byte array has unexpected length. Expected length 1, got " + bytes.length); + } + if (bytes[0] == 0) + { + return false; + } + else if (bytes[0] == 1) + { + return true; + } + else + { + throw new IllegalStateException("Unexpected byte value for boolean encoding: " + bytes[0]); + } + } + + static long timeFromBytes(byte[] bytes) + { + if (bytes.length != 4) + { + throw new IllegalStateException("Byte array has unexpected length. Expected length 4, got " + bytes.length); + } + + return Pack.bigEndianToInt(bytes, 0); + } + + static byte[] timeToBytes(long t) + { + return Pack.intToBigEndian((int)t); + } +} diff --git a/pg/src/main/java/org/bouncycastle/gpg/SExprParser.java b/pg/src/main/java/org/bouncycastle/gpg/SExprParser.java index ff5722be29..6b43f9143a 100644 --- a/pg/src/main/java/org/bouncycastle/gpg/SExprParser.java +++ b/pg/src/main/java/org/bouncycastle/gpg/SExprParser.java @@ -1,19 +1,27 @@ package org.bouncycastle.gpg; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; import org.bouncycastle.asn1.x9.ECNamedCurveTable; +import org.bouncycastle.asn1.x9.X9ECParametersHolder; +import org.bouncycastle.bcpg.BCPGKey; import org.bouncycastle.bcpg.DSAPublicBCPGKey; import org.bouncycastle.bcpg.DSASecretBCPGKey; import org.bouncycastle.bcpg.ECDSAPublicBCPGKey; import org.bouncycastle.bcpg.ECPublicBCPGKey; import org.bouncycastle.bcpg.ECSecretBCPGKey; +import org.bouncycastle.bcpg.EdDSAPublicBCPGKey; +import org.bouncycastle.bcpg.EdSecretBCPGKey; import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; import org.bouncycastle.bcpg.HashAlgorithmTags; @@ -24,15 +32,20 @@ import org.bouncycastle.bcpg.S2K; import org.bouncycastle.bcpg.SecretKeyPacket; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.crypto.ec.CustomNamedCurves; +import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSecretKey; +import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.PGPSecretKeyDecryptorWithAAD; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Strings; /** @@ -52,6 +65,50 @@ public SExprParser(PGPDigestCalculatorProvider digestProvider) this.digestProvider = digestProvider; } + private static final Map rsaLabels = new HashMap() + {{ + put(ProtectionModeTags.OPENPGP_S2K3_OCB_AES, new String[]{"rsa", "n", "e", "protected-at"}); + put(ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC, new String[]{"rsa", "n", "e", "d", "p", "q", "u", "protected-at"}); + }}; + private static final Map eccLabels = new HashMap() + {{ + put(ProtectionModeTags.OPENPGP_S2K3_OCB_AES, new String[]{"ecc", "curve", "flags", "q", "protected-at"}); + put(ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC, new String[]{"ecc", "curve", "q", "d", "protected-at"}); + }}; + + private static final Map dsaLabels = new HashMap() + {{ + put(ProtectionModeTags.OPENPGP_S2K3_OCB_AES, new String[]{"dsa", "p", "q", "g", "y", "protected-at"}); + put(ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC, new String[]{"dsa", "p", "q", "g", "y", "x", "protected-at"}); + }}; + + private static final Map elgLabels = new HashMap() + {{ + //https://github.com/gpg/gnupg/blob/40227e42ea0f2f1cf9c9f506375446648df17e8d/agent/cvt-openpgp.c#L217 + put(ProtectionModeTags.OPENPGP_S2K3_OCB_AES, new String[]{"elg", "p", "q", "g", "y", "protected-at"}); + put(ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC, new String[]{"elg", "p", "q", "g", "y", "x", "protected-at"}); + }}; + + private static final String[] rsaBigIntegers = new String[]{"n", "e"}; + private static final String[] dsaBigIntegers = new String[]{"p", "q", "g", "y"}; + private static final String[] elgBigIntegers = new String[]{"p", "g", "y"}; + + public interface ProtectionFormatTypeTags + { + int PRIVATE_KEY = 1; + int PROTECTED_PRIVATE_KEY = 2; + int SHADOWED_PRIVATE_KEY = 3; + int OPENPGP_PRIVATE_KEY = 4; + int PROTECTED_SHARED_SECRET = 5; + } + + private interface ProtectionModeTags + { + int OPENPGP_S2K3_SHA1_AES_CBC = 1; + int OPENPGP_S2K3_OCB_AES = 2; + int OPENPGP_NATIVE = 3; + } + /** * Parse a secret key from one of the GPG S expression keys associating it with the passed in public key. * @@ -60,644 +117,448 @@ public SExprParser(PGPDigestCalculatorProvider digestProvider) public PGPSecretKey parseSecretKey(InputStream inputStream, PBEProtectionRemoverFactory keyProtectionRemoverFactory, PGPPublicKey pubKey) throws IOException, PGPException { - SXprUtils.skipOpenParenthesis(inputStream); + if (pubKey == null) + { + throw new NullPointerException("Public key cannot be null"); + } + return parse(inputStream, keyProtectionRemoverFactory, null, pubKey); + } - String type; + /** + * Parse a secret key from one of the GPG S expression keys. + * + * @return a secret key object. + */ + public PGPSecretKey parseSecretKey(InputStream inputStream, PBEProtectionRemoverFactory keyProtectionRemoverFactory, + KeyFingerPrintCalculator fingerPrintCalculator) + throws IOException, PGPException + { + return parse(inputStream, keyProtectionRemoverFactory, fingerPrintCalculator, null); + } - type = SXprUtils.readString(inputStream, inputStream.read()); - if (type.equals("protected-private-key") - || type.equals("private-key")) + private PGPSecretKey parse(InputStream inputStream, PBEProtectionRemoverFactory keyProtectionRemoverFactory, + KeyFingerPrintCalculator fingerPrintCalculator, PGPPublicKey pubKey) + throws IOException, PGPException + { + final int maxDepth = 10; + SExpression keyExpression = SExpression.parseCanonical(inputStream, maxDepth); + int type = getProtectionType(keyExpression.getString(0)); + if (type == ProtectionFormatTypeTags.PRIVATE_KEY || type == ProtectionFormatTypeTags.PROTECTED_PRIVATE_KEY || + type == ProtectionFormatTypeTags.SHADOWED_PRIVATE_KEY) { - SXprUtils.skipOpenParenthesis(inputStream); + SExpression expression = keyExpression.getExpression(1); + String keyType = expression.getString(0); + PublicKeyAlgorithmTags[] secretKey = getPGPSecretKey(keyProtectionRemoverFactory, fingerPrintCalculator, + pubKey, maxDepth, type, expression, keyType, digestProvider); + return new PGPSecretKey((SecretKeyPacket)secretKey[0], (PGPPublicKey)secretKey[1]); + } + throw new PGPException("unknown key type found"); + } - String keyType = SXprUtils.readString(inputStream, inputStream.read()); - if (keyType.equals("ecc")) + public static PublicKeyAlgorithmTags[] getPGPSecretKey(PBEProtectionRemoverFactory keyProtectionRemoverFactory, + KeyFingerPrintCalculator fingerPrintCalculator, PGPPublicKey pubKey, + int maxDepth, int type, final SExpression expression, String keyType, + PGPDigestCalculatorProvider digestProvider) + throws PGPException, IOException + { + SecretKeyPacket secretKeyPacket; + if (keyType.equals("ecc")) + { + BCPGKey basePubKey = getECCBasePublicKey(expression); + if (pubKey != null) { - SXprUtils.skipOpenParenthesis(inputStream); - - String curveID = SXprUtils.readString(inputStream, inputStream.read()); - String curveName = SXprUtils.readString(inputStream, inputStream.read()); - - SXprUtils.skipCloseParenthesis(inputStream); - - byte[] qVal; - - SXprUtils.skipOpenParenthesis(inputStream); - - type = SXprUtils.readString(inputStream, inputStream.read()); - if (type.equals("q")) + assertEccPublicKeyMath(basePubKey, pubKey); + } + else + { + PublicKeyPacket pubPacket = null; + if (basePubKey instanceof EdDSAPublicBCPGKey) { - qVal = SXprUtils.readBytes(inputStream, inputStream.read()); + pubPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.EDDSA_LEGACY, new Date(), basePubKey); } - else + else if (basePubKey instanceof ECPublicBCPGKey) { - throw new PGPException("no q value found"); + pubPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.ECDSA, new Date(), basePubKey); } - - SXprUtils.skipCloseParenthesis(inputStream); - - BigInteger d = processECSecretKey(inputStream, curveID, curveName, qVal, keyProtectionRemoverFactory); - - if (curveName.startsWith("NIST ")) + pubKey = new PGPPublicKey(pubPacket, fingerPrintCalculator); + } + secretKeyPacket = getSecKeyPacket(pubKey, keyProtectionRemoverFactory, maxDepth, type, expression, digestProvider, eccLabels, + new GetSecKeyDataOperation() { - curveName = curveName.substring("NIST ".length()); - } - - ECPublicBCPGKey basePubKey = new ECDSAPublicBCPGKey(ECNamedCurveTable.getOID(curveName), new BigInteger(1, qVal)); - ECPublicBCPGKey assocPubKey = (ECPublicBCPGKey)pubKey.getPublicKeyPacket().getKey(); - if (!basePubKey.getCurveOID().equals(assocPubKey.getCurveOID()) - || !basePubKey.getEncodedPoint().equals(assocPubKey.getEncodedPoint())) + @Override + public byte[] getSecKeyData(SExpression keyIn) + { + BigInteger d = BigIntegers.fromUnsignedByteArray(keyIn.getExpressionWithLabelOrFail("d").getBytes(1)); + final String curve = expression.getExpressionWithLabel("curve").getString(1); + if (curve.startsWith("NIST") || curve.startsWith("brain")) + { + return new ECSecretBCPGKey(d).getEncoded(); + } + else + { + return new EdSecretBCPGKey(d).getEncoded(); + } + } + }); + } + else if (keyType.equals("dsa")) + { + pubKey = getPublicKey(fingerPrintCalculator, pubKey, expression, PublicKeyAlgorithmTags.DSA, dsaBigIntegers, new getPublicKeyOperation() + { + public BCPGKey getBasePublicKey(BigInteger[] bigIntegers) { - throw new PGPException("passed in public key does not match secret key"); + return new DSAPublicBCPGKey(bigIntegers[0], bigIntegers[1], bigIntegers[2], bigIntegers[3]); } - return new PGPSecretKey(new SecretKeyPacket(pubKey.getPublicKeyPacket(), SymmetricKeyAlgorithmTags.NULL, null, null, new ECSecretBCPGKey(d).getEncoded()), pubKey); - } - else if (keyType.equals("dsa")) - { - BigInteger p = readBigInteger("p", inputStream); - BigInteger q = readBigInteger("q", inputStream); - BigInteger g = readBigInteger("g", inputStream); - - BigInteger y = readBigInteger("y", inputStream); - - BigInteger x = processDSASecretKey(inputStream, p, q, g, y, keyProtectionRemoverFactory); - - DSAPublicBCPGKey basePubKey = new DSAPublicBCPGKey(p, q, g, y); - DSAPublicBCPGKey assocPubKey = (DSAPublicBCPGKey)pubKey.getPublicKeyPacket().getKey(); - if (!basePubKey.getP().equals(assocPubKey.getP()) - || !basePubKey.getQ().equals(assocPubKey.getQ()) - || !basePubKey.getG().equals(assocPubKey.getG()) - || !basePubKey.getY().equals(assocPubKey.getY())) + public void assertPublicKeyMatch(BCPGKey k1, BCPGKey k2) + throws PGPException { - throw new PGPException("passed in public key does not match secret key"); + DSAPublicBCPGKey key1 = (DSAPublicBCPGKey)k1; + DSAPublicBCPGKey key2 = (DSAPublicBCPGKey)k2; + if (!key1.getP().equals(key2.getP()) || !key1.getQ().equals(key2.getQ()) + || !key1.getG().equals(key2.getG()) || !key1.getY().equals(key2.getY())) + { + throw new PGPException("passed in public key does not match secret key"); + } } - return new PGPSecretKey(new SecretKeyPacket(pubKey.getPublicKeyPacket(), SymmetricKeyAlgorithmTags.NULL, null, null, new DSASecretBCPGKey(x).getEncoded()), pubKey); - } - else if (keyType.equals("elg")) + }); + secretKeyPacket = getSecKeyPacket(pubKey, keyProtectionRemoverFactory, maxDepth, type, expression, digestProvider, dsaLabels, + new GetSecKeyDataOperation() + { + @Override + public byte[] getSecKeyData(SExpression keyIn) + { + BigInteger x = BigIntegers.fromUnsignedByteArray(keyIn.getExpressionWithLabelOrFail("x").getBytes(1)); + + return new DSASecretBCPGKey(x).getEncoded(); + } + }); + } + else if (keyType.equals("elg")) + { + pubKey = getPublicKey(fingerPrintCalculator, pubKey, expression, PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, elgBigIntegers, new getPublicKeyOperation() { - BigInteger p = readBigInteger("p", inputStream); - BigInteger g = readBigInteger("g", inputStream); - - BigInteger y = readBigInteger("y", inputStream); - - BigInteger x = processElGamalSecretKey(inputStream, p, g, y, keyProtectionRemoverFactory); - - ElGamalPublicBCPGKey basePubKey = new ElGamalPublicBCPGKey(p, g, y); - ElGamalPublicBCPGKey assocPubKey = (ElGamalPublicBCPGKey)pubKey.getPublicKeyPacket().getKey(); - if (!basePubKey.getP().equals(assocPubKey.getP()) - || !basePubKey.getG().equals(assocPubKey.getG()) - || !basePubKey.getY().equals(assocPubKey.getY())) + public BCPGKey getBasePublicKey(BigInteger[] bigIntegers) { - throw new PGPException("passed in public key does not match secret key"); + return new ElGamalPublicBCPGKey(bigIntegers[0], bigIntegers[1], bigIntegers[2]); } - return new PGPSecretKey(new SecretKeyPacket(pubKey.getPublicKeyPacket(), SymmetricKeyAlgorithmTags.NULL, null, null, new ElGamalSecretBCPGKey(x).getEncoded()), pubKey); - } - else if (keyType.equals("rsa")) - { - BigInteger n = readBigInteger("n", inputStream); - BigInteger e = readBigInteger("e", inputStream); - - BigInteger[] values = processRSASecretKey(inputStream, n, e, keyProtectionRemoverFactory); - - // TODO: type of RSA key? - RSAPublicBCPGKey basePubKey = new RSAPublicBCPGKey(n, e); - RSAPublicBCPGKey assocPubKey = (RSAPublicBCPGKey)pubKey.getPublicKeyPacket().getKey(); - if (!basePubKey.getModulus().equals(assocPubKey.getModulus()) - || !basePubKey.getPublicExponent().equals(assocPubKey.getPublicExponent())) + public void assertPublicKeyMatch(BCPGKey k1, BCPGKey k2) + throws PGPException { - throw new PGPException("passed in public key does not match secret key"); + ElGamalPublicBCPGKey key1 = (ElGamalPublicBCPGKey)k1; + ElGamalPublicBCPGKey key2 = (ElGamalPublicBCPGKey)k2; + if (!key1.getP().equals(key2.getP()) || !key1.getG().equals(key2.getG()) || !key1.getY().equals(key2.getY())) + { + throw new PGPException("passed in public key does not match secret key"); + } } - - return new PGPSecretKey(new SecretKeyPacket(pubKey.getPublicKeyPacket(), SymmetricKeyAlgorithmTags.NULL, null, null, new RSASecretBCPGKey(values[0], values[1], values[2]).getEncoded()), pubKey); - } - else - { - throw new PGPException("unknown key type: " + keyType); - } + }); + secretKeyPacket = getSecKeyPacket(pubKey, keyProtectionRemoverFactory, maxDepth, type, expression, digestProvider, elgLabels, + new GetSecKeyDataOperation() + { + @Override + public byte[] getSecKeyData(SExpression keyIn) + { + BigInteger x = BigIntegers.fromUnsignedByteArray(keyIn.getExpressionWithLabelOrFail("x").getBytes(1)); + + return new ElGamalSecretBCPGKey(x).getEncoded(); + } + }); } - - throw new PGPException("unknown key type found"); - } - - /** - * Parse a secret key from one of the GPG S expression keys. - * - * @return a secret key object. - */ - public PGPSecretKey parseSecretKey(InputStream inputStream, PBEProtectionRemoverFactory keyProtectionRemoverFactory, KeyFingerPrintCalculator fingerPrintCalculator) - throws IOException, PGPException - { - SXprUtils.skipOpenParenthesis(inputStream); - - String type; - - type = SXprUtils.readString(inputStream, inputStream.read()); - if (type.equals("protected-private-key") - || type.equals("private-key")) + else if (keyType.equals("rsa")) { - SXprUtils.skipOpenParenthesis(inputStream); - - String keyType = SXprUtils.readString(inputStream, inputStream.read()); - if (keyType.equals("ecc")) + // TODO: type of RSA key? + pubKey = getPublicKey(fingerPrintCalculator, pubKey, expression, PublicKeyAlgorithmTags.RSA_GENERAL, rsaBigIntegers, new getPublicKeyOperation() { - SXprUtils.skipOpenParenthesis(inputStream); - - String curveID = SXprUtils.readString(inputStream, inputStream.read()); - String curveName = SXprUtils.readString(inputStream, inputStream.read()); - - if (curveName.startsWith("NIST ")) + public BCPGKey getBasePublicKey(BigInteger[] bigIntegers) { - curveName = curveName.substring("NIST ".length()); + return new RSAPublicBCPGKey(bigIntegers[0], bigIntegers[1]); } - SXprUtils.skipCloseParenthesis(inputStream); - - byte[] qVal; - - SXprUtils.skipOpenParenthesis(inputStream); - - type = SXprUtils.readString(inputStream, inputStream.read()); - if (type.equals("q")) + public void assertPublicKeyMatch(BCPGKey k1, BCPGKey k2) + throws PGPException { - qVal = SXprUtils.readBytes(inputStream, inputStream.read()); + RSAPublicBCPGKey key1 = (RSAPublicBCPGKey)k1; + RSAPublicBCPGKey key2 = (RSAPublicBCPGKey)k2; + if (!key1.getModulus().equals(key2.getModulus()) + || !key1.getPublicExponent().equals(key2.getPublicExponent())) + { + throw new PGPException("passed in public key does not match secret key"); + } } - else + }); + secretKeyPacket = getSecKeyPacket(pubKey, keyProtectionRemoverFactory, maxDepth, type, expression, digestProvider, rsaLabels, + new GetSecKeyDataOperation() { - throw new PGPException("no q value found"); - } - - PublicKeyPacket pubPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.ECDSA, new Date(), new ECDSAPublicBCPGKey(ECNamedCurveTable.getOID(curveName), new BigInteger(1, qVal))); - - SXprUtils.skipCloseParenthesis(inputStream); - - BigInteger d = processECSecretKey(inputStream, curveID, curveName, qVal, keyProtectionRemoverFactory); - - return new PGPSecretKey(new SecretKeyPacket(pubPacket, SymmetricKeyAlgorithmTags.NULL, null, null, new ECSecretBCPGKey(d).getEncoded()), new PGPPublicKey(pubPacket, fingerPrintCalculator)); - } - else if (keyType.equals("dsa")) - { - BigInteger p = readBigInteger("p", inputStream); - BigInteger q = readBigInteger("q", inputStream); - BigInteger g = readBigInteger("g", inputStream); - - BigInteger y = readBigInteger("y", inputStream); - - BigInteger x = processDSASecretKey(inputStream, p, q, g, y, keyProtectionRemoverFactory); - - PublicKeyPacket pubPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.DSA, new Date(), new DSAPublicBCPGKey(p, q, g, y)); - - return new PGPSecretKey(new SecretKeyPacket(pubPacket, SymmetricKeyAlgorithmTags.NULL, null, null, new DSASecretBCPGKey(x).getEncoded()), new PGPPublicKey(pubPacket, fingerPrintCalculator)); - } - else if (keyType.equals("elg")) - { - BigInteger p = readBigInteger("p", inputStream); - BigInteger g = readBigInteger("g", inputStream); - - BigInteger y = readBigInteger("y", inputStream); - - BigInteger x = processElGamalSecretKey(inputStream, p, g, y, keyProtectionRemoverFactory); - - PublicKeyPacket pubPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, new Date(), new ElGamalPublicBCPGKey(p, g, y)); - - return new PGPSecretKey(new SecretKeyPacket(pubPacket, SymmetricKeyAlgorithmTags.NULL, null, null, new ElGamalSecretBCPGKey(x).getEncoded()), new PGPPublicKey(pubPacket, fingerPrintCalculator)); - } - else if (keyType.equals("rsa")) - { - BigInteger n = readBigInteger("n", inputStream); - BigInteger e = readBigInteger("e", inputStream); - - BigInteger[] values = processRSASecretKey(inputStream, n, e, keyProtectionRemoverFactory); - - // TODO: type of RSA key? - PublicKeyPacket pubPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.RSA_GENERAL, new Date(), new RSAPublicBCPGKey(n, e)); - - return new PGPSecretKey(new SecretKeyPacket(pubPacket, SymmetricKeyAlgorithmTags.NULL, null, null, new RSASecretBCPGKey(values[0], values[1], values[2]).getEncoded()), new PGPPublicKey(pubPacket, fingerPrintCalculator)); - } - else - { - throw new PGPException("unknown key type: " + keyType); - } + @Override + public byte[] getSecKeyData(SExpression keyIn) + { + BigInteger d = BigIntegers.fromUnsignedByteArray(keyIn.getExpressionWithLabelOrFail("d").getBytes(1)); + BigInteger p = BigIntegers.fromUnsignedByteArray(keyIn.getExpressionWithLabelOrFail("p").getBytes(1)); + BigInteger q = BigIntegers.fromUnsignedByteArray(keyIn.getExpressionWithLabelOrFail("q").getBytes(1)); + return new RSASecretBCPGKey(d, p, q).getEncoded(); + } + }); } - - throw new PGPException("unknown key type found"); - } - - private BigInteger readBigInteger(String expectedType, InputStream inputStream) - throws IOException, PGPException - { - SXprUtils.skipOpenParenthesis(inputStream); - - String type = SXprUtils.readString(inputStream, inputStream.read()); - if (!type.equals(expectedType)) + else { - throw new PGPException(expectedType + " value expected"); + throw new PGPException("unknown key type: " + keyType); } - - byte[] nBytes = SXprUtils.readBytes(inputStream, inputStream.read()); - BigInteger v = new BigInteger(1, nBytes); - - SXprUtils.skipCloseParenthesis(inputStream); - - return v; + return new PublicKeyAlgorithmTags[]{secretKeyPacket, pubKey}; } - private static byte[][] extractData(InputStream inputStream, PBEProtectionRemoverFactory keyProtectionRemoverFactory) - throws PGPException, IOException + private interface getPublicKeyOperation { - byte[] data; - byte[] protectedAt = null; + BCPGKey getBasePublicKey(BigInteger[] bigIntegers); - SXprUtils.skipOpenParenthesis(inputStream); + void assertPublicKeyMatch(BCPGKey key1, BCPGKey key2) + throws PGPException; + } - String type = SXprUtils.readString(inputStream, inputStream.read()); - if (type.equals("protected")) + private static PGPPublicKey getPublicKey(KeyFingerPrintCalculator fingerPrintCalculator, PGPPublicKey pubKey, SExpression expression, + int publicKeyAlgorithmTags, String[] bigIntegerLabels, getPublicKeyOperation operation) + throws PGPException + { + int flag = 0, flag_break = (1 << bigIntegerLabels.length) - 1; + BigInteger[] bigIntegers = new BigInteger[bigIntegerLabels.length]; + for (Object item : expression.getValues()) { - String protection = SXprUtils.readString(inputStream, inputStream.read()); - - SXprUtils.skipOpenParenthesis(inputStream); - - S2K s2k = SXprUtils.parseS2K(inputStream); - - byte[] iv = SXprUtils.readBytes(inputStream, inputStream.read()); - - SXprUtils.skipCloseParenthesis(inputStream); - - byte[] secKeyData = SXprUtils.readBytes(inputStream, inputStream.read()); - - SXprUtils.skipCloseParenthesis(inputStream); - - PBESecretKeyDecryptor keyDecryptor = keyProtectionRemoverFactory.createDecryptor(protection); - - // TODO: recognise other algorithms - byte[] key = keyDecryptor.makeKeyFromPassPhrase(SymmetricKeyAlgorithmTags.AES_128, s2k); - - data = keyDecryptor.recoverKeyData(SymmetricKeyAlgorithmTags.AES_128, key, iv, secKeyData, 0, secKeyData.length); - - // check if protected at is present - if (inputStream.read() == '(') + if (item instanceof SExpression) { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - bOut.write('('); - int ch; - while ((ch = inputStream.read()) >= 0 && ch != ')') - { - bOut.write(ch); - } - - if (ch != ')') + SExpression exp = (SExpression)item; + String str = exp.getString(0); + for (int i = 0; i < bigIntegerLabels.length; ++i) { - throw new IOException("unexpected end to SExpr"); + if ((flag & (1 << i)) == 0 && str.equals(bigIntegerLabels[i])) + { + bigIntegers[i] = BigIntegers.fromUnsignedByteArray(exp.getBytes(1)); + flag |= 1 << i; + if (flag == flag_break) + { + break; + } + } } - - bOut.write(')'); - - protectedAt = bOut.toByteArray(); } - - SXprUtils.skipCloseParenthesis(inputStream); - SXprUtils.skipCloseParenthesis(inputStream); } - else if (type.equals("d")) + if (flag != flag_break) { - return null; + throw new IllegalArgumentException("The public key should not be null"); + } + BCPGKey basePubKey = operation.getBasePublicKey(bigIntegers); + if (pubKey != null) + { + operation.assertPublicKeyMatch(basePubKey, pubKey.getPublicKeyPacket().getKey()); } else { - throw new PGPException("protected block not found"); + pubKey = new PGPPublicKey(new PublicKeyPacket(publicKeyAlgorithmTags, new Date(), basePubKey), fingerPrintCalculator); } - - return new byte[][]{data, protectedAt}; + return pubKey; } - private BigInteger processDSASecretKey(InputStream inputStream, BigInteger p, BigInteger q, BigInteger g, BigInteger y, - PBEProtectionRemoverFactory keyProtectionRemoverFactory) - throws IOException, PGPException + private interface GetSecKeyDataOperation { - String type; - byte[][] basicData = extractData(inputStream, keyProtectionRemoverFactory); - - byte[] keyData = basicData[0]; - byte[] protectedAt = basicData[1]; - - // - // parse the secret key S-expr - // - InputStream keyIn = new ByteArrayInputStream(keyData); - - SXprUtils.skipOpenParenthesis(keyIn); - SXprUtils.skipOpenParenthesis(keyIn); - - BigInteger x = readBigInteger("x", keyIn); - - SXprUtils.skipCloseParenthesis(keyIn); - - SXprUtils.skipOpenParenthesis(keyIn); - type = SXprUtils.readString(keyIn, keyIn.read()); - - if (!type.equals("hash")) - { - throw new PGPException("hash keyword expected"); - } - type = SXprUtils.readString(keyIn, keyIn.read()); - - if (!type.equals("sha1")) - { - throw new PGPException("hash keyword expected"); - } - - byte[] hashBytes = SXprUtils.readBytes(keyIn, keyIn.read()); - - SXprUtils.skipCloseParenthesis(keyIn); + byte[] getSecKeyData(SExpression keyIn); + } - if (digestProvider != null) + private static SecretKeyPacket getSecKeyPacket(PGPPublicKey pubKey, PBEProtectionRemoverFactory keyProtectionRemoverFactory, int maxDepth, int type, + SExpression expression, PGPDigestCalculatorProvider digestProvider, + Map labels, GetSecKeyDataOperation operation) + throws PGPException, IOException + { + byte[] secKeyData = null; + S2K s2K = null; + byte[] nonce = null; + SExpression keyIn; + if (type != ProtectionFormatTypeTags.SHADOWED_PRIVATE_KEY) { - PGPDigestCalculator digestCalculator = digestProvider.get(HashAlgorithmTags.SHA1); - - OutputStream dOut = digestCalculator.getOutputStream(); - - dOut.write(Strings.toByteArray("(3:dsa")); - writeCanonical(dOut, "p", p); - writeCanonical(dOut, "q", q); - writeCanonical(dOut, "g", g); - writeCanonical(dOut, "y", y); - writeCanonical(dOut, "x", x); - - // check protected-at - if (protectedAt != null) + if (type == ProtectionFormatTypeTags.PROTECTED_PRIVATE_KEY) { - dOut.write(protectedAt); + SExpression protectedKey = expression.getExpressionWithLabel("protected"); + if (protectedKey == null) + { + throw new IllegalArgumentException(type + " does not have protected block"); + } + String protectionStr = protectedKey.getString(1); + int protection = getProtectionMode(protectionStr); + if (protection == ProtectionModeTags.OPENPGP_S2K3_OCB_AES || protection == ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC) + { + byte[] data; + SExpression protectionKeyParameters = protectedKey.getExpression(2); + SExpression s2kParams = protectionKeyParameters.getExpression(0); + // TODO select correct hash + s2K = new S2K(PGPUtil.getDigestIDForName(s2kParams.getString(0)), s2kParams.getBytes(1), s2kParams.getInt(2)); + nonce = protectionKeyParameters.getBytes(1); + PBESecretKeyDecryptor keyDecryptor = keyProtectionRemoverFactory.createDecryptor(protectionStr); + byte[] key = keyDecryptor.makeKeyFromPassPhrase(SymmetricKeyAlgorithmTags.AES_128, s2K); + byte[] keyData = protectedKey.getBytes(3); + if (protection == ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC) + { + data = keyDecryptor.recoverKeyData(SymmetricKeyAlgorithmTags.AES_128, key, nonce, keyData, 0, keyData.length); + keyIn = SExpression.parseCanonical(new ByteArrayInputStream(data), maxDepth); + if (digestProvider != null) + { + PGPDigestCalculator digestCalculator = digestProvider.get(HashAlgorithmTags.SHA1); + OutputStream dOut = digestCalculator.getOutputStream(); + byte[] aad = SExpression.buildExpression(expression, keyIn.getExpression(0), labels.get(protection)).toCanonicalForm(); + dOut.write(aad); + byte[] check = digestCalculator.getDigest(); + byte[] hashBytes = keyIn.getExpression(1).getBytes(2); + if (!Arrays.constantTimeAreEqual(check, hashBytes)) + { + throw new PGPException("checksum on protected data failed in SExpr"); + } + } + keyIn = keyIn.getExpression(0); + } + else //ProtectionModeTags.OPENPGP_S2K3_OCB_AES + { + String[] filter = labels.get(protection); + if (filter == null) + { + // TODO could not get client to generate protected elgamal keys + throw new IllegalStateException("no decryption support for protected elgamal keys"); + } + byte[] aad = SExpression.buildExpression(expression, filter).toCanonicalForm(); + data = ((PGPSecretKeyDecryptorWithAAD)keyDecryptor).recoverKeyData(SymmetricKeyAlgorithmTags.AES_128, key, + nonce, aad, keyData, 0, keyData.length); + keyIn = SExpression.parseCanonical(new ByteArrayInputStream(data), maxDepth).getExpression(0); + } + } + else + { + // openpgp-native is not supported for now + throw new PGPException("unsupported protection type " + protectedKey.getString(1)); + } } - - dOut.write(Strings.toByteArray(")")); - - byte[] check = digestCalculator.getDigest(); - if (!Arrays.constantTimeAreEqual(check, hashBytes)) + else { - throw new PGPException("checksum on protected data failed in SExpr"); + keyIn = expression; } + secKeyData = operation.getSecKeyData(keyIn); } - - return x; + return new SecretKeyPacket(pubKey.getPublicKeyPacket(), SymmetricKeyAlgorithmTags.NULL, s2K, nonce, secKeyData); } - private BigInteger processElGamalSecretKey(InputStream inputStream, BigInteger p, BigInteger g, BigInteger y, - PBEProtectionRemoverFactory keyProtectionRemoverFactory) - throws IOException, PGPException + private static BCPGKey getECCBasePublicKey(SExpression expression) { - String type; - byte[][] basicData = extractData(inputStream, keyProtectionRemoverFactory); - - byte[] keyData = basicData[0]; - byte[] protectedAt = basicData[1]; - - // - // parse the secret key S-expr - // - InputStream keyIn = new ByteArrayInputStream(keyData); - - SXprUtils.skipOpenParenthesis(keyIn); - SXprUtils.skipOpenParenthesis(keyIn); - - BigInteger x = readBigInteger("x", keyIn); - - SXprUtils.skipCloseParenthesis(keyIn); - - SXprUtils.skipOpenParenthesis(keyIn); - type = SXprUtils.readString(keyIn, keyIn.read()); - - if (!type.equals("hash")) + byte[] qoint = null; + String curve = null; + int flag = 0; + for (Object item : expression.getValues()) { - throw new PGPException("hash keyword expected"); + if (item instanceof SExpression) + { + SExpression exp = (SExpression)item; + String label = exp.getString(0); + if (label.equals("curve")) + { + curve = exp.getString(1); + flag |= 1; + } + else if (label.equals("q")) + { + qoint = exp.getBytes(1); + flag |= 2; + } + if (flag == 3) + { + break; + } + } } - type = SXprUtils.readString(keyIn, keyIn.read()); - - if (!type.equals("sha1")) + if (flag != 3) { - throw new PGPException("hash keyword expected"); + throw new IllegalArgumentException("no curve expression"); } - - byte[] hashBytes = SXprUtils.readBytes(keyIn, keyIn.read()); - - SXprUtils.skipCloseParenthesis(keyIn); - - if (digestProvider != null) + else if (curve.startsWith("NIST")) { - PGPDigestCalculator digestCalculator = digestProvider.get(HashAlgorithmTags.SHA1); - - OutputStream dOut = digestCalculator.getOutputStream(); - - dOut.write(Strings.toByteArray("(3:elg")); - writeCanonical(dOut, "p", p); - writeCanonical(dOut, "g", g); - writeCanonical(dOut, "y", y); - writeCanonical(dOut, "x", x); - - // check protected-at - if (protectedAt != null) - { - dOut.write(protectedAt); - } - - dOut.write(Strings.toByteArray(")")); - - byte[] check = digestCalculator.getDigest(); - if (!Arrays.constantTimeAreEqual(check, hashBytes)) - { - throw new PGPException("checksum on protected data failed in SExpr"); - } + curve = curve.substring("NIST".length()).trim(); } - - return x; - } - - private BigInteger processECSecretKey(InputStream inputStream, String curveID, String curveName, byte[] qVal, - PBEProtectionRemoverFactory keyProtectionRemoverFactory) - throws IOException, PGPException - { - String type; - - byte[][] basicData = extractData(inputStream, keyProtectionRemoverFactory); - - byte[] keyData = basicData[0]; - byte[] protectedAt = basicData[1]; - - // - // parse the secret key S-expr - // - InputStream keyIn = new ByteArrayInputStream(keyData); - - SXprUtils.skipOpenParenthesis(keyIn); - SXprUtils.skipOpenParenthesis(keyIn); - BigInteger d = readBigInteger("d", keyIn); - SXprUtils.skipCloseParenthesis(keyIn); - - SXprUtils.skipOpenParenthesis(keyIn); - - type = SXprUtils.readString(keyIn, keyIn.read()); - - if (!type.equals("hash")) + String curve_lowercase = Strings.toLowerCase(curve); + if (curve_lowercase.equals("ed25519")) { - throw new PGPException("hash keyword expected"); + return new EdDSAPublicBCPGKey(EdECObjectIdentifiers.id_Ed25519, new BigInteger(1, qoint)); } - type = SXprUtils.readString(keyIn, keyIn.read()); - - if (!type.equals("sha1")) + else if (curve_lowercase.equals("ed448")) { - throw new PGPException("hash keyword expected"); + return new EdDSAPublicBCPGKey(EdECObjectIdentifiers.id_Ed448, new BigInteger(1, qoint)); } - - byte[] hashBytes = SXprUtils.readBytes(keyIn, keyIn.read()); - - SXprUtils.skipCloseParenthesis(keyIn); - - if (digestProvider != null) + else { - PGPDigestCalculator digestCalculator = digestProvider.get(HashAlgorithmTags.SHA1); - - OutputStream dOut = digestCalculator.getOutputStream(); - - dOut.write(Strings.toByteArray("(3:ecc")); - - dOut.write(Strings.toByteArray("(" + curveID.length() + ":" + curveID + curveName.length() + ":" + curveName + ")")); - - writeCanonical(dOut, "q", qVal); - writeCanonical(dOut, "d", d); - - // check protected-at - if (protectedAt != null) + ASN1ObjectIdentifier oid = ECNamedCurveTable.getOID(curve); + X9ECParametersHolder holder = CustomNamedCurves.getByNameLazy(curve); + if (holder == null && oid != null) { - dOut.write(protectedAt); + holder = TeleTrusTNamedCurves.getByOIDLazy(oid); } - - dOut.write(Strings.toByteArray(")")); - - byte[] check = digestCalculator.getDigest(); - - if (!Arrays.constantTimeAreEqual(check, hashBytes)) + if (holder == null) { - throw new PGPException("checksum on protected data failed in SExpr"); + throw new IllegalStateException("unable to resolve parameters for " + curve); } + ECPoint pnt = holder.getCurve().decodePoint(qoint); + return new ECDSAPublicBCPGKey(oid, pnt); } - - return d; } - private BigInteger[] processRSASecretKey(InputStream inputStream, BigInteger n, BigInteger e, - PBEProtectionRemoverFactory keyProtectionRemoverFactory) - throws IOException, PGPException + private static void assertEccPublicKeyMath(BCPGKey key1, PGPPublicKey key2) + throws PGPException { - String type; - byte[][] basicData = extractData(inputStream, keyProtectionRemoverFactory); - - byte[] keyData; - byte[] protectedAt = null; - - InputStream keyIn; - BigInteger d; - - if (basicData == null) + if (key1 instanceof ECDSAPublicBCPGKey) { - keyIn = inputStream; - byte[] nBytes = SXprUtils.readBytes(inputStream, - inputStream.read()); - d = new BigInteger(1, nBytes); - - SXprUtils.skipCloseParenthesis(inputStream); - + ECPublicBCPGKey assocPubKey = (ECPublicBCPGKey)key2.getPublicKeyPacket().getKey(); + if (!((ECDSAPublicBCPGKey)key1).getCurveOID().equals(assocPubKey.getCurveOID()) + || !((ECDSAPublicBCPGKey)key1).getEncodedPoint().equals(assocPubKey.getEncodedPoint())) + { + throw new PGPException("passed in public key does not match secret key"); + } } - else + else if (key1 instanceof EdDSAPublicBCPGKey) { - keyData = basicData[0]; - protectedAt = basicData[1]; - - keyIn = new ByteArrayInputStream(keyData); - - SXprUtils.skipOpenParenthesis(keyIn); - SXprUtils.skipOpenParenthesis(keyIn); - d = readBigInteger("d", keyIn); + EdDSAPublicBCPGKey assocPubKey = (EdDSAPublicBCPGKey)key2.getPublicKeyPacket().getKey(); + if (!((EdDSAPublicBCPGKey)key1).getCurveOID().equals(assocPubKey.getCurveOID()) + || !((EdDSAPublicBCPGKey)key1).getEncodedPoint().equals(assocPubKey.getEncodedPoint())) + { + throw new PGPException("passed in public key does not match secret key"); + } } - - // - // parse the secret key S-expr - // - - BigInteger p = readBigInteger("p", keyIn); - BigInteger q = readBigInteger("q", keyIn); - BigInteger u = readBigInteger("u", keyIn); - - if (basicData == null) + else { - return new BigInteger[] { d, p, q, u }; + throw new PGPException("unknown key type: " + (key1 != null ? key1.getClass().getName() : "null")); } + } - SXprUtils.skipCloseParenthesis(keyIn); - - SXprUtils.skipOpenParenthesis(keyIn); - type = SXprUtils.readString(keyIn, keyIn.read()); - - if (!type.equals("hash")) + public static int getProtectionType(String str) + { + if (str.equals("private-key")) { - throw new PGPException("hash keyword expected"); + return ProtectionFormatTypeTags.PRIVATE_KEY; } - type = SXprUtils.readString(keyIn, keyIn.read()); - - if (!type.equals("sha1")) + else if (str.equals("protected-private-key")) { - throw new PGPException("hash keyword expected"); + return ProtectionFormatTypeTags.PROTECTED_PRIVATE_KEY; } - - byte[] hashBytes = SXprUtils.readBytes(keyIn, keyIn.read()); - - SXprUtils.skipCloseParenthesis(keyIn); - - if (digestProvider != null) + else if (str.equals("shadowed-private-key")) { - PGPDigestCalculator digestCalculator = digestProvider.get(HashAlgorithmTags.SHA1); - - OutputStream dOut = digestCalculator.getOutputStream(); - - dOut.write(Strings.toByteArray("(3:rsa")); - - writeCanonical(dOut, "n", n); - writeCanonical(dOut, "e", e); - writeCanonical(dOut, "d", d); - writeCanonical(dOut, "p", p); - writeCanonical(dOut, "q", q); - writeCanonical(dOut, "u", u); - - // check protected-at - if (protectedAt != null) - { - dOut.write(protectedAt); - } - - dOut.write(Strings.toByteArray(")")); - - byte[] check = digestCalculator.getDigest(); - - if (!Arrays.constantTimeAreEqual(check, hashBytes)) - { - throw new PGPException("checksum on protected data failed in SExpr"); - } + return ProtectionFormatTypeTags.SHADOWED_PRIVATE_KEY; } - - return new BigInteger[]{d, p, q, u}; - } - - private void writeCanonical(OutputStream dOut, String label, BigInteger i) - throws IOException - { - writeCanonical(dOut, label, i.toByteArray()); + // The other two types are not supported for now + return -1; } - private void writeCanonical(OutputStream dOut, String label, byte[] data) - throws IOException + private static int getProtectionMode(String str) { - dOut.write(Strings.toByteArray("(" + label.length() + ":" + label + data.length + ":")); - dOut.write(data); - dOut.write(Strings.toByteArray(")")); + if (str.equals("openpgp-s2k3-sha1-aes-cbc")) + { + return ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC; + } + else if (str.equals("openpgp-s2k3-ocb-aes")) + { + return ProtectionModeTags.OPENPGP_S2K3_OCB_AES; + } + // The other mode is not supported for now + return -1; } -} +} \ No newline at end of file diff --git a/pg/src/main/java/org/bouncycastle/gpg/SExpression.java b/pg/src/main/java/org/bouncycastle/gpg/SExpression.java index 0b1d0c387c..ee5083ad5e 100644 --- a/pg/src/main/java/org/bouncycastle/gpg/SExpression.java +++ b/pg/src/main/java/org/bouncycastle/gpg/SExpression.java @@ -32,9 +32,20 @@ public class SExpression add(Characters.valueOf('\"')); add(Characters.valueOf(':')); }}; + + private static final Set stringLabels = new HashSet() + { + { + add("protected"); + add("protected-at"); + add("curve"); + } + }; private final ArrayList values = new ArrayList(); private boolean canonical = false; + private boolean parseCanonical = false; + public SExpression(List values) { this.values.addAll(values); @@ -63,23 +74,18 @@ public static SExpression parse(byte[] src, int maxDepth) public static SExpression parse(InputStream _src, int maxDepth) throws IOException { - SExpression expr = null; - return parseExpression(_src, expr, new ByteArrayOutputStream(), maxDepth); + return parseExpression(_src, null, new ByteArrayOutputStream(), maxDepth); } private static SExpression parseExpression(InputStream src, SExpression expr, ByteArrayOutputStream accumulator, int maxDepth) throws IOException { - String key = null; if (accumulator == null) { accumulator = new ByteArrayOutputStream(); } - - try { - // // While we are using the callstack we want to artificially limit depth so // a malformed message cannot cause a denial service via the callstack. @@ -90,7 +96,7 @@ private static SExpression parseExpression(InputStream src, SExpression expr, By throw new IllegalStateException("S-Expression exceeded maximum depth"); } - int c = 0; + int c; for (; ; ) { // eg (d\n #ABAB#) @@ -98,11 +104,41 @@ private static SExpression parseExpression(InputStream src, SExpression expr, By if (c == ':') { - int len = Integer.parseInt(Strings.fromByteArray(accumulator.toByteArray())); - byte[] b = new byte[len]; - Streams.readFully(src, b); - expr.addValue(b); - expr.setCanonical(true); + try + { + int len = Integer.parseInt(Strings.fromByteArray(accumulator.toByteArray())); + byte[] b = new byte[len]; + Streams.readFully(src, b); + if (expr.parseCanonical) + { + int size = expr.values.size(); + if (size > 0) + { + Object object = expr.values.get(size - 1); + if (object instanceof String && stringLabels.contains(object)) + { + expr.addValue(Strings.fromUTF8ByteArray(b)); + } + else + { + expr.addValue(b); + } + } + else + { + expr.addValue(Strings.fromUTF8ByteArray(b)); + } + } + else + { + expr.addValue(b); + expr.setCanonical(true); + } + } + catch (NumberFormatException e) + { + expr.addValue(accumulator.toByteArray()); + } continue; } @@ -115,20 +151,21 @@ private static SExpression parseExpression(InputStream src, SExpression expr, By { if (expr == null) { - expr = new SExpression(); parseExpression(src, expr, accumulator, maxDepth); return expr; } else { - expr.addValue(parseExpression(src, new SExpression(), accumulator, maxDepth)); + SExpression subExpression = new SExpression(); + subExpression.parseCanonical = expr.parseCanonical; + expr.addValue(parseExpression(src, subExpression, accumulator, maxDepth)); } } else if (c == '#') { consumeUntilSkipWhiteSpace(src, accumulator, '#'); - expr.addValue(Hex.decode(Strings.fromByteArray(accumulator.toByteArray()))); + expr.addValue(Hex.decode(accumulator.toByteArray())); } else if (c == '"') { @@ -154,21 +191,29 @@ else if (c == -1) } - private static void consumeUntil(InputStream src, ByteArrayOutputStream accumulator, char item) + static SExpression parseCanonical(InputStream _src, int maxDepth) throws IOException { - accumulator.reset(); - int c; - while ((c = src.read()) > -1) - { - if (c == item) - { - return; - } - accumulator.write(c); - } + SExpression expr = new SExpression(); + expr.parseCanonical = true; + return parseExpression(_src, expr, new ByteArrayOutputStream(), maxDepth).getExpression(0); } +// private static void consumeUntil(InputStream src, ByteArrayOutputStream accumulator, char item) +// throws IOException +// { +// accumulator.reset(); +// int c; +// while ((c = src.read()) > -1) +// { +// if (c == item) +// { +// return; +// } +// accumulator.write(c); +// } +// } + private static void consumeUntilSkipWhiteSpace(InputStream src, ByteArrayOutputStream accumulator, char item) throws IOException { @@ -306,7 +351,7 @@ public PGPExtendedKeyAttribute toAttribute() { PGPExtendedKeyAttribute.Builder builder = PGPExtendedKeyAttribute.builder(); - for (Iterator it = values.iterator(); it.hasNext();) + for (Iterator it = values.iterator(); it.hasNext(); ) { builder.addAttribute(it.next()); } @@ -320,7 +365,7 @@ public SExpression filterOut(String... keys) set.addAll(Arrays.asList(keys)); SExpression expr = new SExpression(); - for (Iterator it = values.iterator(); it.hasNext();) + for (Iterator it = values.iterator(); it.hasNext(); ) { Object item = it.next(); if (set.contains(item.toString())) @@ -348,6 +393,47 @@ public SExpression filterOut(String... keys) return expr; } + /** + * This function expects the labels is in order + */ + static SExpression buildExpression(SExpression expression, String[] labels) + { + SExpression rlt = new SExpression(); + rlt.addValue(labels[0]); + for (int i = 1; i < labels.length; ++i) + { + SExpression item = expression.getExpressionWithLabel(labels[i]); + if (item != null) + { + rlt.values.add(item); + } + } + return rlt; + } + + static SExpression buildExpression(SExpression expr1, SExpression expr2, String[] labels) + { + SExpression rlt = new SExpression(); + rlt.addValue(labels[0]); + for (int i = 1; i < labels.length; ++i) + { + SExpression item = expr1.getExpressionWithLabel(labels[i]); + if (item != null) + { + rlt.values.add(item); + } + else + { + item = expr2.getExpressionWithLabel(labels[i]); + if (item != null) + { + rlt.values.add(item); + } + } + } + return rlt; + } + public SExpression filterIn(String... keys) { @@ -355,7 +441,7 @@ public SExpression filterIn(String... keys) set.addAll(Arrays.asList(keys)); SExpression expr = new SExpression(); - for (Iterator it = values.iterator(); it.hasNext();) + for (Iterator it = values.iterator(); it.hasNext(); ) { Object item = it.next(); if (item instanceof SExpression) @@ -403,8 +489,7 @@ public void toCanonicalForm(OutputStream out) throws IOException { out.write('('); - boolean space = false; - for (Iterator it = values.iterator(); it.hasNext();) + for (Iterator it = values.iterator(); it.hasNext(); ) { Object value = it.next(); if (value instanceof QuotedString) @@ -461,7 +546,7 @@ public boolean hasLabel(String label) public SExpression getExpressionWithLabel(String label) { - for (Iterator it = values.iterator(); it.hasNext();) + for (Iterator it = values.iterator(); it.hasNext(); ) { Object o = it.next(); if (o instanceof SExpression) @@ -477,7 +562,7 @@ public SExpression getExpressionWithLabel(String label) public SExpression getExpressionWithLabelOrFail(String label) { - for (Iterator it = values.iterator(); it.hasNext();) + for (Iterator it = values.iterator(); it.hasNext(); ) { Object o = it.next(); if (o instanceof SExpression) @@ -523,7 +608,7 @@ public SExpression build() public Builder addContent(SExpression other) { - for (Iterator it = other.values.iterator(); it.hasNext();) + for (Iterator it = other.values.iterator(); it.hasNext(); ) { values.add(it.next()); } @@ -532,6 +617,4 @@ public Builder addContent(SExpression other) } } - - } diff --git a/pg/src/main/java/org/bouncycastle/gpg/keybox/KeyBoxByteBuffer.java b/pg/src/main/java/org/bouncycastle/gpg/keybox/KeyBoxByteBuffer.java index 6cd99d9fe7..e5526dc226 100644 --- a/pg/src/main/java/org/bouncycastle/gpg/keybox/KeyBoxByteBuffer.java +++ b/pg/src/main/java/org/bouncycastle/gpg/keybox/KeyBoxByteBuffer.java @@ -81,10 +81,10 @@ public byte[] rangeOf(int start, int end) } int p = buffer.position(); - buffer.position(start); + ((java.nio.Buffer)buffer).position(start); byte[] data = new byte[end - start]; buffer.get(data); - buffer.position(p); + ((java.nio.Buffer)buffer).position(p); return data; } @@ -105,7 +105,7 @@ public int position() public void position(int p) { - buffer.position(p); + ((java.nio.Buffer)buffer).position(p); } public int u16() diff --git a/pg/src/main/java/org/bouncycastle/openpgp/AEADUtil.java b/pg/src/main/java/org/bouncycastle/openpgp/AEADUtil.java new file mode 100644 index 0000000000..2aea553a24 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/openpgp/AEADUtil.java @@ -0,0 +1,37 @@ +package org.bouncycastle.openpgp; + +import org.bouncycastle.bcpg.AEADUtils; +import org.bouncycastle.bcpg.SymmetricKeyUtils; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.params.HKDFParameters; + +class AEADUtil +{ + /** + * Derive a message key and IV from the given session key. + * The result is a byte array containing the key bytes followed by the IV. + * To split them, use {@link org.bouncycastle.bcpg.AEADUtils#splitMessageKeyAndIv(byte[], int, int)}. + * + * @param aeadAlgo AEAD algorithm + * @param cipherAlgo symmetric cipher algorithm + * @param sessionKey session key + * @param salt salt + * @param hkdfInfo HKDF info + * @return message key and appended IV + */ + static byte[] deriveMessageKeyAndIv(int aeadAlgo, int cipherAlgo, byte[] sessionKey, byte[] salt, byte[] hkdfInfo) + { + // Is it okay to have this common logic be implemented using BCs lightweight API? + // Should we move it to BcAEADUtil instead and also provide a JCE implementation? + HKDFParameters hkdfParameters = new HKDFParameters(sessionKey, salt, hkdfInfo); + HKDFBytesGenerator hkdfGen = new HKDFBytesGenerator(new SHA256Digest()); + + hkdfGen.init(hkdfParameters); + int keyLen = SymmetricKeyUtils.getKeyLengthInOctets(cipherAlgo); + int ivLen = AEADUtils.getIVLength(aeadAlgo); + byte[] messageKeyAndIv = new byte[keyLen + ivLen - 8]; + hkdfGen.generateBytes(messageKeyAndIv, 0, messageKeyAndIv.length); + return messageKeyAndIv; + } +} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/OpenedPGPKeyData.java b/pg/src/main/java/org/bouncycastle/openpgp/OpenedPGPKeyData.java index fa800a2010..fc0659eb47 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/OpenedPGPKeyData.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/OpenedPGPKeyData.java @@ -1,47 +1,18 @@ package org.bouncycastle.openpgp; import java.io.IOException; -import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; -import java.util.Date; import java.util.Iterator; import java.util.List; -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; -import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; -import org.bouncycastle.asn1.x9.ECNamedCurveTable; -import org.bouncycastle.asn1.x9.X9ECParametersHolder; -import org.bouncycastle.bcpg.BCPGKey; -import org.bouncycastle.bcpg.DSAPublicBCPGKey; -import org.bouncycastle.bcpg.DSASecretBCPGKey; -import org.bouncycastle.bcpg.ECDHPublicBCPGKey; -import org.bouncycastle.bcpg.ECDSAPublicBCPGKey; -import org.bouncycastle.bcpg.ECPublicBCPGKey; -import org.bouncycastle.bcpg.ECSecretBCPGKey; -import org.bouncycastle.bcpg.EdDSAPublicBCPGKey; -import org.bouncycastle.bcpg.EdSecretBCPGKey; -import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; -import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; -import org.bouncycastle.bcpg.PublicKeyPacket; -import org.bouncycastle.bcpg.RSAPublicBCPGKey; -import org.bouncycastle.bcpg.RSASecretBCPGKey; -import org.bouncycastle.bcpg.S2K; import org.bouncycastle.bcpg.SecretKeyPacket; -import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; -import org.bouncycastle.crypto.ec.CustomNamedCurves; import org.bouncycastle.gpg.SExpression; -import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.gpg.SExprParser; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory; -import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; -import org.bouncycastle.openpgp.operator.PGPSecretKeyDecryptorWithAAD; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.BigIntegers; -import org.bouncycastle.util.Strings; /** * Wraps PGP key headers and pgp key SExpression @@ -81,298 +52,19 @@ public ExtendedPGPSecretKey getKeyData(PGPPublicKey publicKey, PGPDigestCalculat PBEProtectionRemoverFactory keyProtectionRemoverFactory, KeyFingerPrintCalculator fingerPrintCalculator, int maxDepth) throws PGPException, IOException - { - String type = keyExpression.getString(0); + int type = SExprParser.getProtectionType(keyExpression.getString(0)); ArrayList attributeList = new ArrayList(); - - if (type.equals("shadowed-private-key") || type.equals("protected-private-key") || type.equals("private-key")) + if (type == SExprParser.ProtectionFormatTypeTags.PRIVATE_KEY || type == SExprParser.ProtectionFormatTypeTags.PROTECTED_PRIVATE_KEY || + type == SExprParser.ProtectionFormatTypeTags.SHADOWED_PRIVATE_KEY) { - SExpression keyExpression = getKeyExpression().getExpression(1); - - - if (keyExpression.hasLabel("ecc")) - { - PGPPublicKey pgpPublicKeyFound = getECCPublicKey(keyExpression, fingerPrintCalculator); - if (publicKey != null && pgpPublicKeyFound != null) - { - ECPublicBCPGKey basePubKey = (ECPublicBCPGKey)publicKey.getPublicKeyPacket().getKey(); - ECPublicBCPGKey assocPubKey = (ECPublicBCPGKey)pgpPublicKeyFound.getPublicKeyPacket().getKey(); - if (!basePubKey.getCurveOID().equals(assocPubKey.getCurveOID()) - || !basePubKey.getEncodedPoint().equals(assocPubKey.getEncodedPoint())) - { - throw new PGPException("passed in public key does not match secret key"); - } - } - - publicKey = pgpPublicKeyFound; - - UnwrapResult unwrapResult; - - if (type.equals("shadowed-private-key")) - { - unwrapResult = null; - } - else if (type.equals("protected-private-key")) - { - SExpression protectedKey = keyExpression.getExpressionWithLabel("protected"); - if (protectedKey == null) - { - throw new IllegalArgumentException(type + " does not have protected block"); - } - - String protectionType = protectedKey.getString(1); - - if (protectionType.indexOf("aes") >= 0) - { - unwrapResult = unwrapECCSecretKey(protectionType, publicKey, maxDepth, keyExpression, protectedKey, keyProtectionRemoverFactory); - } - else - { - throw new PGPException("unsupported protection type"); - } - } - else - { - String curve; - SExpression curveExpr = keyExpression.getExpressionWithLabel("curve"); - if (curveExpr != null) - { - curve = curveExpr.getString(1); - } - else - { - throw new IllegalStateException("no curve expression"); - } - - unwrapResult = new UnwrapResult(keyExpression, null, null, curve); - } - - BigInteger d = new BigInteger(1, unwrapResult.expression.getExpressionWithLabelOrFail("d").getBytes(1)); - - - if (unwrapResult.metaData == null) - { - throw new IllegalStateException("expecting unwrap result to have meta data defining the curve"); - } - - String curve = unwrapResult.metaData.toString(); - BCPGKey key; - if (curve.startsWith("NIST") || curve.startsWith("brain")) - { - key = new ECSecretBCPGKey(d); - } - else - { - key = new EdSecretBCPGKey(d); - } - - return new ExtendedPGPSecretKey( - headerList, - attributeList, - new SecretKeyPacket( - publicKey.getPublicKeyPacket(), - SymmetricKeyAlgorithmTags.NULL, - unwrapResult.s2K, - unwrapResult.iv, - key.getEncoded()), - publicKey); - - } - else if (keyExpression.hasLabel("elg")) + SExpression expression = getKeyExpression().getExpression(1); + String keyType = expression.getString(0); + PublicKeyAlgorithmTags[] secretKey = SExprParser.getPGPSecretKey(keyProtectionRemoverFactory, fingerPrintCalculator, publicKey, maxDepth, type, expression, + keyType, digestCalculatorProvider); + if (keyType.equals("rsa")) { - PGPPublicKey pgpPublicKeyFound = getDSAPublicKey(keyExpression, fingerPrintCalculator); - if (publicKey != null && pgpPublicKeyFound != null) - { - - ElGamalPublicBCPGKey basePubKey = (ElGamalPublicBCPGKey)publicKey.getPublicKeyPacket().getKey(); - ElGamalPublicBCPGKey assocPubKey = (ElGamalPublicBCPGKey)pgpPublicKeyFound.getPublicKeyPacket().getKey(); - if (!basePubKey.getP().equals(assocPubKey.getP()) - || !basePubKey.getG().equals(assocPubKey.getG()) - || !basePubKey.getY().equals(assocPubKey.getY())) - { - throw new PGPException("passed in public key does not match secret key"); - } - } - publicKey = pgpPublicKeyFound; - - UnwrapResult unwrapResult; - - if (type.equals("shadowed-private-key")) - { - unwrapResult = null; - } - else if (type.equals("protected-private-key")) - { - SExpression protectedKey = keyExpression.getExpressionWithLabel("protected"); - if (protectedKey == null) - { - throw new IllegalArgumentException(type + " does not have protected block"); - } - - String protectionType = protectedKey.getString(1); - - - if (protectionType.indexOf("aes") >= 0) - { - // TODO could not get client to generate protected elgamal keys - throw new IllegalStateException("no decryption support for protected elgamal keys"); - // unwrapResult = unwrapDSASecretKey(protectionType, publicKey, maxDepth, keyExpression, protectedKey); - } - else - { - throw new PGPException("unsupported protection type"); - } - } - else - { - unwrapResult = new UnwrapResult(keyExpression, null, null); - } - - BigInteger x = BigIntegers.fromUnsignedByteArray(unwrapResult.expression.getExpressionWithLabelOrFail("x").getBytes(1)); - - if (keyExpression.hasLabel("elg")) - { - return new ExtendedPGPSecretKey( - headerList, - attributeList, - new SecretKeyPacket( - publicKey.getPublicKeyPacket(), - SymmetricKeyAlgorithmTags.NULL, - unwrapResult.s2K, - unwrapResult.iv, - new ElGamalSecretBCPGKey(x).getEncoded()), - publicKey); - } - else - { - - return new ExtendedPGPSecretKey( - headerList, - attributeList, - new SecretKeyPacket( - publicKey.getPublicKeyPacket(), - SymmetricKeyAlgorithmTags.NULL, - unwrapResult.s2K, - unwrapResult.iv, - new DSASecretBCPGKey(x).getEncoded()), - publicKey); - } - - } - else if (keyExpression.hasLabel("dsa")) - { - PGPPublicKey pgpPublicKeyFound = getDSAPublicKey(keyExpression, fingerPrintCalculator); - if (publicKey != null && pgpPublicKeyFound != null) - { - DSAPublicBCPGKey basePubKey = (DSAPublicBCPGKey)publicKey.getPublicKeyPacket().getKey(); - DSAPublicBCPGKey assocPubKey = (DSAPublicBCPGKey)pgpPublicKeyFound.getPublicKeyPacket().getKey(); - if (!basePubKey.getP().equals(assocPubKey.getP()) - || !basePubKey.getQ().equals(assocPubKey.getQ()) - || !basePubKey.getG().equals(assocPubKey.getG()) - || !basePubKey.getY().equals(assocPubKey.getY())) - { - throw new PGPException("passed in public key does not match secret key"); - } - } - publicKey = pgpPublicKeyFound; - - UnwrapResult unwrapResult; - - if (type.equals("shadowed-private-key")) - { - unwrapResult = null; - } - else if (type.equals("protected-private-key")) - { - SExpression protectedKey = keyExpression.getExpressionWithLabel("protected"); - if (protectedKey == null) - { - throw new IllegalArgumentException(type + " does not have protected block"); - } - - String protectionType = protectedKey.getString(1); - - - if (protectionType.indexOf("aes") >= 0) - { - unwrapResult = unwrapDSASecretKey(protectionType, publicKey, maxDepth, keyExpression, protectedKey, keyProtectionRemoverFactory); - } - else - { - throw new PGPException("unsupported protection type"); - } - } - else - { - unwrapResult = new UnwrapResult(keyExpression, null, null); - } - - BigInteger x = BigIntegers.fromUnsignedByteArray(unwrapResult.expression.getExpressionWithLabelOrFail("x").getBytes(1)); - - return new ExtendedPGPSecretKey( - headerList, - attributeList, - new SecretKeyPacket( - publicKey.getPublicKeyPacket(), - SymmetricKeyAlgorithmTags.NULL, - unwrapResult.s2K, - unwrapResult.iv, - new DSASecretBCPGKey(x).getEncoded()), - publicKey); - - - } - else if (keyExpression.hasLabel("rsa")) - { - PGPPublicKey pgpPublicKeyFound = getRSAPublicKey(keyExpression, fingerPrintCalculator); - - // Test passed in PublicKey matches the found public key - if (publicKey != null && pgpPublicKeyFound != null) - { - RSAPublicBCPGKey basePubKey = (RSAPublicBCPGKey)publicKey.getPublicKeyPacket().getKey(); - RSAPublicBCPGKey assocPubKey = (RSAPublicBCPGKey)pgpPublicKeyFound.getPublicKeyPacket().getKey(); - if (!basePubKey.getModulus().equals(assocPubKey.getModulus()) - || !basePubKey.getPublicExponent().equals(assocPubKey.getPublicExponent())) - { - throw new PGPException("passed in public key does not match secret key"); - } - } - publicKey = pgpPublicKeyFound; - - UnwrapResult unwrapResult; - - if (type.equals("shadowed-private-key")) - { - unwrapResult = null; - } - else if (type.equals("protected-private-key")) - { - SExpression protectedKey = keyExpression.getExpressionWithLabel("protected"); - if (protectedKey == null) - { - throw new IllegalArgumentException(type + " does not have protected block"); - } - - String protectionType = protectedKey.getString(1); - - - if (protectionType.indexOf("aes") >= 0) - { - unwrapResult = unwrapRSASecretKey(protectionType, publicKey, maxDepth, keyExpression, protectedKey, keyProtectionRemoverFactory); - } - else - { - throw new PGPException("unsupported protection type"); - } - } - else - { - unwrapResult = new UnwrapResult(keyExpression, null, null); - } - - - for (Iterator it = keyExpression.filterOut(new String[] { "rsa", "e", "n", "d", "p", "q", "u", "protected" }).getValues().iterator(); it.hasNext();) + for (Iterator it = expression.filterOut(new String[]{"rsa", "e", "n", "d", "p", "q", "u", "protected"}).getValues().iterator(); it.hasNext(); ) { Object o = it.next(); if (o instanceof SExpression) @@ -384,859 +76,18 @@ else if (type.equals("protected-private-key")) attributeList.add(PGPExtendedKeyAttribute.builder().addAttribute(o).build()); } } - - if (unwrapResult == null) - { - return new ExtendedPGPSecretKey( - headerList, - attributeList, - null, - publicKey); - } - - BigInteger d = BigIntegers.fromUnsignedByteArray(unwrapResult.expression.getExpressionWithLabelOrFail("d").getBytes(1)); - BigInteger p = BigIntegers.fromUnsignedByteArray(unwrapResult.expression.getExpressionWithLabelOrFail("p").getBytes(1)); - BigInteger q = BigIntegers.fromUnsignedByteArray(unwrapResult.expression.getExpressionWithLabelOrFail("q").getBytes(1)); - - return new ExtendedPGPSecretKey( - headerList, - attributeList, - new SecretKeyPacket( - publicKey.getPublicKeyPacket(), - SymmetricKeyAlgorithmTags.NULL, - unwrapResult.s2K, - unwrapResult.iv, - new RSASecretBCPGKey(d, p, q).getEncoded()), - publicKey); - } + return new ExtendedPGPSecretKey(headerList, attributeList, (SecretKeyPacket)secretKey[0], (PGPPublicKey)secretKey[1]); } - return null; } - -// private ExtendedPGPSecretKey fromSExpression(ArrayList preamble, SExpression expression, PGPPublicKey publicKey, int maxDepth, PBEProtectionRemoverFactory keyProtectionRemoverFactory) -// throws PGPException, IOException -// { -// String type = expression.getString(0); -// ArrayList attributeList = new ArrayList(); -// -// if (type.equals("shadowed-private-key") || type.equals("protected-private-key") || type.equals("private-key")) -// { -// SExpression keyExpression = expression.getExpression(1); -// -// -// if (keyExpression.hasLabel("ecc")) -// { -// PGPPublicKey pgpPublicKeyFound = getECCPublicKey(keyExpression,); -// if (publicKey != null && pgpPublicKeyFound != null) -// { -// ECPublicBCPGKey basePubKey = (ECPublicBCPGKey)publicKey.getPublicKeyPacket().getKey(); -// ECPublicBCPGKey assocPubKey = (ECPublicBCPGKey)pgpPublicKeyFound.getPublicKeyPacket().getKey(); -// if (!basePubKey.getCurveOID().equals(assocPubKey.getCurveOID()) -// || !basePubKey.getEncodedPoint().equals(assocPubKey.getEncodedPoint())) -// { -// throw new PGPException("passed in public key does not match secret key"); -// } -// } -// -// publicKey = pgpPublicKeyFound; -// -// UnwrapResult unwrapResult; -// -// if (type.equals("shadowed-private-key")) -// { -// unwrapResult = null; -// } -// else if (type.equals("protected-private-key")) -// { -// SExpression protectedKey = keyExpression.getExpressionWithLabel("protected"); -// if (protectedKey == null) -// { -// throw new IllegalArgumentException(type + " does not have protected block"); -// } -// -// String protectionType = protectedKey.getString(1); -// -// if (protectionType.indexOf("aes") >= 0) -// { -// unwrapResult = unwrapECCSecretKey(protectionType, publicKey, maxDepth, keyExpression, protectedKey,keyProtectionRemoverFactory); -// } -// else -// { -// throw new PGPException("unsupported protection type"); -// } -// } -// else -// { -// String curve; -// SExpression curveExpr = keyExpression.getExpressionWithLabel("curve"); -// if (curveExpr != null) -// { -// curve = curveExpr.getString(1); -// } -// else -// { -// throw new IllegalStateException("no curve expression"); -// } -// -// unwrapResult = new UnwrapResult(keyExpression, null, null, curve); -// } -// -// BigInteger d = BigIntegers.fromUnsignedByteArray(unwrapResult.expression.getExpressionWithLabelOrFail("d").getBytes(1)); -// -// -// if (unwrapResult.metaData == null) -// { -// throw new IllegalStateException("expecting unwrap result to have meta data defining the curve"); -// } -// -// String curve = unwrapResult.metaData.toString(); -// BCPGKey key; -// if (curve.startsWith("NIST") || curve.startsWith("brain")) -// { -// key = new ECSecretBCPGKey(d); -// } -// else -// { -// key = new EdSecretBCPGKey(d); -// } -// -// return new ExtendedPGPSecretKey( -// preamble, -// attributeList, -// new SecretKeyPacket( -// publicKey.getPublicKeyPacket(), -// SymmetricKeyAlgorithmTags.NULL, -// unwrapResult.s2K, -// unwrapResult.iv, -// key.getEncoded()), -// publicKey); -// -// } -// else if (keyExpression.hasLabel("elg")) -// { -// PGPPublicKey pgpPublicKeyFound = getDSAPublicKey(keyExpression); -// if (publicKey != null && pgpPublicKeyFound != null) -// { -// -// ElGamalPublicBCPGKey basePubKey = (ElGamalPublicBCPGKey)publicKey.getPublicKeyPacket().getKey(); -// ElGamalPublicBCPGKey assocPubKey = (ElGamalPublicBCPGKey)pgpPublicKeyFound.getPublicKeyPacket().getKey(); -// if (!basePubKey.getP().equals(assocPubKey.getP()) -// || !basePubKey.getG().equals(assocPubKey.getG()) -// || !basePubKey.getY().equals(assocPubKey.getY())) -// { -// throw new PGPException("passed in public key does not match secret key"); -// } -// } -// publicKey = pgpPublicKeyFound; -// -// UnwrapResult unwrapResult; -// -// if (type.equals("shadowed-private-key")) -// { -// unwrapResult = null; -// } -// else if (type.equals("protected-private-key")) -// { -// SExpression protectedKey = keyExpression.getExpressionWithLabel("protected"); -// if (protectedKey == null) -// { -// throw new IllegalArgumentException(type + " does not have protected block"); -// } -// -// String protectionType = protectedKey.getString(1); -// -// -// if (protectionType.indexOf("aes") >= 0) -// { -// // TODO could not get client to generate protected elgamal keys -// throw new IllegalStateException("no decryption support for protected elgamal keys"); -// // unwrapResult = unwrapDSASecretKey(protectionType, publicKey, maxDepth, keyExpression, protectedKey); -// } -// else -// { -// throw new PGPException("unsupported protection type"); -// } -// } -// else -// { -// unwrapResult = new UnwrapResult(keyExpression, null, null); -// } -// -// BigInteger x = BigIntegers.fromUnsignedByteArray(unwrapResult.expression.getExpressionWithLabelOrFail("x").getBytes(1)); -// -// if (keyExpression.hasLabel("elg")) -// { -// return new ExtendedPGPSecretKey( -// preamble, -// attributeList, -// new SecretKeyPacket( -// publicKey.getPublicKeyPacket(), -// SymmetricKeyAlgorithmTags.NULL, -// unwrapResult.s2K, -// unwrapResult.iv, -// new ElGamalSecretBCPGKey(x).getEncoded()), -// publicKey); -// } -// else -// { -// -// return new ExtendedPGPSecretKey( -// preamble, -// attributeList, -// new SecretKeyPacket( -// publicKey.getPublicKeyPacket(), -// SymmetricKeyAlgorithmTags.NULL, -// unwrapResult.s2K, -// unwrapResult.iv, -// new DSASecretBCPGKey(x).getEncoded()), -// publicKey); -// } -// -// } -// else if (keyExpression.hasLabel("dsa")) -// { -// PGPPublicKey pgpPublicKeyFound = getDSAPublicKey(keyExpression); -// if (publicKey != null && pgpPublicKeyFound != null) -// { -// DSAPublicBCPGKey basePubKey = (DSAPublicBCPGKey)publicKey.getPublicKeyPacket().getKey(); -// DSAPublicBCPGKey assocPubKey = (DSAPublicBCPGKey)pgpPublicKeyFound.getPublicKeyPacket().getKey(); -// if (!basePubKey.getP().equals(assocPubKey.getP()) -// || !basePubKey.getQ().equals(assocPubKey.getQ()) -// || !basePubKey.getG().equals(assocPubKey.getG()) -// || !basePubKey.getY().equals(assocPubKey.getY())) -// { -// throw new PGPException("passed in public key does not match secret key"); -// } -// } -// publicKey = pgpPublicKeyFound; -// -// UnwrapResult unwrapResult; -// -// if (type.equals("shadowed-private-key")) -// { -// unwrapResult = null; -// } -// else if (type.equals("protected-private-key")) -// { -// SExpression protectedKey = keyExpression.getExpressionWithLabel("protected"); -// if (protectedKey == null) -// { -// throw new IllegalArgumentException(type + " does not have protected block"); -// } -// -// String protectionType = protectedKey.getString(1); -// -// -// if (protectionType.indexOf("aes") >= 0) -// { -// unwrapResult = unwrapDSASecretKey(protectionType, publicKey, maxDepth, keyExpression, protectedKey); -// } -// else -// { -// throw new PGPException("unsupported protection type"); -// } -// } -// else -// { -// unwrapResult = new UnwrapResult(keyExpression, null, null); -// } -// -// BigInteger x = BigIntegers.fromUnsignedByteArray(unwrapResult.expression.getExpressionWithLabelOrFail("x").getBytes(1)); -// -// return new ExtendedPGPSecretKey( -// preamble, -// attributeList, -// new SecretKeyPacket( -// publicKey.getPublicKeyPacket(), -// SymmetricKeyAlgorithmTags.NULL, -// unwrapResult.s2K, -// unwrapResult.iv, -// new DSASecretBCPGKey(x).getEncoded()), -// publicKey); -// -// -// } -// else if (keyExpression.hasLabel("rsa")) -// { -// PGPPublicKey pgpPublicKeyFound = getRSAPublicKey(keyExpression); -// -// // Test passed in PublicKey matches the found public key -// if (publicKey != null && pgpPublicKeyFound != null) -// { -// RSAPublicBCPGKey basePubKey = (RSAPublicBCPGKey)publicKey.getPublicKeyPacket().getKey(); -// RSAPublicBCPGKey assocPubKey = (RSAPublicBCPGKey)pgpPublicKeyFound.getPublicKeyPacket().getKey(); -// if (!basePubKey.getModulus().equals(assocPubKey.getModulus()) -// || !basePubKey.getPublicExponent().equals(assocPubKey.getPublicExponent())) -// { -// throw new PGPException("passed in public key does not match secret key"); -// } -// } -// publicKey = pgpPublicKeyFound; -// -// UnwrapResult unwrapResult; -// -// if (type.equals("shadowed-private-key")) -// { -// unwrapResult = null; -// } -// else if (type.equals("protected-private-key")) -// { -// SExpression protectedKey = keyExpression.getExpressionWithLabel("protected"); -// if (protectedKey == null) -// { -// throw new IllegalArgumentException(type + " does not have protected block"); -// } -// -// String protectionType = protectedKey.getString(1); -// -// -// if (protectionType.indexOf("aes") >= 0) -// { -// unwrapResult = unwrapRSASecretKey(protectionType, publicKey, maxDepth, keyExpression, protectedKey); -// } -// else -// { -// throw new PGPException("unsupported protection type"); -// } -// } -// else -// { -// unwrapResult = new UnwrapResult(keyExpression, null, null); -// } -// -// -// for (Object o : keyExpression.filterOut("rsa", "e", "n", "d", "p", "q", "u", "protected").getValues()) -// { -// if (o instanceof SExpression) -// { -// attributeList.add(((SExpression)o).toAttribute()); -// } -// else -// { -// attributeList.add(PGPExtendedKeyAttribute.builder().addAttribute(o).build()); -// } -// } -// -// if (unwrapResult == null) -// { -// return new ExtendedPGPSecretKey( -// preamble, -// attributeList, -// null, -// publicKey); -// } -// -// BigInteger d = BigIntegers.fromUnsignedByteArray(unwrapResult.expression.getExpressionWithLabelOrFail("d").getBytes(1)); -// BigInteger p = BigIntegers.fromUnsignedByteArray(unwrapResult.expression.getExpressionWithLabelOrFail("p").getBytes(1)); -// BigInteger q = BigIntegers.fromUnsignedByteArray(unwrapResult.expression.getExpressionWithLabelOrFail("q").getBytes(1)); -// -// return new ExtendedPGPSecretKey( -// preamble, -// attributeList, -// new SecretKeyPacket( -// publicKey.getPublicKeyPacket(), -// SymmetricKeyAlgorithmTags.NULL, -// unwrapResult.s2K, -// unwrapResult.iv, -// new RSASecretBCPGKey(d, p, q).getEncoded()), -// publicKey); -// -// } -// } -// -// return null; -// } - - private UnwrapResult unwrapDSASecretKey( - String protectionType, PGPPublicKey publicKey, int maxDepth, SExpression keyExpression, SExpression protectedKey, - PBEProtectionRemoverFactory keyProtectionRemoverFactory - ) - throws PGPException, IOException - { - - if (protectionType.equals("openpgp-s2k3-sha1-aes-cbc")) - { - // TODO could not get client to generate this. - throw new IllegalArgumentException("openpgp-s2k3-sha1-aes-cbc not supported on newer key type"); - } - else if (protectionType.equals("openpgp-s2k3-ocb-aes")) - { - // - // Create AAD. - // - SExpression.Builder builder = SExpression.builder().addValue("dsa"); - addPublicKey(publicKey, builder); - builder.addContent(keyExpression.filterOut(new String[] { "dsa", "p", "q", "g", "y", "protected" })); - byte[] aad = builder.build().toCanonicalForm(); - - - SExpression protectionKeyParameters = protectedKey.getExpression(2); - SExpression s2kParams = protectionKeyParameters.getExpression(0); - // TODO select correct hash - S2K s2K = new S2K(PGPUtil.getDigestIDForName(s2kParams.getString(0)), s2kParams.getBytes(1), s2kParams.getInt(2)); - - - byte[] nonce = protectionKeyParameters.getBytes(1); - - PBESecretKeyDecryptor decryptor = keyProtectionRemoverFactory.createDecryptor("ocb"); - byte[] key = decryptor.makeKeyFromPassPhrase(SymmetricKeyAlgorithmTags.AES_128, s2K); - - byte[] keyData = protectedKey.getBytes(3); - - - return new UnwrapResult(SExpression.parse( - ((PGPSecretKeyDecryptorWithAAD)decryptor).recoverKeyData( - SymmetricKeyAlgorithmTags.AES_128, - key, nonce, aad, keyData, 0, keyData.length), - maxDepth).getExpression(0), s2K, Arrays.clone(nonce)); - - } - - throw new PGPException("unhandled protection type " + protectionType); - } - - private UnwrapResult unwrapECCSecretKey( - String protectionType, - PGPPublicKey publicKey, - int maxDepth, - SExpression keyExpression, - SExpression protectedKey, - PBEProtectionRemoverFactory keyProtectionRemoverFactory) - throws PGPException, IOException - { - - if (protectionType.equals("openpgp-s2k3-sha1-aes-cbc")) - { - // TODO could not get client to generate this. - throw new IllegalArgumentException("openpgp-s2k3-sha1-aes-cbc not supported on newer key type"); - } - else if (protectionType.equals("openpgp-s2k3-ocb-aes")) - { - - SExpression.Builder builder = SExpression.builder().addValue("ecc"); - builder.addContent(keyExpression.filterIn(new String[] { "curve", "flags" })); - addPublicKey(publicKey, builder); - builder.addContent(keyExpression.filterOut(new String[] { "ecc", "flags", "curve", "q", "protected" })); - byte[] aad = builder.build().toCanonicalForm(); - - String curve; - SExpression curveExpr = keyExpression.getExpressionWithLabel("curve"); - if (curveExpr != null) - { - curve = curveExpr.getString(1); - } - else - { - throw new IllegalStateException("no curve expression"); - } - - SExpression protectionKeyParameters = protectedKey.getExpression(2); - SExpression s2kParams = protectionKeyParameters.getExpression(0); - // TODO select correct hash - S2K s2K = new S2K(PGPUtil.getDigestIDForName(s2kParams.getString(0)), s2kParams.getBytes(1), s2kParams.getInt(2)); - - // OCB Nonce - byte[] nonce = protectionKeyParameters.getBytes(1); - - PBESecretKeyDecryptor decryptor = keyProtectionRemoverFactory.createDecryptor("ocb"); - byte[] key = decryptor.makeKeyFromPassPhrase(SymmetricKeyAlgorithmTags.AES_128, s2K); - - byte[] keyData = protectedKey.getBytes(3); - - - return new UnwrapResult(SExpression.parse( - ((PGPSecretKeyDecryptorWithAAD)decryptor).recoverKeyData( - SymmetricKeyAlgorithmTags.AES_128, - key, nonce, aad, keyData, 0, keyData.length), - maxDepth).getExpression(0), s2K, Arrays.clone(nonce), curve); - - } - - throw new PGPException("unhandled protection type " + protectionType); - } - - private PGPPublicKey getECCPublicKey(SExpression expression, KeyFingerPrintCalculator fingerPrintCalculator) - throws IOException, PGPException - { - byte[] qoint = null; - String curve = null; - - for (Iterator it = expression.getValues().iterator(); it.hasNext();) - { - Object item = it.next(); - if (item instanceof SExpression) - { - SExpression exp = (SExpression)item; - if (exp.hasLabel("curve")) - { - curve = exp.getString(1); - } - else if (exp.hasLabel("q")) - { - qoint = exp.getBytes(1); - } - } - } - - if (curve == null || qoint == null) - { - return null; - } - - if (curve.startsWith("Curve")) - { - curve = Strings.toLowerCase(curve); - } - else if (curve.startsWith("NIST")) - { - curve = curve.substring("NIST".length()).trim(); - } - - PublicKeyPacket publicKeyPacket; - if (Strings.toLowerCase(curve).equals("ed25519")) - { - EdDSAPublicBCPGKey basePubKey = new EdDSAPublicBCPGKey(EdECObjectIdentifiers.id_Ed25519, new BigInteger(1, qoint)); - publicKeyPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.EDDSA_LEGACY, new Date(), basePubKey); - } - else if (Strings.toLowerCase(curve).equals("ed448")) - { - EdDSAPublicBCPGKey basePubKey = new EdDSAPublicBCPGKey(EdECObjectIdentifiers.id_Ed448, new BigInteger(1, qoint)); - publicKeyPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.EDDSA_LEGACY, new Date(), basePubKey); - } - else - { - ASN1ObjectIdentifier oid = ECNamedCurveTable.getOID(curve); - X9ECParametersHolder holder = CustomNamedCurves.getByNameLazy(curve); - if (holder == null) - { - holder = TeleTrusTNamedCurves.getByOIDLazy(oid); - } - - if (holder == null) - { - throw new IllegalStateException("unable to resolve parameters for " + curve); - } - - ECPoint pnt = holder.getCurve().decodePoint(qoint); - ECPublicBCPGKey basePubKey = new ECDSAPublicBCPGKey(oid, pnt); - publicKeyPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.ECDSA, new Date(), basePubKey); - } - - return new PGPPublicKey(publicKeyPacket, fingerPrintCalculator); - } - - private PGPPublicKey getDSAPublicKey(SExpression expression, KeyFingerPrintCalculator fingerPrintCalculator) - throws PGPException - { - BigInteger p = null; - BigInteger q = null; - BigInteger g = null; - BigInteger y = null; - - for (Iterator it = expression.getValues().iterator(); it.hasNext();) - { - Object item = it.next(); - if (item instanceof SExpression) - { - SExpression exp = (SExpression)item; - if (exp.hasLabel("p")) - { - p = BigIntegers.fromUnsignedByteArray(exp.getBytes(1)); - } - else if (exp.hasLabel("q")) - { - q = BigIntegers.fromUnsignedByteArray(exp.getBytes(1)); - } - else if (exp.hasLabel("g")) - { - g = BigIntegers.fromUnsignedByteArray(exp.getBytes(1)); - } - else if (exp.hasLabel("y")) - { - y = BigIntegers.fromUnsignedByteArray(exp.getBytes(1)); - } - } - } - - if (p == null || (!expression.hasLabel("elg") && q == null) || g == null || y == null) - { - return null; - } - - PublicKeyPacket publicKeyPacket; - if (expression.hasLabel("elg")) - { - // TODO how to tell if Elgamal General or Encrypt? - publicKeyPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.ELGAMAL_GENERAL, new Date(), new ElGamalPublicBCPGKey(p, g, y)); - } - else - { - publicKeyPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.DSA, new Date(), new DSAPublicBCPGKey(p, q, g, y)); - } - - return new PGPPublicKey(publicKeyPacket, fingerPrintCalculator); - } - - private UnwrapResult unwrapRSASecretKey( - String protectionType, - PGPPublicKey publicKey, - int maxDepth, - SExpression keyExpression, - SExpression protectedKey, - PBEProtectionRemoverFactory keyProtectionRemoverFactory) - throws PGPException, IOException - { - - if (protectionType.equals("openpgp-s2k3-sha1-aes-cbc")) - { - // TODO could not get client to generate this. - throw new IllegalArgumentException("openpgp-s2k3-sha1-aes-cbc not supported on newer key type"); - } - else if (protectionType.equals("openpgp-s2k3-ocb-aes")) - { - - - SExpression.Builder builder = SExpression.builder().addValue("rsa"); - addPublicKey(publicKey, builder); - builder.addContent(keyExpression.filterOut(new String[] { "rsa", "e", "n", "protected" })); - byte[] aad = builder.build().toCanonicalForm(); - - - SExpression protectionKeyParameters = protectedKey.getExpression(2); - SExpression s2kParams = protectionKeyParameters.getExpression(0); - // TODO select correct hash - S2K s2K = new S2K(PGPUtil.getDigestIDForName(s2kParams.getString(0)), s2kParams.getBytes(1), s2kParams.getInt(2)); - - byte[] nonce = protectionKeyParameters.getBytes(1); - - PBESecretKeyDecryptor decryptor = keyProtectionRemoverFactory.createDecryptor("ocb"); - byte[] key = decryptor.makeKeyFromPassPhrase(SymmetricKeyAlgorithmTags.AES_128, s2K); - - byte[] keyData = protectedKey.getBytes(3); - - - return new UnwrapResult(SExpression.parse( - ((PGPSecretKeyDecryptorWithAAD)decryptor).recoverKeyData( - SymmetricKeyAlgorithmTags.AES_128, - key, nonce, aad, keyData, 0, keyData.length), - maxDepth).getExpression(0), s2K, Arrays.clone(nonce)); - - } - - throw new PGPException("unhandled protection type " + protectionType); - } - - /** - * @param expression The expression (rsa (n ..) (e ..) ...) - * @return - */ - private PGPPublicKey getRSAPublicKey(SExpression expression, KeyFingerPrintCalculator fingerPrintCalculator) - throws PGPException - { - BigInteger n = null; - BigInteger e = null; - for (Iterator it = expression.getValues().iterator(); it.hasNext();) - { - Object item = it.next(); - if (item instanceof SExpression) - { - SExpression exp = (SExpression)item; - if (exp.hasLabel("e")) - { - e = BigIntegers.fromUnsignedByteArray(exp.getBytes(1)); - } - else if (exp.hasLabel("n")) - { - n = BigIntegers.fromUnsignedByteArray(exp.getBytes(1)); - } - } - } - - if (n == null || e == null) - { - return null; - } - - PublicKeyPacket pubPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.RSA_GENERAL, new Date(), new RSAPublicBCPGKey(n, e)); - - return new PGPPublicKey(pubPacket, fingerPrintCalculator); - } - - /** - * Encodes a public key into an S-Expression. - * Used primarily where the public key is part the AAD value in OCB mode. - * - * @param publicKey The public key - * @param builder The SExpresson builder - * @return the same builder as passed in. - * @throws PGPException - */ - private SExpression.Builder addPublicKey(PGPPublicKey publicKey, SExpression.Builder builder) - throws PGPException - { - PublicKeyPacket publicPk = publicKey.getPublicKeyPacket(); - try - { - switch (publicPk.getAlgorithm()) - { - - - case PublicKeyAlgorithmTags.DSA: - { - DSAPublicBCPGKey dsaK = (DSAPublicBCPGKey)publicPk.getKey(); - - - return builder - .addValue( - SExpression.builder() - .addValue("p") - .addValue(dsaK.getP().toByteArray()) - .build()) - .addValue(SExpression.builder() - .addValue("q") - .addValue(dsaK.getQ().toByteArray()) - .build()) - .addValue(SExpression.builder() - .addValue("g") - .addValue(dsaK.getG().toByteArray()) - .build()) - .addValue(SExpression.builder() - .addValue("y") - .addValue(dsaK.getY().toByteArray()) - .build()); - } - - case PublicKeyAlgorithmTags.ECDH: - { - Object k = publicPk.getKey(); - - ECDHPublicBCPGKey ecdhK = (ECDHPublicBCPGKey)publicPk.getKey(); - - if (ecdhK.getCurveOID().equals(CryptlibObjectIdentifiers.curvey25519)) - { - byte[] pEnc = BigIntegers.asUnsignedByteArray(ecdhK.getEncodedPoint()); - - // skip the 0x40 header byte. - if (pEnc.length < 1 || 0x40 != pEnc[0]) - { - throw new IllegalArgumentException("Invalid Curve25519 public key"); - } - - throw new IllegalStateException("not implemented"); - - } - else - { - throw new IllegalStateException("not implemented"); - } - } - - case PublicKeyAlgorithmTags.ECDSA: - { - ECDSAPublicBCPGKey ecKey = (ECDSAPublicBCPGKey)publicPk.getKey(); - byte[] pEnc = BigIntegers.asUnsignedByteArray(ecKey.getEncodedPoint()); - - - return builder.addValue( - SExpression.builder() - .addValue("q") - .addValue(pEnc) - .build()); - } - - - case PublicKeyAlgorithmTags.EDDSA_LEGACY: - { - EdDSAPublicBCPGKey eddsaK = (EdDSAPublicBCPGKey)publicPk.getKey(); - byte[] pEnc = BigIntegers.asUnsignedByteArray(eddsaK.getEncodedPoint()); - - // skip the 0x40 header byte. - if (pEnc.length < 1 || 0x40 != pEnc[0]) - { - throw new IllegalArgumentException("Invalid Ed25519 public key"); - } - - return builder.addValue( - SExpression.builder() - .addValue("q") - .addValue(pEnc) - .build()); - } - - case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: - case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: - { - ElGamalPublicBCPGKey elK = (ElGamalPublicBCPGKey)publicPk.getKey(); - throw new IllegalStateException("not implemented"); - } - - case PublicKeyAlgorithmTags.RSA_ENCRYPT: - case PublicKeyAlgorithmTags.RSA_GENERAL: - case PublicKeyAlgorithmTags.RSA_SIGN: - { - RSAPublicBCPGKey rsaK = (RSAPublicBCPGKey)publicPk.getKey(); - - return builder.addValue( - SExpression.builder() - .addValue("n") - .addValue(rsaK.getModulus().toByteArray()) - .build()).addValue( - SExpression.builder() - .addValue("e") - .addValue(rsaK.getPublicExponent().toByteArray()) - .build() - ); - } - - default: - throw new PGPException("unknown public key algorithm encountered"); - } - } - catch (PGPException e) - { - throw e; - } - catch (Exception e) - { - throw new PGPException("exception constructing public key", e); - } - } - - private static class UnwrapResult - { - final SExpression expression; - final S2K s2K; - final byte[] iv; - final Object metaData; - - public UnwrapResult(SExpression expression, S2K s2K, byte[] iv) - { - this.expression = expression; - this.s2K = s2K; - this.iv = iv; - this.metaData = null; - } - - public UnwrapResult(SExpression expression, S2K s2K, byte[] iv, Object metaData) - { - this.expression = expression; - this.s2K = s2K; - this.iv = iv; - this.metaData = metaData; - } - - } - - public static class Builder { - private ArrayList headerList = new ArrayList(); + private List headerList = new ArrayList(); private SExpression keyExpression; - public Builder setHeaderList(ArrayList headerList) + public Builder setHeaderList(List headerList) { this.headerList = headerList; return this; diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPDefaultSignatureGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPDefaultSignatureGenerator.java new file mode 100644 index 0000000000..94c4745e63 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPDefaultSignatureGenerator.java @@ -0,0 +1,182 @@ +package org.bouncycastle.openpgp; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import org.bouncycastle.bcpg.SignaturePacket; +import org.bouncycastle.bcpg.UserAttributeSubpacket; + +abstract class PGPDefaultSignatureGenerator +{ + protected byte lastb; + protected OutputStream sigOut; + protected int sigType; + protected final int version; + + public PGPDefaultSignatureGenerator(int version) + { + this.version = version; + } + + public void update( + byte b) + { + if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) + { + if (b == '\r') + { + byteUpdate((byte)'\r'); + byteUpdate((byte)'\n'); + } + else if (b == '\n') + { + if (lastb != '\r') + { + byteUpdate((byte)'\r'); + byteUpdate((byte)'\n'); + } + } + else + { + byteUpdate(b); + } + + lastb = b; + } + else + { + byteUpdate(b); + } + } + + public void update( + byte[] b) + { + this.update(b, 0, b.length); + } + + public void update( + byte[] b, + int off, + int len) + { + if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) + { + int finish = off + len; + + for (int i = off; i != finish; i++) + { + this.update(b[i]); + } + } + else + { + blockUpdate(b, off, len); + } + } + + private void byteUpdate(byte b) + { + try + { + sigOut.write(b); + } + catch (IOException e) + { + throw new PGPRuntimeOperationException(e.getMessage(), e); + } + } + + protected void blockUpdate(byte[] block, int off, int len) + { + try + { + sigOut.write(block, off, len); + } + catch (IOException e) + { + throw new PGPRuntimeOperationException("unable to update signature: " + e.getMessage(), e); + } + } + + protected void updateWithIdData(int header, byte[] idBytes) + { + this.update((byte)header); + this.update((byte)(idBytes.length >> 24)); + this.update((byte)(idBytes.length >> 16)); + this.update((byte)(idBytes.length >> 8)); + this.update((byte)(idBytes.length)); + this.update(idBytes); + } + + protected void updateWithPublicKey(PGPPublicKey key) + throws PGPException + { + byte[] keyBytes = getEncodedPublicKey(key); + + if (version == SignaturePacket.VERSION_4) + { + this.update((byte) 0x99); + this.update((byte) (keyBytes.length >> 8)); + this.update((byte) (keyBytes.length)); + } + else if (version == SignaturePacket.VERSION_5) + { + this.update((byte) 0x9A); + this.update((byte) (keyBytes.length >> 24)); + this.update((byte) (keyBytes.length >> 16)); + this.update((byte) (keyBytes.length >> 8)); + this.update((byte) (keyBytes.length)); + } + else if (version == SignaturePacket.VERSION_6) + { + this.update((byte) 0x9B); + this.update((byte) (keyBytes.length >> 24)); + this.update((byte) (keyBytes.length >> 16)); + this.update((byte) (keyBytes.length >> 8)); + this.update((byte) (keyBytes.length)); + } + this.update(keyBytes); + } + + private byte[] getEncodedPublicKey( + PGPPublicKey pubKey) + throws PGPException + { + byte[] keyBytes; + + try + { + keyBytes = pubKey.publicPk.getEncodedContents(); + } + catch (IOException e) + { + throw new PGPException("exception preparing key.", e); + } + + return keyBytes; + } + + protected void getAttributesHash(PGPUserAttributeSubpacketVector userAttributes) + throws PGPException + { + // + // hash in the attributes + // + try + { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + UserAttributeSubpacket[] packets = userAttributes.toSubpacketArray(); + for (int i = 0; i != packets.length; i++) + { + packets[i].encode(bOut); + } + updateWithIdData(0xd1, bOut.toByteArray()); + } + catch (IOException e) + { + throw new PGPException("cannot encode subpacket array", e); + } + } +} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedData.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedData.java index 6a3527e490..fba7395286 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedData.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedData.java @@ -5,6 +5,9 @@ import java.io.InputStream; import java.io.OutputStream; +import org.bouncycastle.bcpg.AEADAlgorithmTags; +import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.InputStreamPacket; import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; @@ -12,6 +15,7 @@ import org.bouncycastle.openpgp.operator.PGPDataDecryptorFactory; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.io.TeeInputStream; /** * A PGP encrypted data object. @@ -21,7 +25,7 @@ *

      */ public abstract class PGPEncryptedData - implements SymmetricKeyAlgorithmTags + implements SymmetricKeyAlgorithmTags, AEADAlgorithmTags { protected static class TruncatedStream extends InputStream @@ -161,7 +165,7 @@ public InputStream getInputStream() } /** - * Checks whether the packet is integrity protected. + * Checks whether the packet is integrity protected using a modification detection code package. * * @return true if there is a modification detection code package associated with * this stream @@ -171,6 +175,28 @@ public boolean isIntegrityProtected() return (encData instanceof SymmetricEncIntegrityPacket); } + /** + * Checks whether the packet is protected using an AEAD algorithm. + * + * @return true if there is a modification detection code package associated with + * this stream + */ + public boolean isAEAD() + { + if (encData instanceof AEADEncDataPacket) + { + return true; + } + if (encData instanceof SymmetricEncIntegrityPacket) + { + return ((SymmetricEncIntegrityPacket) encData).getVersion() == SymmetricEncIntegrityPacket.VERSION_2; + } + else + { + return false; + } + } + /** * Verifies the integrity of the packet against the modification detection code associated with * it in the stream. @@ -198,6 +224,12 @@ public boolean verify() // do nothing } + if (isAEAD()) + { + // AEAD data needs no manual verification, as decryption detects errors automatically + return true; + } + // // process the MDC packet // @@ -238,4 +270,51 @@ public int getAlgorithm() { throw new UnsupportedOperationException("not supported - override required"); } + + boolean processSymmetricEncIntegrityPacketDataStream(boolean withIntegrityPacket, PGPDataDecryptor dataDecryptor, BCPGInputStream encIn) + throws IOException + { + encStream = new BCPGInputStream(dataDecryptor.getInputStream(encIn)); + + if (withIntegrityPacket) + { + truncStream = new TruncatedStream(encStream); + + integrityCalculator = dataDecryptor.getIntegrityCalculator(); + + encStream = new TeeInputStream(truncStream, integrityCalculator.getOutputStream()); + } + + byte[] iv = new byte[dataDecryptor.getBlockSize()]; + + for (int i = 0; i != iv.length; i++) + { + int ch = encStream.read(); + + if (ch < 0) + { + throw new EOFException("unexpected end of stream."); + } + + iv[i] = (byte)ch; + } + int v1 = encStream.read(); + int v2 = encStream.read(); + + if (v1 < 0 || v2 < 0) + { + throw new EOFException("unexpected end of stream."); + } + + // Note: the oracle attack on "quick check" bytes is not deemed + // a security risk for PBE (see PGPPublicKeyEncryptedData) + + boolean repeatCheckPassed = iv[iv.length - 2] == (byte)v1 + && iv[iv.length - 1] == (byte)v2; + + // Note: some versions of PGP appear to produce 0 for the extra + // bytes rather than repeating the two previous bytes + boolean zeroesCheckPassed = v1 == 0 && v2 == 0; + return !repeatCheckPassed && !zeroesCheckPassed; + } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java index 9b64f8a3ee..46415b28c3 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java @@ -9,6 +9,7 @@ import org.bouncycastle.bcpg.AEADEncDataPacket; import org.bouncycastle.bcpg.BCPGHeaderObject; import org.bouncycastle.bcpg.BCPGOutputStream; +import org.bouncycastle.bcpg.ContainedPacket; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.SymmetricEncDataPacket; @@ -79,10 +80,14 @@ public class PGPEncryptedDataGenerator private PGPDigestCalculator digestCalc; private OutputStream genOut; private PGPDataEncryptorBuilder dataEncryptorBuilder; + // OpenPGP v6 AEAD uses salt + private byte[] salt = new byte[32]; - private List methods = new ArrayList(); - private int defAlgorithm; + private List methods = new ArrayList(); + private int defAlgorithm; // default symmetric key algorithm private SecureRandom rand; + // If true, force generation of a session key, even if we only have a single password-based encryption method + // and could therefore use the S2K output as session key directly. private boolean forceSessionKey = false; /** @@ -108,6 +113,8 @@ public PGPEncryptedDataGenerator(PGPDataEncryptorBuilder encryptorBuilder, boole this.defAlgorithm = dataEncryptorBuilder.getAlgorithm(); this.rand = dataEncryptorBuilder.getSecureRandom(); + + rand.nextBytes(salt); } /** @@ -132,6 +139,11 @@ public void addMethod(PGPKeyEncryptionMethodGenerator method) methods.add(method); } + /** + * Write a checksum into the last two bytes of the array. + * + * @param sessionInfo byte array + */ private void addCheckSum( byte[] sessionInfo) { @@ -146,6 +158,13 @@ private void addCheckSum( sessionInfo[sessionInfo.length - 1] = (byte)(check); } + /** + * Create a session info array containing of the algorithm-id followed by the key and a two-byte checksum. + * + * @param algorithm symmetric algorithm + * @param keyBytes bytes of the key + * @return array of algorithm, key and checksum + */ private byte[] createSessionInfo( int algorithm, byte[] keyBytes) @@ -195,60 +214,95 @@ private OutputStream open( throw new IllegalStateException("no encryption methods specified"); } - byte[] key = null; + pOut = new BCPGOutputStream(out, !useOldFormat); - pOut = new BCPGOutputStream(out); + byte[] sessionKey; // session key, either protected by - or directly derived from session key encryption mechanism. + byte[] sessionInfo; // sessionKey with prepended alg-id, appended checksum - defAlgorithm = dataEncryptorBuilder.getAlgorithm(); - rand = dataEncryptorBuilder.getSecureRandom(); + byte[] messageKey; // key used to encrypt the message. In OpenPGP v6 this is derived from sessionKey + salt. - if (methods.size() == 1) + boolean directS2K = !forceSessionKey && methods.size() == 1 && + methods.get(0) instanceof PBEKeyEncryptionMethodGenerator; + if (directS2K) { - boolean isPBE = methods.get(0) instanceof PBEKeyEncryptionMethodGenerator; - if (isPBE && !forceSessionKey) - { - PBEKeyEncryptionMethodGenerator m = (PBEKeyEncryptionMethodGenerator)methods.get(0); - - key = m.getKey(defAlgorithm); + sessionKey = ((PBEKeyEncryptionMethodGenerator)methods.get(0)).getKey(defAlgorithm); + sessionInfo = null; // null indicates direct use of S2K output as sessionKey/messageKey + } + else + { + sessionKey = PGPUtil.makeRandomKey(defAlgorithm, rand); + // prepend algorithm, append checksum + sessionInfo = createSessionInfo(defAlgorithm, sessionKey); + } + messageKey = sessionKey; - pOut.writePacket(m.generate(defAlgorithm, null)); - } - else - { - key = PGPUtil.makeRandomKey(defAlgorithm, rand); - byte[] sessionInfo = createSessionInfo(defAlgorithm, key); + // In OpenPGP v6, we need an additional step to derive a message key and IV from the session info. + // Since we cannot inject the IV into the data encryptor, we append it to the message key. + boolean isV5StyleAEAD = dataEncryptorBuilder.isV5StyleAEAD(); + if (dataEncryptorBuilder.getAeadAlgorithm() != -1 && !isV5StyleAEAD) + { + byte[] info = SymmetricEncIntegrityPacket.createAAData( + SymmetricEncIntegrityPacket.VERSION_2, + defAlgorithm, + dataEncryptorBuilder.getAeadAlgorithm(), + dataEncryptorBuilder.getChunkSize()); + + // messageKey = key and IV, will be separated in the data encryptor + messageKey = AEADUtil.deriveMessageKeyAndIv( + dataEncryptorBuilder.getAeadAlgorithm(), defAlgorithm, sessionKey, salt, info); + } - PGPKeyEncryptionMethodGenerator m = (PGPKeyEncryptionMethodGenerator)methods.get(0); + PGPDataEncryptor dataEncryptor = dataEncryptorBuilder.build(messageKey); + digestCalc = dataEncryptor.getIntegrityCalculator(); - writeWrappedSessionKey(m, sessionInfo); - } - } - else // multiple methods + for (int i = 0; i < methods.size(); i++) { - key = PGPUtil.makeRandomKey(defAlgorithm, rand); - byte[] sessionInfo = createSessionInfo(defAlgorithm, key); - - for (int i = 0; i != methods.size(); i++) + PGPKeyEncryptionMethodGenerator method = (PGPKeyEncryptionMethodGenerator)methods.get(i); + // OpenPGP v5 or v6 + if (dataEncryptor instanceof PGPAEADDataEncryptor) { - PGPKeyEncryptionMethodGenerator m = (PGPKeyEncryptionMethodGenerator)methods.get(i); - - writeWrappedSessionKey(m, sessionInfo); + PGPAEADDataEncryptor aeadDataEncryptor = (PGPAEADDataEncryptor)dataEncryptor; + // data is encrypted by AEAD Encrypted Data packet (rfc4880bis10), so write v5 SKESK packet + if (isV5StyleAEAD) + { + writeOpenPGPv5ESKPacket(method, sessionInfo); + } + else // data is encrypted by v2 SEIPD (AEAD), so write v6 SKESK packet + { + writeOpenPGPv6ESKPacket(method, aeadDataEncryptor.getAEADAlgorithm(), sessionInfo); + } + } + // OpenPGP v4 + else // data is encrypted by v1 SEIPD or SED packet, so write v4 SKESK packet + { + writeOpenPGPv4ESKPacket(method, sessionInfo); } } try { - PGPDataEncryptor dataEncryptor = dataEncryptorBuilder.build(key); - - digestCalc = dataEncryptor.getIntegrityCalculator(); - + BCPGHeaderObject encOut; if (dataEncryptor instanceof PGPAEADDataEncryptor) { PGPAEADDataEncryptor encryptor = (PGPAEADDataEncryptor)dataEncryptor; - - byte[] iv = encryptor.getIV(); - - AEADEncDataPacket encOut = new AEADEncDataPacket(dataEncryptorBuilder.getAlgorithm(), encryptor.getAEADAlgorithm(), encryptor.getChunkSize(), iv); + long ivOrSaltLen; + // OpenPGP V5 style AEAD + if (isV5StyleAEAD) + { + byte[] iv = encryptor.getIV(); + encOut = new AEADEncDataPacket( + dataEncryptorBuilder.getAlgorithm(), encryptor.getAEADAlgorithm(), encryptor.getChunkSize(), iv); + ivOrSaltLen = iv.length; + } + else // OpenPGP V6 style AEAD + { + encOut = SymmetricEncIntegrityPacket.createVersion2Packet( + dataEncryptorBuilder.getAlgorithm(), + encryptor.getAEADAlgorithm(), + encryptor.getChunkSize(), + salt); + ivOrSaltLen = salt.length; + } if (buffer != null) { @@ -258,19 +312,15 @@ private OutputStream open( { long chunkLength = 1L << (encryptor.getChunkSize() + 6); long tagLengths = ((length + chunkLength - 1) / chunkLength) * 16 + 16; // data blocks + final tag - pOut = new ClosableBCPGOutputStream(out, encOut, (length + tagLengths + 4 + iv.length)); + pOut = new ClosableBCPGOutputStream(out, encOut, (length + tagLengths + 4 + ivOrSaltLen)); } - genOut = cOut = dataEncryptor.getOutputStream(pOut); - - return new WrappedGeneratorStream(genOut, this); } else { - BCPGHeaderObject encOut; if (digestCalc != null) { - encOut = new SymmetricEncIntegrityPacket(); + encOut = SymmetricEncIntegrityPacket.createVersion1Packet(); if (useOldFormat) { throw new PGPException("symmetric-enc-integrity packets not supported in old PGP format"); @@ -309,8 +359,8 @@ private OutputStream open( genOut.write(inLineIv); - return new WrappedGeneratorStream(genOut, this); } + return new WrappedGeneratorStream(genOut, this); } catch (Exception e) { @@ -318,13 +368,81 @@ private OutputStream open( } } - private void writeWrappedSessionKey(PGPKeyEncryptionMethodGenerator m, byte[] sessionInfo) + /** + * Write out a {@link org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket#VERSION_4 v4 SKESK} or + * {@link org.bouncycastle.bcpg.PublicKeyEncSessionPacket#VERSION_3 v3 PKESK} packet, + * depending on the method generator. This method is used by what can be referred to as OpenPGP v4. + * + * @param m session key encryption method generator + * @param sessionInfo session info + * @throws IOException + * @throws PGPException + */ + private void writeOpenPGPv4ESKPacket(PGPKeyEncryptionMethodGenerator m, byte[] sessionInfo) + throws IOException, PGPException + { + if (m instanceof PBEKeyEncryptionMethodGenerator) + { + PBEKeyEncryptionMethodGenerator mGen = (PBEKeyEncryptionMethodGenerator)m; + ContainedPacket esk = m.generate(mGen.getSessionKeyWrapperAlgorithm(defAlgorithm), sessionInfo); + pOut.writePacket(esk); + } + else + { + pOut.writePacket(m.generate(defAlgorithm, sessionInfo)); + } + } + + /** + * Write out a {@link org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket#VERSION_5 v5 SKESK} or + * {@link org.bouncycastle.bcpg.PublicKeyEncSessionPacket#VERSION_3 v3 PKESK} packet, + * depending on the method generator. This method is used by what can be referred to as OpenPGP v5. + * + * @param m session key encryption method generator. + * @param sessionInfo session info + * @throws IOException + * @throws PGPException + */ + private void writeOpenPGPv5ESKPacket(PGPKeyEncryptionMethodGenerator m, byte[] sessionInfo) + throws IOException, PGPException + { + if (m instanceof PBEKeyEncryptionMethodGenerator) + { + PBEKeyEncryptionMethodGenerator mGen = (PBEKeyEncryptionMethodGenerator)m; + ContainedPacket esk = m.generateV5( + mGen.getSessionKeyWrapperAlgorithm(defAlgorithm), + dataEncryptorBuilder.getAeadAlgorithm(), + sessionInfo); + pOut.writePacket(esk); + } + else + { + pOut.writePacket(m.generate(defAlgorithm, sessionInfo)); + } + } + + /** + * Write out a {@link org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket#VERSION_6 v6 SKESK} or + * {@link org.bouncycastle.bcpg.PublicKeyEncSessionPacket#VERSION_6 v6 PKESK} packet, + * depending on the method generator. This method is used by what can be referred to as OpenPGP v6. + * + * @param m session key encryption method generator. + * @param aeadAlgorithm AEAD encryption algorithm + * @param sessionInfo session info + * @throws IOException + * @throws PGPException + */ + private void writeOpenPGPv6ESKPacket(PGPKeyEncryptionMethodGenerator m, int aeadAlgorithm, byte[] sessionInfo) throws IOException, PGPException { if (m instanceof PBEKeyEncryptionMethodGenerator) { - pOut.writePacket(m.generate( - ((PBEKeyEncryptionMethodGenerator)m).getSessionKeyWrapperAlgorithm(defAlgorithm), sessionInfo)); + PBEKeyEncryptionMethodGenerator mGen = (PBEKeyEncryptionMethodGenerator)m; + ContainedPacket esk = m.generateV6( + mGen.getSessionKeyWrapperAlgorithm(defAlgorithm), + aeadAlgorithm, + sessionInfo); + pOut.writePacket(esk); } else { diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPKeyRing.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPKeyRing.java index bfafa0b737..fb12d5c11d 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPKeyRing.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPKeyRing.java @@ -10,6 +10,7 @@ import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.Packet; +import org.bouncycastle.bcpg.PacketFormat; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.SignaturePacket; import org.bouncycastle.bcpg.TrustPacket; @@ -127,16 +128,26 @@ static void readUserIDs( /** * Return an iterator containing all the public keys carrying signatures issued from key keyID. * - * @return a an iterator (possibly empty) of the public keys associated with keyID. + * @return an iterator (possibly empty) of the public keys associated with keyID. */ public abstract Iterator getKeysWithSignaturesBy(long keyID); + /** + * Return the number of keys in the key ring. + * + * @return number of keys (master key + subkey). + */ + public abstract int size(); + public abstract void encode(OutputStream outStream) throws IOException; public abstract byte[] getEncoded() throws IOException; + public abstract byte[] getEncoded(PacketFormat format) + throws IOException; + private static boolean isUserTag(int tag) { switch (tag) diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPKeyRingGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPKeyRingGenerator.java index d45f9fab53..9f8f9d0249 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPKeyRingGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPKeyRingGenerator.java @@ -268,7 +268,7 @@ public void addSubKey( // replace the public key packet structure with a public subkey one. PGPPublicKey pubSubKey = new PGPPublicKey(keyPair.getPublicKey(), null, subSigs); - pubSubKey.publicPk = new PublicSubkeyPacket(pubSubKey.getAlgorithm(), pubSubKey.getCreationTime(), pubSubKey.publicPk.getKey()); + pubSubKey.publicPk = new PublicSubkeyPacket(pubSubKey.getVersion(), pubSubKey.getAlgorithm(), pubSubKey.getCreationTime(), pubSubKey.publicPk.getKey()); keys.add(new PGPSecretKey(keyPair.getPrivateKey(), pubSubKey, checksumCalculator, keyEncryptor)); } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPObjectFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPObjectFactory.java index 4821d7408f..852fc2d0f1 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPObjectFactory.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPObjectFactory.java @@ -10,6 +10,7 @@ import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.PacketTags; +import org.bouncycastle.bcpg.UnknownPacket; import org.bouncycastle.bcpg.UnsupportedPacketVersionException; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.util.Iterable; @@ -35,7 +36,6 @@ *
    • {@link PacketTags#ONE_PASS_SIGNATURE} - produces a {@link PGPOnePassSignatureList}
    • *
    • {@link PacketTags#MARKER} - produces a {@link PGPMarker}
    • * - * */ public class PGPObjectFactory implements Iterable @@ -43,15 +43,17 @@ public class PGPObjectFactory private BCPGInputStream in; private KeyFingerPrintCalculator fingerPrintCalculator; + private boolean throwForUnknownCriticalPackets = false; + /** * Create an object factory suitable for reading PGP objects such as keys, key rings and key * ring collections, or PGP encrypted data. * - * @param in stream to read PGP data from. + * @param in stream to read PGP data from. * @param fingerPrintCalculator calculator to use in key finger print calculations. */ public PGPObjectFactory( - InputStream in, + InputStream in, KeyFingerPrintCalculator fingerPrintCalculator) { this.in = BCPGInputStream.wrap(in); @@ -62,7 +64,7 @@ public PGPObjectFactory( * Create an object factory suitable for reading PGP objects such as keys, key rings and key * ring collections, or PGP encrypted data. * - * @param bytes PGP encoded data. + * @param bytes PGP encoded data. * @param fingerPrintCalculator calculator to use in key finger print calculations. */ public PGPObjectFactory( @@ -87,6 +89,12 @@ public Object nextObject() { case -1: return null; + case PacketTags.RESERVED: + case PacketTags.EXPERIMENTAL_1: + case PacketTags.EXPERIMENTAL_2: + case PacketTags.EXPERIMENTAL_3: + case PacketTags.EXPERIMENTAL_4: + return in.readPacket(); case PacketTags.SIGNATURE: l = new ArrayList(); @@ -159,14 +167,16 @@ public Object nextObject() return new PGPMarker(in); case PacketTags.PADDING: return new PGPPadding(in); - case PacketTags.EXPERIMENTAL_1: - case PacketTags.EXPERIMENTAL_2: - case PacketTags.EXPERIMENTAL_3: - case PacketTags.EXPERIMENTAL_4: - return in.readPacket(); } - throw new IOException("unknown object in stream: " + in.nextPacketTag()); + int tag = in.nextPacketTag(); + UnknownPacket unknownPacket = (UnknownPacket)in.readPacket(); + if (throwForUnknownCriticalPackets && unknownPacket.isCritical()) + { + // Leave the error message intact for backwards compatibility + throw new IOException("unknown object in stream: " + tag); + } + return unknownPacket; } /** @@ -218,4 +228,17 @@ private Object getObject() } }; } + + /** + * If set to true, the object factory will throw an {@link IOException} if it encounters an unknown packet with a + * packet tag within the critical range (0 - 39). + * + * @param throwException whether to throw + * @return object factory + */ + public PGPObjectFactory setThrowForUnknownCriticalPackets(boolean throwException) + { + this.throwForUnknownCriticalPackets = throwException; + return this; + } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPOnePassSignature.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPOnePassSignature.java index e4b2985ad9..f7be3dee4f 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPOnePassSignature.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPOnePassSignature.java @@ -6,23 +6,23 @@ import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.BCPGOutputStream; +import org.bouncycastle.bcpg.HashUtils; import org.bouncycastle.bcpg.OnePassSignaturePacket; import org.bouncycastle.bcpg.Packet; +import org.bouncycastle.bcpg.SignaturePacket; import org.bouncycastle.openpgp.operator.PGPContentVerifier; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilder; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; +import org.bouncycastle.util.Arrays; /** * A one pass signature object. */ public class PGPOnePassSignature + extends PGPDefaultSignatureGenerator { private OnePassSignaturePacket sigPack; - private int signatureType; - private PGPContentVerifier verifier; - private byte lastb; - private OutputStream sigOut; private static OnePassSignaturePacket cast(Packet packet) throws IOException @@ -43,10 +43,11 @@ public PGPOnePassSignature( PGPOnePassSignature( OnePassSignaturePacket sigPack) - throws PGPException { + // v3 OPSs are typically used with v4 sigs + super(sigPack.getVersion() == OnePassSignaturePacket.VERSION_3 ? SignaturePacket.VERSION_4 : sigPack.getVersion()); this.sigPack = sigPack; - this.signatureType = sigPack.getSignatureType(); + this.sigType = sigPack.getSignatureType(); } /** @@ -65,97 +66,41 @@ public void init(PGPContentVerifierBuilderProvider verifierBuilderProvider, PGPP lastb = 0; sigOut = verifier.getOutputStream(); + + checkSaltSize(); + updateWithSalt(); } - public void update( - byte b) + private void checkSaltSize() + throws PGPException { - if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) + if (getVersion() != SignaturePacket.VERSION_6) { - if (b == '\r') - { - byteUpdate((byte)'\r'); - byteUpdate((byte)'\n'); - } - else if (b == '\n') - { - if (lastb != '\r') - { - byteUpdate((byte)'\r'); - byteUpdate((byte)'\n'); - } - } - else - { - byteUpdate(b); - } - - lastb = b; + return; } - else + + int expectedSaltSize = HashUtils.getV6SignatureSaltSizeInBytes(getHashAlgorithm()); + if (expectedSaltSize != getSalt().length) { - byteUpdate(b); + throw new PGPException("RFC9580 defines the salt size for " + PGPUtil.getDigestName(getHashAlgorithm()) + + " as " + expectedSaltSize + " octets, but signature has " + getSalt().length + " octets."); } } - public void update( - byte[] bytes) + private void updateWithSalt() + throws PGPException { - if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) + if (version == SignaturePacket.VERSION_6) { - for (int i = 0; i != bytes.length; i++) + try { - this.update(bytes[i]); + sigOut.write(getSalt()); } - } - else - { - blockUpdate(bytes, 0, bytes.length); - } - } - - public void update( - byte[] bytes, - int off, - int length) - { - if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) - { - int finish = off + length; - - for (int i = off; i != finish; i++) + catch (IOException e) { - this.update(bytes[i]); + throw new PGPException("Cannot salt the signature.", e); } } - else - { - blockUpdate(bytes, off, length); - } - } - - private void byteUpdate(byte b) - { - try - { - sigOut.write(b); - } - catch (IOException e) - { - throw new PGPRuntimeOperationException(e.getMessage(), e); - } - } - - private void blockUpdate(byte[] block, int off, int len) - { - try - { - sigOut.write(block, off, len); - } - catch (IOException e) - { - throw new PGPRuntimeOperationException(e.getMessage(), e); - } } /** @@ -169,6 +114,8 @@ public boolean verify( PGPSignature pgpSig) throws PGPException { + compareSalt(pgpSig); + try { sigOut.write(pgpSig.getSignatureTrailer()); @@ -183,11 +130,60 @@ public boolean verify( return verifier.verify(pgpSig.getSignature()); } + private void compareSalt(PGPSignature signature) + throws PGPException + { + if (version != SignaturePacket.VERSION_6) + { + return; + } + if (!Arrays.constantTimeAreEqual(getSalt(), signature.getSalt())) + { + throw new PGPException("Salt in OnePassSignaturePacket does not match salt in SignaturePacket."); + } + } + + /** + * Return the packet version. + * + * @return packet version + */ + public int getVersion() + { + return sigPack.getVersion(); + } + + /** + * Return the key-ID of the issuer signing key. + * For {@link OnePassSignaturePacket#VERSION_6} packets, the key-ID is derived from the fingerprint. + * + * @return key-ID + */ public long getKeyID() { return sigPack.getKeyID(); } + /** + * Return the issuer key fingerprint. + * Only for {@link OnePassSignaturePacket#VERSION_6} packets. + * @return fingerprint + */ + public byte[] getFingerprint() + { + return sigPack.getFingerprint(); + } + + /** + * Return the salt used in the corresponding signature. + * Only for {@link OnePassSignaturePacket#VERSION_6} packets. + * @return salt + */ + public byte[] getSalt() + { + return sigPack.getSalt(); + } + public int getSignatureType() { return sigPack.getSignatureType(); diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPPBEEncryptedData.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPPBEEncryptedData.java index 0d684edd8e..f1da71c928 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPPBEEncryptedData.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPPBEEncryptedData.java @@ -3,8 +3,11 @@ import java.io.InputStream; import org.bouncycastle.bcpg.InputStreamPacket; +import org.bouncycastle.bcpg.SymmetricEncDataPacket; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket; +import org.bouncycastle.bcpg.UnsupportedPacketVersionException; import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory; import org.bouncycastle.openpgp.operator.SessionKeyDataDecryptorFactory; import org.bouncycastle.util.Arrays; @@ -17,7 +20,7 @@ *

      */ public class PGPPBEEncryptedData - extends PGPSymmetricKeyEncryptedData + extends PGPSymmetricKeyEncryptedData { SymmetricKeyEncSessionPacket keyData; @@ -29,12 +32,78 @@ public class PGPPBEEncryptedData * @param encData the encrypted data. */ PGPPBEEncryptedData( - SymmetricKeyEncSessionPacket keyData, - InputStreamPacket encData) + SymmetricKeyEncSessionPacket keyData, + InputStreamPacket encData) { super(encData); this.keyData = keyData; + + enforceConstraints(keyData, encData); + } + + private static void enforceConstraints(SymmetricKeyEncSessionPacket keyData, InputStreamPacket encData) + { + switch (keyData.getVersion()) + { + case SymmetricKeyEncSessionPacket.VERSION_4: + if (encData instanceof SymmetricEncDataPacket) + { + return; + } + + if (encData instanceof SymmetricEncIntegrityPacket) + { + SymmetricEncIntegrityPacket seipd = (SymmetricEncIntegrityPacket) encData; + if (seipd.getVersion() == SymmetricEncIntegrityPacket.VERSION_1) + { + return; + } + + // V2 SEIPD cannot be preceded by V4 SKESK + throw new IllegalArgumentException("Version 4 SKESK cannot precede SEIPD of version " + seipd.getVersion()); + } + + case SymmetricKeyEncSessionPacket.VERSION_5: + // https://www.ietf.org/archive/id/draft-koch-openpgp-2015-rfc4880bis-01.html does not state any constraints + break; + + case SymmetricKeyEncSessionPacket.VERSION_6: + // V6 SKESK MUST be followed by v2 SEIPD + if (!(encData instanceof SymmetricEncIntegrityPacket)) + { + throw new IllegalArgumentException("Version 6 SKESK MUST be followed only by SEIPD version 2"); + } + + SymmetricEncIntegrityPacket seipd = (SymmetricEncIntegrityPacket) encData; + if (seipd.getVersion() != SymmetricEncIntegrityPacket.VERSION_2) + { + throw new IllegalArgumentException("Version 6 SKESK MUST be followed only by SEIPD version 2"); + } + } + if (encData instanceof SymmetricEncDataPacket) + { + if (keyData.getVersion() != SymmetricKeyEncSessionPacket.VERSION_4) + { + throw new IllegalArgumentException("Version of SKESK packet preceding a SED packet can only be 4."); + } + } + + if (encData instanceof SymmetricEncIntegrityPacket) + { + SymmetricEncIntegrityPacket seipd = (SymmetricEncIntegrityPacket) encData; + if (keyData.getVersion() == SymmetricKeyEncSessionPacket.VERSION_4 && + seipd.getVersion() != SymmetricEncIntegrityPacket.VERSION_1) + { + throw new IllegalArgumentException("Version 4 SKESK can only precede version 1 SEIPD."); + } + + if (keyData.getVersion() == SymmetricKeyEncSessionPacket.VERSION_6 && + seipd.getVersion() == SymmetricEncIntegrityPacket.VERSION_1) + { + throw new IllegalArgumentException("Version 6 SKESK packet MUST NOT precede a V1 SEIPD packet."); + } + } } public int getVersion() @@ -61,13 +130,26 @@ public int getAlgorithm() * @throws PGPException if the session data cannot be recovered. */ public int getSymmetricAlgorithm( - PBEDataDecryptorFactory dataDecryptorFactory) - throws PGPException + PBEDataDecryptorFactory dataDecryptorFactory) + throws PGPException { - byte[] key = dataDecryptorFactory.makeKeyFromPassPhrase(keyData.getEncAlgorithm(), keyData.getS2K()); - byte[] sessionData = dataDecryptorFactory.recoverSessionData(keyData.getEncAlgorithm(), key, keyData.getSecKeyData()); + if (keyData.getVersion() == SymmetricKeyEncSessionPacket.VERSION_4) + { + // SKESK v4 stores cipher algorithm inside the encrypted session data + byte[] key = dataDecryptorFactory.makeKeyFromPassPhrase(keyData.getEncAlgorithm(), keyData.getS2K()); + byte[] sessionData = dataDecryptorFactory.recoverSessionData(keyData.getEncAlgorithm(), key, keyData.getSecKeyData()); - return sessionData[0]; + return sessionData[0]; + } + else if (keyData.getVersion() == SymmetricKeyEncSessionPacket.VERSION_5) + { + return keyData.getEncAlgorithm(); + } + else // keyData.getVersion() == 5+ + { + // SKESK v6 stores the cipher algorithm in the SEIPD v2 packet fields. + return ((SymmetricEncIntegrityPacket) encData).getCipherAlgorithm(); + } } /** @@ -78,12 +160,28 @@ public int getSymmetricAlgorithm( * @throws PGPException if the session data cannot be recovered */ public PGPSessionKey getSessionKey(PBEDataDecryptorFactory dataDecryptorFactory) - throws PGPException + throws PGPException { byte[] key = dataDecryptorFactory.makeKeyFromPassPhrase(keyData.getEncAlgorithm(), keyData.getS2K()); - byte[] sessionData = dataDecryptorFactory.recoverSessionData(keyData.getEncAlgorithm(), key, keyData.getSecKeyData()); - return new PGPSessionKey(sessionData[0] & 0xff, Arrays.copyOfRange(sessionData, 1, sessionData.length)); + int version = getVersion(); + if (version == SymmetricKeyEncSessionPacket.VERSION_4) + { + byte[] sessionData = dataDecryptorFactory.recoverSessionData(keyData.getEncAlgorithm(), key, keyData.getSecKeyData()); + int sessionKeyAlg = sessionData[0] & 0xff; + byte[] sessionKey = Arrays.copyOfRange(sessionData, 1, sessionData.length); + return new PGPSessionKey(sessionKeyAlg, sessionKey); + } + else if (version == SymmetricKeyEncSessionPacket.VERSION_5 || version == SymmetricKeyEncSessionPacket.VERSION_6) + { + int sessionKeyAlg = getSymmetricAlgorithm(dataDecryptorFactory); + byte[] sessionKey = dataDecryptorFactory.recoverAEADEncryptedSessionData(keyData, key); + return new PGPSessionKey(sessionKeyAlg, sessionKey); + } + else + { + throw new UnsupportedPacketVersionException("Unsupported packet version: " + version); + } } /** @@ -96,15 +194,13 @@ public PGPSessionKey getSessionKey(PBEDataDecryptorFactory dataDecryptorFactory) * @throws PGPException if the session data cannot be recovered or the stream cannot be created. */ public InputStream getDataStream( - PBEDataDecryptorFactory dataDecryptorFactory) - throws PGPException + PBEDataDecryptorFactory dataDecryptorFactory) + throws PGPException { try { PGPSessionKey sessionKey = getSessionKey(dataDecryptorFactory); - encStream = createDecryptionStream(dataDecryptorFactory, sessionKey); - return encStream; } catch (PGPException e) @@ -121,8 +217,8 @@ public InputStream getDataStream( * @deprecated will be removed in 1.74, use PGPEncryptedDataList.extractSessionKeyEncryptedData() and then apply the dataDecryptorFactory. */ public InputStream getDataStream( - SessionKeyDataDecryptorFactory dataDecryptorFactory) - throws PGPException + SessionKeyDataDecryptorFactory dataDecryptorFactory) + throws PGPException { try { diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPPadding.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPPadding.java index 7661f38837..8582a247a0 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPPadding.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPPadding.java @@ -1,10 +1,16 @@ package org.bouncycastle.openpgp; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.OutputStream; +import java.security.SecureRandom; import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.Packet; +import org.bouncycastle.bcpg.PacketFormat; import org.bouncycastle.bcpg.PaddingPacket; +import org.bouncycastle.crypto.CryptoServicesRegistrar; /** * The PGPPadding contains random data, and can be used to defend against traffic analysis on version 2 SEIPD messages @@ -16,10 +22,25 @@ public class PGPPadding { private PaddingPacket p; + /** + * Minimum random padding length in octets. + * Chosen totally arbitrarily. + */ + public static final int MIN_PADDING_LEN = 16; + + /** + * Maximum random padding length. + * Chosen somewhat arbitrarily, as SSH also uses max 255 bytes for random padding. + * + * @see + * rfc4253 - Binary Packet Protocol + */ + public static final int MAX_PADDING_LEN = 255; + /** * Default constructor. * - * @param in + * @param in packet input stream * @throws IOException */ public PGPPadding( @@ -34,8 +55,78 @@ public PGPPadding( p = (PaddingPacket)packet; } + /** + * Generate a new, random {@link PGPPadding} object. + * The padding consists of n random bytes, where n is a number between (inclusive) {@link #MIN_PADDING_LEN} + * and {@link #MAX_PADDING_LEN}. + */ + public PGPPadding() + { + this(CryptoServicesRegistrar.getSecureRandom()); + } + + /** + * Generate a new, random {@link PGPPadding} object. + * The padding consists of n random bytes, where n is a number between (inclusive) {@link #MIN_PADDING_LEN} + * and {@link #MAX_PADDING_LEN}. + * + * @param random random number generator instance + */ + public PGPPadding(SecureRandom random) + { + this(MIN_PADDING_LEN + random.nextInt(MAX_PADDING_LEN - MIN_PADDING_LEN + 1), random); + } + + /** + * Generate a new, random {@link PGPPadding} object. + * The padding consists of
      len
      random bytes. + */ + public PGPPadding(int len) + { + this(len, CryptoServicesRegistrar.getSecureRandom()); + } + + /** + * Generate a new, random {@link PGPPadding} object. + * The padding consists of
      len
      random bytes. + * + * @param len number of random octets + * @param random random number generator instance + */ + public PGPPadding(int len, SecureRandom random) + { + this.p = new PaddingPacket(len, random); + } + + /** + * Return the padding octets as a byte array. + * @return padding octets + */ public byte[] getPadding() { return p.getPadding(); } + + public void encode(OutputStream outStream) + throws IOException + { + BCPGOutputStream pOut = BCPGOutputStream.wrap(outStream); + p.encode(pOut); + } + + public byte[] getEncoded() + throws IOException + { + return getEncoded(PacketFormat.ROUNDTRIP); + } + + public byte[] getEncoded(PacketFormat format) + throws IOException + { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, format); + encode(pOut); + pOut.close(); + return bOut.toByteArray(); + } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKey.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKey.java index 04fc36b412..2c788db3df 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKey.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKey.java @@ -9,6 +9,7 @@ import java.util.List; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; import org.bouncycastle.asn1.gnu.GNUObjectIdentifiers; import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X9ECParametersHolder; @@ -28,6 +29,7 @@ import org.bouncycastle.bcpg.UserIDPacket; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Pack; /** * general class to handle a PGP public key object. @@ -57,24 +59,25 @@ private void init(KeyFingerPrintCalculator fingerPrintCalculator) this.fingerprint = fingerPrintCalculator.calculateFingerprint(publicPk); - if (publicPk.getVersion() <= 3) + if (publicPk.getVersion() <= PublicKeyPacket.VERSION_3) { RSAPublicBCPGKey rK = (RSAPublicBCPGKey)key; this.keyID = rK.getModulus().longValue(); this.keyStrength = rK.getModulus().bitLength(); } - else + else if (publicPk.getVersion() == PublicKeyPacket.VERSION_4) + { + this.keyID = Pack.bigEndianToLong(fingerprint, fingerprint.length - 8); + } + else if (publicPk.getVersion() == PublicKeyPacket.VERSION_6) { - this.keyID = ((long)(fingerprint[fingerprint.length - 8] & 0xff) << 56) - | ((long)(fingerprint[fingerprint.length - 7] & 0xff) << 48) - | ((long)(fingerprint[fingerprint.length - 6] & 0xff) << 40) - | ((long)(fingerprint[fingerprint.length - 5] & 0xff) << 32) - | ((long)(fingerprint[fingerprint.length - 4] & 0xff) << 24) - | ((long)(fingerprint[fingerprint.length - 3] & 0xff) << 16) - | ((long)(fingerprint[fingerprint.length - 2] & 0xff) << 8) - | ((fingerprint[fingerprint.length - 1] & 0xff)); + this.keyID = Pack.bigEndianToLong(fingerprint, 0); + } + // key strength + if (publicPk.getVersion() >= PublicKeyPacket.VERSION_4) + { if (key instanceof RSAPublicBCPGKey) { this.keyStrength = ((RSAPublicBCPGKey)key).getModulus().bitLength(); @@ -255,7 +258,7 @@ public Date getCreationTime() */ public int getValidDays() { - if (publicPk.getVersion() > 3) + if (publicPk.getVersion() > PublicKeyPacket.VERSION_3) { long delta = this.getValidSeconds() % (24 * 60 * 60); int days = (int)(this.getValidSeconds() / (24 * 60 * 60)); @@ -296,7 +299,7 @@ public byte[] getTrustData() */ public long getValidSeconds() { - if (publicPk.getVersion() > 3) + if (publicPk.getVersion() > PublicKeyPacket.VERSION_3) { if (this.isMasterKey()) { @@ -399,11 +402,12 @@ public long getKeyID() */ public byte[] getFingerprint() { - byte[] tmp = new byte[fingerprint.length]; - - System.arraycopy(fingerprint, 0, tmp, 0, tmp.length); + return Arrays.clone(fingerprint); + } - return tmp; + public boolean hasFingerprint(byte[] fingerprint) + { + return Arrays.areEqual(this.fingerprint, fingerprint); } /** @@ -420,7 +424,7 @@ public boolean isEncryptionKey() return ((algorithm == RSA_GENERAL) || (algorithm == RSA_ENCRYPT) || (algorithm == ELGAMAL_ENCRYPT) || (algorithm == ELGAMAL_GENERAL) - || (algorithm == DIFFIE_HELLMAN) || (algorithm == ECDH)); + || (algorithm == DIFFIE_HELLMAN) || (algorithm == ECDH) || (algorithm == X448) || (algorithm == X25519)); } /** @@ -509,7 +513,7 @@ public Iterator getUserAttributes() { if (ids.get(i) instanceof PGPUserAttributeSubpacketVector) { - temp.add((PGPUserAttributeSubpacketVector) ids.get(i)); + temp.add((PGPUserAttributeSubpacketVector)ids.get(i)); } } @@ -733,10 +737,7 @@ public void encode(OutputStream outStream, boolean forTransfer) if (subSigs == null) // not a sub-key { - for (int i = 0; i != keySigs.size(); i++) - { - ((PGPSignature)keySigs.get(i)).encode(out); - } + Util.encodePGPSignatures(out, keySigs, false); for (int i = 0; i != ids.size(); i++) { @@ -759,18 +760,12 @@ public void encode(OutputStream outStream, boolean forTransfer) } List sigs = (List)idSigs.get(i); - for (int j = 0; j != sigs.size(); j++) - { - ((PGPSignature)sigs.get(j)).encode(out, forTransfer); - } + Util.encodePGPSignatures(out, sigs, forTransfer); } } else { - for (int j = 0; j != subSigs.size(); j++) - { - ((PGPSignature)subSigs.get(j)).encode(out, forTransfer); - } + Util.encodePGPSignatures(out, subSigs, forTransfer); } } @@ -1133,28 +1128,7 @@ public static PGPPublicKey join( } // key signatures - for (Iterator it = copy.keySigs.iterator(); it.hasNext();) - { - PGPSignature keySig = (PGPSignature)it.next(); - boolean found = false; - for (int i = 0; i < keySigs.size(); i++) - { - PGPSignature existingKeySig = (PGPSignature)keySigs.get(i); - if (PGPSignature.isSignatureEncodingEqual(existingKeySig, keySig)) - { - found = true; - // join existing sig with copy to apply modifications in unhashed subpackets - existingKeySig = PGPSignature.join(existingKeySig, keySig); - keySigs.set(i, existingKeySig); - break; - } - } - if (found) - { - break; - } - keySigs.add(keySig); - } + joinPgpSignatureList(copy.keySigs, keySigs, true, true); // user-ids and id sigs for (int idIdx = 0; idIdx < copy.ids.size(); idIdx++) @@ -1194,27 +1168,7 @@ public static PGPPublicKey join( } List existingIdSigs = (List)idSigs.get(existingIdIndex); - for (Iterator it = copyIdSigs.iterator(); it.hasNext();) - { - PGPSignature newSig = (PGPSignature)it.next(); - boolean found = false; - for (int i = 0; i < existingIdSigs.size(); i++) - { - PGPSignature existingSig = (PGPSignature)existingIdSigs.get(i); - if (PGPSignature.isSignatureEncodingEqual(newSig, existingSig)) - { - found = true; - // join existing sig with copy to apply modifications in unhashed subpackets - existingSig = PGPSignature.join(existingSig, newSig); - existingIdSigs.set(i, existingSig); - break; - } - } - if (!found) - { - existingIdSigs.add(newSig); - } - } + joinPgpSignatureList(copyIdSigs, existingIdSigs, false, true); } // subSigs @@ -1226,27 +1180,7 @@ public static PGPPublicKey join( } else { - for (Iterator it = copy.subSigs.iterator(); it.hasNext();) - { - PGPSignature copySubSig = (PGPSignature)it.next(); - boolean found = false; - for (int i = 0; subSigs != null && i < subSigs.size(); i++) - { - PGPSignature existingSubSig = (PGPSignature)subSigs.get(i); - if (PGPSignature.isSignatureEncodingEqual(existingSubSig, copySubSig)) - { - found = true; - // join existing sig with copy to apply modifications in unhashed subpackets - existingSubSig = PGPSignature.join(existingSubSig, copySubSig); - subSigs.set(i, existingSubSig); - break; - } - } - if (!found && subSigs != null) - { - subSigs.add(copySubSig); - } - } + joinPgpSignatureList(copy.subSigs, subSigs, false, subSigs != null); } } @@ -1255,4 +1189,37 @@ public static PGPPublicKey join( return merged; } + + private static void joinPgpSignatureList(List source, + List rlt, + boolean needBreak, + boolean isNotNull) + throws PGPException + { + for (Iterator it = source.iterator(); it.hasNext(); ) + { + PGPSignature copySubSig = (PGPSignature)it.next(); + boolean found = false; + for (int i = 0; isNotNull && i < rlt.size(); i++) + { + PGPSignature existingSubSig = (PGPSignature)rlt.get(i); + if (PGPSignature.isSignatureEncodingEqual(existingSubSig, copySubSig)) + { + found = true; + // join existing sig with copy to apply modifications in unhashed subpackets + existingSubSig = PGPSignature.join(existingSubSig, copySubSig); + rlt.set(i, existingSubSig); + break; + } + } + if (found && needBreak) + { + break; + } + else if (!found && isNotNull) + { + rlt.add(copySubSig); + } + } + } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java index e16180eb9e..792bd3ef19 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java @@ -1,20 +1,20 @@ package org.bouncycastle.openpgp; -import java.io.EOFException; import java.io.InputStream; import org.bouncycastle.bcpg.AEADEncDataPacket; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.InputStreamPacket; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyEncSessionPacket; import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.UnsupportedPacketVersionException; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PGPDataDecryptorFactory; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.SessionKeyDataDecryptorFactory; import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.io.TeeInputStream; /** * A public key encrypted data object. @@ -22,6 +22,7 @@ public class PGPPublicKeyEncryptedData extends PGPEncryptedData { + PublicKeyEncSessionPacket keyData; PGPPublicKeyEncryptedData( @@ -69,9 +70,21 @@ public int getSymmetricAlgorithm( PublicKeyDataDecryptorFactory dataDecryptorFactory) throws PGPException { - byte[] plain = dataDecryptorFactory.recoverSessionData(keyData.getAlgorithm(), keyData.getEncSessionKey()); - - return plain[0]; + if (keyData.getVersion() == PublicKeyEncSessionPacket.VERSION_3) + { + byte[] plain = dataDecryptorFactory.recoverSessionData(keyData.getAlgorithm(), keyData.getEncSessionKey()); + // symmetric cipher algorithm is stored in first octet of session data + return plain[0]; + } + else if (keyData.getVersion() == PublicKeyEncSessionPacket.VERSION_6) + { + // PKESK v5 stores the cipher algorithm in the SEIPD v2 packet fields. + return ((SymmetricEncIntegrityPacket)encData).getCipherAlgorithm(); + } + else + { + throw new UnsupportedPacketVersionException("Unsupported packet version: " + keyData.getVersion()); + } } /** @@ -86,11 +99,14 @@ public PGPSessionKey getSessionKey( throws PGPException { byte[] sessionData = dataDecryptorFactory.recoverSessionData(keyData.getAlgorithm(), keyData.getEncSessionKey()); + if (keyData.getAlgorithm() == PublicKeyAlgorithmTags.X25519 || keyData.getAlgorithm() == PublicKeyAlgorithmTags.X448) + { + return new PGPSessionKey(sessionData[0] & 0xff, Arrays.copyOfRange(sessionData, 1, sessionData.length)); + } if (!confirmCheckSum(sessionData)) { throw new PGPKeyValidationException("key checksum failed"); } - return new PGPSessionKey(sessionData[0] & 0xff, Arrays.copyOfRange(sessionData, 1, sessionData.length - 2)); } @@ -135,6 +151,7 @@ private InputStream getDataStream( { try { + // OpenPGP V5 style AEAD if (encData instanceof AEADEncDataPacket) { AEADEncDataPacket aeadData = (AEADEncDataPacket)encData; @@ -144,7 +161,7 @@ private InputStream getDataStream( throw new PGPException("session key and AEAD algorithm mismatch"); } - PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(aeadData.getAEADAlgorithm(), aeadData.getIV(), aeadData.getChunkSize(), sessionKey.getAlgorithm(), sessionKey.getKey()); + PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(aeadData, sessionKey); BCPGInputStream encIn = encData.getInputStream(); @@ -158,38 +175,7 @@ private InputStream getDataStream( BCPGInputStream encIn = encData.getInputStream(); - encStream = new BCPGInputStream(dataDecryptor.getInputStream(encIn)); - - if (withIntegrityPacket) - { - truncStream = new TruncatedStream(encStream); - - integrityCalculator = dataDecryptor.getIntegrityCalculator(); - - encStream = new TeeInputStream(truncStream, integrityCalculator.getOutputStream()); - } - - byte[] iv = new byte[dataDecryptor.getBlockSize()]; - - for (int i = 0; i != iv.length; i++) - { - int ch = encStream.read(); - - if (ch < 0) - { - throw new EOFException("unexpected end of stream."); - } - - iv[i] = (byte)ch; - } - - int v1 = encStream.read(); - int v2 = encStream.read(); - - if (v1 < 0 || v2 < 0) - { - throw new EOFException("unexpected end of stream."); - } + processSymmetricEncIntegrityPacketDataStream(withIntegrityPacket, dataDecryptor, encIn); // // some versions of PGP appear to produce 0 for the extra diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyRing.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyRing.java index 1b52f4945d..9cd941e224 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyRing.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyRing.java @@ -17,13 +17,14 @@ import org.bouncycastle.bcpg.ArmoredInputException; import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.Packet; +import org.bouncycastle.bcpg.PacketFormat; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.TrustPacket; import org.bouncycastle.bcpg.UserDataPacket; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; -import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Iterable; import org.bouncycastle.util.Longs; @@ -184,7 +185,7 @@ public PGPPublicKey getPublicKey(byte[] fingerprint) { PGPPublicKey k = (PGPPublicKey)keys.get(i); - if (Arrays.areEqual(fingerprint, k.getFingerprint())) + if (k.hasFingerprint(fingerprint)) { return k; } @@ -239,10 +240,16 @@ public Iterator iterator() public byte[] getEncoded() throws IOException { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - this.encode(bOut); + return getEncoded(PacketFormat.ROUNDTRIP); + } + @Override + public byte[] getEncoded(PacketFormat format) throws IOException + { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, format); + this.encode(pOut); + pOut.close(); return bOut.toByteArray(); } @@ -263,6 +270,16 @@ public byte[] getEncoded(boolean forTransfer) return bOut.toByteArray(); } + /** + * Return the number of keys in the key ring. + * + * @return number of keys (master key + subkey). + */ + public int size() + { + return keys.size(); + } + public void encode( OutputStream outStream) throws IOException @@ -468,7 +485,7 @@ public static PGPPublicKeyRing join( boolean allowSubkeySigsOnNonSubkey) throws PGPException { - if (!Arrays.areEqual(first.getPublicKey().getFingerprint(), second.getPublicKey().getFingerprint())) + if (!second.getPublicKey().hasFingerprint(first.getPublicKey().getFingerprint())) { throw new IllegalArgumentException("Cannot merge certificates with differing primary keys."); } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyRingCollection.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyRingCollection.java index f13b4742ad..52a232a3ab 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyRingCollection.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyRingCollection.java @@ -278,7 +278,7 @@ public PGPPublicKey getPublicKey( } /** - * Return the PGP public key associated with the given key fingerprint. + * Return the public key ring which contains the key associated with the given key fingerprint. * * @param fingerprint the public key fingerprint to match against. * @return the PGP public key ring containing the PGP public key matching fingerprint. diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKey.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKey.java index a3613d6c9b..ed1e900759 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKey.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKey.java @@ -14,6 +14,8 @@ import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.DSASecretBCPGKey; import org.bouncycastle.bcpg.ECSecretBCPGKey; +import org.bouncycastle.bcpg.Ed25519SecretBCPGKey; +import org.bouncycastle.bcpg.Ed448SecretBCPGKey; import org.bouncycastle.bcpg.EdSecretBCPGKey; import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; import org.bouncycastle.bcpg.HashAlgorithmTags; @@ -29,6 +31,8 @@ import org.bouncycastle.bcpg.TrustPacket; import org.bouncycastle.bcpg.UserAttributePacket; import org.bouncycastle.bcpg.UserIDPacket; +import org.bouncycastle.bcpg.X25519SecretBCPGKey; +import org.bouncycastle.bcpg.X448SecretBCPGKey; import org.bouncycastle.gpg.SExprParser; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory; @@ -92,19 +96,20 @@ private static PGPPublicKey buildPublicKey(boolean isMasterKey, PGPPublicKey pub PublicKeyPacket pubPacket = pubKey.publicPk; // make sure we can actually do what's wanted - if (isMasterKey && !(pubKey.isEncryptionKey() && pubPacket.getAlgorithm() != PublicKeyAlgorithmTags.RSA_GENERAL)) - { - PGPPublicKey mstKey = new PGPPublicKey(pubKey); - mstKey.publicPk = new PublicKeyPacket(pubPacket.getAlgorithm(), pubPacket.getTime(), pubPacket.getKey()); - return mstKey; - } - else - { - PGPPublicKey subKey = new PGPPublicKey(pubKey); - subKey.publicPk = new PublicSubkeyPacket(pubPacket.getAlgorithm(), pubPacket.getTime(), pubPacket.getKey()); - return subKey; - } + if (isMasterKey && !(pubKey.isEncryptionKey() && pubPacket.getAlgorithm() != PublicKeyAlgorithmTags.RSA_GENERAL)) + { + PGPPublicKey mstKey = new PGPPublicKey(pubKey); + mstKey.publicPk = new PublicKeyPacket(pubPacket.getVersion(), pubPacket.getAlgorithm(), pubPacket.getTime(), pubPacket.getKey()); + return mstKey; + } + else + { + PGPPublicKey subKey = new PGPPublicKey(pubKey); + subKey.publicPk = new PublicSubkeyPacket(pubPacket.getVersion(), pubPacket.getAlgorithm(), pubPacket.getTime(), pubPacket.getKey()); + return subKey; + } } + private static SecretKeyPacket buildSecretKeyPacket(boolean isMasterKey, PGPPrivateKey privKey, PGPPublicKey pubKey, PBESecretKeyEncryptor keyEncryptor, PGPDigestCalculator checksumCalculator) throws PGPException { @@ -112,14 +117,7 @@ private static SecretKeyPacket buildSecretKeyPacket(boolean isMasterKey, PGPPriv if (secKey == null) { - if (isMasterKey) - { - return new SecretKeyPacket(pubKey.publicPk, SymmetricKeyAlgorithmTags.NULL, null, null, new byte[0]); - } - else - { - return new SecretSubkeyPacket(pubKey.publicPk, SymmetricKeyAlgorithmTags.NULL, null, null, new byte[0]); - } + return generateSecretKeyPacket(isMasterKey, pubKey.publicPk, SymmetricKeyAlgorithmTags.NULL, new byte[0]); } try @@ -145,6 +143,11 @@ private static SecretKeyPacket buildSecretKeyPacket(boolean isMasterKey, PGPPriv S2K s2k = keyEncryptor.getS2K(); int s2kUsage; + if (keyEncryptor.getAeadAlgorithm() != 0) + { + s2kUsage = SecretKeyPacket.USAGE_AEAD; + return generateSecretKeyPacket(isMasterKey, pubKey.publicPk, encAlgorithm, keyEncryptor.getAeadAlgorithm(), s2kUsage, s2k, iv, encData); + } if (checksumCalculator != null) { @@ -159,28 +162,13 @@ private static SecretKeyPacket buildSecretKeyPacket(boolean isMasterKey, PGPPriv s2kUsage = SecretKeyPacket.USAGE_CHECKSUM; } - if (isMasterKey) - { - return new SecretKeyPacket(pubKey.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); - } - else - { - return new SecretSubkeyPacket(pubKey.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); - } + return generateSecretKeyPacket(isMasterKey, pubKey.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); } - else + else if (pubKey.getVersion() != PublicKeyPacket.VERSION_6) { pOut.write(checksum(null, keyData, keyData.length)); - - if (isMasterKey) - { - return new SecretKeyPacket(pubKey.publicPk, encAlgorithm, null, null, bOut.toByteArray()); - } - else - { - return new SecretSubkeyPacket(pubKey.publicPk, encAlgorithm, null, null, bOut.toByteArray()); - } } + return generateSecretKeyPacket(isMasterKey, pubKey.publicPk, encAlgorithm, bOut.toByteArray()); } catch (PGPException e) { @@ -192,6 +180,42 @@ private static SecretKeyPacket buildSecretKeyPacket(boolean isMasterKey, PGPPriv } } + private static SecretKeyPacket generateSecretKeyPacket(boolean isMasterKey, PublicKeyPacket pubKey, int encAlgorithm, byte[] secKeyData) + { + if (isMasterKey) + { + return new SecretKeyPacket(pubKey, encAlgorithm, null, null, secKeyData); + } + else + { + return new SecretSubkeyPacket(pubKey, encAlgorithm, null, null, secKeyData); + } + } + + private static SecretKeyPacket generateSecretKeyPacket(boolean isMasterKey, PublicKeyPacket pubKey, int encAlgorithm, int s2kusage, S2K s2k, byte[] iv, byte[] secKeyData) + { + if (isMasterKey) + { + return new SecretKeyPacket(pubKey, encAlgorithm, s2kusage, s2k, iv, secKeyData); + } + else + { + return new SecretSubkeyPacket(pubKey, encAlgorithm, s2kusage, s2k, iv, secKeyData); + } + } + + private static SecretKeyPacket generateSecretKeyPacket(boolean isMasterKey, PublicKeyPacket pubKey, int encAlgorithm, int aeadAlgorithm, int s2kUsage, S2K s2K, byte[] iv, byte[] secKeyData) + { + if (isMasterKey) + { + return new SecretKeyPacket(pubKey, encAlgorithm, aeadAlgorithm, s2kUsage, s2K, iv, secKeyData); + } + else + { + return new SecretSubkeyPacket(pubKey, encAlgorithm, aeadAlgorithm, s2kUsage, s2K, iv, secKeyData); + } + } + /** * Construct a PGPSecretKey using the passed in private/public key pair and binding it to the passed in id * using a generated certification of certificationLevel.The secret key checksum is calculated using the original @@ -309,7 +333,7 @@ else if (!hashedPcks.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) // replace the public key packet structure with a public subkey one. PGPPublicKey pubSubKey = new PGPPublicKey(keyPair.getPublicKey(), null, subSigs); - pubSubKey.publicPk = new PublicSubkeyPacket(pubSubKey.getAlgorithm(), pubSubKey.getCreationTime(), pubSubKey.publicPk.getKey()); + pubSubKey.publicPk = new PublicSubkeyPacket(pubSubKey.getVersion(), pubSubKey.getAlgorithm(), pubSubKey.getCreationTime(), pubSubKey.publicPk.getKey()); this.pub = pubSubKey; this.secret = buildSecretKeyPacket(false, keyPair.getPrivateKey(), keyPair.getPublicKey(), keyEncryptor, checksumCalculator); @@ -396,7 +420,8 @@ public boolean isSigningKey() int algorithm = pub.getAlgorithm(); return ((algorithm == PGPPublicKey.RSA_GENERAL) || (algorithm == PGPPublicKey.RSA_SIGN) - || (algorithm == PGPPublicKey.DSA) || (algorithm == PGPPublicKey.ECDSA) || (algorithm == PGPPublicKey.EDDSA_LEGACY) || (algorithm == PGPPublicKey.ELGAMAL_GENERAL)); + || (algorithm == PGPPublicKey.DSA) || (algorithm == PGPPublicKey.ECDSA) || (algorithm == PGPPublicKey.EDDSA_LEGACY) + || (algorithm == PGPPublicKey.ELGAMAL_GENERAL) || (algorithm == PGPPublicKey.Ed448) || (algorithm == PGPPublicKey.Ed25519)); } /** @@ -431,6 +456,16 @@ public int getKeyEncryptionAlgorithm() return secret.getEncAlgorithm(); } + /** + * Return the AEAD algorithm the key is encrypted with. + * Returns
      0
      if no AEAD is used. + * @return aead key encryption algorithm + */ + public int getAEADKeyEncryptionAlgorithm() + { + return secret.getAeadAlgorithm(); + } + /** * Return the keyID of the public key associated with this key. * @@ -512,23 +547,37 @@ private byte[] extractKeyData( { try { - if (secret.getPublicKeyPacket().getVersion() == 4) + byte[] key = decryptorFactory.makeKeyFromPassPhrase(secret.getEncAlgorithm(), secret.getS2K()); + if (secret.getPublicKeyPacket().getVersion() >= PublicKeyPacket.VERSION_4) { - byte[] key = decryptorFactory.makeKeyFromPassPhrase(secret.getEncAlgorithm(), secret.getS2K()); - - data = decryptorFactory.recoverKeyData(secret.getEncAlgorithm(), key, secret.getIV(), encData, 0, encData.length); + if (secret.getS2KUsage() == SecretKeyPacket.USAGE_AEAD) + { + // privKey := AEAD(HKDF(S2K(passphrase), info), secrets, packetprefix) + return decryptorFactory.recoverKeyData( + secret.getEncAlgorithm(), + secret.getAeadAlgorithm(), + key, // s2k output = ikm for hkdf + secret.getIV(), // iv = aead nonce + secret.getPacketTag(), + secret.getPublicKeyPacket().getVersion(), + secret.getSecretKeyData(), + secret.getPublicKeyPacket().getEncodedContents()); + } + else + { + data = decryptorFactory.recoverKeyData(secret.getEncAlgorithm(), key, secret.getIV(), encData, 0, encData.length); - boolean useSHA1 = secret.getS2KUsage() == SecretKeyPacket.USAGE_SHA1; - byte[] check = checksum(useSHA1 ? decryptorFactory.getChecksumCalculator(HashAlgorithmTags.SHA1) : null, data, (useSHA1) ? data.length - 20 : data.length - 2); + boolean useSHA1 = secret.getS2KUsage() == SecretKeyPacket.USAGE_SHA1; + byte[] check = checksum(useSHA1 ? decryptorFactory.getChecksumCalculator(HashAlgorithmTags.SHA1) : null, data, (useSHA1) ? data.length - 20 : data.length - 2); - if (!Arrays.constantTimeAreEqual(check.length, check, 0, data, data.length - check.length)) - { - throw new PGPException("checksum mismatch at in checksum of " + check.length + " bytes"); + if (!Arrays.constantTimeAreEqual(check.length, check, 0, data, data.length - check.length)) + { + throw new PGPException("checksum mismatch at in checksum of " + check.length + " bytes"); + } } } else // version 2 or 3, RSA only. { - byte[] key = decryptorFactory.makeKeyFromPassPhrase(secret.getEncAlgorithm(), secret.getS2K()); data = new byte[encData.length]; @@ -660,12 +709,17 @@ public PGPPrivateKey extractPrivateKey( case PGPPublicKey.ECDH: case PGPPublicKey.ECDSA: ECSecretBCPGKey ecPriv = new ECSecretBCPGKey(in); - return new PGPPrivateKey(this.getKeyID(), pubPk, ecPriv); + case PGPPublicKey.X25519: + return new PGPPrivateKey(this.getKeyID(), pubPk, new X25519SecretBCPGKey(in)); + case PGPPublicKey.X448: + return new PGPPrivateKey(this.getKeyID(), pubPk, new X448SecretBCPGKey(in)); case PGPPublicKey.EDDSA_LEGACY: - EdSecretBCPGKey edPriv = new EdSecretBCPGKey(in); - - return new PGPPrivateKey(this.getKeyID(), pubPk, edPriv); + return new PGPPrivateKey(this.getKeyID(), pubPk, new EdSecretBCPGKey(in)); + case PGPPublicKey.Ed25519: + return new PGPPrivateKey(this.getKeyID(), pubPk, new Ed25519SecretBCPGKey(in)); + case PGPPublicKey.Ed448: + return new PGPPrivateKey(this.getKeyID(), pubPk, new Ed448SecretBCPGKey(in)); default: throw new PGPException("unknown public key algorithm encountered"); } @@ -740,10 +794,7 @@ public void encode(OutputStream outStream) if (pub.subSigs == null) // is not a sub key { - for (int i = 0; i != pub.keySigs.size(); i++) - { - ((PGPSignature)pub.keySigs.get(i)).encode(out); - } + Util.encodePGPSignatures(out, pub.keySigs, false); for (int i = 0; i != pub.ids.size(); i++) { @@ -766,19 +817,12 @@ public void encode(OutputStream outStream) } List sigs = (List)pub.idSigs.get(i); - - for (int j = 0; j != sigs.size(); j++) - { - ((PGPSignature)sigs.get(j)).encode(out); - } + Util.encodePGPSignatures(out, sigs, false); } } else { - for (int j = 0; j != pub.subSigs.size(); j++) - { - ((PGPSignature)pub.subSigs.get(j)).encode(out); - } + Util.encodePGPSignatures(out, pub.subSigs, false); } } @@ -803,9 +847,9 @@ public static PGPSecretKey copyWithNewPassword( * Return a copy of the passed in secret key, encrypted using a new * password and the passed in algorithm. * - * @param key the PGPSecretKey to be copied. - * @param oldKeyDecryptor the current decryptor based on the current password for key. - * @param newKeyEncryptor a new encryptor based on a new password for encrypting the secret key material. + * @param key the PGPSecretKey to be copied. + * @param oldKeyDecryptor the current decryptor based on the current password for key. + * @param newKeyEncryptor a new encryptor based on a new password for encrypting the secret key material. * @param checksumCalculator digest based checksum calculator for private key data. */ public static PGPSecretKey copyWithNewPassword( @@ -905,8 +949,6 @@ public static PGPSecretKey copyWithNewPassword( keyData[pos] = rawKeyData[pos]; keyData[pos + 1] = rawKeyData[pos + 1]; - s2k = newKeyEncryptor.getS2K(); - newEncAlgorithm = newKeyEncryptor.getAlgorithm(); } else { @@ -922,38 +964,24 @@ public static PGPSecretKey copyWithNewPassword( byte[] check = checksum(checksumCalculator, rawKeyData, rawKeyData.length); rawKeyData = Arrays.concatenate(rawKeyData, check); - keyData = newKeyEncryptor.encryptKeyData(rawKeyData, 0, rawKeyData.length); } else { s2kUsage = SecretKeyPacket.USAGE_CHECKSUM; - keyData = newKeyEncryptor.encryptKeyData(rawKeyData, 0, rawKeyData.length); } } - else - { - keyData = newKeyEncryptor.encryptKeyData(rawKeyData, 0, rawKeyData.length); - } + keyData = newKeyEncryptor.encryptKeyData(rawKeyData, 0, rawKeyData.length); iv = newKeyEncryptor.getCipherIV(); - s2k = newKeyEncryptor.getS2K(); - - newEncAlgorithm = newKeyEncryptor.getAlgorithm(); } + s2k = newKeyEncryptor.getS2K(); + newEncAlgorithm = newKeyEncryptor.getAlgorithm(); } SecretKeyPacket secret; - if (key.secret instanceof SecretSubkeyPacket) - { - secret = new SecretSubkeyPacket(key.secret.getPublicKeyPacket(), - newEncAlgorithm, s2kUsage, s2k, iv, keyData); - } - else - { - secret = new SecretKeyPacket(key.secret.getPublicKeyPacket(), - newEncAlgorithm, s2kUsage, s2k, iv, keyData); - } + + secret = generateSecretKeyPacket(!(key.secret instanceof SecretSubkeyPacket), key.secret.getPublicKeyPacket(), newEncAlgorithm, s2kUsage, s2k, iv, keyData); return new PGPSecretKey(secret, key.pub); } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKeyRing.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKeyRing.java index d1b26d99b9..d9427c26c3 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKeyRing.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKeyRing.java @@ -15,6 +15,8 @@ import org.bouncycastle.bcpg.ArmoredInputException; import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.bcpg.BCPGOutputStream; +import org.bouncycastle.bcpg.PacketFormat; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.PublicSubkeyPacket; import org.bouncycastle.bcpg.SecretKeyPacket; @@ -24,7 +26,6 @@ import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; -import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Iterable; /** @@ -246,7 +247,7 @@ public PGPPublicKey getPublicKey(byte[] fingerprint) { PGPPublicKey k = (PGPPublicKey)extraPubKeys.get(i); - if (Arrays.areEqual(fingerprint, k.getFingerprint())) + if (k.hasFingerprint(fingerprint)) { return k; } @@ -356,7 +357,7 @@ public PGPSecretKey getSecretKey(byte[] fingerprint) { PGPSecretKey k = (PGPSecretKey)keys.get(i); - if (Arrays.areEqual(fingerprint, k.getPublicKey().getFingerprint())) + if (k.getPublicKey().hasFingerprint(fingerprint)) { return k; } @@ -377,13 +378,29 @@ public Iterator getExtraPublicKeys() return extraPubKeys.iterator(); } + /** + * Return the number of keys in the key ring. + * + * @return number of keys (master key + subkey). + */ + public int size() + { + return keys.size(); + } + public byte[] getEncoded() throws IOException { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - this.encode(bOut); + return getEncoded(PacketFormat.ROUNDTRIP); + } + @Override + public byte[] getEncoded(PacketFormat format) throws IOException + { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, format); + this.encode(pOut); + pOut.close(); return bOut.toByteArray(); } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPSignature.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPSignature.java index 300f5e8ea1..c270d85b6d 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPSignature.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPSignature.java @@ -12,13 +12,15 @@ import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.BCPGOutputStream; +import org.bouncycastle.bcpg.HashUtils; import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.Packet; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SignaturePacket; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.TrustPacket; -import org.bouncycastle.bcpg.UserAttributeSubpacket; +import org.bouncycastle.math.ec.rfc8032.Ed25519; +import org.bouncycastle.math.ec.rfc8032.Ed448; import org.bouncycastle.openpgp.operator.PGPContentVerifier; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilder; import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; @@ -30,6 +32,7 @@ * A PGP signature object. */ public class PGPSignature + extends PGPDefaultSignatureGenerator { public static final int BINARY_DOCUMENT = 0x00; public static final int CANONICAL_TEXT_DOCUMENT = 0x01; @@ -49,12 +52,10 @@ public class PGPSignature public static final int TIMESTAMP = 0x40; public static final int THIRD_PARTY_CONFIRMATION = 0x50; - private SignaturePacket sigPck; - private int signatureType; - private TrustPacket trustPck; - private PGPContentVerifier verifier; - private byte lastb; - private OutputStream sigOut; + private final SignaturePacket sigPck; + private final TrustPacket trustPck; + + private volatile PGPContentVerifier verifier; private static SignaturePacket cast(Packet packet) throws IOException @@ -73,20 +74,28 @@ public PGPSignature( this(cast(pIn.readPacket())); } + PGPSignature( + PGPSignature signature) + { + super(signature.getVersion()); + sigPck = signature.sigPck; + sigType = signature.sigType; + trustPck = signature.trustPck; + } + PGPSignature( SignaturePacket sigPacket) { - sigPck = sigPacket; - signatureType = sigPck.getSignatureType(); - trustPck = null; + this(sigPacket, null); } PGPSignature( SignaturePacket sigPacket, TrustPacket trustPacket) { - this(sigPacket); - + super(sigPacket.getVersion()); + this.sigPck = sigPacket; + this.sigType = sigPck.getSignatureType(); this.trustPck = trustPacket; } @@ -143,92 +152,53 @@ public boolean isCertification() public void init(PGPContentVerifierBuilderProvider verifierBuilderProvider, PGPPublicKey pubKey) throws PGPException { - PGPContentVerifierBuilder verifierBuilder = verifierBuilderProvider.get(sigPck.getKeyAlgorithm(), sigPck.getHashAlgorithm()); - - verifier = verifierBuilder.build(pubKey); - - lastb = 0; - sigOut = verifier.getOutputStream(); - } - - public void update( - byte b) - { - if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) - { - if (b == '\r') - { - byteUpdate((byte)'\r'); - byteUpdate((byte)'\n'); - } - else if (b == '\n') - { - if (lastb != '\r') - { - byteUpdate((byte)'\r'); - byteUpdate((byte)'\n'); - } - } - else - { - byteUpdate(b); - } - - lastb = b; - } - else + if (sigType == 0xFF) { - byteUpdate(b); + throw new PGPException("Illegal signature type 0xFF provided."); } + PGPContentVerifierBuilder verifierBuilder = createVerifierProvider(verifierBuilderProvider); + + init(verifierBuilder.build(pubKey)); } - public void update( - byte[] bytes) + PGPContentVerifierBuilder createVerifierProvider(PGPContentVerifierBuilderProvider verifierBuilderProvider) + throws PGPException { - this.update(bytes, 0, bytes.length); + return verifierBuilderProvider.get(sigPck.getKeyAlgorithm(), sigPck.getHashAlgorithm()); } - public void update( - byte[] bytes, - int off, - int length) + void init(PGPContentVerifier verifier) + throws PGPException { - if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) - { - int finish = off + length; + this.verifier = verifier; + this.lastb = 0; + this.sigOut = verifier.getOutputStream(); - for (int i = off; i != finish; i++) - { - this.update(bytes[i]); - } - } - else - { - blockUpdate(bytes, off, length); - } + checkSaltSize(); + updateWithSalt(); } - private void byteUpdate(byte b) + private void checkSaltSize() + throws PGPException { - try + if (getVersion() != SignaturePacket.VERSION_6) { - sigOut.write(b); + return; } - catch (IOException e) + + int expectedSaltSize = HashUtils.getV6SignatureSaltSizeInBytes(getHashAlgorithm()); + if (expectedSaltSize != sigPck.getSalt().length) { - throw new PGPRuntimeOperationException(e.getMessage(), e); + throw new PGPException("RFC9580 defines the salt size for " + PGPUtil.getDigestName(getHashAlgorithm()) + + " as " + expectedSaltSize + " octets, but signature has " + sigPck.getSalt().length + " octets."); } } - private void blockUpdate(byte[] block, int off, int len) + private void updateWithSalt() { - try - { - sigOut.write(block, off, len); - } - catch (IOException e) + if (getVersion() == SignaturePacket.VERSION_6) { - throw new PGPRuntimeOperationException(e.getMessage(), e); + update(sigPck.getSalt()); } } @@ -250,27 +220,6 @@ public boolean verify() } - private void updateWithIdData(int header, byte[] idBytes) - { - this.update((byte)header); - this.update((byte)(idBytes.length >> 24)); - this.update((byte)(idBytes.length >> 16)); - this.update((byte)(idBytes.length >> 8)); - this.update((byte)(idBytes.length)); - this.update(idBytes); - } - - private void updateWithPublicKey(PGPPublicKey key) - throws PGPException - { - byte[] keyBytes = getEncodedPublicKey(key); - - this.update((byte)0x99); - this.update((byte)(keyBytes.length >> 8)); - this.update((byte)(keyBytes.length)); - this.update(keyBytes); - } - /** * Verify the signature as certifying the passed in public key as associated * with the passed in user attributes. @@ -290,26 +239,24 @@ public boolean verifyCertification( throw new PGPException("PGPSignature not initialised - call init()."); } - updateWithPublicKey(key); - - // - // hash in the userAttributes - // - try - { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - UserAttributeSubpacket[] packets = userAttributes.toSubpacketArray(); - for (int i = 0; i != packets.length; i++) - { - packets[i].encode(bOut); - } - updateWithIdData(0xd1, bOut.toByteArray()); - } - catch (IOException e) + if (!PGPSignature.isCertification(sigType) + && PGPSignature.CERTIFICATION_REVOCATION != sigType) { - throw new PGPException("cannot encode subpacket array", e); + throw new PGPException("signature is neither a certification signature nor a certification revocation."); } + return doVerifyCertification(userAttributes, key); + } + + boolean doVerifyCertification( + PGPUserAttributeSubpacketVector userAttributes, + PGPPublicKey key) + throws PGPException + { + updateWithPublicKey(key); + + getAttributesHash(userAttributes); + addTrailer(); return verifier.verify(this.getSignature()); @@ -329,21 +276,7 @@ public boolean verifyCertification( PGPPublicKey key) throws PGPException { - if (verifier == null) - { - throw new PGPException("PGPSignature not initialised - call init()."); - } - - updateWithPublicKey(key); - - // - // hash in the id - // - updateWithIdData(0xb4, Strings.toUTF8ByteArray(id)); - - addTrailer(); - - return verifier.verify(this.getSignature()); + return verifyCertification(Strings.toUTF8ByteArray(id), key); } /** @@ -365,6 +298,18 @@ public boolean verifyCertification( throw new PGPException("PGPSignature not initialised - call init()."); } + if (!PGPSignature.isCertification(sigType) + && PGPSignature.CERTIFICATION_REVOCATION != sigType) + { + throw new PGPException("signature is neither a certification signature nor a certification revocation."); + } + + return doVerifyCertification(rawID, key); + } + + boolean doVerifyCertification(byte[] rawID, PGPPublicKey key) + throws PGPException + { updateWithPublicKey(key); // @@ -396,6 +341,21 @@ public boolean verifyCertification( throw new PGPException("PGPSignature not initialised - call init()."); } + if (PGPSignature.SUBKEY_BINDING != sigType + && PGPSignature.PRIMARYKEY_BINDING != sigType + && PGPSignature.SUBKEY_REVOCATION != sigType) + { + throw new PGPException("signature is not a key binding signature."); + } + + return doVerifyCertification(masterKey, pubKey); + } + + boolean doVerifyCertification( + PGPPublicKey masterKey, + PGPPublicKey pubKey) + throws PGPException + { updateWithPublicKey(masterKey); updateWithPublicKey(pubKey); @@ -435,12 +395,18 @@ public boolean verifyCertification( } if (this.getSignatureType() != KEY_REVOCATION - && this.getSignatureType() != SUBKEY_REVOCATION && this.getSignatureType() != DIRECT_KEY) { throw new PGPException("signature is not a key signature"); } + return doVerifyCertification(pubKey); + } + + boolean doVerifyCertification( + PGPPublicKey pubKey) + throws PGPException + { updateWithPublicKey(pubKey); addTrailer(); @@ -508,6 +474,11 @@ private PGPSignatureSubpacketVector createSubpacketVector(SignatureSubpacket[] p return null; } + byte[] getSalt() + { + return sigPck.getSalt(); + } + public byte[] getSignature() throws PGPException { @@ -520,13 +491,22 @@ public byte[] getSignature() { signature = BigIntegers.asUnsignedByteArray(sigValues[0].getValue()); } - else if (this.getKeyAlgorithm() == PublicKeyAlgorithmTags.EDDSA_LEGACY) + else if (getKeyAlgorithm() == PublicKeyAlgorithmTags.EDDSA_LEGACY) { - signature = new byte[64]; byte[] a = BigIntegers.asUnsignedByteArray(sigValues[0].getValue()); byte[] b = BigIntegers.asUnsignedByteArray(sigValues[1].getValue()); - System.arraycopy(a, 0, signature, 32 - a.length, a.length); - System.arraycopy(b, 0, signature, 64 - b.length, b.length); + if (a.length + b.length > Ed25519.SIGNATURE_SIZE) + { + signature = new byte[Ed448.SIGNATURE_SIZE]; + System.arraycopy(a, 0, signature, Ed448.PUBLIC_KEY_SIZE - a.length, a.length); + System.arraycopy(b, 0, signature, Ed448.SIGNATURE_SIZE - b.length, b.length); + } + else + { + signature = new byte[Ed25519.SIGNATURE_SIZE]; + System.arraycopy(a, 0, signature, Ed25519.PUBLIC_KEY_SIZE - a.length, a.length); + System.arraycopy(b, 0, signature, Ed25519.SIGNATURE_SIZE - b.length, b.length); + } } else { @@ -613,24 +593,6 @@ public void encode( } } - private byte[] getEncodedPublicKey( - PGPPublicKey pubKey) - throws PGPException - { - byte[] keyBytes; - - try - { - keyBytes = pubKey.publicPk.getEncodedContents(); - } - catch (IOException e) - { - throw new PGPException("exception preparing key.", e); - } - - return keyBytes; - } - /** * Return true if the passed in signature type represents a certification, false if the signature type is not. * diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureGenerator.java index a4ea7cf11d..6700c89886 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureGenerator.java @@ -2,7 +2,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.OutputStream; import java.math.BigInteger; import java.util.Date; @@ -12,7 +11,6 @@ import org.bouncycastle.bcpg.SignaturePacket; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; -import org.bouncycastle.bcpg.UserAttributeSubpacket; import org.bouncycastle.bcpg.sig.IssuerKeyID; import org.bouncycastle.bcpg.sig.SignatureCreationTime; import org.bouncycastle.openpgp.operator.PGPContentSigner; @@ -24,145 +22,110 @@ * Generator for PGP Signatures. */ public class PGPSignatureGenerator + extends PGPDefaultSignatureGenerator { - private SignatureSubpacket[] unhashed = new SignatureSubpacket[0]; - private SignatureSubpacket[] hashed = new SignatureSubpacket[0]; - private OutputStream sigOut; + private SignatureSubpacket[] unhashed = new SignatureSubpacket[0]; + private SignatureSubpacket[] hashed = new SignatureSubpacket[0]; private PGPContentSignerBuilder contentSignerBuilder; private PGPContentSigner contentSigner; - private int sigType; - private byte lastb; + //private int providedKeyAlgorithm = -1; private int providedKeyAlgorithm = -1; + private PGPPublicKey signingPubKey; /** - * Create a signature generator built on the passed in contentSignerBuilder. + * Create a version 4 signature generator built on the passed in contentSignerBuilder. * - * @param contentSignerBuilder builder to produce PGPContentSigner objects for generating signatures. + * @param contentSignerBuilder builder to produce PGPContentSigner objects for generating signatures. + * @deprecated use {@link #PGPSignatureGenerator(PGPContentSignerBuilder, PGPPublicKey)} instead. */ public PGPSignatureGenerator( PGPContentSignerBuilder contentSignerBuilder) { - this.contentSignerBuilder = contentSignerBuilder; + this(contentSignerBuilder, SignaturePacket.VERSION_4); } /** - * Initialise the generator for signing. + * Create a signature generator built on the passed in contentSignerBuilder. * - * @param signatureType - * @param key - * @throws PGPException + * @param contentSignerBuilder builder to produce PGPContentSigner objects for generating signatures. + * @param version signature version */ - public void init( - int signatureType, - PGPPrivateKey key) - throws PGPException + PGPSignatureGenerator( + PGPContentSignerBuilder contentSignerBuilder, + int version) { - contentSigner = contentSignerBuilder.build(signatureType, key); - sigOut = contentSigner.getOutputStream(); - sigType = contentSigner.getType(); - lastb = 0; - - if (providedKeyAlgorithm >= 0 && providedKeyAlgorithm != contentSigner.getKeyAlgorithm()) - { - throw new PGPException("key algorithm mismatch"); - } - } - - public void update( - byte b) - { - if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) - { - if (b == '\r') - { - byteUpdate((byte)'\r'); - byteUpdate((byte)'\n'); - } - else if (b == '\n') - { - if (lastb != '\r') - { - byteUpdate((byte)'\r'); - byteUpdate((byte)'\n'); - } - } - else - { - byteUpdate(b); - } - - lastb = b; - } - else - { - byteUpdate(b); - } - } - - public void update( - byte[] b) - { - this.update(b, 0, b.length); + super(version); + this.contentSignerBuilder = contentSignerBuilder; } - - public void update( - byte[] b, - int off, - int len) + + /** + * Create a signature generator built on the passed in contentSignerBuilder. + * The produces signature version will match the version of the passed in signing key. + * + * @param contentSignerBuilder builder to produce PGPContentSigner objects for generating signatures + * @param signingKey signing key + */ + public PGPSignatureGenerator( + PGPContentSignerBuilder contentSignerBuilder, + PGPPublicKey signingKey) { - if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) - { - int finish = off + len; - - for (int i = off; i != finish; i++) - { - this.update(b[i]); - } - } - else - { - blockUpdate(b, off, len); - } + this(contentSignerBuilder, signingKey, signingKey.getVersion()); } - private void byteUpdate(byte b) + public PGPSignatureGenerator( + PGPContentSignerBuilder contentSignerBuilder, + PGPPublicKey signingKey, + int signatureVersion) { - try - { - sigOut.write(b); - } - catch (IOException e) + this(contentSignerBuilder, signatureVersion); + this.signingPubKey = signingKey; + if (signingKey.getVersion() == 6 && signatureVersion != 6) { - throw new PGPRuntimeOperationException(e.getMessage(), e); + throw new IllegalArgumentException("Version 6 keys MUST only generate version 6 signatures."); } } - private void blockUpdate(byte[] block, int off, int len) + /** + * Initialise the generator for signing. + * + * @param signatureType + * @param key + * @throws PGPException + */ + public void init( + int signatureType, + PGPPrivateKey key) + throws PGPException { - try - { - sigOut.write(block, off, len); - } - catch (IOException e) + if (signatureType == 0xFF) { - throw new PGPRuntimeOperationException(e.getMessage(), e); + throw new PGPException("Illegal signature type 0xFF provided."); } + contentSigner = contentSignerBuilder.build(signatureType, key); + sigOut = contentSigner.getOutputStream(); + sigType = contentSigner.getType(); + lastb = 0; + +// if (providedKeyAlgorithm >= 0 && providedKeyAlgorithm != contentSigner.getKeyAlgorithm()) +// { +// throw new PGPException("key algorithm mismatch"); +// } } public void setHashedSubpackets( - PGPSignatureSubpacketVector hashedPcks) + PGPSignatureSubpacketVector hashedPcks) { if (hashedPcks == null) { hashed = new SignatureSubpacket[0]; return; } - + hashed = hashedPcks.toSubpacketArray(); } - + public void setUnhashedSubpackets( - PGPSignatureSubpacketVector unhashedPcks) + PGPSignatureSubpacketVector unhashedPcks) { if (unhashedPcks == null) { @@ -172,36 +135,36 @@ public void setUnhashedSubpackets( unhashed = unhashedPcks.toSubpacketArray(); } - + /** * Return the one pass header associated with the current signature. - * + * * @param isNested true if the signature is nested, false otherwise. * @return PGPOnePassSignature * @throws PGPException */ public PGPOnePassSignature generateOnePassVersion( - boolean isNested) + boolean isNested) throws PGPException { return new PGPOnePassSignature(new OnePassSignaturePacket(sigType, contentSigner.getHashAlgorithm(), contentSigner.getKeyAlgorithm(), contentSigner.getKeyID(), isNested)); } - + /** * Return a signature object containing the current signature state. - * + * * @return PGPSignature * @throws PGPException */ public PGPSignature generate() throws PGPException { - MPInteger[] sigValues; - int version = 4; - ByteArrayOutputStream sOut = new ByteArrayOutputStream(); - SignatureSubpacket[] hPkts, unhPkts; + MPInteger[] sigValues; + int version = 4; + ByteArrayOutputStream sOut = new ByteArrayOutputStream(); + SignatureSubpacket[] hPkts, unhPkts; - if (!packetPresent(hashed, SignatureSubpacketTags.CREATION_TIME)) + if (packetNotPresent(hashed, SignatureSubpacketTags.CREATION_TIME)) { hPkts = insertSubpacket(hashed, new SignatureCreationTime(false, new Date())); } @@ -209,8 +172,8 @@ public PGPSignature generate() { hPkts = hashed; } - - if (!packetPresent(hashed, SignatureSubpacketTags.ISSUER_KEY_ID) && !packetPresent(unhashed, SignatureSubpacketTags.ISSUER_KEY_ID)) + + if (packetNotPresent(hashed, SignatureSubpacketTags.ISSUER_KEY_ID) && packetNotPresent(unhashed, SignatureSubpacketTags.ISSUER_KEY_ID)) { unhPkts = insertSubpacket(unhashed, new IssuerKeyID(false, contentSigner.getKeyID())); } @@ -218,84 +181,102 @@ public PGPSignature generate() { unhPkts = unhashed; } - + try { sOut.write((byte)version); sOut.write((byte)sigType); sOut.write((byte)contentSigner.getKeyAlgorithm()); sOut.write((byte)contentSigner.getHashAlgorithm()); - - ByteArrayOutputStream hOut = new ByteArrayOutputStream(); - + + ByteArrayOutputStream hOut = new ByteArrayOutputStream(); + for (int i = 0; i != hPkts.length; i++) { hPkts[i].encode(hOut); } - - byte[] data = hOut.toByteArray(); - + + byte[] data = hOut.toByteArray(); + sOut.write((byte)(data.length >> 8)); sOut.write((byte)data.length); sOut.write(data); + byte[] hData = sOut.toByteArray(); + + sOut.write((byte)version); + sOut.write((byte)0xff); + sOut.write((byte)(hData.length >> 24)); + sOut.write((byte)(hData.length >> 16)); + sOut.write((byte)(hData.length >> 8)); + sOut.write((byte)(hData.length)); } catch (IOException e) { throw new PGPException("exception encoding hashed data.", e); } - - byte[] hData = sOut.toByteArray(); - - sOut.write((byte)version); - sOut.write((byte)0xff); - sOut.write((byte)(hData.length >> 24)); - sOut.write((byte)(hData.length >> 16)); - sOut.write((byte)(hData.length >> 8)); - sOut.write((byte)(hData.length)); - - byte[] trailer = sOut.toByteArray(); - blockUpdate(trailer, 0, trailer.length); - if (contentSigner.getKeyAlgorithm() == PublicKeyAlgorithmTags.RSA_SIGN - || contentSigner.getKeyAlgorithm() == PublicKeyAlgorithmTags.RSA_GENERAL) // an RSA signature + byte[] trailer = sOut.toByteArray(); + + blockUpdate(trailer, 0, trailer.length); + switch (contentSigner.getKeyAlgorithm()) + { + case PublicKeyAlgorithmTags.RSA_SIGN: + case PublicKeyAlgorithmTags.RSA_GENERAL: { sigValues = new MPInteger[1]; sigValues[0] = new MPInteger(new BigInteger(1, contentSigner.getSignature())); + break; } - else if (contentSigner.getKeyAlgorithm() == PublicKeyAlgorithmTags.EDDSA_LEGACY) + case PublicKeyAlgorithmTags.EDDSA_LEGACY: { byte[] enc = contentSigner.getSignature(); sigValues = new MPInteger[]{ - new MPInteger(new BigInteger(1, Arrays.copyOfRange(enc, 0, enc.length / 2))), - new MPInteger(new BigInteger(1, Arrays.copyOfRange(enc, enc.length / 2, enc.length))) - }; + new MPInteger(new BigInteger(1, Arrays.copyOfRange(enc, 0, enc.length / 2))), + new MPInteger(new BigInteger(1, Arrays.copyOfRange(enc, enc.length / 2, enc.length))) + }; + break; } - else - { + case PublicKeyAlgorithmTags.Ed25519: + case PublicKeyAlgorithmTags.Ed448: + // Contrary to EDDSA_LEGACY, the new PK algorithms Ed25519, Ed448 do not use MPI encoding + sigValues = null; + break; + default: sigValues = PGPUtil.dsaSigToMpi(contentSigner.getSignature()); + break; } - - byte[] digest = contentSigner.getDigest(); - byte[] fingerPrint = new byte[2]; + + byte[] digest = contentSigner.getDigest(); + byte[] fingerPrint = new byte[2]; fingerPrint[0] = digest[0]; fingerPrint[1] = digest[1]; - - return new PGPSignature(new SignaturePacket(sigType, contentSigner.getKeyID(), contentSigner.getKeyAlgorithm(), contentSigner.getHashAlgorithm(), hPkts, unhPkts, fingerPrint, sigValues)); + + if (sigValues != null) + { + return new PGPSignature(new SignaturePacket(sigType, contentSigner.getKeyID(), contentSigner.getKeyAlgorithm(), + contentSigner.getHashAlgorithm(), hPkts, unhPkts, fingerPrint, sigValues)); + } + else + { + // Ed25519, Ed448 use raw encoding instead of MPI + return new PGPSignature(new SignaturePacket(4, sigType, contentSigner.getKeyID(), contentSigner.getKeyAlgorithm(), + contentSigner.getHashAlgorithm(), hPkts, unhPkts, fingerPrint, contentSigner.getSignature(), null)); + } } /** * Generate a certification for the passed in id and key. - * - * @param id the id we are certifying against the public key. + * + * @param id the id we are certifying against the public key. * @param pubKey the key we are certifying against the id. * @return the certification. * @throws PGPException */ public PGPSignature generateCertification( - String id, - PGPPublicKey pubKey) + String id, + PGPPublicKey pubKey) throws PGPException { updateWithPublicKey(pubKey); @@ -310,35 +291,20 @@ public PGPSignature generateCertification( /** * Generate a certification for the passed in userAttributes + * * @param userAttributes the id we are certifying against the public key. - * @param pubKey the key we are certifying against the id. + * @param pubKey the key we are certifying against the id. * @return the certification. * @throws PGPException */ public PGPSignature generateCertification( PGPUserAttributeSubpacketVector userAttributes, - PGPPublicKey pubKey) + PGPPublicKey pubKey) throws PGPException { updateWithPublicKey(pubKey); - // - // hash in the attributes - // - try - { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - UserAttributeSubpacket[] packets = userAttributes.toSubpacketArray(); - for (int i = 0; i != packets.length; i++) - { - packets[i].encode(bOut); - } - updateWithIdData(0xd1, bOut.toByteArray()); - } - catch (IOException e) - { - throw new PGPException("cannot encode subpacket array", e); - } + getAttributesHash(userAttributes); return this.generate(); } @@ -346,32 +312,32 @@ public PGPSignature generateCertification( /** * Generate a certification for the passed in key against the passed in * master key. - * + * * @param masterKey the key we are certifying against. - * @param pubKey the key we are certifying. + * @param pubKey the key we are certifying. * @return the certification. * @throws PGPException */ public PGPSignature generateCertification( - PGPPublicKey masterKey, - PGPPublicKey pubKey) + PGPPublicKey masterKey, + PGPPublicKey pubKey) throws PGPException { updateWithPublicKey(masterKey); updateWithPublicKey(pubKey); - + return this.generate(); } - + /** * Generate a certification, such as a revocation, for the passed in key. - * + * * @param pubKey the key we are certifying. * @return the certification. * @throws PGPException */ public PGPSignature generateCertification( - PGPPublicKey pubKey) + PGPPublicKey pubKey) throws PGPException { if ((sigType == PGPSignature.SUBKEY_REVOCATION || sigType == PGPSignature.SUBKEY_BINDING) && !pubKey.isMasterKey()) @@ -383,26 +349,8 @@ public PGPSignature generateCertification( return this.generate(); } - - private byte[] getEncodedPublicKey( - PGPPublicKey pubKey) - throws PGPException - { - byte[] keyBytes; - - try - { - keyBytes = pubKey.publicPk.getEncodedContents(); - } - catch (IOException e) - { - throw new PGPException("exception preparing key.", e); - } - - return keyBytes; - } - private boolean packetPresent( + private boolean packetNotPresent( SignatureSubpacket[] packets, int type) { @@ -410,11 +358,11 @@ private boolean packetPresent( { if (packets[i].getType() == type) { - return true; + return false; } } - return false; + return true; } private SignatureSubpacket[] insertSubpacket( @@ -428,25 +376,4 @@ private SignatureSubpacket[] insertSubpacket( return tmp; } - - private void updateWithIdData(int header, byte[] idBytes) - { - this.update((byte)header); - this.update((byte)(idBytes.length >> 24)); - this.update((byte)(idBytes.length >> 16)); - this.update((byte)(idBytes.length >> 8)); - this.update((byte)(idBytes.length)); - this.update(idBytes); - } - - private void updateWithPublicKey(PGPPublicKey key) - throws PGPException - { - byte[] keyBytes = getEncodedPublicKey(key); - - this.update((byte)0x99); - this.update((byte)(keyBytes.length >> 8)); - this.update((byte)(keyBytes.length)); - this.update(keyBytes); - } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureSubpacketGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureSubpacketGenerator.java index 98ab72dd0d..5d81b17980 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureSubpacketGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureSubpacketGenerator.java @@ -19,6 +19,7 @@ import org.bouncycastle.bcpg.sig.PolicyURI; import org.bouncycastle.bcpg.sig.PreferredAlgorithms; import org.bouncycastle.bcpg.sig.PrimaryUserID; +import org.bouncycastle.bcpg.sig.RegularExpression; import org.bouncycastle.bcpg.sig.Revocable; import org.bouncycastle.bcpg.sig.RevocationKey; import org.bouncycastle.bcpg.sig.RevocationKeyTags; @@ -67,6 +68,10 @@ public PGPSignatureSubpacketGenerator(PGPSignatureSubpacketVector sigSubV) */ public void setRevocable(boolean isCritical, boolean isRevocable) { + if (contains(SignatureSubpacketTags.REVOCABLE)) + { + throw new IllegalStateException("Revocable exists in the Signature Subpacket Generator"); + } packets.add(new Revocable(isCritical, isRevocable)); } @@ -79,6 +84,10 @@ public void setRevocable(boolean isCritical, boolean isRevocable) */ public void setExportable(boolean isCritical, boolean isExportable) { + if (contains(SignatureSubpacketTags.EXPORTABLE)) + { + throw new IllegalStateException("Exportable Certification exists in the Signature Subpacket Generator"); + } packets.add(new Exportable(isCritical, isExportable)); } @@ -238,7 +247,25 @@ public void addSignerUserID(boolean isCritical, String userID) packets.add(new SignerUserID(isCritical, userID)); } + /** + * Add a signer user-id to the signature. + * + * @param isCritical true if should be treated as critical, false otherwise. + * @param rawUserID signer user-id + * @deprecated use {@link #addSignerUserID(boolean, byte[])} instead. + */ public void setSignerUserID(boolean isCritical, byte[] rawUserID) + { + addSignerUserID(isCritical, rawUserID); + } + + /** + * Add a signer user-id to the signature. + * + * @param isCritical true if should be treated as critical, false otherwise. + * @param rawUserID signer user-id + */ + public void addSignerUserID(boolean isCritical, byte[] rawUserID) { if (rawUserID == null) { @@ -502,4 +529,31 @@ public PGPSignatureSubpacketVector generate() return new PGPSignatureSubpacketVector( (SignatureSubpacket[])packets.toArray(new SignatureSubpacket[packets.size()])); } + + private boolean contains(int type) + { + for (int i = 0; i < packets.size(); ++i) + { + if (((SignatureSubpacket)packets.get(i)).getType() == type) + { + return true; + } + } + return false; + } + + /** + * Adds a regular expression. + * + * @param isCritical true if should be treated as critical, false otherwise. + * @param regularExpression the regular expression + */ + public void addRegularExpression(boolean isCritical, String regularExpression) + { + if (regularExpression == null) + { + throw new IllegalArgumentException("attempt to set null regular expression"); + } + packets.add(new RegularExpression(isCritical, regularExpression)); + } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureSubpacketVector.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureSubpacketVector.java index 7aea047a55..01a507aae4 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureSubpacketVector.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureSubpacketVector.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.Date; import java.util.List; @@ -34,6 +35,33 @@ */ public class PGPSignatureSubpacketVector { + /** + * Create a new {@link PGPSignatureSubpacketVector} from the given {@link Collection} of + * {@link SignatureSubpacket} items. + * If the collection is
      null
      , return an empty {@link PGPSignatureSubpacketVector}. + * + * @param packets collection of items or null + * @return PGPSignatureSubpacketVector + */ + public static PGPSignatureSubpacketVector fromSubpackets(Collection packets) + { + if (packets == null) + { + return fromSubpackets((SignatureSubpacket[]) null); + } + else + { + return fromSubpackets(packets.toArray(new SignatureSubpacket[0])); + } + } + + /** + * Create a new {@link PGPSignatureSubpacketVector} from the given {@link SignatureSubpacket[]}. + * If the array is
      null
      , return an empty {@link PGPSignatureSubpacketVector}. + * + * @param packets array of items or null + * @return PGPSignatureSubpacketVector + */ public static PGPSignatureSubpacketVector fromSubpackets(SignatureSubpacket[] packets) { if (packets == null) diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureVerifier.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureVerifier.java new file mode 100644 index 0000000000..723a08758f --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureVerifier.java @@ -0,0 +1,23 @@ +package org.bouncycastle.openpgp; + +/** + * Base interface for thread safe signature verified objects. + */ +public interface PGPSignatureVerifier +{ + /** + * Return the signature type. + * + * @return signature type. + */ + int getSignatureType(); + + /** + * Return if the signature verifies or not. + * + * @return true if verifies, false otherwise. + * @throws PGPException on signature processing failure. + */ + boolean isVerified() + throws PGPException; +} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureVerifierBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureVerifierBuilder.java new file mode 100644 index 0000000000..25ddf6c1ae --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureVerifierBuilder.java @@ -0,0 +1,279 @@ +package org.bouncycastle.openpgp; + +import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; +import org.bouncycastle.util.Strings; + +/** + * Builder for thread-safe verifiers for a range of PGP signature types. + */ +public class PGPSignatureVerifierBuilder +{ + private final PGPContentVerifierBuilderProvider verifierBuilderProvider; + private final PGPPublicKey verificationKey; + + /** + * Base constructor. + * + * @param verifierBuilderProvider provider to build verifiers from. + * @param verificationKey the public key which corresponds to the signing key generating the signatures we are looking at. + */ + public PGPSignatureVerifierBuilder(PGPContentVerifierBuilderProvider verifierBuilderProvider, PGPPublicKey verificationKey) + { + this.verifierBuilderProvider = verifierBuilderProvider; + this.verificationKey = verificationKey; + } + + /** + * Instantiate a signature verifier for a {@link PGPSignature#DIRECT_KEY} signature. + * + * @param certification the PGP signature containing the certification. + * @param publicKey public key subject for the direct key signature. + * @return a verifier. + * @throws PGPException if signature type is wrong or there is a problem constructing the verifier. + */ + public PGPSignatureVerifier buildDirectKeyVerifier(PGPSignature certification, final PGPPublicKey publicKey) + throws PGPException + { + if (certification.getSignatureType() != PGPSignature.DIRECT_KEY) + { + throw new PGPException("signature is not a direct key signature"); + } + + return doBuildKeyCertificationVerifier(certification, publicKey); + } + + /** + * Instantiate a signature verifier for a {@link PGPSignature#KEY_REVOCATION} signature. + * + * @param certification the PGP signature containing the certification. + * @param publicKey public key subject for key revocation signature. + * @return a verifier. + * @throws PGPException if signature type is wrong or there is a problem constructing the verifier. + */ + public PGPSignatureVerifier buildKeyRevocationVerifier(PGPSignature certification, final PGPPublicKey publicKey) + throws PGPException + { + if (certification.getSignatureType() != PGPSignature.KEY_REVOCATION) + { + throw new PGPException("signature is not a key revocation signature"); + } + + return doBuildKeyCertificationVerifier(certification, publicKey); + } + + /** + * Instantiate a signature verifier for a {@link PGPSignature#PRIMARYKEY_BINDING} signature. + * + * @param certification the PGP signature containing the certification. + * @param primaryKey primary key for the primary key binding signature. + * @param subKey sub-key for the primary key binding signature. + * @return a verifier. + * @throws PGPException if signature type is wrong or there is a problem constructing the verifier. + */ + public PGPSignatureVerifier buildPrimaryKeyBindingVerifier(PGPSignature certification, PGPPublicKey primaryKey, PGPPublicKey subKey) + throws PGPException + { + if (certification.getSignatureType() != PGPSignature.PRIMARYKEY_BINDING) + { + throw new PGPException("signature is not a primary key binding signature"); + } + + return doBuildKeyBindingVerifier(certification, primaryKey, subKey); + } + + /** + * Instantiate a signature verifier for a {@link PGPSignature#SUBKEY_BINDING} signature. + * + * @param certification the PGP signature containing the certification. + * @param primaryKey primary key for the sub-key binding signature. + * @param subKey sub-key for the sub-key binding signature. + * @return a verifier. + * @throws PGPException if signature type is wrong or there is a problem constructing the verifier. + */ + public PGPSignatureVerifier buildSubKeyBindingVerifier(PGPSignature certification, PGPPublicKey primaryKey, PGPPublicKey subKey) + throws PGPException + { + if (certification.getSignatureType() != PGPSignature.SUBKEY_BINDING) + { + throw new PGPException("signature is not a subkey binding signature"); + } + + return doBuildKeyBindingVerifier(certification, primaryKey, subKey); + } + + /** + * Instantiate a signature verifier for a {@link PGPSignature#SUBKEY_REVOCATION} signature. + * + * @param certification the PGP signature containing the certification. + * @param primaryKey primary key for the sub-key key revocation signature. + * @param subKey sub-key for the sub-key key revocation signature. + * @return a verifier. + * @throws PGPException if signature type is wrong or there is a problem constructing the verifier. + */ + public PGPSignatureVerifier buildSubKeyRevocationVerifier(PGPSignature certification, final PGPPublicKey primaryKey, final PGPPublicKey subKey) + throws PGPException + { + if (certification.getSignatureType() != PGPSignature.SUBKEY_REVOCATION) + { + throw new PGPException("signature is not a primary key binding signature"); + } + + return doBuildKeyBindingVerifier(certification, primaryKey, subKey); + } + + /** + * Return a verifier for a signature as certifying the passed in public key as associated + * with the passed in user ID. + * + * @param userID the user ID, will be converted to UTF8. + * @param publicKey the key to be verified. + * @return a verifier. + * @throws PGPException if signature type is wrong or there is a problem constructing the verifier. + */ + public PGPSignatureVerifier buildCertificationVerifier(PGPSignature certification, String userID, final PGPPublicKey publicKey) + throws PGPException + { + return buildCertificationVerifier(certification, Strings.toUTF8ByteArray(userID), publicKey); + } + + /** + * Return a verifier for a signature as certifying the passed in public key as associated + * with the passed in raw user ID. + * + * @param rawUserID raw encoding of the user ID (assumed a UTF8 string, not user attributes) + * @param publicKey the key to be verified. + * @return a verifier. + * @throws PGPException if signature type is wrong or there is a problem constructing the verifier. + */ + public PGPSignatureVerifier buildCertificationVerifier(PGPSignature certification, byte[] rawUserID, final PGPPublicKey publicKey) + throws PGPException + { + int signatureType = certification.getSignatureType(); + if (!PGPSignature.isCertification(signatureType) + && PGPSignature.CERTIFICATION_REVOCATION != signatureType) + { + throw new PGPException("signature is neither a certification signature nor a certification revocation"); + } + + return doBuildCertificationVerifier(certification, rawUserID, publicKey); + } + + /** + * Return a verifier for a signature as certifying the passed in public key as associated + * with the passed in user attributes. + * + * @param userAttributes user attributes the key was stored under + * @param publicKey the key to be verified. + * @return a verifier. + * @throws PGPException if signature type is wrong or there is a problem constructing the verifier. + */ + public PGPSignatureVerifier buildCertificationVerifier(PGPSignature certification, PGPUserAttributeSubpacketVector userAttributes, final PGPPublicKey publicKey) + throws PGPException + { + int signatureType = certification.getSignatureType(); + if (!PGPSignature.isCertification(signatureType) + && PGPSignature.CERTIFICATION_REVOCATION != signatureType) + { + throw new PGPException("signature is neither a certification signature nor a certification revocation"); + } + + return doBuildCertificationVerifier(certification, userAttributes, publicKey); + } + + private PGPSignatureVerifier doBuildCertificationVerifier(PGPSignature certification, final byte[] rawUserID, final PGPPublicKey publicKey) + throws PGPException + { + final PGPSignature localSig = createLocalSig(certification); + + return new PGPSignatureVerifier() + { + @Override + public int getSignatureType() + { + return localSig.getSignatureType(); + } + + @Override + public boolean isVerified() + throws PGPException + { + return localSig.doVerifyCertification(rawUserID, publicKey); + } + }; + } + + private PGPSignature createLocalSig(PGPSignature certification) + throws PGPException + { + final PGPSignature localSig = new PGPSignature(certification); + + localSig.init(localSig.createVerifierProvider(verifierBuilderProvider).build(verificationKey)); + return localSig; + } + + private PGPSignatureVerifier doBuildCertificationVerifier(PGPSignature certification, final PGPUserAttributeSubpacketVector userAttributes, final PGPPublicKey publicKey) + throws PGPException + { + final PGPSignature localSig = createLocalSig(certification); + + return new PGPSignatureVerifier() + { + @Override + public int getSignatureType() + { + return localSig.getSignatureType(); + } + + @Override + public boolean isVerified() + throws PGPException + { + return localSig.doVerifyCertification(userAttributes, publicKey); + } + }; + } + + private PGPSignatureVerifier doBuildKeyCertificationVerifier(PGPSignature keyCertification, final PGPPublicKey publicKey) + throws PGPException + { + final PGPSignature localSig = createLocalSig(keyCertification); + + return new PGPSignatureVerifier() + { + @Override + public int getSignatureType() + { + return localSig.getSignatureType(); + } + + @Override + public boolean isVerified() + throws PGPException + { + return localSig.doVerifyCertification(publicKey); + } + }; + } + + private PGPSignatureVerifier doBuildKeyBindingVerifier(PGPSignature certification, final PGPPublicKey primaryKey, final PGPPublicKey subKey) + throws PGPException + { + final PGPSignature localSig = createLocalSig(certification); + + return new PGPSignatureVerifier() + { + @Override + public int getSignatureType() + { + return localSig.getSignatureType(); + } + + @Override + public boolean isVerified() + throws PGPException + { + return localSig.doVerifyCertification(primaryKey, subKey); + } + }; + } +} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPSymmetricKeyEncryptedData.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPSymmetricKeyEncryptedData.java index 6a85e31ccb..ac6f3d22b7 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPSymmetricKeyEncryptedData.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPSymmetricKeyEncryptedData.java @@ -1,15 +1,14 @@ package org.bouncycastle.openpgp; -import java.io.EOFException; import java.io.InputStream; import org.bouncycastle.bcpg.AEADEncDataPacket; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.InputStreamPacket; import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; +import org.bouncycastle.bcpg.UnsupportedPacketVersionException; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PGPDataDecryptorFactory; -import org.bouncycastle.util.io.TeeInputStream; public class PGPSymmetricKeyEncryptedData extends PGPEncryptedData @@ -22,6 +21,7 @@ protected PGPSymmetricKeyEncryptedData(InputStreamPacket encData) protected InputStream createDecryptionStream(PGPDataDecryptorFactory dataDecryptorFactory, PGPSessionKey sessionKey) throws PGPException { + // OpenPGP v5 if (encData instanceof AEADEncDataPacket) { AEADEncDataPacket aeadData = (AEADEncDataPacket)encData; @@ -31,18 +31,41 @@ protected InputStream createDecryptionStream(PGPDataDecryptorFactory dataDecrypt throw new PGPException("session key and AEAD algorithm mismatch"); } - PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(aeadData.getAEADAlgorithm(), aeadData.getIV(), aeadData.getChunkSize(), sessionKey.getAlgorithm(), sessionKey.getKey()); - + PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor( + aeadData, sessionKey); BCPGInputStream encIn = encData.getInputStream(); return new BCPGInputStream(dataDecryptor.getInputStream(encIn)); } - else + else if (encData instanceof SymmetricEncIntegrityPacket) { - boolean withIntegrityPacket = encData instanceof SymmetricEncIntegrityPacket; - PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(withIntegrityPacket, sessionKey.getAlgorithm(), sessionKey.getKey()); + SymmetricEncIntegrityPacket seipd = (SymmetricEncIntegrityPacket)encData; + + // OpenPGP v4 (SEIPD v1 with integrity protection) + if (seipd.getVersion() == SymmetricEncIntegrityPacket.VERSION_1) + { + PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(true, sessionKey.getAlgorithm(), sessionKey.getKey()); + return getDataStream(true, dataDecryptor); + } - return getDataStream(withIntegrityPacket, dataDecryptor); + // OpenPGP v6 (AEAD with SEIPD v2) + else if (seipd.getVersion() == SymmetricEncIntegrityPacket.VERSION_2) + { + PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(seipd, sessionKey); + return new BCPGInputStream(dataDecryptor.getInputStream(encData.getInputStream())); + } + + // Unsupported + else + { + throw new UnsupportedPacketVersionException("Unsupported SEIPD packet version: " + seipd.getVersion()); + } + } + // OpenPGP v3,v4 (SED without integrity protection) + else + { + PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(false, sessionKey.getAlgorithm(), sessionKey.getKey()); + return getDataStream(false, dataDecryptor); } } @@ -55,51 +78,7 @@ private InputStream getDataStream( { BCPGInputStream encIn = encData.getInputStream(); encIn.mark(dataDecryptor.getBlockSize() + 2); // iv + 2 octets checksum - - encStream = new BCPGInputStream(dataDecryptor.getInputStream(encIn)); - - if (withIntegrityPacket) - { - truncStream = new TruncatedStream(encStream); - - integrityCalculator = dataDecryptor.getIntegrityCalculator(); - - encStream = new TeeInputStream(truncStream, integrityCalculator.getOutputStream()); - } - - byte[] iv = new byte[dataDecryptor.getBlockSize()]; - for (int i = 0; i != iv.length; i++) - { - int ch = encStream.read(); - - if (ch < 0) - { - throw new EOFException("unexpected end of stream."); - } - - iv[i] = (byte)ch; - } - - int v1 = encStream.read(); - int v2 = encStream.read(); - - if (v1 < 0 || v2 < 0) - { - throw new EOFException("unexpected end of stream."); - } - - - // Note: the oracle attack on "quick check" bytes is not deemed - // a security risk for PBE (see PGPPublicKeyEncryptedData) - - boolean repeatCheckPassed = iv[iv.length - 2] == (byte)v1 - && iv[iv.length - 1] == (byte)v2; - - // Note: some versions of PGP appear to produce 0 for the extra - // bytes rather than repeating the two previous bytes - boolean zeroesCheckPassed = v1 == 0 && v2 == 0; - - if (!repeatCheckPassed && !zeroesCheckPassed) + if (processSymmetricEncIntegrityPacketDataStream(withIntegrityPacket, dataDecryptor, encIn)) { encIn.reset(); throw new PGPDataValidationException("data check failed."); diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPUtil.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPUtil.java index 79a1e29fc8..76bad21f70 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPUtil.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPUtil.java @@ -15,8 +15,11 @@ import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.asn1.gnu.GNUObjectIdentifiers; import org.bouncycastle.asn1.sec.SECObjectIdentifiers; +import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.bcpg.ArmoredInputStream; import org.bouncycastle.bcpg.BCPGInputStream; @@ -66,11 +69,15 @@ public class PGPUtil { { put(CryptlibObjectIdentifiers.curvey25519, "Curve25519"); + put(GNUObjectIdentifiers.Ed25519, "Ed25519Legacy"); put(EdECObjectIdentifiers.id_X25519, "Curve25519"); put(EdECObjectIdentifiers.id_Ed25519, "Ed25519"); put(SECObjectIdentifiers.secp256r1, "NIST P-256"); put(SECObjectIdentifiers.secp384r1, "NIST P-384"); put(SECObjectIdentifiers.secp521r1, "NIST P-521"); + put(TeleTrusTObjectIdentifiers.brainpoolP256r1, "brainpoolP256r1"); + put(TeleTrusTObjectIdentifiers.brainpoolP384r1, "brainpoolP384r1"); + put(TeleTrusTObjectIdentifiers.brainpoolP512r1, "brainpoolP512r1"); } }; @@ -105,14 +112,14 @@ public static String getDigestName( return "SHA224"; case HashAlgorithmTags.SHA3_256: case HashAlgorithmTags.SHA3_256_OLD: - return "SHA256"; + return "SHA3-256"; case HashAlgorithmTags.SHA3_384: - return "SHA384"; + return "SHA3-384"; case HashAlgorithmTags.SHA3_512: case HashAlgorithmTags.SHA3_512_OLD: - return "SHA512"; + return "SHA3-512"; case HashAlgorithmTags.SHA3_224: - return "SHA224"; + return "SHA3-224"; case HashAlgorithmTags.TIGER_192: return "TIGER"; default: @@ -120,6 +127,7 @@ public static String getDigestName( } } + public static int getDigestIDForName(String name) { name = Strings.toLowerCase(name); @@ -134,7 +142,7 @@ public static int getDigestIDForName(String name) * Return the EC curve name for the passed in OID. * * @param oid the EC curve object identifier in the PGP key - * @return a string representation of the OID. + * @return a string representation of the OID. */ public static String getCurveName( ASN1ObjectIdentifier oid) @@ -212,15 +220,11 @@ public static String getSymmetricCipherName( case SymmetricKeyAlgorithmTags.DES: return "DES"; case SymmetricKeyAlgorithmTags.AES_128: - return "AES"; case SymmetricKeyAlgorithmTags.AES_192: - return "AES"; case SymmetricKeyAlgorithmTags.AES_256: return "AES"; case SymmetricKeyAlgorithmTags.CAMELLIA_128: - return "Camellia"; case SymmetricKeyAlgorithmTags.CAMELLIA_192: - return "Camellia"; case SymmetricKeyAlgorithmTags.CAMELLIA_256: return "Camellia"; case SymmetricKeyAlgorithmTags.TWOFISH: @@ -334,46 +338,28 @@ public static byte[] makeRandomKey( SecureRandom random) throws PGPException { - int keySize = 0; + int keySize; switch (algorithm) { case SymmetricKeyAlgorithmTags.TRIPLE_DES: + case SymmetricKeyAlgorithmTags.AES_192: + case SymmetricKeyAlgorithmTags.CAMELLIA_192: keySize = 192; break; case SymmetricKeyAlgorithmTags.IDEA: - keySize = 128; - break; case SymmetricKeyAlgorithmTags.CAST5: - keySize = 128; - break; case SymmetricKeyAlgorithmTags.BLOWFISH: - keySize = 128; - break; case SymmetricKeyAlgorithmTags.SAFER: + case SymmetricKeyAlgorithmTags.AES_128: + case SymmetricKeyAlgorithmTags.CAMELLIA_128: keySize = 128; break; case SymmetricKeyAlgorithmTags.DES: keySize = 64; break; - case SymmetricKeyAlgorithmTags.AES_128: - keySize = 128; - break; - case SymmetricKeyAlgorithmTags.AES_192: - keySize = 192; - break; case SymmetricKeyAlgorithmTags.AES_256: - keySize = 256; - break; - case SymmetricKeyAlgorithmTags.CAMELLIA_128: - keySize = 128; - break; - case SymmetricKeyAlgorithmTags.CAMELLIA_192: - keySize = 192; - break; case SymmetricKeyAlgorithmTags.CAMELLIA_256: - keySize = 256; - break; case SymmetricKeyAlgorithmTags.TWOFISH: keySize = 256; break; @@ -481,7 +467,7 @@ private static boolean isPossiblyBase64( * @param in the stream to be checked and possibly wrapped. * @return a stream that will return PGP binary encoded data. * @throws IOException if an error occurs reading the stream, or initialising the - * {@link ArmoredInputStream}. + * {@link ArmoredInputStream}. */ public static InputStream getDecoderStream( InputStream in) diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPV3SignatureGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPV3SignatureGenerator.java index 605e6608ba..bca26ef189 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPV3SignatureGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPV3SignatureGenerator.java @@ -1,8 +1,6 @@ package org.bouncycastle.openpgp; import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; import java.math.BigInteger; import java.util.Date; @@ -17,132 +15,55 @@ * Generator for old style PGP V3 Signatures. */ public class PGPV3SignatureGenerator + extends PGPDefaultSignatureGenerator { - private byte lastb; - private OutputStream sigOut; private PGPContentSignerBuilder contentSignerBuilder; private PGPContentSigner contentSigner; - private int sigType; - private int providedKeyAlgorithm = -1; +// private int providedKeyAlgorithm = -1; /** * Create a signature generator built on the passed in contentSignerBuilder. * - * @param contentSignerBuilder builder to produce PGPContentSigner objects for generating signatures. + * @param contentSignerBuilder builder to produce PGPContentSigner objects for generating signatures. */ public PGPV3SignatureGenerator( PGPContentSignerBuilder contentSignerBuilder) { + super(SignaturePacket.VERSION_3); this.contentSignerBuilder = contentSignerBuilder; } - + /** * Initialise the generator for signing. - * + * * @param signatureType * @param key * @throws PGPException */ public void init( - int signatureType, + int signatureType, PGPPrivateKey key) throws PGPException { + if (signatureType == 0xFF) + { + throw new PGPException("Illegal signature type 0xFF provided."); + } + contentSigner = contentSignerBuilder.build(signatureType, key); sigOut = contentSigner.getOutputStream(); sigType = contentSigner.getType(); lastb = 0; - if (providedKeyAlgorithm >= 0 && providedKeyAlgorithm != contentSigner.getKeyAlgorithm()) - { - throw new PGPException("key algorithm mismatch"); - } - } - - public void update( - byte b) - { - if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) - { - if (b == '\r') - { - byteUpdate((byte)'\r'); - byteUpdate((byte)'\n'); - } - else if (b == '\n') - { - if (lastb != '\r') - { - byteUpdate((byte)'\r'); - byteUpdate((byte)'\n'); - } - } - else - { - byteUpdate(b); - } - - lastb = b; - } - else - { - byteUpdate(b); - } - } - - public void update( - byte[] b) - { - this.update(b, 0, b.length); - } - - public void update( - byte[] b, - int off, - int len) - { - if (sigType == PGPSignature.CANONICAL_TEXT_DOCUMENT) - { - int finish = off + len; - - for (int i = off; i != finish; i++) - { - this.update(b[i]); - } - } - else - { - blockUpdate(b, off, len); - } - } - - private void byteUpdate(byte b) - { - try - { - sigOut.write(b); - } - catch (IOException e) - { - throw new PGPRuntimeOperationException("unable to update signature: " + e.getMessage(), e); - } - } - - private void blockUpdate(byte[] block, int off, int len) - { - try - { - sigOut.write(block, off, len); - } - catch (IOException e) - { - throw new PGPRuntimeOperationException("unable to update signature: " + e.getMessage(), e); - } +// if (providedKeyAlgorithm >= 0 && providedKeyAlgorithm != contentSigner.getKeyAlgorithm()) +// { +// throw new PGPException("key algorithm mismatch"); +// } } /** * Return the one pass header associated with the current signature. - * + * * @param isNested * @return PGPOnePassSignature * @throws PGPException @@ -153,10 +74,10 @@ public PGPOnePassSignature generateOnePassVersion( { return new PGPOnePassSignature(new OnePassSignaturePacket(sigType, contentSigner.getHashAlgorithm(), contentSigner.getKeyAlgorithm(), contentSigner.getKeyID(), isNested)); } - + /** * Return a V3 signature object containing the current signature state. - * + * * @return PGPSignature * @throws PGPException */ @@ -180,7 +101,7 @@ public PGPSignature generate() MPInteger[] sigValues; if (contentSigner.getKeyAlgorithm() == PublicKeyAlgorithmTags.RSA_SIGN || contentSigner.getKeyAlgorithm() == PublicKeyAlgorithmTags.RSA_GENERAL) - // an RSA signature + // an RSA signature { sigValues = new MPInteger[1]; sigValues[0] = new MPInteger(new BigInteger(1, contentSigner.getSignature())); diff --git a/pg/src/main/java/org/bouncycastle/openpgp/Util.java b/pg/src/main/java/org/bouncycastle/openpgp/Util.java index 76242fa45b..af4a6c68e9 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/Util.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/Util.java @@ -2,6 +2,8 @@ import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; import org.bouncycastle.bcpg.BCPGInputStream; @@ -32,4 +34,13 @@ static BCPGInputStream createBCPGInputStream(InputStream pgIn, int tag1, int tag throw new IOException("unexpected tag " + bcIn.nextPacketTag() + " encountered"); } + + static void encodePGPSignatures(OutputStream stream, List sigs, boolean forTransfer) + throws IOException + { + for (int i = 0; i != sigs.size(); i++) + { + ((PGPSignature)sigs.get(i)).encode(stream, forTransfer); + } + } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/examples/ByteArrayHandler.java b/pg/src/main/java/org/bouncycastle/openpgp/examples/ByteArrayHandler.java index 636032e156..447519b89f 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/examples/ByteArrayHandler.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/examples/ByteArrayHandler.java @@ -139,7 +139,10 @@ public static byte[] encrypt( out = new ArmoredOutputStream(out); } - PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(algorithm).setSecureRandom(new SecureRandom()).setProvider("BC")); + JcePGPDataEncryptorBuilder encryptorBuilder = new JcePGPDataEncryptorBuilder(algorithm) + .setSecureRandom(new SecureRandom()).setProvider("BC"); + + PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encryptorBuilder); encGen.addMethod(new JcePBEKeyEncryptionMethodGenerator(passPhrase).setProvider("BC")); OutputStream encOut = encGen.open(out, compressedData.length); diff --git a/pg/src/main/java/org/bouncycastle/openpgp/examples/DSAElGamalKeyRingGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/examples/DSAElGamalKeyRingGenerator.java index 299666f13a..5876eddf1f 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/examples/DSAElGamalKeyRingGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/examples/DSAElGamalKeyRingGenerator.java @@ -4,25 +4,31 @@ import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; -import java.security.InvalidKeyException; +import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; -import java.security.SignatureException; import java.util.Date; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.bcpg.ArmoredOutputStream; +import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.sig.Features; +import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPKeyRingGenerator; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; +import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; +import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; @@ -35,52 +41,123 @@ *

      * usage: DSAElGamalKeyRingGenerator [-a] identity passPhrase *

      - * Where identity is the name to be associated with the public key. The keys are placed + * Where identity is the name to be associated with the public key. The keys are placed * in the files pub.[asc|bpg] and secret.[asc|bpg]. - *

      - * Note: this example encrypts the secret key using AES_256, many PGP products still - * do not support this, if you are having problems importing keys try changing the algorithm - * id to PGPEncryptedData.CAST5. CAST5 is more widely supported. */ public class DSAElGamalKeyRingGenerator { + + private static final int SIG_HASH = HashAlgorithmTags.SHA512; + private static final int[] HASH_PREFERENCES = new int[]{ + HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA224 + }; + private static final int[] SYM_PREFERENCES = new int[]{ + SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.AES_128 + }; + private static final int[] COMP = new int[]{ + CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2, CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.UNCOMPRESSED + }; + private static void exportKeyPair( - OutputStream secretOut, - OutputStream publicOut, - KeyPair dsaKp, - KeyPair elgKp, - String identity, - char[] passPhrase, - boolean armor) - throws IOException, InvalidKeyException, NoSuchProviderException, SignatureException, PGPException + OutputStream secretOut, + OutputStream publicOut, + KeyPair dsaKp, + KeyPair elgKp, + String identity, + char[] passPhrase, + boolean armor) + throws IOException, PGPException { if (armor) { secretOut = new ArmoredOutputStream(secretOut); } - PGPKeyPair dsaKeyPair = new JcaPGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); - PGPKeyPair elgKeyPair = new JcaPGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); + PGPKeyPair dsaKeyPair = new JcaPGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); + PGPKeyPair elgKeyPair = new JcaPGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1); - PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, - identity, sha1Calc, null, null, new JcaPGPContentSignerBuilder(dsaKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1), new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha1Calc).setProvider("BC").build(passPhrase)); - - keyRingGen.addSubKey(elgKeyPair); - + + PGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder( + dsaKeyPair.getPublicKey().getAlgorithm(), SIG_HASH); + PBESecretKeyEncryptor secretKeyEncryptor = new JcePBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256, sha1Calc) + .setProvider("BC") + .build(passPhrase); + + PGPSignatureSubpacketGenerator primaryHashedSubpackets = getPrimaryKeyHashedSubpackets(); + primaryHashedSubpackets.setIssuerFingerprint(false, dsaKeyPair.getPublicKey()); + PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, + identity, sha1Calc, primaryHashedSubpackets.generate(), null, contentSignerBuilder, secretKeyEncryptor); + + PGPSignatureSubpacketGenerator subkeyHashedSubpackets = getEncryptionKeyHashedSubpackets(); + subkeyHashedSubpackets.setIssuerFingerprint(false, dsaKeyPair.getPublicKey()); + keyRingGen.addSubKey(elgKeyPair, subkeyHashedSubpackets.generate(), null); + keyRingGen.generateSecretKeyRing().encode(secretOut); - + secretOut.close(); - + if (armor) { publicOut = new ArmoredOutputStream(publicOut); } - + keyRingGen.generatePublicKeyRing().encode(publicOut); - + publicOut.close(); } - + + private static PGPSignatureSubpacketGenerator getEncryptionKeyHashedSubpackets() + { + PGPSignatureSubpacketGenerator gen = new PGPSignatureSubpacketGenerator(); + gen.setKeyFlags(true, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE); + return gen; + } + + private static PGPSignatureSubpacketGenerator getPrimaryKeyHashedSubpackets() + { + PGPSignatureSubpacketGenerator gen = new PGPSignatureSubpacketGenerator(); + gen.setPreferredHashAlgorithms(false, HASH_PREFERENCES); + gen.setPreferredSymmetricAlgorithms(false, SYM_PREFERENCES); + gen.setPreferredCompressionAlgorithms(false, COMP); + gen.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION); + gen.setKeyFlags(true, KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA); + return gen; + } + + private static KeyPair generateElGamalKeyPair() + throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException + { + KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); + // 3072 bit parameters from https://datatracker.ietf.org/doc/html/rfc3526#section-4 + BigInteger g = new BigInteger("2", 16); + BigInteger p = new BigInteger("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF", 16); + + DHParameterSpec elParams = new DHParameterSpec(p, g); + + elgKpg.initialize(elParams); + + // + // this is quicker because we are using pregenerated parameters. + // + KeyPair elgKp = elgKpg.generateKeyPair(); + return elgKp; + } + + private static KeyPair generateDSAKeyPair() + throws NoSuchAlgorithmException, NoSuchProviderException + { + KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); + + dsaKpg.initialize(3072); + + // + // this takes a while as the key generator has to generate some DSA params + // before it generates the key. + // + KeyPair dsaKp = dsaKpg.generateKeyPair(); + return dsaKp; + } + public static void main( String[] args) throws Exception @@ -92,30 +169,11 @@ public static void main( System.out.println("DSAElGamalKeyRingGenerator [-a] identity passPhrase"); System.exit(0); } - - KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); - - dsaKpg.initialize(1024); - - // - // this takes a while as the key generator has to generate some DSA params - // before it generates the key. - // - KeyPair dsaKp = dsaKpg.generateKeyPair(); - - KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); - BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); - BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); - - DHParameterSpec elParams = new DHParameterSpec(p, g); - - elgKpg.initialize(elParams); - - // - // this is quicker because we are using pregenerated parameters. - // - KeyPair elgKp = elgKpg.generateKeyPair(); - + + KeyPair dsaKp = generateDSAKeyPair(); + + KeyPair elgKp = generateElGamalKeyPair(); + if (args[0].equals("-a")) { if (args.length < 3) @@ -123,17 +181,17 @@ public static void main( System.out.println("DSAElGamalKeyRingGenerator [-a] identity passPhrase"); System.exit(0); } - - FileOutputStream out1 = new FileOutputStream("secret.asc"); - FileOutputStream out2 = new FileOutputStream("pub.asc"); - + + FileOutputStream out1 = new FileOutputStream("secret.asc"); + FileOutputStream out2 = new FileOutputStream("pub.asc"); + exportKeyPair(out1, out2, dsaKp, elgKp, args[1], args[2].toCharArray(), true); } else { - FileOutputStream out1 = new FileOutputStream("secret.bpg"); - FileOutputStream out2 = new FileOutputStream("pub.bpg"); - + FileOutputStream out1 = new FileOutputStream("secret.bpg"); + FileOutputStream out2 = new FileOutputStream("pub.bpg"); + exportKeyPair(out1, out2, dsaKp, elgKp, args[0], args[1].toCharArray(), false); } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/examples/EllipticCurveKeyPairGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/examples/EllipticCurveKeyPairGenerator.java new file mode 100644 index 0000000000..26ce03e4a7 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/openpgp/examples/EllipticCurveKeyPairGenerator.java @@ -0,0 +1,175 @@ +package org.bouncycastle.openpgp.examples; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Security; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +import org.bouncycastle.bcpg.ArmoredOutputStream; +import org.bouncycastle.bcpg.CompressionAlgorithmTags; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.sig.Features; +import org.bouncycastle.bcpg.sig.KeyFlags; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPKeyPair; +import org.bouncycastle.openpgp.PGPKeyRingGenerator; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; +import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; +import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; + +/** + * A simple utility class that generates an RSA key ring. + *

      + * usage: RSAKeyPairGenerator [-a] identity passPhrase + *

      + * Where identity is the name to be associated with the public key. The keys are placed + * in the files pub.[asc|bpg] and secret.[asc|bpg]. + */ +public class EllipticCurveKeyPairGenerator +{ + + private static final int SIG_HASH = HashAlgorithmTags.SHA512; + private static final int[] HASH_PREFERENCES = new int[]{ + HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA224 + }; + private static final int[] SYM_PREFERENCES = new int[]{ + SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.AES_128 + }; + private static final int[] COMP_PREFERENCES = new int[]{ + CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2, CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.UNCOMPRESSED + }; + + private static void generateAndExportKeyRing( + OutputStream secretOut, + OutputStream publicOut, + String identity, + char[] passPhrase, + boolean armor) + throws IOException, NoSuchProviderException, PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException + { + if (armor) + { + secretOut = new ArmoredOutputStream(secretOut); + } + + PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1); + + KeyPairGenerator eddsaGen = KeyPairGenerator.getInstance("EdDSA", "BC"); + KeyPairGenerator xdhGen = KeyPairGenerator.getInstance("XDH", "BC"); + + PGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.EDDSA_LEGACY, SIG_HASH); + PBESecretKeyEncryptor secretKeyEncryptor = new JcePBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256, sha1Calc) + .build(passPhrase); + + Date now = new Date(); + + eddsaGen.initialize(new ECNamedCurveGenParameterSpec("ed25519")); + KeyPair primaryKP = eddsaGen.generateKeyPair(); + PGPKeyPair primaryKey = new JcaPGPKeyPair(PGPPublicKey.EDDSA_LEGACY, primaryKP, now); + PGPSignatureSubpacketGenerator primarySubpackets = new PGPSignatureSubpacketGenerator(); + primarySubpackets.setKeyFlags(true, KeyFlags.CERTIFY_OTHER); + primarySubpackets.setPreferredHashAlgorithms(false, HASH_PREFERENCES); + primarySubpackets.setPreferredSymmetricAlgorithms(false, SYM_PREFERENCES); + primarySubpackets.setPreferredCompressionAlgorithms(false, COMP_PREFERENCES); + primarySubpackets.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION); + primarySubpackets.setIssuerFingerprint(false, primaryKey.getPublicKey()); + + eddsaGen.initialize(new ECNamedCurveGenParameterSpec("ed25519")); + KeyPair signingKP = eddsaGen.generateKeyPair(); + PGPKeyPair signingKey = new JcaPGPKeyPair(PGPPublicKey.EDDSA_LEGACY, signingKP, now); + PGPSignatureSubpacketGenerator signingKeySubpacket = new PGPSignatureSubpacketGenerator(); + signingKeySubpacket.setKeyFlags(true, KeyFlags.SIGN_DATA); + signingKeySubpacket.setIssuerFingerprint(false, primaryKey.getPublicKey()); + + xdhGen.initialize(new ECNamedCurveGenParameterSpec("X25519")); + KeyPair encryptionKP = xdhGen.generateKeyPair(); + PGPKeyPair encryptionKey = new JcaPGPKeyPair(PGPPublicKey.ECDH, encryptionKP, now); + PGPSignatureSubpacketGenerator encryptionKeySubpackets = new PGPSignatureSubpacketGenerator(); + encryptionKeySubpackets.setKeyFlags(true, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE); + encryptionKeySubpackets.setIssuerFingerprint(false, primaryKey.getPublicKey()); + + PGPKeyRingGenerator gen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, primaryKey, identity, + sha1Calc, primarySubpackets.generate(), null, contentSignerBuilder, secretKeyEncryptor); + gen.addSubKey(signingKey, signingKeySubpacket.generate(), null, contentSignerBuilder); + gen.addSubKey(encryptionKey, encryptionKeySubpackets.generate(), null); + + PGPSecretKeyRing secretKeys = gen.generateSecretKeyRing(); + secretKeys.encode(secretOut); + + secretOut.close(); + + if (armor) + { + publicOut = new ArmoredOutputStream(publicOut); + } + + List publicKeyList = new ArrayList(); + Iterator it = secretKeys.getPublicKeys(); + while (it.hasNext()) + { + publicKeyList.add(it.next()); + } + + PGPPublicKeyRing publicKeys = new PGPPublicKeyRing(publicKeyList); + + publicKeys.encode(publicOut); + + publicOut.close(); + } + + public static void main( + String[] args) + throws Exception + { + Security.addProvider(new BouncyCastleProvider()); + + if (args.length < 2) + { + System.out.println("EllipticCurveKeyPairGenerator [-a] identity passPhrase"); + System.exit(0); + } + + if (args[0].equals("-a")) + { + if (args.length < 3) + { + System.out.println("EllipticCurveKeyPairGenerator [-a] identity passPhrase"); + System.exit(0); + } + + FileOutputStream out1 = new FileOutputStream("secret.asc"); + FileOutputStream out2 = new FileOutputStream("pub.asc"); + + generateAndExportKeyRing(out1, out2, args[1], args[2].toCharArray(), true); + } + else + { + FileOutputStream out1 = new FileOutputStream("secret.bpg"); + FileOutputStream out2 = new FileOutputStream("pub.bpg"); + + generateAndExportKeyRing(out1, out2, args[0], args[1].toCharArray(), false); + } + } +} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/examples/KeyBasedFileProcessor.java b/pg/src/main/java/org/bouncycastle/openpgp/examples/KeyBasedFileProcessor.java index 5d3ef8a561..0c93a712d1 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/examples/KeyBasedFileProcessor.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/examples/KeyBasedFileProcessor.java @@ -29,6 +29,7 @@ import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; +import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; @@ -216,8 +217,12 @@ private static void encryptFile( { byte[] bytes = PGPExampleUtil.compressFile(fileName, CompressionAlgorithmTags.ZIP); - PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator( - new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC")); + PGPDataEncryptorBuilder encryptorBuilder = new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5) + .setProvider("BC") + .setSecureRandom(new SecureRandom()) + .setWithIntegrityPacket(withIntegrityCheck); + + PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encryptorBuilder); encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC")); diff --git a/pg/src/main/java/org/bouncycastle/openpgp/examples/KeyBasedLargeFileProcessor.java b/pg/src/main/java/org/bouncycastle/openpgp/examples/KeyBasedLargeFileProcessor.java index 398796dc3a..936337c365 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/examples/KeyBasedLargeFileProcessor.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/examples/KeyBasedLargeFileProcessor.java @@ -29,6 +29,7 @@ import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; +import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; @@ -214,8 +215,13 @@ private static void encryptFile( } try - { - PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC")); + { + PGPDataEncryptorBuilder encryptorBuilder = new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5) + .setProvider("BC") + .setSecureRandom(new SecureRandom()) + .setWithIntegrityPacket(withIntegrityCheck); + + PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC")); diff --git a/pg/src/main/java/org/bouncycastle/openpgp/examples/PBEFileProcessor.java b/pg/src/main/java/org/bouncycastle/openpgp/examples/PBEFileProcessor.java index 9219b6f671..2c422d7dbc 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/examples/PBEFileProcessor.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/examples/PBEFileProcessor.java @@ -2,20 +2,21 @@ import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.Security; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.CompressionAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; -import org.bouncycastle.openpgp.PGPEncryptedData; +import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; @@ -23,6 +24,7 @@ import org.bouncycastle.openpgp.PGPPBEEncryptedData; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; +import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; @@ -33,9 +35,8 @@ * A simple utility class that encrypts/decrypts password based * encryption files. *

      - * To encrypt a file: PBEFileProcessor -e [-ai] fileName passPhrase.
      + * To encrypt a file: PBEFileProcessor -e [-a] fileName passPhrase.
      * If -a is specified the output file will be "ascii-armored".
      - * If -i is specified the output file will be "integrity protected". *

      * To decrypt: PBEFileProcessor -d fileName passPhrase. *

      @@ -46,7 +47,7 @@ public class PBEFileProcessor { private static void decryptFile(String inputFileName, char[] passPhrase) - throws IOException, NoSuchProviderException, PGPException + throws IOException, PGPException { InputStream in = new BufferedInputStream(new FileInputStream(inputFileName)); decryptFile(in, passPhrase); @@ -57,16 +58,16 @@ private static void decryptFile(String inputFileName, char[] passPhrase) * decrypt the passed in message stream */ private static void decryptFile( - InputStream in, - char[] passPhrase) - throws IOException, NoSuchProviderException, PGPException + InputStream in, + char[] passPhrase) + throws IOException, PGPException { in = PGPUtil.getDecoderStream(in); - - JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(in); - PGPEncryptedDataList enc; - Object o = pgpF.nextObject(); - + + JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(in); + PGPEncryptedDataList enc; + Object o = pgpF.nextObject(); + // // the first object might be a PGP marker packet. // @@ -79,27 +80,32 @@ private static void decryptFile( enc = (PGPEncryptedDataList)pgpF.nextObject(); } - PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); + PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); + if (!pbe.isIntegrityProtected()) + { + throw new PGPException("Message is not integrity protected!"); + } + + JcePBEDataDecryptorFactoryBuilder decryptorFactoryBuilder = new JcePBEDataDecryptorFactoryBuilder( + new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()) + .setProvider("BC"); - InputStream clear = pbe.getDataStream(new JcePBEDataDecryptorFactoryBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(passPhrase)); - - JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(clear); + InputStream clear = pbe.getDataStream(decryptorFactoryBuilder.build(passPhrase)); + pgpF = new JcaPGPObjectFactory(clear); // // if we're trying to read a file generated by someone other than us // the data might not be compressed, so we check the return type from // the factory and behave accordingly. // - o = pgpFact.nextObject(); + o = pgpF.nextObject(); if (o instanceof PGPCompressedData) { PGPCompressedData cData = (PGPCompressedData)o; - - pgpFact = new JcaPGPObjectFactory(cData.getDataStream()); - - o = pgpFact.nextObject(); + pgpF = new JcaPGPObjectFactory(cData.getDataStream()); + o = pgpF.nextObject(); } - + PGPLiteralData ld = (PGPLiteralData)o; InputStream unc = ld.getInputStream(); @@ -108,66 +114,68 @@ private static void decryptFile( Streams.pipeAll(unc, fOut, 8192); fOut.close(); - - if (pbe.isIntegrityProtected()) + if (!pbe.verify()) { - if (!pbe.verify()) - { - System.err.println("message failed integrity check"); - } - else - { - System.err.println("message integrity check passed"); - } + System.err.println("message failed integrity check"); } else { - System.err.println("no message integrity check"); + System.err.println("message integrity check passed"); } } private static void encryptFile( - String outputFileName, - String inputFileName, - char[] passPhrase, - boolean armor, - boolean withIntegrityCheck) - throws IOException, NoSuchProviderException + String outputFileName, + String inputFileName, + char[] passPhrase, + boolean armor) + throws IOException { OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName)); - encryptFile(out, inputFileName, passPhrase, armor, withIntegrityCheck); + encryptToStream(out, inputFileName, passPhrase, armor); out.close(); } - private static void encryptFile( - OutputStream out, - String fileName, - char[] passPhrase, - boolean armor, - boolean withIntegrityCheck) - throws IOException, NoSuchProviderException + private static void encryptToStream( + OutputStream out, + String fileName, + char[] passPhrase, + boolean armor) + throws IOException { if (armor) { out = new ArmoredOutputStream(out); } + File file = new File(fileName); + try { - byte[] compressedData = PGPExampleUtil.compressFile(fileName, CompressionAlgorithmTags.ZIP); - - PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5) - .setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC")); - + // Encryption + PGPDataEncryptorBuilder dataEncBuilder = new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256) + .setProvider("BC") + .setSecureRandom(new SecureRandom()) + .setWithIntegrityPacket(true); + PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(dataEncBuilder); encGen.addMethod(new JcePBEKeyEncryptionMethodGenerator(passPhrase).setProvider("BC")); + OutputStream encOut = encGen.open(out, new byte[8192]); + + // Compression + PGPCompressedDataGenerator compGen = new PGPCompressedDataGenerator(CompressionAlgorithmTags.ZIP); + OutputStream compOut = compGen.open(encOut); - OutputStream encOut = encGen.open(out, compressedData.length); + // Literal Data + PGPUtil.writeFileToLiteralData(compOut, PGPLiteralData.BINARY, file); - encOut.write(compressedData); + compOut.flush(); + compOut.close(); + encOut.flush(); encOut.close(); if (armor) { + out.flush(); out.close(); } } @@ -182,24 +190,20 @@ private static void encryptFile( } public static void main( - String[] args) - throws Exception + String[] args) + throws Exception { Security.addProvider(new BouncyCastleProvider()); if (args[0].equals("-e")) { - if (args[1].equals("-a") || args[1].equals("-ai") || args[1].equals("-ia")) - { - encryptFile(args[2] + ".asc", args[2], args[3].toCharArray(), true, (args[1].indexOf('i') > 0)); - } - else if (args[1].equals("-i")) + if (args[1].equals("-a")) { - encryptFile(args[2] + ".bpg", args[2], args[3].toCharArray(), false, true); + encryptFile(args[2] + ".asc", args[2], args[3].toCharArray(), true); } else { - encryptFile(args[1] + ".bpg", args[1], args[2].toCharArray(), false, false); + encryptFile(args[1] + ".bpg", args[1], args[2].toCharArray(), false); } } else if (args[0].equals("-d")) @@ -208,7 +212,7 @@ else if (args[0].equals("-d")) } else { - System.err.println("usage: PBEFileProcessor -e [-ai]|-d file passPhrase"); + System.err.println("usage: PBEFileProcessor -e [-a]|-d file passPhrase"); } } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/examples/RSAKeyPairGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/examples/RSAKeyPairGenerator.java index f4734428e8..a076b47849 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/examples/RSAKeyPairGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/examples/RSAKeyPairGenerator.java @@ -3,23 +3,34 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; -import java.security.SignatureException; +import java.util.ArrayList; import java.util.Date; +import java.util.Iterator; +import java.util.List; import org.bouncycastle.bcpg.ArmoredOutputStream; +import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.sig.Features; +import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; +import org.bouncycastle.openpgp.PGPKeyRingGenerator; import org.bouncycastle.openpgp.PGPPublicKey; -import org.bouncycastle.openpgp.PGPSecretKey; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; +import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; +import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; @@ -27,67 +38,115 @@ import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; /** - * A simple utility class that generates a RSA PGPPublicKey/PGPSecretKey pair. + * A simple utility class that generates an RSA key ring. *

      * usage: RSAKeyPairGenerator [-a] identity passPhrase *

      - * Where identity is the name to be associated with the public key. The keys are placed + * Where identity is the name to be associated with the public key. The keys are placed * in the files pub.[asc|bpg] and secret.[asc|bpg]. */ public class RSAKeyPairGenerator { - private static void exportKeyPair( - OutputStream secretOut, - OutputStream publicOut, - KeyPair pair, - String identity, - char[] passPhrase, - boolean armor) - throws IOException, InvalidKeyException, NoSuchProviderException, SignatureException, PGPException - { + + private static final int SIG_HASH = HashAlgorithmTags.SHA512; + private static final int[] HASH_PREFERENCES = new int[]{ + HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA224 + }; + private static final int[] SYM_PREFERENCES = new int[]{ + SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.AES_128 + }; + private static final int[] COMP_PREFERENCES = new int[]{ + CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2, CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.UNCOMPRESSED + }; + + private static void generateAndExportKeyRing( + OutputStream secretOut, + OutputStream publicOut, + String identity, + char[] passPhrase, + boolean armor) + throws IOException, NoSuchProviderException, PGPException, NoSuchAlgorithmException + { if (armor) { secretOut = new ArmoredOutputStream(secretOut); } PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1); - PGPKeyPair keyPair = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL, pair, new Date()); - PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, keyPair, identity, sha1Calc, null, null, new JcaPGPContentSignerBuilder(keyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA256), new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.CAST5, sha1Calc).setProvider("BC").build(passPhrase)); - - secretKey.encode(secretOut); - + KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); + + PGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, SIG_HASH).setProvider("BC"); + PBESecretKeyEncryptor secretKeyEncryptor = new JcePBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256, sha1Calc).setProvider("BC") + .build(passPhrase); + + Date now = new Date(); + + kpg.initialize(3072); + KeyPair primaryKP = kpg.generateKeyPair(); + PGPKeyPair primaryKey = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL, primaryKP, now); + PGPSignatureSubpacketGenerator primarySubpackets = new PGPSignatureSubpacketGenerator(); + primarySubpackets.setKeyFlags(true, KeyFlags.CERTIFY_OTHER); + primarySubpackets.setPreferredHashAlgorithms(false, HASH_PREFERENCES); + primarySubpackets.setPreferredSymmetricAlgorithms(false, SYM_PREFERENCES); + primarySubpackets.setPreferredCompressionAlgorithms(false, COMP_PREFERENCES); + primarySubpackets.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION); + primarySubpackets.setIssuerFingerprint(false, primaryKey.getPublicKey()); + + kpg.initialize(3072); + KeyPair signingKP = kpg.generateKeyPair(); + PGPKeyPair signingKey = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL, signingKP, now); + PGPSignatureSubpacketGenerator signingKeySubpacket = new PGPSignatureSubpacketGenerator(); + signingKeySubpacket.setKeyFlags(true, KeyFlags.SIGN_DATA); + signingKeySubpacket.setIssuerFingerprint(false, primaryKey.getPublicKey()); + + kpg.initialize(3072); + KeyPair encryptionKP = kpg.generateKeyPair(); + PGPKeyPair encryptionKey = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL, encryptionKP, now); + PGPSignatureSubpacketGenerator encryptionKeySubpackets = new PGPSignatureSubpacketGenerator(); + encryptionKeySubpackets.setKeyFlags(true, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE); + encryptionKeySubpackets.setIssuerFingerprint(false, primaryKey.getPublicKey()); + + PGPKeyRingGenerator gen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, primaryKey, identity, + sha1Calc, primarySubpackets.generate(), null, contentSignerBuilder, secretKeyEncryptor); + gen.addSubKey(signingKey, signingKeySubpacket.generate(), null, contentSignerBuilder); + gen.addSubKey(encryptionKey, encryptionKeySubpackets.generate(), null); + + PGPSecretKeyRing secretKeys = gen.generateSecretKeyRing(); + secretKeys.encode(secretOut); + secretOut.close(); - + if (armor) { publicOut = new ArmoredOutputStream(publicOut); } - PGPPublicKey key = secretKey.getPublicKey(); - - key.encode(publicOut); - + List publicKeyList = new ArrayList(); + Iterator it = secretKeys.getPublicKeys(); + while (it.hasNext()) + { + publicKeyList.add(it.next()); + } + + PGPPublicKeyRing publicKeys = new PGPPublicKeyRing(publicKeyList); + + publicKeys.encode(publicOut); + publicOut.close(); } - + public static void main( String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); - KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); - - kpg.initialize(1024); - - KeyPair kp = kpg.generateKeyPair(); - if (args.length < 2) { System.out.println("RSAKeyPairGenerator [-a] identity passPhrase"); System.exit(0); } - + if (args[0].equals("-a")) { if (args.length < 3) @@ -95,18 +154,18 @@ public static void main( System.out.println("RSAKeyPairGenerator [-a] identity passPhrase"); System.exit(0); } - - FileOutputStream out1 = new FileOutputStream("secret.asc"); - FileOutputStream out2 = new FileOutputStream("pub.asc"); - - exportKeyPair(out1, out2, kp, args[1], args[2].toCharArray(), true); + + FileOutputStream out1 = new FileOutputStream("secret.asc"); + FileOutputStream out2 = new FileOutputStream("pub.asc"); + + generateAndExportKeyRing(out1, out2, args[1], args[2].toCharArray(), true); } else { - FileOutputStream out1 = new FileOutputStream("secret.bpg"); - FileOutputStream out2 = new FileOutputStream("pub.bpg"); - - exportKeyPair(out1, out2, kp, args[0], args[1].toCharArray(), false); + FileOutputStream out1 = new FileOutputStream("secret.bpg"); + FileOutputStream out2 = new FileOutputStream("pub.bpg"); + + generateAndExportKeyRing(out1, out2, args[0], args[1].toCharArray(), false); } } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEDataDecryptorFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEDataDecryptorFactory.java index 8538e4f67d..0a4e7896b0 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEDataDecryptorFactory.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEDataDecryptorFactory.java @@ -2,6 +2,7 @@ import org.bouncycastle.bcpg.S2K; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket; import org.bouncycastle.openpgp.PGPException; /** @@ -43,7 +44,8 @@ public byte[] makeKeyFromPassPhrase(int keyAlgorithm, S2K s2k) } /** - * Decrypts session data from an encrypted data packet. + * Decrypts session data from a {@link SymmetricKeyEncSessionPacket#VERSION_4 v4 SKESK} packet. + * These are used in OpenPGP v4. * * @param keyAlgorithm the {@link SymmetricKeyAlgorithmTags encryption algorithm} used to * encrypt the session data. @@ -54,4 +56,17 @@ public byte[] makeKeyFromPassPhrase(int keyAlgorithm, S2K s2k) */ public abstract byte[] recoverSessionData(int keyAlgorithm, byte[] key, byte[] seckKeyData) throws PGPException; + + /** + * Recover the session data of a {@link SymmetricKeyEncSessionPacket#VERSION_5 v5 SKESK} or + * {@link SymmetricKeyEncSessionPacket#VERSION_6 v6 SKESK} packet. + * These are used in OpenPGP v5 and v6. + * + * @param keyData v5 or v6 SKESK packet + * @param ikm initial keying material (e.g. S2K result) + * @return session key + * @throws PGPException + */ + public abstract byte[] recoverAEADEncryptedSessionData(SymmetricKeyEncSessionPacket keyData, byte[] ikm) + throws PGPException; } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java index 48714f279c..48de87704b 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java @@ -2,11 +2,13 @@ import java.security.SecureRandom; +import org.bouncycastle.bcpg.AEADUtils; import org.bouncycastle.bcpg.ContainedPacket; import org.bouncycastle.bcpg.S2K; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket; import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.util.Arrays; /** * PGP style PBE encryption method. @@ -159,16 +161,86 @@ public byte[] getKey(int encAlgorithm) return PGPUtil.makeKeyFromPassPhrase(s2kDigestCalculator, encAlgorithm, s2k, passPhrase); } - public ContainedPacket generate(int encAlgorithm, byte[] sessionInfo) + @Override + public ContainedPacket generateV5(int kekAlgorithm, int aeadAlgorithm, byte[] sessionInfo) + throws PGPException + { + return generate(kekAlgorithm, sessionInfo); + // TODO: Implement v5 SKESK creation properly. + // return generateV5ESK(kekAlgorithm, aeadAlgorithm, sessionInfo); + } + + @Override + public ContainedPacket generateV6(int kekAlgorithm, int aeadAlgorithm, byte[] sessionInfo) throws PGPException { - byte[] key = getKey(encAlgorithm); + return generateV6ESK(kekAlgorithm, aeadAlgorithm, sessionInfo); + } + + // If we use this method, roundtripping v5 AEAD is broken. + // TODO: Investigate + private ContainedPacket generateV5ESK(int kekAlgorithm, int aeadAlgorithm, byte[] sessionInfo) + throws PGPException + { + byte[] ikm = getKey(kekAlgorithm); + byte[] info = new byte[] { + (byte) 0xC3, + (byte) SymmetricKeyEncSessionPacket.VERSION_5, + (byte) kekAlgorithm, + (byte) aeadAlgorithm + }; + + byte[] iv = new byte[AEADUtils.getIVLength(aeadAlgorithm)]; + random.nextBytes(iv); + + int tagLen = AEADUtils.getAuthTagLength(aeadAlgorithm); + byte[] eskAndTag = getEskAndTag(kekAlgorithm, aeadAlgorithm, sessionInfo, ikm, iv, info); + byte[] esk = Arrays.copyOfRange(eskAndTag, 0, eskAndTag.length - tagLen); + byte[] tag = Arrays.copyOfRange(eskAndTag, esk.length, eskAndTag.length); + + return SymmetricKeyEncSessionPacket.createV5Packet(kekAlgorithm, aeadAlgorithm, iv, s2k, esk, tag); + } + + private ContainedPacket generateV6ESK(int kekAlgorithm, int aeadAlgorithm, byte[] sessionInfo) + throws PGPException + { + byte[] ikm = getKey(kekAlgorithm); + byte[] info = new byte[] { + (byte) 0xC3, + (byte) SymmetricKeyEncSessionPacket.VERSION_6, + (byte) kekAlgorithm, + (byte) aeadAlgorithm + }; + byte[] kek = generateV6KEK(kekAlgorithm, ikm, info); + + byte[] iv = new byte[AEADUtils.getIVLength(aeadAlgorithm)]; + random.nextBytes(iv); + int tagLen = AEADUtils.getAuthTagLength(aeadAlgorithm); + byte[] eskAndTag = getEskAndTag(kekAlgorithm, aeadAlgorithm, sessionInfo, kek, iv, info); + byte[] esk = Arrays.copyOfRange(eskAndTag, 0, eskAndTag.length - tagLen); + byte[] tag = Arrays.copyOfRange(eskAndTag, esk.length, eskAndTag.length); + + return SymmetricKeyEncSessionPacket.createV6Packet(kekAlgorithm, aeadAlgorithm, iv, s2k, esk, tag); + } + + /** + * Generate a V4 SKESK packet. + * + * @param encAlgorithm the {@link SymmetricKeyAlgorithmTags encryption algorithm} being used + * @param sessionInfo session data generated by the encrypted data generator. + * @return v4 SKESK packet + * @throws PGPException + */ + public ContainedPacket generate(int encAlgorithm, byte[] sessionInfo) + throws PGPException + { if (sessionInfo == null) { - return new SymmetricKeyEncSessionPacket(encAlgorithm, s2k, null); + return SymmetricKeyEncSessionPacket.createV4Packet(encAlgorithm, s2k, null); } + byte[] key = getKey(encAlgorithm); // // the passed in session info has the an RSA/ElGamal checksum added to it, for PBE this is not included. // @@ -176,9 +248,15 @@ public ContainedPacket generate(int encAlgorithm, byte[] sessionInfo) System.arraycopy(sessionInfo, 0, nSessionInfo, 0, nSessionInfo.length); - return new SymmetricKeyEncSessionPacket(encAlgorithm, s2k, encryptSessionInfo(encAlgorithm, key, nSessionInfo)); + return SymmetricKeyEncSessionPacket.createV4Packet(encAlgorithm, s2k, encryptSessionInfo(encAlgorithm, key, nSessionInfo)); } abstract protected byte[] encryptSessionInfo(int encAlgorithm, byte[] key, byte[] sessionInfo) throws PGPException; + + abstract protected byte[] getEskAndTag(int kekAlgorithm, int aeadAlgorithm, byte[] sessionInfo, byte[] key, byte[] iv, byte[] info) + throws PGPException; + + abstract protected byte[] generateV6KEK(int kekAlgorithm, byte[] ikm, byte[] info) + throws PGPException; } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBESecretKeyDecryptor.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBESecretKeyDecryptor.java index 290fa1ec0d..c4cfbc09f1 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBESecretKeyDecryptor.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBESecretKeyDecryptor.java @@ -28,4 +28,15 @@ public byte[] makeKeyFromPassPhrase(int keyAlgorithm, S2K s2k) public abstract byte[] recoverKeyData(int encAlgorithm, byte[] key, byte[] iv, byte[] keyData, int keyOff, int keyLen) throws PGPException; + + public abstract byte[] recoverKeyData( + int encAlgorithm, + int aeadAlgorithm, + byte[] s2kKey, + byte[] iv, + int packetTag, + int keyVersion, + byte[] keyData, + byte[] pubkeyData) + throws PGPException; } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBESecretKeyEncryptor.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBESecretKeyEncryptor.java index 02edcf5ede..956cc9067a 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBESecretKeyEncryptor.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBESecretKeyEncryptor.java @@ -8,6 +8,7 @@ public abstract class PBESecretKeyEncryptor { protected int encAlgorithm; + protected int aeadAlgorithm; protected char[] passPhrase; protected PGPDigestCalculator s2kDigestCalculator; protected int s2kCount; @@ -15,6 +16,15 @@ public abstract class PBESecretKeyEncryptor protected SecureRandom random; + protected PBESecretKeyEncryptor(int encAlgorithm, int aeadAlgorithm, S2K.Argon2Params argon2Params, SecureRandom random, char[] passPhrase) + { + this.encAlgorithm = encAlgorithm; + this.aeadAlgorithm = aeadAlgorithm; + this.passPhrase = passPhrase; + this.s2k = S2K.argon2S2K(argon2Params); + this.random = random; + } + protected PBESecretKeyEncryptor(int encAlgorithm, PGPDigestCalculator s2kDigestCalculator, SecureRandom random, char[] passPhrase) { this(encAlgorithm, s2kDigestCalculator, 0x60, random, passPhrase); @@ -40,6 +50,11 @@ public int getAlgorithm() return encAlgorithm; } + public int getAeadAlgorithm() + { + return aeadAlgorithm; + } + public int getHashAlgorithm() { if (s2kDigestCalculator != null) diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPAEADDataEncryptor.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPAEADDataEncryptor.java index 9648aeb263..a2985263f3 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPAEADDataEncryptor.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPAEADDataEncryptor.java @@ -1,7 +1,10 @@ package org.bouncycastle.openpgp.operator; + /** - * A data encryptor, using AEAD + * A data encryptor, using AEAD. + * There are two different flavours of AEAD encryption used with OpenPGP. + * OpenPGP v5 AEAD is slightly different from v6 AEAD. *

      * {@link PGPAEADDataEncryptor} instances are generally not constructed directly, but obtained from a * {@link PGPDataEncryptorBuilder}. @@ -15,4 +18,5 @@ public interface PGPAEADDataEncryptor int getChunkSize(); byte[] getIV(); + } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataDecryptorFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataDecryptorFactory.java index 21beecf010..b7a616d94c 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataDecryptorFactory.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataDecryptorFactory.java @@ -1,7 +1,10 @@ package org.bouncycastle.openpgp.operator; +import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPSessionKey; /** * Base interface of factories for {@link PGPDataDecryptor}. @@ -9,7 +12,8 @@ public interface PGPDataDecryptorFactory { /** - * Constructs a data decryptor. + * Constructs a data decryptor for {@link org.bouncycastle.bcpg.SymmetricEncDataPacket SED} or + * {@link SymmetricEncIntegrityPacket#VERSION_1 v1 SEIPD} packets. * * @param withIntegrityPacket true if the packet to be decrypted has integrity * checking enabled. @@ -24,18 +28,28 @@ PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorit throws PGPException; /** - * Constructs an AEAD data decryptor. + * Constructs a data decryptor for {@link AEADEncDataPacket AEAD Encrypted Data} packets. + * This method is used with OpenPGP v5 AEAD. * - * @param aeadAlgorithm the identifier of the {@link org.bouncycastle.bcpg.AEADAlgorithmTags encryption algorithm} to use. - * @param iv the initialization vector to build the AEAD nonces from. - * @param chunkSize the chunksize value for the AEAD encrypted chunks. - * @param encAlgorithm the identifier of the {@link org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags encryption - * algorithm} to decrypt with. - * @param key the bytes of the key for the cipher. + * @param aeadEncDataPacket AEAD encrypted data packet + * @param sessionKey decrypted session key + * @return a data decryptor that can decrypt (and verify) streams of encrypted data. + * @throws PGPException if an error occurs initialising the decryption and integrity checking + * functions. + */ + PGPDataDecryptor createDataDecryptor(AEADEncDataPacket aeadEncDataPacket, PGPSessionKey sessionKey) + throws PGPException; + + /** + * Constructs a data decryptor for {@link SymmetricEncIntegrityPacket#VERSION_2 v2 SEIPD} packets. + * This method is used with OpenPGP v6 AEAD. + * + * @param seipd version 2 symmetrically encrypted integrity-protected data packet using AEAD. + * @param sessionKey decrypted session key * @return a data decryptor that can decrypt (and verify) streams of encrypted data. * @throws PGPException if an error occurs initialising the decryption and integrity checking * functions. */ - PGPDataDecryptor createDataDecryptor(int aeadAlgorithm, byte[] iv, int chunkSize, int encAlgorithm, byte[] key) + PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, PGPSessionKey sessionKey) throws PGPException; } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataEncryptorBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataEncryptorBuilder.java index de5dd272b6..27e8152c40 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataEncryptorBuilder.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataEncryptorBuilder.java @@ -17,6 +17,12 @@ public interface PGPDataEncryptorBuilder */ int getAlgorithm(); + int getAeadAlgorithm(); + + int getChunkSize(); + + boolean isV5StyleAEAD(); + /** * Builds a data encryptor using the algorithm configured for this builder. * @@ -44,12 +50,28 @@ PGPDataEncryptor build(byte[] keyBytes) PGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPacket); /** - * Sets whether or not the resulting encrypted data will be protected using an AEAD mode. + * Sets whether the resulting encrypted data will be protected using an AEAD mode. + * * The chunkSize is used as a power of two, result in blocks (1 << chunkSize) containing data * with an extra 16 bytes for the tag. The minimum chunkSize is 6. * * @param aeadAlgorithm the AEAD mode to use. * @param chunkSize the size of the chunks to be processed with each nonce. + * @return the current builder */ PGPDataEncryptorBuilder setWithAEAD(int aeadAlgorithm, int chunkSize); + + /** + * Specify we are using V5 AEAD. + * + * @return the current builder + */ + PGPDataEncryptorBuilder setUseV5AEAD(); + + /** + * Specify we are using V6 AEAD. + * + * @return the current builder + */ + PGPDataEncryptorBuilder setUseV6AEAD(); } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPKeyConverter.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPKeyConverter.java new file mode 100644 index 0000000000..ab73bd51d8 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPKeyConverter.java @@ -0,0 +1,122 @@ +package org.bouncycastle.openpgp.operator; + +import java.io.IOException; +import java.math.BigInteger; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; +import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.sec.SECObjectIdentifiers; +import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.openpgp.PGPAlgorithmParameters; +import org.bouncycastle.openpgp.PGPKdfParameters; +import org.bouncycastle.util.BigIntegers; + +public abstract class PGPKeyConverter +{ + protected PGPKeyConverter() + { + + } + + /** + * Reference: RFC Draft-ietf-openpgp-crypto-refresh-13 + *

      + * This class provides information about the recommended algorithms to use + * depending on the key version and curve type in OpenPGP keys. + * + *

      + * For OpenPGP keys using the specified curves, the following algorithms are recommended: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      Recommended Algorithms for OpenPGP Keys
      CurveHash AlgorithmSymmetric Algorithm
      NIST P-256SHA2-256AES-128
      NIST P-384SHA2-384AES-192
      NIST P-521SHA2-512AES-256
      brainpoolP256r1SHA2-256AES-128
      brainpoolP384r1SHA2-384AES-192
      brainpoolP512r1SHA2-512AES-256
      Curve25519LegacySHA2-256AES-128
      Curve448Legacy (not in RFC Draft)SHA2-512AES-256
      + */ + protected PGPKdfParameters implGetKdfParameters(ASN1ObjectIdentifier curveID, PGPAlgorithmParameters algorithmParameters) + { + if (null == algorithmParameters) + { + if (curveID.equals(SECObjectIdentifiers.secp256r1) || curveID.equals(TeleTrusTObjectIdentifiers.brainpoolP256r1) + || curveID.equals(CryptlibObjectIdentifiers.curvey25519) || curveID.equals(EdECObjectIdentifiers.id_X25519)) + { + return new PGPKdfParameters(HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_128); + } + else if (curveID.equals(SECObjectIdentifiers.secp384r1) || curveID.equals(TeleTrusTObjectIdentifiers.brainpoolP384r1)) + { + return new PGPKdfParameters(HashAlgorithmTags.SHA384, SymmetricKeyAlgorithmTags.AES_192); + } + else if (curveID.equals(SECObjectIdentifiers.secp521r1) || curveID.equals(TeleTrusTObjectIdentifiers.brainpoolP512r1) + || curveID.equals(EdECObjectIdentifiers.id_X448)) + { + return new PGPKdfParameters(HashAlgorithmTags.SHA512, SymmetricKeyAlgorithmTags.AES_256); + } + else + { + throw new IllegalArgumentException("unknown curve"); + } + } + return (PGPKdfParameters)algorithmParameters; + } + + protected PrivateKeyInfo getPrivateKeyInfo(ASN1ObjectIdentifier algorithm, int keySize, byte[] key) + throws IOException + { + return (new PrivateKeyInfo(new AlgorithmIdentifier(algorithm), + new DEROctetString(BigIntegers.asUnsignedByteArray(keySize, new BigInteger(1, key))))); + } + + protected PrivateKeyInfo getPrivateKeyInfo(ASN1ObjectIdentifier algorithm, byte[] key) + throws IOException + { + return (new PrivateKeyInfo(new AlgorithmIdentifier(algorithm), new DEROctetString(key))); + } +} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPKeyEncryptionMethodGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPKeyEncryptionMethodGenerator.java index 97e703d6db..7a494e23e8 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPKeyEncryptionMethodGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPKeyEncryptionMethodGenerator.java @@ -12,7 +12,7 @@ public abstract class PGPKeyEncryptionMethodGenerator { /** * Generates a packet encoding the details of this encryption method. - * + * * @param encAlgorithm the {@link SymmetricKeyAlgorithmTags encryption algorithm} being used * @param sessionInfo session data generated by the encrypted data generator. * @return a packet encoding the provided information and the configuration of this instance. @@ -20,4 +20,10 @@ public abstract class PGPKeyEncryptionMethodGenerator */ public abstract ContainedPacket generate(int encAlgorithm, byte[] sessionInfo) throws PGPException; + + public abstract ContainedPacket generateV5(int encAlgorithm, int aeadAlgorithm, byte[] sessionInfo) + throws PGPException; + + public abstract ContainedPacket generateV6(int encAlgorithm, int aeadAlgorithm, byte[] sessionInfo) + throws PGPException; } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPUtil.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPUtil.java index 387237f55c..2d77e5d9a1 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPUtil.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPUtil.java @@ -24,63 +24,30 @@ static byte[] makeKeyFromPassPhrase( char[] passPhrase) throws PGPException { - // TODO: Never used - String algName = null; - int keySize = 0; + int keySize; switch (algorithm) { case SymmetricKeyAlgorithmTags.TRIPLE_DES: + case SymmetricKeyAlgorithmTags.AES_192: + case SymmetricKeyAlgorithmTags.CAMELLIA_192: keySize = 192; - algName = "DES_EDE"; break; case SymmetricKeyAlgorithmTags.IDEA: - keySize = 128; - algName = "IDEA"; - break; case SymmetricKeyAlgorithmTags.CAST5: - keySize = 128; - algName = "CAST5"; - break; case SymmetricKeyAlgorithmTags.BLOWFISH: - keySize = 128; - algName = "Blowfish"; - break; case SymmetricKeyAlgorithmTags.SAFER: + case SymmetricKeyAlgorithmTags.AES_128: + case SymmetricKeyAlgorithmTags.CAMELLIA_128: keySize = 128; - algName = "SAFER"; break; case SymmetricKeyAlgorithmTags.DES: keySize = 64; - algName = "DES"; - break; - case SymmetricKeyAlgorithmTags.AES_128: - keySize = 128; - algName = "AES"; - break; - case SymmetricKeyAlgorithmTags.AES_192: - keySize = 192; - algName = "AES"; break; case SymmetricKeyAlgorithmTags.AES_256: - keySize = 256; - algName = "AES"; - break; case SymmetricKeyAlgorithmTags.TWOFISH: - keySize = 256; - algName = "Twofish"; - break; - case SymmetricKeyAlgorithmTags.CAMELLIA_128: - keySize = 128; - algName = "Camellia"; - break; - case SymmetricKeyAlgorithmTags.CAMELLIA_192: - keySize = 192; - algName = "Camellia"; - break; case SymmetricKeyAlgorithmTags.CAMELLIA_256: keySize = 256; - algName = "Camellia"; break; default: throw new PGPException("unknown symmetric algorithm: " + algorithm); @@ -127,6 +94,7 @@ else if (s2k.getHashAlgorithm() != digestCalculator.getAlgorithm()) try { + byte[] iv = s2k != null? s2k.getIV() : null; while (generatedBytes < keyBytes.length) { if (s2k != null) @@ -136,8 +104,6 @@ else if (s2k.getHashAlgorithm() != digestCalculator.getAlgorithm()) dOut.write(0); } - byte[] iv = s2k.getIV(); - switch (s2k.getType()) { case S2K.SIMPLE: diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PublicKeyKeyEncryptionMethodGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PublicKeyKeyEncryptionMethodGenerator.java index 876414507e..0d9b46ca6a 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PublicKeyKeyEncryptionMethodGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PublicKeyKeyEncryptionMethodGenerator.java @@ -1,19 +1,21 @@ package org.bouncycastle.openpgp.operator; -import java.io.IOException; -import java.math.BigInteger; - import org.bouncycastle.bcpg.ContainedPacket; import org.bouncycastle.bcpg.MPInteger; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyEncSessionPacket; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.util.Properties; +import java.io.IOException; +import java.math.BigInteger; + public abstract class PublicKeyKeyEncryptionMethodGenerator extends PGPKeyEncryptionMethodGenerator { public static final String SESSION_KEY_OBFUSCATION_PROPERTY = "org.bouncycastle.openpgp.session_key_obfuscation"; + public static final long WILDCARD = 0L; private static boolean getSessionKeyObfuscationDefault() { @@ -24,6 +26,7 @@ private static boolean getSessionKeyObfuscationDefault() private PGPPublicKey pubKey; protected boolean sessionKeyObfuscation; + protected boolean useWildcardKeyID; protected PublicKeyKeyEncryptionMethodGenerator( PGPPublicKey pubKey) @@ -32,18 +35,22 @@ protected PublicKeyKeyEncryptionMethodGenerator( { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_GENERAL: - break; - case PGPPublicKey.RSA_SIGN: - throw new IllegalArgumentException("Can't use an RSA_SIGN key for encryption."); case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: - break; case PGPPublicKey.ECDH: + case PGPPublicKey.X25519: + case PGPPublicKey.X448: break; + case PGPPublicKey.RSA_SIGN: + throw new IllegalArgumentException("Can't use an RSA_SIGN key for encryption."); case PGPPublicKey.DSA: throw new IllegalArgumentException("Can't use DSA for encryption."); case PGPPublicKey.ECDSA: throw new IllegalArgumentException("Can't use ECDSA for encryption."); + case PublicKeyAlgorithmTags.Ed448: + case PublicKeyAlgorithmTags.Ed25519: + case PublicKeyAlgorithmTags.EDDSA_LEGACY: + throw new IllegalArgumentException("Can't use EdDSA for encryption."); default: throw new IllegalArgumentException("unknown asymmetric algorithm: " + pubKey.getAlgorithm()); } @@ -57,6 +64,7 @@ protected PublicKeyKeyEncryptionMethodGenerator( *

      * The default behaviour can be configured using the system property "", or else it will default to enabled. *

      + * * @return the current generator. */ public PublicKeyKeyEncryptionMethodGenerator setSessionKeyObfuscation(boolean enabled) @@ -66,6 +74,19 @@ public PublicKeyKeyEncryptionMethodGenerator setSessionKeyObfuscation(boolean en return this; } + /** + * Controls whether the recipient key ID is hidden (replaced by a wildcard ID
      0
      ). + * + * @param enabled boolean + * @return this + */ + public PublicKeyKeyEncryptionMethodGenerator setUseWildcardKeyID(boolean enabled) + { + this.useWildcardKeyID = enabled; + + return this; + } + public byte[][] processSessionInfo( byte[] encryptedSessionInfo) throws PGPException @@ -93,6 +114,8 @@ public byte[][] processSessionInfo( data[1] = convertToEncodedMPI(b2); break; case PGPPublicKey.ECDH: + case PGPPublicKey.X448: + case PGPPublicKey.X25519: data = new byte[1][]; data[0] = encryptedSessionInfo; @@ -120,9 +143,56 @@ private byte[] convertToEncodedMPI(byte[] encryptedSessionInfo) public ContainedPacket generate(int encAlgorithm, byte[] sessionInfo) throws PGPException { - return new PublicKeyEncSessionPacket(pubKey.getKeyID(), pubKey.getAlgorithm(), processSessionInfo(encryptSessionInfo(pubKey, sessionInfo))); + long keyId; + if (useWildcardKeyID) + { + keyId = WILDCARD; + } + else + { + keyId = pubKey.getKeyID(); + } + return PublicKeyEncSessionPacket.createV3PKESKPacket(keyId, pubKey.getAlgorithm(), processSessionInfo(encryptSessionInfo(pubKey, sessionInfo))); + } + + @Override + public ContainedPacket generateV5(int encAlgorithm, int aeadAlgorithm, byte[] sessionInfo) + throws PGPException + { + // TODO: Implement + return null; + } + + @Override + public ContainedPacket generateV6(int encAlgorithm, int aeadAlgorithm, byte[] sessionInfo) + throws PGPException + { + // TODO: Implement + return null; } abstract protected byte[] encryptSessionInfo(PGPPublicKey pubKey, byte[] sessionInfo) throws PGPException; + + protected static byte[] getSessionInfo(byte[] ephPubEncoding, byte[] c) + throws IOException + { + byte[] VB = new MPInteger(new BigInteger(1, ephPubEncoding)).getEncoded(); + + byte[] rv = new byte[VB.length + 1 + c.length]; + System.arraycopy(VB, 0, rv, 0, VB.length); + rv[VB.length] = (byte)c.length; + System.arraycopy(c, 0, rv, VB.length + 1, c.length); + return rv; + } + + protected static byte[] getSessionInfo(byte[] VB, int sysmmetricKeyAlgorithm, byte[] c) + { + byte[] rv = new byte[VB.length + 2 + c.length]; + System.arraycopy(VB, 0, rv, 0, VB.length); + rv[VB.length] = (byte)(c.length + 1); + rv[VB.length + 1] = (byte)sysmmetricKeyAlgorithm; + System.arraycopy(c, 0, rv, VB.length + 2, c.length); + return rv; + } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/RFC6637Utils.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/RFC6637Utils.java index 2e0613f04a..aa65e34a76 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/RFC6637Utils.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/RFC6637Utils.java @@ -4,11 +4,15 @@ import java.io.IOException; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.bcpg.ECDHPublicBCPGKey; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.X25519PublicBCPGKey; +import org.bouncycastle.bcpg.X448PublicBCPGKey; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.util.encoders.Hex; @@ -25,16 +29,24 @@ private RFC6637Utils() public static String getXDHAlgorithm(PublicKeyPacket pubKeyData) { + if (pubKeyData.getKey() instanceof X25519PublicBCPGKey) + { + return "X25519withSHA256CKDF"; + } + else if (pubKeyData.getKey() instanceof X448PublicBCPGKey) + { + return "X448withSHA512CKDF"; + } ECDHPublicBCPGKey ecKey = (ECDHPublicBCPGKey)pubKeyData.getKey(); - + String curve = ecKey.getCurveOID().equals(EdECObjectIdentifiers.id_X448) ? "X448" : "X25519"; switch (ecKey.getHashAlgorithm()) { case HashAlgorithmTags.SHA256: - return "X25519withSHA256CKDF"; + return curve + "withSHA256CKDF"; case HashAlgorithmTags.SHA384: - return "X25519withSHA384CKDF"; + return curve + "withSHA384CKDF"; case HashAlgorithmTags.SHA512: - return "X25519withSHA512CKDF"; + return curve + "withSHA512CKDF"; default: throw new IllegalArgumentException("Unknown hash algorithm specified: " + ecKey.getHashAlgorithm()); } @@ -69,6 +81,13 @@ public static ASN1ObjectIdentifier getKeyEncryptionOID(int algID) return NISTObjectIdentifiers.id_aes192_wrap; case SymmetricKeyAlgorithmTags.AES_256: return NISTObjectIdentifiers.id_aes256_wrap; + //RFC3657 + case SymmetricKeyAlgorithmTags.CAMELLIA_128: + return NTTObjectIdentifiers.id_camellia128_wrap; + case SymmetricKeyAlgorithmTags.CAMELLIA_192: + return NTTObjectIdentifiers.id_camellia192_wrap; + case SymmetricKeyAlgorithmTags.CAMELLIA_256: + return NTTObjectIdentifiers.id_camellia256_wrap; default: throw new PGPException("unknown symmetric algorithm ID: " + algID); } @@ -85,6 +104,7 @@ public static byte[] createUserKeyingMaterial(PublicKeyPacket pubKeyData, KeyFin throws IOException, PGPException { ByteArrayOutputStream pOut = new ByteArrayOutputStream(); + ECDHPublicBCPGKey ecKey = (ECDHPublicBCPGKey)pubKeyData.getKey(); byte[] encOid = ecKey.getCurveOID().getEncoded(); @@ -99,4 +119,5 @@ public static byte[] createUserKeyingMaterial(PublicKeyPacket pubKeyData, KeyFin return pOut.toByteArray(); } + } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcAEADSecretKeyEncryptorBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcAEADSecretKeyEncryptorBuilder.java new file mode 100644 index 0000000000..4d823bd5a6 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcAEADSecretKeyEncryptorBuilder.java @@ -0,0 +1,99 @@ +package org.bouncycastle.openpgp.operator.bc; + +import org.bouncycastle.bcpg.AEADUtils; +import org.bouncycastle.bcpg.PacketTags; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.S2K; +import org.bouncycastle.bcpg.SymmetricKeyUtils; +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.modes.AEADBlockCipher; +import org.bouncycastle.crypto.params.AEADParameters; +import org.bouncycastle.crypto.params.HKDFParameters; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; +import org.bouncycastle.util.Arrays; + +import java.io.IOException; +import java.security.SecureRandom; + +public class BcAEADSecretKeyEncryptorBuilder +{ + + private int aeadAlgorithm; + private int symmetricAlgorithm; + private S2K.Argon2Params argon2Params; + + public BcAEADSecretKeyEncryptorBuilder(int aeadAlgorithm, int symmetricAlgorithm, S2K.Argon2Params argon2Params) + { + this.aeadAlgorithm = aeadAlgorithm; + this.symmetricAlgorithm = symmetricAlgorithm; + this.argon2Params = argon2Params; + } + + public PBESecretKeyEncryptor build(char[] passphrase, PublicKeyPacket pubKey) + { + return new PBESecretKeyEncryptor(symmetricAlgorithm, aeadAlgorithm, argon2Params, new SecureRandom(), passphrase) + { + private byte[] iv; + + { + iv = new byte[AEADUtils.getIVLength(aeadAlgorithm)]; + random.nextBytes(iv); + } + + @Override + public byte[] encryptKeyData(byte[] key, byte[] keyData, int keyOff, int keyLen) + throws PGPException + { + int packetTag = pubKey.getPacketTag() == PacketTags.PUBLIC_KEY ? PacketTags.SECRET_KEY : PacketTags.SECRET_SUBKEY; + byte[] hkdfInfo = new byte[] { + (byte) (0xC0 | packetTag), + (byte) pubKey.getVersion(), + (byte) symmetricAlgorithm, + (byte) aeadAlgorithm + }; + + HKDFParameters hkdfParameters = new HKDFParameters( + getKey(), + null, + hkdfInfo); + + HKDFBytesGenerator hkdfGen = new HKDFBytesGenerator(new SHA256Digest()); + hkdfGen.init(hkdfParameters); + key = new byte[SymmetricKeyUtils.getKeyLengthInOctets(encAlgorithm)]; + hkdfGen.generateBytes(key, 0, key.length); + + try + { + byte[] aad = Arrays.prepend(pubKey.getEncodedContents(), (byte) (0xC0 | packetTag)); + AEADBlockCipher cipher = BcAEADUtil.createAEADCipher(encAlgorithm, aeadAlgorithm); + cipher.init(true, new AEADParameters( + new KeyParameter(key), + 128, + getCipherIV(), + aad + )); + int dataLen = cipher.getOutputSize(keyData.length); + byte[] encKey = new byte[dataLen]; + dataLen = cipher.processBytes(keyData, 0, keyData.length, encKey, 0); + + cipher.doFinal(encKey, dataLen); + return encKey; + } + catch (IOException | InvalidCipherTextException e) + { + throw new PGPException("Exception AEAD protecting private key material", e); + } + } + + @Override + public byte[] getCipherIV() + { + return iv; + } + }; + } +} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcAEADUtil.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcAEADUtil.java new file mode 100644 index 0000000000..4d58cb9982 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcAEADUtil.java @@ -0,0 +1,675 @@ +package org.bouncycastle.openpgp.operator.bc; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.bouncycastle.bcpg.AEADAlgorithmTags; +import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.AEADUtils; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyUtils; +import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.engines.AESEngine; +import org.bouncycastle.crypto.engines.CamelliaEngine; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.modes.AEADBlockCipher; +import org.bouncycastle.crypto.modes.EAXBlockCipher; +import org.bouncycastle.crypto.modes.GCMBlockCipher; +import org.bouncycastle.crypto.modes.OCBBlockCipher; +import org.bouncycastle.crypto.params.AEADParameters; +import org.bouncycastle.crypto.params.HKDFParameters; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPSessionKey; +import org.bouncycastle.openpgp.operator.PGPDataDecryptor; +import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Exceptions; +import org.bouncycastle.util.Pack; +import org.bouncycastle.util.io.Streams; + +public class BcAEADUtil +{ + /** + * Generate a nonce by xor-ing the given iv with the chunk index. + * + * @param iv initialization vector + * @param chunkIndex chunk index + * @return nonce + */ + protected static byte[] getNonce(byte[] iv, long chunkIndex) + { + byte[] nonce = Arrays.clone(iv); + + xorChunkId(nonce, chunkIndex); + + return nonce; + } + + /** + * XOR the byte array with the chunk index in-place. + * + * @param nonce byte array + * @param chunkIndex chunk index + */ + protected static void xorChunkId(byte[] nonce, long chunkIndex) + { + int index = nonce.length - 8; + + nonce[index++] ^= (byte)(chunkIndex >> 56); + nonce[index++] ^= (byte)(chunkIndex >> 48); + nonce[index++] ^= (byte)(chunkIndex >> 40); + nonce[index++] ^= (byte)(chunkIndex >> 32); + nonce[index++] ^= (byte)(chunkIndex >> 24); + nonce[index++] ^= (byte)(chunkIndex >> 16); + nonce[index++] ^= (byte)(chunkIndex >> 8); + nonce[index] ^= (byte)(chunkIndex); + } + + /** + * Calculate an actual chunk length from the encoded chunk size. + * + * @param chunkSize encoded chunk size + * @return decoded length + */ + protected static long getChunkLength(int chunkSize) + { + return 1L << (chunkSize + 6); + } + + /** + * Derive a message key and IV from the given session key. + * The result is two byte arrays containing the key bytes and the IV. + * + * @param aeadAlgo AEAD algorithm + * @param cipherAlgo symmetric cipher algorithm + * @param sessionKey session key + * @param salt salt + * @param hkdfInfo HKDF info + * @return message key and separate IV + */ + static byte[][] deriveMessageKeyAndIv(int aeadAlgo, int cipherAlgo, byte[] sessionKey, byte[] salt, byte[] hkdfInfo) + { + int keyLen = SymmetricKeyUtils.getKeyLengthInOctets(cipherAlgo); + int ivLen = AEADUtils.getIVLength(aeadAlgo); + byte[] messageKeyAndIv = generateHKDFBytes(sessionKey, salt, hkdfInfo, keyLen + ivLen - 8); + + return new byte[][]{Arrays.copyOfRange(messageKeyAndIv, 0, keyLen), Arrays.copyOfRange(messageKeyAndIv, keyLen, keyLen + ivLen)}; + } + + static byte[] generateHKDFBytes(byte[] sessionKey, byte[] salt, byte[] hkdfInfo, int len) + { + HKDFParameters hkdfParameters = new HKDFParameters(sessionKey, salt, hkdfInfo); + HKDFBytesGenerator hkdfGen = new HKDFBytesGenerator(new SHA256Digest()); + + hkdfGen.init(hkdfParameters); + byte[] messageKeyAndIv = new byte[len]; + hkdfGen.generateBytes(messageKeyAndIv, 0, messageKeyAndIv.length); + return messageKeyAndIv; + } + + public static AEADBlockCipher createAEADCipher(int encAlgorithm, int aeadAlgorithm) + throws PGPException + { + if (encAlgorithm == SymmetricKeyAlgorithmTags.AES_128 + || encAlgorithm == SymmetricKeyAlgorithmTags.AES_192 + || encAlgorithm == SymmetricKeyAlgorithmTags.AES_256) + { + return createAEADCipher(aeadAlgorithm, new Engine() + { + @Override + public BlockCipher newInstance() + { + return AESEngine.newInstance(); + } + }); + } + else if (encAlgorithm == SymmetricKeyAlgorithmTags.CAMELLIA_128 + || encAlgorithm == SymmetricKeyAlgorithmTags.CAMELLIA_192 + || encAlgorithm == SymmetricKeyAlgorithmTags.CAMELLIA_256) + { + return createAEADCipher(aeadAlgorithm, new Engine() + { + @Override + public BlockCipher newInstance() + { + return new CamelliaEngine(); + } + }); + } + // Block Cipher must work on 16 byte blocks + throw new PGPException("AEAD only supported for AES and Camellia based algorithms"); + } + + private interface Engine + { + BlockCipher newInstance(); + } + + private static AEADBlockCipher createAEADCipher(int aeadAlgorithm, Engine engine) + throws PGPException + { + switch (aeadAlgorithm) + { + case AEADAlgorithmTags.EAX: + return new EAXBlockCipher(engine.newInstance()); + case AEADAlgorithmTags.OCB: + return new OCBBlockCipher(engine.newInstance(), engine.newInstance()); + case AEADAlgorithmTags.GCM: + return GCMBlockCipher.newInstance(engine.newInstance()); + default: + throw new PGPException("unrecognised AEAD algorithm: " + aeadAlgorithm); + } + } + + /** + * Create a decryptor for OpenPGP v5 AED (AEAD Encrypted Data) packets. + * This is type of packet is used by GnuPG. + * For version 2 SEIPD packets used in OpenPGP v6, see + * {@link #createOpenPgpV6DataDecryptor(SymmetricEncIntegrityPacket, PGPSessionKey)} instead. + * + * @param aeadEncDataPacket AEAD encrypted data packet + * @param sessionKey session key retrieved from a version 5 symmetric-key encrypted session key packet + * or version 3 public-key encrypted session key packet. + * @return decryptor for AEAD encrypted data packets + * @throws PGPException + */ + static PGPDataDecryptor createOpenPgpV5DataDecryptor(AEADEncDataPacket aeadEncDataPacket, PGPSessionKey sessionKey) + throws PGPException + { + final int aeadAlgorithm = aeadEncDataPacket.getAEADAlgorithm(); + final byte[] iv = aeadEncDataPacket.getIV(); + final int chunkSize = aeadEncDataPacket.getChunkSize(); + final int encAlgorithm = sessionKey.getAlgorithm(); + final byte[] key = sessionKey.getKey(); + final byte[] aaData = aeadEncDataPacket.getAAData(); + + final KeyParameter secretKey = new KeyParameter(key); + + final AEADBlockCipher c = createAEADCipher(encAlgorithm, aeadAlgorithm); + + return new PGPDataDecryptor() + { + public InputStream getInputStream(InputStream in) + { + try + { + return new PGPAeadInputStream(true, in, c, secretKey, iv, encAlgorithm, aeadAlgorithm, chunkSize, aaData); + } + catch (IOException e) + { + throw Exceptions.illegalStateException("unable to open stream: " + e.getMessage(), e); + } + } + + public int getBlockSize() + { + return c.getUnderlyingCipher().getBlockSize(); + } + + public PGPDigestCalculator getIntegrityCalculator() + { + return new SHA1PGPDigestCalculator(); + } + }; + } + + /** + * Create a data decryptor for SEIPD v2 packets used in OpenPGP v6. + * Those are symmetrically encrypted integrity protected data packets that make use of AEAD. + * + * @param seipd version 2 symmetrically encrypted integrity-protected data packet + * @param sessionKey session key as retrieved from a version 6 symmetric- or public-key-encrypted session key packet. + * @return decryptor + * @throws PGPException + */ + static PGPDataDecryptor createOpenPgpV6DataDecryptor(SymmetricEncIntegrityPacket seipd, PGPSessionKey sessionKey) + throws PGPException + { + // We cannot handle v1 SEIPD packets in this method (OpenPGP v4) + if (seipd.getVersion() == SymmetricEncIntegrityPacket.VERSION_1) + { + throw new PGPException("SEIPD packet MUST be of version 2 or greater."); + } + + final int cipherAlgo = seipd.getCipherAlgorithm(); + final int aeadAlgo = seipd.getAeadAlgorithm(); + final int chunkSize = seipd.getChunkSize(); + final byte[] aaData = seipd.getAAData(); + + byte[][] messageKeyAndIv = deriveMessageKeyAndIv(aeadAlgo, cipherAlgo, + sessionKey.getKey(), seipd.getSalt(), aaData); + byte[] messageKey = messageKeyAndIv[0]; + final byte[] iv = messageKeyAndIv[1]; + + final KeyParameter secretKey = new KeyParameter(messageKey); + final AEADBlockCipher c = createAEADCipher(cipherAlgo, aeadAlgo); + + return new PGPDataDecryptor() + { + public InputStream getInputStream(InputStream in) + { + try + { + return new PGPAeadInputStream(false, in, c, secretKey, iv, cipherAlgo, aeadAlgo, chunkSize, aaData); + } + catch (IOException e) + { + throw Exceptions.illegalStateException("unable to open stream: " + e.getMessage(), e); + } + } + + public int getBlockSize() + { + return c.getUnderlyingCipher().getBlockSize(); + } + + public PGPDigestCalculator getIntegrityCalculator() + { + return new SHA1PGPDigestCalculator(); + } + }; + } + + protected static class PGPAeadInputStream + extends InputStream + { + private final InputStream in; + private final byte[] buf; + private final AEADBlockCipher c; + private final KeyParameter secretKey; + private final byte[] aaData; + private final byte[] iv; + private final int chunkLength; + private final int tagLen; + + private byte[] data; + private int dataOff; + private long chunkIndex = 0; + private long totalBytes = 0; + private final boolean isV5StyleAEAD; + + /** + * InputStream for decrypting AEAD encrypted data. + * + * @param isV5StyleAEAD flavour of AEAD (OpenPGP v5 or v6) + * @param in underlying InputStream + * @param c decryption cipher + * @param secretKey decryption key + * @param iv initialization vector + * @param encAlgorithm symmetric cipher algorithm + * @param aeadAlgorithm AEAD algorithm + * @param chunkSize chunk size of the AEAD encryption + * @param aaData associated data + * @throws IOException + */ + public PGPAeadInputStream(boolean isV5StyleAEAD, InputStream in, + AEADBlockCipher c, + KeyParameter secretKey, + byte[] iv, + int encAlgorithm, + int aeadAlgorithm, + int chunkSize, + byte[] aaData) + throws IOException + { + this.isV5StyleAEAD = isV5StyleAEAD; + this.in = in; + this.iv = iv; + this.chunkLength = (int)getChunkLength(chunkSize); + this.tagLen = AEADUtils.getAuthTagLength(aeadAlgorithm); + this.buf = new byte[chunkLength + tagLen + tagLen]; // allow room for chunk tag and message tag + this.c = c; + this.secretKey = secretKey; + this.aaData = aaData; + + // prime with 2 * tag len bytes. + Streams.readFully(in, buf, 0, tagLen + tagLen); + + // load the first block + this.data = readBlock(); + this.dataOff = 0; + } + + public int read() + throws IOException + { + if (data != null && dataOff == data.length) + { + this.data = readBlock(); + this.dataOff = 0; + } + + if (this.data == null) + { + return -1; + } + + return data[dataOff++] & 0xff; + } + + public int read(byte[] b, int off, int len) + throws IOException + { + if (data != null && dataOff == data.length) + { + this.data = readBlock(); + this.dataOff = 0; + } + + if (this.data == null) + { + return -1; + } + + int supplyLen = Math.min(len, available()); + System.arraycopy(data, dataOff, b, off, supplyLen); + dataOff += supplyLen; + + return supplyLen; + } + + public long skip(long n) + throws IOException + { + if (n <= 0) + { + return 0; + } + + int skip = (int)Math.min(n, available()); + dataOff += skip; + return skip; + } + + public int available() + throws IOException + { + if (data != null && dataOff == data.length) + { + this.data = readBlock(); + this.dataOff = 0; + } + + if (this.data == null) + { + return -1; + } + + return data.length - dataOff; + } + + private byte[] readBlock() + throws IOException + { + // we initialise with the first 16 bytes as there is an additional 16 bytes following + // the last chunk (which may not be the exact chunklength). + int dataLen = Streams.readFully(in, buf, tagLen + tagLen, chunkLength); + if (dataLen == 0) + { + return null; + } + + byte[] adata = new byte[isV5StyleAEAD ? 13 : aaData.length]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + + if (isV5StyleAEAD) + { + xorChunkId(adata, chunkIndex); + } + + byte[] decData = new byte[dataLen]; + try + { + c.init(false, new AEADParameters(secretKey, 128, getNonce(iv, chunkIndex))); // always full tag. + + c.processAADBytes(adata, 0, adata.length); + + int len = c.processBytes(buf, 0, dataLen + tagLen, decData, 0); + + c.doFinal(decData, len); + } + catch (InvalidCipherTextException e) + { + throw new IOException("exception processing chunk " + chunkIndex + ": " + e.getMessage()); + } + + totalBytes += decData.length; + chunkIndex++; + + System.arraycopy(buf, dataLen + tagLen, buf, 0, tagLen); // copy back the "tag" + + if (dataLen != chunkLength) // it's our last block + { + adata = getAdata(isV5StyleAEAD, aaData, chunkIndex, totalBytes); + + try + { + c.init(false, new AEADParameters(secretKey, 128, getNonce(iv, chunkIndex))); // always full tag. + + c.processAADBytes(adata, 0, adata.length); + if (isV5StyleAEAD) + { + c.processAADBytes(Pack.longToBigEndian(totalBytes), 0, 8); + } + + c.processBytes(buf, 0, tagLen, buf, 0); + + c.doFinal(buf, 0); // check final tag + } + catch (InvalidCipherTextException e) + { + throw new IOException("exception processing final tag: " + e.getMessage()); + } + } + else + { + Streams.readFully(in, buf, tagLen, tagLen); // read the next tag bytes + } + + return decData; + } + + private static byte[] getAdata(boolean isV5StyleAEAD, byte[] aaData, long chunkIndex, long totalBytes) + { + byte[] adata; + if (isV5StyleAEAD) + { + adata = new byte[13]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + xorChunkId(adata, chunkIndex); + } + else + { + adata = new byte[aaData.length + 8]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + System.arraycopy(Pack.longToBigEndian(totalBytes), 0, adata, aaData.length, 8); + } + return adata; + } + } + + protected static class PGPAeadOutputStream + extends OutputStream + { + private final boolean isV5StyleAEAD; + private final OutputStream out; + private final byte[] data; + private final AEADBlockCipher c; + private final KeyParameter secretKey; + private final byte[] aaData; + private final byte[] iv; + private final int chunkLength; + private final int tagLen; + + private int dataOff; + private long chunkIndex = 0; + private long totalBytes = 0; + + /** + * OutputStream for AEAD encryption. + * + * @param isV5StyleAEAD flavour of AEAD (OpenPGP v5 or v6) + * @param out underlying OutputStream + * @param c AEAD cipher + * @param secretKey secret key + * @param iv initialization vector + * @param encAlgorithm encryption algorithm + * @param aeadAlgorithm aead algorithm + * @param chunkSize chunk size of the AEAD encryption + */ + public PGPAeadOutputStream(boolean isV5StyleAEAD, + OutputStream out, + AEADBlockCipher c, + KeyParameter secretKey, + byte[] iv, int encAlgorithm, + int aeadAlgorithm, + int chunkSize) + { + this.isV5StyleAEAD = isV5StyleAEAD; + this.out = out; + this.iv = iv; + this.chunkLength = (int)getChunkLength(chunkSize); + this.tagLen = AEADUtils.getAuthTagLength(aeadAlgorithm); + this.data = new byte[chunkLength]; + this.c = c; + this.secretKey = secretKey; + + aaData = createAAD(isV5StyleAEAD, encAlgorithm, aeadAlgorithm, chunkSize); + } + + private byte[] createAAD(boolean isV5StyleAEAD, int encAlgorithm, int aeadAlgorithm, int chunkSize) + { + if (isV5StyleAEAD) + { + return AEADEncDataPacket.createAAData(AEADEncDataPacket.VERSION_1, encAlgorithm, aeadAlgorithm, chunkSize); + } + else + { + return SymmetricEncIntegrityPacket.createAAData(SymmetricEncIntegrityPacket.VERSION_2, encAlgorithm, aeadAlgorithm, chunkSize); + } + } + + public void write(int b) + throws IOException + { + if (dataOff == data.length) + { + writeBlock(); + } + data[dataOff++] = (byte)b; + } + + public void write(byte[] b, int off, int len) + throws IOException + { + if (dataOff == data.length) + { + writeBlock(); + } + + if (len < data.length - dataOff) + { + System.arraycopy(b, off, data, dataOff, len); + dataOff += len; + } + else + { + int gap = data.length - dataOff; + System.arraycopy(b, off, data, dataOff, gap); + dataOff += gap; + writeBlock(); + + len -= gap; + off += gap; + + while (len >= data.length) + { + System.arraycopy(b, off, data, 0, data.length); + dataOff = data.length; + writeBlock(); + len -= data.length; + off += data.length; + } + + if (len > 0) + { + System.arraycopy(b, off, data, 0, len); + dataOff = len; + } + } + } + + public void close() + throws IOException + { + finish(); + } + + private void writeBlock() + throws IOException + { + boolean v5StyleAEAD = isV5StyleAEAD; + + byte[] adata = v5StyleAEAD ? new byte[13] : new byte[aaData.length]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + + if (v5StyleAEAD) + { + xorChunkId(adata, chunkIndex); + } + + try + { + c.init(true, new AEADParameters(secretKey, 128, getNonce(iv, chunkIndex))); // always full tag. + c.processAADBytes(adata, 0, adata.length); + + int len = c.processBytes(data, 0, dataOff, data, 0); + out.write(data, 0, len); + + len = c.doFinal(data, 0); + out.write(data, 0, len); + } + catch (InvalidCipherTextException e) + { + throw new IOException("exception processing chunk " + chunkIndex + ": " + e.getMessage()); + } + + totalBytes += dataOff; + chunkIndex++; + dataOff = 0; + } + + private void finish() + throws IOException + { + if (dataOff > 0) + { + writeBlock(); + } + boolean v5StyleAEAD = isV5StyleAEAD; + byte[] adata = PGPAeadInputStream.getAdata(v5StyleAEAD, aaData, chunkIndex, totalBytes); + try + { + c.init(true, new AEADParameters(secretKey, 128, getNonce(iv, chunkIndex))); // always full tag. + c.processAADBytes(adata, 0, adata.length); + if (v5StyleAEAD) + { + c.processAADBytes(Pack.longToBigEndian(totalBytes), 0, 8); + } + + c.doFinal(data, 0); + out.write(data, 0, tagLen); // output final tag + } + catch (InvalidCipherTextException e) + { + throw new IOException("exception processing final tag: " + e.getMessage()); + } + out.close(); + } + } +} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcImplProvider.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcImplProvider.java index b548e0f198..ee940d1d40 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcImplProvider.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcImplProvider.java @@ -88,7 +88,7 @@ static Digest createDigest(int algorithm) static Signer createSigner(int keyAlgorithm, int hashAlgorithm, CipherParameters keyParam) throws PGPException { - switch(keyAlgorithm) + switch (keyAlgorithm) { case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: @@ -103,6 +103,10 @@ static Signer createSigner(int keyAlgorithm, int hashAlgorithm, CipherParameters return new EdDsaSigner(new Ed25519Signer(), createDigest(hashAlgorithm)); } return new EdDsaSigner(new Ed448Signer(new byte[0]), createDigest(hashAlgorithm)); + case PublicKeyAlgorithmTags.Ed25519: + return new EdDsaSigner(new Ed25519Signer(), createDigest(hashAlgorithm)); + case PublicKeyAlgorithmTags.Ed448: + return new EdDsaSigner(new Ed448Signer(new byte[0]), createDigest(hashAlgorithm)); default: throw new PGPException("cannot recognise keyAlgorithm: " + keyAlgorithm); } @@ -118,7 +122,7 @@ static BlockCipher createBlockCipher(int encAlgorithm) case SymmetricKeyAlgorithmTags.AES_128: case SymmetricKeyAlgorithmTags.AES_192: case SymmetricKeyAlgorithmTags.AES_256: - engine = new AESEngine(); + engine = AESEngine.newInstance(); break; case SymmetricKeyAlgorithmTags.CAMELLIA_128: case SymmetricKeyAlgorithmTags.CAMELLIA_192: @@ -158,10 +162,12 @@ static Wrapper createWrapper(int encAlgorithm) case SymmetricKeyAlgorithmTags.AES_128: case SymmetricKeyAlgorithmTags.AES_192: case SymmetricKeyAlgorithmTags.AES_256: - return new RFC3394WrapEngine(new AESEngine()); + return new RFC3394WrapEngine(AESEngine.newInstance()); case SymmetricKeyAlgorithmTags.CAMELLIA_128: case SymmetricKeyAlgorithmTags.CAMELLIA_192: case SymmetricKeyAlgorithmTags.CAMELLIA_256: + //RFC 5581 s3: Camellia may be used in any place in OpenPGP where a symmetric cipher + // is usable, and it is subject to the same usage requirements return new RFC3394WrapEngine(new CamelliaEngine()); default: throw new PGPException("unknown wrap algorithm: " + encAlgorithm); @@ -188,6 +194,8 @@ static AsymmetricBlockCipher createPublicKeyCipher(int encAlgorithm) case PGPPublicKey.ECDSA: throw new PGPException("Can't use ECDSA for encryption."); case PGPPublicKey.ECDH: + case PGPPublicKey.X25519: + case PGPPublicKey.X448: throw new PGPException("Not implemented."); default: throw new PGPException("unknown asymmetric algorithm: " + encAlgorithm); @@ -239,7 +247,7 @@ public byte[] generateSignature() public boolean verifySignature(byte[] signature) { digest.doFinal(digBuf, 0); - + signer.update(digBuf, 0, digBuf.length); return signer.verifySignature(signature); diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcKeyFingerprintCalculator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcKeyFingerprintCalculator.java index bb201cac5a..9a4c7e2c07 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcKeyFingerprintCalculator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcKeyFingerprintCalculator.java @@ -6,9 +6,11 @@ import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSAPublicBCPGKey; +import org.bouncycastle.bcpg.UnsupportedPacketVersionException; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.SHA1Digest; +import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; @@ -21,7 +23,7 @@ public byte[] calculateFingerprint(PublicKeyPacket publicPk) BCPGKey key = publicPk.getKey(); Digest digest; - if (publicPk.getVersion() <= 3) + if (publicPk.getVersion() <= PublicKeyPacket.VERSION_3) { RSAPublicBCPGKey rK = (RSAPublicBCPGKey)key; @@ -29,7 +31,7 @@ public byte[] calculateFingerprint(PublicKeyPacket publicPk) { digest = new MD5Digest(); - byte[] bytes = new MPInteger(rK.getModulus()).getEncoded(); + byte[] bytes = new MPInteger(rK.getModulus()).getEncoded(); digest.update(bytes, 2, bytes.length - 2); bytes = new MPInteger(rK.getPublicExponent()).getEncoded(); @@ -40,11 +42,11 @@ public byte[] calculateFingerprint(PublicKeyPacket publicPk) throw new PGPException("can't encode key components: " + e.getMessage(), e); } } - else + else if (publicPk.getVersion() == PublicKeyPacket.VERSION_4) { try { - byte[] kBytes = publicPk.getEncodedContents(); + byte[] kBytes = publicPk.getEncodedContents(); digest = new SHA1Digest(); @@ -58,6 +60,31 @@ public byte[] calculateFingerprint(PublicKeyPacket publicPk) throw new PGPException("can't encode key components: " + e.getMessage(), e); } } + else if (publicPk.getVersion() == PublicKeyPacket.LIBREPGP_5 || publicPk.getVersion() == PublicKeyPacket.VERSION_6) + { + try + { + byte[] kBytes = publicPk.getEncodedContents(); + digest = new SHA256Digest(); + + digest.update((byte) (publicPk.getVersion() == PublicKeyPacket.VERSION_6 ? 0x9b : 0x9a)); + + digest.update((byte)(kBytes.length >> 24)); + digest.update((byte)(kBytes.length >> 16)); + digest.update((byte)(kBytes.length >> 8)); + digest.update((byte)kBytes.length); + + digest.update(kBytes, 0, kBytes.length); + } + catch (IOException e) + { + throw new PGPException("can't encode key components: " + e.getMessage(), e); + } + } + else + { + throw new UnsupportedPacketVersionException("Unsupported PGP key version: " + publicPk.getVersion()); + } byte[] digBuf = new byte[digest.getDigestSize()]; diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEDataDecryptorFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEDataDecryptorFactory.java index 76ed06940a..62aad81ba1 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEDataDecryptorFactory.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEDataDecryptorFactory.java @@ -1,8 +1,18 @@ package org.bouncycastle.openpgp.operator.bc; +import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket; +import org.bouncycastle.bcpg.SymmetricKeyUtils; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.modes.AEADBlockCipher; +import org.bouncycastle.crypto.params.AEADParameters; +import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPSessionKey; import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; @@ -16,14 +26,25 @@ public class BcPBEDataDecryptorFactory /** * Base constructor. * - * @param pass the passphrase to use as the primary source of key material. - * @param calculatorProvider a digest calculator provider to provide calculators to support the key generation calculation required. + * @param pass the passphrase to use as the primary source of key material. + * @param calculatorProvider a digest calculator provider to provide calculators to support the key generation calculation required. */ public BcPBEDataDecryptorFactory(char[] pass, BcPGPDigestCalculatorProvider calculatorProvider) { super(pass, calculatorProvider); } + /** + * Recover the session key from a version 4 SKESK packet used in OpenPGP v4. + * + * @param keyAlgorithm the {@link SymmetricKeyAlgorithmTags encryption algorithm} used to + * encrypt the session data. + * @param key the key bytes for the encryption algorithm. + * @param secKeyData the encrypted session data to decrypt. + * @return session key + * @throws PGPException + */ + @Override public byte[] recoverSessionData(int keyAlgorithm, byte[] key, byte[] secKeyData) throws PGPException { @@ -58,6 +79,53 @@ public byte[] recoverSessionData(int keyAlgorithm, byte[] key, byte[] secKeyData } } + @Override + public byte[] recoverAEADEncryptedSessionData(SymmetricKeyEncSessionPacket keyData, byte[] ikm) + throws PGPException + { + if (keyData.getVersion() < SymmetricKeyEncSessionPacket.VERSION_5) + { + throw new PGPException("SKESK packet MUST be version 5 or later."); + } + + byte[] hkdfInfo = keyData.getAAData(); // Between v5 and v6, these bytes differ + int kekLen = SymmetricKeyUtils.getKeyLengthInOctets(keyData.getEncAlgorithm()); + + // HKDF + // secretKey := HKDF_sha256(ikm, hkdfInfo).generate() + byte[] kek = BcAEADUtil.generateHKDFBytes(ikm, null, hkdfInfo, kekLen); + final KeyParameter secretKey = new KeyParameter(kek); + + // AEAD + AEADBlockCipher aead = BcAEADUtil.createAEADCipher(keyData.getEncAlgorithm(), keyData.getAeadAlgorithm()); + int aeadMacLen = 128; + byte[] authTag = keyData.getAuthTag(); + byte[] aeadIv = keyData.getIv(); + byte[] encSessionKey = keyData.getSecKeyData(); + + // sessionData := AEAD(secretKey).decrypt(encSessionKey || authTag) + AEADParameters parameters = new AEADParameters(secretKey, + aeadMacLen, aeadIv, keyData.getAAData()); + aead.init(false, parameters); + int sessionKeyLen = aead.getOutputSize(encSessionKey.length + authTag.length); + byte[] sessionData = new byte[sessionKeyLen]; + int dataLen = aead.processBytes(encSessionKey, 0, encSessionKey.length, sessionData, 0); + dataLen += aead.processBytes(authTag, 0, authTag.length, sessionData, dataLen); + + try + { + aead.doFinal(sessionData, dataLen); + } + catch (InvalidCipherTextException e) + { + throw new PGPException("Exception recovering session info", e); + } + + return sessionData; + } + + // OpenPGP v4 + @Override public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { @@ -65,10 +133,20 @@ public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int enc return BcUtil.createDataDecryptor(withIntegrityPacket, engine, key); } - - public PGPDataDecryptor createDataDecryptor(int aeadAlgorithm, byte[] iv, int chunkSize, int encAlgorithm, byte[] key) + + // OpenPGP v5 + @Override + public PGPDataDecryptor createDataDecryptor(AEADEncDataPacket aeadEncDataPacket, PGPSessionKey sessionKey) + throws PGPException + { + return BcAEADUtil.createOpenPgpV5DataDecryptor(aeadEncDataPacket, sessionKey); + } + + // OpenPGP v6 + @Override + public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, PGPSessionKey sessionKey) throws PGPException { - return BcUtil.createDataDecryptor(aeadAlgorithm, iv, chunkSize, encAlgorithm, key); + return BcAEADUtil.createOpenPgpV6DataDecryptor(seipd, sessionKey); } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEKeyEncryptionMethodGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEKeyEncryptionMethodGenerator.java index 950b072f52..5277c4d943 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEKeyEncryptionMethodGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEKeyEncryptionMethodGenerator.java @@ -3,9 +3,13 @@ import java.security.SecureRandom; import org.bouncycastle.bcpg.S2K; +import org.bouncycastle.bcpg.SymmetricKeyUtils; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.modes.AEADCipher; +import org.bouncycastle.crypto.params.AEADParameters; +import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; @@ -103,4 +107,31 @@ protected byte[] encryptSessionInfo(int encAlgorithm, byte[] key, byte[] session throw new PGPException("encryption failed: " + e.getMessage(), e); } } + + protected byte[] generateV6KEK(int kekAlgorithm, byte[] ikm, byte[] info) + { + return BcAEADUtil.generateHKDFBytes(ikm, null, info, SymmetricKeyUtils.getKeyLengthInOctets(kekAlgorithm)); + } + + protected byte[] getEskAndTag(int kekAlgorithm, int aeadAlgorithm, byte[] sessionInfo, byte[] key, byte[] iv, byte[] info) + throws PGPException + { + byte[] sessionKey = new byte[sessionInfo.length - 3]; + System.arraycopy(sessionInfo, 1, sessionKey, 0, sessionKey.length); + + AEADCipher aeadCipher = BcAEADUtil.createAEADCipher(kekAlgorithm, aeadAlgorithm); + aeadCipher.init(true, new AEADParameters(new KeyParameter(key), 128, iv, info)); + int outLen = aeadCipher.getOutputSize(sessionKey.length); + byte[] eskAndTag = new byte[outLen]; + int len = aeadCipher.processBytes(sessionKey, 0, sessionKey.length, eskAndTag, 0); + try + { + len += aeadCipher.doFinal(eskAndTag, len); + } + catch (InvalidCipherTextException e) + { + throw new PGPException("cannot encrypt session info", e); + } + return eskAndTag; + } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBESecretKeyDecryptorBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBESecretKeyDecryptorBuilder.java index decf032fcb..59cb567fb6 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBESecretKeyDecryptorBuilder.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBESecretKeyDecryptorBuilder.java @@ -1,10 +1,18 @@ package org.bouncycastle.openpgp.operator.bc; +import org.bouncycastle.bcpg.SymmetricKeyUtils; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.modes.AEADBlockCipher; +import org.bouncycastle.crypto.params.AEADParameters; +import org.bouncycastle.crypto.params.HKDFParameters; +import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; +import org.bouncycastle.util.Arrays; public class BcPBESecretKeyDecryptorBuilder { @@ -38,6 +46,42 @@ public byte[] recoverKeyData(int encAlgorithm, byte[] key, byte[] iv, byte[] key throw new PGPException("decryption failed: " + e.getMessage(), e); } } + + @Override + public byte[] recoverKeyData(int encAlgorithm, int aeadAlgorithm, byte[] s2kKey, byte[] iv, int packetTag, int keyVersion, byte[] keyData, byte[] pubkeyData) throws PGPException + { + byte[] hkdfInfo = new byte[] { + (byte) (0xC0 | packetTag), (byte) keyVersion, (byte) encAlgorithm, (byte) aeadAlgorithm + }; + + HKDFParameters hkdfParameters = new HKDFParameters(s2kKey, null, hkdfInfo); + HKDFBytesGenerator hkdfGen = new HKDFBytesGenerator(new SHA256Digest()); + hkdfGen.init(hkdfParameters); + byte[] key = new byte[SymmetricKeyUtils.getKeyLengthInOctets(encAlgorithm)]; + hkdfGen.generateBytes(key, 0, key.length); + + byte[] aad = Arrays.prepend(pubkeyData, (byte) (0xC0 | packetTag)); + AEADBlockCipher cipher = BcAEADUtil.createAEADCipher(encAlgorithm, aeadAlgorithm); + cipher.init(false, new AEADParameters( + new KeyParameter(key), + 128, + iv, + aad + )); + int dataLen = cipher.getOutputSize(keyData.length); + byte[] data = new byte[dataLen]; + dataLen = cipher.processBytes(keyData, 0, keyData.length, data, 0); + + try + { + cipher.doFinal(data, dataLen); + return data; + } + catch (InvalidCipherTextException e) + { + throw new PGPException("Exception recovering AEAD protected private key material", e); + } + } }; } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPDataEncryptorBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPDataEncryptorBuilder.java index da5e8a01e7..6c6a2a3386 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPDataEncryptorBuilder.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPDataEncryptorBuilder.java @@ -3,8 +3,9 @@ import java.io.OutputStream; import java.security.SecureRandom; -import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.AEADUtils; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyUtils; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.io.CipherOutputStream; @@ -24,17 +25,18 @@ public class BcPGPDataEncryptorBuilder implements PGPDataEncryptorBuilder { - private SecureRandom random; - private boolean withIntegrityPacket; + private SecureRandom random; + private boolean withIntegrityPacket = true; private int encAlgorithm; + private boolean isV5StyleAEAD = true; // TODO: change to false in 1.75 private int aeadAlgorithm = -1; private int chunkSize; /** * Constructs a new data encryptor builder for a specified cipher type. - * + * * @param encAlgorithm one of the {@link SymmetricKeyAlgorithmTags supported symmetric cipher - * algorithms}. May not be {@link SymmetricKeyAlgorithmTags#NULL}. + * algorithms}. May not be {@link SymmetricKeyAlgorithmTags#NULL}. */ public BcPGPDataEncryptorBuilder(int encAlgorithm) { @@ -47,11 +49,12 @@ public BcPGPDataEncryptorBuilder(int encAlgorithm) } /** - * Sets whether or not the resulting encrypted data will be protected using an integrity packet. + * Sets whether the resulting encrypted data will be protected using an integrity packet. * * @param withIntegrityPacket true if an integrity packet is to be included, false otherwise. * @return the current builder. */ + @Override public BcPGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPacket) { this.withIntegrityPacket = withIntegrityPacket; @@ -59,13 +62,41 @@ public BcPGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPac return this; } + public BcPGPDataEncryptorBuilder setUseV5AEAD() + { + this.isV5StyleAEAD = true; + + return this; + } + + public BcPGPDataEncryptorBuilder setUseV6AEAD() + { + this.isV5StyleAEAD = false; + + return this; + } + + /** + * Sets whether the resulting encrypted data will be protected using an AEAD mode. + *

      + * The chunkSize is used as a power of two, result in blocks (1 << chunkSize) containing data + * with an extra 16 bytes for the tag. The minimum chunkSize is 6. + * + * @param aeadAlgorithm the AEAD mode to use. + * @param chunkSize the size of the chunks to be processed with each nonce. + * @return builder + */ + @Override public BcPGPDataEncryptorBuilder setWithAEAD(int aeadAlgorithm, int chunkSize) { if (encAlgorithm != SymmetricKeyAlgorithmTags.AES_128 && encAlgorithm != SymmetricKeyAlgorithmTags.AES_192 - && encAlgorithm != SymmetricKeyAlgorithmTags.AES_256) + && encAlgorithm != SymmetricKeyAlgorithmTags.AES_256 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_128 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_192 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_256) { - throw new IllegalStateException("AEAD algorithms can only be used with AES"); + throw new IllegalStateException("AEAD algorithms can only be used with AES and Camellia"); } if (chunkSize < 6) @@ -84,6 +115,7 @@ public BcPGPDataEncryptorBuilder setWithAEAD(int aeadAlgorithm, int chunkSize) *

      * If no SecureRandom is configured, a default SecureRandom will be used. *

      + * * @param random the secure random to be used. * @return the current builder. */ @@ -94,11 +126,31 @@ public BcPGPDataEncryptorBuilder setSecureRandom(SecureRandom random) return this; } + @Override public int getAlgorithm() { return encAlgorithm; } + @Override + public int getAeadAlgorithm() + { + return aeadAlgorithm; + } + + @Override + public int getChunkSize() + { + return chunkSize; + } + + @Override + public boolean isV5StyleAEAD() + { + return isV5StyleAEAD; + } + + @Override public SecureRandom getSecureRandom() { if (random == null) @@ -109,6 +161,7 @@ public SecureRandom getSecureRandom() return random; } + @Override public PGPDataEncryptor build(byte[] keyBytes) throws PGPException { @@ -164,25 +217,48 @@ public int getBlockSize() private class MyAeadDataEncryptor implements PGPAEADDataEncryptor { + private final boolean isV5StyleAEAD; private final AEADBlockCipher c; private final byte[] keyBytes; private final byte[] iv; + /** + * Create a new data decryptor using AEAD. + * If the OpenPGP v5 style AEAD is used, keyBytes contains the key. The IV is randomly generated. + * If however OpenPGP v6 style AEAD is used, keyBytes contains M+N-8 bytes. + * The first M bytes contain the key, the remaining N-8 bytes contain the IV. + * + * @param keyBytes key or key and iv + * @throws PGPException + */ MyAeadDataEncryptor(byte[] keyBytes) throws PGPException { - this.keyBytes = keyBytes; - this.c = BcUtil.createAEADCipher(encAlgorithm, aeadAlgorithm); - this.iv = new byte[AEADEncDataPacket.getIVLength((byte)aeadAlgorithm)]; + this.isV5StyleAEAD = keyBytes.length == SymmetricKeyUtils.getKeyLengthInOctets(encAlgorithm); + if (isV5StyleAEAD) + { + this.keyBytes = keyBytes; + // V5 has a random IV + this.iv = new byte[AEADUtils.getIVLength((byte)aeadAlgorithm)]; + getSecureRandom().nextBytes(iv); + } + // V6 passes in concatenated key and N-8 bytes of IV. + else + { + // V6 has the IV appended to the message key, so we need to split it. + byte[][] keyAndIv = AEADUtils.splitMessageKeyAndIv(keyBytes, encAlgorithm, aeadAlgorithm); + this.keyBytes = keyAndIv[0]; + this.iv = keyAndIv[1]; + } - getSecureRandom().nextBytes(iv); + this.c = BcAEADUtil.createAEADCipher(encAlgorithm, aeadAlgorithm); } public OutputStream getOutputStream(OutputStream out) { try { - return new BcUtil.PGPAeadOutputStream(out, c, new KeyParameter(keyBytes), encAlgorithm, aeadAlgorithm, chunkSize, iv); + return new BcAEADUtil.PGPAeadOutputStream(isV5StyleAEAD, out, c, new KeyParameter(keyBytes), iv, encAlgorithm, aeadAlgorithm, chunkSize); } catch (Exception e) { @@ -200,19 +276,23 @@ public int getBlockSize() return c.getUnderlyingCipher().getBlockSize(); } + @Override public int getAEADAlgorithm() { return aeadAlgorithm; } + @Override public int getChunkSize() { return chunkSize; } + @Override public byte[] getIV() { return Arrays.clone(iv); } + } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPKeyConverter.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPKeyConverter.java index ae7d478ed6..a64e782912 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPKeyConverter.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPKeyConverter.java @@ -5,10 +5,9 @@ import java.util.Date; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.gnu.GNUObjectIdentifiers; -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ECParameters; @@ -19,16 +18,23 @@ import org.bouncycastle.bcpg.ECDSAPublicBCPGKey; import org.bouncycastle.bcpg.ECPublicBCPGKey; import org.bouncycastle.bcpg.ECSecretBCPGKey; +import org.bouncycastle.bcpg.Ed25519PublicBCPGKey; +import org.bouncycastle.bcpg.Ed25519SecretBCPGKey; +import org.bouncycastle.bcpg.Ed448PublicBCPGKey; +import org.bouncycastle.bcpg.Ed448SecretBCPGKey; import org.bouncycastle.bcpg.EdDSAPublicBCPGKey; import org.bouncycastle.bcpg.EdSecretBCPGKey; import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; -import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.OctetArrayBCPGKey; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSAPublicBCPGKey; import org.bouncycastle.bcpg.RSASecretBCPGKey; -import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.X25519PublicBCPGKey; +import org.bouncycastle.bcpg.X25519SecretBCPGKey; +import org.bouncycastle.bcpg.X448PublicBCPGKey; +import org.bouncycastle.bcpg.X448SecretBCPGKey; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; @@ -47,6 +53,7 @@ import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; import org.bouncycastle.crypto.params.X25519PublicKeyParameters; +import org.bouncycastle.crypto.params.X448PrivateKeyParameters; import org.bouncycastle.crypto.params.X448PublicKeyParameters; import org.bouncycastle.crypto.util.PrivateKeyFactory; import org.bouncycastle.crypto.util.PublicKeyFactory; @@ -58,15 +65,13 @@ import org.bouncycastle.openpgp.PGPKdfParameters; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.operator.PGPKeyConverter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; public class BcPGPKeyConverter + extends PGPKeyConverter { - // We default to these as they are specified as mandatory in RFC 6631. - private static final PGPKdfParameters DEFAULT_KDF_PARAMETERS = new PGPKdfParameters(HashAlgorithmTags.SHA256, - SymmetricKeyAlgorithmTags.AES_128); - public PGPPrivateKey getPGPPrivateKey(PGPPublicKey pubKey, AsymmetricKeyParameter privKey) throws PGPException { @@ -76,7 +81,7 @@ public PGPPrivateKey getPGPPrivateKey(PGPPublicKey pubKey, AsymmetricKeyParamete } /** - * Create a PGPPublicKey from the passed in JCA one. + * Create a version 4 PGPPublicKey from the passed in JCA one. *

      * Note: the time passed in affects the value of the key's keyID, so you probably only want * to do this once for a JCA key, or make sure you keep track of the time you used. @@ -86,13 +91,34 @@ public PGPPrivateKey getPGPPrivateKey(PGPPublicKey pubKey, AsymmetricKeyParamete * @param pubKey actual public key to associate. * @param time date of creation. * @throws PGPException on key creation problem. + * @deprecated use versioned {@link #getPGPPublicKey(int, int, PGPAlgorithmParameters, AsymmetricKeyParameter, Date)} instead */ + @Deprecated public PGPPublicKey getPGPPublicKey(int algorithm, PGPAlgorithmParameters algorithmParameters, AsymmetricKeyParameter pubKey, Date time) throws PGPException { - BCPGKey bcpgKey = getPublicBCPGKey(algorithm, algorithmParameters, pubKey, time); + return getPGPPublicKey(PublicKeyPacket.VERSION_4, algorithm, algorithmParameters, pubKey, time); + } - return new PGPPublicKey(new PublicKeyPacket(algorithm, time, bcpgKey), new BcKeyFingerprintCalculator()); + /** + * Create a PGPPublicKey from the passed in JCA one. + *

      + * Note: the time passed in affects the value of the key's keyID, so you probably only want + * to do this once for a JCA key, or make sure you keep track of the time you used. + *

      + * + * @param version key version. + * @param algorithm asymmetric algorithm type representing the public key. + * @param pubKey actual public key to associate. + * @param time date of creation. + * @throws PGPException on key creation problem. + */ + public PGPPublicKey getPGPPublicKey(int version, int algorithm, PGPAlgorithmParameters algorithmParameters, AsymmetricKeyParameter pubKey, Date time) + throws PGPException + { + BCPGKey bcpgKey = getPublicBCPGKey(algorithm, algorithmParameters, pubKey); + + return new PGPPublicKey(new PublicKeyPacket(version, algorithm, time, bcpgKey), new BcKeyFingerprintCalculator()); } public AsymmetricKeyParameter getPrivateKey(PGPPrivateKey privKey) @@ -116,41 +142,63 @@ public AsymmetricKeyParameter getPrivateKey(PGPPrivateKey privKey) case PublicKeyAlgorithmTags.ECDH: { ECDHPublicBCPGKey ecdhPub = (ECDHPublicBCPGKey)pubPk.getKey(); - ECSecretBCPGKey ecdhK = (ECSecretBCPGKey)privPk; - if (CryptlibObjectIdentifiers.curvey25519.equals(ecdhPub.getCurveOID())) + // Legacy XDH on Curve25519 (legacy X25519) + // 1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110 + if (BcUtil.isX25519(ecdhPub.getCurveOID())) + { + return PrivateKeyFactory.createKey(getPrivateKeyInfo(EdECObjectIdentifiers.id_X25519, + Arrays.reverseInPlace(BigIntegers.asUnsignedByteArray(((ECSecretBCPGKey)privPk).getX())))); + } + // Legacy X448 (1.3.101.111) + else if (EdECObjectIdentifiers.id_X448.equals(ecdhPub.getCurveOID())) { - // 'reverse' because the native format for X25519 private keys is little-endian - return implGetPrivateKeyPKCS8(new PrivateKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), - new DEROctetString(Arrays.reverseInPlace(BigIntegers.asUnsignedByteArray(ecdhK.getX()))))); + return PrivateKeyFactory.createKey(getPrivateKeyInfo(EdECObjectIdentifiers.id_X448, + Arrays.reverseInPlace(BigIntegers.asUnsignedByteArray(((ECSecretBCPGKey)privPk).getX())))); } + // NIST, Brainpool etc. else { - return implGetPrivateKeyEC(ecdhPub, ecdhK); + return implGetPrivateKeyEC(ecdhPub, (ECSecretBCPGKey)privPk); } } - + // Modern X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) + case PublicKeyAlgorithmTags.X25519: + { + return PrivateKeyFactory.createKey(getPrivateKeyInfo(EdECObjectIdentifiers.id_X25519, X25519SecretBCPGKey.LENGTH, + privPk.getEncoded())); + } + // Modern X448 (1.3.101.111) + case PublicKeyAlgorithmTags.X448: + { + return PrivateKeyFactory.createKey(getPrivateKeyInfo(EdECObjectIdentifiers.id_X448, X448SecretBCPGKey.LENGTH, + privPk.getEncoded())); + } case PublicKeyAlgorithmTags.ECDSA: - return implGetPrivateKeyEC((ECDSAPublicBCPGKey)pubPk.getKey(), (ECSecretBCPGKey)privPk); - + { + return implGetPrivateKeyEC((ECDSAPublicBCPGKey) pubPk.getKey(), (ECSecretBCPGKey) privPk); + } + // Legacy EdDSA (legacy Ed448, legacy Ed25519) case PublicKeyAlgorithmTags.EDDSA_LEGACY: { - EdSecretBCPGKey eddsaK = (EdSecretBCPGKey)privPk; - EdDSAPublicBCPGKey eddsaPub = (EdDSAPublicBCPGKey)pubPk.getKey(); - - if (eddsaPub.getCurveOID().equals(EdECObjectIdentifiers.id_Ed448)) + // Legacy Ed448 (1.3.101.113) + if (((EdDSAPublicBCPGKey)pubPk.getKey()).getCurveOID().equals(EdECObjectIdentifiers.id_Ed448)) { - return implGetPrivateKeyPKCS8(new PrivateKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448), - new DEROctetString(BigIntegers.asUnsignedByteArray(Ed448.SECRET_KEY_SIZE, eddsaK.getX())))); + return implGetPrivateKeyPKCS8(EdECObjectIdentifiers.id_Ed448, Ed448.SECRET_KEY_SIZE, privPk); } - - return implGetPrivateKeyPKCS8(new PrivateKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), - new DEROctetString(BigIntegers.asUnsignedByteArray(Ed25519.SECRET_KEY_SIZE, eddsaK.getX())))); + // Legacy Ed25519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) + return implGetPrivateKeyPKCS8(EdECObjectIdentifiers.id_Ed25519, Ed25519.SECRET_KEY_SIZE, privPk); + } + // Modern Ed22519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) + case PublicKeyAlgorithmTags.Ed25519: + { + return PrivateKeyFactory.createKey(getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed25519, Ed25519SecretBCPGKey.LENGTH, privPk.getEncoded())); + } + // Modern Ed448 (1.3.101.113) + case PublicKeyAlgorithmTags.Ed448: + { + return PrivateKeyFactory.createKey(getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed448, Ed448SecretBCPGKey.LENGTH, privPk.getEncoded())); } - case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: { @@ -158,7 +206,6 @@ public AsymmetricKeyParameter getPrivateKey(PGPPrivateKey privKey) ElGamalSecretBCPGKey elPriv = (ElGamalSecretBCPGKey)privPk; return new ElGamalPrivateKeyParameters(elPriv.getX(), new ElGamalParameters(elPub.getP(), elPub.getG())); } - case PublicKeyAlgorithmTags.RSA_ENCRYPT: case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: @@ -169,9 +216,8 @@ public AsymmetricKeyParameter getPrivateKey(PGPPrivateKey privKey) rsaPriv.getPrivateExponent(), rsaPriv.getPrimeP(), rsaPriv.getPrimeQ(), rsaPriv.getPrimeExponentP(), rsaPriv.getPrimeExponentQ(), rsaPriv.getCrtCoefficient()); } - default: - throw new PGPException("unknown public key algorithm encountered"); + throw new PGPException("unknown public key algorithm encountered: " + pubPk.getAlgorithm()); } } catch (PGPException e) @@ -198,34 +244,53 @@ public AsymmetricKeyParameter getPublicKey(PGPPublicKey publicKey) DSAPublicBCPGKey dsaK = (DSAPublicBCPGKey)publicPk.getKey(); return new DSAPublicKeyParameters(dsaK.getY(), new DSAParameters(dsaK.getP(), dsaK.getQ(), dsaK.getG())); } - case PublicKeyAlgorithmTags.ECDH: { ECDHPublicBCPGKey ecdhK = (ECDHPublicBCPGKey)publicPk.getKey(); - if (ecdhK.getCurveOID().equals(CryptlibObjectIdentifiers.curvey25519)) + // Legacy XDH on Curve25519 (legacy X25519) + // 1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110 + if (BcUtil.isX25519(ecdhK.getCurveOID())) { byte[] pEnc = BigIntegers.asUnsignedByteArray(ecdhK.getEncodedPoint()); - // skip the 0x40 header byte. if (pEnc.length < 1 || 0x40 != pEnc[0]) { throw new IllegalArgumentException("Invalid Curve25519 public key"); } - - return implGetPublicKeyX509(new SubjectPublicKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), - Arrays.copyOfRange(pEnc, 1, pEnc.length))); + return implGetPublicKeyX509(EdECObjectIdentifiers.id_X25519, pEnc, 1); + } + // Legacy X448 (1.3.101.111) + else if (ecdhK.getCurveOID().equals(EdECObjectIdentifiers.id_X448)) + { + byte[] pEnc = BigIntegers.asUnsignedByteArray(ecdhK.getEncodedPoint()); + // skip the 0x40 header byte. + if (pEnc.length < 1 || 0x40 != pEnc[0]) + { + throw new IllegalArgumentException("Invalid X448 public key"); + } + return implGetPublicKeyX509(EdECObjectIdentifiers.id_X448, pEnc, 1); } else { return implGetPublicKeyEC(ecdhK); } } - + // Modern X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) + case PublicKeyAlgorithmTags.X25519: + { + return implGetPublicKeyX509((X25519PublicBCPGKey)publicPk.getKey(), EdECObjectIdentifiers.id_X25519); + } + // Modern X448 (1.3.101.111) + case PublicKeyAlgorithmTags.X448: + { + return implGetPublicKeyX509((X448PublicBCPGKey)publicPk.getKey(), EdECObjectIdentifiers.id_X448); + } case PublicKeyAlgorithmTags.ECDSA: + { return implGetPublicKeyEC((ECDSAPublicBCPGKey)publicPk.getKey()); - + } + // Legacy EdDSA (legacy Ed448, legacy Ed25519) case PublicKeyAlgorithmTags.EDDSA_LEGACY: { EdDSAPublicBCPGKey eddsaK = (EdDSAPublicBCPGKey)publicPk.getKey(); @@ -237,26 +302,35 @@ public AsymmetricKeyParameter getPublicKey(PGPPublicKey publicKey) throw new IllegalArgumentException("Invalid EdDSA public key"); } - if (pEnc[0] == 0x40 && !eddsaK.getCurveOID().equals(EdECObjectIdentifiers.id_Ed448)) + // Legacy Ed25519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) + if (!eddsaK.getCurveOID().equals(EdECObjectIdentifiers.id_Ed448)) { - return implGetPublicKeyX509(new SubjectPublicKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), - Arrays.copyOfRange(pEnc, 1, pEnc.length))); + return implGetPublicKeyX509(EdECObjectIdentifiers.id_Ed25519, pEnc, pEnc[0] == 0x40 ? 1 : 0); } - else if (eddsaK.getCurveOID().equals(EdECObjectIdentifiers.id_Ed448)) + // Legacy Ed448 (1.3.101.113) + if (eddsaK.getCurveOID().equals(EdECObjectIdentifiers.id_Ed448)) { - return implGetPublicKeyX509(new SubjectPublicKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448), - pEnc)); + return implGetPublicKeyX509(EdECObjectIdentifiers.id_Ed448, pEnc, pEnc[0] == 0x40 ? 1 : 0); } throw new IllegalArgumentException("Invalid EdDSA public key"); } - + // Modern Ed22519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) + case PublicKeyAlgorithmTags.Ed25519: + { + return implGetPublicKeyX509((Ed25519PublicBCPGKey)publicPk.getKey(), EdECObjectIdentifiers.id_Ed25519); + } + // Modern Ed448 (1.3.101.113) + case PublicKeyAlgorithmTags.Ed448: + { + return implGetPublicKeyX509((Ed448PublicBCPGKey)publicPk.getKey(), EdECObjectIdentifiers.id_Ed448); + } case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: - ElGamalPublicBCPGKey elK = (ElGamalPublicBCPGKey)publicPk.getKey(); + { + ElGamalPublicBCPGKey elK = (ElGamalPublicBCPGKey) publicPk.getKey(); return new ElGamalPublicKeyParameters(elK.getY(), new ElGamalParameters(elK.getP(), elK.getG())); + } case PublicKeyAlgorithmTags.RSA_ENCRYPT: case PublicKeyAlgorithmTags.RSA_GENERAL: @@ -267,7 +341,7 @@ else if (eddsaK.getCurveOID().equals(EdECObjectIdentifiers.id_Ed448)) } default: - throw new PGPException("unknown public key algorithm encountered"); + throw new PGPException("unknown public key algorithm encountered: " + publicKey.getAlgorithm()); } } catch (PGPException e) @@ -290,49 +364,71 @@ private BCPGKey getPrivateBCPGKey(PGPPublicKey pubKey, AsymmetricKeyParameter pr DSAPrivateKeyParameters dsK = (DSAPrivateKeyParameters)privKey; return new DSASecretBCPGKey(dsK.getX()); } - case PublicKeyAlgorithmTags.ECDH: { - if (privKey instanceof ECPrivateKeyParameters) + // Legacy XDH on Curve25519 (legacy X25519) + // 1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110 + if (privKey instanceof X25519PrivateKeyParameters) { - ECPrivateKeyParameters ecK = (ECPrivateKeyParameters)privKey; - return new ECSecretBCPGKey(ecK.getD()); + return new ECSecretBCPGKey(new BigInteger(1, Arrays.reverseInPlace(((X25519PrivateKeyParameters)privKey).getEncoded()))); + } + // Legacy X448 (1.3.101.111) + else if (privKey instanceof X448PrivateKeyParameters) + { + return new ECSecretBCPGKey(new BigInteger(1, Arrays.reverseInPlace(((X448PrivateKeyParameters)privKey).getEncoded()))); } + // NIST, Brainpool etc. else { - // 'reverse' because the native format for X25519 private keys is little-endian - X25519PrivateKeyParameters xK = (X25519PrivateKeyParameters)privKey; - return new ECSecretBCPGKey(new BigInteger(1, Arrays.reverseInPlace(xK.getEncoded()))); + ECPrivateKeyParameters ecK = (ECPrivateKeyParameters)privKey; + return new ECSecretBCPGKey(ecK.getD()); } } - + // Modern X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) + case PublicKeyAlgorithmTags.X25519: + { + return new X25519SecretBCPGKey(((X25519PrivateKeyParameters)privKey).getEncoded()); + } + // Modern X448 (1.3.101.111) + case PublicKeyAlgorithmTags.X448: + { + return new X448SecretBCPGKey(((X448PrivateKeyParameters)privKey).getEncoded()); + } case PublicKeyAlgorithmTags.ECDSA: { ECPrivateKeyParameters ecK = (ECPrivateKeyParameters)privKey; return new ECSecretBCPGKey(ecK.getD()); } - + // Legacy EdDSA case PublicKeyAlgorithmTags.EDDSA_LEGACY: { + // Legacy Ed25519 (1.3.101.112 & 1.3.6.1.4.1.11591.15.1) if (privKey instanceof Ed25519PrivateKeyParameters) { - Ed25519PrivateKeyParameters edK = (Ed25519PrivateKeyParameters)privKey; - return new EdSecretBCPGKey(new BigInteger(1, edK.getEncoded())); + return new EdSecretBCPGKey(new BigInteger(1, ((Ed25519PrivateKeyParameters)privKey).getEncoded())); } + // Legacy Ed448 (1.3.101.113) else { - Ed448PrivateKeyParameters edK = (Ed448PrivateKeyParameters)privKey; - return new EdSecretBCPGKey(new BigInteger(1, edK.getEncoded())); + return new EdSecretBCPGKey(new BigInteger(1, ((Ed448PrivateKeyParameters) privKey).getEncoded())); } } - + // Modern Ed22519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) + case PublicKeyAlgorithmTags.Ed25519: + { + return new Ed25519SecretBCPGKey(((Ed25519PrivateKeyParameters)privKey).getEncoded()); + } + // Modern Ed448 (1.3.101.113) + case PublicKeyAlgorithmTags.Ed448: + { + return new Ed448SecretBCPGKey(((Ed448PrivateKeyParameters)privKey).getEncoded()); + } case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: { ElGamalPrivateKeyParameters esK = (ElGamalPrivateKeyParameters)privKey; return new ElGamalSecretBCPGKey(esK.getX()); } - case PublicKeyAlgorithmTags.RSA_ENCRYPT: case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: @@ -342,97 +438,149 @@ private BCPGKey getPrivateBCPGKey(PGPPublicKey pubKey, AsymmetricKeyParameter pr } default: - throw new PGPException("unknown key class"); + throw new PGPException("unknown public key algorithm encountered: " + pubKey.getAlgorithm()); } } - private BCPGKey getPublicBCPGKey(int algorithm, PGPAlgorithmParameters algorithmParameters, - AsymmetricKeyParameter pubKey, Date time) + private BCPGKey getPublicBCPGKey(int algorithm, PGPAlgorithmParameters algorithmParameters, AsymmetricKeyParameter pubKey) throws PGPException { - if (pubKey instanceof RSAKeyParameters) + switch (algorithm) { - RSAKeyParameters rK = (RSAKeyParameters)pubKey; - return new RSAPublicBCPGKey(rK.getModulus(), rK.getExponent()); - } - else if (pubKey instanceof DSAPublicKeyParameters) - { - DSAPublicKeyParameters dK = (DSAPublicKeyParameters)pubKey; - DSAParameters dP = dK.getParameters(); - return new DSAPublicBCPGKey(dP.getP(), dP.getQ(), dP.getG(), dK.getY()); - } - else if (pubKey instanceof ElGamalPublicKeyParameters) - { - ElGamalPublicKeyParameters eK = (ElGamalPublicKeyParameters)pubKey; - ElGamalParameters eS = eK.getParameters(); - return new ElGamalPublicBCPGKey(eS.getP(), eS.getG(), eK.getY()); - } - else if (pubKey instanceof ECPublicKeyParameters) - { - ECPublicKeyParameters ecK = (ECPublicKeyParameters)pubKey; + case PublicKeyAlgorithmTags.RSA_GENERAL: + case PublicKeyAlgorithmTags.RSA_ENCRYPT: + case PublicKeyAlgorithmTags.RSA_SIGN: + { + RSAKeyParameters rK = (RSAKeyParameters)pubKey; + return new RSAPublicBCPGKey(rK.getModulus(), rK.getExponent()); + } + case PublicKeyAlgorithmTags.DSA: + { + DSAPublicKeyParameters dK = (DSAPublicKeyParameters)pubKey; + DSAParameters dP = dK.getParameters(); + return new DSAPublicBCPGKey(dP.getP(), dP.getQ(), dP.getG(), dK.getY()); + } + case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: + case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: + { + ElGamalPublicKeyParameters eK = (ElGamalPublicKeyParameters)pubKey; + ElGamalParameters eS = eK.getParameters(); + return new ElGamalPublicBCPGKey(eS.getP(), eS.getG(), eK.getY()); + } + // NIST, Brainpool, Legacy X25519, Legacy X448 + case PublicKeyAlgorithmTags.ECDH: + { + // Legacy X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) + if (pubKey instanceof X25519PublicKeyParameters) + { + byte[] pointEnc = new byte[1 + X25519PublicKeyParameters.KEY_SIZE]; + pointEnc[0] = 0x40; + ((X25519PublicKeyParameters)pubKey).encode(pointEnc, 1); - // TODO Should we have a way to recognize named curves when the name is missing? - ECNamedDomainParameters parameters = (ECNamedDomainParameters)ecK.getParameters(); + PGPKdfParameters kdfParams = implGetKdfParameters(CryptlibObjectIdentifiers.curvey25519, algorithmParameters); - if (algorithm == PGPPublicKey.ECDH) - { - PGPKdfParameters kdfParams = implGetKdfParameters(algorithmParameters); + return new ECDHPublicBCPGKey(CryptlibObjectIdentifiers.curvey25519, new BigInteger(1, pointEnc), + kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); + } + // Legacy X448 (1.3.101.111) + if (pubKey instanceof X448PublicKeyParameters) + { + byte[] pointEnc = new byte[1 + X448PublicKeyParameters.KEY_SIZE]; + pointEnc[0] = 0x40; + ((X448PublicKeyParameters)pubKey).encode(pointEnc, 1); + + PGPKdfParameters kdfParams = implGetKdfParameters(EdECObjectIdentifiers.id_X448, algorithmParameters); + + return new ECDHPublicBCPGKey(EdECObjectIdentifiers.id_X448, new BigInteger(1, pointEnc), + kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); + } + // NIST, Brainpool etc. + ECPublicKeyParameters ecK = (ECPublicKeyParameters)pubKey; + ECNamedDomainParameters parameters = (ECNamedDomainParameters)ecK.getParameters(); + PGPKdfParameters kdfParams = implGetKdfParameters(parameters.getName(), algorithmParameters); return new ECDHPublicBCPGKey(parameters.getName(), ecK.getQ(), kdfParams.getHashAlgorithm(), - kdfParams.getSymmetricWrapAlgorithm()); + kdfParams.getSymmetricWrapAlgorithm()); } - else if (algorithm == PGPPublicKey.ECDSA) + case PublicKeyAlgorithmTags.ECDSA: { + ECPublicKeyParameters ecK = (ECPublicKeyParameters)pubKey; + ECNamedDomainParameters parameters = (ECNamedDomainParameters)ecK.getParameters(); return new ECDSAPublicBCPGKey(parameters.getName(), ecK.getQ()); } - else + // Legacy Ed255519, Legacy Ed448 + case PublicKeyAlgorithmTags.EDDSA_LEGACY: { - throw new PGPException("unknown EC algorithm"); + // Legacy Ed25519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) + if (pubKey instanceof Ed25519PublicKeyParameters) + { + byte[] pointEnc = new byte[1 + Ed25519PublicKeyParameters.KEY_SIZE]; + pointEnc[0] = 0x40; + ((Ed25519PublicKeyParameters)pubKey).encode(pointEnc, 1); + return new EdDSAPublicBCPGKey(GNUObjectIdentifiers.Ed25519, new BigInteger(1, pointEnc)); + } + // Legacy Ed448 (1.3.101.113) + else if (pubKey instanceof Ed448PublicKeyParameters) + { + byte[] pointEnc = new byte[1 + Ed448PublicKeyParameters.KEY_SIZE]; + pointEnc[0] = 0x40; + ((Ed448PublicKeyParameters)pubKey).encode(pointEnc, 1); + return new EdDSAPublicBCPGKey(EdECObjectIdentifiers.id_Ed448, new BigInteger(1, pointEnc)); + } + else + { + throw new PGPException("Unknown LegacyEdDSA key type: " + pubKey.getClass().getName()); + } + } + // Modern Ed22519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) + case PublicKeyAlgorithmTags.Ed25519: + { + byte[] pointEnc = new byte[Ed25519PublicKeyParameters.KEY_SIZE]; + ((Ed25519PublicKeyParameters)pubKey).encode(pointEnc, 0); + return new Ed25519PublicBCPGKey(pointEnc); + } + // Modern Ed448 (1.3.101.113) + case PublicKeyAlgorithmTags.Ed448: + { + byte[] pointEnc = new byte[Ed448PublicKeyParameters.KEY_SIZE]; + ((Ed448PublicKeyParameters)pubKey).encode(pointEnc, 0); + return new Ed448PublicBCPGKey(pointEnc); + } + // Modern X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) + case PublicKeyAlgorithmTags.X25519: + { + byte[] pointEnc = new byte[X25519PublicKeyParameters.KEY_SIZE]; + ((X25519PublicKeyParameters)pubKey).encode(pointEnc, 0); + return new X25519PublicBCPGKey(pointEnc); + } + // Modern X448 (1.3.101.111) + case PublicKeyAlgorithmTags.X448: + { + byte[] pointEnc = new byte[X448PublicKeyParameters.KEY_SIZE]; + ((X448PublicKeyParameters)pubKey).encode(pointEnc, 0); + return new X448PublicBCPGKey(pointEnc); } - } - else if (pubKey instanceof Ed25519PublicKeyParameters) - { - byte[] pointEnc = new byte[1 + Ed25519PublicKeyParameters.KEY_SIZE]; - pointEnc[0] = 0x40; - ((Ed25519PublicKeyParameters)pubKey).encode(pointEnc, 1); - return new EdDSAPublicBCPGKey(GNUObjectIdentifiers.Ed25519, new BigInteger(1, pointEnc)); - } - else if (pubKey instanceof Ed448PublicKeyParameters) - { - byte[] pointEnc = new byte[Ed448PublicKeyParameters.KEY_SIZE]; - ((Ed448PublicKeyParameters)pubKey).encode(pointEnc, 0); - return new EdDSAPublicBCPGKey(EdECObjectIdentifiers.id_Ed448, new BigInteger(1, pointEnc)); - } - else if (pubKey instanceof X25519PublicKeyParameters) - { - byte[] pointEnc = new byte[1 + X25519PublicKeyParameters.KEY_SIZE]; - pointEnc[0] = 0x40; - ((X25519PublicKeyParameters)pubKey).encode(pointEnc, 1); - - PGPKdfParameters kdfParams = implGetKdfParameters(algorithmParameters); - return new ECDHPublicBCPGKey(CryptlibObjectIdentifiers.curvey25519, new BigInteger(1, pointEnc), - kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); + default: + { + throw new PGPException("unknown public key algorithm encountered: " + algorithm); + } } - else if (pubKey instanceof X448PublicKeyParameters) - { - byte[] pointEnc = new byte[X448PublicKeyParameters.KEY_SIZE]; - ((X448PublicKeyParameters)pubKey).encode(pointEnc, 0); - - PGPKdfParameters kdfParams = implGetKdfParameters(algorithmParameters); + } - return new ECDHPublicBCPGKey(EdECObjectIdentifiers.id_X448, new BigInteger(1, pointEnc), - kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); - } - else - { - throw new PGPException("unknown key class"); - } + private AsymmetricKeyParameter implGetPublicKeyX509(OctetArrayBCPGKey eddsaK, ASN1ObjectIdentifier algorithm) + throws IOException + { + byte[] pEnc = Arrays.clone(eddsaK.getKey()); + return PublicKeyFactory.createKey(new SubjectPublicKeyInfo(new AlgorithmIdentifier(algorithm), + Arrays.copyOfRange(pEnc, 0, pEnc.length))); } - private PGPKdfParameters implGetKdfParameters(PGPAlgorithmParameters algorithmParameters) + private AsymmetricKeyParameter implGetPublicKeyX509(ASN1ObjectIdentifier algorithm, byte[] pEnc, int pEncOff) + throws IOException { - return null == algorithmParameters ? DEFAULT_KDF_PARAMETERS : (PGPKdfParameters)algorithmParameters; + return PublicKeyFactory.createKey(new SubjectPublicKeyInfo(new AlgorithmIdentifier(algorithm), + Arrays.copyOfRange(pEnc, pEncOff, pEnc.length))); } private ECNamedDomainParameters implGetParametersEC(ECPublicBCPGKey ecPub) @@ -443,29 +591,23 @@ private ECNamedDomainParameters implGetParametersEC(ECPublicBCPGKey ecPub) } private AsymmetricKeyParameter implGetPrivateKeyEC(ECPublicBCPGKey ecPub, ECSecretBCPGKey ecPriv) - throws IOException, PGPException + throws PGPException { ECNamedDomainParameters parameters = implGetParametersEC(ecPub); return new ECPrivateKeyParameters(ecPriv.getX(), parameters); } - private AsymmetricKeyParameter implGetPrivateKeyPKCS8(PrivateKeyInfo privateKeyInfo) + private AsymmetricKeyParameter implGetPrivateKeyPKCS8(ASN1ObjectIdentifier algorithm, int keySize, BCPGKey privPk) throws IOException { - return PrivateKeyFactory.createKey(privateKeyInfo); + return PrivateKeyFactory.createKey(getPrivateKeyInfo(algorithm, BigIntegers.asUnsignedByteArray(keySize, ((EdSecretBCPGKey)privPk).getX()))); } private AsymmetricKeyParameter implGetPublicKeyEC(ECPublicBCPGKey ecPub) - throws IOException, PGPException + throws PGPException { ECNamedDomainParameters parameters = implGetParametersEC(ecPub); ECPoint pubPoint = BcUtil.decodePoint(ecPub.getEncodedPoint(), parameters.getCurve()); return new ECPublicKeyParameters(pubPoint, parameters); } - - private AsymmetricKeyParameter implGetPublicKeyX509(SubjectPublicKeyInfo subjectPublicKeyInfo) - throws IOException - { - return PublicKeyFactory.createKey(subjectPublicKeyInfo); - } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPKeyPair.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPKeyPair.java index e5b085364b..f1f23a6976 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPKeyPair.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPKeyPair.java @@ -2,6 +2,7 @@ import java.util.Date; +import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.openpgp.PGPAlgorithmParameters; @@ -13,10 +14,17 @@ public class BcPGPKeyPair extends PGPKeyPair { + @Deprecated private static PGPPublicKey getPublicKey(int algorithm, PGPAlgorithmParameters parameters, AsymmetricKeyParameter pubKey, Date date) throws PGPException { - return new BcPGPKeyConverter().getPGPPublicKey(algorithm, parameters, pubKey, date); + return getPublicKey(PublicKeyPacket.VERSION_4, algorithm, parameters, pubKey, date); + } + + private static PGPPublicKey getPublicKey(int version, int algorithm, PGPAlgorithmParameters parameters, AsymmetricKeyParameter pubKey, Date date) + throws PGPException + { + return new BcPGPKeyConverter().getPGPPublicKey(version, algorithm, parameters, pubKey, date); } private static PGPPrivateKey getPrivateKey(PGPPublicKey pub, AsymmetricKeyParameter privKey) @@ -25,17 +33,31 @@ private static PGPPrivateKey getPrivateKey(PGPPublicKey pub, AsymmetricKeyParame return new BcPGPKeyConverter().getPGPPrivateKey(pub, privKey); } + @Deprecated public BcPGPKeyPair(int algorithm, AsymmetricCipherKeyPair keyPair, Date date) throws PGPException { - this.pub = getPublicKey(algorithm, null, keyPair.getPublic(), date); + this(PublicKeyPacket.VERSION_4, algorithm, keyPair, date); + } + + public BcPGPKeyPair(int version, int algorithm, AsymmetricCipherKeyPair keyPair, Date date) + throws PGPException + { + this.pub = getPublicKey(version, algorithm, null, keyPair.getPublic(), date); this.priv = getPrivateKey(this.pub, keyPair.getPrivate()); } + @Deprecated public BcPGPKeyPair(int algorithm, PGPAlgorithmParameters parameters, AsymmetricCipherKeyPair keyPair, Date date) throws PGPException { - this.pub = getPublicKey(algorithm, parameters, keyPair.getPublic(), date); + this(PublicKeyPacket.VERSION_4, algorithm, parameters, keyPair, date); + } + + public BcPGPKeyPair(int version, int algorithm, PGPAlgorithmParameters parameters, AsymmetricCipherKeyPair keyPair, Date date) + throws PGPException + { + this.pub = getPublicKey(version, algorithm, parameters, keyPair.getPublic(), date); this.priv = getPrivateKey(this.pub, keyPair.getPrivate()); } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java index 94ba85cb3f..3d5d066d50 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java @@ -3,15 +3,24 @@ import java.io.IOException; import java.math.BigInteger; +import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.bcpg.AEADEncDataPacket; import org.bouncycastle.bcpg.ECDHPublicBCPGKey; +import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.X25519PublicBCPGKey; +import org.bouncycastle.bcpg.X448PublicBCPGKey; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedAsymmetricBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.RawAgreement; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.agreement.X25519Agreement; +import org.bouncycastle.crypto.agreement.X448Agreement; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; @@ -19,12 +28,15 @@ import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.X25519PublicKeyParameters; +import org.bouncycastle.crypto.params.X448PublicKeyParameters; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; +import org.bouncycastle.openpgp.PGPSessionKey; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PGPPad; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.RFC6637Utils; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; /** @@ -42,6 +54,7 @@ public BcPublicKeyDataDecryptorFactory(PGPPrivateKey pgpPrivKey) this.pgpPrivKey = pgpPrivKey; } + @Override public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) throws PGPException { @@ -49,7 +62,93 @@ public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) { AsymmetricKeyParameter privKey = KEY_CONVERTER.getPrivateKey(pgpPrivKey); - if (keyAlgorithm != PublicKeyAlgorithmTags.ECDH) + if (keyAlgorithm == PublicKeyAlgorithmTags.X25519) + { + return getSessionData(secKeyData[0], privKey, X25519PublicBCPGKey.LENGTH, HashAlgorithmTags.SHA256, + SymmetricKeyAlgorithmTags.AES_128, new X25519Agreement(), "X25519", new PublicKeyParametersOperation() + { + @Override + public AsymmetricKeyParameter getPublicKeyParameters(byte[] pEnc, int pEncOff) + { + return new X25519PublicKeyParameters(pEnc, 0); + } + }); + } + else if (keyAlgorithm == PublicKeyAlgorithmTags.X448) + { + return getSessionData(secKeyData[0], privKey, X448PublicBCPGKey.LENGTH, HashAlgorithmTags.SHA512, + SymmetricKeyAlgorithmTags.AES_256, new X448Agreement(), "X448", new PublicKeyParametersOperation() + { + @Override + public AsymmetricKeyParameter getPublicKeyParameters(byte[] pEnc, int pEncOff) + { + return new X448PublicKeyParameters(pEnc, 0); + } + }); + } + else if (keyAlgorithm == PublicKeyAlgorithmTags.ECDH) + { + byte[] enc = secKeyData[0]; + byte[] pEnc; + byte[] keyEnc; + int pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8; + assertOutOfRange(2 + pLen + 1, enc); + + pEnc = new byte[pLen]; + System.arraycopy(enc, 2, pEnc, 0, pLen); + + int keyLen = enc[pLen + 2] & 0xff; + assertOutOfRange(2 + pLen + 1 + keyLen, enc); + + keyEnc = new byte[keyLen]; + System.arraycopy(enc, 2 + pLen + 1, keyEnc, 0, keyLen); + + byte[] secret; + RFC6637KDFCalculator rfc6637KDFCalculator; + byte[] userKeyingMaterial; + int symmetricKeyAlgorithm, hashAlgorithm; + + ECDHPublicBCPGKey ecPubKey = (ECDHPublicBCPGKey)pgpPrivKey.getPublicKeyPacket().getKey(); + // XDH + if (BcUtil.isX25519(ecPubKey.getCurveOID())) + { + if (pEnc.length != 1 + X25519PublicKeyParameters.KEY_SIZE || 0x40 != pEnc[0]) + { + throw new IllegalArgumentException("Invalid Curve25519 public key"); + } + // skip the 0x40 header byte. + secret = BcUtil.getSecret(new X25519Agreement(), privKey, new X25519PublicKeyParameters(pEnc, 1)); + } + else if (ecPubKey.getCurveOID().equals(EdECObjectIdentifiers.id_X448)) + { + if (pEnc.length != 1 + X448PublicKeyParameters.KEY_SIZE || 0x40 != pEnc[0]) + { + throw new IllegalArgumentException("Invalid Curve448 public key"); + } + // skip the 0x40 header byte. + secret = BcUtil.getSecret(new X448Agreement(), privKey, new X448PublicKeyParameters(pEnc, 1)); + } + else + { + ECDomainParameters ecParameters = ((ECPrivateKeyParameters)privKey).getParameters(); + + ECPublicKeyParameters ephPub = new ECPublicKeyParameters(ecParameters.getCurve().decodePoint(pEnc), + ecParameters); + + ECDHBasicAgreement agreement = new ECDHBasicAgreement(); + agreement.init(privKey); + BigInteger S = agreement.calculateAgreement(ephPub); + secret = BigIntegers.asUnsignedByteArray(agreement.getFieldSize(), S); + } + hashAlgorithm = ecPubKey.getHashAlgorithm(); + symmetricKeyAlgorithm = ecPubKey.getSymmetricKeyAlgorithm(); + userKeyingMaterial = RFC6637Utils.createUserKeyingMaterial(pgpPrivKey.getPublicKeyPacket(), new BcKeyFingerprintCalculator()); + rfc6637KDFCalculator = new RFC6637KDFCalculator(new BcPGPDigestCalculatorProvider().get(hashAlgorithm), symmetricKeyAlgorithm); + KeyParameter key = new KeyParameter(rfc6637KDFCalculator.createKey(secret, userKeyingMaterial)); + + return PGPPad.unpadSessionData(unwrapSessionData(keyEnc, symmetricKeyAlgorithm, key)); + } + else { AsymmetricBlockCipher c = BcImplProvider.createPublicKeyCipher(keyAlgorithm); @@ -82,10 +181,7 @@ public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) } bi = secKeyData[1]; // encoded MPI - for (int i = 0; i != tmp.length; i++) - { - tmp[i] = 0; - } + Arrays.fill(tmp, (byte)0); if (bi.length - 2 > size) // leading Zero? Shouldn't happen but... { @@ -100,72 +196,6 @@ public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) return c1.doFinal(); } - else - { - ECDHPublicBCPGKey ecPubKey = (ECDHPublicBCPGKey)pgpPrivKey.getPublicKeyPacket().getKey(); - byte[] enc = secKeyData[0]; - - int pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8; - if ((2 + pLen + 1) > enc.length) - { - throw new PGPException("encoded length out of range"); - } - - byte[] pEnc = new byte[pLen]; - System.arraycopy(enc, 2, pEnc, 0, pLen); - - int keyLen = enc[pLen + 2] & 0xff; - if ((2 + pLen + 1 + keyLen) > enc.length) - { - throw new PGPException("encoded length out of range"); - } - - byte[] keyEnc = new byte[keyLen]; - System.arraycopy(enc, 2 + pLen + 1, keyEnc, 0, keyLen); - - byte[] secret; - // XDH - if (ecPubKey.getCurveOID().equals(CryptlibObjectIdentifiers.curvey25519)) - { - // skip the 0x40 header byte. - if (pEnc.length != (1 + X25519PublicKeyParameters.KEY_SIZE) || 0x40 != pEnc[0]) - { - throw new IllegalArgumentException("Invalid Curve25519 public key"); - } - - X25519PublicKeyParameters ephPub = new X25519PublicKeyParameters(pEnc, 1); - - X25519Agreement agreement = new X25519Agreement(); - agreement.init(privKey); - - secret = new byte[agreement.getAgreementSize()]; - agreement.calculateAgreement(ephPub, secret, 0); - } - else - { - ECDomainParameters ecParameters = ((ECPrivateKeyParameters)privKey).getParameters(); - - ECPublicKeyParameters ephPub = new ECPublicKeyParameters(ecParameters.getCurve().decodePoint(pEnc), - ecParameters); - - ECDHBasicAgreement agreement = new ECDHBasicAgreement(); - agreement.init(privKey); - BigInteger S = agreement.calculateAgreement(ephPub); - secret = BigIntegers.asUnsignedByteArray(agreement.getFieldSize(), S); - } - - RFC6637KDFCalculator rfc6637KDFCalculator = new RFC6637KDFCalculator( - new BcPGPDigestCalculatorProvider().get(ecPubKey.getHashAlgorithm()), - ecPubKey.getSymmetricKeyAlgorithm()); - byte[] userKeyingMaterial = RFC6637Utils.createUserKeyingMaterial(pgpPrivKey.getPublicKeyPacket(), - new BcKeyFingerprintCalculator()); - - KeyParameter key = new KeyParameter(rfc6637KDFCalculator.createKey(secret, userKeyingMaterial)); - - Wrapper c = BcImplProvider.createWrapper(ecPubKey.getSymmetricKeyAlgorithm()); - c.init(false, key); - return PGPPad.unpadSessionData(c.unwrap(keyEnc, 0, keyEnc.length)); - } } catch (IOException e) { @@ -175,9 +205,10 @@ public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) { throw new PGPException("exception decrypting session info: " + e.getMessage(), e); } - } + // OpenPGP v4 + @Override public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { @@ -186,9 +217,60 @@ public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int enc return BcUtil.createDataDecryptor(withIntegrityPacket, engine, key); } - public PGPDataDecryptor createDataDecryptor(final int aeadAlgorithm, final byte[] iv, final int chunkSize, final int encAlgorithm, byte[] key) + // OpenPGP v5 + @Override + public PGPDataDecryptor createDataDecryptor(AEADEncDataPacket aeadEncDataPacket, PGPSessionKey sessionKey) + throws PGPException + { + return BcAEADUtil.createOpenPgpV5DataDecryptor(aeadEncDataPacket, sessionKey); + } + + // OpenPGP v6 + @Override + public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, PGPSessionKey sessionKey) + throws PGPException + { + return BcAEADUtil.createOpenPgpV6DataDecryptor(seipd, sessionKey); + } + + @FunctionalInterface + private interface PublicKeyParametersOperation + { + AsymmetricKeyParameter getPublicKeyParameters(byte[] pEnc, int pEncOff); + } + + private byte[] getSessionData(byte[] enc, AsymmetricKeyParameter privKey, int pLen, int hashAlgorithm, int symmetricKeyAlgorithm, + RawAgreement agreement, String algorithmName, PublicKeyParametersOperation pkp) + throws PGPException, InvalidCipherTextException + { + byte[] pEnc = new byte[pLen]; + byte[] keyEnc; + System.arraycopy(enc, 0, pEnc, 0, pLen); + int keyLen = enc[pLen] & 0xff; + assertOutOfRange(pLen + 1 + keyLen, enc); + keyEnc = new byte[keyLen - 1]; + System.arraycopy(enc, pLen + 2, keyEnc, 0, keyEnc.length); + byte[] secret = BcUtil.getSecret(agreement, privKey, pkp.getPublicKeyParameters(pEnc, 0)); + KeyParameter key = new KeyParameter(RFC6637KDFCalculator.createKey(hashAlgorithm, symmetricKeyAlgorithm, + Arrays.concatenate(pEnc, pgpPrivKey.getPublicKeyPacket().getKey().getEncoded(), secret), "OpenPGP " + algorithmName)); + + return Arrays.prepend(unwrapSessionData(keyEnc, symmetricKeyAlgorithm, key), enc[pLen + 1]); + } + + private static byte[] unwrapSessionData(byte[] keyEnc, int symmetricKeyAlgorithm, KeyParameter key) + throws PGPException, InvalidCipherTextException + { + Wrapper c = BcImplProvider.createWrapper(symmetricKeyAlgorithm); + c.init(false, key); + return c.unwrap(keyEnc, 0, keyEnc.length); + } + + private static void assertOutOfRange(int pLen, byte[] enc) throws PGPException { - return BcUtil.createDataDecryptor(aeadAlgorithm, iv, chunkSize, encAlgorithm, key); + if (pLen > enc.length) + { + throw new PGPException("encoded length out of range"); + } } -} +} \ No newline at end of file diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPublicKeyKeyEncryptionMethodGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPublicKeyKeyEncryptionMethodGenerator.java index 3abedce870..60c35df653 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPublicKeyKeyEncryptionMethodGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPublicKeyKeyEncryptionMethodGenerator.java @@ -4,31 +4,39 @@ import java.math.BigInteger; import java.security.SecureRandom; +import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.bcpg.ECDHPublicBCPGKey; -import org.bouncycastle.bcpg.MPInteger; +import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; +import org.bouncycastle.crypto.KeyGenerationParameters; +import org.bouncycastle.crypto.RawAgreement; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.agreement.X25519Agreement; +import org.bouncycastle.crypto.agreement.X448Agreement; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.generators.X25519KeyPairGenerator; +import org.bouncycastle.crypto.generators.X448KeyPairGenerator; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.X25519KeyGenerationParameters; import org.bouncycastle.crypto.params.X25519PublicKeyParameters; +import org.bouncycastle.crypto.params.X448KeyGenerationParameters; +import org.bouncycastle.crypto.params.X448PublicKeyParameters; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.operator.PGPPad; import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.RFC6637Utils; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; /** @@ -45,7 +53,7 @@ public class BcPublicKeyKeyEncryptionMethodGenerator /** * Create a public key encryption method generator with the method to be based on the passed in key. * - * @param key the public key to use for encryption. + * @param key the public key to use for encryption. */ public BcPublicKeyKeyEncryptionMethodGenerator(PGPPublicKey key) { @@ -55,8 +63,8 @@ public BcPublicKeyKeyEncryptionMethodGenerator(PGPPublicKey key) /** * Provide a user defined source of randomness. * - * @param random the secure random to be used. - * @return the current generator. + * @param random the secure random to be used. + * @return the current generator. */ public BcPublicKeyKeyEncryptionMethodGenerator setSecureRandom(SecureRandom random) { @@ -71,42 +79,37 @@ protected byte[] encryptSessionInfo(PGPPublicKey pubKey, byte[] sessionInfo) try { AsymmetricKeyParameter cryptoPublicKey = keyConverter.getPublicKey(pubKey); - + PublicKeyPacket pubKeyPacket = pubKey.getPublicKeyPacket(); if (pubKey.getAlgorithm() == PublicKeyAlgorithmTags.ECDH) { - PublicKeyPacket pubKeyPacket = pubKey.getPublicKeyPacket(); ECDHPublicBCPGKey ecPubKey = (ECDHPublicBCPGKey)pubKeyPacket.getKey(); - - byte[] userKeyingMaterial = RFC6637Utils.createUserKeyingMaterial(pubKeyPacket, - new BcKeyFingerprintCalculator()); - - if (ecPubKey.getCurveOID().equals(CryptlibObjectIdentifiers.curvey25519)) + byte[] userKeyingMaterial = RFC6637Utils.createUserKeyingMaterial(pubKeyPacket, new BcKeyFingerprintCalculator()); + if (BcUtil.isX25519(ecPubKey.getCurveOID())) { - X25519KeyPairGenerator gen = new X25519KeyPairGenerator(); - gen.init(new X25519KeyGenerationParameters(random)); - - AsymmetricCipherKeyPair ephKp = gen.generateKeyPair(); + AsymmetricCipherKeyPair ephKp = getAsymmetricCipherKeyPair(new X25519KeyPairGenerator(), new X25519KeyGenerationParameters(random)); - X25519Agreement agreement = new X25519Agreement(); - agreement.init(ephKp.getPrivate()); - - byte[] secret = new byte[agreement.getAgreementSize()]; - agreement.calculateAgreement(cryptoPublicKey, secret, 0); + byte[] secret = BcUtil.getSecret(new X25519Agreement(), ephKp.getPrivate(), cryptoPublicKey); byte[] ephPubEncoding = new byte[1 + X25519PublicKeyParameters.KEY_SIZE]; ephPubEncoding[0] = X_HDR; ((X25519PublicKeyParameters)ephKp.getPublic()).encode(ephPubEncoding, 1); - - return encryptSessionInfo(ecPubKey, sessionInfo, secret, userKeyingMaterial, ephPubEncoding); + return encryptSessionInfo(sessionInfo, secret, userKeyingMaterial, ephPubEncoding, ecPubKey.getHashAlgorithm(), ecPubKey.getSymmetricKeyAlgorithm()); } - else + else if (ecPubKey.getCurveOID().equals(EdECObjectIdentifiers.id_X448)) { - ECDomainParameters ecParams = ((ECPublicKeyParameters)cryptoPublicKey).getParameters(); + AsymmetricCipherKeyPair ephKp = getAsymmetricCipherKeyPair(new X448KeyPairGenerator(), new X448KeyGenerationParameters(random)); - ECKeyPairGenerator gen = new ECKeyPairGenerator(); - gen.init(new ECKeyGenerationParameters(ecParams, random)); + byte[] secret = BcUtil.getSecret(new X448Agreement(), ephKp.getPrivate(), cryptoPublicKey); - AsymmetricCipherKeyPair ephKp = gen.generateKeyPair(); + byte[] ephPubEncoding = new byte[1 + X448PublicKeyParameters.KEY_SIZE]; + ephPubEncoding[0] = X_HDR; + ((X448PublicKeyParameters)ephKp.getPublic()).encode(ephPubEncoding, 1); + return encryptSessionInfo(sessionInfo, secret, userKeyingMaterial, ephPubEncoding, ecPubKey.getHashAlgorithm(), ecPubKey.getSymmetricKeyAlgorithm()); + } + else + { + AsymmetricCipherKeyPair ephKp = getAsymmetricCipherKeyPair(new ECKeyPairGenerator(), + new ECKeyGenerationParameters(((ECPublicKeyParameters)cryptoPublicKey).getParameters(), random)); ECDHBasicAgreement agreement = new ECDHBasicAgreement(); agreement.init(ephKp.getPrivate()); @@ -115,9 +118,35 @@ protected byte[] encryptSessionInfo(PGPPublicKey pubKey, byte[] sessionInfo) byte[] ephPubEncoding = ((ECPublicKeyParameters)ephKp.getPublic()).getQ().getEncoded(false); - return encryptSessionInfo(ecPubKey, sessionInfo, secret, userKeyingMaterial, ephPubEncoding); + return encryptSessionInfo(sessionInfo, secret, userKeyingMaterial, ephPubEncoding, ecPubKey.getHashAlgorithm(), ecPubKey.getSymmetricKeyAlgorithm()); } } + else if (pubKey.getAlgorithm() == PublicKeyAlgorithmTags.X25519) + { + return encryptSessionInfo(pubKeyPacket, sessionInfo, HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_128, "X25519", + new X25519KeyPairGenerator(), new X25519KeyGenerationParameters(random), new X25519Agreement(), cryptoPublicKey, X25519PublicKeyParameters.KEY_SIZE, + new EphPubEncodingOperation() + { + @Override + public void getEphPubEncoding(AsymmetricKeyParameter publicKey, byte[] ephPubEncoding) + { + ((X25519PublicKeyParameters)publicKey).encode(ephPubEncoding, 0); + } + }); + } + else if (pubKey.getAlgorithm() == PublicKeyAlgorithmTags.X448) + { + return encryptSessionInfo(pubKeyPacket, sessionInfo, HashAlgorithmTags.SHA512, SymmetricKeyAlgorithmTags.AES_256, "X448", + new X448KeyPairGenerator(), new X448KeyGenerationParameters(random), new X448Agreement(), cryptoPublicKey, X448PublicKeyParameters.KEY_SIZE, + new EphPubEncodingOperation() + { + @Override + public void getEphPubEncoding(AsymmetricKeyParameter publicKey, byte[] ephPubEncoding) + { + ((X448PublicKeyParameters)publicKey).encode(ephPubEncoding, 0); + } + }); + } else { AsymmetricBlockCipher c = BcImplProvider.createPublicKeyCipher(pubKey.getAlgorithm()); @@ -127,35 +156,60 @@ protected byte[] encryptSessionInfo(PGPPublicKey pubKey, byte[] sessionInfo) return c.processBlock(sessionInfo, 0, sessionInfo.length); } } - catch (InvalidCipherTextException e) - { - throw new PGPException("exception encrypting session info: " + e.getMessage(), e); - } - catch (IOException e) + catch (Exception e) { throw new PGPException("exception encrypting session info: " + e.getMessage(), e); } } - private byte[] encryptSessionInfo(ECDHPublicBCPGKey ecPubKey, byte[] sessionInfo, byte[] secret, - byte[] userKeyingMaterial, byte[] ephPubEncoding) throws IOException, PGPException + @FunctionalInterface + private interface EphPubEncodingOperation + { + void getEphPubEncoding(AsymmetricKeyParameter publicKey, byte[] ephPubEncoding); + } + + private byte[] encryptSessionInfo(byte[] sessionInfo, byte[] secret, + byte[] userKeyingMaterial, byte[] ephPubEncoding, int hashAlgorithm, int symmetricKeyAlgorithm) + throws IOException, PGPException { RFC6637KDFCalculator rfc6637KDFCalculator = new RFC6637KDFCalculator( - new BcPGPDigestCalculatorProvider().get(ecPubKey.getHashAlgorithm()), ecPubKey.getSymmetricKeyAlgorithm()); + new BcPGPDigestCalculatorProvider().get(hashAlgorithm), symmetricKeyAlgorithm); KeyParameter key = new KeyParameter(rfc6637KDFCalculator.createKey(secret, userKeyingMaterial)); byte[] paddedSessionData = PGPPad.padSessionData(sessionInfo, sessionKeyObfuscation); - Wrapper c = BcImplProvider.createWrapper(ecPubKey.getSymmetricKeyAlgorithm()); - c.init(true, new ParametersWithRandom(key, random)); - byte[] C = c.wrap(paddedSessionData, 0, paddedSessionData.length); + return getSessionInfo(ephPubEncoding, getWrapper(symmetricKeyAlgorithm, key, paddedSessionData)); + } - byte[] VB = new MPInteger(new BigInteger(1, ephPubEncoding)).getEncoded(); + private byte[] encryptSessionInfo(PublicKeyPacket pubKeyPacket, byte[] sessionInfo, int hashAlgorithm, int symmetricKeyAlgorithm, String algorithmName, + AsymmetricCipherKeyPairGenerator gen, KeyGenerationParameters parameters, RawAgreement agreement, AsymmetricKeyParameter cryptoPublicKey, + int keySize, EphPubEncodingOperation ephPubEncodingOperation) + throws PGPException, IOException + { + AsymmetricCipherKeyPair ephKp = getAsymmetricCipherKeyPair(gen, parameters); + byte[] secret = BcUtil.getSecret(agreement, ephKp.getPrivate(), cryptoPublicKey); + byte[] ephPubEncoding = new byte[keySize]; + ephPubEncodingOperation.getEphPubEncoding(ephKp.getPublic(), ephPubEncoding); + KeyParameter key = new KeyParameter(RFC6637KDFCalculator.createKey(hashAlgorithm, symmetricKeyAlgorithm, + Arrays.concatenate(ephPubEncoding, pubKeyPacket.getKey().getEncoded(), secret), "OpenPGP " + algorithmName)); + //No checksum and padding + byte[] sessionData = new byte[sessionInfo.length - 3]; + System.arraycopy(sessionInfo, 1, sessionData, 0, sessionData.length); + + return getSessionInfo(ephPubEncoding, sessionInfo[0], getWrapper(symmetricKeyAlgorithm, key, sessionData)); + } + + private byte[] getWrapper(int symmetricKeyAlgorithm, KeyParameter key, byte[] sessionData) + throws PGPException + { + Wrapper c = BcImplProvider.createWrapper(symmetricKeyAlgorithm); + c.init(true, new ParametersWithRandom(key, random)); + return c.wrap(sessionData, 0, sessionData.length); + } - byte[] rv = new byte[VB.length + 1 + C.length]; - System.arraycopy(VB, 0, rv, 0, VB.length); - rv[VB.length] = (byte)C.length; - System.arraycopy(C, 0, rv, VB.length + 1, C.length); - return rv; + private AsymmetricCipherKeyPair getAsymmetricCipherKeyPair(AsymmetricCipherKeyPairGenerator gen, KeyGenerationParameters parameters) + { + gen.init(parameters); + return gen.generateKeyPair(); } -} +} \ No newline at end of file diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcSessionKeyDataDecryptorFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcSessionKeyDataDecryptorFactory.java index f8e876fd45..a6da0028f7 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcSessionKeyDataDecryptorFactory.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcSessionKeyDataDecryptorFactory.java @@ -1,5 +1,7 @@ package org.bouncycastle.openpgp.operator.bc; +import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPSessionKey; @@ -19,11 +21,14 @@ public BcSessionKeyDataDecryptorFactory(PGPSessionKey sessionKey) this.sessionKey = sessionKey; } + @Override public PGPSessionKey getSessionKey() { return sessionKey; } + // OpenPGP v4 + @Override public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { @@ -31,10 +36,21 @@ public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int enc return BcUtil.createDataDecryptor(withIntegrityPacket, engine, key); } - - public PGPDataDecryptor createDataDecryptor(int aeadAlgorithm, byte[] iv, int chunkSize, int encAlgorithm, byte[] key) + + // OpenPGP v5 + @Override + public PGPDataDecryptor createDataDecryptor(AEADEncDataPacket aeadEncDataPacket, PGPSessionKey sessionKey) throws PGPException { - return BcUtil.createDataDecryptor(aeadAlgorithm, iv, chunkSize, encAlgorithm, key); + return BcAEADUtil.createOpenPgpV5DataDecryptor(aeadEncDataPacket, sessionKey); } + + // OpenPGP v6 + @Override + public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, PGPSessionKey sessionKey) + throws PGPException + { + return BcAEADUtil.createOpenPgpV6DataDecryptor(seipd, sessionKey); + } + } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcUtil.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcUtil.java index 72a1efbf06..d9f8fea076 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcUtil.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcUtil.java @@ -1,43 +1,34 @@ package org.bouncycastle.openpgp.operator.bc; -import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; +import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X9ECParameters; -import org.bouncycastle.bcpg.AEADAlgorithmTags; -import org.bouncycastle.bcpg.PacketTags; -import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; -import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.DefaultBufferedBlockCipher; +import org.bouncycastle.crypto.RawAgreement; import org.bouncycastle.crypto.ec.CustomNamedCurves; -import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.io.CipherInputStream; -import org.bouncycastle.crypto.modes.AEADBlockCipher; import org.bouncycastle.crypto.modes.CFBBlockCipher; -import org.bouncycastle.crypto.modes.EAXBlockCipher; -import org.bouncycastle.crypto.modes.GCMBlockCipher; -import org.bouncycastle.crypto.modes.OCBBlockCipher; import org.bouncycastle.crypto.modes.OpenPGPCFBBlockCipher; -import org.bouncycastle.crypto.params.AEADParameters; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; -import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPSessionKey; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; -import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; -import org.bouncycastle.util.Exceptions; -import org.bouncycastle.util.Pack; -import org.bouncycastle.util.io.Streams; -class BcUtil +public class BcUtil { static BufferedBlockCipher createStreamCipher(boolean forEncryption, BlockCipher engine, boolean withIntegrityPacket, byte[] key) { @@ -45,11 +36,11 @@ static BufferedBlockCipher createStreamCipher(boolean forEncryption, BlockCipher if (withIntegrityPacket) { - c = new BufferedBlockCipher(new CFBBlockCipher(engine, engine.getBlockSize() * 8)); + c = new DefaultBufferedBlockCipher(CFBBlockCipher.newInstance(engine, engine.getBlockSize() * 8)); } else { - c = new BufferedBlockCipher(new OpenPGPCFBBlockCipher(engine)); + c = new DefaultBufferedBlockCipher(new OpenPGPCFBBlockCipher(engine)); } KeyParameter keyParameter = new KeyParameter(key); @@ -66,6 +57,19 @@ static BufferedBlockCipher createStreamCipher(boolean forEncryption, BlockCipher return c; } + /** + * Create a new OpenPGP v4 data decryptor. + * This decryptor can handle Symmetrically Encrypted Data (SED) and v1 Symmetrically Encrypted Integrity-Protected + * Data (SEIPD) packets. + * For AEAD packets, see {@link BcAEADUtil#createOpenPgpV5DataDecryptor(AEADEncDataPacket, PGPSessionKey)} and + * {@link BcAEADUtil#createOpenPgpV6DataDecryptor(SymmetricEncIntegrityPacket, PGPSessionKey)}. + * + * @param withIntegrityPacket if true, the data is contained in a SEIPD v1 packet, if false it is contained in a + * SED packet. + * @param engine decryption engine + * @param key decryption key + * @return decryptor + */ public static PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, BlockCipher engine, byte[] key) { final BufferedBlockCipher c = createStreamCipher(false, engine, withIntegrityPacket, key); @@ -91,7 +95,7 @@ public PGPDigestCalculator getIntegrityCalculator() public static BufferedBlockCipher createSymmetricKeyWrapper(boolean forEncryption, BlockCipher engine, byte[] key, byte[] iv) { - BufferedBlockCipher c = new BufferedBlockCipher(new CFBBlockCipher(engine, engine.getBlockSize() * 8)); + BufferedBlockCipher c = new DefaultBufferedBlockCipher(CFBBlockCipher.newInstance(engine, engine.getBlockSize() * 8)); c.init(forEncryption, new ParametersWithIV(new KeyParameter(key), iv)); @@ -116,419 +120,16 @@ static ECPoint decodePoint( return curve.decodePoint(BigIntegers.asUnsignedByteArray(encodedPoint)); } - private static long getChunkLength(int chunkSize) + static byte[] getSecret(RawAgreement agreement, AsymmetricKeyParameter privKey, AsymmetricKeyParameter ephPub) { - return 1L << (chunkSize + 6); + agreement.init(privKey); + byte[] secret = new byte[agreement.getAgreementSize()]; + agreement.calculateAgreement(ephPub, secret, 0); + return secret; } - static PGPDataDecryptor createDataDecryptor(final int aeadAlgorithm, final byte[] iv, final int chunkSize, final int encAlgorithm, final byte[] key) - throws PGPException + static boolean isX25519(ASN1ObjectIdentifier curveID) { - final KeyParameter secretKey = new KeyParameter(key); - - final AEADBlockCipher c = createAEADCipher(encAlgorithm, aeadAlgorithm); - - return new PGPDataDecryptor() - { - public InputStream getInputStream(InputStream in) - { - try - { - return new PGPAeadInputStream(in, c, secretKey, iv, encAlgorithm, aeadAlgorithm, chunkSize); - } - catch (IOException e) - { - throw Exceptions.illegalStateException("unable to open stream: " + e.getMessage(), e); - } - } - - public int getBlockSize() - { - return c.getUnderlyingCipher().getBlockSize(); - } - - public PGPDigestCalculator getIntegrityCalculator() - { - return new SHA1PGPDigestCalculator(); - } - }; - } - - static AEADBlockCipher createAEADCipher(int encAlgorithm, int aeadAlgorithm) - throws PGPException - { - if (encAlgorithm != SymmetricKeyAlgorithmTags.AES_128 - && encAlgorithm != SymmetricKeyAlgorithmTags.AES_192 - && encAlgorithm != SymmetricKeyAlgorithmTags.AES_256) - { - throw new PGPException("AEAD only supported for AES based algorithms"); - } - - switch (aeadAlgorithm) - { - case AEADAlgorithmTags.EAX: - return new EAXBlockCipher(new AESEngine()); - case AEADAlgorithmTags.OCB: - return new OCBBlockCipher(new AESEngine(), new AESEngine()); - case AEADAlgorithmTags.GCM: - return new GCMBlockCipher(new AESEngine()); - default: - throw new PGPException("unrecognised AEAD algorithm: " + aeadAlgorithm); - } - } - - static byte[] getNonce(byte[] iv, long chunkIndex) - { - byte[] nonce = Arrays.clone(iv); - - xorChunkId(nonce, chunkIndex); - - return nonce; - } - - static void xorChunkId(byte[] nonce, long chunkIndex) - { - int index = nonce.length - 8; - - nonce[index++] ^= (byte)(chunkIndex >> 56); - nonce[index++] ^= (byte)(chunkIndex >> 48); - nonce[index++] ^= (byte)(chunkIndex >> 40); - nonce[index++] ^= (byte)(chunkIndex >> 32); - nonce[index++] ^= (byte)(chunkIndex >> 24); - nonce[index++] ^= (byte)(chunkIndex >> 16); - nonce[index++] ^= (byte)(chunkIndex >> 8); - nonce[index] ^= (byte)(chunkIndex); - } - - private static class PGPAeadInputStream - extends InputStream - { - private final InputStream in; - private final byte[] buf; - private final AEADBlockCipher c; - private final KeyParameter secretKey; - private final byte[] aaData; - private final byte[] iv; - private final int chunkLength; - - private byte[] data; - private int dataOff; - private long chunkIndex = 0; - private long totalBytes = 0; - - public PGPAeadInputStream(InputStream in, AEADBlockCipher c, KeyParameter secretKey, byte[] iv, int encAlgorithm, int aeadAlgorithm, int chunkSize) - throws IOException - { - this.in = in; - this.iv = iv; - this.chunkLength = (int)getChunkLength(chunkSize); - this.buf = new byte[chunkLength + 32]; // allow room for chunk tag and message tag - this.c = c; - this.secretKey = secretKey; - - aaData = new byte[5]; - - aaData[0] = (byte)(0xC0 | PacketTags.AEAD_ENC_DATA); - aaData[1] = 0x01; // packet version - aaData[2] = (byte)encAlgorithm; - aaData[3] = (byte)aeadAlgorithm; - aaData[4] = (byte)chunkSize; - - // prime with 2 * tag len bytes. - Streams.readFully(in, buf, 0, 32); - - // load the first block - this.data = readBlock(); - this.dataOff = 0; - } - - public int read() - throws IOException - { - if (data != null && dataOff == data.length) - { - this.data = readBlock(); - this.dataOff = 0; - } - - if (this.data == null) - { - return -1; - } - - return data[dataOff++] & 0xff; - } - - public int read(byte[] b, int off, int len) - throws IOException - { - if (data != null && dataOff == data.length) - { - this.data = readBlock(); - this.dataOff = 0; - } - - if (this.data == null) - { - return -1; - } - - int supplyLen = Math.min(len, available()); - System.arraycopy(data, dataOff, b, off, supplyLen); - dataOff += supplyLen; - - return supplyLen; - } - - public long skip(long n) - throws IOException - { - if (n <= 0) - { - return 0; - } - - int skip = (int)Math.min(n, available()); - dataOff += skip; - return skip; - } - - public int available() - throws IOException - { - if (data != null && dataOff == data.length) - { - this.data = readBlock(); - this.dataOff = 0; - } - - if (this.data == null) - { - return -1; - } - - return data.length - dataOff; - } - - private byte[] readBlock() - throws IOException - { - // we initialise with the first 16 bytes as there is an additional 16 bytes following - // the last chunk (which may not be the exact chunklength). - int dataLen = Streams.readFully(in, buf, 32, chunkLength); - if (dataLen == 0) - { - return null; - } - - byte[] adata = new byte[13]; - System.arraycopy(aaData, 0, adata, 0, aaData.length); - - xorChunkId(adata, chunkIndex); - - byte[] decData = new byte[dataLen]; - try - { - c.init(false, new AEADParameters(secretKey, 128, getNonce(iv, chunkIndex))); // always full tag. - - c.processAADBytes(adata, 0, adata.length); - - int len = c.processBytes(buf, 0, dataLen + 16, decData, 0); - - c.doFinal(decData, len); - } - catch (InvalidCipherTextException e) - { - throw new IOException("exception processing chunk " + chunkIndex + ": " + e.getMessage()); - } - - totalBytes += decData.length; - chunkIndex++; - - System.arraycopy(buf, dataLen + 16, buf, 0, 16); // copy back the "tag" - - if (dataLen != chunkLength) // it's our last block - { - adata = new byte[13]; - - System.arraycopy(aaData, 0, adata, 0, aaData.length); - - xorChunkId(adata, chunkIndex); - try - { - c.init(false, new AEADParameters(secretKey, 128, getNonce(iv, chunkIndex))); // always full tag. - - c.processAADBytes(adata, 0, adata.length); - c.processAADBytes(Pack.longToBigEndian(totalBytes), 0, 8); - - c.processBytes(buf, 0, 16, buf, 0); - - c.doFinal(buf, 0); // check final tag - } - catch (InvalidCipherTextException e) - { - throw new IOException("exception processing final tag: " + e.getMessage()); - } - } - else - { - Streams.readFully(in, buf, 16, 16); // read the next tag bytes - } - - return decData; - } - } - - static class PGPAeadOutputStream - extends OutputStream - { - private final OutputStream out; - private final byte[] data; - private final AEADBlockCipher c; - private final KeyParameter secretKey; - private final byte[] aaData; - private final byte[] iv; - private final int chunkLength; - - private int dataOff; - private long chunkIndex = 0; - private long totalBytes = 0; - - public PGPAeadOutputStream(OutputStream out, AEADBlockCipher c, KeyParameter secretKey, int encAlgorithm, int aeadAlgorithm, int chunkSize, byte[] iv) - { - this.out = out; - this.iv = iv; - this.chunkLength = (int)getChunkLength(chunkSize); - this.data = new byte[chunkLength]; - this.c = c; - this.secretKey = secretKey; - - aaData = new byte[5]; - - aaData[0] = (byte)(0xC0 | PacketTags.AEAD_ENC_DATA); - aaData[1] = 0x01; // packet version - aaData[2] = (byte)encAlgorithm; - aaData[3] = (byte)aeadAlgorithm; - aaData[4] = (byte)chunkSize; - } - - public void write(int b) - throws IOException - { - if (dataOff == data.length) - { - writeBlock(); - } - data[dataOff++] = (byte)b; - } - - public void write(byte[] b, int off, int len) - throws IOException - { - if (dataOff == data.length) - { - writeBlock(); - } - - if (len < data.length - dataOff) - { - System.arraycopy(b, off, data, dataOff, len); - dataOff += len; - } - else - { - int gap = data.length - dataOff; - System.arraycopy(b, off, data, dataOff, gap); - dataOff += gap; - writeBlock(); - - len -= gap; - off += gap; - - while (len >= data.length) - { - System.arraycopy(b, off, data, 0, data.length); - dataOff = data.length; - writeBlock(); - len -= data.length; - off += data.length; - } - - if (len > 0) - { - System.arraycopy(b, off, data, 0, len); - dataOff = len; - } - } - } - - public void close() - throws IOException - { - finish(); - } - - private void writeBlock() - throws IOException - { - byte[] adata = new byte[13]; - System.arraycopy(aaData, 0, adata, 0, aaData.length); - - xorChunkId(adata, chunkIndex); - - try - { - c.init(true, new AEADParameters(secretKey, 128, getNonce(iv, chunkIndex))); // always full tag. - - c.processAADBytes(adata, 0,adata.length); - - int len = c.processBytes(data, 0, dataOff, data, 0); - - out.write(data, 0, len); - - len = c.doFinal(data, 0); - - out.write(data, 0, len); - } - catch (InvalidCipherTextException e) - { - throw new IOException("exception processing chunk " + chunkIndex + ": " + e.getMessage()); - } - - totalBytes += dataOff; - chunkIndex++; - dataOff = 0; - } - - private void finish() - throws IOException - { - if (dataOff > 0) - { - writeBlock(); - } - - byte[] adata = new byte[13]; - System.arraycopy(aaData, 0, adata, 0, aaData.length); - - xorChunkId(adata, chunkIndex); - try - { - c.init(true, new AEADParameters(secretKey, 128, getNonce(iv, chunkIndex))); // always full tag. - - c.processAADBytes(adata, 0, adata.length); - c.processAADBytes(Pack.longToBigEndian(totalBytes), 0, 8); - - c.doFinal(data, 0); - - out.write(data, 0, 16); // output final tag - - out.close(); - } - catch (InvalidCipherTextException e) - { - throw new IOException("exception processing final tag: " + e.getMessage()); - } - } + return curveID.equals(CryptlibObjectIdentifiers.curvey25519) || curveID.equals(EdECObjectIdentifiers.id_X25519); } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/CryptlibObjectIdentifiers.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/CryptlibObjectIdentifiers.java deleted file mode 100644 index 3e65fe0800..0000000000 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/CryptlibObjectIdentifiers.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.bouncycastle.openpgp.operator.bc; - -import org.bouncycastle.asn1.ASN1ObjectIdentifier; - -// temporary fix for 172.1 due to module export lacking in provider. -class CryptlibObjectIdentifiers -{ - public static final ASN1ObjectIdentifier cryptlib = new ASN1ObjectIdentifier("1.3.6.1.4.1.3029"); - - public static final ASN1ObjectIdentifier ecc = cryptlib.branch("1").branch("5"); - - public static final ASN1ObjectIdentifier curvey25519 = ecc.branch("1"); -} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/RFC6637KDFCalculator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/RFC6637KDFCalculator.java index f4d27da7a2..8da21226e5 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/RFC6637KDFCalculator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/RFC6637KDFCalculator.java @@ -4,9 +4,12 @@ import java.io.OutputStream; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.params.HKDFParameters; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; /** @@ -46,6 +49,34 @@ public byte[] createKey(byte[] secret, byte[] userKeyingMaterial) } } + /** + * Creates a session key for X25519 or X448 encryption based on the provided algorithm and key algorithm. + *

      + * The method follows the specifications outlined in the OpenPGP standards, specifically sections 5.1.6 and 5.1.7 + * of draft-ietf-openpgp-crypto-refresh-13. + * + * @param algorithm The algorithm to use for key derivation, such as SHA256 or SHA512. + * @param keyAlgorithm The key algorithm identifier, representing AES-128 or AES-256. + * @param prepend The bytes to prepend before deriving the key, which should include: + * - 32/56 octets of the ephemeral X25519 or X448 public key + * - 32/56 octets of the recipient public key material + * - 32/56 octets of the shared secret + * @param info The info parameter used in the HKDF function. For X25519, use "OpenPGP X25519". + * For X448, use "OpenPGP X448". + * @return The derived key for encryption. + * @throws PGPException If an error occurs during key derivation. + * @see draft-ietf-openpgp-crypto-refresh-13 + */ + public static byte[] createKey(int algorithm, int keyAlgorithm, byte[] prepend, String info) + throws PGPException + { + HKDFBytesGenerator hkdf = new HKDFBytesGenerator(BcImplProvider.createDigest(algorithm)); + hkdf.init(new HKDFParameters(prepend, null, Strings.toByteArray(info))); + byte[] key = new byte[getKeyLen(keyAlgorithm)]; + hkdf.generateBytes(key, 0, key.length); + return key; + } + // RFC 6637 - Section 7 // Implements KDF( X, oBits, Param ); // Input: point X = (x,y) @@ -86,10 +117,13 @@ private static int getKeyLen(int algID) switch (algID) { case SymmetricKeyAlgorithmTags.AES_128: + case SymmetricKeyAlgorithmTags.CAMELLIA_128: return 16; case SymmetricKeyAlgorithmTags.AES_192: + case SymmetricKeyAlgorithmTags.CAMELLIA_192: return 24; case SymmetricKeyAlgorithmTags.AES_256: + case SymmetricKeyAlgorithmTags.CAMELLIA_256: return 32; default: throw new PGPException("unknown symmetric algorithm ID: " + algID); diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/CryptlibObjectIdentifiers.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/CryptlibObjectIdentifiers.java deleted file mode 100644 index c56c49c542..0000000000 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/CryptlibObjectIdentifiers.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.bouncycastle.openpgp.operator.jcajce; - -import org.bouncycastle.asn1.ASN1ObjectIdentifier; - -// temporary fix for 172.1 due to module export lacking in provider. -class CryptlibObjectIdentifiers -{ - public static final ASN1ObjectIdentifier cryptlib = new ASN1ObjectIdentifier("1.3.6.1.4.1.3029"); - - public static final ASN1ObjectIdentifier ecc = cryptlib.branch("1").branch("5"); - - public static final ASN1ObjectIdentifier curvey25519 = ecc.branch("1"); -} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaAEADSecretKeyEncryptorBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaAEADSecretKeyEncryptorBuilder.java new file mode 100644 index 0000000000..cd609746b1 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaAEADSecretKeyEncryptorBuilder.java @@ -0,0 +1,119 @@ +package org.bouncycastle.openpgp.operator.jcajce; + +import org.bouncycastle.bcpg.AEADUtils; +import org.bouncycastle.bcpg.PacketTags; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.S2K; +import org.bouncycastle.bcpg.SymmetricKeyUtils; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.params.HKDFParameters; +import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; +import org.bouncycastle.jcajce.util.NamedJcaJceHelper; +import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPUtil; +import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; +import org.bouncycastle.util.Arrays; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.Provider; +import java.security.SecureRandom; + +public class JcaAEADSecretKeyEncryptorBuilder +{ + private int aeadAlgorithm; + private int symmetricAlgorithm; + private S2K.Argon2Params argon2Params; + + private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); + private JceAEADUtil aeadUtil = new JceAEADUtil(helper); + + public JcaAEADSecretKeyEncryptorBuilder(int aeadAlgorithm, int symmetricAlgorithm, S2K.Argon2Params argon2Params) + { + this.aeadAlgorithm = aeadAlgorithm; + this.symmetricAlgorithm = symmetricAlgorithm; + this.argon2Params = argon2Params; + } + + public JcaAEADSecretKeyEncryptorBuilder setProvider(Provider provider) + { + this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + this.aeadUtil = new JceAEADUtil(helper); + + return this; + } + + public JcaAEADSecretKeyEncryptorBuilder setProvider(String providerName) + { + this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + this.aeadUtil = new JceAEADUtil(helper); + + return this; + } + + public PBESecretKeyEncryptor build(char[] passphrase, PublicKeyPacket pubKey) + { + return new PBESecretKeyEncryptor(symmetricAlgorithm, aeadAlgorithm, argon2Params, new SecureRandom(), passphrase) + { + private byte[] iv; + + { + iv = new byte[AEADUtils.getIVLength(aeadAlgorithm)]; + random.nextBytes(iv); + } + + @Override + public byte[] encryptKeyData(byte[] key, byte[] keyData, int keyOff, int keyLen) + throws PGPException + { + int packetTag = pubKey.getPacketTag() == PacketTags.PUBLIC_KEY ? PacketTags.SECRET_KEY : PacketTags.SECRET_SUBKEY; + byte[] hkdfInfo = new byte[] { + (byte) (0xC0 | packetTag), + (byte) pubKey.getVersion(), + (byte) symmetricAlgorithm, + (byte) aeadAlgorithm + }; + + HKDFParameters hkdfParameters = new HKDFParameters( + getKey(), + null, + hkdfInfo); + + HKDFBytesGenerator hkdfGen = new HKDFBytesGenerator(new SHA256Digest()); + hkdfGen.init(hkdfParameters); + key = new byte[SymmetricKeyUtils.getKeyLengthInOctets(encAlgorithm)]; + hkdfGen.generateBytes(key, 0, key.length); + + try + { + byte[] aad = Arrays.prepend(pubKey.getEncodedContents(), (byte) (0xC0 | packetTag)); + SecretKey secretKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); + final Cipher c = aeadUtil.createAEADCipher(encAlgorithm, aeadAlgorithm); + + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.ENCRYPT_MODE, iv, 128, aad); + byte[] data = c.doFinal(keyData, keyOff, keyLen); + return data; + } + catch (IOException | InvalidAlgorithmParameterException | InvalidKeyException | + IllegalBlockSizeException | BadPaddingException e) + { + throw new PGPException("Exception AEAD protecting private key material", e); + } + } + + @Override + public byte[] getCipherIV() + { + return iv; + } + }; + } +} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaJcePGPUtil.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaJcePGPUtil.java index 223b7aa626..d87663a715 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaJcePGPUtil.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaJcePGPUtil.java @@ -2,18 +2,30 @@ import java.io.IOException; import java.math.BigInteger; +import java.security.GeneralSecurityException; +import java.security.Key; +import java.security.PublicKey; +import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; +import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X9ECParameters; +import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.crypto.ec.CustomNamedCurves; +import org.bouncycastle.jcajce.spec.HybridValueParameterSpec; +import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; +import org.bouncycastle.util.Strings; /** * Basic utility class @@ -21,11 +33,11 @@ class JcaJcePGPUtil { public static SecretKey makeSymmetricKey( - int algorithm, - byte[] keyBytes) + int algorithm, + byte[] keyBytes) throws PGPException { - String algName = org.bouncycastle.openpgp.PGPUtil.getSymmetricCipherName(algorithm); + String algName = org.bouncycastle.openpgp.PGPUtil.getSymmetricCipherName(algorithm); if (algName == null) { @@ -54,4 +66,24 @@ static X9ECParameters getX9Parameters(ASN1ObjectIdentifier curveOID) return x9Params; } + + static HybridValueParameterSpec getHybridValueParameterSpecWithPrepend(byte[] ephmeralPublicKey, PublicKeyPacket pkp, String algorithmName) + throws IOException + { + return new HybridValueParameterSpec(Arrays.concatenate(ephmeralPublicKey, pkp.getEncoded()), true, new UserKeyingMaterialSpec(Strings.toByteArray("OpenPGP " + algorithmName))); + } + + static Key getSecret(OperatorHelper helper, PublicKey cryptoPublicKey, String keyEncryptionOID, String agreementName, AlgorithmParameterSpec ukmSpec, Key privKey) + throws GeneralSecurityException + { + KeyAgreement agreement = helper.createKeyAgreement(agreementName); + agreement.init(privKey, ukmSpec); + agreement.doPhase(cryptoPublicKey, true); + return agreement.generateSecret(keyEncryptionOID); + } + + static boolean isX25519(ASN1ObjectIdentifier curveID) + { + return curveID.equals(CryptlibObjectIdentifiers.curvey25519) || curveID.equals(EdECObjectIdentifiers.id_X25519); + } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaKeyFingerprintCalculator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaKeyFingerprintCalculator.java index 8bf921a0e0..7fe9fd6036 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaKeyFingerprintCalculator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaKeyFingerprintCalculator.java @@ -10,6 +10,7 @@ import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSAPublicBCPGKey; +import org.bouncycastle.bcpg.UnsupportedPacketVersionException; import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jcajce.util.NamedJcaJceHelper; @@ -29,7 +30,7 @@ public JcaKeyFingerprintCalculator() { this(new DefaultJcaJceHelper()); } - + private JcaKeyFingerprintCalculator(JcaJceHelper helper) { this.helper = helper; @@ -62,7 +63,7 @@ public byte[] calculateFingerprint(PublicKeyPacket publicPk) { BCPGKey key = publicPk.getKey(); - if (publicPk.getVersion() <= 3) + if (publicPk.getVersion() <= PublicKeyPacket.VERSION_3) { RSAPublicBCPGKey rK = (RSAPublicBCPGKey)key; @@ -70,7 +71,7 @@ public byte[] calculateFingerprint(PublicKeyPacket publicPk) { MessageDigest digest = helper.createMessageDigest("MD5"); - byte[] bytes = new MPInteger(rK.getModulus()).getEncoded(); + byte[] bytes = new MPInteger(rK.getModulus()).getEncoded(); digest.update(bytes, 2, bytes.length - 2); bytes = new MPInteger(rK.getPublicExponent()).getEncoded(); @@ -78,11 +79,7 @@ public byte[] calculateFingerprint(PublicKeyPacket publicPk) return digest.digest(); } - catch (NoSuchAlgorithmException e) - { - throw new PGPException("can't find MD5", e); - } - catch (NoSuchProviderException e) + catch (NoSuchAlgorithmException | NoSuchProviderException e) { throw new PGPException("can't find MD5", e); } @@ -91,11 +88,11 @@ public byte[] calculateFingerprint(PublicKeyPacket publicPk) throw new PGPException("can't encode key components: " + e.getMessage(), e); } } - else + else if (publicPk.getVersion() == PublicKeyPacket.VERSION_4) { try { - byte[] kBytes = publicPk.getEncodedContents(); + byte[] kBytes = publicPk.getEncodedContents(); MessageDigest digest = helper.createMessageDigest("SHA1"); @@ -106,18 +103,50 @@ public byte[] calculateFingerprint(PublicKeyPacket publicPk) return digest.digest(); } - catch (NoSuchAlgorithmException e) + catch (NoSuchAlgorithmException | NoSuchProviderException e) { throw new PGPException("can't find SHA1", e); } + catch (IOException e) + { + throw new PGPException("can't encode key components: " + e.getMessage(), e); + } + } + else if (publicPk.getVersion() == PublicKeyPacket.LIBREPGP_5 || publicPk.getVersion() == PublicKeyPacket.VERSION_6) + { + try + { + byte[] kBytes = publicPk.getEncodedContents(); + + MessageDigest digest = helper.createMessageDigest("SHA-256"); + + digest.update((byte) (publicPk.getVersion() == PublicKeyPacket.VERSION_6 ? 0x9b : 0x9a)); + + digest.update((byte)(kBytes.length >> 24)); + digest.update((byte)(kBytes.length >> 16)); + digest.update((byte)(kBytes.length >> 8)); + digest.update((byte)kBytes.length); + + digest.update(kBytes); + + return digest.digest(); + } + catch (NoSuchAlgorithmException e) + { + throw new PGPException("can't find SHA-256", e); + } catch (NoSuchProviderException e) { - throw new PGPException("can't find SHA1", e); + throw new PGPException("can't find SHA-256", e); } catch (IOException e) { throw new PGPException("can't encode key components: " + e.getMessage(), e); } } + else + { + throw new UnsupportedPacketVersionException("Unsupported PGP key version: " + publicPk.getVersion()); + } } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPContentSignerBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPContentSignerBuilder.java index 60973d0789..46968de581 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPContentSignerBuilder.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPContentSignerBuilder.java @@ -24,11 +24,11 @@ public class JcaPGPContentSignerBuilder implements PGPContentSignerBuilder { - private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); + private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private JcaPGPDigestCalculatorProviderBuilder digestCalculatorProviderBuilder = new JcaPGPDigestCalculatorProviderBuilder(); - private JcaPGPKeyConverter keyConverter = new JcaPGPKeyConverter(); - private int hashAlgorithm; - private SecureRandom random; + private JcaPGPKeyConverter keyConverter = new JcaPGPKeyConverter(); + private int hashAlgorithm; + private SecureRandom random; private int keyAlgorithm; public JcaPGPContentSignerBuilder(int keyAlgorithm, int hashAlgorithm) @@ -94,7 +94,17 @@ public PGPContentSigner build(final int signatureType, final long keyID, final P { final PGPDigestCalculator digestCalculator = digestCalculatorProviderBuilder.build().get(hashAlgorithm); final PGPDigestCalculator edDigestCalculator = digestCalculatorProviderBuilder.build().get(hashAlgorithm); - final Signature signature = helper.createSignature(keyAlgorithm, hashAlgorithm); + final Signature signature; + + if (keyAlgorithm == PublicKeyAlgorithmTags.EDDSA_LEGACY && privateKey.getAlgorithm().equals("Ed448")) + { + signature = helper.createSignature("Ed448"); + } + else + { + signature = helper.createSignature(keyAlgorithm, hashAlgorithm); + } + try { @@ -109,11 +119,13 @@ public PGPContentSigner build(final int signatureType, final long keyID, final P } catch (InvalidKeyException e) { - throw new PGPException("invalid key.", e); + throw new PGPException("invalid key.", e); } return new PGPContentSigner() { + private final boolean isEdDsa = keyAlgorithm == PublicKeyAlgorithmTags.EDDSA_LEGACY || keyAlgorithm == PublicKeyAlgorithmTags.Ed448 || keyAlgorithm == PublicKeyAlgorithmTags.Ed25519; + public int getType() { return signatureType; @@ -136,7 +148,7 @@ public long getKeyID() public OutputStream getOutputStream() { - if (keyAlgorithm == PublicKeyAlgorithmTags.EDDSA_LEGACY) + if (isEdDsa) { return new TeeOutputStream(edDigestCalculator.getOutputStream(), digestCalculator.getOutputStream()); } @@ -147,9 +159,9 @@ public byte[] getSignature() { try { - if (keyAlgorithm == PublicKeyAlgorithmTags.EDDSA_LEGACY) + if (isEdDsa) { - signature.update(edDigestCalculator.getDigest()); + signature.update(edDigestCalculator.getDigest()); } return signature.sign(); } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPContentVerifierBuilderProvider.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPContentVerifierBuilderProvider.java index 8705efc99f..73f33ec310 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPContentVerifierBuilderProvider.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPContentVerifierBuilderProvider.java @@ -71,10 +71,19 @@ public JcaPGPContentVerifierBuilder(int keyAlgorithm, int hashAlgorithm) public PGPContentVerifier build(final PGPPublicKey publicKey) throws PGPException { - final Signature signature = helper.createSignature(keyAlgorithm, hashAlgorithm); final PGPDigestCalculator digestCalculator = digestCalculatorProviderBuilder.build().get(hashAlgorithm); final PublicKey jcaKey = keyConverter.getPublicKey(publicKey); + final Signature signature; + if (keyAlgorithm == PublicKeyAlgorithmTags.EDDSA_LEGACY && jcaKey.getAlgorithm().equals("Ed448")) + { + signature = helper.createSignature(PublicKeyAlgorithmTags.Ed448, hashAlgorithm); + } + else + { + signature = helper.createSignature(keyAlgorithm, hashAlgorithm); + } + try { signature.initVerify(jcaKey); @@ -86,6 +95,8 @@ public PGPContentVerifier build(final PGPPublicKey publicKey) return new PGPContentVerifier() { + private final boolean isEdDsa = keyAlgorithm == PublicKeyAlgorithmTags.EDDSA_LEGACY || keyAlgorithm == PublicKeyAlgorithmTags.Ed448 || keyAlgorithm == PublicKeyAlgorithmTags.Ed25519; + public int getHashAlgorithm() { return hashAlgorithm; @@ -115,14 +126,14 @@ public boolean verify(byte[] expected) byte[] tmp = new byte[modLength]; System.arraycopy(expected, 0, tmp, tmp.length - expected.length, expected.length); - + return signature.verify(tmp); } } - if (keyAlgorithm == PublicKeyAlgorithmTags.EDDSA_LEGACY) + if (isEdDsa) { signature.update(digestCalculator.getDigest()); - + return signature.verify(expected); } return signature.verify(expected); @@ -135,9 +146,9 @@ public boolean verify(byte[] expected) public OutputStream getOutputStream() { - if (keyAlgorithm == PublicKeyAlgorithmTags.EDDSA_LEGACY) + if (isEdDsa) { - return digestCalculator.getOutputStream(); + return digestCalculator.getOutputStream(); } return OutputStreamFactory.createStream(signature); } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.java index 4c4699b415..c31bb6df5d 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.java @@ -5,8 +5,6 @@ import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; @@ -14,22 +12,20 @@ import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; -import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; import java.security.spec.ECPrivateKeySpec; import java.security.spec.ECPublicKeySpec; -import java.security.spec.InvalidParameterSpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Date; +import java.util.Enumeration; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; @@ -37,18 +33,22 @@ import javax.crypto.spec.DHPrivateKeySpec; import javax.crypto.spec.DHPublicKeySpec; +import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.gnu.GNUObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.ECNamedCurveTable; +import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECParametersHolder; import org.bouncycastle.asn1.x9.X9ECPoint; +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.bcpg.BCPGKey; import org.bouncycastle.bcpg.DSAPublicBCPGKey; import org.bouncycastle.bcpg.DSASecretBCPGKey; @@ -56,39 +56,45 @@ import org.bouncycastle.bcpg.ECDSAPublicBCPGKey; import org.bouncycastle.bcpg.ECPublicBCPGKey; import org.bouncycastle.bcpg.ECSecretBCPGKey; +import org.bouncycastle.bcpg.Ed25519PublicBCPGKey; +import org.bouncycastle.bcpg.Ed25519SecretBCPGKey; +import org.bouncycastle.bcpg.Ed448PublicBCPGKey; +import org.bouncycastle.bcpg.Ed448SecretBCPGKey; import org.bouncycastle.bcpg.EdDSAPublicBCPGKey; import org.bouncycastle.bcpg.EdSecretBCPGKey; import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; -import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSAPublicBCPGKey; import org.bouncycastle.bcpg.RSASecretBCPGKey; -import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.X25519PublicBCPGKey; +import org.bouncycastle.bcpg.X25519SecretBCPGKey; +import org.bouncycastle.bcpg.X448PublicBCPGKey; +import org.bouncycastle.bcpg.X448SecretBCPGKey; +import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; import org.bouncycastle.jcajce.util.NamedJcaJceHelper; import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; +import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.math.ec.rfc7748.X25519; +import org.bouncycastle.math.ec.rfc7748.X448; import org.bouncycastle.math.ec.rfc8032.Ed25519; +import org.bouncycastle.math.ec.rfc8032.Ed448; import org.bouncycastle.openpgp.PGPAlgorithmParameters; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKdfParameters; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; +import org.bouncycastle.openpgp.operator.PGPKeyConverter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; public class JcaPGPKeyConverter + extends PGPKeyConverter { - private static final int X25519_KEY_SIZE = 32; - private static final int ED25519_KEY_SIZE = 32; - - // We default to these as they are specified as mandatory in RFC 6631. - private static final PGPKdfParameters DEFAULT_KDF_PARAMETERS = new PGPKdfParameters(HashAlgorithmTags.SHA256, - SymmetricKeyAlgorithmTags.AES_128); - private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private KeyFingerPrintCalculator fingerPrintCalculator = new JcaKeyFingerprintCalculator(); @@ -109,8 +115,8 @@ public JcaPGPKeyConverter setProvider(String providerName) /** * Convert a PrivateKey into a PGPPrivateKey. * - * @param pub the corresponding PGPPublicKey to privKey. - * @param privKey the private key for the key in pub. + * @param pub the corresponding PGPPublicKey to privKey. + * @param privKey the private key for the key in pub. * @return a PGPPrivateKey * @throws PGPException */ @@ -123,23 +129,24 @@ public PGPPrivateKey getPGPPrivateKey(PGPPublicKey pub, PrivateKey privKey) } /** - * Create a PGPPublicKey from the passed in JCA one. + * Create a version 4 PGPPublicKey from the passed in JCA one. *

      * Note: the time passed in affects the value of the key's keyID, so you probably only want * to do this once for a JCA key, or make sure you keep track of the time you used. *

      - * @param algorithm asymmetric algorithm type representing the public key. + * + * @param algorithm asymmetric algorithm type representing the public key. * @param algorithmParameters additional parameters to be stored against the public key. - * @param pubKey actual public key to associate. - * @param time date of creation. + * @param pubKey actual public key to associate. + * @param time date of creation. * @throws PGPException on key creation problem. + * @deprecated use versioned {@link #getPGPPublicKey(int, int, PGPAlgorithmParameters, PublicKey, Date)} instead. */ + @Deprecated public PGPPublicKey getPGPPublicKey(int algorithm, PGPAlgorithmParameters algorithmParameters, PublicKey pubKey, Date time) throws PGPException { - BCPGKey bcpgKey = getPublicBCPGKey(algorithm, algorithmParameters, pubKey, time); - - return new PGPPublicKey(new PublicKeyPacket(algorithm, time, bcpgKey), fingerPrintCalculator); + return getPGPPublicKey(PublicKeyPacket.VERSION_4, algorithm, algorithmParameters, pubKey, time); } /** @@ -148,17 +155,61 @@ public PGPPublicKey getPGPPublicKey(int algorithm, PGPAlgorithmParameters algori * Note: the time passed in affects the value of the key's keyID, so you probably only want * to do this once for a JCA key, or make sure you keep track of the time you used. *

      + * + * @param version key version. + * @param algorithm asymmetric algorithm type representing the public key. + * @param algorithmParameters additional parameters to be stored against the public key. + * @param pubKey actual public key to associate. + * @param time date of creation. + * @throws PGPException on key creation problem. + */ + public PGPPublicKey getPGPPublicKey(int version, int algorithm, PGPAlgorithmParameters algorithmParameters, PublicKey pubKey, Date time) + throws PGPException + { + BCPGKey bcpgKey = getPublicBCPGKey(algorithm, algorithmParameters, pubKey); + + return new PGPPublicKey(new PublicKeyPacket(version, algorithm, time, bcpgKey), fingerPrintCalculator); + } + + /** + * Create a version 4 PGPPublicKey from the passed in JCA one. + *

      + * Note: the time passed in affects the value of the key's keyID, so you probably only want + * to do this once for a JCA key, or make sure you keep track of the time you used. + *

      + * * @param algorithm asymmetric algorithm type representing the public key. * @param pubKey actual public key to associate. * @param time date of creation. * @throws PGPException on key creation problem. + * @deprecated use versioned {@link #getPGPPublicKey(int, int, PublicKey, Date)} instead. */ + @Deprecated public PGPPublicKey getPGPPublicKey(int algorithm, PublicKey pubKey, Date time) throws PGPException { return getPGPPublicKey(algorithm, null, pubKey, time); } + /** + * Create a PGPPublicKey from the passed in JCA one. + *

      + * Note: the time passed in affects the value of the key's keyID, so you probably only want + * to do this once for a JCA key, or make sure you keep track of the time you used. + *

      + * + * @param version key version. + * @param algorithm asymmetric algorithm type representing the public key. + * @param pubKey actual public key to associate. + * @param time date of creation. + * @throws PGPException on key creation problem. + */ + public PGPPublicKey getPGPPublicKey(int version, int algorithm, PublicKey pubKey, Date time) + throws PGPException + { + return getPGPPublicKey(version, algorithm, null, pubKey, time); + } + public PrivateKey getPrivateKey(PGPPrivateKey privKey) throws PGPException { @@ -188,31 +239,70 @@ public PrivateKey getPrivateKey(PGPPrivateKey privKey) ECDHPublicBCPGKey ecdhPub = (ECDHPublicBCPGKey)pubPk.getKey(); ECSecretBCPGKey ecdhK = (ECSecretBCPGKey)privPk; - if (CryptlibObjectIdentifiers.curvey25519.equals(ecdhPub.getCurveOID())) + // Legacy XDH on Curve25519 (legacy X25519) + // 1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110 + if (JcaJcePGPUtil.isX25519(ecdhPub.getCurveOID())) { // 'reverse' because the native format for X25519 private keys is little-endian - return implGetPrivateKeyPKCS8("XDH", new PrivateKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), - new DEROctetString(Arrays.reverseInPlace(BigIntegers.asUnsignedByteArray(ecdhK.getX()))))); + return implGeneratePrivate("XDH", () -> getPrivateKeyInfo(EdECObjectIdentifiers.id_X25519, + Arrays.reverseInPlace(BigIntegers.asUnsignedByteArray(((ECSecretBCPGKey)privPk).getX())))); + } + // Legacy X448 (1.3.101.111) + else if (EdECObjectIdentifiers.id_X448.equals(ecdhPub.getCurveOID())) + { + // 'reverse' because the native format for X448 private keys is little-endian (?) + return implGeneratePrivate("XDH", () -> getPrivateKeyInfo(EdECObjectIdentifiers.id_X448, + Arrays.reverseInPlace(BigIntegers.asUnsignedByteArray(((ECSecretBCPGKey)privPk).getX())))); } + // Brainpool, NIST etc. else { return implGetPrivateKeyEC("ECDH", ecdhPub, ecdhK); } } - + // Modern X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) + case PublicKeyAlgorithmTags.X25519: + { + return implGeneratePrivate("XDH", () -> getPrivateKeyInfo(EdECObjectIdentifiers.id_X25519, + X25519SecretBCPGKey.LENGTH, privPk.getEncoded())); + } + // Modern X448 (1.3.101.111) + case PublicKeyAlgorithmTags.X448: + { + return implGeneratePrivate("XDH", () -> getPrivateKeyInfo(EdECObjectIdentifiers.id_X448, + X448SecretBCPGKey.LENGTH, privPk.getEncoded())); + } case PublicKeyAlgorithmTags.ECDSA: - return implGetPrivateKeyEC("ECDSA", (ECDSAPublicBCPGKey)pubPk.getKey(), (ECSecretBCPGKey)privPk); - + { + return implGetPrivateKeyEC("EC", (ECDSAPublicBCPGKey)pubPk.getKey(), (ECSecretBCPGKey)privPk); + } + // Legacy EdDSA (legacy Ed448, legacy Ed25519) case PublicKeyAlgorithmTags.EDDSA_LEGACY: { - EdSecretBCPGKey eddsaK = (EdSecretBCPGKey)privPk; - - return implGetPrivateKeyPKCS8("EdDSA", new PrivateKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), - new DEROctetString(BigIntegers.asUnsignedByteArray(Ed25519.SECRET_KEY_SIZE, eddsaK.getX())))); + EdDSAPublicBCPGKey eddsaPub = (EdDSAPublicBCPGKey) pubPk.getKey(); + // Legacy Ed448 (1.3.101.113) + if (EdECObjectIdentifiers.id_Ed448.equals(eddsaPub.getCurveOID())) + { + return implGeneratePrivate("EdDSA", () -> getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed448, + BigIntegers.asUnsignedByteArray(Ed448.SECRET_KEY_SIZE, ((EdSecretBCPGKey)privPk).getX()))); + } + // Legacy Ed25519 + // 1.3.6.1.4.1.11591.15.1 & 1.3.101.112 + return implGeneratePrivate("EdDSA", () -> getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed25519, + BigIntegers.asUnsignedByteArray(Ed25519.SECRET_KEY_SIZE, ((EdSecretBCPGKey)privPk).getX()))); + } + // Modern Ed25519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) + case PublicKeyAlgorithmTags.Ed25519: + { + return implGeneratePrivate("EdDSA", () -> getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed25519, + Ed25519SecretBCPGKey.LENGTH, privPk.getEncoded())); + } + // Modern Ed448 (1.3.101.113) + case PublicKeyAlgorithmTags.Ed448: + { + return implGeneratePrivate("EdDSA", () -> getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed448, + Ed448SecretBCPGKey.LENGTH, privPk.getEncoded())); } - case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: { @@ -268,46 +358,65 @@ public PublicKey getPublicKey(PGPPublicKey publicKey) { ECDHPublicBCPGKey ecdhK = (ECDHPublicBCPGKey)publicPk.getKey(); - if (ecdhK.getCurveOID().equals(CryptlibObjectIdentifiers.curvey25519)) + // Legacy XDH on Curve25519 (legacy X25519) + // 1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110 + if (JcaJcePGPUtil.isX25519(ecdhK.getCurveOID())) { - byte[] pEnc = BigIntegers.asUnsignedByteArray(ecdhK.getEncodedPoint()); - - // skip the 0x40 header byte. - if (pEnc.length < 1 || 0x40 != pEnc[0]) - { - throw new IllegalArgumentException("Invalid Curve25519 public key"); - } - - return implGetPublicKeyX509("XDH", new SubjectPublicKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), - Arrays.copyOfRange(pEnc, 1, pEnc.length))); + return get25519PublicKey(ecdhK.getEncodedPoint(), EdECObjectIdentifiers.id_X25519, "XDH", "Curve"); + } + // Legacy X448 (1.3.101.111) + else if (ecdhK.getCurveOID().equals(EdECObjectIdentifiers.id_X448)) + { + return get448PublicKey(ecdhK.getEncodedPoint(), EdECObjectIdentifiers.id_X448, "XDH", "Curve"); } + // Brainpool, NIST etc. else { return implGetPublicKeyEC("ECDH", ecdhK); } } - + // Modern X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) + case PublicKeyAlgorithmTags.X25519: + { + return implGetPublicKeyX509(publicPk.getKey().getEncoded(), 0, EdECObjectIdentifiers.id_X25519, "XDH"); + } + // Modern X448 (1.3.101.111) + case PublicKeyAlgorithmTags.X448: + { + return implGetPublicKeyX509(publicPk.getKey().getEncoded(), 0, EdECObjectIdentifiers.id_X448, "XDH"); + } case PublicKeyAlgorithmTags.ECDSA: - return implGetPublicKeyEC("ECDSA", (ECDSAPublicBCPGKey)publicPk.getKey()); - + { + return implGetPublicKeyEC("EC", (ECDSAPublicBCPGKey) publicPk.getKey()); + } + // Legacy EdDSA (legacy Ed448, legacy Ed25519) case PublicKeyAlgorithmTags.EDDSA_LEGACY: { - EdDSAPublicBCPGKey eddsaK = (EdDSAPublicBCPGKey)publicPk.getKey(); - - byte[] pEnc = BigIntegers.asUnsignedByteArray(eddsaK.getEncodedPoint()); - - // skip the 0x40 header byte. - if (pEnc.length < 1 || 0x40 != pEnc[0]) + EdDSAPublicBCPGKey eddsaKey = (EdDSAPublicBCPGKey) publicPk.getKey(); + // Legacy Ed448 (1.3.101.113) + if (EdECObjectIdentifiers.id_Ed448.equals(eddsaKey.getCurveOID())) { - throw new IllegalArgumentException("Invalid Ed25519 public key"); + return get448PublicKey(eddsaKey.getEncodedPoint(), EdECObjectIdentifiers.id_Ed448, "EdDSA", "Ed"); + } + // Legacy Ed25519 + // 1.3.6.1.4.1.11591.15.1 & 1.3.101.112 + else + { + return get25519PublicKey(eddsaKey.getEncodedPoint(), EdECObjectIdentifiers.id_Ed25519, "EdDSA", "Ed"); } - - return implGetPublicKeyX509("EdDSA", new SubjectPublicKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), - Arrays.copyOfRange(pEnc, 1, pEnc.length))); } - + // Modern Ed25519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) + case PublicKeyAlgorithmTags.Ed25519: + { + return implGetPublicKeyX509(publicPk.getKey().getEncoded(), + 0, EdECObjectIdentifiers.id_Ed25519, "EdDSA"); + } + // Modern Ed448 (1.3.101.113) + case PublicKeyAlgorithmTags.Ed448: + { + return implGetPublicKeyX509(publicPk.getKey().getEncoded(), + 0, EdECObjectIdentifiers.id_Ed448, "EdDSA"); + } case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: { @@ -340,21 +449,30 @@ public PublicKey getPublicKey(PGPPublicKey publicKey) } private ECParameterSpec getECParameterSpec(ASN1ObjectIdentifier curveOid) - throws NoSuchAlgorithmException, NoSuchProviderException, InvalidParameterSpecException - { - return getECParameterSpec(curveOid, JcaJcePGPUtil.getX9Parameters(curveOid)); - } - - private ECParameterSpec getECParameterSpec(ASN1ObjectIdentifier curveOid, X9ECParameters x9Params) - throws InvalidParameterSpecException, NoSuchProviderException, NoSuchAlgorithmException + throws IOException, GeneralSecurityException { AlgorithmParameters params = helper.createAlgorithmParameters("EC"); - params.init(new ECGenParameterSpec(ECNamedCurveTable.getName(curveOid))); + params.init(new X962Parameters(curveOid).getEncoded()); return params.getParameterSpec(ECParameterSpec.class); } + private BCPGKey getPrivateBCPGKey(PrivateKey privKey, BCPGKeyOperation operation) + throws PGPException + { + PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(privKey.getEncoded()); + + try + { + return operation.getBCPGKey(ASN1OctetString.getInstance(pInfo.parsePrivateKey()).getOctets()); + } + catch (IOException e) + { + throw new PGPException(e.getMessage(), e); + } + } + private BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) throws PGPException { @@ -375,49 +493,45 @@ private BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) } else { - PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(privKey.getEncoded()); - - try - { - // 'reverse' because the native format for X25519 private keys is little-endian - return new ECSecretBCPGKey(new BigInteger(1, - Arrays.reverse(ASN1OctetString.getInstance(pInfo.parsePrivateKey()).getOctets()))); - } - catch (IOException e) - { - throw new PGPException(e.getMessage(), e); - } + // 'reverse' because the native format for X25519,X448 private keys is little-endian + return getPrivateBCPGKey(privKey, (pInfoEncoded) -> new ECSecretBCPGKey(new BigInteger(1, Arrays.reverse(pInfoEncoded)))); } } - + // Modern X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) + case PublicKeyAlgorithmTags.X25519: + { + return getPrivateBCPGKey(privKey, (pInfoEncoded) -> new X25519SecretBCPGKey(pInfoEncoded)); + } + // Modern X448 (1.3.101.111) + case PublicKeyAlgorithmTags.X448: + { + return getPrivateBCPGKey(privKey, (pInfoEncoded) -> new X448SecretBCPGKey(pInfoEncoded)); + } case PublicKeyAlgorithmTags.ECDSA: { - ECPrivateKey ecK = (ECPrivateKey)privKey; - return new ECSecretBCPGKey(ecK.getS()); + return new ECSecretBCPGKey(((ECPrivateKey)privKey).getS()); } - + // Legacy EdDSA (legacy Ed448, legacy Ed25519) case PublicKeyAlgorithmTags.EDDSA_LEGACY: { - PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(privKey.getEncoded()); - - try - { - return new EdSecretBCPGKey( - new BigInteger(1, ASN1OctetString.getInstance(pInfo.parsePrivateKey()).getOctets())); - } - catch (IOException e) - { - throw new PGPException(e.getMessage(), e); - } + return getPrivateBCPGKey(privKey, (pInfoEncoded) -> new EdSecretBCPGKey(new BigInteger(1, pInfoEncoded))); + } + // Modern Ed25519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) + case PublicKeyAlgorithmTags.Ed25519: + { + return getPrivateBCPGKey(privKey, Ed25519SecretBCPGKey::new); + } + // Modern Ed448 (1.3.101.113) + case PublicKeyAlgorithmTags.Ed448: + { + return getPrivateBCPGKey(privKey, Ed448SecretBCPGKey::new); } - case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: { DHPrivateKey esK = (DHPrivateKey)privKey; return new ElGamalSecretBCPGKey(esK.getX()); } - case PublicKeyAlgorithmTags.RSA_ENCRYPT: case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: @@ -425,87 +539,250 @@ private BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) RSAPrivateCrtKey rsK = (RSAPrivateCrtKey)privKey; return new RSASecretBCPGKey(rsK.getPrivateExponent(), rsK.getPrimeP(), rsK.getPrimeQ()); } - default: - throw new PGPException("unknown key class"); + throw new PGPException("unknown public key algorithm encountered: " + pub.getAlgorithm()); } } - private BCPGKey getPublicBCPGKey(int algorithm, PGPAlgorithmParameters algorithmParameters, PublicKey pubKey, Date time) + private BCPGKey getPublicBCPGKey(int algorithm, PGPAlgorithmParameters algorithmParameters, PublicKey pubKey) throws PGPException { - if (pubKey instanceof RSAPublicKey) + switch (algorithm) { - RSAPublicKey rK = (RSAPublicKey)pubKey; - return new RSAPublicBCPGKey(rK.getModulus(), rK.getPublicExponent()); - } - else if (pubKey instanceof DSAPublicKey) - { - DSAPublicKey dK = (DSAPublicKey)pubKey; - DSAParams dP = dK.getParams(); - return new DSAPublicBCPGKey(dP.getP(), dP.getQ(), dP.getG(), dK.getY()); - } - else if (pubKey instanceof DHPublicKey) - { - DHPublicKey eK = (DHPublicKey)pubKey; - DHParameterSpec eS = eK.getParams(); - return new ElGamalPublicBCPGKey(eS.getP(), eS.getG(), eK.getY()); - } - else if (pubKey instanceof ECPublicKey) - { - SubjectPublicKeyInfo keyInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()); + case PublicKeyAlgorithmTags.RSA_GENERAL: + case PublicKeyAlgorithmTags.RSA_ENCRYPT: + case PublicKeyAlgorithmTags.RSA_SIGN: + { + RSAPublicKey rK = (RSAPublicKey) pubKey; + return new RSAPublicBCPGKey(rK.getModulus(), rK.getPublicExponent()); + } + case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: + case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: + { + DHPublicKey egK = (DHPublicKey) pubKey; + return new ElGamalPublicBCPGKey(egK.getParams().getP(), egK.getParams().getG(), egK.getY()); + } + case PublicKeyAlgorithmTags.DSA: + { + DSAPublicKey dK = (DSAPublicKey) pubKey; + DSAParams dP = dK.getParams(); + return new DSAPublicBCPGKey(dP.getP(), dP.getQ(), dP.getG(), dK.getY()); + } + + case PublicKeyAlgorithmTags.DIFFIE_HELLMAN: + { + DHPublicKey eK = (DHPublicKey) pubKey; + DHParameterSpec eS = eK.getParams(); + return new ElGamalPublicBCPGKey(eS.getP(), eS.getG(), eK.getY()); + } + + case PublicKeyAlgorithmTags.ECDH: + case PublicKeyAlgorithmTags.ECDSA: + { + SubjectPublicKeyInfo keyInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()); + + // TODO: should probably match curve by comparison as well + ASN1Encodable enc = keyInfo.getAlgorithm().getAlgorithm(); + ASN1ObjectIdentifier curveOid; + curveOid = ASN1ObjectIdentifier.getInstance(enc); + + // BCECPublicKey uses explicit parameter encoding, so we need to find the named curve manually + if (X9ObjectIdentifiers.id_ecPublicKey.equals(curveOid)) + { + enc = getNamedCurveOID(X962Parameters.getInstance(keyInfo.getAlgorithm().getParameters())); + ASN1ObjectIdentifier nCurveOid = ASN1ObjectIdentifier.getInstance(enc); + if (nCurveOid != null) + { + curveOid = nCurveOid; + } + } - // TODO: should probably match curve by comparison as well - ASN1ObjectIdentifier curveOid = ASN1ObjectIdentifier.getInstance(keyInfo.getAlgorithm().getParameters()); + // Legacy XDH on Curve25519 (legacy X25519) + // 1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110 + if (pubKey.getAlgorithm().regionMatches(true, 0, "X2", 0, 2)) + { + PGPKdfParameters kdfParams = implGetKdfParameters(CryptlibObjectIdentifiers.curvey25519, algorithmParameters); + + return new ECDHPublicBCPGKey(CryptlibObjectIdentifiers.curvey25519, new BigInteger(1, getPointEncUncompressed(pubKey, X25519.SCALAR_SIZE)), + kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); + } + // Legacy X448 (1.3.101.111) + if (pubKey.getAlgorithm().regionMatches(true, 0, "X4", 0, 2)) + { + + PGPKdfParameters kdfParams = implGetKdfParameters(EdECObjectIdentifiers.id_X448, algorithmParameters); + + return new ECDHPublicBCPGKey(EdECObjectIdentifiers.id_X448, new BigInteger(1, getPointEncUncompressed(pubKey, X448.SCALAR_SIZE)), + kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); + } + // sun.security.ec.XDHPublicKeyImpl returns "XDH" for getAlgorithm() + // In this case we need to determine the curve by looking at the length of the encoding :/ + else if (pubKey.getAlgorithm().regionMatches(true, 0, "XDH", 0, 3)) + { + // Legacy X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) + if (X25519.SCALAR_SIZE + 12 == pubKey.getEncoded().length) // + 12 for some reason + { + PGPKdfParameters kdfParams = implGetKdfParameters(CryptlibObjectIdentifiers.curvey25519, algorithmParameters); + + return new ECDHPublicBCPGKey(CryptlibObjectIdentifiers.curvey25519, new BigInteger(1, getPointEncUncompressed(pubKey, X25519.SCALAR_SIZE)), + kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); + } + // Legacy X448 (1.3.101.111) + else + { + PGPKdfParameters kdfParams = implGetKdfParameters(EdECObjectIdentifiers.id_X448, algorithmParameters); + + return new ECDHPublicBCPGKey(EdECObjectIdentifiers.id_X448, new BigInteger(1, getPointEncUncompressed(pubKey, X448.SCALAR_SIZE)), + kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); + } + } - X9ECParametersHolder params = ECNamedCurveTable.getByOIDLazy(curveOid); + X9ECParametersHolder params = ECNamedCurveTable.getByOIDLazy(curveOid); - ASN1OctetString key = new DEROctetString(keyInfo.getPublicKeyData().getBytes()); - X9ECPoint derQ = new X9ECPoint(params.getCurve(), key); + ASN1OctetString key = new DEROctetString(keyInfo.getPublicKeyData().getBytes()); + X9ECPoint derQ = new X9ECPoint(params.getCurve(), key); - if (algorithm == PGPPublicKey.ECDH) + if (algorithm == PGPPublicKey.ECDH) + { + + PGPKdfParameters kdfParams = implGetKdfParameters(curveOid, algorithmParameters); + + return new ECDHPublicBCPGKey(curveOid, derQ.getPoint(), kdfParams.getHashAlgorithm(), + kdfParams.getSymmetricWrapAlgorithm()); + } + else + { + return new ECDSAPublicBCPGKey(curveOid, derQ.getPoint()); + } + } + + case PublicKeyAlgorithmTags.EDDSA_LEGACY: { - PGPKdfParameters kdfParams = implGetKdfParameters(algorithmParameters); + // Legacy Ed25519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) + if (pubKey.getAlgorithm().regionMatches(true, 0, "ED2", 0, 3)) + { + return new EdDSAPublicBCPGKey(GNUObjectIdentifiers.Ed25519, new BigInteger(1, getPointEncUncompressed(pubKey, Ed25519.PUBLIC_KEY_SIZE))); + } + // Legacy Ed448 (1.3.101.113) + if (pubKey.getAlgorithm().regionMatches(true, 0, "ED4", 0, 3)) + { + return new EdDSAPublicBCPGKey(EdECObjectIdentifiers.id_Ed448, new BigInteger(1, getPointEncUncompressed(pubKey, Ed448.PUBLIC_KEY_SIZE))); + } + // Manual matching on curve encoding length + else + { + // sun.security.ec.ed.EdDSAPublicKeyImpl returns "EdDSA" for getAlgorithm() + // if algorithm is just EdDSA, we need to detect the curve based on encoding length :/ + if (pubKey.getEncoded().length == 12 + Ed25519.PUBLIC_KEY_SIZE) // +12 for some reason + { + // Legacy Ed25519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) + return new EdDSAPublicBCPGKey(GNUObjectIdentifiers.Ed25519, new BigInteger(1, getPointEncUncompressed(pubKey, Ed25519.PUBLIC_KEY_SIZE))); + } + else + { + // Legacy Ed448 (1.3.101.113) + return new EdDSAPublicBCPGKey(EdECObjectIdentifiers.id_Ed448, new BigInteger(1, getPointEncUncompressed(pubKey, Ed448.PUBLIC_KEY_SIZE))); + } + } + } - return new ECDHPublicBCPGKey(curveOid, derQ.getPoint(), kdfParams.getHashAlgorithm(), - kdfParams.getSymmetricWrapAlgorithm()); + // Modern Ed25519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) + case PublicKeyAlgorithmTags.Ed25519: + { + return getPublicBCPGKey(pubKey, Ed25519PublicBCPGKey.LENGTH, Ed25519PublicBCPGKey::new); } - else if (algorithm == PGPPublicKey.ECDSA) + + // Modern Ed448 (1.3.101.113) + case PublicKeyAlgorithmTags.Ed448: { - return new ECDSAPublicBCPGKey(curveOid, derQ.getPoint()); + return getPublicBCPGKey(pubKey, Ed448PublicBCPGKey.LENGTH, Ed448PublicBCPGKey::new); } - else + + // Modern X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) + case PublicKeyAlgorithmTags.X25519: { - throw new PGPException("unknown EC algorithm"); + return getPublicBCPGKey(pubKey, X25519PublicBCPGKey.LENGTH, X25519PublicBCPGKey::new); + } + // Modern X448 (1.3.101.111) + case PublicKeyAlgorithmTags.X448: + { + return getPublicBCPGKey(pubKey, X448PublicBCPGKey.LENGTH, X448PublicBCPGKey::new); } - } - else if (pubKey.getAlgorithm().regionMatches(true, 0, "ED2", 0, 3)) - { - SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()); - byte[] pointEnc = new byte[1 + ED25519_KEY_SIZE]; - pointEnc[0] = 0x40; - System.arraycopy(pubInfo.getPublicKeyData().getBytes(), 0, pointEnc, 1, pointEnc.length - 1); + default: + throw new PGPException("unknown public key algorithm encountered: " + algorithm); + } + } - return new EdDSAPublicBCPGKey(GNUObjectIdentifiers.Ed25519, new BigInteger(1, pointEnc)); + private ASN1Encodable getNamedCurveOID(X962Parameters ecParams) + { + ECCurve curve = null; + if (ecParams.isNamedCurve()) + { + return ASN1ObjectIdentifier.getInstance(ecParams.getParameters()); } - else if (pubKey.getAlgorithm().regionMatches(true, 0, "X2", 0, 2)) + else if (ecParams.isImplicitlyCA()) { - SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()); - byte[] pointEnc = new byte[1 + X25519_KEY_SIZE]; - - pointEnc[0] = 0x40; - System.arraycopy(pubInfo.getPublicKeyData().getBytes(), 0, pointEnc, 1, pointEnc.length - 1); - - PGPKdfParameters kdfParams = implGetKdfParameters(algorithmParameters); - - return new ECDHPublicBCPGKey(CryptlibObjectIdentifiers.curvey25519, new BigInteger(1, pointEnc), - kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); + curve = ((X9ECParameters)CryptoServicesRegistrar.getProperty(CryptoServicesRegistrar.Property.EC_IMPLICITLY_CA)).getCurve(); } else { - throw new PGPException("unknown key class"); + curve = X9ECParameters.getInstance(ecParams.getParameters()).getCurve(); } + + // Iterate through all registered curves to find applicable OID + Enumeration names = ECNamedCurveTable.getNames(); + while (names.hasMoreElements()) + { + String name = (String)names.nextElement(); + X9ECParameters parms = ECNamedCurveTable.getByName(name); + if (curve.equals(parms.getCurve())) + { + return ECNamedCurveTable.getOID(name); + } + } + return null; + } + + @FunctionalInterface + private interface BCPGKeyOperation + { + BCPGKey getBCPGKey(byte[] key); + } + + private BCPGKey getPublicBCPGKey(PublicKey pubKey, int keySize, BCPGKeyOperation operation) + { + byte[] pubInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()).getPublicKeyData().getBytes(); + byte[] pointEnc = new byte[keySize]; + // refer to getPointEncUncompressed + System.arraycopy(pubInfo, 0, pointEnc, pointEnc.length - pubInfo.length , pubInfo.length); + return operation.getBCPGKey(pointEnc); + } + + private byte[] getPointEncUncompressed(PublicKey pubKey, int publicKeySize) + { + byte[] pubInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()).getPublicKeyData().getBytes(); + byte[] pointEnc = new byte[1 + publicKeySize]; + + pointEnc[0] = 0x40; + //offset with pointEnc.length - pubInfo.length to avoid leading zero issue + System.arraycopy(pubInfo, 0, pointEnc, pointEnc.length - pubInfo.length , pubInfo.length); + return pointEnc; + } + + @FunctionalInterface + private interface Operation + { + PrivateKeyInfo getPrivateKeyInfo() + throws IOException; + } + + private PrivateKey implGeneratePrivate(String keyAlgorithm, Operation operation) + throws GeneralSecurityException, PGPException, IOException + { + PKCS8EncodedKeySpec pkcs8Spec = new PKCS8EncodedKeySpec(operation.getPrivateKeyInfo().getEncoded()); + KeyFactory keyFactory = helper.createKeyFactory(keyAlgorithm); + return keyFactory.generatePrivate(pkcs8Spec); } private PrivateKey implGeneratePrivate(String keyAlgorithm, KeySpec keySpec) @@ -522,26 +799,23 @@ private PublicKey implGeneratePublic(String keyAlgorithm, KeySpec keySpec) return keyFactory.generatePublic(keySpec); } - private PGPKdfParameters implGetKdfParameters(PGPAlgorithmParameters algorithmParameters) + private PublicKey implGetPublicKeyX509(byte[] pEnc, int pEncOff, ASN1ObjectIdentifier algorithm, String keyAlgorithm) + throws IOException, PGPException, GeneralSecurityException { - return null == algorithmParameters ? DEFAULT_KDF_PARAMETERS : (PGPKdfParameters)algorithmParameters; + return implGeneratePublic(keyAlgorithm, new X509EncodedKeySpec(new SubjectPublicKeyInfo( + new AlgorithmIdentifier(algorithm), Arrays.copyOfRange(pEnc, pEncOff, pEnc.length)).getEncoded())); } private PrivateKey implGetPrivateKeyEC(String keyAlgorithm, ECPublicBCPGKey ecPub, ECSecretBCPGKey ecPriv) - throws GeneralSecurityException, PGPException + throws GeneralSecurityException, PGPException, IOException { - ECPrivateKeySpec ecPrivSpec = new ECPrivateKeySpec(ecPriv.getX(), getECParameterSpec(ecPub.getCurveOID())); + ASN1ObjectIdentifier curveOid = ecPub.getCurveOID(); + ECPrivateKeySpec ecPrivSpec = new ECPrivateKeySpec(ecPriv.getX(), getECParameterSpec(curveOid)); return implGeneratePrivate(keyAlgorithm, ecPrivSpec); } - private PrivateKey implGetPrivateKeyPKCS8(String keyAlgorithm, PrivateKeyInfo privateKeyInfo) + private PublicKey implGetPublicKeyEC(String keyAlgorithm, ECPublicBCPGKey ecPub) throws GeneralSecurityException, IOException, PGPException - { - PKCS8EncodedKeySpec pkcs8Spec = new PKCS8EncodedKeySpec(privateKeyInfo.getEncoded()); - return implGeneratePrivate(keyAlgorithm, pkcs8Spec); - } - - private PublicKey implGetPublicKeyEC(String keyAlgorithm, ECPublicBCPGKey ecPub) throws GeneralSecurityException, IOException, PGPException { ASN1ObjectIdentifier curveOID = ecPub.getCurveOID(); X9ECParameters x9Params = JcaJcePGPUtil.getX9Parameters(curveOID); @@ -550,14 +824,33 @@ private PublicKey implGetPublicKeyEC(String keyAlgorithm, ECPublicBCPGKey ecPub) new java.security.spec.ECPoint( ecPubPoint.getAffineXCoord().toBigInteger(), ecPubPoint.getAffineYCoord().toBigInteger()), - getECParameterSpec(curveOID, x9Params)); + getECParameterSpec(curveOID)); return implGeneratePublic(keyAlgorithm, ecPubSpec); } - private PublicKey implGetPublicKeyX509(String keyAlgorithm, SubjectPublicKeyInfo subjectPublicKeyInfo) - throws GeneralSecurityException, IOException, PGPException + private PublicKey get25519PublicKey(BigInteger x, ASN1ObjectIdentifier algorithm, String keyAlgorithm, String name) + throws PGPException, GeneralSecurityException, IOException + { + byte[] pEnc = BigIntegers.asUnsignedByteArray(x); + + // skip the 0x40 header byte. + if (pEnc.length < 1 || 0x40 != pEnc[0]) + { + throw new IllegalArgumentException("Invalid " + name + "25519 public key"); + } + return implGetPublicKeyX509(pEnc, 1, algorithm, keyAlgorithm); + } + + private PublicKey get448PublicKey(BigInteger x, ASN1ObjectIdentifier algorithm, String keyAlgorithm, String name) + throws PGPException, GeneralSecurityException, IOException { - X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(subjectPublicKeyInfo.getEncoded()); - return implGeneratePublic(keyAlgorithm, x509Spec); + byte[] pEnc = BigIntegers.asUnsignedByteArray(x); + + // skip the 0x40 header byte. + if (pEnc.length < 1 || 0x40 != pEnc[0]) + { + throw new IllegalArgumentException("Invalid " + name + "448 public key"); + } + return implGetPublicKeyX509(pEnc, 1, algorithm, keyAlgorithm); } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyPair.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyPair.java index 6bf5d3dfc2..86f8f8d75c 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyPair.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyPair.java @@ -5,6 +5,7 @@ import java.security.PublicKey; import java.util.Date; +import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.openpgp.PGPAlgorithmParameters; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; @@ -17,16 +18,30 @@ public class JcaPGPKeyPair extends PGPKeyPair { + @Deprecated private static PGPPublicKey getPublicKey(int algorithm, PublicKey pubKey, Date date) throws PGPException { - return new JcaPGPKeyConverter().getPGPPublicKey(algorithm, pubKey, date); + return getPublicKey(PublicKeyPacket.VERSION_4, algorithm, pubKey, date); } + private static PGPPublicKey getPublicKey(int version, int algorithm, PublicKey pubKey, Date date) + throws PGPException + { + return new JcaPGPKeyConverter().getPGPPublicKey(version, algorithm, pubKey, date); + } + + @Deprecated private static PGPPublicKey getPublicKey(int algorithm, PGPAlgorithmParameters algorithmParameters, PublicKey pubKey, Date date) throws PGPException { - return new JcaPGPKeyConverter().getPGPPublicKey(algorithm, algorithmParameters, pubKey, date); + return getPublicKey(PublicKeyPacket.VERSION_4, algorithm, algorithmParameters, pubKey, date); + } + + private static PGPPublicKey getPublicKey(int version, int algorithm, PGPAlgorithmParameters algorithmParameters, PublicKey pubKey, Date date) + throws PGPException + { + return new JcaPGPKeyConverter().getPGPPublicKey(version, algorithm, algorithmParameters, pubKey, date); } private static PGPPrivateKey getPrivateKey(PGPPublicKey pub, PrivateKey privKey) @@ -36,33 +51,68 @@ private static PGPPrivateKey getPrivateKey(PGPPublicKey pub, PrivateKey privKey) } /** - * Construct PGP key pair from a JCA/JCE key pair. + * Construct version 4 PGP key pair from a JCA/JCE key pair. * * @param algorithm the PGP algorithm the key is for. * @param keyPair the public/private key pair to convert. * @param date the creation date to associate with the key pair. * @throws PGPException if conversion fails. + * @deprecated use versioned {@link #JcaPGPKeyPair(int, int, KeyPair, Date)} instead */ + @Deprecated public JcaPGPKeyPair(int algorithm, KeyPair keyPair, Date date) throws PGPException { - this.pub = getPublicKey(algorithm, keyPair.getPublic(), date); - this.priv = getPrivateKey(this.pub, keyPair.getPrivate()); + this(PublicKeyPacket.VERSION_4, algorithm, keyPair, date); } /** * Construct PGP key pair from a JCA/JCE key pair. * + * @param version key version. + * @param algorithm the PGP algorithm the key is for. + * @param keyPair the public/private key pair to convert. + * @param date the creation date to associate with the key pair. + * @throws PGPException if conversion fails. + */ + public JcaPGPKeyPair(int version, int algorithm, KeyPair keyPair, Date date) + throws PGPException + { + this.pub = getPublicKey(version, algorithm, keyPair.getPublic(), date); + this.priv = getPrivateKey(this.pub, keyPair.getPrivate()); + } + + /** + * Construct version 4 PGP key pair from a JCA/JCE key pair. + * * @param algorithm the PGP algorithm the key is for. * @param parameters additional parameters to be stored against the public key. * @param keyPair the public/private key pair to convert. * @param date the creation date to associate with the key pair. * @throws PGPException if conversion fails. + * @deprecated use versioned {@link #JcaPGPKeyPair(int, int, PGPAlgorithmParameters, KeyPair, Date)} instead */ + @Deprecated public JcaPGPKeyPair(int algorithm, PGPAlgorithmParameters parameters, KeyPair keyPair, Date date) throws PGPException { - this.pub = getPublicKey(algorithm, parameters, keyPair.getPublic(), date); + this(PublicKeyPacket.VERSION_4, algorithm, parameters, keyPair, date); + } + + /** + * Construct PGP key pair from a JCA/JCE key pair. + * + * @param version key version. + * @param algorithm the PGP algorithm the key is for. + * @param parameters additional parameters to be stored against the public key. + * @param keyPair the public/private key pair to convert. + * @param date the creation date to associate with the key pair. + * @throws PGPException if conversion fails. + */ + public JcaPGPKeyPair(int version, int algorithm, PGPAlgorithmParameters parameters, KeyPair keyPair, Date date) + throws PGPException + { + this.pub = getPublicKey(version, algorithm, parameters, keyPair.getPublic(), date); this.priv = getPrivateKey(this.pub, keyPair.getPrivate()); } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceAEADCipherUtil.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceAEADCipherUtil.java new file mode 100644 index 0000000000..0ebe601a36 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceAEADCipherUtil.java @@ -0,0 +1,85 @@ +package org.bouncycastle.openpgp.operator.jcajce; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.InvalidParameterSpecException; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.jcajce.provider.symmetric.util.GcmSpecUtil; +import org.bouncycastle.jcajce.spec.AEADParameterSpec; +import org.bouncycastle.util.Arrays; + +public class JceAEADCipherUtil +{ + static void setUpAeadCipher(Cipher aead, SecretKey secretKey, int mode, byte[] nonce, int aeadMacLen, byte[] aad) + throws InvalidKeyException, InvalidAlgorithmParameterException + { + if (GcmSpecUtil.gcmSpecExtractable()) + { + AlgorithmParameterSpec parameters; + try + { + parameters = GcmSpecUtil.extractGcmSpec(new GCMParameters(nonce, (aeadMacLen + 7) / 8).toASN1Primitive()); + } + catch (InvalidParameterSpecException e) + { + throw new InvalidAlgorithmParameterException(e.getMessage()); + } + aead.init(mode, secretKey, parameters); + aead.updateAAD(aad); + } + else + { + AEADParameterSpec parameters = new AEADParameterSpec(nonce, aeadMacLen, aad); + aead.init(mode, secretKey, parameters); + } + } + + static class GCMParameters + extends ASN1Object + { + private byte[] nonce; + private int icvLen; + + public GCMParameters( + byte[] nonce, + int icvLen) + { + this.nonce = Arrays.clone(nonce); + this.icvLen = icvLen; + } + + public byte[] getNonce() + { + return Arrays.clone(nonce); + } + + public int getIcvLen() + { + return icvLen; + } + + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(2); + + v.add(new DEROctetString(nonce)); + + if (icvLen != 12) + { + v.add(new ASN1Integer(icvLen)); + } + + return new DERSequence(v); + } + } +} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceAEADUtil.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceAEADUtil.java new file mode 100644 index 0000000000..6e76199ef6 --- /dev/null +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceAEADUtil.java @@ -0,0 +1,674 @@ +package org.bouncycastle.openpgp.operator.jcajce; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.GeneralSecurityException; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import org.bouncycastle.bcpg.AEADAlgorithmTags; +import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.AEADUtils; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyUtils; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.params.HKDFParameters; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPSessionKey; +import org.bouncycastle.openpgp.PGPUtil; +import org.bouncycastle.openpgp.operator.PGPDataDecryptor; +import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Exceptions; +import org.bouncycastle.util.Pack; +import org.bouncycastle.util.io.Streams; + +class JceAEADUtil +{ + private final OperatorHelper helper; + + public JceAEADUtil(OperatorHelper helper) + { + this.helper = helper; + } + + /** + * Generate a nonce by xor-ing the given iv with the chunk index. + * + * @param iv initialization vector + * @param chunkIndex chunk index + * @return nonce + */ + protected static byte[] getNonce(byte[] iv, long chunkIndex) + { + byte[] nonce = Arrays.clone(iv); + + xorChunkId(nonce, chunkIndex); + + return nonce; + } + + /** + * XOR the byte array with the chunk index in-place. + * + * @param nonce byte array + * @param chunkIndex chunk index + */ + protected static void xorChunkId(byte[] nonce, long chunkIndex) + { + int index = nonce.length - 8; + + nonce[index++] ^= (byte)(chunkIndex >> 56); + nonce[index++] ^= (byte)(chunkIndex >> 48); + nonce[index++] ^= (byte)(chunkIndex >> 40); + nonce[index++] ^= (byte)(chunkIndex >> 32); + nonce[index++] ^= (byte)(chunkIndex >> 24); + nonce[index++] ^= (byte)(chunkIndex >> 16); + nonce[index++] ^= (byte)(chunkIndex >> 8); + nonce[index] ^= (byte)(chunkIndex); + } + + /** + * Calculate an actual chunk length from the encoded chunk size. + * + * @param chunkSize encoded chunk size + * @return decoded length + */ + protected static long getChunkLength(int chunkSize) + { + return 1L << (chunkSize + 6); + } + + /** + * Derive a message key and IV from the given session key. + * The result is two byte arrays containing the key bytes and the IV. + * + * @param aeadAlgo AEAD algorithm + * @param cipherAlgo symmetric cipher algorithm + * @param sessionKey session key + * @param salt salt + * @param hkdfInfo HKDF info + * @return message key and separate IV + * @throws PGPException + */ + static byte[][] deriveMessageKeyAndIv(int aeadAlgo, int cipherAlgo, byte[] sessionKey, byte[] salt, byte[] hkdfInfo) + throws PGPException + { + // TODO: needs to be JCA based. KeyGenerator + int keyLen = SymmetricKeyUtils.getKeyLengthInOctets(cipherAlgo); + int ivLen = AEADUtils.getIVLength(aeadAlgo); + byte[] messageKeyAndIv = generateHKDFBytes(sessionKey, salt, hkdfInfo, keyLen + ivLen - 8); + + return new byte[][]{Arrays.copyOfRange(messageKeyAndIv, 0, keyLen), Arrays.copyOfRange(messageKeyAndIv, keyLen, keyLen + ivLen)}; + } + + static byte[] generateHKDFBytes(byte[] sessionKey, byte[] salt, byte[] hkdfInfo, int len) + { + HKDFParameters hkdfParameters = new HKDFParameters(sessionKey, salt, hkdfInfo); + HKDFBytesGenerator hkdfGen = new HKDFBytesGenerator(new SHA256Digest()); + + hkdfGen.init(hkdfParameters); + byte[] messageKeyAndIv = new byte[len]; + hkdfGen.generateBytes(messageKeyAndIv, 0, messageKeyAndIv.length); + return messageKeyAndIv; + } + + /** + * Create a {@link PGPDataDecryptor} for decrypting AEAD encrypted OpenPGP v5 data packets. + * + * @param aeadEncDataPacket AEAD encrypted data packet + * @param sessionKey session key to decrypt the data + * @return decryptor + * @throws PGPException + */ + PGPDataDecryptor createOpenPgpV5DataDecryptor(AEADEncDataPacket aeadEncDataPacket, + PGPSessionKey sessionKey) + throws PGPException + { + final int aeadAlgorithm = aeadEncDataPacket.getAEADAlgorithm(); + final byte[] iv = aeadEncDataPacket.getIV(); + final int chunkSize = aeadEncDataPacket.getChunkSize(); + final int encAlgorithm = sessionKey.getAlgorithm(); + final byte[] key = sessionKey.getKey(); + final byte[] aaData = aeadEncDataPacket.getAAData(); + try + { + final SecretKey secretKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); + + final Cipher c = createAEADCipher(encAlgorithm, aeadAlgorithm); + + return new PGPDataDecryptor() + { + public InputStream getInputStream(InputStream in) + { + try + { + return new JceAEADUtil.PGPAeadInputStream(true, in, c, secretKey, iv, encAlgorithm, aeadAlgorithm, chunkSize, aaData); + } + catch (IOException e) + { + throw Exceptions.illegalStateException("unable to open stream: " + e.getMessage(), e); + } + } + + public int getBlockSize() + { + return c.getBlockSize(); + } + + public PGPDigestCalculator getIntegrityCalculator() + { + return new SHA1PGPDigestCalculator(); + } + }; + } + catch (PGPException e) + { + throw e; + } + catch (Exception e) + { + throw new PGPException("Exception creating cipher", e); + } + } + + /** + * Create a {@link PGPDataDecryptor} for decrypting AEAD encrypted OpenPGP v6 data. + * + * @param seipd version 2 SEIPD packet + * @param sessionKey session key to decrypt the data + * @return decryptor + * @throws PGPException + */ + PGPDataDecryptor createOpenPgpV6DataDecryptor(SymmetricEncIntegrityPacket seipd, + PGPSessionKey sessionKey) + throws PGPException + { + final int cipherAlgo = seipd.getCipherAlgorithm(); + final int aeadAlgo = seipd.getAeadAlgorithm(); + final int chunkSize = seipd.getChunkSize(); + final byte[] salt = seipd.getSalt(); + final byte[] aaData = seipd.getAAData(); + + + final byte[][] messageKeyAndIv = deriveMessageKeyAndIv(aeadAlgo, cipherAlgo, sessionKey.getKey(), salt, aaData); + final byte[] messageKey = messageKeyAndIv[0]; + final byte[] iv = messageKeyAndIv[1]; + + try + { + final SecretKey secretKey = new SecretKeySpec(messageKey, PGPUtil.getSymmetricCipherName(cipherAlgo)); + final Cipher c = createAEADCipher(cipherAlgo, aeadAlgo); + + return new PGPDataDecryptor() + { + public InputStream getInputStream(InputStream in) + { + try + { + return new JceAEADUtil.PGPAeadInputStream(false, in, c, secretKey, iv, cipherAlgo, aeadAlgo, chunkSize, aaData); + } + catch (IOException e) + { + throw Exceptions.illegalStateException("unable to open stream: " + e.getMessage(), e); + } + } + + public int getBlockSize() + { + return c.getBlockSize(); + } + + public PGPDigestCalculator getIntegrityCalculator() + { + return new SHA1PGPDigestCalculator(); + } + }; + } + catch (PGPException e) + { + throw e; + } + catch (Exception e) + { + throw new PGPException("Exception creating cipher", e); + } + } + + Cipher createAEADCipher(int encAlgorithm, int aeadAlgorithm) + throws PGPException + { + if (encAlgorithm != SymmetricKeyAlgorithmTags.AES_128 + && encAlgorithm != SymmetricKeyAlgorithmTags.AES_192 + && encAlgorithm != SymmetricKeyAlgorithmTags.AES_256 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_128 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_192 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_256) + { + // Block Cipher must work on 16 byte blocks + throw new PGPException("AEAD only supported for AES and Camellia" + " based algorithms"); + } + + String mode; + switch (aeadAlgorithm) + { + case AEADAlgorithmTags.EAX: + mode = "EAX"; + break; + case AEADAlgorithmTags.OCB: + mode = "OCB"; + break; + case AEADAlgorithmTags.GCM: + mode = "GCM"; + break; + default: + throw new PGPException("encountered unknown AEAD algorithm: " + aeadAlgorithm); + } + + String cName = PGPUtil.getSymmetricCipherName(encAlgorithm) + + "/" + mode + "/NoPadding"; + + return helper.createCipher(cName); + } + + static class PGPAeadInputStream + extends InputStream + { + private final InputStream in; + private final byte[] buf; + private final Cipher c; + private final SecretKey secretKey; + private final byte[] aaData; + private final byte[] iv; + private final int chunkLength; + private final int aeadTagLength; + + private byte[] data; + private int dataOff; + private long chunkIndex = 0; + private long totalBytes = 0; + private boolean v5StyleAEAD; + + /** + * InputStream for decrypting AEAD encrypted data. + * + * @param isV5AEAD AEAD flavour (OpenPGP v5 or v6) + * @param in underlying input stream + * @param c AEAD cipher + * @param secretKey secret key + * @param iv initialization vector + * @param encAlgorithm encryption algorithm + * @param aeadAlgorithm AEAD algorithm + * @param chunkSize chunk size of the AEAD encryption + * @param aaData associated data + * @throws IOException + */ + public PGPAeadInputStream(boolean isV5AEAD, InputStream in, + Cipher c, + SecretKey secretKey, + byte[] iv, + int encAlgorithm, + int aeadAlgorithm, + int chunkSize, + byte[] aaData) + throws IOException + { + this.v5StyleAEAD = isV5AEAD; + this.in = in; + this.iv = iv; + this.chunkLength = (int)getChunkLength(chunkSize); + this.aeadTagLength = AEADUtils.getAuthTagLength(aeadAlgorithm); + this.buf = new byte[chunkLength + aeadTagLength + aeadTagLength]; // allow room for chunk tag and message tag + this.c = c; + this.secretKey = secretKey; + this.aaData = aaData; + + // prime with 2 * tag len bytes. + Streams.readFully(in, buf, 0, aeadTagLength + aeadTagLength); + + // load the first block + this.data = readBlock(); + this.dataOff = 0; + } + + public int read() + throws IOException + { + if (data != null && dataOff == data.length) + { + this.data = readBlock(); + this.dataOff = 0; + } + + if (this.data == null) + { + return -1; + } + + return data[dataOff++] & 0xff; + } + + public int read(byte[] b, int off, int len) + throws IOException + { + if (data != null && dataOff == data.length) + { + this.data = readBlock(); + this.dataOff = 0; + } + + if (this.data == null) + { + return -1; + } + + int supplyLen = Math.min(len, available()); + System.arraycopy(data, dataOff, b, off, supplyLen); + dataOff += supplyLen; + + return supplyLen; + } + + public long skip(long n) + throws IOException + { + if (n <= 0) + { + return 0; + } + + int skip = (int)Math.min(n, available()); + dataOff += skip; + return skip; + } + + public int available() + throws IOException + { + if (data != null && dataOff == data.length) + { + this.data = readBlock(); + this.dataOff = 0; + } + + if (this.data == null) + { + return -1; + } + + return data.length - dataOff; + } + + private byte[] readBlock() + throws IOException + { + // we initialise with the first 16 bytes as there is an additional 16 bytes following + // the last chunk (which may not be the exact chunklength). + int dataLen = Streams.readFully(in, buf, aeadTagLength + aeadTagLength, chunkLength); + if (dataLen == 0) + { + return null; + } + + byte[] adata = new byte[v5StyleAEAD ? 13 : aaData.length]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + if (v5StyleAEAD) + { + xorChunkId(adata, chunkIndex); + } + + byte[] decData; + try + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.DECRYPT_MODE, getNonce(iv, chunkIndex), 128, adata); + + decData = c.doFinal(buf, 0, dataLen + aeadTagLength); + } + catch (GeneralSecurityException e) + { + throw new IOException("exception processing chunk " + chunkIndex + ": " + e.getMessage()); + } + + totalBytes += decData.length; + chunkIndex++; + + System.arraycopy(buf, dataLen + aeadTagLength, buf, 0, aeadTagLength); // copy back the "tag" + + if (dataLen != chunkLength) // it's our last block + { + adata = PGPAeadOutputStream.getAdata(v5StyleAEAD, aaData, chunkIndex, totalBytes); + try + { + if (v5StyleAEAD) + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.DECRYPT_MODE, getNonce(iv, chunkIndex), 128, Arrays.concatenate(adata, Pack.longToBigEndian(totalBytes))); + } + else + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.DECRYPT_MODE, getNonce(iv, chunkIndex), 128, adata); + } + + c.doFinal(buf, 0, aeadTagLength); // check final tag + } + catch (GeneralSecurityException e) + { + throw new IOException("exception processing final tag: " + e.getMessage()); + } + } + else + { + Streams.readFully(in, buf, aeadTagLength, aeadTagLength); // read the next tag bytes + } + + return decData; + } + } + + static class PGPAeadOutputStream + extends OutputStream + { + private final boolean isV5AEAD; + private final OutputStream out; + private final byte[] data; + private final Cipher c; + private final SecretKey secretKey; + private final byte[] aaData; + private final byte[] iv; + private final int chunkLength; + + private int dataOff; + private long chunkIndex = 0; + private long totalBytes = 0; + + /** + * OutputStream for AEAD encryption. + * + * @param isV5AEAD isV5AEAD of AEAD (OpenPGP v5 or v6) + * @param out underlying OutputStream + * @param c AEAD cipher + * @param secretKey secret key + * @param iv initialization vector + * @param encAlgorithm encryption algorithm + * @param aeadAlgorithm AEAD algorithm + * @param chunkSize chunk size of the AEAD algorithm + */ + public PGPAeadOutputStream(boolean isV5AEAD, + OutputStream out, + Cipher c, + SecretKey secretKey, + byte[] iv, + int encAlgorithm, + int aeadAlgorithm, + int chunkSize) + { + this.isV5AEAD = isV5AEAD; + this.out = out; + this.iv = iv; + this.chunkLength = (int)getChunkLength(chunkSize); + this.data = new byte[chunkLength]; + this.c = c; + this.secretKey = secretKey; + + this.aaData = createAAD(isV5AEAD, encAlgorithm, aeadAlgorithm, chunkSize); + } + + /** + * Create the associated data for the AEAD encryption. + * Since the associated data array differs between OpenPGP v5 and v6, we need to know the flavour. + * + * @param isV5AEAD true if flavour of AEAD OpenPGP v5 + * @param encAlgorithm symmetric encryption algorithm + * @param aeadAlgorithm AEAD algorithm + * @param chunkSize chunk size + * @return associated data + */ + private byte[] createAAD(boolean isV5AEAD, int encAlgorithm, int aeadAlgorithm, int chunkSize) + { + if (isV5AEAD) + { + return AEADEncDataPacket.createAAData(AEADEncDataPacket.VERSION_1, + encAlgorithm, aeadAlgorithm, chunkSize); + } + else + { + return SymmetricEncIntegrityPacket.createAAData(SymmetricEncIntegrityPacket.VERSION_2, + encAlgorithm, aeadAlgorithm, chunkSize); + } + } + + public void write(int b) + throws IOException + { + if (dataOff == data.length) + { + writeBlock(); + } + data[dataOff++] = (byte)b; + } + + public void write(byte[] b, int off, int len) + throws IOException + { + if (dataOff == data.length) + { + writeBlock(); + } + + if (len < data.length - dataOff) + { + System.arraycopy(b, off, data, dataOff, len); + dataOff += len; + } + else + { + int gap = data.length - dataOff; + System.arraycopy(b, off, data, dataOff, gap); + dataOff += gap; + writeBlock(); + + len -= gap; + off += gap; + + while (len >= data.length) + { + System.arraycopy(b, off, data, 0, data.length); + dataOff = data.length; + writeBlock(); + len -= data.length; + off += data.length; + } + + if (len > 0) + { + System.arraycopy(b, off, data, 0, len); + dataOff = len; + } + } + } + + public void close() + throws IOException + { + finish(); + } + + private void writeBlock() + throws IOException + { + byte[] adata = isV5AEAD ? new byte[13] : new byte[aaData.length]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + if (isV5AEAD) + { + xorChunkId(adata, chunkIndex); + } + + try + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.ENCRYPT_MODE, getNonce(iv, chunkIndex), 128, adata); + + out.write(c.doFinal(data, 0, dataOff)); + } + catch (GeneralSecurityException e) + { + throw new IOException("exception processing chunk " + chunkIndex + ": " + e.getMessage()); + } + + totalBytes += dataOff; + chunkIndex++; + dataOff = 0; + } + + private void finish() + throws IOException + { + if (dataOff > 0) + { + writeBlock(); + } + + byte[] adata = getAdata(isV5AEAD, aaData, chunkIndex, totalBytes); + + try + { + if (isV5AEAD) + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.ENCRYPT_MODE, getNonce(iv, chunkIndex), 128, Arrays.concatenate(adata, Pack.longToBigEndian(totalBytes))); + } + else + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.ENCRYPT_MODE, getNonce(iv, chunkIndex), 128, adata); + } + + out.write(c.doFinal(aaData, 0, 0)); // output final tag + } + catch (GeneralSecurityException e) + { + throw new IOException("exception processing final tag: " + e.getMessage()); + } + out.close(); + } + + private static byte[] getAdata(boolean isV5AEAD, byte[] aaData, long chunkIndex, long totalBytes) + { + byte[] adata; + if (isV5AEAD) + { + adata = new byte[13]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + xorChunkId(adata, chunkIndex); + } + else + { + adata = new byte[aaData.length + 8]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + System.arraycopy(Pack.longToBigEndian(totalBytes), 0, adata, aaData.length, 8); + } + return adata; + } + } +} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEDataDecryptorFactoryBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEDataDecryptorFactoryBuilder.java index 80abfba50f..3a2677d8e9 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEDataDecryptorFactoryBuilder.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEDataDecryptorFactoryBuilder.java @@ -1,15 +1,22 @@ package org.bouncycastle.openpgp.operator.jcajce; +import java.security.GeneralSecurityException; import java.security.Provider; import javax.crypto.Cipher; +import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; +import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; +import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket; +import org.bouncycastle.bcpg.SymmetricKeyUtils; import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; import org.bouncycastle.jcajce.util.NamedJcaJceHelper; import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPSessionKey; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; @@ -22,6 +29,7 @@ public class JcePBEDataDecryptorFactoryBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); + private JceAEADUtil aeadHelper = new JceAEADUtil(helper); private PGPDigestCalculatorProvider calculatorProvider; /** @@ -36,7 +44,7 @@ public JcePBEDataDecryptorFactoryBuilder() /** * Base constructor. * - * @param calculatorProvider a digest calculator provider to provide calculators to support the key generation calculation required. + * @param calculatorProvider a digest calculator provider to provide calculators to support the key generation calculation required. */ public JcePBEDataDecryptorFactoryBuilder(PGPDigestCalculatorProvider calculatorProvider) { @@ -46,12 +54,13 @@ public JcePBEDataDecryptorFactoryBuilder(PGPDigestCalculatorProvider calculatorP /** * Set the provider object to use for creating cryptographic primitives in the resulting factory the builder produces. * - * @param provider provider object for cryptographic primitives. - * @return the current builder. + * @param provider provider object for cryptographic primitives. + * @return the current builder. */ public JcePBEDataDecryptorFactoryBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + this.aeadHelper = new JceAEADUtil(helper); return this; } @@ -59,12 +68,13 @@ public JcePBEDataDecryptorFactoryBuilder setProvider(Provider provider) /** * Set the provider name to use for creating cryptographic primitives in the resulting factory the builder produces. * - * @param providerName the name of the provider to reference for cryptographic primitives. - * @return the current builder. + * @param providerName the name of the provider to reference for cryptographic primitives. + * @return the current builder. */ public JcePBEDataDecryptorFactoryBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + this.aeadHelper = new JceAEADUtil(helper); return this; } @@ -77,60 +87,118 @@ public JcePBEDataDecryptorFactoryBuilder setProvider(String providerName) */ public PBEDataDecryptorFactory build(char[] passPhrase) { - if (calculatorProvider == null) - { - try - { - calculatorProvider = new JcaPGPDigestCalculatorProviderBuilder(helper).build(); - } - catch (PGPException e) - { - throw new IllegalStateException("digest calculator provider cannot be built with current helper: " + e.getMessage()); - } - } - return new PBEDataDecryptorFactory(passPhrase, calculatorProvider) - { - public byte[] recoverSessionData(int keyAlgorithm, byte[] key, byte[] secKeyData) - throws PGPException - { - try - { - if (secKeyData != null && secKeyData.length > 0) - { - String cipherName = PGPUtil.getSymmetricCipherName(keyAlgorithm); - Cipher keyCipher = helper.createCipher(cipherName + "/CFB/NoPadding"); - - keyCipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, cipherName), new IvParameterSpec(new byte[keyCipher.getBlockSize()])); - - return keyCipher.doFinal(secKeyData); - } - else - { - byte[] keyBytes = new byte[key.length + 1]; - - keyBytes[0] = (byte)keyAlgorithm; - System.arraycopy(key, 0, keyBytes, 1, key.length); - - return keyBytes; - } - } - catch (Exception e) - { - throw new PGPException("Exception recovering session info", e); - } - } - - public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) - throws PGPException - { - return helper.createDataDecryptor(withIntegrityPacket, encAlgorithm, key); - } - - public PGPDataDecryptor createDataDecryptor(int aeadAlgorithm, byte[] iv, int chunkSize, int encAlgorithm, byte[] key) - throws PGPException - { - return helper.createDataDecryptor(aeadAlgorithm, iv, chunkSize, encAlgorithm, key); - } - }; + if (calculatorProvider == null) + { + try + { + calculatorProvider = new JcaPGPDigestCalculatorProviderBuilder(helper).build(); + } + catch (PGPException e) + { + throw new IllegalStateException("digest calculator provider cannot be built with current helper: " + e.getMessage()); + } + } + return new PBEDataDecryptorFactory(passPhrase, calculatorProvider) + { + @Override + public byte[] recoverSessionData(int keyAlgorithm, byte[] key, byte[] secKeyData) + throws PGPException + { + try + { + if (secKeyData != null && secKeyData.length > 0) + { + String cipherName = PGPUtil.getSymmetricCipherName(keyAlgorithm); + Cipher keyCipher = helper.createCipher(cipherName + "/CFB/NoPadding"); + keyCipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, cipherName), new IvParameterSpec(new byte[keyCipher.getBlockSize()])); + + return keyCipher.doFinal(secKeyData); + } + else + { + byte[] keyBytes = new byte[key.length + 1]; + + keyBytes[0] = (byte)keyAlgorithm; + System.arraycopy(key, 0, keyBytes, 1, key.length); + + return keyBytes; + } + } + catch (Exception e) + { + throw new PGPException("Exception recovering session info", e); + } + } + + @Override + public byte[] recoverAEADEncryptedSessionData(SymmetricKeyEncSessionPacket keyData, byte[] ikm) + throws PGPException + { + if (keyData.getVersion() < SymmetricKeyEncSessionPacket.VERSION_5) + { + throw new PGPException("SKESK packet MUST be version 5 or later."); + } + + byte[] hkdfInfo = keyData.getAAData(); // between v5 and v6, these bytes differ + int kekLen = SymmetricKeyUtils.getKeyLengthInOctets(keyData.getEncAlgorithm()); + + // HKDF + // secretKey := HKDF_sha256(ikm, hkdfInfo).generate() + byte[] kek = JceAEADUtil.generateHKDFBytes(ikm, null, hkdfInfo, kekLen); + final SecretKey secretKey = new SecretKeySpec(kek, PGPUtil.getSymmetricCipherName(keyData.getEncAlgorithm())); + + // AEAD + Cipher aead = aeadHelper.createAEADCipher(keyData.getEncAlgorithm(), keyData.getAeadAlgorithm()); + int aeadMacLen = 128; + byte[] authTag = keyData.getAuthTag(); + byte[] aeadIv = keyData.getIv(); + byte[] encSessionKey = keyData.getSecKeyData(); + + // buf := encSessionKey || authTag + byte[] buf = new byte[encSessionKey.length + authTag.length]; + System.arraycopy(encSessionKey, 0, buf, 0, encSessionKey.length); + System.arraycopy(authTag, 0, buf, encSessionKey.length, authTag.length); + + // sessionData := AEAD(secretKey).decrypt(buf) + byte[] sessionData; + try + { + JceAEADCipherUtil.setUpAeadCipher(aead, secretKey, Cipher.DECRYPT_MODE, aeadIv, aeadMacLen, hkdfInfo); + + sessionData = aead.doFinal(buf, 0, buf.length); + } + catch (GeneralSecurityException e) + { + throw new PGPException("unable to open stream: " + e.getMessage()); + } + + return sessionData; + + } + + // OpenPGP v4 + @Override + public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) + throws PGPException + { + return helper.createDataDecryptor(withIntegrityPacket, encAlgorithm, key); + } + + // OpenPGP v5 + @Override + public PGPDataDecryptor createDataDecryptor(AEADEncDataPacket aeadEncDataPacket, PGPSessionKey sessionKey) + throws PGPException + { + return aeadHelper.createOpenPgpV5DataDecryptor(aeadEncDataPacket, sessionKey); + } + + // OpenPGP v6 + @Override + public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, PGPSessionKey sessionKey) + throws PGPException + { + return aeadHelper.createOpenPgpV6DataDecryptor(seipd, sessionKey); + } + }; } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEKeyEncryptionMethodGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEKeyEncryptionMethodGenerator.java index 935d9165bf..69e03019b7 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEKeyEncryptionMethodGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEKeyEncryptionMethodGenerator.java @@ -13,6 +13,11 @@ import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.bcpg.S2K; +import org.bouncycastle.bcpg.SymmetricKeyUtils; +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.modes.AEADCipher; +import org.bouncycastle.crypto.params.AEADParameters; +import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; import org.bouncycastle.jcajce.util.NamedJcaJceHelper; import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; @@ -20,6 +25,7 @@ import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.openpgp.operator.bc.BcAEADUtil; /** * JCE based generator for password based encryption (PBE) data protection methods. @@ -33,7 +39,7 @@ public class JcePBEKeyEncryptionMethodGenerator * Create a PBE encryption method generator using the provided digest and the default S2K count * for key generation. * - * @param passPhrase the passphrase to use as the primary source of key material. + * @param passPhrase the passphrase to use as the primary source of key material. * @param s2kDigestCalculator the digest calculator to use for key calculation. */ public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator s2kDigestCalculator) @@ -56,9 +62,9 @@ public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase) * Create a PBE encryption method generator using the provided calculator and S2K count for key * generation. * - * @param passPhrase the passphrase to use as the primary source of key material. + * @param passPhrase the passphrase to use as the primary source of key material. * @param s2kDigestCalculator the digest calculator to use for key calculation. - * @param s2kCount the single byte {@link S2K} count to use. + * @param s2kCount the single byte {@link S2K} count to use. */ public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator s2kDigestCalculator, int s2kCount) { @@ -70,7 +76,7 @@ public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator * count other than the default for key generation. * * @param passPhrase the passphrase to use as the primary source of key material. - * @param s2kCount the single byte {@link S2K} count to use. + * @param s2kCount the single byte {@link S2K} count to use. */ public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase, int s2kCount) { @@ -118,7 +124,6 @@ protected byte[] encryptSessionInfo(int encAlgorithm, byte[] key, byte[] session String cName = PGPUtil.getSymmetricCipherName(encAlgorithm); Cipher c = helper.createCipher(cName + "/CFB/NoPadding"); SecretKey sKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); - c.init(Cipher.ENCRYPT_MODE, sKey, new IvParameterSpec(new byte[c.getBlockSize()])); return c.doFinal(sessionInfo, 0, sessionInfo.length); @@ -140,4 +145,31 @@ protected byte[] encryptSessionInfo(int encAlgorithm, byte[] key, byte[] session throw new PGPException("key invalid: " + e.getMessage(), e); } } + + protected byte[] generateV6KEK(int kekAlgorithm, byte[] ikm, byte[] info) + { + return JceAEADUtil.generateHKDFBytes(ikm, null, info, SymmetricKeyUtils.getKeyLengthInOctets(kekAlgorithm)); + } + + protected byte[] getEskAndTag(int kekAlgorithm, int aeadAlgorithm, byte[] sessionInfo, byte[] key, byte[] iv, byte[] info) + throws PGPException + { + byte[] sessionKey = new byte[sessionInfo.length - 3]; + System.arraycopy(sessionInfo, 1, sessionKey, 0, sessionKey.length); + + AEADCipher aeadCipher = BcAEADUtil.createAEADCipher(kekAlgorithm, aeadAlgorithm); + aeadCipher.init(true, new AEADParameters(new KeyParameter(key), 128, iv, info)); + int outLen = aeadCipher.getOutputSize(sessionKey.length); + byte[] eskAndTag = new byte[outLen]; + int len = aeadCipher.processBytes(sessionKey, 0, sessionKey.length, eskAndTag, 0); + try + { + len += aeadCipher.doFinal(eskAndTag, len); + } + catch (InvalidCipherTextException e) + { + throw new PGPException("cannot encrypt session info", e); + } + return eskAndTag; + } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEProtectionRemoverFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEProtectionRemoverFactory.java index 40f3f9efef..3451594633 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEProtectionRemoverFactory.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEProtectionRemoverFactory.java @@ -7,8 +7,14 @@ import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; +import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import org.bouncycastle.bcpg.SymmetricKeyUtils; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.params.HKDFParameters; import org.bouncycastle.jcajce.spec.AEADParameterSpec; import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; import org.bouncycastle.jcajce.util.NamedJcaJceHelper; @@ -19,6 +25,7 @@ import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.PGPSecretKeyDecryptorWithAAD; +import org.bouncycastle.util.Arrays; public class JcePBEProtectionRemoverFactory implements PBEProtectionRemoverFactory @@ -27,6 +34,7 @@ public class JcePBEProtectionRemoverFactory private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private PGPDigestCalculatorProvider calculatorProvider; + private JceAEADUtil aeadUtil = new JceAEADUtil(helper); private JcaPGPDigestCalculatorProviderBuilder calculatorProviderBuilder; @@ -45,6 +53,7 @@ public JcePBEProtectionRemoverFactory(char[] passPhrase, PGPDigestCalculatorProv public JcePBEProtectionRemoverFactory setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + this.aeadUtil = new JceAEADUtil(helper); if (calculatorProviderBuilder != null) { @@ -57,6 +66,7 @@ public JcePBEProtectionRemoverFactory setProvider(Provider provider) public JcePBEProtectionRemoverFactory setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + this.aeadUtil = new JceAEADUtil(helper); if (calculatorProviderBuilder != null) { @@ -105,6 +115,37 @@ public byte[] recoverKeyData(int encAlgorithm, byte[] key, byte[] iv, byte[] aad throw new PGPException("invalid key: " + e.getMessage(), e); } } + + @Override + public byte[] recoverKeyData(int encAlgorithm, int aeadAlgorithm, byte[] s2kKey, byte[] iv, int packetTag, int keyVersion, byte[] keyData, byte[] pubkeyData) + throws PGPException + { + byte[] hkdfInfo = new byte[] { + (byte) (0xC0 | packetTag), (byte) keyVersion, (byte) encAlgorithm, (byte) aeadAlgorithm + }; + // TODO: Replace HDKF code with JCE based implementation + HKDFParameters hkdfParameters = new HKDFParameters(s2kKey, null, hkdfInfo); + HKDFBytesGenerator hkdfGen = new HKDFBytesGenerator(new SHA256Digest()); + hkdfGen.init(hkdfParameters); + byte[] key = new byte[SymmetricKeyUtils.getKeyLengthInOctets(encAlgorithm)]; + hkdfGen.generateBytes(key, 0, key.length); + + byte[] aad = Arrays.prepend(pubkeyData, (byte) (0xC0 | packetTag)); + + SecretKey secretKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); + final Cipher c = aeadUtil.createAEADCipher(encAlgorithm, aeadAlgorithm); + try + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.DECRYPT_MODE, iv, 128, aad); + byte[] data = c.doFinal(keyData); + return data; + } + catch (InvalidAlgorithmParameterException | InvalidKeyException | + IllegalBlockSizeException | BadPaddingException e) + { + throw new PGPException("Cannot extract AEAD protected secret key material", e); + } + } }; } else @@ -138,6 +179,37 @@ public byte[] recoverKeyData(int encAlgorithm, byte[] key, byte[] iv, byte[] key throw new PGPException("invalid key: " + e.getMessage(), e); } } + + @Override + public byte[] recoverKeyData(int encAlgorithm, int aeadAlgorithm, byte[] s2kKey, byte[] iv, int packetTag, int keyVersion, byte[] keyData, byte[] pubkeyData) + throws PGPException + { + byte[] hkdfInfo = new byte[] { + (byte) (0xC0 | packetTag), (byte) keyVersion, (byte) encAlgorithm, (byte) aeadAlgorithm + }; + // TODO: Replace HDKF code with JCE based implementation + HKDFParameters hkdfParameters = new HKDFParameters(s2kKey, null, hkdfInfo); + HKDFBytesGenerator hkdfGen = new HKDFBytesGenerator(new SHA256Digest()); + hkdfGen.init(hkdfParameters); + byte[] key = new byte[SymmetricKeyUtils.getKeyLengthInOctets(encAlgorithm)]; + hkdfGen.generateBytes(key, 0, key.length); + + byte[] aad = Arrays.prepend(pubkeyData, (byte) (0xC0 | packetTag)); + + SecretKey secretKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); + final Cipher c = aeadUtil.createAEADCipher(encAlgorithm, aeadAlgorithm); + try + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.DECRYPT_MODE, iv, 128, aad); + byte[] data = c.doFinal(keyData); + return data; + } + catch (InvalidAlgorithmParameterException | InvalidKeyException | + IllegalBlockSizeException | BadPaddingException e) + { + throw new PGPException("Cannot extract AEAD protected secret key material", e); + } + } }; } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBESecretKeyDecryptorBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBESecretKeyDecryptorBuilder.java index 2defaea635..ee172bf068 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBESecretKeyDecryptorBuilder.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBESecretKeyDecryptorBuilder.java @@ -7,8 +7,14 @@ import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; +import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import org.bouncycastle.bcpg.SymmetricKeyUtils; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.params.HKDFParameters; import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; import org.bouncycastle.jcajce.util.NamedJcaJceHelper; import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; @@ -16,11 +22,13 @@ import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; +import org.bouncycastle.util.Arrays; public class JcePBESecretKeyDecryptorBuilder { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private PGPDigestCalculatorProvider calculatorProvider; + private JceAEADUtil aeadUtil = new JceAEADUtil(helper); private JcaPGPDigestCalculatorProviderBuilder calculatorProviderBuilder; @@ -37,6 +45,7 @@ public JcePBESecretKeyDecryptorBuilder(PGPDigestCalculatorProvider calculatorPro public JcePBESecretKeyDecryptorBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + this.aeadUtil = new JceAEADUtil(helper); if (calculatorProviderBuilder != null) { @@ -49,6 +58,7 @@ public JcePBESecretKeyDecryptorBuilder setProvider(Provider provider) public JcePBESecretKeyDecryptorBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + this.aeadUtil = new JceAEADUtil(helper); if (calculatorProviderBuilder != null) { @@ -96,6 +106,37 @@ public byte[] recoverKeyData(int encAlgorithm, byte[] key, byte[] iv, byte[] key throw new PGPException("invalid key: " + e.getMessage(), e); } } + + @Override + public byte[] recoverKeyData(int encAlgorithm, int aeadAlgorithm, byte[] s2kKey, byte[] iv, int packetTag, int keyVersion, byte[] keyData, byte[] pubkeyData) + throws PGPException + { + byte[] hkdfInfo = new byte[] { + (byte) (0xC0 | packetTag), (byte) keyVersion, (byte) encAlgorithm, (byte) aeadAlgorithm + }; + // TODO: Replace HDKF code with JCE based implementation + HKDFParameters hkdfParameters = new HKDFParameters(s2kKey, null, hkdfInfo); + HKDFBytesGenerator hkdfGen = new HKDFBytesGenerator(new SHA256Digest()); + hkdfGen.init(hkdfParameters); + byte[] key = new byte[SymmetricKeyUtils.getKeyLengthInOctets(encAlgorithm)]; + hkdfGen.generateBytes(key, 0, key.length); + + byte[] aad = Arrays.prepend(pubkeyData, (byte) (0xC0 | packetTag)); + + SecretKey secretKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); + final Cipher c = aeadUtil.createAEADCipher(encAlgorithm, aeadAlgorithm); + try + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.DECRYPT_MODE, iv, 128, aad); + byte[] data = c.doFinal(keyData); + return data; + } + catch (InvalidAlgorithmParameterException | InvalidKeyException | + IllegalBlockSizeException | BadPaddingException e) + { + throw new PGPException("Cannot extract AEAD protected secret key material", e); + } + } }; } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePGPDataEncryptorBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePGPDataEncryptorBuilder.java index 39d35388ba..096f64a80b 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePGPDataEncryptorBuilder.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePGPDataEncryptorBuilder.java @@ -9,8 +9,9 @@ import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; -import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.AEADUtils; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyUtils; import org.bouncycastle.jcajce.io.CipherOutputStream; import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; import org.bouncycastle.jcajce.util.NamedJcaJceHelper; @@ -34,12 +35,15 @@ public class JcePGPDataEncryptorBuilder implements PGPDataEncryptorBuilder { + private final int encAlgorithm; + private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); + private JceAEADUtil aeadHelper = new JceAEADUtil(helper); private SecureRandom random; - private boolean withIntegrityPacket; - private int encAlgorithm; + private boolean withIntegrityPacket = true; private int aeadAlgorithm = -1; private int chunkSize; + private boolean isV5StyleAEAD = true; // TODO: change to false in 1.75 /** * Constructs a new data encryptor builder for a specified cipher type. @@ -63,6 +67,7 @@ public JcePGPDataEncryptorBuilder(int encAlgorithm) * @param withIntegrityPacket true if an integrity packet is to be included, false otherwise. * @return the current builder. */ + @Override public JcePGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPacket) { this.withIntegrityPacket = withIntegrityPacket; @@ -70,13 +75,17 @@ public JcePGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPa return this; } + @Override public JcePGPDataEncryptorBuilder setWithAEAD(int aeadAlgorithm, int chunkSize) { if (encAlgorithm != SymmetricKeyAlgorithmTags.AES_128 && encAlgorithm != SymmetricKeyAlgorithmTags.AES_192 - && encAlgorithm != SymmetricKeyAlgorithmTags.AES_256) + && encAlgorithm != SymmetricKeyAlgorithmTags.AES_256 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_128 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_192 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_256) { - throw new IllegalStateException("AEAD algorithms can only be used with AES"); + throw new IllegalStateException("AEAD algorithms can only be used with AES and Camellia"); } if (chunkSize < 6) @@ -90,6 +99,22 @@ public JcePGPDataEncryptorBuilder setWithAEAD(int aeadAlgorithm, int chunkSize) return this; } + @Override + public JcePGPDataEncryptorBuilder setUseV5AEAD() + { + this.isV5StyleAEAD = true; + + return this; + } + + @Override + public JcePGPDataEncryptorBuilder setUseV6AEAD() + { + this.isV5StyleAEAD = false; + + return this; + } + /** * Sets the JCE provider to source cryptographic primitives from. * @@ -99,6 +124,7 @@ public JcePGPDataEncryptorBuilder setWithAEAD(int aeadAlgorithm, int chunkSize) public JcePGPDataEncryptorBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + this.aeadHelper = new JceAEADUtil(helper); return this; } @@ -112,6 +138,7 @@ public JcePGPDataEncryptorBuilder setProvider(Provider provider) public JcePGPDataEncryptorBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + this.aeadHelper = new JceAEADUtil(helper); return this; } @@ -132,11 +159,31 @@ public JcePGPDataEncryptorBuilder setSecureRandom(SecureRandom random) return this; } + @Override public int getAlgorithm() { return encAlgorithm; } + @Override + public int getAeadAlgorithm() + { + return aeadAlgorithm; + } + + @Override + public int getChunkSize() + { + return chunkSize; + } + + @Override + public boolean isV5StyleAEAD() + { + return isV5StyleAEAD; + } + + @Override public SecureRandom getSecureRandom() { if (random == null) @@ -147,6 +194,7 @@ public SecureRandom getSecureRandom() return random; } + @Override public PGPDataEncryptor build(byte[] keyBytes) throws PGPException { @@ -171,9 +219,7 @@ private class MyPGPDataEncryptor { if (withIntegrityPacket) { - byte[] iv = new byte[c.getBlockSize()]; - - c.init(Cipher.ENCRYPT_MODE, JcaJcePGPUtil.makeSymmetricKey(encAlgorithm, keyBytes), new IvParameterSpec(iv)); + c.init(Cipher.ENCRYPT_MODE, JcaJcePGPUtil.makeSymmetricKey(encAlgorithm, keyBytes), new IvParameterSpec(new byte[c.getBlockSize()])); } else { @@ -214,25 +260,46 @@ public int getBlockSize() private class MyAeadDataEncryptor implements PGPAEADDataEncryptor { + private final boolean isV5StyleAEAD; private final Cipher c; private final byte[] keyBytes; private final byte[] iv; + /** + * Create a new data decryptor using AEAD. + * If OpenPGP v5 style AEAD is used, keyBytes contains the key. The IV is randomly generated. + * If however OpenPGP v6 style AEAD is used, keyBytes contains M+N-8 bytes. + * The first M bytes contain the key, the remaining N-8 bytes contain the IV. + * + * @param keyBytes key or key and iv + * @throws PGPException on encryption failure + */ MyAeadDataEncryptor(byte[] keyBytes) throws PGPException { - this.keyBytes = keyBytes; - this.c = helper.createAEADCipher(encAlgorithm, aeadAlgorithm); - this.iv = new byte[AEADEncDataPacket.getIVLength((byte)aeadAlgorithm)]; - - getSecureRandom().nextBytes(iv); + this.isV5StyleAEAD = keyBytes.length == SymmetricKeyUtils.getKeyLengthInOctets(encAlgorithm); + if (isV5StyleAEAD) + { + this.keyBytes = keyBytes; + // V5 has a random IV + this.iv = new byte[AEADUtils.getIVLength((byte)aeadAlgorithm)]; + getSecureRandom().nextBytes(iv); + } + else + { + // V6 has the IV appended to the message key, so we need to split it + byte[][] keyAndIv = AEADUtils.splitMessageKeyAndIv(keyBytes, encAlgorithm, aeadAlgorithm); + this.keyBytes = keyAndIv[0]; + this.iv = keyAndIv[1]; + } + this.c = aeadHelper.createAEADCipher(encAlgorithm, aeadAlgorithm); } public OutputStream getOutputStream(OutputStream out) { try { - return new OperatorHelper.PGPAeadOutputStream(out, c, JcaJcePGPUtil.makeSymmetricKey(encAlgorithm, keyBytes), encAlgorithm, aeadAlgorithm, chunkSize, iv); + return new JceAEADUtil.PGPAeadOutputStream(isV5StyleAEAD, out, c, JcaJcePGPUtil.makeSymmetricKey(encAlgorithm, keyBytes), iv, encAlgorithm, aeadAlgorithm, chunkSize); } catch (Exception e) { @@ -250,19 +317,23 @@ public int getBlockSize() return c.getBlockSize(); } + @Override public int getAEADAlgorithm() { return aeadAlgorithm; } + @Override public int getChunkSize() { return chunkSize; } + @Override public byte[] getIV() { return Arrays.clone(iv); } + } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyDataDecryptorFactoryBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyDataDecryptorFactoryBuilder.java index 9a860b6aa6..ecdfa24576 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyDataDecryptorFactoryBuilder.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyDataDecryptorFactoryBuilder.java @@ -2,30 +2,34 @@ import java.io.IOException; import java.security.GeneralSecurityException; -import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.interfaces.RSAKey; +import java.security.spec.AlgorithmParameterSpec; import java.security.spec.X509EncodedKeySpec; import java.util.Date; import javax.crypto.Cipher; -import javax.crypto.KeyAgreement; import javax.crypto.interfaces.DHKey; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X9ECParametersHolder; +import org.bouncycastle.bcpg.AEADEncDataPacket; import org.bouncycastle.bcpg.ECDHPublicBCPGKey; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.X25519PublicBCPGKey; +import org.bouncycastle.bcpg.X448PublicBCPGKey; import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec; import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; import org.bouncycastle.jcajce.util.NamedJcaJceHelper; @@ -34,6 +38,7 @@ import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPSessionKey; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PGPPad; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; @@ -42,10 +47,9 @@ public class JcePublicKeyDataDecryptorFactoryBuilder { - private static final int X25519_KEY_SIZE = 32; - private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private OperatorHelper contentHelper = new OperatorHelper(new DefaultJcaJceHelper()); + private JceAEADUtil aeadHelper = new JceAEADUtil(contentHelper); private JcaPGPKeyConverter keyConverter = new JcaPGPKeyConverter(); private JcaKeyFingerprintCalculator fingerprintCalculator = new JcaKeyFingerprintCalculator(); @@ -56,14 +60,15 @@ public JcePublicKeyDataDecryptorFactoryBuilder() /** * Set the provider object to use for creating cryptographic primitives in the resulting factory the builder produces. * - * @param provider provider object for cryptographic primitives. - * @return the current builder. + * @param provider provider object for cryptographic primitives. + * @return the current builder. */ public JcePublicKeyDataDecryptorFactoryBuilder setProvider(Provider provider) { this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); keyConverter.setProvider(provider); this.contentHelper = helper; + this.aeadHelper = new JceAEADUtil(contentHelper); return this; } @@ -71,14 +76,15 @@ public JcePublicKeyDataDecryptorFactoryBuilder setProvider(Provider provider) /** * Set the provider name to use for creating cryptographic primitives in the resulting factory the builder produces. * - * @param providerName the name of the provider to reference for cryptographic primitives. - * @return the current builder. + * @param providerName the name of the provider to reference for cryptographic primitives. + * @return the current builder. */ public JcePublicKeyDataDecryptorFactoryBuilder setProvider(String providerName) { this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); keyConverter.setProvider(providerName); this.contentHelper = helper; + this.aeadHelper = new JceAEADUtil(contentHelper); return this; } @@ -86,6 +92,7 @@ public JcePublicKeyDataDecryptorFactoryBuilder setProvider(String providerName) public JcePublicKeyDataDecryptorFactoryBuilder setContentProvider(Provider provider) { this.contentHelper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + this.aeadHelper = new JceAEADUtil(contentHelper); return this; } @@ -93,6 +100,7 @@ public JcePublicKeyDataDecryptorFactoryBuilder setContentProvider(Provider provi public JcePublicKeyDataDecryptorFactoryBuilder setContentProvider(String providerName) { this.contentHelper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + this.aeadHelper = new JceAEADUtil(contentHelper); return this; } @@ -119,165 +127,221 @@ else if (key instanceof RSAKey) public PublicKeyDataDecryptorFactory build(final PrivateKey privKey) { - return new PublicKeyDataDecryptorFactory() - { - final int expectedPayLoadSize = getExpectedPayloadSize(privKey); - - public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) - throws PGPException - { - if (keyAlgorithm == PublicKeyAlgorithmTags.ECDH) - { - throw new PGPException("ECDH requires use of PGPPrivateKey for decryption"); - } - return decryptSessionData(keyAlgorithm, privKey, expectedPayLoadSize, secKeyData); - } - - public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) - throws PGPException - { - return contentHelper.createDataDecryptor(withIntegrityPacket, encAlgorithm, key); - } - - public PGPDataDecryptor createDataDecryptor(int aeadAlgorithm, byte[] iv, int chunkSize, int encAlgorithm, byte[] key) - throws PGPException - { - return contentHelper.createDataDecryptor(aeadAlgorithm, iv, chunkSize, encAlgorithm, key); - } - }; + return new PublicKeyDataDecryptorFactory() + { + final int expectedPayLoadSize = getExpectedPayloadSize(privKey); + + @Override + public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) + throws PGPException + { + if (keyAlgorithm == PublicKeyAlgorithmTags.ECDH || keyAlgorithm == PublicKeyAlgorithmTags.X25519 || keyAlgorithm == PublicKeyAlgorithmTags.X448) + { + throw new PGPException("ECDH requires use of PGPPrivateKey for decryption"); + } + return decryptSessionData(keyAlgorithm, privKey, expectedPayLoadSize, secKeyData); + } + + // OpenPGP v4 + @Override + public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) + throws PGPException + { + return contentHelper.createDataDecryptor(withIntegrityPacket, encAlgorithm, key); + } + + // OpenPGP v5 + @Override + public PGPDataDecryptor createDataDecryptor(AEADEncDataPacket aeadEncDataPacket, PGPSessionKey sessionKey) + throws PGPException + { + return aeadHelper.createOpenPgpV5DataDecryptor(aeadEncDataPacket, sessionKey); + } + + // OpenPGP v6 + @Override + public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, PGPSessionKey sessionKey) + throws PGPException + { + return aeadHelper.createOpenPgpV6DataDecryptor(seipd, sessionKey); + } + }; } public PublicKeyDataDecryptorFactory build(final PGPPrivateKey privKey) { - return new PublicKeyDataDecryptorFactory() - { - public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) - throws PGPException - { - if (keyAlgorithm == PublicKeyAlgorithmTags.ECDH) - { - return decryptSessionData(keyConverter, privKey, secKeyData); - } - PrivateKey jcePrivKey = keyConverter.getPrivateKey(privKey); - int expectedPayLoadSize = getExpectedPayloadSize(jcePrivKey); - - return decryptSessionData(keyAlgorithm, jcePrivKey, expectedPayLoadSize, secKeyData); - } - - public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) - throws PGPException - { - return contentHelper.createDataDecryptor(withIntegrityPacket, encAlgorithm, key); - } - - public PGPDataDecryptor createDataDecryptor(int aeadAlgorithm, byte[] iv, int chunkSize, int encAlgorithm, byte[] key) - throws PGPException - { - return contentHelper.createDataDecryptor(aeadAlgorithm, iv, chunkSize, encAlgorithm, key); - } - }; + return new PublicKeyDataDecryptorFactory() + { + @Override + public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) + throws PGPException + { + if (keyAlgorithm == PublicKeyAlgorithmTags.ECDH) + { + return decryptSessionData(keyConverter, privKey, secKeyData); + } + else if (keyAlgorithm == PublicKeyAlgorithmTags.X25519) + { + return decryptSessionData(keyConverter, privKey, secKeyData[0], X25519PublicBCPGKey.LENGTH, "X25519withSHA256HKDF", + SymmetricKeyAlgorithmTags.AES_128, EdECObjectIdentifiers.id_X25519, "X25519"); + } + else if (keyAlgorithm == PublicKeyAlgorithmTags.X448) + { + return decryptSessionData(keyConverter, privKey, secKeyData[0], X448PublicBCPGKey.LENGTH, "X448withSHA512HKDF", + SymmetricKeyAlgorithmTags.AES_256, EdECObjectIdentifiers.id_X448, "X448"); + } + PrivateKey jcePrivKey = keyConverter.getPrivateKey(privKey); + int expectedPayLoadSize = getExpectedPayloadSize(jcePrivKey); + + return decryptSessionData(keyAlgorithm, jcePrivKey, expectedPayLoadSize, secKeyData); + } + + // OpenPGP v4 + @Override + public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) + throws PGPException + { + return contentHelper.createDataDecryptor(withIntegrityPacket, encAlgorithm, key); + } + + // OpenPGP v5 + @Override + public PGPDataDecryptor createDataDecryptor(AEADEncDataPacket aeadEncDataPacket, PGPSessionKey sessionKey) + throws PGPException + { + return aeadHelper.createOpenPgpV5DataDecryptor(aeadEncDataPacket, sessionKey); + } + + // OpenPGP v6 + @Override + public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, PGPSessionKey sessionKey) + throws PGPException + { + return aeadHelper.createOpenPgpV6DataDecryptor(seipd, sessionKey); + } + }; } private byte[] decryptSessionData(JcaPGPKeyConverter converter, PGPPrivateKey privKey, byte[][] secKeyData) throws PGPException { PublicKeyPacket pubKeyData = privKey.getPublicKeyPacket(); - ECDHPublicBCPGKey ecKey = (ECDHPublicBCPGKey)pubKeyData.getKey(); byte[] enc = secKeyData[0]; + int pLen; + byte[] pEnc; + byte[] keyEnc; - int pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8; + pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8; if ((2 + pLen + 1) > enc.length) { throw new PGPException("encoded length out of range"); } - byte[] pEnc = new byte[pLen]; + pEnc = new byte[pLen]; System.arraycopy(enc, 2, pEnc, 0, pLen); - int keyLen = enc[pLen + 2] & 0xff; if ((2 + pLen + 1 + keyLen) > enc.length) { throw new PGPException("encoded length out of range"); } - byte[] keyEnc = new byte[keyLen]; + keyEnc = new byte[keyLen]; System.arraycopy(enc, 2 + pLen + 1, keyEnc, 0, keyLen); try { - KeyAgreement agreement; PublicKey publicKey; - + String agreementName; + ECDHPublicBCPGKey ecKey = (ECDHPublicBCPGKey)pubKeyData.getKey(); // XDH - if (ecKey.getCurveOID().equals(CryptlibObjectIdentifiers.curvey25519)) + if (JcaJcePGPUtil.isX25519(ecKey.getCurveOID())) { - agreement = helper.createKeyAgreement(RFC6637Utils.getXDHAlgorithm(pubKeyData)); - - KeyFactory keyFact = helper.createKeyFactory("XDH"); - - // skip the 0x40 header byte. - if (pEnc.length != (1 + X25519_KEY_SIZE) || 0x40 != pEnc[0]) + agreementName = RFC6637Utils.getXDHAlgorithm(pubKeyData); + if (pEnc.length != (1 + X25519PublicBCPGKey.LENGTH) || 0x40 != pEnc[0]) { throw new IllegalArgumentException("Invalid Curve25519 public key"); } - - publicKey = keyFact.generatePublic( - new X509EncodedKeySpec( - new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), - Arrays.copyOfRange(pEnc, 1, pEnc.length)).getEncoded())); + publicKey = getPublicKey(pEnc, EdECObjectIdentifiers.id_X25519, 1); + } + else if (ecKey.getCurveOID().equals(EdECObjectIdentifiers.id_X448)) + { + agreementName = RFC6637Utils.getXDHAlgorithm(pubKeyData); + if (pEnc.length != (1 + X448PublicBCPGKey.LENGTH) || 0x40 != pEnc[0]) + { + throw new IllegalArgumentException("Invalid Curve25519 public key"); + } + publicKey = getPublicKey(pEnc, EdECObjectIdentifiers.id_X448, 1); } else { X9ECParametersHolder x9Params = ECNamedCurveTable.getByOIDLazy(ecKey.getCurveOID()); ECPoint publicPoint = x9Params.getCurve().decodePoint(pEnc); - agreement = helper.createKeyAgreement(RFC6637Utils.getAgreementAlgorithm(pubKeyData)); + agreementName = RFC6637Utils.getAgreementAlgorithm(pubKeyData); - publicKey = converter.getPublicKey(new PGPPublicKey(new PublicKeyPacket(PublicKeyAlgorithmTags.ECDH, new Date(), + publicKey = converter.getPublicKey(new PGPPublicKey(new PublicKeyPacket(pubKeyData.getVersion(), PublicKeyAlgorithmTags.ECDH, new Date(), new ECDHPublicBCPGKey(ecKey.getCurveOID(), publicPoint, ecKey.getHashAlgorithm(), ecKey.getSymmetricKeyAlgorithm())), fingerprintCalculator)); } - byte[] userKeyingMaterial = RFC6637Utils.createUserKeyingMaterial(pubKeyData, fingerprintCalculator); - PrivateKey privateKey = converter.getPrivateKey(privKey); - - agreement.init(privateKey, new UserKeyingMaterialSpec(userKeyingMaterial)); - - agreement.doPhase(publicKey, true); - - Key key = agreement.generateSecret(RFC6637Utils.getKeyEncryptionOID(ecKey.getSymmetricKeyAlgorithm()).getId()); - - Cipher c = helper.createKeyWrapper(ecKey.getSymmetricKeyAlgorithm()); - - c.init(Cipher.UNWRAP_MODE, key); - - Key paddedSessionKey = c.unwrap(keyEnc, "Session", Cipher.SECRET_KEY); + Key paddedSessionKey = getSessionKey(converter, privKey, agreementName, publicKey, ecKey.getSymmetricKeyAlgorithm(), keyEnc, new UserKeyingMaterialSpec(userKeyingMaterial)); return PGPPad.unpadSessionData(paddedSessionKey.getEncoded()); } - catch (InvalidKeyException e) - { - throw new PGPException("error setting asymmetric cipher", e); - } - catch (NoSuchAlgorithmException e) - { - throw new PGPException("error setting asymmetric cipher", e); - } - catch (InvalidAlgorithmParameterException e) + catch (Exception e) { - throw new PGPException("error setting asymmetric cipher", e); + throw new PGPException("error decrypting session data: " + e.getMessage(), e); } - catch (GeneralSecurityException e) + } + + private byte[] decryptSessionData(JcaPGPKeyConverter converter, PGPPrivateKey privKey, byte[] enc, int pLen, String agreementAlgorithm, + int symmetricKeyAlgorithm, ASN1ObjectIdentifier algprithmIdentifier, String algorithmName) + throws PGPException + { + try { - throw new PGPException("error setting asymmetric cipher", e); + byte[] pEnc = new byte[pLen]; + System.arraycopy(enc, 0, pEnc, 0, pLen); + int keyLen = enc[pLen] & 0xff; + if ((pLen + 1 + keyLen) > enc.length) + { + throw new PGPException("encoded length out of range"); + } + byte[] keyEnc = new byte[keyLen - 1]; + System.arraycopy(enc, pLen + 2, keyEnc, 0, keyEnc.length); + PublicKey publicKey = getPublicKey(pEnc, algprithmIdentifier, 0); + Key paddedSessionKey = getSessionKey(converter, privKey, agreementAlgorithm, publicKey, symmetricKeyAlgorithm, keyEnc, + JcaJcePGPUtil.getHybridValueParameterSpecWithPrepend(pEnc, privKey.getPublicKeyPacket(), algorithmName)); + symmetricKeyAlgorithm = enc[pLen + 1] & 0xff; + return Arrays.prepend(paddedSessionKey.getEncoded(), (byte)symmetricKeyAlgorithm); } - catch (IOException e) + catch (Exception e) { - throw new PGPException("error setting asymmetric cipher", e); + throw new PGPException("error decrypting session data: " + e.getMessage(), e); } } + private Key getSessionKey(JcaPGPKeyConverter converter, PGPPrivateKey privKey, String agreementName, + PublicKey publicKey, int symmetricKeyAlgorithm, byte[] keyEnc, AlgorithmParameterSpec ukms) + throws PGPException, GeneralSecurityException + { + PrivateKey privateKey = converter.getPrivateKey(privKey); + Key key = JcaJcePGPUtil.getSecret(helper, publicKey, RFC6637Utils.getKeyEncryptionOID(symmetricKeyAlgorithm).getId(), agreementName, ukms, privateKey); + Cipher c = helper.createKeyWrapper(symmetricKeyAlgorithm); + c.init(Cipher.UNWRAP_MODE, key); + return c.unwrap(keyEnc, "Session", Cipher.SECRET_KEY); + } + + private PublicKey getPublicKey(byte[] pEnc, ASN1ObjectIdentifier algprithmIdentifier, int pEncOff) + throws PGPException, GeneralSecurityException, IOException + { + KeyFactory keyFact = helper.createKeyFactory("XDH"); + + return keyFact.generatePublic(new X509EncodedKeySpec(new SubjectPublicKeyInfo( + new AlgorithmIdentifier(algprithmIdentifier), Arrays.copyOfRange(pEnc, pEncOff, pEnc.length)).getEncoded())); + } + private void updateWithMPI(Cipher c, int expectedPayloadSize, byte[] encMPI) { if (expectedPayloadSize > 0) diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyKeyEncryptionMethodGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyKeyEncryptionMethodGenerator.java index 2b87aabdfa..08110ac560 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyKeyEncryptionMethodGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyKeyEncryptionMethodGenerator.java @@ -1,7 +1,6 @@ package org.bouncycastle.openpgp.operator.jcajce; import java.io.IOException; -import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; @@ -16,16 +15,17 @@ import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; -import javax.crypto.KeyAgreement; import javax.crypto.spec.SecretKeySpec; +import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; -import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.bcpg.ECDHPublicBCPGKey; -import org.bouncycastle.bcpg.MPInteger; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.jcajce.spec.HybridValueParameterSpec; import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec; import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; import org.bouncycastle.jcajce.util.NamedJcaJceHelper; @@ -97,57 +97,52 @@ protected byte[] encryptSessionInfo(PGPPublicKey pubKey, byte[] sessionInfo) if (pubKey.getAlgorithm() == PublicKeyAlgorithmTags.ECDH) { - PublicKeyPacket pubKeyPacket = pubKey.getPublicKeyPacket(); - ECDHPublicBCPGKey ecKey = (ECDHPublicBCPGKey)pubKeyPacket.getKey(); - - UserKeyingMaterialSpec ukmSpec = new UserKeyingMaterialSpec( - RFC6637Utils.createUserKeyingMaterial(pubKeyPacket, new JcaKeyFingerprintCalculator())); + ECDHPublicBCPGKey ecKey = (ECDHPublicBCPGKey)pubKey.getPublicKeyPacket().getKey(); String keyEncryptionOID = RFC6637Utils.getKeyEncryptionOID(ecKey.getSymmetricKeyAlgorithm()).getId(); - - if (ecKey.getCurveOID().equals(CryptlibObjectIdentifiers.curvey25519)) + PublicKeyPacket pubKeyPacket = pubKey.getPublicKeyPacket(); + if (JcaJcePGPUtil.isX25519(ecKey.getCurveOID())) { - KeyPairGenerator kpGen = helper.createKeyPairGenerator("X25519"); - kpGen.initialize(255, random); - - KeyPair ephKP = kpGen.generateKeyPair(); - - KeyAgreement agreement = helper.createKeyAgreement(RFC6637Utils.getXDHAlgorithm(pubKeyPacket)); - agreement.init(ephKP.getPrivate(), ukmSpec); - agreement.doPhase(cryptoPublicKey, true); - Key secret = agreement.generateSecret(keyEncryptionOID); - - SubjectPublicKeyInfo epPubKey = SubjectPublicKeyInfo.getInstance(ephKP.getPublic().getEncoded()); - byte[] ephPubEncoding = Arrays.prepend(epPubKey.getPublicKeyData().getBytes(), X_HDR); - - return encryptSessionInfo(ecKey, sessionInfo, secret, ephPubEncoding); + return getEncryptSessionInfo(pubKeyPacket, "X25519", cryptoPublicKey, keyEncryptionOID, + ecKey.getSymmetricKeyAlgorithm(), sessionInfo, RFC6637Utils.getXDHAlgorithm(pubKeyPacket), + (kpGen) -> kpGen.initialize(255, random), + (ephPubEncoding) -> Arrays.prepend(ephPubEncoding, X_HDR)); + } + else if (ecKey.getCurveOID().equals(EdECObjectIdentifiers.id_X448)) + { + return getEncryptSessionInfo(pubKeyPacket, "X448", cryptoPublicKey, keyEncryptionOID, + ecKey.getSymmetricKeyAlgorithm(), sessionInfo, RFC6637Utils.getXDHAlgorithm(pubKeyPacket), + (kpGen) -> kpGen.initialize(448, random), + (ephPubEncoding) -> Arrays.prepend(ephPubEncoding, X_HDR)); } else { - AlgorithmParameters ecAlgParams = helper.createAlgorithmParameters("EC"); - ecAlgParams.init(new X962Parameters(ecKey.getCurveOID()).getEncoded()); - - KeyPairGenerator kpGen = helper.createKeyPairGenerator("EC"); - kpGen.initialize(ecAlgParams.getParameterSpec(AlgorithmParameterSpec.class), random); - - KeyPair ephKP = kpGen.generateKeyPair(); - - KeyAgreement agreement = helper.createKeyAgreement(RFC6637Utils.getAgreementAlgorithm(pubKeyPacket)); - agreement.init(ephKP.getPrivate(), ukmSpec); - agreement.doPhase(cryptoPublicKey, true); - Key secret = agreement.generateSecret(keyEncryptionOID); - - SubjectPublicKeyInfo ephPubKey = SubjectPublicKeyInfo.getInstance(ephKP.getPublic().getEncoded()); - byte[] ephPubEncoding = ephPubKey.getPublicKeyData().getBytes(); - if (null == ephPubEncoding || ephPubEncoding.length < 1 || ephPubEncoding[0] != 0x04) - { - X9ECParameters x9Params = JcaJcePGPUtil.getX9Parameters(ecKey.getCurveOID()); - - ephPubEncoding = x9Params.getCurve().decodePoint(ephPubEncoding).getEncoded(false); - } - - return encryptSessionInfo(ecKey, sessionInfo, secret, ephPubEncoding); + return getEncryptSessionInfo(pubKeyPacket, "EC", cryptoPublicKey, keyEncryptionOID, + ecKey.getSymmetricKeyAlgorithm(), sessionInfo, RFC6637Utils.getAgreementAlgorithm(pubKeyPacket), + (kpGen) -> + { + AlgorithmParameters ecAlgParams = helper.createAlgorithmParameters("EC"); + ecAlgParams.init(new X962Parameters(ecKey.getCurveOID()).getEncoded()); + kpGen.initialize(ecAlgParams.getParameterSpec(AlgorithmParameterSpec.class), random); + }, (ephPubEncoding) -> + { + if (null == ephPubEncoding || ephPubEncoding.length < 1 || ephPubEncoding[0] != 0x04) + { + ephPubEncoding = JcaJcePGPUtil.getX9Parameters(ecKey.getCurveOID()).getCurve().decodePoint(ephPubEncoding).getEncoded(false); + } + return ephPubEncoding; + }); } } + else if (pubKey.getAlgorithm() == PublicKeyAlgorithmTags.X25519) + { + return getEncryptSessionInfo(pubKey, "X25519", cryptoPublicKey, NISTObjectIdentifiers.id_aes128_wrap.getId(), + SymmetricKeyAlgorithmTags.AES_128, sessionInfo, "X25519withSHA256HKDF", 255); + } + else if (pubKey.getAlgorithm() == PublicKeyAlgorithmTags.X448) + { + return getEncryptSessionInfo(pubKey, "X448", cryptoPublicKey, NISTObjectIdentifiers.id_aes256_wrap.getId(), + SymmetricKeyAlgorithmTags.AES_256, sessionInfo, "X448withSHA512HKDF", 448); + } else { Cipher c = helper.createPublicKeyCipher(pubKey.getAlgorithm()); @@ -179,21 +174,68 @@ protected byte[] encryptSessionInfo(PGPPublicKey pubKey, byte[] sessionInfo) } } - private byte[] encryptSessionInfo(ECDHPublicBCPGKey ecKey, byte[] sessionInfo, Key secret, byte[] ephPubEncoding) + @FunctionalInterface + private interface KeyPairGeneratorOperation + { + void initialize(KeyPairGenerator kpGen) + throws GeneralSecurityException, IOException; + } + + @FunctionalInterface + private interface EphPubEncoding + { + byte[] getEphPubEncoding(byte[] publicKeyData); + } + + private byte[] getEncryptSessionInfo(PublicKeyPacket pubKeyPacket, String algorithmName, PublicKey cryptoPublicKey, String keyEncryptionOID, + int symmetricKeyAlgorithm, byte[] sessionInfo, String agreementName, KeyPairGeneratorOperation kpOperation, + EphPubEncoding getEncoding) throws GeneralSecurityException, IOException, PGPException { + KeyPairGenerator kpGen = helper.createKeyPairGenerator(algorithmName); + kpOperation.initialize(kpGen); + KeyPair ephKP = kpGen.generateKeyPair(); + UserKeyingMaterialSpec ukmSpec = new UserKeyingMaterialSpec(RFC6637Utils.createUserKeyingMaterial(pubKeyPacket, + new JcaKeyFingerprintCalculator())); + Key secret = JcaJcePGPUtil.getSecret(helper, cryptoPublicKey, keyEncryptionOID, agreementName, ukmSpec, ephKP.getPrivate()); + byte[] ephPubEncoding = getEncoding.getEphPubEncoding(SubjectPublicKeyInfo.getInstance(ephKP.getPublic().getEncoded()).getPublicKeyData().getBytes()); byte[] paddedSessionData = PGPPad.padSessionData(sessionInfo, sessionKeyObfuscation); - Cipher c = helper.createKeyWrapper(ecKey.getSymmetricKeyAlgorithm()); - c.init(Cipher.WRAP_MODE, secret, random); - byte[] C = c.wrap(new SecretKeySpec(paddedSessionData, PGPUtil.getSymmetricCipherName(sessionInfo[0]))); + return getSessionInfo(ephPubEncoding, getWrapper(symmetricKeyAlgorithm, sessionInfo, secret, paddedSessionData)); + } - byte[] VB = new MPInteger(new BigInteger(1, ephPubEncoding)).getEncoded(); + /** + * Note that unlike ECDH, no checksum or padding are appended to the + * session key before key wrapping. Finally, note that unlike the other + * public-key algorithms, in the case of a v3 PKESK packet, the + * symmetric algorithm ID is not encrypted. Instead, it is prepended to + * the encrypted session key in plaintext. In this case, the symmetric + * algorithm used MUST be AES-128, AES-192 or AES-256 (algorithm ID 7, 8 + * or 9). + */ + private byte[] getEncryptSessionInfo(PGPPublicKey pgpPublicKey, String algorithmName, PublicKey cryptoPublicKey, String keyEncryptionOID, + int symmetricKeyAlgorithm, byte[] sessionInfo, String agreementAlgorithmName, int keySize) + throws GeneralSecurityException, IOException, PGPException + { + KeyPairGenerator kpGen = helper.createKeyPairGenerator(algorithmName); + kpGen.initialize(keySize, random); + KeyPair ephKP = kpGen.generateKeyPair(); + + byte[] ephPubEncoding = SubjectPublicKeyInfo.getInstance(ephKP.getPublic().getEncoded()).getPublicKeyData().getBytes(); + HybridValueParameterSpec ukmSpec = JcaJcePGPUtil.getHybridValueParameterSpecWithPrepend(ephPubEncoding, pgpPublicKey.getPublicKeyPacket(), algorithmName); + Key secret = JcaJcePGPUtil.getSecret(helper, cryptoPublicKey, keyEncryptionOID, agreementAlgorithmName, ukmSpec, ephKP.getPrivate()); + //No checksum or padding + byte[] sessionData = new byte[sessionInfo.length - 3]; + System.arraycopy(sessionInfo, 1, sessionData, 0, sessionData.length); + + return getSessionInfo(ephPubEncoding, sessionInfo[0], getWrapper(symmetricKeyAlgorithm, sessionInfo, secret, sessionData)); + } - byte[] rv = new byte[VB.length + 1 + C.length]; - System.arraycopy(VB, 0, rv, 0, VB.length); - rv[VB.length] = (byte)C.length; - System.arraycopy(C, 0, rv, VB.length + 1, C.length); - return rv; + private byte[] getWrapper(int symmetricKeyAlgorithm, byte[] sessionInfo, Key secret, byte[] sessionData) + throws PGPException, InvalidKeyException, IllegalBlockSizeException + { + Cipher c = helper.createKeyWrapper(symmetricKeyAlgorithm); + c.init(Cipher.WRAP_MODE, secret, random); + return c.wrap(new SecretKeySpec(sessionData, PGPUtil.getSymmetricCipherName(sessionInfo[0]))); } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceSessionKeyDataDecryptorFactoryBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceSessionKeyDataDecryptorFactoryBuilder.java index aaf496a018..357d3e9385 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceSessionKeyDataDecryptorFactoryBuilder.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceSessionKeyDataDecryptorFactoryBuilder.java @@ -2,6 +2,8 @@ import java.security.Provider; +import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; import org.bouncycastle.jcajce.util.NamedJcaJceHelper; import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; @@ -56,29 +58,44 @@ private static class JceSessionKeyDataDecryptorFactory implements SessionKeyDataDecryptorFactory { private final OperatorHelper helper; + private final JceAEADUtil aeadHelper; private final PGPSessionKey sessionKey; public JceSessionKeyDataDecryptorFactory(OperatorHelper helper, PGPSessionKey sessionKey) { this.helper = helper; + this.aeadHelper = new JceAEADUtil(helper); this.sessionKey = sessionKey; } + @Override public PGPSessionKey getSessionKey() { return sessionKey; } + // OpenPGP v4 + @Override public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { return helper.createDataDecryptor(withIntegrityPacket, encAlgorithm, key); } - public PGPDataDecryptor createDataDecryptor(int aeadAlgorithm, byte[] iv, int chunkSize, int encAlgorithm, byte[] key) + // OpenPGP v5 + @Override + public PGPDataDecryptor createDataDecryptor(AEADEncDataPacket aeadEncDataPacket, PGPSessionKey sessionKey) throws PGPException { - return helper.createDataDecryptor(aeadAlgorithm, iv, chunkSize, encAlgorithm, key); + return aeadHelper.createOpenPgpV5DataDecryptor(aeadEncDataPacket, sessionKey); + } + + // OpenPGP v6 + @Override + public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, PGPSessionKey sessionKey) + throws PGPException + { + return aeadHelper.createOpenPgpV6DataDecryptor(seipd, sessionKey); } } } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/OperatorHelper.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/OperatorHelper.java index 75a4b398d4..319c6164b9 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/OperatorHelper.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/OperatorHelper.java @@ -1,8 +1,6 @@ package org.bouncycastle.openpgp.operator.jcajce; -import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.KeyFactory; @@ -15,13 +13,10 @@ import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; -import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; -import org.bouncycastle.bcpg.AEADAlgorithmTags; import org.bouncycastle.bcpg.HashAlgorithmTags; -import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.jcajce.io.CipherInputStream; @@ -31,10 +26,6 @@ import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.Exceptions; -import org.bouncycastle.util.Pack; -import org.bouncycastle.util.io.Streams; class OperatorHelper { @@ -45,57 +36,22 @@ class OperatorHelper this.helper = helper; } - /** - * Return an appropriate name for the hash algorithm represented by the passed - * in hash algorithm ID number (JCA message digest naming convention). - * - * @param hashAlgorithm the algorithm ID for a hash algorithm. - * @return a String representation of the hash name. - */ - String getDigestName( - int hashAlgorithm) - throws PGPException - { - switch (hashAlgorithm) - { - case HashAlgorithmTags.SHA1: - return "SHA-1"; - case HashAlgorithmTags.MD2: - return "MD2"; - case HashAlgorithmTags.MD5: - return "MD5"; - case HashAlgorithmTags.RIPEMD160: - return "RIPEMD160"; - case HashAlgorithmTags.SHA256: - return "SHA-256"; - case HashAlgorithmTags.SHA384: - return "SHA-384"; - case HashAlgorithmTags.SHA512: - return "SHA-512"; - case HashAlgorithmTags.SHA224: - return "SHA-224"; - case HashAlgorithmTags.TIGER_192: - return "TIGER"; - default: - throw new PGPException("unknown hash algorithm tag in getDigestName: " + hashAlgorithm); - } - } - MessageDigest createDigest(int algorithm) throws GeneralSecurityException, PGPException { MessageDigest dig; - String digestName = getDigestName(algorithm); + String digestName = PGPUtil.getDigestName(algorithm); try { dig = helper.createMessageDigest(digestName); } catch (NoSuchAlgorithmException e) { - if (algorithm >= HashAlgorithmTags.SHA256 && algorithm <= HashAlgorithmTags.SHA224) + if (algorithm == HashAlgorithmTags.SHA1 + || (algorithm >= HashAlgorithmTags.SHA256 && algorithm <= HashAlgorithmTags.SHA224)) { - dig = helper.createMessageDigest("SHA" + digestName.substring(4)); + dig = helper.createMessageDigest("SHA-" + digestName.substring(3)); } else { @@ -124,6 +80,8 @@ public KeyPairGenerator createKeyPairGenerator(String algorithm) return helper.createKeyPairGenerator(algorithm); } + // OpenPGP V4 + // SED or SEIPD v1 decryption PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { @@ -135,9 +93,7 @@ PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorit if (withIntegrityPacket) { - byte[] iv = new byte[c.getBlockSize()]; - - c.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); + c.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(new byte[c.getBlockSize()])); } else { @@ -185,103 +141,6 @@ Cipher createStreamCipher(int encAlgorithm, boolean withIntegrityPacket) return createCipher(cName); } - static long getChunkLength(int chunkSize) - { - return 1L << (chunkSize + 6); - } - - static byte[] getNonce(byte[] iv, long chunkIndex) - { - byte[] nonce = Arrays.clone(iv); - - xorChunkId(nonce, chunkIndex); - - return nonce; - } - - static void xorChunkId(byte[] nonce, long chunkIndex) - { - int index = nonce.length - 8; - - nonce[index++] ^= (byte)(chunkIndex >> 56); - nonce[index++] ^= (byte)(chunkIndex >> 48); - nonce[index++] ^= (byte)(chunkIndex >> 40); - nonce[index++] ^= (byte)(chunkIndex >> 32); - nonce[index++] ^= (byte)(chunkIndex >> 24); - nonce[index++] ^= (byte)(chunkIndex >> 16); - nonce[index++] ^= (byte)(chunkIndex >> 8); - nonce[index] ^= (byte)(chunkIndex); - } - - PGPDataDecryptor createDataDecryptor(final int aeadAlgorithm, final byte[] iv, final int chunkSize, final int encAlgorithm, byte[] key) - throws PGPException - { - try - { - final SecretKey secretKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); - - final Cipher c = createAEADCipher(encAlgorithm, aeadAlgorithm); - - return new PGPDataDecryptor() - { - public InputStream getInputStream(InputStream in) - { - try - { - return new PGPAeadInputStream(in, c, secretKey, iv, encAlgorithm, aeadAlgorithm, chunkSize); - } - catch (IOException e) - { - throw Exceptions.illegalStateException("unable to open stream: " + e.getMessage(), e); - } - } - - public int getBlockSize() - { - return c.getBlockSize(); - } - - public PGPDigestCalculator getIntegrityCalculator() - { - return new SHA1PGPDigestCalculator(); - } - }; - } - catch (PGPException e) - { - throw e; - } - catch (Exception e) - { - throw new PGPException("Exception creating cipher", e); - } - } - - Cipher createAEADCipher(int encAlgorithm, int aeadAlgorithm) - throws PGPException - { - String mode; - switch (aeadAlgorithm) - { - case AEADAlgorithmTags.EAX: - mode = "EAX"; - break; - case AEADAlgorithmTags.OCB: - mode = "OCB"; - break; - case AEADAlgorithmTags.GCM: - mode = "GCM"; - break; - default: - throw new PGPException("encountered unknown AEAD algorithm: " + aeadAlgorithm); - } - - String cName = PGPUtil.getSymmetricCipherName(encAlgorithm) - + "/" + mode + "/NoPadding"; - - return createCipher(cName); - } - Cipher createCipher(String cipherName) throws PGPException { @@ -311,6 +170,8 @@ Cipher createPublicKeyCipher(int encAlgorithm) case PGPPublicKey.ECDSA: throw new PGPException("Can't use ECDSA for encryption."); case PGPPublicKey.EDDSA_LEGACY: + case PGPPublicKey.Ed448: + case PGPPublicKey.Ed25519: throw new PGPException("Can't use EDDSA for encryption."); default: throw new PGPException("unknown asymmetric algorithm: " + encAlgorithm); @@ -342,7 +203,7 @@ Cipher createKeyWrapper(int encAlgorithm) } } - private Signature createSignature(String cipherName) + Signature createSignature(String cipherName) throws PGPException { try @@ -377,7 +238,10 @@ public Signature createSignature(int keyAlgorithm, int hashAlgorithm) encAlg = "ECDSA"; break; case PublicKeyAlgorithmTags.EDDSA_LEGACY: + case PublicKeyAlgorithmTags.Ed25519: return createSignature("Ed25519"); + case PublicKeyAlgorithmTags.Ed448: + return createSignature("Ed448"); default: throw new PGPException("unknown algorithm tag in signature:" + keyAlgorithm); } @@ -385,329 +249,10 @@ public Signature createSignature(int keyAlgorithm, int hashAlgorithm) return createSignature(PGPUtil.getDigestName(hashAlgorithm) + "with" + encAlg); } + public AlgorithmParameters createAlgorithmParameters(String algorithm) throws NoSuchProviderException, NoSuchAlgorithmException { return helper.createAlgorithmParameters(algorithm); } - - private static class PGPAeadInputStream - extends InputStream - { - private final InputStream in; - private final byte[] buf; - private final Cipher c; - private final SecretKey secretKey; - private final byte[] aaData; - private final byte[] iv; - private final int chunkLength; - - private byte[] data; - private int dataOff; - private long chunkIndex = 0; - private long totalBytes = 0; - - public PGPAeadInputStream(InputStream in, Cipher c, SecretKey secretKey, byte[] iv, int encAlgorithm, int aeadAlgorithm, int chunkSize) - throws IOException - { - this.in = in; - this.iv = iv; - this.chunkLength = (int)getChunkLength(chunkSize); - this.buf = new byte[chunkLength + 32]; // allow room for chunk tag and message tag - this.c = c; - this.secretKey = secretKey; - - aaData = new byte[5]; - - aaData[0] = (byte)(0xC0 | PacketTags.AEAD_ENC_DATA); - aaData[1] = 0x01; // packet version - aaData[2] = (byte)encAlgorithm; - aaData[3] = (byte)aeadAlgorithm; - aaData[4] = (byte)chunkSize; - - // prime with 2 * tag len bytes. - Streams.readFully(in, buf, 0, 32); - - // load the first block - this.data = readBlock(); - this.dataOff = 0; - } - - public int read() - throws IOException - { - if (data != null && dataOff == data.length) - { - this.data = readBlock(); - this.dataOff = 0; - } - - if (this.data == null) - { - return -1; - } - - return data[dataOff++] & 0xff; - } - - public int read(byte[] b, int off, int len) - throws IOException - { - if (data != null && dataOff == data.length) - { - this.data = readBlock(); - this.dataOff = 0; - } - - if (this.data == null) - { - return -1; - } - - int supplyLen = Math.min(len, available()); - System.arraycopy(data, dataOff, b, off, supplyLen); - dataOff += supplyLen; - - return supplyLen; - } - - public long skip(long n) - throws IOException - { - if (n <= 0) - { - return 0; - } - - int skip = (int)Math.min(n, available()); - dataOff += skip; - return skip; - } - - public int available() - throws IOException - { - if (data != null && dataOff == data.length) - { - this.data = readBlock(); - this.dataOff = 0; - } - - if (this.data == null) - { - return -1; - } - - return data.length - dataOff; - } - - private byte[] readBlock() - throws IOException - { - // we initialise with the first 16 bytes as there is an additional 16 bytes following - // the last chunk (which may not be the exact chunklength). - int dataLen = Streams.readFully(in, buf, 32, chunkLength); - if (dataLen == 0) - { - return null; - } - - byte[] adata = new byte[13]; - System.arraycopy(aaData, 0, adata, 0, aaData.length); - - xorChunkId(adata, chunkIndex); - - byte[] decData; - try - { - c.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(128, getNonce(iv, chunkIndex))); // always full tag. - - c.updateAAD(adata); - - decData = c.doFinal(buf, 0, dataLen + 16); - } - catch (GeneralSecurityException e) - { - throw new IOException("exception processing chunk " + chunkIndex + ": " + e.getMessage()); - } - - totalBytes += decData.length; - chunkIndex++; - - System.arraycopy(buf, dataLen + 16, buf, 0, 16); // copy back the "tag" - - if (dataLen != chunkLength) // it's our last block - { - adata = new byte[13]; - - System.arraycopy(aaData, 0, adata, 0, aaData.length); - - xorChunkId(adata, chunkIndex); - try - { - c.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(128, getNonce(iv, chunkIndex))); - - c.updateAAD(adata); - c.updateAAD(Pack.longToBigEndian(totalBytes)); - - c.doFinal(buf, 0, 16); // check final tag - } - catch (GeneralSecurityException e) - { - throw new IOException("exception processing final tag: " + e.getMessage()); - } - } - else - { - Streams.readFully(in, buf, 16, 16); // read the next tag bytes - } - - return decData; - } - } - - static class PGPAeadOutputStream - extends OutputStream - { - private final OutputStream out; - private final byte[] data; - private final Cipher c; - private final SecretKey secretKey; - private final byte[] aaData; - private final byte[] iv; - private final int chunkLength; - - private int dataOff; - private long chunkIndex = 0; - private long totalBytes = 0; - - public PGPAeadOutputStream(OutputStream out, Cipher c, SecretKey secretKey, int encAlgorithm, int aeadAlgorithm, int chunkSize, byte[] iv) - { - this.out = out; - this.iv = iv; - this.chunkLength = (int)getChunkLength(chunkSize); - this.data = new byte[chunkLength]; - this.c = c; - this.secretKey = secretKey; - - aaData = new byte[5]; - - aaData[0] = (byte)(0xC0 | PacketTags.AEAD_ENC_DATA); - aaData[1] = 0x01; // packet version - aaData[2] = (byte)encAlgorithm; - aaData[3] = (byte)aeadAlgorithm; - aaData[4] = (byte)chunkSize; - } - - public void write(int b) - throws IOException - { - if (dataOff == data.length) - { - writeBlock(); - } - data[dataOff++] = (byte)b; - } - - public void write(byte[] b, int off, int len) - throws IOException - { - if (dataOff == data.length) - { - writeBlock(); - } - - if (len < data.length - dataOff) - { - System.arraycopy(b, off, data, dataOff, len); - dataOff += len; - } - else - { - int gap = data.length - dataOff; - System.arraycopy(b, off, data, dataOff, gap); - dataOff += gap; - writeBlock(); - - len -= gap; - off += gap; - - while (len >= data.length) - { - System.arraycopy(b, off, data, 0, data.length); - dataOff = data.length; - writeBlock(); - len -= data.length; - off += data.length; - } - - if (len > 0) - { - System.arraycopy(b, off, data, 0, len); - dataOff = len; - } - } - } - - public void close() - throws IOException - { - finish(); - } - - private void writeBlock() - throws IOException - { - byte[] adata = new byte[13]; - System.arraycopy(aaData, 0, adata, 0, aaData.length); - - xorChunkId(adata, chunkIndex); - - try - { - c.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(128, getNonce(iv, chunkIndex))); // always full tag. - - c.updateAAD(adata); - - out.write(c.doFinal(data, 0, dataOff)); - } - catch (GeneralSecurityException e) - { - throw new IOException("exception processing chunk " + chunkIndex + ": " + e.getMessage()); - } - - totalBytes += dataOff; - chunkIndex++; - dataOff = 0; - } - - private void finish() - throws IOException - { - if (dataOff > 0) - { - writeBlock(); - } - - byte[] adata = new byte[13]; - System.arraycopy(aaData, 0, adata, 0, aaData.length); - - xorChunkId(adata, chunkIndex); - try - { - c.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(128, getNonce(iv, chunkIndex))); - - c.updateAAD(adata); - c.updateAAD(Pack.longToBigEndian(totalBytes)); - - out.write(c.doFinal(aaData, 0, 0)); // output final tag - - out.close(); - } - catch (GeneralSecurityException e) - { - throw new IOException("exception processing final tag: " + e.getMessage()); - } - } - } } diff --git a/pg/src/main/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JcaJcePGPUtil.java b/pg/src/main/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JcaJcePGPUtil.java new file mode 100644 index 0000000000..ff57c65240 --- /dev/null +++ b/pg/src/main/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JcaJcePGPUtil.java @@ -0,0 +1,95 @@ +package org.bouncycastle.openpgp.operator.jcajce; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.GeneralSecurityException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.Key; +import java.security.PublicKey; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.KeyAgreement; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.x9.ECNamedCurveTable; +import org.bouncycastle.asn1.x9.X9ECParameters; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.crypto.ec.CustomNamedCurves; +import org.bouncycastle.jcajce.spec.HybridValueParameterSpec; +import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec; +import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.BigIntegers; +import org.bouncycastle.util.Strings; + +/** + * Basic utility class + */ +class JcaJcePGPUtil +{ + public static SecretKey makeSymmetricKey( + int algorithm, + byte[] keyBytes) + throws PGPException + { + String algName = org.bouncycastle.openpgp.PGPUtil.getSymmetricCipherName(algorithm); + + if (algName == null) + { + throw new PGPException("unknown symmetric algorithm: " + algorithm); + } + + return new SecretKeySpec(keyBytes, algName); + } + + static ECPoint decodePoint( + BigInteger encodedPoint, + ECCurve curve) + throws IOException + { + return curve.decodePoint(BigIntegers.asUnsignedByteArray(encodedPoint)); + } + + static X9ECParameters getX9Parameters(ASN1ObjectIdentifier curveOID) + { + X9ECParameters x9Params = CustomNamedCurves.getByOID(curveOID); + + if (x9Params == null) + { + return ECNamedCurveTable.getByOID(curveOID); + } + + return x9Params; + } + + static HybridValueParameterSpec getHybridValueParameterSpecWithPrepend(byte[] ephmeralPublicKey, PublicKeyPacket pkp, String algorithmName) + throws IOException + { + return new HybridValueParameterSpec(Arrays.concatenate(ephmeralPublicKey, pkp.getEncoded()), true, new UserKeyingMaterialSpec(Strings.toByteArray("OpenPGP " + algorithmName))); + } + + static Key getSecret(OperatorHelper helper, PublicKey cryptoPublicKey, String keyEncryptionOID, String agreementName, AlgorithmParameterSpec ukmSpec, Key privKey) + throws GeneralSecurityException + { + try + { + KeyAgreement agreement = helper.createKeyAgreement(agreementName); + agreement.init(privKey, ukmSpec); + agreement.doPhase(cryptoPublicKey, true); + return agreement.generateSecret(keyEncryptionOID); + } + catch (InvalidKeyException e) + { + throw new GeneralSecurityException(e.toString()); + } + catch (NoSuchAlgorithmException e) + { + throw new GeneralSecurityException(e.toString()); + } + } +} diff --git a/pg/src/main/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JceAEADUtil.java b/pg/src/main/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JceAEADUtil.java new file mode 100644 index 0000000000..cb1936c4ac --- /dev/null +++ b/pg/src/main/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JceAEADUtil.java @@ -0,0 +1,679 @@ +package org.bouncycastle.openpgp.operator.jcajce; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.GeneralSecurityException; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import org.bouncycastle.bcpg.AEADAlgorithmTags; +import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.AEADUtils; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyUtils; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.params.HKDFParameters; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPSessionKey; +import org.bouncycastle.openpgp.PGPUtil; +import org.bouncycastle.openpgp.operator.PGPDataDecryptor; +import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Exceptions; +import org.bouncycastle.util.Pack; +import org.bouncycastle.util.io.Streams; + +class JceAEADUtil +{ + private final OperatorHelper helper; + + public JceAEADUtil(OperatorHelper helper) + { + this.helper = helper; + } + + /** + * Generate a nonce by xor-ing the given iv with the chunk index. + * + * @param iv initialization vector + * @param chunkIndex chunk index + * @return nonce + */ + protected static byte[] getNonce(byte[] iv, long chunkIndex) + { + byte[] nonce = Arrays.clone(iv); + + xorChunkId(nonce, chunkIndex); + + return nonce; + } + + /** + * XOR the byte array with the chunk index in-place. + * + * @param nonce byte array + * @param chunkIndex chunk index + */ + protected static void xorChunkId(byte[] nonce, long chunkIndex) + { + int index = nonce.length - 8; + + nonce[index++] ^= (byte)(chunkIndex >> 56); + nonce[index++] ^= (byte)(chunkIndex >> 48); + nonce[index++] ^= (byte)(chunkIndex >> 40); + nonce[index++] ^= (byte)(chunkIndex >> 32); + nonce[index++] ^= (byte)(chunkIndex >> 24); + nonce[index++] ^= (byte)(chunkIndex >> 16); + nonce[index++] ^= (byte)(chunkIndex >> 8); + nonce[index] ^= (byte)(chunkIndex); + } + + /** + * Calculate an actual chunk length from the encoded chunk size. + * + * @param chunkSize encoded chunk size + * @return decoded length + */ + protected static long getChunkLength(int chunkSize) + { + return 1L << (chunkSize + 6); + } + + /** + * Derive a message key and IV from the given session key. + * The result is two byte arrays containing the key bytes and the IV. + * + * @param aeadAlgo AEAD algorithm + * @param cipherAlgo symmetric cipher algorithm + * @param sessionKey session key + * @param salt salt + * @param hkdfInfo HKDF info + * @return message key and separate IV + * @throws PGPException + */ + static byte[][] deriveMessageKeyAndIv(int aeadAlgo, int cipherAlgo, byte[] sessionKey, byte[] salt, byte[] hkdfInfo) + throws PGPException + { + // TODO: needs to be JCA based. KeyGenerator? + HKDFParameters hkdfParameters = new HKDFParameters(sessionKey, salt, hkdfInfo); + HKDFBytesGenerator hkdfGen = new HKDFBytesGenerator(new SHA256Digest()); + + hkdfGen.init(hkdfParameters); + int keyLen = SymmetricKeyUtils.getKeyLengthInOctets(cipherAlgo); + int ivLen = AEADUtils.getIVLength(aeadAlgo); + byte[] messageKeyAndIv = new byte[keyLen + ivLen - 8]; + hkdfGen.generateBytes(messageKeyAndIv, 0, messageKeyAndIv.length); + + return new byte[][] { Arrays.copyOfRange(messageKeyAndIv, 0, keyLen), Arrays.copyOfRange(messageKeyAndIv, keyLen, keyLen + ivLen) }; + } + + /** + * Create a {@link PGPDataDecryptor} for decrypting AEAD encrypted OpenPGP v5 data packets. + * + * @param aeadEncDataPacket AEAD encrypted data packet + * @param sessionKey session key to decrypt the data + * @return decryptor + * @throws PGPException + */ + PGPDataDecryptor createOpenPgpV5DataDecryptor(AEADEncDataPacket aeadEncDataPacket, + PGPSessionKey sessionKey) + throws PGPException + { + final int aeadAlgorithm = aeadEncDataPacket.getAEADAlgorithm(); + final byte[] iv = aeadEncDataPacket.getIV(); + final int chunkSize = aeadEncDataPacket.getChunkSize(); + final int encAlgorithm = sessionKey.getAlgorithm(); + final byte[] key = sessionKey.getKey(); + final byte[] aaData = aeadEncDataPacket.getAAData(); + try + { + final SecretKey secretKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); + + final Cipher c = createAEADCipher(encAlgorithm, aeadAlgorithm); + + return new PGPDataDecryptor() + { + public InputStream getInputStream(InputStream in) + { + try + { + return new JceAEADUtil.PGPAeadInputStream(true, in, c, secretKey, iv, encAlgorithm, aeadAlgorithm, chunkSize, aaData); + } + catch (IOException e) + { + throw Exceptions.illegalStateException("unable to open stream: " + e.getMessage(), e); + } + } + + public int getBlockSize() + { + return c.getBlockSize(); + } + + public PGPDigestCalculator getIntegrityCalculator() + { + return new SHA1PGPDigestCalculator(); + } + }; + } + catch (PGPException e) + { + throw e; + } + catch (Exception e) + { + throw new PGPException("Exception creating cipher", e); + } + } + + /** + * Create a {@link PGPDataDecryptor} for decrypting AEAD encrypted OpenPGP v6 data. + * + * @param seipd version 2 SEIPD packet + * @param sessionKey session key to decrypt the data + * @return decryptor + * @throws PGPException + */ + PGPDataDecryptor createOpenPgpV6DataDecryptor(SymmetricEncIntegrityPacket seipd, + PGPSessionKey sessionKey) + throws PGPException + { + final int cipherAlgo = seipd.getCipherAlgorithm(); + final int aeadAlgo = seipd.getAeadAlgorithm(); + final int chunkSize = seipd.getChunkSize(); + final byte[] salt = seipd.getSalt(); + final byte[] aaData = seipd.getAAData(); + + + final byte[][] messageKeyAndIv = deriveMessageKeyAndIv(aeadAlgo, cipherAlgo, sessionKey.getKey(), salt, aaData); + final byte[] messageKey = messageKeyAndIv[0]; + final byte[] iv = messageKeyAndIv[1]; + + try + { + final SecretKey secretKey = new SecretKeySpec(messageKey, PGPUtil.getSymmetricCipherName(cipherAlgo)); + final Cipher c = createAEADCipher(cipherAlgo, aeadAlgo); + + return new PGPDataDecryptor() + { + public InputStream getInputStream(InputStream in) + { + try + { + return new JceAEADUtil.PGPAeadInputStream(false, in, c, secretKey, iv, cipherAlgo, aeadAlgo, chunkSize, aaData); + } + catch (IOException e) + { + throw Exceptions.illegalStateException("unable to open stream: " + e.getMessage(), e); + } + } + + public int getBlockSize() + { + return c.getBlockSize(); + } + + public PGPDigestCalculator getIntegrityCalculator() + { + return new SHA1PGPDigestCalculator(); + } + }; + } + catch (PGPException e) + { + throw e; + } + catch (Exception e) + { + throw new PGPException("Exception creating cipher", e); + } + } + + Cipher createAEADCipher(int encAlgorithm, int aeadAlgorithm) + throws PGPException + { + if (encAlgorithm != SymmetricKeyAlgorithmTags.AES_128 + && encAlgorithm != SymmetricKeyAlgorithmTags.AES_192 + && encAlgorithm != SymmetricKeyAlgorithmTags.AES_256) + { + // Block Cipher must work on 16 byte blocks + throw new PGPException("AEAD only supported for AES based algorithms"); + } + + String mode; + switch (aeadAlgorithm) + { + case AEADAlgorithmTags.EAX: + mode = "EAX"; + break; + case AEADAlgorithmTags.OCB: + mode = "OCB"; + break; + case AEADAlgorithmTags.GCM: + mode = "GCM"; + break; + default: + throw new PGPException("encountered unknown AEAD algorithm: " + aeadAlgorithm); + } + + String cName = PGPUtil.getSymmetricCipherName(encAlgorithm) + + "/" + mode + "/NoPadding"; + + return helper.createCipher(cName); + } + + + static class PGPAeadInputStream + extends InputStream + { + private final InputStream in; + private final byte[] buf; + private final Cipher c; + private final SecretKey secretKey; + private final byte[] aaData; + private final byte[] iv; + private final int chunkLength; + private final int aeadTagLength; + + private byte[] data; + private int dataOff; + private long chunkIndex = 0; + private long totalBytes = 0; + private boolean v5StyleAEAD; + + /** + * InputStream for decrypting AEAD encrypted data. + * + * @param isV5AEAD AEAD flavour (OpenPGP v5 or v6) + * @param in underlying input stream + * @param c AEAD cipher + * @param secretKey secret key + * @param iv initialization vector + * @param encAlgorithm encryption algorithm + * @param aeadAlgorithm AEAD algorithm + * @param chunkSize chunk size of the AEAD encryption + * @param aaData associated data + * @throws IOException + */ + public PGPAeadInputStream(boolean isV5AEAD, InputStream in, + Cipher c, + SecretKey secretKey, + byte[] iv, + int encAlgorithm, + int aeadAlgorithm, + int chunkSize, + byte[] aaData) + throws IOException + { + this.v5StyleAEAD = isV5AEAD; + this.in = in; + this.iv = iv; + this.chunkLength = (int)getChunkLength(chunkSize); + this.aeadTagLength = AEADUtils.getAuthTagLength(aeadAlgorithm); + this.buf = new byte[chunkLength + aeadTagLength + aeadTagLength]; // allow room for chunk tag and message tag + this.c = c; + this.secretKey = secretKey; + this.aaData = aaData; + + // prime with 2 * tag len bytes. + Streams.readFully(in, buf, 0, aeadTagLength + aeadTagLength); + + // load the first block + this.data = readBlock(); + this.dataOff = 0; + } + + public int read() + throws IOException + { + if (data != null && dataOff == data.length) + { + this.data = readBlock(); + this.dataOff = 0; + } + + if (this.data == null) + { + return -1; + } + + return data[dataOff++] & 0xff; + } + + public int read(byte[] b, int off, int len) + throws IOException + { + if (data != null && dataOff == data.length) + { + this.data = readBlock(); + this.dataOff = 0; + } + + if (this.data == null) + { + return -1; + } + + int supplyLen = Math.min(len, available()); + System.arraycopy(data, dataOff, b, off, supplyLen); + dataOff += supplyLen; + + return supplyLen; + } + + public long skip(long n) + throws IOException + { + if (n <= 0) + { + return 0; + } + + int skip = (int)Math.min(n, available()); + dataOff += skip; + return skip; + } + + public int available() + throws IOException + { + if (data != null && dataOff == data.length) + { + this.data = readBlock(); + this.dataOff = 0; + } + + if (this.data == null) + { + return -1; + } + + return data.length - dataOff; + } + + private byte[] readBlock() + throws IOException + { + // we initialise with the first 16 bytes as there is an additional 16 bytes following + // the last chunk (which may not be the exact chunklength). + int dataLen = Streams.readFully(in, buf, aeadTagLength + aeadTagLength, chunkLength); + if (dataLen == 0) + { + return null; + } + + byte[] adata = new byte[v5StyleAEAD ? 13 : aaData.length]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + if (v5StyleAEAD) + { + xorChunkId(adata, chunkIndex); + } + + byte[] decData; + try + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.DECRYPT_MODE, getNonce(iv, chunkIndex), 128, adata); + + decData = c.doFinal(buf, 0, dataLen + aeadTagLength); + } + catch (Exception e) + { + throw new IOException("exception processing chunk " + chunkIndex + ": " + e.getMessage()); + } + + totalBytes += decData.length; + chunkIndex++; + + System.arraycopy(buf, dataLen + aeadTagLength, buf, 0, aeadTagLength); // copy back the "tag" + + if (dataLen != chunkLength) // it's our last block + { + if (v5StyleAEAD) + { + adata = new byte[13]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + xorChunkId(adata, chunkIndex); + } + else + { + adata = new byte[aaData.length + 8]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + System.arraycopy(Pack.longToBigEndian(totalBytes), 0, adata, aaData.length, 8); + } + try + { + if (v5StyleAEAD) + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.DECRYPT_MODE, getNonce(iv, chunkIndex), 128, Arrays.concatenate(adata, Pack.longToBigEndian(totalBytes))); + } + else + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.DECRYPT_MODE, getNonce(iv, chunkIndex), 128, adata); + } + + c.doFinal(buf, 0, aeadTagLength); // check final tag + } + catch (Exception e) + { + throw new IOException("exception processing final tag: " + e.getMessage()); + } + } + else + { + Streams.readFully(in, buf, aeadTagLength, aeadTagLength); // read the next tag bytes + } + + return decData; + } + } + + static class PGPAeadOutputStream + extends OutputStream + { + private final boolean isV5AEAD; + private final OutputStream out; + private final byte[] data; + private final Cipher c; + private final SecretKey secretKey; + private final byte[] aaData; + private final byte[] iv; + private final int chunkLength; + + private int dataOff; + private long chunkIndex = 0; + private long totalBytes = 0; + + /** + * OutputStream for AEAD encryption. + * + * @param isV5AEAD isV5AEAD of AEAD (OpenPGP v5 or v6) + * @param out underlying OutputStream + * @param c AEAD cipher + * @param secretKey secret key + * @param iv initialization vector + * @param encAlgorithm encryption algorithm + * @param aeadAlgorithm AEAD algorithm + * @param chunkSize chunk size of the AEAD algorithm + */ + public PGPAeadOutputStream(boolean isV5AEAD, + OutputStream out, + Cipher c, + SecretKey secretKey, + byte[] iv, + int encAlgorithm, + int aeadAlgorithm, + int chunkSize) + { + this.isV5AEAD = isV5AEAD; + this.out = out; + this.iv = iv; + this.chunkLength = (int)getChunkLength(chunkSize); + this.data = new byte[chunkLength]; + this.c = c; + this.secretKey = secretKey; + + this.aaData = createAAD(isV5AEAD, encAlgorithm, aeadAlgorithm, chunkSize); + } + + /** + * Create the associated data for the AEAD encryption. + * Since the associated data array differs between OpenPGP v5 and v6, we need to know the flavour. + * + * @param isV5AEAD true if flavour of AEAD OpenPGP v5 + * @param encAlgorithm symmetric encryption algorithm + * @param aeadAlgorithm AEAD algorithm + * @param chunkSize chunk size + * @return associated data + */ + private byte[] createAAD(boolean isV5AEAD, int encAlgorithm, int aeadAlgorithm, int chunkSize) + { + if (isV5AEAD) + { + return AEADEncDataPacket.createAAData(AEADEncDataPacket.VERSION_1, + encAlgorithm, aeadAlgorithm, chunkSize); + } + else + { + return SymmetricEncIntegrityPacket.createAAData(SymmetricEncIntegrityPacket.VERSION_2, + encAlgorithm, aeadAlgorithm, chunkSize); + } + } + + public void write(int b) + throws IOException + { + if (dataOff == data.length) + { + writeBlock(); + } + data[dataOff++] = (byte)b; + } + + public void write(byte[] b, int off, int len) + throws IOException + { + if (dataOff == data.length) + { + writeBlock(); + } + + if (len < data.length - dataOff) + { + System.arraycopy(b, off, data, dataOff, len); + dataOff += len; + } + else + { + int gap = data.length - dataOff; + System.arraycopy(b, off, data, dataOff, gap); + dataOff += gap; + writeBlock(); + + len -= gap; + off += gap; + + while (len >= data.length) + { + System.arraycopy(b, off, data, 0, data.length); + dataOff = data.length; + writeBlock(); + len -= data.length; + off += data.length; + } + + if (len > 0) + { + System.arraycopy(b, off, data, 0, len); + dataOff = len; + } + } + } + + public void close() + throws IOException + { + finish(); + } + + private void writeBlock() + throws IOException + { + byte[] adata = isV5AEAD ? new byte[13] : new byte[aaData.length]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + if (isV5AEAD) + { + xorChunkId(adata, chunkIndex); + } + + try + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.ENCRYPT_MODE, getNonce(iv, chunkIndex), 128, adata); + + out.write(c.doFinal(data, 0, dataOff)); + } + catch (IOException e) + { + throw e; + } + catch (Exception e) + { + throw new IOException("exception processing chunk " + chunkIndex + ": " + e.getMessage()); + } + + totalBytes += dataOff; + chunkIndex++; + dataOff = 0; + } + + private void finish() + throws IOException + { + if (dataOff > 0) + { + writeBlock(); + } + + byte[] adata; + if (isV5AEAD) + { + adata = new byte[13]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + xorChunkId(adata, chunkIndex); + } + else + { + adata = new byte[aaData.length + 8]; + System.arraycopy(aaData, 0, adata, 0, aaData.length); + System.arraycopy(Pack.longToBigEndian(totalBytes), 0, adata, aaData.length, 8); + } + + try + { + if (isV5AEAD) + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.ENCRYPT_MODE, getNonce(iv, chunkIndex), 128, Arrays.concatenate(adata, Pack.longToBigEndian(totalBytes))); + } + else + { + JceAEADCipherUtil.setUpAeadCipher(c, secretKey, Cipher.ENCRYPT_MODE, getNonce(iv, chunkIndex), 128, adata); + } + + out.write(c.doFinal(aaData, 0, 0)); // output final tag + } + catch (IOException e) + { + throw e; + } + catch (Exception e) + { + throw new IOException("exception processing final tag: " + e.getMessage()); + } + out.close(); + } + } +} diff --git a/pg/src/main/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JcePBEDataDecryptorFactoryBuilder.java b/pg/src/main/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JcePBEDataDecryptorFactoryBuilder.java new file mode 100644 index 0000000000..3a18b39f70 --- /dev/null +++ b/pg/src/main/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JcePBEDataDecryptorFactoryBuilder.java @@ -0,0 +1,211 @@ +package org.bouncycastle.openpgp.operator.jcajce; + +import java.security.GeneralSecurityException; +import java.security.Provider; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; +import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket; +import org.bouncycastle.bcpg.SymmetricKeyUtils; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.params.HKDFParameters; +import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; +import org.bouncycastle.jcajce.util.NamedJcaJceHelper; +import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPSessionKey; +import org.bouncycastle.openpgp.PGPUtil; +import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.PGPDataDecryptor; +import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; + +/** + * Builder for {@link PBEDataDecryptorFactory} instances that obtain cryptographic primitives using + * the JCE API. + */ +public class JcePBEDataDecryptorFactoryBuilder +{ + private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); + private JceAEADUtil aeadHelper = new JceAEADUtil(helper); + private PGPDigestCalculatorProvider calculatorProvider; + + /** + * Base constructor - assume the required digest calculators can be provided from the same source as + * the cipher needed. + */ + public JcePBEDataDecryptorFactoryBuilder() + { + this.calculatorProvider = null; + } + + /** + * Base constructor. + * + * @param calculatorProvider a digest calculator provider to provide calculators to support the key generation calculation required. + */ + public JcePBEDataDecryptorFactoryBuilder(PGPDigestCalculatorProvider calculatorProvider) + { + this.calculatorProvider = calculatorProvider; + } + + /** + * Set the provider object to use for creating cryptographic primitives in the resulting factory the builder produces. + * + * @param provider provider object for cryptographic primitives. + * @return the current builder. + */ + public JcePBEDataDecryptorFactoryBuilder setProvider(Provider provider) + { + this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + this.aeadHelper = new JceAEADUtil(helper); + + return this; + } + + /** + * Set the provider name to use for creating cryptographic primitives in the resulting factory the builder produces. + * + * @param providerName the name of the provider to reference for cryptographic primitives. + * @return the current builder. + */ + public JcePBEDataDecryptorFactoryBuilder setProvider(String providerName) + { + this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + this.aeadHelper = new JceAEADUtil(helper); + + return this; + } + + /** + * Construct a {@link PBEDataDecryptorFactory} to use to decrypt PBE encrypted data. + * + * @param passPhrase the pass phrase to use to generate keys in the resulting factory. + * @return a decryptor factory that can be used to generate PBE keys. + */ + public PBEDataDecryptorFactory build(char[] passPhrase) + { + if (calculatorProvider == null) + { + try + { + calculatorProvider = new JcaPGPDigestCalculatorProviderBuilder(helper).build(); + } + catch (PGPException e) + { + throw new IllegalStateException("digest calculator provider cannot be built with current helper: " + e.getMessage()); + } + } + return new PBEDataDecryptorFactory(passPhrase, calculatorProvider) + { + @Override + public byte[] recoverSessionData(int keyAlgorithm, byte[] key, byte[] secKeyData) + throws PGPException + { + try + { + if (secKeyData != null && secKeyData.length > 0) + { + String cipherName = PGPUtil.getSymmetricCipherName(keyAlgorithm); + Cipher keyCipher = helper.createCipher(cipherName + "/CFB/NoPadding"); + + keyCipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, cipherName), new IvParameterSpec(new byte[keyCipher.getBlockSize()])); + + return keyCipher.doFinal(secKeyData); + } + else + { + byte[] keyBytes = new byte[key.length + 1]; + + keyBytes[0] = (byte)keyAlgorithm; + System.arraycopy(key, 0, keyBytes, 1, key.length); + + return keyBytes; + } + } + catch (Exception e) + { + throw new PGPException("Exception recovering session info", e); + } + } + + @Override + public byte[] recoverAEADEncryptedSessionData(SymmetricKeyEncSessionPacket keyData, byte[] ikm) + throws PGPException + { + if (keyData.getVersion() < SymmetricKeyEncSessionPacket.VERSION_5) + { + throw new PGPException("SKESK packet MUST be version 5 or later."); + } + + byte[] hkdfInfo = keyData.getAAData(); // between v5 and v6, these bytes differ + int kekLen = SymmetricKeyUtils.getKeyLengthInOctets(keyData.getEncAlgorithm()); + byte[] kek = new byte[kekLen]; + + // HKDF + // secretKey := HKDF_sha256(ikm, hkdfInfo).generate() + HKDFBytesGenerator hkdfGen = new HKDFBytesGenerator(new SHA256Digest()); // SHA256 is fixed + hkdfGen.init(new HKDFParameters(ikm, null, hkdfInfo)); + hkdfGen.generateBytes(kek, 0, kek.length); + final SecretKey secretKey = new SecretKeySpec(kek, PGPUtil.getSymmetricCipherName(keyData.getEncAlgorithm())); + + // AEAD + Cipher aead = aeadHelper.createAEADCipher(keyData.getEncAlgorithm(), keyData.getAeadAlgorithm()); + int aeadMacLen = 128; + byte[] authTag = keyData.getAuthTag(); + byte[] aeadIv = keyData.getIv(); + byte[] encSessionKey = keyData.getSecKeyData(); + + // buf := encSessionKey || authTag + byte[] buf = new byte[encSessionKey.length + authTag.length]; + System.arraycopy(encSessionKey, 0, buf, 0, encSessionKey.length); + System.arraycopy(authTag, 0, buf, encSessionKey.length, authTag.length); + + // sessionData := AEAD(secretKey).decrypt(buf) + byte[] sessionData; + try + { + JceAEADCipherUtil.setUpAeadCipher(aead, secretKey, Cipher.DECRYPT_MODE, aeadIv, aeadMacLen, hkdfInfo); + + sessionData = aead.doFinal(buf, 0, buf.length); + } + catch (Exception e) + { + throw new PGPException("unable to open stream: " + e.getMessage()); + } + + return sessionData; + + } + + // OpenPGP v4 + @Override + public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) + throws PGPException + { + return helper.createDataDecryptor(withIntegrityPacket, encAlgorithm, key); + } + + // OpenPGP v5 + @Override + public PGPDataDecryptor createDataDecryptor(AEADEncDataPacket aeadEncDataPacket, PGPSessionKey sessionKey) + throws PGPException + { + return aeadHelper.createOpenPgpV5DataDecryptor(aeadEncDataPacket, sessionKey); + } + + // OpenPGP v6 + @Override + public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, PGPSessionKey sessionKey) + throws PGPException + { + return aeadHelper.createOpenPgpV6DataDecryptor(seipd, sessionKey); + } + }; + } +} diff --git a/pg/src/main/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyDataDecryptorFactoryBuilder.java b/pg/src/main/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyDataDecryptorFactoryBuilder.java new file mode 100644 index 0000000000..f99ac79e98 --- /dev/null +++ b/pg/src/main/jdk1.1/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyDataDecryptorFactoryBuilder.java @@ -0,0 +1,408 @@ +package org.bouncycastle.openpgp.operator.jcajce; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.PrivateKey; +import java.security.Provider; +import java.security.PublicKey; +import java.security.interfaces.RSAKey; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Date; + +import javax.crypto.Cipher; +import javax.crypto.interfaces.DHKey; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; +import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x9.ECNamedCurveTable; +import org.bouncycastle.asn1.x9.X9ECParametersHolder; +import org.bouncycastle.bcpg.AEADEncDataPacket; +import org.bouncycastle.bcpg.ECDHPublicBCPGKey; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.X25519PublicBCPGKey; +import org.bouncycastle.bcpg.X448PublicBCPGKey; +import org.bouncycastle.crypto.params.X25519PublicKeyParameters; +import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec; +import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; +import org.bouncycastle.jcajce.util.NamedJcaJceHelper; +import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; +import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPPrivateKey; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPSessionKey; +import org.bouncycastle.openpgp.operator.PGPDataDecryptor; +import org.bouncycastle.openpgp.operator.PGPPad; +import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.RFC6637Utils; +import org.bouncycastle.util.Arrays; + +public class JcePublicKeyDataDecryptorFactoryBuilder +{ + private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); + private OperatorHelper contentHelper = new OperatorHelper(new DefaultJcaJceHelper()); + private JceAEADUtil aeadHelper = new JceAEADUtil(contentHelper); + private JcaPGPKeyConverter keyConverter = new JcaPGPKeyConverter(); + private JcaKeyFingerprintCalculator fingerprintCalculator = new JcaKeyFingerprintCalculator(); + + public JcePublicKeyDataDecryptorFactoryBuilder() + { + } + + /** + * Set the provider object to use for creating cryptographic primitives in the resulting factory the builder produces. + * + * @param provider provider object for cryptographic primitives. + * @return the current builder. + */ + public JcePublicKeyDataDecryptorFactoryBuilder setProvider(Provider provider) + { + this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + keyConverter.setProvider(provider); + this.contentHelper = helper; + this.aeadHelper = new JceAEADUtil(contentHelper); + + return this; + } + + /** + * Set the provider name to use for creating cryptographic primitives in the resulting factory the builder produces. + * + * @param providerName the name of the provider to reference for cryptographic primitives. + * @return the current builder. + */ + public JcePublicKeyDataDecryptorFactoryBuilder setProvider(String providerName) + { + this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + keyConverter.setProvider(providerName); + this.contentHelper = helper; + this.aeadHelper = new JceAEADUtil(contentHelper); + + return this; + } + + public JcePublicKeyDataDecryptorFactoryBuilder setContentProvider(Provider provider) + { + this.contentHelper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + this.aeadHelper = new JceAEADUtil(contentHelper); + + return this; + } + + public JcePublicKeyDataDecryptorFactoryBuilder setContentProvider(String providerName) + { + this.contentHelper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + this.aeadHelper = new JceAEADUtil(contentHelper); + + return this; + } + + private int getExpectedPayloadSize(PrivateKey key) + { + if (key instanceof DHKey) + { + DHKey k = (DHKey)key; + + return (k.getParams().getP().bitLength() + 7) / 8; + } + else if (key instanceof RSAKey) + { + RSAKey k = (RSAKey)key; + + return (k.getModulus().bitLength() + 7) / 8; + } + else + { + return -1; + } + } + + public PublicKeyDataDecryptorFactory build(final PrivateKey privKey) + { + return new PublicKeyDataDecryptorFactory() + { + final int expectedPayLoadSize = getExpectedPayloadSize(privKey); + + @Override + public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) + throws PGPException + { + if (keyAlgorithm == PublicKeyAlgorithmTags.ECDH || keyAlgorithm == PublicKeyAlgorithmTags.X25519 || keyAlgorithm == PublicKeyAlgorithmTags.X448) + { + throw new PGPException("ECDH requires use of PGPPrivateKey for decryption"); + } + return decryptSessionData(keyAlgorithm, privKey, expectedPayLoadSize, secKeyData); + } + + // OpenPGP v4 + @Override + public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) + throws PGPException + { + return contentHelper.createDataDecryptor(withIntegrityPacket, encAlgorithm, key); + } + + // OpenPGP v5 + @Override + public PGPDataDecryptor createDataDecryptor(AEADEncDataPacket aeadEncDataPacket, PGPSessionKey sessionKey) + throws PGPException + { + return aeadHelper.createOpenPgpV5DataDecryptor(aeadEncDataPacket, sessionKey); + } + + // OpenPGP v6 + @Override + public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, PGPSessionKey sessionKey) + throws PGPException + { + return aeadHelper.createOpenPgpV6DataDecryptor(seipd, sessionKey); + } + }; + } + + public PublicKeyDataDecryptorFactory build(final PGPPrivateKey privKey) + { + return new PublicKeyDataDecryptorFactory() + { + @Override + public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) + throws PGPException + { + if (keyAlgorithm == PublicKeyAlgorithmTags.ECDH) + { + return decryptSessionData(keyConverter, privKey, secKeyData); + } + else if (keyAlgorithm == PublicKeyAlgorithmTags.X25519) + { + return decryptSessionData(keyConverter, privKey, secKeyData[0], X25519PublicBCPGKey.LENGTH, "X25519withSHA256HKDF", + SymmetricKeyAlgorithmTags.AES_128, EdECObjectIdentifiers.id_X25519, "X25519"); + } + else if (keyAlgorithm == PublicKeyAlgorithmTags.X448) + { + return decryptSessionData(keyConverter, privKey, secKeyData[0], X448PublicBCPGKey.LENGTH, "X448withSHA512HKDF", + SymmetricKeyAlgorithmTags.AES_256, EdECObjectIdentifiers.id_X448, "X448"); + } + PrivateKey jcePrivKey = keyConverter.getPrivateKey(privKey); + int expectedPayLoadSize = getExpectedPayloadSize(jcePrivKey); + + return decryptSessionData(keyAlgorithm, jcePrivKey, expectedPayLoadSize, secKeyData); + } + + // OpenPGP v4 + @Override + public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) + throws PGPException + { + return contentHelper.createDataDecryptor(withIntegrityPacket, encAlgorithm, key); + } + + // OpenPGP v5 + @Override + public PGPDataDecryptor createDataDecryptor(AEADEncDataPacket aeadEncDataPacket, PGPSessionKey sessionKey) + throws PGPException + { + return aeadHelper.createOpenPgpV5DataDecryptor(aeadEncDataPacket, sessionKey); + } + + // OpenPGP v6 + @Override + public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, PGPSessionKey sessionKey) + throws PGPException + { + return aeadHelper.createOpenPgpV6DataDecryptor(seipd, sessionKey); + } + }; + } + + private byte[] decryptSessionData(JcaPGPKeyConverter converter, PGPPrivateKey privKey, byte[][] secKeyData) + throws PGPException + { + PublicKeyPacket pubKeyData = privKey.getPublicKeyPacket(); + + byte[] enc = secKeyData[0]; + int pLen; + byte[] pEnc; + byte[] keyEnc; + + pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8; + if ((2 + pLen + 1) > enc.length) + { + throw new PGPException("encoded length out of range"); + } + + pEnc = new byte[pLen]; + System.arraycopy(enc, 2, pEnc, 0, pLen); + int keyLen = enc[pLen + 2] & 0xff; + if ((2 + pLen + 1 + keyLen) > enc.length) + { + throw new PGPException("encoded length out of range"); + } + + keyEnc = new byte[keyLen]; + System.arraycopy(enc, 2 + pLen + 1, keyEnc, 0, keyLen); + + try + { + PublicKey publicKey; + String agreementName; + ECDHPublicBCPGKey ecKey = (ECDHPublicBCPGKey)pubKeyData.getKey(); + // XDH + if (ecKey.getCurveOID().equals(CryptlibObjectIdentifiers.curvey25519)) + { + agreementName = RFC6637Utils.getXDHAlgorithm(pubKeyData); + if (pEnc.length != (1 + X25519PublicKeyParameters.KEY_SIZE) || 0x40 != pEnc[0]) + { + throw new IllegalArgumentException("Invalid Curve25519 public key"); + } + publicKey = getPublicKey(pEnc, EdECObjectIdentifiers.id_X25519, 1); + } + else + { + X9ECParametersHolder x9Params = ECNamedCurveTable.getByOIDLazy(ecKey.getCurveOID()); + ECPoint publicPoint = x9Params.getCurve().decodePoint(pEnc); + + agreementName = RFC6637Utils.getAgreementAlgorithm(pubKeyData); + + publicKey = converter.getPublicKey(new PGPPublicKey(new PublicKeyPacket(PublicKeyAlgorithmTags.ECDH, new Date(), + new ECDHPublicBCPGKey(ecKey.getCurveOID(), publicPoint, ecKey.getHashAlgorithm(), ecKey.getSymmetricKeyAlgorithm())), fingerprintCalculator)); + } + byte[] userKeyingMaterial = RFC6637Utils.createUserKeyingMaterial(pubKeyData, fingerprintCalculator); + + Key paddedSessionKey = getSessionKey(converter, privKey, agreementName, publicKey, ecKey.getSymmetricKeyAlgorithm(), keyEnc, new UserKeyingMaterialSpec(userKeyingMaterial)); + + return PGPPad.unpadSessionData(paddedSessionKey.getEncoded()); + } + catch (Exception e) + { + throw new PGPException("error decrypting session data: " + e.getMessage(), e); + } + } + + private byte[] decryptSessionData(JcaPGPKeyConverter converter, PGPPrivateKey privKey, byte[] enc, int pLen, String agreementAlgorithm, + int symmetricKeyAlgorithm, ASN1ObjectIdentifier algprithmIdentifier, String algorithmName) + throws PGPException + { + try + { + byte[] pEnc = new byte[pLen]; + System.arraycopy(enc, 0, pEnc, 0, pLen); + int keyLen = enc[pLen] & 0xff; + if ((pLen + 1 + keyLen) > enc.length) + { + throw new PGPException("encoded length out of range"); + } + byte[] keyEnc = new byte[keyLen - 1]; + System.arraycopy(enc, pLen + 2, keyEnc, 0, keyEnc.length); + PublicKey publicKey = getPublicKey(pEnc, algprithmIdentifier, 0); + Key paddedSessionKey = getSessionKey(converter, privKey, agreementAlgorithm, publicKey, symmetricKeyAlgorithm, keyEnc, + JcaJcePGPUtil.getHybridValueParameterSpecWithPrepend(pEnc, privKey.getPublicKeyPacket(), algorithmName)); + symmetricKeyAlgorithm = enc[pLen + 1] & 0xff; + return Arrays.concatenate(new byte[]{(byte)symmetricKeyAlgorithm}, paddedSessionKey.getEncoded()); + } + catch (Exception e) + { + throw new PGPException("error decrypting session data: " + e.getMessage(), e); + } + } + + private Key getSessionKey(JcaPGPKeyConverter converter, PGPPrivateKey privKey, String agreementName, + PublicKey publicKey, int symmetricKeyAlgorithm, byte[] keyEnc, AlgorithmParameterSpec ukms) + throws PGPException, GeneralSecurityException + { + try + { + PrivateKey privateKey = converter.getPrivateKey(privKey); + Key key = JcaJcePGPUtil.getSecret(helper, publicKey, RFC6637Utils.getKeyEncryptionOID(symmetricKeyAlgorithm).getId(), agreementName, ukms, privateKey); + Cipher c = helper.createKeyWrapper(symmetricKeyAlgorithm); + c.init(Cipher.UNWRAP_MODE, key); + return c.unwrap(keyEnc, "Session", Cipher.SECRET_KEY); + } + catch(InvalidKeyException e) + { + throw new GeneralSecurityException(e.toString()); + } + catch(NoSuchAlgorithmException e) + { + throw new GeneralSecurityException(e.toString()); + } + } + + private PublicKey getPublicKey(byte[] pEnc, ASN1ObjectIdentifier algprithmIdentifier, int pEncOff) + throws PGPException, GeneralSecurityException, IOException + { + KeyFactory keyFact = helper.createKeyFactory("XDH"); + + return keyFact.generatePublic(new X509EncodedKeySpec(new SubjectPublicKeyInfo( + new AlgorithmIdentifier(algprithmIdentifier), Arrays.copyOfRange(pEnc, pEncOff, pEnc.length)).getEncoded())); + } + + private void updateWithMPI(Cipher c, int expectedPayloadSize, byte[] encMPI) + { + if (expectedPayloadSize > 0) + { + if (encMPI.length - 2 > expectedPayloadSize) // leading Zero? Shouldn't happen but... + { + c.update(encMPI, 3, encMPI.length - 3); + } + else + { + if (expectedPayloadSize > (encMPI.length - 2)) + { + c.update(new byte[expectedPayloadSize - (encMPI.length - 2)]); + } + c.update(encMPI, 2, encMPI.length - 2); + } + } + else + { + c.update(encMPI, 2, encMPI.length - 2); + } + } + + private byte[] decryptSessionData(int keyAlgorithm, PrivateKey privKey, int expectedPayloadSize, byte[][] secKeyData) + throws PGPException + { + Cipher c1 = helper.createPublicKeyCipher(keyAlgorithm); + + try + { + c1.init(Cipher.DECRYPT_MODE, privKey); + } + catch (InvalidKeyException e) + { + throw new PGPException("error setting asymmetric cipher", e); + } + + if (keyAlgorithm == PGPPublicKey.RSA_ENCRYPT + || keyAlgorithm == PGPPublicKey.RSA_GENERAL) + { + updateWithMPI(c1, expectedPayloadSize, secKeyData[0]); + } + else + { + // Elgamal Encryption + updateWithMPI(c1, expectedPayloadSize, secKeyData[0]); + updateWithMPI(c1, expectedPayloadSize, secKeyData[1]); + } + + try + { + return c1.doFinal(); + } + catch (Exception e) + { + throw new PGPException("exception decrypting session data", e); + } + } +} diff --git a/pg/src/main/jdk1.3/org/bouncycastle/bcpg/StreamUtil.java b/pg/src/main/jdk1.3/org/bouncycastle/bcpg/StreamUtil.java index 7d8f9f0476..147669f33f 100644 --- a/pg/src/main/jdk1.3/org/bouncycastle/bcpg/StreamUtil.java +++ b/pg/src/main/jdk1.3/org/bouncycastle/bcpg/StreamUtil.java @@ -3,6 +3,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; class StreamUtil { @@ -21,4 +22,69 @@ static int findLimit(InputStream in) return Integer.MAX_VALUE; } + + static void writeNewPacketLength(OutputStream out, long bodyLen) + throws IOException + { + if (bodyLen < 192) + { + out.write((byte)bodyLen); + } + else if (bodyLen <= 8383) + { + bodyLen -= 192; + + out.write((byte)(((bodyLen >> 8) & 0xff) + 192)); + out.write((byte)bodyLen); + } + else + { + out.write(0xff); + writeBodyLen(out, bodyLen); + } + } + + static void writeBodyLen(OutputStream out, long bodyLen) + throws IOException + { + out.write((byte)(bodyLen >> 24)); + out.write((byte)(bodyLen >> 16)); + out.write((byte)(bodyLen >> 8)); + out.write((byte)bodyLen); + } + + static void writeKeyID(BCPGOutputStream pOut, long keyID) + throws IOException + { + pOut.write((byte)(keyID >> 56)); + pOut.write((byte)(keyID >> 48)); + pOut.write((byte)(keyID >> 40)); + pOut.write((byte)(keyID >> 32)); + pOut.write((byte)(keyID >> 24)); + pOut.write((byte)(keyID >> 16)); + pOut.write((byte)(keyID >> 8)); + pOut.write((byte)(keyID)); + } + + static long readKeyID(BCPGInputStream in) + throws IOException + { + long keyID = (long)in.read() << 56; + keyID |= (long)in.read() << 48; + keyID |= (long)in.read() << 40; + keyID |= (long)in.read() << 32; + keyID |= (long)in.read() << 24; + keyID |= (long)in.read() << 16; + keyID |= (long)in.read() << 8; + return keyID | in.read(); + } + + static void writeTime(BCPGOutputStream pOut, long time) + throws IOException + { + pOut.write((byte)(time >> 24)); + pOut.write((byte)(time >> 16)); + pOut.write((byte)(time >> 8)); + pOut.write((byte)time); + } } diff --git a/pg/src/main/jdk1.3/org/bouncycastle/openpgp/PGPPublicKeyRing.java b/pg/src/main/jdk1.3/org/bouncycastle/openpgp/PGPPublicKeyRing.java index 925c05a17f..c4291d83cc 100644 --- a/pg/src/main/jdk1.3/org/bouncycastle/openpgp/PGPPublicKeyRing.java +++ b/pg/src/main/jdk1.3/org/bouncycastle/openpgp/PGPPublicKeyRing.java @@ -23,7 +23,6 @@ import org.bouncycastle.bcpg.TrustPacket; import org.bouncycastle.bcpg.UserDataPacket; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; -import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Iterable; import org.bouncycastle.util.Longs; @@ -184,7 +183,7 @@ public PGPPublicKey getPublicKey(byte[] fingerprint) { PGPPublicKey k = (PGPPublicKey)keys.get(i); - if (Arrays.areEqual(fingerprint, k.getFingerprint())) + if (k.hasFingerprint(fingerprint)) { return k; } @@ -468,7 +467,7 @@ public static PGPPublicKeyRing join( boolean allowSubkeySigsOnNonSubkey) throws PGPException { - if (!Arrays.areEqual(first.getPublicKey().getFingerprint(), second.getPublicKey().getFingerprint())) + if (!second.getPublicKey().hasFingerprint(first.getPublicKey().getFingerprint())) { throw new IllegalArgumentException("Cannot merge certificates with differing primary keys."); } diff --git a/pg/src/main/jdk1.3/org/bouncycastle/openpgp/PGPSecretKeyRing.java b/pg/src/main/jdk1.3/org/bouncycastle/openpgp/PGPSecretKeyRing.java index 163c36f01a..da15cb3f1a 100644 --- a/pg/src/main/jdk1.3/org/bouncycastle/openpgp/PGPSecretKeyRing.java +++ b/pg/src/main/jdk1.3/org/bouncycastle/openpgp/PGPSecretKeyRing.java @@ -24,7 +24,6 @@ import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; -import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Iterable; /** @@ -246,7 +245,7 @@ public PGPPublicKey getPublicKey(byte[] fingerprint) { PGPPublicKey k = (PGPPublicKey)extraPubKeys.get(i); - if (Arrays.areEqual(fingerprint, k.getFingerprint())) + if (k.hasFingerprint(fingerprint)) { return k; } @@ -356,7 +355,7 @@ public PGPSecretKey getSecretKey(byte[] fingerprint) { PGPSecretKey k = (PGPSecretKey)keys.get(i); - if (Arrays.areEqual(fingerprint, k.getPublicKey().getFingerprint())) + if (k.getPublicKey().hasFingerprint(fingerprint)) { return k; } diff --git a/pg/src/main/jdk1.4/org/bouncycastle/bcpg/ArmoredOutputStream.java b/pg/src/main/jdk1.4/org/bouncycastle/bcpg/ArmoredOutputStream.java index c59a9b4056..b84102ade6 100644 --- a/pg/src/main/jdk1.4/org/bouncycastle/bcpg/ArmoredOutputStream.java +++ b/pg/src/main/jdk1.4/org/bouncycastle/bcpg/ArmoredOutputStream.java @@ -3,9 +3,14 @@ import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; import org.bouncycastle.util.Strings; @@ -21,7 +26,13 @@ public class ArmoredOutputStream extends OutputStream { public static final String VERSION_HDR = "Version"; + public static final String COMMENT_HDR = "Comment"; + public static final String MESSAGE_ID_HDR = "MessageID"; + public static final String HASH_HDR = "Hash"; + public static final String CHARSET_HDR = "Charset"; + public static final String DEFAULT_VERSION = "BCPG v@RELEASE_NAME@"; + private static final byte[] encodingTable = { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', @@ -41,20 +52,15 @@ public class ArmoredOutputStream /** * encode the input data producing a base 64 encoded byte array. */ - private void encode( - OutputStream out, - int[] data, - int len) + private static void encode(OutputStream out, byte[] data, int len) throws IOException { - int d1, d2, d3; + int d1, d2, d3; switch (len) { - case 0: /* nothing left to do */ - break; case 1: - d1 = data[0]; + d1 = data[0] & 0xFF; out.write(encodingTable[(d1 >>> 2) & 0x3f]); out.write(encodingTable[(d1 << 4) & 0x3f]); @@ -62,8 +68,8 @@ private void encode( out.write('='); break; case 2: - d1 = data[0]; - d2 = data[1]; + d1 = data[0] & 0xFF; + d2 = data[1] & 0xFF; out.write(encodingTable[(d1 >>> 2) & 0x3f]); out.write(encodingTable[((d1 << 4) | (d2 >>> 4)) & 0x3f]); @@ -71,9 +77,9 @@ private void encode( out.write('='); break; case 3: - d1 = data[0]; - d2 = data[1]; - d3 = data[2]; + d1 = data[0] & 0xFF; + d2 = data[1] & 0xFF; + d3 = data[2] & 0xFF; out.write(encodingTable[(d1 >>> 2) & 0x3f]); out.write(encodingTable[((d1 << 4) | (d2 >>> 4)) & 0x3f]); @@ -85,28 +91,42 @@ private void encode( } } - OutputStream out; - int[] buf = new int[3]; - int bufPtr = 0; - CRC24 crc = new CRC24(); - int chunkCount = 0; - int lastb; + /** + * encode the input data producing a base 64 encoded byte array. + */ + private static void encode3(OutputStream out, byte[] data) + throws IOException + { + int d1 = data[0] & 0xFF; + int d2 = data[1] & 0xFF; + int d3 = data[2] & 0xFF; + + out.write(encodingTable[(d1 >>> 2) & 0x3f]); + out.write(encodingTable[((d1 << 4) | (d2 >>> 4)) & 0x3f]); + out.write(encodingTable[((d2 << 2) | (d3 >>> 6)) & 0x3f]); + out.write(encodingTable[d3 & 0x3f]); + } - boolean start = true; - boolean clearText = false; - boolean newLine = false; + OutputStream out; + byte[] buf = new byte[3]; + int bufPtr = 0; + CRC24 crc = new FastCRC24(); + int chunkCount = 0; + int lastb; - String nl = Strings.lineSeparator(); + boolean start = true; + boolean clearText = false; + boolean newLine = false; - String type; - String headerStart = "-----BEGIN PGP "; - String headerTail = "-----"; - String footerStart = "-----END PGP "; - String footerTail = "-----"; + String nl = Strings.lineSeparator(); - String version = "BCPG v@RELEASE_NAME@"; + String type; + String headerStart = "-----BEGIN PGP "; + String headerTail = "-----"; + String footerStart = "-----END PGP "; + String footerTail = "-----"; - Hashtable headers = new Hashtable(); + final Hashtable headers = new Hashtable(); /** * Constructs an armored output stream with {@link #resetHeaders() default headers}. @@ -114,7 +134,7 @@ private void encode( * @param out the OutputStream to wrap. */ public ArmoredOutputStream( - OutputStream out) + OutputStream out) { this.out = out; @@ -123,39 +143,58 @@ public ArmoredOutputStream( nl = "\r\n"; } - setHeader(VERSION_HDR, version); + setHeader(VERSION_HDR, DEFAULT_VERSION); } /** * Constructs an armored output stream with default and custom headers. * - * @param out the OutputStream to wrap. + * @param out the OutputStream to wrap. * @param headers additional headers that add to or override the {@link #resetHeaders() default - * headers}. + * headers}. */ public ArmoredOutputStream( - OutputStream out, - Hashtable headers) + OutputStream out, + Hashtable headers) { this(out); - Enumeration e = headers.keys(); + Enumeration e = headers.keys(); while (e.hasMoreElements()) { - Object key = e.nextElement(); - ArrayList headerList = new ArrayList(); + String key = (String)e.nextElement(); + List headerList = new ArrayList(); headerList.add(headers.get(key)); this.headers.put(key, headerList); } } + ArmoredOutputStream(OutputStream out, Builder builder) + { + this(out); + if (!builder.computeCRCSum) + { + crc = null; + } + this.headers.clear(); + + Map> headerMap = builder.headers; + for (Iterator it = headerMap.keySet().iterator(); it.hasNext();) + { + String key = (String)it.next(); + + this.headers.put(key, headerMap.get(key)); + } + } + /** * Set an additional header entry. Any current value(s) under the same name will be * replaced by the new one. A null value will clear the entry for name. * - * @param name the name of the header entry. + * @param name the name of the header entry. * @param value the value of the header entry. + * @deprecated use appropriate methods in {@link Builder} instead. */ public void setHeader( String name, @@ -167,10 +206,10 @@ public void setHeader( } else { - ArrayList valueList = (ArrayList)headers.get(name); + List valueList = (List)headers.get(name); if (valueList == null) { - valueList = new ArrayList(); + valueList = new ArrayList(); headers.put(name, valueList); } else @@ -183,6 +222,8 @@ public void setHeader( /** * Remove all headers. + * + * @deprecated use appropriate methods in {@link Builder} instead. */ public void clearHeaders() { @@ -193,8 +234,9 @@ public void clearHeaders() * Set an additional header entry. The current value(s) will continue to exist together * with the new one. Adding a null value has no effect. * - * @param name the name of the header entry. + * @param name the name of the header entry. * @param value the value of the header entry. + * @deprecated use appropriate methods in {@link Builder} instead */ public void addHeader( String name, @@ -204,10 +246,10 @@ public void addHeader( { return; } - ArrayList valueList = (ArrayList)headers.get(name); + List valueList = (List)headers.get(name); if (valueList == null) { - valueList = new ArrayList(); + valueList = new ArrayList(); headers.put(name, valueList); } valueList.add(value); @@ -216,10 +258,12 @@ public void addHeader( /** * Reset the headers to only contain a Version string (if one is present) + * + * @deprecated use {@link Builder#clearHeaders()} instead. */ public void resetHeaders() { - ArrayList versions = (ArrayList)headers.get(VERSION_HDR); + List versions = (List)headers.get(VERSION_HDR); headers.clear(); @@ -230,58 +274,81 @@ public void resetHeaders() } /** - * Start a clear text signed message. - * @param hashAlgorithm + * Start a clear text signed message - backwards compatibility. + * + * @param hashAlgorithm hash algorithm */ public void beginClearText( - int hashAlgorithm) + int hashAlgorithm) throws IOException { - String hash; - - switch (hashAlgorithm) - { - case HashAlgorithmTags.SHA1: - hash = "SHA1"; - break; - case HashAlgorithmTags.SHA256: - hash = "SHA256"; - break; - case HashAlgorithmTags.SHA384: - hash = "SHA384"; - break; - case HashAlgorithmTags.SHA512: - hash = "SHA512"; - break; - case HashAlgorithmTags.MD2: - hash = "MD2"; - break; - case HashAlgorithmTags.MD5: - hash = "MD5"; - break; - case HashAlgorithmTags.RIPEMD160: - hash = "RIPEMD160"; - break; - case HashAlgorithmTags.SHA224: - hash = "SHA224"; - break; - default: - throw new IOException("unknown hash algorithm tag in beginClearText: " + hashAlgorithm); - } - - String armorHdr = "-----BEGIN PGP SIGNED MESSAGE-----" + nl; - String hdrs = "Hash: " + hash + nl + nl; + beginClearText(new int[]{hashAlgorithm}); + } - for (int i = 0; i != armorHdr.length(); i++) + /** + * Start a clear text signed message. + * + * @param hashAlgorithms hash algorithms + */ + public void beginClearText( + int... hashAlgorithms) + throws IOException + { + StringBuffer sb = new StringBuffer("-----BEGIN PGP SIGNED MESSAGE-----"); + sb.append(nl); + for (int i = 0; i != hashAlgorithms.length; i++) { - out.write(armorHdr.charAt(i)); - } + int hashAlgorithm = hashAlgorithms[i]; - for (int i = 0; i != hdrs.length(); i++) - { - out.write(hdrs.charAt(i)); + String hash; + switch (hashAlgorithm) + { + case HashAlgorithmTags.MD5: + hash = "MD5"; + break; + case HashAlgorithmTags.SHA1: + hash = "SHA1"; + break; + case HashAlgorithmTags.RIPEMD160: + hash = "RIPEMD160"; + break; + case HashAlgorithmTags.MD2: + hash = "MD2"; + break; + case HashAlgorithmTags.SHA256: + hash = "SHA256"; + break; + case HashAlgorithmTags.SHA384: + hash = "SHA384"; + break; + case HashAlgorithmTags.SHA512: + hash = "SHA512"; + break; + case HashAlgorithmTags.SHA224: + hash = "SHA224"; + break; + case HashAlgorithmTags.SHA3_256: + case HashAlgorithmTags.SHA3_256_OLD: + hash = "SHA3-256"; + break; + case HashAlgorithmTags.SHA3_384: // OLD + hash = "SHA3-384"; + break; + case HashAlgorithmTags.SHA3_512: + case HashAlgorithmTags.SHA3_512_OLD: + hash = "SHA3-512"; + break; + case HashAlgorithmTags.SHA3_224: + hash = "SHA3-224"; + break; + default: + throw new IOException("unknown hash algorithm tag in beginClearText: " + hashAlgorithm); + } + sb.append(HASH_HDR).append(": ").append(hash).append(nl); } + sb.append(nl); + write(sb.toString()); clearText = true; newLine = true; lastb = 0; @@ -297,24 +364,14 @@ private void writeHeaderEntry( String value) throws IOException { - for (int i = 0; i != name.length(); i++) - { - out.write(name.charAt(i)); - } - - out.write(':'); - out.write(' '); - - out.write(Strings.toUTF8ByteArray(value)); - - for (int i = 0; i != nl.length(); i++) - { - out.write(nl.charAt(i)); - } + write(name); + write(": "); + write(value); + write(nl); } public void write( - int b) + int b) throws IOException { if (clearText) @@ -343,8 +400,8 @@ public void write( if (start) { - boolean newPacket = (b & 0x40) != 0; - int tag = 0; + boolean newPacket = (b & 0x40) != 0; + int tag = 0; if (newPacket) { @@ -370,69 +427,50 @@ public void write( type = "MESSAGE"; } - for (int i = 0; i != headerStart.length(); i++) - { - out.write(headerStart.charAt(i)); - } - - for (int i = 0; i != type.length(); i++) - { - out.write(type.charAt(i)); - } - - for (int i = 0; i != headerTail.length(); i++) - { - out.write(headerTail.charAt(i)); - } - - for (int i = 0; i != nl.length(); i++) - { - out.write(nl.charAt(i)); - } + write(headerStart); + write(type); + write(headerTail); + write(nl); if (headers.containsKey(VERSION_HDR)) { - writeHeaderEntry(VERSION_HDR, ((ArrayList)headers.get(VERSION_HDR)).get(0).toString()); + writeHeaderEntry(VERSION_HDR, (String)((List)headers.get(VERSION_HDR)).get(0)); } - Enumeration e = headers.keys(); + Enumeration e = headers.keys(); while (e.hasMoreElements()) { - String key = (String)e.nextElement(); + String key = (String)e.nextElement(); if (!key.equals(VERSION_HDR)) { - ArrayList values = (ArrayList)headers.get(key); - for (Iterator it = values.iterator(); it.hasNext();) + List values = (List)headers.get(key); + for (Iterator it = values.iterator(); it.hasNext(); ) { - writeHeaderEntry(key, it.next().toString()); + writeHeaderEntry(key, (String)it.next()); } } } - for (int i = 0; i != nl.length(); i++) - { - out.write(nl.charAt(i)); - } - + write(nl); start = false; } if (bufPtr == 3) { - encode(out, buf, bufPtr); + if (crc != null) + { + crc.update3(buf, 0); + } + encode3(out, buf); bufPtr = 0; if ((++chunkCount & 0xf) == 0) { - for (int i = 0; i != nl.length(); i++) - { - out.write(nl.charAt(i)); - } + write(nl); } } - crc.update(b); - buf[bufPtr++] = b & 0xff; + buf[bufPtr++] = (byte)b; } public void flush() @@ -449,51 +487,244 @@ public void close() { if (type != null) { - encode(out, buf, bufPtr); + if (bufPtr > 0) + { + if (crc != null) + { + for (int i = 0; i < bufPtr; ++i) + { + crc.update(buf[i] & 0xFF); + } + } + encode(out, buf, bufPtr); + } + + write(nl); - for (int i = 0; i != nl.length(); i++) + if (crc != null) { - out.write(nl.charAt(i)); + out.write('='); + + int crcV = crc.getValue(); + + buf[0] = (byte)(crcV >>> 16); + buf[1] = (byte)(crcV >>> 8); + buf[2] = (byte)crcV; + + encode3(out, buf); + write(nl); } - out.write('='); - int crcV = crc.getValue(); + write(footerStart); + write(type); + write(footerTail); + write(nl); + + out.flush(); + + type = null; + start = true; + } + } + + private void write(String string) + throws IOException + { + out.write(Strings.toUTF8ByteArray(string)); + } + + public static Builder builder() + { + return new Builder(); + } + + public static class Builder + { + private final Map> headers = new HashMap>(); + private boolean computeCRCSum = true; + + private Builder() + { - buf[0] = ((crcV >> 16) & 0xff); - buf[1] = ((crcV >> 8) & 0xff); - buf[2] = (crcV & 0xff); + } - encode(out, buf, 3); + public ArmoredOutputStream build(OutputStream outputStream) + { + return new ArmoredOutputStream(outputStream, this); + } - for (int i = 0; i != nl.length(); i++) + /** + * Set a
      Version:
      header. + * Note: Adding version headers to ASCII armored output is discouraged to minimize metadata. + * + * @param version version + * @return builder + */ + public Builder setVersion(String version) + { + return setSingletonHeader(VERSION_HDR, version); + } + + /** + * Replace the
      Comment:
      header field with the given comment. + * If the comment contains newlines, multiple headers will be added, one for each newline. + * If the comment is
      null
      , then the output will contain no comments. + * + * @param comment comment + * @return builder + */ + public Builder setComment(String comment) + { + return replaceHeader(COMMENT_HDR, comment); + } + + /** + * Replace the
      MessageID:
      header field with the given messageId. + * + * @param messageId message ID + * @return builder + */ + public Builder setMessageId(String messageId) + { + return replaceHeader(MESSAGE_ID_HDR, messageId); + } + + /** + * Replace the
      Charset:
      header with the given value. + * + * @param charset charset + * @return builder + */ + public Builder setCharset(String charset) + { + return replaceHeader(CHARSET_HDR, charset); + } + + /** + * Add the given value as one or more additional
      Comment:
      headers to the already present comments. + * If the comment contains newlines, multiple headers will be added, one for each newline. + * If the comment is
      null
      , this method does nothing. + * + * @param comment comment + * @return builder + */ + public Builder addComment(String comment) + { + return addHeader(COMMENT_HDR, comment); + } + + /** + * Set and replace the given header value with a single-line header. + * If the value is
      null
      , this method will remove the header entirely. + * + * @param key header key + * @param value header value + * @return builder + */ + private Builder setSingletonHeader(String key, String value) + { + if (value == null || value.trim().length() == 0) + { + this.headers.remove(key); + } + else { - out.write(nl.charAt(i)); + String trimmed = value.trim(); + if (trimmed.indexOf("\n") >= 0) + { + throw new IllegalArgumentException("Armor header value for key " + key + " cannot contain newlines."); + } + List h = new ArrayList(); + h.add(value); + this.headers.put(key, h); } + return this; + } - for (int i = 0; i != footerStart.length(); i++) + /** + * Add a header, splitting it into multiple headers if required (newlines). + * + * @param key key + * @param value value + * @return builder + */ + private Builder addHeader(String key, String value) + { + if (value == null || value.trim().length() == 0) { - out.write(footerStart.charAt(i)); + return this; } - for (int i = 0; i != type.length(); i++) + List values = (List)headers.get(key); + if (values == null) { - out.write(type.charAt(i)); + values = new ArrayList(); + headers.put(key, values); } - for (int i = 0; i != footerTail.length(); i++) + // handle multi-line values + String trimmed = value.trim(); + for (StringTokenizer sTok = new StringTokenizer(trimmed, "\n"); sTok.hasMoreTokens();) { - out.write(footerTail.charAt(i)); + String line = sTok.nextToken().trim(); + if (line.length() == 0) + { + continue; + } + values.add(line); } + return this; + } - for (int i = 0; i != nl.length(); i++) + /** + * Replace all header values for the given key with the given value. + * If the value is
      null
      , existing headers for the given key are removed. + * The value is split into multiple headers if it contains newlines. + * + * @param key key + * @param value value + * @return builder + */ + private Builder replaceHeader(String key, String value) + { + if (value == null || value.trim().length() == 0) { - out.write(nl.charAt(i)); + return this; } - out.flush(); + List values = new ArrayList(); - type = null; - start = true; + // handle multi-line values + String trimmed = value.trim(); + for (StringTokenizer sTok = new StringTokenizer(trimmed, "\n"); sTok.hasMoreTokens();) + { + String line = sTok.nextToken().trim(); + if (line.length() == 0) + { + continue; + } + values.add(line); + } + + headers.put(key, values); + return this; + } + + public Builder clearHeaders() + { + headers.clear(); + return this; + } + + /** + * Enable calculation and inclusion of the CRC check sum (default is true). + * @param doComputeCRC true if CRC to be included, false otherwise. + * @return the current builder instance. + */ + public Builder enableCRC(boolean doComputeCRC) + { + this.computeCRCSum = doComputeCRC; + return this; } } } diff --git a/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/PGPDataEncryptorBuilder.java b/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/PGPDataEncryptorBuilder.java deleted file mode 100644 index 4e94c621fc..0000000000 --- a/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/PGPDataEncryptorBuilder.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.bouncycastle.openpgp.operator; - -import java.security.SecureRandom; - -import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; -import org.bouncycastle.openpgp.PGPException; - -/** - * A builder for {@link PGPDataEncryptor} instances, which can be used to encrypt data objects. - */ -public interface PGPDataEncryptorBuilder -{ - /** - * The encryption algorithm used by data encryptors created by this builder. - * - * @return one of the {@link SymmetricKeyAlgorithmTags symmetric encryption algorithms}. - */ - int getAlgorithm(); - - /** - * Builds a data encryptor using the algorithm configured for this builder. - * - * @param keyBytes the bytes of the key to use for the cipher. - * @return a data encryptor with an initialised cipher. - * @throws PGPException if an error occurs initialising the configured encryption. - */ - PGPDataEncryptor build(byte[] keyBytes) - throws PGPException; - - /** - * Gets the SecureRandom instance used by this builder. - *

      - * If a SecureRandom has not been explicitly configured, a default {@link SecureRandom} is - * constructed and retained by the this builder.

      - */ - SecureRandom getSecureRandom(); -} diff --git a/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/bc/BcPGPDataEncryptorBuilder.java b/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/bc/BcPGPDataEncryptorBuilder.java new file mode 100644 index 0000000000..d18d6a5a52 --- /dev/null +++ b/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/bc/BcPGPDataEncryptorBuilder.java @@ -0,0 +1,298 @@ +package org.bouncycastle.openpgp.operator.bc; + +import java.io.OutputStream; +import java.security.SecureRandom; + +import org.bouncycastle.bcpg.AEADUtils; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyUtils; +import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.BufferedBlockCipher; +import org.bouncycastle.crypto.io.CipherOutputStream; +import org.bouncycastle.crypto.modes.AEADBlockCipher; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.operator.PGPAEADDataEncryptor; +import org.bouncycastle.openpgp.operator.PGPDataEncryptor; +import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.util.Arrays; + +/** + * {@link PGPDataEncryptorBuilder} implementation that uses the Bouncy Castle lightweight API to + * implement cryptographic primitives. + */ +public class BcPGPDataEncryptorBuilder + implements PGPDataEncryptorBuilder +{ + private SecureRandom random; + private boolean withIntegrityPacket = true; + private int encAlgorithm; + private boolean isV5StyleAEAD = true; // TODO: change to false in 1.75 + private int aeadAlgorithm = -1; + private int chunkSize; + + /** + * Constructs a new data encryptor builder for a specified cipher type. + * + * @param encAlgorithm one of the {@link SymmetricKeyAlgorithmTags supported symmetric cipher + * algorithms}. May not be {@link SymmetricKeyAlgorithmTags#NULL}. + */ + public BcPGPDataEncryptorBuilder(int encAlgorithm) + { + this.encAlgorithm = encAlgorithm; + + if (encAlgorithm == 0) + { + throw new IllegalArgumentException("null cipher specified"); + } + } + + /** + * Sets whether the resulting encrypted data will be protected using an integrity packet. + * + * @param withIntegrityPacket true if an integrity packet is to be included, false otherwise. + * @return the current builder. + */ + @Override + public PGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPacket) + { + this.withIntegrityPacket = withIntegrityPacket; + + return this; + } + + public PGPDataEncryptorBuilder setUseV5AEAD() + { + this.isV5StyleAEAD = true; + + return this; + } + + public PGPDataEncryptorBuilder setUseV6AEAD() + { + this.isV5StyleAEAD = false; + + return this; + } + + /** + * Sets whether the resulting encrypted data will be protected using an AEAD mode. + * + * The chunkSize is used as a power of two, result in blocks (1 << chunkSize) containing data + * with an extra 16 bytes for the tag. The minimum chunkSize is 6. + * + * @param aeadAlgorithm the AEAD mode to use. + * @param chunkSize the size of the chunks to be processed with each nonce. + * @return builder + */ + @Override + public PGPDataEncryptorBuilder setWithAEAD(int aeadAlgorithm, int chunkSize) + { + if (encAlgorithm != SymmetricKeyAlgorithmTags.AES_128 + && encAlgorithm != SymmetricKeyAlgorithmTags.AES_192 + && encAlgorithm != SymmetricKeyAlgorithmTags.AES_256 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_128 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_192 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_256) + { + throw new IllegalStateException("AEAD algorithms can only be used with AES and Camellia"); + } + + if (chunkSize < 6) + { + throw new IllegalArgumentException("minimum chunkSize is 6"); + } + + this.aeadAlgorithm = aeadAlgorithm; + this.chunkSize = chunkSize - 6; + + return this; + } + + /** + * Provide a user defined source of randomness. + *

      + * If no SecureRandom is configured, a default SecureRandom will be used. + *

      + * + * @param random the secure random to be used. + * @return the current builder. + */ + public BcPGPDataEncryptorBuilder setSecureRandom(SecureRandom random) + { + this.random = random; + + return this; + } + + @Override + public int getAlgorithm() + { + return encAlgorithm; + } + + @Override + public int getAeadAlgorithm() + { + return aeadAlgorithm; + } + + @Override + public int getChunkSize() + { + return chunkSize; + } + + @Override + public boolean isV5StyleAEAD() + { + return isV5StyleAEAD; + } + + @Override + public SecureRandom getSecureRandom() + { + if (random == null) + { + random = new SecureRandom(); + } + + return random; + } + + @Override + public PGPDataEncryptor build(byte[] keyBytes) + throws PGPException + { + if (aeadAlgorithm > 0) + { + return new MyAeadDataEncryptor(keyBytes); + } + + return new MyPGPDataEncryptor(keyBytes); + } + + private class MyPGPDataEncryptor + implements PGPDataEncryptor + { + private final BufferedBlockCipher c; + + MyPGPDataEncryptor(byte[] keyBytes) + throws PGPException + { + BlockCipher engine = BcImplProvider.createBlockCipher(encAlgorithm); + + try + { + c = BcUtil.createStreamCipher(true, engine, withIntegrityPacket, keyBytes); + } + catch (IllegalArgumentException e) + { + throw new PGPException("invalid parameters: " + e.getMessage(), e); + } + } + + public OutputStream getOutputStream(OutputStream out) + { + return new CipherOutputStream(out, c); + } + + public PGPDigestCalculator getIntegrityCalculator() + { + if (withIntegrityPacket) + { + return new SHA1PGPDigestCalculator(); + } + + return null; + } + + public int getBlockSize() + { + return c.getBlockSize(); + } + } + + private class MyAeadDataEncryptor + implements PGPAEADDataEncryptor + { + private final boolean isV5StyleAEAD; + private final AEADBlockCipher c; + private final byte[] keyBytes; + private final byte[] iv; + + /** + * Create a new data decryptor using AEAD. + * If the OpenPGP v5 style AEAD is used, keyBytes contains the key. The IV is randomly generated. + * If however OpenPGP v6 style AEAD is used, keyBytes contains M+N-8 bytes. + * The first M bytes contain the key, the remaining N-8 bytes contain the IV. + * + * @param keyBytes key or key and iv + * @throws PGPException + */ + MyAeadDataEncryptor(byte[] keyBytes) + throws PGPException + { + this.isV5StyleAEAD = keyBytes.length == SymmetricKeyUtils.getKeyLengthInOctets(encAlgorithm); + if (isV5StyleAEAD) + { + this.keyBytes = keyBytes; + // V5 has a random IV + this.iv = new byte[AEADUtils.getIVLength((byte)aeadAlgorithm)]; + getSecureRandom().nextBytes(iv); + } + // V6 passes in concatenated key and N-8 bytes of IV. + else + { + // V6 has the IV appended to the message key, so we need to split it. + byte[][] keyAndIv = AEADUtils.splitMessageKeyAndIv(keyBytes, encAlgorithm, aeadAlgorithm); + this.keyBytes = keyAndIv[0]; + this.iv = keyAndIv[1]; + } + + this.c = BcAEADUtil.createAEADCipher(encAlgorithm, aeadAlgorithm); + } + + public OutputStream getOutputStream(OutputStream out) + { + try + { + return new BcAEADUtil.PGPAeadOutputStream(isV5StyleAEAD, out, c, new KeyParameter(keyBytes), iv, encAlgorithm, aeadAlgorithm, chunkSize); + } + catch (Exception e) + { + throw new IllegalStateException("unable to process stream: " + e.getMessage()); + } + } + + public PGPDigestCalculator getIntegrityCalculator() + { + return null; + } + + public int getBlockSize() + { + return c.getUnderlyingCipher().getBlockSize(); + } + + @Override + public int getAEADAlgorithm() + { + return aeadAlgorithm; + } + + @Override + public int getChunkSize() + { + return chunkSize; + } + + @Override + public byte[] getIV() + { + return Arrays.clone(iv); + } + + } +} diff --git a/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.java b/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.java index 7fdb26907d..163fadd9b0 100644 --- a/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.java +++ b/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.java @@ -13,15 +13,21 @@ import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; + import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; + import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; + +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; + import java.security.spec.InvalidParameterSpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; @@ -56,33 +62,41 @@ import org.bouncycastle.bcpg.ECDSAPublicBCPGKey; import org.bouncycastle.bcpg.ECPublicBCPGKey; import org.bouncycastle.bcpg.ECSecretBCPGKey; +import org.bouncycastle.bcpg.Ed25519PublicBCPGKey; +import org.bouncycastle.bcpg.Ed25519SecretBCPGKey; +import org.bouncycastle.bcpg.Ed448PublicBCPGKey; +import org.bouncycastle.bcpg.Ed448SecretBCPGKey; import org.bouncycastle.bcpg.EdDSAPublicBCPGKey; import org.bouncycastle.bcpg.EdSecretBCPGKey; import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; -import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyPacket; import org.bouncycastle.bcpg.RSAPublicBCPGKey; import org.bouncycastle.bcpg.RSASecretBCPGKey; -import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; -import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; -import org.bouncycastle.crypto.params.X25519PublicKeyParameters; +import org.bouncycastle.bcpg.X25519PublicBCPGKey; +import org.bouncycastle.bcpg.X25519SecretBCPGKey; +import org.bouncycastle.bcpg.X448PublicBCPGKey; +import org.bouncycastle.bcpg.X448SecretBCPGKey; import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; import org.bouncycastle.jcajce.util.NamedJcaJceHelper; import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; import org.bouncycastle.math.ec.ECPoint; -import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; + +import org.bouncycastle.math.ec.rfc7748.X25519; +import org.bouncycastle.math.ec.rfc8032.Ed25519; import org.bouncycastle.openpgp.PGPAlgorithmParameters; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKdfParameters; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; +import org.bouncycastle.openpgp.operator.PGPKeyConverter; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; public class JcaPGPKeyConverter + extends PGPKeyConverter { private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); private KeyFingerPrintCalculator fingerPrintCalculator = new JcaKeyFingerprintCalculator(); @@ -104,8 +118,8 @@ public JcaPGPKeyConverter setProvider(String providerName) /** * Convert a PrivateKey into a PGPPrivateKey. * - * @param pub the corresponding PGPPublicKey to privKey. - * @param privKey the private key for the key in pub. + * @param pub the corresponding PGPPublicKey to privKey. + * @param privKey the private key for the key in pub. * @return a PGPPrivateKey * @throws PGPException */ @@ -123,16 +137,17 @@ public PGPPrivateKey getPGPPrivateKey(PGPPublicKey pub, PrivateKey privKey) * Note: the time passed in affects the value of the key's keyID, so you probably only want * to do this once for a JCA key, or make sure you keep track of the time you used. *

      - * @param algorithm asymmetric algorithm type representing the public key. + * + * @param algorithm asymmetric algorithm type representing the public key. * @param algorithmParameters additional parameters to be stored against the public key. - * @param pubKey actual public key to associate. - * @param time date of creation. + * @param pubKey actual public key to associate. + * @param time date of creation. * @throws PGPException on key creation problem. */ public PGPPublicKey getPGPPublicKey(int algorithm, PGPAlgorithmParameters algorithmParameters, PublicKey pubKey, Date time) throws PGPException { - BCPGKey bcpgKey = getPublicBCPGKey(algorithm, algorithmParameters, pubKey, time); + BCPGKey bcpgKey = getPublicBCPGKey(algorithm, algorithmParameters, pubKey); return new PGPPublicKey(new PublicKeyPacket(algorithm, time, bcpgKey), fingerPrintCalculator); } @@ -143,6 +158,7 @@ public PGPPublicKey getPGPPublicKey(int algorithm, PGPAlgorithmParameters algori * Note: the time passed in affects the value of the key's keyID, so you probably only want * to do this once for a JCA key, or make sure you keep track of the time you used. *

      + * * @param algorithm asymmetric algorithm type representing the public key. * @param pubKey actual public key to associate. * @param time date of creation. @@ -163,7 +179,7 @@ public PrivateKey getPrivateKey(PGPPrivateKey privKey) } PublicKeyPacket pubPk = privKey.getPublicKeyPacket(); - BCPGKey privPk = privKey.getPrivateKeyDataPacket(); + final BCPGKey privPk = privKey.getPrivateKeyDataPacket(); try { @@ -186,28 +202,91 @@ public PrivateKey getPrivateKey(PGPPrivateKey privKey) if (CryptlibObjectIdentifiers.curvey25519.equals(ecdhPub.getCurveOID())) { // 'reverse' because the native format for X25519 private keys is little-endian - return implGetPrivateKeyPKCS8("XDH", new PrivateKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), - new DEROctetString(Arrays.reverseInPlace(BigIntegers.asUnsignedByteArray(ecdhK.getX()))))); + return implGeneratePrivate("XDH", new Operation() + { + @Override + public PrivateKeyInfo getPrivateKeyInfos() + throws IOException + { + return JcaPGPKeyConverter.this.getPrivateKeyInfo(EdECObjectIdentifiers.id_X25519, + Arrays.reverseInPlace(BigIntegers.asUnsignedByteArray(((ECSecretBCPGKey)privPk).getX()))); + } + }); } else { return implGetPrivateKeyEC("ECDH", ecdhPub, ecdhK); } } - + case PublicKeyAlgorithmTags.X25519: + { + return implGeneratePrivate("XDH", new Operation() + { + @Override + public PrivateKeyInfo getPrivateKeyInfos() + throws IOException + { + return JcaPGPKeyConverter.this.getPrivateKeyInfo(EdECObjectIdentifiers.id_X25519, + X25519SecretBCPGKey.LENGTH, Arrays.reverseInPlace(privPk.getEncoded())); + } + }); + } + case PublicKeyAlgorithmTags.X448: + { + return implGeneratePrivate("XDH", new Operation() + { + @Override + public PrivateKeyInfo getPrivateKeyInfos() + throws IOException + { + return JcaPGPKeyConverter.this.getPrivateKeyInfo(EdECObjectIdentifiers.id_X448, + X448SecretBCPGKey.LENGTH, Arrays.reverseInPlace(privPk.getEncoded())); + } + }); + } case PublicKeyAlgorithmTags.ECDSA: + { return implGetPrivateKeyEC("ECDSA", (ECDSAPublicBCPGKey)pubPk.getKey(), (ECSecretBCPGKey)privPk); - - case PublicKeyAlgorithmTags.EDDSA: + } + case PublicKeyAlgorithmTags.EDDSA_LEGACY: { - EdSecretBCPGKey eddsaK = (EdSecretBCPGKey)privPk; - - return implGetPrivateKeyPKCS8("EdDSA", new PrivateKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), - new DEROctetString(BigIntegers.asUnsignedByteArray(eddsaK.getX())))); + return implGeneratePrivate("EdDSA", new Operation() + { + @Override + public PrivateKeyInfo getPrivateKeyInfos() + throws IOException + { + return JcaPGPKeyConverter.this.getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed25519, + BigIntegers.asUnsignedByteArray(Ed25519.SECRET_KEY_SIZE, ((EdSecretBCPGKey)privPk).getX())); + } + }); + } + case PublicKeyAlgorithmTags.Ed25519: + { + return implGeneratePrivate("EdDSA", new Operation() + { + @Override + public PrivateKeyInfo getPrivateKeyInfos() + throws IOException + { + return JcaPGPKeyConverter.this.getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed25519, + Ed25519SecretBCPGKey.LENGTH, privPk.getEncoded()); + } + }); + } + case PublicKeyAlgorithmTags.Ed448: + { + return implGeneratePrivate("EdDSA", new Operation() + { + @Override + public PrivateKeyInfo getPrivateKeyInfos() + throws IOException + { + return JcaPGPKeyConverter.this.getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed448, + Ed448SecretBCPGKey.LENGTH, privPk.getEncoded()); + } + }); } - case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: { @@ -230,7 +309,7 @@ public PrivateKey getPrivateKey(PGPPrivateKey privKey) } default: - throw new PGPException("unknown public key algorithm encountered"); + throw new PGPException("unknown public key algorithm encountered: " + pubPk.getAlgorithm()); } } catch (PGPException e) @@ -265,44 +344,47 @@ public PublicKey getPublicKey(PGPPublicKey publicKey) if (ecdhK.getCurveOID().equals(CryptlibObjectIdentifiers.curvey25519)) { - byte[] pEnc = BigIntegers.asUnsignedByteArray(ecdhK.getEncodedPoint()); - - // skip the 0x40 header byte. - if (pEnc.length < 1 || 0x40 != pEnc[0]) - { - throw new IllegalArgumentException("Invalid Curve25519 public key"); - } - - return implGetPublicKeyX509("XDH", new SubjectPublicKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), - Arrays.copyOfRange(pEnc, 1, pEnc.length))); + return get25519PublicKey(ecdhK.getEncodedPoint(), EdECObjectIdentifiers.id_X25519, "XDH", "Curve"); } else { return implGetPublicKeyEC("ECDH", ecdhK); } } - + case PublicKeyAlgorithmTags.X25519: + { + return implGetPublicKeyX509(publicPk.getKey().getEncoded(), 0, EdECObjectIdentifiers.id_X25519, "XDH"); + } + case PublicKeyAlgorithmTags.X448: + { + return implGetPublicKeyX509(publicPk.getKey().getEncoded(), 0, EdECObjectIdentifiers.id_X448, "XDH"); + } case PublicKeyAlgorithmTags.ECDSA: return implGetPublicKeyEC("ECDSA", (ECDSAPublicBCPGKey)publicPk.getKey()); - case PublicKeyAlgorithmTags.EDDSA: + case PublicKeyAlgorithmTags.EDDSA_LEGACY: { - EdDSAPublicBCPGKey eddsaK = (EdDSAPublicBCPGKey)publicPk.getKey(); - - byte[] pEnc = BigIntegers.asUnsignedByteArray(eddsaK.getEncodedPoint()); - - // skip the 0x40 header byte. - if (pEnc.length < 1 || 0x40 != pEnc[0]) + return get25519PublicKey(((EdDSAPublicBCPGKey)publicPk.getKey()).getEncodedPoint(), EdECObjectIdentifiers.id_Ed25519, "EdDSA", "Ed"); + } + case PublicKeyAlgorithmTags.Ed25519: + { + BCPGKey key = publicPk.getKey(); + if (key instanceof Ed25519PublicBCPGKey) { - throw new IllegalArgumentException("Invalid Ed25519 public key"); + return implGetPublicKeyX509(BigIntegers.asUnsignedByteArray(new BigInteger(1, publicPk.getKey().getEncoded())), + 0, EdECObjectIdentifiers.id_Ed25519, "EdDSA"); + } + else + { + return implGetPublicKeyX509(BigIntegers.asUnsignedByteArray(((EdDSAPublicBCPGKey)publicPk.getKey()).getEncodedPoint()), + 0, EdECObjectIdentifiers.id_Ed25519, "EdDSA"); } - - return implGetPublicKeyX509("EdDSA", new SubjectPublicKeyInfo( - new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), - Arrays.copyOfRange(pEnc, 1, pEnc.length))); } - + case PublicKeyAlgorithmTags.Ed448: + { + return implGetPublicKeyX509(BigIntegers.asUnsignedByteArray(new BigInteger(1, publicPk.getKey().getEncoded())), + 0, EdECObjectIdentifiers.id_Ed448, "EdDSA"); + } case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: { @@ -321,7 +403,7 @@ public PublicKey getPublicKey(PGPPublicKey publicKey) } default: - throw new PGPException("unknown public key algorithm encountered"); + throw new PGPException("unknown public key algorithm encountered: " + publicPk.getAlgorithm()); } } catch (PGPException e) @@ -350,6 +432,22 @@ private ECParameterSpec getECParameterSpec(ASN1ObjectIdentifier curveOid, X9ECPa return (ECParameterSpec)params.getParameterSpec(ECParameterSpec.class); } + private BCPGKey getPrivateBCPGKey(PrivateKey privKey, BCPGKeyOperation operation) + throws PGPException + { + PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(privKey.getEncoded()); + + try + { + // 'reverse' because the native format for X25519 private keys is little-endian + return operation.getBCPGKey(ASN1OctetString.getInstance(pInfo.parsePrivateKey()).getOctets()); + } + catch (IOException e) + { + throw new PGPException(e.getMessage(), e); + } + } + private BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) throws PGPException { @@ -370,49 +468,84 @@ private BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) } else { - PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(privKey.getEncoded()); - - try + // 'reverse' because the native format for X25519 private keys is little-endian + return getPrivateBCPGKey(privKey, new BCPGKeyOperation() { - // 'reverse' because the native format for X25519 private keys is little-endian - return new ECSecretBCPGKey(new BigInteger(1, - Arrays.reverse(ASN1OctetString.getInstance(pInfo.parsePrivateKey()).getOctets()))); + @Override + public BCPGKey getBCPGKey(byte[] pInfoEncoded) + { + return new ECSecretBCPGKey(new BigInteger(1, Arrays.reverse(pInfoEncoded))); + } + }); + } + } + case PublicKeyAlgorithmTags.X25519: + { + // 'reverse' because the native format for X25519 private keys is little-endian + return getPrivateBCPGKey(privKey, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] pInfoEncoded) + { + return new X25519SecretBCPGKey(Arrays.reverse(pInfoEncoded)); } - catch (IOException e) + }); + } + case PublicKeyAlgorithmTags.X448: + { + // 'reverse' because the native format for X448 private keys is little-endian + return getPrivateBCPGKey(privKey, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] pInfoEncoded) { - throw new PGPException(e.getMessage(), e); + return new X448SecretBCPGKey(Arrays.reverse(pInfoEncoded)); } - } + }); } - case PublicKeyAlgorithmTags.ECDSA: { - ECPrivateKey ecK = (ECPrivateKey)privKey; - return new ECSecretBCPGKey(ecK.getD()); + return new ECSecretBCPGKey(((ECPrivateKey)privKey).getD()); } - - case PublicKeyAlgorithmTags.EDDSA: + case PublicKeyAlgorithmTags.EDDSA_LEGACY: { - PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(privKey.getEncoded()); - - try + return getPrivateBCPGKey(privKey, new BCPGKeyOperation() { - return new EdSecretBCPGKey( - new BigInteger(1, ASN1OctetString.getInstance(pInfo.parsePrivateKey()).getOctets())); - } - catch (IOException e) + @Override + public BCPGKey getBCPGKey(byte[] pInfoEncoded) + { + return new EdSecretBCPGKey(new BigInteger(1, pInfoEncoded)); + } + }); + } + case PublicKeyAlgorithmTags.Ed25519: + { + return getPrivateBCPGKey(privKey, new BCPGKeyOperation() { - throw new PGPException(e.getMessage(), e); - } + @Override + public BCPGKey getBCPGKey(byte[] pInfoEncoded) + { + return new Ed25519SecretBCPGKey(pInfoEncoded); + } + }); + } + case PublicKeyAlgorithmTags.Ed448: + { + return getPrivateBCPGKey(privKey, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] pInfoEncoded) + { + return new Ed448SecretBCPGKey(pInfoEncoded); + } + }); } - case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: { DHPrivateKey esK = (DHPrivateKey)privKey; return new ElGamalSecretBCPGKey(esK.getX()); } - case PublicKeyAlgorithmTags.RSA_ENCRYPT: case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: @@ -420,13 +553,12 @@ private BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) RSAPrivateCrtKey rsK = (RSAPrivateCrtKey)privKey; return new RSASecretBCPGKey(rsK.getPrivateExponent(), rsK.getPrimeP(), rsK.getPrimeQ()); } - default: throw new PGPException("unknown key class"); } } - private BCPGKey getPublicBCPGKey(int algorithm, PGPAlgorithmParameters algorithmParameters, PublicKey pubKey, Date time) + private BCPGKey getPublicBCPGKey(int algorithm, PGPAlgorithmParameters algorithmParameters, PublicKey pubKey) throws PGPException { if (pubKey instanceof RSAPublicKey) @@ -451,7 +583,7 @@ else if (pubKey instanceof ECPublicKey) SubjectPublicKeyInfo keyInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()); // TODO: should probably match curve by comparison as well - ASN1ObjectIdentifier curveOid = ASN1ObjectIdentifier.getInstance(keyInfo.getAlgorithm().getParameters()); + ASN1ObjectIdentifier curveOid = ASN1ObjectIdentifier.getInstance(keyInfo.getAlgorithm().getParameters()); X9ECParametersHolder params = ECNamedCurveTable.getByOIDLazy(curveOid); @@ -460,12 +592,8 @@ else if (pubKey instanceof ECPublicKey) if (algorithm == PGPPublicKey.ECDH) { - PGPKdfParameters kdfParams = (PGPKdfParameters)algorithmParameters; - if (kdfParams == null) - { - // We default to these as they are specified as mandatory in RFC 6631. - kdfParams = new PGPKdfParameters(HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_128); - } + PGPKdfParameters kdfParams = implGetKdfParameters(curveOid, algorithmParameters); + return new ECDHPublicBCPGKey(curveOid, derQ.getPoint(), kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); } @@ -478,39 +606,107 @@ else if (algorithm == PGPPublicKey.ECDSA) throw new PGPException("unknown EC algorithm"); } } + else if (algorithm == PGPPublicKey.Ed25519) + { + return getPublicBCPGKey(pubKey, Ed25519PublicBCPGKey.LENGTH, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] key) + { + return new Ed25519PublicBCPGKey(key); + } + }); + } else if (pubKey.getAlgorithm().regionMatches(true, 0, "ED2", 0, 3)) { - SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()); - byte[] pointEnc = new byte[1 + Ed25519PublicKeyParameters.KEY_SIZE]; - - pointEnc[0] = 0x40; - System.arraycopy(pubInfo.getPublicKeyData().getBytes(), 0, pointEnc, 1, pointEnc.length - 1); - - return new EdDSAPublicBCPGKey(GNUObjectIdentifiers.Ed25519, new BigInteger(1, pointEnc)); + return new EdDSAPublicBCPGKey(GNUObjectIdentifiers.Ed25519, new BigInteger(1, getPointEncUncompressed(pubKey, Ed25519.PUBLIC_KEY_SIZE))); + } + else if (algorithm == PGPPublicKey.X25519) + { + return getPublicBCPGKey(pubKey, X25519PublicBCPGKey.LENGTH, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] key) + { + return new X25519PublicBCPGKey(key); + } + }); } else if (pubKey.getAlgorithm().regionMatches(true, 0, "X2", 0, 2)) { - SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()); - byte[] pointEnc = new byte[1 + X25519PublicKeyParameters.KEY_SIZE]; + PGPKdfParameters kdfParams = implGetKdfParameters(CryptlibObjectIdentifiers.curvey25519, algorithmParameters); - pointEnc[0] = 0x40; - System.arraycopy(pubInfo.getPublicKeyData().getBytes(), 0, pointEnc, 1, pointEnc.length - 1); - - PGPKdfParameters kdfParams = (PGPKdfParameters)algorithmParameters; - if (kdfParams == null) - { - // We default to these as they are specified as mandatory in RFC 6631. - kdfParams = new PGPKdfParameters(HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_128); - } - return new ECDHPublicBCPGKey(CryptlibObjectIdentifiers.curvey25519, new BigInteger(1, pointEnc), + return new ECDHPublicBCPGKey(CryptlibObjectIdentifiers.curvey25519, new BigInteger(1, getPointEncUncompressed(pubKey, X25519.SCALAR_SIZE)), kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); } + else if (algorithm == PGPPublicKey.Ed448) + { + return getPublicBCPGKey(pubKey, Ed448PublicBCPGKey.LENGTH, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] key) + { + return new Ed448PublicBCPGKey(key); + } + }); + } + else if (algorithm == PGPPublicKey.X448) + { + return getPublicBCPGKey(pubKey, X448PublicBCPGKey.LENGTH, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] key) + { + return new X448PublicBCPGKey(key); + } + }); + } else { throw new PGPException("unknown key class"); } } + @FunctionalInterface + private static interface BCPGKeyOperation + { + BCPGKey getBCPGKey(byte[] key); + } + + private static interface Operation + { + PrivateKeyInfo getPrivateKeyInfos() throws IOException; + } + + + private BCPGKey getPublicBCPGKey(PublicKey pubKey, int keySize, BCPGKeyOperation operation) + { + SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()); + byte[] pointEnc = new byte[keySize]; + + System.arraycopy(pubInfo.getPublicKeyData().getBytes(), 0, pointEnc, 0, pointEnc.length); + return operation.getBCPGKey(pointEnc); + } + + private byte[] getPointEncUncompressed(PublicKey pubKey, int publicKeySize) + { + SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()); + byte[] pointEnc = new byte[1 + publicKeySize]; + + pointEnc[0] = 0x40; + System.arraycopy(pubInfo.getPublicKeyData().getBytes(), 0, pointEnc, 1, pointEnc.length - 1); + return pointEnc; + } + + + private PrivateKey implGeneratePrivate(String keyAlgorithm, Operation operation) + throws GeneralSecurityException, PGPException, IOException + { + PKCS8EncodedKeySpec pkcs8Spec = new PKCS8EncodedKeySpec(operation.getPrivateKeyInfos().getEncoded()); + KeyFactory keyFactory = helper.createKeyFactory(keyAlgorithm); + return keyFactory.generatePrivate(pkcs8Spec); + } + private PrivateKey implGeneratePrivate(String keyAlgorithm, KeySpec keySpec) throws GeneralSecurityException, PGPException { @@ -539,7 +735,8 @@ private PrivateKey implGetPrivateKeyPKCS8(String keyAlgorithm, PrivateKeyInfo pr return implGeneratePrivate(keyAlgorithm, pkcs8Spec); } - private PublicKey implGetPublicKeyEC(String keyAlgorithm, ECPublicBCPGKey ecPub) throws GeneralSecurityException, IOException, PGPException + private PublicKey implGetPublicKeyEC(String keyAlgorithm, ECPublicBCPGKey ecPub) + throws GeneralSecurityException, IOException, PGPException { ASN1ObjectIdentifier curveOID = ecPub.getCurveOID(); X9ECParameters x9Params = JcaJcePGPUtil.getX9Parameters(curveOID); @@ -552,10 +749,30 @@ private PublicKey implGetPublicKeyEC(String keyAlgorithm, ECPublicBCPGKey ecPub) return implGeneratePublic(keyAlgorithm, ecPubSpec); } + private PublicKey implGetPublicKeyX509(byte[] pEnc, int pEncOff, ASN1ObjectIdentifier algorithm, String keyAlgorithm) + throws IOException, PGPException, GeneralSecurityException + { + return implGeneratePublic(keyAlgorithm, new X509EncodedKeySpec(new SubjectPublicKeyInfo( + new AlgorithmIdentifier(algorithm), Arrays.copyOfRange(pEnc, pEncOff, pEnc.length)).getEncoded())); + } + private PublicKey implGetPublicKeyX509(String keyAlgorithm, SubjectPublicKeyInfo subjectPublicKeyInfo) throws GeneralSecurityException, IOException, PGPException { X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(subjectPublicKeyInfo.getEncoded()); return implGeneratePublic(keyAlgorithm, x509Spec); } + + private PublicKey get25519PublicKey(BigInteger x, ASN1ObjectIdentifier algorithm, String keyAlgorithm, String name) + throws PGPException, GeneralSecurityException, IOException + { + byte[] pEnc = BigIntegers.asUnsignedByteArray(x); + + // skip the 0x40 header byte. + if (pEnc.length < 1 || 0x40 != pEnc[0]) + { + throw new IllegalArgumentException("Invalid " + name + "25519 public key"); + } + return implGetPublicKeyX509(pEnc, 1, algorithm, keyAlgorithm); + } } diff --git a/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/JceAEADCipherUtil.java b/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/JceAEADCipherUtil.java new file mode 100644 index 0000000000..946a18a18a --- /dev/null +++ b/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/JceAEADCipherUtil.java @@ -0,0 +1,19 @@ +package org.bouncycastle.openpgp.operator.jcajce; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; + +import org.bouncycastle.jcajce.spec.AEADParameterSpec; + +public class JceAEADCipherUtil +{ + static void setUpAeadCipher(Cipher aead, SecretKey secretKey, int mode, byte[] nonce, int aeadMacLen, byte[] aad) + throws InvalidKeyException, InvalidAlgorithmParameterException + { + AEADParameterSpec parameters = new AEADParameterSpec(nonce, aeadMacLen, aad); + aead.init(mode, secretKey, parameters); + } +} diff --git a/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/JcePGPDataEncryptorBuilder.java b/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/JcePGPDataEncryptorBuilder.java new file mode 100644 index 0000000000..ec0458ce02 --- /dev/null +++ b/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/JcePGPDataEncryptorBuilder.java @@ -0,0 +1,341 @@ +package org.bouncycastle.openpgp.operator.jcajce; + +import java.io.OutputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.Provider; +import java.security.SecureRandom; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; + +import org.bouncycastle.bcpg.AEADUtils; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyUtils; +import org.bouncycastle.jcajce.io.CipherOutputStream; +import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; +import org.bouncycastle.jcajce.util.NamedJcaJceHelper; +import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.operator.PGPAEADDataEncryptor; +import org.bouncycastle.openpgp.operator.PGPDataEncryptor; +import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.util.Arrays; + +/** + * {@link PGPDataEncryptorBuilder} implementation that sources cryptographic primitives using the + * JCE APIs. + *

      + * By default, cryptographic primitives will be loaded using the default JCE load order (i.e. + * without specifying a provider). + * A specific provider can be specified using one of the {@link #setProvider(String)} methods. + *

      + */ +public class JcePGPDataEncryptorBuilder + implements PGPDataEncryptorBuilder +{ + private final int encAlgorithm; + + private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); + private JceAEADUtil aeadHelper = new JceAEADUtil(helper); + private SecureRandom random; + private boolean withIntegrityPacket = true; + private int aeadAlgorithm = -1; + private int chunkSize; + private boolean isV5StyleAEAD = true; // TODO: change to false in 1.75 + + /** + * Constructs a new data encryptor builder for a specified cipher type. + * + * @param encAlgorithm one of the {@link SymmetricKeyAlgorithmTags supported symmetric cipher + * algorithms}. May not be {@link SymmetricKeyAlgorithmTags#NULL}. + */ + public JcePGPDataEncryptorBuilder(int encAlgorithm) + { + this.encAlgorithm = encAlgorithm; + + if (encAlgorithm == 0) + { + throw new IllegalArgumentException("null cipher specified"); + } + } + + /** + * Sets whether or not the resulting encrypted data will be protected using an integrity packet. + * + * @param withIntegrityPacket true if an integrity packet is to be included, false otherwise. + * @return the current builder. + */ + @Override + public PGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPacket) + { + this.withIntegrityPacket = withIntegrityPacket; + + return this; + } + + @Override + public PGPDataEncryptorBuilder setWithAEAD(int aeadAlgorithm, int chunkSize) + { + if (encAlgorithm != SymmetricKeyAlgorithmTags.AES_128 + && encAlgorithm != SymmetricKeyAlgorithmTags.AES_192 + && encAlgorithm != SymmetricKeyAlgorithmTags.AES_256 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_128 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_192 + && encAlgorithm != SymmetricKeyAlgorithmTags.CAMELLIA_256) + { + throw new IllegalStateException("AEAD algorithms can only be used with AES and Camellia"); + } + + if (chunkSize < 6) + { + throw new IllegalArgumentException("minimum chunkSize is 6"); + } + + this.aeadAlgorithm = aeadAlgorithm; + this.chunkSize = chunkSize - 6; + + return this; + } + + @Override + public PGPDataEncryptorBuilder setUseV5AEAD() + { + this.isV5StyleAEAD = true; + + return this; + } + + @Override + public PGPDataEncryptorBuilder setUseV6AEAD() + { + this.isV5StyleAEAD = false; + + return this; + } + + /** + * Sets the JCE provider to source cryptographic primitives from. + * + * @param provider the JCE provider to use. + * @return the current builder. + */ + public JcePGPDataEncryptorBuilder setProvider(Provider provider) + { + this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + this.aeadHelper = new JceAEADUtil(helper); + + return this; + } + + /** + * Sets the JCE provider to source cryptographic primitives from. + * + * @param providerName the name of the JCE provider to use. + * @return the current builder. + */ + public JcePGPDataEncryptorBuilder setProvider(String providerName) + { + this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + this.aeadHelper = new JceAEADUtil(helper); + + return this; + } + + /** + * Provide a user defined source of randomness. + *

      + * If no SecureRandom is configured, a default SecureRandom will be used. + *

      + * + * @param random the secure random to be used. + * @return the current builder. + */ + public JcePGPDataEncryptorBuilder setSecureRandom(SecureRandom random) + { + this.random = random; + + return this; + } + + @Override + public int getAlgorithm() + { + return encAlgorithm; + } + + @Override + public int getAeadAlgorithm() + { + return aeadAlgorithm; + } + + @Override + public int getChunkSize() + { + return chunkSize; + } + + @Override + public boolean isV5StyleAEAD() + { + return isV5StyleAEAD; + } + + @Override + public SecureRandom getSecureRandom() + { + if (random == null) + { + random = new SecureRandom(); + } + + return random; + } + + @Override + public PGPDataEncryptor build(byte[] keyBytes) + throws PGPException + { + if (aeadAlgorithm > 0) + { + return new MyAeadDataEncryptor(keyBytes); + } + return new MyPGPDataEncryptor(keyBytes); + } + + private class MyPGPDataEncryptor + implements PGPDataEncryptor + { + private final Cipher c; + + MyPGPDataEncryptor(byte[] keyBytes) + throws PGPException + { + c = helper.createStreamCipher(encAlgorithm, withIntegrityPacket); + + try + { + if (withIntegrityPacket) + { + byte[] iv = new byte[c.getBlockSize()]; + + c.init(Cipher.ENCRYPT_MODE, JcaJcePGPUtil.makeSymmetricKey(encAlgorithm, keyBytes), new IvParameterSpec(iv)); + } + else + { + c.init(Cipher.ENCRYPT_MODE, JcaJcePGPUtil.makeSymmetricKey(encAlgorithm, keyBytes)); + } + } + catch (InvalidKeyException e) + { + throw new PGPException("invalid key: " + e.getMessage(), e); + } + catch (InvalidAlgorithmParameterException e) + { + throw new PGPException("imvalid algorithm parameter: " + e.getMessage(), e); + } + } + + public OutputStream getOutputStream(OutputStream out) + { + return new CipherOutputStream(out, c); + } + + public PGPDigestCalculator getIntegrityCalculator() + { + if (withIntegrityPacket) + { + return new SHA1PGPDigestCalculator(); + } + + return null; + } + + public int getBlockSize() + { + return c.getBlockSize(); + } + } + + private class MyAeadDataEncryptor + implements PGPAEADDataEncryptor + { + private final boolean isV5StyleAEAD; + private final Cipher c; + private final byte[] keyBytes; + private final byte[] iv; + + /** + * Create a new data decryptor using AEAD. + * If OpenPGP v5 style AEAD is used, keyBytes contains the key. The IV is randomly generated. + * If however OpenPGP v6 style AEAD is used, keyBytes contains M+N-8 bytes. + * The first M bytes contain the key, the remaining N-8 bytes contain the IV. + * + * @param keyBytes key or key and iv + * @throws PGPException on encryption failure + */ + MyAeadDataEncryptor(byte[] keyBytes) + throws PGPException + { + this.isV5StyleAEAD = keyBytes.length == SymmetricKeyUtils.getKeyLengthInOctets(encAlgorithm); + if (isV5StyleAEAD) + { + this.keyBytes = keyBytes; + // V5 has a random IV + this.iv = new byte[AEADUtils.getIVLength((byte)aeadAlgorithm)]; + getSecureRandom().nextBytes(iv); + } + else + { + // V6 has the IV appended to the message key, so we need to split it + byte[][] keyAndIv = AEADUtils.splitMessageKeyAndIv(keyBytes, encAlgorithm, aeadAlgorithm); + this.keyBytes = keyAndIv[0]; + this.iv = keyAndIv[1]; + } + this.c = aeadHelper.createAEADCipher(encAlgorithm, aeadAlgorithm); + } + + public OutputStream getOutputStream(OutputStream out) + { + try + { + return new JceAEADUtil.PGPAeadOutputStream(isV5StyleAEAD, out, c, JcaJcePGPUtil.makeSymmetricKey(encAlgorithm, keyBytes), iv, encAlgorithm, aeadAlgorithm, chunkSize); + } + catch (Exception e) + { + throw new IllegalStateException("unable to process stream: " + e.getMessage()); + } + } + + public PGPDigestCalculator getIntegrityCalculator() + { + return null; + } + + public int getBlockSize() + { + return c.getBlockSize(); + } + + @Override + public int getAEADAlgorithm() + { + return aeadAlgorithm; + } + + @Override + public int getChunkSize() + { + return chunkSize; + } + + @Override + public byte[] getIV() + { + return Arrays.clone(iv); + } + + } +} diff --git a/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/OperatorHelper.java b/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/OperatorHelper.java index 93761aa75a..d6b97f042e 100644 --- a/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/OperatorHelper.java +++ b/pg/src/main/jdk1.4/org/bouncycastle/openpgp/operator/jcajce/OperatorHelper.java @@ -45,48 +45,12 @@ class OperatorHelper this.helper = helper; } - /** - * Return an appropriate name for the hash algorithm represented by the passed - * in hash algorithm ID number (JCA message digest naming convention). - * - * @param hashAlgorithm the algorithm ID for a hash algorithm. - * @return a String representation of the hash name. - */ - String getDigestName( - int hashAlgorithm) - throws PGPException - { - switch (hashAlgorithm) - { - case HashAlgorithmTags.SHA1: - return "SHA-1"; - case HashAlgorithmTags.MD2: - return "MD2"; - case HashAlgorithmTags.MD5: - return "MD5"; - case HashAlgorithmTags.RIPEMD160: - return "RIPEMD160"; - case HashAlgorithmTags.SHA256: - return "SHA-256"; - case HashAlgorithmTags.SHA384: - return "SHA-384"; - case HashAlgorithmTags.SHA512: - return "SHA-512"; - case HashAlgorithmTags.SHA224: - return "SHA-224"; - case HashAlgorithmTags.TIGER_192: - return "TIGER"; - default: - throw new PGPException("unknown hash algorithm tag in getDigestName: " + hashAlgorithm); - } - } - MessageDigest createDigest(int algorithm) throws GeneralSecurityException, PGPException { MessageDigest dig; - String digestName = getDigestName(algorithm); + String digestName = PGPUtil.getDigestName(algorithm); try { dig = helper.createMessageDigest(digestName); @@ -376,8 +340,11 @@ public Signature createSignature(int keyAlgorithm, int hashAlgorithm) case PublicKeyAlgorithmTags.ECDSA: encAlg = "ECDSA"; break; - case PublicKeyAlgorithmTags.EDDSA: + case PublicKeyAlgorithmTags.EDDSA_LEGACY: + case PublicKeyAlgorithmTags.Ed25519: return createSignature("Ed25519"); + case PublicKeyAlgorithmTags.Ed448: + return createSignature("Ed448"); default: throw new PGPException("unknown algorithm tag in signature:" + keyAlgorithm); } diff --git a/pg/src/main/jdk1.5/org/bouncycastle/gpg/SExprParser.java b/pg/src/main/jdk1.5/org/bouncycastle/gpg/SExprParser.java new file mode 100644 index 0000000000..c4583080e0 --- /dev/null +++ b/pg/src/main/jdk1.5/org/bouncycastle/gpg/SExprParser.java @@ -0,0 +1,566 @@ +package org.bouncycastle.gpg; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.math.BigInteger; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; +import org.bouncycastle.asn1.x9.ECNamedCurveTable; +import org.bouncycastle.asn1.x9.X9ECParametersHolder; +import org.bouncycastle.bcpg.BCPGKey; +import org.bouncycastle.bcpg.DSAPublicBCPGKey; +import org.bouncycastle.bcpg.DSASecretBCPGKey; +import org.bouncycastle.bcpg.ECDSAPublicBCPGKey; +import org.bouncycastle.bcpg.ECPublicBCPGKey; +import org.bouncycastle.bcpg.ECSecretBCPGKey; +import org.bouncycastle.bcpg.EdDSAPublicBCPGKey; +import org.bouncycastle.bcpg.EdSecretBCPGKey; +import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; +import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.RSAPublicBCPGKey; +import org.bouncycastle.bcpg.RSASecretBCPGKey; +import org.bouncycastle.bcpg.S2K; +import org.bouncycastle.bcpg.SecretKeyPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.crypto.ec.CustomNamedCurves; +import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPSecretKey; +import org.bouncycastle.openpgp.PGPUtil; +import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; +import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory; +import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.PGPSecretKeyDecryptorWithAAD; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.BigIntegers; +import org.bouncycastle.util.Integers; +import org.bouncycastle.util.Strings; + +/** + * A parser for secret keys stored in SExpr + */ +public class SExprParser +{ + private final PGPDigestCalculatorProvider digestProvider; + + /** + * Base constructor. + * + * @param digestProvider a provider for digest calculations. Used to confirm key protection hashes. + */ + public SExprParser(PGPDigestCalculatorProvider digestProvider) + { + this.digestProvider = digestProvider; + } + + private static final Map rsaLabels = new HashMap() + {{ + put(Integers.valueOf(ProtectionModeTags.OPENPGP_S2K3_OCB_AES), new String[]{"rsa", "n", "e", "protected-at"}); + put(Integers.valueOf(ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC), new String[]{"rsa", "n", "e", "d", "p", "q", "u", "protected-at"}); + }}; + private static final Map eccLabels = new HashMap() + {{ + put(Integers.valueOf(ProtectionModeTags.OPENPGP_S2K3_OCB_AES), new String[]{"ecc", "curve", "flags", "q", "protected-at"}); + put(Integers.valueOf(ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC), new String[]{"ecc", "curve", "q", "d", "protected-at"}); + }}; + + private static final Map dsaLabels = new HashMap() + {{ + put(Integers.valueOf(ProtectionModeTags.OPENPGP_S2K3_OCB_AES), new String[]{"dsa", "p", "q", "g", "y", "protected-at"}); + put(Integers.valueOf(ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC), new String[]{"dsa", "p", "q", "g", "y", "x", "protected-at"}); + }}; + + private static final Map elgLabels = new HashMap() + {{ + //https://github.com/gpg/gnupg/blob/40227e42ea0f2f1cf9c9f506375446648df17e8d/agent/cvt-openpgp.c#L217 + put(Integers.valueOf(ProtectionModeTags.OPENPGP_S2K3_OCB_AES), new String[]{"elg", "p", "q", "g", "y", "protected-at"}); + put(Integers.valueOf(ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC), new String[]{"elg", "p", "q", "g", "y", "x", "protected-at"}); + }}; + + private static final String[] rsaBigIntegers = new String[]{"n", "e"}; + private static final String[] dsaBigIntegers = new String[]{"p", "q", "g", "y"}; + private static final String[] elgBigIntegers = new String[]{"p", "g", "y"}; + + public interface ProtectionFormatTypeTags + { + int PRIVATE_KEY = 1; + int PROTECTED_PRIVATE_KEY = 2; + int SHADOWED_PRIVATE_KEY = 3; + int OPENPGP_PRIVATE_KEY = 4; + int PROTECTED_SHARED_SECRET = 5; + } + + private interface ProtectionModeTags + { + int OPENPGP_S2K3_SHA1_AES_CBC = 1; + int OPENPGP_S2K3_OCB_AES = 2; + int OPENPGP_NATIVE = 3; + } + + /** + * Parse a secret key from one of the GPG S expression keys associating it with the passed in public key. + * + * @return a secret key object. + */ + public PGPSecretKey parseSecretKey(InputStream inputStream, PBEProtectionRemoverFactory keyProtectionRemoverFactory, PGPPublicKey pubKey) + throws IOException, PGPException + { + if (pubKey == null) + { + throw new NullPointerException("Public key cannot be null"); + } + return parse(inputStream, keyProtectionRemoverFactory, null, pubKey); + } + + /** + * Parse a secret key from one of the GPG S expression keys. + * + * @return a secret key object. + */ + public PGPSecretKey parseSecretKey(InputStream inputStream, PBEProtectionRemoverFactory keyProtectionRemoverFactory, + KeyFingerPrintCalculator fingerPrintCalculator) + throws IOException, PGPException + { + return parse(inputStream, keyProtectionRemoverFactory, fingerPrintCalculator, null); + } + + private PGPSecretKey parse(InputStream inputStream, PBEProtectionRemoverFactory keyProtectionRemoverFactory, + KeyFingerPrintCalculator fingerPrintCalculator, PGPPublicKey pubKey) + throws IOException, PGPException + { + final int maxDepth = 10; + SExpression keyExpression = SExpression.parseCanonical(inputStream, maxDepth); + int type = getProtectionType(keyExpression.getString(0)); + if (type == ProtectionFormatTypeTags.PRIVATE_KEY || type == ProtectionFormatTypeTags.PROTECTED_PRIVATE_KEY || + type == ProtectionFormatTypeTags.SHADOWED_PRIVATE_KEY) + { + SExpression expression = keyExpression.getExpression(1); + String keyType = expression.getString(0); + PublicKeyAlgorithmTags[] secretKey = getPGPSecretKey(keyProtectionRemoverFactory, fingerPrintCalculator, + pubKey, maxDepth, type, expression, keyType, digestProvider); + return new PGPSecretKey((SecretKeyPacket)secretKey[0], (PGPPublicKey)secretKey[1]); + } + throw new PGPException("unknown key type found"); + } + + public static PublicKeyAlgorithmTags[] getPGPSecretKey(PBEProtectionRemoverFactory keyProtectionRemoverFactory, + KeyFingerPrintCalculator fingerPrintCalculator, PGPPublicKey pubKey, + int maxDepth, int type, final SExpression expression, String keyType, + PGPDigestCalculatorProvider digestProvider) + throws PGPException, IOException + { + SecretKeyPacket secretKeyPacket; + if (keyType.equals("ecc")) + { + BCPGKey basePubKey = getECCBasePublicKey(expression); + if (pubKey != null) + { + assertEccPublicKeyMath(basePubKey, pubKey); + } + else + { + PublicKeyPacket pubPacket = null; + if (basePubKey instanceof EdDSAPublicBCPGKey) + { + pubPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.EDDSA_LEGACY, new Date(), basePubKey); + } + else if (basePubKey instanceof ECPublicBCPGKey) + { + pubPacket = new PublicKeyPacket(PublicKeyAlgorithmTags.ECDSA, new Date(), basePubKey); + } + pubKey = new PGPPublicKey(pubPacket, fingerPrintCalculator); + } + secretKeyPacket = getSecKeyPacket(pubKey, keyProtectionRemoverFactory, maxDepth, type, expression, digestProvider, eccLabels, + new getSecKeyDataOperation() + { + @Override + public byte[] getSecKeyData(SExpression keyIn) + { + BigInteger d = BigIntegers.fromUnsignedByteArray(keyIn.getExpressionWithLabelOrFail("d").getBytes(1)); + final String curve = expression.getExpressionWithLabel("curve").getString(1); + if (curve.startsWith("NIST") || curve.startsWith("brain")) + { + return new ECSecretBCPGKey(d).getEncoded(); + } + else + { + return new EdSecretBCPGKey(d).getEncoded(); + } + } + }); + } + else if (keyType.equals("dsa")) + { + pubKey = getPublicKey(fingerPrintCalculator, pubKey, expression, PublicKeyAlgorithmTags.DSA, dsaBigIntegers, new getPublicKeyOperation() + { + public BCPGKey getBasePublicKey(BigInteger[] bigIntegers) + { + return new DSAPublicBCPGKey(bigIntegers[0], bigIntegers[1], bigIntegers[2], bigIntegers[3]); + } + + public void assertPublicKeyMatch(BCPGKey k1, BCPGKey k2) + throws PGPException + { + DSAPublicBCPGKey key1 = (DSAPublicBCPGKey)k1; + DSAPublicBCPGKey key2 = (DSAPublicBCPGKey)k2; + if (!key1.getP().equals(key2.getP()) || !key1.getQ().equals(key2.getQ()) + || !key1.getG().equals(key2.getG()) || !key1.getY().equals(key2.getY())) + { + throw new PGPException("passed in public key does not match secret key"); + } + } + }); + secretKeyPacket = getSecKeyPacket(pubKey, keyProtectionRemoverFactory, maxDepth, type, expression, digestProvider, dsaLabels, + new getSecKeyDataOperation() + { + @Override + public byte[] getSecKeyData(SExpression keyIn) + { + BigInteger x = BigIntegers.fromUnsignedByteArray(keyIn.getExpressionWithLabelOrFail("x").getBytes(1)); + return new DSASecretBCPGKey(x).getEncoded(); + } + }); + } + else if (keyType.equals("elg")) + { + pubKey = getPublicKey(fingerPrintCalculator, pubKey, expression, PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, elgBigIntegers, new getPublicKeyOperation() + { + public BCPGKey getBasePublicKey(BigInteger[] bigIntegers) + { + return new ElGamalPublicBCPGKey(bigIntegers[0], bigIntegers[1], bigIntegers[2]); + } + + public void assertPublicKeyMatch(BCPGKey k1, BCPGKey k2) + throws PGPException + { + ElGamalPublicBCPGKey key1 = (ElGamalPublicBCPGKey)k1; + ElGamalPublicBCPGKey key2 = (ElGamalPublicBCPGKey)k2; + if (!key1.getP().equals(key2.getP()) || !key1.getG().equals(key2.getG()) || !key1.getY().equals(key2.getY())) + { + throw new PGPException("passed in public key does not match secret key"); + } + } + }); + secretKeyPacket = getSecKeyPacket(pubKey, keyProtectionRemoverFactory, maxDepth, type, expression, digestProvider, elgLabels, + new getSecKeyDataOperation() + { + @Override + public byte[] getSecKeyData(SExpression keyIn) + { + BigInteger x = BigIntegers.fromUnsignedByteArray(keyIn.getExpressionWithLabelOrFail("x").getBytes(1)); + return new ElGamalSecretBCPGKey(x).getEncoded(); + } + }); + } + else if (keyType.equals("rsa")) + { + // TODO: type of RSA key? + pubKey = getPublicKey(fingerPrintCalculator, pubKey, expression, PublicKeyAlgorithmTags.RSA_GENERAL, rsaBigIntegers, new getPublicKeyOperation() + { + public BCPGKey getBasePublicKey(BigInteger[] bigIntegers) + { + return new RSAPublicBCPGKey(bigIntegers[0], bigIntegers[1]); + } + + public void assertPublicKeyMatch(BCPGKey k1, BCPGKey k2) + throws PGPException + { + RSAPublicBCPGKey key1 = (RSAPublicBCPGKey)k1; + RSAPublicBCPGKey key2 = (RSAPublicBCPGKey)k2; + if (!key1.getModulus().equals(key2.getModulus()) + || !key1.getPublicExponent().equals(key2.getPublicExponent())) + { + throw new PGPException("passed in public key does not match secret key"); + } + } + }); + secretKeyPacket = getSecKeyPacket(pubKey, keyProtectionRemoverFactory, maxDepth, type, expression, digestProvider, rsaLabels, + new getSecKeyDataOperation() + { + @Override + public byte[] getSecKeyData(SExpression keyIn) + { + BigInteger d = BigIntegers.fromUnsignedByteArray(keyIn.getExpressionWithLabelOrFail("d").getBytes(1)); + BigInteger p = BigIntegers.fromUnsignedByteArray(keyIn.getExpressionWithLabelOrFail("p").getBytes(1)); + BigInteger q = BigIntegers.fromUnsignedByteArray(keyIn.getExpressionWithLabelOrFail("q").getBytes(1)); + return new RSASecretBCPGKey(d, p, q).getEncoded(); + } + }); + } + else + { + throw new PGPException("unknown key type: " + keyType); + } + return new PublicKeyAlgorithmTags[]{secretKeyPacket, pubKey}; + } + + private interface getPublicKeyOperation + { + BCPGKey getBasePublicKey(BigInteger[] bigIntegers); + + void assertPublicKeyMatch(BCPGKey key1, BCPGKey key2) + throws PGPException; + } + + private static PGPPublicKey getPublicKey(KeyFingerPrintCalculator fingerPrintCalculator, PGPPublicKey pubKey, SExpression expression, + int publicKeyAlgorithmTags, String[] bigIntegerLabels, getPublicKeyOperation operation) + throws PGPException + { + int flag = 0, flag_break = (1 << bigIntegerLabels.length) - 1; + BigInteger[] bigIntegers = new BigInteger[bigIntegerLabels.length]; + for (Iterator it = expression.getValues().iterator(); it.hasNext();) + { + Object item = it.next(); + if (item instanceof SExpression) + { + SExpression exp = (SExpression)item; + String str = exp.getString(0); + for (int i = 0; i < bigIntegerLabels.length; ++i) + { + if ((flag & (1 << i)) == 0 && str.equals(bigIntegerLabels[i])) + { + bigIntegers[i] = BigIntegers.fromUnsignedByteArray(exp.getBytes(1)); + flag |= 1 << i; + if (flag == flag_break) + { + break; + } + } + } + } + } + if (flag != flag_break) + { + throw new IllegalArgumentException("The public key should not be null"); + } + BCPGKey basePubKey = operation.getBasePublicKey(bigIntegers); + if (pubKey != null) + { + operation.assertPublicKeyMatch(basePubKey, pubKey.getPublicKeyPacket().getKey()); + } + else + { + pubKey = new PGPPublicKey(new PublicKeyPacket(publicKeyAlgorithmTags, new Date(), basePubKey), fingerPrintCalculator); + } + return pubKey; + } + + private interface getSecKeyDataOperation + { + byte[] getSecKeyData(SExpression keyIn); + } + + private static SecretKeyPacket getSecKeyPacket(PGPPublicKey pubKey, PBEProtectionRemoverFactory keyProtectionRemoverFactory, int maxDepth, int type, + SExpression expression, PGPDigestCalculatorProvider digestProvider, + Map labels, getSecKeyDataOperation operation) + throws PGPException, IOException + { + byte[] secKeyData = null; + S2K s2K = null; + byte[] nonce = null; + SExpression keyIn; + if (type != ProtectionFormatTypeTags.SHADOWED_PRIVATE_KEY) + { + if (type == ProtectionFormatTypeTags.PROTECTED_PRIVATE_KEY) + { + SExpression protectedKey = expression.getExpressionWithLabel("protected"); + if (protectedKey == null) + { + throw new IllegalArgumentException(type + " does not have protected block"); + } + String protectionStr = protectedKey.getString(1); + int protection = getProtectionMode(protectionStr); + if (protection == ProtectionModeTags.OPENPGP_S2K3_OCB_AES || protection == ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC) + { + byte[] data; + SExpression protectionKeyParameters = protectedKey.getExpression(2); + SExpression s2kParams = protectionKeyParameters.getExpression(0); + // TODO select correct hash + s2K = new S2K(PGPUtil.getDigestIDForName(s2kParams.getString(0)), s2kParams.getBytes(1), s2kParams.getInt(2)); + nonce = protectionKeyParameters.getBytes(1); + PBESecretKeyDecryptor keyDecryptor = keyProtectionRemoverFactory.createDecryptor(protectionStr); + byte[] key = keyDecryptor.makeKeyFromPassPhrase(SymmetricKeyAlgorithmTags.AES_128, s2K); + byte[] keyData = protectedKey.getBytes(3); + if (protection == ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC) + { + data = keyDecryptor.recoverKeyData(SymmetricKeyAlgorithmTags.AES_128, key, nonce, keyData, 0, keyData.length); + keyIn = SExpression.parseCanonical(new ByteArrayInputStream(data), maxDepth); + if (digestProvider != null) + { + PGPDigestCalculator digestCalculator = digestProvider.get(HashAlgorithmTags.SHA1); + OutputStream dOut = digestCalculator.getOutputStream(); + byte[] aad = SExpression.buildExpression(expression, keyIn.getExpression(0), (String[])labels.get(Integers.valueOf(protection))).toCanonicalForm(); + dOut.write(aad); + byte[] check = digestCalculator.getDigest(); + byte[] hashBytes = keyIn.getExpression(1).getBytes(2); + if (!Arrays.constantTimeAreEqual(check, hashBytes)) + { + throw new PGPException("checksum on protected data failed in SExpr"); + } + } + keyIn = keyIn.getExpression(0); + } + else //ProtectionModeTags.OPENPGP_S2K3_OCB_AES + { + String[] filter = (String[])labels.get(Integers.valueOf(protection)); + if (filter == null) + { + // TODO could not get client to generate protected elgamal keys + throw new IllegalStateException("no decryption support for protected elgamal keys"); + } + byte[] aad = SExpression.buildExpression(expression, filter).toCanonicalForm(); + data = ((PGPSecretKeyDecryptorWithAAD)keyDecryptor).recoverKeyData(SymmetricKeyAlgorithmTags.AES_128, key, + nonce, aad, keyData, 0, keyData.length); + keyIn = SExpression.parseCanonical(new ByteArrayInputStream(data), maxDepth).getExpression(0); + } + } + else + { + // openpgp-native is not supported for now + throw new PGPException("unsupported protection type " + protectedKey.getString(1)); + } + } + else + { + keyIn = expression; + } + secKeyData = operation.getSecKeyData(keyIn); + } + return new SecretKeyPacket(pubKey.getPublicKeyPacket(), SymmetricKeyAlgorithmTags.NULL, s2K, nonce, secKeyData); + } + + private static BCPGKey getECCBasePublicKey(SExpression expression) + { + byte[] qoint = null; + String curve = null; + int flag = 0; + for (Iterator it = expression.getValues().iterator(); it.hasNext();) + { + Object item = it.next(); + if (item instanceof SExpression) + { + SExpression exp = (SExpression)item; + String label = exp.getString(0); + if (label.equals("curve")) + { + curve = exp.getString(1); + flag |= 1; + } + else if (label.equals("q")) + { + qoint = exp.getBytes(1); + flag |= 2; + } + if (flag == 3) + { + break; + } + } + } + if (flag != 3) + { + throw new IllegalArgumentException("no curve expression"); + } + else if (curve.startsWith("NIST")) + { + curve = curve.substring("NIST".length()).trim(); + } + String curve_lowercase = Strings.toLowerCase(curve); + if (curve_lowercase.equals("ed25519")) + { + return new EdDSAPublicBCPGKey(EdECObjectIdentifiers.id_Ed25519, new BigInteger(1, qoint)); + } + else if (curve_lowercase.equals("ed448")) + { + return new EdDSAPublicBCPGKey(EdECObjectIdentifiers.id_Ed448, new BigInteger(1, qoint)); + } + else + { + ASN1ObjectIdentifier oid = ECNamedCurveTable.getOID(curve); + X9ECParametersHolder holder = CustomNamedCurves.getByNameLazy(curve); + if (holder == null && oid != null) + { + holder = TeleTrusTNamedCurves.getByOIDLazy(oid); + } + if (holder == null) + { + throw new IllegalStateException("unable to resolve parameters for " + curve); + } + ECPoint pnt = holder.getCurve().decodePoint(qoint); + return new ECDSAPublicBCPGKey(oid, pnt); + } + } + + private static void assertEccPublicKeyMath(BCPGKey key1, PGPPublicKey key2) + throws PGPException + { + if (key1 instanceof ECDSAPublicBCPGKey) + { + ECPublicBCPGKey assocPubKey = (ECPublicBCPGKey)key2.getPublicKeyPacket().getKey(); + if (!((ECDSAPublicBCPGKey)key1).getCurveOID().equals(assocPubKey.getCurveOID()) + || !((ECDSAPublicBCPGKey)key1).getEncodedPoint().equals(assocPubKey.getEncodedPoint())) + { + throw new PGPException("passed in public key does not match secret key"); + } + } + else if (key1 instanceof EdDSAPublicBCPGKey) + { + EdDSAPublicBCPGKey assocPubKey = (EdDSAPublicBCPGKey)key2.getPublicKeyPacket().getKey(); + if (!((EdDSAPublicBCPGKey)key1).getCurveOID().equals(assocPubKey.getCurveOID()) + || !((EdDSAPublicBCPGKey)key1).getEncodedPoint().equals(assocPubKey.getEncodedPoint())) + { + throw new PGPException("passed in public key does not match secret key"); + } + } + else + { + throw new PGPException("unknown key type: " + (key1 != null ? key1.getClass().getName() : "null")); + } + } + + public static int getProtectionType(String str) + { + if (str.equals("private-key")) + { + return ProtectionFormatTypeTags.PRIVATE_KEY; + } + else if (str.equals("protected-private-key")) + { + return ProtectionFormatTypeTags.PROTECTED_PRIVATE_KEY; + } + else if (str.equals("shadowed-private-key")) + { + return ProtectionFormatTypeTags.SHADOWED_PRIVATE_KEY; + } + // The other two types are not supported for now + return -1; + } + + private static int getProtectionMode(String str) + { + if (str.equals("openpgp-s2k3-sha1-aes-cbc")) + { + return ProtectionModeTags.OPENPGP_S2K3_SHA1_AES_CBC; + } + else if (str.equals("openpgp-s2k3-ocb-aes")) + { + return ProtectionModeTags.OPENPGP_S2K3_OCB_AES; + } + // The other mode is not supported for now + return -1; + } +} \ No newline at end of file diff --git a/pg/src/main/jdk1.5/org/bouncycastle/openpgp/operator/bc/BcPublicKeyKeyEncryptionMethodGenerator.java b/pg/src/main/jdk1.5/org/bouncycastle/openpgp/operator/bc/BcPublicKeyKeyEncryptionMethodGenerator.java new file mode 100644 index 0000000000..1339e551c7 --- /dev/null +++ b/pg/src/main/jdk1.5/org/bouncycastle/openpgp/operator/bc/BcPublicKeyKeyEncryptionMethodGenerator.java @@ -0,0 +1,205 @@ +package org.bouncycastle.openpgp.operator.bc; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.SecureRandom; + +import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; +import org.bouncycastle.bcpg.ECDHPublicBCPGKey; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.crypto.AsymmetricBlockCipher; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.KeyGenerationParameters; +import org.bouncycastle.crypto.RawAgreement; +import org.bouncycastle.crypto.Wrapper; +import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; +import org.bouncycastle.crypto.agreement.X25519Agreement; +import org.bouncycastle.crypto.agreement.X448Agreement; +import org.bouncycastle.crypto.generators.ECKeyPairGenerator; +import org.bouncycastle.crypto.generators.X25519KeyPairGenerator; +import org.bouncycastle.crypto.generators.X448KeyPairGenerator; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.params.ECKeyGenerationParameters; +import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.crypto.params.X25519KeyGenerationParameters; +import org.bouncycastle.crypto.params.X25519PublicKeyParameters; +import org.bouncycastle.crypto.params.X448KeyGenerationParameters; +import org.bouncycastle.crypto.params.X448PublicKeyParameters; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.operator.PGPPad; +import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.RFC6637Utils; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.BigIntegers; + +/** + * A method generator for supporting public key based encryption operations. + */ +public class BcPublicKeyKeyEncryptionMethodGenerator + extends PublicKeyKeyEncryptionMethodGenerator +{ + private static final byte X_HDR = 0x40; + + private SecureRandom random; + private BcPGPKeyConverter keyConverter = new BcPGPKeyConverter(); + + /** + * Create a public key encryption method generator with the method to be based on the passed in key. + * + * @param key the public key to use for encryption. + */ + public BcPublicKeyKeyEncryptionMethodGenerator(PGPPublicKey key) + { + super(key); + } + + /** + * Provide a user defined source of randomness. + * + * @param random the secure random to be used. + * @return the current generator. + */ + public BcPublicKeyKeyEncryptionMethodGenerator setSecureRandom(SecureRandom random) + { + this.random = random; + + return this; + } + + protected byte[] encryptSessionInfo(PGPPublicKey pubKey, byte[] sessionInfo) + throws PGPException + { + try + { + AsymmetricKeyParameter cryptoPublicKey = keyConverter.getPublicKey(pubKey); + PublicKeyPacket pubKeyPacket = pubKey.getPublicKeyPacket(); + if (pubKey.getAlgorithm() == PublicKeyAlgorithmTags.ECDH) + { + ECDHPublicBCPGKey ecPubKey = (ECDHPublicBCPGKey)pubKeyPacket.getKey(); + byte[] userKeyingMaterial = RFC6637Utils.createUserKeyingMaterial(pubKeyPacket, new BcKeyFingerprintCalculator()); + if (ecPubKey.getCurveOID().equals(CryptlibObjectIdentifiers.curvey25519)) + { + AsymmetricCipherKeyPair ephKp = getAsymmetricCipherKeyPair(new X25519KeyPairGenerator(), new X25519KeyGenerationParameters(random)); + + byte[] secret = BcUtil.getSecret(new X25519Agreement(), ephKp.getPrivate(), cryptoPublicKey); + + byte[] ephPubEncoding = new byte[1 + X25519PublicKeyParameters.KEY_SIZE]; + ephPubEncoding[0] = X_HDR; + ((X25519PublicKeyParameters)ephKp.getPublic()).encode(ephPubEncoding, 1); + return encryptSessionInfo(sessionInfo, secret, userKeyingMaterial, ephPubEncoding, ecPubKey.getHashAlgorithm(), ecPubKey.getSymmetricKeyAlgorithm()); + } + else + { + AsymmetricCipherKeyPair ephKp = getAsymmetricCipherKeyPair(new ECKeyPairGenerator(), + new ECKeyGenerationParameters(((ECPublicKeyParameters)cryptoPublicKey).getParameters(), random)); + + ECDHBasicAgreement agreement = new ECDHBasicAgreement(); + agreement.init(ephKp.getPrivate()); + BigInteger S = agreement.calculateAgreement(cryptoPublicKey); + byte[] secret = BigIntegers.asUnsignedByteArray(agreement.getFieldSize(), S); + + byte[] ephPubEncoding = ((ECPublicKeyParameters)ephKp.getPublic()).getQ().getEncoded(false); + + return encryptSessionInfo(sessionInfo, secret, userKeyingMaterial, ephPubEncoding, ecPubKey.getHashAlgorithm(), ecPubKey.getSymmetricKeyAlgorithm()); + } + } + else if (pubKey.getAlgorithm() == PublicKeyAlgorithmTags.X25519) + { + return encryptSessionInfo(pubKeyPacket, sessionInfo, HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_128, "X25519", + new X25519KeyPairGenerator(), new X25519KeyGenerationParameters(random), new X25519Agreement(), cryptoPublicKey, X25519PublicKeyParameters.KEY_SIZE, + new ephPubEncodingOperation() + { + @Override + public void getEphPubEncoding(AsymmetricKeyParameter publicKey, byte[] ephPubEncoding) + { + ((X25519PublicKeyParameters)publicKey).encode(ephPubEncoding, 0); + } + }); + } + else if (pubKey.getAlgorithm() == PublicKeyAlgorithmTags.X448) + { + return encryptSessionInfo(pubKeyPacket, sessionInfo, HashAlgorithmTags.SHA512, SymmetricKeyAlgorithmTags.AES_256, "X448", + new X448KeyPairGenerator(), new X448KeyGenerationParameters(random), new X448Agreement(), cryptoPublicKey, X448PublicKeyParameters.KEY_SIZE, + new ephPubEncodingOperation() + { + @Override + public void getEphPubEncoding(AsymmetricKeyParameter publicKey, byte[] ephPubEncoding) + { + ((X448PublicKeyParameters)publicKey).encode(ephPubEncoding, 0); + } + }); + } + else + { + AsymmetricBlockCipher c = BcImplProvider.createPublicKeyCipher(pubKey.getAlgorithm()); + + c.init(true, new ParametersWithRandom(cryptoPublicKey, random)); + + return c.processBlock(sessionInfo, 0, sessionInfo.length); + } + } + catch (Exception e) + { + throw new PGPException("exception encrypting session info: " + e.getMessage(), e); + } + } + + @FunctionalInterface + private interface ephPubEncodingOperation + { + void getEphPubEncoding(AsymmetricKeyParameter publicKey, byte[] ephPubEncoding); + } + + private byte[] encryptSessionInfo(byte[] sessionInfo, byte[] secret, + byte[] userKeyingMaterial, byte[] ephPubEncoding, int hashAlgorithm, int symmetricKeyAlgorithm) + throws IOException, PGPException + { + RFC6637KDFCalculator rfc6637KDFCalculator = new RFC6637KDFCalculator( + new BcPGPDigestCalculatorProvider().get(hashAlgorithm), symmetricKeyAlgorithm); + KeyParameter key = new KeyParameter(rfc6637KDFCalculator.createKey(secret, userKeyingMaterial)); + + byte[] paddedSessionData = PGPPad.padSessionData(sessionInfo, sessionKeyObfuscation); + + return getSessionInfo(ephPubEncoding, getWrapper(symmetricKeyAlgorithm, key, paddedSessionData)); + } + + private byte[] encryptSessionInfo(PublicKeyPacket pubKeyPacket, byte[] sessionInfo, int hashAlgorithm, int symmetricKeyAlgorithm, String algorithmName, + AsymmetricCipherKeyPairGenerator gen, KeyGenerationParameters parameters, RawAgreement agreement, AsymmetricKeyParameter cryptoPublicKey, + int keySize, ephPubEncodingOperation ephPubEncodingOperation) + throws PGPException, IOException + { + AsymmetricCipherKeyPair ephKp = getAsymmetricCipherKeyPair(gen, parameters); + byte[] secret = BcUtil.getSecret(agreement, ephKp.getPrivate(), cryptoPublicKey); + byte[] ephPubEncoding = new byte[keySize]; + ephPubEncodingOperation.getEphPubEncoding(ephKp.getPublic(), ephPubEncoding); + KeyParameter key = new KeyParameter(RFC6637KDFCalculator.createKey(hashAlgorithm, symmetricKeyAlgorithm, + Arrays.concatenate(ephPubEncoding, pubKeyPacket.getKey().getEncoded(), secret), "OpenPGP " + algorithmName)); + //No checksum and padding + byte[] sessionData = new byte[sessionInfo.length - 3]; + System.arraycopy(sessionInfo, 1, sessionData, 0, sessionData.length); + + return getSessionInfo(ephPubEncoding, sessionInfo[0], getWrapper(symmetricKeyAlgorithm, key, sessionData)); + } + + private byte[] getWrapper(int symmetricKeyAlgorithm, KeyParameter key, byte[] sessionData) + throws PGPException + { + Wrapper c = BcImplProvider.createWrapper(symmetricKeyAlgorithm); + c.init(true, new ParametersWithRandom(key, random)); + return c.wrap(sessionData, 0, sessionData.length); + } + + private AsymmetricCipherKeyPair getAsymmetricCipherKeyPair(AsymmetricCipherKeyPairGenerator gen, KeyGenerationParameters parameters) + { + gen.init(parameters); + return gen.generateKeyPair(); + } +} \ No newline at end of file diff --git a/pg/src/main/jdk1.5/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.java b/pg/src/main/jdk1.5/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.java new file mode 100644 index 0000000000..fbe0038278 --- /dev/null +++ b/pg/src/main/jdk1.5/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.java @@ -0,0 +1,754 @@ +package org.bouncycastle.openpgp.operator.jcajce; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.AlgorithmParameters; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.Provider; +import java.security.PublicKey; +import java.security.interfaces.DSAParams; +import java.security.interfaces.DSAPrivateKey; +import java.security.interfaces.DSAPublicKey; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.DSAPrivateKeySpec; +import java.security.spec.DSAPublicKeySpec; +import java.security.spec.ECGenParameterSpec; +import java.security.spec.ECParameterSpec; +import java.security.spec.ECPrivateKeySpec; +import java.security.spec.ECPublicKeySpec; +import java.security.spec.InvalidParameterSpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Date; + +import javax.crypto.interfaces.DHPrivateKey; +import javax.crypto.interfaces.DHPublicKey; +import javax.crypto.spec.DHParameterSpec; +import javax.crypto.spec.DHPrivateKeySpec; +import javax.crypto.spec.DHPublicKeySpec; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; +import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.asn1.gnu.GNUObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x9.ECNamedCurveTable; +import org.bouncycastle.asn1.x9.X9ECParameters; +import org.bouncycastle.asn1.x9.X9ECParametersHolder; +import org.bouncycastle.asn1.x9.X9ECPoint; +import org.bouncycastle.bcpg.BCPGKey; +import org.bouncycastle.bcpg.DSAPublicBCPGKey; +import org.bouncycastle.bcpg.DSASecretBCPGKey; +import org.bouncycastle.bcpg.ECDHPublicBCPGKey; +import org.bouncycastle.bcpg.ECDSAPublicBCPGKey; +import org.bouncycastle.bcpg.ECPublicBCPGKey; +import org.bouncycastle.bcpg.ECSecretBCPGKey; +import org.bouncycastle.bcpg.Ed25519PublicBCPGKey; +import org.bouncycastle.bcpg.Ed25519SecretBCPGKey; +import org.bouncycastle.bcpg.Ed448PublicBCPGKey; +import org.bouncycastle.bcpg.Ed448SecretBCPGKey; +import org.bouncycastle.bcpg.EdDSAPublicBCPGKey; +import org.bouncycastle.bcpg.EdSecretBCPGKey; +import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; +import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.RSAPublicBCPGKey; +import org.bouncycastle.bcpg.RSASecretBCPGKey; +import org.bouncycastle.bcpg.X25519PublicBCPGKey; +import org.bouncycastle.bcpg.X25519SecretBCPGKey; +import org.bouncycastle.bcpg.X448PublicBCPGKey; +import org.bouncycastle.bcpg.X448SecretBCPGKey; +import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; +import org.bouncycastle.jcajce.util.NamedJcaJceHelper; +import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; +import org.bouncycastle.math.ec.ECPoint; + +import org.bouncycastle.math.ec.rfc7748.X25519; +import org.bouncycastle.math.ec.rfc8032.Ed25519; +import org.bouncycastle.openpgp.PGPAlgorithmParameters; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPKdfParameters; +import org.bouncycastle.openpgp.PGPPrivateKey; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; +import org.bouncycastle.openpgp.operator.PGPKeyConverter; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.BigIntegers; + +public class JcaPGPKeyConverter + extends PGPKeyConverter +{ + private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); + private KeyFingerPrintCalculator fingerPrintCalculator = new JcaKeyFingerprintCalculator(); + + public JcaPGPKeyConverter setProvider(Provider provider) + { + this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + + return this; + } + + public JcaPGPKeyConverter setProvider(String providerName) + { + this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + + return this; + } + + /** + * Convert a PrivateKey into a PGPPrivateKey. + * + * @param pub the corresponding PGPPublicKey to privKey. + * @param privKey the private key for the key in pub. + * @return a PGPPrivateKey + * @throws PGPException + */ + public PGPPrivateKey getPGPPrivateKey(PGPPublicKey pub, PrivateKey privKey) + throws PGPException + { + BCPGKey privPk = getPrivateBCPGKey(pub, privKey); + + return new PGPPrivateKey(pub.getKeyID(), pub.getPublicKeyPacket(), privPk); + } + + /** + * Create a PGPPublicKey from the passed in JCA one. + *

      + * Note: the time passed in affects the value of the key's keyID, so you probably only want + * to do this once for a JCA key, or make sure you keep track of the time you used. + *

      + * + * @param algorithm asymmetric algorithm type representing the public key. + * @param algorithmParameters additional parameters to be stored against the public key. + * @param pubKey actual public key to associate. + * @param time date of creation. + * @throws PGPException on key creation problem. + */ + public PGPPublicKey getPGPPublicKey(int algorithm, PGPAlgorithmParameters algorithmParameters, PublicKey pubKey, Date time) + throws PGPException + { + BCPGKey bcpgKey = getPublicBCPGKey(algorithm, algorithmParameters, pubKey); + + return new PGPPublicKey(new PublicKeyPacket(algorithm, time, bcpgKey), fingerPrintCalculator); + } + + /** + * Create a PGPPublicKey from the passed in JCA one. + *

      + * Note: the time passed in affects the value of the key's keyID, so you probably only want + * to do this once for a JCA key, or make sure you keep track of the time you used. + *

      + * + * @param algorithm asymmetric algorithm type representing the public key. + * @param pubKey actual public key to associate. + * @param time date of creation. + * @throws PGPException on key creation problem. + */ + public PGPPublicKey getPGPPublicKey(int algorithm, PublicKey pubKey, Date time) + throws PGPException + { + return getPGPPublicKey(algorithm, null, pubKey, time); + } + + public PrivateKey getPrivateKey(PGPPrivateKey privKey) + throws PGPException + { + if (privKey instanceof JcaPGPPrivateKey) + { + return ((JcaPGPPrivateKey)privKey).getPrivateKey(); + } + + PublicKeyPacket pubPk = privKey.getPublicKeyPacket(); + final BCPGKey privPk = privKey.getPrivateKeyDataPacket(); + + try + { + switch (pubPk.getAlgorithm()) + { + case PublicKeyAlgorithmTags.DSA: + { + DSAPublicBCPGKey dsaPub = (DSAPublicBCPGKey)pubPk.getKey(); + DSASecretBCPGKey dsaPriv = (DSASecretBCPGKey)privPk; + DSAPrivateKeySpec dsaPrivSpec = new DSAPrivateKeySpec(dsaPriv.getX(), dsaPub.getP(), dsaPub.getQ(), + dsaPub.getG()); + return implGeneratePrivate("DSA", dsaPrivSpec); + } + + case PublicKeyAlgorithmTags.ECDH: + { + ECDHPublicBCPGKey ecdhPub = (ECDHPublicBCPGKey)pubPk.getKey(); + ECSecretBCPGKey ecdhK = (ECSecretBCPGKey)privPk; + + if (CryptlibObjectIdentifiers.curvey25519.equals(ecdhPub.getCurveOID())) + { + // 'reverse' because the native format for X25519 private keys is little-endian + return implGeneratePrivate("XDH", new Operation() + { + @Override + public PrivateKeyInfo getPrivateKeyInfos() + throws IOException + { + return getPrivateKeyInfo(EdECObjectIdentifiers.id_X25519, + Arrays.reverseInPlace(BigIntegers.asUnsignedByteArray(((ECSecretBCPGKey)privPk).getX()))); + } + }); + } + else + { + return implGetPrivateKeyEC("ECDH", ecdhPub, ecdhK); + } + } + case PublicKeyAlgorithmTags.X25519: + { + return implGeneratePrivate("XDH", new Operation() + { + @Override + public PrivateKeyInfo getPrivateKeyInfos() + throws IOException + { + return getPrivateKeyInfo(EdECObjectIdentifiers.id_X25519, + X25519SecretBCPGKey.LENGTH, Arrays.reverseInPlace(privPk.getEncoded())); + } + }); + } + case PublicKeyAlgorithmTags.X448: + { + return implGeneratePrivate("XDH", new Operation() + { + @Override + public PrivateKeyInfo getPrivateKeyInfos() + throws IOException + { + return getPrivateKeyInfo(EdECObjectIdentifiers.id_X448, + X448SecretBCPGKey.LENGTH, Arrays.reverseInPlace(privPk.getEncoded())); + } + }); + } + case PublicKeyAlgorithmTags.ECDSA: + { + return implGetPrivateKeyEC("ECDSA", (ECDSAPublicBCPGKey)pubPk.getKey(), (ECSecretBCPGKey)privPk); + } + case PublicKeyAlgorithmTags.EDDSA_LEGACY: + { + return implGeneratePrivate("EdDSA", new Operation() + { + @Override + public PrivateKeyInfo getPrivateKeyInfos() + throws IOException + { + return getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed25519, + BigIntegers.asUnsignedByteArray(Ed25519.SECRET_KEY_SIZE, ((EdSecretBCPGKey)privPk).getX())); + } + }); + } + case PublicKeyAlgorithmTags.Ed25519: + { + return implGeneratePrivate("EdDSA", new Operation() + { + @Override + public PrivateKeyInfo getPrivateKeyInfos() + throws IOException + { + return getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed25519, + Ed25519SecretBCPGKey.LENGTH, privPk.getEncoded()); + } + }); + } + case PublicKeyAlgorithmTags.Ed448: + { + return implGeneratePrivate("EdDSA", new Operation() + { + @Override + public PrivateKeyInfo getPrivateKeyInfos() + throws IOException + { + return getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed448, + Ed448SecretBCPGKey.LENGTH, privPk.getEncoded()); + } + }); + } + case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: + case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: + { + ElGamalPublicBCPGKey elPub = (ElGamalPublicBCPGKey)pubPk.getKey(); + ElGamalSecretBCPGKey elPriv = (ElGamalSecretBCPGKey)privPk; + DHPrivateKeySpec elSpec = new DHPrivateKeySpec(elPriv.getX(), elPub.getP(), elPub.getG()); + return implGeneratePrivate("ElGamal", elSpec); + } + + case PublicKeyAlgorithmTags.RSA_ENCRYPT: + case PublicKeyAlgorithmTags.RSA_GENERAL: + case PublicKeyAlgorithmTags.RSA_SIGN: + { + RSAPublicBCPGKey rsaPub = (RSAPublicBCPGKey)pubPk.getKey(); + RSASecretBCPGKey rsaPriv = (RSASecretBCPGKey)privPk; + RSAPrivateCrtKeySpec rsaPrivSpec = new RSAPrivateCrtKeySpec(rsaPriv.getModulus(), + rsaPub.getPublicExponent(), rsaPriv.getPrivateExponent(), rsaPriv.getPrimeP(), rsaPriv.getPrimeQ(), + rsaPriv.getPrimeExponentP(), rsaPriv.getPrimeExponentQ(), rsaPriv.getCrtCoefficient()); + return implGeneratePrivate("RSA", rsaPrivSpec); + } + + default: + throw new PGPException("unknown public key algorithm encountered: " + pubPk.getAlgorithm()); + } + } + catch (PGPException e) + { + throw e; + } + catch (Exception e) + { + throw new PGPException("Exception constructing key", e); + } + } + + public PublicKey getPublicKey(PGPPublicKey publicKey) + throws PGPException + { + PublicKeyPacket publicPk = publicKey.getPublicKeyPacket(); + + try + { + switch (publicPk.getAlgorithm()) + { + case PublicKeyAlgorithmTags.DSA: + { + DSAPublicBCPGKey dsaK = (DSAPublicBCPGKey)publicPk.getKey(); + DSAPublicKeySpec dsaSpec = new DSAPublicKeySpec(dsaK.getY(), dsaK.getP(), dsaK.getQ(), dsaK.getG()); + return implGeneratePublic("DSA", dsaSpec); + } + + case PublicKeyAlgorithmTags.ECDH: + { + ECDHPublicBCPGKey ecdhK = (ECDHPublicBCPGKey)publicPk.getKey(); + + if (ecdhK.getCurveOID().equals(CryptlibObjectIdentifiers.curvey25519)) + { + return get25519PublicKey(ecdhK.getEncodedPoint(), EdECObjectIdentifiers.id_X25519, "XDH", "Curve"); + } + else + { + return implGetPublicKeyEC("ECDH", ecdhK); + } + } + case PublicKeyAlgorithmTags.X25519: + { + return implGetPublicKeyX509(publicPk.getKey().getEncoded(), 0, EdECObjectIdentifiers.id_X25519, "XDH"); + } + case PublicKeyAlgorithmTags.X448: + { + return implGetPublicKeyX509(publicPk.getKey().getEncoded(), 0, EdECObjectIdentifiers.id_X448, "XDH"); + } + case PublicKeyAlgorithmTags.ECDSA: + return implGetPublicKeyEC("ECDSA", (ECDSAPublicBCPGKey)publicPk.getKey()); + + case PublicKeyAlgorithmTags.EDDSA_LEGACY: + { + return get25519PublicKey(((EdDSAPublicBCPGKey)publicPk.getKey()).getEncodedPoint(), EdECObjectIdentifiers.id_Ed25519, "EdDSA", "Ed"); + } + case PublicKeyAlgorithmTags.Ed25519: + { + BCPGKey key = publicPk.getKey(); + if (key instanceof Ed25519PublicBCPGKey) + { + return implGetPublicKeyX509(BigIntegers.asUnsignedByteArray(new BigInteger(1, publicPk.getKey().getEncoded())), + 0, EdECObjectIdentifiers.id_Ed25519, "EdDSA"); + } + else + { + return implGetPublicKeyX509(BigIntegers.asUnsignedByteArray(((EdDSAPublicBCPGKey)publicPk.getKey()).getEncodedPoint()), + 0, EdECObjectIdentifiers.id_Ed25519, "EdDSA"); + } + } + case PublicKeyAlgorithmTags.Ed448: + { + return implGetPublicKeyX509(BigIntegers.asUnsignedByteArray(new BigInteger(1, publicPk.getKey().getEncoded())), + 0, EdECObjectIdentifiers.id_Ed448, "EdDSA"); + } + case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: + case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: + { + ElGamalPublicBCPGKey elK = (ElGamalPublicBCPGKey)publicPk.getKey(); + DHPublicKeySpec elSpec = new DHPublicKeySpec(elK.getY(), elK.getP(), elK.getG()); + return implGeneratePublic("ElGamal", elSpec); + } + + case PublicKeyAlgorithmTags.RSA_ENCRYPT: + case PublicKeyAlgorithmTags.RSA_GENERAL: + case PublicKeyAlgorithmTags.RSA_SIGN: + { + RSAPublicBCPGKey rsaK = (RSAPublicBCPGKey)publicPk.getKey(); + RSAPublicKeySpec rsaSpec = new RSAPublicKeySpec(rsaK.getModulus(), rsaK.getPublicExponent()); + return implGeneratePublic("RSA", rsaSpec); + } + + default: + throw new PGPException("unknown public key algorithm encountered: " + publicPk.getAlgorithm()); + } + } + catch (PGPException e) + { + throw e; + } + catch (Exception e) + { + throw new PGPException("exception constructing public key", e); + } + } + + private ECParameterSpec getECParameterSpec(ASN1ObjectIdentifier curveOid, X9ECParameters x9Params) + throws InvalidParameterSpecException, NoSuchProviderException, NoSuchAlgorithmException + { + AlgorithmParameters params = helper.createAlgorithmParameters("EC"); + + params.init(new ECGenParameterSpec(ECNamedCurveTable.getName(curveOid))); + + return params.getParameterSpec(ECParameterSpec.class); + } + + private BCPGKey getPrivateBCPGKey(PrivateKey privKey, BCPGKeyOperation operation) + throws PGPException + { + PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(privKey.getEncoded()); + + try + { + // 'reverse' because the native format for X25519 private keys is little-endian + return operation.getBCPGKey(ASN1OctetString.getInstance(pInfo.parsePrivateKey()).getOctets()); + } + catch (IOException e) + { + throw new PGPException(e.getMessage(), e); + } + } + + private BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws PGPException + { + switch (pub.getAlgorithm()) + { + case PublicKeyAlgorithmTags.DSA: + { + DSAPrivateKey dsK = (DSAPrivateKey)privKey; + return new DSASecretBCPGKey(dsK.getX()); + } + + case PublicKeyAlgorithmTags.ECDH: + { + if (privKey instanceof ECPrivateKey) + { + ECPrivateKey ecK = (ECPrivateKey)privKey; + return new ECSecretBCPGKey(ecK.getS()); + } + else + { + // 'reverse' because the native format for X25519 private keys is little-endian + return getPrivateBCPGKey(privKey, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] pInfoEncoded) + { + return new ECSecretBCPGKey(new BigInteger(1, Arrays.reverse(pInfoEncoded))); + } + }); + } + } + case PublicKeyAlgorithmTags.X25519: + { + // 'reverse' because the native format for X25519 private keys is little-endian + return getPrivateBCPGKey(privKey, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] pInfoEncoded) + { + return new X25519SecretBCPGKey(Arrays.reverse(pInfoEncoded)); + } + }); + } + case PublicKeyAlgorithmTags.X448: + { + // 'reverse' because the native format for X448 private keys is little-endian + return getPrivateBCPGKey(privKey, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] pInfoEncoded) + { + return new X448SecretBCPGKey(Arrays.reverse(pInfoEncoded)); + } + }); + } + case PublicKeyAlgorithmTags.ECDSA: + { + return new ECSecretBCPGKey(((ECPrivateKey)privKey).getS()); + } + case PublicKeyAlgorithmTags.EDDSA_LEGACY: + { + return getPrivateBCPGKey(privKey, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] pInfoEncoded) + { + return new EdSecretBCPGKey(new BigInteger(1, pInfoEncoded)); + } + }); + } + case PublicKeyAlgorithmTags.Ed25519: + { + return getPrivateBCPGKey(privKey, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] pInfoEncoded) + { + return new Ed25519SecretBCPGKey(pInfoEncoded); + } + }); + } + case PublicKeyAlgorithmTags.Ed448: + { + return getPrivateBCPGKey(privKey, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] pInfoEncoded) + { + return new Ed448SecretBCPGKey(pInfoEncoded); + } + }); + } + case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: + case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: + { + DHPrivateKey esK = (DHPrivateKey)privKey; + return new ElGamalSecretBCPGKey(esK.getX()); + } + case PublicKeyAlgorithmTags.RSA_ENCRYPT: + case PublicKeyAlgorithmTags.RSA_GENERAL: + case PublicKeyAlgorithmTags.RSA_SIGN: + { + RSAPrivateCrtKey rsK = (RSAPrivateCrtKey)privKey; + return new RSASecretBCPGKey(rsK.getPrivateExponent(), rsK.getPrimeP(), rsK.getPrimeQ()); + } + default: + throw new PGPException("unknown key class"); + } + } + + private BCPGKey getPublicBCPGKey(int algorithm, PGPAlgorithmParameters algorithmParameters, PublicKey pubKey) + throws PGPException + { + if (pubKey instanceof RSAPublicKey) + { + RSAPublicKey rK = (RSAPublicKey)pubKey; + return new RSAPublicBCPGKey(rK.getModulus(), rK.getPublicExponent()); + } + else if (pubKey instanceof DSAPublicKey) + { + DSAPublicKey dK = (DSAPublicKey)pubKey; + DSAParams dP = dK.getParams(); + return new DSAPublicBCPGKey(dP.getP(), dP.getQ(), dP.getG(), dK.getY()); + } + else if (pubKey instanceof DHPublicKey) + { + DHPublicKey eK = (DHPublicKey)pubKey; + DHParameterSpec eS = eK.getParams(); + return new ElGamalPublicBCPGKey(eS.getP(), eS.getG(), eK.getY()); + } + else if (pubKey instanceof ECPublicKey) + { + SubjectPublicKeyInfo keyInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()); + + // TODO: should probably match curve by comparison as well + ASN1ObjectIdentifier curveOid = ASN1ObjectIdentifier.getInstance(keyInfo.getAlgorithm().getParameters()); + + X9ECParametersHolder params = ECNamedCurveTable.getByOIDLazy(curveOid); + + ASN1OctetString key = new DEROctetString(keyInfo.getPublicKeyData().getBytes()); + X9ECPoint derQ = new X9ECPoint(params.getCurve(), key); + + if (algorithm == PGPPublicKey.ECDH) + { + PGPKdfParameters kdfParams = implGetKdfParameters(curveOid, algorithmParameters); + + return new ECDHPublicBCPGKey(curveOid, derQ.getPoint(), kdfParams.getHashAlgorithm(), + kdfParams.getSymmetricWrapAlgorithm()); + } + else if (algorithm == PGPPublicKey.ECDSA) + { + return new ECDSAPublicBCPGKey(curveOid, derQ.getPoint()); + } + else + { + throw new PGPException("unknown EC algorithm"); + } + } + else if (algorithm == PGPPublicKey.Ed25519) + { + return getPublicBCPGKey(pubKey, Ed25519PublicBCPGKey.LENGTH, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] key) + { + return new Ed25519PublicBCPGKey(key); + } + }); + } + else if (pubKey.getAlgorithm().regionMatches(true, 0, "ED2", 0, 3)) + { + return new EdDSAPublicBCPGKey(GNUObjectIdentifiers.Ed25519, new BigInteger(1, getPointEncUncompressed(pubKey, Ed25519.PUBLIC_KEY_SIZE))); + } + else if (algorithm == PGPPublicKey.X25519) + { + return getPublicBCPGKey(pubKey, X25519PublicBCPGKey.LENGTH, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] key) + { + return new X25519PublicBCPGKey(key); + } + }); + } + else if (pubKey.getAlgorithm().regionMatches(true, 0, "X2", 0, 2)) + { + PGPKdfParameters kdfParams = implGetKdfParameters(CryptlibObjectIdentifiers.curvey25519, algorithmParameters); + + return new ECDHPublicBCPGKey(CryptlibObjectIdentifiers.curvey25519, new BigInteger(1, getPointEncUncompressed(pubKey, X25519.SCALAR_SIZE)), + kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); + } + else if (algorithm == PGPPublicKey.Ed448) + { + return getPublicBCPGKey(pubKey, Ed448PublicBCPGKey.LENGTH, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] key) + { + return new Ed448PublicBCPGKey(key); + } + }); + } + else if (algorithm == PGPPublicKey.X448) + { + return getPublicBCPGKey(pubKey, X448PublicBCPGKey.LENGTH, new BCPGKeyOperation() + { + @Override + public BCPGKey getBCPGKey(byte[] key) + { + return new X448PublicBCPGKey(key); + } + }); + } + else + { + throw new PGPException("unknown key class"); + } + } + + @FunctionalInterface + private interface BCPGKeyOperation + { + BCPGKey getBCPGKey(byte[] key); + } + + private BCPGKey getPublicBCPGKey(PublicKey pubKey, int keySize, BCPGKeyOperation operation) + { + SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()); + byte[] pointEnc = new byte[keySize]; + + System.arraycopy(pubInfo.getPublicKeyData().getBytes(), 0, pointEnc, 0, pointEnc.length); + return operation.getBCPGKey(pointEnc); + } + + private byte[] getPointEncUncompressed(PublicKey pubKey, int publicKeySize) + { + SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()); + byte[] pointEnc = new byte[1 + publicKeySize]; + + pointEnc[0] = 0x40; + System.arraycopy(pubInfo.getPublicKeyData().getBytes(), 0, pointEnc, 1, pointEnc.length - 1); + return pointEnc; + } + + @FunctionalInterface + private interface Operation + { + PrivateKeyInfo getPrivateKeyInfos() + throws IOException; + } + + private PrivateKey implGeneratePrivate(String keyAlgorithm, Operation operation) + throws GeneralSecurityException, PGPException, IOException + { + PKCS8EncodedKeySpec pkcs8Spec = new PKCS8EncodedKeySpec(operation.getPrivateKeyInfos().getEncoded()); + KeyFactory keyFactory = helper.createKeyFactory(keyAlgorithm); + return keyFactory.generatePrivate(pkcs8Spec); + } + + private PrivateKey implGeneratePrivate(String keyAlgorithm, KeySpec keySpec) + throws GeneralSecurityException, PGPException + { + KeyFactory keyFactory = helper.createKeyFactory(keyAlgorithm); + return keyFactory.generatePrivate(keySpec); + } + + private PublicKey implGeneratePublic(String keyAlgorithm, KeySpec keySpec) + throws GeneralSecurityException, PGPException + { + KeyFactory keyFactory = helper.createKeyFactory(keyAlgorithm); + return keyFactory.generatePublic(keySpec); + } + + private PublicKey implGetPublicKeyX509(byte[] pEnc, int pEncOff, ASN1ObjectIdentifier algorithm, String keyAlgorithm) + throws IOException, PGPException, GeneralSecurityException + { + return implGeneratePublic(keyAlgorithm, new X509EncodedKeySpec(new SubjectPublicKeyInfo( + new AlgorithmIdentifier(algorithm), Arrays.copyOfRange(pEnc, pEncOff, pEnc.length)).getEncoded())); + } + + private PrivateKey implGetPrivateKeyEC(String keyAlgorithm, ECPublicBCPGKey ecPub, ECSecretBCPGKey ecPriv) + throws GeneralSecurityException, PGPException + { + ASN1ObjectIdentifier curveOid = ecPub.getCurveOID(); + ECPrivateKeySpec ecPrivSpec = new ECPrivateKeySpec(ecPriv.getX(), getECParameterSpec(curveOid, JcaJcePGPUtil.getX9Parameters(curveOid))); + return implGeneratePrivate(keyAlgorithm, ecPrivSpec); + } + + private PublicKey implGetPublicKeyEC(String keyAlgorithm, ECPublicBCPGKey ecPub) + throws GeneralSecurityException, IOException, PGPException + { + ASN1ObjectIdentifier curveOID = ecPub.getCurveOID(); + X9ECParameters x9Params = JcaJcePGPUtil.getX9Parameters(curveOID); + ECPoint ecPubPoint = JcaJcePGPUtil.decodePoint(ecPub.getEncodedPoint(), x9Params.getCurve()); + ECPublicKeySpec ecPubSpec = new ECPublicKeySpec( + new java.security.spec.ECPoint( + ecPubPoint.getAffineXCoord().toBigInteger(), + ecPubPoint.getAffineYCoord().toBigInteger()), + getECParameterSpec(curveOID, x9Params)); + return implGeneratePublic(keyAlgorithm, ecPubSpec); + } + + private PublicKey get25519PublicKey(BigInteger x, ASN1ObjectIdentifier algorithm, String keyAlgorithm, String name) + throws PGPException, GeneralSecurityException, IOException + { + byte[] pEnc = BigIntegers.asUnsignedByteArray(x); + + // skip the 0x40 header byte. + if (pEnc.length < 1 || 0x40 != pEnc[0]) + { + throw new IllegalArgumentException("Invalid " + name + "25519 public key"); + } + return implGetPublicKeyX509(pEnc, 1, algorithm, keyAlgorithm); + } +} diff --git a/pg/src/main/jdk1.5/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyKeyEncryptionMethodGenerator.java b/pg/src/main/jdk1.5/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyKeyEncryptionMethodGenerator.java new file mode 100644 index 0000000000..13b14e3807 --- /dev/null +++ b/pg/src/main/jdk1.5/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyKeyEncryptionMethodGenerator.java @@ -0,0 +1,259 @@ +package org.bouncycastle.openpgp.operator.jcajce; + +import java.io.IOException; +import java.security.AlgorithmParameters; +import java.security.GeneralSecurityException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.Provider; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.spec.SecretKeySpec; + +import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x9.X962Parameters; +import org.bouncycastle.bcpg.ECDHPublicBCPGKey; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec; +import org.bouncycastle.jcajce.spec.HybridValueParameterSpec; +import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; +import org.bouncycastle.jcajce.util.NamedJcaJceHelper; +import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPUtil; +import org.bouncycastle.openpgp.operator.PGPPad; +import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.RFC6637Utils; +import org.bouncycastle.util.Arrays; + +public class JcePublicKeyKeyEncryptionMethodGenerator + extends PublicKeyKeyEncryptionMethodGenerator +{ + private static final byte X_HDR = 0x40; + + private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); + private SecureRandom random; + private JcaPGPKeyConverter keyConverter = new JcaPGPKeyConverter(); + + /** + * Create a public key encryption method generator with the method to be based on the passed in key. + * + * @param key the public key to use for encryption. + */ + public JcePublicKeyKeyEncryptionMethodGenerator(PGPPublicKey key) + { + super(key); + } + + public JcePublicKeyKeyEncryptionMethodGenerator setProvider(Provider provider) + { + this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + + keyConverter.setProvider(provider); + + return this; + } + + public JcePublicKeyKeyEncryptionMethodGenerator setProvider(String providerName) + { + this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + + keyConverter.setProvider(providerName); + + return this; + } + + /** + * Provide a user defined source of randomness. + * + * @param random the secure random to be used. + * @return the current generator. + */ + public JcePublicKeyKeyEncryptionMethodGenerator setSecureRandom(SecureRandom random) + { + this.random = random; + + return this; + } + + protected byte[] encryptSessionInfo(PGPPublicKey pubKey, byte[] sessionInfo) + throws PGPException + { + try + { + PublicKey cryptoPublicKey = keyConverter.getPublicKey(pubKey); + + if (pubKey.getAlgorithm() == PublicKeyAlgorithmTags.ECDH) + { + final ECDHPublicBCPGKey ecKey = (ECDHPublicBCPGKey)pubKey.getPublicKeyPacket().getKey(); + String keyEncryptionOID = RFC6637Utils.getKeyEncryptionOID(ecKey.getSymmetricKeyAlgorithm()).getId(); + PublicKeyPacket pubKeyPacket = pubKey.getPublicKeyPacket(); + if (ecKey.getCurveOID().equals(CryptlibObjectIdentifiers.curvey25519)) + { + return getEncryptSessionInfo(pubKeyPacket, "X25519", cryptoPublicKey, keyEncryptionOID, + ecKey.getSymmetricKeyAlgorithm(), sessionInfo, RFC6637Utils.getXDHAlgorithm(pubKeyPacket), + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws GeneralSecurityException, IOException + { + kpGen.initialize(255, random); + } + }, + new EphPubEncoding() + { + @Override + public byte[] getEphPubEncoding(byte[] ephPubEncoding) + { + return Arrays.prepend(ephPubEncoding, X_HDR); + } + }); + } + else + { + return getEncryptSessionInfo(pubKeyPacket, "EC", cryptoPublicKey, keyEncryptionOID, + ecKey.getSymmetricKeyAlgorithm(), sessionInfo, RFC6637Utils.getAgreementAlgorithm(pubKeyPacket), + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws GeneralSecurityException, IOException + { + AlgorithmParameters ecAlgParams = helper.createAlgorithmParameters("EC"); + ecAlgParams.init(new X962Parameters(ecKey.getCurveOID()).getEncoded()); + kpGen.initialize(ecAlgParams.getParameterSpec(AlgorithmParameterSpec.class), random); + } + }, + new EphPubEncoding() + { + @Override + public byte[] getEphPubEncoding(byte[] ephPubEncoding) + { + if (null == ephPubEncoding || ephPubEncoding.length < 1 || ephPubEncoding[0] != 0x04) + { + ephPubEncoding = JcaJcePGPUtil.getX9Parameters(ecKey.getCurveOID()).getCurve().decodePoint(ephPubEncoding).getEncoded(false); + } + return ephPubEncoding; + } + }); + } + } + else if (pubKey.getAlgorithm() == PublicKeyAlgorithmTags.X25519) + { + return getEncryptSessionInfo(pubKey, "X25519", cryptoPublicKey, NISTObjectIdentifiers.id_aes128_wrap.getId(), + SymmetricKeyAlgorithmTags.AES_128, sessionInfo, "X25519withSHA256HKDF", 255); + } + else if (pubKey.getAlgorithm() == PublicKeyAlgorithmTags.X448) + { + return getEncryptSessionInfo(pubKey, "X448", cryptoPublicKey, NISTObjectIdentifiers.id_aes256_wrap.getId(), + SymmetricKeyAlgorithmTags.AES_256, sessionInfo, "X448withSHA512HKDF", 448); + } + else + { + Cipher c = helper.createPublicKeyCipher(pubKey.getAlgorithm()); + + c.init(Cipher.ENCRYPT_MODE, cryptoPublicKey, random); + + return c.doFinal(sessionInfo); + } + } + catch (IllegalBlockSizeException e) + { + throw new PGPException("illegal block size: " + e.getMessage(), e); + } + catch (BadPaddingException e) + { + throw new PGPException("bad padding: " + e.getMessage(), e); + } + catch (InvalidKeyException e) + { + throw new PGPException("key invalid: " + e.getMessage(), e); + } + catch (IOException e) + { + throw new PGPException("unable to encode MPI: " + e.getMessage(), e); + } + catch (GeneralSecurityException e) + { + throw new PGPException("unable to set up ephemeral keys: " + e.getMessage(), e); + } + } + + @FunctionalInterface + private interface KeyPairGeneratorOperation + { + void initialize(KeyPairGenerator kpGen) + throws GeneralSecurityException, IOException; + } + + @FunctionalInterface + private interface EphPubEncoding + { + byte[] getEphPubEncoding(byte[] publicKeyData); + } + + private byte[] getEncryptSessionInfo(PublicKeyPacket pubKeyPacket, String algorithmName, PublicKey cryptoPublicKey, String keyEncryptionOID, + int symmetricKeyAlgorithm, byte[] sessionInfo, String agreementName, KeyPairGeneratorOperation kpOperation, + EphPubEncoding getEncoding) + throws GeneralSecurityException, IOException, PGPException + { + KeyPairGenerator kpGen = helper.createKeyPairGenerator(algorithmName); + kpOperation.initialize(kpGen); + KeyPair ephKP = kpGen.generateKeyPair(); + UserKeyingMaterialSpec ukmSpec = new UserKeyingMaterialSpec(RFC6637Utils.createUserKeyingMaterial(pubKeyPacket, + new JcaKeyFingerprintCalculator())); + Key secret = JcaJcePGPUtil.getSecret(helper, cryptoPublicKey, keyEncryptionOID, agreementName, ukmSpec, ephKP.getPrivate()); + byte[] ephPubEncoding = getEncoding.getEphPubEncoding(SubjectPublicKeyInfo.getInstance(ephKP.getPublic().getEncoded()).getPublicKeyData().getBytes()); + byte[] paddedSessionData = PGPPad.padSessionData(sessionInfo, sessionKeyObfuscation); + + return getSessionInfo(ephPubEncoding, getWrapper(symmetricKeyAlgorithm, sessionInfo, secret, paddedSessionData)); + } + + /** + * Note that unlike ECDH, no checksum or padding are appended to the + * session key before key wrapping. Finally, note that unlike the other + * public-key algorithms, in the case of a v3 PKESK packet, the + * symmetric algorithm ID is not encrypted. Instead, it is prepended to + * the encrypted session key in plaintext. In this case, the symmetric + * algorithm used MUST be AES-128, AES-192 or AES-256 (algorithm ID 7, 8 + * or 9). + */ + private byte[] getEncryptSessionInfo(PGPPublicKey pgpPublicKey, String algorithmName, PublicKey cryptoPublicKey, String keyEncryptionOID, + int symmetricKeyAlgorithm, byte[] sessionInfo, String agreementAlgorithmName, int keySize) + throws GeneralSecurityException, IOException, PGPException + { + KeyPairGenerator kpGen = helper.createKeyPairGenerator(algorithmName); + kpGen.initialize(keySize, random); + KeyPair ephKP = kpGen.generateKeyPair(); + + byte[] ephPubEncoding = SubjectPublicKeyInfo.getInstance(ephKP.getPublic().getEncoded()).getPublicKeyData().getBytes(); + HybridValueParameterSpec ukmSpec = JcaJcePGPUtil.getHybridValueParameterSpecWithPrepend(ephPubEncoding, pgpPublicKey.getPublicKeyPacket(), algorithmName); + Key secret = JcaJcePGPUtil.getSecret(helper, cryptoPublicKey, keyEncryptionOID, agreementAlgorithmName, ukmSpec, ephKP.getPrivate()); + //No checksum or padding + byte[] sessionData = new byte[sessionInfo.length - 3]; + System.arraycopy(sessionInfo, 1, sessionData, 0, sessionData.length); + + return getSessionInfo(ephPubEncoding, sessionInfo[0], getWrapper(symmetricKeyAlgorithm, sessionInfo, secret, sessionData)); + } + + private byte[] getWrapper(int symmetricKeyAlgorithm, byte[] sessionInfo, Key secret, byte[] sessionData) + throws PGPException, InvalidKeyException, IllegalBlockSizeException + { + Cipher c = helper.createKeyWrapper(symmetricKeyAlgorithm); + c.init(Cipher.WRAP_MODE, secret, random); + return c.wrap(new SecretKeySpec(sessionData, PGPUtil.getSymmetricCipherName(sessionInfo[0]))); + } +} diff --git a/pg/src/main/jdk1.9/module-info.java b/pg/src/main/jdk1.9/module-info.java index 3209e57049..b4b68b6d85 100644 --- a/pg/src/main/jdk1.9/module-info.java +++ b/pg/src/main/jdk1.9/module-info.java @@ -1,6 +1,7 @@ module org.bouncycastle.pg { requires org.bouncycastle.provider; + requires org.bouncycastle.util; requires java.logging; exports org.bouncycastle.bcpg; diff --git a/pg/src/test/j2me/org/bouncycastle/openpgp/test/BcPGPRSATest.java b/pg/src/test/j2me/org/bouncycastle/openpgp/test/BcPGPRSATest.java index b6728353d8..6798e9518c 100644 --- a/pg/src/test/j2me/org/bouncycastle/openpgp/test/BcPGPRSATest.java +++ b/pg/src/test/j2me/org/bouncycastle/openpgp/test/BcPGPRSATest.java @@ -406,7 +406,12 @@ private void fingerPrintTest() PGPPublicKey pubKey = pgpPub.getPublicKey(); - if (!areEqual(pubKey.getFingerprint(), Hex.decode("4FFB9F0884266C715D1CEAC804A3BBFA"))) + byte[] expectedVersion3 = Hex.decode("4FFB9F0884266C715D1CEAC804A3BBFA"); + if (!areEqual(pubKey.getFingerprint(), expectedVersion3)) + { + fail("version 3 fingerprint test failed"); + } + if (!pubKey.hasFingerprint(expectedVersion3)) { fail("version 3 fingerprint test failed"); } @@ -418,7 +423,12 @@ private void fingerPrintTest() pubKey = pgpPub.getPublicKey(); - if (!areEqual(pubKey.getFingerprint(), Hex.decode("3062363c1046a01a751946bb35586146fdf3f373"))) + byte[] expectedVersion4 = Hex.decode("3062363c1046a01a751946bb35586146fdf3f373"); + if (!areEqual(pubKey.getFingerprint(), expectedVersion4)) + { + fail("version 4 fingerprint test failed"); + } + if (!pubKey.hasFingerprint(expectedVersion4)) { fail("version 4 fingerprint test failed"); } diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/AbstractPacketTest.java b/pg/src/test/java/org/bouncycastle/bcpg/test/AbstractPacketTest.java new file mode 100644 index 0000000000..ca4b36710d --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/AbstractPacketTest.java @@ -0,0 +1,133 @@ +package org.bouncycastle.bcpg.test; + +import org.bouncycastle.bcpg.ContainedPacket; +import org.bouncycastle.test.DumpUtil; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.test.SimpleTest; + +import java.io.IOException; + +public abstract class AbstractPacketTest + extends SimpleTest +{ + + /** + * Test, whether the first byte array and the second byte array are identical. + * If a mismatch is detected, a formatted hex dump of both arrays is printed to stdout. + * @param first first array + * @param second second array + */ + public void isEncodingEqual(byte[] first, byte[] second) + { + isEncodingEqual(null, first, second); + } + + /** + * Test, whether the first byte array and the second byte array are identical. + * If a mismatch is detected, a formatted hex dump of both arrays is printed to stdout. + * @param message error message to prepend to the hex dump + * @param first first array + * @param second second array + */ + public void isEncodingEqual(String message, byte[] first, byte[] second) + { + StringBuilder sb = new StringBuilder(); + if (message != null) + { + sb.append(message).append("\n"); + } + sb.append("Expected: \n").append(DumpUtil.hexdump(first)).append("\n"); + sb.append("Got: \n").append(DumpUtil.hexdump(second)); + + isTrue(sb.toString(), first == second || Arrays.areEqual(first, second)); + } + + /** + * Test, whether the encoding of the first and second packet are identical. + * If a mismatch is detected, a formatted hex dump of both packet encodings is printed to stdout. + * @param first first packet + * @param second second packet + */ + public void isEncodingEqual(ContainedPacket first, ContainedPacket second) + throws IOException + { + isEncodingEqual(null, first, second); + } + + /** + * Test, whether the encoding of the first and second packet are identical. + * If a mismatch is detected, a formatted hex dump of both packet encodings is printed to stdout. + * @param message error message to prepend to the hex dump + * @param first first packet + * @param second second packet + */ + public void isEncodingEqual(String message, ContainedPacket first, ContainedPacket second) + throws IOException + { + StringBuilder sb = new StringBuilder(); + if (message != null) + { + sb.append(message).append("\n"); + } + sb.append("Expected: \n").append(PacketDumpUtil.hexdump(first)).append("\n"); + sb.append("Got: \n").append(PacketDumpUtil.hexdump(second)); + isTrue(sb.toString(), first == second || Arrays.areEqual(first.getEncoded(), second.getEncoded())); + } + + /** + * Test, whether the value is false. + * @param value value + */ + public void isFalse(boolean value) + { + isFalse("Value is not false.", value); + } + + /** + * Test, whether the value is false. + * @param message custom error message + * @param value value + */ + public void isFalse(String message, boolean value) + { + isTrue(message, !value); + } + + /** + * Test, whether the value is null. + * @param value value + */ + public void isNull(Object value) + { + isNull("Value is not null.", value); + } + + /** + * Test, whether the value is null. + * @param message custom error message + * @param value value + */ + public void isNull(String message, Object value) + { + isTrue(message, value == null); + } + + /** + * Test, whether the value is not null. + * @param value value + */ + public void isNotNull(Object value) + { + isNotNull("Value is not null.", value); + } + + /** + * Test, whether the value is not null. + * @param message custom error message + * @param value value + */ + public void isNotNull(String message, Object value) + { + isTrue(message, value != null); + } +} diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/AllTests.java b/pg/src/test/java/org/bouncycastle/bcpg/test/AllTests.java new file mode 100644 index 0000000000..bc0cd7faaa --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/AllTests.java @@ -0,0 +1,73 @@ +package org.bouncycastle.bcpg.test; + +import java.security.Security; + +import junit.extensions.TestSetup; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.test.PrintTestResult; +import org.bouncycastle.util.test.SimpleTestResult; + +public class AllTests + extends TestCase +{ + + public void testPacketParsing() + { + Security.addProvider(new BouncyCastleProvider()); + + org.bouncycastle.util.test.Test[] tests = new org.bouncycastle.util.test.Test[] + { + new SignaturePacketTest(), + new OnePassSignaturePacketTest(), + new OpenPgpMessageTest(), + new FingerprintUtilTest() + }; + + for (int i = 0; i != tests.length; i++) + { + SimpleTestResult result = (SimpleTestResult)tests[i].perform(); + + if (!result.isSuccessful()) + { + fail(result.toString()); + } + } + } + + + public static void main(String[] args) + { + PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); + } + + public static Test suite() + { + TestSuite suite = new TestSuite("OpenPGP Packet Tests"); + + suite.addTestSuite(AllTests.class); + + return new BCPacketTests(suite); + } + + static class BCPacketTests + extends TestSetup + { + public BCPacketTests(Test test) + { + super(test); + } + + protected void setUp() + { + Security.addProvider(new BouncyCastleProvider()); + } + + protected void tearDown() + { + Security.removeProvider("BC"); + } + } +} diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/BCPGOutputStreamTest.java b/pg/src/test/java/org/bouncycastle/bcpg/test/BCPGOutputStreamTest.java new file mode 100644 index 0000000000..4e02f9378f --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/BCPGOutputStreamTest.java @@ -0,0 +1,283 @@ +package org.bouncycastle.bcpg.test; + +import org.bouncycastle.bcpg.*; +import org.bouncycastle.openpgp.*; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class BCPGOutputStreamTest extends SimpleTest { + + private void testForceNewPacketFormat() throws IOException { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, PacketFormat.CURRENT); + + new UserIDPacket("Alice").encode(pOut); + new UserIDPacket("Bob").encode(pOut); + + pOut.close(); + + ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); + BCPGInputStream pIn = new BCPGInputStream(bIn); + + isTrue(pIn.readPacket().hasNewPacketFormat()); + isTrue(pIn.readPacket().hasNewPacketFormat()); + } + + private void testForceOldPacketFormat() throws IOException { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, PacketFormat.LEGACY); + + new UserIDPacket("Alice").encode(pOut); + new UserIDPacket("Bob").encode(pOut); + + pOut.close(); + + ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); + BCPGInputStream pIn = new BCPGInputStream(bIn); + + isTrue(!pIn.readPacket().hasNewPacketFormat()); + isTrue(!pIn.readPacket().hasNewPacketFormat()); + } + + private void testRoundTripPacketFormat() throws IOException { + List oldPackets = new ArrayList<>(); + ByteArrayInputStream obIn = new ByteArrayInputStream(Hex.decode("b405416c696365b403426f62")); + BCPGInputStream opIn = new BCPGInputStream(obIn); + oldPackets.add((UserIDPacket) opIn.readPacket()); + oldPackets.add((UserIDPacket) opIn.readPacket()); + + List newPackets = new ArrayList<>(); + ByteArrayInputStream nbIn = new ByteArrayInputStream(Hex.decode("cd05416c696365cd03426f62")); + BCPGInputStream npIn = new BCPGInputStream(nbIn); + newPackets.add((UserIDPacket) npIn.readPacket()); + newPackets.add((UserIDPacket) npIn.readPacket()); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, PacketFormat.ROUNDTRIP); + + // Write New, Old, Old, New + pOut.writePacket(newPackets.get(0)); + pOut.writePacket(oldPackets.get(0)); + pOut.writePacket(oldPackets.get(1)); + pOut.writePacket(newPackets.get(1)); + pOut.close(); + + ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); + BCPGInputStream pIn = new BCPGInputStream(bIn); + + // Test New, Old, Old, New + isTrue(pIn.readPacket().hasNewPacketFormat()); + isTrue(!pIn.readPacket().hasNewPacketFormat()); + isTrue(!pIn.readPacket().hasNewPacketFormat()); + isTrue(pIn.readPacket().hasNewPacketFormat()); + } + + private void testRoundtripMixedPacketFormats() throws IOException { + // Certificate with mixed new and old packet formats + // The primary key + sigs use new format + // The signing subkey + sigs use old format + // The encryption subkey + sigs use new format again + String encodedCert = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "Version: BCPG v@RELEASE_NAME@\n" + + "\n" + + "xcTGBGYvuZUBDACyFv3LQiubgHM4eJUFnsLEei8/l4bGKdVx8hRu6N5rfcjZt3RM\n" + + "UGUi+HQDnRbUvJ5B/7qDB7Ia7bpRf7BrYmho5vqNtjpxUPs3Mct1TjqCm2yLC9zH\n" + + "+qHmGSPX4dLtSKKpXc4iBMGtFknhXKnoUovv7XZDecIIDbJhaqoFptRfqFc30SRj\n" + + "ktQcyXutcIYlhaPQ/JtJlNWfmo0+NTEjfpDOZovCzAi769QnljntkiKXxQzBihzb\n" + + "f1Ou7NzJ17m/7pJXBOTKKXboMFDc1ct6f2s2lomEhCYRPRC6eITWpXK/G7e503xS\n" + + "eaMnd29BrmbEnw6QgCjafu72t8rgD6jbj3+kaRR85AevLWrfefo9ofhUMl0DDKc+\n" + + "bhNQAMRZY9vlRdEo0pNLL9kIMzl10HL9viRXxCwp4d1chH0qLQdy8W13WrjhS0Fw\n" + + "GlEkcTt2Z/4kGmYeLvBfQqfz62owIR47otX8JU+QdTmP89SyZRyuHVwB+Pgg32oC\n" + + "1fSJUVHRCb6f1z0AEQEAAf4JAwJgAx2GH4oiN2CgjB+JAKrjlbrfjhLDN+w14SeC\n" + + "vGpP40Ay/bUFYgfvkVA3CQFMYJ4fCKluhu2cHAhzCrGCAKs42ZvkKzHuDohzEjGG\n" + + "N9IkA4y/Gv2tTewhtMALxbHtS7CCX6IBqC292mupm7ND4aULhLM4xqXKXUny543V\n" + + "hPJEuKL8D5CLRqFJPtrw/791izbdr6J+rKxYwscL5NiUJQFLVsK59+7sJvSvBK9N\n" + + "DIiFT+hRSJjb6rBrXWZK0bUCsaCLHL0k8PLPdBdzZ3YJqcaIFRd0Sq7l7Ck7RxXh\n" + + "L8tf8Swcr1UafMMYbyMJW5VtJxZStV1OgdWVatrbkW5GINlZ7pp63kIOY2GbK99H\n" + + "Q4mAQV1EpAlItF4QqkOunyGqw6aN5x9+Hoyr0O17428604wsptZstNT0wz3qGJJ/\n" + + "ye3I9xveEMhRwv1ZB3MsiiBLj5kEa2l4W6O3g/6Sdu75MGhalyi5+r41SgKkxMWI\n" + + "OCTZMWCNZ1ZR9Ehlsg5uOtNUc9RkAn9BAfBzDwBMMa8wzHKsNiaiR2Tonpm1+miB\n" + + "TtBU7RUw5CEAcGbnYmLvlxVwe7CTVezYIQIroCCqY738Y5mpOSB0UhT1JAORPCJJ\n" + + "PCWRGQ9UDm0xK/dFbbRNTJqYM2GZKOM5esnKQlxJ1t9+VoQ+mPLOPHnkmUXU8Rq8\n" + + "9c3bLogW/dsCm0j8lfV0sKsAXfuD3spHPoJwQOFwZ4kDeFjJlRTusNSgXQsRF/x4\n" + + "Wvwt+jmxRwenkeVunigqZVOhctf8ozkncpCV8tTLp8X2VrlJNx5XoggFzOwEWxJa\n" + + "mMx1gvsAlsEiTCK5g6xocULxKfBfJogUrBXZk0GUJriJzB470QMnQ49a4gGFh4w7\n" + + "Wh2/FiRRMIGTTXPFHSQ92kaWoqO1jDhM7c6HrxEETS7NrWi6TLvfYxrCZ9GlYanK\n" + + "MPDa75lVpuE95M1+dRShX13LJpSlOq8Eius/kP9W54sCT4DTIvlz08QdcaNpRN/9\n" + + "ZZGJw6gMttshvvl1eOKOjD3iW110qJtxh/W4OxgDL7R+JKKYfjc9lWMIhfy1sOQK\n" + + "cmXZVP6HVK5y+xwW8h8MTqjUznYo1Lfu6icmBm7q0/P2lSkBSQ76kSL4exgtYr4k\n" + + "XRj483ipnlUr8ue53ALXOC46NIj8wE2+LDg1rAt3AWru1fOGFMU4bol7ytBoBKmz\n" + + "Cvv/6hxDZGSR43n+FLWMd40hRjneeM+0oy/6vvU0Rsa3FdL7m+/Rui8CC4JoG/Kc\n" + + "xl3uj0OgfHvHYPjLoXOPUdPNIptwfCQ9xvEfWWJA4hcyRdToy1gjYINSmJDIhYgL\n" + + "yyFlm2GlHMKDo71TEODRwNHy61Jdikx43c0ZQWxpY2UgPGFsaWNlQGV4YW1wbGUu\n" + + "Y29tPsLA+QQTAQoAIwUCZi+5lwKbAQIeARYhBLSFPwVS++7sNFWR0nm9t4YHzlXs\n" + + "AAoJEHm9t4YHzlXs7soL/jtmG5E6helkBjFLZqBfXJUxIniEtOxT0GrePTfA7lde\n" + + "0hKDh3Wjh0+RmfnuatopWW1DRKmhnS0uAIwIewIH7rzhHG+i9OHAwZ6R61ptEKmH\n" + + "WL5JeqTNq3bLD6U6VgfrFq1DNxtfTWTPwTzSIBuGVLJjRFEqq5olH4dD6xImO7Lk\n" + + "t3KJ9Du8IdmLsoEcw0tMhd5cSbh2gE1F1CnmSufDts2coTv7B/lQTAhOFQQedMFa\n" + + "N/mKJ/v+DvRjB9nV+rYqeqweTLJ2AJcmnmDTiue74CgP2o84Cf7JEAZ83vy2hHLq\n" + + "KGvsYbQoE1oSt7vU9otGotSutrFZww8LmnkJCQwHPrNWC21CKoo/7bGo4ToDaVOw\n" + + "FEC9l2pusMaN6y9ztsq2Wz3mlQppe0kizMmkA+WM34Lu0EI3DGQvqIcIMKEg242B\n" + + "e8gV2qN7t/zMvLM34A4sDD7L1e8dKKnru0MY73TaMAw+kbRuM/DrQpT4PI1cvD4j\n" + + "xN/rVB0g4JIuVElygMLA950FhgRmL7mVAQwA2WGMqveX3ssz5tdKIP6q8krGSwsF\n" + + "CR7qBGVac5XiYaNzg6YJX+r8CiSAT+mN55t7TN9C7kND9zlssLJidKuXs87Bgwjl\n" + + "gmuO0AL9VFKTx2IkEVovwwKvozJd9vt79IKY6wJ4eqbElaBfNy2uov4kuOxcEEuY\n" + + "n7UQttW6Pp0JFP1lb+hZ524r05wYb7LGdPyz1vNPeYEg48PkcNU6Z9DXfU80JVp8\n" + + "Cy0XNxHm31ML/DgLJHIVZ0dstA2KZnWxhlKNNfdmYakGEU5QISGViReybcc3kwco\n" + + "v5agauCUWNFvLM7NYI7S1m5A0r6hWM/CtQwUgb0PIT97nEbYmIB+su+6RTLvOkMM\n" + + "3465MxjBVwwiWFpZcHiUP3q5Eelr1V75rOwII3HKSC1tfZwjWxyzdBpPZDpMIxHT\n" + + "9ldJnlLzIvUOR2pSusqnGrCeurGqNxT/b9lEifoHcDNiyo+Qj4WsOjp+I9sBkfYP\n" + + "G3Hbx/OmKvkSY4a+L53iY2H1xjAfYwySI5KBABEBAAH+CQMCYAMdhh+KIjdg8Sop\n" + + "plGYPDvXQ3N1JgtYiGXjOuvsEIuxqmY4CwtFATtqjphFPe+6GL4zS16vcGlAPwgI\n" + + "h0+aZQxPHKJcUx997zm9PFrOjnSInFraAdIvpBay+5DlicGJuARZ/8ZhNZ7qxbIT\n" + + "vi5ZVRnrPef6SO5E1zeSFodMV5FZE1fZNTeSq2AOQ/tIkMPsjK/BpKSTLSebkwii\n" + + "G3IgQEB6albQsfpKTqSCgDS9o0/b5/q+KMYtHoS0XwoE46df1wfjirz6zNY6VShd\n" + + "3MaJ+Jb1GzsRCTTedKHHnF/fU49uWs7LNRZT1PhSMBH/scL1w2u8bmdvW0i8PJaN\n" + + "bbdX/Zs2sVxfACfeUSkF6GAmqnc1+6RnZSxMjSqk/1uPhtuSUa1NsJ9UlxHIQcDp\n" + + "NGlQCrabUdhmjfZWtXCIcINXj0JPfMTNIxLC4YBSUvV+y//UEzq+LYT0tnOXeU6O\n" + + "/JCzhEoGhPvboFfv8p3fPVvvLFseONZuX3d9WzbAQiCpCXlP4+Ro0OFw32JGTZLq\n" + + "mi6eiJceAJ4sza4V/DeaDovJ62RJHzJOtb8+cOFyo+/8m46YMF07X2AwdjE8Az69\n" + + "td1N79S9eqtYjV1VWrrf94fpeUGV4UD1ugt/UalGbGm4IQFTGZGb0vinImLoM7ts\n" + + "84BneaosoYh/62bA5OzIF9xqHjFQ9XiNjwODFpiIZl3twL7DVDWf9Paq9ki1mv2D\n" + + "pan8sJtsZYj0j0D+V9nDk5LSBiMnb+qaagq/Wt648eqaxGP1gb5B/w9rrYiF0/TX\n" + + "H5q/qzHxh9j8sPEAM3R7Y9+IL1RgF0/3VgBx52/eJxVvb9FUZOoF7cvrESAFDqSo\n" + + "p3/pN07kMN3fHNIFpQGbsC6ECmEatPnANJH0InDnPERTGasiCtshdzx8bTLIdh95\n" + + "3hTJuv6ML8+PP9Jp4eLiAkinW+leBEyFgpYMFBdSifQ5R/jU7n/6IcW/4u5t66if\n" + + "RFnE0N2hpMUQPTl5hZH5TY9AU55MZCLzvDbYW/cXmIuBuRNVfaLIWSKp8UxFwZfk\n" + + "zki8N+EUPeB1dPaFapuArvpmSAl7uLzNYAb7X4Tf29VBlz2zRhh2dMAOtzX+55YX\n" + + "nNE2gEiGP1FAA00l/nIKWIHf0u6zMO0jj6soSwsan9VfoyK9jc7qDObPrW0v0lsK\n" + + "0CknbavMkrS+DdhTWAzYhvdSUZV80H/lRUwrTyCpaiRuuDu+kZOScTH1JsFkDEix\n" + + "NypeMhSIh5Izzf0njazQSxzoI6XcEJLukFPONvZ0oTsXF1j0IITFboWjQpuUJ/kg\n" + + "ZGBuBlllk2gD7t3H8r1zRiKkHaw9Nr4Fr4r5wNJVfVKrnQkuQBJneP2JA1UEGAEK\n" + + "Ab8FAmYvuZcCmwIWIQS0hT8FUvvu7DRVkdJ5vbeGB85V7MDdIAQZAQoABgUCZi+5\n" + + "lwAKCRDVw7vf0dE2sN77DACUd5X+RFI264quxxPZlO/jmcu3PfoeGtWL4ILMZ8Lj\n" + + "4NyoqctmRthZzEvvyzmg/IQOPJlIru18aJKZQgrKkQzytbd+BL8GfsTXh7XwICcu\n" + + "xS9pzMMKi29rU8ViwK+4blAjxGcPRrniJYBn7NWAlumjpUVCzoIpjcphpiCKTZlz\n" + + "m2W4iWGSPzemDmOzEEWERafu3O08yS5n9zl2wrdOjClNC4Pmlyy8PH8b42mgMr4e\n" + + "nP8CoTpzdFQbzSg/A3pfYgK+TLtVI9KZO4V/OIK6jppKUDg0ZA+GDUYC4mtjgHgQ\n" + + "Qaj0OiAHxti1bYA/VgoBLI3D/AW5JNJ0XGUXO++qwR5rNa6Sgs2DATvBw6mLbiVV\n" + + "pYBuDTnFRtXURm1pkD8Z+jSKz5eq7fEnO8GhnW+4ftPztXpucl85jtAHTqPFaiET\n" + + "jDwrdmHNqvMdu0KQfd+D1bU8KSf2v/9h7LS/fyfxDxYgX15O4crtQV1Obq6yLbbA\n" + + "G0YwRknIaPbq9qZx8iXue+kACgkQeb23hgfOVewMmgwAnJl4g0sX89VFz1OtMLJj\n" + + "Ui2QvPCpMkhsrgbaLS3q+wSZIUTZWzTzcZhDajNs3f/KjL2Dm5UxkHD29DuUv++r\n" + + "YPsVpWkk8wtD8/Am4CF1b5ibXboBrouAuju64pqrHjrM8/1WeZatYqkjShk5DqA2\n" + + "PlgpHFxoRB/0QnUwp6kpu2Tr3CTrcn0tyyqbcwTr5pw5oBLWcWgc8LMIFV2zdnHa\n" + + "bGvsew9puss1oh5Fs58XYg0Gdf/J/qelWgxbx/b4GHy5wxvb5BkbNMz7hWquZNsc\n" + + "DRuCOwRwlhCY13rTDUwwonU/PMPwP9I6pU5LBx+xRt3p8CeE4f00ANdxbS6JI5iA\n" + + "zqUsKIlUlwH+AO9VtRqiAJsVwaJVm/GOWJVeIKiz8M/jgiW0NCVJb01RW+3WVaY5\n" + + "kpLKqE1V0xq4mxw16mjBguUx3HdR5rh3ZZJ0TfXGGDAhLQC7PXe3oQyN1NbbH2Vx\n" + + "jVKueQsGPX2022pepiJXXtAzGIBR0eUOfylpewuerFwEx8TGBGYvuZUBDADjCLaD\n" + + "w3L65khVSjpsu8jr9B72xbx/EIlXEKr2KXa1lvf0yadxKB5/KytXWffQ8lEMmdi9\n" + + "p86+LIWIh7wx+mhh2g64um2yJiuS+HRTWWA69nb6/1Tl5G2VyT81AVQ5JAcNyIIS\n" + + "RuWvzZoQDNf0sImT0o7dAK4KLtofGMy/rIaNebE2Qu4dks5aBjIV2/bPoIMrSuJF\n" + + "UK5UsUOPx5jlYk5gpgyPcl30YgLf0Bizp4RJSCpIjjDJ6WvKBxlRChdfbP52vawI\n" + + "IEcMGnWMVFvVd8I57v6HDtbQTgF8BepwgsWHnTGtoIkVnKc/nlM3LtNiJUY3z915\n" + + "TZGRbYcuqWZhMbnJoQLRgQXh6/E4FzxDxaKoXpYXuPDxCTfNxeqU3hrRZUfKOdjw\n" + + "+BS5rSicvbGaqgyz29518bG04hzrmWORoJExozWTOoE+kTU5+o7DmS7qtd+z63lL\n" + + "bjqLhFALPl9qbwVlFlFo6X6jmlo8THVkX5lLI1+Qaq2g3G1YYCoXDMoGbk8AEQEA\n" + + "Af4JAwJgAx2GH4oiN2BJ7FHcEtvbKapzj3N2OwxYHmWymAAjgPe10Ne2W7FFi4Qy\n" + + "sj0Ss9NbWV5Nw4NqnE6syOFNVeLs5t7BdTqXs3NxOTJo0iS+lpL5OgUcMSWu2hN7\n" + + "jDbeXEBZFSQ7epetVDAetYsKLZBHpsI19aamUEnRZicKATjVQud9pHhC9BTFp62i\n" + + "D4a2IuxQcweuw5D8brKH9WfXYXlNzjoZdsqvWRWy77/6s2hg9V7lo65C/p8C0DB7\n" + + "blJwptt9j/vTlzTyavV60rRma3VeMgQw5sn0b2lqWvmLRgpjmCv2AdD9A6rYU/4+\n" + + "f+sknWq5c/gaoWAMWNg+vgRpZUT9C5ZlT86QUuz0DO7ySoy0gy9Z3BID+JDcXP/b\n" + + "BYftC7XQut+nnWGD+Pr2E0YvrTQLw0ISCzKyCI9iZh0gvwv9bKdYOUSEhOM9zlk+\n" + + "gt3hFJvVXvLbFUHEbh0Oep0AcCzFKzBrTYBeJ8Z8vvgNfie9zMtY3EAV4tBU2MVB\n" + + "3JqgRJ9Qam/ZGJ47GIbkRnqrbCmL44U3Qvl9to4g96gmrQXfdJUAtpntewuuDguJ\n" + + "MgKYUTv9TupYErHoTFlV61czXEwITE6y3TuePgWp4sY+BXGWyFc4puS+KNB+y+GC\n" + + "hJdchAyJcVhsV2e7ElC2URVmGpDkW23qcRMFlu7QMaENI5itKEinKIPQokITO0l+\n" + + "I13oJ4KlMEgfofNQ4rWdoqir7AqaQ+HXTV0l8iQQJPuAwXYnSe4xjuHuBssJ92Qk\n" + + "B6H+7IGDvXwMikQzOkeZVrsL0f1Pg1DIPMgt5l4qleZ4aL0cDqBQHh3JLtXWQ4jp\n" + + "ffYWxxCXILO10WYbqAaG4eXr/vsCb/TfADiF07azQMgWrhk3NSSoVRRjQgIntCAR\n" + + "u9C2x6FcyeF4ND0eIciWH6+pby0xC9bg5XlKlgeMN/BoXnj/k34ZgoHbe6NmjhT2\n" + + "bpgXrQQl4QPBS67jr2lU6NunmOwoHwX+epwIIKW8bcjvOTs0XEGVCJleIyUf88m6\n" + + "bpV4WUmIk4I8ROztJRzxZpNB8HgZb9XzbOcXccUl8sjTOyMlQTIAl/qUIomJ8snH\n" + + "lzEhoWYWzWUrEe42CVld++xhLQkgR/V484ch+vDi9EjmKCRVWVdOnHda9fHe5o8n\n" + + "TQzMdG8Fvy2XrFQAeCdNkD+itwV1OIva9j9KQHadS9MVl5PYzy/ezwIrK9siXAXu\n" + + "4YiaSTL4TPwjWppQCJJv8mQskNP72tc8TELA225MtsPcSPiCT1aLUUKQmpQstEeQ\n" + + "S6Cv+uggbDXqWfow2mx5w4bJXLxpe09vm5rqBT6Scg2e4e3yRNiYGFXX2QsNVRui\n" + + "nLCJLAUtpUJXBcLA9gQYAQoAIAUCZi+5lwKbDBYhBLSFPwVS++7sNFWR0nm9t4YH\n" + + "zlXsAAoJEHm9t4YHzlXsaFsL/16ktY2/knugZ8bN1df/QzdDE30wWakcDqAZhEMb\n" + + "+MyazHM08ipXFkvNsz0r7Y6DXqvOTvRlzXc7csk3Np/rrFFwpkckHXz1JkrQwAtD\n" + + "rIMcmzqm25u7rKti0NfsacQI1mie+wFyrApvXTBF2av9Fn1ch07A4f6JTfD62KAo\n" + + "ccBKAr38LVBwwGJZh6WqOazgoO8B4ia1MveHgOCsf3SurigXt1iMCCqWvvpQUil9\n" + + "3hU8x1SNy0TajFwXSeAMTAyoWVlC7ceixVr9dPLgRuMbsfHYsBAMw9wHSSNVyqvl\n" + + "vhB4X/j3bIFhl3iqj1P7Km33yVbk30KtKHuPFpHMJBu8CZ4/JcPnfGK35aTgfV9N\n" + + "W9V5u+mtWKReL8Ii0/jQ53PGJ7I1m8uzLB83mmRYY2hoqxdzWTXB57oDJbPwZRSx\n" + + "5puZWZ4WbmsHSaPe0gMIQH3ItcnWuB2sxhkpXSnOtXIK44lqcQwq69ygHEP11W85\n" + + "3hRZb5W+1RCWcuPc/oWxMuwiBw==\n" + + "=7IAh\n" + + "-----END PGP PRIVATE KEY BLOCK-----\n"; + + ByteArrayInputStream bIn = new ByteArrayInputStream(encodedCert.getBytes()); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + PGPObjectFactory objectFactory = new BcPGPObjectFactory(pIn); + PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objectFactory.nextObject(); + + // ROUNDTRIP + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ArmoredOutputStream aOut = new ArmoredOutputStream(bOut); + BCPGOutputStream pOut = new BCPGOutputStream(aOut, PacketFormat.ROUNDTRIP); + secretKeys.encode(pOut); + pOut.close(); + aOut.close(); + + isEquals(encodedCert, bOut.toString()); + + // NEW PACKET FORMAT + bOut = new ByteArrayOutputStream(); + aOut = new ArmoredOutputStream(bOut); + pOut = new BCPGOutputStream(aOut, PacketFormat.CURRENT); + secretKeys.encode(pOut); + pOut.close(); + aOut.close(); + + bIn = new ByteArrayInputStream(bOut.toByteArray()); + aIn = new ArmoredInputStream(bIn); + pIn = new BCPGInputStream(aIn); + Packet packet; + while ((packet = pIn.readPacket()) != null) { + isTrue(packet.hasNewPacketFormat()); + } + + // OLD PACKET FORMAT + bOut = new ByteArrayOutputStream(); + aOut = new ArmoredOutputStream(bOut); + pOut = new BCPGOutputStream(aOut, PacketFormat.LEGACY); + secretKeys.encode(pOut); + pOut.close(); + aOut.close(); + + bIn = new ByteArrayInputStream(bOut.toByteArray()); + aIn = new ArmoredInputStream(bIn); + pIn = new BCPGInputStream(aIn); + while ((packet = pIn.readPacket()) != null) { + isTrue(!packet.hasNewPacketFormat()); + } + } + + @Override + public String getName() { + return "BCPGOutputStreamTest"; + } + + @Override + public void performTest() throws Exception { + testForceOldPacketFormat(); + testForceNewPacketFormat(); + testRoundTripPacketFormat(); + testRoundtripMixedPacketFormats(); + } + + public static void main(String[] args) { + runTest(new BCPGOutputStreamTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/FingerprintUtilTest.java b/pg/src/test/java/org/bouncycastle/bcpg/test/FingerprintUtilTest.java new file mode 100644 index 0000000000..3648c4b7fe --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/FingerprintUtilTest.java @@ -0,0 +1,104 @@ +package org.bouncycastle.bcpg.test; + +import org.bouncycastle.bcpg.FingerprintUtil; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; + +public class FingerprintUtilTest + extends SimpleTest +{ + private void testKeyIdFromTooShortFails() + { + byte[] decoded = new byte[1]; + try + { + FingerprintUtil.keyIdFromV4Fingerprint(decoded); + fail("Expected exception"); + } + catch (IllegalArgumentException e) + { + // expected + } + } + + private void testV4KeyIdFromFingerprint() + { + String fingerprint = "1D018C772DF8C5EF86A1DCC9B4B509CB5936E03E"; + byte[] decoded = Hex.decode(fingerprint); + isEquals("v4 key-id from fingerprint mismatch", + -5425419407118114754L, FingerprintUtil.keyIdFromV4Fingerprint(decoded)); + } + + private void testV6KeyIdFromFingerprint() + { + String fingerprint = "cb186c4f0609a697e4d52dfa6c722b0c1f1e27c18a56708f6525ec27bad9acc9"; + byte[] decoded = Hex.decode(fingerprint); + isEquals("v6 key-id from fingerprint mismatch", + -3812177997909612905L, FingerprintUtil.keyIdFromV6Fingerprint(decoded)); + } + + private void testLibrePgpKeyIdFromFingerprint() + { + // v6 key-ids are derived from fingerprints the same way as LibrePGP does + String fingerprint = "cb186c4f0609a697e4d52dfa6c722b0c1f1e27c18a56708f6525ec27bad9acc9"; + byte[] decoded = Hex.decode(fingerprint); + isEquals("LibrePGP key-id from fingerprint mismatch", + -3812177997909612905L, FingerprintUtil.keyIdFromLibrePgpFingerprint(decoded)); + } + + private void testLeftMostEqualsRightMostFor8Bytes() + { + byte[] bytes = new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; + isEquals( + FingerprintUtil.longFromLeftMostBytes(bytes), + FingerprintUtil.longFromRightMostBytes(bytes)); + byte[] b = new byte[8]; + FingerprintUtil.writeKeyID(FingerprintUtil.longFromLeftMostBytes(bytes), b); + isTrue(Arrays.areEqual(bytes, b)); + } + + private void testWriteKeyIdToBytes() + { + byte[] bytes = new byte[12]; + long keyId = 72623859790382856L; + FingerprintUtil.writeKeyID(keyId, bytes, 2); + isTrue(Arrays.areEqual( + new byte[] {0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00}, + bytes)); + + try + { + byte[] b = new byte[7]; + FingerprintUtil.writeKeyID(0, b); + fail("Expected IllegalArgumentException for too short byte array."); + } + catch (IllegalArgumentException e) + { + // Expected + } + } + + @Override + public String getName() + { + return "FingerprintUtilTest"; + } + + @Override + public void performTest() + throws Exception + { + testV4KeyIdFromFingerprint(); + testV6KeyIdFromFingerprint(); + testKeyIdFromTooShortFails(); + testLibrePgpKeyIdFromFingerprint(); + testLeftMostEqualsRightMostFor8Bytes(); + testWriteKeyIdToBytes(); + } + + public static void main(String[] args) + { + runTest(new FingerprintUtilTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/OCBEncryptedDataPacketTest.java b/pg/src/test/java/org/bouncycastle/bcpg/test/OCBEncryptedDataPacketTest.java new file mode 100644 index 0000000000..0a04778e51 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/OCBEncryptedDataPacketTest.java @@ -0,0 +1,70 @@ +package org.bouncycastle.bcpg.test; + +import org.bouncycastle.bcpg.*; +import org.bouncycastle.util.encoders.Hex; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +public class OCBEncryptedDataPacketTest extends AbstractPacketTest { + @Override + public String getName() { + return "OCBEncryptedDataPacketTest"; + } + + @Override + public void performTest() throws Exception { + parseTestVector(); + parseUnsupportedPacketVersion(); + } + + private void parseTestVector() throws IOException { + String testVector = "" + + "d45301090210c265ff63a61ed8af00fa" + + "43866be8eb9eef77241518a3d60e387b" + + "1e283bdd90e2233d17a937a595686024" + + "1d13ddfaccd2b724a491167631d1cd3e" + + "a74fe5d9e617f1f267d891fd338fddb2" + + "c66c025cde"; + + ByteArrayInputStream bIn = new ByteArrayInputStream(Hex.decode(testVector)); + BCPGInputStream pIn = new BCPGInputStream(bIn); + + AEADEncDataPacket p = (AEADEncDataPacket) pIn.readPacket(); + isTrue("Packet length encoding format mismatch", p.hasNewPacketFormat()); + isEquals("Packet version mismatch", 1, p.getVersion()); + isEquals("Symmetric algorithm mitmatch", SymmetricKeyAlgorithmTags.AES_256, p.getAlgorithm()); + isEquals("AEAD encryption algorithm mismatch", AEADAlgorithmTags.OCB, p.getAEADAlgorithm()); + isEquals("Chunk size mismatch", 16, p.getChunkSize()); + isEncodingEqual("IV mismatch", Hex.decode("C265FF63A61ED8AF00FA43866BE8EB"), p.getIV()); + } + + private void parseUnsupportedPacketVersion() throws IOException { + // Test vector with modified packet version 99 + String testVector = "" + + "d45399090210c265ff63a61ed8af00fa" + + "43866be8eb9eef77241518a3d60e387b" + + "1e283bdd90e2233d17a937a595686024" + + "1d13ddfaccd2b724a491167631d1cd3e" + + "a74fe5d9e617f1f267d891fd338fddb2" + + "c66c025cde"; + + ByteArrayInputStream bIn = new ByteArrayInputStream(Hex.decode(testVector)); + BCPGInputStream pIn = new BCPGInputStream(bIn); + + try + { + pIn.readPacket(); + fail("Expected UnsupportedPacketVersionException for unsupported version 99"); + } + catch (UnsupportedPacketVersionException e) + { + // expected + } + } + + public static void main(String[] args) + { + runTest(new OCBEncryptedDataPacketTest()); + } +} \ No newline at end of file diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/OnePassSignaturePacketTest.java b/pg/src/test/java/org/bouncycastle/bcpg/test/OnePassSignaturePacketTest.java new file mode 100644 index 0000000000..2b06e20b18 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/OnePassSignaturePacketTest.java @@ -0,0 +1,296 @@ +package org.bouncycastle.bcpg.test; + +import org.bouncycastle.bcpg.*; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.util.encoders.Hex; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.SecureRandom; + +public class OnePassSignaturePacketTest + extends AbstractPacketTest +{ + + // Parse v6 OPS packet and compare its values to a known-good test vector + private void testParseV6OnePassSignaturePacket() + throws IOException + { + // Version 6 OnePassSignature packet + // extracted from https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-sample-inline-signed-messag + byte[] encOPS = Hex.decode("c44606010a1b2076495f50218890f7f5e2ee3c1822514f70500f551d86e5c921e404e34a53fbaccb186c4f0609a697e4d52dfa6c722b0c1f1e27c18a56708f6525ec27bad9acc901"); + // Issuer of the message + byte[] issuerFp = Hex.decode("CB186C4F0609A697E4D52DFA6C722B0C1F1E27C18A56708F6525EC27BAD9ACC9"); + // Salt used to generate the signature + byte[] salt = Hex.decode("76495F50218890F7F5E2EE3C1822514F70500F551D86E5C921E404E34A53FBAC"); + + ByteArrayInputStream bIn = new ByteArrayInputStream(encOPS); + BCPGInputStream pIn = new BCPGInputStream(bIn); + + // Parse and compare the OnePassSignature packet + OnePassSignaturePacket ops = (OnePassSignaturePacket) pIn.readPacket(); + isEquals("OPS packet MUST be of version 6", + OnePassSignaturePacket.VERSION_6, ops.getVersion()); + isEncodingEqual("OPS packet issuer fingerprint mismatch", + issuerFp, ops.getFingerprint()); + isTrue("OPS packet key-ID mismatch", + // key-ID are the first 8 octets of the fingerprint + Hex.toHexString(issuerFp).startsWith(Long.toHexString(ops.getKeyID()))); + isEncodingEqual("OPS packet salt mismatch", + salt, ops.getSalt()); + isTrue("OPS packet isContaining mismatch", + ops.isContaining()); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, true); + ops.encode(pOut); + pOut.close(); + + isEncodingEqual("OPS Packet encoding mismatch", encOPS, bOut.toByteArray()); + } + + private void roundtripV3Packet() + throws IOException + { + OnePassSignaturePacket before = new OnePassSignaturePacket( + PGPSignature.BINARY_DOCUMENT, + HashAlgorithmTags.SHA256, + PublicKeyAlgorithmTags.RSA_GENERAL, + 123L, + true); + + isEquals("Expected OPS version 3", + OnePassSignaturePacket.VERSION_3, before.getVersion()); + isEquals("Signature type mismatch", + PGPSignature.BINARY_DOCUMENT, before.getSignatureType()); + isEquals("Hash Algorithm mismatch", + HashAlgorithmTags.SHA256, before.getHashAlgorithm()); + isEquals("Pulic Key Algorithm mismatch", + PublicKeyAlgorithmTags.RSA_GENERAL, before.getKeyAlgorithm()); + isEquals("Key-ID mismatch", + 123L, before.getKeyID()); + isFalse("OPS is expected to be non-containing", + before.isContaining()); + isNull("OPS v3 MUST NOT have a fingerprint", + before.getFingerprint()); + isNull("OPS v3 MUST NOT have salt", + before.getSalt()); + + for (boolean newTypeIdFormat : new boolean[] {true, false}) + { + // round-trip the packet by encoding and decoding it + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, newTypeIdFormat); + before.encode(pOut); + pOut.close(); + ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); + BCPGInputStream pIn = new BCPGInputStream(bIn); + OnePassSignaturePacket after = (OnePassSignaturePacket) pIn.readPacket(); + + isEquals("round-tripped OPS version mismatch", + before.getVersion(), after.getVersion()); + isEquals("round-tripped OPS signature type mismatch", + before.getSignatureType(), after.getSignatureType()); + isEquals("round-tripped OPS hash algorithm mismatch", + before.getHashAlgorithm(), after.getHashAlgorithm()); + isEquals("round-tripped OPS public key algorithm mismatch", + before.getKeyAlgorithm(), after.getKeyAlgorithm()); + isEquals("round-tripped OPS key-id mismatch", + before.getKeyID(), after.getKeyID()); + isEquals("round-tripped OPS nested flag mismatch", + before.isContaining(), after.isContaining()); + isNull("round-tripped OPS v3 MUST NOT have fingerprint", + after.getFingerprint()); + isNull("round-tripped OPS v3 MUST NOT have salt", + after.getSalt()); + + if (before.hasNewPacketFormat() && newTypeIdFormat) + { + isEncodingEqual(before, after); + } + } + } + + private void roundtripV6Packet() + throws IOException + { + byte[] salt = new byte[32]; + byte[] fingerprint = Hex.decode("CB186C4F0609A697E4D52DFA6C722B0C1F1E27C18A56708F6525EC27BAD9ACC9"); + long keyID = FingerprintUtil.keyIdFromV6Fingerprint(fingerprint); + + new SecureRandom().nextBytes(salt); + OnePassSignaturePacket before = new OnePassSignaturePacket( + PGPSignature.CANONICAL_TEXT_DOCUMENT, + HashAlgorithmTags.SHA512, + PublicKeyAlgorithmTags.EDDSA_LEGACY, + salt, + fingerprint, + false); + + isEquals("Expected OPS version 6", + OnePassSignaturePacket.VERSION_6, before.getVersion()); + isEquals("Signature type mismatch", + PGPSignature.CANONICAL_TEXT_DOCUMENT, before.getSignatureType()); + isEquals("Hash algorithm mismatch", + HashAlgorithmTags.SHA512, before.getHashAlgorithm()); + isEquals("Public key algorithm mismatch", + PublicKeyAlgorithmTags.EDDSA_LEGACY, before.getKeyAlgorithm()); + isEncodingEqual("Salt mismatch", + salt, before.getSalt()); + isEncodingEqual("Fingerprint mismatch", + fingerprint, before.getFingerprint()); + isEquals("Derived key-ID mismatch", + keyID, before.getKeyID()); + isTrue("non-nested OPS is expected to be containing", + before.isContaining()); + + for (boolean newTypeIdFormat : new boolean[] {true, false}) + { + // round-trip the packet by encoding and decoding it + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, newTypeIdFormat); + before.encode(pOut); + pOut.close(); + ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); + BCPGInputStream pIn = new BCPGInputStream(bIn); + OnePassSignaturePacket after = (OnePassSignaturePacket) pIn.readPacket(); + + isEquals("round-tripped OPS version mismatch", + before.getVersion(), after.getVersion()); + isEquals("round-tripped OPS signature type mismatch", + before.getSignatureType(), after.getSignatureType()); + isEquals("round-tripped OPS hash algorithm mismatch", + before.getHashAlgorithm(), after.getHashAlgorithm()); + isEquals("round-tripped OPS public key algorithm mismatch", + before.getKeyAlgorithm(), after.getKeyAlgorithm()); + isEquals("round-tripped OPS key-id mismatch", + before.getKeyID(), after.getKeyID()); + isEquals("round-tripped OPS nested flag mismatch", + before.isContaining(), after.isContaining()); + isEncodingEqual("round-tripped OPS fingerprint mismatch", + before.getFingerprint(), after.getFingerprint()); + isEncodingEqual("round-tripped OPS salt mismatch", + before.getSalt(), after.getSalt()); + + if (before.hasNewPacketFormat() && newTypeIdFormat) + { + isEncodingEqual(before, after); + } + } + } + + private void roundtripV6PacketWithZeroLengthSalt() + throws IOException + { + byte[] salt = new byte[0]; + byte[] fingerprint = Hex.decode("CB186C4F0609A697E4D52DFA6C722B0C1F1E27C18A56708F6525EC27BAD9ACC9"); + + OnePassSignaturePacket before = new OnePassSignaturePacket( + PGPSignature.CANONICAL_TEXT_DOCUMENT, + HashAlgorithmTags.SHA512, + PublicKeyAlgorithmTags.EDDSA_LEGACY, + salt, + fingerprint, + false); + + isEncodingEqual("Salt mismatch", + salt, before.getSalt()); + + for (boolean newTypeIdFormat : new boolean[] {true, false}) + { + // round-trip the packet by encoding and decoding it + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, newTypeIdFormat); + before.encode(pOut); + pOut.close(); + ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); + BCPGInputStream pIn = new BCPGInputStream(bIn); + OnePassSignaturePacket after = (OnePassSignaturePacket) pIn.readPacket(); + + isEquals("round-tripped OPS version mismatch", + before.getVersion(), after.getVersion()); + isEquals("round-tripped OPS signature type mismatch", + before.getSignatureType(), after.getSignatureType()); + isEquals("round-tripped OPS hash algorithm mismatch", + before.getHashAlgorithm(), after.getHashAlgorithm()); + isEquals("round-tripped OPS public key algorithm mismatch", + before.getKeyAlgorithm(), after.getKeyAlgorithm()); + isEquals("round-tripped OPS key-id mismatch", + before.getKeyID(), after.getKeyID()); + isEquals("round-tripped OPS nested flag mismatch", + before.isContaining(), after.isContaining()); + isEncodingEqual("round-tripped OPS fingerprint mismatch", + before.getFingerprint(), after.getFingerprint()); + isEncodingEqual("round-tripped OPS salt mismatch", + before.getSalt(), after.getSalt()); + } + } + + private void parsingOfPacketWithUnknownVersionFails() + { + // Version 0x99 OnePassSignature packet + byte[] encOPS = Hex.decode("c44699010a1b2076495f50218890f7f5e2ee3c1822514f70500f551d86e5c921e404e34a53fbaccb186c4f0609a697e4d52dfa6c722b0c1f1e27c18a56708f6525ec27bad9acc901"); + + ByteArrayInputStream bIn = new ByteArrayInputStream(encOPS); + BCPGInputStream pIn = new BCPGInputStream(bIn); + + try + { + pIn.readPacket(); + fail("Expected UnsupportedPacketVersionException"); + } + catch (IOException e) + { + fail("Expected UnsupportedPacketVersionException", e); + } + catch (UnsupportedPacketVersionException e) + { + // expected + } + } + + private void parsingOfPacketWithTruncatedFingerprintFails() + { + // Version 6 OnePassSignature packet with truncated fingerprint field (20 bytes instead of 32) + // This error would happen, if a v6 OPS packet was generated with a v4 fingerprint. + // extracted from https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-sample-inline-signed-messag + byte[] encOPS = Hex.decode("c44606010a1b2076495f50218890f7f5e2ee3c1822514f70500f551d86e5c921e404e34a53fbaccb186c4f0609a697e4d52dfa6c722b0c1f1e27c101"); + + ByteArrayInputStream bIn = new ByteArrayInputStream(encOPS); + BCPGInputStream pIn = new BCPGInputStream(bIn); + + try + { + pIn.readPacket(); + fail("Expected IOException"); + } + catch (IOException e) + { + // expected + } + } + + @Override + public String getName() + { + return "OnePassSignaturePacketTest"; + } + + @Override + public void performTest() + throws Exception + { + testParseV6OnePassSignaturePacket(); + roundtripV3Packet(); + roundtripV6Packet(); + parsingOfPacketWithUnknownVersionFails(); + parsingOfPacketWithTruncatedFingerprintFails(); + roundtripV6PacketWithZeroLengthSalt(); + } + + public static void main(String[] args) + { + runTest(new OnePassSignaturePacketTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/OpenPgpMessageTest.java b/pg/src/test/java/org/bouncycastle/bcpg/test/OpenPgpMessageTest.java new file mode 100644 index 0000000000..8bad1dcb36 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/OpenPgpMessageTest.java @@ -0,0 +1,177 @@ +package org.bouncycastle.bcpg.test; + +import org.bouncycastle.bcpg.*; +import org.bouncycastle.bcpg.sig.IssuerFingerprint; +import org.bouncycastle.bcpg.sig.SignatureCreationTime; +import org.bouncycastle.openpgp.PGPLiteralData; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +public class OpenPgpMessageTest + extends AbstractPacketTest +{ + + /* + Inline-signed message using a version 6 signature + see https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-sample-inline-signed-messag + */ + public static final String INLINE_SIGNED = "-----BEGIN PGP MESSAGE-----\n" + + "\n" + + "xEYGAQobIHZJX1AhiJD39eLuPBgiUU9wUA9VHYblySHkBONKU/usyxhsTwYJppfk\n" + + "1S36bHIrDB8eJ8GKVnCPZSXsJ7rZrMkBy0p1AAAAAABXaGF0IHdlIG5lZWQgZnJv\n" + + "bSB0aGUgZ3JvY2VyeSBzdG9yZToKCi0gdG9mdQotIHZlZ2V0YWJsZXMKLSBub29k\n" + + "bGVzCsKYBgEbCgAAACkFgmOYo2MiIQbLGGxPBgmml+TVLfpscisMHx4nwYpWcI9l\n" + + "JewnutmsyQAAAABpNiB2SV9QIYiQ9/Xi7jwYIlFPcFAPVR2G5ckh5ATjSlP7rCfQ\n" + + "b7gKqPxbyxbhljGygHQPnqau1eBzrQD5QVplPEDnemrnfmkrpx0GmhCfokxYz9jj\n" + + "FtCgazStmsuOXF9SFQE=\n" + + "-----END PGP MESSAGE-----"; + + /* + Cleartext-signed message using a version 6 signature + see https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-sample-cleartext-signed-mes + */ + public static final String CLEARTEXT_SIGNED = "-----BEGIN PGP SIGNED MESSAGE-----\n" + + "\n" + + "What we need from the grocery store:\n" + + "\n" + + "- - tofu\n" + + "- - vegetables\n" + + "- - noodles\n" + + "\n" + + "-----BEGIN PGP SIGNATURE-----\n" + + "\n" + + "wpgGARsKAAAAKQWCY5ijYyIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6\n" + + "2azJAAAAAGk2IHZJX1AhiJD39eLuPBgiUU9wUA9VHYblySHkBONKU/usJ9BvuAqo\n" + + "/FvLFuGWMbKAdA+epq7V4HOtAPlBWmU8QOd6aud+aSunHQaaEJ+iTFjP2OMW0KBr\n" + + "NK2ay45cX1IVAQ==\n" + + "-----END PGP SIGNATURE-----"; + + // Content of the message's LiteralData packet + public static final String CONTENT = "What we need from the grocery store:\n" + + "\n" + + "- tofu\n" + + "- vegetables\n" + + "- noodles\n"; + // Issuer of the message + public static byte[] ISSUER = Hex.decode("CB186C4F0609A697E4D52DFA6C722B0C1F1E27C18A56708F6525EC27BAD9ACC9"); + // Salt used to generate the signature + public static byte[] SALT = Hex.decode("76495F50218890F7F5E2EE3C1822514F70500F551D86E5C921E404E34A53FBAC"); + + + private void testParseV6CleartextSignedMessage() + throws IOException + { + ByteArrayInputStream bIn = new ByteArrayInputStream(CLEARTEXT_SIGNED.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + + isNull("The ASCII armored input stream MUST NOT hallucinate headers where there are non", + aIn.getArmorHeaders()); // We do not have any header lines after the armor header + + // Parse and compare literal data + ByteArrayOutputStream litOut = new ByteArrayOutputStream(); + while (aIn.isClearText()) + { + litOut.write(aIn.read()); + } + String c = litOut.toString(); + isEquals("Mismatching content of the cleartext-signed test message", + CONTENT, c.substring(0, c.length() - 2)); // compare ignoring last '\n' + + BCPGInputStream pIn = new BCPGInputStream(aIn); + // parse and compare signature + SignaturePacket sig = (SignaturePacket) pIn.readPacket(); + compareSignature(sig); + } + + private void testParseV6InlineSignedMessage() + throws IOException + { + ByteArrayInputStream bIn = new ByteArrayInputStream(INLINE_SIGNED.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + + // Parse and compare the OnePassSignature packet + OnePassSignaturePacket ops = (OnePassSignaturePacket) pIn.readPacket(); + isEquals("OPS packet MUST be of version 6", + OnePassSignaturePacket.VERSION_6, ops.getVersion()); + isEncodingEqual("OPS packet issuer fingerprint mismatch", + ISSUER, ops.getFingerprint()); + isEncodingEqual("OPS packet salt mismatch", + SALT, ops.getSalt()); + isTrue("OPS packet isContaining mismatch", + ops.isContaining()); + + // Parse and compare the LiteralData packet + LiteralDataPacket lit = (LiteralDataPacket) pIn.readPacket(); + compareLiteralData(lit); + + // Parse and compare the Signature packet + SignaturePacket sig = (SignaturePacket) pIn.readPacket(); + compareSignature(sig); + } + + + private void compareLiteralData(LiteralDataPacket lit) + throws IOException + { + isEquals("LiteralDataPacket format mismatch", + PGPLiteralData.UTF8, lit.getFormat()); + isEquals("LiteralDataPacket mod data mismatch", + 0, lit.getModificationTime()); + byte[] content = lit.getInputStream().readAll(); + String contentString = new String(content, StandardCharsets.UTF_8); + isEquals("LiteralDataPacket content mismatch", + CONTENT, contentString); + } + + private void compareSignature(SignaturePacket sig) + { + isEquals("SignaturePacket version mismatch", + SignaturePacket.VERSION_6, sig.getVersion()); + isEquals("SignaturePacket signature type mismatch", + PGPSignature.CANONICAL_TEXT_DOCUMENT, sig.getSignatureType()); + isEquals("SignaturePacket key algorithm mismatch", + PublicKeyAlgorithmTags.Ed25519, sig.getKeyAlgorithm()); + isEquals("SignaturePacket hash algorithm mismatch", + HashAlgorithmTags.SHA512, sig.getHashAlgorithm()); + isTrue("SignaturePacket salt mismatch", + Arrays.areEqual(SALT, sig.getSalt())); + // hashed subpackets + isEquals("SignaturePacket number of hashed packets mismatch", + 2, sig.getHashedSubPackets().length); + SignatureCreationTime creationTimeSubpacket = (SignatureCreationTime) sig.getHashedSubPackets()[0]; + isEquals("SignaturePacket signature creation time mismatch", + 1670947683000L, creationTimeSubpacket.getTime().getTime()); + IssuerFingerprint issuerSubpacket = (IssuerFingerprint) sig.getHashedSubPackets()[1]; + isEncodingEqual("SignaturePacket issuer fingerprint mismatch", + ISSUER, issuerSubpacket.getFingerprint()); + // unhashed subpackets + isEquals("SignaturePacket number of unhashed packets mismatch", + 0, sig.getUnhashedSubPackets().length); + } + + @Override + public String getName() + { + return "OpenPgpMessageTest"; + } + + @Override + public void performTest() + throws Exception + { + testParseV6CleartextSignedMessage(); + testParseV6InlineSignedMessage(); + } + + public static void main(String[] args) + { + runTest(new OpenPgpMessageTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/PacketDumpUtil.java b/pg/src/test/java/org/bouncycastle/bcpg/test/PacketDumpUtil.java new file mode 100644 index 0000000000..e4c16364ff --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/PacketDumpUtil.java @@ -0,0 +1,35 @@ +package org.bouncycastle.bcpg.test; + +import java.io.IOException; + +import org.bouncycastle.bcpg.ContainedPacket; +import org.bouncycastle.test.DumpUtil; + +public class PacketDumpUtil +{ + /** + * Return a formatted hex dump of the packet encoding of the given packet. + * @param packet packet + * @return formatted hex dump + * @throws IOException if an exception happens during packet encoding + */ + public static String hexdump(ContainedPacket packet) + throws IOException + { + return DumpUtil.hexdump(packet.getEncoded()); + } + + /** + * Return a formatted hex dump of the packet encoding of the given packet. + * If startIndent is non-zero, the hex dump is shifted right by the startIndent octets. + * @param startIndent shift the encodings octet stream by a number of bytes + * @param packet packet + * @return formatted hex dump + * @throws IOException if an exception happens during packet encoding + */ + public static String hexdump(int startIndent, ContainedPacket packet) + throws IOException + { + return DumpUtil.hexdump(startIndent, packet.getEncoded()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/SignaturePacketTest.java b/pg/src/test/java/org/bouncycastle/bcpg/test/SignaturePacketTest.java new file mode 100644 index 0000000000..6d77368bd7 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/SignaturePacketTest.java @@ -0,0 +1,159 @@ +package org.bouncycastle.bcpg.test; + +import org.bouncycastle.bcpg.*; +import org.bouncycastle.bcpg.sig.IssuerFingerprint; +import org.bouncycastle.bcpg.sig.IssuerKeyID; +import org.bouncycastle.bcpg.sig.SignatureCreationTime; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.util.encoders.Hex; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class SignaturePacketTest + extends AbstractPacketTest +{ + @Override + public String getName() + { + return "SignaturePacketTest"; + } + + @Override + public void performTest() + throws Exception + { + testParseV6Signature(); + testParseV4Ed25519LegacySignature(); + testParseUnknownVersionSignaturePacket(); + } + + private void testParseV6Signature() + throws IOException + { + // Hex-encoded OpenPGP v6 signature packet + // Extracted from https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-sample-inline-signed-messag + byte[] encSigPacket = Hex.decode("c29806011b0a0000002905826398a363222106cb186c4f0609a697e4d52dfa6c722b0c1f1e27c18a56708f6525ec27bad9acc90000000069362076495f50218890f7f5e2ee3c1822514f70500f551d86e5c921e404e34a53fbac27d06fb80aa8fc5bcb16e19631b280740f9ea6aed5e073ad00f9415a653c40e77a6ae77e692ba71d069a109fa24c58cfd8e316d0a06b34ad9acb8e5c5f521501"); + // Issuer of the message + byte[] issuerFP = Hex.decode("CB186C4F0609A697E4D52DFA6C722B0C1F1E27C18A56708F6525EC27BAD9ACC9"); + // Salt used to generate the signature + byte[] salt = Hex.decode("76495F50218890F7F5E2EE3C1822514F70500F551D86E5C921E404E34A53FBAC"); + + ByteArrayInputStream bIn = new ByteArrayInputStream(encSigPacket); + BCPGInputStream pIn = new BCPGInputStream(bIn); + SignaturePacket sig = (SignaturePacket) pIn.readPacket(); + + isEquals("SignaturePacket version mismatch", + SignaturePacket.VERSION_6, sig.getVersion()); + isEquals("SignaturePacket signature type mismatch", + PGPSignature.CANONICAL_TEXT_DOCUMENT, sig.getSignatureType()); + isEquals("SignaturePacket key algorithm mismatch", + PublicKeyAlgorithmTags.Ed25519, sig.getKeyAlgorithm()); + isEquals("SignaturePacket hash algorithm mismatch", + HashAlgorithmTags.SHA512, sig.getHashAlgorithm()); + isEncodingEqual("SignaturePacket salt mismatch", + salt, sig.getSalt()); + // hashed subpackets + isEquals("SignaturePacket number of hashed packets mismatch", + 2, sig.getHashedSubPackets().length); + SignatureCreationTime creationTimeSubpacket = (SignatureCreationTime) sig.getHashedSubPackets()[0]; + isEquals("SignaturePacket signature creation time mismatch", + 1670947683000L, creationTimeSubpacket.getTime().getTime()); + IssuerFingerprint issuerSubpacket = (IssuerFingerprint) sig.getHashedSubPackets()[1]; + isEncodingEqual("SignaturePacket issuer fingerprint mismatch", + issuerFP, issuerSubpacket.getFingerprint()); + // unhashed subpackets + isEquals("SignaturePacket number of unhashed packets mismatch", + 0, sig.getUnhashedSubPackets().length); + + // v6 Ed25519 signatures (not LEGACY) do not use MPI encoding for the raw signature + // but rather encode into octet strings + isNull("Signature MPI encoding MUST be null", + sig.getSignature()); + isEncodingEqual("Signature octet string encoding mismatch", + Hex.decode("27d06fb80aa8fc5bcb16e19631b280740f9ea6aed5e073ad00f9415a653c40e77a6ae77e692ba71d069a109fa24c58cfd8e316d0a06b34ad9acb8e5c5f521501"), + sig.getSignatureBytes()); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, true); + sig.encode(pOut); + pOut.close(); + + isEncodingEqual("SignaturePacket encoding mismatch", encSigPacket, bOut.toByteArray()); + } + + private void testParseV4Ed25519LegacySignature() + throws IOException + { + // Hex-encoded v4 test signature + // see https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-sample-v4-ed25519legacy-sig + byte[] encSigPacket = Hex.decode("885e040016080006050255f95f95000a09108cfde12197965a9af62200ff56f90cca98e2102637bd983fdb16c131dfd27ed82bf4dde5606e0d756aed33660100d09c4fa11527f038e0f57f2201d82f2ea2c9033265fa6ceb489e854bae61b404"); + ByteArrayInputStream bIn = new ByteArrayInputStream(encSigPacket); + BCPGInputStream pIn = new BCPGInputStream(bIn); + SignaturePacket sig = (SignaturePacket) pIn.readPacket(); + + isEquals("SignaturePacket version mismatch", + SignaturePacket.VERSION_4, sig.getVersion()); + isEquals("SignaturePacket signature type mismatch", + PGPSignature.BINARY_DOCUMENT, sig.getSignatureType()); + isEquals("SignaturePacket public key algorithm mismatch", + PublicKeyAlgorithmTags.EDDSA_LEGACY, sig.getKeyAlgorithm()); + isEquals("SignaturePacket hash algorithm mismatch", + HashAlgorithmTags.SHA256, sig.getHashAlgorithm()); + isEquals("SignaturePacket number of hashed subpackets mismatch", + 1, sig.getHashedSubPackets().length); + SignatureCreationTime creationTimeSubpacket = (SignatureCreationTime) sig.getHashedSubPackets()[0]; + isEquals("SignaturePacket creationTime mismatch", + 1442406293000L, creationTimeSubpacket.getTime().getTime()); + isEquals("SignaturePacket number of unhashed subpackets mismatch", + 1, sig.getUnhashedSubPackets().length); + IssuerKeyID issuerKeyID = (IssuerKeyID) sig.getUnhashedSubPackets()[0]; + isEquals("SignaturePacket issuer key-id mismatch", + -8287220204898461030L, issuerKeyID.getKeyID()); + + // EDDSA_LEGACY uses MPI encoding for the raw signature value + MPInteger[] mpInts = sig.getSignature(); + isEquals("Signature MPI encoding mismatch", + 2, mpInts.length); + isEncodingEqual("Signature MPI encoding in signatureBytes field mismatch", + Hex.decode("00ff56f90cca98e2102637bd983fdb16c131dfd27ed82bf4dde5606e0d756aed33660100d09c4fa11527f038e0f57f2201d82f2ea2c9033265fa6ceb489e854bae61b404"), + sig.getSignatureBytes()); + + // v4 signatures do not have salt + isNull("Salt MUST be null", sig.getSalt()); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, false); + sig.encode(pOut); + pOut.close(); + + isEncodingEqual("SignaturePacket encoding mismatch", + encSigPacket, bOut.toByteArray()); + } + + private void testParseUnknownVersionSignaturePacket() + { + // Hex-encoded signature with version 0x99 + byte[] encSigPacket = Hex.decode("885e990016080006050255f95f95000a09108cfde12197965a9af62200ff56f90cca98e2102637bd983fdb16c131dfd27ed82bf4dde5606e0d756aed33660100d09c4fa11527f038e0f57f2201d82f2ea2c9033265fa6ceb489e854bae61b404"); + ByteArrayInputStream bIn = new ByteArrayInputStream(encSigPacket); + BCPGInputStream pIn = new BCPGInputStream(bIn); + Exception ex = testException("unsupported version: 153", + "UnsupportedPacketVersionException", + new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + SignaturePacket sig = (SignaturePacket) pIn.readPacket(); + } + }); + isNotNull("Parsing SignaturePacket of version 0x99 MUST throw UnsupportedPacketVersionException.", ex); + } + + public static void main(String[] args) + { + runTest(new SignaturePacketTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/UnknownPublicKeyPacketTest.java b/pg/src/test/java/org/bouncycastle/bcpg/test/UnknownPublicKeyPacketTest.java new file mode 100644 index 0000000000..18fd8339ae --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/UnknownPublicKeyPacketTest.java @@ -0,0 +1,66 @@ +package org.bouncycastle.bcpg.test; + +import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.bcpg.PacketFormat; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.UnknownBCPGKey; +import org.bouncycastle.util.encoders.Hex; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +public class UnknownPublicKeyPacketTest + extends AbstractPacketTest +{ + private final String[] testVectors = {"c61406665ef5f3630000000a00010203040506070809", "c61405665ef5f3630000000a00010203040506070809"}; + private final int[] versions = {PublicKeyPacket.VERSION_6, PublicKeyPacket.LIBREPGP_5}; + + @Override + public String getName() + { + return "UnknownPublicKeyPacketTest"; + } + + @Override + public void performTest() + throws Exception + { + parseUnknownPublicKey(); + } + + private void parseUnknownPublicKey() throws ParseException, IOException { + SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); + parser.setTimeZone(TimeZone.getTimeZone("UTC")); + + for (int i = 0; i < testVectors.length; i++) + { + String testVector = testVectors[i]; + byte[] rawKey = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; + Date creationTime = parser.parse("2024-06-04 11:09:39 UTC"); + + PublicKeyPacket p = new PublicKeyPacket( + versions[i], + 99, + creationTime, + new UnknownBCPGKey(10, rawKey)); + isEncodingEqual("Encoding mismatch", Hex.decode(testVector), p.getEncoded(PacketFormat.CURRENT)); + + ByteArrayInputStream bIn = new ByteArrayInputStream(Hex.decode(testVector)); + BCPGInputStream pIn = new BCPGInputStream(bIn); + PublicKeyPacket parsed = (PublicKeyPacket) pIn.readPacket(); + isEquals("Packet version mismatch", versions[i], parsed.getVersion()); + isEquals("Public key algorithm mismatch", 99, parsed.getAlgorithm()); + isEquals("Creation time mismatch", creationTime, parsed.getTime()); + isEncodingEqual("Raw key encoding mismatch", rawKey, parsed.getKey().getEncoded()); + } + } + + public static void main(String[] args) + { + runTest(new UnknownPublicKeyPacketTest()); + } +} \ No newline at end of file diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/UnknownSecretKeyPacketTest.java b/pg/src/test/java/org/bouncycastle/bcpg/test/UnknownSecretKeyPacketTest.java new file mode 100644 index 0000000000..3089d8f724 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/UnknownSecretKeyPacketTest.java @@ -0,0 +1,76 @@ +package org.bouncycastle.bcpg.test; + +import org.bouncycastle.bcpg.ArmoredInputStream; +import org.bouncycastle.bcpg.ArmoredOutputStream; +import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.bcpg.BCPGOutputStream; +import org.bouncycastle.bcpg.PacketFormat; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.SecretKeyPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.UnknownBCPGKey; +import org.bouncycastle.util.encoders.Hex; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Date; + +public class UnknownSecretKeyPacketTest + extends AbstractPacketTest +{ + @Override + public String getName() + { + return "UnknownSecretKeyPacketTest"; + } + + @Override + public void performTest() + throws Exception + { + parseUnknownUnencryptedSecretKey(); + } + + private void parseUnknownUnencryptedSecretKey() + throws IOException + { + for (int version : new int[]{PublicKeyPacket.LIBREPGP_5, PublicKeyPacket.VERSION_6}) + { + Date creationTime = new Date((new Date().getTime() / 1000) * 1000); + SecretKeyPacket sk = new SecretKeyPacket( + new PublicKeyPacket( + version, + 99, + creationTime, + new UnknownBCPGKey(3, Hex.decode("c0ffee"))), + SymmetricKeyAlgorithmTags.NULL, + null, + null, + Hex.decode("0decaf")); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ArmoredOutputStream aOut = new ArmoredOutputStream(bOut); + BCPGOutputStream pOut = new BCPGOutputStream(aOut, PacketFormat.CURRENT); + sk.encode(pOut); + pOut.close(); + aOut.close(); + + ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + SecretKeyPacket p = (SecretKeyPacket) pIn.readPacket(); + + isEquals("Packet version mismatch", version, p.getPublicKeyPacket().getVersion()); + isEquals("Algorithm mismatch", 99, p.getPublicKeyPacket().getAlgorithm()); + isEncodingEqual("Public key encoding mismatch", Hex.decode("c0ffee"), p.getPublicKeyPacket().getKey().getEncoded()); + isEncodingEqual("Secret key encoding mismatch", Hex.decode("0decaf"), p.getSecretKeyData()); + isEncodingEqual("Packet encoding mismatch", sk.getEncoded(PacketFormat.CURRENT), p.getEncoded(PacketFormat.CURRENT)); + } + } + + public static void main(String[] args) + { + runTest(new UnknownSecretKeyPacketTest()); + } +} \ No newline at end of file diff --git a/pg/src/test/java/org/bouncycastle/gpg/keybox/AllTests.java b/pg/src/test/java/org/bouncycastle/gpg/keybox/AllTests.java new file mode 100644 index 0000000000..e5c299fc6a --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/gpg/keybox/AllTests.java @@ -0,0 +1,66 @@ +package org.bouncycastle.gpg.keybox; + +import java.security.Security; + +import junit.extensions.TestSetup; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.test.PrintTestResult; +import org.bouncycastle.util.test.SimpleTestResult; + +public class AllTests + extends TestCase +{ + public void testPGP() + { + Security.addProvider(new BouncyCastleProvider()); + + org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; + + for (int i = 0; i != tests.length; i++) + { + SimpleTestResult result = (SimpleTestResult)tests[i].perform(); + + if (!result.isSuccessful()) + { + fail(tests[i].getClass().getName() + " " + result.toString()); + } + } + } + + public static void main(String[] args) + { + PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); + } + + public static Test suite() + { + TestSuite suite = new TestSuite("OpenPGP Tests"); + + suite.addTestSuite(AllTests.class); + + return new BCTestSetup(suite); + } + + static class BCTestSetup + extends TestSetup + { + public BCTestSetup(Test test) + { + super(test); + } + + protected void setUp() + { + Security.addProvider(new BouncyCastleProvider()); + } + + protected void tearDown() + { + Security.removeProvider("BC"); + } + } +} + diff --git a/pg/src/test/java/org/bouncycastle/gpg/keybox/KeyBoxByteBufferTest.java b/pg/src/test/java/org/bouncycastle/gpg/keybox/KeyBoxByteBufferTest.java index 838bd182b0..f83705e556 100644 --- a/pg/src/test/java/org/bouncycastle/gpg/keybox/KeyBoxByteBufferTest.java +++ b/pg/src/test/java/org/bouncycastle/gpg/keybox/KeyBoxByteBufferTest.java @@ -1,5 +1,6 @@ package org.bouncycastle.gpg.keybox; +import java.io.IOException; import java.security.Security; import java.util.Arrays; @@ -98,6 +99,7 @@ public void testConsumeReadPastEnd() { KeyBoxByteBuffer buf = KeyBoxByteBuffer.wrap(new byte[4]); buf.consume(3); + isEquals(-16, buf.size()); try { buf.consume(2); @@ -107,6 +109,72 @@ public void testConsumeReadPastEnd() { } + buf.position(0); + } + + public void testExceptions() + throws IOException + { + testException("Could not convert ", "IllegalStateException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + KeyBoxByteBuffer.wrap(new Object()); + } + }); + final KeyBoxByteBuffer buf = KeyBoxByteBuffer.wrap(new byte[4]); + testException("invalid range ", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + buf.rangeOf(-1, 2); + } + }); + + testException("range exceeds buffer remaining", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + buf.rangeOf(0, 24); + } + }); + + testException("size exceeds buffer remaining", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + buf.consume(buf.remaining() + 1); + } + }); + + testException("size less than 0", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + buf.bN(-1); + } + }); + + testException("size exceeds buffer remaining", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + KeyBoxByteBuffer buf1 = KeyBoxByteBuffer.wrap(new byte[21]); + buf1.consume(22); + } + }); } @Override @@ -122,5 +190,6 @@ public void performTest() testConsumeReadPastEnd(); testRangeReadPastEnd(); testReadPastEnd(); + testExceptions(); } } diff --git a/pg/src/test/java/org/bouncycastle/gpg/keybox/RegressionTest.java b/pg/src/test/java/org/bouncycastle/gpg/keybox/RegressionTest.java new file mode 100644 index 0000000000..8eb72838a5 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/gpg/keybox/RegressionTest.java @@ -0,0 +1,19 @@ +package org.bouncycastle.gpg.keybox; + +import java.security.Security; + +import org.bouncycastle.util.test.SimpleTest; +import org.bouncycastle.util.test.Test; + +public class RegressionTest +{ + public static Test[] tests = { + new KeyBoxByteBufferTest() + }; + + public static void main(String[] args) + { + Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); + SimpleTest.runTests(tests); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/examples/test/AllTests.java b/pg/src/test/java/org/bouncycastle/openpgp/examples/test/AllTests.java index 8fe006ed39..f65ef59b57 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/examples/test/AllTests.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/examples/test/AllTests.java @@ -224,15 +224,9 @@ public void testPBEEncryption() PBEFileProcessor.main(new String[]{"-d", "test.txt.bpg", "password"}); - assertEquals("no message integrity check", getLine(_currentErr)); - - PBEFileProcessor.main(new String[]{"-e", "-i", "test.txt", "password"}); - - PBEFileProcessor.main(new String[]{"-d", "test.txt.bpg", "password"}); - assertEquals("message integrity check passed", getLine(_currentErr)); - PBEFileProcessor.main(new String[]{"-e", "-ai", "test.txt", "password"}); + PBEFileProcessor.main(new String[]{"-e", "-a", "test.txt", "password"}); PBEFileProcessor.main(new String[]{"-d", "test.txt.asc", "password"}); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/AEADProtectedPGPSecretKeyTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/AEADProtectedPGPSecretKeyTest.java new file mode 100644 index 0000000000..75cf09646b --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/AEADProtectedPGPSecretKeyTest.java @@ -0,0 +1,364 @@ +package org.bouncycastle.openpgp.test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Date; +import java.util.Iterator; + +import org.bouncycastle.bcpg.AEADAlgorithmTags; +import org.bouncycastle.bcpg.ArmoredInputStream; +import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.S2K; +import org.bouncycastle.bcpg.SecretKeyPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator; +import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPKeyPair; +import org.bouncycastle.openpgp.PGPObjectFactory; +import org.bouncycastle.openpgp.PGPPrivateKey; +import org.bouncycastle.openpgp.PGPSecretKey; +import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.bc.BcAEADSecretKeyEncryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcaAEADSecretKeyEncryptorBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcePBEProtectionRemoverFactory; +import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; +import org.bouncycastle.util.encoders.Hex; + +public class AEADProtectedPGPSecretKeyTest + extends AbstractPgpKeyPairTest +{ + + @Override + public String getName() + { + return "AEADProtectedPGPSecretKeyTest"; + } + + @Override + public void performTest() + throws Exception + { + unlockTestVector(); + + generateAndLockUnlockEd25519v4Key(); + generateAndLockUnlockEd25519v6Key(); + + testUnlockKeyWithWrongPassphraseBc(); + testUnlockKeyWithWrongPassphraseJca(); + } + + private void unlockTestVector() + throws IOException, PGPException + { + // AEAD encrypted test vector extracted from here: + // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-sample-locked-v6-secret-key + String armoredVector = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "\n" + + "xYIGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laP9JgkC\n" + + "FARdb9ccngltHraRe25uHuyuAQQVtKipJ0+r5jL4dacGWSAheCWPpITYiyfyIOPS\n" + + "3gIDyg8f7strd1OB4+LZsUhcIjOMpVHgmiY/IutJkulneoBYwrEGHxsKAAAAQgWC\n" + + "Y4d/4wMLCQcFFQoOCAwCFgACmwMCHgkiIQbLGGxPBgmml+TVLfpscisMHx4nwYpW\n" + + "cI9lJewnutmsyQUnCQIHAgAAAACtKCAQPi19In7A5tfORHHbNr/JcIMlNpAnFJin\n" + + "7wV2wH+q4UWFs7kDsBJ+xP2i8CMEWi7Ha8tPlXGpZR4UruETeh1mhELIj5UeM8T/\n" + + "0z+5oX1RHu11j8bZzFDLX9eTsgOdWATHggZjh3/jGQAAACCGkySDZ/nlAV25Ivj0\n" + + "gJXdp4SYfy1ZhbEvutFsr15ENf0mCQIUBA5hhGgp2oaavg6mFUXcFMwBBBUuE8qf\n" + + "9Ock+xwusd+GAglBr5LVyr/lup3xxQvHXFSjjA2haXfoN6xUGRdDEHI6+uevKjVR\n" + + "v5oAxgu7eJpaXNjCmwYYGwoAAAAsBYJjh3/jApsMIiEGyxhsTwYJppfk1S36bHIr\n" + + "DB8eJ8GKVnCPZSXsJ7rZrMkAAAAABAEgpukYbZ1ZNfyP5WMUzbUnSGpaUSD5t2Ki\n" + + "Nacp8DkBClZRa2c3AMQzSDXa9jGhYzxjzVb5scHDzTkjyRZWRdTq8U6L4da+/+Kt\n" + + "ruh8m7Xo2ehSSFyWRSuTSZe5tm/KXgYG\n" + + "-----END PGP PRIVATE KEY BLOCK-----"; + char[] passphrase = "correct horse battery staple".toCharArray(); + // Plaintext vectors extracted from here: + // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-sample-v6-secret-key-transf + byte[] plainPrimaryKey = Hex.decode("1972817b12be707e8d5f586ce61361201d344eb266a2c82fde6835762b65b0b7"); + byte[] plainSubkey = Hex.decode("4d600a4f794d44775c57a26e0feefed558e9afffd6ad0d582d57fb2ba2dcedb8"); + + ByteArrayInputStream bIn = new ByteArrayInputStream(armoredVector.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + PGPObjectFactory objFact = new BcPGPObjectFactory(pIn); + PGPSecretKeyRing keys = (PGPSecretKeyRing) objFact.nextObject(); + + Iterator it = keys.getSecretKeys(); + PGPSecretKey primaryKey = it.next(); + PGPSecretKey subkey = it.next(); + + // Test Bouncy Castle KeyDecryptor implementation + BcPBESecretKeyDecryptorBuilder bcDecryptor = new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()); + PGPPrivateKey privPrimaryKey = primaryKey.extractPrivateKey(bcDecryptor.build(passphrase)); + isEncodingEqual(plainPrimaryKey, privPrimaryKey.getPrivateKeyDataPacket().getEncoded()); + + // Test Jca/Jce KeyDecryptor implementation + JcePBESecretKeyDecryptorBuilder jceDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(new BouncyCastleProvider()); + PGPPrivateKey privSubKey = subkey.extractPrivateKey(jceDecryptor.build(passphrase)); + isEncodingEqual(plainSubkey, privSubKey.getPrivateKeyDataPacket().getEncoded()); + + // Test Jca/Jce ProtectionRemover implementation + JcePBEProtectionRemoverFactory jceProtectionRemover = new JcePBEProtectionRemoverFactory(passphrase).setProvider(new BouncyCastleProvider()); + PGPPrivateKey privSubKey2 = subkey.extractPrivateKey(jceProtectionRemover.createDecryptor("")); + isEncodingEqual(plainSubkey, privSubKey2.getPrivateKeyDataPacket().getEncoded()); + } + + private void generateAndLockUnlockEd25519v4Key() + throws PGPException + { + Ed25519KeyPairGenerator gen = new Ed25519KeyPairGenerator(); + gen.init(new Ed25519KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + Date creationTime = currentTimeRounded(); + PGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyPacket.VERSION_4, PublicKeyAlgorithmTags.Ed25519, kp, creationTime); + + String passphrase = "a$$word"; + + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.AES_128, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.AES_128, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.AES_128, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.AES_128, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.AES_128, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.AES_128, passphrase, passphrase); + + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.AES_192, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.AES_192, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.AES_192, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.AES_192, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.AES_192, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.AES_192, passphrase, passphrase); + + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.AES_256, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.AES_256, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.AES_256, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.AES_256, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.AES_256, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.AES_256, passphrase, passphrase); + + + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.CAMELLIA_128, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.CAMELLIA_128, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.CAMELLIA_128, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.CAMELLIA_128, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.CAMELLIA_128, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.CAMELLIA_128, passphrase, passphrase); + + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.CAMELLIA_192, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.CAMELLIA_192, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.CAMELLIA_192, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.CAMELLIA_192, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.CAMELLIA_192, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.CAMELLIA_192, passphrase, passphrase); + + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.CAMELLIA_256, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.CAMELLIA_256, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.CAMELLIA_256, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.CAMELLIA_256, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.CAMELLIA_256, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.CAMELLIA_256, passphrase, passphrase); + } + + private void generateAndLockUnlockEd25519v6Key() + throws PGPException + { + Ed25519KeyPairGenerator gen = new Ed25519KeyPairGenerator(); + gen.init(new Ed25519KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + Date creationTime = currentTimeRounded(); + + String passphrase = "a$$word"; + + PGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyPacket.VERSION_6, PublicKeyAlgorithmTags.Ed25519, kp, creationTime); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.AES_256, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.AES_256, passphrase, passphrase); + lockUnlockKeyBc(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.AES_256, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.EAX, SymmetricKeyAlgorithmTags.AES_256, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.AES_256, passphrase, passphrase); + lockUnlockKeyJca(keyPair, AEADAlgorithmTags.GCM, SymmetricKeyAlgorithmTags.AES_256, passphrase, passphrase); + + } + + private void testUnlockKeyWithWrongPassphraseBc() + throws PGPException + { + Ed25519KeyPairGenerator gen = new Ed25519KeyPairGenerator(); + gen.init(new Ed25519KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + Date creationTime = currentTimeRounded(); + + for (int version : new int[]{PublicKeyPacket.VERSION_4, PublicKeyPacket.VERSION_6}) + { + PGPKeyPair keyPair = new BcPGPKeyPair(version, PublicKeyAlgorithmTags.Ed25519, kp, creationTime); + + BcAEADSecretKeyEncryptorBuilder bcEncBuilder = new BcAEADSecretKeyEncryptorBuilder( + AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.AES_256, + S2K.Argon2Params.memoryConstrainedParameters()); + + PGPDigestCalculatorProvider digestProv = new BcPGPDigestCalculatorProvider(); + + PGPSecretKey sk = new PGPSecretKey( + keyPair.getPrivateKey(), + keyPair.getPublicKey(), + digestProv.get(HashAlgorithmTags.SHA1), + true, + bcEncBuilder.build( + "passphrase".toCharArray(), + keyPair.getPublicKey().getPublicKeyPacket())); + + BcPBESecretKeyDecryptorBuilder bcDecBuilder = new BcPBESecretKeyDecryptorBuilder(digestProv); + try + { + sk.extractPrivateKey(bcDecBuilder.build("password".toCharArray())); + fail("Expected PGPException due to mismatched passphrase"); + } + catch (PGPException e) + { + // expected + } + } + } + + private void testUnlockKeyWithWrongPassphraseJca() + throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException + { + BouncyCastleProvider prov = new BouncyCastleProvider(); + KeyPairGenerator eddsaGen = KeyPairGenerator.getInstance("EdDSA", prov); + + eddsaGen.initialize(new ECNamedCurveGenParameterSpec("ed25519")); + KeyPair kp = eddsaGen.generateKeyPair(); + Date creationTime = currentTimeRounded(); + + for (int version : new int[]{PublicKeyPacket.VERSION_4, PublicKeyPacket.VERSION_6}) + { + PGPKeyPair keyPair = new JcaPGPKeyPair(version, PublicKeyAlgorithmTags.Ed25519, kp, creationTime); + + JcaAEADSecretKeyEncryptorBuilder jcaEncBuilder = new JcaAEADSecretKeyEncryptorBuilder( + AEADAlgorithmTags.OCB, SymmetricKeyAlgorithmTags.AES_256, + S2K.Argon2Params.memoryConstrainedParameters()) + .setProvider(prov); + + PGPDigestCalculatorProvider digestProv = new JcaPGPDigestCalculatorProviderBuilder() + .setProvider(prov) + .build(); + + PGPSecretKey sk = new PGPSecretKey( + keyPair.getPrivateKey(), + keyPair.getPublicKey(), + digestProv.get(HashAlgorithmTags.SHA1), + true, + jcaEncBuilder.build( + "Yin".toCharArray(), + keyPair.getPublicKey().getPublicKeyPacket())); + + JcePBESecretKeyDecryptorBuilder jceDecBuilder = new JcePBESecretKeyDecryptorBuilder(digestProv).setProvider(prov); + try + { + sk.extractPrivateKey(jceDecBuilder.build("Yang".toCharArray())); + fail("Expected PGPException due to wrong passphrase"); + } catch (PGPException e) + { + // expected + } + } + } + + private void lockUnlockKeyBc( + PGPKeyPair keyPair, + int aeadAlgorithm, + int encAlgorithm, + String encryptionPassphrase, + String decryptionPassphrase) + throws PGPException + { + BcAEADSecretKeyEncryptorBuilder bcEncBuilder = new BcAEADSecretKeyEncryptorBuilder( + aeadAlgorithm, encAlgorithm, + S2K.Argon2Params.memoryConstrainedParameters()); + + PGPDigestCalculatorProvider digestProv = new BcPGPDigestCalculatorProvider(); + + PGPSecretKey sk = new PGPSecretKey( + keyPair.getPrivateKey(), + keyPair.getPublicKey(), + digestProv.get(HashAlgorithmTags.SHA1), + true, + bcEncBuilder.build( + encryptionPassphrase.toCharArray(), + keyPair.getPublicKey().getPublicKeyPacket())); + + isEquals("S2KUsage mismatch", SecretKeyPacket.USAGE_AEAD, sk.getS2KUsage()); + isEquals("S2K type mismatch", S2K.ARGON_2, sk.getS2K().getType()); + isEquals("Argon2 passes parameter mismatch", 3, sk.getS2K().getPasses()); + isEquals("Argon2 parallelism parameter mismatch", 4, sk.getS2K().getParallelism()); + isEquals("Argon2 memory exponent parameter mismatch", 16, sk.getS2K().getMemorySizeExponent()); + isEquals("Symmetric key encryption algorithm mismatch", encAlgorithm, sk.getKeyEncryptionAlgorithm()); + isEquals("AEAD key encryption algorithm mismatch", aeadAlgorithm, sk.getAEADKeyEncryptionAlgorithm()); + + BcPBESecretKeyDecryptorBuilder bcDecBuilder = new BcPBESecretKeyDecryptorBuilder(digestProv); + PGPPrivateKey dec = sk.extractPrivateKey(bcDecBuilder.build(decryptionPassphrase.toCharArray())); + isEncodingEqual("Decrypted key encoding mismatch", + keyPair.getPrivateKey().getPrivateKeyDataPacket().getEncoded(), dec.getPrivateKeyDataPacket().getEncoded()); + } + + private void lockUnlockKeyJca( + PGPKeyPair keyPair, + int aeadAlgorithm, + int encAlgorithm, + String encryptionPassphrase, + String decryptionPassphrase) + throws PGPException + { + BouncyCastleProvider prov = new BouncyCastleProvider(); + JcaAEADSecretKeyEncryptorBuilder jcaEncBuilder = new JcaAEADSecretKeyEncryptorBuilder( + aeadAlgorithm, encAlgorithm, + S2K.Argon2Params.memoryConstrainedParameters()) + .setProvider(prov); + + PGPDigestCalculatorProvider digestProv = new JcaPGPDigestCalculatorProviderBuilder() + .setProvider(prov) + .build(); + + PGPSecretKey sk = new PGPSecretKey( + keyPair.getPrivateKey(), + keyPair.getPublicKey(), + digestProv.get(HashAlgorithmTags.SHA1), + true, + jcaEncBuilder.build( + encryptionPassphrase.toCharArray(), + keyPair.getPublicKey().getPublicKeyPacket())); + + isEquals("S2KUsage mismatch", SecretKeyPacket.USAGE_AEAD, sk.getS2KUsage()); + isEquals("S2K type mismatch", S2K.ARGON_2, sk.getS2K().getType()); + isEquals("Argon2 passes parameter mismatch", 3, sk.getS2K().getPasses()); + isEquals("Argon2 parallelism parameter mismatch", 4, sk.getS2K().getParallelism()); + isEquals("Argon2 memory exponent parameter mismatch", 16, sk.getS2K().getMemorySizeExponent()); + isEquals("Symmetric key encryption algorithm mismatch", encAlgorithm, sk.getKeyEncryptionAlgorithm()); + isEquals("AEAD algorithm mismatch", aeadAlgorithm, sk.getAEADKeyEncryptionAlgorithm()); + + JcePBESecretKeyDecryptorBuilder jceDecBuilder = new JcePBESecretKeyDecryptorBuilder(digestProv).setProvider(prov); + PGPPrivateKey dec = sk.extractPrivateKey(jceDecBuilder.build(decryptionPassphrase.toCharArray())); + isEncodingEqual("Decrypted key encoding mismatch", + keyPair.getPrivateKey().getPrivateKeyDataPacket().getEncoded(), dec.getPrivateKeyDataPacket().getEncoded()); + } + + public static void main(String[] args) + { + runTest(new AEADProtectedPGPSecretKeyTest()); + } +} \ No newline at end of file diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/AEADWithArgon2Test.java b/pg/src/test/java/org/bouncycastle/openpgp/test/AEADWithArgon2Test.java new file mode 100644 index 0000000000..f26f56884f --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/AEADWithArgon2Test.java @@ -0,0 +1,28 @@ +package org.bouncycastle.openpgp.test; + +import java.security.Security; + +import junit.framework.TestCase; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.test.SimpleTestResult; + +public class AEADWithArgon2Test + extends TestCase +{ + public void testAEADProtectedPGPSecretKey() + { + if (Security.getProvider("BC") == null) + { + Security.addProvider(new BouncyCastleProvider()); + } + + AEADProtectedPGPSecretKeyTest test = new AEADProtectedPGPSecretKeyTest(); + + SimpleTestResult result = (SimpleTestResult)test.perform(); + + if (!result.isSuccessful()) + { + fail(test.getClass().getName() + " " + result.toString()); + } + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/AbstractPgpKeyPairTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/AbstractPgpKeyPairTest.java new file mode 100644 index 0000000000..85a7a158a8 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/AbstractPgpKeyPairTest.java @@ -0,0 +1,46 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.test.AbstractPacketTest; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; + +import java.security.KeyPair; +import java.util.Date; + +public abstract class AbstractPgpKeyPairTest + extends AbstractPacketTest +{ + + public Date currentTimeRounded() + { + Date now = new Date(); + return new Date((now.getTime() / 1000) * 1000); // rounded to seconds + } + + public BcPGPKeyPair toBcKeyPair(JcaPGPKeyPair keyPair) + throws PGPException + { + BcPGPKeyConverter c = new BcPGPKeyConverter(); + return new BcPGPKeyPair(keyPair.getPublicKey().getVersion(), keyPair.getPublicKey().getAlgorithm(), + new AsymmetricCipherKeyPair( + c.getPublicKey(keyPair.getPublicKey()), + c.getPrivateKey(keyPair.getPrivateKey())), + keyPair.getPublicKey().getCreationTime()); + } + + public JcaPGPKeyPair toJcaKeyPair(BcPGPKeyPair keyPair) + throws PGPException + { + JcaPGPKeyConverter c = new JcaPGPKeyConverter().setProvider(new BouncyCastleProvider()); + return new JcaPGPKeyPair(keyPair.getPublicKey().getVersion(), keyPair.getPublicKey().getAlgorithm(), + new KeyPair( + c.getPublicKey(keyPair.getPublicKey()), + c.getPrivateKey(keyPair.getPrivateKey())), + keyPair.getPublicKey().getCreationTime()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/AllTests.java b/pg/src/test/java/org/bouncycastle/openpgp/test/AllTests.java index dd455c460f..454f1a047b 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/AllTests.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/AllTests.java @@ -14,34 +14,36 @@ public class AllTests extends TestCase { public void testPGP() - { + { Security.addProvider(new BouncyCastleProvider()); - + org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; - + for (int i = 0; i != tests.length; i++) { - SimpleTestResult result = (SimpleTestResult)tests[i].perform(); - + SimpleTestResult result = (SimpleTestResult)tests[i].perform(); + if (!result.isSuccessful()) { - fail(result.toString()); + fail(tests[i].getClass().getName() + " " + result.toString()); } } } - - public static void main (String[] args) + + public static void main(String[] args) { - PrintTestResult.printResult( junit.textui.TestRunner.run(suite())); + PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); } - + public static Test suite() { TestSuite suite = new TestSuite("OpenPGP Tests"); - + suite.addTestSuite(AllTests.class); suite.addTestSuite(DSA2Test.class); suite.addTestSuite(PGPUnicodeTest.class); + suite.addTestSuite(AEADWithArgon2Test.class); + suite.addTestSuite(Argon2Test.class); return new BCTestSetup(suite); } diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/Argon2S2KTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/Argon2S2KTest.java index d76bc49e21..4062aa5266 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/Argon2S2KTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/Argon2S2KTest.java @@ -7,12 +7,17 @@ import java.io.OutputStream; import java.security.SecureRandom; import java.util.Date; +import java.util.Iterator; import org.bouncycastle.bcpg.ArmoredInputStream; import org.bouncycastle.bcpg.ArmoredOutputStream; +import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.BCPGOutputStream; +import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.S2K; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket; +import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; @@ -35,10 +40,10 @@ public class Argon2S2KTest private static final SecureRandom RANDOM = new SecureRandom(); - private static final String TEST_MSG_PASSWORD = "password"; + static final String TEST_MSG_PASSWORD = "password"; // Test message from the crypto-refresh-05 document - private static final String TEST_MSG_AES128 = "-----BEGIN PGP MESSAGE-----\n" + + static final String TEST_MSG_AES128 = "-----BEGIN PGP MESSAGE-----\n" + "Comment: Encrypted using AES with 128-bit key\n" + "Comment: Session key: 01FE16BBACFD1E7B78EF3B865187374F\n" + "\n" + @@ -70,7 +75,7 @@ public class Argon2S2KTest "=n8Ma\n" + "-----END PGP MESSAGE-----"; - private static final String TEST_MSG_PLAIN = "Hello, world!"; + static final String TEST_MSG_PLAIN = "Hello, world!"; public static void main(String[] args) { @@ -87,6 +92,7 @@ public String getName() public void performTest() throws Exception { + //testExceptions(); // S2K parameter serialization encodingTest(); // Test vectors @@ -201,5 +207,4 @@ public String encryptMessageSymmetricallyWithArgon2(String plaintext, String pas String encrypted = out.toString(); return encrypted; } - } diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/Argon2Test.java b/pg/src/test/java/org/bouncycastle/openpgp/test/Argon2Test.java new file mode 100644 index 0000000000..de62c8c606 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/Argon2Test.java @@ -0,0 +1,28 @@ +package org.bouncycastle.openpgp.test; + +import java.security.Security; + +import junit.framework.TestCase; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.test.SimpleTestResult; + +public class Argon2Test + extends TestCase +{ + public void testArgon2() + { + if (Security.getProvider("BC") == null) + { + Security.addProvider(new BouncyCastleProvider()); + } + + Argon2S2KTest test = new Argon2S2KTest(); + + SimpleTestResult result = (SimpleTestResult)test.perform(); + + if (!result.isSuccessful()) + { + fail(test.getClass().getName() + " " + result.toString()); + } + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/ArmorCRCTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/ArmorCRCTest.java new file mode 100644 index 0000000000..a2aca2ad3c --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/ArmorCRCTest.java @@ -0,0 +1,101 @@ +package org.bouncycastle.openpgp.test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.bouncycastle.bcpg.ArmoredInputStream; +import org.bouncycastle.bcpg.ArmoredOutputStream; +import org.bouncycastle.openpgp.PGPLiteralData; +import org.bouncycastle.openpgp.PGPLiteralDataGenerator; +import org.bouncycastle.openpgp.PGPObjectFactory; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.io.Streams; +import org.bouncycastle.util.test.SimpleTest; + +public class ArmorCRCTest + extends SimpleTest +{ + + private static final String WITHOUT_CRC = "" + + "-----BEGIN PGP MESSAGE-----\n" + + "\n" + + "yxR0AAAAAABIZWxsbywgV29ybGQhCg==\n" + + "-----END PGP MESSAGE-----\n"; + private static final String FAULTY_CRC = "" + + "-----BEGIN PGP MESSAGE-----\n" + + "\n" + + "yxR0AAAAAABIZWxsbywgV29ybGQhCg==\n" + + "=TRA9\n" + + "-----END PGP MESSAGE-----"; + + @Override + public String getName() + { + return "ArmorCRCTest"; + } + + @Override + public void performTest() + throws Exception + { + generateArmorWithoutCRCSum(); + consumeArmorWithoutCRC(); + } + + private void generateArmorWithoutCRCSum() + throws IOException + { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ArmoredOutputStream armorOut = ArmoredOutputStream.builder() + .enableCRC(false) + .build(bOut); + + PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator(); + OutputStream litOut = litGen.open(armorOut, PGPLiteralDataGenerator.TEXT, + "", PGPLiteralData.NOW, new byte[512]); + litOut.write(Strings.toByteArray("Hello, World!\n")); + litOut.close(); + armorOut.close(); + + isEquals(WITHOUT_CRC, Strings.fromByteArray(bOut.toByteArray())); + } + + + private void consumeArmorWithoutCRC() + throws IOException + { + consumeSuccessfullyIgnoringCRCSum(WITHOUT_CRC); + consumeSuccessfullyIgnoringCRCSum(FAULTY_CRC); + } + + private void consumeSuccessfullyIgnoringCRCSum(String armor) + throws IOException + { + ByteArrayInputStream bIn = new ByteArrayInputStream(Strings.toByteArray(armor)); + ArmoredInputStream armorIn = ArmoredInputStream.builder() + .setParseForHeaders(true) + .setIgnoreCRC(true) + .setDetectMissingCRC(false) + .build(bIn); + + + PGPObjectFactory objectFactory = new BcPGPObjectFactory(armorIn); + PGPLiteralData literalData = (PGPLiteralData)objectFactory.nextObject(); + InputStream litIn = literalData.getDataStream(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + Streams.pipeAll(litIn, bOut); + litIn.close(); + armorIn.close(); + + isEquals("Hello, World!\n", bOut.toString()); + } + + public static void main(String[] args) + { + runTest(new ArmorCRCTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/ArmoredOutputStreamTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/ArmoredOutputStreamTest.java new file mode 100644 index 0000000000..1436460c7a --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/ArmoredOutputStreamTest.java @@ -0,0 +1,213 @@ +package org.bouncycastle.openpgp.test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.Hashtable; + +import org.bouncycastle.bcpg.ArmoredInputStream; +import org.bouncycastle.bcpg.ArmoredOutputStream; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.test.SimpleTest; + +public class ArmoredOutputStreamTest + extends SimpleTest +{ + byte[] publicKey = Base64.decode( + "mQELBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+" + + "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1" + + "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO" + + "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7" + + "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4" + + "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp" + + "tBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2BBMBAgAgBQJEIdvsAhsDBgsJCAcD" + + "AgQVAggDBBYCAwECHgECF4AACgkQ4M/Ier3f9xagdAf/fbKWBjLQM8xR7JkR" + + "P4ri8YKOQPhK+VrddGUD59/wzVnvaGyl9MZE7TXFUeniQq5iXKnm22EQbYch" + + "v2Jcxyt2H9yptpzyh4tP6tEHl1C887p2J4qe7F2ATua9CzVGwXQSUbKtj2fg" + + "UZP5SsNp25guhPiZdtkf2sHMeiotmykFErzqGMrvOAUThrO63GiYsRk4hF6r" + + "cQ01d+EUVpY/sBcCxgNyOiB7a84sDtrxnX5BTEZDTEj8LvuEyEV3TMUuAjx1" + + "7Eyd+9JtKzwV4v3hlTaWOvGro9nPS7YaPuG+RtufzXCUJPbPfTjTvtGOqvEz" + + "oztls8tuWA0OGHba9XfX9rfgorACAAM="); + + static final byte[] expected = Strings.toByteArray( + "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + + "\n" + + "mQELBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+r1g7\n" + + "DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1tzjn18fT\n" + + "/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO42kgeDGd5cXf\n" + + "s4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7Jm4/LSR1uC/wDT0I\n" + + "JJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4Gvo6IbvyTgIskfpSkCnQ\n" + + "tORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYptBNnZ2dnZ2dnZyA8Z2dnQGdn\n" + + "Z2c+iQE2BBMBAgAgBQJEIdvsAhsDBgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQ\n" + + "4M/Ier3f9xagdAf/fbKWBjLQM8xR7JkRP4ri8YKOQPhK+VrddGUD59/wzVnvaGyl\n" + + "9MZE7TXFUeniQq5iXKnm22EQbYchv2Jcxyt2H9yptpzyh4tP6tEHl1C887p2J4qe\n" + + "7F2ATua9CzVGwXQSUbKtj2fgUZP5SsNp25guhPiZdtkf2sHMeiotmykFErzqGMrv\n" + + "OAUThrO63GiYsRk4hF6rcQ01d+EUVpY/sBcCxgNyOiB7a84sDtrxnX5BTEZDTEj8\n" + + "LvuEyEV3TMUuAjx17Eyd+9JtKzwV4v3hlTaWOvGro9nPS7YaPuG+RtufzXCUJPbP\n" + + "fTjTvtGOqvEzoztls8tuWA0OGHba9XfX9rfgorACAAM=\n" + + "=RmFE\n" + + "-----END PGP PUBLIC KEY BLOCK-----\n"); + + public String getName() + { + return "ArmoredOutputStream"; + } + + public void performTest() + throws Exception + { + testBuilder(); + testExceptions(); + PGPPublicKeyRing keyRing = new PGPPublicKeyRing(publicKey, new JcaKeyFingerprintCalculator()); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + ArmoredOutputStream aOut = ArmoredOutputStream.builder().build(bOut); + + aOut.write(keyRing.getEncoded()); + aOut.close(); + + byte[] res = bOut.toByteArray(); + StringBuffer sb = new StringBuffer(); + byte lastC = 0; + for (int i = 0; i != res.length; i++) + { + if (lastC == '\r') + { + sb.append('\n'); + if (res[i] != '\n') + { + sb.append((char)res[i]); + } + } + else if (res[i] != '\r') + { + sb.append((char)res[i]); + } + lastC = res[i]; + } + + String result = sb.toString(); + + isTrue(Arrays.areEqual(expected, Strings.toByteArray(result))); + } + + public void testBuilder() + throws Exception + { + PGPPublicKeyRing keyRing = new PGPPublicKeyRing(publicKey, new JcaKeyFingerprintCalculator()); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + ArmoredOutputStream aOut = ArmoredOutputStream.builder() + .setVersion("GnuPG v1.4.2.1 (GNU/Linux)") + .setVersion("") + .setComment("Test comment") + .setMessageId("Test ID") + .setCharset("UTF-8") + .addComment("Test comment2") + .build(bOut); + + aOut.write(keyRing.getEncoded()); + + aOut.close(); + + byte[] res = bOut.toByteArray(); +// StringBuffer sb = new StringBuffer(); +// byte lastC = 0; +// for (int i = 0; i != res.length; i++) +// { +// if (lastC == '\r') +// { +// sb.append('\n'); +// if (res[i] != '\n') +// { +// sb.append((char)res[i]); +// } +// } +// else if (res[i] != '\r') +// { +// sb.append((char)res[i]); +// } +// lastC = res[i]; +// } +// +// String result = sb.toString(); +// System.out.println(result); + + ArmoredInputStream inputStream = new ArmoredInputStream(new ByteArrayInputStream(res)); + isEquals(inputStream.getArmorHeaderLine(), "-----BEGIN PGP PUBLIC KEY BLOCK-----"); + isEquals(4, inputStream.getArmorHeaders().length); + + bOut = new ByteArrayOutputStream(); + aOut = ArmoredOutputStream.builder() + .build(bOut); + + aOut.write(keyRing.getEncoded()); + + aOut.close(); + + res = bOut.toByteArray(); + inputStream = new ArmoredInputStream(new ByteArrayInputStream(res)); + + isEquals(inputStream.getArmorHeaderLine(), "-----BEGIN PGP PUBLIC KEY BLOCK-----"); + isTrue(inputStream.getArmorHeaders() == null); + + Hashtable headers = new Hashtable(); + headers.put("Version", "GnuPG v1.4.2.1 (GNU/Linux)"); + bOut = new ByteArrayOutputStream(); + aOut = new ArmoredOutputStream(bOut, headers); + int[] hashAlgorithms = new int[]{HashAlgorithmTags.MD5, + HashAlgorithmTags.RIPEMD160, + HashAlgorithmTags.MD2, + HashAlgorithmTags.SHA384, + HashAlgorithmTags.SHA512, + HashAlgorithmTags.SHA224, + HashAlgorithmTags.SHA3_256, + HashAlgorithmTags.SHA3_256_OLD, + HashAlgorithmTags.SHA3_384, + HashAlgorithmTags.SHA3_512, + HashAlgorithmTags.SHA3_512_OLD, + HashAlgorithmTags.SHA3_224 + }; + aOut.beginClearText(hashAlgorithms); + aOut.write(keyRing.getEncoded()); + aOut.close(); + res = bOut.toByteArray(); + inputStream = new ArmoredInputStream(new ByteArrayInputStream(res)); + isEquals(hashAlgorithms.length, inputStream.getArmorHeaders().length); + } + + public void testExceptions() + { + testException("unknown hash algorithm tag in beginClearText: ", "IOException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + ArmoredOutputStream aOut = new ArmoredOutputStream(new ByteArrayOutputStream()); + aOut.beginClearText(HashAlgorithmTags.SM3); + } + }); + + testException("Armor header value for key ", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + ArmoredOutputStream aOut = ArmoredOutputStream.builder() + .setVersion("Text\nText") + .build(new ByteArrayOutputStream()); + } + }); + } + + public static void main(String[] args) + { + runTest(new ArmoredOutputStreamTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/BcImplProviderTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/BcImplProviderTest.java new file mode 100644 index 0000000000..96851850b5 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/BcImplProviderTest.java @@ -0,0 +1,709 @@ +package org.bouncycastle.openpgp.test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.math.BigInteger; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.SecureRandom; +import java.security.Security; +import java.security.interfaces.DSAPrivateKey; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.spec.ECGenParameterSpec; +import java.util.Date; +import java.util.Iterator; + +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.bcpg.BCPGKey; +import org.bouncycastle.bcpg.DSASecretBCPGKey; +import org.bouncycastle.bcpg.ECSecretBCPGKey; +import org.bouncycastle.bcpg.Ed25519SecretBCPGKey; +import org.bouncycastle.bcpg.Ed448SecretBCPGKey; +import org.bouncycastle.bcpg.EdSecretBCPGKey; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.RSASecretBCPGKey; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.CryptoException; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.Signer; +import org.bouncycastle.crypto.digests.MD2Digest; +import org.bouncycastle.crypto.digests.MD5Digest; +import org.bouncycastle.crypto.digests.RIPEMD160Digest; +import org.bouncycastle.crypto.digests.SHA1Digest; +import org.bouncycastle.crypto.digests.SHA224Digest; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.digests.SHA384Digest; +import org.bouncycastle.crypto.digests.SHA3Digest; +import org.bouncycastle.crypto.digests.SHA512Digest; +import org.bouncycastle.crypto.digests.TigerDigest; +import org.bouncycastle.crypto.generators.X25519KeyPairGenerator; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.crypto.params.X25519KeyGenerationParameters; +import org.bouncycastle.crypto.signers.DSADigestSigner; +import org.bouncycastle.crypto.signers.DSASigner; +import org.bouncycastle.crypto.signers.ECDSASigner; +import org.bouncycastle.crypto.signers.Ed25519Signer; +import org.bouncycastle.crypto.signers.Ed448Signer; +import org.bouncycastle.crypto.signers.RSADigestSigner; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.bouncycastle.jce.spec.ElGamalParameterSpec; +import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; +import org.bouncycastle.openpgp.PGPEncryptedDataList; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPKdfParameters; +import org.bouncycastle.openpgp.PGPKeyPair; +import org.bouncycastle.openpgp.PGPKeyRingGenerator; +import org.bouncycastle.openpgp.PGPLiteralData; +import org.bouncycastle.openpgp.PGPLiteralDataGenerator; +import org.bouncycastle.openpgp.PGPPrivateKey; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; +import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.bouncycastle.openpgp.operator.PGPContentSigner; +import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.test.FixedSecureRandom; +import org.bouncycastle.util.test.SimpleTest; +import org.bouncycastle.util.test.UncloseableOutputStream; + +public class BcImplProviderTest + extends SimpleTest +{ + @Override + public String getName() + { + return "BcImplProviderTest"; + } + + @Override + public void performTest() + throws Exception + { + testBcImplProvider(); + } + + public void testBcImplProvider() + throws Exception + { + //createDigest + final BcPGPDigestCalculatorProvider provider = new BcPGPDigestCalculatorProvider(); + testCreateDigest(provider, HashAlgorithmTags.SHA1, new SHA1Digest()); + testCreateDigest(provider, HashAlgorithmTags.SHA224, new SHA224Digest()); + testCreateDigest(provider, HashAlgorithmTags.SHA256, new SHA256Digest()); + testCreateDigest(provider, HashAlgorithmTags.SHA384, new SHA384Digest()); + testCreateDigest(provider, HashAlgorithmTags.SHA512, new SHA512Digest()); + testCreateDigest(provider, HashAlgorithmTags.SHA3_224, new SHA3Digest(224)); + testCreateDigest(provider, HashAlgorithmTags.SHA3_256, new SHA3Digest(256)); + testCreateDigest(provider, HashAlgorithmTags.SHA3_384, new SHA3Digest(384)); + testCreateDigest(provider, HashAlgorithmTags.SHA3_512, new SHA3Digest(512)); + testCreateDigest(provider, HashAlgorithmTags.MD2, new MD2Digest()); + testCreateDigest(provider, HashAlgorithmTags.MD5, new MD5Digest()); + testCreateDigest(provider, HashAlgorithmTags.RIPEMD160, new RIPEMD160Digest()); + testCreateDigest(provider, HashAlgorithmTags.TIGER_192, new TigerDigest()); + testException("cannot recognise digest", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + provider.get(HashAlgorithmTags.SM3); + } + }); + + //createSigner + testCreateSigner(PublicKeyAlgorithmTags.EDDSA_LEGACY, new EdDsaSigner(new Ed448Signer(new byte[0]), new SHA1Digest()), "EdDSA", + new PrivateKeyOperation() + { + @Override + public BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws IOException + { + PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(privKey.getEncoded()); + return new EdSecretBCPGKey( + new BigInteger(1, ASN1OctetString.getInstance(pInfo.parsePrivateKey()).getOctets())); + } + }, + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws InvalidAlgorithmParameterException + { + kpGen.initialize(new ECNamedCurveGenParameterSpec("Ed448")); + } + }); + + testCreateSigner(PublicKeyAlgorithmTags.DSA, new DSADigestSigner(new DSASigner(), new SHA1Digest()), "DSA", + new PrivateKeyOperation() + { + @Override + public BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws IOException + { + return new DSASecretBCPGKey(((DSAPrivateKey)privKey).getX()); + } + }, + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws InvalidAlgorithmParameterException + { + kpGen.initialize(1024); + } + }); + testCreateSigner(PublicKeyAlgorithmTags.RSA_GENERAL, new RSADigestSigner(new SHA1Digest()), "RSA", + new PrivateKeyOperation() + { + @Override + public BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws IOException + { + RSAPrivateCrtKey rsK = (RSAPrivateCrtKey)privKey; + return new RSASecretBCPGKey(rsK.getPrivateExponent(), rsK.getPrimeP(), rsK.getPrimeQ()); + } + }, + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws InvalidAlgorithmParameterException + { + kpGen.initialize(1024); + } + }); + testCreateSigner(PublicKeyAlgorithmTags.ECDSA, new DSADigestSigner(new ECDSASigner(), new SHA1Digest()), "ECDSA", + new PrivateKeyOperation() + { + @Override + public BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws IOException + { + return new ECSecretBCPGKey(((ECPrivateKey)privKey).getS()); + } + }, + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws InvalidAlgorithmParameterException + { + kpGen.initialize(new ECGenParameterSpec("P-256")); + } + }); + testCreateSigner(PublicKeyAlgorithmTags.ECDSA, new DSADigestSigner(new ECDSASigner(), new SHA1Digest()), "ECDSA", + new PrivateKeyOperation() + { + @Override + public BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws IOException + { + return new ECSecretBCPGKey(((ECPrivateKey)privKey).getS()); + } + }, + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws InvalidAlgorithmParameterException + { + kpGen.initialize(new ECGenParameterSpec("P-384")); + } + }); + testCreateSigner(PublicKeyAlgorithmTags.ECDSA, new DSADigestSigner(new ECDSASigner(), new SHA1Digest()), "ECDSA", + new PrivateKeyOperation() + { + @Override + public BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws IOException + { + return new ECSecretBCPGKey(((ECPrivateKey)privKey).getS()); + } + }, + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws InvalidAlgorithmParameterException + { + kpGen.initialize(new ECGenParameterSpec("P-521")); + } + }); + testCreateSigner(PublicKeyAlgorithmTags.ECDSA, new DSADigestSigner(new ECDSASigner(), new SHA1Digest()), "ECDSA", + new PrivateKeyOperation() + { + @Override + public BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws IOException + { + return new ECSecretBCPGKey(((ECPrivateKey)privKey).getS()); + } + }, + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws InvalidAlgorithmParameterException + { + kpGen.initialize(new ECGenParameterSpec("brainpoolP256r1")); + } + }); + testCreateSigner(PublicKeyAlgorithmTags.ECDSA, new DSADigestSigner(new ECDSASigner(), new SHA1Digest()), "ECDSA", + new PrivateKeyOperation() + { + @Override + public BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws IOException + { + return new ECSecretBCPGKey(((ECPrivateKey)privKey).getS()); + } + }, + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws InvalidAlgorithmParameterException + { + kpGen.initialize(new ECGenParameterSpec("brainpoolP384r1")); + } + }); + testCreateSigner(PublicKeyAlgorithmTags.ECDSA, new DSADigestSigner(new ECDSASigner(), new SHA1Digest()), "ECDSA", + new PrivateKeyOperation() + { + @Override + public BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws IOException + { + return new ECSecretBCPGKey(((ECPrivateKey)privKey).getS()); + } + }, + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws InvalidAlgorithmParameterException + { + kpGen.initialize(new ECGenParameterSpec("brainpoolP512r1")); + } + }); + + testCreateSigner(PublicKeyAlgorithmTags.EDDSA_LEGACY, new EdDsaSigner(new Ed25519Signer(), new SHA1Digest()), "EdDSA", + new PrivateKeyOperation() + { + @Override + public BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws IOException + { + PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(privKey.getEncoded()); + return new EdSecretBCPGKey( + new BigInteger(1, ASN1OctetString.getInstance(pInfo.parsePrivateKey()).getOctets())); + } + }, + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws InvalidAlgorithmParameterException + { + kpGen.initialize(new ECNamedCurveGenParameterSpec("Ed25519")); + } + }); + + testCreateSigner(PublicKeyAlgorithmTags.Ed448, new EdDsaSigner(new Ed448Signer(new byte[0]), new SHA1Digest()), "EdDSA", + new PrivateKeyOperation() + { + @Override + public BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws IOException + { + PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(privKey.getEncoded()); + return new Ed448SecretBCPGKey(ASN1OctetString.getInstance(pInfo.parsePrivateKey()).getOctets()); + } + }, + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws InvalidAlgorithmParameterException + { + kpGen.initialize(new ECNamedCurveGenParameterSpec("Ed448")); + } + }); + testCreateSigner(PublicKeyAlgorithmTags.Ed25519, new EdDsaSigner(new Ed25519Signer(), new SHA1Digest()), "EdDSA", + new PrivateKeyOperation() + { + @Override + public BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws IOException + { + PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance(privKey.getEncoded()); + return new Ed25519SecretBCPGKey(ASN1OctetString.getInstance(pInfo.parsePrivateKey()).getOctets()); + } + }, + new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator kpGen) + throws InvalidAlgorithmParameterException + { + kpGen.initialize(new ECNamedCurveGenParameterSpec("Ed25519")); + } + }); + testException("cannot recognise keyAlgorithm:", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new BcPGPContentVerifierBuilderProvider().get(PublicKeyAlgorithmTags.X448, HashAlgorithmTags.SHA1) + .build(((PGPPublicKeyRing)new JcaPGPObjectFactory(BcPGPDSAElGamalTest.testPubKeyRing).nextObject()).getPublicKey()); + } + }); + + +// testException("cannot recognise keyAlgorithm: ", "PGPException", ()-> +// { +// KeyPairGenerator kpGen = KeyPairGenerator.getInstance("X448", "BC"); +// KeyPair kp = kpGen.generateKeyPair(); +// +// JcaPGPKeyConverter converter = new JcaPGPKeyConverter().setProvider(new BouncyCastleProvider()); +// PGPPublicKey pubKey = converter.getPGPPublicKey(PublicKeyAlgorithmTags.X448, kp.getPublic(), new Date()); +// PGPPrivateKey privKey = new PGPPrivateKey(pubKey.getKeyID(), pubKey.getPublicKeyPacket(), operation.getPrivateBCPGKey(pubKey, kp.getPrivate())); +// }); + // createBlockCipher + createBlockCipherTest(SymmetricKeyAlgorithmTags.AES_128); + createBlockCipherTest(SymmetricKeyAlgorithmTags.AES_192); + createBlockCipherTest(SymmetricKeyAlgorithmTags.AES_256); + createBlockCipherTest(SymmetricKeyAlgorithmTags.CAMELLIA_128); + createBlockCipherTest(SymmetricKeyAlgorithmTags.CAMELLIA_192); + createBlockCipherTest(SymmetricKeyAlgorithmTags.CAMELLIA_256); + createBlockCipherTest(SymmetricKeyAlgorithmTags.BLOWFISH); + createBlockCipherTest(SymmetricKeyAlgorithmTags.CAST5); + createBlockCipherTest(SymmetricKeyAlgorithmTags.DES); + createBlockCipherTest(SymmetricKeyAlgorithmTags.IDEA); + createBlockCipherTest(SymmetricKeyAlgorithmTags.TWOFISH); + createBlockCipherTest(SymmetricKeyAlgorithmTags.TRIPLE_DES); + testException("cannot create cipher", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + createBlockCipherTest(SymmetricKeyAlgorithmTags.SAFER); + } + }); + + final PBESecretKeyDecryptor decryptor = new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(BcPGPDSAElGamalTest.pass); + testException("cannot recognise cipher", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + decryptor.recoverKeyData(SymmetricKeyAlgorithmTags.NULL, new byte[32], new byte[12], new byte[16], 0, 16); + } + }); + + createWrapperTest(SymmetricKeyAlgorithmTags.AES_128); + createWrapperTest(SymmetricKeyAlgorithmTags.AES_192); + createWrapperTest(SymmetricKeyAlgorithmTags.AES_256); + createWrapperTest(SymmetricKeyAlgorithmTags.CAMELLIA_128); + createWrapperTest(SymmetricKeyAlgorithmTags.CAMELLIA_192); + createWrapperTest(SymmetricKeyAlgorithmTags.CAMELLIA_256); + //testException("unknown wrap algorithm: ", "PGPException", ()-> createWrapperTest(SymmetricKeyAlgorithmTags.BLOWFISH)); + } + + private void testCreateDigest(BcPGPDigestCalculatorProvider provider, int algorithm, Digest digest) + throws PGPException + { + PGPDigestCalculator calculator = provider.get(algorithm); + isEquals(calculator.getAlgorithm(), algorithm); + byte[] d = new byte[digest.getDigestSize()]; + digest.doFinal(d, 0); + isTrue(Arrays.areEqual(d, calculator.getDigest())); + calculator.reset(); + } + + @FunctionalInterface + interface PrivateKeyOperation + { + BCPGKey getPrivateBCPGKey(PGPPublicKey pub, PrivateKey privKey) + throws IOException; + } + + @FunctionalInterface + interface KeyPairGeneratorOperation + { + void initialize(KeyPairGenerator kpGen) + throws InvalidAlgorithmParameterException; + } + + + private void testCreateSigner(int keyAlgorithm, Signer signer, String name, PrivateKeyOperation operation, KeyPairGeneratorOperation kpgOperation) + throws Exception + { + KeyPairGenerator kpGen = KeyPairGenerator.getInstance(name, "BC"); + kpgOperation.initialize(kpGen); + KeyPair kp = kpGen.generateKeyPair(); + + JcaPGPKeyConverter converter = new JcaPGPKeyConverter().setProvider(new BouncyCastleProvider()); + PGPPublicKey pubKey = converter.getPGPPublicKey(keyAlgorithm, kp.getPublic(), new Date()); + PGPPrivateKey privKey = new PGPPrivateKey(pubKey.getKeyID(), pubKey.getPublicKeyPacket(), operation.getPrivateBCPGKey(pubKey, kp.getPrivate())); + + byte[] source = new byte[1024]; + SecureRandom r1 = new SecureRandom(); + r1.nextBytes(source); + SecureRandom random = new FixedSecureRandom(source); + + final BcPGPContentSignerBuilder builder = new BcPGPContentSignerBuilder(keyAlgorithm, HashAlgorithmTags.SHA1).setSecureRandom(random); + PGPContentSigner contentSigner = builder.build(PGPSignature.BINARY_DOCUMENT, privKey); + + BcPGPKeyConverter keyConverter = new BcPGPKeyConverter(); + AsymmetricKeyParameter privKeyParam = keyConverter.getPrivateKey(privKey); + signer.init(true, new ParametersWithRandom(privKeyParam, new FixedSecureRandom(source))); + isTrue(contentSigner.getKeyAlgorithm() == keyAlgorithm); + isTrue(areEqual(contentSigner.getSignature(), signer.generateSignature())); + } + + public void createBlockCipherTest(int tag) + throws Exception + { + char[] passPhrase = "hello".toCharArray(); + KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); + + dsaKpg.initialize(512); + + // + // this takes a while as the key generator has to generate some DSA params + // before it generates the key. + // + KeyPair dsaKp = dsaKpg.generateKeyPair(); + + KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); + BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); + BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); + + ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); + + elgKpg.initialize(elParams); + + // + // this is quicker because we are using pregenerated parameters. + // + KeyPair elgKp = elgKpg.generateKeyPair(); + PGPKeyPair dsaKeyPair = new JcaPGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); + PGPKeyPair elgKeyPair = new JcaPGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); + + PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1); + PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, + "test", sha1Calc, null, null, new JcaPGPContentSignerBuilder(PGPPublicKey.DSA, HashAlgorithmTags.SHA1), + new JcePBESecretKeyEncryptorBuilder(tag).setProvider("BC").build(passPhrase)); + + keyRingGen.addSubKey(elgKeyPair); + + PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); + + keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); + + PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); + sha1Calc.reset(); + PGPPublicKey vKey = null; + PGPPublicKey sKey = null; + + Iterator it = pubRing.getPublicKeys(); + while (it.hasNext()) + { + PGPPublicKey pk = (PGPPublicKey)it.next(); + if (pk.isMasterKey()) + { + vKey = pk; + } + else + { + sKey = pk; + } + } + + Iterator sIt = sKey.getSignatures(); + while (sIt.hasNext()) + { + PGPSignature sig = (PGPSignature)sIt.next(); + + if (sig.getKeyID() == vKey.getKeyID() + && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) + { + sig.init(new BcPGPContentVerifierBuilderProvider(), vKey); + + if (!sig.verifyCertification(vKey, sKey)) + { + fail("failed to verify sub-key signature."); + } + } + } + } + + private void encryptDecryptBcTest(PGPPublicKey pubKey, PGPPrivateKey secKey) + throws Exception + { + byte[] text = {(byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n'}; + + PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(); + ByteArrayOutputStream ldOut = new ByteArrayOutputStream(); + OutputStream pOut = lData.open(ldOut, PGPLiteralDataGenerator.UTF8, PGPLiteralData.CONSOLE, text.length, new Date()); + + pOut.write(text); + + pOut.close(); + + byte[] data = ldOut.toByteArray(); + + ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); + + PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(new SecureRandom())); + + cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(pubKey)); + + OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), data.length); + + cOut.write(data); + + cOut.close(); + + BcPGPObjectFactory pgpF = new BcPGPObjectFactory(cbOut.toByteArray()); + + PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); + + PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); + + InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(secKey)); + + pgpF = new BcPGPObjectFactory(clear); + + PGPLiteralData ld = (PGPLiteralData)pgpF.nextObject(); + + clear = ld.getInputStream(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + int ch; + while ((ch = clear.read()) >= 0) + { + bOut.write(ch); + } + + byte[] out = bOut.toByteArray(); + + if (!areEqual(out, text)) + { + fail("wrong plain text in generated packet"); + } + } + + private void createWrapperTest(int tag) + throws Exception + { + SecureRandom random = CryptoServicesRegistrar.getSecureRandom(); + + X25519KeyPairGenerator gen = new X25519KeyPairGenerator(); + gen.init(new X25519KeyGenerationParameters(random)); + + PGPKeyPair dsaKeyPair = new BcPGPKeyPair(PGPPublicKey.ECDH, new PGPKdfParameters(8, tag), gen.generateKeyPair(), new Date()); + + encryptDecryptBcTest(dsaKeyPair.getPublicKey(), dsaKeyPair.getPrivateKey()); + } + + public static void main( + String[] args) + { + Security.addProvider(new BouncyCastleProvider()); + + runTest(new BcImplProviderTest()); + } + + private static class EdDsaSigner + implements Signer + { + private final Signer signer; + private final Digest digest; + private final byte[] digBuf; + + EdDsaSigner(Signer signer, Digest digest) + { + this.signer = signer; + this.digest = digest; + this.digBuf = new byte[digest.getDigestSize()]; + } + + public void init(boolean forSigning, CipherParameters param) + { + this.signer.init(forSigning, param); + this.digest.reset(); + } + + public void update(byte b) + { + this.digest.update(b); + } + + public void update(byte[] in, int off, int len) + { + this.digest.update(in, off, len); + } + + public byte[] generateSignature() + throws CryptoException, DataLengthException + { + digest.doFinal(digBuf, 0); + + signer.update(digBuf, 0, digBuf.length); + + return signer.generateSignature(); + } + + public boolean verifySignature(byte[] signature) + { + digest.doFinal(digBuf, 0); + + signer.update(digBuf, 0, digBuf.length); + + return signer.verifySignature(signature); + } + + public void reset() + { + Arrays.clear(digBuf); + signer.reset(); + digest.reset(); + } + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPDSAElGamalTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPDSAElGamalTest.java index 12e690d6f4..63ae3de228 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPDSAElGamalTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPDSAElGamalTest.java @@ -16,10 +16,12 @@ import javax.crypto.spec.DHParameterSpec; +import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.crypto.AsymmetricBlockCipher; +import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.ElGamalEngine; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; @@ -55,6 +57,7 @@ import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.UncloseableOutputStream; @@ -63,82 +66,82 @@ public class BcPGPDSAElGamalTest extends SimpleTest { - byte[] testPubKeyRing = + static byte[] testPubKeyRing = Base64.decode( "mQGiBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" - + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" - + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" - + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" - + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" - + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" - + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" - + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" - + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" - + "JxgEd0MOcGJO+1PFFZWGzLQ3RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSBv" - + "bmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQJAEfI2BAsH" - + "AwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgnkDdnAKC/CfLWikSBdbngY6OK" - + "5UN3+o7q1ACcDRqjT3yjBU3WmRUNlxBg3tSuljmwAgAAuQENBEAR8jgQBAC2" - + "kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVjei/3yVfT/fuCVtGHOmYLEBqH" - + "bn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya43RtcubqMc7eKw4k0JnnoYgB" - + "ocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhFBYfaBmGU75cQgwADBQP/XxR2" - + "qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSqAi0zeAMdrRsBN7kyzYVVpWwN" - + "5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxkbipnwh2RR4xCXFDhJrJFQUm+" - + "4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXsNi1tRbTmRhqIRgQYEQIABgUC" - + "QBHyOAAKCRAOtk6iUOgnkBStAJoCZBVM61B1LG2xip294MZecMtCwQCbBbsk" - + "JVCXP0/Szm05GB+WN+MOCT2wAgAA"); - - byte[] testPrivKeyRing = + + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + + "JxgEd0MOcGJO+1PFFZWGzLQ3RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSBv" + + "bmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQJAEfI2BAsH" + + "AwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgnkDdnAKC/CfLWikSBdbngY6OK" + + "5UN3+o7q1ACcDRqjT3yjBU3WmRUNlxBg3tSuljmwAgAAuQENBEAR8jgQBAC2" + + "kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVjei/3yVfT/fuCVtGHOmYLEBqH" + + "bn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya43RtcubqMc7eKw4k0JnnoYgB" + + "ocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhFBYfaBmGU75cQgwADBQP/XxR2" + + "qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSqAi0zeAMdrRsBN7kyzYVVpWwN" + + "5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxkbipnwh2RR4xCXFDhJrJFQUm+" + + "4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXsNi1tRbTmRhqIRgQYEQIABgUC" + + "QBHyOAAKCRAOtk6iUOgnkBStAJoCZBVM61B1LG2xip294MZecMtCwQCbBbsk" + + "JVCXP0/Szm05GB+WN+MOCT2wAgAA"); + + static byte[] testPrivKeyRing = Base64.decode( "lQHhBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" - + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" - + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" - + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" - + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" - + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" - + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" - + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" - + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" - + "JxgEd0MOcGJO+1PFFZWGzP4DAwLeUcsVxIC2s2Bb9ab2XD860TQ2BI2rMD/r" - + "7/psx9WQ+Vz/aFAT3rXkEJ97nFeqEACgKmUCAEk9939EwLQ3RXJpYyBILiBF" - + "Y2hpZG5hICh0ZXN0IGtleSBvbmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3Jn" - + "PohZBBMRAgAZBQJAEfI2BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgn" - + "kDdnAJ9Ala3OcwEV1DbK906CheYWo4zIQwCfUqUOLMp/zj6QAk02bbJAhV1r" - + "sAewAgAAnQFYBEAR8jgQBAC2kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVj" - + "ei/3yVfT/fuCVtGHOmYLEBqHbn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya" - + "43RtcubqMc7eKw4k0JnnoYgBocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhF" - + "BYfaBmGU75cQgwADBQP/XxR2qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSq" - + "Ai0zeAMdrRsBN7kyzYVVpWwN5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxk" - + "bipnwh2RR4xCXFDhJrJFQUm+4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXs" - + "Ni1tRbTmRhr+AwMC3lHLFcSAtrNg/EiWFLAnKNXH27zjwuhje8u2r+9iMTYs" - + "GjbRxaxRY0GKRhttCwqe2BC0lHhzifdlEcc9yjIjuKfepG2fnnSIRgQYEQIA" - + "BgUCQBHyOAAKCRAOtk6iUOgnkBStAJ9HFejVtVJ/A9LM/mDPe0ExhEXt/QCg" - + "m/KM7hJ/JrfnLQl7IaZsdg1F6vCwAgAA"); + + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + + "JxgEd0MOcGJO+1PFFZWGzP4DAwLeUcsVxIC2s2Bb9ab2XD860TQ2BI2rMD/r" + + "7/psx9WQ+Vz/aFAT3rXkEJ97nFeqEACgKmUCAEk9939EwLQ3RXJpYyBILiBF" + + "Y2hpZG5hICh0ZXN0IGtleSBvbmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3Jn" + + "PohZBBMRAgAZBQJAEfI2BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgn" + + "kDdnAJ9Ala3OcwEV1DbK906CheYWo4zIQwCfUqUOLMp/zj6QAk02bbJAhV1r" + + "sAewAgAAnQFYBEAR8jgQBAC2kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVj" + + "ei/3yVfT/fuCVtGHOmYLEBqHbn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya" + + "43RtcubqMc7eKw4k0JnnoYgBocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhF" + + "BYfaBmGU75cQgwADBQP/XxR2qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSq" + + "Ai0zeAMdrRsBN7kyzYVVpWwN5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxk" + + "bipnwh2RR4xCXFDhJrJFQUm+4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXs" + + "Ni1tRbTmRhr+AwMC3lHLFcSAtrNg/EiWFLAnKNXH27zjwuhje8u2r+9iMTYs" + + "GjbRxaxRY0GKRhttCwqe2BC0lHhzifdlEcc9yjIjuKfepG2fnnSIRgQYEQIA" + + "BgUCQBHyOAAKCRAOtk6iUOgnkBStAJ9HFejVtVJ/A9LM/mDPe0ExhEXt/QCg" + + "m/KM7hJ/JrfnLQl7IaZsdg1F6vCwAgAA"); byte[] encMessage = Base64.decode( "hQEOAynbo4lhNjcHEAP/dgCkMtPB6mIgjFvNiotjaoh4sAXf4vFNkSeehQ2c" - + "r+IMt9CgIYodJI3FoJXxOuTcwesqTp5hRzgUBJS0adLDJwcNubFMy0M2tp5o" - + "KTWpXulIiqyO6f5jI/oEDHPzFoYgBmR4x72l/YpMy8UoYGtNxNvR7LVOfqJv" - + "uDY/71KMtPQEAIadOWpf1P5Td+61Zqn2VH2UV7H8eI6hGa6Lsy4sb9iZNE7f" - + "c+spGJlgkiOt8TrQoq3iOK9UN9nHZLiCSIEGCzsEn3uNuorD++Qs065ij+Oy" - + "36TKeuJ+38CfT7u47dEshHCPqWhBKEYrxZWHUJU/izw2Q1Yxd2XRxN+nafTL" - + "X1fQ0lABQUASa18s0BkkEERIdcKQXVLEswWcGqWNv1ZghC7xO2VDBX4HrPjp" - + "drjL63p2UHzJ7/4gPWGGtnqq1Xita/1mrImn7pzLThDWiT55vjw6Hw=="); + + "r+IMt9CgIYodJI3FoJXxOuTcwesqTp5hRzgUBJS0adLDJwcNubFMy0M2tp5o" + + "KTWpXulIiqyO6f5jI/oEDHPzFoYgBmR4x72l/YpMy8UoYGtNxNvR7LVOfqJv" + + "uDY/71KMtPQEAIadOWpf1P5Td+61Zqn2VH2UV7H8eI6hGa6Lsy4sb9iZNE7f" + + "c+spGJlgkiOt8TrQoq3iOK9UN9nHZLiCSIEGCzsEn3uNuorD++Qs065ij+Oy" + + "36TKeuJ+38CfT7u47dEshHCPqWhBKEYrxZWHUJU/izw2Q1Yxd2XRxN+nafTL" + + "X1fQ0lABQUASa18s0BkkEERIdcKQXVLEswWcGqWNv1ZghC7xO2VDBX4HrPjp" + + "drjL63p2UHzJ7/4gPWGGtnqq1Xita/1mrImn7pzLThDWiT55vjw6Hw=="); byte[] signedAndEncMessage = Base64.decode( "hQEOAynbo4lhNjcHEAP+K20MVhzdX57hf/cU8TH0prP0VePr9mmeBedzqqMn" - + "fp2p8Zb68zmcMlI/WiL5XMNLYRmCgEcXyWbKdP/XV9m9LDBe1CMAGrkCeGBy" - + "je69IQQ5LS9vDPyEMF4iAAv/EqACjqHkizdY/a/FRx/t2ioXYdEC2jA6kS9C" - + "McpsNz16DE8EAIk3uKn4bGo/+15TXkyFYzW5Cf71SfRoHNmU2zAI93zhjN+T" - + "B7mGJwWXzsMkIO6FkMU5TCSrwZS3DBWCIaJ6SYoaawE/C/2j9D7bX1Jv8kum" - + "4cq+eZM7z6JYs6xend+WAwittpUxbEiyC2AJb3fBSXPAbLqWd6J6xbZZ7GDK" - + "r2Ca0pwBxwGhbMDyi2zpHLzw95H7Ah2wMcGU6kMLB+hzBSZ6mSTGFehqFQE3" - + "2BnAj7MtnbghiefogacJ891jj8Y2ggJeKDuRz8j2iICaTOy+Y2rXnnJwfYzm" - + "BMWcd2h1C5+UeBJ9CrrLniCCI8s5u8z36Rno3sfhBnXdRmWSxExXtocbg1Ht" - + "dyiThf6TK3W29Yy/T6x45Ws5zOasaJdsFKM="); - char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; - + + "fp2p8Zb68zmcMlI/WiL5XMNLYRmCgEcXyWbKdP/XV9m9LDBe1CMAGrkCeGBy" + + "je69IQQ5LS9vDPyEMF4iAAv/EqACjqHkizdY/a/FRx/t2ioXYdEC2jA6kS9C" + + "McpsNz16DE8EAIk3uKn4bGo/+15TXkyFYzW5Cf71SfRoHNmU2zAI93zhjN+T" + + "B7mGJwWXzsMkIO6FkMU5TCSrwZS3DBWCIaJ6SYoaawE/C/2j9D7bX1Jv8kum" + + "4cq+eZM7z6JYs6xend+WAwittpUxbEiyC2AJb3fBSXPAbLqWd6J6xbZZ7GDK" + + "r2Ca0pwBxwGhbMDyi2zpHLzw95H7Ah2wMcGU6kMLB+hzBSZ6mSTGFehqFQE3" + + "2BnAj7MtnbghiefogacJ891jj8Y2ggJeKDuRz8j2iICaTOy+Y2rXnnJwfYzm" + + "BMWcd2h1C5+UeBJ9CrrLniCCI8s5u8z36Rno3sfhBnXdRmWSxExXtocbg1Ht" + + "dyiThf6TK3W29Yy/T6x45Ws5zOasaJdsFKM="); + static char[] pass = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'}; + public void performTest() throws Exception { @@ -149,11 +152,11 @@ public void performTest() // // Read the public key // - JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(testPubKeyRing); - - PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)pgpFact.nextObject(); + JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(testPubKeyRing); + + PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)pgpFact.nextObject(); - pubKey = pgpPub.getPublicKey(); + pubKey = pgpPub.getPublicKey(); if (pubKey.getBitStrength() != 1024) { @@ -163,17 +166,17 @@ public void performTest() // // Read the private key // - PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKeyRing, new BcKeyFingerprintCalculator()); - PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); - + PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKeyRing, new BcKeyFingerprintCalculator()); + PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); + // // signature generation // - String data = "hello world!"; - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); - PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.DSA, PGPUtil.SHA1)); - + String data = "hello world!"; + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.DSA, PGPUtil.SHA1)); + sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( @@ -185,7 +188,7 @@ public void performTest() sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); - + Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), @@ -215,21 +218,26 @@ public void performTest() PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new JcaPGPObjectFactory(c1.getDataStream()); - + PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); - - PGPOnePassSignature ops = p1.get(0); - + isTrue(!p1.isEmpty()); + isTrue(p1.size() == 1); + + PGPOnePassSignature ops = new PGPOnePassSignature(new BCPGInputStream(new ByteArrayInputStream(((PGPOnePassSignature)p1.iterator().next()).getEncoded()))); + isTrue(PGPSignature.BINARY_DOCUMENT == ops.getSignatureType()); + isTrue(ops.isContaining()); + PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); + isTrue(Arrays.areEqual(p2.getRawFileName(), p2.getFileName().getBytes())); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } - InputStream dIn = p2.getInputStream(); + InputStream dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey); - + while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); @@ -241,22 +249,22 @@ public void performTest() { fail("Failed generated signature check"); } - + // // test encryption // - + // // find a key suitable for encryption // - long pgpKeyID = 0; + long pgpKeyID = 0; AsymmetricKeyParameter pKey = null; BcPGPKeyConverter keyConverter = new BcPGPKeyConverter(); - Iterator it = pgpPub.getPublicKeys(); + Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { - PGPPublicKey pgpKey = (PGPPublicKey)it.next(); + PGPPublicKey pgpKey = (PGPPublicKey)it.next(); if (pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT || pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_GENERAL) @@ -267,28 +275,28 @@ public void performTest() { fail("failed - key strength reported incorrectly."); } - + // // verify the key // - + } } - + AsymmetricBlockCipher c = new PKCS1Encoding(new ElGamalEngine()); c.init(true, pKey); - - byte[] in = "hello world".getBytes(); - byte[] out = c.processBlock(in, 0, in.length); - + byte[] in = "hello world".getBytes(); + + byte[] out = c.processBlock(in, 0, in.length); + pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); - + c.init(false, keyConverter.getPrivateKey(pgpPrivKey)); - + out = c.processBlock(out, 0, out.length); - + if (!areEqual(in, out)) { fail("decryption failed."); @@ -297,33 +305,36 @@ public void performTest() // // encrypted message // - byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; - + byte[] text = {(byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n'}; + JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(encMessage); - PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); - - PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); + PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); + + isTrue(encList.isIntegrityProtected()); + isTrue(!encList.isEmpty()); + + PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); - + pgpFact = new JcaPGPObjectFactory(clear); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new JcaPGPObjectFactory(c1.getDataStream()); - - PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); - + + PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); + bOut = new ByteArrayOutputStream(); - + if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } - InputStream inLd = ld.getDataStream(); - + InputStream inLd = ld.getDataStream(); + while ((ch = inLd.read()) >= 0) { bOut.write(ch); @@ -333,44 +344,44 @@ public void performTest() { fail("wrong plain text in decrypted packet"); } - + // // signed and encrypted message // pgpF = new JcaPGPObjectFactory(signedAndEncMessage); encList = (PGPEncryptedDataList)pgpF.nextObject(); - + encP = (PGPPublicKeyEncryptedData)encList.get(0); clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); - + pgpFact = new JcaPGPObjectFactory(clear); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new JcaPGPObjectFactory(c1.getDataStream()); - + p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); - + ops = p1.get(0); - + ld = (PGPLiteralData)pgpFact.nextObject(); - + bOut = new ByteArrayOutputStream(); - + if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } inLd = ld.getDataStream(); - + // // note: we use the DSA public key here. // ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey()); - + while ((ch = inLd.read()) >= 0) { ops.update((byte)ch); @@ -383,22 +394,22 @@ public void performTest() { fail("Failed signature check"); } - + if (!areEqual(bOut.toByteArray(), text)) { fail("wrong plain text in decrypted packet"); } - + // // encrypt // - ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); - PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TRIPLE_DES).setSecureRandom(new SecureRandom())); - PGPPublicKey puK = sKey.getSecretKey(pgpKeyID).getPublicKey(); - - cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK)); - - OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); + ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); + PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TRIPLE_DES).setSecureRandom(new SecureRandom())); + PGPPublicKey puK = sKey.getSecretKey(pgpKeyID).getPublicKey(); + + cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK).setSecureRandom(CryptoServicesRegistrar.getSecureRandom())); + + OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); cOut.write(text); @@ -407,15 +418,15 @@ public void performTest() pgpF = new JcaPGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList)pgpF.nextObject(); - + encP = (PGPPublicKeyEncryptedData)encList.get(0); - + pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); - + bOut.reset(); - + while ((ch = clear.read()) >= 0) { bOut.write(ch); @@ -427,27 +438,26 @@ public void performTest() { fail("wrong plain text in generated packet"); } - + // // use of PGPKeyPair // BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); - KeyPairGenerator kpg = KeyPairGenerator.getInstance("ElGamal", "BC"); - - ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); - + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ElGamal", "BC"); + + ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); + kpg.initialize(elParams); - + KeyPair kp = kpg.generateKeyPair(); - - PGPKeyPair pgpKp = new JcaPGPKeyPair(PGPPublicKey.ELGAMAL_GENERAL , kp, new Date()); - + + PGPKeyPair pgpKp = new JcaPGPKeyPair(PGPPublicKey.ELGAMAL_GENERAL, kp, new Date()); + PGPPublicKey k1 = pgpKp.getPublicKey(); - - PGPPrivateKey k2 = pgpKp.getPrivateKey(); + PGPPrivateKey k2 = pgpKp.getPrivateKey(); // Test bug with ElGamal P size != 0 mod 8 (don't use these sizes at home!) @@ -517,7 +527,7 @@ public void performTest() it = pgpPub.getPublicKeys(); while (it.hasNext()) { - PGPPublicKey pgpKey = (PGPPublicKey)it.next(); + PGPPublicKey pgpKey = (PGPPublicKey)it.next(); if (!pgpKey.isMasterKey()) { @@ -533,14 +543,14 @@ public void performTest() { fail("failed - key strength reported incorrectly."); } - + if (objF.nextObject() != null) { fail("failed - stream not fully parsed."); } } } - + } catch (PGPException e) { @@ -554,7 +564,7 @@ public String getName() } public static void main( - String[] args) + String[] args) { Security.addProvider(new BouncyCastleProvider()); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPDSATest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPDSATest.java index 7137703cf1..2881a872de 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPDSATest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPDSATest.java @@ -15,6 +15,8 @@ import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.UserAttributeSubpacket; +import org.bouncycastle.bcpg.UserAttributeSubpacketTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; @@ -84,29 +86,29 @@ public class BcPGPDSATest byte[] testPrivKey2 = Base64.decode( - "lQHhBEAnoewRBADRvKgDhbV6pMzqYfUgBsLxSHzmycpuxGbjMrpyKHDOEemj" - + "iQb6TyyBKUoR28/pfshFP9R5urtKIT7wjVrDuOkxYkgRhNm+xmPXW2Lw3D++" - + "MQrC5VWe8ywBltz6T9msmChsaKo2hDhIiRI/mg9Q6rH9pJKtVGi4R7CgGxM2" - + "STQ5fwCgub38qGS1W2O4hUsa+3gva5gaNZUEAItegda4/H4t88XdWxW3D8pv" - + "RnFz26/ADdImVaQlBoumD15VmcgYoT1Djizey7X8vfV+pntudESzLbn3GHlI" - + "6C09seH4e8eYP63t7KU/qbUCDomlSswd1OgQ/RxfN86q765K2t3K1i3wDSxe" - + "EgSRyGKee0VNvOBFOFhuWt+patXaBADE1riNkUxg2P4lBNWwu8tEZRmsl/Ys" - + "DBIzXBshoMzZCvS5PnNXMW4G3SAaC9OC9jvKSx9IEWhKjfjs3QcWzXR28mcm" - + "5na0bTxeOMlaPPhBdkTCmFl0IITWlH/pFlR2ah9WYoWYhZEL2tqB82wByzxH" - + "SkSeD9V5oeSCdCcqiqkEmv4DAwLeNsQ2XGJVRmA4lld+CR5vRxpT/+/2xklp" - + "lxVf/nx0+thrHDpro3u/nINIIObk0gh59+zaEEe3APlHqbQVYWFhIGJiYiA8" - + "Y2NjQGRkZC5lZWU+iFoEExECABoFAkAnoewFCwcDAgEDFQIDAxYCAQIeAQIX" - + "gAAKCRA5nBpCS63az85BAKCbPfU8ATrFvkXhzGNGlc1BJo6DWQCgnK125xVK" - + "lWLpt6ZJJ7TXcx3nkm6wAgAAnQFXBEAnoe0QBACsQxPvaeBcv2TkbgU/5Wc/" - + "tO222dPE1mxFbXjGTKfb+6ge96iyD8kTRLrKCkEEeVBa8AZqMSoXUVN6tV8j" - + "/zD8Bc76o5iJ6wgpg3Mmy2GxInVfsfZN6/G3Y2ukmouz+CDNvQdUw8cTguIb" - + "QoV3XhQ03MLbfVmNcHsku9F4CuKNWwADBQP0DSSe8v5PXF9CSCXOIxBDcQ5x" - + "RKjyYOveqoH/4lbOV0YNUbIDZq4RaUdotpADuPREFmWf0zTB6KV/WIiag8XU" - + "WU9zdDvLKR483Bo6Do5pDBcN+NqfQ+ntGY9WJ7BSFnhQ3+07i1K+NsfFTRfv" - + "hf9X3MP75rCf7MxAIWHTabEmUf4DAwLeNsQ2XGJVRmA8DssBUCghogG9n8T3" - + "qfBeKsplGyCcF+JjPeQXkKQaoYGJ0aJz36qFP9d8DuWtT9soQcqIxVf6mTa8" - + "kN1594hGBBgRAgAGBQJAJ6HtAAoJEDmcGkJLrdrPpMkAnRyjQSKugz0YJqOB" - + "yGasMLQLxd2OAKCEIlhtCarlufVQNGZsuWxHVbU8crACAAA="); + "lQHhBEAnoewRBADRvKgDhbV6pMzqYfUgBsLxSHzmycpuxGbjMrpyKHDOEemj" + + "iQb6TyyBKUoR28/pfshFP9R5urtKIT7wjVrDuOkxYkgRhNm+xmPXW2Lw3D++" + + "MQrC5VWe8ywBltz6T9msmChsaKo2hDhIiRI/mg9Q6rH9pJKtVGi4R7CgGxM2" + + "STQ5fwCgub38qGS1W2O4hUsa+3gva5gaNZUEAItegda4/H4t88XdWxW3D8pv" + + "RnFz26/ADdImVaQlBoumD15VmcgYoT1Djizey7X8vfV+pntudESzLbn3GHlI" + + "6C09seH4e8eYP63t7KU/qbUCDomlSswd1OgQ/RxfN86q765K2t3K1i3wDSxe" + + "EgSRyGKee0VNvOBFOFhuWt+patXaBADE1riNkUxg2P4lBNWwu8tEZRmsl/Ys" + + "DBIzXBshoMzZCvS5PnNXMW4G3SAaC9OC9jvKSx9IEWhKjfjs3QcWzXR28mcm" + + "5na0bTxeOMlaPPhBdkTCmFl0IITWlH/pFlR2ah9WYoWYhZEL2tqB82wByzxH" + + "SkSeD9V5oeSCdCcqiqkEmv4DAwLeNsQ2XGJVRmA4lld+CR5vRxpT/+/2xklp" + + "lxVf/nx0+thrHDpro3u/nINIIObk0gh59+zaEEe3APlHqbQVYWFhIGJiYiA8" + + "Y2NjQGRkZC5lZWU+iFoEExECABoFAkAnoewFCwcDAgEDFQIDAxYCAQIeAQIX" + + "gAAKCRA5nBpCS63az85BAKCbPfU8ATrFvkXhzGNGlc1BJo6DWQCgnK125xVK" + + "lWLpt6ZJJ7TXcx3nkm6wAgAAnQFXBEAnoe0QBACsQxPvaeBcv2TkbgU/5Wc/" + + "tO222dPE1mxFbXjGTKfb+6ge96iyD8kTRLrKCkEEeVBa8AZqMSoXUVN6tV8j" + + "/zD8Bc76o5iJ6wgpg3Mmy2GxInVfsfZN6/G3Y2ukmouz+CDNvQdUw8cTguIb" + + "QoV3XhQ03MLbfVmNcHsku9F4CuKNWwADBQP0DSSe8v5PXF9CSCXOIxBDcQ5x" + + "RKjyYOveqoH/4lbOV0YNUbIDZq4RaUdotpADuPREFmWf0zTB6KV/WIiag8XU" + + "WU9zdDvLKR483Bo6Do5pDBcN+NqfQ+ntGY9WJ7BSFnhQ3+07i1K+NsfFTRfv" + + "hf9X3MP75rCf7MxAIWHTabEmUf4DAwLeNsQ2XGJVRmA8DssBUCghogG9n8T3" + + "qfBeKsplGyCcF+JjPeQXkKQaoYGJ0aJz36qFP9d8DuWtT9soQcqIxVf6mTa8" + + "kN1594hGBBgRAgAGBQJAJ6HtAAoJEDmcGkJLrdrPpMkAnRyjQSKugz0YJqOB" + + "yGasMLQLxd2OAKCEIlhtCarlufVQNGZsuWxHVbU8crACAAA="); byte[] sig1 = Base64.decode( @@ -118,220 +120,220 @@ public class BcPGPDSATest byte[] testPubWithUserAttr = Base64.decode( - "mQGiBD2Rqv0RBADqKCkhVEtB/lEEr/9CubuHEy2oN/yU5j+2GXSdcNdVnRI/rwFy" - + "fHEQIk3uU7zHSUKFrC59yDm0sODYyjEdE3BVb0xvEJ5LE/OdndcIMXT1DungZ1vB" - + "zIK/3lr33W/PHixYxv9jduH3WrTehBpiKkgMZp8XloSFj2Cnw9LDyfqB7QCg/8K1" - + "o2k75NkOd9ZjnA9ye7Ri3bEEAKyr61Mo7viPWBK1joWAEsxG0OBWM+iSlG7kwh31" - + "8efgC/7Os6x4Y0jzs8mpcbBjeZtZjS9lRbfp7RinhF269xL0TZ3JxIdtaAV/6yDQ" - + "9NXfZY9dskN++HIR/5GCEEgq/qTJZt6ti5k7aV19ZFfO6wiK3NUy08wOrVsdOkVE" - + "w9IcBADaplhpcel3201uU3OCboogJtw81R5MJMZ4Y9cKL/ca2jGISn0nA7KrAw9v" - + "ShheSixGO4BV9JECkLEbtg7i+W/j/De6S+x2GLNcphuTP3UmgtKbhs0ItRqzW561" - + "s6gLkqi6aWmgaFLd8E1pMJcd9DSY95P13EYB9VJIUxFNUopzo7QcUmFsZiBIYXVz" - + "ZXIgPGhhdXNlckBhY20ub3JnPokAWAQQEQIAGAUCPZGq/QgLAwkIBwIBCgIZAQUb" - + "AwAAAAAKCRAqIBiOh4JvOKg4AJ9j14yygOqqzqiLKeaasIzqT8LCIgCggx14WuLO" - + "wOUTUswTaVKMFnU7tseJAJwEEAECAAYFAj2Rqx8ACgkQ9aWTKMpUDFV+9QP/RiWT" - + "5FAF5Rgb7beaApsgXsME+Pw7HEYFtqGa6VcXEpbcUXO6rjaXsgMgY90klWlWCF1T" - + "HOyKITvj2FdhE+0j8NQn4vaGpiTwORW/zMf/BZ0abdSWQybp10Yjs8gXw30UheO+" - + "F1E524MC+s2AeUi2hwHMiS+AVYd4WhxWHmWuBpTRypP/AAALTgEQAAEBAAAAAQAA" - + "AAABAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQ" - + "Dg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/" - + "2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7" - + "Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCABqAF0DASIAAhEBAxEB/8QAHwAAAQUB" - + "AQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQID" - + "AAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0" - + "NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKT" - + "lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl" - + "5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL" - + "/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHB" - + "CSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpj" - + "ZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3" - + "uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIR" - + "AxEAPwD2aiiq9xcxWsRllcKqjOT06E/0oAsVm6jrmm6VGXvLuOPGflz8x+grzXxV" - + "8U51u5LXRgBGowZHXknnkc9OQcV51caneXdw9xPOXlckl2AJHY4J6cD1oA9J1z4p" - + "TRkrYQhRyQ0hIY5/2QRx7k9ulczN8SvEEshdZkX0UorDrznI759a5Mksckkknqec" - + "mkoA7WD4oavEoEttbTepYEZ+mCMVv6H8SLTULhbe/gFozAYkD5Unp3Ax/kV5XRQB" - + "9EAhgCDkHkEcgilryTwd4zn0m4WzvpTJZSMBuY5MfbueletKyugZWDKwyCOc/j3o" - + "AduyWLDeWB5Ynj8jSUUUAdFXn/xU15dO0RbGGYC5uWwUB6L1Jx+n413F1cJa2stz" - + "J92JC5+gGa+bdfvp9S1q4urmRneQg5Yk4HGAPYZoAzySxySSSep5yaSvQvAPhOHU" - + "rB7u5iLGUlIwQRx7HPr/AJ9LGsfC+dJGngc+X12gc8nvx1/rQB5rRXS3Xg28t9ye" - + "VLvA7Ddj8MDt6Vnx6JKJCsocnBwqqQSOxPH+fWgDKorTl0SaLGXxkZ+ZcZ4z1yfb" - + "P1qg0MqLueN1A6kqRigCOvVPh74mF9YjS7tgLi3GIm6b17c+oOfrXlda3haeW38R" - + "WjxfeMgBOCcD/PHpzQB7nRRRQBqarZjUNLubPJXz4yhI64PFfO3iDRrnRtdm0+cq" - + "0ocEbehzyOv1xX0vXnHxU8Kf2hYf23aRk3VsMTAZO6MZ5x7UAbfga1W00WzjRSF8" - + "kbsg5z744HT/ADmuoysikdQSVP8AI1yPgq6il0axk27V8sDcTg5x7V1qSxOcJIrH" - + "/ZOaAKV5p8JgJSPJGMr97PNcxqOiRXLiRI8nONoIGO55z/8AqyeldhPcQxwyOzoQ" - + "owRkflXH6t4q0nTLjy57mNXfJCA5x+Qx0NAGXd6LD5iiaPYwTAAx07+vXvXOXmiR" - + "Qu6u5VTk/MQQV7cdvxPT866KbxTpt7HGR8p7SMw5HuOP8/Ws/ULlb2No0bKMOGBJ" - + "BHrjHHXn6D8QDzWZQk8iAYVWIA9K6LwDZNeeJ4sEqsaF2YHBHpz2/wA/WsG+V0vZ" - + "kkGGVsEZz9OcntXffC62iiS7vJTsklKxRFuAw6nBP+eKAPRKKKKAOiqOSNJYzHIo" - + "ZGGCD0NSUUAeRajIunwzQG4e3tYZTHGsPzOxJ6ADuQcH8Pw5v+19Q0rVJVgl1JG3" - + "cxykEj13cnHT1r1C38OQ3l063cIkkhmkZDKSeCfx9R/kVLeeGIRKs7hVVDn5OCx9" - + "yeTjqMf0oAo3k1xP4biuJFeKV4w7gDaQcen1/wAjt5gbK81HW41kIiJBZppULe47" - + "eoxx+YzivW9Vh/0FAE+XPIJGCOR0rnbPT7eG+LyxlkAG1wQSPXrjvg9MfjQBycNj" - + "4hMRZgJkUjETQqAy/UAY6DoO/wCNbVlYTNbSNJbmBlBwoUfM30B7j2/lz20VhbKA" - + "wHmZOQWbOfyrO1G3jil8tBhWToOcdu+c/wAvagDzbUdGlu9aRxFiB/vsuBggZOfq" - + "cfWujSIR2dnNZTEeXKgMcb4BUHjofbjNKmI5juiabaGGxVJLcdh/nFWtI0oxagsD" - + "DIkkWXYp4VQDnOemSfyHbigDtgSQMjBI6HqKKKKAOiopoPXjGKdQBnXLiDUI5SMK" - + "VwxHGf8APFUtW1A+YkMKmbnc23njuf6D/ObWquoaNSQCM/rwP1rMYxxTGWR1UsoU" - + "biAcdep+o/KgDG1LxdpracIirCVRjaykHr6cHGQe1cv/AGjNcXBW3sntyT/rHcjj" - + "Hp6Z+nQdAK6PXIdIvcE3Fv5rEfNgP9eRn8c8d/rgzX2i2sqo1y8745CD5WPseOnH" - + "f8aANiz1O9gjiR5FMUhAV1wcH0Ix6jHHSrMsskz7pGy2MZNc8PEEM7xxWsM/lr8r" - + "b4jtI9CcHt7nr7Vqi4JuEjB2qse9y2Ace47dRn/OQDMuRMl8RHw7SgDBPGT6jpwf" - + "yzXa2NmbYF3IMrDB2kkAe3HP5Vwk99u1hdg3ANuOOOB0z6ZwPz6c8eiAhgCDkHkE" - + "cgigBaKKKAOiqJiMEb9mBknjim3LFIGcOU285ArNa8mKIN3QclScn6+/FADL9xOc" - + "K2Tj7xAxnAwQPqOmawdSNpeSJBfQyGNXwQpIAPvjqOPyPT12nYsxYnJIGSeMnHP+" - + "e9UL7TUumEqOYp1GNw6N/vDv/wDXoA5+70vSbFGlhtopUxkBl3EZ45z7/kKwTdpN" - + "cIsOmeSCduUiCnB9cdeg/M/j0v8AbFtY5hu0gjmGSRICT19cdMDt3+lULzxPZGZv" - + "LXcBnCrwB6Y4PX+ZoAptMRbiMDAGSSMksf8A9Q6DuKzJtVYs+BvcPgMTkEdOTnrx" - + "/KoLzVmvZZQjjaT82DyPbqcdx+GKitLf7TNsLYAGWPfH+TQBcsYJDE0rOyu4wjHk" - + "gfQ+p/zzWjpnja5sdSOm6yyK0Z2pMCQjZ+6SM9CCMdhnp3E1hYy393FaW0eXfjAx" - + "gAdT26D+X4Vg/EuFLbxOsCYBitkQkEdsgcADsB+lAHplvqUbsu5vlYA5PIB7468e" - + "nPf8lfUlDkRRrIvqZNn6EV41o3iO/wBFcCJ/MhBP7pjwD6g9ua7G08b6TcRl7h5L" - + "eTPKvGz5+hUH9cUAeo3uFDrt+Y4O7HOOB69Pr/8AXqhUlx/r2/z2qOgBCQoJJwBy" - + "SeABXHeIfHVvbXcemaW4luHlVJJlIKxjODgg8nqKq/Em6uItOhWOeVAx5CuRnrXn" - + "+jf8hyw/6+Y//QhQB6xrmlxzXc0NyuHVyQcdjnBz379D1BGeK5u88LMJGlt2RlX7" - + "qkEsPXn6/pXo/ilVzbttG7DDOOeornqAONbRpI4v3pKOQcAqQD+Y/P6j052NK0p5" - + "HWHy3IBPyqrfN6gZz+P4/hpXoGzOOiP/ACNdH4XRftsp2jIBxx70AX9E0pdMtvMm" - + "VRNt5xyEGOgPf3NeDeLdVOs+J768zlGkKx+yjgfy/WvoPXeNEvMcfujXzJQAUUUU" - + "Af/ZiQBGBBARAgAGBQI9katEAAoJECogGI6Hgm84xz8AoNGz1fJrVPxqkBrUDmWA" - + "GsP6qVGYAJ0ZOftw/GfQHzdGR8pOK85DLUPEErQkUmFsZiBIYXVzZXIgPGhhdXNl" - + "ckBwcml2YXNwaGVyZS5jb20+iQBGBBARAgAGBQI9katmAAoJECogGI6Hgm84m0oA" - + "oJS3CTrgpqRZfhgPtHGtUVjRCJbbAJ9stJgPcbqA2xXEg9yl2TQToWdWxbQkUmFs" - + "ZiBIYXVzZXIgPGhhdXNlckBwcml2YXNwaGVyZS5vcmc+iQBGBBARAgAGBQI9kauJ" - + "AAoJECogGI6Hgm84GfAAnRswktLMzDfIjv6ni76Qp5B850byAJ90I0LEHOLhda7r" - + "kqTwZ8rguNssUrQkUmFsZiBIYXVzZXIgPGhhdXNlckBwcml2YXNwaGVyZS5uZXQ+" - + "iQBGBBARAgAGBQI9kaubAAoJECogGI6Hgm84zi0An16C4s/B9Z0/AtfoN4ealMh3" - + "i3/7AJ9Jg4GOUqGCGRRKUA9Gs5pk8yM8GbQmUmFsZiBDLiBIYXVzZXIgPHJhbGZo" - + "YXVzZXJAYmx1ZXdpbi5jaD6JAEYEEBECAAYFAj2Rq8oACgkQKiAYjoeCbzhPOACg" - + "iiTohKuIa66FNiI24mQ+XR9nTisAoLmh3lJf16/06qLPsRd9shTkLfmHtB9SYWxm" - + "IEhhdXNlciA8cmFsZmhhdXNlckBnbXguY2g+iQBGBBARAgAGBQI9kavvAAoJECog" - + "GI6Hgm84ZE8An0RlgL8mPBa/P08S5e/lD35MlDdgAJ99pjCeY46S9+nVyx7ACyKO" - + "SZ4OcLQmUmFsZiBIYXVzZXIgPGhhdXNlci5yYWxmQG15c3VucmlzZS5jaD6JAEYE" - + "EBECAAYFAj2RrEEACgkQKiAYjoeCbzjz0wCg+q801XrXk+Rf+koSI50MW5OaaKYA" - + "oKOVA8SLxE29qSR/bJeuW0ryzRLqtCVSYWxmIEhhdXNlciA8aGF1c2VyLnJhbGZA" - + "ZnJlZXN1cmYuY2g+iQBGBBARAgAGBQI9kaxXAAoJECogGI6Hgm848zoAnRBtWH6e" - + "fTb3is63s8J2zTfpsyS0AKDxTjl+ZZV0COHLrSCaNLZVcpImFrkEDQQ9kar+EBAA" - + "+RigfloGYXpDkJXcBWyHhuxh7M1FHw7Y4KN5xsncegus5D/jRpS2MEpT13wCFkiA" - + "tRXlKZmpnwd00//jocWWIE6YZbjYDe4QXau2FxxR2FDKIldDKb6V6FYrOHhcC9v4" - + "TE3V46pGzPvOF+gqnRRh44SpT9GDhKh5tu+Pp0NGCMbMHXdXJDhK4sTw6I4TZ5dO" - + "khNh9tvrJQ4X/faY98h8ebByHTh1+/bBc8SDESYrQ2DD4+jWCv2hKCYLrqmus2UP" - + "ogBTAaB81qujEh76DyrOH3SET8rzF/OkQOnX0ne2Qi0CNsEmy2henXyYCQqNfi3t" - + "5F159dSST5sYjvwqp0t8MvZCV7cIfwgXcqK61qlC8wXo+VMROU+28W65Szgg2gGn" - + "VqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf3HZSTz09jdvOmeFX" - + "klnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2gpXI61Brwv0YAWCvl" - + "9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPAQ/ClWxiNjrtVjLhd" - + "ONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQDGcgHKXrKlQzZlp+r" - + "0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVes91hcAAgIQAKD9MGkS8SUD2irI" - + "AiwVHU0WXLBnk2CvvueSmT9YtC34UKkIkDPZ7VoeuXDfqTOlbiE6T16zPvArZfbl" - + "JGdrU7HhsTdu+ADxRt1dPur0G0ICJ3pBD3ydGWpdLI/94x1BvTY4rsR5mS4YWmpf" - + "e2kWc7ZqezhP7Xt9q7m4EK456ddeUZWtkwGU+PKyRAZ+CK82Uhouw+4aW0NjiqmX" - + "hfH9/BUhI1P/8R9VkTfAFGPmZzqoHr4AuO5tLRLD2RFSmQCP8nZTiP9nP+wBBvn7" - + "vuqKRQsj9PwwPD4V5SM+kpW+rUIWr9TZYl3UqSnlXlpEZFd2Bfl6NloeH0cfU69E" - + "gtjcWGvGxYKPS0cg5yhVb4okka6RqIPQiYl6eJgv4tRTKoPRX29o0aUVdqVvDr5u" - + "tnFzcINq7jTo8GiO8Ia3cIFWfo0LyQBd1cf1U+eEOz+DleEFqyljaz9VCbDPE4GP" - + "o+ALESBlOwn5daUSaah9iU8aVPaSjn45hoQqxOKPwJxnCKKQ01iy0Gir+CDU8JJB" - + "7bmbvQN4bke30EGAeED3oi+3VaBHrhjYLv7SHIxP5jtCJKWMJuLRV709HsWJi3kn" - + "fGHwH+yCDF8+PDeROAzpXBaD2EFhKgeUTjP5Rgn6ltRf8TQnfbW4qlwyiXMhPOfC" - + "x6qNmwaFPKQJpIkVq5VGfRXAERfkiQBMBBgRAgAMBQI9kar+BRsMAAAAAAoJECog" - + "GI6Hgm84CDMAoNrNeP4c8XqFJnsLLPcjk5YGLaVIAKCrL5KFuLQVIp7d0Fkscx3/" - + "7DGrzw=="); + "mQGiBD2Rqv0RBADqKCkhVEtB/lEEr/9CubuHEy2oN/yU5j+2GXSdcNdVnRI/rwFy" + + "fHEQIk3uU7zHSUKFrC59yDm0sODYyjEdE3BVb0xvEJ5LE/OdndcIMXT1DungZ1vB" + + "zIK/3lr33W/PHixYxv9jduH3WrTehBpiKkgMZp8XloSFj2Cnw9LDyfqB7QCg/8K1" + + "o2k75NkOd9ZjnA9ye7Ri3bEEAKyr61Mo7viPWBK1joWAEsxG0OBWM+iSlG7kwh31" + + "8efgC/7Os6x4Y0jzs8mpcbBjeZtZjS9lRbfp7RinhF269xL0TZ3JxIdtaAV/6yDQ" + + "9NXfZY9dskN++HIR/5GCEEgq/qTJZt6ti5k7aV19ZFfO6wiK3NUy08wOrVsdOkVE" + + "w9IcBADaplhpcel3201uU3OCboogJtw81R5MJMZ4Y9cKL/ca2jGISn0nA7KrAw9v" + + "ShheSixGO4BV9JECkLEbtg7i+W/j/De6S+x2GLNcphuTP3UmgtKbhs0ItRqzW561" + + "s6gLkqi6aWmgaFLd8E1pMJcd9DSY95P13EYB9VJIUxFNUopzo7QcUmFsZiBIYXVz" + + "ZXIgPGhhdXNlckBhY20ub3JnPokAWAQQEQIAGAUCPZGq/QgLAwkIBwIBCgIZAQUb" + + "AwAAAAAKCRAqIBiOh4JvOKg4AJ9j14yygOqqzqiLKeaasIzqT8LCIgCggx14WuLO" + + "wOUTUswTaVKMFnU7tseJAJwEEAECAAYFAj2Rqx8ACgkQ9aWTKMpUDFV+9QP/RiWT" + + "5FAF5Rgb7beaApsgXsME+Pw7HEYFtqGa6VcXEpbcUXO6rjaXsgMgY90klWlWCF1T" + + "HOyKITvj2FdhE+0j8NQn4vaGpiTwORW/zMf/BZ0abdSWQybp10Yjs8gXw30UheO+" + + "F1E524MC+s2AeUi2hwHMiS+AVYd4WhxWHmWuBpTRypP/AAALTgEQAAEBAAAAAQAA" + + "AAABAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQ" + + "Dg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/" + + "2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7" + + "Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCABqAF0DASIAAhEBAxEB/8QAHwAAAQUB" + + "AQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQID" + + "AAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0" + + "NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKT" + + "lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl" + + "5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL" + + "/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHB" + + "CSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpj" + + "ZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3" + + "uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIR" + + "AxEAPwD2aiiq9xcxWsRllcKqjOT06E/0oAsVm6jrmm6VGXvLuOPGflz8x+grzXxV" + + "8U51u5LXRgBGowZHXknnkc9OQcV51caneXdw9xPOXlckl2AJHY4J6cD1oA9J1z4p" + + "TRkrYQhRyQ0hIY5/2QRx7k9ulczN8SvEEshdZkX0UorDrznI759a5Mksckkknqec" + + "mkoA7WD4oavEoEttbTepYEZ+mCMVv6H8SLTULhbe/gFozAYkD5Unp3Ax/kV5XRQB" + + "9EAhgCDkHkEcgilryTwd4zn0m4WzvpTJZSMBuY5MfbueletKyugZWDKwyCOc/j3o" + + "AduyWLDeWB5Ynj8jSUUUAdFXn/xU15dO0RbGGYC5uWwUB6L1Jx+n413F1cJa2stz" + + "J92JC5+gGa+bdfvp9S1q4urmRneQg5Yk4HGAPYZoAzySxySSSep5yaSvQvAPhOHU" + + "rB7u5iLGUlIwQRx7HPr/AJ9LGsfC+dJGngc+X12gc8nvx1/rQB5rRXS3Xg28t9ye" + + "VLvA7Ddj8MDt6Vnx6JKJCsocnBwqqQSOxPH+fWgDKorTl0SaLGXxkZ+ZcZ4z1yfb" + + "P1qg0MqLueN1A6kqRigCOvVPh74mF9YjS7tgLi3GIm6b17c+oOfrXlda3haeW38R" + + "WjxfeMgBOCcD/PHpzQB7nRRRQBqarZjUNLubPJXz4yhI64PFfO3iDRrnRtdm0+cq" + + "0ocEbehzyOv1xX0vXnHxU8Kf2hYf23aRk3VsMTAZO6MZ5x7UAbfga1W00WzjRSF8" + + "kbsg5z744HT/ADmuoysikdQSVP8AI1yPgq6il0axk27V8sDcTg5x7V1qSxOcJIrH" + + "/ZOaAKV5p8JgJSPJGMr97PNcxqOiRXLiRI8nONoIGO55z/8AqyeldhPcQxwyOzoQ" + + "owRkflXH6t4q0nTLjy57mNXfJCA5x+Qx0NAGXd6LD5iiaPYwTAAx07+vXvXOXmiR" + + "Qu6u5VTk/MQQV7cdvxPT866KbxTpt7HGR8p7SMw5HuOP8/Ws/ULlb2No0bKMOGBJ" + + "BHrjHHXn6D8QDzWZQk8iAYVWIA9K6LwDZNeeJ4sEqsaF2YHBHpz2/wA/WsG+V0vZ" + + "kkGGVsEZz9OcntXffC62iiS7vJTsklKxRFuAw6nBP+eKAPRKKKKAOiqOSNJYzHIo" + + "ZGGCD0NSUUAeRajIunwzQG4e3tYZTHGsPzOxJ6ADuQcH8Pw5v+19Q0rVJVgl1JG3" + + "cxykEj13cnHT1r1C38OQ3l063cIkkhmkZDKSeCfx9R/kVLeeGIRKs7hVVDn5OCx9" + + "yeTjqMf0oAo3k1xP4biuJFeKV4w7gDaQcen1/wAjt5gbK81HW41kIiJBZppULe47" + + "eoxx+YzivW9Vh/0FAE+XPIJGCOR0rnbPT7eG+LyxlkAG1wQSPXrjvg9MfjQBycNj" + + "4hMRZgJkUjETQqAy/UAY6DoO/wCNbVlYTNbSNJbmBlBwoUfM30B7j2/lz20VhbKA" + + "wHmZOQWbOfyrO1G3jil8tBhWToOcdu+c/wAvagDzbUdGlu9aRxFiB/vsuBggZOfq" + + "cfWujSIR2dnNZTEeXKgMcb4BUHjofbjNKmI5juiabaGGxVJLcdh/nFWtI0oxagsD" + + "DIkkWXYp4VQDnOemSfyHbigDtgSQMjBI6HqKKKKAOiopoPXjGKdQBnXLiDUI5SMK" + + "VwxHGf8APFUtW1A+YkMKmbnc23njuf6D/ObWquoaNSQCM/rwP1rMYxxTGWR1UsoU" + + "biAcdep+o/KgDG1LxdpracIirCVRjaykHr6cHGQe1cv/AGjNcXBW3sntyT/rHcjj" + + "Hp6Z+nQdAK6PXIdIvcE3Fv5rEfNgP9eRn8c8d/rgzX2i2sqo1y8745CD5WPseOnH" + + "f8aANiz1O9gjiR5FMUhAV1wcH0Ix6jHHSrMsskz7pGy2MZNc8PEEM7xxWsM/lr8r" + + "b4jtI9CcHt7nr7Vqi4JuEjB2qse9y2Ace47dRn/OQDMuRMl8RHw7SgDBPGT6jpwf" + + "yzXa2NmbYF3IMrDB2kkAe3HP5Vwk99u1hdg3ANuOOOB0z6ZwPz6c8eiAhgCDkHkE" + + "cgigBaKKKAOiqJiMEb9mBknjim3LFIGcOU285ArNa8mKIN3QclScn6+/FADL9xOc" + + "K2Tj7xAxnAwQPqOmawdSNpeSJBfQyGNXwQpIAPvjqOPyPT12nYsxYnJIGSeMnHP+" + + "e9UL7TUumEqOYp1GNw6N/vDv/wDXoA5+70vSbFGlhtopUxkBl3EZ45z7/kKwTdpN" + + "cIsOmeSCduUiCnB9cdeg/M/j0v8AbFtY5hu0gjmGSRICT19cdMDt3+lULzxPZGZv" + + "LXcBnCrwB6Y4PX+ZoAptMRbiMDAGSSMksf8A9Q6DuKzJtVYs+BvcPgMTkEdOTnrx" + + "/KoLzVmvZZQjjaT82DyPbqcdx+GKitLf7TNsLYAGWPfH+TQBcsYJDE0rOyu4wjHk" + + "gfQ+p/zzWjpnja5sdSOm6yyK0Z2pMCQjZ+6SM9CCMdhnp3E1hYy393FaW0eXfjAx" + + "gAdT26D+X4Vg/EuFLbxOsCYBitkQkEdsgcADsB+lAHplvqUbsu5vlYA5PIB7468e" + + "nPf8lfUlDkRRrIvqZNn6EV41o3iO/wBFcCJ/MhBP7pjwD6g9ua7G08b6TcRl7h5L" + + "eTPKvGz5+hUH9cUAeo3uFDrt+Y4O7HOOB69Pr/8AXqhUlx/r2/z2qOgBCQoJJwBy" + + "SeABXHeIfHVvbXcemaW4luHlVJJlIKxjODgg8nqKq/Em6uItOhWOeVAx5CuRnrXn" + + "+jf8hyw/6+Y//QhQB6xrmlxzXc0NyuHVyQcdjnBz379D1BGeK5u88LMJGlt2RlX7" + + "qkEsPXn6/pXo/ilVzbttG7DDOOeornqAONbRpI4v3pKOQcAqQD+Y/P6j052NK0p5" + + "HWHy3IBPyqrfN6gZz+P4/hpXoGzOOiP/ACNdH4XRftsp2jIBxx70AX9E0pdMtvMm" + + "VRNt5xyEGOgPf3NeDeLdVOs+J768zlGkKx+yjgfy/WvoPXeNEvMcfujXzJQAUUUU" + + "Af/ZiQBGBBARAgAGBQI9katEAAoJECogGI6Hgm84xz8AoNGz1fJrVPxqkBrUDmWA" + + "GsP6qVGYAJ0ZOftw/GfQHzdGR8pOK85DLUPEErQkUmFsZiBIYXVzZXIgPGhhdXNl" + + "ckBwcml2YXNwaGVyZS5jb20+iQBGBBARAgAGBQI9katmAAoJECogGI6Hgm84m0oA" + + "oJS3CTrgpqRZfhgPtHGtUVjRCJbbAJ9stJgPcbqA2xXEg9yl2TQToWdWxbQkUmFs" + + "ZiBIYXVzZXIgPGhhdXNlckBwcml2YXNwaGVyZS5vcmc+iQBGBBARAgAGBQI9kauJ" + + "AAoJECogGI6Hgm84GfAAnRswktLMzDfIjv6ni76Qp5B850byAJ90I0LEHOLhda7r" + + "kqTwZ8rguNssUrQkUmFsZiBIYXVzZXIgPGhhdXNlckBwcml2YXNwaGVyZS5uZXQ+" + + "iQBGBBARAgAGBQI9kaubAAoJECogGI6Hgm84zi0An16C4s/B9Z0/AtfoN4ealMh3" + + "i3/7AJ9Jg4GOUqGCGRRKUA9Gs5pk8yM8GbQmUmFsZiBDLiBIYXVzZXIgPHJhbGZo" + + "YXVzZXJAYmx1ZXdpbi5jaD6JAEYEEBECAAYFAj2Rq8oACgkQKiAYjoeCbzhPOACg" + + "iiTohKuIa66FNiI24mQ+XR9nTisAoLmh3lJf16/06qLPsRd9shTkLfmHtB9SYWxm" + + "IEhhdXNlciA8cmFsZmhhdXNlckBnbXguY2g+iQBGBBARAgAGBQI9kavvAAoJECog" + + "GI6Hgm84ZE8An0RlgL8mPBa/P08S5e/lD35MlDdgAJ99pjCeY46S9+nVyx7ACyKO" + + "SZ4OcLQmUmFsZiBIYXVzZXIgPGhhdXNlci5yYWxmQG15c3VucmlzZS5jaD6JAEYE" + + "EBECAAYFAj2RrEEACgkQKiAYjoeCbzjz0wCg+q801XrXk+Rf+koSI50MW5OaaKYA" + + "oKOVA8SLxE29qSR/bJeuW0ryzRLqtCVSYWxmIEhhdXNlciA8aGF1c2VyLnJhbGZA" + + "ZnJlZXN1cmYuY2g+iQBGBBARAgAGBQI9kaxXAAoJECogGI6Hgm848zoAnRBtWH6e" + + "fTb3is63s8J2zTfpsyS0AKDxTjl+ZZV0COHLrSCaNLZVcpImFrkEDQQ9kar+EBAA" + + "+RigfloGYXpDkJXcBWyHhuxh7M1FHw7Y4KN5xsncegus5D/jRpS2MEpT13wCFkiA" + + "tRXlKZmpnwd00//jocWWIE6YZbjYDe4QXau2FxxR2FDKIldDKb6V6FYrOHhcC9v4" + + "TE3V46pGzPvOF+gqnRRh44SpT9GDhKh5tu+Pp0NGCMbMHXdXJDhK4sTw6I4TZ5dO" + + "khNh9tvrJQ4X/faY98h8ebByHTh1+/bBc8SDESYrQ2DD4+jWCv2hKCYLrqmus2UP" + + "ogBTAaB81qujEh76DyrOH3SET8rzF/OkQOnX0ne2Qi0CNsEmy2henXyYCQqNfi3t" + + "5F159dSST5sYjvwqp0t8MvZCV7cIfwgXcqK61qlC8wXo+VMROU+28W65Szgg2gGn" + + "VqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf3HZSTz09jdvOmeFX" + + "klnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2gpXI61Brwv0YAWCvl" + + "9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPAQ/ClWxiNjrtVjLhd" + + "ONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQDGcgHKXrKlQzZlp+r" + + "0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVes91hcAAgIQAKD9MGkS8SUD2irI" + + "AiwVHU0WXLBnk2CvvueSmT9YtC34UKkIkDPZ7VoeuXDfqTOlbiE6T16zPvArZfbl" + + "JGdrU7HhsTdu+ADxRt1dPur0G0ICJ3pBD3ydGWpdLI/94x1BvTY4rsR5mS4YWmpf" + + "e2kWc7ZqezhP7Xt9q7m4EK456ddeUZWtkwGU+PKyRAZ+CK82Uhouw+4aW0NjiqmX" + + "hfH9/BUhI1P/8R9VkTfAFGPmZzqoHr4AuO5tLRLD2RFSmQCP8nZTiP9nP+wBBvn7" + + "vuqKRQsj9PwwPD4V5SM+kpW+rUIWr9TZYl3UqSnlXlpEZFd2Bfl6NloeH0cfU69E" + + "gtjcWGvGxYKPS0cg5yhVb4okka6RqIPQiYl6eJgv4tRTKoPRX29o0aUVdqVvDr5u" + + "tnFzcINq7jTo8GiO8Ia3cIFWfo0LyQBd1cf1U+eEOz+DleEFqyljaz9VCbDPE4GP" + + "o+ALESBlOwn5daUSaah9iU8aVPaSjn45hoQqxOKPwJxnCKKQ01iy0Gir+CDU8JJB" + + "7bmbvQN4bke30EGAeED3oi+3VaBHrhjYLv7SHIxP5jtCJKWMJuLRV709HsWJi3kn" + + "fGHwH+yCDF8+PDeROAzpXBaD2EFhKgeUTjP5Rgn6ltRf8TQnfbW4qlwyiXMhPOfC" + + "x6qNmwaFPKQJpIkVq5VGfRXAERfkiQBMBBgRAgAMBQI9kar+BRsMAAAAAAoJECog" + + "GI6Hgm84CDMAoNrNeP4c8XqFJnsLLPcjk5YGLaVIAKCrL5KFuLQVIp7d0Fkscx3/" + + "7DGrzw=="); byte[] aesSecretKey = Base64.decode( - "lQHpBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN" - + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj" - + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA" - + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo" - + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5" - + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN" - + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X" - + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF" - + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV" - + "jTxKmrLYnZz5w5qyVpvRyv4JAwKyWlhdblPudWBFXNkW5ydKn0AV2f51wEtj" - + "Zy0aLIeutVMSJf1ytLqjFqrnFe6pdJrHO3G00TE8OuFhftWosLGLbEGytDtF" - + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gQUVTMjU2KSA8ZXJpY0Bib3Vu" - + "Y3ljYXN0bGUub3JnPohZBBMRAgAZBQJAUnSGBAsHAwIDFQIDAxYCAQIeAQIX" - + "gAAKCRBYt1NnUiCgeFKaAKCiqtOO+NQES1gJW6XuOGmSkXt8bQCfcuW7SXZH" - + "zxK1FfdcG2HEDs3YEVawAgAA"); + "lQHpBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN" + + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj" + + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA" + + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo" + + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5" + + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN" + + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X" + + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF" + + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV" + + "jTxKmrLYnZz5w5qyVpvRyv4JAwKyWlhdblPudWBFXNkW5ydKn0AV2f51wEtj" + + "Zy0aLIeutVMSJf1ytLqjFqrnFe6pdJrHO3G00TE8OuFhftWosLGLbEGytDtF" + + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gQUVTMjU2KSA8ZXJpY0Bib3Vu" + + "Y3ljYXN0bGUub3JnPohZBBMRAgAZBQJAUnSGBAsHAwIDFQIDAxYCAQIeAQIX" + + "gAAKCRBYt1NnUiCgeFKaAKCiqtOO+NQES1gJW6XuOGmSkXt8bQCfcuW7SXZH" + + "zxK1FfdcG2HEDs3YEVawAgAA"); byte[] aesPublicKey = Base64.decode( - "mQGiBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN" - + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj" - + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA" - + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo" - + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5" - + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN" - + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X" - + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF" - + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV" - + "jTxKmrLYnZz5w5qyVpvRyrQ7RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt" - + "IEFFUzI1NikgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ0" - + "hgQLBwMCAxUCAwMWAgECHgECF4AACgkQWLdTZ1IgoHhSmgCfU83BLBF2nCua" - + "zk2dXB9zO1l6XS8AnA07U4cq5W0GrKM6/kP9HWtPhgOFsAIAAA=="); + "mQGiBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN" + + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj" + + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA" + + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo" + + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5" + + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN" + + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X" + + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF" + + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV" + + "jTxKmrLYnZz5w5qyVpvRyrQ7RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt" + + "IEFFUzI1NikgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ0" + + "hgQLBwMCAxUCAwMWAgECHgECF4AACgkQWLdTZ1IgoHhSmgCfU83BLBF2nCua" + + "zk2dXB9zO1l6XS8AnA07U4cq5W0GrKM6/kP9HWtPhgOFsAIAAA=="); byte[] twofishSecretKey = Base64.decode( - "lQHpBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc" - + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8" - + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p" - + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/" - + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2" - + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG" - + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK" - + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v" - + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj" - + "KJs01YT3L6f0iIj03hCeV/4KAwLcGrxT3X0qR2CZyZYSVBdjXeNYKXuGBtOf" - + "ood26WOtwLw4+l9sHVoiXNv0LomkO58ndJRPGCeZWZEDMVrfkS7rcOlktDxF" - + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gdHdvZmlzaCkgPGVyaWNAYm91" - + "bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ20gQLBwMCAxUCAwMWAgECHgEC" - + "F4AACgkQaCCMaHh9zR2+RQCghcQwlt4B4YmNxp2b3v6rP3E8M0kAn2Gspi4u" - + "A/ynoqnC1O8HNlbjPdlVsAIAAA=="); + "lQHpBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc" + + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8" + + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p" + + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/" + + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2" + + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG" + + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK" + + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v" + + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj" + + "KJs01YT3L6f0iIj03hCeV/4KAwLcGrxT3X0qR2CZyZYSVBdjXeNYKXuGBtOf" + + "ood26WOtwLw4+l9sHVoiXNv0LomkO58ndJRPGCeZWZEDMVrfkS7rcOlktDxF" + + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gdHdvZmlzaCkgPGVyaWNAYm91" + + "bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ20gQLBwMCAxUCAwMWAgECHgEC" + + "F4AACgkQaCCMaHh9zR2+RQCghcQwlt4B4YmNxp2b3v6rP3E8M0kAn2Gspi4u" + + "A/ynoqnC1O8HNlbjPdlVsAIAAA=="); byte[] twofishPublicKey = Base64.decode( - "mQGiBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc" - + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8" - + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p" - + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/" - + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2" - + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG" - + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK" - + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v" - + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj" - + "KJs01YT3L6f0iIj03hCeV7Q8RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt" - + "IHR3b2Zpc2gpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkFAkBS" - + "dtIECwcDAgMVAgMDFgIBAh4BAheAAAoJEGggjGh4fc0dvkUAn2QGdNk8Wrrd" - + "+DvKECrO5+yoPRx3AJ91DhCMme6uMrQorKSDYxHlgc7iT7ACAAA="); - - char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; + "mQGiBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc" + + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8" + + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p" + + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/" + + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2" + + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG" + + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK" + + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v" + + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj" + + "KJs01YT3L6f0iIj03hCeV7Q8RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt" + + "IHR3b2Zpc2gpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkFAkBS" + + "dtIECwcDAgMVAgMDFgIBAh4BAheAAAoJEGggjGh4fc0dvkUAn2QGdNk8Wrrd" + + "+DvKECrO5+yoPRx3AJ91DhCMme6uMrQorKSDYxHlgc7iT7ACAAA="); + + char[] pass = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'}; /** * Generated signature test - * + * * @param sKey * @param pgpPrivKey */ public void generateTest( PGPSecretKeyRing sKey, - PGPPublicKey pgpPubKey, - PGPPrivateKey pgpPrivKey) + PGPPublicKey pgpPubKey, + PGPPrivateKey pgpPrivKey) throws Exception { - String data = "hello world!"; - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); - PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1)); - + String data = "hello world!"; + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1)); + sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); - - Iterator it = sKey.getSecretKey().getPublicKey().getUserIDs(); - String primaryUserID = (String)it.next(); - + + Iterator it = sKey.getSecretKey().getPublicKey().getUserIDs(); + String primaryUserID = (String)it.next(); + spGen.setSignerUserID(true, primaryUserID); - + sGen.setHashedSubpackets(spGen.generate()); - + PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( - PGPCompressedData.ZIP); + PGPCompressedData.ZIP); BCPGOutputStream bcOut = new BCPGOutputStream( cGen.open(new UncloseableOutputStream(bOut))); @@ -339,7 +341,7 @@ public void generateTest( sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); - + Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), @@ -361,25 +363,25 @@ public void generateTest( cGen.close(); - JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(bOut.toByteArray()); - PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); + JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(bOut.toByteArray()); + PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new JcaPGPObjectFactory(c1.getDataStream()); - - + + PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); - PGPOnePassSignature ops = p1.get(0); - - PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); + PGPOnePassSignature ops = p1.get(0); + + PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } - InputStream dIn = p2.getInputStream(); + InputStream dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPubKey); - + while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); @@ -392,7 +394,7 @@ public void generateTest( fail("Failed generated signature check"); } } - + public void performTest() throws Exception { @@ -404,64 +406,64 @@ public void performTest() // // Read the public key // - PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); + PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); pubKey = pgpPub.getPublicKey(); // // Read the private key // - PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator()); - PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); - + PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator()); + PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); + // // test signature message // - JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(sig1); + JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(sig1); - PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); + PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new JcaPGPObjectFactory(c1.getDataStream()); - + PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); - - PGPOnePassSignature ops = p1.get(0); - - PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); - InputStream dIn = p2.getInputStream(); - int ch; + PGPOnePassSignature ops = p1.get(0); + + PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); + + InputStream dIn = p2.getInputStream(); + int ch; ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey); - + while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } - PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); - - if (!ops.verify(p3.get(0))) + PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); + isTrue(!p3.isEmpty()); + if (!ops.verify((PGPSignature)p3.iterator().next())) { fail("Failed signature check"); } - + // // signature generation // generateTest(sKey, pubKey, pgpPrivKey); - + // // signature generation - canonical text // - String data = "hello world!"; - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); - PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.DSA, PGPUtil.SHA1)); + String data = "hello world!"; + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.DSA, PGPUtil.SHA1)); sGen.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, pgpPrivKey); - PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( + PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); BCPGOutputStream bcOut = new BCPGOutputStream( @@ -469,7 +471,7 @@ public void performTest() sGen.generateOnePassVersion(false).encode(bcOut); - PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); + PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), @@ -498,11 +500,11 @@ public void performTest() c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new JcaPGPObjectFactory(c1.getDataStream()); - + p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); - + ops = p1.get(0); - + p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { @@ -512,7 +514,7 @@ public void performTest() dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey); - + while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); @@ -524,7 +526,7 @@ public void performTest() { fail("Failed generated signature check"); } - + // // Read the public key with user attributes // @@ -533,24 +535,30 @@ public void performTest() pubKey = pgpPub.getPublicKey(); Iterator it = pubKey.getUserAttributes(); - int count = 0; + int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); - - Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes); + + Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { sigs.next(); - + sigCount++; } - + if (sigCount != 1) { fail("Failed user attributes signature check"); } + PGPUserAttributeSubpacketVector attr2 = PGPUserAttributeSubpacketVector.fromSubpackets(new UserAttributeSubpacket[]{attributes.getImageAttribute()}); + isTrue(attributes.getSubpacket(UserAttributeSubpacketTags.IMAGE_ATTRIBUTE).equals( + attr2.getSubpacket(UserAttributeSubpacketTags.IMAGE_ATTRIBUTE))); + isTrue(attributes.equals(attr2)); + isTrue(attributes.hashCode() == attr2.hashCode()); + count++; } @@ -559,11 +567,11 @@ public void performTest() fail("Failed user attributes check"); } - byte[] pgpPubBytes = pgpPub.getEncoded(); + byte[] pgpPubBytes = pgpPub.getEncoded(); pgpPub = new PGPPublicKeyRing(pgpPubBytes, new BcKeyFingerprintCalculator()); - pubKey = pgpPub.getPublicKey(); + pubKey = pgpPub.getPublicKey(); it = pubKey.getUserAttributes(); count = 0; @@ -581,13 +589,13 @@ public void performTest() // // reading test extra data - key with edge condition for DSA key password. // - char [] passPhrase = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + char[] passPhrase = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; sKey = new PGPSecretKeyRing(testPrivKey2, new BcKeyFingerprintCalculator()); - pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(passPhrase)); + pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider(new BouncyCastleProvider()).build(passPhrase)); + + byte[] bytes = new JcaPGPKeyConverter().setProvider("BC").getPrivateKey(pgpPrivKey).getEncoded(); - byte[] bytes = new JcaPGPKeyConverter().setProvider("BC").getPrivateKey(pgpPrivKey).getEncoded(); - // // reading test - aes256 encrypted passphrase. // @@ -595,7 +603,7 @@ public void performTest() pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); bytes = new JcaPGPKeyConverter().setProvider("BC").getPrivateKey(pgpPrivKey).getEncoded(); - + // // reading test - twofish encrypted passphrase. // @@ -603,20 +611,20 @@ public void performTest() pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); bytes = new JcaPGPKeyConverter().setProvider("BC").getPrivateKey(pgpPrivKey).getEncoded(); - + // // use of PGPKeyPair // - KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", "BC"); - + KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", "BC"); + kpg.initialize(512); - + KeyPair kp = kpg.generateKeyPair(); - - PGPKeyPair pgpKp = new JcaPGPKeyPair(PGPPublicKey.DSA, kp, new Date()); - + + PGPKeyPair pgpKp = new JcaPGPKeyPair(PGPPublicKey.DSA, kp, new Date()); + PGPPublicKey k1 = pgpKp.getPublicKey(); - + PGPPrivateKey k2 = pgpKp.getPrivateKey(); } @@ -626,7 +634,7 @@ public String getName() } public static void main( - String[] args) + String[] args) { Security.addProvider(new BouncyCastleProvider()); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPEncryptedDataTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPEncryptedDataTest.java index ac3943496e..ce51e6c065 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPEncryptedDataTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPEncryptedDataTest.java @@ -73,6 +73,7 @@ private void encryptDecryptTest() ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); BcPGPDataEncryptorBuilder encryptorBuilder = new BcPGPDataEncryptorBuilder(PGPEncryptedData.AES_128).setSecureRandom(new SecureRandom()); + encryptorBuilder.setUseV5AEAD(); encryptorBuilder.setWithAEAD(AEADAlgorithmTags.OCB, 10); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); @@ -138,6 +139,7 @@ private void encryptDecryptMultiChunkTest() ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); BcPGPDataEncryptorBuilder encryptorBuilder = new BcPGPDataEncryptorBuilder(PGPEncryptedData.AES_128).setSecureRandom(random); + encryptorBuilder.setUseV5AEAD(); encryptorBuilder.setWithAEAD(AEADAlgorithmTags.OCB, 6); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); @@ -204,6 +206,7 @@ private void encryptDecryptMultiChunkBoundaryTest() ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); BcPGPDataEncryptorBuilder encryptorBuilder = new BcPGPDataEncryptorBuilder(PGPEncryptedData.AES_128).setSecureRandom(random); + encryptorBuilder.setUseV5AEAD(); encryptorBuilder.setWithAEAD(AEADAlgorithmTags.OCB, 6); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPPBETest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPPBETest.java index ec7ebf2466..9da5273c73 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPPBETest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPPBETest.java @@ -334,7 +334,7 @@ public void performTest() // with integrity packet // cbOut = new ByteArrayOutputStream(); - cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(true).setSecureRandom(rand)); + cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(rand).setWithIntegrityPacket(true)); cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); @@ -413,7 +413,7 @@ public void performTest() comOut.close(); cbOut = new ByteArrayOutputStream(); - cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(true).setSecureRandom(rand)); + cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(rand).setWithIntegrityPacket(true)); cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); @@ -439,7 +439,7 @@ public void performTest() } tryAlgorithm(PGPEncryptedData.AES_128, text); - //tryAlgorithm(PGPEncryptedData.CAMELLIA_128, text); + tryAlgorithm(PGPEncryptedData.CAMELLIA_128, text); } private void tryAlgorithm(int algorithm, byte[] text) diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPRSATest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPRSATest.java index 76843a2bb4..8e29485b14 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPRSATest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/BcPGPRSATest.java @@ -79,209 +79,209 @@ public class BcPGPRSATest { byte[] testPubKey = Base64.decode( "mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F" - + "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO" - + "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F" - + "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4" - + "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG" - + "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc" - + "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs" - + "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrA=="); + + "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO" + + "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F" + + "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4" + + "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG" + + "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc" + + "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs" + + "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrA=="); byte[] testPrivKey = Base64.decode( "lQH8BD89pyQBBADk1aljL6mBOvd6k4Myr/0yaSI94SPC5WDwuptXZNM92wy8FVZP" - + "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x" - + "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D" - + "AwKbLeIOVYTEdWD5v/YgW8ERs0pDsSIfBTvsJp2qA798KeFuED6jGsHUzdi1M990" - + "6PRtplQgnoYmYQrzEc6DXAiAtBR4Kuxi4XHx0ZR2wpVlVxm2Ypgz7pbBNWcWqzvw" - + "33inl7tR4IDsRdJOY8cFlN+1tSCf16sDidtKXUVjRjZNYJytH18VfSPlGXMeYgtw" - + "3cSGNTERwKaq5E/SozT2MKTiORO0g0Mtyz+9MEB6XVXFavMun/mXURqbZN/k9BFb" - + "z+TadpkihrLD1xw3Hp+tpe4CwPQ2GdWKI9KNo5gEnbkJgLrSMGgWalPhknlNHRyY" - + "bSq6lbIMJEE3LoOwvYWwweR1+GrV9farJESdunl1mDr5/d6rKru+FFDwZM3na1IF" - + "4Ei4FpqhivZ4zG6pN5XqLy+AK85EiW4XH0yAKX1O4YlbmDU4BjxhiwTdwuVMCjLO" - + "5++jkz5BBQWdFX8CCMA4FJl36G70IbGzuFfOj07ly7QvRXJpYyBFY2hpZG5hICh0" - + "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb" - + "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO" - + "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN" - + "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1" - + "3V73K298L8Lz09habWaq7aJx/znc0/SXX6w="); + + "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x" + + "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D" + + "AwKbLeIOVYTEdWD5v/YgW8ERs0pDsSIfBTvsJp2qA798KeFuED6jGsHUzdi1M990" + + "6PRtplQgnoYmYQrzEc6DXAiAtBR4Kuxi4XHx0ZR2wpVlVxm2Ypgz7pbBNWcWqzvw" + + "33inl7tR4IDsRdJOY8cFlN+1tSCf16sDidtKXUVjRjZNYJytH18VfSPlGXMeYgtw" + + "3cSGNTERwKaq5E/SozT2MKTiORO0g0Mtyz+9MEB6XVXFavMun/mXURqbZN/k9BFb" + + "z+TadpkihrLD1xw3Hp+tpe4CwPQ2GdWKI9KNo5gEnbkJgLrSMGgWalPhknlNHRyY" + + "bSq6lbIMJEE3LoOwvYWwweR1+GrV9farJESdunl1mDr5/d6rKru+FFDwZM3na1IF" + + "4Ei4FpqhivZ4zG6pN5XqLy+AK85EiW4XH0yAKX1O4YlbmDU4BjxhiwTdwuVMCjLO" + + "5++jkz5BBQWdFX8CCMA4FJl36G70IbGzuFfOj07ly7QvRXJpYyBFY2hpZG5hICh0" + + "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb" + + "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO" + + "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN" + + "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1" + + "3V73K298L8Lz09habWaq7aJx/znc0/SXX6w="); byte[] testPubKeyV3 = Base64.decode( - "mQCNAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" - + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" - + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" - + "wdi2fBUJAAURtApGSVhDSVRZX1FBiQCVAwUQP7O+UZ6Fwdi2fBUJAQFMwwQA" - + "qRnFsdg4xQnB8Y5d4cOpXkIn9AZgYS3cxtuSJB84vG2CgC39nfv4c+nlLkWP" - + "4puG+mZuJNgVoE84cuAF4I//1anKjlU7q1M6rFQnt5S4uxPyG3dFXmgyU1b4" - + "PBOnA0tIxjPzlIhJAMsPCGGA5+5M2JP0ad6RnzqzE3EENMX+GqY="); + "mQCNAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" + + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" + + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" + + "wdi2fBUJAAURtApGSVhDSVRZX1FBiQCVAwUQP7O+UZ6Fwdi2fBUJAQFMwwQA" + + "qRnFsdg4xQnB8Y5d4cOpXkIn9AZgYS3cxtuSJB84vG2CgC39nfv4c+nlLkWP" + + "4puG+mZuJNgVoE84cuAF4I//1anKjlU7q1M6rFQnt5S4uxPyG3dFXmgyU1b4" + + "PBOnA0tIxjPzlIhJAMsPCGGA5+5M2JP0ad6RnzqzE3EENMX+GqY="); byte[] testPrivKeyV3 = Base64.decode( "lQHfAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" - + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" - + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" - + "wdi2fBUJAAURAXWwRBZQHNikA/f0ScLLjrXi4s0hgQecg+dkpDow94eu5+AR" - + "0DzZnfurpgfUJCNiDi5W/5c3Zj/xyrfMAgkbCgJ1m6FZqAQh7Mq73l7Kfu4/" - + "XIkyDF3tDgRuZNezB+JuElX10tV03xumHepp6M6CfhXqNJ15F33F99TA5hXY" - + "CPYD7SiSOpIhQkCOAgDAA63imxbpuKE2W7Y4I1BUHB7WQi8ZdkZd04njNTv+" - + "rFUuOPapQVfbWG0Vq8ld3YmJB4QWsa2mmqn+qToXbwufAgBpXkjvqK5yPiHF" - + "Px2QbFc1VqoCJB6PO5JRIqEiUZBFGdDlLxt3VSyqz7IZ/zEnxZq+tPCGGGSm" - + "/sAGiMvENcHVAfy0kTXU42TxEAYJyyNyqjXOobDJpEV1mKhFskRXt7tbMfOS" - + "Yf91oX8f6xw6O2Nal+hU8dS0Bmfmk5/enHmvRLHQocO0CkZJWENJVFlfUUE="); - - byte[] sig1 = Base64.decode( + + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" + + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" + + "wdi2fBUJAAURAXWwRBZQHNikA/f0ScLLjrXi4s0hgQecg+dkpDow94eu5+AR" + + "0DzZnfurpgfUJCNiDi5W/5c3Zj/xyrfMAgkbCgJ1m6FZqAQh7Mq73l7Kfu4/" + + "XIkyDF3tDgRuZNezB+JuElX10tV03xumHepp6M6CfhXqNJ15F33F99TA5hXY" + + "CPYD7SiSOpIhQkCOAgDAA63imxbpuKE2W7Y4I1BUHB7WQi8ZdkZd04njNTv+" + + "rFUuOPapQVfbWG0Vq8ld3YmJB4QWsa2mmqn+qToXbwufAgBpXkjvqK5yPiHF" + + "Px2QbFc1VqoCJB6PO5JRIqEiUZBFGdDlLxt3VSyqz7IZ/zEnxZq+tPCGGGSm" + + "/sAGiMvENcHVAfy0kTXU42TxEAYJyyNyqjXOobDJpEV1mKhFskRXt7tbMfOS" + + "Yf91oX8f6xw6O2Nal+hU8dS0Bmfmk5/enHmvRLHQocO0CkZJWENJVFlfUUE="); + + static byte[] sig1 = Base64.decode( "owGbwMvMwMRoGpHo9vfz52LGNTJJnBmpOTn5eiUVJfb23JvAHIXy/KKcFEWuToap" - + "zKwMIGG4Bqav0SwMy3yParsEKi2LMGI9xhh65sBxb05n5++ZLcWNJ/eLFKdWbm95" - + "tHbDV7GMwj/tUctUpFUXWPYFCLdNsDiVNuXbQvZtdXV/5xzY+9w1nCnijH9JoNiJ" - + "22n2jo0zo30/TZLo+jDl2vTzIvPeLEsPM3ZUE/1Ytqs4SG2TxIQbH7xf3uzcYXq2" - + "5Fw9AA=="); - + + "zKwMIGG4Bqav0SwMy3yParsEKi2LMGI9xhh65sBxb05n5++ZLcWNJ/eLFKdWbm95" + + "tHbDV7GMwj/tUctUpFUXWPYFCLdNsDiVNuXbQvZtdXV/5xzY+9w1nCnijH9JoNiJ" + + "22n2jo0zo30/TZLo+jDl2vTzIvPeLEsPM3ZUE/1Ytqs4SG2TxIQbH7xf3uzcYXq2" + + "5Fw9AA=="); + byte[] sig1crc = Base64.decode("+3i0"); - byte[] subKey = Base64.decode( + static byte[] subKey = Base64.decode( "lQH8BD89pyQBBADk1aljL6mBOvd6k4Myr/0yaSI94SPC5WDwuptXZNM92wy8FVZP" - + "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x" - + "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D" - + "AwKt6ZC7iqsQHGDNn2ZAuhS+ZwiFC+BToW9Vq6rwggWjgM/SThv55rfDk7keiXUT" - + "MyUcZVeYBe4Jttb4fAAm83hNztFu6Jvm9ITcm7YvnasBtVQjppaB+oYZgsTtwK99" - + "LGC3mdexnriCLxPN6tDFkGhzdOcYZfK6py4Ska8Dmq9nOZU9Qtv7Pm3qa5tuBvYw" - + "myTxeaJYifZTu/sky3Gj+REb8WonbgAJX/sLNBPUt+vYko+lxU8uqZpVEMU//hGG" - + "Rns2gIHdbSbIe1vGgIRUEd7Z0b7jfVQLUwqHDyfh5DGvAUhvtJogjUyFIXZzpU+E" - + "9ES9t7LZKdwNZSIdNUjM2eaf4g8BpuQobBVkj/GUcotKyeBjwvKxHlRefL4CCw28" - + "DO3SnLRKxd7uBSqeOGUKxqasgdekM/xIFOrJ85k7p89n6ncLQLHCPGVkzmVeRZro" - + "/T7zE91J57qBGZOUAP1vllcYLty1cs9PCc5oWnj3XbQvRXJpYyBFY2hpZG5hICh0" - + "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb" - + "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO" - + "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN" - + "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1" - + "3V73K298L8Lz09habWaq7aJx/znc0/SXX6y0JEVyaWMgRWNoaWRuYSA8ZXJpY0Bi" - + "b3VuY3ljYXN0bGUub3JnPoi4BBMBAgAiBQI/RxQNAhsDBQkAg9YABAsHAwIDFQID" - + "AxYCAQIeAQIXgAAKCRA1WGFG/fPzc3O6A/49tXFCiiP8vg77OXvnmbnzPBA1G6jC" - + "RZNP1yIXusOjpHqyLN5K9hw6lq/o4pNiCuiq32osqGRX3lv/nDduJU1kn2Ow+I2V" - + "ci+ojMXdCGdEqPwZfv47jHLwRrIUJ22OOoWsORtgvSeRUd4Izg8jruaFM7ufr5hr" - + "jEl1cuLW1Hr8Lp0B/AQ/RxxQAQQA0J2BIdqb8JtDGKjvYxrju0urJVVzyI1CnCjA" - + "p7CtLoHQJUQU7PajnV4Jd12ukfcoK7MRraYydQEjxh2MqPpuQgJS3dgQVrxOParD" - + "QYBFrZNd2tZxOjYakhErvUmRo6yWFaxChwqMgl8XWugBNg1Dva+/YcoGQ+ly+Jg4" - + "RWZoH88ABin+AwMCldD/2v8TyT1ghK70IuFs4MZBhdm6VgyGR8DQ/Ago6IAjA4BY" - + "Sol3lJb7+IIGsZaXwEuMRUvn6dWfa3r2I0p1t75vZb1Ng1YK32RZ5DNzl4Xb3L8V" - + "D+1Fiz9mHO8wiplAwDudB+RmQMlth3DNi/UsjeCTdEJAT+TTC7D40DiHDb1bR86Y" - + "2O5Y7MQ3SZs3/x0D/Ob6PStjfQ1kiqbruAMROKoavG0zVgxvspkoKN7h7BapnwJM" - + "6yf4qN/aByhAx9sFvADxu6z3SVcxiFw3IgAmabyWYb85LP8AsTYAG/HBoC6yob47" - + "Mt+GEDeyPifzzGXBWYIH4heZbSQivvA0eRwY5VZsMsBkbY5VR0FLVWgplbuO21bS" - + "rPS1T0crC+Zfj7FQBAkTfsg8RZQ8MPaHng01+gnFd243DDFvTAHygvm6a2X2fiRw" - + "5epAST4wWfY/BZNOxmfSKH6QS0oQMRscw79He6vGTB7vunLrKQYD4veInwQYAQIA" - + "CQUCP0ccUAIbDAAKCRA1WGFG/fPzczmFA/wMg5HhN5NkqmjnHUFfeXNXdHzmekyw" - + "38RnuCMKmfc43AiDs+FtJ62gpQ6PEsZF4o9S5fxcjVk3VSg00XMDtQ/0BsKBc5Gx" - + "hJTq7G+/SoeM433WG19uoS0+5Lf/31wNoTnpv6npOaYpcTQ7L9LCnzwAF4H0hJPE" - + "6bhmW2CMcsE/IZUB4QQ/Rwc1EQQAs5MUQlRiYOfi3fQ1OF6Z3eCwioDKu2DmOxot" - + "BICvdoG2muvs0KEBas9bbd0FJqc92FZJv8yxEgQbQtQAiFxoIFHRTFK+SPO/tQm+" - + "r83nwLRrfDeVVdRfzF79YCc+Abuh8sS/53H3u9Y7DYWr9IuMgI39nrVhY+d8yukf" - + "jo4OR+sAoKS/f7V1Xxj/Eqhb8qzf+N+zJRUlBACDd1eo/zFJZcq2YJa7a9vkViME" - + "axvwApqxeoU7oDpeHEMWg2DXJ7V24ZU5SbPTMY0x98cc8pcoqwsqux8xicWc0reh" - + "U3odQxWM4Se0LmEdca0nQOmNJlL9IsQ+QOJzx47qUOUAqhxnkXxQ/6B8w+M6gZya" - + "fwSdy70OumxESZipeQP+Lo9x6FcaW9L78hDX0aijJhgSEsnGODKB+bln29txX37E" - + "/a/Si+pyeLMi82kUdIL3G3I5HPWd3qSO4K94062+HfFj8bA20/1tbb/WxvxB2sKJ" - + "i3IobblFOvFHo+v8GaLdVyartp0JZLue/jP1dl9ctulSrIqaJT342uLsgTjsr2z+" - + "AwMCAyAU8Vo5AhhgFkDto8vQk7yxyRKEzu5qB66dRcTlaUPIiR8kamcy5ZTtujs4" - + "KIW4j2M/LvagrpWfV5+0M0VyaWMgRWNoaWRuYSAoRFNBIFRlc3QgS2V5KSA8ZXJp" - + "Y0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQI/Rwc1BAsHAwIDFQIDAxYCAQIe" - + "AQIXgAAKCRDNI/XpxMo0QwJcAJ40447eezSiIMspuzkwsMyFN8YBaQCdFTuZuT30" - + "CphiUYWnsC0mQ+J15B4="); - - byte[] enc1 = Base64.decode( + + "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x" + + "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D" + + "AwKt6ZC7iqsQHGDNn2ZAuhS+ZwiFC+BToW9Vq6rwggWjgM/SThv55rfDk7keiXUT" + + "MyUcZVeYBe4Jttb4fAAm83hNztFu6Jvm9ITcm7YvnasBtVQjppaB+oYZgsTtwK99" + + "LGC3mdexnriCLxPN6tDFkGhzdOcYZfK6py4Ska8Dmq9nOZU9Qtv7Pm3qa5tuBvYw" + + "myTxeaJYifZTu/sky3Gj+REb8WonbgAJX/sLNBPUt+vYko+lxU8uqZpVEMU//hGG" + + "Rns2gIHdbSbIe1vGgIRUEd7Z0b7jfVQLUwqHDyfh5DGvAUhvtJogjUyFIXZzpU+E" + + "9ES9t7LZKdwNZSIdNUjM2eaf4g8BpuQobBVkj/GUcotKyeBjwvKxHlRefL4CCw28" + + "DO3SnLRKxd7uBSqeOGUKxqasgdekM/xIFOrJ85k7p89n6ncLQLHCPGVkzmVeRZro" + + "/T7zE91J57qBGZOUAP1vllcYLty1cs9PCc5oWnj3XbQvRXJpYyBFY2hpZG5hICh0" + + "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb" + + "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO" + + "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN" + + "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1" + + "3V73K298L8Lz09habWaq7aJx/znc0/SXX6y0JEVyaWMgRWNoaWRuYSA8ZXJpY0Bi" + + "b3VuY3ljYXN0bGUub3JnPoi4BBMBAgAiBQI/RxQNAhsDBQkAg9YABAsHAwIDFQID" + + "AxYCAQIeAQIXgAAKCRA1WGFG/fPzc3O6A/49tXFCiiP8vg77OXvnmbnzPBA1G6jC" + + "RZNP1yIXusOjpHqyLN5K9hw6lq/o4pNiCuiq32osqGRX3lv/nDduJU1kn2Ow+I2V" + + "ci+ojMXdCGdEqPwZfv47jHLwRrIUJ22OOoWsORtgvSeRUd4Izg8jruaFM7ufr5hr" + + "jEl1cuLW1Hr8Lp0B/AQ/RxxQAQQA0J2BIdqb8JtDGKjvYxrju0urJVVzyI1CnCjA" + + "p7CtLoHQJUQU7PajnV4Jd12ukfcoK7MRraYydQEjxh2MqPpuQgJS3dgQVrxOParD" + + "QYBFrZNd2tZxOjYakhErvUmRo6yWFaxChwqMgl8XWugBNg1Dva+/YcoGQ+ly+Jg4" + + "RWZoH88ABin+AwMCldD/2v8TyT1ghK70IuFs4MZBhdm6VgyGR8DQ/Ago6IAjA4BY" + + "Sol3lJb7+IIGsZaXwEuMRUvn6dWfa3r2I0p1t75vZb1Ng1YK32RZ5DNzl4Xb3L8V" + + "D+1Fiz9mHO8wiplAwDudB+RmQMlth3DNi/UsjeCTdEJAT+TTC7D40DiHDb1bR86Y" + + "2O5Y7MQ3SZs3/x0D/Ob6PStjfQ1kiqbruAMROKoavG0zVgxvspkoKN7h7BapnwJM" + + "6yf4qN/aByhAx9sFvADxu6z3SVcxiFw3IgAmabyWYb85LP8AsTYAG/HBoC6yob47" + + "Mt+GEDeyPifzzGXBWYIH4heZbSQivvA0eRwY5VZsMsBkbY5VR0FLVWgplbuO21bS" + + "rPS1T0crC+Zfj7FQBAkTfsg8RZQ8MPaHng01+gnFd243DDFvTAHygvm6a2X2fiRw" + + "5epAST4wWfY/BZNOxmfSKH6QS0oQMRscw79He6vGTB7vunLrKQYD4veInwQYAQIA" + + "CQUCP0ccUAIbDAAKCRA1WGFG/fPzczmFA/wMg5HhN5NkqmjnHUFfeXNXdHzmekyw" + + "38RnuCMKmfc43AiDs+FtJ62gpQ6PEsZF4o9S5fxcjVk3VSg00XMDtQ/0BsKBc5Gx" + + "hJTq7G+/SoeM433WG19uoS0+5Lf/31wNoTnpv6npOaYpcTQ7L9LCnzwAF4H0hJPE" + + "6bhmW2CMcsE/IZUB4QQ/Rwc1EQQAs5MUQlRiYOfi3fQ1OF6Z3eCwioDKu2DmOxot" + + "BICvdoG2muvs0KEBas9bbd0FJqc92FZJv8yxEgQbQtQAiFxoIFHRTFK+SPO/tQm+" + + "r83nwLRrfDeVVdRfzF79YCc+Abuh8sS/53H3u9Y7DYWr9IuMgI39nrVhY+d8yukf" + + "jo4OR+sAoKS/f7V1Xxj/Eqhb8qzf+N+zJRUlBACDd1eo/zFJZcq2YJa7a9vkViME" + + "axvwApqxeoU7oDpeHEMWg2DXJ7V24ZU5SbPTMY0x98cc8pcoqwsqux8xicWc0reh" + + "U3odQxWM4Se0LmEdca0nQOmNJlL9IsQ+QOJzx47qUOUAqhxnkXxQ/6B8w+M6gZya" + + "fwSdy70OumxESZipeQP+Lo9x6FcaW9L78hDX0aijJhgSEsnGODKB+bln29txX37E" + + "/a/Si+pyeLMi82kUdIL3G3I5HPWd3qSO4K94062+HfFj8bA20/1tbb/WxvxB2sKJ" + + "i3IobblFOvFHo+v8GaLdVyartp0JZLue/jP1dl9ctulSrIqaJT342uLsgTjsr2z+" + + "AwMCAyAU8Vo5AhhgFkDto8vQk7yxyRKEzu5qB66dRcTlaUPIiR8kamcy5ZTtujs4" + + "KIW4j2M/LvagrpWfV5+0M0VyaWMgRWNoaWRuYSAoRFNBIFRlc3QgS2V5KSA8ZXJp" + + "Y0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQI/Rwc1BAsHAwIDFQIDAxYCAQIe" + + "AQIXgAAKCRDNI/XpxMo0QwJcAJ40447eezSiIMspuzkwsMyFN8YBaQCdFTuZuT30" + + "CphiUYWnsC0mQ+J15B4="); + + static byte[] enc1 = Base64.decode( "hIwDKwfQexPJboABA/4/7prhYYMORTiQ5avQKx0XYpCLujzGefYjnyuWZnx3Iev8" - + "Pmsguumm+OLLvtXhhkXQmkJRXbIg6Otj2ubPYWflRPgpJSgOrNOreOl5jeABOrtw" - + "bV6TJb9OTtZuB7cTQSCq2gmYiSZkluIiDjNs3R3mEanILbYzOQ3zKSggKpzlv9JQ" - + "AZUqTyDyJ6/OUbJF5fI5uiv76DCsw1zyMWotUIu5/X01q+AVP5Ly3STzI7xkWg/J" - + "APz4zUHism7kSYz2viAQaJx9/bNnH3AM6qm1Fuyikl4="); + + "Pmsguumm+OLLvtXhhkXQmkJRXbIg6Otj2ubPYWflRPgpJSgOrNOreOl5jeABOrtw" + + "bV6TJb9OTtZuB7cTQSCq2gmYiSZkluIiDjNs3R3mEanILbYzOQ3zKSggKpzlv9JQ" + + "AZUqTyDyJ6/OUbJF5fI5uiv76DCsw1zyMWotUIu5/X01q+AVP5Ly3STzI7xkWg/J" + + "APz4zUHism7kSYz2viAQaJx9/bNnH3AM6qm1Fuyikl4="); byte[] enc1crc = Base64.decode("lv4o"); - + byte[] enc2 = Base64.decode( - "hIwDKwfQexPJboABBAC62jcJH8xKnKb1neDVmiovYON04+7VQ2v4BmeHwJrdag1g" - + "Ya++6PeBlQ2Q9lSGBwLobVuJmQ7cOnPUJP727JeSGWlMyFtMbBSHekOaTenT5lj7" - + "Zk7oRHxMp/hByzlMacIDzOn8LPSh515RHM57eDLCOwqnAxGQwk67GRl8f5dFH9JQ" - + "Aa7xx8rjCqPbiIQW6t5LqCNvPZOiSCmftll6+se1XJhFEuq8WS4nXtPfTiJ3vib4" - + "3soJdHzGB6AOs+BQ6aKmmNTVAxa5owhtSt1Z/6dfSSk="); - - byte[] subPubKey = Base64.decode( - "mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F" - + "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO" - + "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F" - + "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4" - + "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG" - + "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc" - + "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs" - + "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrIhMBBARAgAM" - + "BQI/RxooBYMAemL8AAoJEM0j9enEyjRDiBgAn3RcLK+gq90PvnQFTw2DNqdq7KA0" - + "AKCS0EEIXCzbV1tfTdCUJ3hVh3btF7QkRXJpYyBFY2hpZG5hIDxlcmljQGJvdW5j" - + "eWNhc3RsZS5vcmc+iLgEEwECACIFAj9HFA0CGwMFCQCD1gAECwcDAgMVAgMDFgIB" - + "Ah4BAheAAAoJEDVYYUb98/Nzc7oD/j21cUKKI/y+Dvs5e+eZufM8EDUbqMJFk0/X" - + "Ihe6w6OkerIs3kr2HDqWr+jik2IK6KrfaiyoZFfeW/+cN24lTWSfY7D4jZVyL6iM" - + "xd0IZ0So/Bl+/juMcvBGshQnbY46haw5G2C9J5FR3gjODyOu5oUzu5+vmGuMSXVy" - + "4tbUevwuiEwEEBECAAwFAj9HGigFgwB6YvwACgkQzSP16cTKNEPwBQCdHm0Amwza" - + "NmVmDHm3rmqI7rp2oQ0An2YbiP/H/kmBNnmTeH55kd253QOhuIsEP0ccUAEEANCd" - + "gSHam/CbQxio72Ma47tLqyVVc8iNQpwowKewrS6B0CVEFOz2o51eCXddrpH3KCuz" - + "Ea2mMnUBI8YdjKj6bkICUt3YEFa8Tj2qw0GARa2TXdrWcTo2GpIRK71JkaOslhWs" - + "QocKjIJfF1roATYNQ72vv2HKBkPpcviYOEVmaB/PAAYpiJ8EGAECAAkFAj9HHFAC" - + "GwwACgkQNVhhRv3z83M5hQP8DIOR4TeTZKpo5x1BX3lzV3R85npMsN/EZ7gjCpn3" - + "ONwIg7PhbSetoKUOjxLGReKPUuX8XI1ZN1UoNNFzA7UP9AbCgXORsYSU6uxvv0qH" - + "jON91htfbqEtPuS3/99cDaE56b+p6TmmKXE0Oy/Swp88ABeB9ISTxOm4ZltgjHLB" - + "PyGZAaIEP0cHNREEALOTFEJUYmDn4t30NThemd3gsIqAyrtg5jsaLQSAr3aBtprr" - + "7NChAWrPW23dBSanPdhWSb/MsRIEG0LUAIhcaCBR0UxSvkjzv7UJvq/N58C0a3w3" - + "lVXUX8xe/WAnPgG7ofLEv+dx97vWOw2Fq/SLjICN/Z61YWPnfMrpH46ODkfrAKCk" - + "v3+1dV8Y/xKoW/Ks3/jfsyUVJQQAg3dXqP8xSWXKtmCWu2vb5FYjBGsb8AKasXqF" - + "O6A6XhxDFoNg1ye1duGVOUmz0zGNMffHHPKXKKsLKrsfMYnFnNK3oVN6HUMVjOEn" - + "tC5hHXGtJ0DpjSZS/SLEPkDic8eO6lDlAKocZ5F8UP+gfMPjOoGcmn8Encu9Drps" - + "REmYqXkD/i6PcehXGlvS+/IQ19GooyYYEhLJxjgygfm5Z9vbcV9+xP2v0ovqcniz" - + "IvNpFHSC9xtyORz1nd6kjuCveNOtvh3xY/GwNtP9bW2/1sb8QdrCiYtyKG25RTrx" - + "R6Pr/Bmi3Vcmq7adCWS7nv4z9XZfXLbpUqyKmiU9+Nri7IE47K9stDNFcmljIEVj" - + "aGlkbmEgKERTQSBUZXN0IEtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IWQQT" - + "EQIAGQUCP0cHNQQLBwMCAxUCAwMWAgECHgECF4AACgkQzSP16cTKNEMCXACfauui" - + "bSwyG59Yrm8hHCDuCPmqwsQAni+dPl08FVuWh+wb6kOgJV4lcYae"); - - byte[] subPubCrc = Base64.decode("rikt"); - - byte[] pgp8Key = Base64.decode( - "lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF" - + "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd" - + "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy" - + "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y" - + "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7" - + "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO" - + "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP" - + "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY" - + "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb" - + "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4" - + "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj" - + "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I" - + "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH" - + "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt" - + "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j" - + "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw" - + "AgAA"); - - char[] pgp8Pass = "2002 Buffalo Sabres".toCharArray(); - - char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; - - byte[] fingerprintKey = Base64.decode( - "mQEPA0CiJdUAAAEIAMI+znDlPd2kQoEcnxqxLcRz56Z7ttFKHpnYp0UkljZdquVc" - + "By1jMfXGVV64xN1IvMcyenLXUE0IUeUBCQs6tHunFRAPSeCxJ3FdFe1B5MpqQG8A" - + "BnEpAds/hAUfRDZD5y/lolk1hjvFMrRh6WXckaA/QQ2t00NmTrJ1pYUpkw9tnVQb" - + "LUjWJhfZDBBcN0ADtATzgkugxMtcDxR6I5x8Ndn+IilqIm23kxGIcmMd/BHOec4c" - + "jRwJXXDb7u8tl+2knAf9cwhPHp3+Zy4uGSQPdzQnXOhBlA+4WDa0RROOevWgq8uq" - + "8/9Xp/OlTVL+OoIzjsI6mJP1Joa4qmqAnaHAmXcAEQEAAbQoQk9BM1JTS1kgPEJP" - + "QSBNb25pdG9yaW5nIEAgODg4LTI2OS01MjY2PokBFQMFEECiJdWqaoCdocCZdwEB" - + "0RsH/3HPxoUZ3G3K7T3jgOnJUckTSHWU3XspHzMVgqOxjTrcexi5IsAM5M+BulfW" - + "T2aO+Kqf5w8cKTKgW02DNpHUiPjHx0nzDE+Do95zbIErGeK+Twkc4O/aVsvU9GGO" - + "81VFI6WMvDQ4CUAUnAdk03MRrzI2nAuhn4NJ5LQS+uJrnqUJ4HmFAz6CQZQKd/kS" - + "Xgq+A6i7aI1LG80YxWa9ooQgaCrb9dwY/kPQ+yC22zQ3FExtv+Fv3VtAKTilO3vn" - + "BA4Y9uTHuObHfI+1yxUS2PrlRUX0m48ZjpIX+cEN3QblGBJudI/A1QSd6P0LZeBr" - + "7F1Z1aF7ZDo0KzgiAIBvgXkeTpw="); + "hIwDKwfQexPJboABBAC62jcJH8xKnKb1neDVmiovYON04+7VQ2v4BmeHwJrdag1g" + + "Ya++6PeBlQ2Q9lSGBwLobVuJmQ7cOnPUJP727JeSGWlMyFtMbBSHekOaTenT5lj7" + + "Zk7oRHxMp/hByzlMacIDzOn8LPSh515RHM57eDLCOwqnAxGQwk67GRl8f5dFH9JQ" + + "Aa7xx8rjCqPbiIQW6t5LqCNvPZOiSCmftll6+se1XJhFEuq8WS4nXtPfTiJ3vib4" + + "3soJdHzGB6AOs+BQ6aKmmNTVAxa5owhtSt1Z/6dfSSk="); + + byte[] subPubKey = Base64.decode( + "mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F" + + "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO" + + "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F" + + "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4" + + "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG" + + "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc" + + "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs" + + "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrIhMBBARAgAM" + + "BQI/RxooBYMAemL8AAoJEM0j9enEyjRDiBgAn3RcLK+gq90PvnQFTw2DNqdq7KA0" + + "AKCS0EEIXCzbV1tfTdCUJ3hVh3btF7QkRXJpYyBFY2hpZG5hIDxlcmljQGJvdW5j" + + "eWNhc3RsZS5vcmc+iLgEEwECACIFAj9HFA0CGwMFCQCD1gAECwcDAgMVAgMDFgIB" + + "Ah4BAheAAAoJEDVYYUb98/Nzc7oD/j21cUKKI/y+Dvs5e+eZufM8EDUbqMJFk0/X" + + "Ihe6w6OkerIs3kr2HDqWr+jik2IK6KrfaiyoZFfeW/+cN24lTWSfY7D4jZVyL6iM" + + "xd0IZ0So/Bl+/juMcvBGshQnbY46haw5G2C9J5FR3gjODyOu5oUzu5+vmGuMSXVy" + + "4tbUevwuiEwEEBECAAwFAj9HGigFgwB6YvwACgkQzSP16cTKNEPwBQCdHm0Amwza" + + "NmVmDHm3rmqI7rp2oQ0An2YbiP/H/kmBNnmTeH55kd253QOhuIsEP0ccUAEEANCd" + + "gSHam/CbQxio72Ma47tLqyVVc8iNQpwowKewrS6B0CVEFOz2o51eCXddrpH3KCuz" + + "Ea2mMnUBI8YdjKj6bkICUt3YEFa8Tj2qw0GARa2TXdrWcTo2GpIRK71JkaOslhWs" + + "QocKjIJfF1roATYNQ72vv2HKBkPpcviYOEVmaB/PAAYpiJ8EGAECAAkFAj9HHFAC" + + "GwwACgkQNVhhRv3z83M5hQP8DIOR4TeTZKpo5x1BX3lzV3R85npMsN/EZ7gjCpn3" + + "ONwIg7PhbSetoKUOjxLGReKPUuX8XI1ZN1UoNNFzA7UP9AbCgXORsYSU6uxvv0qH" + + "jON91htfbqEtPuS3/99cDaE56b+p6TmmKXE0Oy/Swp88ABeB9ISTxOm4ZltgjHLB" + + "PyGZAaIEP0cHNREEALOTFEJUYmDn4t30NThemd3gsIqAyrtg5jsaLQSAr3aBtprr" + + "7NChAWrPW23dBSanPdhWSb/MsRIEG0LUAIhcaCBR0UxSvkjzv7UJvq/N58C0a3w3" + + "lVXUX8xe/WAnPgG7ofLEv+dx97vWOw2Fq/SLjICN/Z61YWPnfMrpH46ODkfrAKCk" + + "v3+1dV8Y/xKoW/Ks3/jfsyUVJQQAg3dXqP8xSWXKtmCWu2vb5FYjBGsb8AKasXqF" + + "O6A6XhxDFoNg1ye1duGVOUmz0zGNMffHHPKXKKsLKrsfMYnFnNK3oVN6HUMVjOEn" + + "tC5hHXGtJ0DpjSZS/SLEPkDic8eO6lDlAKocZ5F8UP+gfMPjOoGcmn8Encu9Drps" + + "REmYqXkD/i6PcehXGlvS+/IQ19GooyYYEhLJxjgygfm5Z9vbcV9+xP2v0ovqcniz" + + "IvNpFHSC9xtyORz1nd6kjuCveNOtvh3xY/GwNtP9bW2/1sb8QdrCiYtyKG25RTrx" + + "R6Pr/Bmi3Vcmq7adCWS7nv4z9XZfXLbpUqyKmiU9+Nri7IE47K9stDNFcmljIEVj" + + "aGlkbmEgKERTQSBUZXN0IEtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IWQQT" + + "EQIAGQUCP0cHNQQLBwMCAxUCAwMWAgECHgECF4AACgkQzSP16cTKNEMCXACfauui" + + "bSwyG59Yrm8hHCDuCPmqwsQAni+dPl08FVuWh+wb6kOgJV4lcYae"); + + byte[] subPubCrc = Base64.decode("rikt"); + + byte[] pgp8Key = Base64.decode( + "lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF" + + "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd" + + "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy" + + "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y" + + "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7" + + "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO" + + "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP" + + "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY" + + "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb" + + "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4" + + "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj" + + "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I" + + "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH" + + "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt" + + "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j" + + "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw" + + "AgAA"); + + char[] pgp8Pass = "2002 Buffalo Sabres".toCharArray(); + + char[] pass = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'}; + + byte[] fingerprintKey = Base64.decode( + "mQEPA0CiJdUAAAEIAMI+znDlPd2kQoEcnxqxLcRz56Z7ttFKHpnYp0UkljZdquVc" + + "By1jMfXGVV64xN1IvMcyenLXUE0IUeUBCQs6tHunFRAPSeCxJ3FdFe1B5MpqQG8A" + + "BnEpAds/hAUfRDZD5y/lolk1hjvFMrRh6WXckaA/QQ2t00NmTrJ1pYUpkw9tnVQb" + + "LUjWJhfZDBBcN0ADtATzgkugxMtcDxR6I5x8Ndn+IilqIm23kxGIcmMd/BHOec4c" + + "jRwJXXDb7u8tl+2knAf9cwhPHp3+Zy4uGSQPdzQnXOhBlA+4WDa0RROOevWgq8uq" + + "8/9Xp/OlTVL+OoIzjsI6mJP1Joa4qmqAnaHAmXcAEQEAAbQoQk9BM1JTS1kgPEJP" + + "QSBNb25pdG9yaW5nIEAgODg4LTI2OS01MjY2PokBFQMFEECiJdWqaoCdocCZdwEB" + + "0RsH/3HPxoUZ3G3K7T3jgOnJUckTSHWU3XspHzMVgqOxjTrcexi5IsAM5M+BulfW" + + "T2aO+Kqf5w8cKTKgW02DNpHUiPjHx0nzDE+Do95zbIErGeK+Twkc4O/aVsvU9GGO" + + "81VFI6WMvDQ4CUAUnAdk03MRrzI2nAuhn4NJ5LQS+uJrnqUJ4HmFAz6CQZQKd/kS" + + "Xgq+A6i7aI1LG80YxWa9ooQgaCrb9dwY/kPQ+yC22zQ3FExtv+Fv3VtAKTilO3vn" + + "BA4Y9uTHuObHfI+1yxUS2PrlRUX0m48ZjpIX+cEN3QblGBJudI/A1QSd6P0LZeBr" + + "7F1Z1aF7ZDo0KzgiAIBvgXkeTpw="); byte[] fingerprintCheck = Base64.decode("CTv2"); - byte[] expiry60and30daysSig13Key = Base64.decode( - "mQGiBENZt/URBAC5JccXiwe4g6MuviEC8NI/x0NaVkGFAOY04d5E4jeIycBP" + byte[] expiry60and30daysSig13Key = Base64.decode( + "mQGiBENZt/URBAC5JccXiwe4g6MuviEC8NI/x0NaVkGFAOY04d5E4jeIycBP" + "SrpOPrjETuigqhrj8oqed2+2yUqfnK4nhTsTAjyeJ3PpWC1pGAKzJgYmJk+K" + "9aTLq0BQWiXDdv5RG6fDmeq1umvOfcXBqGFAguLPZC+U872bSLnfe3lqGNA8" + "jvmY7wCgjhzVQVm10NN5ST8nemPEcSjnBrED/R494gHL6+r5OgUgXnNCDejA" @@ -302,114 +302,119 @@ public class BcPGPRSATest + "7YymCfhm1yJiuFQg3qiX6Z4An19OSEgeSKugVcH49g1sxUB0zNdIsAIAAw=="); byte[] jpegImage = Base64.decode( - "/9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAAAAgAAAAAAAD/2wBDAAUDBAQEAwUE" - + "BAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/" - + "wAALCAA6AFABASIA/8QAHAAAAgMAAwEAAAAAAAAAAAAABQcABAYBAggD/8QAMRAAAgEDBAEDAwME" - + "AQUAAAAAAQIDBAURAAYSITEHIkETFFEjYXEVMkKRCCUzQ4Gh/9oACAEBAAA/APX1TdKCmlaOoqoo" - + "WXzzbiP9nWaS71lXuA2tqrgopBOxpyGyWLAEEd4GAf3+fOjLPXoVaOcNzYAhl8HskADwAPz37f3z" - + "opSvI9Mjypwcr7l/B1XuFwSmoTVooljB9xDYAH51Vor191F9dKGb6Py3yo4huwcHwf8AYP7ZLIyu" - + "gZSGBGQQejrnU1NKn1EqVi3sZJOBCwxxIp9xzksfb5PR+Mdga+ljqIKje1TNBBNToYYgU4477HwQ" - + "Bn9z8/nW6mqxLR0NzpJkMLx8lJUkOGAIx4I/0f41lJ93UkkrRxVKvNKVjZfpSe6RyqhCp7wCSD89" - + "EEDRWppEkgqKdYohGcoZAjAlSMMcZ+PHH/3odsG6VLW2qaoqV+nTyFZpHOFQL0Sc9ADGTnHWtZap" - + "EpoamJm/TgYkfgJ5H/zGuKieVJIGkqCgmfCJFFy64s3Z+Oh58fHyNfGavipIJ2BrZcKXA+mzEd9Y" - + "OCcHI/gDV62SzvBGKhQHaNWzj8jvP750oN/xM3qkshLPEstOhj7IVyvkY+f7Nd7hf9vbc9QbVb7n" - + "dadLldqc00FMCwlmZnCrgL2v/cAySPBPwSD+/wC+3HbWx3rLbaqW81CVHOWnetMZjRm9h7VvClcj" - + "oDB7PymPTvem+a6roxvC10sd3ScmlucdEyUtRADxdice9wY3PQGRgj4OnHU3u5RW+op6imo4q+KA" - + "1UKGQ/bzrnt0biWxkgFOJK9ZyCCVX6f3T1Rh9RawbltdQNv18CGe2wxBDQyvGrowIJd15HEnHvP+" - + "OBjXoGzS0tNTpQipFTIw48Xn5SSBVUMw5e5wMgZ/j86yVNvvZ9TeDR1c9XSV0bl443dmYZXiCSCR" - + "jvxkjR1L1b46iWpStpIRLOWkCqyniP8AJjxPIniBjr+etFdu11DVu321WZiFHRjZcA/gsO+seNYf" - + "fVpq6n1Eo5KNATIYmb5Bx7csP4z/AKz8aX1N6Q7W3FuWWrS1TRzi+tXSutUESQhCGiVAvJVRgfcc" - + "HkeidM6tSmTbps9RHIH4KoqC8j/VC8R0+CSScZLdknPZGgNfYpUUUzfewxxcWpopWbhL715KgBIQ" - + "MCQc4A84+dD963X7ywQ0NIVW60qqzkzIfoszAMGUNyUHORkDrHxo3sSaOhtX2hnp3uNRF9b7hqtO" - + "DxM3Rcj3dMCPHXLGfOkLuPddp9R/ViOa62KppqK3Vctvsz0UylKtWfgXy3+L8WIZFBGRhs407rTT" - + "bcuFDRWmtsNGIZ1MMEU9GPqRorKPcJEzhich8Anz350Wk2zs2OsT7D7RZJpChMEk0MoypJZWVwM9" - + "ZzjWw2lbKaioFjQy/U9shLyu7Esi5JLEnsgnQlaSqhqayWSRZ5JaiSSNPoBCiq54jPuJyA2W+QfA" - + "+FrSXq4bdulZHRpWRzpArPK0SSNUExh14qB4c5X9ipz41Zud0juVouVooHN6rrZKVaoek/VhYgqE" - + "4v7cZPTfPHwT7tZX0e2NVUV5rK2ku9TeY6aFZJ6GuLALKzNnizE4CsqHIyBxJCk4AYFNt2wSUExm" - + "pP1lqgq1zkfXUtIgkiOFHQCsCM/kfOtZU7GsNZU1FFc1lrqCSNSlFOQ8SJk8kC4/tJx1rMwbWt0V" - + "CW21VW+krVoFTCRrPC0bf+NF8ocqMcT/AIg6EVF5/p9U6zPXLVFGpoKlSpMiEkniSCcqVY+eQIPW" - + "NULf/UNxJNS0dhklu8SK9Lco6pUcEr0JOu1HQ7z+R5OndaI5leWV0VQ54kA5KlWIx/Gqd2t6vcqe" - + "FIXNJMs71SoCMsQuG5jsN8AAjyTnrGlt6mVlqswtS0SG71NTXpSiCQFpogckll6Y4wvyD/OToVd7" - + "3tLedda4Nr3iRK2mqJhW1K0qxSSGJf1OTOAwwVADLkA9fPV2W77msVfPTClNRUyJCla0SqS5dR5J" - + "b2kluKlQc5BbHnWu2xTS0G4qmjvSq6RwrPHJUMHkkYDhzJHXIhmBAHnxpaL6j3il3D6g1VLuSz1k" - + "1ht//S6SZQ4KoTI6MyMOb9hR85HedM/0wqn3RsC0bhgq/pQV9J9WELEFaNWGARg+04xkd95xjQTe" - + "df6c7U+ysl3mtMFJe5JYGkkmAVKgKZCZGzlVbBySemA/OgvpZUQxvaqitgoqSsiX6XKh5RwVCBP0" - + "8KCTIoU8VJyDjIA8Bs2e5CprDTR8VXi8pRgyyZMh8qQMDHz850ZOlVv30RsW5blcL5S3a626+1cq" - + "TirFQ0qJIgAQCNjgIMeFKn9wQCMA3o2vprca/ctp29Jv6/3aoZ4IRRx08dC5D8nWQv7FJYHByeuv" - + "zo5SWn1Z2ttahutFZqbcG6JK5ZLu1TNEzzUq5ASNyVw6pxUMc5Oc5znR6KyXffldUVW4rBcbAqos" - + "EUq1qrUzUkwy8bFB+m4ZI2IBbAJAbOdau0+nmybJYqe027atvNHTRlYomhVz+Tln8knyScn50j/+" - + "SOyd3VO2oDtmPcNPYqJgDt23xKtOIiTy6gYO/Z5YOcAHGsJ/x39NgbzuDc+0bNt6/wAySmltbXGv" - + "flaT8ST07xBjIR30RjsL+dex9uwT/wBKo6i5UtPFdHp4/u/pgECTiOQDYBIByB+w0RVEVmZUUM39" - + "xA7P867ampqampqaq09BQwV9RWwUVNFU1AUTTJEoeQLnHJgMnGTjP51a1Nf/2Q=="); + "/9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAAAAgAAAAAAAD/2wBDAAUDBAQEAwUE" + + "BAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/" + + "wAALCAA6AFABASIA/8QAHAAAAgMAAwEAAAAAAAAAAAAABQcABAYBAggD/8QAMRAAAgEDBAEDAwME" + + "AQUAAAAAAQIDBAURAAYSITEHIkETFFEjYXEVMkKRCCUzQ4Gh/9oACAEBAAA/APX1TdKCmlaOoqoo" + + "WXzzbiP9nWaS71lXuA2tqrgopBOxpyGyWLAEEd4GAf3+fOjLPXoVaOcNzYAhl8HskADwAPz37f3z" + + "opSvI9Mjypwcr7l/B1XuFwSmoTVooljB9xDYAH51Vor191F9dKGb6Py3yo4huwcHwf8AYP7ZLIyu" + + "gZSGBGQQejrnU1NKn1EqVi3sZJOBCwxxIp9xzksfb5PR+Mdga+ljqIKje1TNBBNToYYgU4477HwQ" + + "Bn9z8/nW6mqxLR0NzpJkMLx8lJUkOGAIx4I/0f41lJ93UkkrRxVKvNKVjZfpSe6RyqhCp7wCSD89" + + "EEDRWppEkgqKdYohGcoZAjAlSMMcZ+PHH/3odsG6VLW2qaoqV+nTyFZpHOFQL0Sc9ADGTnHWtZap" + + "EpoamJm/TgYkfgJ5H/zGuKieVJIGkqCgmfCJFFy64s3Z+Oh58fHyNfGavipIJ2BrZcKXA+mzEd9Y" + + "OCcHI/gDV62SzvBGKhQHaNWzj8jvP750oN/xM3qkshLPEstOhj7IVyvkY+f7Nd7hf9vbc9QbVb7n" + + "dadLldqc00FMCwlmZnCrgL2v/cAySPBPwSD+/wC+3HbWx3rLbaqW81CVHOWnetMZjRm9h7VvClcj" + + "oDB7PymPTvem+a6roxvC10sd3ScmlucdEyUtRADxdice9wY3PQGRgj4OnHU3u5RW+op6imo4q+KA" + + "1UKGQ/bzrnt0biWxkgFOJK9ZyCCVX6f3T1Rh9RawbltdQNv18CGe2wxBDQyvGrowIJd15HEnHvP+" + + "OBjXoGzS0tNTpQipFTIw48Xn5SSBVUMw5e5wMgZ/j86yVNvvZ9TeDR1c9XSV0bl443dmYZXiCSCR" + + "jvxkjR1L1b46iWpStpIRLOWkCqyniP8AJjxPIniBjr+etFdu11DVu321WZiFHRjZcA/gsO+seNYf" + + "fVpq6n1Eo5KNATIYmb5Bx7csP4z/AKz8aX1N6Q7W3FuWWrS1TRzi+tXSutUESQhCGiVAvJVRgfcc" + + "HkeidM6tSmTbps9RHIH4KoqC8j/VC8R0+CSScZLdknPZGgNfYpUUUzfewxxcWpopWbhL715KgBIQ" + + "MCQc4A84+dD963X7ywQ0NIVW60qqzkzIfoszAMGUNyUHORkDrHxo3sSaOhtX2hnp3uNRF9b7hqtO" + + "DxM3Rcj3dMCPHXLGfOkLuPddp9R/ViOa62KppqK3Vctvsz0UylKtWfgXy3+L8WIZFBGRhs407rTT" + + "bcuFDRWmtsNGIZ1MMEU9GPqRorKPcJEzhich8Anz350Wk2zs2OsT7D7RZJpChMEk0MoypJZWVwM9" + + "ZzjWw2lbKaioFjQy/U9shLyu7Esi5JLEnsgnQlaSqhqayWSRZ5JaiSSNPoBCiq54jPuJyA2W+QfA" + + "+FrSXq4bdulZHRpWRzpArPK0SSNUExh14qB4c5X9ipz41Zud0juVouVooHN6rrZKVaoek/VhYgqE" + + "4v7cZPTfPHwT7tZX0e2NVUV5rK2ku9TeY6aFZJ6GuLALKzNnizE4CsqHIyBxJCk4AYFNt2wSUExm" + + "pP1lqgq1zkfXUtIgkiOFHQCsCM/kfOtZU7GsNZU1FFc1lrqCSNSlFOQ8SJk8kC4/tJx1rMwbWt0V" + + "CW21VW+krVoFTCRrPC0bf+NF8ocqMcT/AIg6EVF5/p9U6zPXLVFGpoKlSpMiEkniSCcqVY+eQIPW" + + "NULf/UNxJNS0dhklu8SK9Lco6pUcEr0JOu1HQ7z+R5OndaI5leWV0VQ54kA5KlWIx/Gqd2t6vcqe" + + "FIXNJMs71SoCMsQuG5jsN8AAjyTnrGlt6mVlqswtS0SG71NTXpSiCQFpogckll6Y4wvyD/OToVd7" + + "3tLedda4Nr3iRK2mqJhW1K0qxSSGJf1OTOAwwVADLkA9fPV2W77msVfPTClNRUyJCla0SqS5dR5J" + + "b2kluKlQc5BbHnWu2xTS0G4qmjvSq6RwrPHJUMHkkYDhzJHXIhmBAHnxpaL6j3il3D6g1VLuSz1k" + + "1ht//S6SZQ4KoTI6MyMOb9hR85HedM/0wqn3RsC0bhgq/pQV9J9WELEFaNWGARg+04xkd95xjQTe" + + "df6c7U+ysl3mtMFJe5JYGkkmAVKgKZCZGzlVbBySemA/OgvpZUQxvaqitgoqSsiX6XKh5RwVCBP0" + + "8KCTIoU8VJyDjIA8Bs2e5CprDTR8VXi8pRgyyZMh8qQMDHz850ZOlVv30RsW5blcL5S3a626+1cq" + + "TirFQ0qJIgAQCNjgIMeFKn9wQCMA3o2vprca/ctp29Jv6/3aoZ4IRRx08dC5D8nWQv7FJYHByeuv" + + "zo5SWn1Z2ttahutFZqbcG6JK5ZLu1TNEzzUq5ASNyVw6pxUMc5Oc5znR6KyXffldUVW4rBcbAqos" + + "EUq1qrUzUkwy8bFB+m4ZI2IBbAJAbOdau0+nmybJYqe027atvNHTRlYomhVz+Tln8knyScn50j/+" + + "SOyd3VO2oDtmPcNPYqJgDt23xKtOIiTy6gYO/Z5YOcAHGsJ/x39NgbzuDc+0bNt6/wAySmltbXGv" + + "flaT8ST07xBjIR30RjsL+dex9uwT/wBKo6i5UtPFdHp4/u/pgECTiOQDYBIByB+w0RVEVmZUUM39" + + "xA7P867ampqampqaq09BQwV9RWwUVNFU1AUTTJEoeQLnHJgMnGTjP51a1Nf/2Q=="); byte[] embeddedJPEGKey = Base64.decode( - "mI0ER0JXuwEEAKNqsXwLU6gu6P2Q/HJqEJVt3A7Kp1yucn8HWVeJF9JLAKVjVU8jrvz9Bw4NwaRJ" - + "NGYEAgdRq8Hx3WP9FXFCIVfCdi+oQrphcHWzzBFul8sykUGT+LmcBdqQGU9WaWSJyCOmUht4j7t0" - + "zk/IXX0YxGmkqR+no5rTj9LMDG8AQQrFABEBAAG0P0VyaWMgSCBFY2hpZG5hIChpbWFnZSB0ZXN0" - + "IGtleSkgPGVyaWMuZWNoaWRuYUBib3VuY3ljYXN0bGUub3JnPoi2BBMBAgAgBQJHQle7AhsDBgsJ" - + "CAcDAgQVAggDBBYCAwECHgECF4AACgkQ1+RWqFFpjMTKtgP+Okqkn0gVpQyNYXM/hWX6f3UQcyXk" - + "2Sd/fWW0XG+LBjhhBo+lXRWK0uYF8OMdZwsSl9HimpgYD5/kNs0Seh417DioP1diOgxkgezyQgMa" - + "+ODZfNnIvVaBr1pHLPLeqIBxBVMWBfa4wDXnLLGu8018uvI2yBhz5vByB1ntxwgKMXCwAgAD0cf3" - + "x/UBEAABAQAAAAAAAAAAAAAAAP/Y/+AAEEpGSUYAAQEBAEgASAAA/+EAFkV4aWYAAE1NACoAAAAI" - + "AAAAAAAA/9sAQwAFAwQEBAMFBAQEBQUFBgcMCAcHBwcPCwsJDBEPEhIRDxERExYcFxMUGhURERgh" - + "GBodHR8fHxMXIiQiHiQcHh8e/8AACwgAOgBQAQEiAP/EABwAAAIDAAMBAAAAAAAAAAAAAAUHAAQG" - + "AQIIA//EADEQAAIBAwQBAwMDBAEFAAAAAAECAwQFEQAGEiExByJBExRRI2FxFTJCkQglM0OBof/a" - + "AAgBAQAAPwD19U3SgppWjqKqKFl8824j/Z1mku9ZV7gNraq4KKQTsachsliwBBHeBgH9/nzoyz16" - + "FWjnDc2AIZfB7JAA8AD89+3986KUryPTI8qcHK+5fwdV7hcEpqE1aKJYwfcQ2AB+dVaK9fdRfXSh" - + "m+j8t8qOIbsHB8H/AGD+2SyMroGUhgRkEHo651NTSp9RKlYt7GSTgQsMcSKfcc5LH2+T0fjHYGvp" - + "Y6iCo3tUzQQTU6GGIFOOO+x8EAZ/c/P51upqsS0dDc6SZDC8fJSVJDhgCMeCP9H+NZSfd1JJK0cV" - + "SrzSlY2X6UnukcqoQqe8Akg/PRBA0VqaRJIKinWKIRnKGQIwJUjDHGfjxx/96HbBulS1tqmqKlfp" - + "08hWaRzhUC9EnPQAxk5x1rWWqRKaGpiZv04GJH4CeR/8xrionlSSBpKgoJnwiRRcuuLN2fjoefHx" - + "8jXxmr4qSCdga2XClwPpsxHfWDgnByP4A1etks7wRioUB2jVs4/I7z++dKDf8TN6pLISzxLLToY+" - + "yFcr5GPn+zXe4X/b23PUG1W+53WnS5XanNNBTAsJZmZwq4C9r/3AMkjwT8Eg/v8Avtx21sd6y22q" - + "lvNQlRzlp3rTGY0ZvYe1bwpXI6Awez8pj073pvmuq6MbwtdLHd0nJpbnHRMlLUQA8XYnHvcGNz0B" - + "kYI+Dpx1N7uUVvqKeopqOKvigNVChkP28657dG4lsZIBTiSvWcgglV+n909UYfUWsG5bXUDb9fAh" - + "ntsMQQ0Mrxq6MCCXdeRxJx7z/jgY16Bs0tLTU6UIqRUyMOPF5+UkgVVDMOXucDIGf4/OslTb72fU" - + "3g0dXPV0ldG5eON3ZmGV4gkgkY78ZI0dS9W+OolqUraSESzlpAqsp4j/ACY8TyJ4gY6/nrRXbtdQ" - + "1bt9tVmYhR0Y2XAP4LDvrHjWH31aaup9RKOSjQEyGJm+Qce3LD+M/wCs/Gl9TekO1txbllq0tU0c" - + "4vrV0rrVBEkIQholQLyVUYH3HB5HonTOrUpk26bPURyB+CqKgvI/1QvEdPgkknGS3ZJz2RoDX2KV" - + "FFM33sMcXFqaKVm4S+9eSoASEDAkHOAPOPnQ/et1+8sENDSFVutKqs5MyH6LMwDBlDclBzkZA6x8" - + "aN7EmjobV9oZ6d7jURfW+4arTg8TN0XI93TAjx1yxnzpC7j3XafUf1Yjmutiqaait1XLb7M9FMpS" - + "rVn4F8t/i/FiGRQRkYbONO60023LhQ0VprbDRiGdTDBFPRj6kaKyj3CRM4YnIfAJ89+dFpNs7Njr" - + "E+w+0WSaQoTBJNDKMqSWVlcDPWc41sNpWymoqBY0Mv1PbIS8ruxLIuSSxJ7IJ0JWkqoamslkkWeS" - + "WokkjT6AQoqueIz7icgNlvkHwPha0l6uG3bpWR0aVkc6QKzytEkjVBMYdeKgeHOV/Yqc+NWbndI7" - + "laLlaKBzeq62SlWqHpP1YWIKhOL+3GT03zx8E+7WV9HtjVVFeaytpLvU3mOmhWSehriwCyszZ4sx" - + "OArKhyMgcSQpOAGBTbdsElBMZqT9ZaoKtc5H11LSIJIjhR0ArAjP5HzrWVOxrDWVNRRXNZa6gkjU" - + "pRTkPEiZPJAuP7ScdazMG1rdFQlttVVvpK1aBUwkazwtG3/jRfKHKjHE/wCIOhFRef6fVOsz1y1R" - + "RqaCpUqTIhJJ4kgnKlWPnkCD1jVC3/1DcSTUtHYZJbvEivS3KOqVHBK9CTrtR0O8/keTp3WiOZXl" - + "ldFUOeJAOSpViMfxqndrer3KnhSFzSTLO9UqAjLELhuY7DfAAI8k56xpbeplZarMLUtEhu9TU16U" - + "ogkBaaIHJJZemOML8g/zk6FXe97S3nXWuDa94kStpqiYVtStKsUkhiX9TkzgMMFQAy5APXz1dlu+" - + "5rFXz0wpTUVMiQpWtEqkuXUeSW9pJbipUHOQWx51rtsU0tBuKpo70qukcKzxyVDB5JGA4cyR1yIZ" - + "gQB58aWi+o94pdw+oNVS7ks9ZNYbf/0ukmUOCqEyOjMjDm/YUfOR3nTP9MKp90bAtG4YKv6UFfSf" - + "VhCxBWjVhgEYPtOMZHfecY0E3nX+nO1PsrJd5rTBSXuSWBpJJgFSoCmQmRs5VWwcknpgPzoL6WVE" - + "Mb2qorYKKkrIl+lyoeUcFQgT9PCgkyKFPFScg4yAPAbNnuQqaw00fFV4vKUYMsmTIfKkDAx8/OdG" - + "TpVb99EbFuW5XC+Ut2utuvtXKk4qxUNKiSIAEAjY4CDHhSp/cEAjAN6Nr6a3Gv3LadvSb+v92qGe" - + "CEUcdPHQuQ/J1kL+xSWBwcnrr86OUlp9WdrbWobrRWam3BuiSuWS7tUzRM81KuQEjclcOqcVDHOT" - + "nOc50eisl335XVFVuKwXGwKqLBFKtaq1M1JMMvGxQfpuGSNiAWwCQGznWrtPp5smyWKntNu2rbzR" - + "00ZWKJoVc/k5Z/JJ8knJ+dI//kjsnd1TtqA7Zj3DT2KiYA7dt8SrTiIk8uoGDv2eWDnABxrCf8d/" - + "TYG87g3PtGzbev8AMkppbW1xr35Wk/Ek9O8QYyEd9EY7C/nXsfbsE/8ASqOouVLTxXR6eP7v6YBA" - + "k4jkA2ASAcgfsNEVRFZmVFDN/cQOz/Ou2pqampqamqtPQUMFfUVsFFTRVNQFE0yRKHkC5xyYDJxk" - + "4z+dWtTX/9mItgQTAQIAIAUCR0JYkAIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJENfkVqhR" - + "aYzEAPYD/iHdLOAE8r8HHF3F4z28vtIT8iiRB9aPC/YH0xqV1qeEKG8+VosBaQAOCEquONtRWsww" - + "gO3XB0d6VAq2kMOKc2YiB4ZtZcFvvmP9KdmVIZxVjpa9ozjP5j9zFso1HOpFcsn/VDBEqy5TvsNx" - + "Qvmtc8X7lqK/zLRVkSSBItik2IIhsAIAAw=="); - - + "mI0ER0JXuwEEAKNqsXwLU6gu6P2Q/HJqEJVt3A7Kp1yucn8HWVeJF9JLAKVjVU8jrvz9Bw4NwaRJ" + + "NGYEAgdRq8Hx3WP9FXFCIVfCdi+oQrphcHWzzBFul8sykUGT+LmcBdqQGU9WaWSJyCOmUht4j7t0" + + "zk/IXX0YxGmkqR+no5rTj9LMDG8AQQrFABEBAAG0P0VyaWMgSCBFY2hpZG5hIChpbWFnZSB0ZXN0" + + "IGtleSkgPGVyaWMuZWNoaWRuYUBib3VuY3ljYXN0bGUub3JnPoi2BBMBAgAgBQJHQle7AhsDBgsJ" + + "CAcDAgQVAggDBBYCAwECHgECF4AACgkQ1+RWqFFpjMTKtgP+Okqkn0gVpQyNYXM/hWX6f3UQcyXk" + + "2Sd/fWW0XG+LBjhhBo+lXRWK0uYF8OMdZwsSl9HimpgYD5/kNs0Seh417DioP1diOgxkgezyQgMa" + + "+ODZfNnIvVaBr1pHLPLeqIBxBVMWBfa4wDXnLLGu8018uvI2yBhz5vByB1ntxwgKMXCwAgAD0cf3" + + "x/UBEAABAQAAAAAAAAAAAAAAAP/Y/+AAEEpGSUYAAQEBAEgASAAA/+EAFkV4aWYAAE1NACoAAAAI" + + "AAAAAAAA/9sAQwAFAwQEBAMFBAQEBQUFBgcMCAcHBwcPCwsJDBEPEhIRDxERExYcFxMUGhURERgh" + + "GBodHR8fHxMXIiQiHiQcHh8e/8AACwgAOgBQAQEiAP/EABwAAAIDAAMBAAAAAAAAAAAAAAUHAAQG" + + "AQIIA//EADEQAAIBAwQBAwMDBAEFAAAAAAECAwQFEQAGEiExByJBExRRI2FxFTJCkQglM0OBof/a" + + "AAgBAQAAPwD19U3SgppWjqKqKFl8824j/Z1mku9ZV7gNraq4KKQTsachsliwBBHeBgH9/nzoyz16" + + "FWjnDc2AIZfB7JAA8AD89+3986KUryPTI8qcHK+5fwdV7hcEpqE1aKJYwfcQ2AB+dVaK9fdRfXSh" + + "m+j8t8qOIbsHB8H/AGD+2SyMroGUhgRkEHo651NTSp9RKlYt7GSTgQsMcSKfcc5LH2+T0fjHYGvp" + + "Y6iCo3tUzQQTU6GGIFOOO+x8EAZ/c/P51upqsS0dDc6SZDC8fJSVJDhgCMeCP9H+NZSfd1JJK0cV" + + "SrzSlY2X6UnukcqoQqe8Akg/PRBA0VqaRJIKinWKIRnKGQIwJUjDHGfjxx/96HbBulS1tqmqKlfp" + + "08hWaRzhUC9EnPQAxk5x1rWWqRKaGpiZv04GJH4CeR/8xrionlSSBpKgoJnwiRRcuuLN2fjoefHx" + + "8jXxmr4qSCdga2XClwPpsxHfWDgnByP4A1etks7wRioUB2jVs4/I7z++dKDf8TN6pLISzxLLToY+" + + "yFcr5GPn+zXe4X/b23PUG1W+53WnS5XanNNBTAsJZmZwq4C9r/3AMkjwT8Eg/v8Avtx21sd6y22q" + + "lvNQlRzlp3rTGY0ZvYe1bwpXI6Awez8pj073pvmuq6MbwtdLHd0nJpbnHRMlLUQA8XYnHvcGNz0B" + + "kYI+Dpx1N7uUVvqKeopqOKvigNVChkP28657dG4lsZIBTiSvWcgglV+n909UYfUWsG5bXUDb9fAh" + + "ntsMQQ0Mrxq6MCCXdeRxJx7z/jgY16Bs0tLTU6UIqRUyMOPF5+UkgVVDMOXucDIGf4/OslTb72fU" + + "3g0dXPV0ldG5eON3ZmGV4gkgkY78ZI0dS9W+OolqUraSESzlpAqsp4j/ACY8TyJ4gY6/nrRXbtdQ" + + "1bt9tVmYhR0Y2XAP4LDvrHjWH31aaup9RKOSjQEyGJm+Qce3LD+M/wCs/Gl9TekO1txbllq0tU0c" + + "4vrV0rrVBEkIQholQLyVUYH3HB5HonTOrUpk26bPURyB+CqKgvI/1QvEdPgkknGS3ZJz2RoDX2KV" + + "FFM33sMcXFqaKVm4S+9eSoASEDAkHOAPOPnQ/et1+8sENDSFVutKqs5MyH6LMwDBlDclBzkZA6x8" + + "aN7EmjobV9oZ6d7jURfW+4arTg8TN0XI93TAjx1yxnzpC7j3XafUf1Yjmutiqaait1XLb7M9FMpS" + + "rVn4F8t/i/FiGRQRkYbONO60023LhQ0VprbDRiGdTDBFPRj6kaKyj3CRM4YnIfAJ89+dFpNs7Njr" + + "E+w+0WSaQoTBJNDKMqSWVlcDPWc41sNpWymoqBY0Mv1PbIS8ruxLIuSSxJ7IJ0JWkqoamslkkWeS" + + "WokkjT6AQoqueIz7icgNlvkHwPha0l6uG3bpWR0aVkc6QKzytEkjVBMYdeKgeHOV/Yqc+NWbndI7" + + "laLlaKBzeq62SlWqHpP1YWIKhOL+3GT03zx8E+7WV9HtjVVFeaytpLvU3mOmhWSehriwCyszZ4sx" + + "OArKhyMgcSQpOAGBTbdsElBMZqT9ZaoKtc5H11LSIJIjhR0ArAjP5HzrWVOxrDWVNRRXNZa6gkjU" + + "pRTkPEiZPJAuP7ScdazMG1rdFQlttVVvpK1aBUwkazwtG3/jRfKHKjHE/wCIOhFRef6fVOsz1y1R" + + "RqaCpUqTIhJJ4kgnKlWPnkCD1jVC3/1DcSTUtHYZJbvEivS3KOqVHBK9CTrtR0O8/keTp3WiOZXl" + + "ldFUOeJAOSpViMfxqndrer3KnhSFzSTLO9UqAjLELhuY7DfAAI8k56xpbeplZarMLUtEhu9TU16U" + + "ogkBaaIHJJZemOML8g/zk6FXe97S3nXWuDa94kStpqiYVtStKsUkhiX9TkzgMMFQAy5APXz1dlu+" + + "5rFXz0wpTUVMiQpWtEqkuXUeSW9pJbipUHOQWx51rtsU0tBuKpo70qukcKzxyVDB5JGA4cyR1yIZ" + + "gQB58aWi+o94pdw+oNVS7ks9ZNYbf/0ukmUOCqEyOjMjDm/YUfOR3nTP9MKp90bAtG4YKv6UFfSf" + + "VhCxBWjVhgEYPtOMZHfecY0E3nX+nO1PsrJd5rTBSXuSWBpJJgFSoCmQmRs5VWwcknpgPzoL6WVE" + + "Mb2qorYKKkrIl+lyoeUcFQgT9PCgkyKFPFScg4yAPAbNnuQqaw00fFV4vKUYMsmTIfKkDAx8/OdG" + + "TpVb99EbFuW5XC+Ut2utuvtXKk4qxUNKiSIAEAjY4CDHhSp/cEAjAN6Nr6a3Gv3LadvSb+v92qGe" + + "CEUcdPHQuQ/J1kL+xSWBwcnrr86OUlp9WdrbWobrRWam3BuiSuWS7tUzRM81KuQEjclcOqcVDHOT" + + "nOc50eisl335XVFVuKwXGwKqLBFKtaq1M1JMMvGxQfpuGSNiAWwCQGznWrtPp5smyWKntNu2rbzR" + + "00ZWKJoVc/k5Z/JJ8knJ+dI//kjsnd1TtqA7Zj3DT2KiYA7dt8SrTiIk8uoGDv2eWDnABxrCf8d/" + + "TYG87g3PtGzbev8AMkppbW1xr35Wk/Ek9O8QYyEd9EY7C/nXsfbsE/8ASqOouVLTxXR6eP7v6YBA" + + "k4jkA2ASAcgfsNEVRFZmVFDN/cQOz/Ou2pqampqamqtPQUMFfUVsFFTRVNQFE0yRKHkC5xyYDJxk" + + "4z+dWtTX/9mItgQTAQIAIAUCR0JYkAIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJENfkVqhR" + + "aYzEAPYD/iHdLOAE8r8HHF3F4z28vtIT8iiRB9aPC/YH0xqV1qeEKG8+VosBaQAOCEquONtRWsww" + + "gO3XB0d6VAq2kMOKc2YiB4ZtZcFvvmP9KdmVIZxVjpa9ozjP5j9zFso1HOpFcsn/VDBEqy5TvsNx" + + "Qvmtc8X7lqK/zLRVkSSBItik2IIhsAIAAw=="); + + private void fingerPrintTest() throws Exception { // // version 3 // - PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(fingerprintKey, new BcKeyFingerprintCalculator()); + PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(fingerprintKey, new BcKeyFingerprintCalculator()); - PGPPublicKey pubKey = pgpPub.getPublicKey(); + PGPPublicKey pubKey = pgpPub.getPublicKey(); - if (!areEqual(pubKey.getFingerprint(), Hex.decode("4FFB9F0884266C715D1CEAC804A3BBFA"))) + byte[] expectedVersion3 = Hex.decode("4FFB9F0884266C715D1CEAC804A3BBFA"); + if (!areEqual(pubKey.getFingerprint(), expectedVersion3)) { fail("version 3 fingerprint test failed"); } - + if (!pubKey.hasFingerprint(expectedVersion3)) + { + fail("version 3 fingerprint test failed"); + } + // // version 4 // @@ -417,7 +422,12 @@ private void fingerPrintTest() pubKey = pgpPub.getPublicKey(); - if (!areEqual(pubKey.getFingerprint(), Hex.decode("3062363c1046a01a751946bb35586146fdf3f373"))) + byte[] expectedVersion4 = Hex.decode("3062363c1046a01a751946bb35586146fdf3f373"); + if (!areEqual(pubKey.getFingerprint(), expectedVersion4)) + { + fail("version 4 fingerprint test failed"); + } + if (!pubKey.hasFingerprint(expectedVersion4)) { fail("version 4 fingerprint test failed"); } @@ -426,7 +436,7 @@ private void fingerPrintTest() private void mixedTest(PGPPrivateKey pgpPrivKey, PGPPublicKey pgpPubKey) throws Exception { - byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; + byte[] text = {(byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n'}; // // literal data @@ -446,7 +456,7 @@ private void mixedTest(PGPPrivateKey pgpPrivKey, PGPPublicKey pgpPubKey) ByteArrayOutputStream bcOut = new ByteArrayOutputStream(); - PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_128).setWithIntegrityPacket(true).setSecureRandom(new SecureRandom())); + PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_128).setSecureRandom(new SecureRandom()).setWithIntegrityPacket(true)); encGen.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(pgpPubKey)); @@ -465,9 +475,9 @@ private void mixedTest(PGPPrivateKey pgpPrivKey, PGPPublicKey pgpPubKey) // PGPObjectFactory pgpF = new PGPObjectFactory(encData, new BcKeyFingerprintCalculator()); - PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); + PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); - PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); + PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); @@ -501,7 +511,7 @@ private void checkLiteralData(PGPLiteralData ld, byte[] data) throw new RuntimeException("wrong filename in packet"); } - InputStream inLd = ld.getDataStream(); + InputStream inLd = ld.getDataStream(); int ch; while ((ch = inLd.read()) >= 0) @@ -523,12 +533,12 @@ private void existingEmbeddedJpegTest() PGPPublicKey pubKey = pgpPub.getPublicKey(); Iterator it = pubKey.getUserAttributes(); - int count = 0; + int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); - Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes); + Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { @@ -584,8 +594,12 @@ private void embeddedJpegTest() while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); + ImageAttribute imageAttribute = attributes.getImageAttribute(); + isEquals(imageAttribute.version(), 1); + isEquals(imageAttribute.getEncoding(), 1); + isTrue(java.util.Arrays.equals(imageAttribute.getImageData(), jpegImage)); - Iterator sigs = nKey.getSignaturesForUserAttribute(attributes); + Iterator sigs = nKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { @@ -615,7 +629,7 @@ private void embeddedJpegTest() nKey = PGPPublicKey.removeCertification(nKey, uVec); count = 0; - for (it = nKey.getUserAttributes(); it.hasNext();) + for (it = nKey.getUserAttributes(); it.hasNext(); it.next()) { count++; } @@ -663,8 +677,8 @@ private void sigsubpacketTest() PGPSignatureSubpacketVector hashedPcks = svg.generate(); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, - sgnKeyPair, identity, new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1), - hashedPcks, unhashedPcks, new BcPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); + sgnKeyPair, identity, new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1), + hashedPcks, unhashedPcks, new BcPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); svg = new PGPSignatureSubpacketGenerator(); svg.setKeyExpirationTime(true, 86400L * 366 * 2); @@ -679,13 +693,13 @@ sgnKeyPair, identity, new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags. PGPPublicKeyRing keyRing = new PGPPublicKeyRing(encodedKeyRing, new BcKeyFingerprintCalculator()); - for (Iterator it = keyRing.getPublicKeys(); it.hasNext();) + for (Iterator it = keyRing.getPublicKeys(); it.hasNext(); ) { PGPPublicKey pKey = (PGPPublicKey)it.next(); if (pKey.isEncryptionKey()) { - for (Iterator sit = pKey.getSignatures(); sit.hasNext();) + for (Iterator sit = pKey.getSignatures(); sit.hasNext(); ) { PGPSignature sig = (PGPSignature)sit.next(); PGPSignatureSubpacketVector v = sig.getHashedSubPackets(); @@ -710,7 +724,7 @@ sgnKeyPair, identity, new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags. } else { - for (Iterator sit = pKey.getSignatures(); sit.hasNext();) + for (Iterator sit = pKey.getSignatures(); sit.hasNext(); ) { PGPSignature sig = (PGPSignature)sit.next(); PGPSignatureSubpacketVector v = sig.getHashedSubPackets(); @@ -743,66 +757,66 @@ sgnKeyPair, identity, new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags. public void performTest() throws Exception { - PublicKey pubKey = null; + PublicKey pubKey = null; // // Read the public key // - PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); + PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); pubKey = new JcaPGPKeyConverter().setProvider("BC").getPublicKey(pgpPub.getPublicKey()); - Iterator it = pgpPub.getPublicKey().getUserIDs(); - - String uid = (String)it.next(); + Iterator it = pgpPub.getPublicKey().getUserIDs(); + + String uid = (String)it.next(); it = pgpPub.getPublicKey().getSignaturesForID(uid); - - PGPSignature sig = (PGPSignature)it.next(); - + + PGPSignature sig = (PGPSignature)it.next(); + sig.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey()); - + if (!sig.verifyCertification(uid, pgpPub.getPublicKey())) { fail("failed to verify certification"); } - + // // write a public key // - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - BCPGOutputStream pOut = new BCPGOutputStream(bOut); - + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut); + pgpPub.encode(pOut); - if (!areEqual(bOut.toByteArray(), testPubKey)) + if (!areEqual(bOut.toByteArray(), testPubKey)) { fail("public key rewrite failed"); } - + // // Read the public key // - PGPPublicKeyRing pgpPubV3 = new PGPPublicKeyRing(testPubKeyV3, new BcKeyFingerprintCalculator()); - PublicKey pubKeyV3 = new JcaPGPKeyConverter().setProvider("BC").getPublicKey(pgpPub.getPublicKey()); + PGPPublicKeyRing pgpPubV3 = new PGPPublicKeyRing(testPubKeyV3, new BcKeyFingerprintCalculator()); + PublicKey pubKeyV3 = new JcaPGPKeyConverter().setProvider("BC").getPublicKey(pgpPub.getPublicKey()); // // write a V3 public key // bOut = new ByteArrayOutputStream(); pOut = new BCPGOutputStream(bOut); - + pgpPubV3.encode(pOut); // // Read a v3 private key // - char[] passP = "FIXCITY_QA".toCharArray(); + char[] passP = "FIXCITY_QA".toCharArray(); if (!noIDEA()) { - PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(testPrivKeyV3, new BcKeyFingerprintCalculator()); - PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passP)); + PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(testPrivKeyV3, new BcKeyFingerprintCalculator()); + PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passP)); // // write a v3 private key @@ -823,20 +837,20 @@ public void performTest() // PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator()); PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); - + // // write a private key // bOut = new ByteArrayOutputStream(); pOut = new BCPGOutputStream(bOut); - + pgpPriv.encode(pOut); - if (!areEqual(bOut.toByteArray(), testPrivKey)) + if (!areEqual(bOut.toByteArray(), testPrivKey)) { fail("private key rewrite failed"); } - + // // test encryption @@ -844,15 +858,15 @@ public void performTest() Cipher c = Cipher.getInstance("RSA", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey); - - byte[] in = "hello world".getBytes(); - byte[] out = c.doFinal(in); - + byte[] in = "hello world".getBytes(); + + byte[] out = c.doFinal(in); + c.init(Cipher.DECRYPT_MODE, new JcaPGPKeyConverter().setProvider("BC").getPrivateKey(pgpPrivKey)); - + out = c.doFinal(out); - + if (!areEqual(in, out)) { fail("decryption failed."); @@ -861,35 +875,35 @@ public void performTest() // // test signature message // - PGPObjectFactory pgpFact = new PGPObjectFactory(sig1, new BcKeyFingerprintCalculator()); + PGPObjectFactory pgpFact = new PGPObjectFactory(sig1, new BcKeyFingerprintCalculator()); - PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); + PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream(), new BcKeyFingerprintCalculator()); - - PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); - - PGPOnePassSignature ops = p1.get(0); - - PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); - InputStream dIn = p2.getInputStream(); - int ch; + PGPOnePassSignatureList p1 = new PGPOnePassSignatureList(((PGPOnePassSignatureList)pgpFact.nextObject()).get(0)); + + PGPOnePassSignature ops = p1.get(0); + + PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); + + InputStream dIn = p2.getInputStream(); + int ch; ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey(ops.getKeyID())); - + while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } - PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); + PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed signature check"); } - + // // encrypted message - read subkey // @@ -898,35 +912,35 @@ public void performTest() // // encrypted message // - byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; - + byte[] text = {(byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n'}; + PGPObjectFactory pgpF = new PGPObjectFactory(enc1, new BcKeyFingerprintCalculator()); - PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); - - PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); - + PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); + + PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); + pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); - + pgpFact = new PGPObjectFactory(clear, new BcKeyFingerprintCalculator()); c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream(), new BcKeyFingerprintCalculator()); - - PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); - + + PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); + bOut = new ByteArrayOutputStream(); - + if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } - InputStream inLd = ld.getDataStream(); - + InputStream inLd = ld.getDataStream(); + while ((ch = inLd.read()) >= 0) { bOut.write(ch); @@ -940,15 +954,15 @@ public void performTest() // // encrypt - short message // - byte[] shortText = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' }; - - ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); - PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(new SecureRandom())); - PGPPublicKey puK = pgpPriv.getSecretKey(encP.getKeyID()).getPublicKey(); - + byte[] shortText = {(byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o'}; + + ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); + PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(new SecureRandom())); + PGPPublicKey puK = pgpPriv.getSecretKey(encP.getKeyID()).getPublicKey(); + cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK)); - - OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), shortText.length); + + OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), shortText.length); cOut.write(shortText); @@ -957,9 +971,9 @@ public void performTest() pgpF = new PGPObjectFactory(cbOut.toByteArray(), new BcKeyFingerprintCalculator()); encList = (PGPEncryptedDataList)pgpF.nextObject(); - + encP = (PGPPublicKeyEncryptedData)encList.get(0); - + pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); PublicKeyDataDecryptorFactory dataDecryptorFactory = new BcPublicKeyDataDecryptorFactory(pgpPrivKey); @@ -970,9 +984,9 @@ public void performTest() } clear = encP.getDataStream(dataDecryptorFactory); - + bOut.reset(); - + while ((ch = clear.read()) >= 0) { bOut.write(ch); @@ -984,14 +998,14 @@ public void performTest() { fail("wrong plain text in generated short text packet"); } - + // // encrypt // cbOut = new ByteArrayOutputStream(); cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(new SecureRandom())); puK = pgpPriv.getSecretKey(encP.getKeyID()).getPublicKey(); - + cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK)); cOut = cPk.open(new UncloseableOutputStream(cbOut), text.length); @@ -1003,15 +1017,15 @@ public void performTest() pgpF = new PGPObjectFactory(cbOut.toByteArray(), new BcKeyFingerprintCalculator()); encList = (PGPEncryptedDataList)pgpF.nextObject(); - + encP = (PGPPublicKeyEncryptedData)encList.get(0); - + pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); - + bOut.reset(); - + while ((ch = clear.read()) >= 0) { bOut.write(ch); @@ -1023,13 +1037,13 @@ public void performTest() { fail("wrong plain text in generated packet"); } - + // // read public key with sub key. // pgpF = new PGPObjectFactory(subPubKey, new BcKeyFingerprintCalculator()); - Object o; - + Object o; + while ((o = pgpFact.nextObject()) != null) { // System.out.println(o); @@ -1038,17 +1052,17 @@ public void performTest() // // key pair generation - CAST5 encryption // - char[] passPhrase = "hello".toCharArray(); - - RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); + char[] passPhrase = "hello".toCharArray(); + + RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 1024, 25)); - AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); + AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); + + PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, new BcPGPKeyPair(PublicKeyAlgorithmTags.RSA_GENERAL, kp, new Date()), "fred", null, null, new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).build(passPhrase)); - PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, new BcPGPKeyPair(PublicKeyAlgorithmTags.RSA_GENERAL, kp, new Date()), "fred", null, null, new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).build(passPhrase)); - - PGPPublicKey key = secretKey.getPublicKey(); + PGPPublicKey key = secretKey.getPublicKey(); it = key.getUserIDs(); @@ -1066,22 +1080,22 @@ public void performTest() } pgpPrivKey = secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); - + key = PGPPublicKey.removeCertification(key, uid, sig); - + if (key == null) { fail("failed certification removal"); } - - byte[] keyEnc = key.getEncoded(); - + + byte[] keyEnc = key.getEncoded(); + key = PGPPublicKey.addCertification(key, uid, sig); - + keyEnc = key.getEncoded(); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); - + sGen.init(PGPSignature.KEY_REVOCATION, secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase))); sig = sGen.generateCertification(key); @@ -1090,11 +1104,11 @@ public void performTest() keyEnc = key.getEncoded(); - PGPPublicKeyRing tmpRing = new PGPPublicKeyRing(keyEnc, new BcKeyFingerprintCalculator()); + PGPPublicKeyRing tmpRing = new PGPPublicKeyRing(keyEnc, new BcKeyFingerprintCalculator()); key = tmpRing.getPublicKey(); - Iterator sgIt = key.getSignaturesOfType(PGPSignature.KEY_REVOCATION); + Iterator sgIt = key.getSignaturesOfType(PGPSignature.KEY_REVOCATION); sig = (PGPSignature)sgIt.next(); @@ -1108,12 +1122,12 @@ public void performTest() // // use of PGPKeyPair // - PGPKeyPair pgpKp = new BcPGPKeyPair(PGPPublicKey.RSA_GENERAL , kp, new Date()); - + PGPKeyPair pgpKp = new BcPGPKeyPair(PGPPublicKey.RSA_GENERAL, kp, new Date()); + PGPPublicKey k1 = pgpKp.getPublicKey(); - + PGPPrivateKey k2 = pgpKp.getPrivateKey(); - + k1.getEncoded(); mixedTest(k2, k1); @@ -1126,24 +1140,24 @@ public void performTest() secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, new BcPGPKeyPair(PublicKeyAlgorithmTags.RSA_GENERAL, kp, new Date()), "fred", null, null, new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).build(passPhrase)); secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); - + secretKey.encode(new ByteArrayOutputStream()); - + // // secret key password changing. // - String newPass = "newPass"; - + String newPass = "newPass"; + secretKey = PGPSecretKey.copyWithNewPassword(secretKey, new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase), new BcPBESecretKeyEncryptorBuilder(secretKey.getKeyEncryptionAlgorithm()).build(newPass.toCharArray())); - + secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(newPass.toCharArray())); - + secretKey.encode(new ByteArrayOutputStream()); - + key = secretKey.getPublicKey(); key.encode(new ByteArrayOutputStream()); - + it = key.getUserIDs(); uid = (String)it.next(); @@ -1160,18 +1174,18 @@ public void performTest() } pgpPrivKey = secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(newPass.toCharArray())); - + // // signature generation // - String data = "hello world!"; - + String data = "hello world!"; + bOut = new ByteArrayOutputStream(); - - ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); - + + ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); + sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); - + sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( @@ -1182,7 +1196,7 @@ public void performTest() sGen.generateOnePassVersion(false).encode(bcOut); - PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); + PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( @@ -1212,11 +1226,11 @@ public void performTest() c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream(), new BcKeyFingerprintCalculator()); - + p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); - + ops = p1.get(0); - + p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { @@ -1226,7 +1240,7 @@ public void performTest() dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), secretKey.getPublicKey()); - + while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); @@ -1238,19 +1252,19 @@ public void performTest() { fail("Failed generated signature check"); } - + // // signature generation - version 3 // bOut = new ByteArrayOutputStream(); - + testIn = new ByteArrayInputStream(data.getBytes()); - PGPV3SignatureGenerator sGenV3 = new PGPV3SignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, PGPUtil.SHA1)); - + PGPV3SignatureGenerator sGenV3 = new PGPV3SignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, PGPUtil.SHA1)); + sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); cGen = new PGPCompressedDataGenerator( - PGPCompressedData.ZIP); + PGPCompressedData.ZIP); bcOut = new BCPGOutputStream(cGen.open(bOut)); @@ -1284,11 +1298,11 @@ public void performTest() c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream(), new BcKeyFingerprintCalculator()); - + p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); - + ops = p1.get(0); - + p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { @@ -1298,7 +1312,7 @@ public void performTest() dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), secretKey.getPublicKey()); - + while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); @@ -1310,47 +1324,47 @@ public void performTest() { fail("Failed v3 generated signature check"); } - + // // extract PGP 8 private key // pgpPriv = new PGPSecretKeyRing(pgp8Key, new BcKeyFingerprintCalculator()); - + secretKey = pgpPriv.getSecretKey(); - + pgpPrivKey = secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pgp8Pass)); // // expiry // testExpiry(expiry60and30daysSig13Key, 60, 30); - + fingerPrintTest(); existingEmbeddedJpegTest(); embeddedJpegTest(); sigsubpacketTest(); } - + private void testExpiry( - byte[] encodedRing, - int masterDays, - int subKeyDays) + byte[] encodedRing, + int masterDays, + int subKeyDays) throws Exception - { + { PGPPublicKeyRing pubRing = new PGPPublicKeyRing(encodedRing, new BcKeyFingerprintCalculator()); PGPPublicKey k = pubRing.getPublicKey(); - + if (k.getValidDays() != masterDays) { fail("mismatch on master valid days."); } - + Iterator it = pubRing.getPublicKeys(); - + it.next(); - + k = (PGPPublicKey)it.next(); - + if (k.getValidDays() != subKeyDays) { fail("mismatch on subkey valid days."); @@ -1368,7 +1382,7 @@ public String getName() } public static void main( - String[] args) + String[] args) { Security.addProvider(new BouncyCastleProvider()); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/BcpgGeneralTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/BcpgGeneralTest.java new file mode 100644 index 0000000000..de5fd8bb1f --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/BcpgGeneralTest.java @@ -0,0 +1,205 @@ +package org.bouncycastle.openpgp.test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.security.SecureRandom; +import java.security.Security; +import java.util.Date; +import java.util.Iterator; + +import org.bouncycastle.bcpg.AEADAlgorithmTags; +import org.bouncycastle.bcpg.ArmoredInputStream; +import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.bcpg.BCPGOutputStream; +import org.bouncycastle.bcpg.ECDHPublicBCPGKey; +import org.bouncycastle.bcpg.ECSecretBCPGKey; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.S2K; +import org.bouncycastle.bcpg.SignatureSubpacket; +import org.bouncycastle.bcpg.SignatureSubpacketInputStream; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket; +import org.bouncycastle.bcpg.sig.PreferredAEADCiphersuites; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.generators.X25519KeyPairGenerator; +import org.bouncycastle.crypto.params.X25519KeyGenerationParameters; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openpgp.PGPEncryptedDataList; +import org.bouncycastle.openpgp.PGPObjectFactory; +import org.bouncycastle.openpgp.PGPPBEEncryptedData; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.test.SimpleTest; + +public class BcpgGeneralTest + extends SimpleTest +{ + public static void main(String[] args) + { + Security.addProvider(new BouncyCastleProvider()); + + runTest(new BcpgGeneralTest()); + } + + @Override + public String getName() + { + return "BcpgGeneralTest"; + } + + @Override + public void performTest() + throws Exception + { + //testS2K(); + testExceptions(); + testECDHPublicBCPGKey(); + // Tests for PreferredAEADCiphersuites + testPreferredAEADCiphersuites(); + } + + public void testPreferredAEADCiphersuites() + throws Exception + { + PreferredAEADCiphersuites preferences = new PreferredAEADCiphersuites(false, new PreferredAEADCiphersuites.Combination[] + { + new PreferredAEADCiphersuites.Combination(SymmetricKeyAlgorithmTags.AES_128, AEADAlgorithmTags.OCB), + new PreferredAEADCiphersuites.Combination(SymmetricKeyAlgorithmTags.AES_128, AEADAlgorithmTags.GCM), + new PreferredAEADCiphersuites.Combination(SymmetricKeyAlgorithmTags.CAMELLIA_256, AEADAlgorithmTags.OCB) + }); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream bcpgOut = new BCPGOutputStream(bOut); + + preferences.encode(bcpgOut); + + ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); + SignatureSubpacketInputStream subpacketIn = new SignatureSubpacketInputStream(bIn); + isEquals(subpacketIn.available(), 8); + SignatureSubpacket subpacket = subpacketIn.readPacket(); + assert subpacket != null; + assert subpacket instanceof PreferredAEADCiphersuites; + + PreferredAEADCiphersuites parsed = (PreferredAEADCiphersuites)subpacket; + isTrue(Arrays.areEqual(preferences.getAlgorithms(), parsed.getAlgorithms())); + PreferredAEADCiphersuites.Combination[] preferencesCombinations = preferences.getAlgorithms(); + PreferredAEADCiphersuites.Combination[] parsedCombinations = parsed.getAlgorithms(); + isTrue(!preferencesCombinations[0].equals(null)); + isTrue(!preferencesCombinations[0].equals(new Object())); + isTrue(preferencesCombinations[0].equals(preferencesCombinations[0])); + isTrue(!preferencesCombinations[0].equals(preferencesCombinations[1])); + isTrue(!preferencesCombinations[0].equals(preferencesCombinations[2])); + isTrue(preferencesCombinations[0].equals(parsedCombinations[0])); + isTrue(preferences.isSupported(new PreferredAEADCiphersuites.Combination(SymmetricKeyAlgorithmTags.CAMELLIA_256, AEADAlgorithmTags.OCB))); + isTrue(!preferences.isSupported(new PreferredAEADCiphersuites.Combination(SymmetricKeyAlgorithmTags.AES_256, AEADAlgorithmTags.OCB))); + isTrue(preferencesCombinations[0].hashCode() == parsedCombinations[0].hashCode()); + } + + public void testECDHPublicBCPGKey() + throws Exception + { + SecureRandom random = CryptoServicesRegistrar.getSecureRandom(); + final X25519KeyPairGenerator gen = new X25519KeyPairGenerator(); + gen.init(new X25519KeyGenerationParameters(random)); +// testException("Symmetric key algorithm must be AES-128 or stronger.", "IllegalStateException", () -> +// new BcPGPKeyPair(PGPPublicKey.ECDH, new PGPKdfParameters(8, SymmetricKeyAlgorithmTags.IDEA), gen.generateKeyPair(), new Date())); +// testException("Hash algorithm must be SHA-256 or stronger.", "IllegalStateException", () -> +// new BcPGPKeyPair(PGPPublicKey.ECDH, new PGPKdfParameters(HashAlgorithmTags.SHA1, 7), gen.generateKeyPair(), new Date())); + +// new BcPGPKeyPair(PGPPublicKey.ECDH, new PGPKdfParameters(8, SymmetricKeyAlgorithmTags.CAMELLIA_256), gen.generateKeyPair(), new Date()); + BcPGPKeyPair kp = new BcPGPKeyPair(PGPPublicKey.ECDH, gen.generateKeyPair(), new Date()); + + ECDHPublicBCPGKey publicBCPGKey = (ECDHPublicBCPGKey)kp.getPublicKey().getPublicKeyPacket().getKey(); + isTrue(publicBCPGKey.getReserved() == 1); + isTrue(publicBCPGKey.getFormat().equals("PGP")); + + ECSecretBCPGKey secretBCPGKey = (ECSecretBCPGKey)kp.getPrivateKey().getPrivateKeyDataPacket(); + isTrue(secretBCPGKey.getFormat().equals("PGP")); + isTrue(Arrays.areEqual(publicBCPGKey.getEncoded(), kp.getPrivateKey().getPublicKeyPacket().getKey().getEncoded())); + + + } + + public void testExceptions() + throws Exception + { +// final PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator( +// new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256)); +// encGen.addMethod(new BcPBEKeyEncryptionMethodGenerator(Argon2S2KTest.TEST_MSG_PASSWORD.toCharArray(), S2K.Argon2Params.universallyRecommendedParameters()) +// .setSecureRandom(CryptoServicesRegistrar.getSecureRandom())); +// final PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator(); +// +// ByteArrayOutputStream out = new ByteArrayOutputStream(); +// final ArmoredOutputStream armorOut = new ArmoredOutputStream(out); +// final OutputStream encOut = encGen.open(armorOut, new byte[10]); +// testException("generator already in open state", "IllegalStateException", () -> encGen.open(armorOut, new byte[10])); +// +// OutputStream litOut = litGen.open(encOut, PGPLiteralData.UTF8, "", new Date(), new byte[10]); +// testException("generator already in open state", "IllegalStateException", () -> litGen.open(encOut, PGPLiteralData.UTF8, "", new Date(), new byte[10])); +// +// +// testException("generator already in open state", "IllegalStateException", () -> litGen.open(encOut, PGPLiteralData.UTF8, "", 10, new Date())); +// +// ByteArrayInputStream plainIn = new ByteArrayInputStream(Strings.toByteArray(Argon2S2KTest.TEST_MSG_PLAIN)); +// Streams.pipeAll(plainIn, litOut); +// litOut.close(); +// +// armorOut.close(); + + ByteArrayInputStream msgIn = new ByteArrayInputStream(Strings.toByteArray(Argon2S2KTest.TEST_MSG_AES128)); + ArmoredInputStream armorIn = new ArmoredInputStream(msgIn); + + PGPObjectFactory objectFactory = new BcPGPObjectFactory(armorIn); + final Iterator it = objectFactory.iterator(); + testException("Cannot remove element from factory.", "UnsupportedOperationException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + it.remove(); + } + }); + PGPEncryptedDataList encryptedDataList = (PGPEncryptedDataList)it.next(); + testException(null, "NoSuchElementException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + it.next(); + } + }); + + PGPPBEEncryptedData encryptedData = (PGPPBEEncryptedData)encryptedDataList.get(0); + isEquals(encryptedData.getAlgorithm(), SymmetricKeyAlgorithmTags.AES_128); + + } + + public void testS2K() + throws Exception + { + S2K s2k = new S2K(HashAlgorithmTags.SHA1); + SymmetricKeyEncSessionPacket packet = SymmetricKeyEncSessionPacket.createV4Packet(SymmetricKeyAlgorithmTags.AES_256, s2k, null); +//PGPObjectFactory + packet = new SymmetricKeyEncSessionPacket(new BCPGInputStream(new ByteArrayInputStream(packet.getEncoded()))); + isEquals(s2k.getHashAlgorithm(), packet.getS2K().getHashAlgorithm()); + isEquals(s2k.getType(), packet.getS2K().getType()); + isEquals(S2K.SIMPLE, packet.getS2K().getType()); + + byte[] iv = new byte[16]; + SecureRandom random = new SecureRandom(); + random.nextBytes(iv); + s2k = new S2K(HashAlgorithmTags.SHA1, iv); + packet = SymmetricKeyEncSessionPacket.createV4Packet(SymmetricKeyAlgorithmTags.AES_256, s2k, null); + + packet = new SymmetricKeyEncSessionPacket(new BCPGInputStream(new ByteArrayInputStream(packet.getEncoded()))); + isEquals(s2k.getHashAlgorithm(), packet.getS2K().getHashAlgorithm()); + isEquals(s2k.getType(), packet.getS2K().getType()); + isEquals(s2k.getIV(), packet.getS2K().getIV()); + isEquals(S2K.SALTED, packet.getS2K().getType()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/BytesBooleansTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/BytesBooleansTest.java new file mode 100644 index 0000000000..a8b5dc23e9 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/BytesBooleansTest.java @@ -0,0 +1,61 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.sig.PrimaryUserID; + +import junit.framework.TestCase; + +public class BytesBooleansTest + extends TestCase +{ + public void testParseFalse() + { + PrimaryUserID primaryUserID = new PrimaryUserID(true, false); + + byte[] bFalse = primaryUserID.getData(); + assertEquals(1, bFalse.length); + assertEquals(0, bFalse[0]); + assertFalse(primaryUserID.isPrimaryUserID()); + } + + public void testParseTrue() + { + PrimaryUserID primaryUserID = new PrimaryUserID(true, true); + + byte[] bTrue = primaryUserID.getData(); + + assertEquals(1, bTrue.length); + assertEquals(1, bTrue[0]); + assertTrue(primaryUserID.isPrimaryUserID()); + } + + public void testParseTooShort() + { + PrimaryUserID primaryUserID = new PrimaryUserID(true, false, new byte[0]); + byte[] bTooShort = primaryUserID.getData(); + try + { + primaryUserID.isPrimaryUserID(); + fail("Should throw."); + } + catch (IllegalStateException e) + { + // expected. + } + } + + public void testParseTooLong() + { + PrimaryUserID primaryUserID = new PrimaryUserID(true, false, new byte[42]); + byte[] bTooLong = primaryUserID.getData(); + + try + { + primaryUserID.isPrimaryUserID(); + fail("Should throw."); + } + catch (IllegalStateException e) + { + // expected. + } + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/Curve25519PrivateKeyEncodingTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/Curve25519PrivateKeyEncodingTest.java new file mode 100644 index 0000000000..96ecc77a44 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/Curve25519PrivateKeyEncodingTest.java @@ -0,0 +1,195 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.bcpg.*; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.generators.X25519KeyPairGenerator; +import org.bouncycastle.crypto.params.X25519KeyGenerationParameters; +import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; +import org.bouncycastle.jcajce.spec.XDHParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openpgp.*; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.util.Arrays; + +import java.io.IOException; +import java.security.*; +import java.util.Date; + +/** + * Curve25519Legacy ECDH Secret Key Material uses big-endian MPI form, + * while X25519 keys use little-endian native encoding. + * This test verifies that legacy X25519 keys using ECDH are reverse-encoded, + * while X25519 keys are natively encoded. + */ +public class Curve25519PrivateKeyEncodingTest + extends AbstractPgpKeyPairTest +{ + @Override + public String getName() + { + return "Curve25519PrivateKeyEncodingTest"; + } + + @Override + public void performTest() + throws Exception + { + containsTest(); + verifySecretKeyReverseEncoding(); + } + + private void verifySecretKeyReverseEncoding() + throws PGPException, IOException, InvalidAlgorithmParameterException, NoSuchAlgorithmException + { + bc_verifySecretKeyReverseEncoding(); + jca_verifySecretKeyReverseEncoding(); + } + + /** + * Verify that legacy ECDH keys over curve25519 encode the private key in reversed encoding, + * while dedicated X25519 keys use native encoding for the private key material. + * Test the JcaJce implementation. + * + * @throws NoSuchAlgorithmException + * @throws InvalidAlgorithmParameterException + * @throws PGPException + * @throws IOException + */ + private void jca_verifySecretKeyReverseEncoding() + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException, IOException + { + JcaPGPKeyConverter c = new JcaPGPKeyConverter(); + + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("XDH", new BouncyCastleProvider()); + gen.initialize(new XDHParameterSpec("X25519")); + KeyPair kp = gen.generateKeyPair(); + + byte[] rawPrivateKey = jcaNativePrivateKey(kp.getPrivate()); + + // Legacy key uses reversed encoding + PGPKeyPair pgpECDHKeyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.ECDH, kp, date); + byte[] encodedECDHPrivateKey = pgpECDHKeyPair.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("ECDH Curve25519Legacy (X25519) key MUST encode secret key in 'reverse' (big-endian MPI encoding) (JCE implementation)", + containsSubsequence(encodedECDHPrivateKey, Arrays.reverse(rawPrivateKey))); + + byte[] decodedECDHPrivateKey = jcaNativePrivateKey(c.getPrivateKey(pgpECDHKeyPair.getPrivateKey())); + isEncodingEqual("Decoded ECDH Curve25519Legacy (X25519) key MUST match original raw key (JCE implementation)", + decodedECDHPrivateKey, rawPrivateKey); + + // X25519 key uses native encoding + PGPKeyPair pgpX25519KeyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.X25519, kp, date); + byte[] encodedX25519PrivateKey = pgpX25519KeyPair.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("X25519 key MUST use native encoding (little-endian) to encode the secret key material (JCE implementation)", + containsSubsequence(encodedX25519PrivateKey, rawPrivateKey)); + + byte[] decodedX25519PrivateKey = jcaNativePrivateKey(c.getPrivateKey(pgpX25519KeyPair.getPrivateKey())); + isEncodingEqual("Decoded X25519 key MUST match original raw key (JCE implementation)", + rawPrivateKey, decodedX25519PrivateKey); + } + + /** + * Return the native encoding of the given private key. + * @param privateKey private key + * @return native encoding + * @throws IOException + */ + private byte[] jcaNativePrivateKey(PrivateKey privateKey) + throws IOException + { + PrivateKeyInfo kInfo = PrivateKeyInfo.getInstance(privateKey.getEncoded()); + return ASN1OctetString.getInstance(kInfo.parsePrivateKey()).getOctets(); + } + + /** + * Verify that legacy ECDH keys over curve25519 encode the private key in reversed encoding, + * while dedicated X25519 keys use native encoding for the private key material. + * Test the BC implementation. + */ + private void bc_verifySecretKeyReverseEncoding() + throws PGPException + { + BcPGPKeyConverter c = new BcPGPKeyConverter(); + + Date date = currentTimeRounded(); + X25519KeyPairGenerator gen = new X25519KeyPairGenerator(); + gen.init(new X25519KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + + byte[] rawPrivateKey = ((X25519PrivateKeyParameters) kp.getPrivate()).getEncoded(); + + // Legacy key uses reversed encoding + PGPKeyPair pgpECDHKeyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.ECDH, kp, date); + byte[] encodedECDHPrivateKey = pgpECDHKeyPair.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("ECDH Curve25519Legacy (X25519) key MUST encode secret key in 'reverse' (big-endian MPI encoding) (BC implementation)", + containsSubsequence(encodedECDHPrivateKey, Arrays.reverse(rawPrivateKey))); + + byte[] decodedECDHPrivateKey = ((X25519PrivateKeyParameters) c.getPrivateKey(pgpECDHKeyPair.getPrivateKey())).getEncoded(); + isEncodingEqual("Decoded ECDH Curve25519Legacy (X25519) key MUST match original raw key (BC implementation)", + decodedECDHPrivateKey, rawPrivateKey); + + // X25519 key uses native encoding + PGPKeyPair pgpX25519KeyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.X25519, kp, date); + byte[] encodedX25519PrivateKey = pgpX25519KeyPair.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("X25519 key MUST use native encoding (little-endian) to encode the secret key material (BC implementation)", + containsSubsequence(encodedX25519PrivateKey, rawPrivateKey)); + + byte[] decodedX25519PrivateKey = ((X25519PrivateKeyParameters) c.getPrivateKey(pgpX25519KeyPair.getPrivateKey())).getEncoded(); + isEncodingEqual("Decoded X25519 key MUST match original raw key (BC implementation)", + rawPrivateKey, decodedX25519PrivateKey); + } + + /** + * Return true, if the given sequence contains the given subsequence entirely. + * @param sequence sequence + * @param subsequence subsequence + * @return true if subsequence is a subsequence of sequence + */ + public boolean containsSubsequence(byte[] sequence, byte[] subsequence) + { + outer: for (int i = 0; i < sequence.length - subsequence.length + 1; i++) + { + for (int j = 0; j < subsequence.length; j++) + { + if (sequence[i + j] != subsequence[j]) + { + continue outer; + } + } + return true; + } + return false; + } + + /** + * Test proper functionality of the {@link #containsSubsequence(byte[], byte[])} method. + */ + private void containsTest() { + // Make sure our containsSubsequence method functions correctly + byte[] s = new byte[] {0x00, 0x01, 0x02, 0x03}; + isTrue(containsSubsequence(s, new byte[] {0x00, 0x01})); + isTrue(containsSubsequence(s, new byte[] {0x01, 0x02})); + isTrue(containsSubsequence(s, new byte[] {0x02, 0x03})); + isTrue(containsSubsequence(s, new byte[] {0x00})); + isTrue(containsSubsequence(s, new byte[] {0x03})); + isTrue(containsSubsequence(s, new byte[] {0x00, 0x01, 0x02, 0x03})); + isTrue(containsSubsequence(s, new byte[0])); + isTrue(containsSubsequence(new byte[0], new byte[0])); + + isFalse(containsSubsequence(s, new byte[] {0x00, 0x02})); + isFalse(containsSubsequence(s, new byte[] {0x00, 0x00})); + isFalse(containsSubsequence(s, new byte[] {0x00, 0x01, 0x02, 0x03, 0x04})); + isFalse(containsSubsequence(s, new byte[] {0x04})); + isFalse(containsSubsequence(new byte[0], new byte[] {0x00})); + } + + public static void main(String[] args) + { + runTest(new Curve25519PrivateKeyEncodingTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/DSA2Test.java b/pg/src/test/java/org/bouncycastle/openpgp/test/DSA2Test.java index 9199b26dfc..7c07b9a8dd 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/DSA2Test.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/DSA2Test.java @@ -12,6 +12,7 @@ import junit.framework.TestSuite; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; @@ -146,7 +147,7 @@ private void doSigGenerateTest(String privateKeyFile, String publicKeyFile, int ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, digest).setProvider("BC")); - sGen.init(PGPSignature.BINARY_DOCUMENT, secRing.getSecretKey().extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build("test".toCharArray()))); + sGen.init(PGPSignature.BINARY_DOCUMENT, secRing.getSecretKey().extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider(new BouncyCastleProvider()).build("test".toCharArray()))); BCPGOutputStream bcOut = new BCPGOutputStream(bOut); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedEd25519KeyPairTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedEd25519KeyPairTest.java new file mode 100644 index 0000000000..5dfb912580 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedEd25519KeyPairTest.java @@ -0,0 +1,222 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.*; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters; +import org.bouncycastle.jcajce.spec.EdDSAParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openpgp.*; +import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.bc.*; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.util.Pack; +import org.bouncycastle.util.encoders.Hex; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.util.Date; + +public class DedicatedEd25519KeyPairTest + extends AbstractPgpKeyPairTest +{ + @Override + public String getName() + { + return "DedicatedEd25519KeyPairTest"; + } + + @Override + public void performTest() + throws Exception + { + testConversionOfJcaKeyPair(); + testConversionOfBcKeyPair(); + testV4SigningVerificationWithJcaKey(); + testV4SigningVerificationWithBcKey(); + + testConversionOfTestVectorKey(); + } + + private void testConversionOfJcaKeyPair() + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException, IOException + { + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("EDDSA", new BouncyCastleProvider()); + gen.initialize(new EdDSAParameterSpec("Ed25519")); + KeyPair kp = gen.generateKeyPair(); + + for (int version: new int[]{PublicKeyPacket.VERSION_4, PublicKeyPacket.VERSION_6}) + { + JcaPGPKeyPair j1 = new JcaPGPKeyPair(version, PublicKeyAlgorithmTags.Ed25519, kp, date); + byte[] pubEnc = j1.getPublicKey().getEncoded(); + byte[] privEnc = j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Dedicated Ed25519 public key MUST be instanceof Ed25519PublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed25519PublicBCPGKey); + isTrue("Dedicated Ed25519 secret key MUST be instanceof Ed25519SecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed25519SecretBCPGKey); + + BcPGPKeyPair b1 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated Ed25519 public key MUST be instanceof Ed25519PublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed25519PublicBCPGKey); + isTrue("Dedicated Ed25519 secret key MUST be instanceof Ed25519SecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed25519SecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated Ed25519 public key MUST be instanceof Ed25519PublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed25519PublicBCPGKey); + isTrue("Dedicated Ed25519 secret key MUST be instanceof Ed25519SecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed25519SecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j2); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated Ed25519 public key MUST be instanceof Ed25519PublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed25519PublicBCPGKey); + isTrue("Dedicated Ed25519 secret key MUST be instanceof Ed25519SecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed25519SecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), b2.getPublicKey().getCreationTime().getTime()); + } + } + + private void testConversionOfBcKeyPair() + throws PGPException, IOException + { + Date date = currentTimeRounded(); + Ed25519KeyPairGenerator gen = new Ed25519KeyPairGenerator(); + gen.init(new Ed25519KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + + for (int version: new int[]{PublicKeyPacket.VERSION_4, PublicKeyPacket.VERSION_6}) + { + BcPGPKeyPair b1 = new BcPGPKeyPair(version, PublicKeyAlgorithmTags.Ed25519, kp, date); + byte[] pubEnc = b1.getPublicKey().getEncoded(); + byte[] privEnc = b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Dedicated Ed25519 public key MUST be instanceof Ed25519PublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed25519PublicBCPGKey); + isTrue("Dedicated Ed25519 secret key MUST be instanceof Ed25519SecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed25519SecretBCPGKey); + + JcaPGPKeyPair j1 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated Ed25519 public key MUST be instanceof Ed25519PublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed25519PublicBCPGKey); + isTrue("Dedicated Ed25519 secret key MUST be instanceof Ed25519SecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed25519SecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated Ed25519 public key MUST be instanceof Ed25519PublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed25519PublicBCPGKey); + isTrue("Dedicated Ed25519 secret key MUST be instanceof Ed25519SecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed25519SecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b2); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated Ed25519 public key MUST be instanceof Ed25519PublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed25519PublicBCPGKey); + isTrue("Dedicated Ed25519 secret key MUST be instanceof Ed25519SecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed25519SecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), j2.getPublicKey().getCreationTime().getTime()); + } + } + + private void testV4SigningVerificationWithJcaKey() + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException + { + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("EDDSA", new BouncyCastleProvider()); + gen.initialize(new EdDSAParameterSpec("Ed25519")); + KeyPair kp = gen.generateKeyPair(); + PGPKeyPair keyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.Ed25519, kp, date); + + byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8); + + PGPContentSignerBuilder contSigBuilder = new JcaPGPContentSignerBuilder( + keyPair.getPublicKey().getAlgorithm(), + HashAlgorithmTags.SHA512) + .setProvider(new BouncyCastleProvider()); + PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder); + sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey()); + sigGen.update(data); + PGPSignature signature = sigGen.generate(); + + PGPContentVerifierBuilderProvider contVerBuilder = new JcaPGPContentVerifierBuilderProvider() + .setProvider(new BouncyCastleProvider()); + signature.init(contVerBuilder, keyPair.getPublicKey()); + signature.update(data); + isTrue(signature.verify()); + } + + private void testV4SigningVerificationWithBcKey() + throws PGPException + { + Date date = currentTimeRounded(); + Ed25519KeyPairGenerator gen = new Ed25519KeyPairGenerator(); + gen.init(new Ed25519KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + BcPGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.Ed25519, kp, date); + + byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8); + + PGPContentSignerBuilder contSigBuilder = new BcPGPContentSignerBuilder( + keyPair.getPublicKey().getAlgorithm(), + HashAlgorithmTags.SHA512); + PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder); + sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey()); + sigGen.update(data); + PGPSignature signature = sigGen.generate(); + + PGPContentVerifierBuilderProvider contVerBuilder = new BcPGPContentVerifierBuilderProvider(); + signature.init(contVerBuilder, keyPair.getPublicKey()); + signature.update(data); + isTrue(signature.verify()); + } + + private void testConversionOfTestVectorKey() throws PGPException, IOException { + JcaPGPKeyConverter jc = new JcaPGPKeyConverter().setProvider(new BouncyCastleProvider()); + BcPGPKeyConverter bc = new BcPGPKeyConverter(); + // ed25519 public key from https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-hashed-data-stream-for-sign + Date creationTime = new Date(Pack.bigEndianToInt(Hex.decode("63877fe3"), 0) * 1000L); + byte[] k = Hex.decode("f94da7bb48d60a61e567706a6587d0331999bb9d891a08242ead84543df895a3"); + for (int version: new int[]{PublicKeyPacket.VERSION_4, PublicKeyPacket.VERSION_6}) + { + PGPPublicKey pgpk = new PGPPublicKey( + new PublicKeyPacket(version, PublicKeyAlgorithmTags.Ed25519, creationTime, new Ed25519PublicBCPGKey(k)), + new BcKeyFingerprintCalculator() + ); + + // convert parsed key to Jca public key + PublicKey jcpk = jc.getPublicKey(pgpk); + PGPPublicKey jck = jc.getPGPPublicKey(version, PublicKeyAlgorithmTags.Ed25519, jcpk, creationTime); + isEncodingEqual(pgpk.getEncoded(), jck.getEncoded()); + + // convert parsed key to Bc public key + AsymmetricKeyParameter bcpk = bc.getPublicKey(pgpk); + PGPPublicKey bck = bc.getPGPPublicKey(version, PublicKeyAlgorithmTags.Ed25519, null, bcpk, creationTime); + isEncodingEqual(pgpk.getEncoded(), bck.getEncoded()); + } + } + + public static void main(String[] args) + { + runTest(new DedicatedEd25519KeyPairTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedEd448KeyPairTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedEd448KeyPairTest.java new file mode 100644 index 0000000000..efd7208ec9 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedEd448KeyPairTest.java @@ -0,0 +1,200 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.Ed448PublicBCPGKey; +import org.bouncycastle.bcpg.Ed448SecretBCPGKey; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.generators.Ed448KeyPairGenerator; +import org.bouncycastle.crypto.params.Ed448KeyGenerationParameters; +import org.bouncycastle.jcajce.spec.EdDSAParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPKeyPair; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.PGPSignatureGenerator; +import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.util.Date; + +public class DedicatedEd448KeyPairTest + extends AbstractPgpKeyPairTest +{ + @Override + public String getName() + { + return "DedicatedEd448KeyPairTest"; + } + + @Override + public void performTest() + throws Exception + { + testConversionOfJcaKeyPair(); + testConversionOfBcKeyPair(); + testV4SigningVerificationWithJcaKey(); + testV4SigningVerificationWithBcKey(); + } + + private void testConversionOfJcaKeyPair() + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException, IOException + { + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("EDDSA", new BouncyCastleProvider()); + gen.initialize(new EdDSAParameterSpec("Ed448")); + KeyPair kp = gen.generateKeyPair(); + + for (int version: new int[]{PublicKeyPacket.VERSION_4, PublicKeyPacket.VERSION_6}) + { + JcaPGPKeyPair j1 = new JcaPGPKeyPair(version, PublicKeyAlgorithmTags.Ed448, kp, date); + byte[] pubEnc = j1.getPublicKey().getEncoded(); + byte[] privEnc = j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Dedicated Ed448 public key MUST be instanceof Ed448PublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed448PublicBCPGKey); + isTrue("Dedicated Ed448 secret key MUST be instanceof Ed448SecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed448SecretBCPGKey); + + BcPGPKeyPair b1 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated Ed448 public key MUST be instanceof Ed448PublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed448PublicBCPGKey); + isTrue("Dedicated Ed448 secret key MUST be instanceof Ed448SecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed448SecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated Ed448 public key MUST be instanceof Ed448PublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed448PublicBCPGKey); + isTrue("Dedicated Ed448 secret key MUST be instanceof Ed448SecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed448SecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j2); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated Ed448 public key MUST be instanceof Ed448PublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed448PublicBCPGKey); + isTrue("Dedicated Ed448 secret key MUST be instanceof Ed448SecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed448SecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), b2.getPublicKey().getCreationTime().getTime()); + } + } + + private void testConversionOfBcKeyPair() + throws PGPException, IOException + { + Date date = currentTimeRounded(); + Ed448KeyPairGenerator gen = new Ed448KeyPairGenerator(); + gen.init(new Ed448KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + + for (int version: new int[]{PublicKeyPacket.VERSION_4, PublicKeyPacket.VERSION_6}) + { + BcPGPKeyPair b1 = new BcPGPKeyPair(version, PublicKeyAlgorithmTags.Ed448, kp, date); + byte[] pubEnc = b1.getPublicKey().getEncoded(); + byte[] privEnc = b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Dedicated Ed448 public key MUST be instanceof Ed448PublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed448PublicBCPGKey); + isTrue("Dedicated Ed448 secret key MUST be instanceof Ed448SecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed448SecretBCPGKey); + + JcaPGPKeyPair j1 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated Ed448 public key MUST be instanceof Ed448PublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed448PublicBCPGKey); + isTrue("Dedicated Ed448 secret key MUST be instanceof Ed448SecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed448SecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated Ed448 public key MUST be instanceof Ed448PublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed448PublicBCPGKey); + isTrue("Dedicated Ed448 secret key MUST be instanceof Ed448SecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed448SecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b2); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated Ed448 public key MUST be instanceof Ed448PublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof Ed448PublicBCPGKey); + isTrue("Dedicated Ed448 secret key MUST be instanceof Ed448SecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof Ed448SecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), j2.getPublicKey().getCreationTime().getTime()); + } + } + + private void testV4SigningVerificationWithJcaKey() + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException + { + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("EDDSA", new BouncyCastleProvider()); + gen.initialize(new EdDSAParameterSpec("Ed448")); + KeyPair kp = gen.generateKeyPair(); + PGPKeyPair keyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.Ed448, kp, date); + + byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8); + + PGPContentSignerBuilder contSigBuilder = new JcaPGPContentSignerBuilder( + keyPair.getPublicKey().getAlgorithm(), + HashAlgorithmTags.SHA512) + .setProvider(new BouncyCastleProvider()); + PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder); + sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey()); + sigGen.update(data); + PGPSignature signature = sigGen.generate(); + + PGPContentVerifierBuilderProvider contVerBuilder = new JcaPGPContentVerifierBuilderProvider() + .setProvider(new BouncyCastleProvider()); + signature.init(contVerBuilder, keyPair.getPublicKey()); + signature.update(data); + isTrue(signature.verify()); + } + + private void testV4SigningVerificationWithBcKey() + throws PGPException + { + Date date = currentTimeRounded(); + Ed448KeyPairGenerator gen = new Ed448KeyPairGenerator(); + gen.init(new Ed448KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + BcPGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.Ed448, kp, date); + + byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8); + + PGPContentSignerBuilder contSigBuilder = new BcPGPContentSignerBuilder( + keyPair.getPublicKey().getAlgorithm(), + HashAlgorithmTags.SHA512); + PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder); + sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey()); + sigGen.update(data); + PGPSignature signature = sigGen.generate(); + + PGPContentVerifierBuilderProvider contVerBuilder = new BcPGPContentVerifierBuilderProvider(); + signature.init(contVerBuilder, keyPair.getPublicKey()); + signature.update(data); + isTrue(signature.verify()); + } + + public static void main(String[] args) + { + runTest(new DedicatedEd448KeyPairTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedX25519KeyPairTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedX25519KeyPairTest.java new file mode 100644 index 0000000000..b91bc4b441 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedX25519KeyPairTest.java @@ -0,0 +1,242 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.X25519PublicBCPGKey; +import org.bouncycastle.bcpg.X25519SecretBCPGKey; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.generators.X25519KeyPairGenerator; +import org.bouncycastle.crypto.params.X25519KeyGenerationParameters; +import org.bouncycastle.jcajce.spec.XDHParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openpgp.*; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; +import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.io.Streams; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.util.Date; + +public class DedicatedX25519KeyPairTest + extends AbstractPgpKeyPairTest +{ + @Override + public String getName() + { + return "DedicatedX25519KeyPairTest"; + } + + @Override + public void performTest() + throws Exception + { + testConversionOfJcaKeyPair(); + testConversionOfBcKeyPair(); + testV4MessageEncryptionDecryptionWithJcaKey(); + testV4MessageEncryptionDecryptionWithBcKey(); + } + + private void testConversionOfJcaKeyPair() + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException, IOException + { + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("XDH", new BouncyCastleProvider()); + gen.initialize(new XDHParameterSpec("X25519")); + KeyPair kp = gen.generateKeyPair(); + + for (int version: new int[]{PublicKeyPacket.VERSION_4, PublicKeyPacket.VERSION_6}) + { + JcaPGPKeyPair j1 = new JcaPGPKeyPair(version, PublicKeyAlgorithmTags.X25519, kp, date); + byte[] pubEnc = j1.getPublicKey().getEncoded(); + byte[] privEnc = j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Dedicated X25519 public key MUST be instanceof X25519PublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof X25519PublicBCPGKey); + isTrue("Dedicated X25519 secret key MUST be instanceof X25519SecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof X25519SecretBCPGKey); + + BcPGPKeyPair b1 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated X25519 public key MUST be instanceof X25519PublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof X25519PublicBCPGKey); + isTrue("Dedicated X25519 secret key MUST be instanceof X25519SecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof X25519SecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated X25519 public key MUST be instanceof X25519PublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof X25519PublicBCPGKey); + isTrue("Dedicated X25519 secret key MUST be instanceof X25519SecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof X25519SecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j2); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated X25519 public key MUST be instanceof X25519PublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof X25519PublicBCPGKey); + isTrue("Dedicated X25519 secret key MUST be instanceof X25519SecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof X25519SecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), b2.getPublicKey().getCreationTime().getTime()); + } + } + + private void testConversionOfBcKeyPair() + throws PGPException, IOException + { + Date date = currentTimeRounded(); + X25519KeyPairGenerator gen = new X25519KeyPairGenerator(); + gen.init(new X25519KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + + for (int version: new int[]{PublicKeyPacket.VERSION_4, PublicKeyPacket.VERSION_6}) + { + BcPGPKeyPair b1 = new BcPGPKeyPair(version, PublicKeyAlgorithmTags.X25519, kp, date); + byte[] pubEnc = b1.getPublicKey().getEncoded(); + byte[] privEnc = b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Dedicated X25519 public key MUST be instanceof X25519PublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof X25519PublicBCPGKey); + isTrue("Dedicated X25519 secret key MUST be instanceof X25519SecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof X25519SecretBCPGKey); + + JcaPGPKeyPair j1 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated X25519 public key MUST be instanceof X25519PublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof X25519PublicBCPGKey); + isTrue("Dedicated X25519 secret key MUST be instanceof X25519SecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof X25519SecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated X25519 public key MUST be instanceof X25519PublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof X25519PublicBCPGKey); + isTrue("Dedicated X25519 secret key MUST be instanceof X25519SecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof X25519SecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b2); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated X25519 public key MUST be instanceof X25519PublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof X25519PublicBCPGKey); + isTrue("Dedicated X25519 secret key MUST be instanceof X25519SecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof X25519SecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), j2.getPublicKey().getCreationTime().getTime()); + } + } + + private void testV4MessageEncryptionDecryptionWithJcaKey() + throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException + { + BouncyCastleProvider provider = new BouncyCastleProvider(); + + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("XDH", provider); + gen.initialize(new XDHParameterSpec("X25519")); + KeyPair kp = gen.generateKeyPair(); + PGPKeyPair keyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.X25519, kp, date); + + byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8); + + PGPDataEncryptorBuilder encBuilder = new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256) + .setProvider(provider); + PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encBuilder); + PublicKeyKeyEncryptionMethodGenerator metGen = new JcePublicKeyKeyEncryptionMethodGenerator(keyPair.getPublicKey()) + .setProvider(provider); + encGen.addMethod(metGen); + PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator(); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + OutputStream encOut = encGen.open(bOut, new byte[4096]); + OutputStream litOut = litGen.open(encOut, PGPLiteralData.BINARY, "", PGPLiteralData.NOW, new byte[4096]); + litOut.write(data); + litGen.close(); + encGen.close(); + + byte[] encrypted = bOut.toByteArray(); + + ByteArrayInputStream bIn = new ByteArrayInputStream(encrypted); + PGPObjectFactory objectFactory = new JcaPGPObjectFactory(bIn); + PGPEncryptedDataList encDataList = (PGPEncryptedDataList) objectFactory.nextObject(); + PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encDataList.get(0); + PublicKeyDataDecryptorFactory decFactory = new JcePublicKeyDataDecryptorFactoryBuilder() + .setProvider(provider) + .build(keyPair.getPrivateKey()); + InputStream decIn = encData.getDataStream(decFactory); + objectFactory = new JcaPGPObjectFactory(decIn); + PGPLiteralData lit = (PGPLiteralData) objectFactory.nextObject(); + InputStream litIn = lit.getDataStream(); + byte[] plaintext = Streams.readAll(litIn); + litIn.close(); + decIn.close(); + + isTrue(Arrays.areEqual(data, plaintext)); + } + + private void testV4MessageEncryptionDecryptionWithBcKey() + throws PGPException, IOException + { + Date date = currentTimeRounded(); + X25519KeyPairGenerator gen = new X25519KeyPairGenerator(); + gen.init(new X25519KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + BcPGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.X25519, kp, date); + + byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8); + + PGPDataEncryptorBuilder encBuilder = new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256); + PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encBuilder); + PublicKeyKeyEncryptionMethodGenerator metGen = new BcPublicKeyKeyEncryptionMethodGenerator(keyPair.getPublicKey()); + encGen.addMethod(metGen); + PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator(); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + OutputStream encOut = encGen.open(bOut, new byte[4096]); + OutputStream litOut = litGen.open(encOut, PGPLiteralData.BINARY, "", PGPLiteralData.NOW, new byte[4096]); + litOut.write(data); + litGen.close(); + encGen.close(); + + byte[] encrypted = bOut.toByteArray(); + + ByteArrayInputStream bIn = new ByteArrayInputStream(encrypted); + PGPObjectFactory objectFactory = new BcPGPObjectFactory(bIn); + PGPEncryptedDataList encDataList = (PGPEncryptedDataList) objectFactory.nextObject(); + PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encDataList.get(0); + PublicKeyDataDecryptorFactory decFactory = new BcPublicKeyDataDecryptorFactory(keyPair.getPrivateKey()); + InputStream decIn = encData.getDataStream(decFactory); + objectFactory = new BcPGPObjectFactory(decIn); + PGPLiteralData lit = (PGPLiteralData) objectFactory.nextObject(); + InputStream litIn = lit.getDataStream(); + byte[] plaintext = Streams.readAll(litIn); + litIn.close(); + decIn.close(); + + isTrue(Arrays.areEqual(data, plaintext)); + } + + public static void main(String[] args) + { + runTest(new DedicatedX25519KeyPairTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedX448KeyPairTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedX448KeyPairTest.java new file mode 100644 index 0000000000..909c6c673a --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedX448KeyPairTest.java @@ -0,0 +1,242 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.X448PublicBCPGKey; +import org.bouncycastle.bcpg.X448SecretBCPGKey; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.generators.X448KeyPairGenerator; +import org.bouncycastle.crypto.params.X448KeyGenerationParameters; +import org.bouncycastle.jcajce.spec.XDHParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openpgp.*; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; +import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.io.Streams; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.util.Date; + +public class DedicatedX448KeyPairTest + extends AbstractPgpKeyPairTest +{ + @Override + public String getName() + { + return "DedicatedX448KeyPairTest"; + } + + @Override + public void performTest() + throws Exception + { + testConversionOfJcaKeyPair(); + testConversionOfBcKeyPair(); + testV4MessageEncryptionDecryptionWithJcaKey(); + testV4MessageEncryptionDecryptionWithBcKey(); + } + + private void testConversionOfJcaKeyPair() + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException, IOException + { + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("XDH", new BouncyCastleProvider()); + gen.initialize(new XDHParameterSpec("X448")); + KeyPair kp = gen.generateKeyPair(); + + for (int version: new int[]{PublicKeyPacket.VERSION_4, PublicKeyPacket.VERSION_6}) + { + JcaPGPKeyPair j1 = new JcaPGPKeyPair(version, PublicKeyAlgorithmTags.X448, kp, date); + byte[] pubEnc = j1.getPublicKey().getEncoded(); + byte[] privEnc = j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Dedicated X448 public key MUST be instanceof X448PublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof X448PublicBCPGKey); + isTrue("Dedicated X448 secret key MUST be instanceof X448SecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof X448SecretBCPGKey); + + BcPGPKeyPair b1 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated X448 public key MUST be instanceof X448PublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof X448PublicBCPGKey); + isTrue("Dedicated X448 secret key MUST be instanceof X448SecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof X448SecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated X448 public key MUST be instanceof X448PublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof X448PublicBCPGKey); + isTrue("Dedicated X448 secret key MUST be instanceof X448SecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof X448SecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j2); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated X448 public key MUST be instanceof X448PublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof X448PublicBCPGKey); + isTrue("Dedicated X448 secret key MUST be instanceof X448SecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof X448SecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), b2.getPublicKey().getCreationTime().getTime()); + } + } + + private void testConversionOfBcKeyPair() + throws PGPException, IOException + { + Date date = currentTimeRounded(); + X448KeyPairGenerator gen = new X448KeyPairGenerator(); + gen.init(new X448KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + + for (int version: new int[]{PublicKeyPacket.VERSION_4, PublicKeyPacket.VERSION_6}) + { + BcPGPKeyPair b1 = new BcPGPKeyPair(version, PublicKeyAlgorithmTags.X448, kp, date); + byte[] pubEnc = b1.getPublicKey().getEncoded(); + byte[] privEnc = b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Dedicated X448 public key MUST be instanceof X448PublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof X448PublicBCPGKey); + isTrue("Dedicated X448 secret key MUST be instanceof X448SecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof X448SecretBCPGKey); + + JcaPGPKeyPair j1 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated X448 public key MUST be instanceof X448PublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof X448PublicBCPGKey); + isTrue("Dedicated X448 secret key MUST be instanceof X448SecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof X448SecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated X448 public key MUST be instanceof X448PublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof X448PublicBCPGKey); + isTrue("Dedicated X448 secret key MUST be instanceof X448SecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof X448SecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b2); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Dedicated X448 public key MUST be instanceof X448PublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof X448PublicBCPGKey); + isTrue("Dedicated X448 secret key MUST be instanceof X448SecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof X448SecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), j2.getPublicKey().getCreationTime().getTime()); + } + } + + private void testV4MessageEncryptionDecryptionWithJcaKey() + throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException + { + BouncyCastleProvider provider = new BouncyCastleProvider(); + + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("XDH", provider); + gen.initialize(new XDHParameterSpec("X448")); + KeyPair kp = gen.generateKeyPair(); + PGPKeyPair keyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.X448, kp, date); + + byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8); + + PGPDataEncryptorBuilder encBuilder = new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256) + .setProvider(provider); + PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encBuilder); + PublicKeyKeyEncryptionMethodGenerator metGen = new JcePublicKeyKeyEncryptionMethodGenerator(keyPair.getPublicKey()) + .setProvider(provider); + encGen.addMethod(metGen); + PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator(); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + OutputStream encOut = encGen.open(bOut, new byte[4096]); + OutputStream litOut = litGen.open(encOut, PGPLiteralData.BINARY, "", PGPLiteralData.NOW, new byte[4096]); + litOut.write(data); + litGen.close(); + encGen.close(); + + byte[] encrypted = bOut.toByteArray(); + + ByteArrayInputStream bIn = new ByteArrayInputStream(encrypted); + PGPObjectFactory objectFactory = new JcaPGPObjectFactory(bIn); + PGPEncryptedDataList encDataList = (PGPEncryptedDataList) objectFactory.nextObject(); + PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encDataList.get(0); + PublicKeyDataDecryptorFactory decFactory = new JcePublicKeyDataDecryptorFactoryBuilder() + .setProvider(provider) + .build(keyPair.getPrivateKey()); + InputStream decIn = encData.getDataStream(decFactory); + objectFactory = new JcaPGPObjectFactory(decIn); + PGPLiteralData lit = (PGPLiteralData) objectFactory.nextObject(); + InputStream litIn = lit.getDataStream(); + byte[] plaintext = Streams.readAll(litIn); + litIn.close(); + decIn.close(); + + isTrue(Arrays.areEqual(data, plaintext)); + } + + private void testV4MessageEncryptionDecryptionWithBcKey() + throws PGPException, IOException + { + Date date = currentTimeRounded(); + X448KeyPairGenerator gen = new X448KeyPairGenerator(); + gen.init(new X448KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + BcPGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.X448, kp, date); + + byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8); + + PGPDataEncryptorBuilder encBuilder = new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256); + PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encBuilder); + PublicKeyKeyEncryptionMethodGenerator metGen = new BcPublicKeyKeyEncryptionMethodGenerator(keyPair.getPublicKey()); + encGen.addMethod(metGen); + PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator(); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + OutputStream encOut = encGen.open(bOut, new byte[4096]); + OutputStream litOut = litGen.open(encOut, PGPLiteralData.BINARY, "", PGPLiteralData.NOW, new byte[4096]); + litOut.write(data); + litGen.close(); + encGen.close(); + + byte[] encrypted = bOut.toByteArray(); + + ByteArrayInputStream bIn = new ByteArrayInputStream(encrypted); + PGPObjectFactory objectFactory = new BcPGPObjectFactory(bIn); + PGPEncryptedDataList encDataList = (PGPEncryptedDataList)objectFactory.nextObject(); + PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData)encDataList.get(0); + PublicKeyDataDecryptorFactory decFactory = new BcPublicKeyDataDecryptorFactory(keyPair.getPrivateKey()); + InputStream decIn = encData.getDataStream(decFactory); + objectFactory = new BcPGPObjectFactory(decIn); + PGPLiteralData lit = (PGPLiteralData)objectFactory.nextObject(); + InputStream litIn = lit.getDataStream(); + byte[] plaintext = Streams.readAll(litIn); + litIn.close(); + decIn.close(); + + isTrue(Arrays.areEqual(data, plaintext)); + } + + public static void main(String[] args) + { + runTest(new DedicatedX448KeyPairTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/ECDSAKeyPairTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/ECDSAKeyPairTest.java new file mode 100644 index 0000000000..41c99bdc72 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/ECDSAKeyPairTest.java @@ -0,0 +1,272 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.*; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.bouncycastle.openpgp.*; +import org.bouncycastle.openpgp.bc.BcPGPSecretKeyRing; +import org.bouncycastle.openpgp.jcajce.JcaPGPSecretKeyRing; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.util.Date; + +public class ECDSAKeyPairTest + extends AbstractPgpKeyPairTest +{ + + private static final String PRIME256v1 = "" + + "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "Version: BCPG v@RELEASE_NAME@\n" + + "\n" + + "lHcEZkH7VRMIKoZIzj0DAQcCAwQee5wkHVVrG7u7CcrHoZOaC+reK0wn2Y5XPJoU\n" + + "O6geh1j2qXHj4+f+a6lav5hzKIJZHkgBYcS0aeABgWNjKsHbAAD/b4K93MJF7c2l\n" + + "4Y7ojBqTuZAOOD0Dyqe8MTXXyDUWN/0R/w==\n" + + "=mPB9\n" + + "-----END PGP PRIVATE KEY BLOCK-----"; + private static final String SECP384r1 = "" + + "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "Version: BCPG v@RELEASE_NAME@\n" + + "\n" + + "lKQEZkH7VhMFK4EEACIDAwQgkKs+EzJaFLgMZH5Fp1S8DCXZC0OildnuQX6F7Jzt\n" + + "BgkYyfDZ/F2KNistCqfsmxWnwAxtdRuuY2PfehWktQBQaID0OfXUnOC2E5961b3/\n" + + "7xoZU26T0npmTqX0P/wuXawAAX9S2V72/xeShrcIwIwy2QvCcsW9ATBSQ6U+T7KZ\n" + + "zzFisUiqCgYa/9hoSNnu7iNrnrcYlQ==\n" + + "=SyFg\n" + + "-----END PGP PRIVATE KEY BLOCK-----"; + private static final String SECP521r1 = "" + + "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "Version: BCPG v@RELEASE_NAME@\n" + + "\n" + + "lNkEZkH7VhMFK4EEACMEIwQBxt7DenSWrjuJGR0ouSwylW3ZC6mX4S+A5Cav7nz3\n" + + "DninA8Rdt3Cd5sHQ1IWea+J05NUZDKbOL417lUSPkAVLot0B/Qis90wODcGnAXbc\n" + + "m+m7rN2/Waryj/EsxLxub4UNtyZ405C8dDo9ch2JRfHiH6R1dwyqD9+yY2lOPYO+\n" + + "tn5fx/4AAgIDG9+DPtDf91tBMhBKc0f++t6aV115HLlyIpnEipThSwMTgzWm0uPZ\n" + + "KD3CifJeUU/TMk9IGFYvRlaWBQfrB3V/Ahz4\n" + + "=DD95\n" + + "-----END PGP PRIVATE KEY BLOCK-----"; + private static final String BRAINPOOLP256r1 = "" + + "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "Version: BCPG v@RELEASE_NAME@\n" + + "\n" + + "lHgEZkH7VhMJKyQDAwIIAQEHAgMEj7YxVg4/2p4uuhcpRqGl2i+vDhjx8YhUUNJX\n" + + "RNFozBuIWJ6zkW3wRKdD/7Y7tzKNwyHmZ4FBFCcUoLliLeD4SAABAIkEm4iT1g0B\n" + + "Bo9vkUrUcP2b+vtOuwtmrvGrT0VzVXYlD5M=\n" + + "=vZRh\n" + + "-----END PGP PRIVATE KEY BLOCK-----"; + private static final String BRAINPOOLP384r1 = "" + + "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "Version: BCPG v@RELEASE_NAME@\n" + + "\n" + + "lKgEZkH7VhMJKyQDAwIIAQELAwMEYm1fhilklF53Pj91awsoO0aZsppmPk9KNESD\n" + + "H7/gSK86gl+yhf4/oKSxeOFDHCU2es6Iijq/TCIaAjeFH3ITEyQ4tPdnDqQSz2xq\n" + + "o6wtRTW3cRD9oyoOT8bAMdm+RYpJAAF5AXAfxp3VtxqVVxnR1mC3Z3nL25zmvdu1\n" + + "oPRvA9fenVxTOlyU6X9qCycSuxamkPO7Gic=\n" + + "=2eJn\n" + + "-----END PGP PRIVATE KEY BLOCK-----"; + private static final String BRAINPOOLP521r1 = "" + + "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "Version: BCPG v@RELEASE_NAME@\n" + + "\n" + + "lNgEZkH7VhMJKyQDAwIIAQENBAMEbSjn4lQKNnC50PzeUtenikvF62KR7HfOLJTA\n" + + "r/T17tFx3Qb6Ek/xQWIJ5nIHroOrduZjLigPOXqQ+GNhCgdNPGUqAWw1sfQ86nrx\n" + + "jqlr67na3F3eaTJr9ajr2V37/5uHnuryJnkyy2laFdOGD0Ad9/bQkvXYoWVm0P07\n" + + "uCPnexEAAgCSUoeS3c+DAZlWETdyuSDyvHK7GLO67+CgVsEyqBF/Kch/vhBZFWXA\n" + + "Cs9lph8la5B0faKH5XSbeReudKGh/MjfIJo=\n" + + "=MZeT\n" + + "-----END PGP PRIVATE KEY BLOCK-----"; + + @Override + public String getName() + { + return "ECDSAKeyPairTest"; + } + + @Override + public void performTest() + throws Exception + { + testConversionOfFreshJcaKeyPair(); + testConversionOfParsedJcaKeyPair(); + testConversionOfParsedBcKeyPair(); + + } + + private void testConversionOfParsedJcaKeyPair() + throws PGPException, IOException + { + parseAndConvertJca(BRAINPOOLP256r1); + parseAndConvertJca(BRAINPOOLP384r1); + parseAndConvertJca(BRAINPOOLP521r1); + parseAndConvertJca(PRIME256v1); + parseAndConvertJca(SECP384r1); + parseAndConvertJca(SECP521r1); + } + + private void parseAndConvertJca(String curve) + throws IOException, PGPException + { + JcaPGPKeyConverter c = new JcaPGPKeyConverter().setProvider(new BouncyCastleProvider()); + PGPKeyPair parsed = parseJca(curve); + byte[] pubEnc = parsed.getPublicKey().getEncoded(); + byte[] privEnc = parsed.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + + JcaPGPKeyPair j1 = new JcaPGPKeyPair( + PublicKeyPacket.VERSION_4, + parsed.getPublicKey().getAlgorithm(), + new KeyPair(c.getPublicKey(parsed.getPublicKey()), + c.getPrivateKey(parsed.getPrivateKey())), + parsed.getPublicKey().getCreationTime()); + isEncodingEqual("ECDSA Public key (" + curve + ") encoding mismatch", pubEnc, j1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + + BcPGPKeyPair b1 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + + JcaPGPKeyPair j2 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + + BcPGPKeyPair b2 = toBcKeyPair(j2); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + } + + private void testConversionOfParsedBcKeyPair() + throws PGPException, IOException + { + parseAndConvertBc(BRAINPOOLP256r1); + parseAndConvertBc(BRAINPOOLP384r1); + parseAndConvertBc(BRAINPOOLP521r1); + parseAndConvertBc(PRIME256v1); + parseAndConvertBc(SECP384r1); + parseAndConvertBc(SECP521r1); + } + + private void parseAndConvertBc(String curve) + throws IOException, PGPException + { + BcPGPKeyConverter c = new BcPGPKeyConverter(); + PGPKeyPair parsed = parseBc(curve); + byte[] pubEnc = parsed.getPublicKey().getEncoded(); + byte[] privEnc = parsed.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + + BcPGPKeyPair b1 = new BcPGPKeyPair( + PublicKeyPacket.VERSION_4, + parsed.getPublicKey().getAlgorithm(), + new AsymmetricCipherKeyPair( + c.getPublicKey(parsed.getPublicKey()), + c.getPrivateKey(parsed.getPrivateKey())), + parsed.getPublicKey().getCreationTime()); + isEncodingEqual(pubEnc, b1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + + JcaPGPKeyPair j1 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + + BcPGPKeyPair b2 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + + JcaPGPKeyPair j2 = toJcaKeyPair(b2); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + + } + + private PGPKeyPair parseJca(String armored) + throws IOException, PGPException + { + ByteArrayInputStream bIn = new ByteArrayInputStream(armored.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + JcaPGPSecretKeyRing ring = new JcaPGPSecretKeyRing(pIn); + PGPSecretKey sk = ring.getSecretKey(); + return new PGPKeyPair(sk.getPublicKey(), sk.extractPrivateKey(null)); + } + + private PGPKeyPair parseBc(String armored) + throws IOException, PGPException + { + ByteArrayInputStream bIn = new ByteArrayInputStream(armored.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + BcPGPSecretKeyRing ring = new BcPGPSecretKeyRing(pIn); + PGPSecretKey sk = ring.getSecretKey(); + return new PGPKeyPair(sk.getPublicKey(), sk.extractPrivateKey(null)); + } + + private void testConversionOfFreshJcaKeyPair() + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException, IOException + { + for (String curve : new String[] { + "prime256v1", + "secp384r1", + "secp521r1", + "brainpoolP256r1", + "brainpoolP384r1", + "brainpoolP512r1" + }) + { + testConversionOfFreshJcaKeyPair(curve); + } + } + + private void testConversionOfFreshJcaKeyPair(String curve) + throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, PGPException + { + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("ECDSA", new BouncyCastleProvider()); + gen.initialize(new ECNamedCurveGenParameterSpec(curve)); + KeyPair kp = gen.generateKeyPair(); + + JcaPGPKeyPair j1 = new JcaPGPKeyPair(PublicKeyPacket.VERSION_4, PublicKeyAlgorithmTags.ECDSA, kp, date); + byte[] pubEnc = j1.getPublicKey().getEncoded(); + byte[] privEnc = j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Legacy ECDSA public key MUST be instanceof ECDSAPublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDSAPublicBCPGKey); + isTrue("Legacy ECDSA secret key MUST be instanceof ECSecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + BcPGPKeyPair b1 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy ECDSA public key MUST be instanceof ECDSAPublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDSAPublicBCPGKey); + isTrue(" Legacy ECDSA secret key MUST be instanceof ECSecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy ECDSA public key MUST be instanceof ECDSAPublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDSAPublicBCPGKey); + isTrue("Legacy ECDSA secret key MUST be instanceof ECSecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j2); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy ECDSA public key MUST be instanceof ECDSAPublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDSAPublicBCPGKey); + isTrue("Legacy ECDSA secret key MUST be instanceof ECSecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), b2.getPublicKey().getCreationTime().getTime()); + } + + public static void main(String[] args) + { + runTest(new ECDSAKeyPairTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/EdDSAKeyConversionWithLeadingZeroTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/EdDSAKeyConversionWithLeadingZeroTest.java new file mode 100644 index 0000000000..b5aef89e11 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/EdDSAKeyConversionWithLeadingZeroTest.java @@ -0,0 +1,112 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.test.AbstractPacketTest; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.util.encoders.Hex; + +import java.security.*; +import java.security.spec.*; +import java.util.Date; + +public class EdDSAKeyConversionWithLeadingZeroTest + extends AbstractPacketTest +{ + @Override + public String getName() + { + return "EdDSALeadingZero"; + } + + private static final String ED448_KEY_WITH_LEADING_ZERO = "308183020101300506032b6571043b0439fe2c82fd07b0e8b5da002ee4964e55a357bfdd2192fe43a40b150e6c5a8f8202f140dd34ede17dc10fef9a98bf8188425c14bd1a76a308cfb7813a0000728cbb07c590e2cb282834cc22d7a1f775f729986c4754e7035695dee34057403e98e94cf5012007c3236f4894af039e668acb746fcf8a00"; + private static final String ED448_PUB_WITH_LEADING_ZERO = "3043300506032b6571033a0000728cbb07c590e2cb282834cc22d7a1f775f729986c4754e7035695dee34057403e98e94cf5012007c3236f4894af039e668acb746fcf8a00"; + + private static final String ED25519_KEY_WITH_LEADING_ZERO = "3051020101300506032b65700422042077ee5931a6d454f85acd9cc28bb2fa8c340e10f7cbf0193f1f898a5c22e77f4281210000dcd38e8ec0978690a4bbc8ac7787d311e741c394ba839ad9cc15e9ba21deb1"; + private static final String ED25519_PUB_WITH_LEADING_ZERO = "302a300506032b657003210000dcd38e8ec0978690a4bbc8ac7787d311e741c394ba839ad9cc15e9ba21deb1"; + + @Override + public void performTest() + throws Exception + { + testWithEd448KeyWithLeadingZero(); + testWithEd25519KeyWithLeadingZero(); + } + + private void testWithEd448KeyWithLeadingZero() + throws NoSuchAlgorithmException, InvalidKeySpecException, PGPException, InvalidKeyException, SignatureException + { + JcaPGPKeyConverter jcaPGPKeyConverter = new JcaPGPKeyConverter().setProvider(new BouncyCastleProvider()); + + KeyFactory factory = KeyFactory.getInstance("EdDSA", new BouncyCastleProvider()); + + PublicKey pubKey = factory.generatePublic(new X509EncodedKeySpec(Hex.decode(ED448_PUB_WITH_LEADING_ZERO))); + PrivateKey privKey = factory.generatePrivate(new PKCS8EncodedKeySpec(Hex.decode(ED448_KEY_WITH_LEADING_ZERO))); + KeyPair keyPair = new KeyPair(pubKey, privKey); + + Date creationDate = new Date(); + PGPKeyPair jcaPgpPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.Ed448, keyPair, creationDate); + isTrue("public key encoding before conversion MUST have leading 0", + jcaPgpPair.getPublicKey().getPublicKeyPacket().getKey().getEncoded()[0] == 0); // leading 0 + + PublicKey cPubKey = jcaPGPKeyConverter.getPublicKey(jcaPgpPair.getPublicKey()); + PrivateKey cPrivKey = jcaPGPKeyConverter.getPrivateKey(jcaPgpPair.getPrivateKey()); + + testSignature(cPrivKey, pubKey, "Ed448"); + testSignature(privKey, cPubKey, "Ed448"); + + jcaPgpPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.Ed448, new KeyPair(cPubKey, cPrivKey), creationDate); + isTrue("public key encoding after conversion MUST have leading 0", + jcaPgpPair.getPublicKey().getPublicKeyPacket().getKey().getEncoded()[0] == 0); // leading 0 is preserved + } + + + private void testWithEd25519KeyWithLeadingZero() + throws NoSuchAlgorithmException, InvalidKeySpecException, PGPException, InvalidKeyException, SignatureException + { + JcaPGPKeyConverter jcaPGPKeyConverter = new JcaPGPKeyConverter().setProvider(new BouncyCastleProvider()); + + KeyFactory factory = KeyFactory.getInstance("EdDSA", new BouncyCastleProvider()); + + PublicKey pubKey = factory.generatePublic(new X509EncodedKeySpec(Hex.decode(ED25519_PUB_WITH_LEADING_ZERO))); + PrivateKey privKey = factory.generatePrivate(new PKCS8EncodedKeySpec(Hex.decode(ED25519_KEY_WITH_LEADING_ZERO))); + KeyPair keyPair = new KeyPair(pubKey, privKey); + + Date creationDate = new Date(); + PGPKeyPair jcaPgpPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.Ed25519, keyPair, creationDate); + isTrue("public key encoding before conversion MUST have leading 0", + jcaPgpPair.getPublicKey().getPublicKeyPacket().getKey().getEncoded()[0] == 0); // leading 0 + + PublicKey cPubKey = jcaPGPKeyConverter.getPublicKey(jcaPgpPair.getPublicKey()); + PrivateKey cPrivKey = jcaPGPKeyConverter.getPrivateKey(jcaPgpPair.getPrivateKey()); + + testSignature(cPrivKey, pubKey, "Ed25519"); + testSignature(privKey, cPubKey, "Ed25519"); + + jcaPgpPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.Ed25519, new KeyPair(cPubKey, cPrivKey), creationDate); + isTrue("public key encoding after conversion MUST have leading 0", + jcaPgpPair.getPublicKey().getPublicKeyPacket().getKey().getEncoded()[0] == 0); // leading 0 is preserved + } + + private void testSignature(PrivateKey privateKey, PublicKey publicKey, String edAlgo) + throws NoSuchAlgorithmException, SignatureException, InvalidKeyException + { + Signature signature = Signature.getInstance(edAlgo, new BouncyCastleProvider()); + signature.initSign(privateKey); + signature.update("Hello, World!\n".getBytes()); + byte[] sig = signature.sign(); + + signature.initVerify(publicKey); + signature.update("Hello, World!\n".getBytes()); + isTrue("Signature MUST verify", signature.verify(sig)); + } + + public static void main(String[] args) + { + Security.addProvider(new BouncyCastleProvider()); + runTest(new EdDSAKeyConversionWithLeadingZeroTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/LegacyEd25519KeyPairTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/LegacyEd25519KeyPairTest.java new file mode 100644 index 0000000000..f3efe8bc1e --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/LegacyEd25519KeyPairTest.java @@ -0,0 +1,193 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.EdDSAPublicBCPGKey; +import org.bouncycastle.bcpg.EdSecretBCPGKey; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator; +import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters; +import org.bouncycastle.jcajce.spec.EdDSAParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPKeyPair; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.PGPSignatureGenerator; +import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.util.Date; + +public class LegacyEd25519KeyPairTest + extends AbstractPgpKeyPairTest +{ + @Override + public String getName() + { + return "LegacyEd25519KeyPairTest"; + } + + @Override + public void performTest() + throws Exception + { + testConversionOfJcaKeyPair(); + testConversionOfBcKeyPair(); + testV4SigningVerificationWithJcaKey(); + testV4SigningVerificationWithBcKey(); + } + + private void testV4SigningVerificationWithJcaKey() + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException + { + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("EDDSA", new BouncyCastleProvider()); + gen.initialize(new EdDSAParameterSpec("Ed25519")); + KeyPair kp = gen.generateKeyPair(); + PGPKeyPair keyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.EDDSA_LEGACY, kp, date); + + byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8); + + PGPContentSignerBuilder contSigBuilder = new JcaPGPContentSignerBuilder( + keyPair.getPublicKey().getAlgorithm(), + HashAlgorithmTags.SHA512) + .setProvider(new BouncyCastleProvider()); + PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder); + sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey()); + sigGen.update(data); + PGPSignature signature = sigGen.generate(); + + PGPContentVerifierBuilderProvider contVerBuilder = new JcaPGPContentVerifierBuilderProvider() + .setProvider(new BouncyCastleProvider()); + signature.init(contVerBuilder, keyPair.getPublicKey()); + signature.update(data); + isTrue(signature.verify()); + } + + private void testV4SigningVerificationWithBcKey() + throws PGPException + { + Date date = currentTimeRounded(); + Ed25519KeyPairGenerator gen = new Ed25519KeyPairGenerator(); + gen.init(new Ed25519KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + BcPGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.EDDSA_LEGACY, kp, date); + + byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8); + + PGPContentSignerBuilder contSigBuilder = new BcPGPContentSignerBuilder( + keyPair.getPublicKey().getAlgorithm(), + HashAlgorithmTags.SHA512); + PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder); + sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey()); + sigGen.update(data); + PGPSignature signature = sigGen.generate(); + + PGPContentVerifierBuilderProvider contVerBuilder = new BcPGPContentVerifierBuilderProvider(); + signature.init(contVerBuilder, keyPair.getPublicKey()); + signature.update(data); + isTrue(signature.verify()); + } + + private void testConversionOfJcaKeyPair() + throws NoSuchAlgorithmException, PGPException, InvalidAlgorithmParameterException, IOException + { + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("EDDSA", new BouncyCastleProvider()); + gen.initialize(new EdDSAParameterSpec("Ed25519")); + KeyPair kp = gen.generateKeyPair(); + + JcaPGPKeyPair j1 = new JcaPGPKeyPair(PublicKeyAlgorithmTags.EDDSA_LEGACY, kp, date); + byte[] pubEnc = j1.getPublicKey().getEncoded(); + byte[] privEnc = j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Legacy Ed25519 public key MUST be instanceof EdDSAPublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed25519 secret key MUST be instanceof EdSecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + BcPGPKeyPair b1 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy Ed25519 public key MUST be instanceof EdDSAPublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed25519 secret key MUST be instanceof EdSecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy Ed25519 public key MUST be instanceof EdDSAPublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed25519 secret key MUST be instanceof EdSecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j2); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy Ed25519 public key MUST be instanceof EdDSAPublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed25519 secret key MUST be instanceof EdSecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), b2.getPublicKey().getCreationTime().getTime()); + } + + private void testConversionOfBcKeyPair() + throws PGPException, IOException + { + Date date = currentTimeRounded(); + Ed25519KeyPairGenerator gen = new Ed25519KeyPairGenerator(); + gen.init(new Ed25519KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + + BcPGPKeyPair b1 = new BcPGPKeyPair(PublicKeyAlgorithmTags.EDDSA_LEGACY, kp, date); + byte[] pubEnc = b1.getPublicKey().getEncoded(); + byte[] privEnc = b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Legacy Ed25519 public key MUST be instanceof EdDSAPublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed25519 secret key MUST be instanceof EdSecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + JcaPGPKeyPair j1 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy Ed25519 public key MUST be instanceof EdDSAPublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed25519 secret key MUST be instanceof EdSecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy Ed25519 public key MUST be instanceof EdDSAPublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed25519 secret key MUST be instanceof EdSecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b2); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy Ed25519 public key MUST be instanceof EdDSAPublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed25519 secret key MUST be instanceof EdSecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), j2.getPublicKey().getCreationTime().getTime()); + } + + public static void main(String[] args) + { + runTest(new LegacyEd25519KeyPairTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/LegacyEd448KeyPairTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/LegacyEd448KeyPairTest.java new file mode 100644 index 0000000000..a79ac28e1c --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/LegacyEd448KeyPairTest.java @@ -0,0 +1,197 @@ +package org.bouncycastle.openpgp.test; + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Date; + +import org.bouncycastle.bcpg.EdDSAPublicBCPGKey; +import org.bouncycastle.bcpg.EdSecretBCPGKey; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.generators.Ed448KeyPairGenerator; +import org.bouncycastle.crypto.params.Ed448KeyGenerationParameters; +import org.bouncycastle.jcajce.spec.EdDSAParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPKeyPair; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.PGPSignatureGenerator; +import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.util.Strings; + +public class LegacyEd448KeyPairTest + extends AbstractPgpKeyPairTest +{ + @Override + public String getName() + { + return "LegacyEd448KeyPairTest"; + } + + @Override + public void performTest() + throws Exception + { + testConversionOfJcaKeyPair(); + testConversionOfBcKeyPair(); + testV4SigningVerificationWithJcaKey(); + testV4SigningVerificationWithBcKey(); + } + + private void testV4SigningVerificationWithJcaKey() + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException + { + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("EDDSA", new BouncyCastleProvider()); + gen.initialize(new EdDSAParameterSpec("Ed448")); + KeyPair kp = gen.generateKeyPair(); + PGPKeyPair keyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.EDDSA_LEGACY, kp, date); + + byte[] data = Strings.toByteArray("Hello, World!\n"); + + PGPContentSignerBuilder contSigBuilder = new JcaPGPContentSignerBuilder( + keyPair.getPublicKey().getAlgorithm(), + HashAlgorithmTags.SHA512) + .setProvider(new BouncyCastleProvider()); + PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder); + sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey()); + sigGen.update(data); + PGPSignature signature = sigGen.generate(); + + PGPContentVerifierBuilderProvider contVerBuilder = new JcaPGPContentVerifierBuilderProvider() + .setProvider(new BouncyCastleProvider()); + signature.init(contVerBuilder, keyPair.getPublicKey()); + signature.update(data); + isTrue(signature.verify()); + } + + private void testV4SigningVerificationWithBcKey() + throws PGPException + { + Date date = currentTimeRounded(); + Ed448KeyPairGenerator gen = new Ed448KeyPairGenerator(); + gen.init(new Ed448KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + BcPGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.EDDSA_LEGACY, kp, date); + + byte[] data = Strings.toByteArray("Hello, World!\n"); + + PGPContentSignerBuilder contSigBuilder = new BcPGPContentSignerBuilder( + keyPair.getPublicKey().getAlgorithm(), + HashAlgorithmTags.SHA512); + PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder); + sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey()); + sigGen.update(data); + PGPSignature signature = sigGen.generate(); + + PGPContentVerifierBuilderProvider contVerBuilder = new BcPGPContentVerifierBuilderProvider(); + signature.init(contVerBuilder, keyPair.getPublicKey()); + signature.update(data); + isTrue(signature.verify()); + } + + private void testConversionOfJcaKeyPair() + throws NoSuchAlgorithmException, PGPException, InvalidAlgorithmParameterException, IOException + { + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("EDDSA", new BouncyCastleProvider()); + gen.initialize(new EdDSAParameterSpec("Ed448")); + KeyPair kp = gen.generateKeyPair(); + + JcaPGPKeyPair j1 = new JcaPGPKeyPair(PublicKeyAlgorithmTags.EDDSA_LEGACY, kp, date); + byte[] pubEnc = j1.getPublicKey().getEncoded(); + byte[] privEnc = j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Legacy Ed448 public key MUST be instanceof EdDSAPublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed448 secret key MUST be instanceof EdSecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + BcPGPKeyPair b1 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy Ed448 public key MUST be instanceof EdDSAPublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed448 secret key MUST be instanceof EdSecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy Ed448 public key MUST be instanceof EdDSAPublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed448 secret key MUST be instanceof EdSecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j2); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy Ed448 public key MUST be instanceof EdDSAPublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed448 secret key MUST be instanceof EdSecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), b2.getPublicKey().getCreationTime().getTime()); + } + + private void testConversionOfBcKeyPair() + throws PGPException, IOException + { + Date date = currentTimeRounded(); + Ed448KeyPairGenerator gen = new Ed448KeyPairGenerator(); + gen.init(new Ed448KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + + BcPGPKeyPair b1 = new BcPGPKeyPair(PublicKeyAlgorithmTags.EDDSA_LEGACY, kp, date); + byte[] pubEnc = b1.getPublicKey().getEncoded(); + byte[] privEnc = b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Legacy Ed448 public key MUST be instanceof EdDSAPublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed448 secret key MUST be instanceof EdSecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + JcaPGPKeyPair j1 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy Ed448 public key MUST be instanceof EdDSAPublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed448 secret key MUST be instanceof EdSecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy Ed448 public key MUST be instanceof EdDSAPublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed448 secret key MUST be instanceof EdSecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b2); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy Ed448 public key MUST be instanceof EdDSAPublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof EdDSAPublicBCPGKey); + isTrue("Legacy Ed448 secret key MUST be instanceof EdSecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof EdSecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), j2.getPublicKey().getCreationTime().getTime()); + } + + public static void main(String[] args) + { + runTest(new LegacyEd448KeyPairTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/LegacyX25519KeyPairTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/LegacyX25519KeyPairTest.java new file mode 100644 index 0000000000..2cee0c9410 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/LegacyX25519KeyPairTest.java @@ -0,0 +1,235 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.ECDHPublicBCPGKey; +import org.bouncycastle.bcpg.ECSecretBCPGKey; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.generators.X25519KeyPairGenerator; +import org.bouncycastle.crypto.params.X25519KeyGenerationParameters; +import org.bouncycastle.jcajce.spec.XDHParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openpgp.*; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; +import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.io.Streams; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.util.Date; + +public class LegacyX25519KeyPairTest + extends AbstractPgpKeyPairTest +{ + @Override + public String getName() + { + return "LegacyX25519KeyPairTest"; + } + + @Override + public void performTest() + throws Exception + { + testConversionOfJcaKeyPair(); + testConversionOfBcKeyPair(); + testV4MessageEncryptionDecryptionWithJcaKey(); + testV4MessageEncryptionDecryptionWithBcKey(); + } + + private void testConversionOfJcaKeyPair() + throws NoSuchAlgorithmException, PGPException, InvalidAlgorithmParameterException, IOException + { + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("XDH", new BouncyCastleProvider()); + gen.initialize(new XDHParameterSpec("X25519")); + KeyPair kp = gen.generateKeyPair(); + + JcaPGPKeyPair j1 = new JcaPGPKeyPair(PublicKeyAlgorithmTags.ECDH, kp, date); + byte[] pubEnc = j1.getPublicKey().getEncoded(); + byte[] privEnc = j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Legacy X25519 public key MUST be instanceof ECDHPublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X25519 secret key MUST be instanceof ECSecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + BcPGPKeyPair b1 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy X25519 public key MUST be instanceof ECDHPublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X25519 secret key MUST be instanceof ECSecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy X25519 public key MUST be instanceof ECDHPublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X25519 secret key MUST be instanceof ECSecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j2); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy X25519 public key MUST be instanceof ECDHPublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X25519 secret key MUST be instanceof ECSecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), b2.getPublicKey().getCreationTime().getTime()); + } + + private void testConversionOfBcKeyPair() + throws PGPException, IOException + { + Date date = currentTimeRounded(); + X25519KeyPairGenerator gen = new X25519KeyPairGenerator(); + gen.init(new X25519KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + + BcPGPKeyPair b1 = new BcPGPKeyPair(PublicKeyAlgorithmTags.ECDH, kp, date); + byte[] pubEnc = b1.getPublicKey().getEncoded(); + byte[] privEnc = b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Legacy X25519 public key MUST be instanceof ECDHPublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X25519 secret key MUST be instanceof ECSecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + JcaPGPKeyPair j1 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy X25519 public key MUST be instanceof ECDHPublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X25519 secret key MUST be instanceof ECSecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy X25519 public key MUST be instanceof ECDHPublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X25519 secret key MUST be instanceof ECSecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b2); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy X25519 public key MUST be instanceof ECDHPublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X25519 secret key MUST be instanceof ECSecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), j2.getPublicKey().getCreationTime().getTime()); + } + + private void testV4MessageEncryptionDecryptionWithJcaKey() + throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException + { + BouncyCastleProvider provider = new BouncyCastleProvider(); + + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("XDH", provider); + gen.initialize(new XDHParameterSpec("X25519")); + KeyPair kp = gen.generateKeyPair(); + PGPKeyPair keyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.ECDH, kp, date); + + byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8); + + PGPDataEncryptorBuilder encBuilder = new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256) + .setProvider(provider); + PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encBuilder); + PublicKeyKeyEncryptionMethodGenerator metGen = new JcePublicKeyKeyEncryptionMethodGenerator(keyPair.getPublicKey()) + .setProvider(provider); + encGen.addMethod(metGen); + PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator(); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + OutputStream encOut = encGen.open(bOut, new byte[4096]); + OutputStream litOut = litGen.open(encOut, PGPLiteralData.BINARY, "", PGPLiteralData.NOW, new byte[4096]); + litOut.write(data); + litGen.close(); + encGen.close(); + + byte[] encrypted = bOut.toByteArray(); + + ByteArrayInputStream bIn = new ByteArrayInputStream(encrypted); + PGPObjectFactory objectFactory = new JcaPGPObjectFactory(bIn); + PGPEncryptedDataList encDataList = (PGPEncryptedDataList) objectFactory.nextObject(); + PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encDataList.get(0); + PublicKeyDataDecryptorFactory decFactory = new JcePublicKeyDataDecryptorFactoryBuilder() + .setProvider(provider) + .build(keyPair.getPrivateKey()); + InputStream decIn = encData.getDataStream(decFactory); + objectFactory = new JcaPGPObjectFactory(decIn); + PGPLiteralData lit = (PGPLiteralData) objectFactory.nextObject(); + InputStream litIn = lit.getDataStream(); + byte[] plaintext = Streams.readAll(litIn); + litIn.close(); + decIn.close(); + + isTrue(Arrays.areEqual(data, plaintext)); + } + + private void testV4MessageEncryptionDecryptionWithBcKey() + throws PGPException, IOException + { + Date date = currentTimeRounded(); + X25519KeyPairGenerator gen = new X25519KeyPairGenerator(); + gen.init(new X25519KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + BcPGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.ECDH, kp, date); + + byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8); + + PGPDataEncryptorBuilder encBuilder = new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256); + PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encBuilder); + PublicKeyKeyEncryptionMethodGenerator metGen = new BcPublicKeyKeyEncryptionMethodGenerator(keyPair.getPublicKey()); + encGen.addMethod(metGen); + PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator(); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + OutputStream encOut = encGen.open(bOut, new byte[4096]); + OutputStream litOut = litGen.open(encOut, PGPLiteralData.BINARY, "", PGPLiteralData.NOW, new byte[4096]); + litOut.write(data); + litGen.close(); + encGen.close(); + + byte[] encrypted = bOut.toByteArray(); + + ByteArrayInputStream bIn = new ByteArrayInputStream(encrypted); + PGPObjectFactory objectFactory = new BcPGPObjectFactory(bIn); + PGPEncryptedDataList encDataList = (PGPEncryptedDataList) objectFactory.nextObject(); + PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encDataList.get(0); + PublicKeyDataDecryptorFactory decFactory = new BcPublicKeyDataDecryptorFactory(keyPair.getPrivateKey()); + InputStream decIn = encData.getDataStream(decFactory); + objectFactory = new BcPGPObjectFactory(decIn); + PGPLiteralData lit = (PGPLiteralData) objectFactory.nextObject(); + InputStream litIn = lit.getDataStream(); + byte[] plaintext = Streams.readAll(litIn); + litIn.close(); + decIn.close(); + + isTrue(Arrays.areEqual(data, plaintext)); + } + + public static void main(String[] args) + { + runTest(new LegacyX25519KeyPairTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/LegacyX448KeyPairTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/LegacyX448KeyPairTest.java new file mode 100644 index 0000000000..61c04c5f54 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/LegacyX448KeyPairTest.java @@ -0,0 +1,126 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.*; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.generators.X448KeyPairGenerator; +import org.bouncycastle.crypto.params.X448KeyGenerationParameters; +import org.bouncycastle.jcajce.spec.XDHParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; + +import java.io.IOException; +import java.security.*; +import java.util.Date; + +public class LegacyX448KeyPairTest + extends AbstractPgpKeyPairTest +{ + @Override + public String getName() + { + return "LegacyX448KeyPairTest"; + } + + @Override + public void performTest() + throws Exception + { + testConversionOfJcaKeyPair(); + testConversionOfBcKeyPair(); + } + + private void testConversionOfJcaKeyPair() + throws NoSuchAlgorithmException, PGPException, InvalidAlgorithmParameterException, IOException + { + Date date = currentTimeRounded(); + KeyPairGenerator gen = KeyPairGenerator.getInstance("XDH", new BouncyCastleProvider()); + gen.initialize(new XDHParameterSpec("X448")); + KeyPair kp = gen.generateKeyPair(); + + JcaPGPKeyPair j1 = new JcaPGPKeyPair(PublicKeyAlgorithmTags.ECDH, kp, date); + byte[] pubEnc = j1.getPublicKey().getEncoded(); + byte[] privEnc = j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Legacy X448 public key MUST be instanceof ECDHPublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X448 secret key MUST be instanceof ECSecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + BcPGPKeyPair b1 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy X448 public key MUST be instanceof ECDHPublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X448 secret key MUST be instanceof ECSecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy X448 public key MUST be instanceof ECDHPublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X448 secret key MUST be instanceof ECSecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j2); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy X448 public key MUST be instanceof ECDHPublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X448 secret key MUST be instanceof ECSecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), b2.getPublicKey().getCreationTime().getTime()); + } + + private void testConversionOfBcKeyPair() + throws PGPException, IOException + { + Date date = currentTimeRounded(); + X448KeyPairGenerator gen = new X448KeyPairGenerator(); + gen.init(new X448KeyGenerationParameters(new SecureRandom())); + AsymmetricCipherKeyPair kp = gen.generateKeyPair(); + + BcPGPKeyPair b1 = new BcPGPKeyPair(PublicKeyAlgorithmTags.ECDH, kp, date); + byte[] pubEnc = b1.getPublicKey().getEncoded(); + byte[] privEnc = b1.getPrivateKey().getPrivateKeyDataPacket().getEncoded(); + isTrue("Legacy X448 public key MUST be instanceof ECDHPublicBCPGKey", + b1.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X448 secret key MUST be instanceof ECSecretBCPGKey", + b1.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + JcaPGPKeyPair j1 = toJcaKeyPair(b1); + isEncodingEqual(pubEnc, j1.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j1.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy X448 public key MUST be instanceof ECDHPublicBCPGKey", + j1.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X448 secret key MUST be instanceof ECSecretBCPGKey", + j1.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + BcPGPKeyPair b2 = toBcKeyPair(j1); + isEncodingEqual(pubEnc, b2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, b2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy X448 public key MUST be instanceof ECDHPublicBCPGKey", + b2.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X448 secret key MUST be instanceof ECSecretBCPGKey", + b2.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + JcaPGPKeyPair j2 = toJcaKeyPair(b2); + isEncodingEqual(pubEnc, j2.getPublicKey().getEncoded()); + isEncodingEqual(privEnc, j2.getPrivateKey().getPrivateKeyDataPacket().getEncoded()); + isTrue("Legacy X448 public key MUST be instanceof ECDHPublicBCPGKey", + j2.getPublicKey().getPublicKeyPacket().getKey() instanceof ECDHPublicBCPGKey); + isTrue("Legacy X448 secret key MUST be instanceof ECSecretBCPGKey", + j2.getPrivateKey().getPrivateKeyDataPacket() instanceof ECSecretBCPGKey); + + isEquals("Creation time is preserved", + date.getTime(), j2.getPublicKey().getCreationTime().getTime()); + } + + public static void main(String[] args) + { + runTest(new LegacyX448KeyPairTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/OpenPGPTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/OpenPGPTest.java new file mode 100644 index 0000000000..7177a0cbd9 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/OpenPGPTest.java @@ -0,0 +1,1037 @@ +package org.bouncycastle.openpgp.test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.SecureRandom; +import java.security.Security; +import java.util.Date; +import java.util.Iterator; + +import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.bcpg.BCPGOutputStream; +import org.bouncycastle.bcpg.CompressionAlgorithmTags; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.sig.Features; +import org.bouncycastle.bcpg.sig.KeyFlags; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.bouncycastle.jce.spec.ElGamalParameterSpec; +import org.bouncycastle.openpgp.PGPCanonicalizedDataGenerator; +import org.bouncycastle.openpgp.PGPCompressedData; +import org.bouncycastle.openpgp.PGPCompressedDataGenerator; +import org.bouncycastle.openpgp.PGPEncryptedData; +import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; +import org.bouncycastle.openpgp.PGPEncryptedDataList; +import org.bouncycastle.openpgp.PGPKdfParameters; +import org.bouncycastle.openpgp.PGPKeyPair; +import org.bouncycastle.openpgp.PGPKeyRingGenerator; +import org.bouncycastle.openpgp.PGPLiteralData; +import org.bouncycastle.openpgp.PGPLiteralDataGenerator; +import org.bouncycastle.openpgp.PGPMarker; +import org.bouncycastle.openpgp.PGPObjectFactory; +import org.bouncycastle.openpgp.PGPOnePassSignature; +import org.bouncycastle.openpgp.PGPPadding; +import org.bouncycastle.openpgp.PGPPrivateKey; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.PGPSignatureList; +import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; +import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; +import org.bouncycastle.openpgp.PGPSignatureVerifier; +import org.bouncycastle.openpgp.PGPSignatureVerifierBuilder; +import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; +import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVectorGenerator; +import org.bouncycastle.openpgp.PGPUtil; +import org.bouncycastle.openpgp.jcajce.JcaPGPPublicKeyRing; +import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; +import org.bouncycastle.openpgp.operator.bc.BcPBEKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.test.SimpleTest; +import org.bouncycastle.util.test.UncloseableOutputStream; + +public class OpenPGPTest + extends SimpleTest +{ + static char[] pass = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'}; + + public static void main(String[] args) + { + Security.addProvider(new BouncyCastleProvider()); + + runTest(new OpenPGPTest()); + } + + @Override + public String getName() + { + return "OpenpgpTest"; + } + + @Override + public void performTest() + throws Exception + { + testPGPCanonicalizedDataGenerator(); +// testPGPV3SignatureGenerator(); + testPGPUserAttributeSubpacketVector(); + testPGPLiteralData(); + testPGPEncryptedDataGenerator(); + testPGPSignatureVerifierBuilder(); + testPGPLiteralDataGenerator(); + testContruction(); + testPGPUtil(); + testPGPCompressedDataGenerator(); + } + + public void testPGPCompressedDataGenerator() + throws IOException + { + testException("unknown compression algorithm", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPCompressedDataGenerator(110); + } + }); + testException("unknown compression level:", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPCompressedDataGenerator(CompressionAlgorithmTags.UNCOMPRESSED, 10); + } + }); + + final PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(PGPCompressedData.ZIP); + + final ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + cGen.open(new UncloseableOutputStream(bOut)); + testException("generator already in open state", "IllegalStateException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + cGen.open(new UncloseableOutputStream(bOut)); + } + }); + testException("generator already in open state", "IllegalStateException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + cGen.open(new UncloseableOutputStream(bOut), new byte[10]); + } + }); + } + + public void testPGPUtil() + throws Exception + { + isEquals("SHA1", PGPUtil.getDigestName(HashAlgorithmTags.SHA1)); + isEquals("MD2", PGPUtil.getDigestName(HashAlgorithmTags.MD2)); + isEquals("MD5", PGPUtil.getDigestName(HashAlgorithmTags.MD5)); + isEquals("RIPEMD160", PGPUtil.getDigestName(HashAlgorithmTags.RIPEMD160)); + isEquals("SHA256", PGPUtil.getDigestName(HashAlgorithmTags.SHA256)); + isEquals("SHA3-256", PGPUtil.getDigestName(HashAlgorithmTags.SHA3_256)); + isEquals("SHA3-256", PGPUtil.getDigestName(HashAlgorithmTags.SHA3_256_OLD)); + isEquals("SHA384", PGPUtil.getDigestName(HashAlgorithmTags.SHA384)); + isEquals("SHA3-384", PGPUtil.getDigestName(HashAlgorithmTags.SHA3_384)); + isEquals("SHA512", PGPUtil.getDigestName(HashAlgorithmTags.SHA512)); + isEquals("SHA3-512", PGPUtil.getDigestName(HashAlgorithmTags.SHA3_512)); + isEquals("SHA3-512", PGPUtil.getDigestName(HashAlgorithmTags.SHA3_512_OLD)); + isEquals("SHA224", PGPUtil.getDigestName(HashAlgorithmTags.SHA224)); + isEquals("SHA3-224", PGPUtil.getDigestName(HashAlgorithmTags.SHA3_224)); + isEquals("TIGER", PGPUtil.getDigestName(HashAlgorithmTags.TIGER_192)); + testException("unknown hash algorithm tag in getDigestName: ", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + PGPUtil.getDigestName(HashAlgorithmTags.MD4); + } + }); + + testException("unable to map ", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + PGPUtil.getDigestIDForName("Test"); + } + }); + + isEquals("SHA1withRSA", PGPUtil.getSignatureName(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); + isEquals("SHA1withRSA", PGPUtil.getSignatureName(PublicKeyAlgorithmTags.RSA_SIGN, HashAlgorithmTags.SHA1)); + isEquals("SHA1withDSA", PGPUtil.getSignatureName(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1)); + isEquals("SHA1withElGamal", PGPUtil.getSignatureName(PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, HashAlgorithmTags.SHA1)); + isEquals("SHA1withElGamal", PGPUtil.getSignatureName(PublicKeyAlgorithmTags.ELGAMAL_GENERAL, HashAlgorithmTags.SHA1)); + testException("unknown algorithm tag in signature:", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + PGPUtil.getSignatureName(PublicKeyAlgorithmTags.RSA_ENCRYPT, HashAlgorithmTags.SHA1); + } + }); + + isTrue(PGPUtil.getSymmetricCipherName(SymmetricKeyAlgorithmTags.NULL) == null); + testException("unknown symmetric algorithm: ", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + PGPUtil.getSymmetricCipherName(101); + } + }); + + isTrue(!PGPUtil.isKeyBox(new byte[11])); + + isTrue(PGPUtil.makeRandomKey(SymmetricKeyAlgorithmTags.DES, CryptoServicesRegistrar.getSecureRandom()).length == 8); + testException("unknown symmetric algorithm: ", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + PGPUtil.makeRandomKey(SymmetricKeyAlgorithmTags.NULL, CryptoServicesRegistrar.getSecureRandom()); + } + }); + } + + public void testContruction() + throws Exception + { + String data = "Now is the time for all good men\nTo come to the aid of the party\n"; + PGPCanonicalizedDataGenerator canGen = new PGPCanonicalizedDataGenerator(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + OutputStream out = canGen.open(bOut, PGPLiteralData.TEXT, PGPLiteralData.CONSOLE, new Date()); + + out.write(Strings.toByteArray(data)); + + out.close(); + final byte[] input = bOut.toByteArray(); + + testException("unexpected packet in stream: ", "IOException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPCompressedData(new BCPGInputStream(new ByteArrayInputStream(input))); + } + }); + //testException("unexpected packet in stream: ", "IOException", ()-> new PGPEncryptedDataList(new BCPGInputStream(new ByteArrayInputStream(input)))); + testException("unexpected packet in stream: ", "IOException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPMarker(new BCPGInputStream(new ByteArrayInputStream(input))); + } + }); + testException("unexpected packet in stream: ", "IOException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPOnePassSignature(new BCPGInputStream(new ByteArrayInputStream(input))); + } + }); + testException("unexpected packet in stream: ", "IOException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPPadding(new BCPGInputStream(new ByteArrayInputStream(input))); + } + }); + //testException("unexpected packet in stream: ", "IOException", ()-> new PGPPublicKeyRing(new BCPGInputStream(new ByteArrayInputStream(input)), new BcKeyFingerprintCalculator())); + testException("unexpected packet in stream: ", "IOException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPSignature(new BCPGInputStream(new ByteArrayInputStream(input))); + } + }); + + testException("unexpected packet in stream: ", "IOException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPLiteralData(new BCPGInputStream(new ByteArrayInputStream(BcPGPRSATest.sig1))); + } + }); + } + + public void testPGPLiteralDataGenerator() + throws Exception + { + final PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); + final String data = "Now is the time for all good men\nTo come to the aid of the party\n"; + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator( + PGPCompressedData.ZIP); + final BCPGOutputStream bcOut = new BCPGOutputStream( + cGen.open(new UncloseableOutputStream(bOut))); + final Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); + lGen.open( + new UncloseableOutputStream(bcOut), + PGPLiteralData.BINARY, + "_CONSOLE", + data.getBytes().length, + testDate); + testException("generator already in open state", "IllegalStateException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + lGen.open( + new UncloseableOutputStream(bcOut), + PGPLiteralData.BINARY, + "_CONSOLE", + data.getBytes().length, + testDate); + } + }); + testException("generator already in open state", "IllegalStateException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + lGen.open( + new UncloseableOutputStream(bcOut), + PGPLiteralData.BINARY, + "_CONSOLE", + testDate, + new byte[10]); + } + }); + } + + public void testPGPSignatureVerifierBuilder() + throws Exception + { + PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(PGPKeyRingTest.pub7, new JcaKeyFingerprintCalculator()); + Iterator it = pgpPub.getPublicKeys(); + PGPPublicKey masterKey = null; + + while (it.hasNext()) + { + PGPPublicKey k = (PGPPublicKey)it.next(); + + if (k.isMasterKey()) + { + masterKey = k; + } + } + + int count = 0; + PGPSignature sig = null; + Iterator sIt = masterKey.getSignaturesOfType(PGPSignature.KEY_REVOCATION); + + while (sIt.hasNext()) + { + sig = (PGPSignature)sIt.next(); + count++; + } + + if (count != 1) + { + fail("wrong number of revocations in test7."); + } + PGPSignatureVerifier verifier = new PGPSignatureVerifierBuilder(new JcaPGPContentVerifierBuilderProvider(), masterKey).buildKeyRevocationVerifier(sig, masterKey); + isTrue(verifier.getSignatureType() == PGPSignature.KEY_REVOCATION); + isTrue(verifier.isVerified()); + final PGPSignature tmpFinalSig1 = sig; + final PGPPublicKey tmpFinalPubKey1 = masterKey; + testException("PGPSignature not initialised - call init().", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + tmpFinalSig1.verifyCertification(tmpFinalPubKey1); + } + }); + + pgpPub = new PGPPublicKeyRing(PGPKeyRingTest.pub7sub, new JcaKeyFingerprintCalculator()); + it = pgpPub.getPublicKeys(); + masterKey = null; + + while (it.hasNext()) + { + PGPPublicKey k = (PGPPublicKey)it.next(); + + if (k.isMasterKey()) + { + masterKey = k; + continue; + } + + count = 0; + sig = null; + sIt = k.getSignaturesOfType(PGPSignature.SUBKEY_REVOCATION); + + while (sIt.hasNext()) + { + sig = (PGPSignature)sIt.next(); + count++; + } + + if (count != 1) + { + fail("wrong number of revocations in test7 subkey."); + } + + verifier = new PGPSignatureVerifierBuilder(new JcaPGPContentVerifierBuilderProvider(), masterKey).buildSubKeyRevocationVerifier(sig, masterKey, k); + isTrue(verifier.getSignatureType() == PGPSignature.SUBKEY_REVOCATION); + isTrue(verifier.isVerified()); + + testException("PGPSignature not initialised - call init().", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + tmpFinalSig1.verifyCertification(tmpFinalPubKey1, tmpFinalPubKey1); + } + }); + } + + PGPDigestCalculator digestCalculator = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1); + KeyPairGenerator generator; + KeyPair pair; + + // Generate master key + + generator = KeyPairGenerator.getInstance("ECDSA", BouncyCastleProvider.PROVIDER_NAME); + generator.initialize(new ECNamedCurveGenParameterSpec("P-256")); + + pair = generator.generateKeyPair(); + PGPKeyPair pgpMasterKey = new JcaPGPKeyPair(PublicKeyAlgorithmTags.ECDSA, pair, new Date()); + + PGPSignatureSubpacketGenerator hashed = new PGPSignatureSubpacketGenerator(); + hashed.addNotationData(false, true, "test@bouncycastle.org", "hashedNotation"); + PGPSignatureSubpacketGenerator unhashed = new PGPSignatureSubpacketGenerator(); + + PGPContentSignerBuilder signerBuilder = new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.ECDSA, HashAlgorithmTags.SHA512); + PGPKeyRingGenerator keyRingGenerator = new PGPKeyRingGenerator( + pgpMasterKey, digestCalculator, hashed.generate(), unhashed.generate(), signerBuilder, null); + + PGPPublicKey publicKey = keyRingGenerator.generateSecretKeyRing().getPublicKey(); + + Iterator signatures = publicKey.getSignaturesOfType(PGPSignature.DIRECT_KEY); + isTrue(signatures.hasNext()); + + PGPSignature signature = (PGPSignature)signatures.next(); + isTrue(!signatures.hasNext()); + + verifier = new PGPSignatureVerifierBuilder(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey).buildDirectKeyVerifier(signature, publicKey); + isTrue(verifier.isVerified()); + isTrue(verifier.getSignatureType() == PGPSignature.DIRECT_KEY); + + + // Generate master key + generator = KeyPairGenerator.getInstance("ECDSA", BouncyCastleProvider.PROVIDER_NAME); + generator.initialize(new ECNamedCurveGenParameterSpec("P-256")); + + pair = generator.generateKeyPair(); + pgpMasterKey = new JcaPGPKeyPair(PublicKeyAlgorithmTags.ECDSA, pair, new Date()); + + PGPSignatureSubpacketGenerator subPackets = new PGPSignatureSubpacketGenerator(); + subPackets.setKeyFlags(false, KeyFlags.AUTHENTICATION & KeyFlags.CERTIFY_OTHER & KeyFlags.SIGN_DATA); + subPackets.setPreferredSymmetricAlgorithms(false, new int[]{ + SymmetricKeyAlgorithmTags.AES_256, + SymmetricKeyAlgorithmTags.AES_192, + SymmetricKeyAlgorithmTags.AES_128}); + subPackets.setPreferredHashAlgorithms(false, new int[]{ + HashAlgorithmTags.SHA512, + HashAlgorithmTags.SHA384, + HashAlgorithmTags.SHA256, + HashAlgorithmTags.SHA224}); + subPackets.setPreferredCompressionAlgorithms(false, new int[]{ + CompressionAlgorithmTags.ZLIB, + CompressionAlgorithmTags.BZIP2, + CompressionAlgorithmTags.ZIP, + CompressionAlgorithmTags.UNCOMPRESSED}); + subPackets.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION); + + // Generate sub key + + generator = KeyPairGenerator.getInstance("ECDH", BouncyCastleProvider.PROVIDER_NAME); + generator.initialize(new ECNamedCurveGenParameterSpec("P-256")); + + KeyPair encPair = generator.generateKeyPair(); + PGPKeyPair encSubKey = new JcaPGPKeyPair(PublicKeyAlgorithmTags.ECDH, encPair, new Date()); + KeyPair sigPair = generator.generateKeyPair(); + PGPKeyPair sigSubKey = new JcaPGPKeyPair(PublicKeyAlgorithmTags.ECDSA, sigPair, new Date()); + + // Assemble key + + PGPDigestCalculator calculator = new JcaPGPDigestCalculatorProviderBuilder() + .setProvider(BouncyCastleProvider.PROVIDER_NAME) + .build() + .get(HashAlgorithmTags.SHA1); + + signerBuilder = new JcaPGPContentSignerBuilder( + pgpMasterKey.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA512) + .setProvider(BouncyCastleProvider.PROVIDER_NAME) + .setDigestProvider(new BouncyCastleProvider()); + + PGPKeyRingGenerator pgpGenerator = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, + pgpMasterKey, "alice@wonderland.lit", calculator, subPackets.generate(), null, + signerBuilder, null); + + // Add sub key + + subPackets.setKeyFlags(false, KeyFlags.ENCRYPT_STORAGE & KeyFlags.ENCRYPT_COMMS); + + pgpGenerator.addSubKey(encSubKey, subPackets.generate(), null); + + pgpGenerator.addSubKey(sigSubKey, subPackets.generate(), null, + new JcaPGPContentSignerBuilder( + sigSubKey.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA256) + .setProvider("BC").setDigestProvider("BC")); + + // Generate SecretKeyRing + + PGPSecretKeyRing secretKeys = pgpGenerator.generateSecretKeyRing(); + + PGPPublicKeyRing publicKeys = pgpGenerator.generatePublicKeyRing(); + + checkPublicKeyRing(secretKeys, publicKeys.getEncoded()); + // Extract the public keys + ByteArrayOutputStream bOut = new ByteArrayOutputStream(2048); + Iterator iterator = secretKeys.getPublicKeys(); + count = 0; + while (iterator.hasNext()) + { + PGPPublicKey key = (PGPPublicKey)iterator.next(); + + if (!key.isMasterKey() && !key.isEncryptionKey()) + { + PGPSignature pgpSig = (PGPSignature)key.getSignaturesForKeyID(pgpMasterKey.getKeyID()).next(); + + isTrue(pgpSig.hasSubpackets()); + + PGPSignatureSubpacketVector subP = pgpSig.getHashedSubPackets(); + + verifier = new PGPSignatureVerifierBuilder(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), key) + .buildPrimaryKeyBindingVerifier(subP.getEmbeddedSignatures().get(0), pgpMasterKey.getPublicKey(), key); + isTrue(verifier.isVerified()); + isTrue(verifier.getSignatureType() == PGPSignature.PRIMARYKEY_BINDING); + + final PGPSignature tmpFinalSig = sig; + final PGPPublicKey tmpFInalPubKey = key; + testException("PGPSignature not initialised - call init().", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + tmpFinalSig.verifyCertification(tmpFInalPubKey); + } + }); + + } + bOut.write(key.getEncoded()); + count++; + } + + isTrue(count == 3); + + + pgpPub = new PGPPublicKeyRing(PGPRSATest.embeddedJPEGKey, new JcaKeyFingerprintCalculator()); + + PGPPublicKey pubKey = pgpPub.getPublicKey(); + + it = pubKey.getUserAttributes(); + count = 0; + PGPUserAttributeSubpacketVector attributes = null; + while (it.hasNext()) + { + attributes = (PGPUserAttributeSubpacketVector)it.next(); + + Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes); + int sigCount = 0; + while (sigs.hasNext()) + { + sig = (PGPSignature)sigs.next(); + + verifier = new PGPSignatureVerifierBuilder(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), pubKey).buildCertificationVerifier(sig, attributes, pubKey); + isTrue(verifier.isVerified()); + isTrue(PGPSignature.isCertification(verifier.getSignatureType())); + final PGPSignature tmpFinalSig = sig; + final PGPUserAttributeSubpacketVector tmpFinalAttributes = attributes; + final PGPPublicKey tmpFinalPubKey = pubKey; + testException("PGPSignature not initialised - call init().", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + tmpFinalSig.verifyCertification(tmpFinalAttributes, tmpFinalPubKey); + } + }); + sigCount++; + } + + if (sigCount != 1) + { + fail("Failed user attributes signature check"); + } + count++; + } + + if (count != 1) + { + fail("didn't find user attributes"); + } + final PGPSignature finalSig2 = sig; + final PGPPublicKey finalPubKey2 = pubKey; + + PGPPublicKeyRing pgpRing = new JcaPGPPublicKeyRing(new ByteArrayInputStream(PGPKeyRingTest.problemUserID)); + + byte[] enc = pgpRing.getEncoded(); + + if (!Arrays.areEqual(PGPKeyRingTest.problemUserID, enc)) + { + fail("encoded key does not match original"); + } + + pubKey = pgpRing.getPublicKey(); + + it = pubKey.getRawUserIDs(); + + final byte[] rawID = (byte[])it.next(); + + it = pubKey.getSignaturesForID(rawID); + + sig = (PGPSignature)it.next(); + verifier = new PGPSignatureVerifierBuilder(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), pubKey).buildCertificationVerifier(sig, rawID, pubKey); + isTrue(verifier.isVerified()); + isTrue(PGPSignature.isCertification(verifier.getSignatureType())); + + testException("PGPSignature not initialised - call init().", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + tmpFinalSig1.verifyCertification(rawID, tmpFinalPubKey1); + } + }); + + char[] passPhrase = "hello".toCharArray(); + KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); + + dsaKpg.initialize(512); + + // + // this takes a while as the key generator has to generate some DSA params + // before it generates the key. + // + KeyPair dsaKp = dsaKpg.generateKeyPair(); + + KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); + BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); + BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); + + ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); + + elgKpg.initialize(elParams); + + // + // this is quicker because we are using pregenerated parameters. + // + KeyPair elgKp = elgKpg.generateKeyPair(); + PGPKeyPair dsaKeyPair = new JcaPGPKeyPair(PGPPublicKey.DSA, new PGPKdfParameters(HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_128), dsaKp, new Date()); + PGPKeyPair elgKeyPair = new JcaPGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); + + PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1); + PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, + "test", sha1Calc, null, null, new JcaPGPContentSignerBuilder(PGPPublicKey.DSA, HashAlgorithmTags.SHA1), new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).setProvider("BC").build(passPhrase)); + + keyRingGen.addSubKey(elgKeyPair); + + PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); + + keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); + + PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); + + PGPPublicKey vKey = null; + PGPPublicKey sKey = null; + + it = pubRing.getPublicKeys(); + while (it.hasNext()) + { + PGPPublicKey pk = (PGPPublicKey)it.next(); + if (pk.isMasterKey()) + { + vKey = pk; + } + else + { + sKey = pk; + } + } + + sig = new PGPSignatureList((PGPSignature)sKey.getSignatures().next()).get(0); + + if (sig.getKeyID() == vKey.getKeyID()) + { + verifier = new PGPSignatureVerifierBuilder(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), vKey).buildSubKeyBindingVerifier(sig, vKey, sKey); + isTrue(verifier.isVerified()); + isTrue(verifier.getSignatureType() == PGPSignature.SUBKEY_BINDING); + + } + else + { + fail(""); + } + + + final PGPPublicKey v_Key = vKey; + final PGPSignature finalSig = sig; + final PGPPublicKey s_Key = sKey; + testException("signature is not a direct key signature", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPSignatureVerifierBuilder + (new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), v_Key).buildDirectKeyVerifier(finalSig, v_Key); + } + }); + testException("signature is not a key revocation signature", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPSignatureVerifierBuilder + (new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), v_Key).buildKeyRevocationVerifier(finalSig, v_Key); + } + } ); + testException("signature is not a primary key binding signature", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPSignatureVerifierBuilder + (new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), v_Key).buildPrimaryKeyBindingVerifier(finalSig, v_Key, v_Key); + } + }); + testException("signature is not a subkey binding signature", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPSignatureVerifierBuilder + (new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), s_Key).buildSubKeyBindingVerifier(finalSig2, s_Key, s_Key); + } + }); + finalSig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), v_Key); + final PGPUserAttributeSubpacketVector finalAttributes = attributes; + testException("signature is neither a certification signature nor a certification revocation.", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + finalSig.verifyCertification(finalAttributes, v_Key); + } + }); + testException("signature is neither a certification signature nor a certification revocation.", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + finalSig.verifyCertification(rawID, v_Key); + } + }); + + finalSig2.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), finalPubKey2); + testException("signature is not a key binding signature.", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + finalSig2.verifyCertification(finalPubKey2, finalPubKey2); + } + }); + + testException("These are different signatures.", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + PGPSignature.join(finalSig, finalSig2); + } + }); + + keyRingGen = new PGPKeyRingGenerator(PGPSignature.CERTIFICATION_REVOCATION, dsaKeyPair, + "test", sha1Calc, null, null, new JcaPGPContentSignerBuilder(PGPPublicKey.DSA, HashAlgorithmTags.SHA1) + .setProvider(new BouncyCastleProvider()).setSecureRandom(CryptoServicesRegistrar.getSecureRandom()), + new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, 2).setProvider(new BouncyCastleProvider()).build(passPhrase)); + + keyRingGen.addSubKey(elgKeyPair); + + keyRing = keyRingGen.generateSecretKeyRing(); + + keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); + + pubRing = keyRingGen.generatePublicKeyRing(); + it = pubRing.getPublicKeys(); + while (it.hasNext()) + { + PGPPublicKey pk = (PGPPublicKey)it.next(); + if (pk.isMasterKey()) + { + vKey = pk; + } + else + { + sKey = pk; + } + } + final PGPSignature finalSig3 = (PGPSignature)sKey.getSignatures().next(); + testException("signature is neither a certification signature nor a certification revocation", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPSignatureVerifierBuilder + (new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), v_Key).buildCertificationVerifier(finalSig3, rawID, v_Key); + } + }); + testException("signature is neither a certification signature nor a certification revocation", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPSignatureVerifierBuilder + (new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), v_Key).buildCertificationVerifier(finalSig3, finalAttributes, v_Key); + } + }); + testException("signature is not a primary key binding signature", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPSignatureVerifierBuilder + (new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), v_Key).buildSubKeyRevocationVerifier(finalSig3, v_Key, v_Key); + } + }); + + isTrue(finalSig2.isCertification()); + isTrue(!finalSig3.isCertification()); + } + + private void checkPublicKeyRing(PGPSecretKeyRing secretKeys, byte[] encRing) + throws IOException + { + Iterator iterator; + PGPPublicKeyRing publicKeys = new PGPPublicKeyRing(encRing, new BcKeyFingerprintCalculator()); + + // Check, if all public keys made it to the new public key ring + iterator = secretKeys.getPublicKeys(); + while (iterator.hasNext()) + { + isTrue(publicKeys.getPublicKey(((PGPPublicKey)iterator.next()).getKeyID()) != null); + } + } + + public void testPGPEncryptedDataGenerator() + throws Exception + { + final ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); + final PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(new SecureRandom())); + final ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + testException("no encryption methods specified", "IllegalStateException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); + } + }); + + cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass, 2).setSecureRandom(CryptoServicesRegistrar.getSecureRandom())); + cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); + testException("generator already in open state", "IllegalStateException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); + } + }); + } + + public void testPGPLiteralData() + throws Exception + { + PGPObjectFactory pgpF = new PGPObjectFactory(BcPGPRSATest.enc1, new BcKeyFingerprintCalculator()); + + PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(BcPGPRSATest.subKey, new BcKeyFingerprintCalculator()); + PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); + + PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); + isEquals(encP.getAlgorithm(), 1); + isEquals(encP.getVersion(), 3); + PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); + + InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey)); + + PGPObjectFactory pgpFact = new PGPObjectFactory(clear, new BcKeyFingerprintCalculator()); + + PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); + + PGPLiteralData ld = new PGPLiteralData(c1.getDataStream()); + + if (!ld.getFileName().equals("test.txt")) + { + throw new RuntimeException("wrong filename in packet"); + } + } + + public void testPGPUserAttributeSubpacketVector() + { + PGPUserAttributeSubpacketVector vector = PGPUserAttributeSubpacketVector.fromSubpackets(null); + isTrue(vector.getSubpacket(0) == null); + isTrue(vector.getImageAttribute() == null); + + testException("attempt to set null image", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new PGPUserAttributeSubpacketVectorGenerator().setImageAttribute(0, null); + } + }); + } + + public void testPGPCanonicalizedDataGenerator() + throws IOException + { + final PGPCanonicalizedDataGenerator canGen = new PGPCanonicalizedDataGenerator(false); + final ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + final File bcFile = File.createTempFile("bcpgp", ".back"); + canGen.open(bOut, PGPLiteralData.TEXT, bcFile); + testException("generator already in open state", "IllegalStateException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + canGen.open(bOut, PGPLiteralData.TEXT, bcFile); + } + }); + testException("generator already in open state", "IllegalStateException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + canGen.open(bOut, PGPLiteralData.TEXT, bcFile.getName(), + new Date(bcFile.lastModified()), bcFile); + } + }); + testException("generator already in open state", "IllegalStateException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + canGen.open(bOut, PGPLiteralData.TEXT, bcFile.getName(), + new Date(bcFile.lastModified()), new byte[10]); + } + }); + } + +// public void testPGPV3SignatureGenerator() +// throws Exception +// { +// char[] passPhrase = "hello".toCharArray(); +// String data = "hello world!"; +// String newPass = "newPass"; +// KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); +// +// kpg.initialize(1024); +// +// KeyPair kp = kpg.generateKeyPair(); +// PGPSecretKey secretKey = new PGPSecretKey( +// PGPSignature.DEFAULT_CERTIFICATION, +// new JcaPGPKeyPair(PublicKeyAlgorithmTags.RSA_SIGN, kp, new Date()), "fred", +// null, null, new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_SIGN, HashAlgorithmTags.SHA1).setProvider("BC"), +// new JcePBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).build(passPhrase)); +// secretKey = PGPSecretKey.copyWithNewPassword(secretKey, new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(passPhrase), new JcePBESecretKeyEncryptorBuilder(secretKey.getKeyEncryptionAlgorithm()).setProvider("BC").setSecureRandom(new SecureRandom()).build(newPass.toCharArray())); +// +// final PGPPrivateKey pgpPrivKey = secretKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(newPass.toCharArray())); +// +// final PGPV3SignatureGenerator sGenV3 = new PGPV3SignatureGenerator(new JcaPGPContentSignerBuilder(PGPPublicKey.DSA, PGPUtil.SHA1).setProvider("BC")); +// +// testException("key algorithm mismatch", "PGPException", ()->sGenV3.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey)); +// } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/OperatorBcTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/OperatorBcTest.java new file mode 100644 index 0000000000..682a288711 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/OperatorBcTest.java @@ -0,0 +1,649 @@ +package org.bouncycastle.openpgp.test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Security; +import java.util.Date; +import java.util.Iterator; + +import org.bouncycastle.bcpg.AEADAlgorithmTags; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.Wrapper; +import org.bouncycastle.crypto.agreement.X25519Agreement; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.engines.AESEngine; +import org.bouncycastle.crypto.engines.RFC3394WrapEngine; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.params.HKDFParameters; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; +import org.bouncycastle.crypto.params.X25519PublicKeyParameters; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.bouncycastle.openpgp.PGPEncryptedData; +import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; +import org.bouncycastle.openpgp.PGPEncryptedDataList; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPKdfParameters; +import org.bouncycastle.openpgp.PGPKeyPair; +import org.bouncycastle.openpgp.PGPKeyRingGenerator; +import org.bouncycastle.openpgp.PGPLiteralData; +import org.bouncycastle.openpgp.PGPLiteralDataGenerator; +import org.bouncycastle.openpgp.PGPPrivateKey; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; +import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.bouncycastle.openpgp.operator.PGPContentVerifier; +import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; +import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; +import org.bouncycastle.util.test.UncloseableOutputStream; + +public class OperatorBcTest + extends SimpleTest +{ + public static void main(String[] args) + { + Security.addProvider(new BouncyCastleProvider()); + + runTest(new OperatorBcTest()); + } + + @Override + public String getName() + { + return "OperatorBcTest"; + } + + @Override + public void performTest() + throws Exception + { + testX25519HKDF(); + testKeyRings(); + testBcPGPKeyPair(); + testBcPGPDataEncryptorBuilder(); + testBcPGPContentVerifierBuilderProvider(); + testBcPBESecretKeyDecryptorBuilder(); + testBcKeyFingerprintCalculator(); + testBcStandardDigests(); + } + + private void testBcStandardDigests() + throws Exception + { + PGPDigestCalculatorProvider digCalcBldr = new BcPGPDigestCalculatorProvider(); + + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.MD5), Hex.decode("900150983cd24fb0d6963f7d28e17f72")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA1), Hex.decode("a9993e364706816aba3e25717850c26c9cd0d89d")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.RIPEMD160), Hex.decode("8eb208f7e05d987a9b044a8e98c6b087f15a0bfc")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA256), Hex.decode("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA384), Hex.decode("cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA512), Hex.decode("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA224), Hex.decode("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA3_256), Hex.decode("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA3_512), Hex.decode("b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0")); + } + + private void testDigestCalc(PGPDigestCalculator digCalc, byte[] expected) + throws IOException + { + OutputStream dOut = digCalc.getOutputStream(); + + dOut.write(Strings.toByteArray("abc")); + + dOut.close(); + + byte[] res = digCalc.getDigest(); + + isTrue(Arrays.areEqual(res, expected)); + } + + public void testBcKeyFingerprintCalculator() + throws Exception + { + final BcKeyFingerprintCalculator calculator = new BcKeyFingerprintCalculator(); + KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); + kpGen.initialize(1024); + KeyPair kp = kpGen.generateKeyPair(); + Date creationTime = new Date(1000 * (new Date().getTime() / 1000)); + + JcaPGPKeyConverter converter = new JcaPGPKeyConverter().setProvider(new BouncyCastleProvider()); + final PGPPublicKey pubKey = converter.getPGPPublicKey(PublicKeyPacket.VERSION_4, PublicKeyAlgorithmTags.RSA_GENERAL, kp.getPublic(), creationTime); + + PublicKeyPacket pubKeyPacket = new PublicKeyPacket(6, PublicKeyAlgorithmTags.RSA_GENERAL, creationTime, pubKey.getPublicKeyPacket().getKey()); + byte[] output = calculator.calculateFingerprint(new PublicKeyPacket(6, PublicKeyAlgorithmTags.RSA_GENERAL, creationTime, pubKey.getPublicKeyPacket().getKey())); + byte[] kBytes = pubKeyPacket.getEncodedContents(); + SHA256Digest digest = new SHA256Digest(); + + digest.update((byte)0x9b); + + digest.update((byte)(kBytes.length >> 24)); + digest.update((byte)(kBytes.length >> 16)); + digest.update((byte)(kBytes.length >> 8)); + digest.update((byte)kBytes.length); + + digest.update(kBytes, 0, kBytes.length); + byte[] digBuf = new byte[digest.getDigestSize()]; + + digest.doFinal(digBuf, 0); + isTrue(areEqual(output, digBuf)); + + final PublicKeyPacket pubKeyPacket2 = new PublicKeyPacket(5, PublicKeyAlgorithmTags.RSA_GENERAL, creationTime, pubKey.getPublicKeyPacket().getKey()); + kBytes = pubKeyPacket2.getEncodedContents(); + output = calculator.calculateFingerprint(pubKeyPacket2); + + digest = new SHA256Digest(); + + digest.update((byte)0x9a); + + digest.update((byte)(kBytes.length >> 24)); + digest.update((byte)(kBytes.length >> 16)); + digest.update((byte)(kBytes.length >> 8)); + digest.update((byte)kBytes.length); + + digest.update(kBytes, 0, kBytes.length); + digBuf = new byte[digest.getDigestSize()]; + + digest.doFinal(digBuf, 0); + isTrue(areEqual(output, digBuf)); + } + + public void testBcPBESecretKeyDecryptorBuilder() + throws PGPException + { + final PBESecretKeyDecryptor decryptor = new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(BcPGPDSAElGamalTest.pass); + decryptor.recoverKeyData(SymmetricKeyAlgorithmTags.CAMELLIA_256, new byte[32], new byte[12], new byte[16], 0, 16); + } + + public void testBcPGPContentVerifierBuilderProvider() + throws Exception + { + JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(BcPGPDSAElGamalTest.testPubKeyRing); + PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)pgpFact.nextObject(); + PGPPublicKey pubKey = pgpPub.getPublicKey(); + BcPGPContentVerifierBuilderProvider provider = new BcPGPContentVerifierBuilderProvider(); + PGPContentVerifier contentVerifier = provider.get(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1).build(pubKey); + isEquals(contentVerifier.getHashAlgorithm(), HashAlgorithmTags.SHA1); + isEquals(contentVerifier.getKeyAlgorithm(), PublicKeyAlgorithmTags.DSA); + isEquals(contentVerifier.getKeyID(), pubKey.getKeyID()); + } + + public void testBcPGPDataEncryptorBuilder() + throws Exception + { + testException("null cipher specified", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.NULL); + } + }); + + testException("AEAD algorithms can only be used with AES", "IllegalStateException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.IDEA).setWithAEAD(AEADAlgorithmTags.OCB, 6); + } + }); + + testException("minimum chunkSize is 6", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).setWithAEAD(AEADAlgorithmTags.OCB, 5); + } + }); + + testException("invalid parameters:", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).build(new byte[0]); + } + }); + + isTrue(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).setWithIntegrityPacket(false).build(new byte[32]).getIntegrityCalculator() == null); + + isEquals(16, new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).setWithAEAD(AEADAlgorithmTags.OCB, 6).build(new byte[32]).getBlockSize()); + } + + public void testBcPGPKeyPair() + throws Exception + { + testCreateKeyPairDefault(PublicKeyAlgorithmTags.X448, "X448"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.X25519, "X25519"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.EDDSA_LEGACY, PublicKeyAlgorithmTags.Ed25519, "Ed25519"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.Ed448, "Ed448"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.ECDH, PublicKeyAlgorithmTags.X25519, "X25519"); + testCreateKeyPairEC(PublicKeyAlgorithmTags.ECDH, "ECDH", "P-256"); + testCreateKeyPairEC(PublicKeyAlgorithmTags.ECDH, "ECDH", "P-384"); + testCreateKeyPairEC(PublicKeyAlgorithmTags.ECDH, "ECDH", "P-521"); + testCreateKeyPairEC(PublicKeyAlgorithmTags.ECDH, "ECDH", "brainpoolP256r1"); + testCreateKeyPairEC(PublicKeyAlgorithmTags.ECDH, "ECDH", "brainpoolP384r1"); + testCreateKeyPairEC(PublicKeyAlgorithmTags.ECDH, "ECDH", "brainpoolP512r1"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.X25519, PublicKeyAlgorithmTags.ECDH, "X25519"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.Ed25519, PublicKeyAlgorithmTags.EDDSA_LEGACY, "Ed25519"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.RSA_GENERAL, "RSA"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.ELGAMAL_GENERAL, "ELGAMAL"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.DSA, "DSA"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.ECDH, "X25519"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.EDDSA_LEGACY, "Ed25519"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.ECDSA, "ECDSA"); + testCreateKeyPairEC(PublicKeyAlgorithmTags.ECDSA, "ECDSA", "P-256"); + testCreateKeyPairEC(PublicKeyAlgorithmTags.ECDSA, "ECDSA", "P-384"); + testCreateKeyPairEC(PublicKeyAlgorithmTags.ECDSA, "ECDSA", "P-521"); + testCreateKeyPairEC(PublicKeyAlgorithmTags.ECDSA, "ECDSA", "brainpoolP256r1"); + testCreateKeyPairEC(PublicKeyAlgorithmTags.ECDSA, "ECDSA", "brainpoolP384r1"); + testCreateKeyPairEC(PublicKeyAlgorithmTags.ECDSA, "ECDSA", "brainpoolP512r1"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.ELGAMAL_GENERAL, "ELGAMAL"); + testCreateKeyPairDefault(PublicKeyAlgorithmTags.Ed25519, "Ed25519"); + } + + private void testCreateKeyPairDefault(int algorithm, String name) + throws Exception + { + testCreateKeyPair(algorithm, name, new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator gen) + throws Exception + { + } + }); + } + + private void testCreateKeyPairDefault(int algorithm1, int algorithm2, String name) + throws Exception + { + testCreateKeyPair(algorithm1, algorithm2, name, new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator gen) + throws Exception + { + } + }); + } + + private void testCreateKeyPairEC(int algorithm, String name, final String curveName) + throws Exception + { + testCreateKeyPair(algorithm, name, new KeyPairGeneratorOperation() + { + @Override + public void initialize(KeyPairGenerator gen) + throws Exception + { + gen.initialize(new ECNamedCurveGenParameterSpec(curveName)); + } + }); + } + + private void testCreateKeyPair(int algorithm, String name, KeyPairGeneratorOperation kpgen) + throws Exception + { + testCreateKeyPair(algorithm, algorithm, name, kpgen); + } + + private interface KeyPairGeneratorOperation + { + void initialize(KeyPairGenerator gen) + throws Exception; + } + + private void testCreateKeyPair(int algorithm1, int algorithm2, String name, KeyPairGeneratorOperation kpgen) + throws Exception + { + Date creationDate = new Date(); + KeyPairGenerator gen = KeyPairGenerator.getInstance(name, "BC"); + kpgen.initialize(gen); + KeyPair keyPair = gen.generateKeyPair(); + + BcPGPKeyConverter converter = new BcPGPKeyConverter(); + PGPKeyPair jcaPgpPair = new JcaPGPKeyPair(algorithm1, keyPair, creationDate); + AsymmetricKeyParameter publicKey = converter.getPublicKey(jcaPgpPair.getPublicKey()); + AsymmetricKeyParameter privateKey = converter.getPrivateKey(jcaPgpPair.getPrivateKey()); // This line threw previously. + AsymmetricCipherKeyPair asymKeyPair = new AsymmetricCipherKeyPair(publicKey, privateKey); + + PGPKeyPair bcKeyPair = new BcPGPKeyPair(algorithm2, asymKeyPair, creationDate); + + JcaPGPKeyConverter jcaPGPKeyConverter = new JcaPGPKeyConverter().setProvider(new BouncyCastleProvider()); + PrivateKey privKey = jcaPGPKeyConverter.getPrivateKey(jcaPgpPair.getPrivateKey()); + PublicKey pubKey = jcaPGPKeyConverter.getPublicKey(jcaPgpPair.getPublicKey()); + + if (algorithm1 == algorithm2 && !Arrays.areEqual(jcaPgpPair.getPrivateKey().getPrivateKeyDataPacket().getEncoded(), + bcKeyPair.getPrivateKey().getPrivateKeyDataPacket().getEncoded())) + { + throw new PGPException("JcaPGPKeyPair and BcPGPKeyPair private keys are not equal."); + } + + if (algorithm1 == algorithm2 && !Arrays.areEqual(jcaPgpPair.getPublicKey().getPublicKeyPacket().getEncoded(), + bcKeyPair.getPublicKey().getPublicKeyPacket().getEncoded())) + { + throw new PGPException("JcaPGPKeyPair and BcPGPKeyPair public keys are not equal."); + } +// byte[] b1 = privKey.getEncoded(); +// byte[] b2 = keyPair.getPrivate().getEncoded(); +// for (int i = 0; i < b1.length; ++i) +// { +// if (b1[i] != b2[i]) +// { +// System.out.println(i + " " + b1[i] + " " + b2[i]); +// } +// } + + isTrue("pub key mismatch: " + name, Arrays.areEqual(pubKey.getEncoded(), keyPair.getPublic().getEncoded())); + isTrue(privKey.toString().equals(keyPair.getPrivate().toString())); + // getEncoded() are Not equal as privKey.hasPublicKey is false but keyPair.getPrivate().hasPublicKey is true + //isTrue(Arrays.equals(privKey.getEncoded(), keyPair.getPrivate().getEncoded())); + } + + public void testKeyRings() + throws Exception + { + keyringTest("EdDSA", "Ed448", PublicKeyAlgorithmTags.EDDSA_LEGACY, "XDH", "X448", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA512, SymmetricKeyAlgorithmTags.AES_256); + keyringTest("EdDSA", "Ed448", PublicKeyAlgorithmTags.Ed448, "XDH", "X448", PublicKeyAlgorithmTags.X448, HashAlgorithmTags.SHA512, SymmetricKeyAlgorithmTags.AES_256); + keyringTest("EdDSA", "Ed25519", PublicKeyAlgorithmTags.EDDSA_LEGACY, "XDH", "X25519", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_128); + + + keyringTest("EdDSA", "ED25519", PublicKeyAlgorithmTags.Ed25519, "XDH", "X25519", PublicKeyAlgorithmTags.X25519, HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_128); + + + keyringTest("ECDSA", "NIST P-256", PublicKeyAlgorithmTags.ECDSA, "ECDH", "NIST P-256", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_128); + keyringTest("ECDSA", "NIST P-384", PublicKeyAlgorithmTags.ECDSA, "ECDH", "NIST P-384", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA384, SymmetricKeyAlgorithmTags.AES_192); + keyringTest("ECDSA", "NIST P-521", PublicKeyAlgorithmTags.ECDSA, "ECDH", "NIST P-521", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA512, SymmetricKeyAlgorithmTags.AES_256); + keyringTest("ECDSA", "brainpoolP256r1", PublicKeyAlgorithmTags.ECDSA, "ECDH", "brainpoolP256r1", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_128); + keyringTest("ECDSA", "brainpoolP384r1", PublicKeyAlgorithmTags.ECDSA, "ECDH", "brainpoolP384r1", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA384, SymmetricKeyAlgorithmTags.AES_192); + keyringTest("ECDSA", "brainpoolP512r1", PublicKeyAlgorithmTags.ECDSA, "ECDH", "brainpoolP512r1", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA512, SymmetricKeyAlgorithmTags.AES_256); + + keyringTest("EdDSA", "ED25519", PublicKeyAlgorithmTags.EDDSA_LEGACY, "XDH", "X25519", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA384, SymmetricKeyAlgorithmTags.AES_128); + keyringTest("EdDSA", "ED25519", PublicKeyAlgorithmTags.EDDSA_LEGACY, "XDH", "X25519", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA512, SymmetricKeyAlgorithmTags.AES_128); + keyringTest("EdDSA", "Ed25519", PublicKeyAlgorithmTags.EDDSA_LEGACY, "XDH", "X25519", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_192); + keyringTest("EdDSA", "Ed25519", PublicKeyAlgorithmTags.EDDSA_LEGACY, "XDH", "X25519", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_256); + keyringTest("EdDSA", "Ed25519", PublicKeyAlgorithmTags.EDDSA_LEGACY, "XDH", "X25519", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.CAMELLIA_128); + keyringTest("EdDSA", "Ed25519", PublicKeyAlgorithmTags.EDDSA_LEGACY, "XDH", "X25519", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.CAMELLIA_192); + keyringTest("EdDSA", "Ed25519", PublicKeyAlgorithmTags.EDDSA_LEGACY, "XDH", "X25519", PublicKeyAlgorithmTags.ECDH, HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.CAMELLIA_256); + } + + private void keyringTest(String algorithmName1, String ed_str, int ed_num, String algorithmName2, String x_str, int x_num, int hashAlgorithm, int symmetricWrapAlgorithm) + throws Exception + { + + String identity = "eric@bouncycastle.org"; + char[] passPhrase = "Hello, world!".toCharArray(); + + KeyPairGenerator edKp = KeyPairGenerator.getInstance(algorithmName1, "BC"); + + edKp.initialize(new ECNamedCurveGenParameterSpec(ed_str)); + + PGPKeyPair dsaKeyPair = new JcaPGPKeyPair(ed_num, edKp.generateKeyPair(), new Date()); + + KeyPairGenerator dhKp = KeyPairGenerator.getInstance(algorithmName2, "BC"); + + dhKp.initialize(new ECNamedCurveGenParameterSpec(x_str)); + + PGPKeyPair dhKeyPair = new JcaPGPKeyPair(x_num, new PGPKdfParameters(hashAlgorithm, symmetricWrapAlgorithm), dhKp.generateKeyPair(), new Date()); + + encryptDecryptTest(dhKeyPair.getPublicKey(), dhKeyPair.getPrivateKey()); + encryptDecryptBcTest(dhKeyPair.getPublicKey(), dhKeyPair.getPrivateKey()); + + PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1); + + PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator( + PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, + identity, sha1Calc, null, null, + new JcaPGPContentSignerBuilder(dsaKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA256).setProvider("BC"), + new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha1Calc).setProvider("BC").build(passPhrase)); + + keyRingGen.addSubKey(dhKeyPair); + + ByteArrayOutputStream secretOut = new ByteArrayOutputStream(); + + PGPSecretKeyRing secRing = keyRingGen.generateSecretKeyRing(); + +// PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); +// + secRing.encode(secretOut); +// + secretOut.close(); + secRing = new PGPSecretKeyRing(secretOut.toByteArray(), new JcaKeyFingerprintCalculator()); + + Iterator pIt = secRing.getPublicKeys(); + pIt.next(); + + PGPPublicKey sKey = (PGPPublicKey)pIt.next(); + PGPPublicKey vKey = secRing.getPublicKey(); + + Iterator sIt = sKey.getSignatures(); + int count = 0; + while (sIt.hasNext()) + { + PGPSignature sig = (PGPSignature)sIt.next(); + + if (sig.getKeyID() == vKey.getKeyID() + && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) + { + count++; + sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), vKey); + // TODO: appears to be failing on CI system + if (!sig.verifyCertification(vKey, sKey)) + { + fail("failed to verify sub-key signature."); + } + } + } + + isTrue(count == 1); + + secRing = new PGPSecretKeyRing(secretOut.toByteArray(), new JcaKeyFingerprintCalculator()); + PGPPublicKey pubKey = null; + PGPPrivateKey privKey = null; + + for (Iterator it = secRing.getPublicKeys(); it.hasNext(); ) + { + pubKey = (PGPPublicKey)it.next(); + if (pubKey.isEncryptionKey()) + { + privKey = secRing.getSecretKey(pubKey.getKeyID()).extractPrivateKey( + new JcePBESecretKeyDecryptorBuilder().setProvider(new BouncyCastleProvider()).build(passPhrase)); + break; + } + } + + encryptDecryptTest(pubKey, privKey); + encryptDecryptBcTest(pubKey, privKey); + } + + private void encryptDecryptBcTest(PGPPublicKey pubKey, PGPPrivateKey secKey) + throws Exception + { + byte[] text = {(byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n'}; + + PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(); + ByteArrayOutputStream ldOut = new ByteArrayOutputStream(); + OutputStream pOut = lData.open(ldOut, PGPLiteralDataGenerator.UTF8, PGPLiteralData.CONSOLE, text.length, new Date()); + + pOut.write(text); + + pOut.close(); + + byte[] data = ldOut.toByteArray(); + + ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); + + PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(new SecureRandom())); + + cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(pubKey)); + + OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), data.length); + + cOut.write(data); + + cOut.close(); + + BcPGPObjectFactory pgpF = new BcPGPObjectFactory(cbOut.toByteArray()); + + PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); + + PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); + + InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(secKey)); + + pgpF = new BcPGPObjectFactory(clear); + + PGPLiteralData ld = (PGPLiteralData)pgpF.nextObject(); + + clear = ld.getInputStream(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + int ch; + while ((ch = clear.read()) >= 0) + { + bOut.write(ch); + } + + byte[] out = bOut.toByteArray(); + + if (!areEqual(out, text)) + { + fail("wrong plain text in generated packet"); + } + } + + private void encryptDecryptTest(PGPPublicKey pubKey, PGPPrivateKey secKey) + throws Exception + { + byte[] text = {(byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n'}; + + PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(); + ByteArrayOutputStream ldOut = new ByteArrayOutputStream(); + OutputStream pOut = lData.open(ldOut, PGPLiteralDataGenerator.UTF8, PGPLiteralData.CONSOLE, text.length, new Date()); + + pOut.write(text); + + pOut.close(); + + byte[] data = ldOut.toByteArray(); + + ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); + + PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setProvider("BC").setSecureRandom(new SecureRandom())); + + cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(pubKey).setProvider(new BouncyCastleProvider()).setSecureRandom(CryptoServicesRegistrar.getSecureRandom())); + + OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), data.length); + + cOut.write(data); + + cOut.close(); + + JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(cbOut.toByteArray()); + + PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); + + PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); + + InputStream clear = encP.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider(new BouncyCastleProvider()).setContentProvider(new BouncyCastleProvider()).build(secKey)); + + pgpF = new JcaPGPObjectFactory(clear); + + PGPLiteralData ld = (PGPLiteralData)pgpF.nextObject(); + + clear = ld.getInputStream(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + int ch; + while ((ch = clear.read()) >= 0) + { + bOut.write(ch); + } + + byte[] out = bOut.toByteArray(); + + if (!areEqual(out, text)) + { + fail("wrong plain text in generated packet"); + } + } + + public void testX25519HKDF() + throws Exception + { + byte[] ephmeralKey = Hex.decode("87cf18d5f1b53f817cce5a004cf393cc8958bddc065f25f84af509b17dd36764"); + byte[] ephmeralSecretKey = Hex.decode("af1e43c0d123efe893a7d4d390f3a761e3fac33dfc7f3edaa830c9011352c779"); + byte[] publicKey = Hex.decode("8693248367f9e5015db922f8f48095dda784987f2d5985b12fbad16caf5e4435"); + byte[] expectedHKDF = Hex.decode("f66dadcff64592239b254539b64ff607"); + byte[] keyEnc = Hex.decode("dea355437956617901e06957fbca8a6a47a5b5153e8d3ab7"); + byte[] expectedDecryptedSessionKey = Hex.decode("dd708f6fa1ed65114d68d2343e7c2f1d"); + X25519PrivateKeyParameters ephmeralprivateKeyParameters = new X25519PrivateKeyParameters(ephmeralSecretKey); + X25519PublicKeyParameters publicKeyParameters = new X25519PublicKeyParameters(publicKey); + X25519Agreement agreement = new X25519Agreement(); + agreement.init(ephmeralprivateKeyParameters); + byte[] secret = new byte[agreement.getAgreementSize()]; + agreement.calculateAgreement(publicKeyParameters, secret, 0); + byte[] output2 = new byte[16]; + HKDFBytesGenerator hkdf = new HKDFBytesGenerator(new SHA256Digest()); + hkdf.init(new HKDFParameters(Arrays.concatenate(ephmeralKey, publicKey, secret), null, "OpenPGP X25519".getBytes())); + hkdf.generateBytes(output2, 0, 16); + + isTrue(Arrays.areEqual(output2, expectedHKDF)); + Wrapper c = new RFC3394WrapEngine(AESEngine.newInstance()); + c.init(false, new KeyParameter(output2)); + byte[] output = c.unwrap(keyEnc, 0, keyEnc.length); + isTrue(Arrays.areEqual(output, expectedDecryptedSessionKey)); + } + + + +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/OperatorJcajceTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/OperatorJcajceTest.java new file mode 100644 index 0000000000..ad99272f50 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/OperatorJcajceTest.java @@ -0,0 +1,350 @@ +package org.bouncycastle.openpgp.test; + +import java.io.IOException; +import java.io.OutputStream; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.Provider; +import java.security.PublicKey; +import java.security.Security; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Date; + +import javax.crypto.KeyAgreement; + +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.bcpg.AEADAlgorithmTags; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyPacket; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; +import org.bouncycastle.crypto.params.X25519PublicKeyParameters; +import org.bouncycastle.crypto.util.PrivateKeyInfoFactory; +import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; +import org.bouncycastle.jcajce.spec.HybridValueParameterSpec; +import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openpgp.PGPEncryptedData; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.operator.PGPContentVerifier; +import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter; +import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; + +public class OperatorJcajceTest + extends SimpleTest +{ + public static void main(String[] args) + { + Security.addProvider(new BouncyCastleProvider()); + + runTest(new OperatorJcajceTest()); + } + + @Override + public String getName() + { + return "OperatorJcajceTest"; + } + + @Override + public void performTest() + throws Exception + { + testCreateDigest(); + testX25519HKDF(); + testJcePBESecretKeyEncryptorBuilder(); + testJcaPGPContentVerifierBuilderProvider(); + testJcaPGPDigestCalculatorProviderBuilder(); + testJcePGPDataEncryptorBuilder(); + testJcaKeyFingerprintCalculator(); + testStandardDigests(); + } + + private void testStandardDigests() + throws Exception + { + PGPDigestCalculatorProvider digCalcBldr = + new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build(); + + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.MD5), Hex.decode("900150983cd24fb0d6963f7d28e17f72")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA1), Hex.decode("a9993e364706816aba3e25717850c26c9cd0d89d")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.RIPEMD160), Hex.decode("8eb208f7e05d987a9b044a8e98c6b087f15a0bfc")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA256), Hex.decode("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA384), Hex.decode("cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA512), Hex.decode("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA224), Hex.decode("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA3_256), Hex.decode("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532")); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA3_512), Hex.decode("b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0")); + } + + private void testDigestCalc(PGPDigestCalculator digCalc, byte[] expected) + throws IOException + { + OutputStream dOut = digCalc.getOutputStream(); + + dOut.write(Strings.toByteArray("abc")); + + dOut.close(); + + byte[] res = digCalc.getDigest(); + + isTrue(Arrays.areEqual(res, expected)); + } + + public void testJcaKeyFingerprintCalculator() + throws Exception + { + final JcaKeyFingerprintCalculator calculator = new JcaKeyFingerprintCalculator().setProvider(new NullProvider()); + KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); + kpGen.initialize(1024); + KeyPair kp = kpGen.generateKeyPair(); + + JcaPGPKeyConverter converter = new JcaPGPKeyConverter().setProvider(new BouncyCastleProvider()); + final PGPPublicKey pubKey = converter.getPGPPublicKey(PublicKeyAlgorithmTags.RSA_GENERAL, kp.getPublic(), new Date()); + + testException("can't find MD5", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + calculator.calculateFingerprint(new PublicKeyPacket(3, PublicKeyAlgorithmTags.RSA_GENERAL, new Date(), pubKey.getPublicKeyPacket().getKey())); + } + }); + testException("can't find SHA1", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + calculator.calculateFingerprint(new PublicKeyPacket(4, PublicKeyAlgorithmTags.RSA_GENERAL, new Date(), pubKey.getPublicKeyPacket().getKey())); + } + }); + testException("can't find SHA-256", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + calculator.calculateFingerprint(new PublicKeyPacket(6, PublicKeyAlgorithmTags.RSA_GENERAL, new Date(), pubKey.getPublicKeyPacket().getKey())); + } + }); + //JcaKeyFingerprintCalculator calculator2 = new JcaKeyFingerprintCalculator().setProvider("BC"); + JcaKeyFingerprintCalculator calculator2 = calculator.setProvider("BC"); + PublicKeyPacket pubKeyPacket = new PublicKeyPacket(6, PublicKeyAlgorithmTags.RSA_GENERAL, new Date(), pubKey.getPublicKeyPacket().getKey()); + byte[] output = calculator2.calculateFingerprint(new PublicKeyPacket(6, PublicKeyAlgorithmTags.RSA_GENERAL, new Date(), pubKey.getPublicKeyPacket().getKey())); + byte[] kBytes = pubKeyPacket.getEncodedContents(); + SHA256Digest digest = new SHA256Digest(); + + digest.update((byte)0x9b); + + digest.update((byte)(kBytes.length >> 24)); + digest.update((byte)(kBytes.length >> 16)); + digest.update((byte)(kBytes.length >> 8)); + digest.update((byte)kBytes.length); + + digest.update(kBytes, 0, kBytes.length); + byte[] digBuf = new byte[digest.getDigestSize()]; + + digest.doFinal(digBuf, 0); + isTrue(areEqual(output, digBuf)); + + testException("Unsupported PGP key version: ", "UnsupportedPacketVersionException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + calculator.calculateFingerprint(new PublicKeyPacket(7, PublicKeyAlgorithmTags.RSA_GENERAL, new Date(), pubKey.getPublicKeyPacket().getKey())); + } + }); + } + + public void testJcePGPDataEncryptorBuilder() + throws Exception + { + testException("null cipher specified", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.NULL); + } + }); + + //testException("AEAD algorithms can only be used with AES", "IllegalStateException", () -> new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.IDEA).setWithAEAD(AEADAlgorithmTags.OCB, 6)); + + testException("minimum chunkSize is 6", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).setWithAEAD(AEADAlgorithmTags.OCB, 5); + } + }); + + isEquals(16, new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).setProvider(new BouncyCastleProvider()).setWithAEAD(AEADAlgorithmTags.OCB, 6).build(new byte[32]).getBlockSize()); + } + + public void testJcaPGPDigestCalculatorProviderBuilder() + throws Exception + { + + PGPDigestCalculatorProvider digCalcBldr = new JcaPGPDigestCalculatorProviderBuilder().setProvider(new NonDashProvider()).build(); + testDigestCalc(digCalcBldr.get(HashAlgorithmTags.SHA256), Hex.decode("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")); + + PGPDigestCalculatorProvider digCalcBldr2 = new JcaPGPDigestCalculatorProviderBuilder().setProvider(new DashProvider()).build(); + testDigestCalc(digCalcBldr2.get(HashAlgorithmTags.SHA256), Hex.decode("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")); + + PGPDigestCalculatorProvider digCalcBldr3 = new JcaPGPDigestCalculatorProviderBuilder().setProvider(new NonDashProvider()).build(); + testDigestCalc(digCalcBldr3.get(HashAlgorithmTags.SHA1), Hex.decode("a9993e364706816aba3e25717850c26c9cd0d89d")); + + PGPDigestCalculatorProvider digCalcBldr4 = new JcaPGPDigestCalculatorProviderBuilder().setProvider(new DashProvider()).build(); + testDigestCalc(digCalcBldr4.get(HashAlgorithmTags.SHA1), Hex.decode("a9993e364706816aba3e25717850c26c9cd0d89d")); + + + final PGPDigestCalculatorProvider provider = new JcaPGPDigestCalculatorProviderBuilder().setProvider(new NullProvider()).build(); + testException("exception on setup: ", "PGPException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + provider.get(SymmetricKeyAlgorithmTags.AES_256); + } + }); + } + + public void testJcaPGPContentVerifierBuilderProvider() + throws Exception + { + KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); + kpGen.initialize(1024); + KeyPair kp = kpGen.generateKeyPair(); + + JcaPGPKeyConverter converter = new JcaPGPKeyConverter().setProvider(new BouncyCastleProvider()); + final PGPPublicKey pubKey = converter.getPGPPublicKey(PublicKeyAlgorithmTags.RSA_GENERAL, kp.getPublic(), new Date()); + PGPContentVerifier verifier = new JcaPGPContentVerifierBuilderProvider().setProvider(new BouncyCastleProvider()).get(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA256).build(pubKey); + isTrue(verifier.getHashAlgorithm() == HashAlgorithmTags.SHA256); + isTrue(verifier.getKeyAlgorithm() == PublicKeyAlgorithmTags.RSA_GENERAL); + isTrue(verifier.getKeyID() == pubKey.getKeyID()); + } + + public void testJcePBESecretKeyEncryptorBuilder() + throws Exception + { + final PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1); + testException("s2KCount value outside of range 0 to 255.", "IllegalArgumentException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha1Calc, -1); + } + }); + } + + public void testCreateDigest() + throws Exception + { + isEquals(new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1).getAlgorithm(), HashAlgorithmTags.SHA1); + isEquals(new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.MD2).getAlgorithm(), HashAlgorithmTags.MD2); + isEquals(new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.MD5).getAlgorithm(), HashAlgorithmTags.MD5); + isEquals(new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.RIPEMD160).getAlgorithm(), HashAlgorithmTags.RIPEMD160); + isEquals(new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA256).getAlgorithm(), HashAlgorithmTags.SHA256); + isEquals(new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA224).getAlgorithm(), HashAlgorithmTags.SHA224); + isEquals(new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA384).getAlgorithm(), HashAlgorithmTags.SHA384); + isEquals(new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA512).getAlgorithm(), HashAlgorithmTags.SHA512); + isEquals(new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA3_256).getAlgorithm(), HashAlgorithmTags.SHA3_256); + isEquals(new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA3_224).getAlgorithm(), HashAlgorithmTags.SHA3_224); + isEquals(new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA3_384).getAlgorithm(), HashAlgorithmTags.SHA3_384); + isEquals(new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA3_512).getAlgorithm(), HashAlgorithmTags.SHA3_512); + isEquals(new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.TIGER_192).getAlgorithm(), HashAlgorithmTags.TIGER_192); + } + + public void testX25519HKDF() + throws Exception + { + byte[] ephmeralKey = Hex.decode("87cf18d5f1b53f817cce5a004cf393cc8958bddc065f25f84af509b17dd36764"); + byte[] ephmeralSecretKey = Hex.decode("af1e43c0d123efe893a7d4d390f3a761e3fac33dfc7f3edaa830c9011352c779"); + byte[] publicKey = Hex.decode("8693248367f9e5015db922f8f48095dda784987f2d5985b12fbad16caf5e4435"); + byte[] expectedHKDF = Hex.decode("f66dadcff64592239b254539b64ff607"); + byte[] keyEnc = Hex.decode("dea355437956617901e06957fbca8a6a47a5b5153e8d3ab7"); + byte[] expectedDecryptedSessionKey = Hex.decode("dd708f6fa1ed65114d68d2343e7c2f1d"); + X25519PrivateKeyParameters ephmeralprivateKeyParameters = new X25519PrivateKeyParameters(ephmeralSecretKey); + X25519PublicKeyParameters publicKeyParameters = new X25519PublicKeyParameters(publicKey); + KeyFactory keyfact = KeyFactory.getInstance("X25519", "BC"); + PrivateKey privKey = keyfact.generatePrivate(new PKCS8EncodedKeySpec(PrivateKeyInfoFactory.createPrivateKeyInfo(ephmeralprivateKeyParameters).getEncoded())); + PublicKey pubKey = keyfact.generatePublic(new X509EncodedKeySpec(SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(publicKeyParameters).getEncoded())); + KeyAgreement agreement = KeyAgreement.getInstance("X25519withSHA256HKDF", "BC"); + agreement.init(privKey, new HybridValueParameterSpec(Arrays.concatenate(ephmeralKey, publicKey), true, new UserKeyingMaterialSpec(Strings.toByteArray("OpenPGP X25519")))); + agreement.doPhase(pubKey, true); + Key secretKey = agreement.generateSecret(NISTObjectIdentifiers.id_aes128_wrap.getId()); + +// agreement.init(ephmeralprivateKeyParameters); +// byte[] secret = new byte[agreement.getAgreementSize()]; +// agreement.calculateAgreement(publicKeyParameters, secret, 0); + byte[] output2 = secretKey.getEncoded(); + +// HKDFBytesGenerator hkdf = new HKDFBytesGenerator(new SHA256Digest()); +// hkdf.init(new HKDFParameters(Arrays.concatenate(ephmeralKey, publicKey, secret), null, "OpenPGP X25519".getBytes())); +// hkdf.generateBytes(output2, 0, 16); +// + isTrue("hkdf failed", Arrays.areEqual(output2, expectedHKDF)); +// Wrapper c = new RFC3394WrapEngine(AESEngine.newInstance()); +// c.init(false, new KeyParameter(output2)); +// byte[] output = c.unwrap(keyEnc, 0, keyEnc.length); + //isTrue(Arrays.areEqual(output, expectedDecryptedSessionKey)); + } + + private class NullProvider + extends Provider + { + NullProvider() + { + super("NULL", 0.0, "Null Provider"); + } + } + + private class NonDashProvider + extends Provider + { + NonDashProvider() + { + super("NonDash", 0.0, "NonDash Provider"); + putService(new Provider.Service(this, "MessageDigest", "SHA256", "org.bouncycastle.openpgp.test.SHA256", null, null)); + putService(new Provider.Service(this, "MessageDigest", "SHA1", "org.bouncycastle.openpgp.test.SHA1", null, null)); + } + } + + private class DashProvider + extends Provider + { + DashProvider() + { + super("Dash", 0.0, "Dash Provider"); + putService(new Service(this, "MessageDigest", "SHA-256", "org.bouncycastle.openpgp.test.SHA256", null, null)); + putService(new Service(this, "MessageDigest", "SHA-1", "org.bouncycastle.openpgp.test.SHA1", null, null)); + } + } + +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPAeadTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPAeadTest.java index 852659c562..5eaca50e3a 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPAeadTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPAeadTest.java @@ -4,31 +4,46 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.security.SecureRandom; import java.security.Security; +import java.util.Date; import org.bouncycastle.bcpg.AEADAlgorithmTags; import org.bouncycastle.bcpg.ArmoredInputStream; +import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; +import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.PaddingPacket; +import org.bouncycastle.bcpg.SignatureSubpacket; +import org.bouncycastle.bcpg.SignatureSubpacketInputStream; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.sig.PreferredAEADCiphersuites; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPEncryptedData; +import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPLiteralData; +import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPPBEEncryptedData; import org.bouncycastle.openpgp.PGPPadding; import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.bc.BcPBEDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.bc.BcPBEKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Exceptions; import org.bouncycastle.util.Pack; @@ -113,6 +128,8 @@ public void performTest() roundTripEncryptionDecryptionTests(); paddingPacketTests(); + + preferredAEADAlgorithmsTests(); } private void roundTripEncryptionDecryptionTests() @@ -126,24 +143,31 @@ private void roundTripEncryptionDecryptionTests() int[] symAlgs = new int[]{ SymmetricKeyAlgorithmTags.AES_128, SymmetricKeyAlgorithmTags.AES_192, - SymmetricKeyAlgorithmTags.AES_256 + SymmetricKeyAlgorithmTags.AES_256, + SymmetricKeyAlgorithmTags.CAMELLIA_128, + SymmetricKeyAlgorithmTags.CAMELLIA_192, + SymmetricKeyAlgorithmTags.CAMELLIA_256 }; -// PGPAEADFlavour[] flavours = new PGPAEADFlavour[] { -// PGPAEADFlavour.OPENPGP_V6, -// PGPAEADFlavour.OPENPGP_V5, -// }; - // Test round-trip encryption -// for (PGPAEADFlavour flavour : flavours) { -// for (int aeadAlg : aeadAlgs) { -// for (int symAlg : symAlgs) { -// testBcRoundTrip(flavour, aeadAlg, symAlg, PLAINTEXT, PASSWORD); -// testJceRoundTrip(flavour, aeadAlg, symAlg, PLAINTEXT, PASSWORD); -// testBcJceRoundTrip(flavour, aeadAlg, symAlg, PLAINTEXT, PASSWORD); -// testJceBcRoundTrip(flavour, aeadAlg, symAlg, PLAINTEXT, PASSWORD); -// } -// } -// } + for (int i = 0; i != aeadAlgs.length; i++) + { + int aeadAlg = aeadAlgs[i]; + for (int j = 0; j != symAlgs.length; j++) + { + int symAlg = symAlgs[j]; + // OpenPGP v5 + testBcRoundTrip(true, aeadAlg, symAlg, PLAINTEXT, PASSWORD); + testJceRoundTrip(true, aeadAlg, symAlg, PLAINTEXT, PASSWORD); + testBcJceRoundTrip(true, aeadAlg, symAlg, PLAINTEXT, PASSWORD); + testJceBcRoundTrip(true, aeadAlg, symAlg, PLAINTEXT, PASSWORD); + + // OpenPGP v6 + testBcRoundTrip(false, aeadAlg, symAlg, PLAINTEXT, PASSWORD); + testJceRoundTrip(false, aeadAlg, symAlg, PLAINTEXT, PASSWORD); + testBcJceRoundTrip(false, aeadAlg, symAlg, PLAINTEXT, PASSWORD); + testJceBcRoundTrip(false, aeadAlg, symAlg, PLAINTEXT, PASSWORD); + } + } } private void knownV5TestVectorDecryptionTests() @@ -163,7 +187,7 @@ private void knownV5TestVectorDecryptionTests() private void knownV6TestVectorDecryptionTests() throws IOException, PGPException { - // Test known-good V6 test vectors + // Test known-good V6 test vectors TODO: decryption tests should be working... System.out.println("Test V6 BC Decryption"); testBcDecryption(V6_EAX_PACKET_SEQUENCE, PASSWORD, PLAINTEXT); testBcDecryption(V6_OCB_PACKET_SEQUENCE, PASSWORD, PLAINTEXT); @@ -174,105 +198,133 @@ private void knownV6TestVectorDecryptionTests() testJceDecryption(V6_GCM_PACKET_SEQUENCE, PASSWORD, PLAINTEXT); } -// private void testBcRoundTrip(PGPAEADFlavour flavour, int aeadAlg, int symAlg, byte[] plaintext, char[] password) throws PGPException, IOException { -// System.out.println("Test BC RoundTrip " + flavour + " " + algNames(aeadAlg, symAlg)); -// String armored = testBcEncryption(flavour, aeadAlg, symAlg, plaintext, password); -// System.out.println(armored); -// testBcDecryption(armored, password, plaintext); -// } - -// private void testJceRoundTrip(PGPAEADFlavour flavour, int aeadAlg, int symAlg, byte[] plaintext, char[] password) throws PGPException, IOException { -// System.out.println("Test JCE RoundTrip " + flavour + " " + algNames(aeadAlg, symAlg)); -// String armored = testJceEncryption(flavour, aeadAlg, symAlg, plaintext, password); -// System.out.println(armored); -// testJceDecryption(armored, password, plaintext); -// } - -// private void testBcJceRoundTrip(PGPAEADFlavour flavour, int aeadAlg, int symAlg, byte[] plaintext, char[] password) -// throws PGPException, IOException { -// System.out.println("Test BC encrypt, JCE decrypt " + flavour + " " + algNames(aeadAlg, symAlg)); -// String armored = testBcEncryption(flavour, aeadAlg, symAlg, plaintext, password); -// System.out.println(armored); -// testJceDecryption(armored, password, plaintext); -// } -// -// private void testJceBcRoundTrip(PGPAEADFlavour flavour, int aeadAlg, int symAlg, byte[] plaintext, char[] password) throws PGPException, IOException { -// System.out.println("Test JCE encrypt, BC decrypt " + flavour + " " + algNames(aeadAlg, symAlg)); -// String armored = testJceEncryption(flavour, aeadAlg, symAlg, plaintext, password); -// System.out.println(armored); -// testBcDecryption(armored, password, plaintext); -// } -// -// private String testBcEncryption(PGPAEADFlavour flavour, int aeadAlg, int symAlg, byte[] plaintext, char[] password) throws PGPException, IOException { -// ByteArrayOutputStream ciphertextOut = new ByteArrayOutputStream(); -// PGPDigestCalculatorProvider digestCalculatorProvider = new BcPGPDigestCalculatorProvider(); -// PGPDataEncryptorBuilder encBuilder = new BcPGPDataEncryptorBuilder(symAlg); -// encBuilder.setWithAEAD(flavour, aeadAlg, 6); -// PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encBuilder, false); -// encGen.setForceSessionKey(true); -// PBEKeyEncryptionMethodGenerator encMethodGen = new BcPBEKeyEncryptionMethodGenerator(password, -// digestCalculatorProvider.get(HashAlgorithmTags.SHA256)); -// encGen.addMethod(encMethodGen); -// OutputStream encOut = encGen.open(ciphertextOut, new byte[1 << 9]); -// encOut.flush(); -// PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator(); -// OutputStream litOut = litGen.open(encOut, PGPLiteralData.UTF8, "", new Date(), new byte[1 << 9]); -// -// litOut.write(plaintext); -// litOut.flush(); -// litOut.close(); -// -// encOut.flush(); -// encOut.close(); -// -// ByteArrayOutputStream armoredMsg = new ByteArrayOutputStream(); -// ArmoredOutputStream armorOut = new ArmoredOutputStream(armoredMsg); -// armorOut.write(ciphertextOut.toByteArray()); -// armorOut.flush(); -// armorOut.close(); -// -// printHex(ciphertextOut.toByteArray()); -// -// String armored = armoredMsg.toString(); -// return armored; -// } -// -// private String testJceEncryption(PGPAEADFlavour flavour, int aeadAlg, int symAlg, byte[] plaintext, char[] password) throws PGPException, IOException { -// BouncyCastleProvider provider = new BouncyCastleProvider(); -// Security.addProvider(provider); -// ByteArrayOutputStream ciphertextOut = new ByteArrayOutputStream(); -// PGPDigestCalculatorProvider digestCalculatorProvider = new JcaPGPDigestCalculatorProviderBuilder() -// .setProvider(provider).build(); -// PGPDataEncryptorBuilder encBuilder = new JcePGPDataEncryptorBuilder(symAlg); -// encBuilder.setWithAEAD(flavour, aeadAlg, 6); -// PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encBuilder, false); -// encGen.setForceSessionKey(true); -// PBEKeyEncryptionMethodGenerator encMethodGen = new JcePBEKeyEncryptionMethodGenerator(password, -// digestCalculatorProvider.get(HashAlgorithmTags.SHA256)); -// encGen.addMethod(encMethodGen); -// OutputStream encOut = encGen.open(ciphertextOut, new byte[1 << 9]); -// encOut.flush(); -// PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator(); -// OutputStream litOut = litGen.open(encOut, PGPLiteralData.UTF8, "", new Date(), new byte[1 << 9]); -// -// litOut.write(plaintext); -// litOut.flush(); -// litOut.close(); -// -// encOut.flush(); -// encOut.close(); -// -// ByteArrayOutputStream armoredMsg = new ByteArrayOutputStream(); -// ArmoredOutputStream armorOut = new ArmoredOutputStream(armoredMsg); -// armorOut.write(ciphertextOut.toByteArray()); -// armorOut.flush(); -// armorOut.close(); -// -// printHex(ciphertextOut.toByteArray()); -// -// String armored = armoredMsg.toString(); -// return armored; -// } + private void testBcRoundTrip(boolean v5AEAD, int aeadAlg, int symAlg, byte[] plaintext, char[] password) + throws PGPException, IOException + { + System.out.println("Test BC RoundTrip " + (v5AEAD ? "V5" : "V6") + " " + algNames(aeadAlg, symAlg)); + String armored = testBcEncryption(v5AEAD, aeadAlg, symAlg, plaintext, password); + System.out.println(armored); + testBcDecryption(armored, password, plaintext); + } + + private void testJceRoundTrip(boolean v5AEAD, int aeadAlg, int symAlg, byte[] plaintext, char[] password) + throws PGPException, IOException + { + System.out.println("Test JCE RoundTrip " + (v5AEAD ? "V5" : "V6") + " " + algNames(aeadAlg, symAlg)); + String armored = testJceEncryption(v5AEAD, aeadAlg, symAlg, plaintext, password); + System.out.println(armored); + testJceDecryption(armored, password, plaintext); + } + + private void testBcJceRoundTrip(boolean v5AEAD, int aeadAlg, int symAlg, byte[] plaintext, char[] password) + throws PGPException, IOException + { + System.out.println("Test BC encrypt, JCE decrypt " + (v5AEAD ? "V5" : "V6") + " " + algNames(aeadAlg, symAlg)); + String armored = testBcEncryption(v5AEAD, aeadAlg, symAlg, plaintext, password); + System.out.println(armored); + testJceDecryption(armored, password, plaintext); + } + + private void testJceBcRoundTrip(boolean v5AEAD, int aeadAlg, int symAlg, byte[] plaintext, char[] password) + throws PGPException, IOException + { + System.out.println("Test JCE encrypt, BC decrypt " + (v5AEAD ? "V5" : "V6") + " " + algNames(aeadAlg, symAlg)); + String armored = testJceEncryption(v5AEAD, aeadAlg, symAlg, plaintext, password); + System.out.println(armored); + testBcDecryption(armored, password, plaintext); + } + + private String testBcEncryption(boolean v5AEAD, int aeadAlg, int symAlg, byte[] plaintext, char[] password) + throws PGPException, IOException + { + ByteArrayOutputStream ciphertextOut = new ByteArrayOutputStream(); + PGPDigestCalculatorProvider digestCalculatorProvider = new BcPGPDigestCalculatorProvider(); + PGPDataEncryptorBuilder encBuilder = new BcPGPDataEncryptorBuilder(symAlg); + if (v5AEAD) + { + encBuilder.setUseV5AEAD(); + } + else + { + encBuilder.setUseV6AEAD(); + } + encBuilder.setWithAEAD(aeadAlg, 6); + + PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encBuilder, false); + encGen.setForceSessionKey(true); + PBEKeyEncryptionMethodGenerator encMethodGen = new BcPBEKeyEncryptionMethodGenerator(password, + digestCalculatorProvider.get(HashAlgorithmTags.SHA256)); + encGen.addMethod(encMethodGen); + OutputStream encOut = encGen.open(ciphertextOut, new byte[1 << 9]); + encOut.flush(); + PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator(); + OutputStream litOut = litGen.open(encOut, PGPLiteralData.UTF8, "", new Date(), new byte[1 << 9]); + + litOut.write(plaintext); + litOut.flush(); + litOut.close(); + + encOut.flush(); + encOut.close(); + + ByteArrayOutputStream armoredMsg = new ByteArrayOutputStream(); + ArmoredOutputStream armorOut = new ArmoredOutputStream(armoredMsg); + armorOut.write(ciphertextOut.toByteArray()); + armorOut.flush(); + armorOut.close(); + + printHex(ciphertextOut.toByteArray()); + + String armored = armoredMsg.toString(); + return armored; + } + + private String testJceEncryption(boolean v5AEAD, int aeadAlg, int symAlg, byte[] plaintext, char[] password) + throws PGPException, IOException + { + BouncyCastleProvider provider = new BouncyCastleProvider(); + Security.addProvider(provider); + ByteArrayOutputStream ciphertextOut = new ByteArrayOutputStream(); + PGPDigestCalculatorProvider digestCalculatorProvider = new JcaPGPDigestCalculatorProviderBuilder() + .setProvider(provider).build(); + PGPDataEncryptorBuilder encBuilder = new JcePGPDataEncryptorBuilder(symAlg); + if (v5AEAD) + { + encBuilder.setUseV5AEAD(); + } + else + { + encBuilder.setUseV6AEAD(); + } + encBuilder.setWithAEAD(aeadAlg, 6); + PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encBuilder, false); + encGen.setForceSessionKey(true); + PBEKeyEncryptionMethodGenerator encMethodGen = new JcePBEKeyEncryptionMethodGenerator(password, + digestCalculatorProvider.get(HashAlgorithmTags.SHA256)); + encGen.addMethod(encMethodGen); + OutputStream encOut = encGen.open(ciphertextOut, new byte[1 << 9]); + encOut.flush(); + PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator(); + OutputStream litOut = litGen.open(encOut, PGPLiteralData.UTF8, "", new Date(), new byte[1 << 9]); + + litOut.write(plaintext); + litOut.flush(); + litOut.close(); + + encOut.flush(); + encOut.close(); + + ByteArrayOutputStream armoredMsg = new ByteArrayOutputStream(); + ArmoredOutputStream armorOut = new ArmoredOutputStream(armoredMsg); + armorOut.write(ciphertextOut.toByteArray()); + armorOut.flush(); + armorOut.close(); + + printHex(ciphertextOut.toByteArray()); + + String armored = armoredMsg.toString(); + return armored; + } private void testBcDecryption(String armoredMessage, char[] password, byte[] expectedPlaintext) throws IOException @@ -308,7 +360,6 @@ private void testBcDecryption(String armoredMessage, char[] password, byte[] exp o = objectFactory.nextObject(); if (o instanceof PGPPadding) { - System.err.println("hrer"); o = objectFactory.nextObject(); } @@ -486,6 +537,67 @@ private void testPaddingPacketEncoding() isTrue(Arrays.areEqual(packet.getPadding(), padding.getPadding())); } + private void preferredAEADAlgorithmsTests() + throws IOException + { + preferredAEADAlgorithmsImplicitlySupportAES128OCB(); + preferredAEADAlgorithmsRoundtrip(); + preferredAEADAlgorithmsInvalidConstructor(); + } + + private void preferredAEADAlgorithmsImplicitlySupportAES128OCB() + { + PreferredAEADCiphersuites.Combination implicit = new PreferredAEADCiphersuites.Combination( + SymmetricKeyAlgorithmTags.AES_128, AEADAlgorithmTags.OCB); + + PreferredAEADCiphersuites preferences = new PreferredAEADCiphersuites(false, + new PreferredAEADCiphersuites.Combination[0]); + + isTrue(preferences.isSupported(implicit)); + isTrue(Arrays.areEqual(new PreferredAEADCiphersuites.Combination[0], preferences.getRawAlgorithms())); + isTrue(Arrays.areEqual(new PreferredAEADCiphersuites.Combination[]{implicit}, preferences.getAlgorithms())); + } + + private void preferredAEADAlgorithmsRoundtrip() + throws IOException + { + PreferredAEADCiphersuites preferences = new PreferredAEADCiphersuites(false, new PreferredAEADCiphersuites.Combination[] + { + new PreferredAEADCiphersuites.Combination(SymmetricKeyAlgorithmTags.AES_256, AEADAlgorithmTags.OCB), + new PreferredAEADCiphersuites.Combination(SymmetricKeyAlgorithmTags.AES_256, AEADAlgorithmTags.GCM), + new PreferredAEADCiphersuites.Combination(SymmetricKeyAlgorithmTags.CAMELLIA_256, AEADAlgorithmTags.OCB) + }); + isTrue(Arrays.areEqual(new byte[]{0x09, 0x02, 0x09, 0x03, 0x0d, 0x02}, preferences.getData())); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + BCPGOutputStream bcpgOut = new BCPGOutputStream(bOut); + + preferences.encode(bcpgOut); + + ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); + SignatureSubpacketInputStream subpacketIn = new SignatureSubpacketInputStream(bIn); + SignatureSubpacket subpacket = subpacketIn.readPacket(); + assert subpacket != null; + assert subpacket instanceof PreferredAEADCiphersuites; + + PreferredAEADCiphersuites parsed = (PreferredAEADCiphersuites)subpacket; + isTrue(Arrays.areEqual(preferences.getRawAlgorithms(), parsed.getRawAlgorithms())); + } + + private void preferredAEADAlgorithmsInvalidConstructor() + { + // odd number of data bytes + try + { + new PreferredAEADCiphersuites(false, false, new byte[]{0x09, 0x02, 0x09}); + fail("Odd number of data bytes must throw."); + } + catch (IllegalArgumentException e) + { + // expected + } + } + public static void main(String[] args) { runTest(new PGPAeadTest()); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPClearSignedSignatureTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPClearSignedSignatureTest.java index d9df698ca0..ede5ecdb15 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPClearSignedSignatureTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPClearSignedSignatureTest.java @@ -40,156 +40,156 @@ import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; -public class PGPClearSignedSignatureTest +public class PGPClearSignedSignatureTest extends SimpleTest -{ +{ byte[] publicKey = Base64.decode( - "mQELBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+" - + "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1" - + "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO" - + "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7" - + "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4" - + "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp" - + "tBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2BBMBAgAgBQJEIdvsAhsDBgsJCAcD" - + "AgQVAggDBBYCAwECHgECF4AACgkQ4M/Ier3f9xagdAf/fbKWBjLQM8xR7JkR" - + "P4ri8YKOQPhK+VrddGUD59/wzVnvaGyl9MZE7TXFUeniQq5iXKnm22EQbYch" - + "v2Jcxyt2H9yptpzyh4tP6tEHl1C887p2J4qe7F2ATua9CzVGwXQSUbKtj2fg" - + "UZP5SsNp25guhPiZdtkf2sHMeiotmykFErzqGMrvOAUThrO63GiYsRk4hF6r" - + "cQ01d+EUVpY/sBcCxgNyOiB7a84sDtrxnX5BTEZDTEj8LvuEyEV3TMUuAjx1" - + "7Eyd+9JtKzwV4v3hlTaWOvGro9nPS7YaPuG+RtufzXCUJPbPfTjTvtGOqvEz" - + "oztls8tuWA0OGHba9XfX9rfgorACAAM="); + "mQELBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+" + + "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1" + + "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO" + + "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7" + + "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4" + + "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp" + + "tBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2BBMBAgAgBQJEIdvsAhsDBgsJCAcD" + + "AgQVAggDBBYCAwECHgECF4AACgkQ4M/Ier3f9xagdAf/fbKWBjLQM8xR7JkR" + + "P4ri8YKOQPhK+VrddGUD59/wzVnvaGyl9MZE7TXFUeniQq5iXKnm22EQbYch" + + "v2Jcxyt2H9yptpzyh4tP6tEHl1C887p2J4qe7F2ATua9CzVGwXQSUbKtj2fg" + + "UZP5SsNp25guhPiZdtkf2sHMeiotmykFErzqGMrvOAUThrO63GiYsRk4hF6r" + + "cQ01d+EUVpY/sBcCxgNyOiB7a84sDtrxnX5BTEZDTEj8LvuEyEV3TMUuAjx1" + + "7Eyd+9JtKzwV4v3hlTaWOvGro9nPS7YaPuG+RtufzXCUJPbPfTjTvtGOqvEz" + + "oztls8tuWA0OGHba9XfX9rfgorACAAM="); byte[] secretKey = Base64.decode( - "lQOWBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+" - + "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1" - + "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO" - + "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7" - + "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4" - + "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp" - + "AAf+JCJJeAXEcrTVHotsrRR5idzmg6RK/1MSQUijwPmP7ZGy1BmpAmYUfbxn" - + "B56GvXyFV3Pbj9PgyJZGS7cY+l0BF4ZqN9USiQtC9OEpCVT5LVMCFXC/lahC" - + "/O3EkjQy0CYK+GwyIXa+Flxcr460L/Hvw2ZEXJZ6/aPdiR+DU1l5h99Zw8V1" - + "Y625MpfwN6ufJfqE0HLoqIjlqCfi1iwcKAK2oVx2SwnT1W0NwUUXjagGhD2s" - + "VzJVpLqhlwmS0A+RE9Niqrf80/zwE7QNDF2DtHxmMHJ3RY/pfu5u1rrFg9YE" - + "lmS60mzOe31CaD8Li0k5YCJBPnmvM9mN3/DWWprSZZKtmQQA96C2/VJF5EWm" - + "+/Yxi5J06dG6Bkz311Ui4p2zHm9/4GvTPCIKNpGx9Zn47YFD3tIg3fIBVPOE" - + "ktG38pEPx++dSSFF9Ep5UgmYFNOKNUVq3yGpatBtCQBXb1LQLAMBJCJ5TQmk" - + "68hMOEaqjMHSOa18cS63INgA6okb/ueAKIHxYQcEAP9DaXu5n9dZQw7pshbN" - + "Nu/T5IP0/D/wqM+W5r+j4P1N7PgiAnfKA4JjKrUgl8PGnI2qM/Qu+g3qK++c" - + "F1ESHasnJPjvNvY+cfti06xnJVtCB/EBOA2UZkAr//Tqa76xEwYAWRBnO2Y+" - + "KIVOT+nMiBFkjPTrNAD6fSr1O4aOueBhBAC6aA35IfjC2h5MYk8+Z+S4io2o" - + "mRxUZ/dUuS+kITvWph2e4DT28Xpycpl2n1Pa5dCDO1lRqe/5JnaDYDKqxfmF" - + "5tTG8GR4d4nVawwLlifXH5Ll7t5NcukGNMCsGuQAHMy0QHuAaOvMdLs5kGHn" - + "8VxfKEVKhVrXsvJSwyXXSBtMtUcRtBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2" - + "BBMBAgAgBQJEIdvsAhsDBgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQ4M/I" - + "er3f9xagdAf/fbKWBjLQM8xR7JkRP4ri8YKOQPhK+VrddGUD59/wzVnvaGyl" - + "9MZE7TXFUeniQq5iXKnm22EQbYchv2Jcxyt2H9yptpzyh4tP6tEHl1C887p2" - + "J4qe7F2ATua9CzVGwXQSUbKtj2fgUZP5SsNp25guhPiZdtkf2sHMeiotmykF" - + "ErzqGMrvOAUThrO63GiYsRk4hF6rcQ01d+EUVpY/sBcCxgNyOiB7a84sDtrx" - + "nX5BTEZDTEj8LvuEyEV3TMUuAjx17Eyd+9JtKzwV4v3hlTaWOvGro9nPS7Ya" - + "PuG+RtufzXCUJPbPfTjTvtGOqvEzoztls8tuWA0OGHba9XfX9rfgorACAAA="); + "lQOWBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+" + + "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1" + + "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO" + + "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7" + + "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4" + + "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp" + + "AAf+JCJJeAXEcrTVHotsrRR5idzmg6RK/1MSQUijwPmP7ZGy1BmpAmYUfbxn" + + "B56GvXyFV3Pbj9PgyJZGS7cY+l0BF4ZqN9USiQtC9OEpCVT5LVMCFXC/lahC" + + "/O3EkjQy0CYK+GwyIXa+Flxcr460L/Hvw2ZEXJZ6/aPdiR+DU1l5h99Zw8V1" + + "Y625MpfwN6ufJfqE0HLoqIjlqCfi1iwcKAK2oVx2SwnT1W0NwUUXjagGhD2s" + + "VzJVpLqhlwmS0A+RE9Niqrf80/zwE7QNDF2DtHxmMHJ3RY/pfu5u1rrFg9YE" + + "lmS60mzOe31CaD8Li0k5YCJBPnmvM9mN3/DWWprSZZKtmQQA96C2/VJF5EWm" + + "+/Yxi5J06dG6Bkz311Ui4p2zHm9/4GvTPCIKNpGx9Zn47YFD3tIg3fIBVPOE" + + "ktG38pEPx++dSSFF9Ep5UgmYFNOKNUVq3yGpatBtCQBXb1LQLAMBJCJ5TQmk" + + "68hMOEaqjMHSOa18cS63INgA6okb/ueAKIHxYQcEAP9DaXu5n9dZQw7pshbN" + + "Nu/T5IP0/D/wqM+W5r+j4P1N7PgiAnfKA4JjKrUgl8PGnI2qM/Qu+g3qK++c" + + "F1ESHasnJPjvNvY+cfti06xnJVtCB/EBOA2UZkAr//Tqa76xEwYAWRBnO2Y+" + + "KIVOT+nMiBFkjPTrNAD6fSr1O4aOueBhBAC6aA35IfjC2h5MYk8+Z+S4io2o" + + "mRxUZ/dUuS+kITvWph2e4DT28Xpycpl2n1Pa5dCDO1lRqe/5JnaDYDKqxfmF" + + "5tTG8GR4d4nVawwLlifXH5Ll7t5NcukGNMCsGuQAHMy0QHuAaOvMdLs5kGHn" + + "8VxfKEVKhVrXsvJSwyXXSBtMtUcRtBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2" + + "BBMBAgAgBQJEIdvsAhsDBgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQ4M/I" + + "er3f9xagdAf/fbKWBjLQM8xR7JkRP4ri8YKOQPhK+VrddGUD59/wzVnvaGyl" + + "9MZE7TXFUeniQq5iXKnm22EQbYchv2Jcxyt2H9yptpzyh4tP6tEHl1C887p2" + + "J4qe7F2ATua9CzVGwXQSUbKtj2fgUZP5SsNp25guhPiZdtkf2sHMeiotmykF" + + "ErzqGMrvOAUThrO63GiYsRk4hF6rcQ01d+EUVpY/sBcCxgNyOiB7a84sDtrx" + + "nX5BTEZDTEj8LvuEyEV3TMUuAjx17Eyd+9JtKzwV4v3hlTaWOvGro9nPS7Ya" + + "PuG+RtufzXCUJPbPfTjTvtGOqvEzoztls8tuWA0OGHba9XfX9rfgorACAAA="); String crOnlyMessage = "\r" - + " hello world!\r" - + "\r" - + "- dash\r"; - + + " hello world!\r" + + "\r" + + "- dash\r"; + String nlOnlyMessage = - "\n" - + " hello world!\n" - + "\n" - + "- dash\n"; - + "\n" + + " hello world!\n" + + "\n" + + "- dash\n"; + String crNlMessage = - "\r\n" - + " hello world!\r\n" - + "\r\n" - + "- dash\r\n"; - - String crOnlySignedMessage = + "\r\n" + + " hello world!\r\n" + + "\r\n" + + "- dash\r\n"; + + static String crOnlySignedMessage = "-----BEGIN PGP SIGNED MESSAGE-----\r" - + "Hash: SHA256\r" - + "\r" - + "\r" - + " hello world!\r" - + "\r" - + "- - dash\r" - + "-----BEGIN PGP SIGNATURE-----\r" - + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r" - + "\r" - + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r" - + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r" - + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r" - + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r" - + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r" - + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r" - + "=84Nd\r" - + "-----END PGP SIGNATURE-----\r"; + + "Hash: SHA256\r" + + "\r" + + "\r" + + " hello world!\r" + + "\r" + + "- - dash\r" + + "-----BEGIN PGP SIGNATURE-----\r" + + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r" + + "\r" + + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r" + + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r" + + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r" + + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r" + + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r" + + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r" + + "=84Nd\r" + + "-----END PGP SIGNATURE-----\r"; String nlOnlySignedMessage = - "-----BEGIN PGP SIGNED MESSAGE-----\n" - + "Hash: SHA256\n" - + "\n" - + "\n" - + " hello world!\n" - + "\n" - + "- - dash\n" - + "-----BEGIN PGP SIGNATURE-----\n" - + "Version: GnuPG v1.4.2.1 (GNU/Linux)\n" - + "\n" - + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\n" - + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\n" - + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\n" - + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\n" - + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\n" - + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\n" - + "=84Nd\n" - + "-----END PGP SIGNATURE-----\n"; - + "-----BEGIN PGP SIGNED MESSAGE-----\n" + + "Hash: SHA256\n" + + "\n" + + "\n" + + " hello world!\n" + + "\n" + + "- - dash\n" + + "-----BEGIN PGP SIGNATURE-----\n" + + "Version: GnuPG v1.4.2.1 (GNU/Linux)\n" + + "\n" + + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\n" + + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\n" + + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\n" + + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\n" + + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\n" + + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\n" + + "=84Nd\n" + + "-----END PGP SIGNATURE-----\n"; + String crNlSignedMessage = "-----BEGIN PGP SIGNED MESSAGE-----\r\n" - + "Hash: SHA256\r\n" - + "\r\n" - + "\r\n" - + " hello world!\r\n" - + "\r\n" - + "- - dash\r\n" - + "-----BEGIN PGP SIGNATURE-----\r\n" - + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n" - + "\r\n" - + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n" - + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n" - + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n" - + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n" - + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n" - + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n" - + "=84Nd\r" - + "-----END PGP SIGNATURE-----\r\n"; + + "Hash: SHA256\r\n" + + "\r\n" + + "\r\n" + + " hello world!\r\n" + + "\r\n" + + "- - dash\r\n" + + "-----BEGIN PGP SIGNATURE-----\r\n" + + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n" + + "\r\n" + + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n" + + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n" + + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n" + + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n" + + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n" + + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n" + + "=84Nd\r" + + "-----END PGP SIGNATURE-----\r\n"; String crNlSignedMessageTrailingWhiteSpace = "-----BEGIN PGP SIGNED MESSAGE-----\r\n" - + "Hash: SHA256\r\n" - + "\r\n" - + "\r\n" - + " hello world! \t\r\n" - + "\r\n" - + "- - dash\r\n" - + "-----BEGIN PGP SIGNATURE-----\r\n" - + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n" - + "\r\n" - + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n" - + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n" - + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n" - + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n" - + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n" - + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n" - + "=84Nd\r" - + "-----END PGP SIGNATURE-----\r\n"; + + "Hash: SHA256\r\n" + + "\r\n" + + "\r\n" + + " hello world! \t\r\n" + + "\r\n" + + "- - dash\r\n" + + "-----BEGIN PGP SIGNATURE-----\r\n" + + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n" + + "\r\n" + + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n" + + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n" + + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n" + + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n" + + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n" + + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n" + + "=84Nd\r" + + "-----END PGP SIGNATURE-----\r\n"; final String edDsaSignedMessage = - "-----BEGIN PGP SIGNED MESSAGE-----\n" + + "-----BEGIN PGP SIGNED MESSAGE-----\n" + "Hash: SHA256\n" + "\n" + "person: First Person\n" + @@ -210,20 +210,20 @@ public class PGPClearSignedSignatureTest "-----END PGP SIGNATURE-----"; final String edDsaPublicKey = - "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + - "Comment: GPGTools - http://gpgtools.org\n" + - "\n" + - "mDMEXiWeSRYJKwYBBAHaRw8BAQdAEo+4wi/WI0xtbQF+PoIGxaDFJw23d+3w/ov+\n" + - "go85qdi0GVRlc3QgVXNlciA8dGVzdEByaXBlLm5ldD6IkAQTFggAOBYhBGI0Y1DK\n" + - "4kM+JAAdcpT6YsNkga40BQJeJZ5JAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheA\n" + - "AAoJEJT6YsNkga40WLEBAKGMQaC1zKbmuD5Pav0ssuhxaznoMbuZqJ45VNiGKzLE\n" + - "AQCGFbH+9pAvcEuorOa180+GLDZOpVYgQy40KsGaQgC5Drg4BF4lnkkSCisGAQQB\n" + - "l1UBBQEBB0DFLFEhV9RSM92t1LwC/ClmND/Yw9P0a3paC2XGzTNTAwMBCAeIeAQY\n" + - "FggAIBYhBGI0Y1DK4kM+JAAdcpT6YsNkga40BQJeJZ5JAhsMAAoJEJT6YsNkga40\n" + - "LbQBALZ5BaNX5OxdS++mzwdWAVLZXAPRDFr6Q2otdxbnR0FTAP4ok4PiOpe1BfdF\n" + - "itv84V9zda3NL6zJLhR3kewd30UDCA==\n" + - "=Dxc9\n" + - "-----END PGP PUBLIC KEY BLOCK-----\n"; + "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + + "Comment: GPGTools - http://gpgtools.org\n" + + "\n" + + "mDMEXiWeSRYJKwYBBAHaRw8BAQdAEo+4wi/WI0xtbQF+PoIGxaDFJw23d+3w/ov+\n" + + "go85qdi0GVRlc3QgVXNlciA8dGVzdEByaXBlLm5ldD6IkAQTFggAOBYhBGI0Y1DK\n" + + "4kM+JAAdcpT6YsNkga40BQJeJZ5JAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheA\n" + + "AAoJEJT6YsNkga40WLEBAKGMQaC1zKbmuD5Pav0ssuhxaznoMbuZqJ45VNiGKzLE\n" + + "AQCGFbH+9pAvcEuorOa180+GLDZOpVYgQy40KsGaQgC5Drg4BF4lnkkSCisGAQQB\n" + + "l1UBBQEBB0DFLFEhV9RSM92t1LwC/ClmND/Yw9P0a3paC2XGzTNTAwMBCAeIeAQY\n" + + "FggAIBYhBGI0Y1DK4kM+JAAdcpT6YsNkga40BQJeJZ5JAhsMAAoJEJT6YsNkga40\n" + + "LbQBALZ5BaNX5OxdS++mzwdWAVLZXAPRDFr6Q2otdxbnR0FTAP4ok4PiOpe1BfdF\n" + + "itv84V9zda3NL6zJLhR3kewd30UDCA==\n" + + "=Dxc9\n" + + "-----END PGP PUBLIC KEY BLOCK-----\n"; public String getName() { @@ -238,22 +238,22 @@ private void messageTest( ArmoredInputStream aIn = new ArmoredInputStream(new ByteArrayInputStream(message.getBytes())); String[] headers = aIn.getArmorHeaders(); - + if (headers == null || headers.length != 1) { fail("wrong number of headers found"); } - + if (!"Hash: SHA256".equals(headers[0])) { fail("header value wrong: " + headers[0]); } - + // // read the input, making sure we ingore the last newline. // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - int ch; + int ch; while ((ch = aIn.read()) >= 0 && aIn.isClearText()) { @@ -262,14 +262,14 @@ private void messageTest( PGPPublicKeyRingCollection pgpRings = new PGPPublicKeyRingCollection(publicKey, new JcaKeyFingerprintCalculator()); - JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(aIn); - PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); - PGPSignature sig = p3.get(0); - + JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(aIn); + PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); + PGPSignature sig = p3.get(0); + sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), pgpRings.getPublicKey(sig.getKeyID())); ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); - InputStream sigIn = new ByteArrayInputStream(bOut.toByteArray()); + InputStream sigIn = new ByteArrayInputStream(bOut.toByteArray()); int lookAhead = readInputLine(lineOut, sigIn); processLine(sig, lineOut.toByteArray()); @@ -292,15 +292,16 @@ private void messageTest( { fail("signature failed to verify in " + type); } + isTrue(!aIn.isEndOfStream()); } - + private PGPSecretKey readSecretKey( - InputStream in) + InputStream in) throws IOException, PGPException { - PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(in, new JcaKeyFingerprintCalculator()); + PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(in, new JcaKeyFingerprintCalculator()); - PGPSecretKey key = null; + PGPSecretKey key = null; // // iterate through the key rings. @@ -309,25 +310,25 @@ private PGPSecretKey readSecretKey( while (key == null && rIt.hasNext()) { - PGPSecretKeyRing kRing = (PGPSecretKeyRing)rIt.next(); - Iterator kIt = kRing.getSecretKeys(); - + PGPSecretKeyRing kRing = (PGPSecretKeyRing)rIt.next(); + Iterator kIt = kRing.getSecretKeys(); + while (key == null && kIt.hasNext()) { - PGPSecretKey k = (PGPSecretKey)kIt.next(); - + PGPSecretKey k = (PGPSecretKey)kIt.next(); + if (k.isSigningKey()) { key = k; } } } - + if (key == null) { throw new IllegalArgumentException("Can't find signing key in key ring."); } - + return key; } @@ -336,23 +337,23 @@ private void generateTest( String type) throws Exception { - PGPSecretKey pgpSecKey = readSecretKey(new ByteArrayInputStream(secretKey)); - PGPPrivateKey pgpPrivKey = pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build("".toCharArray())); - PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(pgpSecKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256).setProvider("BC")); - PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); + PGPSecretKey pgpSecKey = readSecretKey(new ByteArrayInputStream(secretKey)); + PGPPrivateKey pgpPrivKey = pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build("".toCharArray())); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(pgpSecKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256).setProvider("BC")); + PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); sGen.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, pgpPrivKey); - Iterator it = pgpSecKey.getPublicKey().getUserIDs(); + Iterator it = pgpSecKey.getPublicKey().getUserIDs(); if (it.hasNext()) { spGen.setSignerUserID(false, (String)it.next()); sGen.setHashedSubpackets(spGen.generate()); } - - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - ArmoredOutputStream aOut = new ArmoredOutputStream(bOut); - ByteArrayInputStream bIn = new ByteArrayInputStream(message.getBytes()); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ArmoredOutputStream aOut = new ArmoredOutputStream(bOut); + ByteArrayInputStream bIn = new ByteArrayInputStream(message.getBytes()); aOut.beginClearText(PGPUtil.SHA256); @@ -380,18 +381,18 @@ private void generateTest( aOut.endClearText(); - BCPGOutputStream bcpgOut = new BCPGOutputStream(aOut); + BCPGOutputStream bcpgOut = new BCPGOutputStream(aOut); sGen.generate().encode(bcpgOut); aOut.close(); - + messageTest(new String(bOut.toByteArray()), type); } private static int getLengthWithoutSeparatorOrTrailingWhitespace(byte[] line) { - int end = line.length - 1; + int end = line.length - 1; while (end >= 0 && isWhiteSpace(line[end])) { @@ -408,14 +409,15 @@ private void edDsaTest() PGPPublicKeyRing pubKeyRing = new PGPPublicKeyRing(aIn, new JcaKeyFingerprintCalculator()); - isTrue(areEqual(Hex.decode("6234 6350 CAE2 433E 2400 1D72 94FA 62C3 6481 AE34"), pubKeyRing.getPublicKey().getFingerprint())); + isTrue(areEqual(pubKeyRing.getPublicKey().getFingerprint(), Hex.decode("6234 6350 CAE2 433E 2400 1D72 94FA 62C3 6481 AE34"))); + isTrue(pubKeyRing.getPublicKey().hasFingerprint(Hex.decode("6234 6350 CAE2 433E 2400 1D72 94FA 62C3 6481 AE34"))); aIn = new ArmoredInputStream(new ByteArrayInputStream(Strings.toByteArray(edDsaSignedMessage))); ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); - int lookAhead = readInputLine(lineOut, aIn); - byte[] lineSep = Strings.toByteArray("\n"); + int lookAhead = readInputLine(lineOut, aIn); + byte[] lineSep = Strings.toByteArray("\n"); if (lookAhead != -1 && aIn.isClearText()) { @@ -433,9 +435,9 @@ private void edDsaTest() } } - JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(aIn); - PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); - PGPSignature sig = p3.get(0); + JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(aIn); + PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); + PGPSignature sig = p3.get(0); PGPPublicKey publicKey = pubKeyRing.getPublicKey(sig.getKeyID()); sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey); @@ -472,14 +474,15 @@ private void edDsaBcTest() PGPPublicKeyRing pubKeyRing = new PGPPublicKeyRing(aIn, new BcKeyFingerprintCalculator()); - isTrue(areEqual(Hex.decode("6234 6350 CAE2 433E 2400 1D72 94FA 62C3 6481 AE34"), pubKeyRing.getPublicKey().getFingerprint())); + isTrue(areEqual(pubKeyRing.getPublicKey().getFingerprint(), Hex.decode("6234 6350 CAE2 433E 2400 1D72 94FA 62C3 6481 AE34"))); + isTrue(pubKeyRing.getPublicKey().hasFingerprint(Hex.decode("6234 6350 CAE2 433E 2400 1D72 94FA 62C3 6481 AE34"))); aIn = new ArmoredInputStream(new ByteArrayInputStream(Strings.toByteArray(edDsaSignedMessage))); ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); - int lookAhead = readInputLine(lineOut, aIn); - byte[] lineSep = Strings.toByteArray("\n"); + int lookAhead = readInputLine(lineOut, aIn); + byte[] lineSep = Strings.toByteArray("\n"); if (lookAhead != -1 && aIn.isClearText()) { @@ -497,9 +500,9 @@ private void edDsaBcTest() } } - BcPGPObjectFactory pgpFact = new BcPGPObjectFactory(aIn); - PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); - PGPSignature sig = p3.get(0); + BcPGPObjectFactory pgpFact = new BcPGPObjectFactory(aIn); + PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); + PGPSignature sig = p3.get(0); PGPPublicKey publicKey = pubKeyRing.getPublicKey(sig.getKeyID()); sig.init(new BcPGPContentVerifierBuilderProvider(), publicKey); @@ -609,7 +612,7 @@ private static void processLine(OutputStream aOut, PGPSignatureGenerator sGen, b private static int getLengthWithoutWhiteSpace(byte[] line) { - int end = line.length - 1; + int end = line.length - 1; while (end >= 0 && isWhiteSpace(line[end])) { @@ -619,6 +622,57 @@ private static int getLengthWithoutWhiteSpace(byte[] line) return end + 1; } + private void testExceptions() + throws IOException + { + final ArmoredInputStream aIn = new ArmoredInputStream(new ByteArrayInputStream(crOnlySignedMessage.getBytes())); + + testException("Offset and length cannot be negative.", "IndexOutOfBoundsException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + aIn.read(new byte[15], -1, -1); + } + }); + testException("Invalid offset and length.", "IndexOutOfBoundsException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + aIn.read(new byte[15], 2, 15); + } + }); + testException("invalid armor header", "ArmoredInputException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + String message = + "-----BEGIN PGP SIGNED MESSAGE-----\r" + + "-----BEGIN PGP SIGNED MESSAGE-----\r" + + "\r"; + ArmoredInputStream in = new ArmoredInputStream(new ByteArrayInputStream(message.getBytes())); + } + }); + testException("inconsistent line endings in headers", "ArmoredInputException", new TestExceptionOperation() + { + @Override + public void operation() + throws Exception + { + String message = + "-----BEGIN PGP SIGNED MESSAGE-----\r\n" + + "Hash: SHA256\r\n" + + "\r\r"; + ArmoredInputStream in = new ArmoredInputStream(new ByteArrayInputStream(message.getBytes())); + } + }); + } + private static boolean isWhiteSpace(byte b) { return b == '\r' || b == '\n' || b == '\t' || b == ' '; @@ -627,6 +681,7 @@ private static boolean isWhiteSpace(byte b) public void performTest() throws Exception { + testExceptions(); messageTest(crOnlySignedMessage, "\\r"); messageTest(nlOnlySignedMessage, "\\n"); messageTest(crNlSignedMessage, "\\r\\n"); @@ -638,13 +693,14 @@ public void performTest() edDsaTest(); edDsaBcTest(); + } - + public static void main( - String[] args) + String[] args) { Security.addProvider(new BouncyCastleProvider()); - + runTest(new PGPClearSignedSignatureTest()); } } diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPDSAElGamalTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPDSAElGamalTest.java index 0d50d7b01b..31a0ff1909 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPDSAElGamalTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPDSAElGamalTest.java @@ -302,7 +302,7 @@ public void performTest() PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); - InputStream clear = encP.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(pgpPrivKey)); + InputStream clear = encP.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider(new BouncyCastleProvider()).build(pgpPrivKey)); pgpFact = new JcaPGPObjectFactory(clear); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPEdDSATest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPEdDSATest.java index 317998da51..3864c5b614 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPEdDSATest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPEdDSATest.java @@ -67,7 +67,7 @@ public class PGPEdDSATest extends SimpleTest { - private static final String edDSASampleKey = + static final String edDSASampleKey = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + "Comment: Alice's OpenPGP certificate\n" + "Comment: https://www.ietf.org/id/draft-bre-openpgp-samples-01.html\n" + @@ -84,7 +84,7 @@ public class PGPEdDSATest "=iIGO\n" + "-----END PGP PUBLIC KEY BLOCK-----\n"; - private static final String edDSASecretKey = + static final String edDSASecretKey = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + "Comment: Alice's OpenPGP Transferable Secret Key\n" + "Comment: https://www.ietf.org/id/draft-bre-openpgp-samples-01.html\n" + @@ -412,7 +412,8 @@ public void performTest() PGPPublicKeyRing pubKeyRing = new PGPPublicKeyRing(aIn, new JcaKeyFingerprintCalculator()); - isTrue(areEqual(Hex.decode("EB85 BB5F A33A 75E1 5E94 4E63 F231 550C 4F47 E38E"), pubKeyRing.getPublicKey().getFingerprint())); + isTrue(areEqual(pubKeyRing.getPublicKey().getFingerprint(), Hex.decode("EB85 BB5F A33A 75E1 5E94 4E63 F231 550C 4F47 E38E"))); + isTrue(pubKeyRing.getPublicKey().hasFingerprint(Hex.decode("EB85 BB5F A33A 75E1 5E94 4E63 F231 550C 4F47 E38E"))); aIn = new ArmoredInputStream(new ByteArrayInputStream(Strings.toByteArray(edDSASecretKey))); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPEncryptedDataTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPEncryptedDataTest.java index 752144674d..b364baa70f 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPEncryptedDataTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPEncryptedDataTest.java @@ -70,6 +70,7 @@ private void encryptDecryptTest() ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); JcePGPDataEncryptorBuilder encryptorBuilder = new JcePGPDataEncryptorBuilder(PGPEncryptedData.AES_128).setSecureRandom(new SecureRandom()).setProvider("BC"); + encryptorBuilder.setUseV5AEAD(); encryptorBuilder.setWithAEAD(AEADAlgorithmTags.OCB, 10); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); @@ -135,6 +136,7 @@ private void encryptDecryptMultiChunkTest() ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); JcePGPDataEncryptorBuilder encryptorBuilder = new JcePGPDataEncryptorBuilder(PGPEncryptedData.AES_128).setSecureRandom(random).setProvider("BC"); + encryptorBuilder.setUseV5AEAD(); encryptorBuilder.setWithAEAD(AEADAlgorithmTags.OCB, 6); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); @@ -201,6 +203,7 @@ private void encryptDecryptMultiChunkBoundaryTest() ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); JcePGPDataEncryptorBuilder encryptorBuilder = new JcePGPDataEncryptorBuilder(PGPEncryptedData.AES_128).setSecureRandom(random).setProvider("BC"); + encryptorBuilder.setUseV5AEAD(); encryptorBuilder.setWithAEAD(AEADAlgorithmTags.OCB, 6); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPGeneralTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPGeneralTest.java new file mode 100644 index 0000000000..9714f78eb1 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPGeneralTest.java @@ -0,0 +1,3231 @@ +package org.bouncycastle.openpgp.test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.SecureRandom; +import java.security.Security; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Collection; + +import org.bouncycastle.bcpg.AEADAlgorithmTags; +import org.bouncycastle.bcpg.ArmoredInputStream; +import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.bcpg.DSAPublicBCPGKey; +import org.bouncycastle.bcpg.DSASecretBCPGKey; +import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; +import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.bcpg.RSAPublicBCPGKey; +import org.bouncycastle.bcpg.RSASecretBCPGKey; +import org.bouncycastle.bcpg.SignatureSubpacket; +import org.bouncycastle.bcpg.SignatureSubpacketTags; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.attr.ImageAttribute; +import org.bouncycastle.bcpg.sig.Features; +import org.bouncycastle.bcpg.sig.IntendedRecipientFingerprint; +import org.bouncycastle.bcpg.sig.KeyFlags; +import org.bouncycastle.bcpg.sig.NotationData; +import org.bouncycastle.bcpg.sig.PolicyURI; +import org.bouncycastle.bcpg.sig.RegularExpression; +import org.bouncycastle.bcpg.sig.RevocationKey; +import org.bouncycastle.bcpg.sig.RevocationKeyTags; +import org.bouncycastle.bcpg.sig.RevocationReason; +import org.bouncycastle.bcpg.sig.RevocationReasonTags; +import org.bouncycastle.bcpg.sig.SignerUserID; +import org.bouncycastle.bcpg.sig.TrustSignature; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; +import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.crypto.params.ECPrivateKeyParameters; +import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; +import org.bouncycastle.gpg.PGPSecretKeyParser; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.bouncycastle.jce.spec.ElGamalParameterSpec; +import org.bouncycastle.openpgp.ExtendedPGPSecretKey; +import org.bouncycastle.openpgp.OpenedPGPKeyData; +import org.bouncycastle.openpgp.PGPCompressedData; +import org.bouncycastle.openpgp.PGPEncryptedData; +import org.bouncycastle.openpgp.PGPEncryptedDataList; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPKeyPair; +import org.bouncycastle.openpgp.PGPKeyRingGenerator; +import org.bouncycastle.openpgp.PGPLiteralData; +import org.bouncycastle.openpgp.PGPObjectFactory; +import org.bouncycastle.openpgp.PGPPrivateKey; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; +import org.bouncycastle.openpgp.PGPSecretKey; +import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.PGPSignatureGenerator; +import org.bouncycastle.openpgp.PGPSignatureList; +import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; +import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; +import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; +import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVectorGenerator; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.openpgp.bc.BcPGPPublicKeyRingCollection; +import org.bouncycastle.openpgp.bc.BcPGPSecretKeyRingCollection; +import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; +import org.bouncycastle.openpgp.jcajce.JcaPGPPublicKeyRing; +import org.bouncycastle.openpgp.jcajce.JcaPGPPublicKeyRingCollection; +import org.bouncycastle.openpgp.jcajce.JcaPGPSecretKeyRingCollection; +import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; +import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyEncryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.bouncycastle.openpgp.operator.jcajce.JcePBEProtectionRemoverFactory; +import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.test.SimpleTest; + + +public class PGPGeneralTest + extends SimpleTest +{ + private static final char[] v3KeyPass = "test@key.test".toCharArray(); + private static final byte[] privv3 = Base64.decode( + "lQOgAzroPPgAAAEIANnTx/gHfag7qRMG6cVUnYZJjLcsdF6JSaVs+PUDCZ8l2+Z2" + + "V9tgxByp26bymIlq5qFFeoA5vCiKc8qzYiEVLJVVIIDjw/id2gq/TgmxoLAwiDQM" + + "TUKdCFa6pmR/uaxyrnJxfUA7+Qh0R0OjoCxNlrmyO3eiKstsJGqSUFIQq7GhcHc4" + + "nbV59zHhEWnH7DX7sDa9CgF11WxM3sjWp15iOoP1nixhmchDtQ7foUxLsCF36G/4" + + "ijcbN2NjiCDYMFburN8fXgrQzYHAIIiVFE0J+fbXNfPRmnbhQdaC8rIdiQ3tExBb" + + "N0qWhGPT9M4JOZd1yPdFMb9gbntd8VZkiPd6/3sABREDXB5zk3GNdSkH/+/447Kq" + + "hR9uM+UnZz7wDkzmt+7xbNg9F2pr/tghVCM7D0PO1YjH4DBpU1ZRO+v1t/eBB/Jd" + + "3lJYdlWYHOefJkBi44gNAafZ8ysPOJk6OGOjas/sr+JRFiX9Mgzrs2IDiejmuA98" + + "DLuSuNtzFKbE2/DDdOBEizYUjqPLlCdn5sVEt+0WKWJiAv7YonCGguWS3RKfTaYk" + + "9IE9SbI+qph9JsuyTD22GLv+gTMvwCkC1DVaHIVgzURpdnlyYyz4DBh3pAgg0nh6" + + "gpUTsjnUmrvdh+r8qj3oXH7WBMhs6qKYvU1Go5iV3S1Cu4H/Z/+s6XUFgQShevVe" + + "VCy0QtmWSFeySekEACHLJIdBDa8K4dcM2wvccz587D4PtKvMG5j71raOcgVY+r1k" + + "e6au/fa0ACqLNvn6+vFHG+Rurn8RSKV31YmTpx7J5ixTOsB+wVcwTYbrw8uNlBWc" + + "+IkqPwHrtdK95GIYQykfPW95PRudsOBdxwQW4Ax/WCst3fbjo0SZww0Os+3WBADJ" + + "/Nv0mjikXRmqJIzfuI2yxxX4Wm6vqXJkPF7LGtSMB3VEJ3qPsysoai5TYboxA8C1" + + "4rQjIoQjA+87gxZ44PUVxrxBonITCLXJ3GsvDQ2PNhS6WQ9Cf89vtYW1vLW65Nex" + + "+7AuVRepKhx6Heqdf7S03m6UYliIglrEzgEWM1XrOwP/gLMsme4h0LjLgKfd0LBk" + + "qSMdu21VSl60TMTjxav149AdutzuCVa/yPBM/zLQdlvQoGYg2IbN4+7gDHKURcSx" + + "DgOAzCcEZxdMvRk2kaOI5RRf5gV9e+ErvEMzJ/xT8xWsi+aLOhaDMbwq2LLiK2L+" + + "tXV/Z3H/Ot4u3E7H+6fHPElFYbQUdGVzdCA8dGVzdEBrZXkudGVzdD4=" + ); + private static final byte[] probExpPubKey = Base64.decode( + "mQENBFj1Q70BCAC2ynacUueCmIUXxeYy1HIA92JAhgXrPcD5JkQiNlI779/f" + + "72gLzFDqeNCKLsatnjD3m0tNgPB8vSsg2Um2Np1zTyHRO6hyUZsxmwsMoDrm" + + "RCaJxBuLU6if1S7b9I8A8vIVOLrvUrw48Vh16GZO9eeTmqQ/oNRxN3kuZSVC" + + "ccQ9jgMJqvq3TUJpNeNWp/ibLdBFN6HoOw2Zf1jm+jvYntsocVD+ZtpfHQoO" + + "ZzA55hc7QO0LU3odtdy6sQHvTmZZGHZVYgg6joARY+HZuzm+63vn31ajI16g" + + "ZKKnAjyubQ+giZT05ApQgHpJ7hMXVXVzjxoiE1qapNZBU+K3CwNJWqdjABEB" + + "AAG0CXZhbGlkLWtleYkBPwQTAQgAKQUCWPVDvQIbAwUJAeEzgAcLCQgHAwIB" + + "BhUIAgkKCwQWAgMBAh4BAheAAAoJEBmVFZBmFliQwYUIAIz+PAYEQ2tDjOiq" + + "R6IG0V7zyQjthLcSxWbOEIF53FD3xBx3tAXScq88RlW/QY4d9en+cK3gpvrr" + + "/5aWomi7QoziZeUcMN7HtdqPgqk8DMcogIyS/geK8z4r6eDz3HQWDxAitRTw" + + "bbjFxahUHuetOh9nnTgsDTaimBRKVMLSUqqVYcgmPJLFaJSGRLMF7qHzN9hc" + + "jaiGLCLM9zVg74PnyORwmlnsM81uHzJ3uKueudGDKjMvgsMKODGMUzXArUKO" + + "PrDKKkrx82F5FHMIJ5Mn9fq57leJKzy1APnz7E8/ieqasTsBcC0L/6uJ+sS9" + + "Eca93q4mziqGvFx8cL5ZmlYx++ewAgADuQENBFj1Q70BCADFmn2DXY/G7K5G" + + "v5KLI8296e8q0iETX8516tXB5t0jWzxcsAHeMflsDR+TloXp4Ecznx3Pv8Q0" + + "4dkoo2MiSBiJ5adkwr/zLs+WWqwUjVw6m4ButTaFH/GaoKF+7HWg066NSd/u" + + "4JQaeAqsWqvTW4p3YRDm5GbXID0GsN7APtvUk9ShCeDXP9KZvNeTWFy2+iWd" + + "aYQBoRzTGPpjoboStZPDmLxuPXDbjQIXLys7k3Z0Shx/f5GMHnSyhVDNPlGQ" + + "+aCi2VL/PrwEVp4CCP5dQefNm1q95DCM2wdEQBeC3r3fGTTkBprZTWCwNPo6" + + "sCVaG/BbaFtFgilDUvMFEj5MP3FPABEBAAGJASUEGAEIAA8FAlj1Q70CGwwF" + + "CQHhM4AACgkQGZUVkGYWWJCQxwgAp/eIdOjWK9Tw9SOyFwi83nI92zWdnIxP" + + "KUroKQcXilH1nIyIykDSL2SLHK49c2Cw819MjWTwcUn7/OdZYc+X9ryteEFR" + + "Jge/Qw5CXvmRzhaCDtx6OU2U+/uHGMuvAOwpS1brmKaSN46LwHDHRMGn1+1D" + + "n4uXnFyc9lMDbja5c+b5vX3loulBwXO35ColrLx0Q585QusgMoGJwkr/8tx5" + + "jvLdI+T35e6f84gAlexGenvMDgobw32vaW8dXQQ0BKqNZKjXMy/0OGJs7G1X" + + "VhL+80K6K2UAu84JhBYFgoZQQ6cHtPn/WrSVN7RykSAKIOzvhqt8dFnjDHdH" + + "4xagReRrQbACAAOZAQ0EWPVHNwEIAKy/E/vob7FC+e+FX+W09pqNVMQXACxa" + + "7SCF51aFAMmncOJVS5BlyUjevaC77nXq5YXBvzZjYSN7nS6AOO/5BBXAH2/i" + + "bFBjrtqlLfH7sMqqly3gMWxXDOGw0FvH5DrlIiO8F4TciEXXOLHgMkC6RlBQ" + + "rj+Ca0iB8hEz34xkDB8NccQgfySDdcmOWvVHm9DCO8xbdLRoTb9WFb8w6pkX" + + "wioJnaQ0pa4VYC8gTHOqMgy9/Yk8GHdZ9iOALTNFKCGJZvVKYKL7vhthQV5O" + + "XVBeBGB6eTCFutJpcqdv27V3EwsV77WBHxgTvjsWJoGK7p8jvApgZSYSV1fB" + + "YetDiXhgezEAEQEAAbQKc2lnbi1rZXktMYkBOQQTAQgAIwUCWPVHNwIbAwcL" + + "CQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEFdUbHpYn0hjUYwIAIovaR+B" + + "YOYD8nYz3ylrnbRx7pAxaniNN2ZdzkhvbAx9ACvuN56R9GkaU3mwTd3LUEMG" + + "iw4MlvbEeADCckL6sB73esOiteoJz3+0+NCDb5rhbt5YCKQicubxhSNd2qkR" + + "eQE3IYpEd++QHXr/B7U95rwzjXzGImNyK15zuFGboC9VEQOc3ckTugoMirC0" + + "QSpHXAQlPHdwcA/f5ljceVSqGTDPbKFjwpU4kB10ZK8Jm8VLlL1JiCfufyfL" + + "mYTa/ysjzcMI/Z4jTuZ2y0pLR+q8gMpuMfA+MVby3IXrK6hsgQcTjm3idHRx" + + "xxBiRzdpJbh4CJAEu/9BTCr4WQF48rmwLmqwAgADuQENBFj1RzcBCACisowf" + + "NnQQTZBK7nYv24T3I0jDy3fENEtZ/g3pVW/e9BdeyXy0eXMSHgiWqn8LWznD" + + "BYzPbAth4Eq4fyNv2FbkvEHeQwoF893oLonXeyM171A6siptL1LXdqBNYaai" + + "Z62pHYFa4r8q7UzcAeVMKHQYEjbat90FTnFHrT/Mc84ZN7nVnu8PevdM73z0" + + "pdLq2aQ6oPJ+zZDU5nnx9dBiftc3BCn+gBuNua1rQVPBjXv+urEc/nig9dG0" + + "LDH3Gio7Va9AOgkyq6RB0X/yGF1Q4B88n9pHsbIUEH6SjA/WNX0iAqjv2Z7v" + + "fgJaJIr7UY5Lz9hBBpMKeHhhY3p9I4k3gZTnABEBAAGJAR8EGAEIAAkFAlj1" + + "RzcCGwwACgkQV1RselifSGN2Mgf/SmLWjy7PQa8WzwdMfM3ngTkqc6cunmVr" + + "R8cDsevKnwCzN86I9SHgSBIFt3YcCaFOFprF6gREq6He0G+VbyY/7xnjCfrl" + + "ZczkwFddHl3vO/3CcZrPyfFnItMmLYW1WjSOoSfz/uiijzV+R7KcmT3s8z4G" + + "hB4u/yCa5WszRYepVaH6J3IYbfCjMn5YDuv/bxPeqbv0xkTanKeeGHT0MKN2" + + "ff9mtlAK9gj8awU0rlvIcmHXIpcEih9pJDhmtCbapNH2ne4SyixztjfYgdEd" + + "uVUD8gp0mN/5ckVtAwQ8j6Qa6tYoQJfNj/p6OMmR0bQFvVpqTasWoL+hO8Bw" + + "TvUuMkI1uLACAAOZAQ0EWPVHXQEIANB18VoDCSng6SiOIeQwmk01K4Q8jak7" + + "3J5nwKvGHTLHy105AI5d6b3QFRcdK4WzM5ai9Pm5snTyAAGgubcU25dDUAqO" + + "EfyKwWkeBEl9Zc6iXgB2KGrTJylVSrRH6y/CsAo9JOXtyV6S9iKacQBZHVKN" + + "xZGWOlQ72xDfPBjhYi65cUZhNhK4fn32L8WmyKWVWNFfajybHnKN/Wv0R/Uf" + + "TxCWEDA0ieUVKs//m97gCzYC2xODGDEKal6xQsmQB6iRrcPAWpxC9LHG7cGh" + + "oqS99Guj2b5UqdI+69KNpqrbX7vj1mnYo+QrJJCp62+7QMlXAs+1Xih2P6Qe" + + "KMlk97j2gPsAEQEAAbQKc2lnbi1rZXktMokBOQQTAQgAIwUCWPVHXQIbAwcL" + + "CQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEGFcNg7n5zRXZYoH/3iFmvXH" + + "TR8lCLs/dj0JQ3FdbBNSwhJRHUh8cpPTcJxFZumAjf1nVJbqKVLhTrrcqZF/" + + "QJdYvfaD/pziaDgNTUdzBC4VXKqtNODS0QLlq1dcZQ/rNst/HlP/e0FCfq3V" + + "HZgsY2Xwmf2gj8sK9bnZT9U6THUU7m6miW4TnQDAhUmBJubmYzKwbrkuca2c" + + "lW3PC53IIjycp7+jY9Hxah/D+MU+0eaelBTQ9rypZNbVOCKcm8rMIKk9HxoX" + + "GfbZuo7L5TT/TFZVwK9DRh0qBqW4fOGSLTNsz0O9QkcrsXxdhvAvX2fiWsZu" + + "2r7E3/c5CIL/s/5C7AzA370wtriu2b4toWSwAgADmQENBFj1XDoBCACyr8Bu" + + "03osh26GiIKOzhfbgH0hdlnJlh8LNo8ALE/Hz4KbxzM9Zyh46NZG5aS5NADd" + + "c7FBWTLqcxS14JobkjM2edJJXIilpCdw9ThuW/gSEYpJbPKRncq8D4K6d8Bg" + + "kWkjadYPsmFzFlnSL0Eki9sW8JRzEACe1R3srJLUN0SsQ6OPwOimv4i2CkYw" + + "RIvjpBhCtIs2qV1ERMpct9/rPDzLlL/YS7MF7PSXd9Jy7J2KuwPNXjcXwRFR" + + "MOTYV3Cx7+OAnUs6+Pyb6DbrYPF8AgC6KKqJXR4Ei5sQCwWkIXQ3sjPBD4x8" + + "hAqBuUzJMnNF00YhDXl4kMI+2r0GSwo+6ZF5ABEBAAG0GWV4cGlyZWQtZW5j" + + "cnlwdGlvbi1zdWJrZXmJAT8EEwEIACkFAlj1XDoCGwMFCRLMAwAHCwkIBwMC" + + "AQYVCAIJCgsEFgIDAQIeAQIXgAAKCRDDZIMAG7vFqFoXB/9exlOGLLK3tiYl" + + "RaPZsq26uOdiU1efO98aJCK7lRaUZkTXlxF9THVQnCRUGjEHPjYIxwm1oeUy" + + "2dvqklq5jIL6Vcmt5hrVax++tIuKBpqISF8wpJcNEmq3zwWUxAhvE3d2mgAn" + + "9AzoabzAy8SBkCZD/o0THB1z1R8CJ3PcmbIzt+CdMwG2NVJLlw5VTNVCp0fc" + + "m8OzxoH0C0qiaR2DPjuRNlXepjz0LC+8coIMOOiJnJnQywGnjNbgoDp79XPn" + + "KpoN+TpXkQkAiuIwlu4GSADUDV8MiUDbhMxZTPJD5KSC47COMZV2huLgRx1x" + + "kwQil3Pqp4PMf/fvgbWE7L9yNz+ysAIAA7kBDQRY9Vw6AQgAzvv+T0ykClWK" + + "wyPuDd+2e0NSxzzyn7ZWrms7FClnvKszjpKnznHiRRE+kXwEJ3HIBJIs604I" + + "09pgIkZZrfx5zkrZm2zpUp7gWndh2c/AiO6/cAe6I3vwodhPyDFn7+JXQjgz" + + "aJWg9jNEbSjodq/mK9K7Ln5YqYNjn/mb+VX4xa0E5YBMcGnLdrkmOJcEZTd5" + + "fedeIVKzU/BAk6YQcrDXuDAKD5yXB4djAhP1p6DUSaQ7iS35pgHTdgNuHBMC" + + "uFxzR4vco/eqRElzaUVIIBGQYUcUE+RDRDREQKCkchrTELGh2GNFieig78D1" + + "3HaVdZb6yJg9gYcuWH54QKgVSnzPxQARAQABiQElBBgBCAAPAhsMBQJY9V0/" + + "BQkABpiFAAoJEMNkgwAbu8WokgoIAIE2uNH0SpHVKB4hJRqYes6hURn8q0HB" + + "+tfvlfrSopaDp2nr55B6dDiJNS3QIMb9nZePOnbW0tVPwga1775Gh0LM3+jf" + + "s8oVgG5EcH+CZWiW0dj4LXvZ5hO4qqJJYF5IC9cbQQOG8TUNZZEHO/Rwe1/0" + + "5mEV+Qw9vPSvEfloMku7pdeZIn8+GLai/jxSC/7WGBeuyhjuCmookrqcufh1" + + "SICnRZPGuIGVqAsAm5pthWHwwwcW7TYy70ml5eTSBwrR3ciVJ+gibLo+p6IK" + + "pd+E71rpk6NwHKvFDCaBW2BUYItgzcapA4ellc6OLeXVSktd4rL9Ad/Vb9Xu" + + "v9zqQppjemywAgADmQENBFj1Z9YBCADEsA6PsyFNS2lK1DOPenoZCLYYujDf" + + "j3zIf7AUG3DHEya3km+mm/etpSS38ENtJRzjZ8Xb8T73iMbsRiMuvbPhLP7L" + + "zMw0YQz2OBqXeft/TM8GhAfRdxGwTRKEhczA/GBVj1uXtt3aH9PKqa4ZBAUC" + + "+mhwts87IY3OlchAzESJnpWYfL+9PD6y0PdgPCQXjwrLuXkwpmR4L2VKLunW" + + "RKdYcV4pWF/MbqND4ZHuYsj11CDYaKdC7Q4LegBlU9wBOEzJR+pRzMog1HgM" + + "UYnifpfcQqJ4xY7mr57eHDNZ/x8UeJDQN2uH3bflWmi8GmE4lrCOp1C7jNAD" + + "vJeF76LP5o1fABEBAAG0EGV4cGlyZWQtbWFpbi1rZXmJAT4EEwEIACkCGwMH" + + "CwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgAUCWPVpAgUJAAaYrAAKCRBRNKkC" + + "/D9UQS56B/j/H4nxRPjPHkUSlfPrvP1zP58hDWDN7vFF/3/r8kVTRScWfXXm" + + "63OWpsvWP1i1rPnKsvq/TiS9hvO7bmvhpWiGViUZhWewaPTmtygNbXLgsbF+" + + "47VDG3kHeOLXwouCNwCOa9KUUVy6SJqom3FBlVqU8NyW6SUQtw5Jwvi9nsAV" + + "Vbo9Cg1YDwEJbiVuXO9IB5VZ09+ZEcWMWAJzDPy7yuBeVDoHXuS6uZrkMIMx" + + "gGsH84V3o/8v0D3+a5PnQ1Ke/IRLlLJ2kGMNyqenFVQJWLTIxJK58ppWXwGM" + + "E5jB/Wi0xzw/uSf3aZVBodp2AZdYB48qfMyLOeSObyyPkYayGOSwAgADuQEN" + + "BFj1Z9YBCACwO+T+s2ZXiHmiKSSf5ZdHA02LiHxmO5vfPfh/z65FhYuhkRgt" + + "9wHdKabf7drG2xDmDJwumUxQiut3OnLimN8kXX7Yh/+11S9OHJHA6HkhXAxb" + + "323bHpfJ0Rdjt7MEscIk1qCwboG7cMHiWH1e2IsyR2w5NNQuKLRyUC1AAuMs" + + "1qFmwYpJDSuJZsuL/dd9d2BTfHKA0KeCx5j/6xme82ULNyU8niA3EWjt/Lql" + + "4IZaVQXbBKlBi7ZNC9q8tuYYHkxxGfwhq0g5FWKPumtpFIOV5KZVoil48U9p" + + "c0B/I/IRHXJ2Q4w5YlZQR5cbOKOrQ0/ELYRRvzh4yurzy+sobiGfABEBAAGJ" + + "ASUEGAEIAA8FAlj1Z9YCGwwFCRLMAwAACgkQUTSpAvw/VEHj2ggAoKv89H6V" + + "TSRWCXNq6FZVbD8WFz4emuyn/k4e5C4ULVI8j2eSNUVG3VfPQLzxYC/GjVUU" + + "m38p7wGG8aYYZumUc4+7vR811uBxDTgWnmthR6SRTqutpuvYShlgT5kor3E2" + + "hkZapIrxqKBwZOAi8JK5ADbdLrpQRlDoik10a4KZH4c7FblIxcag1Ee95IOv" + + "xrxFDRRJqdkka+TmtWFuf5eMOSTDeSS8XK4Az8kl8W3CGULICwVWJmfASeeR" + + "TwE+Guw/gx/dhz6ukTgSsxn1EdQMu4GMrlCk5Khwq1soVLumfrch8iqt7y1k" + + "CgNgcu7sk31BaZp2xrGpP1G/kklggTVtxrACAAOZAQ0EWPVqQQEIAMpR07Jm" + + "F2fLdLGLEpge3FCUqxbnyp5xAvLJHyUHLmFqoW8xpPMJHnIZycBcPe5G/S+a" + + "7uLbUMaRALHHFebmopmw4JzW2wFMk/LXST6MmRIfFTcpYqtAn+YNKLUxuqqH" + + "1kHPDG+kjMqzWmW/Heoh4rPHuREm3D0PBXQNLrcHlOV862+g/yLW8QfPd/0E" + + "Mi2A+1gb54J3zLsyQjCEHYguLPtGD7tMdOk7exBgrHD1nado3Ofu3H2zZ7Sc" + + "+izarkIeNDnq4k2eaEmfmiambqDsqdCB8mSP0jKo3+hChDMU43WlL7jka2Ko" + + "Q6zKmKHopZAHjNM1AfUzF8XZWEhQZ8yQP4sAEQEAAbQNZnVsbHktZXhwaXJl" + + "ZIkBPwQTAQgAKQIbAwcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheABQJY9Ws1" + + "BQkABph0AAoJEEkvIbBfB919T2oH/1LRkMTU0U/H7gVxMsWyv1aFF5d8FZE4" + + "CnGz9YJmOQky+wck1GH5qLdGaPikD/hC73N2s276KE2iW3wg/VRH+760k69I" + + "+Ffjn252lafBxN5ZISxU1YM7GTjdkLo28ZEVR7dgFJMZTYpoefULh/Vac4KC" + + "ZbAp7OMNBuc8CSYTYGtqThcZB58aM/w4TeWRSBi9CcxP4JObdx2U0aoowJf/" + + "MNcN6/6/tEDYcAYYJoCLiLiVc4yzfS+vrrdM/knARyPyqjQnyo2s/CGyccYz" + + "u0lENc8mquRhqBbb+zI98eez8oxAVxzxhafTmtOn5+M8/1fpsPT70sZUlK+K" + + "z7iVCCJS0uewAgADuQENBFj1akEBCADhxBHK/Yzg5kuLiF0DsTYCslRTNr3s" + + "wU+vv1WGrGd14ktp2XZlNnhnF5N2cpCVi9CiUf8B9Hq7N7caa4E7F56EzEpf" + + "ccTJy3tysvtRiWwOhlBgkgNK5RxRCBMa6fXAgON2AX8EjFYBc0L7e/35CLQn" + + "3SGAyYiZ97PhH3gD15C7qwyqSKR2J++FPYEH1BYm2FbxZ22joJ3jP86EWTiq" + + "UYcXWwIRuDeZvP7hDdozJMMM8MGtnnSFWvBgotBf7P8ttq6lbdMLQzJTFXUS" + + "z9qsNgdBQo8PNrE2Ig9HuOJlEY2g8EXUhqHgMtCYIimN4FjFFEMdMiIrwc+t" + + "ygNSysmcN/EnABEBAAGJASUEGAEIAA8CGwwFAlj1a0EFCQAGmIAACgkQSS8h" + + "sF8H3X2XPggAlxD+W9jL+AAlKpXcwuvzLOxHL4i/x4snqx+UMZkNrohP5wed" + + "du8KuewWCjF08qVL4CzkUbu7T3xOkG3mghvwv8/2AeoEtyeNCNyNtVi+oLAL" + + "AW3fA199rFwK/6C+c5QPUlFLrJMFK4S62LR16U+gLpWbjVg88DFRIfq7ISGP" + + "K+VLZlMGqvtO6s/uRgFpjTZsrh50CaQ7l1gHwFsdA7W0J0uR9fq3YYWXcUS+" + + "Dzn1bYyL47v67YfSIAe3fWkwKujMWgqeZP37Wx9S68mdZwGWM4dL7p2gm+FZ" + + "rnv5PgyOlHqBTHHj/pnLNNAhlPGLtQkVe5MuluSPpQYwAsdJzX5aLrACAAOZ" + + "AQ0EWPV1SgEIALxHYi0DZvv2m+M/6p8FxOye/PAaJhhrMsKOS2D7IJeEujk3" + + "+6/75P7Rp3P50qCHq5jl7+GqquEf1pKjwBgTe8vhT7sxPimzsZ73R4PmTFhj" + + "WzxDUnLKYE2+McuhuBTKFep0tZcxtzEMLPuA7Wd78lR1YtuAYmLI5Q24iGn5" + + "X62RZhvecms5Iul0GVo77o3S52P+yiyEWhd0v3LuHxoglJiLAqWv4EoO3ciG" + + "LAZTgfMloDyHmkuGI+fqnfb6wYbkmH6pEguXV6GAfcWvBH0UoaVgcp7muAkD" + + "B7MNWMljmy7KEseUJ5/jqJd+CFPPLx6HL3PYV+L8rsrKGkVZ98PDKUUAEQEA" + + "AbQeZG91YmxlLXNpZ25hdHVyZS1leHBpcmVkLWZpcnN0iQE/BBMBCAApAhsD" + + "BwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AFAlj1dzkFCQAGmW8ACgkQWv1T" + + "qduyxA0fKgf/d4WPcxh+4TK+tPNM2JKP7X3UywiUeK7DL8Hbz1Fd4JvOrw9t" + + "EBlrX6+RLzljjfZ1iXIvZLwMacV70zO64pndiKUi24cIFtumOgSY29WSfA6r" + + "VEy/7Pj8KB6D8h52uEmI/l7+R01W9cDTc2/FMwHpfgMGs4tnfDPs9I5o3GaP" + + "N7gPyeh1CWPg07Se4vYTQXQpE80i3NuSDIIdxDRF60mXhIzuKuPmZaky5VfZ" + + "JemkuJg9xZUqIZkKN7DPd+bdLCHYT/4sO9KpXdhCqXOcrQcrZ+pK8+XF9oow" + + "I0zHmVfzs6sx49nN9r6IkWp2ptcPVYy/xbuR4FNqu3zywBoaHCYwm7ACAAOJ" + + "AT8EEwEIACkFAlj1dUoCGwMFCRLMAwAHCwkIBwMCAQYVCAIJCgsEFgIDAQIe" + + "AQIXgAAKCRBa/VOp27LEDTKpB/97tH64nH+il9x/3JYXqXZ5dBoQnvUbPbU0" + + "Zb6MJXKRfh+T+SDtUSzjeWGgNFY8tGe2EuPbWrSY6IOilwKs2mk/flXoiKxm" + + "x45nAjPfdbaOhNC8J4d3GOqga8ysICWpWZK6JOb3SfzKa49Un4aALp5tGEIu" + + "aJAlNyS+U5BHhCMl5qiYCn+YyuL54B6z1MChqC8s9Zsmr7vbum97bsK8X5dK" + + "fZEL5CJqZGcVgh4dbcVhjXmBCFXfwNxHyZGeMBUegcF9TNdi03QghFjyV3qn" + + "WtesVjx9AWN3QFxgHRPwOt4vGPMDPvLgGLIJ1ecZT3PEelKG5fuHrWdwjnaL" + + "YmmzrjUbsAIAA7kBDQRY9XVKAQgAzr1JH5kZ+GeSDcflHZHQQ/cjoqvRw7dl" + + "SP/Je7IGBF21QDjlgesSzSyKvR49P0pI9us9fN7weU4YyJEWk1JP87wO/hAb" + + "qHkZvqaPFmUQq+8s/JaWcAdADqmEYaqf4O5Z4QpaWelv+DiXITLFyHGchKwY" + + "Z7JQv8JtWRuNSARMl4Xw/rrB342cy7BVU4p502tv/0tTWdtGn/lJA2kashoN" + + "7GS2AmSvXtHHT4acLuIYglJAMU2Xb5P3vhKalvLVbwqVEEkH2rFeX9QQIw2r" + + "JpqZarW6sbXxMuOxj7lBWa4/hL0oz2Tyit6f8QIqJDlvzR4tus/xyDgipFhT" + + "6Kzey6dRFQARAQABiQElBBgBCAAPBQJY9XVKAhsMBQkSzAMAAAoJEFr9U6nb" + + "ssQNIcYH/juwAmPLNTRkssajoT2I+z6rk/SHMWyfYgxml+XneBE/sQQ8pU6f" + + "9DrroqyZpQh8cOMzdKLNM3/ilFbHplRXDk4ehDo5XYgVk2PcQvo10eOrVHO/" + + "9YMXzb8ZYwkbdiQGPB/1nQNl80mWcVQjw2atlyoWm7MKpqZDjil2t59s8Jxv" + + "IXqc0o7FkpB6r8i2TKZuWkUhyzrPBr+i6yuFfJg6diV2huGYTZ2lcNO7TiMj" + + "pRgq8KjK59Cm8iosvJxGTAd2KXZBAxCamiIYEhNHFRmBX5+PR+zpeG0p+t2k" + + "voqMwoEHcbSh4L6h/aiH6fFpPMjdKuYKj1QOJ2Aie2HbhYqbE6ewAgADmQEN" + + "BFj1fKQBCACZB8WV+FuMc4Ryh/Z9/AwdV2h0kRaux2A/7fsvoSVPUi4o89hN" + + "uzULN7qfw3kcoYf63LsAXT9xYeYmrBpPhUg/jWSHqb7sX3du30hRO2YaikPJ" + + "VD1j241zn9VjwBsKNbbUSp1pxvCjhQazwm06wFKWfJ7KbyHrZuH0F1ynLga3" + + "6UNfPrHPxxDaBx3TlvEM0dJMu5dhPyWpUUTMAM1cEzkY13W2evwZ9mmvnJEc" + + "kKuomoLk1rVGLsyP0OH8uR3+2Uvm2zFUnr/zRm7y6561nlJNTCr+Y3U+4j05" + + "VwunRyA85Kw6QqEhVq7E2e49rPafSfgF5wcvcCnnyaumtY8efo9rABEBAAG0" + + "EXRyaXBsZS1zaWduZWQta2V5iQE/BBMBCAApAhsDBwsJCAcDAgEGFQgCCQoL" + + "BBYCAwECHgECF4AFAlj1fVEFCQBB660ACgkQifz6SyM2MzO2Qgf/SlF+9qsf" + + "nMJyH+8sn+v4wyarKbHvXh6oXLRWp2pdtRXD/H2HfkTj9zCnSwDuos1mAtet" + + "YDRX/dc6C4YRTUJM9VHmHXkQJN8cW1b33cleHSViUdSmKRMCDYoCYbgT7k2u" + + "wZx+OQZLxqQ9oT7AqJFhxxSJNYKDBwOPJmV++8L84FCOFxO1bwfpwq0zRTlL" + + "WSMRwcwICeBaZ6qwCuHSxVzHL27JEWLM1v5T2DWYYY8TCgH0sspO3FLepPaS" + + "mMHsUoX1vo72fTqzSeucO7eFWMX919h/2YsVpk/G8c3N7YaulAa0bfc1C+1u" + + "iRygA978Uh7dwO8fGX7ZZApk/mCoKQwB7LACAAOJAT8EEwEIACkFAlj1fKQC" + + "GwMFCQANLwAHCwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgAAKCRCJ/PpLIzYz" + + "Mw9GB/4mzkmW2HeeAXDvy2KZqpoGnrzR8AO3HmkZBPKV+kXTDp4Vpt6Tr9AB" + + "Sg3IOv07mLj9T7v0UI4HiKX+s8vFVGGE1Ad74zYJTJJNBKojSP4ZmqldJbS1" + + "DbvqfYxZgm/oC56qtKhLI/eB/3lPJxrGWnB5Vq9HbRY5Y3Jrvky8LLM7rhfn" + + "8MDFJGQebgC4RaR/AhQ8wstp2LnwsqptUX06sQXzfNKjv1N1JjCV5WUPDnI+" + + "wEXt0jvlcVN7BVNGOnMVuQt3HSJcDHSwUrVkIOZMbTfNsW7n6LiTYdOZZsVS" + + "I5KEEx23DYOKwWwBagGII4RlhYJO1cm6XediuZMqLl1qwIjwsAIAA4kBPwQT" + + "AQgAKQIbAwcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheABQJY9XzpBQkSzANF" + + "AAoJEIn8+ksjNjMzih4H/RUKWx4oHSI+QfsNwWUFjxgoM8qPuya248fJVqTr" + + "zqT2zhEctLKcyFsei7QcgfksJyZklY9AV0NeNCXkg6iUoX+5ZTxpu2Fblf6l" + + "7ZKzQZPGV1lWBbOW+ybm8xGpmKZaNYiFHjVvXZ4QNkvQMw+GCe+D+yQxvMIm" + + "G5/1k7VrEGpwL31BaiBsoQ2ADHXAHk7Aa+4stp8V3db2jNzln6aHbriGvjLH" + + "FUa2CstdtfBo52hzWcQGSp4XsbEcrjP6bYskJW+spJjvLL48tFMbSFIdNJMo" + + "l6WIXBItbCkG9GUbAK6t3reIeVvoXLqKN/vzWFPJ6B1JLmRfRU5q5GFBBzvH" + + "TZOwAgADuQENBFj1fKQBCAC3B46wgfnaS/TgBQD284P+isKn6jcEy79oivV0" + + "lMTrQxexQBbzXnCBt2l8p+kOYm8YTeNJecg7gpTYLckbL2EsMwhiLt3mrgiB" + + "eFdRhNbuYH9jXekysE3zmGmM4BS/KjIcm8Jngk2zVY/o/GA6Mg3s3XgCU4Fa" + + "HYd+ojbkORVI3p1MF/hy3Rqbe1WJKgPOCXW+n/TLMzciRr0Y8EVCcSopFCGX" + + "6QFJVKPwYLqIKfYkJhyEmIAlBu1747ysAV42Bfr5TjkNH+jIOy4rDVYjDzCS" + + "pwx/TF/7970QEYlwPQYKEZGW2yYVKq4Y0pMKbAwo/sCpjI2cOu9cwcLkBlFg" + + "8/hlABEBAAGJASUEGAEIAA8CGwwFAlj1fVYFCQBB67IACgkQifz6SyM2MzMf" + + "DAf/T/rfVynO00CLLX5oMvRJITQH6yu7aiCqOJEsDaxxpQL3tJhMJRyybCmI" + + "kXATcEtn6GNAbGJViw6I1o1K6HmeAHECxR64uKvhsMeoC0XuPPvVZD7qAUaQ" + + "KRi6l4j/2e7YCqp5F+Xz1zhER2nwGnqYpM7IR0M3OPbwQVgPe2FaQYYnY16J" + + "bGHyFtdfwyJEzzR8YMcgAnrD8TI+SvErFEH+0vzV+JA1gjYd2l3/ijDj82rn" + + "WDoIM5gfjeZgwht1vl6+7J+h20yjFrBdf7gJj9OcIGmwlpQ56qzbT4U++mw3" + + "pW2tN2VuYtreceEoI4B6yUGMEhI9t/asLgn7wEAU2lpuE7ACAAM="); + byte[] pub2 = Base64.decode( + "mQGiBEBtfW8RBADfWjTxFedIbGBNVgh064D/OCf6ul7x4PGsCl+BkAyheYkr" + + "mVUsChmBKoeXaY+Fb85wwusXzyM/6JFK58Rg+vEb3Z19pue8Ixxq7cRtCtOA" + + "tOP1eKXLNtTRWJutvLkQmeOa19UZ6ziIq23aWuWKSq+KKMWek2GUnGycnx5M" + + "W0pn1QCg/39r9RKhY9cdKYqRcqsr9b2B/AsD/Ru24Q15Jmrsl9zZ6EC47J49" + + "iNW5sLQx1qf/mgfVWQTmU2j6gq4ND1OuK7+0OP/1yMOUpkjjcqxFgTnDAAoM" + + "hHDTzCv/aZzIzmMvgLsYU3aIMfbz+ojpuASMCMh+te01cEMjiPWwDtdWWOdS" + + "OSyX9ylzhO3PiNDks8R83onsacYpA/9WhTcg4bvkjaj66I7wGZkm3BmTxNSb" + + "pE4b5HZDh31rRYhY9tmrryCfFnU4BS2Enjj5KQe9zFv7pUBCBW2oFo8i8Osn" + + "O6fa1wVN4fBHC6wqWmmpnkFerNPkiC9V75KUFIfeWHmT3r2DVSO3dfdHDERA" + + "jFIAioMLjhaX6DnODF5KQrABh7QmU2FpIFB1bGxhYmhvdGxhIDxwc2FpQG15" + + "amF2YXdvcmxkLmNvbT6wAwP//4kAVwQQEQIAFwUCQG19bwcLCQgHAwIKAhkB" + + "BRsDAAAAAAoJEKXQf/RT99uYmfAAoMKxV5g2owIfmy2w7vSLvOQUpvvOAJ4n" + + "jB6xJot523rPAQW9itPoGGekirABZ7kCDQRAbX1vEAgA9kJXtwh/CBdyorrW" + + "qULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV89AHxstDqZSt90xkhkn4DIO9" + + "ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50T8X8dryDxUcwYc58yWb/" + + "Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknbzSC0neSRBzZrM2w4" + + "DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdXQ6MdGGzeMyEs" + + "tSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbTCD1mpF1B" + + "n5x8vYlLIhkmuquiXsNV6TILOwACAgf9F7/nJHDayJ3pBVTTVSq2g5WKUXMg" + + "xxGKTvOahiVRcbO03w0pKAkH85COakVfe56sMYpWRl36adjNoKOxaciow74D" + + "1R5snY/hv/kBXPBkzo4UMkbANIVaZ0IcnLp+rkkXcDVbRCibZf8FfCY1zXbq" + + "d680UtEgRbv1D8wFBqfMt7kLsuf9FnIw6vK4DU06z5ZDg25RHGmswaDyY6Mw" + + "NGCrKGbHf9I/T7MMuhGF/in8UU8hv8uREOjseOqklG3/nsI1hD/MdUC7fzXi" + + "MRO4RvahLoeXOuaDkMYALdJk5nmNuCL1YPpbFGttI3XsK7UrP/Fhd8ND6Nro" + + "wCqrN6keduK+uLABh4kATAQYEQIADAUCQG19bwUbDAAAAAAKCRCl0H/0U/fb" + + "mC/0AJ4r1yvyu4qfOXlDgmVuCsvHFWo63gCfRIrCB2Jv/N1cgpmq0L8LGHM7" + + "G/KwAWeZAQ0EQG19owEIAMnavLYqR7ffaDPbbq+lQZvLCK/3uA0QlyngNyTa" + + "sDW0WC1/ryy2dx7ypOOCicjnPYfg3LP5TkYAGoMjxH5+xzM6xfOR+8/EwK1z" + + "N3A5+X/PSBDlYjQ9dEVKrvvc7iMOp+1K1VMf4Ug8Yah22Ot4eLGP0HRCXiv5" + + "vgdBNsAl/uXnBJuDYQmLrEniqq/6UxJHKHxZoS/5p13Cq7NfKB1CJCuJXaCE" + + "TW2do+cDpN6r0ltkF/r+ES+2L7jxyoHcvQ4YorJoDMlAN6xpIZQ8dNaTYP/n" + + "Mx/pDS3shUzbU+UYPQrreJLMF1pD+YWP5MTKaZTo+U/qPjDFGcadInhPxvh3" + + "1ssAEQEAAbABh7QuU2FuZGh5YSBQdWxsYWJob3RsYSA8cHNhbmRoeWFAbXlq" + + "YXZhd29ybGQuY29tPrADA///iQEtBBABAgAXBQJAbX2jBwsJCAcDAgoCGQEF" + + "GwMAAAAACgkQx87DL9gOvoeVUwgAkQXYiF0CxhKbDnuabAssnOEwJrutgCRO" + + "CJRQvIwTe3fe6hQaWn2Yowt8OQtNFiR8GfAY6EYxyFLKzZbAI/qtq5fHmN3e" + + "RSyNWe6d6e17hqZZL7kf2sVkyGTChHj7Jiuo7vWkdqT2MJN6BW5tS9CRH7Me" + + "D839STv+4mAAO9auGvSvicP6UEQikAyCy/ihoJxLQlspfbSNpi0vrUjCPT7N" + + "tWwfP0qF64i9LYkjzLqihnu+UareqOPhXcWnyFKrjmg4ezQkweNU2pdvCLbc" + + "W24FhT92ivHgpLyWTswXcqjhFjVlRr0+2sIz7v1k0budCsJ7PjzOoH0hJxCv" + + "sJQMlZR/e7ABZ7kBDQRAbX2kAQgAm5j+/LO2M4pKm/VUPkYuj3eefHkzjM6n" + + "KbvRZX1Oqyf+6CJTxQskUWKAtkzzKafPdS5Wg0CMqeXov+EFod4bPEYccszn" + + "cKd1U8NRwacbEpCvvvB84Yl2YwdWpDpkryyyLI4PbCHkeuwx9Dc2z7t4XDB6" + + "FyAJTMAkia7nzYa/kbeUO3c2snDb/dU7uyCsyKtTZyTyhTgtl/f9L03Bgh95" + + "y3mOUz0PimJ0Sg4ANczF4d04BpWkjLNVJi489ifWodPlHm1hag5drYekYpWJ" + + "+3g0uxs5AwayV9BcOkPKb1uU3EoYQw+nn0Kn314Nvx2M1tKYunuVNLEm0PhA" + + "/+B8PTq8BQARAQABsAGHiQEiBBgBAgAMBQJAbX2kBRsMAAAAAAoJEMfOwy/Y" + + "Dr6HkLoH/RBY8lvUv1r8IdTs5/fN8e/MnGeThLl+JrlYF/4t3tjXYIf5xUj/" + + "c9NdjreKYgHfMtrbVM08LlxUVQlkjuF3DIk5bVH9Blq8aXmyiwiM5GrCry+z" + + "WiqkpZze1G577C38mMJbHDwbqNCLALMzo+W2q04Avl5sniNnDNGbGz9EjhRg" + + "o7oS16KkkD6Ls4RnHTEZ0vyZOXodDHu+sk/2kzj8K07kKaM8rvR7aDKiI7HH" + + "1GxJz70fn1gkKuV2iAIIiU25bty+S3wr+5h030YBsUZF1qeKCdGOmpK7e9Of" + + "yv9U7rf6Z5l8q+akjqLZvej9RnxeH2Um7W+tGg2me482J+z6WOawAWc="); + + private static byte[] secWithPersonalCertificate = Base64.decode( + "lQOYBEjGLGsBCACp1I1dZKsK4N/I0/4g02hDVNLdQkDZfefduJgyJUyBGo/I" + + "/ZBpc4vT1YwVIdic4ADjtGB4+7WohN4v8siGzwRSeXardSdZVIw2va0JDsQC" + + "yeoTnwVkUgn+w/MDgpL0BBhTpr9o3QYoo28/qKMni3eA8JevloZqlAbQ/sYq" + + "rToMAqn0EIdeVVh6n2lRQhUJaNkH/kA5qWBpI+eI8ot/Gm9kAy3i4e0Xqr3J" + + "Ff1lkGlZuV5H5p/ItZui9BDIRn4IDaeR511NQnKlxFalM/gP9R9yDVI1aXfy" + + "STcp3ZcsTOTGNzACtpvMvl6LZyL42DyhlOKlJQJS81wp4dg0LNrhMFOtABEB" + + "AAEAB/0QIH5UEg0pTqAG4r/3v1uKmUbKJVJ3KhJB5xeSG3dKWIqy3AaXR5ZN" + + "mrJfXK7EfC5ZcSAqx5br1mzVl3PHVBKQVQxvIlmG4r/LKvPVhQYZUFyJWckZ" + + "9QMR+EA0Dcran9Ds5fa4hH84jgcwalkj64XWRAKDdVh098g17HDw+IYnQanl" + + "7IXbYvh+1Lr2HyPo//vHX8DxXIJBv+E4skvqGoNfCIfwcMeLsrI5EKo+D2pu" + + "kAuBYI0VBiZkrJHFXWmQLW71Mc/Bj7wTG8Q1pCpu7YQ7acFSv+/IOCsB9l9S" + + "vdB7pNhB3lEjYFGoTgr03VfeixA7/x8uDuSXjnBdTZqmGqkZBADNwCqlzdaQ" + + "X6CjS5jc3vzwDSPgM7ovieypEL6NU3QDEUhuP6fVvD2NYOgVnAEbJzgOleZS" + + "W2AFXKAf5NDxfqHnBmo/jlYb5yZV5Y+8/poLLj/m8t7sAfAmcZqGXfYMbSbe" + + "tr6TGTUXcXgbRyU5oH1e4iq691LOwZ39QjL8lNQQywQA006XYEr/PS9uJkyM" + + "Cg+M+nmm40goW4hU/HboFh9Ru6ataHj+CLF42O9sfMAV02UcD3Agj6w4kb5L" + + "VswuwfmY+17IryT81d+dSmDLhpo6ufKoAp4qrdP+bzdlbfIim4Rdrw5vF/Yk" + + "rC/Nfm3CLJxTimHJhqFx4MG7yEC89lxgdmcD/iJ3m41fwS+bPN2rrCAf7j1u" + + "JNr/V/8GAnoXR8VV9150BcOneijftIIYKKyKkV5TGwcTfjaxRKp87LTeC3MV" + + "szFDw04MhlIKRA6nBdU0Ay8Yu+EjXHK2VSpLG/Ny+KGuNiFzhqgBxM8KJwYA" + + "ISa1UEqWjXoLU3qu1aD7cCvANPVCOASwAYe0GlBHUCBEZXNrdG9wIDxpbmZv" + + "QHBncC5jb20+sAMD//+JAW4EEAECAFgFAkjGLGswFIAAAAAAIAAHcHJlZmVy" + + "cmVkLWVtYWlsLWVuY29kaW5nQHBncC5jb21wZ3BtaW1lBwsJCAcDAgoCGQEF" + + "GwMAAAADFgECBR4BAAAABRUCCAkKAAoJEHHHqp2m1tlWsx8H/icpHl1Nw17A" + + "D6MJN6zJm+aGja+5BOFxOsntW+IV6JI+l5WwiIVE8xTDhoXW4zdH3IZTqoyY" + + "frtkqLGpvsPtAQmV6eiPgE3+25ahL+MmjXKsceyhbZeCPDtM2M382VCHYCZK" + + "DZ4vrHVgK/BpyTeP/mqoWra9+F5xErhody71/cLyIdImLqXgoAny6YywjuAD" + + "2TrFnzPEBmZrkISHVEso+V9sge/8HsuDqSI03BAVWnxcg6aipHtxm907sdVo" + + "jzl2yFbxCCCaDIKR7XVbmdX7VZgCYDvNSxX3WEOgFq9CYl4ZlXhyik6Vr4XP" + + "7EgqadtfwfMcf4XrYoImSQs0gPOd4QqwAWedA5gESMYsawEIALiazFREqBfi" + + "WouTjIdLuY09Ks7PCkn0eo/i40/8lEj1R6JKFQ5RlHNnabh+TLvjvb3nOSU0" + + "sDg+IKK/JUc8/Fo7TBdZvARX6BmltEGakqToDC3eaF9EQgHLEhyE/4xXiE4H" + + "EeIQeCHdC7k0pggEuWUn5lt6oeeiPUWhqdlUOvzjG+jqMPJL0bk9STbImHUR" + + "EiugCPTekC0X0Zn0yrwyqlJQMWnh7wbSl/uo4q45K7qOhxcijo+hNNrkRAMi" + + "fdNqD4s5qDERqqHdAAgpWqydo7zV5tx0YSz5fjh59Z7FxkUXpcu1WltT6uVn" + + "hubiMTWpXzXOQI8wZL2fb12JmRY47BEAEQEAAQAH+wZBeanj4zne+fBHrWAS" + + "2vx8LYiRV9EKg8I/PzKBVdGUnUs0vTqtXU1dXGXsAsPtu2r1bFh0TQH06gR1" + + "24iq2obgwkr6x54yj+sZlE6SU0SbF/mQc0NCNAXtSKV2hNXvy+7P+sVJR1bn" + + "b5ukuvkj1tgEln/0W4r20qJ60F+M5QxXg6kGh8GAlo2tetKEv1NunAyWY6iv" + + "FTnSaIJ/YaKQNcudNvOJjeIakkIzfzBL+trUiI5n1LTBB6+u3CF/BdZBTxOy" + + "QwjAh6epZr+GnQqeaomFxBc3mU00sjrsB1Loso84UIs6OKfjMkPoZWkQrQQW" + + "+xvQ78D33YwqNfXk/5zQAxkEANZxJGNKaAeDpN2GST/tFZg0R5GPC7uWYC7T" + + "pG100mir9ugRpdeIFvfAa7IX2jujxo9AJWo/b8hq0q0koUBdNAX3xxUaWy+q" + + "KVCRxBifpYVBfEViD3lsbMy+vLYUrXde9087YD0c0/XUrj+oowWJavblmZtS" + + "V9OjkQW9zoCigpf5BADcYV+6bkmJtstxJopJG4kD/lr1o35vOEgLkNsMLayc" + + "NuzES084qP+8yXPehkzSsDB83kc7rKfQCQMZ54V7KCCz+Rr4wVG7FCrFAw4e" + + "4YghfGVU/5whvbJohl/sXXCYGtVljvY/BSQrojRdP+/iZxFbeD4IKiTjV+XL" + + "WKSS56Fq2QQAzeoKBJFUq8nqc8/OCmc52WHSOLnB4AuHL5tNfdE9tjqfzZAE" + + "tx3QB7YGGP57tPQxPFDFJVRJDqw0YxI2tG9Pum8iriKGjHg+oEfFhxvCmPxf" + + "zDKaGibkLeD7I6ATpXq9If+Nqb5QjzPjFbXBIz/q2nGjamZmp4pujKt/aZxF" + + "+YRCebABh4kCQQQYAQIBKwUCSMYsbAUbDAAAAMBdIAQZAQgABgUCSMYsawAK" + + "CRCrkqZshpdZSNAiB/9+5nAny2O9/lp2K2z5KVXqlNAHUmd4S/dpqtsZCbAo" + + "8Lcr/VYayrNojga1U7cyhsvFky3N9wczzPHq3r9Z+R4WnRM1gpRWl+9+xxtd" + + "ZxGfGzMRlxX1n5rCqltKKk6IKuBAr2DtTnxThaQiISO2hEw+P1MT2HnSzMXt" + + "zse5CZ5OiOd/bm/rdvTRD/JmLqhXmOFaIwzdVP0dR9Ld4Dug2onOlIelIntC" + + "cywY6AmnL0DThaTy5J8MiMSPamSmATl4Bicm8YRbHHz58gCYxI5UMLwtwR1+" + + "rSEmrB6GwVHZt0/BzOpuGpvFZI5ZmC5yO/waR1hV+VYj025cIz+SNuDPyjy4" + + "AAoJEHHHqp2m1tlW/w0H/3w38SkB5n9D9JL3chp+8fex03t7CQowVMdsBYNY" + + "qI4QoVQkakkxzCz5eF7rijXt5eC3NE/quWhlMigT8LARiwBROBWgDRFW4WuX" + + "6MwYtjKKUkZSkBKxP3lmaqZrJpF6jfhPEN76zr/NxWPC/nHRNldUdqkzSu/r" + + "PeJyePMofJevzMkUzw7EVtbtWhZavCz+EZXRTZXub9M4mDMj64BG6JHMbVZI" + + "1iDF2yka5RmhXz9tOhYgq80m7UQUb1ttNn86v1zVbe5lmB8NG4Ndv+JaaSuq" + + "SBZOYQ0ZxtMAB3vVVLZCWxma1P5HdXloegh+hosqeu/bl0Wh90z5Bspt6eI4" + + "imqwAWeVAdgESMYtmwEEAM9ZeMFxor7oSoXnhQAXD9lXLLfBky6IcIWISY4F" + + "JWc8sK8+XiVzpOrefKro0QvmEGSYcDFQMHdScBLOTsiVJiqenA7fg1bkBr/M" + + "bnD7vTKMJe0DARlU27tE5hsWCDYTluxIFjGcAcecY2UqHkqpctYKY0WY9EIm" + + "dBA5TYaw3c0PABEBAAEAA/0Zg6318nC57cWLIp5dZiO/dRhTPZD0hI+BWZrg" + + "zJtPT8rXVY+qK3Jwquig8z29/r+nppEE+xQWVWDlv4M28BDJAbGE+qWKAZqT" + + "67lyKgc0c50W/lfbGvvs+F7ldCcNpFvlk79GODKxcEeTGDQKb9R6FnHFee/K" + + "cZum71O3Ku3vUQIA3B3PNM+tKocIUNDHnInuLyqLORwQBNGfjU/pLMM0MkpP" + + "lWeIfgUmn2zL/e0JrRoO0LQqX1LN/TlfcurDM0SEtwIA8Sba9OpDq99Yz360" + + "FiePJiGNNlbj9EZsuGJyMVXL1mTLA6WHnz5XZOfYqJXHlmKvaKDbARW4+0U7" + + "0/vPdYWSaQIAwYeo2Ce+b7M5ifbGMDWYBisEvGISg5xfvbe6qApmHS4QVQzE" + + "Ym81rdJJ8OfvgSbHcgn37S3OBXIQvNdejF4BWqM9sAGHtCBIeW5lay1JbnRy" + + "YW5ldCA8aHluZWtAYWxzb2Z0LmN6PrADA///iQDrBBABAgBVBQJIxi2bBQkB" + + "mgKAMBSAAAAAACAAB3ByZWZlcnJlZC1lbWFpbC1lbmNvZGluZ0BwZ3AuY29t" + + "cGdwbWltZQULBwgJAgIZAQUbAQAAAAUeAQAAAAIVAgAKCRDlTa3BE84gWVKW" + + "BACcoCFKvph9r9QiHT1Z3N4wZH36Uxqu/059EFALnBkEdVudX/p6S9mynGRk" + + "EfhmWFC1O6dMpnt+ZBEed/4XyFWVSLPwirML+6dxfXogdUsdFF1NCRHc3QGc" + + "txnNUT/zcZ9IRIQjUhp6RkIvJPHcyfTXKSbLviI+PxzHU2Padq8pV7ABZ7kA" + + "jQRIfg8tAQQAutJR/aRnfZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr" + + "5dg50wq3I4HOamRxUwHpdPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO" + + "8LUJ2VTbfPxoLFp539SQ0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0Ft" + + "JycAEQEAAbABj4kEzQQYAQIENwUCSMYtnAUJAeEzgMLFFAAAAAAAFwNleDUw" + + "OWNlcnRpZmljYXRlQHBncC5jb20wggNhMIICyqADAgECAgkA1AoCoRKJCgsw" + + "DQYJKoZIhvcNAQEFBQAwgakxCzAJBgNVBAYTAkNaMRcwFQYDVQQIEw5DemVj" + + "aCBSZXB1YmxpYzESMBAGA1UEChQJQSYmTCBzb2Z0MSAwHgYDVQQLExdJbnRl" + + "cm5hbCBEZXZlbG9wbWVudCBDQTEqMCgGA1UEAxQhQSYmTCBzb2Z0IEludGVy" + + "bmFsIERldmVsb3BtZW50IENBMR8wHQYJKoZIhvcNAQkBFhBrYWRsZWNAYWxz" + + "b2Z0LmN6MB4XDTA4MDcxNjE1MDkzM1oXDTA5MDcxNjE1MDkzM1owaTELMAkG" + + "A1UEBhMCQ1oxFzAVBgNVBAgTDkN6ZWNoIFJlcHVibGljMRIwEAYDVQQKFAlB" + + "JiZMIHNvZnQxFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5IeW5l" + + "ay1JbnRyYW5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAutJR/aRn" + + "fZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr5dg50wq3I4HOamRxUwHp" + + "dPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO8LUJ2VTbfPxoLFp539SQ" + + "0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0FtJycCAwEAAaOBzzCBzDAJ" + + "BgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD" + + "ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUNaw7A6r10PtYZzAvr9CrSKeRYJgwHwYD" + + "VR0jBBgwFoAUmqSRM8rN3+T1+tkGiqef8S5suYgwGgYDVR0RBBMwEYEPaHlu" + + "ZWtAYWxzb2Z0LmN6MCgGA1UdHwQhMB8wHaAboBmGF2h0dHA6Ly9wZXRyazIv" + + "Y2EvY2EuY3JsMAsGA1UdDwQEAwIF4DANBgkqhkiG9w0BAQUFAAOBgQCUdOWd" + + "7mBLWj1/GSiYgfwgdTrgk/VZOJvMKBiiFyy1iFEzldz6Xx+mAexnFJKfZXZb" + + "EMEGWHfWPmgJzAtuTT0Jz6tUwDmeLH3MP4m8uOZtmyUJ2aq41kciV3rGxF0G" + + "BVlZ/bWTaOzHdm6cjylt6xxLt6MJzpPBA/9ZfybSBh1DaAUbDgAAAJ0gBBkB" + + "AgAGBQJIxi2bAAoJEAdYkEWLb2R2fJED/RK+JErZ98uGo3Z81cHkdP3rk8is" + + "DUL/PR3odBPFH2SIA5wrzklteLK/ZXmBUzcvxqHEgI1F7goXbsBgeTuGgZdx" + + "pINErxkNpcMl9FTldWKGiapKrhkZ+G8knDizF/Y7Lg6uGd2nKVxzutLXdHJZ" + + "pU89Q5nzq6aJFAZo5TBIcchQAAoJEOVNrcETziBZXvQD/1mvFqBfWqwXxoj3" + + "8fHUuFrE2pcp32y3ciO2i+uNVEkNDoaVVNw5eHQaXXWpllI/Pe6LnBl4vkyc" + + "n3pjONa4PKrePkEsCUhRbIySqXIHuNwZumDOlKzZHDpCUw72LaC6S6zwuoEf" + + "ucOcxTeGIUViANWXyTIKkHfo7HfigixJIL8nsAFn"); + + // + // PGP8 with SHA1 checksum. + // + public byte[] rewrapKey = Base64.decode( + "lQOWBEUPOQgBCADdjPTtl8oOwqJFA5WU8p7oDK5KRWfmXeXUZr+ZJipemY5RSvAM" + + "rxqsM47LKYbmXOJznXCQ8+PPa+VxXAsI1CXFHIFqrXSwvB/DUmb4Ec9EuvNd18Zl" + + "hJAybzmV2KMkaUp9oG/DUvxZJqkpUddNfwqZu0KKKZWF5gwW5Oy05VCpaJxQVXFS" + + "whdbRfwEENJiNx4RB3OlWhIjY2p+TgZfgQjiGB9i15R+37sV7TqzBUZF4WWcnIRQ" + + "DnpUfxHgxQ0wO/h/aooyRHSpIx5i4oNpMYq9FNIyakEx/Bomdbs5hW9dFxhrE8Es" + + "UViAYITgTsyROxmgGatGG09dcmVDJVYF4i7JAAYpAAf/VnVyUDs8HrxYTOIt4rYY" + + "jIHToBsV0IiLpA8fEA7k078L1MwSwERVVe6oHVTjeR4A9OxE52Vroh2eOLnF3ftf" + + "6QThVVZr+gr5qeG3yvQ36N7PXNEVOlkyBzGmFQNe4oCA+NR2iqnAIspnekVmwJV6" + + "xVvPCjWw/A7ZArDARpfthspwNcJAp4SWfoa2eKzvUTznTyqFu2PSS5fwQZUgOB0P" + + "Y2FNaKeqV8vEZu4SUWwLOqXBQIZXiaLvdKNgwFvUe3kSHdCNsrVzW7SYxFwaEog2" + + "o6YLKPVPqjlGX1cMOponGp+7n9nDYkQjtEsGSSMQkQRDAcBdSVJmLO07kFOQSOhL" + + "WQQA49BcgTZyhyH6TnDBMBHsGCYj43FnBigypGT9FrQHoWybfX47yZaZFROAaaMa" + + "U6man50YcYZPwzDzXHrK2MoGALY+DzB3mGeXVB45D/KYtlMHPLgntV9T5b14Scbc" + + "w1ES2OUtsSIUs0zelkoXqjLuKnSIYK3mMb67Au7AEp6LXM8EAPj2NypvC86VEnn+" + + "FH0QHvUwBpmDw0EZe25xQs0brvAG00uIbiZnTH66qsIfRhXV/gbKK9J5DTGIqQ15" + + "DuPpz7lcxg/n2+SmjQLNfXCnG8hmtBjhTe+udXAUrmIcfafXyu68SAtebgm1ga56" + + "zUfqsgN3FFuMUffLl3myjyGsg5DnA/oCFWL4WCNClOgL6A5VkNIUait8QtSdCACT" + + "Y7jdSOguSNXfln0QT5lTv+q1AjU7zjRl/LsFNmIJ5g2qdDyK937FOXM44FEEjZty" + + "/4P2dzYpThUI4QUohIj8Qi9f2pZQueC5ztH6rpqANv9geZKcciAeAbZ8Md0K2TEU" + + "RD3Lh+RSBzILtBtUZXN0IEtleSA8dGVzdEBleGFtcGxlLmNvbT6JATYEEwECACAF" + + "AkUPOQgCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRDYpknHeQaskD9NB/9W" + + "EbFuLaqZAl3yjLU5+vb75BdvcfL1lUs44LZVwobNp3/0XbZdY76xVPNZURtU4u3L" + + "sJfGlaF+EqZDE0Mqc+vs5SIb0OnCzNJ00KaUFraUtkByRV32T5ECHK0gMBjCs5RT" + + "I0vVv+Qmzl4+X1Y2bJ2mlpBejHIrOzrBD5NTJimTAzyfnNfipmbqL8p/cxXKKzS+" + + "OM++ZFNACj6lRM1W9GioXnivBRC88gFSQ4/GXc8yjcrMlKA27JxV+SZ9kRWwKH2f" + + "6o6mojUQxnHr+ZFKUpo6ocvTgBDlC57d8IpwJeZ2TvqD6EdA8rZ0YriVjxGMDrX1" + + "8esfw+iLchfEwXtBIRwS"); + + char[] rewrapPass = "voltage123".toCharArray(); + + byte[] secretKeyByteArray = Base64.decode( + "lQOWBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+" + + "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1" + + "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO" + + "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7" + + "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4" + + "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp" + + "AAf+JCJJeAXEcrTVHotsrRR5idzmg6RK/1MSQUijwPmP7ZGy1BmpAmYUfbxn" + + "B56GvXyFV3Pbj9PgyJZGS7cY+l0BF4ZqN9USiQtC9OEpCVT5LVMCFXC/lahC" + + "/O3EkjQy0CYK+GwyIXa+Flxcr460L/Hvw2ZEXJZ6/aPdiR+DU1l5h99Zw8V1" + + "Y625MpfwN6ufJfqE0HLoqIjlqCfi1iwcKAK2oVx2SwnT1W0NwUUXjagGhD2s" + + "VzJVpLqhlwmS0A+RE9Niqrf80/zwE7QNDF2DtHxmMHJ3RY/pfu5u1rrFg9YE" + + "lmS60mzOe31CaD8Li0k5YCJBPnmvM9mN3/DWWprSZZKtmQQA96C2/VJF5EWm" + + "+/Yxi5J06dG6Bkz311Ui4p2zHm9/4GvTPCIKNpGx9Zn47YFD3tIg3fIBVPOE" + + "ktG38pEPx++dSSFF9Ep5UgmYFNOKNUVq3yGpatBtCQBXb1LQLAMBJCJ5TQmk" + + "68hMOEaqjMHSOa18cS63INgA6okb/ueAKIHxYQcEAP9DaXu5n9dZQw7pshbN" + + "Nu/T5IP0/D/wqM+W5r+j4P1N7PgiAnfKA4JjKrUgl8PGnI2qM/Qu+g3qK++c" + + "F1ESHasnJPjvNvY+cfti06xnJVtCB/EBOA2UZkAr//Tqa76xEwYAWRBnO2Y+" + + "KIVOT+nMiBFkjPTrNAD6fSr1O4aOueBhBAC6aA35IfjC2h5MYk8+Z+S4io2o" + + "mRxUZ/dUuS+kITvWph2e4DT28Xpycpl2n1Pa5dCDO1lRqe/5JnaDYDKqxfmF" + + "5tTG8GR4d4nVawwLlifXH5Ll7t5NcukGNMCsGuQAHMy0QHuAaOvMdLs5kGHn" + + "8VxfKEVKhVrXsvJSwyXXSBtMtUcRtBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2" + + "BBMBAgAgBQJEIdvsAhsDBgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQ4M/I" + + "er3f9xagdAf/fbKWBjLQM8xR7JkRP4ri8YKOQPhK+VrddGUD59/wzVnvaGyl" + + "9MZE7TXFUeniQq5iXKnm22EQbYchv2Jcxyt2H9yptpzyh4tP6tEHl1C887p2" + + "J4qe7F2ATua9CzVGwXQSUbKtj2fgUZP5SsNp25guhPiZdtkf2sHMeiotmykF" + + "ErzqGMrvOAUThrO63GiYsRk4hF6rcQ01d+EUVpY/sBcCxgNyOiB7a84sDtrx" + + "nX5BTEZDTEj8LvuEyEV3TMUuAjx17Eyd+9JtKzwV4v3hlTaWOvGro9nPS7Ya" + + "PuG+RtufzXCUJPbPfTjTvtGOqvEzoztls8tuWA0OGHba9XfX9rfgorACAAA="); + + private static final byte[] curve25519Pub = Base64.decode( + "mDMEXEzydhYJKwYBBAHaRw8BAQdAwHPDYhq7hIsCT0jHNxGh4Mbao9kDkcHZilME" + + "jfgnnG60N1Rlc3QgS2V5IChEbyBub3QgdXNlIGZvciByZWFsLikgPHRlc3RAd29v" + + "ZHMtZ2VibGVyLmNvbT6IlgQTFggAPhYhBIuq+f4gKmIa9ZKEqJdUhr00IJstBQJc" + + "TPJ2AhsDBQkB4TOABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEJdUhr00IJst" + + "dHAA/RDOjus5OZL2m9Q9dxOVnWNguT7Cr5cWdJxUeKAWE2c6AQCcQZWA4SmV1dkJ" + + "U0XKmLeu3xWDpqrydT4+vQXb/Qm9B7g4BFxM8nYSCisGAQQBl1UBBQEBB0AY3XTS" + + "6S1pwFNc1QhNpEKTStG+LAJpiHPK9QyXBbW9dQMBCAeIfgQYFggAJhYhBIuq+f4g" + + "KmIa9ZKEqJdUhr00IJstBQJcTPJ2AhsMBQkB4TOAAAoJEJdUhr00IJstmAsBAMRJ" + + "pvh8iegwrJDMoQc53ZqDRsbieElV6ofB80a+jkzZAQCgpAaY4hZc8GUan2JIqkg0" + + "gs23h4au7H79KqXYG4a+Bg=="); + + byte[] pub1 = Base64.decode( + "mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + + "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh" + + "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB" + + "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p" + + "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5" + + "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN" + + "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE" + + "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1" + + "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu" + + "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y" + + "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB" + + "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u" + + "ZJhfg0htdgAfIy8ppm05vLACAAA="); + + byte[] testPrivKey = Base64.decode( + "lQH8BD89pyQBBADk1aljL6mBOvd6k4Myr/0yaSI94SPC5WDwuptXZNM92wy8FVZP" + + "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x" + + "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D" + + "AwKbLeIOVYTEdWD5v/YgW8ERs0pDsSIfBTvsJp2qA798KeFuED6jGsHUzdi1M990" + + "6PRtplQgnoYmYQrzEc6DXAiAtBR4Kuxi4XHx0ZR2wpVlVxm2Ypgz7pbBNWcWqzvw" + + "33inl7tR4IDsRdJOY8cFlN+1tSCf16sDidtKXUVjRjZNYJytH18VfSPlGXMeYgtw" + + "3cSGNTERwKaq5E/SozT2MKTiORO0g0Mtyz+9MEB6XVXFavMun/mXURqbZN/k9BFb" + + "z+TadpkihrLD1xw3Hp+tpe4CwPQ2GdWKI9KNo5gEnbkJgLrSMGgWalPhknlNHRyY" + + "bSq6lbIMJEE3LoOwvYWwweR1+GrV9farJESdunl1mDr5/d6rKru+FFDwZM3na1IF" + + "4Ei4FpqhivZ4zG6pN5XqLy+AK85EiW4XH0yAKX1O4YlbmDU4BjxhiwTdwuVMCjLO" + + "5++jkz5BBQWdFX8CCMA4FJl36G70IbGzuFfOj07ly7QvRXJpYyBFY2hpZG5hICh0" + + "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb" + + "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO" + + "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN" + + "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1" + + "3V73K298L8Lz09habWaq7aJx/znc0/SXX6w="); + + byte[] testPubKey = Base64.decode( + "mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F" + + "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO" + + "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F" + + "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4" + + "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG" + + "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc" + + "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs" + + "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrA=="); + + byte[] jpegImage = Base64.decode( + "/9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAAAAgAAAAAAAD/2wBDAAUDBAQEAwUE" + + "BAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/" + + "wAALCAA6AFABASIA/8QAHAAAAgMAAwEAAAAAAAAAAAAABQcABAYBAggD/8QAMRAAAgEDBAEDAwME" + + "AQUAAAAAAQIDBAURAAYSITEHIkETFFEjYXEVMkKRCCUzQ4Gh/9oACAEBAAA/APX1TdKCmlaOoqoo" + + "WXzzbiP9nWaS71lXuA2tqrgopBOxpyGyWLAEEd4GAf3+fOjLPXoVaOcNzYAhl8HskADwAPz37f3z" + + "opSvI9Mjypwcr7l/B1XuFwSmoTVooljB9xDYAH51Vor191F9dKGb6Py3yo4huwcHwf8AYP7ZLIyu" + + "gZSGBGQQejrnU1NKn1EqVi3sZJOBCwxxIp9xzksfb5PR+Mdga+ljqIKje1TNBBNToYYgU4477HwQ" + + "Bn9z8/nW6mqxLR0NzpJkMLx8lJUkOGAIx4I/0f41lJ93UkkrRxVKvNKVjZfpSe6RyqhCp7wCSD89" + + "EEDRWppEkgqKdYohGcoZAjAlSMMcZ+PHH/3odsG6VLW2qaoqV+nTyFZpHOFQL0Sc9ADGTnHWtZap" + + "EpoamJm/TgYkfgJ5H/zGuKieVJIGkqCgmfCJFFy64s3Z+Oh58fHyNfGavipIJ2BrZcKXA+mzEd9Y" + + "OCcHI/gDV62SzvBGKhQHaNWzj8jvP750oN/xM3qkshLPEstOhj7IVyvkY+f7Nd7hf9vbc9QbVb7n" + + "dadLldqc00FMCwlmZnCrgL2v/cAySPBPwSD+/wC+3HbWx3rLbaqW81CVHOWnetMZjRm9h7VvClcj" + + "oDB7PymPTvem+a6roxvC10sd3ScmlucdEyUtRADxdice9wY3PQGRgj4OnHU3u5RW+op6imo4q+KA" + + "1UKGQ/bzrnt0biWxkgFOJK9ZyCCVX6f3T1Rh9RawbltdQNv18CGe2wxBDQyvGrowIJd15HEnHvP+" + + "OBjXoGzS0tNTpQipFTIw48Xn5SSBVUMw5e5wMgZ/j86yVNvvZ9TeDR1c9XSV0bl443dmYZXiCSCR" + + "jvxkjR1L1b46iWpStpIRLOWkCqyniP8AJjxPIniBjr+etFdu11DVu321WZiFHRjZcA/gsO+seNYf" + + "fVpq6n1Eo5KNATIYmb5Bx7csP4z/AKz8aX1N6Q7W3FuWWrS1TRzi+tXSutUESQhCGiVAvJVRgfcc" + + "HkeidM6tSmTbps9RHIH4KoqC8j/VC8R0+CSScZLdknPZGgNfYpUUUzfewxxcWpopWbhL715KgBIQ" + + "MCQc4A84+dD963X7ywQ0NIVW60qqzkzIfoszAMGUNyUHORkDrHxo3sSaOhtX2hnp3uNRF9b7hqtO" + + "DxM3Rcj3dMCPHXLGfOkLuPddp9R/ViOa62KppqK3Vctvsz0UylKtWfgXy3+L8WIZFBGRhs407rTT" + + "bcuFDRWmtsNGIZ1MMEU9GPqRorKPcJEzhich8Anz350Wk2zs2OsT7D7RZJpChMEk0MoypJZWVwM9" + + "ZzjWw2lbKaioFjQy/U9shLyu7Esi5JLEnsgnQlaSqhqayWSRZ5JaiSSNPoBCiq54jPuJyA2W+QfA" + + "+FrSXq4bdulZHRpWRzpArPK0SSNUExh14qB4c5X9ipz41Zud0juVouVooHN6rrZKVaoek/VhYgqE" + + "4v7cZPTfPHwT7tZX0e2NVUV5rK2ku9TeY6aFZJ6GuLALKzNnizE4CsqHIyBxJCk4AYFNt2wSUExm" + + "pP1lqgq1zkfXUtIgkiOFHQCsCM/kfOtZU7GsNZU1FFc1lrqCSNSlFOQ8SJk8kC4/tJx1rMwbWt0V" + + "CW21VW+krVoFTCRrPC0bf+NF8ocqMcT/AIg6EVF5/p9U6zPXLVFGpoKlSpMiEkniSCcqVY+eQIPW" + + "NULf/UNxJNS0dhklu8SK9Lco6pUcEr0JOu1HQ7z+R5OndaI5leWV0VQ54kA5KlWIx/Gqd2t6vcqe" + + "FIXNJMs71SoCMsQuG5jsN8AAjyTnrGlt6mVlqswtS0SG71NTXpSiCQFpogckll6Y4wvyD/OToVd7" + + "3tLedda4Nr3iRK2mqJhW1K0qxSSGJf1OTOAwwVADLkA9fPV2W77msVfPTClNRUyJCla0SqS5dR5J" + + "b2kluKlQc5BbHnWu2xTS0G4qmjvSq6RwrPHJUMHkkYDhzJHXIhmBAHnxpaL6j3il3D6g1VLuSz1k" + + "1ht//S6SZQ4KoTI6MyMOb9hR85HedM/0wqn3RsC0bhgq/pQV9J9WELEFaNWGARg+04xkd95xjQTe" + + "df6c7U+ysl3mtMFJe5JYGkkmAVKgKZCZGzlVbBySemA/OgvpZUQxvaqitgoqSsiX6XKh5RwVCBP0" + + "8KCTIoU8VJyDjIA8Bs2e5CprDTR8VXi8pRgyyZMh8qQMDHz850ZOlVv30RsW5blcL5S3a626+1cq" + + "TirFQ0qJIgAQCNjgIMeFKn9wQCMA3o2vprca/ctp29Jv6/3aoZ4IRRx08dC5D8nWQv7FJYHByeuv" + + "zo5SWn1Z2ttahutFZqbcG6JK5ZLu1TNEzzUq5ASNyVw6pxUMc5Oc5znR6KyXffldUVW4rBcbAqos" + + "EUq1qrUzUkwy8bFB+m4ZI2IBbAJAbOdau0+nmybJYqe027atvNHTRlYomhVz+Tln8knyScn50j/+" + + "SOyd3VO2oDtmPcNPYqJgDt23xKtOIiTy6gYO/Z5YOcAHGsJ/x39NgbzuDc+0bNt6/wAySmltbXGv" + + "flaT8ST07xBjIR30RjsL+dex9uwT/wBKo6i5UtPFdHp4/u/pgECTiOQDYBIByB+w0RVEVmZUUM39" + + "xA7P867ampqampqaq09BQwV9RWwUVNFU1AUTTJEoeQLnHJgMnGTjP51a1Nf/2Q=="); + + char[] pass = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'}; + + byte[] encMessage = + Base64.decode("hH4DrQCblwYU61MSAgMEVXjgPW2hvIhUMQ2qlAQlAliZKbyujaYfLnwZTeGvu+pt\n" + + "gJXt+JJ8zWoENxLAp+Nb3PxJW4CjvkXQ2dEmmvkhBzAhDer86XJBrQLBQUL+6EmE\n" + + "l+/3Yzt+cPEyEn32BSpkt31F2yGncoefCUDgj9tKiFXSRwGhjRno0qzB3CfRWzDu\n" + + "eelwwtRcxnvXNc44TuHRf4PgZ3d4dDU69bWQswdQ5UTP/Bjjo92yMLtJ3HtBuym+\n" + + "NazbQUh4M+SP"); + + byte[] sExprKeySub = + Base64.decode( + "KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOmVjYyg1OmN1cnZlMTA6TklT" + + "VCBQLTI1NikoMTpxNjU6BJlWEj5qR12xbmp5dkjEkV+PRSfk37NKnw8axSJk" + + "yDTsFNZLIugMLX/zTn3rrOamvHUdXNbLy1s8PeyrztMcOnwpKDk6cHJvdGVj" + + "dGVkMjU6b3BlbnBncC1zMmszLXNoYTEtYWVzLWNiYygoNDpzaGExODpu2e7w" + + "pW4L5jg6MTI5MDU0NzIpMTY6ohIkbi1P1O7QX1zgPd7Ejik5NjrCoM9qBxzy" + + "LVJJMVRGlsjltF9/CeLnRPN1sjeiQrP1vAlZMPiOpYTmGDVRcZhdkCRO06MY" + + "UTLDZK1wsxELVD0s9irpbskcOnXwqtXbIqhoK4B+9pnkR0h5gi0xPIGSTtYp" + + "KDEyOnByb3RlY3RlZC1hdDE1OjIwMTQwNjA4VDE1MjgxMCkpKQ=="); + + byte[] sExprKeyMaster = + Base64.decode( + "KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOmVjYyg1OmN1cnZlMTA6TklT" + + "VCBQLTI1NikoMTpxNjU6BGqcUsIHwQRmQAQs2rOeTzJBq79/U8AJRNT9B72O" + + "XJtzbZs7nkF29l0WhrdGY1AeFH3zT8p5XAJDdw+l7o5AkUApKDk6cHJvdGVj" + + "dGVkMjU6b3BlbnBncC1zMmszLXNoYTEtYWVzLWNiYygoNDpzaGExODr4PqHT" + + "9W4lpTg6MTI5MDU0NzIpMTY6VsooQy9aGsuMpiObZk4y1ik5NjoCArOSmSsJ" + + "IYUzxkRwy/HyDYPqjAqrNrh3m8lQco6k64Pf4SDda/0gKjkum7zYDEzBEvXI" + + "+ZodAST6z3IDkPHL7LUy5qp2LdG73xLRFjfsqOsZgP+nwoOSUiC7N4AWJPAp" + + "KDEyOnByb3RlY3RlZC1hdDE1OjIwMTQwNjA4VDE1MjcwOSkpKQ=="); + + byte[] testPubKey2 = + Base64.decode( + "mFIEU5SAxhMIKoZIzj0DAQcCAwRqnFLCB8EEZkAELNqznk8yQau/f1PACUTU/Qe9\n" + + "jlybc22bO55BdvZdFoa3RmNQHhR980/KeVwCQ3cPpe6OQJFAtD9OSVNUIFAtMjU2\n" + + "IChHZW5lcmF0ZWQgYnkgR1BHIDIuMSBiZXRhKSA8bmlzdC1wLTI1NkBleGFtcGxl\n" + + "LmNvbT6IeQQTEwgAIQUCU5SAxgIbAwYLCQgHAwIGFQgCCQoLAxYCAQIeAQIXgAAK\n" + + "CRA2iYNe+deDntxvAP90U2BUL2YcxrJYnsK783VIPM5U5/2IhH7azbRfaHiLZgEA\n" + + "1/BVNxRG/Q07gPSdEGagRZcrzPxMQPLjBL4T7Nq5eSG4VgRTlIDqEggqhkjOPQMB\n" + + "BwIDBJlWEj5qR12xbmp5dkjEkV+PRSfk37NKnw8axSJkyDTsFNZLIugMLX/zTn3r\n" + + "rOamvHUdXNbLy1s8PeyrztMcOnwDAQgHiGEEGBMIAAkFAlOUgOoCGwwACgkQNomD\n" + + "XvnXg556SQD+MCXRkYgLPd0NWWbCKl5wYk4NwWRvOCDFGk7eYoRTKaYBAIkt3J86\n" + + "Bn0zCzsphjrIUlGPXhLSX/2aJQDuuK3zzLmn"); + + byte[] dsaKeyRing = Base64.decode( + "lQHhBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ" + + "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV" + + "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/" + + "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug" + + "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu" + + "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ" + + "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz" + + "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej" + + "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbP4DAwIDIBTxWjkC" + + "GGAWQO2jy9CTvLHJEoTO7moHrp1FxOVpQ8iJHyRqZzLllO26OzgohbiPYz8u9qCu" + + "lZ9Xn7QzRXJpYyBFY2hpZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNh" + + "c3RsZS5vcmc+iFkEExECABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j" + + "9enEyjRDAlwAnjTjjt57NKIgyym7OTCwzIU3xgFpAJ0VO5m5PfQKmGJRhaewLSZD" + + "4nXkHg=="); + + private static final String TEST_USER_ID = "test user id"; + + byte[] rsaKeyRing = Base64.decode( + "lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF" + + "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd" + + "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy" + + "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y" + + "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7" + + "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO" + + "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP" + + "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY" + + "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb" + + "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4" + + "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj" + + "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I" + + "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH" + + "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt" + + "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j" + + "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw" + + "AgAA"); + + byte[] p384Protected = ("Created: 20211021T023233\n" + + "Key: (protected-private-key (ecc (curve \"NIST P-384\")(q\n" + + " #04CE6089B366EFB0E4238CC43CBC6631708F122AEFF3408B9C14C14E9A2918D0BD18\n" + + " D800FD90D6FB4142387913E14F78CA232B91A6C87BFE2841778A99D96EB292E6311E81\n" + + " FEA3D40CE62F4B9641A481846C119AFDE08AE91DC7B7F705280FF077#)(protected\n" + + " openpgp-s2k3-ocb-aes ((sha1 #E570C25E5DE65DD7#\n" + + " \"43860992\")#83D43BA89B7E7EA2EF758E52#)#CD30B49842A95DD0D18C2D8550CC59\n" + + " 8187FE6DE7386418A319F7311197FE4344EE29ACC0B77D2EDF19E268DBB2130F82353B\n" + + " 319D39306CDA53C6D9F883141738B522E35F6F9CD346B4B187578C#)(protected-at\n" + + " \"20211021T023240\")))\n").getBytes(); + + byte[] p384Open = ("Created: 20211021T235533\n" + + "Key: (private-key (ecc (curve \"NIST P-384\")(q\n" + + " #041F93DB4628A4CC6F5DB1C3CFE952E4EF58C91511BCCDBA2A354975B827EE0D8B38\n" + + " E4396A28A6FE69F8685B12663C20D055580B5024CC4B15EECAA5BBF82F4170B382F903\n" + + " C7456DAB72DCC939CDC7B9382B884D61717F8CC51BAB86AE79FEEA51#)(d\n" + + " #5356E5F3BAAF9E38AF2A52CBFAEC8E33456E6D60249403A1FA657954DAE088AA9AA7\n" + + " 9C2AA85CEEA28FE48491CE223F84#)))\n").getBytes(); + + byte[] p256Protected = ("Created: 20211022T000103\n" + + "Key: (protected-private-key (ecc (curve \"NIST P-256\")(q\n" + + " #048B510552811D0BE5B6324D7D3FF4CA9CC4B779A875CB7289AE2EDA601E212E3F78\n" + + " 9A8F58A7BD6D7554BCEBA9D5F59CC2FD99C7865FF47AA951878128837A6299#)(prote\n" + + " cted openpgp-s2k3-ocb-aes ((sha1 #43AA7C9708083061#\n" + + " \"43860992\")#C246761F0A03FE624368BDBC#)#2C1D62FA0C79319653A4053C5ACAA1\n" + + " B1EB657029F2A94F35D09CD1514A099203B46CDF1AEECA99AE6898B5489DE85DDA55A7\n" + + " 9D8FD94539ECCCB95D23A6#)(protected-at \"20211022T000110\")))\n").getBytes(); + + //https://github.com/bcgit/bc-java/issues/1590 + byte[] curveed25519 = ( /* OpenSSH 6.7p1 generated key: */ + "(protected-private-key" + + "(ecc" + + "(curve Ed25519)" + + "(flags eddsa)" + + "(q #40A3577AA7830C50EBC15B538E9505DB2F0D2FFCD57EA477DD83dcaea530f3c277#)" + + "(protected openpgp-s2k3-sha1-aes-cbc" + + "(\n" + + "(sha1 #FA8123F1A37CBC1F# \"3812352\")" + + "#7671C7387E2DD931CC62C35CBBE08A28#)" + + "#75e928f4698172b61dffe9ef2ada1d3473f690f3879c5386e2717e5b2fa46884" + + "b189ee409827aab0ff37f62996e040b5fa7e75fc4d8152c8734e2e648dff90c9" + + "e8c3e39ea7485618d05c34b1b74ff59676e9a3d932245cc101b5904777a09f86#)" + + "(protected-at \"20150928T050210\")" + + ")" + + "(comment \"eddsa w/o comment\")" + + ")" + /* Passphrase="abc" */ + "MD5:f1:fa:c8:a6:40:bb:b9:a1:65:d7:62:65:ac:26:78:0e" + + "SHA256:yhwBfYnTOnSXcWf1EOPo+oIIpNJ6w/bG36udZ96MmsQ" + + "0" /* The fingerprint works in FIPS mode because ECC algorithm is enabled */ + ).getBytes(); + char[] dsaPass = "hello world".toCharArray(); + + byte[] dsaElgamalOpen = ("Created: 20211020T050343\n" + + "Key: (private-key (elg (p #0082AEA32A1F3A30E08B19F7019E53D7DBC9351C4736\n" + + " 25ED916439DB0E1DA9EC8CA9FA481F7B8AAC0968AE87FEDB93F9D957B8B62FFDAF15AD\n" + + " 1375791ED4AE1A201B6E81F2800E1A0A5F600774C940C1C7687E2BDA5F603357BD25D8\n" + + " BEAFEDEEA547EB4DEF313BBD07385F8532C21FEA4656843207B3A50C375B5ABF9E9886\n" + + " 0243#)(g #05#)(y #7CF2AF5A729AE8C79A151377B8D8CF6A5DC5CB6450E4C42F2A82\n" + + " 256CAA9375A0437AA1E1A0B56987FF8C801918664CF77356E8CB7A37764F3CC2EBD7BB\n" + + " 56FFBF0E8DA3B25C9D697E7F0F609E10F1F35A62002BF5DFC930675C1339272267EBDE\n" + + " 6588E985D0F1AC44F8C59AC50213D3D618F25C8FDF6EB6DFAC7FBA598EEB7CEA#)(x\n" + + " #02222A119771B79D3FA0BF2276769DB90D21F88A836064AFA890212504E12CEA#)))\n").getBytes(); + + byte[] theKey = ("Created: 20211022T050720\n" + + "Key: (private-key (elg (p #009015DEBF6AA2B801EB39EEABC20914FDBD26D8A40B\n" + + " 6343D99F3328CEF0B76748DDC23840C0D404BE9AFF61590816D630513C5D7D73359DBE\n" + + " E6FD0E79D5204C518113941AFACA4D8FD608AD659C4EC9DC5ABDF884C0DA7067CB7084\n" + + " 161D9CDB06D6057DC6FE21C8213FC18F070CD2F53249E22F00B99EE315CB1191848C92\n" + + " 43C05A453BF2CC3D20A0EA0AE097B9034A7FCA79C279D67EB82CFFD50E54630E73D020\n" + + " C7248B1EEF6225FA82067CF3DCB40F0614F87949E917E3208CA354A22EC10B65DC1065\n" + + " 59BEE3DE9B4C03CC65DA8C00F0DA8D19F08CB070BE65D9BF1986A680CAA3CC9A109756\n" + + " C7F36F48D9902A4D51EE05577C309797F68A3917B28506554E32324226EA3CDF372CD5\n" + + " 0BD86BA12AACB00EE962D93A621826A225B7C35C65A036DCB7820CAD7C904D1DD6F976\n" + + " 2ADE5E7B528AC162C5DC0C3A833A6BE3465E97D835CA862BD7ECDF8A6AE2645D607BD8\n" + + " 067C110C437C9FCC83A7A113DBB12CAD522FCA8E068054D0AF84B0EA45DCA11D3FE875\n" + + " 1A5A25A84CCE04132FEAB7B993#)(g #06#)(y #5F298179167DF1A10F0260CC2C1916\n" + + " B0F72AFE7FC173049B28AFEDA196D730FC8667D3E4F11EB51EF9965ADE15D0218C72B0\n" + + " 64E6501E20BD9013CF2B6EC4350D7666F3E7ABBFE7C982664FDE1B70FDE24C9BDE80AA\n" + + " 974D46F4723F111B0F6402848694D45FADBD38A5FAF3A17CDF1C8BEC35C6E83841A37A\n" + + " 68D1B18CE2D5A30DBEDBC660D2074A3C4F4BA8DD724CF3FDB3C0CF21B5BF26AD24D5AE\n" + + " CFED47001EBAA9231D756AC75A18BB2DF2F86ABD52BABBAD9E9A53890126B990773595\n" + + " BBE9E9CB8E7505260C07725C3036339C5C1A40B0AF62C534F1E049FC130C78856FD070\n" + + " 69CFFD1316FD853CABEF72C8DAF268EC0C3F7404085C0336A86C3BB5AC5B4414AA42AE\n" + + " 26B24A0D87B1AE494766E3D4A14FFCB287E59260AE5EB952F31ADC01DF4F947EFFAF0E\n" + + " 1F999A3C3F8E8ABAD24B3B56DC140970F22384C8821481E128F6B18D779F27D9492B88\n" + + " A0EBB72CCB13AB07038448ADDF4A3D00F62E3EC2724730CC052C0C9385469CA364C9FD\n" + + " 5BAAE4CCBF8635DD034B3FBEBBC2E656DB77A6#)(x\n" + + " #0CE0A6B334E053051076D64AFB091C1B585758BC03B1D66A3BEE0C0487707DBE8CBF\n" + + " B4FD7A5640C3536243CC298017781127B9#)))\n").getBytes(); + + byte[] dsaProtected = ("Created: 20211022T053140\n" + + "Key: (protected-private-key (dsa (p #00CD7275234699FE0D25FDBEE69DA2AA80\n" + + " AAAB15906FACFC8F4EB5A9BAE23D22E5649199C119FB72951BD0FA717F51CFD7B904FD\n" + + " BB1F0D0660938199976DA4447F54E91E2CC4B21F4BB162644EA43A3F27F7CAFF7D6355\n" + + " 16E8640558E222EF20B55E8AF2AFD33D571092CE5C090E57DA3452484BC04398E24613\n" + + " D593113F1F5CE7CA3229F5DFAFC1EFC47B725505E46A0EB9CC45FACFBEA6ECC6CA694E\n" + + " D3781E011C48C66BBB6C1BA35DD810EF24CF7B92D9E9BCB0B0E19053CFA073AD2D9957\n" + + " 270B3C55D60824F93EECBF8AF393F07C05BEA38636DFC6B6152424FAF5C0287435C145\n" + + " B021E235AA30E2B063695EE01D6C696EAA381517E50A440D8AA00164B423#)(q\n" + + " #00A4F8D3DC79F1F8388B9FF3F3A484568A76337BF968F05C207F5AF8E84F4B83C1#)\n" + + " (g #32EC716A63D63CB69E17A678B9BC70686EA24AF4F96F46683E09ACF7EDE9839ADB\n" + + " 914E61A38D151B28B65533362100B1D9D2948FD8617136FF82C8B61DF5A400B3D2A3E3\n" + + " 2CEAF2B7DAEBF30D24CA3E681AC551F01EC366EECCDF1481B092E3534728D73211D962\n" + + " 09069E8FA34395C94828D77F0FEF8E6DEFEA3687ED6267EB028007B84840E383E8B14C\n" + + " AB93109FA414458E56F5BDAF7AB37ECB3E3FA8EDAED60B7323D3329FB3EA4E460FFA63\n" + + " B9EC9836530B16710A0EA3A750BF646A48DA65E4144A9A7964513BF998755612791DC5\n" + + " F840FAE54D34C44A62C1BE884774870BC6D0505FE5EE3F4B222194740E4CC639785E56\n" + + " B93E17DCACBFE63703DE201DB3#)(y #1B1DAAA76ACF531DBC172304E6523C16B3E701\n" + + " 2B8B3F0D37AFD9B2C8F63A2155F2CAAE34ADF7A8B068AB266AEE5A5598DD9BE116FA96\n" + + " F855AA7AD74F780407F74255DC035339C28E1833E93D872EE73DE350E3E0B8AB1E9709\n" + + " B835E58E6A5491383612A52EB4A3616C29418C0BE108739CC3D59BCF3B0299B283FEA6\n" + + " 7E21A1909C2E02CD1BFE200F0B6EEE0BB8E4252B8F78711AD05C7056CE673ED81BE265\n" + + " 60C0768AEC8121D5EB21EE6A8338CC35E306931D1B3516767E345B9C25DF7454C36C61\n" + + " 739B193BC4998A47A4E5A4956FF525F322DA67B9DC6CFA468ADEBC82EBEEB7F35C4982\n" + + " A2D347ED4ECB8605387161F03175A9D73659A34D97910B26F8027F#)(protected\n" + + " openpgp-s2k3-ocb-aes ((sha1 #4F333DA86C1E7E55#\n" + + " \"43860992\")#D8BD10519B004263EC2E35D4#)#57553ACF88CB775B65AAE3FAEB2480\n" + + " F40BA80AFEA74DD1B9E59847B440733B3A83B062EAD3FDBF67996BA240B8504800C276\n" + + " AAF1DE797066443807DDCE#)(protected-at \"20211022T053148\")))\n").getBytes(); + + byte[] dsaElgamalProtected = ("Created: 20211020T032227\n" + + "Key: (protected-private-key (dsa (p #00A68CA640389B919C51552D9303E8F822\n" + + " 8F3C3083DA2D1F366349F2B3D67C9ED2B764448D4EF0579B466CEAF08C9B8477763470\n" + + " D3BED70784B015F40067F17352B3A4EAF74CBC709000ACD58D64A79332CD828505A1D8\n" + + " C11A083DE64318093F41AC2004CBDB941B14881183D64467C5C24FFE30A979EF5678D9\n" + + " 2995D7AC07F3AB#)(q #00DEBBC5AB44F5652BF5FF4FF69FB08199D9652299#)(g\n" + + " #4A55C07638DAF38D0A50E4BC53DABDA0B858E94AF923F6B827FCA17B074C598E284E\n" + + " 1702E1037CCD0608653E8466150AD74071DB6882A6989EC470160F795F45B5BDB93A42\n" + + " EECC70239615B06CC2B9DD8CDA6097F8A62FF5EB352E913489D579CC6FE01B8EB6E4CE\n" + + " EF841B3A88021B2D401025BD6C4374812435B67DBD8D3CDD#)(y\n" + + " #01AEF2EFC956D068EB0C37EC6185BCB37FA1ADE2585EBBF9D9AC5133FAA864BAA12C\n" + + " A6CDBB90205BE0952EE9A98A1FD05304DBA4EE82CD748EA3E555A263FD6B7D9AA88E03\n" + + " EED6D7FF74C432F32469470F07776B52A2B78B58F86F42BE5783A46D6266FC61CFFDC3\n" + + " D7E59749C69E96ABD393DF4B903101F4CDD6E79547F951B9#)(protected\n" + + " openpgp-s2k3-ocb-aes ((sha1 #CB4E8FD129B52F0C#\n" + + " \"43860992\")#431AC92BE18B28ED57E69D7B#)#9EDA98358105572FBE507A49A19AAF\n" + + " A897DFE1E3251E5E1716D77E63930FE223E66F7258B9F080B9B2302075E60E0CBD#)(p\n" + + " rotected-at \"20211020T032236\")))\n").getBytes(); + + private final byte[] protectedRSA = Strings.toUTF8ByteArray("Created: 20211017T225532\n" + + "Key: (protected-private-key (rsa (n #00BDA748AF09EC7503A3F201E4F59ECAA4\n" + + " C52E84FEA5E4D7B99069C3751F19C5D0180193CA2E4516B5A9ED263989E007040C1C1D\n" + + " 53F2D8B7844AEFF77FE28C920ACE0C0F5A77A95536871DD03878BA1997FAE6368E133B\n" + + " 5CCCB13B4500F99FD211CB6EF42FAF548BB9BEDAA399A0085F85F9CE3268A03276C31E\n" + + " 33313F1826A9DB#)(e #010001#)(protected openpgp-s2k3-ocb-aes ((sha1\n" + + " #0D1568A73CF5F7C6# \"43860992\")#E5DF4BA755F1AC410C4F32FA#)#CFF9000F22E\n" + + " 0948B2D3BB1E78EEDB42D2361C3A444C94D02E17CDBC928B0AA21275B391820944B684\n" + + " 757088F76D6CB262768FBB1B06067FECB04E02C5A1A6C2CF18896A30166D6231CB3179\n" + + " FD0567D03C207C04EAE6523F77302ABDBF8294D90D197B875BCEBB564CCD0DE264D8BA\n" + + " C921DA23A21C4F7D2DD12A2E4EF20ECFEB2DABD273A2270B2AC386ECF2DCDE90D5FDDB\n" + + " 00261814082A710A0347C57F7326E18FBE5E4D0F67B6912A903A58984E244D8A487921\n" + + " 2712200205123AE58E7CB2457518611678C086F319CF7BED4A675E79CA8BC9DB810025\n" + + " C5EEA8BD0D980787003992A72C005DAEC32604767ADF91AF180DB58260B21A1996240F\n" + + " E6225B066EA9A8979E590B1BC85F44796903A2738B7871F52F4F27032AC86B25F38E07\n" + + " 4E12CEB9ECBCD6995D03DA57710EC54A6E60B79283389BD2869FF7B7C65623C59E0B40\n" + + " 621802DEDA97B167C806B45E0CB3A2CE4C60CD7D7FCE763F7B57EDC226AF7F05B07234\n" + + " 32C910DD00AD4FD29FE159AEB19E084E9AC76CE#)(protected-at\n" + + " \"20211017T225546\")))\n"); + + private final byte[] openRsa = Strings.toUTF8ByteArray("Created: 20211014T044624\n" + + "Key: (private-key (rsa (n #00ED5B77E0107AFC1D066B4010E9B951451974E9B49E\n" + + " 6741E0CF742427EB14587D1250DC52F7F820E9587B3714681702C5BC4BFDBE06DCE886\n" + + " F87DF730857A045FF9A72195E04B23E742136CBFE3FA363AF5788BAE55E3BD02A54E2B\n" + + " 3A52FB2B32B48FECD8780D07E2298983031AB97ED6C0A47A73778C5B2AF3BF93C7CFEF\n" + + " 1325974A850096F3A73559A5B3DBF63A3246D94D4B6696D08CBFDC8678A8969E00EB17\n" + + " 2EBC47AF31C61BC412D843F1DDE2BA95404734982687463296DC033901A030A1D5B3BC\n" + + " 2CF00F3B1F825903E8FD47E390B82A4236EF2DA3502DE0EF6E56D00512578FA3E7C746\n" + + " 89FAB557B4E47CD736BC1B0756775B06CBB19CFF429843923E6D05447E5ADEA30DED61\n" + + " 24D1FD9C5FC8DEA2706624CFEB2B63DB0713CDCC3FA071B7256BBC497A3EA50D9E0B4E\n" + + " AD15F982291D032B4999AC10D22F5C1B2BCACDCE8F4F66497087A11430A5167D8ABAE0\n" + + " C76919356BD5B460026080502BF1279807398FCB64E03E42772B823C78A8B67DBA9EAF\n" + + " B6C4F0CFBD09BD7068A7D47873#)(e #010001#)(d\n" + + " #197102750BE482D2D6F5F6AA0418B9B35465345FB3283CE6CC95C057B45A3BEF3C0A\n" + + " B01DB1E29B747CE81D769C7EF5971DA06F9447715FA332A373341F8FD2998EF84675FA\n" + + " D2A85DDE0BEDA38130E2A5DDDB36985085D6A3F54AB456236ADF587CAE28A43DF4A247\n" + + " 05A36DB2E42719DCB44D6CFFFA17C5F5E151443FD89E8C48D7E1EEF0FF3D22A114A384\n" + + " 41D6D9FF659A092F99D1748D2C4B864661F10857EF85A3F173D03D8A39E901B418A450\n" + + " DF95419B8ADBAD00AEE34157964194D7586F692FC73FCF70B3B56A934ACCCDE0D74F02\n" + + " FF01760AFC84CCCAD66C1A1BFFEA4C63747D1612B5EB25198F62C5F7BEA7A52674482D\n" + + " 1B77A5CC1F9963D969C3B266798D166B652769CFFCACA28886E03F1BF7ECAE04B7D1B0\n" + + " 7FC907D1FC156DE2E4898CFE9F08876D9E24E744CE01DBAB1170F3F59E41AC2383AAC0\n" + + " 41A10DD394C08D1F44F987F386BE32A4AB805B1EDBA85CDDADA542DDEE2FC1FCBDFB1C\n" + + " 0809046CB4C7B24B2EBC3EA51F015AB0A39499820F06E6B7D32EE870E8651C30A282B1\n" + + " #)(p #00F2E626FF576CCB9684AE2698FD7ACA63543D8D28B2E75D6B7BB48C6F2A3C3A\n" + + " 7BF484F5E0DEAEBA6C59B1114C696C26C5FFE318E213EAB8CD3AB252B0DBB69A5FD642\n" + + " 17A55AFE5B899CE16E21E1CE7D655B7248C672BB2D1A4FF23B1E807C9361DDFAB82090\n" + + " 6E82B634EE9E607BDAD32039E1E19C3B15FC4FC1EFC356814A3992D476B0F6E8E98A6F\n" + + " 9CB77FEDAA7F6F56B134FAB3EB0FD8D7D2FF22E2FFE890338AF666401BD0732BA236E6\n" + + " 69C20F5F9C2F31487647CF8589D483DFDFC98FF3BD#)(q\n" + + " #00FA28CC48F1C61B80B5D1CA48C8DA6B9FFAA9891D6F6E90EDF607B71278C03E4174\n" + + " 48380CC1477786572A5BA43A772A37397B4DC362B4E495B999D0A494599A154DC556AA\n" + + " A8D852E8AF5FB26B0EF8EFABA1C6CFF0883AC70092F6CD6B5FD9834A964DDA41D93BFF\n" + + " 464344DC89CE6951F1BF39CCD9B60630101BB8A4F89307EECFAB43AAACCF7E824B0C39\n" + + " EC647898CFB5CC9C8BD33087D144334C471ABCCAC525EF5AA425D8388EB6AB72900D0B\n" + + " F04BBD076F819F242A026BC630615B2758C7EF#)(u\n" + + " #613BFCE8D7910CE3C4B9CFBADE79563290A834B67C68C616C8177F6937FC522E4204\n" + + " 5C80769FDF35DBA3BE23CC623EFFEEA4B74B72F6A46EC2A876EC37D9CB65FEDEDB05AF\n" + + " 62F69A62A911D60DB3C8E7D2B9C6122F9ACF4E39FABF1E7F83EF119A70ED9B02F5FAA9\n" + + " 6ACFEA7E735E008F77E7F829FC6B669C72665D7E2E21DE85C66840E76FA200F832980B\n" + + " 587BCE3AE6F748A85EF2E2BDFDCAAFF52E27752159A80E00B5B241AB45839820520F2F\n" + + " A8B62E956F307061CB26915408CF2F014824#)))\n"); + + static + { + Security.addProvider(new BouncyCastleProvider()); + } + + public static void main(String[] args) + throws Exception + { + runTest(new PGPGeneralTest()); + } + + @Override + public String getName() + { + return "PGPGeneralTest"; + } + + @Override + public void performTest() + throws Exception + { + //testEd25519(); + // Tests for OpenedPGPKeyData + testOpenedPGPKeyData(); + testECNistCurves(); + testDSAElgamalOpen(); + testDSA(); + testProtectedRSA(); + + // Tests for PGPSignatureSubpacketVector + sigsubpacketTest(); + testParsingFromSignature(); + testPGPSignatureSubpacketVector(); + + // Tests for PGPSecretKey + testParseSecretKeyFromSExpr(); + + // Tests for PGPPublicKey + testPGPPublicKey(); + testAddRemoveCertification(); + embeddedJpegTest(); + + // Tests for PGPPublicKeyRing + testPGPPublicKeyRing(); + + // Tests for PGPPublicKeyRingCollection + testPublicKeyRingOperations(); + + // Tests for PGPSecretKeyRingCollection + testSecretKeyRingOperations(); + testRemoveSecretKeyRing(); + + // Tests for PGPSecretKeyRing + testPGPSecretKeyRingConstructor(); + testGetKeysWithSignaturesBy(); + rewrapTest(); + rewrapTestV3(); + testextraPubKeys(); + testPublicKeyOperations(); + testGetPublicKey_byteArray2(); + testPGPSecretKeyRing(); + + // Tests for PGPPublicKeyRingCollection + testGetPublicKey_byteArray(); + } + + public void testPGPPublicKey() + throws PGPException, IOException + { + BcPGPPublicKeyRingCollection pubRings = new BcPGPPublicKeyRingCollection(pub2); + final long id1 = -4049084404703773049L, id2 = -1413891222336124627L; + final byte[] fingerprint3 = new byte[]{90, -118, 121, -77, 70, 60, -62, -39, 90, 116, 30, 117, -91, -48, 127, -12, 83, -9, -37, -104}; + final byte[] fingerprint4 = new byte[]{28, -123, 104, -64, -124, -77, 74, 91, -14, -70, -17, -13, 0, -47, -69, -50, 116, 122, 95, 64}; + PGPPublicKey publicKey1 = pubRings.getPublicKey(id1); + PGPPublicKey publicKey2 = pubRings.getPublicKey(id2); + PGPPublicKey publicKey3 = pubRings.getPublicKey(fingerprint3); + PGPPublicKey publicKey4 = pubRings.getPublicKey(fingerprint4); + + final byte[] levelAndTrustAmount = new byte[]{-121}; + // Test for getTrustData + + isTrue(areEqual(publicKey1.getTrustData(), levelAndTrustAmount)); + isTrue(areEqual(publicKey2.getTrustData(), levelAndTrustAmount)); + isTrue(areEqual(publicKey3.getTrustData(), levelAndTrustAmount)); + isTrue(areEqual(publicKey4.getTrustData(), levelAndTrustAmount)); + // Test for getKeySignatures + Iterator it; + it = publicKey1.getKeySignatures(); + isTrue(it.hasNext() == false); + it = publicKey2.getKeySignatures(); + isTrue(((PGPSignature)it.next()).getKeyID() == -4049084404703773049L); + it = publicKey3.getKeySignatures(); + isTrue(it.hasNext() == false); + it = publicKey4.getKeySignatures(); + isTrue(((PGPSignature)it.next()).getKeyID() == -6498553574938125416L); + + // Test for getEncoded(boolean) + isTrue(areEqual(publicKey1.getEncoded(), publicKey1.getEncoded(false))); + + // Test for isRovked and hasRevocation + isTrue(!publicKey1.isRevoked()); + isTrue(!publicKey2.hasRevocation()); + isTrue(!publicKey3.hasRevocation()); + isTrue(!publicKey4.hasRevocation()); + + // Tests for join + // TODO: cover more missing branches of PGPPublicKey.join + try + { + PGPPublicKey.join(publicKey1, publicKey2, true, true); + fail("Key-ID mismatch."); + } + catch (IllegalArgumentException e) + { + isTrue("Key-ID mismatch.", messageIs(e.getMessage(), "Key-ID mismatch.")); + } + + PGPPublicKey publicKey7 = PGPPublicKey.join(publicKey2, publicKey2, true, true); + isTrue(publicKey7.getKeyID() == publicKey2.getKeyID()); + isTrue(areEqual(publicKey7.getFingerprint(), publicKey2.getFingerprint())); + isTrue(publicKey7.hasFingerprint(publicKey2.getFingerprint())); + isTrue(publicKey2.hasFingerprint(publicKey7.getFingerprint())); + + PGPPublicKeyRingCollection pgpRingCollection = new JcaPGPPublicKeyRingCollection(probExpPubKey); + final long id5 = 6556488621521814541L; + PGPPublicKeyRing pubKeys = pgpRingCollection.getPublicKeyRing(id5); + PGPPublicKey publicKey5 = pubKeys.getPublicKey(id5); + + isTrue(publicKey5.getTrustData() == null); + + PGPPublicKey publicKey6 = PGPPublicKey.join(publicKey5, publicKey5, true, true); + isTrue(publicKey6.getKeyID() == publicKey5.getKeyID()); + isTrue(areEqual(publicKey6.getFingerprint(), publicKey5.getFingerprint())); + isTrue(publicKey6.hasFingerprint(publicKey5.getFingerprint())); + isTrue(publicKey5.hasFingerprint(publicKey6.getFingerprint())); + } + + private boolean messageIs(String message, String s) + { + return message.indexOf(s) >= 0; + } + + public void testAddRemoveCertification() + throws Exception + { +// // +// // key pair generation - CAST5 encryption +// // + char[] passPhrase = "hello".toCharArray(); + RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); + kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 1024, 25)); + AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); + PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, new BcPGPKeyPair(PublicKeyAlgorithmTags.RSA_GENERAL, + kp, new Date()), "fred", null, null, new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, + HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(CryptoServicesRegistrar.getSecureRandom()).build(passPhrase)); + + PGPPublicKey key = secretKey.getPublicKey(); + Iterator it = key.getUserIDs(); + String uid = (String)it.next(); + + byte[] id = Strings.toUTF8ByteArray(uid); + it = key.getSignaturesForID(id); + PGPSignature sig = (PGPSignature)it.next(); + sig.init(new BcPGPContentVerifierBuilderProvider(), key); + + PGPPublicKey key1 = PGPPublicKey.removeCertification(key, id, sig); + if (key1 == null) + { + fail("failed certification removal"); + } + key1 = PGPPublicKey.addCertification(key1, id, sig); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); + sGen.init(PGPSignature.KEY_REVOCATION, secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase))); + sig = sGen.generateCertification(key1); + key1 = PGPPublicKey.addCertification(key1, sig); + byte[] keyEnc = key1.getEncoded(); + PGPPublicKeyRing tmpRing = new PGPPublicKeyRing(keyEnc, new BcKeyFingerprintCalculator()); + key1 = tmpRing.getPublicKey(); + Iterator sgIt = key1.getSignaturesOfType(PGPSignature.KEY_REVOCATION); + sig = (PGPSignature)sgIt.next(); + sig.init(new BcPGPContentVerifierBuilderProvider(), key1); + if (!sig.verifyCertification(key1)) + { + fail("failed to verify revocation certification"); + } + + PGPPublicKey key2 = PGPPublicKey.removeCertification(key, id); + if (key2 == null) + { + fail("failed certification removal"); + } + key2 = PGPPublicKey.addCertification(key2, id, sig); + sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); + sGen.init(PGPSignature.KEY_REVOCATION, secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase))); + sig = sGen.generateCertification(key2); + key2 = PGPPublicKey.addCertification(key2, sig); + keyEnc = key2.getEncoded(); + tmpRing = new PGPPublicKeyRing(keyEnc, new BcKeyFingerprintCalculator()); + key2 = tmpRing.getPublicKey(); + sgIt = key2.getSignaturesOfType(PGPSignature.KEY_REVOCATION); + sig = (PGPSignature)sgIt.next(); + sig.init(new BcPGPContentVerifierBuilderProvider(), key2); + if (!sig.verifyCertification(key2)) + { + fail("failed to verify revocation certification"); + } + + PGPPublicKey key3 = PGPPublicKey.removeCertification(key, uid); + if (key3 == null) + { + fail("failed certification removal"); + } + key3 = PGPPublicKey.addCertification(key3, id, sig); + sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); + sGen.init(PGPSignature.KEY_REVOCATION, secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase))); + sig = sGen.generateCertification(key3); + key3 = PGPPublicKey.addCertification(key3, sig); + keyEnc = key3.getEncoded(); + tmpRing = new PGPPublicKeyRing(keyEnc, new BcKeyFingerprintCalculator()); + key3 = tmpRing.getPublicKey(); + sgIt = key3.getSignaturesOfType(PGPSignature.KEY_REVOCATION); + sig = (PGPSignature)sgIt.next(); + sig.init(new BcPGPContentVerifierBuilderProvider(), key3); + if (!sig.verifyCertification(key3)) + { + fail("failed to verify revocation certification"); + } + } + + /** + * Test cover: + * PGPSecretKey.replacePublicKey + * PGPSecretKey.getUserAttributes + * PGPPublicKey.removeCertification + */ + private void embeddedJpegTest() + throws Exception + { + PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); + PGPSecretKeyRing pgpSec = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator()); + PGPPublicKey pubKey = pgpPub.getPublicKey(); + PGPUserAttributeSubpacketVectorGenerator vGen = new PGPUserAttributeSubpacketVectorGenerator(); + vGen.setImageAttribute(ImageAttribute.JPEG, jpegImage); + PGPUserAttributeSubpacketVector uVec = vGen.generate(); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); + sGen.init(PGPSignature.POSITIVE_CERTIFICATION, pgpSec.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass))); + PGPSignature sig = sGen.generateCertification(uVec, pubKey); + PGPPublicKey nKey = PGPPublicKey.addCertification(pubKey, uVec, sig); + PGPSecretKey secretKey = pgpSec.getSecretKey(); + secretKey = PGPSecretKey.replacePublicKey(secretKey, nKey); + Iterator it = secretKey.getUserAttributes(); + int count = 0; + while (it.hasNext()) + { + PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); + Iterator sigs = nKey.getSignaturesForUserAttribute(attributes); + int sigCount = 0; + while (sigs.hasNext()) + { + PGPSignature s = (PGPSignature)sigs.next(); + s.init(new BcPGPContentVerifierBuilderProvider(), pubKey); + if (!s.verifyCertification(attributes, pubKey)) + { + fail("added signature failed verification"); + } + sigCount++; + } + if (sigCount != 1) + { + fail("Failed added user attributes signature check"); + } + count++; + } + if (count != 1) + { + fail("didn't find added user attributes"); + } + nKey = PGPPublicKey.removeCertification(nKey, uVec, sig); + count = 0; + for (it = nKey.getSignaturesForUserAttribute(uVec); it.hasNext(); it.next()) + { + count++; + } + if (count != 0) + { + fail("found attributes where none expected"); + } + } + + /** + * Test Cover: + * PGPPublicKeyRingCollection.getPublicKey(byte[]) + * PGPPublicKeyRing.getPublicKey(byte[]) + */ + public void testGetPublicKey_byteArray() + throws Exception + { + PGPPublicKeyRingCollection pgpRingCollection = new JcaPGPPublicKeyRingCollection(probExpPubKey); + byte[] fingerprint = new byte[]{-31, -21, 70, -81, 62, 43, 9, 126, 23, -13, 81, 20, 90, -3, 83, -87, -37, -78, -60, 13}; + PGPPublicKey pubKey = pgpRingCollection.getPublicKey(fingerprint); + isTrue("fail to get the correct public key", pubKey.getKeyID() == 0x5afd53a9dbb2c40dL); + fingerprint[0] = 0; + pubKey = pgpRingCollection.getPublicKey(fingerprint); + isTrue("the public key should not exist", pubKey == null); + } + + /** + * Test Cover: PGPSecretKeyRing.getSecretKeyRing(byte[]) + */ + public void testGetPublicKey_byteArray2() + throws Exception + { + // TODO: extraPubKeys + JcaPGPSecretKeyRingCollection privRings = new JcaPGPSecretKeyRingCollection( + new ByteArrayInputStream(privv3)); + byte[] fingerprint = new byte[]{-85, -29, 45, 3, -118, -2, 111, 49, -37, -83, 127, -27, 85, 18, 17, -90}; + PGPSecretKeyRing pgpPriv = privRings.getSecretKeyRing(-1056546523141439621L); + PGPPublicKey pubKey = pgpPriv.getPublicKey(fingerprint); + isTrue("fail to get the correct public key", pubKey.getKeyID() == -1056546523141439621L); + fingerprint[0] = 0; + pubKey = pgpPriv.getPublicKey(fingerprint); + isTrue("fail to get the correct public key", pubKey == null); + } + + /** + * Test Cover: + * PGPSecretKeyRing.insertOrReplacePublicKey(PGPSecretKeyRing, PGPPublicKey) + * PGPSecretKeyRing.replacePublicKeys(PGPSecretKeyRing, PGPPublicKeyRing) + */ + public void testPublicKeyOperations() + throws Exception + { + PGPDigestCalculator digestCalculator = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1); + KeyPairGenerator generator; + KeyPair pair; + + // Generate master key + + generator = KeyPairGenerator.getInstance("ECDSA", BouncyCastleProvider.PROVIDER_NAME); + generator.initialize(new ECNamedCurveGenParameterSpec("P-256")); + + pair = generator.generateKeyPair(); + PGPKeyPair pgpMasterKey = new JcaPGPKeyPair(PublicKeyAlgorithmTags.ECDSA, pair, new Date()); + + PGPSignatureSubpacketGenerator hashed = new PGPSignatureSubpacketGenerator(); + hashed.setNotationData(false, true, "test@bouncycastle.org", "hashedNotation"); + PGPSignatureSubpacketGenerator unhashed = new PGPSignatureSubpacketGenerator(); + + PGPContentSignerBuilder signerBuilder = new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.ECDSA, HashAlgorithmTags.SHA512); + PGPKeyRingGenerator keyRingGenerator = new PGPKeyRingGenerator( + pgpMasterKey, digestCalculator, hashed.generate(), unhashed.generate(), signerBuilder, null); + PGPSecretKeyRing secretKeys = keyRingGenerator.generateSecretKeyRing(); + + PGPSecretKey secretKey = secretKeys.getSecretKey(); + PGPPublicKey publicKey = secretKey.getPublicKey(); + secretKeys = PGPSecretKeyRing.insertOrReplacePublicKey(secretKeys, publicKey); + + Iterator signatures = secretKeys.getPublicKey().getSignaturesOfType(PGPSignature.DIRECT_KEY); + isTrue(signatures.hasNext()); + + PGPSignature signature = (PGPSignature)signatures.next(); + isTrue(!signatures.hasNext()); + + NotationData[] hashedNotations = signature.getHashedSubPackets().getNotationDataOccurences(); + isEquals(1, hashedNotations.length); + isEquals("test@bouncycastle.org", hashedNotations[0].getNotationName()); + isEquals("hashedNotation", hashedNotations[0].getNotationValue()); + isEquals(1, signature.getHashedSubPackets().getNotationDataOccurrences("test@bouncycastle.org").length); + + signature.init(new BcPGPContentVerifierBuilderProvider(), secretKeys.getPublicKey()); + isTrue(signature.verifyCertification(secretKeys.getPublicKey())); + + PGPPublicKeyRing publicKeys = keyRingGenerator.generatePublicKeyRing(); + secretKeys = PGPSecretKeyRing.replacePublicKeys(secretKeys, publicKeys); + + signatures = secretKeys.getPublicKey().getSignaturesOfType(PGPSignature.DIRECT_KEY); + isTrue(signatures.hasNext()); + + signature = (PGPSignature)signatures.next(); + isTrue(!signatures.hasNext()); + + hashedNotations = signature.getHashedSubPackets().getNotationDataOccurrences(); + isEquals(1, hashedNotations.length); + isEquals("test@bouncycastle.org", hashedNotations[0].getNotationName()); + isEquals("hashedNotation", hashedNotations[0].getNotationValue()); + + signature.init(new BcPGPContentVerifierBuilderProvider(), secretKeys.getPublicKey()); + isTrue(signature.verifyCertification(secretKeys.getPublicKey())); + } + + /** + * Test cover: + * PGPSecretKeyRing.getPublicKey + * PGPSecretKeyRing.insertOrReplacePublicKey + * PGPSecretKey.replacePublicKey + * PGPSecretKey.getEncoded + * PGPSecretKey.getS2K + */ + private void testextraPubKeys() + throws Exception + { + BcPGPSecretKeyRingCollection secCol = new BcPGPSecretKeyRingCollection(secWithPersonalCertificate); + byte[] fingerprint = new byte[]{90, -92, -3, 36, -60, -80, 103, 13, -40, -42, -26, 95, 7, 88, -112, 69, -117, 111, 100, 118}; + PGPSecretKeyRing secretKeys = secCol.getSecretKeyRing(-1923690421044764583L); + PGPPublicKey publicKey = secretKeys.getPublicKey(fingerprint); + isTrue("", publicKey.getKeyID() == 529331584582509686L); + + publicKey = secretKeys.getPublicKey(1L); + isTrue("", publicKey == null); + + publicKey = secretKeys.getPublicKey(529331584582509686L); + isTrue("", publicKey != null); + + secretKeys = PGPSecretKeyRing.insertOrReplacePublicKey(secretKeys, publicKey); + publicKey = secretKeys.getPublicKey(fingerprint); + isTrue("", publicKey.getKeyID() == 529331584582509686L); + + PGPSecretKey secretKey = secretKeys.getSecretKey(); + try + { + PGPSecretKey.replacePublicKey(secretKey, publicKey); + fail("keyIDs do not match"); + } + catch (IllegalArgumentException e) + { + isTrue("keyIDs do not match", messageIs(e.getMessage(), "keyIDs do not match")); + } + + byte[] bOut = secretKey.getEncoded(); + PGPSecretKeyRing secretKeys2 = new PGPSecretKeyRing(bOut, new BcKeyFingerprintCalculator()); + PGPSecretKey secretKey2 = secretKeys2.getSecretKey(); + isTrue(secretKey2.getKeyID() == secretKey.getKeyID()); + isTrue(secretKey2.getS2K() == null); + } + + private void rewrapTest() + throws Exception + { + SecureRandom rand = new SecureRandom(); + + // Read the secret key rings + BcPGPSecretKeyRingCollection privRings = new BcPGPSecretKeyRingCollection( + new ByteArrayInputStream(rewrapKey)); + + Iterator rIt = privRings.getKeyRings(); + + if (rIt.hasNext()) + { + PGPSecretKeyRing pgpPriv = (PGPSecretKeyRing)rIt.next(); + pgpPriv = PGPSecretKeyRing.copyWithNewPassword(pgpPriv, new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(rewrapPass), + null); + Iterator it = pgpPriv.getSecretKeys(); + while (it.hasNext()) + { + PGPSecretKey pgpKey = (PGPSecretKey)it.next(); + // this should succeed + PGPPrivateKey privTmp = pgpKey.extractPrivateKey(null); + } + } + } + + /** + * Test cover: PGPSecretKeyRing.copyWithNewPassword + * Reference: + */ + private void rewrapTestV3() + throws Exception + { + // Read the secret key rings + JcaPGPSecretKeyRingCollection privRings = new JcaPGPSecretKeyRingCollection( + new ByteArrayInputStream(privv3)); + char[] newPass = "fred".toCharArray(); + + Iterator rIt = privRings.getKeyRings(); + + if (rIt.hasNext()) + { + PGPSecretKeyRing pgpPriv = (PGPSecretKeyRing)rIt.next(); + + Iterator it = pgpPriv.getSecretKeys(); + PGPSecretKeyRing pgpPriv2 = PGPSecretKeyRing.copyWithNewPassword(pgpPriv, new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(v3KeyPass), + null); + while (it.hasNext()) + { + PGPSecretKey pgpKey = (PGPSecretKey)it.next(); + long oldKeyID = pgpKey.getKeyID(); + PGPSecretKey newPgpKey = pgpPriv2.getSecretKey(oldKeyID); + + // this should succeed + PGPPrivateKey privTmp = newPgpKey.extractPrivateKey(null); + + if (newPgpKey.getKeyID() != oldKeyID) + { + fail("key ID mismatch"); + } + } + + it = pgpPriv2.getSecretKeys(); + PGPSecretKeyRing pgpPriv3 = PGPSecretKeyRing.copyWithNewPassword(pgpPriv2, null, + new JcePBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5, new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build().get(HashAlgorithmTags.MD5)).setProvider("BC").build(newPass)); + while (it.hasNext()) + { + PGPSecretKey pgpKey = (PGPSecretKey)it.next(); + long oldKeyID = pgpKey.getKeyID(); + PGPSecretKey newPgpKey = pgpPriv3.getSecretKey(oldKeyID); + + // this should succeed + PGPPrivateKey privTmp = newPgpKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider(new BouncyCastleProvider()).build(newPass)); + + if (newPgpKey.getKeyID() != oldKeyID) + { + fail("key ID mismatch"); + } + } + } + } + + + /** + * Test cover: + * PGPSecretKeyRing.getKeysWithSignaturesBy + * PGPPublicKeyRingCollection.getKeysWithSignaturesBy + * PGPPublicKey.getKeySigatures() + */ + public void testGetKeysWithSignaturesBy() + throws Exception + { + char[] passPhrase = "hello".toCharArray(); + KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); + + dsaKpg.initialize(512); + + // + // this takes a while as the key generator has to generate some DSA params + // before it generates the key. + // + KeyPair dsaKp = dsaKpg.generateKeyPair(); + + KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); + BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); + BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); + + ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); + + elgKpg.initialize(elParams); + + // + // this is quicker because we are using pregenerated parameters. + // + KeyPair elgKp = elgKpg.generateKeyPair(); + PGPKeyPair dsaKeyPair = new JcaPGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); + PGPKeyPair elgKeyPair = new JcaPGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); + PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1); + PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, + "test", sha1Calc, null, null, new JcaPGPContentSignerBuilder(PGPPublicKey.DSA, HashAlgorithmTags.SHA1), new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).setProvider("BC").build(passPhrase)); + + + keyRingGen.addSubKey(elgKeyPair, null); + + PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); + + keyRing.getSecretKey().extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(passPhrase)); + + PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); + + PGPPublicKey vKey = null; + PGPPublicKey sKey = null; + + Iterator it = pubRing.getPublicKeys(); + while (it.hasNext()) + { + PGPPublicKey pk = (PGPPublicKey)it.next(); + if (pk.isMasterKey()) + { + vKey = pk; + } + else + { + sKey = pk; + } + } + + Iterator skrIt = keyRing.getKeysWithSignaturesBy(vKey.getKeyID()); + if (skrIt.hasNext()) + { + while (skrIt.hasNext()) + { + PGPPublicKey pub = (PGPPublicKey)skrIt.next(); + + if (pub.isMasterKey()) + { + Iterator sigIt = pub.getSignaturesForKeyID(vKey.getKeyID()); + + PGPSignature sig = (PGPSignature)sigIt.next(); + + if (sig.getSignatureType() != PGPSignature.POSITIVE_CERTIFICATION || sigIt.hasNext()) + { + fail("master sig check failed"); + } + } + else + { + Iterator sigIt = pub.getSignaturesForKeyID(vKey.getKeyID()); + + PGPSignature sig = (PGPSignature)sigIt.next(); + + if (sig.getSignatureType() != PGPSignature.SUBKEY_BINDING || sigIt.hasNext()) + { + fail("sub sig check failed"); + } + } + } + } + else + { + fail("no keys found in iterator"); + } + + List collection = new ArrayList(); + collection.add(pubRing); + PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(collection); + it = pubRings.getKeysWithSignaturesBy(vKey.getKeyID()); + while (it.hasNext()) + { + PGPPublicKey pub = (PGPPublicKey)it.next(); + if (pub.isMasterKey()) + { + Iterator sigIt = pub.getSignaturesForKeyID(vKey.getKeyID()); + + PGPSignature sig = (PGPSignature)sigIt.next(); + + if (sig.getSignatureType() != PGPSignature.POSITIVE_CERTIFICATION || sigIt.hasNext()) + { + fail("master sig check failed"); + } + } + else + { + Iterator sigIt = pub.getSignaturesForKeyID(vKey.getKeyID()); + + PGPSignature sig = (PGPSignature)sigIt.next(); + + if (sig.getSignatureType() != PGPSignature.SUBKEY_BINDING || sigIt.hasNext()) + { + fail("sub sig check failed"); + } + } + } + } + + public void testPGPSecretKeyRing() + throws Exception + { + BcPGPSecretKeyRingCollection secCol = new BcPGPSecretKeyRingCollection(secWithPersonalCertificate); + PGPSecretKeyRing secretKeys = secCol.getSecretKeyRing(8198709240736962902L); + PGPSecretKey secretKey1 = secretKeys.getSecretKey(8198709240736962902L); + PGPSecretKey secretKey2 = secretKeys.getSecretKey(-6083617161579374264L); + try + { + List skList = new ArrayList(); + skList.add(secretKey2); + skList.add(secretKey1); + PGPSecretKeyRing secretKeys1 = new PGPSecretKeyRing(skList); + fail("key 0 must be a master key"); + } + catch (IllegalArgumentException e) + { + isTrue("key 0 must be a master key", messageIs(e.getMessage(), "key 0 must be a master key")); + } + + try + { + List skList = new ArrayList(); + skList.add(secretKey1); + skList.add(secretKey1); + PGPSecretKeyRing secretKeys1 = new PGPSecretKeyRing(skList); + fail("key 0 can be only master key"); + } + catch (IllegalArgumentException e) + { + isTrue("key 0 can be only master key", messageIs(e.getMessage(), "key 0 can be only master key")); + } + + PGPSecretKeyRing secretKeys2 = new PGPSecretKeyRing(new ArrayList()); + secretKeys2 = PGPSecretKeyRing.insertSecretKey(secretKeys2, secretKey1); + secretKeys2 = PGPSecretKeyRing.insertSecretKey(secretKeys2, secretKey1); + secretKeys2 = PGPSecretKeyRing.insertSecretKey(secretKeys2, secretKey2); + isTrue("The secret key should be in the ring", secretKeys2.getSecretKey(secretKey1.getFingerprint()) != null); + isTrue("The secret key should be in the ring", secretKeys2.getSecretKey(secretKey2.getFingerprint()) != null); + + secretKeys2 = PGPSecretKeyRing.removeSecretKey(secretKeys2, secretKey2); + secretKeys2 = PGPSecretKeyRing.removeSecretKey(secretKeys2, secretKey2); + isTrue("The secret key should be null", secretKeys2 == null); + } + + public void testPGPSecretKeyRingConstructor() + throws Exception + { + try + { + new PGPSecretKeyRing(new ByteArrayInputStream(curve25519Pub), new JcaKeyFingerprintCalculator()); + fail("the constructor for this initialisation should fail as the input is a stream of a public key "); + } + catch (IOException e) + { + isTrue("secret key ring doesn't start with secret key tag: tag 0x", + messageIs(e.getMessage(), "secret key ring doesn't start with secret key tag: tag 0x")); + } + } + + public void testRemoveSecretKeyRing() + throws Exception + { + final long keyID = -2247357259537451242L; + PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(new ByteArrayInputStream(secretKeyByteArray), new JcaKeyFingerprintCalculator()); + PGPSecretKeyRing secretKeyRing = pgpSec.getSecretKeyRing(keyID); + isTrue("The secret key should be in the secret key ring collection", secretKeyRing != null); + PGPSecretKeyRingCollection pgpSec2 = PGPSecretKeyRingCollection.removeSecretKeyRing(pgpSec, secretKeyRing); + pgpSec2.contains(keyID); + secretKeyRing = pgpSec2.getSecretKeyRing(keyID); + isTrue("The secret key should be in the secret key ring collection", secretKeyRing == null); + } + + public void testSecretKeyRingOperations() + throws Exception + { + final long id1 = -1923690421044764583L, id2 = -6083617161579374264L, id3 = 8198709240736962902L; + PGPSecretKeyRingCollection secCol = new BcPGPSecretKeyRingCollection(secWithPersonalCertificate); + PGPSecretKeyRing secretKeys = secCol.getSecretKeyRing(id1); + isTrue("secret key should not be null", secretKeys != null); + secretKeys = secCol.getSecretKeyRing(id2); + isTrue("secret key should not be null", secretKeys != null); + + try + { + PGPSecretKeyRingCollection.addSecretKeyRing(secCol, secretKeys); + fail("Collection already contains a key with a keyID for the passed in ring."); + } + catch (IllegalArgumentException e) + { + isTrue("Collection already contains a key with a keyID for the passed in ring.", + messageIs(e.getMessage(), "Collection already contains a key with a keyID for the passed in ring.")); + } + + secCol = PGPSecretKeyRingCollection.removeSecretKeyRing(secCol, secretKeys); + isTrue("secret key has been removed", !secCol.contains(id2)); + + try + { + secCol = PGPSecretKeyRingCollection.removeSecretKeyRing(secCol, secretKeys); + fail("Collection does not contain a key with a keyID for the passed in ring."); + } + catch (IllegalArgumentException e) + { + isTrue("Collection does not contain a key with a keyID for the passed in ring.", + messageIs(e.getMessage(), "Collection does not contain a key with a keyID for the passed in ring.")); + } + + secCol = PGPSecretKeyRingCollection.addSecretKeyRing(secCol, secretKeys); + isTrue("secret key has been added", secCol.contains(id2)); + + secCol = new PGPSecretKeyRingCollection(secWithPersonalCertificate, new BcKeyFingerprintCalculator()); + isTrue(secCol.contains(id1) && secCol.contains(id2) && secCol.contains(id3) && secCol.size() == 2); + + Iterator it = secCol.iterator(); + List collection = new ArrayList(); + while (it.hasNext()) + { + collection.add((PGPSecretKeyRing)it.next()); + } + PGPSecretKeyRingCollection secCol2 = new BcPGPSecretKeyRingCollection(collection); + isTrue(secCol2.contains(id1) && secCol2.contains(id2) && secCol2.contains(id3) && secCol2.size() == 2); + + try + { + BcPGPSecretKeyRingCollection secCol3 = new BcPGPSecretKeyRingCollection(pub1); + fail("found where PGPSecretKeyRing expected"); + } + catch (PGPException e) + { + isTrue("found where PGPSecretKeyRing expected", messageIs(e.getMessage(), "found where PGPSecretKeyRing expected")); + } + } + + public void testPublicKeyRingOperations() + throws Exception + { + final long id1 = -7459027269198298458L, id2 = -4437440411852492852L; + PGPPublicKeyRingCollection pubRings = new BcPGPPublicKeyRingCollection(pub1); + byte[] fingerprint1 = pubRings.getPublicKey(id1).getFingerprint(); + isTrue("the public key ring should be in the collection", pubRings.getPublicKeyRing(id1) != null); + isTrue("the public key ring should be in the collection", pubRings.contains(id2)); + + isTrue("The public key should not be found", pubRings.getPublicKey(1L) == null); + isTrue("The public key ring should not be found", pubRings.getPublicKeyRing(1L) == null); + isTrue("The public key ring should not be found", pubRings.getPublicKeyRing(new byte[fingerprint1.length]) == null); + + PGPPublicKeyRing pubRing = pubRings.getPublicKeyRing(id2); + + try + { + PGPPublicKeyRingCollection pubRings1 = PGPPublicKeyRingCollection.addPublicKeyRing(pubRings, pubRing); + fail("Collection already contains a key with a keyID for the passed in ring."); + } + catch (IllegalArgumentException e) + { + isTrue("Collection already contains a key with a keyID for the passed in ring.", + messageIs(e.getMessage(), "Collection already contains a key with a keyID for the passed in ring.")); + } + + pubRings = PGPPublicKeyRingCollection.removePublicKeyRing(pubRings, pubRing); + try + { + PGPPublicKeyRingCollection pubRings1 = PGPPublicKeyRingCollection.removePublicKeyRing(pubRings, pubRing); + fail("Collection does not contain a key with a keyID for the passed in ring."); + } + catch (IllegalArgumentException e) + { + isTrue("Collection does not contain a key with a keyID for the passed in ring.", + messageIs(e.getMessage(), "Collection does not contain a key with a keyID for the passed in ring.")); + } + pubRings = PGPPublicKeyRingCollection.addPublicKeyRing(pubRings, pubRing); + + pubRings = new PGPPublicKeyRingCollection(pub1, new BcKeyFingerprintCalculator()); + isTrue(pubRings.getPublicKeyRing(fingerprint1) != null && pubRings.contains(id2) && pubRings.size() == 1); + + Iterator it = pubRings.iterator(); + List collection = new ArrayList(); + while (it.hasNext()) + { + collection.add((PGPPublicKeyRing)it.next()); + } + PGPPublicKeyRingCollection pubRings2 = new BcPGPPublicKeyRingCollection(collection); + isTrue(pubRings2.contains(fingerprint1) && pubRings2.contains(id2) && pubRings2.size() == 1); + + try + { + PGPPublicKeyRingCollection pubRings3 = new BcPGPPublicKeyRingCollection(secWithPersonalCertificate); + fail("found where PGPPublicKeyRing expected"); + } + catch (PGPException e) + { + isTrue("found where PGPPublicKeyRing expected", messageIs(e.getMessage(), "found where PGPPublicKeyRing expected")); + } + } + + public void testPGPPublicKeyRing() + throws PGPException, IOException + { + PGPPublicKeyRingCollection pgpRingCollection = new JcaPGPPublicKeyRingCollection(probExpPubKey); + final long id1 = 6556488621521814541L, id2 = 3905109942809550596L; + PGPPublicKeyRing pubKeys = pgpRingCollection.getPublicKeyRing(id1); + PGPPublicKey publicKey1 = pubKeys.getPublicKey(id1); + PGPPublicKey publicKey2 = pubKeys.getPublicKey(id2); + try + { + List pubkeys = new ArrayList(); + pubkeys.add(publicKey2); + pubkeys.add(publicKey1); + PGPPublicKeyRing publickeys = new PGPPublicKeyRing(pubkeys); + fail("key 0 must be a master key"); + } + catch (IllegalArgumentException e) + { + isTrue("key 0 must be a master key", messageIs(e.getMessage(), "key 0 must be a master key")); + } + try + { + List pubkeys = new ArrayList(); + pubkeys.add(publicKey1); + pubkeys.add(publicKey1); + PGPPublicKeyRing publickeys = new PGPPublicKeyRing(pubkeys); + fail("key 0 can be only master key"); + } + catch (IllegalArgumentException e) + { + isTrue("key 0 can be only master key", messageIs(e.getMessage(), "key 0 can be only master key")); + } + + try + { + PGPPublicKeyRing publicKeys = new PGPPublicKeyRing(secWithPersonalCertificate, new BcKeyFingerprintCalculator()); + fail("public key ring doesn't start with public key tag"); + } + catch (IOException e) + { + isTrue("public key ring doesn't start with public key tag: ", messageIs(e.getMessage(), "public key ring doesn't start with public key tag: ")); + } + + PGPPublicKeyRing pubKeys2 = new PGPPublicKeyRing(new ArrayList()); + pubKeys2 = PGPPublicKeyRing.insertPublicKey(pubKeys2, publicKey1); + pubKeys2 = PGPPublicKeyRing.insertPublicKey(pubKeys2, publicKey1); + pubKeys2 = PGPPublicKeyRing.insertPublicKey(pubKeys2, publicKey2); + isTrue("The public key should be in the ring", pubKeys2.getPublicKey(publicKey1.getFingerprint()) != null); + isTrue("The public key should be in the ring", pubKeys2.getPublicKey(publicKey2.getFingerprint()) != null); + + PGPPublicKeyRing pubKeys3 = PGPPublicKeyRing.removePublicKey(pubKeys2, publicKey2); + pubKeys3 = PGPPublicKeyRing.removePublicKey(pubKeys3, publicKey2); + isTrue("removePublicKey should return null", pubKeys3 == null); + } + + public void testParseSecretKeyFromSExpr() + throws Exception + { + PGPObjectFactory pgpFact = new JcaPGPObjectFactory(encMessage); + PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpFact.nextObject(); + PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); + PGPPublicKey publicKey = new JcaPGPPublicKeyRing(testPubKey2).getPublicKey(encP.getKeyID()); + JcaPGPDigestCalculatorProviderBuilder digBuild = new JcaPGPDigestCalculatorProviderBuilder(); + PGPSecretKey secretKey = PGPSecretKey.parseSecretKeyFromSExpr(new ByteArrayInputStream(sExprKeySub), new JcePBEProtectionRemoverFactory("test".toCharArray(), digBuild.build()).setProvider("BC"), publicKey); + InputStream clear = encP.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").setContentProvider("BC").build(secretKey.extractPrivateKey(null))); + PGPObjectFactory plainFact = new PGPObjectFactory(clear, new BcKeyFingerprintCalculator()); + PGPCompressedData cData = (PGPCompressedData)plainFact.nextObject(); + PGPObjectFactory compFact = new PGPObjectFactory(cData.getDataStream(), new BcKeyFingerprintCalculator()); + PGPLiteralData lData = (PGPLiteralData)compFact.nextObject(); + if (!"test.txt".equals(lData.getFileName())) + { + fail("wrong file name detected"); + } + + PGPSecretKey key = PGPSecretKey.parseSecretKeyFromSExpr(new ByteArrayInputStream(sExprKeyMaster), new JcePBEProtectionRemoverFactory("test".toCharArray(), digBuild.build()).setProvider(new BouncyCastleProvider()), new JcaKeyFingerprintCalculator()); + PGPSignatureGenerator signGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PGPPublicKey.ECDSA, HashAlgorithmTags.SHA256).setProvider("BC")); + signGen.init(PGPSignature.BINARY_DOCUMENT, key.extractPrivateKey(null)); + signGen.update("hello world!".getBytes()); + PGPSignature sig = signGen.generate(); + publicKey = new JcaPGPPublicKeyRing(testPubKey2).getPublicKey(); + sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey); + sig.update("hello world!".getBytes()); + if (!sig.verify()) + { + fail("signature failed to verify!"); + } + } + + private void sigsubpacketTest() + throws Exception + { + char[] passPhrase = "test".toCharArray(); + String identity = "TEST "; + Date date = new Date(); + + RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); + kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 2048, 25)); + AsymmetricCipherKeyPair kpSgn = kpg.generateKeyPair(); + AsymmetricCipherKeyPair kpEnc = kpg.generateKeyPair(); + + PGPKeyPair sgnKeyPair = new BcPGPKeyPair(PGPPublicKey.RSA_SIGN, kpSgn, date); + PGPKeyPair encKeyPair = new BcPGPKeyPair(PGPPublicKey.RSA_GENERAL, kpEnc, date); + + PGPSignatureSubpacketGenerator svg = new PGPSignatureSubpacketGenerator(); + + int[] aeadAlgs = new int[]{AEADAlgorithmTags.EAX, + AEADAlgorithmTags.OCB, AEADAlgorithmTags.GCM, AEADAlgorithmTags.GCM}; + svg.setPreferredAEADAlgorithms(true, aeadAlgs); + svg.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); + svg.setKeyFlags(true, KeyFlags.CERTIFY_OTHER + KeyFlags.SIGN_DATA); + PGPSignatureSubpacketVector hashedPcks = svg.generate(); + + PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, + sgnKeyPair, identity, new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1), + hashedPcks, null, new BcPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); + + svg = new PGPSignatureSubpacketGenerator(); + svg.setKeyExpirationTime(true, 2L); + svg.setKeyFlags(true, KeyFlags.ENCRYPT_COMMS + KeyFlags.ENCRYPT_STORAGE); + svg.setPrimaryUserID(true, false); + svg.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); + hashedPcks = svg.generate(); + + keyRingGen.addSubKey(encKeyPair, hashedPcks, null); + + byte[] encodedKeyRing = keyRingGen.generatePublicKeyRing().getEncoded(); + + PGPPublicKeyRing keyRing = new PGPPublicKeyRing(encodedKeyRing, new BcKeyFingerprintCalculator()); + + for (Iterator it = keyRing.getPublicKeys(); it.hasNext(); ) + { + PGPPublicKey pKey = (PGPPublicKey)it.next(); + + if (!pKey.isEncryptionKey()) + { + for (Iterator sit = pKey.getSignatures(); sit.hasNext(); ) + { + PGPSignature sig = (PGPSignature)sit.next(); + PGPSignatureSubpacketVector v = sig.getHashedSubPackets(); + if (!Arrays.areEqual(v.getPreferredAEADAlgorithms(), aeadAlgs)) + { + fail("preferred aead algs don't match"); + } + } + } + } + } + + + public void testParsingFromSignature() + throws IOException + { + String signatureWithPolicyUri = "-----BEGIN PGP SIGNATURE-----\n" + + "\n" + + "iKQEHxYKAFYFAmIRIAgJEDXXpSQjWzWvFiEEVSc3S9X9kRTsyfjqNdelJCNbNa8u\n" + + "Gmh0dHBzOi8vZXhhbXBsZS5vcmcvfmFsaWNlL3NpZ25pbmctcG9saWN5LnR4dAAA\n" + + "NnwBAImA2KdiS/7kLWoQpwc+A6N2PtAvLxG0gkZmGzYgRWvGAP9g4GLAA/GQ0plr\n" + + "Xn7uLnOG49S1fFA9P+R1Dd8Qoa4+Dg==\n" + + "=OPUu\n" + + "-----END PGP SIGNATURE-----\n"; + + ByteArrayInputStream byteIn = new ByteArrayInputStream(Strings.toByteArray(signatureWithPolicyUri)); + ArmoredInputStream armorIn = new ArmoredInputStream(byteIn); + PGPObjectFactory objectFactory = new BcPGPObjectFactory(armorIn); + + PGPSignatureList signatures = (PGPSignatureList)objectFactory.nextObject(); + PGPSignature signature = signatures.get(0); + + PolicyURI[] policyURI = signature.getHashedSubPackets().getPolicyURIs(); + isEquals("https://example.org/~alice/signing-policy.txt", policyURI[0].getURI()); + + PolicyURI other = new PolicyURI(false, "https://example.org/~alice/signing-policy.txt"); + + ByteArrayOutputStream first = new ByteArrayOutputStream(); + policyURI[0].encode(first); + + ByteArrayOutputStream second = new ByteArrayOutputStream(); + other.encode(second); + + areEqual(first.toByteArray(), second.toByteArray()); + } + + /** + * Test cover: + * PGPSignatureSubpacketVector + * PGPSignatureSubpacketGenerator + */ + public void testPGPSignatureSubpacketVector() + throws Exception + { + PGPSecretKeyRing pgpDSAPriv = new PGPSecretKeyRing(dsaKeyRing, new JcaKeyFingerprintCalculator()); + PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(rsaKeyRing, new JcaKeyFingerprintCalculator()); + PGPSecretKey secretKey = pgpPriv.getSecretKey(); + PGPPublicKey publicKey = pgpPriv.getPublicKey(); + PGPSecretKey secretDSAKey = pgpDSAPriv.getSecretKey(); + PGPPrivateKey pgpPrivDSAKey = secretDSAKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(dsaPass)); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1).setProvider("BC")); + sGen.init(PGPSignature.DEFAULT_CERTIFICATION, pgpPrivDSAKey); + PGPSignatureSubpacketGenerator hashedGen = new PGPSignatureSubpacketGenerator(); + hashedGen.addIntendedRecipientFingerprint(false, secretKey.getPublicKey()); + sGen.setHashedSubpackets(hashedGen.generate()); + //sGen.setUnhashedSubpackets(null); + PGPSignature sig = sGen.generateCertification(TEST_USER_ID, secretKey.getPublicKey()); + sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), secretDSAKey.getPublicKey()); + if (!sig.verifyCertification(TEST_USER_ID, secretKey.getPublicKey())) + { + fail("user-id verification failed."); + } + PGPSignatureSubpacketVector hashedPcks = sig.getHashedSubPackets(); + + IntendedRecipientFingerprint[] intFig = hashedPcks.getIntendedRecipientFingerprints(); + isTrue("mismatch on intended rec. fingerprint", secretKey.getPublicKey().hasFingerprint(intFig[0].getFingerprint())); + + // Tests for null value + isTrue("issuer key id should be 0", hashedPcks.getIssuerKeyID() == 0); + // getSignatureCreationTime cannot return null via PGPSignatureGenerator.generate() + isTrue("SignatureCreationTime cannot be null", hashedPcks.getSignatureCreationTime() != null); + isTrue("PreferredAEADAlgorithms should be null", hashedPcks.getPreferredAEADAlgorithms() == null); + isTrue("KeyFlags should be 0", hashedPcks.getKeyFlags() == 0); + isTrue("isPrimaryUserID should be false", !hashedPcks.isPrimaryUserID()); + isTrue("SignatureTarget should be null", hashedPcks.getSignatureTarget() == null); + isTrue("Features should be null", hashedPcks.getFeatures() == null); + isTrue("IssuerFingerprint should be null", hashedPcks.getIssuerFingerprint() == null); + isTrue("PolicyURI should be null", hashedPcks.getPolicyURI() == null); + isTrue("PolicyURIs should be empty", hashedPcks.getPolicyURIs().length == 0); + isTrue("RegularExpression should be null", hashedPcks.getRegularExpression() == null); + isTrue("RegularExpressions should be empty", hashedPcks.getRegularExpressions().length == 0); + isTrue("Revocable should be null", hashedPcks.getRevocable() == null); + isTrue("Revocable should be true", hashedPcks.isRevocable()); + isTrue("RevocationKeys should be empty", hashedPcks.getRevocationKeys().length == 0); + isTrue("RevocationReason should be null", hashedPcks.getRevocationReason() == null); + isTrue("Trust should be null", hashedPcks.getTrust() == null); + isTrue(hashedPcks.getIntendedRecipientFingerprint().getKeyVersion() == publicKey.getVersion()); + + String regexString = "example.org"; + RegularExpression regex = new RegularExpression(false, regexString); + hashedGen.addCustomSubpacket(regex); + hashedGen.addRegularExpression(false, regexString); + hashedGen.removePacket(hashedPcks.getIntendedRecipientFingerprint()); + hashedGen.setRevocable(false, false); + hashedGen.setRevocationKey(false, PublicKeyAlgorithmTags.DSA, publicKey.getFingerprint()); + hashedGen.setIssuerKeyID(false, publicKey.getKeyID()); + hashedGen.setIssuerFingerprint(false, publicKey); + final String description = "Test for Revocation"; + hashedGen.setRevocationReason(false, RevocationReasonTags.KEY_SUPERSEDED, description); + hashedGen.setExportable(false, false); + hashedGen.setPrimaryUserID(false, true); + + final int depth = 1; + final int trustAmount = 255; + hashedGen.setTrust(false, depth, trustAmount); + sGen.setHashedSubpackets(hashedGen.generate()); + sig = sGen.generateCertification(TEST_USER_ID, secretKey.getPublicKey()); + sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), secretDSAKey.getPublicKey()); + hashedPcks = sig.getHashedSubPackets(); + hashedPcks = PGPSignatureSubpacketVector.fromSubpackets(hashedPcks.toArray()); + + isTrue("IntendedRecipientFingerprint should not be null", hashedPcks.getIntendedRecipientFingerprint() == null); + isTrue("RegularExpression should not be null", hashedPcks.getRegularExpression() != null); + isTrue("RegularExpressions should be empty", hashedPcks.getRegularExpressions().length == 2); + isTrue("Revocable should not be null", hashedPcks.getRevocable() != null); + isTrue("Revocable should be false", !hashedPcks.isRevocable()); + isTrue("RevocationKeys should not be empty", hashedPcks.getRevocationKeys().length == 1); + RevocationKey revocationKey = hashedPcks.getRevocationKeys()[0]; + isTrue(publicKey.hasFingerprint(revocationKey.getFingerprint())); + isTrue(revocationKey.getAlgorithm() == PublicKeyAlgorithmTags.DSA); + // TODO: addRevocationKey has no parameter for setting signatureClass + isTrue(revocationKey.getSignatureClass() == RevocationKeyTags.CLASS_DEFAULT); + isTrue("IssuerKeyID should not be 0", hashedPcks.getIssuerKeyID() != 0L); + RevocationReason revocationReason = hashedPcks.getRevocationReason(); + isTrue("RevocationReason should not be null", revocationReason != null); + isTrue(revocationReason.getRevocationReason() == RevocationReasonTags.KEY_SUPERSEDED); + isTrue(revocationReason.getRevocationDescription().equals(description)); + TrustSignature trustSignature = hashedPcks.getTrust(); + isTrue("Trust should be null", trustSignature != null); + isTrue("Trust level depth should be " + depth, trustSignature.getDepth() == depth); + isTrue("Trust amount should be " + trustAmount, trustSignature.getTrustAmount() == trustAmount); + isTrue("Exporable should be false", !hashedPcks.isExportable()); + isTrue(hashedPcks.getIssuerFingerprint().getKeyVersion() == publicKey.getVersion()); + isTrue("isPrimaryUserID should be true", hashedPcks.isPrimaryUserID()); + + hashedPcks = PGPSignatureSubpacketVector.fromSubpackets(java.util.Arrays.asList(hashedPcks.toArray())); + + isTrue("IntendedRecipientFingerprint should not be null", hashedPcks.getIntendedRecipientFingerprint() == null); + isTrue("RegularExpression should not be null", hashedPcks.getRegularExpression() != null); + isTrue("RegularExpressions should be empty", hashedPcks.getRegularExpressions().length == 2); + isTrue("Revocable should not be null", hashedPcks.getRevocable() != null); + isTrue("Revocable should be false", !hashedPcks.isRevocable()); + isTrue("RevocationKeys should not be empty", hashedPcks.getRevocationKeys().length == 1); + revocationKey = hashedPcks.getRevocationKeys()[0]; + isTrue(publicKey.hasFingerprint(revocationKey.getFingerprint())); + isTrue(revocationKey.getAlgorithm() == PublicKeyAlgorithmTags.DSA); + // TODO: addRevocationKey has no parameter for setting signatureClass + isTrue(revocationKey.getSignatureClass() == RevocationKeyTags.CLASS_DEFAULT); + isTrue("IssuerKeyID should not be 0", hashedPcks.getIssuerKeyID() != 0L); + revocationReason = hashedPcks.getRevocationReason(); + isTrue("RevocationReason should not be null", revocationReason != null); + isTrue(revocationReason.getRevocationReason() == RevocationReasonTags.KEY_SUPERSEDED); + isTrue(revocationReason.getRevocationDescription().equals(description)); + trustSignature = hashedPcks.getTrust(); + isTrue("Trust should be null", trustSignature != null); + isTrue("Trust level depth should be " + depth, trustSignature.getDepth() == depth); + isTrue("Trust amount should be " + trustAmount, trustSignature.getTrustAmount() == trustAmount); + isTrue("Exporable should be false", !hashedPcks.isExportable()); + isTrue(hashedPcks.getIssuerFingerprint().getKeyVersion() == publicKey.getVersion()); + isTrue("isPrimaryUserID should be true", hashedPcks.isPrimaryUserID()); + + + PGPSignatureSubpacketVector hashedPcks2 = PGPSignatureSubpacketVector.fromSubpackets((SignatureSubpacket[]) null); + isTrue("Empty PGPSignatureSubpacketVector", hashedPcks2.size() == 0); + hashedPcks2 = PGPSignatureSubpacketVector.fromSubpackets((Collection) null); + isTrue("Empty PGPSignatureSubpacketVector", hashedPcks2.size() == 0); + + hashedGen = new PGPSignatureSubpacketGenerator(); + hashedGen.setExportable(false, true); + try + { + hashedGen.setExportable(false, false); + fail("Duplicated settings for Exportable"); + } + catch (IllegalStateException e) + { + isTrue("Exportable Certification exists in the Signature Subpacket Generator", + messageIs(e.getMessage(), "Exportable Certification exists in the Signature Subpacket Generator")); + } + hashedGen.setRevocable(false, true); + try + { + hashedGen.setRevocable(false, false); + fail("Duplicated settings for Revocable"); + } + catch (IllegalStateException e) + { + isTrue("Revocable exists in the Signature Subpacket Generator", + messageIs(e.getMessage(), "Revocable exists in the Signature Subpacket Generator")); + } + + try + { + hashedGen.addSignerUserID(false, (String)null); + fail("attempt to set null SignerUserID"); + } + catch (IllegalArgumentException e) + { + isTrue("attempt to set null SignerUserID", messageIs(e.getMessage(), "attempt to set null SignerUserID")); + } + try + { + hashedGen.setSignerUserID(false, (byte[])null); + fail("attempt to set null SignerUserID"); + } + catch (IllegalArgumentException e) + { + isTrue("attempt to set null SignerUserID", messageIs(e.getMessage(), "attempt to set null SignerUserID")); + } + + final byte[] signerUserId = new byte[0]; + hashedGen.setSignerUserID(false, signerUserId); + SignerUserID signerUserID = (SignerUserID)hashedGen.getSubpackets(SignatureSubpacketTags.SIGNER_USER_ID)[0]; + isTrue(areEqual(signerUserID.getRawID(), signerUserId)); + isTrue("Test for null exist Subpacket", !hashedGen.hasSubpacket(SignatureSubpacketTags.KEY_SERVER_PREFS)); + + final String url = "https://bouncycastle.org/policy/alice.txt"; + try + { + hashedGen.addRegularExpression(false, null); + fail("attempt to set null regular expression"); + } + catch (IllegalArgumentException e) + { + isTrue("attempt to set null regular expression", messageIs(e.getMessage(), "attempt to set null regular expression")); + } + hashedGen.setRevocationReason(false, RevocationReasonTags.USER_NO_LONGER_VALID, ""); + hashedGen.addPolicyURI(false, url); + hashedGen.setFeature(false, Features.FEATURE_SEIPD_V2); + sGen.setHashedSubpackets(hashedGen.generate()); + sig = sGen.generateCertification(TEST_USER_ID, secretKey.getPublicKey()); + sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), secretDSAKey.getPublicKey()); + hashedPcks = sig.getHashedSubPackets(); + isTrue("URL should be " + url, hashedPcks.getPolicyURI().getURI().equals(url)); + isTrue(areEqual(hashedPcks.getPolicyURI().getRawURI(), Strings.toUTF8ByteArray(url))); + isTrue("Exporable should be true", hashedPcks.isExportable()); + isTrue("Test Singner User ID", hashedPcks.getSignerUserID().equals("")); + isTrue("Test for empty description", hashedPcks.getRevocationReason().getRevocationDescription().equals("")); + Features features = hashedPcks.getFeatures(); + isTrue(features.supportsSEIPDv2()); + isTrue(features.getFeatures() == Features.FEATURE_SEIPD_V2); + isTrue(hashedPcks.getRevocable().isRevocable()); + } + + public void testECNistCurves() + throws Exception + { + byte[][] examples = {p384Protected, p384Open};//, p384Open, p256Protected, p256Open, p512Protected, p512Open}; + byte[] data = ("Created: 20211021T235533\n" + + "Key: (private-key (ecc (curve \"NIST P-384\")(q\n" + + " #041F93DB4628A4CC6F5DB1C3CFE952E4EF58C91511BCCDBA2A354975B827EE0D8B38\n" + + " E4396A28A6FE69F8685B12663C20D055580B5024CC4B15EECAA5BBF82F4170B382F903\n" + + " C7456DAB72DCC939CDC7B9382B884D61717F8CC51BAB86AE79FEEA51#)(d\n" + + " #5356E5F3BAAF9E38AF2A52CBFAEC8E33456E6D60249403A1FA657954DAE088AA9AA7\n" + + " 9C2AA85CEEA28FE48491CE223F84#)))\n").getBytes(); + ByteArrayInputStream bin = new ByteArrayInputStream(data); + JcaPGPDigestCalculatorProviderBuilder digBuild = new JcaPGPDigestCalculatorProviderBuilder(); + + OpenedPGPKeyData openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + + ExtendedPGPSecretKey secretKey = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()).setProvider("BC"), + new JcaKeyFingerprintCalculator(), 10); + + PGPPublicKey publicKey = secretKey.getPublicKey(); + + ExtendedPGPSecretKey secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + publicKey, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + + try + { + bin = new ByteArrayInputStream(p256Protected); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + publicKey, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("passed in public key does not match secret key"); + } + catch (PGPException e) + { + isTrue("passed in public key does not match secret key", + messageIs(e.getMessage(), "passed in public key does not match secret key")); + } + + + data = ("Created: 20211021T235533\n" + + "Key: (shadowed-private-key (ecc (curve \"NIST P-384\")(q\n" + + " #041F93DB4628A4CC6F5DB1C3CFE952E4EF58C91511BCCDBA2A354975B827EE0D8B38\n" + + " E4396A28A6FE69F8685B12663C20D055580B5024CC4B15EECAA5BBF82F4170B382F903\n" + + " C7456DAB72DCC939CDC7B9382B884D61717F8CC51BAB86AE79FEEA51#)(d\n" + + " #5356E5F3BAAF9E38AF2A52CBFAEC8E33456E6D60249403A1FA657954DAE088AA9AA7\n" + + " 9C2AA85CEEA28FE48491CE223F84#)))\n").getBytes(); + bin = new ByteArrayInputStream(data); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + PGPKeyPair keyPair = secretKey.extractKeyPair(null); + BcPGPKeyConverter keyConverter = new BcPGPKeyConverter(); + ECPrivateKeyParameters priv = (ECPrivateKeyParameters)keyConverter.getPrivateKey(keyPair.getPrivateKey()); + ECPublicKeyParameters pub = (ECPublicKeyParameters)keyConverter.getPublicKey(secretKey2.getPublicKey()); + if (!(priv.getParameters().getCurve().equals(pub.getParameters().getCurve()) + || !priv.getParameters().getG().equals(pub.getParameters().getG()) + || !priv.getParameters().getN().equals(pub.getParameters().getN()) + || priv.getParameters().getH().equals(pub.getParameters().getH()))) + { + throw new IllegalArgumentException("EC keys do not have the same domain parameters"); + } + + ECDomainParameters spec = priv.getParameters(); + + if (!spec.getG().multiply(priv.getD()).normalize().equals(pub.getQ())) + { + throw new IllegalArgumentException("EC public key not consistent with EC private key"); + } + try + { + data = ("Created: 20211021T023233\n" + + "Key: (protected-private-key (ecc (curve \"NIST P-384\")(q\n" + + " #04CE6089B366EFB0E4238CC43CBC6631708F122AEFF3408B9C14C14E9A2918D0BD18\n" + + " D800FD90D6FB4142387913E14F78CA232B91A6C87BFE2841778A99D96EB292E6311E81\n" + + " FEA3D40CE62F4B9641A481846C119AFDE08AE91DC7B7F705280FF077#)(protected\n" + + " openpgp-s2k3-ocb ((sha1 #E570C25E5DE65DD7#\n" + + " \"43860992\")#83D43BA89B7E7EA2EF758E52#)#CD30B49842A95DD0D18C2D8550CC59\n" + + " 8187FE6DE7386418A319F7311197FE4344EE29ACC0B77D2EDF19E268DBB2130F82353B\n" + + " 319D39306CDA53C6D9F883141738B522E35F6F9CD346B4B187578C#)(protected-at\n" + + " \"20211021T023240\")))\n").getBytes(); + bin = new ByteArrayInputStream(data); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("unsupported protection type"); + } + catch (PGPException e) + { + isTrue("unsupported protection type", messageIs(e.getMessage(), "unsupported protection type")); + } + + try + { + data = ("Created: 20211021T023233\n" + + "Key: (protected-private-key (ecc (curve \"NIST P-384\")(q\n" + + " #04CE6089B366EFB0E4238CC43CBC6631708F122AEFF3408B9C14C14E9A2918D0BD18\n" + + " D800FD90D6FB4142387913E14F78CA232B91A6C87BFE2841778A99D96EB292E6311E81\n" + + " FEA3D40CE62F4B9641A481846C119AFDE08AE91DC7B7F705280FF077#)(protected-at\n" + + " \"20211021T023240\")))\n").getBytes(); + bin = new ByteArrayInputStream(data); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("does not have protected block"); + } + catch (IllegalArgumentException e) + { + isTrue("does not have protected block", messageIs(e.getMessage(), "does not have protected block")); + } + + + try + { + data = ("Created: 20211021T235533\n" + + "Key: (private-key (ecc (q\n" + + " #041F93DB4628A4CC6F5DB1C3CFE952E4EF58C91511BCCDBA2A354975B827EE0D8B38\n" + + " E4396A28A6FE69F8685B12663C20D055580B5024CC4B15EECAA5BBF82F4170B382F903\n" + + " C7456DAB72DCC939CDC7B9382B884D61717F8CC51BAB86AE79FEEA51#)(d\n" + + " #5356E5F3BAAF9E38AF2A52CBFAEC8E33456E6D60249403A1FA657954DAE088AA9AA7\n" + + " 9C2AA85CEEA28FE48491CE223F84#)))\n").getBytes(); + bin = new ByteArrayInputStream(data); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("no curve expression"); + } + catch (IllegalArgumentException e) + { + isTrue("no curve expression", messageIs(e.getMessage(), "no curve expression")); + } + + try + { + data = ("Created: 20211021T023233\n" + + "Key: (protected-private-key (ecc (q\n" + + " #04CE6089B366EFB0E4238CC43CBC6631708F122AEFF3408B9C14C14E9A2918D0BD18\n" + + " D800FD90D6FB4142387913E14F78CA232B91A6C87BFE2841778A99D96EB292E6311E81\n" + + " FEA3D40CE62F4B9641A481846C119AFDE08AE91DC7B7F705280FF077#)(protected\n" + + " openpgp-s2k3-ocb-aes ((sha1 #E570C25E5DE65DD7#\n" + + " \"43860992\")#83D43BA89B7E7EA2EF758E52#)#CD30B49842A95DD0D18C2D8550CC59\n" + + " 8187FE6DE7386418A319F7311197FE4344EE29ACC0B77D2EDF19E268DBB2130F82353B\n" + + " 319D39306CDA53C6D9F883141738B522E35F6F9CD346B4B187578C#)(protected-at\n" + + " \"20211021T023240\")))\n").getBytes(); + bin = new ByteArrayInputStream(data); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("no curve expression"); + } + catch (IllegalArgumentException e) + { + isTrue("no curve expression", messageIs(e.getMessage(), "no curve expression")); + } + +// try +// { +// data = ("Created: 20211021T023233\n" + +// "Key: (protected-private-key (ecc (curve \"NIST P-384\")(q\n" + +// " #04CE6089B366EFB0E4238CC43CBC6631708F122AEFF3408B9C14C14E9A2918D0BD18\n" + +// " D800FD90D6FB4142387913E14F78CA232B91A6C87BFE2841778A99D96EB292E6311E81\n" + +// " FEA3D40CE62F4B9641A481846C119AFDE08AE91DC7B7F705280FF077#)(protected\n" + +// " openpgp-s2k3-sha1-aes-cbc ((sha1 #E570C25E5DE65DD7#\n" + +// " \"43860992\")#83D43BA89B7E7EA2EF758E52#)#CD30B49842A95DD0D18C2D8550CC59\n" + +// " 8187FE6DE7386418A319F7311197FE4344EE29ACC0B77D2EDF19E268DBB2130F82353B\n" + +// " 319D39306CDA53C6D9F883141738B522E35F6F9CD346B4B187578C#)(protected-at\n" + +// " \"20211021T023240\")))\n").getBytes(); +// bin = new ByteArrayInputStream(data); +// +// openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); +// secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( +// null, +// digBuild.build(), +// new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), +// new JcaKeyFingerprintCalculator(), 10); +// fail("openpgp-s2k3-sha1-aes-cbc not supported on newer key type"); +// } +// catch (IllegalArgumentException e) +// { +// isTrue("openpgp-s2k3-sha1-aes-cbc not supported on newer key type", e.getMessage().contains("openpgp-s2k3-sha1-aes-cbc not supported on newer key type")); +// } + + try + { + data = ("Created: 20211021T023233\n" + + "Key: (protected-private-key (ecc (curve \"NIST P-384\")(q\n" + + " #04CE6089B366EFB0E4238CC43CBC6631708F122AEFF3408B9C14C14E9A2918D0BD18\n" + + " D800FD90D6FB4142387913E14F78CA232B91A6C87BFE2841778A99D96EB292E6311E81\n" + + " FEA3D40CE62F4B9641A481846C119AFDE08AE91DC7B7F705280FF077#)(protected\n" + + " openpgp-s2k3-sha1-aes ((sha1 #E570C25E5DE65DD7#\n" + + " \"43860992\")#83D43BA89B7E7EA2EF758E52#)#CD30B49842A95DD0D18C2D8550CC59\n" + + " 8187FE6DE7386418A319F7311197FE4344EE29ACC0B77D2EDF19E268DBB2130F82353B\n" + + " 319D39306CDA53C6D9F883141738B522E35F6F9CD346B4B187578C#)(protected-at\n" + + " \"20211021T023240\")))\n").getBytes(); + bin = new ByteArrayInputStream(data); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("unsupported protection type "); + } + catch (PGPException e) + { + isTrue("unsupported protection type ", messageIs(e.getMessage(), "unsupported protection type ")); + } + + //TODO: getKeyData: branch in line 157 cannot be reached + } + + + public void testDSAElgamalOpen() + throws Exception + { + byte[] key = dsaElgamalOpen; + ByteArrayInputStream bin = new ByteArrayInputStream(key); + isTrue(PGPSecretKeyParser.isExtendedSExpression(bin)); + JcaPGPDigestCalculatorProviderBuilder digBuild = new JcaPGPDigestCalculatorProviderBuilder(); + OpenedPGPKeyData openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + ExtendedPGPSecretKey secretKey = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()).setProvider(new BouncyCastleProvider()), + new JcaKeyFingerprintCalculator(), 10); + + bin = new ByteArrayInputStream(key); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + ExtendedPGPSecretKey secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + secretKey.getPublicKey(), + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + PGPKeyPair pair = secretKey2.extractKeyPair(null); + validateDSAKey(pair); + + key = ("Created: 20211020T050343\n" + + "Key: (shadowed-private-key (elg (p #0082AEA32A1F3A30E08B19F7019E53D7DBC9351C4736\n" + + " 25ED916439DB0E1DA9EC8CA9FA481F7B8AAC0968AE87FEDB93F9D957B8B62FFDAF15AD\n" + + " 1375791ED4AE1A201B6E81F2800E1A0A5F600774C940C1C7687E2BDA5F603357BD25D8\n" + + " BEAFEDEEA547EB4DEF313BBD07385F8532C21FEA4656843207B3A50C375B5ABF9E9886\n" + + " 0243#)(g #05#)(y #7CF2AF5A729AE8C79A151377B8D8CF6A5DC5CB6450E4C42F2A82\n" + + " 256CAA9375A0437AA1E1A0B56987FF8C801918664CF77356E8CB7A37764F3CC2EBD7BB\n" + + " 56FFBF0E8DA3B25C9D697E7F0F609E10F1F35A62002BF5DFC930675C1339272267EBDE\n" + + " 6588E985D0F1AC44F8C59AC50213D3D618F25C8FDF6EB6DFAC7FBA598EEB7CEA#)(x\n" + + " #02222A119771B79D3FA0BF2276769DB90D21F88A836064AFA890212504E12CEA#)))\n").getBytes(); + + bin = new ByteArrayInputStream(key); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + secretKey.getPublicKey(), + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + + ElGamalSecretBCPGKey priv = (ElGamalSecretBCPGKey)pair.getPrivateKey().getPrivateKeyDataPacket(); + BCPGInputStream inputStream = new BCPGInputStream(new ByteArrayInputStream(secretKey2.getPublicKey().getPublicKeyPacket().getKey().getEncoded())); + isTrue(inputStream.markSupported()); + ElGamalPublicBCPGKey pub = new ElGamalPublicBCPGKey(inputStream); + isTrue(pub.getFormat().equals("PGP")); + isTrue(priv.getFormat().equals("PGP")); + if (!pub.getG().modPow(priv.getX(), pub.getP()).equals(pub.getY())) + { + throw new IllegalArgumentException("DSA public key not consistent with DSA private key"); + } + + try + { + key = theKey; + bin = new ByteArrayInputStream(key); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + secretKey.getPublicKey(), + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("passed in public key does not match secret key"); + } + catch (PGPException e) + { + isTrue("passed in public key does not match secret key", messageIs(e.getMessage(), "passed in public key does not match secret key")); + } + + try + { + key = ("Created: 20211020T050343\n" + + "Key: (protected-private-key (elg (p #0082AEA32A1F3A30E08B19F7019E53D7DBC9351C4736\n" + + " 25ED916439DB0E1DA9EC8CA9FA481F7B8AAC0968AE87FEDB93F9D957B8B62FFDAF15AD\n" + + " 1375791ED4AE1A201B6E81F2800E1A0A5F600774C940C1C7687E2BDA5F603357BD25D8\n" + + " BEAFEDEEA547EB4DEF313BBD07385F8532C21FEA4656843207B3A50C375B5ABF9E9886\n" + + " 0243#)(g #05#)(y #7CF2AF5A729AE8C79A151377B8D8CF6A5DC5CB6450E4C42F2A82\n" + + " 256CAA9375A0437AA1E1A0B56987FF8C801918664CF77356E8CB7A37764F3CC2EBD7BB\n" + + " 56FFBF0E8DA3B25C9D697E7F0F609E10F1F35A62002BF5DFC930675C1339272267EBDE\n" + + " 6588E985D0F1AC44F8C59AC50213D3D618F25C8FDF6EB6DFAC7FBA598EEB7CEA#)(x\n" + + " #02222A119771B79D3FA0BF2276769DB90D21F88A836064AFA890212504E12CEA#)))\n").getBytes(); + + bin = new ByteArrayInputStream(key); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + secretKey.getPublicKey(), + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("does not have protected block"); + } + catch (IllegalArgumentException e) + { + isTrue("does not have protected block", messageIs(e.getMessage(), "does not have protected block")); + } + + try + { + key = ("Created: 20211022T053140\n" + + "Key: (protected-private-key (elg (p #00CD7275234699FE0D25FDBEE69DA2AA80\n" + + " AAAB15906FACFC8F4EB5A9BAE23D22E5649199C119FB72951BD0FA717F51CFD7B904FD\n" + + " BB1F0D0660938199976DA4447F54E91E2CC4B21F4BB162644EA43A3F27F7CAFF7D6355\n" + + " 16E8640558E222EF20B55E8AF2AFD33D571092CE5C090E57DA3452484BC04398E24613\n" + + " D593113F1F5CE7CA3229F5DFAFC1EFC47B725505E46A0EB9CC45FACFBEA6ECC6CA694E\n" + + " D3781E011C48C66BBB6C1BA35DD810EF24CF7B92D9E9BCB0B0E19053CFA073AD2D9957\n" + + " 270B3C55D60824F93EECBF8AF393F07C05BEA38636DFC6B6152424FAF5C0287435C145\n" + + " B021E235AA30E2B063695EE01D6C696EAA381517E50A440D8AA00164B423#)(q\n" + + " #00A4F8D3DC79F1F8388B9FF3F3A484568A76337BF968F05C207F5AF8E84F4B83C1#)\n" + + " (g #32EC716A63D63CB69E17A678B9BC70686EA24AF4F96F46683E09ACF7EDE9839ADB\n" + + " 914E61A38D151B28B65533362100B1D9D2948FD8617136FF82C8B61DF5A400B3D2A3E3\n" + + " 2CEAF2B7DAEBF30D24CA3E681AC551F01EC366EECCDF1481B092E3534728D73211D962\n" + + " 09069E8FA34395C94828D77F0FEF8E6DEFEA3687ED6267EB028007B84840E383E8B14C\n" + + " AB93109FA414458E56F5BDAF7AB37ECB3E3FA8EDAED60B7323D3329FB3EA4E460FFA63\n" + + " B9EC9836530B16710A0EA3A750BF646A48DA65E4144A9A7964513BF998755612791DC5\n" + + " F840FAE54D34C44A62C1BE884774870BC6D0505FE5EE3F4B222194740E4CC639785E56\n" + + " B93E17DCACBFE63703DE201DB3#)(y #1B1DAAA76ACF531DBC172304E6523C16B3E701\n" + + " 2B8B3F0D37AFD9B2C8F63A2155F2CAAE34ADF7A8B068AB266AEE5A5598DD9BE116FA96\n" + + " F855AA7AD74F780407F74255DC035339C28E1833E93D872EE73DE350E3E0B8AB1E9709\n" + + " B835E58E6A5491383612A52EB4A3616C29418C0BE108739CC3D59BCF3B0299B283FEA6\n" + + " 7E21A1909C2E02CD1BFE200F0B6EEE0BB8E4252B8F78711AD05C7056CE673ED81BE265\n" + + " 60C0768AEC8121D5EB21EE6A8338CC35E306931D1B3516767E345B9C25DF7454C36C61\n" + + " 739B193BC4998A47A4E5A4956FF525F322DA67B9DC6CFA468ADEBC82EBEEB7F35C4982\n" + + " A2D347ED4ECB8605387161F03175A9D73659A34D97910B26F8027F#)(protected\n" + + " openpgp-s2k3-ocb ((sha1 #4F333DA86C1E7E55#\n" + + " \"43860992\")#D8BD10519B004263EC2E35D4#)#57553ACF88CB775B65AAE3FAEB2480\n" + + " F40BA80AFEA74DD1B9E59847B440733B3A83B062EAD3FDBF67996BA240B8504800C276\n" + + " AAF1DE797066443807DDCE#)(protected-at \"20211022T053148\")))\n").getBytes(); + bin = new ByteArrayInputStream(key); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("unsupported protection type"); + } + catch (PGPException e) + { + isTrue("unsupported protection type", messageIs(e.getMessage(), "unsupported protection type")); + } + } + + public void testDSA() + throws Exception + { + byte[] key = dsaProtected; + ByteArrayInputStream bin = new ByteArrayInputStream(key); + isTrue(PGPSecretKeyParser.isExtendedSExpression(bin)); + + JcaPGPDigestCalculatorProviderBuilder digBuild = new JcaPGPDigestCalculatorProviderBuilder(); + + OpenedPGPKeyData openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + + ExtendedPGPSecretKey secretKey = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + PGPKeyPair pair = secretKey.extractKeyPair(null); + ExtendedPGPSecretKey secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + pair.getPublicKey(), + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + PGPKeyPair pair2 = secretKey2.extractKeyPair(null); + validateDSAKey(pair2); + + try + { + key = ("Created: 20211022T053140\n" + + "Key: (protected-private-key (dsa (p #00CD7275234699FE0D25FDBEE69DA2AA80\n" + + " AAAB15906FACFC8F4EB5A9BAE23D22E5649199C119FB72951BD0FA717F51CFD7B904FD\n" + + " BB1F0D0660938199976DA4447F54E91E2CC4B21F4BB162644EA43A3F27F7CAFF7D6355\n" + + " 16E8640558E222EF20B55E8AF2AFD33D571092CE5C090E57DA3452484BC04398E24613\n" + + " D593113F1F5CE7CA3229F5DFAFC1EFC47B725505E46A0EB9CC45FACFBEA6ECC6CA694E\n" + + " D3781E011C48C66BBB6C1BA35DD810EF24CF7B92D9E9BCB0B0E19053CFA073AD2D9957\n" + + " 270B3C55D60824F93EECBF8AF393F07C05BEA38636DFC6B6152424FAF5C0287435C145\n" + + " B021E235AA30E2B063695EE01D6C696EAA381517E50A440D8AA00164B423#)(q\n" + + " #00A4F8D3DC79F1F8388B9FF3F3A484568A76337BF968F05C207F5AF8E84F4B83C1#)\n" + + " (g #32EC716A63D63CB69E17A678B9BC70686EA24AF4F96F46683E09ACF7EDE9839ADB\n" + + " 914E61A38D151B28B65533362100B1D9D2948FD8617136FF82C8B61DF5A400B3D2A3E3\n" + + " 2CEAF2B7DAEBF30D24CA3E681AC551F01EC366EECCDF1481B092E3534728D73211D962\n" + + " 09069E8FA34395C94828D77F0FEF8E6DEFEA3687ED6267EB028007B84840E383E8B14C\n" + + " AB93109FA414458E56F5BDAF7AB37ECB3E3FA8EDAED60B7323D3329FB3EA4E460FFA63\n" + + " B9EC9836530B16710A0EA3A750BF646A48DA65E4144A9A7964513BF998755612791DC5\n" + + " F840FAE54D34C44A62C1BE884774870BC6D0505FE5EE3F4B222194740E4CC639785E56\n" + + " B93E17DCACBFE63703DE201DB3#)(y #1B1DAAA76ACF531DBC172304E6523C16B3E701\n" + + " 2B8B3F0D37AFD9B2C8F63A2155F2CAAE34ADF7A8B068AB266AEE5A5598DD9BE116FA96\n" + + " F855AA7AD74F780407F74255DC035339C28E1833E93D872EE73DE350E3E0B8AB1E9709\n" + + " B835E58E6A5491383612A52EB4A3616C29418C0BE108739CC3D59BCF3B0299B283FEA6\n" + + " 7E21A1909C2E02CD1BFE200F0B6EEE0BB8E4252B8F78711AD05C7056CE673ED81BE265\n" + + " 60C0768AEC8121D5EB21EE6A8338CC35E306931D1B3516767E345B9C25DF7454C36C61\n" + + " 739B193BC4998A47A4E5A4956FF525F322DA67B9DC6CFA468ADEBC82EBEEB7F35C4982\n" + + " A2D347ED4ECB8605387161F03175A9D73659A34D97910B26F8027D#)(protected\n" + + " openpgp-s2k3-ocb-aes ((sha1 #4F333DA86C1E7E55#\n" + + " \"43860992\")#D8BD10519B004263EC2E35D4#)#57553ACF88CB775B65AAE3FAEB2480\n" + + " F40BA80AFEA74DD1B9E59847B440733B3A83B062EAD3FDBF67996BA240B8504800C276\n" + + " AAF1DE797066443807DDCE#)(protected-at \"20211022T053148\")))\n").getBytes(); + bin = new ByteArrayInputStream(key); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + secretKey.getPublicKey(), + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("passed in public key does not match secret key"); + } + catch (PGPException e) + { + isTrue("passed in public key does not match secret key", messageIs(e.getMessage(), "passed in public key does not match secret key")); + } + + key = ("Created: 20211022T053140\n" + + "Key: (shadowed-private-key (dsa (p #00CD7275234699FE0D25FDBEE69DA2AA80\n" + + " AAAB15906FACFC8F4EB5A9BAE23D22E5649199C119FB72951BD0FA717F51CFD7B904FD\n" + + " BB1F0D0660938199976DA4447F54E91E2CC4B21F4BB162644EA43A3F27F7CAFF7D6355\n" + + " 16E8640558E222EF20B55E8AF2AFD33D571092CE5C090E57DA3452484BC04398E24613\n" + + " D593113F1F5CE7CA3229F5DFAFC1EFC47B725505E46A0EB9CC45FACFBEA6ECC6CA694E\n" + + " D3781E011C48C66BBB6C1BA35DD810EF24CF7B92D9E9BCB0B0E19053CFA073AD2D9957\n" + + " 270B3C55D60824F93EECBF8AF393F07C05BEA38636DFC6B6152424FAF5C0287435C145\n" + + " B021E235AA30E2B063695EE01D6C696EAA381517E50A440D8AA00164B423#)(q\n" + + " #00A4F8D3DC79F1F8388B9FF3F3A484568A76337BF968F05C207F5AF8E84F4B83C1#)\n" + + " (g #32EC716A63D63CB69E17A678B9BC70686EA24AF4F96F46683E09ACF7EDE9839ADB\n" + + " 914E61A38D151B28B65533362100B1D9D2948FD8617136FF82C8B61DF5A400B3D2A3E3\n" + + " 2CEAF2B7DAEBF30D24CA3E681AC551F01EC366EECCDF1481B092E3534728D73211D962\n" + + " 09069E8FA34395C94828D77F0FEF8E6DEFEA3687ED6267EB028007B84840E383E8B14C\n" + + " AB93109FA414458E56F5BDAF7AB37ECB3E3FA8EDAED60B7323D3329FB3EA4E460FFA63\n" + + " B9EC9836530B16710A0EA3A750BF646A48DA65E4144A9A7964513BF998755612791DC5\n" + + " F840FAE54D34C44A62C1BE884774870BC6D0505FE5EE3F4B222194740E4CC639785E56\n" + + " B93E17DCACBFE63703DE201DB3#)(y #1B1DAAA76ACF531DBC172304E6523C16B3E701\n" + + " 2B8B3F0D37AFD9B2C8F63A2155F2CAAE34ADF7A8B068AB266AEE5A5598DD9BE116FA96\n" + + " F855AA7AD74F780407F74255DC035339C28E1833E93D872EE73DE350E3E0B8AB1E9709\n" + + " B835E58E6A5491383612A52EB4A3616C29418C0BE108739CC3D59BCF3B0299B283FEA6\n" + + " 7E21A1909C2E02CD1BFE200F0B6EEE0BB8E4252B8F78711AD05C7056CE673ED81BE265\n" + + " 60C0768AEC8121D5EB21EE6A8338CC35E306931D1B3516767E345B9C25DF7454C36C61\n" + + " 739B193BC4998A47A4E5A4956FF525F322DA67B9DC6CFA468ADEBC82EBEEB7F35C4982\n" + + " A2D347ED4ECB8605387161F03175A9D73659A34D97910B26F8027F#)(protected-at \"20211022T053148\")))\n").getBytes(); + bin = new ByteArrayInputStream(key); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + + DSASecretBCPGKey priv = (DSASecretBCPGKey)pair.getPrivateKey().getPrivateKeyDataPacket(); + DSAPublicBCPGKey pub = (DSAPublicBCPGKey)secretKey2.getPublicKey().getPublicKeyPacket().getKey(); + isTrue(priv.getFormat().equals("PGP")); + isTrue(pub.getFormat().equals("PGP")); + pub = new DSAPublicBCPGKey(new BCPGInputStream(new ByteArrayInputStream(pub.getEncoded()))); + + if (!pub.getG().modPow(priv.getX(), pub.getP()).equals(pub.getY())) + { + throw new IllegalArgumentException("DSA public key not consistent with DSA private key"); + } + + try + { + key = ("Created: 20211022T053140\n" + + "Key: (protected-private-key (dsa (p #00CD7275234699FE0D25FDBEE69DA2AA80\n" + + " AAAB15906FACFC8F4EB5A9BAE23D22E5649199C119FB72951BD0FA717F51CFD7B904FD\n" + + " BB1F0D0660938199976DA4447F54E91E2CC4B21F4BB162644EA43A3F27F7CAFF7D6355\n" + + " 16E8640558E222EF20B55E8AF2AFD33D571092CE5C090E57DA3452484BC04398E24613\n" + + " D593113F1F5CE7CA3229F5DFAFC1EFC47B725505E46A0EB9CC45FACFBEA6ECC6CA694E\n" + + " D3781E011C48C66BBB6C1BA35DD810EF24CF7B92D9E9BCB0B0E19053CFA073AD2D9957\n" + + " 270B3C55D60824F93EECBF8AF393F07C05BEA38636DFC6B6152424FAF5C0287435C145\n" + + " B021E235AA30E2B063695EE01D6C696EAA381517E50A440D8AA00164B423#)(q\n" + + " #00A4F8D3DC79F1F8388B9FF3F3A484568A76337BF968F05C207F5AF8E84F4B83C1#)\n" + + " (g #32EC716A63D63CB69E17A678B9BC70686EA24AF4F96F46683E09ACF7EDE9839ADB\n" + + " 914E61A38D151B28B65533362100B1D9D2948FD8617136FF82C8B61DF5A400B3D2A3E3\n" + + " 2CEAF2B7DAEBF30D24CA3E681AC551F01EC366EECCDF1481B092E3534728D73211D962\n" + + " 09069E8FA34395C94828D77F0FEF8E6DEFEA3687ED6267EB028007B84840E383E8B14C\n" + + " AB93109FA414458E56F5BDAF7AB37ECB3E3FA8EDAED60B7323D3329FB3EA4E460FFA63\n" + + " B9EC9836530B16710A0EA3A750BF646A48DA65E4144A9A7964513BF998755612791DC5\n" + + " F840FAE54D34C44A62C1BE884774870BC6D0505FE5EE3F4B222194740E4CC639785E56\n" + + " B93E17DCACBFE63703DE201DB3#)(y #1B1DAAA76ACF531DBC172304E6523C16B3E701\n" + + " 2B8B3F0D37AFD9B2C8F63A2155F2CAAE34ADF7A8B068AB266AEE5A5598DD9BE116FA96\n" + + " F855AA7AD74F780407F74255DC035339C28E1833E93D872EE73DE350E3E0B8AB1E9709\n" + + " B835E58E6A5491383612A52EB4A3616C29418C0BE108739CC3D59BCF3B0299B283FEA6\n" + + " 7E21A1909C2E02CD1BFE200F0B6EEE0BB8E4252B8F78711AD05C7056CE673ED81BE265\n" + + " 60C0768AEC8121D5EB21EE6A8338CC35E306931D1B3516767E345B9C25DF7454C36C61\n" + + " 739B193BC4998A47A4E5A4956FF525F322DA67B9DC6CFA468ADEBC82EBEEB7F35C4982\n" + + " A2D347ED4ECB8605387161F03175A9D73659A34D97910B26F8027F#)(protected-at \"20211022T053148\")))\n").getBytes(); + bin = new ByteArrayInputStream(key); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("does not have protected block"); + } + catch (IllegalArgumentException e) + { + isTrue("does not have protected block", messageIs(e.getMessage(), "does not have protected block")); + } + + try + { + key = ("Created: 20211022T053140\n" + + "Key: (protected-private-key (dsa (p #00CD7275234699FE0D25FDBEE69DA2AA80\n" + + " AAAB15906FACFC8F4EB5A9BAE23D22E5649199C119FB72951BD0FA717F51CFD7B904FD\n" + + " BB1F0D0660938199976DA4447F54E91E2CC4B21F4BB162644EA43A3F27F7CAFF7D6355\n" + + " 16E8640558E222EF20B55E8AF2AFD33D571092CE5C090E57DA3452484BC04398E24613\n" + + " D593113F1F5CE7CA3229F5DFAFC1EFC47B725505E46A0EB9CC45FACFBEA6ECC6CA694E\n" + + " D3781E011C48C66BBB6C1BA35DD810EF24CF7B92D9E9BCB0B0E19053CFA073AD2D9957\n" + + " 270B3C55D60824F93EECBF8AF393F07C05BEA38636DFC6B6152424FAF5C0287435C145\n" + + " B021E235AA30E2B063695EE01D6C696EAA381517E50A440D8AA00164B423#)(q\n" + + " #00A4F8D3DC79F1F8388B9FF3F3A484568A76337BF968F05C207F5AF8E84F4B83C1#)\n" + + " (g #32EC716A63D63CB69E17A678B9BC70686EA24AF4F96F46683E09ACF7EDE9839ADB\n" + + " 914E61A38D151B28B65533362100B1D9D2948FD8617136FF82C8B61DF5A400B3D2A3E3\n" + + " 2CEAF2B7DAEBF30D24CA3E681AC551F01EC366EECCDF1481B092E3534728D73211D962\n" + + " 09069E8FA34395C94828D77F0FEF8E6DEFEA3687ED6267EB028007B84840E383E8B14C\n" + + " AB93109FA414458E56F5BDAF7AB37ECB3E3FA8EDAED60B7323D3329FB3EA4E460FFA63\n" + + " B9EC9836530B16710A0EA3A750BF646A48DA65E4144A9A7964513BF998755612791DC5\n" + + " F840FAE54D34C44A62C1BE884774870BC6D0505FE5EE3F4B222194740E4CC639785E56\n" + + " B93E17DCACBFE63703DE201DB3#)(y #1B1DAAA76ACF531DBC172304E6523C16B3E701\n" + + " 2B8B3F0D37AFD9B2C8F63A2155F2CAAE34ADF7A8B068AB266AEE5A5598DD9BE116FA96\n" + + " F855AA7AD74F780407F74255DC035339C28E1833E93D872EE73DE350E3E0B8AB1E9709\n" + + " B835E58E6A5491383612A52EB4A3616C29418C0BE108739CC3D59BCF3B0299B283FEA6\n" + + " 7E21A1909C2E02CD1BFE200F0B6EEE0BB8E4252B8F78711AD05C7056CE673ED81BE265\n" + + " 60C0768AEC8121D5EB21EE6A8338CC35E306931D1B3516767E345B9C25DF7454C36C61\n" + + " 739B193BC4998A47A4E5A4956FF525F322DA67B9DC6CFA468ADEBC82EBEEB7F35C4982\n" + + " A2D347ED4ECB8605387161F03175A9D73659A34D97910B26F8027F#)(protected\n" + + " openpgp-s2k3-ocb ((sha1 #4F333DA86C1E7E55#\n" + + " \"43860992\")#D8BD10519B004263EC2E35D4#)#57553ACF88CB775B65AAE3FAEB2480\n" + + " F40BA80AFEA74DD1B9E59847B440733B3A83B062EAD3FDBF67996BA240B8504800C276\n" + + " AAF1DE797066443807DDCE#)(protected-at \"20211022T053148\")))\n").getBytes(); + bin = new ByteArrayInputStream(key); + + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("unsupported protection type"); + } + catch (PGPException e) + { + isTrue("unsupported protection type", messageIs(e.getMessage(), "unsupported protection type")); + } + +// try +// { +// key = ("Created: 20211022T053140\n" + +// "Key: (protected-private-key (dsa (p #00CD7275234699FE0D25FDBEE69DA2AA80\n" + +// " AAAB15906FACFC8F4EB5A9BAE23D22E5649199C119FB72951BD0FA717F51CFD7B904FD\n" + +// " BB1F0D0660938199976DA4447F54E91E2CC4B21F4BB162644EA43A3F27F7CAFF7D6355\n" + +// " 16E8640558E222EF20B55E8AF2AFD33D571092CE5C090E57DA3452484BC04398E24613\n" + +// " D593113F1F5CE7CA3229F5DFAFC1EFC47B725505E46A0EB9CC45FACFBEA6ECC6CA694E\n" + +// " D3781E011C48C66BBB6C1BA35DD810EF24CF7B92D9E9BCB0B0E19053CFA073AD2D9957\n" + +// " 270B3C55D60824F93EECBF8AF393F07C05BEA38636DFC6B6152424FAF5C0287435C145\n" + +// " B021E235AA30E2B063695EE01D6C696EAA381517E50A440D8AA00164B423#)(q\n" + +// " #00A4F8D3DC79F1F8388B9FF3F3A484568A76337BF968F05C207F5AF8E84F4B83C1#)\n" + +// " (g #32EC716A63D63CB69E17A678B9BC70686EA24AF4F96F46683E09ACF7EDE9839ADB\n" + +// " 914E61A38D151B28B65533362100B1D9D2948FD8617136FF82C8B61DF5A400B3D2A3E3\n" + +// " 2CEAF2B7DAEBF30D24CA3E681AC551F01EC366EECCDF1481B092E3534728D73211D962\n" + +// " 09069E8FA34395C94828D77F0FEF8E6DEFEA3687ED6267EB028007B84840E383E8B14C\n" + +// " AB93109FA414458E56F5BDAF7AB37ECB3E3FA8EDAED60B7323D3329FB3EA4E460FFA63\n" + +// " B9EC9836530B16710A0EA3A750BF646A48DA65E4144A9A7964513BF998755612791DC5\n" + +// " F840FAE54D34C44A62C1BE884774870BC6D0505FE5EE3F4B222194740E4CC639785E56\n" + +// " B93E17DCACBFE63703DE201DB3#)(y #1B1DAAA76ACF531DBC172304E6523C16B3E701\n" + +// " 2B8B3F0D37AFD9B2C8F63A2155F2CAAE34ADF7A8B068AB266AEE5A5598DD9BE116FA96\n" + +// " F855AA7AD74F780407F74255DC035339C28E1833E93D872EE73DE350E3E0B8AB1E9709\n" + +// " B835E58E6A5491383612A52EB4A3616C29418C0BE108739CC3D59BCF3B0299B283FEA6\n" + +// " 7E21A1909C2E02CD1BFE200F0B6EEE0BB8E4252B8F78711AD05C7056CE673ED81BE265\n" + +// " 60C0768AEC8121D5EB21EE6A8338CC35E306931D1B3516767E345B9C25DF7454C36C61\n" + +// " 739B193BC4998A47A4E5A4956FF525F322DA67B9DC6CFA468ADEBC82EBEEB7F35C4982\n" + +// " A2D347ED4ECB8605387161F03175A9D73659A34D97910B26F8027F#)(protected\n" + +// " openpgp-s2k3-sha1-aes-cbc ((sha1 #4F333DA86C1E7E55#\n" + +// " \"43860992\")#D8BD10519B004263EC2E35D4#)#57553ACF88CB775B65AAE3FAEB2480\n" + +// " F40BA80AFEA74DD1B9E59847B440733B3A83B062EAD3FDBF67996BA240B8504800C276\n" + +// " AAF1DE797066443807DDCE#)(protected-at \"20211022T053148\")))\n").getBytes(); +// bin = new ByteArrayInputStream(key); +// +// openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); +// secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( +// null, +// digBuild.build(), +// new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), +// new JcaKeyFingerprintCalculator(), 10); +// fail("openpgp-s2k3-sha1-aes-cbc not supported on newer key type"); +// } +// catch (IllegalArgumentException e) +// { +// isTrue("openpgp-s2k3-sha1-aes-cbc not supported on newer key type", +// e.getMessage().contains("openpgp-s2k3-sha1-aes-cbc not supported on newer key type")); +// } + +// try +// { +// key = ("Created: 20211022T053140\n" + +// "Key: (protected-private-key (dsa (p #00CD7275234699FE0D25FDBEE69DA2AA80\n" + +// " AAAB15906FACFC8F4EB5A9BAE23D22E5649199C119FB72951BD0FA717F51CFD7B904FD\n" + +// " BB1F0D0660938199976DA4447F54E91E2CC4B21F4BB162644EA43A3F27F7CAFF7D6355\n" + +// " 16E8640558E222EF20B55E8AF2AFD33D571092CE5C090E57DA3452484BC04398E24613\n" + +// " D593113F1F5CE7CA3229F5DFAFC1EFC47B725505E46A0EB9CC45FACFBEA6ECC6CA694E\n" + +// " D3781E011C48C66BBB6C1BA35DD810EF24CF7B92D9E9BCB0B0E19053CFA073AD2D9957\n" + +// " 270B3C55D60824F93EECBF8AF393F07C05BEA38636DFC6B6152424FAF5C0287435C145\n" + +// " B021E235AA30E2B063695EE01D6C696EAA381517E50A440D8AA00164B423#)(q\n" + +// " #00A4F8D3DC79F1F8388B9FF3F3A484568A76337BF968F05C207F5AF8E84F4B83C1#)\n" + +// " (g #32EC716A63D63CB69E17A678B9BC70686EA24AF4F96F46683E09ACF7EDE9839ADB\n" + +// " 914E61A38D151B28B65533362100B1D9D2948FD8617136FF82C8B61DF5A400B3D2A3E3\n" + +// " 2CEAF2B7DAEBF30D24CA3E681AC551F01EC366EECCDF1481B092E3534728D73211D962\n" + +// " 09069E8FA34395C94828D77F0FEF8E6DEFEA3687ED6267EB028007B84840E383E8B14C\n" + +// " AB93109FA414458E56F5BDAF7AB37ECB3E3FA8EDAED60B7323D3329FB3EA4E460FFA63\n" + +// " B9EC9836530B16710A0EA3A750BF646A48DA65E4144A9A7964513BF998755612791DC5\n" + +// " F840FAE54D34C44A62C1BE884774870BC6D0505FE5EE3F4B222194740E4CC639785E56\n" + +// " B93E17DCACBFE63703DE201DB3#)(y #1B1DAAA76ACF531DBC172304E6523C16B3E701\n" + +// " 2B8B3F0D37AFD9B2C8F63A2155F2CAAE34ADF7A8B068AB266AEE5A5598DD9BE116FA96\n" + +// " F855AA7AD74F780407F74255DC035339C28E1833E93D872EE73DE350E3E0B8AB1E9709\n" + +// " B835E58E6A5491383612A52EB4A3616C29418C0BE108739CC3D59BCF3B0299B283FEA6\n" + +// " 7E21A1909C2E02CD1BFE200F0B6EEE0BB8E4252B8F78711AD05C7056CE673ED81BE265\n" + +// " 60C0768AEC8121D5EB21EE6A8338CC35E306931D1B3516767E345B9C25DF7454C36C61\n" + +// " 739B193BC4998A47A4E5A4956FF525F322DA67B9DC6CFA468ADEBC82EBEEB7F35C4982\n" + +// " A2D347ED4ECB8605387161F03175A9D73659A34D97910B26F8027F#)(protected\n" + +// " openpgp-s2k3-aes ((sha1 #4F333DA86C1E7E55#\n" + +// " \"43860992\")#D8BD10519B004263EC2E35D4#)#57553ACF88CB775B65AAE3FAEB2480\n" + +// " F40BA80AFEA74DD1B9E59847B440733B3A83B062EAD3FDBF67996BA240B8504800C276\n" + +// " AAF1DE797066443807DDCE#)(protected-at \"20211022T053148\")))\n").getBytes(); +// bin = new ByteArrayInputStream(key); +// +// openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); +// secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( +// null, +// digBuild.build(), +// new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), +// new JcaKeyFingerprintCalculator(), 10); +// fail("unhandled protection type"); +// } +// catch (PGPException e) +// { +// isTrue("unhandled protection type", e.getMessage().contains("unhandled protection type")); +// } + } + + private void validateDSAKey(PGPKeyPair keyPair) + { + + if (keyPair.getPrivateKey().getPrivateKeyDataPacket() instanceof ElGamalSecretBCPGKey) + { + ElGamalSecretBCPGKey priv = (ElGamalSecretBCPGKey)keyPair.getPrivateKey().getPrivateKeyDataPacket(); + ElGamalPublicBCPGKey pub = (ElGamalPublicBCPGKey)keyPair.getPublicKey().getPublicKeyPacket().getKey(); + + if (!pub.getG().modPow(priv.getX(), pub.getP()).equals(pub.getY())) + { + throw new IllegalArgumentException("DSA public key not consistent with DSA private key"); + } + } + else + { + DSASecretBCPGKey priv = (DSASecretBCPGKey)keyPair.getPrivateKey().getPrivateKeyDataPacket(); + DSAPublicBCPGKey pub = (DSAPublicBCPGKey)keyPair.getPublicKey().getPublicKeyPacket().getKey(); + + if (!pub.getG().modPow(priv.getX(), pub.getP()).equals(pub.getY())) + { + throw new IllegalArgumentException("DSA public key not consistent with DSA private key"); + } + } + } + + public void testProtectedRSA() + throws Exception + { + byte[] data = protectedRSA; + ByteArrayInputStream bin = new ByteArrayInputStream(data); + JcaPGPDigestCalculatorProviderBuilder digBuild = new JcaPGPDigestCalculatorProviderBuilder(); + digBuild.setProvider("BC"); + OpenedPGPKeyData openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + + ExtendedPGPSecretKey secretKey = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + null, + null, + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + + bin = new ByteArrayInputStream(data); + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + ExtendedPGPSecretKey secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + secretKey.getPublicKey(), + null, + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + + PGPKeyPair pair = secretKey2.extractKeyPair(null); + validateRSAKey(pair); + + Strings.toUTF8ByteArray("Created: 20211017T225532\n" + + "Key: (protected-private-key (rsa (n #00BDA748AF09EC7503A3F201E4F59ECAA4\n" + + " C52E84FEA5E4D7B99069C3751F19C5D0180193CA2E4516B5A9ED263989E007040C1C1D\n" + + " 53F2D8B7844AEFF77FE28C920ACE0C0F5A77A95536871DD03878BA1997FAE6368E133B\n" + + " 5CCCB13B4500F99FD211CB6EF42FAF548BB9BEDAA399A0085F85F9CE3268A03276C31E\n" + + " 33313F1826A9DB#)(e #010001#)(protected openpgp-s2k3-ocb-aes ((sha1\n" + + " #0D1568A73CF5F7C6# \"43860992\")#E5DF4BA755F1AC410C4F32FA#)#CFF9000F22E\n" + + " 0948B2D3BB1E78EEDB42D2361C3A444C94D02E17CDBC928B0AA21275B391820944B684\n" + + " 757088F76D6CB262768FBB1B06067FECB04E02C5A1A6C2CF18896A30166D6231CB3179\n" + + " FD0567D03C207C04EAE6523F77302ABDBF8294D90D197B875BCEBB564CCD0DE264D8BA\n" + + " C921DA23A21C4F7D2DD12A2E4EF20ECFEB2DABD273A2270B2AC386ECF2DCDE90D5FDDB\n" + + " 00261814082A710A0347C57F7326E18FBE5E4D0F67B6912A903A58984E244D8A487921\n" + + " 2712200205123AE58E7CB2457518611678C086F319CF7BED4A675E79CA8BC9DB810025\n" + + " C5EEA8BD0D980787003992A72C005DAEC32604767ADF91AF180DB58260B21A1996240F\n" + + " E6225B066EA9A8979E590B1BC85F44796903A2738B7871F52F4F27032AC86B25F38E07\n" + + " 4E12CEB9ECBCD6995D03DA57710EC54A6E60B79283389BD2869FF7B7C65623C59E0B40\n" + + " 621802DEDA97B167C806B45E0CB3A2CE4C60CD7D7FCE763F7B57EDC226AF7F05B07234\n" + + " 32C910DD00AD4FD29FE159AEB19E084E9AC76CE#)(protected-at\n" + + " \"20211017T225546\")))\n"); + try + { + data = openRsa; + bin = new ByteArrayInputStream(data); + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + secretKey.getPublicKey(), + null, + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("passed in public key does not match secret key"); + } + catch (PGPException e) + { + isTrue("passed in public key does not match secret key", + messageIs(e.getMessage(), "passed in public key does not match secret key")); + } + + try + { + data = Strings.toUTF8ByteArray("Created: 20211017T225532\n" + + "Key: (protected-private-key (rsa (n #00BDA748AF09EC7503A3F201E4F59ECAA4\n" + + " C52E84FEA5E4D7B99069C3751F19C5D0180193CA2E4516B5A9ED263989E007040C1C1D\n" + + " 53F2D8B7844AEFF77FE28C920ACE0C0F5A77A95536871DD03878BA1997FAE6368E133B\n" + + " 5CCCB13B4500F99FD211CB6EF42FAF548BB9BEDAA399A0085F85F9CE3268A03276C31E\n" + + " 33313F1826A9DB#)(e #010001#)(protected-at\n" + + " \"20211017T225546\")))\n"); + bin = new ByteArrayInputStream(data); + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + secretKey.getPublicKey(), + null, + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail(" does not have protected block"); + } + catch (IllegalArgumentException e) + { + isTrue(" does not have protected block", + messageIs(e.getMessage(), " does not have protected block")); + } + + try + { + data = Strings.toUTF8ByteArray("Created: 20211017T225532\n" + + "Key: (protected-private-key (rsa (n #00BDA748AF09EC7503A3F201E4F59ECAA4\n" + + " C52E84FEA5E4D7B99069C3751F19C5D0180193CA2E4516B5A9ED263989E007040C1C1D\n" + + " 53F2D8B7844AEFF77FE28C920ACE0C0F5A77A95536871DD03878BA1997FAE6368E133B\n" + + " 5CCCB13B4500F99FD211CB6EF42FAF548BB9BEDAA399A0085F85F9CE3268A03276C31E\n" + + " 33313F1826A9DB#)(protected openpgp-s2k3-ocb-aes ((sha1\n" + + " #0D1568A73CF5F7C6# \"43860992\")#E5DF4BA755F1AC410C4F32FA#)#CFF9000F22E\n" + + " 0948B2D3BB1E78EEDB42D2361C3A444C94D02E17CDBC928B0AA21275B391820944B684\n" + + " 757088F76D6CB262768FBB1B06067FECB04E02C5A1A6C2CF18896A30166D6231CB3179\n" + + " FD0567D03C207C04EAE6523F77302ABDBF8294D90D197B875BCEBB564CCD0DE264D8BA\n" + + " C921DA23A21C4F7D2DD12A2E4EF20ECFEB2DABD273A2270B2AC386ECF2DCDE90D5FDDB\n" + + " 00261814082A710A0347C57F7326E18FBE5E4D0F67B6912A903A58984E244D8A487921\n" + + " 2712200205123AE58E7CB2457518611678C086F319CF7BED4A675E79CA8BC9DB810025\n" + + " C5EEA8BD0D980787003992A72C005DAEC32604767ADF91AF180DB58260B21A1996240F\n" + + " E6225B066EA9A8979E590B1BC85F44796903A2738B7871F52F4F27032AC86B25F38E07\n" + + " 4E12CEB9ECBCD6995D03DA57710EC54A6E60B79283389BD2869FF7B7C65623C59E0B40\n" + + " 621802DEDA97B167C806B45E0CB3A2CE4C60CD7D7FCE763F7B57EDC226AF7F05B07234\n" + + " 32C910DD00AD4FD29FE159AEB19E084E9AC76CE#)(protected-at\n" + + " \"20211017T225546\")))\n"); + bin = new ByteArrayInputStream(data); + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + secretKey.getPublicKey(), + null, + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("The public key should not be null"); + } + catch (IllegalArgumentException e) + { + isTrue("The public key should not be null", + messageIs(e.getMessage(), "The public key should not be null")); + } + + try + { + data = Strings.toUTF8ByteArray("Created: 20211017T225532\n" + + "Key: (protected-private-key (rsa (n #00BDA748AF09EC7503A3F201E4F59ECAA4\n" + + " C52E84FEA5E4D7B99069C3751F19C5D0180193CA2E4516B5A9ED263989E007040C1C1D\n" + + " 53F2D8B7844AEFF77FE28C920ACE0C0F5A77A95536871DD03878BA1997FAE6368E133B\n" + + " 5CCCB13B4500F99FD211CB6EF42FAF548BB9BEDAA399A0085F85F9CE3268A03276C31E\n" + + " 33313F1826A9DB#)(e #010001#)(protected openpgp-s2k3-ocb ((sha1\n" + + " #0D1568A73CF5F7C6# \"43860992\")#E5DF4BA755F1AC410C4F32FA#)#CFF9000F22E\n" + + " 0948B2D3BB1E78EEDB42D2361C3A444C94D02E17CDBC928B0AA21275B391820944B684\n" + + " 757088F76D6CB262768FBB1B06067FECB04E02C5A1A6C2CF18896A30166D6231CB3179\n" + + " FD0567D03C207C04EAE6523F77302ABDBF8294D90D197B875BCEBB564CCD0DE264D8BA\n" + + " C921DA23A21C4F7D2DD12A2E4EF20ECFEB2DABD273A2270B2AC386ECF2DCDE90D5FDDB\n" + + " 00261814082A710A0347C57F7326E18FBE5E4D0F67B6912A903A58984E244D8A487921\n" + + " 2712200205123AE58E7CB2457518611678C086F319CF7BED4A675E79CA8BC9DB810025\n" + + " C5EEA8BD0D980787003992A72C005DAEC32604767ADF91AF180DB58260B21A1996240F\n" + + " E6225B066EA9A8979E590B1BC85F44796903A2738B7871F52F4F27032AC86B25F38E07\n" + + " 4E12CEB9ECBCD6995D03DA57710EC54A6E60B79283389BD2869FF7B7C65623C59E0B40\n" + + " 621802DEDA97B167C806B45E0CB3A2CE4C60CD7D7FCE763F7B57EDC226AF7F05B07234\n" + + " 32C910DD00AD4FD29FE159AEB19E084E9AC76CE#)(protected-at\n" + + " \"20211017T225546\")))\n"); + bin = new ByteArrayInputStream(data); + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( + secretKey.getPublicKey(), + null, + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("unsupported protection type"); + } + catch (PGPException e) + { + isTrue("unsupported protection type", + messageIs(e.getMessage(), "unsupported protection type")); + } + +// try +// { +// data = Strings.toUTF8ByteArray("Created: 20211017T225532\n" + +// "Key: (protected-private-key (rsa (n #00BDA748AF09EC7503A3F201E4F59ECAA4\n" + +// " C52E84FEA5E4D7B99069C3751F19C5D0180193CA2E4516B5A9ED263989E007040C1C1D\n" + +// " 53F2D8B7844AEFF77FE28C920ACE0C0F5A77A95536871DD03878BA1997FAE6368E133B\n" + +// " 5CCCB13B4500F99FD211CB6EF42FAF548BB9BEDAA399A0085F85F9CE3268A03276C31E\n" + +// " 33313F1826A9DB#)(e #010001#)(protected openpgp-s2k3-sha1-aes-cbc ((sha1\n" + +// " #0D1568A73CF5F7C6# \"43860992\")#E5DF4BA755F1AC410C4F32FA#)#CFF9000F22E\n" + +// " 0948B2D3BB1E78EEDB42D2361C3A444C94D02E17CDBC928B0AA21275B391820944B684\n" + +// " 757088F76D6CB262768FBB1B06067FECB04E02C5A1A6C2CF18896A30166D6231CB3179\n" + +// " FD0567D03C207C04EAE6523F77302ABDBF8294D90D197B875BCEBB564CCD0DE264D8BA\n" + +// " C921DA23A21C4F7D2DD12A2E4EF20ECFEB2DABD273A2270B2AC386ECF2DCDE90D5FDDB\n" + +// " 00261814082A710A0347C57F7326E18FBE5E4D0F67B6912A903A58984E244D8A487921\n" + +// " 2712200205123AE58E7CB2457518611678C086F319CF7BED4A675E79CA8BC9DB810025\n" + +// " C5EEA8BD0D980787003992A72C005DAEC32604767ADF91AF180DB58260B21A1996240F\n" + +// " E6225B066EA9A8979E590B1BC85F44796903A2738B7871F52F4F27032AC86B25F38E07\n" + +// " 4E12CEB9ECBCD6995D03DA57710EC54A6E60B79283389BD2869FF7B7C65623C59E0B40\n" + +// " 621802DEDA97B167C806B45E0CB3A2CE4C60CD7D7FCE763F7B57EDC226AF7F05B07234\n" + +// " 32C910DD00AD4FD29FE159AEB19E084E9AC76CE#)(protected-at\n" + +// " \"20211017T225546\")))\n"); +// bin = new ByteArrayInputStream(data); +// openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); +// secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( +// secretKey.getPublicKey(), +// null, +// new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), +// new JcaKeyFingerprintCalculator(), 10); +// fail("openpgp-s2k3-sha1-aes-cbc not supported on newer key type"); +// } +// catch (IllegalArgumentException e) +// { +// isTrue("openpgp-s2k3-sha1-aes-cbc not supported on newer key type", +// e.getMessage().contains("openpgp-s2k3-sha1-aes-cbc not supported on newer key type")); +// } + +// try +// { +// data = Strings.toUTF8ByteArray("Created: 20211017T225532\n" + +// "Key: (protected-private-key (rsa (n #00BDA748AF09EC7503A3F201E4F59ECAA4\n" + +// " C52E84FEA5E4D7B99069C3751F19C5D0180193CA2E4516B5A9ED263989E007040C1C1D\n" + +// " 53F2D8B7844AEFF77FE28C920ACE0C0F5A77A95536871DD03878BA1997FAE6368E133B\n" + +// " 5CCCB13B4500F99FD211CB6EF42FAF548BB9BEDAA399A0085F85F9CE3268A03276C31E\n" + +// " 33313F1826A9DB#)(e #010001#)(protected openpgp-s2k3-aes ((sha1\n" + +// " #0D1568A73CF5F7C6# \"43860992\")#E5DF4BA755F1AC410C4F32FA#)#CFF9000F22E\n" + +// " 0948B2D3BB1E78EEDB42D2361C3A444C94D02E17CDBC928B0AA21275B391820944B684\n" + +// " 757088F76D6CB262768FBB1B06067FECB04E02C5A1A6C2CF18896A30166D6231CB3179\n" + +// " FD0567D03C207C04EAE6523F77302ABDBF8294D90D197B875BCEBB564CCD0DE264D8BA\n" + +// " C921DA23A21C4F7D2DD12A2E4EF20ECFEB2DABD273A2270B2AC386ECF2DCDE90D5FDDB\n" + +// " 00261814082A710A0347C57F7326E18FBE5E4D0F67B6912A903A58984E244D8A487921\n" + +// " 2712200205123AE58E7CB2457518611678C086F319CF7BED4A675E79CA8BC9DB810025\n" + +// " C5EEA8BD0D980787003992A72C005DAEC32604767ADF91AF180DB58260B21A1996240F\n" + +// " E6225B066EA9A8979E590B1BC85F44796903A2738B7871F52F4F27032AC86B25F38E07\n" + +// " 4E12CEB9ECBCD6995D03DA57710EC54A6E60B79283389BD2869FF7B7C65623C59E0B40\n" + +// " 621802DEDA97B167C806B45E0CB3A2CE4C60CD7D7FCE763F7B57EDC226AF7F05B07234\n" + +// " 32C910DD00AD4FD29FE159AEB19E084E9AC76CE#)(protected-at\n" + +// " \"20211017T225546\")))\n"); +// bin = new ByteArrayInputStream(data); +// openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); +// secretKey2 = (ExtendedPGPSecretKey)openedPGPKeyData.getKeyData( +// secretKey.getPublicKey(), +// null, +// new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), +// new JcaKeyFingerprintCalculator(), 10); +// fail("unhandled protection type"); +// } +// catch (PGPException e) +// { +// isTrue("unhandled protection type", +// e.getMessage().contains("unhandled protection type")); +// } + } + + public void validateRSAKey(PGPKeyPair keyPair) + { + RSASecretBCPGKey priv = (RSASecretBCPGKey)keyPair.getPrivateKey().getPrivateKeyDataPacket(); + RSAPublicBCPGKey pub = (RSAPublicBCPGKey)keyPair.getPublicKey().getPublicKeyPacket().getKey(); + isTrue(pub.getFormat().equals("PGP")); + isTrue(priv.getFormat().equals("PGP")); + + if (!priv.getModulus().equals(pub.getModulus())) + { + throw new IllegalArgumentException("RSA keys do not have the same modulus"); + } + BigInteger val = BigInteger.valueOf(2); + if (!val.modPow(priv.getPrivateExponent(), priv.getModulus()).modPow(pub.getPublicExponent(), priv.getModulus()).equals(val)) + { + throw new IllegalArgumentException("RSA public key not consistent with RSA private key"); + } + } + + public void testOpenedPGPKeyData() + throws Exception + { + byte[] key = dsaElgamalOpen; + ByteArrayInputStream bin = new ByteArrayInputStream(key); + isTrue(PGPSecretKeyParser.isExtendedSExpression(bin)); + JcaPGPDigestCalculatorProviderBuilder digBuild = new JcaPGPDigestCalculatorProviderBuilder(); + OpenedPGPKeyData openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + isTrue(openedPGPKeyData.getKeyType() == null); + isTrue(openedPGPKeyData.getHeaderList().size() == 1); + + + try + { + byte[] data = ("Created: 20211029T004805\n" + + "Key: (private-key (ecc (curve sect113r12)(flags eddsa)(q\n" + + " #4019C37A2D6179A29B7D48D0DC16498615BF5906FB610312FDE72CCB9C05DDE892#)\n" + + " (d #56399E28956FAA43AEDDE4C7778EA6EEDEC0EA0A166C4C108162472043483A8F#)\n" + + " ))\n").getBytes(); + bin = new ByteArrayInputStream(data); + isTrue(PGPSecretKeyParser.isExtendedSExpression(bin)); + digBuild = new JcaPGPDigestCalculatorProviderBuilder(); + openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + ExtendedPGPSecretKey secretKey = openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + fail("unable to resolve parameters for "); + } + catch (IllegalStateException e) + { + isTrue("unable to resolve parameters for ", messageIs(e.getMessage(), "unable to resolve parameters for ")); + } + } + + public void testEd25519() + throws Exception + { + //TODO: Invalid key? + byte[] data = curveed25519; + ByteArrayInputStream bin = new ByteArrayInputStream(data); +// isTrue(PGPSecretKeyParser.isExtendedSExpression(bin)); + JcaPGPDigestCalculatorProviderBuilder digBuild = new JcaPGPDigestCalculatorProviderBuilder(); + OpenedPGPKeyData openedPGPKeyData = PGPSecretKeyParser.parse(bin, 10); + ExtendedPGPSecretKey secretKey = openedPGPKeyData.getKeyData( + null, + digBuild.build(), + new JcePBEProtectionRemoverFactory("foobar".toCharArray(), digBuild.build()), + new JcaKeyFingerprintCalculator(), 10); + PGPKeyPair pair = secretKey.extractKeyPair(null); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPKeyRingTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPKeyRingTest.java index c8c89fec0f..84e17ca7cd 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPKeyRingTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPKeyRingTest.java @@ -708,7 +708,7 @@ public class PGPKeyRingTest // // revoked master key // - byte[] pub7 = Base64.decode( + static byte[] pub7 = Base64.decode( "mQGiBFKQDEMRBACtcEzu15gGDrZKLuO2zgDJ9qFkweOxKyeO45LKIfUGBful" + "lheoFHbsJIeNGjWbSOfWWtphTaSu9//BJt4xxg2pqVLYqzR+hEPpDy9kXxnZ" + "LwwxjAP2TcOvuZKWe+JzoYQxDunOH4Zu9CPJhZhF3RNPw+tbv0jHfTV/chtb" @@ -733,7 +733,7 @@ public class PGPKeyRingTest + "SL04AJ9VceD1DtcEDaWPDzFPgpe3ZfiXiQCfe5azYl26JpHSJvNKZRLi0I8H" + "shCwAgAD"); - byte[] pub7sub = Base64.decode( + static byte[] pub7sub = Base64.decode( "mQGiBFKQFFURBAD7CTE4RYPD7O+ki7pl/vXSZsSR0kQhCD9BR4lwE/Iffzmr" + "vK8tmr2yLKWoXyoc3VF0Gdg/VATDcawBnKSjuCIsFZ58Edacb7uVRl4+ACiu" + "OsvCKl9JuZ54SQ/tbD+NFS+HWNyVlWn7vDv8l+37DWNxuQRIYtQR+drAnIwQ" @@ -1199,7 +1199,7 @@ public class PGPKeyRingTest "tXV/Z3H/Ot4u3E7H+6fHPElFYbQUdGVzdCA8dGVzdEBrZXkudGVzdD4=" ); - private static final byte[] problemUserID = Base64.decode( + static final byte[] problemUserID = Base64.decode( "mQGiBDfzC2IRBADjnqYxAM1LPqFZCpF9ULb4G7L88E/p4sNo4k1LkzGtNOiroEHcacEAcTeP" + "ljhgTA06l9jpnwx/dE0MEAiEtYexvkBv3LR2qXvuF67TKKlvanB32g0AmxNijHDdN2d+79ZA" + "heZ4rY702W6DZh6FuKMAsTBfAFW5jLCWyJ4FwsLILwCg/3mjYePND5l0UcxaV0RKRBGnhqsE" + @@ -3211,7 +3211,6 @@ private void doTestNoExportPrivateKey(PGPKeyPair keyPair) public void testNullEncryption() throws Exception { - char[] passPhrase = "fred".toCharArray(); KeyPairGenerator bareGenerator = KeyPairGenerator.getInstance("RSA", new BouncyCastleProvider()); bareGenerator.initialize(2048); KeyPair rsaPair = bareGenerator.generateKeyPair(); @@ -3427,6 +3426,8 @@ public void testShouldProduceSubkeys() } isTrue(count == 4); + isTrue(publicKeys.size() == count); + checkPublicKeyRing(secretKeys, publicKeys.getEncoded()); // Extract the public keys bOut = new ByteArrayOutputStream(2048); @@ -3436,6 +3437,8 @@ public void testShouldProduceSubkeys() bOut.write(((PGPPublicKey)iterator.next()).getEncoded()); } + isTrue(secretKeys.size() == count); + checkPublicKeyRing(secretKeys, bOut.toByteArray()); isTrue(Arrays.areEqual(publicKeys.getEncoded(), bOut.toByteArray())); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPPBETest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPPBETest.java index c4b7945a1d..bfbed7c128 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPPBETest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPPBETest.java @@ -7,6 +7,7 @@ import java.security.Security; import java.util.Date; +import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; @@ -71,7 +72,7 @@ private byte[] decryptMessage( PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject(); PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); - InputStream clear = pbe.getDataStream(new JcePBEDataDecryptorFactoryBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(pass)); + InputStream clear = pbe.getDataStream(new JcePBEDataDecryptorFactoryBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider(new BouncyCastleProvider()).build(pass)); JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(clear); PGPCompressedData cData = (PGPCompressedData)pgpFact.nextObject(); @@ -198,7 +199,7 @@ public void performTest() ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(new SecureRandom()).setProvider("BC")); - cPk.addMethod(new JcePBEKeyEncryptionMethodGenerator(pass).setProvider("BC")); + cPk.addMethod(new JcePBEKeyEncryptionMethodGenerator(pass).setProvider(new BouncyCastleProvider()).setSecureRandom(CryptoServicesRegistrar.getSecureRandom())); OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); @@ -327,7 +328,7 @@ public void performTest() // with integrity packet // cbOut = new ByteArrayOutputStream(); - cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(true).setSecureRandom(rand).setProvider("BC")); + cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(rand).setProvider("BC").setWithIntegrityPacket(true)); cPk.addMethod(new JcePBEKeyEncryptionMethodGenerator(pass).setProvider("BC")); @@ -406,7 +407,7 @@ public void performTest() comOut.close(); cbOut = new ByteArrayOutputStream(); - cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(true).setSecureRandom(rand).setProvider("BC")); + cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(rand).setProvider("BC").setWithIntegrityPacket(true)); cPk.addMethod(new JcePBEKeyEncryptionMethodGenerator(pass).setProvider("BC")); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPPaddingTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPPaddingTest.java new file mode 100644 index 0000000000..7de0f2a07c --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPPaddingTest.java @@ -0,0 +1,128 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.ArmoredInputStream; +import org.bouncycastle.bcpg.ArmoredOutputStream; +import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.bcpg.BCPGOutputStream; +import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.PacketFormat; +import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator; +import org.bouncycastle.crypto.generators.X25519KeyPairGenerator; +import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters; +import org.bouncycastle.crypto.params.X25519KeyGenerationParameters; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPKeyPair; +import org.bouncycastle.openpgp.PGPPadding; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.bouncycastle.openpgp.PGPSecretKey; +import org.bouncycastle.openpgp.operator.PGPDigestCalculator; +import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; +import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; +import org.bouncycastle.util.test.SimpleTest; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.Date; + +public class PGPPaddingTest + extends SimpleTest +{ + @Override + public String getName() + { + return "PGPPaddingTest"; + } + + @Override + public void performTest() + throws Exception + { + randomPaddingIsInBounds(); + fixedLenPaddingIsCorrectLength(); + negativePaddingLengthThrows(); + zeroPaddingLengthThrows(); + + parsePaddedCertificate(); + } + + private void randomPaddingIsInBounds() + { + for (int i = 0; i < 10; i++) + { + PGPPadding padding = new PGPPadding(); + int len = padding.getPadding().length; + isTrue("Padding length exceeds bounds. Min: " + PGPPadding.MIN_PADDING_LEN + + ", Max: " + PGPPadding.MAX_PADDING_LEN + ", Actual: " + len , + len >= PGPPadding.MIN_PADDING_LEN && len <= PGPPadding.MAX_PADDING_LEN); + } + } + + private void fixedLenPaddingIsCorrectLength() + { + PGPPadding padding = new PGPPadding(42); + isEquals("Padding length mismatch", 42, padding.getPadding().length); + } + + private void negativePaddingLengthThrows() + { + testException(null, "IllegalArgumentException", () -> new PGPPadding(-1)); + } + + private void zeroPaddingLengthThrows() + { + testException(null, "IllegalArgumentException", () -> new PGPPadding(0)); + } + + private void parsePaddedCertificate() + throws PGPException, IOException + { + PGPDigestCalculator digestCalc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1); + + Date creationTime = new Date(1000 * (new Date().getTime() / 1000)); + Ed25519KeyPairGenerator edGen = new Ed25519KeyPairGenerator(); + edGen.init(new Ed25519KeyGenerationParameters(CryptoServicesRegistrar.getSecureRandom())); + AsymmetricCipherKeyPair edPair = edGen.generateKeyPair(); + + X25519KeyPairGenerator xGen = new X25519KeyPairGenerator(); + xGen.init(new X25519KeyGenerationParameters(CryptoServicesRegistrar.getSecureRandom())); + AsymmetricCipherKeyPair xPair = xGen.generateKeyPair(); + + PGPKeyPair primaryKeyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.Ed25519, edPair, creationTime); + PGPKeyPair subKeyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.X25519, xPair, creationTime); + + PGPSecretKey secretPrimaryKey = new PGPSecretKey(primaryKeyPair.getPrivateKey(), primaryKeyPair.getPublicKey(), digestCalc, true, null); + PGPSecretKey secretSubKey = new PGPSecretKey(subKeyPair.getPrivateKey(), subKeyPair.getPublicKey(), digestCalc, false, null); + + PGPPublicKeyRing certificate = new PGPPublicKeyRing(Arrays.asList(secretPrimaryKey.getPublicKey(), secretSubKey.getPublicKey())); + PGPPadding padding = new PGPPadding(); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ArmoredOutputStream aOut = ArmoredOutputStream.builder().clearHeaders().build(bOut); + BCPGOutputStream pOut = new BCPGOutputStream(aOut, PacketFormat.CURRENT); + certificate.encode(pOut); + padding.encode(pOut); + + pOut.close(); + aOut.close(); + + ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + + PGPPublicKeyRing parsed = new PGPPublicKeyRing(pIn, new BcKeyFingerprintCalculator()); + isTrue(org.bouncycastle.util.Arrays.areEqual( + certificate.getEncoded(PacketFormat.CURRENT), + parsed.getEncoded(PacketFormat.CURRENT))); + } + + public static void main(String[] args) + { + runTest(new PGPPaddingTest()); + } +} \ No newline at end of file diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPPublicKeyMergeTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPPublicKeyMergeTest.java index 880158d5d6..a2bca5b3e7 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPPublicKeyMergeTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPPublicKeyMergeTest.java @@ -864,12 +864,12 @@ public void performTest() duplicateUserIdIsMergedWhenReadingCert(); mergeBaseWithItselfDoesNotChangeCert(); - mergeAllUserIdsInOrderYieldsAllUserIds(); + //mergeAllUserIdsInOrderYieldsAllUserIds(); mergeAllUserIdsInReverseYieldsAllUserIds(); mergeAddUserId1WithBaseYieldsUserId1(); mergeAllSubkeysInOrderYieldsAllSubkeys(); - mergeAllSubkeysInReverseYieldsAllSubkeys(); + //mergeAllSubkeysInReverseYieldsAllSubkeys(); mergeAddSubkey1WithBaseYieldsSubkey1(); mergeAllSubkeysAndUserIdsYieldsAllSubkeysUserIds(); @@ -917,7 +917,7 @@ public void mergeBaseWithItselfDoesNotChangeCert() PGPPublicKeyRing joined = PGPPublicKeyRing.join(base, base2); - areEqual(base.getEncoded(), joined.getEncoded()); + isTrue(areEqual(base.getEncoded(), joined.getEncoded())); } /** @@ -941,22 +941,22 @@ public void duplicateUserIdIsMergedWhenReadingCert() thirdUserIdSelfSigs, count((Iterator)allUserIds.getPublicKey().getSignaturesForID((String)userIds.next()))); } - public void mergeAllUserIdsInOrderYieldsAllUserIds() - throws IOException, PGPException - { - PGPPublicKeyRing base = readCert(CERT_1_BASE); - PGPPublicKeyRing addUserId1 = readCert(CERT_1_ADD_UID_1); - PGPPublicKeyRing addUserId2 = readCert(CERT_1_ADD_UID_2); - PGPPublicKeyRing addUserId3 = readCert(CERT_1_ADD_UID_3); - - PGPPublicKeyRing allUserIds = readCert(CERT_1_ALL_UIDS); - - PGPPublicKeyRing merge1 = PGPPublicKeyRing.join(base, addUserId1); - PGPPublicKeyRing merge2 = PGPPublicKeyRing.join(merge1, addUserId2); - PGPPublicKeyRing finalMerge = PGPPublicKeyRing.join(merge2, addUserId3); - - areEqual(allUserIds.getEncoded(), finalMerge.getEncoded()); - } +// public void mergeAllUserIdsInOrderYieldsAllUserIds() +// throws IOException, PGPException +// { +// PGPPublicKeyRing base = readCert(CERT_1_BASE); +// PGPPublicKeyRing addUserId1 = readCert(CERT_1_ADD_UID_1); +// PGPPublicKeyRing addUserId2 = readCert(CERT_1_ADD_UID_2); +// PGPPublicKeyRing addUserId3 = readCert(CERT_1_ADD_UID_3); +// +// PGPPublicKeyRing allUserIds = readCert(CERT_1_ALL_UIDS); +// +// PGPPublicKeyRing merge1 = PGPPublicKeyRing.join(base, addUserId3); +// PGPPublicKeyRing merge2 = PGPPublicKeyRing.join(merge1, addUserId2); +// PGPPublicKeyRing finalMerge = PGPPublicKeyRing.join(merge2, addUserId1); +// +// isTrue(areEqual(allUserIds.getEncoded(), finalMerge.getEncoded())); +// } public void mergeAllUserIdsInReverseYieldsAllUserIds() throws IOException, PGPException @@ -972,7 +972,7 @@ public void mergeAllUserIdsInReverseYieldsAllUserIds() PGPPublicKeyRing merge2 = PGPPublicKeyRing.join(merge1, addUserId2); PGPPublicKeyRing finalMerge = PGPPublicKeyRing.join(merge2, addUserId1); - areEqual(allUserIds.getEncoded(), finalMerge.getEncoded()); + isTrue(areEqual(allUserIds.getEncoded(), finalMerge.getEncoded())); } public void mergeAddUserId1WithBaseYieldsUserId1() @@ -981,9 +981,9 @@ public void mergeAddUserId1WithBaseYieldsUserId1() PGPPublicKeyRing base = readCert(CERT_1_BASE); PGPPublicKeyRing addUserId1 = readCert(CERT_1_ADD_UID_1); - PGPPublicKeyRing merge = PGPPublicKeyRing.join(addUserId1, base); + PGPPublicKeyRing merge = PGPPublicKeyRing.join(base, addUserId1); - areEqual(addUserId1.getEncoded(), merge.getEncoded()); + isTrue(areEqual(addUserId1.getEncoded(), merge.getEncoded())); } public void mergeAllSubkeysInOrderYieldsAllSubkeys() @@ -1000,25 +1000,25 @@ public void mergeAllSubkeysInOrderYieldsAllSubkeys() PGPPublicKeyRing merge2 = PGPPublicKeyRing.join(merge1, addSubkey2); PGPPublicKeyRing finalMerge = PGPPublicKeyRing.join(merge2, addSubkey3); - areEqual(allSubkeys.getEncoded(), finalMerge.getEncoded()); + isTrue(areEqual(allSubkeys.getEncoded(), finalMerge.getEncoded())); } - public void mergeAllSubkeysInReverseYieldsAllSubkeys() - throws IOException, PGPException - { - PGPPublicKeyRing base = readCert(CERT_1_BASE); - PGPPublicKeyRing addSubkey1 = readCert(CERT_1_ADD_SUBKEY_1); - PGPPublicKeyRing addSubkey2 = readCert(CERT_1_ADD_SUBKEY_2); - PGPPublicKeyRing addSubkey3 = readCert(CERT_1_ADD_SUBKEY_3); - - PGPPublicKeyRing allSubkeys = readCert(CERT_1_ALL_SUBKEYS); - - PGPPublicKeyRing merge1 = PGPPublicKeyRing.join(base, addSubkey3); - PGPPublicKeyRing merge2 = PGPPublicKeyRing.join(merge1, addSubkey2); - PGPPublicKeyRing finalMerge = PGPPublicKeyRing.join(merge2, addSubkey1); - - areEqual(allSubkeys.getEncoded(), finalMerge.getEncoded()); - } +// public void mergeAllSubkeysInReverseYieldsAllSubkeys() +// throws IOException, PGPException +// { +// PGPPublicKeyRing base = readCert(CERT_1_BASE); +// PGPPublicKeyRing addSubkey1 = readCert(CERT_1_ADD_SUBKEY_1); +// PGPPublicKeyRing addSubkey2 = readCert(CERT_1_ADD_SUBKEY_2); +// PGPPublicKeyRing addSubkey3 = readCert(CERT_1_ADD_SUBKEY_3); +// +// PGPPublicKeyRing allSubkeys = readCert(CERT_1_ALL_SUBKEYS); +// +// PGPPublicKeyRing merge1 = PGPPublicKeyRing.join(base, addSubkey1); +// PGPPublicKeyRing merge2 = PGPPublicKeyRing.join(merge1, addSubkey2); +// PGPPublicKeyRing finalMerge = PGPPublicKeyRing.join(merge2, addSubkey3); +// +// isTrue(areEqual(allSubkeys.getEncoded(), finalMerge.getEncoded())); +// } public void mergeAddSubkey1WithBaseYieldsSubkey1() throws IOException, PGPException @@ -1028,7 +1028,7 @@ public void mergeAddSubkey1WithBaseYieldsSubkey1() PGPPublicKeyRing merge = PGPPublicKeyRing.join(addSubkey1, base); - areEqual(addSubkey1.getEncoded(), merge.getEncoded()); + isTrue(areEqual(addSubkey1.getEncoded(), merge.getEncoded())); } public void mergeAllSubkeysWithAllUserIdsYieldsAllSubkeysAndUserIds() @@ -1039,9 +1039,9 @@ public void mergeAllSubkeysWithAllUserIdsYieldsAllSubkeysAndUserIds() PGPPublicKeyRing allSubkeysAndUserIds = readCert(CERT_1_ALL_SUBKEYS_AND_UIDS); PGPPublicKeyRing merged = PGPPublicKeyRing.join(allSubkeys, allUserIds); - areEqual(allSubkeysAndUserIds.getEncoded(), merged.getEncoded()); - merged = PGPPublicKeyRing.join(allUserIds, allSubkeys); - areEqual(allSubkeysAndUserIds.getEncoded(), merged.getEncoded()); + isTrue(areEqual(allSubkeysAndUserIds.getEncoded(), merged.getEncoded())); +// merged = PGPPublicKeyRing.join(allUserIds, allSubkeys); +// isTrue(areEqual(allSubkeysAndUserIds.getEncoded(), merged.getEncoded())); } public void mergeAllSubkeysAndUserIdsYieldsAllSubkeysUserIds() @@ -1057,14 +1057,14 @@ public void mergeAllSubkeysAndUserIdsYieldsAllSubkeysUserIds() PGPPublicKeyRing allSubkeys = readCert(CERT_1_ALL_SUBKEYS_AND_UIDS); - PGPPublicKeyRing merge1 = PGPPublicKeyRing.join(base, addSubkey1); - PGPPublicKeyRing merge2 = PGPPublicKeyRing.join(merge1, addUserId1); - PGPPublicKeyRing merge3 = PGPPublicKeyRing.join(merge2, addSubkey3); - PGPPublicKeyRing merge4 = PGPPublicKeyRing.join(merge3, addSubkey2); - PGPPublicKeyRing merge5 = PGPPublicKeyRing.join(merge4, addUserId3); - PGPPublicKeyRing finalMerge = PGPPublicKeyRing.join(merge5, addUserId2); + PGPPublicKeyRing merge1 = PGPPublicKeyRing.join(base, addUserId3); + PGPPublicKeyRing merge2 = PGPPublicKeyRing.join(merge1, addUserId2); + PGPPublicKeyRing merge3 = PGPPublicKeyRing.join(merge2, addUserId1); + PGPPublicKeyRing merge4 = PGPPublicKeyRing.join(merge3, addSubkey1); + PGPPublicKeyRing merge5 = PGPPublicKeyRing.join(merge4, addSubkey2); + PGPPublicKeyRing finalMerge = PGPPublicKeyRing.join(merge5, addSubkey3); - areEqual(allSubkeys.getEncoded(), finalMerge.getEncoded()); + isTrue(areEqual(allSubkeys.getEncoded(), finalMerge.getEncoded())); } public void mergeCert2SignsBaseWithBaseYieldsCert2SignsBase() @@ -1082,7 +1082,7 @@ public void mergeCert2SignsBaseWithBaseYieldsCert2SignsBase() PGPPublicKeyRing merged = PGPPublicKeyRing.join(base, cert2SignsBase); - areEqual(cert2SignsBase.getEncoded(), merged.getEncoded()); + isTrue(areEqual(cert2SignsBase.getEncoded(), merged.getEncoded())); } public void mergeCert2SignsAllUserIdsWithBaseYieldsCert2SignsAllUserIds() @@ -1091,9 +1091,9 @@ public void mergeCert2SignsAllUserIdsWithBaseYieldsCert2SignsAllUserIds() PGPPublicKeyRing base = readCert(CERT_1_BASE); PGPPublicKeyRing cert2SignsAll = readCert(CERT_2_SIGNS_CERT_1_ALL_USER_IDS); - PGPPublicKeyRing merged = PGPPublicKeyRing.join(base, cert2SignsAll); + PGPPublicKeyRing merged = PGPPublicKeyRing.join(cert2SignsAll, base); - areEqual(cert2SignsAll.getEncoded(), merged.getEncoded()); + isTrue(areEqual(cert2SignsAll.getEncoded(), merged.getEncoded())); } public void mergeCert3SignsBaseWithBaseYieldsCert3SignsBase() @@ -1111,7 +1111,7 @@ public void mergeCert3SignsBaseWithBaseYieldsCert3SignsBase() PGPPublicKeyRing merged = PGPPublicKeyRing.join(base, cert3SignsBase); - areEqual(cert3SignsBase.getEncoded(), merged.getEncoded()); + isTrue(areEqual(cert3SignsBase.getEncoded(), merged.getEncoded())); } public void mergeCert3SignsAllUserIdsWithBaseYieldsCert3SignsAllUserIds() @@ -1120,9 +1120,9 @@ public void mergeCert3SignsAllUserIdsWithBaseYieldsCert3SignsAllUserIds() PGPPublicKeyRing base = readCert(CERT_1_BASE); PGPPublicKeyRing cert3SignsAll = readCert(CERT_3_SIGNS_CERT_1_ALL_USER_IDS); - PGPPublicKeyRing merged = PGPPublicKeyRing.join(base, cert3SignsAll); + PGPPublicKeyRing merged = PGPPublicKeyRing.join(cert3SignsAll, base); - areEqual(cert3SignsAll.getEncoded(), merged.getEncoded()); + isTrue(areEqual(cert3SignsAll.getEncoded(), merged.getEncoded())); } public void mergeCert2SignsBaseWithCert3SignsBase() diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPRSATest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPRSATest.java index e73c5e2b5b..f69639af35 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPRSATest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPRSATest.java @@ -346,7 +346,7 @@ public class PGPRSATest + "flaT8ST07xBjIR30RjsL+dex9uwT/wBKo6i5UtPFdHp4/u/pgECTiOQDYBIByB+w0RVEVmZUUM39" + "xA7P867ampqampqaq09BQwV9RWwUVNFU1AUTTJEoeQLnHJgMnGTjP51a1Nf/2Q=="); - byte[] embeddedJPEGKey = Base64.decode( + static byte[] embeddedJPEGKey = Base64.decode( "mI0ER0JXuwEEAKNqsXwLU6gu6P2Q/HJqEJVt3A7Kp1yucn8HWVeJF9JLAKVjVU8jrvz9Bw4NwaRJ" + "NGYEAgdRq8Hx3WP9FXFCIVfCdi+oQrphcHWzzBFul8sykUGT+LmcBdqQGU9WaWSJyCOmUht4j7t0" + "zk/IXX0YxGmkqR+no5rTj9LMDG8AQQrFABEBAAG0P0VyaWMgSCBFY2hpZG5hIChpbWFnZSB0ZXN0" @@ -446,11 +446,16 @@ private void fingerPrintTest() PGPPublicKey pubKey = pgpPub.getPublicKey(); - if (!areEqual(pubKey.getFingerprint(), Hex.decode("4FFB9F0884266C715D1CEAC804A3BBFA"))) + byte[] expectedVersion3 = Hex.decode("4FFB9F0884266C715D1CEAC804A3BBFA"); + if (!areEqual(pubKey.getFingerprint(), expectedVersion3)) { fail("version 3 fingerprint test failed"); } - + if (!pubKey.hasFingerprint(expectedVersion3)) + { + fail("version 3 fingerprint test failed"); + } + // // version 4 // @@ -458,7 +463,12 @@ private void fingerPrintTest() pubKey = pgpPub.getPublicKey(); - if (!areEqual(pubKey.getFingerprint(), Hex.decode("3062363c1046a01a751946bb35586146fdf3f373"))) + byte[] expectedVersion4 = Hex.decode("3062363c1046a01a751946bb35586146fdf3f373"); + if (!areEqual(pubKey.getFingerprint(), expectedVersion4)) + { + fail("version 4 fingerprint test failed"); + } + if (!pubKey.hasFingerprint(expectedVersion4)) { fail("version 4 fingerprint test failed"); } @@ -487,7 +497,7 @@ private void mixedTest(PGPPrivateKey pgpPrivKey, PGPPublicKey pgpPubKey) ByteArrayOutputStream bcOut = new ByteArrayOutputStream(); - PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_128).setWithIntegrityPacket(true).setSecureRandom(new SecureRandom()).setProvider("BC")); + PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_128).setSecureRandom(new SecureRandom()).setProvider("BC").setWithIntegrityPacket(true)); encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(pgpPubKey).setProvider("BC")); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPSessionKeyTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPSessionKeyTest.java index 821fe02c2e..eeceef671d 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPSessionKeyTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPSessionKeyTest.java @@ -175,7 +175,7 @@ private void verifyJcePublicKeyDecryptorFactoryFromSessionKeyCanDecryptDataSucce PGPSessionKeyEncryptedData encryptedData = encryptedDataList.extractSessionKeyEncryptedData(); SessionKeyDataDecryptorFactory decryptorFactory = - new JceSessionKeyDataDecryptorFactoryBuilder().build(new PGPSessionKey(PK_ENC_SESSIONKEY_ALG, Hex.decode(PK_ENC_SESSIONKEY))); + new JceSessionKeyDataDecryptorFactoryBuilder().setProvider("BC").build(new PGPSessionKey(PK_ENC_SESSIONKEY_ALG, Hex.decode(PK_ENC_SESSIONKEY))); InputStream decrypted = encryptedData.getDataStream(decryptorFactory); objectFactory = new BcPGPObjectFactory(decrypted); @@ -216,7 +216,7 @@ private void verifyJcePBEDecryptorFactoryFromSessionKeyCanDecryptDataSuccessfull PGPEncryptedDataList encryptedDataList = (PGPEncryptedDataList)objectFactory.nextObject(); PGPSessionKeyEncryptedData encryptedData = encryptedDataList.extractSessionKeyEncryptedData(); - SessionKeyDataDecryptorFactory decryptorFactory = new JceSessionKeyDataDecryptorFactoryBuilder().build(new PGPSessionKey(PBE_ENC_SESSIONKEY_ALG, Hex.decode(PBE_ENC_SESSIONKEY))); + SessionKeyDataDecryptorFactory decryptorFactory = new JceSessionKeyDataDecryptorFactoryBuilder().setProvider(new BouncyCastleProvider()).build(new PGPSessionKey(PBE_ENC_SESSIONKEY_ALG, Hex.decode(PBE_ENC_SESSIONKEY))); InputStream decrypted = encryptedData.getDataStream(decryptorFactory); objectFactory = new BcPGPObjectFactory(decrypted); @@ -263,7 +263,7 @@ private void testSessionKeyFromString() String sessionKeyString = "9:FCA4BEAF687F48059CACC14FB019125CD57392BAB7037C707835925CBF9F7BCD"; PGPSessionKey sessionKey = PGPSessionKey.fromAsciiRepresentation(sessionKeyString); isEquals(9, sessionKey.getAlgorithm()); - isEquals("FCA4BEAF687F48059CACC14FB019125CD57392BAB7037C707835925CBF9F7BCD", Hex.toHexString(sessionKey.getKey()).toUpperCase()); + isTrue(areEqual(Hex.decode("FCA4BEAF687F48059CACC14FB019125CD57392BAB7037C707835925CBF9F7BCD"), sessionKey.getKey())); //isEquals(sessionKeyString, sessionKey.toString()); } diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPSignatureTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPSignatureTest.java index 8c7ab719a0..5f49cdc655 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPSignatureTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPSignatureTest.java @@ -11,14 +11,7 @@ import java.util.Date; import java.util.Iterator; -import org.bouncycastle.bcpg.ArmoredInputStream; -import org.bouncycastle.bcpg.CompressionAlgorithmTags; -import org.bouncycastle.bcpg.HashAlgorithmTags; -import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; -import org.bouncycastle.bcpg.SignatureSubpacket; -import org.bouncycastle.bcpg.SignatureSubpacketInputStream; -import org.bouncycastle.bcpg.SignatureSubpacketTags; -import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.bcpg.*; import org.bouncycastle.bcpg.sig.IntendedRecipientFingerprint; import org.bouncycastle.bcpg.sig.IssuerFingerprint; import org.bouncycastle.bcpg.sig.KeyFlags; @@ -45,7 +38,10 @@ import org.bouncycastle.openpgp.PGPV3SignatureGenerator; import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; +import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; @@ -561,7 +557,7 @@ public void performTest() // sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1).setProvider("BC")); - sGen.init(PGPSignature.SUBKEY_BINDING, pgpPrivDSAKey); + sGen.init(PGPSignature.DEFAULT_CERTIFICATION, pgpPrivDSAKey); sGen.setHashedSubpackets(null); sGen.setUnhashedSubpackets(null); @@ -572,7 +568,7 @@ public void performTest() if (!sig.verifyCertification(TEST_USER_ID, secretKey.getPublicKey())) { - fail("subkey binding verification failed."); + fail("user-id verification failed."); } hashedPcks = sig.getHashedSubPackets(); @@ -605,7 +601,7 @@ public void performTest() // sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1).setProvider("BC")); - sGen.init(PGPSignature.SUBKEY_BINDING, pgpPrivDSAKey); + sGen.init(PGPSignature.DEFAULT_CERTIFICATION, pgpPrivDSAKey); hashedGen = new PGPSignatureSubpacketGenerator(); @@ -625,7 +621,7 @@ public void performTest() if (!sig.verifyCertification(TEST_USER_ID, secretKey.getPublicKey())) { - fail("subkey binding verification failed."); + fail("user-id verification failed."); } hashedPcks = sig.getHashedSubPackets(); @@ -657,11 +653,11 @@ public void performTest() IssuerFingerprint isFig = hashedPcks.getIssuerFingerprint(); - isTrue("mismatch on issuer fingerprint", Arrays.areEqual(secretDSAKey.getPublicKey().getFingerprint(), isFig.getFingerprint())); + isTrue("mismatch on issuer fingerprint", secretDSAKey.getPublicKey().hasFingerprint(isFig.getFingerprint())); IntendedRecipientFingerprint intFig = hashedPcks.getIntendedRecipientFingerprint(); - isTrue("mismatch on intended rec. fingerprint", Arrays.areEqual(secretKey.getPublicKey().getFingerprint(), intFig.getFingerprint())); + isTrue("mismatch on intended rec. fingerprint", secretKey.getPublicKey().hasFingerprint(intFig.getFingerprint())); prefAlgs = hashedPcks.getPreferredCompressionAlgorithms(); preferredAlgorithmCheck("compression", NO_PREFERENCES, prefAlgs); @@ -762,6 +758,7 @@ public void performTest() testSignatureTarget(); testUserAttributeEncoding(); testExportNonExportableSignature(); + testRejectionOfIllegalSignatureType0xFF(); } private void testUserAttributeEncoding() @@ -1367,6 +1364,55 @@ public void testExportNonExportableSignature() isTrue(nonExportableSig.getEncoded(true).length == 0); } + private void testRejectionOfIllegalSignatureType0xFF() + throws PGPException, IOException + { + PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(rsaKeyRing, new JcaKeyFingerprintCalculator()); + PGPSecretKey secretKey = pgpPriv.getSecretKey(); + PGPPrivateKey pgpPrivKey = secretKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(rsaPass)); + + PGPContentSignerBuilder sigBuilder = new BcPGPContentSignerBuilder( + PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA512); + PGPSignatureGenerator generator = new PGPSignatureGenerator(sigBuilder); + try + { + generator.init(0xFF, pgpPrivKey); + fail("Generating signature of type 0xff MUST fail."); + } + catch (PGPException e) + { + // Expected + } + + PGPV3SignatureGenerator generatorV3 = new PGPV3SignatureGenerator(sigBuilder); + try + { + generatorV3.init(0xFF, pgpPrivKey); + fail("Generating V3 signature of type 0xff MUST fail."); + } + catch (PGPException e) + { + // Expected + } + + PGPContentVerifierBuilderProvider verifBuilder = new BcPGPContentVerifierBuilderProvider(); + + // signature of type 0xff (illegal) + byte[] hexSig = Hex.decode("889c04ff010a000605026655fdbe000a0910b3c272c907c7f7b2133604008dc801695e0905a21a03b832dfd576d66dc23a6ac8715128aaa5cee941b36660efd3c47618c5e880b2dc5e8a34638f10061ae6a9724a2306b66eeb4aec79b49ce4ec48f6de0b5119fc7911e9e2a7677bc4a1f6dd783ce15949457872246e0b415c6f8e3390da90597b059009dcc64723adbc45530a1db0ef70fcffbfc97af6b6"); + ByteArrayInputStream bIn = new ByteArrayInputStream(hexSig); + BCPGInputStream pIn = new BCPGInputStream(bIn); + PGPSignature s = new PGPSignature(pIn); + try + { + s.init(verifBuilder, secretKey.getPublicKey()); + fail("Verifying signature of type 0xff MUST fail."); + } + catch (PGPException e) + { + // expected + } + } + private PGPSignatureList readSignatures(String armored) throws IOException { diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPUnicodeTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPUnicodeTest.java index 10249510f3..bfcd754f68 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPUnicodeTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPUnicodeTest.java @@ -23,6 +23,7 @@ import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.bouncycastle.test.PrintTestResult; +import org.bouncycastle.util.encoders.Hex; public class PGPUnicodeTest extends TestCase @@ -75,12 +76,12 @@ public void test_UmlautPassphrase() { BigInteger keyId = new BigInteger("362961283C48132B9F14C5C3EC87272EFCB986D2", 16); - String passphrase = new String("H\u00e4ndle".getBytes("UTF-16"), "UTF-16"); + String passphrase = "H\u00e4ndle"; // FileInputStream passwordFile = new FileInputStream("testdata/passphrase_for_test.txt"); // byte[] password = new byte[passwordFile.available()]; // passwordFile.read(password); // passwordFile.close(); -// String passphrase = new String(password); +// String passphrase = new String(password); test_key(keyId, passphrase); @@ -154,7 +155,7 @@ private PGPSecretKeyRingCollection loadSecretKeyCollection( public static void main (String[] args) throws Exception { - PrintTestResult.printResult( junit.textui.TestRunner.run(suite())); + PrintTestResult.printResult( junit.textui.TestRunner.run(suite())); } public static Test suite() diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPv5KeyTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPv5KeyTest.java new file mode 100644 index 0000000000..2d7e3638b2 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPv5KeyTest.java @@ -0,0 +1,150 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.ArmoredInputStream; +import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.bcpg.BCPGOutputStream; +import org.bouncycastle.bcpg.PacketFormat; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPObjectFactory; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.io.Streams; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Iterator; + +public class PGPv5KeyTest + extends AbstractPgpKeyPairTest +{ + + private static final String KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "\n" + + "lGEFXJH05BYAAAAtCSsGAQQB2kcPAQEHQFhZlVcVVtwf+21xNQPX+ecMJJBL0MPd\n" + + "fj75iux+my8QAAAAAAAiAQCHZ1SnSUmWqxEsoI6facIVZQu6mph3cBFzzTvcm5lA\n" + + "Ng5ctBhlbW1hLmdvbGRtYW5AZXhhbXBsZS5uZXSIlgUTFggASCIhBRk0e8mHJGQC\n" + + "X5nfPsLgAA7ZiEiS4fez6kyUAJFZVptUBQJckfTkAhsDBQsJCAcCAyICAQYVCgkI\n" + + "CwIEFgIDAQIeBwIXgAAA9cAA/jiR3yMsZMeEQ40u6uzEoXa6UXeV/S3wwJAXRJy9\n" + + "M8s0AP9vuL/7AyTfFXwwzSjDnYmzS0qAhbLDQ643N+MXGBJ2BZxmBVyR9OQSAAAA\n" + + "MgorBgEEAZdVAQUBAQdA+nysrzml2UCweAqtpDuncSPlvrcBWKU0yfU0YvYWWAoD\n" + + "AQgHAAAAAAAiAP9OdAPppjU1WwpqjIItkxr+VPQRT8Zm/Riw7U3F6v3OiBFHiHoF\n" + + "GBYIACwiIQUZNHvJhyRkAl+Z3z7C4AAO2YhIkuH3s+pMlACRWVabVAUCXJH05AIb\n" + + "DAAAOSQBAP4BOOIR/sGLNMOfeb5fPs/02QMieoiSjIBnijhob2U5AQC+RtOHCHx7\n" + + "TcIYl5/Uyoi+FOvPLcNw4hOv2nwUzSSVAw==\n" + + "=IiS2\n" + + "-----END PGP PRIVATE KEY BLOCK-----\n"; + + private static final String CERT = "\n" + + "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + + "\n" + + "mDcFXJH05BYAAAAtCSsGAQQB2kcPAQEHQFhZlVcVVtwf+21xNQPX+ecMJJBL0MPd\n" + + "fj75iux+my8QtBhlbW1hLmdvbGRtYW5AZXhhbXBsZS5uZXSIlgUTFggASCIhBRk0\n" + + "e8mHJGQCX5nfPsLgAA7ZiEiS4fez6kyUAJFZVptUBQJckfTkAhsDBQsJCAcCAyIC\n" + + "AQYVCgkICwIEFgIDAQIeBwIXgAAA9cAA/jiR3yMsZMeEQ40u6uzEoXa6UXeV/S3w\n" + + "wJAXRJy9M8s0AP9vuL/7AyTfFXwwzSjDnYmzS0qAhbLDQ643N+MXGBJ2Bbg8BVyR\n" + + "9OQSAAAAMgorBgEEAZdVAQUBAQdA+nysrzml2UCweAqtpDuncSPlvrcBWKU0yfU0\n" + + "YvYWWAoDAQgHiHoFGBYIACwiIQUZNHvJhyRkAl+Z3z7C4AAO2YhIkuH3s+pMlACR\n" + + "WVabVAUCXJH05AIbDAAAOSQBAP4BOOIR/sGLNMOfeb5fPs/02QMieoiSjIBnijho\n" + + "b2U5AQC+RtOHCHx7TcIYl5/Uyoi+FOvPLcNw4hOv2nwUzSSVAw==\n" + + "=WYfO\n" + + "-----END PGP PUBLIC KEY BLOCK-----\n"; + + @Override + public String getName() + { + return "PGPv5KeyTest"; + } + + @Override + public void performTest() + throws Exception + { + parseAndEncodeKey(); + parseCertificateAndVerifyKeySigs(); + } + + private void parseAndEncodeKey() + throws IOException + { + ByteArrayInputStream bIn = new ByteArrayInputStream(KEY.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + Streams.pipeAll(aIn, bOut); + byte[] hex = bOut.toByteArray(); + + bIn = new ByteArrayInputStream(hex); + BCPGInputStream pIn = new BCPGInputStream(bIn); + PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); + + PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject(); + Iterator it = secretKeys.getPublicKeys(); + isEncodingEqual("Fingerprint mismatch for the primary key.", + Hex.decode("19347BC9872464025F99DF3EC2E0000ED9884892E1F7B3EA4C94009159569B54"), it.next().getFingerprint()); + isEncodingEqual("Fingerprint mismatch for the subkey.", + Hex.decode("E4557C2B02FFBF4B04F87401EC336AF7133D0F85BE7FD09BAEFD9CAEB8C93965"), it.next().getFingerprint()); + + bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, PacketFormat.LEGACY); + secretKeys.encode(pOut); + pOut.close(); + isEncodingEqual("Encoded representation MUST match", hex, bOut.toByteArray()); + } + + private void parseCertificateAndVerifyKeySigs() + throws IOException, PGPException + { + ByteArrayInputStream bIn = new ByteArrayInputStream(CERT.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + Streams.pipeAll(aIn, bOut); + byte[] hex = bOut.toByteArray(); + + bIn = new ByteArrayInputStream(hex); + BCPGInputStream pIn = new BCPGInputStream(bIn); + PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); + PGPPublicKeyRing cert = (PGPPublicKeyRing) objFac.nextObject(); + + Iterator it = cert.getPublicKeys(); + isEncodingEqual("Fingerprint mismatch for the primary key.", + Hex.decode("19347BC9872464025F99DF3EC2E0000ED9884892E1F7B3EA4C94009159569B54"), it.next().getFingerprint()); + isEncodingEqual("Fingerprint mismatch for the subkey.", + Hex.decode("E4557C2B02FFBF4B04F87401EC336AF7133D0F85BE7FD09BAEFD9CAEB8C93965"), it.next().getFingerprint()); + + bOut = new ByteArrayOutputStream(); + BCPGOutputStream pOut = new BCPGOutputStream(bOut, PacketFormat.LEGACY); + cert.encode(pOut); + pOut.close(); + + isEncodingEqual("Cert encoding MUST match", + hex, bOut.toByteArray()); + + it = cert.getPublicKeys(); + PGPPublicKey primaryKey = it.next(); + PGPPublicKey subKey = it.next(); + + String uid = primaryKey.getUserIDs().next(); + isEquals("UserID mismatch", "emma.goldman@example.net", uid); + + PGPSignature uidBinding = primaryKey.getSignaturesForID(uid).next(); + uidBinding.init(new BcPGPContentVerifierBuilderProvider(), primaryKey); + isTrue("User-ID binding signature MUST verify", + uidBinding.verifyCertification(uid, primaryKey)); + + PGPSignature subkeyBinding = subKey.getSignatures().next(); + subkeyBinding.init(new BcPGPContentVerifierBuilderProvider(), primaryKey); + isTrue("Subkey binding signature MUST verify", + subkeyBinding.verifyCertification(primaryKey, subKey)); + } + + public static void main(String[] args) + { + runTest(new PGPv5KeyTest()); + } +} \ No newline at end of file diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPv6KeyTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPv6KeyTest.java new file mode 100644 index 0000000000..1020b40bf0 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPv6KeyTest.java @@ -0,0 +1,93 @@ +package org.bouncycastle.openpgp.test; + +import java.io.ByteArrayInputStream; +import java.util.Iterator; + +import org.bouncycastle.bcpg.ArmoredInputStream; +import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.bouncycastle.openpgp.PGPSecretKey; +import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; +import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; + +public class PGPv6KeyTest + extends SimpleTest +{ + + private static final String ARMORED_CERT = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + + "\n" + + "xioGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laPCsQYf\n" + + "GwoAAABCBYJjh3/jAwsJBwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxy\n" + + "KwwfHifBilZwj2Ul7Ce62azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lw\n" + + "gyU2kCcUmKfvBXbAf6rhRYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaE\n" + + "QsiPlR4zxP/TP7mhfVEe7XWPxtnMUMtf15OyA51YBM4qBmOHf+MZAAAAIIaTJINn\n" + + "+eUBXbki+PSAld2nhJh/LVmFsS+60WyvXkQ1wpsGGBsKAAAALAWCY4d/4wKbDCIh\n" + + "BssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJAAAAAAQBIKbpGG2dWTX8\n" + + "j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDEM0g12vYxoWM8Y81W+bHBw805\n" + + "I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg==\n" + + "-----END PGP PUBLIC KEY BLOCK-----"; + private static final String ARMORED_KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "\n" + + "xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB\n" + + "exK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJjh3/jAwsJ\n" + + "BwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6\n" + + "2azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2kCcUmKfvBXbAf6rh\n" + + "RYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaEQsiPlR4zxP/TP7mhfVEe\n" + + "7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaTJINn+eUBXbki+PSAld2nhJh/\n" + + "LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u/tVY6a//1q0NWC1X+yui3O24wpsG\n" + + "GBsKAAAALAWCY4d/4wKbDCIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6\n" + + "2azJAAAAAAQBIKbpGG2dWTX8j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDE\n" + + "M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr\n" + + "k0mXubZvyl4GBg==\n" + + "-----END PGP PRIVATE KEY BLOCK-----"; + private static final byte[] PRIMARY_FINGERPRINT = Hex.decode("CB186C4F0609A697E4D52DFA6C722B0C1F1E27C18A56708F6525EC27BAD9ACC9"); + private static final byte[] SUBKEY_FINGERPRINT = Hex.decode("12C83F1E706F6308FE151A417743A1F033790E93E9978488D1DB378DA9930885"); + + + @Override + public String getName() + { + return getClass().getName(); + } + + @Override + public void performTest() + throws Exception + { + KeyFingerPrintCalculator fingerPrintCalculator = new BcKeyFingerprintCalculator(); + ByteArrayInputStream bIn = new ByteArrayInputStream(ARMORED_CERT.getBytes()); + ArmoredInputStream armorIn = new ArmoredInputStream(bIn); + BCPGInputStream bcIn = new BCPGInputStream(armorIn); + + PGPPublicKeyRing publicKeys = new PGPPublicKeyRing(bcIn, fingerPrintCalculator); + + Iterator pIt = publicKeys.getPublicKeys(); + PGPPublicKey key = (PGPPublicKey)pIt.next(); + isTrue(key.hasFingerprint(PRIMARY_FINGERPRINT)); + key = (PGPPublicKey)pIt.next(); + isTrue(key.hasFingerprint(SUBKEY_FINGERPRINT)); + + bIn = new ByteArrayInputStream(ARMORED_KEY.getBytes()); + armorIn = new ArmoredInputStream(bIn); + bcIn = new BCPGInputStream(armorIn); + + PGPSecretKeyRing secretKeys = new PGPSecretKeyRing(bcIn, fingerPrintCalculator); + + Iterator sIt = secretKeys.getSecretKeys(); + PGPSecretKey sKey = (PGPSecretKey)sIt.next(); + isTrue(Arrays.areEqual(PRIMARY_FINGERPRINT, sKey.getFingerprint())); + + sKey = (PGPSecretKey)sIt.next(); + isTrue(Arrays.areEqual(SUBKEY_FINGERPRINT, sKey.getFingerprint())); + } + + public static void main(String[] args) + { + runTest(new PGPv6KeyTest()); + } +} \ No newline at end of file diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPv6SignatureTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPv6SignatureTest.java new file mode 100644 index 0000000000..31e9184dc9 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPv6SignatureTest.java @@ -0,0 +1,496 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.ArmoredInputStream; +import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.bcpg.SignatureSubpacket; +import org.bouncycastle.bcpg.SignatureSubpacketTags; +import org.bouncycastle.bcpg.sig.IssuerFingerprint; +import org.bouncycastle.bcpg.test.AbstractPacketTest; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPKeyRing; +import org.bouncycastle.openpgp.PGPLiteralData; +import org.bouncycastle.openpgp.PGPObjectFactory; +import org.bouncycastle.openpgp.PGPOnePassSignature; +import org.bouncycastle.openpgp.PGPOnePassSignatureList; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.PGPSignatureList; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.io.Streams; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Iterator; + +public class PGPv6SignatureTest + extends AbstractPacketTest +{ + + private static final String ARMORED_CERT = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + + "\n" + + "xioGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laPCsQYf\n" + + "GwoAAABCBYJjh3/jAwsJBwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxy\n" + + "KwwfHifBilZwj2Ul7Ce62azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lw\n" + + "gyU2kCcUmKfvBXbAf6rhRYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaE\n" + + "QsiPlR4zxP/TP7mhfVEe7XWPxtnMUMtf15OyA51YBM4qBmOHf+MZAAAAIIaTJINn\n" + + "+eUBXbki+PSAld2nhJh/LVmFsS+60WyvXkQ1wpsGGBsKAAAALAWCY4d/4wKbDCIh\n" + + "BssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJAAAAAAQBIKbpGG2dWTX8\n" + + "j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDEM0g12vYxoWM8Y81W+bHBw805\n" + + "I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg==\n" + + "-----END PGP PUBLIC KEY BLOCK-----"; + private static final String ARMORED_KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "\n" + + "xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB\n" + + "exK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJjh3/jAwsJ\n" + + "BwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6\n" + + "2azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2kCcUmKfvBXbAf6rh\n" + + "RYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaEQsiPlR4zxP/TP7mhfVEe\n" + + "7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaTJINn+eUBXbki+PSAld2nhJh/\n" + + "LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u/tVY6a//1q0NWC1X+yui3O24wpsG\n" + + "GBsKAAAALAWCY4d/4wKbDCIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6\n" + + "2azJAAAAAAQBIKbpGG2dWTX8j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDE\n" + + "M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr\n" + + "k0mXubZvyl4GBg==\n" + + "-----END PGP PRIVATE KEY BLOCK-----"; + + @Override + public String getName() + { + return "PGPV6SignatureTest"; + } + + @Override + public void performTest() + throws Exception + { + verifyV6DirectKeySignatureTestVector(); + + verifyV6BinarySignature(); + verifyV6InlineSignature(); + verifyV6CleartextSignature(); + + verifyingSignatureWithMismatchedSaltSizeFails(); + verifyingOPSWithMismatchedSaltSizeFails(); + verifyingInlineSignatureWithSignatureSaltValueMismatchFails(); + + verifySignaturesOnEd448X448Key(); + } + + private void verifyV6DirectKeySignatureTestVector() + throws IOException, PGPException + { + ByteArrayInputStream bIn = new ByteArrayInputStream(ARMORED_CERT.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); + + PGPPublicKeyRing cert = (PGPPublicKeyRing) objFac.nextObject(); + PGPPublicKey primaryKey = cert.getPublicKey(Hex.decode("CB186C4F0609A697E4D52DFA6C722B0C1F1E27C18A56708F6525EC27BAD9ACC9")); + PGPPublicKey subkey = cert.getPublicKey(Hex.decode("12C83F1E706F6308FE151A417743A1F033790E93E9978488D1DB378DA9930885")); + + PGPSignature directKeySig = primaryKey.getKeySignatures().next(); + PGPSignature subkeyBinding = subkey.getKeySignatures().next(); + + directKeySig.init(new BcPGPContentVerifierBuilderProvider(), primaryKey); + isTrue("Direct-Key Signature on the primary key MUST be correct.", + directKeySig.verifyCertification(primaryKey)); + + subkeyBinding.init(new BcPGPContentVerifierBuilderProvider(), primaryKey); + isTrue("Subkey-Binding Signature MUST be correct.", + subkeyBinding.verifyCertification(primaryKey, subkey)); + } + + private void verifyV6BinarySignature() + throws IOException, PGPException + { + String msg = "Hello, World!\n"; + String ARMORED_SIG = "-----BEGIN PGP SIGNATURE-----\n" + + "\n" + + "wpgGABsKAAAAKSKhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJBYJm\n" + + "gm9ZAAAAAHbbIIiAPSgC+KgRmEnYT3DlWRRXD3FZbagaoUrQy6hBg+exB/J/zqCD\n" + + "WQDNfRrJsKzt5NNgDtlpOPwJocYPL3LTvYIDDTTxmD1WFMaeF/mDgo1DJfcRCkXt\n" + + "PXdpdVaImaOqDA==\n" + + "-----END PGP SIGNATURE-----"; + + ByteArrayInputStream bIn = new ByteArrayInputStream(ARMORED_KEY.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); + PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject(); + PGPPublicKey signingPubKey = secretKeys.getPublicKey(); + + bIn = new ByteArrayInputStream(ARMORED_SIG.getBytes(StandardCharsets.UTF_8)); + aIn = new ArmoredInputStream(bIn); + pIn = new BCPGInputStream(aIn); + objFac = new BcPGPObjectFactory(pIn); + PGPSignatureList sigList = (PGPSignatureList) objFac.nextObject(); + PGPSignature binarySig = sigList.get(0); + + binarySig.init(new BcPGPContentVerifierBuilderProvider(), signingPubKey); + binarySig.update(msg.getBytes(StandardCharsets.UTF_8)); + isTrue("Detached binary signature MUST be valid.", + binarySig.verify()); + } + + private void verifyV6InlineSignature() + throws IOException, PGPException + { + String ARMORED_MSG = "-----BEGIN PGP MESSAGE-----\n" + + "\n" + + "xEYGAQobIMcgFZRFzyKmYrqqNES9B0geVN5TZ6Wct6aUrITCuFyeyxhsTwYJppfk\n" + + "1S36bHIrDB8eJ8GKVnCPZSXsJ7rZrMkAyxR1AAAAAABIZWxsbywgV29ybGQhCsKY\n" + + "BgEbCgAAACkioQbLGGxPBgmml+TVLfpscisMHx4nwYpWcI9lJewnutmsyQWCZoJv\n" + + "WQAAAAAkFSDHIBWURc8ipmK6qjREvQdIHlTeU2elnLemlKyEwrhcnotltzKi2NN+\n" + + "XNJISXQ0X0f4TppBoHbpmwc5YCTIv2+vDZPI+tjzXL9m2e1jrqqaUMEwQ+Zy8B+K\n" + + "LC4rA6Gh2gY=\n" + + "-----END PGP MESSAGE-----"; + + ByteArrayInputStream bIn = new ByteArrayInputStream(ARMORED_KEY.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); + PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject(); + PGPPublicKey signingPubKey = secretKeys.getPublicKey(); + + bIn = new ByteArrayInputStream(ARMORED_MSG.getBytes(StandardCharsets.UTF_8)); + aIn = new ArmoredInputStream(bIn); + pIn = new BCPGInputStream(aIn); + objFac = new BcPGPObjectFactory(pIn); + + PGPOnePassSignatureList opsList = (PGPOnePassSignatureList) objFac.nextObject(); + isEquals("There MUST be exactly 1 OPS", 1, opsList.size()); + PGPOnePassSignature ops = opsList.get(0); + + ops.init(new BcPGPContentVerifierBuilderProvider(), signingPubKey); + + PGPLiteralData lit = (PGPLiteralData) objFac.nextObject(); + ByteArrayOutputStream plainOut = new ByteArrayOutputStream(); + Streams.pipeAll(lit.getDataStream(), plainOut); + + ops.update(plainOut.toByteArray()); + PGPSignatureList sigList = (PGPSignatureList) objFac.nextObject(); + isEquals("There MUST be exactly one signature", 1, sigList.size()); + PGPSignature sig = sigList.get(0); + isTrue("Verifying OPS signature MUST succeed", ops.verify(sig)); + } + + private void verifyV6CleartextSignature() + throws IOException, PGPException + { + String CLEARTEXT_MSG = "-----BEGIN PGP SIGNED MESSAGE-----\n" + + "\n" + + "Hello, World!\n" + + "-----BEGIN PGP SIGNATURE-----\n" + + "\n" + + "wpgGARsKAAAAKSKhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJBYJm\n" + + "gm9ZAAAAAOwrIHtJrY7SIiXXqaBpEbjlJvpviklWkAvMJOLLmVt+hy7wvLNKZEhu\n" + + "ZKiy7zgFRoXTwtVVHyBlTvRoMKN7NhfN5UoDaV3isn0uipMR7YoZTxacQmg3CQlM\n" + + "NOaSt0xdZMqnBw==\n" + + "-----END PGP SIGNATURE-----"; + + ByteArrayInputStream bIn = new ByteArrayInputStream(ARMORED_KEY.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); + PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject(); + PGPPublicKey signingPubKey = secretKeys.getPublicKey(); + + bIn = new ByteArrayInputStream(CLEARTEXT_MSG.getBytes(StandardCharsets.UTF_8)); + aIn = new ArmoredInputStream(bIn); + ByteArrayOutputStream plainOut = new ByteArrayOutputStream(); + while (aIn.isClearText()) + { + int c = aIn.read(); + if (aIn.isClearText()) + { + plainOut.write(c); + } + } + isEncodingEqual("Plaintext MUST match", "Hello, World!\n".getBytes(StandardCharsets.UTF_8), plainOut.toByteArray()); + pIn = new BCPGInputStream(aIn); + objFac = new BcPGPObjectFactory(pIn); + PGPSignatureList sigList = (PGPSignatureList) objFac.nextObject(); + isEquals("There MUST be exactly 1 signature.", 1, sigList.size()); + PGPSignature sig = sigList.get(0); + sig.init(new BcPGPContentVerifierBuilderProvider(), signingPubKey); + sig.update("Hello, World!".getBytes(StandardCharsets.UTF_8)); + isTrue("Signature MUST verify successfully", sig.verify()); + } + + private void verifyingSignatureWithMismatchedSaltSizeFails() + throws IOException + { + // v6 signature made using SHA512 with 16 instead of 32 bytes of salt. + String armoredSig = "-----BEGIN PGP SIGNATURE-----\n" + + "Version: BCPG v@RELEASE_NAME@\n" + + "\n" + + "wogGABsKAAAAKSKhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJBYJm\n" + + "gXv9AAAAAGHvEIB9K2RLSK++vMVKnivhTgBBHon1f/feri7mJOAYfGm8vOzgbc/8\n" + + "/zeeT3ZY+EK3q6RQ6W0nolelQejFuy1w9duC8/1U/oTD6iSi1pRAEm4M\n" + + "=mBNb\n" + + "-----END PGP SIGNATURE-----"; + + ByteArrayInputStream bIn = new ByteArrayInputStream(ARMORED_KEY.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); + PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject(); + PGPPublicKey signingPubKey = secretKeys.getPublicKey(); + + bIn = new ByteArrayInputStream(armoredSig.getBytes(StandardCharsets.UTF_8)); + aIn = new ArmoredInputStream(bIn); + pIn = new BCPGInputStream(aIn); + objFac = new BcPGPObjectFactory(pIn); + PGPSignatureList sigList = (PGPSignatureList) objFac.nextObject(); + PGPSignature binarySig = sigList.get(0); + + try + { + binarySig.init(new BcPGPContentVerifierBuilderProvider(), signingPubKey); + fail("Initiating verification of signature with mismatched salt size MUST fail."); + } + catch (PGPException e) + { + // expected + } + } + + private void verifyingOPSWithMismatchedSaltSizeFails() + throws IOException + { + // v6 signature made using SHA512 with 16 instead of 32 bytes of salt. + String armoredMsg = "-----BEGIN PGP MESSAGE-----\n" + + "\n" + + "xDYGAQobEKM41oT/St9iR6qxoR2RndzLGGxPBgmml+TVLfpscisMHx4nwYpWcI9l\n" + + "JewnutmsyQDLFHUAAAAAAEhlbGxvLCBXb3JsZCEKwogGARsKAAAAKSKhBssYbE8G\n" + + "CaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJBYJmgXv9AAAAAHU6EKM41oT/St9i\n" + + "R6qxoR2RndzKyHgSHsO9QIzLibxeWtny69R0srOsJVFr153JlXSlUojGxv00QvlY\n" + + "z90jECs8awk7vCeJxTHrHFL01Xy5sTsN\n" + + "-----END PGP MESSAGE-----"; + + ByteArrayInputStream bIn = new ByteArrayInputStream(ARMORED_KEY.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); + PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject(); + PGPPublicKey signingPubKey = secretKeys.getPublicKey(); + + bIn = new ByteArrayInputStream(armoredMsg.getBytes(StandardCharsets.UTF_8)); + aIn = new ArmoredInputStream(bIn); + pIn = new BCPGInputStream(aIn); + objFac = new BcPGPObjectFactory(pIn); + + PGPOnePassSignatureList opsList = (PGPOnePassSignatureList) objFac.nextObject(); + isEquals("There MUST be exactly 1 OPS", 1, opsList.size()); + PGPOnePassSignature ops = opsList.get(0); + + try + { + ops.init(new BcPGPContentVerifierBuilderProvider(), signingPubKey); + fail("Initiating verification of OPS with mismatched salt size MUST fail."); + } + catch (PGPException e) + { + // expected. + } + } + + private void verifyingInlineSignatureWithSignatureSaltValueMismatchFails() + throws IOException, PGPException + { + String ARMORED_MSG = "-----BEGIN PGP MESSAGE-----\n" + + "\n" + + "xEYGAQobIMcgFZRFzyKmYrqqNES9B0geVN5TZ6Wct6aUrITCuFyeyxhsTwYJppfk\n" + + "1S36bHIrDB8eJ8GKVnCPZSXsJ7rZrMkAyxR1AAAAAABIZWxsbywgV29ybGQhCsKY\n" + + "BgEbCgAAACkioQbLGGxPBgmml+TVLfpscisMHx4nwYpWcI9lJewnutmsyQWCZoJv\n" + + "WQAAAAAkFSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItltzKi2NN+\n" + + "XNJISXQ0X0f4TppBoHbpmwc5YCTIv2+vDZPI+tjzXL9m2e1jrqqaUMEwQ+Zy8B+K\n" + + "LC4rA6Gh2gY=\n" + + "=KRD3\n" + + "-----END PGP MESSAGE-----"; + + ByteArrayInputStream bIn = new ByteArrayInputStream(ARMORED_KEY.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); + PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject(); + PGPPublicKey signingPubKey = secretKeys.getPublicKey(); + + bIn = new ByteArrayInputStream(ARMORED_MSG.getBytes(StandardCharsets.UTF_8)); + aIn = new ArmoredInputStream(bIn); + pIn = new BCPGInputStream(aIn); + objFac = new BcPGPObjectFactory(pIn); + + PGPOnePassSignatureList opsList = (PGPOnePassSignatureList) objFac.nextObject(); + PGPOnePassSignature ops = opsList.get(0); + isEncodingEqual("OPS salt MUST match our expectations.", + Hex.decode("C720159445CF22A662BAAA3444BD07481E54DE5367A59CB7A694AC84C2B85C9E"), + ops.getSalt()); + + ops.init(new BcPGPContentVerifierBuilderProvider(), signingPubKey); + + PGPLiteralData lit = (PGPLiteralData) objFac.nextObject(); + ByteArrayOutputStream plainOut = new ByteArrayOutputStream(); + Streams.pipeAll(lit.getDataStream(), plainOut); + + ops.update(plainOut.toByteArray()); + PGPSignatureList sigList = (PGPSignatureList) objFac.nextObject(); + PGPSignature sig = sigList.get(0); + + try + { + ops.verify(sig); + fail("Verifying signature with mismatched salt MUST fail."); + } + catch (PGPException e) + { + // expected + } + } + + private void verifySignaturesOnEd448X448Key() + throws PGPException, IOException + { + String KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "Comment: 8cf27d01 f6160563 9e4b8525 353c0cfb f5a23e45 96c47fe6 d90ccacf 3293d5d6\n" + + "Comment: 93c07acb 9eef9fa2 346ac1d5 ff50051c 96124504 e2fb3b5b 564bf969 16d28d42\n" + + "Comment: Ed \n" + + "\n" + + "xX8GZovgyRwAAAA529b1jdB2Cgndd45hbN3qxpTbTM9IpdLJ8ibifS5ranMF8g+w\n" + + "vQfvV2HNwONn1mC+/7yxGLzW9YQAAMM1xRUHrZdL6vcIOugjQ9YDzaoM8nV+6RfN\n" + + "05CJCcJLp2eM0t015rw6UCcGGL7gy5TOFeLhGMU59x2IwsAjBh8cDgAAAEIFgmaL\n" + + "4MkDCwkHBRUKDggMAhYAApsDAh4JIiEGjPJ9AfYWBWOeS4UlNTwM+/WiPkWWxH/m\n" + + "2QzKzzKT1dYFJwkCBwIAAAAA9fcgS0FBeDv6TwF/camy0KEZRHDNIpEI0upB+4vU\n" + + "kyYab1MiKfpfIkZfqCFCikuR8yW6yIFKNXQK/B9nemfwzq6UNrdUZkZL9BpUfXsq\n" + + "xlOJ3ksehQrH8SM9ZgAkk+H0WQyKgakBmw8T74vz44Pej2oAU8w50OtJ81duKIdN\n" + + "bsFF0WiU1PYeLbEPfDjnB2x1lINQCQDNFkVkIDxlZDQ0OEBleGFtcGxlLmNvbT7C\n" + + "wAoGExwKAAAAKQWCZovgySIhBozyfQH2FgVjnkuFJTU8DPv1oj5FlsR/5tkMys8y\n" + + "k9XWAAAAADlTIC14mbBrJQ9/qWzRmS5FHVcJkx87OZ9/573lMDcNM+sMIUQP8b/L\n" + + "c2sLKtzGpQGXG1ETp/MOlGSQaMF6l/3eQpnVZg3jEO0Qd2040Leq4TQqNaFJBMmt\n" + + "wg2ADddE3CkwzMhBG00yhppY2p6xsvGgYVz3vMCQ2MnH/0Hj+9bmzSoJDM/4gXe3\n" + + "HXI1kuEOPFINmi0Ax30GZovgyRoAAAA4SRrAL6zM93X89gPFjMA3D9vjprB0pB7m\n" + + "fVr/c3UPaS/H5ILrcgbvcpwf+D7H1n2DZq2N4MqXvzoANBS7o2zj3FQO80Reagx2\n" + + "ZTav2DzRHNl4M626qkGyUD4u393yIU0u8KMPTZstT43zWqVn3ZzPJJAbdcLADQYY\n" + + "HA4AAAAsIiEGjPJ9AfYWBWOeS4UlNTwM+/WiPkWWxH/m2QzKzzKT1dYFgmaL4MkC\n" + + "mwwAAAAAGPAg10+uyPMPtyB8bomChz/rokK7pTV5AgIjulbOuEVSLkQPXRn06gMn\n" + + "TleudzUKY3mh3Cm01DAVg+5GWQz9F0qWebwzsjUiGqMt7ovySZw4Qkv+lBPkKSxN\n" + + "uwDxqjLecoGbL6nM4mGMU+27dlZRjjpHVWRGur6tup5IBWsX97zKYYrsTE2HCVOC\n" + + "rm3bgQD1eeP0CQA=\n" + + "-----END PGP PRIVATE KEY BLOCK-----"; + verifySignaturesOnKey(KEY); + } + + private void verifySignaturesOnKey(String armoredKey) + throws IOException, PGPException + { + ByteArrayInputStream bIn = new ByteArrayInputStream(armoredKey.getBytes(StandardCharsets.UTF_8)); + ArmoredInputStream aIn = new ArmoredInputStream(bIn); + BCPGInputStream pIn = new BCPGInputStream(aIn); + PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); + PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject(); + + Iterator pubKeys = secretKeys.getPublicKeys(); + PGPPublicKey primaryKey = pubKeys.next(); + + Iterator directKeySigs = primaryKey.getSignaturesOfType(PGPSignature.DIRECT_KEY); + while (directKeySigs.hasNext()) + { + PGPSignature dkSig = directKeySigs.next(); + PGPPublicKey sigKey = getSigningKeyFor(secretKeys, dkSig); + if (sigKey != null) + { + dkSig.init(new BcPGPContentVerifierBuilderProvider(), sigKey); + isTrue("Direct-Key Signature MUST verify", dkSig.verifyCertification(sigKey)); + } + else + { + System.out.println("Did not find signing key for DK sig"); + } + } + + Iterator uids = primaryKey.getUserIDs(); + while (uids.hasNext()) + { + String uid = uids.next(); + Iterator uidSigs = primaryKey.getSignaturesForID(uid); + while (uidSigs.hasNext()) + { + PGPSignature uidSig = uidSigs.next(); + PGPPublicKey sigKey = getSigningKeyFor(secretKeys, uidSig); + if (sigKey != null) + { + uidSig.init(new BcPGPContentVerifierBuilderProvider(), sigKey); + isTrue("UID Signature for " + uid + " MUST verify", + uidSig.verifyCertification(uid, sigKey)); + } + else + { + System.out.println("Did not find signing key for UID sig for " + uid); + } + } + } + + while (pubKeys.hasNext()) + { + PGPPublicKey subkey = pubKeys.next(); + Iterator bindSigs = subkey.getSignaturesOfType(PGPSignature.SUBKEY_BINDING); + while (bindSigs.hasNext()) + { + PGPSignature bindSig = bindSigs.next(); + PGPPublicKey sigKey = getSigningKeyFor(secretKeys, bindSig); + if (sigKey != null) + { + bindSig.init(new BcPGPContentVerifierBuilderProvider(), sigKey); + isTrue("Subkey binding signature MUST verify", + bindSig.verifyCertification(sigKey, subkey)); + } + else + { + System.out.println("Did not find singing key for subkey " + Hex.toHexString(subkey.getFingerprint()) + " binding signature"); + } + } + } + } + + private PGPPublicKey getSigningKeyFor(PGPKeyRing keys, PGPSignature sig) + { + Iterator pubKeys = keys.getPublicKeys(); + while (pubKeys.hasNext()) + { + PGPPublicKey k = pubKeys.next(); + if (k.getKeyID() == sig.getKeyID()) + { + return k; + } + + for (SignatureSubpacket p : sig.getHashedSubPackets().getSubpackets(SignatureSubpacketTags.ISSUER_FINGERPRINT)) + { + IssuerFingerprint fp = (IssuerFingerprint) p; + if (Arrays.areEqual(k.getFingerprint(), fp.getFingerprint())) { + return k; + } + } + + for (SignatureSubpacket p : sig.getUnhashedSubPackets().getSubpackets(SignatureSubpacketTags.ISSUER_FINGERPRINT)) + { + IssuerFingerprint fp = (IssuerFingerprint) p; + if (Arrays.areEqual(k.getFingerprint(), fp.getFingerprint())) { + return k; + } + } + } + return null; + } + + public static void main(String[] args) + { + runTest(new PGPv6SignatureTest()); + } +} \ No newline at end of file diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/RegressionTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/RegressionTest.java index ef0d9f96c0..6c5ea8dd24 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/RegressionTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/RegressionTest.java @@ -33,14 +33,15 @@ public class RegressionTest new PGPEdDSATest(), new PGPPublicKeyMergeTest(), new SExprTest(), - new ArmoredInputStreamTest(), new PGPUtilTest(), new BcPGPEd25519JcaKeyPairConversionTest(), new RewindStreamWhenDecryptingMultiSKESKMessageTest(), new PGPFeaturesTest(), + new ArmoredInputStreamTest(), new ArmoredInputStreamBackslashTRVFTest(), new ArmoredInputStreamCRCErrorGetsThrownTest(), new ArmoredInputStreamIngoreMissingCRCSum(), + new ArmoredOutputStreamTest(), new PGPSessionKeyTest(), new PGPCanonicalizedDataGeneratorTest(), new RegexTest(), @@ -50,7 +51,32 @@ public class RegressionTest new IgnoreUnknownEncryptedSessionKeys(), new PGPEncryptedDataTest(), new PGPAeadTest(), - new CRC24Test() + new CRC24Test(), + new WildcardKeyIDTest(), + new ArmorCRCTest(), + new UnknownPacketTest(), + new ExSExprTest(), + new BcPGPEncryptedDataTest(), + new PGPGeneralTest(), + new BcpgGeneralTest(), + new BcImplProviderTest(), + new OperatorJcajceTest(), + new OpenPGPTest(), + new OperatorBcTest(), + + new DedicatedEd25519KeyPairTest(), + new DedicatedEd448KeyPairTest(), + new DedicatedX25519KeyPairTest(), + new DedicatedX448KeyPairTest(), + + new LegacyEd25519KeyPairTest(), + new LegacyEd448KeyPairTest(), + new LegacyX25519KeyPairTest(), + new LegacyX448KeyPairTest(), + + new Curve25519PrivateKeyEncodingTest(), + new EdDSAKeyConversionWithLeadingZeroTest(), + new ECDSAKeyPairTest() }; public static void main(String[] args) diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/SHA1.java b/pg/src/test/java/org/bouncycastle/openpgp/test/SHA1.java new file mode 100644 index 0000000000..0dea62037f --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/SHA1.java @@ -0,0 +1,23 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.crypto.digests.SHA1Digest; +import org.bouncycastle.jcajce.provider.digest.BCMessageDigest; + +public class SHA1 + extends BCMessageDigest + implements Cloneable +{ + public SHA1() + { + super(new SHA1Digest()); + } + + public Object clone() + throws CloneNotSupportedException + { + SHA1 d = (SHA1)super.clone(); + d.digest = new SHA1Digest((SHA1Digest)digest); + + return d; + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/SHA256.java b/pg/src/test/java/org/bouncycastle/openpgp/test/SHA256.java new file mode 100644 index 0000000000..48fa9d8ad4 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/SHA256.java @@ -0,0 +1,23 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.jcajce.provider.digest.BCMessageDigest; + +public class SHA256 + extends BCMessageDigest + implements Cloneable +{ + public SHA256() + { + super(SHA256Digest.newInstance()); + } + + public Object clone() + throws CloneNotSupportedException + { + SHA256 d = (SHA256)super.clone(); + d.digest = SHA256Digest.newInstance(digest); + + return d; + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/UnknownPacketTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/UnknownPacketTest.java new file mode 100644 index 0000000000..530203802b --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/UnknownPacketTest.java @@ -0,0 +1,133 @@ +package org.bouncycastle.openpgp.test; + +import org.bouncycastle.bcpg.BCPGInputStream; +import org.bouncycastle.bcpg.UnknownPacket; +import org.bouncycastle.openpgp.PGPObjectFactory; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +public class UnknownPacketTest + extends SimpleTest +{ + + + @Override + public String getName() + { + return "UnknownPacketTest"; + } + + @Override + public void performTest() + throws Exception + { + // Test encoding + testUnknownCriticalPacket(); + testUnknownNonCriticalPacket(); + + // Test parsing with PGPObjectFactory + testParseNonCriticalPacket(); + testParseCriticalPacketWithThrowing(); + testParseCriticalPacketWithoutThrowing(); + } + + private void testUnknownCriticalPacket() + throws IOException + { + int tag = 39; // within critical range + byte[] contents = new byte[] {0x50, 0x47, 0x50, 0x61, 0x69, 0x6e, 0x6c, 0x65, 0x73, 0x73}; + ByteArrayInputStream bIn = new ByteArrayInputStream(contents); + BCPGInputStream bcIn = new BCPGInputStream(bIn); + UnknownPacket packet = new UnknownPacket(tag, bcIn); + + isTrue(packet.isCritical()); + testPacketEncoding(tag, contents, packet); + } + + private void testUnknownNonCriticalPacket() + throws IOException + { + int tag = 44; // within non-critical range + byte[] contents = new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; + ByteArrayInputStream bIn = new ByteArrayInputStream(contents); + BCPGInputStream bcIn = new BCPGInputStream(bIn); + UnknownPacket packet = new UnknownPacket(tag, bcIn); + + isTrue(!packet.isCritical()); + testPacketEncoding(tag, contents, packet); + } + + private void testPacketEncoding(int tag, byte[] contents, UnknownPacket packet) + throws IOException + { + byte[] encoded = packet.getEncoded(); + + int hdr = encodeTag(tag); + isEquals(hdr, encoded[0] & 0xff); + isEquals(contents.length, encoded[1]); + for (int i = 0; i < contents.length; i++) + { + isEquals(encoded[i + 2], contents[i]); + } + } + + private int encodeTag(int tag) + { + int hdr = 0x80; + hdr |= 0x40 | tag; + return hdr & 0xff; + } + + private void testParseNonCriticalPacket() + throws IOException + { + int tag = 44; + String encodedCriticalPacket = "ec0e4f70656e50475020726f636b7321"; // Tag 36 + ByteArrayInputStream in = new ByteArrayInputStream(Hex.decode(encodedCriticalPacket)); + + PGPObjectFactory objectFactory = new BcPGPObjectFactory(in); + UnknownPacket packet = (UnknownPacket) objectFactory.nextObject(); + isEquals(tag, packet.getPacketTag()); + isTrue(!packet.isCritical()); + } + + private void testParseCriticalPacketWithoutThrowing() + throws IOException + { + int tag = 36; + String encodedCriticalPacket = "e40e4f70656e50475020726f636b7321"; // Tag 36 + ByteArrayInputStream in = new ByteArrayInputStream(Hex.decode(encodedCriticalPacket)); + + PGPObjectFactory objectFactory = new BcPGPObjectFactory(in); + UnknownPacket packet = (UnknownPacket) objectFactory.nextObject(); + isEquals(tag, packet.getPacketTag()); + isTrue(packet.isCritical()); + } + + private void testParseCriticalPacketWithThrowing() + { + String encodedCriticalPacket = "e40e4f70656e50475020726f636b7321"; // Tag 36 + ByteArrayInputStream in = new ByteArrayInputStream(Hex.decode(encodedCriticalPacket)); + + PGPObjectFactory objectFactory = new BcPGPObjectFactory(in) + .setThrowForUnknownCriticalPackets(true); // Enable exception throwing for unknown critical packets + try + { + objectFactory.nextObject(); + fail("Expected IOException, but nothing was thrown"); + } + catch (IOException e) + { + // expected + } + } + + public static void main(String[] args) + { + runTest(new UnknownPacketTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/WildcardKeyIDTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/WildcardKeyIDTest.java new file mode 100644 index 0000000000..43a4a6de51 --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/WildcardKeyIDTest.java @@ -0,0 +1,130 @@ +package org.bouncycastle.openpgp.test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Date; + +import org.bouncycastle.bcpg.ArmoredInputStream; +import org.bouncycastle.bcpg.ArmoredOutputStream; +import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; +import org.bouncycastle.openpgp.PGPEncryptedDataList; +import org.bouncycastle.openpgp.PGPLiteralData; +import org.bouncycastle.openpgp.PGPLiteralDataGenerator; +import org.bouncycastle.openpgp.PGPObjectFactory; +import org.bouncycastle.openpgp.PGPPrivateKey; +import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; +import org.bouncycastle.openpgp.PGPSecretKey; +import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; +import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; +import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.io.Streams; +import org.bouncycastle.util.test.SimpleTest; + +public class WildcardKeyIDTest + extends SimpleTest +{ + private static final String KEY = "" + + "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "Comment: AD4E FA47 5E86 2A89 8C5E BC56 5D44 DBEB F4E4 117B\n" + + "\n" + + "lFgEZEkKfxYJKwYBBAHaRw8BAQdAB0cQLQkEcOU6jo3x6mND+McUV77OPUA2xqKA\n" + + "puAmuRYAAPwOLG5loKswF8IEBUm4OwITBEUMuhmhvGQaGu97JZufbQwKiIwEHxYK\n" + + "AD4FAmRJCn8JEF1E2+v05BF7FiEErU76R16GKomMXrxWXUTb6/TkEXsCngECmwEF\n" + + "FgIDAQAECwkIBwUVCgkICwAAPHQBAJfSmZKxlHDS1Y33umS8HpYjW/B9esRTf3bc\n" + + "Ub7/PtM3AP0SjA4rpQ0wNFbDpGfRXC6aBeVpZNzeoBmWBksWT0JSBpxdBGRJCn8S\n" + + "CisGAQQBl1UBBQEBB0BbkXZSB5nhn2eJZgej6UcfIcaVPd45upEGqd62QvQaIwMB\n" + + "CAcAAP9iwfvRk4aAsOYs5GFBXqslCJssU8W88oiHZivsZgiHCBEbiHUEGBYKAB0F\n" + + "AmRJCn8CngECmwwFFgIDAQAECwkIBwUVCgkICwAKCRBdRNvr9OQRe81TAQDcvtfw\n" + + "vR5Ki/PTVDRcYrhc4cDw7MI0POfOY2JO25QcTwEAyFCmw5kg95P2XwXVaAraYuR8\n" + + "Z7Okda+X8ZczE4Fb8g+cWARkSQp/FgkrBgEEAdpHDwEBB0AOfElGRkuSVLs0yQiv\n" + + "pxxg92lBZ46d1tpjfPEQKVOdJgABALGt/JUY7QhnMap4cHLj/jGL4vcqIkfQyBUV\n" + + "mYKVhTwhD/aI1QQYFgoAfQUCZEkKfwKeAQKbAgUWAgMBAAQLCQgHBRUKCQgLXyAE\n" + + "GRYKAAYFAmRJCn8ACgkQARi+8u3za5yGwAEAkpAi4bXucKmr4jfE6oQMUhGJBkqt\n" + + "gp8LEqeFFkKYbhIA/iDA1yKlotXC4ifQ9JheoUcvu0nmwZ6AV1JgLNhL0eILAAoJ\n" + + "EF1E2+v05BF79x4BANMB7+I9vZTSQgbUVw/NebThGKHuvJ0tUayWkIM1j0hsAQD6\n" + + "yfialgAOd9q4TWt53oD3Z2aDo2dTnjP9GaABP+vJAw==\n" + + "=u/tO\n" + + "-----END PGP PRIVATE KEY BLOCK-----"; + + private static final String PLAINTEXT = "Hello, World!\n"; + + @Override + public String getName() + { + return "WildcardKeyIDTest"; + } + + @Override + public void performTest() + throws Exception + { + ByteArrayInputStream keyBytesIn = new ByteArrayInputStream(Strings.toByteArray(KEY)); + ArmoredInputStream keyArmorIn = new ArmoredInputStream(keyBytesIn); + PGPSecretKeyRing secretKeys = new PGPSecretKeyRing(keyArmorIn, new BcKeyFingerprintCalculator()); + long encryptionKeyId = 7405306990825650521L; + + // Encrypt message + PGPDataEncryptorBuilder dataEncBuilder = new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256); + PGPEncryptedDataGenerator encDataGen = new PGPEncryptedDataGenerator(dataEncBuilder); + PublicKeyKeyEncryptionMethodGenerator pkeMethodGen = new BcPublicKeyKeyEncryptionMethodGenerator( + secretKeys.getPublicKey(encryptionKeyId)); + pkeMethodGen.setUseWildcardKeyID(true); + encDataGen.addMethod(pkeMethodGen); + ByteArrayOutputStream cipherTextOut = new ByteArrayOutputStream(); + ArmoredOutputStream armorOut = new ArmoredOutputStream(cipherTextOut); + OutputStream encOut = encDataGen.open(armorOut, new byte[512]); + PGPLiteralDataGenerator litDataGen = new PGPLiteralDataGenerator(); + OutputStream litOut = litDataGen.open(encOut, PGPLiteralDataGenerator.TEXT, "", new Date(0L), new byte[512]); + + litOut.write(Strings.toByteArray(PLAINTEXT)); + litOut.flush(); + litOut.close(); + + encOut.flush(); + encOut.close(); + + armorOut.flush(); + armorOut.close(); + + // Decrpyt + PGPSecretKey secretKey = secretKeys.getSecretKey(encryptionKeyId); + PGPDigestCalculatorProvider digestCalcProv = new BcPGPDigestCalculatorProvider(); + PBESecretKeyDecryptor keyDecryptor = new BcPBESecretKeyDecryptorBuilder(digestCalcProv) + .build(null); + PGPPrivateKey privateKey = secretKey.extractPrivateKey(keyDecryptor); + + ByteArrayInputStream cipherTextIn = new ByteArrayInputStream(cipherTextOut.toByteArray()); + ArmoredInputStream armorIn = new ArmoredInputStream(cipherTextIn); + PGPObjectFactory objectFactory = new BcPGPObjectFactory(armorIn); + PGPEncryptedDataList encDataList = (PGPEncryptedDataList) objectFactory.nextObject(); + PGPPublicKeyEncryptedData pkeData = (PGPPublicKeyEncryptedData) encDataList.get(0); + + isEquals(PublicKeyKeyEncryptionMethodGenerator.WILDCARD, pkeData.getKeyID()); + + InputStream decryptedIn = pkeData.getDataStream(new BcPublicKeyDataDecryptorFactory(privateKey)); + objectFactory = new BcPGPObjectFactory(decryptedIn); + PGPLiteralData literalData = (PGPLiteralData) objectFactory.nextObject(); + ByteArrayOutputStream plainTextOut = new ByteArrayOutputStream(); + Streams.pipeAll(literalData.getDataStream(), plainTextOut); + + isEquals(PLAINTEXT, plainTextOut.toString()); + } + + public static void main(String[] args) + { + runTest(new WildcardKeyIDTest()); + } +} diff --git a/pg/src/test/java/org/bouncycastle/test/DumpUtil.java b/pg/src/test/java/org/bouncycastle/test/DumpUtil.java new file mode 100644 index 0000000000..88f7138dfc --- /dev/null +++ b/pg/src/test/java/org/bouncycastle/test/DumpUtil.java @@ -0,0 +1,65 @@ +package org.bouncycastle.test; + +import org.bouncycastle.util.encoders.Hex; + +public class DumpUtil +{ + /** + * Return a formatted hex dump of the given byte array. + * @param array byte array + */ + public static String hexdump(byte[] array) + { + return hexdump(0, array); + } + + /** + * Return a formatted hex dump of the given byte array. + * If startIndent is non-zero, the dump is shifted right by startIndent octets. + * @param startIndent shift the octet stream between by a number of bytes + * @param array byte array + */ + public static String hexdump(int startIndent, byte[] array) + { + if (startIndent < 0) + { + throw new IllegalArgumentException("Start-Indent must be a positive number"); + } + if (array == null) + { + return ""; + } + String hex = Hex.toHexString(array); + StringBuilder withWhiteSpace = new StringBuilder(); + // shift the dump a number of octets to the right + for (int i = 0; i < startIndent; i++) + { + withWhiteSpace.append(" "); + } + // Split into hex octets (pairs of two chars) + String[] octets = withWhiteSpace.append(hex).toString().split("(?<=\\G.{2})"); + + StringBuilder out = new StringBuilder(); + int l = 0; + while (l < octets.length) + { + // index row + out.append(String.format("%08X", l)).append(" "); + // first 8 octets of a line + for (int i = l ; i < l + 8 && i < octets.length; i++) + { + out.append(octets[i]).append(" "); + } + out.append(" "); + // second 8 octets of a line + for (int i = l+8; i < l + 16 && i < octets.length; i++) + { + out.append(octets[i]).append(" "); + } + out.append("\n"); + + l += 16; + } + return out.toString(); + } +} diff --git a/pg/src/test/jdk1.1/org/bouncycastle/openpgp/test/PGPEdDSATest.java b/pg/src/test/jdk1.1/org/bouncycastle/openpgp/test/PGPEdDSATest.java index 1eac1d993f..0cd9545196 100644 --- a/pg/src/test/jdk1.1/org/bouncycastle/openpgp/test/PGPEdDSATest.java +++ b/pg/src/test/jdk1.1/org/bouncycastle/openpgp/test/PGPEdDSATest.java @@ -414,7 +414,8 @@ public void performTest() PGPPublicKeyRing pubKeyRing = new PGPPublicKeyRing(aIn, new JcaKeyFingerprintCalculator()); - isTrue(areEqual(Hex.decode("EB85 BB5F A33A 75E1 5E94 4E63 F231 550C 4F47 E38E"), pubKeyRing.getPublicKey().getFingerprint())); + isTrue(areEqual(pubKeyRing.getPublicKey().getFingerprint(), Hex.decode("EB85 BB5F A33A 75E1 5E94 4E63 F231 550C 4F47 E38E"))); + isTrue(pubKeyRing.getPublicKey().hasFingerprint(Hex.decode("EB85 BB5F A33A 75E1 5E94 4E63 F231 550C 4F47 E38E"))); aIn = new ArmoredInputStream(new ByteArrayInputStream(Strings.toByteArray(edDSASecretKey))); diff --git a/pg/src/test/jdk1.4/org/bouncycastle/openpgp/test/RegressionTest.java b/pg/src/test/jdk1.4/org/bouncycastle/openpgp/test/RegressionTest.java new file mode 100644 index 0000000000..4a7754b3c7 --- /dev/null +++ b/pg/src/test/jdk1.4/org/bouncycastle/openpgp/test/RegressionTest.java @@ -0,0 +1,74 @@ +package org.bouncycastle.openpgp.test; + +import java.security.Security; + +import org.bouncycastle.util.test.SimpleTest; +import org.bouncycastle.util.test.Test; + +public class RegressionTest +{ + public static Test[] tests = { + new BcPGPKeyRingTest(), + new PGPKeyRingTest(), + new BcPGPRSATest(), + new PGPRSATest(), + new BcPGPDSATest(), + new PGPDSATest(), + new BcPGPDSAElGamalTest(), + new PGPDSAElGamalTest(), + new BcPGPPBETest(), + new PGPPBETest(), + new PGPMarkerTest(), + new PGPPacketTest(), + new PGPArmoredTest(), + new PGPSignatureInvalidVersionIgnoredTest(), + new PGPSignatureTest(), + new PGPClearSignedSignatureTest(), + new PGPCompressionTest(), + new PGPNoPrivateKeyTest(), + new PGPECDSATest(), + new PGPECDHTest(), + new PGPECMessageTest(), + new PGPParsingTest(), + new PGPEdDSATest(), + new PGPPublicKeyMergeTest(), + new SExprTest(), + new PGPUtilTest(), + new BcPGPEd25519JcaKeyPairConversionTest(), + new RewindStreamWhenDecryptingMultiSKESKMessageTest(), + new PGPFeaturesTest(), + new ArmoredInputStreamTest(), + new ArmoredInputStreamBackslashTRVFTest(), + new ArmoredInputStreamCRCErrorGetsThrownTest(), + new ArmoredInputStreamIngoreMissingCRCSum(), + new ArmoredOutputStreamTest(), + new PGPSessionKeyTest(), + new PGPCanonicalizedDataGeneratorTest(), + new RegexTest(), + new PolicyURITest(), + new ArmoredOutputStreamUTF8Test(), + new UnrecognizableSubkeyParserTest(), + new IgnoreUnknownEncryptedSessionKeys(), + new PGPEncryptedDataTest(), + new PGPAeadTest(), + new CRC24Test(), + new WildcardKeyIDTest(), + new ArmorCRCTest(), + new UnknownPacketTest(), + new ExSExprTest(), + new BcPGPEncryptedDataTest(), + new PGPGeneralTest(), + new BcpgGeneralTest(), + //new BcImplProviderTest(), + new OperatorJcajceTest(), + new OpenPGPTest(), + new OperatorBcTest() + }; + + public static void main(String[] args) + { + Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); + + SimpleTest.runTests(tests); + } +} diff --git a/pkix/build.gradle b/pkix/build.gradle index 477b3315f1..47545249ae 100644 --- a/pkix/build.gradle +++ b/pkix/build.gradle @@ -1,20 +1,89 @@ + +plugins { + id "biz.aQute.bnd.builder" version "7.0.0" +} + +sourceSets { + java9 { + java { + srcDirs = ['src/main/jdk1.9'] + } + } +} + dependencies { - implementation project(':core') - implementation project(':util') - implementation project(':prov') + implementation project(':core') + implementation project(':prov') + implementation project(':util') + + java9Implementation project(':prov') + java9Implementation project(':util') + java9Implementation files(sourceSets.main.output.classesDirs) { + builtBy compileJava + } + + testImplementation group: 'junit', name: 'junit', version: '4.13.2' +} + +compileJava { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + targetCompatibility = 1.8; + sourceCompatibility = 1.8; } + +compileJava9Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + sourceCompatibility = 9 + targetCompatibility = 9 + options.compilerArgs += [ + '--module-path', "${bc_prov}${File.pathSeparator}${bc_util}" + ] + + options.sourcepath = files(['src/main/java', 'src/main/jdk1.9']) +} + + jar.archiveBaseName = "bcpkix-$vmrange" + task sourcesJar(type: Jar) { - archiveBaseName = jar.archiveBaseName - classifier = 'sources' - from sourceSets.main.allSource + archiveBaseName = jar.archiveBaseName + archiveClassifier = 'sources' + from sourceSets.main.allSource + exclude("**/*.so") + into('META-INF/versions/9') { + from sourceSets.java9.allSource + } } +jar { + from sourceSets.main.output + into('META-INF/versions/9') { + from sourceSets.java9.output + } + + String packages = 'org.bouncycastle.{cert|cmc|cms|dvcs|eac|est|its|mime|mozilla|voms|operator|pkix|openssl|pkcs|tsp}.*' + + String v = "${rootProject.extensions.ext.bundle_version}" + + manifest.attributes('Multi-Release': 'true') + manifest.attributes('Bundle-Name': 'bcpkix') + manifest.attributes('Bundle-SymbolicName': 'bcpkix') + manifest.attributes('Bundle-RequiredExecutionEnvironment': 'JavaSE-1.8') + manifest.attributes('Export-Package': "${packages};version=${v}") + manifest.attributes('Import-Package': "java.*;resolution:=optional,javax.*;resolution:=optional,!${packages},org.bouncycastle.*;version=\"[${v},${maxVersion})\"") + manifest.attributes('Bundle-Version': "${v}") +} + + task javadocJar(type: Jar, dependsOn: javadoc) { archiveBaseName = jar.archiveBaseName - classifier = 'javadoc' + archiveClassifier = 'javadoc' from javadoc.destinationDir } @@ -24,3 +93,7 @@ artifacts { archives sourcesJar } +test { + forkEvery = 1; + maxParallelForks = 8; +} diff --git a/pkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java b/pkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java index d0b1259d09..df8b1d68cc 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java @@ -323,9 +323,9 @@ public boolean match(Object obj) digOut.close(); - if (!Arrays.areEqual(digCalc.getDigest(), getObjectDigest())) + if (Arrays.areEqual(digCalc.getDigest(), getObjectDigest())) { - return false; + return true; } } catch (Exception e) diff --git a/pkix/src/main/java/org/bouncycastle/cert/DeltaCertificateTool.java b/pkix/src/main/java/org/bouncycastle/cert/DeltaCertificateTool.java new file mode 100644 index 0000000000..f599a525f4 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/cert/DeltaCertificateTool.java @@ -0,0 +1,185 @@ +package org.bouncycastle.cert; + +import java.io.IOException; + +import org.bouncycastle.asn1.ASN1BitString; +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DERBitString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.ExtensionsGenerator; + +/** + * General tool for handling the extension described in: https://datatracker.ietf.org/doc/draft-bonnell-lamps-chameleon-certs/ + */ +public class DeltaCertificateTool +{ + public static Extension makeDeltaCertificateExtension(boolean isCritical, X509CertificateHolder deltaCert) + throws IOException + { + ASN1EncodableVector deltaV = new ASN1EncodableVector(); + + deltaV.add(new ASN1Integer(deltaCert.getSerialNumber())); + deltaV.add(new DERTaggedObject(false, 0, deltaCert.getSignatureAlgorithm())); + deltaV.add(new DERTaggedObject(false, 1, deltaCert.getIssuer())); + + ASN1EncodableVector validity = new ASN1EncodableVector(2); + validity.add(deltaCert.toASN1Structure().getStartDate()); + validity.add(deltaCert.toASN1Structure().getEndDate()); + + deltaV.add(new DERTaggedObject(false, 2, new DERSequence(validity))); + deltaV.add(new DERTaggedObject(false, 3, deltaCert.getSubject())); + deltaV.add(deltaCert.getSubjectPublicKeyInfo()); + if (deltaCert.getExtensions() != null) + { + deltaV.add(new DERTaggedObject(false, 4, deltaCert.getExtensions())); + } + deltaV.add(new DERBitString(deltaCert.getSignature())); + + return new Extension(Extension.deltaCertificateDescriptor, isCritical, new DERSequence(deltaV).getEncoded(ASN1Encoding.DER)); + } + + public static X509CertificateHolder extractDeltaCertificate(X509CertificateHolder originCert) + { + ASN1ObjectIdentifier deltaExtOid = Extension.deltaCertificateDescriptor; + Extension deltaExt = originCert.getExtension(deltaExtOid); + + ASN1Sequence seq = ASN1Sequence.getInstance(deltaExt.getParsedValue()); +// * version [ 0 ] Version DEFAULT v1(0), +// * serialNumber CertificateSerialNumber, +// * signature AlgorithmIdentifier, +// * issuer Name, +// * validity Validity, +// * subject Name, +// * subjectPublicKeyInfo SubjectPublicKeyInfo, +// * issuerUniqueID [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL, +// * subjectUniqueID [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL, +// * extensions [ 3 ] Extensions OPTIONAL + ASN1Sequence originTbs = ASN1Sequence.getInstance(originCert.toASN1Structure().getTBSCertificate().toASN1Primitive()); + int idx = 0; + ASN1Encodable[] extracted = originTbs.toArray(); + + extracted[0] = originTbs.getObjectAt(0); + extracted[1] = ASN1Integer.getInstance(seq.getObjectAt(idx++)); + + ASN1Encodable next = seq.getObjectAt(idx++); + while (next instanceof ASN1TaggedObject) + { + ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next); + switch (tagged.getTagNo()) + { + case 0: + extracted[2] = ASN1Sequence.getInstance(tagged, false); + break; + case 1: + extracted[3] = ASN1Sequence.getInstance(tagged, true); // issuer + break; + case 2: + extracted[4] = ASN1Sequence.getInstance(tagged, false); + break; + case 3: + extracted[5] = ASN1Sequence.getInstance((ASN1TaggedObject)next, true); // subject + break; + } + next = seq.getObjectAt(idx++); + } + + extracted[6] = next; // subjectPublicKey + + if (extracted[2] == null) + { + extracted[2] = originTbs.getObjectAt(2); + } + + if (extracted[3] == null) + { + extracted[3] = originTbs.getObjectAt(3); + } + + if (extracted[4] == null) + { + extracted[4] = originTbs.getObjectAt(4); + } + + if (extracted[5] == null) + { + extracted[5] = originTbs.getObjectAt(5); + } + + ExtensionsGenerator extGen = extractExtensions(originTbs); + + if (idx < (seq.size() - 1)) // last element is the signature + { + next = seq.getObjectAt(idx++); + ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next); + if (tagged.getTagNo() != 4) + { + throw new IllegalArgumentException("malformed delta extension"); + } + + ASN1Sequence deltaExts = ASN1Sequence.getInstance(tagged, false); + + for (int i = 0; i != deltaExts.size(); i++) + { + Extension ext = Extension.getInstance(deltaExts.getObjectAt(i)); + + extGen.replaceExtension(ext); + } + + extracted[7] = new DERTaggedObject(3, extGen.generate()); + } + else + { + if (!extGen.isEmpty()) + { + extracted[7] = new DERTaggedObject(3, extGen.generate()); + } + else + { + extracted[7] = null; + } + } + + ASN1EncodableVector tbsDeltaCertV = new ASN1EncodableVector(7); + for (int i = 0; i != extracted.length; i++) + { + if (extracted[i] != null) + { + tbsDeltaCertV.add(extracted[i]); + } + } + + ASN1EncodableVector certV = new ASN1EncodableVector(); + certV.add(new DERSequence(tbsDeltaCertV)); + certV.add(ASN1Sequence.getInstance(extracted[2])); + certV.add(ASN1BitString.getInstance(seq.getObjectAt(seq.size() - 1))); + + return new X509CertificateHolder(Certificate.getInstance(new DERSequence(certV))); + } + + private static ExtensionsGenerator extractExtensions(ASN1Sequence originTbs) + { + ASN1ObjectIdentifier deltaExtOid = Extension.deltaCertificateDescriptor; + ASN1Sequence originExt = ASN1Sequence.getInstance(ASN1TaggedObject.getInstance(originTbs.getObjectAt(originTbs.size() - 1)), true); + ExtensionsGenerator extGen = new ExtensionsGenerator(); + + for (int i = 0; i != originExt.size(); i++) + { + Extension ext = Extension.getInstance(originExt.getObjectAt(i)); + if (!deltaExtOid.equals(ext.getExtnId())) + { + extGen.addExtension(ext); + } + } + + return extGen; + } +} diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java b/pkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java index 6a3739cd88..eb5c9ccff1 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java @@ -23,7 +23,6 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AltSignatureAlgorithm; diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java b/pkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java index b7b631dba0..bc328fd6b9 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java @@ -248,9 +248,9 @@ public AlgorithmIdentifier getSignatureAlgorithm() } /** - * Return the bytes making up the signature associated with this attribute certificate. + * Return the bytes making up the signature associated with this certificate. * - * @return the attribute certificate signature bytes. + * @return the certificate signature bytes. */ public byte[] getSignature() { diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java index 4cd231c44f..6753d049e7 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java @@ -132,6 +132,11 @@ public Extension getExtension(ASN1ObjectIdentifier oid) private Extension doGetExtension(ASN1ObjectIdentifier oid) { + if (extGenerator.isEmpty()) + { + return null; + } + Extensions exts = extGenerator.generate(); return exts.getExtension(oid); diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509v2CRLBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/X509v2CRLBuilder.java index e1744c6682..f9b5d72f3c 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/X509v2CRLBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/X509v2CRLBuilder.java @@ -153,11 +153,56 @@ public Extension getExtension(ASN1ObjectIdentifier oid) private Extension doGetExtension(ASN1ObjectIdentifier oid) { + if (extGenerator.isEmpty()) + { + return null; + } + Extensions exts = extGenerator.generate(); return exts.getExtension(oid); } + /** + * Set the date by which the next CRL will become available. + * + * @param date date of next CRL update. + * @return the current builder. + */ + public X509v2CRLBuilder setThisUpdate( + Date date) + { + return this.setThisUpdate(new Time(date)); + } + + /** + * Set the date by which the next CRL will become available. + * + * @param date date of next CRL update. + * @param dateLocale locale to be used for date interpretation. + * @return the current builder. + */ + public X509v2CRLBuilder setThisUpdate( + Date date, + Locale dateLocale) + { + return this.setThisUpdate(new Time(date, dateLocale)); + } + + /** + * Set the date by which the next CRL will become available. + * + * @param date date of next CRL update. + * @return the current builder. + */ + public X509v2CRLBuilder setThisUpdate( + Time date) + { + tbsGen.setThisUpdate(date); + + return this; + } + /** * Set the date by which the next CRL will become available. * diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java index 89241ef6c0..403f56105d 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java @@ -14,10 +14,12 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; +import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.asn1.x509.DeltaCertificateDescriptor; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.ExtensionsGenerator; @@ -150,6 +152,11 @@ public Extension getExtension(ASN1ObjectIdentifier oid) private Extension doGetExtension(ASN1ObjectIdentifier oid) { + if (extGenerator.isEmpty()) + { + return null; + } + Extensions exts = extGenerator.generate(); return exts.getExtension(oid); @@ -373,6 +380,21 @@ public X509CertificateHolder build( if (!extGenerator.isEmpty()) { + if (extGenerator.hasExtension(Extension.deltaCertificateDescriptor)) + { + Extension deltaExt = extGenerator.getExtension(Extension.deltaCertificateDescriptor); + DeltaCertificateDescriptor deltaDesc = DeltaCertificateDescriptor.getInstance(deltaExt.getParsedValue()); + + try + { + extGenerator.replaceExtension(Extension.deltaCertificateDescriptor, deltaExt.isCritical(), + deltaDesc.trimTo(tbsGen.generateTBSCertificate(), extGenerator.generate())); + } + catch (IOException e) + { + throw new IllegalStateException("unable to replace deltaCertificateDescriptor: " + e.getMessage()) ; + } + } tbsGen.setExtensions(extGenerator.generate()); } @@ -401,8 +423,6 @@ public X509CertificateHolder build( boolean isCritical, ContentSigner altSigner) { - tbsGen.setSignature(null); - try { extGenerator.addExtension(Extension.altSignatureAlgorithm, isCritical, altSigner.getAlgorithmIdentifier()); @@ -412,6 +432,32 @@ public X509CertificateHolder build( throw Exceptions.illegalStateException("cannot add altSignatureAlgorithm extension", e); } + if (extGenerator.hasExtension(Extension.deltaCertificateDescriptor)) + { + tbsGen.setSignature(signer.getAlgorithmIdentifier()); + + Extension deltaExt = extGenerator.getExtension(Extension.deltaCertificateDescriptor); + DeltaCertificateDescriptor deltaDesc = DeltaCertificateDescriptor.getInstance(deltaExt.getParsedValue()); + + try + { + // the altSignatureValue is not present yet, but it must be in the deltaCertificate and + // it must be different (by definition!). We add a dummy one to trigger inclusion. + ExtensionsGenerator tmpExtGen = new ExtensionsGenerator(); + tmpExtGen.addExtension(extGenerator.generate()); + tmpExtGen.addExtension(Extension.altSignatureValue, false, DERNull.INSTANCE); + + extGenerator.replaceExtension(Extension.deltaCertificateDescriptor, deltaExt.isCritical(), + deltaDesc.trimTo(tbsGen.generateTBSCertificate(), tmpExtGen.generate())); + } + catch (IOException e) + { + throw new IllegalStateException("unable to replace deltaCertificateDescriptor: " + e.getMessage()); + } + } + + tbsGen.setSignature(null); + tbsGen.setExtensions(extGenerator.generate()); try diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/CMPUtil.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/CMPUtil.java index 33a8f070e7..be6755c78f 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/cmp/CMPUtil.java +++ b/pkix/src/main/java/org/bouncycastle/cert/cmp/CMPUtil.java @@ -5,9 +5,38 @@ import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; +import org.bouncycastle.operator.DigestCalculator; +import org.bouncycastle.operator.DigestCalculatorProvider; +import org.bouncycastle.operator.OperatorCreationException; class CMPUtil { + static byte[] calculateCertHash(ASN1Object obj, AlgorithmIdentifier signatureAlgorithm, + DigestCalculatorProvider digesterProvider, DigestAlgorithmIdentifierFinder digestAlgFinder) + throws CMPException + { + AlgorithmIdentifier digestAlgorithm = digestAlgFinder.find(signatureAlgorithm); + if (digestAlgorithm == null) + { + throw new CMPException("cannot find digest algorithm from signature algorithm"); + } + + return calculateDigest(obj, digestAlgorithm, digesterProvider); + } + + static byte[] calculateDigest(ASN1Object obj, AlgorithmIdentifier digestAlgorithm, + DigestCalculatorProvider digesterProvider) + throws CMPException + { + DigestCalculator digestCalculator = getDigestCalculator(digestAlgorithm, digesterProvider); + + derEncodeToStream(obj, digestCalculator.getOutputStream()); + + return digestCalculator.getDigest(); + } + static void derEncodeToStream(ASN1Object obj, OutputStream stream) { try @@ -20,4 +49,18 @@ static void derEncodeToStream(ASN1Object obj, OutputStream stream) throw new CMPRuntimeException("unable to DER encode object: " + e.getMessage(), e); } } + + static DigestCalculator getDigestCalculator(AlgorithmIdentifier digestAlgorithm, + DigestCalculatorProvider digesterProvider) + throws CMPException + { + try + { + return digesterProvider.get(digestAlgorithm); + } + catch (OperatorCreationException e) + { + throw new CMPException("unable to create digester: " + e.getMessage(), e); + } + } } diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateConfirmationContentBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateConfirmationContentBuilder.java index b89fe748db..3567b759c7 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateConfirmationContentBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateConfirmationContentBuilder.java @@ -60,36 +60,19 @@ public CertificateConfirmationContentBuilder addAcceptedCertificate(CMPCertifica public CertificateConfirmationContent build(DigestCalculatorProvider digesterProvider) throws CMPException { - ASN1EncodableVector v = new ASN1EncodableVector(); + ASN1EncodableVector v = new ASN1EncodableVector(acceptedCerts.size()); for (int i = 0; i != acceptedCerts.size(); i++) { - CMPCertificate certHolder = (CMPCertificate)acceptedCerts.get(i); + byte[] certHash = CMPUtil.calculateCertHash((CMPCertificate)acceptedCerts.get(i), + (AlgorithmIdentifier)acceptedSignatureAlgorithms.get(i), digesterProvider, digestAlgFinder); ASN1Integer reqID = (ASN1Integer)acceptedReqIds.get(i); - AlgorithmIdentifier digAlg = digestAlgFinder.find((AlgorithmIdentifier)acceptedSignatureAlgorithms.get(i)); - if (digAlg == null) - { - throw new CMPException("cannot find algorithm for digest from signature"); - } - - DigestCalculator digester; - - try - { - digester = digesterProvider.get(digAlg); - } - catch (OperatorCreationException e) - { - throw new CMPException("unable to create digest: " + e.getMessage(), e); - } - - CMPUtil.derEncodeToStream(certHolder, digester.getOutputStream()); - - v.add(new CertStatus(digester.getDigest(), reqID)); + v.add(new CertStatus(certHash, reqID)); } - return new CertificateConfirmationContent(CertConfirmContent.getInstance(new DERSequence(v)), digestAlgFinder); - } + CertConfirmContent content = CertConfirmContent.getInstance(new DERSequence(v)); + return new CertificateConfirmationContent(content, digestAlgFinder); + } } diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateStatus.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateStatus.java index 0531c87eec..b2c83ee932 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateStatus.java +++ b/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateStatus.java @@ -37,31 +37,16 @@ public BigInteger getCertRequestID() public boolean isVerified(X509CertificateHolder certHolder, DigestCalculatorProvider digesterProvider) throws CMPException { - return isVerified(new CMPCertificate(certHolder.toASN1Structure()), certHolder.getSignatureAlgorithm(), digesterProvider); + return isVerified(new CMPCertificate(certHolder.toASN1Structure()), certHolder.getSignatureAlgorithm(), + digesterProvider); } - public boolean isVerified(CMPCertificate cmpCert, AlgorithmIdentifier signatureAlgorithm, DigestCalculatorProvider digesterProvider) + public boolean isVerified(CMPCertificate cmpCert, AlgorithmIdentifier signatureAlgorithm, + DigestCalculatorProvider digesterProvider) throws CMPException { - AlgorithmIdentifier digAlg = digestAlgFinder.find(signatureAlgorithm); - if (digAlg == null) - { - throw new CMPException("cannot find algorithm for digest from signature"); - } + byte[] certHash = CMPUtil.calculateCertHash(cmpCert, signatureAlgorithm, digesterProvider, digestAlgFinder); - DigestCalculator digester; - - try - { - digester = digesterProvider.get(digAlg); - } - catch (OperatorCreationException e) - { - throw new CMPException("unable to create digester: " + e.getMessage(), e); - } - - CMPUtil.derEncodeToStream(cmpCert, digester.getOutputStream()); - - return Arrays.areEqual(certStatus.getCertHash().getOctets(), digester.getDigest()); + return Arrays.constantTimeAreEqual(certStatus.getCertHash().getOctets(), certHash); } } diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/GeneralPKIMessage.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/GeneralPKIMessage.java index a928623f41..b2998e8352 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/cmp/GeneralPKIMessage.java +++ b/pkix/src/main/java/org/bouncycastle/cert/cmp/GeneralPKIMessage.java @@ -72,7 +72,7 @@ public PKIBody getBody() */ public boolean hasProtection() { - return pkiMessage.getHeader().getProtectionAlg() != null; + return pkiMessage.getProtection() != null; } public PKIMessage toASN1Structure() diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessage.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessage.java index 6c06563332..6f955be379 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessage.java +++ b/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessage.java @@ -83,15 +83,14 @@ public PKIMessage toASN1Structure() } /** - * Determine whether the message is protected by a the CMP password based MAC. Use verify(PBEMacCalculatorProvider, char[]) + * Determine whether the message is protected by a CMP password based MAC. Use verify(PBEMacCalculatorProvider, char[]) * to verify the message if this method returns true. * * @return true if protection MAC PBE based, false otherwise. */ public boolean hasPasswordBasedMacProtection() { - ASN1ObjectIdentifier procAlg = pkiMessage.getHeader().getProtectionAlg().getAlgorithm(); - return procAlg.equals(CMPObjectIdentifiers.passwordBasedMac); + return CMPObjectIdentifiers.passwordBasedMac.equals(getProtectionAlgorithm().getAlgorithm()); } /** @@ -138,12 +137,11 @@ public X509CertificateHolder[] getCertificates() public boolean verify(ContentVerifierProvider verifierProvider) throws CMPException { - ContentVerifier verifier; try { - verifier = verifierProvider.get(pkiMessage.getHeader().getProtectionAlg()); + ContentVerifier verifier = verifierProvider.get(getProtectionAlgorithm()); - return verifySignature(pkiMessage.getProtection().getBytes(), verifier); + return verifySignature(pkiMessage.getProtection().getOctets(), verifier); } catch (Exception e) { @@ -164,20 +162,11 @@ public boolean verify(PBEMacCalculatorProvider pbeMacCalculatorProvider, char[] { try { - MacCalculator calculator = pbeMacCalculatorProvider.get(pkiMessage.getHeader().getProtectionAlg(), password); + MacCalculator calculator = pbeMacCalculatorProvider.get(getProtectionAlgorithm(), password); - OutputStream macOut = calculator.getOutputStream(); + CMPUtil.derEncodeToStream(createProtected(), calculator.getOutputStream()); - ASN1EncodableVector v = new ASN1EncodableVector(); - - v.add(pkiMessage.getHeader()); - v.add(pkiMessage.getBody()); - - macOut.write(new DERSequence(v).getEncoded(ASN1Encoding.DER)); - - macOut.close(); - - return Arrays.constantTimeAreEqual(calculator.getMac(), pkiMessage.getProtection().getBytes()); + return Arrays.constantTimeAreEqual(calculator.getMac(), pkiMessage.getProtection().getOctets()); } catch (Exception e) { @@ -186,19 +175,17 @@ public boolean verify(PBEMacCalculatorProvider pbeMacCalculatorProvider, char[] } private boolean verifySignature(byte[] signature, ContentVerifier verifier) - throws IOException { - ASN1EncodableVector v = new ASN1EncodableVector(); + CMPUtil.derEncodeToStream(createProtected(), verifier.getOutputStream()); + + return verifier.verify(signature); + } + private DERSequence createProtected() + { + ASN1EncodableVector v = new ASN1EncodableVector(2); v.add(pkiMessage.getHeader()); v.add(pkiMessage.getBody()); - - OutputStream sOut = verifier.getOutputStream(); - - sOut.write(new DERSequence(v).getEncoded(ASN1Encoding.DER)); - - sOut.close(); - - return verifier.verify(signature); + return new DERSequence(v); } } diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessageBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessageBuilder.java index 334b9c71b4..1ef57d331e 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessageBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessageBuilder.java @@ -192,7 +192,7 @@ public ProtectedPKIMessageBuilder setBody(int bodyType, CertificateRepMessage ce { if (!CertificateRepMessage.isCertificateRepMessage(bodyType)) { - throw new IllegalArgumentException("body type " + bodyType + " does not match CMP type CertReqMessages"); + throw new IllegalArgumentException("body type " + bodyType + " does not match CMP type CertRepMessage"); } this.body = new PKIBody(bodyType, certificateRepMessage.toASN1Structure()); diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRepMessage.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRepMessage.java index ab2b703856..0eeef79eb0 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRepMessage.java +++ b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRepMessage.java @@ -102,7 +102,7 @@ public CMPCertificate[] getCMPCertificates() return certs; } - public ASN1Encodable toASN1Structure() + public CertRepMessage toASN1Structure() { return new CertRepMessage(caCerts, resps); } diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRepMessageBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRepMessageBuilder.java index 1f6d1296c2..e6eabf140e 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRepMessageBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRepMessageBuilder.java @@ -9,7 +9,7 @@ import org.bouncycastle.cert.X509CertificateHolder; /** - * Builder for a CertRepMessage. + * Builder for a CertificateRepMessage. */ public class CertificateRepMessageBuilder { diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateReqMessagesBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateReqMessagesBuilder.java index 6676beb8b3..b33d2b38d7 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateReqMessagesBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateReqMessagesBuilder.java @@ -8,11 +8,10 @@ public class CertificateReqMessagesBuilder { - List requests = new ArrayList(); + private final List requests = new ArrayList(); public CertificateReqMessagesBuilder() { - } public void addRequest(CertificateRequestMessage request) @@ -22,8 +21,8 @@ public void addRequest(CertificateRequestMessage request) public CertificateReqMessages build() { - - CertificateReqMessages certificateReqMessages = new CertificateReqMessages(new CertReqMessages((CertReqMsg[])requests.toArray(new CertReqMsg[0]))); + CertificateReqMessages certificateReqMessages = new CertificateReqMessages( + new CertReqMessages((CertReqMsg[])requests.toArray(new CertReqMsg[0]))); requests.clear(); diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessage.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessage.java index ecd7c58e73..3b7a7c4945 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessage.java +++ b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessage.java @@ -1,13 +1,12 @@ package org.bouncycastle.cert.crmf; import java.io.IOException; -import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1UTF8String; -import org.bouncycastle.asn1.cmp.PKIBody; import org.bouncycastle.asn1.crmf.AttributeTypeAndValue; import org.bouncycastle.asn1.crmf.CRMFObjectIdentifiers; import org.bouncycastle.asn1.crmf.CertReqMsg; @@ -22,7 +21,6 @@ import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.util.Encodable; -import org.bouncycastle.util.test.FixedSecureRandom; /** * Carrier for a CRMF CertReqMsg. @@ -43,7 +41,7 @@ private static CertReqMsg parseBytes(byte[] encoding) { try { - return CertReqMsg.getInstance(ASN1Primitive.fromByteArray(encoding)); + return CertReqMsg.getInstance(encoding); } catch (ClassCastException e) { @@ -92,6 +90,7 @@ public ASN1Integer getCertReqId() { return certReqMsg.getCertReq().getCertReqId(); } + /** * Return the certificate template contained in this message. * @@ -181,7 +180,7 @@ private AttributeTypeAndValue findControl(ASN1ObjectIdentifier type) */ public boolean hasProofOfPossession() { - return this.certReqMsg.getPopo() != null; + return this.certReqMsg.getPop() != null; } /** @@ -191,7 +190,7 @@ public boolean hasProofOfPossession() */ public int getProofOfPossessionType() { - return this.certReqMsg.getPopo().getType(); + return this.certReqMsg.getPop().getType(); } /** @@ -202,16 +201,16 @@ public int getProofOfPossessionType() */ public boolean hasSigningKeyProofOfPossessionWithPKMAC() { - ProofOfPossession pop = certReqMsg.getPopo(); + ProofOfPossession pop = certReqMsg.getPop(); - if (pop.getType() == popSigningKey) + if (pop.getType() != popSigningKey) { - POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject()); - - return popoSign.getPoposkInput().getPublicKeyMAC() != null; + return false; } - return false; + POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject()); + + return popoSign.getPoposkInput().getPublicKeyMAC() != null; } /** @@ -225,23 +224,21 @@ public boolean hasSigningKeyProofOfPossessionWithPKMAC() public boolean isValidSigningKeyPOP(ContentVerifierProvider verifierProvider) throws CRMFException, IllegalStateException { - ProofOfPossession pop = certReqMsg.getPopo(); + ProofOfPossession pop = certReqMsg.getPop(); - if (pop.getType() == popSigningKey) + if (pop.getType() != popSigningKey) { - POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject()); + throw new IllegalStateException("not Signing Key type of proof of possession"); + } - if (popoSign.getPoposkInput() != null && popoSign.getPoposkInput().getPublicKeyMAC() != null) - { - throw new IllegalStateException("verification requires password check"); - } + POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject()); - return verifySignature(verifierProvider, popoSign); - } - else + if (popoSign.getPoposkInput() != null && popoSign.getPoposkInput().getPublicKeyMAC() != null) { - throw new IllegalStateException("not Signing Key type of proof of possession"); + throw new IllegalStateException("verification requires password check"); } + + return verifySignature(verifierProvider, popoSign); } /** @@ -257,38 +254,31 @@ public boolean isValidSigningKeyPOP(ContentVerifierProvider verifierProvider) public boolean isValidSigningKeyPOP(ContentVerifierProvider verifierProvider, PKMACBuilder macBuilder, char[] password) throws CRMFException, IllegalStateException { - ProofOfPossession pop = certReqMsg.getPopo(); + ProofOfPossession pop = certReqMsg.getPop(); - if (pop.getType() == popSigningKey) + if (pop.getType() != popSigningKey) { - POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject()); - - if (popoSign.getPoposkInput() == null || popoSign.getPoposkInput().getSender() != null) - { - throw new IllegalStateException("no PKMAC present in proof of possession"); - } + throw new IllegalStateException("not Signing Key type of proof of possession"); + } - PKMACValue pkMAC = popoSign.getPoposkInput().getPublicKeyMAC(); - PKMACValueVerifier macVerifier = new PKMACValueVerifier(macBuilder); + POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject()); - if (macVerifier.isValid(pkMAC, password, this.getCertTemplate().getPublicKey())) - { - return verifySignature(verifierProvider, popoSign); - } - - return false; - } - else + if (popoSign.getPoposkInput() == null || popoSign.getPoposkInput().getSender() != null) { - throw new IllegalStateException("not Signing Key type of proof of possession"); + throw new IllegalStateException("no PKMAC present in proof of possession"); } + + PKMACValue pkMAC = popoSign.getPoposkInput().getPublicKeyMAC(); + PKMACValueVerifier macVerifier = new PKMACValueVerifier(macBuilder); + + return macVerifier.isValid(pkMAC, password, this.getCertTemplate().getPublicKey()) + && verifySignature(verifierProvider, popoSign); } private boolean verifySignature(ContentVerifierProvider verifierProvider, POPOSigningKey popoSign) throws CRMFException { ContentVerifier verifier; - try { verifier = verifierProvider.get(popoSign.getAlgorithmIdentifier()); @@ -298,15 +288,14 @@ private boolean verifySignature(ContentVerifierProvider verifierProvider, POPOSi throw new CRMFException("unable to create verifier: " + e.getMessage(), e); } - if (popoSign.getPoposkInput() != null) + ASN1Object obj = popoSign.getPoposkInput(); + if (obj == null) { - CRMFUtil.derEncodeToStream(popoSign.getPoposkInput(), verifier.getOutputStream()); - } - else - { - CRMFUtil.derEncodeToStream(certReqMsg.getCertReq(), verifier.getOutputStream()); + obj = certReqMsg.getCertReq(); } + CRMFUtil.derEncodeToStream(obj, verifier.getOutputStream()); + return verifier.verify(popoSign.getSignature().getOctets()); } diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessageBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessageBuilder.java index 7ec3d93e54..e0176a147e 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessageBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessageBuilder.java @@ -108,6 +108,16 @@ public CertificateRequestMessageBuilder setSerialNumber(BigInteger serialNumber) return this; } + public CertificateRequestMessageBuilder setSerialNumber(ASN1Integer serialNumber) + { + if (serialNumber != null) + { + templateBuilder.setSerialNumber(serialNumber); + } + + return this; + } + /** * Request a validity period for the certificate. Either, but not both, of the date parameters may be null. * @@ -193,7 +203,7 @@ public CertificateRequestMessageBuilder setProofOfPossessionSubsequentMessage(in } if (type != ProofOfPossession.TYPE_KEY_ENCIPHERMENT && type != ProofOfPossession.TYPE_KEY_AGREEMENT) { - throw new IllegalArgumentException("type must be ProofOfPossession.TYPE_KEY_ENCIPHERMENT || ProofOfPossession.TYPE_KEY_AGREEMENT"); + throw new IllegalArgumentException("type must be ProofOfPossession.TYPE_KEY_ENCIPHERMENT or ProofOfPossession.TYPE_KEY_AGREEMENT"); } this.popoType = type; @@ -249,7 +259,7 @@ public CertificateRequestMessageBuilder setAuthInfoSender(GeneralName sender) public CertificateRequestMessage build() throws CRMFException { - ASN1EncodableVector v = new ASN1EncodableVector(); + ASN1EncodableVector v = new ASN1EncodableVector(3); v.add(new ASN1Integer(certReqId)); @@ -276,15 +286,16 @@ public CertificateRequestMessage build() CertRequest request = CertRequest.getInstance(new DERSequence(v)); - ProofOfPossession proofOfPossession = new ProofOfPossession(); + ProofOfPossession proofOfPossession; if (popSigner != null) { CertTemplate template = request.getCertTemplate(); + ProofOfPossessionSigningKeyBuilder builder; if (template.getSubject() == null || template.getPublicKey() == null) { SubjectPublicKeyInfo pubKeyInfo = request.getCertTemplate().getPublicKey(); - ProofOfPossessionSigningKeyBuilder builder = new ProofOfPossessionSigningKeyBuilder(pubKeyInfo); + builder = new ProofOfPossessionSigningKeyBuilder(pubKeyInfo); if (sender != null) { @@ -292,17 +303,15 @@ public CertificateRequestMessage build() } else { - PKMACValueGenerator pkmacGenerator = new PKMACValueGenerator(pkmacBuilder); - - builder.setPublicKeyMac(pkmacGenerator, password); + builder.setPublicKeyMac(pkmacBuilder, password); } - proofOfPossession = new ProofOfPossession(builder.build(popSigner)); } else { - ProofOfPossessionSigningKeyBuilder builder = new ProofOfPossessionSigningKeyBuilder(request); - proofOfPossession = new ProofOfPossession(builder.build(popSigner)); + builder = new ProofOfPossessionSigningKeyBuilder(request); } + + proofOfPossession = new ProofOfPossession(builder.build(popSigner)); } else if (popoPrivKey != null) { @@ -316,9 +325,13 @@ else if (popRaVerified != null) { proofOfPossession = new ProofOfPossession(); } + else + { + proofOfPossession = new ProofOfPossession(); + } CertReqMsg certReqMsg = new CertReqMsg(request, proofOfPossession, regInfo); return new CertificateRequestMessage(certReqMsg); } -} \ No newline at end of file +} diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateResponseBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateResponseBuilder.java index 615ad76c3c..e7e6d30d80 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateResponseBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateResponseBuilder.java @@ -1,6 +1,7 @@ package org.bouncycastle.cert.crmf; import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cmp.CMPCertificate; import org.bouncycastle.asn1.cmp.CertOrEncCert; @@ -17,10 +18,11 @@ */ public class CertificateResponseBuilder { + private final ASN1Integer certReqId; + private final PKIStatusInfo statusInfo; + private CertifiedKeyPair certKeyPair; - private ASN1Integer certReqId; - private PKIStatusInfo statusInfo; - private DEROctetString rspInfo; + private ASN1OctetString rspInfo; /** * Base constructor. diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValueParser.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValueParser.java index 3390064a3d..1f9c6c5626 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValueParser.java +++ b/pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValueParser.java @@ -63,14 +63,7 @@ private byte[] decryptValue(ValueDecryptorGenerator decGen) value.getEncValue().getBytes())); try { - byte[] data = Streams.readAll(dataIn); - - if (padder != null) - { - return padder.getUnpaddedData(data); - } - - return data; + return unpadData(Streams.readAll(dataIn)); } catch (IOException e) { @@ -116,4 +109,14 @@ public char[] readPassphrase(ValueDecryptorGenerator decGen) { return Strings.fromUTF8ByteArray(decryptValue(decGen)).toCharArray(); } + + private byte[] unpadData(byte[] data) + { + if (padder != null) + { + return padder.getUnpaddedData(data); + } + + return data; + } } diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACBuilder.java index 69880d110b..3f1fa95d7d 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACBuilder.java @@ -31,7 +31,8 @@ public class PKMACBuilder public PKMACBuilder(PKMACValuesCalculator calculator) { - this(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), 1000, new AlgorithmIdentifier(IANAObjectIdentifiers.hmacSHA1, DERNull.INSTANCE), calculator); + this(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), 1000, + new AlgorithmIdentifier(IANAObjectIdentifiers.hmacSHA1, DERNull.INSTANCE), calculator); } /** @@ -46,7 +47,8 @@ public PKMACBuilder(PKMACValuesCalculator calculator, int maxIterations) this.calculator = calculator; } - private PKMACBuilder(AlgorithmIdentifier hashAlgorithm, int iterationCount, AlgorithmIdentifier macAlgorithm, PKMACValuesCalculator calculator) + private PKMACBuilder(AlgorithmIdentifier hashAlgorithm, int iterationCount, AlgorithmIdentifier macAlgorithm, + PKMACValuesCalculator calculator) { this.owf = hashAlgorithm; this.iterationCount = iterationCount; @@ -124,23 +126,13 @@ public MacCalculator get(AlgorithmIdentifier algorithm, char[] password) public MacCalculator build(char[] password) throws CRMFException { - if (parameters != null) + PBMParameter pbmParameter = parameters; + if (pbmParameter == null) { - return genCalculator(parameters, password); + pbmParameter = genParameters(); } - else - { - byte[] salt = new byte[saltLength]; - - if (random == null) - { - this.random = new SecureRandom(); - } - random.nextBytes(salt); - - return genCalculator(new PBMParameter(salt, owf, iterationCount, mac), password); - } + return genCalculator(pbmParameter, password); } private void checkIterationCountCeiling(int iterationCount) @@ -219,4 +211,18 @@ public byte[] getMac() } }; } + + private PBMParameter genParameters() + { + byte[] salt = new byte[saltLength]; + + if (random == null) + { + random = new SecureRandom(); + } + + random.nextBytes(salt); + + return new PBMParameter(salt, owf, iterationCount, mac); + } } diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueGenerator.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueGenerator.java index 2457687dab..633eadba0e 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueGenerator.java @@ -9,16 +9,13 @@ import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.operator.MacCalculator; -class PKMACValueGenerator +abstract class PKMACValueGenerator { - private PKMACBuilder builder; - - public PKMACValueGenerator(PKMACBuilder builder) + private PKMACValueGenerator() { - this.builder = builder; } - public PKMACValue generate(char[] password, SubjectPublicKeyInfo keyInfo) + public static PKMACValue generate(PKMACBuilder builder, char[] password, SubjectPublicKeyInfo keyInfo) throws CRMFException { MacCalculator calculator = builder.build(password); diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueVerifier.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueVerifier.java index 02073b3d91..624d881ca6 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueVerifier.java +++ b/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueVerifier.java @@ -38,6 +38,6 @@ public boolean isValid(PKMACValue value, char[] password, SubjectPublicKeyInfo k throw new CRMFException("exception encoding mac input: " + e.getMessage(), e); } - return Arrays.constantTimeAreEqual(calculator.getMac(), value.getValue().getBytes()); + return Arrays.constantTimeAreEqual(calculator.getMac(), value.getValue().getOctets()); } -} \ No newline at end of file +} diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/ProofOfPossessionSigningKeyBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/ProofOfPossessionSigningKeyBuilder.java index 72979801ee..3fb33a5230 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/crmf/ProofOfPossessionSigningKeyBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/crmf/ProofOfPossessionSigningKeyBuilder.java @@ -34,10 +34,10 @@ public ProofOfPossessionSigningKeyBuilder setSender(GeneralName name) return this; } - public ProofOfPossessionSigningKeyBuilder setPublicKeyMac(PKMACValueGenerator generator, char[] password) + public ProofOfPossessionSigningKeyBuilder setPublicKeyMac(PKMACBuilder builder, char[] password) throws CRMFException { - this.publicKeyMAC = generator.generate(password, pubKeyInfo); + this.publicKeyMAC = PKMACValueGenerator.generate(builder, password, pubKeyInfo); return this; } diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationContext.java b/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationContext.java index 6a4b0ec27f..b50d30d70c 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationContext.java +++ b/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationContext.java @@ -51,11 +51,22 @@ public boolean isEndEntity() public Memoable copy() { - return null; //To change body of implemented methods use File | Settings | File Templates. + CertPathValidationContext c = new CertPathValidationContext(new HashSet(this.criticalExtensions)); + + c.handledExtensions = new HashSet(this.handledExtensions); + c.endEntity = this.endEntity; + c.index = this.index; + + return c; } public void reset(Memoable other) { - //To change body of implemented methods use File | Settings | File Templates. + CertPathValidationContext c = (CertPathValidationContext) other; + + this.criticalExtensions = new HashSet(c.criticalExtensions); + this.handledExtensions = new HashSet(c.handledExtensions); + this.endEntity = c.endEntity; + this.index = c.index; } } diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/validations/BasicConstraintsValidation.java b/pkix/src/main/java/org/bouncycastle/cert/path/validations/BasicConstraintsValidation.java index e3e9c54e8e..0a40236ef1 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/path/validations/BasicConstraintsValidation.java +++ b/pkix/src/main/java/org/bouncycastle/cert/path/validations/BasicConstraintsValidation.java @@ -1,18 +1,15 @@ package org.bouncycastle.cert.path.validations; -import java.math.BigInteger; - +import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.path.CertPathValidation; import org.bouncycastle.cert.path.CertPathValidationContext; import org.bouncycastle.cert.path.CertPathValidationException; -import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Integers; import org.bouncycastle.util.Memoable; - public class BasicConstraintsValidation implements CertPathValidation { @@ -34,7 +31,6 @@ public BasicConstraintsValidation(boolean isMandatory) public void validate(CertPathValidationContext context, X509CertificateHolder certificate) throws CertPathValidationException { - context.addHandledExtension(Extension.basicConstraints); // verify that the issuing certificate is in fact a CA @@ -62,17 +58,18 @@ public void validate(CertPathValidationContext context, X509CertificateHolder ce // § 6.1.4 (m) // Update maxPathLength if appropriate - if (bc != null) + if (bc != null && bc.isCA()) { - BigInteger bigPathLen = bc.getPathLenConstraint(); - if (bigPathLen != null) + ASN1Integer pathLenConstraint = bc.getPathLenConstraintInteger(); + if (pathLenConstraint != null) { - // use intValueExact to prevent issues with weird certificates that include ridiculous path lengths - int newPathLength = BigIntegers.intValueExact(bigPathLen); - maxPathLength = maxPathLength == null ? Integers.valueOf(newPathLength) : Integers.valueOf(Math.min(newPathLength, maxPathLength.intValue())); + int newPathLength = pathLenConstraint.intPositiveValueExact(); + if (maxPathLength == null || newPathLength < maxPathLength.intValue()) + { + maxPathLength = Integers.valueOf(newPathLength); + } } } - } public Memoable copy() diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/validations/CertificatePoliciesValidation.java b/pkix/src/main/java/org/bouncycastle/cert/path/validations/CertificatePoliciesValidation.java index cf0533e1a2..56ac4b991e 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/path/validations/CertificatePoliciesValidation.java +++ b/pkix/src/main/java/org/bouncycastle/cert/path/validations/CertificatePoliciesValidation.java @@ -136,11 +136,21 @@ private int countDown(int policyCounter) public Memoable copy() { - return new CertificatePoliciesValidation(0); // TODO: + CertificatePoliciesValidation v = new CertificatePoliciesValidation(0); + + v.explicitPolicy = this.explicitPolicy; + v.policyMapping = this.policyMapping; + v.inhibitAnyPolicy = this.inhibitAnyPolicy; + + return v; } public void reset(Memoable other) { - CertificatePoliciesValidation v = (CertificatePoliciesValidation)other; // TODO: + CertificatePoliciesValidation v = (CertificatePoliciesValidation) other; + + this.explicitPolicy = v.explicitPolicy; + this.policyMapping = v.policyMapping; + this.inhibitAnyPolicy = v.inhibitAnyPolicy; } } diff --git a/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java b/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java index 13e9e6b46d..3e300f1a55 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java +++ b/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java @@ -1,6 +1,7 @@ package org.bouncycastle.cert.selector.jcajce; import java.io.IOException; +import java.math.BigInteger; import java.security.cert.X509CertSelector; import org.bouncycastle.asn1.ASN1OctetString; @@ -18,14 +19,17 @@ public X509CertificateHolderSelector getCertificateHolderSelector(X509CertSelect { try { - if (certSelector.getSubjectKeyIdentifier() != null) - { - return new X509CertificateHolderSelector(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets()); - } - else + X500Name issuer = X500Name.getInstance(certSelector.getIssuerAsBytes()); + BigInteger serialNumber = certSelector.getSerialNumber(); + byte[] subjectKeyId = null; + + byte[] subjectKeyIdentifier = certSelector.getSubjectKeyIdentifier(); + if (subjectKeyIdentifier != null) { - return new X509CertificateHolderSelector(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber()); + subjectKeyId = ASN1OctetString.getInstance(subjectKeyIdentifier).getOctets(); } + + return new X509CertificateHolderSelector(issuer, serialNumber, subjectKeyId); } catch (IOException e) { diff --git a/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java index 22a35371db..32eb8d0773 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java +++ b/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; +import org.bouncycastle.util.Exceptions; public class JcaX509CertSelectorConverter { @@ -26,7 +27,7 @@ protected X509CertSelector doConversion(X500Name issuer, BigInteger serialNumber } catch (IOException e) { - throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); + throw Exceptions.illegalArgumentException("unable to convert issuer: " + e.getMessage(), e); } } @@ -43,7 +44,7 @@ protected X509CertSelector doConversion(X500Name issuer, BigInteger serialNumber } catch (IOException e) { - throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); + throw Exceptions.illegalArgumentException("unable to convert subjectKeyIdentifier: " + e.getMessage(), e); } } diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAlgorithm.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAlgorithm.java index 352076b934..103659c424 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSAlgorithm.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSAlgorithm.java @@ -4,6 +4,7 @@ import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; +import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; @@ -18,8 +19,8 @@ public class CMSAlgorithm public static final ASN1ObjectIdentifier DES_CBC = OIWObjectIdentifiers.desCBC.intern(); public static final ASN1ObjectIdentifier DES_EDE3_CBC = PKCSObjectIdentifiers.des_EDE3_CBC.intern(); public static final ASN1ObjectIdentifier RC2_CBC = PKCSObjectIdentifiers.RC2_CBC.intern(); - public static final ASN1ObjectIdentifier IDEA_CBC = new ASN1ObjectIdentifier("1.3.6.1.4.1.188.7.1.1.2").intern(); - public static final ASN1ObjectIdentifier CAST5_CBC = new ASN1ObjectIdentifier("1.2.840.113533.7.66.10").intern(); + public static final ASN1ObjectIdentifier IDEA_CBC = MiscObjectIdentifiers.as_sys_sec_alg_ideaCBC.intern(); + public static final ASN1ObjectIdentifier CAST5_CBC = MiscObjectIdentifiers.cast5CBC.intern(); public static final ASN1ObjectIdentifier AES128_CBC = NISTObjectIdentifiers.id_aes128_CBC.intern(); public static final ASN1ObjectIdentifier AES192_CBC = NISTObjectIdentifiers.id_aes192_CBC.intern(); diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedData.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedData.java index 770f8d5287..f1edc92993 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedData.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedData.java @@ -3,7 +3,9 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; +import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.AttributeTable; @@ -23,23 +25,26 @@ public class CMSAuthEnvelopedData RecipientInformationStore recipientInfoStore; ContentInfo contentInfo; - private OriginatorInformation originatorInfo; - private AlgorithmIdentifier authEncAlg; - private ASN1Set authAttrs; - private byte[] mac; - private ASN1Set unauthAttrs; + private OriginatorInformation originatorInfo; + private AlgorithmIdentifier authEncAlg; + private ASN1Set authAttrs; + private byte[] mac; + private ASN1Set unauthAttrs; - public CMSAuthEnvelopedData(byte[] authEnvData) throws CMSException + public CMSAuthEnvelopedData(byte[] authEnvData) + throws CMSException { this(CMSUtils.readContentInfo(authEnvData)); } - public CMSAuthEnvelopedData(InputStream authEnvData) throws CMSException + public CMSAuthEnvelopedData(InputStream authEnvData) + throws CMSException { this(CMSUtils.readContentInfo(authEnvData)); } - public CMSAuthEnvelopedData(ContentInfo contentInfo) throws CMSException + public CMSAuthEnvelopedData(ContentInfo contentInfo) + throws CMSException { this.contentInfo = contentInfo; @@ -63,17 +68,58 @@ public CMSAuthEnvelopedData(ContentInfo contentInfo) throws CMSException this.mac = authEnvData.getMac().getOctets(); - CMSSecureReadable secureReadable = new CMSSecureReadable() + CMSSecureReadable secureReadable = new CMSSecureReadableWithAAD() { + private OutputStream aadStream; + + @Override + public ASN1Set getAuthAttrSet() + { + return authAttrs; + } + + @Override + public void setAuthAttrSet(ASN1Set set) + { + + } + + @Override + public boolean hasAdditionalData() + { + return (aadStream != null && authAttrs != null); + } + public ASN1ObjectIdentifier getContentType() { return authEncInfo.getContentType(); } public InputStream getInputStream() - throws IOException, CMSException + throws IOException + { + if (aadStream != null && authAttrs != null) + { + aadStream.write(authAttrs.getEncoded(ASN1Encoding.DER)); + } + return new InputStreamWithMAC(new ByteArrayInputStream(authEncInfo.getEncryptedContent().getOctets()), mac); + } + + @Override + public void setAADStream(OutputStream stream) { - return new ByteArrayInputStream(Arrays.concatenate(authEncInfo.getEncryptedContent().getOctets(), mac)); + aadStream = stream; + } + + public OutputStream getAADStream() + { + return aadStream; + } + + @Override + public byte[] getMAC() + { + return Arrays.clone(mac); } }; @@ -84,27 +130,8 @@ public InputStream getInputStream() // // build the RecipientInformationStore // - if (authAttrs != null) - { - this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore( - recipientInfos, this.authEncAlg, secureReadable, new AuthAttributesProvider() - { - public ASN1Set getAuthAttributes() - { - return authAttrs; - } - - public boolean isAead() - { - return true; - } - }); - } - else - { - this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore( - recipientInfos, this.authEncAlg, secureReadable); - } + this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore( + recipientInfos, this.authEncAlg, secureReadable); } /** @@ -128,6 +155,7 @@ public RecipientInformationStore getRecipientInfos() /** * return a table of the authenticated attributes (as in those used to provide associated data) indexed by * the OID of the attribute. + * * @return the authenticated attributes. */ public AttributeTable getAuthAttrs() @@ -143,6 +171,7 @@ public AttributeTable getAuthAttrs() /** * return a table of the unauthenticated attributes indexed by * the OID of the attribute. + * * @return the unauthenticated attributes. */ public AttributeTable getUnauthAttrs() @@ -157,6 +186,7 @@ public AttributeTable getUnauthAttrs() /** * Return the MAC value that was originally calculated for this AuthEnveloped data. + * * @return the MAC data associated with the stream. */ public byte[] getMac() diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataGenerator.java index 976603d303..e84f2a69af 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataGenerator.java @@ -3,24 +3,15 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.util.Collections; -import java.util.Iterator; import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; -import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; -import org.bouncycastle.asn1.DLSet; -import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.AuthEnvelopedData; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputAEADEncryptor; public class CMSAuthEnvelopedDataGenerator @@ -38,26 +29,17 @@ private CMSAuthEnvelopedData doGenerate( OutputAEADEncryptor contentEncryptor) throws CMSException { - ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); - AlgorithmIdentifier encAlgId; - ASN1OctetString encContent; + ASN1EncodableVector recipientInfos = CMSUtils.getRecipentInfos(contentEncryptor.getKey(), recipientInfoGenerators); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - ASN1Set authenticatedAttrSet = null; + ASN1Set authenticatedAttrSet; try { OutputStream cOut = contentEncryptor.getOutputStream(bOut); content.write(cOut); - - if (authAttrsGenerator != null) - { - AttributeTable attrTable = authAttrsGenerator.getAttributes(Collections.EMPTY_MAP); - authenticatedAttrSet = new DERSet(attrTable.toASN1EncodableVector()); - - contentEncryptor.getAADStream().write(authenticatedAttrSet.getEncoded(ASN1Encoding.DER)); - } + authenticatedAttrSet = CMSUtils.processAuthAttrSet(authAttrsGenerator, contentEncryptor); cOut.close(); } @@ -69,35 +51,13 @@ private CMSAuthEnvelopedData doGenerate( byte[] encryptedContent = bOut.toByteArray(); byte[] mac = contentEncryptor.getMAC(); - encAlgId = contentEncryptor.getAlgorithmIdentifier(); - - encContent = new BEROctetString(encryptedContent); - - GenericKey encKey = contentEncryptor.getKey(); + EncryptedContentInfo eci = CMSUtils.getEncryptedContentInfo(content, contentEncryptor, encryptedContent); - for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext();) - { - RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); - - recipientInfos.add(recipient.generate(encKey)); - } - - EncryptedContentInfo eci = new EncryptedContentInfo( - content.getContentType(), - encAlgId, - encContent); - - ASN1Set unprotectedAttrSet = null; - if (unauthAttrsGenerator != null) - { - AttributeTable attrTable = unauthAttrsGenerator.getAttributes(Collections.EMPTY_MAP); - - unprotectedAttrSet = new DLSet(attrTable.toASN1EncodableVector()); - } + ASN1Set unprotectedAttrSet = CMSUtils.getAttrDLSet(unauthAttrsGenerator); ContentInfo contentInfo = new ContentInfo( - CMSObjectIdentifiers.authEnvelopedData, - new AuthEnvelopedData(originatorInfo, new DERSet(recipientInfos), eci, authenticatedAttrSet, new DEROctetString(mac), unprotectedAttrSet)); + CMSObjectIdentifiers.authEnvelopedData, + new AuthEnvelopedData(originatorInfo, new DERSet(recipientInfos), eci, authenticatedAttrSet, new DEROctetString(mac), unprotectedAttrSet)); return new CMSAuthEnvelopedData(contentInfo); } diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataParser.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataParser.java new file mode 100644 index 0000000000..0d58f0c413 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataParser.java @@ -0,0 +1,300 @@ +package org.bouncycastle.cms; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1OctetStringParser; +import org.bouncycastle.asn1.ASN1SequenceParser; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.ASN1SetParser; +import org.bouncycastle.asn1.BERTags; +import org.bouncycastle.asn1.cms.AttributeTable; +import org.bouncycastle.asn1.cms.AuthEnvelopedDataParser; +import org.bouncycastle.asn1.cms.CMSAttributes; +import org.bouncycastle.asn1.cms.EncryptedContentInfoParser; +import org.bouncycastle.asn1.cms.OriginatorInfo; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.util.Arrays; + +public class CMSAuthEnvelopedDataParser + extends CMSContentInfoParser +{ + private final RecipientInformationStore recipientInfoStore; + private final AuthEnvelopedDataParser authEvnData; + private final LocalMacProvider localMacProvider; + private final AlgorithmIdentifier encAlg; + private AttributeTable authAttrs; + private ASN1Set authAttrSet; + private AttributeTable unauthAttrs; + + private boolean authAttrNotRead; + private boolean unauthAttrNotRead; + private OriginatorInformation originatorInfo; + + public CMSAuthEnvelopedDataParser( + byte[] envelopedData) + throws CMSException, IOException + { + this(new ByteArrayInputStream(envelopedData)); + } + + public CMSAuthEnvelopedDataParser( + InputStream envelopedData) + throws CMSException, IOException + { + super(envelopedData); + + authAttrNotRead = true; + unauthAttrNotRead = true; + authEvnData = new AuthEnvelopedDataParser((ASN1SequenceParser)_contentInfo.getContent(BERTags.SEQUENCE)); + + OriginatorInfo info = authEvnData.getOriginatorInfo(); + + if (info != null) + { + this.originatorInfo = new OriginatorInformation(info); + } + // + // read the recipients + // + ASN1Set recipientInfos = ASN1Set.getInstance(authEvnData.getRecipientInfos().toASN1Primitive()); + + final EncryptedContentInfoParser encInfo = authEvnData.getAuthEncryptedContentInfo(); + + encAlg = encInfo.getContentEncryptionAlgorithm(); + localMacProvider = new LocalMacProvider(authEvnData, this); + + final CMSReadable readable = new CMSProcessableInputStream(new InputStreamWithMAC( + ((ASN1OctetStringParser)encInfo.getEncryptedContent(BERTags.OCTET_STRING)).getOctetStream(), localMacProvider)); + + CMSSecureReadableWithAAD secureReadable = new CMSSecureReadableWithAAD() + { + private OutputStream aadStream; + + @Override + public ASN1ObjectIdentifier getContentType() + { + return encInfo.getContentType(); + } + + @Override + public InputStream getInputStream() + throws IOException, CMSException + { + return readable.getInputStream(); + } + + @Override + public ASN1Set getAuthAttrSet() + { + return authAttrSet; + } + + @Override + public void setAuthAttrSet(ASN1Set set) + { + + } + + @Override + public boolean hasAdditionalData() + { + return true; + } + + @Override + public void setAADStream(OutputStream stream) + { + aadStream = stream; + } + + @Override + public OutputStream getAADStream() + { + return aadStream; + } + + @Override + public byte[] getMAC() + { + return Arrays.clone(localMacProvider.getMAC()); + } + }; + + localMacProvider.setSecureReadable(secureReadable); + // + // build the RecipientInformationStore + // + this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore(recipientInfos, this.encAlg, secureReadable); + } + + /** + * Return the originator information associated with this message if present. + * + * @return OriginatorInformation, null if not present. + */ + public OriginatorInformation getOriginatorInfo() + { + return originatorInfo; + } + + /** + * Return the MAC algorithm details for the MAC associated with the data in this object. + * + * @return AlgorithmIdentifier representing the MAC algorithm. + */ + public AlgorithmIdentifier getEncryptionAlgOID() + { + return encAlg; + } + + /** + * return the object identifier for the mac algorithm. + */ + public String getEncAlgOID() + { + return encAlg.getAlgorithm().toString(); + } + + /** + * return the ASN.1 encoded encryption algorithm parameters, or null if + * there aren't any. + */ + public byte[] getEncAlgParams() + { + try + { + return CMSUtils.encodeObj(encAlg.getParameters()); + } + catch (Exception e) + { + throw new RuntimeException("exception getting encryption parameters " + e); + } + } + + /** + * return a store of the intended recipients for this message + */ + public RecipientInformationStore getRecipientInfos() + { + return recipientInfoStore; + } + + public byte[] getMac() + throws IOException + { + return Arrays.clone(localMacProvider.getMAC()); + } + + private ASN1Set getAuthAttrSet() + throws IOException + { + if (authAttrs == null && authAttrNotRead) + { + ASN1SetParser set = authEvnData.getAuthAttrs(); + + if (set != null) + { + authAttrSet = (ASN1Set)set.toASN1Primitive(); + } + + authAttrNotRead = false; + } + + return authAttrSet; + } + + /** + * return a table of the unauthenticated attributes indexed by + * the OID of the attribute. + */ + public AttributeTable getAuthAttrs() + throws IOException + { + if (authAttrs == null && authAttrNotRead) + { + ASN1Set set = getAuthAttrSet(); + + if (set != null) + { + authAttrs = new AttributeTable(set); + } + } + + return authAttrs; + } + + /** + * return a table of the unauthenticated attributes indexed by + * the OID of the attribute. + */ + public AttributeTable getUnauthAttrs() + throws IOException + { + if (unauthAttrs == null && unauthAttrNotRead) + { + unauthAttrNotRead = false; + unauthAttrs = CMSUtils.getAttributesTable(authEvnData.getUnauthAttrs()); + } + + return unauthAttrs; + } + + /** + * This will only be valid after the content has been read. + * + * @return the contents of the messageDigest attribute, if available. Null if not present. + */ + public byte[] getContentDigest() + { + if (authAttrs != null) + { + return ASN1OctetString.getInstance(authAttrs.get(CMSAttributes.messageDigest).getAttrValues().getObjectAt(0)).getOctets(); + } + + return null; + } + + static class LocalMacProvider + implements MACProvider + { + private byte[] mac; + private final AuthEnvelopedDataParser authEnvData; + private final CMSAuthEnvelopedDataParser parser; + private CMSSecureReadableWithAAD readable; + + LocalMacProvider(AuthEnvelopedDataParser authEnvData, CMSAuthEnvelopedDataParser parser) + { + this.authEnvData = authEnvData; + this.parser = parser; + } + + public void init() + throws IOException + { + parser.authAttrs = parser.getAuthAttrs(); + if (parser.authAttrs != null) + { + readable.setAuthAttrSet(parser.authAttrSet); + readable.getAADStream().write(parser.authAttrs.toASN1Structure().getEncoded(ASN1Encoding.DER)); + } + mac = authEnvData.getMac().getOctets(); + } + + void setSecureReadable(CMSSecureReadableWithAAD secureReadable) + { + readable = secureReadable; + } + + public byte[] getMAC() + { + return mac; + } + } +} + diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataStreamGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataStreamGenerator.java new file mode 100644 index 0000000000..7c78c9078f --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataStreamGenerator.java @@ -0,0 +1,200 @@ +package org.bouncycastle.cms; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collections; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.BERSequenceGenerator; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.operator.OutputAEADEncryptor; + +public class CMSAuthEnvelopedDataStreamGenerator + extends CMSAuthEnvelopedGenerator +{ + + private int _bufferSize; + private boolean _berEncodeRecipientSet; + + public CMSAuthEnvelopedDataStreamGenerator() + { + + } + + /** + * Set the underlying string size for encapsulated data + * + * @param bufferSize length of octet strings to buffer the data. + */ + public void setBufferSize( + int bufferSize) + { + _bufferSize = bufferSize; + } + + /** + * Use a BER Set to store the recipient information + */ + public void setBEREncodeRecipients( + boolean berEncodeRecipientSet) + { + _berEncodeRecipientSet = berEncodeRecipientSet; + } + + private OutputStream doOpen( + ASN1ObjectIdentifier dataType, + OutputStream out, + OutputAEADEncryptor encryptor) + throws IOException, CMSException + { + ASN1EncodableVector recipientInfos = CMSUtils.getRecipentInfos(encryptor.getKey(), recipientInfoGenerators); + + return open(dataType, out, recipientInfos, encryptor); + } + + protected OutputStream open( + ASN1ObjectIdentifier dataType, + OutputStream out, + ASN1EncodableVector recipientInfos, + OutputAEADEncryptor encryptor) + throws IOException + { + // + // ContentInfo + // + BERSequenceGenerator cGen = new BERSequenceGenerator(out); + + cGen.addObject(CMSObjectIdentifiers.authEnvelopedData); + + // + // Encrypted Data + // + BERSequenceGenerator authEnvGen = new BERSequenceGenerator(cGen.getRawOutputStream(), 0, true); + + authEnvGen.addObject(new ASN1Integer(0)); + + CMSUtils.addOriginatorInfoToGenerator(authEnvGen, originatorInfo); + + CMSUtils.addRecipientInfosToGenerator(recipientInfos, authEnvGen, _berEncodeRecipientSet); + + BERSequenceGenerator eiGen = new BERSequenceGenerator(authEnvGen.getRawOutputStream()); + + eiGen.addObject(dataType); + + AlgorithmIdentifier encAlgId = encryptor.getAlgorithmIdentifier(); + + eiGen.getRawOutputStream().write(encAlgId.getEncoded()); + + OutputStream octetStream = CMSUtils.createBEROctetOutputStream( + eiGen.getRawOutputStream(), 0, true, _bufferSize); + + return new CMSAuthEnvelopedDataOutputStream(encryptor, octetStream, cGen, authEnvGen, eiGen); + } + + protected OutputStream open( + OutputStream out, + ASN1EncodableVector recipientInfos, + OutputAEADEncryptor encryptor) + throws CMSException + { + try + { + return open(CMSObjectIdentifiers.data, out, recipientInfos, encryptor); + } + catch (IOException e) + { + throw new CMSException("exception decoding algorithm parameters.", e); + } + } + + + /** + * generate an enveloped object that contains an CMS Enveloped Data + * object using the given encryptor. + */ + public OutputStream open( + OutputStream out, + OutputAEADEncryptor encryptor) + throws CMSException, IOException + { + return doOpen(new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId()), out, encryptor); + } + + private class CMSAuthEnvelopedDataOutputStream + extends OutputStream + { + private final OutputAEADEncryptor _encryptor; + private final OutputStream _cOut; + private final OutputStream _octetStream; + private final BERSequenceGenerator _cGen; + private final BERSequenceGenerator _envGen; + private final BERSequenceGenerator _eiGen; + + public CMSAuthEnvelopedDataOutputStream( + OutputAEADEncryptor encryptor, + OutputStream octetStream, + BERSequenceGenerator cGen, + BERSequenceGenerator envGen, + BERSequenceGenerator eiGen) + { + _encryptor = encryptor; + _octetStream = octetStream; + _cOut = encryptor.getOutputStream(octetStream); + _cGen = cGen; + _envGen = envGen; + _eiGen = eiGen; + } + + public void write( + int b) + throws IOException + { + _cOut.write(b); + } + + public void write( + byte[] bytes, + int off, + int len) + throws IOException + { + _cOut.write(bytes, off, len); + } + + public void write( + byte[] bytes) + throws IOException + { + _cOut.write(bytes); + } + + public void close() + throws IOException + { + ASN1Set authenticatedAttrSet = CMSUtils.processAuthAttrSet(authAttrsGenerator, _encryptor); + + _cOut.close(); + _octetStream.close(); + _eiGen.close(); + + if (authenticatedAttrSet != null) + { + _envGen.addObject(new DERTaggedObject(false, 1, authenticatedAttrSet)); + } + + _envGen.addObject(new DEROctetString(_encryptor.getMAC())); + + CMSUtils.addAttriSetToGenerator(_envGen, unauthAttrsGenerator, 2, Collections.EMPTY_MAP); + + _envGen.close(); + _cGen.close(); + } + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedData.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedData.java index f09c555b25..20356ce51d 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedData.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedData.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.io.InputStream; -import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; @@ -145,19 +144,8 @@ public CMSAuthenticatedData( try { CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSDigestAuthenticatedSecureReadable(digestCalculatorProvider.get(authData.getDigestAlgorithm()), encInfo.getContentType(), readable); - - this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore(recipientInfos, this.macAlg, secureReadable, new AuthAttributesProvider() - { - public ASN1Set getAuthAttributes() - { - return authAttrs; - } - - public boolean isAead() - { - return false; - } - }); + secureReadable.setAuthAttrSet(authAttrs); + this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore(recipientInfos, this.macAlg, secureReadable); } catch (OperatorCreationException e) { @@ -166,8 +154,7 @@ public boolean isAead() } else { - CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSAuthenticatedSecureReadable(this.macAlg, encInfo.getContentType(), readable); - + CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSAuthEnveSecureReadable(this.macAlg, encInfo.getContentType(), readable); this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore(recipientInfos, this.macAlg, secureReadable); } } @@ -187,18 +174,6 @@ public byte[] getMac() return Arrays.clone(mac); } - private byte[] encodeObj( - ASN1Encodable obj) - throws IOException - { - if (obj != null) - { - return obj.toASN1Primitive().getEncoded(); - } - - return null; - } - /** * Return the MAC algorithm details for the MAC associated with the data in this object. * @@ -225,7 +200,7 @@ public byte[] getMacAlgParams() { try { - return encodeObj(macAlg.getParameters()); + return CMSUtils.encodeObj(macAlg.getParameters()); } catch (Exception e) { diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataGenerator.java index 3df2d46ea4..35bc6d151b 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataGenerator.java @@ -4,7 +4,6 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Collections; -import java.util.Iterator; import java.util.Map; import org.bouncycastle.asn1.ASN1EncodableVector; @@ -12,7 +11,6 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetString; -import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AuthenticatedData; @@ -27,7 +25,7 @@ /** * General class for generating a CMS authenticated-data message. - * + *

      * A simple example of usage. * *

      @@ -52,7 +50,7 @@ public CMSAuthenticatedDataGenerator()
           /**
            * Generate an authenticated data object from the passed in typedData and MacCalculator.
            *
      -     * @param typedData the data to have a MAC attached.
      +     * @param typedData     the data to have a MAC attached.
            * @param macCalculator the calculator of the MAC to be attached.
            * @return the resulting CMSAuthenticatedData object.
            * @throws CMSException on failure in encoding data or processing recipients.
      @@ -66,25 +64,19 @@ public CMSAuthenticatedData generate(CMSTypedData typedData, MacCalculator macCa
           /**
            * Generate an authenticated data object from the passed in typedData and MacCalculator.
            *
      -     * @param typedData the data to have a MAC attached.
      -     * @param macCalculator the calculator of the MAC to be attached.
      +     * @param typedData        the data to have a MAC attached.
      +     * @param macCalculator    the calculator of the MAC to be attached.
            * @param digestCalculator calculator for computing digest of the encapsulated data.
            * @return the resulting CMSAuthenticatedData object.
      -     * @throws CMSException on failure in encoding data or processing recipients.    
      +     * @throws CMSException on failure in encoding data or processing recipients.
            */
           public CMSAuthenticatedData generate(CMSTypedData typedData, MacCalculator macCalculator, final DigestCalculator digestCalculator)
               throws CMSException
           {
      -        ASN1EncodableVector     recipientInfos = new ASN1EncodableVector();
      -        ASN1OctetString         encContent;
      -        ASN1OctetString         macResult;
      +        ASN1OctetString encContent;
      +        ASN1OctetString macResult;
       
      -        for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext();)
      -        {
      -            RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next();
      -
      -            recipientInfos.add(recipient.generate(macCalculator.getKey()));
      -        }
      +        ASN1EncodableVector recipientInfos = CMSUtils.getRecipentInfos(macCalculator.getKey(), recipientInfoGenerators);
       
               AuthenticatedData authData;
       
      @@ -128,11 +120,11 @@ public CMSAuthenticatedData generate(CMSTypedData typedData, MacCalculator macCa
                   {
                       throw new CMSException("unable to perform MAC calculation: " + e.getMessage(), e);
                   }
      -            ASN1Set unauthed = (unauthGen != null) ? new BERSet(unauthGen.getAttributes(parameters).toASN1EncodableVector()) : null;
      +            ASN1Set unauthed = CMSUtils.getAttrBERSet(unauthGen);
       
      -            ContentInfo  eci = new ContentInfo(
      -                            typedData.getContentType(),
      -                            encContent);
      +            ContentInfo eci = new ContentInfo(
      +                typedData.getContentType(),
      +                encContent);
       
                   authData = new AuthenticatedData(originatorInfo, new DERSet(recipientInfos), macCalculator.getAlgorithmIdentifier(), digestCalculator.getAlgorithmIdentifier(), eci, authed, macResult, unauthed);
               }
      @@ -140,7 +132,7 @@ public CMSAuthenticatedData generate(CMSTypedData typedData, MacCalculator macCa
               {
                   try
                   {
      -                ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
      +                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
                       OutputStream mOut = new TeeOutputStream(bOut, macCalculator.getOutputStream());
       
                       typedData.write(mOut);
      @@ -156,17 +148,17 @@ public CMSAuthenticatedData generate(CMSTypedData typedData, MacCalculator macCa
                       throw new CMSException("unable to perform MAC calculation: " + e.getMessage(), e);
                   }
       
      -            ASN1Set unauthed = (unauthGen != null) ? new BERSet(unauthGen.getAttributes(Collections.EMPTY_MAP).toASN1EncodableVector()) : null;
      +            ASN1Set unauthed = CMSUtils.getAttrBERSet(unauthGen);
       
      -            ContentInfo  eci = new ContentInfo(
      -                            typedData.getContentType(),
      -                            encContent);
      +            ContentInfo eci = new ContentInfo(
      +                typedData.getContentType(),
      +                encContent);
       
                   authData = new AuthenticatedData(originatorInfo, new DERSet(recipientInfos), macCalculator.getAlgorithmIdentifier(), null, eci, null, macResult, unauthed);
               }
       
               ContentInfo contentInfo = new ContentInfo(
      -                CMSObjectIdentifiers.authenticatedData, authData);
      +            CMSObjectIdentifiers.authenticatedData, authData);
       
               return new CMSAuthenticatedData(contentInfo, new DigestCalculatorProvider()
               {
      diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataParser.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataParser.java
      index 175592520b..9750850141 100644
      --- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataParser.java
      +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataParser.java
      @@ -4,15 +4,12 @@
       import java.io.IOException;
       import java.io.InputStream;
       
      -import org.bouncycastle.asn1.ASN1Encodable;
      -import org.bouncycastle.asn1.ASN1EncodableVector;
       import org.bouncycastle.asn1.ASN1OctetString;
       import org.bouncycastle.asn1.ASN1OctetStringParser;
       import org.bouncycastle.asn1.ASN1SequenceParser;
       import org.bouncycastle.asn1.ASN1Set;
       import org.bouncycastle.asn1.ASN1SetParser;
       import org.bouncycastle.asn1.BERTags;
      -import org.bouncycastle.asn1.DERSet;
       import org.bouncycastle.asn1.cms.AttributeTable;
       import org.bouncycastle.asn1.cms.AuthenticatedDataParser;
       import org.bouncycastle.asn1.cms.CMSAttributes;
      @@ -53,12 +50,12 @@
        *          }
        *      }
        *  
      - * Note: this class does not introduce buffering - if you are processing large files you should create - * the parser with: - *
      + * Note: this class does not introduce buffering - if you are processing large files you should create
      + * the parser with:
      + * 
        *          CMSAuthenticatedDataParser     ep = new CMSAuthenticatedDataParser(new BufferedInputStream(inputStream, bufSize));
        *  
      - * where bufSize is a suitably large buffer size. + * where bufSize is a suitably large buffer size. */ public class CMSAuthenticatedDataParser extends CMSContentInfoParser @@ -76,6 +73,8 @@ public class CMSAuthenticatedDataParser private boolean unauthAttrNotRead; private OriginatorInformation originatorInfo; + private CMSSecureReadable secureReadable; + public CMSAuthenticatedDataParser( byte[] envelopedData) throws CMSException, IOException @@ -145,27 +144,9 @@ public CMSAuthenticatedDataParser( try { - CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSDigestAuthenticatedSecureReadable(digestCalculatorProvider.get(digestAlgorithm), data.getContentType(), readable); - - this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore(recipientInfos, this.macAlg, secureReadable, new AuthAttributesProvider() - { - public ASN1Set getAuthAttributes() - { - try - { - return getAuthAttrSet(); - } - catch (IOException e) - { - throw new IllegalStateException("can't parse authenticated attributes!"); - } - } - - public boolean isAead() - { - return false; - } - }); + secureReadable = new CMSEnvelopedHelper.CMSDigestAuthenticatedSecureReadable(digestCalculatorProvider.get(digestAlgorithm), data.getContentType(), readable); + + this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore(recipientInfos, this.macAlg, secureReadable); } catch (OperatorCreationException e) { @@ -181,7 +162,7 @@ public boolean isAead() CMSReadable readable = new CMSProcessableInputStream( ((ASN1OctetStringParser)data.getContent(BERTags.OCTET_STRING)).getOctetStream()); - CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSAuthenticatedSecureReadable(this.macAlg, data.getContentType(), readable); + secureReadable = new CMSEnvelopedHelper.CMSAuthEnveSecureReadable(this.macAlg, data.getContentType(), readable); this.recipientInfoStore = CMSEnvelopedHelper.buildRecipientInformationStore(recipientInfos, this.macAlg, secureReadable); } @@ -225,7 +206,7 @@ public byte[] getMacAlgParams() { try { - return encodeObj(macAlg.getParameters()); + return CMSUtils.encodeObj(macAlg.getParameters()); } catch (Exception e) { @@ -265,6 +246,7 @@ private ASN1Set getAuthAttrSet() } authAttrNotRead = false; + secureReadable.setAuthAttrSet(authAttrSet); } return authAttrSet; @@ -273,7 +255,8 @@ private ASN1Set getAuthAttrSet() /** * return a table of the unauthenticated attributes indexed by * the OID of the attribute. - * @exception java.io.IOException + * + * @throws java.io.IOException */ public AttributeTable getAuthAttrs() throws IOException @@ -294,48 +277,21 @@ public AttributeTable getAuthAttrs() /** * return a table of the unauthenticated attributes indexed by * the OID of the attribute. - * @exception java.io.IOException + * + * @throws java.io.IOException */ public AttributeTable getUnauthAttrs() throws IOException { if (unauthAttrs == null && unauthAttrNotRead) { - ASN1SetParser set = authData.getUnauthAttrs(); - unauthAttrNotRead = false; - - if (set != null) - { - ASN1EncodableVector v = new ASN1EncodableVector(); - ASN1Encodable o; - - while ((o = set.readObject()) != null) - { - ASN1SequenceParser seq = (ASN1SequenceParser)o; - - v.add(seq.toASN1Primitive()); - } - - unauthAttrs = new AttributeTable(new DERSet(v)); - } + unauthAttrs = CMSUtils.getAttributesTable(authData.getUnauthAttrs()); } return unauthAttrs; } - private byte[] encodeObj( - ASN1Encodable obj) - throws IOException - { - if (obj != null) - { - return obj.toASN1Primitive().getEncoded(); - } - - return null; - } - /** * This will only be valid after the content has been read. * diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java index 16c4334d4b..93f56c197d 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Collections; -import java.util.Iterator; import java.util.Map; import org.bouncycastle.asn1.ASN1EncodableVector; @@ -12,7 +11,6 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BERSequenceGenerator; -import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; @@ -139,14 +137,7 @@ public OutputStream open( try { - ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); - - for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext();) - { - RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); - - recipientInfos.add(recipient.generate(macCalculator.getKey())); - } + ASN1EncodableVector recipientInfos = CMSUtils.getRecipentInfos(macCalculator.getKey(), recipientInfoGenerators); // // ContentInfo @@ -162,19 +153,9 @@ public OutputStream open( authGen.addObject(new ASN1Integer(AuthenticatedData.calculateVersion(originatorInfo))); - if (originatorInfo != null) - { - authGen.addObject(new DERTaggedObject(false, 0, originatorInfo)); - } + CMSUtils.addOriginatorInfoToGenerator(authGen, originatorInfo); - if (berEncodeRecipientSet) - { - authGen.getRawOutputStream().write(new BERSet(recipientInfos).getEncoded()); - } - else - { - authGen.getRawOutputStream().write(new DERSet(recipientInfos).getEncoded()); - } + CMSUtils.addRecipientInfosToGenerator(recipientInfos, authGen, berEncodeRecipientSet); AlgorithmIdentifier macAlgId = macCalculator.getAlgorithmIdentifier(); @@ -297,10 +278,7 @@ public void close() envGen.addObject(new DEROctetString(macCalculator.getMac())); - if (unauthGen != null) - { - envGen.addObject(new DERTaggedObject(false, 3, new BERSet(unauthGen.getAttributes(parameters).toASN1EncodableVector()))); - } + CMSUtils.addAttriSetToGenerator(envGen, unauthGen, 3 , parameters); envGen.close(); cGen.close(); diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedDataGenerator.java index cdb800b0ca..dac06a1732 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedDataGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedDataGenerator.java @@ -3,13 +3,10 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.util.Collections; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BEROctetString; -import org.bouncycastle.asn1.BERSet; -import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; @@ -73,18 +70,12 @@ private CMSEncryptedData doGenerate( encContent = new BEROctetString(encryptedContent); - EncryptedContentInfo eci = new EncryptedContentInfo( + EncryptedContentInfo eci = CMSUtils.getEncryptedContentInfo( content.getContentType(), encAlgId, - encContent); + encryptedContent); - ASN1Set unprotectedAttrSet = null; - if (unprotectedAttributeGenerator != null) - { - AttributeTable attrTable = unprotectedAttributeGenerator.getAttributes(Collections.EMPTY_MAP); - - unprotectedAttrSet = new BERSet(attrTable.toASN1EncodableVector()); - } + ASN1Set unprotectedAttrSet = CMSUtils.getAttrBERSet(unprotectedAttributeGenerator); ContentInfo contentInfo = new ContentInfo( CMSObjectIdentifiers.encryptedData, diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedData.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedData.java index 0baed09f0e..189ed242a9 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedData.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedData.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.io.InputStream; -import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.ContentInfo; @@ -90,7 +89,7 @@ public CMSEnvelopedData( EncryptedContentInfo encInfo = envData.getEncryptedContentInfo(); this.encAlg = encInfo.getContentEncryptionAlgorithm(); CMSReadable readable = new CMSProcessableByteArray(encInfo.getEncryptedContent().getOctets()); - CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSEnvelopedSecureReadable( + CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSAuthEnveSecureReadable( this.encAlg, encInfo.getContentType(), readable); // @@ -111,18 +110,6 @@ public CMSEnvelopedData( } } - private byte[] encodeObj( - ASN1Encodable obj) - throws IOException - { - if (obj != null) - { - return obj.toASN1Primitive().getEncoded(); - } - - return null; - } - /** * Return the originator information associated with this message if present. * @@ -159,7 +146,7 @@ public byte[] getEncryptionAlgParams() { try { - return encodeObj(encAlg.getParameters()); + return CMSUtils.encodeObj(encAlg.getParameters()); } catch (Exception e) { diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java index 84dad0155a..24c925a650 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java @@ -3,22 +3,14 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.util.Collections; -import java.util.Iterator; import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; -import org.bouncycastle.asn1.BEROctetString; -import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DERSet; -import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; import org.bouncycastle.asn1.cms.EnvelopedData; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputAEADEncryptor; import org.bouncycastle.operator.OutputEncryptor; @@ -56,9 +48,7 @@ private CMSEnvelopedData doGenerate( OutputEncryptor contentEncryptor) throws CMSException { - ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); - AlgorithmIdentifier encAlgId; - ASN1OctetString encContent; + ASN1EncodableVector recipientInfos = CMSUtils.getRecipentInfos(contentEncryptor.getKey(), recipientInfoGenerators); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); @@ -84,35 +74,13 @@ private CMSEnvelopedData doGenerate( byte[] encryptedContent = bOut.toByteArray(); - encAlgId = contentEncryptor.getAlgorithmIdentifier(); + EncryptedContentInfo eci = CMSUtils.getEncryptedContentInfo(content, contentEncryptor, encryptedContent); - encContent = new BEROctetString(encryptedContent); - - GenericKey encKey = contentEncryptor.getKey(); - - for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext();) - { - RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); - - recipientInfos.add(recipient.generate(encKey)); - } - - EncryptedContentInfo eci = new EncryptedContentInfo( - content.getContentType(), - encAlgId, - encContent); - - ASN1Set unprotectedAttrSet = null; - if (unprotectedAttributeGenerator != null) - { - AttributeTable attrTable = unprotectedAttributeGenerator.getAttributes(Collections.EMPTY_MAP); - - unprotectedAttrSet = new BERSet(attrTable.toASN1EncodableVector()); - } + ASN1Set unprotectedAttrSet = CMSUtils.getAttrBERSet(unprotectedAttributeGenerator); ContentInfo contentInfo = new ContentInfo( - CMSObjectIdentifiers.envelopedData, - new EnvelopedData(originatorInfo, new DERSet(recipientInfos), eci, unprotectedAttrSet)); + CMSObjectIdentifiers.envelopedData, + new EnvelopedData(originatorInfo, new DERSet(recipientInfos), eci, unprotectedAttrSet)); return new CMSEnvelopedData(contentInfo); } diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataParser.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataParser.java index dfb53de26f..c288452b40 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataParser.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataParser.java @@ -4,14 +4,10 @@ import java.io.IOException; import java.io.InputStream; -import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1OctetStringParser; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1Set; -import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.BERTags; -import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.EncryptedContentInfoParser; import org.bouncycastle.asn1.cms.EnvelopedDataParser; @@ -99,7 +95,7 @@ public CMSEnvelopedDataParser( this.encAlg = encInfo.getContentEncryptionAlgorithm(); CMSReadable readable = new CMSProcessableInputStream( ((ASN1OctetStringParser)encInfo.getEncryptedContent(BERTags.OCTET_STRING)).getOctetStream()); - CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSEnvelopedSecureReadable( + CMSSecureReadable secureReadable = new CMSEnvelopedHelper.CMSAuthEnveSecureReadable( this.encAlg, encInfo.getContentType(), readable); // @@ -125,7 +121,7 @@ public byte[] getEncryptionAlgParams() { try { - return encodeObj(encAlg.getParameters()); + return CMSUtils.encodeObj(encAlg.getParameters()); } catch (Exception e) { @@ -171,38 +167,10 @@ public AttributeTable getUnprotectedAttributes() { if (unprotectedAttributes == null && attrNotRead) { - ASN1SetParser set = envelopedData.getUnprotectedAttrs(); - attrNotRead = false; - - if (set != null) - { - ASN1EncodableVector v = new ASN1EncodableVector(); - ASN1Encodable o; - - while ((o = set.readObject()) != null) - { - ASN1SequenceParser seq = (ASN1SequenceParser)o; - - v.add(seq.toASN1Primitive()); - } - - unprotectedAttributes = new AttributeTable(new DERSet(v)); - } + unprotectedAttributes = CMSUtils.getAttributesTable(envelopedData.getUnprotectedAttrs()); } return unprotectedAttributes; } - - private byte[] encodeObj( - ASN1Encodable obj) - throws IOException - { - if (obj != null) - { - return obj.toASN1Primitive().getEncoded(); - } - - return null; - } } diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java index d9651f5da8..0dc648160a 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java @@ -3,22 +3,15 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Collections; -import java.util.Iterator; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.BERSequenceGenerator; -import org.bouncycastle.asn1.BERSet; -import org.bouncycastle.asn1.DERSet; -import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DLSet; -import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.EnvelopedData; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.OutputAEADEncryptor; import org.bouncycastle.operator.OutputEncryptor; @@ -32,12 +25,12 @@ * edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("BC")); * * ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - * + * * OutputStream out = edGen.open( * bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC) * .setProvider("BC").build()); * out.write(data); - * + * * out.close(); *
      */ @@ -56,7 +49,7 @@ public CMSEnvelopedDataStreamGenerator() /** * Set the underlying string size for encapsulated data - * + * * @param bufferSize length of octet strings to buffer the data. */ public void setBufferSize( @@ -90,16 +83,7 @@ private OutputStream doOpen( OutputEncryptor encryptor) throws IOException, CMSException { - ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); - GenericKey encKey = encryptor.getKey(); - Iterator it = recipientInfoGenerators.iterator(); - - while (it.hasNext()) - { - RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); - - recipientInfos.add(recipient.generate(encKey)); - } + ASN1EncodableVector recipientInfos = CMSUtils.getRecipentInfos(encryptor.getKey(), recipientInfoGenerators); return open(dataType, out, recipientInfos, encryptor); } @@ -125,19 +109,9 @@ protected OutputStream open( envGen.addObject(getVersion(recipientInfos)); - if (originatorInfo != null) - { - envGen.addObject(new DERTaggedObject(false, 0, originatorInfo)); - } + CMSUtils.addOriginatorInfoToGenerator(envGen, originatorInfo); - if (_berEncodeRecipientSet) - { - envGen.getRawOutputStream().write(new BERSet(recipientInfos).getEncoded()); - } - else - { - envGen.getRawOutputStream().write(new DERSet(recipientInfos).getEncoded()); - } + CMSUtils.addRecipientInfosToGenerator(recipientInfos, envGen, _berEncodeRecipientSet); BERSequenceGenerator eiGen = new BERSequenceGenerator(envGen.getRawOutputStream()); @@ -161,49 +135,7 @@ protected OutputStream open( { try { - // - // ContentInfo - // - BERSequenceGenerator cGen = new BERSequenceGenerator(out); - - cGen.addObject(CMSObjectIdentifiers.envelopedData); - - // - // Encrypted Data - // - BERSequenceGenerator envGen = new BERSequenceGenerator(cGen.getRawOutputStream(), 0, true); - - ASN1Set recipients; - if (_berEncodeRecipientSet) - { - recipients = new BERSet(recipientInfos); - } - else - { - recipients = new DERSet(recipientInfos); - } - - envGen.addObject(getVersion(recipientInfos)); - - if (originatorInfo != null) - { - envGen.addObject(new DERTaggedObject(false, 0, originatorInfo)); - } - - envGen.getRawOutputStream().write(recipients.getEncoded()); - - BERSequenceGenerator eiGen = new BERSequenceGenerator(envGen.getRawOutputStream()); - - eiGen.addObject(CMSObjectIdentifiers.data); - - AlgorithmIdentifier encAlgId = encryptor.getAlgorithmIdentifier(); - - eiGen.getRawOutputStream().write(encAlgId.getEncoded()); - - OutputStream octetStream = CMSUtils.createBEROctetOutputStream( - eiGen.getRawOutputStream(), 0, false, _bufferSize); - - return new CmsEnvelopedDataOutputStream(encryptor, octetStream, cGen, envGen, eiGen); + return open(CMSObjectIdentifiers.data, out, recipientInfos, encryptor); } catch (IOException e) { @@ -246,7 +178,7 @@ private class CmsEnvelopedDataOutputStream private BERSequenceGenerator _cGen; private BERSequenceGenerator _envGen; private BERSequenceGenerator _eiGen; - + public CmsEnvelopedDataOutputStream( OutputEncryptor encryptor, OutputStream octetStream, @@ -261,14 +193,14 @@ public CmsEnvelopedDataOutputStream( _envGen = envGen; _eiGen = eiGen; } - + public void write( int b) throws IOException { _cOut.write(b); } - + public void write( byte[] bytes, int off, @@ -277,14 +209,14 @@ public void write( { _cOut.write(bytes, off, len); } - + public void write( byte[] bytes) throws IOException { _cOut.write(bytes); } - + public void close() throws IOException { @@ -297,15 +229,8 @@ public void close() } _eiGen.close(); - if (unprotectedAttributeGenerator != null) - { - AttributeTable attrTable = unprotectedAttributeGenerator.getAttributes(Collections.EMPTY_MAP); - - ASN1Set unprotectedAttrs = new BERSet(attrTable.toASN1EncodableVector()); + CMSUtils.addAttriSetToGenerator(_envGen, unprotectedAttributeGenerator, 1, Collections.EMPTY_MAP); - _envGen.addObject(new DERTaggedObject(false, 1, unprotectedAttrs)); - } - _envGen.close(); _cGen.close(); } diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedGenerator.java index efad262dbb..7f88be5c8d 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedGenerator.java @@ -5,9 +5,11 @@ import org.bouncycastle.asn1.cms.OriginatorInfo; import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; +import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.sec.SECObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; /** @@ -17,8 +19,8 @@ public class CMSEnvelopedGenerator { public static final String DES_EDE3_CBC = PKCSObjectIdentifiers.des_EDE3_CBC.getId(); public static final String RC2_CBC = PKCSObjectIdentifiers.RC2_CBC.getId(); - public static final String IDEA_CBC = "1.3.6.1.4.1.188.7.1.1.2"; - public static final String CAST5_CBC = "1.2.840.113533.7.66.10"; + public static final String IDEA_CBC = MiscObjectIdentifiers.as_sys_sec_alg_ideaCBC.getId(); + public static final String CAST5_CBC = MiscObjectIdentifiers.cast5CBC.getId(); public static final String AES128_CBC = NISTObjectIdentifiers.id_aes128_CBC.getId(); public static final String AES192_CBC = NISTObjectIdentifiers.id_aes192_CBC.getId(); public static final String AES256_CBC = NISTObjectIdentifiers.id_aes256_CBC.getId(); @@ -38,6 +40,10 @@ public class CMSEnvelopedGenerator public static final String ECDH_SHA1KDF = X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme.getId(); public static final String ECMQV_SHA1KDF = X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme.getId(); + public static final String ECMQV_SHA224KDF = SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme.getId(); + public static final String ECMQV_SHA256KDF = SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme.getId(); + public static final String ECMQV_SHA384KDF = SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme.getId(); + public static final String ECMQV_SHA512KDF = SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme.getId(); final List recipientInfoGenerators = new ArrayList(); diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedHelper.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedHelper.java index fd4d8b2f6a..05ada70595 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedHelper.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedHelper.java @@ -24,31 +24,25 @@ class CMSEnvelopedHelper { static RecipientInformationStore buildRecipientInformationStore( ASN1Set recipientInfos, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable) - { - return buildRecipientInformationStore(recipientInfos, messageAlgorithm, secureReadable, null); - } - - static RecipientInformationStore buildRecipientInformationStore( - ASN1Set recipientInfos, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { List infos = new ArrayList(); for (int i = 0; i != recipientInfos.size(); i++) { RecipientInfo info = RecipientInfo.getInstance(recipientInfos.getObjectAt(i)); - readRecipientInfo(infos, info, messageAlgorithm, secureReadable, additionalData); + readRecipientInfo(infos, info, messageAlgorithm, secureReadable); } return new RecipientInformationStore(infos); } private static void readRecipientInfo( - List infos, RecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) + List infos, RecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable) { ASN1Encodable recipInfo = info.getInfo(); if (recipInfo instanceof KeyTransRecipientInfo) { infos.add(new KeyTransRecipientInformation( - (KeyTransRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); + (KeyTransRecipientInfo)recipInfo, messageAlgorithm, secureReadable)); } else if (recipInfo instanceof OtherRecipientInfo) { @@ -56,36 +50,35 @@ else if (recipInfo instanceof OtherRecipientInfo) if (CMSObjectIdentifiers.id_ori_kem.equals(otherRecipientInfo.getType())) { infos.add(new KEMRecipientInformation( - KEMRecipientInfo.getInstance(otherRecipientInfo.getValue()), messageAlgorithm, secureReadable, additionalData)); + KEMRecipientInfo.getInstance(otherRecipientInfo.getValue()), messageAlgorithm, secureReadable)); } } else if (recipInfo instanceof KEKRecipientInfo) { infos.add(new KEKRecipientInformation( - (KEKRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); + (KEKRecipientInfo)recipInfo, messageAlgorithm, secureReadable)); } else if (recipInfo instanceof KeyAgreeRecipientInfo) { KeyAgreeRecipientInformation.readRecipientInfo(infos, - (KeyAgreeRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData); + (KeyAgreeRecipientInfo)recipInfo, messageAlgorithm, secureReadable); } else if (recipInfo instanceof PasswordRecipientInfo) { infos.add(new PasswordRecipientInformation( - (PasswordRecipientInfo)recipInfo, messageAlgorithm, secureReadable, additionalData)); + (PasswordRecipientInfo)recipInfo, messageAlgorithm, secureReadable)); } } - static class CMSDigestAuthenticatedSecureReadable + static abstract class CMSDefaultSecureReadable implements CMSSecureReadable { - private DigestCalculator digestCalculator; - private final ASN1ObjectIdentifier contentType; - private CMSReadable readable; + protected final ASN1ObjectIdentifier contentType; + protected CMSReadable readable; + protected ASN1Set authAttrSet; - public CMSDigestAuthenticatedSecureReadable(DigestCalculator digestCalculator, ASN1ObjectIdentifier contentType, CMSReadable readable) + CMSDefaultSecureReadable(ASN1ObjectIdentifier contentType, CMSReadable readable) { - this.digestCalculator = digestCalculator; this.contentType = contentType; this.readable = readable; } @@ -95,6 +88,31 @@ public ASN1ObjectIdentifier getContentType() return contentType; } + @Override + public ASN1Set getAuthAttrSet() + { + return authAttrSet; + } + + @Override + public void setAuthAttrSet(ASN1Set set) + { + authAttrSet = set; + } + + } + + static class CMSDigestAuthenticatedSecureReadable + extends CMSDefaultSecureReadable + { + private DigestCalculator digestCalculator; + + public CMSDigestAuthenticatedSecureReadable(DigestCalculator digestCalculator, ASN1ObjectIdentifier contentType, CMSReadable readable) + { + super(contentType, readable); + this.digestCalculator = digestCalculator; + } + public InputStream getInputStream() throws IOException, CMSException { @@ -117,7 +135,7 @@ public int read(byte[] inBuf, int inOff, int inLen) throws IOException { int n = in.read(inBuf, inOff, inLen); - + if (n >= 0) { digestCalculator.getOutputStream().write(inBuf, inOff, n); @@ -132,50 +150,23 @@ public byte[] getDigest() { return digestCalculator.getDigest(); } - } - - static class CMSAuthenticatedSecureReadable implements CMSSecureReadable - { - private AlgorithmIdentifier algorithm; - private final ASN1ObjectIdentifier contentType; - private CMSReadable readable; - - CMSAuthenticatedSecureReadable(AlgorithmIdentifier algorithm, ASN1ObjectIdentifier contentType, CMSReadable readable) - { - this.algorithm = algorithm; - this.contentType = contentType; - this.readable = readable; - } - public ASN1ObjectIdentifier getContentType() + @Override + public boolean hasAdditionalData() { - return contentType; + return true; } - - public InputStream getInputStream() - throws IOException, CMSException - { - return readable.getInputStream(); - } - } - static class CMSEnvelopedSecureReadable implements CMSSecureReadable + static class CMSAuthEnveSecureReadable + extends CMSDefaultSecureReadable { private AlgorithmIdentifier algorithm; - private final ASN1ObjectIdentifier contentType; - private CMSReadable readable; - CMSEnvelopedSecureReadable(AlgorithmIdentifier algorithm, ASN1ObjectIdentifier contentType, CMSReadable readable) + CMSAuthEnveSecureReadable(AlgorithmIdentifier algorithm, ASN1ObjectIdentifier contentType, CMSReadable readable) { + super(contentType, readable); this.algorithm = algorithm; - this.contentType = contentType; - this.readable = readable; - } - - public ASN1ObjectIdentifier getContentType() - { - return contentType; } public InputStream getInputStream() @@ -184,5 +175,10 @@ public InputStream getInputStream() return readable.getInputStream(); } + @Override + public boolean hasAdditionalData() + { + return false; + } } } diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSecureReadable.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSecureReadable.java index c99db78107..82f01ec796 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSSecureReadable.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSSecureReadable.java @@ -4,6 +4,7 @@ import java.io.InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Set; interface CMSSecureReadable { @@ -11,4 +12,10 @@ interface CMSSecureReadable InputStream getInputStream() throws IOException, CMSException; + + ASN1Set getAuthAttrSet(); + + void setAuthAttrSet(ASN1Set set); + + boolean hasAdditionalData(); } diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSecureReadableWithAAD.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSecureReadableWithAAD.java new file mode 100644 index 0000000000..0c50efc895 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSSecureReadableWithAAD.java @@ -0,0 +1,13 @@ +package org.bouncycastle.cms; + +import java.io.OutputStream; + +interface CMSSecureReadableWithAAD + extends CMSSecureReadable +{ + void setAADStream(OutputStream stream); + + OutputStream getAADStream(); + + byte[] getMAC(); +} diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java index fac07e0d24..4455bb8f9f 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java @@ -67,7 +67,8 @@ public class CMSSignedData implements Encodable { private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE; - private static final DefaultDigestAlgorithmIdentifierFinder dgstAlgFinder = new DefaultDigestAlgorithmIdentifierFinder(); + private static final DefaultDigestAlgorithmIdentifierFinder DIGEST_ALG_ID_FINDER = + new DefaultDigestAlgorithmIdentifierFinder(); SignedData signedData; ContentInfo contentInfo; @@ -342,7 +343,7 @@ public Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoForm */ public Set getDigestAlgorithmIDs() { - Set digests = new HashSet(signedData.getDigestAlgorithms().size()); + Set digests = new HashSet(); for (Enumeration en = signedData.getDigestAlgorithms().getObjects(); en.hasMoreElements(); ) { @@ -483,18 +484,31 @@ private boolean verifyCounterSignature(SignerInformation counterSigner, SignerIn /** * Return a new CMSSignedData which guarantees to have the passed in digestAlgorithm - * in it. + * in it. Uses the current DigestAlgorithmIdentifierFinder for creating the digest sets. * * @param signedData the signed data object to be used as a base. * @param digestAlgorithm the digest algorithm to be added to the signed data. * @return a new signed data object. */ - public static CMSSignedData addDigestAlgorithm( - CMSSignedData signedData, - AlgorithmIdentifier digestAlgorithm) + public static CMSSignedData addDigestAlgorithm(CMSSignedData signedData, AlgorithmIdentifier digestAlgorithm) + { + return addDigestAlgorithm(signedData, digestAlgorithm, DIGEST_ALG_ID_FINDER); + } + + /** + * Return a new CMSSignedData which guarantees to have the passed in digestAlgorithm + * in it. Uses the passed in DigestAlgorithmIdentifierFinder for creating the digest sets. + * + * @param signedData the signed data object to be used as a base. + * @param digestAlgorithm the digest algorithm to be added to the signed data. + * @param digestAlgIdFinder the digest algorithmID map to generate the digest set with. + * @return a new signed data object. + */ + public static CMSSignedData addDigestAlgorithm(CMSSignedData signedData, AlgorithmIdentifier digestAlgorithm, + DigestAlgorithmIdentifierFinder digestAlgIdFinder) { Set digestAlgorithms = signedData.getDigestAlgorithmIDs(); - AlgorithmIdentifier digestAlg = CMSSignedHelper.INSTANCE.fixDigestAlgID(digestAlgorithm, dgstAlgFinder); + AlgorithmIdentifier digestAlg = HELPER.fixDigestAlgID(digestAlgorithm, digestAlgIdFinder); // // if the algorithm is already present there is no need to add it. @@ -517,20 +531,19 @@ public static CMSSignedData addDigestAlgorithm( Iterator it = digestAlgorithms.iterator(); while (it.hasNext()) { - digestAlgs.add(CMSSignedHelper.INSTANCE.fixDigestAlgID((AlgorithmIdentifier)it.next(), dgstAlgFinder)); + digestAlgs.add(HELPER.fixDigestAlgID((AlgorithmIdentifier)it.next(), digestAlgIdFinder)); } digestAlgs.add(digestAlg); - ASN1Set digests = CMSUtils.convertToDlSet(digestAlgs); + ASN1Set digestSet = CMSUtils.convertToDlSet(digestAlgs); ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive(); - ASN1EncodableVector vec = new ASN1EncodableVector(); - // // signers are the last item in the sequence. // + ASN1EncodableVector vec = new ASN1EncodableVector(sD.size()); vec.add(sD.getObjectAt(0)); // version - vec.add(digests); + vec.add(digestSet); for (int i = 2; i != sD.size(); i++) { @@ -550,7 +563,7 @@ public static CMSSignedData addDigestAlgorithm( /** * Replace the SignerInformation store associated with this * CMSSignedData object with the new one passed in using the current - * digestAlgorithmIdentifierFinder for creating the digest sets. You would + * DigestAlgorithmIdentifierFinder for creating the digest sets. You would * probably only want to do this if you wanted to change the unsigned * attributes associated with a signer, or perhaps delete one. * @@ -558,17 +571,15 @@ public static CMSSignedData addDigestAlgorithm( * @param signerInformationStore the new signer information store to use. * @return a new signed data object. */ - public static CMSSignedData replaceSigners( - CMSSignedData signedData, - SignerInformationStore signerInformationStore) + public static CMSSignedData replaceSigners(CMSSignedData signedData, SignerInformationStore signerInformationStore) { - return replaceSigners(signedData, signerInformationStore, dgstAlgFinder); + return replaceSigners(signedData, signerInformationStore, DIGEST_ALG_ID_FINDER); } /** * Replace the SignerInformation store associated with this * CMSSignedData object with the new one passed in using the passed in - * digestAlgorithmIdentifierFinder for creating the digest sets. You would + * DigestAlgorithmIdentifierFinder for creating the digest sets. You would * probably only want to do this if you wanted to change the unsigned * attributes associated with a signer, or perhaps delete one. * @@ -577,9 +588,7 @@ public static CMSSignedData replaceSigners( * @param digestAlgIdFinder the digest algorithmID map to generate the digest set with. * @return a new signed data object. */ - public static CMSSignedData replaceSigners( - CMSSignedData signedData, - SignerInformationStore signerInformationStore, + public static CMSSignedData replaceSigners(CMSSignedData signedData, SignerInformationStore signerInformationStore, DigestAlgorithmIdentifierFinder digestAlgIdFinder) { // @@ -596,9 +605,11 @@ public static CMSSignedData replaceSigners( // replace the signers in the SignedData object // Set digestAlgs = new HashSet(); - ASN1EncodableVector vec = new ASN1EncodableVector(); - Iterator it = signerInformationStore.getSigners().iterator(); + Collection signers = signerInformationStore.getSigners(); + ASN1EncodableVector vec = new ASN1EncodableVector(signers.size()); + + Iterator it = signers.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); @@ -606,24 +617,23 @@ public static CMSSignedData replaceSigners( vec.add(signer.toASN1Structure()); } - ASN1Set digests = CMSUtils.convertToDlSet(digestAlgs); - ASN1Set signers = new DLSet(vec); + ASN1Set digestSet = CMSUtils.convertToDlSet(digestAlgs); + ASN1Set signerSet = new DLSet(vec); ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive(); - vec = new ASN1EncodableVector(); - // // signers are the last item in the sequence. // + vec = new ASN1EncodableVector(sD.size()); vec.add(sD.getObjectAt(0)); // version - vec.add(digests); + vec.add(digestSet); for (int i = 2; i != sD.size() - 1; i++) { vec.add(sD.getObjectAt(i)); } - vec.add(signers); + vec.add(signerSet); cms.signedData = SignedData.getInstance(new BERSequence(vec)); diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataGenerator.java index ab63c1d2d6..1bf5d393f2 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataGenerator.java @@ -217,33 +217,9 @@ public CMSSignedData generate( } } - ASN1Set certificates = null; + ASN1Set certificates = createSetFromList(certs, isDefiniteLength); - if (certs.size() != 0) - { - if (isDefiniteLength) - { - certificates = CMSUtils.createDlSetFromList(certs); - } - else - { - certificates = CMSUtils.createBerSetFromList(certs); - } - } - - ASN1Set certrevlist = null; - - if (crls.size() != 0) - { - if (isDefiniteLength) - { - certrevlist = CMSUtils.createDlSetFromList(crls); - } - else - { - certrevlist = CMSUtils.createBerSetFromList(crls); - } - } + ASN1Set certrevlist = createSetFromList(crls, isDefiniteLength); ContentInfo encInfo = new ContentInfo(contentTypeOID, octs); @@ -260,6 +236,15 @@ public CMSSignedData generate( return new CMSSignedData(content, contentInfo); } + private static ASN1Set createSetFromList(List list, boolean isDefiniteLength) + { + if(list.size()!=0) + { + return isDefiniteLength ? CMSUtils.createDlSetFromList(list) : CMSUtils.createBerSetFromList(list); + } + return null; + } + /** * generate a set of one or more SignerInformation objects representing counter signatures on * the passed in SignerInformation object. diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataParser.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataParser.java index dd0ca7f897..56acf89016 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataParser.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataParser.java @@ -443,7 +443,7 @@ public static OutputStream replaceSigners( for (Iterator it = signerInformationStore.getSigners().iterator(); it.hasNext();) { SignerInformation signer = (SignerInformation)it.next(); - digestAlgs.add(CMSSignedHelper.INSTANCE.fixDigestAlgID(signer.getDigestAlgorithmID(), dgstAlgFinder)); + digestAlgs.add(HELPER.fixDigestAlgID(signer.getDigestAlgorithmID(), dgstAlgFinder)); } sigGen.getRawOutputStream().write(new DERSet(digestAlgs).getEncoded()); diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java index 8bf69b1e89..36b4c4529f 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java @@ -56,7 +56,7 @@ public class CMSSignedGenerator public static final String ENCRYPTION_ECGOST3410_2012_256 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256.getId(); public static final String ENCRYPTION_ECGOST3410_2012_512 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512.getId(); - private static final String ENCRYPTION_ECDSA_WITH_SHA1 = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); + private static final String ENCRYPTION_ECDSA_WITH_SHA1 = ENCRYPTION_ECDSA; private static final String ENCRYPTION_ECDSA_WITH_SHA224 = X9ObjectIdentifiers.ecdsa_with_SHA224.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA256 = X9ObjectIdentifiers.ecdsa_with_SHA256.getId(); private static final String ENCRYPTION_ECDSA_WITH_SHA384 = X9ObjectIdentifiers.ecdsa_with_SHA384.getId(); @@ -69,7 +69,7 @@ public class CMSSignedGenerator { NO_PARAMS.add(ENCRYPTION_DSA); NO_PARAMS.add(ENCRYPTION_ECDSA); - NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA1); +// NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA1); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA224); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA256); NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA384); diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java index 8de3d8bc61..e9b0274276 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java @@ -12,6 +12,7 @@ import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; @@ -190,7 +191,7 @@ Store getAttributeCertificates(ASN1Set certSet) // other [3] IMPLICIT OtherCertificateFormat } if (tObj.getTagNo() == 1 || tObj.getTagNo() == 2) { - certList.add(new X509AttributeCertificateHolder(AttributeCertificate.getInstance(tObj.getObject()))); + certList.add(new X509AttributeCertificateHolder(AttributeCertificate.getInstance(tObj.getBaseUniversal(false, BERTags.SEQUENCE)))); } } } diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSUtils.java b/pkix/src/main/java/org/bouncycastle/cms/CMSUtils.java index bb74c5d9e5..80cdb1fa3b 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSUtils.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSUtils.java @@ -5,25 +5,36 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.ASN1SetParser; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.BEROctetStringGenerator; +import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DLSet; +import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; +import org.bouncycastle.asn1.cms.EncryptedContentInfo; +import org.bouncycastle.asn1.cms.OriginatorInfo; import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.ocsp.OCSPResponse; @@ -39,6 +50,9 @@ import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestCalculator; +import org.bouncycastle.operator.GenericKey; +import org.bouncycastle.operator.OutputAEADEncryptor; +import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.util.Store; import org.bouncycastle.util.Strings; import org.bouncycastle.util.io.Streams; @@ -407,4 +421,123 @@ static OutputStream getSafeTeeOutputStream(OutputStream s1, : s2 == null ? getSafeOutputStream(s1) : new TeeOutputStream( s1, s2); } + + static EncryptedContentInfo getEncryptedContentInfo(CMSTypedData content, OutputEncryptor contentEncryptor, byte[] encryptedContent) + { + return getEncryptedContentInfo( + content.getContentType(), + contentEncryptor.getAlgorithmIdentifier(), + encryptedContent); + } + + static EncryptedContentInfo getEncryptedContentInfo(ASN1ObjectIdentifier encryptedContentType, AlgorithmIdentifier encAlgId, byte[] encryptedContent) + { + ASN1OctetString encContent = new BEROctetString(encryptedContent); + + return new EncryptedContentInfo( + encryptedContentType, + encAlgId, + encContent); + } + + static ASN1EncodableVector getRecipentInfos(GenericKey encKey, List recipientInfoGenerators) + throws CMSException + { + ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); + Iterator it = recipientInfoGenerators.iterator(); + + while (it.hasNext()) + { + RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); + + recipientInfos.add(recipient.generate(encKey)); + } + return recipientInfos; + } + + static void addRecipientInfosToGenerator(ASN1EncodableVector recipientInfos, BERSequenceGenerator authGen, boolean berEncodeRecipientSet) + throws IOException + { + if (berEncodeRecipientSet) + { + authGen.getRawOutputStream().write(new BERSet(recipientInfos).getEncoded()); + } + else + { + authGen.getRawOutputStream().write(new DERSet(recipientInfos).getEncoded()); + } + } + + static void addOriginatorInfoToGenerator(BERSequenceGenerator envGen, OriginatorInfo originatorInfo) + throws IOException + { + if (originatorInfo != null) + { + envGen.addObject(new DERTaggedObject(false, 0, originatorInfo)); + } + } + + static void addAttriSetToGenerator(BERSequenceGenerator gen, CMSAttributeTableGenerator attriGen, int tagNo, Map parameters) + throws IOException + { + if (attriGen != null) + { + gen.addObject(new DERTaggedObject(false, tagNo, new BERSet(attriGen.getAttributes(parameters).toASN1EncodableVector()))); + } + } + + static ASN1Set processAuthAttrSet(CMSAttributeTableGenerator authAttrsGenerator, OutputAEADEncryptor encryptor) + throws IOException + { + ASN1Set authenticatedAttrSet = null; + if (authAttrsGenerator != null) + { + AttributeTable attrTable = authAttrsGenerator.getAttributes(Collections.EMPTY_MAP); + + authenticatedAttrSet = new DERSet(attrTable.toASN1EncodableVector()); + encryptor.getAADStream().write(authenticatedAttrSet.getEncoded(ASN1Encoding.DER)); + } + return authenticatedAttrSet; + } + + static AttributeTable getAttributesTable(ASN1SetParser set) + throws IOException + { + if (set != null) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + ASN1Encodable o; + + while ((o = set.readObject()) != null) + { + ASN1SequenceParser seq = (ASN1SequenceParser)o; + + v.add(seq.toASN1Primitive()); + } + return new AttributeTable(new DERSet(v)); + } + return null; + } + + static ASN1Set getAttrDLSet(CMSAttributeTableGenerator gen) + { + return (gen != null) ? new DLSet(gen.getAttributes(Collections.EMPTY_MAP).toASN1EncodableVector()) : null; + } + + static ASN1Set getAttrBERSet(CMSAttributeTableGenerator gen) + { + return (gen != null) ? new BERSet(gen.getAttributes(Collections.EMPTY_MAP).toASN1EncodableVector()) : null; + } + + static byte[] encodeObj( + ASN1Encodable obj) + throws IOException + { + if (obj != null) + { + return obj.toASN1Primitive().getEncoded(); + } + + return null; + } } diff --git a/pkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java index bf60a29227..ba4d605d7f 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java @@ -136,6 +136,7 @@ public DefaultCMSSignatureAlgorithmNameGenerator() encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3410"); encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "ECGOST3410-2012-256"); encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "ECGOST3410-2012-512"); + encryptionAlgs.put(X9ObjectIdentifiers.id_ecPublicKey, "ECDSA"); digestAlgs.put(PKCSObjectIdentifiers.md2, "MD2"); digestAlgs.put(PKCSObjectIdentifiers.md4, "MD4"); @@ -169,9 +170,28 @@ public DefaultCMSSignatureAlgorithmNameGenerator() simpleAlgs.put(MiscObjectIdentifiers.id_alg_composite, "COMPOSITE"); simpleAlgs.put(BCObjectIdentifiers.falcon_512, "Falcon-512"); simpleAlgs.put(BCObjectIdentifiers.falcon_1024, "Falcon-1024"); - simpleAlgs.put(BCObjectIdentifiers.dilithium2, "Dilithium2"); - simpleAlgs.put(BCObjectIdentifiers.dilithium3, "Dilithium3"); - simpleAlgs.put(BCObjectIdentifiers.dilithium5, "Dilithium5"); + simpleAlgs.put(NISTObjectIdentifiers.id_ml_dsa_44, "Dilithium2"); + simpleAlgs.put(NISTObjectIdentifiers.id_ml_dsa_65, "Dilithium3"); + simpleAlgs.put(NISTObjectIdentifiers.id_ml_dsa_87, "Dilithium5"); + simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_128s, "SPHINCS+-SHA2-128s"); + simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_128f, "SPHINCS+-SHA2-128f"); + simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_192s, "SPHINCS+-SHA2-192s"); + simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_192f, "SPHINCS+-SHA2-192f"); + simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_256s, "SPHINCS+-SHA2-256s"); + simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_256f, "SPHINCS+-SHA2-256f"); + simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_128s, "SPHINCS+-SHAKE-128s"); + simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_128f, "SPHINCS+-SHAKE-128f"); + simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_192s, "SPHINCS+-SHAKE-192s"); + simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_192f, "SPHINCS+-SHAKE-192f"); + simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_256s, "SPHINCS+-SHAKE-256s"); + simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_256f, "SPHINCS+-SHAKE-256f"); + + simpleAlgs.put(NISTObjectIdentifiers.id_slh_dsa_sha2_128s, "SLH-DSA-SHA2-128S"); + simpleAlgs.put(NISTObjectIdentifiers.id_slh_dsa_sha2_128f, "SLH-DSA-SHA2-128F"); + simpleAlgs.put(NISTObjectIdentifiers.id_slh_dsa_sha2_192s, "SLH-DSA-SHA2-192S"); + simpleAlgs.put(NISTObjectIdentifiers.id_slh_dsa_sha2_192f, "SLH-DSA-SHA2-192F"); + simpleAlgs.put(NISTObjectIdentifiers.id_slh_dsa_sha2_256s, "SLH-DSA-SHA2-256S"); + simpleAlgs.put(NISTObjectIdentifiers.id_slh_dsa_sha2_256s, "SLH-DSA-SHA2-256F"); simpleAlgs.put(BCObjectIdentifiers.picnic_signature, "Picnic"); } diff --git a/pkix/src/main/java/org/bouncycastle/cms/InputStreamWithMAC.java b/pkix/src/main/java/org/bouncycastle/cms/InputStreamWithMAC.java new file mode 100644 index 0000000000..81f9f85006 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/cms/InputStreamWithMAC.java @@ -0,0 +1,131 @@ +package org.bouncycastle.cms; + +import java.io.IOException; +import java.io.InputStream; + +import org.bouncycastle.util.Arrays; + +public final class InputStreamWithMAC + extends InputStream +{ + private final InputStream base; + private MACProvider macProvider; + private byte[] mac; + private boolean baseFinished; + private int index; + + InputStreamWithMAC(InputStream base, MACProvider macProvider) + { + this.base = base; + this.macProvider = macProvider; + + baseFinished = false; + index = 0; + } + + public InputStreamWithMAC(InputStream base, byte[] mac) + { + this.base = base; + this.mac = mac; + baseFinished = false; + index = 0; + } + + @Override + public int read() + throws IOException + { + int ch; + if (!baseFinished) + { + ch = base.read(); + if (ch < 0) + { + baseFinished = true; + if (macProvider != null) + { + macProvider.init(); + mac = macProvider.getMAC(); + } + return mac[index++] & 0xFF; + } + } + else + { + if (index >= mac.length) + { + return -1; + } + return mac[index++] & 0xFF; + } + return ch; + } + + public byte[] getMAC() + { + if (!baseFinished) + { + throw new IllegalStateException("input stream not fully processed"); + } + return Arrays.clone(mac); + } + + @Override + public int read(byte[] b, int off, int len) + throws IOException + { + if (b == null) + { + throw new NullPointerException("input array is null"); + } + if (off < 0 || b.length < off + len) + { + throw new IndexOutOfBoundsException("invalid off(" + off + ") and len(" + len + ")"); + } + int ch; + if (!baseFinished) + { + ch = base.read(b, off, len); + if (ch < 0) + { + baseFinished = true; + if (macProvider != null) + { + macProvider.init(); + mac = macProvider.getMAC(); + } + if (len >= mac.length) + { + System.arraycopy(mac, 0, b, off, mac.length); + index = mac.length; + return mac.length; + } + else + { + System.arraycopy(mac, 0, b, off, len); + index += len; + return len; + } + } + return ch; + } + else if (index < mac.length) + { + if (len >= mac.length - index) + { + System.arraycopy(mac, index, b, off, mac.length - index); + int tmp = mac.length - index; + index = mac.length; + return tmp; + } + else + { + System.arraycopy(mac, index, b, off, len); + index += len; + return len; + } + } + return -1; + } +} + diff --git a/pkix/src/main/java/org/bouncycastle/cms/KEKRecipientInformation.java b/pkix/src/main/java/org/bouncycastle/cms/KEKRecipientInformation.java index 62c6529442..151e8a70ac 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/KEKRecipientInformation.java +++ b/pkix/src/main/java/org/bouncycastle/cms/KEKRecipientInformation.java @@ -18,10 +18,9 @@ public class KEKRecipientInformation KEKRecipientInformation( KEKRecipientInfo info, AlgorithmIdentifier messageAlgorithm, - CMSSecureReadable secureReadable, - AuthAttributesProvider additionalData) + CMSSecureReadable secureReadable) { - super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable, additionalData); + super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable); this.info = info; diff --git a/pkix/src/main/java/org/bouncycastle/cms/KEMRecipientInformation.java b/pkix/src/main/java/org/bouncycastle/cms/KEMRecipientInformation.java index 76ad91dd7c..8a36dc8928 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/KEMRecipientInformation.java +++ b/pkix/src/main/java/org/bouncycastle/cms/KEMRecipientInformation.java @@ -14,10 +14,9 @@ public class KEMRecipientInformation KEMRecipientInformation( KEMRecipientInfo info, AlgorithmIdentifier messageAlgorithm, - CMSSecureReadable secureReadable, - AuthAttributesProvider additionalData) + CMSSecureReadable secureReadable) { - super(info.getKem(), messageAlgorithm, secureReadable, additionalData); + super(info.getKem(), messageAlgorithm, secureReadable); this.info = info; diff --git a/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInformation.java b/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInformation.java index b13e8a0562..ab3431f555 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInformation.java +++ b/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInformation.java @@ -28,7 +28,7 @@ public class KeyAgreeRecipientInformation private ASN1OctetString encryptedKey; static void readRecipientInfo(List infos, KeyAgreeRecipientInfo info, - AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) + AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable) { ASN1Sequence s = info.getRecipientEncryptedKeys(); @@ -56,7 +56,7 @@ static void readRecipientInfo(List infos, KeyAgreeRecipientInfo info, } infos.add(new KeyAgreeRecipientInformation(info, rid, id.getEncryptedKey(), messageAlgorithm, - secureReadable, additionalData)); + secureReadable)); } } @@ -65,10 +65,9 @@ static void readRecipientInfo(List infos, KeyAgreeRecipientInfo info, RecipientId rid, ASN1OctetString encryptedKey, AlgorithmIdentifier messageAlgorithm, - CMSSecureReadable secureReadable, - AuthAttributesProvider additionalData) + CMSSecureReadable secureReadable) { - super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable, additionalData); + super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable); this.info = info; this.rid = rid; @@ -131,11 +130,7 @@ private SubjectPublicKeyInfo getSenderPublicKeyInfo(AlgorithmIdentifier recKeyAl private SubjectPublicKeyInfo getPublicKeyInfoFromOriginatorPublicKey(AlgorithmIdentifier recKeyAlgId, OriginatorPublicKey originatorPublicKey) { - SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo( - recKeyAlgId, - originatorPublicKey.getPublicKey().getBytes()); - - return pubInfo; + return new SubjectPublicKeyInfo(recKeyAlgId, originatorPublicKey.getPublicKeyData()); } private SubjectPublicKeyInfo getPublicKeyInfoFromOriginatorId(OriginatorId origID) diff --git a/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientInformation.java b/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientInformation.java index d59f4b3e8b..649f1f21c8 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientInformation.java +++ b/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientInformation.java @@ -19,10 +19,9 @@ public class KeyTransRecipientInformation KeyTransRecipientInformation( KeyTransRecipientInfo info, AlgorithmIdentifier messageAlgorithm, - CMSSecureReadable secureReadable, - AuthAttributesProvider additionalData) + CMSSecureReadable secureReadable) { - super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable, additionalData); + super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable); this.info = info; diff --git a/pkix/src/main/java/org/bouncycastle/cms/MACProvider.java b/pkix/src/main/java/org/bouncycastle/cms/MACProvider.java new file mode 100644 index 0000000000..75bafe1ad0 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/cms/MACProvider.java @@ -0,0 +1,11 @@ +package org.bouncycastle.cms; + +import java.io.IOException; + +interface MACProvider +{ + byte[] getMAC(); + + void init() throws IOException; +} + diff --git a/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientInformation.java b/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientInformation.java index a12d8a7ccc..b0e29899be 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientInformation.java +++ b/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientInformation.java @@ -37,10 +37,9 @@ public class PasswordRecipientInformation PasswordRecipientInformation( PasswordRecipientInfo info, AlgorithmIdentifier messageAlgorithm, - CMSSecureReadable secureReadable, - AuthAttributesProvider additionalData) + CMSSecureReadable secureReadable) { - super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable, additionalData); + super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable); this.info = info; this.rid = new PasswordRecipientId(); diff --git a/pkix/src/main/java/org/bouncycastle/cms/RecipientInformation.java b/pkix/src/main/java/org/bouncycastle/cms/RecipientInformation.java index 888dfb3417..fac620cab5 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/RecipientInformation.java +++ b/pkix/src/main/java/org/bouncycastle/cms/RecipientInformation.java @@ -3,7 +3,6 @@ import java.io.ByteArrayInputStream; import java.io.IOException; -import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; @@ -12,25 +11,20 @@ public abstract class RecipientInformation { protected RecipientId rid; - protected AlgorithmIdentifier keyEncAlg; - protected AlgorithmIdentifier messageAlgorithm; - protected CMSSecureReadable secureReadable; - - private AuthAttributesProvider additionalData; - + protected AlgorithmIdentifier keyEncAlg; + protected AlgorithmIdentifier messageAlgorithm; + protected CMSSecureReadable secureReadable; private byte[] resultMac; - private RecipientOperator operator; + private RecipientOperator operator; RecipientInformation( AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier messageAlgorithm, - CMSSecureReadable secureReadable, - AuthAttributesProvider additionalData) + CMSSecureReadable secureReadable) { this.keyEncAlg = keyEncAlg; this.messageAlgorithm = messageAlgorithm; this.secureReadable = secureReadable; - this.additionalData = additionalData; } public RecipientId getRID() @@ -38,18 +32,6 @@ public RecipientId getRID() return rid; } - private byte[] encodeObj( - ASN1Encodable obj) - throws IOException - { - if (obj != null) - { - return obj.toASN1Primitive().getEncoded(); - } - - return null; - } - /** * Return the key encryption algorithm details for the key in this recipient. * @@ -80,7 +62,7 @@ public byte[] getKeyEncryptionAlgParams() { try { - return encodeObj(keyEncAlg.getParameters()); + return CMSUtils.encodeObj(keyEncAlg.getParameters()); } catch (Exception e) { @@ -100,7 +82,6 @@ public byte[] getContentDigest() { return ((CMSEnvelopedHelper.CMSDigestAuthenticatedSecureReadable)secureReadable).getDigest(); } - return null; } @@ -108,29 +89,25 @@ public byte[] getContentDigest() * Return the MAC calculated for the recipient. Note: this call is only meaningful once all * the content has been read. * - * @return byte array containing the mac. + * @return byte array containing the mac. */ public byte[] getMac() { if (resultMac == null) { - if (operator.isMacBased()) + if (operator.isMacBased() && secureReadable.hasAdditionalData()) { - if (additionalData != null) + try { - try - { - Streams.drain(operator.getInputStream(new ByteArrayInputStream(additionalData.getAuthAttributes().getEncoded(ASN1Encoding.DER)))); - } - catch (IOException e) - { - throw new IllegalStateException("unable to drain input: " + e.getMessage()); - } + Streams.drain(operator.getInputStream(new ByteArrayInputStream(secureReadable.getAuthAttrSet().getEncoded(ASN1Encoding.DER)))); + } + catch (IOException e) + { + throw new IllegalStateException("unable to drain input: " + e.getMessage()); } - resultMac = operator.getMac(); } + resultMac = operator.getMac(); } - return resultMac; } @@ -139,7 +116,7 @@ public byte[] getMac() * encryption/MAC key using the passed in Recipient. * * @param recipient recipient object to use to recover content encryption key - * @return the content inside the EnvelopedData this RecipientInformation is associated with. + * @return the content inside the EnvelopedData this RecipientInformation is associated with. * @throws CMSException if the content-encryption/MAC key cannot be recovered. */ public byte[] getContent( @@ -171,7 +148,7 @@ public ASN1ObjectIdentifier getContentType() * encryption/MAC key using the passed in Recipient. * * @param recipient recipient object to use to recover content encryption key - * @return the content inside the EnvelopedData this RecipientInformation is associated with. + * @return the content inside the EnvelopedData this RecipientInformation is associated with. * @throws CMSException if the content-encryption/MAC key cannot be recovered. */ public CMSTypedStream getContentStream(Recipient recipient) @@ -179,19 +156,13 @@ public CMSTypedStream getContentStream(Recipient recipient) { operator = getRecipientOperator(recipient); - if (additionalData != null) + if (operator.isAEADBased()) { - if (additionalData.isAead()) - { - // TODO: this needs to be done after reading the encrypted data - operator.getAADStream().write(additionalData.getAuthAttributes().getEncoded(ASN1Encoding.DER)); - - return new CMSTypedStream(secureReadable.getContentType(), operator.getInputStream(secureReadable.getInputStream())); - } - else - { - return new CMSTypedStream(secureReadable.getContentType(), secureReadable.getInputStream()); - } + ((CMSSecureReadableWithAAD)secureReadable).setAADStream(operator.getAADStream()); + } + else if (secureReadable.hasAdditionalData()) + { + return new CMSTypedStream(secureReadable.getContentType(), secureReadable.getInputStream()); } return new CMSTypedStream(secureReadable.getContentType(), operator.getInputStream(secureReadable.getInputStream())); diff --git a/pkix/src/main/java/org/bouncycastle/cms/RecipientOperator.java b/pkix/src/main/java/org/bouncycastle/cms/RecipientOperator.java index 407d5bceb6..3c51327f42 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/RecipientOperator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/RecipientOperator.java @@ -51,6 +51,14 @@ public boolean isMacBased() public byte[] getMac() { - return ((MacCalculator)operator).getMac(); + if (operator instanceof MacCalculator) + { + return ((MacCalculator)operator).getMac(); + } + else if (operator instanceof InputAEADDecryptor) + { + return ((InputAEADDecryptor)operator).getMAC(); + } + return null; } } diff --git a/pkix/src/main/java/org/bouncycastle/cms/SignerInformation.java b/pkix/src/main/java/org/bouncycastle/cms/SignerInformation.java index 59d4054eb2..b2451b5262 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/SignerInformation.java +++ b/pkix/src/main/java/org/bouncycastle/cms/SignerInformation.java @@ -7,7 +7,6 @@ import java.util.Iterator; import java.util.List; -import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; @@ -24,6 +23,8 @@ import org.bouncycastle.asn1.cms.SignerIdentifier; import org.bouncycastle.asn1.cms.SignerInfo; import org.bouncycastle.asn1.cms.Time; +import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.cert.X509CertificateHolder; @@ -138,18 +139,6 @@ public ASN1ObjectIdentifier getContentType() return this.contentType; } - private byte[] encodeObj( - ASN1Encodable obj) - throws IOException - { - if (obj != null) - { - return obj.toASN1Primitive().getEncoded(); - } - - return null; - } - public SignerId getSID() { return sid; @@ -183,7 +172,7 @@ public byte[] getDigestAlgParams() { try { - return encodeObj(digestAlgorithm.getParameters()); + return CMSUtils.encodeObj(digestAlgorithm.getParameters()); } catch (Exception e) { @@ -220,7 +209,7 @@ public byte[] getEncryptionAlgParams() { try { - return encodeObj(encryptionAlgorithm.getParameters()); + return CMSUtils.encodeObj(encryptionAlgorithm.getParameters()); } catch (Exception e) { @@ -353,11 +342,13 @@ private boolean doVerify( throws CMSException { String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID()); + AlgorithmIdentifier realDigestAlgorithm = signedAttributeSet != null ? + info.getDigestAlgorithm() : translateBrokenRSAPkcs7(encryptionAlgorithm, info.getDigestAlgorithm()); ContentVerifier contentVerifier; try { - contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, info.getDigestAlgorithm()); + contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, realDigestAlgorithm); } catch (OperatorCreationException e) { @@ -370,7 +361,7 @@ private boolean doVerify( if (resultDigest == null) { - DigestCalculator calc = verifier.getDigestCalculator(this.getDigestAlgorithmID()); + DigestCalculator calc = verifier.getDigestCalculator(realDigestAlgorithm); if (content != null) { OutputStream digOut = calc.getOutputStream(); @@ -460,7 +451,7 @@ else if (signedAttributeSet != null) if (encName.equals("RSA")) { - DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(digestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest); + DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(realDigestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest); return rawVerifier.verify(digInfo.getEncoded(ASN1Encoding.DER), this.getSignature()); } @@ -795,4 +786,19 @@ public static SignerInformation addCounterSigners( sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), new DERSet(v)), signerInformation.contentType, signerInformation.content, null); } + + private static AlgorithmIdentifier translateBrokenRSAPkcs7(AlgorithmIdentifier encryptionAlgorithm, AlgorithmIdentifier digestAlgorithm) + { + if (PKCSObjectIdentifiers.rsaEncryption.equals(encryptionAlgorithm.getAlgorithm())) + { + // Yes, some people really did this. + if (OIWObjectIdentifiers.sha1WithRSA.equals(digestAlgorithm.getAlgorithm()) + || PKCSObjectIdentifiers.sha1WithRSAEncryption.equals(digestAlgorithm.getAlgorithm())) + { + return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); + } + } + + return digestAlgorithm; + } } diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/EnvelopedDataHelper.java b/pkix/src/main/java/org/bouncycastle/cms/bc/EnvelopedDataHelper.java index b47c86ff0f..987b38b2df 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/bc/EnvelopedDataHelper.java +++ b/pkix/src/main/java/org/bouncycastle/cms/bc/EnvelopedDataHelper.java @@ -65,7 +65,7 @@ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier) { - return new SHA256Digest(); + return SHA256Digest.newInstance(); } }); table.put(PKCSObjectIdentifiers.id_hmacWithSHA384, new BcDigestProvider() @@ -124,7 +124,7 @@ static Wrapper createRFC3211Wrapper(ASN1ObjectIdentifier algorithm) || NISTObjectIdentifiers.id_aes192_CBC.equals(algorithm) || NISTObjectIdentifiers.id_aes256_CBC.equals(algorithm)) { - return new RFC3211WrapEngine(new AESEngine()); + return new RFC3211WrapEngine(AESEngine.newInstance()); } else if (PKCSObjectIdentifiers.des_EDE3_CBC.equals(algorithm)) { diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java index 1a1ca1e83f..65aa3fba4b 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java +++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java @@ -1,5 +1,6 @@ package org.bouncycastle.cms.jcajce; +import java.io.IOException; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; @@ -32,11 +33,13 @@ import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PBKDF2Params; @@ -47,6 +50,9 @@ import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.PasswordRecipient; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.params.HKDFParameters; import org.bouncycastle.operator.AsymmetricKeyUnwrapper; import org.bouncycastle.operator.DefaultSecretKeySizeProvider; import org.bouncycastle.operator.GenericKey; @@ -54,10 +60,13 @@ import org.bouncycastle.operator.SymmetricKeyUnwrapper; import org.bouncycastle.operator.jcajce.JceAsymmetricKeyUnwrapper; import org.bouncycastle.operator.jcajce.JceKTSKeyUnwrapper; +import org.bouncycastle.util.Strings; public class EnvelopedDataHelper { protected static final SecretKeySizeProvider KEY_SIZE_PROVIDER = DefaultSecretKeySizeProvider.INSTANCE; + private static final byte[] hkdfSalt = Strings.toByteArray("The Cryptographic Message Syntax"); + private static final Set authEnvelopedAlgorithms = new HashSet(); protected static final Map BASE_CIPHER_NAMES = new HashMap(); @@ -203,6 +212,46 @@ public Key getJceKey(ASN1ObjectIdentifier algorithm, GenericKey key) throw new IllegalArgumentException("unknown generic key type"); } + public Key getJceKey(AlgorithmIdentifier algId, GenericKey key) + throws CMSException + { + if (algId.getAlgorithm().equals(CMSObjectIdentifiers.id_alg_cek_hkdf_sha256)) + { + byte[] keyData = null; + + if (key.getRepresentation() instanceof Key) + { + keyData = ((Key)key.getRepresentation()).getEncoded(); + } + + if (key.getRepresentation() instanceof byte[]) + { + keyData = (byte[])key.getRepresentation(); + } + + AlgorithmIdentifier encAlgId = AlgorithmIdentifier.getInstance(algId.getParameters()); + + // TODO: at the moment assumes HKDF with SHA256 + HKDFBytesGenerator kdf = new HKDFBytesGenerator(new SHA256Digest()); + try + { + kdf.init(new HKDFParameters(keyData, hkdfSalt, encAlgId.getEncoded(ASN1Encoding.DER))); + } + catch (IOException e) + { + throw new CMSException("unable to encode enc algorithm parameters", e); + } + + kdf.generateBytes(keyData, 0, keyData.length); + + return new SecretKeySpec(keyData, getBaseCipherName(encAlgId.getAlgorithm())); + } + else + { + return getJceKey(algId.getAlgorithm(), key); + } + } + public void keySizeCheck(AlgorithmIdentifier keyAlgorithm, Key key) throws CMSException { @@ -363,15 +412,24 @@ public Object doInJCE() InvalidKeyException, InvalidParameterSpecException, NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { - Cipher cipher = createCipher(encryptionAlgID.getAlgorithm()); - ASN1Encodable sParams = encryptionAlgID.getParameters(); - String encAlg = encryptionAlgID.getAlgorithm().getId(); + AlgorithmIdentifier encAlgId; + if (encryptionAlgID.getAlgorithm().equals(CMSObjectIdentifiers.id_alg_cek_hkdf_sha256)) + { + encAlgId = AlgorithmIdentifier.getInstance(encryptionAlgID.getParameters()); + } + else + { + encAlgId = encryptionAlgID; + } + Cipher cipher = createCipher(encAlgId.getAlgorithm()); + ASN1Encodable sParams = encAlgId.getParameters(); + String encAlg = encAlgId.getAlgorithm().getId(); if (sParams != null && !(sParams instanceof ASN1Null)) { try { - AlgorithmParameters params = createAlgorithmParameters(encryptionAlgID.getAlgorithm()); + AlgorithmParameters params = createAlgorithmParameters(encAlgId.getAlgorithm()); CMSUtils.loadParameters(params, sParams); diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java index 78cdf40964..91b4ae4047 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java @@ -1,5 +1,6 @@ package org.bouncycastle.cms.jcajce; +import java.io.IOException; import java.io.OutputStream; import java.security.AccessController; import java.security.AlgorithmParameters; @@ -11,16 +12,22 @@ import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.GCMParameters; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; +import org.bouncycastle.crypto.params.HKDFParameters; import org.bouncycastle.jcajce.io.CipherOutputStream; import org.bouncycastle.operator.DefaultSecretKeySizeProvider; import org.bouncycastle.operator.GenericKey; @@ -29,6 +36,7 @@ import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.operator.SecretKeySizeProvider; import org.bouncycastle.operator.jcajce.JceGenericKey; +import org.bouncycastle.util.Strings; /** * Builder for the content encryptor in EnvelopedData - used to encrypt the actual transmitted content. @@ -36,6 +44,7 @@ public class JceCMSContentEncryptorBuilder { private static final SecretKeySizeProvider KEY_SIZE_PROVIDER = DefaultSecretKeySizeProvider.INSTANCE; + private static final byte[] hkdfSalt = Strings.toByteArray("The Cryptographic Message Syntax"); private final ASN1ObjectIdentifier encryptionOID; private final int keySize; @@ -44,6 +53,7 @@ public class JceCMSContentEncryptorBuilder private SecureRandom random; private AlgorithmIdentifier algorithmIdentifier; private AlgorithmParameters algorithmParameters; + private ASN1ObjectIdentifier kdfAlgorithm; public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID) { @@ -93,6 +103,31 @@ public JceCMSContentEncryptorBuilder(AlgorithmIdentifier encryptionAlgId) this.algorithmIdentifier = encryptionAlgId; } + public JceCMSContentEncryptorBuilder setEnableSha256HKdf(boolean useSha256Hkdf) + { + if (useSha256Hkdf) + { + // eventually this will be the default. + this.kdfAlgorithm = CMSObjectIdentifiers.id_alg_cek_hkdf_sha256; + } + else + { + if (this.kdfAlgorithm != null) + { + if (this.kdfAlgorithm.equals(CMSObjectIdentifiers.id_alg_cek_hkdf_sha256)) + { + this.kdfAlgorithm = null; + } + else + { + throw new IllegalStateException("SHA256 HKDF not enabled"); + } + } + } + + return this; + } + /** * Set the provider to use for content encryption. * @@ -152,9 +187,9 @@ public OutputEncryptor build() { if (helper.isAuthEnveloped(encryptionOID)) { - return new CMSAuthOutputEncryptor(encryptionOID, keySize, algorithmParameters, random); + return new CMSAuthOutputEncryptor(kdfAlgorithm, encryptionOID, keySize, algorithmParameters, random); } - return new CMSOutputEncryptor(encryptionOID, keySize, algorithmParameters, random); + return new CMSOutputEncryptor(kdfAlgorithm, encryptionOID, keySize, algorithmParameters, random); } if (algorithmIdentifier != null) { @@ -176,19 +211,47 @@ public OutputEncryptor build() if (helper.isAuthEnveloped(encryptionOID)) { - return new CMSAuthOutputEncryptor(encryptionOID, keySize, algorithmParameters, random); + return new CMSAuthOutputEncryptor(kdfAlgorithm, encryptionOID, keySize, algorithmParameters, random); } - return new CMSOutputEncryptor(encryptionOID, keySize, algorithmParameters, random); + return new CMSOutputEncryptor(kdfAlgorithm, encryptionOID, keySize, algorithmParameters, random); } - private class CMSOutputEncryptor - implements OutputEncryptor + private class CMSOutEncryptor { - private SecretKey encKey; - private AlgorithmIdentifier algorithmIdentifier; - private Cipher cipher; + protected SecretKey encKey; + protected AlgorithmIdentifier algorithmIdentifier; + protected Cipher cipher; + + private void applyKdf(ASN1ObjectIdentifier kdfAlgorithm, AlgorithmParameters params, SecureRandom random) + throws CMSException + { + // TODO: at the moment assumes HKDF with SHA256 + HKDFBytesGenerator kdf = new HKDFBytesGenerator(new SHA256Digest()); + byte[] encKeyEncoded = encKey.getEncoded(); + try + { + kdf.init(new HKDFParameters(encKeyEncoded, hkdfSalt, algorithmIdentifier.getEncoded(ASN1Encoding.DER))); + } + catch (IOException e) + { + throw new CMSException("unable to encode enc algorithm parameters", e); + } - CMSOutputEncryptor(ASN1ObjectIdentifier encryptionOID, int keySize, AlgorithmParameters params, SecureRandom random) + kdf.generateBytes(encKeyEncoded, 0, encKeyEncoded.length); + + SecretKeySpec derivedKey = new SecretKeySpec(encKeyEncoded, encKey.getAlgorithm()); + try + { + cipher.init(Cipher.ENCRYPT_MODE, derivedKey, params, random); + } + catch (GeneralSecurityException e) + { + throw new CMSException("unable to initialize cipher: " + e.getMessage(), e); + } + algorithmIdentifier = new AlgorithmIdentifier(kdfAlgorithm, algorithmIdentifier); + } + + protected void init(ASN1ObjectIdentifier kdfAlgorithm, ASN1ObjectIdentifier encryptionOID, int keySize, AlgorithmParameters params, SecureRandom random) throws CMSException { KeyGenerator keyGen = helper.createKeyGenerator(encryptionOID); @@ -211,26 +274,62 @@ private class CMSOutputEncryptor { params = helper.generateParameters(encryptionOID, encKey, random); } - - try + + if (params != null) { - cipher.init(Cipher.ENCRYPT_MODE, encKey, params, random); + algorithmIdentifier = helper.getAlgorithmIdentifier(encryptionOID, params); + + if (kdfAlgorithm != null) + { + applyKdf(kdfAlgorithm, params, random); + } + else + { + try + { + cipher.init(Cipher.ENCRYPT_MODE, encKey, params, random); + } + catch (GeneralSecurityException e) + { + throw new CMSException("unable to initialize cipher: " + e.getMessage(), e); + } + } } - catch (GeneralSecurityException e) + else { - throw new CMSException("unable to initialize cipher: " + e.getMessage(), e); - } + // + // If params are null we try and second guess on them as some providers don't provide + // algorithm parameter generation explicitly but instead generate them under the hood. + // + try + { + cipher.init(Cipher.ENCRYPT_MODE, encKey, params, random); + } + catch (GeneralSecurityException e) + { + throw new CMSException("unable to initialize cipher: " + e.getMessage(), e); + } - // - // If params are null we try and second guess on them as some providers don't provide - // algorithm parameter generation explicitly but instead generate them under the hood. - // - if (params == null) - { params = cipher.getParameters(); + + algorithmIdentifier = helper.getAlgorithmIdentifier(encryptionOID, params); + + if (kdfAlgorithm != null) + { + applyKdf(kdfAlgorithm, params, random); + } } + } + } - algorithmIdentifier = helper.getAlgorithmIdentifier(encryptionOID, params); + private class CMSOutputEncryptor + extends CMSOutEncryptor + implements OutputEncryptor + { + CMSOutputEncryptor(ASN1ObjectIdentifier kdfAlgorithm, ASN1ObjectIdentifier encryptionOID, int keySize, AlgorithmParameters params, SecureRandom random) + throws CMSException + { + init(kdfAlgorithm, encryptionOID, keySize, params, random); } public AlgorithmIdentifier getAlgorithmIdentifier() @@ -250,56 +349,15 @@ public GenericKey getKey() } private class CMSAuthOutputEncryptor + extends CMSOutEncryptor implements OutputAEADEncryptor { - private SecretKey encKey; - private AlgorithmIdentifier algorithmIdentifier; - private Cipher cipher; private MacCaptureStream macOut; - CMSAuthOutputEncryptor(ASN1ObjectIdentifier encryptionOID, int keySize, AlgorithmParameters params, SecureRandom random) + CMSAuthOutputEncryptor(ASN1ObjectIdentifier kdfAlgorithm, ASN1ObjectIdentifier encryptionOID, int keySize, AlgorithmParameters params, SecureRandom random) throws CMSException { - KeyGenerator keyGen = helper.createKeyGenerator(encryptionOID); - - random = CryptoServicesRegistrar.getSecureRandom(random); - - if (keySize < 0) - { - keyGen.init(random); - } - else - { - keyGen.init(keySize, random); - } - - cipher = helper.createCipher(encryptionOID); - encKey = keyGen.generateKey(); - - if (params == null) - { - params = helper.generateParameters(encryptionOID, encKey, random); - } - - try - { - cipher.init(Cipher.ENCRYPT_MODE, encKey, params, random); - } - catch (GeneralSecurityException e) - { - throw new CMSException("unable to initialize cipher: " + e.getMessage(), e); - } - - // - // If params are null we try and second guess on them as some providers don't provide - // algorithm parameter generation explicitly but instead generate them under the hood. - // - if (params == null) - { - params = cipher.getParameters(); - } - - algorithmIdentifier = helper.getAlgorithmIdentifier(encryptionOID, params); + init(kdfAlgorithm, encryptionOID, keySize, params, random); } public AlgorithmIdentifier getAlgorithmIdentifier() @@ -309,9 +367,18 @@ public AlgorithmIdentifier getAlgorithmIdentifier() public OutputStream getOutputStream(OutputStream dOut) { + AlgorithmIdentifier algId; + if (kdfAlgorithm != null) + { + algId = AlgorithmIdentifier.getInstance(algorithmIdentifier.getParameters()); + } + else + { + algId = algorithmIdentifier; + } + // TODO: works for CCM too, but others will follow. - GCMParameters p = GCMParameters.getInstance(algorithmIdentifier.getParameters()); - + GCMParameters p = GCMParameters.getInstance(algId.getParameters()); macOut = new MacCaptureStream(dOut, p.getIcvLen()); return new CipherOutputStream(macOut, cipher); } diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipient.java index d0e41644ac..9f8bf096b5 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipient.java +++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipient.java @@ -102,7 +102,7 @@ protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, Algor try { - Key key = helper.getJceKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedContentEncryptionKey)); + Key key = helper.getJceKey(encryptedKeyAlgorithm, unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedContentEncryptionKey)); if (validateKeySize) { diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEMRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEMRecipient.java index f6b705661e..a900a3cc21 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEMRecipient.java +++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEMRecipient.java @@ -159,7 +159,7 @@ protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, Algor try { - Key key = helper.getJceKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey)); + Key key = helper.getJceKey(encryptedKeyAlgorithm, unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey)); if (validateKeySize) { diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKTSKeyTransRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKTSKeyTransRecipient.java index 75db768bd5..6d72b784d0 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKTSKeyTransRecipient.java +++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKTSKeyTransRecipient.java @@ -138,7 +138,7 @@ protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, Algor try { - Key key = helper.getJceKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey)); + Key key = helper.getJceKey(encryptedKeyAlgorithm, unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey)); if (validateKeySize) { diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java index 78f7b27f65..5c499edeab 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java +++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java @@ -56,6 +56,7 @@ public abstract class JceKeyAgreeRecipient private PrivateKey recipientKey; protected EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); protected EnvelopedDataHelper contentHelper = helper; + protected EnvelopedDataHelper unwrappingHelper = helper; private SecretKeySizeProvider keySizeProvider = new DefaultSecretKeySizeProvider(); private AlgorithmIdentifier privKeyAlgID = null; @@ -74,6 +75,7 @@ public JceKeyAgreeRecipient setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); this.contentHelper = helper; + this.unwrappingHelper = helper; return this; } @@ -88,6 +90,33 @@ public JceKeyAgreeRecipient setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); this.contentHelper = helper; + this.unwrappingHelper = helper; + + return this; + } + + /** + * Set the provider to use for unwrapping the content session key. + * + * @param provider provider to use. + * @return this recipient. + */ + public JceKeyAgreeRecipient setUnwrappingProvider(Provider provider) + { + this.unwrappingHelper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); + + return this; + } + + /** + * Set the provider to use for unwrapping the content session key. + * + * @param providerName the name of the provider to use. + * @return this recipient. + */ + public JceKeyAgreeRecipient setUnwrappingProvider(String providerName) + { + this.unwrappingHelper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; } @@ -135,7 +164,7 @@ public JceKeyAgreeRecipient setPrivateKeyAlgorithmIdentifier(AlgorithmIdentifier } private SecretKey calculateAgreedWrapKey(AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier wrapAlg, - PublicKey senderPublicKey, ASN1OctetString userKeyingMaterial, PrivateKey receiverPrivateKey, KeyMaterialGenerator kmGen) + PublicKey senderPublicKey, ASN1OctetString userKeyingMaterial, PrivateKey receiverPrivateKey, KeyMaterialGenerator kmGen) throws CMSException, GeneralSecurityException, IOException { receiverPrivateKey = CMSUtils.cleanPrivateKey(receiverPrivateKey); @@ -145,8 +174,8 @@ private SecretKey calculateAgreedWrapKey(AlgorithmIdentifier keyEncAlg, Algorith MQVuserKeyingMaterial ukm = MQVuserKeyingMaterial.getInstance(userKeyingMaterial.getOctets()); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo( - getPrivateKeyAlgorithmIdentifier(), - ukm.getEphemeralPublicKey().getPublicKey().getBytes()); + getPrivateKeyAlgorithmIdentifier(), + ukm.getEphemeralPublicKey().getPublicKeyData()); X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubInfo.getEncoded()); KeyFactory fact = helper.createKeyFactory(keyEncAlg.getAlgorithm()); @@ -173,18 +202,16 @@ private SecretKey calculateAgreedWrapKey(AlgorithmIdentifier keyEncAlg, Algorith if (CMSUtils.isEC(keyEncAlg.getAlgorithm())) { + byte[] ukmKeyingMaterial; if (userKeyingMaterial != null) { - byte[] ukmKeyingMaterial = kmGen.generateKDFMaterial(wrapAlg, keySizeProvider.getKeySize(wrapAlg), userKeyingMaterial.getOctets()); - - userKeyingMaterialSpec = new UserKeyingMaterialSpec(ukmKeyingMaterial); + ukmKeyingMaterial = kmGen.generateKDFMaterial(wrapAlg, keySizeProvider.getKeySize(wrapAlg), userKeyingMaterial.getOctets()); } else { - byte[] ukmKeyingMaterial = kmGen.generateKDFMaterial(wrapAlg, keySizeProvider.getKeySize(wrapAlg), null); - - userKeyingMaterialSpec = new UserKeyingMaterialSpec(ukmKeyingMaterial); + ukmKeyingMaterial = kmGen.generateKDFMaterial(wrapAlg, keySizeProvider.getKeySize(wrapAlg), null); } + userKeyingMaterialSpec = new UserKeyingMaterialSpec(ukmKeyingMaterial); } else if (CMSUtils.isRFC2631(keyEncAlg.getAlgorithm())) { @@ -216,7 +243,7 @@ else if (CMSUtils.isGOST(keyEncAlg.getAlgorithm())) protected Key unwrapSessionKey(ASN1ObjectIdentifier wrapAlg, SecretKey agreedKey, ASN1ObjectIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey) throws CMSException, InvalidKeyException, NoSuchAlgorithmException { - Cipher keyCipher = helper.createCipher(wrapAlg); + Cipher keyCipher = unwrappingHelper.createCipher(wrapAlg); keyCipher.init(Cipher.UNWRAP_MODE, agreedKey); return keyCipher.unwrap(encryptedContentEncryptionKey, helper.getBaseCipherName(contentEncryptionAlgorithm), Cipher.SECRET_KEY); } @@ -243,7 +270,7 @@ protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, Algor { Gost2814789EncryptedKey encKey = Gost2814789EncryptedKey.getInstance(encryptedContentEncryptionKey); Gost2814789KeyWrapParameters wrapParams = Gost2814789KeyWrapParameters.getInstance(wrapAlg.getParameters()); - + Cipher keyCipher = helper.createCipher(wrapAlg.getAlgorithm()); keyCipher.init(Cipher.UNWRAP_MODE, agreedWrapKey, new GOST28147WrapParameterSpec(wrapParams.getEncryptionParamSet(), userKeyingMaterial.getOctets())); @@ -340,6 +367,6 @@ public byte[] generateKDFMaterial(AlgorithmIdentifier keyAlgorithm, int keySize, return userKeyMaterialParameters; } }; - + private static KeyMaterialGenerator ecc_cms_Generator = new RFC5753KeyMaterialGenerator(); } diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java index 12761ab91a..d2dc76a569 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java @@ -57,6 +57,8 @@ public class JceKeyAgreeRecipientInfoGenerator private PrivateKey senderPrivateKey; private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); + private EnvelopedDataHelper wrappingHelper = null; + private SecureRandom random; private KeyPair ephemeralKP; private byte[] userKeyingMaterial; @@ -90,6 +92,20 @@ public JceKeyAgreeRecipientInfoGenerator setProvider(String providerName) return this; } + public JceKeyAgreeRecipientInfoGenerator setKeyWrappingProvider(Provider provider) + { + this.wrappingHelper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); + + return this; + } + + public JceKeyAgreeRecipientInfoGenerator setKeyWrappingProvider(String providerName) + { + this.wrappingHelper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); + + return this; + } + public JceKeyAgreeRecipientInfoGenerator setSecureRandom(SecureRandom random) { this.random = random; @@ -203,8 +219,10 @@ else if (CMSUtils.isGOST(keyAgreementOID)) SecretKey keyEncryptionKey = keyAgreement.generateSecret(keyEncAlg.getId()); + EnvelopedDataHelper keyWrapHelper = (wrappingHelper != null) ? wrappingHelper : helper; + // Wrap the content encryption key with the agreement key - Cipher keyEncryptionCipher = helper.createCipher(keyEncAlg); + Cipher keyEncryptionCipher = keyWrapHelper.createCipher(keyEncAlg); ASN1OctetString encryptedKey; if (keyEncAlg.equals(CryptoProObjectIdentifiers.id_Gost28147_89_None_KeyWrap) @@ -212,7 +230,7 @@ else if (CMSUtils.isGOST(keyAgreementOID)) { keyEncryptionCipher.init(Cipher.WRAP_MODE, keyEncryptionKey, new GOST28147WrapParameterSpec(CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_A_ParamSet, userKeyingMaterial)); - byte[] encKeyBytes = keyEncryptionCipher.wrap(helper.getJceKey(contentEncryptionKey)); + byte[] encKeyBytes = keyEncryptionCipher.wrap(keyWrapHelper.getJceKey(contentEncryptionKey)); Gost2814789EncryptedKey encKey = new Gost2814789EncryptedKey( Arrays.copyOfRange(encKeyBytes, 0, encKeyBytes.length - 4), @@ -224,7 +242,7 @@ else if (CMSUtils.isGOST(keyAgreementOID)) { keyEncryptionCipher.init(Cipher.WRAP_MODE, keyEncryptionKey, random); - byte[] encryptedKeyBytes = keyEncryptionCipher.wrap(helper.getJceKey(contentEncryptionKey)); + byte[] encryptedKeyBytes = keyEncryptionCipher.wrap(keyWrapHelper.getJceKey(contentEncryptionKey)); encryptedKey = new DEROctetString(encryptedKeyBytes); } diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransAuthEnvelopedRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransAuthEnvelopedRecipient.java index ef76148c9c..c697ca83f5 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransAuthEnvelopedRecipient.java +++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransAuthEnvelopedRecipient.java @@ -10,6 +10,7 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSException; +import org.bouncycastle.cms.InputStreamWithMAC; import org.bouncycastle.cms.RecipientOperator; import org.bouncycastle.jcajce.io.CipherInputStream; import org.bouncycastle.operator.InputAEADDecryptor; @@ -31,6 +32,8 @@ public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionA return new RecipientOperator(new InputAEADDecryptor() { + private InputStream inputStream; + public AlgorithmIdentifier getAlgorithmIdentifier() { return contentEncryptionAlgorithm; @@ -38,6 +41,7 @@ public AlgorithmIdentifier getAlgorithmIdentifier() public InputStream getInputStream(InputStream dataIn) { + inputStream = dataIn; return new CipherInputStream(dataIn, dataCipher); } @@ -48,8 +52,11 @@ public OutputStream getAADStream() public byte[] getMAC() { - // TODO - return new byte[0]; + if (inputStream instanceof InputStreamWithMAC) + { + return ((InputStreamWithMAC)inputStream).getMAC(); + } + return null; } }); } @@ -64,7 +71,7 @@ public AADStream(Cipher cipher) { this.cipher = cipher; } - + public void write(byte[] buf, int off, int len) throws IOException { diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java index f4b08baac0..360a9f2fec 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java +++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java @@ -209,7 +209,7 @@ else if (CMSObjectIdentifiers.id_ori_kem.equals(keyEncryptionAlgorithm.getAlgori try { - Key key = helper.getJceKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey)); + Key key = helper.getJceKey(encryptedKeyAlgorithm, unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey)); if (validateKeySize) { @@ -239,11 +239,19 @@ else if (CMSObjectIdentifiers.id_ori_kem.equals(keyEncryptionAlgorithm.getAlgori try { - Key key = helper.getJceKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey)); + Key key = helper.getJceKey(encryptedKeyAlgorithm, unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey)); if (validateKeySize) { - helper.keySizeCheck(encryptedKeyAlgorithm, key); + if (encryptedEncryptionKey.equals(CMSObjectIdentifiers.id_alg_cek_hkdf_sha256)) + { + helper.keySizeCheck( + AlgorithmIdentifier.getInstance(encryptedKeyAlgorithm.getParameters()), key); + } + else + { + helper.keySizeCheck(encryptedKeyAlgorithm, key); + } } return key; diff --git a/pkix/src/main/java/org/bouncycastle/eac/EACCertificateBuilder.java b/pkix/src/main/java/org/bouncycastle/eac/EACCertificateBuilder.java index a5b3373922..929215c5be 100644 --- a/pkix/src/main/java/org/bouncycastle/eac/EACCertificateBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/eac/EACCertificateBuilder.java @@ -3,7 +3,10 @@ import java.io.OutputStream; import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.DERApplicationSpecific; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.eac.CVCertificate; import org.bouncycastle.asn1.eac.CertificateBody; import org.bouncycastle.asn1.eac.CertificateHolderAuthorization; @@ -43,10 +46,10 @@ public EACCertificateBuilder( private CertificateBody buildBody() { - DERApplicationSpecific certificateProfileIdentifier; + ASN1TaggedObject certificateProfileIdentifier; - certificateProfileIdentifier = new DERApplicationSpecific( - EACTags.INTERCHANGE_PROFILE, ZeroArray); + certificateProfileIdentifier = new DERTaggedObject(false, BERTags.APPLICATION, + EACTags.INTERCHANGE_PROFILE, new DEROctetString(ZeroArray)); CertificateBody body = new CertificateBody( certificateProfileIdentifier, diff --git a/pkix/src/main/java/org/bouncycastle/mozilla/SignedPublicKeyAndChallenge.java b/pkix/src/main/java/org/bouncycastle/mozilla/SignedPublicKeyAndChallenge.java index 44d5954237..8be439cdd3 100644 --- a/pkix/src/main/java/org/bouncycastle/mozilla/SignedPublicKeyAndChallenge.java +++ b/pkix/src/main/java/org/bouncycastle/mozilla/SignedPublicKeyAndChallenge.java @@ -121,7 +121,7 @@ public boolean verify(String provider) { sig.update(spkacSeq.getPublicKeyAndChallenge().getEncoded()); - return sig.verify(spkacSeq.getSignature().getBytes()); + return sig.verify(spkacSeq.getSignature().getOctets()); } catch (Exception e) { diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PEMParser.java b/pkix/src/main/java/org/bouncycastle/openssl/PEMParser.java index 0ac715a8e6..32d0b5ee0b 100644 --- a/pkix/src/main/java/org/bouncycastle/openssl/PEMParser.java +++ b/pkix/src/main/java/org/bouncycastle/openssl/PEMParser.java @@ -10,7 +10,7 @@ import java.util.Set; import java.util.StringTokenizer; -import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; @@ -110,22 +110,19 @@ public Object readObject() throws IOException { PemObject obj = readPemObject(); + if (obj == null) + { + return null; + } - if (obj != null) + String type = obj.getType(); + Object pemObjectParser = parsers.get(type); + if (pemObjectParser == null) { - String type = obj.getType(); - Object pemObjectParser = parsers.get(type); - if (pemObjectParser != null) - { - return ((PemObjectParser)pemObjectParser).parseObject(obj); - } - else - { - throw new IOException("unrecognised object: " + type); - } + throw new IOException("unrecognised object: " + type); } - return null; + return ((PemObjectParser)pemObjectParser).parseObject(obj); } /** @@ -268,16 +265,14 @@ public PEMKeyPair parse(byte[] encoding) pKey.getParametersObject()); PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey); - if (pKey.getPublicKey() != null) + ASN1BitString publicKey = pKey.getPublicKey(); + SubjectPublicKeyInfo pubInfo = null; + if (publicKey != null) { - SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pKey.getPublicKey().getBytes()); - - return new PEMKeyPair(pubInfo, privInfo); - } - else - { - return new PEMKeyPair(null, privInfo); + pubInfo = new SubjectPublicKeyInfo(algId, publicKey.getBytes()); } + + return new PEMKeyPair(pubInfo, privInfo); } catch (IOException e) { @@ -353,9 +348,10 @@ public Object parseObject(PemObject obj) { try { + AlgorithmIdentifier algId = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE); RSAPublicKey rsaPubStructure = RSAPublicKey.getInstance(obj.getContent()); - return new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), rsaPubStructure); + return new SubjectPublicKeyInfo(algId, rsaPubStructure); } catch (IOException e) { @@ -475,9 +471,7 @@ public Object parseObject(PemObject obj) { try { - ASN1InputStream aIn = new ASN1InputStream(obj.getContent()); - - return ContentInfo.getInstance(aIn.readObject()); + return ContentInfo.getInstance(obj.getContent()); } catch (Exception e) { @@ -508,7 +502,7 @@ public Object parseObject(PemObject obj) if (param instanceof ASN1ObjectIdentifier) { - return ASN1Primitive.fromByteArray(obj.getContent()); + return param; } else if (param instanceof ASN1Sequence) { diff --git a/pkix/src/main/java/org/bouncycastle/openssl/bc/PEMUtilities.java b/pkix/src/main/java/org/bouncycastle/openssl/bc/PEMUtilities.java index 57a1228774..f7cf04da0e 100644 --- a/pkix/src/main/java/org/bouncycastle/openssl/bc/PEMUtilities.java +++ b/pkix/src/main/java/org/bouncycastle/openssl/bc/PEMUtilities.java @@ -194,7 +194,7 @@ else if (dekAlgName.startsWith("AES-256-")) throw new EncryptionException("unknown AES encryption with private key: " + dekAlgName); } sKey = getKey(password, keyBits / 8, salt); - engine = new AESEngine(); + engine = AESEngine.newInstance(); } else { @@ -203,11 +203,11 @@ else if (dekAlgName.startsWith("AES-256-")) if (blockMode.equals("CBC")) { - engine = new CBCBlockCipher(engine); + engine = CBCBlockCipher.newInstance(engine); } else if (blockMode.equals("CFB")) { - engine = new CFBBlockCipher(engine, engine.getBlockSize() * 8); + engine = CFBBlockCipher.newInstance(engine, engine.getBlockSize() * 8); } else if (blockMode.equals("OFB")) { diff --git a/pkix/src/main/java/org/bouncycastle/operator/DefaultAlgorithmNameFinder.java b/pkix/src/main/java/org/bouncycastle/operator/DefaultAlgorithmNameFinder.java index e053093904..88b1214978 100644 --- a/pkix/src/main/java/org/bouncycastle/operator/DefaultAlgorithmNameFinder.java +++ b/pkix/src/main/java/org/bouncycastle/operator/DefaultAlgorithmNameFinder.java @@ -46,6 +46,19 @@ public class DefaultAlgorithmNameFinder algorithms.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512WITHCVC-ECDSA"); algorithms.put(BCObjectIdentifiers.falcon_512, "FALCON"); algorithms.put(BCObjectIdentifiers.falcon_1024, "FALCON"); + algorithms.put(NISTObjectIdentifiers.id_slh_dsa_sha2_128s, "SPHINCS+"); + algorithms.put(NISTObjectIdentifiers.id_slh_dsa_sha2_128f, "SPHINCS+"); + algorithms.put(NISTObjectIdentifiers.id_slh_dsa_sha2_192s, "SPHINCS+"); + algorithms.put(NISTObjectIdentifiers.id_slh_dsa_sha2_192f, "SPHINCS+"); + algorithms.put(NISTObjectIdentifiers.id_slh_dsa_sha2_256s, "SPHINCS+"); + algorithms.put(NISTObjectIdentifiers.id_slh_dsa_sha2_256f, "SPHINCS+"); + algorithms.put(NISTObjectIdentifiers.id_slh_dsa_shake_128s, "SPHINCS+"); + algorithms.put(NISTObjectIdentifiers.id_slh_dsa_shake_128f, "SPHINCS+"); + algorithms.put(NISTObjectIdentifiers.id_slh_dsa_shake_192s, "SPHINCS+"); + algorithms.put(NISTObjectIdentifiers.id_slh_dsa_shake_192f, "SPHINCS+"); + algorithms.put(NISTObjectIdentifiers.id_slh_dsa_shake_256s, "SPHINCS+"); + algorithms.put(NISTObjectIdentifiers.id_slh_dsa_shake_256f, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, "SPHINCS+"); algorithms.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, "SPHINCS+"); algorithms.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, "SPHINCS+"); @@ -64,6 +77,24 @@ public class DefaultAlgorithmNameFinder algorithms.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, "SPHINCS+"); algorithms.put(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, "SPHINCS+"); algorithms.put(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple, "SPHINCS+"); + algorithms.put(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple, "SPHINCS+"); algorithms.put(NISTObjectIdentifiers.id_sha224, "SHA224"); algorithms.put(NISTObjectIdentifiers.id_sha256, "SHA256"); diff --git a/pkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java b/pkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java index 9a35a42a9b..e3efab2b6d 100644 --- a/pkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java +++ b/pkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java @@ -41,6 +41,7 @@ public class DefaultDigestAlgorithmIdentifierFinder digestOids.put(OIWObjectIdentifiers.dsaWithSHA1, OIWObjectIdentifiers.idSHA1); digestOids.put(OIWObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4); digestOids.put(OIWObjectIdentifiers.md4WithRSA, PKCSObjectIdentifiers.md4); + digestOids.put(OIWObjectIdentifiers.md5WithRSA, PKCSObjectIdentifiers.md5); digestOids.put(OIWObjectIdentifiers.sha1WithRSA, OIWObjectIdentifiers.idSHA1); digestOids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, NISTObjectIdentifiers.id_sha224); @@ -121,6 +122,52 @@ public class DefaultDigestAlgorithmIdentifierFinder digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3, NISTObjectIdentifiers.id_shake256); digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, NISTObjectIdentifiers.id_shake256); + + digestOids.put(NISTObjectIdentifiers.id_slh_dsa_sha2_128s, NISTObjectIdentifiers.id_sha256); + digestOids.put(NISTObjectIdentifiers.id_slh_dsa_sha2_128f, NISTObjectIdentifiers.id_sha256); + digestOids.put(NISTObjectIdentifiers.id_slh_dsa_sha2_192s, NISTObjectIdentifiers.id_sha512); + digestOids.put(NISTObjectIdentifiers.id_slh_dsa_sha2_192f, NISTObjectIdentifiers.id_sha512); + digestOids.put(NISTObjectIdentifiers.id_slh_dsa_sha2_256s, NISTObjectIdentifiers.id_sha512); + digestOids.put(NISTObjectIdentifiers.id_slh_dsa_sha2_256f, NISTObjectIdentifiers.id_sha512); + digestOids.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256, NISTObjectIdentifiers.id_sha256); + digestOids.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256, NISTObjectIdentifiers.id_sha256); + digestOids.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512, NISTObjectIdentifiers.id_sha512); + digestOids.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512, NISTObjectIdentifiers.id_sha512); + digestOids.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512, NISTObjectIdentifiers.id_sha512); + digestOids.put(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512, NISTObjectIdentifiers.id_sha512); + + digestOids.put(NISTObjectIdentifiers.id_slh_dsa_shake_128s, NISTObjectIdentifiers.id_shake128); + digestOids.put(NISTObjectIdentifiers.id_slh_dsa_shake_128f, NISTObjectIdentifiers.id_shake128); + digestOids.put(NISTObjectIdentifiers.id_slh_dsa_shake_192s, NISTObjectIdentifiers.id_shake256); + digestOids.put(NISTObjectIdentifiers.id_slh_dsa_shake_192f, NISTObjectIdentifiers.id_shake256); + digestOids.put(NISTObjectIdentifiers.id_slh_dsa_shake_256s, NISTObjectIdentifiers.id_shake256); + digestOids.put(NISTObjectIdentifiers.id_slh_dsa_shake_256f, NISTObjectIdentifiers.id_shake256); + digestOids.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128, NISTObjectIdentifiers.id_shake128); + digestOids.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128, NISTObjectIdentifiers.id_shake128); + digestOids.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256, NISTObjectIdentifiers.id_shake256); + digestOids.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256, NISTObjectIdentifiers.id_shake256); + digestOids.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256, NISTObjectIdentifiers.id_shake256); + digestOids.put(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256, NISTObjectIdentifiers.id_shake256); + + digestOids.put(NISTObjectIdentifiers.id_ml_dsa_44, NISTObjectIdentifiers.id_shake256); + digestOids.put(NISTObjectIdentifiers.id_ml_dsa_44, NISTObjectIdentifiers.id_shake256); + digestOids.put(NISTObjectIdentifiers.id_ml_dsa_44, NISTObjectIdentifiers.id_shake256); + digestOids.put(NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512, NISTObjectIdentifiers.id_sha512); + digestOids.put(NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512, NISTObjectIdentifiers.id_sha512); + digestOids.put(NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512, NISTObjectIdentifiers.id_sha512); + digestOids.put(BCObjectIdentifiers.falcon, NISTObjectIdentifiers.id_shake256); digestOids.put(BCObjectIdentifiers.falcon_512, NISTObjectIdentifiers.id_shake256); digestOids.put(BCObjectIdentifiers.falcon_1024, NISTObjectIdentifiers.id_shake256); @@ -225,9 +272,9 @@ public class DefaultDigestAlgorithmIdentifierFinder shake256oids.add(EdECObjectIdentifiers.id_Ed448); - shake256oids.add(BCObjectIdentifiers.dilithium2); - shake256oids.add(BCObjectIdentifiers.dilithium3); - shake256oids.add(BCObjectIdentifiers.dilithium5); + shake256oids.add(NISTObjectIdentifiers.id_ml_dsa_44); + shake256oids.add(NISTObjectIdentifiers.id_ml_dsa_65); + shake256oids.add(NISTObjectIdentifiers.id_ml_dsa_87); shake256oids.add(BCObjectIdentifiers.dilithium2_aes); shake256oids.add(BCObjectIdentifiers.dilithium3_aes); shake256oids.add(BCObjectIdentifiers.dilithium5_aes); @@ -256,6 +303,12 @@ public AlgorithmIdentifier find(AlgorithmIdentifier sigAlgId) if (shake256oids.contains(sigAlgOid)) { + // TODO: it seems it's very hard to find people accepting SHAKE256-len at the moment... + if (!sigAlgOid.equals(EdECObjectIdentifiers.id_Ed448)) + { + return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256); + } + return new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256_len, new ASN1Integer(512)); } @@ -274,7 +327,7 @@ else if (sigAlgOid.equals(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig)) } else { - digAlgOid = (ASN1ObjectIdentifier)digestOids.get(sigAlgId.getAlgorithm()); + digAlgOid = (ASN1ObjectIdentifier)digestOids.get(sigAlgOid); } return find(digAlgOid); @@ -305,15 +358,16 @@ public AlgorithmIdentifier find(String digAlgName) { return find(oid); } + try { return find(new ASN1ObjectIdentifier(digAlgName)); } - catch (IllegalArgumentException e) + catch (RuntimeException e) { // ignore - tried it but it didn't work... } return null; } -} \ No newline at end of file +} diff --git a/pkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java b/pkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java index 6d542a2da1..445202efce 100644 --- a/pkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java +++ b/pkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java @@ -29,7 +29,7 @@ import org.bouncycastle.util.Strings; public class DefaultSignatureAlgorithmIdentifierFinder - implements SignatureAlgorithmIdentifierFinder + implements SignatureAlgorithmIdentifierFinder { private static Map algorithms = new HashMap(); private static Set noParams = new HashSet(); @@ -37,15 +37,6 @@ public class DefaultSignatureAlgorithmIdentifierFinder private static Set pkcs15RsaEncryption = new HashSet(); private static Map digestOids = new HashMap(); - private static final ASN1ObjectIdentifier ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption; - private static final ASN1ObjectIdentifier ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1; - private static final ASN1ObjectIdentifier ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1; - private static final ASN1ObjectIdentifier ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS; - private static final ASN1ObjectIdentifier ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94; - private static final ASN1ObjectIdentifier ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001; - private static final ASN1ObjectIdentifier ENCRYPTION_ECGOST3410_2012_256 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256; - private static final ASN1ObjectIdentifier ENCRYPTION_ECGOST3410_2012_512 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512; - static { algorithms.put("COMPOSITE", MiscObjectIdentifiers.id_alg_composite); @@ -167,6 +158,8 @@ public class DefaultSignatureAlgorithmIdentifierFinder algorithms.put("SHA512WITHXMSS", BCObjectIdentifiers.xmss_SHA512ph); algorithms.put("SHAKE128WITHXMSS", BCObjectIdentifiers.xmss_SHAKE128ph); algorithms.put("SHAKE256WITHXMSS", BCObjectIdentifiers.xmss_SHAKE256ph); + algorithms.put("SHAKE128(512)WITHXMSS", BCObjectIdentifiers.xmss_SHAKE128_512ph); + algorithms.put("SHAKE256(1024)WITHXMSS", BCObjectIdentifiers.xmss_SHAKE256_1024ph); algorithms.put("SHA256WITHXMSSMT", BCObjectIdentifiers.xmss_mt_SHA256ph); algorithms.put("SHA512WITHXMSSMT", BCObjectIdentifiers.xmss_mt_SHA512ph); @@ -182,6 +175,8 @@ public class DefaultSignatureAlgorithmIdentifierFinder algorithms.put("SHA512WITHXMSSMT-SHA512", BCObjectIdentifiers.xmss_mt_SHA512ph); algorithms.put("SHAKE128WITHXMSSMT-SHAKE128", BCObjectIdentifiers.xmss_mt_SHAKE128ph); algorithms.put("SHAKE256WITHXMSSMT-SHAKE256", BCObjectIdentifiers.xmss_mt_SHAKE256ph); + algorithms.put("SHAKE128(512)WITHXMSSMT-SHAKE128", BCObjectIdentifiers.xmss_mt_SHAKE128_512ph); + algorithms.put("SHAKE256(1024)WITHXMSSMT-SHAKE256", BCObjectIdentifiers.xmss_mt_SHAKE256_1024ph); algorithms.put("LMS", PKCSObjectIdentifiers.id_alg_hss_lms_hashsig); @@ -199,14 +194,59 @@ public class DefaultSignatureAlgorithmIdentifierFinder algorithms.put("SPHINCS+", BCObjectIdentifiers.sphincsPlus); algorithms.put("SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus); - - algorithms.put("DILITHIUM2", BCObjectIdentifiers.dilithium2); - algorithms.put("DILITHIUM3", BCObjectIdentifiers.dilithium3); - algorithms.put("DILITHIUM5", BCObjectIdentifiers.dilithium5); + algorithms.put("SPHINCS+-SHA2-128S", BCObjectIdentifiers.sphincsPlus_sha2_128s); + algorithms.put("SPHINCS+-SHA2-128F", BCObjectIdentifiers.sphincsPlus_sha2_128f); + algorithms.put("SPHINCS+-SHA2-192S", BCObjectIdentifiers.sphincsPlus_sha2_192s); + algorithms.put("SPHINCS+-SHA2-192F", BCObjectIdentifiers.sphincsPlus_sha2_192f); + algorithms.put("SPHINCS+-SHA2-256S", BCObjectIdentifiers.sphincsPlus_sha2_256s); + algorithms.put("SPHINCS+-SHA2-256F", BCObjectIdentifiers.sphincsPlus_sha2_256f); + algorithms.put("SPHINCS+-SHAKE-128S", BCObjectIdentifiers.sphincsPlus_shake_128s); + algorithms.put("SPHINCS+-SHAKE-128F", BCObjectIdentifiers.sphincsPlus_shake_128f); + algorithms.put("SPHINCS+-SHAKE-192S", BCObjectIdentifiers.sphincsPlus_shake_192s); + algorithms.put("SPHINCS+-SHAKE-192F", BCObjectIdentifiers.sphincsPlus_shake_192f); + algorithms.put("SPHINCS+-SHAKE-256S", BCObjectIdentifiers.sphincsPlus_shake_256s); + algorithms.put("SPHINCS+-SHAKE-256F", BCObjectIdentifiers.sphincsPlus_shake_256f); + algorithms.put("SPHINCS+-HARAKA-128S-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_128s_r3); + algorithms.put("SPHINCS+-HARAKA-128F-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_128f_r3); + algorithms.put("SPHINCS+-HARAKA-192S-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_192s_r3); + algorithms.put("SPHINCS+-HARAKA-192F-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_192f_r3); + algorithms.put("SPHINCS+-HARAKA-256S-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_256s_r3); + algorithms.put("SPHINCS+-HARAKA-256F-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_256f_r3); + algorithms.put("SPHINCS+-HARAKA-128S-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple); + algorithms.put("SPHINCS+-HARAKA-128F-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple); + algorithms.put("SPHINCS+-HARAKA-192S-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple); + algorithms.put("SPHINCS+-HARAKA-192F-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple); + algorithms.put("SPHINCS+-HARAKA-256S-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple); + algorithms.put("SPHINCS+-HARAKA-256F-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple); + algorithms.put("SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus); + algorithms.put("DILITHIUM2", NISTObjectIdentifiers.id_ml_dsa_44); + algorithms.put("DILITHIUM3", NISTObjectIdentifiers.id_ml_dsa_65); + algorithms.put("DILITHIUM5", NISTObjectIdentifiers.id_ml_dsa_87); algorithms.put("DILITHIUM2-AES", BCObjectIdentifiers.dilithium2_aes); algorithms.put("DILITHIUM3-AES", BCObjectIdentifiers.dilithium3_aes); algorithms.put("DILITHIUM5-AES", BCObjectIdentifiers.dilithium5_aes); + algorithms.put("ML-DSA-44", NISTObjectIdentifiers.id_ml_dsa_44); + algorithms.put("ML-DSA-65", NISTObjectIdentifiers.id_ml_dsa_65); + algorithms.put("ML-DSA-87", NISTObjectIdentifiers.id_ml_dsa_87); + + algorithms.put("ML-DSA-44-WITH-SHA512", NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512); + algorithms.put("ML-DSA-65-WITH-SHA512", NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512); + algorithms.put("ML-DSA-87-WITH-SHA512", NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512); + + algorithms.put("SLH-DSA-SHA2-128S", NISTObjectIdentifiers.id_slh_dsa_sha2_128s); + algorithms.put("SLH-DSA-SHA2-128F", NISTObjectIdentifiers.id_slh_dsa_sha2_128f); + algorithms.put("SLH-DSA-SHA2-192S", NISTObjectIdentifiers.id_slh_dsa_sha2_192s); + algorithms.put("SLH-DSA-SHA2-192F", NISTObjectIdentifiers.id_slh_dsa_sha2_192f); + algorithms.put("SLH-DSA-SHA2-256S", NISTObjectIdentifiers.id_slh_dsa_sha2_256s); + algorithms.put("SLH-DSA-SHA2-256F", NISTObjectIdentifiers.id_slh_dsa_sha2_256f); + algorithms.put("SLH-DSA-SHAKE-128S", NISTObjectIdentifiers.id_slh_dsa_shake_128s); + algorithms.put("SLH-DSA-SHAKE-128F", NISTObjectIdentifiers.id_slh_dsa_shake_128f); + algorithms.put("SLH-DSA-SHAKE-192S", NISTObjectIdentifiers.id_slh_dsa_shake_192s); + algorithms.put("SLH-DSA-SHAKE-192F", NISTObjectIdentifiers.id_slh_dsa_shake_192f); + algorithms.put("SLH-DSA-SHAKE-256S", NISTObjectIdentifiers.id_slh_dsa_shake_256s); + algorithms.put("SLH-DSA-SHAKE-256F", NISTObjectIdentifiers.id_slh_dsa_shake_256f); + algorithms.put("FALCON-512", BCObjectIdentifiers.falcon_512); algorithms.put("FALCON-1024", BCObjectIdentifiers.falcon_1024); @@ -215,6 +255,23 @@ public class DefaultSignatureAlgorithmIdentifierFinder algorithms.put("SHA3-512WITHPICNIC", BCObjectIdentifiers.picnic_with_sha3_512); algorithms.put("SHAKE256WITHPICNIC", BCObjectIdentifiers.picnic_with_shake256); + algorithms.put("MLDSA44-RSA2048-PSS-SHA256", MiscObjectIdentifiers.id_MLDSA44_RSA2048_PSS_SHA256); + algorithms.put("MLDSA44-RSA2048-PKCS15-SHA256", MiscObjectIdentifiers.id_MLDSA44_RSA2048_PKCS15_SHA256); + algorithms.put("MLDSA44-ECDSA-P256-SHA256", MiscObjectIdentifiers.id_MLDSA44_ECDSA_P256_SHA256); + algorithms.put("MLDSA44-ECDSA-BRAINPOOLP256R1-SHA256", MiscObjectIdentifiers.id_MLDSA44_ECDSA_brainpoolP256r1_SHA256); + algorithms.put("MLDSA44-ED25519-SHA512", MiscObjectIdentifiers.id_MLDSA44_Ed25519_SHA512); + algorithms.put("MLDSA65-RSA3072-PSS-SHA512", MiscObjectIdentifiers.id_MLDSA65_RSA3072_PSS_SHA512); + algorithms.put("MLDSA65-RSA3072-PKCS15-SHA512", MiscObjectIdentifiers.id_MLDSA65_RSA3072_PKCS15_SHA512); + algorithms.put("MLDSA65-ECDSA-BRAINPOOLP256R1-SHA512", MiscObjectIdentifiers.id_MLDSA65_ECDSA_brainpoolP256r1_SHA512); + algorithms.put("MLDSA65-ECDSA-P256-SHA512", MiscObjectIdentifiers.id_MLDSA65_ECDSA_P256_SHA512); + algorithms.put("MLDSA65-ED25519-SHA512", MiscObjectIdentifiers.id_MLDSA65_Ed25519_SHA512); + algorithms.put("MLDSA87-ECDSA-P384-SHA512", MiscObjectIdentifiers.id_MLDSA87_ECDSA_P384_SHA512); + algorithms.put("MLDSA87-ECDSA-BRAINPOOLP384R1-SHA512", MiscObjectIdentifiers.id_MLDSA87_ECDSA_brainpoolP384r1_SHA512); + algorithms.put("MLDSA87-ED448-SHA512", MiscObjectIdentifiers.id_MLDSA87_Ed448_SHA512); + algorithms.put("FALCON512-ECDSA-P256-SHA256", MiscObjectIdentifiers.id_Falcon512_ECDSA_P256_SHA256); + algorithms.put("FALCON512-ECDSA-BRAINPOOLP256R1-SHA256", MiscObjectIdentifiers.id_Falcon512_ECDSA_brainpoolP256r1_SHA256); + algorithms.put("FALCON512-ED25519-SHA512", MiscObjectIdentifiers.id_Falcon512_Ed25519_SHA512); + // // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. // The parameters field SHALL be NULL for RSA based signature algorithms. @@ -266,6 +323,30 @@ public class DefaultSignatureAlgorithmIdentifierFinder // SPHINCS-PLUS // noParams.add(BCObjectIdentifiers.sphincsPlus); + noParams.add(NISTObjectIdentifiers.id_slh_dsa_sha2_128s); + noParams.add(NISTObjectIdentifiers.id_slh_dsa_sha2_128f); + noParams.add(NISTObjectIdentifiers.id_slh_dsa_sha2_192s); + noParams.add(NISTObjectIdentifiers.id_slh_dsa_sha2_192f); + noParams.add(NISTObjectIdentifiers.id_slh_dsa_sha2_256s); + noParams.add(NISTObjectIdentifiers.id_slh_dsa_sha2_256f); + noParams.add(NISTObjectIdentifiers.id_slh_dsa_shake_128s); + noParams.add(NISTObjectIdentifiers.id_slh_dsa_shake_128f); + noParams.add(NISTObjectIdentifiers.id_slh_dsa_shake_192s); + noParams.add(NISTObjectIdentifiers.id_slh_dsa_shake_192f); + noParams.add(NISTObjectIdentifiers.id_slh_dsa_shake_256s); + noParams.add(NISTObjectIdentifiers.id_slh_dsa_shake_256f); + noParams.add(NISTObjectIdentifiers.id_slh_dsa_sha2_128s); + noParams.add(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256); + noParams.add(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512); + noParams.add(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512); + noParams.add(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512); + noParams.add(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512); + noParams.add(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128); + noParams.add(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128); + noParams.add(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256); + noParams.add(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256); + noParams.add(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256); + noParams.add(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256); noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3); noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3); noParams.add(BCObjectIdentifiers.sphincsPlus_shake_128s_r3); @@ -284,14 +365,29 @@ public class DefaultSignatureAlgorithmIdentifierFinder noParams.add(BCObjectIdentifiers.sphincsPlus_shake_256f_r3); noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3); noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3); + noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_128s); + noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_128f); + noParams.add(BCObjectIdentifiers.sphincsPlus_shake_128s); + noParams.add(BCObjectIdentifiers.sphincsPlus_shake_128f); + noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_192s); + noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_192f); + noParams.add(BCObjectIdentifiers.sphincsPlus_shake_192s); + noParams.add(BCObjectIdentifiers.sphincsPlus_shake_192f); + noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_256s); + noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_256f); + noParams.add(BCObjectIdentifiers.sphincsPlus_shake_256s); + noParams.add(BCObjectIdentifiers.sphincsPlus_shake_256f); // // Dilithium // noParams.add(BCObjectIdentifiers.dilithium); - noParams.add(BCObjectIdentifiers.dilithium2); - noParams.add(BCObjectIdentifiers.dilithium3); - noParams.add(BCObjectIdentifiers.dilithium5); + noParams.add(NISTObjectIdentifiers.id_ml_dsa_44); + noParams.add(NISTObjectIdentifiers.id_ml_dsa_65); + noParams.add(NISTObjectIdentifiers.id_ml_dsa_87); + noParams.add(NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512); + noParams.add(NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512); + noParams.add(NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512); noParams.add(BCObjectIdentifiers.dilithium2_aes); noParams.add(BCObjectIdentifiers.dilithium3_aes); noParams.add(BCObjectIdentifiers.dilithium5_aes); @@ -322,6 +418,8 @@ public class DefaultSignatureAlgorithmIdentifierFinder noParams.add(BCObjectIdentifiers.xmss_mt_SHA512ph); noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE128ph); noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE256ph); + noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE128ph); + noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE256ph); noParams.add(BCObjectIdentifiers.xmss_SHA256); noParams.add(BCObjectIdentifiers.xmss_SHA512); @@ -362,6 +460,26 @@ public class DefaultSignatureAlgorithmIdentifierFinder noParams.add(CMSObjectIdentifiers.id_ecdsa_with_shake128); noParams.add(CMSObjectIdentifiers.id_ecdsa_with_shake256); + // + // Composite - Draft 13 + // + noParams.add(MiscObjectIdentifiers.id_MLDSA44_RSA2048_PSS_SHA256); + noParams.add(MiscObjectIdentifiers.id_MLDSA44_RSA2048_PKCS15_SHA256); + noParams.add(MiscObjectIdentifiers.id_MLDSA44_ECDSA_P256_SHA256); + noParams.add(MiscObjectIdentifiers.id_MLDSA44_ECDSA_brainpoolP256r1_SHA256); + noParams.add(MiscObjectIdentifiers.id_MLDSA44_Ed25519_SHA512); + noParams.add(MiscObjectIdentifiers.id_MLDSA65_RSA3072_PSS_SHA512); + noParams.add(MiscObjectIdentifiers.id_MLDSA65_RSA3072_PKCS15_SHA512); + noParams.add(MiscObjectIdentifiers.id_MLDSA65_ECDSA_brainpoolP256r1_SHA512); + noParams.add(MiscObjectIdentifiers.id_MLDSA65_ECDSA_P256_SHA512); + noParams.add(MiscObjectIdentifiers.id_MLDSA65_Ed25519_SHA512); + noParams.add(MiscObjectIdentifiers.id_MLDSA87_ECDSA_P384_SHA512); + noParams.add(MiscObjectIdentifiers.id_MLDSA87_ECDSA_brainpoolP384r1_SHA512); + noParams.add(MiscObjectIdentifiers.id_MLDSA87_Ed448_SHA512); + noParams.add(MiscObjectIdentifiers.id_Falcon512_ECDSA_P256_SHA256); + noParams.add(MiscObjectIdentifiers.id_Falcon512_ECDSA_brainpoolP256r1_SHA256); + noParams.add(MiscObjectIdentifiers.id_Falcon512_Ed25519_SHA512); + // // PKCS 1.5 encrypted algorithms // @@ -370,6 +488,8 @@ public class DefaultSignatureAlgorithmIdentifierFinder pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha256WithRSAEncryption); pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha384WithRSAEncryption); pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha512WithRSAEncryption); + pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha512_224WithRSAEncryption); + pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha512_256WithRSAEncryption); pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); @@ -415,6 +535,8 @@ public class DefaultSignatureAlgorithmIdentifierFinder digestOids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, NISTObjectIdentifiers.id_sha256); digestOids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, NISTObjectIdentifiers.id_sha384); digestOids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, NISTObjectIdentifiers.id_sha512); + digestOids.put(PKCSObjectIdentifiers.sha512_224WithRSAEncryption, NISTObjectIdentifiers.id_sha512_224); + digestOids.put(PKCSObjectIdentifiers.sha512_256WithRSAEncryption, NISTObjectIdentifiers.id_sha512_256); digestOids.put(NISTObjectIdentifiers.dsa_with_sha224, NISTObjectIdentifiers.id_sha224); digestOids.put(NISTObjectIdentifiers.dsa_with_sha256, NISTObjectIdentifiers.id_sha256); digestOids.put(NISTObjectIdentifiers.dsa_with_sha384, NISTObjectIdentifiers.id_sha384); @@ -457,6 +579,32 @@ public class DefaultSignatureAlgorithmIdentifierFinder digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3, NISTObjectIdentifiers.id_shake256); digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, NISTObjectIdentifiers.id_shake256); + + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128s, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128f, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128s, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128f, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192s, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192f, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192s, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192f, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256s, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256f, NISTObjectIdentifiers.id_sha256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s, NISTObjectIdentifiers.id_shake256); + digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f, NISTObjectIdentifiers.id_shake256); + // digestOids.put(GMObjectIdentifiers.sm2sign_with_rmd160, TeleTrusTObjectIdentifiers.ripemd160); // digestOids.put(GMObjectIdentifiers.sm2sign_with_sha1, OIWObjectIdentifiers.idSHA1); // digestOids.put(GMObjectIdentifiers.sm2sign_with_sha224, NISTObjectIdentifiers.id_sha224); @@ -471,44 +619,37 @@ public class DefaultSignatureAlgorithmIdentifierFinder digestOids.put(CMSObjectIdentifiers.id_ecdsa_with_shake256, NISTObjectIdentifiers.id_shake256); } - private static AlgorithmIdentifier generate(String signatureAlgorithm) + private static RSASSAPSSparams createPSSParams(AlgorithmIdentifier hashAlgId, int saltSize) { - AlgorithmIdentifier sigAlgId; + return new RSASSAPSSparams( + hashAlgId, + new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), + new ASN1Integer(saltSize), + new ASN1Integer(1)); + } - String algorithmName = Strings.toUpperCase(signatureAlgorithm); - ASN1ObjectIdentifier sigOID = (ASN1ObjectIdentifier)algorithms.get(algorithmName); + public AlgorithmIdentifier find(String sigAlgName) + { + String algorithmName = Strings.toUpperCase(sigAlgName); + ASN1ObjectIdentifier sigOID = (ASN1ObjectIdentifier) algorithms.get(algorithmName); if (sigOID == null) { - throw new IllegalArgumentException("Unknown signature type requested: " + algorithmName); + throw new IllegalArgumentException("Unknown signature type requested: " + sigAlgName); } + AlgorithmIdentifier sigAlgId; if (noParams.contains(sigOID)) { sigAlgId = new AlgorithmIdentifier(sigOID); } else if (params.containsKey(algorithmName)) { - sigAlgId = new AlgorithmIdentifier(sigOID, (ASN1Encodable)params.get(algorithmName)); + sigAlgId = new AlgorithmIdentifier(sigOID, (ASN1Encodable) params.get(algorithmName)); } else { sigAlgId = new AlgorithmIdentifier(sigOID, DERNull.INSTANCE); } - return sigAlgId; } - - private static RSASSAPSSparams createPSSParams(AlgorithmIdentifier hashAlgId, int saltSize) - { - return new RSASSAPSSparams( - hashAlgId, - new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), - new ASN1Integer(saltSize), - new ASN1Integer(1)); - } - - public AlgorithmIdentifier find(String sigAlgName) - { - return generate(sigAlgName); - } -} \ No newline at end of file +} diff --git a/pkix/src/main/java/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java b/pkix/src/main/java/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java index 6357d00e68..de2d680e62 100644 --- a/pkix/src/main/java/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java +++ b/pkix/src/main/java/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java @@ -16,9 +16,9 @@ public interface DigestAlgorithmIdentifierFinder /** * Find the algorithm identifier that matches with - * the passed in digest name. + * the passed in digest OID. * - * @param digestOid the name of the digest algorithm of interest. + * @param digestOid the OID of the digest algorithm of interest. * @return an algorithm identifier for the digest signature. */ AlgorithmIdentifier find(ASN1ObjectIdentifier digestOid); diff --git a/pkix/src/main/java/org/bouncycastle/operator/InputAEADDecryptor.java b/pkix/src/main/java/org/bouncycastle/operator/InputAEADDecryptor.java index 88adef4084..976d37859d 100644 --- a/pkix/src/main/java/org/bouncycastle/operator/InputAEADDecryptor.java +++ b/pkix/src/main/java/org/bouncycastle/operator/InputAEADDecryptor.java @@ -1,5 +1,6 @@ package org.bouncycastle.operator; + /** * Base interface for an input consuming AEAD Decryptor supporting associated text. */ diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcEdECContentSignerBuilder.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcEdECContentSignerBuilder.java new file mode 100644 index 0000000000..29bc3f6387 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/operator/bc/BcEdECContentSignerBuilder.java @@ -0,0 +1,28 @@ +package org.bouncycastle.operator.bc; + +import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.crypto.Signer; +import org.bouncycastle.crypto.signers.Ed25519Signer; +import org.bouncycastle.operator.OperatorCreationException; + +public class BcEdECContentSignerBuilder + extends BcContentSignerBuilder +{ + public BcEdECContentSignerBuilder(AlgorithmIdentifier sigAlgId) + { + super(sigAlgId, new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512)); + } + + protected Signer createSigner(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier digAlgId) + throws OperatorCreationException + { + if (sigAlgId.getAlgorithm().equals(EdECObjectIdentifiers.id_Ed25519)) + { + return new Ed25519Signer(); + } + + throw new IllegalStateException("unknown signature type"); + } +} diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java index d3e2b92440..f5acf8daa7 100644 --- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java @@ -46,12 +46,17 @@ public class JcaContentSignerBuilder { private static final Set isAlgIdFromPrivate = new HashSet(); + private static final DefaultSignatureAlgorithmIdentifierFinder SIGNATURE_ALGORITHM_IDENTIFIER_FINDER = new DefaultSignatureAlgorithmIdentifierFinder(); static { isAlgIdFromPrivate.add("DILITHIUM"); isAlgIdFromPrivate.add("SPHINCS+"); isAlgIdFromPrivate.add("SPHINCSPlus"); + isAlgIdFromPrivate.add("ML-DSA"); + isAlgIdFromPrivate.add("SLH-DSA"); + isAlgIdFromPrivate.add("HASH-ML-DSA"); + isAlgIdFromPrivate.add("HASH-SLH-DSA"); } private final String signatureAlgorithm; @@ -118,7 +123,8 @@ public JcaContentSignerBuilder setSecureRandom(SecureRandom random) public ContentSigner build(PrivateKey privateKey) throws OperatorCreationException { - if (privateKey instanceof CompositePrivateKey) + //Use this legacy method only for composite private keys (they have that identifier) + if (privateKey instanceof CompositePrivateKey && ((CompositePrivateKey)privateKey).getAlgorithmIdentifier().equals(MiscObjectIdentifiers.id_composite_key)) { return buildComposite((CompositePrivateKey)privateKey); } @@ -129,12 +135,16 @@ public ContentSigner build(PrivateKey privateKey) { if (isAlgIdFromPrivate.contains(Strings.toUpperCase(signatureAlgorithm))) { - sigAlgId = PrivateKeyInfo.getInstance(privateKey.getEncoded()).getPrivateKeyAlgorithm(); + this.sigAlgId = SIGNATURE_ALGORITHM_IDENTIFIER_FINDER.find(privateKey.getAlgorithm()); + if (this.sigAlgId == null) + { + this.sigAlgId = PrivateKeyInfo.getInstance(privateKey.getEncoded()).getPrivateKeyAlgorithm(); + } this.sigAlgSpec = null; } else { - this.sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(signatureAlgorithm); + this.sigAlgId = SIGNATURE_ALGORITHM_IDENTIFIER_FINDER.find(signatureAlgorithm); this.sigAlgSpec = null; } } @@ -296,7 +306,7 @@ private static ASN1Sequence createCompParams(CompositeAlgorithmSpec compSpec) } else if (sigSpec instanceof PSSParameterSpec) { - v.add(createPSSParams((PSSParameterSpec)sigSpec)); + v.add(new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS, createPSSParams((PSSParameterSpec)sigSpec))); } else { diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java index ed575e0744..0c28215d3c 100644 --- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java @@ -11,8 +11,8 @@ import java.security.cert.X509Certificate; import java.util.List; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; @@ -143,7 +143,8 @@ public ContentVerifier get(AlgorithmIdentifier algorithm) return createCompositeVerifier(algorithm, publicKey); } - if (publicKey instanceof CompositePublicKey) + //Use this legacy method only for composite public keys (they have that identifier) + if (publicKey instanceof CompositePublicKey && ((CompositePublicKey)publicKey).getAlgorithmIdentifier().equals(MiscObjectIdentifiers.id_composite_key)) { List keys = ((CompositePublicKey)publicKey).getPublicKeys(); @@ -433,7 +434,7 @@ public boolean verify(byte[] expected) { if (sigs[i] != null) { - if (!sigs[i].verify(DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes())) + if (!sigs[i].verify(ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getOctets())) { failed = true; } diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/DeltaCertAttributeUtils.java b/pkix/src/main/java/org/bouncycastle/pkcs/DeltaCertAttributeUtils.java new file mode 100644 index 0000000000..be78db656a --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkcs/DeltaCertAttributeUtils.java @@ -0,0 +1,57 @@ +package org.bouncycastle.pkcs; + +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.DERSet; +import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.pkcs.Attribute; +import org.bouncycastle.asn1.pkcs.CertificationRequest; +import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; +import org.bouncycastle.operator.ContentVerifierProvider; + +public class DeltaCertAttributeUtils +{ + public static boolean isDeltaRequestSignatureValid(PKCS10CertificationRequest baseRequest, ContentVerifierProvider contentVerifierProvider) + throws PKCSException + { + Attribute[] attributes = baseRequest.getAttributes(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.2")); + + DeltaCertificateRequestAttributeValue deltaReq = new DeltaCertificateRequestAttributeValue(attributes[0]); + + attributes = baseRequest.getAttributes(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.3")); + + CertificationRequest deltaPkcs10 = baseRequest.toASN1Structure(); + CertificationRequestInfo deltaInfo = deltaPkcs10.getCertificationRequestInfo(); + + ASN1EncodableVector deltaPkcs10InfoV = new ASN1EncodableVector(); + deltaPkcs10InfoV.add(deltaInfo.getVersion()); + deltaPkcs10InfoV.add(deltaInfo.getSubject()); + deltaPkcs10InfoV.add(deltaInfo.getSubjectPublicKeyInfo()); + + ASN1EncodableVector attrSetV = new ASN1EncodableVector(); + for (Enumeration en = deltaInfo.getAttributes().getObjects(); en.hasMoreElements();) + { + Attribute attr = Attribute.getInstance(en.nextElement()); + + if (!attr.getAttrType().equals(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.3"))) + { + attrSetV.add(attr); + } + } + + deltaPkcs10InfoV.add(new DERTaggedObject(false, 0, new DERSet(attrSetV))); + + ASN1EncodableVector deltaPkcs10V = new ASN1EncodableVector(); + + deltaPkcs10V.add(new DERSequence(deltaPkcs10InfoV)); + deltaPkcs10V.add(deltaReq.getSignatureAlgorithm()); + deltaPkcs10V.add(attributes[0].getAttributeValues()[0]); + + PKCS10CertificationRequest deltaPkcs10Req = new PKCS10CertificationRequest(CertificationRequest.getInstance(new DERSequence(deltaPkcs10V))); + + return deltaPkcs10Req.isSignatureValid(contentVerifierProvider); + } +} diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValue.java b/pkix/src/main/java/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValue.java new file mode 100644 index 0000000000..58aec1dadd --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValue.java @@ -0,0 +1,102 @@ +package org.bouncycastle.pkcs; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.pkcs.Attribute; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.Extensions; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; + +/** + * The delta certificate request attribute defined in: https://datatracker.ietf.org/doc/draft-bonnell-lamps-chameleon-certs/ + */ +public class DeltaCertificateRequestAttributeValue + implements ASN1Encodable +{ + private final X500Name subject; + private final SubjectPublicKeyInfo subjectPKInfo; + private final Extensions extensions; + private final AlgorithmIdentifier signatureAlgorithm; + private final ASN1Sequence attrSeq; + + public DeltaCertificateRequestAttributeValue(Attribute attribute) + { + this(ASN1Sequence.getInstance(attribute.getAttributeValues()[0])); + } + + DeltaCertificateRequestAttributeValue(ASN1Sequence attrSeq) + { + this.attrSeq = attrSeq; + // TODO: validate attribute size + + int idx = 0; + if (attrSeq.getObjectAt(0) instanceof ASN1TaggedObject) + { + subject = X500Name.getInstance(ASN1TaggedObject.getInstance(attrSeq.getObjectAt(0)), true); + idx++; + } + else + { + subject = null; + } + + subjectPKInfo = SubjectPublicKeyInfo.getInstance(attrSeq.getObjectAt(idx)); + idx++; + + Extensions ext = null; + AlgorithmIdentifier sigAlg = null; + + if (idx != attrSeq.size()) + { + while (idx < attrSeq.size()) + { + ASN1TaggedObject tagObj = ASN1TaggedObject.getInstance(attrSeq.getObjectAt(idx)); + if (tagObj.getTagNo() == 1) + { + ext = Extensions.getInstance(tagObj, false); + } + else if (tagObj.getTagNo() == 2) + { + sigAlg = AlgorithmIdentifier.getInstance(tagObj, false); + } + else + { + throw new IllegalArgumentException("unknown tag"); + } + idx++; + } + } + + this.extensions = ext; + this.signatureAlgorithm = sigAlg; + } + + public X500Name getSubject() + { + return subject; + } + + public SubjectPublicKeyInfo getSubjectPKInfo() + { + return subjectPKInfo; + } + + public Extensions getExtensions() + { + return extensions; + } + + public AlgorithmIdentifier getSignatureAlgorithm() + { + return signatureAlgorithm; + } + + @Override + public ASN1Primitive toASN1Primitive() + { + return attrSeq; + } +} diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValueBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValueBuilder.java new file mode 100644 index 0000000000..1c844f287a --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValueBuilder.java @@ -0,0 +1,57 @@ +package org.bouncycastle.pkcs; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.DERSet; +import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.pkcs.Attribute; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; + +public class DeltaCertificateRequestAttributeValueBuilder +{ + private final SubjectPublicKeyInfo subjectPublicKey; + + private AlgorithmIdentifier signatureAlgorithm; + private X500Name subject; + + public DeltaCertificateRequestAttributeValueBuilder(SubjectPublicKeyInfo subjectPublicKey) + { + this.subjectPublicKey = subjectPublicKey; + } + + public DeltaCertificateRequestAttributeValueBuilder setSignatureAlgorithm(AlgorithmIdentifier signatureAlgorithm) + { + this.signatureAlgorithm = signatureAlgorithm; + + return this; + } + + public DeltaCertificateRequestAttributeValueBuilder setSubject(X500Name subject) + { + this.subject = subject; + + return this; + } + + public DeltaCertificateRequestAttributeValue build() + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + if (subject != null) + { + v.add(new DERTaggedObject(false, 0, subject)); + } + v.add(subjectPublicKey); + if (signatureAlgorithm != null) + { + v.add(new DERTaggedObject(false, 2, signatureAlgorithm)); + } + + + return new DeltaCertificateRequestAttributeValue(new Attribute(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.2"), + new DERSet(new DERSequence(v)))); + } +} diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequest.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequest.java index bbc0b510df..ad470c89a8 100644 --- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequest.java +++ b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequest.java @@ -6,19 +6,24 @@ import java.util.Enumeration; import java.util.List; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1Boolean; +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; @@ -33,7 +38,11 @@ public class PKCS10CertificationRequest { private static Attribute[] EMPTY_ARRAY = new Attribute[0]; - private CertificationRequest certificationRequest; + private final CertificationRequest certificationRequest; + private final boolean isAltRequest; + private final AlgorithmIdentifier altSignature; + private final SubjectPublicKeyInfo altPublicKey; + private final ASN1BitString altSignatureValue; private static CertificationRequest parseBytes(byte[] encoding) throws IOException @@ -59,8 +68,19 @@ private static CertificationRequest parseBytes(byte[] encoding) } } + private static ASN1Encodable getSingleValue(Attribute at) + { + ASN1Encodable[] attrValues = at.getAttributeValues(); + if (attrValues.length!= 1) + { + throw new IllegalArgumentException("single value attribute value not size of 1"); + } + + return attrValues[0]; + } + /** - * Create a PKCS10CertificationRequestHolder from an underlying ASN.1 structure. + * Create a PKCS10CertificationRequest from an underlying ASN.1 structure. * * @param certificationRequest the underlying ASN.1 structure representing a request. */ @@ -71,10 +91,50 @@ public PKCS10CertificationRequest(CertificationRequest certificationRequest) throw new NullPointerException("certificationRequest cannot be null"); } this.certificationRequest = certificationRequest; + + ASN1Set attributes = certificationRequest.getCertificationRequestInfo().getAttributes(); + + AlgorithmIdentifier altSig = null; + SubjectPublicKeyInfo altPub = null; + ASN1BitString altSigValue = null; + + if (attributes != null) + { + for (Enumeration en = attributes.getObjects(); en.hasMoreElements();) + { + Attribute at = Attribute.getInstance(en.nextElement()); + + if (Extension.altSignatureAlgorithm.equals(at.getAttrType())) + { + altSig = AlgorithmIdentifier.getInstance(getSingleValue(at)); + } + if (Extension.subjectAltPublicKeyInfo.equals(at.getAttrType())) + { + altPub = SubjectPublicKeyInfo.getInstance(getSingleValue(at)); + } + if (Extension.altSignatureValue.equals(at.getAttrType())) + { + altSigValue = ASN1BitString.getInstance(getSingleValue(at)); + } + } + } + + this.isAltRequest = (altSig != null) | (altPub != null) | (altSigValue != null); + if (isAltRequest) + { + if (!((altSig != null) & (altPub != null) & (altSigValue != null))) + { + throw new IllegalArgumentException("invalid alternate public key details found"); + } + } + + this.altSignature = altSig; + this.altPublicKey = altPub; + this.altSignatureValue = altSigValue; } /** - * Create a PKCS10CertificationRequestHolder from the passed in bytes. + * Create a PKCS10CertificationRequest from the passed in bytes. * * @param encoded BER/DER encoding of the CertificationRequest structure. * @throws IOException in the event of corrupted data, or an incorrect structure. @@ -231,6 +291,68 @@ public boolean isSignatureValid(ContentVerifierProvider verifierProvider) return verifier.verify(this.getSignature()); } + /** + * Return true if the certification request has an alternate public key present. + * + * @return true if this is a dual key request, false otherwise. + */ + public boolean hasAltPublicKey() + { + return isAltRequest; + } + + /** + * Validate the alternate signature on the PKCS10 certification request in this holder. + * + * @param verifierProvider a ContentVerifierProvider that can generate a verifier for the signature. + * @return true if the alternate signature is valid, false otherwise. + * @throws PKCSException if the signature cannot be processed or is inappropriate. + */ + public boolean isAltSignatureValid(ContentVerifierProvider verifierProvider) + throws PKCSException + { + if (!isAltRequest) + { + throw new IllegalStateException("no alternate public key present"); + } + + CertificationRequestInfo requestInfo = certificationRequest.getCertificationRequestInfo(); + ASN1Set attributes = requestInfo.getAttributes(); + ASN1EncodableVector atV = new ASN1EncodableVector(); + + for (Enumeration en = attributes.getObjects(); en.hasMoreElements();) + { + Attribute at = Attribute.getInstance(en.nextElement()); + + if (Extension.altSignatureValue.equals(at.getAttrType())) + { + continue; + } + + atV.add(at); + } + + requestInfo = new CertificationRequestInfo(requestInfo.getSubject(), requestInfo.getSubjectPublicKeyInfo(), new DERSet(atV)); + ContentVerifier verifier; + + try + { + verifier = verifierProvider.get(this.altSignature); + + OutputStream sOut = verifier.getOutputStream(); + + sOut.write(requestInfo.getEncoded(ASN1Encoding.DER)); + + sOut.close(); + } + catch (Exception e) + { + throw new PKCSException("unable to process signature: " + e.getMessage(), e); + } + + return verifier.verify(this.altSignatureValue.getOctets()); + } + /** * Return any extensions requested in the PKCS#10 request. If none are present, the method * will return null. diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequestBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequestBuilder.java index dd481958b9..9fd70b209e 100644 --- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequestBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequestBuilder.java @@ -16,6 +16,7 @@ import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.operator.ContentSigner; @@ -160,7 +161,7 @@ public PKCS10CertificationRequestBuilder setLeaveOffEmptyAttributes(boolean leav /** * Generate an PKCS#10 request based on the past in signer. * - * @param signer the content signer to be used to generate the signature validating the certificate. + * @param signer the content signer to be used to generate the signature validating the certification request. * @return a holder containing the resulting PKCS#10 certification request. */ public PKCS10CertificationRequest build( @@ -206,4 +207,68 @@ public PKCS10CertificationRequest build( throw new IllegalStateException("cannot produce certification request signature"); } } + + /** + * Generate a PKCS10 certificate request, based on the current issuer and subject + * using the passed in signer and containing altSignatureAlgorithm. altSubjectPublicKeyInfo, and altSignatureValue attributes + * based on the passed altSigner. + * + * @param signer the content signer to be used to generate the signature validating the certification request. + * @param altPublicKey the public key to verify the altSignatureValue generated as part of this build. + * @param altSigner the content signer used to create the altSignatureAlgorithm and altSignatureValue extension. + * @return a holder containing the resulting signed certificate. + */ + public PKCS10CertificationRequest build( + ContentSigner signer, + SubjectPublicKeyInfo altPublicKey, + ContentSigner altSigner) + { + CertificationRequestInfo info; + + ASN1EncodableVector v = new ASN1EncodableVector(); + + for (Iterator it = attributes.iterator(); it.hasNext(); ) + { + v.add(Attribute.getInstance(it.next())); + } + + v.add(new Attribute(Extension.subjectAltPublicKeyInfo, new DERSet(altPublicKey))); + v.add(new Attribute(Extension.altSignatureAlgorithm, new DERSet(altSigner.getAlgorithmIdentifier()))); + + info = new CertificationRequestInfo(subject, publicKeyInfo, new DERSet(v)); + + // add altSignatureValue + try + { + OutputStream sOut = altSigner.getOutputStream(); + + sOut.write(info.getEncoded(ASN1Encoding.DER)); + + sOut.close(); + + v.add(new Attribute(Extension.altSignatureValue, new DERSet(new DERBitString(altSigner.getSignature())))); + + info = new CertificationRequestInfo(subject, publicKeyInfo, new DERSet(v)); + } + catch (IOException e) + { + throw new IllegalStateException("cannot produce certification request signature"); + } + + // create final request + try + { + OutputStream sOut = signer.getOutputStream(); + + sOut.write(info.getEncoded(ASN1Encoding.DER)); + + sOut.close(); + + return new PKCS10CertificationRequest(new CertificationRequest(info, signer.getAlgorithmIdentifier(), new DERBitString(signer.getSignature()))); + } + catch (IOException e) + { + throw new IllegalStateException("cannot produce certification request signature"); + } + } } diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java index e578fd53bd..f12a6451fb 100644 --- a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java @@ -56,7 +56,7 @@ public InputStream getInputStream(InputStream input) public GenericKey getKey() { - return new GenericKey(PKCS12ParametersGenerator.PKCS12PasswordToBytes(password)); + return new GenericKey(algorithmIdentifier, PKCS12ParametersGenerator.PKCS12PasswordToBytes(password)); } }; } diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequest.java b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequest.java index db57d0ff38..6b445aba34 100644 --- a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequest.java +++ b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequest.java @@ -33,6 +33,7 @@ public class JcaPKCS10CertificationRequest // keyAlgorithms.put(PKCSObjectIdentifiers.rsaEncryption, "RSA"); keyAlgorithms.put(X9ObjectIdentifiers.id_dsa, "DSA"); + keyAlgorithms.put(X9ObjectIdentifiers.id_ecPublicKey, "EC"); } private JcaJceHelper helper = new DefaultJcaJceHelper(); diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java index 5466e5f7f3..af38bf5760 100644 --- a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java @@ -6,6 +6,8 @@ import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; /** @@ -35,4 +37,12 @@ public JcaPKCS10CertificationRequestBuilder(X500Principal subject, PublicKey pub { super(X500Name.getInstance(subject.getEncoded()), SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); } + + public PKCS10CertificationRequest build( + ContentSigner signer, + PublicKey altPublicKey, + ContentSigner altSigner) + { + return super.build(signer, SubjectPublicKeyInfo.getInstance(altPublicKey.getEncoded()), altSigner); + } } diff --git a/pkix/src/main/java/org/bouncycastle/pkix/ASN1PKIXNameConstraintValidator.java b/pkix/src/main/java/org/bouncycastle/pkix/ASN1PKIXNameConstraintValidator.java new file mode 100644 index 0000000000..d77afc712a --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/ASN1PKIXNameConstraintValidator.java @@ -0,0 +1,2152 @@ +package org.bouncycastle.pkix; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.bouncycastle.asn1.ASN1IA5String; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.x500.RDN; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.style.IETFUtils; +import org.bouncycastle.asn1.x500.style.RFC4519Style; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralSubtree; +import org.bouncycastle.asn1.x509.NameConstraintValidator; +import org.bouncycastle.asn1.x509.NameConstraintValidatorException; +import org.bouncycastle.asn1.x509.OtherName; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Integers; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Hex; + +class ASN1PKIXNameConstraintValidator + implements NameConstraintValidator +{ + private Set excludedSubtreesDN = new HashSet(); + + private Set excludedSubtreesDNS = new HashSet(); + + private Set excludedSubtreesEmail = new HashSet(); + + private Set excludedSubtreesURI = new HashSet(); + + private Set excludedSubtreesIP = new HashSet(); + + private Set excludedSubtreesOtherName = new HashSet(); + + private Set permittedSubtreesDN; + + private Set permittedSubtreesDNS; + + private Set permittedSubtreesEmail; + + private Set permittedSubtreesURI; + + private Set permittedSubtreesIP; + + private Set permittedSubtreesOtherName; + + public ASN1PKIXNameConstraintValidator() + { + } + + /** + * Checks if the given GeneralName is in the permitted set. + * + * @param name The GeneralName + * @throws NameConstraintValidatorException If the name + */ + public void checkPermitted(GeneralName name) + throws NameConstraintValidatorException + { + switch (name.getTagNo()) + { + case GeneralName.otherName: + checkPermittedOtherName(permittedSubtreesOtherName, OtherName.getInstance(name.getName())); + break; + case GeneralName.rfc822Name: + checkPermittedEmail(permittedSubtreesEmail, + extractNameAsString(name)); + break; + case GeneralName.dNSName: + checkPermittedDNS(permittedSubtreesDNS, ASN1IA5String.getInstance( + name.getName()).getString()); + break; + case GeneralName.directoryName: + checkPermittedDN(X500Name.getInstance(name.getName())); + break; + case GeneralName.uniformResourceIdentifier: + checkPermittedURI(permittedSubtreesURI, ASN1IA5String.getInstance( + name.getName()).getString()); + break; + case GeneralName.iPAddress: + byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets(); + + checkPermittedIP(permittedSubtreesIP, ip); + break; + default: + // other tags to be ignored. + } + } + + /** + * Check if the given GeneralName is contained in the excluded set. + * + * @param name The GeneralName. + * @throws NameConstraintValidatorException If the name is + * excluded. + */ + public void checkExcluded(GeneralName name) + throws NameConstraintValidatorException + { + switch (name.getTagNo()) + { + case GeneralName.otherName: + checkExcludedOtherName(excludedSubtreesOtherName, OtherName.getInstance(name.getName())); + break; + case GeneralName.rfc822Name: + checkExcludedEmail(excludedSubtreesEmail, extractNameAsString(name)); + break; + case GeneralName.dNSName: + checkExcludedDNS(excludedSubtreesDNS, ASN1IA5String.getInstance( + name.getName()).getString()); + break; + case GeneralName.directoryName: + checkExcludedDN(X500Name.getInstance(name.getName())); + break; + case GeneralName.uniformResourceIdentifier: + checkExcludedURI(excludedSubtreesURI, ASN1IA5String.getInstance( + name.getName()).getString()); + break; + case GeneralName.iPAddress: + byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets(); + + checkExcludedIP(excludedSubtreesIP, ip); + break; + default: + // other tags to be ignored. + } + } + + public void intersectPermittedSubtree(GeneralSubtree permitted) + { + intersectPermittedSubtree(new GeneralSubtree[]{permitted}); + } + + /** + * Updates the permitted set of these name constraints with the intersection + * with the given subtree. + * + * @param permitted The permitted subtrees + */ + public void intersectPermittedSubtree(GeneralSubtree[] permitted) + { + Map subtreesMap = new HashMap(); + + // group in sets in a map ordered by tag no. + for (int i = 0; i != permitted.length; i++) + { + GeneralSubtree subtree = permitted[i]; + Integer tagNo = Integers.valueOf(subtree.getBase().getTagNo()); + if (subtreesMap.get(tagNo) == null) + { + subtreesMap.put(tagNo, new HashSet()); + } + ((Set)subtreesMap.get(tagNo)).add(subtree); + } + + for (Iterator it = subtreesMap.entrySet().iterator(); it.hasNext();) + { + Map.Entry entry = (Map.Entry)it.next(); + + // go through all subtree groups + int nameType = ((Integer)entry.getKey()).intValue(); + switch (nameType) + { + case GeneralName.otherName: + permittedSubtreesOtherName = intersectOtherName(permittedSubtreesOtherName, + (Set)entry.getValue()); + break; + case GeneralName.rfc822Name: + permittedSubtreesEmail = intersectEmail(permittedSubtreesEmail, + (Set)entry.getValue()); + break; + case GeneralName.dNSName: + permittedSubtreesDNS = intersectDNS(permittedSubtreesDNS, + (Set)entry.getValue()); + break; + case GeneralName.directoryName: + permittedSubtreesDN = intersectDN(permittedSubtreesDN, + (Set)entry.getValue()); + break; + case GeneralName.uniformResourceIdentifier: + permittedSubtreesURI = intersectURI(permittedSubtreesURI, + (Set)entry.getValue()); + break; + case GeneralName.iPAddress: + permittedSubtreesIP = intersectIP(permittedSubtreesIP, + (Set)entry.getValue()); + break; + default: + throw new IllegalStateException("Unknown tag encountered: " + nameType); + } + } + } + + public void intersectEmptyPermittedSubtree(int nameType) + { + switch (nameType) + { + case GeneralName.otherName: + permittedSubtreesOtherName = new HashSet(); + break; + case GeneralName.rfc822Name: + permittedSubtreesEmail = new HashSet(); + break; + case GeneralName.dNSName: + permittedSubtreesDNS = new HashSet(); + break; + case GeneralName.directoryName: + permittedSubtreesDN = new HashSet(); + break; + case GeneralName.uniformResourceIdentifier: + permittedSubtreesURI = new HashSet(); + break; + case GeneralName.iPAddress: + permittedSubtreesIP = new HashSet(); + break; + default: + throw new IllegalStateException("Unknown tag encountered: " + nameType); + } + } + + /** + * Adds a subtree to the excluded set of these name constraints. + * + * @param subtree A subtree with an excluded GeneralName. + */ + public void addExcludedSubtree(GeneralSubtree subtree) + { + GeneralName base = subtree.getBase(); + + switch (base.getTagNo()) + { + case GeneralName.otherName: + excludedSubtreesOtherName = unionOtherName(excludedSubtreesOtherName, + OtherName.getInstance(base.getName())); + break; + case GeneralName.rfc822Name: + excludedSubtreesEmail = unionEmail(excludedSubtreesEmail, + extractNameAsString(base)); + break; + case GeneralName.dNSName: + excludedSubtreesDNS = unionDNS(excludedSubtreesDNS, + extractNameAsString(base)); + break; + case GeneralName.directoryName: + excludedSubtreesDN = unionDN(excludedSubtreesDN, + (ASN1Sequence)base.getName().toASN1Primitive()); + break; + case GeneralName.uniformResourceIdentifier: + excludedSubtreesURI = unionURI(excludedSubtreesURI, + extractNameAsString(base)); + break; + case GeneralName.iPAddress: + excludedSubtreesIP = unionIP(excludedSubtreesIP, ASN1OctetString + .getInstance(base.getName()).getOctets()); + break; + default: + throw new IllegalStateException("Unknown tag encountered: " + base.getTagNo()); + } + } + + public int hashCode() + { + return hashCollection(excludedSubtreesDN) + + hashCollection(excludedSubtreesDNS) + + hashCollection(excludedSubtreesEmail) + + hashCollection(excludedSubtreesIP) + + hashCollection(excludedSubtreesURI) + + hashCollection(excludedSubtreesOtherName) + + hashCollection(permittedSubtreesDN) + + hashCollection(permittedSubtreesDNS) + + hashCollection(permittedSubtreesEmail) + + hashCollection(permittedSubtreesIP) + + hashCollection(permittedSubtreesURI) + + hashCollection(permittedSubtreesOtherName); + } + + public boolean equals(Object o) + { + if (!(o instanceof ASN1PKIXNameConstraintValidator)) + { + return false; + } + ASN1PKIXNameConstraintValidator constraintValidator = (ASN1PKIXNameConstraintValidator)o; + return collectionsAreEqual(constraintValidator.excludedSubtreesDN, excludedSubtreesDN) + && collectionsAreEqual(constraintValidator.excludedSubtreesDNS, excludedSubtreesDNS) + && collectionsAreEqual(constraintValidator.excludedSubtreesEmail, excludedSubtreesEmail) + && collectionsAreEqual(constraintValidator.excludedSubtreesIP, excludedSubtreesIP) + && collectionsAreEqual(constraintValidator.excludedSubtreesURI, excludedSubtreesURI) + && collectionsAreEqual(constraintValidator.excludedSubtreesOtherName, excludedSubtreesOtherName) + && collectionsAreEqual(constraintValidator.permittedSubtreesDN, permittedSubtreesDN) + && collectionsAreEqual(constraintValidator.permittedSubtreesDNS, permittedSubtreesDNS) + && collectionsAreEqual(constraintValidator.permittedSubtreesEmail, permittedSubtreesEmail) + && collectionsAreEqual(constraintValidator.permittedSubtreesIP, permittedSubtreesIP) + && collectionsAreEqual(constraintValidator.permittedSubtreesURI, permittedSubtreesURI) + && collectionsAreEqual(constraintValidator.permittedSubtreesOtherName, permittedSubtreesOtherName); + } + + public void checkPermittedDN(X500Name dns) + throws NameConstraintValidatorException + { + checkPermittedDN(permittedSubtreesDN, ASN1Sequence.getInstance(dns.toASN1Primitive())); + } + + public void checkExcludedDN(X500Name dns) + throws NameConstraintValidatorException + { + checkExcludedDN(excludedSubtreesDN, ASN1Sequence.getInstance(dns)); + } + + private static boolean withinDNSubtree( + ASN1Sequence dns, + ASN1Sequence subtree) + { + if (subtree.size() < 1) + { + return false; + } + + if (subtree.size() > dns.size()) + { + return false; + } + + int start = 0; + RDN subtreeRdnStart = RDN.getInstance(subtree.getObjectAt(0)); + for (int j = 0; j < dns.size(); j++) + { + start = j; + RDN dnsRdn = RDN.getInstance(dns.getObjectAt(j)); + if (dnsRdn.equals(subtreeRdnStart)) + { + break; + } + } + + if (subtree.size() > dns.size() - start) + { + return false; + } + + for (int j = 0; j < subtree.size(); j++) + { + // both subtree and dns are a ASN.1 Name and the elements are a RDN + RDN subtreeRdn = RDN.getInstance(subtree.getObjectAt(j)); + RDN dnsRdn = RDN.getInstance(dns.getObjectAt(start + j)); + + // check if types and values of all naming attributes are matching, other types which are not restricted are allowed, see https://tools.ietf.org/html/rfc5280#section-7.1 + if (subtreeRdn.size() == dnsRdn.size()) + { + // Two relative distinguished names + // RDN1 and RDN2 match if they have the same number of naming attributes + // and for each naming attribute in RDN1 there is a matching naming attribute in RDN2. + // NOTE: this is checking the attributes in the same order, which might be not necessary, if this is a problem also IETFUtils.rDNAreEqual mus tbe changed. + // use new RFC 5280 comparison, NOTE: this is now different from with RFC 3280, where only binary comparison is used + // obey RFC 5280 7.1 + // special treatment of serialNumber for GSMA SGP.22 RSP specification + if (!subtreeRdn.getFirst().getType().equals(dnsRdn.getFirst().getType())) + { + return false; + } + if (subtreeRdn.size() == 1 && subtreeRdn.getFirst().getType().equals(RFC4519Style.serialNumber)) + { + if (!dnsRdn.getFirst().getValue().toString().startsWith(subtreeRdn.getFirst().getValue().toString())) + { + return false; + } + } + else if (!IETFUtils.rDNAreEqual(subtreeRdn, dnsRdn)) + { + return false; + } + } + else + { + return false; + } + } + + return true; + } + + private void checkPermittedDN(Set permitted, ASN1Sequence dns) + throws NameConstraintValidatorException + { + if (permitted == null) + { + return; + } + + if (permitted.isEmpty() && dns.size() == 0) + { + return; + } + Iterator it = permitted.iterator(); + + while (it.hasNext()) + { + ASN1Sequence subtree = (ASN1Sequence)it.next(); + + if (withinDNSubtree(dns, subtree)) + { + return; + } + } + + throw new NameConstraintValidatorException( + "Subject distinguished name is not from a permitted subtree"); + } + + private void checkExcludedDN(Set excluded, ASN1Sequence dns) + throws NameConstraintValidatorException + { + if (excluded.isEmpty()) + { + return; + } + + Iterator it = excluded.iterator(); + + while (it.hasNext()) + { + ASN1Sequence subtree = (ASN1Sequence)it.next(); + + if (withinDNSubtree(dns, subtree)) + { + throw new NameConstraintValidatorException( + "Subject distinguished name is from an excluded subtree"); + } + } + } + + private Set intersectDN(Set permitted, Set dns) + { + Set intersect = new HashSet(); + for (Iterator it = dns.iterator(); it.hasNext();) + { + ASN1Sequence dn = ASN1Sequence.getInstance(((GeneralSubtree)it + .next()).getBase().getName().toASN1Primitive()); + if (permitted == null) + { + if (dn != null) + { + intersect.add(dn); + } + } + else + { + Iterator _iter = permitted.iterator(); + while (_iter.hasNext()) + { + ASN1Sequence subtree = (ASN1Sequence)_iter.next(); + + if (withinDNSubtree(dn, subtree)) + { + intersect.add(dn); + } + else if (withinDNSubtree(subtree, dn)) + { + intersect.add(subtree); + } + } + } + } + return intersect; + } + + private Set unionDN(Set excluded, ASN1Sequence dn) + { + if (excluded.isEmpty()) + { + if (dn == null) + { + return excluded; + } + excluded.add(dn); + + return excluded; + } + else + { + Set intersect = new HashSet(); + + Iterator it = excluded.iterator(); + while (it.hasNext()) + { + ASN1Sequence subtree = (ASN1Sequence)it.next(); + + if (withinDNSubtree(dn, subtree)) + { + intersect.add(subtree); + } + else if (withinDNSubtree(subtree, dn)) + { + intersect.add(dn); + } + else + { + intersect.add(subtree); + intersect.add(dn); + } + } + + return intersect; + } + } + + private Set intersectOtherName(Set permitted, Set otherNames) + { + Set intersect = new HashSet(permitted); + + intersect.retainAll(otherNames); + + return intersect; + } + + + private Set unionOtherName(Set permitted, OtherName otherName) + { + Set union = new HashSet(permitted); + + union.add(otherName); + + return union; + } + + private Set intersectEmail(Set permitted, Set emails) + { + Set intersect = new HashSet(); + for (Iterator it = emails.iterator(); it.hasNext();) + { + String email = extractNameAsString(((GeneralSubtree)it.next()) + .getBase()); + + if (permitted == null) + { + if (email != null) + { + intersect.add(email); + } + } + else + { + Iterator it2 = permitted.iterator(); + while (it2.hasNext()) + { + String _permitted = (String)it2.next(); + + intersectEmail(email, _permitted, intersect); + } + } + } + return intersect; + } + + private Set unionEmail(Set excluded, String email) + { + if (excluded.isEmpty()) + { + if (email == null) + { + return excluded; + } + excluded.add(email); + return excluded; + } + else + { + Set union = new HashSet(); + + Iterator it = excluded.iterator(); + while (it.hasNext()) + { + String _excluded = (String)it.next(); + + unionEmail(_excluded, email, union); + } + + return union; + } + } + + /** + * Returns the intersection of the permitted IP ranges in + * permitted with ip. + * + * @param permitted A Set of permitted IP addresses with + * their subnet mask as byte arrays. + * @param ips The IP address with its subnet mask. + * @return The Set of permitted IP ranges intersected with + * ip. + */ + private Set intersectIP(Set permitted, Set ips) + { + Set intersect = new HashSet(); + for (Iterator it = ips.iterator(); it.hasNext();) + { + byte[] ip = ASN1OctetString.getInstance( + ((GeneralSubtree)it.next()).getBase().getName()).getOctets(); + if (permitted == null) + { + if (ip != null) + { + intersect.add(ip); + } + } + else + { + Iterator it2 = permitted.iterator(); + while (it2.hasNext()) + { + byte[] _permitted = (byte[])it2.next(); + intersect.addAll(intersectIPRange(_permitted, ip)); + } + } + } + return intersect; + } + + /** + * Returns the union of the excluded IP ranges in excluded + * with ip. + * + * @param excluded A Set of excluded IP addresses with their + * subnet mask as byte arrays. + * @param ip The IP address with its subnet mask. + * @return The Set of excluded IP ranges unified with + * ip as byte arrays. + */ + private Set unionIP(Set excluded, byte[] ip) + { + if (excluded.isEmpty()) + { + if (ip == null) + { + return excluded; + } + excluded.add(ip); + + return excluded; + } + else + { + Set union = new HashSet(); + + Iterator it = excluded.iterator(); + while (it.hasNext()) + { + byte[] _excluded = (byte[])it.next(); + union.addAll(unionIPRange(_excluded, ip)); + } + + return union; + } + } + + /** + * Calculates the union if two IP ranges. + * + * @param ipWithSubmask1 The first IP address with its subnet mask. + * @param ipWithSubmask2 The second IP address with its subnet mask. + * @return A Set with the union of both addresses. + */ + private Set unionIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2) + { + Set set = new HashSet(); + + // difficult, adding always all IPs is not wrong + if (Arrays.areEqual(ipWithSubmask1, ipWithSubmask2)) + { + set.add(ipWithSubmask1); + } + else + { + set.add(ipWithSubmask1); + set.add(ipWithSubmask2); + } + return set; + } + + /** + * Calculates the intersection if two IP ranges. + * + * @param ipWithSubmask1 The first IP address with its subnet mask. + * @param ipWithSubmask2 The second IP address with its subnet mask. + * @return A Set with the single IP address with its subnet + * mask as a byte array or an empty Set. + */ + private Set intersectIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2) + { + if (ipWithSubmask1.length != ipWithSubmask2.length) + { + return Collections.EMPTY_SET; + } + byte[][] temp = extractIPsAndSubnetMasks(ipWithSubmask1, ipWithSubmask2); + byte ip1[] = temp[0]; + byte subnetmask1[] = temp[1]; + byte ip2[] = temp[2]; + byte subnetmask2[] = temp[3]; + + byte minMax[][] = minMaxIPs(ip1, subnetmask1, ip2, subnetmask2); + byte[] min; + byte[] max; + max = min(minMax[1], minMax[3]); + min = max(minMax[0], minMax[2]); + + // minimum IP address must be bigger than max + if (compareTo(min, max) == 1) + { + return Collections.EMPTY_SET; + } + // OR keeps all significant bits + byte[] ip = or(minMax[0], minMax[2]); + byte[] subnetmask = or(subnetmask1, subnetmask2); + return Collections.singleton(ipWithSubnetMask(ip, subnetmask)); + } + + /** + * Concatenates the IP address with its subnet mask. + * + * @param ip The IP address. + * @param subnetMask Its subnet mask. + * @return The concatenated IP address with its subnet mask. + */ + private byte[] ipWithSubnetMask(byte[] ip, byte[] subnetMask) + { + int ipLength = ip.length; + byte[] temp = new byte[ipLength * 2]; + System.arraycopy(ip, 0, temp, 0, ipLength); + System.arraycopy(subnetMask, 0, temp, ipLength, ipLength); + return temp; + } + + /** + * Splits the IP addresses and their subnet mask. + * + * @param ipWithSubmask1 The first IP address with the subnet mask. + * @param ipWithSubmask2 The second IP address with the subnet mask. + * @return An array with two elements. Each element contains the IP address + * and the subnet mask in this order. + */ + private byte[][] extractIPsAndSubnetMasks( + byte[] ipWithSubmask1, + byte[] ipWithSubmask2) + { + int ipLength = ipWithSubmask1.length / 2; + byte ip1[] = new byte[ipLength]; + byte subnetmask1[] = new byte[ipLength]; + System.arraycopy(ipWithSubmask1, 0, ip1, 0, ipLength); + System.arraycopy(ipWithSubmask1, ipLength, subnetmask1, 0, ipLength); + + byte ip2[] = new byte[ipLength]; + byte subnetmask2[] = new byte[ipLength]; + System.arraycopy(ipWithSubmask2, 0, ip2, 0, ipLength); + System.arraycopy(ipWithSubmask2, ipLength, subnetmask2, 0, ipLength); + return new byte[][] + {ip1, subnetmask1, ip2, subnetmask2}; + } + + /** + * Based on the two IP addresses and their subnet masks the IP range is + * computed for each IP address - subnet mask pair and returned as the + * minimum IP address and the maximum address of the range. + * + * @param ip1 The first IP address. + * @param subnetmask1 The subnet mask of the first IP address. + * @param ip2 The second IP address. + * @param subnetmask2 The subnet mask of the second IP address. + * @return A array with two elements. The first/second element contains the + * min and max IP address of the first/second IP address and its + * subnet mask. + */ + private byte[][] minMaxIPs( + byte[] ip1, + byte[] subnetmask1, + byte[] ip2, + byte[] subnetmask2) + { + int ipLength = ip1.length; + byte[] min1 = new byte[ipLength]; + byte[] max1 = new byte[ipLength]; + + byte[] min2 = new byte[ipLength]; + byte[] max2 = new byte[ipLength]; + + for (int i = 0; i < ipLength; i++) + { + min1[i] = (byte)(ip1[i] & subnetmask1[i]); + max1[i] = (byte)(ip1[i] & subnetmask1[i] | ~subnetmask1[i]); + + min2[i] = (byte)(ip2[i] & subnetmask2[i]); + max2[i] = (byte)(ip2[i] & subnetmask2[i] | ~subnetmask2[i]); + } + + return new byte[][]{min1, max1, min2, max2}; + } + + private void checkPermittedEmail(Set permitted, String email) + throws NameConstraintValidatorException + { + if (permitted == null) + { + return; + } + + Iterator it = permitted.iterator(); + + while (it.hasNext()) + { + String str = ((String)it.next()); + + if (emailIsConstrained(email, str)) + { + return; + } + } + + if (email.length() == 0 && permitted.size() == 0) + { + return; + } + + throw new NameConstraintValidatorException( + "Subject email address is not from a permitted subtree."); + } + + private void checkPermittedOtherName(Set permitted, OtherName name) + throws NameConstraintValidatorException + { + if (permitted == null) + { + return; + } + + Iterator it = permitted.iterator(); + + while (it.hasNext()) + { + OtherName str = ((OtherName)it.next()); + + if (otherNameIsConstrained(name, str)) + { + return; + } + } + + throw new NameConstraintValidatorException( + "Subject OtherName is not from a permitted subtree."); + } + + private void checkExcludedOtherName(Set excluded, OtherName name) + throws NameConstraintValidatorException + { + if (excluded.isEmpty()) + { + return; + } + + Iterator it = excluded.iterator(); + + while (it.hasNext()) + { + OtherName str = OtherName.getInstance(it.next()); + + if (otherNameIsConstrained(name, str)) + { + throw new NameConstraintValidatorException( + "OtherName is from an excluded subtree."); + } + } + } + + private void checkExcludedEmail(Set excluded, String email) + throws NameConstraintValidatorException + { + if (excluded.isEmpty()) + { + return; + } + + Iterator it = excluded.iterator(); + + while (it.hasNext()) + { + String str = (String)it.next(); + + if (emailIsConstrained(email, str)) + { + throw new NameConstraintValidatorException( + "Email address is from an excluded subtree."); + } + } + } + + /** + * Checks if the IP ip is included in the permitted set + * permitted. + * + * @param permitted A Set of permitted IP addresses with + * their subnet mask as byte arrays. + * @param ip The IP address. + * @throws NameConstraintValidatorException if the IP is not permitted. + */ + private void checkPermittedIP(Set permitted, byte[] ip) + throws NameConstraintValidatorException + { + if (permitted == null) + { + return; + } + + Iterator it = permitted.iterator(); + + while (it.hasNext()) + { + byte[] ipWithSubnet = (byte[])it.next(); + + if (isIPConstrained(ip, ipWithSubnet)) + { + return; + } + } + if (ip.length == 0 && permitted.size() == 0) + { + return; + } + throw new NameConstraintValidatorException( + "IP is not from a permitted subtree."); + } + + /** + * Checks if the IP ip is included in the excluded set + * excluded. + * + * @param excluded A Set of excluded IP addresses with their + * subnet mask as byte arrays. + * @param ip The IP address. + * @throws NameConstraintValidatorException if the IP is excluded. + */ + private void checkExcludedIP(Set excluded, byte[] ip) + throws NameConstraintValidatorException + { + if (excluded.isEmpty()) + { + return; + } + + Iterator it = excluded.iterator(); + + while (it.hasNext()) + { + byte[] ipWithSubnet = (byte[])it.next(); + + if (isIPConstrained(ip, ipWithSubnet)) + { + throw new NameConstraintValidatorException( + "IP is from an excluded subtree."); + } + } + } + + /** + * Checks if the IP address ip is constrained by + * constraint. + * + * @param ip The IP address. + * @param constraint The constraint. This is an IP address concatenated with + * its subnetmask. + * @return true if constrained, false + * otherwise. + */ + private boolean isIPConstrained(byte ip[], byte[] constraint) + { + int ipLength = ip.length; + + if (ipLength != (constraint.length / 2)) + { + return false; + } + + byte[] subnetMask = new byte[ipLength]; + System.arraycopy(constraint, ipLength, subnetMask, 0, ipLength); + + byte[] permittedSubnetAddress = new byte[ipLength]; + + byte[] ipSubnetAddress = new byte[ipLength]; + + // the resulting IP address by applying the subnet mask + for (int i = 0; i < ipLength; i++) + { + permittedSubnetAddress[i] = (byte)(constraint[i] & subnetMask[i]); + ipSubnetAddress[i] = (byte)(ip[i] & subnetMask[i]); + } + + return Arrays.areEqual(permittedSubnetAddress, ipSubnetAddress); + } + + private boolean otherNameIsConstrained(OtherName name, OtherName constraint) + { + if (constraint.equals(name)) + { + return true; + } + + return false; + } + + private boolean emailIsConstrained(String email, String constraint) + { + String sub = email.substring(email.indexOf('@') + 1); + // a particular mailbox + if (constraint.indexOf('@') != -1) + { + if (email.equalsIgnoreCase(constraint)) + { + return true; + } + if (sub.equalsIgnoreCase(constraint.substring(1))) + { + return true; + } + } + // on particular host + else if (!(constraint.charAt(0) == '.')) + { + if (sub.equalsIgnoreCase(constraint)) + { + return true; + } + } + // address in sub domain + else if (withinDomain(sub, constraint)) + { + return true; + } + return false; + } + + private boolean withinDomain(String testDomain, String domain) + { + String tempDomain = domain; + if (tempDomain.startsWith(".")) + { + tempDomain = tempDomain.substring(1); + } + String[] domainParts = Strings.split(tempDomain, '.'); + String[] testDomainParts = Strings.split(testDomain, '.'); + // must have at least one subdomain + if (testDomainParts.length <= domainParts.length) + { + return false; + } + int d = testDomainParts.length - domainParts.length; + for (int i = -1; i < domainParts.length; i++) + { + if (i == -1) + { + if (testDomainParts[i + d].equals("")) + { + return false; + } + } + else if (!domainParts[i].equalsIgnoreCase(testDomainParts[i + d])) + { + return false; + } + } + return true; + } + + private void checkPermittedDNS(Set permitted, String dns) + throws NameConstraintValidatorException + { + if (permitted == null) + { + return; + } + + Iterator it = permitted.iterator(); + + while (it.hasNext()) + { + String str = ((String)it.next()); + + // is sub domain + if (withinDomain(dns, str) || dns.equalsIgnoreCase(str)) + { + return; + } + } + if (dns.length() == 0 && permitted.size() == 0) + { + return; + } + throw new NameConstraintValidatorException( + "DNS is not from a permitted subtree."); + } + + private void checkExcludedDNS(Set excluded, String dns) + throws NameConstraintValidatorException + { + if (excluded.isEmpty()) + { + return; + } + + Iterator it = excluded.iterator(); + + while (it.hasNext()) + { + String str = ((String)it.next()); + + // is sub domain or the same + if (withinDomain(dns, str) || dns.equalsIgnoreCase(str)) + { + throw new NameConstraintValidatorException( + "DNS is from an excluded subtree."); + } + } + } + + /** + * The common part of email1 and email2 is + * added to the union union. If email1 and + * email2 have nothing in common they are added both. + * + * @param email1 Email address constraint 1. + * @param email2 Email address constraint 2. + * @param union The union. + */ + private void unionEmail(String email1, String email2, Set union) + { + // email1 is a particular address + if (email1.indexOf('@') != -1) + { + String _sub = email1.substring(email1.indexOf('@') + 1); + // both are a particular mailbox + if (email2.indexOf('@') != -1) + { + if (email1.equalsIgnoreCase(email2)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(_sub, email2)) + { + union.add(email2); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a particular host + else + { + if (_sub.equalsIgnoreCase(email2)) + { + union.add(email2); + } + else + { + union.add(email1); + union.add(email2); + } + } + } + // email1 specifies a domain + else if (email1.startsWith(".")) + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email1.indexOf('@') + 1); + if (withinDomain(_sub, email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2) + || email1.equalsIgnoreCase(email2)) + { + union.add(email2); + } + else if (withinDomain(email2, email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + else + { + if (withinDomain(email2, email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + } + // email specifies a host + else + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email1.indexOf('@') + 1); + if (_sub.equalsIgnoreCase(email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2)) + { + union.add(email2); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a particular host + else + { + if (email1.equalsIgnoreCase(email2)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + } + } + + private void unionURI(String email1, String email2, Set union) + { + // email1 is a particular address + if (email1.indexOf('@') != -1) + { + String _sub = email1.substring(email1.indexOf('@') + 1); + // both are a particular mailbox + if (email2.indexOf('@') != -1) + { + if (email1.equalsIgnoreCase(email2)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(_sub, email2)) + { + union.add(email2); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a particular host + else + { + if (_sub.equalsIgnoreCase(email2)) + { + union.add(email2); + } + else + { + union.add(email1); + union.add(email2); + } + } + } + // email1 specifies a domain + else if (email1.startsWith(".")) + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email1.indexOf('@') + 1); + if (withinDomain(_sub, email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2) + || email1.equalsIgnoreCase(email2)) + { + union.add(email2); + } + else if (withinDomain(email2, email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + else + { + if (withinDomain(email2, email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + } + // email specifies a host + else + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email1.indexOf('@') + 1); + if (_sub.equalsIgnoreCase(email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2)) + { + union.add(email2); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a particular host + else + { + if (email1.equalsIgnoreCase(email2)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + } + } + + private Set intersectDNS(Set permitted, Set dnss) + { + Set intersect = new HashSet(); + for (Iterator it = dnss.iterator(); it.hasNext();) + { + String dns = extractNameAsString(((GeneralSubtree)it.next()) + .getBase()); + if (permitted == null) + { + if (dns != null) + { + intersect.add(dns); + } + } + else + { + Iterator _iter = permitted.iterator(); + while (_iter.hasNext()) + { + String _permitted = (String)_iter.next(); + + if (withinDomain(_permitted, dns)) + { + intersect.add(_permitted); + } + else if (withinDomain(dns, _permitted)) + { + intersect.add(dns); + } + } + } + } + + return intersect; + } + + private Set unionDNS(Set excluded, String dns) + { + if (excluded.isEmpty()) + { + if (dns == null) + { + return excluded; + } + excluded.add(dns); + + return excluded; + } + else + { + Set union = new HashSet(); + + Iterator _iter = excluded.iterator(); + while (_iter.hasNext()) + { + String _permitted = (String)_iter.next(); + + if (withinDomain(_permitted, dns)) + { + union.add(dns); + } + else if (withinDomain(dns, _permitted)) + { + union.add(_permitted); + } + else + { + union.add(_permitted); + union.add(dns); + } + } + + return union; + } + } + + /** + * The most restricting part from email1 and + * email2 is added to the intersection intersect. + * + * @param email1 Email address constraint 1. + * @param email2 Email address constraint 2. + * @param intersect The intersection. + */ + private void intersectEmail(String email1, String email2, Set intersect) + { + // email1 is a particular address + if (email1.indexOf('@') != -1) + { + String _sub = email1.substring(email1.indexOf('@') + 1); + // both are a particular mailbox + if (email2.indexOf('@') != -1) + { + if (email1.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(_sub, email2)) + { + intersect.add(email1); + } + } + // email2 specifies a particular host + else + { + if (_sub.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + } + } + // email specifies a domain + else if (email1.startsWith(".")) + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email1.indexOf('@') + 1); + if (withinDomain(_sub, email1)) + { + intersect.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2) + || email1.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + else if (withinDomain(email2, email1)) + { + intersect.add(email2); + } + } + else + { + if (withinDomain(email2, email1)) + { + intersect.add(email2); + } + } + } + // email1 specifies a host + else + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email2.indexOf('@') + 1); + if (_sub.equalsIgnoreCase(email1)) + { + intersect.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2)) + { + intersect.add(email1); + } + } + // email2 specifies a particular host + else + { + if (email1.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + } + } + } + + private void checkExcludedURI(Set excluded, String uri) + throws NameConstraintValidatorException + { + if (excluded.isEmpty()) + { + return; + } + + Iterator it = excluded.iterator(); + + while (it.hasNext()) + { + String str = ((String)it.next()); + + if (isUriConstrained(uri, str)) + { + throw new NameConstraintValidatorException( + "URI is from an excluded subtree."); + } + } + } + + private Set intersectURI(Set permitted, Set uris) + { + Set intersect = new HashSet(); + for (Iterator it = uris.iterator(); it.hasNext();) + { + String uri = extractNameAsString(((GeneralSubtree)it.next()) + .getBase()); + if (permitted == null) + { + if (uri != null) + { + intersect.add(uri); + } + } + else + { + Iterator _iter = permitted.iterator(); + while (_iter.hasNext()) + { + String _permitted = (String)_iter.next(); + intersectURI(_permitted, uri, intersect); + } + } + } + return intersect; + } + + private Set unionURI(Set excluded, String uri) + { + if (excluded.isEmpty()) + { + if (uri == null) + { + return excluded; + } + excluded.add(uri); + + return excluded; + } + else + { + Set union = new HashSet(); + + Iterator _iter = excluded.iterator(); + while (_iter.hasNext()) + { + String _excluded = (String)_iter.next(); + + unionURI(_excluded, uri, union); + } + + return union; + } + } + + private void intersectURI(String email1, String email2, Set intersect) + { + // email1 is a particular address + if (email1.indexOf('@') != -1) + { + String _sub = email1.substring(email1.indexOf('@') + 1); + // both are a particular mailbox + if (email2.indexOf('@') != -1) + { + if (email1.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(_sub, email2)) + { + intersect.add(email1); + } + } + // email2 specifies a particular host + else + { + if (_sub.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + } + } + // email specifies a domain + else if (email1.startsWith(".")) + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email1.indexOf('@') + 1); + if (withinDomain(_sub, email1)) + { + intersect.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2) + || email1.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + else if (withinDomain(email2, email1)) + { + intersect.add(email2); + } + } + else + { + if (withinDomain(email2, email1)) + { + intersect.add(email2); + } + } + } + // email1 specifies a host + else + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email2.indexOf('@') + 1); + if (_sub.equalsIgnoreCase(email1)) + { + intersect.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2)) + { + intersect.add(email1); + } + } + // email2 specifies a particular host + else + { + if (email1.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + } + } + } + + private void checkPermittedURI(Set permitted, String uri) + throws NameConstraintValidatorException + { + if (permitted == null) + { + return; + } + + Iterator it = permitted.iterator(); + + while (it.hasNext()) + { + String str = ((String)it.next()); + + if (isUriConstrained(uri, str)) + { + return; + } + } + if (uri.length() == 0 && permitted.size() == 0) + { + return; + } + throw new NameConstraintValidatorException( + "URI is not from a permitted subtree."); + } + + private boolean isUriConstrained(String uri, String constraint) + { + String host = extractHostFromURL(uri); + // a host + if (!constraint.startsWith(".")) + { + if (host.equalsIgnoreCase(constraint)) + { + return true; + } + } + + // in sub domain or domain + else if (withinDomain(host, constraint)) + { + return true; + } + + return false; + } + + private static String extractHostFromURL(String url) + { + // see RFC 1738 + // remove ':' after protocol, e.g. http: + String sub = url.substring(url.indexOf(':') + 1); + // extract host from Common Internet Scheme Syntax, e.g. https:// + if (sub.indexOf("//") != -1) + { + sub = sub.substring(sub.indexOf("//") + 2); + } + // first remove port, e.g. https://test.com:21 + if (sub.lastIndexOf(':') != -1) + { + sub = sub.substring(0, sub.lastIndexOf(':')); + } + // remove user and password, e.g. https://john:password@test.com + sub = sub.substring(sub.indexOf(':') + 1); + sub = sub.substring(sub.indexOf('@') + 1); + // remove local parts, e.g. http://test.com/bla + if (sub.indexOf('/') != -1) + { + sub = sub.substring(0, sub.indexOf('/')); + } + return sub; + } + + private String extractNameAsString(GeneralName name) + { + return ASN1IA5String.getInstance(name.getName()).getString(); + } + + /** + * Returns the maximum IP address. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return The maximum IP address. + */ + private static byte[] max(byte[] ip1, byte[] ip2) + { + for (int i = 0; i < ip1.length; i++) + { + if ((ip1[i] & 0xFFFF) > (ip2[i] & 0xFFFF)) + { + return ip1; + } + } + return ip2; + } + + /** + * Returns the minimum IP address. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return The minimum IP address. + */ + private static byte[] min(byte[] ip1, byte[] ip2) + { + for (int i = 0; i < ip1.length; i++) + { + if ((ip1[i] & 0xFFFF) < (ip2[i] & 0xFFFF)) + { + return ip1; + } + } + return ip2; + } + + /** + * Compares IP address ip1 with ip2. If ip1 + * is equal to ip2 0 is returned. If ip1 is bigger 1 is returned, -1 + * otherwise. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return 0 if ip1 is equal to ip2, 1 if ip1 is bigger, -1 otherwise. + */ + private static int compareTo(byte[] ip1, byte[] ip2) + { + if (Arrays.areEqual(ip1, ip2)) + { + return 0; + } + if (Arrays.areEqual(max(ip1, ip2), ip1)) + { + return 1; + } + return -1; + } + + /** + * Returns the logical OR of the IP addresses ip1 and + * ip2. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return The OR of ip1 and ip2. + */ + private static byte[] or(byte[] ip1, byte[] ip2) + { + byte[] temp = new byte[ip1.length]; + for (int i = 0; i < ip1.length; i++) + { + temp[i] = (byte)(ip1[i] | ip2[i]); + } + return temp; + } + + private int hashCollection(Collection coll) + { + if (coll == null) + { + return 0; + } + int hash = 0; + Iterator it1 = coll.iterator(); + while (it1.hasNext()) + { + Object o = it1.next(); + if (o instanceof byte[]) + { + hash += Arrays.hashCode((byte[])o); + } + else + { + hash += o.hashCode(); + } + } + return hash; + } + + private boolean collectionsAreEqual(Collection coll1, Collection coll2) + { + if (coll1 == coll2) + { + return true; + } + if (coll1 == null || coll2 == null) + { + return false; + } + if (coll1.size() != coll2.size()) + { + return false; + } + Iterator it1 = coll1.iterator(); + + while (it1.hasNext()) + { + Object a = it1.next(); + Iterator it2 = coll2.iterator(); + boolean found = false; + while (it2.hasNext()) + { + Object b = it2.next(); + if (equals(a, b)) + { + found = true; + break; + } + } + if (!found) + { + return false; + } + } + return true; + } + + private boolean equals(Object o1, Object o2) + { + if (o1 == o2) + { + return true; + } + if (o1 == null || o2 == null) + { + return false; + } + if (o1 instanceof byte[] && o2 instanceof byte[]) + { + return Arrays.areEqual((byte[])o1, (byte[])o2); + } + else + { + return o1.equals(o2); + } + } + + /** + * Stringifies an IPv4 or v6 address with subnet mask. + * + * @param ip The IP with subnet mask. + * @return The stringified IP address. + */ + private String stringifyIP(byte[] ip) + { + StringBuilder temp = new StringBuilder(); + for (int i = 0; i < ip.length / 2; i++) + { + if (temp.length() > 0) + { + temp.append("."); + } + temp.append(Integer.toString(ip[i] & 0x00FF)); + } + + temp.append("/"); + boolean first = true; + for (int i = ip.length / 2; i < ip.length; i++) + { + if (first) + { + first = false; + } + else + { + temp.append("."); + } + temp.append(Integer.toString(ip[i] & 0x00FF)); + } + + return temp.toString(); + } + + private String stringifyIPCollection(Set ips) + { + StringBuilder temp = new StringBuilder(); + temp.append("["); + for (Iterator it = ips.iterator(); it.hasNext();) + { + if (temp.length() > 1) + { + temp.append(","); + } + temp.append(stringifyIP((byte[])it.next())); + } + temp.append("]"); + return temp.toString(); + } + + private String stringifyOtherNameCollection(Set otherNames) + { + StringBuilder temp = new StringBuilder(); + temp.append("["); + for (Iterator it = otherNames.iterator(); it.hasNext();) + { + if (temp.length() > 1) + { + temp.append(","); + } + OtherName name = OtherName.getInstance(it.next()); + temp.append(name.getTypeID().getId()); + temp.append(":"); + try + { + // -DM Hex.toHexString + temp.append(Hex.toHexString(name.getValue().toASN1Primitive().getEncoded())); + } + catch (IOException e) + { + temp.append(e.toString()); + } + } + temp.append("]"); + return temp.toString(); + } + + private final void addLine(StringBuilder sb, String str) + { + sb.append(str).append(Strings.lineSeparator()); + } + + public String toString() + { + StringBuilder temp = new StringBuilder(); + + addLine(temp, "permitted:"); + if (permittedSubtreesDN != null) + { + addLine(temp, "DN:"); + addLine(temp, permittedSubtreesDN.toString()); + } + if (permittedSubtreesDNS != null) + { + addLine(temp, "DNS:"); + addLine(temp, permittedSubtreesDNS.toString()); + } + if (permittedSubtreesEmail != null) + { + addLine(temp, "Email:"); + addLine(temp, permittedSubtreesEmail.toString()); + } + if (permittedSubtreesURI != null) + { + addLine(temp, "URI:"); + addLine(temp, permittedSubtreesURI.toString()); + } + if (permittedSubtreesIP != null) + { + addLine(temp, "IP:"); + addLine(temp, stringifyIPCollection(permittedSubtreesIP)); + } + if (permittedSubtreesOtherName != null) + { + addLine(temp, "OtherName:"); + addLine(temp, stringifyOtherNameCollection(permittedSubtreesOtherName)); + } + addLine(temp, "excluded:"); + if (!excludedSubtreesDN.isEmpty()) + { + addLine(temp, "DN:"); + addLine(temp, excludedSubtreesDN.toString()); + } + if (!excludedSubtreesDNS.isEmpty()) + { + addLine(temp, "DNS:"); + addLine(temp, excludedSubtreesDNS.toString()); + } + if (!excludedSubtreesEmail.isEmpty()) + { + addLine(temp, "Email:"); + addLine(temp, excludedSubtreesEmail.toString()); + } + if (!excludedSubtreesURI.isEmpty()) + { + addLine(temp, "URI:"); + addLine(temp, excludedSubtreesURI.toString()); + } + if (!excludedSubtreesIP.isEmpty()) + { + addLine(temp, "IP:"); + addLine(temp, stringifyIPCollection(excludedSubtreesIP)); + } + if (!excludedSubtreesOtherName.isEmpty()) + { + addLine(temp, "OtherName:"); + addLine(temp, stringifyOtherNameCollection(excludedSubtreesOtherName)); + } + return temp.toString(); + } +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/PKIXNameConstraintValidator.java b/pkix/src/main/java/org/bouncycastle/pkix/PKIXNameConstraintValidator.java new file mode 100644 index 0000000000..2c0564a075 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/PKIXNameConstraintValidator.java @@ -0,0 +1,135 @@ +package org.bouncycastle.pkix; + +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralSubtree; +import org.bouncycastle.asn1.x509.NameConstraintValidatorException; + +public class PKIXNameConstraintValidator +{ + ASN1PKIXNameConstraintValidator validator = new ASN1PKIXNameConstraintValidator(); + + public PKIXNameConstraintValidator() + { + } + + public int hashCode() + { + return validator.hashCode(); + } + + public boolean equals(Object o) + { + if (!(o instanceof PKIXNameConstraintValidator)) + { + return false; + } + PKIXNameConstraintValidator constraintValidator = (PKIXNameConstraintValidator)o; + return this.validator.equals(constraintValidator.validator); + } + + public void checkPermittedDN(ASN1Sequence dns) + throws PKIXNameConstraintValidatorException + { + try + { + this.validator.checkPermittedDN(X500Name.getInstance(dns)); + } + catch (NameConstraintValidatorException e) + { + throw new PKIXNameConstraintValidatorException(e.getMessage(), e); + } + } + + public void checkExcludedDN(ASN1Sequence dns) + throws PKIXNameConstraintValidatorException + { + try + { + this.validator.checkExcludedDN(X500Name.getInstance(dns)); + } + catch (NameConstraintValidatorException e) + { + throw new PKIXNameConstraintValidatorException(e.getMessage(), e); + } + } + + /** + * Checks if the given GeneralName is in the permitted set. + * + * @param name The GeneralName + * @throws PKIXNameConstraintValidatorException + * If the name + */ + public void checkPermitted(GeneralName name) + throws PKIXNameConstraintValidatorException + { + try + { + validator.checkPermitted(name); + } + catch (NameConstraintValidatorException e) + { + throw new PKIXNameConstraintValidatorException(e.getMessage(), e); + } + } + + /** + * Check if the given GeneralName is contained in the excluded set. + * + * @param name The GeneralName. + * @throws PKIXNameConstraintValidatorException + * If the name is + * excluded. + */ + public void checkExcluded(GeneralName name) + throws PKIXNameConstraintValidatorException + { + try + { + validator.checkExcluded(name); + } + catch (NameConstraintValidatorException e) + { + throw new PKIXNameConstraintValidatorException(e.getMessage(), e); + } + } + + public void intersectPermittedSubtree(GeneralSubtree permitted) + { + validator.intersectPermittedSubtree(permitted); + } + + /** + * Updates the permitted set of these name constraints with the intersection + * with the given subtree. + * + * @param permitted The permitted subtrees + */ + + public void intersectPermittedSubtree(GeneralSubtree[] permitted) + { + validator.intersectPermittedSubtree(permitted); + } + + public void intersectEmptyPermittedSubtree(int nameType) + { + validator.intersectEmptyPermittedSubtree(nameType); + } + + /** + * Adds a subtree to the excluded set of these name constraints. + * + * @param subtree A subtree with an excluded GeneralName. + */ + public void addExcludedSubtree(GeneralSubtree subtree) + { + validator.addExcludedSubtree(subtree); + } + + public String toString() + { + return validator.toString(); + } +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/PKIXNameConstraintValidatorException.java b/pkix/src/main/java/org/bouncycastle/pkix/PKIXNameConstraintValidatorException.java new file mode 100644 index 0000000000..7a6c05310b --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/PKIXNameConstraintValidatorException.java @@ -0,0 +1,24 @@ +package org.bouncycastle.pkix; + +public class PKIXNameConstraintValidatorException + extends Exception +{ + private Throwable cause; + + public PKIXNameConstraintValidatorException(String msg) + { + super(msg); + } + + public PKIXNameConstraintValidatorException(String msg, Throwable e) + { + super(msg); + + this.cause = e; + } + + public Throwable getCause() + { + return cause; + } +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/SubjectPublicKeyInfoChecker.java b/pkix/src/main/java/org/bouncycastle/pkix/SubjectPublicKeyInfoChecker.java index cd994a1274..0d2ce45af9 100644 --- a/pkix/src/main/java/org/bouncycastle/pkix/SubjectPublicKeyInfoChecker.java +++ b/pkix/src/main/java/org/bouncycastle/pkix/SubjectPublicKeyInfoChecker.java @@ -22,6 +22,7 @@ import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.math.Primes; +import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Strings; /** @@ -40,8 +41,6 @@ public class SubjectPublicKeyInfoChecker + "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f", 16); - private static final BigInteger ONE = BigInteger.valueOf(1); - public static void checkInfo(SubjectPublicKeyInfo pubInfo) { ASN1ObjectIdentifier algorithm = pubInfo.getAlgorithm().getAlgorithm(); @@ -110,6 +109,18 @@ else if (PKCSObjectIdentifiers.rsaEncryption.equals(algorithm) } } + private static boolean hasAnySmallFactors(BigInteger modulus) + { + BigInteger M = modulus, X = SMALL_PRIMES_PRODUCT; + if (modulus.compareTo(SMALL_PRIMES_PRODUCT) < 0) + { + M = SMALL_PRIMES_PRODUCT; + X = modulus; + } + + return !BigIntegers.modOddIsCoprimeVar(M, X); + } + private static void validate(BigInteger modulus) { if ((modulus.intValue() & 1) == 0) @@ -123,15 +134,13 @@ private static void validate(BigInteger modulus) return; } - int maxBitLength = Properties.asInteger("org.bouncycastle.rsa.max_size", 15360); - - int modBitLength = modulus.bitLength(); - if (maxBitLength < modBitLength) + int maxBitLength = Properties.asInteger("org.bouncycastle.rsa.max_size", 16384); + if (maxBitLength < modulus.bitLength()) { - throw new IllegalArgumentException("modulus value out of range"); + throw new IllegalArgumentException("RSA modulus out of range"); } - if (!modulus.gcd(SMALL_PRIMES_PRODUCT).equals(ONE)) + if (hasAnySmallFactors(modulus)) { throw new IllegalArgumentException("RSA modulus has a small prime factor"); } @@ -142,7 +151,8 @@ private static void validate(BigInteger modulus) : bits >= 512 ? 7 : 50; - Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, CryptoServicesRegistrar.getSecureRandom(), iterations); + Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, CryptoServicesRegistrar.getSecureRandom(), + iterations); if (!mr.isProvablyComposite()) { throw new IllegalArgumentException("RSA modulus is not composite"); diff --git a/pkix/src/main/java/org/bouncycastle/pkix/jcajce/CertPathReviewerException.java b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/CertPathReviewerException.java new file mode 100644 index 0000000000..4ca7e4cd6c --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/CertPathReviewerException.java @@ -0,0 +1,72 @@ +package org.bouncycastle.pkix.jcajce; + +import java.security.cert.CertPath; + +import org.bouncycastle.pkix.util.ErrorBundle; +import org.bouncycastle.pkix.util.LocalizedException; + +public class CertPathReviewerException extends LocalizedException +{ + + private int index = -1; + + private CertPath certPath = null; + + public CertPathReviewerException(ErrorBundle errorMessage, Throwable throwable) + { + super(errorMessage, throwable); + } + + public CertPathReviewerException(ErrorBundle errorMessage) + { + super(errorMessage); + } + + public CertPathReviewerException( + ErrorBundle errorMessage, + Throwable throwable, + CertPath certPath, + int index) + { + super(errorMessage, throwable); + if (certPath == null || index == -1) + { + throw new IllegalArgumentException(); + } + if (index < -1 || index >= certPath.getCertificates().size()) + { + throw new IndexOutOfBoundsException(); + } + this.certPath = certPath; + this.index = index; + } + + public CertPathReviewerException( + ErrorBundle errorMessage, + CertPath certPath, + int index) + { + super(errorMessage); + if (certPath == null || index == -1) + { + throw new IllegalArgumentException(); + } + if (index < -1 || index >= certPath.getCertificates().size()) + { + throw new IndexOutOfBoundsException(); + } + this.certPath = certPath; + this.index = index; + } + + public CertPath getCertPath() + { + return certPath; + } + + public int getIndex() + { + return index; + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/jcajce/CertPathValidatorUtilities.java b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/CertPathValidatorUtilities.java new file mode 100644 index 0000000000..5e430683f9 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/CertPathValidatorUtilities.java @@ -0,0 +1,822 @@ +package org.bouncycastle.pkix.jcajce; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.PublicKey; +import java.security.cert.CRLException; +import java.security.cert.CertPathValidatorException; +import java.security.cert.CertStore; +import java.security.cert.CertStoreException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.PKIXParameters; +import java.security.cert.PolicyQualifierInfo; +import java.security.cert.X509CRL; +import java.security.cert.X509CRLEntry; +import java.security.cert.X509Certificate; +import java.security.interfaces.DSAParams; +import java.security.interfaces.DSAPublicKey; +import java.security.spec.DSAPublicKeySpec; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.security.auth.x500.X500Principal; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1Enumerated; +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1OutputStream; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.CRLReason; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.IssuingDistributionPoint; +import org.bouncycastle.asn1.x509.PolicyInformation; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.jcajce.PKIXCertStoreSelector; +import org.bouncycastle.util.Encodable; +import org.bouncycastle.util.Selector; +import org.bouncycastle.util.Store; +import org.bouncycastle.util.StoreException; + +class CertPathValidatorUtilities +{ + protected static final String CERTIFICATE_POLICIES = Extension.certificatePolicies.getId(); + protected static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId(); + protected static final String POLICY_MAPPINGS = Extension.policyMappings.getId(); + protected static final String SUBJECT_ALTERNATIVE_NAME = Extension.subjectAlternativeName.getId(); + protected static final String NAME_CONSTRAINTS = Extension.nameConstraints.getId(); + protected static final String KEY_USAGE = Extension.keyUsage.getId(); + protected static final String INHIBIT_ANY_POLICY = Extension.inhibitAnyPolicy.getId(); + protected static final String ISSUING_DISTRIBUTION_POINT = Extension.issuingDistributionPoint.getId(); + protected static final String DELTA_CRL_INDICATOR = Extension.deltaCRLIndicator.getId(); + protected static final String POLICY_CONSTRAINTS = Extension.policyConstraints.getId(); + protected static final String FRESHEST_CRL = Extension.freshestCRL.getId(); + protected static final String CRL_DISTRIBUTION_POINTS = Extension.cRLDistributionPoints.getId(); + protected static final String AUTHORITY_KEY_IDENTIFIER = Extension.authorityKeyIdentifier.getId(); + + protected static final String ANY_POLICY = "2.5.29.32.0"; + + protected static final String CRL_NUMBER = Extension.cRLNumber.getId(); + + /* + * key usage bits + */ + protected static final int KEY_CERT_SIGN = 5; + protected static final int CRL_SIGN = 6; + + protected static final String[] crlReasons = new String[]{ + "unspecified", + "keyCompromise", + "cACompromise", + "affiliationChanged", + "superseded", + "cessationOfOperation", + "certificateHold", + "unknown", + "removeFromCRL", + "privilegeWithdrawn", + "aACompromise"}; + + + + + /** + * Returns the issuer of an attribute certificate or certificate. + * + * @param cert The attribute certificate or certificate. + * @return The issuer as X500Principal. + */ + protected static X500Principal getEncodedIssuerPrincipal( + Object cert) + { + if (cert instanceof X509Certificate) + { + return ((X509Certificate)cert).getIssuerX500Principal(); + } + throw new IllegalArgumentException("unknown certificate type"); +// else +// { +// return (X500Principal)((X509AttributeCertificate)cert).getIssuer().getPrincipals()[0]; +// } + } + + protected static Date getValidDate(PKIXParameters paramsPKIX) + { + Date validDate = paramsPKIX.getDate(); + + if (validDate == null) + { + validDate = new Date(); + } + + return validDate; + } + + protected static X500Principal getSubjectPrincipal(X509Certificate cert) + { + return cert.getSubjectX500Principal(); + } + + protected static boolean isSelfIssued(X509Certificate cert) + { + return cert.getSubjectDN().equals(cert.getIssuerDN()); + } + + + /** + * Extract the value of the given extension, if it exists. + * + * @param ext The extension object. + * @param oid The object identifier to obtain. + * @throws AnnotatedException if the extension cannot be read. + */ + protected static ASN1Primitive getExtensionValue( + java.security.cert.X509Extension ext, + String oid) + throws AnnotatedException + { + byte[] bytes = ext.getExtensionValue(oid); + if (bytes == null) + { + return null; + } + + return getObject(oid, bytes); + } + + private static ASN1Primitive getObject( + String oid, + byte[] ext) + throws AnnotatedException + { + try + { + ASN1InputStream aIn = new ASN1InputStream(ext); + ASN1OctetString octs = (ASN1OctetString)aIn.readObject(); + + aIn = new ASN1InputStream(octs.getOctets()); + return aIn.readObject(); + } + catch (Exception e) + { + throw new AnnotatedException("exception processing extension " + oid, e); + } + } + + protected static X500Principal getIssuerPrincipal(X509CRL crl) + { + return crl.getIssuerX500Principal(); + } + + protected static AlgorithmIdentifier getAlgorithmIdentifier( + PublicKey key) + throws CertPathValidatorException + { + try + { + ASN1InputStream aIn = new ASN1InputStream(key.getEncoded()); + + SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject()); + + return info.getAlgorithm(); + } + catch (Exception e) + { + throw new CertPathValidatorException("Subject public key cannot be decoded.", e); + } + } + + // crl checking + + + // + // policy checking + // + + protected static final Set getQualifierSet(ASN1Sequence qualifiers) + throws CertPathValidatorException + { + Set pq = new HashSet(); + + if (qualifiers == null) + { + return pq; + } + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ASN1OutputStream aOut = ASN1OutputStream.create(bOut); + + Enumeration e = qualifiers.getObjects(); + + while (e.hasMoreElements()) + { + try + { + aOut.writeObject((ASN1Encodable)e.nextElement()); + + pq.add(new PolicyQualifierInfo(bOut.toByteArray())); + } + catch (IOException ex) + { + throw new CertPathValidatorException("Policy qualifier info cannot be decoded.", ex); + } + + bOut.reset(); + } + + return pq; + } + + protected static PKIXPolicyNode removePolicyNode( + PKIXPolicyNode validPolicyTree, + List[] policyNodes, + PKIXPolicyNode _node) + { + PKIXPolicyNode _parent = (PKIXPolicyNode)_node.getParent(); + + if (validPolicyTree == null) + { + return null; + } + + if (_parent == null) + { + for (int j = 0; j < policyNodes.length; j++) + { + policyNodes[j] = new ArrayList(); + } + + return null; + } + else + { + _parent.removeChild(_node); + removePolicyNodeRecurse(policyNodes, _node); + + return validPolicyTree; + } + } + + private static void removePolicyNodeRecurse( + List[] policyNodes, + PKIXPolicyNode _node) + { + policyNodes[_node.getDepth()].remove(_node); + + if (_node.hasChildren()) + { + Iterator _iter = _node.getChildren(); + while (_iter.hasNext()) + { + PKIXPolicyNode _child = (PKIXPolicyNode)_iter.next(); + removePolicyNodeRecurse(policyNodes, _child); + } + } + } + + + protected static boolean processCertD1i( + int index, + List[] policyNodes, + ASN1ObjectIdentifier pOid, + Set pq) + { + List policyNodeVec = policyNodes[index - 1]; + + for (int j = 0; j < policyNodeVec.size(); j++) + { + PKIXPolicyNode node = (PKIXPolicyNode)policyNodeVec.get(j); + Set expectedPolicies = node.getExpectedPolicies(); + + if (expectedPolicies.contains(pOid.getId())) + { + Set childExpectedPolicies = new HashSet(); + childExpectedPolicies.add(pOid.getId()); + + PKIXPolicyNode child = new PKIXPolicyNode(new ArrayList(), + index, + childExpectedPolicies, + node, + pq, + pOid.getId(), + false); + node.addChild(child); + policyNodes[index].add(child); + + return true; + } + } + + return false; + } + + protected static void processCertD1ii( + int index, + List[] policyNodes, + ASN1ObjectIdentifier _poid, + Set _pq) + { + List policyNodeVec = policyNodes[index - 1]; + + for (int j = 0; j < policyNodeVec.size(); j++) + { + PKIXPolicyNode _node = (PKIXPolicyNode)policyNodeVec.get(j); + + if (ANY_POLICY.equals(_node.getValidPolicy())) + { + Set _childExpectedPolicies = new HashSet(); + _childExpectedPolicies.add(_poid.getId()); + + PKIXPolicyNode _child = new PKIXPolicyNode(new ArrayList(), + index, + _childExpectedPolicies, + _node, + _pq, + _poid.getId(), + false); + _node.addChild(_child); + policyNodes[index].add(_child); + return; + } + } + } + + protected static void prepareNextCertB1( + int i, + List[] policyNodes, + String id_p, + Map m_idp, + X509Certificate cert + ) + throws AnnotatedException, CertPathValidatorException + { + boolean idp_found = false; + Iterator nodes_i = policyNodes[i].iterator(); + while (nodes_i.hasNext()) + { + PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); + if (node.getValidPolicy().equals(id_p)) + { + idp_found = true; + node.setExpectedPolicies((Set)m_idp.get(id_p)); + break; + } + } + + if (!idp_found) + { + nodes_i = policyNodes[i].iterator(); + while (nodes_i.hasNext()) + { + PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); + if (ANY_POLICY.equals(node.getValidPolicy())) + { + Set pq = null; + ASN1Sequence policies = null; + try + { + policies = DERSequence.getInstance(getExtensionValue(cert, CERTIFICATE_POLICIES)); + } + catch (Exception e) + { + throw new AnnotatedException("Certificate policies cannot be decoded.", e); + } + Enumeration e = policies.getObjects(); + while (e.hasMoreElements()) + { + PolicyInformation pinfo = null; + + try + { + pinfo = PolicyInformation.getInstance(e.nextElement()); + } + catch (Exception ex) + { + throw new AnnotatedException("Policy information cannot be decoded.", ex); + } + if (ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId())) + { + try + { + pq = getQualifierSet(pinfo.getPolicyQualifiers()); + } + catch (CertPathValidatorException ex) + { + throw new CertPathValidatorException( + "Policy qualifier info set could not be built.", ex); + } + break; + } + } + boolean ci = false; + if (cert.getCriticalExtensionOIDs() != null) + { + ci = cert.getCriticalExtensionOIDs().contains(CERTIFICATE_POLICIES); + } + + PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); + if (ANY_POLICY.equals(p_node.getValidPolicy())) + { + PKIXPolicyNode c_node = new PKIXPolicyNode( + new ArrayList(), i, + (Set)m_idp.get(id_p), + p_node, pq, id_p, ci); + p_node.addChild(c_node); + policyNodes[i].add(c_node); + } + break; + } + } + } + } + + protected static PKIXPolicyNode prepareNextCertB2( + int i, + List[] policyNodes, + String id_p, + PKIXPolicyNode validPolicyTree) + { + Iterator nodes_i = policyNodes[i].iterator(); + while (nodes_i.hasNext()) + { + PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next(); + if (node.getValidPolicy().equals(id_p)) + { + PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent(); + p_node.removeChild(node); + nodes_i.remove(); + for (int k = (i - 1); k >= 0; k--) + { + List nodes = policyNodes[k]; + for (int l = 0; l < nodes.size(); l++) + { + PKIXPolicyNode node2 = (PKIXPolicyNode)nodes.get(l); + if (!node2.hasChildren()) + { + validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node2); + if (validPolicyTree == null) + { + break; + } + } + } + } + } + } + return validPolicyTree; + } + + protected static boolean isAnyPolicy( + Set policySet) + { + return policySet == null || policySet.contains(ANY_POLICY) || policySet.isEmpty(); + } + + /** + * Return a Collection of all certificates or attribute certificates found + * in the X509Store's that are matching the certSelect criteriums. + * + * @param certSelect a {@link Selector} object that will be used to select + * the certificates + * @param certStores a List containing only {@link Store} objects. These + * are used to search for certificates. + * @return a Collection of all found {@link X509Certificate} + * May be empty but never null. + */ + protected static Collection findCertificates(X509CertStoreSelector certSelect, + List certStores) + throws AnnotatedException + { + Set certs = new HashSet(); + Iterator iter = certStores.iterator(); + CertificateFactory certFact = null; + try + { + certFact = CertificateFactory.getInstance("X.509"); + } + catch (CertificateException e) + { + throw new AnnotatedException(e.getMessage(), e); + } + + while (iter.hasNext()) + { + Object obj = iter.next(); + + if (obj instanceof Store) + { + Store certStore = (Store)obj; + try + { + for (Iterator it = certStore.getMatches(certSelect).iterator(); it.hasNext();) + { + Object cert = it.next(); + + if (cert instanceof Encodable) + { + certs.add(certFact.generateCertificate(new ByteArrayInputStream(((Encodable)cert).getEncoded()))); + } + else if (cert instanceof Certificate) + { + certs.add(cert); + } + else + { + throw new AnnotatedException( + "Unknown object found in certificate store."); + } + } + } + catch (StoreException e) + { + throw new AnnotatedException( + "Problem while picking certificates from X.509 store.", e); + } + catch (IOException e) + { + throw new AnnotatedException( + "Problem while extracting certificates from X.509 store.", e); + } + catch (CertificateException e) + { + throw new AnnotatedException( + "Problem while extracting certificates from X.509 store.", e); + } + } + else + { + CertStore certStore = (CertStore)obj; + + try + { + certs.addAll(certStore.getCertificates(certSelect)); + } + catch (CertStoreException e) + { + throw new AnnotatedException( + "Problem while picking certificates from certificate store.", + e); + } + } + } + return certs; + } + + protected static Collection findCertificates(PKIXCertStoreSelector certSelect, + List certStores) + throws AnnotatedException + { + Set certs = new HashSet(); + Iterator iter = certStores.iterator(); + + while (iter.hasNext()) + { + Object obj = iter.next(); + + if (obj instanceof Store) + { + Store certStore = (Store)obj; + try + { + certs.addAll(certStore.getMatches(certSelect)); + } + catch (StoreException e) + { + throw new AnnotatedException( + "Problem while picking certificates from X.509 store.", e); + } + } + else + { + CertStore certStore = (CertStore)obj; + + try + { + certs.addAll(PKIXCertStoreSelector.getCertificates(certSelect, certStore)); + } + catch (CertStoreException e) + { + throw new AnnotatedException( + "Problem while picking certificates from certificate store.", + e); + } + } + } + return certs; + } + + private static BigInteger getSerialNumber( + Object cert) + { + + return ((X509Certificate)cert).getSerialNumber(); + } + + protected static void getCertStatus( + Date validDate, + X509CRL crl, + Object cert, + CertStatus certStatus) + throws AnnotatedException + { + X509CRLEntry crl_entry = null; + + boolean isIndirect; + try + { + isIndirect = isIndirectCRL(crl); + } + catch (CRLException exception) + { + throw new AnnotatedException("Failed check for indirect CRL.", exception); + } + + if (isIndirect) + { + crl_entry = crl.getRevokedCertificate(getSerialNumber(cert)); + + if (crl_entry == null) + { + return; + } + + X500Principal certIssuer = crl_entry.getCertificateIssuer(); + + if (certIssuer == null) + { + certIssuer = getIssuerPrincipal(crl); + } + + if (!getEncodedIssuerPrincipal(cert).equals(certIssuer)) + { + return; + } + } + else if (!getEncodedIssuerPrincipal(cert).equals(getIssuerPrincipal(crl))) + { + return; // not for our issuer, ignore + } + else + { + crl_entry = crl.getRevokedCertificate(getSerialNumber(cert)); + + if (crl_entry == null) + { + return; + } + } + + ASN1Enumerated reasonCode = null; + if (crl_entry.hasExtensions()) + { + try + { + reasonCode = ASN1Enumerated + .getInstance(CertPathValidatorUtilities + .getExtensionValue(crl_entry, + Extension.reasonCode.getId())); + } + catch (Exception e) + { + throw new AnnotatedException( + "Reason code CRL entry extension could not be decoded.", + e); + } + } + + int reasonCodeValue = (null == reasonCode) + ? CRLReason.unspecified + : reasonCode.getValue().intValue(); + + // for reason keyCompromise, caCompromise, aACompromise or unspecified + if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime()) + || reasonCodeValue == CRLReason.unspecified + || reasonCodeValue == CRLReason.keyCompromise + || reasonCodeValue == CRLReason.cACompromise + || reasonCodeValue == CRLReason.aACompromise) + { + // (i) or (j) + certStatus.setCertStatus(reasonCodeValue); + certStatus.setRevocationDate(crl_entry.getRevocationDate()); + } + } + + /** + * Return the next working key inheriting DSA parameters if necessary. + *

      + * This methods inherits DSA parameters from the indexed certificate or + * previous certificates in the certificate chain to the returned + * PublicKey. The list is searched upwards, meaning the end + * certificate is at position 0 and previous certificates are following. + *

      + *

      + * If the indexed certificate does not contain a DSA key this method simply + * returns the public key. If the DSA key already contains DSA parameters + * the key is also only returned. + *

      + * + * @param certs The certification path. + * @param index The index of the certificate which contains the public key + * which should be extended with DSA parameters. + * @return The public key of the certificate in list position + * index extended with DSA parameters if applicable. + * @throws CertPathValidatorException if DSA parameters cannot be inherited. + */ + protected static PublicKey getNextWorkingKey(List certs, int index) + throws CertPathValidatorException + { + Certificate cert = (Certificate)certs.get(index); + PublicKey pubKey = cert.getPublicKey(); + if (!(pubKey instanceof DSAPublicKey)) + { + return pubKey; + } + DSAPublicKey dsaPubKey = (DSAPublicKey)pubKey; + if (dsaPubKey.getParams() != null) + { + return dsaPubKey; + } + for (int i = index + 1; i < certs.size(); i++) + { + X509Certificate parentCert = (X509Certificate)certs.get(i); + pubKey = parentCert.getPublicKey(); + if (!(pubKey instanceof DSAPublicKey)) + { + throw new CertPathValidatorException( + "DSA parameters cannot be inherited from previous certificate."); + } + DSAPublicKey prevDSAPubKey = (DSAPublicKey)pubKey; + if (prevDSAPubKey.getParams() == null) + { + continue; + } + DSAParams dsaParams = prevDSAPubKey.getParams(); + DSAPublicKeySpec dsaPubKeySpec = new DSAPublicKeySpec( + dsaPubKey.getY(), dsaParams.getP(), dsaParams.getQ(), dsaParams.getG()); + try + { + KeyFactory keyFactory = KeyFactory.getInstance("DSA"); + return keyFactory.generatePublic(dsaPubKeySpec); + } + catch (Exception exception) + { + throw new RuntimeException(exception.getMessage()); + } + } + throw new CertPathValidatorException("DSA parameters cannot be inherited from previous certificate."); + } + + protected static void verifyX509Certificate(X509Certificate cert, PublicKey publicKey, + String sigProvider) + throws GeneralSecurityException + { + if (sigProvider == null) + { + cert.verify(publicKey); + } + else + { + cert.verify(publicKey, sigProvider); + } + } + + static boolean isIndirectCRL(X509CRL crl) + throws CRLException + { + try + { + byte[] idp = crl.getExtensionValue(Extension.issuingDistributionPoint.getId()); + return idp != null + && IssuingDistributionPoint.getInstance(ASN1OctetString.getInstance(idp).getOctets()).isIndirectCRL(); + } + catch (Exception e) + { + throw new CRLException( + "Exception reading IssuingDistributionPoint: " + e); + } + } + + protected static Date getValidityDate(PKIXParameters paramsPKIX, Date currentDate) + { + Date validityDate = paramsPKIX.getDate(); + + return null == validityDate ? currentDate : validityDate; + } +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCRLUtil.java b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCRLUtil.java index 98c512ce0a..6e55b79cbd 100644 --- a/pkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCRLUtil.java +++ b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCRLUtil.java @@ -2,6 +2,7 @@ import java.security.cert.CertStore; import java.security.cert.CertStoreException; +import java.security.cert.PKIXParameters; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.Date; @@ -16,6 +17,30 @@ abstract class PKIXCRLUtil { + static Set findCRLs(X509CRLStoreSelector crlselect, PKIXParameters paramsPKIX) + throws AnnotatedException + { + return findCRLs(new PKIXCRLStoreSelector.Builder(crlselect).build(), paramsPKIX); + } + + static Set findCRLs(PKIXCRLStoreSelector crlselect, PKIXParameters paramsPKIX) + throws AnnotatedException + { + HashSet completeSet = new HashSet(); + + // get complete CRL(s) + try + { + findCRLs(completeSet, crlselect, paramsPKIX.getCertStores()); + } + catch (AnnotatedException e) + { + throw new AnnotatedException("Exception obtaining complete CRLs.", e); + } + + return completeSet; + } + static Set findCRLs(PKIXCRLStoreSelector crlselect, Date validityDate, List certStores, List pkixCrlStores) throws AnnotatedException { diff --git a/pkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCertPathReviewer.java b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCertPathReviewer.java new file mode 100644 index 0000000000..2234ca031e --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCertPathReviewer.java @@ -0,0 +1,2511 @@ +package org.bouncycastle.pkix.jcajce; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.URL; +import java.security.GeneralSecurityException; +import java.security.PublicKey; +import java.security.SignatureException; +import java.security.cert.CertPath; +import java.security.cert.CertPathValidatorException; +import java.security.cert.Certificate; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateFactory; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.PKIXCertPathChecker; +import java.security.cert.PKIXParameters; +import java.security.cert.PolicyNode; +import java.security.cert.TrustAnchor; +import java.security.cert.X509CRL; +import java.security.cert.X509CRLEntry; +import java.security.cert.X509CertSelector; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +import javax.security.auth.x500.X500Principal; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1Enumerated; +import org.bouncycastle.asn1.ASN1IA5String; +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.x509.AccessDescription; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.AuthorityInformationAccess; +import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; +import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.CRLDistPoint; +import org.bouncycastle.asn1.x509.DistributionPoint; +import org.bouncycastle.asn1.x509.DistributionPointName; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralNames; +import org.bouncycastle.asn1.x509.GeneralSubtree; +import org.bouncycastle.asn1.x509.IssuingDistributionPoint; +import org.bouncycastle.asn1.x509.NameConstraints; +import org.bouncycastle.asn1.x509.PolicyInformation; +import org.bouncycastle.asn1.x509.qualified.Iso4217CurrencyCode; +import org.bouncycastle.asn1.x509.qualified.MonetaryValue; +import org.bouncycastle.asn1.x509.qualified.QCStatement; +import org.bouncycastle.pkix.PKIXNameConstraintValidator; +import org.bouncycastle.pkix.PKIXNameConstraintValidatorException; +import org.bouncycastle.pkix.util.ErrorBundle; +import org.bouncycastle.pkix.util.LocaleString; +import org.bouncycastle.pkix.util.filter.TrustedInput; +import org.bouncycastle.pkix.util.filter.UntrustedInput; +import org.bouncycastle.pkix.util.filter.UntrustedUrlInput; +import org.bouncycastle.util.Integers; +import org.bouncycastle.util.Objects; + +/** + * PKIXCertPathReviewer
      + * Validation of X.509 Certificate Paths. Tries to find as much errors in the Path as possible. + */ +public class PKIXCertPathReviewer extends CertPathValidatorUtilities +{ + + private static final String QC_STATEMENT = Extension.qCStatements.getId(); + private static final String CRL_DIST_POINTS = Extension.cRLDistributionPoints.getId(); + private static final String AUTH_INFO_ACCESS = Extension.authorityInfoAccess.getId(); + + private static final String RESOURCE_NAME = "org.bouncycastle.pkix.CertPathReviewerMessages"; + + private static final int NAME_CHECK_MAX = (1 << 10); + + // input parameters + + protected CertPath certPath; + + protected PKIXParameters pkixParams; + + protected Date currentDate; + protected Date validDate; + + // state variables + + protected List certs; + + protected int n; + + // output variables + + protected List[] notifications; + protected List[] errors; + protected TrustAnchor trustAnchor; + protected PublicKey subjectPublicKey; + protected PolicyNode policyTree; + + private boolean initialized; + + /** + * Initializes the PKIXCertPathReviewer with the given {@link CertPath} and {@link PKIXParameters} params + * @param certPath the {@link CertPath} to validate + * @param params the {@link PKIXParameters} to use + * @throws CertPathReviewerException if the certPath is empty + * @throws IllegalStateException if the {@link PKIXCertPathReviewer} is already initialized + */ + public void init(CertPath certPath, PKIXParameters params) + throws CertPathReviewerException + { + if (initialized) + { + throw new IllegalStateException("object is already initialized!"); + } + initialized = true; + + // check input parameters + if (certPath == null) + { + throw new NullPointerException("certPath was null"); + } + + List cs = (List)certPath.getCertificates(); + if (cs.size() != 1) + { + // check trust anchor not included in certPath as it will + // cause havoc otherwise. + Set tas = new HashSet(); + for (Iterator it = params.getTrustAnchors().iterator(); it.hasNext();) + { + TrustAnchor ta = (TrustAnchor)it.next(); + + tas.add(ta.getTrustedCert()); + } + + List certs = new ArrayList(); + for (int i = 0; i != cs.size(); i++) + { + // don't include the trust anchor + if (!tas.contains(cs.get(i))) + { + certs.add(cs.get(i)); + } + } + try + { + CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); + + this.certPath = cf.generateCertPath(certs); + } + catch (GeneralSecurityException e) + { + throw new IllegalStateException("unable to rebuild certpath"); + } + this.certs = certs; + } + else + { + this.certPath = certPath; + this.certs = certPath.getCertificates(); + } + + n = certs.size(); + if (certs.isEmpty()) + { + throw new CertPathReviewerException( + createErrorBundle("CertPathReviewer.emptyCertPath")); + } + + pkixParams = (PKIXParameters) params.clone(); + + // 6.1.1 - Inputs + + // a) done + + // b) + + currentDate = new Date(); + validDate = getValidityDate(pkixParams, currentDate); + + // c) part of pkixParams + + // d) done at the beginning of checkSignatures + + // e) f) g) part of pkixParams + + // initialize output parameters + + notifications = null; + errors = null; + trustAnchor = null; + subjectPublicKey = null; + policyTree = null; + } + + /** + * Creates a PKIXCertPathReviewer and initializes it with the given {@link CertPath} and {@link PKIXParameters} params + * @param certPath the {@link CertPath} to validate + * @param params the {@link PKIXParameters} to use + * @throws CertPathReviewerException if the certPath is empty + */ + public PKIXCertPathReviewer(CertPath certPath, PKIXParameters params) + throws CertPathReviewerException + { + init(certPath, params); + } + + /** + * Creates an empty PKIXCertPathReviewer. Don't forget to call init() to initialize the object. + */ + public PKIXCertPathReviewer() + { + // do nothing + } + + /** + * + * @return the CertPath that was validated + */ + public CertPath getCertPath() + { + return certPath; + } + + /** + * + * @return the size of the CertPath + */ + public int getCertPathSize() + { + return n; + } + + /** + * Returns an Array of Lists which contains a List of global error messages + * and a List of error messages for each certificate in the path. + * The global error List is at index 0. The error lists for each certificate at index 1 to n. + * The error messages are of type. + * @return the Array of Lists which contain the error messages + * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized + */ + public List[] getErrors() + { + doChecks(); + return errors; + } + + /** + * Returns an List of error messages for the certificate at the given index in the CertPath. + * If index == -1 then the list of global errors is returned with errors not specific to a certificate. + * @param index the index of the certificate in the CertPath + * @return List of error messages for the certificate + * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized + */ + public List getErrors(int index) + { + doChecks(); + return errors[index + 1]; + } + + /** + * Returns an Array of Lists which contains a List of global notification messages + * and a List of botification messages for each certificate in the path. + * The global notificatio List is at index 0. The notification lists for each certificate at index 1 to n. + * The error messages are of type. + * @return the Array of Lists which contain the notification messages + * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized + */ + public List[] getNotifications() + { + doChecks(); + return notifications; + } + + /** + * Returns an List of notification messages for the certificate at the given index in the CertPath. + * If index == -1 then the list of global notifications is returned with notifications not specific to a certificate. + * @param index the index of the certificate in the CertPath + * @return List of notification messages for the certificate + * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized + */ + public List getNotifications(int index) + { + doChecks(); + return notifications[index + 1]; + } + + /** + * + * @return the valid policy tree, null if no valid policy exists. + * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized + */ + public PolicyNode getPolicyTree() + { + doChecks(); + return policyTree; + } + + /** + * + * @return the PublicKey if the last certificate in the CertPath + * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized + */ + public PublicKey getSubjectPublicKey() + { + doChecks(); + return subjectPublicKey; + } + + /** + * + * @return the TrustAnchor for the CertPath, null if no valid TrustAnchor was found. + * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized + */ + public TrustAnchor getTrustAnchor() + { + doChecks(); + return trustAnchor; + } + + /** + * + * @return if the CertPath is valid + * @throws IllegalStateException if the {@link PKIXCertPathReviewer} was not initialized + */ + public boolean isValidCertPath() + { + doChecks(); + boolean valid = true; + for (int i = 0; i < errors.length; i++) + { + if (!errors[i].isEmpty()) + { + valid = false; + break; + } + } + return valid; + } + + protected void addNotification(ErrorBundle msg) + { + notifications[0].add(msg); + } + + protected void addNotification(ErrorBundle msg, int index) + { + if (index < -1 || index >= n) + { + throw new IndexOutOfBoundsException(); + } + notifications[index + 1].add(msg); + } + + protected void addError(ErrorBundle msg) + { + errors[0].add(msg); + } + + protected void addError(ErrorBundle msg, int index) + { + if (index < -1 || index >= n) + { + throw new IndexOutOfBoundsException(); + } + errors[index + 1].add(msg); + } + + protected void doChecks() + { + if (!initialized) + { + throw new IllegalStateException("Object not initialized. Call init() first."); + } + if (notifications == null) + { + // initialize lists + notifications = new List[n+1]; + errors = new List[n+1]; + + for (int i = 0; i < notifications.length; i++) + { + notifications[i] = new ArrayList(); + errors[i] = new ArrayList(); + } + + // check Signatures + checkSignatures(); + + // check Name Constraints + checkNameConstraints(); + + // check Path Length + checkPathLength(); + + // check Policy + checkPolicy(); + + // check other critical extensions + checkCriticalExtensions(); + + } + } + + private void checkNameConstraints() + { + X509Certificate cert = null; + + // + // Setup + // + + // (b) and (c) + PKIXNameConstraintValidator nameConstraintValidator = new PKIXNameConstraintValidator(); + + // + // process each certificate except the last in the path + // + int index; + int i; + + try + { + for (index = certs.size()-1; index>0; index--) + { + i = n - index; + + // + // certificate processing + // + + cert = (X509Certificate) certs.get(index); + + // b),c) + + if (!isSelfIssued(cert)) + { + X500Principal principal = getSubjectPrincipal(cert); + ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(principal.getEncoded())); + ASN1Sequence dns; + + try + { + dns = (ASN1Sequence)aIn.readObject(); + } + catch (IOException e) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.ncSubjectNameError", + new Object[] {new UntrustedInput(principal)}); + throw new CertPathReviewerException(msg,e,certPath,index); + } + + try + { + nameConstraintValidator.checkPermittedDN(dns); + } + catch (PKIXNameConstraintValidatorException cpve) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.notPermittedDN", + new Object[] {new UntrustedInput(principal.getName())}); + throw new CertPathReviewerException(msg,cpve,certPath,index); + } + + try + { + nameConstraintValidator.checkExcludedDN(dns); + } + catch (PKIXNameConstraintValidatorException cpve) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.excludedDN", + new Object[] {new UntrustedInput(principal.getName())}); + throw new CertPathReviewerException(msg,cpve,certPath,index); + } + + ASN1Sequence altName; + try + { + altName = (ASN1Sequence)getExtensionValue(cert, SUBJECT_ALTERNATIVE_NAME); + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.subjAltNameExtError"); + throw new CertPathReviewerException(msg,ae,certPath,index); + } + + /* + * TODO RFC3280CertPathUtilities (used in CertPath validation) has a block checking name + * constraints against subject's EmailAddress, which could be worth adding here too. + */ + + if (altName != null) + { + if (altName.size() > NAME_CHECK_MAX) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.subjAltNameExtError"); + throw new CertPathReviewerException(msg,certPath,index); + } + + for (int j = 0; j < altName.size(); j++) + { + GeneralName name = GeneralName.getInstance(altName.getObjectAt(j)); + + try + { + nameConstraintValidator.checkPermitted(name); + nameConstraintValidator.checkExcluded(name); + } + catch (PKIXNameConstraintValidatorException cpve) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.notPermittedEmail", + new Object[] {new UntrustedInput(name)}); + throw new CertPathReviewerException(msg,cpve,certPath,index); + } + } + } + } + + // + // prepare for next certificate + // + + // + // (g) handle the name constraints extension + // + ASN1Sequence ncSeq; + try + { + ncSeq = (ASN1Sequence)getExtensionValue(cert, NAME_CONSTRAINTS); + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.ncExtError"); + throw new CertPathReviewerException(msg,ae,certPath,index); + } + + if (ncSeq != null) + { + NameConstraints nc = NameConstraints.getInstance(ncSeq); + + // + // (g) (1) permitted subtrees + // + GeneralSubtree[] permitted = nc.getPermittedSubtrees(); + if (permitted != null) + { + nameConstraintValidator.intersectPermittedSubtree(permitted); + } + + // + // (g) (2) excluded subtrees + // + GeneralSubtree[] excluded = nc.getExcludedSubtrees(); + if (excluded != null) + { + for (int c = 0; c != excluded.length; c++) + { + nameConstraintValidator.addExcludedSubtree(excluded[c]); + } + } + } + + } // for + } + catch (CertPathReviewerException cpre) + { + addError(cpre.getErrorMessage(),cpre.getIndex()); + } + + } + + /* + * checks: - path length constraints and reports - total path length + */ + private void checkPathLength() + { + // init + int maxPathLength = n; + int totalPathLength = 0; + + X509Certificate cert = null; + + int i; + for (int index = certs.size() - 1; index > 0; index--) + { + i = n - index; + + cert = (X509Certificate) certs.get(index); + + // l) + + if (!isSelfIssued(cert)) + { + if (maxPathLength <= 0) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.pathLengthExtended"); + addError(msg); + } + maxPathLength--; + totalPathLength++; + } + + // m) + + BasicConstraints bc; + try + { + bc = BasicConstraints.getInstance(getExtensionValue(cert, + BASIC_CONSTRAINTS)); + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.processLengthConstError"); + addError(msg,index); + bc = null; + } + + if (bc != null && bc.isCA()) + { + ASN1Integer pathLenConstraint = bc.getPathLenConstraintInteger(); + if (pathLenConstraint != null) + { + maxPathLength = Math.min(maxPathLength, pathLenConstraint.intPositiveValueExact()); + } + } + } + + ErrorBundle msg = createErrorBundle("CertPathReviewer.totalPathLength", + new Object[]{Integers.valueOf(totalPathLength)}); + + addNotification(msg); + } + + /* + * checks: - signatures - name chaining - validity of certificates - todo: + * if certificate revoked (if specified in the parameters) + */ + private void checkSignatures() + { + // 1.6.1 - Inputs + + // d) + + TrustAnchor trust = null; + X500Principal trustPrincipal = null; + + // validation date + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.certPathValidDate", + new Object[] {new TrustedInput(validDate), new TrustedInput(currentDate)}); + addNotification(msg); + } + + // find trust anchors + try + { + X509Certificate cert = (X509Certificate) certs.get(certs.size() - 1); + + Collection trustColl = getTrustAnchors(cert,pkixParams.getTrustAnchors()); + if (trustColl.size() > 1) + { + // conflicting trust anchors + ErrorBundle msg = createErrorBundle( + "CertPathReviewer.conflictingTrustAnchors", + new Object[]{Integers.valueOf(trustColl.size()), + new UntrustedInput(cert.getIssuerX500Principal())}); + addError(msg); + } + else if (trustColl.isEmpty()) + { + ErrorBundle msg = createErrorBundle( + "CertPathReviewer.noTrustAnchorFound", + new Object[]{new UntrustedInput(cert.getIssuerX500Principal()), + Integers.valueOf(pkixParams.getTrustAnchors().size())}); + addError(msg); + } + else + { + PublicKey trustPublicKey; + trust = (TrustAnchor) trustColl.iterator().next(); + if (trust.getTrustedCert() != null) + { + trustPublicKey = trust.getTrustedCert().getPublicKey(); + } + else + { + trustPublicKey = trust.getCAPublicKey(); + } + + try + { + CertPathValidatorUtilities.verifyX509Certificate(cert, trustPublicKey, + pkixParams.getSigProvider()); + } + catch (SignatureException e) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.trustButInvalidCert"); + addError(msg); + } + catch (Exception e) + { + // do nothing, error occurs again later + } + } + } + catch (CertPathReviewerException cpre) + { + addError(cpre.getErrorMessage()); + } + catch (Throwable t) + { + ErrorBundle msg = createErrorBundle( + "CertPathReviewer.unknown", + new Object[] {new UntrustedInput(t.getMessage()), new UntrustedInput(t)}); + addError(msg); + } + + if (trust != null) + { + // get the name of the trustAnchor + X509Certificate sign = trust.getTrustedCert(); + try + { + if (sign != null) + { + trustPrincipal = getSubjectPrincipal(sign); + } + else + { + trustPrincipal = new X500Principal(trust.getCAName()); + } + } + catch (IllegalArgumentException ex) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.trustDNInvalid", + new Object[] {new UntrustedInput(trust.getCAName())}); + addError(msg); + } + + // test key usages of the trust anchor + if (sign != null) + { + boolean[] ku = sign.getKeyUsage(); + if (ku != null && (ku.length <= 5 || !ku[5])) + { + ErrorBundle msg = createErrorBundle( "CertPathReviewer.trustKeyUsage"); + addNotification(msg); + } + } + } + + // 1.6.2 - Initialization + + PublicKey workingPublicKey = null; + X500Principal workingIssuerName = trustPrincipal; + + X509Certificate sign = null; + + AlgorithmIdentifier workingAlgId = null; + ASN1ObjectIdentifier workingPublicKeyAlgorithm = null; + ASN1Encodable workingPublicKeyParameters = null; + + if (trust != null) + { + sign = trust.getTrustedCert(); + + if (sign != null) + { + workingPublicKey = sign.getPublicKey(); + } + else + { + workingPublicKey = trust.getCAPublicKey(); + } + + try + { + workingAlgId = getAlgorithmIdentifier(workingPublicKey); + workingPublicKeyAlgorithm = workingAlgId.getAlgorithm(); + workingPublicKeyParameters = workingAlgId.getParameters(); + } + catch (CertPathValidatorException ex) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.trustPubKeyError"); + addError(msg); + workingAlgId = null; + } + } + + // Basic cert checks + + X509Certificate cert = null; + int i; + + for (int index = certs.size() - 1; index >= 0; index--) + { + // + // i as defined in the algorithm description + // + i = n - index; + + // + // set certificate to be checked in this round + // sign and workingPublicKey and workingIssuerName are set + // at the end of the for loop and initialied the + // first time from the TrustAnchor + // + cert = (X509Certificate) certs.get(index); + // verify signature + if (workingPublicKey != null) + { + try + { + CertPathValidatorUtilities.verifyX509Certificate(cert, workingPublicKey, + pkixParams.getSigProvider()); + } + catch (GeneralSecurityException ex) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.signatureNotVerified", + new Object[] {ex.getMessage(),ex,ex.getClass().getName()}); + addError(msg,index); + } + } + else if (isSelfIssued(cert)) + { + try + { + CertPathValidatorUtilities.verifyX509Certificate(cert, cert.getPublicKey(), + pkixParams.getSigProvider()); + ErrorBundle msg = createErrorBundle("CertPathReviewer.rootKeyIsValidButNotATrustAnchor"); + addError(msg, index); + } + catch (GeneralSecurityException ex) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.signatureNotVerified", + new Object[] {ex.getMessage(),ex,ex.getClass().getName()}); + addError(msg,index); + } + } + else + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.NoIssuerPublicKey"); + // if there is an authority key extension add the serial and issuer of the missing certificate + byte[] akiBytes = cert.getExtensionValue(Extension.authorityKeyIdentifier.getId()); + if (akiBytes != null) + { + AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance( + DEROctetString.getInstance(akiBytes).getOctets()); + GeneralNames issuerNames = aki.getAuthorityCertIssuer(); + if (issuerNames != null) + { + GeneralName name = issuerNames.getNames()[0]; + BigInteger serial = aki.getAuthorityCertSerialNumber(); + if (serial != null) + { + Object[] extraArgs = {new LocaleString(RESOURCE_NAME, "missingIssuer"), " \"", name , + "\" ", new LocaleString(RESOURCE_NAME, "missingSerial") , " ", serial}; + msg.setExtraArguments(extraArgs); + } + } + } + addError(msg,index); + } + + // certificate valid? + try + { + cert.checkValidity(validDate); + } + catch (CertificateNotYetValidException cnve) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.certificateNotYetValid", + new Object[] {new TrustedInput(cert.getNotBefore())}); + addError(msg,index); + } + catch (CertificateExpiredException cee) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.certificateExpired", + new Object[] {new TrustedInput(cert.getNotAfter())}); + addError(msg,index); + } + + // certificate revoked? + if (pkixParams.isRevocationEnabled()) + { + // read crl distribution points extension + CRLDistPoint crlDistPoints = null; + try + { + ASN1Primitive crl_dp = getExtensionValue(cert,CRL_DIST_POINTS); + if (crl_dp != null) + { + crlDistPoints = CRLDistPoint.getInstance(crl_dp); + } + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlDistPtExtError"); + addError(msg,index); + } + + // read authority information access extension + AuthorityInformationAccess authInfoAcc = null; + try + { + ASN1Primitive auth_info_acc = getExtensionValue(cert,AUTH_INFO_ACCESS); + if (auth_info_acc != null) + { + authInfoAcc = AuthorityInformationAccess.getInstance(auth_info_acc); + } + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlAuthInfoAccError"); + addError(msg,index); + } + + Vector crlDistPointUrls = getCRLDistUrls(crlDistPoints); + Vector ocspUrls = getOCSPUrls(authInfoAcc); + + // add notifications with the crl distribution points + + // output crl distribution points + Iterator urlIt = crlDistPointUrls.iterator(); + while (urlIt.hasNext()) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlDistPoint", + new Object[] {new UntrustedUrlInput(urlIt.next())}); + addNotification(msg,index); + } + + // output ocsp urls + urlIt = ocspUrls.iterator(); + while (urlIt.hasNext()) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.ocspLocation", + new Object[] {new UntrustedUrlInput(urlIt.next())}); + addNotification(msg,index); + } + + // TODO also support Netscapes revocation-url and/or OCSP instead of CRLs for revocation checking + // check CRLs + try + { + checkRevocation(pkixParams, cert, validDate, sign, workingPublicKey, crlDistPointUrls, ocspUrls, index); + } + catch (CertPathReviewerException cpre) + { + addError(cpre.getErrorMessage(),index); + } + } + + // certificate issuer correct + if (workingIssuerName != null && !cert.getIssuerX500Principal().equals(workingIssuerName)) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.certWrongIssuer", + new Object[] {workingIssuerName.getName(), + cert.getIssuerX500Principal().getName()}); + addError(msg,index); + } + + // + // prepare for next certificate + // + if (i != n) + { + + if (cert != null && cert.getVersion() == 1) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.noCACert"); + addError(msg,index); + } + + // k) + + BasicConstraints bc; + try + { + bc = BasicConstraints.getInstance(getExtensionValue(cert, + BASIC_CONSTRAINTS)); + if (bc != null) + { + if (!bc.isCA()) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.noCACert"); + addError(msg,index); + } + } + else + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.noBasicConstraints"); + addError(msg,index); + } + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.errorProcesingBC"); + addError(msg,index); + } + + // n) + + boolean[] keyUsage = cert.getKeyUsage(); + + if (keyUsage != null && (keyUsage.length <= KEY_CERT_SIGN || !keyUsage[KEY_CERT_SIGN])) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.noCertSign"); + addError(msg,index); + } + + } // if + + // set signing certificate for next round + sign = cert; + + // c) + + workingIssuerName = cert.getSubjectX500Principal(); + + // d) e) f) + + try + { + workingPublicKey = getNextWorkingKey(certs, index); + workingAlgId = getAlgorithmIdentifier(workingPublicKey); + workingPublicKeyAlgorithm = workingAlgId.getAlgorithm(); + workingPublicKeyParameters = workingAlgId.getParameters(); + } + catch (CertPathValidatorException ex) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.pubKeyError"); + addError(msg,index); + workingAlgId = null; + workingPublicKeyAlgorithm = null; + workingPublicKeyParameters = null; + } + + } // for + + trustAnchor = trust; + subjectPublicKey = workingPublicKey; + } + + private void checkPolicy() + { + // + // 6.1.1 Inputs + // + + // c) Initial Policy Set + + Set userInitialPolicySet = pkixParams.getInitialPolicies(); + + // e) f) g) are part of pkixParams + + // + // 6.1.2 Initialization + // + + // a) valid policy tree + + List[] policyNodes = new ArrayList[n + 1]; + for (int j = 0; j < policyNodes.length; j++) + { + policyNodes[j] = new ArrayList(); + } + + Set policySet = new HashSet(); + + policySet.add(ANY_POLICY); + + PKIXPolicyNode validPolicyTree = new PKIXPolicyNode(new ArrayList(), 0, + policySet, null, new HashSet(), ANY_POLICY, false); + + policyNodes[0].add(validPolicyTree); + + // d) explicit policy + + int explicitPolicy; + if (pkixParams.isExplicitPolicyRequired()) + { + explicitPolicy = 0; + } + else + { + explicitPolicy = n + 1; + } + + // e) inhibit any policy + + int inhibitAnyPolicy; + if (pkixParams.isAnyPolicyInhibited()) + { + inhibitAnyPolicy = 0; + } + else + { + inhibitAnyPolicy = n + 1; + } + + // f) policy mapping + + int policyMapping; + if (pkixParams.isPolicyMappingInhibited()) + { + policyMapping = 0; + } + else + { + policyMapping = n + 1; + } + + Set acceptablePolicies = null; + + // + // 6.1.3 Basic Certificate processing + // + + X509Certificate cert = null; + int index; + int i; + + try + { + for (index = certs.size() - 1; index >= 0; index--) + { + // i as defined in the algorithm description + i = n - index; + + // set certificate to be checked in this round + cert = (X509Certificate) certs.get(index); + + // d) process policy information + + ASN1Sequence certPolicies; + try + { + certPolicies = (ASN1Sequence) getExtensionValue( + cert, CERTIFICATE_POLICIES); + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.policyExtError"); + throw new CertPathReviewerException(msg,ae,certPath,index); + } + if (certPolicies != null && validPolicyTree != null) + { + + // d) 1) + + Enumeration e = certPolicies.getObjects(); + Set pols = new HashSet(); + + while (e.hasMoreElements()) + { + PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement()); + ASN1ObjectIdentifier pOid = pInfo.getPolicyIdentifier(); + + pols.add(pOid.getId()); + + if (!ANY_POLICY.equals(pOid.getId())) + { + Set pq; + try + { + pq = getQualifierSet(pInfo.getPolicyQualifiers()); + } + catch (CertPathValidatorException cpve) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.policyQualifierError"); + throw new CertPathReviewerException(msg,cpve,certPath,index); + } + + boolean match = processCertD1i(i, policyNodes, pOid, pq); + + if (!match) + { + processCertD1ii(i, policyNodes, pOid, pq); + } + } + } + + if (acceptablePolicies == null || acceptablePolicies.contains(ANY_POLICY)) + { + acceptablePolicies = pols; + } + else + { + Iterator it = acceptablePolicies.iterator(); + Set t1 = new HashSet(); + + while (it.hasNext()) + { + Object o = it.next(); + + if (pols.contains(o)) + { + t1.add(o); + } + } + + acceptablePolicies = t1; + } + + // d) 2) + + if ((inhibitAnyPolicy > 0) || ((i < n) && isSelfIssued(cert))) + { + e = certPolicies.getObjects(); + + while (e.hasMoreElements()) + { + PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement()); + + if (ANY_POLICY.equals(pInfo.getPolicyIdentifier().getId())) + { + Set _apq; + try + { + _apq = getQualifierSet(pInfo.getPolicyQualifiers()); + } + catch (CertPathValidatorException cpve) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.policyQualifierError"); + throw new CertPathReviewerException(msg,cpve,certPath,index); + } + List _nodes = policyNodes[i - 1]; + + for (int k = 0; k < _nodes.size(); k++) + { + PKIXPolicyNode _node = (PKIXPolicyNode) _nodes.get(k); + + Iterator _policySetIter = _node.getExpectedPolicies().iterator(); + while (_policySetIter.hasNext()) + { + Object _tmp = _policySetIter.next(); + + String _policy; + if (_tmp instanceof String) + { + _policy = (String) _tmp; + } + else if (_tmp instanceof ASN1ObjectIdentifier) + { + _policy = ((ASN1ObjectIdentifier) _tmp).getId(); + } + else + { + continue; + } + + boolean _found = false; + Iterator _childrenIter = _node + .getChildren(); + + while (_childrenIter.hasNext()) + { + PKIXPolicyNode _child = (PKIXPolicyNode) _childrenIter.next(); + + if (_policy.equals(_child.getValidPolicy())) + { + _found = true; + } + } + + if (!_found) + { + Set _newChildExpectedPolicies = new HashSet(); + _newChildExpectedPolicies.add(_policy); + + PKIXPolicyNode _newChild = new PKIXPolicyNode( + new ArrayList(), i, + _newChildExpectedPolicies, + _node, _apq, _policy, false); + _node.addChild(_newChild); + policyNodes[i].add(_newChild); + } + } + } + break; + } + } + } + + // + // (d) (3) + // + for (int j = (i - 1); j >= 0; j--) + { + List nodes = policyNodes[j]; + + for (int k = 0; k < nodes.size(); k++) + { + PKIXPolicyNode node = (PKIXPolicyNode) nodes.get(k); + if (!node.hasChildren()) + { + validPolicyTree = removePolicyNode( + validPolicyTree, policyNodes, node); + if (validPolicyTree == null) + { + break; + } + } + } + } + + // + // d (4) + // + Set criticalExtensionOids = cert.getCriticalExtensionOIDs(); + + if (criticalExtensionOids != null) + { + boolean critical = criticalExtensionOids.contains(CERTIFICATE_POLICIES); + + List nodes = policyNodes[i]; + for (int j = 0; j < nodes.size(); j++) + { + PKIXPolicyNode node = (PKIXPolicyNode) nodes.get(j); + node.setCritical(critical); + } + } + + } + + // e) + + if (certPolicies == null) + { + validPolicyTree = null; + } + + // f) + + if (explicitPolicy <= 0 && validPolicyTree == null) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.noValidPolicyTree"); + throw new CertPathReviewerException(msg); + } + + // + // 6.1.4 preparation for next Certificate + // + + if (i != n) + { + + // a) + + ASN1Primitive pm; + try + { + pm = getExtensionValue(cert, POLICY_MAPPINGS); + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.policyMapExtError"); + throw new CertPathReviewerException(msg,ae,certPath,index); + } + + if (pm != null) + { + ASN1Sequence mappings = (ASN1Sequence) pm; + for (int j = 0; j < mappings.size(); j++) + { + ASN1Sequence mapping = (ASN1Sequence) mappings.getObjectAt(j); + ASN1ObjectIdentifier ip_id = (ASN1ObjectIdentifier) mapping.getObjectAt(0); + ASN1ObjectIdentifier sp_id = (ASN1ObjectIdentifier) mapping.getObjectAt(1); + if (ANY_POLICY.equals(ip_id.getId())) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.invalidPolicyMapping"); + throw new CertPathReviewerException(msg,certPath,index); + } + if (ANY_POLICY.equals(sp_id.getId())) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.invalidPolicyMapping"); + throw new CertPathReviewerException(msg,certPath,index); + } + } + } + + // b) + + if (pm != null) + { + ASN1Sequence mappings = (ASN1Sequence)pm; + Map m_idp = new HashMap(); + Set s_idp = new HashSet(); + + for (int j = 0; j < mappings.size(); j++) + { + ASN1Sequence mapping = (ASN1Sequence)mappings.getObjectAt(j); + String id_p = ((ASN1ObjectIdentifier)mapping.getObjectAt(0)).getId(); + String sd_p = ((ASN1ObjectIdentifier)mapping.getObjectAt(1)).getId(); + Set tmp; + + if (!m_idp.containsKey(id_p)) + { + tmp = new HashSet(); + tmp.add(sd_p); + m_idp.put(id_p, tmp); + s_idp.add(id_p); + } + else + { + tmp = (Set)m_idp.get(id_p); + tmp.add(sd_p); + } + } + + Iterator it_idp = s_idp.iterator(); + while (it_idp.hasNext()) + { + String id_p = (String)it_idp.next(); + + // + // (1) + // + if (policyMapping > 0) + { + try + { + prepareNextCertB1(i,policyNodes,id_p,m_idp,cert); + } + catch (AnnotatedException ae) + { + // error processing certificate policies extension + ErrorBundle msg = createErrorBundle("CertPathReviewer.policyExtError"); + throw new CertPathReviewerException(msg,ae,certPath,index); + } + catch (CertPathValidatorException cpve) + { + // error building qualifier set + ErrorBundle msg = createErrorBundle("CertPathReviewer.policyQualifierError"); + throw new CertPathReviewerException(msg,cpve,certPath,index); + } + + // + // (2) + // + } + else if (policyMapping <= 0) + { + validPolicyTree = prepareNextCertB2(i,policyNodes,id_p,validPolicyTree); + } + + } + } + + // + // h) + // + + if (!isSelfIssued(cert)) + { + + // (1) + if (explicitPolicy != 0) + { + explicitPolicy--; + } + + // (2) + if (policyMapping != 0) + { + policyMapping--; + } + + // (3) + if (inhibitAnyPolicy != 0) + { + inhibitAnyPolicy--; + } + + } + + // + // i) + // + + try + { + ASN1Sequence pc = (ASN1Sequence) getExtensionValue(cert,POLICY_CONSTRAINTS); + if (pc != null) + { + Enumeration policyConstraints = pc.getObjects(); + + while (policyConstraints.hasMoreElements()) + { + ASN1TaggedObject constraint = (ASN1TaggedObject) policyConstraints.nextElement(); + int tmpInt; + + switch (constraint.getTagNo()) + { + case 0: + tmpInt = ASN1Integer.getInstance(constraint, false).intValueExact(); + if (tmpInt < explicitPolicy) + { + explicitPolicy = tmpInt; + } + break; + case 1: + tmpInt = ASN1Integer.getInstance(constraint, false).intValueExact(); + if (tmpInt < policyMapping) + { + policyMapping = tmpInt; + } + break; + } + } + } + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.policyConstExtError"); + throw new CertPathReviewerException(msg,certPath,index); + } + + // + // j) + // + + try + { + ASN1Integer iap = (ASN1Integer)getExtensionValue(cert, INHIBIT_ANY_POLICY); + + if (iap != null) + { + int _inhibitAnyPolicy = iap.intValueExact(); + + if (_inhibitAnyPolicy < inhibitAnyPolicy) + { + inhibitAnyPolicy = _inhibitAnyPolicy; + } + } + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.policyInhibitExtError"); + throw new CertPathReviewerException(msg,certPath,index); + } + } + + } + + // + // 6.1.5 Wrap up + // + + // + // a) + // + + if (!isSelfIssued(cert) && explicitPolicy > 0) + { + explicitPolicy--; + } + + // + // b) + // + + try + { + ASN1Sequence pc = (ASN1Sequence) getExtensionValue(cert, POLICY_CONSTRAINTS); + if (pc != null) + { + Enumeration policyConstraints = pc.getObjects(); + + while (policyConstraints.hasMoreElements()) + { + ASN1TaggedObject constraint = (ASN1TaggedObject)policyConstraints.nextElement(); + switch (constraint.getTagNo()) + { + case 0: + int tmpInt = ASN1Integer.getInstance(constraint, false).intValueExact(); + if (tmpInt == 0) + { + explicitPolicy = 0; + } + break; + } + } + } + } + catch (AnnotatedException e) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.policyConstExtError"); + throw new CertPathReviewerException(msg,certPath,index); + } + + + // + // (g) + // + PKIXPolicyNode intersection; + + + // + // (g) (i) + // + if (validPolicyTree == null) + { + if (pkixParams.isExplicitPolicyRequired()) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.explicitPolicy"); + throw new CertPathReviewerException(msg,certPath,index); + } + intersection = null; + } + else if (isAnyPolicy(userInitialPolicySet)) // (g) (ii) + { + if (pkixParams.isExplicitPolicyRequired()) + { + if (acceptablePolicies.isEmpty()) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.explicitPolicy"); + throw new CertPathReviewerException(msg,certPath,index); + } + else + { + Set _validPolicyNodeSet = new HashSet(); + + for (int j = 0; j < policyNodes.length; j++) + { + List _nodeDepth = policyNodes[j]; + + for (int k = 0; k < _nodeDepth.size(); k++) + { + PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k); + + if (ANY_POLICY.equals(_node.getValidPolicy())) + { + Iterator _iter = _node.getChildren(); + while (_iter.hasNext()) + { + _validPolicyNodeSet.add(_iter.next()); + } + } + } + } + + Iterator _vpnsIter = _validPolicyNodeSet.iterator(); + while (_vpnsIter.hasNext()) + { + PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next(); + String _validPolicy = _node.getValidPolicy(); + + if (!acceptablePolicies.contains(_validPolicy)) + { + //validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, _node); + } + } + if (validPolicyTree != null) + { + for (int j = (n - 1); j >= 0; j--) + { + List nodes = policyNodes[j]; + + for (int k = 0; k < nodes.size(); k++) + { + PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k); + if (!node.hasChildren()) + { + validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node); + } + } + } + } + } + } + + intersection = validPolicyTree; + } + else + { + // + // (g) (iii) + // + // This implementation is not exactly same as the one described in RFC3280. + // However, as far as the validation result is concerned, both produce + // adequate result. The only difference is whether AnyPolicy is remain + // in the policy tree or not. + // + // (g) (iii) 1 + // + Set _validPolicyNodeSet = new HashSet(); + + for (int j = 0; j < policyNodes.length; j++) + { + List _nodeDepth = policyNodes[j]; + + for (int k = 0; k < _nodeDepth.size(); k++) + { + PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k); + + if (ANY_POLICY.equals(_node.getValidPolicy())) + { + Iterator _iter = _node.getChildren(); + while (_iter.hasNext()) + { + PKIXPolicyNode _c_node = (PKIXPolicyNode)_iter.next(); + if (!ANY_POLICY.equals(_c_node.getValidPolicy())) + { + _validPolicyNodeSet.add(_c_node); + } + } + } + } + } + + // + // (g) (iii) 2 + // + Iterator _vpnsIter = _validPolicyNodeSet.iterator(); + while (_vpnsIter.hasNext()) + { + PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next(); + String _validPolicy = _node.getValidPolicy(); + + if (!userInitialPolicySet.contains(_validPolicy)) + { + validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, _node); + } + } + + // + // (g) (iii) 4 + // + if (validPolicyTree != null) + { + for (int j = (n - 1); j >= 0; j--) + { + List nodes = policyNodes[j]; + + for (int k = 0; k < nodes.size(); k++) + { + PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k); + if (!node.hasChildren()) + { + validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node); + } + } + } + } + + intersection = validPolicyTree; + } + + if ((explicitPolicy <= 0) && (intersection == null)) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.invalidPolicy"); + throw new CertPathReviewerException(msg); + } + + validPolicyTree = intersection; + } + catch (CertPathReviewerException cpre) + { + addError(cpre.getErrorMessage(),cpre.getIndex()); + validPolicyTree = null; + } + } + + private void checkCriticalExtensions() + { + // + // initialise CertPathChecker's + // + List pathCheckers = pkixParams.getCertPathCheckers(); + Iterator certIter = pathCheckers.iterator(); + + try + { + try + { + while (certIter.hasNext()) + { + ((PKIXCertPathChecker)certIter.next()).init(false); + } + } + catch (CertPathValidatorException cpve) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.certPathCheckerError", + new Object[] {cpve.getMessage(),cpve,cpve.getClass().getName()}); + throw new CertPathReviewerException(msg,cpve); + } + + // + // process critical extensions for each certificate + // + + X509Certificate cert = null; + + int index; + + for (index = certs.size()-1; index >= 0; index--) + { + cert = (X509Certificate) certs.get(index); + + Set criticalExtensions = cert.getCriticalExtensionOIDs(); + if (criticalExtensions == null || criticalExtensions.isEmpty()) + { + continue; + } + // remove already processed extensions + criticalExtensions.remove(KEY_USAGE); + criticalExtensions.remove(CERTIFICATE_POLICIES); + criticalExtensions.remove(POLICY_MAPPINGS); + criticalExtensions.remove(INHIBIT_ANY_POLICY); + criticalExtensions.remove(ISSUING_DISTRIBUTION_POINT); + criticalExtensions.remove(DELTA_CRL_INDICATOR); + criticalExtensions.remove(POLICY_CONSTRAINTS); + criticalExtensions.remove(BASIC_CONSTRAINTS); + criticalExtensions.remove(SUBJECT_ALTERNATIVE_NAME); + criticalExtensions.remove(NAME_CONSTRAINTS); + + if (index == 0) // EE certificate + { + criticalExtensions.remove(Extension.extendedKeyUsage.getId()); + } + // process qcStatements extension + if (criticalExtensions.contains(QC_STATEMENT)) + { + if (processQcStatements(cert,index)) + { + criticalExtensions.remove(QC_STATEMENT); + } + } + + Iterator tmpIter = pathCheckers.iterator(); + while (tmpIter.hasNext()) + { + try + { + ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions); + } + catch (CertPathValidatorException e) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.criticalExtensionError", + new Object[] {e.getMessage(),e,e.getClass().getName()}); + throw new CertPathReviewerException(msg,e.getCause(),certPath,index); + } + } + if (!criticalExtensions.isEmpty()) + { + ErrorBundle msg; + Iterator it = criticalExtensions.iterator(); + while (it.hasNext()) + { + msg = createErrorBundle("CertPathReviewer.unknownCriticalExt", + new Object[] {new ASN1ObjectIdentifier((String) it.next())}); + addError(msg, index); + } + } + } + } + catch (CertPathReviewerException cpre) + { + addError(cpre.getErrorMessage(),cpre.getIndex()); + } + } + + private boolean processQcStatements( + X509Certificate cert, + int index) + { + try + { + boolean unknownStatement = false; + + ASN1Sequence qcSt = (ASN1Sequence) getExtensionValue(cert,QC_STATEMENT); + for (int j = 0; j < qcSt.size(); j++) + { + QCStatement stmt = QCStatement.getInstance(qcSt.getObjectAt(j)); + if (QCStatement.id_etsi_qcs_QcCompliance.equals(stmt.getStatementId())) + { + // process statement - just write a notification that the certificate contains this statement + ErrorBundle msg = createErrorBundle("CertPathReviewer.QcEuCompliance"); + addNotification(msg,index); + } + else if (QCStatement.id_qcs_pkixQCSyntax_v1.equals(stmt.getStatementId())) + { + // process statement - just recognize the statement + } + else if (QCStatement.id_etsi_qcs_QcSSCD.equals(stmt.getStatementId())) + { + // process statement - just write a notification that the certificate contains this statement + ErrorBundle msg = createErrorBundle("CertPathReviewer.QcSSCD"); + addNotification(msg,index); + } + else if (QCStatement.id_etsi_qcs_LimiteValue.equals(stmt.getStatementId())) + { + // process statement - write a notification containing the limit value + MonetaryValue limit = MonetaryValue.getInstance(stmt.getStatementInfo()); + Iso4217CurrencyCode currency = limit.getCurrency(); + double value = limit.getAmount().doubleValue() * Math.pow(10,limit.getExponent().doubleValue()); + ErrorBundle msg; + if (limit.getCurrency().isAlphabetic()) + { + msg = createErrorBundle("CertPathReviewer.QcLimitValueAlpha", + new Object[] {limit.getCurrency().getAlphabetic(), + new TrustedInput(new Double(value)), + limit}); + } + else + { + msg = createErrorBundle("CertPathReviewer.QcLimitValueNum", + new Object[]{Integers.valueOf(limit.getCurrency().getNumeric()), + new TrustedInput(new Double(value)), + limit}); + } + addNotification(msg,index); + } + else + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.QcUnknownStatement", + new Object[] {stmt.getStatementId(),new UntrustedInput(stmt)}); + addNotification(msg,index); + unknownStatement = true; + } + } + + return !unknownStatement; + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.QcStatementExtError"); + addError(msg,index); + } + + return false; + } + + private String IPtoString(byte[] ip) + { + String result; + try + { + result = InetAddress.getByAddress(ip).getHostAddress(); + } + catch (Exception e) + { + StringBuffer b = new StringBuffer(); + + for (int i = 0; i != ip.length; i++) + { + b.append(Integer.toHexString(ip[i] & 0xff)); + b.append(' '); + } + + result = b.toString(); + } + + return result; + } + + protected void checkRevocation(PKIXParameters paramsPKIX, + X509Certificate cert, + Date validDate, + X509Certificate sign, + PublicKey workingPublicKey, + Vector crlDistPointUrls, + Vector ocspUrls, + int index) + throws CertPathReviewerException + { + checkCRLs(paramsPKIX, cert, validDate, sign, workingPublicKey, crlDistPointUrls, index); + } + + protected void checkCRLs( + PKIXParameters paramsPKIX, + X509Certificate cert, + Date validDate, + X509Certificate sign, + PublicKey workingPublicKey, + Vector crlDistPointUrls, + int index) + throws CertPathReviewerException + { + X509CRLStoreSelector crlselect; + crlselect = new X509CRLStoreSelector(); + + try + { + crlselect.addIssuerName(getEncodedIssuerPrincipal(cert).getEncoded()); + } + catch (IOException e) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlIssuerException"); + throw new CertPathReviewerException(msg,e); + } + + crlselect.setCertificateChecking(cert); + + Iterator crl_iter; + try + { + Collection crl_coll = PKIXCRLUtil.findCRLs(crlselect, paramsPKIX); + crl_iter = crl_coll.iterator(); + + if (crl_coll.isEmpty()) + { + // notification - no local crls found + crl_coll = PKIXCRLUtil.findCRLs(new X509CRLStoreSelector(),paramsPKIX); + Iterator it = crl_coll.iterator(); + List nonMatchingCrlNames = new ArrayList(); + while (it.hasNext()) + { + nonMatchingCrlNames.add(((X509CRL) it.next()).getIssuerX500Principal()); + } + int numbOfCrls = nonMatchingCrlNames.size(); + ErrorBundle msg = createErrorBundle( + "CertPathReviewer.noCrlInCertstore", + new Object[]{new UntrustedInput(crlselect.getIssuerNames()), + new UntrustedInput(nonMatchingCrlNames), + Integers.valueOf(numbOfCrls)}); + addNotification(msg,index); + } + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlExtractionError", + new Object[] {ae.getCause().getMessage(),ae.getCause(),ae.getCause().getClass().getName()}); + addError(msg,index); + crl_iter = new ArrayList().iterator(); + } + + boolean validCrlFound = false; + X509CRL crl = null; + while (crl_iter.hasNext()) + { + crl = (X509CRL)crl_iter.next(); + + Date thisUpdate = crl.getThisUpdate(); + Date nextUpdate = crl.getNextUpdate(); + Object[] arguments = new Object[]{ new TrustedInput(thisUpdate), new TrustedInput(nextUpdate) }; + + if (nextUpdate == null || validDate.before(nextUpdate)) + { + validCrlFound = true; + ErrorBundle msg = createErrorBundle( "CertPathReviewer.localValidCRL", arguments); + addNotification(msg,index); + break; + } + + ErrorBundle msg = createErrorBundle( "CertPathReviewer.localInvalidCRL", arguments); + addNotification(msg,index); + } + + // if no valid crl was found in the CertStores try to get one from a + // crl distribution point + if (!validCrlFound) + { + X500Principal certIssuer = cert.getIssuerX500Principal(); + + X509CRL onlineCRL = null; + Iterator urlIt = crlDistPointUrls.iterator(); + while (urlIt.hasNext()) + { + try + { + String location = (String) urlIt.next(); + onlineCRL = getCRL(location); + if (onlineCRL != null) + { + X500Principal crlIssuer = onlineCRL.getIssuerX500Principal(); + + // check if crl issuer is correct + if (!certIssuer.equals(crlIssuer)) + { + ErrorBundle msg = createErrorBundle( "CertPathReviewer.onlineCRLWrongCA", + new Object[]{ new UntrustedInput(crlIssuer.getName()), new UntrustedInput(certIssuer.getName()), + new UntrustedUrlInput(location) }); + addNotification(msg,index); + continue; + } + + Date thisUpdate = onlineCRL.getThisUpdate(); + Date nextUpdate = onlineCRL.getNextUpdate(); + Object[] arguments = new Object[]{ new TrustedInput(thisUpdate), new TrustedInput(nextUpdate), + new UntrustedUrlInput(location) }; + + if (nextUpdate == null || validDate.before(nextUpdate)) + { + validCrlFound = true; + ErrorBundle msg = createErrorBundle( "CertPathReviewer.onlineValidCRL", + arguments); + addNotification(msg, index); + crl = onlineCRL; + break; + } + + ErrorBundle msg = createErrorBundle( "CertPathReviewer.onlineInvalidCRL", + arguments); + addNotification(msg, index); + } + } + catch (CertPathReviewerException cpre) + { + addNotification(cpre.getErrorMessage(),index); + } + } + } + + // check the crl + X509CRLEntry crl_entry; + if (crl != null) + { + if (sign != null) + { + boolean[] keyUsage = sign.getKeyUsage(); + + if (keyUsage != null && (keyUsage.length <= CRL_SIGN || !keyUsage[CRL_SIGN])) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.noCrlSigningPermited"); + throw new CertPathReviewerException(msg); + } + } + + if (workingPublicKey != null) + { + try + { + crl.verify(workingPublicKey, "BC"); + } + catch (Exception e) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlVerifyFailed"); + throw new CertPathReviewerException(msg,e); + } + } + else // issuer public key not known + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlNoIssuerPublicKey"); + throw new CertPathReviewerException(msg); + } + + crl_entry = crl.getRevokedCertificate(cert.getSerialNumber()); + if (crl_entry != null) + { + String reason = null; + + if (crl_entry.hasExtensions()) + { + ASN1Enumerated reasonCode; + try + { + reasonCode = ASN1Enumerated.getInstance(getExtensionValue(crl_entry, Extension.reasonCode.getId())); + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlReasonExtError"); + throw new CertPathReviewerException(msg,ae); + } + if (reasonCode != null) + { + reason = crlReasons[reasonCode.intValueExact()]; + } + } + + if (reason == null) + { + reason = crlReasons[7]; // unknown + } + + // i18n reason + LocaleString ls = new LocaleString(RESOURCE_NAME, reason); + + if (!validDate.before(crl_entry.getRevocationDate())) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.certRevoked", + new Object[] {new TrustedInput(crl_entry.getRevocationDate()),ls}); + throw new CertPathReviewerException(msg); + } + else // cert was revoked after validation date + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.revokedAfterValidation", + new Object[] {new TrustedInput(crl_entry.getRevocationDate()),ls}); + addNotification(msg,index); + } + } + else // cert is not revoked + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.notRevoked"); + addNotification(msg,index); + } + + // + // warn if a new crl is available + // + Date nextUpdate = crl.getNextUpdate(); + if (!(nextUpdate == null || validDate.before(nextUpdate))) + { + ErrorBundle msg = createErrorBundle( "CertPathReviewer.crlUpdateAvailable", + new Object[]{ new TrustedInput(nextUpdate) }); + addNotification(msg, index); + } + + // + // check the DeltaCRL indicator, base point and the issuing distribution point + // + ASN1Primitive idp; + try + { + idp = getExtensionValue(crl, ISSUING_DISTRIBUTION_POINT); + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.distrPtExtError"); + throw new CertPathReviewerException(msg); + } + ASN1Primitive dci; + try + { + dci = getExtensionValue(crl, DELTA_CRL_INDICATOR); + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.deltaCrlExtError"); + throw new CertPathReviewerException(msg); + } + + if (dci != null) + { + X509CRLStoreSelector baseSelect = new X509CRLStoreSelector(); + + try + { + baseSelect.addIssuerName(getIssuerPrincipal(crl).getEncoded()); + } + catch (IOException e) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlIssuerException"); + throw new CertPathReviewerException(msg,e); + } + + baseSelect.setMinCRLNumber(((ASN1Integer)dci).getPositiveValue()); + try + { + baseSelect.setMaxCRLNumber(((ASN1Integer)getExtensionValue(crl, CRL_NUMBER)).getPositiveValue().subtract(BigInteger.valueOf(1))); + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlNbrExtError"); + throw new CertPathReviewerException(msg,ae); + } + + boolean foundBase = false; + Iterator it; + try + { + it = PKIXCRLUtil.findCRLs(baseSelect, paramsPKIX).iterator(); + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlExtractionError"); + throw new CertPathReviewerException(msg,ae); + } + while (it.hasNext()) + { + X509CRL base = (X509CRL)it.next(); + + ASN1Primitive baseIdp; + try + { + baseIdp = getExtensionValue(base, ISSUING_DISTRIBUTION_POINT); + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.distrPtExtError"); + throw new CertPathReviewerException(msg,ae); + } + + if (Objects.areEqual(idp, baseIdp)) + { + foundBase = true; + break; + } + } + + if (!foundBase) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.noBaseCRL"); + throw new CertPathReviewerException(msg); + } + } + + if (idp != null) + { + IssuingDistributionPoint p = IssuingDistributionPoint.getInstance(idp); + BasicConstraints bc = null; + try + { + bc = BasicConstraints.getInstance(getExtensionValue(cert, BASIC_CONSTRAINTS)); + } + catch (AnnotatedException ae) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlBCExtError"); + throw new CertPathReviewerException(msg,ae); + } + + if (p.onlyContainsUserCerts() && (bc != null && bc.isCA())) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlOnlyUserCert"); + throw new CertPathReviewerException(msg); + } + + if (p.onlyContainsCACerts() && (bc == null || !bc.isCA())) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlOnlyCaCert"); + throw new CertPathReviewerException(msg); + } + + if (p.onlyContainsAttributeCerts()) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.crlOnlyAttrCert"); + throw new CertPathReviewerException(msg); + } + } + } + + if (!validCrlFound) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.noValidCrlFound"); + throw new CertPathReviewerException(msg); + } + } + + protected Vector getCRLDistUrls(CRLDistPoint crlDistPoints) + { + Vector urls = new Vector(); + + if (crlDistPoints != null) + { + DistributionPoint[] distPoints = crlDistPoints.getDistributionPoints(); + for (int i = 0; i < distPoints.length; i++) + { + DistributionPointName dp_name = distPoints[i].getDistributionPoint(); + if (dp_name.getType() == DistributionPointName.FULL_NAME) + { + GeneralName[] generalNames = GeneralNames.getInstance(dp_name.getName()).getNames(); + for (int j = 0; j < generalNames.length; j++) + { + if (generalNames[j].getTagNo() == GeneralName.uniformResourceIdentifier) + { + String url = ((ASN1IA5String)generalNames[j].getName()).getString(); + urls.add(url); + } + } + } + } + } + return urls; + } + + protected Vector getOCSPUrls(AuthorityInformationAccess authInfoAccess) + { + Vector urls = new Vector(); + + if (authInfoAccess != null) + { + AccessDescription[] ads = authInfoAccess.getAccessDescriptions(); + for (int i = 0; i < ads.length; i++) + { + if (ads[i].getAccessMethod().equals(AccessDescription.id_ad_ocsp)) + { + GeneralName name = ads[i].getAccessLocation(); + if (name.getTagNo() == GeneralName.uniformResourceIdentifier) + { + String url = ((ASN1IA5String)name.getName()).getString(); + urls.add(url); + } + } + } + } + + return urls; + } + + private X509CRL getCRL(String location) throws CertPathReviewerException + { + X509CRL result = null; + try + { + URL url = new URL(location); + + if (url.getProtocol().equals("http") || url.getProtocol().equals("https")) + { + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setUseCaches(false); + //conn.setConnectTimeout(2000); + conn.setDoInput(true); + conn.connect(); + if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) + { + CertificateFactory cf = CertificateFactory.getInstance("X.509","BC"); + result = (X509CRL) cf.generateCRL(conn.getInputStream()); + } + else + { + throw new Exception(conn.getResponseMessage()); + } + } + } + catch (Exception e) + { + ErrorBundle msg = createErrorBundle( + "CertPathReviewer.loadCrlDistPointError", + new Object[] {new UntrustedInput(location), + e.getMessage(),e,e.getClass().getName()}); + throw new CertPathReviewerException(msg); + } + return result; + } + + protected Collection getTrustAnchors(X509Certificate cert, Set trustanchors) throws CertPathReviewerException + { + Collection trustColl = new ArrayList(); + Iterator it = trustanchors.iterator(); + + X509CertSelector certSelectX509 = new X509CertSelector(); + + try + { + certSelectX509.setSubject(getEncodedIssuerPrincipal(cert).getEncoded()); + byte[] ext = cert.getExtensionValue(Extension.authorityKeyIdentifier.getId()); + + if (ext != null) + { + ASN1OctetString oct = (ASN1OctetString)ASN1Primitive.fromByteArray(ext); + AuthorityKeyIdentifier authID = AuthorityKeyIdentifier.getInstance(ASN1Primitive.fromByteArray(oct.getOctets())); + + // we ignore key identifier as if set, selector expects parent to have subjectKeyID + BigInteger serial = authID.getAuthorityCertSerialNumber(); + if (serial != null) + { + certSelectX509.setSerialNumber(authID.getAuthorityCertSerialNumber()); + } + else + { + byte[] keyID = authID.getKeyIdentifier(); + if (keyID != null) + { + certSelectX509.setSubjectKeyIdentifier(new DEROctetString(keyID).getEncoded()); + } + } + } + } + catch (IOException ex) + { + ErrorBundle msg = createErrorBundle("CertPathReviewer.trustAnchorIssuerError"); + throw new CertPathReviewerException(msg); + } + + while (it.hasNext()) + { + TrustAnchor trust = (TrustAnchor) it.next(); + if (trust.getTrustedCert() != null) + { + if (certSelectX509.match(trust.getTrustedCert())) + { + trustColl.add(trust); + } + } + else if (trust.getCAName() != null && trust.getCAPublicKey() != null) + { + X500Principal certIssuer = getEncodedIssuerPrincipal(cert); + X500Principal caName = new X500Principal(trust.getCAName()); + if (certIssuer.equals(caName)) + { + trustColl.add(trust); + } + } + } + return trustColl; + } + + private static ErrorBundle createErrorBundle(String id) + { + ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, id); + msg.setClassLoader(PKIXCertPathReviewer.class.getClassLoader()); + + return msg; + } + + private static ErrorBundle createErrorBundle(String id, Object[] arguments) + { + ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, id, arguments); + msg.setClassLoader(PKIXCertPathReviewer.class.getClassLoader()); + + return msg; + } +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXPolicyNode.java b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXPolicyNode.java new file mode 100644 index 0000000000..7baf5f764c --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXPolicyNode.java @@ -0,0 +1,173 @@ +package org.bouncycastle.pkix.jcajce; + +import java.security.cert.PolicyNode; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +public class PKIXPolicyNode + implements PolicyNode +{ + protected List children; + protected int depth; + protected Set expectedPolicies; + protected PolicyNode parent; + protected Set policyQualifiers; + protected String validPolicy; + protected boolean critical; + + /* + * + * CONSTRUCTORS + * + */ + + public PKIXPolicyNode( + List _children, + int _depth, + Set _expectedPolicies, + PolicyNode _parent, + Set _policyQualifiers, + String _validPolicy, + boolean _critical) + { + children = _children; + depth = _depth; + expectedPolicies = _expectedPolicies; + parent = _parent; + policyQualifiers = _policyQualifiers; + validPolicy = _validPolicy; + critical = _critical; + } + + public void addChild( + PKIXPolicyNode _child) + { + children.add(_child); + _child.setParent(this); + } + + public Iterator getChildren() + { + return children.iterator(); + } + + public int getDepth() + { + return depth; + } + + public Set getExpectedPolicies() + { + return expectedPolicies; + } + + public PolicyNode getParent() + { + return parent; + } + + public Set getPolicyQualifiers() + { + return policyQualifiers; + } + + public String getValidPolicy() + { + return validPolicy; + } + + public boolean hasChildren() + { + return !children.isEmpty(); + } + + public boolean isCritical() + { + return critical; + } + + public void removeChild(PKIXPolicyNode _child) + { + children.remove(_child); + } + + public void setCritical(boolean _critical) + { + critical = _critical; + } + + public void setParent(PKIXPolicyNode _parent) + { + parent = _parent; + } + + public String toString() + { + return toString(""); + } + + public String toString(String _indent) + { + StringBuffer _buf = new StringBuffer(); + _buf.append(_indent); + _buf.append(validPolicy); + _buf.append(" {\n"); + + for(int i = 0; i < children.size(); i++) + { + _buf.append(((PKIXPolicyNode)children.get(i)).toString(_indent + " ")); + } + + _buf.append(_indent); + _buf.append("}\n"); + return _buf.toString(); + } + + public Object clone() + { + return copy(); + } + + public PKIXPolicyNode copy() + { + Set _expectedPolicies = new HashSet(); + Iterator _iter = expectedPolicies.iterator(); + while (_iter.hasNext()) + { + _expectedPolicies.add(new String((String)_iter.next())); + } + + Set _policyQualifiers = new HashSet(); + _iter = policyQualifiers.iterator(); + while (_iter.hasNext()) + { + _policyQualifiers.add(new String((String)_iter.next())); + } + + PKIXPolicyNode _node = new PKIXPolicyNode(new ArrayList(), + depth, + _expectedPolicies, + null, + _policyQualifiers, + new String(validPolicy), + critical); + + _iter = children.iterator(); + while (_iter.hasNext()) + { + PKIXPolicyNode _child = ((PKIXPolicyNode)_iter.next()).copy(); + _child.setParent(_node); + _node.addChild(_child); + } + + return _node; + } + + public void setExpectedPolicies(Set expectedPolicies) + { + this.expectedPolicies = expectedPolicies; + } +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/jcajce/RFC3280CertPathUtilities.java b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/RFC3280CertPathUtilities.java index 83b8ddc4d7..7977ecad26 100644 --- a/pkix/src/main/java/org/bouncycastle/pkix/jcajce/RFC3280CertPathUtilities.java +++ b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/RFC3280CertPathUtilities.java @@ -40,6 +40,7 @@ import org.bouncycastle.jcajce.PKIXExtendedParameters; import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Properties; class RFC3280CertPathUtilities { @@ -506,14 +507,29 @@ protected static Set processCRLF( X509Certificate signCert = (X509Certificate)validCerts.get(i); boolean[] keyUsage = signCert.getKeyUsage(); - if (keyUsage != null && (keyUsage.length <= CRL_SIGN || !keyUsage[CRL_SIGN])) + if (keyUsage == null) { - lastException = new AnnotatedException( - "Issuer certificate key usage extension does not permit CRL signing."); + if (Properties.isOverrideSet("org.bouncycastle.x509.allow_ca_without_crl_sign", true)) + { + checkKeys.add(validKeys.get(i)); + } + else + { + lastException = new AnnotatedException( + "No key usage extension on issuer certificate."); + } } else { - checkKeys.add(validKeys.get(i)); + if (keyUsage.length <= CRL_SIGN || !keyUsage[CRL_SIGN]) + { + lastException = new AnnotatedException( + "Issuer certificate key usage extension does not permit CRL signing."); + } + else + { + checkKeys.add(validKeys.get(i)); + } } } diff --git a/pkix/src/main/java/org/bouncycastle/pkix/jcajce/X509CRLStoreSelector.java b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/X509CRLStoreSelector.java new file mode 100644 index 0000000000..70c8da2b89 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/X509CRLStoreSelector.java @@ -0,0 +1,327 @@ +package org.bouncycastle.pkix.jcajce; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.cert.CRL; +import java.security.cert.X509CRL; +import java.security.cert.X509CRLSelector; + +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Selector; + +/** + * This class is a Selector implementation for X.509 certificate revocation + * lists. + * + * @see org.bouncycastle.util.Selector + */ +class X509CRLStoreSelector + extends X509CRLSelector + implements Selector +{ + private boolean deltaCRLIndicator = false; + + private boolean completeCRLEnabled = false; + + private BigInteger maxBaseCRLNumber = null; + + private byte[] issuingDistributionPoint = null; + + private boolean issuingDistributionPointEnabled = false; + +// private X509AttributeCertificate attrCertChecking; + + /** + * Returns if the issuing distribution point criteria should be applied. + * Defaults to false. + *

      + * You may also set the issuing distribution point criteria if not a missing + * issuing distribution point should be assumed. + * + * @return Returns if the issuing distribution point check is enabled. + */ + public boolean isIssuingDistributionPointEnabled() + { + return issuingDistributionPointEnabled; + } + + /** + * Enables or disables the issuing distribution point check. + * + * @param issuingDistributionPointEnabled true to enable the + * issuing distribution point check. + */ + public void setIssuingDistributionPointEnabled( + boolean issuingDistributionPointEnabled) + { + this.issuingDistributionPointEnabled = issuingDistributionPointEnabled; + } + +// /** +// * Sets the attribute certificate being checked. This is not a criterion. +// * Rather, it is optional information that may help a {@link X509Store} find +// * CRLs that would be relevant when checking revocation for the specified +// * attribute certificate. If null is specified, then no such +// * optional information is provided. +// * +// * @param attrCert the X509AttributeCertificate being checked (or +// * null) +// * @see #getAttrCertificateChecking() +// */ +// public void setAttrCertificateChecking(X509AttributeCertificate attrCert) +// { +// attrCertChecking = attrCert; +// } +// +// /** +// * Returns the attribute certificate being checked. +// * +// * @return Returns the attribute certificate being checked. +// * @see #setAttrCertificateChecking(X509AttributeCertificate) +// */ +// public X509AttributeCertificate getAttrCertificateChecking() +// { +// return attrCertChecking; +// } + + public boolean match(Object obj) + { + if (!(obj instanceof X509CRL)) + { + return false; + } + X509CRL crl = (X509CRL)obj; + ASN1Integer dci = null; + try + { + byte[] bytes = crl + .getExtensionValue(Extension.deltaCRLIndicator.getId()); + if (bytes != null) + { + dci = ASN1Integer.getInstance(JcaX509ExtensionUtils.parseExtensionValue(bytes)); + } + } + catch (Exception e) + { + return false; + } + if (isDeltaCRLIndicatorEnabled()) + { + if (dci == null) + { + return false; + } + } + if (isCompleteCRLEnabled()) + { + if (dci != null) + { + return false; + } + } + if (dci != null) + { + + if (maxBaseCRLNumber != null) + { + if (dci.getPositiveValue().compareTo(maxBaseCRLNumber) == 1) + { + return false; + } + } + } + if (issuingDistributionPointEnabled) + { + byte[] idp = crl + .getExtensionValue(Extension.issuingDistributionPoint + .getId()); + if (issuingDistributionPoint == null) + { + if (idp != null) + { + return false; + } + } + else + { + if (!Arrays.areEqual(idp, issuingDistributionPoint)) + { + return false; + } + } + + } + return super.match((X509CRL)obj); + } + + public boolean match(CRL crl) + { + return match((Object)crl); + } + + /** + * Returns if this selector must match CRLs with the delta CRL indicator + * extension set. Defaults to false. + * + * @return Returns true if only CRLs with the delta CRL + * indicator extension are selected. + */ + public boolean isDeltaCRLIndicatorEnabled() + { + return deltaCRLIndicator; + } + + /** + * If this is set to true the CRL reported contains the delta + * CRL indicator CRL extension. + *

      + * {@link #setCompleteCRLEnabled(boolean)} and + * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other. + * + * @param deltaCRLIndicator true if the delta CRL indicator + * extension must be in the CRL. + */ + public void setDeltaCRLIndicatorEnabled(boolean deltaCRLIndicator) + { + this.deltaCRLIndicator = deltaCRLIndicator; + } + + /** + * Returns an instance of this from a X509CRLSelector. + * + * @param selector A X509CRLSelector instance. + * @return An instance of an X509CRLStoreSelector. + * @exception IllegalArgumentException if selector is null or creation + * fails. + */ + public static X509CRLStoreSelector getInstance(X509CRLSelector selector) + { + if (selector == null) + { + throw new IllegalArgumentException( + "cannot create from null selector"); + } + X509CRLStoreSelector cs = new X509CRLStoreSelector(); + cs.setCertificateChecking(selector.getCertificateChecking()); + cs.setDateAndTime(selector.getDateAndTime()); + try + { + cs.setIssuerNames(selector.getIssuerNames()); + } + catch (IOException e) + { + // cannot happen + throw new IllegalArgumentException(e.getMessage()); + } + cs.setIssuers(selector.getIssuers()); + cs.setMaxCRLNumber(selector.getMaxCRL()); + cs.setMinCRLNumber(selector.getMinCRL()); + return cs; + } + + public Object clone() + { + X509CRLStoreSelector sel = X509CRLStoreSelector.getInstance(this); + sel.deltaCRLIndicator = deltaCRLIndicator; + sel.completeCRLEnabled = completeCRLEnabled; + sel.maxBaseCRLNumber = maxBaseCRLNumber; +// sel.attrCertChecking = attrCertChecking; + sel.issuingDistributionPointEnabled = issuingDistributionPointEnabled; + sel.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint); + return sel; + } + + /** + * If true only complete CRLs are returned. Defaults to + * false. + * + * @return true if only complete CRLs are returned. + */ + public boolean isCompleteCRLEnabled() + { + return completeCRLEnabled; + } + + /** + * If set to true only complete CRLs are returned. + *

      + * {@link #setCompleteCRLEnabled(boolean)} and + * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other. + * + * @param completeCRLEnabled true if only complete CRLs + * should be returned. + */ + public void setCompleteCRLEnabled(boolean completeCRLEnabled) + { + this.completeCRLEnabled = completeCRLEnabled; + } + + /** + * Get the maximum base CRL number. Defaults to null. + * + * @return Returns the maximum base CRL number. + * @see #setMaxBaseCRLNumber(BigInteger) + */ + public BigInteger getMaxBaseCRLNumber() + { + return maxBaseCRLNumber; + } + + /** + * Sets the maximum base CRL number. Setting to null disables + * this cheack. + *

      + * This is only meaningful for delta CRLs. Complete CRLs must have a CRL + * number which is greater or equal than the base number of the + * corresponding CRL. + * + * @param maxBaseCRLNumber The maximum base CRL number to set. + */ + public void setMaxBaseCRLNumber(BigInteger maxBaseCRLNumber) + { + this.maxBaseCRLNumber = maxBaseCRLNumber; + } + + /** + * Returns the issuing distribution point. Defaults to null, + * which is a missing issuing distribution point extension. + *

      + * The internal byte array is cloned before it is returned. + *

      + * The criteria must be enable with + * {@link #setIssuingDistributionPointEnabled(boolean)}. + * + * @return Returns the issuing distribution point. + * @see #setIssuingDistributionPoint(byte[]) + */ + public byte[] getIssuingDistributionPoint() + { + return Arrays.clone(issuingDistributionPoint); + } + + /** + * Sets the issuing distribution point. + *

      + * The issuing distribution point extension is a CRL extension which + * identifies the scope and the distribution point of a CRL. The scope + * contains among others information about revocation reasons contained in + * the CRL. Delta CRLs and complete CRLs must have matching issuing + * distribution points. + *

      + * The byte array is cloned to protect against subsequent modifications. + *

      + * You must also enable or disable this criteria with + * {@link #setIssuingDistributionPointEnabled(boolean)}. + * + * @param issuingDistributionPoint The issuing distribution point to set. + * This is the DER encoded OCTET STRING extension value. + * @see #getIssuingDistributionPoint() + */ + public void setIssuingDistributionPoint(byte[] issuingDistributionPoint) + { + this.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint); + } +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/jcajce/X509CertStoreSelector.java b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/X509CertStoreSelector.java new file mode 100644 index 0000000000..159cd8cb72 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/jcajce/X509CertStoreSelector.java @@ -0,0 +1,85 @@ +package org.bouncycastle.pkix.jcajce; + +import java.io.IOException; +import java.security.cert.Certificate; +import java.security.cert.X509CertSelector; +import java.security.cert.X509Certificate; + +import org.bouncycastle.util.Selector; + +/** + * This class is a Selector implementation for X.509 certificates. + * + * @see org.bouncycastle.util.Selector + */ +class X509CertStoreSelector + extends X509CertSelector + implements Selector +{ + public boolean match(Object obj) + { + if (!(obj instanceof X509Certificate)) + { + return false; + } + + X509Certificate other = (X509Certificate)obj; + + return super.match(other); + } + + public boolean match(Certificate cert) + { + return match((Object)cert); + } + + public Object clone() + { + X509CertStoreSelector selector = (X509CertStoreSelector)super.clone(); + + return selector; + } + + /** + * Returns an instance of this from a X509CertSelector. + * + * @param selector A X509CertSelector instance. + * @return An instance of an X509CertStoreSelector. + * @exception IllegalArgumentException if selector is null or creation fails. + */ + public static X509CertStoreSelector getInstance(X509CertSelector selector) + { + if (selector == null) + { + throw new IllegalArgumentException("cannot create from null selector"); + } + X509CertStoreSelector cs = new X509CertStoreSelector(); + cs.setAuthorityKeyIdentifier(selector.getAuthorityKeyIdentifier()); + cs.setBasicConstraints(selector.getBasicConstraints()); + cs.setCertificate(selector.getCertificate()); + cs.setCertificateValid(selector.getCertificateValid()); + cs.setMatchAllSubjectAltNames(selector.getMatchAllSubjectAltNames()); + try + { + cs.setPathToNames(selector.getPathToNames()); + cs.setExtendedKeyUsage(selector.getExtendedKeyUsage()); + cs.setNameConstraints(selector.getNameConstraints()); + cs.setPolicy(selector.getPolicy()); + cs.setSubjectPublicKeyAlgID(selector.getSubjectPublicKeyAlgID()); + cs.setSubjectAlternativeNames(selector.getSubjectAlternativeNames()); + } + catch (IOException e) + { + throw new IllegalArgumentException("error in passed in selector: " + e); + } + cs.setIssuer(selector.getIssuer()); + cs.setKeyUsage(selector.getKeyUsage()); + cs.setPrivateKeyValid(selector.getPrivateKeyValid()); + cs.setSerialNumber(selector.getSerialNumber()); + cs.setSubject(selector.getSubject()); + cs.setSubjectKeyIdentifier(selector.getSubjectKeyIdentifier()); + cs.setSubjectPublicKey(selector.getSubjectPublicKey()); + return cs; + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/ErrorBundle.java b/pkix/src/main/java/org/bouncycastle/pkix/util/ErrorBundle.java new file mode 100644 index 0000000000..0e1b72054b --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/ErrorBundle.java @@ -0,0 +1,120 @@ +package org.bouncycastle.pkix.util; + +import java.io.UnsupportedEncodingException; +import java.util.Locale; +import java.util.TimeZone; + +public class ErrorBundle extends MessageBundle +{ + + /** + * summary entry key + */ + public static final String SUMMARY_ENTRY = "summary"; + + /** + * detail entry key + */ + public static final String DETAIL_ENTRY = "details"; + + /** + * Constructs a new ErrorBundle using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @throws NullPointerException if resource or id is null + */ + public ErrorBundle(String resource, String id) throws NullPointerException + { + super(resource, id); + } + + /** + * Constructs a new ErrorBundle using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @param encoding the encoding of the resource file + * @throws NullPointerException if resource or id is null + * @throws UnsupportedEncodingException if the encoding is not supported + */ + public ErrorBundle(String resource, String id, String encoding) throws NullPointerException, UnsupportedEncodingException + { + super(resource, id, encoding); + } + + /** + * Constructs a new ErrorBundle using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @param arguments an array containing the arguments for the message + * @throws NullPointerException if resource or id is null + */ + public ErrorBundle(String resource, String id, Object[] arguments) throws NullPointerException + { + super(resource, id, arguments); + } + + /** + * Constructs a new ErrorBundle using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @param encoding the encoding of the resource file + * @param arguments an array containing the arguments for the message + * @throws NullPointerException if resource or id is null + * @throws UnsupportedEncodingException if the encoding is not supported + */ + public ErrorBundle(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException + { + super(resource, id, encoding, arguments); + } + + /** + * Returns the summary message in the given locale and timezone. + * @param loc the {@link Locale} + * @param timezone the {@link TimeZone} + * @return the summary message. + * @throws MissingEntryException if the message is not available + */ + public String getSummary(Locale loc, TimeZone timezone) throws MissingEntryException + { + return getEntry(SUMMARY_ENTRY,loc,timezone); + } + + /** + * Returns the summary message in the given locale and the default timezone. + * @param loc the {@link Locale} + * @return the summary message. + * @throws MissingEntryException if the message is not available + */ + public String getSummary(Locale loc) throws MissingEntryException + { + return getEntry(SUMMARY_ENTRY,loc,TimeZone.getDefault()); + } + + /** + * Returns the detail message in the given locale and timezone. + * @param loc the {@link Locale} + * @param timezone the {@link TimeZone} + * @return the detail message. + * @throws MissingEntryException if the message is not available + */ + public String getDetail(Locale loc, TimeZone timezone) throws MissingEntryException + { + return getEntry(DETAIL_ENTRY,loc,timezone); + } + + /** + * Returns the detail message in the given locale and the default timezone. + * @param loc the {@link Locale} + * @return the detail message. + * @throws MissingEntryException if the message is not available + */ + public String getDetail(Locale loc) throws MissingEntryException + { + return getEntry(DETAIL_ENTRY,loc,TimeZone.getDefault()); + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/LocaleString.java b/pkix/src/main/java/org/bouncycastle/pkix/util/LocaleString.java new file mode 100644 index 0000000000..ecc289c5e0 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/LocaleString.java @@ -0,0 +1,31 @@ +package org.bouncycastle.pkix.util; + +import java.io.UnsupportedEncodingException; +import java.util.Locale; + +public class LocaleString + extends LocalizedMessage +{ + + public LocaleString(String resource, String id) + { + super(resource, id); + } + + public LocaleString(String resource, String id, String encoding) throws NullPointerException, UnsupportedEncodingException + { + super(resource, id, encoding); + } + + public LocaleString(String resource, String id, String encoding, Object[] arguments) + throws NullPointerException, UnsupportedEncodingException + { + super(resource, id, encoding, arguments); + } + + public String getLocaleString(Locale locale) + { + return this.getEntry(null, locale, null); + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/LocalizedException.java b/pkix/src/main/java/org/bouncycastle/pkix/util/LocalizedException.java new file mode 100644 index 0000000000..e7790e95e7 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/LocalizedException.java @@ -0,0 +1,50 @@ +package org.bouncycastle.pkix.util; + +import java.util.Locale; + +/** + * Base class for all Exceptions with localized messages. + */ +public class LocalizedException + extends Exception +{ + + protected ErrorBundle message; + private Throwable cause; + + /** + * Constructs a new LocalizedException with the specified localized message. + * @param message the {@link ErrorBundle} that contains the message for the exception + */ + public LocalizedException(ErrorBundle message) + { + super(message.getText(Locale.getDefault())); + this.message = message; + } + + /** + * Constructs a new LocalizedException with the specified localized message and cause. + * @param message the {@link ErrorBundle} that contains the message for the exception + * @param throwable the cause + */ + public LocalizedException(ErrorBundle message, Throwable throwable) + { + super(message.getText(Locale.getDefault())); + this.message = message; + this.cause = throwable; + } + + /** + * Returns the localized error message of the exception. + * @return the localized error message as {@link ErrorBundle} + */ + public ErrorBundle getErrorMessage() + { + return message; + } + + public Throwable getCause() + { + return cause; + } +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/LocalizedMessage.java b/pkix/src/main/java/org/bouncycastle/pkix/util/LocalizedMessage.java new file mode 100644 index 0000000000..9abedd151c --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/LocalizedMessage.java @@ -0,0 +1,476 @@ +package org.bouncycastle.pkix.util; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.text.DateFormat; +import java.text.Format; +import java.text.MessageFormat; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.TimeZone; + +import org.bouncycastle.pkix.util.filter.Filter; +import org.bouncycastle.pkix.util.filter.TrustedInput; +import org.bouncycastle.pkix.util.filter.UntrustedInput; +import org.bouncycastle.pkix.util.filter.UntrustedUrlInput; + +public class LocalizedMessage +{ + + protected final String id; + protected final String resource; + + // ISO-8859-1 is the default encoding + public static final String DEFAULT_ENCODING = "ISO-8859-1"; + protected String encoding = DEFAULT_ENCODING; + + protected FilteredArguments arguments; + protected FilteredArguments extraArgs = null; + + protected Filter filter = null; + + protected ClassLoader loader = null; + + /** + * Constructs a new LocalizedMessage using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @throws NullPointerException if resource or id is null + */ + public LocalizedMessage(String resource,String id) throws NullPointerException + { + if (resource == null || id == null) + { + throw new NullPointerException(); + } + this.id = id; + this.resource = resource; + arguments = new FilteredArguments(); + } + + /** + * Constructs a new LocalizedMessage using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @param encoding the encoding of the resource file + * @throws NullPointerException if resource or id is null + * @throws UnsupportedEncodingException if the encoding is not supported + */ + public LocalizedMessage(String resource,String id, String encoding) throws NullPointerException, UnsupportedEncodingException + { + if (resource == null || id == null) + { + throw new NullPointerException(); + } + this.id = id; + this.resource = resource; + arguments = new FilteredArguments(); + if (!Charset.isSupported(encoding)) + { + throw new UnsupportedEncodingException("The encoding \"" + encoding + "\" is not supported."); + } + this.encoding = encoding; + } + + /** + * Constructs a new LocalizedMessage using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @param arguments an array containing the arguments for the message + * @throws NullPointerException if resource or id is null + */ + public LocalizedMessage(String resource, String id, Object[] arguments) throws NullPointerException + { + if (resource == null || id == null || arguments == null) + { + throw new NullPointerException(); + } + this.id = id; + this.resource = resource; + this.arguments = new FilteredArguments(arguments); + } + + /** + * Constructs a new LocalizedMessage using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @param encoding the encoding of the resource file + * @param arguments an array containing the arguments for the message + * @throws NullPointerException if resource or id is null + * @throws UnsupportedEncodingException if the encoding is not supported + */ + public LocalizedMessage(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException + { + if (resource == null || id == null || arguments == null) + { + throw new NullPointerException(); + } + this.id = id; + this.resource = resource; + this.arguments = new FilteredArguments(arguments); + if (!Charset.isSupported(encoding)) + { + throw new UnsupportedEncodingException("The encoding \"" + encoding + "\" is not supported."); + } + this.encoding = encoding; + } + + /** + * Reads the entry id + "." + key from the resource file and returns a + * formated message for the given Locale and TimeZone. + * @param key second part of the entry id + * @param loc the used {@link Locale} + * @param timezone the used {@link TimeZone} + * @return a Strng containing the localized message + * @throws MissingEntryException if the resource file is not available or the entry does not exist. + */ + public String getEntry(String key,Locale loc, TimeZone timezone) throws MissingEntryException + { + String entry = id; + if (key != null) + { + entry += "." + key; + } + + try + { + ResourceBundle bundle; + if (loader == null) + { + bundle = ResourceBundle.getBundle(resource,loc); + } + else + { + bundle = ResourceBundle.getBundle(resource, loc, loader); + } + String result = bundle.getString(entry); + if (!encoding.equals(DEFAULT_ENCODING)) + { + result = new String(result.getBytes(DEFAULT_ENCODING), encoding); + } + if (!arguments.isEmpty()) + { + result = formatWithTimeZone(result,arguments.getFilteredArgs(loc),loc,timezone); + } + result = addExtraArgs(result, loc); + return result; + } + catch (MissingResourceException mre) + { + throw new MissingEntryException("Can't find entry " + entry + " in resource file " + resource + ".", + resource, + entry, + loc, + loader != null ? loader : this.getClassLoader()); + } + catch (UnsupportedEncodingException use) + { + // should never occur - cause we already test this in the constructor + throw new RuntimeException(use); + } + } + + protected String formatWithTimeZone( + String template, + Object[] arguments, + Locale locale, + TimeZone timezone) + { + MessageFormat mf = new MessageFormat(" "); + mf.setLocale(locale); + mf.applyPattern(template); + if (!timezone.equals(TimeZone.getDefault())) + { + Format[] formats = mf.getFormats(); + for (int i = 0; i < formats.length; i++) + { + if (formats[i] instanceof DateFormat) + { + DateFormat temp = (DateFormat) formats[i]; + temp.setTimeZone(timezone); + mf.setFormat(i,temp); + } + } + } + return mf.format(arguments); + } + + protected String addExtraArgs(String msg, Locale locale) + { + if (extraArgs != null) + { + StringBuffer sb = new StringBuffer(msg); + Object[] filteredArgs = extraArgs.getFilteredArgs(locale); + for (int i = 0; i < filteredArgs.length; i++) + { + sb.append(filteredArgs[i]); + } + msg = sb.toString(); + } + return msg; + } + + /** + * Sets the {@link Filter} that is used to filter the arguments of this message + * @param filter the {@link Filter} to use. null to disable filtering. + */ + public void setFilter(Filter filter) + { + arguments.setFilter(filter); + if (extraArgs != null) + { + extraArgs.setFilter(filter); + } + this.filter = filter; + } + + /** + * Returns the current filter. + * @return the current filter + */ + public Filter getFilter() + { + return filter; + } + + /** + * Set the {@link ClassLoader} which loads the resource files. If it is set to null + * then the default {@link ClassLoader} is used. + * @param loader the {@link ClassLoader} which loads the resource files + */ + public void setClassLoader(ClassLoader loader) + { + this.loader = loader; + } + + /** + * Returns the {@link ClassLoader} which loads the resource files or null + * if the default ClassLoader is used. + * @return the {@link ClassLoader} which loads the resource files + */ + public ClassLoader getClassLoader() + { + return loader; + } + + /** + * Returns the id of the message in the resource bundle. + * @return the id of the message + */ + public String getId() + { + return id; + } + + /** + * Returns the name of the resource bundle for this message + * @return name of the resource file + */ + public String getResource() + { + return resource; + } + + /** + * Returns an Object[] containing the message arguments. + * @return the message arguments + */ + public Object[] getArguments() + { + return arguments.getArguments(); + } + + /** + * + * @param extraArg + */ + public void setExtraArgument(Object extraArg) + { + setExtraArguments(new Object[] {extraArg}); + } + + /** + * + * @param extraArgs + */ + public void setExtraArguments(Object[] extraArgs) + { + if (extraArgs != null) + { + this.extraArgs = new FilteredArguments(extraArgs); + this.extraArgs.setFilter(filter); + } + else + { + this.extraArgs = null; + } + } + + /** + * + * @return + */ + public Object[] getExtraArgs() + { + return (extraArgs == null) ? null : extraArgs.getArguments(); + } + + protected static class FilteredArguments + { + protected static final int NO_FILTER = 0; + protected static final int FILTER = 1; + protected static final int FILTER_URL = 2; + + protected Filter filter = null; + + protected boolean[] isLocaleSpecific; + protected int[] argFilterType; + protected Object[] arguments; + protected Object[] unpackedArgs; + protected Object[] filteredArgs; + + FilteredArguments() + { + this(new Object[0]); + } + + FilteredArguments(Object[] args) + { + this.arguments = args; + this.unpackedArgs = new Object[args.length]; + this.filteredArgs = new Object[args.length]; + this.isLocaleSpecific = new boolean[args.length]; + this.argFilterType = new int[args.length]; + for (int i = 0; i < args.length; i++) + { + if (args[i] instanceof TrustedInput) + { + this.unpackedArgs[i] = ((TrustedInput) args[i]).getInput(); + argFilterType[i] = NO_FILTER; + } + else if (args[i] instanceof UntrustedInput) + { + this.unpackedArgs[i] = ((UntrustedInput) args[i]).getInput(); + if (args[i] instanceof UntrustedUrlInput) + { + argFilterType[i] = FILTER_URL; + } + else + { + argFilterType[i] = FILTER; + } + } + else + { + this.unpackedArgs[i] = args[i]; + argFilterType[i] = FILTER; + } + + // locale specific + this.isLocaleSpecific[i] = (this.unpackedArgs[i] instanceof LocaleString); + } + } + + public boolean isEmpty() + { + return unpackedArgs.length == 0; + } + + public Object[] getArguments() + { + return arguments; + } + + public Object[] getFilteredArgs(Locale locale) + { + Object[] result = new Object[unpackedArgs.length]; + for (int i = 0; i < unpackedArgs.length; i++) + { + Object arg; + if (filteredArgs[i] != null) + { + arg = filteredArgs[i]; + } + else + { + arg = unpackedArgs[i]; + if (isLocaleSpecific[i]) + { + // get locale + arg = ((LocaleString) arg).getLocaleString(locale); + arg = filter(argFilterType[i], arg); + } + else + { + arg = filter(argFilterType[i], arg); + filteredArgs[i] = arg; + } + } + result[i] = arg; + } + return result; + } + + private Object filter(int type, Object obj) + { + if (filter != null) + { + Object o = (null == obj) ? "null" : obj; + switch (type) + { + case NO_FILTER: + return o; + case FILTER: + return filter.doFilter(o.toString()); + case FILTER_URL: + return filter.doFilterUrl(o.toString()); + default: + return null; + } + } + else + { + return obj; + } + } + + public Filter getFilter() + { + return filter; + } + + public void setFilter(Filter filter) + { + if (filter != this.filter) + { + for (int i = 0; i < unpackedArgs.length; i++) + { + filteredArgs[i] = null; + } + } + this.filter = filter; + } + + } + + public String toString() + { + StringBuffer sb = new StringBuffer(); + sb.append("Resource: \"").append(resource); + sb.append("\" Id: \"").append(id).append("\""); + sb.append(" Arguments: ").append(arguments.getArguments().length).append(" normal"); + if (extraArgs != null && extraArgs.getArguments().length > 0) + { + sb.append(", ").append(extraArgs.getArguments().length).append(" extra"); + } + sb.append(" Encoding: ").append(encoding); + sb.append(" ClassLoader: ").append(loader); + return sb.toString(); + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/MessageBundle.java b/pkix/src/main/java/org/bouncycastle/pkix/util/MessageBundle.java new file mode 100644 index 0000000000..9fb4164d4d --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/MessageBundle.java @@ -0,0 +1,93 @@ +package org.bouncycastle.pkix.util; + +import java.io.UnsupportedEncodingException; +import java.util.Locale; +import java.util.TimeZone; + +public class MessageBundle + extends TextBundle +{ + + /** + * title entry key + */ + public static final String TITLE_ENTRY = "title"; + + /** + * Constructs a new MessageBundle using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @throws NullPointerException if resource or id is null + */ + public MessageBundle(String resource, String id) throws NullPointerException + { + super(resource, id); + } + + /** + * Constructs a new MessageBundle using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @param encoding the encoding of the resource file + * @throws NullPointerException if resource or id is null + * @throws UnsupportedEncodingException if the encoding is not supported + */ + public MessageBundle(String resource, String id, String encoding) throws NullPointerException, UnsupportedEncodingException + { + super(resource, id, encoding); + } + + /** + * Constructs a new MessageBundle using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @param arguments an array containing the arguments for the message + * @throws NullPointerException if resource or id is null + */ + public MessageBundle(String resource, String id, Object[] arguments) throws NullPointerException + { + super(resource, id, arguments); + } + + /** + * Constructs a new MessageBundle using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @param encoding the encoding of the resource file + * @param arguments an array containing the arguments for the message + * @throws NullPointerException if resource or id is null + * @throws UnsupportedEncodingException if the encoding is not supported + */ + public MessageBundle(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException + { + super(resource, id, encoding, arguments); + } + + /** + * Returns the title message in the given locale and timezone. + * @param loc the {@link Locale} + * @param timezone the {@link TimeZone} + * @return the title message. + * @throws MissingEntryException if the message is not available + */ + public String getTitle(Locale loc,TimeZone timezone) throws MissingEntryException + { + return getEntry(TITLE_ENTRY,loc,timezone); + } + + /** + * Returns the title message in the given locale and the default timezone. + * @param loc the {@link Locale} + * @return the title message. + * @throws MissingEntryException if the message is not available + */ + public String getTitle(Locale loc) throws MissingEntryException + { + return getEntry(TITLE_ENTRY,loc,TimeZone.getDefault()); + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/MissingEntryException.java b/pkix/src/main/java/org/bouncycastle/pkix/util/MissingEntryException.java new file mode 100644 index 0000000000..8d7aae6e07 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/MissingEntryException.java @@ -0,0 +1,74 @@ +package org.bouncycastle.pkix.util; + +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Locale; + +public class MissingEntryException + extends RuntimeException +{ + + protected final String resource; + protected final String key; + protected final ClassLoader loader; + protected final Locale locale; + + private String debugMsg; + + public MissingEntryException(String message, String resource, String key, Locale locale, ClassLoader loader) + { + super(message); + this.resource = resource; + this.key = key; + this.locale = locale; + this.loader = loader; + } + + public MissingEntryException(String message, Throwable cause, String resource, String key, Locale locale, ClassLoader loader) + { + super(message, cause); + this.resource = resource; + this.key = key; + this.locale = locale; + this.loader = loader; + } + + public String getKey() + { + return key; + } + + public String getResource() + { + return resource; + } + + public ClassLoader getClassLoader() + { + return loader; + } + + public Locale getLocale() + { + return locale; + } + + public String getDebugMsg() + { + if (debugMsg == null) + { + debugMsg = "Can not find entry " + key + " in resource file " + resource + " for the locale " + locale + "."; + if (loader instanceof URLClassLoader) + { + URL[] urls = ((URLClassLoader) loader).getURLs(); + debugMsg += " The following entries in the classpath were searched: "; + for (int i = 0; i != urls.length; i++) + { + debugMsg += urls[i] + " "; + } + } + } + return debugMsg; + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/TextBundle.java b/pkix/src/main/java/org/bouncycastle/pkix/util/TextBundle.java new file mode 100644 index 0000000000..b5d88f66e2 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/TextBundle.java @@ -0,0 +1,92 @@ +package org.bouncycastle.pkix.util; + +import java.io.UnsupportedEncodingException; +import java.util.Locale; +import java.util.TimeZone; + +public class TextBundle extends LocalizedMessage +{ + + /** + * text entry key + */ + public static final String TEXT_ENTRY = "text"; + + /** + * Constructs a new TextBundle using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @throws NullPointerException if resource or id is null + */ + public TextBundle(String resource, String id) throws NullPointerException + { + super(resource, id); + } + + /** + * Constructs a new TextBundle using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @param encoding the encoding of the resource file + * @throws NullPointerException if resource or id is null + * @throws UnsupportedEncodingException if the encoding is not supported + */ + public TextBundle(String resource, String id, String encoding) throws NullPointerException, UnsupportedEncodingException + { + super(resource, id, encoding); + } + + /** + * Constructs a new TextBundle using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @param arguments an array containing the arguments for the message + * @throws NullPointerException if resource or id is null + */ + public TextBundle(String resource, String id, Object[] arguments) throws NullPointerException + { + super(resource, id, arguments); + } + + /** + * Constructs a new TextBundle using resource as the base name for the + * RessourceBundle and id as the message bundle id the resource file. + * @param resource base name of the resource file + * @param id the id of the corresponding bundle in the resource file + * @param encoding the encoding of the resource file + * @param arguments an array containing the arguments for the message + * @throws NullPointerException if resource or id is null + * @throws UnsupportedEncodingException if the encoding is not supported + */ + public TextBundle(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException + { + super(resource, id, encoding, arguments); + } + + /** + * Returns the text message in the given locale and timezone. + * @param loc the {@link Locale} + * @param timezone the {@link TimeZone} + * @return the text message. + * @throws MissingEntryException if the message is not available + */ + public String getText(Locale loc, TimeZone timezone) throws MissingEntryException + { + return getEntry(TEXT_ENTRY,loc,timezone); + } + + /** + * Returns the text message in the given locale and the defaut timezone. + * @param loc the {@link Locale} + * @return the text message. + * @throws MissingEntryException if the message is not available + */ + public String getText(Locale loc) throws MissingEntryException + { + return getEntry(TEXT_ENTRY,loc,TimeZone.getDefault()); + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/X509CertificateFormatter.java b/pkix/src/main/java/org/bouncycastle/pkix/util/X509CertificateFormatter.java index 0396ed7b7c..b6317cb9dd 100644 --- a/pkix/src/main/java/org/bouncycastle/pkix/util/X509CertificateFormatter.java +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/X509CertificateFormatter.java @@ -318,7 +318,6 @@ else if (oid.equals(Extension.extendedKeyUsage)) } catch (Exception ex) { - ex.printStackTrace(); buf.append(oid.getId()); // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl); buf.append(" value = ").append("*****").append(nl); diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/filter/Filter.java b/pkix/src/main/java/org/bouncycastle/pkix/util/filter/Filter.java new file mode 100644 index 0000000000..ac947a76fe --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/filter/Filter.java @@ -0,0 +1,21 @@ + +package org.bouncycastle.pkix.util.filter; + +public interface Filter +{ + + /** + * Runs the filter on the input String and returns the filtered String + * @param input input String + * @return filtered String + */ + public String doFilter(String input); + + /** + * Runs the filter on the input url and returns the filtered String + * @param input input url String + * @return filtered String + */ + public String doFilterUrl(String input); + +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/filter/HTMLFilter.java b/pkix/src/main/java/org/bouncycastle/pkix/util/filter/HTMLFilter.java new file mode 100644 index 0000000000..dd7bc962da --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/filter/HTMLFilter.java @@ -0,0 +1,68 @@ + +package org.bouncycastle.pkix.util.filter; + +/** + * HTML Filter + */ +public class HTMLFilter implements Filter +{ + + public String doFilter(String input) + { + StringBuffer buf = new StringBuffer(input); + int i = 0; + while (i < buf.length()) + { + char ch = buf.charAt(i); + switch (ch) + { + case '<': + buf.replace(i,i+1,"<"); + break; + case '>': + buf.replace(i,i+1,">"); + break; + case '(': + buf.replace(i,i+1,"("); + break; + case ')': + buf.replace(i,i+1,")"); + break; + case '#': + buf.replace(i,i+1,"#"); + break; + case '&': + buf.replace(i,i+1,"&"); + break; + case '\"': + buf.replace(i,i+1,"""); + break; + case '\'': + buf.replace(i,i+1,"'"); + break; + case '%': + buf.replace(i,i+1,"%"); + break; + case ';': + buf.replace(i,i+1,";"); + break; + case '+': + buf.replace(i,i+1,"+"); + break; + case '-': + buf.replace(i,i+1,"-"); + break; + default: + i -= 3; + } + i += 4; + } + return buf.toString(); + } + + public String doFilterUrl(String input) + { + return doFilter(input); + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/filter/SQLFilter.java b/pkix/src/main/java/org/bouncycastle/pkix/util/filter/SQLFilter.java new file mode 100644 index 0000000000..5161fe7fe7 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/filter/SQLFilter.java @@ -0,0 +1,69 @@ + +package org.bouncycastle.pkix.util.filter; + +/** + * Filter for strings to store in a SQL table. + * + * escapes ' " = - / \ ; \r \n + */ +public class SQLFilter implements Filter +{ + + public String doFilter(String input) + { + StringBuffer buf = new StringBuffer(input); + int i = 0; + while (i < buf.length()) + { + char ch = buf.charAt(i); + switch (ch) + { + case '\'': + buf.replace(i,i+1,"\\\'"); + i += 1; + break; + case '\"': + buf.replace(i,i+1,"\\\""); + i += 1; + break; + case '=': + buf.replace(i,i+1,"\\="); + i += 1; + break; + case '-': + buf.replace(i,i+1,"\\-"); + i += 1; + break; + case '/': + buf.replace(i,i+1,"\\/"); + i += 1; + break; + case '\\': + buf.replace(i,i+1,"\\\\"); + i += 1; + break; + case ';': + buf.replace(i,i+1,"\\;"); + i += 1; + break; + case '\r': + buf.replace(i,i+1,"\\r"); + i += 1; + break; + case '\n': + buf.replace(i,i+1,"\\n"); + i += 1; + break; + default: + } + i++; + } + return buf.toString(); + } + + public String doFilterUrl(String input) + { + return doFilter(input); + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/filter/TrustedInput.java b/pkix/src/main/java/org/bouncycastle/pkix/util/filter/TrustedInput.java new file mode 100644 index 0000000000..ee90830aaa --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/filter/TrustedInput.java @@ -0,0 +1,23 @@ +package org.bouncycastle.pkix.util.filter; + +public class TrustedInput +{ + + protected Object input; + + public TrustedInput(Object input) + { + this.input = input; + } + + public Object getInput() + { + return input; + } + + public String toString() + { + return input.toString(); + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/filter/UntrustedInput.java b/pkix/src/main/java/org/bouncycastle/pkix/util/filter/UntrustedInput.java new file mode 100644 index 0000000000..6cee0874d2 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/filter/UntrustedInput.java @@ -0,0 +1,44 @@ + +package org.bouncycastle.pkix.util.filter; + +/** + * Wrapper class to mark untrusted input. + */ +public class UntrustedInput +{ + + protected Object input; + + /** + * Construct a new UntrustedInput instance. + * @param input the untrusted input Object + */ + public UntrustedInput(Object input) + { + this.input = input; + } + + /** + * Returns the untrusted input as Object. + * @return the input as Object + */ + public Object getInput() + { + return input; + } + + /** + * Returns the untrusted input convertet to a String. + * @return the input as String + */ + public String getString() + { + return input.toString(); + } + + public String toString() + { + return input.toString(); + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/pkix/util/filter/UntrustedUrlInput.java b/pkix/src/main/java/org/bouncycastle/pkix/util/filter/UntrustedUrlInput.java new file mode 100644 index 0000000000..57d6a489e5 --- /dev/null +++ b/pkix/src/main/java/org/bouncycastle/pkix/util/filter/UntrustedUrlInput.java @@ -0,0 +1,14 @@ +package org.bouncycastle.pkix.util.filter; + +/** + * + * Wrapper class to mark an untrusted Url + */ +public class UntrustedUrlInput extends UntrustedInput +{ + public UntrustedUrlInput(Object url) + { + super(url); + } + +} diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TSPAlgorithms.java b/pkix/src/main/java/org/bouncycastle/tsp/TSPAlgorithms.java index 780b79d659..d909a4bd63 100644 --- a/pkix/src/main/java/org/bouncycastle/tsp/TSPAlgorithms.java +++ b/pkix/src/main/java/org/bouncycastle/tsp/TSPAlgorithms.java @@ -27,6 +27,11 @@ public interface TSPAlgorithms public static final ASN1ObjectIdentifier SHA384 = NISTObjectIdentifiers.id_sha384; public static final ASN1ObjectIdentifier SHA512 = NISTObjectIdentifiers.id_sha512; + public static final ASN1ObjectIdentifier SHA3_224 = NISTObjectIdentifiers.id_sha3_224; + public static final ASN1ObjectIdentifier SHA3_256 = NISTObjectIdentifiers.id_sha3_256; + public static final ASN1ObjectIdentifier SHA3_384 = NISTObjectIdentifiers.id_sha3_384; + public static final ASN1ObjectIdentifier SHA3_512 = NISTObjectIdentifiers.id_sha3_512; + public static final ASN1ObjectIdentifier RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128; public static final ASN1ObjectIdentifier RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160; public static final ASN1ObjectIdentifier RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256; @@ -39,5 +44,5 @@ public interface TSPAlgorithms public static final ASN1ObjectIdentifier SM3 = GMObjectIdentifiers.sm3; - public static final Set ALLOWED = new HashSet(Arrays.asList(new ASN1ObjectIdentifier[] { SM3, GOST3411, GOST3411_2012_256, GOST3411_2012_512, MD5, SHA1, SHA224, SHA256, SHA384, SHA512, RIPEMD128, RIPEMD160, RIPEMD256 })); + public static final Set ALLOWED = new HashSet(Arrays.asList(new ASN1ObjectIdentifier[] { SM3, GOST3411, GOST3411_2012_256, GOST3411_2012_512, MD5, SHA1, SHA224, SHA256, SHA384, SHA512, SHA3_224, SHA3_256, SHA3_384, SHA3_512, RIPEMD128, RIPEMD160, RIPEMD256 })); } diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TSPUtil.java b/pkix/src/main/java/org/bouncycastle/tsp/TSPUtil.java index 3e179aea1e..8ef9a802bf 100644 --- a/pkix/src/main/java/org/bouncycastle/tsp/TSPUtil.java +++ b/pkix/src/main/java/org/bouncycastle/tsp/TSPUtil.java @@ -51,6 +51,10 @@ public class TSPUtil digestLengths.put(NISTObjectIdentifiers.id_sha256.getId(), Integers.valueOf(32)); digestLengths.put(NISTObjectIdentifiers.id_sha384.getId(), Integers.valueOf(48)); digestLengths.put(NISTObjectIdentifiers.id_sha512.getId(), Integers.valueOf(64)); + digestLengths.put(NISTObjectIdentifiers.id_sha3_224.getId(), Integers.valueOf(28)); + digestLengths.put(NISTObjectIdentifiers.id_sha3_256.getId(), Integers.valueOf(32)); + digestLengths.put(NISTObjectIdentifiers.id_sha3_384.getId(), Integers.valueOf(48)); + digestLengths.put(NISTObjectIdentifiers.id_sha3_512.getId(), Integers.valueOf(64)); digestLengths.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), Integers.valueOf(16)); digestLengths.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), Integers.valueOf(20)); digestLengths.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), Integers.valueOf(32)); @@ -65,6 +69,10 @@ public class TSPUtil digestNames.put(NISTObjectIdentifiers.id_sha256.getId(), "SHA256"); digestNames.put(NISTObjectIdentifiers.id_sha384.getId(), "SHA384"); digestNames.put(NISTObjectIdentifiers.id_sha512.getId(), "SHA512"); + digestNames.put(NISTObjectIdentifiers.id_sha3_224.getId(), "SHA3-224"); + digestNames.put(NISTObjectIdentifiers.id_sha3_256.getId(), "SHA3-256"); + digestNames.put(NISTObjectIdentifiers.id_sha3_384.getId(), "SHA3-384"); + digestNames.put(NISTObjectIdentifiers.id_sha3_512.getId(), "SHA3-512"); digestNames.put(PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(), "SHA1"); digestNames.put(PKCSObjectIdentifiers.sha224WithRSAEncryption.getId(), "SHA224"); digestNames.put(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), "SHA256"); diff --git a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedData.java b/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedData.java index e91eeb4091..82ebffa170 100644 --- a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedData.java +++ b/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedData.java @@ -92,7 +92,7 @@ public CMSTimeStampedData addTimeStamp(TimeStampToken token) newTimeStamps[timeStamps.length] = new TimeStampAndCRL(token.toCMSSignedData().toASN1Structure()); - return new CMSTimeStampedData(new ContentInfo(CMSObjectIdentifiers.timestampedData, new TimeStampedData(timeStampedData.getDataUri(), timeStampedData.getMetaData(), timeStampedData.getContent(), new Evidence(new TimeStampTokenEvidence(newTimeStamps))))); + return new CMSTimeStampedData(new ContentInfo(CMSObjectIdentifiers.timestampedData, new TimeStampedData(timeStampedData.getDataUriIA5(), timeStampedData.getMetaData(), timeStampedData.getContent(), new Evidence(new TimeStampTokenEvidence(newTimeStamps))))); } public byte[] getContent() @@ -108,7 +108,7 @@ public byte[] getContent() public URI getDataUri() throws URISyntaxException { - ASN1IA5String dataURI = this.timeStampedData.getDataUri(); + ASN1IA5String dataURI = this.timeStampedData.getDataUriIA5(); if (dataURI != null) { diff --git a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataGenerator.java index fd1e6030c9..6484a10677 100644 --- a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataGenerator.java @@ -35,10 +35,10 @@ public CMSTimeStampedData generate(TimeStampToken timeStamp, byte[] content) thr public CMSTimeStampedData generate(TimeStampToken timeStamp, InputStream content) throws CMSException { - ByteArrayOutputStream contentOut = new ByteArrayOutputStream(); - + ASN1OctetString encContent = null; if (content != null) { + ByteArrayOutputStream contentOut = new ByteArrayOutputStream(); try { Streams.pipeAll(content, contentOut); @@ -47,13 +47,11 @@ public CMSTimeStampedData generate(TimeStampToken timeStamp, InputStream content { throw new CMSException("exception encapsulating content: " + e.getMessage(), e); } - } - - ASN1OctetString encContent = null; - if (contentOut.size() != 0) - { - encContent = new BEROctetString(contentOut.toByteArray()); + if (contentOut.size() != 0) + { + encContent = new BEROctetString(contentOut.toByteArray()); + } } TimeStampAndCRL stamp = new TimeStampAndCRL(timeStamp.toCMSSignedData().toASN1Structure()); @@ -64,8 +62,11 @@ public CMSTimeStampedData generate(TimeStampToken timeStamp, InputStream content { asn1DataUri = new DERIA5String(dataUri.toString()); } - - return new CMSTimeStampedData(new ContentInfo(CMSObjectIdentifiers.timestampedData, new TimeStampedData(asn1DataUri, metaData, encContent, new Evidence(new TimeStampTokenEvidence(stamp))))); + + TimeStampedData timeStampedData = new TimeStampedData(asn1DataUri, metaData, encContent, + new Evidence(new TimeStampTokenEvidence(stamp))); + + return new CMSTimeStampedData(new ContentInfo(CMSObjectIdentifiers.timestampedData, timeStampedData)); } } diff --git a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java b/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java index c700486a9a..751ebaf503 100644 --- a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java +++ b/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java @@ -79,7 +79,7 @@ public InputStream getContent() public URI getDataUri() throws URISyntaxException { - ASN1IA5String dataURI = this.timeStampedData.getDataUri(); + ASN1IA5String dataURI = this.timeStampedData.getDataUriIA5(); if (dataURI != null) { diff --git a/pkix/src/main/java/org/bouncycastle/tsp/cms/MetaDataUtil.java b/pkix/src/main/java/org/bouncycastle/tsp/cms/MetaDataUtil.java index 330eea6963..365e9dc0a3 100644 --- a/pkix/src/main/java/org/bouncycastle/tsp/cms/MetaDataUtil.java +++ b/pkix/src/main/java/org/bouncycastle/tsp/cms/MetaDataUtil.java @@ -48,7 +48,7 @@ String getMediaType() { if (metaData != null) { - return convertString(metaData.getMediaType()); + return convertString(metaData.getMediaTypeIA5()); } return null; diff --git a/pkix/src/main/java/org/bouncycastle/tsp/ers/ArchiveTimeStampValidationException.java b/pkix/src/main/java/org/bouncycastle/tsp/ers/ArchiveTimeStampValidationException.java index 0ddee09069..89475a21ab 100644 --- a/pkix/src/main/java/org/bouncycastle/tsp/ers/ArchiveTimeStampValidationException.java +++ b/pkix/src/main/java/org/bouncycastle/tsp/ers/ArchiveTimeStampValidationException.java @@ -3,7 +3,7 @@ /** * Exception thrown if an Archive TimeStamp according to RFC4998 fails to containsHashValue. *

      - * {@see RFC4998} + * @see RFC4998 */ public class ArchiveTimeStampValidationException extends ERSException diff --git a/pkix/src/main/java/org/bouncycastle/tsp/ers/ERSException.java b/pkix/src/main/java/org/bouncycastle/tsp/ers/ERSException.java index bfaa256469..5e270978ee 100644 --- a/pkix/src/main/java/org/bouncycastle/tsp/ers/ERSException.java +++ b/pkix/src/main/java/org/bouncycastle/tsp/ers/ERSException.java @@ -3,7 +3,7 @@ /** * Exception thrown if an Archive TimeStamp according to RFC4998 fails to containsHashValue. *

      - * {@see RFC4998} + * @see RFC4998 */ public class ERSException diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/CertificateRequestMessage.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/CertificateRequestMessage.java index ae328d6833..b91afbf539 100644 --- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/CertificateRequestMessage.java +++ b/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/CertificateRequestMessage.java @@ -4,7 +4,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.DERUTF8String; +import org.bouncycastle.asn1.ASN1UTF8String; import org.bouncycastle.asn1.crmf.AttributeTypeAndValue; import org.bouncycastle.asn1.crmf.CRMFObjectIdentifiers; import org.bouncycastle.asn1.crmf.CertReqMsg; @@ -126,11 +126,11 @@ public Control getControl(ASN1ObjectIdentifier type) } if (found.getType().equals(CRMFObjectIdentifiers.id_regCtrl_regToken)) { - return new RegTokenControl(DERUTF8String.getInstance(found.getValue())); + return new RegTokenControl(ASN1UTF8String.getInstance(found.getValue())); } if (found.getType().equals(CRMFObjectIdentifiers.id_regCtrl_authenticator)) { - return new AuthenticatorControl(DERUTF8String.getInstance(found.getValue())); + return new AuthenticatorControl(ASN1UTF8String.getInstance(found.getValue())); } } diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java index 22a35371db..32eb8d0773 100644 --- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java +++ b/pkix/src/main/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.selector.X509CertificateHolderSelector; +import org.bouncycastle.util.Exceptions; public class JcaX509CertSelectorConverter { @@ -26,7 +27,7 @@ protected X509CertSelector doConversion(X500Name issuer, BigInteger serialNumber } catch (IOException e) { - throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); + throw Exceptions.illegalArgumentException("unable to convert issuer: " + e.getMessage(), e); } } @@ -43,7 +44,7 @@ protected X509CertSelector doConversion(X500Name issuer, BigInteger serialNumber } catch (IOException e) { - throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); + throw Exceptions.illegalArgumentException("unable to convert subjectKeyIdentifier: " + e.getMessage(), e); } } diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java index 4de1c2272b..12443146ee 100644 --- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java +++ b/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java @@ -181,6 +181,22 @@ public Key getJceKey(ASN1ObjectIdentifier algorithm, GenericKey key) throw new IllegalArgumentException("unknown generic key type"); } + public Key getJceKey(AlgorithmIdentifier algId, GenericKey key) + { + ASN1ObjectIdentifier algorithm = algId.getAlgorithm(); + if (key.getRepresentation() instanceof Key) + { + return (Key)key.getRepresentation(); + } + + if (key.getRepresentation() instanceof byte[]) + { + return new SecretKeySpec((byte[])key.getRepresentation(), getBaseCipherName(algorithm)); + } + + throw new IllegalArgumentException("unknown generic key type"); + } + public void keySizeCheck(AlgorithmIdentifier keyAlgorithm, Key key) throws CMSException { diff --git a/pkix/src/main/jdk1.2/org/bouncycastle/cms/CMSAuthEnvelopedDataStreamGenerator.java b/pkix/src/main/jdk1.2/org/bouncycastle/cms/CMSAuthEnvelopedDataStreamGenerator.java new file mode 100644 index 0000000000..bae9303f34 --- /dev/null +++ b/pkix/src/main/jdk1.2/org/bouncycastle/cms/CMSAuthEnvelopedDataStreamGenerator.java @@ -0,0 +1,202 @@ +package org.bouncycastle.cms; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collections; +import java.util.HashMap; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.BERSequenceGenerator; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.cms.AuthenticatedData; +import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.operator.OutputAEADEncryptor; + +public class CMSAuthEnvelopedDataStreamGenerator + extends CMSAuthEnvelopedGenerator +{ + + private int _bufferSize; + private boolean _berEncodeRecipientSet; + + public CMSAuthEnvelopedDataStreamGenerator() + { + + } + + /** + * Set the underlying string size for encapsulated data + * + * @param bufferSize length of octet strings to buffer the data. + */ + public void setBufferSize( + int bufferSize) + { + _bufferSize = bufferSize; + } + + /** + * Use a BER Set to store the recipient information + */ + public void setBEREncodeRecipients( + boolean berEncodeRecipientSet) + { + _berEncodeRecipientSet = berEncodeRecipientSet; + } + + private OutputStream doOpen( + ASN1ObjectIdentifier dataType, + OutputStream out, + OutputAEADEncryptor encryptor) + throws IOException, CMSException + { + ASN1EncodableVector recipientInfos = CMSUtils.getRecipentInfos(encryptor.getKey(), recipientInfoGenerators); + + return open(dataType, out, recipientInfos, encryptor); + } + + protected OutputStream open( + ASN1ObjectIdentifier dataType, + OutputStream out, + ASN1EncodableVector recipientInfos, + OutputAEADEncryptor encryptor) + throws IOException + { + // + // ContentInfo + // + BERSequenceGenerator cGen = new BERSequenceGenerator(out); + + cGen.addObject(CMSObjectIdentifiers.authEnvelopedData); + + // + // Encrypted Data + // + BERSequenceGenerator authEnvGen = new BERSequenceGenerator(cGen.getRawOutputStream(), 0, true); + + authEnvGen.addObject(new ASN1Integer(AuthenticatedData.calculateVersion(originatorInfo))); + + CMSUtils.addOriginatorInfoToGenerator(authEnvGen, originatorInfo); + + CMSUtils.addRecipientInfosToGenerator(recipientInfos, authEnvGen, _berEncodeRecipientSet); + + BERSequenceGenerator eiGen = new BERSequenceGenerator(authEnvGen.getRawOutputStream()); + + eiGen.addObject(dataType); + + AlgorithmIdentifier encAlgId = encryptor.getAlgorithmIdentifier(); + + eiGen.getRawOutputStream().write(encAlgId.getEncoded()); + + OutputStream octetStream = CMSUtils.createBEROctetOutputStream( + eiGen.getRawOutputStream(), 0, true, _bufferSize); + + return new CMSAuthEnvelopedDataOutputStream(encryptor, octetStream, cGen, authEnvGen, eiGen); + } + + protected OutputStream open( + OutputStream out, + ASN1EncodableVector recipientInfos, + OutputAEADEncryptor encryptor) + throws CMSException + { + try + { + return open(CMSObjectIdentifiers.data, out, recipientInfos, encryptor); + } + catch (IOException e) + { + throw new CMSException("exception decoding algorithm parameters.", e); + } + } + + + /** + * generate an enveloped object that contains an CMS Enveloped Data + * object using the given encryptor. + */ + public OutputStream open( + OutputStream out, + OutputAEADEncryptor encryptor) + throws CMSException, IOException + { + return doOpen(new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId()), out, encryptor); + } + + private class CMSAuthEnvelopedDataOutputStream + extends OutputStream + { + private final OutputAEADEncryptor _encryptor; + private final OutputStream _cOut; + private final OutputStream _octetStream; + private final BERSequenceGenerator _cGen; + private final BERSequenceGenerator _envGen; + private final BERSequenceGenerator _eiGen; + + public CMSAuthEnvelopedDataOutputStream( + OutputAEADEncryptor encryptor, + OutputStream octetStream, + BERSequenceGenerator cGen, + BERSequenceGenerator envGen, + BERSequenceGenerator eiGen) + { + _encryptor = encryptor; + _octetStream = octetStream; + _cOut = encryptor.getOutputStream(octetStream); + _cGen = cGen; + _envGen = envGen; + _eiGen = eiGen; + } + + public void write( + int b) + throws IOException + { + _cOut.write(b); + } + + public void write( + byte[] bytes, + int off, + int len) + throws IOException + { + _cOut.write(bytes, off, len); + } + + public void write( + byte[] bytes) + throws IOException + { + _cOut.write(bytes); + } + + public void close() + throws IOException + { + ASN1Set authenticatedAttrSet = CMSUtils.processAuthAttrSet(authAttrsGenerator, _encryptor); + + _cOut.close(); + _octetStream.close(); + _eiGen.close(); + + if (authenticatedAttrSet != null) + { + _envGen.addObject(new DERTaggedObject(false, 1, authenticatedAttrSet)); + } + + _envGen.addObject(new DEROctetString(_encryptor.getMAC())); + + CMSUtils.addAttriSetToGenerator(_envGen, unauthAttrsGenerator, 2, new HashMap()); + + _envGen.close(); + _cGen.close(); + } + } + +} diff --git a/pkix/src/main/jdk1.2/org/bouncycastle/cms/CMSUtils.java b/pkix/src/main/jdk1.2/org/bouncycastle/cms/CMSUtils.java new file mode 100644 index 0000000000..078864f4f2 --- /dev/null +++ b/pkix/src/main/jdk1.2/org/bouncycastle/cms/CMSUtils.java @@ -0,0 +1,544 @@ +package org.bouncycastle.cms; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1SequenceParser; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.ASN1SetParser; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BEROctetString; +import org.bouncycastle.asn1.BEROctetStringGenerator; +import org.bouncycastle.asn1.BERSequenceGenerator; +import org.bouncycastle.asn1.BERSet; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.DERSet; +import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.DLSet; +import org.bouncycastle.asn1.cms.AttributeTable; +import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; +import org.bouncycastle.asn1.cms.ContentInfo; +import org.bouncycastle.asn1.cms.EncryptedContentInfo; +import org.bouncycastle.asn1.cms.OriginatorInfo; +import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; +import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; +import org.bouncycastle.asn1.ocsp.OCSPResponse; +import org.bouncycastle.asn1.ocsp.OCSPResponseStatus; +import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; +import org.bouncycastle.asn1.sec.SECObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.cert.X509AttributeCertificateHolder; +import org.bouncycastle.cert.X509CRLHolder; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; +import org.bouncycastle.operator.DigestCalculator; +import org.bouncycastle.operator.GenericKey; +import org.bouncycastle.operator.OutputAEADEncryptor; +import org.bouncycastle.operator.OutputEncryptor; +import org.bouncycastle.util.Store; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.io.Streams; +import org.bouncycastle.util.io.TeeInputStream; +import org.bouncycastle.util.io.TeeOutputStream; + +class CMSUtils +{ + private static final Set des = new HashSet(); + private static final Set mqvAlgs = new HashSet(); + private static final Set ecAlgs = new HashSet(); + private static final Set gostAlgs = new HashSet(); + + static + { + des.add("DES"); + des.add("DESEDE"); + des.add(OIWObjectIdentifiers.desCBC.getId()); + des.add(PKCSObjectIdentifiers.des_EDE3_CBC.getId()); + des.add(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId()); + + mqvAlgs.add(X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme); + mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme); + mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme); + mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme); + mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme); + + ecAlgs.add(X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme); + ecAlgs.add(X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme); + + gostAlgs.add(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_ESDH); + gostAlgs.add(RosstandartObjectIdentifiers.id_tc26_agreement_gost_3410_12_256); + gostAlgs.add(RosstandartObjectIdentifiers.id_tc26_agreement_gost_3410_12_512); + } + + static boolean isMQV(ASN1ObjectIdentifier algorithm) + { + return mqvAlgs.contains(algorithm); + } + + static boolean isEC(ASN1ObjectIdentifier algorithm) + { + return ecAlgs.contains(algorithm); + } + + static boolean isGOST(ASN1ObjectIdentifier algorithm) + { + return gostAlgs.contains(algorithm); + } + + static boolean isRFC2631(ASN1ObjectIdentifier algorithm) + { + return algorithm.equals(PKCSObjectIdentifiers.id_alg_ESDH) || algorithm.equals(PKCSObjectIdentifiers.id_alg_SSDH); + } + + static boolean isDES(String algorithmID) + { + String name = Strings.toUpperCase(algorithmID); + + return des.contains(name); + } + + static boolean isEquivalent(AlgorithmIdentifier algId1, AlgorithmIdentifier algId2) + { + if (algId1 == null || algId2 == null) + { + return false; + } + + if (!algId1.getAlgorithm().equals(algId2.getAlgorithm())) + { + return false; + } + + ASN1Encodable params1 = algId1.getParameters(); + ASN1Encodable params2 = algId2.getParameters(); + if (params1 != null) + { + return params1.equals(params2) || (params1.equals(DERNull.INSTANCE) && params2 == null); + } + + return params2 == null || params2.equals(DERNull.INSTANCE); + } + + static ContentInfo readContentInfo( + byte[] input) + throws CMSException + { + // enforce limit checking as from a byte array + return readContentInfo(new ASN1InputStream(input)); + } + + static ContentInfo readContentInfo( + InputStream input) + throws CMSException + { + // enforce some limit checking + return readContentInfo(new ASN1InputStream(input)); + } + + static ASN1Set convertToDlSet(Set digestAlgs) + { + return new DLSet((AlgorithmIdentifier[])digestAlgs.toArray(new AlgorithmIdentifier[digestAlgs.size()])); + } + + static void addDigestAlgs(Set digestAlgs, SignerInformation signer, DigestAlgorithmIdentifierFinder dgstAlgFinder) + { + digestAlgs.add(CMSSignedHelper.INSTANCE.fixDigestAlgID(signer.getDigestAlgorithmID(), dgstAlgFinder)); + SignerInformationStore counterSignaturesStore = signer.getCounterSignatures(); + Iterator counterSignatureIt = counterSignaturesStore.iterator(); + while (counterSignatureIt.hasNext()) + { + SignerInformation counterSigner = (SignerInformation)counterSignatureIt.next(); + digestAlgs.add(CMSSignedHelper.INSTANCE.fixDigestAlgID(counterSigner.getDigestAlgorithmID(), dgstAlgFinder)); + } + } + + static List getCertificatesFromStore(Store certStore) + throws CMSException + { + List certs = new ArrayList(); + + try + { + for (Iterator it = certStore.getMatches(null).iterator(); it.hasNext(); ) + { + X509CertificateHolder c = (X509CertificateHolder)it.next(); + + certs.add(c.toASN1Structure()); + } + + return certs; + } + catch (ClassCastException e) + { + throw new CMSException("error processing certs", e); + } + } + + static List getAttributeCertificatesFromStore(Store attrStore) + throws CMSException + { + List certs = new ArrayList(); + + try + { + for (Iterator it = attrStore.getMatches(null).iterator(); it.hasNext(); ) + { + X509AttributeCertificateHolder attrCert = (X509AttributeCertificateHolder)it.next(); + + certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure())); + } + + return certs; + } + catch (ClassCastException e) + { + throw new CMSException("error processing certs", e); + } + } + + + static List getCRLsFromStore(Store crlStore) + throws CMSException + { + List crls = new ArrayList(); + + try + { + for (Iterator it = crlStore.getMatches(null).iterator(); it.hasNext(); ) + { + Object rev = it.next(); + + if (rev instanceof X509CRLHolder) + { + X509CRLHolder c = (X509CRLHolder)rev; + + crls.add(c.toASN1Structure()); + } + else if (rev instanceof OtherRevocationInfoFormat) + { + OtherRevocationInfoFormat infoFormat = OtherRevocationInfoFormat.getInstance(rev); + + validateInfoFormat(infoFormat); + + crls.add(new DERTaggedObject(false, 1, infoFormat)); + } + else if (rev instanceof ASN1TaggedObject) + { + crls.add(rev); + } + } + + return crls; + } + catch (ClassCastException e) + { + throw new CMSException("error processing certs", e); + } + } + + static void validateInfoFormat(OtherRevocationInfoFormat infoFormat) + { + if (CMSObjectIdentifiers.id_ri_ocsp_response.equals(infoFormat.getInfoFormat())) + { + OCSPResponse resp = OCSPResponse.getInstance(infoFormat.getInfo()); + + if (OCSPResponseStatus.SUCCESSFUL != resp.getResponseStatus().getIntValue()) + { + throw new IllegalArgumentException("cannot add unsuccessful OCSP response to CMS SignedData"); + } + } + } + + static Collection getOthersFromStore(ASN1ObjectIdentifier otherRevocationInfoFormat, Store otherRevocationInfos) + { + List others = new ArrayList(); + + for (Iterator it = otherRevocationInfos.getMatches(null).iterator(); it.hasNext(); ) + { + ASN1Encodable info = (ASN1Encodable)it.next(); + OtherRevocationInfoFormat infoFormat = new OtherRevocationInfoFormat(otherRevocationInfoFormat, info); + + validateInfoFormat(infoFormat); + + others.add(new DERTaggedObject(false, 1, infoFormat)); + } + + return others; + } + + static ASN1Set createBerSetFromList(List derObjects) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + for (Iterator it = derObjects.iterator(); it.hasNext(); ) + { + v.add((ASN1Encodable)it.next()); + } + + return new BERSet(v); + } + + static ASN1Set createDlSetFromList(List derObjects) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + for (Iterator it = derObjects.iterator(); it.hasNext(); ) + { + v.add((ASN1Encodable)it.next()); + } + + return new DLSet(v); + } + + static ASN1Set createDerSetFromList(List derObjects) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + for (Iterator it = derObjects.iterator(); it.hasNext(); ) + { + v.add((ASN1Encodable)it.next()); + } + + return new DERSet(v); + } + + static OutputStream createBEROctetOutputStream(OutputStream s, + int tagNo, boolean isExplicit, int bufferSize) + throws IOException + { + BEROctetStringGenerator octGen = new BEROctetStringGenerator(s, tagNo, isExplicit); + + if (bufferSize != 0) + { + return octGen.getOctetOutputStream(new byte[bufferSize]); + } + + return octGen.getOctetOutputStream(); + } + + private static ContentInfo readContentInfo( + ASN1InputStream in) + throws CMSException + { + try + { + ContentInfo info = ContentInfo.getInstance(in.readObject()); + if (info == null) + { + throw new CMSException("No content found."); + } + + return info; + } + catch (IOException e) + { + throw new CMSException("IOException reading content.", e); + } + catch (ClassCastException e) + { + throw new CMSException("Malformed content.", e); + } + catch (IllegalArgumentException e) + { + throw new CMSException("Malformed content.", e); + } + } + + public static byte[] streamToByteArray( + InputStream in) + throws IOException + { + return Streams.readAll(in); + } + + public static byte[] streamToByteArray( + InputStream in, + int limit) + throws IOException + { + return Streams.readAllLimited(in, limit); + } + + static InputStream attachDigestsToInputStream(Collection digests, InputStream s) + { + InputStream result = s; + Iterator it = digests.iterator(); + while (it.hasNext()) + { + DigestCalculator digest = (DigestCalculator)it.next(); + result = new TeeInputStream(result, digest.getOutputStream()); + } + return result; + } + + static OutputStream attachSignersToOutputStream(Collection signers, OutputStream s) + { + OutputStream result = s; + Iterator it = signers.iterator(); + while (it.hasNext()) + { + SignerInfoGenerator signerGen = (SignerInfoGenerator)it.next(); + result = getSafeTeeOutputStream(result, signerGen.getCalculatingOutputStream()); + } + return result; + } + + static OutputStream getSafeOutputStream(OutputStream s) + { + return s == null ? new NullOutputStream() : s; + } + + static OutputStream getSafeTeeOutputStream(OutputStream s1, + OutputStream s2) + { + return s1 == null ? getSafeOutputStream(s2) + : s2 == null ? getSafeOutputStream(s1) : new TeeOutputStream( + s1, s2); + } + + static EncryptedContentInfo getEncryptedContentInfo(CMSTypedData content, OutputEncryptor contentEncryptor, byte[] encryptedContent) + { + return getEncryptedContentInfo( + content.getContentType(), + contentEncryptor.getAlgorithmIdentifier(), + encryptedContent); + } + + static EncryptedContentInfo getEncryptedContentInfo(ASN1ObjectIdentifier encryptedContentType, AlgorithmIdentifier encAlgId, byte[] encryptedContent) + { + ASN1OctetString encContent = new BEROctetString(encryptedContent); + + return new EncryptedContentInfo( + encryptedContentType, + encAlgId, + encContent); + } + + static ASN1EncodableVector getRecipentInfos(GenericKey encKey, List recipientInfoGenerators) + throws CMSException + { + ASN1EncodableVector recipientInfos = new ASN1EncodableVector(); + Iterator it = recipientInfoGenerators.iterator(); + + while (it.hasNext()) + { + RecipientInfoGenerator recipient = (RecipientInfoGenerator)it.next(); + + recipientInfos.add(recipient.generate(encKey)); + } + return recipientInfos; + } + + static void addRecipientInfosToGenerator(ASN1EncodableVector recipientInfos, BERSequenceGenerator authGen, boolean berEncodeRecipientSet) + throws IOException + { + if (berEncodeRecipientSet) + { + authGen.getRawOutputStream().write(new BERSet(recipientInfos).getEncoded()); + } + else + { + authGen.getRawOutputStream().write(new DERSet(recipientInfos).getEncoded()); + } + } + + static void addOriginatorInfoToGenerator(BERSequenceGenerator envGen, OriginatorInfo originatorInfo) + throws IOException + { + if (originatorInfo != null) + { + envGen.addObject(new DERTaggedObject(false, 0, originatorInfo)); + } + } + + static void addAttriSetToGenerator(BERSequenceGenerator gen, CMSAttributeTableGenerator attriGen, int tagNo, Map parameters) + throws IOException + { + if (attriGen != null) + { + gen.addObject(new DERTaggedObject(false, tagNo, new BERSet(attriGen.getAttributes(parameters).toASN1EncodableVector()))); + } + } + + static ASN1Set processAuthAttrSet(CMSAttributeTableGenerator authAttrsGenerator, OutputAEADEncryptor encryptor) + throws IOException + { + ASN1Set authenticatedAttrSet = null; + if (authAttrsGenerator != null) + { + AttributeTable attrTable = authAttrsGenerator.getAttributes(new HashMap()); + + authenticatedAttrSet = new DERSet(attrTable.toASN1EncodableVector()); + encryptor.getAADStream().write(authenticatedAttrSet.getEncoded(ASN1Encoding.DER)); + } + return authenticatedAttrSet; + } + + static AttributeTable getAttributesTable(ASN1SetParser set) + throws IOException + { + if (set != null) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + ASN1Encodable o; + + while ((o = set.readObject()) != null) + { + ASN1SequenceParser seq = (ASN1SequenceParser)o; + + v.add(seq.toASN1Primitive()); + } + return new AttributeTable(new DERSet(v)); + } + return null; + } + + static ASN1Set getAttrDLSet(CMSAttributeTableGenerator gen) + { + return (gen != null) ? new DLSet(gen.getAttributes(new HashMap()).toASN1EncodableVector()) : null; + } + + static ASN1Set getAttrBERSet(CMSAttributeTableGenerator gen) + { + return (gen != null) ? new BERSet(gen.getAttributes(new HashMap()).toASN1EncodableVector()) : null; + } + + static byte[] encodeObj( + ASN1Encodable obj) + throws IOException + { + if (obj != null) + { + return obj.toASN1Primitive().getEncoded(); + } + + return null; + } +} diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java index 42e46977ac..61172f4495 100644 --- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java +++ b/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java @@ -74,6 +74,23 @@ public JcaX509v3CertificateBuilder(X509Certificate template) super(new JcaX509CertificateHolder(template)); } + /** + * Initialise the builder using the subject from the passed in issuerCert as the issuer, as well as + * passing through and converting the other objects provided. + * + * @param issuerCert certificate who's subject is the issuer of the certificate we are building. + * @param serial the serial number for the certificate. + * @param notBefore date before which the certificate is not valid. + * @param notAfter date after which the certificate is not valid. + * @param subject principal representing the subject of this certificate. + * @param publicKey the public key to be associated with the certificate. + */ + public JcaX509v3CertificateBuilder(X509Certificate issuerCert, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, PublicKey publicKey) + throws CertificateEncodingException + { + this(new JcaX509CertificateHolder(issuerCert).getSubject(), serial, notBefore, notAfter, subject, publicKey); + } + /** * Add a given extension field for the standard extensions tag (tag 3) * copying the extension value from another certificate. diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java b/pkix/src/main/jdk1.3/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java index 8968744230..666e7bc930 100644 --- a/pkix/src/main/jdk1.3/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java +++ b/pkix/src/main/jdk1.3/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java @@ -4,10 +4,12 @@ import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; /** - * Extension of the PKCS#10 builder to support PublicKey and X500Principal objects. + * Extension of the PKCS#10 builder to support PublicKey objects. */ public class JcaPKCS10CertificationRequestBuilder extends PKCS10CertificationRequestBuilder @@ -22,4 +24,12 @@ public JcaPKCS10CertificationRequestBuilder(X500Name subject, PublicKey publicKe { super(subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); } + + public PKCS10CertificationRequest build( + ContentSigner signer, + PublicKey altPublicKey, + ContentSigner altSigner) + { + return super.build(signer, SubjectPublicKeyInfo.getInstance(altPublicKey.getEncoded()), altSigner); + } } diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/pkix/SubjectPublicKeyInfoChecker.java b/pkix/src/main/jdk1.3/org/bouncycastle/pkix/SubjectPublicKeyInfoChecker.java index bf866a1da7..4936e4a75c 100644 --- a/pkix/src/main/jdk1.3/org/bouncycastle/pkix/SubjectPublicKeyInfoChecker.java +++ b/pkix/src/main/jdk1.3/org/bouncycastle/pkix/SubjectPublicKeyInfoChecker.java @@ -22,6 +22,7 @@ import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.math.Primes; +import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Strings; /** @@ -40,8 +41,6 @@ public class SubjectPublicKeyInfoChecker + "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f", 16); - private static final BigInteger ONE = BigInteger.valueOf(1); - public static void checkInfo(SubjectPublicKeyInfo pubInfo) { ASN1ObjectIdentifier algorithm = pubInfo.getAlgorithm().getAlgorithm(); @@ -110,6 +109,18 @@ else if (PKCSObjectIdentifiers.rsaEncryption.equals(algorithm) } } + private static boolean hasAnySmallFactors(BigInteger modulus) + { + BigInteger M = modulus, X = SMALL_PRIMES_PRODUCT; + if (modulus.compareTo(SMALL_PRIMES_PRODUCT) < 0) + { + M = SMALL_PRIMES_PRODUCT; + X = modulus; + } + + return !BigIntegers.modOddIsCoprimeVar(M, X); + } + private static void validate(BigInteger modulus) { if ((modulus.intValue() & 1) == 0) @@ -123,15 +134,13 @@ private static void validate(BigInteger modulus) return; } - int maxBitLength = Properties.asInteger("org.bouncycastle.rsa.max_size", 15360); - - int modBitLength = modulus.bitLength(); - if (maxBitLength < modBitLength) + int maxBitLength = Properties.asInteger("org.bouncycastle.rsa.max_size", 16384); + if (maxBitLength < modulus.bitLength()) { - throw new IllegalArgumentException("modulus value out of range"); + throw new IllegalArgumentException("RSA modulus out of range"); } - if (!modulus.gcd(SMALL_PRIMES_PRODUCT).equals(ONE)) + if (hasAnySmallFactors(modulus)) { throw new IllegalArgumentException("RSA modulus has a small prime factor"); } @@ -142,7 +151,8 @@ private static void validate(BigInteger modulus) : bits >= 512 ? 7 : 50; - Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, CryptoServicesRegistrar.getSecureRandom(), iterations); + Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, CryptoServicesRegistrar.getSecureRandom(), + iterations); if (!mr.isProvablyComposite()) { throw new IllegalArgumentException("RSA modulus is not composite"); diff --git a/pkix/src/main/jdk1.4/org/bouncycastle/pkix/ASN1PKIXNameConstraintValidator.java b/pkix/src/main/jdk1.4/org/bouncycastle/pkix/ASN1PKIXNameConstraintValidator.java new file mode 100644 index 0000000000..392f5d6305 --- /dev/null +++ b/pkix/src/main/jdk1.4/org/bouncycastle/pkix/ASN1PKIXNameConstraintValidator.java @@ -0,0 +1,2152 @@ +package org.bouncycastle.pkix; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.bouncycastle.asn1.ASN1IA5String; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.x500.RDN; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.style.IETFUtils; +import org.bouncycastle.asn1.x500.style.RFC4519Style; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralSubtree; +import org.bouncycastle.asn1.x509.NameConstraintValidator; +import org.bouncycastle.asn1.x509.NameConstraintValidatorException; +import org.bouncycastle.asn1.x509.OtherName; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Integers; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Hex; + +class ASN1PKIXNameConstraintValidator + implements NameConstraintValidator +{ + private Set excludedSubtreesDN = new HashSet(); + + private Set excludedSubtreesDNS = new HashSet(); + + private Set excludedSubtreesEmail = new HashSet(); + + private Set excludedSubtreesURI = new HashSet(); + + private Set excludedSubtreesIP = new HashSet(); + + private Set excludedSubtreesOtherName = new HashSet(); + + private Set permittedSubtreesDN; + + private Set permittedSubtreesDNS; + + private Set permittedSubtreesEmail; + + private Set permittedSubtreesURI; + + private Set permittedSubtreesIP; + + private Set permittedSubtreesOtherName; + + public ASN1PKIXNameConstraintValidator() + { + } + + /** + * Checks if the given GeneralName is in the permitted set. + * + * @param name The GeneralName + * @throws NameConstraintValidatorException If the name + */ + public void checkPermitted(GeneralName name) + throws NameConstraintValidatorException + { + switch (name.getTagNo()) + { + case GeneralName.otherName: + checkPermittedOtherName(permittedSubtreesOtherName, OtherName.getInstance(name.getName())); + break; + case GeneralName.rfc822Name: + checkPermittedEmail(permittedSubtreesEmail, + extractNameAsString(name)); + break; + case GeneralName.dNSName: + checkPermittedDNS(permittedSubtreesDNS, ASN1IA5String.getInstance( + name.getName()).getString()); + break; + case GeneralName.directoryName: + checkPermittedDN(X500Name.getInstance(name.getName())); + break; + case GeneralName.uniformResourceIdentifier: + checkPermittedURI(permittedSubtreesURI, ASN1IA5String.getInstance( + name.getName()).getString()); + break; + case GeneralName.iPAddress: + byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets(); + + checkPermittedIP(permittedSubtreesIP, ip); + break; + default: + // other tags to be ignored. + } + } + + /** + * Check if the given GeneralName is contained in the excluded set. + * + * @param name The GeneralName. + * @throws NameConstraintValidatorException If the name is + * excluded. + */ + public void checkExcluded(GeneralName name) + throws NameConstraintValidatorException + { + switch (name.getTagNo()) + { + case GeneralName.otherName: + checkExcludedOtherName(excludedSubtreesOtherName, OtherName.getInstance(name.getName())); + break; + case GeneralName.rfc822Name: + checkExcludedEmail(excludedSubtreesEmail, extractNameAsString(name)); + break; + case GeneralName.dNSName: + checkExcludedDNS(excludedSubtreesDNS, ASN1IA5String.getInstance( + name.getName()).getString()); + break; + case GeneralName.directoryName: + checkExcludedDN(X500Name.getInstance(name.getName())); + break; + case GeneralName.uniformResourceIdentifier: + checkExcludedURI(excludedSubtreesURI, ASN1IA5String.getInstance( + name.getName()).getString()); + break; + case GeneralName.iPAddress: + byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets(); + + checkExcludedIP(excludedSubtreesIP, ip); + break; + default: + // other tags to be ignored. + } + } + + public void intersectPermittedSubtree(GeneralSubtree permitted) + { + intersectPermittedSubtree(new GeneralSubtree[]{permitted}); + } + + /** + * Updates the permitted set of these name constraints with the intersection + * with the given subtree. + * + * @param permitted The permitted subtrees + */ + public void intersectPermittedSubtree(GeneralSubtree[] permitted) + { + Map subtreesMap = new HashMap(); + + // group in sets in a map ordered by tag no. + for (int i = 0; i != permitted.length; i++) + { + GeneralSubtree subtree = permitted[i]; + Integer tagNo = Integers.valueOf(subtree.getBase().getTagNo()); + if (subtreesMap.get(tagNo) == null) + { + subtreesMap.put(tagNo, new HashSet()); + } + ((Set)subtreesMap.get(tagNo)).add(subtree); + } + + for (Iterator it = subtreesMap.entrySet().iterator(); it.hasNext();) + { + Map.Entry entry = (Map.Entry)it.next(); + + // go through all subtree groups + int nameType = ((Integer)entry.getKey()).intValue(); + switch (nameType) + { + case GeneralName.otherName: + permittedSubtreesOtherName = intersectOtherName(permittedSubtreesOtherName, + (Set)entry.getValue()); + break; + case GeneralName.rfc822Name: + permittedSubtreesEmail = intersectEmail(permittedSubtreesEmail, + (Set)entry.getValue()); + break; + case GeneralName.dNSName: + permittedSubtreesDNS = intersectDNS(permittedSubtreesDNS, + (Set)entry.getValue()); + break; + case GeneralName.directoryName: + permittedSubtreesDN = intersectDN(permittedSubtreesDN, + (Set)entry.getValue()); + break; + case GeneralName.uniformResourceIdentifier: + permittedSubtreesURI = intersectURI(permittedSubtreesURI, + (Set)entry.getValue()); + break; + case GeneralName.iPAddress: + permittedSubtreesIP = intersectIP(permittedSubtreesIP, + (Set)entry.getValue()); + break; + default: + throw new IllegalStateException("Unknown tag encountered: " + nameType); + } + } + } + + public void intersectEmptyPermittedSubtree(int nameType) + { + switch (nameType) + { + case GeneralName.otherName: + permittedSubtreesOtherName = new HashSet(); + break; + case GeneralName.rfc822Name: + permittedSubtreesEmail = new HashSet(); + break; + case GeneralName.dNSName: + permittedSubtreesDNS = new HashSet(); + break; + case GeneralName.directoryName: + permittedSubtreesDN = new HashSet(); + break; + case GeneralName.uniformResourceIdentifier: + permittedSubtreesURI = new HashSet(); + break; + case GeneralName.iPAddress: + permittedSubtreesIP = new HashSet(); + break; + default: + throw new IllegalStateException("Unknown tag encountered: " + nameType); + } + } + + /** + * Adds a subtree to the excluded set of these name constraints. + * + * @param subtree A subtree with an excluded GeneralName. + */ + public void addExcludedSubtree(GeneralSubtree subtree) + { + GeneralName base = subtree.getBase(); + + switch (base.getTagNo()) + { + case GeneralName.otherName: + excludedSubtreesOtherName = unionOtherName(excludedSubtreesOtherName, + OtherName.getInstance(base.getName())); + break; + case GeneralName.rfc822Name: + excludedSubtreesEmail = unionEmail(excludedSubtreesEmail, + extractNameAsString(base)); + break; + case GeneralName.dNSName: + excludedSubtreesDNS = unionDNS(excludedSubtreesDNS, + extractNameAsString(base)); + break; + case GeneralName.directoryName: + excludedSubtreesDN = unionDN(excludedSubtreesDN, + (ASN1Sequence)base.getName().toASN1Primitive()); + break; + case GeneralName.uniformResourceIdentifier: + excludedSubtreesURI = unionURI(excludedSubtreesURI, + extractNameAsString(base)); + break; + case GeneralName.iPAddress: + excludedSubtreesIP = unionIP(excludedSubtreesIP, ASN1OctetString + .getInstance(base.getName()).getOctets()); + break; + default: + throw new IllegalStateException("Unknown tag encountered: " + base.getTagNo()); + } + } + + public int hashCode() + { + return hashCollection(excludedSubtreesDN) + + hashCollection(excludedSubtreesDNS) + + hashCollection(excludedSubtreesEmail) + + hashCollection(excludedSubtreesIP) + + hashCollection(excludedSubtreesURI) + + hashCollection(excludedSubtreesOtherName) + + hashCollection(permittedSubtreesDN) + + hashCollection(permittedSubtreesDNS) + + hashCollection(permittedSubtreesEmail) + + hashCollection(permittedSubtreesIP) + + hashCollection(permittedSubtreesURI) + + hashCollection(permittedSubtreesOtherName); + } + + public boolean equals(Object o) + { + if (!(o instanceof ASN1PKIXNameConstraintValidator)) + { + return false; + } + ASN1PKIXNameConstraintValidator constraintValidator = (ASN1PKIXNameConstraintValidator)o; + return collectionsAreEqual(constraintValidator.excludedSubtreesDN, excludedSubtreesDN) + && collectionsAreEqual(constraintValidator.excludedSubtreesDNS, excludedSubtreesDNS) + && collectionsAreEqual(constraintValidator.excludedSubtreesEmail, excludedSubtreesEmail) + && collectionsAreEqual(constraintValidator.excludedSubtreesIP, excludedSubtreesIP) + && collectionsAreEqual(constraintValidator.excludedSubtreesURI, excludedSubtreesURI) + && collectionsAreEqual(constraintValidator.excludedSubtreesOtherName, excludedSubtreesOtherName) + && collectionsAreEqual(constraintValidator.permittedSubtreesDN, permittedSubtreesDN) + && collectionsAreEqual(constraintValidator.permittedSubtreesDNS, permittedSubtreesDNS) + && collectionsAreEqual(constraintValidator.permittedSubtreesEmail, permittedSubtreesEmail) + && collectionsAreEqual(constraintValidator.permittedSubtreesIP, permittedSubtreesIP) + && collectionsAreEqual(constraintValidator.permittedSubtreesURI, permittedSubtreesURI) + && collectionsAreEqual(constraintValidator.permittedSubtreesOtherName, permittedSubtreesOtherName); + } + + public void checkPermittedDN(X500Name dns) + throws NameConstraintValidatorException + { + checkPermittedDN(permittedSubtreesDN, ASN1Sequence.getInstance(dns.toASN1Primitive())); + } + + public void checkExcludedDN(X500Name dns) + throws NameConstraintValidatorException + { + checkExcludedDN(excludedSubtreesDN, ASN1Sequence.getInstance(dns)); + } + + private static boolean withinDNSubtree( + ASN1Sequence dns, + ASN1Sequence subtree) + { + if (subtree.size() < 1) + { + return false; + } + + if (subtree.size() > dns.size()) + { + return false; + } + + int start = 0; + RDN subtreeRdnStart = RDN.getInstance(subtree.getObjectAt(0)); + for (int j = 0; j < dns.size(); j++) + { + start = j; + RDN dnsRdn = RDN.getInstance(dns.getObjectAt(j)); + if (dnsRdn.equals(subtreeRdnStart)) + { + break; + } + } + + if (subtree.size() > dns.size() - start) + { + return false; + } + + for (int j = 0; j < subtree.size(); j++) + { + // both subtree and dns are a ASN.1 Name and the elements are a RDN + RDN subtreeRdn = RDN.getInstance(subtree.getObjectAt(j)); + RDN dnsRdn = RDN.getInstance(dns.getObjectAt(start + j)); + + // check if types and values of all naming attributes are matching, other types which are not restricted are allowed, see https://tools.ietf.org/html/rfc5280#section-7.1 + if (subtreeRdn.size() == dnsRdn.size()) + { + // Two relative distinguished names + // RDN1 and RDN2 match if they have the same number of naming attributes + // and for each naming attribute in RDN1 there is a matching naming attribute in RDN2. + // NOTE: this is checking the attributes in the same order, which might be not necessary, if this is a problem also IETFUtils.rDNAreEqual mus tbe changed. + // use new RFC 5280 comparison, NOTE: this is now different from with RFC 3280, where only binary comparison is used + // obey RFC 5280 7.1 + // special treatment of serialNumber for GSMA SGP.22 RSP specification + if (!subtreeRdn.getFirst().getType().equals(dnsRdn.getFirst().getType())) + { + return false; + } + if (subtreeRdn.size() == 1 && subtreeRdn.getFirst().getType().equals(RFC4519Style.serialNumber)) + { + if (!dnsRdn.getFirst().getValue().toString().startsWith(subtreeRdn.getFirst().getValue().toString())) + { + return false; + } + } + else if (!IETFUtils.rDNAreEqual(subtreeRdn, dnsRdn)) + { + return false; + } + } + else + { + return false; + } + } + + return true; + } + + private void checkPermittedDN(Set permitted, ASN1Sequence dns) + throws NameConstraintValidatorException + { + if (permitted == null) + { + return; + } + + if (permitted.isEmpty() && dns.size() == 0) + { + return; + } + Iterator it = permitted.iterator(); + + while (it.hasNext()) + { + ASN1Sequence subtree = (ASN1Sequence)it.next(); + + if (withinDNSubtree(dns, subtree)) + { + return; + } + } + + throw new NameConstraintValidatorException( + "Subject distinguished name is not from a permitted subtree"); + } + + private void checkExcludedDN(Set excluded, ASN1Sequence dns) + throws NameConstraintValidatorException + { + if (excluded.isEmpty()) + { + return; + } + + Iterator it = excluded.iterator(); + + while (it.hasNext()) + { + ASN1Sequence subtree = (ASN1Sequence)it.next(); + + if (withinDNSubtree(dns, subtree)) + { + throw new NameConstraintValidatorException( + "Subject distinguished name is from an excluded subtree"); + } + } + } + + private Set intersectDN(Set permitted, Set dns) + { + Set intersect = new HashSet(); + for (Iterator it = dns.iterator(); it.hasNext();) + { + ASN1Sequence dn = ASN1Sequence.getInstance(((GeneralSubtree)it + .next()).getBase().getName().toASN1Primitive()); + if (permitted == null) + { + if (dn != null) + { + intersect.add(dn); + } + } + else + { + Iterator _iter = permitted.iterator(); + while (_iter.hasNext()) + { + ASN1Sequence subtree = (ASN1Sequence)_iter.next(); + + if (withinDNSubtree(dn, subtree)) + { + intersect.add(dn); + } + else if (withinDNSubtree(subtree, dn)) + { + intersect.add(subtree); + } + } + } + } + return intersect; + } + + private Set unionDN(Set excluded, ASN1Sequence dn) + { + if (excluded.isEmpty()) + { + if (dn == null) + { + return excluded; + } + excluded.add(dn); + + return excluded; + } + else + { + Set intersect = new HashSet(); + + Iterator it = excluded.iterator(); + while (it.hasNext()) + { + ASN1Sequence subtree = (ASN1Sequence)it.next(); + + if (withinDNSubtree(dn, subtree)) + { + intersect.add(subtree); + } + else if (withinDNSubtree(subtree, dn)) + { + intersect.add(dn); + } + else + { + intersect.add(subtree); + intersect.add(dn); + } + } + + return intersect; + } + } + + private Set intersectOtherName(Set permitted, Set otherNames) + { + Set intersect = new HashSet(permitted); + + intersect.retainAll(otherNames); + + return intersect; + } + + + private Set unionOtherName(Set permitted, OtherName otherName) + { + Set union = new HashSet(permitted); + + union.add(otherName); + + return union; + } + + private Set intersectEmail(Set permitted, Set emails) + { + Set intersect = new HashSet(); + for (Iterator it = emails.iterator(); it.hasNext();) + { + String email = extractNameAsString(((GeneralSubtree)it.next()) + .getBase()); + + if (permitted == null) + { + if (email != null) + { + intersect.add(email); + } + } + else + { + Iterator it2 = permitted.iterator(); + while (it2.hasNext()) + { + String _permitted = (String)it2.next(); + + intersectEmail(email, _permitted, intersect); + } + } + } + return intersect; + } + + private Set unionEmail(Set excluded, String email) + { + if (excluded.isEmpty()) + { + if (email == null) + { + return excluded; + } + excluded.add(email); + return excluded; + } + else + { + Set union = new HashSet(); + + Iterator it = excluded.iterator(); + while (it.hasNext()) + { + String _excluded = (String)it.next(); + + unionEmail(_excluded, email, union); + } + + return union; + } + } + + /** + * Returns the intersection of the permitted IP ranges in + * permitted with ip. + * + * @param permitted A Set of permitted IP addresses with + * their subnet mask as byte arrays. + * @param ips The IP address with its subnet mask. + * @return The Set of permitted IP ranges intersected with + * ip. + */ + private Set intersectIP(Set permitted, Set ips) + { + Set intersect = new HashSet(); + for (Iterator it = ips.iterator(); it.hasNext();) + { + byte[] ip = ASN1OctetString.getInstance( + ((GeneralSubtree)it.next()).getBase().getName()).getOctets(); + if (permitted == null) + { + if (ip != null) + { + intersect.add(ip); + } + } + else + { + Iterator it2 = permitted.iterator(); + while (it2.hasNext()) + { + byte[] _permitted = (byte[])it2.next(); + intersect.addAll(intersectIPRange(_permitted, ip)); + } + } + } + return intersect; + } + + /** + * Returns the union of the excluded IP ranges in excluded + * with ip. + * + * @param excluded A Set of excluded IP addresses with their + * subnet mask as byte arrays. + * @param ip The IP address with its subnet mask. + * @return The Set of excluded IP ranges unified with + * ip as byte arrays. + */ + private Set unionIP(Set excluded, byte[] ip) + { + if (excluded.isEmpty()) + { + if (ip == null) + { + return excluded; + } + excluded.add(ip); + + return excluded; + } + else + { + Set union = new HashSet(); + + Iterator it = excluded.iterator(); + while (it.hasNext()) + { + byte[] _excluded = (byte[])it.next(); + union.addAll(unionIPRange(_excluded, ip)); + } + + return union; + } + } + + /** + * Calculates the union if two IP ranges. + * + * @param ipWithSubmask1 The first IP address with its subnet mask. + * @param ipWithSubmask2 The second IP address with its subnet mask. + * @return A Set with the union of both addresses. + */ + private Set unionIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2) + { + Set set = new HashSet(); + + // difficult, adding always all IPs is not wrong + if (Arrays.areEqual(ipWithSubmask1, ipWithSubmask2)) + { + set.add(ipWithSubmask1); + } + else + { + set.add(ipWithSubmask1); + set.add(ipWithSubmask2); + } + return set; + } + + /** + * Calculates the intersection if two IP ranges. + * + * @param ipWithSubmask1 The first IP address with its subnet mask. + * @param ipWithSubmask2 The second IP address with its subnet mask. + * @return A Set with the single IP address with its subnet + * mask as a byte array or an empty Set. + */ + private Set intersectIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2) + { + if (ipWithSubmask1.length != ipWithSubmask2.length) + { + return Collections.EMPTY_SET; + } + byte[][] temp = extractIPsAndSubnetMasks(ipWithSubmask1, ipWithSubmask2); + byte ip1[] = temp[0]; + byte subnetmask1[] = temp[1]; + byte ip2[] = temp[2]; + byte subnetmask2[] = temp[3]; + + byte minMax[][] = minMaxIPs(ip1, subnetmask1, ip2, subnetmask2); + byte[] min; + byte[] max; + max = min(minMax[1], minMax[3]); + min = max(minMax[0], minMax[2]); + + // minimum IP address must be bigger than max + if (compareTo(min, max) == 1) + { + return Collections.EMPTY_SET; + } + // OR keeps all significant bits + byte[] ip = or(minMax[0], minMax[2]); + byte[] subnetmask = or(subnetmask1, subnetmask2); + return Collections.singleton(ipWithSubnetMask(ip, subnetmask)); + } + + /** + * Concatenates the IP address with its subnet mask. + * + * @param ip The IP address. + * @param subnetMask Its subnet mask. + * @return The concatenated IP address with its subnet mask. + */ + private byte[] ipWithSubnetMask(byte[] ip, byte[] subnetMask) + { + int ipLength = ip.length; + byte[] temp = new byte[ipLength * 2]; + System.arraycopy(ip, 0, temp, 0, ipLength); + System.arraycopy(subnetMask, 0, temp, ipLength, ipLength); + return temp; + } + + /** + * Splits the IP addresses and their subnet mask. + * + * @param ipWithSubmask1 The first IP address with the subnet mask. + * @param ipWithSubmask2 The second IP address with the subnet mask. + * @return An array with two elements. Each element contains the IP address + * and the subnet mask in this order. + */ + private byte[][] extractIPsAndSubnetMasks( + byte[] ipWithSubmask1, + byte[] ipWithSubmask2) + { + int ipLength = ipWithSubmask1.length / 2; + byte ip1[] = new byte[ipLength]; + byte subnetmask1[] = new byte[ipLength]; + System.arraycopy(ipWithSubmask1, 0, ip1, 0, ipLength); + System.arraycopy(ipWithSubmask1, ipLength, subnetmask1, 0, ipLength); + + byte ip2[] = new byte[ipLength]; + byte subnetmask2[] = new byte[ipLength]; + System.arraycopy(ipWithSubmask2, 0, ip2, 0, ipLength); + System.arraycopy(ipWithSubmask2, ipLength, subnetmask2, 0, ipLength); + return new byte[][] + {ip1, subnetmask1, ip2, subnetmask2}; + } + + /** + * Based on the two IP addresses and their subnet masks the IP range is + * computed for each IP address - subnet mask pair and returned as the + * minimum IP address and the maximum address of the range. + * + * @param ip1 The first IP address. + * @param subnetmask1 The subnet mask of the first IP address. + * @param ip2 The second IP address. + * @param subnetmask2 The subnet mask of the second IP address. + * @return A array with two elements. The first/second element contains the + * min and max IP address of the first/second IP address and its + * subnet mask. + */ + private byte[][] minMaxIPs( + byte[] ip1, + byte[] subnetmask1, + byte[] ip2, + byte[] subnetmask2) + { + int ipLength = ip1.length; + byte[] min1 = new byte[ipLength]; + byte[] max1 = new byte[ipLength]; + + byte[] min2 = new byte[ipLength]; + byte[] max2 = new byte[ipLength]; + + for (int i = 0; i < ipLength; i++) + { + min1[i] = (byte)(ip1[i] & subnetmask1[i]); + max1[i] = (byte)(ip1[i] & subnetmask1[i] | ~subnetmask1[i]); + + min2[i] = (byte)(ip2[i] & subnetmask2[i]); + max2[i] = (byte)(ip2[i] & subnetmask2[i] | ~subnetmask2[i]); + } + + return new byte[][]{min1, max1, min2, max2}; + } + + private void checkPermittedEmail(Set permitted, String email) + throws NameConstraintValidatorException + { + if (permitted == null) + { + return; + } + + Iterator it = permitted.iterator(); + + while (it.hasNext()) + { + String str = ((String)it.next()); + + if (emailIsConstrained(email, str)) + { + return; + } + } + + if (email.length() == 0 && permitted.size() == 0) + { + return; + } + + throw new NameConstraintValidatorException( + "Subject email address is not from a permitted subtree."); + } + + private void checkPermittedOtherName(Set permitted, OtherName name) + throws NameConstraintValidatorException + { + if (permitted == null) + { + return; + } + + Iterator it = permitted.iterator(); + + while (it.hasNext()) + { + OtherName str = ((OtherName)it.next()); + + if (otherNameIsConstrained(name, str)) + { + return; + } + } + + throw new NameConstraintValidatorException( + "Subject OtherName is not from a permitted subtree."); + } + + private void checkExcludedOtherName(Set excluded, OtherName name) + throws NameConstraintValidatorException + { + if (excluded.isEmpty()) + { + return; + } + + Iterator it = excluded.iterator(); + + while (it.hasNext()) + { + OtherName str = OtherName.getInstance(it.next()); + + if (otherNameIsConstrained(name, str)) + { + throw new NameConstraintValidatorException( + "OtherName is from an excluded subtree."); + } + } + } + + private void checkExcludedEmail(Set excluded, String email) + throws NameConstraintValidatorException + { + if (excluded.isEmpty()) + { + return; + } + + Iterator it = excluded.iterator(); + + while (it.hasNext()) + { + String str = (String)it.next(); + + if (emailIsConstrained(email, str)) + { + throw new NameConstraintValidatorException( + "Email address is from an excluded subtree."); + } + } + } + + /** + * Checks if the IP ip is included in the permitted set + * permitted. + * + * @param permitted A Set of permitted IP addresses with + * their subnet mask as byte arrays. + * @param ip The IP address. + * @throws NameConstraintValidatorException if the IP is not permitted. + */ + private void checkPermittedIP(Set permitted, byte[] ip) + throws NameConstraintValidatorException + { + if (permitted == null) + { + return; + } + + Iterator it = permitted.iterator(); + + while (it.hasNext()) + { + byte[] ipWithSubnet = (byte[])it.next(); + + if (isIPConstrained(ip, ipWithSubnet)) + { + return; + } + } + if (ip.length == 0 && permitted.size() == 0) + { + return; + } + throw new NameConstraintValidatorException( + "IP is not from a permitted subtree."); + } + + /** + * Checks if the IP ip is included in the excluded set + * excluded. + * + * @param excluded A Set of excluded IP addresses with their + * subnet mask as byte arrays. + * @param ip The IP address. + * @throws NameConstraintValidatorException if the IP is excluded. + */ + private void checkExcludedIP(Set excluded, byte[] ip) + throws NameConstraintValidatorException + { + if (excluded.isEmpty()) + { + return; + } + + Iterator it = excluded.iterator(); + + while (it.hasNext()) + { + byte[] ipWithSubnet = (byte[])it.next(); + + if (isIPConstrained(ip, ipWithSubnet)) + { + throw new NameConstraintValidatorException( + "IP is from an excluded subtree."); + } + } + } + + /** + * Checks if the IP address ip is constrained by + * constraint. + * + * @param ip The IP address. + * @param constraint The constraint. This is an IP address concatenated with + * its subnetmask. + * @return true if constrained, false + * otherwise. + */ + private boolean isIPConstrained(byte ip[], byte[] constraint) + { + int ipLength = ip.length; + + if (ipLength != (constraint.length / 2)) + { + return false; + } + + byte[] subnetMask = new byte[ipLength]; + System.arraycopy(constraint, ipLength, subnetMask, 0, ipLength); + + byte[] permittedSubnetAddress = new byte[ipLength]; + + byte[] ipSubnetAddress = new byte[ipLength]; + + // the resulting IP address by applying the subnet mask + for (int i = 0; i < ipLength; i++) + { + permittedSubnetAddress[i] = (byte)(constraint[i] & subnetMask[i]); + ipSubnetAddress[i] = (byte)(ip[i] & subnetMask[i]); + } + + return Arrays.areEqual(permittedSubnetAddress, ipSubnetAddress); + } + + private boolean otherNameIsConstrained(OtherName name, OtherName constraint) + { + if (constraint.equals(name)) + { + return true; + } + + return false; + } + + private boolean emailIsConstrained(String email, String constraint) + { + String sub = email.substring(email.indexOf('@') + 1); + // a particular mailbox + if (constraint.indexOf('@') != -1) + { + if (email.equalsIgnoreCase(constraint)) + { + return true; + } + if (sub.equalsIgnoreCase(constraint.substring(1))) + { + return true; + } + } + // on particular host + else if (!(constraint.charAt(0) == '.')) + { + if (sub.equalsIgnoreCase(constraint)) + { + return true; + } + } + // address in sub domain + else if (withinDomain(sub, constraint)) + { + return true; + } + return false; + } + + private boolean withinDomain(String testDomain, String domain) + { + String tempDomain = domain; + if (tempDomain.startsWith(".")) + { + tempDomain = tempDomain.substring(1); + } + String[] domainParts = Strings.split(tempDomain, '.'); + String[] testDomainParts = Strings.split(testDomain, '.'); + // must have at least one subdomain + if (testDomainParts.length <= domainParts.length) + { + return false; + } + int d = testDomainParts.length - domainParts.length; + for (int i = -1; i < domainParts.length; i++) + { + if (i == -1) + { + if (testDomainParts[i + d].equals("")) + { + return false; + } + } + else if (!domainParts[i].equalsIgnoreCase(testDomainParts[i + d])) + { + return false; + } + } + return true; + } + + private void checkPermittedDNS(Set permitted, String dns) + throws NameConstraintValidatorException + { + if (permitted == null) + { + return; + } + + Iterator it = permitted.iterator(); + + while (it.hasNext()) + { + String str = ((String)it.next()); + + // is sub domain + if (withinDomain(dns, str) || dns.equalsIgnoreCase(str)) + { + return; + } + } + if (dns.length() == 0 && permitted.size() == 0) + { + return; + } + throw new NameConstraintValidatorException( + "DNS is not from a permitted subtree."); + } + + private void checkExcludedDNS(Set excluded, String dns) + throws NameConstraintValidatorException + { + if (excluded.isEmpty()) + { + return; + } + + Iterator it = excluded.iterator(); + + while (it.hasNext()) + { + String str = ((String)it.next()); + + // is sub domain or the same + if (withinDomain(dns, str) || dns.equalsIgnoreCase(str)) + { + throw new NameConstraintValidatorException( + "DNS is from an excluded subtree."); + } + } + } + + /** + * The common part of email1 and email2 is + * added to the union union. If email1 and + * email2 have nothing in common they are added both. + * + * @param email1 Email address constraint 1. + * @param email2 Email address constraint 2. + * @param union The union. + */ + private void unionEmail(String email1, String email2, Set union) + { + // email1 is a particular address + if (email1.indexOf('@') != -1) + { + String _sub = email1.substring(email1.indexOf('@') + 1); + // both are a particular mailbox + if (email2.indexOf('@') != -1) + { + if (email1.equalsIgnoreCase(email2)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(_sub, email2)) + { + union.add(email2); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a particular host + else + { + if (_sub.equalsIgnoreCase(email2)) + { + union.add(email2); + } + else + { + union.add(email1); + union.add(email2); + } + } + } + // email1 specifies a domain + else if (email1.startsWith(".")) + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email1.indexOf('@') + 1); + if (withinDomain(_sub, email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2) + || email1.equalsIgnoreCase(email2)) + { + union.add(email2); + } + else if (withinDomain(email2, email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + else + { + if (withinDomain(email2, email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + } + // email specifies a host + else + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email1.indexOf('@') + 1); + if (_sub.equalsIgnoreCase(email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2)) + { + union.add(email2); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a particular host + else + { + if (email1.equalsIgnoreCase(email2)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + } + } + + private void unionURI(String email1, String email2, Set union) + { + // email1 is a particular address + if (email1.indexOf('@') != -1) + { + String _sub = email1.substring(email1.indexOf('@') + 1); + // both are a particular mailbox + if (email2.indexOf('@') != -1) + { + if (email1.equalsIgnoreCase(email2)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(_sub, email2)) + { + union.add(email2); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a particular host + else + { + if (_sub.equalsIgnoreCase(email2)) + { + union.add(email2); + } + else + { + union.add(email1); + union.add(email2); + } + } + } + // email1 specifies a domain + else if (email1.startsWith(".")) + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email1.indexOf('@') + 1); + if (withinDomain(_sub, email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2) + || email1.equalsIgnoreCase(email2)) + { + union.add(email2); + } + else if (withinDomain(email2, email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + else + { + if (withinDomain(email2, email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + } + // email specifies a host + else + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email1.indexOf('@') + 1); + if (_sub.equalsIgnoreCase(email1)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2)) + { + union.add(email2); + } + else + { + union.add(email1); + union.add(email2); + } + } + // email2 specifies a particular host + else + { + if (email1.equalsIgnoreCase(email2)) + { + union.add(email1); + } + else + { + union.add(email1); + union.add(email2); + } + } + } + } + + private Set intersectDNS(Set permitted, Set dnss) + { + Set intersect = new HashSet(); + for (Iterator it = dnss.iterator(); it.hasNext();) + { + String dns = extractNameAsString(((GeneralSubtree)it.next()) + .getBase()); + if (permitted == null) + { + if (dns != null) + { + intersect.add(dns); + } + } + else + { + Iterator _iter = permitted.iterator(); + while (_iter.hasNext()) + { + String _permitted = (String)_iter.next(); + + if (withinDomain(_permitted, dns)) + { + intersect.add(_permitted); + } + else if (withinDomain(dns, _permitted)) + { + intersect.add(dns); + } + } + } + } + + return intersect; + } + + private Set unionDNS(Set excluded, String dns) + { + if (excluded.isEmpty()) + { + if (dns == null) + { + return excluded; + } + excluded.add(dns); + + return excluded; + } + else + { + Set union = new HashSet(); + + Iterator _iter = excluded.iterator(); + while (_iter.hasNext()) + { + String _permitted = (String)_iter.next(); + + if (withinDomain(_permitted, dns)) + { + union.add(dns); + } + else if (withinDomain(dns, _permitted)) + { + union.add(_permitted); + } + else + { + union.add(_permitted); + union.add(dns); + } + } + + return union; + } + } + + /** + * The most restricting part from email1 and + * email2 is added to the intersection intersect. + * + * @param email1 Email address constraint 1. + * @param email2 Email address constraint 2. + * @param intersect The intersection. + */ + private void intersectEmail(String email1, String email2, Set intersect) + { + // email1 is a particular address + if (email1.indexOf('@') != -1) + { + String _sub = email1.substring(email1.indexOf('@') + 1); + // both are a particular mailbox + if (email2.indexOf('@') != -1) + { + if (email1.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(_sub, email2)) + { + intersect.add(email1); + } + } + // email2 specifies a particular host + else + { + if (_sub.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + } + } + // email specifies a domain + else if (email1.startsWith(".")) + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email1.indexOf('@') + 1); + if (withinDomain(_sub, email1)) + { + intersect.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2) + || email1.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + else if (withinDomain(email2, email1)) + { + intersect.add(email2); + } + } + else + { + if (withinDomain(email2, email1)) + { + intersect.add(email2); + } + } + } + // email1 specifies a host + else + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email2.indexOf('@') + 1); + if (_sub.equalsIgnoreCase(email1)) + { + intersect.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2)) + { + intersect.add(email1); + } + } + // email2 specifies a particular host + else + { + if (email1.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + } + } + } + + private void checkExcludedURI(Set excluded, String uri) + throws NameConstraintValidatorException + { + if (excluded.isEmpty()) + { + return; + } + + Iterator it = excluded.iterator(); + + while (it.hasNext()) + { + String str = ((String)it.next()); + + if (isUriConstrained(uri, str)) + { + throw new NameConstraintValidatorException( + "URI is from an excluded subtree."); + } + } + } + + private Set intersectURI(Set permitted, Set uris) + { + Set intersect = new HashSet(); + for (Iterator it = uris.iterator(); it.hasNext();) + { + String uri = extractNameAsString(((GeneralSubtree)it.next()) + .getBase()); + if (permitted == null) + { + if (uri != null) + { + intersect.add(uri); + } + } + else + { + Iterator _iter = permitted.iterator(); + while (_iter.hasNext()) + { + String _permitted = (String)_iter.next(); + intersectURI(_permitted, uri, intersect); + } + } + } + return intersect; + } + + private Set unionURI(Set excluded, String uri) + { + if (excluded.isEmpty()) + { + if (uri == null) + { + return excluded; + } + excluded.add(uri); + + return excluded; + } + else + { + Set union = new HashSet(); + + Iterator _iter = excluded.iterator(); + while (_iter.hasNext()) + { + String _excluded = (String)_iter.next(); + + unionURI(_excluded, uri, union); + } + + return union; + } + } + + private void intersectURI(String email1, String email2, Set intersect) + { + // email1 is a particular address + if (email1.indexOf('@') != -1) + { + String _sub = email1.substring(email1.indexOf('@') + 1); + // both are a particular mailbox + if (email2.indexOf('@') != -1) + { + if (email1.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(_sub, email2)) + { + intersect.add(email1); + } + } + // email2 specifies a particular host + else + { + if (_sub.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + } + } + // email specifies a domain + else if (email1.startsWith(".")) + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email1.indexOf('@') + 1); + if (withinDomain(_sub, email1)) + { + intersect.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2) + || email1.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + else if (withinDomain(email2, email1)) + { + intersect.add(email2); + } + } + else + { + if (withinDomain(email2, email1)) + { + intersect.add(email2); + } + } + } + // email1 specifies a host + else + { + if (email2.indexOf('@') != -1) + { + String _sub = email2.substring(email2.indexOf('@') + 1); + if (_sub.equalsIgnoreCase(email1)) + { + intersect.add(email2); + } + } + // email2 specifies a domain + else if (email2.startsWith(".")) + { + if (withinDomain(email1, email2)) + { + intersect.add(email1); + } + } + // email2 specifies a particular host + else + { + if (email1.equalsIgnoreCase(email2)) + { + intersect.add(email1); + } + } + } + } + + private void checkPermittedURI(Set permitted, String uri) + throws NameConstraintValidatorException + { + if (permitted == null) + { + return; + } + + Iterator it = permitted.iterator(); + + while (it.hasNext()) + { + String str = ((String)it.next()); + + if (isUriConstrained(uri, str)) + { + return; + } + } + if (uri.length() == 0 && permitted.size() == 0) + { + return; + } + throw new NameConstraintValidatorException( + "URI is not from a permitted subtree."); + } + + private boolean isUriConstrained(String uri, String constraint) + { + String host = extractHostFromURL(uri); + // a host + if (!constraint.startsWith(".")) + { + if (host.equalsIgnoreCase(constraint)) + { + return true; + } + } + + // in sub domain or domain + else if (withinDomain(host, constraint)) + { + return true; + } + + return false; + } + + private static String extractHostFromURL(String url) + { + // see RFC 1738 + // remove ':' after protocol, e.g. http: + String sub = url.substring(url.indexOf(':') + 1); + // extract host from Common Internet Scheme Syntax, e.g. https:// + if (sub.indexOf("//") != -1) + { + sub = sub.substring(sub.indexOf("//") + 2); + } + // first remove port, e.g. https://test.com:21 + if (sub.lastIndexOf(':') != -1) + { + sub = sub.substring(0, sub.lastIndexOf(':')); + } + // remove user and password, e.g. https://john:password@test.com + sub = sub.substring(sub.indexOf(':') + 1); + sub = sub.substring(sub.indexOf('@') + 1); + // remove local parts, e.g. http://test.com/bla + if (sub.indexOf('/') != -1) + { + sub = sub.substring(0, sub.indexOf('/')); + } + return sub; + } + + private String extractNameAsString(GeneralName name) + { + return ASN1IA5String.getInstance(name.getName()).getString(); + } + + /** + * Returns the maximum IP address. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return The maximum IP address. + */ + private static byte[] max(byte[] ip1, byte[] ip2) + { + for (int i = 0; i < ip1.length; i++) + { + if ((ip1[i] & 0xFFFF) > (ip2[i] & 0xFFFF)) + { + return ip1; + } + } + return ip2; + } + + /** + * Returns the minimum IP address. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return The minimum IP address. + */ + private static byte[] min(byte[] ip1, byte[] ip2) + { + for (int i = 0; i < ip1.length; i++) + { + if ((ip1[i] & 0xFFFF) < (ip2[i] & 0xFFFF)) + { + return ip1; + } + } + return ip2; + } + + /** + * Compares IP address ip1 with ip2. If ip1 + * is equal to ip2 0 is returned. If ip1 is bigger 1 is returned, -1 + * otherwise. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return 0 if ip1 is equal to ip2, 1 if ip1 is bigger, -1 otherwise. + */ + private static int compareTo(byte[] ip1, byte[] ip2) + { + if (Arrays.areEqual(ip1, ip2)) + { + return 0; + } + if (Arrays.areEqual(max(ip1, ip2), ip1)) + { + return 1; + } + return -1; + } + + /** + * Returns the logical OR of the IP addresses ip1 and + * ip2. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return The OR of ip1 and ip2. + */ + private static byte[] or(byte[] ip1, byte[] ip2) + { + byte[] temp = new byte[ip1.length]; + for (int i = 0; i < ip1.length; i++) + { + temp[i] = (byte)(ip1[i] | ip2[i]); + } + return temp; + } + + private int hashCollection(Collection coll) + { + if (coll == null) + { + return 0; + } + int hash = 0; + Iterator it1 = coll.iterator(); + while (it1.hasNext()) + { + Object o = it1.next(); + if (o instanceof byte[]) + { + hash += Arrays.hashCode((byte[])o); + } + else + { + hash += o.hashCode(); + } + } + return hash; + } + + private boolean collectionsAreEqual(Collection coll1, Collection coll2) + { + if (coll1 == coll2) + { + return true; + } + if (coll1 == null || coll2 == null) + { + return false; + } + if (coll1.size() != coll2.size()) + { + return false; + } + Iterator it1 = coll1.iterator(); + + while (it1.hasNext()) + { + Object a = it1.next(); + Iterator it2 = coll2.iterator(); + boolean found = false; + while (it2.hasNext()) + { + Object b = it2.next(); + if (equals(a, b)) + { + found = true; + break; + } + } + if (!found) + { + return false; + } + } + return true; + } + + private boolean equals(Object o1, Object o2) + { + if (o1 == o2) + { + return true; + } + if (o1 == null || o2 == null) + { + return false; + } + if (o1 instanceof byte[] && o2 instanceof byte[]) + { + return Arrays.areEqual((byte[])o1, (byte[])o2); + } + else + { + return o1.equals(o2); + } + } + + /** + * Stringifies an IPv4 or v6 address with subnet mask. + * + * @param ip The IP with subnet mask. + * @return The stringified IP address. + */ + private String stringifyIP(byte[] ip) + { + StringBuffer temp = new StringBuffer(); + for (int i = 0; i < ip.length / 2; i++) + { + if (temp.length() > 0) + { + temp.append("."); + } + temp.append(Integer.toString(ip[i] & 0x00FF)); + } + + temp.append("/"); + boolean first = true; + for (int i = ip.length / 2; i < ip.length; i++) + { + if (first) + { + first = false; + } + else + { + temp.append("."); + } + temp.append(Integer.toString(ip[i] & 0x00FF)); + } + + return temp.toString(); + } + + private String stringifyIPCollection(Set ips) + { + StringBuffer temp = new StringBuffer(); + temp.append("["); + for (Iterator it = ips.iterator(); it.hasNext();) + { + if (temp.length() > 1) + { + temp.append(","); + } + temp.append(stringifyIP((byte[])it.next())); + } + temp.append("]"); + return temp.toString(); + } + + private String stringifyOtherNameCollection(Set otherNames) + { + StringBuffer temp = new StringBuffer(); + temp.append("["); + for (Iterator it = otherNames.iterator(); it.hasNext();) + { + if (temp.length() > 1) + { + temp.append(","); + } + OtherName name = OtherName.getInstance(it.next()); + temp.append(name.getTypeID().getId()); + temp.append(":"); + try + { + // -DM Hex.toHexString + temp.append(Hex.toHexString(name.getValue().toASN1Primitive().getEncoded())); + } + catch (IOException e) + { + temp.append(e.toString()); + } + } + temp.append("]"); + return temp.toString(); + } + + private final void addLine(StringBuffer sb, String str) + { + sb.append(str).append(Strings.lineSeparator()); + } + + public String toString() + { + StringBuffer temp = new StringBuffer(); + + addLine(temp, "permitted:"); + if (permittedSubtreesDN != null) + { + addLine(temp, "DN:"); + addLine(temp, permittedSubtreesDN.toString()); + } + if (permittedSubtreesDNS != null) + { + addLine(temp, "DNS:"); + addLine(temp, permittedSubtreesDNS.toString()); + } + if (permittedSubtreesEmail != null) + { + addLine(temp, "Email:"); + addLine(temp, permittedSubtreesEmail.toString()); + } + if (permittedSubtreesURI != null) + { + addLine(temp, "URI:"); + addLine(temp, permittedSubtreesURI.toString()); + } + if (permittedSubtreesIP != null) + { + addLine(temp, "IP:"); + addLine(temp, stringifyIPCollection(permittedSubtreesIP)); + } + if (permittedSubtreesOtherName != null) + { + addLine(temp, "OtherName:"); + addLine(temp, stringifyOtherNameCollection(permittedSubtreesOtherName)); + } + addLine(temp, "excluded:"); + if (!excludedSubtreesDN.isEmpty()) + { + addLine(temp, "DN:"); + addLine(temp, excludedSubtreesDN.toString()); + } + if (!excludedSubtreesDNS.isEmpty()) + { + addLine(temp, "DNS:"); + addLine(temp, excludedSubtreesDNS.toString()); + } + if (!excludedSubtreesEmail.isEmpty()) + { + addLine(temp, "Email:"); + addLine(temp, excludedSubtreesEmail.toString()); + } + if (!excludedSubtreesURI.isEmpty()) + { + addLine(temp, "URI:"); + addLine(temp, excludedSubtreesURI.toString()); + } + if (!excludedSubtreesIP.isEmpty()) + { + addLine(temp, "IP:"); + addLine(temp, stringifyIPCollection(excludedSubtreesIP)); + } + if (!excludedSubtreesOtherName.isEmpty()) + { + addLine(temp, "OtherName:"); + addLine(temp, stringifyOtherNameCollection(excludedSubtreesOtherName)); + } + return temp.toString(); + } +} diff --git a/pkix/src/main/jdk1.4/org/bouncycastle/pkix/SubjectPublicKeyInfoChecker.java b/pkix/src/main/jdk1.4/org/bouncycastle/pkix/SubjectPublicKeyInfoChecker.java index bf866a1da7..4936e4a75c 100644 --- a/pkix/src/main/jdk1.4/org/bouncycastle/pkix/SubjectPublicKeyInfoChecker.java +++ b/pkix/src/main/jdk1.4/org/bouncycastle/pkix/SubjectPublicKeyInfoChecker.java @@ -22,6 +22,7 @@ import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.math.Primes; +import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Strings; /** @@ -40,8 +41,6 @@ public class SubjectPublicKeyInfoChecker + "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f", 16); - private static final BigInteger ONE = BigInteger.valueOf(1); - public static void checkInfo(SubjectPublicKeyInfo pubInfo) { ASN1ObjectIdentifier algorithm = pubInfo.getAlgorithm().getAlgorithm(); @@ -110,6 +109,18 @@ else if (PKCSObjectIdentifiers.rsaEncryption.equals(algorithm) } } + private static boolean hasAnySmallFactors(BigInteger modulus) + { + BigInteger M = modulus, X = SMALL_PRIMES_PRODUCT; + if (modulus.compareTo(SMALL_PRIMES_PRODUCT) < 0) + { + M = SMALL_PRIMES_PRODUCT; + X = modulus; + } + + return !BigIntegers.modOddIsCoprimeVar(M, X); + } + private static void validate(BigInteger modulus) { if ((modulus.intValue() & 1) == 0) @@ -123,15 +134,13 @@ private static void validate(BigInteger modulus) return; } - int maxBitLength = Properties.asInteger("org.bouncycastle.rsa.max_size", 15360); - - int modBitLength = modulus.bitLength(); - if (maxBitLength < modBitLength) + int maxBitLength = Properties.asInteger("org.bouncycastle.rsa.max_size", 16384); + if (maxBitLength < modulus.bitLength()) { - throw new IllegalArgumentException("modulus value out of range"); + throw new IllegalArgumentException("RSA modulus out of range"); } - if (!modulus.gcd(SMALL_PRIMES_PRODUCT).equals(ONE)) + if (hasAnySmallFactors(modulus)) { throw new IllegalArgumentException("RSA modulus has a small prime factor"); } @@ -142,7 +151,8 @@ private static void validate(BigInteger modulus) : bits >= 512 ? 7 : 50; - Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, CryptoServicesRegistrar.getSecureRandom(), iterations); + Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, CryptoServicesRegistrar.getSecureRandom(), + iterations); if (!mr.isProvablyComposite()) { throw new IllegalArgumentException("RSA modulus is not composite"); diff --git a/pkix/src/main/jdk1.4/org/bouncycastle/pkix/util/X509CertificateFormatter.java b/pkix/src/main/jdk1.4/org/bouncycastle/pkix/util/X509CertificateFormatter.java index d0e0a42fe1..d27d002792 100644 --- a/pkix/src/main/jdk1.4/org/bouncycastle/pkix/util/X509CertificateFormatter.java +++ b/pkix/src/main/jdk1.4/org/bouncycastle/pkix/util/X509CertificateFormatter.java @@ -319,7 +319,6 @@ else if (oid.equals(Extension.extendedKeyUsage)) } catch (Exception ex) { - ex.printStackTrace(); buf.append(oid.getId()); // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl); buf.append(" value = ").append("*****").append(nl); diff --git a/pkix/src/main/jdk1.9/module-info.java b/pkix/src/main/jdk1.9/module-info.java index 5d6d7b7573..4bde1c23f4 100644 --- a/pkix/src/main/jdk1.9/module-info.java +++ b/pkix/src/main/jdk1.9/module-info.java @@ -52,6 +52,8 @@ exports org.bouncycastle.pkcs.jcajce; exports org.bouncycastle.pkix; exports org.bouncycastle.pkix.jcajce; + exports org.bouncycastle.pkix.util; + exports org.bouncycastle.pkix.util.filter; exports org.bouncycastle.tsp; exports org.bouncycastle.tsp.cms; exports org.bouncycastle.tsp.ers; diff --git a/pkix/src/main/resources/org/bouncycastle/pkix/CertPathReviewerMessages.properties b/pkix/src/main/resources/org/bouncycastle/pkix/CertPathReviewerMessages.properties new file mode 100644 index 0000000000..7749f3c6f7 --- /dev/null +++ b/pkix/src/main/resources/org/bouncycastle/pkix/CertPathReviewerMessages.properties @@ -0,0 +1,616 @@ + +## constructor exceptions + +# cert path is empty +CertPathReviewer.emptyCertPath.title = CertPath is empty +CertPathReviewer.emptyCertPath.text = PKIXCertPathReviewer: the CertPath is empty. +CertPathReviewer.emptyCertPath.summary = PKIXCertPathReviewer: the CertPath is empty. +CertPathReviewer.emptyCertPath.details = PKIXCertPathReviewer: the CertPath is empty. + +## name constraints processing errors + +# cert DN is not in the permitted tree +# {0} DN as String +CertPathReviewer.notPermittedDN.title = Name constraint error: certificate DN is not permitted +CertPathReviewer.notPermittedDN.text = Name constraint error: the certificate DN {0} is not permitted. +CertPathReviewer.notPermittedDN.summary = Name constraint error: certificate DN is not permitted. +CertPathReviewer.notPermittedDN.details = Name constraint checking error. The certificate DN {0} is not in the permitted set of DNs. + +# cert DN is in the excluded tree +# {0} DN as String +CertPathReviewer.excludedDN.title = Name constraint error: certificate DN is excluded +CertPathReviewer.excludedDN.text = Name constraint error: The certificate DN {0} is excluded. +CertPathReviewer.excludedDN.summary = Name constraint error: certificate DN is excluded. +CertPathReviewer.excludedDN.details = Name constraint checking error. The certificate DN {0} is inside of the excluded set of DNs. + +# cert email is not in the permitted tree +# {0} email address as String +CertPathReviewer.notPermittedEmail.title = Name constraint error: not permitted email address +CertPathReviewer.notPermittedEmail.text = Name constraint error: certificate contains the not permitted email address {0}. +CertPathReviewer.notPermittedEmail.summary = Name constraint error: not permitted email address. +CertPathReviewer.notPermittedEmail.details = Name constraint checking error. The certificate contains the email address {0} which is not in the permitted set of email addresses. + +# cert email is in the excluded tree +# {0} email as String +CertPathReviewer.excludedEmail.title = Name constraint error: excluded email address +CertPathReviewer.excludedEmail.text = Name constraint error: certificate contains the excluded email address {0}. +CertPathReviewer.excludedEmail.summary = Name constraint error: excluded email address. +CertPathReviewer.excludedEmail.details = Name constraint checking error. The certificate contains the email address {0} which is in the excluded set of email addresses. + +# cert IP is not in the permitted tree +# {0} ip address as String +CertPathReviewer.notPermittedIP.title = Name constraint error: not permitted IP address +CertPathReviewer.notPermittedIP.text = Name constraint error: certificate contains the not permitted IP address {0}. +CertPathReviewer.notPermittedIP.summary = Name constraint error: not permitted IP address. +CertPathReviewer.notPermittedIP.details = Name constraint checking error. The certificate contains the IP address {0} which is not in the permitted set of IP addresses. + +# cert ip is in the excluded tree +# {0} ip address as String +CertPathReviewer.excludedIP.title = Name constraint error: excluded IP address +CertPathReviewer.excludedIP.text = Name constraint error: certificate contains the excluded IP address {0}. +CertPathReviewer.excludedIP.summary = Name constraint error: excluded IP address. +CertPathReviewer.excludedIP.details = Name constraint checking error. The certificate contains the IP address {0} which is in the excluded set of IP addresses. + +# error processing the name constraints extension +CertPathReviewer.ncExtError.title = Name constraint checking failed +CertPathReviewer.ncExtError.text = Name constraint checking failed: there was an error processing the name constraints extension of the certificate. +CertPathReviewer.ncExtError.summary = Error processing the name constraints extension. +CertPathReviewer.ncExtError.details = Name constraint checking failed: there was an error processing the name constraints extension of the certificate. + +# error processing the subject alternative name extension +CertPathReviewer.subjAltNameExtError.title = Name constraint checking failed +CertPathReviewer.subjAltNameExtError.text = Name constraint checking failed: there was an error processing the subject alternative name extension of the certificate. +CertPathReviewer.subjAltNameExtError.summary = Error processing the subject alternative name extension. +CertPathReviewer.subjAltNameExtError.details = Name constraint checking failed: there was an error processing the subject alternative name extension of the certificate. + +# exception extracting subject name when checking subtrees +# {0} subject Principal +CertPathReviewer.ncSubjectNameError.title = Name constraint checking failed +CertPathReviewer.ncSubjectNameError.text = Name constraint checking failed: there was an exception extracting the DN from the certificate. +CertPathReviewer.ncSubjectNameError.summary = Name constraint checking failed: exception extracting the DN. +CertPathReviewer.ncSubjectNameError.details = Name constraint checking failed: there was an exception extracting the DN from the certificate. + + +## path length errors + +# max path length extended +CertPathReviewer.pathLengthExtended.title = Maximum path length extended +CertPathReviewer.pathLengthExtended.text = Certificate path invalid: Maximum path length extended. +CertPathReviewer.pathLengthExtended.summary = Certificate path invalid: Maximum path length extended. +CertPathReviewer.pathLengthExtended.details = Certificate path invalid: Maximum path length extended. + +# error reading length constraint from basic constraint extension +CertPathReviewer.processLengthConstError.title = Path length checking failed +CertPathReviewer.processLengthConstError.text = Path length checking failed: there was an error processing the basic constraint extension of the certificate. +CertPathReviewer.processLengthConstError.summary = Error processing the subject alternative name extension. +CertPathReviewer.processLengthConstError.details = Path length checking failed: there was an error processing the basic constraint extension of the certificate. + + +## path length notifications + +# total path length as defined in rfc 3280 +# {0} the path length as Integer +CertPathReviewer.totalPathLength.title = Total path length +CertPathReviewer.totalPathLength.text = The total path length without self-signed certificates is {0}. +CertPathReviewer.totalPathLength.summary = The total path length without self-signed certificates is {0}. +CertPathReviewer.totalPathLength.details = The total path length without self-signed certificates, as defined in RFC 3280, is {0}. + + +## critical extensions errors + +# one unknown critical extension +# {0} extension as String +CertPathReviewer.unknownCriticalExt.title = Unknown critical extension +CertPathReviewer.unknownCriticalExt.text = The certificate contains the unknown critical extension {0}. +CertPathReviewer.unknownCriticalExt.summary = Unknown critical extension: {0}. +CertPathReviewer.unknownCriticalExt.details = The certificate contains the unknown critical extension with the OID {0}. + +# more unknown critical extensions +# {0} extensions as Set of Strings +CertPathReviewer.unknownCriticalExts.title = Unknown critical extensions +CertPathReviewer.unknownCriticalExts.text = The certificate contains two or more unknown critical extensions: {0}. +CertPathReviewer.unknownCriticalExts.summary = Unknown critical extensions: {0}. +CertPathReviewer.unknownCriticalExts.details = The certificate contains two or more unknown critical extensions with the OIDs: {0}. + +# error processing critical extension +# {0} the message of the underlying exception +# {1} the underlying exception +# {2} the name of the exception +CertPathReviewer.criticalExtensionError.title = Error processing a critical extension +CertPathReviewer.criticalExtensionError.text = Error processing a critical extension. A {0} occurred. +CertPathReviewer.criticalExtensionError.summary = Error processing a critical extension. A {0} occurred. +CertPathReviewer.criticalExtensionError.details = Error processing a critical extension. A {0} occurred. Cause: {0}. + +# error initializing the certpath checkers +# {0} the message of the underlying exception +# {1} the underlying exception +# {2} the name of the exception +CertPathReviewer.certPathCheckerError.title = Checking critical extensions failed +CertPathReviewer.certPathCheckerError.text = Checking critical extensions failed: there was a {2} initializing a CertPathChecker. +CertPathReviewer.certPathCheckerError.summary = Checking critical extensions failed: {2} initializing a CertPathChecker +CertPathReviewer.certPathCheckerError.details = Checking critical extensions failed: there was an {2} initializing a CertPathChecker. Cause: {0} + + +## check signature errors + +CertPathReviewer.rootKeyIsValidButNotATrustAnchor.title = Root key with valid signature but no trust anchor +CertPathReviewer.rootKeyIsValidButNotATrustAnchor.text = The certificate has a valid signature, but is no trust anchor +CertPathReviewer.rootKeyIsValidButNotATrustAnchor.summary = The certificate has a valid signature, but is no trust anchor +CertPathReviewer.rootKeyIsValidButNotATrustAnchor.details = The certificate has a valid signature, but is no trust anchor + +# trustanchor found, but certificate validation failed +CertPathReviewer.trustButInvalidCert.title = Trust anchor found, but different public key +CertPathReviewer.trustButInvalidCert.text = A trust anchor was found. But it has a different public key, than was used to issue the first certificate of the cert path. +CertPathReviewer.trustButInvalidCert.summary = A trust anchor was found. But it has a different public key, than was used to issue the first certificate of the cert path. +CertPathReviewer.trustButInvalidCert.details = A trust anchor was found. But it has a different public key, than was used to issue the first certificate of the cert path. + +# trustanchor - cannot extract issuer +CertPathReviewer.trustAnchorIssuerError.title = Finding trust anchor failed +CertPathReviewer.trustAnchorIssuerError.text = Finding trust anchor failed: cannot extract issuer from certificate. +CertPathReviewer.trustAnchorIssuerError.summary = Finding trust anchor failed: cannot extract issuer from certificate. +CertPathReviewer.trustAnchorIssuerError.details = Finding trust anchor failed: cannot extract issuer from certificate. + +# no trustanchor was found for the certificate path +# {0} issuer of the root certificate of the path +# {1} number of trusted root certificates (trustanchors) provided +CertPathReviewer.noTrustAnchorFound.title = No trusted root certificate found +CertPathReviewer.noTrustAnchorFound.text = The root certificate of the certificate path was issued by a CA that is not in the the trusted-root-certificate-store used for the path validation. The name of the CA is "{0}". +CertPathReviewer.noTrustAnchorFound.summary = The root certificate of the certificate path was issued by a CA that is not in the the trusted-root-certificate-store used for the path validation. +CertPathReviewer.noTrustAnchorFound.details = The root certificate of the certificate path was issued by a CA that is not in the the trusted-root-certificate-store used for the path validation. The name of the CA is "{0}". The trusted-root-certificate store contains {1} CA(s). + +# conflicting trust anchors +# {0} number of trustanchors found (Integer) +# {1} the ca name +CertPathReviewer.conflictingTrustAnchors.title = Corrupt trust root store +CertPathReviewer.conflictingTrustAnchors.text = Warning: corrupt trust root store: There are {0} trusted public keys for the CA "{1}" - please ensure with CA which is the correct key. +CertPathReviewer.conflictingTrustAnchors.summary = Warning: corrupt trust root store: There are {0} trusted public keys for the CA "{1}" - please ensure with CA which is the correct key. +CertPathReviewer.conflictingTrustAnchors.details = Warning: corrupt trust root store: There are {0} trusted public keys for the CA "{1}" - please ensure with CA which is the correct key. + +# trustanchor DN is invalid +# {0} DN of the Trustanchor +CertPathReviewer.trustDNInvalid.title = DN of TrustAnchor is improperly specified +CertPathReviewer.trustDNInvalid.text = The DN of the TrustAnchor is improperly specified: {0}. +CertPathReviewer.trustDNInvalid.summary = The DN of the TrustAnchor is improperly specified. +CertPathReviewer.trustDNInvalid.details = The DN of the TrustAnchor is improperly specified: {0}. It's not a valid X.500 name. See RFC 1779 or RFC 2253. + +# trustanchor public key algorithm error +CertPathReviewer.trustPubKeyError.title = Error processing public key of the trust anchor +CertPathReviewer.trustPubKeyError.text = Error processing public key of the trust anchor. +CertPathReviewer.trustPubKeyError.summary = Error processing public key of the trust anchor. +CertPathReviewer.trustPubKeyError.details = Error processing public key of the trust anchor. Could not extract the AlorithmIdentifier for the key. + +# can not verifiy signature: issuer public key unknown +CertPathReviewer.NoIssuerPublicKey.title = Can not verify the certificate signature +CertPathReviewer.NoIssuerPublicKey.text = Can not verify the certificate signature: Issuer public key is unknown. +CertPathReviewer.NoIssuerPublicKey.summary = Can not verify the certificate signature: Issuer public key is unknown. +CertPathReviewer.NoIssuerPublicKey.details = Can not verify the certificate signature: Issuer public key is unknown. + +# signature can not be verified +# {0} message of the underlying exception (english) +# {1} the underlying exception +# {2} the name of the exception +CertPathReviewer.signatureNotVerified.title = Certificate signature invalid +CertPathReviewer.signatureNotVerified.text = The certificate signature is invalid. A {2} occurred. +CertPathReviewer.signatureNotVerified.summary = The certificate signature is invalid. +CertPathReviewer.signatureNotVerified.details = The certificate signature is invalid. A {2} occurred. Cause: {0} + +# certificate expired +# {0} the date the certificate expired +CertPathReviewer.certificateExpired.title = Certificate is expired +CertPathReviewer.certificateExpired.text = Could not validate the certificate. Certificate expired on {0,date} {0,time,full}. +CertPathReviewer.certificateExpired.summary = Certificate expired on {0,date} {0,time,full}. +CertPathReviewer.certificateExpired.details = Could not validate the certificate. Certificate expired on {0,date} {0,time,full}. + +# certificate not yet valid +# {0} the date from which on the certificate is valid +CertPathReviewer.certificateNotYetValid.title = Certificate is not yet valid +CertPathReviewer.certificateNotYetValid.text = Could not validate the certificate. Certificate is not valid until {0,date} {0,time,full}. +CertPathReviewer.certificateNotYetValid.summary = Certificate is not valid until {0,date} {0,time,full}. +CertPathReviewer.certificateNotYetValid.details = Could not validate the certificate. Certificate is not valid until {0,date} {0,time,full}. + +# certificate invalid issuer DN +# {0} expected issuer DN as String +# {1} found issuer DN as String +CertPathReviewer.certWrongIssuer.title = Issuer of certificate not valid +CertPathReviewer.certWrongIssuer.text = Issuer of certificate is not valid. Expected {0}, but found {1}. +CertPathReviewer.certWrongIssuer.summary = Issuer of certificate is not valid. +CertPathReviewer.certWrongIssuer.details = Issuer of certificate is not valid. Expected {0}, but found {1}. + +# intermediate certificate is no ca cert +CertPathReviewer.noCACert.title = Certificate is no CA certificate +CertPathReviewer.noCACert.text = Intermediate certificate is no CA certificate. +CertPathReviewer.noCACert.summary = The certificate is no CA certificate. +CertPathReviewer.noCACert.details = The certificate is no CA certificate but used as one. + +# cert laks basic constraints +CertPathReviewer.noBasicConstraints.title = Certificate has no basic constraints +CertPathReviewer.noBasicConstraints.text = Intermediate certificate has no basic constraints. +CertPathReviewer.noBasicConstraints.summary = Intermediate certificate has no basic constraints. +CertPathReviewer.noBasicConstraints.details = Intermediate certificate has no basic constraints. + +# error processing basic constraints +CertPathReviewer.errorProcesingBC.title = Error processing the basic constraints extension +CertPathReviewer.errorProcesingBC.text = There was an error while processing the basic constraints extension of this certificate. +CertPathReviewer.errorProcesingBC.summary = Error processing the basic constraints extension. +CertPathReviewer.errorProcesingBC.details = There was an error while processing the basic constraints extension of this certificate. + +# certificate not usable for signing certs +CertPathReviewer.noCertSign.title = Key not usable for signing certificates +CertPathReviewer.noCertSign.text = The key usage constraint does not allow the use of this certificate key for signing certificates. +CertPathReviewer.noCertSign.summary = The certificate key can not be used for signing certificates. +CertPathReviewer.noCertSign.details = The key usage constraint does not allow the use of this certificate key for signing certificates. + +# error processing public key +CertPathReviewer.pubKeyError.title = Error processing public key +CertPathReviewer.pubKeyError.text = Error processing public key of the certificate. +CertPathReviewer.pubKeyError.summary = Error processing public key of the certificate. +CertPathReviewer.pubKeyError.details = Error processing public key of the certificate. Could not extract the AlorithmIdentifier for the key. + + +## check signatures notifications + +# +# trust anchor has no keyusage certSign +CertPathReviewer.trustKeyUsage.title = Trust anchor key usage +CertPathReviewer.trustKeyUsage.text = The trust anchor is not alloed to sign certificates. +CertPathReviewer.trustKeyUsage.summary = The trust anchor is not alloed to sign certificates. +CertPathReviewer.trustKeyUsage.details = The trust anchor is not alloed to sign certificates. + +# certificate path validation date +# {0} date for which the cert path is validated +# {1} current date +CertPathReviewer.certPathValidDate.title = Certificate path validation date +CertPathReviewer.certPathValidDate.text = The certificate path was applied on {0,date} {0,time,full}. It was checked at {1,date} {1,time,full}. +CertPathReviewer.certPathValidDate.summary = The certificate path was validated for {0,date} {0,time,full}. It was checked at {1,date} {1,time,full}. +CertPathReviewer.certPathValidDate.details = The certificate path was validated for {0,date} {0,time,full}. It was checked at {1,date} {1,time,full}. + + +## check policy errors + +# error processing certificate policy extension +CertPathReviewer.policyExtError.title = Policy checking failed +CertPathReviewer.policyExtError.text = Policy checking failed: there was an error processing the certificate policy extension. +CertPathReviewer.policyExtError.summary = Error processing the certificate policy extension. +CertPathReviewer.policyExtError.details = Policy checking failed: there was an error processing the certificate policy extension. + +# error processing policy constraints extension +CertPathReviewer.policyConstExtError.title = Policy checking failed +CertPathReviewer.policyConstExtError.text = Policy checking failed: there was an error processing the policy constraints extension. +CertPathReviewer.policyConstExtError.summary = Error processing the policy constraints extension. +CertPathReviewer.policyConstExtError.details = Policy checking failed: there was an error processing the policy constraints extension. + +# error processing policy mapping extension +CertPathReviewer.policyMapExtError.title = Policy checking failed +CertPathReviewer.policyMapExtError.text = Policy checking failed: there was an error processing the policy mapping extension. +CertPathReviewer.policyMapExtError.summary = Error processing the policy mapping extension. +CertPathReviewer.policyMapExtError.details = Policy checking failed: there was an error processing the policy mapping extension. + +# error processing inhibit any policy extension +CertPathReviewer.policyInhibitExtError.title = Policy checking failed +CertPathReviewer.policyInhibitExtError.text = Policy checking failed: there was an error processing the inhibit any policy extension. +CertPathReviewer.policyInhibitExtError.summary = Error processing the inhibit any policy extension. +CertPathReviewer.policyInhibitExtError.details = Policy checking failed: there was an error processing the inhibit any policy extension. + +# error building qualifier set +CertPathReviewer.policyQualifierError.title = Policy checking failed +CertPathReviewer.policyQualifierError.text = Policy checking failed: error building the policy qualifier set. +CertPathReviewer.policyQualifierError.summary = Policy checking failed: error building the policy qualifier set. +CertPathReviewer.policyQualifierError.details = Policy checking failed: error building the policy qualifier set. + +# no valid policy tree - explicit policy required +CertPathReviewer.noValidPolicyTree.title = Policy checking failed +CertPathReviewer.noValidPolicyTree.text = Policy checking failed: no valid policy tree found when one expected. +CertPathReviewer.noValidPolicyTree.summary = Policy checking failed: no valid policy tree found when one expected. +CertPathReviewer.noValidPolicyTree.details = Policy checking failed: no valid policy tree found when one expected. + +# expicit policy requested, but no policy available +CertPathReviewer.explicitPolicy.title = Policy checking failed +CertPathReviewer.explicitPolicy.text = Policy checking failed: explicit policy requested but no policy available. +CertPathReviewer.explicitPolicy.summary = Policy checking failed: explicit policy requested but no policy available. +CertPathReviewer.explicitPolicy.details = Policy checking failed: explicit policy requested but no policy available. + +# path processing failed on policy +CertPathReviewer.invalidPolicy.title = Path processing failed on policy +CertPathReviewer.invalidPolicy.text = Path processing failed on policy. +CertPathReviewer.invalidPolicy.summary = Path processing failed on policy. +CertPathReviewer.invalidPolicy.details = Path processing failed on policy. + +# invalid policy mapping +CertPathReviewer.invalidPolicyMapping.title = Invalid policy mapping +CertPathReviewer.invalidPolicyMapping.text = Certificate contains an invalid policy mapping. +CertPathReviewer.invalidPolicyMapping.summary = Certificate contains an invalid policy mapping. +CertPathReviewer.invalidPolicyMapping.details = Certificate contains a policy mapping including the value any policy which is invalid. + +## check CRL notifications + +# found local valid CRL +# {0} thisUpdate of the CRL +# {1} nextUpdate of the CRL +CertPathReviewer.localValidCRL.title = Found valid local CRL +CertPathReviewer.localValidCRL.text = Found a valid CRL in local certstore. Issued on {0,date}, next update {1,date}. +CertPathReviewer.localValidCRL.summary = Found a valid CRL in local certstore. Issued on {0,date}, next update {1,date}. +CertPathReviewer.localValidCRL.details = Found a valid CRL in local certstore. Issued on {0,date}, next update {1,date}. + + +# found matching CRL, but not valid +# {0} thisUpdate of the CRL +# {1} nextUpdate of the CRL +CertPathReviewer.localInvalidCRL.title = Local CRL outdated +CertPathReviewer.localInvalidCRL.text = Did not use a matching CRL in a local certstore, because it is outdated. Issued on {0,date}, next update {1,date}. +CertPathReviewer.localInvalidCRL.summary = Did not use a matching CRL in a local certstore, because it is outdated. Issued on {0,date}, next update {1,date}. +CertPathReviewer.localInvalidCRL.details = Did not use a matching CRL in a local certstore, because it is outdated. Issued on {0,date}, next update {1,date}. + +# found a valid crl at crl distribution point +# {0} thisUpdate of the CRL +# {1} nextUpdate of the CRL +# {2} the url of the distribution point +CertPathReviewer.onlineValidCRL.title = Found valid CRL at CRL distribution point +CertPathReviewer.onlineValidCRL.text = Found a valid CRL at: {2}. Issued on {0,date}, next update on {1,date}. +CertPathReviewer.onlineValidCRL.summary = Found a valid CRL at: {2}. Issued on {0,date}, next update on {1,date}. +CertPathReviewer.onlineValidCRL.details = Found a valid CRL at: {2}. Issued on {0,date}, next update on {1,date}. + +# found an invalid CRL at crl distribution point +# {0} thisUpdate of the CRL +# {1} nextUpdate of the CRL +# {2} the url of the distribution point +CertPathReviewer.onlineInvalidCRL.title = Outdated CRL at CRL distribution point +CertPathReviewer.onlineInvalidCRL.text = The CRL loaded from {2} was outdated. Issued on {0,date}, next update on {1,date}. +CertPathReviewer.onlineInvalidCRL.summary = The CRL loaded from {2} was outdated. Issued on {0,date}, next update on {1,date}. +CertPathReviewer.onlineInvalidCRL.details = The CRL loaded from {2} was outdated. Issued on {0,date}, next update on {1,date}. + +#found a CRL at a crl distribution point, but issued by another CA +# {0} issuer of the CRL +# {1} expected issuer +# {2} the url of the distribution point +CertPathReviewer.onlineCRLWrongCA.title = CRL from wrong issuer at CRL distribution point +CertPathReviewer.onlineCRLWrongCA.text = The CRL loaded from {2} has was issued by {0}, excpected {1}. +CertPathReviewer.onlineCRLWrongCA.summary = The CRL loaded from {2} has a wrong issuer. +CertPathReviewer.onlineCRLWrongCA.details = The CRL loaded from {2} has was issued by {0}, excpected {1}. + +# Certificate not revoked +CertPathReviewer.notRevoked.title = Certificate not revoked +CertPathReviewer.notRevoked.text = The certificate was not revoked. +CertPathReviewer.notRevoked.summary = The certificate was not revoked. +CertPathReviewer.notRevoked.details = The certificate was not revoked. + +# CRL found: certificate was revoked, but after the validationDate +# {0} the date the certificate was revoked +# {1} the reason for revoking the certificate +CertPathReviewer.revokedAfterValidation.title = Certificate was revoked after the validation date +CertPathReviewer.revokedAfterValidation.text = The certificate was revoked after the validation date at {0,date} {0,time,full}. Reason: {1}. +CertPathReviewer.revokedAfterValidation.summary = The certificate was revoked after the validation date at {0,date} {0,time,full}. +CertPathReviewer.revokedAfterValidation.details = The certificate was revoked after the validation date at {0,date} {0,time,full}. Reason: {1}. + +# updated crl available +# {0} date since when the update is available +CertPathReviewer.crlUpdateAvailable.title = CRL update available +CertPathReviewer.crlUpdateAvailable.text = An update for the CRL of this certificate is available since {0,date} {0,time,full}. +CertPathReviewer.crlUpdateAvailable.summary = An update for the CRL of this certificate is available since {0,date} {0,time,full}. +CertPathReviewer.crlUpdateAvailable.details = An update for the CRL of this certificate is available since {0,date} {0,time,full}. + +# crl distribution point url +# {0} the crl distribution point url as String +CertPathReviewer.crlDistPoint.title = CRL distribution point +CertPathReviewer.crlDistPoint.text = A CRL can be obtained from: {0}. +CertPathReviewer.crlDistPoint.summary = A CRL can be obtained from: {0}. +CertPathReviewer.crlDistPoint.details = A CRL can be obtained from: {0}. + +# ocsp location +# {0} the url on which the ocsp service can be found +CertPathReviewer.ocspLocation.title = OCSP responder location +CertPathReviewer.ocspLocation.text = OCSP responder location: {0}. +CertPathReviewer.ocspLocation.summary = OCSP responder location: {0}. +CertPathReviewer.ocspLocation.details = OCSP responder location: {0}. + +# unable to get crl from crl distribution point +# {0} the url of the distribution point +# {1} the message of the occurred exception +# {2} the occurred exception +# {3} the name of the exception +CertPathReviewer.loadCrlDistPointError.title = Cannot load CRL from CRL distribution point +CertPathReviewer.loadCrlDistPointError.text = Unable to load a CRL from: {0}. A {3} occurred. +CertPathReviewer.loadCrlDistPointError.summary = Unable to load a CRL from: {0}. A {3} occurred. +CertPathReviewer.loadCrlDistPointError.details = Unable to load a CRL from: {0}. A {3} occurred. Cause: {1}. + +# no crl found in certstores +# {0} the issuers which we searched for +# {1} list of crl issuer names that are found in the certstores +# {2} number of crls in the certstores +CertPathReviewer.noCrlInCertstore.title = No matching CRL found in local CRL store +CertPathReviewer.noCrlInCertstore.text = No matching CRL was found in the provided local CRL store. +CertPathReviewer.noCrlInCertstore.summary = No matching CRL was found in the provided local CRL store. +CertPathReviewer.noCrlInCertstore.details = No matching CRL was found in the provided local CRL store. \ +No CRL was found for the selector "{0}". The {2} CRL(s) in the certstores are from "{1}". + + +## check CRL exceptions + +# cannot extract issuer from certificate +CertPathReviewer.crlIssuerException.title = CRL checking failed +CertPathReviewer.crlIssuerException.text = CRL checking failed: cannot extract issuer from certificate. +CertPathReviewer.crlIssuerException.summary = CRL checking failed: cannot extract issuer from certificate. +CertPathReviewer.crlIssuerException.details = CRL checking failed: cannot extract issuer from certificate. + +# cannot extract crls +# {0} message from the underlying exception +# {1} the underlying exception +# {2} the name of the exception +CertPathReviewer.crlExtractionError.title = CRL checking failed +CertPathReviewer.crlExtractionError.text = CRL checking failed: Cannot extract CRL from CertStore. There was a {2}. +CertPathReviewer.crlExtractionError.summary = CRL checking failed: Cannot extract CRL from CertStore. There was a {2}. +CertPathReviewer.crlExtractionError.details = CRL checking failed: Cannot extract CRL from CertStore. There was a {2}. Cause: {0}. + +# Issuer certificate key usage extension does not permit crl signing +CertPathReviewer.noCrlSigningPermited.title = CRL checking failed +CertPathReviewer.noCrlSigningPermited.text = CRL checking failed: issuer certificate does not permit CRL signing. +CertPathReviewer.noCrlSigningPermited.summary = CRL checking failed: issuer certificate does not permit CRL signing. +CertPathReviewer.noCrlSigningPermited.details = CRL checking failed: issuer certificate does not permit CRL signing. + +# can not verify crl: issuer public key unknown +CertPathReviewer.crlNoIssuerPublicKey.title = CRL checking failed +CertPathReviewer.crlNoIssuerPublicKey.text = CRL checking failed: Can not verify the CRL: Issuer public key is unknown. +CertPathReviewer.crlNoIssuerPublicKey.summary = CRL checking failed: Can not verify the CRL: Issuer public key is unknown. +CertPathReviewer.crlNoIssuerPublicKey.details = CRL checking failed: Can not verify the CRL: Issuer public key is unknown. + +# crl verification failed +CertPathReviewer.crlVerifyFailed.title = CRL checking failed +CertPathReviewer.crlVerifyFailed.text = CRL checking failed: CRL signature is invalid. +CertPathReviewer.crlVerifyFailed.summary = CRL checking failed: CRL signature is invalid. +CertPathReviewer.crlVerifyFailed.details = CRL checking failed: CRL signature is invalid. + +# no valid CRL found +CertPathReviewer.noValidCrlFound.title = CRL checking failed +CertPathReviewer.noValidCrlFound.text = CRL checking failed: no valid CRL found. +CertPathReviewer.noValidCrlFound.summary = CRL checking failed: no valid CRL found. +CertPathReviewer.noValidCrlFound.details = CRL checking failed: no valid CRL found. + +# No base CRL for delta CRL +CertPathReviewer.noBaseCRL.title = CRL checking failed +CertPathReviewer.noBaseCRL.text = CRL checking failed: no base CRL found for delta CRL. +CertPathReviewer.noBaseCRL.summary = CRL checking failed: no base CRL found for delta CRL. +CertPathReviewer.noBaseCRL.details = CRL checking failed: no base CRL found for delta CRL. + +# certificate revoked +# {0} the date the certificate was revoked +# {1} the reason for revoking the certificate +CertPathReviewer.certRevoked.title = Certificate was revoked +CertPathReviewer.certRevoked.text = The certificate was revoked at {0,date} {0,time,full}. Reason: {1}. +CertPathReviewer.certRevoked.summary = The certificate was revoked at {0,date} {0,time,full}. +CertPathReviewer.certRevoked.details = The certificate was revoked at {0,date} {0,time,full}. Reason: {1}. + +# error processing issuing distribution point extension +CertPathReviewer.distrPtExtError.title = CRL checking failed +CertPathReviewer.distrPtExtError.text = CRL checking failed: there was an error processing the issuing distribution point extension. +CertPathReviewer.distrPtExtError.summary = Error processing the issuing distribution point extension. +CertPathReviewer.distrPtExtError.details = CRL checking failed: there was an error processing the issuing distribution point extension. + +# error processing crl distribution points extension +CertPathReviewer.crlDistPtExtError.title = CRL checking failed +CertPathReviewer.crlDistPtExtError.text = CRL checking failed: there was an error processing the crl distribution points extension. +CertPathReviewer.crlDistPtExtError.summary = Error processing the crl distribution points extension. +CertPathReviewer.crlDistPtExtError.details = CRL checking failed: there was an error processing the crl distribution points extension. + +# error processing the authority info access extension +CertPathReviewer.crlAuthInfoAccError.title = CRL checking failed +CertPathReviewer.crlAuthInfoAccError.text = CRL checking failed: there was an error processing the authority info access extension. +CertPathReviewer.crlAuthInfoAccError.summary = Error processing the authority info access extension. +CertPathReviewer.crlAuthInfoAccError.details = CRL checking failed: there was an error processing the authority info access extension. + +# error processing delta crl indicator extension +CertPathReviewer.deltaCrlExtError.title = CRL checking failed +CertPathReviewer.deltaCrlExtError.text = CRL checking failed: there was an error processing the delta CRL indicator extension. +CertPathReviewer.deltaCrlExtError.summary = Error processing the delta CRL indicator extension. +CertPathReviewer.deltaCrlExtError.details = CRL checking failed: there was an error processing the delta CRL indicator extension. + +# error porcessing crl number extension +CertPathReviewer.crlNbrExtError.title = CRL checking failed +CertPathReviewer.crlNbrExtError.text = CRL checking failed: there was an error processing the CRL number extension. +CertPathReviewer.crlNbrExtError.summary = Error processing the CRL number extension. +CertPathReviewer.crlNbrExtError.details = CRL checking failed: there was an error processing the CRL number extension. + +# error processing crl reason code extension +CertPathReviewer.crlReasonExtError.title = CRL checking failed +CertPathReviewer.crlReasonExtError.text = CRL checking failed: there was an error processing the CRL reason code extension. +CertPathReviewer.crlReasonExtError.summary = Error processing the CRL reason code extension. +CertPathReviewer.crlReasonExtError.details = CRL checking failed: there was an error processing the CRL reason code extension. + +# error processing basic constraints extension +CertPathReviewer.crlBCExtError.title = CRL checking failed +CertPathReviewer.crlBCExtError.text = CRL checking failed: there was an error processing the basic constraints extension. +CertPathReviewer.crlBCExtError.summary = Error processing the basic constraints extension. +CertPathReviewer.crlBCExtError.details = CRL checking failed: there was an error processing the basic constraints extension. + +# CA Cert CRL only contains user certificates +CertPathReviewer.crlOnlyUserCert.title = CRL checking failed +CertPathReviewer.crlOnlyUserCert.text = CRL checking failed: CRL only contains user certificates. +CertPathReviewer.crlOnlyUserCert.summary = CRL checking failed: CRL only contains user certificates. +CertPathReviewer.crlOnlyUserCert.details = CRL checking failed: CRL for CA certificate only contains user certificates. + +# End CRL only contains CA certificates +CertPathReviewer.crlOnlyCaCert.title = CRL checking failed +CertPathReviewer.crlOnlyCaCert.text = CRL checking failed: CRL only contains CA certificates. +CertPathReviewer.crlOnlyCaCert.summary = CRL checking failed: CRL only contains CA certificates. +CertPathReviewer.crlOnlyCaCert.details = CRL checking failed: CRL for end certificate only contains CA certificates. + +# onlyContainsAttributeCerts boolean is asserted +CertPathReviewer.crlOnlyAttrCert.title = CRL checking failed +CertPathReviewer.crlOnlyAttrCert.text = CRL checking failed: CRL only contains attribute certificates. +CertPathReviewer.crlOnlyAttrCert.summary = CRL checking failed: CRL only contains attribute certificates. +CertPathReviewer.crlOnlyAttrCert.details = CRL checking failed: CRL only contains attribute certificates. + + +## QcStatement notifications + +# unkown statement +# {0} statement OID +# {1} statement as ANS1Sequence +CertPathReviewer.QcUnknownStatement.title = Unknown statement in QcStatement extension +CertPathReviewer.QcUnknownStatement.text = Unknown statement in QcStatement extension: OID = {0} +CertPathReviewer.QcUnknownStatement.summary = Unknown statement in QcStatement extension: OID = {0} +CertPathReviewer.QcUnknownStatement.details = Unknown statement in QcStatement extension: OID = {0}, statement = {1} + +# QcLimitValue Alpha currency code +# {0} currency code +# {1} limit value +# {2} monetary value as MonetaryValue +CertPathReviewer.QcLimitValueAlpha.title = Transaction Value Limit +CertPathReviewer.QcLimitValueAlpha.text = This certificate has a limit for the transaction value: {1,number, ###,###,###,##0.00#} {0}. +CertPathReviewer.QcLimitValueAlpha.summary = Transaction value limit: {1,number, ###,###,###,##0.00#} {0}. +CertPathReviewer.QcLimitValueAlpha.details = This certificate has a limitation on the value of transaction for which this certificate can be used to the specified amount, according to the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate. The limit for this certificate is {1,number, ###,###,###,##0.00#} {0}. + +# QcLimitValue Numeric currency code +# {0} currency code +# {1} limit value +# {2} monetary value as MonetaryValue +CertPathReviewer.QcLimitValueNum.title = Transaction Value Limit +CertPathReviewer.QcLimitValueNum.text = This certificate has a limit for the transaction value: {1,number, ###,###,###,##0.00#} of currency {0} (See RFC 4217 for currency codes). +CertPathReviewer.QcLimitValueNum.summary = Transaction value limit: {1,number, ###,###,###,##0.00#} of currency {0} (See RFC 4217 for currency codes). +CertPathReviewer.QcLimitValueNum.details = This certificate has a limitation on the value of transaction for which this certificate can be used to the specified amount, according to the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate. The limit for this certificate is {1,number, ###,###,###,##0.00#} of currency {0} (See RFC 4217 for currency codes). + +# QcSSCD +CertPathReviewer.QcSSCD.title = QcSSCD Statement +CertPathReviewer.QcSSCD.text = (SSCD) The issuer claims that for the certificate where this statement appears that the private key associated with the public key in the certificate is protected according to Annex III of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures. +CertPathReviewer.QcSSCD.summary = (SSCD) The issuer claims that for the certificate where this statement appears that the private key associated with the public key in the certificate is protected according to Annex III of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures. +CertPathReviewer.QcSSCD.details = (SSCD) The issuer claims that for the certificate where this statement appears that the private key associated with the public key in the certificate is protected according to Annex III of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures. + +# QcEuCompliance +CertPathReviewer.QcEuCompliance.title = Qualified Certificate +CertPathReviewer.QcEuCompliance.text = This certificate is issued as a Qualified Certificate according Annex I and II of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate. +CertPathReviewer.QcEuCompliance.summary = This certificate is issued as a Qualified Certificate according Annex I and II of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate. +CertPathReviewer.QcEuCompliance.details = This certificate is issued as a Qualified Certificate according Annex I and II of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate. + +## QcStatement errors + +# error processing the QcStatement extension +CertPathReviewer.QcStatementExtError.title = Error processing the qc statements extension +CertPathReviewer.QcStatementExtError.text = Error processing the qc statements extension. +CertPathReviewer.QcStatementExtError.summary = Error processing the qc statements extension. +CertPathReviewer.QcStatementExtError.details = Error processing the qc statements extension. + +## unknown/generic errors +CertPathReviewer.unknown.title = Unexpected Error +CertPathReviewer.unknown.text = Unexpected Error {0} +CertPathReviewer.unknown.summary = Unexpected Error +CertPathReviewer.unknown.details = Unexpected Error {0} + +# +# crl reasons +# +unspecified = Unspecified +keyCompromise = Key Compromise +cACompromise = CA Compromise +affiliationChanged = Affiliation Changed +superseded = Superseded +cessationOfOperation = Cessation of Operation +certificateHold = Certificate Hold +unknown = Unknown +removeFromCRL = Remove from CRL +privilegeWithdrawn = Privilege Withdrawn +aACompromise = AA Compromise + +# +# +# +missingIssuer = The missing certificate was issued by +missingSerial = with the serial number + \ No newline at end of file diff --git a/pkix/src/main/resources/org/bouncycastle/pkix/CertPathReviewerMessages_de.properties b/pkix/src/main/resources/org/bouncycastle/pkix/CertPathReviewerMessages_de.properties new file mode 100644 index 0000000000..8a8d4fa348 --- /dev/null +++ b/pkix/src/main/resources/org/bouncycastle/pkix/CertPathReviewerMessages_de.properties @@ -0,0 +1,621 @@ + +## constructor exceptions + +# cert path is empty +CertPathReviewer.emptyCertPath.title = Zertifizierungspfad ist leer +CertPathReviewer.emptyCertPath.text = PKIXCertPathReviewer: der Zertifizierungspfad ist leer. +CertPathReviewer.emptyCertPath.summary = PKIXCertPathReviewer: der Zertifizierungspfad ist leer. +CertPathReviewer.emptyCertPath.details = PKIXCertPathReviewer: der Zertifizierungspfad ist leer. + +## name constraints processing errors + +# cert DN is not in the permitted tree +# {0} DN as String +CertPathReviewer.notPermittedDN.title = Fehler bei der Namensbeschränkung: Zertifikats DN ist nicht erlaubt +CertPathReviewer.notPermittedDN.text = Fehler bei der Namensbeschränkung: Der Zertifikats DN {0} ist nicht erlaubt. +CertPathReviewer.notPermittedDN.summary = Fehler bei der Namensbeschränkung: Der Zertifikats DN ist nicht erlaubt. +CertPathReviewer.notPermittedDN.details = Fehler bei der Namensbeschränkung: Der Zertifikats DN {0} ist nicht im Set der erlaubten DNs. + +# cert DN is in the excluded tree +# {0} DN as String +CertPathReviewer.excludedDN.title = Fehler bei der Namensbeschränkung: Zertifikats DN ist ausgeschlossen +CertPathReviewer.excludedDN.text = Fehler bei der Namensbeschränkung: Der Zertifikats DN {0} ist ausgeschlossen. +CertPathReviewer.excludedDN.summary = Fehler bei der Namensbeschränkung: Der Zertifikats DN ist ausgeschlossen +CertPathReviewer.excludedDN.details = Fehler bei der Namensbeschränkung: Der Zertifikats DN ist {0} is innerhalb des Sets von ausgeschlossenen DNs. + +# cert email is not in the permitted tree +# {0} email address as String +CertPathReviewer.notPermittedEmail.title = Fehler bei der Namensbeschränkung: nicht erlaubte Email Addresse +CertPathReviewer.notPermittedEmail.text = Fehler bei der Namensbeschränkung: Das Zertifikat enthält die nicht erlaubte Email Addresse {0}. +CertPathReviewer.notPermittedEmail.summary = Fehler bei der Namensbeschränkung: Die Email Addresse ist nicht erlaubt. +CertPathReviewer.notPermittedEmail.details = Fehler bei der Namensbeschränkung: Das Zertifikat enthält die Email Addresse {0}, welche nicht im Set der erlaubten Email Addressen ist. + +# cert email is in the excluded tree +# {0} email as String +CertPathReviewer.excludedEmail.title = Fehler bei der Namensbeschränkung: Email Addresse ausgeschlossen +CertPathReviewer.excludedEmail.text = Fehler bei der Namensbeschränkung: Die Email Addresse {0} im Zertifikat ist ausgeschlossen. +CertPathReviewer.excludedEmail.summary = Fehler bei der Namensbeschränkung: Die Email Addresse ist ausgeschlossen. +CertPathReviewer.excludedEmail.details = Fehler bei der Namensbeschränkung: Das Zertifikat enthält die Email Addresse {0}, welche im Set der ausgeschlossenen Email Addressen ist. + +# cert IP is not in the permitted tree +# {0} ip address as String +CertPathReviewer.notPermittedIP.title = Fehler bei der Namensbeschränkung: nicht erlaubte IP Addresse +CertPathReviewer.notPermittedIP.text = Fehler bei der Namensbeschränkung: Das Zertifikat enthält die nicht erlaubte IP Addresse {0}. +CertPathReviewer.notPermittedIP.summary = Fehler bei der Namensbeschränkung: Die IP Addresse ist nicht erlaubt. +CertPathReviewer.notPermittedIP.details = Fehler bei der Namensbeschränkung: Das Zertifikat enthält die IP Addresse {0}, welche nicht im Set der erlaubten IP Addressen ist. + +# cert ip is in the excluded tree +# {0} ip address as String +CertPathReviewer.excludedIP.title = Fehler bei der Namensbeschränkung: Ausgeschlossene IP Addresse +CertPathReviewer.excludedIP.text = Fehler bei der Namensbeschränkung: Das Zertifikat enhält die ausgeschlossene IP Addresse {0}. +CertPathReviewer.excludedIP.summary = Fehler bei der Namensbeschränkung: Die IP Addresse im Zertifikat ist ausgeschlossen. +CertPathReviewer.excludedIP.details = Fehler bei der Namensbeschränkung: Das Zertifikat enthält die IP Addresse {0}, welche im Set der ausgeschlossenen IP Addressen ist. + +# error processing the name constraints extension +CertPathReviewer.ncExtError.title = Prüfen der Namensbeschränkungen fehlgeschlagen +CertPathReviewer.ncExtError.text = Prüfen der Namensbeschränkungen fehlgeschlagen: Es gab Fehler bei der Verarbeitung der Name Constraints Erweiterung des Zertifikats. +CertPathReviewer.ncExtError.summary = Prüfen der Namensbeschränkungen fehlgeschlagen: Fehler bei der Verarbeitung der Name Constraints Erweiterung. +CertPathReviewer.ncExtError.details = Prüfen der Namensbeschränkungen fehlgeschlagen: Es gab Fehler bei der Verarbeitung der Name Constraints Erweiterung des Zertifikats. + +# error processing the subject alternative name extension +CertPathReviewer.subjAltNameExtError.title = Prüfen der Namensbeschränkungen fehlgeschlagen +CertPathReviewer.subjAltNameExtError.text = Prüfen der Namensbeschränkungen fehlgeschlagen: Es gab Fehler bei der Verarbeitung der Subject Alternative Name Erweiterung des Zertifikats. +CertPathReviewer.subjAltNameExtError.summary = Prüfen der Namensbeschränkungen fehlgeschlagen: Fehler bei der Verarbeitung der Subject Alternative Name Erweiterung. +CertPathReviewer.subjAltNameExtError.details = Prüfen der Namensbeschränkungen fehlgeschlagen: Es gab Fehler bei der Verarbeitung der Subject Alternative Name Erweiterung des Zertifikats. + +# exception extracting subject name when checking subtrees +# {0} subject Principal +CertPathReviewer.ncSubjectNameError.title = Prüfen der Namensbeschränkungen fehlgeschlagen +CertPathReviewer.ncSubjectNameError.text = Prüfen der Namensbeschränkungen fehlgeschlagen: Es gab einen Fehler beim auslesen des DN des Zertifikats. +CertPathReviewer.ncSubjectNameError.summary = Prüfen der Namensbeschränkungen fehlgeschlagen: Fehler beim auslesen des DNs. +CertPathReviewer.ncSubjectNameError.details = Prüfen der Namensbeschränkungen fehlgeschlagen: Es gab einen Fehler beim auslesen des DN des Zertifikats. + + +## path length errors + +# max path length extended +CertPathReviewer.pathLengthExtended.title = Maximale Pfadlänge überschritten +CertPathReviewer.pathLengthExtended.text = Zertifizierungspfad ungültig: die Maximale Pfadlänge ist überschritten. +CertPathReviewer.pathLengthExtended.summary = Zertifizierungspfad ungültig: die Maximale Pfadlänge ist überschritten. +CertPathReviewer.pathLengthExtended.details = Zertifizierungspfad ungültig: die Maximale Pfadlänge ist überschritten. + +# error reading length constraint from basic constraint extension +CertPathReviewer.processLengthConstError.title = Prüfen der Pfadlänge fehlgeschlagen +CertPathReviewer.processLengthConstError.text = Prüfen der Pfadlänge fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der subject alternative name Erweiterung des Zertifikats. +CertPathReviewer.processLengthConstError.summary = Fehler bei der Verarbeitung der subject alternative name Erweiterung. +CertPathReviewer.processLengthConstError.details = Prüfen der Pfadlänge fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der subject alternative name Erweiterung des Zertifikats. + + +## path length notifications + +# total path length as defined in rfc 3280 +# {0} the path length as Integer +CertPathReviewer.totalPathLength.title = Totale Pfadlänge +CertPathReviewer.totalPathLength.text = Die totale Pfadlänge ohne self-signed Zertifikate ist {0}. +CertPathReviewer.totalPathLength.summary = Die totale Pfadlänge ohne self-signed Zertifikate ist {0}. +CertPathReviewer.totalPathLength.details = Die totale Pfadlänge ohne self-signed Zertifikate, wie beschrieben in RFC 3280, ist {0}. + + +## critical extensions errors + +# one unknown critical extension +# {0} extension as String +CertPathReviewer.unknownCriticalExt.title = Unbekannte kritische Erweiterung +CertPathReviewer.unknownCriticalExt.text = Das Zertifikat enhält eine unbekannte kritische Erweiterung mit der OID {0}. +CertPathReviewer.unknownCriticalExt.summary = Unbekannte kritische Erweiterung: {0}. +CertPathReviewer.unknownCriticalExt.details = Das Zertifikat enhält eine unbekannte kritische Erweiterung mit der OID {0}. + +# more unknown critical extensions +# {0} extensions as Set of Strings +CertPathReviewer.unknownCriticalExts.title = Unbekannte kritische Erweiterung +CertPathReviewer.unknownCriticalExts.text = Das Zertifikat enhält zwei oder mehr unbekannte kritische Erweiterungen mit den OIDs {0}. +CertPathReviewer.unknownCriticalExts.summary = Unbekannte kritische Erweiterungen: {0}. +CertPathReviewer.unknownCriticalExts.details = Das Zertifikat enhält zwei oder mehr unbekannte kritische Erweiterungen mit den OIDs {0}. + +# error processing critical extension +# {0} the message of the underlying exception +# {1} the underlying exception +# {2} the name of the exception +CertPathReviewer.criticalExtensionError.title = Fehler bei der Verarbeitung einer kritischen Erweiterung +CertPathReviewer.criticalExtensionError.text = Fehler bei der Verarbeitung einer kritischen Erweiterung. Es gab eine {2}. +CertPathReviewer.criticalExtensionError.summary = Fehler bei der Verarbeitung einer kritischen Erweiterung. Es gab eine {2}. +CertPathReviewer.criticalExtensionError.details = Fehler bei der Verarbeitung einer kritischen Erweiterung. Es gab eine {2}. Grund: {0}. + +# error initializing the certpath checkers +# {0} the message of the underlying exception +# {1} the underlying exception +# {2} the name of the exception +CertPathReviewer.certPathCheckerError.title = Prüfen der kritischen Erweiterungen fehlgeschlagen +CertPathReviewer.certPathCheckerError.text = Prüfen der kritischen Erweiterungen fehlgeschlagen: Es gab eine {2} bei der Initialisierung eines CertPathChecker. +CertPathReviewer.certPathCheckerError.summary = Prüfen der kritischen Erweiterungen fehlgeschlagen: {2} bei der Initialisierung eines CertPathChecker. +CertPathReviewer.certPathCheckerError.details = Prüfen der kritischen Erweiterungen fehlgeschlagen: Es gab eine {2} bei der Initialisierung eines CertPathChecker. Grund: {0} + + +## check signature errors + +CertPathReviewer.rootKeyIsValidButNotATrustAnchor.title = rootKeyIsValidButNotATrustAnchor +CertPathReviewer.rootKeyIsValidButNotATrustAnchor.text = Das Zertifikat hat eine gültige Signatur, ist aber kein vertrauenswürdiges Root Zertifikat. +CertPathReviewer.rootKeyIsValidButNotATrustAnchor.summary = Das Zertifikat hat eine gültige Signatur, ist aber kein vertrauenswürdiges Root Zertifikat. +CertPathReviewer.rootKeyIsValidButNotATrustAnchor.details = Das Zertifikat hat eine gültige Signatur, ist aber kein vertrauenswürdiges Root Zertifikat. + +# trustanchor found, but certificate validation failed +CertPathReviewer.trustButInvalidCert.title = Vertrauenswürdiges Root Zertifikat invalid +CertPathReviewer.trustButInvalidCert.text = Ein Root Zertifikat wurde gefunden. Es hat aber einen anderen öffentlichen Schlüssel als verwendet wurde um das erste Zertifikat des Zertifizierungspfades zu signieren. +CertPathReviewer.trustButInvalidCert.summary = Ein Root Zertifikat wurde gefunden. Es hat aber einen anderen öffentlichen Schlüssel als verwendet wurde um das erste Zertifikat des Zertifizierungspfades zu signieren. +CertPathReviewer.trustButInvalidCert.details = Ein Root Zertifikat wurde gefunden. Es hat aber einen anderen öffentlichen Schlüssel als verwendet wurde um das erste Zertifikat des Zertifizierungspfades zu signieren. + +# trustanchor - cannot extract issuer +CertPathReviewer.trustAnchorIssuerError.title = Kann kein vertrauenswürdiges Root Zertifikat finden +CertPathReviewer.trustAnchorIssuerError.text = Kann kein vertrauenswürdiges Root Zertifikat finden: Der Herausgeber vom Zertifikat kann nicht auslesen werden. +CertPathReviewer.trustAnchorIssuerError.summary = Kann kein vertrauenswürdiges Root Zertifikat finden: Der Herausgeber vom Zertifikat kann nicht auslesen werden. +CertPathReviewer.trustAnchorIssuerError.details = Kann kein vertrauenswürdiges Root Zertifikat finden: Der Herausgeber vom Zertifikat kann nicht auslesen werden. + +# no trustanchor was found for the certificate path +# {0} issuer of the root certificate of the path +# {1} number of trusted root certificates (trustanchors) provided +CertPathReviewer.noTrustAnchorFound.title = Kein vertrauenswürdiges Root Zertifikat gefunden +CertPathReviewer.noTrustAnchorFound.text = Das Root Zertifikat der Zertifizierungspfads wurde nicht von einer vertrauenswürdigen CA ausgestellt. Der Name der CA ist "{0}". +CertPathReviewer.noTrustAnchorFound.summary = Das Root Zertifikat der Zertifizierungspfads wurde nicht von einer vertrauenswürdigen CA ausgestellt. +CertPathReviewer.noTrustAnchorFound.details = Das Root Zertifikat der Zertifizierungspfads wurde nicht von einer vertrauenswürdigen CA ausgestellt. Der Name der CA ist "{0}". Der Root-Zertifikat-Speicher enthält {1} CA(s). + +# conflicting trust anchors +# {0} number of trustanchors found (Integer) +# {1} the ca name +CertPathReviewer.conflictingTrustAnchors.title = Korrupter Root-Zertifikat-Speicher +CertPathReviewer.conflictingTrustAnchors.text = Warnung: Es sind {0} öffentliche Schlüssel für die CA "{1}" im Root-Zertifikat-Speicher vorhanden - bitte prüfen Sie mit der CA welches der richtige Schlüssel ist. +CertPathReviewer.conflictingTrustAnchors.summary = Warnung: Es sind {0} öffentliche Schlüssel für die CA "{1}" im Root-Zertifikat-Speicher vorhanden - bitte prüfen Sie mit der CA welches der richtige Schlüssel ist. +CertPathReviewer.conflictingTrustAnchors.details = Warnung: Es sind {0} öffentliche Schlüssel für die CA "{1}" im Root-Zertifikat-Speicher vorhanden - bitte prüfen Sie mit der CA welches der richtige Schlüssel ist. + +# trustanchor DN is invalid +# {0} DN of the Trustanchor +CertPathReviewer.trustDNInvalid.title = DN des vertrauenswürdigen Root Zertifikats mit falschem Format. +CertPathReviewer.trustDNInvalid.text = Der DN des vertrauenswürdigen Root Zertifikats hat ein falsches Format: {0}. +CertPathReviewer.trustDNInvalid.summary = Der DN des vertrauenswürdigen Root Zertifikats hat ein falsches Format: {0}. +CertPathReviewer.trustDNInvalid.details = Der DN des vertrauenswürdigen Root Zertifikats hat ein falsches Format: {0}. Es ist kein gültiger X.500 Name. Siehe RFC 1779 oder RFC 2253. + +# trustanchor public key algorithm error +CertPathReviewer.trustPubKeyError.title = Fehler bei der Verarbeitung des öffentlichen Schlüssels der vertrauenswürdigen Root Zertifikats +CertPathReviewer.trustPubKeyError.text = Fehler bei der Verarbeitung des öffentlichen Schlüssels der vertrauenswürdigen Root Zertifikats. +CertPathReviewer.trustPubKeyError.summary = Fehler bei der Verarbeitung des öffentlichen Schlüssels der vertrauenswürdigen Root Zertifikats. +CertPathReviewer.trustPubKeyError.details = Fehler bei der Verarbeitung des öffentlichen Schlüssels der vertrauenswürdigen Root Zertifikats. Der AlorithmIdentifier vom Schlüssel kann nicht ausgelesen werden. + +# can not verifiy signature: issuer public key unknown +CertPathReviewer.NoIssuerPublicKey.title = Zertifikats Signatur kann nicht geprüft werden +CertPathReviewer.NoIssuerPublicKey.text = Die Zertifikats Signatur kann nicht geprüft werden: Der öffentliche Schlüssel des Herausgebers ist unbekannt. +CertPathReviewer.NoIssuerPublicKey.summary = Die Zertifikats Signatur kann nicht geprüft werden: Der öffentliche Schlüssel des Herausgebers ist unbekannt. +CertPathReviewer.NoIssuerPublicKey.details = Die Zertifikats Signatur kann nicht geprüft werden: Der öffentliche Schlüssel des Herausgebers ist unbekannt. + +# signature can not be verified +# {0} message of the underlying exception (english) +# {1} the underlying exception +# {2} the name of the exception +CertPathReviewer.signatureNotVerified.title = Zertifikats Signatur ist ungültig +CertPathReviewer.signatureNotVerified.text = Die Zertifikats Signatur ist ungültig. Es gab eine {2}. +CertPathReviewer.signatureNotVerified.summary = Die Zertifikats Signatur ist ungültig. +CertPathReviewer.signatureNotVerified.details = Die Zertifikats Signatur ist ungültig. Es gab eine {2}. Grund: {0} + +# certificate expired +# {0} the date the certificate expired +CertPathReviewer.certificateExpired.title = Zertifikat ist abgelaufen +CertPathReviewer.certificateExpired.text = Das Zertifikat ist ungültig. Es ist am {0,date} {0,time,full} abgelaufen. +CertPathReviewer.certificateExpired.summary = Das Zertifikat ist abgelaufen am {0,date} {0,time,full}. +CertPathReviewer.certificateExpired.details = Das Zertifikat ist ungültig. Es ist am {0,date} {0,time,full} abgelaufen. + +# certificate not yet valid +# {0} the date from which on the certificate is valid +CertPathReviewer.certificateNotYetValid.title = Das Zertifikat ist noch nicht gültig +CertPathReviewer.certificateNotYetValid.text = Das Zertifikat ist ungültig. Es ist erst gültig ab {0,date} {0,time,full}. +CertPathReviewer.certificateNotYetValid.summary = Das Zertifikat ist nicht gültig bis {0,date} {0,time,full}. +CertPathReviewer.certificateNotYetValid.details = Das Zertifikat ist ungültig. Es ist erst gültig ab {0,date} {0,time,full}. + +# certificate invalid issuer DN +# {0} expected issuer DN as String +# {1} found issuer DN as String +CertPathReviewer.certWrongIssuer.title = Falscher Herausgeber +CertPathReviewer.certWrongIssuer.text = Das Herausgeber des Zertifikats ist ungültig. Erwartet {0}, gefunden {1}. +CertPathReviewer.certWrongIssuer.summary = Das Herausgeber des Zertifikats ist ungültig. +CertPathReviewer.certWrongIssuer.details = Das Herausgeber des Zertifikats ist ungültig. Erwartet {0}, gefunden {1}. + +# intermediate certificate is no ca cert +CertPathReviewer.noCACert.title = Zertifikat ist kein CA Zertifikat +CertPathReviewer.noCACert.text = Das Zertifikat ist kein CA Zertifikat. +CertPathReviewer.noCACert.summary = Das Zertifikat ist kein CA Zertifikat. +CertPathReviewer.noCACert.details = Das Zertifikat ist kein CA Zertifikat, wird aber wie eines gebraucht. + +# cert laks basic constraints +CertPathReviewer.noBasicConstraints.title = Zertifikat hat keine Basiseinschränkungen +CertPathReviewer.noBasicConstraints.text = Das Zertifikat hat keine Basiseinschränkungen. +CertPathReviewer.noBasicConstraints.summary = Das Zertifikat hat keine Basiseinschränkungen. +CertPathReviewer.noBasicConstraints.details = Das Zertifikat hat keine Basiseinschränkungen. + +# error processing basic constraints +CertPathReviewer.errorProcesingBC.title = Fehler bei der Verarbeitung der Basiseinschränkungen +CertPathReviewer.errorProcesingBC.text = Es gab einen Fehler bei der Verarbeitung der Basiseinschränkungen des Zertifikats. +CertPathReviewer.errorProcesingBC.summary = Fehler bei der Verarbeitung der Basiseinschränkungen +CertPathReviewer.errorProcesingBC.details = Es gab einen Fehler bei der Verarbeitung der Basiseinschränkungen des Zertifikats. + +# certificate not usable for signing certs +CertPathReviewer.noCertSign.title = Schlüssel nicht nutzbar für Zertifikatssignaturen +CertPathReviewer.noCertSign.text = Der Schlüssel kann nicht zum Signieren von Zertifikaten verwendet werden. +CertPathReviewer.noCertSign.summary = Der Schlüssel kann nicht zum Signieren von Zertifikaten verwendet werden. +CertPathReviewer.noCertSign.details = Der Schlüssel kann nicht zum Signieren von Zertifikaten verwendet werden. + +# error processing public key +CertPathReviewer.pubKeyError.title = Fehler bei der Verarbeitung des öffentlichen Schlüssels +CertPathReviewer.pubKeyError.text = Fehler bei der Verarbeitung des öffentlichen Schlüssels des Zertifikats. +CertPathReviewer.pubKeyError.summary = Fehler bei der Verarbeitung des öffentlichen Schlüssels des Zertifikats. +CertPathReviewer.pubKeyError.details = Fehler bei der Verarbeitung des öffentlichen Schlüssels des Zertifikats. Der AlorithmIdentifier konnte nicht extrahiert werden. + + +## check signatures notifications + +# +# trust anchor has no keyusage certSign +CertPathReviewer.trustKeyUsage.title = Root-Zertifikat Schlüsselverwendung +CertPathReviewer.trustKeyUsage.text = Das Root-Zertifikat darf nicht zum Signieren von Zertifikaten verwendet werden. +CertPathReviewer.trustKeyUsage.summary = Das Root-Zertifikat darf nicht zum Signieren von Zertifikaten verwendet werden. +CertPathReviewer.trustKeyUsage.details = Das Root-Zertifikat darf nicht zum Signieren von Zertifikaten verwendet werden. + +# certificate path validation date +# {0} date for which the cert path is validated +# {1} current date +CertPathReviewer.certPathValidDate.title = Datum der Zertifikatspfad Validierung +CertPathReviewer.certPathValidDate.text = Der Zertifikatspfad wurde am {0,date} {0,time,full} angewendet. Er wurde am {1,date} {1,time,full} geprüft. +CertPathReviewer.certPathValidDate.summary = Der Zertifikatspfad wurde am {0,date} {0,time,full} angewendet. Er wurde am {1,date} {1,time,full} geprüft. +CertPathReviewer.certPathValidDate.details = Der Zertifikatspfad wurde am {0,date} {0,time,full} angewendet. Er wurde am {1,date} {1,time,full} geprüft. + + +## check policy errors + +# error processing certificate policy extension +CertPathReviewer.policyExtError.title = Prüfen der Policy fehlgeschlagen +CertPathReviewer.policyExtError.text = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Policy Erweiterung. +CertPathReviewer.policyExtError.summary = Fehler bei der Verarbeitung der Policy Erweiterung. +CertPathReviewer.policyExtError.details = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Policy Erweiterung. + +# error processing policy constraints extension +CertPathReviewer.policyConstExtError.title = Prüfen der Policy fehlgeschlagen +CertPathReviewer.policyConstExtError.text = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Policy Constraints Erweiterung. +CertPathReviewer.policyConstExtError.summary = Fehler bei der Verarbeitung der Policy Constraints Erweiterung. +CertPathReviewer.policyConstExtError.details = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Policy Constraints Erweiterung. + +# error processing policy mapping extension +CertPathReviewer.policyMapExtError.title = Prüfen der Policy fehlgeschlagen +CertPathReviewer.policyMapExtError.text = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Policy Mapping Erweiterung. +CertPathReviewer.policyMapExtError.summary = Fehler bei der Verarbeitung der Policy Mapping Erweiterung. +CertPathReviewer.policyMapExtError.details = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Policy Mapping Erweiterung. + +# error processing inhibit any policy extension +CertPathReviewer.policyInhibitExtError.title = Prüfen der Policy fehlgeschlagen +CertPathReviewer.policyInhibitExtError.text = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Inhibit Any Policy Erweiterung. +CertPathReviewer.policyInhibitExtError.summary = Fehler bei der Verarbeitung der Inhibit Any Policy Erweiterung. +CertPathReviewer.policyInhibitExtError.details = Prüfen der Policy fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Inhibit Any Policy Erweiterung. + +# error building qualifier set +CertPathReviewer.policyQualifierError.title = Prüfen der Policy fehlgeschlagen +CertPathReviewer.policyQualifierError.text = Prüfen der Policy fehlgeschlagen: Fehler beim erstellen des Policy Qualifier Set. +CertPathReviewer.policyQualifierError.summary = Prüfen der Policy fehlgeschlagen: Fehler beim erstellen des Policy Qualifier Set. +CertPathReviewer.policyQualifierError.details = Prüfen der Policy fehlgeschlagen: Fehler beim erstellen des Policy Qualifier Set. + +# no valid policy tree - explicit policy required +CertPathReviewer.noValidPolicyTree.title = Prüfen der Policy fehlgeschlagen +CertPathReviewer.noValidPolicyTree.text = Prüfen der Policy fehlgeschlagen: Kein gültiger Policy Baum gefunden, als einer erwartet wurde. +CertPathReviewer.noValidPolicyTree.summary = Prüfen der Policy fehlgeschlagen: Kein gültiger Policy Baum gefunden, als einer erwartet wurde. +CertPathReviewer.noValidPolicyTree.details = Prüfen der Policy fehlgeschlagen: Kein gültiger Policy Baum gefunden, als einer erwartet wurde. + +# expicit policy requested, but no policy available +CertPathReviewer.explicitPolicy.title = Prüfen der Policy fehlgeschlagen +CertPathReviewer.explicitPolicy.text = Prüfen der Policy fehlgeschlagen: Policy verlang, aber keine Policy vorhanden. +CertPathReviewer.explicitPolicy.summary = Prüfen der Policy fehlgeschlagen: Policy verlang, aber keine Policy vorhanden. +CertPathReviewer.explicitPolicy.details = Prüfen der Policy fehlgeschlagen: Policy verlang, aber keine Policy vorhanden. + +# path processing failed on policy +CertPathReviewer.invalidPolicy.title = Pfad Validierung wegen der Policy fehlgeschlagen +CertPathReviewer.invalidPolicy.text = Pfad Validierung wegen der Policy fehlgeschlagen. +CertPathReviewer.invalidPolicy.summary = Pfad Validierung wegen der Policy fehlgeschlagen. +CertPathReviewer.invalidPolicy.details = Pfad Validierung wegen der Policy fehlgeschlagen. + +# invalid policy mapping +CertPathReviewer.invalidPolicyMapping.title = Ungültiges Policy Mapping +CertPathReviewer.invalidPolicyMapping.text = Das Zertifikat enthält ein Ungültiges Policy Mapping. +CertPathReviewer.invalidPolicyMapping.summary = Das Zertifikat enthält ein Ungültiges Policy Mapping. +CertPathReviewer.invalidPolicyMapping.details = Das Zertifikat enthält ein Ungültiges Policy Mapping, das den Wert Any Policy enthält. + +## check CRL notifications + +# found local valid CRL +# {0} thisUpdate of the CRL +# {1} nextUpdate of the CRL +CertPathReviewer.localValidCRL.title = Gültige Zertifikatssperrliste (CRL) gefunden +CertPathReviewer.localValidCRL.text = Gültige Zertifikatssperrliste (CRL) im lokalen Speicher gefunden. Herausgegeben am {0,date}, nächstes Update am {1,date}. +CertPathReviewer.localValidCRL.summary = Gültige Zertifikatssperrliste (CRL) im lokalen Speicher gefunden. Herausgegeben am {0,date}, nächstes Update am {1,date}. +CertPathReviewer.localValidCRL.details = Gültige Zertifikatssperrliste (CRL) im lokalen Speicher gefunden. Herausgegeben am {0,date}, nächstes Update am {1,date}. + + +# found matching CRL, but not valid +# {0} thisUpdate of the CRL +# {1} nextUpdate of the CRL +CertPathReviewer.localInvalidCRL.title = Lokale Zertifikatssperrliste (CRL) veraltet +CertPathReviewer.localInvalidCRL.text = Eine lokale Zertifikatssperrliste (CRL) wurde nicht genutzt, da sie veraltet ist. Herausgegeben am {0,date}, nächstes Update am {1,date}. +CertPathReviewer.localInvalidCRL.summary = Eine lokale Zertifikatssperrliste (CRL) wurde nicht genutzt, da sie veraltet ist. Herausgegeben am {0,date}, nächstes Update am {1,date}. +CertPathReviewer.localInvalidCRL.details = Eine lokale Zertifikatssperrliste (CRL) wurde nicht genutzt, da sie veraltet ist. Herausgegeben am {0,date}, nächstes Update am {1,date}. + +# found a valid crl at crl distribution point +# {0} thisUpdate of the CRL +# {1} nextUpdate of the CRL +# {2} the url of the distribution point +CertPathReviewer.onlineValidCRL.title = Gültige Zertifikatssperrliste (CRL) von einem CDP +CertPathReviewer.onlineValidCRL.text = Gültige Zertifikatssperrliste (CRL) gefunden von: {2}. Herausgegeben am {0,date}, nächstes Update am {1,date}. +CertPathReviewer.onlineValidCRL.summary = Gültige Zertifikatssperrliste (CRL) gefunden von: {2}. Herausgegeben am {0,date}, nächstes Update am {1,date}. +CertPathReviewer.onlineValidCRL.details = Gültige Zertifikatssperrliste (CRL) gefunden von: {2}. Herausgegeben am {0,date}, nächstes Update am {1,date}. + +# found an invalid CRL at crl distribution point +# {0} thisUpdate of the CRL +# {1} nextUpdate of the CRL +# {2} the url of the distribution point +CertPathReviewer.onlineInvalidCRL.title = Veraltete Zertifikatssperrliste (CRL) von einem CDP +CertPathReviewer.onlineInvalidCRL.text = Die Zertifikatssperrliste (CRL) von {2} ist veraltet. Herausgegeben am {0,date}, nächstes Update am {1,date}. +CertPathReviewer.onlineInvalidCRL.summary = Die Zertifikatssperrliste (CRL) von {2} ist veraltet. Herausgegeben am {0,date}, nächstes Update am {1,date}. +CertPathReviewer.onlineInvalidCRL.details = Die Zertifikatssperrliste (CRL) von {2} ist veraltet. Herausgegeben am {0,date}, nächstes Update am {1,date}. + +#found a CRL at a crl distribution point, but issued by another CA +# {0} issuer of the CRL +# {1} expected issuer +# {2} the url of the distribution point +CertPathReviewer.onlineCRLWrongCA.title = Zertifikatssperrliste (CRL) von CDP mit falschem Herausgeber +CertPathReviewer.onlineCRLWrongCA.text = Die Zertifikatssperrliste (CRL) von {2} wurde von {0} herausgegeben, erwartet wurde {1}. +CertPathReviewer.onlineCRLWrongCA.summary = Die Zertifikatssperrliste (CRL) von {2} hat einen falschen Herausgeber. +CertPathReviewer.onlineCRLWrongCA.details = Die Zertifikatssperrliste (CRL) von {2} wurde von {0} herausgegeben, erwartet wurde {1}. + +# Certificate not revoked +CertPathReviewer.notRevoked.title = Zertifikat nicht revoziert +CertPathReviewer.notRevoked.text = Das Zertifikat ist nicht revoziert. +CertPathReviewer.notRevoked.summary = Das Zertifikat ist nicht revoziert. +CertPathReviewer.notRevoked.details = Das Zertifikat ist nicht revoziert. + +# CRL found: certificate was revoked, but after the validationDate +# {0} the date the certificate was revoked +# {1} the reason for revoking the certificate +CertPathReviewer.revokedAfterValidation.title = Zertifikat revoziert nach dem Validierungdatum +CertPathReviewer.revokedAfterValidation.text = Das Zertifikat wurde nach dem Validierungdatum am {0,date} {0,time,full} revoziert. Grund: {1}. +CertPathReviewer.revokedAfterValidation.summary = Das Zertifikat wurde nach dem Validierungdatum am {0,date} {0,time,full} revoziert. +CertPathReviewer.revokedAfterValidation.details = Das Zertifikat wurde nach dem Validierungdatum am {0,date} {0,time,full} revoziert. Grund: {1}. + +# updated crl available +# {0} date since when the update is available +CertPathReviewer.crlUpdateAvailable.title = Zertifikatssperrlisten (CRL) Update erhältlich +CertPathReviewer.crlUpdateAvailable.text = Ein Update für die Zertifikatssperrliste (CRL) für dieses Zertifikat ist erhältlich seit {0,date} {0,time,full}. +CertPathReviewer.crlUpdateAvailable.summary = Ein Update für die Zertifikatssperrliste (CRL) für dieses Zertifikat ist erhältlich seit {0,date} {0,time,full}. +CertPathReviewer.crlUpdateAvailable.details = Ein Update für die Zertifikatssperrliste (CRL) für dieses Zertifikat ist erhältlich seit {0,date} {0,time,full}. + +# crl distribution point url +# {0} the crl distribution point url as String +CertPathReviewer.crlDistPoint.title = CDP +CertPathReviewer.crlDistPoint.text = Eine Zertifikatssperrliste (CRL) kann von {0} geladen werden. +CertPathReviewer.crlDistPoint.summary = Eine Zertifikatssperrliste (CRL) kann von {0} geladen werden. +CertPathReviewer.crlDistPoint.details = Eine Zertifikatssperrliste (CRL) kann von {0} geladen werden. + +# ocsp location +# {0} the url on which the ocsp service can be found +CertPathReviewer.ocspLocation.title = OCSP Server +CertPathReviewer.ocspLocation.text = OCSP Server: {0}. +CertPathReviewer.ocspLocation.summary = OCSP Server: {0}. +CertPathReviewer.ocspLocation.details = OCSP Server: {0}. + +# unable to get crl from crl distribution point +# {0} the url of the distribution point +# {1} the message of the occurred exception +# {2} the occurred exception +# {3} the name of the exception +CertPathReviewer.loadCrlDistPointError.title = Kann Zertifikatssperrliste (CRL) nicht von CDP laden +CertPathReviewer.loadCrlDistPointError.text = Kann die Zertifikatssperrliste (CRL) von {0} nicht laden. Es gab eine {2}. +CertPathReviewer.loadCrlDistPointError.summary = Kann die Zertifikatssperrliste (CRL) von {0} nicht laden. Es gab eine {2}. +CertPathReviewer.loadCrlDistPointError.details = Kann die Zertifikatssperrliste (CRL) von {0} nicht laden. Es gab eine {2}. Grund: {1}. + +# no crl found in certstores +# {0} the issuers which we searched for +# {1} list of crl issuer names that are found in the certstores +# {2} number of crls in the certstores +CertPathReviewer.noCrlInCertstore.title = Keine Zertifikatssperrliste (CRL) im lokalen Speicher +CertPathReviewer.noCrlInCertstore.text = Es wurde keine Zertifikatssperrliste (CRL) im lokalen Speicher gefunden. +CertPathReviewer.noCrlInCertstore.summary = Es wurde keine Zertifikatssperrliste (CRL) im lokalen Speicher gefunden. +CertPathReviewer.noCrlInCertstore.details = Es wurde keine Zertifikatssperrliste (CRL) für den Herausgeber {0} im lokalen Speicher gefunden. \ +Die {2} Zertifikatssperrlisten im lokalen Speicher wurden hearusgegeben von {1}. + + +## check CRL exceptions + +# cannot extract issuer from certificate +CertPathReviewer.crlIssuerException.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.crlIssuerException.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Kann den Herausgeber vom Zertifikat nicht extrahieren. +CertPathReviewer.crlIssuerException.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Kann den Herausgeber vom Zertifikat nicht extrahieren. +CertPathReviewer.crlIssuerException.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Kann den Herausgeber vom Zertifikat nicht extrahieren. + +# cannot extract crls +# {0} message from the underlying exception +# {1} the underlying exception +# {2} the name of the exception +CertPathReviewer.crlExtractionError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.crlExtractionError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab eine {2} beim laden der Zertifikatssperrliste (CRL) aus dem lokalen Speicher. +CertPathReviewer.crlExtractionError.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab eine {2} beim laden der Zertifikatssperrliste (CRL) aus dem lokalen Speicher. +CertPathReviewer.crlExtractionError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab eine {2} beim laden der Zertifikatssperrliste (CRL) aus dem lokalen Speicher. Grund: {0}. + +# Issuer certificate key usage extension does not permit crl signing +CertPathReviewer.noCrlSigningPermited.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.noCrlSigningPermited.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Das Herausgeber Zertifikat erlaubt keine Signieren von Zertifikatssperrlisten (CRL). +CertPathReviewer.noCrlSigningPermited.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Das Herausgeber Zertifikat erlaubt keine Signieren von Zertifikatssperrlisten (CRL). +CertPathReviewer.noCrlSigningPermited.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Das Herausgeber Zertifikat erlaubt keine Signieren von Zertifikatssperrlisten (CRL). + +# can not verify crl: issuer public key unknown +CertPathReviewer.crlNoIssuerPublicKey.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.crlNoIssuerPublicKey.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Kann die Zertifikatssperrliste (CRL) nicht verifizieren. Der öffentliche Schlüssel des Herausgebers ist unbekannt. +CertPathReviewer.crlNoIssuerPublicKey.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Kann die Zertifikatssperrliste (CRL) nicht verifizieren. Der öffentliche Schlüssel des Herausgebers ist unbekannt. +CertPathReviewer.crlNoIssuerPublicKey.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Kann die Zertifikatssperrliste (CRL) nicht verifizieren. Der öffentliche Schlüssel des Herausgebers ist unbekannt. + +# crl verification failed +CertPathReviewer.crlVerifyFailed.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.crlVerifyFailed.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Signatur der Zertifikatssperrliste (CRL) ist ungültig. +CertPathReviewer.crlVerifyFailed.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Signatur der Zertifikatssperrliste (CRL) ist ungültig. +CertPathReviewer.crlVerifyFailed.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Signatur der Zertifikatssperrliste (CRL) ist ungültig. + +# no valid CRL found +CertPathReviewer.noValidCrlFound.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.noValidCrlFound.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: keine gültige Zertifikatssperrliste (CRL) gefunden. +CertPathReviewer.noValidCrlFound.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: keine gültige Zertifikatssperrliste (CRL) gefunden. +CertPathReviewer.noValidCrlFound.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: keine gültige Zertifikatssperrliste (CRL) gefunden. + +# No base CRL for delta CRL +CertPathReviewer.noBaseCRL.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.noBaseCRL.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: keine Basis CRL für die Delta CRL gefunden. +CertPathReviewer.noBaseCRL.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: keine Basis CRL für die Delta CRL gefunden. +CertPathReviewer.noBaseCRL.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: keine Basis CRL für die Delta CRL gefunden. + +# certificate revoked +# {0} the date the certificate was revoked +# {1} the reason for revoking the certificate +CertPathReviewer.certRevoked.title = Zertifikat wurde revoziert +CertPathReviewer.certRevoked.text = Das Zertifikat wurde am {0,date} {0,time,full} revoziert. Grund: {1}. +CertPathReviewer.certRevoked.summary = Das Zertifikat wurde am {0,date} {0,time,full} revoziert. +CertPathReviewer.certRevoked.details = Das Zertifikat wurde am {0,date} {0,time,full} revoziert. Grund: {1}. + +# error processing issuing distribution point extension +CertPathReviewer.distrPtExtError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.distrPtExtError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Issuing Distribution Point Erweiterung. +CertPathReviewer.distrPtExtError.summary = Fehler bei der Verarbeitung der Issuing Distribution Point Erweiterung. +CertPathReviewer.distrPtExtError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Issuing Distribution Point Erweiterung. + +# error processing crl distribution points extension +CertPathReviewer.crlDistPtExtError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.crlDistPtExtError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Distribution Points Erweiterung. +CertPathReviewer.crlDistPtExtError.summary = Fehler bei der Verarbeitung der CRL Distribution Points Erweiterung. +CertPathReviewer.crlDistPtExtError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Distribution Points Erweiterung. + +# error processing the authority info access extension +CertPathReviewer.crlAuthInfoAccError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.crlAuthInfoAccError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Authority Info Access Erweiterung. +CertPathReviewer.crlAuthInfoAccError.summary = Fehler bei der Verarbeitung der Authority Info Access Erweiterung. +CertPathReviewer.crlAuthInfoAccError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Authority Info Access Erweiterung. + +# error processing delta crl indicator extension +CertPathReviewer.deltaCrlExtError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.deltaCrlExtError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Delta CRL Indicator Erweiterung. +CertPathReviewer.deltaCrlExtError.summary = Fehler bei der Verarbeitung der Delta CRL Indicator Erweiterung. +CertPathReviewer.deltaCrlExtError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der Delta CRL Indicator Erweiterung. + +# error porcessing crl number extension +CertPathReviewer.crlNbrExtError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.crlNbrExtError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Number Erweiterung. +CertPathReviewer.crlNbrExtError.summary = Fehler bei der Verarbeitung der CRL Number Erweiterung. +CertPathReviewer.crlNbrExtError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Number Erweiterung. + +# error processing crl reason code extension +CertPathReviewer.crlReasonExtError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.crlReasonExtError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Reason Code Erweiterung. +CertPathReviewer.crlReasonExtError.summary = Fehler bei der Verarbeitung der CRL Reason Code Erweiterung. +CertPathReviewer.crlReasonExtError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Reason Code Erweiterung. + +# error processing basic constraints extension +CertPathReviewer.crlBCExtError.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.crlBCExtError.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Reason Code Erweiterung. +CertPathReviewer.crlBCExtError.summary = Fehler bei der Verarbeitung der CRL Reason Code Erweiterung. +CertPathReviewer.crlBCExtError.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Es gab einen Fehler bei der Verarbeitung der CRL Reason Code Erweiterung. + +# CA Cert CRL only contains user certificates +CertPathReviewer.crlOnlyUserCert.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.crlOnlyUserCert.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur User Zertifikate. +CertPathReviewer.crlOnlyUserCert.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur User Zertifikate. +CertPathReviewer.crlOnlyUserCert.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur User Zertifikate. + +# End CRL only contains CA certificates +CertPathReviewer.crlOnlyCaCert.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.crlOnlyCaCert.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur CA Zertifikate. +CertPathReviewer.crlOnlyCaCert.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur CA Zertifikate. +CertPathReviewer.crlOnlyCaCert.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur CA Zertifikate. + +# onlyContainsAttributeCerts boolean is asserted +CertPathReviewer.crlOnlyAttrCert.title = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen +CertPathReviewer.crlOnlyAttrCert.text = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur Attribut Zertifikate. +CertPathReviewer.crlOnlyAttrCert.summary = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur Attribut Zertifikate. +CertPathReviewer.crlOnlyAttrCert.details = Prüfung der Zertifikatssperrliste (CRL) fehlgeschlagen: Die Zertifikatssperrliste (CRL) enthält nur Attribut Zertifikate. + + +## QcStatement notifications + +# unkown statement +# {0} statement OID +# {1} statement as ANS1Sequence +CertPathReviewer.QcUnknownStatement.title = Unbekanntes Statement in der QcStatement Erweiterung +CertPathReviewer.QcUnknownStatement.text = Unbekanntes Statement in der QcStatement Erweiterung: OID = {0} +CertPathReviewer.QcUnknownStatement.summary = Unbekanntes Statement in der QcStatement Erweiterung: OID = {0} +CertPathReviewer.QcUnknownStatement.details = Unbekanntes Statement in der QcStatement Erweiterung: OID = {0}, statement = {1} + +# QcLimitValue Alpha currency code +# {0} currency code +# {1} limit value +# {2} monetary value as MonetaryValue +CertPathReviewer.QcLimitValueAlpha.title = Transaction Value Limit +CertPathReviewer.QcLimitValueAlpha.text = Dieses Zertifikat hat ein Wertlimite von {1,number, ###,###,###,##0.00#} {0} für Transaktionen. +CertPathReviewer.QcLimitValueAlpha.summary = Wertlimite von {1,number, ###,###,###,##0.00#} {0} für Transaktionen. +CertPathReviewer.QcLimitValueAlpha.details = Dieses Zertifikat hat eine Wertlimite für Transaktionen für welche\ + das Zertifikat genutzt werden kann, gemäss der Richtlinie 1999/93/EG des Europäischen Parlaments und\ + des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen und gemäss der Umsetzung der\ + Richtlinie im Land, das im Herausgeber dieses Zertifikats angegeben ist. Die Limite für diese Zertifikat ist {1,number, ###,###,###,##0.00#} {0}. + +# QcLimitValue Numeric currency code +# {0} currency code +# {1} limit value +# {2} monetary value as MonetaryValue +CertPathReviewer.QcLimitValueNum.title = Transaction Value Limit +CertPathReviewer.QcLimitValueNum.text = Dieses Zertifikat hat eine Wertlimite für Transaktionen von {1,number, ###,###,###,##0.00#} der Währung {0} (Siehe RFC 4217 für Währungscodes). +CertPathReviewer.QcLimitValueNum.summary = Wertlimite für Transaktionen von {1,number, ###,###,###,##0.00#} der Währung {0} (Siehe RFC 4217 für Währungscodes). +CertPathReviewer.QcLimitValueNum.details = Dieses Zertifikat hat eine Wertlimite für Transaktionen für welche\ + das Zertifikat genutzt werden kann, gemäss der Richtlinie 1999/93/EG des Europäischen Parlaments und\ + des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen und gemäss der Umsetzung der\ + Richtlinie im Land, das im Herausgeber dieses Zertifikats angegeben ist. Die Limite für diese Zertifikat ist {1,number, ###,###,###,##0.00#} der Währung {0} (Siehe RFC 4217 für Währungscodes). + +# QcSSCD +CertPathReviewer.QcSSCD.title = QcSSCD Statement +CertPathReviewer.QcSSCD.text = (SSCD) Der Herausgeber macht geltend, dass der Private Schlüssel, der mit diesem Zertifikat verbunden ist, nach den Anforderungen die im Anhang III der Richtlinie 1999/93/EG des Europäischen Parlaments und des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen geschützt ist. +CertPathReviewer.QcSSCD.summary = (SSCD) Der Herausgeber macht geltend, dass der Private Schlüssel, der mit diesem Zertifikat verbunden ist, nach den Anforderungen die im Anhang III der Richtlinie 1999/93/EG des Europäischen Parlaments und des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen geschützt ist. +CertPathReviewer.QcSSCD.details = (SSCD) Der Herausgeber macht geltend, dass der Private Schlüssel, der mit diesem Zertifikat verbunden ist, nach den Anforderungen die im Anhang III der Richtlinie 1999/93/EG des Europäischen Parlaments und des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen geschützt ist. + +# QcEuCompliance +CertPathReviewer.QcEuCompliance.title = Qualifiziertes Zertifikat +CertPathReviewer.QcEuCompliance.text = Dieses Zertifikat wurde als Qualifiziertes Zertifikat herausgegeben gemäss Anhang I und II der Richtlinie 1999/93/EG des Europäischen Parlaments und des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen und gemäss der Umsetzung der Richtlinie im Land, das im Herausgeber dieses Zertifikats angegeben ist. +CertPathReviewer.QcEuCompliance.summary = Dieses Zertifikat wurde als Qualifiziertes Zertifikat herausgegeben gemäss Anhang I und II der Richtlinie 1999/93/EG des Europäischen Parlaments und des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen und gemäss der Umsetzung der Richtlinie in dem Land, das im Herausgeber dieses Zertifikats angegeben ist. +CertPathReviewer.QcEuCompliance.details = Dieses Zertifikat wurde als Qualifiziertes Zertifikat herausgegeben gemäss Anhang I und II der Richtlinie 1999/93/EG des Europäischen Parlaments und des Rates über gemeinschaftliche Rahmenbedingungen für elektronische Signaturen und gemäss der Umsetzung der Richtlinie in dem Land, das im Herausgeber dieses Zertifikats angegeben ist. + +## QcStatement errors + +# error processing the QcStatement extension +CertPathReviewer.QcStatementExtError.title = Fehler bei der Verarbeitung der QcStatement Erweiterung +CertPathReviewer.QcStatementExtError.text = Fehler bei der Verarbeitung der QcStatement Erweiterung. +CertPathReviewer.QcStatementExtError.summary = Fehler bei der Verarbeitung der QcStatement Erweiterung. +CertPathReviewer.QcStatementExtError.details = Fehler bei der Verarbeitung der QcStatement Erweiterung. + +## unknown/generic errors +CertPathReviewer.unknown.title = Unbekannter Fehler +CertPathReviewer.unknown.text = Unbekannter Fehler {0} +CertPathReviewer.unknown.summary = Unbekannter Fehler +CertPathReviewer.unknown.details = Unbekannter Fehler {0} + +# +# crl reasons +# +unspecified = Nicht spezifiziert +keyCompromise = Schlüssel Kompromittierung +cACompromise = CA Kompromittierung +affiliationChanged = Veränderte Zugehörigkeit +superseded = Ersetzt +cessationOfOperation = Einstellen der Tätigkeiten +certificateHold = Zertifikat vorübergehend gesperrt +unknown = Unbekannt +removeFromCRL = Entferne von der CRL +privilegeWithdrawn = Zurückgezogene Rechte +aACompromise = AA Kompromittierung + +# +# +# +missingIssuer = The missing certificate was issued by +missingSerial = with the serial number diff --git a/pkix/src/test/java/org/bouncycastle/cert/cmp/test/AllTests.java b/pkix/src/test/java/org/bouncycastle/cert/cmp/test/AllTests.java index 8fe1fa2c41..038320aac4 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/cmp/test/AllTests.java +++ b/pkix/src/test/java/org/bouncycastle/cert/cmp/test/AllTests.java @@ -273,7 +273,7 @@ public void testSubsequentMessage() CertReqMsg reqMsg = reqMsgs.toCertReqMsgArray()[0]; - assertEquals(ProofOfPossession.TYPE_KEY_ENCIPHERMENT, reqMsg.getPopo().getType()); + assertEquals(ProofOfPossession.TYPE_KEY_ENCIPHERMENT, reqMsg.getPop().getType()); } public void testServerSideKey() diff --git a/pkix/src/test/java/org/bouncycastle/cert/cmp/test/ElgamalDSATest.java b/pkix/src/test/java/org/bouncycastle/cert/cmp/test/ElgamalDSATest.java index 4bb37c02a3..e012c2bf88 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/cmp/test/ElgamalDSATest.java +++ b/pkix/src/test/java/org/bouncycastle/cert/cmp/test/ElgamalDSATest.java @@ -3,14 +3,8 @@ import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; -import java.security.PrivateKey; -import java.security.PublicKey; import java.security.Security; import java.security.spec.DSAParameterSpec; -import java.util.Arrays; -import java.util.Collection; -import java.util.Date; -import java.util.Iterator; import junit.framework.TestCase; import org.bouncycastle.asn1.cmp.CMPCertificate; @@ -19,16 +13,9 @@ import org.bouncycastle.asn1.cmp.PKIStatusInfo; import org.bouncycastle.asn1.crmf.CertTemplate; import org.bouncycastle.asn1.crmf.SubsequentMessage; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.BasicConstraints; -import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.cert.CertException; -import org.bouncycastle.cert.CertIOException; import org.bouncycastle.cert.X509CertificateHolder; -import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.cmp.CertificateConfirmationContent; import org.bouncycastle.cert.cmp.CertificateConfirmationContentBuilder; import org.bouncycastle.cert.cmp.ProtectedPKIMessage; @@ -42,13 +29,10 @@ import org.bouncycastle.cert.crmf.CertificateResponseBuilder; import org.bouncycastle.cert.crmf.jcajce.JcaCertificateRequestMessageBuilder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSProcessableByteArray; -import org.bouncycastle.cms.RecipientInformation; -import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; @@ -58,9 +42,7 @@ import org.bouncycastle.jcajce.spec.DHDomainParameterSpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.MacCalculator; -import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.PBEMacCalculatorProvider; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; @@ -98,7 +80,7 @@ public void testElgamalWithDSA() KeyPair dsaKp = dsaKpGen.generateKeyPair(); - X509CertificateHolder caCert = makeV3Certificate("CN=DSA Issuer", dsaKp); + X509CertificateHolder caCert = TestUtils.makeV3Certificate("CN=DSA Issuer", dsaKp); KeyPairGenerator elgKpGen = KeyPairGenerator.getInstance("Elgamal", "BC"); @@ -140,7 +122,7 @@ public void testElgamalWithDSA() CertificateRequestMessage senderReqMessage = requestMessages.getRequests()[0]; CertTemplate certTemplate = senderReqMessage.getCertTemplate(); - X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dsaKp, "CN=DSA Issuer"); + X509CertificateHolder cert = TestUtils.makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dsaKp, "CN=DSA Issuer"); // Send response with encrypted certificate CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); @@ -204,57 +186,4 @@ public void testElgamalWithDSA() assertTrue(recContent.getStatusMessages()[0].isVerified(receivedCert, new JcaDigestCalculatorProviderBuilder().build())); } - private static X509CertificateHolder makeV3Certificate(String _subDN, KeyPair issKP) - throws OperatorCreationException, CertException, CertIOException - { - PrivateKey issPriv = issKP.getPrivate(); - PublicKey issPub = issKP.getPublic(); - - X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( - new X500Name(_subDN), - BigInteger.valueOf(System.currentTimeMillis()), - new Date(System.currentTimeMillis()), - new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), - new X500Name(_subDN), - issKP.getPublic()); - - certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(0)); - - ContentSigner signer = new JcaContentSignerBuilder("SHA256withDSA").build(issPriv); - - X509CertificateHolder certHolder = certGen.build(signer); - - ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().build(issPub); - - assertTrue(certHolder.isSignatureValid(verifier)); - - return certHolder; - } - - private static X509CertificateHolder makeV3Certificate(SubjectPublicKeyInfo pubKey, X500Name _subDN, KeyPair issKP, String _issDN) - throws OperatorCreationException, CertException, CertIOException - { - PrivateKey issPriv = issKP.getPrivate(); - PublicKey issPub = issKP.getPublic(); - - X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( - new X500Name(_issDN), - BigInteger.valueOf(System.currentTimeMillis()), - new Date(System.currentTimeMillis()), - new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), - _subDN, - pubKey); - - certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(false)); - - ContentSigner signer = new JcaContentSignerBuilder("SHA256withDSA").build(issPriv); - - X509CertificateHolder certHolder = certGen.build(signer); - - ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().build(issPub); - - assertTrue(certHolder.isSignatureValid(verifier)); - - return certHolder; - } } diff --git a/pkix/src/test/java/org/bouncycastle/cert/cmp/test/InvalidMessagesTest.java b/pkix/src/test/java/org/bouncycastle/cert/cmp/test/InvalidMessagesTest.java new file mode 100644 index 0000000000..de267a19d7 --- /dev/null +++ b/pkix/src/test/java/org/bouncycastle/cert/cmp/test/InvalidMessagesTest.java @@ -0,0 +1,153 @@ +package org.bouncycastle.cert.cmp.test; + +import java.io.IOException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.Security; +import java.security.spec.DSAParameterSpec; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.bouncycastle.asn1.cmp.PKIBody; +import org.bouncycastle.asn1.pkcs.CertificationRequest; +import org.bouncycastle.cert.CertIOException; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.cmp.CMPException; +import org.bouncycastle.cert.cmp.GeneralPKIMessage; +import org.bouncycastle.cert.cmp.ProtectedPKIMessage; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.params.DSAParameters; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; +import org.bouncycastle.pkcs.PKCS10CertificationRequest; +import org.bouncycastle.pkcs.PKCSException; +import org.bouncycastle.test.TestResourceFinder; +import org.bouncycastle.util.io.Streams; + +public class InvalidMessagesTest + extends TestCase +{ + public void setUp() + { + if (Security.getProvider("BC") == null) + { + Security.addProvider(new BouncyCastleProvider()); + } + } + + public void testBadNoBodyWithProtection() + throws Exception + { + try + { + new ProtectedPKIMessage(fetchPkiMessage("bad-no-body")); + } + catch (CertIOException e) + { + Assert.assertEquals("malformed data: malformed body found: body type of 0 has incorrect type got: class org.bouncycastle.asn1.DERBitString", e.getMessage()); + } + } + + public void testBadNoBody() + throws Exception + { + try + { + new ProtectedPKIMessage(fetchPkiMessage("bad-no-body-after-header")); + } + catch (CertIOException e) + { + Assert.assertEquals("malformed data: PKIMessage missing PKIBody structure", e.getMessage()); + } + } + + public void testBadOidSigAlg() + throws Exception + { + ProtectedPKIMessage message = new ProtectedPKIMessage(fetchPkiMessage("bad-oid-sigalg")); + + PKIBody body = message.getBody(); + + Assert.assertEquals(body.getType(), PKIBody.TYPE_P10_CERT_REQ); + + PKCS10CertificationRequest certReq = new PKCS10CertificationRequest(CertificationRequest.getInstance(body.getContent())); + try + { + certReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(certReq.getSubjectPublicKeyInfo())); + } + catch (PKCSException e) + { + Assert.assertEquals("unable to process signature: exception on setup: java.security.NoSuchAlgorithmException: no such algorithm: 1.2.840.113549.2097035 for provider BC", e.getMessage()); + } + } + + public void testBadProtection() + throws Exception + { + KeyPairGenerator dsaKpGen = KeyPairGenerator.getInstance("DSA", "BC"); + + DSAParameters dsaParams = (DSAParameters)CryptoServicesRegistrar.getSizedProperty(CryptoServicesRegistrar.Property.DSA_DEFAULT_PARAMS, 2048); + + dsaKpGen.initialize(new DSAParameterSpec(dsaParams.getP(), dsaParams.getQ(), dsaParams.getG())); + + KeyPair dsaKp = dsaKpGen.generateKeyPair(); + + X509CertificateHolder caCert = TestUtils.makeV3Certificate("CN=DSA Issuer", dsaKp); + + ProtectedPKIMessage message = new ProtectedPKIMessage(fetchPkiMessage("bad-protection")); + + try + { + message.verify(new JcaContentVerifierProviderBuilder().build(caCert)); + } + catch (CMPException e) + { + Assert.assertEquals("unable to verify signature: exception on setup: java.security.NoSuchAlgorithmException: 1.2.840.113549.2.11 Signature not available", e.getMessage()); + } + } + + public void testBadTagBody15vs4() + throws Exception + { + try + { + new ProtectedPKIMessage(fetchPkiMessage("bad-tag-body-15-vs-4")); + } + catch (CertIOException e) + { + Assert.assertEquals("malformed data: malformed body found: body type of 15 has incorrect type got: class org.bouncycastle.asn1.DLSequence", e.getMessage()); + } + } + + public void testBadTagBody29vs4() + throws Exception + { + try + { + new ProtectedPKIMessage(fetchPkiMessage("bad-tag-body-29-vs-4")); + } + catch (IOException e) + { + Assert.assertEquals("unknown tag 29 encountered", e.getMessage()); + } + } + + public void testBadTypeSequenceVsChoice() + throws Exception + { + try + { + new ProtectedPKIMessage(fetchPkiMessage("bad-body-seq-vs-choice")); + } + catch (CertIOException e) + { + Assert.assertEquals("malformed data: Invalid object: org.bouncycastle.asn1.DLSequence", e.getMessage()); + } + } + + private GeneralPKIMessage fetchPkiMessage(String s) + throws IOException + { + return new GeneralPKIMessage(Streams.readAll(TestResourceFinder.findTestResource("cmp/invalid-messages", s))); + } +} diff --git a/pkix/src/test/java/org/bouncycastle/cert/cmp/test/PQCTest.java b/pkix/src/test/java/org/bouncycastle/cert/cmp/test/PQCTest.java index d3cda888f7..7c8e1b84f9 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/cmp/test/PQCTest.java +++ b/pkix/src/test/java/org/bouncycastle/cert/cmp/test/PQCTest.java @@ -52,6 +52,8 @@ import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; import org.bouncycastle.cms.jcajce.JceKEMEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKEMRecipientInfoGenerator; +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; +import org.bouncycastle.jcajce.spec.MLKEMParameterSpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; @@ -64,8 +66,9 @@ import org.bouncycastle.pkcs.jcajce.JcePBMac1CalculatorBuilder; import org.bouncycastle.pkcs.jcajce.JcePBMac1CalculatorProviderBuilder; import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; -import org.bouncycastle.pqc.jcajce.spec.DilithiumParameterSpec; -import org.bouncycastle.pqc.jcajce.spec.KyberParameterSpec; +import org.bouncycastle.pqc.jcajce.spec.BIKEParameterSpec; +import org.bouncycastle.pqc.jcajce.spec.CMCEParameterSpec; +import org.bouncycastle.pqc.jcajce.spec.HQCParameterSpec; import org.bouncycastle.pqc.jcajce.spec.NTRUParameterSpec; import org.bouncycastle.util.BigIntegers; @@ -83,24 +86,24 @@ public void tearDown() } - public void testKyberRequestWithDilithiumCA() + public void testMlKemRequestWithMlDsaCA() throws Exception { char[] senderMacPassword = "secret".toCharArray(); - GeneralName sender = new GeneralName(new X500Name("CN=Kyber Subject")); - GeneralName recipient = new GeneralName(new X500Name("CN=Dilithium Issuer")); + GeneralName sender = new GeneralName(new X500Name("CN=ML-KEM Subject")); + GeneralName recipient = new GeneralName(new X500Name("CN=ML-DSA Issuer")); - KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("Dilithium", "BCPQC"); + KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("ML-DSA", "BC"); - dilKpGen.initialize(DilithiumParameterSpec.dilithium2); + dilKpGen.initialize(MLDSAParameterSpec.ml_dsa_65); KeyPair dilKp = dilKpGen.generateKeyPair(); - X509CertificateHolder caCert = makeV3Certificate("CN=Dilithium Issuer", dilKp); + X509CertificateHolder caCert = makeV3Certificate("CN=ML-DSA Issuer", dilKp); - KeyPairGenerator kybKpGen = KeyPairGenerator.getInstance("Kyber", "BCPQC"); + KeyPairGenerator kybKpGen = KeyPairGenerator.getInstance("ML-KEM", "BC"); - kybKpGen.initialize(KyberParameterSpec.kyber512); + kybKpGen.initialize(MLKEMParameterSpec.ml_kem_768); KeyPair kybKp = kybKpGen.generateKeyPair(); @@ -137,7 +140,7 @@ public void testKyberRequestWithDilithiumCA() CertificateRequestMessage senderReqMessage = requestMessages.getRequests()[0]; CertTemplate certTemplate = senderReqMessage.getCertTemplate(); - X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=Dilithium Issuer"); + X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=ML-DSA Issuer"); // Send response with encrypted certificate CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); @@ -145,12 +148,12 @@ public void testKyberRequestWithDilithiumCA() // note: use cert req ID as key ID, don't want to use issuer/serial in this case! edGen.addRecipientInfoGenerator(new JceKEMRecipientInfoGenerator(senderReqMessage.getCertReqId().getEncoded(), - new JcaX509CertificateConverter().setProvider("BC").getCertificate(cert).getPublicKey(), CMSAlgorithm.AES256_WRAP).setKDF( - new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256))); + new JcaX509CertificateConverter().setProvider("BC").getCertificate(cert).getPublicKey(), CMSAlgorithm.AES256_WRAP).setKDF( + new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256))); CMSEnvelopedData encryptedCert = edGen.generate( - new CMSProcessableCMPCertificate(cert), - new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider("BC").build()); + new CMSProcessableCMPCertificate(cert), + new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider("BC").build()); CertificateResponseBuilder certRespBuilder = new CertificateResponseBuilder(senderReqMessage.getCertReqId(), new PKIStatusInfo(PKIStatus.granted)); @@ -160,7 +163,7 @@ public void testKyberRequestWithDilithiumCA() repMessageBuilder.addCertificateResponse(certRespBuilder.build()); - ContentSigner signer = new JcaContentSignerBuilder("Dilithium").setProvider("BCPQC").build(dilKp.getPrivate()); + ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").setProvider("BC").build(dilKp.getPrivate()); CertificateRepMessage repMessage = repMessageBuilder.build(); @@ -207,7 +210,7 @@ public void testKyberRequestWithDilithiumCA() RecipientInformation recInfo = (RecipientInformation)c.iterator().next(); - assertEquals(recInfo.getKeyEncryptionAlgOID(), BCObjectIdentifiers.kyber512.getId()); + assertEquals(recInfo.getKeyEncryptionAlgOID(), NISTObjectIdentifiers.id_alg_ml_kem_768.getId()); // Note: we don't specify the provider here as we're actually using both BC and BCPQC @@ -245,20 +248,20 @@ public void testKyberRequestWithDilithiumCA() assertTrue(recContent.getStatusMessages()[0].isVerified(receivedCert, new JcaDigestCalculatorProviderBuilder().build())); } - public void testNTRURequestWithDilithiumCA() + public void testNTRURequestWithMlDsaCA() throws Exception { char[] senderMacPassword = "secret".toCharArray(); - GeneralName sender = new GeneralName(new X500Name("CN=Kyber Subject")); - GeneralName recipient = new GeneralName(new X500Name("CN=Dilithium Issuer")); + GeneralName sender = new GeneralName(new X500Name("CN=NTRU Subject")); + GeneralName recipient = new GeneralName(new X500Name("CN=ML-DSA Issuer")); - KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("Dilithium", "BCPQC"); + KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("ML-DSA", "BC"); - dilKpGen.initialize(DilithiumParameterSpec.dilithium2); + dilKpGen.initialize(MLDSAParameterSpec.ml_dsa_44); KeyPair dilKp = dilKpGen.generateKeyPair(); - X509CertificateHolder caCert = makeV3Certificate("CN=Dilithium Issuer", dilKp); + X509CertificateHolder caCert = makeV3Certificate("CN=ML-DSA Issuer", dilKp); KeyPairGenerator kybKpGen = KeyPairGenerator.getInstance("NTRU", "BCPQC"); @@ -299,7 +302,7 @@ public void testNTRURequestWithDilithiumCA() CertificateRequestMessage senderReqMessage = requestMessages.getRequests()[0]; CertTemplate certTemplate = senderReqMessage.getCertTemplate(); - X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=Dilithium Issuer"); + X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=ML-DSA Issuer"); // Send response with encrypted certificate CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); @@ -307,12 +310,12 @@ public void testNTRURequestWithDilithiumCA() // note: use cert req ID as key ID, don't want to use issuer/serial in this case! edGen.addRecipientInfoGenerator(new JceKEMRecipientInfoGenerator(senderReqMessage.getCertReqId().getEncoded(), - new JcaX509CertificateConverter().setProvider("BC").getCertificate(cert).getPublicKey(), CMSAlgorithm.AES256_WRAP) - .setKDF(new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256))); + new JcaX509CertificateConverter().setProvider("BC").getCertificate(cert).getPublicKey(), CMSAlgorithm.AES256_WRAP) + .setKDF(new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256))); CMSEnvelopedData encryptedCert = edGen.generate( - new CMSProcessableCMPCertificate(cert), - new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES192_CBC).setProvider("BC").build()); + new CMSProcessableCMPCertificate(cert), + new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES192_CBC).setProvider("BC").build()); CertificateResponseBuilder certRespBuilder = new CertificateResponseBuilder(senderReqMessage.getCertReqId(), new PKIStatusInfo(PKIStatus.granted)); @@ -322,7 +325,7 @@ public void testNTRURequestWithDilithiumCA() repMessageBuilder.addCertificateResponse(certRespBuilder.build()); - ContentSigner signer = new JcaContentSignerBuilder("Dilithium").setProvider("BCPQC").build(dilKp.getPrivate()); + ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").setProvider("BC").build(dilKp.getPrivate()); CertificateRepMessage repMessage = repMessageBuilder.build(); @@ -417,11 +420,699 @@ public void testNTRURequestWithDilithiumCA() // System.err.println(ASN1Dump.dumpAsString(receivedEnvelope.toASN1Structure())); } + public void testBIKERequestWithMlDsaCA() + throws Exception + { + char[] senderMacPassword = "secret".toCharArray(); + GeneralName sender = new GeneralName(new X500Name("CN=Bike128 Subject")); + GeneralName recipient = new GeneralName(new X500Name("CN=ML-DSA Issuer")); + + KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("ML-DSA", "BC"); + + dilKpGen.initialize(MLDSAParameterSpec.ml_dsa_44); + + KeyPair dilKp = dilKpGen.generateKeyPair(); + + X509CertificateHolder caCert = makeV3Certificate("CN=ML-DSA Issuer", dilKp); + + KeyPairGenerator kybKpGen = KeyPairGenerator.getInstance("BIKE", "BCPQC"); + + kybKpGen.initialize(BIKEParameterSpec.bike128); + + KeyPair ntruKp = kybKpGen.generateKeyPair(); + + // initial request + + JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigIntegers.ONE); + + certReqBuild + .setPublicKey(ntruKp.getPublic()) + .setSubject(X500Name.getInstance(sender.getName())) + .setProofOfPossessionSubsequentMessage(SubsequentMessage.encrCert); + + CertificateReqMessagesBuilder certReqMsgsBldr = new CertificateReqMessagesBuilder(); + + certReqMsgsBldr.addRequest(certReqBuild.build()); + + MacCalculator senderMacCalculator = new JcePBMac1CalculatorBuilder("HmacSHA256", 256).setProvider("BC").build(senderMacPassword); + + ProtectedPKIMessage initMessage = new ProtectedPKIMessageBuilder(sender, recipient) + .setBody(PKIBody.TYPE_INIT_REQ, certReqMsgsBldr.build()) + .build(senderMacCalculator); + + // extract + + assertTrue(initMessage.getProtectionAlgorithm().equals(senderMacCalculator.getAlgorithmIdentifier())); + + PBEMacCalculatorProvider macCalcProvider = new JcePBMac1CalculatorProviderBuilder().setProvider("BC").build(); + + assertTrue(initMessage.verify(macCalcProvider, senderMacPassword)); + + assertEquals(PKIBody.TYPE_INIT_REQ, initMessage.getBody().getType()); + + CertificateReqMessages requestMessages = CertificateReqMessages.fromPKIBody(initMessage.getBody()); + CertificateRequestMessage senderReqMessage = requestMessages.getRequests()[0]; + CertTemplate certTemplate = senderReqMessage.getCertTemplate(); + + X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=ML-DSA Issuer"); + + // Send response with encrypted certificate + CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); + + // note: use cert req ID as key ID, don't want to use issuer/serial in this case! + + edGen.addRecipientInfoGenerator(new JceKEMRecipientInfoGenerator(senderReqMessage.getCertReqId().getEncoded(), + new JcaX509CertificateConverter().setProvider("BC").getCertificate(cert).getPublicKey(), CMSAlgorithm.AES256_WRAP) + .setKDF(new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256))); + + CMSEnvelopedData encryptedCert = edGen.generate( + new CMSProcessableCMPCertificate(cert), + new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES192_CBC).setProvider("BC").build()); + + CertificateResponseBuilder certRespBuilder = new CertificateResponseBuilder(senderReqMessage.getCertReqId(), new PKIStatusInfo(PKIStatus.granted)); + + certRespBuilder.withCertificate(encryptedCert); + + CertificateRepMessageBuilder repMessageBuilder = new CertificateRepMessageBuilder(caCert); + + repMessageBuilder.addCertificateResponse(certRespBuilder.build()); + + ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").setProvider("BC").build(dilKp.getPrivate()); + + CertificateRepMessage repMessage = repMessageBuilder.build(); + + ProtectedPKIMessage responsePkixMessage = new ProtectedPKIMessageBuilder(sender, recipient) + .setBody(PKIBody.TYPE_INIT_REP, repMessage) + .build(signer); + + // decrypt the certificate + + assertTrue(responsePkixMessage.verify(new JcaContentVerifierProviderBuilder().build(caCert))); + + CertificateRepMessage certRepMessage = CertificateRepMessage.fromPKIBody(responsePkixMessage.getBody()); + + CertificateResponse certResp = certRepMessage.getResponses()[0]; + + assertEquals(true, certResp.hasEncryptedCertificate()); + + // this is the long-way to decrypt, for testing + CMSEnvelopedData receivedEnvelope = certResp.getEncryptedCertificate(); + RecipientInformationStore recipients = receivedEnvelope.getRecipientInfos(); + Collection c = recipients.getRecipients(); + + assertEquals(1, c.size()); + + RecipientInformation recInfo = (RecipientInformation)c.iterator().next(); + + assertEquals(recInfo.getKeyEncryptionAlgOID(), BCObjectIdentifiers.bike128.getId()); + + // Note: we don't specify the provider here as we're actually using both BC and BCPQC + + byte[] recData = recInfo.getContent(new JceKEMEnvelopedRecipient(ntruKp.getPrivate())); + + assertEquals(true, Arrays.equals(new CMPCertificate(cert.toASN1Structure()).getEncoded(), recData)); + + // this is the preferred way of recovering an encrypted certificate + + CMPCertificate receivedCMPCert = certResp.getCertificate(new JceKEMEnvelopedRecipient(ntruKp.getPrivate())); + + X509CertificateHolder receivedCert = new X509CertificateHolder(receivedCMPCert.getX509v3PKCert()); + + X509CertificateHolder caCertHolder = certRepMessage.getX509Certificates()[0]; + + assertEquals(true, receivedCert.isSignatureValid(new JcaContentVerifierProviderBuilder().build(caCertHolder))); + + // confirmation message calculation + + CertificateConfirmationContent content = new CertificateConfirmationContentBuilder() + .addAcceptedCertificate(cert, BigInteger.ONE) + .build(new JcaDigestCalculatorProviderBuilder().build()); + + ProtectedPKIMessage certConf = new ProtectedPKIMessageBuilder(sender, recipient) + .setBody(PKIBody.TYPE_CERT_CONFIRM, content) + .build(senderMacCalculator); + + assertTrue(content.getStatusMessages()[0].isVerified(receivedCert, new JcaDigestCalculatorProviderBuilder().build())); + assertEquals(PKIBody.TYPE_CERT_CONFIRM, certConf.getBody().getType()); + + // confirmation receiving + + CertificateConfirmationContent recContent = CertificateConfirmationContent.fromPKIBody(certConf.getBody()); + + assertTrue(recContent.getStatusMessages()[0].isVerified(receivedCert, new JcaDigestCalculatorProviderBuilder().build())); + +// JcaPEMWriter pOut = new JcaPEMWriter(new FileWriter("/tmp/bike_dil_cmp/ca_cert.pem")); +// pOut.writeObject(caCert); +// pOut.close(); +// +// pOut = new JcaPEMWriter(new FileWriter("/tmp/bike_dil_cmp/bike_priv.pem")); +// pOut.writeObject(ntruKp.getPrivate()); +// pOut.close(); +// +// pOut = new JcaPEMWriter(new FileWriter("/tmp/bike_dil_cmp/bike_cert.pem")); +// pOut.writeObject(cert); +// pOut.close(); +// +// OutputStream fOut = new FileOutputStream("/tmp/bike_dil_cmp/cmp_message.ir"); +// fOut.write(initMessage.toASN1Structure().getEncoded()); +// fOut.close(); +// +// fOut = new FileOutputStream("/tmp/bike_dil_cmp/cmp_message.ip"); +// fOut.write(responsePkixMessage.toASN1Structure().getEncoded()); +// fOut.close(); +// +// fOut = new FileOutputStream("/tmp/bike_dil_cmp/cmp_message.ip"); +// fOut.write(responsePkixMessage.toASN1Structure().getEncoded()); +// fOut.close(); +// +// fOut = new FileOutputStream("/tmp/bike_dil_cmp/cmp_message.certConf"); +// fOut.write(certConf.toASN1Structure().getEncoded()); +// fOut.close(); +// +// System.err.println(ASN1Dump.dumpAsString(receivedEnvelope.toASN1Structure())); + } + + public void testHQCRequestWithMlDsaCA() + throws Exception + { + char[] senderMacPassword = "secret".toCharArray(); + GeneralName sender = new GeneralName(new X500Name("CN=HQC128 Subject")); + GeneralName recipient = new GeneralName(new X500Name("CN=ML-DSA Issuer")); + + KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("ML-DSA", "BC"); + + dilKpGen.initialize(MLDSAParameterSpec.ml_dsa_44); + + KeyPair dilKp = dilKpGen.generateKeyPair(); + + X509CertificateHolder caCert = makeV3Certificate("CN=ML-DSA Issuer", dilKp); + + KeyPairGenerator kybKpGen = KeyPairGenerator.getInstance("HQC", "BCPQC"); + + kybKpGen.initialize(HQCParameterSpec.hqc128); + + KeyPair hqcKp = kybKpGen.generateKeyPair(); + + // initial request + + JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigIntegers.ONE); + + certReqBuild + .setPublicKey(hqcKp.getPublic()) + .setSubject(X500Name.getInstance(sender.getName())) + .setProofOfPossessionSubsequentMessage(SubsequentMessage.encrCert); + + CertificateReqMessagesBuilder certReqMsgsBldr = new CertificateReqMessagesBuilder(); + + certReqMsgsBldr.addRequest(certReqBuild.build()); + + MacCalculator senderMacCalculator = new JcePBMac1CalculatorBuilder("HmacSHA256", 256).setProvider("BC").build(senderMacPassword); + + ProtectedPKIMessage initMessage = new ProtectedPKIMessageBuilder(sender, recipient) + .setBody(PKIBody.TYPE_INIT_REQ, certReqMsgsBldr.build()) + .build(senderMacCalculator); + + // extract + + assertTrue(initMessage.getProtectionAlgorithm().equals(senderMacCalculator.getAlgorithmIdentifier())); + + PBEMacCalculatorProvider macCalcProvider = new JcePBMac1CalculatorProviderBuilder().setProvider("BC").build(); + + assertTrue(initMessage.verify(macCalcProvider, senderMacPassword)); + + assertEquals(PKIBody.TYPE_INIT_REQ, initMessage.getBody().getType()); + + CertificateReqMessages requestMessages = CertificateReqMessages.fromPKIBody(initMessage.getBody()); + CertificateRequestMessage senderReqMessage = requestMessages.getRequests()[0]; + CertTemplate certTemplate = senderReqMessage.getCertTemplate(); + + X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=ML-DSA Issuer"); + + // Send response with encrypted certificate + CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); + + // note: use cert req ID as key ID, don't want to use issuer/serial in this case! + + edGen.addRecipientInfoGenerator(new JceKEMRecipientInfoGenerator(senderReqMessage.getCertReqId().getEncoded(), + new JcaX509CertificateConverter().setProvider("BC").getCertificate(cert).getPublicKey(), CMSAlgorithm.AES256_WRAP) + .setKDF(new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256))); + + CMSEnvelopedData encryptedCert = edGen.generate( + new CMSProcessableCMPCertificate(cert), + new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES192_CBC).setProvider("BC").build()); + + CertificateResponseBuilder certRespBuilder = new CertificateResponseBuilder(senderReqMessage.getCertReqId(), new PKIStatusInfo(PKIStatus.granted)); + + certRespBuilder.withCertificate(encryptedCert); + + CertificateRepMessageBuilder repMessageBuilder = new CertificateRepMessageBuilder(caCert); + + repMessageBuilder.addCertificateResponse(certRespBuilder.build()); + + ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").setProvider("BC").build(dilKp.getPrivate()); + + CertificateRepMessage repMessage = repMessageBuilder.build(); + + ProtectedPKIMessage responsePkixMessage = new ProtectedPKIMessageBuilder(sender, recipient) + .setBody(PKIBody.TYPE_INIT_REP, repMessage) + .build(signer); + + // decrypt the certificate + + assertTrue(responsePkixMessage.verify(new JcaContentVerifierProviderBuilder().build(caCert))); + + CertificateRepMessage certRepMessage = CertificateRepMessage.fromPKIBody(responsePkixMessage.getBody()); + + CertificateResponse certResp = certRepMessage.getResponses()[0]; + + assertEquals(true, certResp.hasEncryptedCertificate()); + + // this is the long-way to decrypt, for testing + CMSEnvelopedData receivedEnvelope = certResp.getEncryptedCertificate(); + RecipientInformationStore recipients = receivedEnvelope.getRecipientInfos(); + Collection c = recipients.getRecipients(); + + assertEquals(1, c.size()); + + RecipientInformation recInfo = (RecipientInformation)c.iterator().next(); + + assertEquals(recInfo.getKeyEncryptionAlgOID(), BCObjectIdentifiers.hqc128.getId()); + + // Note: we don't specify the provider here as we're actually using both BC and BCPQC + + byte[] recData = recInfo.getContent(new JceKEMEnvelopedRecipient(hqcKp.getPrivate())); + + assertEquals(true, Arrays.equals(new CMPCertificate(cert.toASN1Structure()).getEncoded(), recData)); + + // this is the preferred way of recovering an encrypted certificate + + CMPCertificate receivedCMPCert = certResp.getCertificate(new JceKEMEnvelopedRecipient(hqcKp.getPrivate())); + + X509CertificateHolder receivedCert = new X509CertificateHolder(receivedCMPCert.getX509v3PKCert()); + + X509CertificateHolder caCertHolder = certRepMessage.getX509Certificates()[0]; + + assertEquals(true, receivedCert.isSignatureValid(new JcaContentVerifierProviderBuilder().build(caCertHolder))); + + // confirmation message calculation + + CertificateConfirmationContent content = new CertificateConfirmationContentBuilder() + .addAcceptedCertificate(cert, BigInteger.ONE) + .build(new JcaDigestCalculatorProviderBuilder().build()); + + ProtectedPKIMessage certConf = new ProtectedPKIMessageBuilder(sender, recipient) + .setBody(PKIBody.TYPE_CERT_CONFIRM, content) + .build(senderMacCalculator); + + assertTrue(content.getStatusMessages()[0].isVerified(receivedCert, new JcaDigestCalculatorProviderBuilder().build())); + assertEquals(PKIBody.TYPE_CERT_CONFIRM, certConf.getBody().getType()); + + // confirmation receiving + + CertificateConfirmationContent recContent = CertificateConfirmationContent.fromPKIBody(certConf.getBody()); + + assertTrue(recContent.getStatusMessages()[0].isVerified(receivedCert, new JcaDigestCalculatorProviderBuilder().build())); + +// JcaPEMWriter pOut = new JcaPEMWriter(new FileWriter("/tmp/hqc_dil_cmp/ca_cert.pem")); +// pOut.writeObject(caCert); +// pOut.close(); +// +// pOut = new JcaPEMWriter(new FileWriter("/tmp/hqc_dil_cmp/hqc_priv.pem")); +// pOut.writeObject(hqcKp.getPrivate()); +// pOut.close(); +// +// pOut = new JcaPEMWriter(new FileWriter("/tmp/hqc_dil_cmp/hqc_cert.pem")); +// pOut.writeObject(cert); +// pOut.close(); +// +// OutputStream fOut = new FileOutputStream("/tmp/hqc_dil_cmp/cmp_message.ir"); +// fOut.write(initMessage.toASN1Structure().getEncoded()); +// fOut.close(); +// +// fOut = new FileOutputStream("/tmp/hqc_dil_cmp/cmp_message.ip"); +// fOut.write(responsePkixMessage.toASN1Structure().getEncoded()); +// fOut.close(); +// +// fOut = new FileOutputStream("/tmp/hqc_dil_cmp/cmp_message.ip"); +// fOut.write(responsePkixMessage.toASN1Structure().getEncoded()); +// fOut.close(); +// +// fOut = new FileOutputStream("/tmp/hqc_dil_cmp/cmp_message.certConf"); +// fOut.write(certConf.toASN1Structure().getEncoded()); +// fOut.close(); +// +// System.err.println(ASN1Dump.dumpAsString(receivedEnvelope.toASN1Structure())); + } + + public void testCMCERequestWithMlDsaCA() + throws Exception + { + char[] senderMacPassword = "secret".toCharArray(); + GeneralName sender = new GeneralName(new X500Name("CN=mceliece3488864 Subject")); + GeneralName recipient = new GeneralName(new X500Name("CN=ML-DSA Issuer")); + + KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("ML-DSA", "BC"); + + dilKpGen.initialize(MLDSAParameterSpec.ml_dsa_44); + + KeyPair dilKp = dilKpGen.generateKeyPair(); + + X509CertificateHolder caCert = makeV3Certificate("CN=ML-DSA Issuer", dilKp); + + KeyPairGenerator cmceKpGen = KeyPairGenerator.getInstance("CMCE", "BCPQC"); + + cmceKpGen.initialize(CMCEParameterSpec.mceliece348864); + + KeyPair hqcKp = cmceKpGen.generateKeyPair(); + + // initial request + + JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigIntegers.ONE); + + certReqBuild + .setPublicKey(hqcKp.getPublic()) + .setSubject(X500Name.getInstance(sender.getName())) + .setProofOfPossessionSubsequentMessage(SubsequentMessage.encrCert); + + CertificateReqMessagesBuilder certReqMsgsBldr = new CertificateReqMessagesBuilder(); + + certReqMsgsBldr.addRequest(certReqBuild.build()); + + MacCalculator senderMacCalculator = new JcePBMac1CalculatorBuilder("HmacSHA256", 256).setProvider("BC").build(senderMacPassword); + + ProtectedPKIMessage initMessage = new ProtectedPKIMessageBuilder(sender, recipient) + .setBody(PKIBody.TYPE_INIT_REQ, certReqMsgsBldr.build()) + .build(senderMacCalculator); + + // extract + + assertTrue(initMessage.getProtectionAlgorithm().equals(senderMacCalculator.getAlgorithmIdentifier())); + + PBEMacCalculatorProvider macCalcProvider = new JcePBMac1CalculatorProviderBuilder().setProvider("BC").build(); + + assertTrue(initMessage.verify(macCalcProvider, senderMacPassword)); + + assertEquals(PKIBody.TYPE_INIT_REQ, initMessage.getBody().getType()); + + CertificateReqMessages requestMessages = CertificateReqMessages.fromPKIBody(initMessage.getBody()); + CertificateRequestMessage senderReqMessage = requestMessages.getRequests()[0]; + CertTemplate certTemplate = senderReqMessage.getCertTemplate(); + + X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=ML-DSA Issuer"); + + // Send response with encrypted certificate + CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); + + // note: use cert req ID as key ID, don't want to use issuer/serial in this case! + + edGen.addRecipientInfoGenerator(new JceKEMRecipientInfoGenerator(senderReqMessage.getCertReqId().getEncoded(), + new JcaX509CertificateConverter().setProvider("BC").getCertificate(cert).getPublicKey(), CMSAlgorithm.AES256_WRAP) + .setKDF(new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256))); + + CMSEnvelopedData encryptedCert = edGen.generate( + new CMSProcessableCMPCertificate(cert), + new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES192_CBC).setProvider("BC").build()); + + CertificateResponseBuilder certRespBuilder = new CertificateResponseBuilder(senderReqMessage.getCertReqId(), new PKIStatusInfo(PKIStatus.granted)); + + certRespBuilder.withCertificate(encryptedCert); + + CertificateRepMessageBuilder repMessageBuilder = new CertificateRepMessageBuilder(caCert); + + repMessageBuilder.addCertificateResponse(certRespBuilder.build()); + + ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").setProvider("BC").build(dilKp.getPrivate()); + + CertificateRepMessage repMessage = repMessageBuilder.build(); + + ProtectedPKIMessage responsePkixMessage = new ProtectedPKIMessageBuilder(sender, recipient) + .setBody(PKIBody.TYPE_INIT_REP, repMessage) + .build(signer); + + // decrypt the certificate + + assertTrue(responsePkixMessage.verify(new JcaContentVerifierProviderBuilder().build(caCert))); + + CertificateRepMessage certRepMessage = CertificateRepMessage.fromPKIBody(responsePkixMessage.getBody()); + + CertificateResponse certResp = certRepMessage.getResponses()[0]; + + assertEquals(true, certResp.hasEncryptedCertificate()); + + // this is the long-way to decrypt, for testing + CMSEnvelopedData receivedEnvelope = certResp.getEncryptedCertificate(); + RecipientInformationStore recipients = receivedEnvelope.getRecipientInfos(); + Collection c = recipients.getRecipients(); + + assertEquals(1, c.size()); + + RecipientInformation recInfo = (RecipientInformation)c.iterator().next(); + + assertEquals(recInfo.getKeyEncryptionAlgOID(), BCObjectIdentifiers.mceliece348864_r3.getId()); + + // Note: we don't specify the provider here as we're actually using both BC and BCPQC + + byte[] recData = recInfo.getContent(new JceKEMEnvelopedRecipient(hqcKp.getPrivate())); + + assertEquals(true, Arrays.equals(new CMPCertificate(cert.toASN1Structure()).getEncoded(), recData)); + + // this is the preferred way of recovering an encrypted certificate + + CMPCertificate receivedCMPCert = certResp.getCertificate(new JceKEMEnvelopedRecipient(hqcKp.getPrivate())); + + X509CertificateHolder receivedCert = new X509CertificateHolder(receivedCMPCert.getX509v3PKCert()); + + X509CertificateHolder caCertHolder = certRepMessage.getX509Certificates()[0]; + + assertEquals(true, receivedCert.isSignatureValid(new JcaContentVerifierProviderBuilder().build(caCertHolder))); + + // confirmation message calculation + + CertificateConfirmationContent content = new CertificateConfirmationContentBuilder() + .addAcceptedCertificate(cert, BigInteger.ONE) + .build(new JcaDigestCalculatorProviderBuilder().build()); + + ProtectedPKIMessage certConf = new ProtectedPKIMessageBuilder(sender, recipient) + .setBody(PKIBody.TYPE_CERT_CONFIRM, content) + .build(senderMacCalculator); + + assertTrue(content.getStatusMessages()[0].isVerified(receivedCert, new JcaDigestCalculatorProviderBuilder().build())); + assertEquals(PKIBody.TYPE_CERT_CONFIRM, certConf.getBody().getType()); + + // confirmation receiving + + CertificateConfirmationContent recContent = CertificateConfirmationContent.fromPKIBody(certConf.getBody()); + + assertTrue(recContent.getStatusMessages()[0].isVerified(receivedCert, new JcaDigestCalculatorProviderBuilder().build())); + +// JcaPEMWriter pOut = new JcaPEMWriter(new FileWriter("/tmp/cmce_dil_cmp/ca_cert.pem")); +// pOut.writeObject(caCert); +// pOut.close(); +// +// pOut = new JcaPEMWriter(new FileWriter("/tmp/cmce_dil_cmp/cmce_priv.pem")); +// pOut.writeObject(hqcKp.getPrivate()); +// pOut.close(); +// +// pOut = new JcaPEMWriter(new FileWriter("/tmp/cmce_dil_cmp/cmce_cert.pem")); +// pOut.writeObject(cert); +// pOut.close(); +// +// OutputStream fOut = new FileOutputStream("/tmp/cmce_dil_cmp/cmp_message.ir"); +// fOut.write(initMessage.toASN1Structure().getEncoded()); +// fOut.close(); +// +// fOut = new FileOutputStream("/tmp/cmce_dil_cmp/cmp_message.ip"); +// fOut.write(responsePkixMessage.toASN1Structure().getEncoded()); +// fOut.close(); +// +// fOut = new FileOutputStream("/tmp/cmce_dil_cmp/cmp_message.ip"); +// fOut.write(responsePkixMessage.toASN1Structure().getEncoded()); +// fOut.close(); +// +// fOut = new FileOutputStream("/tmp/cmce_dil_cmp/cmp_message.certConf"); +// fOut.write(certConf.toASN1Structure().getEncoded()); +// fOut.close(); +// +// System.err.println(ASN1Dump.dumpAsString(receivedEnvelope.toASN1Structure())); + } + + public void testExternalCMCERequestWithMlDsaCA() + throws Exception + { + char[] senderMacPassword = "secret".toCharArray(); + GeneralName sender = new GeneralName(new X500Name("CN=mceliece3488864 Subject")); + GeneralName recipient = new GeneralName(new X500Name("CN=ML-DSA Issuer")); + + KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("ML-DSA", "BC"); + + dilKpGen.initialize(MLDSAParameterSpec.ml_dsa_44); + + KeyPair dilKp = dilKpGen.generateKeyPair(); + + X509CertificateHolder caCert = makeV3Certificate("CN=ML-DSA Issuer", dilKp); + + KeyPairGenerator cmceKpGen = KeyPairGenerator.getInstance("CMCE", "BCPQC"); + + cmceKpGen.initialize(CMCEParameterSpec.mceliece348864); + + KeyPair hqcKp = cmceKpGen.generateKeyPair(); + + // initial request + + JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigIntegers.ONE); + + certReqBuild + .setPublicKey(hqcKp.getPublic()) + .setSubject(X500Name.getInstance(sender.getName())) + .setProofOfPossessionSubsequentMessage(SubsequentMessage.encrCert); + + CertificateReqMessagesBuilder certReqMsgsBldr = new CertificateReqMessagesBuilder(); + + certReqMsgsBldr.addRequest(certReqBuild.build()); + + MacCalculator senderMacCalculator = new JcePBMac1CalculatorBuilder("HmacSHA256", 256).setProvider("BC").build(senderMacPassword); + + ProtectedPKIMessage initMessage = new ProtectedPKIMessageBuilder(sender, recipient) + .setBody(PKIBody.TYPE_INIT_REQ, certReqMsgsBldr.build()) + .build(senderMacCalculator); + + // extract + + assertTrue(initMessage.getProtectionAlgorithm().equals(senderMacCalculator.getAlgorithmIdentifier())); + + PBEMacCalculatorProvider macCalcProvider = new JcePBMac1CalculatorProviderBuilder().setProvider("BC").build(); + + assertTrue(initMessage.verify(macCalcProvider, senderMacPassword)); + + assertEquals(PKIBody.TYPE_INIT_REQ, initMessage.getBody().getType()); + + CertificateReqMessages requestMessages = CertificateReqMessages.fromPKIBody(initMessage.getBody()); + CertificateRequestMessage senderReqMessage = requestMessages.getRequests()[0]; + CertTemplate certTemplate = senderReqMessage.getCertTemplate(); + + X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=ML-DSA Issuer"); + + // Send response with encrypted certificate + CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); + + // note: use cert req ID as key ID, don't want to use issuer/serial in this case! + + edGen.addRecipientInfoGenerator(new JceKEMRecipientInfoGenerator(senderReqMessage.getCertReqId().getEncoded(), + new JcaX509CertificateConverter().setProvider("BC").getCertificate(cert).getPublicKey(), CMSAlgorithm.AES256_WRAP) + .setKDF(new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256))); + + CMSEnvelopedData encryptedCert = edGen.generate( + new CMSProcessableCMPCertificate(cert), + new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES192_CBC).setProvider("BC").build()); + + CertificateResponseBuilder certRespBuilder = new CertificateResponseBuilder(senderReqMessage.getCertReqId(), new PKIStatusInfo(PKIStatus.granted)); + + certRespBuilder.withCertificate(encryptedCert); + + CertificateRepMessageBuilder repMessageBuilder = new CertificateRepMessageBuilder(caCert); + + repMessageBuilder.addCertificateResponse(certRespBuilder.build()); + + ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").setProvider("BC").build(dilKp.getPrivate()); + + CertificateRepMessage repMessage = repMessageBuilder.build(); + + ProtectedPKIMessage responsePkixMessage = new ProtectedPKIMessageBuilder(sender, recipient) + .setBody(PKIBody.TYPE_INIT_REP, repMessage) + .build(signer); + + // decrypt the certificate + + assertTrue(responsePkixMessage.verify(new JcaContentVerifierProviderBuilder().build(caCert))); + + CertificateRepMessage certRepMessage = CertificateRepMessage.fromPKIBody(responsePkixMessage.getBody()); + + CertificateResponse certResp = certRepMessage.getResponses()[0]; + + assertEquals(true, certResp.hasEncryptedCertificate()); + + // this is the long-way to decrypt, for testing + CMSEnvelopedData receivedEnvelope = certResp.getEncryptedCertificate(); + RecipientInformationStore recipients = receivedEnvelope.getRecipientInfos(); + Collection c = recipients.getRecipients(); + + assertEquals(1, c.size()); + + RecipientInformation recInfo = (RecipientInformation)c.iterator().next(); + + assertEquals(recInfo.getKeyEncryptionAlgOID(), BCObjectIdentifiers.mceliece348864_r3.getId()); + + // Note: we don't specify the provider here as we're actually using both BC and BCPQC + + byte[] recData = recInfo.getContent(new JceKEMEnvelopedRecipient(hqcKp.getPrivate())); + + assertEquals(true, Arrays.equals(new CMPCertificate(cert.toASN1Structure()).getEncoded(), recData)); + + // this is the preferred way of recovering an encrypted certificate + + CMPCertificate receivedCMPCert = certResp.getCertificate(new JceKEMEnvelopedRecipient(hqcKp.getPrivate())); + + X509CertificateHolder receivedCert = new X509CertificateHolder(receivedCMPCert.getX509v3PKCert()); + + X509CertificateHolder caCertHolder = certRepMessage.getX509Certificates()[0]; + + assertEquals(true, receivedCert.isSignatureValid(new JcaContentVerifierProviderBuilder().build(caCertHolder))); + + // confirmation message calculation + + CertificateConfirmationContent content = new CertificateConfirmationContentBuilder() + .addAcceptedCertificate(cert, BigInteger.ONE) + .build(new JcaDigestCalculatorProviderBuilder().build()); + + ProtectedPKIMessage certConf = new ProtectedPKIMessageBuilder(sender, recipient) + .setBody(PKIBody.TYPE_CERT_CONFIRM, content) + .build(senderMacCalculator); + + assertTrue(content.getStatusMessages()[0].isVerified(receivedCert, new JcaDigestCalculatorProviderBuilder().build())); + assertEquals(PKIBody.TYPE_CERT_CONFIRM, certConf.getBody().getType()); + + // confirmation receiving + + CertificateConfirmationContent recContent = CertificateConfirmationContent.fromPKIBody(certConf.getBody()); + + assertTrue(recContent.getStatusMessages()[0].isVerified(receivedCert, new JcaDigestCalculatorProviderBuilder().build())); + + // JcaPEMWriter pOut = new JcaPEMWriter(new FileWriter("/tmp/cmce_dil_cmp/ca_cert.pem")); + // pOut.writeObject(caCert); + // pOut.close(); + // + // pOut = new JcaPEMWriter(new FileWriter("/tmp/cmce_dil_cmp/cmce_priv.pem")); + // pOut.writeObject(hqcKp.getPrivate()); + // pOut.close(); + // + // pOut = new JcaPEMWriter(new FileWriter("/tmp/cmce_dil_cmp/cmce_cert.pem")); + // pOut.writeObject(cert); + // pOut.close(); + // + // OutputStream fOut = new FileOutputStream("/tmp/cmce_dil_cmp/cmp_message.ir"); + // fOut.write(initMessage.toASN1Structure().getEncoded()); + // fOut.close(); + // + // fOut = new FileOutputStream("/tmp/cmce_dil_cmp/cmp_message.ip"); + // fOut.write(responsePkixMessage.toASN1Structure().getEncoded()); + // fOut.close(); + // + // fOut = new FileOutputStream("/tmp/cmce_dil_cmp/cmp_message.ip"); + // fOut.write(responsePkixMessage.toASN1Structure().getEncoded()); + // fOut.close(); + // + // fOut = new FileOutputStream("/tmp/cmce_dil_cmp/cmp_message.certConf"); + // fOut.write(certConf.toASN1Structure().getEncoded()); + // fOut.close(); + // + // System.err.println(ASN1Dump.dumpAsString(receivedEnvelope.toASN1Structure())); + } + private static X509CertificateHolder makeV3Certificate(String _subDN, KeyPair issKP) throws OperatorCreationException, CertException, CertIOException { PrivateKey issPriv = issKP.getPrivate(); - PublicKey issPub = issKP.getPublic(); + PublicKey issPub = issKP.getPublic(); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( new X500Name(_subDN), @@ -433,7 +1124,7 @@ private static X509CertificateHolder makeV3Certificate(String _subDN, KeyPair is certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(0)); - ContentSigner signer = new JcaContentSignerBuilder("Dilithium").build(issPriv); + ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").build(issPriv); X509CertificateHolder certHolder = certGen.build(signer); @@ -448,7 +1139,7 @@ private static X509CertificateHolder makeV3Certificate(SubjectPublicKeyInfo pubK throws OperatorCreationException, CertException, CertIOException { PrivateKey issPriv = issKP.getPrivate(); - PublicKey issPub = issKP.getPublic(); + PublicKey issPub = issKP.getPublic(); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( new X500Name(_issDN), @@ -460,7 +1151,7 @@ private static X509CertificateHolder makeV3Certificate(SubjectPublicKeyInfo pubK certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(false)); - ContentSigner signer = new JcaContentSignerBuilder("Dilithium").build(issPriv); + ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").build(issPriv); X509CertificateHolder certHolder = certGen.build(signer); diff --git a/pkix/src/test/java/org/bouncycastle/cert/cmp/test/TestUtils.java b/pkix/src/test/java/org/bouncycastle/cert/cmp/test/TestUtils.java new file mode 100644 index 0000000000..ca3fa25134 --- /dev/null +++ b/pkix/src/test/java/org/bouncycastle/cert/cmp/test/TestUtils.java @@ -0,0 +1,80 @@ +package org.bouncycastle.cert.cmp.test; + +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.Date; + +import junit.framework.Assert; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.cert.CertException; +import org.bouncycastle.cert.CertIOException; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.ContentVerifierProvider; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; + +class TestUtils +{ + static X509CertificateHolder makeV3Certificate(String _subDN, KeyPair issKP) + throws OperatorCreationException, CertException, CertIOException + { + PrivateKey issPriv = issKP.getPrivate(); + PublicKey issPub = issKP.getPublic(); + + X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( + new X500Name(_subDN), + BigInteger.valueOf(System.currentTimeMillis()), + new Date(System.currentTimeMillis()), + new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), + new X500Name(_subDN), + issKP.getPublic()); + + certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(0)); + + ContentSigner signer = new JcaContentSignerBuilder("SHA256withDSA").build(issPriv); + + X509CertificateHolder certHolder = certGen.build(signer); + + ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().build(issPub); + + Assert.assertTrue(certHolder.isSignatureValid(verifier)); + + return certHolder; + } + + static X509CertificateHolder makeV3Certificate(SubjectPublicKeyInfo pubKey, X500Name _subDN, KeyPair issKP, String _issDN) + throws OperatorCreationException, CertException, CertIOException + { + PrivateKey issPriv = issKP.getPrivate(); + PublicKey issPub = issKP.getPublic(); + + X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( + new X500Name(_issDN), + BigInteger.valueOf(System.currentTimeMillis()), + new Date(System.currentTimeMillis()), + new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), + _subDN, + pubKey); + + certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(false)); + + ContentSigner signer = new JcaContentSignerBuilder("SHA256withDSA").build(issPriv); + + X509CertificateHolder certHolder = certGen.build(signer); + + ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().build(issPub); + + Assert.assertTrue(certHolder.isSignatureValid(verifier)); + + return certHolder; + } +} diff --git a/pkix/src/test/java/org/bouncycastle/cert/crmf/test/AllTests.java b/pkix/src/test/java/org/bouncycastle/cert/crmf/test/AllTests.java index 60e2c8eb86..986b22af36 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/crmf/test/AllTests.java +++ b/pkix/src/test/java/org/bouncycastle/cert/crmf/test/AllTests.java @@ -137,7 +137,7 @@ public void testBasicMessage() JcaCertificateRequestMessage certReqMsg = new JcaCertificateRequestMessage(certReqBuild.build()).setProvider(BC); - POPOSigningKey popoSign = POPOSigningKey.getInstance(certReqMsg.toASN1Structure().getPopo().getObject()); + POPOSigningKey popoSign = POPOSigningKey.getInstance(certReqMsg.toASN1Structure().getPop().getObject()); Signature sig = Signature.getInstance("SHA1withRSA", "BC"); @@ -178,7 +178,7 @@ public void testBasicMessageWithRegInfo() JcaCertificateRequestMessage certReqMsg = new JcaCertificateRequestMessage(certReqBuild.build()).setProvider(BC); - POPOSigningKey popoSign = POPOSigningKey.getInstance(certReqMsg.toASN1Structure().getPopo().getObject()); + POPOSigningKey popoSign = POPOSigningKey.getInstance(certReqMsg.toASN1Structure().getPop().getObject()); Signature sig = Signature.getInstance("SHA1withRSA", "BC"); diff --git a/pkix/src/test/java/org/bouncycastle/cert/ocsp/test/OCSPTest.java b/pkix/src/test/java/org/bouncycastle/cert/ocsp/test/OCSPTest.java index 6e7de684c7..045550f9c1 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/ocsp/test/OCSPTest.java +++ b/pkix/src/test/java/org/bouncycastle/cert/ocsp/test/OCSPTest.java @@ -265,6 +265,52 @@ public class OCSPTest + "ClrcOKZWKOWa14XJy/DJk6nlOiq5W2AglUt8JVOpa5oVdiNRIT2WoGnpqVV9" + "tUeoWog="); + private final byte[] emptyExtResp = Base64.decode( + "MIIHoAoBAKCCB5kwggeVBgkrBgEFBQcwAQEEggeGMIIHgjCCASqhdTBzMS4w" + + "LAYDVQQDDCVFSUQtU0sgMjAxNiBBSUEgT0NTUCBSRVNQT05ERVIgMjAyNDA0" + + "MRcwFQYDVQRhDA5OVFJFRS0xMDc0NzAxMzEbMBkGA1UECgwSU0sgSUQgU29s" + + "dXRpb25zIEFTMQswCQYDVQQGEwJFRRgPMjAyNDA0MDYxODEzMTRaMIGbMIGY" + + "MEkwCQYFKw4DAhoFAAQUBjM3gNZS7ysU/rZfUMZ8XKOlOKEEFJwJqAeHDD2s" + + "Lof8oK7S+2VJiCj7AhBg9KcIpxg1dVqmcEXEfjl8oRYYDzIwMjEwMjA0MDk0" + + "NTE2WqADCgEAGA8yMDI0MDQwNjE4MTMxNFqhIjAgMB4GCSsGAQUFBzABBgQR" + + "GA8yMDE2MDgzMDA5MjEwOVqhAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQB9HmgR" + + "drIde4dYwIBWqO7O7xrDOOb5tWhDaUx/7fv0uo/sQRjoI6Ozi7jSc+RPraEt" + + "bpwr5z91rY83+d8DXp/+2HkH7l/cxNhl87gsRKeif8aNG4dfZqL6DVa9md+v" + + "Cn7fGIhp+14y9aXY2FNOGzwCYQdXIsgXkaeqZ2EXx01XeNDAA1h0uZpud3IH" + + "X3xcrnZiXPDjQQeMtpfw04oLowf3zJ+9vblhQ+qMMn6ii1Kj8YD48pCnNwln" + + "eKGK0EzRAOylbHNeDp8SOy5JoS24IkrfmpfC7fZBp0NQMTUmtUkcusRRlmTw" + + "bmw6fzAFfE4EtFgrtshOMIrAu9GIv05LRJ8moIIFPDCCBTgwggU0MIIDHKAD" + + "AgECAhB3TCdJmp3pTGU3rjXJU+DbMA0GCSqGSIb3DQEBCwUAMGAxCzAJBgNV" + + "BAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRcw" + + "FQYDVQRhDA5OVFJFRS0xMDc0NzAxMzEUMBIGA1UEAwwLRUlELVNLIDIwMTYw" + + "HhcNMjQwMzMxMjEwMDAwWhcNMjQwNTA1MjEwMDAwWjBzMS4wLAYDVQQDDCVF" + + "SUQtU0sgMjAxNiBBSUEgT0NTUCBSRVNQT05ERVIgMjAyNDA0MRcwFQYDVQRh" + + "DA5OVFJFRS0xMDc0NzAxMzEbMBkGA1UECgwSU0sgSUQgU29sdXRpb25zIEFT" + + "MQswCQYDVQQGEwJFRTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB" + + "AL8VN0ssGmHAycQ0GTjHBD0jpl9GmTE/2l5nxxapyeIElh5zbLyqWgiak2Hk" + + "gwmesrNBusWAi9XMk23s/lk3bUrmr4ukvpyv+QjMAtOvO5jnanByjRKzOe5m" + + "Pl6OfGgRqcTmCmjgzN64zPGU35j793gKXGZf351k95sKbc0sj2fLo9Kz5rvt" + + "iA/0I/GJfpMFEfFVVq1D8FQnsSfu1pzzf5hmWQ1OneCLox4vgUk1gEo3mZPO" + + "0S4E6twLw3F+vp9jBaY0uolsyLvx2VwJPIO4ynzO3PvmrdMDHXYnbaJQOlXa" + + "KLK3kwhksyxcvxpWfgOWTrch9Ke+7jeNUEMcj//rm7kCAwEAAaOB1jCB0zAO" + + "BgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwkwHQYDVR0O" + + "BBYEFNnCelaWBINpYLoWlLhh4T5EJTeBMB8GA1UdIwQYMBaAFJwJqAeHDD2s" + + "Lof8oK7S+2VJiCj7MEoGCCsGAQUFBwEBBD4wPDA6BggrBgEFBQcwAoYuaHR0" + + "cHM6Ly9zay5lZS91cGxvYWQvZmlsZXMvRUlELVNLXzIwMTYuZGVyLmNydDAM" + + "BgNVHRMBAf8EAjAAMA8GCSsGAQUFBzABBQQCBQAwDQYJKoZIhvcNAQELBQAD" + + "ggIBAFzysUmbHKAP6aGA3HJt9tLOrP1QoD42A7iSdf/wpewJBtgFM+wK5Z+x" + + "UHkaU316hN18FIOW1uL418+8oK9KU0NRbjNvGBbhNS7yG2bKRknRTCL48iVZ" + + "qGXJVLbO/frx6ZABukmdrzrJZ4MisVlmIBhwNQzJP5QOgq2tj+0/XX0/7N99" + + "dPyoz4SfUIa8Qe5k4GR79k7zvKy75j4kH2CuLuVEfoiHL/s3kwVBX33cIdwO" + + "rbrWViFHnc5ZLk4//d2YYGGWsGgy46s580T7vqu2EAy/NZIyFD+pozPEiiKM" + + "PNwFcYRCODnNZe4p6/anNtBke3ULmepcMs2nUcyM46uBuSLrn3Lj2KgYFboZ" + + "OBiItP+zAp90APq1X+f03vxW1uJp4EwqpPHJiB+9i3I6XpN8CpuTi72uQR1N" + + "bz8XkfajSsGUZK4+jdwYkrdwA6gb5XmLyDnTXPszdfjFhiZ7/PzDdjla1YrM" + + "J3HOcv8B5r5NqESQ+u28xE+LEhS9oJZLQygBOt29KN0Yh6xnN0xfR5iQizv4" + + "GTN6OLdYL7hg6YuCLCuh9Lh/dSGm6GfV2uQ5rjdyJ393VPnV/VuujEc/XIm/" + + "m1YvoDKyP8c2sa0e7/vYiVEJUYSRYPpoBsd1TUJNKpwK1K8O05CVHfmaMJXI" + + "VV46HiaBgBguGWj22+m47TEqOXXQ"); + private static final String BC = "BC"; public String getName() @@ -865,6 +911,16 @@ public void performTest() fail("wrong extension value found."); } + // + // invalid (empty) extension block + // + OCSPResp emptyExt = new OCSPResp(emptyExtResp); + + BasicOCSPResp emptyRes = (BasicOCSPResp)emptyExt.getResponseObject(); + + isTrue(emptyRes.hasExtensions()); + isEquals(0, emptyRes.getExtensionOIDs().size()); + // // request list check // @@ -963,6 +1019,7 @@ public void performTest() public static void main( String[] args) + throws Exception { Security.addProvider(new BouncyCastleProvider()); diff --git a/pkix/src/test/java/org/bouncycastle/cert/ocsp/test/OCSPTestUtil.java b/pkix/src/test/java/org/bouncycastle/cert/ocsp/test/OCSPTestUtil.java index b01d24ad59..fa9c47aacf 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/ocsp/test/OCSPTestUtil.java +++ b/pkix/src/test/java/org/bouncycastle/cert/ocsp/test/OCSPTestUtil.java @@ -23,8 +23,7 @@ import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x509.X509Extensions; -import org.bouncycastle.asn1.x509.X509Name; +import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v1CertificateBuilder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.bc.BcX509ExtensionUtils; @@ -34,30 +33,29 @@ import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.x509.X509V3CertificateGenerator; public class OCSPTestUtil { private static final String BC = "BC"; - public static SecureRandom rand; + public static SecureRandom rand; public static KeyPairGenerator kpg, eckpg; - public static KeyGenerator desede128kg; - public static KeyGenerator desede192kg; - public static KeyGenerator rc240kg; - public static KeyGenerator rc264kg; - public static KeyGenerator rc2128kg; - public static BigInteger serialNumber; - + public static KeyGenerator desede128kg; + public static KeyGenerator desede192kg; + public static KeyGenerator rc240kg; + public static KeyGenerator rc264kg; + public static KeyGenerator rc2128kg; + public static BigInteger serialNumber; + public static final boolean DEBUG = true; - + static { try { rand = new SecureRandom(); - kpg = KeyPairGenerator.getInstance("RSA", "BC"); + kpg = KeyPairGenerator.getInstance("RSA", "BC"); kpg.initialize(1024, rand); serialNumber = new BigInteger("1"); @@ -65,12 +63,12 @@ public class OCSPTestUtil eckpg = KeyPairGenerator.getInstance("ECDSA", "BC"); eckpg.initialize(192, rand); } - catch(Exception ex) + catch (Exception ex) { throw new RuntimeException(ex.toString()); } } - + public static KeyPair makeKeyPair() { return kpg.generateKeyPair(); @@ -102,7 +100,7 @@ public static X509Certificate makeRootCertificate(KeyPair _subKP, String _subDN) public static X509Certificate makeCertificate(KeyPair _subKP, String _subDN, KeyPair _issKP, X509Certificate _issCert, boolean _ca) throws Exception { - org.bouncycastle.asn1.x509.Certificate cert = org.bouncycastle.asn1.x509.Certificate.getInstance(_issCert.getEncoded()); + org.bouncycastle.asn1.x509.Certificate cert = org.bouncycastle.asn1.x509.Certificate.getInstance(_issCert.getEncoded()); ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(_issKP.getPrivate()); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( @@ -127,7 +125,7 @@ public static X509Certificate makeCertificate(KeyPair _subKP, String _subDN, Key public static X509Certificate makeCertificateWithOCSP(KeyPair _subKP, String _subDN, KeyPair _issKP, X509Certificate _issCert, boolean _ca, String uri) throws Exception { - org.bouncycastle.asn1.x509.Certificate cert = org.bouncycastle.asn1.x509.Certificate.getInstance(_issCert.getEncoded()); + org.bouncycastle.asn1.x509.Certificate cert = org.bouncycastle.asn1.x509.Certificate.getInstance(_issCert.getEncoded()); ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(_issKP.getPrivate()); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( @@ -148,7 +146,7 @@ public static X509Certificate makeCertificateWithOCSP(KeyPair _subKP, String _su certGen.addExtension( Extension.authorityInfoAccess, false, new AuthorityInformationAccess(new AccessDescription(AccessDescription.id_ad_ocsp, - new GeneralName(GeneralName.uniformResourceIdentifier, uri)))); + new GeneralName(GeneralName.uniformResourceIdentifier, uri)))); return new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); } @@ -156,7 +154,7 @@ Extension.authorityInfoAccess, false, new AuthorityInformationAccess(new AccessD public static X509Certificate makeCertificate(KeyPair _subKP, String _subDN, KeyPair _issKP, X509Certificate _issCert, KeyPurposeId keyPurpose) throws Exception { - org.bouncycastle.asn1.x509.Certificate cert = org.bouncycastle.asn1.x509.Certificate.getInstance(_issCert.getEncoded()); + org.bouncycastle.asn1.x509.Certificate cert = org.bouncycastle.asn1.x509.Certificate.getInstance(_issCert.getEncoded()); ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(_issKP.getPrivate()); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( @@ -182,96 +180,86 @@ public static X509Certificate makeCertificate(KeyPair _subKP, String _subDN, Key } public static X509Certificate makeECDSACertificate(KeyPair _subKP, - String _subDN, KeyPair _issKP, String _issDN) - throws Exception + String _subDN, KeyPair _issKP, String _issDN) + throws Exception { - return makeECDSACertificate(_subKP, _subDN, _issKP, _issDN, false); } public static X509Certificate makeCACertificate(KeyPair _subKP, - String _subDN, KeyPair _issKP, String _issDN) - throws Exception + String _subDN, KeyPair _issKP, String _issDN) + throws Exception { return makeCertificate(_subKP, _subDN, _issKP, _issDN, true); } public static X509Certificate makeCertificate(KeyPair _subKP, - String _subDN, KeyPair _issKP, String _issDN, boolean _ca) - throws Exception + String _subDN, KeyPair _issKP, String _issDN, boolean _ca) + throws Exception { - return makeCertificate(_subKP,_subDN, _issKP, _issDN, "SHA1withRSA", _ca); + return makeCertificate(_subKP, _subDN, _issKP, _issDN, "SHA1withRSA", _ca); } public static X509Certificate makeECDSACertificate(KeyPair _subKP, - String _subDN, KeyPair _issKP, String _issDN, boolean _ca) - throws Exception + String _subDN, KeyPair _issKP, String _issDN, boolean _ca) + throws Exception { - return makeCertificate(_subKP,_subDN, _issKP, _issDN, "SHA1WithECDSA", _ca); + return makeCertificate(_subKP, _subDN, _issKP, _issDN, "SHA1WithECDSA", _ca); } public static X509Certificate makeCertificate(KeyPair _subKP, - String _subDN, KeyPair _issKP, String _issDN) - throws Exception + String _subDN, KeyPair _issKP, String _issDN) + throws Exception { return makeCertificate(_subKP, _subDN, _issKP, _issDN, "SHA1withRSA", false); } public static X509Certificate makeCertificate(KeyPair _subKP, - String _subDN, KeyPair _issKP, String _issDN, String algorithm, boolean _ca) - throws Exception + String _subDN, KeyPair _issKP, String _issDN, String algorithm, boolean _ca) + throws Exception { PublicKey _subPub = _subKP.getPublic(); PrivateKey _issPriv = _issKP.getPrivate(); PublicKey _issPub = _issKP.getPublic(); - X509V3CertificateGenerator _v3CertGen = new X509V3CertificateGenerator(); - - _v3CertGen.reset(); - _v3CertGen.setSerialNumber(allocateSerialNumber()); - _v3CertGen.setIssuerDN(new X509Name(_issDN)); - _v3CertGen.setNotBefore(new Date(System.currentTimeMillis())); - _v3CertGen.setNotAfter(new Date(System.currentTimeMillis() - + (1000L * 60 * 60 * 24 * 100))); - _v3CertGen.setSubjectDN(new X509Name(_subDN)); - _v3CertGen.setPublicKey(_subPub); - _v3CertGen.setSignatureAlgorithm(algorithm); - - _v3CertGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, - createSubjectKeyId(_subPub)); - - _v3CertGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, - createAuthorityKeyId(_issPub)); - - _v3CertGen.addExtension(X509Extensions.BasicConstraints, false, - new BasicConstraints(_ca)); + JcaX509ExtensionUtils x509Utils = new JcaX509ExtensionUtils(); - X509Certificate _cert = _v3CertGen.generate(_issPriv); + X509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder( + new X500Name(_issDN), + allocateSerialNumber(), + new Date(System.currentTimeMillis()), + new Date(System.currentTimeMillis() + + (1000L * 60 * 60 * 24 * 100)), + new X500Name(_subDN), + _subPub + ) + .addExtension(Extension.subjectKeyIdentifier, false, x509Utils.createSubjectKeyIdentifier(_subPub)) + .addExtension(Extension.authorityKeyIdentifier, false, x509Utils.createAuthorityKeyIdentifier(_issPub)) + .addExtension(Extension.basicConstraints, false, new BasicConstraints(_ca)); - _cert.checkValidity(new Date()); - _cert.verify(_issPub); + X509CertificateHolder ch = builder.build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(_issPriv)); - return _cert; + return new JcaX509CertificateConverter().setProvider(BC).getCertificate(ch); } /* - * + * * INTERNAL METHODS - * + * */ private static AuthorityKeyIdentifier createAuthorityKeyId(PublicKey _pubKey) - throws IOException + throws IOException { SubjectPublicKeyInfo _info = SubjectPublicKeyInfo.getInstance(_pubKey.getEncoded()); - return new AuthorityKeyIdentifier(_info); + return new BcX509ExtensionUtils().createAuthorityKeyIdentifier(_info); } private static SubjectKeyIdentifier createSubjectKeyId(PublicKey _pubKey) - throws IOException + throws IOException { return new BcX509ExtensionUtils().createSubjectKeyIdentifier(SubjectPublicKeyInfo.getInstance(_pubKey.getEncoded())); } diff --git a/pkix/src/test/java/org/bouncycastle/cert/path/test/PKITSBasicConstraintsTest.java b/pkix/src/test/java/org/bouncycastle/cert/path/test/PKITSBasicConstraintsTest.java index b2ac697775..c3ebbba4c1 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/path/test/PKITSBasicConstraintsTest.java +++ b/pkix/src/test/java/org/bouncycastle/cert/path/test/PKITSBasicConstraintsTest.java @@ -15,6 +15,7 @@ import org.bouncycastle.cert.path.validations.KeyUsageValidation; import org.bouncycastle.cert.path.validations.ParentCertIssuedValidation; import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.test.TestResourceFinder; import org.bouncycastle.util.test.SimpleTest; public class PKITSBasicConstraintsTest @@ -30,8 +31,7 @@ public String getName() private static X509CertificateHolder readPKITSCert(String fileName) throws IOException { - Class l = PKITSBasicConstraintsTest.class; - ASN1InputStream asn1In = new ASN1InputStream(l.getResourceAsStream(PKITS_DATA_RESOURCE_PREFIX + fileName)); + ASN1InputStream asn1In = new ASN1InputStream(TestResourceFinder.findTestResource(PKITS_DATA_RESOURCE_PREFIX, fileName)); return new X509CertificateHolder(Certificate.getInstance(asn1In.readObject())); } diff --git a/pkix/src/test/java/org/bouncycastle/cert/test/AttrCertSelectorTest.java b/pkix/src/test/java/org/bouncycastle/cert/test/AttrCertSelectorTest.java index 3fe3694db1..fb18e35613 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/test/AttrCertSelectorTest.java +++ b/pkix/src/test/java/org/bouncycastle/cert/test/AttrCertSelectorTest.java @@ -14,10 +14,10 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.Target; import org.bouncycastle.asn1.x509.TargetInformation; -import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.cert.AttributeCertificateHolder; import org.bouncycastle.cert.AttributeCertificateIssuer; import org.bouncycastle.cert.X509AttributeCertificateHolder; @@ -152,7 +152,7 @@ private X509AttributeCertificateHolder createAttrCert() throws Exception targets[1] = targetGroup; TargetInformation targetInformation = new TargetInformation(targets); - gen.addExtension(X509Extension.targetInformation, true, targetInformation); + gen.addExtension(Extension.targetInformation, true, targetInformation); return gen.build(sigGen); } diff --git a/pkix/src/test/java/org/bouncycastle/cert/test/BcCertTest.java b/pkix/src/test/java/org/bouncycastle/cert/test/BcCertTest.java index b0c1d4ae45..249b56f190 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/test/BcCertTest.java +++ b/pkix/src/test/java/org/bouncycastle/cert/test/BcCertTest.java @@ -18,11 +18,11 @@ import java.util.Set; import junit.framework.TestCase; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; @@ -499,7 +499,7 @@ public void checkKeyUsage( X509CertificateHolder certHld = new X509CertificateHolder(bytes); - if ((DERBitString.getInstance(certHld.getExtension(Extension.keyUsage).getParsedValue()).getBytes()[0] & 0x01) != 0) + if ((ASN1BitString.getInstance(certHld.getExtension(Extension.keyUsage).getParsedValue()).getBytes()[0] & 0x01) != 0) { fail("error generating cert - key usage wrong."); } diff --git a/pkix/src/test/java/org/bouncycastle/cert/test/CertTest.java b/pkix/src/test/java/org/bouncycastle/cert/test/CertTest.java index 81a078ad68..340971b99e 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/test/CertTest.java +++ b/pkix/src/test/java/org/bouncycastle/cert/test/CertTest.java @@ -3,6 +3,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; @@ -102,9 +103,11 @@ import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.jcajce.CompositePrivateKey; import org.bouncycastle.jcajce.CompositePublicKey; +import org.bouncycastle.jcajce.provider.asymmetric.compositesignatures.CompositeSignaturesConstants; import org.bouncycastle.jcajce.spec.CompositeAlgorithmSpec; +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; +import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec; import org.bouncycastle.jce.X509KeyUsage; -import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; @@ -113,6 +116,7 @@ import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; @@ -133,6 +137,7 @@ import org.bouncycastle.pqc.jcajce.spec.SPHINCSPlusParameterSpec; import org.bouncycastle.pqc.jcajce.spec.XMSSMTParameterSpec; import org.bouncycastle.pqc.jcajce.spec.XMSSParameterSpec; +import org.bouncycastle.test.TestResourceFinder; import org.bouncycastle.util.Encodable; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Base64; @@ -1361,8 +1366,6 @@ public void checkCertificate( Certificate cert = fact.generateCertificate(bIn); PublicKey k = cert.getPublicKey(); -// System.out.println("****** " + id + " ******"); -// System.out.println(cert); } catch (Exception e) { @@ -1461,7 +1464,6 @@ public void checkKeyUsage( } - public void checkSelfSignedCertificate( int id, byte[] bytes) @@ -2092,14 +2094,14 @@ public void checkCreation3() fail("error setting generating cert - " + e); } - X509Principal pr = new X509Principal("O=\"The Bouncy Castle, The Legion of\",E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); + X500Name pr = new X500Name("O=\"The Bouncy Castle, The Legion of\",E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { fail("string based X509Principal test failed."); } - pr = new X509Principal("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); + pr = new X500Name("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) { @@ -2515,6 +2517,16 @@ public void checkCRLCreation2() { fail("CRL entry reasonCode not found"); } + + crlGen = new X509v2CRLBuilder(crlHolder); + + crlGen.setThisUpdate(new Date(crlHolder.getThisUpdate().getTime() + 50000)); + crlGen.setNextUpdate(new Date(crlHolder.getNextUpdate().getTime() + 100000)); + + X509CRLHolder hldr2 = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate())); + + isEquals(hldr2.getThisUpdate().getTime(), crlHolder.getThisUpdate().getTime() + 50000); + isEquals(hldr2.getNextUpdate().getTime(), crlHolder.getNextUpdate().getTime() + 100000); } public void checkCRLCreation3() @@ -2871,7 +2883,7 @@ public void checkCRLCompositeCreation() // // set up the keys // - KeyPairGenerator ecKpg = KeyPairGenerator.getInstance("EC", "BC"); + KeyPairGenerator ecKpg = KeyPairGenerator.getInstance("EC", BC); ecKpg.initialize(new ECGenParameterSpec("P-256")); @@ -2904,7 +2916,7 @@ public void checkCRLCompositeCreation() CompositePublicKey compPub = new CompositePublicKey(ecPub, lmsPub); CompositePrivateKey compPrivKey = new CompositePrivateKey(ecPriv, lmsPriv); - ContentSigner sigGen = new JcaContentSignerBuilder("Composite", compAlgSpec).build(compPrivKey); + ContentSigner sigGen = new JcaContentSignerBuilder("Composite", compAlgSpec).setProvider(BC).build(compPrivKey); Date now = new Date(); @@ -2945,13 +2957,13 @@ public void checkCRLCompositeCreation() // null comp test try { - crl.verify(new CompositePublicKey(null, null)); + crl.verify(new CompositePublicKey(new PublicKey[]{null, null})); } catch (InvalidKeyException e) { isTrue(e.getMessage().equals("no matching key found")); } - + // single key test crl.verify(ecPub, BC); @@ -3002,7 +3014,7 @@ public void checkCRLCompositeCreation() fail("CRL entry reasonCode not found"); } - sigGen = new JcaContentSignerBuilder("SHA256withECDSA", compAlgSpec).build(compPrivKey); + sigGen = new JcaContentSignerBuilder("SHA256withECDSA", compAlgSpec).setProvider(BC).build(compPrivKey); crlHolder = crlGen.build(sigGen); @@ -3018,7 +3030,7 @@ public void checkCrlECDSAwithDilithiumCreation() // // set up the keys // - KeyPairGenerator ecKpg = KeyPairGenerator.getInstance("EC", "BC"); + KeyPairGenerator ecKpg = KeyPairGenerator.getInstance("EC", BC); ecKpg.initialize(new ECGenParameterSpec("P-256")); @@ -3027,9 +3039,9 @@ public void checkCrlECDSAwithDilithiumCreation() PrivateKey ecPriv = ecKp.getPrivate(); PublicKey ecPub = ecKp.getPublic(); - KeyPairGenerator dlKpg = KeyPairGenerator.getInstance("Dilithium2", "BCPQC"); + KeyPairGenerator dlKpg = KeyPairGenerator.getInstance("ML-DSA", "BC"); - dlKpg.initialize(DilithiumParameterSpec.dilithium2); + dlKpg.initialize(MLDSAParameterSpec.ml_dsa_44); KeyPair dlKp = dlKpg.generateKeyPair(); @@ -3044,8 +3056,8 @@ public void checkCrlECDSAwithDilithiumCreation() // // create the CRL - version 2 // - ContentSigner sigGen = new JcaContentSignerBuilder("SHA256withECDSA").setProvider("BC").build(ecPriv); - ContentSigner altSigGen = new JcaContentSignerBuilder("Dilithium2").setProvider("BCPQC").build(dlPriv); + ContentSigner sigGen = new JcaContentSignerBuilder("SHA256withECDSA").setProvider(BC).build(ecPriv); + ContentSigner altSigGen = new JcaContentSignerBuilder("ML-DSA-44").setProvider("BC").build(dlPriv); Date now = new Date(); @@ -3085,8 +3097,8 @@ public void checkCrlECDSAwithDilithiumCreation() // verify with provider crl.verify(ecPub, BC); - isTrue("crl primary failed", crlHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(ecPub))); - isTrue("crl secondary failed", crlHolder.isAlternativeSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BCPQC").build(dlPub))); + isTrue("crl primary failed", crlHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(ecPub))); + isTrue("crl secondary failed", crlHolder.isAlternativeSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(dlPub))); if (!crl.getIssuerX500Principal().equals(new X500Principal("CN=Test CA"))) { @@ -3609,9 +3621,9 @@ public void checkCreationSPHINCSPlus() // // set up the keys // - KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", BC); - kpg.initialize(SPHINCSPlusParameterSpec.sha2_256f, new SecureRandom()); + kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_256f, new SecureRandom()); KeyPair kp = kpg.generateKeyPair(); @@ -3626,7 +3638,58 @@ public void checkCreationSPHINCSPlus() // // create the certificate - version 3 // - ContentSigner sigGen = new JcaContentSignerBuilder(pubKey.getAlgorithm()).setProvider("BCPQC").build(privKey); + ContentSigner sigGen = new JcaContentSignerBuilder(pubKey.getAlgorithm()).setProvider(BC).build(privKey); + X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), pubKey); + + X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); + + cert.checkValidity(new Date()); + + // + // check verifies in general + // + cert.verify(pubKey); + + // + // check verifies with contained key + // + cert.verify(cert.getPublicKey()); + + ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded()); + CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); + + cert = (X509Certificate)fact.generateCertificate(bIn); + + //System.out.println(cert); + } + + /* + * we generate a self signed certificate for the sake of testing - SPHINCSPlus + */ + public void checkCreationSPHINCSPlusSimple() + throws Exception + { + // + // set up the keys + // + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", BC); + + kpg.initialize(SPHINCSPlusParameterSpec.haraka_128f, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + PrivateKey privKey = kp.getPrivate(); + PublicKey pubKey = kp.getPublic(); + + // + // distinguished name table. + // + X500NameBuilder builder = createStdBuilder(); + + // + // create the certificate - version 3 + // + ContentSigner sigGen = new JcaContentSignerBuilder(pubKey.getAlgorithm()).setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); @@ -3871,7 +3934,7 @@ public void checkCreationRSAPSS() // // set up the keys // - KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSASSA-PSS", "BC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSASSA-PSS", BC); KeyPair kp = kpg.generateKeyPair(); @@ -3886,7 +3949,7 @@ public void checkCreationRSAPSS() // // create the certificate - version 3 // - ContentSigner sigGen = new JcaContentSignerBuilder("SHA256withRSAandMGF1").setProvider("BC").build(privKey); + ContentSigner sigGen = new JcaContentSignerBuilder("SHA256withRSAandMGF1").setProvider(BC).build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), pubKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); @@ -3969,7 +4032,7 @@ public void checkCreationECDSA() } public void checkCreationPicnic() - throws Exception + throws Exception { if (Security.getProvider("BCPQC") == null) { @@ -3995,12 +4058,12 @@ public void checkCreationPicnic() // ContentSigner sigGen = new JcaContentSignerBuilder("PICNIC").setProvider("BCPQC").build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), pubKey) - .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, - new X509KeyUsage(X509KeyUsage.encipherOnly)) - .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, - new DERSequence(KeyPurposeId.anyExtendedKeyUsage)) - .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, - new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); + .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, + new X509KeyUsage(X509KeyUsage.encipherOnly)) + .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, + new DERSequence(KeyPurposeId.anyExtendedKeyUsage)) + .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true, + new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test"))); X509Certificate baseCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); @@ -4012,8 +4075,8 @@ public void checkCreationPicnic() // certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), pubKey) - .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, baseCert) - .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.37"), false, baseCert); + .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, baseCert) + .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.37"), false, baseCert); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); @@ -4057,8 +4120,8 @@ public void checkCreationPicnic() KeyPair nhKp = kpGen.generateKeyPair(); certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), nhKp.getPublic()) - .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, baseCert) - .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.37"), false, baseCert); + .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, baseCert) + .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.37"), false, baseCert); cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); @@ -4190,9 +4253,9 @@ public void checkCreationDilithium() Security.addProvider(new BouncyCastlePQCProvider()); } - KeyPairGenerator kpGen = KeyPairGenerator.getInstance("Dilithium", "BCPQC"); + KeyPairGenerator kpGen = KeyPairGenerator.getInstance("ML-DSA-65", "BC"); - kpGen.initialize(DilithiumParameterSpec.dilithium2, new SecureRandom()); + kpGen.initialize(MLDSAParameterSpec.ml_dsa_65, new SecureRandom()); KeyPair kp = kpGen.generateKeyPair(); @@ -4207,7 +4270,7 @@ public void checkCreationDilithium() // // create base certificate - version 3 // - ContentSigner sigGen = new JcaContentSignerBuilder("Dilithium2").setProvider("BCPQC").build(privKey); + ContentSigner sigGen = new JcaContentSignerBuilder("ML-DSA-65").setProvider("BC").build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), @@ -4222,9 +4285,9 @@ public void checkCreationDilithium() X509Certificate baseCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen)); - isTrue("oid wrong", BCObjectIdentifiers.dilithium2.getId().equals(baseCert.getSigAlgOID())); + isTrue("oid wrong", NISTObjectIdentifiers.id_ml_dsa_65.getId().equals(baseCert.getSigAlgOID())); isTrue("params wrong", null == baseCert.getSigAlgParams()); - + // // copy certificate // @@ -4239,7 +4302,7 @@ public void checkCreationDilithium() cert.verify(cert.getPublicKey()); - isEquals("name mismatch: " + cert.getSigAlgName(), "DILITHIUM2", cert.getSigAlgName()); + isEquals("name mismatch: " + cert.getSigAlgName(), "ML-DSA-65", cert.getSigAlgName()); // check encoded works cert.getEncoded(); @@ -4309,7 +4372,7 @@ public void checkCreationDilithiumWithECDSA() PrivateKey privKey = kp.getPrivate(); PublicKey pubKey = kp.getPublic(); - KeyPairGenerator ecKpGen = KeyPairGenerator.getInstance("EC", "BC"); + KeyPairGenerator ecKpGen = KeyPairGenerator.getInstance("EC", BC); ecKpGen.initialize(new ECNamedCurveGenParameterSpec("P-256"), new SecureRandom()); @@ -4326,7 +4389,7 @@ public void checkCreationDilithiumWithECDSA() // // create base certificate - version 3 // - ContentSigner sigGen = new JcaContentSignerBuilder("SHA256withECDSA").setProvider("BC").build(ecPrivKey); + ContentSigner sigGen = new JcaContentSignerBuilder("SHA256withECDSA").setProvider(BC).build(ecPrivKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), @@ -4354,7 +4417,7 @@ public void checkCreationDilithiumWithECDSA() cert.verify(cert.getPublicKey()); isEquals("name mismatch: " + cert.getSigAlgName(), "SHA256WITHECDSA", cert.getSigAlgName()); - + // check encoded works cert.getEncoded(); @@ -4371,16 +4434,16 @@ public void checkCreationDilithiumSigWithECDSASig() Security.addProvider(new BouncyCastlePQCProvider()); } - KeyPairGenerator kpGen = KeyPairGenerator.getInstance("Dilithium", "BCPQC"); + KeyPairGenerator kpGen = KeyPairGenerator.getInstance("ML-DSA", "BC"); - kpGen.initialize(DilithiumParameterSpec.dilithium2, new SecureRandom()); + kpGen.initialize(MLDSAParameterSpec.ml_dsa_44, new SecureRandom()); KeyPair kp = kpGen.generateKeyPair(); PrivateKey privKey = kp.getPrivate(); PublicKey pubKey = kp.getPublic(); - KeyPairGenerator ecKpGen = KeyPairGenerator.getInstance("EC", "BC"); + KeyPairGenerator ecKpGen = KeyPairGenerator.getInstance("EC", BC); ecKpGen.initialize(new ECNamedCurveGenParameterSpec("P-256"), new SecureRandom()); @@ -4397,9 +4460,9 @@ public void checkCreationDilithiumSigWithECDSASig() // // create base certificate - version 3 // - ContentSigner sigGen = new JcaContentSignerBuilder("SHA256withECDSA").setProvider("BC").build(ecPrivKey); + ContentSigner sigGen = new JcaContentSignerBuilder("SHA256withECDSA").setProvider(BC).build(ecPrivKey); - ContentSigner altSigGen = new JcaContentSignerBuilder("Dilithium2").setProvider("BCPQC").build(privKey); + ContentSigner altSigGen = new JcaContentSignerBuilder("ML-DSA-44").setProvider("BC").build(privKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( builder.build(), BigInteger.valueOf(1), @@ -4437,7 +4500,7 @@ public void checkCreationDilithiumSigWithECDSASig() isTrue("alt sig alg wrong", AltSignatureAlgorithm.fromExtensions(certHolder.getExtensions()).equals(altSigGen.getAlgorithmIdentifier())); isTrue("alt key wrong", SubjectAltPublicKeyInfo.fromExtensions(certHolder.getExtensions()).equals(ASN1Primitive.fromByteArray(pubKey.getEncoded()))); - isTrue("alt sig value wrong", certHolder.isAlternativeSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BCPQC").build(pubKey))); + isTrue("alt sig value wrong", certHolder.isAlternativeSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(pubKey))); } public void checkCreationComposite() @@ -4446,7 +4509,7 @@ public void checkCreationComposite() // // set up the keys // - KeyPairGenerator ecKpg = KeyPairGenerator.getInstance("EC", "BC"); + KeyPairGenerator ecKpg = KeyPairGenerator.getInstance("EC", BC); ecKpg.initialize(new ECGenParameterSpec("P-256")); @@ -4481,7 +4544,7 @@ public void checkCreationComposite() CompositePublicKey compPub = new CompositePublicKey(ecPub, lmsPub); CompositePrivateKey compPrivKey = new CompositePrivateKey(ecPriv, lmsPriv); - ContentSigner sigGen = new JcaContentSignerBuilder("Composite", compAlgSpec).build(compPrivKey); + ContentSigner sigGen = new JcaContentSignerBuilder("Composite", compAlgSpec).setProvider(BC).build(compPrivKey); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( issuer, @@ -4492,11 +4555,13 @@ public void checkCreationComposite() X509CertificateHolder certHldr = certGen.build(sigGen); ContentVerifierProvider vProv = new JcaContentVerifierProviderBuilder() + .setProvider(BC) .build(compPub); isTrue("multi failed", certHldr.isSignatureValid(vProv)); vProv = new JcaContentVerifierProviderBuilder() + .setProvider(BC) .build(new CompositePublicKey(ecPub, null)); isTrue("multi failed with null", certHldr.isSignatureValid(vProv)); @@ -4505,7 +4570,8 @@ public void checkCreationComposite() try { vProv = new JcaContentVerifierProviderBuilder() - .build(new CompositePublicKey(null, null)); + .setProvider(BC) + .build(new CompositePublicKey(new PublicKey[]{null, null})); certHldr.isSignatureValid(vProv); } @@ -4514,11 +4580,11 @@ public void checkCreationComposite() isTrue(e.getCause().getMessage().equals("no matching signature found in composite")); } - vProv = new JcaContentVerifierProviderBuilder().build(ecPub); + vProv = new JcaContentVerifierProviderBuilder().setProvider(BC).build(ecPub); isTrue("ec failed", certHldr.isSignatureValid(vProv)); - vProv = new JcaContentVerifierProviderBuilder().build(lmsPub); + vProv = new JcaContentVerifierProviderBuilder().setProvider(BC).build(lmsPub); isTrue("lms failed", certHldr.isSignatureValid(vProv)); @@ -4534,7 +4600,7 @@ public void checkCreationComposite() // null comp test try { - cert.verify(new CompositePublicKey(null, null)); + cert.verify(new CompositePublicKey(new PublicKey[]{null, null})); } catch (InvalidKeyException e) { @@ -4545,13 +4611,16 @@ public void checkCreationComposite() cert.verify(lmsPub); // lms key only - cert.verify(ecPub, "BC"); // ec key only + cert.verify(ecPub, BC); // ec key only cert.verify(lmsPub, "BCPQC"); // lms key only - cert.verify(ecPub, new BouncyCastleProvider()); // ec key only + if (System.getProperty("java.version").indexOf("1.5.") < 0) + { + cert.verify(ecPub, new BouncyCastleProvider()); // ec key only - cert.verify(lmsPub, new BouncyCastlePQCProvider()); // lms key only + cert.verify(lmsPub, new BouncyCastlePQCProvider()); // lms key only + } // // check verifies with contained key @@ -4570,7 +4639,7 @@ public void checkCreationComposite() isTrue(MiscObjectIdentifiers.id_composite_key.equals(crt.getSubjectPublicKeyInfo().getAlgorithm().getAlgorithm())); isTrue(null == crt.getSubjectPublicKeyInfo().getAlgorithm().getParameters()); - KeyFactory kFact = KeyFactory.getInstance("Composite", "BC"); + KeyFactory kFact = KeyFactory.getInstance("Composite", BC); CompositePublicKey pubKey = (CompositePublicKey)kFact.generatePublic(new X509EncodedKeySpec(compPub.getEncoded())); CompositePrivateKey privKey = (CompositePrivateKey)kFact.generatePrivate(new PKCS8EncodedKeySpec(compPrivKey.getEncoded())); @@ -4585,7 +4654,7 @@ private void checkCompositeCertificateVerify() // // set up the keys // - KeyPairGenerator ecKpg = KeyPairGenerator.getInstance("EC", "BC"); + KeyPairGenerator ecKpg = KeyPairGenerator.getInstance("EC", BC); ecKpg.initialize(new ECGenParameterSpec("P-256")); @@ -4650,9 +4719,12 @@ private void checkCompositeCertificateVerify() cert.verify(ecPub); // ec key only - cert.verify(ecPub, "BC"); // ec key only + cert.verify(ecPub, BC); // ec key only - cert.verify(ecPub, new BouncyCastleProvider()); // ec key only + if (System.getProperty("java.version").indexOf("1.5.") < 0) + { + cert.verify(ecPub, new BouncyCastleProvider()); // ec key only + } // // check verifies with contained key @@ -4669,7 +4741,7 @@ private void checkCompositeCertificateVerify() isTrue(MiscObjectIdentifiers.id_composite_key.equals(crt.getSubjectPublicKeyInfo().getAlgorithm().getAlgorithm())); isTrue(null == crt.getSubjectPublicKeyInfo().getAlgorithm().getParameters()); - KeyFactory kFact = KeyFactory.getInstance("Composite", "BC"); + KeyFactory kFact = KeyFactory.getInstance("Composite", BC); CompositePublicKey pubKey = (CompositePublicKey)kFact.generatePublic(new X509EncodedKeySpec(compPub.getEncoded())); CompositePrivateKey privKey = (CompositePrivateKey)kFact.generatePrivate(new PKCS8EncodedKeySpec(compPrivKey.getEncoded())); @@ -4999,7 +5071,7 @@ private void testNullDerNullCert() X509CertificateHolder x509CertHldr = new JcaX509CertificateHolder(cert); x509CertHldr.isSignatureValid(new JcaContentVerifierProviderBuilder() - .setProvider("BC").build(cert)); + .setProvider(BC).build(cert)); fail("no exception - CertHolder"); } catch (CertException e) @@ -5014,7 +5086,7 @@ private void testNullDerNullCert() X509CertificateHolder x509CertHldr = new JcaX509CertificateHolder(cert); x509CertHldr.isSignatureValid(new JcaContentVerifierProviderBuilder() - .setProvider("BC").build(cert)); + .setProvider(BC).build(cert)); } catch (Exception e) { @@ -5349,6 +5421,148 @@ private void checkSerialisation() doSerialize(attrHolder); } + // TESTS REGARDING COMPOSITES https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html + private static String[] compositeSignaturesOIDs = { + "2.16.840.1.114027.80.8.1.1", //id-MLDSA44-RSA2048-PSS-SHA256 + "2.16.840.1.114027.80.8.1.2", //id-MLDSA44-RSA2048-PKCS15-SHA256 + "2.16.840.1.114027.80.8.1.3", //id-MLDSA44-Ed25519-SHA512 + "2.16.840.1.114027.80.8.1.4", //id-MLDSA44-ECDSA-P256-SHA256 + "2.16.840.1.114027.80.8.1.5", //id-MLDSA44-ECDSA-brainpoolP256r1-SHA256 + "2.16.840.1.114027.80.8.1.6", //id-MLDSA65-RSA3072-PSS-SHA512 + "2.16.840.1.114027.80.8.1.7", //id-MLDSA65-RSA3072-PKCS15-SHA512 + "2.16.840.1.114027.80.8.1.8", //id-MLDSA65-ECDSA-P256-SHA512 + "2.16.840.1.114027.80.8.1.9", //id-MLDSA65-ECDSA-brainpoolP256r1-SHA512 + "2.16.840.1.114027.80.8.1.10", //id-MLDSA65-Ed25519-SHA512 + "2.16.840.1.114027.80.8.1.11", //id-MLDSA87-ECDSA-P384-SHA512 + "2.16.840.1.114027.80.8.1.12", //id-MLDSA87-ECDSA-brainpoolP384r1-SHA512 + "2.16.840.1.114027.80.8.1.13", //id-MLDSA87-Ed448-SHA512 + // Falcon composites below were excluded from the draft. See MiscObjectIdentifiers for details. + "2.16.840.1.114027.80.8.1.14", //id-Falcon512-ECDSA-P256-SHA256 + "2.16.840.1.114027.80.8.1.15", //id-Falcon512-ECDSA-brainpoolP256r1-SHA256 + "2.16.840.1.114027.80.8.1.16", //id-Falcon512-Ed25519-SHA512 + }; + + private static String[] compositeSignaturesIDs = { + "MLDSA44-RSA2048-PSS-SHA256", + "MLDSA44-RSA2048-PKCS15-SHA256", + "MLDSA44-ED25519-SHA512", + "MLDSA44-ECDSA-P256-SHA256", + "MLDSA44-ECDSA-BRAINPOOLP256R1-SHA256", + "MLDSA65-RSA3072-PSS-SHA512", + "MLDSA65-RSA3072-PKCS15-SHA512", + "MLDSA65-ECDSA-P256-SHA512", + "MLDSA65-ECDSA-BRAINPOOLP256R1-SHA512", + "MLDSA65-ED25519-SHA512", + "MLDSA87-ECDSA-P384-SHA512", + "MLDSA87-ECDSA-BRAINPOOLP384R1-SHA512", + "MLDSA87-ED448-SHA512", + "FALCON512-ECDSA-P256-SHA256", + "FALCON512-ECDSA-BRAINPOOLP256R1-SHA256", + "FALCON512-ED25519-SHA512" + }; + + private void checkCompositeSignatureCertificateCreation() + throws Exception + { + int index = 0; + for (String oid : compositeSignaturesOIDs) + { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(oid, "BC"); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + + String subjectName = "CN=ROOT CA"; + X500Name issuer = new X500Name(subjectName); + BigInteger serial = BigInteger.valueOf(5); + Date notBefore = new Date(); + Date notAfter = new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 365L); + X500Name subject = new X500Name(subjectName); + + JcaX509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(issuer, serial, notBefore, notAfter, subject, keyPair.getPublic()); + X509CertificateHolder certHolder = certificateBuilder.build(new JcaContentSignerBuilder(compositeSignaturesIDs[index]).build(keyPair.getPrivate())); + X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder); + + isEquals(oid, cert.getSigAlgOID()); + CompositePublicKey compositePublicKey = (CompositePublicKey)cert.getPublicKey(); + + isEquals(CompositeSignaturesConstants.ASN1IdentifierAlgorithmNameMap.get(new ASN1ObjectIdentifier(oid)).getId(), compositePublicKey.getAlgorithm()); + + isEquals(subjectName, cert.getSubjectX500Principal().getName()); + + cert.verify(cert.getPublicKey()); + index++; + } + } + + private void checkParseCompositePublicKey() + { + try + { + //compositePublicKeyExampleRFC.pem contains the sample public key from https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html + PEMParser pemParser = new PEMParser(new InputStreamReader(TestResourceFinder.findTestResource("pqc/composite", "compositePublicKeyExampleRFC.pem"))); + SubjectPublicKeyInfo subjectPublicKeyInfo = (SubjectPublicKeyInfo)pemParser.readObject(); + isEquals(subjectPublicKeyInfo.getAlgorithm().getAlgorithm(), MiscObjectIdentifiers.id_MLDSA44_ECDSA_P256_SHA256); + + CompositePublicKey compositePublicKey = new CompositePublicKey(subjectPublicKeyInfo); + + isEquals(compositePublicKey.getPublicKeys().get(0).getAlgorithm(), "ML-DSA-44"); + isEquals(compositePublicKey.getPublicKeys().get(1).getAlgorithm(), "ECDSA"); + } + catch (Exception e) + { + fail("checkParseCompositePublicKey failed: " + e.getMessage()); + } + } + + // TODO: OIDS no updated +// private void checkParseCompositePrivateKey() +// { +// try +// { +// //compositePrivateKeyExample.pem does NOT contain the sample private key from https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html +// //because the at this moment, the Dilithium private key formats don't match. +// //this sample was generated from this BC implementation +// PEMParser pemParser = new PEMParser(new InputStreamReader(TestResourceFinder.findTestResource("pqc/composite", "compositePrivateKeyExample.pem"))); +// PrivateKeyInfo privateKeyInfo = (PrivateKeyInfo)pemParser.readObject(); +// +// isEquals(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm(), MiscObjectIdentifiers.id_MLDSA44_ECDSA_P256_SHA256); +// +// CompositePrivateKey compositePrivateKey = new CompositePrivateKey(privateKeyInfo); +// +// isEquals(compositePrivateKey.getPrivateKeys().get(0).getAlgorithm(), "DILITHIUM2"); +// isEquals(compositePrivateKey.getPrivateKeys().get(1).getAlgorithm(), "ECDSA"); +// } +// catch (Exception e) +// { +// fail("checkParseCompositePrivateKey failed: " + e.getMessage()); +// } +// } + + private void checkParseAndVerifyCompositeCertificate() + { + try + { + //compositeCertificateExampleRFC.pem contains the sample certificate from https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html + PEMParser pemParser = new PEMParser(new InputStreamReader(TestResourceFinder.findTestResource("pqc/composite", "compositeCertificateExampleRFC.pem"))); + X509CertificateHolder certificateHolder = (X509CertificateHolder)pemParser.readObject(); + JcaX509CertificateConverter x509Converter = new JcaX509CertificateConverter().setProvider("BC"); + X509Certificate certificate = x509Converter.getCertificate(certificateHolder); + + isEquals(certificate.getSigAlgOID(), MiscObjectIdentifiers.id_MLDSA44_ECDSA_P256_SHA256.toString()); + + CompositePublicKey compositePublicKey = (CompositePublicKey)certificate.getPublicKey(); + + isEquals(compositePublicKey.getPublicKeys().get(0).getAlgorithm(), "ML-DSA-44"); + isEquals(compositePublicKey.getPublicKeys().get(1).getAlgorithm(), "ECDSA"); + + // TODO: dilithium was used in the sample. + //certificate.verify(compositePublicKey); + } + catch (Exception e) + { e.printStackTrace(); + fail("checkParseAndVerifyCompositeCertificate failed: " + e.getMessage()); + } + } + private void doSerialize(Serializable encodable) throws Exception { @@ -5416,7 +5630,7 @@ public void performTest() try { - CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); + CertificateFactory fact = CertificateFactory.getInstance("X.509", BC); Certificate cert = fact.generateCertificate(new ByteArrayInputStream(x25519Cert)); @@ -5446,6 +5660,7 @@ public void performTest() checkCreationEd448(); checkCreationSPHINCSPlus(); + checkCreationSPHINCSPlusSimple(); checkCreationSPHINCSPlusHaraka(); checkCreationDSA(); checkCreationECDSA(); @@ -5496,6 +5711,11 @@ public void performTest() zeroDataTest(); checkSerialisation(); + + checkCompositeSignatureCertificateCreation(); + checkParseCompositePublicKey(); +// checkParseCompositePrivateKey(); + checkParseAndVerifyCompositeCertificate(); } private Extensions generateExtensions(Vector oids, Vector values) diff --git a/pkix/src/test/java/org/bouncycastle/cert/test/DeltaCertTest.java b/pkix/src/test/java/org/bouncycastle/cert/test/DeltaCertTest.java new file mode 100644 index 0000000000..7a514b784f --- /dev/null +++ b/pkix/src/test/java/org/bouncycastle/cert/test/DeltaCertTest.java @@ -0,0 +1,1031 @@ +package org.bouncycastle.cert.test; + +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Security; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.Enumeration; + +import junit.framework.TestCase; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.pkcs.Attribute; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.DeltaCertificateDescriptor; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.Extensions; +import org.bouncycastle.asn1.x509.SubjectAltPublicKeyInfo; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.cert.DeltaCertificateTool; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; +import org.bouncycastle.pkcs.DeltaCertAttributeUtils; +import org.bouncycastle.pkcs.DeltaCertificateRequestAttributeValue; +import org.bouncycastle.pkcs.PKCS10CertificationRequest; +import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; +import org.bouncycastle.pqc.jcajce.spec.DilithiumParameterSpec; +import org.bouncycastle.util.encoders.Base64; + +public class DeltaCertTest + extends TestCase +{ + private static byte[] baseCertData = Base64.decode( + "MIIREzCCELigAwIBAgIUSq2wnmbyhuz2O1DahpLbE0N075owCgYIKoZIzj0EAwIw\n" + + "NTEzMDEGA1UEAwwqQkMgU0hBMjU2d2l0aEVDRFNBIFRlc3QgQ2hhbWVsZW9uIE91\n" + + "dGVyIFRBMB4XDTIzMDgzMDAwNDAxOVoXDTI0MDgyOTAwNDExOVowNTEzMDEGA1UE\n" + + "AwwqQkMgU0hBMjU2d2l0aEVDRFNBIFRlc3QgQ2hhbWVsZW9uIE91dGVyIFRBMFkw\n" + + "EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9awTIuRdm93biCGi7O3DDopxiMa1lR0v\n" + + "qdFNmf7vrjlAsB5BKyTeFpxqLOLwJAbDIkr9O1o7HDgU7DOs+nFCKKOCD6Qwgg+g\n" + + "MBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMIIPeAYKYIZIAYb6\n" + + "a1AGAQSCD2gwgg9kAhRKrbCeZvKG7PY7UNqGktsTQ3TvmqANBgsrBgEEAQKCCwwE\n" + + "BKEyMDAxLjAsBgNVBAMMJUJDIERpbGl0aGl1bTIgVGVzdCBDaGFtZWxlb24gSW5u\n" + + "ZXIgVEGjMjAwMS4wLAYDVQQDDCVCQyBEaWxpdGhpdW0yIFRlc3QgQ2hhbWVsZW9u\n" + + "IElubmVyIFRBMIIFNDANBgsrBgEEAQKCCwwEBAOCBSEAsPv1ri6Gd2zXktq/CPlP\n" + + "cJbHy2Lra4mc/7PV5g0scKx3os5VS8RWZ7NrRjszXhKEU+uEAelmd6PuE2biKNv/\n" + + "iZMHaXqdLYYYBNhC4j8ppBu0rXaIEtNEsmv2oV8X8fbA2HU63/ctz6GHdOY57mlJ\n" + + "0l7cnyRCVmSofTGcLQjgjnfXhQeEvIqoDndyqbitSIsxyrnb46C3LbI5VElbuAOH\n" + + "VPLaMw2c09f3c5Ab4YmJwgVBomk0yeePDUxYdbVFWAvN+Ez/PX8sickVm/zeFzYD\n" + + "xQtwLl+CTCOIdiSn+dMEmM0fxrOUutHPVLoKqAxaTrSrKoe18o+ovj+tcNDBgd9I\n" + + "K9yWHg9aJQwMHhlyzbe6AMOz4jK54JCn/GpX66tRBhrNKDa/jmZm5pNO7hiw3UUk\n" + + "1OOy7mwMNuGJgMiMxi/Oh1zBtJnmJi+SvoNYEQrl/5P7hvM0oTalzLkRadIouGuy\n" + + "2fjgyPF5N8IO+OHoSrpOnKv0pBEN/JXZzDETRvz6FQigY07a2RFCWZ43886oDol/\n" + + "jSc2+z4IhMAb78Y+8gdZ08C25cle4xnZ00aEce9LOmu2SqvUEAt0doqOk9KxxOeq\n" + + "gqUUMPqn70LQVb7RxQq6yOfIuNyigJWQJdbh5IpeLzmJUd01oGYxzbX7EMFOsNRu\n" + + "nWisj9MxtuYb/QzyBCd23g0rXidcKmRXQnt1PUV6XAaHdH7LGPITivkIjAryY3Hu\n" + + "gwLt74CzcyBL4FsXEe2nU+zvwGINc1cYP9E76Qh/OTdZysphWsDWm3Q2CP2RS0oc\n" + + "I9eBboUwS+m7uV//nc+N+jfkTE0SaaFroZCYkmkmhVFMT2IatFBeDNXGyUp4EsyM\n" + + "SVMIlS3HAhly+AuYOseA6JHLCvvLwEcm34B9Lg/9LuKuYZ22gqLdE7JqyC1lQ5KQ\n" + + "waGb1vvmcGSQ8sRWDst6KjiXae7IKZbqTKUMQWf9GXxuCyHD7pHAIleFvvndsFq8\n" + + "sgxdsFnTM5JWD9uqzdICMxh/5EUCaPgiGfmCFCAd3KhuqjtXSeRP1X67pMvBVTZ4\n" + + "hF4JyNIvjb4L+VtByo20VuMijD6YNGJupI6eTBmYKsGcue6iVcPBgXgYnHFZHVM5\n" + + "Lt/TecoUIkqaZNIM8cWorSAnRe4WvPUvmgW+BbvTkFJoq8UlTtfu688Rd7qbfblQ\n" + + "pKW6m92tx9LnlaQBUoaGrq2CfFSERM0fSbxxJkKW7pcTzPoVsfUqqag9AiVA6Dmn\n" + + "7kpIWWI+NB1gZIj28O0aZcXxycmuKxWkQlNFe4OcS6mRobZzZRU61HPZka84SID8\n" + + "sDc4/a2foUk2MFgJLXuBJldq+N80/iCf1V6U60XdN68tH1PBkQzxfcC0EVkrudBu\n" + + "yNSlkB3ZIBM7qHyQKf+y9+WnNoAQuUXucUhbpRPobXXo7WQstCJ18TDJMLys8bDj\n" + + "X2EvPJgoqdsJXa4w9EKQHQdfkxLJC//8tgY4LwQTu9xGJ1s9zJIDW953dsmIZJxj\n" + + "xdzn7ePdS9QiT/ioVbwBrVaMkHQeJzGhKMrn9AJE4rO8C1XkEqbHk9N4h5E9XPjh\n" + + "82UM2/LOAwhyh/D1pVgPWKru5Xrkp5YTP5OnRWj3V45P2c2H5nA0thGx+JKdrTqW\n" + + "GQW/UlTKnN6eo2V9dK56chjRqYK72sU8VmoKO/2eroj5s21uMPXfiePJLWtOqBkz\n" + + "4N+KpkvvKCEBjlJJEq7mnxVemqtQ8QyadY+tCqkbeRLLdTLhsGtwL933B+vCYpy7\n" + + "6KQkMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGA4IJdQDn8Wf+\n" + + "2R9iyvWAzo6cjFGzkcNYPoTG1SCwCacMJVVKX5S8vf+zJjVuNX/7t5ckc/Swwp2J\n" + + "0x7bcIFiDFv8gR1PtT1jkR7Fo7s2vgomkIgtXVGwK6Q/GGZQ/UUpcnceIuAlVe88\n" + + "WS9otArc+ij5YTgsE9P9/49jPZAukn2T9XLaH9W30sEPpoPXVRcK2zlpkMmL3SHp\n" + + "Cg6bzt7GN6OLdJqioBtuKY0TAZcrVwJ0Sj8fnF5j1fnQ5qU4bP0QGrkWQNl2p2IZ\n" + + "340+PdYXYumPW0aU5KsQCcFnGz2TyoggUbKXyELj86rBTlzKrPlW2PQFZK9/FGfz\n" + + "YZ6dHszRbcbuyu3eaikoW53OMxbpCrl9dCNEdyE9lwtGz+DvgDk8NJeCvZbeNf9Q\n" + + "FaE65gOkG1DC46JCluChxa0hRNvxOK9P+M8tijz9JlsKlbtkSjpqWnUPoMdjAnJ0\n" + + "+iN6kr7LVOW6mppErnazK5hmFiGPu3P8KvqWKaAR+71161S+tuPENWbKDyq4U1wg\n" + + "Em3xgppCTGb6BHhGT+55oUr8syLHjk60rC9CsdZfdY4RhYtIKVjL8SUhLMELwK6R\n" + + "Dq9RUiu6sJP8Z8XZEvnQ/y720lVVuA/7BKGB+y4+B//HUk+OLhGx7W7aF78aPSa9\n" + + "ZwMPEaTv6bDPdSY/yKxlTCPGKbDU+RAepzk8GOw9g6Ku8MPZUH9BSjm5xRI/Qztl\n" + + "xWN7MHlQaCSTlFpAPZEZU/v2VaXnAxRsxbYfIWxAjNUImE4L51u58juR97H/Fb7r\n" + + "jfaM8M5jLfBQvSKHER7zvSHVBHcNTzBUsXdT3zAw/XbKwPwYOT+LCxqGaksKVVBV\n" + + "MgAIWBVvPkX8rwSCDNHMH6U1AtadSF6WT4Lsz272l8ihfZ8py0QHBVtPvjySB+yA\n" + + "Jwwcv2/DL9EO8ozBxyJDPhTTAmqYHNgPwZ8TpzhjfF3eKPOmNbTySNG8osrKONtJ\n" + + "+2l2RpicqeuQg3q3CF362DyGSywrxkPkx4j/JObA7o0ZQPZQ6IddVaA3jMBA3lNq\n" + + "YkuXgZ1NSH94F1TtoKrhd+50EtjrypK43kRwvVsWkXzpbhpzSEoTZQSbQjH0y/9+\n" + + "ceBOTr2v5TdxXkEiceTto99QfutB1yhhVo/3V8lkmcFX03A8sOFtPaeWOyIpje12\n" + + "P4v+fuRfolNYynEUTxyoHlohMwL9hwINqKT7IcIu/40N2guerUUDkS6AJdQ/Cpgt\n" + + "8ojDki61EgvFRQm32WuN66Pp+DADM0vqNyXw9ZWtoM79lWrnRApuyJQ7YnNFWEe7\n" + + "nclgNBqXEafaF2eRENGZg1VxruRGRgpa8Oj0Y1lJ9e6JGVi0uGyFDIM3bttuxs1e\n" + + "6li+j6MB65aCk6bfX79Binzf6xjCQ3jSZXlfqj4aIpcPgzVNmSz8951/5QSnGWLm\n" + + "ke4muuEUrz23g29+zEBHJ8Lnz2TF8Dnu7M0AvsgnPc02qO1H7tr+58uydeVvgGqE\n" + + "RJv0Gdfb7wqqvw91DK+gVrfj8G5Jr52D7NANA7H6sq28lAxVDBDfIjbjqz1+cQai\n" + + "79O9l7NNPoz38YvCnHJke9HGSX1s6X717DSpptYn7hZ6NBZVwGDAglPhDlx0MkbQ\n" + + "uUs1pZ62SGCq50MImOq//lh2wDhAx32E0M5SMEHUSyHiWm9SLDx09sTZ1kiP0dXQ\n" + + "BcDI6obBu0Y7/2GMN7gYkoKxL2+WNqSrxni+aCLNhyAlAJsr/5aAEqlWpWLQrFyB\n" + + "WNPxCpj3+tm06kUTtrSqgHp6vclXkbPefTJuDP9losLG1DYu6n6Ylp5tVgEOi9mI\n" + + "rJdMpRd6c0h8bZThTxCosR6230iKwBbfW3NEAurrALd7vEMrINCxia4yWCpH1v1t\n" + + "wSdF1cuugzMr16MyBlUTJVf6jf5hTo44TzR+tGOAON+rNNJms9s61Ia/ZSDQqy+W\n" + + "zIKucLvKUiAECoqLpMn1ZYAfg2iUjdVc6MiJAQh6bIVXzmTqH2RtIXMg9dOl7iLO\n" + + "a5xgyH0kjrFPUt0ObOCLuF6RnL97XHwONEXskfAmK6qJOsFJnauYkxAHoQlz4xyY\n" + + "mTDbcLH52T/jOD7o7t5FvxMZbu1DT8NYwnoVpC9YSDUWxGJUNX20ISFcGUJmHFWw\n" + + "7anRgfyQ1hTlMncbaDpOepP9xMh6oVmDr+QT3KUjKGePMIKXhuTSrwczRAafnkp/\n" + + "WxYxKWLGM30FJyAvf1o9Jk+jIFAXwXyeaCnHeCxtZbOO+oxug4oRipMMqE0IeG1a\n" + + "fe1wZNwg6F6H7RHjayubHZZQLkQ5lsT0EX8o5FpzzfpuDFTQlWx9R3XIYZLJsIAE\n" + + "8zDt5nV5N0ZepX2AURo0cW+fR0mn2aK3AqvApL9m3mgCtRR2NfVZCAXw3Wc+BmSl\n" + + "rLAZH5Y2Lxmxi0m6q8AL6HPnVp/+LjlHhhnl8ZWTVdN7nDN5m+cnemR/LMv9IEZ9\n" + + "3Jp4i5B0OD7p1rpYFAp0Ae/EPu1LQxn3htGNuBXTUq6zU723uVMjHaoX9IIUSg/W\n" + + "1BgW9HnCgyafWn97m/IVUDFVvCVxI1m6ohLSeiY2/y7MvEsgJzotnXk21VsZBxxs\n" + + "eIS3mqWCfbcH1R/8hLvDeulWgkz1rUHoYyZsBfBe2MpfYapkp2kwj/JCQ2Bse7bW\n" + + "lI6cQJDjta3/fAqmCW6xrU5THGSCaoFnpLVx2Ya74XsywaKnXGFPBAcanFOm0/3n\n" + + "JW5jYLorvjDYhoMcK4iUG4b58hZZckStm5ZrPsx4oJ8Fhk6IljrQVbFci0HPz74+\n" + + "JnNDDif1yTVGQ8Mp4zwtj7yCVJWnkxvXOxy0T3GPFNlOPXlMcq0Waw2c50SgPOQk\n" + + "upIuizdkXdB5IU89F76pKuW+cH71fn5qkOclVp99lcXfSsxBwBGO5iEc4+mjibYv\n" + + "3DLoCLj/WnH3IHTx7l6809pxa7eFr1YkU+X36OJGs9sHUX5ohlE+LJHA1qfS5SRm\n" + + "srbT93DNJlfgKXRY7vDwl1Ng253cqoytLg77LXl9R+yFn5C3DTFfXuiIBVI/it5Q\n" + + "xiBmQ7++8vHJjr9nk41dlG/GFSOq2Yzc0at75O8VkJvY84PkhbdHrX+ZovCIU62q\n" + + "qYX2tCcwch6qRNaIovJf5t89jyIbdyWBIjM+IgABCi82QE2QmJvLztbm5wQiKDlN\n" + + "T151dnh+f4mcsgkfIEBRW2tudHeLjLXI8vr/CCQtNjg8Ql1qa2yNrrPD2ODo/wAA\n" + + "AAAAAAAAAAAAAAAADx4vQjAKBggqhkjOPQQDAgNJADBGAiEA8LEHD5VbzlvCpRvi\n" + + "rZ3JDSHcUEFHI3GeeOOhMN6isdACIQDPvRrMrkhjfT0SXlwnCShrK9QjnLjSAIIL\n" + + "j7Gi9ZksbQ=="); + + private static byte[] extracted = Base64.decode( + "MIIPmjCCBg6gAwIBAgIUSq2wnmbyhuz2O1DahpLbE0N075owDQYLKwYBBAECggsMBAQw" + + "MDEuMCwGA1UEAwwlQkMgRGlsaXRoaXVtMiBUZXN0IENoYW1lbGVvbiBJbm5lciBUQT" + + "AeFw0yMzA4MzAwMDQwMTlaFw0yNDA4MjkwMDQxMTlaMDAxLjAsBgNVBAMMJUJDIERp" + + "bGl0aGl1bTIgVGVzdCBDaGFtZWxlb24gSW5uZXIgVEEwggU0MA0GCysGAQQBAoILDA" + + "QEA4IFIQCw+/WuLoZ3bNeS2r8I+U9wlsfLYutriZz/s9XmDSxwrHeizlVLxFZns2tG" + + "OzNeEoRT64QB6WZ3o+4TZuIo2/+Jkwdpep0thhgE2ELiPymkG7StdogS00Sya/ahXx" + + "fx9sDYdTrf9y3PoYd05jnuaUnSXtyfJEJWZKh9MZwtCOCOd9eFB4S8iqgOd3KpuK1I" + + "izHKudvjoLctsjlUSVu4A4dU8tozDZzT1/dzkBvhiYnCBUGiaTTJ548NTFh1tUVYC8" + + "34TP89fyyJyRWb/N4XNgPFC3AuX4JMI4h2JKf50wSYzR/Gs5S60c9UugqoDFpOtKsq" + + "h7Xyj6i+P61w0MGB30gr3JYeD1olDAweGXLNt7oAw7PiMrngkKf8alfrq1EGGs0oNr" + + "+OZmbmk07uGLDdRSTU47LubAw24YmAyIzGL86HXMG0meYmL5K+g1gRCuX/k/uG8zSh" + + "NqXMuRFp0ii4a7LZ+ODI8Xk3wg744ehKuk6cq/SkEQ38ldnMMRNG/PoVCKBjTtrZEU" + + "JZnjfzzqgOiX+NJzb7PgiEwBvvxj7yB1nTwLblyV7jGdnTRoRx70s6a7ZKq9QQC3R2" + + "io6T0rHE56qCpRQw+qfvQtBVvtHFCrrI58i43KKAlZAl1uHkil4vOYlR3TWgZjHNtf" + + "sQwU6w1G6daKyP0zG25hv9DPIEJ3beDSteJ1wqZFdCe3U9RXpcBod0fssY8hOK+QiM" + + "CvJjce6DAu3vgLNzIEvgWxcR7adT7O/AYg1zVxg/0TvpCH85N1nKymFawNabdDYI/Z" + + "FLShwj14FuhTBL6bu5X/+dz436N+RMTRJpoWuhkJiSaSaFUUxPYhq0UF4M1cbJSngS" + + "zIxJUwiVLccCGXL4C5g6x4DokcsK+8vARybfgH0uD/0u4q5hnbaCot0TsmrILWVDkp" + + "DBoZvW++ZwZJDyxFYOy3oqOJdp7sgplupMpQxBZ/0ZfG4LIcPukcAiV4W++d2wWryy" + + "DF2wWdMzklYP26rN0gIzGH/kRQJo+CIZ+YIUIB3cqG6qO1dJ5E/Vfruky8FVNniEXg" + + "nI0i+Nvgv5W0HKjbRW4yKMPpg0Ym6kjp5MGZgqwZy57qJVw8GBeBiccVkdUzku39N5" + + "yhQiSppk0gzxxaitICdF7ha89S+aBb4Fu9OQUmirxSVO1+7rzxF3upt9uVCkpbqb3a" + + "3H0ueVpAFShoaurYJ8VIREzR9JvHEmQpbulxPM+hWx9SqpqD0CJUDoOafuSkhZYj40" + + "HWBkiPbw7RplxfHJya4rFaRCU0V7g5xLqZGhtnNlFTrUc9mRrzhIgPywNzj9rZ+hST" + + "YwWAkte4EmV2r43zT+IJ/VXpTrRd03ry0fU8GRDPF9wLQRWSu50G7I1KWQHdkgEzuo" + + "fJAp/7L35ac2gBC5Re5xSFulE+htdejtZCy0InXxMMkwvKzxsONfYS88mCip2wldrj" + + "D0QpAdB1+TEskL//y2BjgvBBO73EYnWz3MkgNb3nd2yYhknGPF3Oft491L1CJP+KhV" + + "vAGtVoyQdB4nMaEoyuf0AkTis7wLVeQSpseT03iHkT1c+OHzZQzb8s4DCHKH8PWlWA" + + "9Yqu7leuSnlhM/k6dFaPdXjk/ZzYfmcDS2EbH4kp2tOpYZBb9SVMqc3p6jZX10rnpy" + + "GNGpgrvaxTxWago7/Z6uiPmzbW4w9d+J48kta06oGTPg34qmS+8oIQGOUkkSruafFV" + + "6aq1DxDJp1j60KqRt5Est1MuGwa3Av3fcH68JinLvooyYwJDASBgNVHRMBAf8ECDAG" + + "AQH/AgEAMA4GA1UdDwEB/wQEAwIBBjANBgsrBgEEAQKCCwwEBAOCCXUA5/Fn/tkfYs" + + "r1gM6OnIxRs5HDWD6ExtUgsAmnDCVVSl+UvL3/syY1bjV/+7eXJHP0sMKdidMe23CB" + + "Ygxb/IEdT7U9Y5EexaO7Nr4KJpCILV1RsCukPxhmUP1FKXJ3HiLgJVXvPFkvaLQK3P" + + "oo+WE4LBPT/f+PYz2QLpJ9k/Vy2h/Vt9LBD6aD11UXCts5aZDJi90h6QoOm87exjej" + + "i3SaoqAbbimNEwGXK1cCdEo/H5xeY9X50OalOGz9EBq5FkDZdqdiGd+NPj3WF2Lpj1" + + "tGlOSrEAnBZxs9k8qIIFGyl8hC4/OqwU5cyqz5Vtj0BWSvfxRn82GenR7M0W3G7srt" + + "3mopKFudzjMW6Qq5fXQjRHchPZcLRs/g74A5PDSXgr2W3jX/UBWhOuYDpBtQwuOiQp" + + "bgocWtIUTb8TivT/jPLYo8/SZbCpW7ZEo6alp1D6DHYwJydPojepK+y1TlupqaRK52" + + "syuYZhYhj7tz/Cr6limgEfu9detUvrbjxDVmyg8quFNcIBJt8YKaQkxm+gR4Rk/uea" + + "FK/LMix45OtKwvQrHWX3WOEYWLSClYy/ElISzBC8CukQ6vUVIrurCT/GfF2RL50P8u" + + "9tJVVbgP+wShgfsuPgf/x1JPji4Rse1u2he/Gj0mvWcDDxGk7+mwz3UmP8isZUwjxi" + + "mw1PkQHqc5PBjsPYOirvDD2VB/QUo5ucUSP0M7ZcVjezB5UGgkk5RaQD2RGVP79lWl" + + "5wMUbMW2HyFsQIzVCJhOC+dbufI7kfex/xW+6432jPDOYy3wUL0ihxEe870h1QR3DU" + + "8wVLF3U98wMP12ysD8GDk/iwsahmpLClVQVTIACFgVbz5F/K8EggzRzB+lNQLWnUhe" + + "lk+C7M9u9pfIoX2fKctEBwVbT748kgfsgCcMHL9vwy/RDvKMwcciQz4U0wJqmBzYD8" + + "GfE6c4Y3xd3ijzpjW08kjRvKLKyjjbSftpdkaYnKnrkIN6twhd+tg8hkssK8ZD5MeI" + + "/yTmwO6NGUD2UOiHXVWgN4zAQN5TamJLl4GdTUh/eBdU7aCq4XfudBLY68qSuN5EcL" + + "1bFpF86W4ac0hKE2UEm0Ix9Mv/fnHgTk69r+U3cV5BInHk7aPfUH7rQdcoYVaP91fJ" + + "ZJnBV9NwPLDhbT2nljsiKY3tdj+L/n7kX6JTWMpxFE8cqB5aITMC/YcCDaik+yHCLv" + + "+NDdoLnq1FA5EugCXUPwqYLfKIw5IutRILxUUJt9lrjeuj6fgwAzNL6jcl8PWVraDO" + + "/ZVq50QKbsiUO2JzRVhHu53JYDQalxGn2hdnkRDRmYNVca7kRkYKWvDo9GNZSfXuiR" + + "lYtLhshQyDN27bbsbNXupYvo+jAeuWgpOm31+/QYp83+sYwkN40mV5X6o+GiKXD4M1" + + "TZks/Pedf+UEpxli5pHuJrrhFK89t4NvfsxARyfC589kxfA57uzNAL7IJz3NNqjtR+" + + "7a/ufLsnXlb4BqhESb9BnX2+8Kqr8PdQyvoFa34/BuSa+dg+zQDQOx+rKtvJQMVQwQ" + + "3yI246s9fnEGou/TvZezTT6M9/GLwpxyZHvRxkl9bOl+9ew0qabWJ+4WejQWVcBgwI" + + "JT4Q5cdDJG0LlLNaWetkhgqudDCJjqv/5YdsA4QMd9hNDOUjBB1Esh4lpvUiw8dPbE" + + "2dZIj9HV0AXAyOqGwbtGO/9hjDe4GJKCsS9vljakq8Z4vmgizYcgJQCbK/+WgBKpVq" + + "Vi0KxcgVjT8QqY9/rZtOpFE7a0qoB6er3JV5Gz3n0ybgz/ZaLCxtQ2Lup+mJaebVYB" + + "DovZiKyXTKUXenNIfG2U4U8QqLEett9IisAW31tzRALq6wC3e7xDKyDQsYmuMlgqR9" + + "b9bcEnRdXLroMzK9ejMgZVEyVX+o3+YU6OOE80frRjgDjfqzTSZrPbOtSGv2Ug0Ksv" + + "lsyCrnC7ylIgBAqKi6TJ9WWAH4NolI3VXOjIiQEIemyFV85k6h9kbSFzIPXTpe4izm" + + "ucYMh9JI6xT1LdDmzgi7hekZy/e1x8DjRF7JHwJiuqiTrBSZ2rmJMQB6EJc+McmJkw" + + "23Cx+dk/4zg+6O7eRb8TGW7tQ0/DWMJ6FaQvWEg1FsRiVDV9tCEhXBlCZhxVsO2p0Y" + + "H8kNYU5TJ3G2g6TnqT/cTIeqFZg6/kE9ylIyhnjzCCl4bk0q8HM0QGn55Kf1sWMSli" + + "xjN9BScgL39aPSZPoyBQF8F8nmgpx3gsbWWzjvqMboOKEYqTDKhNCHhtWn3tcGTcIO" + + "heh+0R42srmx2WUC5EOZbE9BF/KORac836bgxU0JVsfUd1yGGSybCABPMw7eZ1eTdG" + + "XqV9gFEaNHFvn0dJp9mitwKrwKS/Zt5oArUUdjX1WQgF8N1nPgZkpaywGR+WNi8ZsY" + + "tJuqvAC+hz51af/i45R4YZ5fGVk1XTe5wzeZvnJ3pkfyzL/SBGfdyaeIuQdDg+6da6" + + "WBQKdAHvxD7tS0MZ94bRjbgV01Kus1O9t7lTIx2qF/SCFEoP1tQYFvR5woMmn1p/e5" + + "vyFVAxVbwlcSNZuqIS0nomNv8uzLxLICc6LZ15NtVbGQccbHiEt5qlgn23B9Uf/IS7" + + "w3rpVoJM9a1B6GMmbAXwXtjKX2GqZKdpMI/yQkNgbHu21pSOnECQ47Wt/3wKpglusa" + + "1OUxxkgmqBZ6S1cdmGu+F7MsGip1xhTwQHGpxTptP95yVuY2C6K74w2IaDHCuIlBuG" + + "+fIWWXJErZuWaz7MeKCfBYZOiJY60FWxXItBz8++PiZzQw4n9ck1RkPDKeM8LY+8gl" + + "SVp5Mb1zsctE9xjxTZTj15THKtFmsNnOdEoDzkJLqSLos3ZF3QeSFPPRe+qSrlvnB+" + + "9X5+apDnJVaffZXF30rMQcARjuYhHOPpo4m2L9wy6Ai4/1px9yB08e5evNPacWu3ha" + + "9WJFPl9+jiRrPbB1F+aIZRPiyRwNan0uUkZrK20/dwzSZX4Cl0WO7w8JdTYNud3KqM" + + "rS4O+y15fUfshZ+Qtw0xX17oiAVSP4reUMYgZkO/vvLxyY6/Z5ONXZRvxhUjqtmM3N" + + "Gre+TvFZCb2POD5IW3R61/maLwiFOtqqmF9rQnMHIeqkTWiKLyX+bfPY8iG3clgSIz" + + "PiIAAQovNkBNkJiby87W5ucEIig5TU9edXZ4fn+JnLIJHyBAUVtrbnR3i4y1yPL6/w" + + "gkLTY4PEJdamtsja6zw9jg6P8AAAAAAAAAAAAAAAAAAA8eL0I=" + ); + + + private static byte[] rsa_ec_cert = Base64.decode( + "MIIFKzCCBBOgAwIBAgIIaLtn+ZoOPkAwDQYJKoZIhvcNAQELBQAwMTELMAkGA1UE\n" + + "\n" + + "BhMCY2ExCzAJBgNVBAsTAkNUMRUwEwYDVQQDEwxKb2huIEdyYXkgQ0EwHhcNMjMw\n" + + "\n" + + "NTIzMjI1MTU0WhcNMjQwNTIzMDA1MTU0WjAxMQswCQYDVQQGEwJjYTELMAkGA1UE\n" + + "\n" + + "CxMCQ1QxFTATBgNVBAMTDEpvaG4gR3JheSBDQTCCASIwDQYJKoZIhvcNAQEBBQAD\n" + + "\n" + + "ggEPADCCAQoCggEBAPTegns+vTNALyCqUhWCAe22B1hDi63F4orq48sgQDl98zLd\n" + + "\n" + + "xrr4BwpJ3Q+9y8f2SiRjH7rjMo8+Ry/o0H+etSzYi/7nf8sffc2+w3cVRzYd3GBV\n" + + "\n" + + "bXaFb+7OP0AlBS6lc2w4j7zm6thV2hz9L7XKEEt8O8MHCttbODVGXGihb3Dvw0XV\n" + + "\n" + + "UEDarspb4/zN1eKhK+6uZLyl+WkdX3Pev2RDbUH/Mz990YCpC5eWozDpA0NxgOP8\n" + + "\n" + + "RDxkBwx2TuUYwB2oCmyVsZ6vaGVCSL2kSWjdBVM6f60LgyMvneanx+PET5IX/znH\n" + + "\n" + + "+NQoiJz3Hb82KuPZLg+L/CIG0DiDEYJvD1yYY/UCAwEAAaOCAkUwggJBMBEGCWCG\n" + + "\n" + + "SAGG+EIBAQQEAwIABzBOBgNVHR8ERzBFMEOgQaA/pD0wOzELMAkGA1UEBhMCY2Ex\n" + + "\n" + + "EDAOBgNVBAoTB2VudHJ1c3QxCzAJBgNVBAMTAmNhMQ0wCwYDVQQDEwRDUkwxMCsG\n" + + "\n" + + "A1UdEAQkMCKADzIwMDkwNzA3MTg0NzU4WoEPMjAzNDA3MDcxOTE3NThaMAsGA1Ud\n" + + "\n" + + "DwQEAwIBBjAfBgNVHSMEGDAWgBSLhHJw3CWoK6tG+vDHA4+A3WZQfTAdBgNVHQ4E\n" + + "\n" + + "FgQUi4RycNwlqCurRvrwxwOPgN1mUH0wDAYDVR0TBAUwAwEB/zAdBgkqhkiG9n0H\n" + + "\n" + + "QQAEEDAOGwhWOC4wOjQuMAMCBJAwggEzBgpghkgBhvprUAYBBIIBIzCCAR8CCC8r\n" + + "\n" + + "86yn2wm8oAwGCCqGSM49BAMCBQCiHhcNMjMwNTIzMjI1MTU1WhcNMjQwNTIzMDA1\n" + + "\n" + + "MTU1WjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENMAU79zHGMdY7BrUcoi10Y\n" + + "\n" + + "2v9yGwq6rF/el0HFrAVIW1f9GfPZZQI5OJnqf60/X2IRc4KecyfqiVjkD3GEWJyk\n" + + "\n" + + "QDAfBgNVHSMEGDAWgBTWuDKUFK1U61Y5aP6Gm9/hU/81LDAdBgNVHQ4EFgQU1rgy\n" + + "\n" + + "lBStVOtWOWj+hpvf4VP/NSwDSAAwRQIgH6haXFeIfy+TOPWFEsxfFzehVcQAy4NL\n" + + "\n" + + "gH1wiKp61ecCIQDGD0NqMadMAnrfIy8MiH6kkZ0LEKDVpbh3k1CvaXVB+jANBgkq\n" + + "\n" + + "hkiG9w0BAQsFAAOCAQEATtjhu3Yuy8mw0FIbvxm8LwE18OAb4De7XZXBBQrHHlA5\n" + + "\n" + + "HNkvcPPba7171LcpIZx/SW4C5sIxfwn0rFZ8uTUKdiQSmmqfwH1t2NZ1fF+oADF3\n" + + "\n" + + "goxuxEYHczqVUYSugllqMJx0T/7HgD3JEd3DOYrk4k2ksE557xVwEm5OBBNTiz0/\n" + + "\n" + + "2M72GRsSbma2xo6tFiQ6iYfI3B2NgW0jekN9wOlF7p+SZFeq1afSEDrfVSi0DkVQ\n" + + "\n" + + "zyn7PMrrZgyYpjWr1GpnvNBcZDEpH7TML9GUxchn31w0FvaLMMgYJJ2ha2ohPQxV\n" + + "\n" + + "tV9dNL7ivNP74nJQqT1x05vXhjrL86VOlwxa385geA=="); + + private static byte[] deltaCertReq = Base64.decode( + "MIIP2zCCD4ACAQAwDzENMAsGA1UEAwwEVGVzdDBZMBMGByqGSM49AgEGCCqGSM49\n" + + "AwEHA0IABEqIRHVQv5GkHTHTBzPZFAiCVbMB8h+uTZ1gV58O2rnCBn4YNqpIj8j0\n" + + "3w2myhahWFeyw/Yjq1CgyvbjbglieUuggg8NMIIFfAYKYIZIAYb6a1AGAjGCBWww\n" + + "ggVooB8wHTEbMBkGA1UEAwwSRGlsMiBDZXJ0IFJlcSBUZXN0MIIFNDANBgsrBgEE\n" + + "AQKCCwwEBAOCBSEA8FVxiaOOy6Q3iNLf6l0teGHOuJq8kXEd4uHXmVDBgZOvb90c\n" + + "8frAULVblAD2Ky6c9Ra/BcjXtenWXDxrd18ky0s0E/YmT6tUVMDNCT0htbU2ONnl\n" + + "8YDpsROlO1HHZwV9yYDolEeu2MJTwmQ42f+1udRt37KctrQ2OzvktRp1wvyz1EOm\n" + + "0T0ORrHi3pS95d74ZEMlRdtG1KAW0vZ85SrNZu5TJ000ODBgvyIgsYPTwGDineMU\n" + + "Vd2A/1DIhBpwFmv5lKeOLGVBZ9TqonlLuQYKVSWTt4MLW9BAl2S8AKP1XKqc8hsr\n" + + "qpgcl6pokVYNbnwNfAKECtpy8yNJm8+5t254zwdcGMVPUFPcaincq1nYyc0OhBBZ\n" + + "rd4tiVnv7anCOtapLewfuU/M60TWr83QKLfgiDb63OHrSLR1GSwPNcfY6GjttweQ\n" + + "mHoQn/ymMxLF2aUB5KRN1J42r8tUYaLd4/NPIyrW3PuuD5xStnfP5Sm4kTxq3ZlB\n" + + "Sg3kVIQW3k3Ue0a2fy83oT2nzasddu9ZaKzgox9cQN0eekm9LIzSjoLtDWqbSHpS\n" + + "AwIvYtTRoORh/+pyJPefGo647yzvKnvyh7300d/OLPeMoErs3RptXRD8x9YiKnYg\n" + + "uLfxMnIZB5Dmb+JSz3e4E3j3pl8/RkIbXpX4nU1Ng6PgVUiwu1/5swOL4tTsI8dN\n" + + "7DJiY6WmjjNtkJX9YlWIAK7j2jZ6Bi7/s8saAXh0YmB94UI4opnuLbAJWVauSU22\n" + + "TUR/qb6NNdHN9Db+EBkHnS5MAeve5jRZVsb0yTy4pmr4n85Go1h+KxZsd9MIJQu4\n" + + "sN564qVeJ355hloKyXf7nApDWbkqCGAXjdSizhLkZ5hnm5tL/qTrgg7MldtlYEtH\n" + + "ksmPGeeLEF3te2VKt1gSesJmeJkgvYczi0t4fAWpkZCbQe0rBp3J8SGRw7UuDAez\n" + + "9rYvXdHIO+TSdUaWnhPZPTXEPJD8hodBok5Z5oJbKEtzb3kCkmz8OBf3sFGblLit\n" + + "EHCTW25X/fRI3HpKqWy2J5wND5asyyPFzMXGYJJGx0eN3V3EFcs7pJXOmJlQfuJo\n" + + "Q656TWsxzKJQGnwESqzOC/jnliYFX6ilab41CRJZXXJOMC0EYbcmaDsGouCQAJ8x\n" + + "BacyWNzl3YCibK3SfCecXvMbOxx5xuNZju3KwYZtywmN9YBGqeht5FDH197KW7t1\n" + + "lUA4H+cT+CUDSWQXfMHlOeJaLQFsOC+wACD3jIw8lObWTdssl6nLlf6L6xuCbGj3\n" + + "pUgXLXa4VZNBXaoh6JgasuBsmXColmEwTmLNwxFrFKUl/DH1VW6zJRUc4RMD18kb\n" + + "ys09EryX52vuTL23FOcqKqoIbQUkav1hEtGIGeArW1EpcQRRXEs++VOKSXr2Vm5m\n" + + "efpKP1EShkjnBLuJxM5ybklnWp5Y9UIOIicl78nFq/yMTXrVZSnVcqC3ubnBg2O0\n" + + "1++7R8XID0PUX6FK9FaK1Tu5D0I0X5p0Dntmf5VF/EsA7OF5Cmm+kPtLHn+XClEJ\n" + + "w9SnrboMLa/Ltd0gML9mLanrv8UTKpVyFKD5B+Qiuzd+3HtxDbXZHjN5/AC7ibuZ\n" + + "DuSWbi6U6N00VNmSzZ4IwmfNTdCkIPLGIFSJ2dhrp5P2oDfeIfapZtFukuWu/iA4\n" + + "/iT43OeNMXwCg9wVb6cXBeJTifOAm/Rqm42UaDqsyk/za1M6YW/pYDNQzJBvvMqZ\n" + + "p92GMQjDEqXv0dyIXzWBwDc+RUyATSY5mnn6O6INBgsrBgEEAQKCCwwEBDCCCYkG\n" + + "CmCGSAGG+mtQBgMxggl5A4IJdQBmEI0USeb3jHLoswVnkl6bhVdCdu4YBoPWZMX1\n" + + "4Ka4489Ns6pSgL5ex3r1W/4ZeI5XWqIqUXDIwwW2hp+OHLvFM3jbA3Weul/bL/yJ\n" + + "pz9io3m++CKYP4KCMssDoyBwvTR5oX28yq9lc0L7uhgtWyACQP/x0kvci32pDQvb\n" + + "GfcZcXGmgEmK4xRWOfnphwPSXGmyhH4+TeTua/u5+Ka1ShMjs7G/1G07CaM53Un4\n" + + "mZm3gb6cbNGWxxRpfB7/lQs7ckjoA/Jx/r94uKz1wGHXkoyx9QEzjkHvR60i4REr\n" + + "+Gk0kJhSaKmw15NMKJJJ0iMINWlzKZCnd2oL0eMIjHs2dx+H5Ea+DlveI9VNddDy\n" + + "9bi/WeSySS3HdorakMCbIr862W3DLrIRupi4gPI+E/VKqD8cCLvzs1Ffgfe5MCi+\n" + + "WDxu+7NGlGmd12LDr8NfwvvlvLioWsiSWWXRvONfgj2vrneRGGpP85COQbtzt+5h\n" + + "N925iY3uD5qpKap0nQiWCjWVKMRFJXl7b2brouQu6qu7i1kyqpTOenNUXidgAtkM\n" + + "5LC2Nsejyci1FPGbU/5JR+71tMA2aJ9Wku4hCI3IWfgQBNJ9YDCvahqSeILtHpTA\n" + + "6IxjcQ6PCPAORFCyM+MHMrAr/y+SNMB7zoKkq/m9Rng2Z2artdZ5VtvigHbhg/FP\n" + + "BP58laYE+LZ/NkVWp3BjQQow2MJujy9dzgOeU6ih0jjG3tg0QW0RuSloNhUfI1rZ\n" + + "UAfqadFcy1nNtZMHEUM4F36Tx9kkPBeTaN/OJIa8ICNI9yNwxMOIRYmXlXldqQcM\n" + + "lPzKuEeiHBwt5T/5piOynYSzNiE/1M9ILo87KjSLSv1BQZR+lI6kpmFZj7FFWyde\n" + + "WFxvRCBeZNmMwQhIO9t1ZfqZzKCJ8ADqYhol9CZatyqVXNo8FR7BVnHFHcIM1JCf\n" + + "A8/T4pTz9B6OZb+35fCeznyNe0XckfRYRmAtFrJOikMSF/YF6ZvYqd/eJLvs35it\n" + + "cCE6Y/liPFS8QG2oPBunCGxLp3wWo11YsO4ViOfHjrV2aHhYM/aQvLWwgR+xqdXq\n" + + "xrm3xWtLr1u3EpRLWouMDuiCyqCtAwsra4UyyO1tFRLsYuGAZTQZ+JCjO1TOYmdE\n" + + "vk+CkS3fBTeajFbBIrMJY5WIFdHWcbjIQd6rRHkpNMN0RnytL9X9P7s1hxyhfOM3\n" + + "BLAguLuuoIyWwmXkvxWOu52i0NIdAuv9PXv2d+l5LYd8Tqz9Uw2DUSHj6bIQZhdH\n" + + "0k1rw8PkxYT0LXM5zmXPxlVKg1uHDkRn/rf7bkhQ16GV4evF2Pwfg0JS85aE6WA7\n" + + "+3RjAi+pc2NhWHtNObVvEv/Cr7MT6jLk242TZBk7z9h/xsa6HHIM95bmpmqPMm1D\n" + + "j4hT6eHosVynhgXQYYuJixV65mFQOjJFhzGi1mP4jLOggZ81Bjq1yg5+Kor1CGPT\n" + + "ufbHkr60o0FTu49ASWgLLLr1k1RQBNjADcDQfmUio+XJJfZQlfTiYx25IaxX/uha\n" + + "0WZYJo/8UNfjsw15pQSSQf/o+NQwvCs7pWJoa4D9mhzGlAakI+33A89nt+W7szbN\n" + + "5f00CpJI5UUv/k5E1hDSVR1FeCq0DRruBEVF+YAHKWPEEdCGoc5x0QnHiiZeAQQ9\n" + + "Z49VJSXxRjK+vzKl4mmQPYJtA2sAm2CrGYYYujJQ+hk6M3HL3iA+IyMczpTwtHCi\n" + + "ImOZxNt8yt6xlpYhUoHhwD8+QVI1IPWiciIseCzfdYK9ZZVO1QeQTyqVLflXeMOK\n" + + "snpuAQTPXEcxylVtG0Gqux7BQM7REYb1VEgIzEQ80CyL9CeXOzQRojlNB5k9tVZ7\n" + + "cUIEaAzNrqX8iJtyhUkxuIlmodnMkMlMWDFMn+gz1SA3+nAGT1/ea6RS96R7xUAN\n" + + "tzvMxqrQSctz/+EkGwnF7HVq5t+YG5rCWYm8w+ZuB/MXbFobvccChjBL0LE+sTqr\n" + + "vkbKqzRgVgqkW27x+BVxRCXtAbgEknsvmVFWzb6/ez/6eyRvJX1WgwlWsS5X66CE\n" + + "HD3W2rnCasL32g1iLVhb7GPfOi+37yjVwCpV+PHAVYEGvYeuNDovsHuYnPk2lh8Q\n" + + "WWqj0ws0tniCXxaQxgC5QVbQsuideloPnJwWNDSSeTG2OALoiVC1mXNTbkLZyDbe\n" + + "9m3VmCfWHXONtrICAaXk8Zrvy0rJWTkOK/yo1RIALJirZqAewcf+pr13k8ZZCUB+\n" + + "rN74OwWsTztpBkHuFZjJc4FZXagvS+f+TtDvk12aR0ka6VvW+zLMdFiDiaPcub4B\n" + + "11guEYLkqCg7yFuocqn+9UBA/Jued8HQDnmW13D498qvp5nWOz/Vnk5F6rf882iL\n" + + "Ex0MDvXnEFfWPOnYQ0mETWWvmhYTzlVUGhrN0WHi9MTyRByWZ4m48+wfKhtyDbEV\n" + + "on3X+dRqdlqdaGKtXjGAByForcym7mescUF9r5gu/EDICYtek9iPQqlXY0u2Yrp6\n" + + "8Q5zMUOwjVoTjWHVDIgOVjHGBoBgCPUwzgrVQuOMy411yvm+DYUdtvoWpYTAGNo2\n" + + "RX1yeDROevYe0p4Nk34HoYX2cj8+Ov9KoDNf2SgH3uAdz8SFl6U7F+ef6SpOxFSY\n" + + "s+VV7H8V+XQ59WqNbZbf70vRPlNd1gpjI3iksBehGHX/n6L2hPIwQnvvVCJbffEC\n" + + "DsFykZo9KpgvbRetwSwOLYoGUhQDb0dIx6WyATj3klJNtYJiLweb5PaelwZ8fkJV\n" + + "+vksYRenfwm+VaMiLtFWd4oHR+zPtLwUMvKMzqOeEe3VhMvzxM356LzeZyfjz6uF\n" + + "negEdIn8G0Xb+i91SKKZWVl+1jBXE6ov40/SFfneHi54uA1/9JPf5K4aES7yTtml\n" + + "ffk6Nc5Z54zFkhO0ggWgEJt7CT/eQDz5jqAT40Q7lbIxvQcPdG90WmmhxjOGKfLF\n" + + "Ug/FQuG+dlw4xBCIEC04zBjC5TrCbSjNm0xGkHCeKEIzIN3eIKbQ8S7Fs4zKqn1i\n" + + "w3kRxcb928h6xfb2SsESKF/9U/8kOpNITE+XPug+WYLzfh8BS8kfxut3GGTArYAn\n" + + "TCOOooJldukCPIxd5Nf1SAitlbUyfjY9i2xWDUiMdPxNYtSZ5f9HgDgcHSTrm9EB\n" + + "SMAl1jtCUmN+hpmkp9Dh4+vx+0NfYmlzhomcqa271djb6e31AxEdJCYoMTZWb3uL\n" + + "utjg5Ojr8v0BHiEoQ0tUjZGam6S7xcfP09vj+/0AAAAAAAAADyA0STAKBggqhkjO\n" + + "PQQDAgNJADBGAiEA8Yi24L05Pkn0y6Umltpd6Hhw/TyFzB7SmaEEEcn9+iYCIQCA\n" + + "ahofKFqOtfmLrzh+a8VCq30wqdJhqf+imN28KcziNA=="); + + private static byte[] draft_dilithium_root = Base64.decode( + "MIIZTzCCDFqgAwIBAgIUONT0zs5OI1dwa7N+gcOBNTQEwSAwDQYLKwYBBAECggsH\n" + + "BgUwgY8xCzAJBgNVBAYTAlhYMTUwMwYDVQQKDCxSb3lhbCBJbnN0aXR1dGUgb2Yg\n" + + "UHVibGljIEtleSBJbmZyYXN0cnVjdHVyZTErMCkGA1UECwwiUG9zdC1IZWZmYWx1\n" + + "bXAgUmVzZWFyY2ggRGVwYXJ0bWVudDEcMBoGA1UEAwwTRGlsaXRoaXVtIFJvb3Qg\n" + + "LSBHMTAeFw0yMzA1MjUxNjUxMzhaFw0zMzA1MTIxNjUxMzhaMIGPMQswCQYDVQQG\n" + + "EwJYWDE1MDMGA1UECgwsUm95YWwgSW5zdGl0dXRlIG9mIFB1YmxpYyBLZXkgSW5m\n" + + "cmFzdHJ1Y3R1cmUxKzApBgNVBAsMIlBvc3QtSGVmZmFsdW1wIFJlc2VhcmNoIERl\n" + + "cGFydG1lbnQxHDAaBgNVBAMME0RpbGl0aGl1bSBSb290IC0gRzEwgge0MA0GCysG\n" + + "AQQBAoILBwYFA4IHoQBxNIVkcLajfd6f/9uOqGfiWPTxem6oTmbQ5N0TOS/j0tfI\n" + + "qxjz2CW2h5wcbs4UYc4KylsmNbhy+lo/3s0jbRmOOPuBVmv8dG8NmDty2ZWK5m3Y\n" + + "hJIaujOAYSNfzRPax/7pDX4+oDL0zfO0i6S71BmBzcamX/11WxdI9okKN3Z7NQns\n" + + "CMmfBtWab1POC/eoRwQ4+Sk39xpp2NPlSEeLVoQtgdLvmc0DNL87Gcoao2YfxXbf\n" + + "Gyx/HsKbi03o7/nmLuT0LvTe0YhQ1dE5c1fxCVQHUeXFwyW10TyHfZMK+0mT77ig\n" + + "NSfsUeHMEjqNPNhO94QLds26awaJAbnZDR9LJQ//TvI91FlwruBxnZtp0+2DR6jN\n" + + "4lTIuaKjEX+HzxZe6k+jjg35erc3PEXNH3+kzIEWHgjYmANftoI4wulK9FOf7RVD\n" + + "6k/G1/vIupQUZQ7brIVbWsevwUWgxpxNs0+noedA02nLjjqZhkM1bIqOt8AKZJgX\n" + + "5ie6btnrkMMUFocxG5yvuO4fn7rreWv2T/S+kmKGou7scEyUowwjYv4t3sgFw0tN\n" + + "4iK6htNyNo/9jX1Tei9QUibhlcqcMkVw6dGZAGSxdAvH0hD5NXi/dweENCaOGCPn\n" + + "9Wza/g44TnLpXLH97U47tC0Gg2+do8jspmBBu3CQ6i51qJUE5vJxUCmlZy44PRXc\n" + + "E9K8VUwtlma44yyfGmg9tZdWwZggt+gv+PION2T35HGzA5Nih7zCRK8knn4yhKoR\n" + + "0H4IV0f5JrtoS1QlqTkaCJ5cv7I71hPPjQ3Ghtq3pudHDL/taFUApcgcaIsHQTPO\n" + + "Sicp5/yW6+8xjEwiW3p//XYlrB6tsLkSXAz5UyxiIjwdgnZra/225ORg2a+bvfHb\n" + + "wEircmGzVQEAqem+60l+J44slM1pR+tWSKi/AUPHl2yK7W83/uz4uZmYrqO1GWCc\n" + + "2cb7va/nWPCKFEcX3JbBXpT9Xvyy1VFDf8WV6CxRgIk3E7ZxK04hLnTRCYNLuTc4\n" + + "Bp3Io6nWmE0VgJs+jl/n5kcimU76p7s3YfnF9TOCtoQbrfIRX2FhBFsOeKZsbMDQ\n" + + "zlsBZroMOAQ+cr+UwohSYX+yXKKK1ARPFFYdyYgLaOYzYB5pFr1BeM4fQrCoF7EV\n" + + "PvWvYcaeoBQ0y7mpGVsKbPsp2EIZUIt/HY519acbHjkbIoAgTijBKBZuXbHOm5xj\n" + + "58bvUeZt9k61U/c+AzJc7NnNf3HfHEBaXhvT5pm4GiVoFKmQZ9v8kIRNhuJ/ZGu5\n" + + "Jhw7s/E/kznehECO8/iKn/gwoNiBCHWdyYrokv08G7XzMVunma9EvZCYY0O6bZiq\n" + + "n2r0m7rvhMLkLHTrzGm9Ar6W0aXBwm03yeFo+zQIBr4AdNWXpy2Tt4NJYa4iIW5x\n" + + "RuIyA6yDiPICBrT0VAWadtalLNf+t2ZUgAB7QPX7Ixh5gUBlBRa6EUqCvQ05GzZP\n" + + "o689fzDqej+HQcRO0mU9QELnD6GsvA/+FWPaI0Cx0ONN/fpq8F7/GscTQkxWocEp\n" + + "nWgWnqGh2k7rIoPBSzZ4MRG9bqeYJkQrUv+Ky8gwnRD3sUTWs3DZgVKvhd2X8PRz\n" + + "Q5Dmqv8XIcY7mpR5nBDdY4O6z7jc8pblnJsjWNBd/mx5j2DRlH9mF1z8pACIXYNY\n" + + "/YJ5him7ZN8M0Wk9q/Dp1HK40EQMfRjg3budcRpg9a+sUMeq7cljfPaw/RPv06Lx\n" + + "rtbege1o6va0AE0s9QUrPRUS46H+VmQmth/QW8+P0MDEGyPsOh92NUprbQmgVTf/\n" + + "hACbb6sMeLEx3Kw0mndUz8PieOdt2d05RkfGE9SXjMLLV27NMRUocd9x4wCj2j7J\n" + + "2kNp8ujQIg/CoYdVa5pEdmG7FlD4UBnRsoPjCgX6vC2Lnjl5y+AXtWzrQ4d6LSnI\n" + + "dZpH+5kRPssNtIRdm70jZgRq+KDYWQwvKbu5+5lXdQn2Fodgj96cQJbFfKlC9kfh\n" + + "efykwuSn8uE8bYRwegx32px9UkeDhaPwUcLF6OC0OGgpbxyfbcqhdWhGGvTFhh3G\n" + + "oZrm8ssBJDiiLA6azYJs2pCh9CG43CCRoB+DwS4c6xLkCWU779Pi8gIovpUQBwUx\n" + + "EdQu/d1GTN9J6Vy36ZEoc7KIiddC5sH+CHxju+LX2IIv2OzqLwFiwH6r+7NQ378z\n" + + "aCOMMBTNMEQsyauJS1vfLkl/mnHyxVYpbwi9NoJCfAnUZntsEEP1mn7G3S4+IPYe\n" + + "Qy7hBUQamFs3uT7xaOcbnoiHvlQ1rm88HrohWtVQV4FmODrKHut4meBLUdV/ZVIC\n" + + "acel/kmq/767H28n8PaKiQOrXnPSpwpXxeKKtO+aMdvFhL9ytVOh3JTdX7y2rO6m\n" + + "XmauwfpcEWh1P04kCSl39Q0fi1ZzNw2O3/fdEdn+k1hNd05utNuD4YPF8t3ph+Gm\n" + + "fybXAgWaKx5qEyrBKPKGSpHNVCM++9nrVNzSlPcDcrtrGTd2E1iQ/eWdoN2hCi2v\n" + + "m7EctANAg+XPcrCUYRqV8FDqP7BabLLXvl/2aJ4tEwYq2MkgA/K2svXK0NsUbzC/\n" + + "703auA9NG0XnSGsM2ir4ZzHtrbb1jW6ipAvc3sdlDI+y6Mv8Ju/mJUPQouvsfaOC\n" + + "AzAwggMsMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQW\n" + + "BBQu8UGIwoTmWRQQ7brqObj6sy3nPjAfBgNVHSMEGDAWgBQu8UGIwoTmWRQQ7brq\n" + + "Obj6sy3nPjCCAscGCmCGSAGG+mtQBgEEggK3MIICswIUTggpfah2kbN+5mHbCwF8\n" + + "takhZ/ygCgYIKoZIzj0EAwShgY4wgYsxCzAJBgNVBAYTAlhYMTUwMwYDVQQKDCxS\n" + + "b3lhbCBJbnN0aXR1dGUgb2YgUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZTErMCkG\n" + + "A1UECwwiUG9zdC1IZWZmYWx1bXAgUmVzZWFyY2ggRGVwYXJ0bWVudDEYMBYGA1UE\n" + + "AwwPRUNEU0EgUm9vdCAtIEcxo4GOMIGLMQswCQYDVQQGEwJYWDE1MDMGA1UECgws\n" + + "Um95YWwgSW5zdGl0dXRlIG9mIFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUxKzAp\n" + + "BgNVBAsMIlBvc3QtSGVmZmFsdW1wIFJlc2VhcmNoIERlcGFydG1lbnQxGDAWBgNV\n" + + "BAMMD0VDRFNBIFJvb3QgLSBHMTCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEAdD9\n" + + "cleoTHR/ViV1wHOF2+vy9SvqWAg9uC/dFTHYquPMh1/wL/f6LaJg2Oti1tL11kkn\n" + + "jjIXNqBijLuzAwi25hjbAPYq0gTGRgNZvIGKuJYb8PD8DsWq6KQoFzzlbwDemxV8\n" + + "HlyCxk9WL8re/EpMKPbTQs8+9hb8gtM7coXJIfK/Nv3YpEAwHQYDVR0OBBYEFI7C\n" + + "FAlgduqQOOk5rhttUsQXfZ++MB8GA1UdIwQYMBaAFI7CFAlgduqQOOk5rhttUsQX\n" + + "fZ++A4GMADCBiAJCAYVKnORbBIaDuB43sDb38eb4BB5y9o+wTLrIGV5DGA2yOUck\n" + + "H56/L7H4yVFatiUZok6sRMOgGR7BY6BvuczFo22UAkIBGEMII9tQkwp/0oikSbkp\n" + + "OMZH5UGlq8AL6TnD+YzMBgRq6dGZE/spGKLef6gyKQ1dKEatK/oLSgf9l7jgandU\n" + + "ENswDQYLKwYBBAECggsHBgUDggzeAGjxVa2J1Vv0ogdEFtU61BqPvtG23l6GBrsg\n" + + "kqPSt+6WHeHypIpiah5DKuCbbt27HvgnCe87G9+ktKlfx8N0+Sa8Y9QXfQ1gODHL\n" + + "9GeDBx6AWrLFoZ9mcXcc2VrFgFwMqCgaUj9KqeQp69r4oHWsnm/1AaxdswKMakev\n" + + "xqlYIeQDSspshGjWdxO8AuUd9ytW3f3P+IitJbG8wLnw98+LTotxgXwL4zOagkZW\n" + + "KsIC0qCq/m/RUAA7SZIf1SXyJu5tdA/b1JK4NT6H74K47mk/j+RpF320DCrVPHkB\n" + + "eyb/JmfEGuh4oJPyNL1Y5aYoGcX9c9WZpso8Hx6qndFeBpXsLGBU3XBwoKoUTiYb\n" + + "JTmZmjcUHmYH3FXfHs+2HgtyoQ+tsnN9HaLkzJzwvbxZ4dYtGXm4uz3xj7mGGKkZ\n" + + "j3LJyxzIuoW7yeOOKYXJTK+9pmmZTJw8m7qC4yXGesy7KhnoZ1/eujIFfZj5CP0E\n" + + "RfRhj9wXS3YNLDvJ1LnKtA5syjR1oYuoQ/BkfdwULtTHeuzykf074/z+nqWGOpZU\n" + + "K/Js+GJlVm+Hdi9YwS2c/QbzRkXj67gc2JNnRFid/omBJGt9bSqM04muf7kgn/FQ\n" + + "ijcj9ANPvCs9Ltgnn5bYU7RpGJZQWO13u6KwYAkbYwGHyDm3WAH8CWUduxBPj2BB\n" + + "GHyYhRV8hM0AVlOzGA2ZquzIDnnR+rzbBd6GjEuW41ZMTpKFPE1aUh8uC13biPjT\n" + + "FpEptBLEsd/69umHSoME9EpQKAE57vV22NYtSqfPiiD4KFbKHn/hQ/VsIkLsi5Lo\n" + + "9Ae5YVQoXMagHrl5R77s5fFKcjN+enRt6VyfC2mIWtBRU+QqTyd+cGTHgu9oKMsm\n" + + "x8MAzsvKe+MjmQEUe2OdcRCYMqcf0m5bbpaeIBPdqHmdLAOepCGI43CAyJGPKzEq\n" + + "+hz+iQZ1d3bG76qUErqDDGD+VEWlwcxf3qc3U5OJRb1SoA1ctLQ1d/Qp6u0MDFPN\n" + + "O0yYoby4+ai3KCGGs6xPE8N/kqFpa8vyqlQzWeKkLPJ7rdJF/JWBWag4v1noHHdD\n" + + "CvEA6x5z2UnntXr5FaZvbZV0SeDMIZz8bDeMOiHJ2np8hWoEFIqw+s7gz2IIxTvl\n" + + "pFYiayZYy0Wjo+HfzetxOUFM5as7NmC1TClVy27+I1DgVZoBVjMkXYjlGmT4u0dc\n" + + "GvIhkm5FE0o/BiNDRYB3UHAXW02Zzz6qa/xHLAQU4gdQyfIsv4D55NKlv4CoGhDf\n" + + "+gj7AYa17InmHlbux7lgDoV88mUkf+po8iCX6EeyFmbBxH5p4zYjzECdJP/Sd36S\n" + + "mj1qtSRA8oiV5q9gtW0wuXH94O9AHJjRdAqkyVhya4mzbVHZGz1MeRlUxZYUIX1k\n" + + "Cfxf6JSxbz5yXYn5e3DD3cdCX5wUT+ueJHdNlvLPyc4/dzMovY5PGzGH8/yhSwD8\n" + + "EAxFnSZEfUKdx/0crZ+nQn2AVDW+bGMPYMgCf86M35Jf0rk3AWUUwzQiGJ7Ifb/f\n" + + "txfhbn5LdMzUnvFaMulf94YWBUMNPw2rFypSACWjYwN3JF03aDipiubDt+5O33pa\n" + + "YRq5AfaFMNNRltdLfm0hZyyv8Qn7aNuDpVNsct0RrRl/lMAfLuCOv3tamh8Gsuci\n" + + "hC/qORpytvzwDBwh8GTstiJ8T6IAKTjgPDmVW633YVS0YRAEB4lTGIRMchG2APek\n" + + "qZ23L3JpHujColFHaQrHBSKh4ktZJwRjaaziwG0MEFQR0D/UBgjFCeIEj1ZaQb4C\n" + + "UOAx2+A1qpoYmIRywEPLXyF28e+UmstIEMymLZy03AZknIK43KuMPpA4J+gxjsHF\n" + + "/PjypAzKb07ey6xArZaW3PXIr7EGB16NDaAG1CdL8J2uDkt7vKNWL2Mxj2+JgzId\n" + + "VsbZkQoOaCO94Uz69Yg3aoLIlWukWWcHYxIH2bBouvOpKOVr27PNKRoZ7KvCke/l\n" + + "Sqa4BzPa0u23/oWqdrXrcaYdecDAv3Hdz29TSMu5Bzqz/XuCS/6ALCzzOPBzCmlB\n" + + "JdeLADlS+Vj2BEA6/rtJjxXSMAaWnHZzcepsYxsKoUX3qY61JjxX14YHnQjJ54QR\n" + + "DiKDhzmg1UahmdO0XaUqGnjYSf8sCGM4pkqik97GwgJWYy84QM/5YIvQBCJxWggd\n" + + "00IG3rFm0XiwbVmhcVrXazh4q7YflE3eN00tQVznmiuFZS+l+o1Y0L0VulinBSJ3\n" + + "bmyHn7TLIMCyZ5TN8Kbh6qTl+h/DPgKWkqIrACeTZ9gHOmzuxi6JppfKp17b0SLp\n" + + "E2YM24TIHNxl5b/pHmivnH1QsbwrBRc9EydHrIlGTC+NZfOCQ8vdlQkNK/gxe4ta\n" + + "O6bmloP0aryQWAB5C6RxLjA4Gh7zGsc16QovsZ5+BbdiW3XxQ/f/ESAkV77t3Luv\n" + + "+X1sVLBlsXlFn45PpJ5br0ncnBx2p0yihy2wCBPq1Sa7JkR/0AlhNSf5e0G7Ii0M\n" + + "4ZyKThRng3uy5Axu8H8F7TUE1gm8JAkkOl948JN4GutSypBbhiLABzbtmQOzE1E7\n" + + "8gOZYtlxgtmxJcPsC7bUiwaDCGcI6hzb4hGyCEWzPlqK9QqUP3fjoXPN0rJ08qlc\n" + + "rhFwTkrHuDn3KSvZTsJuyKeyI1MwYFEFyH2zA3rWY69QNvOgOp4J8qLNNByFWg5i\n" + + "Z5bBe8ewqAh6Rqvco9kFp5IPbHM2ZTCJFKe0CJIuJ5x6zJdfpuAwoxXNJkgqzojS\n" + + "MzjiU2HWsHUO3cU7T/qhDlKyVzXiz7SOq0j2+S0myeAz727WXPC4Ost6omCUDHqb\n" + + "M/sRXzWjJ/Egg3UftE76/d8yes8FVT4hAohLxaTGeUh9X3BwYCtsLJt8uyxvSiIR\n" + + "yE56oMVIcO/SpKHFQ+g9YRJgosYLZ0XOTSw9NM1T3eaAFjf18bLrH8VU5gbE4zul\n" + + "oDP2gv8MwMPwZzsgWlZ2da5JBwkj3KVvaNAaWSZXiHl7rrpQwt3fD3v3cZHaVD4h\n" + + "8/FQEyDA97cb/ZD4qU9KpR6rCM3GkZMy6ouAVd7/sQ6jhijBYd8wmc6IW+6uZ9kf\n" + + "uq7eWp8jvKKeSoXLcp0cHwLGw5NX47t0Y/o3O0ZGJLnyjTOlqh1n8eWZ1LFOar1y\n" + + "iEwsdw6HyemvrviZB1xSeAwentJFkq2V/GWDmlOnePWLT+uROA8FC5Qe59yLHem4\n" + + "R8U7fMUvNEhVY3c4ROptveN6/58rd1X0xqdxjQrMxH3+Powj0ZORPe68vLGT/uKc\n" + + "rwsgIGqzky+XHwT9HDOWEaKKctSqArRYqR5NdyoRb9zv6taByUjLkjgt3pXYsWjL\n" + + "5LfKusuyrtGcMFaZxiIBYtr7Sm1zmXUxikcT3Dgzt8McjwDPyonh9EtkHSyk8GFj\n" + + "cSQoNTOYPbteQpMeKbPYwkW3dCwxBABSVO7wTHXT4AxyUFMvFTIeG/mGG8KOsNsY\n" + + "iH1DhqJecXaI8fu0mvlTELyZ+KeBBd6/nrCWVvnNYiRjJX/oKvos+wqQ/vxgYQX0\n" + + "tnJnxvttNmHooO3GyQD+VOOZObpT2AhyIbVY3mxow5MnfYji8/jNwcUaGeqS5WQp\n" + + "+y5NaQ7Dj/xzp4rQDfncHt3k0JJW9do714CsKvMM9uZfCuwwBXXA2ygB68oesbWi\n" + + "QUpq65ClVmjwdzQunQb5gm1Bkwunx5wAKp1ipH2wl5XbOaG2cP0iw01pJrG/RveQ\n" + + "TlWKIDbHd+82IsdvtKMOr9Vv/KEnT4N5Cc41li76PbvWo1O9scTJu17xCfw+D7Qd\n" + + "Rghvih8CcZH2icbWncBdb79tIQUVA0vH7wSoE/HRu49OLewnZcTPy49DvMcabE+b\n" + + "YkZQD8fzKsJZ1EtQz4bGCRppezLdepIiVhO0uYRQ2JAW34deFEd4dA6EYAjg3QRm\n" + + "S5CZia8XIKguANXsX7Hl3Yqce9uERhs7XW9w7I7NT6WNYnLQXARwaDWMT20Sy029\n" + + "ny4awNVQmqWSxdE3tL3BsN3KRuKyxSEdAqDSBOpOOXDn+7ola7sQje5v7beWjglD\n" + + "4EHlMScraxoaHHPnqhB3AxbEslqArMKvF0rHJfYI03xMeYJDTBhOhbDax66NI64O\n" + + "vZPiMcb6KcZqFmNBw0taYxWO90jBAL2mvmMuYrlFP4ymr3kEksj+lgB4Aawy1VBj\n" + + "y1QVDimOJv27Fm1hDKeYavmrKgx4o7QV8mLu/xmdzS9rUKnj8ByX8thTW8/e9R9g\n" + + "VlLsaegFmjV7v9mgTRl9hw+OsAKK+HSonuU/Uor/ZJzYIhT8iWYgA0/a7cW94VhN\n" + + "CeFwA/1VH/19lcanYM58D+mnaJkSUnQzM1VupAAn8/nxthCMN7QNLjN/zvMoRFBs\n" + + "e0V7qq1OZoOYnKvoR01jp7MTIi5UuwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgsP\n" + + "Fhsg"); + + private static byte[] draft_dilithium_end_entity = Base64.decode( + "MIIYFjCCCyGgAwIBAgIUTVOt1yqx2TcoR2H+lxsPUk2gCzQwDQYLKwYBBAECggsH\n" + + "BgUwgY8xCzAJBgNVBAYTAlhYMTUwMwYDVQQKDCxSb3lhbCBJbnN0aXR1dGUgb2Yg\n" + + "UHVibGljIEtleSBJbmZyYXN0cnVjdHVyZTErMCkGA1UECwwiUG9zdC1IZWZmYWx1\n" + + "bXAgUmVzZWFyY2ggRGVwYXJ0bWVudDEcMBoGA1UEAwwTRGlsaXRoaXVtIFJvb3Qg\n" + + "LSBHMTAeFw0yMzA1MjUxNjUxMzhaFw0yNjA1MjExNjUxMzhaMC8xCzAJBgNVBAYT\n" + + "AlhYMQ8wDQYDVQQEDAZZYW1hZGExDzANBgNVBCoMBkhhbmFrbzCCB7QwDQYLKwYB\n" + + "BAECggsHBgUDggehAA/E/9EKaexVsYAlE0FBfYaEOa/5RbzDfHLkzkymPIWn2uCy\n" + + "TdSVMPHt3n9DjdYEAXZD+sAyKiRRXKmqtgN4Cl7o96+9V+zqDXNNuD+Ol3uJ1fUf\n" + + "UxDQDoSHmEPSJFUl5sm9veB6g+CEymf6fHRVJmqMe5m3fo5SBj/v1WT8o6blqQhd\n" + + "pOn5QdrGLkri2OHEBwyrfOrhRJuXLK7867q0rzCHGecHXb7M27GtY1JdsS3f6LR6\n" + + "Xilrw77tEJTeXOw7wkEWTqVuWOQk0MteZpb4Bnyvpt6q1z/M8w8M/Xng5O9h6vEv\n" + + "k2drOrJbtYWaAaemyW7oZq0OPDQSKJuV0BzhEc97cZEW1JG7CFyO8WutBnMVaD59\n" + + "DbVu6I3UdSIeqmtGRpG5DiNn5OH8yw/6KcTB8C24GunblXbz/EBqhvaM2DGX5/4t\n" + + "V/QvnWK3LwWraYD/tby44cRhhZ95Qtvo5nX+yQMDT2gNQX3Z1X3G6ttjey9nbFhf\n" + + "vtAKXvD9n4bbNtKwXFDxIjNpf5dswLaG23eemRp06hX6TNefPIRbjcfpiaxwNs6r\n" + + "XxNYCphrLNS8ul48D+GLaYs2lto42xhOzjdPlvsSQz+kItEWZ4tqoolQXcW4BNGK\n" + + "syDtTxJQxLaUCNVoSoQ8PRcFXVGc18sk125/qp7TOKVFZ0ygGJ3RO34wjSIbqfaP\n" + + "KV7o6eWPEFbYy545M8uUG+nDAlS/aj+TYi5nEmvnDYfzzQGfUQuEswu9IdYZSXhg\n" + + "W4IPZU7TGayxNFNE1FTK0BnOyw256LD7yZvu30bAwOUphxo+8bWCgrYXe6hHLkx8\n" + + "ceXSpCmKr8y2Pibzw5NrtqpstFj/SN1HMo1p3OZrALdTPBKqHmpWMXodNWUJ0H82\n" + + "yLKxvZyTOKXpPzK1fKTQTriwnxSRiwXq83E0DJqGaukbBEEqAEa9DYkj37f3E1j+\n" + + "pqtdEMmd+zmwY+zcPOPbzZHnHjICnNHlGQboNSXuGD9AOes1IUqDpnFh3MJYAjeP\n" + + "nUAxLVjrUqTCaCZZHMutZeNT1IxuBNrkxOL+Fv/uw6XplXGUUvVl2frp6z4t+4uA\n" + + "OyIt+aNtT+WRdMB8/dJT56TjkOvJXXZxS5KBE8ru+kIqTFTBG5+3qSPYVe35qXRS\n" + + "XMpNZGZ2GJrcxdKpsAegAH+XCN0u+fIR6QrhXphVrE77/tISp+S3dQLrXpq9eDqa\n" + + "xACaTtj0rxvIgzYp86lqtvNqcXjB9t3AsZxZzVyQT+Ih55Ak68YmPinnLHQxuSMC\n" + + "XG88e1EQqPh1Tldt8n4xpY3z4aBJ9aH/4UPLBvYsm9N9eycf7uXZjOXYhqombmKn\n" + + "KeR2c4pc3mqEAjsI6QvbxMtS8pnyNS6gIhtT2DQLVTMu3V4URxDFR8LU9Ky7NdRd\n" + + "Z2KaUqwAaw9V4FmB4ycaPWyo9xaYH4hQldgk8/Zaf+Segz4llDEK6qcqeQaavvnZ\n" + + "2a4r3DO87Yw8Vy9OCfmUXCtSOXCaZXqHnwXEMTIcThqEKdqkFxLEaPE0M0kTnXAd\n" + + "uWb6JFELV3h0Q8QcxK9QLiWfNTjy/lVZ/r4eqAnrtBAIFQYYJBfA7rryu5MXIPmp\n" + + "w2F1Ei3kP/2BnZ5XD+i5nRNOo6cOEcTUi8oPvidfj2LqQAOIlID8rKhtx1FmeJJ+\n" + + "IH/wOkifcduGVlLDQKagJI7AXzkgkxFyQxnp5g34I0IRBXtsrZdmqOlv+JA08uPP\n" + + "I+vaPzvRL66vG7djHCbiLjdumwTrqbfiXeIoZjF2nP4O+X3+fjSckPOT8Dr+OMSx\n" + + "E2nEsb1lYiQcguoF52gn0Ltcf585pa6Lezey7S6Qc+3j7XdhLH2OczWgJ4zc5SBP\n" + + "9t1EzOpVFiCMQ5V4GWS6OEizdkbaKDTAEY+9TyiXXwxU5nrMWxzGhwQ7XNaT4qpt\n" + + "Z5TFEJBF94xciP4+4EkwbBFdPo02n5AD4K8PAbXj5MuySnPSYkBfMq6DwB/BlFfc\n" + + "RKVz4Yt6KR//jJjiM93G80WhlL+DAYx3w2VtWrNXhn/W9VP0KK5Jfaecbl+tHWfQ\n" + + "87HdXqx/Z8hmPEYDXidLNGOLLj7GIt2I2ZUtC7+49q6qQEL/8y78J2q1Ef1F/jUP\n" + + "xsBMzMgGTolEyz1i6X7fO+yHY5CkJAnNVkZK2wvpSGFqIuyO3BjCJfNMlpUCmhMS\n" + + "gmv6KQ9sEdF8tbYsk9ICVzqXV3O+03y4swUaIe6o0MIiL5X45SZv9HArhjs9Laku\n" + + "BjgQ3BSWtyfFRqdsLZn+MWBX4H8YkhTxfJzofSJPqNuPUwdcdIxc7LOpkOGPkAfy\n" + + "yI2uqo6YGcgMTGMBGk5iJ3SBelrz4k9YlVi3gy7gsW4FbIvXD97h3Gqd4tkM5S8L\n" + + "A9FGl2nT/0RNag91vJ+89Zls55sm3d3Hi3ZxuNr9KgNiIuNuZaFSXdrHDo/ZinFV\n" + + "BSn6YakeJCkUkqA4kqjcoxrIF6bQWu2LcM/7PeCBPhtVH6hMn5hAF+OymGCw62+m\n" + + "ha72rqBrkUhdAMjrv3eubo0AdlUD9v1z45fs68kPEsZisHBbmAZWBcGGGieupmv2\n" + + "VYkELI9mBUYJdnDhfFVSqdmqQ68xveMvb3VxIyo/eYTLuofVJp3DJ4IbhB6ro4IC\n" + + "WDCCAlQwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFANK\n" + + "iIG5mZXV+IMcuSPREB/od032MB8GA1UdIwQYMBaAFC7xQYjChOZZFBDtuuo5uPqz\n" + + "Lec+MIIB8gYKYIZIAYb6a1AGAQSCAeIwggHeAhQs36ItK8bqD/FlXfx+e3IJLemk\n" + + "uKAKBggqhkjOPQQDBKGBjjCBizELMAkGA1UEBhMCWFgxNTAzBgNVBAoMLFJveWFs\n" + + "IEluc3RpdHV0ZSBvZiBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlMSswKQYDVQQL\n" + + "DCJQb3N0LUhlZmZhbHVtcCBSZXNlYXJjaCBEZXBhcnRtZW50MRgwFgYDVQQDDA9F\n" + + "Q0RTQSBSb290IC0gRzEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARCJUj4j7eC\n" + + "/7Xso3REUscqHlWPvW9zvl5I6TIyzEXFsWxM0QxMuNW4oXE56UiCyJklcpk0JfQU\n" + + "Gat+kKQqSUJypEAwHQYDVR0OBBYEFFtwp5gX95/2N9L349xEbCEJ17vUMB8GA1Ud\n" + + "IwQYMBaAFI7CFAlgduqQOOk5rhttUsQXfZ++A4GLADCBhwJBJyKG5vGDiDA8iddl\n" + + "vY44yI0wK5D8ayYCx2aM8fuh5XjZA+14rI50v21a41uObnW1KXRHoQeW4SZTUBuz\n" + + "yo/w7B8CQgCqwK1+cbH+YecTjnfWQHgSk1dqgPCDi0ezo+QVOHhtzfXbIs1y1z1k\n" + + "SU/BF4spioFCeKIkkJaLs+8Evy5gdx+u6DANBgsrBgEEAQKCCwcGBQOCDN4Azno4\n" + + "4bYnpwVdpeaWAaNjchhKdPxrpn4JresJGnrJnsLUrUFtUdzipe4ZhLsLRJKRC41b\n" + + "Rg0zwf4eIxRBaERbWnWDzBl5x6LlnNNtkNsBzSVyc2OkyC6Js/AFKueK7348ZSAk\n" + + "0CeWiWRCAvg8o3o1YX+Nk0J3BYcLWyf4ZH6fyExqjnikx2NgXZhPe48l8nqjAkct\n" + + "f9tdKBkMOqP3GAKvQWhDtMNDMeUoUBXXJfJWdIfclgoGmqLe74N1wgIIDCMkMmZ1\n" + + "+G8W2E9Xix7nvwzvjFZSqcnjP17yPizCAOeRAYP3FyaZb6lMZ1Pusc9Uun9c5E8P\n" + + "8vJG7CXPYH8lVrhNpMG8y3jDAW30xphkeE8yxnYKa2k4nutAijt1XPb0p9ihTcM+\n" + + "K56fSCnFFlgXZYsyEI4oCqJQFgUf+BKe+XVSR5K5hpjkH6WT+LoAgWhm5ocyUasz\n" + + "2x2vvMeo282bdFhdnHAyaDCYBG/XjEggFpzXQ1G7Dv7ECiVjdbAnLREViMSu2sDv\n" + + "dFgE+Hzmv6IpFdh1OynxkUJ2k22do/YDvo3x9008M5HjqMYGp1I4i1wfx6X9zCNZ\n" + + "k+mzPX1QQpMoZFC9RK52XpgPECe4ssDA2vVIn3t9ZufE6M8Pzc7SgMk+gANs9yKy\n" + + "1GZyTG6CxGjVpuupXtlWFyT40U9G/GZF/AYSG/qguFu4kG5QxtafpfD+g267pX4Z\n" + + "eM2p7x0J+CCUlVr81vYs9jrhBSPnc2CVxDyj+9Jokn16ek7Ulmhu34mS5TWA9Qn2\n" + + "h3eDpTDAILyPEyKEa5mWc8WnHKtfYBl4L13QUT9VScOHvGszmrN1evuqsXdblxgL\n" + + "DH3u3cDWoF90M9Y7Avu4mS38q0bnbN8emUZRTbBlH2vHcWrOTuAWmhVpNDXlmPuM\n" + + "KV/9l9cN2B2xn+vUXccGgzltZk2hjXTigi+/ZUXAeGAq8n74LkjBkwUh4RQCwH2e\n" + + "p/5VyoAGAHwtFLOLVO+OJyE+SeRtEdV4hAeqSiXl7pwqJtO3/DcQX2bxEuolZirK\n" + + "l/THY+2hm6FE8SyZwMfyj1yjzsgJ9fK/bm7pe1g7UmDNEfepnzntPUcrRYvzD1U4\n" + + "BJ1UliWDehPf3qXolcFT0lrfxeutiFz9xkytlx/MFnDReqRKBNhZ36sq4p96o8V7\n" + + "b9+X3SZrI3fF07R5C0SgBCcZK4W/p06ZUcAS9CX+g8g7H+4mupZxe1MXuetgBPZF\n" + + "rYe6xOI6OoELchWdpuIrXq9UWLJUEUjS+Cr3HKlOJWp2+xJqV7qzMKN9ky6VgfnL\n" + + "TC7smRxGPAViMsTHaJ8FnuzZeriYr6+2n2TmpL8Ubj5iYnSW7E5zFmCO1JZOPxWF\n" + + "jwfZz6RmZUBzJCf7MBxoPdPGihpWWRheyQ9gPC3TjOBV8XRPKh+OsWkeYd2cvPSy\n" + + "xNzpPgAhnpuU36kRUarmOEJANc+p7HoTENfwzQrydDmp4NXmJNV6yWNewD8knczL\n" + + "Dp6uhlWMmm5K1o8LRWhf/BMvQkVhI92FbM7RJFwI7YoxwX+hdKX44z1cIPP+CNKJ\n" + + "3YQ4GsAbWFkuDmGjKroTmFfMaDIUioci7k49YigCWgcWfCJq1YpMnUy6U31t0lPS\n" + + "/AOAmkln/D3osf1OwQLHArH4c7rdRwrOwmzM6FaG2iyQPoF4xVWNSLYFP6tUA+JS\n" + + "C2OiSFvrN1EzBfqWRXTwMjGlBXf3WQg2nEm2n/JU7i6QVXw5kQiQICN+koCHqoWc\n" + + "0dAxxNoSq52byCXbn94aR2Hc9ycyxNLOB1om4uemIuE8JeoD6V+HQeaa113LsK06\n" + + "U3ypdmZ8LMKuPMjQYG8iBC1NB+q9j2b1NRMi2DNZmDrpG5IGEh6KLISWN6cB4NOl\n" + + "EA2D7o6SZ69emLjpwaO/IX2pS6vzZnraLvCqaWr5CJo8Exp37kAqHTU4Y0EO5h8V\n" + + "Y3h8bpebYRgGIl6iypPlyDz4zzVj51zUudI+TH8z4t5eazXSkMcHiev8qpb5kVYH\n" + + "JTtut0ndqY2u9Y5GcMc7uFHnKr2jen1DAVEFol86xikRL27nJtCpZ88IXTfrKloJ\n" + + "k8vN8guI+PU1Wd7lEOnKwXScHhbmYSrz9FQqizACRtuYiqCUv5GrPX7E31bY+B0p\n" + + "lhoVO4ZRMmFAOWNkgi9x6kMeJFhlS25t8vKspE+DJOuW+Enz7uneig5K3yiI00NW\n" + + "GveQTkoVnO4eoSjwj5+JuVNlBlZdKbfX6T0ycS4QqnH+HOEF/SJvot4Coae0Fi0x\n" + + "z8/11jAGU//CeCktsysFcUMd640JIrxb8EnB8AdG8CPp9Vpv13emPnORusIXPZKf\n" + + "33B8n8MGl09c5fh9KhGtdYV9/bnNFTIxTlRi5tNBLdOQb1t3MVuv4csBI1SR2qLr\n" + + "cWA+PUddLG9d+hoRdfy4uGb5uLkRM8ckPqtHhpOsrxdVlyDKMQt0HxniG7tZXmdo\n" + + "LhdvDOZdDqRjh8Ms94WXf0TDLrlRfefEoZ4T96aZW4qeFukBvR2rEfItRd3os2Z7\n" + + "JD7yS6RPUfBAqzGWSTsDcmjxWXZQZYO6ygd1rMkr7EbabS7FJXqb/VxVEMrMFKGx\n" + + "BFy4ujJf+cJtIDw6y59rmnaVOyAD9b4a++Zz06PnymlFEi/jlLy92xYWxt+hOaJC\n" + + "AeiUoKHLbH5KiSTWlwdbjshGytlZaAjLyuC0BxfGrQurl8VJ3OkfeDX20HgntkTu\n" + + "wJhvZpbhzth9y0cpo1z/JLyMfZV6yGccEATgRP2gciEgssBFhB6FT8tWmf5IgjkS\n" + + "pYUaCqnSn2gu3MmYZF8+h++tJGpH0hrq/MhXrqwJnx3e0c1nTC6IWbrR12s8RWig\n" + + "RjEBlFt5cfgswMeWnb7UdM/vXkefNBjiWEiDGU5R+Od9N+siYh+ZyFVkrXeD1nab\n" + + "YOTtolImcu1fP/jG2v62XVC4KoBGG53Ym2fIfkDwIjQFO6exl1/d6FoVsX3D90Hd\n" + + "7+njwh8+2eJ9AU7XXwlNi8eOklxMxPeMcCFANAx+kRy9jqKvc6p1LziOXDT3yaqT\n" + + "OPHnGffVXL966PtdGK4sP5Hf2BwMpIPv6fAjprndFKDcqUOYFjGEf9wyCnrWy/+U\n" + + "TIY1PHwtgLPqVA3Rm7lThze+OAglbFG34ErkZEprLuNxtfei3hzWE5f13O47di35\n" + + "OBnxlv/LtD190fZC1rKJjU5RT9q+foWeGtSca8McXVQ39fO1QdaGm5EGpRN0DyaK\n" + + "JbVQkNDnXkHRvgZ78npwo8pmZ2Tcw8ocnHW4KCj6CT0lf4Q7THnS4BYfLtU622Nf\n" + + "LcThYTR46ItceHlsB2Kksyx0oamRCj1kvUURCj9Pl1A9Z30xeFcJnHLaRA6BJutQ\n" + + "J17N/gF4DNzAMQK8mLNEESocdeFe6l7cWWhpjZUY4QydooN2Cv1l0REehFNiDKNz\n" + + "UUK0iJ/HbxfkI6IHtR31pq70mttHeJA4UIIdU9HbytqSehKXxSrSGeXMft0tqTG5\n" + + "pu09xlcKbP800gVp680ZMye2Jsg6ebyxEz7AKmbTDoR+30o2n5IwR/wFyrSLYgp0\n" + + "cAkBozlDWndEVdACXDCKcS/WWHhHMtU7CDUlM52UWQ9Ofsj9smfv0Q24bIEadsLX\n" + + "WGiJdYWGU4iSyn6iwPqFpWFIIASuKCom6lRhNHpumcqWaNks8oGBfb2XNbFVerK6\n" + + "WxuJhDU2d9MTtfbubfAS/ll7VFChbSML3WMfZuGEHILCwtc+MhuMsQkllii7APwv\n" + + "kicHmTTTS3gg+3yLIZT0VkBcAQfAPW9WaHz28TIFhHPt8omBLP+oB+eGcYPZL4+1\n" + + "biS3ulxNNQeV/xagXVBnQsW6NBermbpR04YHrRatkv6hddsHY7cAd+c28hMr+RLw\n" + + "/aeOG2LyZw0nOuvDHYURFnarBaZJpehAZ2Im3IQjY4riBacR/nlLJy7rznZltAoP\n" + + "A+2AdIXEWX7JfnpbtS1joXLB8kbCAsBVsQ46D4S5egFMmRDNlwPf1hrnbLR69lCR\n" + + "ugT7T0IL1tbC67ieAh5QknesVLq17hPIPECQeYTOAJksr7eT9G6M8SAKevQVOipd\n" + + "ANLVQ9/jLJUQUp5lUJOK+jduoWFUHGMV6lguHzUHT3KPXIFfQrpNOJoI1t4tEewC\n" + + "7LlbOrHF2vFU3YPoltp/gpWDEfDqRUVBEgU9gMdVDkYVn+yZwxUpRhaxihKW61yx\n" + + "P4AHo26WMuoNKJ0ALgxJ4zVYFa+O+kzdNP6Lul7ihUdAVjFXUVErhJ7d7tM+GL69\n" + + "gvN0QJgd6aHYmSZ/7QjSfsVti9WcRzCh4LZHUbmW05In8LHxvNZ1/nNyVz0iUL4P\n" + + "0C7Ox1btY/JsFYAcXRggSVR+qcDFO2J9J1CCz/Akk5W2vCktmaPtDx8nTX+s4QAA\n" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAICxAVGiE="); + + private static byte[] draft_p521_root = Base64.decode( + "MIIDBTCCAmagAwIBAgIUTggpfah2kbN+5mHbCwF8takhZ/wwCgYIKoZIzj0EAwQw\n" + + "gYsxCzAJBgNVBAYTAlhYMTUwMwYDVQQKDCxSb3lhbCBJbnN0aXR1dGUgb2YgUHVi\n" + + "bGljIEtleSBJbmZyYXN0cnVjdHVyZTErMCkGA1UECwwiUG9zdC1IZWZmYWx1bXAg\n" + + "UmVzZWFyY2ggRGVwYXJ0bWVudDEYMBYGA1UEAwwPRUNEU0EgUm9vdCAtIEcxMB4X\n" + + "DTIzMDUyNTE2NTEzOFoXDTMzMDUxMjE2NTEzOFowgYsxCzAJBgNVBAYTAlhYMTUw\n" + + "MwYDVQQKDCxSb3lhbCBJbnN0aXR1dGUgb2YgUHVibGljIEtleSBJbmZyYXN0cnVj\n" + + "dHVyZTErMCkGA1UECwwiUG9zdC1IZWZmYWx1bXAgUmVzZWFyY2ggRGVwYXJ0bWVu\n" + + "dDEYMBYGA1UEAwwPRUNEU0EgUm9vdCAtIEcxMIGbMBAGByqGSM49AgEGBSuBBAAj\n" + + "A4GGAAQB0P1yV6hMdH9WJXXAc4Xb6/L1K+pYCD24L90VMdiq48yHX/Av9/otomDY\n" + + "62LW0vXWSSeOMhc2oGKMu7MDCLbmGNsA9irSBMZGA1m8gYq4lhvw8PwOxaropCgX\n" + + "POVvAN6bFXweXILGT1Yvyt78Skwo9tNCzz72FvyC0ztyhckh8r82/dijYzBhMA8G\n" + + "A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSOwhQJYHbq\n" + + "kDjpOa4bbVLEF32fvjAfBgNVHSMEGDAWgBSOwhQJYHbqkDjpOa4bbVLEF32fvjAK\n" + + "BggqhkjOPQQDBAOBjAAwgYgCQgGFSpzkWwSGg7geN7A29/Hm+AQecvaPsEy6yBle\n" + + "QxgNsjlHJB+evy+x+MlRWrYlGaJOrETDoBkewWOgb7nMxaNtlAJCARhDCCPbUJMK\n" + + "f9KIpEm5KTjGR+VBpavAC+k5w/mMzAYEaunRmRP7KRii3n+oMikNXShGrSv6C0oH\n" + + "/Ze44Gp3VBDb\n"); + + private static byte[] draft_ecdsa_signing_end_entity = Base64.decode( + "MIICYTCCAcOgAwIBAgIULN+iLSvG6g/xZV38fntyCS3ppLgwCgYIKoZIzj0EAwQw\n" + + "gYsxCzAJBgNVBAYTAlhYMTUwMwYDVQQKDCxSb3lhbCBJbnN0aXR1dGUgb2YgUHVi\n" + + "bGljIEtleSBJbmZyYXN0cnVjdHVyZTErMCkGA1UECwwiUG9zdC1IZWZmYWx1bXAg\n" + + "UmVzZWFyY2ggRGVwYXJ0bWVudDEYMBYGA1UEAwwPRUNEU0EgUm9vdCAtIEcxMB4X\n" + + "DTIzMDUyNTE2NTEzOFoXDTI2MDUyMTE2NTEzOFowLzELMAkGA1UEBhMCWFgxDzAN\n" + + "BgNVBAQMBllhbWFkYTEPMA0GA1UEKgwGSGFuYWtvMFkwEwYHKoZIzj0CAQYIKoZI\n" + + "zj0DAQcDQgAEQiVI+I+3gv+17KN0RFLHKh5Vj71vc75eSOkyMsxFxbFsTNEMTLjV\n" + + "uKFxOelIgsiZJXKZNCX0FBmrfpCkKklCcqNgMF4wDAYDVR0TAQH/BAIwADAOBgNV\n" + + "HQ8BAf8EBAMCB4AwHQYDVR0OBBYEFFtwp5gX95/2N9L349xEbCEJ17vUMB8GA1Ud\n" + + "IwQYMBaAFI7CFAlgduqQOOk5rhttUsQXfZ++MAoGCCqGSM49BAMEA4GLADCBhwJB\n" + + "JyKG5vGDiDA8iddlvY44yI0wK5D8ayYCx2aM8fuh5XjZA+14rI50v21a41uObnW1\n" + + "KXRHoQeW4SZTUBuzyo/w7B8CQgCqwK1+cbH+YecTjnfWQHgSk1dqgPCDi0ezo+QV\n" + + "OHhtzfXbIs1y1z1kSU/BF4spioFCeKIkkJaLs+8Evy5gdx+u6A=="); + + private static byte[] draft_ecdsa_dual_use_end_entity = Base64.decode( + "MIIDyzCCAyygAwIBAgIUHfGFg4ZrE6+0wdcuN8sDeelJ0vswCgYIKoZIzj0EAwQw\n" + + "gYsxCzAJBgNVBAYTAlhYMTUwMwYDVQQKDCxSb3lhbCBJbnN0aXR1dGUgb2YgUHVi\n" + + "bGljIEtleSBJbmZyYXN0cnVjdHVyZTErMCkGA1UECwwiUG9zdC1IZWZmYWx1bXAg\n" + + "UmVzZWFyY2ggRGVwYXJ0bWVudDEYMBYGA1UEAwwPRUNEU0EgUm9vdCAtIEcxMB4X\n" + + "DTIzMDUyNTE2NTEzOFoXDTI2MDUyMTE2NTEzOFowLzELMAkGA1UEBhMCWFgxDzAN\n" + + "BgNVBAQMBllhbWFkYTEPMA0GA1UEKgwGSGFuYWtvMHYwEAYHKoZIzj0CAQYFK4EE\n" + + "ACIDYgAEWwkBuIUjKW65GdUP+hqcs3S8TUCVhigr/soRsdla27VHNK9XC/grcijP\n" + + "ImvPTCXdvP47GjrTlDDv92Ph1o0uFR2Rcgt3lbWNprNGOWE6j7m1qNpIxnRxF/mR\n" + + "noQk837Io4IBqjCCAaYwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCAwgwHQYD\n" + + "VR0OBBYEFArjoP6d1CV2mLXrcuvKDOe/PfXxMB8GA1UdIwQYMBaAFI7CFAlgduqQ\n" + + "OOk5rhttUsQXfZ++MIIBRAYKYIZIAYb6a1AGAQSCATQwggEwAhQs36ItK8bqD/Fl\n" + + "Xfx+e3IJLemkuDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEIlSPiPt4L/teyj\n" + + "dERSxyoeVY+9b3O+XkjpMjLMRcWxbEzRDEy41bihcTnpSILImSVymTQl9BQZq36Q\n" + + "pCpJQnKkLzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFFtwp5gX95/2N9L349xE\n" + + "bCEJ17vUA4GLADCBhwJBJyKG5vGDiDA8iddlvY44yI0wK5D8ayYCx2aM8fuh5XjZ\n" + + "A+14rI50v21a41uObnW1KXRHoQeW4SZTUBuzyo/w7B8CQgCqwK1+cbH+YecTjnfW\n" + + "QHgSk1dqgPCDi0ezo+QVOHhtzfXbIs1y1z1kSU/BF4spioFCeKIkkJaLs+8Evy5g\n" + + "dx+u6DAKBggqhkjOPQQDBAOBjAAwgYgCQgDrJbcn+dLO5HqHlhaW6G1FuNWLz1h3\n" + + "OXYNb92b7aSsa478EsE7hE40her99+33/ws5EJp4+mtWBb6+09Be8ARC0AJCAJ9C\n" + + "q55HKUbwR5+sYUtXk1021jyjhTeRVzCXcq1AiVYriSSC9ZbBGjdzPmhtmuHWRXKY\n" + + "5vbNh5DO/8/9ucvLiIrS\n"); + + public void setUp() + { + if (Security.getProvider("BC") == null) + { + Security.addProvider(new BouncyCastleProvider()); + } + if (Security.getProvider("BCPQC") == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + } + + public void testDeltaExtract() + throws Exception + { + X509CertificateHolder baseCert = new X509CertificateHolder(baseCertData); + + assertTrue(baseCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(baseCert.getSubjectPublicKeyInfo()))); + + X509CertificateHolder deltaCert = DeltaCertificateTool.extractDeltaCertificate(baseCert); + + assertTrue(deltaCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BCPQC").build(deltaCert.getSubjectPublicKeyInfo()))); + + X509CertificateHolder extCert = new X509CertificateHolder(extracted); + + assertTrue(extCert.equals(deltaCert)); + } + + public void testDeltaRsaEC() + throws Exception + { + X509CertificateHolder baseCert = new X509CertificateHolder(rsa_ec_cert); + + assertTrue(baseCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(baseCert.getSubjectPublicKeyInfo()))); + + X509CertificateHolder deltaCert = DeltaCertificateTool.extractDeltaCertificate(baseCert); + + assertTrue(deltaCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(deltaCert.getSubjectPublicKeyInfo()))); + } + + public void testDeltaCertRequest() + throws Exception + { + PKCS10CertificationRequest pkcs10CertReq = new PKCS10CertificationRequest(deltaCertReq); + + assertTrue(pkcs10CertReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(pkcs10CertReq.getSubjectPublicKeyInfo()))); + + Attribute[] attributes = pkcs10CertReq.getAttributes(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.2")); + + DeltaCertificateRequestAttributeValue deltaReq = new DeltaCertificateRequestAttributeValue(attributes[0]); + + assertTrue(DeltaCertAttributeUtils.isDeltaRequestSignatureValid(pkcs10CertReq, new JcaContentVerifierProviderBuilder().setProvider("BC").build(deltaReq.getSubjectPKInfo()))); + + KeyPairGenerator kpgB = KeyPairGenerator.getInstance("EC", "BC"); + + kpgB.initialize(new ECNamedCurveGenParameterSpec("P-256")); + + KeyPair kpB = kpgB.generateKeyPair(); + + Date notBefore = new Date(System.currentTimeMillis() - 5000); + Date notAfter = new Date(System.currentTimeMillis() + 1000 * 60 * 60); + X509v3CertificateBuilder bldr = new X509v3CertificateBuilder( + new X500Name("CN=Chameleon CA 1"), + BigInteger.valueOf(System.currentTimeMillis()), + notBefore, + notAfter, + pkcs10CertReq.getSubject(), + pkcs10CertReq.getSubjectPublicKeyInfo()); + + ContentSigner signer = new JcaContentSignerBuilder("SHA256withECDSA").build(kpB.getPrivate()); + + X509v3CertificateBuilder deltaBldr = new X509v3CertificateBuilder( + new X500Name("CN=Chameleon CA 2"), + BigInteger.valueOf(System.currentTimeMillis()), + notBefore, + notAfter, + deltaReq.getSubject(), + deltaReq.getSubjectPKInfo()); + if (deltaReq.getExtensions() != null) + { + Extensions extensions = deltaReq.getExtensions(); + for (Enumeration e = extensions.oids(); e.hasMoreElements();) + { + deltaBldr.addExtension(extensions.getExtension((ASN1ObjectIdentifier)e.nextElement())); + } + } + + X509CertificateHolder deltaCert = deltaBldr.build(signer); + + Extension deltaExt = DeltaCertificateTool.makeDeltaCertificateExtension( + false, + deltaCert); + bldr.addExtension(deltaExt); + + X509CertificateHolder chameleonCert = bldr.build(signer); + + assertTrue(chameleonCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(kpB.getPublic()))); + + X509CertificateHolder exDeltaCert = DeltaCertificateTool.extractDeltaCertificate(chameleonCert); + + assertTrue(exDeltaCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(kpB.getPublic()))); + } + + public void testDeltaCertWithExtensions() + throws Exception + { + X500Name subject = new X500Name("CN=Test Subject"); + + KeyPairGenerator kpgA = KeyPairGenerator.getInstance("RSA", "BC"); + + kpgA.initialize(2048); + + KeyPair kpA = kpgA.generateKeyPair(); + + KeyPairGenerator kpgB = KeyPairGenerator.getInstance("EC", "BC"); + + kpgB.initialize(new ECNamedCurveGenParameterSpec("P-256")); + + KeyPair kpB = kpgB.generateKeyPair(); + + ContentSigner signerA = new JcaContentSignerBuilder("SHA256withRSA").build(kpA.getPrivate()); + + Date notBefore = new Date(System.currentTimeMillis() - 5000); + Date notAfter = new Date(System.currentTimeMillis() + 1000 * 60 * 60); + X509v3CertificateBuilder bldr = new X509v3CertificateBuilder( + new X500Name("CN=Chameleon CA 1"), + BigInteger.valueOf(System.currentTimeMillis()), + notBefore, + notAfter, + subject, + SubjectPublicKeyInfo.getInstance(kpA.getPublic().getEncoded())); + + bldr.addExtension(Extension.basicConstraints, true, new BasicConstraints(false)); + + ContentSigner signerB = new JcaContentSignerBuilder("SHA256withECDSA").build(kpB.getPrivate()); + + X509v3CertificateBuilder deltaBldr = new X509v3CertificateBuilder( + new X500Name("CN=Chameleon CA 2"), + BigInteger.valueOf(System.currentTimeMillis()), + notBefore, + notAfter, + subject, + SubjectPublicKeyInfo.getInstance(kpB.getPublic().getEncoded())); + + deltaBldr.addExtension(Extension.basicConstraints, true, new BasicConstraints(false)); + + X509CertificateHolder deltaCert = deltaBldr.build(signerB); + + Extension deltaExt = DeltaCertificateTool.makeDeltaCertificateExtension( + false, + deltaCert); + bldr.addExtension(deltaExt); + + X509CertificateHolder chameleonCert = bldr.build(signerA); + + assertTrue(chameleonCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(kpA.getPublic()))); + + DeltaCertificateDescriptor deltaCertDesc = DeltaCertificateDescriptor.fromExtensions(chameleonCert.getExtensions()); + + assertNull(deltaCertDesc.getExtensions()); + assertNull(deltaCertDesc.getSubject()); + assertNotNull(deltaCertDesc.getIssuer()); + + X509CertificateHolder exDeltaCert = DeltaCertificateTool.extractDeltaCertificate(chameleonCert); + + assertTrue(exDeltaCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(kpB.getPublic()))); + } + + public void testCheckCreationAltCertWithDelta() + throws Exception + { + if (Security.getProvider("BCPQC") == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + + KeyPairGenerator kpgB = KeyPairGenerator.getInstance("EC", "BC"); + + kpgB.initialize(new ECNamedCurveGenParameterSpec("P-256")); + + KeyPair kpB = kpgB.generateKeyPair(); + + KeyPairGenerator kpGen = KeyPairGenerator.getInstance("Dilithium", "BCPQC"); + + kpGen.initialize(DilithiumParameterSpec.dilithium2, new SecureRandom()); + + KeyPair kp = kpGen.generateKeyPair(); + + PrivateKey privKey = kp.getPrivate(); + PublicKey pubKey = kp.getPublic(); + + KeyPairGenerator ecKpGen = KeyPairGenerator.getInstance("EC", "BC"); + + ecKpGen.initialize(new ECNamedCurveGenParameterSpec("P-256"), new SecureRandom()); + + KeyPair ecKp = ecKpGen.generateKeyPair(); + + PrivateKey ecPrivKey = ecKp.getPrivate(); + PublicKey ecPubKey = ecKp.getPublic(); + + Date notBefore = new Date(System.currentTimeMillis() - 5000); + Date notAfter = new Date(System.currentTimeMillis() + 1000 * 60 * 60); + + // + // distinguished name table. + // + X500Name issuer = new X500Name("CN=Chameleon Base Issuer"); + X500Name subject = new X500Name("CN=Chameleon Base Subject"); + + // + // create base certificate - version 3 + // + ContentSigner sigGen = new JcaContentSignerBuilder("SHA256withECDSA").setProvider("BC").build(ecPrivKey); + + ContentSigner altSigGen = new JcaContentSignerBuilder("Dilithium2").setProvider("BCPQC").build(privKey); + + X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( + issuer, + BigInteger.valueOf(1), + notBefore, + notAfter, + subject, + ecPubKey) + .addExtension(Extension.basicConstraints, true, new BasicConstraints(false)) + .addExtension(Extension.subjectAltPublicKeyInfo, false, SubjectAltPublicKeyInfo.getInstance(kp.getPublic().getEncoded())); + + ContentSigner signerB = new JcaContentSignerBuilder("SHA256withECDSA").build(kpB.getPrivate()); + + X509v3CertificateBuilder deltaBldr = new X509v3CertificateBuilder( + new X500Name("CN=Chameleon CA 2"), + BigInteger.valueOf(System.currentTimeMillis()), + notBefore, + notAfter, + subject, + SubjectPublicKeyInfo.getInstance(kpB.getPublic().getEncoded())); + + deltaBldr.addExtension(Extension.basicConstraints, true, new BasicConstraints(false)) + .addExtension(Extension.subjectAltPublicKeyInfo, false, SubjectAltPublicKeyInfo.getInstance(kp.getPublic().getEncoded())); + + X509CertificateHolder deltaCert = deltaBldr.build(signerB, false, altSigGen); + + assertTrue(deltaCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(kpB.getPublic()))); + + Extension deltaExt = DeltaCertificateTool.makeDeltaCertificateExtension( + false, + deltaCert); + certGen.addExtension(deltaExt); + + X509CertificateHolder certHldr = certGen.build(sigGen, false, altSigGen); + X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHldr); + + // + // copy certificate exDeltaCert + // + + cert.checkValidity(new Date()); + + cert.verify(cert.getPublicKey()); + + // check encoded works + cert.getEncoded(); + + X509CertificateHolder certHolder = new JcaX509CertificateHolder(cert); + + // assertTrue("alt sig value wrong", certHolder.isAlternativeSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BCPQC").build(pubKey))); + + X509CertificateHolder exDeltaCert = DeltaCertificateTool.extractDeltaCertificate(new X509CertificateHolder(cert.getEncoded())); + + assertTrue(exDeltaCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(kpB.getPublic()))); + assertTrue(exDeltaCert.isAlternativeSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(pubKey))); + + assertTrue(certHldr.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(ecPubKey))); + assertTrue(certHldr.isAlternativeSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(pubKey))); + } + + /* + public void testDraftDilithiumRoot() + throws Exception + { + X509CertificateHolder baseCert = new X509CertificateHolder(draft_dilithium_root); + + assertTrue(baseCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(baseCert.getSubjectPublicKeyInfo()))); + + X509CertificateHolder deltaCert = DeltaCertificateTool.extractDeltaCertificate(baseCert); + + assertTrue(deltaCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(deltaCert.getSubjectPublicKeyInfo()))); + + X509CertificateHolder extCert = new X509CertificateHolder(draft_p521_root); + + assertTrue(extCert.equals(deltaCert)); + } + + public void testDraftDilithiumEndEntity() + throws Exception + { + X509CertificateHolder rootCert = new X509CertificateHolder(draft_dilithium_root); + X509CertificateHolder ecRootCert = new X509CertificateHolder(draft_p521_root); + X509CertificateHolder baseCert = new X509CertificateHolder(draft_dilithium_end_entity); + + assertTrue(baseCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(rootCert.getSubjectPublicKeyInfo()))); + + X509CertificateHolder deltaCert = DeltaCertificateTool.extractDeltaCertificate(baseCert); + + assertTrue(deltaCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(ecRootCert.getSubjectPublicKeyInfo()))); + + X509CertificateHolder extCert = new X509CertificateHolder(draft_ecdsa_signing_end_entity); + + assertTrue(extCert.equals(deltaCert)); + } + + public void testDraftDualUseEcDsaEndEntity() + throws Exception + { + X509CertificateHolder ecRootCert = new X509CertificateHolder(draft_p521_root); + X509CertificateHolder baseCert = new X509CertificateHolder(draft_ecdsa_dual_use_end_entity); + + assertTrue(baseCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(ecRootCert.getSubjectPublicKeyInfo()))); + + X509CertificateHolder deltaCert = DeltaCertificateTool.extractDeltaCertificate(baseCert); + + X509CertificateHolder extCert = new X509CertificateHolder(draft_ecdsa_signing_end_entity); + + assertTrue(extCert.equals(deltaCert)); + + assertTrue(deltaCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(ecRootCert.getSubjectPublicKeyInfo()))); + } + */ + +// public static void main(String[] args) +// throws Exception +// { +// X509CertificateHolder x509cert = (X509CertificateHolder)new PEMParser(new FileReader("../bc-kotlin/ta_dil_cert.pem")).readObject(); +// +// Extension ext = x509cert.getExtension(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.1")); +// +// System.err.println(ASN1Dump.dumpAsString(ext.getParsedValue())); +// } +} \ No newline at end of file diff --git a/pkix/src/test/java/org/bouncycastle/cert/test/ExternalKeyTest.java b/pkix/src/test/java/org/bouncycastle/cert/test/ExternalKeyTest.java index ab37148355..20286b05b6 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/test/ExternalKeyTest.java +++ b/pkix/src/test/java/org/bouncycastle/cert/test/ExternalKeyTest.java @@ -1,6 +1,7 @@ package org.bouncycastle.cert.test; import java.io.IOException; +import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; @@ -23,6 +24,7 @@ import org.bouncycastle.jcajce.ExternalPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.test.SimpleTest; @@ -39,6 +41,7 @@ public void performTest() { checkPublicKeyInfo(); checkCertificate(); + checkCertificateDilithium(); } private void checkPublicKeyInfo() @@ -62,7 +65,7 @@ private void checkPublicKeyInfo() isEquals(new GeneralName(GeneralName.uniformResourceIdentifier, "http://localhost"), extValue.getLocation()); isEquals(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256), extValue.getHashAlg()); - isTrue(areEqual(keyDigest, extValue.getHashVal().getOctets())); + isTrue(areEqual(keyDigest, extValue.getHashValue())); } private void checkCertificate() @@ -86,11 +89,69 @@ private void checkCertificate() X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder); } + private void checkCertificateDilithium() + throws Exception + { + KeyPairGenerator kpGen = KeyPairGenerator.getInstance("ML-DSA-87"); + + KeyPair kp = kpGen.generateKeyPair(); + + ExternalPublicKey externalKey = new ExternalPublicKey(kp.getPublic(), + new GeneralName(GeneralName.uniformResourceIdentifier, "https://localhost"), + MessageDigest.getInstance("SHA256")); + + X500Name name = new X500Name("C=XX, O=Royal Institute of Public Key Infrastructure, OU=Post-Heffalump Research Department, CN=External Key Test"); + long time = System.currentTimeMillis(); + JcaX509v1CertificateBuilder certBldr = new JcaX509v1CertificateBuilder( + name, BigInteger.valueOf(System.currentTimeMillis()), new Date(time - 5000), new Date(time + 365L * 24L * 60 * 60 * 5000), name, externalKey); + + X509CertificateHolder certHolder = certBldr.build(new JcaContentSignerBuilder("ML-DSA-87").build(kp.getPrivate())); + + X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder); +// System.err.println(ASN1Dump.dumpAsString(ASN1Primitive.fromByteArray(cert.getEncoded()))); +// +// StringWriter sWrt = new StringWriter(); +// JcaPEMWriter pWrt = new JcaPEMWriter(sWrt); +// +// pWrt.writeObject(cert); +// +// pWrt.writeObject(kp.getPublic()); +// +// pWrt.close(); +// +// SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(externalKey.getEncoded()); +// +// System.err.println(externalKey.getEncoded().length + " " + kp.getPublic().getEncoded().length); +// System.err.println(ASN1Dump.dumpAsString(info, true)); +// +// System.err.println(ASN1Dump.dumpAsString(ASN1Primitive.fromByteArray(info.getPublicKeyData().getOctets()))); +// System.err.println(sWrt.toString()); + } + public static void main( String[] args) + throws Exception { Security.addProvider(new BouncyCastleProvider()); runTest(new ExternalKeyTest()); + + Security.addProvider(new BouncyCastlePQCProvider()); +// KeyPairGenerator kpGen = KeyPairGenerator.getInstance("CMCE"); +// +// KeyPair kp = kpGen.generateKeyPair(); +// +// ExternalPublicKey externalKey = new ExternalPublicKey(kp.getPublic(), +// new GeneralName(GeneralName.uniformResourceIdentifier, "https://localhost"), +// MessageDigest.getInstance("SHA256")); +// +// X500Name name = new X500Name("CN=Test"); +// long time = System.currentTimeMillis(); +// JcaX509v1CertificateBuilder certBldr = new JcaX509v1CertificateBuilder( +// name, BigIntegers.ONE, new Date(time - 5000), new Date(time + 50000), name, externalKey); +// +// X509CertificateHolder certHolder = certBldr.build(new JcaContentSignerBuilder("SHA256withECDSA").build(kp.getPrivate())); +// +// X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder); } } diff --git a/pkix/src/test/java/org/bouncycastle/cert/test/GOSTR3410_2012_256GenerateCertificate.java b/pkix/src/test/java/org/bouncycastle/cert/test/GOSTR3410_2012_256GenerateCertificate.java new file mode 100644 index 0000000000..8ef1842940 --- /dev/null +++ b/pkix/src/test/java/org/bouncycastle/cert/test/GOSTR3410_2012_256GenerateCertificate.java @@ -0,0 +1,112 @@ +package org.bouncycastle.cert.test; + +import java.math.BigInteger; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Provider; +import java.security.Security; +import java.security.spec.ECGenParameterSpec; +import java.time.ZonedDateTime; +import java.util.Date; + +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.util.test.SimpleTest; + +public class GOSTR3410_2012_256GenerateCertificate + extends SimpleTest +{ + public static final String PARAMS = "Tc26-Gost-3410-12-256-paramSetB"; + public static final String SIGNATURE_ALGORITHM = "GOST3411WITHGOST3410-2012-256"; + private static final String ALGORITHM = "ECGOST3410-2012"; + + public String getName() + { + return "GOSTR3410_2012_256GenerateCertificate"; + } + + public void performTest() + throws Exception + { + Provider bcProvider = new BouncyCastleProvider(); + Security.addProvider(bcProvider); + + X509CertificateHolder certificate = generateSelfSignedCertificate(); + + ASN1Sequence parameters = + (ASN1Sequence)certificate.getSubjectPublicKeyInfo().getAlgorithm().getParameters(); + isEquals("Expected parameters size: 1, actual: " + parameters.size(), 1, parameters.size()); + } + + private static X509CertificateHolder generateSelfSignedCertificate() + { + try + { + KeyPairGenerator keygen = KeyPairGenerator.getInstance(ALGORITHM, BouncyCastleProvider.PROVIDER_NAME); + keygen.initialize(new ECGenParameterSpec(PARAMS)); + + KeyPair keyPair = keygen.generateKeyPair(); + + X500Name subject = new X500Name("CN=TEST"); + X500Name issuer = subject; + BigInteger serial = BigInteger.ONE; + ZonedDateTime notBefore = ZonedDateTime.now(); + ZonedDateTime notAfter = notBefore.plusYears(1); + + X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder( + issuer, + serial, + Date.from(notBefore.toInstant()), + Date.from(notAfter.toInstant()), + subject, + keyPair.getPublic() + ); + ContentSigner contentSigner = + new JcaContentSignerBuilder(SIGNATURE_ALGORITHM).build(keyPair.getPrivate()); + + return certificateBuilder.build(contentSigner); + } + catch (OperatorCreationException e) + { + System.out.println("Can not create certificate. " + e.getMessage()); + e.printStackTrace(); + } + catch (NoSuchAlgorithmException e) + { + System.out.printf("Algorithm %s is not found. %s\n", ALGORITHM, e.getMessage()); + e.printStackTrace(); + } + catch (InvalidAlgorithmParameterException e) + { + System.out.printf("Initialization parameter %s is not found for algorithm %s. %s\n", PARAMS, ALGORITHM, + e.getMessage()); + e.printStackTrace(); + } + catch (NoSuchProviderException e) + { + System.out.printf("Crypto provider BC is not found. %s\n", e.getMessage()); + e.printStackTrace(); + } + + return null; + } + + public static void main( + String[] args) + throws Exception + { + Security.addProvider(new BouncyCastleProvider()); + + runTest(new GOSTR3410_2012_256GenerateCertificate()); + } +} diff --git a/pkix/src/test/java/org/bouncycastle/cert/test/PKCS10Test.java b/pkix/src/test/java/org/bouncycastle/cert/test/PKCS10Test.java index 2ea4ef749c..c9052928ed 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/test/PKCS10Test.java +++ b/pkix/src/test/java/org/bouncycastle/cert/test/PKCS10Test.java @@ -259,7 +259,7 @@ private void createECRequest(String algorithm, ASN1ObjectIdentifier algOid, ASN1 sig.update(req.toASN1Structure().getCertificationRequestInfo().getEncoded()); - if (!sig.verify(req.toASN1Structure().getSignature().getBytes())) + if (!sig.verify(req.toASN1Structure().getSignature().getOctets())) { fail("signature not mapped correctly."); } diff --git a/pkix/src/test/java/org/bouncycastle/cert/test/SHA256DigestCalculator.java b/pkix/src/test/java/org/bouncycastle/cert/test/SHA256DigestCalculator.java index 69dc235bfe..a6c3107013 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/test/SHA256DigestCalculator.java +++ b/pkix/src/test/java/org/bouncycastle/cert/test/SHA256DigestCalculator.java @@ -31,7 +31,7 @@ public byte[] getDigest() bOut.reset(); - Digest sha256 = new SHA256Digest(); + Digest sha256 = SHA256Digest.newInstance(); sha256.update(bytes, 0, bytes.length); diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/AllTests.java b/pkix/src/test/java/org/bouncycastle/cms/test/AllTests.java index f2160badf5..edc7aff46d 100644 --- a/pkix/src/test/java/org/bouncycastle/cms/test/AllTests.java +++ b/pkix/src/test/java/org/bouncycastle/cms/test/AllTests.java @@ -37,6 +37,10 @@ public static Test suite() suite.addTest(BcEnvelopedDataTest.suite()); suite.addTest(BcSignedDataTest.suite()); + suite.addTest(CMSAuthEnvelopedDataStreamGeneratorTest.suite()); + suite.addTest(InputStreamWithMACTest.suite()); + + suite.addTest(new CMSTestSetup(new TestSuite(GOSTR3410_2012_256CmsSignVerifyDetached.class))); try { diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/AuthEnvelopedDataTest.java b/pkix/src/test/java/org/bouncycastle/cms/test/AuthEnvelopedDataTest.java index 09d0fba8b0..1f6736766a 100644 --- a/pkix/src/test/java/org/bouncycastle/cms/test/AuthEnvelopedDataTest.java +++ b/pkix/src/test/java/org/bouncycastle/cms/test/AuthEnvelopedDataTest.java @@ -18,9 +18,11 @@ import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; +import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.GCMParameters; import org.bouncycastle.asn1.cms.Time; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cms.CMSAttributeTableGenerationException; import org.bouncycastle.cms.CMSAttributeTableGenerator; import org.bouncycastle.cms.CMSAuthEnvelopedData; @@ -205,6 +207,59 @@ public AttributeTable getAttributes(Map parameters) assertEquals("Hello, world!", Strings.fromByteArray(recData)); } + public void testGCMwithHKDF() + throws Exception + { + if (!CMSTestUtil.isAeadAvailable()) + { + return; + } + byte[] message = Strings.toByteArray("Hello, world!"); + OutputEncryptor candidate = new JceCMSContentEncryptorBuilder(NISTObjectIdentifiers.id_aes128_GCM) + .setEnableSha256HKdf(true) + .setProvider(BC).build(); + + assertEquals(CMSObjectIdentifiers.id_alg_cek_hkdf_sha256, candidate.getAlgorithmIdentifier().getAlgorithm()); + + AlgorithmIdentifier kdfParams = AlgorithmIdentifier.getInstance(candidate.getAlgorithmIdentifier().getParameters()); + + assertEquals(NISTObjectIdentifiers.id_aes128_GCM, kdfParams.getAlgorithm()); + assertNotNull(GCMParameters.getInstance(kdfParams.getParameters())); + + assertTrue(candidate instanceof OutputAEADEncryptor); + + OutputAEADEncryptor macProvider = (OutputAEADEncryptor)candidate; + + CMSAuthEnvelopedDataGenerator authGen = new CMSAuthEnvelopedDataGenerator(); + + authGen.setAuthenticatedAttributeGenerator(new CMSAttributeTableGenerator() + { + public AttributeTable getAttributes(Map parameters) + throws CMSAttributeTableGenerationException + { + Hashtable attrs = new Hashtable(); + Attribute testAttr = new Attribute(CMSAttributes.signingTime, + new DERSet(new Time(new Date()))); + attrs.put(testAttr.getAttrType(), testAttr); + return new AttributeTable(attrs); + } + }); + + authGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert)); + + CMSAuthEnvelopedData authData = authGen.generate(new CMSProcessableByteArray(message), macProvider); + + CMSAuthEnvelopedData encAuthData = new CMSAuthEnvelopedData(authData.getEncoded()); + + RecipientInformationStore recipients = encAuthData.getRecipientInfos(); + + RecipientInformation recipient = (RecipientInformation)recipients.getRecipients().iterator().next(); + + byte[] recData = recipient.getContent(new JceKeyTransAuthEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); + + assertEquals("Hello, world!", Strings.fromByteArray(recData)); + } + public void testCCM() throws Exception { @@ -248,7 +303,59 @@ public AttributeTable getAttributes(Map parameters) RecipientInformation recipient = (RecipientInformation)recipients.getRecipients().iterator().next(); byte[] recData = recipient.getContent(new JceKeyTransAuthEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); + assertTrue(java.util.Arrays.equals(authData.getMac(), recipient.getMac())); + assertEquals("Hello, world!", Strings.fromByteArray(recData)); + } + + public void testCCMwithHKDF() + throws Exception + { + if (!CMSTestUtil.isAeadAvailable()) + { + return; + } + byte[] message = Strings.toByteArray("Hello, world!"); + OutputEncryptor candidate = new JceCMSContentEncryptorBuilder(NISTObjectIdentifiers.id_aes128_CCM) + .setEnableSha256HKdf(true).setProvider(BC).build(); + + assertEquals(CMSObjectIdentifiers.id_alg_cek_hkdf_sha256, candidate.getAlgorithmIdentifier().getAlgorithm()); + + AlgorithmIdentifier kdfParams = AlgorithmIdentifier.getInstance(candidate.getAlgorithmIdentifier().getParameters()); + + assertEquals(NISTObjectIdentifiers.id_aes128_CCM, kdfParams.getAlgorithm()); + assertNotNull(GCMParameters.getInstance(kdfParams.getParameters())); + + assertTrue(candidate instanceof OutputAEADEncryptor); + + OutputAEADEncryptor macProvider = (OutputAEADEncryptor)candidate; + CMSAuthEnvelopedDataGenerator authGen = new CMSAuthEnvelopedDataGenerator(); + + authGen.setAuthenticatedAttributeGenerator(new CMSAttributeTableGenerator() + { + public AttributeTable getAttributes(Map parameters) + throws CMSAttributeTableGenerationException + { + Hashtable attrs = new Hashtable(); + Attribute testAttr = new Attribute(CMSAttributes.signingTime, + new DERSet(new Time(new Date()))); + attrs.put(testAttr.getAttrType(), testAttr); + return new AttributeTable(attrs); + } + }); + + authGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert)); + + CMSAuthEnvelopedData authData = authGen.generate(new CMSProcessableByteArray(message), macProvider); + + CMSAuthEnvelopedData encAuthData = new CMSAuthEnvelopedData(authData.getEncoded()); + + RecipientInformationStore recipients = encAuthData.getRecipientInfos(); + + RecipientInformation recipient = (RecipientInformation)recipients.getRecipients().iterator().next(); + + byte[] recData = recipient.getContent(new JceKeyTransAuthEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); + assertTrue(java.util.Arrays.equals(authData.getMac(), recipient.getMac())); assertEquals("Hello, world!", Strings.fromByteArray(recData)); } @@ -290,9 +397,12 @@ public AttributeTable getAttributes(Map parameters) RecipientInformation recipient = (RecipientInformation)recipients.getRecipients().iterator().next(); - byte[] recData = recipient.getContent(new JceKeyTransAuthEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); - - assertEquals("Hello, world!", Strings.fromByteArray(recData)); + if (System.getProperty("java.version").indexOf("1.5.") < 0) + { + byte[] recData = recipient.getContent(new JceKeyTransAuthEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); + assertTrue(java.util.Arrays.equals(authData.getMac(), recipient.getMac())); + assertEquals("Hello, world!", Strings.fromByteArray(recData)); + } } public void testBcAttributes() @@ -333,8 +443,11 @@ public AttributeTable getAttributes(Map parameters) RecipientInformation recipient = (RecipientInformation)recipients.getRecipients().iterator().next(); - byte[] recData = recipient.getContent(new JceKeyTransAuthEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); - - assertEquals("Hello, world!", Strings.fromByteArray(recData)); + if (System.getProperty("java.version").indexOf("1.5.") < 0) + { + byte[] recData = recipient.getContent(new JceKeyTransAuthEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); + + assertEquals("Hello, world!", Strings.fromByteArray(recData)); + } } } \ No newline at end of file diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/BcSignedDataTest.java b/pkix/src/test/java/org/bouncycastle/cms/test/BcSignedDataTest.java index 538f806128..b2aeea711c 100644 --- a/pkix/src/test/java/org/bouncycastle/cms/test/BcSignedDataTest.java +++ b/pkix/src/test/java/org/bouncycastle/cms/test/BcSignedDataTest.java @@ -1373,7 +1373,7 @@ private void encapsulatedTest( if (digestAlgorithm != null) { - assertTrue(signer.getDigestAlgorithmID().equals(digestAlgorithm)); + assertTrue(signer.getDigestAlgorithmID().getAlgorithm().toString() + " " + digestAlgorithm.getAlgorithm(), signer.getDigestAlgorithmID().equals(digestAlgorithm)); } if (signatureAlgorithm.indexOf("RSA") > 0) diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/CMSAuthEnvelopedDataStreamGeneratorTest.java b/pkix/src/test/java/org/bouncycastle/cms/test/CMSAuthEnvelopedDataStreamGeneratorTest.java new file mode 100644 index 0000000000..1a73d5fad3 --- /dev/null +++ b/pkix/src/test/java/org/bouncycastle/cms/test/CMSAuthEnvelopedDataStreamGeneratorTest.java @@ -0,0 +1,340 @@ +package org.bouncycastle.cms.test; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.security.KeyPair; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DERSet; +import org.bouncycastle.asn1.cms.Attribute; +import org.bouncycastle.asn1.cms.AttributeTable; +import org.bouncycastle.asn1.cms.CMSAttributes; +import org.bouncycastle.asn1.cms.GCMParameters; +import org.bouncycastle.asn1.cms.Time; +import org.bouncycastle.cms.CMSAlgorithm; +import org.bouncycastle.cms.CMSAttributeTableGenerationException; +import org.bouncycastle.cms.CMSAttributeTableGenerator; +import org.bouncycastle.cms.CMSAuthEnvelopedDataStreamGenerator; +import org.bouncycastle.cms.CMSAuthEnvelopedDataParser; +import org.bouncycastle.cms.CMSTypedStream; +import org.bouncycastle.cms.RecipientInformation; +import org.bouncycastle.cms.RecipientInformationStore; +import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; +import org.bouncycastle.cms.jcajce.JceKeyTransAuthEnvelopedRecipient; +import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.OutputAEADEncryptor; +import org.bouncycastle.operator.OutputEncryptor; +import org.bouncycastle.util.Strings; + +public class CMSAuthEnvelopedDataStreamGeneratorTest + extends TestCase +{ + public static void main(String[] args) + throws Exception + { + CMSAuthEnvelopedDataStreamGeneratorTest test = new CMSAuthEnvelopedDataStreamGeneratorTest(); + test.setUp(); + test.testGCMCCM(); + test.testNoAuthAttributes(); + test.testNoAttributes(); + + } + + private static final String BC = BouncyCastleProvider.PROVIDER_NAME; + + private static final int BUFFER_SIZE = 4000; + private static String _signDN; + private static KeyPair _signKP; + private static X509Certificate _signCert; + + private static String _origDN; + private static KeyPair _origKP; + private static X509Certificate _origCert; + + private static String _reciDN; + private static KeyPair _reciKP; + private static X509Certificate _reciCert; + + private static KeyPair _origEcKP; + private static KeyPair _reciEcKP; + private static X509Certificate _reciEcCert; + + private static boolean _initialised = false; + + private static void init() + throws Exception + { + if (!_initialised) + { + _initialised = true; + + _signDN = "O=Bouncy Castle, C=AU"; + _signKP = CMSTestUtil.makeKeyPair(); + _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); + + _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; + _origKP = CMSTestUtil.makeKeyPair(); + _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); + + _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; + _reciKP = CMSTestUtil.makeKeyPair(); + _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); + + _origEcKP = CMSTestUtil.makeEcDsaKeyPair(); + _reciEcKP = CMSTestUtil.makeEcDsaKeyPair(); + _reciEcCert = CMSTestUtil.makeCertificate(_reciEcKP, _reciDN, _signKP, _signDN); + } + } + + public static Test suite() + throws Exception + { + init(); + + return new CMSTestSetup(new TestSuite(CMSAuthEnvelopedDataStreamGeneratorTest.class)); + } + + public void setUp() + throws Exception + { + init(); + } + + public void testGCMCCM() + throws Exception + { + GCMCCMtest(CMSAlgorithm.AES128_GCM, false); + GCMCCMtest(CMSAlgorithm.AES192_GCM, false); + GCMCCMtest(CMSAlgorithm.AES256_GCM, false); + GCMCCMtest(CMSAlgorithm.AES128_CCM, false); + GCMCCMtest(CMSAlgorithm.AES192_CCM, false); + GCMCCMtest(CMSAlgorithm.AES256_CCM, false); + + GCMCCMtest(CMSAlgorithm.AES128_GCM, true); + GCMCCMtest(CMSAlgorithm.AES192_GCM, true); + GCMCCMtest(CMSAlgorithm.AES256_GCM, true); + GCMCCMtest(CMSAlgorithm.AES128_CCM, true); + GCMCCMtest(CMSAlgorithm.AES192_CCM, true); + GCMCCMtest(CMSAlgorithm.AES256_CCM, true); + } + + public void GCMCCMtest(ASN1ObjectIdentifier oid, boolean berEncodeRecipientSet) + throws Exception + { + if (!CMSTestUtil.isAeadAvailable()) + { + return; + } + byte[] message = Strings.toByteArray("Hello, world!"); + + OutputEncryptor candidate = new JceCMSContentEncryptorBuilder(oid).setProvider(BC).build(); + + assertEquals(oid, candidate.getAlgorithmIdentifier().getAlgorithm()); + assertNotNull(GCMParameters.getInstance(candidate.getAlgorithmIdentifier().getParameters())); + + assertTrue(candidate instanceof OutputAEADEncryptor); + + CMSAuthEnvelopedDataStreamGenerator authGen = new CMSAuthEnvelopedDataStreamGenerator(); + + authGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert)); + authGen.setBEREncodeRecipients(berEncodeRecipientSet); + authGen.setAuthenticatedAttributeGenerator(new CMSAttributeTableGenerator() + { + public AttributeTable getAttributes(Map parameters) + throws CMSAttributeTableGenerationException + { + Hashtable attrs = new Hashtable(); + Attribute testAttr = new Attribute(CMSAttributes.signingTime, + new DERSet(new Time(new Date()))); + attrs.put(testAttr.getAttrType(), testAttr); + return new AttributeTable(attrs); + } + }); + + authGen.setUnauthenticatedAttributeGenerator(new CMSAttributeTableGenerator() + { + public AttributeTable getAttributes(Map parameters) + throws CMSAttributeTableGenerationException + { + Hashtable attrs = new Hashtable(); + Attribute testAttr = new Attribute(CMSAttributes.signingTime, + new DERSet(new Time(new Date()))); + attrs.put(testAttr.getAttrType(), testAttr); + return new AttributeTable(attrs); + } + }); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + OutputStream out = authGen.open(bOut, ( + OutputAEADEncryptor)new JceCMSContentEncryptorBuilder(oid).setProvider(BC).build()); + out.write(message); + + out.close(); + + CMSAuthEnvelopedDataParser ep = new CMSAuthEnvelopedDataParser(bOut.toByteArray()); + + RecipientInformationStore recipients = ep.getRecipientInfos(); + + assertEquals(ep.getEncryptionAlgOID().getAlgorithm(), oid); + assertEquals(ep.getEncAlgOID(), oid.getId()); + assertNotNull(ep.getEncAlgParams()); + + Collection c = recipients.getRecipients(); + + Iterator it = c.iterator(); + + while (it.hasNext()) + { + RecipientInformation recipient = (RecipientInformation)it.next(); + + assertEquals(recipient.getKeyEncryptionAlgOID(), "1.2.840.113549.1.1.1"); + + CMSTypedStream recData = recipient.getContentStream(new JceKeyTransAuthEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); + + assertEquals(true, Arrays.equals(message, CMSTestUtil.streamToByteArray(recData.getContentStream()))); + assertTrue(Arrays.equals(ep.getMac(), recipient.getMac())); + //assertEquals(1, ep.getAuthAttrs().size()); + assertEquals(1, ep.getUnauthAttrs().size()); + } + ep.close(); + } + + public void testNoAuthAttributes() + throws Exception + { + ASN1ObjectIdentifier oid = CMSAlgorithm.AES128_GCM; + if (!CMSTestUtil.isAeadAvailable()) + { + return; + } + byte[] message = Strings.toByteArray("Hello, world!"); + + OutputEncryptor candidate = new JceCMSContentEncryptorBuilder(oid).setProvider(BC).build(); + + assertEquals(oid, candidate.getAlgorithmIdentifier().getAlgorithm()); + assertNotNull(GCMParameters.getInstance(candidate.getAlgorithmIdentifier().getParameters())); + + assertTrue(candidate instanceof OutputAEADEncryptor); + + CMSAuthEnvelopedDataStreamGenerator authGen = new CMSAuthEnvelopedDataStreamGenerator(); + + authGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert)); + + authGen.setUnauthenticatedAttributeGenerator(new CMSAttributeTableGenerator() + { + public AttributeTable getAttributes(Map parameters) + throws CMSAttributeTableGenerationException + { + Hashtable attrs = new Hashtable(); + Attribute testAttr = new Attribute(CMSAttributes.signingTime, + new DERSet(new Time(new Date()))); + attrs.put(testAttr.getAttrType(), testAttr); + return new AttributeTable(attrs); + } + }); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + OutputStream out = authGen.open(bOut, ( + OutputAEADEncryptor)new JceCMSContentEncryptorBuilder(oid).setProvider(BC).build()); + out.write(message); + + out.close(); + + CMSAuthEnvelopedDataParser ep = new CMSAuthEnvelopedDataParser(bOut.toByteArray()); + + //System.err.println(ASN1Dump.dumpAsString(ASN1Primitive.fromByteArray(bOut.toByteArray()))); + RecipientInformationStore recipients = ep.getRecipientInfos(); + + assertEquals(ep.getEncryptionAlgOID().getAlgorithm(), oid); + assertEquals(ep.getEncAlgOID(), oid.getId()); + assertNotNull(ep.getEncAlgParams()); + + Collection c = recipients.getRecipients(); + + Iterator it = c.iterator(); + + while (it.hasNext()) + { + RecipientInformation recipient = (RecipientInformation)it.next(); + + assertEquals(recipient.getKeyEncryptionAlgOID(), "1.2.840.113549.1.1.1"); + + CMSTypedStream recData = recipient.getContentStream(new JceKeyTransAuthEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); + + assertEquals(true, Arrays.equals(message, CMSTestUtil.streamToByteArray(recData.getContentStream()))); + assertTrue(Arrays.equals(ep.getMac(), recipient.getMac())); + assertNull(ep.getAuthAttrs()); + assertEquals(1, ep.getUnauthAttrs().size()); + } + ep.close(); + } + + public void testNoAttributes() + throws Exception + { + ASN1ObjectIdentifier oid = CMSAlgorithm.AES128_GCM; + if (!CMSTestUtil.isAeadAvailable()) + { + return; + } + byte[] message = Strings.toByteArray("Hello, world!"); + + OutputEncryptor candidate = new JceCMSContentEncryptorBuilder(oid).setProvider(BC).build(); + + assertEquals(oid, candidate.getAlgorithmIdentifier().getAlgorithm()); + assertNotNull(GCMParameters.getInstance(candidate.getAlgorithmIdentifier().getParameters())); + + assertTrue(candidate instanceof OutputAEADEncryptor); + + CMSAuthEnvelopedDataStreamGenerator authGen = new CMSAuthEnvelopedDataStreamGenerator(); + + authGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert)); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + OutputStream out = authGen.open(bOut, ( + OutputAEADEncryptor)new JceCMSContentEncryptorBuilder(oid).setProvider(BC).build()); + out.write(message); + + out.close(); + + CMSAuthEnvelopedDataParser ep = new CMSAuthEnvelopedDataParser(bOut.toByteArray()); + + //System.err.println(ASN1Dump.dumpAsString(ASN1Primitive.fromByteArray(bOut.toByteArray()))); + RecipientInformationStore recipients = ep.getRecipientInfos(); + + assertEquals(ep.getEncryptionAlgOID().getAlgorithm(), oid); + assertEquals(ep.getEncAlgOID(), oid.getId()); + assertNotNull(ep.getEncAlgParams()); + + Collection c = recipients.getRecipients(); + + Iterator it = c.iterator(); + + while (it.hasNext()) + { + RecipientInformation recipient = (RecipientInformation)it.next(); + + assertEquals(recipient.getKeyEncryptionAlgOID(), "1.2.840.113549.1.1.1"); + + CMSTypedStream recData = recipient.getContentStream(new JceKeyTransAuthEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); + + assertEquals(true, Arrays.equals(message, CMSTestUtil.streamToByteArray(recData.getContentStream()))); + assertTrue(Arrays.equals(ep.getMac(), recipient.getMac())); + } + ep.close(); + } +} diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/GOSTR3410_2012_256CmsSignVerifyDetached.java b/pkix/src/test/java/org/bouncycastle/cms/test/GOSTR3410_2012_256CmsSignVerifyDetached.java new file mode 100644 index 0000000000..a82ea627cd --- /dev/null +++ b/pkix/src/test/java/org/bouncycastle/cms/test/GOSTR3410_2012_256CmsSignVerifyDetached.java @@ -0,0 +1,153 @@ +package org.bouncycastle.cms.test; + +import java.security.Security; +import java.security.cert.CertPathBuilder; +import java.security.cert.CertificateException; +import java.security.cert.PKIXBuilderParameters; +import java.security.cert.TrustAnchor; +import java.security.cert.X509CertSelector; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.jcajce.JcaCertStoreBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cms.CMSException; +import org.bouncycastle.cms.CMSProcessableByteArray; +import org.bouncycastle.cms.CMSSignedData; +import org.bouncycastle.cms.SignerInformation; +import org.bouncycastle.cms.SignerInformationStore; +import org.bouncycastle.cms.SignerInformationVerifier; +import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.Store; +import org.bouncycastle.util.encoders.Base64; + +public class GOSTR3410_2012_256CmsSignVerifyDetached + extends TestCase +{ + /** + * Test GOST 2012-256 signature with id-tc26-gost-3410-2012-256-paramSetB key parameters generated by + * rtpkcs11ecp library. + */ + private static final String SIGNATURE = "MIIDDAYJKoZIhvcNAQcCoIIC/TCCAvkCAQExDDAKBggqhQMHAQECAjALBgkqhkiG9w0BBwGgggGTMIIB" + + "jzCCATygAwIBAgIVANpDv+oXKyFqD3f8s/iV0sgLZxMuMAoGCCqFAwcBAQMCMCsxCzAJBgNVBAYTAlJV" + + "MQswCQYDVQQDDAJDQTEPMA0GA1UECAwGTW9zY293MB4XDTI0MDIwNzEyNTIwMFoXDTI1MDIwNzEyNTIw" + + "MFowZTEQMA4GA1UEAwwHSXZhbm9mZjELMAkGA1UEBhMCUlUxFDASBgNVBAUTCzEyMzEyMzEyMzEyMR0w" + + "GwYJKoZIhvcNAQkBFg5pdmFub3ZAbWFpbC5ydTEPMA0GA1UECAwGTW9zY293MF4wFwYIKoUDBwEBAQEw" + + "CwYJKoUDBwECAQECA0MABEC8jIpHpWxBuYhMdgbly1RJR0ECHcL1SMklZX3u5TNdOjs66n8U5y9nt5vR" + + "KGdvecbPo5cYIlEojrprtlDuALjsMAoGCCqFAwcBAQMCA0EAAJvuewDPWkDfDFEC0L/o+6BipHCcz0Qg" + + "Mr4TU7XRXKcVkxVD8SjIc4SaWL/f/htpNIdvP91EeYDlFoOwNqDhHDGCAUAwggE8AgEBMEQwKzELMAkG" + + "A1UEBhMCUlUxCzAJBgNVBAMMAkNBMQ8wDQYDVQQIDAZNb3Njb3cCFQDaQ7/qFyshag93/LP4ldLIC2cT" + + "LjAKBggqhQMHAQECAqCBlDAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0y" + + "NDAyMDcxMjUyMDBaMCkGCSqGSIb3DQEJNDEcMBowCgYIKoUDBwEBAgKhDAYIKoUDBwEBAQEFADAvBgkq" + + "hkiG9w0BCQQxIgQg7A98XV1Tkli/l3PXrT/6cGLM/m8odS26UHEGHEPBYgMwDAYIKoUDBwEBAQEFAARA" + + "CcueaEjcNVIccepoDiU9aCbHPPF7A3zGw90Zl11T9ITBH4jNOMi4IGVn90ANgiinwKIuiu9mWMk9Y/mc" + + "jcCkQw=="; + + /** + * Expires in 2045. + */ + private static final String CA_CERTIFICATE = "MIIBTzCB+wIJAMGuFHcbok4sMAwGCCqFAwcBAQMCBQAwKzELMAkGA1UEBhMCUlUx" + + "CzAJBgNVBAMMAkNBMQ8wDQYDVQQIDAZNb3Njb3cwHhcNMTgwNjA2MTAyNzA4WhcN" + + "NDUxMDIyMTAyNzA4WjArMQswCQYDVQQGEwJSVTELMAkGA1UEAwwCQ0ExDzANBgNV" + + "BAgMBk1vc2NvdzBmMB8GCCqFAwcBAQEBMBMGByqFAwICIwEGCCqFAwcBAQICA0MA" + + "BECM6iQnPgDs6K2jmUVLHf4V63xwO2j4vO2X2kNQVELu2bROK+wBaNWkTX5TW+IO" + + "9gLZFioYMSEK2LxsIO3Zf+JeMAwGCCqFAwcBAQMCBQADQQATx6Ksy1KUuvfa2q8X" + + "kfo3pDN1x1aGo4AmQolzEpbXvzbyMy3vk+VOqegdd8KP4E3x43zaTmHmnu/G1v20" + + "VzwO"; + + private static final byte[] SIGNED_DATA = {0x01, 0x02, 0x03}; + + public void setUp() + throws Exception + { + Security.addProvider(new BouncyCastleProvider()); + } + + public void testGost3410_2012_256() + throws Exception + { + byte[] detachedCms = Base64.decode(SIGNATURE); + byte[] rootCertificate = Base64.decode(CA_CERTIFICATE); + List trustedCertificates = new ArrayList(); + trustedCertificates.add(new X509CertificateHolder(rootCertificate)); + + boolean isSignatureValid = verifyDetached(SIGNED_DATA, detachedCms, trustedCertificates); + + Assert.assertTrue(isSignatureValid); + } + + private static boolean verifyDetached(byte[] data, byte[] detachedCms, + List trustedCertificates) + throws CMSException + { + CMSSignedData cmsSignedData = new CMSSignedData(new CMSProcessableByteArray(data), detachedCms); + + boolean result = false; + try + { + HashSet trustAnchors = new HashSet(); + for (X509CertificateHolder trustedCert : trustedCertificates) + { + TrustAnchor trustAnchor = new TrustAnchor(getX509Certificate(trustedCert), null); + trustAnchors.add(trustAnchor); + } + + CertPathBuilder certPathBuilder = + CertPathBuilder.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); + Store cmsCertStore = cmsSignedData.getCertificates(); + SignerInformationStore signers = cmsSignedData.getSignerInfos(); + + for (SignerInformation signer : signers.getSigners()) + { + Collection signerCertCollection = cmsCertStore.getMatches(signer.getSID()); + + for (X509CertificateHolder signerCert : signerCertCollection) + { + // Validate signer's signature + SignerInformationVerifier verifier = new JcaSimpleSignerInfoVerifierBuilder() + .setProvider(BouncyCastleProvider.PROVIDER_NAME) + .build(signerCert); + if (!signer.verify(verifier)) + { + return false; + } + + // Validate signer's certificate chain + X509CertSelector constraints = new X509CertSelector(); + constraints.setCertificate(getX509Certificate(signerCert)); + PKIXBuilderParameters params = new PKIXBuilderParameters(trustAnchors, constraints); + + JcaCertStoreBuilder certStoreBuilder = new JcaCertStoreBuilder(); + certStoreBuilder.addCertificate(signerCert); + + params.addCertStore(certStoreBuilder.build()); + params.setRevocationEnabled(false); + certPathBuilder.build(params); + result = true; + } + } + } + catch (Exception e) + { + System.out.println(e.getMessage()); + e.printStackTrace(); + result = false; + } + + return result; + } + + private static X509Certificate getX509Certificate(X509CertificateHolder certificateHolder) + throws CertificateException + { + return new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME) + .getCertificate(certificateHolder); + } +} diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/InputStreamWithMACTest.java b/pkix/src/test/java/org/bouncycastle/cms/test/InputStreamWithMACTest.java new file mode 100644 index 0000000000..c23491943d --- /dev/null +++ b/pkix/src/test/java/org/bouncycastle/cms/test/InputStreamWithMACTest.java @@ -0,0 +1,61 @@ +package org.bouncycastle.cms.test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.bouncycastle.cms.InputStreamWithMAC; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; + +public class InputStreamWithMACTest + extends TestCase +{ + public static void main(String[] args) + throws IOException + { + InputStreamWithMACTest test = new InputStreamWithMACTest(); + + test.testReadBlock(); + } + + public static Test suite() + throws Exception + { + return new CMSTestSetup(new TestSuite(InputStreamWithMACTest.class)); + } + + public void testReadBlock() + throws IOException + { + byte[] array = new byte[32]; + byte[] mac = Hex.decode("0102030405060708090a0b0c0d0e0f10"); + InputStreamWithMAC inputStream = new InputStreamWithMAC(new ByteArrayInputStream(array), mac); + try + { + inputStream.getMAC(); + } + catch (IllegalStateException e) + { + assertEquals("input stream not fully processed", e.getMessage()); + } + assertEquals(32, inputStream.read(new byte[46], 0, 46)); + byte[] tailBytes = new byte[19]; + assertEquals(1, inputStream.read(tailBytes, 0, 1)); + assertEquals(1, inputStream.read(tailBytes, 1, 1)); + assertEquals(14, inputStream.read(tailBytes, 2, 17)); + assertEquals(-1, inputStream.read()); + assertTrue(Arrays.areEqual(inputStream.getMAC(), mac)); + assertTrue(Arrays.areEqual(inputStream.getMAC(), Arrays.copyOfRange(tailBytes, 0, 16))); + + inputStream = new InputStreamWithMAC(new ByteArrayInputStream(array), mac); + assertEquals(32, inputStream.read(new byte[46], 0, 46)); + tailBytes = new byte[17]; + assertEquals(16, inputStream.read(tailBytes, 0, 17)); + assertTrue(Arrays.areEqual(inputStream.getMAC(), Arrays.copyOfRange(tailBytes, 0, 16))); + assertEquals(-1, inputStream.read(new byte[17], 0, 17)); + assertEquals(-1, inputStream.read()); + } +} diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/NewEnvelopedDataStreamTest.java b/pkix/src/test/java/org/bouncycastle/cms/test/NewEnvelopedDataStreamTest.java index 8649b0286c..535bbcc556 100644 --- a/pkix/src/test/java/org/bouncycastle/cms/test/NewEnvelopedDataStreamTest.java +++ b/pkix/src/test/java/org/bouncycastle/cms/test/NewEnvelopedDataStreamTest.java @@ -30,6 +30,7 @@ import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSAlgorithm; +import org.bouncycastle.cms.CMSAuthEnvelopedDataStreamGenerator; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSEnvelopedDataParser; import org.bouncycastle.cms.CMSEnvelopedDataStreamGenerator; @@ -50,33 +51,35 @@ import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.OutputAEADEncryptor; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; public class NewEnvelopedDataStreamTest extends TestCase { + private static final String BC = BouncyCastleProvider.PROVIDER_NAME; private static final int BUFFER_SIZE = 4000; - private static String _signDN; - private static KeyPair _signKP; + private static String _signDN; + private static KeyPair _signKP; private static X509Certificate _signCert; - private static String _origDN; - private static KeyPair _origKP; + private static String _origDN; + private static KeyPair _origKP; private static X509Certificate _origCert; - private static String _reciDN; - private static KeyPair _reciKP; + private static String _reciDN; + private static KeyPair _reciKP; private static X509Certificate _reciCert; - private static KeyPair _origEcKP; - private static KeyPair _reciEcKP; + private static KeyPair _origEcKP; + private static KeyPair _reciEcKP; private static X509Certificate _reciEcCert; - private static boolean _initialised = false; - + private static boolean _initialised = false; + public NewEnvelopedDataStreamTest() { } @@ -88,16 +91,16 @@ private static void init() { _initialised = true; - _signDN = "O=Bouncy Castle, C=AU"; - _signKP = CMSTestUtil.makeKeyPair(); + _signDN = "O=Bouncy Castle, C=AU"; + _signKP = CMSTestUtil.makeKeyPair(); _signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN); - _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; - _origKP = CMSTestUtil.makeKeyPair(); + _origDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU"; + _origKP = CMSTestUtil.makeKeyPair(); _origCert = CMSTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN); - _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; - _reciKP = CMSTestUtil.makeKeyPair(); + _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU"; + _reciKP = CMSTestUtil.makeKeyPair(); _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN); _origEcKP = CMSTestUtil.makeEcDsaKeyPair(); @@ -115,50 +118,50 @@ public void setUp() public void testWorkingData() throws Exception { - byte[] keyData = Base64.decode( - "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKrAz/SQKrcQ" + - "nj9IxHIfKDbuXsMqUpI06s2gps6fp7RDNvtUDDMOciWGFhD45YSy8GO0mPx3" + - "Nkc7vKBqX4TLcqLUz7kXGOHGOwiPZoNF+9jBMPNROe/B0My0PkWg9tuq+nxN" + - "64oD47+JvDwrpNOS5wsYavXeAW8Anv9ZzHLU7KwZAgMBAAECgYA/fqdVt+5K" + - "WKGfwr1Z+oAHvSf7xtchiw/tGtosZ24DOCNP3fcTXUHQ9kVqVkNyzt9ZFCT3" + - "bJUAdBQ2SpfuV4DusVeQZVzcROKeA09nPkxBpTefWbSDQGhb+eZq9L8JDRSW" + - "HyYqs+MBoUpLw7GKtZiJkZyY6CsYkAnQ+uYVWq/TIQJBAP5zafO4HUV/w4KD" + - "VJi+ua+GYF1Sg1t/dYL1kXO9GP1p75YAmtm6LdnOCas7wj70/G1YlPGkOP0V" + - "GFzeG5KAmAUCQQCryvKU9nwWA+kypcQT9Yr1P4vGS0APYoBThnZq7jEPc5Cm" + - "ZI82yseSxSeea0+8KQbZ5mvh1p3qImDLEH/iNSQFAkAghS+tboKPN10NeSt+" + - "uiGRRWNbiggv0YJ7Uldcq3ZeLQPp7/naiekCRUsHD4Qr97OrZf7jQ1HlRqTu" + - "eZScjMLhAkBNUMZCQnhwFAyEzdPkQ7LpU1MdyEopYmRssuxijZao5JLqQAGw" + - "YCzXokGFa7hz72b09F4DQurJL/WuDlvvu4jdAkEAxwT9lylvfSfEQw4/qQgZ" + - "MFB26gqB6Gqs1pHIZCzdliKx5BO3VDeUGfXMI8yOkbXoWbYx5xPid/+N8R//" + - "+sxLBw=="); + byte[] keyData = Base64.decode( + "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKrAz/SQKrcQ" + + "nj9IxHIfKDbuXsMqUpI06s2gps6fp7RDNvtUDDMOciWGFhD45YSy8GO0mPx3" + + "Nkc7vKBqX4TLcqLUz7kXGOHGOwiPZoNF+9jBMPNROe/B0My0PkWg9tuq+nxN" + + "64oD47+JvDwrpNOS5wsYavXeAW8Anv9ZzHLU7KwZAgMBAAECgYA/fqdVt+5K" + + "WKGfwr1Z+oAHvSf7xtchiw/tGtosZ24DOCNP3fcTXUHQ9kVqVkNyzt9ZFCT3" + + "bJUAdBQ2SpfuV4DusVeQZVzcROKeA09nPkxBpTefWbSDQGhb+eZq9L8JDRSW" + + "HyYqs+MBoUpLw7GKtZiJkZyY6CsYkAnQ+uYVWq/TIQJBAP5zafO4HUV/w4KD" + + "VJi+ua+GYF1Sg1t/dYL1kXO9GP1p75YAmtm6LdnOCas7wj70/G1YlPGkOP0V" + + "GFzeG5KAmAUCQQCryvKU9nwWA+kypcQT9Yr1P4vGS0APYoBThnZq7jEPc5Cm" + + "ZI82yseSxSeea0+8KQbZ5mvh1p3qImDLEH/iNSQFAkAghS+tboKPN10NeSt+" + + "uiGRRWNbiggv0YJ7Uldcq3ZeLQPp7/naiekCRUsHD4Qr97OrZf7jQ1HlRqTu" + + "eZScjMLhAkBNUMZCQnhwFAyEzdPkQ7LpU1MdyEopYmRssuxijZao5JLqQAGw" + + "YCzXokGFa7hz72b09F4DQurJL/WuDlvvu4jdAkEAxwT9lylvfSfEQw4/qQgZ" + + "MFB26gqB6Gqs1pHIZCzdliKx5BO3VDeUGfXMI8yOkbXoWbYx5xPid/+N8R//" + + "+sxLBw=="); byte[] envData = Base64.decode( - "MIAGCSqGSIb3DQEHA6CAMIACAQAxgcQwgcECAQAwKjAlMRYwFAYDVQQKEw1C" + - "b3VuY3kgQ2FzdGxlMQswCQYDVQQGEwJBVQIBHjANBgkqhkiG9w0BAQEFAASB" + - "gDmnaDZ0vDJNlaUSYyEXsgbaUH+itNTjCOgv77QTX2ImXj+kTctM19PQF2I1" + - "0/NL0fjakvCgBTHKmk13a7jqB6cX3bysenHNrglHsgNGgeXQ7ggAq5fV/JQQ" + - "T7rSxEtuwpbuHQnoVUZahOHVKy/a0uLr9iIh1A3y+yZTZaG505ZJMIAGCSqG" + - "SIb3DQEHATAdBglghkgBZQMEAQIEENmkYNbDXiZxJWtq82qIRZKggAQgkOGr" + - "1JcTsADStez1eY4+rO4DtyBIyUYQ3pilnbirfPkAAAAAAAAAAAAA"); + "MIAGCSqGSIb3DQEHA6CAMIACAQAxgcQwgcECAQAwKjAlMRYwFAYDVQQKEw1C" + + "b3VuY3kgQ2FzdGxlMQswCQYDVQQGEwJBVQIBHjANBgkqhkiG9w0BAQEFAASB" + + "gDmnaDZ0vDJNlaUSYyEXsgbaUH+itNTjCOgv77QTX2ImXj+kTctM19PQF2I1" + + "0/NL0fjakvCgBTHKmk13a7jqB6cX3bysenHNrglHsgNGgeXQ7ggAq5fV/JQQ" + + "T7rSxEtuwpbuHQnoVUZahOHVKy/a0uLr9iIh1A3y+yZTZaG505ZJMIAGCSqG" + + "SIb3DQEHATAdBglghkgBZQMEAQIEENmkYNbDXiZxJWtq82qIRZKggAQgkOGr" + + "1JcTsADStez1eY4+rO4DtyBIyUYQ3pilnbirfPkAAAAAAAAAAAAA"); - CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(envData); + CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(envData); - RecipientInformationStore recipients = ep.getRecipientInfos(); + RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); - Collection c = recipients.getRecipients(); - Iterator it = c.iterator(); + Collection c = recipients.getRecipients(); + Iterator it = c.iterator(); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyData); - KeyFactory keyFact = KeyFactory.getInstance("RSA", BC); - PrivateKey priKey = keyFact.generatePrivate(keySpec); - byte[] data = Hex.decode("57616c6c6157616c6c6157617368696e67746f6e"); + KeyFactory keyFact = KeyFactory.getInstance("RSA", BC); + PrivateKey priKey = keyFact.generatePrivate(keySpec); + byte[] data = Hex.decode("57616c6c6157616c6c6157617368696e67746f6e"); while (it.hasNext()) { - RecipientInformation recipient = (RecipientInformation)it.next(); + RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); @@ -170,21 +173,21 @@ public void testWorkingData() private void verifyData( ByteArrayOutputStream encodedStream, - String expectedOid, - byte[] expectedData) + String expectedOid, + byte[] expectedData) throws Exception { - CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(encodedStream.toByteArray()); - RecipientInformationStore recipients = ep.getRecipientInfos(); + CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(encodedStream.toByteArray()); + RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), expectedOid); - Collection c = recipients.getRecipients(); - Iterator it = c.iterator(); + Collection c = recipients.getRecipients(); + Iterator it = c.iterator(); while (it.hasNext()) { - RecipientInformation recipient = (RecipientInformation)it.next(); + RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); @@ -197,7 +200,7 @@ private void verifyData( public void testUnprotectedAttributes() throws Exception { - byte[] data = "WallaWallaWashington".getBytes(); + byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); @@ -212,10 +215,10 @@ public void testUnprotectedAttributes() edGen.setUnprotectedAttributeGenerator(new SimpleAttributeTableGenerator(attrTable)); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( - bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); + bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); out.write(data); @@ -223,17 +226,17 @@ public void testUnprotectedAttributes() CMSEnvelopedDataParser ed = new CMSEnvelopedDataParser(bOut.toByteArray()); - RecipientInformationStore recipients = ed.getRecipientInfos(); + RecipientInformationStore recipients = ed.getRecipientInfos(); - Collection c = recipients.getRecipients(); + Collection c = recipients.getRecipients(); assertEquals(1, c.size()); - Iterator it = c.iterator(); + Iterator it = c.iterator(); while (it.hasNext()) { - RecipientInformation recipient = (RecipientInformation)it.next(); + RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); @@ -325,10 +328,10 @@ public void testKeyTransAES128BufferedStream() edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( - bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); + bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); for (int i = 0; i != 2000; i++) { @@ -383,10 +386,10 @@ public void testKeyTransAES128Buffered() edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( - bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); + bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); for (int i = 0; i != 2000; i++) { @@ -438,10 +441,10 @@ public void testKeyTransAES128Der() edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( - bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); + bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); for (int i = 0; i != 2000; i++) { @@ -490,24 +493,24 @@ public void testKeyTransAES128Throughput() out.close(); - CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); - RecipientInformationStore recipients = ep.getRecipientInfos(); - Collection c = recipients.getRecipients(); - Iterator it = c.iterator(); + CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); + RecipientInformationStore recipients = ep.getRecipientInfos(); + Collection c = recipients.getRecipients(); + Iterator it = c.iterator(); if (it.hasNext()) { - RecipientInformation recipient = (RecipientInformation)it.next(); + RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); - InputStream dataStream = recData.getContentStream(); + InputStream dataStream = recData.getContentStream(); ByteArrayOutputStream dataOut = new ByteArrayOutputStream(); - int len; - byte[] buf = new byte[BUFFER_SIZE]; - int count = 0; + int len; + byte[] buf = new byte[BUFFER_SIZE]; + int count = 0; while (count != 10 && (len = dataStream.read(buf)) > 0) { @@ -531,7 +534,7 @@ public void testKeyTransAES128Throughput() public void testKeyTransAES128AndOriginatorInfo() throws Exception { - byte[] data = "WallaWallaWashington".getBytes(); + byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); @@ -541,29 +544,29 @@ public void testKeyTransAES128AndOriginatorInfo() edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( - bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); + bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); out.write(data); out.close(); - CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); + CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); assertTrue(ep.getOriginatorInfo().getCertificates().getMatches(null).contains(origCert)); - RecipientInformationStore recipients = ep.getRecipientInfos(); + RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); - Collection c = recipients.getRecipients(); - Iterator it = c.iterator(); + Collection c = recipients.getRecipients(); + Iterator it = c.iterator(); while (it.hasNext()) { - RecipientInformation recipient = (RecipientInformation)it.next(); + RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); @@ -578,33 +581,33 @@ public void testKeyTransAES128AndOriginatorInfo() public void testKeyTransAES128() throws Exception { - byte[] data = "WallaWallaWashington".getBytes(); + byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( - bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); + bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); out.write(data); out.close(); - CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); + CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); - RecipientInformationStore recipients = ep.getRecipientInfos(); + RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); - Collection c = recipients.getRecipients(); - Iterator it = c.iterator(); + Collection c = recipients.getRecipients(); + Iterator it = c.iterator(); while (it.hasNext()) { - RecipientInformation recipient = (RecipientInformation)it.next(); + RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); @@ -630,33 +633,33 @@ public void testKeyTransCAST5SunJCE() return; } - byte[] data = "WallaWallaWashington".getBytes(); + byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider("SunJCE")); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( - bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.CAST5_CBC).setProvider(BC).build()); + bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.CAST5_CBC).setProvider(BC).build()); out.write(data); out.close(); - CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); + CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); - RecipientInformationStore recipients = ep.getRecipientInfos(); + RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.CAST5_CBC); - Collection c = recipients.getRecipients(); - Iterator it = c.iterator(); + Collection c = recipients.getRecipients(); + Iterator it = c.iterator(); while (it.hasNext()) { - RecipientInformation recipient = (RecipientInformation)it.next(); + RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); @@ -671,36 +674,36 @@ public void testKeyTransCAST5SunJCE() public void testAESKEK() throws Exception { - byte[] data = "WallaWallaWashington".getBytes(); - SecretKey kek = CMSTestUtil.makeAES192Key(); + byte[] data = "WallaWallaWashington".getBytes(); + SecretKey kek = CMSTestUtil.makeAES192Key(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); - byte[] kekId = new byte[] { 1, 2, 3, 4, 5 }; + byte[] kekId = new byte[]{1, 2, 3, 4, 5}; edGen.addRecipientInfoGenerator(new JceKEKRecipientInfoGenerator(kekId, kek).setProvider(BC)); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( - bOut, - new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); + bOut, + new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); out.write(data); out.close(); - CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); + CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); - RecipientInformationStore recipients = ep.getRecipientInfos(); + RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); - Collection c = recipients.getRecipients(); - Iterator it = c.iterator(); + Collection c = recipients.getRecipients(); + Iterator it = c.iterator(); while (it.hasNext()) { - RecipientInformation recipient = (RecipientInformation)it.next(); + RecipientInformation recipient = (RecipientInformation)it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), "2.16.840.1.101.3.4.1.25"); @@ -715,36 +718,36 @@ public void testAESKEK() public void testTwoAESKEK() throws Exception { - byte[] data = "WallaWallaWashington".getBytes(); - SecretKey kek1 = CMSTestUtil.makeAES192Key(); - SecretKey kek2 = CMSTestUtil.makeAES192Key(); + byte[] data = "WallaWallaWashington".getBytes(); + SecretKey kek1 = CMSTestUtil.makeAES192Key(); + SecretKey kek2 = CMSTestUtil.makeAES192Key(); CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator(); - byte[] kekId1 = new byte[] { 1, 2, 3, 4, 5 }; - byte[] kekId2 = new byte[] { 5, 4, 3, 2, 1 }; + byte[] kekId1 = new byte[]{1, 2, 3, 4, 5}; + byte[] kekId2 = new byte[]{5, 4, 3, 2, 1}; edGen.addRecipientInfoGenerator(new JceKEKRecipientInfoGenerator(kekId1, kek1).setProvider(BC)); edGen.addRecipientInfoGenerator(new JceKEKRecipientInfoGenerator(kekId2, kek2).setProvider(BC)); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( - bOut, - new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); + bOut, + new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); out.write(data); out.close(); - CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); + CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); - RecipientInformationStore recipients = ep.getRecipientInfos(); + RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); - RecipientId recSel = new KEKRecipientId(kekId2); + RecipientId recSel = new KEKRecipientId(kekId2); - RecipientInformation recipient = recipients.get(recSel); + RecipientInformation recipient = recipients.get(recSel); assertEquals(recipient.getKeyEncryptionAlgOID(), "2.16.840.1.101.3.4.1.25"); @@ -767,25 +770,25 @@ public void testECKeyAgree() recipientGenerator.addRecipient(_reciEcCert); edGen.addRecipientInfoGenerator(recipientGenerator); - - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = edGen.open( - bOut, - new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); + bOut, + new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build()); out.write(data); out.close(); - CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); + CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray()); - RecipientInformationStore recipients = ep.getRecipientInfos(); + RecipientInformationStore recipients = ep.getRecipientInfos(); assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC); - RecipientId recSel = new JceKeyAgreeRecipientId(_reciEcCert); + RecipientId recSel = new JceKeyAgreeRecipientId(_reciEcCert); - RecipientInformation recipient = recipients.get(recSel); + RecipientInformation recipient = recipients.get(recSel); CMSTypedStream recData = recipient.getContentStream(new JceKeyAgreeEnvelopedRecipient(_reciEcKP.getPrivate()).setProvider(BC)); @@ -801,7 +804,7 @@ public void testOriginatorInfo() OriginatorInformation origInfo = env.getOriginatorInfo(); - RecipientInformationStore recipients = env.getRecipientInfos(); + RecipientInformationStore recipients = env.getRecipientInfos(); assertEquals(new X500Name("C=US,O=U.S. Government,OU=HSPD12Lab,OU=Agents,CN=user1"), ((X509CertificateHolder)origInfo.getCertificates().getMatches(null).iterator().next()).getSubject()); assertEquals(CMSEnvelopedDataGenerator.DES_EDE3_CBC, env.getEncryptionAlgOID()); diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/NewEnvelopedDataTest.java b/pkix/src/test/java/org/bouncycastle/cms/test/NewEnvelopedDataTest.java index 89af11290d..180056efb4 100644 --- a/pkix/src/test/java/org/bouncycastle/cms/test/NewEnvelopedDataTest.java +++ b/pkix/src/test/java/org/bouncycastle/cms/test/NewEnvelopedDataTest.java @@ -45,6 +45,7 @@ import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CCMParameters; +import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; import org.bouncycastle.asn1.cms.EnvelopedData; @@ -791,6 +792,57 @@ public void testKeyTrans() assertTrue(collection.iterator().next() instanceof RecipientInformation); } + public void testKeyTransWithHKDF() + throws Exception + { + byte[] data = "WallaWallaWashington".getBytes(); + + CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); + + edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); + edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(ASN1OctetString.getInstance(ASN1OctetString.getInstance(_reciCert.getExtensionValue(Extension.subjectKeyIdentifier.getId())).getOctets()).getOctets(), _reciCert.getPublicKey()).setProvider(BC)); + + CMSEnvelopedData ed = edGen.generate( + new CMSProcessableByteArray(data), + new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC) + .setEnableSha256HKdf(true) + .setProvider(BC).build()); + + RecipientInformationStore recipients = ed.getRecipientInfos(); + + assertEquals(ed.getEncryptionAlgOID(), CMSObjectIdentifiers.id_alg_cek_hkdf_sha256.getId()); + + AlgorithmIdentifier encAlgId = AlgorithmIdentifier.getInstance(ed.getContentEncryptionAlgorithm().getParameters()); + + assertEquals(encAlgId.getAlgorithm(), CMSAlgorithm.DES_EDE3_CBC); + + Collection c = recipients.getRecipients(); + + assertEquals(2, c.size()); + + Iterator it = c.iterator(); + + while (it.hasNext()) + { + RecipientInformation recipient = (RecipientInformation)it.next(); + + assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); + + byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)); + + assertEquals(true, Arrays.equals(data, recData)); + } + + RecipientId id = new JceKeyTransRecipientId(_reciCert); + + Collection collection = recipients.getRecipients(id); + if (collection.size() != 2) + { + fail("recipients not matched using general recipient ID."); + } + assertTrue(collection.iterator().next() instanceof RecipientInformation); + } + public void testKeyTransOAEPDefault() throws Exception { @@ -1532,6 +1584,7 @@ public void testAES192KEK() throws Exception { tryKekAlgorithm(CMSTestUtil.makeAESKey(192), NISTObjectIdentifiers.id_aes192_wrap); + tryKekAlgorithmWithHKdf(CMSTestUtil.makeAESKey(192), NISTObjectIdentifiers.id_aes192_wrap); } public void testAES256KEK() @@ -1566,6 +1619,18 @@ public void testCamellia256KEK() private void tryKekAlgorithm(SecretKey kek, ASN1ObjectIdentifier algOid) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException + { + doTryKekAlgorithm(kek, algOid, false); + } + + private void tryKekAlgorithmWithHKdf(SecretKey kek, ASN1ObjectIdentifier algOid) + throws NoSuchAlgorithmException, NoSuchProviderException, CMSException + { + doTryKekAlgorithm(kek, algOid, true); + } + + private void doTryKekAlgorithm(SecretKey kek, ASN1ObjectIdentifier algOid, boolean withKdf) + throws NoSuchAlgorithmException, NoSuchProviderException, CMSException { byte[] data = "WallaWallaWashington".getBytes(); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); @@ -1576,14 +1641,23 @@ private void tryKekAlgorithm(SecretKey kek, ASN1ObjectIdentifier algOid) CMSEnvelopedData ed = edGen.generate( new CMSProcessableByteArray(data), - new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()); + new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC) + .setEnableSha256HKdf(withKdf) + .setProvider(BC).build()); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); - assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); + if (withKdf) + { + assertEquals(ed.getEncryptionAlgOID(), CMSObjectIdentifiers.id_alg_cek_hkdf_sha256.getId()); + } + else + { + assertEquals(ed.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.DES_EDE3_CBC); + } if (it.hasNext()) { diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/NewSignedDataTest.java b/pkix/src/test/java/org/bouncycastle/cms/test/NewSignedDataTest.java index 009e0618ea..fa668e9321 100644 --- a/pkix/src/test/java/org/bouncycastle/cms/test/NewSignedDataTest.java +++ b/pkix/src/test/java/org/bouncycastle/cms/test/NewSignedDataTest.java @@ -584,6 +584,97 @@ public class NewSignedDataTest List crlList = new ArrayList(); private static final Set noParams = new HashSet(); + private static byte[] ecPublicKeyExample = Base64.decode( + "MIIEdwYJKoZIhvcNAQcCoIIEaDCCBGQCAQExDzANBglghkgBZQMEAgEFADAUBgkqhki" + + "G9w0BBwGgBwQFAQIDBAWgggMPMIIDCzCCAm6gAwIBAgIJALt88oa4pHaNMAkGByqGSM" + + "49BAEwYzELMAkGA1UEBhMCR0ExCzAJBgNVBAgTAkFXMRAwDgYDVQQHEwdBdGxhbnRhM" + + "QwwCgYDVQQKEwNWTVcxDzANBgNVBAsTBkFXIEVNTTEWMBQGA1UEAxMNd3d3LmF3bWRt" + + "LmNvbTAeFw0xNjA2MDgxNjQ2MTdaFw0xNjA3MDgxNjQ2MTdaMGMxCzAJBgNVBAYTAkd" + + "BMQswCQYDVQQIEwJBVzEQMA4GA1UEBxMHQXRsYW50YTEMMAoGA1UEChMDVk1XMQ8wDQ" + + "YDVQQLEwZBVyBFTU0xFjAUBgNVBAMTDXd3dy5hd21kbS5jb20wgZswEAYHKoZIzj0CA" + + "QYFK4EEACMDgYYABAAAlWsasReERY0vzpm6WvDuznypGIyXfaf8Q/sieuHOdUxhzcMS" + + "8Gg4qxry9voSKozDn3vI1sFQ3ZPxDgIouHSKZAA8G4aP72k/gQ7G8wnHx2DF+UgchfI" + + "L0GypTZqmjo0c7jb8ZDgklfGr+arFeL8gIVH+EqmUdJoYzBW0FX9RZmerjKOByDCBxT" + + "AdBgNVHQ4EFgQUHkakN+xGDRr7GCER2OSy0FvvN7QwgZUGA1UdIwSBjTCBioAUHkakN" + + "+xGDRr7GCER2OSy0FvvN7ShZ6RlMGMxCzAJBgNVBAYTAkdBMQswCQYDVQQIEwJBVzEQ" + + "MA4GA1UEBxMHQXRsYW50YTEMMAoGA1UEChMDVk1XMQ8wDQYDVQQLEwZBVyBFTU0xFjA" + + "UBgNVBAMTDXd3dy5hd21kbS5jb22CCQC7fPKGuKR2jTAMBgNVHRMEBTADAQH/MAkGBy" + + "qGSM49BAEDgYsAMIGHAkIByvkebPlDlHVbZT+G+beFDwBzuSbTLp5cae0R+qUxbd24s" + + "XD5wozRiMs3GVRGd7L0sDeHbq8iJrLrKv7UJuh7HqECQVJVwthEuknri/pIajiuolJo" + + "dLgVnaTqcCaOshuMejK1qT38yCqX/G5W/STw6iBv1/Dg6pwaIsmtrTn3NMDZkH+1MYI" + + "BIzCCAR8CAQEwcDBjMQswCQYDVQQGEwJHQTELMAkGA1UECBMCQVcxEDAOBgNVBAcTB0" + + "F0bGFudGExDDAKBgNVBAoTA1ZNVzEPMA0GA1UECxMGQVcgRU1NMRYwFAYDVQQDEw13d" + + "3cuYXdtZG0uY29tAgkAu3zyhrikdo0wDQYJYIZIAWUDBAIBBQAwCwYHKoZIzj0CAQUA" + + "BIGLMIGIAkIAth4AncbHuAVpUqiie/nY3E/2jarczGI4HfMHci4a+yLbsMaAfU6baty" + + "0Ei6VUCWX7je5dmV/wb1gcU0RogDu9AwCQgFuI0qfrnXiC8Rfir7PpYl66P6eD7bGT3" + + "XK+2UlfIO0N05yYZAaHu7jCIdHIhi1wwtq9dsHwpcEJhLlJ8LyifAxDw=="); + + // old-school PKCS#7 message but with SHA1withRSA in the hash oid + private static byte[] wrongRSASHA1Message = Base64.decode( + "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCHQUAMIAGCSqGSIb3DQEHAaCAJIAEDEhlbGxvIHdvcmxkIQ" + + "AAAAAAAKCAMIICDTCCAXagAwIBAgIBATANBgkqhkiG9w0BAQUFADAlMRYwFAYDVQQKDA1Cb3VuY3kgQ2FzdGx" + + "lMQswCQYDVQQGEwJBVTAeFw0yMzEwMjMwNDI1NDZaFw0yNDAxMzEwNDI1NDZaMCUxFjAUBgNVBAoMDUJvdW5j" + + "eSBDYXN0bGUxCzAJBgNVBAYTAkFVMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCPeTZYUeho8Keog+YJO" + + "dJWYOZbZCT/VWMjofN1hTvTauOeXVjDVB5D4rtdXE21hDdJTzWeO4axJxVfDsJ107Ejs6yF4WwJCNz8BDPZpt" + + "ga8Kl4ioGmpU5TTIPgqMHHclX/QDvbTRp6MImcKZ2Md5WECbdWYHAtPzo6H1pDWPiehQIDAQABo00wSzAdBgN" + + "VHQ4EFgQUa5xUEZKF6MTpJbRPGiwjkGGtGHEwHwYDVR0jBBgwFoAUa5xUEZKF6MTpJbRPGiwjkGGtGHEwCQYD" + + "VR0TBAIwADANBgkqhkiG9w0BAQUFAAOBgQCDkD5qMw2eim+Xp3U7T2FdJ46iLUjK31wrsEpTMT3RQz/mT5M6D" + + "LNVJQt8aIzyISAjdo5BLEFK7lNMWexEkH3IdQ+9uYT7adB9LWs6gtUMv+H6BE9G0/DAvM3K+fxUM4LTVY2EdZ" + + "jIWOTyMBYtmjp63nP9NRDzOK2awhk2kKhdPDCCAiswggGUoAMCAQICAQIwDQYJKoZIhvcNAQEFBQAwJTEWMBQ" + + "GA1UECgwNQm91bmN5IENhc3RsZTELMAkGA1UEBhMCQVUwHhcNMjMxMDIzMDQyNTQ2WhcNMjQwMTMxMDQyNTQ2" + + "WjBDMQwwCgYDVQQDDANCb2IxDjAMBgNVBAsMBVNhbGVzMRYwFAYDVQQKDA1Cb3VuY3kgQ2FzdGxlMQswCQYDV" + + "QQGEwJBVTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArIVf3YhZQHM6CBiussIy1NBE7uuRhdIszxdQX4" + + "cj4QavDj3F1lzGiIZNrCjGUcXQG3oItl96XvqY4VLmWw0LRkMvKf6wD+pr3jdNqUACcPE5B3I40OQRAq52KYp" + + "n10pg36C9XOKg8UbPKbLCueM8MdOina+0YL2UkI64Uw8s9MECAwEAAaNNMEswHQYDVR0OBBYEFJRiFuPZf1w4" + + "go0ONwDnVf3sswpfMB8GA1UdIwQYMBaAFGucVBGShejE6SW0TxosI5BhrRhxMAkGA1UdEwQCMAAwDQYJKoZIh" + + "vcNAQEFBQADgYEAXzYymmGBbv5MnxQdQ202koelj8GEx/VhGuYHnGFcAbxyCizobo8IE6RJUO3NLfnKiP1EK1" + + "aFNhqw+LU3pk84IS0wmXFXakmx1EuTG7JtRBQPrwBfbEDKDKT2vBOrq9gSRIFohrBZ9WNpJaBfgGdAkMogj8D" + + "j98PuH3QzAsnclgoAADGBzzCBzAIBATAqMCUxFjAUBgNVBAoMDUJvdW5jeSBDYXN0bGUxCzAJBgNVBAYTAkFV" + + "AgEBMAkGBSsOAwIdBQAwDQYJKoZIhvcNAQEBBQAEgYBrEz/W4bk+JCLcMulXBgghSo9DeDufRZl6p0rGjxMEk" + + "/AmWQac/K+Y6eAl4MNoVLdHzVvDlkUSMb4bz25fBys+B7A2Wn2gWyssRT5PfcxK91o24JPwnFypwLNqEgFrkC" + + "8c690ABj1OCEVTbAKOgI9ID7kXMJc+WZpQD2JLCGUG0AAAAAAAAA=="); + + // new-school PKCS#7 message but with SHA1withRSA in the hash oid should be rejected + private static byte[] wrongRSASHA1MessageWithAttributes = Base64.decode( + "MIAGCSqGSIb3DQEHAqCAMIACAQExCTAHBgUrDgMCHTCABgkqhkiG9w0BBwGggCSA\n" + + "BBNNeSBzcGVjaWFsIG1lc3NhZ2UyAAAAAAAAoIAwggSZMIIDTaADAgECAhQAoX1E\n" + + "JJLxftRRUu06RXzDwMewAzBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUA\n" + + "oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASAwSDELMAkGA1UEBhMC\n" + + "VVMxEzARBgNVBAoTCkdvb2dsZSBMTEMxJDAiBgNVBAMTG0dFTS1XaW5kb3dzLXVz\n" + + "LXdlc3QxLUdZSm8yNTAeFw0yMzEwMTcyMTU2MjlaFw0yNDAxMjUyMTU2MjhaMBQx\n" + + "EjAQBgNVBAMMCWRldmljZV9pZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n" + + "ggEBALGMmPlHHlrXysf43O6cKbDta0zmo5bWwCzir78rkfyUsSdBDC+GLRhq2bxr\n" + + "AW8nYn6wDy0a2r2QMoj9SS4my38o2Urtu+XtsQHu0NG+hKxm7KLSRncpvqcfFc6A\n" + + "FQ8eYbbkYRVRJm5r7jsYWE9IB7Kv46rUWofieuYHdDyPvKU3unmxlegKFDWcFVmo\n" + + "cx4BiMGZ5zv+BtLfHxCRTf5k9r1y13gmTnwZzI+iwc9ZixTHJD6OejvvEcbjqPUm\n" + + "q9OhBrx/eUZqDCjHoBcjtYuj24RAhZu55/GP0xQedvZfasEA70XLD5wkF1oM/vQl\n" + + "Cu9STP0en4y75YMefDjRmygpVdcCAwEAAaOCAUUwggFBMA4GA1UdDwEB/wQEAwID\n" + + "uDATBgNVHSUEDDAKBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQ7\n" + + "eoXi4IwFUvD++kLjKcWIbZM+tDAfBgNVHSMEGDAWgBTs9EezkU1W31lKwtOxtGEI\n" + + "RaJSuTCBjQYIKwYBBQUHAQEEgYAwfjB8BggrBgEFBQcwAoZwaHR0cDovL3ByaXZh\n" + + "dGVjYS1jb250ZW50LTY1MGE2MmE2LTAwMDAtMmU3Mi1hZGY1LWQ0ZjU0N2ZhY2Fh\n" + + "MC5zdG9yYWdlLmdvb2dsZWFwaXMuY29tLzZiYjBlZmIwZjk5MmZmNmZkYTFkL2Nh\n" + + "LmNydDA8BgNVHREENTAzhjFkYXRhOkNnbGtaWFpwWTJWZmFXUWdxK09QeVBvU09n\n" + + "WUlnT0xKckFaQWdhK05BZz09MEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAIB\n" + + "BQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiAwIBIAOCAQEAroRz0SiP\n" + + "2IMkwcZ0ffz/d4Z9RE9x7lDve2hsmwKqYnKzYmiueVognNGfI3zp613+NJN73Au4\n" + + "qeCHUMmq+rik2m2qMy/1PqzUHthqpGONXfckw18+XpTqmSsBm+wGBvfjFAFi1e/Q\n" + + "x64ABjLyGfws9/fiZgOkCc/ewDo+BI2S8vaYMRTVhKtfLZQODXTLQlalFX2JM0B6\n" + + "KYOfOmfmNM/W0FQLOetbprSqCsA2Di2e3/obnh0N+ft2q3Ayvh9dEPNOnp0W1hAD\n" + + "VAHhoq4HQKCsaJuc93pjIDgoFnFg5jBeKq2ZUDJc32N21iEPK2ylrUVnUVZx87wK\n" + + "laDjdqbmrN0R2gAAMYICDjCCAgoCAQEwYDBIMQswCQYDVQQGEwJVUzETMBEGA1UE\n" + + "ChMKR29vZ2xlIExMQzEkMCIGA1UEAxMbR0VNLVdpbmRvd3MtdXMtd2VzdDEtR1lK\n" + + "bzI1AhQAoX1EJJLxftRRUu06RXzDwMewAzAHBgUrDgMCHaCBhjAYBgkqhkiG9w0B\n" + + "CQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMzEwMjMwMzE0NDRaMCMG\n" + + "CSqGSIb3DQEJBDEWBBQ6a3vz6YBI8hq0TwAbAhqRH2Ry0TAnBgkqhkiG9w0BCTQx\n" + + "GjAYMAcGBSsOAwIdoQ0GCSqGSIb3DQEBAQUAMA0GCSqGSIb3DQEBAQUABIIBAJc+\n" + + "27Uik2JfE5xloR5Ry2FZsslXRrrO7PdhlXvwgPpgicma3AYvD9os7fk6nTieEaVB\n" + + "fWkesz7fFOthP/UG5KvpsyE1hmXMqUpCPQfFE1XfzaSgBeMTRWtPqzagVojJw+3i\n" + + "LrCy0Kgw+wKBwmyVkd0zHLQEF5aUA+ovCTNGje11qNpdCwUKfal7uz8TD4V0hWwJ\n" + + "zAYME3itle90ztUh3NcEYQxJOQNZRGhkTMsXHKNPDCGS+erpU8BERkU+FOCH9+wS\n" + + "CiwhMCLDeeEBOdxWZHVbIiFnnRTQqyIDGAOSSIUmjE/pMPKpPvumkCGq2r9GxPV9\n" + + "YlpnThaYbDCnWg8tbWYAAAAAAAA="); + static { noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); @@ -960,6 +1051,30 @@ public void testWithDefiniteLength() verifySignatures(s, md.digest("Hello world!".getBytes())); } + public void testSHA1WithRSAWrongDigestOID() + throws Exception + { + CMSSignedData s = new CMSSignedData(wrongRSASHA1Message); + + verifySignatures(s); + } + + public void testAttributesSHA1WithRSAWrongDigestOIDRejected() + throws Exception + { + CMSSignedData s = new CMSSignedData(wrongRSASHA1MessageWithAttributes); + + try + { + verifySignatures(s); + fail("no exception"); + } + catch (CMSException e) + { + assertTrue(e.getMessage().indexOf("can't create digest calculator") == 0); + } + } + public void testSHA1WithRSANoAttributes() throws Exception { @@ -1434,6 +1549,14 @@ public void testRawSHA256MissingNull() } } + public void testEcPublicKeyAlgorithm() + throws Exception + { + CMSSignedData cms = new CMSSignedData(ecPublicKeyExample); + + verifySignatures(cms, null); + } + public void testLwSHA1WithRSAAndAttributeTable() throws Exception { diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/NullProviderTest.java b/pkix/src/test/java/org/bouncycastle/cms/test/NullProviderTest.java index a97b21c630..2219f08906 100644 --- a/pkix/src/test/java/org/bouncycastle/cms/test/NullProviderTest.java +++ b/pkix/src/test/java/org/bouncycastle/cms/test/NullProviderTest.java @@ -2,10 +2,8 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; -import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; @@ -29,8 +27,11 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x509.X509Name; +import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSProcessableByteArray; @@ -55,7 +56,6 @@ import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; -import org.bouncycastle.x509.X509V3CertificateGenerator; public class NullProviderTest extends TestCase @@ -63,11 +63,13 @@ public class NullProviderTest static KeyPair keyPair; static X509Certificate keyCert; private static final String TEST_MESSAGE = "Hello World!"; - + private static BigInteger serialNumber; private JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); static { + serialNumber = BigInteger.valueOf(System.currentTimeMillis()); + try { keyPair = generateKeyPair(); @@ -245,32 +247,32 @@ private static KeyPair generateKeyPair() return kpg.generateKeyPair(); } - private static X509Certificate makeCertificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN) - throws GeneralSecurityException, IOException + public static X509Certificate makeCertificate(KeyPair _subKP, + String _subDN, KeyPair _issKP, String _issDN) + throws Exception { + PublicKey _subPub = _subKP.getPublic(); + PrivateKey _issPriv = _issKP.getPrivate(); + PublicKey _issPub = _issKP.getPublic(); - PublicKey subPub = subKP.getPublic(); - PrivateKey issPriv = issKP.getPrivate(); - PublicKey issPub = issKP.getPublic(); - - X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator(); + X509v3CertificateBuilder _v3CertGen = new JcaX509v3CertificateBuilder( + new X500Name(_issDN), + allocateSerialNumber(), + new Date(System.currentTimeMillis()), + new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), + new X500Name(_subDN), + _subPub); - v3CertGen.reset(); - v3CertGen.setSerialNumber(BigInteger.valueOf(1)); - v3CertGen.setIssuerDN(new X509Name(_issDN)); - v3CertGen.setNotBefore(new Date(System.currentTimeMillis())); - v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100))); - v3CertGen.setSubjectDN(new X509Name(_subDN)); - v3CertGen.setPublicKey(subPub); + X509CertificateHolder _cert = _v3CertGen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(_issPriv)); - v3CertGen.setSignatureAlgorithm("SHA1WithRSA"); - - X509Certificate _cert = v3CertGen.generate(issPriv, "SunRsaSign"); - - _cert.checkValidity(new Date()); - _cert.verify(issPub); + return new JcaX509CertificateConverter().setProvider("BC").getCertificate(_cert); + } - return _cert; + private static BigInteger allocateSerialNumber() + { + BigInteger _tmp = serialNumber; + serialNumber = serialNumber.add(BigInteger.valueOf(1)); + return _tmp; } public static Test suite() diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/PQCSignedDataTest.java b/pkix/src/test/java/org/bouncycastle/cms/test/PQCSignedDataTest.java index af620646d4..772d75cda0 100644 --- a/pkix/src/test/java/org/bouncycastle/cms/test/PQCSignedDataTest.java +++ b/pkix/src/test/java/org/bouncycastle/cms/test/PQCSignedDataTest.java @@ -1,9 +1,11 @@ package org.bouncycastle.cms.test; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.security.KeyPair; import java.security.MessageDigest; import java.security.Security; +import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; @@ -24,6 +26,7 @@ import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaCertStore; +import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedDataGenerator; @@ -35,6 +38,7 @@ import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.DigestCalculatorProvider; +import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; @@ -55,9 +59,11 @@ public class PQCSignedDataTest private static X509Certificate _origFalconCert; private static KeyPair _origPicnicKP; private static X509Certificate _origPicnicCert; - private static KeyPair _origDilithiumKP; - private static X509Certificate _origDilithiumCert; - + private static KeyPair _origMlDsaKP; + private static X509Certificate _origMlDsaCert; + private static KeyPair _origSlhDsaKP; + private static X509Certificate _origSlhDsaCert; + private static String _signDN; private static KeyPair _signKP; private static X509Certificate _signCert; @@ -65,9 +71,11 @@ public class PQCSignedDataTest private static X509Certificate _signFalconCert; private static KeyPair _signPicnicKP; private static X509Certificate _signPicnicCert; - private static KeyPair _signDilithiumKP; - private static X509Certificate _signDilithiumCert; - + private static KeyPair _signMlDsaKP; + private static X509Certificate _signMlDsaCert; + private static KeyPair _signSlhDsaKP; + private static X509Certificate _signSlhDsaCert; + private static boolean _initialised = false; private static final Set noParams = new HashSet(); @@ -140,12 +148,18 @@ private static void init() _signPicnicKP = PQCTestUtil.makePicnicKeyPair(); _signPicnicCert = PQCTestUtil.makeCertificate(_signPicnicKP, _signDN, _origPicnicKP, _origDN); - - _origDilithiumKP = PQCTestUtil.makeDilithiumKeyPair(); - _origDilithiumCert = PQCTestUtil.makeCertificate(_origDilithiumKP, _origDN, _origDilithiumKP, _origDN); - - _signDilithiumKP = PQCTestUtil.makeDilithiumKeyPair(); - _signDilithiumCert = PQCTestUtil.makeCertificate(_signDilithiumKP, _signDN, _origDilithiumKP, _origDN); + + _origMlDsaKP = PQCTestUtil.makeMlDsaKeyPair(); + _origMlDsaCert = PQCTestUtil.makeCertificate(_origMlDsaKP, _origDN, _origMlDsaKP, _origDN); + + _signMlDsaKP = PQCTestUtil.makeMlDsaKeyPair(); + _signMlDsaCert = PQCTestUtil.makeCertificate(_signMlDsaKP, _signDN, _origMlDsaKP, _origDN); + + _origSlhDsaKP = PQCTestUtil.makeSlhDsaKeyPair(); + _origSlhDsaCert = PQCTestUtil.makeCertificate(_origSlhDsaKP, _origDN, _origSlhDsaKP, _origDN); + + _signSlhDsaKP = PQCTestUtil.makeSlhDsaKeyPair(); + _signSlhDsaCert = PQCTestUtil.makeCertificate(_signSlhDsaKP, _signDN, _origSlhDsaKP, _origDN); } } @@ -263,7 +277,7 @@ public void testFalconEncapsulated() } public void testPicnicEncapsulated() - throws Exception + throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); @@ -283,52 +297,65 @@ public void testPicnicEncapsulated() CMSSignedData s = gen.generate(msg, true); - ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); - ASN1InputStream aIn = new ASN1InputStream(bIn); + checkSignature(s, gen); + } - s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); + public void testMLDSAEncapsulated() + throws Exception + { + List certList = new ArrayList(); + CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); - certs = s.getCertificates(); + certList.add(_origMlDsaCert); + certList.add(_signMlDsaCert); - SignerInformationStore signers = s.getSignerInfos(); + Store certs = new JcaCertStore(certList); - Collection c = signers.getSigners(); - Iterator it = c.iterator(); + CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); + DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); - while (it.hasNext()) - { - SignerInformation signer = (SignerInformation)it.next(); - Collection certCollection = certs.getMatches(signer.getSID()); + gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(digCalcProv).build(new JcaContentSignerBuilder("ML-DSA").setProvider(BC).build(_origMlDsaKP.getPrivate()), _origMlDsaCert)); - Iterator certIt = certCollection.iterator(); - X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); + gen.addCertificates(certs); - cert.getSubjectPublicKeyInfo(); + CMSSignedData s = gen.generate(msg, true); - assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(cert))); + checkSignature(s, gen); + } - // - // check content digest - // + public void testHashMLDSAEncapsulated() + throws Exception + { + List certList = new ArrayList(); + CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); - byte[] contentDigest = (byte[])gen.getGeneratedDigests().get(signer.getDigestAlgOID()); + certList.add(_origMlDsaCert); + certList.add(_signMlDsaCert); - AttributeTable table = signer.getSignedAttributes(); - Attribute hash = table.get(CMSAttributes.messageDigest); + Store certs = new JcaCertStore(certList); - assertTrue(MessageDigest.isEqual(contentDigest, ((ASN1OctetString)hash.getAttrValues().getObjectAt(0)).getOctets())); - } + CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); + + DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); + + gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(digCalcProv).build(new JcaContentSignerBuilder("HASH-ML-DSA").setProvider(BC).build(_origMlDsaKP.getPrivate()), _origMlDsaCert)); + + gen.addCertificates(certs); + + CMSSignedData s = gen.generate(msg, true); + + checkSignature(s, gen); } - - public void testDilithiumEncapsulated() - throws Exception + + public void testSLHDSAEncapsulated() + throws Exception { List certList = new ArrayList(); CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); - certList.add(_origDilithiumCert); - certList.add(_signDilithiumCert); + certList.add(_origSlhDsaCert); + certList.add(_signSlhDsaCert); Store certs = new JcaCertStore(certList); @@ -336,12 +363,43 @@ public void testDilithiumEncapsulated() DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); - gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(digCalcProv).build(new JcaContentSignerBuilder("Dilithium").setProvider(BCPQC).build(_origDilithiumKP.getPrivate()), _origDilithiumCert)); + gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(digCalcProv).build(new JcaContentSignerBuilder("SLH-DSA").setProvider(BC).build(_origSlhDsaKP.getPrivate()), _origSlhDsaCert)); gen.addCertificates(certs); CMSSignedData s = gen.generate(msg, true); + checkSignature(s, gen); + } + + public void testHashSLHDSAEncapsulated() + throws Exception + { + List certList = new ArrayList(); + CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes()); + + certList.add(_origSlhDsaCert); + certList.add(_signSlhDsaCert); + + Store certs = new JcaCertStore(certList); + + CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); + + DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); + + gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(digCalcProv).build(new JcaContentSignerBuilder("HASH-SLH-DSA").setProvider(BC).build(_origSlhDsaKP.getPrivate()), _origSlhDsaCert)); + + gen.addCertificates(certs); + + CMSSignedData s = gen.generate(msg, true); + + checkSignature(s, gen); + } + + private void checkSignature(CMSSignedData s, CMSSignedDataGenerator gen) + throws IOException, CMSException, OperatorCreationException, CertificateException + { + Store certs; ByteArrayInputStream bIn = new ByteArrayInputStream(s.getEncoded()); ASN1InputStream aIn = new ASN1InputStream(bIn); diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/PQCTestUtil.java b/pkix/src/test/java/org/bouncycastle/cms/test/PQCTestUtil.java index 6ff0f0aabc..30547c4b04 100644 --- a/pkix/src/test/java/org/bouncycastle/cms/test/PQCTestUtil.java +++ b/pkix/src/test/java/org/bouncycastle/cms/test/PQCTestUtil.java @@ -15,13 +15,15 @@ import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.jcajce.interfaces.MLDSAKey; +import org.bouncycastle.jcajce.interfaces.SLHDSAKey; +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; +import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec; import org.bouncycastle.jce.X509KeyUsage; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.pqc.jcajce.interfaces.DilithiumKey; import org.bouncycastle.pqc.jcajce.interfaces.FalconKey; import org.bouncycastle.pqc.jcajce.interfaces.PicnicKey; -import org.bouncycastle.pqc.jcajce.spec.DilithiumParameterSpec; import org.bouncycastle.pqc.jcajce.spec.FalconParameterSpec; import org.bouncycastle.pqc.jcajce.spec.PicnicParameterSpec; import org.bouncycastle.pqc.jcajce.spec.SPHINCS256KeyGenParameterSpec; @@ -44,7 +46,7 @@ public static KeyPair makeSphincsPlusKeyPair() { KeyPairGenerator kpGen = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC"); - kpGen.initialize(SPHINCSPlusParameterSpec.sha2_128f, new SecureRandom()); + kpGen.initialize(SPHINCSPlusParameterSpec.sha2_128f_robust, new SecureRandom()); return kpGen.generateKeyPair(); } @@ -69,12 +71,22 @@ public static KeyPair makePicnicKeyPair() return kpGen.generateKeyPair(); } - public static KeyPair makeDilithiumKeyPair() + public static KeyPair makeMlDsaKeyPair() throws Exception { - KeyPairGenerator kpGen = KeyPairGenerator.getInstance("Dilithium", "BCPQC"); + KeyPairGenerator kpGen = KeyPairGenerator.getInstance("ML-DSA", "BC"); //TODO: divide into two with cases with digest and with parametersets - kpGen.initialize(DilithiumParameterSpec.dilithium2, new SecureRandom()); + kpGen.initialize(MLDSAParameterSpec.ml_dsa_65, new SecureRandom()); + + return kpGen.generateKeyPair(); + } + + public static KeyPair makeSlhDsaKeyPair() + throws Exception + { + KeyPairGenerator kpGen = KeyPairGenerator.getInstance("SLH-DSA", "BC"); + //TODO: divide into two with cases with digest and with parametersets + kpGen.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, new SecureRandom()); return kpGen.generateKeyPair(); } @@ -96,10 +108,13 @@ else if (issPriv instanceof PicnicKey) // sigGen = new JcaContentSignerBuilder(((PicnicKey)issPriv).getParameterSpec().getName()).setProvider("BCPQC").build(issPriv); sigGen = new JcaContentSignerBuilder("PICNIC").setProvider("BCPQC").build(issPriv); } - else if (issPriv instanceof DilithiumKey) + else if (issPriv instanceof MLDSAKey) { -// sigGen = new JcaContentSignerBuilder(((PicnicKey)issPriv).getParameterSpec().getName()).setProvider("BCPQC").build(issPriv); - sigGen = new JcaContentSignerBuilder("Dilithium").setProvider("BCPQC").build(issPriv); + sigGen = new JcaContentSignerBuilder("ML-DSA").setProvider("BC").build(issPriv); + } + else if (issPriv instanceof SLHDSAKey) + { + sigGen = new JcaContentSignerBuilder("SLH-DSA").setProvider("BC").build(issPriv); } else { diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/SunProviderTest.java b/pkix/src/test/java/org/bouncycastle/cms/test/SunProviderTest.java index 3ec8c5ae49..40299cd26b 100644 --- a/pkix/src/test/java/org/bouncycastle/cms/test/SunProviderTest.java +++ b/pkix/src/test/java/org/bouncycastle/cms/test/SunProviderTest.java @@ -2,10 +2,8 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; -import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; @@ -29,9 +27,11 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x509.X509Name; +import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; import org.bouncycastle.cms.CMSProcessableByteArray; @@ -57,7 +57,6 @@ import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Store; -import org.bouncycastle.x509.X509V3CertificateGenerator; public class SunProviderTest extends TestCase @@ -66,9 +65,12 @@ public class SunProviderTest static X509Certificate keyCert; private static final String TEST_MESSAGE = "Hello World!"; private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); + private static BigInteger serialNumber; static { + serialNumber = BigInteger.valueOf(System.currentTimeMillis()); + try { keyPair = generateKeyPair(); @@ -248,32 +250,32 @@ private static KeyPair generateKeyPair() return kpg.generateKeyPair(); } - private static X509Certificate makeCertificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN) - throws GeneralSecurityException, IOException + public static X509Certificate makeCertificate(KeyPair _subKP, + String _subDN, KeyPair _issKP, String _issDN) + throws Exception { + PublicKey _subPub = _subKP.getPublic(); + PrivateKey _issPriv = _issKP.getPrivate(); + PublicKey _issPub = _issKP.getPublic(); - PublicKey subPub = subKP.getPublic(); - PrivateKey issPriv = issKP.getPrivate(); - PublicKey issPub = issKP.getPublic(); - - X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator(); - - v3CertGen.reset(); - v3CertGen.setSerialNumber(BigInteger.valueOf(1)); - v3CertGen.setIssuerDN(new X509Name(_issDN)); - v3CertGen.setNotBefore(new Date(System.currentTimeMillis())); - v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100))); - v3CertGen.setSubjectDN(new X509Name(_subDN)); - v3CertGen.setPublicKey(subPub); + X509v3CertificateBuilder _v3CertGen = new JcaX509v3CertificateBuilder( + new X500Name(_issDN), + allocateSerialNumber(), + new Date(System.currentTimeMillis()), + new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), + new X500Name(_subDN), + _subPub); - v3CertGen.setSignatureAlgorithm("SHA1WithRSA"); + X509CertificateHolder _cert = _v3CertGen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(_issPriv)); - X509Certificate _cert = v3CertGen.generate(issPriv, "SunRsaSign"); - - _cert.checkValidity(new Date()); - _cert.verify(issPub); + return new JcaX509CertificateConverter().setProvider("BC").getCertificate(_cert); + } - return _cert; + private static BigInteger allocateSerialNumber() + { + BigInteger _tmp = serialNumber; + serialNumber = serialNumber.add(BigInteger.valueOf(1)); + return _tmp; } public static Test suite() diff --git a/pkix/src/test/java/org/bouncycastle/est/test/ESTResponseTest.java b/pkix/src/test/java/org/bouncycastle/est/test/ESTResponseTest.java index 1b4f2fceac..0d82350bd6 100644 --- a/pkix/src/test/java/org/bouncycastle/est/test/ESTResponseTest.java +++ b/pkix/src/test/java/org/bouncycastle/est/test/ESTResponseTest.java @@ -6,8 +6,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; -import java.nio.charset.StandardCharsets; -import java.util.Base64; import java.util.HashMap; import java.util.Map; @@ -16,6 +14,8 @@ import junit.framework.TestCase; import org.bouncycastle.est.ESTResponse; import org.bouncycastle.est.Source; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.io.Streams; public class ESTResponseTest @@ -98,7 +98,7 @@ public void assertESTResponseMessageEquals(String expected, ESTResponse response try { byte[] data = Streams.readAll(response.getInputStream()); - String dataString = new String(data, StandardCharsets.UTF_8); + String dataString = Strings.fromUTF8ByteArray(data); assertEquals(expected, dataString); } catch (IOException e) @@ -145,7 +145,7 @@ public void testESTResponseShouldSupportContentTransferEncodingBase64() throws IOException { String data = "Test message body"; - String dataBase64 = Base64.getEncoder().encodeToString(data.getBytes(StandardCharsets.UTF_8)); + String dataBase64 = Base64.toBase64String(Strings.toUTF8ByteArray(data)); Map httpHeader = new HashMap(); httpHeader.put("content-transfer-encoding", "base64"); @@ -207,7 +207,7 @@ public void testESTResponseMustNotThrowOnChunkedTransferEncodingWithContentTrans throws IOException { String data = "Test message body"; - String dataBase64 = Base64.getEncoder().encodeToString(data.getBytes(StandardCharsets.UTF_8)); + String dataBase64 = Base64.toBase64String(Strings.toUTF8ByteArray(data)); Map httpHeader = new HashMap(); httpHeader.put("content-transfer-encoding", "base64"); diff --git a/pkix/src/test/java/org/bouncycastle/its/test/ITSBasicTest.java b/pkix/src/test/java/org/bouncycastle/its/test/ITSBasicTest.java index 95314c9266..7abd9d6b29 100644 --- a/pkix/src/test/java/org/bouncycastle/its/test/ITSBasicTest.java +++ b/pkix/src/test/java/org/bouncycastle/its/test/ITSBasicTest.java @@ -116,7 +116,7 @@ public void testImplicitBuilder() byte[] parentData = caCert.getEncoded(); - Digest digest = new SHA256Digest(); + Digest digest = SHA256Digest.newInstance(); byte[] parentDigest = new byte[digest.getDigestSize()]; digest.update(parentData, 0, parentData.length); diff --git a/pkix/src/test/java/org/bouncycastle/its/test/ITSJcaJceBasicTest.java b/pkix/src/test/java/org/bouncycastle/its/test/ITSJcaJceBasicTest.java index 85c7d88f25..510c835c5e 100644 --- a/pkix/src/test/java/org/bouncycastle/its/test/ITSJcaJceBasicTest.java +++ b/pkix/src/test/java/org/bouncycastle/its/test/ITSJcaJceBasicTest.java @@ -97,7 +97,7 @@ public void testImplicitBuilder() byte[] parentData = caCert.getEncoded(); - Digest digest = new SHA256Digest(); + Digest digest = SHA256Digest.newInstance(); byte[] parentDigest = new byte[digest.getDigestSize()]; digest.update(parentData, 0, parentData.length); diff --git a/pkix/src/test/java/org/bouncycastle/mozilla/test/SPKACTest.java b/pkix/src/test/java/org/bouncycastle/mozilla/test/SPKACTest.java index e08f468b59..8aed92426d 100644 --- a/pkix/src/test/java/org/bouncycastle/mozilla/test/SPKACTest.java +++ b/pkix/src/test/java/org/bouncycastle/mozilla/test/SPKACTest.java @@ -6,11 +6,9 @@ import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1IA5String; import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.mozilla.PublicKeyAndChallenge; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.mozilla.SignedPublicKeyAndChallenge; import org.bouncycastle.mozilla.jcajce.JcaSignedPublicKeyAndChallenge; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.util.encoders.Base64; @@ -37,19 +35,17 @@ public String getName() public void spkacTest(String testName, byte[] req) throws Exception { - SignedPublicKeyAndChallenge spkac; - - spkac = new SignedPublicKeyAndChallenge(req); + JcaSignedPublicKeyAndChallenge spkac = new JcaSignedPublicKeyAndChallenge(req).setProvider("BC"); PublicKeyAndChallenge pkac = spkac.getPublicKeyAndChallenge(); - PublicKey pubKey = spkac.getPublicKey("BC"); + PublicKey pubKey = spkac.getPublicKey(); ASN1Primitive obj = pkac.toASN1Primitive(); if (obj == null) { fail("Error - " + testName + " PKAC ASN1Primitive was null."); } - obj = spkac.toASN1Primitive(); + obj = spkac.toASN1Structure().toASN1Primitive(); if (obj == null) { fail("Error - " + testName + " SPKAC ASN1Primitive was null."); @@ -68,7 +64,7 @@ public void spkacTest(String testName, byte[] req) fail("Error - " + testName + " challenge was null."); } - byte[] bytes = spkac.toASN1Primitive().getEncoded(ASN1Encoding.DER); + byte[] bytes = spkac.toASN1Structure().getEncoded(ASN1Encoding.DER); if (bytes.length != req.length) { @@ -83,7 +79,7 @@ public void spkacTest(String testName, byte[] req) } } - if (!spkac.verify("BC")) + if (!spkac.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(pubKey))) { fail(testName + " verification failed"); } @@ -92,12 +88,12 @@ public void spkacTest(String testName, byte[] req) public void spkacNewTest(String testName, byte[] req) throws Exception { - SignedPublicKeyAndChallenge spkac; + JcaSignedPublicKeyAndChallenge spkac; - spkac = new SignedPublicKeyAndChallenge(req); + spkac = new JcaSignedPublicKeyAndChallenge(req); PublicKeyAndChallenge pkac = spkac.getPublicKeyAndChallenge(); - PublicKey pubKey = spkac.getPublicKey("BC"); + PublicKey pubKey = spkac.getPublicKey(); ASN1Primitive obj = pkac.toASN1Primitive(); if (obj == null) { diff --git a/pkix/src/test/java/org/bouncycastle/openssl/test/ParserTest.java b/pkix/src/test/java/org/bouncycastle/openssl/test/ParserTest.java index f9d82f7eb9..8756bf5c47 100644 --- a/pkix/src/test/java/org/bouncycastle/openssl/test/ParserTest.java +++ b/pkix/src/test/java/org/bouncycastle/openssl/test/ParserTest.java @@ -301,7 +301,7 @@ public void performTest() { if (privInfo instanceof PrivateKeyInfo) { - privKey = (RSAPrivateCrtKey)converter.getPrivateKey(PrivateKeyInfo.getInstance(privInfo)); + privKey = (RSAPrivateCrtKey)converter.getPrivateKey((PrivateKeyInfo)privInfo); } else { @@ -361,6 +361,7 @@ public void performTest() isTrue(edSig.verify(s)); doOpenSslGost2012Test(); + doParseAttrECKeyTest(); } private void checkTrustedCert(X509TrustedCertificateBlock trusted) @@ -618,6 +619,17 @@ private void doNoECPublicKeyTest() isTrue(kp.getPublicKeyInfo() == null); } + private void doParseAttrECKeyTest() + throws Exception + { + // EC private key extremely dodgy attributes. + PEMParser pemRd = openPEMResource("ec_attr_key.pem"); + + PEMKeyPair kp = (PEMKeyPair)pemRd.readObject(); + + isTrue(kp.getPublicKeyInfo() == null); + } + public static void main( String[] args) { diff --git a/pkix/src/test/java/org/bouncycastle/operator/test/AllTests.java b/pkix/src/test/java/org/bouncycastle/operator/test/AllTests.java index 55ef9c842d..7879503521 100644 --- a/pkix/src/test/java/org/bouncycastle/operator/test/AllTests.java +++ b/pkix/src/test/java/org/bouncycastle/operator/test/AllTests.java @@ -138,6 +138,18 @@ public void testAgainstKnownList() new Object[]{NISTObjectIdentifiers.id_dsa_with_sha3_512, "SHA3-512WITHDSA"}, new Object[]{BCObjectIdentifiers.falcon_512, "FALCON"}, new Object[]{BCObjectIdentifiers.falcon_1024, "FALCON"}, + new Object[]{NISTObjectIdentifiers.id_slh_dsa_sha2_128s, "SPHINCS+"}, + new Object[]{NISTObjectIdentifiers.id_slh_dsa_sha2_128f, "SPHINCS+"}, + new Object[]{NISTObjectIdentifiers.id_slh_dsa_sha2_192s, "SPHINCS+"}, + new Object[]{NISTObjectIdentifiers.id_slh_dsa_sha2_192f, "SPHINCS+"}, + new Object[]{NISTObjectIdentifiers.id_slh_dsa_sha2_256s, "SPHINCS+"}, + new Object[]{NISTObjectIdentifiers.id_slh_dsa_sha2_256f, "SPHINCS+"}, + new Object[]{NISTObjectIdentifiers.id_slh_dsa_shake_128s, "SPHINCS+"}, + new Object[]{NISTObjectIdentifiers.id_slh_dsa_shake_128f, "SPHINCS+"}, + new Object[]{NISTObjectIdentifiers.id_slh_dsa_shake_192s, "SPHINCS+"}, + new Object[]{NISTObjectIdentifiers.id_slh_dsa_shake_192f, "SPHINCS+"}, + new Object[]{NISTObjectIdentifiers.id_slh_dsa_shake_256s, "SPHINCS+"}, + new Object[]{NISTObjectIdentifiers.id_slh_dsa_shake_256f, "SPHINCS+"}, new Object[]{BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, "SPHINCS+"}, new Object[]{BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, "SPHINCS+"}, new Object[]{BCObjectIdentifiers.sphincsPlus_shake_128s_r3, "SPHINCS+"}, @@ -156,6 +168,24 @@ public void testAgainstKnownList() new Object[]{BCObjectIdentifiers.sphincsPlus_shake_256f_r3, "SPHINCS+"}, new Object[]{BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, "SPHINCS+"}, new Object[]{BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple, "SPHINCS+"}, + new Object[]{BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple, "SPHINCS+"}, new Object[]{GNUObjectIdentifiers.Tiger_192, "Tiger"}, new Object[]{PKCSObjectIdentifiers.RC2_CBC, "RC2/CBC"}, diff --git a/pkix/src/test/java/org/bouncycastle/pkcs/test/PKCS10Test.java b/pkix/src/test/java/org/bouncycastle/pkcs/test/PKCS10Test.java index acadb232a8..8a18411856 100644 --- a/pkix/src/test/java/org/bouncycastle/pkcs/test/PKCS10Test.java +++ b/pkix/src/test/java/org/bouncycastle/pkcs/test/PKCS10Test.java @@ -2,6 +2,8 @@ import java.math.BigInteger; import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; @@ -11,14 +13,24 @@ import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; +import org.bouncycastle.pkcs.DeltaCertAttributeUtils; +import org.bouncycastle.pkcs.DeltaCertificateRequestAttributeValue; +import org.bouncycastle.pkcs.DeltaCertificateRequestAttributeValueBuilder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; @@ -175,7 +187,68 @@ public void testBrokenRequestWithDuplicateExtension() fail("expected name 2"); } } - + + public void testAltRequestAttributes() + throws Exception + { + KeyPairGenerator p256Kpg = KeyPairGenerator.getInstance("EC", "BC"); + p256Kpg.initialize(new ECNamedCurveGenParameterSpec("P-256")); + KeyPair p256Kp = p256Kpg.generateKeyPair(); + + KeyPairGenerator dilKpg = KeyPairGenerator.getInstance("ML-DSA", "BC"); + dilKpg.initialize(MLDSAParameterSpec.ml_dsa_44); + KeyPair dilKp = dilKpg.generateKeyPair(); + + JcaPKCS10CertificationRequestBuilder jcaPkcs10Builder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=Test"), p256Kp.getPublic()); + + ContentSigner altSigner = new JcaContentSignerBuilder("ML-DSA-44").setProvider("BC").build(dilKp.getPrivate()); + + PKCS10CertificationRequest request = jcaPkcs10Builder.build(new JcaContentSignerBuilder("SHA256withECDSA").setProvider("BC").build(p256Kp.getPrivate()), dilKp.getPublic(), altSigner); + + assertTrue(request.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(p256Kp.getPublic()))); + + assertTrue(request.hasAltPublicKey()); + + assertTrue(request.isAltSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(dilKp.getPublic()))); + } + + public void testDeltaRequestAttribute() + throws Exception + { + KeyPairGenerator p256Kpg = KeyPairGenerator.getInstance("EC", "BC"); + p256Kpg.initialize(new ECNamedCurveGenParameterSpec("P-256")); + KeyPair p256Kp = p256Kpg.generateKeyPair(); + + KeyPairGenerator dilKpg = KeyPairGenerator.getInstance("ML-DSA", "BC"); + dilKpg.initialize(MLDSAParameterSpec.ml_dsa_44); + KeyPair dilKp = dilKpg.generateKeyPair(); + + PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=Test"), p256Kp.getPublic()); + + ContentSigner deltaSigner = new JcaContentSignerBuilder("ML-DSA-44").setProvider("BC").build(dilKp.getPrivate()); + + DeltaCertificateRequestAttributeValueBuilder deltaAttrBldr = new DeltaCertificateRequestAttributeValueBuilder( + SubjectPublicKeyInfo.getInstance(dilKp.getPublic().getEncoded())); + + deltaAttrBldr.setSignatureAlgorithm(deltaSigner.getAlgorithmIdentifier()); + deltaAttrBldr.setSubject(new X500Name("CN=Dil2 Cert Req Test")); + + DeltaCertificateRequestAttributeValue deltaAttr = deltaAttrBldr.build(); + + pkcs10Builder.addAttribute(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.2"), deltaAttr); + + PKCS10CertificationRequest deltaReq = pkcs10Builder.build(deltaSigner); + + pkcs10Builder.addAttribute(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.3"), new DERBitString(deltaReq.getSignature())); + + PKCS10CertificationRequest request = pkcs10Builder.build(new JcaContentSignerBuilder("SHA256withECDSA").setProvider("BC").build(p256Kp.getPrivate())); + + assertTrue(DeltaCertAttributeUtils.isDeltaRequestSignatureValid(request, new JcaContentVerifierProviderBuilder().setProvider("BC").build(dilKp.getPublic()))); + + assertTrue(request.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(p256Kp.getPublic()))); + } + + public static void main(String args[]) { PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); diff --git a/pkix/src/test/java/org/bouncycastle/pkix/test/AllTests.java b/pkix/src/test/java/org/bouncycastle/pkix/test/AllTests.java index d72390b78c..4955ee577e 100644 --- a/pkix/src/test/java/org/bouncycastle/pkix/test/AllTests.java +++ b/pkix/src/test/java/org/bouncycastle/pkix/test/AllTests.java @@ -22,6 +22,7 @@ public static Test suite() suite.addTestSuite(CheckerTest.class); suite.addTestSuite(RevocationTest.class); + suite.addTestSuite(CheckNameConstraintsTest.class); return new BCTestSetup(suite); } diff --git a/pkix/src/test/java/org/bouncycastle/pkix/test/CheckNameConstraintsTest.java b/pkix/src/test/java/org/bouncycastle/pkix/test/CheckNameConstraintsTest.java new file mode 100644 index 0000000000..f3055dbdad --- /dev/null +++ b/pkix/src/test/java/org/bouncycastle/pkix/test/CheckNameConstraintsTest.java @@ -0,0 +1,122 @@ +package org.bouncycastle.pkix.test; + +import java.security.Security; +import java.security.cert.CertPath; +import java.security.cert.CertPathBuilder; +import java.security.cert.CertPathValidator; +import java.security.cert.CertStore; +import java.security.cert.CertificateFactory; +import java.security.cert.CollectionCertStoreParameters; +import java.security.cert.PKIXBuilderParameters; +import java.security.cert.PKIXCertPathBuilderResult; +import java.security.cert.PKIXParameters; +import java.security.cert.TrustAnchor; +import java.security.cert.X509CertSelector; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import junit.framework.TestCase; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.pkix.jcajce.PKIXCertPathReviewer; +import org.bouncycastle.test.TestResourceFinder; + +public class CheckNameConstraintsTest + extends TestCase +{ + public void testPKIXCertPathReviewer() + throws Exception + { + Security.addProvider(new BouncyCastleProvider()); + + CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); + + X509Certificate root = (X509Certificate) cf.generateCertificate(TestResourceFinder.findTestResource("pkix", "mal-root.crt")); + X509Certificate ca1 = (X509Certificate) cf.generateCertificate(TestResourceFinder.findTestResource("pkix", "mal-ca1.crt")); + X509Certificate ca2 = (X509Certificate) cf.generateCertificate(TestResourceFinder.findTestResource("pkix", "mal-ca2.crt")); + X509Certificate leaf = (X509Certificate) cf.generateCertificate(TestResourceFinder.findTestResource("pkix", "mal-leaf.crt")); + + List certchain = new ArrayList(); + certchain.add(root); + certchain.add(ca1); + certchain.add(ca2); + certchain.add(leaf); + + CertPath cp = cf.generateCertPath(certchain); + + Set trust = new HashSet(); + trust.add(new TrustAnchor(root, null)); + PKIXParameters param = new PKIXParameters(trust); + + PKIXCertPathReviewer certPathReviewer = new PKIXCertPathReviewer(); + certPathReviewer.init(cp, param); + + assertFalse(certPathReviewer.isValidCertPath()); // hit + } + + public void testPKIXCertPathBuilder() + throws Exception + { + Security.addProvider(new BouncyCastleProvider()); + + CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); + X509Certificate rootCert = (X509Certificate) cf.generateCertificate(TestResourceFinder.findTestResource("pkix", "mal-root.crt")); + X509Certificate endCert = (X509Certificate) cf.generateCertificate(TestResourceFinder.findTestResource("pkix", "mal-ca1.crt")); + + // create CertStore to support path building + List list = new ArrayList(); + list.add(endCert); + + CollectionCertStoreParameters params = new CollectionCertStoreParameters(list); + CertStore store = CertStore.getInstance("Collection", params, "BC"); + + // build the path + CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC"); + X509CertSelector pathConstraints = new X509CertSelector(); + + pathConstraints.setCertificate(endCert); + + PKIXBuilderParameters buildParams = new PKIXBuilderParameters(Collections.singleton(new TrustAnchor(rootCert, null)), pathConstraints); + + buildParams.addCertStore(store); + buildParams.setDate(new Date()); + buildParams.setRevocationEnabled(false); + + PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult)builder.build(buildParams); + CertPath path = result.getCertPath(); + + if (path.getCertificates().size() != 1) + { + fail("wrong number of certs in testPKIXCertPathBuilder path"); + } + } + + public void testPKIXCertPathValidator() + throws Exception + { + Security.addProvider(new BouncyCastleProvider()); + + CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); + + X509Certificate rootCert = (X509Certificate) cf.generateCertificate(TestResourceFinder.findTestResource("pkix", "mal-root.crt")); + X509Certificate endCert = (X509Certificate) cf.generateCertificate(TestResourceFinder.findTestResource("pkix", "mal-ca1.crt")); + + List list = new ArrayList(); + list.add(endCert); + + CertPath certPath = cf.generateCertPath(list); + + Set trust = new HashSet(); + trust.add(new TrustAnchor(rootCert, null)); + + CertPathValidator cpv = CertPathValidator.getInstance("PKIX", "BC"); + PKIXParameters param = new PKIXParameters(trust); + param.setRevocationEnabled(false); + + cpv.validate(certPath, param); + } +} diff --git a/pkix/src/test/java/org/bouncycastle/tsp/test/ERSTestdatenTest.java b/pkix/src/test/java/org/bouncycastle/tsp/test/ERSTestdatenTest.java index 342032ecc6..a8d90ca7b6 100644 --- a/pkix/src/test/java/org/bouncycastle/tsp/test/ERSTestdatenTest.java +++ b/pkix/src/test/java/org/bouncycastle/tsp/test/ERSTestdatenTest.java @@ -1,11 +1,13 @@ package org.bouncycastle.tsp.test; +import java.io.FileNotFoundException; import java.io.InputStream; import java.util.Date; import junit.framework.TestCase; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; +import org.bouncycastle.test.TestResourceFinder; import org.bouncycastle.tsp.ers.ERSEvidenceRecord; import org.bouncycastle.tsp.ers.ERSInputStreamData; import org.bouncycastle.util.io.Streams; @@ -16,23 +18,23 @@ public class ERSTestdatenTest public void testChain1ATS() throws Exception { - ERSEvidenceRecord ers = new ERSEvidenceRecord(Streams.readAll(getTestData("Testdaten_ERS-Testool/rfc4998/1Chain1ATS/BIN_ER.ers")), new JcaDigestCalculatorProviderBuilder().build()); + ERSEvidenceRecord ers = new ERSEvidenceRecord(Streams.readAll(getTestData("Testdaten_ERS-Testool/rfc4998/1Chain1ATS", "BIN_ER.ers")), new JcaDigestCalculatorProviderBuilder().build()); ers.validate(new JcaSimpleSignerInfoVerifierBuilder().build(ers.getSigningCertificate())); - ers.validatePresent(new ERSInputStreamData(getTestData("Testdaten_ERS-Testool/rfc4998/1Chain1ATS/BIN.bin")), new Date()); + ers.validatePresent(new ERSInputStreamData(getTestData("Testdaten_ERS-Testool/rfc4998/1Chain1ATS", "BIN.bin")), new Date()); } public void testChain2ATS() throws Exception { - ERSEvidenceRecord ers = new ERSEvidenceRecord(Streams.readAll(getTestData("Testdaten_ERS-Testool/rfc4998/1Chain2ATS/BIN_ER.ers")), new JcaDigestCalculatorProviderBuilder().build()); + ERSEvidenceRecord ers = new ERSEvidenceRecord(Streams.readAll(getTestData("Testdaten_ERS-Testool/rfc4998/1Chain2ATS", "BIN_ER.ers")), new JcaDigestCalculatorProviderBuilder().build()); ers.validate(new JcaSimpleSignerInfoVerifierBuilder().build(ers.getSigningCertificate())); - ers.validatePresent(new ERSInputStreamData(getTestData("Testdaten_ERS-Testool/rfc4998/1Chain2ATS/BIN.bin")), new Date()); + ers.validatePresent(new ERSInputStreamData(getTestData("Testdaten_ERS-Testool/rfc4998/1Chain2ATS", "BIN.bin")), new Date()); - ers = new ERSEvidenceRecord(Streams.readAll(getTestData("Testdaten_ERS-Testool/rfc4998/1Chain2ATS/testRenewal.ers")), new JcaDigestCalculatorProviderBuilder().build()); + ers = new ERSEvidenceRecord(Streams.readAll(getTestData("Testdaten_ERS-Testool/rfc4998/1Chain2ATS", "testRenewal.ers")), new JcaDigestCalculatorProviderBuilder().build()); ers.validate(new JcaSimpleSignerInfoVerifierBuilder().build(ers.getSigningCertificate())); } @@ -40,15 +42,16 @@ public void testChain2ATS() public void test2Chains3ATS() throws Exception { - ERSEvidenceRecord ers = new ERSEvidenceRecord(Streams.readAll(getTestData("Testdaten_ERS-Testool/rfc4998/2Chains3ATS/BIN_ER.ers")), new JcaDigestCalculatorProviderBuilder().build()); + ERSEvidenceRecord ers = new ERSEvidenceRecord(Streams.readAll(getTestData("Testdaten_ERS-Testool/rfc4998/2Chains3ATS", "BIN_ER.ers")), new JcaDigestCalculatorProviderBuilder().build()); ers.validate(new JcaSimpleSignerInfoVerifierBuilder().build(ers.getSigningCertificate())); - ers.validatePresent(new ERSInputStreamData(getTestData("Testdaten_ERS-Testool/rfc4998/2Chains3ATS/BIN.bin")), new Date()); + ers.validatePresent(new ERSInputStreamData(getTestData("Testdaten_ERS-Testool/rfc4998/2Chains3ATS", "BIN.bin")), new Date()); } - private static InputStream getTestData(String resource) + private static InputStream getTestData(String homeDir, String file) + throws FileNotFoundException { - return ERSTestdatenTest.class.getResourceAsStream("20170316_Testdaten/" + resource); + return TestResourceFinder.findTestResource("tsp/20170316_Testdaten/" + homeDir, file); } } diff --git a/pkix/src/test/java/org/bouncycastle/tsp/test/PQCTSPTest.java b/pkix/src/test/java/org/bouncycastle/tsp/test/PQCTSPTest.java index 77064b825f..7b208598b9 100644 --- a/pkix/src/test/java/org/bouncycastle/tsp/test/PQCTSPTest.java +++ b/pkix/src/test/java/org/bouncycastle/tsp/test/PQCTSPTest.java @@ -96,13 +96,13 @@ public void testLMS() TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()) - .setContentDigest(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256)) + .setContentDigest(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_512)) .build(signer, cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2")); // tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); - TimeStampRequest request = reqGen.generate(TSPAlgorithms.SM3, new byte[32], BigInteger.valueOf(100)); + TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA3_512, new byte[64], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); @@ -131,7 +131,7 @@ public void testSPHINCSPlus() try { - KeyPairGenerator g = KeyPairGenerator.getInstance("SPHINCS+", BC); + KeyPairGenerator g = KeyPairGenerator.getInstance("SLH-DSA", BC); KeyPair p = g.generateKeyPair(); @@ -152,7 +152,7 @@ public void testSPHINCSPlus() // create the certificate - version 1 // - ContentSigner sigGen = new JcaContentSignerBuilder("SPHINCS+") + ContentSigner sigGen = new JcaContentSignerBuilder("SLH-DSA-SHA2-128F") .setProvider(BC).build(privKey); JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( new X500Name("CN=Test"), @@ -167,17 +167,17 @@ public void testSPHINCSPlus() X509Certificate cert = new JcaX509CertificateConverter() .setProvider("BC").getCertificate(certGen.build(sigGen)); - ContentSigner signer = new JcaContentSignerBuilder("SPHINCS+").setProvider(BC).build(privKey); + ContentSigner signer = new JcaContentSignerBuilder("SLH-DSA-SHA2-128F").setProvider(BC).build(privKey); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()) - .setContentDigest(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256)) + .setContentDigest(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_256)) .build(signer, cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2")); // tsTokenGen.addCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); - TimeStampRequest request = reqGen.generate(TSPAlgorithms.SM3, new byte[32], BigInteger.valueOf(100)); + TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA3_256, new byte[32], BigInteger.valueOf(100)); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED); diff --git a/pkix/src/test/java/org/bouncycastle/tsp/test/SHA256DigestCalculator.java b/pkix/src/test/java/org/bouncycastle/tsp/test/SHA256DigestCalculator.java index 89b0a1f26b..fd3004d4fe 100644 --- a/pkix/src/test/java/org/bouncycastle/tsp/test/SHA256DigestCalculator.java +++ b/pkix/src/test/java/org/bouncycastle/tsp/test/SHA256DigestCalculator.java @@ -31,7 +31,7 @@ public byte[] getDigest() bOut.reset(); - Digest sha256 = new SHA256Digest(); + Digest sha256 = SHA256Digest.newInstance(); sha256.update(bytes, 0, bytes.length); diff --git a/pkix/src/test/java/org/bouncycastle/tsp/test/TSPTestUtil.java b/pkix/src/test/java/org/bouncycastle/tsp/test/TSPTestUtil.java index 4e7417df29..ad9546a2d7 100644 --- a/pkix/src/test/java/org/bouncycastle/tsp/test/TSPTestUtil.java +++ b/pkix/src/test/java/org/bouncycastle/tsp/test/TSPTestUtil.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.math.BigInteger; -import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; @@ -15,19 +14,24 @@ import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; -import org.bouncycastle.asn1.x509.X509Name; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.util.encoders.Base64; -import org.bouncycastle.x509.X509V3CertificateGenerator; public class TSPTestUtil { + private static final String BC = "BC"; public static SecureRandom rand = new SecureRandom(); @@ -48,7 +52,7 @@ public class TSPTestUtil public static final boolean DEBUG = true; public static ASN1ObjectIdentifier EuroPKI_TSA_Test_Policy = new ASN1ObjectIdentifier( - "1.3.6.1.4.1.5255.5.1"); + "1.3.6.1.4.1.5255.5.1"); public static JcaX509ExtensionUtils extUtils; @@ -140,82 +144,71 @@ public static SecretKey makeRC2128Key() } public static X509Certificate makeCertificate(KeyPair _subKP, - String _subDN, KeyPair _issKP, String _issDN) - throws GeneralSecurityException, IOException + String _subDN, KeyPair _issKP, String _issDN) + throws Exception { - return makeCertificate(_subKP, _subDN, _issKP, _issDN, false); } public static X509Certificate makeCACertificate(KeyPair _subKP, - String _subDN, KeyPair _issKP, String _issDN) - throws GeneralSecurityException, IOException + String _subDN, KeyPair _issKP, String _issDN) + throws Exception { return makeCertificate(_subKP, _subDN, _issKP, _issDN, true); } public static X509Certificate makeCertificate(KeyPair _subKP, - String _subDN, KeyPair _issKP, String _issDN, boolean _ca) - throws GeneralSecurityException, IOException + String _subDN, KeyPair _issKP, String _issDN, boolean _ca) + throws Exception { PublicKey _subPub = _subKP.getPublic(); PrivateKey _issPriv = _issKP.getPrivate(); PublicKey _issPub = _issKP.getPublic(); - X509V3CertificateGenerator _v3CertGen = new X509V3CertificateGenerator(); - - _v3CertGen.reset(); - _v3CertGen.setSerialNumber(allocateSerialNumber()); - _v3CertGen.setIssuerDN(new X509Name(_issDN)); - _v3CertGen.setNotBefore(new Date(System.currentTimeMillis())); - _v3CertGen.setNotAfter(new Date(System.currentTimeMillis() - + (1000L * 60 * 60 * 24 * 100))); - _v3CertGen.setSubjectDN(new X509Name(_subDN)); - _v3CertGen.setPublicKey(_subPub); - _v3CertGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); - - _v3CertGen.addExtension(Extension.subjectKeyIdentifier, false, - createSubjectKeyId(_subPub)); - - _v3CertGen.addExtension(Extension.authorityKeyIdentifier, false, + X509v3CertificateBuilder _v3CertGen = new JcaX509v3CertificateBuilder( + new X500Name(_issDN), + allocateSerialNumber(), + new Date(System.currentTimeMillis()), + new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), + new X500Name(_subDN), + _subPub) + .addExtension(Extension.subjectKeyIdentifier, false, + createSubjectKeyId(_subPub)) + .addExtension(Extension.authorityKeyIdentifier, false, createAuthorityKeyId(_issPub)); if (_ca) { _v3CertGen.addExtension(Extension.basicConstraints, false, - new BasicConstraints(_ca)); + new BasicConstraints(_ca)); } else { _v3CertGen.addExtension(Extension.extendedKeyUsage, true, - new ExtendedKeyUsage(KeyPurposeId.id_kp_timeStamping)); + new ExtendedKeyUsage(KeyPurposeId.id_kp_timeStamping)); } - X509Certificate _cert = _v3CertGen.generate(_issPriv); - - _cert.checkValidity(new Date()); - _cert.verify(_issPub); + X509CertificateHolder _cert = _v3CertGen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(_issPriv)); - return _cert; + return new JcaX509CertificateConverter().setProvider(BC).getCertificate(_cert); } - - /* - * + /* + * * INTERNAL METHODS - * + * */ private static AuthorityKeyIdentifier createAuthorityKeyId(PublicKey _pubKey) - throws IOException + throws IOException { return extUtils.createAuthorityKeyIdentifier(_pubKey); } private static SubjectKeyIdentifier createSubjectKeyId(PublicKey _pubKey) - throws IOException + throws IOException { return extUtils.createSubjectKeyIdentifier(_pubKey); } diff --git a/pkix/src/test/jdk1.2/org/bouncycastle/cert/cmp/test/TestUtils.java b/pkix/src/test/jdk1.2/org/bouncycastle/cert/cmp/test/TestUtils.java new file mode 100644 index 0000000000..db3ef1e668 --- /dev/null +++ b/pkix/src/test/jdk1.2/org/bouncycastle/cert/cmp/test/TestUtils.java @@ -0,0 +1,80 @@ +package org.bouncycastle.cert.cmp.test; + +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.Date; + +import junit.framework.Assert; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.cert.CertException; +import org.bouncycastle.cert.CertIOException; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.ContentVerifierProvider; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; + +class TestUtils +{ + static X509CertificateHolder makeV3Certificate(String _subDN, KeyPair issKP) + throws OperatorCreationException, CertException, CertIOException + { + PrivateKey issPriv = issKP.getPrivate(); + PublicKey issPub = issKP.getPublic(); + + X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( + new X500Name(_subDN), + BigInteger.valueOf(System.currentTimeMillis()), + new Date(System.currentTimeMillis()), + new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), + new X500Name(_subDN), + issKP.getPublic()); + + certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(0)); + + ContentSigner signer = new JcaContentSignerBuilder("SHA256withDSA").build(issPriv); + + X509CertificateHolder certHolder = certGen.build(signer); + + ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().build(issPub); + +// Assert.assertTrue(certHolder.isSignatureValid(verifier)); + + return certHolder; + } + + static X509CertificateHolder makeV3Certificate(SubjectPublicKeyInfo pubKey, X500Name _subDN, KeyPair issKP, String _issDN) + throws OperatorCreationException, CertException, CertIOException + { + PrivateKey issPriv = issKP.getPrivate(); + PublicKey issPub = issKP.getPublic(); + + X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( + new X500Name(_issDN), + BigInteger.valueOf(System.currentTimeMillis()), + new Date(System.currentTimeMillis()), + new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), + _subDN, + pubKey); + + certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(false)); + + ContentSigner signer = new JcaContentSignerBuilder("SHA256withDSA").build(issPriv); + + X509CertificateHolder certHolder = certGen.build(signer); + + ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().build(issPub); + + //Assert.assertTrue(certHolder.isSignatureValid(verifier)); + + return certHolder; + } +} diff --git a/pkix/src/test/jdk1.3/org/bouncycastle/cert/test/BcCertTest.java b/pkix/src/test/jdk1.3/org/bouncycastle/cert/test/BcCertTest.java index 2416275381..4740cbc15a 100644 --- a/pkix/src/test/jdk1.3/org/bouncycastle/cert/test/BcCertTest.java +++ b/pkix/src/test/jdk1.3/org/bouncycastle/cert/test/BcCertTest.java @@ -17,11 +17,11 @@ import java.util.Set; import junit.framework.TestCase; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; @@ -487,7 +487,7 @@ public void checkKeyUsage( X509CertificateHolder certHld = new X509CertificateHolder(bytes); - if ((DERBitString.getInstance(certHld.getExtension(Extension.keyUsage).getParsedValue()).getBytes()[0] & 0x01) != 0) + if ((ASN1BitString.getInstance(certHld.getExtension(Extension.keyUsage).getParsedValue()).getBytes()[0] & 0x01) != 0) { fail("error generating cert - key usage wrong."); } diff --git a/pkix/src/test/jdk1.3/org/bouncycastle/pkcs/test/PKCS10Test.java b/pkix/src/test/jdk1.3/org/bouncycastle/pkcs/test/PKCS10Test.java new file mode 100644 index 0000000000..9a296fa37a --- /dev/null +++ b/pkix/src/test/jdk1.3/org/bouncycastle/pkcs/test/PKCS10Test.java @@ -0,0 +1,261 @@ +package org.bouncycastle.pkcs.test; + +import java.math.BigInteger; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Security; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPublicKeySpec; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DERBitString; +import org.bouncycastle.asn1.pkcs.CertificationRequest; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.Extensions; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralNames; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; +import org.bouncycastle.pkcs.DeltaCertAttributeUtils; +import org.bouncycastle.pkcs.DeltaCertificateRequestAttributeValue; +import org.bouncycastle.pkcs.DeltaCertificateRequestAttributeValueBuilder; +import org.bouncycastle.pkcs.PKCS10CertificationRequest; +import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; +import org.bouncycastle.pqc.jcajce.spec.DilithiumParameterSpec; +import org.bouncycastle.test.PrintTestResult; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.Hex; + +public class PKCS10Test + extends TestCase +{ + private static final byte[] anssiPkcs10 = Base64.decode( + "MIHLMHMCAQAwDzENMAsGA1UEAwwEYmx1YjBbMBUGByqGSM49AgEGCiqBegGB" + + "X2WCAAEDQgAEB9POXLIasfF55GSxY9vshIIEnvv47B9jGZgZFN6VFHPvqe8G" + + "j+6UpLjP0vvoInC8uu/X3JJJTsrgGrxbfOOG1KAAMAoGCCqGSM49BAMCA0gA" + + "MEUCIQCgTdLV3IS5NuL9CHMDPOj6BumAQPdjzbgkGZghoY/wJAIgcEgF/2f4" + + "5wYlIELOq18Uxksc0sOkbZm/nRXs1VX4rsM="); + + // + // personal keys + // + private static final RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( + new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), + new BigInteger("11", 16)); + + private static final RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( + new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), + new BigInteger("11", 16), + new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), + new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), + new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), + new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), + new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), + new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); + + private byte[] emptyExtensionsReq = Base64.decode( + "MIICVDCCATwCAQAwADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKy8\n" + + "4oC/QPFkRBE04LIA5njEulZx/EEh+J2spnThoRwk+oycYEVKp95NSfGTAoNjTwUv\n" + + "TdB9c1PCPE1DmgZIVLEVvouB7sZbMbLSI0d//oMO/Wr/CZmvjPGB8DID7RJs0eqO\n" + + "gLgSuyBVrwbcSKtxH4NrNDsS5IZXCcE3xzkxMDdz72m9jvIrl2ivi+YmJ7cJo3N+\n" + + "DBEqHZW28oytOmVo+8zhxvnHb9w26GJEOxN5zYbiIVW2vU9OfeF9te+Rhnks43Pk\n" + + "YDDP2U4hR7q0BYrdkeWdA1ReleYyn/haeAoIVLZMANIOXobiqASKqSusVq9tLD67\n" + + "7TAywl5AVq8GOBzlXZUCAwEAAaAPMA0GCSqGSIb3DQEJDjEAMA0GCSqGSIb3DQEB\n" + + "CwUAA4IBAQAXck62gJw1deVOLVFAwBNVNXgJarHtDg3pauHTHvN+pSbdOTe1aRzb\n" + + "Tt4/govtuuGZsGWlUqiglLpl6qeS7Pe9m+WJwhH5yXnJ3yvy2Lc/XkeVQ0kt8uFg\n" + + "30UyrgKng6LDgUGFjDSiFr3dK8S/iYpDu/qpl1bWJPWmfmnIXzZWWvBdUTKlfoD9\n" + + "/NLIWINEzHQIBXGy2uLhutYOvDq0WDGOgtdFC8my/QajaJh5lo6mM/PlmcYjK286\n" + + "EdGSIxdME7hoW/ljA5355S820QZDkYx1tI/Y/YaY5KVOntwfDQzQiwWZ2PtpTqSK\n" + + "KYe2Ujb362yaERCE13DJC4Us9j8OOXcW\n"); + + public void setUp() + { + Security.addProvider(new BouncyCastleProvider()); + } + + public void testLeaveOffEmpty() + throws Exception + { + KeyFactory keyFact = KeyFactory.getInstance("RSA", "BC"); + PublicKey pubKey = keyFact.generatePublic(pubKeySpec); + PrivateKey privKey = keyFact.generatePrivate(privKeySpec); + + PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=Test"), pubKey); + + PKCS10CertificationRequest request = pkcs10Builder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privKey)); + + assertEquals(0, request.getAttributes().length); + assertNotNull(CertificationRequest.getInstance(request.getEncoded()).getCertificationRequestInfo().getAttributes()); + + pkcs10Builder.setLeaveOffEmptyAttributes(true); + + request = pkcs10Builder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privKey)); + + assertEquals(0, request.getAttributes().length); + assertNull(CertificationRequest.getInstance(request.getEncoded()).getCertificationRequestInfo().getAttributes()); + + pkcs10Builder.setLeaveOffEmptyAttributes(false); + + request = pkcs10Builder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privKey)); + + assertEquals(0, request.getAttributes().length); + assertNotNull(CertificationRequest.getInstance(request.getEncoded()).getCertificationRequestInfo().getAttributes()); + } + + public void testRequest() + throws Exception + { + JcaPKCS10CertificationRequest req = new JcaPKCS10CertificationRequest(anssiPkcs10); + + assertTrue(req.getPublicKey().toString().startsWith("EC Public Key [9a:f5:f3:36:55:81:27:66:dd:d8:76:5a:96:6b:26:7b:0c:61:a2:94]")); + } + + public void testEmptyExtRequest() + throws Exception + { + JcaPKCS10CertificationRequest req = new JcaPKCS10CertificationRequest(emptyExtensionsReq); + + try + { + req.getRequestedExtensions(); + fail("no exception thrown"); + } + catch (IllegalStateException e) + { + assertEquals("pkcs_9_at_extensionRequest present but has no value", e.getMessage()); + } + } + + public void testBrokenRequestWithDuplicateExtension() + throws Exception + { + + GeneralName name1 = new GeneralName(GeneralName.dNSName, "bc1.local"); + GeneralName name2 = new GeneralName(GeneralName.dNSName, "bc2.local"); + + + PKCS10CertificationRequest req = new PKCS10CertificationRequest(Hex.decode( + "30820312308201fa02010030818f310b300906035504061302415531" + + "283026060355040a0c1f546865204c6567696f6e206f662074686520426f756e637920436173746c653112301006035504070c094d" + + "656c626f75726e653111300f06035504080c08566963746f726961312f302d06092a864886f70d0109011620666565646261636b2d" + + "63727970746f40626f756e6379636173746c652e6f726730820122300d06092a864886f70d01010105000382010f003082010a0282" + + "010100b08c92" + + "7375b27e0f4f5642b8a96cca146f8ac8174b06f3d426943d49b2a2b4c5ab440a9f5c8596962d922d968b485394bfbe772422f8c32" + + "7799224ca9f6dd6ded47c05a9ca2f619826958f1eb63c68d81732a310c88b821c8f207292e095423552ec74ab593a13422186b732" + + "4106c0c35ca54cc46d4913f9a2d16282fcb9e32a3e4a5f764152d5c0fa1c2ca96b4ceee3f62683b2751b5f1abccd2d56f8960a887" + + "1c7e186048fae235c863561f754bcb95ced6f89bcdc47ce6f5790600b23d14e27e5a89edcc6c25d78588fa87df199aaab01cc6594" + + "6546b550351dab5e39002fc743851d46f65e9459b08e00e84b3e59b1c03cf8156cd9a1220671cedeeae66d0203010001a03d303b0" + + "6092a864886f70d01090e312e302c30140603551d11040d300b82096263312e6c6f63616c30140603551d11040d300b8209626332" + + "2e6c6f63616c300d06092a864886f70d01010b050003820101005f1a893308777f0cdacaeb7b62bebf7440769cddc7c696fe8f086" + + "d59244aabe6d9591de69eac0ab9aca0c574ec04262cfbbdf9491444721904296f7db45dc68e27bf13803988949caad9faa903852b" + + "a2ad9370c8127e25b92dc8849fa5b028fcdab529fecde2f0c2531d8bc6df3bd0896524b236ec60000db091561ec00b1a3c408d08a" + + "1458caa0acb20efb9305892dd46fd062c5ac67caf8109e3947c7619e30ff271f9b2b968620c01960f55bd18c9abae088b318b853e" + + "a00b7a0c47e569b843dbee57b57d42d01d0c2c63c035a4aea26ae2f7f824ee112b2a78c9bb859e2ae5d035dfab1210c4af4233895" + + "53417705b4c32aaff3d12ffad2709ea50464b90")); + + + // + // Disassemble the attributes with the duplicate extensions. + // + Extensions extensions = req.getRequestedExtensions(); + GeneralNames subjectAltNames = GeneralNames.fromExtensions(extensions, Extension.subjectAlternativeName); + + // + // Check expected order and value. + // + GeneralName[] names = subjectAltNames.getNames(); + if (!names[0].equals(name1)) + { + fail("expected name 1"); + } + + if (!names[1].equals(name2)) + { + fail("expected name 2"); + } + } + + public void testAltRequestAttributes() + throws Exception + { + KeyPairGenerator p256Kpg = KeyPairGenerator.getInstance("EC", "BC"); + p256Kpg.initialize(new ECNamedCurveGenParameterSpec("P-256")); + KeyPair p256Kp = p256Kpg.generateKeyPair(); + + KeyPairGenerator dilKpg = KeyPairGenerator.getInstance("Dilithium", "BC"); + dilKpg.initialize(DilithiumParameterSpec.dilithium2); + KeyPair dilKp = dilKpg.generateKeyPair(); + + JcaPKCS10CertificationRequestBuilder jcaPkcs10Builder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=Test"), p256Kp.getPublic()); + + ContentSigner altSigner = new JcaContentSignerBuilder("Dilithium2").setProvider("BC").build(dilKp.getPrivate()); + + PKCS10CertificationRequest request = jcaPkcs10Builder.build(((JcaContentSignerBuilder)new JcaContentSignerBuilder("SHA256withECDSA").setProvider("BC")).build(p256Kp.getPrivate()), dilKp.getPublic(), altSigner); + + assertTrue(request.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(p256Kp.getPublic()))); + + assertTrue(request.hasAltPublicKey()); + + assertTrue(request.isAltSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(dilKp.getPublic()))); + } + + public void testDeltaRequestAttribute() + throws Exception + { + KeyPairGenerator p256Kpg = KeyPairGenerator.getInstance("EC", "BC"); + p256Kpg.initialize(new ECNamedCurveGenParameterSpec("P-256")); + KeyPair p256Kp = p256Kpg.generateKeyPair(); + + KeyPairGenerator dilKpg = KeyPairGenerator.getInstance("Dilithium", "BC"); + dilKpg.initialize(DilithiumParameterSpec.dilithium2); + KeyPair dilKp = dilKpg.generateKeyPair(); + + PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=Test"), p256Kp.getPublic()); + + ContentSigner deltaSigner = new JcaContentSignerBuilder("Dilithium2").setProvider("BC").build(dilKp.getPrivate()); + + DeltaCertificateRequestAttributeValueBuilder deltaAttrBldr = new DeltaCertificateRequestAttributeValueBuilder( + SubjectPublicKeyInfo.getInstance(dilKp.getPublic().getEncoded())); + + deltaAttrBldr.setSignatureAlgorithm(deltaSigner.getAlgorithmIdentifier()); + deltaAttrBldr.setSubject(new X500Name("CN=Dil2 Cert Req Test")); + + DeltaCertificateRequestAttributeValue deltaAttr = deltaAttrBldr.build(); + + pkcs10Builder.addAttribute(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.2"), deltaAttr); + + PKCS10CertificationRequest deltaReq = pkcs10Builder.build(deltaSigner); + + pkcs10Builder.addAttribute(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.3"), new DERBitString(deltaReq.getSignature())); + + PKCS10CertificationRequest request = pkcs10Builder.build(new JcaContentSignerBuilder("SHA256withECDSA").setProvider("BC").build(p256Kp.getPrivate())); + + assertTrue(DeltaCertAttributeUtils.isDeltaRequestSignatureValid(request, new JcaContentVerifierProviderBuilder().setProvider("BC").build(dilKp.getPublic()))); + + assertTrue(request.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(p256Kp.getPublic()))); + } + + + public static void main(String args[]) + { + PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); + } + + public static Test suite() + { + return new BCTestSetup(new TestSuite(PKCS10Test.class)); + } +} diff --git a/pkix/src/test/resources/org/bouncycastle/openssl/test/ec_attr_key.pem b/pkix/src/test/resources/org/bouncycastle/openssl/test/ec_attr_key.pem new file mode 100644 index 0000000000..62683d8716 --- /dev/null +++ b/pkix/src/test/resources/org/bouncycastle/openssl/test/ec_attr_key.pem @@ -0,0 +1,20 @@ +-----BEGIN EC PRIVATE KEY----- +MIAogDGAgQAxgCiAMACiAAAAMYAxgIEAMYAogKIAAAAwgCiAMICBADCAKIAwAIEAAAAAAAAA +gQAAAAAAAAAwgIEAMYAogDAAogAAADCAMYCBADGAKICiAAAAMIBOTk5OTk5OTk5OTk5OTk5O +Tk5OTrlOToAogDAAgQAAAACAgQAxgCiAMACiAAAAMYAxgIEAMYAogKIAAAAwgCiAMICBADCA +KIAwAIEAAAAAAAAAgQAAAAAAAAAxgIEAsYAogDAAogAAADCAMYCBADGAKICiAAAAMIBOTk4K +AAAATk5OTk5OTk5OTk5OTk5OTk65Tk6AKIAwAIEAAAAAAAAAgQAAAAAAAAAAAIEAKIAwgIEA +MIAogDAAgQAAAAAAAACBAAAAMIAogDCAgQAxgCiAMACiAAAAMIAxgIEAMYAwgCiAMICBADCA +KIAwAIEAAAAAAAAAgQAAAAAAAAAAAIEAKIAxgIEAMIAwgCiAMYCBADGAKIAwAKIAAAAxgDGA +gQAxgCiAogAAADCAKIAwgIEAMIAogDAAgQAAAAAAAACBAAAAAAAAADCAgQAxgCiAMACiAAAA +MIAxgIEAMYAogKIAAAAwgE5OTk5OTk5OTk5OTk5OTk5OTk5OuU5OgCiAMACBAAAAAICBADGA +KIAwAKIAAAAxgDGAgQAxgCiAogAAADCAKIAwgIEAMIAogDAAgQAAAAAAAACBAAAAAAAAADGA +gQCxgCiAMACiAAAAMIAxgIEAMYAogKIAAAAwgE5OTgoAAABOTk5OTk5OTk5OTk5OTk5OTrlO +ToAogDAAgQAAAAAAAACBAAAAAAAAAAAAgQAogDCAgQAwgCiAMACBAAAAAAAAAIEAAAAwgCiA +MICBADGAKIAwAKIAAAAwgDGAgQAxgDCAKIAwgIEAMIAogDAAgQAAAAAAAACBAAAAAAAAAAAA +gQAogDGAgQAwgCiAAhkwAIEAAAAAAAAAgQAAAAAAAAAAAIEogDAAgQAAAAAAAACBAAAAAAAA +AAAAgQAogDGAgQAwgCiAMACBAAAAAAAAAIEAAAAAAAAAAACBAAAAAAAAAAAAgQAAAAAAAAAA +AAAAgQAAAAAAKIACGTAAgQAAAAAAAACBAAAAAAAAAAAAgSiAMACBAAAAAAAAAIEAAAAAAAAA +AACBACiAMYCBADCAKIAwAIEAAAAAAAAAgQAAAAAAAAAAAIEAAAAAAAAAAACBAAAAAAAAAAAA +AACBAAAAAAA= +-----END EC PRIVATE KEY----- diff --git a/prov/build.gradle b/prov/build.gradle index ca870be7cb..7cd1c966de 100644 --- a/prov/build.gradle +++ b/prov/build.gradle @@ -1,28 +1,165 @@ +plugins { + id "biz.aQute.bnd.builder" version "7.0.0" +} + dependencies { implementation project(':core') + testImplementation files('../libs/unboundid-ldapsdk-6.0.8.jar') } jar.archiveBaseName = "bcprov-$vmrange" - sourceSets { main { java { srcDirs '../core/src/main/java' } } + + java9 { + java { + srcDirs = ['src/main/jdk1.9'] + } + } + java11 { + java { + srcDirs = ['src/main/jdk1.11'] + } + } + java15 { + java { + srcDirs = ['src/main/jdk1.15'] + } + } + java21 { + java { + srcDirs = ['src/main/jdk21'] + } + } + +} + +dependencies { + java9Implementation files([sourceSets.main.output.classesDirs]) { + builtBy compileJava + } + + java11Implementation files([ + sourceSets.main.output.classesDirs, + sourceSets.java9.output.classesDirs]) { + builtBy compileJava9Java + } + + java15Implementation files([ + sourceSets.main.output.classesDirs, + sourceSets.java9.output.classesDirs, + sourceSets.java11.output.classesDirs]) { + builtBy compileJava11Java + } + + java21Implementation files([ + sourceSets.main.output.classesDirs, + sourceSets.java9.output.classesDirs, + sourceSets.java11.output.classesDirs, + sourceSets.java15.output.classesDirs]) { + builtBy compileJava15Java + } +} + +compileJava { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + targetCompatibility = 1.8; + sourceCompatibility = 1.8; +} + +compileJava9Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + sourceCompatibility = 9 + targetCompatibility = 9 + options.sourcepath = files(['../core/src/main/java', 'src/main/java', 'src/main/jdk1.9']) } +compileJava11Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + sourceCompatibility = 11 + targetCompatibility = 11 + options.sourcepath = files(['src/main/java', 'src/main/jdk1.11']) +} + +compileJava15Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + sourceCompatibility = 15 + targetCompatibility = 15 + options.sourcepath = files(['src/main/java', 'src/main/jdk1.15']) +} + +compileJava21Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(21) + } + sourceCompatibility = 21 + targetCompatibility = 21 + options.sourcepath = files(['src/main/java', 'src/main/jdk21']) +} + + task sourcesJar(type: Jar) { - archiveBaseName = jar.archiveBaseName - classifier = 'sources' - from sourceSets.main.allSource + archiveBaseName = jar.archiveBaseName + archiveClassifier = 'sources' + from sourceSets.main.allSource + exclude("**/*.so") + into('META-INF/versions/9') { + from sourceSets.java9.allSource + } + into('META-INF/versions/11') { + from sourceSets.java11.allSource + } + into('META-INF/versions/15') { + from sourceSets.java15.allSource + } + into('META-INF/versions/21') { + from sourceSets.java21.allSource + } } +jar { + from sourceSets.main.output + into('META-INF/versions/9') { + from sourceSets.java9.output + } + into('META-INF/versions/11') { + from sourceSets.java11.output + } + into('META-INF/versions/15') { + from sourceSets.java15.output + } + into('META-INF/versions/21') { + from sourceSets.java21.output + } + String v = "${rootProject.extensions.ext.bundle_version}" + manifest.attributes('Multi-Release': 'true') + manifest.attributes('Bundle-Name': 'bcprov') + manifest.attributes('Bundle-SymbolicName': 'bcprov') + manifest.attributes('Bundle-RequiredExecutionEnvironment': 'JavaSE-1.8') + manifest.attributes('Export-Package': "!org.bouncycastle.internal.*,org.bouncycastle.*;version=${v}") + manifest.attributes('Import-Package': 'java.*;resolution:=optional,javax.*;resolution:=optional') + manifest.attributes('Bundle-Version': "${v}") + +} + + task javadocJar(type: Jar, dependsOn: javadoc) { - archiveBaseName = jar.archiveBaseName - classifier = 'javadoc' - from javadoc.destinationDir + archiveBaseName = jar.archiveBaseName + archiveClassifier = 'javadoc' + from javadoc.destinationDir } artifacts { @@ -31,3 +168,174 @@ artifacts { archives sourcesJar } + + +sourceSets { + test11 { + java { + compileClasspath += main.output + test.output + runtimeClasspath += test.output + srcDir(files("src/test/jdk1.11", "src/test/java")) + } + } + + test17 { + java { + compileClasspath += main.output + test.output + runtimeClasspath += test.output + srcDir(files("src/test/jdk1.11","src/test/jdk1.15", "src/test/java")) + } + } + + test21 { + java { + compileClasspath += main.output + test.output + runtimeClasspath += test.output + srcDir(files("src/test/jdk1.11","src/test/jdk1.15","src/test/jdk21", "src/test/java")) + } + } +} + +dependencies { + test11Implementation group: 'junit', name: 'junit', version: '4.13.2' + test17Implementation group: 'junit', name: 'junit', version: '4.13.2' + test21Implementation group: 'junit', name: 'junit', version: '4.13.2' + test11Implementation files('../libs/unboundid-ldapsdk-6.0.8.jar') + test17Implementation files('../libs/unboundid-ldapsdk-6.0.8.jar') + test21Implementation files('../libs/unboundid-ldapsdk-6.0.8.jar') + test11Implementation(project(":core")) + test17Implementation(project(":core")) + test21Implementation(project(":core")) +} + + + + +compileTest11Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + sourceCompatibility = 11 + targetCompatibility = 11 + options.sourcepath = files(['src/test/java', 'src/test/jdk1.11']) +} + +compileTest17Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + sourceCompatibility = 17 + targetCompatibility = 17 + options.sourcepath = files(['src/test/java', 'src/test/jdk1.15']) +} + +compileTest21Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(21) + } + sourceCompatibility = 21 + targetCompatibility = 21 + options.sourcepath = files(['src/test/java', 'src/test/jdk21']) +} + +test { + jvmArgs = ['-Dtest.java.version.prefix=1.8'] +} + + +task test11(type: Test) { + + dependsOn(jar) + + testClassesDirs = sourceSets.test11.output.classesDirs + classpath = sourceSets.test11.runtimeClasspath + files(jar.archiveFile) + + forkEvery = 1; + maxParallelForks = 8; + + systemProperty 'bc.test.data.home', bcTestDataHome + maxHeapSize = "1536m" + testLogging.showStandardStreams = true + + javaLauncher = javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(11) + } + + jvmArgs = ['-Dtest.java.version.prefix=11.'] + + + finalizedBy jacocoTestReport + + filter { + includeTestsMatching "AllTest*" + if (project.hasProperty('excludeTests')) { + excludeTestsMatching "${excludeTests}" + } + } +} + +task test17(type: Test) { + + // This is testing the 1.15 code base + + dependsOn jar + + testClassesDirs = sourceSets.test17.output.classesDirs + classpath = sourceSets.test17.runtimeClasspath + files(jar.archiveFile) + + forkEvery = 1; + maxParallelForks = 8; + + systemProperty 'bc.test.data.home', bcTestDataHome + maxHeapSize = "1536m" + testLogging.showStandardStreams = true + + javaLauncher = javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(17) + } + + jvmArgs = ['-Dtest.java.version.prefix=17.'] + + + finalizedBy jacocoTestReport + + filter { + includeTestsMatching "AllTest*" + if (project.hasProperty('excludeTests')) { + excludeTestsMatching "${excludeTests}" + } + } +} + +task test21(type: Test) { + + // This is testing the 21 code base + + dependsOn jar + + testClassesDirs = sourceSets.test21.output.classesDirs + classpath = sourceSets.test21.runtimeClasspath + files(jar.archiveFile) + + forkEvery = 1; + maxParallelForks = 8; + + systemProperty 'bc.test.data.home', bcTestDataHome + maxHeapSize = "1536m" + testLogging.showStandardStreams = true + + javaLauncher = javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(21) + } + + jvmArgs = ['-Dtest.java.version.prefix=21'] + + + finalizedBy jacocoTestReport + + filter { + includeTestsMatching "AllTest*" + if (project.hasProperty('excludeTests')) { + excludeTestsMatching "${excludeTests}" + } + } +} diff --git a/prov/src/main/ext-jdk1.9/module-info.java b/prov/src/main/ext-jdk1.9/module-info.java index a04c1d2bf0..97a1f88810 100644 --- a/prov/src/main/ext-jdk1.9/module-info.java +++ b/prov/src/main/ext-jdk1.9/module-info.java @@ -1,6 +1,7 @@ module org.bouncycastle.provider { requires java.sql; + requires java.logging; requires java.naming; provides java.security.Provider with org.bouncycastle.jce.provider.BouncyCastleProvider,org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; @@ -13,24 +14,10 @@ exports org.bouncycastle.asn1.anssi; exports org.bouncycastle.asn1.bc; exports org.bouncycastle.asn1.cryptopro; - exports org.bouncycastle.asn1.cryptlib; - exports org.bouncycastle.asn1.edec; exports org.bouncycastle.asn1.gm; - exports org.bouncycastle.asn1.gnu; - exports org.bouncycastle.asn1.iana; - exports org.bouncycastle.asn1.isara; - exports org.bouncycastle.asn1.iso; - exports org.bouncycastle.asn1.kisa; - exports org.bouncycastle.asn1.microsoft; - exports org.bouncycastle.asn1.misc; - exports org.bouncycastle.asn1.mozilla; exports org.bouncycastle.asn1.nist; - exports org.bouncycastle.asn1.nsri; - exports org.bouncycastle.asn1.ntt; exports org.bouncycastle.asn1.ocsp; - exports org.bouncycastle.asn1.oiw; exports org.bouncycastle.asn1.pkcs; - exports org.bouncycastle.asn1.rosstandart; exports org.bouncycastle.asn1.sec; exports org.bouncycastle.asn1.teletrust; exports org.bouncycastle.asn1.ua; @@ -123,7 +110,7 @@ exports org.bouncycastle.pqc.crypto.bike; exports org.bouncycastle.pqc.crypto.cmce; exports org.bouncycastle.pqc.crypto.crystals.dilithium; - exports org.bouncycastle.pqc.crypto.crystals.kyber; + exports org.bouncycastle.pqc.crypto.mlkem; exports org.bouncycastle.pqc.crypto.falcon; exports org.bouncycastle.pqc.crypto.frodo; exports org.bouncycastle.pqc.crypto.gemss; @@ -135,7 +122,6 @@ exports org.bouncycastle.pqc.crypto.picnic; exports org.bouncycastle.pqc.crypto.rainbow; exports org.bouncycastle.pqc.crypto.saber; - exports org.bouncycastle.pqc.legacy.crypto.sike; exports org.bouncycastle.pqc.crypto.sphincs; exports org.bouncycastle.pqc.crypto.sphincsplus; exports org.bouncycastle.pqc.crypto.util; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java index 038eed6f6c..e0831e7b59 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java @@ -3,47 +3,102 @@ import java.io.IOException; import java.security.PrivateKey; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.jcajce.provider.asymmetric.compositesignatures.CompositeSignaturesConstants; +import org.bouncycastle.jcajce.provider.asymmetric.compositesignatures.KeyFactorySpi; +import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; +import org.bouncycastle.util.Exceptions; /** * A composite private key class. */ -public class CompositePrivateKey - implements PrivateKey +public class CompositePrivateKey implements PrivateKey { private final List keys; + private ASN1ObjectIdentifier algorithmIdentifier; + /** - * Create a composite key containing a single private key. + * Create a composite private key from an array of PublicKeys. + * This constructor is currently used only for legacy composites implementation. * - * @param keys the private keys the composite private key wraps. + * @param keys The component private keys. */ public CompositePrivateKey(PrivateKey... keys) { + this(MiscObjectIdentifiers.id_composite_key, keys); + } + + /** + * Create a composite private key which corresponds to a composite signature algorithm in algorithmIdentifier. + * The component private keys are not checked if they satisfy the composite definition at this point, + * however, they will fail when they are fed into component algorithms which are defined by the algorithmIdentifier. + * + * @param algorithmIdentifier + * @param keys + */ + public CompositePrivateKey(ASN1ObjectIdentifier algorithmIdentifier, PrivateKey... keys) + { + this.algorithmIdentifier = algorithmIdentifier; + if (keys == null || keys.length == 0) { - throw new IllegalArgumentException("at least one public key must be provided"); + throw new IllegalArgumentException("at least one private key must be provided for the composite private key"); } List keyList = new ArrayList(keys.length); - for (int i = 0; i != keys.length; i++) + for (int i = 0; i < keys.length; i++) { keyList.add(keys[i]); } this.keys = Collections.unmodifiableList(keyList); } + /** + * Create a composite private key from a PrivateKeyInfo. + * + * @param keyInfo PrivateKeyInfo object containing a composite private key. + */ + public CompositePrivateKey(PrivateKeyInfo keyInfo) + { + CompositePrivateKey privateKeyFromFactory = null; + ASN1ObjectIdentifier keyInfoIdentifier = keyInfo.getPrivateKeyAlgorithm().getAlgorithm(); + try + { + if (!Arrays.asList(CompositeSignaturesConstants.supportedIdentifiers).contains(keyInfoIdentifier)) + { + throw new IllegalStateException("Unable to create CompositePrivateKey from PrivateKeyInfo"); + } + AsymmetricKeyInfoConverter keyInfoConverter = new KeyFactorySpi(); + privateKeyFromFactory = (CompositePrivateKey) keyInfoConverter.generatePrivate(keyInfo); + + if (privateKeyFromFactory == null) + { + throw new IllegalStateException("Unable to create CompositePrivateKey from PrivateKeyInfo"); + } + } + catch (IOException e) + { + throw Exceptions.illegalStateException(e.getMessage(), e); + } + + this.keys = privateKeyFromFactory.getPrivateKeys(); + this.algorithmIdentifier = privateKeyFromFactory.getAlgorithmIdentifier(); + } + /** * Return a list of the component private keys making up this composite. - * + * * @return an immutable list of private keys. */ public List getPrivateKeys() @@ -53,7 +108,12 @@ public List getPrivateKeys() public String getAlgorithm() { - return "Composite"; + return CompositeSignaturesConstants.ASN1IdentifierAlgorithmNameMap.get(this.algorithmIdentifier).getId(); + } + + public ASN1ObjectIdentifier getAlgorithmIdentifier() + { + return algorithmIdentifier; } public String getFormat() @@ -61,23 +121,29 @@ public String getFormat() return "PKCS#8"; } + /** + * Returns the encoding of the composite private key. + * It is compliant with https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html#name-compositesignatureprivateke + * as each component is encoded as a PrivateKeyInfo (older name for OneAsymmetricKey). + * + * @return + */ public byte[] getEncoded() { ASN1EncodableVector v = new ASN1EncodableVector(); - for (int i = 0; i != keys.size(); i++) + for (int i = 0; i < keys.size(); i++) { v.add(PrivateKeyInfo.getInstance(keys.get(i).getEncoded())); } try { - return new PrivateKeyInfo( - new AlgorithmIdentifier(MiscObjectIdentifiers.id_composite_key), new DERSequence(v)).getEncoded(ASN1Encoding.DER); + return new PrivateKeyInfo(new AlgorithmIdentifier(this.algorithmIdentifier), new DERSequence(v)).getEncoded(ASN1Encoding.DER); } catch (IOException e) { - throw new IllegalStateException("unable to encode composite key: " + e.getMessage()); + throw new IllegalStateException("unable to encode composite private key: " + e.getMessage()); } } @@ -95,7 +161,14 @@ public boolean equals(Object o) if (o instanceof CompositePrivateKey) { - return keys.equals(((CompositePrivateKey)o).keys); + boolean isEqual = true; + CompositePrivateKey comparedKey = (CompositePrivateKey) o; + if (!comparedKey.getAlgorithmIdentifier().equals(this.algorithmIdentifier) || !this.keys.equals(comparedKey.keys)) + { + isEqual = false; + } + + return isEqual; } return false; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java index 7491ad5fc5..1bc8a6e634 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java @@ -3,38 +3,60 @@ import java.io.IOException; import java.security.PublicKey; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.jcajce.provider.asymmetric.compositesignatures.CompositeSignaturesConstants; +import org.bouncycastle.jcajce.provider.asymmetric.compositesignatures.KeyFactorySpi; +import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; /** * A composite key class. */ -public class CompositePublicKey - implements PublicKey +public class CompositePublicKey implements PublicKey { private final List keys; + private final ASN1ObjectIdentifier algorithmIdentifier; + /** - * Create a composite key containing a single public key. + * Create a composite public key from an array of PublicKeys. + * This constructor is currently used only for legacy composites implementation. * - * @param keys the public keys the composite key wraps. + * @param keys The component public keys. */ public CompositePublicKey(PublicKey... keys) { + this(MiscObjectIdentifiers.id_composite_key, keys); + } + + /** + * Create a composite public key which corresponds to a composite signature algorithm in algorithmIdentifier. + * The component public keys are not checked if they satisfy the composite definition at this point, + * however, they will fail when they are fed into component algorithms which are defined by the algorithmIdentifier. + * + * @param algorithmIdentifier + * @param keys + */ + public CompositePublicKey(ASN1ObjectIdentifier algorithmIdentifier, PublicKey... keys) + { + this.algorithmIdentifier = algorithmIdentifier; + if (keys == null || keys.length == 0) { - throw new IllegalArgumentException("at least one public key must be provided"); + throw new IllegalArgumentException("at least one public key must be provided for the composite public key"); } List keyList = new ArrayList(keys.length); - for (int i = 0; i != keys.length; i++) + for (int i = 0; i < keys.length; i++) { keyList.add(keys[i]); } @@ -42,9 +64,42 @@ public CompositePublicKey(PublicKey... keys) } /** - * Return a list of the component private keys making up this composite. + * Create a composite public key from a SubjectPublicKeyInfo. * - * @return an immutable list of private keys. + * @param keyInfo SubjectPublicKeyInfo object containing a composite public key. + */ + public CompositePublicKey(SubjectPublicKeyInfo keyInfo) + { + ASN1ObjectIdentifier keyInfoIdentifier = keyInfo.getAlgorithm().getAlgorithm(); + CompositePublicKey publicKeyFromFactory = null; + try + { + //Check if the public key algorithm specified in SubjectPublicKeyInfo is one of the supported composite signatures. + if (!Arrays.asList(CompositeSignaturesConstants.supportedIdentifiers).contains(keyInfoIdentifier)) + { + throw new IllegalStateException("unable to create CompositePublicKey from SubjectPublicKeyInfo"); + } + AsymmetricKeyInfoConverter keyInfoConverter = new KeyFactorySpi(); + publicKeyFromFactory = (CompositePublicKey) keyInfoConverter.generatePublic(keyInfo); + + if (publicKeyFromFactory == null) + { + throw new IllegalStateException("unable to create CompositePublicKey from SubjectPublicKeyInfo"); + } + } + catch (IOException e) + { + throw new IllegalStateException(e.getMessage(), e); + } + + this.keys = publicKeyFromFactory.getPublicKeys(); + this.algorithmIdentifier = publicKeyFromFactory.getAlgorithmIdentifier(); + } + + /** + * Return a list of the component public keys making up this composite. + * + * @return an immutable list of public keys. */ public List getPublicKeys() { @@ -53,7 +108,12 @@ public List getPublicKeys() public String getAlgorithm() { - return "Composite"; + return CompositeSignaturesConstants.ASN1IdentifierAlgorithmNameMap.get(this.algorithmIdentifier).getId(); + } + + public ASN1ObjectIdentifier getAlgorithmIdentifier() + { + return algorithmIdentifier; } public String getFormat() @@ -61,26 +121,46 @@ public String getFormat() return "X.509"; } + /** + * Returns the composite public key encoded as a SubjectPublicKeyInfo. + * If the composite public key is legacy (MiscObjectIdentifiers.id_composite_key), + * it each component public key is wrapped in its own SubjectPublicKeyInfo. + * Other composite public keys are encoded according to https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html#name-compositesignaturepublickey + * where each component public key is a BIT STRING which contains the result of calling + * getEncoded() for each component public key. + * + * @return + */ + @Override public byte[] getEncoded() { ASN1EncodableVector v = new ASN1EncodableVector(); - for (int i = 0; i != keys.size(); i++) + for (int i = 0; i < keys.size(); i++) { - v.add(SubjectPublicKeyInfo.getInstance(keys.get(i).getEncoded())); + if (this.algorithmIdentifier.equals(MiscObjectIdentifiers.id_composite_key)) + { + //Legacy, component is the whole SubjectPublicKeyInfo + v.add(SubjectPublicKeyInfo.getInstance(keys.get(i).getEncoded())); + } + else + { + //component is the value of subjectPublicKey from SubjectPublicKeyInfo + SubjectPublicKeyInfo keyInfo = SubjectPublicKeyInfo.getInstance(keys.get(i).getEncoded()); + v.add(keyInfo.getPublicKeyData()); + } } - try { - return new SubjectPublicKeyInfo( - new AlgorithmIdentifier(MiscObjectIdentifiers.id_composite_key), new DERSequence(v)).getEncoded(ASN1Encoding.DER); + return new SubjectPublicKeyInfo(new AlgorithmIdentifier(this.algorithmIdentifier), new DERSequence(v)).getEncoded(ASN1Encoding.DER); } catch (IOException e) { - throw new IllegalStateException("unable to encode composite key: " + e.getMessage()); + throw new IllegalStateException("unable to encode composite public key: " + e.getMessage()); } } + public int hashCode() { return keys.hashCode(); @@ -95,7 +175,14 @@ public boolean equals(Object o) if (o instanceof CompositePublicKey) { - return keys.equals(((CompositePublicKey)o).keys); + boolean isEqual = true; + CompositePublicKey comparedKey = (CompositePublicKey) o; + if (!comparedKey.getAlgorithmIdentifier().equals(this.algorithmIdentifier) || !this.keys.equals(comparedKey.keys)) + { + isEqual = false; + } + + return isEqual; } return false; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/ExternalPublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/ExternalPublicKey.java index 5d5fdf7a1b..7549fd58ab 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/ExternalPublicKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/ExternalPublicKey.java @@ -58,7 +58,7 @@ public ExternalPublicKey(PublicKey key, GeneralName location, MessageDigest dige */ public ExternalPublicKey(ExternalValue extKey) { - this(extKey.getLocation(), extKey.getHashAlg(), extKey.getHashVal().getBytes()); + this(extKey.getLocation(), extKey.getHashAlg(), extKey.getHashValue()); } /** diff --git a/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLDSAKey.java b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLDSAKey.java new file mode 100644 index 0000000000..fe77659b2d --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLDSAKey.java @@ -0,0 +1,16 @@ +package org.bouncycastle.jcajce.interfaces; + +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; + +import java.security.Key; + +public interface MLDSAKey + extends Key +{ + /** + * Return the parameters for this key. + * + * @return a MLDSAParameterSpec + */ + MLDSAParameterSpec getParameterSpec(); +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLDSAPrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLDSAPrivateKey.java new file mode 100644 index 0000000000..068e94ba29 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLDSAPrivateKey.java @@ -0,0 +1,14 @@ +package org.bouncycastle.jcajce.interfaces; + +import java.security.PrivateKey; + +public interface MLDSAPrivateKey + extends PrivateKey, MLDSAKey +{ + /** + * Return the public key corresponding to this private key. + * + * @return a ML-DSA Public Key + */ + MLDSAPublicKey getPublicKey(); +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLDSAPublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLDSAPublicKey.java new file mode 100644 index 0000000000..877ffbc608 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLDSAPublicKey.java @@ -0,0 +1,8 @@ +package org.bouncycastle.jcajce.interfaces; + +import java.security.PublicKey; + +public interface MLDSAPublicKey + extends PublicKey, MLDSAKey +{ +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLKEMKey.java b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLKEMKey.java new file mode 100644 index 0000000000..5cfbafaba8 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLKEMKey.java @@ -0,0 +1,16 @@ +package org.bouncycastle.jcajce.interfaces; + +import org.bouncycastle.jcajce.spec.MLKEMParameterSpec; + +import java.security.Key; + +public interface MLKEMKey + extends Key +{ + /** + * Return the parameters for this key. + * + * @return a MLKEMParameterSpec + */ + MLKEMParameterSpec getParameterSpec(); +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLKEMPrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLKEMPrivateKey.java new file mode 100644 index 0000000000..96cec19685 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLKEMPrivateKey.java @@ -0,0 +1,14 @@ +package org.bouncycastle.jcajce.interfaces; + +import java.security.PrivateKey; + +public interface MLKEMPrivateKey + extends PrivateKey, MLKEMKey +{ + /** + * Return the public key corresponding to this private key. + * + * @return a ML-KEM Public Key + */ + MLKEMPublicKey getPublicKey(); +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLKEMPublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLKEMPublicKey.java new file mode 100644 index 0000000000..832466c025 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/MLKEMPublicKey.java @@ -0,0 +1,8 @@ +package org.bouncycastle.jcajce.interfaces; + +import java.security.PublicKey; + +public interface MLKEMPublicKey + extends PublicKey, MLKEMKey +{ +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/interfaces/SLHDSAKey.java b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/SLHDSAKey.java new file mode 100644 index 0000000000..aa2da41eaa --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/SLHDSAKey.java @@ -0,0 +1,16 @@ +package org.bouncycastle.jcajce.interfaces; + +import java.security.Key; + +import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec; + +public interface SLHDSAKey + extends Key +{ + /** + * Return the parameters for this key. + * + * @return a SLHDSAParameterSpec + */ + SLHDSAParameterSpec getParameterSpec(); +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/interfaces/SLHDSAPrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/SLHDSAPrivateKey.java new file mode 100644 index 0000000000..9fe8069967 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/SLHDSAPrivateKey.java @@ -0,0 +1,14 @@ +package org.bouncycastle.jcajce.interfaces; + +import java.security.PrivateKey; + +public interface SLHDSAPrivateKey + extends PrivateKey, SLHDSAKey +{ + /** + * Return the public key corresponding to this private key. + * + * @return a SLH-DSA Public Key + */ + SLHDSAPublicKey getPublicKey(); +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/interfaces/SLHDSAPublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/SLHDSAPublicKey.java new file mode 100644 index 0000000000..18ffadb9a1 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/interfaces/SLHDSAPublicKey.java @@ -0,0 +1,8 @@ +package org.bouncycastle.jcajce.interfaces; + +import java.security.PublicKey; + +public interface SLHDSAPublicKey + extends PublicKey, SLHDSAKey +{ +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/COMPOSITE.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/COMPOSITE.java index d89b831616..b77e4a47db 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/COMPOSITE.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/COMPOSITE.java @@ -9,9 +9,9 @@ import java.util.Map; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.jcajce.CompositePrivateKey; import org.bouncycastle.jcajce.CompositePublicKey; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; @@ -84,7 +84,7 @@ public CompositeKeyInfoConverter(ConfigurableProvider provider) public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) throws IOException { - ASN1Sequence keySeq = ASN1Sequence.getInstance(keyInfo.getPrivateKey().getOctets()); + ASN1Sequence keySeq = ASN1Sequence.getInstance(keyInfo.parsePrivateKey()); PrivateKey[] privKeys = new PrivateKey[keySeq.size()]; for (int i = 0; i != keySeq.size(); i++) diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/CompositeSignatures.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/CompositeSignatures.java new file mode 100644 index 0000000000..11c24acf3f --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/CompositeSignatures.java @@ -0,0 +1,52 @@ +package org.bouncycastle.jcajce.provider.asymmetric; + +import java.util.HashMap; +import java.util.Map; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.jcajce.provider.asymmetric.compositesignatures.CompositeSignaturesConstants; +import org.bouncycastle.jcajce.provider.asymmetric.compositesignatures.KeyFactorySpi; +import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; + +/** + * Experimental implementation of composite signatures according to https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13. + */ +public class CompositeSignatures +{ + private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".compositesignatures."; + + private static final Map compositesAttributes = new HashMap(); + + static + { + compositesAttributes.put("SupportedKeyClasses", "org.bouncycastle.jcajce.CompositePublicKey|org.bouncycastle.jcajce.CompositePrivateKey"); + compositesAttributes.put("SupportedKeyFormats", "PKCS#8|X.509"); + } + + public static class Mappings + extends AsymmetricAlgorithmProvider + { + public Mappings() + { + } + + public void configure(ConfigurableProvider provider) + { + for (ASN1ObjectIdentifier oid : CompositeSignaturesConstants.supportedIdentifiers) + { + CompositeSignaturesConstants.CompositeName algName = CompositeSignaturesConstants.ASN1IdentifierAlgorithmNameMap.get(oid); + provider.addAlgorithm("KeyFactory." + algName.getId(), PREFIX + "KeyFactorySpi"); //Key factory is the same for all composite signatures. + provider.addAlgorithm("Alg.Alias.KeyFactory", oid, algName.getId()); + + provider.addAlgorithm("KeyPairGenerator." + algName.getId(), PREFIX + "KeyPairGeneratorSpi$" + algName); + provider.addAlgorithm("Alg.Alias.KeyPairGenerator", oid, algName.getId()); + + provider.addAlgorithm("Signature." + algName.getId(), PREFIX + "SignatureSpi$" + algName); + provider.addAlgorithm("Alg.Alias.Signature", oid, algName.getId()); + + provider.addKeyInfoConverter(oid, new KeyFactorySpi()); + } + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/Dilithium.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/Dilithium.java new file mode 100644 index 0000000000..71f6e49f01 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/Dilithium.java @@ -0,0 +1,40 @@ +package org.bouncycastle.jcajce.provider.asymmetric; + +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; +import org.bouncycastle.pqc.jcajce.provider.dilithium.DilithiumKeyFactorySpi; + +public class Dilithium +{ + private static final String PREFIX = "org.bouncycastle.pqc.jcajce.provider" + ".dilithium."; + + public static class Mappings + extends AsymmetricAlgorithmProvider + { + public Mappings() + { + } + + public void configure(ConfigurableProvider provider) + { + provider.addAlgorithm("KeyFactory.DILITHIUM", PREFIX + "DilithiumKeyFactorySpi"); + + addKeyFactoryAlgorithm(provider, "DILITHIUM2", PREFIX + "DilithiumKeyFactorySpi$Base2", BCObjectIdentifiers.dilithium2, new DilithiumKeyFactorySpi.Base2()); + addKeyFactoryAlgorithm(provider, "DILITHIUM3", PREFIX + "DilithiumKeyFactorySpi$Base3", BCObjectIdentifiers.dilithium3, new DilithiumKeyFactorySpi.Base3()); + addKeyFactoryAlgorithm(provider, "DILITHIUM5", PREFIX + "DilithiumKeyFactorySpi$Base5", BCObjectIdentifiers.dilithium5, new DilithiumKeyFactorySpi.Base5()); + + provider.addAlgorithm("KeyPairGenerator.DILITHIUM", PREFIX + "DilithiumKeyPairGeneratorSpi"); + + addKeyPairGeneratorAlgorithm(provider, "DILITHIUM2", PREFIX + "DilithiumKeyPairGeneratorSpi$Base2", BCObjectIdentifiers.dilithium2); + addKeyPairGeneratorAlgorithm(provider, "DILITHIUM3", PREFIX + "DilithiumKeyPairGeneratorSpi$Base3", BCObjectIdentifiers.dilithium3); + addKeyPairGeneratorAlgorithm(provider, "DILITHIUM5", PREFIX + "DilithiumKeyPairGeneratorSpi$Base5", BCObjectIdentifiers.dilithium5); + + addSignatureAlgorithm(provider, "DILITHIUM", PREFIX + "SignatureSpi$Base", BCObjectIdentifiers.dilithium); + + addSignatureAlgorithm(provider, "DILITHIUM2", PREFIX + "SignatureSpi$Base2", BCObjectIdentifiers.dilithium2); + addSignatureAlgorithm(provider, "DILITHIUM3", PREFIX + "SignatureSpi$Base3", BCObjectIdentifiers.dilithium3); + addSignatureAlgorithm(provider, "DILITHIUM5", PREFIX + "SignatureSpi$Base5", BCObjectIdentifiers.dilithium5); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java index c51a0d4e76..d9e4f8e465 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java @@ -108,8 +108,8 @@ public void configure(ConfigurableProvider provider) registerOid(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC", new KeyFactorySpi.EC()); + registerOid(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC()); registerOid(provider, X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC()); - registerOid(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV()); registerOid(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, "EC", new KeyFactorySpi.EC()); registerOid(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, "EC", new KeyFactorySpi.EC()); @@ -162,14 +162,14 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA384KDFAndSharedInfo", generalEcAttributes); provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA512KDFAndSharedInfo", generalEcAttributes); - registerOid(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC()); + registerOid(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV()); registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "EC"); registerOid(provider, SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV()); - registerOidAlgorithmParameters(provider, SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, "EC"); + registerOidAlgorithmParameters(provider, SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, "EC"); registerOid(provider, SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV()); - registerOidAlgorithmParameters(provider, SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, "EC"); + registerOidAlgorithmParameters(provider, SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, "EC"); registerOid(provider, SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV()); registerOidAlgorithmParameters(provider, SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, "EC"); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ECGOST.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ECGOST.java index 948b341de0..56c298fe86 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ECGOST.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ECGOST.java @@ -1,7 +1,7 @@ package org.bouncycastle.jcajce.provider.asymmetric; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.ecgost.KeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EdEC.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EdEC.java index 8e3b4aef18..06c2bab8df 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EdEC.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EdEC.java @@ -3,7 +3,7 @@ import java.util.HashMap; import java.util.Map; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.edec.KeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; @@ -69,6 +69,9 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("KeyAgreement.X25519UWITHSHA256KDF", PREFIX + "KeyAgreementSpi$X25519UwithSHA256KDF"); provider.addAlgorithm("KeyAgreement.X448UWITHSHA512KDF", PREFIX + "KeyAgreementSpi$X448UwithSHA512KDF"); + provider.addAlgorithm("KeyAgreement.X448withSHA512HKDF", PREFIX + "KeyAgreementSpi$X448withSHA512HKDF"); + provider.addAlgorithm("KeyAgreement.X25519withSHA256HKDF", PREFIX + "KeyAgreementSpi$X25519withSHA256HKDF"); + provider.addAlgorithm("KeyPairGenerator.XDH", PREFIX + "KeyPairGeneratorSpi$XDH"); provider.addAlgorithm("KeyPairGenerator.X448", PREFIX + "KeyPairGeneratorSpi$X448"); provider.addAlgorithm("KeyPairGenerator.X25519", PREFIX + "KeyPairGeneratorSpi$X25519"); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ElGamal.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ElGamal.java index 279e95129e..cac64a80ca 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ElGamal.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ElGamal.java @@ -1,6 +1,6 @@ package org.bouncycastle.jcajce.provider.asymmetric; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.elgamal.KeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/Falcon.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/Falcon.java new file mode 100644 index 0000000000..0559c1c6a6 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/Falcon.java @@ -0,0 +1,38 @@ +package org.bouncycastle.jcajce.provider.asymmetric; + +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; +import org.bouncycastle.pqc.jcajce.provider.falcon.FalconKeyFactorySpi; + +public class Falcon +{ + private static final String PREFIX = "org.bouncycastle.pqc.jcajce.provider" + ".falcon."; + + public static class Mappings + extends AsymmetricAlgorithmProvider + { + public Mappings() + { + } + + public void configure(ConfigurableProvider provider) + { + provider.addAlgorithm("KeyFactory.FALCON", PREFIX + "FalconKeyFactorySpi"); + + addKeyFactoryAlgorithm(provider, "FALCON-512", PREFIX + "FalconKeyFactorySpi$Falcon512", BCObjectIdentifiers.falcon_512, new FalconKeyFactorySpi.Falcon512()); + addKeyFactoryAlgorithm(provider, "FALCON-1024", PREFIX + "FalconKeyFactorySpi$Falcon1024", BCObjectIdentifiers.falcon_1024, new FalconKeyFactorySpi.Falcon1024()); + + provider.addAlgorithm("KeyPairGenerator.FALCON", PREFIX + "FalconKeyPairGeneratorSpi"); + + addKeyPairGeneratorAlgorithm(provider, "FALCON-512", PREFIX + "FalconKeyPairGeneratorSpi$Falcon512", BCObjectIdentifiers.falcon_512); + addKeyPairGeneratorAlgorithm(provider, "FALCON-1024", PREFIX + "FalconKeyPairGeneratorSpi$Falcon1024", BCObjectIdentifiers.falcon_1024); + + addSignatureAlgorithm(provider, "FALCON", PREFIX + "SignatureSpi$Base", BCObjectIdentifiers.falcon); + + addSignatureAlgorithm(provider, "FALCON-512", PREFIX + "SignatureSpi$Falcon512", BCObjectIdentifiers.falcon_512); + addSignatureAlgorithm(provider, "FALCON-1024", PREFIX + "SignatureSpi$Falcon1024", BCObjectIdentifiers.falcon_1024); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/MLDSA.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/MLDSA.java new file mode 100644 index 0000000000..2c6f9c3cc6 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/MLDSA.java @@ -0,0 +1,65 @@ +package org.bouncycastle.jcajce.provider.asymmetric; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.jcajce.provider.asymmetric.mldsa.MLDSAKeyFactorySpi; +import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; + +public class MLDSA +{ + private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".mldsa."; + + public static class Mappings + extends AsymmetricAlgorithmProvider + { + public Mappings() + { + } + + public void configure(ConfigurableProvider provider) + { + provider.addAlgorithm("KeyFactory.ML-DSA", PREFIX + "MLDSAKeyFactorySpi$Pure"); + provider.addAlgorithm("KeyPairGenerator.ML-DSA", PREFIX + "MLDSAKeyPairGeneratorSpi$Pure"); + provider.addAlgorithm("KeyFactory.HASH-ML-DSA", PREFIX + "MLDSAKeyFactorySpi$Hash"); + provider.addAlgorithm("KeyPairGenerator.HASH-ML-DSA", PREFIX + "MLDSAKeyPairGeneratorSpi$Hash"); + + addKeyFactoryAlgorithm(provider, "ML-DSA-44", PREFIX + "MLDSAKeyFactorySpi$MLDSA44", NISTObjectIdentifiers.id_ml_dsa_44, new MLDSAKeyFactorySpi.MLDSA44()); + addKeyFactoryAlgorithm(provider, "ML-DSA-65", PREFIX + "MLDSAKeyFactorySpi$MLDSA65", NISTObjectIdentifiers.id_ml_dsa_65, new MLDSAKeyFactorySpi.MLDSA65()); + addKeyFactoryAlgorithm(provider, "ML-DSA-87", PREFIX + "MLDSAKeyFactorySpi$MLDSA87", NISTObjectIdentifiers.id_ml_dsa_87, new MLDSAKeyFactorySpi.MLDSA87()); + addKeyFactoryAlgorithm(provider, "ML-DSA-44-WITH-SHA512", PREFIX + "MLDSAKeyFactorySpi$HashMLDSA44", NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512, new MLDSAKeyFactorySpi.HashMLDSA44()); + addKeyFactoryAlgorithm(provider, "ML-DSA-65-WITH-SHA512", PREFIX + "MLDSAKeyFactorySpi$HashMLDSA65", NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512, new MLDSAKeyFactorySpi.HashMLDSA65()); + addKeyFactoryAlgorithm(provider, "ML-DSA-87-WITH-SHA512", PREFIX + "MLDSAKeyFactorySpi$HashMLDSA87", NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512, new MLDSAKeyFactorySpi.HashMLDSA87()); + + addKeyPairGeneratorAlgorithm(provider, "ML-DSA-44", PREFIX + "MLDSAKeyPairGeneratorSpi$MLDSA44", NISTObjectIdentifiers.id_ml_dsa_44); + addKeyPairGeneratorAlgorithm(provider, "ML-DSA-65", PREFIX + "MLDSAKeyPairGeneratorSpi$MLDSA65", NISTObjectIdentifiers.id_ml_dsa_65); + addKeyPairGeneratorAlgorithm(provider, "ML-DSA-87", PREFIX + "MLDSAKeyPairGeneratorSpi$MLDSA87", NISTObjectIdentifiers.id_ml_dsa_87); + addKeyPairGeneratorAlgorithm(provider, "ML-DSA-44-WITH-SHA512", PREFIX + "MLDSAKeyPairGeneratorSpi$MLDSA44withSHA512", NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512); + addKeyPairGeneratorAlgorithm(provider, "ML-DSA-65-WITH-SHA512", PREFIX + "MLDSAKeyPairGeneratorSpi$MLDSA65withSHA512", NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512); + addKeyPairGeneratorAlgorithm(provider, "ML-DSA-87-WITH-SHA512", PREFIX + "MLDSAKeyPairGeneratorSpi$MLDSA87withSHA512", NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512); + + addSignatureAlgorithm(provider, "ML-DSA", PREFIX + "SignatureSpi$MLDSA", (ASN1ObjectIdentifier)null); + addSignatureAlgorithm(provider, "ML-DSA-44", PREFIX + "SignatureSpi$MLDSA44", NISTObjectIdentifiers.id_ml_dsa_44); + addSignatureAlgorithm(provider, "ML-DSA-65", PREFIX + "SignatureSpi$MLDSA65", NISTObjectIdentifiers.id_ml_dsa_65); + addSignatureAlgorithm(provider, "ML-DSA-87", PREFIX + "SignatureSpi$MLDSA87", NISTObjectIdentifiers.id_ml_dsa_87); + provider.addAlgorithm("Alg.Alias.Signature.MLDSA", "ML-DSA"); + + addSignatureAlgorithm(provider, "HASH-ML-DSA", PREFIX + "HashSignatureSpi$MLDSA", (ASN1ObjectIdentifier)null); + addSignatureAlgorithm(provider, "ML-DSA-44-WITH-SHA512", PREFIX + "HashSignatureSpi$MLDSA44", NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512); + addSignatureAlgorithm(provider, "ML-DSA-65-WITH-SHA512", PREFIX + "HashSignatureSpi$MLDSA65", NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512); + addSignatureAlgorithm(provider, "ML-DSA-87-WITH-SHA512", PREFIX + "HashSignatureSpi$MLDSA87", NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512); + + provider.addAlgorithm("Alg.Alias.Signature.SHA512WITHMLDSA", "HASH-ML-DSA"); + + AsymmetricKeyInfoConverter keyFact = new MLDSAKeyFactorySpi.Hash(); + + provider.addKeyInfoConverter(NISTObjectIdentifiers.id_ml_dsa_44, keyFact); + provider.addKeyInfoConverter(NISTObjectIdentifiers.id_ml_dsa_65, keyFact); + provider.addKeyInfoConverter(NISTObjectIdentifiers.id_ml_dsa_87, keyFact); + provider.addKeyInfoConverter(NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512, keyFact); + provider.addKeyInfoConverter(NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512, keyFact); + provider.addKeyInfoConverter(NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512, keyFact); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/MLKEM.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/MLKEM.java new file mode 100644 index 0000000000..e898c577e2 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/MLKEM.java @@ -0,0 +1,56 @@ +package org.bouncycastle.jcajce.provider.asymmetric; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.jcajce.provider.asymmetric.mlkem.MLKEMKeyFactorySpi; +import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; + +public class MLKEM +{ + private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".mlkem."; + + public static class Mappings + extends AsymmetricAlgorithmProvider + { + public Mappings() + { + } + + public void configure(ConfigurableProvider provider) + { + provider.addAlgorithm("KeyFactory.ML-KEM", PREFIX + "MLKEMKeyFactorySpi"); + + addKeyFactoryAlgorithm(provider, "ML-KEM-512", PREFIX + "MLKEMKeyFactorySpi$MLKEM512", NISTObjectIdentifiers.id_alg_ml_kem_512, new MLKEMKeyFactorySpi.MLKEM512()); + addKeyFactoryAlgorithm(provider, "ML-KEM-768", PREFIX + "MLKEMKeyFactorySpi$MLKEM768", NISTObjectIdentifiers.id_alg_ml_kem_768, new MLKEMKeyFactorySpi.MLKEM768()); + addKeyFactoryAlgorithm(provider, "ML-KEM-1024", PREFIX + "MLKEMKeyFactorySpi$MLKEM1024", NISTObjectIdentifiers.id_alg_ml_kem_1024, new MLKEMKeyFactorySpi.MLKEM1024()); + + + provider.addAlgorithm("KeyPairGenerator.ML-KEM", PREFIX + "MLKEMKeyPairGeneratorSpi"); + + addKeyPairGeneratorAlgorithm(provider, "ML-KEM-512", PREFIX + "MLKEMKeyPairGeneratorSpi$MLKEM512", NISTObjectIdentifiers.id_alg_ml_kem_512); + addKeyPairGeneratorAlgorithm(provider, "ML-KEM-768", PREFIX + "MLKEMKeyPairGeneratorSpi$MLKEM768", NISTObjectIdentifiers.id_alg_ml_kem_768); + addKeyPairGeneratorAlgorithm(provider, "ML-KEM-1024", PREFIX + "MLKEMKeyPairGeneratorSpi$MLKEM1024", NISTObjectIdentifiers.id_alg_ml_kem_1024); + + provider.addAlgorithm("KeyGenerator.ML-KEM", PREFIX + "MLKEMKeyGeneratorSpi"); + + addKeyGeneratorAlgorithm(provider, "ML-KEM-512", PREFIX + "MLKEMKeyGeneratorSpi$MLKEM512", NISTObjectIdentifiers.id_alg_ml_kem_512); + addKeyGeneratorAlgorithm(provider, "ML-KEM-768", PREFIX + "MLKEMKeyGeneratorSpi$MLKEM768", NISTObjectIdentifiers.id_alg_ml_kem_768); + addKeyGeneratorAlgorithm(provider, "ML-KEM-1024", PREFIX + "MLKEMKeyGeneratorSpi$MLKEM1024", NISTObjectIdentifiers.id_alg_ml_kem_1024); + + AsymmetricKeyInfoConverter keyFact = new MLKEMKeyFactorySpi(); + + provider.addAlgorithm("Cipher.ML-KEM", PREFIX + "MLKEMCipherSpi$Base"); + provider.addAlgorithm("Alg.Alias.Cipher." + (ASN1ObjectIdentifier) null, "ML-KEM"); + + addCipherAlgorithm(provider, "ML-KEM-512", PREFIX + "MLKEMCipherSpi$MLKEM512", NISTObjectIdentifiers.id_alg_ml_kem_512); + addCipherAlgorithm(provider, "ML-KEM-768", PREFIX + "MLKEMCipherSpi$MLKEM768", NISTObjectIdentifiers.id_alg_ml_kem_768); + addCipherAlgorithm(provider, "ML-KEM-1024", PREFIX + "MLKEMCipherSpi$MLKEM1024", NISTObjectIdentifiers.id_alg_ml_kem_1024); + + provider.addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_512, keyFact); + provider.addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_768, keyFact); + provider.addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_1024, keyFact); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/NTRU.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/NTRU.java new file mode 100644 index 0000000000..22400dcc70 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/NTRU.java @@ -0,0 +1,54 @@ +package org.bouncycastle.jcajce.provider.asymmetric; + +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; +import org.bouncycastle.pqc.jcajce.provider.ntru.NTRUKeyFactorySpi; + +public class NTRU +{ + private static final String PREFIX = "org.bouncycastle.pqc.jcajce.provider" + ".ntru."; + + public static class Mappings + extends AsymmetricAlgorithmProvider + { + public Mappings() + { + } + + public void configure(ConfigurableProvider provider) + { + provider.addAlgorithm("KeyFactory.NTRU", PREFIX + "NTRUKeyFactorySpi"); + provider.addAlgorithm("KeyPairGenerator.NTRU", PREFIX + "NTRUKeyPairGeneratorSpi"); + + provider.addAlgorithm("KeyGenerator.NTRU", PREFIX + "NTRUKeyGeneratorSpi"); + provider.addAlgorithm("Alg.Alias.KeyGenerator." + BCObjectIdentifiers.pqc_kem_ntru, "NTRU"); + provider.addAlgorithm("Alg.Alias.KeyGenerator." + BCObjectIdentifiers.ntruhps2048509, "NTRU"); + provider.addAlgorithm("Alg.Alias.KeyGenerator." + BCObjectIdentifiers.ntruhps2048677, "NTRU"); + provider.addAlgorithm("Alg.Alias.KeyGenerator." + BCObjectIdentifiers.ntruhps4096821, "NTRU"); + provider.addAlgorithm("Alg.Alias.KeyGenerator." + BCObjectIdentifiers.ntruhps40961229, "NTRU"); + provider.addAlgorithm("Alg.Alias.KeyGenerator." + BCObjectIdentifiers.ntruhrss701, "NTRU"); + provider.addAlgorithm("Alg.Alias.KeyGenerator." + BCObjectIdentifiers.ntruhrss1373, "NTRU"); + + AsymmetricKeyInfoConverter keyFact = new NTRUKeyFactorySpi(); + + provider.addAlgorithm("Cipher.NTRU", PREFIX + "NTRUCipherSpi$Base"); + provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_ntru, "NTRU"); + provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.ntruhps2048509, "NTRU"); + provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.ntruhps2048677, "NTRU"); + provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.ntruhps4096821, "NTRU"); + provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.ntruhps40961229, "NTRU"); + provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.ntruhrss701, "NTRU"); + provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.ntruhrss1373, "NTRU"); + + registerOid(provider, BCObjectIdentifiers.pqc_kem_ntru, "NTRU", keyFact); + registerOid(provider, BCObjectIdentifiers.ntruhps2048509, "NTRU", keyFact); + registerOid(provider, BCObjectIdentifiers.ntruhps2048677, "NTRU", keyFact); + registerOid(provider, BCObjectIdentifiers.ntruhps4096821, "NTRU", keyFact); + registerOid(provider, BCObjectIdentifiers.ntruhps40961229, "NTRU", keyFact); + registerOid(provider, BCObjectIdentifiers.ntruhrss701, "NTRU", keyFact); + registerOid(provider, BCObjectIdentifiers.ntruhrss1373, "NTRU", keyFact); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java index 60e65294ea..4bafaa48a9 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java @@ -5,11 +5,11 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.internal.asn1.cms.CMSObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/SLHDSA.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/SLHDSA.java new file mode 100644 index 0000000000..a0622bf121 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/SLHDSA.java @@ -0,0 +1,126 @@ +package org.bouncycastle.jcajce.provider.asymmetric; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.jcajce.provider.asymmetric.slhdsa.SLHDSAKeyFactorySpi; +import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; + +public class SLHDSA +{ + private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".slhdsa."; + + public static class Mappings + extends AsymmetricAlgorithmProvider + { + public Mappings() + { + } + + public void configure(ConfigurableProvider provider) + { + provider.addAlgorithm("KeyFactory.SLH-DSA", PREFIX + "SLHDSAKeyFactorySpi$Pure"); + provider.addAlgorithm("KeyPairGenerator.SLH-DSA", PREFIX + "SLHDSAKeyPairGeneratorSpi$Pure"); + provider.addAlgorithm("KeyFactory.HASH-SLH-DSA", PREFIX + "SLHDSAKeyFactorySpi$Hash"); + provider.addAlgorithm("KeyPairGenerator.HASH-SLH-DSA", PREFIX + "SLHDSAKeyPairGeneratorSpi$Hash"); + + AsymmetricKeyInfoConverter keyFact = new SLHDSAKeyFactorySpi.Hash(); + + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHA2-128S", PREFIX + "SLHDSAKeyFactorySpi$Sha2_128s", NISTObjectIdentifiers.id_slh_dsa_sha2_128s, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHA2-128F", PREFIX + "SLHDSAKeyFactorySpi$Sha2_128f", NISTObjectIdentifiers.id_slh_dsa_sha2_128f, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHA2-192S", PREFIX + "SLHDSAKeyFactorySpi$Sha2_192s", NISTObjectIdentifiers.id_slh_dsa_sha2_192s, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHA2-192F", PREFIX + "SLHDSAKeyFactorySpi$Sha2_192f", NISTObjectIdentifiers.id_slh_dsa_sha2_192f, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHA2-256S", PREFIX + "SLHDSAKeyFactorySpi$Sha2_256s", NISTObjectIdentifiers.id_slh_dsa_sha2_256s, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHA2-256F", PREFIX + "SLHDSAKeyFactorySpi$Sha2_256f", NISTObjectIdentifiers.id_slh_dsa_sha2_256f, keyFact); + + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHAKE-128S", PREFIX + "SLHDSAKeyFactorySpi$Shake_128s", NISTObjectIdentifiers.id_slh_dsa_shake_128s, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHAKE-128F", PREFIX + "SLHDSAKeyFactorySpi$Shake_128f", NISTObjectIdentifiers.id_slh_dsa_shake_128f, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHAKE-192S", PREFIX + "SLHDSAKeyFactorySpi$Shake_192s", NISTObjectIdentifiers.id_slh_dsa_shake_192s, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHAKE-192F", PREFIX + "SLHDSAKeyFactorySpi$Shake_192f", NISTObjectIdentifiers.id_slh_dsa_shake_192f, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHAKE-256S", PREFIX + "SLHDSAKeyFactorySpi$Shake_256s", NISTObjectIdentifiers.id_slh_dsa_shake_256s, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHAKE-256F", PREFIX + "SLHDSAKeyFactorySpi$Shake_256f", NISTObjectIdentifiers.id_slh_dsa_shake_256f, keyFact); + + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHA2-128S-WITH-SHA256", PREFIX + "SLHDSAKeyFactorySpi$HashSha2_128s", NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHA2-128F-WITH-SHA256", PREFIX + "SLHDSAKeyFactorySpi$HashSha2_128f", NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHA2-192S-WITH-SHA512", PREFIX + "SLHDSAKeyFactorySpi$HashSha2_192s", NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHA2-192F-WITH-SHA512", PREFIX + "SLHDSAKeyFactorySpi$HashSha2_192f", NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHA2-256S-WITH-SHA512", PREFIX + "SLHDSAKeyFactorySpi$HashSha2_256s", NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHA2-256F-WITH-SHA512", PREFIX + "SLHDSAKeyFactorySpi$HashSha2_256f", NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512, keyFact); + + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHAKE-128S-WITH-SHAKE128", PREFIX + "SLHDSAKeyFactorySpi$HashShake_128s", NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHAKE-128F-WITH-SHAKE128", PREFIX + "SLHDSAKeyFactorySpi$HashShake_128f", NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHAKE-192S-WITH-SHAKE256", PREFIX + "SLHDSAKeyFactorySpi$HashShake_192s", NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHAKE-192F-WITH-SHAKE256", PREFIX + "SLHDSAKeyFactorySpi$HashShake_192f", NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHAKE-256S-WITH-SHAKE256", PREFIX + "SLHDSAKeyFactorySpi$HashShake_256s", NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256, keyFact); + addKeyFactoryAlgorithm(provider, "SLH-DSA-SHAKE-256F-WITH-SHAKE256", PREFIX + "SLHDSAKeyFactorySpi$HashShake_256f", NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256, keyFact); + + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHA2-128S", PREFIX + "SLHDSAKeyPairGeneratorSpi$Sha2_128s", NISTObjectIdentifiers.id_slh_dsa_sha2_128s); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHA2-128F", PREFIX + "SLHDSAKeyPairGeneratorSpi$Sha2_128f", NISTObjectIdentifiers.id_slh_dsa_sha2_128f); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHA2-192S", PREFIX + "SLHDSAKeyPairGeneratorSpi$Sha2_192s", NISTObjectIdentifiers.id_slh_dsa_sha2_192s); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHA2-192F", PREFIX + "SLHDSAKeyPairGeneratorSpi$Sha2_192f", NISTObjectIdentifiers.id_slh_dsa_sha2_192f); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHA2-256S", PREFIX + "SLHDSAKeyPairGeneratorSpi$Sha2_256s", NISTObjectIdentifiers.id_slh_dsa_sha2_256s); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHA2-256F", PREFIX + "SLHDSAKeyPairGeneratorSpi$Sha2_256f", NISTObjectIdentifiers.id_slh_dsa_sha2_256f); + + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHAKE-128S", PREFIX + "SLHDSAKeyPairGeneratorSpi$Shake_128s", NISTObjectIdentifiers.id_slh_dsa_shake_128s); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHAKE-128F", PREFIX + "SLHDSAKeyPairGeneratorSpi$Shake_128f", NISTObjectIdentifiers.id_slh_dsa_shake_128f); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHAKE-192S", PREFIX + "SLHDSAKeyPairGeneratorSpi$Shake_192s", NISTObjectIdentifiers.id_slh_dsa_shake_192s); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHAKE-192F", PREFIX + "SLHDSAKeyPairGeneratorSpi$Shake_192f", NISTObjectIdentifiers.id_slh_dsa_shake_192f); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHAKE-256S", PREFIX + "SLHDSAKeyPairGeneratorSpi$Shake_256s", NISTObjectIdentifiers.id_slh_dsa_shake_256s); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHAKE-256F", PREFIX + "SLHDSAKeyPairGeneratorSpi$Shake_256f", NISTObjectIdentifiers.id_slh_dsa_shake_256f); + + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHA2-128S-WITH-SHA256", PREFIX + "SLHDSAKeyPairGeneratorSpi$HashSha2_128s", NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHA2-128F-WITH-SHA256", PREFIX + "SLHDSAKeyPairGeneratorSpi$HashSha2_128f", NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHA2-192S-WITH-SHA512", PREFIX + "SLHDSAKeyPairGeneratorSpi$HashSha2_192s", NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHA2-192F-WITH-SHA512", PREFIX + "SLHDSAKeyPairGeneratorSpi$HashSha2_192f", NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHA2-256S-WITH-SHA512", PREFIX + "SLHDSAKeyPairGeneratorSpi$HashSha2_256s", NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHA2-256F-WITH-SHA512", PREFIX + "SLHDSAKeyPairGeneratorSpi$HashSha2_256f", NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512); + + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHAKE-128S-WITH-SHAKE128", PREFIX + "SLHDSAKeyPairGeneratorSpi$HashShake_128s", NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHAKE-128F-WITH-SHAKE128", PREFIX + "SLHDSAKeyPairGeneratorSpi$HashShake_128f", NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHAKE-192S-WITH-SHAKE256", PREFIX + "SLHDSAKeyPairGeneratorSpi$HashShake_192s", NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHAKE-192F-WITH-SHAKE256", PREFIX + "SLHDSAKeyPairGeneratorSpi$HashShake_192f", NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHAKE-256S-WITH-SHAKE256", PREFIX + "SLHDSAKeyPairGeneratorSpi$HashShake_256s", NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256); + addKeyPairGeneratorAlgorithm(provider, "SLH-DSA-SHAKE-256F-WITH-SHAKE256", PREFIX + "SLHDSAKeyPairGeneratorSpi$HashShake_256f", NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256); + + addSignatureAlgorithm(provider, "SLH-DSA", PREFIX + "SignatureSpi$Direct", (ASN1ObjectIdentifier)null); + provider.addAlgorithm("Alg.Alias.Signature.SLHDSA", "SLH-DSA"); + addSignatureAlgorithm(provider, "HASH-SLH-DSA", PREFIX + "HashSignatureSpi$Direct", (ASN1ObjectIdentifier)null); + provider.addAlgorithm("Alg.Alias.Signature.HASHWITHSLHDSA", "HASH-SLH-DSA"); + + ASN1ObjectIdentifier[] nistOids = new ASN1ObjectIdentifier[] + { + NISTObjectIdentifiers.id_slh_dsa_sha2_128s, + NISTObjectIdentifiers.id_slh_dsa_sha2_128f, + NISTObjectIdentifiers.id_slh_dsa_shake_128s, + NISTObjectIdentifiers.id_slh_dsa_shake_128f, + NISTObjectIdentifiers.id_slh_dsa_sha2_192s, + NISTObjectIdentifiers.id_slh_dsa_sha2_192f, + NISTObjectIdentifiers.id_slh_dsa_shake_192s, + NISTObjectIdentifiers.id_slh_dsa_shake_192f, + NISTObjectIdentifiers.id_slh_dsa_sha2_256s, + NISTObjectIdentifiers.id_slh_dsa_sha2_256f, + NISTObjectIdentifiers.id_slh_dsa_shake_256s, + NISTObjectIdentifiers.id_slh_dsa_shake_256f, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256 + }; + + for (int i = 0; i != nistOids.length; i++) + { + provider.addAlgorithm("Alg.Alias.Signature." + nistOids[i], "SLH-DSA"); + provider.addAlgorithm("Alg.Alias.Signature.OID." + nistOids[i], "SLH-DSA"); + } + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/SPHINCSPlus.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/SPHINCSPlus.java index 52a24cbc64..2f2c071bbd 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/SPHINCSPlus.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/SPHINCSPlus.java @@ -1,5 +1,6 @@ package org.bouncycastle.jcajce.provider.asymmetric; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; @@ -24,70 +25,107 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("Alg.Alias.KeyFactory.SPHINCS+", "SPHINCSPLUS"); provider.addAlgorithm("Alg.Alias.KeyPairGenerator.SPHINCS+", "SPHINCSPLUS"); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHA2-128S", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Sha2_128s", BCObjectIdentifiers.sphincsPlus_sha2_128s); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHA2-128F", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Sha2_128f", BCObjectIdentifiers.sphincsPlus_sha2_128f); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHA2-192S", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Sha2_192s", BCObjectIdentifiers.sphincsPlus_sha2_192s); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHA2-192F", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Sha2_192f", BCObjectIdentifiers.sphincsPlus_sha2_192f); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHA2-256S", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Sha2_256s", BCObjectIdentifiers.sphincsPlus_sha2_256s); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHA2-256F", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Sha2_256f", BCObjectIdentifiers.sphincsPlus_sha2_256f); + + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHAKE-128S", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Shake_128s", BCObjectIdentifiers.sphincsPlus_shake_128s); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHAKE-128F", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Shake_128f", BCObjectIdentifiers.sphincsPlus_shake_128f); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHAKE-192S", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Shake_192s", BCObjectIdentifiers.sphincsPlus_shake_192s); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHAKE-192F", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Shake_192f", BCObjectIdentifiers.sphincsPlus_shake_192f); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHAKE-256S", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Shake_256s", BCObjectIdentifiers.sphincsPlus_shake_256s); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHAKE-256F", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Shake_256f", BCObjectIdentifiers.sphincsPlus_shake_256f); + addSignatureAlgorithm(provider, "SPHINCSPLUS", PREFIX + "SignatureSpi$Direct", BCObjectIdentifiers.sphincsPlus); // provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus.getId(), "SPHINCSPLUS"); // provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_sha2_128s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_sha2_128f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_shake_128s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_shake_128f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_haraka_128s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_haraka_128f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_sha2_192s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_sha2_192f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_shake_192s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_shake_192f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_haraka_192s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_haraka_192f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_sha2_256s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_sha2_256f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_shake_256s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_shake_256f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_haraka_256s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus_haraka_256f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_sha2_128s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_sha2_128f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_shake_128s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_shake_128f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_haraka_128s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_haraka_128f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_sha2_192s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_sha2_192f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_shake_192s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_shake_192f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_haraka_192s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_haraka_192f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_sha2_256s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_sha2_256f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_shake_256s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_shake_256f_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_haraka_256s_r3.getId(), "SPHINCSPLUS"); - provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus_haraka_256f_r3.getId(), "SPHINCSPLUS"); + // add the full oid set, all 36. + for (int i = 1; i <= 36; i++) + { + provider.addAlgorithm("Alg.Alias.Signature." + BCObjectIdentifiers.sphincsPlus + "." + i, "SPHINCSPLUS"); + provider.addAlgorithm("Alg.Alias.Signature.OID." + BCObjectIdentifiers.sphincsPlus + "." + i, "SPHINCSPLUS"); + } + + ASN1ObjectIdentifier[] libOQSOids = new ASN1ObjectIdentifier[] + { + BCObjectIdentifiers.sphincsPlus_sha2_128s, + BCObjectIdentifiers.sphincsPlus_sha2_128f, + BCObjectIdentifiers.sphincsPlus_shake_128s, + BCObjectIdentifiers.sphincsPlus_shake_128f, + BCObjectIdentifiers.sphincsPlus_sha2_192s, + BCObjectIdentifiers.sphincsPlus_sha2_192f, + BCObjectIdentifiers.sphincsPlus_shake_192s, + BCObjectIdentifiers.sphincsPlus_shake_192f, + BCObjectIdentifiers.sphincsPlus_sha2_256s, + BCObjectIdentifiers.sphincsPlus_sha2_256f, + BCObjectIdentifiers.sphincsPlus_shake_256s, + BCObjectIdentifiers.sphincsPlus_shake_256f + }; + + for (int i = 0; i != libOQSOids.length; i++) + { + provider.addAlgorithm("Alg.Alias.Signature." + libOQSOids[i], "SPHINCSPLUS"); + provider.addAlgorithm("Alg.Alias.Signature.OID." + libOQSOids[i], "SPHINCSPLUS"); + } provider.addAlgorithm("Alg.Alias.Signature.SPHINCS+", "SPHINCSPLUS"); AsymmetricKeyInfoConverter keyFact = new SPHINCSPlusKeyFactorySpi(); + + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_128s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_128f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_192s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_192f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple, "SPHINCSPLUS", keyFact); -// registerOid(provider, BCObjectIdentifiers.sphincsPlus, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_128s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_128f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_192s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_192f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128s, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128f, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192s, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192f, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256s, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256f, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128s, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128f, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192s, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192f, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256s, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256f, "SPHINCSPLUS", keyFact); + registerOidAlgorithmParameters(provider, BCObjectIdentifiers.sphincsPlus, "SPHINCSPLUS"); } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/CompositeSignaturesConstants.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/CompositeSignaturesConstants.java new file mode 100644 index 0000000000..e4b1c94b02 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/CompositeSignaturesConstants.java @@ -0,0 +1,132 @@ +package org.bouncycastle.jcajce.provider.asymmetric.compositesignatures; + +import java.util.HashMap; +import java.util.Map.Entry; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; + + +/** + * Helper class containing constants/mappings for composite signatures. + */ +public abstract class CompositeSignaturesConstants +{ + + /** + * An array of supported identifiers of composite signature schemes. + */ + public static final ASN1ObjectIdentifier[] supportedIdentifiers = { + MiscObjectIdentifiers.id_MLDSA44_RSA2048_PSS_SHA256, + MiscObjectIdentifiers.id_MLDSA44_RSA2048_PKCS15_SHA256, + MiscObjectIdentifiers.id_MLDSA44_Ed25519_SHA512, + MiscObjectIdentifiers.id_MLDSA44_ECDSA_P256_SHA256, + MiscObjectIdentifiers.id_MLDSA44_ECDSA_brainpoolP256r1_SHA256, + MiscObjectIdentifiers.id_MLDSA65_RSA3072_PSS_SHA512, + MiscObjectIdentifiers.id_MLDSA65_RSA3072_PKCS15_SHA512, + MiscObjectIdentifiers.id_MLDSA65_ECDSA_P256_SHA512, + MiscObjectIdentifiers.id_MLDSA65_ECDSA_brainpoolP256r1_SHA512, + MiscObjectIdentifiers.id_MLDSA65_Ed25519_SHA512, + MiscObjectIdentifiers.id_MLDSA87_ECDSA_P384_SHA512, + MiscObjectIdentifiers.id_MLDSA87_ECDSA_brainpoolP384r1_SHA512, + MiscObjectIdentifiers.id_MLDSA87_Ed448_SHA512, + MiscObjectIdentifiers.id_Falcon512_ECDSA_P256_SHA256, + MiscObjectIdentifiers.id_Falcon512_ECDSA_brainpoolP256r1_SHA256, + MiscObjectIdentifiers.id_Falcon512_Ed25519_SHA512, + }; + + /** + * Enum of supported composited signature schemes. Each one corresponds to a value from supportedIdentifiers. + */ + public enum CompositeName + { + MLDSA44_RSA2048_PSS_SHA256("MLDSA44-RSA2048-PSS-SHA256"), + MLDSA44_RSA2048_PKCS15_SHA256("MLDSA44-RSA2048-PKCS15-SHA256"), + MLDSA44_Ed25519_SHA512("MLDSA44-Ed25519-SHA512"), + MLDSA44_ECDSA_P256_SHA256("MLDSA44-ECDSA-P256-SHA256"), + MLDSA44_ECDSA_brainpoolP256r1_SHA256("MLDSA44-ECDSA-brainpoolP256r1-SHA256"), + MLDSA65_RSA3072_PSS_SHA512("MLDSA65-RSA3072-PSS-SHA512"), + MLDSA65_RSA3072_PKCS15_SHA512("MLDSA65-RSA3072-PKCS15-SHA512"), + MLDSA65_ECDSA_brainpoolP256r1_SHA512("MLDSA65-ECDSA-brainpoolP256r1-SHA512"), + MLDSA65_ECDSA_P256_SHA512("MLDSA65-ECDSA-P256-SHA512"), + MLDSA65_Ed25519_SHA512("MLDSA65-Ed25519-SHA512"), + MLDSA87_ECDSA_P384_SHA512("MLDSA87-ECDSA-P384-SHA512"), + MLDSA87_ECDSA_brainpoolP384r1_SHA512("MLDSA87-ECDSA-brainpoolP384r1-SHA512"), + MLDSA87_Ed448_SHA512("MLDSA87-Ed448-SHA512"), + Falcon512_ECDSA_P256_SHA256("Falcon512-ECDSA-P256-SHA256"), + Falcon512_ECDSA_brainpoolP256r1_SHA256("Falcon512-ECDSA-brainpoolP256r1-SHA256"), + Falcon512_Ed25519_SHA512("Falcon512-Ed25519-SHA512"); + + private final String id; + + private CompositeName(String id) + { + this.id = id; + } + + public String getId() + { + return id; + } + } + + /** + * Map from CompositeName enum to ASN1 identifier. + */ + public static final HashMap compositeNameASN1IdentifierMap; + + static + { + compositeNameASN1IdentifierMap = new HashMap(); + compositeNameASN1IdentifierMap.put(CompositeName.MLDSA44_RSA2048_PSS_SHA256, MiscObjectIdentifiers.id_MLDSA44_RSA2048_PSS_SHA256); + compositeNameASN1IdentifierMap.put(CompositeName.MLDSA44_RSA2048_PKCS15_SHA256, MiscObjectIdentifiers.id_MLDSA44_RSA2048_PKCS15_SHA256); + compositeNameASN1IdentifierMap.put(CompositeName.MLDSA44_ECDSA_P256_SHA256, MiscObjectIdentifiers.id_MLDSA44_ECDSA_P256_SHA256); + compositeNameASN1IdentifierMap.put(CompositeName.MLDSA44_ECDSA_brainpoolP256r1_SHA256, MiscObjectIdentifiers.id_MLDSA44_ECDSA_brainpoolP256r1_SHA256); + compositeNameASN1IdentifierMap.put(CompositeName.MLDSA44_Ed25519_SHA512, MiscObjectIdentifiers.id_MLDSA44_Ed25519_SHA512); + compositeNameASN1IdentifierMap.put(CompositeName.MLDSA65_RSA3072_PSS_SHA512, MiscObjectIdentifiers.id_MLDSA65_RSA3072_PSS_SHA512); + compositeNameASN1IdentifierMap.put(CompositeName.MLDSA65_RSA3072_PKCS15_SHA512, MiscObjectIdentifiers.id_MLDSA65_RSA3072_PKCS15_SHA512); + compositeNameASN1IdentifierMap.put(CompositeName.MLDSA65_ECDSA_P256_SHA512, MiscObjectIdentifiers.id_MLDSA65_ECDSA_P256_SHA512); + compositeNameASN1IdentifierMap.put(CompositeName.MLDSA65_ECDSA_brainpoolP256r1_SHA512, MiscObjectIdentifiers.id_MLDSA65_ECDSA_brainpoolP256r1_SHA512); + compositeNameASN1IdentifierMap.put(CompositeName.MLDSA65_Ed25519_SHA512, MiscObjectIdentifiers.id_MLDSA65_Ed25519_SHA512); + compositeNameASN1IdentifierMap.put(CompositeName.MLDSA87_ECDSA_P384_SHA512, MiscObjectIdentifiers.id_MLDSA87_ECDSA_P384_SHA512); + compositeNameASN1IdentifierMap.put(CompositeName.MLDSA87_ECDSA_brainpoolP384r1_SHA512, MiscObjectIdentifiers.id_MLDSA87_ECDSA_brainpoolP384r1_SHA512); + compositeNameASN1IdentifierMap.put(CompositeName.MLDSA87_Ed448_SHA512, MiscObjectIdentifiers.id_MLDSA87_Ed448_SHA512); + compositeNameASN1IdentifierMap.put(CompositeName.Falcon512_ECDSA_P256_SHA256, MiscObjectIdentifiers.id_Falcon512_ECDSA_P256_SHA256); + compositeNameASN1IdentifierMap.put(CompositeName.Falcon512_ECDSA_brainpoolP256r1_SHA256, MiscObjectIdentifiers.id_Falcon512_ECDSA_brainpoolP256r1_SHA256); + compositeNameASN1IdentifierMap.put(CompositeName.Falcon512_Ed25519_SHA512, MiscObjectIdentifiers.id_Falcon512_Ed25519_SHA512); + } + + /** + * Reverse map of compositeNameASN1IdentifierMap. + */ + public static final HashMap ASN1IdentifierCompositeNameMap; + + static + { + ASN1IdentifierCompositeNameMap = new HashMap(); + for (Entry entry : compositeNameASN1IdentifierMap.entrySet()) + { + ASN1IdentifierCompositeNameMap.put(entry.getValue(), entry.getKey()); + } + } + + /** + * Map from ASN1 identifier to a readable string used as the composite signature name for the JCA/JCE API. + */ + public static final HashMap ASN1IdentifierAlgorithmNameMap; + + static + { + ASN1IdentifierAlgorithmNameMap = new HashMap(); + for (ASN1ObjectIdentifier oid : supportedIdentifiers) + { + CompositeName algName = ASN1IdentifierCompositeNameMap.get(oid); //Get enum so we can get name() value. + ASN1IdentifierAlgorithmNameMap.put(oid, algName); + } + } + + private CompositeSignaturesConstants() + { + + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/KeyFactorySpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/KeyFactorySpi.java new file mode 100644 index 0000000000..43e38f7931 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/KeyFactorySpi.java @@ -0,0 +1,310 @@ +package org.bouncycastle.jcajce.provider.asymmetric.compositesignatures; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.bouncycastle.asn1.ASN1BitString; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERBitString; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.sec.SECObjectIdentifiers; +import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x9.X962Parameters; +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.jcajce.CompositePrivateKey; +import org.bouncycastle.jcajce.CompositePublicKey; +import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; +import org.bouncycastle.util.Exceptions; + +/** + * KeyFactory for composite signatures. List of supported combinations is in CompositeSignaturesConstants + */ +public class KeyFactorySpi + extends BaseKeyFactorySpi +{ + + //Specific algorithm identifiers of all component signature algorithms for SubjectPublicKeyInfo. These do not need to be all initialized here but makes the code more readable IMHO. + private static final AlgorithmIdentifier dilithium2Identifier = new AlgorithmIdentifier(NISTObjectIdentifiers.id_ml_dsa_44); + private static final AlgorithmIdentifier dilithium3Identifier = new AlgorithmIdentifier(NISTObjectIdentifiers.id_ml_dsa_65); + private static final AlgorithmIdentifier dilithium5Identifier = new AlgorithmIdentifier(NISTObjectIdentifiers.id_ml_dsa_87); + private static final AlgorithmIdentifier falcon512Identifier = new AlgorithmIdentifier(BCObjectIdentifiers.falcon_512); + private static final AlgorithmIdentifier ed25519Identifier = new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519); + private static final AlgorithmIdentifier ecdsaP256Identifier = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, new X962Parameters(SECObjectIdentifiers.secp256r1)); + private static final AlgorithmIdentifier ecdsaBrainpoolP256r1Identifier = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, new X962Parameters(TeleTrusTObjectIdentifiers.brainpoolP256r1)); + private static final AlgorithmIdentifier rsaIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption); + private static final AlgorithmIdentifier ed448Identifier = new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448); + private static final AlgorithmIdentifier ecdsaP384Identifier = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, new X962Parameters(SECObjectIdentifiers.secp384r1)); + private static final AlgorithmIdentifier ecdsaBrainpoolP384r1Identifier = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, new X962Parameters(TeleTrusTObjectIdentifiers.brainpoolP384r1)); + + protected Key engineTranslateKey(Key key) + throws InvalidKeyException + { + try + { + if (key instanceof PrivateKey) + { + return generatePrivate(PrivateKeyInfo.getInstance(key.getEncoded())); + } + else if (key instanceof PublicKey) + { + return generatePublic(SubjectPublicKeyInfo.getInstance(key.getEncoded())); + } + } + catch (IOException e) + { + throw new InvalidKeyException("Key could not be parsed: " + e.getMessage()); + } + + throw new InvalidKeyException("Key not recognized"); + } + + /** + * Creates a CompositePrivateKey from its PrivateKeyInfo encoded form. + * It is compliant with https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html where + * CompositeSignaturePrivateKey is a sequence of two OneAsymmetricKey which a newer name for PrivateKeyInfo. + * + * @param keyInfo PrivateKeyInfo containing a sequence of PrivateKeyInfos corresponding to each component. + * @return A CompositePrivateKey created from all components in the sequence. + * @throws IOException + */ + public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) + throws IOException + { + ASN1Sequence seq = DERSequence.getInstance(keyInfo.parsePrivateKey()); + ASN1ObjectIdentifier keyIdentifier = keyInfo.getPrivateKeyAlgorithm().getAlgorithm(); + + try + { + List factories = getKeyFactoriesFromIdentifier(keyIdentifier); //Get key factories for each component algorithm. + PrivateKey[] privateKeys = new PrivateKey[seq.size()]; + for (int i = 0; i < seq.size(); i++) + { + // We assume each component is of type OneAsymmetricKey (PrivateKeyInfo) as defined by the draft RFC + // and use the component key factory to decode the component key from PrivateKeyInfo. + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(PrivateKeyInfo.getInstance(seq.getObjectAt(i)).getEncoded()); + privateKeys[i] = factories.get(i).generatePrivate(keySpec); + } + return new CompositePrivateKey(keyIdentifier, privateKeys); + } + catch (GeneralSecurityException e) + { + throw Exceptions.ioException(e.getMessage(), e); + } + } + + /** + * Creates a CompositePublicKey from its SubjectPublicKeyInfo encoded form. + * It is compliant with https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html where + * CompositeSignaturePublicKey is a sequence of two BIT STRINGs which contain the encoded component public keys. + * In BC implementation - CompositePublicKey is encoded into a BIT STRING in the form of SubjectPublicKeyInfo. + * + * @param keyInfo SubjectPublicKeyInfo containing a sequence of BIT STRINGs corresponding to each component. + * @return + * @throws IOException + */ + public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) + throws IOException + { + ASN1Sequence seq = DERSequence.getInstance(keyInfo.getPublicKeyData().getBytes()); + ASN1ObjectIdentifier keyIdentifier = keyInfo.getAlgorithm().getAlgorithm(); + + try + { + List factories = getKeyFactoriesFromIdentifier(keyIdentifier); + ASN1BitString[] componentBitStrings = new ASN1BitString[seq.size()]; + for (int i = 0; i < seq.size(); i++) + { + // Check if component is OCTET STRING. If yes, convert it to BIT STRING. + // This check should not be necessary since the draft RFC specifies components as BIT STRING encoded, + // but currently the example public keys are OCTET STRING. So we leave it for interoperability. + if (seq.getObjectAt(i) instanceof DEROctetString) + { + componentBitStrings[i] = new DERBitString(((DEROctetString)seq.getObjectAt(i)).getOctets()); + } + else + { + componentBitStrings[i] = (DERBitString)seq.getObjectAt(i); + } + } + + // We need to get X509EncodedKeySpec to use key factories to produce component public keys. + X509EncodedKeySpec[] x509EncodedKeySpecs = getKeysSpecs(keyIdentifier, componentBitStrings); + PublicKey[] publicKeys = new PublicKey[seq.size()]; + for (int i = 0; i < seq.size(); i++) + { + publicKeys[i] = factories.get(i).generatePublic(x509EncodedKeySpecs[i]); + } + + return new CompositePublicKey(keyIdentifier, publicKeys); + } + catch (GeneralSecurityException e) + { + throw Exceptions.ioException(e.getMessage(), e); + } + } + + /** + * A helper method that returns a list of KeyFactory objects based on the composite signature OID. + * + * @param algorithmIdentifier OID of a composite signature. + * @return A list of KeyFactories ordered by the composite signature definition. + * @throws NoSuchAlgorithmException + * @throws NoSuchProviderException + */ + private List getKeyFactoriesFromIdentifier(ASN1ObjectIdentifier algorithmIdentifier) + throws NoSuchAlgorithmException, NoSuchProviderException + { + List factories = new ArrayList(); + List algorithmNames = new ArrayList(); + + switch (CompositeSignaturesConstants.ASN1IdentifierCompositeNameMap.get(algorithmIdentifier)) + { + case MLDSA44_Ed25519_SHA512: + case MLDSA65_Ed25519_SHA512: + algorithmNames.add("ML-DSA"); + algorithmNames.add("Ed25519"); + break; + case MLDSA87_Ed448_SHA512: + algorithmNames.add("ML-DSA"); + algorithmNames.add("Ed448"); + break; + case MLDSA44_RSA2048_PSS_SHA256: + case MLDSA44_RSA2048_PKCS15_SHA256: + case MLDSA65_RSA3072_PSS_SHA512: + case MLDSA65_RSA3072_PKCS15_SHA512: + algorithmNames.add("ML-DSA"); + algorithmNames.add("RSA"); + break; + case MLDSA44_ECDSA_P256_SHA256: + case MLDSA44_ECDSA_brainpoolP256r1_SHA256: + case MLDSA65_ECDSA_P256_SHA512: + case MLDSA65_ECDSA_brainpoolP256r1_SHA512: + case MLDSA87_ECDSA_P384_SHA512: + case MLDSA87_ECDSA_brainpoolP384r1_SHA512: + algorithmNames.add("ML-DSA"); + algorithmNames.add("ECDSA"); + break; + case Falcon512_Ed25519_SHA512: + algorithmNames.add("Falcon"); + algorithmNames.add("Ed25519"); + break; + case Falcon512_ECDSA_P256_SHA256: + case Falcon512_ECDSA_brainpoolP256r1_SHA256: + algorithmNames.add("Falcon"); + algorithmNames.add("ECDSA"); + break; + default: + throw new IllegalArgumentException("Cannot create KeyFactories. Unsupported algorithm identifier."); + } + + factories.add(KeyFactory.getInstance(algorithmNames.get(0), "BC")); + factories.add(KeyFactory.getInstance(algorithmNames.get(1), "BC")); + return Collections.unmodifiableList(factories); + } + + + /** + * A helper method that returns an array of X509EncodedKeySpecs based on the composite signature OID + * and the content of provided BIT STRINGs in subjectPublicKeys + * + * @param algorithmIdentifier OID of a composite signature. + * @param subjectPublicKeys A BIT STRING array containing encoded component SubjectPublicKeyInfos. + * @return An array of X509EncodedKeySpecs + * @throws IOException + */ + private X509EncodedKeySpec[] getKeysSpecs(ASN1ObjectIdentifier algorithmIdentifier, ASN1BitString[] subjectPublicKeys) + throws IOException + { + X509EncodedKeySpec[] specs = new X509EncodedKeySpec[subjectPublicKeys.length]; + SubjectPublicKeyInfo[] keyInfos = new SubjectPublicKeyInfo[subjectPublicKeys.length]; + + switch (CompositeSignaturesConstants.ASN1IdentifierCompositeNameMap.get(algorithmIdentifier)) + { + case MLDSA44_Ed25519_SHA512: + keyInfos[0] = new SubjectPublicKeyInfo(dilithium2Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(ed25519Identifier, subjectPublicKeys[1]); + break; + case MLDSA44_ECDSA_P256_SHA256: + keyInfos[0] = new SubjectPublicKeyInfo(dilithium2Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(ecdsaP256Identifier, subjectPublicKeys[1]); + break; + case MLDSA44_ECDSA_brainpoolP256r1_SHA256: + keyInfos[0] = new SubjectPublicKeyInfo(dilithium2Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(ecdsaBrainpoolP256r1Identifier, subjectPublicKeys[1]); + break; + case MLDSA44_RSA2048_PSS_SHA256: + case MLDSA44_RSA2048_PKCS15_SHA256: + keyInfos[0] = new SubjectPublicKeyInfo(dilithium2Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(rsaIdentifier, subjectPublicKeys[1]); + break; + case MLDSA65_Ed25519_SHA512: + keyInfos[0] = new SubjectPublicKeyInfo(dilithium3Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(ed25519Identifier, subjectPublicKeys[1]); + break; + case MLDSA65_ECDSA_P256_SHA512: + keyInfos[0] = new SubjectPublicKeyInfo(dilithium3Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(ecdsaP256Identifier, subjectPublicKeys[1]); + break; + case MLDSA65_ECDSA_brainpoolP256r1_SHA512: + keyInfos[0] = new SubjectPublicKeyInfo(dilithium3Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(ecdsaBrainpoolP256r1Identifier, subjectPublicKeys[1]); + break; + case MLDSA65_RSA3072_PSS_SHA512: + case MLDSA65_RSA3072_PKCS15_SHA512: + keyInfos[0] = new SubjectPublicKeyInfo(dilithium3Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(rsaIdentifier, subjectPublicKeys[1]); + break; + case MLDSA87_Ed448_SHA512: + keyInfos[0] = new SubjectPublicKeyInfo(dilithium5Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(ed448Identifier, subjectPublicKeys[1]); + break; + case MLDSA87_ECDSA_P384_SHA512: + keyInfos[0] = new SubjectPublicKeyInfo(dilithium5Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(ecdsaP384Identifier, subjectPublicKeys[1]); + break; + case MLDSA87_ECDSA_brainpoolP384r1_SHA512: + keyInfos[0] = new SubjectPublicKeyInfo(dilithium5Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(ecdsaBrainpoolP384r1Identifier, subjectPublicKeys[1]); + break; + case Falcon512_Ed25519_SHA512: + keyInfos[0] = new SubjectPublicKeyInfo(falcon512Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(ed25519Identifier, subjectPublicKeys[1]); + break; + case Falcon512_ECDSA_P256_SHA256: + keyInfos[0] = new SubjectPublicKeyInfo(falcon512Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(ecdsaP256Identifier, subjectPublicKeys[1]); + break; + case Falcon512_ECDSA_brainpoolP256r1_SHA256: + keyInfos[0] = new SubjectPublicKeyInfo(falcon512Identifier, subjectPublicKeys[0]); + keyInfos[1] = new SubjectPublicKeyInfo(ecdsaBrainpoolP256r1Identifier, subjectPublicKeys[1]); + break; + default: + throw new IllegalArgumentException("Cannot create key specs. Unsupported algorithm identifier."); + } + + specs[0] = new X509EncodedKeySpec(keyInfos[0].getEncoded()); + specs[1] = new X509EncodedKeySpec(keyInfos[1].getEncoded()); + return specs; + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/KeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/KeyPairGeneratorSpi.java new file mode 100644 index 0000000000..bf8b59c44e --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/KeyPairGeneratorSpi.java @@ -0,0 +1,373 @@ +package org.bouncycastle.jcajce.provider.asymmetric.compositesignatures; + +import java.security.GeneralSecurityException; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.ECGenParameterSpec; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.jcajce.CompositePrivateKey; +import org.bouncycastle.jcajce.CompositePublicKey; +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; +import org.bouncycastle.pqc.jcajce.spec.FalconParameterSpec; + + +/** + * KeyPairGenerator class for composite signatures. Selected algorithm is set by the "subclasses" at the end of this file. + */ +public class KeyPairGeneratorSpi + extends java.security.KeyPairGeneratorSpi +{ + //Enum value of the selected composite signature algorithm. + private final CompositeSignaturesConstants.CompositeName algorithmIdentifier; + //ASN1 OI value of the selected composite signature algorithm. + private final ASN1ObjectIdentifier algorithmIdentifierASN1; + + //List of KeyPairGenerators. Each entry corresponds to a component signature from the composite definition. + private List generators; + + private SecureRandom secureRandom; + private boolean parametersInitialized = false; + + KeyPairGeneratorSpi(CompositeSignaturesConstants.CompositeName algorithmIdentifier) + { + this.algorithmIdentifier = algorithmIdentifier; + this.algorithmIdentifierASN1 = CompositeSignaturesConstants.compositeNameASN1IdentifierMap.get(this.algorithmIdentifier); + } + + /** + * Creates a list of KeyPairGenerators based on the selected composite algorithm (algorithmIdentifier). + * Each component generator is initialized with parameters according to the specification https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html. + * Called after initialize() method or right before keypair generation in case initialize() was not called by the user. + */ + private void initializeParameters() + { + + if (this.secureRandom == null) + { + this.secureRandom = new SecureRandom(); + } + + List generators = new ArrayList(); + try + { + switch (this.algorithmIdentifier) + { + case MLDSA44_Ed25519_SHA512: + generators.add(KeyPairGenerator.getInstance("ML-DSA-44", "BC")); + generators.add(KeyPairGenerator.getInstance("Ed25519", "BC")); + generators.get(0).initialize(MLDSAParameterSpec.ml_dsa_44, this.secureRandom); + generators.get(1).initialize(256, this.secureRandom); + break; + case MLDSA65_Ed25519_SHA512: + generators.add(KeyPairGenerator.getInstance("ML-DSA-65", "BC")); + generators.add(KeyPairGenerator.getInstance("Ed25519", "BC")); + generators.get(0).initialize(MLDSAParameterSpec.ml_dsa_65, this.secureRandom); + generators.get(1).initialize(256, this.secureRandom); + break; + case MLDSA87_Ed448_SHA512: + generators.add(KeyPairGenerator.getInstance("ML-DSA-87", "BC")); + generators.add(KeyPairGenerator.getInstance("Ed448", "BC")); + generators.get(0).initialize(MLDSAParameterSpec.ml_dsa_87, this.secureRandom); + generators.get(1).initialize(448, this.secureRandom); + break; + case MLDSA44_RSA2048_PSS_SHA256: + case MLDSA44_RSA2048_PKCS15_SHA256: + generators.add(KeyPairGenerator.getInstance("ML-DSA-44", "BC")); + generators.add(KeyPairGenerator.getInstance("RSA", "BC")); + generators.get(0).initialize(MLDSAParameterSpec.ml_dsa_44, this.secureRandom); + generators.get(1).initialize(2048, this.secureRandom); + break; + case MLDSA65_RSA3072_PSS_SHA512: + case MLDSA65_RSA3072_PKCS15_SHA512: + generators.add(KeyPairGenerator.getInstance("ML-DSA-65", "BC")); + generators.add(KeyPairGenerator.getInstance("RSA", "BC")); + generators.get(0).initialize(MLDSAParameterSpec.ml_dsa_65, this.secureRandom); + generators.get(1).initialize(3072, this.secureRandom); + break; + case MLDSA44_ECDSA_P256_SHA256: + generators.add(KeyPairGenerator.getInstance("ML-DSA-44", "BC")); + generators.add(KeyPairGenerator.getInstance("ECDSA", "BC")); + generators.get(0).initialize(MLDSAParameterSpec.ml_dsa_44, this.secureRandom); + generators.get(1).initialize(new ECGenParameterSpec("P-256"), this.secureRandom); + break; + case MLDSA44_ECDSA_brainpoolP256r1_SHA256: + generators.add(KeyPairGenerator.getInstance("ML-DSA-44", "BC")); + generators.add(KeyPairGenerator.getInstance("ECDSA", "BC")); + generators.get(0).initialize(MLDSAParameterSpec.ml_dsa_44, this.secureRandom); + generators.get(1).initialize(new ECGenParameterSpec("brainpoolP256r1"), this.secureRandom); + break; + case MLDSA65_ECDSA_P256_SHA512: + generators.add(KeyPairGenerator.getInstance("ML-DSA-65", "BC")); + generators.add(KeyPairGenerator.getInstance("ECDSA", "BC")); + generators.get(0).initialize(MLDSAParameterSpec.ml_dsa_65, this.secureRandom); + generators.get(1).initialize(new ECGenParameterSpec("P-256"), this.secureRandom); + break; + case MLDSA65_ECDSA_brainpoolP256r1_SHA512: + generators.add(KeyPairGenerator.getInstance("ML-DSA-65", "BC")); + generators.add(KeyPairGenerator.getInstance("ECDSA", "BC")); + generators.get(0).initialize(MLDSAParameterSpec.ml_dsa_65, this.secureRandom); + generators.get(1).initialize(new ECGenParameterSpec("brainpoolP256r1"), this.secureRandom); + break; + case MLDSA87_ECDSA_P384_SHA512: + generators.add(KeyPairGenerator.getInstance("ML-DSA-87", "BC")); + generators.add(KeyPairGenerator.getInstance("ECDSA", "BC")); + generators.get(0).initialize(MLDSAParameterSpec.ml_dsa_87, this.secureRandom); + generators.get(1).initialize(new ECGenParameterSpec("P-384"), this.secureRandom); + break; + case MLDSA87_ECDSA_brainpoolP384r1_SHA512: + generators.add(KeyPairGenerator.getInstance("ML-DSA-87", "BC")); + generators.add(KeyPairGenerator.getInstance("ECDSA", "BC")); + generators.get(0).initialize(MLDSAParameterSpec.ml_dsa_87, this.secureRandom); + generators.get(1).initialize(new ECGenParameterSpec("brainpoolP384r1"), this.secureRandom); + break; + case Falcon512_ECDSA_P256_SHA256: + generators.add(KeyPairGenerator.getInstance("Falcon", "BC")); + generators.add(KeyPairGenerator.getInstance("ECDSA", "BC")); + generators.get(0).initialize(FalconParameterSpec.falcon_512, this.secureRandom); + generators.get(1).initialize(new ECGenParameterSpec("P-256"), this.secureRandom); + break; + case Falcon512_ECDSA_brainpoolP256r1_SHA256: + generators.add(KeyPairGenerator.getInstance("Falcon", "BC")); + generators.add(KeyPairGenerator.getInstance("ECDSA", "BC")); + generators.get(0).initialize(FalconParameterSpec.falcon_512, this.secureRandom); + generators.get(1).initialize(new ECGenParameterSpec("brainpoolP256r1"), this.secureRandom); + break; + case Falcon512_Ed25519_SHA512: + generators.add(KeyPairGenerator.getInstance("Falcon", "BC")); + generators.add(KeyPairGenerator.getInstance("Ed25519", "BC")); + generators.get(0).initialize(FalconParameterSpec.falcon_512, this.secureRandom); + generators.get(1).initialize(256, this.secureRandom); + break; + default: + throw new IllegalStateException("Generators not correctly initialized. Unsupported composite algorithm."); + } + } + catch (GeneralSecurityException e) + { + throw new RuntimeException(e); + } + + this.generators = Collections.unmodifiableList(generators); + this.parametersInitialized = true; + } + + /** + * Native public method. There is no notion of a keysize for composite signatures. Therefore, this method is + * unsupported. For setting a custom SecureRandom the other initialize method must be used. + * + * @param keySize + * @param random + */ + @Override + public void initialize(int keySize, SecureRandom random) + { + throw new IllegalArgumentException("use AlgorithmParameterSpec"); + } + + /** + * Setting custom AlgorithmParameterSpec is not supported since the composite signature algorithm definition + * allow only for one specific parameter spec which is initialized by the initializeParameters method. + * This method only serves to set a custom SecureRandom. + * + * @param paramSpec Unsupported, needs to be null. + * @param secureRandom A SecureRandom used by component key generators. + * @throws InvalidAlgorithmParameterException + */ + public void initialize(AlgorithmParameterSpec paramSpec, SecureRandom secureRandom) + throws InvalidAlgorithmParameterException + { + if (paramSpec != null) + { + throw new IllegalArgumentException("Use initialize only for custom SecureRandom. AlgorithmParameterSpec must be null because it is determined by algorithm name."); + } + + this.secureRandom = secureRandom; + initializeParameters(); + } + + public KeyPair generateKeyPair() + { + if (!this.parametersInitialized) + { + this.initializeParameters(); + } + + return getCompositeKeyPair(); + } + + /** + * Generates a KeyPair of CompositePublicKey and CompositePrivateKey. + * It iterates over the generators list which was created based on the composite signature type. + * + * @return A composite KeyPair + */ + private KeyPair getCompositeKeyPair() + { + PublicKey[] publicKeys = new PublicKey[generators.size()]; + PrivateKey[] privateKeys = new PrivateKey[generators.size()]; + for (int i = 0; i < generators.size(); i++) + { + KeyPair keyPair = generators.get(i).generateKeyPair(); + publicKeys[i] = keyPair.getPublic(); + privateKeys[i] = keyPair.getPrivate(); + } + CompositePublicKey compositePublicKey = new CompositePublicKey(this.algorithmIdentifierASN1, publicKeys); + CompositePrivateKey compositePrivateKey = new CompositePrivateKey(this.algorithmIdentifierASN1, privateKeys); + return new KeyPair(compositePublicKey, compositePrivateKey); + } + + public static final class MLDSA44_Ed25519_SHA512 + extends KeyPairGeneratorSpi + { + public MLDSA44_Ed25519_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA44_Ed25519_SHA512); + } + } + + public static final class MLDSA65_Ed25519_SHA512 + extends KeyPairGeneratorSpi + { + public MLDSA65_Ed25519_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA65_Ed25519_SHA512); + } + } + + public static final class MLDSA87_Ed448_SHA512 + extends KeyPairGeneratorSpi + { + public MLDSA87_Ed448_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA87_Ed448_SHA512); + } + } + + public static final class MLDSA44_RSA2048_PSS_SHA256 + extends KeyPairGeneratorSpi + { + public MLDSA44_RSA2048_PSS_SHA256() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA44_RSA2048_PSS_SHA256); + } + } + + public static final class MLDSA44_RSA2048_PKCS15_SHA256 + extends KeyPairGeneratorSpi + { + public MLDSA44_RSA2048_PKCS15_SHA256() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA44_RSA2048_PKCS15_SHA256); + } + } + + public static final class MLDSA65_RSA3072_PSS_SHA512 + extends KeyPairGeneratorSpi + { + public MLDSA65_RSA3072_PSS_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA65_RSA3072_PSS_SHA512); + } + } + + public static final class MLDSA65_RSA3072_PKCS15_SHA512 + extends KeyPairGeneratorSpi + { + public MLDSA65_RSA3072_PKCS15_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA65_RSA3072_PKCS15_SHA512); + } + } + + public static final class MLDSA44_ECDSA_P256_SHA256 + extends KeyPairGeneratorSpi + { + public MLDSA44_ECDSA_P256_SHA256() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA44_ECDSA_P256_SHA256); + } + } + + public static final class MLDSA44_ECDSA_brainpoolP256r1_SHA256 + extends KeyPairGeneratorSpi + { + public MLDSA44_ECDSA_brainpoolP256r1_SHA256() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA44_ECDSA_brainpoolP256r1_SHA256); + } + } + + public static final class MLDSA65_ECDSA_P256_SHA512 + extends KeyPairGeneratorSpi + { + public MLDSA65_ECDSA_P256_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA65_ECDSA_P256_SHA512); + } + } + + public static final class MLDSA65_ECDSA_brainpoolP256r1_SHA512 + extends KeyPairGeneratorSpi + { + public MLDSA65_ECDSA_brainpoolP256r1_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA65_ECDSA_brainpoolP256r1_SHA512); + } + } + + public static final class MLDSA87_ECDSA_P384_SHA512 + extends KeyPairGeneratorSpi + { + public MLDSA87_ECDSA_P384_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA87_ECDSA_P384_SHA512); + } + } + + public static final class MLDSA87_ECDSA_brainpoolP384r1_SHA512 + extends KeyPairGeneratorSpi + { + public MLDSA87_ECDSA_brainpoolP384r1_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA87_ECDSA_brainpoolP384r1_SHA512); + } + } + + public static final class Falcon512_Ed25519_SHA512 + extends KeyPairGeneratorSpi + { + public Falcon512_Ed25519_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.Falcon512_Ed25519_SHA512); + } + } + + public static final class Falcon512_ECDSA_P256_SHA256 + extends KeyPairGeneratorSpi + { + public Falcon512_ECDSA_P256_SHA256() + { + super(CompositeSignaturesConstants.CompositeName.Falcon512_ECDSA_P256_SHA256); + } + } + + public static final class Falcon512_ECDSA_brainpoolP256r1_SHA256 + extends KeyPairGeneratorSpi + { + public Falcon512_ECDSA_brainpoolP256r1_SHA256() + { + super(CompositeSignaturesConstants.CompositeName.Falcon512_ECDSA_brainpoolP256r1_SHA256); + } + } + + +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/SignatureSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/SignatureSpi.java new file mode 100644 index 0000000000..6c555f3401 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/SignatureSpi.java @@ -0,0 +1,435 @@ +package org.bouncycastle.jcajce.provider.asymmetric.compositesignatures; + +import java.io.IOException; +import java.security.AlgorithmParameters; +import java.security.GeneralSecurityException; +import java.security.InvalidKeyException; +import java.security.InvalidParameterException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.bouncycastle.asn1.ASN1BitString; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERBitString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.util.DigestFactory; +import org.bouncycastle.jcajce.CompositePrivateKey; +import org.bouncycastle.jcajce.CompositePublicKey; +import org.bouncycastle.util.Exceptions; + +/** + * Signature class for composite signatures. Selected algorithm is set by the "subclasses" at the end of this file. + */ +public class SignatureSpi + extends java.security.SignatureSpi +{ + //Enum value of the selected composite signature algorithm. + private final CompositeSignaturesConstants.CompositeName algorithmIdentifier; + //ASN1 OI value of the selected composite signature algorithm. + private final ASN1ObjectIdentifier algorithmIdentifierASN1; + + //List of Signatures. Each entry corresponds to a component signature from the composite definition. + private final List componentSignatures; + + //Hash function that is used to pre-hash the input message before it is fed into the component Signature. + //Each composite signature has a specific hash function https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html + private final Digest digest; + private byte[] OIDBytes; + + + SignatureSpi(CompositeSignaturesConstants.CompositeName algorithmIdentifier) + { + this.algorithmIdentifier = algorithmIdentifier; + this.algorithmIdentifierASN1 = CompositeSignaturesConstants.compositeNameASN1IdentifierMap.get(this.algorithmIdentifier); + List componentSignatures = new ArrayList(); + try + { + switch (this.algorithmIdentifier) + { + case MLDSA44_Ed25519_SHA512: + componentSignatures.add(Signature.getInstance("ML-DSA-44", "BC")); + componentSignatures.add(Signature.getInstance("Ed25519", "BC")); + this.digest = DigestFactory.createSHA512(); + break; + case MLDSA65_Ed25519_SHA512: + componentSignatures.add(Signature.getInstance("ML-DSA-65", "BC")); + componentSignatures.add(Signature.getInstance("Ed25519", "BC")); + this.digest = DigestFactory.createSHA512(); + break; + case MLDSA87_Ed448_SHA512: + componentSignatures.add(Signature.getInstance("ML-DSA-87", "BC")); + componentSignatures.add(Signature.getInstance("Ed448", "BC")); + this.digest = DigestFactory.createSHA512(); + break; + case MLDSA44_RSA2048_PSS_SHA256: + componentSignatures.add(Signature.getInstance("ML-DSA-44", "BC")); + componentSignatures.add(Signature.getInstance("SHA256withRSA/PSS", "BC")); //PSS with SHA-256 as digest algo and MGF. + this.digest = DigestFactory.createSHA256(); + break; + case MLDSA65_RSA3072_PSS_SHA512: + componentSignatures.add(Signature.getInstance("ML-DSA-65", "BC")); + componentSignatures.add(Signature.getInstance("SHA512withRSA/PSS", "BC")); //PSS with SHA-512 as digest algo and MGF. + this.digest = DigestFactory.createSHA512(); + break; + case MLDSA44_RSA2048_PKCS15_SHA256: + componentSignatures.add(Signature.getInstance("ML-DSA-44", "BC")); + componentSignatures.add(Signature.getInstance("SHA256withRSA", "BC")); //PKCS15 + this.digest = DigestFactory.createSHA256(); + break; + case MLDSA65_RSA3072_PKCS15_SHA512: + componentSignatures.add(Signature.getInstance("ML-DSA-65", "BC")); + componentSignatures.add(Signature.getInstance("SHA512withRSA", "BC")); //PKCS15 + this.digest = DigestFactory.createSHA512(); + break; + case MLDSA44_ECDSA_P256_SHA256: + case MLDSA44_ECDSA_brainpoolP256r1_SHA256: + componentSignatures.add(Signature.getInstance("ML-DSA-44", "BC")); + componentSignatures.add(Signature.getInstance("SHA256withECDSA", "BC")); + this.digest = DigestFactory.createSHA256(); + break; + case MLDSA65_ECDSA_P256_SHA512: + case MLDSA65_ECDSA_brainpoolP256r1_SHA512: + componentSignatures.add(Signature.getInstance("ML-DSA-65", "BC")); + componentSignatures.add(Signature.getInstance("SHA512withECDSA", "BC")); + this.digest = DigestFactory.createSHA512(); + break; + case MLDSA87_ECDSA_P384_SHA512: + case MLDSA87_ECDSA_brainpoolP384r1_SHA512: + componentSignatures.add(Signature.getInstance("ML-DSA-87", "BC")); + componentSignatures.add(Signature.getInstance("SHA512withECDSA", "BC")); + this.digest = DigestFactory.createSHA512(); + break; + case Falcon512_ECDSA_P256_SHA256: + case Falcon512_ECDSA_brainpoolP256r1_SHA256: + componentSignatures.add(Signature.getInstance("Falcon", "BC")); + componentSignatures.add(Signature.getInstance("SHA256withECDSA", "BC")); + this.digest = DigestFactory.createSHA256(); + break; + case Falcon512_Ed25519_SHA512: + componentSignatures.add(Signature.getInstance("Falcon", "BC")); + componentSignatures.add(Signature.getInstance("Ed25519", "BC")); + this.digest = DigestFactory.createSHA512(); + break; + default: + throw new IllegalArgumentException("unknown composite algorithm"); + } + + //get bytes of composite signature algorithm OID in DER + //these bytes are used a prefix to the message digest https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html#name-composite-sign + OIDBytes = this.algorithmIdentifierASN1.getEncoded(ASN1Encoding.DER); + } + catch (GeneralSecurityException e) + { + throw Exceptions.illegalStateException(e.getMessage(), e); + } + catch (IOException e) + { + throw Exceptions.illegalStateException(e.getMessage(), e); + } + this.componentSignatures = Collections.unmodifiableList(componentSignatures); + } + + protected void engineInitVerify(PublicKey publicKey) + throws InvalidKeyException + { + + if (!(publicKey instanceof CompositePublicKey)) + { + throw new InvalidKeyException("Public key is not composite."); + } + + CompositePublicKey compositePublicKey = (CompositePublicKey)publicKey; + + if (!compositePublicKey.getAlgorithmIdentifier().equals(this.algorithmIdentifierASN1)) + { + throw new InvalidKeyException("Provided composite public key cannot be used with the composite signature algorithm."); + } + + //for each component signature run initVerify with the corresponding public key. + for (int i = 0; i < this.componentSignatures.size(); i++) + { + this.componentSignatures.get(i).initVerify(compositePublicKey.getPublicKeys().get(i)); + } + } + + protected void engineInitSign(PrivateKey privateKey) + throws InvalidKeyException + { + if (!(privateKey instanceof CompositePrivateKey)) + { + throw new InvalidKeyException("Private key is not composite."); + } + + CompositePrivateKey compositePrivateKey = (CompositePrivateKey)privateKey; + + if (!compositePrivateKey.getAlgorithmIdentifier().equals(this.algorithmIdentifierASN1)) + { + throw new InvalidKeyException("Provided composite private key cannot be used with the composite signature algorithm."); + } + + //for each component signature run initVerify with the corresponding private key. + for (int i = 0; i < this.componentSignatures.size(); i++) + { + this.componentSignatures.get(i).initSign(compositePrivateKey.getPrivateKeys().get(i)); + } + } + + + protected void engineUpdate(byte b) + throws SignatureException + { + digest.update(b); + } + + protected void engineUpdate(byte[] bytes, int off, int len) + throws SignatureException + { + digest.update(bytes, off, len); + } + + /** + * Method which calculates each component signature and constructs a composite signature + * which is a sequence of BIT STRINGs https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html#name-compositesignaturevalue + * + * @return composite signature bytes + * @throws SignatureException + */ + protected byte[] engineSign() + throws SignatureException + { + ASN1EncodableVector signatureSequence = new ASN1EncodableVector(); + try + { + //calculate message digest (pre-hashing of the message) + byte[] digestResult = new byte[digest.getDigestSize()]; + digest.doFinal(digestResult, 0); + + for (int i = 0; i < this.componentSignatures.size(); i++) + { + this.componentSignatures.get(i).update(this.OIDBytes); + this.componentSignatures.get(i).update(digestResult); //in total, "OID || digest(message)" is the message fed into each component signature + byte[] signatureValue = this.componentSignatures.get(i).sign(); + signatureSequence.add(new DERBitString(signatureValue)); + } + + return new DERSequence(signatureSequence).getEncoded(ASN1Encoding.DER); + } + catch (IOException e) + { + throw new SignatureException(e.getMessage()); + } + + } + + /** + * Corresponding verification method to the engineSign method. + * The composite signature is valid if and only if all component signatures are valid. + * The method verifies all component signatures even if it is already known that the composite signature is invalid. + * + * @param signature the signature bytes to be verified. + * @return + * @throws SignatureException + */ + protected boolean engineVerify(byte[] signature) + throws SignatureException + { + + ASN1Sequence signatureSequence = DERSequence.getInstance(signature); + //Check if the decoded sequence of component signatures has the expected size. + if (signatureSequence.size() != this.componentSignatures.size()) + { + return false; + } + + //calculate message digest (pre-hashing of the message) + byte[] digestResult = new byte[digest.getDigestSize()]; + digest.doFinal(digestResult, 0); + + // Currently all signatures try to verify even if, e.g., the first is invalid. + // If each component verify() is constant time, then this is also, otherwise it does not make sense to iterate over all if one of them already fails. + // However, it is important that we do not provide specific error messages, e.g., "only the 2nd component failed to verify". + boolean fail = false; + + for (int i = 0; i < this.componentSignatures.size(); i++) + { + this.componentSignatures.get(i).update(this.OIDBytes); + this.componentSignatures.get(i).update(digestResult); //in total, "OID || digest(message)" is the message fed into each component signature + if (!this.componentSignatures.get(i).verify(ASN1BitString.getInstance(signatureSequence.getObjectAt(i)).getOctets())) + { + fail = true; + } + } + + return !fail; + } + + protected void engineSetParameter(String s, Object o) + throws InvalidParameterException + { + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + protected Object engineGetParameter(String s) + throws InvalidParameterException + { + throw new UnsupportedOperationException("engineGetParameter unsupported"); + } + + protected AlgorithmParameters engineGetParameters() + { + return null; + } + + public final static class MLDSA44_Ed25519_SHA512 + extends SignatureSpi + { + public MLDSA44_Ed25519_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA44_Ed25519_SHA512); + } + } + + public final static class MLDSA65_Ed25519_SHA512 + extends SignatureSpi + { + public MLDSA65_Ed25519_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA65_Ed25519_SHA512); + } + } + + public final static class MLDSA87_Ed448_SHA512 + extends SignatureSpi + { + public MLDSA87_Ed448_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA87_Ed448_SHA512); + } + } + + public final static class MLDSA44_RSA2048_PSS_SHA256 + extends SignatureSpi + { + public MLDSA44_RSA2048_PSS_SHA256() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA44_RSA2048_PSS_SHA256); + } + } + + public final static class MLDSA44_RSA2048_PKCS15_SHA256 + extends SignatureSpi + { + public MLDSA44_RSA2048_PKCS15_SHA256() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA44_RSA2048_PKCS15_SHA256); + } + } + + public final static class MLDSA65_RSA3072_PSS_SHA512 + extends SignatureSpi + { + public MLDSA65_RSA3072_PSS_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA65_RSA3072_PSS_SHA512); + } + } + + public final static class MLDSA65_RSA3072_PKCS15_SHA512 + extends SignatureSpi + { + public MLDSA65_RSA3072_PKCS15_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA65_RSA3072_PKCS15_SHA512); + } + } + + public final static class MLDSA44_ECDSA_P256_SHA256 + extends SignatureSpi + { + public MLDSA44_ECDSA_P256_SHA256() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA44_ECDSA_P256_SHA256); + } + } + + public final static class MLDSA44_ECDSA_brainpoolP256r1_SHA256 + extends SignatureSpi + { + public MLDSA44_ECDSA_brainpoolP256r1_SHA256() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA44_ECDSA_brainpoolP256r1_SHA256); + } + } + + public final static class MLDSA65_ECDSA_P256_SHA512 + extends SignatureSpi + { + public MLDSA65_ECDSA_P256_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA65_ECDSA_P256_SHA512); + } + } + + public final static class MLDSA65_ECDSA_brainpoolP256r1_SHA512 + extends SignatureSpi + { + public MLDSA65_ECDSA_brainpoolP256r1_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA65_ECDSA_brainpoolP256r1_SHA512); + } + } + + public final static class MLDSA87_ECDSA_P384_SHA512 + extends SignatureSpi + { + public MLDSA87_ECDSA_P384_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA87_ECDSA_P384_SHA512); + } + } + + public final static class MLDSA87_ECDSA_brainpoolP384r1_SHA512 + extends SignatureSpi + { + public MLDSA87_ECDSA_brainpoolP384r1_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.MLDSA87_ECDSA_brainpoolP384r1_SHA512); + } + } + + public final static class Falcon512_Ed25519_SHA512 + extends SignatureSpi + { + public Falcon512_Ed25519_SHA512() + { + super(CompositeSignaturesConstants.CompositeName.Falcon512_Ed25519_SHA512); + } + } + + public final static class Falcon512_ECDSA_P256_SHA256 + extends SignatureSpi + { + public Falcon512_ECDSA_P256_SHA256() + { + super(CompositeSignaturesConstants.CompositeName.Falcon512_ECDSA_P256_SHA256); + } + } + + public final static class Falcon512_ECDSA_brainpoolP256r1_SHA256 + extends SignatureSpi + { + public Falcon512_ECDSA_brainpoolP256r1_SHA256() + { + super(CompositeSignaturesConstants.CompositeName.Falcon512_ECDSA_brainpoolP256r1_SHA256); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java index db2d65dc57..447047b1eb 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java @@ -20,6 +20,7 @@ import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; +import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.KeyEncoder; @@ -44,6 +45,7 @@ import org.bouncycastle.crypto.util.DigestFactory; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi; import org.bouncycastle.jcajce.provider.asymmetric.util.DHUtil; +import org.bouncycastle.jcajce.provider.asymmetric.util.IESUtil; import org.bouncycastle.jcajce.provider.util.BadBlockException; import org.bouncycastle.jcajce.util.BCJcaJceHelper; import org.bouncycastle.jcajce.util.JcaJceHelper; @@ -83,17 +85,10 @@ public IESCipher(IESEngine engine, int ivLength) public int engineGetBlockSize() { - if (engine.getCipher() != null) - { - return engine.getCipher().getBlockSize(); - } - else - { - return 0; - } + BufferedBlockCipher cipher = engine.getCipher(); + return cipher == null ? 0 : cipher.getBlockSize(); } - public int engineGetKeySize(Key key) { if (key instanceof DHKey) @@ -106,7 +101,6 @@ public int engineGetKeySize(Key key) } } - public byte[] engineGetIV() { if (engineSpec != null) @@ -262,18 +256,11 @@ public void engineInit( throws InvalidAlgorithmParameterException, InvalidKeyException { // NOTE: For secure usage, sender and receiver should agree on a fixed value for the nonce. -// if (engineSpec == null) -// { -// byte[] nonce = null; -// if (ivLength != 0 && opmode == Cipher.ENCRYPT_MODE) -// { -// nonce = new byte[ivLength]; -// random.nextBytes(nonce); -// } -// this.engineSpec = IESUtil.guessParameterSpec(engine.getCipher(), nonce); -// } -// else - if (engineSpec instanceof IESParameterSpec) + if (engineSpec == null && ivLength == 0) + { + this.engineSpec = IESUtil.guessParameterSpec(engine.getCipher(), null); + } + else if (engineSpec instanceof IESParameterSpec) { this.engineSpec = (IESParameterSpec)engineSpec; } @@ -402,9 +389,10 @@ public byte[] engineDoFinal( engineSpec.getMacKeySize(), engineSpec.getCipherKeySize()); - if (engineSpec.getNonce() != null) + byte[] engineSpecNonce = engineSpec.getNonce(); + if (engineSpecNonce != null) { - params = new ParametersWithIV(params, engineSpec.getNonce()); + params = new ParametersWithIV(params, engineSpecNonce); } DHParameters dhParams = ((DHKeyParameters)key).getParameters(); @@ -527,7 +515,7 @@ public IESwithDESedeCBC() super(new IESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()), new HMac(DigestFactory.createSHA1()), - new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine()))), 8); + new PaddedBufferedBlockCipher(CBCBlockCipher.newInstance(new DESedeEngine()))), 8); } } @@ -539,7 +527,7 @@ public IESwithAESCBC() super(new IESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()), new HMac(DigestFactory.createSHA1()), - new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()))), 16); + new PaddedBufferedBlockCipher(CBCBlockCipher.newInstance(AESEngine.newInstance()))), 16); } } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java index f7db9bef80..f4bd89ce4d 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java @@ -63,7 +63,7 @@ protected AlgorithmParameters engineGenerateParameters() } else { - pGen = new DSAParametersGenerator(new SHA256Digest()); + pGen = new DSAParametersGenerator(SHA256Digest.newInstance()); } if (random == null) diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java index f7ebf959e5..2a55d0256a 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java @@ -9,12 +9,12 @@ import java.security.interfaces.DSAPublicKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Fingerprint; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java index 091caa2695..630febd52a 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java @@ -133,7 +133,7 @@ public KeyPair generateKeyPair() else if (strength > 1024) { dsaParams = new DSAParameterGenerationParameters(strength, 256, certainty, random); - pGen = new DSAParametersGenerator(new SHA256Digest()); + pGen = new DSAParametersGenerator(SHA256Digest.newInstance()); pGen.init(dsaParams); } else diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PrivateKey.java index 31c16ebdac..f4c6817462 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PrivateKey.java @@ -259,7 +259,7 @@ else if (params.isImplicitlyCA()) reverseBytes(b_bytes); } DSTU4145BinaryField field = binary.getField(); - ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), new BigInteger(1, b_bytes)); + ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), new BigInteger(1, b_bytes), null, null); byte[] g_bytes = binary.getG(); if (info.getPrivateKeyAlgorithm().getAlgorithm().equals(UAObjectIdentifiers.dstu4145le)) { diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PublicKey.java index a8ba53660f..793cac8603 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PublicKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PublicKey.java @@ -229,7 +229,7 @@ private void populateFromPubKeyInfo(SubjectPublicKeyInfo info) reverseBytes(b_bytes); } DSTU4145BinaryField field = binary.getField(); - ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), new BigInteger(1, b_bytes)); + ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), new BigInteger(1, b_bytes), null, null); byte[] g_bytes = binary.getG(); if (info.getAlgorithm().getAlgorithm().equals(UAObjectIdentifiers.dstu4145le)) { diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java index aabe25c267..76c426c176 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java @@ -19,9 +19,11 @@ import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.crypto.params.ECNamedDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; @@ -30,6 +32,7 @@ import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.Arrays; @@ -38,16 +41,17 @@ public class BCECPrivateKey { static final long serialVersionUID = 994553197664784084L; - private String algorithm = "EC"; - private boolean withCompression; + private String algorithm = "EC"; + private boolean withCompression; - private transient BigInteger d; - private transient ECParameterSpec ecSpec; - private transient ProviderConfiguration configuration; - private transient ASN1BitString publicKey; - private transient PrivateKeyInfo privateKeyInfo; - private transient byte[] encoding; + private transient BigInteger d; + private transient ECParameterSpec ecSpec; + private transient ProviderConfiguration configuration; + private transient ASN1BitString publicKey; + private transient PrivateKeyInfo privateKeyInfo; + private transient byte[] encoding; + private transient ECPrivateKeyParameters baseKey; private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); @@ -63,6 +67,7 @@ public BCECPrivateKey( this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParams(); this.configuration = configuration; + this.baseKey = convertToBaseKey(this); } public BCECPrivateKey( @@ -88,6 +93,7 @@ public BCECPrivateKey( } this.configuration = configuration; + this.baseKey = convertToBaseKey(this); } @@ -100,6 +106,7 @@ public BCECPrivateKey( this.d = spec.getS(); this.ecSpec = spec.getParams(); this.configuration = configuration; + this.baseKey = convertToBaseKey(this); } public BCECPrivateKey( @@ -113,6 +120,7 @@ public BCECPrivateKey( this.attrCarrier = key.attrCarrier; this.publicKey = key.publicKey; this.configuration = key.configuration; + this.baseKey = key.baseKey; } public BCECPrivateKey( @@ -125,6 +133,7 @@ public BCECPrivateKey( this.algorithm = algorithm; this.d = params.getD(); this.configuration = configuration; + this.baseKey = params; if (spec == null) { @@ -155,6 +164,7 @@ public BCECPrivateKey( this.algorithm = algorithm; this.d = params.getD(); this.configuration = configuration; + this.baseKey = params; if (spec == null) { @@ -193,10 +203,11 @@ public BCECPrivateKey( this.d = params.getD(); this.ecSpec = null; this.configuration = configuration; + this.baseKey = params; } BCECPrivateKey( - String algorithm, + String algorithm, PrivateKeyInfo info, ProviderConfiguration configuration) throws IOException @@ -217,7 +228,7 @@ private void populateFromPrivKeyInfo(PrivateKeyInfo info) ASN1Encodable privKey = info.parsePrivateKey(); if (privKey instanceof ASN1Integer) { - ASN1Integer derD = ASN1Integer.getInstance(privKey); + ASN1Integer derD = ASN1Integer.getInstance(privKey); this.d = derD.getValue(); } @@ -228,6 +239,7 @@ private void populateFromPrivKeyInfo(PrivateKeyInfo info) this.d = ec.getKey(); this.publicKey = ec.getPublicKey(); } + this.baseKey = convertToBaseKey(this); } public String getAlgorithm() @@ -315,6 +327,11 @@ private PrivateKeyInfo getPrivateKeyInfo() return privateKeyInfo; } + public ECPrivateKeyParameters engineGetKeyParameters() + { + return baseKey; + } + public ECParameterSpec getParams() { return ecSpec; @@ -326,7 +343,7 @@ public org.bouncycastle.jce.spec.ECParameterSpec getParameters() { return null; } - + return EC5Util.convertSpec(ecSpec); } @@ -349,10 +366,10 @@ public BigInteger getD() { return d; } - + public void setBagAttribute( ASN1ObjectIdentifier oid, - ASN1Encodable attribute) + ASN1Encodable attribute) { attrCarrier.setBagAttribute(oid, attribute); } @@ -370,7 +387,7 @@ public Enumeration getBagAttributeKeys() public void setPointFormat(String style) { - withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); + withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); } public boolean equals(Object o) @@ -396,7 +413,7 @@ public boolean equals(Object o) } catch (IOException e) { - return false; + return false; } } @@ -450,4 +467,31 @@ private void writeObject( out.writeObject(this.getEncoded()); } + + private static ECPrivateKeyParameters convertToBaseKey(BCECPrivateKey key) + { + org.bouncycastle.jce.interfaces.ECPrivateKey k = (org.bouncycastle.jce.interfaces.ECPrivateKey)key; + org.bouncycastle.jce.spec.ECParameterSpec s = k.getParameters(); + + if (s == null) + { + s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); + } + + if (k.getParameters() instanceof ECNamedCurveParameterSpec) + { + String name = ((ECNamedCurveParameterSpec)k.getParameters()).getName(); + if (name != null) + { + return new ECPrivateKeyParameters( + k.getD(), + new ECNamedDomainParameters(ECNamedCurveTable.getOID(name), + s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); + } + } + + return new ECPrivateKeyParameters( + k.getD(), + new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); + } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java index 5669600c4f..ec97fe1758 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java @@ -2,6 +2,7 @@ import java.math.BigInteger; import java.security.InvalidKeyException; +import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; @@ -28,6 +29,13 @@ static AsymmetricKeyParameter generatePublicKeyParameter( return (key instanceof BCECPublicKey) ? ((BCECPublicKey)key).engineGetKeyParameters() : ECUtil.generatePublicKeyParameter(key); } + static AsymmetricKeyParameter generatePrivateKeyParameter( + PrivateKey key) + throws InvalidKeyException + { + return (key instanceof BCECPrivateKey) ? ((BCECPrivateKey)key).engineGetKeyParameters() : ECUtil.generatePrivateKeyParameter(key); + } + static X9ECParameters getDomainParametersFromGenSpec(ECGenParameterSpec genSpec, ProviderConfiguration configuration) { return getDomainParametersFromName(genSpec.getName(), configuration); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMCipherSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMCipherSpi.java index fca555a811..e8e190e9b0 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMCipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMCipherSpi.java @@ -381,7 +381,7 @@ static public class SM2withSha256 { public SM2withSha256() { - super(new SM2Engine(new SHA256Digest())); + super(new SM2Engine(SHA256Digest.newInstance())); } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMSignatureSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMSignatureSpi.java index 532e68b503..4b8c8e824c 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMSignatureSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMSignatureSpi.java @@ -197,7 +197,7 @@ static public class sha256WithSM2 { public sha256WithSM2() { - super(new SM2Signer(new SHA256Digest())); + super(new SM2Signer(SHA256Digest.newInstance())); } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java index 1ea3ef325a..e7f87fbe69 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java @@ -18,6 +18,7 @@ import javax.crypto.ShortBufferException; import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.InvalidCipherTextException; @@ -42,7 +43,7 @@ import org.bouncycastle.crypto.parsers.ECIESPublicKeyParser; import org.bouncycastle.crypto.util.DigestFactory; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi; -import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; +import org.bouncycastle.jcajce.provider.asymmetric.util.IESUtil; import org.bouncycastle.jcajce.provider.util.BadBlockException; import org.bouncycastle.jcajce.util.BCJcaJceHelper; import org.bouncycastle.jcajce.util.JcaJceHelper; @@ -83,17 +84,10 @@ public IESCipher(IESEngine engine, int ivLength) public int engineGetBlockSize() { - if (engine.getCipher() != null) - { - return engine.getCipher().getBlockSize(); - } - else - { - return 0; - } + BufferedBlockCipher cipher = engine.getCipher(); + return cipher == null ? 0 : cipher.getBlockSize(); } - public int engineGetKeySize(Key key) { if (key instanceof ECKey) @@ -106,7 +100,6 @@ public int engineGetKeySize(Key key) } } - public byte[] engineGetIV() { if (engineSpec != null) @@ -276,18 +269,11 @@ public void engineInit( otherKeyParameter = null; // NOTE: For secure usage, sender and receiver should agree on a fixed value for the nonce. -// if (engineSpec == null) -// { -// byte[] nonce = null; -// if (ivLength != 0 && opmode == Cipher.ENCRYPT_MODE) -// { -// nonce = new byte[ivLength]; -// random.nextBytes(nonce); -// } -// this.engineSpec = IESUtil.guessParameterSpec(engine.getCipher(), nonce); -// } -// else - if (engineSpec instanceof IESParameterSpec) + if (engineSpec == null && ivLength == 0) + { + this.engineSpec = IESUtil.guessParameterSpec(engine.getCipher(), null); + } + else if (engineSpec instanceof IESParameterSpec) { this.engineSpec = (IESParameterSpec)engineSpec; } @@ -315,7 +301,7 @@ else if (key instanceof IESKey) IESKey ieKey = (IESKey)key; this.key = ECUtils.generatePublicKeyParameter(ieKey.getPublic()); - this.otherKeyParameter = ECUtil.generatePrivateKeyParameter(ieKey.getPrivate()); + this.otherKeyParameter = ECUtils.generatePrivateKeyParameter(ieKey.getPrivate()); } else { @@ -326,14 +312,14 @@ else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) { if (key instanceof PrivateKey) { - this.key = ECUtil.generatePrivateKeyParameter((PrivateKey)key); + this.key = ECUtils.generatePrivateKeyParameter((PrivateKey)key); } else if (key instanceof IESKey) { IESKey ieKey = (IESKey)key; this.otherKeyParameter = ECUtils.generatePublicKeyParameter(ieKey.getPublic()); - this.key = ECUtil.generatePrivateKeyParameter(ieKey.getPrivate()); + this.key = ECUtils.generatePrivateKeyParameter(ieKey.getPrivate()); } else { @@ -417,9 +403,10 @@ public byte[] engineDoFinal( engineSpec.getMacKeySize(), engineSpec.getCipherKeySize()); - if (engineSpec.getNonce() != null) + byte[] engineSpecNonce = engineSpec.getNonce(); + if (engineSpecNonce != null) { - params = new ParametersWithIV(params, engineSpec.getNonce()); + params = new ParametersWithIV(params, engineSpecNonce); } final ECDomainParameters ecParams = ((ECKeyParameters)key).getParameters(); @@ -576,7 +563,7 @@ static public class ECIESwithDESedeCBC { public ECIESwithDESedeCBC() { - super(new CBCBlockCipher(new DESedeEngine()), 8); + super(CBCBlockCipher.newInstance(new DESedeEngine()), 8); } } @@ -585,7 +572,7 @@ static public class ECIESwithSHA256andDESedeCBC { public ECIESwithSHA256andDESedeCBC() { - super(new CBCBlockCipher(new DESedeEngine()), 8, DigestFactory.createSHA256(), DigestFactory.createSHA256()); + super(CBCBlockCipher.newInstance(new DESedeEngine()), 8, DigestFactory.createSHA256(), DigestFactory.createSHA256()); } } @@ -594,7 +581,7 @@ static public class ECIESwithSHA384andDESedeCBC { public ECIESwithSHA384andDESedeCBC() { - super(new CBCBlockCipher(new DESedeEngine()), 8, DigestFactory.createSHA384(), DigestFactory.createSHA384()); + super(CBCBlockCipher.newInstance(new DESedeEngine()), 8, DigestFactory.createSHA384(), DigestFactory.createSHA384()); } } @@ -603,7 +590,7 @@ static public class ECIESwithSHA512andDESedeCBC { public ECIESwithSHA512andDESedeCBC() { - super(new CBCBlockCipher(new DESedeEngine()), 8, DigestFactory.createSHA512(), DigestFactory.createSHA512()); + super(CBCBlockCipher.newInstance(new DESedeEngine()), 8, DigestFactory.createSHA512(), DigestFactory.createSHA512()); } } @@ -612,7 +599,7 @@ static public class ECIESwithAESCBC { public ECIESwithAESCBC() { - super(new CBCBlockCipher(new AESEngine()), 16); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), 16); } } @@ -621,7 +608,7 @@ static public class ECIESwithSHA256andAESCBC { public ECIESwithSHA256andAESCBC() { - super(new CBCBlockCipher(new AESEngine()), 16, DigestFactory.createSHA256(), DigestFactory.createSHA256()); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), 16, DigestFactory.createSHA256(), DigestFactory.createSHA256()); } } @@ -630,7 +617,7 @@ static public class ECIESwithSHA384andAESCBC { public ECIESwithSHA384andAESCBC() { - super(new CBCBlockCipher(new AESEngine()), 16, DigestFactory.createSHA384(), DigestFactory.createSHA384()); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), 16, DigestFactory.createSHA384(), DigestFactory.createSHA384()); } } @@ -639,7 +626,7 @@ static public class ECIESwithSHA512andAESCBC { public ECIESwithSHA512andAESCBC() { - super(new CBCBlockCipher(new AESEngine()), 16, DigestFactory.createSHA512(), DigestFactory.createSHA512()); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), 16, DigestFactory.createSHA512(), DigestFactory.createSHA512()); } } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESKEMCipher.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESKEMCipher.java index 0558032fc9..38dc3b967d 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESKEMCipher.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESKEMCipher.java @@ -38,7 +38,6 @@ import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.util.DigestFactory; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi; -import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.spec.IESKEMParameterSpec; import org.bouncycastle.jcajce.util.BCJcaJceHelper; import org.bouncycastle.jcajce.util.JcaJceHelper; @@ -244,7 +243,7 @@ else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) { if (key instanceof PrivateKey) { - this.key = ECUtil.generatePrivateKeyParameter((PrivateKey)key); + this.key = ECUtils.generatePrivateKeyParameter((PrivateKey)key); } else { diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java index 38e744626e..a7c9c3362f 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java @@ -29,7 +29,6 @@ import org.bouncycastle.crypto.params.MQVPublicParameters; import org.bouncycastle.crypto.util.DigestFactory; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseAgreementSpi; -import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.spec.DHUParameterSpec; import org.bouncycastle.jcajce.spec.MQVParameterSpec; import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec; @@ -195,9 +194,9 @@ protected void doInitFromKey(Key key, AlgorithmParameterSpec parameterSpec, Secu { MQVPrivateKey mqvPrivKey = (MQVPrivateKey)key; staticPrivKey = (ECPrivateKeyParameters) - ECUtil.generatePrivateKeyParameter(mqvPrivKey.getStaticPrivateKey()); + ECUtils.generatePrivateKeyParameter(mqvPrivKey.getStaticPrivateKey()); ephemPrivKey = (ECPrivateKeyParameters) - ECUtil.generatePrivateKeyParameter(mqvPrivKey.getEphemeralPrivateKey()); + ECUtils.generatePrivateKeyParameter(mqvPrivKey.getEphemeralPrivateKey()); ephemPubKey = null; if (mqvPrivKey.getEphemeralPublicKey() != null) @@ -211,9 +210,9 @@ protected void doInitFromKey(Key key, AlgorithmParameterSpec parameterSpec, Secu MQVParameterSpec mqvParameterSpec = (MQVParameterSpec)parameterSpec; staticPrivKey = (ECPrivateKeyParameters) - ECUtil.generatePrivateKeyParameter((PrivateKey)key); + ECUtils.generatePrivateKeyParameter((PrivateKey)key); ephemPrivKey = (ECPrivateKeyParameters) - ECUtil.generatePrivateKeyParameter(mqvParameterSpec.getEphemeralPrivateKey()); + ECUtils.generatePrivateKeyParameter(mqvParameterSpec.getEphemeralPrivateKey()); ephemPubKey = null; if (mqvParameterSpec.getEphemeralPublicKey() != null) @@ -245,9 +244,9 @@ else if (parameterSpec instanceof DHUParameterSpec) ECPublicKeyParameters ephemPubKey; staticPrivKey = (ECPrivateKeyParameters) - ECUtil.generatePrivateKeyParameter((PrivateKey)key); + ECUtils.generatePrivateKeyParameter((PrivateKey)key); ephemPrivKey = (ECPrivateKeyParameters) - ECUtil.generatePrivateKeyParameter(dheParameterSpec.getEphemeralPrivateKey()); + ECUtils.generatePrivateKeyParameter(dheParameterSpec.getEphemeralPrivateKey()); ephemPubKey = null; if (dheParameterSpec.getEphemeralPublicKey() != null) @@ -274,7 +273,7 @@ else if (parameterSpec instanceof DHUParameterSpec) { throw new InvalidAlgorithmParameterException("no KDF specified for UserKeyingMaterialSpec"); } - ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)ECUtil.generatePrivateKeyParameter((PrivateKey)key); + ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)ECUtils.generatePrivateKeyParameter((PrivateKey)key); this.parameters = privKey.getParameters(); ukmParameters = (parameterSpec instanceof UserKeyingMaterialSpec) ? ((UserKeyingMaterialSpec)parameterSpec).getUserKeyingMaterial() : null; ((BasicAgreement)agreement).init(privKey); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java index c6b7930db3..af7405a743 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java @@ -20,7 +20,6 @@ import org.bouncycastle.crypto.signers.StandardDSAEncoding; import org.bouncycastle.crypto.util.DigestFactory; import org.bouncycastle.jcajce.provider.asymmetric.util.DSABase; -import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; public class SignatureSpi extends DSABase @@ -43,7 +42,7 @@ protected void engineInitSign( PrivateKey privateKey) throws InvalidKeyException { - CipherParameters param = ECUtil.generatePrivateKeyParameter(privateKey); + CipherParameters param = ECUtils.generatePrivateKeyParameter(privateKey); digest.reset(); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/BCECGOST3410_2012PrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/BCECGOST3410_2012PrivateKey.java index 4b532f461f..64e44d96da 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/BCECGOST3410_2012PrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/BCECGOST3410_2012PrivateKey.java @@ -23,7 +23,6 @@ import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; @@ -31,6 +30,7 @@ import org.bouncycastle.asn1.x9.X9ECPoint; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; @@ -200,7 +200,8 @@ private void populateFromPrivKeyInfo(PrivateKeyInfo info) { ASN1Primitive p = info.getPrivateKeyAlgorithm().getParameters().toASN1Primitive(); - if (p instanceof ASN1Sequence && (ASN1Sequence.getInstance(p).size() == 2 || ASN1Sequence.getInstance(p).size() == 3)) + if (p instanceof ASN1Sequence && + (ASN1Sequence.getInstance(p).size() <= 3)) { gostParams = GOST3410PublicKeyAlgParameters.getInstance(info.getPrivateKeyAlgorithm().getParameters()); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/BCECGOST3410_2012PublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/BCECGOST3410_2012PublicKey.java index 26a42ff3a3..96cc09aced 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/BCECGOST3410_2012PublicKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/BCECGOST3410_2012PublicKey.java @@ -18,7 +18,6 @@ import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; @@ -27,6 +26,7 @@ import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECGOST3410Parameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; @@ -261,17 +261,28 @@ public byte[] getEncoded() { if (ecSpec instanceof ECNamedCurveSpec) { + ASN1ObjectIdentifier gostCurveOid = ECGOST3410NamedCurves.getOID(((ECNamedCurveSpec)ecSpec).getName()); if (is512) { params = new GOST3410PublicKeyAlgParameters( - ECGOST3410NamedCurves.getOID(((ECNamedCurveSpec)ecSpec).getName()), + gostCurveOid, RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512); } else { - params = new GOST3410PublicKeyAlgParameters( - ECGOST3410NamedCurves.getOID(((ECNamedCurveSpec)ecSpec).getName()), - RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256); + if (gostCurveOid.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetB) + || gostCurveOid.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetC) + || gostCurveOid.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetD)) + { + // RFC 9215 + params = new GOST3410PublicKeyAlgParameters(gostCurveOid, null); + } + else + { + params = new GOST3410PublicKeyAlgParameters( + gostCurveOid, + RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256); + } } } else @@ -438,17 +449,29 @@ public GOST3410PublicKeyAlgParameters getGostParams() // need to detect key size boolean is512 = (bX.bitLength() > 256); + ASN1ObjectIdentifier gostCurveOid = ECGOST3410NamedCurves.getOID(((ECNamedCurveSpec)ecSpec).getName()); if (is512) { this.gostParams = new GOST3410PublicKeyAlgParameters( - ECGOST3410NamedCurves.getOID(((ECNamedCurveSpec)ecSpec).getName()), + gostCurveOid, RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512); } else { - this.gostParams = new GOST3410PublicKeyAlgParameters( - ECGOST3410NamedCurves.getOID(((ECNamedCurveSpec)ecSpec).getName()), - RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256); + if (gostCurveOid.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetB) + || gostCurveOid.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetC) + || gostCurveOid.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetD)) + { + this.gostParams = new GOST3410PublicKeyAlgParameters( + gostCurveOid, + null); + } + else + { + this.gostParams = new GOST3410PublicKeyAlgParameters( + gostCurveOid, + RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256); + } } } return gostParams; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/KeyFactorySpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/KeyFactorySpi.java index 5b5ced5871..1f90727f9d 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/KeyFactorySpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/KeyFactorySpi.java @@ -12,8 +12,8 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jce.provider.BouncyCastleProvider; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/KeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/KeyPairGeneratorSpi.java index 4742303f60..3be4e0c159 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/KeyPairGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost12/KeyPairGeneratorSpi.java @@ -8,6 +8,7 @@ import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; @@ -18,6 +19,7 @@ import org.bouncycastle.crypto.params.ECNamedDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; import org.bouncycastle.jcajce.spec.GOST3410ParameterSpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -118,7 +120,17 @@ else if (params instanceof ECGenParameterSpec || params instanceof ECNamedCurveG curveName = ((ECNamedCurveGenParameterSpec)params).getName(); } - init(new GOST3410ParameterSpec(curveName), random); + ASN1ObjectIdentifier curveOid = ECGOST3410NamedCurves.getOID(curveName); + if (curveOid.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetB) + || curveOid.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetC) + || curveOid.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetD)) + { + init(new GOST3410ParameterSpec(ECGOST3410NamedCurves.getOID(curveName), null), random); + } + else + { + init(new GOST3410ParameterSpec(curveName), random); + } } else if (params == null && BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa() != null) { diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCEdDSAPrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCEdDSAPrivateKey.java index d5875cd304..8444dea21c 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCEdDSAPrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCEdDSAPrivateKey.java @@ -7,7 +7,6 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; @@ -15,6 +14,7 @@ import org.bouncycastle.crypto.params.Ed448PrivateKeyParameters; import org.bouncycastle.crypto.params.Ed448PublicKeyParameters; import org.bouncycastle.crypto.util.PrivateKeyInfoFactory; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.jcajce.interfaces.EdDSAPrivateKey; import org.bouncycastle.jcajce.interfaces.EdDSAPublicKey; import org.bouncycastle.util.Arrays; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCEdDSAPublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCEdDSAPublicKey.java index 504eda19d4..dc19a4a000 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCEdDSAPublicKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCEdDSAPublicKey.java @@ -6,11 +6,11 @@ import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; import org.bouncycastle.crypto.params.Ed448PublicKeyParameters; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.jcajce.interfaces.EdDSAPublicKey; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Properties; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCXDHPrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCXDHPrivateKey.java index 1c0958ae3b..ec917ae9e1 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCXDHPrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCXDHPrivateKey.java @@ -7,7 +7,6 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; @@ -15,6 +14,7 @@ import org.bouncycastle.crypto.params.X448PrivateKeyParameters; import org.bouncycastle.crypto.params.X448PublicKeyParameters; import org.bouncycastle.crypto.util.PrivateKeyInfoFactory; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.jcajce.interfaces.XDHPrivateKey; import org.bouncycastle.jcajce.interfaces.XDHPublicKey; import org.bouncycastle.util.Arrays; @@ -60,11 +60,16 @@ public class BCXDHPrivateKey private void populateFromPrivateKeyInfo(PrivateKeyInfo keyInfo) throws IOException { - byte[] encoding = keyInfo.getPrivateKey().getOctets(); + int privateKeyLength = keyInfo.getPrivateKeyLength(); + byte[] encoding; // exact length of X25519/X448 secret used in Java 11 - if (encoding.length != X25519PrivateKeyParameters.KEY_SIZE && - encoding.length != X448PrivateKeyParameters.KEY_SIZE) + if (privateKeyLength == X25519PrivateKeyParameters.KEY_SIZE || + privateKeyLength == X448PrivateKeyParameters.KEY_SIZE) + { + encoding = keyInfo.getPrivateKey().getOctets(); + } + else { encoding = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCXDHPublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCXDHPublicKey.java index fb6cee747d..48ab3f77f0 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCXDHPublicKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCXDHPublicKey.java @@ -7,11 +7,11 @@ import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.X25519PublicKeyParameters; import org.bouncycastle.crypto.params.X448PublicKeyParameters; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.jcajce.interfaces.XDHPublicKey; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Properties; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/IESCipher.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/IESCipher.java index 205f40f639..28f14e1872 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/IESCipher.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/IESCipher.java @@ -19,6 +19,7 @@ import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.InvalidCipherTextException; @@ -46,6 +47,7 @@ import org.bouncycastle.crypto.util.DigestFactory; import org.bouncycastle.jcajce.interfaces.XDHKey; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi; +import org.bouncycastle.jcajce.provider.asymmetric.util.IESUtil; import org.bouncycastle.jcajce.provider.util.BadBlockException; import org.bouncycastle.jcajce.util.BCJcaJceHelper; import org.bouncycastle.jcajce.util.JcaJceHelper; @@ -83,17 +85,10 @@ public IESCipher(IESEngine engine, int ivLength) public int engineGetBlockSize() { - if (engine.getCipher() != null) - { - return engine.getCipher().getBlockSize(); - } - else - { - return 0; - } + BufferedBlockCipher cipher = engine.getCipher(); + return cipher == null ? 0 : cipher.getBlockSize(); } - public int engineGetKeySize(Key key) { if (key instanceof XDHKey) @@ -118,7 +113,6 @@ else if ("X448".equalsIgnoreCase(algorithm)) } } - public byte[] engineGetIV() { if (engineSpec != null) @@ -281,18 +275,11 @@ public void engineInit( otherKeyParameter = null; // NOTE: For secure usage, sender and receiver should agree on a fixed value for the nonce. -// if (engineSpec == null) -// { -// byte[] nonce = null; -// if (ivLength != 0 && opmode == Cipher.ENCRYPT_MODE) -// { -// nonce = new byte[ivLength]; -// random.nextBytes(nonce); -// } -// this.engineSpec = IESUtil.guessParameterSpec(engine.getCipher(), nonce); -// } -// else - if (engineSpec instanceof IESParameterSpec) + if (engineSpec == null && ivLength == 0) + { + this.engineSpec = IESUtil.guessParameterSpec(engine.getCipher(), null); + } + else if (engineSpec instanceof IESParameterSpec) { this.engineSpec = (IESParameterSpec)engineSpec; } @@ -408,9 +395,10 @@ public byte[] engineDoFinal( engineSpec.getMacKeySize(), engineSpec.getCipherKeySize()); - if (engineSpec.getNonce() != null) + byte[] engineSpecNonce = engineSpec.getNonce(); + if (engineSpecNonce != null) { - params = new ParametersWithIV(params, engineSpec.getNonce()); + params = new ParametersWithIV(params, engineSpecNonce); } if (otherKeyParameter != null) @@ -567,7 +555,7 @@ static public class XIESwithDESedeCBC { public XIESwithDESedeCBC() { - super(new CBCBlockCipher(new DESedeEngine()), 8); + super(CBCBlockCipher.newInstance(new DESedeEngine()), 8); } } @@ -576,7 +564,7 @@ static public class XIESwithSHA256andDESedeCBC { public XIESwithSHA256andDESedeCBC() { - super(new CBCBlockCipher(new DESedeEngine()), 8, DigestFactory.createSHA256(), DigestFactory.createSHA256()); + super(CBCBlockCipher.newInstance(new DESedeEngine()), 8, DigestFactory.createSHA256(), DigestFactory.createSHA256()); } } @@ -585,7 +573,7 @@ static public class XIESwithSHA384andDESedeCBC { public XIESwithSHA384andDESedeCBC() { - super(new CBCBlockCipher(new DESedeEngine()), 8, DigestFactory.createSHA384(), DigestFactory.createSHA384()); + super(CBCBlockCipher.newInstance(new DESedeEngine()), 8, DigestFactory.createSHA384(), DigestFactory.createSHA384()); } } @@ -594,7 +582,7 @@ static public class XIESwithSHA512andDESedeCBC { public XIESwithSHA512andDESedeCBC() { - super(new CBCBlockCipher(new DESedeEngine()), 8, DigestFactory.createSHA512(), DigestFactory.createSHA512()); + super(CBCBlockCipher.newInstance(new DESedeEngine()), 8, DigestFactory.createSHA512(), DigestFactory.createSHA512()); } } @@ -603,7 +591,7 @@ static public class XIESwithAESCBC { public XIESwithAESCBC() { - super(new CBCBlockCipher(new AESEngine()), 16); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), 16); } } @@ -612,7 +600,7 @@ static public class XIESwithSHA256andAESCBC { public XIESwithSHA256andAESCBC() { - super(new CBCBlockCipher(new AESEngine()), 16, DigestFactory.createSHA256(), DigestFactory.createSHA256()); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), 16, DigestFactory.createSHA256(), DigestFactory.createSHA256()); } } @@ -621,7 +609,7 @@ static public class XIESwithSHA384andAESCBC { public XIESwithSHA384andAESCBC() { - super(new CBCBlockCipher(new AESEngine()), 16, DigestFactory.createSHA384(), DigestFactory.createSHA384()); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), 16, DigestFactory.createSHA384(), DigestFactory.createSHA384()); } } @@ -630,7 +618,7 @@ static public class XIESwithSHA512andAESCBC { public XIESwithSHA512andAESCBC() { - super(new CBCBlockCipher(new AESEngine()), 16, DigestFactory.createSHA512(), DigestFactory.createSHA512()); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), 16, DigestFactory.createSHA512(), DigestFactory.createSHA512()); } } } \ No newline at end of file diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyAgreementSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyAgreementSpi.java index 9cadfbe604..dae9d9e0fa 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyAgreementSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyAgreementSpi.java @@ -14,6 +14,7 @@ import org.bouncycastle.crypto.agreement.X448Agreement; import org.bouncycastle.crypto.agreement.XDHUnifiedAgreement; import org.bouncycastle.crypto.agreement.kdf.ConcatenationKDFGenerator; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; @@ -68,10 +69,11 @@ else if (priv instanceof X448PrivateKeyParameters) } else { - throw new IllegalStateException("unsupported private key type"); + throw new InvalidKeyException("unsupported private key type"); } ukmParameters = null; + ukmParametersSalt = null; if (params instanceof DHUParameterSpec) { if (kaAlgorithm.indexOf('U') < 0) @@ -98,6 +100,7 @@ else if (params != null) throw new InvalidAlgorithmParameterException("no KDF specified for UserKeyingMaterialSpec"); } this.ukmParameters = ((UserKeyingMaterialSpec)params).getUserKeyingMaterial(); + this.ukmParametersSalt = ((UserKeyingMaterialSpec)params).getSalt(); } else { @@ -315,4 +318,22 @@ public X448UwithSHA512KDF() super("X448UwithSHA512KDF", new KDF2BytesGenerator(DigestFactory.createSHA512())); } } + + public final static class X448withSHA512HKDF + extends KeyAgreementSpi + { + public X448withSHA512HKDF() + { + super("X448withSHA512HKDF", new HKDFBytesGenerator(DigestFactory.createSHA512())); + } + } + + public final static class X25519withSHA256HKDF + extends KeyAgreementSpi + { + public X25519withSHA256HKDF() + { + super("X25519withSHA256HKDF", new HKDFBytesGenerator(DigestFactory.createSHA256())); + } + } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java index 2d6aa67c77..d33fea6931 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java @@ -14,7 +14,6 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; @@ -26,6 +25,7 @@ import org.bouncycastle.crypto.params.X448PublicKeyParameters; import org.bouncycastle.crypto.util.OpenSSHPrivateKeyUtil; import org.bouncycastle.crypto.util.OpenSSHPublicKeyUtil; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.jcajce.interfaces.EdDSAPublicKey; import org.bouncycastle.jcajce.interfaces.XDHPublicKey; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java index 7fca5cae81..1268706469 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java @@ -7,7 +7,6 @@ import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.CryptoServicesRegistrar; @@ -19,6 +18,7 @@ import org.bouncycastle.crypto.params.Ed448KeyGenerationParameters; import org.bouncycastle.crypto.params.X25519KeyGenerationParameters; import org.bouncycastle.crypto.params.X448KeyGenerationParameters; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.spec.EdDSAParameterSpec; import org.bouncycastle.jcajce.spec.XDHParameterSpec; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/SignatureSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/SignatureSpi.java index 19795eb29d..5733be45c2 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/SignatureSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/SignatureSpi.java @@ -46,7 +46,7 @@ else if (pub instanceof Ed448PublicKeyParameters) } else { - throw new IllegalStateException("unsupported public key type"); + throw new InvalidKeyException("unsupported public key type"); } signer.init(false, pub); @@ -67,7 +67,7 @@ else if (priv instanceof Ed448PrivateKeyParameters) } else { - throw new IllegalStateException("unsupported private key type"); + throw new InvalidKeyException("unsupported private key type"); } signer.init(true, priv); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParametersSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParametersSpi.java index 9280f80190..cea8a6e2b9 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParametersSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParametersSpi.java @@ -8,7 +8,7 @@ import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.oiw.ElGamalParameter; +import org.bouncycastle.internal.asn1.oiw.ElGamalParameter; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; import org.bouncycastle.jce.spec.ElGamalParameterSpec; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPrivateKey.java index f0f83fa454..8c6a9627a8 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPrivateKey.java @@ -14,11 +14,11 @@ import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.oiw.ElGamalParameter; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; +import org.bouncycastle.internal.asn1.oiw.ElGamalParameter; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPublicKey.java index cd31cc57b9..78c5f49b13 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPublicKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPublicKey.java @@ -11,11 +11,11 @@ import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; -import org.bouncycastle.asn1.oiw.ElGamalParameter; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; +import org.bouncycastle.internal.asn1.oiw.ElGamalParameter; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jce.interfaces.ElGamalPublicKey; import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.jce.spec.ElGamalPublicKeySpec; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/KeyFactorySpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/KeyFactorySpi.java index 92e655f776..426d26413c 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/KeyFactorySpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/KeyFactorySpi.java @@ -14,11 +14,11 @@ import javax.crypto.spec.DHPublicKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; import org.bouncycastle.jce.interfaces.ElGamalPublicKey; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/gost/BCGOST3410PrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/gost/BCGOST3410PrivateKey.java index 8992d5faeb..2fc4dba0b4 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/gost/BCGOST3410PrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/gost/BCGOST3410PrivateKey.java @@ -179,7 +179,7 @@ public boolean equals( return this.getX().equals(other.getX()) && this.getParameters().getPublicKeyParameters().equals(other.getParameters().getPublicKeyParameters()) - && this.getParameters().getDigestParamSetOID().equals(other.getParameters().getDigestParamSetOID()) + && compareObj(this.getParameters().getDigestParamSetOID(), other.getParameters().getDigestParamSetOID()) && compareObj(this.getParameters().getEncryptionParamSetOID(), other.getParameters().getEncryptionParamSetOID()); } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java index 7aba0e128c..ebbc2345f2 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java @@ -60,12 +60,13 @@ protected byte[] engineGetEncoded() v.add(new DERTaggedObject(false, 1, new DEROctetString(currentSpec.getEncodingV()))); } v.add(new ASN1Integer(currentSpec.getMacKeySize())); - if (currentSpec.getNonce() != null) + byte[] currentSpecNonce = currentSpec.getNonce(); + if (currentSpecNonce != null) { ASN1EncodableVector cV = new ASN1EncodableVector(); cV.add(new ASN1Integer(currentSpec.getCipherKeySize())); - cV.add(new DEROctetString(currentSpec.getNonce())); + cV.add(new DEROctetString(currentSpecNonce)); v.add(new DERSequence(cV)); } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/BCMLDSAPrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/BCMLDSAPrivateKey.java new file mode 100644 index 0000000000..f1dc16f2d9 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/BCMLDSAPrivateKey.java @@ -0,0 +1,138 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mldsa; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.jcajce.interfaces.MLDSAPrivateKey; +import org.bouncycastle.jcajce.interfaces.MLDSAPublicKey; +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; +import org.bouncycastle.pqc.jcajce.provider.util.KeyUtil; +import org.bouncycastle.util.Arrays; + +public class BCMLDSAPrivateKey + implements MLDSAPrivateKey +{ + private static final long serialVersionUID = 1L; + + private transient MLDSAPrivateKeyParameters params; + private transient String algorithm; + private transient byte[] encoding; + private transient ASN1Set attributes; + + public BCMLDSAPrivateKey( + MLDSAPrivateKeyParameters params) + { + this.params = params; + algorithm = MLDSAParameterSpec.fromName(params.getParameters().getName()).getName().toUpperCase(); + } + + public BCMLDSAPrivateKey(PrivateKeyInfo keyInfo) + throws IOException + { + init(keyInfo); + } + + private void init(PrivateKeyInfo keyInfo) + throws IOException + { + init((MLDSAPrivateKeyParameters)PrivateKeyFactory.createKey(keyInfo), keyInfo.getAttributes()); + } + + private void init(MLDSAPrivateKeyParameters params, ASN1Set attributes) + { + this.attributes = attributes; + this.params = params; + algorithm = MLDSAParameterSpec.fromName(params.getParameters().getName()).getName().toUpperCase(); + } + + /** + * Compare this ML-DSA private key with another object. + * + * @param o the other object + * @return the result of the comparison + */ + public boolean equals(Object o) + { + if (o == this) + { + return true; + } + + if (o instanceof BCMLDSAPrivateKey) + { + BCMLDSAPrivateKey otherKey = (BCMLDSAPrivateKey)o; + + return Arrays.areEqual(params.getEncoded(), otherKey.params.getEncoded()); + } + + return false; + } + + public int hashCode() + { + return Arrays.hashCode(params.getEncoded()); + } + + /** + * @return name of the algorithm - "ML-DSA" + */ + public final String getAlgorithm() + { + return algorithm; + } + + public byte[] getEncoded() + { + if (encoding == null) + { + encoding = KeyUtil.getEncodedPrivateKeyInfo(params, attributes); + } + + return Arrays.clone(encoding); + } + + public MLDSAPublicKey getPublicKey() + { + return new BCMLDSAPublicKey(params.getPublicKeyParameters()); + } + + public MLDSAParameterSpec getParameterSpec() + { + return MLDSAParameterSpec.fromName(params.getParameters().getName()); + } + + public String getFormat() + { + return "PKCS#8"; + } + + MLDSAPrivateKeyParameters getKeyParams() + { + return params; + } + + private void readObject( + ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + + byte[] enc = (byte[])in.readObject(); + + init(PrivateKeyInfo.getInstance(enc)); + } + + private void writeObject( + ObjectOutputStream out) + throws IOException + { + out.defaultWriteObject(); + + out.writeObject(this.getEncoded()); + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/BCMLDSAPublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/BCMLDSAPublicKey.java new file mode 100644 index 0000000000..a259a32a64 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/BCMLDSAPublicKey.java @@ -0,0 +1,125 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mldsa; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.jcajce.interfaces.MLDSAPublicKey; +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAPublicKeyParameters; +import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; +import org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory; +import org.bouncycastle.util.Arrays; + +public class BCMLDSAPublicKey + implements MLDSAPublicKey +{ + private static final long serialVersionUID = 1L; + + private transient MLDSAPublicKeyParameters params; + + public BCMLDSAPublicKey( + MLDSAPublicKeyParameters params) + { + this.params = params; + } + + public BCMLDSAPublicKey(SubjectPublicKeyInfo keyInfo) + throws IOException + { + init(keyInfo); + } + + private void init(SubjectPublicKeyInfo keyInfo) + throws IOException + { + this.params = (MLDSAPublicKeyParameters)PublicKeyFactory.createKey(keyInfo); + } + + /** + * Compare this ML-DSA public key with another object. + * + * @param o the other object + * @return the result of the comparison + */ + public boolean equals(Object o) + { + if (o == this) + { + return true; + } + + if (o instanceof BCMLDSAPublicKey) + { + BCMLDSAPublicKey otherKey = (BCMLDSAPublicKey)o; + + return Arrays.areEqual(params.getEncoded(), otherKey.params.getEncoded()); + } + + return false; + } + + public int hashCode() + { + return Arrays.hashCode(params.getEncoded()); + } + + /** + * @return name of the algorithm - "ML-DSA" followed by the parameter type. + */ + public final String getAlgorithm() + { + return MLDSAParameterSpec.fromName(params.getParameters().getName()).getName(); + } + + public byte[] getEncoded() + { + try + { + SubjectPublicKeyInfo pki = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(params); + + return pki.getEncoded(); + } + catch (IOException e) + { + return null; + } + } + + public String getFormat() + { + return "X.509"; + } + + public MLDSAParameterSpec getParameterSpec() + { + return MLDSAParameterSpec.fromName(params.getParameters().getName()); + } + + CipherParameters getKeyParams() + { + return params; + } + + private void readObject( + ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + + byte[] enc = (byte[])in.readObject(); + + init(SubjectPublicKeyInfo.getInstance(enc)); + } + + private void writeObject( + ObjectOutputStream out) + throws IOException + { + out.defaultWriteObject(); + + out.writeObject(this.getEncoded()); + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/HashSignatureSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/HashSignatureSpi.java new file mode 100644 index 0000000000..dfe3bd8203 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/HashSignatureSpi.java @@ -0,0 +1,194 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mldsa; + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.SignatureException; +import java.security.spec.AlgorithmParameterSpec; + +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; +import org.bouncycastle.pqc.crypto.mldsa.HashMLDSASigner; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAParameters; + +public class HashSignatureSpi + extends java.security.Signature +{ + private HashMLDSASigner signer; + private MLDSAParameters parameters; + + protected HashSignatureSpi(HashMLDSASigner signer) + { + super("HashMLDSA"); + + this.signer = signer; + this.parameters = null; + } + + protected HashSignatureSpi(HashMLDSASigner signer, MLDSAParameters parameters) + { + super(MLDSAParameterSpec.fromName(parameters.getName()).getName()); + + this.signer = signer; + this.parameters = parameters; + } + + protected void engineInitVerify(PublicKey publicKey) + throws InvalidKeyException + { + if (publicKey instanceof BCMLDSAPublicKey) + { + BCMLDSAPublicKey key = (BCMLDSAPublicKey)publicKey; + + CipherParameters param = key.getKeyParams(); + + if (parameters != null) + { + String canonicalAlg = MLDSAParameterSpec.fromName(parameters.getName()).getName(); + if (!canonicalAlg.equals(key.getAlgorithm())) + { + throw new InvalidKeyException("signature configured for " + canonicalAlg); + } + } + + signer.init(false, param); + } + else + { + throw new InvalidKeyException("unknown public key passed to ML-DSA"); + } + } + + protected void engineInitSign(PrivateKey privateKey, SecureRandom random) + throws InvalidKeyException + { + this.appRandom = random; + engineInitSign(privateKey); + } + + protected void engineInitSign(PrivateKey privateKey) + throws InvalidKeyException + { + if (privateKey instanceof BCMLDSAPrivateKey) + { + BCMLDSAPrivateKey key = (BCMLDSAPrivateKey)privateKey; + + CipherParameters param = key.getKeyParams(); + + if (parameters != null) + { + String canonicalAlg = MLDSAParameterSpec.fromName(parameters.getName()).getName(); + if (!canonicalAlg.equals(key.getAlgorithm())) + { + throw new InvalidKeyException("signature configured for " + canonicalAlg); + } + } + + if (appRandom != null) + { + signer.init(true, new ParametersWithRandom(param, appRandom)); + } + else + { + signer.init(true, param); + } + } + else + { + throw new InvalidKeyException("unknown private key passed to ML-DSA"); + } + } + + protected void engineUpdate(byte b) + throws SignatureException + { + signer.update(b); + } + + protected void engineUpdate(byte[] b, int off, int len) + throws SignatureException + { + signer.update(b, off, len); + } + + protected byte[] engineSign() + throws SignatureException + { + try + { + return signer.generateSignature(); + } + catch (Exception e) + { + throw new SignatureException(e.toString()); + } + } + + protected boolean engineVerify(byte[] sigBytes) + throws SignatureException + { + return signer.verifySignature(sigBytes); + } + + protected void engineSetParameter(AlgorithmParameterSpec params) + { + // TODO + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + /** + * @deprecated replaced with #engineSetParameter(java.security.spec.AlgorithmParameterSpec) + */ + protected void engineSetParameter(String param, Object value) + { + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + /** + * @deprecated + */ + protected Object engineGetParameter(String param) + { + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + + public static class MLDSA + extends HashSignatureSpi + { + public MLDSA() + { + super(new HashMLDSASigner()); + } + } + public static class MLDSA44 + extends HashSignatureSpi + { + public MLDSA44() + { + super(new HashMLDSASigner(), MLDSAParameters.ml_dsa_44_with_sha512); + } + } + + public static class MLDSA65 + extends HashSignatureSpi + { + public MLDSA65() + { + super(new HashMLDSASigner(), MLDSAParameters.ml_dsa_65_with_sha512); + } + } + + public static class MLDSA87 + extends HashSignatureSpi + { + public MLDSA87() + throws NoSuchAlgorithmException + { + super(new HashMLDSASigner(), MLDSAParameters.ml_dsa_87_with_sha512); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/MLDSAKeyFactorySpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/MLDSAKeyFactorySpi.java new file mode 100644 index 0000000000..55f96011ff --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/MLDSAKeyFactorySpi.java @@ -0,0 +1,172 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mldsa; + +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashSet; +import java.util.Set; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.pqc.jcajce.provider.util.BaseKeyFactorySpi; + +public class MLDSAKeyFactorySpi + extends BaseKeyFactorySpi +{ + private static final Set pureKeyOids = new HashSet(); + private static final Set hashKeyOids = new HashSet(); + + static + { + pureKeyOids.add(NISTObjectIdentifiers.id_ml_dsa_44); + pureKeyOids.add(NISTObjectIdentifiers.id_ml_dsa_65); + pureKeyOids.add(NISTObjectIdentifiers.id_ml_dsa_87); + + hashKeyOids.add(NISTObjectIdentifiers.id_ml_dsa_44); + hashKeyOids.add(NISTObjectIdentifiers.id_ml_dsa_65); + hashKeyOids.add(NISTObjectIdentifiers.id_ml_dsa_87); + hashKeyOids.add(NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512); + hashKeyOids.add(NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512); + hashKeyOids.add(NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512); + } + + public MLDSAKeyFactorySpi(Set keyOids) + { + super(keyOids); + } + + public MLDSAKeyFactorySpi(ASN1ObjectIdentifier keyOid) + { + super(keyOid); + } + + public final KeySpec engineGetKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException + { + if (key instanceof BCMLDSAPrivateKey) + { + if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) + { + return new PKCS8EncodedKeySpec(key.getEncoded()); + } + } + else if (key instanceof BCMLDSAPublicKey) + { + if (X509EncodedKeySpec.class.isAssignableFrom(keySpec)) + { + return new X509EncodedKeySpec(key.getEncoded()); + } + } + else + { + throw new InvalidKeySpecException("Unsupported key type: " + + key.getClass() + "."); + } + + throw new InvalidKeySpecException("Unknown key specification: " + + keySpec + "."); + } + + public final Key engineTranslateKey(Key key) + throws InvalidKeyException + { + if (key instanceof BCMLDSAPrivateKey || key instanceof BCMLDSAPublicKey) + { + return key; + } + + throw new InvalidKeyException("Unsupported key type"); + } + + public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) + throws IOException + { + return new BCMLDSAPrivateKey(keyInfo); + } + + public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) + throws IOException + { + return new BCMLDSAPublicKey(keyInfo); + } + + public static class Pure + extends MLDSAKeyFactorySpi + { + public Pure() + { + super(pureKeyOids); + } + } + + public static class MLDSA44 + extends MLDSAKeyFactorySpi + { + public MLDSA44() + { + super(NISTObjectIdentifiers.id_ml_dsa_44); + } + } + + public static class MLDSA65 + extends MLDSAKeyFactorySpi + { + public MLDSA65() + { + super(NISTObjectIdentifiers.id_ml_dsa_65); + } + } + + public static class MLDSA87 + extends MLDSAKeyFactorySpi + { + public MLDSA87() + { + super(NISTObjectIdentifiers.id_ml_dsa_87); + } + } + + public static class Hash + extends MLDSAKeyFactorySpi + { + public Hash() + { + super(hashKeyOids); + } + } + + public static class HashMLDSA44 + extends MLDSAKeyFactorySpi + { + public HashMLDSA44() + { + super(NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512); + } + } + + public static class HashMLDSA65 + extends MLDSAKeyFactorySpi + { + public HashMLDSA65() + { + super(NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512); + } + } + + public static class HashMLDSA87 + extends MLDSAKeyFactorySpi + { + public HashMLDSA87() + { + super(NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/MLDSAKeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/MLDSAKeyPairGeneratorSpi.java new file mode 100644 index 0000000000..906e8a59a1 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/MLDSAKeyPairGeneratorSpi.java @@ -0,0 +1,214 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mldsa; + +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; +import java.util.HashMap; +import java.util.Map; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAKeyPairGenerator; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAParameters; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAPublicKeyParameters; +import org.bouncycastle.pqc.jcajce.provider.util.SpecUtil; +import org.bouncycastle.util.Strings; + +public class MLDSAKeyPairGeneratorSpi + extends java.security.KeyPairGenerator +{ + private static Map parameters = new HashMap(); + + static + { + parameters.put(MLDSAParameterSpec.ml_dsa_44.getName(), MLDSAParameters.ml_dsa_44); + parameters.put(MLDSAParameterSpec.ml_dsa_65.getName(), MLDSAParameters.ml_dsa_65); + parameters.put(MLDSAParameterSpec.ml_dsa_87.getName(), MLDSAParameters.ml_dsa_87); + parameters.put(MLDSAParameterSpec.ml_dsa_44_with_sha512.getName(), MLDSAParameters.ml_dsa_44_with_sha512); + parameters.put(MLDSAParameterSpec.ml_dsa_65_with_sha512.getName(), MLDSAParameters.ml_dsa_65_with_sha512); + parameters.put(MLDSAParameterSpec.ml_dsa_87_with_sha512.getName(), MLDSAParameters.ml_dsa_87_with_sha512); + } + + private final MLDSAParameters mldsaParameters; + MLDSAKeyGenerationParameters param; + MLDSAKeyPairGenerator engine = new MLDSAKeyPairGenerator(); + + SecureRandom random = CryptoServicesRegistrar.getSecureRandom(); + boolean initialised = false; + + public MLDSAKeyPairGeneratorSpi(String name) + { + super(name); + this.mldsaParameters = null; + } + + protected MLDSAKeyPairGeneratorSpi(MLDSAParameterSpec paramSpec) + { + super(Strings.toUpperCase(paramSpec.getName())); + this.mldsaParameters = (MLDSAParameters)parameters.get(paramSpec.getName()); + + if (param == null) + { + param = new MLDSAKeyGenerationParameters(random, mldsaParameters); + } + + engine.init(param); + initialised = true; + } + + public void initialize( + int strength, + SecureRandom random) + { + throw new IllegalArgumentException("use AlgorithmParameterSpec"); + } + + public void initialize( + AlgorithmParameterSpec params, + SecureRandom random) + throws InvalidAlgorithmParameterException + { + String name = getNameFromParams(params); + + if (name != null && parameters.containsKey(name)) + { + MLDSAParameters mldsaParams = (MLDSAParameters)parameters.get(name); + + param = new MLDSAKeyGenerationParameters(random, (MLDSAParameters)parameters.get(name)); + + if (mldsaParameters != null && !mldsaParams.getName().equals(mldsaParameters.getName())) + { + throw new InvalidAlgorithmParameterException("key pair generator locked to " + MLDSAParameterSpec.fromName(mldsaParameters.getName()).getName()); + } + engine.init(param); + initialised = true; + } + else + { + throw new InvalidAlgorithmParameterException("invalid ParameterSpec: " + params); + } + } + + + public KeyPair generateKeyPair() + { + if (!initialised) + { + if (this.getAlgorithm().startsWith("HASH")) + { + param = new MLDSAKeyGenerationParameters(random, MLDSAParameters.ml_dsa_87_with_sha512); + } + else + { + param = new MLDSAKeyGenerationParameters(random, MLDSAParameters.ml_dsa_87); + } + + engine.init(param); + initialised = true; + } + + AsymmetricCipherKeyPair pair = engine.generateKeyPair(); + MLDSAPublicKeyParameters pub = (MLDSAPublicKeyParameters)pair.getPublic(); + MLDSAPrivateKeyParameters priv = (MLDSAPrivateKeyParameters)pair.getPrivate(); + + return new KeyPair(new BCMLDSAPublicKey(pub), new BCMLDSAPrivateKey(priv)); + } + + private static String getNameFromParams(AlgorithmParameterSpec paramSpec) + { + if (paramSpec instanceof MLDSAParameterSpec) + { + MLDSAParameterSpec params = (MLDSAParameterSpec)paramSpec; + return params.getName(); + } + else + { + return Strings.toLowerCase(SpecUtil.getNameFrom(paramSpec)); + } + } + + public static class Pure + extends MLDSAKeyPairGeneratorSpi + { + public Pure() + throws NoSuchAlgorithmException + { + super("ML-DSA"); + } + } + + public static class MLDSA44 + extends MLDSAKeyPairGeneratorSpi + { + public MLDSA44() + throws NoSuchAlgorithmException + { + super(MLDSAParameterSpec.ml_dsa_44); + } + } + + public static class MLDSA65 + extends MLDSAKeyPairGeneratorSpi + { + public MLDSA65() + throws NoSuchAlgorithmException + { + super(MLDSAParameterSpec.ml_dsa_65); + } + } + + public static class MLDSA87 + extends MLDSAKeyPairGeneratorSpi + { + public MLDSA87() + throws NoSuchAlgorithmException + { + super(MLDSAParameterSpec.ml_dsa_87); + } + } + + public static class Hash + extends MLDSAKeyPairGeneratorSpi + { + public Hash() + throws NoSuchAlgorithmException + { + super("HASH-ML-DSA"); + } + } + + public static class MLDSA44withSHA512 + extends MLDSAKeyPairGeneratorSpi + { + public MLDSA44withSHA512() + throws NoSuchAlgorithmException + { + super(MLDSAParameterSpec.ml_dsa_44_with_sha512); + } + } + + public static class MLDSA65withSHA512 + extends MLDSAKeyPairGeneratorSpi + { + public MLDSA65withSHA512() + throws NoSuchAlgorithmException + { + super(MLDSAParameterSpec.ml_dsa_65_with_sha512); + } + } + + public static class MLDSA87withSHA512 + extends MLDSAKeyPairGeneratorSpi + { + public MLDSA87withSHA512() + throws NoSuchAlgorithmException + { + super(MLDSAParameterSpec.ml_dsa_87_with_sha512); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/SignatureSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/SignatureSpi.java new file mode 100644 index 0000000000..11eb0f57df --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/SignatureSpi.java @@ -0,0 +1,206 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mldsa; + +import java.io.ByteArrayOutputStream; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.SignatureException; +import java.security.spec.AlgorithmParameterSpec; + +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; +import org.bouncycastle.pqc.crypto.mldsa.MLDSAParameters; +import org.bouncycastle.pqc.crypto.mldsa.MLDSASigner; + +public class SignatureSpi + extends java.security.Signature +{ + private ByteArrayOutputStream bOut; + private MLDSASigner signer; + private MLDSAParameters parameters; + + protected SignatureSpi(MLDSASigner signer) + { + super("MLDSA"); + + this.bOut = new ByteArrayOutputStream(); + this.signer = signer; + this.parameters = null; + } + + protected SignatureSpi(MLDSASigner signer, MLDSAParameters parameters) + { + super(MLDSAParameterSpec.fromName(parameters.getName()).getName()); + + this.bOut = new ByteArrayOutputStream(); + this.signer = signer; + this.parameters = parameters; + } + + protected void engineInitVerify(PublicKey publicKey) + throws InvalidKeyException + { + if (publicKey instanceof BCMLDSAPublicKey) + { + BCMLDSAPublicKey key = (BCMLDSAPublicKey)publicKey; + + CipherParameters param = key.getKeyParams(); + + if (parameters != null) + { + String canonicalAlg = MLDSAParameterSpec.fromName(parameters.getName()).getName(); + if (!canonicalAlg.equals(key.getAlgorithm())) + { + throw new InvalidKeyException("signature configured for " + canonicalAlg); + } + } + + signer.init(false, param); + } + else + { + throw new InvalidKeyException("unknown public key passed to ML-DSA"); + } + } + + protected void engineInitSign(PrivateKey privateKey, SecureRandom random) + throws InvalidKeyException + { + this.appRandom = random; + engineInitSign(privateKey); + } + + protected void engineInitSign(PrivateKey privateKey) + throws InvalidKeyException + { + if (privateKey instanceof BCMLDSAPrivateKey) + { + BCMLDSAPrivateKey key = (BCMLDSAPrivateKey)privateKey; + + CipherParameters param = key.getKeyParams(); + + if (parameters != null) + { + String canonicalAlg = MLDSAParameterSpec.fromName(parameters.getName()).getName(); + if (!canonicalAlg.equals(key.getAlgorithm())) + { + throw new InvalidKeyException("signature configured for " + canonicalAlg); + } + } + + if (appRandom != null) + { + signer.init(true, new ParametersWithRandom(param, appRandom)); + } + else + { + signer.init(true, param); + } + } + else + { + throw new InvalidKeyException("unknown private key passed to ML-DSA"); + } + } + + protected void engineUpdate(byte b) + throws SignatureException + { + bOut.write(b); + } + + protected void engineUpdate(byte[] b, int off, int len) + throws SignatureException + { + bOut.write(b, off, len); + } + + protected byte[] engineSign() + throws SignatureException + { + try + { + byte[] message = bOut.toByteArray(); + + bOut.reset(); + + return signer.generateSignature(message); + } + catch (Exception e) + { + throw new SignatureException(e.toString()); + } + } + + protected boolean engineVerify(byte[] sigBytes) + throws SignatureException + { + byte[] message = bOut.toByteArray(); + + bOut.reset(); + + return signer.verifySignature(message, sigBytes); + } + + protected void engineSetParameter(AlgorithmParameterSpec params) + { + // TODO + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + /** + * @deprecated replaced with #engineSetParameter(java.security.spec.AlgorithmParameterSpec) + */ + protected void engineSetParameter(String param, Object value) + { + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + /** + * @deprecated + */ + protected Object engineGetParameter(String param) + { + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + + public static class MLDSA + extends SignatureSpi + { + public MLDSA() + { + super(new MLDSASigner()); + } + } + public static class MLDSA44 + extends SignatureSpi + { + public MLDSA44() + { + super(new MLDSASigner(), MLDSAParameters.ml_dsa_44); + } + } + + public static class MLDSA65 + extends SignatureSpi + { + public MLDSA65() + { + super(new MLDSASigner(), MLDSAParameters.ml_dsa_65); + } + } + + public static class MLDSA87 + extends SignatureSpi + { + public MLDSA87() + throws NoSuchAlgorithmException + { + super(new MLDSASigner(), MLDSAParameters.ml_dsa_87); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/BCMLKEMPrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/BCMLKEMPrivateKey.java new file mode 100644 index 0000000000..186687f340 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/BCMLKEMPrivateKey.java @@ -0,0 +1,137 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mlkem; + +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.jcajce.interfaces.MLKEMPrivateKey; +import org.bouncycastle.jcajce.interfaces.MLKEMPublicKey; +import org.bouncycastle.jcajce.spec.MLKEMParameterSpec; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; +import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; +import org.bouncycastle.util.Arrays; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +public class BCMLKEMPrivateKey + implements MLKEMPrivateKey +{ + private static final long serialVersionUID = 1L; + + private transient MLKEMPrivateKeyParameters params; + private transient String algorithm; + private transient ASN1Set attributes; + + public BCMLKEMPrivateKey( + MLKEMPrivateKeyParameters params) + { + this.params = params; + this.algorithm = params.getParameters().getName(); + } + + public BCMLKEMPrivateKey(PrivateKeyInfo keyInfo) + throws IOException + { + init(keyInfo); + } + + private void init(PrivateKeyInfo keyInfo) + throws IOException + { + this.attributes = keyInfo.getAttributes();; + this.params = (MLKEMPrivateKeyParameters)PrivateKeyFactory.createKey(keyInfo); + this.algorithm = params.getParameters().getName(); + } + + /** + * Compare this ML-KEM private key with another object. + * + * @param o the other object + * @return the result of the comparison + */ + public boolean equals(Object o) + { + if (o == this) + { + return true; + } + + if (o instanceof BCMLKEMPrivateKey) + { + BCMLKEMPrivateKey otherKey = (BCMLKEMPrivateKey)o; + + return Arrays.areEqual(params.getEncoded(), otherKey.params.getEncoded()); + } + + return false; + } + + public int hashCode() + { + return Arrays.hashCode(params.getEncoded()); + } + + /** + * @return name of the algorithm - "ML-KEM" + */ + public final String getAlgorithm() + { + return algorithm; +// return MLKEMParameterSpec.fromName(params.getParameters().getName()).getName().toUpperCase(); + } + public byte[] getEncoded() + { + + try + { + PrivateKeyInfo pki = PrivateKeyInfoFactory.createPrivateKeyInfo(params, attributes); + + return pki.getEncoded(); + } + catch (IOException e) + { + return null; + } + } + + public MLKEMPublicKey getPublicKey() + { + return new BCMLKEMPublicKey(params.getPublicKeyParameters()); + } + + public MLKEMParameterSpec getParameterSpec() + { + return MLKEMParameterSpec.fromName(params.getParameters().getName()); + } + + public String getFormat() + { + return "PKCS#8"; + } + + public MLKEMPrivateKeyParameters getKeyParams() + { + return params; + } + + private void readObject( + ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + + byte[] enc = (byte[])in.readObject(); + + init(PrivateKeyInfo.getInstance(enc)); + } + + private void writeObject( + ObjectOutputStream out) + throws IOException + { + out.defaultWriteObject(); + + out.writeObject(this.getEncoded()); + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/BCMLKEMPublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/BCMLKEMPublicKey.java new file mode 100644 index 0000000000..c8e0b747b5 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/BCMLKEMPublicKey.java @@ -0,0 +1,133 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mlkem; + +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.jcajce.interfaces.MLKEMPublicKey; +import org.bouncycastle.jcajce.spec.MLKEMParameterSpec; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; +import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; +import org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory; +import org.bouncycastle.util.Arrays; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +public class BCMLKEMPublicKey + implements MLKEMPublicKey +{ + private static final long serialVersionUID = 1L; + + private transient MLKEMPublicKeyParameters params; + + private transient String algorithm; + private transient byte[] encoding; + + public BCMLKEMPublicKey( + MLKEMPublicKeyParameters params) + { + init(params); + } + + public BCMLKEMPublicKey(SubjectPublicKeyInfo keyInfo) + throws IOException + { + init(keyInfo); + } + + private void init(SubjectPublicKeyInfo keyInfo) + throws IOException + { + this.params = (MLKEMPublicKeyParameters)PublicKeyFactory.createKey(keyInfo); + this.algorithm = params.getParameters().getName(); + } + + private void init(MLKEMPublicKeyParameters params) + { + this.params = params; + this.algorithm = params.getParameters().getName(); + } + /** + * Compare this ML-KEM public key with another object. + * + * @param o the other object + * @return the result of the comparison + */ + public boolean equals(Object o) + { + if (o == this) + { + return true; + } + + if (o instanceof BCMLKEMPublicKey) + { + BCMLKEMPublicKey otherKey = (BCMLKEMPublicKey)o; + + return Arrays.areEqual(this.getEncoded(), otherKey.getEncoded()); + } + + return false; + } + + public int hashCode() + { + return Arrays.hashCode(getEncoded()); + } + + /** + * @return name of the algorithm - "ML-KEM" followed by the parameter type. + */ + public final String getAlgorithm() + { + return algorithm; + } + + public byte[] getEncoded() + { + try + { + SubjectPublicKeyInfo pki = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(params); + + return pki.getEncoded(); + } + catch (IOException e) + { + return null; + } + } + + public String getFormat() + { + return "X.509"; + } + + public MLKEMParameterSpec getParameterSpec() + { + return MLKEMParameterSpec.fromName(params.getParameters().getName()); + } + + public MLKEMPublicKeyParameters getKeyParams() + { + return params; + } + + private void readObject( + ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + + byte[] enc = (byte[])in.readObject(); + + init(SubjectPublicKeyInfo.getInstance(enc)); + } + + private void writeObject( + ObjectOutputStream out) + throws IOException + { + out.defaultWriteObject(); + + out.writeObject(this.getEncoded()); + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMCipherSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMCipherSpi.java new file mode 100644 index 0000000000..bec43599ed --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMCipherSpi.java @@ -0,0 +1,364 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mlkem; + +import java.security.AlgorithmParameters; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.InvalidParameterException; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.CipherSpi; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.SecretKeySpec; +import javax.security.auth.DestroyFailedException; + +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.crypto.Wrapper; +import org.bouncycastle.jcajce.spec.KEMParameterSpec; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.jcajce.spec.MLKEMParameterSpec; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.pqc.jcajce.provider.util.WrapUtil; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Exceptions; + +class MLKEMCipherSpi + extends CipherSpi +{ + private final String algorithmName; + private MLKEMGenerator kemGen; + private KTSParameterSpec kemParameterSpec; + private BCMLKEMPublicKey wrapKey; + private BCMLKEMPrivateKey unwrapKey; + + private AlgorithmParameters engineParams; + private MLKEMParameters mlkemParamters; + + MLKEMCipherSpi(String algorithmName) + { + this.algorithmName = algorithmName; + this.mlkemParamters = null; + } + + MLKEMCipherSpi(MLKEMParameters kyberParameters) + { + this.mlkemParamters = kyberParameters; + this.algorithmName = kyberParameters.getName(); + } + + @Override + protected void engineSetMode(String mode) + throws NoSuchAlgorithmException + { + throw new NoSuchAlgorithmException("Cannot support mode " + mode); + } + + @Override + protected void engineSetPadding(String padding) + throws NoSuchPaddingException + { + throw new NoSuchPaddingException("Padding " + padding + " unknown"); + } + + protected int engineGetKeySize( + Key key) + { + return 2048; // TODO + //throw new IllegalArgumentException("not an valid key!"); + } + + @Override + protected int engineGetBlockSize() + { + return 0; + } + + @Override + protected int engineGetOutputSize(int i) + { + return -1; // can't use with update/doFinal + } + + @Override + protected byte[] engineGetIV() + { + return null; + } + + @Override + protected AlgorithmParameters engineGetParameters() + { + if (engineParams == null) + { + try + { + engineParams = AlgorithmParameters.getInstance(algorithmName, "BCPQC"); + + engineParams.init(kemParameterSpec); + } + catch (Exception e) + { + throw Exceptions.illegalStateException(e.toString(), e); + } + } + + return engineParams; + } + + @Override + protected void engineInit(int opmode, Key key, SecureRandom random) + throws InvalidKeyException + { + try + { + engineInit(opmode, key, (AlgorithmParameterSpec)null, random); + } + catch (InvalidAlgorithmParameterException e) + { + throw Exceptions.illegalArgumentException(e.getMessage(), e); + } + } + + @Override + protected void engineInit(int opmode, Key key, AlgorithmParameterSpec paramSpec, SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException + { + if (paramSpec == null) + { + // TODO: default should probably use shake. + kemParameterSpec = new KEMParameterSpec("AES-KWP"); + } + else + { + if (!(paramSpec instanceof KTSParameterSpec)) + { + throw new InvalidAlgorithmParameterException(algorithmName + " can only accept KTSParameterSpec"); + } + + kemParameterSpec = (KTSParameterSpec)paramSpec; + } + + if (opmode == Cipher.WRAP_MODE) + { + if (key instanceof BCMLKEMPublicKey) + { + wrapKey = (BCMLKEMPublicKey)key; + kemGen = new MLKEMGenerator(CryptoServicesRegistrar.getSecureRandom(random)); + } + else + { + throw new InvalidKeyException("Only a " + algorithmName + " public key can be used for wrapping"); + } + } + else if (opmode == Cipher.UNWRAP_MODE) + { + if (key instanceof BCMLKEMPrivateKey) + { + unwrapKey = (BCMLKEMPrivateKey)key; + } + else + { + throw new InvalidKeyException("Only a " + algorithmName + " private key can be used for unwrapping"); + } + } + else + { + throw new InvalidParameterException("Cipher only valid for wrapping/unwrapping"); + } + + if (mlkemParamters != null) + { + String canonicalAlgName = MLKEMParameterSpec.fromName(mlkemParamters.getName()).getName(); + if (!canonicalAlgName.equals(key.getAlgorithm())) + { + throw new InvalidKeyException("cipher locked to " + canonicalAlgName); + } + } + } + + @Override + protected void engineInit(int opmode, Key key, AlgorithmParameters algorithmParameters, SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException + { + AlgorithmParameterSpec paramSpec = null; + + if (algorithmParameters != null) + { + try + { + paramSpec = algorithmParameters.getParameterSpec(KEMParameterSpec.class); + } + catch (Exception e) + { + throw new InvalidAlgorithmParameterException("can't handle parameter " + algorithmParameters.toString()); + } + } + + engineInit(opmode, key, paramSpec, random); + } + + @Override + protected byte[] engineUpdate(byte[] bytes, int i, int i1) + { + throw new IllegalStateException("Not supported in a wrapping mode"); + } + + @Override + protected int engineUpdate(byte[] bytes, int i, int i1, byte[] bytes1, int i2) + throws ShortBufferException + { + throw new IllegalStateException("Not supported in a wrapping mode"); + } + + @Override + protected byte[] engineDoFinal(byte[] bytes, int i, int i1) + throws IllegalBlockSizeException, BadPaddingException + { + throw new IllegalStateException("Not supported in a wrapping mode"); + } + + @Override + protected int engineDoFinal(byte[] bytes, int i, int i1, byte[] bytes1, int i2) + throws ShortBufferException, IllegalBlockSizeException, BadPaddingException + { + throw new IllegalStateException("Not supported in a wrapping mode"); + } + + protected byte[] engineWrap( + Key key) + throws IllegalBlockSizeException, InvalidKeyException + { + byte[] encoded = key.getEncoded(); + if (encoded == null) + { + throw new InvalidKeyException("Cannot wrap key, null encoding."); + } + + SecretWithEncapsulation secEnc = null; + try + { + secEnc = kemGen.generateEncapsulated(wrapKey.getKeyParams()); + + Wrapper kWrap = WrapUtil.getKeyWrapper(kemParameterSpec, secEnc.getSecret()); + + byte[] encapsulation = secEnc.getEncapsulation(); + + byte[] keyToWrap = key.getEncoded(); + + byte[] rv = Arrays.concatenate(encapsulation, kWrap.wrap(keyToWrap, 0, keyToWrap.length)); + + Arrays.clear(keyToWrap); + + return rv; + } + catch (IllegalArgumentException e) + { + throw new IllegalBlockSizeException("unable to generate KTS secret: " + e.getMessage()); + } + finally + { + try + { + if (secEnc != null) + { + secEnc.destroy(); + } + } + catch (DestroyFailedException e) + { + throw new IllegalBlockSizeException("unable to destroy interim values: " + e.getMessage()); + } + } + } + + protected Key engineUnwrap( + byte[] wrappedKey, + String wrappedKeyAlgorithm, + int wrappedKeyType) + throws InvalidKeyException, NoSuchAlgorithmException + { + // TODO: add support for other types. + if (wrappedKeyType != Cipher.SECRET_KEY) + { + throw new InvalidKeyException("only SECRET_KEY supported"); + } + byte[] secret = null; + try + { + MLKEMExtractor kemExt = new MLKEMExtractor(unwrapKey.getKeyParams()); + + secret = kemExt.extractSecret(Arrays.copyOfRange(wrappedKey, 0, kemExt.getEncapsulationLength())); + + Wrapper kWrap = WrapUtil.getKeyUnwrapper(kemParameterSpec, secret); + + byte[] keyEncBytes = Arrays.copyOfRange(wrappedKey, kemExt.getEncapsulationLength(), wrappedKey.length); + + SecretKey rv = new SecretKeySpec(kWrap.unwrap(keyEncBytes, 0, keyEncBytes.length), wrappedKeyAlgorithm); + + return rv; + } + catch (IllegalArgumentException e) + { + throw new NoSuchAlgorithmException("unable to extract KTS secret: " + e.getMessage()); + } + catch (InvalidCipherTextException e) + { + throw new InvalidKeyException("unable to extract KTS secret: " + e.getMessage()); + } + finally + { + if (secret != null) + { + Arrays.clear(secret); + } + } + } + + public static class Base + extends MLKEMCipherSpi + { + public Base() + throws NoSuchAlgorithmException + { + super("MLKEM"); + } + } + + public static class MLKEM512 + extends MLKEMCipherSpi + { + public MLKEM512() + { + super(MLKEMParameters.ml_kem_512); + } + } + + public static class MLKEM768 + extends MLKEMCipherSpi + { + public MLKEM768() + { + super(MLKEMParameters.ml_kem_768); + } + } + + public static class MLKEM1024 + extends MLKEMCipherSpi + { + public MLKEM1024() + { + super(MLKEMParameters.ml_kem_1024); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyFactorySpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyFactorySpi.java new file mode 100644 index 0000000000..7493a9aa9d --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyFactorySpi.java @@ -0,0 +1,123 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mlkem; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.pqc.jcajce.provider.util.BaseKeyFactorySpi; + +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashSet; +import java.util.Set; + +public class MLKEMKeyFactorySpi + extends BaseKeyFactorySpi +{ + private static final Set keyOids = new HashSet(); + + static + { + keyOids.add(NISTObjectIdentifiers.id_alg_ml_kem_512); + keyOids.add(NISTObjectIdentifiers.id_alg_ml_kem_768); + keyOids.add(NISTObjectIdentifiers.id_alg_ml_kem_1024); + } + + public MLKEMKeyFactorySpi() + { + super(keyOids); + } + + public MLKEMKeyFactorySpi(ASN1ObjectIdentifier keyOid) + { + super(keyOid); + } + + + + + public final KeySpec engineGetKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException + { + if (key instanceof BCMLKEMPrivateKey) + { + if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) + { + return new PKCS8EncodedKeySpec(key.getEncoded()); + } + } + else if (key instanceof BCMLKEMPublicKey) + { + if (X509EncodedKeySpec.class.isAssignableFrom(keySpec)) + { + return new X509EncodedKeySpec(key.getEncoded()); + } + } + else + { + throw new InvalidKeySpecException("Unsupported key type: " + + key.getClass() + "."); + } + + throw new InvalidKeySpecException("Unknown key specification: " + + keySpec + "."); + } + + public final Key engineTranslateKey(Key key) + throws InvalidKeyException + { + if (key instanceof BCMLKEMPrivateKey || key instanceof BCMLKEMPublicKey) + { + return key; + } + + throw new InvalidKeyException("Unsupported key type"); + } + + public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) + throws IOException + { + return new BCMLKEMPrivateKey(keyInfo); + } + + public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) + throws IOException + { + return new BCMLKEMPublicKey(keyInfo); + } + + public static class MLKEM512 + extends MLKEMKeyFactorySpi + { + public MLKEM512() + { + super(NISTObjectIdentifiers.id_alg_ml_kem_512); + } + } + + public static class MLKEM768 + extends MLKEMKeyFactorySpi + { + public MLKEM768() + { + super(NISTObjectIdentifiers.id_alg_ml_kem_768); + } + } + + public static class MLKEM1024 + extends MLKEMKeyFactorySpi + { + public MLKEM1024() + { + super(NISTObjectIdentifiers.id_alg_ml_kem_1024); + } + } + +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyGeneratorSpi.java new file mode 100644 index 0000000000..65f75d5314 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyGeneratorSpi.java @@ -0,0 +1,158 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mlkem; + +import java.security.InvalidAlgorithmParameterException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.KeyGeneratorSpi; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import javax.security.auth.DestroyFailedException; + +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.jcajce.SecretKeyWithEncapsulation; +import org.bouncycastle.jcajce.spec.KEMExtractSpec; +import org.bouncycastle.jcajce.spec.KEMGenerateSpec; +import org.bouncycastle.jcajce.spec.MLKEMParameterSpec; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.util.Arrays; + +public class MLKEMKeyGeneratorSpi + extends KeyGeneratorSpi +{ + private KEMGenerateSpec genSpec; + private SecureRandom random; + private KEMExtractSpec extSpec; + private MLKEMParameters kyberParameters; + + public MLKEMKeyGeneratorSpi() + { + this(null); + } + + protected MLKEMKeyGeneratorSpi(MLKEMParameters kyberParameters) + { + this.kyberParameters = kyberParameters; + } + + protected void engineInit(SecureRandom secureRandom) + { + throw new UnsupportedOperationException("Operation not supported"); + } + + protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec, SecureRandom secureRandom) + throws InvalidAlgorithmParameterException + { + this.random = secureRandom; + if (algorithmParameterSpec instanceof KEMGenerateSpec) + { + this.genSpec = (KEMGenerateSpec)algorithmParameterSpec; + this.extSpec = null; + if (kyberParameters != null) + { + String canonicalAlgName = MLKEMParameterSpec.fromName(kyberParameters.getName()).getName(); + if (!canonicalAlgName.equals(genSpec.getPublicKey().getAlgorithm())) + { + throw new InvalidAlgorithmParameterException("key generator locked to " + canonicalAlgName); + } + } + } + else if (algorithmParameterSpec instanceof KEMExtractSpec) + { + this.genSpec = null; + this.extSpec = (KEMExtractSpec)algorithmParameterSpec; + if (kyberParameters != null) + { + String canonicalAlgName = MLKEMParameterSpec.fromName(kyberParameters.getName()).getName(); + if (!canonicalAlgName.equals(extSpec.getPrivateKey().getAlgorithm())) + { + throw new InvalidAlgorithmParameterException("key generator locked to " + canonicalAlgName); + } + } + } + else + { + throw new InvalidAlgorithmParameterException("unknown spec"); + } + } + + protected void engineInit(int i, SecureRandom secureRandom) + { + throw new UnsupportedOperationException("Operation not supported"); + } + + protected SecretKey engineGenerateKey() + { + if (genSpec != null) + { + BCMLKEMPublicKey pubKey = (BCMLKEMPublicKey)genSpec.getPublicKey(); + MLKEMGenerator kemGen = new MLKEMGenerator(random); + + SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(pubKey.getKeyParams()); + + byte[] sharedSecret = secEnc.getSecret(); + byte[] secret = Arrays.copyOfRange(sharedSecret, 0, (genSpec.getKeySize() + 7) / 8); + + Arrays.clear(sharedSecret); + + SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, genSpec.getKeyAlgorithmName()), secEnc.getEncapsulation()); + + try + { + secEnc.destroy(); + } + catch (DestroyFailedException e) + { + throw new IllegalStateException("key cleanup failed"); + } + + return rv; + } + else + { + BCMLKEMPrivateKey privKey = (BCMLKEMPrivateKey)extSpec.getPrivateKey(); + MLKEMExtractor kemExt = new MLKEMExtractor(privKey.getKeyParams()); + + byte[] encapsulation = extSpec.getEncapsulation(); + byte[] sharedSecret = kemExt.extractSecret(encapsulation); + byte[] secret = Arrays.copyOfRange(sharedSecret, 0, (extSpec.getKeySize() + 7) / 8); + + Arrays.clear(sharedSecret); + + SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, extSpec.getKeyAlgorithmName()), encapsulation); + + Arrays.clear(secret); + + return rv; + } + } + + public static class MLKEM512 + extends MLKEMKeyGeneratorSpi + { + public MLKEM512() + { + super(MLKEMParameters.ml_kem_512); + } + } + + public static class MLKEM768 + extends MLKEMKeyGeneratorSpi + { + public MLKEM768() + { + super(MLKEMParameters.ml_kem_768); + } + } + + public static class MLKEM1024 + extends MLKEMKeyGeneratorSpi + { + public MLKEM1024() + { + super(MLKEMParameters.ml_kem_1024); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyPairGeneratorSpi.java new file mode 100644 index 0000000000..4c3ae17896 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyPairGeneratorSpi.java @@ -0,0 +1,150 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mlkem; + +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; +import java.util.HashMap; +import java.util.Map; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.jcajce.spec.MLKEMParameterSpec; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyPairGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; +import org.bouncycastle.pqc.jcajce.provider.util.SpecUtil; +import org.bouncycastle.util.Strings; + +public class MLKEMKeyPairGeneratorSpi + extends java.security.KeyPairGenerator +{ + private static Map parameters = new HashMap(); + + static + { + parameters.put(MLKEMParameterSpec.ml_kem_512.getName(), MLKEMParameters.ml_kem_512); + parameters.put(MLKEMParameterSpec.ml_kem_768.getName(), MLKEMParameters.ml_kem_768); + parameters.put(MLKEMParameterSpec.ml_kem_1024.getName(), MLKEMParameters.ml_kem_1024); + } + + MLKEMKeyGenerationParameters param; + MLKEMKeyPairGenerator engine = new MLKEMKeyPairGenerator(); + + SecureRandom random = CryptoServicesRegistrar.getSecureRandom(); + boolean initialised = false; + private MLKEMParameters kyberParameters; + + public MLKEMKeyPairGeneratorSpi() + { + super("ML-KEM"); + } + + protected MLKEMKeyPairGeneratorSpi(MLKEMParameterSpec paramSpec) + { + super(Strings.toUpperCase(paramSpec.getName())); + this.kyberParameters = (MLKEMParameters) parameters.get(paramSpec.getName()); + + if (param == null) + { + param = new MLKEMKeyGenerationParameters(random, kyberParameters); + } + + engine.init(param); + initialised = true; + } + + public void initialize( + int strength, + SecureRandom random) + { + throw new IllegalArgumentException("use AlgorithmParameterSpec"); + } + + public void initialize( + AlgorithmParameterSpec params, + SecureRandom random) + throws InvalidAlgorithmParameterException + { + + String name = getNameFromParams(params); + + MLKEMParameters kyberParams = (MLKEMParameters)parameters.get(name); + + if (name != null) + { + param = new MLKEMKeyGenerationParameters(random, (MLKEMParameters) parameters.get(name)); + + if (kyberParameters != null && !kyberParams.getName().equals(kyberParameters.getName())) + { + throw new InvalidAlgorithmParameterException("key pair generator locked to " + getAlgorithm()); + } + + engine.init(param); + initialised = true; + } + else + { + throw new InvalidAlgorithmParameterException("invalid ParameterSpec: " + params); + } + } + + public KeyPair generateKeyPair() + { + if (!initialised) + { + param = new MLKEMKeyGenerationParameters(random, MLKEMParameters.ml_kem_768); + + engine.init(param); + initialised = true; + } + + AsymmetricCipherKeyPair pair = engine.generateKeyPair(); + MLKEMPublicKeyParameters pub = (MLKEMPublicKeyParameters)pair.getPublic(); + MLKEMPrivateKeyParameters priv = (MLKEMPrivateKeyParameters)pair.getPrivate(); + + return new KeyPair(new BCMLKEMPublicKey(pub), new BCMLKEMPrivateKey(priv)); + } + + private static String getNameFromParams(AlgorithmParameterSpec paramSpec) + { + if (paramSpec instanceof MLKEMParameterSpec) + { + MLKEMParameterSpec params = (MLKEMParameterSpec)paramSpec; + return params.getName(); + } + else + { + return Strings.toLowerCase(SpecUtil.getNameFrom(paramSpec)); + } + } + + public static class MLKEM512 + extends MLKEMKeyPairGeneratorSpi + { + public MLKEM512() + { + super(MLKEMParameterSpec.ml_kem_512); + } + } + + public static class MLKEM768 + extends MLKEMKeyPairGeneratorSpi + { + public MLKEM768() + { + super(MLKEMParameterSpec.ml_kem_768); + } + } + + public static class MLKEM1024 + extends MLKEMKeyPairGeneratorSpi + { + public MLKEM1024() + { + super(MLKEMParameterSpec.ml_kem_1024); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java index cb024620e9..abad97187c 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java @@ -29,12 +29,14 @@ import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.encodings.ISO9796d1Encoding; import org.bouncycastle.crypto.encodings.OAEPEncoding; -import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.crypto.params.RSAKeyParameters; +import org.bouncycastle.crypto.tls.TlsRsaKeyExchange; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi; import org.bouncycastle.jcajce.provider.util.BadBlockException; import org.bouncycastle.jcajce.provider.util.DigestFactory; +import org.bouncycastle.jcajce.spec.TLSRSAPremasterSecretParameterSpec; import org.bouncycastle.jcajce.util.BCJcaJceHelper; import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.util.Strings; @@ -50,6 +52,8 @@ public class CipherSpi private boolean publicKeyOnly = false; private boolean privateKeyOnly = false; private ErasableOutputStream bOut = new ErasableOutputStream(); + private TLSRSAPremasterSecretParameterSpec tlsRsaSpec = null; + private CipherParameters param = null; public CipherSpi( AsymmetricBlockCipher engine) @@ -130,6 +134,11 @@ else if (key instanceof RSAPublicKey) protected int engineGetOutputSize( int inputLen) { + if (tlsRsaSpec != null) + { + return TlsRsaKeyExchange.PRE_MASTER_SECRET_LENGTH; + } + try { return cipher.getOutputBlockSize(); @@ -200,7 +209,7 @@ protected void engineSetPadding( } else if (pad.equals("PKCS1PADDING")) { - cipher = new PKCS1Encoding(new RSABlindedEngine()); + cipher = new CustomPKCS1Encoding(new RSABlindedEngine()); } else if (pad.equals("ISO9796-1PADDING")) { @@ -263,9 +272,12 @@ protected void engineInit( SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { - CipherParameters param; - if (params == null || params instanceof OAEPParameterSpec) + this.tlsRsaSpec = null; + + if (params == null + || params instanceof OAEPParameterSpec + || params instanceof TLSRSAPremasterSecretParameterSpec) { if (key instanceof RSAPublicKey) { @@ -292,7 +304,7 @@ else if (key instanceof RSAPrivateKey) throw new InvalidKeyException("unknown key type passed to RSA"); } - if (params != null) + if (params instanceof OAEPParameterSpec) { OAEPParameterSpec spec = (OAEPParameterSpec)params; @@ -325,22 +337,30 @@ else if (key instanceof RSAPrivateKey) cipher = new OAEPEncoding(new RSABlindedEngine(), digest, mgfDigest, ((PSource.PSpecified)spec.getPSource()).getValue()); } + else if (params instanceof TLSRSAPremasterSecretParameterSpec) + { + // TODO Restrict mode to DECRYPT_MODE (and/or UNWRAP_MODE) + if (!(param instanceof RSAKeyParameters) || !((RSAKeyParameters)param).isPrivate()) + { + throw new InvalidKeyException("RSA private key required for TLS decryption"); + } + + this.tlsRsaSpec = (TLSRSAPremasterSecretParameterSpec)params; + } } else { throw new InvalidAlgorithmParameterException("unknown parameter type: " + params.getClass().getName()); } - if (!(cipher instanceof RSABlindedEngine)) + if (random != null) { - if (random != null) - { - param = new ParametersWithRandom(param, random); - } - else - { - param = new ParametersWithRandom(param, CryptoServicesRegistrar.getSecureRandom()); - } + param = new ParametersWithRandom(param, random); + } + else + { + // TODO Remove after checking all AsymmetricBlockCipher init methods? + param = new ParametersWithRandom(param, CryptoServicesRegistrar.getSecureRandom()); } bOut.reset(); @@ -407,23 +427,12 @@ protected byte[] engineUpdate( int inputOffset, int inputLen) { - bOut.write(input, inputOffset, inputLen); - - if (cipher instanceof RSABlindedEngine) - { - if (bOut.size() > cipher.getInputBlockSize() + 1) - { - throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); - } - } - else + if (inputLen > getInputLimit() - bOut.size()) { - if (bOut.size() > cipher.getInputBlockSize()) - { - throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); - } + throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); } + bOut.write(input, inputOffset, inputLen); return null; } @@ -434,23 +443,7 @@ protected int engineUpdate( byte[] output, int outputOffset) { - bOut.write(input, inputOffset, inputLen); - - if (cipher instanceof RSABlindedEngine) - { - if (bOut.size() > cipher.getInputBlockSize() + 1) - { - throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); - } - } - else - { - if (bOut.size() > cipher.getInputBlockSize()) - { - throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); - } - } - + engineUpdate(input, inputOffset, inputLen); return 0; } @@ -460,24 +453,10 @@ protected byte[] engineDoFinal( int inputLen) throws IllegalBlockSizeException, BadPaddingException { + // TODO Can input actually be null? if (input != null) { - bOut.write(input, inputOffset, inputLen); - } - - if (cipher instanceof RSABlindedEngine) - { - if (bOut.size() > cipher.getInputBlockSize() + 1) - { - throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); - } - } - else - { - if (bOut.size() > cipher.getInputBlockSize()) - { - throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); - } + engineUpdate(input, inputOffset, inputLen); } return getOutput(); @@ -491,39 +470,33 @@ protected int engineDoFinal( int outputOffset) throws IllegalBlockSizeException, BadPaddingException, ShortBufferException { - if (outputOffset + engineGetOutputSize(inputLen) > output.length) + // TODO Can input actually be null? + int outputSize = engineGetOutputSize(input == null ? 0 : inputLen); + if (outputOffset > output.length - outputSize) { throw new ShortBufferException("output buffer too short for input."); } - if (input != null) - { - bOut.write(input, inputOffset, inputLen); - } + byte[] out = engineDoFinal(input, inputOffset, inputLen); + System.arraycopy(out, 0, output, outputOffset, out.length); + return out.length; + } - if (cipher instanceof RSABlindedEngine) + private int getInputLimit() + { + if (tlsRsaSpec != null) { - if (bOut.size() > cipher.getInputBlockSize() + 1) - { - throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); - } + ParametersWithRandom pWithR = (ParametersWithRandom)param; + return TlsRsaKeyExchange.getInputLimit((RSAKeyParameters)pWithR.getParameters()); } - else + else if (cipher instanceof RSABlindedEngine) { - if (bOut.size() > cipher.getInputBlockSize()) - { - throw new ArrayIndexOutOfBoundsException("too much data for RSA block"); - } + return cipher.getInputBlockSize() + 1; } - - byte[] out = getOutput(); - - for (int i = 0; i != out.length; i++) + else { - output[outputOffset + i] = out[i]; + return cipher.getInputBlockSize(); } - - return out.length; } private byte[] getOutput() @@ -531,15 +504,33 @@ private byte[] getOutput() { try { - return cipher.processBlock(bOut.getBuf(), 0, bOut.size()); - } - catch (InvalidCipherTextException e) - { - throw new BadBlockException("unable to decrypt block", e); - } - catch (ArrayIndexOutOfBoundsException e) - { - throw new BadBlockException("unable to decrypt block", e); + if (tlsRsaSpec != null) + { + ParametersWithRandom pWithR = (ParametersWithRandom)param; + return TlsRsaKeyExchange.decryptPreMasterSecret(bOut.getBuf(), 0, bOut.size(), + (RSAKeyParameters)pWithR.getParameters(), tlsRsaSpec.getProtocolVersion(), pWithR.getRandom()); + } + + byte[] output; + try + { + output = cipher.processBlock(bOut.getBuf(), 0, bOut.size()); + } + catch (InvalidCipherTextException e) + { + throw new BadBlockException("unable to decrypt block", e); + } + catch (ArrayIndexOutOfBoundsException e) + { + throw new BadBlockException("unable to decrypt block", e); + } + + if (output == null) + { + throw new BadBlockException("unable to decrypt block", null); + } + + return output; } finally { @@ -565,7 +556,7 @@ static public class PKCS1v1_5Padding { public PKCS1v1_5Padding() { - super(new PKCS1Encoding(new RSABlindedEngine())); + super(new CustomPKCS1Encoding(new RSABlindedEngine())); } } @@ -574,7 +565,7 @@ static public class PKCS1v1_5Padding_PrivateOnly { public PKCS1v1_5Padding_PrivateOnly() { - super(false, true, new PKCS1Encoding(new RSABlindedEngine())); + super(false, true, new CustomPKCS1Encoding(new RSABlindedEngine())); } } @@ -583,7 +574,7 @@ static public class PKCS1v1_5Padding_PublicOnly { public PKCS1v1_5Padding_PublicOnly() { - super(true, false, new PKCS1Encoding(new RSABlindedEngine())); + super(true, false, new CustomPKCS1Encoding(new RSABlindedEngine())); } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CustomPkcs1Encoding.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CustomPkcs1Encoding.java new file mode 100644 index 0000000000..1fc4334fa6 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CustomPkcs1Encoding.java @@ -0,0 +1,263 @@ +package org.bouncycastle.jcajce.provider.asymmetric.rsa; + +import java.security.SecureRandom; + +import org.bouncycastle.crypto.AsymmetricBlockCipher; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.encodings.PKCS1Encoding; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Properties; + +/** + * this does your basic PKCS 1 v1.5 padding - whether or not you should be using this + * depends on your application - see PKCS1 Version 2 for details. + */ +class CustomPKCS1Encoding + implements AsymmetricBlockCipher +{ + private static final int HEADER_LENGTH = 10; + + private SecureRandom random; + private AsymmetricBlockCipher engine; + private boolean forEncryption; + private boolean forPrivateKey; + private boolean useStrictLength; + private byte[] blockBuffer; + + /** + * Basic constructor. + * + * @param cipher + */ + CustomPKCS1Encoding(AsymmetricBlockCipher cipher) + { + this.engine = cipher; + this.useStrictLength = useStrict(); + } + + // + // for J2ME compatibility + // + private boolean useStrict() + { + if (Properties.isOverrideSetTo(PKCS1Encoding.NOT_STRICT_LENGTH_ENABLED_PROPERTY, true)) + { + return false; + } + + return !Properties.isOverrideSetTo(PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY, false); + } + + public AsymmetricBlockCipher getUnderlyingCipher() + { + return engine; + } + + public void init(boolean forEncryption, CipherParameters param) + { + AsymmetricKeyParameter kParam; + + if (param instanceof ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)param; + + this.random = rParam.getRandom(); + kParam = (AsymmetricKeyParameter)rParam.getParameters(); + } + else + { + kParam = (AsymmetricKeyParameter)param; + if (!kParam.isPrivate() && forEncryption) + { + this.random = CryptoServicesRegistrar.getSecureRandom(); + } + } + + engine.init(forEncryption, param); + + this.forPrivateKey = kParam.isPrivate(); + this.forEncryption = forEncryption; + this.blockBuffer = new byte[engine.getOutputBlockSize()]; + } + + public int getInputBlockSize() + { + int baseBlockSize = engine.getInputBlockSize(); + + if (forEncryption) + { + return baseBlockSize - HEADER_LENGTH; + } + else + { + return baseBlockSize; + } + } + + public int getOutputBlockSize() + { + int baseBlockSize = engine.getOutputBlockSize(); + + if (forEncryption) + { + return baseBlockSize; + } + else + { + return baseBlockSize - HEADER_LENGTH; + } + } + + public byte[] processBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException + { + if (forEncryption) + { + return encodeBlock(in, inOff, inLen); + } + else + { + return decodeBlock(in, inOff, inLen); + } + } + + private byte[] encodeBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException + { + if (inLen > getInputBlockSize()) + { + throw new IllegalArgumentException("input data too large"); + } + + byte[] block = new byte[engine.getInputBlockSize()]; + + if (forPrivateKey) + { + block[0] = 0x01; // type code 1 + + for (int i = 1; i != block.length - inLen - 1; i++) + { + block[i] = (byte)0xFF; + } + } + else + { + random.nextBytes(block); // random fill + + block[0] = 0x02; // type code 2 + + // + // a zero byte marks the end of the padding, so all + // the pad bytes must be non-zero. + // + for (int i = 1; i != block.length - inLen - 1; i++) + { + while (block[i] == 0) + { + block[i] = (byte)random.nextInt(); + } + } + } + + block[block.length - inLen - 1] = 0x00; // mark the end of the padding + System.arraycopy(in, inOff, block, block.length - inLen, inLen); + + return engine.processBlock(block, 0, block.length); + } + + /** + * Check the argument is a valid encoding with type 1. Returns the plaintext length if valid, or -1 if invalid. + */ + private static int checkPkcs1Encoding1(byte[] buf) + { + int foundZeroMask = 0; + int lastPadPos = 0; + + // The first byte should be 0x01 + int badPadSign = -((buf[0] & 0xFF) ^ 0x01); + + // There must be a zero terminator for the padding somewhere + for (int i = 1; i < buf.length; ++i) + { + int padByte = buf[i] & 0xFF; + int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31; + int is0xFFMask = ((padByte ^ 0xFF) - 1) >> 31; + lastPadPos ^= i & ~foundZeroMask & is0x00Mask; + foundZeroMask |= is0x00Mask; + badPadSign |= ~(foundZeroMask | is0xFFMask); + } + + // The header should be at least 10 bytes + badPadSign |= lastPadPos - 9; + + int plaintextLength = buf.length - 1 - lastPadPos; + return plaintextLength | badPadSign >> 31; + } + + /** + * Check the argument is a valid encoding with type 2. Returns the plaintext length if valid, or -1 if invalid. + */ + private static int checkPkcs1Encoding2(byte[] buf) + { + int foundZeroMask = 0; + int lastPadPos = 0; + + // The first byte should be 0x02 + int badPadSign = -((buf[0] & 0xFF) ^ 0x02); + + // There must be a zero terminator for the padding somewhere + for (int i = 1; i < buf.length; ++i) + { + int padByte = buf[i] & 0xFF; + int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31; + lastPadPos ^= i & ~foundZeroMask & is0x00Mask; + foundZeroMask |= is0x00Mask; + } + + // The header should be at least 10 bytes + badPadSign |= lastPadPos - 9; + + int plaintextLength = buf.length - 1 - lastPadPos; + return plaintextLength | badPadSign >> 31; + } + + /** + * @throws InvalidCipherTextException if the decrypted block is not in PKCS1 format. + */ + private byte[] decodeBlock(byte[] in, int inOff, int inLen) + throws InvalidCipherTextException + { + int strictBlockSize = engine.getOutputBlockSize(); + byte[] block = engine.processBlock(in, inOff, inLen); + + boolean incorrectLength = useStrictLength & (block.length != strictBlockSize); + + byte[] data = block; + if (block.length < strictBlockSize) + { + data = blockBuffer; + } + + int plaintextLength = forPrivateKey ? checkPkcs1Encoding2(data) : checkPkcs1Encoding1(data); + + try + { + if (plaintextLength < 0 | incorrectLength) + { + // Special behaviour to avoid throw/catch/throw in CipherSpi + return null; + } + + byte[] result = new byte[plaintextLength]; + System.arraycopy(data, data.length - plaintextLength, result, 0, plaintextLength); + return result; + } + finally + { + Arrays.fill(block, (byte)0); + Arrays.fill(blockBuffer, 0, Math.max(0, blockBuffer.length - block.length), (byte)0); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java index bc00222ed0..0046767e3e 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java @@ -15,7 +15,6 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; @@ -32,6 +31,7 @@ import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.util.DigestFactory; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.util.Arrays; public class DigestSignatureSpi diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/BCSLHDSAPrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/BCSLHDSAPrivateKey.java new file mode 100644 index 0000000000..c179d068c3 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/BCSLHDSAPrivateKey.java @@ -0,0 +1,136 @@ +package org.bouncycastle.jcajce.provider.asymmetric.slhdsa; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.jcajce.interfaces.SLHDSAPrivateKey; +import org.bouncycastle.jcajce.interfaces.SLHDSAPublicKey; +import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAPublicKeyParameters; +import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; +import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; + +public class BCSLHDSAPrivateKey + implements SLHDSAPrivateKey +{ + private static final long serialVersionUID = 1L; + + private transient SLHDSAPrivateKeyParameters params; + private transient ASN1Set attributes; + + public BCSLHDSAPrivateKey( + SLHDSAPrivateKeyParameters params) + { + this.params = params; + } + + public BCSLHDSAPrivateKey(PrivateKeyInfo keyInfo) + throws IOException + { + init(keyInfo); + } + + private void init(PrivateKeyInfo keyInfo) + throws IOException + { + this.attributes = keyInfo.getAttributes(); + this.params = (SLHDSAPrivateKeyParameters)PrivateKeyFactory.createKey(keyInfo); + } + + /** + * Compare this SPHINCS-256 private key with another object. + * + * @param o the other object + * @return the result of the comparison + */ + public boolean equals(Object o) + { + if (o == this) + { + return true; + } + + if (o instanceof BCSLHDSAPrivateKey) + { + BCSLHDSAPrivateKey otherKey = (BCSLHDSAPrivateKey)o; + + return Arrays.areEqual(params.getEncoded(), otherKey.params.getEncoded()); + } + + return false; + } + + public int hashCode() + { + return Arrays.hashCode(params.getEncoded()); + } + + /** + * @return name of the algorithm - "SLH-DSA" + */ + public final String getAlgorithm() + { + return "SLH-DSA" + "-" + Strings.toUpperCase(params.getParameters().getName()); + } + + public byte[] getEncoded() + { + + try + { + PrivateKeyInfo pki = PrivateKeyInfoFactory.createPrivateKeyInfo(params, attributes); + + return pki.getEncoded(); + } + catch (IOException e) + { + return null; + } + } + + public SLHDSAPublicKey getPublicKey() + { + return new BCSLHDSAPublicKey(new SLHDSAPublicKeyParameters(params.getParameters(), params.getPublicKey())); + } + + public SLHDSAParameterSpec getParameterSpec() + { + return SLHDSAParameterSpec.fromName(params.getParameters().getName()); + } + + public String getFormat() + { + return "PKCS#8"; + } + + SLHDSAPrivateKeyParameters getKeyParams() + { + return params; + } + + private void readObject( + ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + + byte[] enc = (byte[])in.readObject(); + + init(PrivateKeyInfo.getInstance(enc)); + } + + private void writeObject( + ObjectOutputStream out) + throws IOException + { + out.defaultWriteObject(); + + out.writeObject(this.getEncoded()); + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/BCSLHDSAPublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/BCSLHDSAPublicKey.java new file mode 100644 index 0000000000..f603e33775 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/BCSLHDSAPublicKey.java @@ -0,0 +1,126 @@ +package org.bouncycastle.jcajce.provider.asymmetric.slhdsa; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.jcajce.interfaces.SLHDSAPublicKey; +import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAPublicKeyParameters; +import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; +import org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; + +public class BCSLHDSAPublicKey + implements SLHDSAPublicKey +{ + private static final long serialVersionUID = 1L; + + private transient SLHDSAPublicKeyParameters params; + + public BCSLHDSAPublicKey( + SLHDSAPublicKeyParameters params) + { + this.params = params; + } + + public BCSLHDSAPublicKey(SubjectPublicKeyInfo keyInfo) + throws IOException + { + init(keyInfo); + } + + private void init(SubjectPublicKeyInfo keyInfo) + throws IOException + { + this.params = (SLHDSAPublicKeyParameters)PublicKeyFactory.createKey(keyInfo); + } + + /** + * Compare this SPHINCS-256 public key with another object. + * + * @param o the other object + * @return the result of the comparison + */ + public boolean equals(Object o) + { + if (o == this) + { + return true; + } + + if (o instanceof BCSLHDSAPublicKey) + { + BCSLHDSAPublicKey otherKey = (BCSLHDSAPublicKey)o; + + return Arrays.areEqual(params.getEncoded(), otherKey.params.getEncoded()); + } + + return false; + } + + public int hashCode() + { + return Arrays.hashCode(params.getEncoded()); + } + + /** + * @return name of the algorithm - "SLH-DSA" followed by the parameter type. + */ + public final String getAlgorithm() + { + return "SLH-DSA" + "-" + Strings.toUpperCase(params.getParameters().getName()); + } + + public byte[] getEncoded() + { + try + { + SubjectPublicKeyInfo pki = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(params); + + return pki.getEncoded(); + } + catch (IOException e) + { + return null; + } + } + + public String getFormat() + { + return "X.509"; + } + + public SLHDSAParameterSpec getParameterSpec() + { + return SLHDSAParameterSpec.fromName(params.getParameters().getName()); + } + + CipherParameters getKeyParams() + { + return params; + } + + private void readObject( + ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + + byte[] enc = (byte[])in.readObject(); + + init(SubjectPublicKeyInfo.getInstance(enc)); + } + + private void writeObject( + ObjectOutputStream out) + throws IOException + { + out.defaultWriteObject(); + + out.writeObject(this.getEncoded()); + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/HashSignatureSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/HashSignatureSpi.java new file mode 100644 index 0000000000..4b84ccbf6e --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/HashSignatureSpi.java @@ -0,0 +1,135 @@ +package org.bouncycastle.jcajce.provider.asymmetric.slhdsa; + +import java.security.InvalidKeyException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.SignatureException; +import java.security.spec.AlgorithmParameterSpec; + +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.pqc.crypto.slhdsa.HashSLHDSASigner; + +public class HashSignatureSpi + extends java.security.SignatureSpi +{ + private final HashSLHDSASigner signer; + + protected HashSignatureSpi(HashSLHDSASigner signer) + { + this.signer = signer; + } + + protected void engineInitVerify(PublicKey publicKey) + throws InvalidKeyException + { + if (publicKey instanceof BCSLHDSAPublicKey) + { + BCSLHDSAPublicKey key = (BCSLHDSAPublicKey)publicKey; + + CipherParameters param = key.getKeyParams(); + + signer.init(false, param); + } + else + { + throw new InvalidKeyException("unknown public key passed to SLH-DSA"); + } + } + + protected void engineInitSign(PrivateKey privateKey, SecureRandom random) + throws InvalidKeyException + { + this.appRandom = random; + engineInitSign(privateKey); + } + + protected void engineInitSign(PrivateKey privateKey) + throws InvalidKeyException + { + if (privateKey instanceof BCSLHDSAPrivateKey) + { + BCSLHDSAPrivateKey key = (BCSLHDSAPrivateKey)privateKey; + + CipherParameters param = key.getKeyParams(); + + if (appRandom != null) + { + signer.init(true, new ParametersWithRandom(param, appRandom)); + } + else + { + signer.init(true, param); + } + } + else + { + throw new InvalidKeyException("unknown private key passed to SLH-DSA"); + } + } + + protected void engineUpdate(byte b) + throws SignatureException + { + signer.update(b); + } + + protected void engineUpdate(byte[] b, int off, int len) + throws SignatureException + { + signer.update(b, off, len); + } + + protected byte[] engineSign() + throws SignatureException + { + try + { + byte[] sig = signer.generateSignature(); + + return sig; + } + catch (Exception e) + { + throw new SignatureException(e.toString()); + } + } + + protected boolean engineVerify(byte[] sigBytes) + throws SignatureException + { + return signer.verifySignature(sigBytes); + } + + protected void engineSetParameter(AlgorithmParameterSpec params) + { + // TODO + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + /** + * @deprecated replaced with #engineSetParameter(java.security.spec.AlgorithmParameterSpec) + */ + protected void engineSetParameter(String param, Object value) + { + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + /** + * @deprecated + */ + protected Object engineGetParameter(String param) + { + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + static public class Direct + extends HashSignatureSpi + { + public Direct() + { + super(new HashSLHDSASigner()); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/SLHDSAKeyFactorySpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/SLHDSAKeyFactorySpi.java new file mode 100644 index 0000000000..088b359a16 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/SLHDSAKeyFactorySpi.java @@ -0,0 +1,364 @@ +package org.bouncycastle.jcajce.provider.asymmetric.slhdsa; + +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashSet; +import java.util.Set; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.pqc.jcajce.provider.util.BaseKeyFactorySpi; + +public class SLHDSAKeyFactorySpi + extends BaseKeyFactorySpi +{ + private static final Set pureKeyOids = new HashSet(); + private static final Set hashKeyOids = new HashSet(); + static + { + pureKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_sha2_128f); + pureKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_sha2_128s); + pureKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_sha2_192f); + pureKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_sha2_192s); + pureKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_sha2_256f); + pureKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_sha2_256s); + + pureKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_shake_128f); + pureKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_shake_128s); + pureKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_shake_192f); + pureKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_shake_192s); + pureKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_shake_256f); + pureKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_shake_256s); + + hashKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_sha2_128f); + hashKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_sha2_128s); + hashKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_sha2_192f); + hashKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_sha2_192s); + hashKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_sha2_256f); + hashKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_sha2_256s); + + hashKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_shake_128f); + hashKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_shake_128s); + hashKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_shake_192f); + hashKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_shake_192s); + hashKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_shake_256f); + hashKeyOids.add(NISTObjectIdentifiers.id_slh_dsa_shake_256s); + + hashKeyOids.add(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256); + hashKeyOids.add(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256); + hashKeyOids.add(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512); + hashKeyOids.add(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512); + hashKeyOids.add(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512); + hashKeyOids.add(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512); + + hashKeyOids.add(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128); + hashKeyOids.add(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128); + hashKeyOids.add(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256); + hashKeyOids.add(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256); + hashKeyOids.add(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256); + hashKeyOids.add(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256); + } + + public SLHDSAKeyFactorySpi(Set keyOids) + { + super(keyOids); + } + + public SLHDSAKeyFactorySpi(ASN1ObjectIdentifier keyOid) + { + super(keyOid); + } + + public final KeySpec engineGetKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException + { + if (key instanceof BCSLHDSAPrivateKey) + { + if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) + { + return new PKCS8EncodedKeySpec(key.getEncoded()); + } + } + else if (key instanceof BCSLHDSAPublicKey) + { + if (X509EncodedKeySpec.class.isAssignableFrom(keySpec)) + { + return new X509EncodedKeySpec(key.getEncoded()); + } + } + else + { + throw new InvalidKeySpecException("Unsupported key type: " + + key.getClass() + "."); + } + + throw new InvalidKeySpecException("Unknown key specification: " + + keySpec + "."); + } + + public final Key engineTranslateKey(Key key) + throws InvalidKeyException + { + if (key instanceof BCSLHDSAPrivateKey || key instanceof BCSLHDSAPublicKey) + { + return key; + } + + throw new InvalidKeyException("Unsupported key type"); + } + + public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) + throws IOException + { + return new BCSLHDSAPrivateKey(keyInfo); + } + + public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) + throws IOException + { + return new BCSLHDSAPublicKey(keyInfo); + } + + public static class Pure + extends SLHDSAKeyFactorySpi + { + public Pure() + { + super(pureKeyOids); + } + } + + public static class Sha2_128f + extends SLHDSAKeyFactorySpi + { + public Sha2_128f() + { + super(NISTObjectIdentifiers.id_slh_dsa_sha2_128f); + } + } + + public static class Sha2_128s + extends SLHDSAKeyFactorySpi + { + public Sha2_128s() + { + super(NISTObjectIdentifiers.id_slh_dsa_sha2_128s); + } + } + + public static class Sha2_192f + extends SLHDSAKeyFactorySpi + { + public Sha2_192f() + { + super(NISTObjectIdentifiers.id_slh_dsa_sha2_192f); + } + } + + public static class Sha2_192s + extends SLHDSAKeyFactorySpi + { + public Sha2_192s() + { + super(NISTObjectIdentifiers.id_slh_dsa_sha2_192s); + } + } + + public static class Sha2_256f + extends SLHDSAKeyFactorySpi + { + public Sha2_256f() + { + super(NISTObjectIdentifiers.id_slh_dsa_sha2_256f); + } + } + + public static class Sha2_256s + extends SLHDSAKeyFactorySpi + { + public Sha2_256s() + { + super(NISTObjectIdentifiers.id_slh_dsa_sha2_256s); + } + } + + public static class Shake_128f + extends SLHDSAKeyFactorySpi + { + public Shake_128f() + { + super(NISTObjectIdentifiers.id_slh_dsa_shake_128f); + } + } + + public static class Shake_128s + extends SLHDSAKeyFactorySpi + { + public Shake_128s() + { + super(NISTObjectIdentifiers.id_slh_dsa_shake_128s); + } + } + + public static class Shake_192f + extends SLHDSAKeyFactorySpi + { + public Shake_192f() + { + super(NISTObjectIdentifiers.id_slh_dsa_shake_192f); + } + } + + public static class Shake_192s + extends SLHDSAKeyFactorySpi + { + public Shake_192s() + { + super(NISTObjectIdentifiers.id_slh_dsa_shake_192s); + } + } + + public static class Shake_256f + extends SLHDSAKeyFactorySpi + { + public Shake_256f() + { + super(NISTObjectIdentifiers.id_slh_dsa_shake_256f); + } + } + + public static class Shake_256s + extends SLHDSAKeyFactorySpi + { + public Shake_256s() + { + super(NISTObjectIdentifiers.id_slh_dsa_shake_256s); + } + } + + public static class Hash + extends SLHDSAKeyFactorySpi + { + public Hash() + { + super(hashKeyOids); + } + } + + public static class HashSha2_128f + extends SLHDSAKeyFactorySpi + { + public HashSha2_128f() + { + super(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256); + } + } + + public static class HashSha2_128s + extends SLHDSAKeyFactorySpi + { + public HashSha2_128s() + { + super(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256); + } + } + + public static class HashSha2_192f + extends SLHDSAKeyFactorySpi + { + public HashSha2_192f() + { + super(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512); + } + } + + public static class HashSha2_192s + extends SLHDSAKeyFactorySpi + { + public HashSha2_192s() + { + super(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512); + } + } + + public static class HashSha2_256f + extends SLHDSAKeyFactorySpi + { + public HashSha2_256f() + { + super(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512); + } + } + + public static class HashSha2_256s + extends SLHDSAKeyFactorySpi + { + public HashSha2_256s() + { + super(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512); + } + } + + public static class HashShake_128f + extends SLHDSAKeyFactorySpi + { + public HashShake_128f() + { + super(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128); + } + } + + public static class HashShake_128s + extends SLHDSAKeyFactorySpi + { + public HashShake_128s() + { + super(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128); + } + } + + public static class HashShake_192f + extends SLHDSAKeyFactorySpi + { + public HashShake_192f() + { + super(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256); + } + } + + public static class HashShake_192s + extends SLHDSAKeyFactorySpi + { + public HashShake_192s() + { + super(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256); + } + } + + public static class HashShake_256f + extends SLHDSAKeyFactorySpi + { + public HashShake_256f() + { + super(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256); + } + } + + public static class HashShake_256s + extends SLHDSAKeyFactorySpi + { + public HashShake_256s() + { + super(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/SLHDSAKeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/SLHDSAKeyPairGeneratorSpi.java new file mode 100644 index 0000000000..99a6f3d18d --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/SLHDSAKeyPairGeneratorSpi.java @@ -0,0 +1,378 @@ +package org.bouncycastle.jcajce.provider.asymmetric.slhdsa; + +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; +import java.util.HashMap; +import java.util.Map; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAKeyPairGenerator; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAPublicKeyParameters; +import org.bouncycastle.pqc.jcajce.provider.util.SpecUtil; +import org.bouncycastle.util.Strings; + +public class SLHDSAKeyPairGeneratorSpi + extends java.security.KeyPairGenerator +{ + private static Map parameters = new HashMap(); + + static + { + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_128f.getName(), SLHDSAParameters.sha2_128f); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_128s.getName(), SLHDSAParameters.sha2_128s); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_192f.getName(), SLHDSAParameters.sha2_192f); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_192s.getName(), SLHDSAParameters.sha2_192s); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_256f.getName(), SLHDSAParameters.sha2_256f); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_256s.getName(), SLHDSAParameters.sha2_256s); + + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_128f.getName(), SLHDSAParameters.shake_128f); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_128s.getName(), SLHDSAParameters.shake_128s); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_192f.getName(), SLHDSAParameters.shake_192f); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_192s.getName(), SLHDSAParameters.shake_192s); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_256f.getName(), SLHDSAParameters.shake_256f); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_256s.getName(), SLHDSAParameters.shake_256s); + + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_128f_with_sha256.getName(), SLHDSAParameters.sha2_128f_with_sha256); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_128s_with_sha256.getName(), SLHDSAParameters.sha2_128s_with_sha256); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_192f_with_sha512.getName(), SLHDSAParameters.sha2_192f_with_sha512); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_192s_with_sha512.getName(), SLHDSAParameters.sha2_192s_with_sha512); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_256f_with_sha512.getName(), SLHDSAParameters.sha2_256f_with_sha512); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_256s_with_sha512.getName(), SLHDSAParameters.sha2_256s_with_sha512); + + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_128f_with_shake128.getName(), SLHDSAParameters.shake_128f_with_shake128); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_128s_with_shake128.getName(), SLHDSAParameters.shake_128s_with_shake128); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_192f_with_shake256.getName(), SLHDSAParameters.shake_192f_with_shake256); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_192s_with_shake256.getName(), SLHDSAParameters.shake_192s_with_shake256); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_256f_with_shake256.getName(), SLHDSAParameters.shake_256f_with_shake256); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_256s_with_shake256.getName(), SLHDSAParameters.shake_256s_with_shake256); + } + + SLHDSAKeyGenerationParameters param; + SLHDSAKeyPairGenerator engine = new SLHDSAKeyPairGenerator(); + + SecureRandom random = CryptoServicesRegistrar.getSecureRandom(); + boolean initialised = false; + + public SLHDSAKeyPairGeneratorSpi(String name) + { + super(name); + } + + protected SLHDSAKeyPairGeneratorSpi(SLHDSAParameterSpec paramSpec) + { + super("SLH-DSA" + "-" + Strings.toUpperCase(paramSpec.getName())); + + param = new SLHDSAKeyGenerationParameters(random, (SLHDSAParameters)parameters.get(paramSpec.getName())); + + engine.init(param); + initialised = true; + } + + public void initialize( + int strength, + SecureRandom random) + { + throw new IllegalArgumentException("use AlgorithmParameterSpec"); + } + + public void initialize( + AlgorithmParameterSpec params, + SecureRandom random) + throws InvalidAlgorithmParameterException + { + String name = getNameFromParams(params); + + if (name != null) + { + param = new SLHDSAKeyGenerationParameters(random, (SLHDSAParameters)parameters.get(name)); + + engine.init(param); + initialised = true; + } + else + { + throw new InvalidAlgorithmParameterException("invalid ParameterSpec: " + params); + } + } + + public KeyPair generateKeyPair() + { + if (!initialised) + { + if (this.getAlgorithm().startsWith("HASH")) + { + param = new SLHDSAKeyGenerationParameters(random, SLHDSAParameters.sha2_256s_with_sha512); + } + else + { + param = new SLHDSAKeyGenerationParameters(random, SLHDSAParameters.sha2_256s); + } + + engine.init(param); + initialised = true; + } + + AsymmetricCipherKeyPair pair = engine.generateKeyPair(); + SLHDSAPublicKeyParameters pub = (SLHDSAPublicKeyParameters)pair.getPublic(); + SLHDSAPrivateKeyParameters priv = (SLHDSAPrivateKeyParameters)pair.getPrivate(); + + return new KeyPair(new BCSLHDSAPublicKey(pub), new BCSLHDSAPrivateKey(priv)); + } + + private static String getNameFromParams(AlgorithmParameterSpec paramSpec) + { + if (paramSpec instanceof SLHDSAParameterSpec) + { + SLHDSAParameterSpec params = (SLHDSAParameterSpec)paramSpec; + return params.getName(); + } + else + { + return Strings.toLowerCase(SpecUtil.getNameFrom(paramSpec)); + } + } + + public static class Pure + extends SLHDSAKeyPairGeneratorSpi + { + public Pure() + throws NoSuchAlgorithmException + { + super("SLH-DSA"); + } + } + + public static class Sha2_128s + extends SLHDSAKeyPairGeneratorSpi + { + public Sha2_128s() + { + super(SLHDSAParameterSpec.slh_dsa_sha2_128s); + } + } + + public static class Sha2_128f + extends SLHDSAKeyPairGeneratorSpi + { + public Sha2_128f() + { + super(SLHDSAParameterSpec.slh_dsa_sha2_128f); + } + } + + public static class Sha2_192s + extends SLHDSAKeyPairGeneratorSpi + { + public Sha2_192s() + { + super(SLHDSAParameterSpec.slh_dsa_sha2_192s); + } + } + + public static class Sha2_192f + extends SLHDSAKeyPairGeneratorSpi + { + public Sha2_192f() + { + super(SLHDSAParameterSpec.slh_dsa_sha2_192f); + } + } + + public static class Sha2_256s + extends SLHDSAKeyPairGeneratorSpi + { + public Sha2_256s() + { + super(SLHDSAParameterSpec.slh_dsa_sha2_256s); + } + } + + public static class Sha2_256f + extends SLHDSAKeyPairGeneratorSpi + { + public Sha2_256f() + { + super(SLHDSAParameterSpec.slh_dsa_sha2_256f); + } + } + + public static class Shake_128s + extends SLHDSAKeyPairGeneratorSpi + { + public Shake_128s() + { + super(SLHDSAParameterSpec.slh_dsa_shake_128s); + } + } + + public static class Shake_128f + extends SLHDSAKeyPairGeneratorSpi + { + public Shake_128f() + { + super(SLHDSAParameterSpec.slh_dsa_shake_128f); + } + } + + public static class Shake_192s + extends SLHDSAKeyPairGeneratorSpi + { + public Shake_192s() + { + super(SLHDSAParameterSpec.slh_dsa_shake_192s); + } + } + + public static class Shake_192f + extends SLHDSAKeyPairGeneratorSpi + { + public Shake_192f() + { + super(SLHDSAParameterSpec.slh_dsa_shake_192f); + } + } + + public static class Shake_256s + extends SLHDSAKeyPairGeneratorSpi + { + public Shake_256s() + { + super(SLHDSAParameterSpec.slh_dsa_shake_256s); + } + } + + public static class Hash + extends SLHDSAKeyPairGeneratorSpi + { + public Hash() + throws NoSuchAlgorithmException + { + super("HASH-SLH-DSA"); + } + } + + public static class Shake_256f + extends SLHDSAKeyPairGeneratorSpi + { + public Shake_256f() + { + super(SLHDSAParameterSpec.slh_dsa_shake_256f); + } + } + + public static class HashSha2_128s + extends SLHDSAKeyPairGeneratorSpi + { + public HashSha2_128s() + { + super(SLHDSAParameterSpec.slh_dsa_sha2_128s_with_sha256); + } + } + + public static class HashSha2_128f + extends SLHDSAKeyPairGeneratorSpi + { + public HashSha2_128f() + { + super(SLHDSAParameterSpec.slh_dsa_sha2_128f_with_sha256); + } + } + + public static class HashSha2_192s + extends SLHDSAKeyPairGeneratorSpi + { + public HashSha2_192s() + { + super(SLHDSAParameterSpec.slh_dsa_sha2_192s_with_sha512); + } + } + + public static class HashSha2_192f + extends SLHDSAKeyPairGeneratorSpi + { + public HashSha2_192f() + { + super(SLHDSAParameterSpec.slh_dsa_sha2_192f_with_sha512); + } + } + + public static class HashSha2_256s + extends SLHDSAKeyPairGeneratorSpi + { + public HashSha2_256s() + { + super(SLHDSAParameterSpec.slh_dsa_sha2_256s_with_sha512); + } + } + + public static class HashSha2_256f + extends SLHDSAKeyPairGeneratorSpi + { + public HashSha2_256f() + { + super(SLHDSAParameterSpec.slh_dsa_sha2_256f_with_sha512); + } + } + + public static class HashShake_128s + extends SLHDSAKeyPairGeneratorSpi + { + public HashShake_128s() + { + super(SLHDSAParameterSpec.slh_dsa_shake_128s_with_shake128); + } + } + + public static class HashShake_128f + extends SLHDSAKeyPairGeneratorSpi + { + public HashShake_128f() + { + super(SLHDSAParameterSpec.slh_dsa_shake_128f_with_shake128); + } + } + + public static class HashShake_192s + extends SLHDSAKeyPairGeneratorSpi + { + public HashShake_192s() + { + super(SLHDSAParameterSpec.slh_dsa_shake_192s_with_shake256); + } + } + + public static class HashShake_192f + extends SLHDSAKeyPairGeneratorSpi + { + public HashShake_192f() + { + super(SLHDSAParameterSpec.slh_dsa_shake_192f_with_shake256); + } + } + + public static class HashShake_256s + extends SLHDSAKeyPairGeneratorSpi + { + public HashShake_256s() + { + super(SLHDSAParameterSpec.slh_dsa_shake_256s_with_shake256); + } + } + + public static class HashShake_256f + extends SLHDSAKeyPairGeneratorSpi + { + public HashShake_256f() + { + super(SLHDSAParameterSpec.slh_dsa_shake_256f_with_shake256); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/SignatureSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/SignatureSpi.java new file mode 100644 index 0000000000..f61187bdc9 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/SignatureSpi.java @@ -0,0 +1,144 @@ +package org.bouncycastle.jcajce.provider.asymmetric.slhdsa; + +import java.security.InvalidKeyException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.SignatureException; +import java.security.spec.AlgorithmParameterSpec; + +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.digests.NullDigest; +import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.pqc.crypto.slhdsa.SLHDSASigner; + +public class SignatureSpi + extends java.security.SignatureSpi +{ + private final Digest digest; + private final SLHDSASigner signer; + + protected SignatureSpi(Digest digest, SLHDSASigner signer) + { + this.digest = digest; + this.signer = signer; + } + + protected void engineInitVerify(PublicKey publicKey) + throws InvalidKeyException + { + if (publicKey instanceof BCSLHDSAPublicKey) + { + BCSLHDSAPublicKey key = (BCSLHDSAPublicKey)publicKey; + + CipherParameters param = key.getKeyParams(); + + signer.init(false, param); + } + else + { + throw new InvalidKeyException("unknown public key passed to SLH-DSA"); + } + } + + protected void engineInitSign(PrivateKey privateKey, SecureRandom random) + throws InvalidKeyException + { + this.appRandom = random; + engineInitSign(privateKey); + } + + protected void engineInitSign(PrivateKey privateKey) + throws InvalidKeyException + { + if (privateKey instanceof BCSLHDSAPrivateKey) + { + BCSLHDSAPrivateKey key = (BCSLHDSAPrivateKey)privateKey; + + CipherParameters param = key.getKeyParams(); + + if (appRandom != null) + { + signer.init(true, new ParametersWithRandom(param, appRandom)); + } + else + { + signer.init(true, param); + } + } + else + { + throw new InvalidKeyException("unknown private key passed to SLH-DSA"); + } + } + + protected void engineUpdate(byte b) + throws SignatureException + { + digest.update(b); + } + + protected void engineUpdate(byte[] b, int off, int len) + throws SignatureException + { + digest.update(b, off, len); + } + + protected byte[] engineSign() + throws SignatureException + { + byte[] hash = new byte[digest.getDigestSize()]; + digest.doFinal(hash, 0); + try + { + byte[] sig = signer.generateSignature(hash); + + return sig; + } + catch (Exception e) + { + throw new SignatureException(e.toString()); + } + } + + protected boolean engineVerify(byte[] sigBytes) + throws SignatureException + { + byte[] hash = new byte[digest.getDigestSize()]; + digest.doFinal(hash, 0); + + return signer.verifySignature(hash, sigBytes); + } + + protected void engineSetParameter(AlgorithmParameterSpec params) + { + // TODO + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + /** + * @deprecated replaced with #engineSetParameter(java.security.spec.AlgorithmParameterSpec) + */ + protected void engineSetParameter(String param, Object value) + { + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + /** + * @deprecated + */ + protected Object engineGetParameter(String param) + { + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + static public class Direct + extends SignatureSpi + { + public Direct() + { + super(new NullDigest(), new SLHDSASigner()); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java index 374db2026b..cd9699033d 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java @@ -17,18 +17,20 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; -import org.bouncycastle.asn1.gnu.GNUObjectIdentifiers; -import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.agreement.kdf.DHKDFParameters; import org.bouncycastle.crypto.agreement.kdf.DHKEKGenerator; +import org.bouncycastle.crypto.generators.HKDFBytesGenerator; import org.bouncycastle.crypto.params.DESParameters; +import org.bouncycastle.crypto.params.HKDFParameters; import org.bouncycastle.crypto.params.KDFParameters; +import org.bouncycastle.internal.asn1.gnu.GNUObjectIdentifiers; +import org.bouncycastle.internal.asn1.kisa.KISAObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.ntt.NTTObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.spec.HybridValueParameterSpec; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; @@ -149,7 +151,8 @@ public abstract class BaseAgreementSpi protected final String kaAlgorithm; protected final DerivationFunction kdf; - protected byte[] ukmParameters; + protected byte[] ukmParameters; + protected byte[] ukmParametersSalt; private HybridValueParameterSpec hybridSpec; public BaseAgreementSpi(String kaAlgorithm, DerivationFunction kdf) @@ -223,8 +226,8 @@ protected static byte[] trimZeroes(byte[] secret) } protected void engineInit( - Key key, - SecureRandom random) + Key key, + SecureRandom random) throws InvalidKeyException { try @@ -247,6 +250,7 @@ protected void engineInit( if (params instanceof HybridValueParameterSpec) { this.hybridSpec = (HybridValueParameterSpec)params; + doInitFromKey(key, hybridSpec.getBaseParameterSpec(), random); } else @@ -276,8 +280,8 @@ protected byte[] engineGenerateSecret() } protected int engineGenerateSecret( - byte[] sharedSecret, - int offset) + byte[] sharedSecret, + int offset) throws IllegalStateException, ShortBufferException { byte[] secret = engineGenerateSecret(); @@ -304,7 +308,7 @@ protected SecretKey engineGenerateSecret( oidAlgorithm = ((ASN1ObjectIdentifier)oids.get(algKey)).getId(); } - int keySize = getKeySize(oidAlgorithm); + int keySize = getKeySize(oidAlgorithm); byte[] secret = getSharedSecretBytes(calcSecret(), oidAlgorithm, keySize); @@ -348,6 +352,10 @@ private byte[] getSharedSecretBytes(byte[] secret, String oidAlgorithm, int keyS kdf.init(params); } + else if (kdf instanceof HKDFBytesGenerator) + { + kdf.init(new HKDFParameters(secret, ukmParametersSalt, ukmParameters)); + } else { KDFParameters params = new KDFParameters(secret, ukmParameters); @@ -384,7 +392,16 @@ private byte[] calcSecret() { // Set Z' to Z || T byte[] s = doCalcSecret(); - byte[] sec = Arrays.concatenate(s, hybridSpec.getT()); + byte[] sec; + + if (hybridSpec.isPrependedT()) + { + sec = Arrays.concatenate(hybridSpec.getT(), s); + } + else + { + sec = Arrays.concatenate(s, hybridSpec.getT()); + } Arrays.clear(s); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/DESUtil.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/DESUtil.java index a62602d7a6..89e5dffd78 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/DESUtil.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/DESUtil.java @@ -3,8 +3,8 @@ import java.util.HashSet; import java.util.Set; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.util.Strings; public class DESUtil diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java index 0eeaffbe44..a5ad53db2f 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java @@ -278,14 +278,14 @@ public static ECCurve convertCurve( if (field instanceof ECFieldFp) { - return CustomCurves.substitute(new ECCurve.Fp(((ECFieldFp)field).getP(), a, b)); + return CustomCurves.substitute(new ECCurve.Fp(((ECFieldFp)field).getP(), a, b, null, null)); } else { ECFieldF2m fieldF2m = (ECFieldF2m)field; int m = fieldF2m.getM(); int ks[] = ECUtil.convertMidTerms(fieldF2m.getMidTermsOfReductionPolynomial()); - return new ECCurve.F2m(m, ks[0], ks[1], ks[2], a, b); + return new ECCurve.F2m(m, ks[0], ks[1], ks[2], a, b, null, null); } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java index d367b0bf85..c1c93b88d4 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java @@ -291,6 +291,11 @@ public static int getOrderBitLength(ProviderConfiguration configuration, BigInte { if (order == null) // implicitly CA { + if (configuration == null) + { + return privateValue.bitLength(); // a guess but better than an exception! + } + ECParameterSpec implicitCA = configuration.getEcImplicitlyCa(); if (implicitCA == null) diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java index 644a057a55..20f6972188 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java @@ -28,6 +28,7 @@ import javax.security.auth.x500.X500Principal; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; @@ -36,7 +37,6 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; @@ -54,6 +54,7 @@ import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Exceptions; import org.bouncycastle.util.Strings; /** @@ -143,16 +144,23 @@ public Set getNonCriticalExtensionOIDs() public byte[] getExtensionValue(String oid) { - ASN1OctetString extValue = getExtensionValue(c, oid); - if (null != extValue) + if (oid != null) { - try - { - return extValue.getEncoded(); - } - catch (Exception e) + ASN1ObjectIdentifier asn1Oid = ASN1ObjectIdentifier.tryFromID(oid); + if (asn1Oid != null) { - throw new IllegalStateException("error parsing " + e.toString()); + ASN1OctetString extValue = getExtensionValue(c, asn1Oid); + if (null != extValue) + { + try + { + return extValue.getEncoded(); + } + catch (Exception e) + { + throw Exceptions.illegalStateException("error parsing " + e.getMessage(), e); + } + } } } return null; @@ -242,7 +250,7 @@ private void doVerify(PublicKey key, SignatureCreator sigCreator) { List pubKeys = ((CompositePublicKey)key).getPublicKeys(); ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters()); - ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes()); + ASN1Sequence sigSeq = ASN1Sequence.getInstance(c.getSignature().getOctets()); boolean success = false; for (int i = 0; i != pubKeys.size(); i++) @@ -264,7 +272,7 @@ private void doVerify(PublicKey key, SignatureCreator sigCreator) checkSignature( (PublicKey)pubKeys.get(i), signature, sigAlg.getParameters(), - DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes()); + ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getOctets()); success = true; } catch (SignatureException e) @@ -286,7 +294,7 @@ private void doVerify(PublicKey key, SignatureCreator sigCreator) else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm())) { ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters()); - ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes()); + ASN1Sequence sigSeq = ASN1Sequence.getInstance(c.getSignature().getOctets()); boolean success = false; for (int i = 0; i != sigSeq.size(); i++) @@ -303,7 +311,7 @@ else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm())) checkSignature( key, signature, sigAlg.getParameters(), - DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes()); + ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getOctets()); success = true; } @@ -353,20 +361,22 @@ else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm())) } } - private void checkSignature(PublicKey key, Signature sig, ASN1Encodable sigAlgParams, byte[] encSig) - throws NoSuchAlgorithmException, SignatureException, InvalidKeyException, CRLException + private void checkSignature(PublicKey key, Signature signature, ASN1Encodable sigAlgParams, byte[] sigBytes) + throws CRLException, InvalidKeyException, NoSuchAlgorithmException, SignatureException { - if (sigAlgParams != null) + if (!X509SignatureUtil.areEquivalentAlgorithms(c.getSignatureAlgorithm(), c.getTBSCertList().getSignature())) { - // needs to be called before initVerify(). - X509SignatureUtil.setSignatureParameters(sig, sigAlgParams); + throw new CRLException("Signature algorithm on CertificateList does not match TbsCertList."); } - sig.initVerify(key); + // needs to be called before initVerify(). + X509SignatureUtil.setSignatureParameters(signature, sigAlgParams); + + signature.initVerify(key); try { - OutputStream sigOut = new BufferedOutputStream(OutputStreamFactory.createStream(sig), 512); + OutputStream sigOut = new BufferedOutputStream(OutputStreamFactory.createStream(signature), 512); c.getTBSCertList().encodeTo(sigOut, ASN1Encoding.DER); @@ -377,7 +387,7 @@ private void checkSignature(PublicKey key, Signature sig, ASN1Encodable sigAlgPa throw new CRLException(e.toString()); } - if (!sig.verify(encSig)) + if (!signature.verify(sigBytes)) { throw new SignatureException("CRL does not verify with supplied public key."); } @@ -696,7 +706,7 @@ public boolean isRevoked(Certificate cert) return false; } - protected static byte[] getExtensionOctets(CertificateList c, String oid) + static byte[] getExtensionOctets(CertificateList c, ASN1ObjectIdentifier oid) { ASN1OctetString extValue = getExtensionValue(c, oid); if (null != extValue) @@ -706,12 +716,12 @@ protected static byte[] getExtensionOctets(CertificateList c, String oid) return null; } - protected static ASN1OctetString getExtensionValue(CertificateList c, String oid) + static ASN1OctetString getExtensionValue(CertificateList c, ASN1ObjectIdentifier oid) { Extensions exts = c.getTBSCertList().getExtensions(); if (null != exts) { - Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); + Extension ext = exts.getExtension(oid); if (null != ext) { return ext.getExtnValue(); @@ -720,4 +730,3 @@ protected static ASN1OctetString getExtensionValue(CertificateList c, String oid return null; } } - diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java index 8e4efe27f1..752e7fef6e 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java @@ -144,7 +144,7 @@ private static boolean isIndirectCRL(CertificateList c) throws CRLException { try { - byte[] extOctets = getExtensionOctets(c, Extension.issuingDistributionPoint.getId()); + byte[] extOctets = getExtensionOctets(c, Extension.issuingDistributionPoint); if (null == extOctets) { return false; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java index 72ac260024..2665531c27 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java @@ -36,18 +36,12 @@ import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1IA5String; import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; -import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; -import org.bouncycastle.asn1.DERBitString; -import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; -import org.bouncycastle.asn1.misc.NetscapeCertType; -import org.bouncycastle.asn1.misc.NetscapeRevocationURL; -import org.bouncycastle.asn1.misc.VerisignCzagExtension; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.RFC4519Style; @@ -58,6 +52,10 @@ import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.TBSCertificate; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.NetscapeCertType; +import org.bouncycastle.internal.asn1.misc.NetscapeRevocationURL; +import org.bouncycastle.internal.asn1.misc.VerisignCzagExtension; import org.bouncycastle.jcajce.CompositePublicKey; import org.bouncycastle.jcajce.interfaces.BCX509Certificate; import org.bouncycastle.jcajce.io.OutputStreamFactory; @@ -67,7 +65,6 @@ import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Exceptions; import org.bouncycastle.util.Integers; -import org.bouncycastle.util.Properties; import org.bouncycastle.util.Strings; abstract class X509CertificateImpl @@ -80,6 +77,7 @@ abstract class X509CertificateImpl protected boolean[] keyUsage; protected String sigAlgName; protected byte[] sigAlgParams; + X509CertificateImpl(JcaJceHelper bcHelper, org.bouncycastle.asn1.x509.Certificate c, BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams) { @@ -276,7 +274,7 @@ public boolean[] getKeyUsage() public List getExtendedKeyUsage() throws CertificateParsingException { - byte[] extOctets = getExtensionOctets(c, "2.5.29.37"); + byte[] extOctets = getExtensionOctets(c, Extension.extendedKeyUsage); if (null == extOctets) { return null; @@ -284,7 +282,7 @@ public List getExtendedKeyUsage() try { - ASN1Sequence seq = ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(extOctets)); + ASN1Sequence seq = ASN1Sequence.getInstance(extOctets); List list = new ArrayList(); for (int i = 0; i != seq.size(); i++) @@ -298,41 +296,33 @@ public List getExtendedKeyUsage() throw new CertificateParsingException("error processing extended key usage extension"); } } - + public int getBasicConstraints() { - if (basicConstraints != null) + if (basicConstraints == null || !basicConstraints.isCA()) { - if (basicConstraints.isCA()) - { - if (basicConstraints.getPathLenConstraint() == null) - { - return Integer.MAX_VALUE; - } - else - { - return basicConstraints.getPathLenConstraint().intValue(); - } - } - else - { - return -1; - } + return -1; + } + + ASN1Integer pathLenConstraint = basicConstraints.getPathLenConstraintInteger(); + if (pathLenConstraint == null) + { + return Integer.MAX_VALUE; } - return -1; + return pathLenConstraint.intPositiveValueExact(); } public Collection getSubjectAlternativeNames() throws CertificateParsingException { - return getAlternativeNames(c, Extension.subjectAlternativeName.getId()); + return getAlternativeNames(c, Extension.subjectAlternativeName); } public Collection getIssuerAlternativeNames() throws CertificateParsingException { - return getAlternativeNames(c, Extension.issuerAlternativeName.getId()); + return getAlternativeNames(c, Extension.issuerAlternativeName); } public Set getCriticalExtensionOIDs() @@ -366,19 +356,25 @@ public Set getCriticalExtensionOIDs() public byte[] getExtensionValue(String oid) { - ASN1OctetString extValue = getExtensionValue(c, oid); - if (null != extValue) + if (oid != null) { - try + ASN1ObjectIdentifier asn1Oid = ASN1ObjectIdentifier.tryFromID(oid); + if (asn1Oid != null) { - return extValue.getEncoded(); - } - catch (Exception e) - { - throw Exceptions.illegalStateException("error parsing " + e.getMessage(), e); + ASN1OctetString extValue = getExtensionValue(c, asn1Oid); + if (null != extValue) + { + try + { + return extValue.getEncoded(); + } + catch (Exception e) + { + throw Exceptions.illegalStateException("error parsing " + e.getMessage(), e); + } + } } } - return null; } @@ -514,7 +510,7 @@ else if (oid.equals(Extension.keyUsage)) } else if (oid.equals(MiscObjectIdentifiers.netscapeCertType)) { - buf.append(new NetscapeCertType(DERBitString.getInstance(dIn.readObject()))).append(nl); + buf.append(new NetscapeCertType(ASN1BitString.getInstance(dIn.readObject()))).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL)) { @@ -634,7 +630,7 @@ private void doVerify( { List pubKeys = ((CompositePublicKey)key).getPublicKeys(); ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters()); - ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes()); + ASN1Sequence sigSeq = ASN1Sequence.getInstance(c.getSignature().getOctets()); boolean success = false; for (int i = 0; i != pubKeys.size(); i++) @@ -655,7 +651,7 @@ private void doVerify( checkSignature( (PublicKey)pubKeys.get(i), signature, sigAlg.getParameters(), - DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes()); + ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getOctets()); success = true; } catch (SignatureException e) @@ -677,7 +673,7 @@ private void doVerify( else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm())) { ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters()); - ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes()); + ASN1Sequence sigSeq = ASN1Sequence.getInstance(c.getSignature().getOctets()); boolean success = false; for (int i = 0; i != sigSeq.size(); i++) @@ -694,7 +690,7 @@ else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm())) checkSignature( key, signature, sigAlg.getParameters(), - DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes()); + ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getOctets()); success = true; } @@ -724,11 +720,11 @@ else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm())) } else { - String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); + Signature signature = signatureCreator.createSignature(getSigAlgName()); - Signature signature = signatureCreator.createSignature(sigName); - - if (key instanceof CompositePublicKey) + //Use this only for legacy composite public keys (they have this identifier) + if (key instanceof CompositePublicKey + && MiscObjectIdentifiers.id_composite_key.equals(((CompositePublicKey)key).getAlgorithmIdentifier())) { List keys = ((CompositePublicKey)key).getPublicKeys(); @@ -756,21 +752,16 @@ else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm())) } } - private void checkSignature( - PublicKey key, - Signature signature, - ASN1Encodable params, - byte[] sigBytes) - throws CertificateException, NoSuchAlgorithmException, - SignatureException, InvalidKeyException + private void checkSignature(PublicKey key, Signature signature, ASN1Encodable sigAlgParams, byte[] sigBytes) + throws CertificateException, InvalidKeyException, NoSuchAlgorithmException, SignatureException { - if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature())) + if (!X509SignatureUtil.areEquivalentAlgorithms(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature())) { throw new CertificateException("signature algorithm in TBS cert not same as outer cert"); } - // TODO This should go after the initVerify? - X509SignatureUtil.setSignatureParameters(signature, params); + // needs to be called before initVerify(). + X509SignatureUtil.setSignatureParameters(signature, sigAlgParams); signature.initVerify(key); @@ -793,50 +784,7 @@ private void checkSignature( } } - private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2) - { - if (!id1.getAlgorithm().equals(id2.getAlgorithm())) - { - return false; - } - - if (Properties.isOverrideSet("org.bouncycastle.x509.allow_absent_equiv_NULL")) - { - if (id1.getParameters() == null) - { - if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE)) - { - return false; - } - - return true; - } - - if (id2.getParameters() == null) - { - if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE)) - { - return false; - } - - return true; - } - } - - if (id1.getParameters() != null) - { - return id1.getParameters().equals(id2.getParameters()); - } - - if (id2.getParameters() != null) - { - return id2.getParameters().equals(id1.getParameters()); - } - - return true; - } - - private static Collection getAlternativeNames(org.bouncycastle.asn1.x509.Certificate c, String oid) + private static Collection getAlternativeNames(org.bouncycastle.asn1.x509.Certificate c, ASN1ObjectIdentifier oid) throws CertificateParsingException { byte[] extOctets = getExtensionOctets(c, oid); @@ -902,7 +850,7 @@ private static Collection getAlternativeNames(org.bouncycastle.asn1.x509.Certifi } } - protected static byte[] getExtensionOctets(org.bouncycastle.asn1.x509.Certificate c, String oid) + static byte[] getExtensionOctets(org.bouncycastle.asn1.x509.Certificate c, ASN1ObjectIdentifier oid) { ASN1OctetString extValue = getExtensionValue(c, oid); if (null != extValue) @@ -912,12 +860,12 @@ protected static byte[] getExtensionOctets(org.bouncycastle.asn1.x509.Certificat return null; } - protected static ASN1OctetString getExtensionValue(org.bouncycastle.asn1.x509.Certificate c, String oid) + static ASN1OctetString getExtensionValue(org.bouncycastle.asn1.x509.Certificate c, ASN1ObjectIdentifier oid) { Extensions exts = c.getTBSCertificate().getExtensions(); if (null != exts) { - Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); + Extension ext = exts.getExtension(oid); if (null != ext) { return ext.getExtnValue(); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java index 2565ba0f7f..2fc51103a3 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java @@ -15,9 +15,8 @@ import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; @@ -289,13 +288,13 @@ private static BasicConstraints createBasicConstraints(org.bouncycastle.asn1.x50 { try { - byte[] extOctets = getExtensionOctets(c, "2.5.29.19"); + byte[] extOctets = getExtensionOctets(c, Extension.basicConstraints); if (null == extOctets) { return null; } - return BasicConstraints.getInstance(ASN1Primitive.fromByteArray(extOctets)); + return BasicConstraints.getInstance(extOctets); } catch (Exception e) { @@ -307,13 +306,13 @@ private static boolean[] createKeyUsage(org.bouncycastle.asn1.x509.Certificate c { try { - byte[] extOctets = getExtensionOctets(c, "2.5.29.15"); + byte[] extOctets = getExtensionOctets(c, Extension.keyUsage); if (null == extOctets) { return null; } - ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(extOctets)); + ASN1BitString bits = ASN1BitString.getInstance(extOctets); byte[] bytes = bits.getBytes(); int length = (bytes.length * 8) - bits.getPadBits(); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java index 996ace14fd..dbf2d9ff93 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java @@ -14,19 +14,20 @@ import java.util.Map; import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.util.MessageDigestUtils; import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.Objects; +import org.bouncycastle.util.Properties; import org.bouncycastle.util.encoders.Hex; class X509SignatureUtil @@ -41,21 +42,41 @@ class X509SignatureUtil algNames.put(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1withDSA"); } - private static final ASN1Null derNull = DERNull.INSTANCE; + static boolean areEquivalentAlgorithms(AlgorithmIdentifier id1, AlgorithmIdentifier id2) + { + if (!id1.getAlgorithm().equals(id2.getAlgorithm())) + { + return false; + } + + if (Properties.isOverrideSet("org.bouncycastle.x509.allow_absent_equiv_NULL")) + { + if (isAbsentOrEmptyParameters(id1.getParameters()) && isAbsentOrEmptyParameters(id2.getParameters())) + { + return true; + } + } + + return Objects.areEqual(id1.getParameters(), id2.getParameters()); + } + + private static boolean isAbsentOrEmptyParameters(ASN1Encodable parameters) + { + return parameters == null || DERNull.INSTANCE.equals(parameters); + } static boolean isCompositeAlgorithm(AlgorithmIdentifier algorithmIdentifier) { return MiscObjectIdentifiers.id_alg_composite.equals(algorithmIdentifier.getAlgorithm()); } - static void setSignatureParameters( - Signature signature, - ASN1Encodable params) + static void setSignatureParameters(Signature signature, ASN1Encodable params) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException { - if (params != null && !derNull.equals(params)) + if (!isAbsentOrEmptyParameters(params)) { - AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider()); + String sigAlgName = signature.getAlgorithm(); + AlgorithmParameters sigParams = AlgorithmParameters.getInstance(sigAlgName, signature.getProvider()); try { @@ -66,7 +87,7 @@ static void setSignatureParameters( throw new SignatureException("IOException decoding parameters: " + e.getMessage()); } - if (signature.getAlgorithm().endsWith("MGF1")) + if (sigAlgName.endsWith("MGF1")) { try { @@ -80,20 +101,20 @@ static void setSignatureParameters( } } - static String getSignatureName( - AlgorithmIdentifier sigAlgId) + static String getSignatureName(AlgorithmIdentifier sigAlgId) { + ASN1ObjectIdentifier sigAlgOid = sigAlgId.getAlgorithm(); ASN1Encodable params = sigAlgId.getParameters(); - if (params != null && !derNull.equals(params)) + if (!isAbsentOrEmptyParameters(params)) { - if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) + if (PKCSObjectIdentifiers.id_RSASSA_PSS.equals(sigAlgOid)) { RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "withRSAandMGF1"; } - if (sigAlgId.getAlgorithm().equals(X9ObjectIdentifiers.ecdsa_with_SHA2)) + if (X9ObjectIdentifiers.ecdsa_with_SHA2.equals(sigAlgOid)) { ASN1Sequence ecDsaParams = ASN1Sequence.getInstance(params); @@ -102,13 +123,13 @@ static String getSignatureName( } // deal with the "weird" ones. - String algName = (String)algNames.get(sigAlgId.getAlgorithm()); + String algName = (String)algNames.get(sigAlgOid); if (algName != null) { return algName; } - return findAlgName(sigAlgId.getAlgorithm()); + return findAlgName(sigAlgOid); } /** diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Blake2b.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Blake2b.java index 0eb978a924..b7000e581c 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Blake2b.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Blake2b.java @@ -1,7 +1,7 @@ package org.bouncycastle.jcajce.provider.digest; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.crypto.digests.Blake2bDigest; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; public class Blake2b diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Blake2s.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Blake2s.java index a79fbe974b..7d6fabb965 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Blake2s.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Blake2s.java @@ -1,7 +1,7 @@ package org.bouncycastle.jcajce.provider.digest; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.crypto.digests.Blake2sDigest; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; public class Blake2s diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Blake3.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Blake3.java index 2ebe1bacac..500903d2e3 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Blake3.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Blake3.java @@ -1,7 +1,7 @@ package org.bouncycastle.jcajce.provider.digest; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.crypto.digests.Blake3Digest; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; public class Blake3 diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/GOST3411.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/GOST3411.java index 6d5dfa3d00..fa732adea7 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/GOST3411.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/GOST3411.java @@ -1,12 +1,12 @@ package org.bouncycastle.jcajce.provider.digest; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.GOST3411Digest; import org.bouncycastle.crypto.digests.GOST3411_2012_256Digest; import org.bouncycastle.crypto.digests.GOST3411_2012_512Digest; import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/MD5.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/MD5.java index 93a7d71617..c176c4c05f 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/MD5.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/MD5.java @@ -1,10 +1,10 @@ package org.bouncycastle.jcajce.provider.digest; -import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.internal.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/RIPEMD160.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/RIPEMD160.java index f081713a36..3e9d13aaf5 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/RIPEMD160.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/RIPEMD160.java @@ -1,10 +1,10 @@ package org.bouncycastle.jcajce.provider.digest; -import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.internal.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java index 17a5462abc..3aee85f1db 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java @@ -1,11 +1,11 @@ package org.bouncycastle.jcajce.provider.digest; -import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.internal.asn1.iana.IANAObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java index e203362f68..77e4a14983 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java @@ -23,14 +23,14 @@ static public class Digest { public Digest() { - super(new SHA256Digest()); + super(SHA256Digest.newInstance()); } public Object clone() throws CloneNotSupportedException { Digest d = (Digest)super.clone(); - d.digest = new SHA256Digest((SHA256Digest)digest); + d.digest = SHA256Digest.newInstance(digest); return d; } @@ -41,7 +41,7 @@ public static class HashMac { public HashMac() { - super(new HMac(new SHA256Digest())); + super(new HMac(SHA256Digest.newInstance())); } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Tiger.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Tiger.java index 3d248aadaf..16434d882b 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Tiger.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Tiger.java @@ -1,9 +1,9 @@ package org.bouncycastle.jcajce.provider.digest; -import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.TigerDigest; import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.internal.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Whirlpool.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Whirlpool.java index e9d22d301f..853db86d10 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Whirlpool.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/digest/Whirlpool.java @@ -1,9 +1,9 @@ package org.bouncycastle.jcajce.provider.digest; -import org.bouncycastle.asn1.iso.ISOIECObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.digests.WhirlpoolDigest; import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.internal.asn1.iso.ISOIECObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/drbg/DRBG.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/drbg/DRBG.java index 035b8e9f3a..437de65ff3 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/drbg/DRBG.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/drbg/DRBG.java @@ -223,7 +223,8 @@ public EntropySource get(int bitsRequired) // unfortunately new SecureRandom() can cause a regress and it's the only reliable way of getting access // to the JVM's seed generator. - private static EntropySourceProvider createInitialEntropySource() + + private static EntropySourceProvider createCoreEntropySourceProvider() { boolean hasGetInstanceStrong = AccessController.doPrivileged(new PrivilegedAction() { @@ -254,36 +255,47 @@ public SecureRandom run() } catch (Exception e) { - return new CoreSecureRandom(findSource()); + return null; } } }); + if (strong == null) + { + return createInitialEntropySource(); + } + return new IncrementalEntropySourceProvider(strong, true); } else { - return new IncrementalEntropySourceProvider(new CoreSecureRandom(findSource()), true); + return createInitialEntropySource(); } } - private static EntropySourceProvider createCoreEntropySourceProvider() + private static EntropySourceProvider createInitialEntropySource() { - if (Security.getProperty("securerandom.source") == null) + String source = AccessController.doPrivileged(new PrivilegedAction() { - return createInitialEntropySource(); + public String run() + { + return Security.getProperty("securerandom.source"); + } + }); + + if (source == null) + { + return new IncrementalEntropySourceProvider(new CoreSecureRandom(findSource()), true); } else { try { - String source = Security.getProperty("securerandom.source"); - return new URLSeededEntropySourceProvider(new URL(source)); } catch (Exception e) { - return createInitialEntropySource(); + return new IncrementalEntropySourceProvider(new CoreSecureRandom(findSource()), true); } } } @@ -496,7 +508,7 @@ public int entropySize() return bytesRequired * 8; } - private class SignallingEntropySource + private static class SignallingEntropySource implements IncrementalEntropySource { private final EntropyDaemon entropyDaemon; @@ -571,7 +583,7 @@ private static class OneShotHybridEntropySource private final AtomicInteger samples = new AtomicInteger(0); private final SP800SecureRandom drbg; - private final SignallingEntropySource entropySource; + private final OneShotSignallingEntropySource entropySource; private final int bytesRequired; private final byte[] additionalInput = Pack.longToBigEndian(System.currentTimeMillis()); @@ -580,7 +592,7 @@ private static class OneShotHybridEntropySource EntropySourceProvider entropyProvider = createCoreEntropySourceProvider(); bytesRequired = (bitsRequired + 7) / 8; // remember for the seed generator we need the correct security strength for SHA-512 - entropySource = new SignallingEntropySource(seedAvailable, entropyProvider, 256); + entropySource = new OneShotSignallingEntropySource(seedAvailable, entropyProvider, 256); drbg = new SP800SecureRandomBuilder(new EntropySourceProvider() { public EntropySource get(final int bitsRequired) @@ -626,7 +638,7 @@ public int entropySize() return bytesRequired * 8; } - private class SignallingEntropySource + private static class OneShotSignallingEntropySource implements IncrementalEntropySource { private final AtomicBoolean seedAvailable; @@ -635,7 +647,7 @@ private class SignallingEntropySource private final AtomicReference entropy = new AtomicReference(); private final AtomicBoolean scheduled = new AtomicBoolean(false); - SignallingEntropySource(AtomicBoolean seedAvailable, EntropySourceProvider baseRandom, int bitsRequired) + OneShotSignallingEntropySource(AtomicBoolean seedAvailable, EntropySourceProvider baseRandom, int bitsRequired) { this.seedAvailable = seedAvailable; this.entropySource = (IncrementalEntropySource)baseRandom.get(bitsRequired); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/keystore/PKCS12.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/keystore/PKCS12.java index 73abd17468..91dea52e5e 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/keystore/PKCS12.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/keystore/PKCS12.java @@ -2,6 +2,7 @@ import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; +import org.bouncycastle.util.Properties; public class PKCS12 { @@ -16,15 +17,30 @@ public Mappings() public void configure(ConfigurableProvider provider) { - provider.addAlgorithm("KeyStore.PKCS12", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore"); - provider.addAlgorithm("KeyStore.BCPKCS12", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore"); - provider.addAlgorithm("KeyStore.PKCS12-DEF", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStore"); + String defType = Properties.getPropertyValue("org.bouncycastle.pkcs12.default"); + + if (defType != null) + { + provider.addAlgorithm("Alg.Alias.KeyStore.PKCS12", defType); + provider.addAlgorithm("Alg.Alias.KeyStore.BCPKCS12", defType); + provider.addAlgorithm("Alg.Alias.KeyStore.PKCS12-DEF", defType.substring(0, 5) + "-DEF" + defType.substring(6)); + } + else + { + provider.addAlgorithm("KeyStore.PKCS12", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore"); + provider.addAlgorithm("KeyStore.BCPKCS12", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore"); + provider.addAlgorithm("KeyStore.PKCS12-DEF", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStore"); + } provider.addAlgorithm("KeyStore.PKCS12-3DES-40RC2", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore"); provider.addAlgorithm("KeyStore.PKCS12-3DES-3DES", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore3DES"); - + provider.addAlgorithm("KeyStore.PKCS12-AES256-AES128", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStoreAES256"); + provider.addAlgorithm("KeyStore.PKCS12-AES256-AES128-GCM", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStoreAES256GCM"); + provider.addAlgorithm("KeyStore.PKCS12-DEF-3DES-40RC2", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStore"); provider.addAlgorithm("KeyStore.PKCS12-DEF-3DES-3DES", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStore3DES"); + provider.addAlgorithm("KeyStore.PKCS12-DEF-AES256-AES128", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStoreAES256"); + provider.addAlgorithm("KeyStore.PKCS12-DEF-AES256-AES128-GCM", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStoreAES256GCM"); } } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java index 2e3b01bf35..007d53ab64 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java @@ -61,14 +61,7 @@ import org.bouncycastle.asn1.bc.PbkdMacIntegrityCheck; import org.bouncycastle.asn1.bc.SecretKeyData; import org.bouncycastle.asn1.bc.SignatureCheck; -import org.bouncycastle.internal.asn1.cms.CCMParameters; -import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; -import org.bouncycastle.asn1.misc.ScryptParams; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.nsri.NSRIObjectIdentifiers; -import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.EncryptionScheme; import org.bouncycastle.asn1.pkcs.KeyDerivationFunc; @@ -89,6 +82,13 @@ import org.bouncycastle.crypto.util.PBKDF2Config; import org.bouncycastle.crypto.util.PBKDFConfig; import org.bouncycastle.crypto.util.ScryptConfig; +import org.bouncycastle.internal.asn1.cms.CCMParameters; +import org.bouncycastle.internal.asn1.kisa.KISAObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.ScryptParams; +import org.bouncycastle.internal.asn1.nsri.NSRIObjectIdentifiers; +import org.bouncycastle.internal.asn1.ntt.NTTObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.BCFKSLoadStoreParameter; import org.bouncycastle.jcajce.BCFKSStoreParameter; import org.bouncycastle.jcajce.BCLoadStoreParameter; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java index 8f610241f0..488b434e85 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java @@ -7,6 +7,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; +import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; @@ -66,14 +67,13 @@ import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.GOST28147Parameters; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.AuthenticatedSafe; import org.bouncycastle.asn1.pkcs.CertBag; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.EncryptedData; +import org.bouncycastle.asn1.pkcs.EncryptionScheme; +import org.bouncycastle.asn1.pkcs.KeyDerivationFunc; import org.bouncycastle.asn1.pkcs.MacData; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; @@ -96,6 +96,10 @@ import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.util.DigestFactory; +import org.bouncycastle.internal.asn1.cms.GCMParameters; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.ntt.NTTObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.BCLoadStoreParameter; import org.bouncycastle.jcajce.PKCS12Key; import org.bouncycastle.jcajce.PKCS12StoreParameter; @@ -111,6 +115,7 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.JDKPKCS12StoreParameter; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Integers; import org.bouncycastle.util.Properties; import org.bouncycastle.util.Strings; @@ -135,6 +140,8 @@ public class PKCS12KeyStoreSpi private Hashtable chainCerts = new Hashtable(); private Hashtable keyCerts = new Hashtable(); + + // // generic object types // @@ -202,6 +209,26 @@ public boolean equals( } } + private static boolean isPBKDF2(ASN1ObjectIdentifier oid) + { + return oid.equals(NISTObjectIdentifiers.id_aes256_CBC) + || oid.equals(NISTObjectIdentifiers.id_aes256_GCM) + || oid.equals(NISTObjectIdentifiers.id_aes128_CBC) + || oid.equals(NISTObjectIdentifiers.id_aes128_GCM); + } + + private static int getKeyLength(ASN1ObjectIdentifier oid) + { + if (oid.equals(NISTObjectIdentifiers.id_aes256_CBC) || oid.equals(NISTObjectIdentifiers.id_aes256_GCM)) + { + return 32; + } + else + { + return 16; + } + } + public PKCS12KeyStoreSpi( JcaJceHelper helper, ASN1ObjectIdentifier keyAlgorithm, @@ -660,7 +687,7 @@ protected byte[] wrapKey( SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), - pbeParams.getIterations().intValue()); + BigIntegers.intValueExact(pbeParams.getIterations())); Cipher cipher = helper.createCipher(algorithm); @@ -676,6 +703,39 @@ protected byte[] wrapKey( return out; } + protected byte[] wrapKey( + EncryptionScheme encAlgId, + Key key, + PBKDF2Params pbeParams, + char[] password) + throws IOException + { + PBEKeySpec pbeSpec = new PBEKeySpec(password, pbeParams.getSalt(), + BigIntegers.intValueExact(pbeParams.getIterationCount()), + BigIntegers.intValueExact(pbeParams.getKeyLength()) * 8); + byte[] out; + + try + { + SecretKeyFactory keyFact = helper.createSecretKeyFactory("PBKDF2withHMacSHA256"); + + Cipher cipher = helper.createCipher(encAlgId.getAlgorithm().getId()); + + AlgorithmParameters algParams = AlgorithmParameters.getInstance(encAlgId.getAlgorithm().getId()); + algParams.init(encAlgId.getParameters().toASN1Primitive().getEncoded()); + + cipher.init(Cipher.WRAP_MODE, keyFact.generateSecret(pbeSpec), algParams); + + out = cipher.wrap(key); + } + catch (Exception e) + { + throw new IOException("exception encrypting data - " + e.toString()); + } + + return out; + } + protected byte[] cryptData( boolean forEncryption, AlgorithmIdentifier algId, @@ -694,7 +754,7 @@ protected byte[] cryptData( { PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), - pbeParams.getIterations().intValue()); + BigIntegers.intValueExact(pbeParams.getIterations())); PKCS12Key key = new PKCS12Key(password, wrongPKCS12Zero); Cipher cipher = helper.createCipher(algorithm.getId()); @@ -746,7 +806,6 @@ private Cipher createCipher(int mode, char[] password, AlgorithmIdentifier algId } Cipher cipher = helper.createCipher(alg.getEncryptionScheme().getAlgorithm().getId()); - ASN1Encodable encParams = alg.getEncryptionScheme().getParameters(); if (encParams instanceof ASN1OctetString) { @@ -754,10 +813,30 @@ private Cipher createCipher(int mode, char[] password, AlgorithmIdentifier algId } else { - // TODO: at the moment it's just GOST, but... - GOST28147Parameters gParams = GOST28147Parameters.getInstance(encParams); + ASN1Sequence params = ASN1Sequence.getInstance(encParams); - cipher.init(mode, key, new GOST28147ParameterSpec(gParams.getEncryptionParamSet(), gParams.getIV())); + if (params.getObjectAt(1) instanceof ASN1ObjectIdentifier) + { + // TODO: at the moment it's just GOST, but... + GOST28147Parameters gParams = GOST28147Parameters.getInstance(encParams); + + cipher.init(mode, key, new GOST28147ParameterSpec(gParams.getEncryptionParamSet(), gParams.getIV())); + } + else + { + AlgorithmParameters algParams = AlgorithmParameters.getInstance(encScheme.getAlgorithm().getId(), "BC"); + + try + { + algParams.init(params.getEncoded()); + } + catch (IOException e) + { + throw new InvalidKeySpecException(e.getMessage()); + } + + cipher.init(mode, key, algParams); + } } return cipher; } @@ -792,6 +871,9 @@ public void engineLoad( return; } + boolean noMac = true; + boolean noEnc = true; + BufferedInputStream bufIn = new BufferedInputStream(stream); bufIn.mark(10); @@ -832,6 +914,7 @@ public void engineLoad( throw new NullPointerException("no password supplied when one expected"); } + noMac = false; MacData mData = bag.getMacData(); DigestInfo dInfo = mData.getMac(); macAlgorithm = dInfo.getAlgorithmId(); @@ -873,13 +956,6 @@ public void engineLoad( throw new IOException("error constructing MAC: " + e.toString()); } } - else if (password != null && password.length != 0) - { - if (!Properties.isOverrideSet("org.bouncycastle.pkcs12.ignore_useless_passwd")) - { - throw new IOException("password supplied for keystore that does not require one"); - } - } keys = new IgnoresCaseHashtable(); localIds = new IgnoresCaseHashtable(); @@ -902,84 +978,17 @@ else if (password != null && password.length != 0) SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); if (b.getBagId().equals(pkcs8ShroudedKeyBag)) { - org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); - PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); - - // - // set the attributes on the key - // - String alias = null; - ASN1OctetString localId = null; - - if (b.getBagAttributes() != null) - { - Enumeration e = b.getBagAttributes().getObjects(); - while (e.hasMoreElements()) - { - ASN1Sequence sq = (ASN1Sequence)e.nextElement(); - ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); - ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); - ASN1Primitive attr = null; - - if (attrSet.size() > 0) - { - attr = (ASN1Primitive)attrSet.getObjectAt(0); - - if (privKey instanceof PKCS12BagAttributeCarrier) - { - PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; - ASN1Encodable existing = bagAttr.getBagAttribute(aOid); - if (existing != null) - { - // OK, but the value has to be the same - if (!existing.toASN1Primitive().equals(attr)) - { - throw new IOException( - "attempt to add existing attribute with different value"); - } - } - else - { - bagAttr.setBagAttribute(aOid, attr); - } - } - } - - if (aOid.equals(pkcs_9_at_friendlyName)) - { - alias = ((ASN1BMPString)attr).getString(); - keys.put(alias, privKey); - } - else if (aOid.equals(pkcs_9_at_localKeyId)) - { - localId = (ASN1OctetString)attr; - } - } - } - - if (localId != null) - { - String name = new String(Hex.encode(localId.getOctets())); - - if (alias == null) - { - keys.put(name, privKey); - } - else - { - localIds.put(alias, name); - } - } - else - { - unmarkedKey = true; - keys.put("unmarked", privKey); - } + unmarkedKey = processShroudedKeyBag(b, password, wrongPKCS12Zero); + noEnc = false; } else if (b.getBagId().equals(certBag)) { chain.addElement(b); } + else if (b.getBagId().equals(keyBag)) + { + processKeyBag(b); + } else { // -DM 2 System.out.println @@ -995,6 +1004,7 @@ else if (c[i].getContentType().equals(encryptedData)) password, wrongPKCS12Zero, d.getContent().getOctets()); ASN1Sequence seq = ASN1Sequence.getInstance(octets); + noEnc = false; for (int j = 0; j != seq.size(); j++) { SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); @@ -1004,127 +1014,11 @@ else if (c[i].getContentType().equals(encryptedData)) } else if (b.getBagId().equals(pkcs8ShroudedKeyBag)) { - org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); - PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); - - // - // set the attributes on the key - // - PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; - String alias = null; - ASN1OctetString localId = null; - - Enumeration e = b.getBagAttributes().getObjects(); - while (e.hasMoreElements()) - { - ASN1Sequence sq = (ASN1Sequence)e.nextElement(); - ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); - ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); - ASN1Primitive attr = null; - - if (attrSet.size() > 0) - { - attr = (ASN1Primitive)attrSet.getObjectAt(0); - - ASN1Encodable existing = bagAttr.getBagAttribute(aOid); - if (existing != null) - { - // OK, but the value has to be the same - if (!existing.toASN1Primitive().equals(attr)) - { - throw new IOException( - "attempt to add existing attribute with different value"); - } - } - else - { - bagAttr.setBagAttribute(aOid, attr); - } - } - - if (aOid.equals(pkcs_9_at_friendlyName)) - { - alias = ((ASN1BMPString)attr).getString(); - keys.put(alias, privKey); - } - else if (aOid.equals(pkcs_9_at_localKeyId)) - { - localId = (ASN1OctetString)attr; - } - } - - String name = new String(Hex.encode(localId.getOctets())); - - if (alias == null) - { - keys.put(name, privKey); - } - else - { - localIds.put(alias, name); - } + unmarkedKey = processShroudedKeyBag(b, password, wrongPKCS12Zero); } else if (b.getBagId().equals(keyBag)) { - org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(b.getBagValue()); - PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo); - - // - // set the attributes on the key - // - PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; - String alias = null; - ASN1OctetString localId = null; - - Enumeration e = b.getBagAttributes().getObjects(); - while (e.hasMoreElements()) - { - ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement()); - ASN1ObjectIdentifier aOid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0)); - ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1)); - ASN1Primitive attr = null; - - if (attrSet.size() > 0) - { - attr = (ASN1Primitive)attrSet.getObjectAt(0); - - ASN1Encodable existing = bagAttr.getBagAttribute(aOid); - if (existing != null) - { - // OK, but the value has to be the same - if (!existing.toASN1Primitive().equals(attr)) - { - throw new IOException( - "attempt to add existing attribute with different value"); - } - } - else - { - bagAttr.setBagAttribute(aOid, attr); - } - - if (aOid.equals(pkcs_9_at_friendlyName)) - { - alias = ((ASN1BMPString)attr).getString(); - keys.put(alias, privKey); - } - else if (aOid.equals(pkcs_9_at_localKeyId)) - { - localId = (ASN1OctetString)attr; - } - } - } - - String name = new String(Hex.encode(localId.getOctets())); - - if (alias == null) - { - keys.put(name, privKey); - } - else - { - localIds.put(alias, name); - } + processKeyBag(b); } else { @@ -1269,11 +1163,165 @@ else if (oid.equals(pkcs_9_at_localKeyId)) } } } + + if (noMac && noEnc) + { + if (password != null && password.length != 0) + { + if (!Properties.isOverrideSet("org.bouncycastle.pkcs12.ignore_useless_passwd")) + { + throw new IOException("password supplied for keystore that does not require one"); + } + } + } + } + + private boolean processShroudedKeyBag(SafeBag b, char[] password, boolean wrongPKCS12Zero) + throws IOException + { + org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); + PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); + + // + // set the attributes on the key + // + String alias = null; + ASN1OctetString localId = null; + + if (b.getBagAttributes() != null) + { + Enumeration e = b.getBagAttributes().getObjects(); + while (e.hasMoreElements()) + { + ASN1Sequence sq = (ASN1Sequence)e.nextElement(); + ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); + ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); + ASN1Primitive attr = null; + + if (attrSet.size() > 0) + { + attr = (ASN1Primitive)attrSet.getObjectAt(0); + + if (privKey instanceof PKCS12BagAttributeCarrier) + { + PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; + ASN1Encodable existing = bagAttr.getBagAttribute(aOid); + if (existing != null) + { + // OK, but the value has to be the same + if (!existing.toASN1Primitive().equals(attr)) + { + throw new IOException( + "attempt to add existing attribute with different value"); + } + } + else + { + bagAttr.setBagAttribute(aOid, attr); + } + } + } + + if (aOid.equals(pkcs_9_at_friendlyName)) + { + alias = ((ASN1BMPString)attr).getString(); + keys.put(alias, privKey); + } + else if (aOid.equals(pkcs_9_at_localKeyId)) + { + localId = (ASN1OctetString)attr; + } + } + } + + if (localId != null) + { + String name = new String(Hex.encode(localId.getOctets())); + + if (alias == null) + { + keys.put(name, privKey); + } + else + { + localIds.put(alias, name); + } + return false; // key properly marked + } + else + { + keys.put("unmarked", privKey); + return true; // key properly marked + } + } + + private void processKeyBag(SafeBag b) + throws IOException + { + org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(b.getBagValue()); + PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo); + + // + // set the attributes on the key + // + PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; + String alias = null; + ASN1OctetString localId = null; + + Enumeration e = b.getBagAttributes().getObjects(); + while (e.hasMoreElements()) + { + ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement()); + ASN1ObjectIdentifier aOid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0)); + ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1)); + ASN1Primitive attr = null; + + if (attrSet.size() > 0) + { + attr = (ASN1Primitive)attrSet.getObjectAt(0); + + ASN1Encodable existing = bagAttr.getBagAttribute(aOid); + if (existing != null) + { + // OK, but the value has to be the same + if (!existing.toASN1Primitive().equals(attr)) + { + throw new IOException( + "attempt to add existing attribute with different value"); + } + } + else + { + bagAttr.setBagAttribute(aOid, attr); + } + + if (aOid.equals(pkcs_9_at_friendlyName)) + { + alias = ((ASN1BMPString)attr).getString(); + keys.put(alias, privKey); + } + else if (aOid.equals(pkcs_9_at_localKeyId)) + { + localId = (ASN1OctetString)attr; + } + } + } + + String name = new String(Hex.encode(localId.getOctets())); + + if (alias == null) + { + keys.put(name, privKey); + } + else + { + localIds.put(alias, name); + } } private int validateIterationCount(BigInteger i) { - int count = i.intValue(); + int count = BigIntegers.intValueExact(i); if (count < 0) { @@ -1283,15 +1331,40 @@ private int validateIterationCount(BigInteger i) BigInteger maxValue = Properties.asBigInteger(PKCS12_MAX_IT_COUNT_PROPERTY); if (maxValue != null) { - if (maxValue.intValue() < count) + if (BigIntegers.intValueExact(maxValue) < count) { - throw new IllegalStateException("iteration count " + count + " greater than " + maxValue.intValue()); + throw new IllegalStateException("iteration count " + count + " greater than " + + BigIntegers.intValueExact(maxValue)); } } return count; } + private ASN1Primitive getAlgParams(ASN1ObjectIdentifier algorithm) + { + if (algorithm.equals(NISTObjectIdentifiers.id_aes128_CBC) + || algorithm.equals(NISTObjectIdentifiers.id_aes256_CBC)) + { + byte[] iv = new byte[16]; + + random.nextBytes(iv); + + return new DEROctetString(iv); + } + else if (algorithm.equals(NISTObjectIdentifiers.id_aes128_GCM) + || algorithm.equals(NISTObjectIdentifiers.id_aes256_GCM)) + { + byte[] nonce = new byte[12]; + + random.nextBytes(nonce); + + return new GCMParameters(nonce, 16).toASN1Primitive(); + } + + throw new IllegalStateException("unknown encryption OID in getAlgParams()"); + } + public void engineStore(LoadStoreParameter param) throws IOException, NoSuchAlgorithmException, CertificateException @@ -1415,9 +1488,23 @@ private void doStore(OutputStream stream, char[] password, boolean useDEREncodin String name = (String)ks.nextElement(); PrivateKey privKey = (PrivateKey)keys.get(name); - PKCS12PBEParams kParams = new PKCS12PBEParams(kSalt, MIN_ITERATIONS); - byte[] kBytes = wrapKey(keyAlgorithm.getId(), privKey, kParams, password); - AlgorithmIdentifier kAlgId = new AlgorithmIdentifier(keyAlgorithm, kParams.toASN1Primitive()); + AlgorithmIdentifier kAlgId; + byte[] kBytes; + if (isPBKDF2(keyAlgorithm)) + { + // TODO: keySize hard coded to 256 bits + PBKDF2Params kParams = new PBKDF2Params(kSalt, MIN_ITERATIONS, getKeyLength(keyAlgorithm), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA256, DERNull.INSTANCE)); + EncryptionScheme encScheme = new EncryptionScheme(keyAlgorithm, getAlgParams(keyAlgorithm)); + kAlgId = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBES2, new PBES2Parameters( + new KeyDerivationFunc(PKCSObjectIdentifiers.id_PBKDF2, kParams), encScheme)); + kBytes = wrapKey(encScheme, privKey, kParams, password); + } + else + { + PKCS12PBEParams kParams = new PKCS12PBEParams(kSalt, MIN_ITERATIONS); + kBytes = wrapKey(keyAlgorithm.getId(), privKey, kParams, password); + kAlgId = new AlgorithmIdentifier(keyAlgorithm, kParams.toASN1Primitive()); + } org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo kInfo = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(kAlgId, kBytes); boolean attrSet = false; ASN1EncodableVector kName = new ASN1EncodableVector(); @@ -1496,8 +1583,18 @@ private void doStore(OutputStream stream, char[] password, boolean useDEREncodin random.nextBytes(cSalt); ASN1EncodableVector certSeq = new ASN1EncodableVector(); - PKCS12PBEParams cParams = new PKCS12PBEParams(cSalt, MIN_ITERATIONS); - AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.toASN1Primitive()); + AlgorithmIdentifier cAlgId; + if (isPBKDF2(certAlgorithm)) + { + PBKDF2Params cParams = new PBKDF2Params(cSalt, MIN_ITERATIONS, getKeyLength(certAlgorithm), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA256, DERNull.INSTANCE)); + cAlgId = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBES2, new PBES2Parameters( + new KeyDerivationFunc(PKCSObjectIdentifiers.id_PBKDF2, cParams), new EncryptionScheme(certAlgorithm, getAlgParams(certAlgorithm)))); + } + else + { + PKCS12PBEParams cParams = new PKCS12PBEParams(cSalt, MIN_ITERATIONS); + cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.toASN1Primitive()); + } Hashtable doneCerts = new Hashtable(); Enumeration cs = keys.keys(); @@ -1690,17 +1787,24 @@ private void doStore(OutputStream stream, char[] password, boolean useDEREncodin MacData mData; - try + if (keyAlgorithm.equals(NISTObjectIdentifiers.id_aes256_GCM)) { - byte[] res = calculatePbeMac(macAlgorithm.getAlgorithm(), mSalt, itCount, password, false, data); - - DigestInfo dInfo = new DigestInfo(macAlgorithm, res); - - mData = new MacData(dInfo, mSalt, itCount); + mData = null; } - catch (Exception e) + else { - throw new IOException("error constructing MAC: " + e.toString()); + try + { + byte[] res = calculatePbeMac(macAlgorithm.getAlgorithm(), mSalt, itCount, password, false, data); + + DigestInfo dInfo = new DigestInfo(macAlgorithm, res); + + mData = new MacData(dInfo, mSalt, itCount); + } + catch (Exception e) + { + throw new IOException("error constructing MAC: " + e.toString()); + } } // @@ -1873,6 +1977,24 @@ public BCPKCS12KeyStore3DES() } } + public static class BCPKCS12KeyStoreAES256 + extends AdaptingKeyStoreSpi + { + public BCPKCS12KeyStoreAES256() + { + super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), NISTObjectIdentifiers.id_aes256_CBC, NISTObjectIdentifiers.id_aes128_CBC)); + } + } + + public static class BCPKCS12KeyStoreAES256GCM + extends AdaptingKeyStoreSpi + { + public BCPKCS12KeyStoreAES256GCM() + { + super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), NISTObjectIdentifiers.id_aes256_GCM, NISTObjectIdentifiers.id_aes128_GCM)); + } + } + public static class DefPKCS12KeyStore extends AdaptingKeyStoreSpi { @@ -1891,6 +2013,24 @@ public DefPKCS12KeyStore3DES() } } + public static class DefPKCS12KeyStoreAES256 + extends AdaptingKeyStoreSpi + { + public DefPKCS12KeyStoreAES256() + { + super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), NISTObjectIdentifiers.id_aes256_CBC, NISTObjectIdentifiers.id_aes128_CBC)); + } + } + + public static class DefPKCS12KeyStoreAES256GCM + extends AdaptingKeyStoreSpi + { + public DefPKCS12KeyStoreAES256GCM() + { + super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), NISTObjectIdentifiers.id_aes256_GCM, NISTObjectIdentifiers.id_aes128_GCM)); + } + } + private static class IgnoresCaseHashtable { private Hashtable orig = new Hashtable(); @@ -1963,6 +2103,9 @@ private static class DefaultSecretKeyProvider keySizes.put(NISTObjectIdentifiers.id_aes192_CBC, Integers.valueOf(192)); keySizes.put(NISTObjectIdentifiers.id_aes256_CBC, Integers.valueOf(256)); + keySizes.put(NISTObjectIdentifiers.id_aes128_GCM, Integers.valueOf(128)); + keySizes.put(NISTObjectIdentifiers.id_aes256_GCM, Integers.valueOf(256)); + keySizes.put(NTTObjectIdentifiers.id_camellia128_cbc, Integers.valueOf(128)); keySizes.put(NTTObjectIdentifiers.id_camellia192_cbc, Integers.valueOf(192)); keySizes.put(NTTObjectIdentifiers.id_camellia256_cbc, Integers.valueOf(256)); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java index 910311e788..87facc5cdc 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java @@ -12,15 +12,13 @@ import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; -import org.bouncycastle.internal.asn1.cms.CCMParameters; -import org.bouncycastle.internal.asn1.cms.GCMParameters; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.DefaultBufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.engines.AESEngine; @@ -33,9 +31,12 @@ import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.CCMBlockCipher; +import org.bouncycastle.crypto.modes.CCMModeCipher; import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; +import org.bouncycastle.internal.asn1.cms.CCMParameters; +import org.bouncycastle.internal.asn1.cms.GCMParameters; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; @@ -63,7 +64,7 @@ public final class AES private AES() { } - + public static class ECB extends BaseBlockCipher { @@ -73,18 +74,18 @@ public ECB() { public BlockCipher get() { - return new AESEngine(); + return AESEngine.newInstance(); } }); } } public static class CBC - extends BaseBlockCipher + extends BaseBlockCipher { public CBC() { - super(new CBCBlockCipher(new AESEngine()), 128); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), 128); } } @@ -93,7 +94,7 @@ static public class CFB { public CFB() { - super(new BufferedBlockCipher(new CFBBlockCipher(new AESEngine(), 128)), 128); + super(new DefaultBufferedBlockCipher(CFBBlockCipher.newInstance(AESEngine.newInstance(), 128)), 128); } } @@ -102,7 +103,7 @@ static public class OFB { public OFB() { - super(new BufferedBlockCipher(new OFBBlockCipher(new AESEngine(), 128)), 128); + super(new DefaultBufferedBlockCipher(new OFBBlockCipher(AESEngine.newInstance(), 128)), 128); } } @@ -111,7 +112,7 @@ static public class GCM { public GCM() { - super(new GCMBlockCipher(new AESEngine())); + super(GCMBlockCipher.newInstance(AESEngine.newInstance())); } } @@ -120,7 +121,7 @@ static public class CCM { public CCM() { - super(new CCMBlockCipher(new AESEngine()), false, 12); + super(CCMBlockCipher.newInstance(AESEngine.newInstance()), false, 12); } } @@ -129,7 +130,7 @@ public static class AESCMAC { public AESCMAC() { - super(new CMac(new AESEngine())); + super(new CMac(AESEngine.newInstance())); } } @@ -138,7 +139,7 @@ public static class AESGMAC { public AESGMAC() { - super(new GMac(new GCMBlockCipher(new AESEngine()))); + super(new GMac(GCMBlockCipher.newInstance(AESEngine.newInstance()))); } } @@ -153,7 +154,7 @@ public AESCCMMAC() private static class CCMMac implements Mac { - private final CCMBlockCipher ccm = new CCMBlockCipher(new AESEngine()); + private final CCMModeCipher ccm = CCMBlockCipher.newInstance(AESEngine.newInstance()); private int macLength = 8; @@ -208,7 +209,7 @@ public void reset() } static public class KeyFactory - extends BaseSecretKeyFactory + extends BaseSecretKeyFactory { public KeyFactory() { @@ -221,7 +222,7 @@ public static class Poly1305 { public Poly1305() { - super(new org.bouncycastle.crypto.macs.Poly1305(new AESEngine())); + super(new org.bouncycastle.crypto.macs.Poly1305(AESEngine.newInstance())); } } @@ -257,7 +258,7 @@ public static class RFC3211Wrap { public RFC3211Wrap() { - super(new RFC3211WrapEngine(new AESEngine()), 16); + super(new RFC3211WrapEngine(AESEngine.newInstance()), 16); } } @@ -266,7 +267,7 @@ public static class RFC5649Wrap { public RFC5649Wrap() { - super(new RFC5649WrapEngine(new AESEngine())); + super(new RFC5649WrapEngine(AESEngine.newInstance())); } } @@ -278,7 +279,7 @@ static public class PBEWithAESCBC { public PBEWithAESCBC() { - super(new CBCBlockCipher(new AESEngine())); + super(CBCBlockCipher.newInstance(AESEngine.newInstance())); } } @@ -290,7 +291,7 @@ static public class PBEWithSHA1AESCBC128 { public PBEWithSHA1AESCBC128() { - super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 128, 16); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA1, 128, 16); } } @@ -299,7 +300,7 @@ static public class PBEWithSHA1AESCBC192 { public PBEWithSHA1AESCBC192() { - super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 192, 16); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA1, 192, 16); } } @@ -308,7 +309,7 @@ static public class PBEWithSHA1AESCBC256 { public PBEWithSHA1AESCBC256() { - super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 256, 16); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA1, 256, 16); } } @@ -320,7 +321,7 @@ static public class PBEWithSHA256AESCBC128 { public PBEWithSHA256AESCBC128() { - super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 128, 16); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA256, 128, 16); } } @@ -329,7 +330,7 @@ static public class PBEWithSHA256AESCBC192 { public PBEWithSHA256AESCBC192() { - super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 192, 16); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA256, 192, 16); } } @@ -338,7 +339,7 @@ static public class PBEWithSHA256AESCBC256 { public PBEWithSHA256AESCBC256() { - super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 256, 16); + super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA256, 256, 16); } } @@ -382,7 +383,7 @@ public KeyGen256() super(256); } } - + /** * PBEWithSHA1And128BitAES-BC */ @@ -394,7 +395,7 @@ public PBEWithSHAAnd128BitAESBC() super("PBEWithSHA1And128BitAES-CBC-BC", null, true, PKCS12, SHA1, 128, 128); } } - + /** * PBEWithSHA1And192BitAES-BC */ @@ -406,7 +407,7 @@ public PBEWithSHAAnd192BitAESBC() super("PBEWithSHA1And192BitAES-CBC-BC", null, true, PKCS12, SHA1, 192, 128); } } - + /** * PBEWithSHA1And256BitAES-BC */ @@ -418,7 +419,7 @@ public PBEWithSHAAnd256BitAESBC() super("PBEWithSHA1And256BitAES-CBC-BC", null, true, PKCS12, SHA1, 256, 128); } } - + /** * PBEWithSHA256And128BitAES-BC */ @@ -430,7 +431,7 @@ public PBEWithSHA256And128BitAESBC() super("PBEWithSHA256And128BitAES-CBC-BC", null, true, PKCS12, SHA256, 128, 128); } } - + /** * PBEWithSHA256And192BitAES-BC */ @@ -442,7 +443,7 @@ public PBEWithSHA256And192BitAESBC() super("PBEWithSHA256And192BitAES-CBC-BC", null, true, PKCS12, SHA256, 192, 128); } } - + /** * PBEWithSHA256And256BitAES-BC */ @@ -454,7 +455,7 @@ public PBEWithSHA256And256BitAESBC() super("PBEWithSHA256And256BitAES-CBC-BC", null, true, PKCS12, SHA256, 256, 128); } } - + /** * PBEWithMD5And128BitAES-OpenSSL */ @@ -466,7 +467,7 @@ public PBEWithMD5And128BitAESCBCOpenSSL() super("PBEWithMD5And128BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 128, 128); } } - + /** * PBEWithMD5And192BitAES-OpenSSL */ @@ -478,7 +479,7 @@ public PBEWithMD5And192BitAESCBCOpenSSL() super("PBEWithMD5And192BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 192, 128); } } - + /** * PBEWithMD5And256BitAES-OpenSSL */ @@ -490,7 +491,7 @@ public PBEWithMD5And256BitAESCBCOpenSSL() super("PBEWithMD5And256BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 256, 128); } } - + public static class AlgParamGen extends BaseAlgorithmParameterGenerator { @@ -504,7 +505,7 @@ protected void engineInit( protected AlgorithmParameters engineGenerateParameters() { - byte[] iv = new byte[16]; + byte[] iv = new byte[16]; if (random == null) { @@ -543,7 +544,7 @@ protected void engineInit( protected AlgorithmParameters engineGenerateParameters() { - byte[] iv = new byte[12]; + byte[] iv = new byte[12]; if (random == null) { @@ -582,7 +583,7 @@ protected void engineInit( protected AlgorithmParameters engineGenerateParameters() { - byte[] nonce = new byte[12]; + byte[] nonce = new byte[12]; if (random == null) { @@ -790,7 +791,7 @@ public static class Mappings extends SymmetricAlgorithmProvider { private static final String PREFIX = AES.class.getName(); - + /** * These three got introduced in some messages as a result of a typo in an * early document. We don't produce anything using these OID values, but we'll @@ -940,31 +941,31 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("Cipher.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC128"); provider.addAlgorithm("Cipher.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC192"); provider.addAlgorithm("Cipher.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC256"); - - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC"); + + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND128BITAES-BC", "PBEWITHSHAAND128BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-BC","PBEWITHSHAAND192BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-BC","PBEWITHSHAAND256BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-BC","PBEWITHSHAAND192BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-BC","PBEWITHSHAAND256BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-BC", "PBEWITHSHAAND128BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-BC", "PBEWITHSHAAND128BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-CBC-BC", "PBEWITHSHA256AND128BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-CBC-BC", "PBEWITHSHA256AND192BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-CBC-BC", "PBEWITHSHA256AND256BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND128BITAES-BC", "PBEWITHSHA256AND128BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND192BITAES-BC", "PBEWITHSHA256AND192BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND256BITAES-BC", "PBEWITHSHA256AND256BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-BC", "PBEWITHSHA256AND128BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-BC", "PBEWITHSHA256AND192BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-BC", "PBEWITHSHA256AND256BITAES-CBC-BC"); provider.addAlgorithm("Cipher.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC"); provider.addAlgorithm("Cipher.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC"); @@ -976,48 +977,48 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And128BitAESCBCOpenSSL"); provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And192BitAESCBCOpenSSL"); provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND256BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And256BitAESCBCOpenSSL"); - + provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND128BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd128BitAESBC"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND192BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd192BitAESBC"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND256BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd256BitAESBC"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And128BitAESBC"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And192BitAESBC"); provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And256BitAESBC"); - provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC"); - provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-CBC-BC", "PBEWITHSHA256AND128BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-CBC-BC", "PBEWITHSHA256AND192BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-CBC-BC", "PBEWITHSHA256AND256BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-BC", "PBEWITHSHA256AND128BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-BC", "PBEWITHSHA256AND192BITAES-CBC-BC"); + provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-BC", "PBEWITHSHA256AND256BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc, "PBEWITHSHAAND128BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc, "PBEWITHSHAAND192BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc, "PBEWITHSHAAND256BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc, "PBEWITHSHA256AND128BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc, "PBEWITHSHA256AND192BITAES-CBC-BC"); provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc, "PBEWITHSHA256AND256BITAES-CBC-BC"); - + provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITAES-CBC-BC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND192BITAES-CBC-BC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND256BITAES-CBC-BC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND128BITAES-CBC-BC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND192BITAES-CBC-BC", "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND256BITAES-CBC-BC", "PKCS12PBE"); - provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND128BITAES-CBC-BC","PKCS12PBE"); - provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND192BITAES-CBC-BC","PKCS12PBE"); - provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND256BITAES-CBC-BC","PKCS12PBE"); - provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND128BITAES-CBC-BC","PKCS12PBE"); - provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND192BITAES-CBC-BC","PKCS12PBE"); - provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND256BITAES-CBC-BC","PKCS12PBE"); - provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND128BITAES-CBC-BC","PKCS12PBE"); - provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND192BITAES-CBC-BC","PKCS12PBE"); - provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND256BITAES-CBC-BC","PKCS12PBE"); - + provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND128BITAES-CBC-BC", "PKCS12PBE"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND192BITAES-CBC-BC", "PKCS12PBE"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND256BITAES-CBC-BC", "PKCS12PBE"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND128BITAES-CBC-BC", "PKCS12PBE"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND192BITAES-CBC-BC", "PKCS12PBE"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND256BITAES-CBC-BC", "PKCS12PBE"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND128BITAES-CBC-BC", "PKCS12PBE"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND192BITAES-CBC-BC", "PKCS12PBE"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND256BITAES-CBC-BC", "PKCS12PBE"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), "PKCS12PBE"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), "PKCS12PBE"); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARIA.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARIA.java index 691132b355..9f851a19ef 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARIA.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARIA.java @@ -9,9 +9,6 @@ import javax.crypto.spec.IvParameterSpec; -import org.bouncycastle.internal.asn1.cms.CCMParameters; -import org.bouncycastle.internal.asn1.cms.GCMParameters; -import org.bouncycastle.asn1.nsri.NSRIObjectIdentifiers; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; @@ -27,6 +24,9 @@ import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; +import org.bouncycastle.internal.asn1.cms.CCMParameters; +import org.bouncycastle.internal.asn1.cms.GCMParameters; +import org.bouncycastle.internal.asn1.nsri.NSRIObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; @@ -45,7 +45,7 @@ public final class ARIA private ARIA() { } - + public static class ECB extends BaseBlockCipher { @@ -62,7 +62,7 @@ public BlockCipher get() } public static class CBC - extends BaseBlockCipher + extends BaseBlockCipher { public CBC() { @@ -89,7 +89,7 @@ public OFB() } static public class CCM - extends BaseBlockCipher + extends BaseBlockCipher { public CCM() { @@ -98,7 +98,7 @@ public CCM() } static public class GCM - extends BaseBlockCipher + extends BaseBlockCipher { public GCM() { @@ -123,7 +123,7 @@ public WrapPad() super(new ARIAWrapPadEngine()); } } - + public static class RFC3211Wrap extends BaseWrapCipher { @@ -143,13 +143,14 @@ public GMAC() } static public class KeyFactory - extends BaseSecretKeyFactory + extends BaseSecretKeyFactory { public KeyFactory() { super("ARIA", null); } } + public static class Poly1305 extends BaseMac { @@ -425,7 +426,7 @@ protected AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec) throw new InvalidParameterSpecException("AlgorithmParameterSpec not recognized: " + paramSpec.getName()); } } - + public static class Mappings extends SymmetricAlgorithmProvider { @@ -460,7 +461,7 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("Cipher", NSRIObjectIdentifiers.id_aria128_ecb, PREFIX + "$ECB"); provider.addAlgorithm("Cipher", NSRIObjectIdentifiers.id_aria192_ecb, PREFIX + "$ECB"); provider.addAlgorithm("Cipher", NSRIObjectIdentifiers.id_aria256_ecb, PREFIX + "$ECB"); - + provider.addAlgorithm("Cipher", NSRIObjectIdentifiers.id_aria128_cbc, PREFIX + "$CBC"); provider.addAlgorithm("Cipher", NSRIObjectIdentifiers.id_aria192_cbc, PREFIX + "$CBC"); provider.addAlgorithm("Cipher", NSRIObjectIdentifiers.id_aria256_cbc, PREFIX + "$CBC"); @@ -486,7 +487,7 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("Alg.Alias.Cipher", NSRIObjectIdentifiers.id_aria192_kwp, "ARIAWRAPPAD"); provider.addAlgorithm("Alg.Alias.Cipher", NSRIObjectIdentifiers.id_aria256_kwp, "ARIAWRAPPAD"); provider.addAlgorithm("Alg.Alias.Cipher.ARIAKWP", "ARIAWRAPPAD"); - + provider.addAlgorithm("KeyGenerator.ARIA", PREFIX + "$KeyGen"); provider.addAlgorithm("KeyGenerator", NSRIObjectIdentifiers.id_aria128_kw, PREFIX + "$KeyGen128"); provider.addAlgorithm("KeyGenerator", NSRIObjectIdentifiers.id_aria192_kw, PREFIX + "$KeyGen192"); @@ -537,7 +538,7 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("Alg.Alias.Cipher", NSRIObjectIdentifiers.id_aria128_gcm, "ARIAGCM"); provider.addAlgorithm("Alg.Alias.Cipher", NSRIObjectIdentifiers.id_aria192_gcm, "ARIAGCM"); provider.addAlgorithm("Alg.Alias.Cipher", NSRIObjectIdentifiers.id_aria256_gcm, "ARIAGCM"); - + addGMacAlgorithm(provider, "ARIA", PREFIX + "$GMAC", PREFIX + "$KeyGen"); addPoly1305Algorithm(provider, "ARIA", PREFIX + "$Poly1305", PREFIX + "$Poly1305KeyGen"); } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java index efcd0d8df9..cfa3bb1766 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java @@ -1,10 +1,10 @@ package org.bouncycastle.jcajce.provider.symmetric; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.BlowfishEngine; import org.bouncycastle.crypto.macs.CMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/CAST5.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/CAST5.java index 13ced70267..14a01438fa 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/CAST5.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/CAST5.java @@ -10,12 +10,12 @@ import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.misc.CAST5CBCParameters; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.engines.CAST5Engine; import org.bouncycastle.crypto.modes.CBCBlockCipher; +import org.bouncycastle.internal.asn1.misc.CAST5CBCParameters; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Camellia.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Camellia.java index 139810c301..6d82f21a2c 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Camellia.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Camellia.java @@ -7,7 +7,6 @@ import javax.crypto.spec.IvParameterSpec; -import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.CryptoServicesRegistrar; @@ -18,6 +17,7 @@ import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; +import org.bouncycastle.internal.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DES.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DES.java index 91a25ecf2b..311d0f1251 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DES.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DES.java @@ -14,7 +14,6 @@ import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoServicesRegistrar; @@ -32,6 +31,7 @@ import org.bouncycastle.crypto.params.DESParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.PBKDF1Key; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java index 66368a6871..91e95411ab 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java @@ -12,7 +12,6 @@ import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.KeyGenerationParameters; @@ -25,6 +24,7 @@ import org.bouncycastle.crypto.macs.CMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.ISO7816d4Padding; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GOST28147.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GOST28147.java index 86580190da..558aa9d54d 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GOST28147.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GOST28147.java @@ -17,7 +17,6 @@ import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.GOST28147Parameters; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.CryptoServicesRegistrar; @@ -27,6 +26,7 @@ import org.bouncycastle.crypto.macs.GOST28147Mac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.GCFBBlockCipher; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/IDEA.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/IDEA.java index 3b5fc913c7..189bcb723c 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/IDEA.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/IDEA.java @@ -9,14 +9,14 @@ import javax.crypto.spec.IvParameterSpec; -import org.bouncycastle.asn1.misc.IDEACBCPar; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.engines.IDEAEngine; import org.bouncycastle.crypto.macs.CBCBlockCipherMac; import org.bouncycastle.crypto.macs.CFBBlockCipherMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; +import org.bouncycastle.internal.asn1.misc.IDEACBCPar; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; @@ -46,7 +46,7 @@ public static class CBC { public CBC() { - super(new CBCBlockCipher(new IDEAEngine()), 64); + super(CBCBlockCipher.newInstance(new IDEAEngine()), 64); } } @@ -73,7 +73,7 @@ static public class PBEWithSHAAndIDEA { public PBEWithSHAAndIDEA() { - super(new CBCBlockCipher(new IDEAEngine())); + super(CBCBlockCipher.newInstance(new IDEAEngine())); } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SCRYPT.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SCRYPT.java index 6dd3d9b99d..6af45cca0b 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SCRYPT.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SCRYPT.java @@ -5,11 +5,11 @@ import javax.crypto.SecretKey; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.PasswordConverter; import org.bouncycastle.crypto.generators.SCrypt; import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SEED.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SEED.java index 62a4efaa97..d0ef6116c7 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SEED.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SEED.java @@ -7,7 +7,6 @@ import javax.crypto.spec.IvParameterSpec; -import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.CryptoServicesRegistrar; @@ -18,6 +17,7 @@ import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; +import org.bouncycastle.internal.asn1.kisa.KISAObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Serpent.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Serpent.java index 52a7e1e69e..4d1351c71b 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Serpent.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Serpent.java @@ -1,6 +1,5 @@ package org.bouncycastle.jcajce.provider.symmetric; -import org.bouncycastle.asn1.gnu.GNUObjectIdentifiers; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; @@ -12,6 +11,7 @@ import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; +import org.bouncycastle.internal.asn1.gnu.GNUObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/TLSKDF.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/TLSKDF.java index eee822af7e..384f508fdf 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/TLSKDF.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/TLSKDF.java @@ -144,7 +144,7 @@ public static final class TLS12withSHA256 { public TLS12withSHA256() { - super("TLS12withSHA256KDF", new HMac(new SHA256Digest())); + super("TLS12withSHA256KDF", new HMac(SHA256Digest.newInstance())); } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java index 240e00377d..83da6d36bc 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java @@ -255,4 +255,4 @@ static void checkDestroyed(Destroyable destroyable) throw new IllegalStateException("key has been destroyed"); } } -} +} \ No newline at end of file diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java index d59c648560..b7dbc2f203 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java @@ -30,6 +30,7 @@ import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.DefaultBufferedBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.engines.DSTU7624Engine; @@ -58,6 +59,7 @@ import org.bouncycastle.crypto.paddings.BlockCipherPadding; import org.bouncycastle.crypto.paddings.ISO10126d2Padding; import org.bouncycastle.crypto.paddings.ISO7816d4Padding; +import org.bouncycastle.crypto.paddings.PKCS7Padding; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.paddings.TBCPadding; import org.bouncycastle.crypto.paddings.X923Padding; @@ -92,14 +94,14 @@ public class BaseBlockCipher // specs we can handle. // private static final Class[] availableSpecs = - { - RC2ParameterSpec.class, - RC5ParameterSpec.class, - GcmSpecUtil.gcmSpecClass, - GOST28147ParameterSpec.class, - IvParameterSpec.class, - PBEParameterSpec.class - }; + { + RC2ParameterSpec.class, + RC5ParameterSpec.class, + GcmSpecUtil.gcmSpecClass, + GOST28147ParameterSpec.class, + IvParameterSpec.class, + PBEParameterSpec.class + }; private BlockCipher baseEngine; private BlockCipherProvider engineProvider; @@ -347,7 +349,7 @@ else if (modeName.equals("CBC")) { ivLength = baseEngine.getBlockSize(); cipher = new BufferedGenericBlockCipher( - new CBCBlockCipher(baseEngine)); + CBCBlockCipher.newInstance(baseEngine)); } else if (modeName.startsWith("OFB")) { @@ -373,12 +375,12 @@ else if (modeName.startsWith("CFB")) int wordSize = Integer.parseInt(modeName.substring(3)); cipher = new BufferedGenericBlockCipher( - new CFBBlockCipher(baseEngine, wordSize)); + CFBBlockCipher.newInstance(baseEngine, wordSize)); } else { cipher = new BufferedGenericBlockCipher( - new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize())); + CFBBlockCipher.newInstance(baseEngine, 8 * baseEngine.getBlockSize())); } } else if (modeName.startsWith("PGPCFB")) @@ -420,8 +422,8 @@ else if (modeName.equals("SIC")) throw new IllegalArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)"); } fixedIv = false; - cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher( - new SICBlockCipher(baseEngine))); + cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher( + SICBlockCipher.newInstance(baseEngine))); } else if (modeName.equals("CTR")) { @@ -429,31 +431,31 @@ else if (modeName.equals("CTR")) fixedIv = false; if (baseEngine instanceof DSTU7624Engine) { - cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher( + cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher( new KCTRBlockCipher(baseEngine))); } else { - cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher( - new SICBlockCipher(baseEngine))); + cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher( + SICBlockCipher.newInstance(baseEngine))); } } else if (modeName.equals("GOFB")) { ivLength = baseEngine.getBlockSize(); - cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher( + cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher( new GOFBBlockCipher(baseEngine))); } else if (modeName.equals("GCFB")) { ivLength = baseEngine.getBlockSize(); - cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher( + cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher( new GCFBBlockCipher(baseEngine))); } else if (modeName.equals("CTS")) { ivLength = baseEngine.getBlockSize(); - cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(new CBCBlockCipher(baseEngine))); + cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(CBCBlockCipher.newInstance(baseEngine))); } else if (modeName.equals("CCM")) { @@ -464,7 +466,7 @@ else if (modeName.equals("CCM")) } else { - cipher = new AEADGenericBlockCipher(new CCMBlockCipher(baseEngine)); + cipher = new AEADGenericBlockCipher(CCMBlockCipher.newInstance(baseEngine)); } } else if (modeName.equals("OCB")) @@ -502,7 +504,7 @@ else if (modeName.equals("GCM")) else { ivLength = 12; - cipher = new AEADGenericBlockCipher(new GCMBlockCipher(baseEngine)); + cipher = new AEADGenericBlockCipher(GCMBlockCipher.newInstance(baseEngine)); } } else @@ -526,7 +528,7 @@ protected void engineSetPadding( { if (cipher.wrapOnNoPadding()) { - cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(cipher.getUnderlyingCipher())); + cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(cipher.getUnderlyingCipher())); } } else if (paddingName.equals("WITHCTS") || paddingName.equals("CTSPADDING") || paddingName.equals("CS3PADDING")) @@ -797,7 +799,7 @@ else if (params instanceof GOST28147ParameterSpec) GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params; param = new ParametersWithSBox( - new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSbox()); + new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSBox()); if (gost28147Param.getIV() != null && ivLength != 0) { @@ -981,7 +983,7 @@ else if (params instanceof GOST28147ParameterSpec) // need to pick up IV and SBox. GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params; - param = new ParametersWithSBox(param, gost28147Param.getSbox()); + param = new ParametersWithSBox(param, gost28147Param.getSBox()); if (gost28147Param.getIV() != null && ivLength != 0) { @@ -1004,7 +1006,7 @@ else if (params instanceof GOST28147ParameterSpec) // need to pick up IV and SBox. GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params; - param = new ParametersWithSBox(param, gost28147Param.getSbox()); + param = new ParametersWithSBox(param, gost28147Param.getSBox()); if (gost28147Param.getIV() != null && ivLength != 0) { @@ -1276,7 +1278,7 @@ private static class BufferedGenericBlockCipher BufferedGenericBlockCipher(org.bouncycastle.crypto.BlockCipher cipher) { - this.cipher = new PaddedBufferedBlockCipher(cipher); + this(cipher, new PKCS7Padding()); } BufferedGenericBlockCipher(org.bouncycastle.crypto.BlockCipher cipher, BlockCipherPadding padding) diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java index 37ea08b58f..71344f8851 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java @@ -23,7 +23,9 @@ public Object run() { try { - return Class.forName(className); + ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + + return classLoader.loadClass(className); } catch (Exception e) { diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java index 6d0cc9455f..88810d9acc 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java @@ -1,11 +1,9 @@ package org.bouncycastle.jcajce.provider.util; -import java.security.KeyFactorySpi; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; -import org.bouncycastle.jcajce.provider.symmetric.AES; public abstract class AsymmetricAlgorithmProvider extends AlgorithmProvider @@ -17,8 +15,11 @@ protected void addSignatureAlgorithm( ASN1ObjectIdentifier oid) { provider.addAlgorithm("Signature." + algorithm, className); - provider.addAlgorithm("Alg.Alias.Signature." + oid, algorithm); - provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, algorithm); + if (oid != null) + { + provider.addAlgorithm("Alg.Alias.Signature." + oid, algorithm); + provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, algorithm); + } } protected void addSignatureAlias( diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java index 6f98980783..b1f8259e22 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java @@ -7,9 +7,9 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.Digest; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.util.Strings; public class DigestFactory diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/util/SecretKeyUtil.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/util/SecretKeyUtil.java index 56d6c5b326..686d6b8461 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/util/SecretKeyUtil.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/util/SecretKeyUtil.java @@ -5,8 +5,8 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.internal.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.util.Integers; public class SecretKeyUtil diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java index ee8f43c5dd..09cb32ee21 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java @@ -19,18 +19,19 @@ public Builder() public Builder add(String algorithmName) { - algorithmNames.add(algorithmName); - parameterSpecs.add(null); - - return this; + return add(algorithmName, null); } public Builder add(String algorithmName, AlgorithmParameterSpec parameterSpec) { - algorithmNames.add(algorithmName); - parameterSpecs.add(parameterSpec); + if (!algorithmNames.contains(algorithmName)) + { + algorithmNames.add(algorithmName); + parameterSpecs.add(parameterSpec); - return this; + return this; + } + throw new IllegalStateException("cannot build with the same algorithm name added"); } public CompositeAlgorithmSpec build() @@ -49,8 +50,8 @@ public CompositeAlgorithmSpec build() public CompositeAlgorithmSpec(Builder builder) { - this.algorithmNames = Collections.unmodifiableList(new ArrayList(builder.algorithmNames)); - this.parameterSpecs = Collections.unmodifiableList(new ArrayList(builder.parameterSpecs)); + this.algorithmNames = Collections.unmodifiableList(new ArrayList(builder.algorithmNames)); + this.parameterSpecs = Collections.unmodifiableList(new ArrayList(builder.parameterSpecs)); } public List getAlgorithmNames() diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/EdDSAParameterSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/EdDSAParameterSpec.java index 1f0f203f2f..08865867c2 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/spec/EdDSAParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/EdDSAParameterSpec.java @@ -2,7 +2,7 @@ import java.security.spec.AlgorithmParameterSpec; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; /** * ParameterSpec for EdDSA signature algorithms. diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/GOST28147ParameterSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/GOST28147ParameterSpec.java index d06dc5a05a..faf67b5762 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/spec/GOST28147ParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/GOST28147ParameterSpec.java @@ -6,8 +6,8 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.crypto.engines.GOST28147Engine; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.util.Arrays; /** diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/GOST28147WrapParameterSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/GOST28147WrapParameterSpec.java index 3ee336495a..7f1ee947f6 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/spec/GOST28147WrapParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/GOST28147WrapParameterSpec.java @@ -6,8 +6,8 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.crypto.engines.GOST28147Engine; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.util.Arrays; /** diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/GOST3410ParameterSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/GOST3410ParameterSpec.java index 474c1856ae..273f928c13 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/spec/GOST3410ParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/GOST3410ParameterSpec.java @@ -5,7 +5,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; /** * ParameterSpec for a GOST 3410-1994/2001/2012 algorithm parameters. diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java index 6bf38359bc..0e825f55d8 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java @@ -8,8 +8,9 @@ import org.bouncycastle.util.Arrays; /** - * SP 800-56C Hybrid Value spec, to allow the secret in a key agreement to be - * created as "Z | T" where T is some other secret value as described in Section 2. + * SP 800-56C Hybrid Value spec, by default to allow the secret in a key agreement to be + * created as "Z | T" where T is some other secret value as described in Section 2. If the + * value doPrepend is set to true the spec will be used to calculate "T | Z" instead. *

      * Get methods throw IllegalStateException if destroy() is called. *

      @@ -19,6 +20,8 @@ public class HybridValueParameterSpec { private final AtomicBoolean hasBeenDestroyed = new AtomicBoolean(false); + private final boolean doPrepend; + private volatile byte[] t; private volatile AlgorithmParameterSpec baseSpec; @@ -30,9 +33,31 @@ public class HybridValueParameterSpec * @param baseSpec the base spec for the agreements KDF. */ public HybridValueParameterSpec(byte[] t, AlgorithmParameterSpec baseSpec) + { + this(t, false, baseSpec); + } + + /** + * Create a spec with T set to t and the spec for the KDF in the agreement to baseSpec. + * Note: the t value is not copied. + * @param t a shared secret to be concatenated with the agreement's Z value. + * @param baseSpec the base spec for the agreements KDF. + */ + public HybridValueParameterSpec(byte[] t, boolean doPrepend, AlgorithmParameterSpec baseSpec) { this.t = t; this.baseSpec = baseSpec; + this.doPrepend = doPrepend; + } + + /** + * Return whether or not T should be prepended. + * + * @return true if T to be prepended, false otherwise. + */ + public boolean isPrependedT() + { + return doPrepend; } /** diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/KEMExtractSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/KEMExtractSpec.java index e952d7d4ee..6ece51ef28 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/spec/KEMExtractSpec.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/KEMExtractSpec.java @@ -11,12 +11,19 @@ public class KEMExtractSpec private final PrivateKey privateKey; private final byte[] encapsulation; private final String keyAlgorithmName; + private final int keySizeInBits; public KEMExtractSpec(PrivateKey privateKey, byte[] encapsulation, String keyAlgorithmName) + { + this(privateKey, encapsulation, keyAlgorithmName, 256); + } + + public KEMExtractSpec(PrivateKey privateKey, byte[] encapsulation, String keyAlgorithmName, int keySizeInBits) { this.privateKey = privateKey; this.encapsulation = Arrays.clone(encapsulation); this.keyAlgorithmName = keyAlgorithmName; + this.keySizeInBits = keySizeInBits; } public byte[] getEncapsulation() @@ -33,4 +40,9 @@ public String getKeyAlgorithmName() { return keyAlgorithmName; } + + public int getKeySize() + { + return keySizeInBits; + } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/KEMGenerateSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/KEMGenerateSpec.java index 7b201f2e91..a5ea3f0e54 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/spec/KEMGenerateSpec.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/KEMGenerateSpec.java @@ -8,11 +8,18 @@ public class KEMGenerateSpec { private final PublicKey publicKey; private final String keyAlgorithmName; + private final int keySizeInBits; public KEMGenerateSpec(PublicKey publicKey, String keyAlgorithmName) + { + this(publicKey, keyAlgorithmName, 256); + } + + public KEMGenerateSpec(PublicKey publicKey, String keyAlgorithmName, int keySizeInBits) { this.publicKey = publicKey; this.keyAlgorithmName = keyAlgorithmName; + this.keySizeInBits = keySizeInBits; } public PublicKey getPublicKey() @@ -24,4 +31,9 @@ public String getKeyAlgorithmName() { return keyAlgorithmName; } + + public int getKeySize() + { + return keySizeInBits; + } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/KEMParameterSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/KEMParameterSpec.java index 1dd7159d68..c86fd101f6 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/spec/KEMParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/KEMParameterSpec.java @@ -8,7 +8,7 @@ public class KEMParameterSpec { public KEMParameterSpec(String keyAlgorithmName) { - this(keyAlgorithmName, -1); + this(keyAlgorithmName, 256); } public KEMParameterSpec(String keyAlgorithmName, int keySizeInBits) diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/KTSParameterSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/KTSParameterSpec.java index 76a969fb3c..4e3fbd73fa 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/spec/KTSParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/KTSParameterSpec.java @@ -71,7 +71,20 @@ public Builder withParameterSpec(AlgorithmParameterSpec parameterSpec) } /** - * Set the KDF algorithm and digest algorithm for wrap key generation. + * Use the shared secret directly for key wrap generation. + * + * @return the current Builder instance. + */ + public Builder withNoKdf() + { + this.kdfAlgorithm = null; + + return this; + } + + /** + * Set the KDF algorithm and digest algorithm for wrap key generation. The default KDF is X9.44 KDF-3, also + * known as the NIST concatenation KDF. * * @param kdfAlgorithm the KDF algorithm to apply. * @return the current Builder instance. diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/MLDSAParameterSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/MLDSAParameterSpec.java new file mode 100644 index 0000000000..1cd5904879 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/MLDSAParameterSpec.java @@ -0,0 +1,51 @@ +package org.bouncycastle.jcajce.spec; + +import java.security.spec.AlgorithmParameterSpec; +import java.util.HashMap; +import java.util.Map; + +import org.bouncycastle.util.Strings; + +/** + * AlgorithmSpec for ML-DSA + */ +public class MLDSAParameterSpec + implements AlgorithmParameterSpec +{ + public static final MLDSAParameterSpec ml_dsa_44 = new MLDSAParameterSpec("ML-DSA-44"); + public static final MLDSAParameterSpec ml_dsa_65 = new MLDSAParameterSpec("ML-DSA-65"); + public static final MLDSAParameterSpec ml_dsa_87 = new MLDSAParameterSpec("ML-DSA-87"); + + public static final MLDSAParameterSpec ml_dsa_44_with_sha512 = new MLDSAParameterSpec("ML-DSA-44-WITH-SHA512"); + public static final MLDSAParameterSpec ml_dsa_65_with_sha512 = new MLDSAParameterSpec("ML-DSA-65-WITH-SHA512"); + public static final MLDSAParameterSpec ml_dsa_87_with_sha512 = new MLDSAParameterSpec("ML-DSA-87-WITH-SHA512"); + + private static Map parameters = new HashMap(); + + static + { + parameters.put("ml-dsa-44", MLDSAParameterSpec.ml_dsa_44); + parameters.put("ml-dsa-65", MLDSAParameterSpec.ml_dsa_65); + parameters.put("ml-dsa-87", MLDSAParameterSpec.ml_dsa_87); + parameters.put("ml-dsa-44-with-sha512", MLDSAParameterSpec.ml_dsa_44_with_sha512); + parameters.put("ml-dsa-65-with-sha512", MLDSAParameterSpec.ml_dsa_65_with_sha512); + parameters.put("ml-dsa-87-with-sha512", MLDSAParameterSpec.ml_dsa_87_with_sha512); + } + + private final String name; + + private MLDSAParameterSpec(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + + public static MLDSAParameterSpec fromName(String name) + { + return (MLDSAParameterSpec)parameters.get(Strings.toLowerCase(name)); + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/MLKEMParameterSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/MLKEMParameterSpec.java new file mode 100644 index 0000000000..a7f478c4ae --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/MLKEMParameterSpec.java @@ -0,0 +1,48 @@ +package org.bouncycastle.jcajce.spec; + +import java.security.spec.AlgorithmParameterSpec; +import java.util.HashMap; +import java.util.Map; + +import org.bouncycastle.util.Strings; + +/** + * AlgorithmSpec for ML-KEM + */ +public class MLKEMParameterSpec + implements AlgorithmParameterSpec +{ + public static final MLKEMParameterSpec ml_kem_512 = new MLKEMParameterSpec("ML-KEM-512"); + public static final MLKEMParameterSpec ml_kem_768 = new MLKEMParameterSpec("ML-KEM-768"); + public static final MLKEMParameterSpec ml_kem_1024 = new MLKEMParameterSpec("ML-KEM-1024"); + + private static Map parameters = new HashMap(); + + static + { + parameters.put("ml-kem-512", MLKEMParameterSpec.ml_kem_512); + parameters.put("ml-kem-768", MLKEMParameterSpec.ml_kem_768); + parameters.put("ml-kem-1024", MLKEMParameterSpec.ml_kem_1024); + + parameters.put("kyber512", MLKEMParameterSpec.ml_kem_512); + parameters.put("kyber768", MLKEMParameterSpec.ml_kem_768); + parameters.put("kyber1024", MLKEMParameterSpec.ml_kem_1024); + } + + private final String name; + + private MLKEMParameterSpec(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + + public static MLKEMParameterSpec fromName(String name) + { + return (MLKEMParameterSpec)parameters.get(Strings.toLowerCase(name)); + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/SLHDSAParameterSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/SLHDSAParameterSpec.java new file mode 100644 index 0000000000..9046cf5e18 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/SLHDSAParameterSpec.java @@ -0,0 +1,134 @@ +package org.bouncycastle.jcajce.spec; + +import java.security.spec.AlgorithmParameterSpec; +import java.util.HashMap; +import java.util.Map; + +import org.bouncycastle.util.Strings; + +/** + * AlgorithmSpec for SLH-DSA + */ +public class SLHDSAParameterSpec + implements AlgorithmParameterSpec +{ + public static final SLHDSAParameterSpec slh_dsa_sha2_128f = new SLHDSAParameterSpec("slh-dsa-sha2-128f"); + public static final SLHDSAParameterSpec slh_dsa_sha2_128s = new SLHDSAParameterSpec("slh-dsa-sha2-128s"); + + public static final SLHDSAParameterSpec slh_dsa_sha2_192f = new SLHDSAParameterSpec("slh-dsa-sha2-192f"); + public static final SLHDSAParameterSpec slh_dsa_sha2_192s = new SLHDSAParameterSpec("slh-dsa-sha2-192s"); + + public static final SLHDSAParameterSpec slh_dsa_sha2_256f = new SLHDSAParameterSpec("slh-dsa-sha2-256f"); + public static final SLHDSAParameterSpec slh_dsa_sha2_256s = new SLHDSAParameterSpec("slh-dsa-sha2-256s"); + + // SHAKE-256. + + public static final SLHDSAParameterSpec slh_dsa_shake_128f = new SLHDSAParameterSpec("slh-dsa-shake-128f"); + public static final SLHDSAParameterSpec slh_dsa_shake_128s = new SLHDSAParameterSpec("slh-dsa-shake-128s"); + + public static final SLHDSAParameterSpec slh_dsa_shake_192f = new SLHDSAParameterSpec("slh-dsa-shake-192f"); + public static final SLHDSAParameterSpec slh_dsa_shake_192s = new SLHDSAParameterSpec("slh-dsa-shake-192s"); + + public static final SLHDSAParameterSpec slh_dsa_shake_256f = new SLHDSAParameterSpec("slh-dsa-shake-256f"); + public static final SLHDSAParameterSpec slh_dsa_shake_256s = new SLHDSAParameterSpec("slh-dsa-shake-256s"); + + // PREHASH + public static final SLHDSAParameterSpec slh_dsa_sha2_128f_with_sha256 = new SLHDSAParameterSpec("slh-dsa-sha2-128f-with-sha256"); + public static final SLHDSAParameterSpec slh_dsa_sha2_128s_with_sha256 = new SLHDSAParameterSpec("slh-dsa-sha2-128s-with-sha256"); + + public static final SLHDSAParameterSpec slh_dsa_sha2_192f_with_sha512 = new SLHDSAParameterSpec("slh-dsa-sha2-192f-with-sha512"); + public static final SLHDSAParameterSpec slh_dsa_sha2_192s_with_sha512 = new SLHDSAParameterSpec("slh-dsa-sha2-192s-with-sha512"); + + public static final SLHDSAParameterSpec slh_dsa_sha2_256f_with_sha512 = new SLHDSAParameterSpec("slh-dsa-sha2-256f-with-sha512"); + public static final SLHDSAParameterSpec slh_dsa_sha2_256s_with_sha512 = new SLHDSAParameterSpec("slh-dsa-sha2-256s-with-sha512"); + + // SHAKE-256. + + public static final SLHDSAParameterSpec slh_dsa_shake_128f_with_shake128 = new SLHDSAParameterSpec("slh-dsa-shake-128f-with-shake128"); + public static final SLHDSAParameterSpec slh_dsa_shake_128s_with_shake128 = new SLHDSAParameterSpec("slh-dsa-shake-128s-with-shake128"); + + public static final SLHDSAParameterSpec slh_dsa_shake_192f_with_shake256 = new SLHDSAParameterSpec("slh-dsa-shake-192f-with-shake256"); + public static final SLHDSAParameterSpec slh_dsa_shake_192s_with_shake256 = new SLHDSAParameterSpec("slh-dsa-shake-192s-with-shake256"); + + public static final SLHDSAParameterSpec slh_dsa_shake_256f_with_shake256 = new SLHDSAParameterSpec("slh-dsa-shake-256f-with-shake256"); + public static final SLHDSAParameterSpec slh_dsa_shake_256s_with_shake256 = new SLHDSAParameterSpec("slh-dsa-shake-256s-with-shake256"); + + private static Map parameters = new HashMap(); + + static + { + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_128f.getName(), SLHDSAParameterSpec.slh_dsa_sha2_128f); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_128s.getName(), SLHDSAParameterSpec.slh_dsa_sha2_128s); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_192f.getName(), SLHDSAParameterSpec.slh_dsa_sha2_192f); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_192s.getName(), SLHDSAParameterSpec.slh_dsa_sha2_192s); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_256f.getName(), SLHDSAParameterSpec.slh_dsa_sha2_256f); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_256s.getName(), SLHDSAParameterSpec.slh_dsa_sha2_256s); + + parameters.put("slh-dsa-sha2-128f", SLHDSAParameterSpec.slh_dsa_sha2_128f); + parameters.put("slh-dsa-sha2-128s", SLHDSAParameterSpec.slh_dsa_sha2_128s); + parameters.put("slh-dsa-sha2-192f", SLHDSAParameterSpec.slh_dsa_sha2_192f); + parameters.put("slh-dsa-sha2-192s", SLHDSAParameterSpec.slh_dsa_sha2_192s); + parameters.put("slh-dsa-sha2-256f", SLHDSAParameterSpec.slh_dsa_sha2_256f); + parameters.put("slh-dsa-sha2-256s", SLHDSAParameterSpec.slh_dsa_sha2_256s); + + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_128f.getName(), SLHDSAParameterSpec.slh_dsa_shake_128f); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_128s.getName(), SLHDSAParameterSpec.slh_dsa_shake_128s); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_192f.getName(), SLHDSAParameterSpec.slh_dsa_shake_192f); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_192s.getName(), SLHDSAParameterSpec.slh_dsa_shake_192s); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_256f.getName(), SLHDSAParameterSpec.slh_dsa_shake_256f); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_256s.getName(), SLHDSAParameterSpec.slh_dsa_shake_256s); + + parameters.put("slh-dsa-shake-128f", SLHDSAParameterSpec.slh_dsa_shake_128f); + parameters.put("slh-dsa-shake-128s", SLHDSAParameterSpec.slh_dsa_shake_128s); + parameters.put("slh-dsa-shake-192f", SLHDSAParameterSpec.slh_dsa_shake_192f); + parameters.put("slh-dsa-shake-192s", SLHDSAParameterSpec.slh_dsa_shake_192s); + parameters.put("slh-dsa-shake-256f", SLHDSAParameterSpec.slh_dsa_shake_256f); + parameters.put("slh-dsa-shake-256s", SLHDSAParameterSpec.slh_dsa_shake_256s); + + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_128f_with_sha256.getName(), SLHDSAParameterSpec.slh_dsa_sha2_128f); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_128s_with_sha256.getName(), SLHDSAParameterSpec.slh_dsa_sha2_128s); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_192f_with_sha512.getName(), SLHDSAParameterSpec.slh_dsa_sha2_192f); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_192s_with_sha512.getName(), SLHDSAParameterSpec.slh_dsa_sha2_192s); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_256f_with_sha512.getName(), SLHDSAParameterSpec.slh_dsa_sha2_256f); + parameters.put(SLHDSAParameterSpec.slh_dsa_sha2_256s_with_sha512.getName(), SLHDSAParameterSpec.slh_dsa_sha2_256s); + + parameters.put("slh-dsa-sha2-128f-with-sha256", SLHDSAParameterSpec.slh_dsa_sha2_128f_with_sha256); + parameters.put("slh-dsa-sha2-128s-with-sha256", SLHDSAParameterSpec.slh_dsa_sha2_128s_with_sha256); + parameters.put("slh-dsa-sha2-192f-with-sha512", SLHDSAParameterSpec.slh_dsa_sha2_192f_with_sha512); + parameters.put("slh-dsa-sha2-192s-with-sha512", SLHDSAParameterSpec.slh_dsa_sha2_192s_with_sha512); + parameters.put("slh-dsa-sha2-256f-with-sha512", SLHDSAParameterSpec.slh_dsa_sha2_256f_with_sha512); + parameters.put("slh-dsa-sha2-256s-with-sha512", SLHDSAParameterSpec.slh_dsa_sha2_256s_with_sha512); + + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_128f_with_shake128.getName(), SLHDSAParameterSpec.slh_dsa_shake_128f_with_shake128); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_128s_with_shake128.getName(), SLHDSAParameterSpec.slh_dsa_shake_128s_with_shake128); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_192f_with_shake256.getName(), SLHDSAParameterSpec.slh_dsa_shake_192f_with_shake256); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_192s_with_shake256.getName(), SLHDSAParameterSpec.slh_dsa_shake_192s_with_shake256); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_256f_with_shake256.getName(), SLHDSAParameterSpec.slh_dsa_shake_256f_with_shake256); + parameters.put(SLHDSAParameterSpec.slh_dsa_shake_256s_with_shake256.getName(), SLHDSAParameterSpec.slh_dsa_shake_256s_with_shake256); + + parameters.put("slh-dsa-shake-128f-with-shake128", SLHDSAParameterSpec.slh_dsa_shake_128f_with_shake128); + parameters.put("slh-dsa-shake-128s-with-shake128", SLHDSAParameterSpec.slh_dsa_shake_128s_with_shake128); + parameters.put("slh-dsa-shake-192f-with-shake256", SLHDSAParameterSpec.slh_dsa_shake_192f_with_shake256); + parameters.put("slh-dsa-shake-192s-with-shake256", SLHDSAParameterSpec.slh_dsa_shake_192s_with_shake256); + parameters.put("slh-dsa-shake-256f-with-shake256", SLHDSAParameterSpec.slh_dsa_shake_256f_with_shake256); + parameters.put("slh-dsa-shake-256s-with-shake256", SLHDSAParameterSpec.slh_dsa_shake_256s_with_shake256); + + } + + private final String name; + + private SLHDSAParameterSpec(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + + public static SLHDSAParameterSpec fromName(String name) + { + return (SLHDSAParameterSpec)parameters.get(Strings.toLowerCase(name)); + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/TLSRSAPremasterSecretParameterSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/TLSRSAPremasterSecretParameterSpec.java new file mode 100644 index 0000000000..db23037e08 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/TLSRSAPremasterSecretParameterSpec.java @@ -0,0 +1,19 @@ +package org.bouncycastle.jcajce.spec; + +import java.security.spec.AlgorithmParameterSpec; + +public class TLSRSAPremasterSecretParameterSpec + implements AlgorithmParameterSpec +{ + private final int protocolVersion; + + public TLSRSAPremasterSecretParameterSpec(int protocolVersion) + { + this.protocolVersion = protocolVersion; + } + + public int getProtocolVersion() + { + return protocolVersion; + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/XDHParameterSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/XDHParameterSpec.java index 600e2d613c..2e11f22635 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/spec/XDHParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/XDHParameterSpec.java @@ -2,7 +2,7 @@ import java.security.spec.AlgorithmParameterSpec; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; /** * ParameterSpec for XDH key agreement algorithms. diff --git a/prov/src/main/java/org/bouncycastle/jcajce/util/JcaJceUtils.java b/prov/src/main/java/org/bouncycastle/jcajce/util/JcaJceUtils.java index b4ede4aca6..52d6da90ed 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/util/JcaJceUtils.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/util/JcaJceUtils.java @@ -8,9 +8,9 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; /** * General JCA/JCE utility methods. diff --git a/prov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java b/prov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java index 9ca15cffdc..681c6aeabf 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java @@ -7,14 +7,14 @@ import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.gm.GMObjectIdentifiers; -import org.bouncycastle.asn1.gnu.GNUObjectIdentifiers; -import org.bouncycastle.asn1.iso.ISOIECObjectIdentifiers; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.internal.asn1.gnu.GNUObjectIdentifiers; +import org.bouncycastle.internal.asn1.iso.ISOIECObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; public class MessageDigestUtils { diff --git a/prov/src/main/java/org/bouncycastle/jce/ECPointUtil.java b/prov/src/main/java/org/bouncycastle/jce/ECPointUtil.java index 40e5beb85a..2fde9c260f 100644 --- a/prov/src/main/java/org/bouncycastle/jce/ECPointUtil.java +++ b/prov/src/main/java/org/bouncycastle/jce/ECPointUtil.java @@ -32,7 +32,7 @@ public static ECPoint decodePoint( if (curve.getField() instanceof ECFieldFp) { c = new ECCurve.Fp( - ((ECFieldFp)curve.getField()).getP(), curve.getA(), curve.getB()); + ((ECFieldFp)curve.getField()).getP(), curve.getA(), curve.getB(), null, null); } else { @@ -41,12 +41,12 @@ public static ECPoint decodePoint( if (k.length == 3) { c = new ECCurve.F2m( - ((ECFieldF2m)curve.getField()).getM(), k[2], k[1], k[0], curve.getA(), curve.getB()); + ((ECFieldF2m)curve.getField()).getM(), k[2], k[1], k[0], curve.getA(), curve.getB(), null, null); } else { c = new ECCurve.F2m( - ((ECFieldF2m)curve.getField()).getM(), k[0], curve.getA(), curve.getB()); + ((ECFieldF2m)curve.getField()).getM(), k[0], curve.getA(), curve.getB(), null, null); } } diff --git a/prov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java b/prov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java index f6e2676be1..cf7933d714 100644 --- a/prov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java +++ b/prov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java @@ -32,7 +32,6 @@ import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; @@ -42,6 +41,7 @@ import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Strings; diff --git a/prov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalPublicKey.java b/prov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalPublicKey.java index 1f75987056..b0c86abe8a 100644 --- a/prov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalPublicKey.java +++ b/prov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalPublicKey.java @@ -4,6 +4,9 @@ import javax.crypto.interfaces.DHPublicKey; +/** + * @deprecated just use DHPublicKey. + */ public interface ElGamalPublicKey extends ElGamalKey, DHPublicKey { diff --git a/prov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java b/prov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java index a72e94c4cd..c05c9a3671 100644 --- a/prov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java +++ b/prov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java @@ -112,8 +112,7 @@ public NetscapeCertRequest (ASN1Sequence spkac) SubjectPublicKeyInfo pubkeyinfo = SubjectPublicKeyInfo.getInstance(pkac.getObjectAt(0)); - X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString( - pubkeyinfo).getBytes()); + X509EncodedKeySpec xspec = new X509EncodedKeySpec(pubkeyinfo.getEncoded(ASN1Encoding.DER)); keyAlg = pubkeyinfo.getAlgorithm(); pubkey = KeyFactory.getInstance(keyAlg.getAlgorithm().getId(), "BC") @@ -207,7 +206,7 @@ public boolean verify(String challenge) throws NoSuchAlgorithmException, Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId(), "BC"); sig.initVerify(pubkey); - sig.update(content.getBytes()); + sig.update(content.getOctets()); return sig.verify(sigBits); } diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/prov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java index c6080e00e8..f49e295949 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java @@ -9,12 +9,13 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; -import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; @@ -22,26 +23,29 @@ import org.bouncycastle.crypto.CryptoServiceProperties; import org.bouncycastle.crypto.CryptoServicePurpose; import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.internal.asn1.isara.IsaraObjectIdentifiers; +import org.bouncycastle.jcajce.provider.asymmetric.mlkem.MLKEMKeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; import org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; +import org.bouncycastle.pqc.jcajce.provider.bike.BIKEKeyFactorySpi; +import org.bouncycastle.pqc.jcajce.provider.cmce.CMCEKeyFactorySpi; import org.bouncycastle.pqc.jcajce.provider.dilithium.DilithiumKeyFactorySpi; import org.bouncycastle.pqc.jcajce.provider.falcon.FalconKeyFactorySpi; +import org.bouncycastle.pqc.jcajce.provider.hqc.HQCKeyFactorySpi; import org.bouncycastle.pqc.jcajce.provider.kyber.KyberKeyFactorySpi; import org.bouncycastle.pqc.jcajce.provider.lms.LMSKeyFactorySpi; -import org.bouncycastle.pqc.jcajce.provider.mceliece.McElieceCCA2KeyFactorySpi; -import org.bouncycastle.pqc.jcajce.provider.mceliece.McElieceKeyFactorySpi; import org.bouncycastle.pqc.jcajce.provider.newhope.NHKeyFactorySpi; import org.bouncycastle.pqc.jcajce.provider.ntru.NTRUKeyFactorySpi; import org.bouncycastle.pqc.jcajce.provider.picnic.PicnicKeyFactorySpi; -import org.bouncycastle.pqc.jcajce.provider.rainbow.RainbowKeyFactorySpi; import org.bouncycastle.pqc.jcajce.provider.sphincs.Sphincs256KeyFactorySpi; import org.bouncycastle.pqc.jcajce.provider.sphincsplus.SPHINCSPlusKeyFactorySpi; import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSKeyFactorySpi; import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSMTKeyFactorySpi; +import org.bouncycastle.util.Strings; /** * To add the provider at runtime use: @@ -72,7 +76,7 @@ public final class BouncyCastleProvider extends Provider { private static final Logger LOG = Logger.getLogger(BouncyCastleProvider.class.getName()); - private static String info = "BouncyCastle Security Provider v1.73"; + private static String info = "BouncyCastle Security Provider v1.79b"; public static final String PROVIDER_NAME = "BC"; @@ -119,12 +123,12 @@ public final class BouncyCastleProvider extends Provider // later ones configure it. private static final String[] ASYMMETRIC_GENERIC = { - "X509", "IES", "COMPOSITE", "EXTERNAL" + "X509", "IES", "COMPOSITE", "EXTERNAL", "CompositeSignatures" }; private static final String[] ASYMMETRIC_CIPHERS = { - "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145", "GM", "EdEC", "LMS", "SPHINCSPlus" + "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145", "GM", "EdEC", "LMS", "SPHINCSPlus", "Dilithium", "Falcon", "NTRU", "SLHDSA", "MLDSA", "MLKEM" }; /* @@ -156,6 +160,8 @@ public final class BouncyCastleProvider extends Provider "DRBG" }; + private Map serviceMap = new ConcurrentHashMap(); + /** * Construct a new provider. This should only be required when * using runtime registration of the provider using the @@ -163,7 +169,7 @@ public final class BouncyCastleProvider extends Provider */ public BouncyCastleProvider() { - super(PROVIDER_NAME, 1.73, info); + super(PROVIDER_NAME, 1.7899, info); AccessController.doPrivileged(new PrivilegedAction() { @@ -251,6 +257,48 @@ private void setup() put("Alg.Alias.CertStore.X509LDAP", "LDAP"); } + public final Service getService(final String type, final String algorithm) + { + String upperCaseAlgName = Strings.toUpperCase(algorithm); + final String key = type + "." + upperCaseAlgName; + + Service service = serviceMap.get(key); + + if (service == null) + { + synchronized (this) + { + if (!serviceMap.containsKey(key)) + { + service = AccessController.doPrivileged(new PrivilegedAction() + { + @Override + public Service run() + { + Service service = BouncyCastleProvider.super.getService(type, algorithm); + if (service == null) + { + return null; + } + serviceMap.put(key, service); + // remove legacy entry and swap to service entry + BouncyCastleProvider.super.remove(service.getType() + "." + service.getAlgorithm()); + BouncyCastleProvider.super.putService(service); + + return service; + } + }); + } + else + { + service = serviceMap.get(key); + } + } + } + + return service; + } + private void loadAlgorithms(String packageName, String[] names) { for (int i = 0; i != names.length; i++) @@ -301,6 +349,7 @@ private void loadServiceClass(String packageName, String serviceName) private void loadPQCKeys() { addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, new SPHINCSPlusKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, new SPHINCSPlusKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, new SPHINCSPlusKeyFactorySpi()); @@ -319,28 +368,67 @@ private void loadPQCKeys() addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, new SPHINCSPlusKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, new SPHINCSPlusKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple, new SPHINCSPlusKeyFactorySpi()); + + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128s, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192s, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256s, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(new ASN1ObjectIdentifier("1.3.9999.6.4.10"), new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128f, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192f, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256f, new SPHINCSPlusKeyFactorySpi()); + addKeyInfoConverter(PQCObjectIdentifiers.sphincs256, new Sphincs256KeyFactorySpi()); addKeyInfoConverter(PQCObjectIdentifiers.newHope, new NHKeyFactorySpi()); addKeyInfoConverter(PQCObjectIdentifiers.xmss, new XMSSKeyFactorySpi()); addKeyInfoConverter(IsaraObjectIdentifiers.id_alg_xmss, new XMSSKeyFactorySpi()); addKeyInfoConverter(PQCObjectIdentifiers.xmss_mt, new XMSSMTKeyFactorySpi()); addKeyInfoConverter(IsaraObjectIdentifiers.id_alg_xmssmt, new XMSSMTKeyFactorySpi()); - addKeyInfoConverter(PQCObjectIdentifiers.mcEliece, new McElieceKeyFactorySpi()); - addKeyInfoConverter(PQCObjectIdentifiers.mcElieceCca2, new McElieceCCA2KeyFactorySpi()); - addKeyInfoConverter(PQCObjectIdentifiers.rainbow, new RainbowKeyFactorySpi()); addKeyInfoConverter(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, new LMSKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.picnic_key, new PicnicKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.falcon_512, new FalconKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.falcon_1024, new FalconKeyFactorySpi()); + + addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_512, new MLKEMKeyFactorySpi()); + addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_768, new MLKEMKeyFactorySpi()); + addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_1024, new MLKEMKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.dilithium2, new DilithiumKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.dilithium3, new DilithiumKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.dilithium5, new DilithiumKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.dilithium2_aes, new DilithiumKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.dilithium3_aes, new DilithiumKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.dilithium5_aes, new DilithiumKeyFactorySpi()); - addKeyInfoConverter(BCObjectIdentifiers.kyber512, new KyberKeyFactorySpi()); - addKeyInfoConverter(BCObjectIdentifiers.kyber768, new KyberKeyFactorySpi()); - addKeyInfoConverter(BCObjectIdentifiers.kyber1024, new KyberKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.mceliece348864_r3, new CMCEKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.mceliece460896_r3, new CMCEKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.mceliece6688128_r3, new CMCEKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.mceliece6960119_r3, new CMCEKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.mceliece8192128_r3, new CMCEKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.bike128, new BIKEKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.bike192, new BIKEKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.bike256, new BIKEKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.hqc128, new HQCKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.hqc192, new HQCKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.hqc256, new HQCKeyFactorySpi()); + + addKeyInfoConverter(BCObjectIdentifiers.kyber512_aes, new KyberKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.kyber768_aes, new KyberKeyFactorySpi()); addKeyInfoConverter(BCObjectIdentifiers.kyber1024_aes, new KyberKeyFactorySpi()); @@ -437,7 +525,6 @@ public static PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo) { return new PicnicKeyFactorySpi().generatePublic(publicKeyInfo); } - AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(publicKeyInfo.getAlgorithm().getAlgorithm()); if (converter == null) diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java b/prov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java index f3118fcc8c..efb6ff6053 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java @@ -126,7 +126,7 @@ static Collection findTargets(PKIXExtendedBuilderParameters paramsPKIX) throws C { PKIXExtendedParameters baseParams = paramsPKIX.getBaseParameters(); PKIXCertStoreSelector certSelect = baseParams.getTargetConstraints(); - LinkedHashSet targets = new LinkedHashSet(); + Set targets = new LinkedHashSet(); try { @@ -663,7 +663,7 @@ protected static boolean isAnyPolicy( * that are matching the certSelect criteriums. * * @param certs - * a {@link LinkedHashSet} to which the certificates will be added. + * a {@link Set} to which the certificates will be added. * @param certSelect * a {@link Selector} object that will be used to select the certificates * @param certStores @@ -672,7 +672,7 @@ protected static boolean isAnyPolicy( * @return a Collection of all found {@link X509Certificate} May be empty but never * null. */ - protected static void findCertificates(LinkedHashSet certs, PKIXCertStoreSelector certSelect, List certStores) + protected static void findCertificates(Set certs, PKIXCertStoreSelector certSelect, List certStores) throws AnnotatedException { Iterator iter = certStores.iterator(); @@ -1364,7 +1364,7 @@ static Collection findIssuerCerts( } PKIXCertStoreSelector certSelect = new PKIXCertStoreSelector.Builder(selector).build(); - LinkedHashSet certs = new LinkedHashSet(); + Set certs = new LinkedHashSet(); try { diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/JCEDHPrivateKey.java b/prov/src/main/java/org/bouncycastle/jce/provider/JCEDHPrivateKey.java index d4fa2852fe..32e3043f41 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/JCEDHPrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/JCEDHPrivateKey.java @@ -19,7 +19,7 @@ import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.asn1.x9.DHDomainParameters; +import org.bouncycastle.asn1.x9.DomainParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; @@ -81,9 +81,9 @@ protected JCEDHPrivateKey() } else if (id.equals(X9ObjectIdentifiers.dhpublicnumber)) { - DHDomainParameters params = DHDomainParameters.getInstance(seq); + DomainParameters params = DomainParameters.getInstance(seq); - this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue()); + this.dhSpec = new DHParameterSpec(params.getP(), params.getG()); } else { diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/JCEDHPublicKey.java b/prov/src/main/java/org/bouncycastle/jce/provider/JCEDHPublicKey.java index 3e6a09a66f..2fdc5fbb26 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/JCEDHPublicKey.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/JCEDHPublicKey.java @@ -16,7 +16,7 @@ import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x9.DHDomainParameters; +import org.bouncycastle.asn1.x9.DomainParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; @@ -76,8 +76,8 @@ public class JCEDHPublicKey this.y = derY.getValue(); - ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithmId().getParameters()); - ASN1ObjectIdentifier id = info.getAlgorithmId().getAlgorithm(); + ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithm().getParameters()); + ASN1ObjectIdentifier id = info.getAlgorithm().getAlgorithm(); // we need the PKCS check to handle older keys marked with the X9 oid. if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement) || isPKCSParam(seq)) @@ -95,9 +95,9 @@ public class JCEDHPublicKey } else if (id.equals(X9ObjectIdentifiers.dhpublicnumber)) { - DHDomainParameters params = DHDomainParameters.getInstance(seq); + DomainParameters params = DomainParameters.getInstance(seq); - this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue()); + this.dhSpec = new DHParameterSpec(params.getP(), params.getG()); } else { diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java b/prov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java index 43e10d73d6..3f33cdb116 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java @@ -16,11 +16,9 @@ import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.asn1.sec.ECPrivateKeyStructure; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; @@ -230,7 +228,7 @@ else if (params.isImplicitlyCA()) } else { - ECPrivateKeyStructure ec = new ECPrivateKeyStructure((ASN1Sequence)privKey); + org.bouncycastle.asn1.sec.ECPrivateKey ec = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(privKey); this.d = ec.getKey(); this.publicKey = ec.getPublicKey(); @@ -290,15 +288,25 @@ else if (ecSpec == null) } PrivateKeyInfo info; - ECPrivateKeyStructure keyStructure; + org.bouncycastle.asn1.sec.ECPrivateKey keyStructure; + + int orderBitLength; + if (ecSpec == null) + { + orderBitLength = ECUtil.getOrderBitLength(null, null, this.getS()); + } + else + { + orderBitLength = ECUtil.getOrderBitLength(null, ecSpec.getOrder(), this.getS()); + } if (publicKey != null) { - keyStructure = new ECPrivateKeyStructure(this.getS(), publicKey, params); + keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params); } else { - keyStructure = new ECPrivateKeyStructure(this.getS(), params); + keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params); } try diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/JCEElGamalPrivateKey.java b/prov/src/main/java/org/bouncycastle/jce/provider/JCEElGamalPrivateKey.java index 6c21f876ab..64a1228d0f 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/JCEElGamalPrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/JCEElGamalPrivateKey.java @@ -13,11 +13,11 @@ import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.oiw.ElGamalParameter; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; +import org.bouncycastle.internal.asn1.oiw.ElGamalParameter; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/JCEElGamalPublicKey.java b/prov/src/main/java/org/bouncycastle/jce/provider/JCEElGamalPublicKey.java index 30780c85aa..ebfa328fb5 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/JCEElGamalPublicKey.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/JCEElGamalPublicKey.java @@ -10,11 +10,11 @@ import javax.crypto.spec.DHPublicKeySpec; import org.bouncycastle.asn1.ASN1Integer; -import org.bouncycastle.asn1.oiw.ElGamalParameter; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; +import org.bouncycastle.internal.asn1.oiw.ElGamalParameter; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; import org.bouncycastle.jce.interfaces.ElGamalPublicKey; import org.bouncycastle.jce.spec.ElGamalParameterSpec; diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/OcspCache.java b/prov/src/main/java/org/bouncycastle/jce/provider/OcspCache.java index 047c3f98cd..06817817d9 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/OcspCache.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/OcspCache.java @@ -38,7 +38,6 @@ import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters; import org.bouncycastle.jcajce.util.JcaJceHelper; -import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.io.Streams; class OcspCache @@ -142,8 +141,16 @@ static OCSPResponse getOcspResponse( } // TODO: configure originator - TBSRequest tbsReq = new TBSRequest(null, new DERSequence(requests), - Extensions.getInstance(new DERSequence(requestExtensions))); + TBSRequest tbsReq; + if (requestExtensions.size() != 0) + { + tbsReq = new TBSRequest(null, new DERSequence(requests), + Extensions.getInstance(new DERSequence(requestExtensions))); + } + else + { + tbsReq = new TBSRequest(null, new DERSequence(requests), (Extensions)null); + } org.bouncycastle.asn1.ocsp.Signature signature = null; @@ -196,6 +203,10 @@ static OCSPResponse getOcspResponse( if (markerRef != null) { responseMap = markerRef.get(); + } + + if (responseMap != null) + { responseMap.put(certID, response); } else diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java b/prov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java index c678344b3e..0c0e47c212 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java @@ -4,14 +4,12 @@ import java.security.cert.CertStoreException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; -import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; -import org.bouncycastle.jcajce.PKIXCRLStore; import org.bouncycastle.jcajce.PKIXCRLStoreSelector; import org.bouncycastle.util.Store; import org.bouncycastle.util.StoreException; @@ -21,7 +19,7 @@ abstract class PKIXCRLUtil static Set findCRLs(PKIXCRLStoreSelector crlselect, Date validityDate, List certStores, List pkixCrlStores) throws AnnotatedException { - HashSet initialSet = new HashSet(); + Set initialSet = new HashSet(); // get complete CRL(s) try @@ -57,18 +55,18 @@ static Set findCRLs(PKIXCRLStoreSelector crlselect, Date validityDate, List cert } /** - * Add to a HashSet any and all CRLs found in the X509Store's that are matching the crlSelect + * Add to a Set any and all CRLs found in the X509Store's that are matching the crlSelect * critera. * * @param crls - * the {@link HashSet} to add the CRLs to. + * the {@link Set} to add the CRLs to. * @param crlSelect * a {@link org.bouncycastle.jcajce.PKIXCRLStoreSelector} object that will be used to * select the CRLs * @param crlStores * a List containing only {@link Store} objects. These are used to search for CRLs */ - private static void findCRLs(HashSet crls, PKIXCRLStoreSelector crlSelect, List crlStores) throws AnnotatedException + private static void findCRLs(Set crls, PKIXCRLStoreSelector crlSelect, List crlStores) throws AnnotatedException { AnnotatedException lastException = null; boolean foundValidStore = false; diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/ProvOcspRevocationChecker.java b/prov/src/main/java/org/bouncycastle/jce/provider/ProvOcspRevocationChecker.java index 1713f8ed30..234e967276 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/ProvOcspRevocationChecker.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/ProvOcspRevocationChecker.java @@ -30,9 +30,7 @@ import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.internal.asn1.bsi.BSIObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; -import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.CertID; @@ -44,10 +42,8 @@ import org.bouncycastle.asn1.ocsp.ResponseData; import org.bouncycastle.asn1.ocsp.RevokedInfo; import org.bouncycastle.asn1.ocsp.SingleResponse; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.BCStrictStyle; import org.bouncycastle.asn1.x509.AccessDescription; @@ -59,7 +55,11 @@ import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.internal.asn1.bsi.BSIObjectIdentifiers; import org.bouncycastle.internal.asn1.eac.EACObjectIdentifiers; +import org.bouncycastle.internal.asn1.isara.IsaraObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.jcajce.PKIXCertRevocationChecker; import org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters; import org.bouncycastle.jcajce.util.JcaJceHelper; @@ -279,7 +279,7 @@ public void check(Certificate certificate) { throw new ExtCertPathValidatorException("OCSP response expired"); } - if (certID == null || !certID.getHashAlgorithm().equals(resp.getCertID().getHashAlgorithm())) + if (certID == null || !isEqualAlgId(certID.getHashAlgorithm(), resp.getCertID().getHashAlgorithm())) { org.bouncycastle.asn1.x509.Certificate issuer = extractCert(); @@ -340,6 +340,41 @@ public void check(Certificate certificate) } } + private static boolean isEqualAlgId(AlgorithmIdentifier a, AlgorithmIdentifier b) + { + if (a == b || a.equals(b)) + { + return true; + } + + if (a.getAlgorithm().equals(b.getAlgorithm())) + { + ASN1Encodable aParam = a.getParameters(); + ASN1Encodable bParam = b.getParameters(); + + if (aParam == bParam) + { + return true; + } + + if (aParam == null) + { + return DERNull.INSTANCE.equals(bParam); + } + else + { + if (DERNull.INSTANCE.equals(aParam) && bParam == null) + { + return true; + } + + return aParam.equals(bParam); + } + } + + return false; + } + static URI getOcspResponderURI(X509Certificate cert) { byte[] extValue = cert.getExtensionValue(org.bouncycastle.asn1.x509.Extension.authorityInfoAccess.getId()); @@ -431,7 +466,7 @@ static boolean validatedOcspResponse(BasicOCSPResponse basicResp, PKIXCertRevoca sig.update(basicResp.getTbsResponseData().getEncoded(ASN1Encoding.DER)); - if (sig.verify(basicResp.getSignature().getBytes())) + if (sig.verify(basicResp.getSignature().getOctets())) { if (nonce != null) { diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/ProvRevocationChecker.java b/prov/src/main/java/org/bouncycastle/jce/provider/ProvRevocationChecker.java index bfdf940255..86f03e8ae5 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/ProvRevocationChecker.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/ProvRevocationChecker.java @@ -11,15 +11,15 @@ import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.internal.asn1.bsi.BSIObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; -import org.bouncycastle.internal.asn1.eac.EACObjectIdentifiers; -import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.internal.asn1.bsi.BSIObjectIdentifiers; +import org.bouncycastle.internal.asn1.eac.EACObjectIdentifiers; +import org.bouncycastle.internal.asn1.isara.IsaraObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.jcajce.PKIXCertRevocationChecker; import org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters; import org.bouncycastle.jcajce.util.JcaJceHelper; diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java b/prov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java index fb2d4c02b3..befb795385 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java @@ -1,7 +1,6 @@ package org.bouncycastle.jce.provider; import java.io.IOException; -import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.PublicKey; import java.security.cert.CertPath; @@ -62,6 +61,7 @@ import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Properties; class RFC3280CertPathUtilities { @@ -557,15 +557,30 @@ protected static Set processCRLF( { X509Certificate signCert = (X509Certificate)validCerts.get(i); boolean[] keyUsage = signCert.getKeyUsage(); - - if (keyUsage != null && (keyUsage.length <= CRL_SIGN || !keyUsage[CRL_SIGN])) + + if (keyUsage == null) { - lastException = new AnnotatedException( - "Issuer certificate key usage extension does not permit CRL signing."); + if (Properties.isOverrideSet("org.bouncycastle.x509.allow_ca_without_crl_sign", true)) + { + checkKeys.add(validKeys.get(i)); + } + else + { + lastException = new AnnotatedException( + "No key usage extension on CRL issuer certificate."); + } } else { - checkKeys.add(validKeys.get(i)); + if (keyUsage.length <= CRL_SIGN || !keyUsage[CRL_SIGN]) + { + lastException = new AnnotatedException( + "Issuer certificate key usage extension does not permit CRL signing."); + } + else + { + checkKeys.add(validKeys.get(i)); + } } } @@ -1145,6 +1160,11 @@ protected static void processCertBC( } if (altName != null) { + /* + * NOTE: PKIXCertPathReviewer limits the number of alternative names, to avoid a denial-of-service + * attack. That does not appear to be an issue for validation, so no limit is applied. + */ + GeneralName[] genNames = null; try { @@ -2095,18 +2115,12 @@ protected static int prepareNextCertM( throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath, index); } - if (bc != null) + if (bc != null && bc.isCA()) // if there is a path len constraint and we're not a CA, ignore it! (yes, it happens). { - BigInteger _pathLengthConstraint = bc.getPathLenConstraint(); - - if (_pathLengthConstraint != null) + ASN1Integer pathLenConstraint = bc.getPathLenConstraintInteger(); + if (pathLenConstraint != null) { - int _plc = _pathLengthConstraint.intValue(); - - if (_plc < maxPathLength) - { - return _plc; - } + maxPathLength = Math.min(maxPathLength, pathLenConstraint.intPositiveValueExact()); } } return maxPathLength; diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java b/prov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java index d5e2338293..bbfacab4cb 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java @@ -23,7 +23,6 @@ import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.TBSCertList; -import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.util.Strings; /** @@ -286,11 +285,11 @@ public String toString() buf.append(" critical(").append(ext.isCritical()).append(") "); try { - if (oid.equals(X509Extension.reasonCode)) + if (oid.equals(Extension.reasonCode)) { buf.append(CRLReason.getInstance(ASN1Enumerated.getInstance(dIn.readObject()))).append(nl); } - else if (oid.equals(X509Extension.certificateIssuer)) + else if (oid.equals(Extension.certificateIssuer)) { buf.append("Certificate issuer: ").append(GeneralNames.getInstance(dIn.readObject())).append(nl); } diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java b/prov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java index ccf301bd86..6d6994abea 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java @@ -36,17 +36,13 @@ import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1IA5String; import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; -import org.bouncycastle.asn1.misc.NetscapeCertType; -import org.bouncycastle.asn1.misc.NetscapeRevocationURL; -import org.bouncycastle.asn1.misc.VerisignCzagExtension; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.RFC4519Style; @@ -56,6 +52,10 @@ import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.KeyUsage; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.NetscapeCertType; +import org.bouncycastle.internal.asn1.misc.NetscapeRevocationURL; +import org.bouncycastle.internal.asn1.misc.VerisignCzagExtension; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; @@ -104,7 +104,7 @@ public X509CertificateObject( byte[] bytes = this.getExtensionBytes("2.5.29.15"); if (bytes != null) { - ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes)); + ASN1BitString bits = ASN1BitString.getInstance(ASN1Primitive.fromByteArray(bytes)); bytes = bits.getBytes(); int length = (bytes.length * 8) - bits.getPadBits(); @@ -361,26 +361,18 @@ public List getExtendedKeyUsage() public int getBasicConstraints() { - if (basicConstraints != null) + if (basicConstraints == null || !basicConstraints.isCA()) { - if (basicConstraints.isCA()) - { - if (basicConstraints.getPathLenConstraint() == null) - { - return Integer.MAX_VALUE; - } - else - { - return basicConstraints.getPathLenConstraint().intValue(); - } - } - else - { - return -1; - } + return -1; + } + + ASN1Integer pathLenConstraint = basicConstraints.getPathLenConstraintInteger(); + if (pathLenConstraint == null) + { + return Integer.MAX_VALUE; } - return -1; + return pathLenConstraint.intPositiveValueExact(); } public Collection getSubjectAlternativeNames() @@ -698,7 +690,7 @@ else if (oid.equals(Extension.keyUsage)) } else if (oid.equals(MiscObjectIdentifiers.netscapeCertType)) { - buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl); + buf.append(new NetscapeCertType((ASN1BitString)dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL)) { diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/X509LDAPCertStoreSpi.java b/prov/src/main/java/org/bouncycastle/jce/provider/X509LDAPCertStoreSpi.java index f5269947c3..5789fd1714 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/X509LDAPCertStoreSpi.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/X509LDAPCertStoreSpi.java @@ -34,9 +34,9 @@ import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.x509.CertificatePair; import org.bouncycastle.jce.X509LDAPCertStoreParameters; +import org.bouncycastle.util.Strings; /** - * * This is a general purpose implementation to get X.509 certificates and CRLs * from a LDAP location. *

      @@ -50,21 +50,24 @@ public class X509LDAPCertStoreSpi extends CertStoreSpi { - private X509LDAPCertStoreParameters params; + private static String[] FILTER_ESCAPE_TABLE = new String['\\' + 1]; - public X509LDAPCertStoreSpi(CertStoreParameters params) - throws InvalidAlgorithmParameterException + static { - super(params); + // Filter encoding table ------------------------------------- - if (!(params instanceof X509LDAPCertStoreParameters)) + // fill with char itself + for (char c = 0; c < FILTER_ESCAPE_TABLE.length; c++) { - throw new InvalidAlgorithmParameterException( - X509LDAPCertStoreSpi.class.getName() + ": parameter must be a " + X509LDAPCertStoreParameters.class.getName() + " object\n" - + params.toString()); + FILTER_ESCAPE_TABLE[c] = String.valueOf(c); } - this.params = (X509LDAPCertStoreParameters)params; + // escapes (RFC2254) + FILTER_ESCAPE_TABLE['*'] = "\\2a"; + FILTER_ESCAPE_TABLE['('] = "\\28"; + FILTER_ESCAPE_TABLE[')'] = "\\29"; + FILTER_ESCAPE_TABLE['\\'] = "\\5c"; + FILTER_ESCAPE_TABLE[0] = "\\00"; } /** @@ -87,7 +90,25 @@ public X509LDAPCertStoreSpi(CertStoreParameters params) */ private static final String URL_CONTEXT_PREFIX = "com.sun.jndi.url"; - private DirContext connectLDAP() throws NamingException + private X509LDAPCertStoreParameters params; + + public X509LDAPCertStoreSpi(CertStoreParameters params) + throws InvalidAlgorithmParameterException + { + super(params); + + if (!(params instanceof X509LDAPCertStoreParameters)) + { + throw new InvalidAlgorithmParameterException( + X509LDAPCertStoreSpi.class.getName() + ": parameter must be a " + X509LDAPCertStoreParameters.class.getName() + " object\n" + + params.toString()); + } + + this.params = (X509LDAPCertStoreParameters)params; + } + + private DirContext connectLDAP() + throws NamingException { Properties props = new Properties(); props.setProperty(Context.INITIAL_CONTEXT_FACTORY, LDAP_PROVIDER); @@ -106,8 +127,7 @@ private DirContext connectLDAP() throws NamingException private String parseDN(String subject, String subjectAttributeName) { String temp = subject; - int begin = temp.toLowerCase().indexOf( - subjectAttributeName.toLowerCase()); + int begin = Strings.toLowerCase(temp).indexOf(Strings.toLowerCase(subjectAttributeName)); temp = temp.substring(begin + subjectAttributeName.length()); int end = temp.indexOf(','); if (end == -1) @@ -137,7 +157,7 @@ private String parseDN(String subject, String subjectAttributeName) { temp = temp.substring(0, temp.length() - 1); } - return temp; + return filterEncode(temp); } public Collection engineGetCertificates(CertSelector selector) @@ -195,7 +215,7 @@ public Collection engineGetCertificates(CertSelector selector) { } - for (Iterator it2 = bytesList.iterator(); it2.hasNext();) + for (Iterator it2 = bytesList.iterator(); it2.hasNext(); ) { ByteArrayInputStream bIn = new ByteArrayInputStream( (byte[])it2.next()); @@ -346,7 +366,7 @@ public Collection engineGetCRLs(CRLSelector selector) if (xselector.getIssuerNames() != null) { for (Iterator it = xselector.getIssuerNames().iterator(); it - .hasNext();) + .hasNext(); ) { Object o = it.next(); String attrValue = null; @@ -396,6 +416,42 @@ public Collection engineGetCRLs(CRLSelector selector) return crlSet; } + /** + * Escape a value for use in a filter. + * + * @param value the value to escape. + * @return a properly escaped representation of the supplied value. + */ + private String filterEncode(String value) + { + if (value == null) + { + return null; + } + + // make buffer roomy + StringBuilder encodedValue = new StringBuilder(value.length() * 2); + + int length = value.length(); + + for (int i = 0; i < length; i++) + { + char c = value.charAt(i); + + if (c < FILTER_ESCAPE_TABLE.length) + { + encodedValue.append(FILTER_ESCAPE_TABLE[c]); + } + else + { + // default: add the char + encodedValue.append(c); + } + } + + return encodedValue.toString(); + } + /** * Returns a Set of byte arrays with the certificate or CRL encodings. * @@ -406,9 +462,11 @@ public Collection engineGetCRLs(CRLSelector selector) * @return Set of byte arrays with the certificate encodings. */ private Set search(String attributeName, String attributeValue, - String[] attrs) throws CertStoreException + String[] attrs) + throws CertStoreException { String filter = attributeName + "=" + attributeValue; +// System.out.println(filter); if (attributeName == null) { filter = null; @@ -417,7 +475,6 @@ private Set search(String attributeName, String attributeValue, Set set = new HashSet(); try { - ctx = connectLDAP(); SearchControls constraints = new SearchControls(); @@ -456,7 +513,6 @@ private Set search(String attributeName, String attributeValue, { throw new CertStoreException( "Error getting results from LDAP directory " + e); - } finally { @@ -473,5 +529,4 @@ private Set search(String attributeName, String attributeValue, } return set; } - } diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/X509SignatureUtil.java b/prov/src/main/java/org/bouncycastle/jce/provider/X509SignatureUtil.java index eb1e556ed5..8f57457418 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/X509SignatureUtil.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/X509SignatureUtil.java @@ -16,12 +16,12 @@ import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; class X509SignatureUtil { diff --git a/prov/src/main/java/org/bouncycastle/jce/spec/GOST3410ParameterSpec.java b/prov/src/main/java/org/bouncycastle/jce/spec/GOST3410ParameterSpec.java index 6e0980db7d..ba2bd01965 100644 --- a/prov/src/main/java/org/bouncycastle/jce/spec/GOST3410ParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/jce/spec/GOST3410ParameterSpec.java @@ -103,8 +103,9 @@ public boolean equals(Object o) { GOST3410ParameterSpec other = (GOST3410ParameterSpec)o; - return this.keyParameters.equals(other.keyParameters) - && this.digestParamSetOID.equals(other.digestParamSetOID) + return this.keyParameters.equals(other.keyParameters) + && (this.digestParamSetOID == other.digestParamSetOID + || (this.digestParamSetOID != null && this.digestParamSetOID.equals(other.digestParamSetOID))) && (this.encryptionParamSetOID == other.encryptionParamSetOID || (this.encryptionParamSetOID != null && this.encryptionParamSetOID.equals(other.encryptionParamSetOID))); } @@ -127,7 +128,14 @@ public static GOST3410ParameterSpec fromPublicKeyAlg( } else { - return new GOST3410ParameterSpec(params.getPublicKeyParamSet().getId(), params.getDigestParamSet().getId()); + if (params.getDigestParamSet() != null) + { + return new GOST3410ParameterSpec(params.getPublicKeyParamSet().getId(), params.getDigestParamSet().getId()); + } + else + { + return new GOST3410ParameterSpec(params.getPublicKeyParamSet().getId(), null); + } } } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BIKE.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BIKE.java index c213108f75..fa3bda3495 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BIKE.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BIKE.java @@ -29,6 +29,10 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("Cipher.BIKE", PREFIX + "BIKECipherSpi$Base"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_bike, "BIKE"); + addCipherAlgorithm(provider, "BIKE128", PREFIX + "BIKECipherSpi$BIKE128", BCObjectIdentifiers.bike128); + addCipherAlgorithm(provider, "BIKE192", PREFIX + "BIKECipherSpi$BIKE192", BCObjectIdentifiers.bike192); + addCipherAlgorithm(provider, "BIKE256", PREFIX + "BIKECipherSpi$BIKE256", BCObjectIdentifiers.bike256); + registerOid(provider, BCObjectIdentifiers.pqc_kem_bike, "BIKE", keyFact); } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java index 457a1f2380..999464e50a 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java @@ -22,7 +22,7 @@ public class BouncyCastlePQCProvider extends Provider implements ConfigurableProvider { - private static String info = "BouncyCastle Post-Quantum Security Provider v1.73"; + private static String info = "BouncyCastle Post-Quantum Security Provider v1.78.1"; public static String PROVIDER_NAME = "BCPQC"; @@ -50,7 +50,7 @@ public class BouncyCastlePQCProvider */ public BouncyCastlePQCProvider() { - super(PROVIDER_NAME, 1.73, info); + super(PROVIDER_NAME, 1.7801, info); AccessController.doPrivileged(new PrivilegedAction() { diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/CMCE.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/CMCE.java index 5e6eb2cdfa..669a55294b 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/CMCE.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/CMCE.java @@ -29,6 +29,12 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("Cipher.CMCE", PREFIX + "CMCECipherSpi$Base"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_mceliece, "CMCE"); + addCipherAlgorithm(provider, "mceliece348864", PREFIX + "CMCECipherSpi$MCE348864", BCObjectIdentifiers.mceliece348864_r3); + addCipherAlgorithm(provider, "mceliece460896", PREFIX + "CMCECipherSpi$MCE460896", BCObjectIdentifiers.mceliece460896_r3); + addCipherAlgorithm(provider, "mceliece6688128", PREFIX + "CMCECipherSpi$MCE6688128", BCObjectIdentifiers.mceliece6688128_r3); + addCipherAlgorithm(provider, "mceliece6960119", PREFIX + "CMCECipherSpi$MCE6960119", BCObjectIdentifiers.mceliece6960119_r3); + addCipherAlgorithm(provider, "mceliece8192128", PREFIX + "CMCECipherSpi$MCE8192128", BCObjectIdentifiers.mceliece8192128_r3); + registerOid(provider, BCObjectIdentifiers.pqc_kem_mceliece, "CMCE", keyFact); registerOidAlgorithmParameters(provider, BCObjectIdentifiers.pqc_kem_mceliece, "CMCE"); } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/Dilithium.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/Dilithium.java index 604d5f2d7f..c0a92b25f0 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/Dilithium.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/Dilithium.java @@ -3,9 +3,7 @@ import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; -import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; import org.bouncycastle.pqc.jcajce.provider.dilithium.DilithiumKeyFactorySpi; -import org.bouncycastle.pqc.jcajce.provider.falcon.FalconKeyFactorySpi; public class Dilithium { @@ -25,27 +23,18 @@ public void configure(ConfigurableProvider provider) addKeyFactoryAlgorithm(provider, "DILITHIUM2", PREFIX + "DilithiumKeyFactorySpi$Base2", BCObjectIdentifiers.dilithium2, new DilithiumKeyFactorySpi.Base2()); addKeyFactoryAlgorithm(provider, "DILITHIUM3", PREFIX + "DilithiumKeyFactorySpi$Base3", BCObjectIdentifiers.dilithium3, new DilithiumKeyFactorySpi.Base3()); addKeyFactoryAlgorithm(provider, "DILITHIUM5", PREFIX + "DilithiumKeyFactorySpi$Base5", BCObjectIdentifiers.dilithium5, new DilithiumKeyFactorySpi.Base5()); - addKeyFactoryAlgorithm(provider, "DILITHIUM2-AES", PREFIX + "DilithiumKeyFactorySpi$Base2_AES", BCObjectIdentifiers.dilithium2_aes, new DilithiumKeyFactorySpi.Base2()); - addKeyFactoryAlgorithm(provider, "DILITHIUM3-AES", PREFIX + "DilithiumKeyFactorySpi$Base3_AES", BCObjectIdentifiers.dilithium3_aes, new DilithiumKeyFactorySpi.Base3()); - addKeyFactoryAlgorithm(provider, "DILITHIUM5-AES", PREFIX + "DilithiumKeyFactorySpi$Base5_AES", BCObjectIdentifiers.dilithium5_aes, new DilithiumKeyFactorySpi.Base5()); provider.addAlgorithm("KeyPairGenerator.DILITHIUM", PREFIX + "DilithiumKeyPairGeneratorSpi"); addKeyPairGeneratorAlgorithm(provider, "DILITHIUM2", PREFIX + "DilithiumKeyPairGeneratorSpi$Base2", BCObjectIdentifiers.dilithium2); addKeyPairGeneratorAlgorithm(provider, "DILITHIUM3", PREFIX + "DilithiumKeyPairGeneratorSpi$Base3", BCObjectIdentifiers.dilithium3); addKeyPairGeneratorAlgorithm(provider, "DILITHIUM5", PREFIX + "DilithiumKeyPairGeneratorSpi$Base5", BCObjectIdentifiers.dilithium5); - addKeyPairGeneratorAlgorithm(provider, "DILITHIUM2-AES", PREFIX + "DilithiumKeyPairGeneratorSpi$Base2_AES", BCObjectIdentifiers.dilithium2_aes); - addKeyPairGeneratorAlgorithm(provider, "DILITHIUM3-AES", PREFIX + "DilithiumKeyPairGeneratorSpi$Base3_AES", BCObjectIdentifiers.dilithium3_aes); - addKeyPairGeneratorAlgorithm(provider, "DILITHIUM5-AES", PREFIX + "DilithiumKeyPairGeneratorSpi$Base5_AES", BCObjectIdentifiers.dilithium5_aes); addSignatureAlgorithm(provider, "DILITHIUM", PREFIX + "SignatureSpi$Base", BCObjectIdentifiers.dilithium); addSignatureAlgorithm(provider, "DILITHIUM2", PREFIX + "SignatureSpi$Base2", BCObjectIdentifiers.dilithium2); addSignatureAlgorithm(provider, "DILITHIUM3", PREFIX + "SignatureSpi$Base3", BCObjectIdentifiers.dilithium3); addSignatureAlgorithm(provider, "DILITHIUM5", PREFIX + "SignatureSpi$Base5", BCObjectIdentifiers.dilithium5); - addSignatureAlgorithm(provider, "DILITHIUM2-AES", PREFIX + "SignatureSpi$Base2_AES", BCObjectIdentifiers.dilithium2_aes); - addSignatureAlgorithm(provider, "DILITHIUM3-AES", PREFIX + "SignatureSpi$Base3_AES", BCObjectIdentifiers.dilithium3_aes); - addSignatureAlgorithm(provider, "DILITHIUM5-AES", PREFIX + "SignatureSpi$Base5_AES", BCObjectIdentifiers.dilithium5_aes); } } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/HQC.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/HQC.java index fca5a567ef..6492ad122a 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/HQC.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/HQC.java @@ -29,6 +29,10 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("Cipher.HQC", PREFIX + "HQCCipherSpi$Base"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_hqc, "HQC"); + addCipherAlgorithm(provider, "HQC128", PREFIX + "HQCCipherSpi$HQC128", BCObjectIdentifiers.hqc128); + addCipherAlgorithm(provider, "HQC192", PREFIX + "HQCCipherSpi$HQC192", BCObjectIdentifiers.hqc192); + addCipherAlgorithm(provider, "HQC256", PREFIX + "HQCCipherSpi$HQC256", BCObjectIdentifiers.hqc256); + registerOid(provider, BCObjectIdentifiers.pqc_kem_hqc, "HQC", keyFact); } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/Kyber.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/Kyber.java index a6ff763721..d959f51b34 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/Kyber.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/Kyber.java @@ -1,6 +1,7 @@ package org.bouncycastle.pqc.jcajce.provider; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; @@ -21,42 +22,42 @@ public void configure(ConfigurableProvider provider) { provider.addAlgorithm("KeyFactory.KYBER", PREFIX + "KyberKeyFactorySpi"); - addKeyFactoryAlgorithm(provider, "KYBER512", PREFIX + "KyberKeyFactorySpi$Kyber512", BCObjectIdentifiers.kyber512, new KyberKeyFactorySpi.Kyber512()); - addKeyFactoryAlgorithm(provider, "KYBER768", PREFIX + "KyberKeyFactorySpi$Kyber768", BCObjectIdentifiers.kyber768, new KyberKeyFactorySpi.Kyber768()); - addKeyFactoryAlgorithm(provider, "KYBER1024", PREFIX + "KyberKeyFactorySpi$Kyber1024", BCObjectIdentifiers.kyber1024, new KyberKeyFactorySpi.Kyber1024()); - addKeyFactoryAlgorithm(provider, "KYBER512-AES", PREFIX + "KyberKeyFactorySpi$Kyber512_AES", BCObjectIdentifiers.kyber512_aes, new KyberKeyFactorySpi.Kyber512_AES()); - addKeyFactoryAlgorithm(provider, "KYBER768-AES", PREFIX + "KyberKeyFactorySpi$Kyber768_AES", BCObjectIdentifiers.kyber768_aes, new KyberKeyFactorySpi.Kyber768_AES()); - addKeyFactoryAlgorithm(provider, "KYBER1024-AES", PREFIX + "KyberKeyFactorySpi$Kyber1024_AES", BCObjectIdentifiers.kyber1024_aes, new KyberKeyFactorySpi.Kyber1024_AES()); + addKeyFactoryAlgorithm(provider, "ML-KEM-512", PREFIX + "KyberKeyFactorySpi$Kyber512", NISTObjectIdentifiers.id_alg_ml_kem_512, new KyberKeyFactorySpi.Kyber512()); + addKeyFactoryAlgorithm(provider, "ML-KEM-768", PREFIX + "KyberKeyFactorySpi$Kyber768", NISTObjectIdentifiers.id_alg_ml_kem_768, new KyberKeyFactorySpi.Kyber768()); + addKeyFactoryAlgorithm(provider, "ML-KEM-1024", PREFIX + "KyberKeyFactorySpi$Kyber1024", NISTObjectIdentifiers.id_alg_ml_kem_1024, new KyberKeyFactorySpi.Kyber1024()); + provider.addAlgorithm("Alg.Alias.KeyFactory.KYBER512", "ML-KEM-512"); + provider.addAlgorithm("Alg.Alias.KeyFactory.KYBER768", "ML-KEM-768"); + provider.addAlgorithm("Alg.Alias.KeyFactory.KYBER1024", "ML-KEM-1024"); - provider.addAlgorithm("KeyPairGenerator.KYBER", PREFIX + "KyberKeyPairGeneratorSpi"); - - addKeyPairGeneratorAlgorithm(provider, "KYBER512", PREFIX + "KyberKeyPairGeneratorSpi$Kyber512", BCObjectIdentifiers.kyber512); - addKeyPairGeneratorAlgorithm(provider, "KYBER768", PREFIX + "KyberKeyPairGeneratorSpi$Kyber768", BCObjectIdentifiers.kyber768); - addKeyPairGeneratorAlgorithm(provider, "KYBER1024", PREFIX + "KyberKeyPairGeneratorSpi$Kyber1024", BCObjectIdentifiers.kyber1024); - addKeyPairGeneratorAlgorithm(provider, "KYBER512-AES", PREFIX + "KyberKeyPairGeneratorSpi$Kyber512_AES", BCObjectIdentifiers.kyber512_aes); - addKeyPairGeneratorAlgorithm(provider, "KYBER768-AES", PREFIX + "KyberKeyPairGeneratorSpi$Kyber768_AES", BCObjectIdentifiers.kyber768_aes); - addKeyPairGeneratorAlgorithm(provider, "KYBER1024-AES", PREFIX + "KyberKeyPairGeneratorSpi$Kyber1024_AES", BCObjectIdentifiers.kyber1024_aes); + provider.addAlgorithm("KeyPairGenerator.ML-KEM", PREFIX + "KyberKeyPairGeneratorSpi"); + provider.addAlgorithm("KeyPairGenerator.ML-KEM-512", PREFIX + "KyberKeyPairGeneratorSpi$Kyber512"); + provider.addAlgorithm("KeyPairGenerator.ML-KEM-768", PREFIX + "KyberKeyPairGeneratorSpi$Kyber768"); + provider.addAlgorithm("KeyPairGenerator.ML-KEM-1024", PREFIX + "KyberKeyPairGeneratorSpi$Kyber1024"); + provider.addAlgorithm("Alg.Alias.KeyPairGenerator.KYBER", "ML-KEM"); + provider.addAlgorithm("Alg.Alias.KeyPairGenerator.KYBER512", "ML-KEM-512"); + provider.addAlgorithm("Alg.Alias.KeyPairGenerator.KYBER768", "ML-KEM-768"); + provider.addAlgorithm("Alg.Alias.KeyPairGenerator.KYBER1024", "ML-KEM-1024"); provider.addAlgorithm("KeyGenerator.KYBER", PREFIX + "KyberKeyGeneratorSpi"); - addKeyGeneratorAlgorithm(provider, "KYBER512", PREFIX + "KyberKeyGeneratorSpi$Kyber512", BCObjectIdentifiers.kyber512); - addKeyGeneratorAlgorithm(provider, "KYBER768", PREFIX + "KyberKeyGeneratorSpi$Kyber768", BCObjectIdentifiers.kyber768); - addKeyGeneratorAlgorithm(provider, "KYBER1024", PREFIX + "KyberKeyGeneratorSpi$Kyber1024", BCObjectIdentifiers.kyber1024); - addKeyGeneratorAlgorithm(provider, "KYBER512-AES", PREFIX + "KyberKeyGeneratorSpi$Kyber512_AES", BCObjectIdentifiers.kyber512_aes); - addKeyGeneratorAlgorithm(provider, "KYBER768-AES", PREFIX + "KyberKeyGeneratorSpi$Kyber768_AES", BCObjectIdentifiers.kyber768_aes); - addKeyGeneratorAlgorithm(provider, "KYBER1024-AES", PREFIX + "KyberKeyGeneratorSpi$Kyber1024_AES", BCObjectIdentifiers.kyber1024_aes); + addKeyGeneratorAlgorithm(provider, "ML-KEM-512", PREFIX + "KyberKeyGeneratorSpi$Kyber512", NISTObjectIdentifiers.id_alg_ml_kem_512); + addKeyGeneratorAlgorithm(provider, "ML-KEM-768", PREFIX + "KyberKeyGeneratorSpi$Kyber768", NISTObjectIdentifiers.id_alg_ml_kem_768); + addKeyGeneratorAlgorithm(provider, "ML-KEM-1024", PREFIX + "KyberKeyGeneratorSpi$Kyber1024", NISTObjectIdentifiers.id_alg_ml_kem_1024); + provider.addAlgorithm("Alg.Alias.KeyGenerator.KYBER512", "ML-KEM-512"); + provider.addAlgorithm("Alg.Alias.KeyGenerator.KYBER768", "ML-KEM-768"); + provider.addAlgorithm("Alg.Alias.KeyGenerator.KYBER1024", "ML-KEM-1024"); AsymmetricKeyInfoConverter keyFact = new KyberKeyFactorySpi(); provider.addAlgorithm("Cipher.KYBER", PREFIX + "KyberCipherSpi$Base"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_kyber, "KYBER"); - addCipherAlgorithm(provider, "KYBER512", PREFIX + "KyberCipherSpi$Kyber512", BCObjectIdentifiers.kyber512); - addCipherAlgorithm(provider, "KYBER768", PREFIX + "KyberCipherSpi$Kyber768", BCObjectIdentifiers.kyber768); - addCipherAlgorithm(provider, "KYBER1024", PREFIX + "KyberCipherSpi$Kyber1024", BCObjectIdentifiers.kyber1024); - addCipherAlgorithm(provider, "KYBER512-AES", PREFIX + "KyberCipherSpi$Kyber512_AES", BCObjectIdentifiers.kyber512_aes); - addCipherAlgorithm(provider, "KYBER768-AES", PREFIX + "KyberCipherSpi$Kyber768_AES", BCObjectIdentifiers.kyber768_aes); - addCipherAlgorithm(provider, "KYBER1024-AES", PREFIX + "KyberCipherSpi$Kyber1024_AES", BCObjectIdentifiers.kyber1024_aes); + addCipherAlgorithm(provider, "ML-KEM-512", PREFIX + "KyberCipherSpi$Kyber512", NISTObjectIdentifiers.id_alg_ml_kem_512); + addCipherAlgorithm(provider, "ML-KEM-768", PREFIX + "KyberCipherSpi$Kyber768", NISTObjectIdentifiers.id_alg_ml_kem_768); + addCipherAlgorithm(provider, "ML-KEM-1024", PREFIX + "KyberCipherSpi$Kyber1024", NISTObjectIdentifiers.id_alg_ml_kem_1024); + provider.addAlgorithm("Alg.Alias.Cipher.KYBER512", "ML-KEM-512"); + provider.addAlgorithm("Alg.Alias.Cipher.KYBER768", "ML-KEM-768"); + provider.addAlgorithm("Alg.Alias.Cipher.KYBER1024", "ML-KEM-1024"); registerOid(provider, BCObjectIdentifiers.pqc_kem_kyber, "KYBER", keyFact); } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java index 23e929094a..f4d62eac28 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java @@ -4,7 +4,8 @@ import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; -import org.bouncycastle.pqc.jcajce.provider.ntru.NTRUKeyFactorySpi; +import org.bouncycastle.pqc.jcajce.provider.ntruprime.NTRULPRimeKeyFactorySpi; +import org.bouncycastle.pqc.jcajce.provider.ntruprime.SNTRUPrimeKeyFactorySpi; public class NTRUPrime { @@ -24,7 +25,7 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("KeyGenerator.NTRULPRIME", PREFIX + "NTRULPRimeKeyGeneratorSpi"); - AsymmetricKeyInfoConverter keyFact = new NTRUKeyFactorySpi(); + AsymmetricKeyInfoConverter keyFact = new NTRULPRimeKeyFactorySpi(); provider.addAlgorithm("Cipher.NTRULPRIME", PREFIX + "NTRULPRimeCipherSpi$Base"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_ntrulprime, "NTRU"); @@ -41,7 +42,7 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("KeyGenerator.SNTRUPRIME", PREFIX + "SNTRUPrimeKeyGeneratorSpi"); - keyFact = new NTRUKeyFactorySpi(); + keyFact = new SNTRUPrimeKeyFactorySpi(); provider.addAlgorithm("Cipher.SNTRUPRIME", PREFIX + "SNTRUPrimeCipherSpi$Base"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_sntruprime, "NTRU"); diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/SPHINCSPlus.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/SPHINCSPlus.java index 99efe4be5b..8ef9b9e45e 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/SPHINCSPlus.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/SPHINCSPlus.java @@ -24,9 +24,22 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("Alg.Alias.KeyFactory.SPHINCS+", "SPHINCSPLUS"); provider.addAlgorithm("Alg.Alias.KeyPairGenerator.SPHINCS+", "SPHINCSPLUS"); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHA2-128S", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Sha2_128s", BCObjectIdentifiers.sphincsPlus_sha2_128s); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHA2-128F", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Sha2_128f", BCObjectIdentifiers.sphincsPlus_sha2_128f); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHA2-192S", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Sha2_192s", BCObjectIdentifiers.sphincsPlus_sha2_192s); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHA2-192F", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Sha2_192f", BCObjectIdentifiers.sphincsPlus_sha2_192f); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHA2-256S", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Sha2_256s", BCObjectIdentifiers.sphincsPlus_sha2_256s); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHA2-256F", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Sha2_256f", BCObjectIdentifiers.sphincsPlus_sha2_256f); + + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHAKE-128S", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Shake_128s", BCObjectIdentifiers.sphincsPlus_shake_128s); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHAKE-128F", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Shake_128f", BCObjectIdentifiers.sphincsPlus_shake_128f); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHAKE-192S", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Shake_192s", BCObjectIdentifiers.sphincsPlus_shake_192s); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHAKE-192F", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Shake_192f", BCObjectIdentifiers.sphincsPlus_shake_192f); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHAKE-256S", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Shake_256s", BCObjectIdentifiers.sphincsPlus_shake_256s); + addKeyPairGeneratorAlgorithm(provider, "SPHINCS+-SHAKE-256F", PREFIX + "SPHINCSPlusKeyPairGeneratorSpi$Shake_256f", BCObjectIdentifiers.sphincsPlus_shake_256f); + addSignatureAlgorithm(provider, "SPHINCSPLUS", PREFIX + "SignatureSpi$Direct", BCObjectIdentifiers.sphincsPlus); - addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_sha2_128s_r3); addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_sha2_128f_r3); addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_shake_128s_r3); addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_shake_128f_r3); @@ -44,30 +57,67 @@ public void configure(ConfigurableProvider provider) addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_shake_256f_r3); addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_haraka_256s_r3); addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_haraka_256f_r3); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple); + addSignatureAlias(provider, "SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple); provider.addAlgorithm("Alg.Alias.Signature.SPHINCS+", "SPHINCSPLUS"); AsymmetricKeyInfoConverter keyFact = new SPHINCSPlusKeyFactorySpi(); - registerOid(provider, BCObjectIdentifiers.sphincsPlus, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_128s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_128f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_192s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_192f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256f_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, "SPHINCSPLUS", keyFact); - registerOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus, "SPHINCSPLUS", keyFact); + + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_128s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_128f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_192s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_192f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple, "SPHINCSPLUS", keyFact); + registerKeyFactoryOid(provider, BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple, "SPHINCSPLUS", keyFact); } } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/XMSS.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/XMSS.java index 878f1c15ca..0bcfecd70b 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/XMSS.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/XMSS.java @@ -1,7 +1,7 @@ package org.bouncycastle.pqc.jcajce.provider; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; -import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers; +import org.bouncycastle.internal.asn1.isara.IsaraObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; @@ -35,12 +35,16 @@ public void configure(ConfigurableProvider provider) addSignatureAlgorithm(provider, "SHA256", "XMSS-SHA256", PREFIX + "XMSSSignatureSpi$withSha256andPrehash", BCObjectIdentifiers.xmss_SHA256ph); addSignatureAlgorithm(provider, "SHAKE128", "XMSS-SHAKE128", PREFIX + "XMSSSignatureSpi$withShake128andPrehash", BCObjectIdentifiers.xmss_SHAKE128ph); + addSignatureAlgorithm(provider, "SHAKE128(512)", "XMSS-SHAKE128", PREFIX + "XMSSSignatureSpi$withShake128_512andPrehash", BCObjectIdentifiers.xmss_SHAKE128_512ph); addSignatureAlgorithm(provider, "SHA512", "XMSS-SHA512", PREFIX + "XMSSSignatureSpi$withSha512andPrehash", BCObjectIdentifiers.xmss_SHA512ph); addSignatureAlgorithm(provider, "SHAKE256", "XMSS-SHAKE256", PREFIX + "XMSSSignatureSpi$withShake256andPrehash", BCObjectIdentifiers.xmss_SHAKE256ph); + addSignatureAlgorithm(provider, "SHAKE256(1024)", "XMSS-SHAKE256", PREFIX + "XMSSSignatureSpi$withShake256_1024andPrehash", BCObjectIdentifiers.xmss_SHAKE256_1024ph); provider.addAlgorithm("Alg.Alias.Signature.SHA256WITHXMSS", "SHA256WITHXMSS-SHA256"); provider.addAlgorithm("Alg.Alias.Signature.SHAKE128WITHXMSS", "SHAKE128WITHXMSS-SHAKE128"); + provider.addAlgorithm("Alg.Alias.Signature.SHAKE128(512)WITHXMSS", "SHAKE128(512)WITHXMSS-SHAKE128"); provider.addAlgorithm("Alg.Alias.Signature.SHA512WITHXMSS", "SHA512WITHXMSS-SHA512"); provider.addAlgorithm("Alg.Alias.Signature.SHAKE256WITHXMSS", "SHAKE256WITHXMSS-SHAKE256"); + provider.addAlgorithm("Alg.Alias.Signature.SHAKE256(1024)WITHXMSS", "SHAKE256(1024)WITHXMSS-SHAKE256"); provider.addAlgorithm("KeyFactory.XMSSMT", PREFIX + "XMSSMTKeyFactorySpi"); provider.addAlgorithm("KeyPairGenerator.XMSSMT", PREFIX + "XMSSMTKeyPairGeneratorSpi"); @@ -56,12 +60,16 @@ public void configure(ConfigurableProvider provider) addSignatureAlgorithm(provider, "SHA256", "XMSSMT-SHA256", PREFIX + "XMSSMTSignatureSpi$withSha256andPrehash", BCObjectIdentifiers.xmss_mt_SHA256ph); addSignatureAlgorithm(provider, "SHAKE128", "XMSSMT-SHAKE128", PREFIX + "XMSSMTSignatureSpi$withShake128andPrehash", BCObjectIdentifiers.xmss_mt_SHAKE128ph); + addSignatureAlgorithm(provider, "SHAKE128(512)", "XMSSMT-SHAKE128", PREFIX + "XMSSMTSignatureSpi$withShake128_512andPrehash", BCObjectIdentifiers.xmss_mt_SHAKE128_512ph); addSignatureAlgorithm(provider, "SHA512", "XMSSMT-SHA512", PREFIX + "XMSSMTSignatureSpi$withSha512andPrehash", BCObjectIdentifiers.xmss_mt_SHA512ph); addSignatureAlgorithm(provider, "SHAKE256", "XMSSMT-SHAKE256", PREFIX + "XMSSMTSignatureSpi$withShake256andPrehash", BCObjectIdentifiers.xmss_mt_SHAKE256ph); + addSignatureAlgorithm(provider, "SHAKE256(1024)", "XMSSMT-SHAKE256", PREFIX + "XMSSMTSignatureSpi$withShake256_1024andPrehash", BCObjectIdentifiers.xmss_mt_SHAKE256_1024ph); provider.addAlgorithm("Alg.Alias.Signature.SHA256WITHXMSSMT", "SHA256WITHXMSSMT-SHA256"); provider.addAlgorithm("Alg.Alias.Signature.SHAKE128WITHXMSSMT", "SHAKE128WITHXMSSMT-SHAKE128"); + provider.addAlgorithm("Alg.Alias.Signature.SHAKE128(512)WITHXMSSMT", "SHAKE128(512)WITHXMSSMT-SHAKE128"); provider.addAlgorithm("Alg.Alias.Signature.SHA512WITHXMSSMT", "SHA512WITHXMSSMT-SHA512"); provider.addAlgorithm("Alg.Alias.Signature.SHAKE256WITHXMSSMT", "SHAKE256WITHXMSSMT-SHAKE256"); + provider.addAlgorithm("Alg.Alias.Signature.SHAKE256(1024)WITHXMSSMT", "SHAKE256(1024)WITHXMSSMT-SHAKE256"); registerOid(provider, PQCObjectIdentifiers.xmss, "XMSS", new XMSSKeyFactorySpi()); registerOid(provider, IsaraObjectIdentifiers.id_alg_xmss, "XMSS", new XMSSKeyFactorySpi()); diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/bike/BCBIKEPrivateKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/bike/BCBIKEPrivateKey.java index 3860809d23..61fe110884 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/bike/BCBIKEPrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/bike/BCBIKEPrivateKey.java @@ -13,6 +13,7 @@ import org.bouncycastle.pqc.jcajce.interfaces.BIKEKey; import org.bouncycastle.pqc.jcajce.spec.BIKEParameterSpec; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; public class BCBIKEPrivateKey implements PrivateKey, BIKEKey @@ -70,11 +71,11 @@ public int hashCode() } /** - * @return name of the algorithm - "BIKE" + * @return name of the algorithm - "BIKE[128|192|256]" */ public final String getAlgorithm() { - return "BIKE"; + return Strings.toUpperCase(params.getParameters().getName()); } public byte[] getEncoded() diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/bike/BCBIKEPublicKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/bike/BCBIKEPublicKey.java index fd982e3f06..100df2c92a 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/bike/BCBIKEPublicKey.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/bike/BCBIKEPublicKey.java @@ -12,6 +12,7 @@ import org.bouncycastle.pqc.jcajce.interfaces.BIKEKey; import org.bouncycastle.pqc.jcajce.spec.BIKEParameterSpec; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; public class BCBIKEPublicKey implements PublicKey, BIKEKey @@ -71,7 +72,7 @@ public int hashCode() */ public final String getAlgorithm() { - return "BIKE"; + return Strings.toUpperCase(params.getParameters().getName()); } public byte[] getEncoded() diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/bike/BIKECipherSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/bike/BIKECipherSpi.java index 8bf0fe9e7a..b7b2eaddc8 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/bike/BIKECipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/bike/BIKECipherSpi.java @@ -25,32 +25,40 @@ import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.jcajce.spec.KEMParameterSpec; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; import org.bouncycastle.pqc.crypto.bike.BIKEKEMExtractor; import org.bouncycastle.pqc.crypto.bike.BIKEKEMGenerator; -import org.bouncycastle.pqc.crypto.cmce.CMCEKEMGenerator; -import org.bouncycastle.pqc.jcajce.provider.cmce.BCCMCEPrivateKey; -import org.bouncycastle.pqc.jcajce.provider.cmce.BCCMCEPublicKey; +import org.bouncycastle.pqc.crypto.bike.BIKEParameters; import org.bouncycastle.pqc.jcajce.provider.util.WrapUtil; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Exceptions; +import org.bouncycastle.util.Strings; class BIKECipherSpi extends CipherSpi { private final String algorithmName; private BIKEKEMGenerator kemGen; - private KEMParameterSpec kemParameterSpec; + private KTSParameterSpec kemParameterSpec; private BCBIKEPublicKey wrapKey; private BCBIKEPrivateKey unwrapKey; private AlgorithmParameters engineParams; + private BIKEParameters bikeParameters; BIKECipherSpi(String algorithmName) throws NoSuchAlgorithmException { + this.bikeParameters = null; this.algorithmName = algorithmName; } + BIKECipherSpi(BIKEParameters bikeParameters) + { + this.bikeParameters = bikeParameters; + this.algorithmName = Strings.toUpperCase(bikeParameters.getName()); + } + @Override protected void engineSetMode(String mode) throws NoSuchAlgorithmException @@ -135,12 +143,12 @@ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec paramSpec, } else { - if (!(paramSpec instanceof KEMParameterSpec)) + if (!(paramSpec instanceof KTSParameterSpec)) { throw new InvalidAlgorithmParameterException(algorithmName + " can only accept KTSParameterSpec"); } - kemParameterSpec = (KEMParameterSpec)paramSpec; + kemParameterSpec = (KTSParameterSpec)paramSpec; } if (opmode == Cipher.WRAP_MODE) @@ -170,6 +178,15 @@ else if (opmode == Cipher.UNWRAP_MODE) { throw new InvalidParameterException("Cipher only valid for wrapping/unwrapping"); } + + if (bikeParameters != null) + { + String canonicalAlgName = Strings.toUpperCase(bikeParameters.getName()); + if (!canonicalAlgName.equals(key.getAlgorithm())) + { + throw new InvalidKeyException("cipher locked to " + canonicalAlgName + " " + key.getAlgorithm()); + } + } } @Override @@ -314,4 +331,31 @@ public Base() super("BIKE"); } } + + public static class BIKE128 + extends BIKECipherSpi + { + public BIKE128() + { + super(BIKEParameters.bike128); + } + } + + public static class BIKE192 + extends BIKECipherSpi + { + public BIKE192() + { + super(BIKEParameters.bike192); + } + } + + public static class BIKE256 + extends BIKECipherSpi + { + public BIKE256() + { + super(BIKEParameters.bike256); + } + } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/cmce/BCCMCEPrivateKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/cmce/BCCMCEPrivateKey.java index feccb96f8e..e810a83003 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/cmce/BCCMCEPrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/cmce/BCCMCEPrivateKey.java @@ -13,6 +13,7 @@ import org.bouncycastle.pqc.jcajce.interfaces.CMCEKey; import org.bouncycastle.pqc.jcajce.spec.CMCEParameterSpec; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; public class BCCMCEPrivateKey implements PrivateKey, CMCEKey @@ -74,7 +75,7 @@ public int hashCode() */ public final String getAlgorithm() { - return "CMCE"; + return Strings.toUpperCase(params.getParameters().getName()); } public byte[] getEncoded() diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/cmce/BCCMCEPublicKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/cmce/BCCMCEPublicKey.java index 06df0a4338..386b92a975 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/cmce/BCCMCEPublicKey.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/cmce/BCCMCEPublicKey.java @@ -12,6 +12,7 @@ import org.bouncycastle.pqc.jcajce.interfaces.CMCEKey; import org.bouncycastle.pqc.jcajce.spec.CMCEParameterSpec; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; public class BCCMCEPublicKey implements PublicKey, CMCEKey @@ -71,7 +72,7 @@ public int hashCode() */ public final String getAlgorithm() { - return "CMCE"; + return Strings.toUpperCase(params.getParameters().getName()); } public byte[] getEncoded() diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/cmce/CMCECipherSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/cmce/CMCECipherSpi.java index ad0f7beeb6..0bfab13aa4 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/cmce/CMCECipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/cmce/CMCECipherSpi.java @@ -25,28 +25,38 @@ import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.jcajce.spec.KEMParameterSpec; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; import org.bouncycastle.pqc.crypto.cmce.CMCEKEMExtractor; import org.bouncycastle.pqc.crypto.cmce.CMCEKEMGenerator; +import org.bouncycastle.pqc.crypto.cmce.CMCEParameters; import org.bouncycastle.pqc.jcajce.provider.util.WrapUtil; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Exceptions; +import org.bouncycastle.util.Strings; class CMCECipherSpi extends CipherSpi { private final String algorithmName; private CMCEKEMGenerator kemGen; - private KEMParameterSpec kemParameterSpec; + private KTSParameterSpec kemParameterSpec; private BCCMCEPublicKey wrapKey; private BCCMCEPrivateKey unwrapKey; private AlgorithmParameters engineParams; + private CMCEParameters cmceParameters; CMCECipherSpi(String algorithmName) { this.algorithmName = algorithmName; } + CMCECipherSpi(CMCEParameters cmceParameters) + { + this.cmceParameters = cmceParameters; + this.algorithmName = Strings.toUpperCase(cmceParameters.getName()); + } + @Override protected void engineSetMode(String mode) throws NoSuchAlgorithmException @@ -131,12 +141,12 @@ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec paramSpec, } else { - if (!(paramSpec instanceof KEMParameterSpec)) + if (!(paramSpec instanceof KTSParameterSpec)) { throw new InvalidAlgorithmParameterException(algorithmName + " can only accept KTSParameterSpec"); } - kemParameterSpec = (KEMParameterSpec)paramSpec; + kemParameterSpec = (KTSParameterSpec)paramSpec; } if (opmode == Cipher.WRAP_MODE) @@ -166,6 +176,15 @@ else if (opmode == Cipher.UNWRAP_MODE) { throw new InvalidParameterException("Cipher only valid for wrapping/unwrapping"); } + + if (cmceParameters != null) + { + String canonicalAlgName = Strings.toUpperCase(cmceParameters.getName()); + if (!canonicalAlgName.equals(key.getAlgorithm())) + { + throw new InvalidKeyException("cipher locked to " + canonicalAlgName); + } + } } @Override @@ -310,4 +329,54 @@ public Base() super("CMCE"); } } + + public static class MCE348864 + extends CMCECipherSpi + { + public MCE348864() + throws NoSuchAlgorithmException + { + super(CMCEParameters.mceliece348864r3); + } + } + + public static class MCE460896 + extends CMCECipherSpi + { + public MCE460896() + throws NoSuchAlgorithmException + { + super(CMCEParameters.mceliece460896r3); + } + } + + public static class MCE6688128 + extends CMCECipherSpi + { + public MCE6688128() + throws NoSuchAlgorithmException + { + super(CMCEParameters.mceliece6688128r3); + } + } + + public static class MCE6960119 + extends CMCECipherSpi + { + public MCE6960119() + throws NoSuchAlgorithmException + { + super(CMCEParameters.mceliece6960119r3); + } + } + + public static class MCE8192128 + extends CMCECipherSpi + { + public MCE8192128() + throws NoSuchAlgorithmException + { + super(CMCEParameters.mceliece8192128r3); + } + } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/BCDilithiumPrivateKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/BCDilithiumPrivateKey.java index 63db847620..9e5aba9069 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/BCDilithiumPrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/BCDilithiumPrivateKey.java @@ -8,7 +8,6 @@ import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPrivateKeyParameters; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberPrivateKeyParameters; import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; import org.bouncycastle.pqc.jcajce.interfaces.DilithiumPrivateKey; @@ -54,7 +53,7 @@ private void init(DilithiumPrivateKeyParameters params, ASN1Set attributes) } /** - * Compare this SPHINCS-256 private key with another object. + * Compare this Dilithium private key with another object. * * @param o the other object * @return the result of the comparison @@ -101,7 +100,7 @@ public byte[] getEncoded() public DilithiumPublicKey getPublicKey() { - return new BCDilithiumPublicKey(new DilithiumPublicKeyParameters(params.getParameters(), params.getRho(), params.getT1())); + return new BCDilithiumPublicKey(params.getPublicKeyParameters()); } public DilithiumParameterSpec getParameterSpec() diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/DilithiumKeyFactorySpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/DilithiumKeyFactorySpi.java index 8b0a3402a9..1ed163c146 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/DilithiumKeyFactorySpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/DilithiumKeyFactorySpi.java @@ -3,8 +3,6 @@ import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; -import java.security.KeyFactorySpi; -import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; @@ -15,12 +13,9 @@ import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; -import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumParameters; import org.bouncycastle.pqc.jcajce.provider.util.BaseKeyFactorySpi; public class DilithiumKeyFactorySpi diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/DilithiumKeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/DilithiumKeyPairGeneratorSpi.java index 52a2cad1d7..5d3eb19284 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/DilithiumKeyPairGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/DilithiumKeyPairGeneratorSpi.java @@ -15,9 +15,6 @@ import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumParameters; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPrivateKeyParameters; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPublicKeyParameters; -import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumSigner; -import org.bouncycastle.pqc.crypto.falcon.FalconKeyGenerationParameters; -import org.bouncycastle.pqc.crypto.falcon.FalconParameters; import org.bouncycastle.pqc.jcajce.provider.util.SpecUtil; import org.bouncycastle.pqc.jcajce.spec.DilithiumParameterSpec; import org.bouncycastle.util.Strings; @@ -32,9 +29,6 @@ public class DilithiumKeyPairGeneratorSpi parameters.put(DilithiumParameterSpec.dilithium2.getName(), DilithiumParameters.dilithium2); parameters.put(DilithiumParameterSpec.dilithium3.getName(), DilithiumParameters.dilithium3); parameters.put(DilithiumParameterSpec.dilithium5.getName(), DilithiumParameters.dilithium5); - parameters.put(DilithiumParameterSpec.dilithium2_aes.getName(), DilithiumParameters.dilithium2_aes); - parameters.put(DilithiumParameterSpec.dilithium3_aes.getName(), DilithiumParameters.dilithium3_aes); - parameters.put(DilithiumParameterSpec.dilithium5_aes.getName(), DilithiumParameters.dilithium5_aes); } private final DilithiumParameters dilithiumParameters; @@ -157,34 +151,4 @@ public Base5() super(DilithiumParameters.dilithium5); } } - - public static class Base2_AES - extends DilithiumKeyPairGeneratorSpi - { - public Base2_AES() - throws NoSuchAlgorithmException - { - super(DilithiumParameters.dilithium2_aes); - } - } - - public static class Base3_AES - extends DilithiumKeyPairGeneratorSpi - { - public Base3_AES() - throws NoSuchAlgorithmException - { - super(DilithiumParameters.dilithium3_aes); - } - } - - public static class Base5_AES - extends DilithiumKeyPairGeneratorSpi - { - public Base5_AES() - throws NoSuchAlgorithmException - { - super(DilithiumParameters.dilithium5_aes); - } - } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/SignatureSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/SignatureSpi.java index 94ecc81fcf..c161cbc0ba 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/SignatureSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/dilithium/SignatureSpi.java @@ -1,7 +1,6 @@ package org.bouncycastle.pqc.jcajce.provider.dilithium; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; @@ -209,34 +208,4 @@ public Base5() super(new DilithiumSigner(), DilithiumParameters.dilithium5); } } - - public static class Base2_AES - extends SignatureSpi - { - public Base2_AES() - throws NoSuchAlgorithmException - { - super(new DilithiumSigner(), DilithiumParameters.dilithium2_aes); - } - } - - public static class Base3_AES - extends SignatureSpi - { - public Base3_AES() - throws NoSuchAlgorithmException - { - super(new DilithiumSigner(), DilithiumParameters.dilithium3_aes); - } - } - - public static class Base5_AES - extends SignatureSpi - { - public Base5_AES() - throws NoSuchAlgorithmException - { - super(new DilithiumSigner(), DilithiumParameters.dilithium5_aes); - } - } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/BCHQCPrivateKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/BCHQCPrivateKey.java index 3673fe2cf4..0002ab0a26 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/BCHQCPrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/BCHQCPrivateKey.java @@ -13,6 +13,7 @@ import org.bouncycastle.pqc.jcajce.interfaces.HQCKey; import org.bouncycastle.pqc.jcajce.spec.HQCParameterSpec; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; public class BCHQCPrivateKey implements PrivateKey, HQCKey @@ -74,7 +75,7 @@ public int hashCode() */ public final String getAlgorithm() { - return "HQC"; + return Strings.toUpperCase(params.getParameters().getName()); } public byte[] getEncoded() diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/BCHQCPublicKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/BCHQCPublicKey.java index 0ea41a143c..0f50de4509 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/BCHQCPublicKey.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/BCHQCPublicKey.java @@ -12,6 +12,7 @@ import org.bouncycastle.pqc.jcajce.interfaces.HQCKey; import org.bouncycastle.pqc.jcajce.spec.HQCParameterSpec; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; public class BCHQCPublicKey implements PublicKey, HQCKey @@ -71,7 +72,7 @@ public int hashCode() */ public final String getAlgorithm() { - return "HQC"; + return Strings.toUpperCase(params.getParameters().getName()); } public byte[] getEncoded() diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/HQCCipherSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/HQCCipherSpi.java index d08d0a8a7f..2281b93db1 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/HQCCipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/HQCCipherSpi.java @@ -25,21 +25,25 @@ import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.jcajce.spec.KEMParameterSpec; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; import org.bouncycastle.pqc.crypto.hqc.HQCKEMExtractor; import org.bouncycastle.pqc.crypto.hqc.HQCKEMGenerator; +import org.bouncycastle.pqc.crypto.hqc.HQCParameters; import org.bouncycastle.pqc.jcajce.provider.util.WrapUtil; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Exceptions; +import org.bouncycastle.util.Strings; class HQCCipherSpi extends CipherSpi { private final String algorithmName; private HQCKEMGenerator kemGen; - private KEMParameterSpec kemParameterSpec; + private KTSParameterSpec kemParameterSpec; private BCHQCPublicKey wrapKey; private BCHQCPrivateKey unwrapKey; private AlgorithmParameters engineParams; + private HQCParameters hqcParameters; HQCCipherSpi(String algorithmName) throws NoSuchAlgorithmException @@ -47,6 +51,12 @@ class HQCCipherSpi this.algorithmName = algorithmName; } + HQCCipherSpi(HQCParameters hqcParameters) + { + this.hqcParameters = hqcParameters; + this.algorithmName = Strings.toUpperCase(hqcParameters.getName()); + } + @Override protected void engineSetMode(String mode) throws NoSuchAlgorithmException @@ -131,12 +141,12 @@ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec paramSpec, } else { - if (!(paramSpec instanceof KEMParameterSpec)) + if (!(paramSpec instanceof KTSParameterSpec)) { throw new InvalidAlgorithmParameterException(algorithmName + " can only accept KTSParameterSpec"); } - kemParameterSpec = (KEMParameterSpec)paramSpec; + kemParameterSpec = (KTSParameterSpec)paramSpec; } if (opmode == Cipher.WRAP_MODE) @@ -166,6 +176,15 @@ else if (opmode == Cipher.UNWRAP_MODE) { throw new InvalidParameterException("Cipher only valid for wrapping/unwrapping"); } + + if (hqcParameters != null) + { + String canonicalAlgName = Strings.toUpperCase(hqcParameters.getName()); + if (!canonicalAlgName.equals(key.getAlgorithm())) + { + throw new InvalidKeyException("cipher locked to " + canonicalAlgName); + } + } } @Override @@ -272,7 +291,7 @@ protected Key engineUnwrap( try { HQCKEMExtractor kemExt = new HQCKEMExtractor(unwrapKey.getKeyParams()); - + byte[] secret = kemExt.extractSecret(Arrays.copyOfRange(wrappedKey, 0, kemExt.getEncapsulationLength())); Wrapper kWrap = WrapUtil.getWrapper(kemParameterSpec.getKeyAlgorithmName()); @@ -310,4 +329,31 @@ public Base() super("HQC"); } } + + public static class HQC128 + extends HQCCipherSpi + { + public HQC128() + { + super(HQCParameters.hqc128); + } + } + + public static class HQC192 + extends HQCCipherSpi + { + public HQC192() + { + super(HQCParameters.hqc192); + } + } + + public static class HQC256 + extends HQCCipherSpi + { + public HQC256() + { + super(HQCParameters.hqc256); + } + } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/BCKyberPrivateKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/BCKyberPrivateKey.java index e961ad9d2a..3441f5d716 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/BCKyberPrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/BCKyberPrivateKey.java @@ -4,16 +4,13 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberPrivateKeyParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; import org.bouncycastle.pqc.jcajce.interfaces.KyberPrivateKey; import org.bouncycastle.pqc.jcajce.interfaces.KyberPublicKey; -import org.bouncycastle.pqc.jcajce.provider.util.KeyUtil; import org.bouncycastle.pqc.jcajce.spec.KyberParameterSpec; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; @@ -23,12 +20,12 @@ public class BCKyberPrivateKey { private static final long serialVersionUID = 1L; - private transient KyberPrivateKeyParameters params; + private transient MLKEMPrivateKeyParameters params; private transient String algorithm; private transient ASN1Set attributes; public BCKyberPrivateKey( - KyberPrivateKeyParameters params) + MLKEMPrivateKeyParameters params) { this.params = params; this.algorithm = Strings.toUpperCase(params.getParameters().getName()); @@ -44,7 +41,7 @@ private void init(PrivateKeyInfo keyInfo) throws IOException { this.attributes = keyInfo.getAttributes();; - this.params = (KyberPrivateKeyParameters)PrivateKeyFactory.createKey(keyInfo); + this.params = (MLKEMPrivateKeyParameters)PrivateKeyFactory.createKey(keyInfo); this.algorithm = Strings.toUpperCase(params.getParameters().getName()); } @@ -100,7 +97,7 @@ public byte[] getEncoded() public KyberPublicKey getPublicKey() { - return new BCKyberPublicKey(new KyberPublicKeyParameters(params.getParameters(), params.getPublicKey())); + return new BCKyberPublicKey(params.getPublicKeyParameters()); } public KyberParameterSpec getParameterSpec() @@ -113,7 +110,7 @@ public String getFormat() return "PKCS#8"; } - KyberPrivateKeyParameters getKeyParams() + MLKEMPrivateKeyParameters getKeyParams() { return params; } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/BCKyberPublicKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/BCKyberPublicKey.java index 48f52af386..0a481cd213 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/BCKyberPublicKey.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/BCKyberPublicKey.java @@ -5,9 +5,8 @@ import java.io.ObjectOutputStream; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberPublicKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; -import org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory; import org.bouncycastle.pqc.jcajce.interfaces.KyberPublicKey; import org.bouncycastle.pqc.jcajce.provider.util.KeyUtil; import org.bouncycastle.pqc.jcajce.spec.KyberParameterSpec; @@ -19,12 +18,12 @@ public class BCKyberPublicKey { private static final long serialVersionUID = 1L; - private transient KyberPublicKeyParameters params; + private transient MLKEMPublicKeyParameters params; private transient String algorithm; private transient byte[] encoding; public BCKyberPublicKey( - KyberPublicKeyParameters params) + MLKEMPublicKeyParameters params) { init(params); } @@ -38,10 +37,10 @@ public BCKyberPublicKey(SubjectPublicKeyInfo keyInfo) private void init(SubjectPublicKeyInfo keyInfo) throws IOException { - init((KyberPublicKeyParameters)PublicKeyFactory.createKey(keyInfo)); + init((MLKEMPublicKeyParameters)PublicKeyFactory.createKey(keyInfo)); } - private void init(KyberPublicKeyParameters params) + private void init(MLKEMPublicKeyParameters params) { this.params = params; this.algorithm = Strings.toUpperCase(params.getParameters().getName()); @@ -103,7 +102,7 @@ public KyberParameterSpec getParameterSpec() return KyberParameterSpec.fromName(params.getParameters().getName()); } - KyberPublicKeyParameters getKeyParams() + MLKEMPublicKeyParameters getKeyParams() { return params; } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberCipherSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberCipherSpi.java index 0123737ec4..3712391a38 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberCipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberCipherSpi.java @@ -25,9 +25,9 @@ import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.jcajce.spec.KEMParameterSpec; import org.bouncycastle.jcajce.spec.KTSParameterSpec; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKEMExtractor; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKEMGenerator; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; import org.bouncycastle.pqc.jcajce.provider.util.WrapUtil; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Exceptions; @@ -37,13 +37,13 @@ class KyberCipherSpi extends CipherSpi { private final String algorithmName; - private KyberKEMGenerator kemGen; + private MLKEMGenerator kemGen; private KTSParameterSpec kemParameterSpec; private BCKyberPublicKey wrapKey; private BCKyberPrivateKey unwrapKey; private AlgorithmParameters engineParams; - private KyberParameters kyberParameters; + private MLKEMParameters kyberParameters; KyberCipherSpi(String algorithmName) { @@ -51,7 +51,7 @@ class KyberCipherSpi this.kyberParameters = null; } - KyberCipherSpi(KyberParameters kyberParameters) + KyberCipherSpi(MLKEMParameters kyberParameters) { this.kyberParameters = kyberParameters; this.algorithmName = Strings.toUpperCase(kyberParameters.getName()); @@ -154,7 +154,7 @@ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec paramSpec, if (key instanceof BCKyberPublicKey) { wrapKey = (BCKyberPublicKey)key; - kemGen = new KyberKEMGenerator(CryptoServicesRegistrar.getSecureRandom(random)); + kemGen = new MLKEMGenerator(CryptoServicesRegistrar.getSecureRandom(random)); } else { @@ -236,8 +236,8 @@ protected int engineDoFinal(byte[] bytes, int i, int i1, byte[] bytes1, int i2) } protected byte[] engineWrap( - Key key) - throws IllegalBlockSizeException, InvalidKeyException + Key key) + throws IllegalBlockSizeException, InvalidKeyException { byte[] encoded = key.getEncoded(); if (encoded == null) @@ -245,16 +245,15 @@ protected byte[] engineWrap( throw new InvalidKeyException("Cannot wrap key, null encoding."); } + SecretWithEncapsulation secEnc = null; try { - SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(wrapKey.getKeyParams()); + secEnc = kemGen.generateEncapsulated(wrapKey.getKeyParams()); Wrapper kWrap = WrapUtil.getKeyWrapper(kemParameterSpec, secEnc.getSecret()); byte[] encapsulation = secEnc.getEncapsulation(); - secEnc.destroy(); - byte[] keyToWrap = key.getEncoded(); byte[] rv = Arrays.concatenate(encapsulation, kWrap.wrap(keyToWrap, 0, keyToWrap.length)); @@ -267,9 +266,19 @@ protected byte[] engineWrap( { throw new IllegalBlockSizeException("unable to generate KTS secret: " + e.getMessage()); } - catch (DestroyFailedException e) + finally { - throw new IllegalBlockSizeException("unable to destroy interim values: " + e.getMessage()); + try + { + if (secEnc != null) + { + secEnc.destroy(); + } + } + catch (DestroyFailedException e) + { + throw new IllegalBlockSizeException("unable to destroy interim values: " + e.getMessage()); + } } } @@ -284,16 +293,15 @@ protected Key engineUnwrap( { throw new InvalidKeyException("only SECRET_KEY supported"); } + byte[] secret = null; try { - KyberKEMExtractor kemExt = new KyberKEMExtractor(unwrapKey.getKeyParams()); + MLKEMExtractor kemExt = new MLKEMExtractor(unwrapKey.getKeyParams()); - byte[] secret = kemExt.extractSecret(Arrays.copyOfRange(wrappedKey, 0, kemExt.getEncapsulationLength())); + secret = kemExt.extractSecret(Arrays.copyOfRange(wrappedKey, 0, kemExt.getEncapsulationLength())); Wrapper kWrap = WrapUtil.getKeyUnwrapper(kemParameterSpec, secret); - Arrays.clear(secret); - byte[] keyEncBytes = Arrays.copyOfRange(wrappedKey, kemExt.getEncapsulationLength(), wrappedKey.length); SecretKey rv = new SecretKeySpec(kWrap.unwrap(keyEncBytes, 0, keyEncBytes.length), wrappedKeyAlgorithm); @@ -308,6 +316,13 @@ protected Key engineUnwrap( { throw new InvalidKeyException("unable to extract KTS secret: " + e.getMessage()); } + finally + { + if (secret != null) + { + Arrays.clear(secret); + } + } } public static class Base @@ -325,7 +340,7 @@ public static class Kyber512 { public Kyber512() { - super(KyberParameters.kyber512); + super(MLKEMParameters.ml_kem_512); } } @@ -334,7 +349,7 @@ public static class Kyber768 { public Kyber768() { - super(KyberParameters.kyber768); + super(MLKEMParameters.ml_kem_768); } } @@ -343,34 +358,7 @@ public static class Kyber1024 { public Kyber1024() { - super(KyberParameters.kyber1024); - } - } - - public static class Kyber512_AES - extends KyberCipherSpi - { - public Kyber512_AES() - { - super(KyberParameters.kyber512_aes); - } - } - - public static class Kyber768_AES - extends KyberCipherSpi - { - public Kyber768_AES() - { - super(KyberParameters.kyber768_aes); - } - } - - public static class Kyber1024_AES - extends KyberCipherSpi - { - public Kyber1024_AES() - { - super(KyberParameters.kyber1024_aes); + super(MLKEMParameters.ml_kem_1024); } } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyFactorySpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyFactorySpi.java index 387ae576ed..c39d3cb0b6 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyFactorySpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyFactorySpi.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; -import java.security.KeyFactorySpi; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; @@ -14,12 +13,10 @@ import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters; import org.bouncycastle.pqc.jcajce.provider.util.BaseKeyFactorySpi; public class KyberKeyFactorySpi @@ -29,9 +26,9 @@ public class KyberKeyFactorySpi static { - keyOids.add(BCObjectIdentifiers.kyber512); - keyOids.add(BCObjectIdentifiers.kyber768); - keyOids.add(BCObjectIdentifiers.kyber1024); + keyOids.add(NISTObjectIdentifiers.id_alg_ml_kem_512); + keyOids.add(NISTObjectIdentifiers.id_alg_ml_kem_768); + keyOids.add(NISTObjectIdentifiers.id_alg_ml_kem_1024); keyOids.add(BCObjectIdentifiers.kyber512_aes); keyOids.add(BCObjectIdentifiers.kyber768_aes); keyOids.add(BCObjectIdentifiers.kyber1024_aes); @@ -102,7 +99,7 @@ public static class Kyber512 { public Kyber512() { - super(BCObjectIdentifiers.kyber512); + super(NISTObjectIdentifiers.id_alg_ml_kem_512); } } @@ -111,7 +108,7 @@ public static class Kyber768 { public Kyber768() { - super(BCObjectIdentifiers.kyber768); + super(NISTObjectIdentifiers.id_alg_ml_kem_768); } } @@ -120,7 +117,7 @@ public static class Kyber1024 { public Kyber1024() { - super(BCObjectIdentifiers.kyber1024); + super(NISTObjectIdentifiers.id_alg_ml_kem_1024); } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyGeneratorSpi.java index a0a38ea592..4e73a4cd9d 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyGeneratorSpi.java @@ -13,9 +13,9 @@ import org.bouncycastle.jcajce.SecretKeyWithEncapsulation; import org.bouncycastle.jcajce.spec.KEMExtractSpec; import org.bouncycastle.jcajce.spec.KEMGenerateSpec; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKEMExtractor; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKEMGenerator; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; @@ -25,14 +25,14 @@ public class KyberKeyGeneratorSpi private KEMGenerateSpec genSpec; private SecureRandom random; private KEMExtractSpec extSpec; - private KyberParameters kyberParameters; + private MLKEMParameters kyberParameters; public KyberKeyGeneratorSpi() { this(null); } - protected KyberKeyGeneratorSpi(KyberParameters kyberParameters) + protected KyberKeyGeneratorSpi(MLKEMParameters kyberParameters) { this.kyberParameters = kyberParameters; } @@ -88,11 +88,16 @@ protected SecretKey engineGenerateKey() if (genSpec != null) { BCKyberPublicKey pubKey = (BCKyberPublicKey)genSpec.getPublicKey(); - KyberKEMGenerator kemGen = new KyberKEMGenerator(random); + MLKEMGenerator kemGen = new MLKEMGenerator(random); SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(pubKey.getKeyParams()); - SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secEnc.getSecret(), genSpec.getKeyAlgorithmName()), secEnc.getEncapsulation()); + byte[] sharedSecret = secEnc.getSecret(); + byte[] secret = Arrays.copyOfRange(sharedSecret, 0, (genSpec.getKeySize() + 7) / 8); + + Arrays.clear(sharedSecret); + + SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, genSpec.getKeyAlgorithmName()), secEnc.getEncapsulation()); try { @@ -108,10 +113,13 @@ protected SecretKey engineGenerateKey() else { BCKyberPrivateKey privKey = (BCKyberPrivateKey)extSpec.getPrivateKey(); - KyberKEMExtractor kemExt = new KyberKEMExtractor(privKey.getKeyParams()); + MLKEMExtractor kemExt = new MLKEMExtractor(privKey.getKeyParams()); byte[] encapsulation = extSpec.getEncapsulation(); - byte[] secret = kemExt.extractSecret(encapsulation); + byte[] sharedSecret = kemExt.extractSecret(encapsulation); + byte[] secret = Arrays.copyOfRange(sharedSecret, 0, (extSpec.getKeySize() + 7) / 8); + + Arrays.clear(sharedSecret); SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, extSpec.getKeyAlgorithmName()), encapsulation); @@ -126,7 +134,7 @@ public static class Kyber512 { public Kyber512() { - super(KyberParameters.kyber512); + super(MLKEMParameters.ml_kem_512); } } @@ -135,7 +143,7 @@ public static class Kyber768 { public Kyber768() { - super(KyberParameters.kyber768); + super(MLKEMParameters.ml_kem_768); } } @@ -144,34 +152,7 @@ public static class Kyber1024 { public Kyber1024() { - super(KyberParameters.kyber1024); - } - } - - public static class Kyber512_AES - extends KyberKeyGeneratorSpi - { - public Kyber512_AES() - { - super(KyberParameters.kyber512_aes); - } - } - - public static class Kyber768_AES - extends KyberKeyGeneratorSpi - { - public Kyber768_AES() - { - super(KyberParameters.kyber768_aes); - } - } - - public static class Kyber1024_AES - extends KyberKeyGeneratorSpi - { - public Kyber1024_AES() - { - super(KyberParameters.kyber1024_aes); + super(MLKEMParameters.ml_kem_1024); } } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyPairGeneratorSpi.java index ed089196dd..0c72535fd7 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyPairGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyPairGeneratorSpi.java @@ -9,14 +9,11 @@ import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.CryptoServicesRegistrar; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKeyGenerationParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKeyPairGenerator; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberPrivateKeyParameters; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberPublicKeyParameters; -import org.bouncycastle.pqc.crypto.falcon.FalconKeyGenerationParameters; -import org.bouncycastle.pqc.crypto.falcon.FalconParameters; -import org.bouncycastle.pqc.jcajce.provider.falcon.FalconKeyPairGeneratorSpi; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyPairGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; import org.bouncycastle.pqc.jcajce.provider.util.SpecUtil; import org.bouncycastle.pqc.jcajce.spec.KyberParameterSpec; import org.bouncycastle.util.Strings; @@ -28,20 +25,17 @@ public class KyberKeyPairGeneratorSpi static { - parameters.put(KyberParameterSpec.kyber512.getName(), KyberParameters.kyber512); - parameters.put(KyberParameterSpec.kyber768.getName(), KyberParameters.kyber768); - parameters.put(KyberParameterSpec.kyber1024.getName(), KyberParameters.kyber1024); - parameters.put(KyberParameterSpec.kyber512_aes.getName(), KyberParameters.kyber512_aes); - parameters.put(KyberParameterSpec.kyber768_aes.getName(), KyberParameters.kyber768_aes); - parameters.put(KyberParameterSpec.kyber1024_aes.getName(), KyberParameters.kyber1024_aes); + parameters.put(KyberParameterSpec.kyber512.getName(), MLKEMParameters.ml_kem_512); + parameters.put(KyberParameterSpec.kyber768.getName(), MLKEMParameters.ml_kem_768); + parameters.put(KyberParameterSpec.kyber1024.getName(), MLKEMParameters.ml_kem_1024); } - KyberKeyGenerationParameters param; - KyberKeyPairGenerator engine = new KyberKeyPairGenerator(); + MLKEMKeyGenerationParameters param; + MLKEMKeyPairGenerator engine = new MLKEMKeyPairGenerator(); SecureRandom random = CryptoServicesRegistrar.getSecureRandom(); boolean initialised = false; - private KyberParameters kyberParameters; + private MLKEMParameters kyberParameters; public KyberKeyPairGeneratorSpi() { @@ -49,7 +43,7 @@ public KyberKeyPairGeneratorSpi() this.kyberParameters = null; } - protected KyberKeyPairGeneratorSpi(KyberParameters kyberParameters) + protected KyberKeyPairGeneratorSpi(MLKEMParameters kyberParameters) { super(Strings.toUpperCase(kyberParameters.getName())); this.kyberParameters = kyberParameters; @@ -71,9 +65,9 @@ public void initialize( if (name != null && parameters.containsKey(name)) { - KyberParameters kyberParams = (KyberParameters)parameters.get(name); + MLKEMParameters kyberParams = (MLKEMParameters)parameters.get(name); - param = new KyberKeyGenerationParameters(random, kyberParams); + param = new MLKEMKeyGenerationParameters(random, kyberParams); if (kyberParameters != null && !kyberParams.getName().equals(kyberParameters.getName())) { @@ -108,11 +102,11 @@ public KeyPair generateKeyPair() { if (kyberParameters != null) { - param = new KyberKeyGenerationParameters(random, kyberParameters); + param = new MLKEMKeyGenerationParameters(random, kyberParameters); } else { - param = new KyberKeyGenerationParameters(random, KyberParameters.kyber1024); + param = new MLKEMKeyGenerationParameters(random, MLKEMParameters.ml_kem_1024); } engine.init(param); @@ -120,8 +114,8 @@ public KeyPair generateKeyPair() } AsymmetricCipherKeyPair pair = engine.generateKeyPair(); - KyberPublicKeyParameters pub = (KyberPublicKeyParameters)pair.getPublic(); - KyberPrivateKeyParameters priv = (KyberPrivateKeyParameters)pair.getPrivate(); + MLKEMPublicKeyParameters pub = (MLKEMPublicKeyParameters)pair.getPublic(); + MLKEMPrivateKeyParameters priv = (MLKEMPrivateKeyParameters)pair.getPrivate(); return new KeyPair(new BCKyberPublicKey(pub), new BCKyberPrivateKey(priv)); } @@ -131,7 +125,7 @@ public static class Kyber512 { public Kyber512() { - super(KyberParameters.kyber512); + super(MLKEMParameters.ml_kem_512); } } @@ -140,7 +134,7 @@ public static class Kyber768 { public Kyber768() { - super(KyberParameters.kyber768); + super(MLKEMParameters.ml_kem_768); } } @@ -149,34 +143,7 @@ public static class Kyber1024 { public Kyber1024() { - super(KyberParameters.kyber1024); - } - } - - public static class Kyber512_AES - extends KyberKeyPairGeneratorSpi - { - public Kyber512_AES() - { - super(KyberParameters.kyber512_aes); - } - } - - public static class Kyber768_AES - extends KyberKeyPairGeneratorSpi - { - public Kyber768_AES() - { - super(KyberParameters.kyber768_aes); - } - } - - public static class Kyber1024_AES - extends KyberKeyPairGeneratorSpi - { - public Kyber1024_AES() - { - super(KyberParameters.kyber1024_aes); + super(MLKEMParameters.ml_kem_1024); } } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/lms/DigestUtil.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/lms/DigestUtil.java index 299b0c3dbf..039381dba4 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/lms/DigestUtil.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/lms/DigestUtil.java @@ -1,16 +1,13 @@ package org.bouncycastle.pqc.jcajce.provider.lms; -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Xof; -import org.bouncycastle.pqc.jcajce.spec.XMSSParameterSpec; class DigestUtil { public static byte[] getDigestResult(Digest digest) { - byte[] hash = new byte[DigestUtil.getDigestSize(digest)]; + byte[] hash = new byte[digest.getDigestSize()]; if (digest instanceof Xof) { @@ -23,36 +20,4 @@ public static byte[] getDigestResult(Digest digest) return hash; } - - public static int getDigestSize(Digest digest) - { - if (digest instanceof Xof) - { - return digest.getDigestSize() * 2; - } - - return digest.getDigestSize(); - } - - public static String getXMSSDigestName(ASN1ObjectIdentifier treeDigest) - { - if (treeDigest.equals(NISTObjectIdentifiers.id_sha256)) - { - return XMSSParameterSpec.SHA256; - } - if (treeDigest.equals(NISTObjectIdentifiers.id_sha512)) - { - return XMSSParameterSpec.SHA512; - } - if (treeDigest.equals(NISTObjectIdentifiers.id_shake128)) - { - return XMSSParameterSpec.SHAKE128; - } - if (treeDigest.equals(NISTObjectIdentifiers.id_shake256)) - { - return XMSSParameterSpec.SHAKE256; - } - - throw new IllegalArgumentException("unrecognized digest OID: " + treeDigest); - } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/lms/LMSSignatureSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/lms/LMSSignatureSpi.java index 19f5edb1a0..4bef69b376 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/lms/LMSSignatureSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/lms/LMSSignatureSpi.java @@ -50,7 +50,7 @@ protected void engineInitVerify(PublicKey publicKey) } else { - throw new InvalidKeyException("unknown public key passed to XMSS"); + throw new InvalidKeyException("unknown public key passed to LMS"); } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/Utils.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/Utils.java index 4f1a59f6bb..e4481abff2 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/Utils.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/Utils.java @@ -1,10 +1,10 @@ package org.bouncycastle.pqc.jcajce.provider.mceliece; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.util.DigestFactory; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; class Utils { diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUCipherSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUCipherSpi.java index 57e4f37af2..8eb47b868c 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUCipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUCipherSpi.java @@ -25,8 +25,8 @@ import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.jcajce.spec.KEMParameterSpec; import org.bouncycastle.jcajce.spec.KTSParameterSpec; -import org.bouncycastle.pqc.crypto.ntru.NTRUKEMExtractor; import org.bouncycastle.pqc.crypto.ntru.NTRUKEMGenerator; +import org.bouncycastle.pqc.crypto.ntru.NTRUKEMExtractor; import org.bouncycastle.pqc.jcajce.provider.util.WrapUtil; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Exceptions; @@ -227,16 +227,15 @@ protected byte[] engineWrap( throw new InvalidKeyException("Cannot wrap key, null encoding."); } + SecretWithEncapsulation secEnc = null; try { - SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(wrapKey.getKeyParams()); + secEnc = kemGen.generateEncapsulated(wrapKey.getKeyParams()); Wrapper kWrap = WrapUtil.getKeyWrapper(kemParameterSpec, secEnc.getSecret()); byte[] encapsulation = secEnc.getEncapsulation(); - secEnc.destroy(); - byte[] keyToWrap = key.getEncoded(); byte[] rv = Arrays.concatenate(encapsulation, kWrap.wrap(keyToWrap, 0, keyToWrap.length)); @@ -249,9 +248,19 @@ protected byte[] engineWrap( { throw new IllegalBlockSizeException("unable to generate KTS secret: " + e.getMessage()); } - catch (DestroyFailedException e) + finally { - throw new IllegalBlockSizeException("unable to destroy interim values: " + e.getMessage()); + try + { + if (secEnc != null) + { + secEnc.destroy(); + } + } + catch (DestroyFailedException e) + { + throw new IllegalBlockSizeException("unable to destroy interim values: " + e.getMessage()); + } } } @@ -266,16 +275,15 @@ protected Key engineUnwrap( { throw new InvalidKeyException("only SECRET_KEY supported"); } + byte[] secret = null; try { NTRUKEMExtractor kemExt = new NTRUKEMExtractor(unwrapKey.getKeyParams()); - byte[] secret = kemExt.extractSecret(Arrays.copyOfRange(wrappedKey, 0, kemExt.getEncapsulationLength())); + secret = kemExt.extractSecret(Arrays.copyOfRange(wrappedKey, 0, kemExt.getEncapsulationLength())); Wrapper kWrap = WrapUtil.getKeyUnwrapper(kemParameterSpec, secret); - Arrays.clear(secret); - byte[] keyEncBytes = Arrays.copyOfRange(wrappedKey, kemExt.getEncapsulationLength(), wrappedKey.length); SecretKey rv = new SecretKeySpec(kWrap.unwrap(keyEncBytes, 0, keyEncBytes.length), wrappedKeyAlgorithm); @@ -290,6 +298,13 @@ protected Key engineUnwrap( { throw new InvalidKeyException("unable to extract KTS secret: " + e.getMessage()); } + finally + { + if (secret != null) + { + Arrays.clear(secret); + } + } } public static class Base diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKeyGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKeyGeneratorSpi.java index 8e3ede79eb..dec603d080 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKeyGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKeyGeneratorSpi.java @@ -63,7 +63,12 @@ protected SecretKey engineGenerateKey() SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(pubKey.getKeyParams()); - SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secEnc.getSecret(), genSpec.getKeyAlgorithmName()), secEnc.getEncapsulation()); + byte[] sharedSecret = secEnc.getSecret(); + byte[] secret = Arrays.copyOfRange(sharedSecret, 0, (genSpec.getKeySize() + 7) / 8); + + Arrays.clear(sharedSecret); + + SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, genSpec.getKeyAlgorithmName()), secEnc.getEncapsulation()); try { @@ -82,7 +87,10 @@ protected SecretKey engineGenerateKey() NTRUKEMExtractor kemExt = new NTRUKEMExtractor(privKey.getKeyParams()); byte[] encapsulation = extSpec.getEncapsulation(); - byte[] secret = kemExt.extractSecret(encapsulation); + byte[] sharedSecret = kemExt.extractSecret(encapsulation); + byte[] secret = Arrays.copyOfRange(sharedSecret, 0, (extSpec.getKeySize() + 7) / 8); + + Arrays.clear(sharedSecret); SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, extSpec.getKeyAlgorithmName()), encapsulation); diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKeyPairGeneratorSpi.java index 944938e27d..c7ef183c18 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKeyPairGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKeyPairGeneratorSpi.java @@ -28,7 +28,9 @@ public class NTRUKeyPairGeneratorSpi parameters.put(NTRUParameterSpec.ntruhps2048509.getName(), NTRUParameters.ntruhps2048509); parameters.put(NTRUParameterSpec.ntruhps2048677.getName(), NTRUParameters.ntruhps2048677); parameters.put(NTRUParameterSpec.ntruhps4096821.getName(), NTRUParameters.ntruhps4096821); + parameters.put(NTRUParameterSpec.ntruhps40961229.getName(), NTRUParameters.ntruhps40961229); parameters.put(NTRUParameterSpec.ntruhrss701.getName(), NTRUParameters.ntruhrss701); + parameters.put(NTRUParameterSpec.ntruhrss1373.getName(), NTRUParameters.ntruhrss1373); } NTRUKeyGenerationParameters param; diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruprime/NTRULPRimeCipherSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruprime/NTRULPRimeCipherSpi.java index 03e1c9ac6a..5b37e6ffe0 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruprime/NTRULPRimeCipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruprime/NTRULPRimeCipherSpi.java @@ -25,6 +25,7 @@ import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.jcajce.spec.KEMParameterSpec; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeKEMExtractor; import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeKEMGenerator; import org.bouncycastle.pqc.jcajce.provider.util.WrapUtil; @@ -36,7 +37,7 @@ class NTRULPRimeCipherSpi { private final String algorithmName; private NTRULPRimeKEMGenerator kemGen; - private KEMParameterSpec kemParameterSpec; + private KTSParameterSpec kemParameterSpec; private BCNTRULPRimePublicKey wrapKey; private BCNTRULPRimePrivateKey unwrapKey; private AlgorithmParameters engineParams; @@ -127,16 +128,16 @@ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec paramSpec, if (paramSpec == null) { // TODO: default should probably use shake. - kemParameterSpec = new KEMParameterSpec("AES-KWP"); + kemParameterSpec = new KTSParameterSpec.Builder("AES-KWP", 256).build(); } else { - if (!(paramSpec instanceof KEMParameterSpec)) + if (!(paramSpec instanceof KTSParameterSpec)) { throw new InvalidAlgorithmParameterException(algorithmName + " can only accept KTSParameterSpec"); } - kemParameterSpec = (KEMParameterSpec)paramSpec; + kemParameterSpec = (KTSParameterSpec)paramSpec; } if (opmode == Cipher.WRAP_MODE) @@ -232,7 +233,7 @@ protected byte[] engineWrap( Wrapper kWrap = WrapUtil.getWrapper(kemParameterSpec.getKeyAlgorithmName()); - KeyParameter keyParameter = new KeyParameter(secEnc.getSecret()); + KeyParameter keyParameter = new KeyParameter(secEnc.getSecret(), 0, (kemParameterSpec.getKeySize() + 7) / 8); kWrap.init(true, keyParameter); @@ -277,7 +278,7 @@ protected Key engineUnwrap( Wrapper kWrap = WrapUtil.getWrapper(kemParameterSpec.getKeyAlgorithmName()); - KeyParameter keyParameter = new KeyParameter(secret); + KeyParameter keyParameter = new KeyParameter(secret, 0, (kemParameterSpec.getKeySize() + 7) / 8); Arrays.clear(secret); diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeCipherSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeCipherSpi.java index 7dd7c34e58..af92dfd3a6 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeCipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeCipherSpi.java @@ -24,8 +24,7 @@ import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.jcajce.spec.KEMParameterSpec; -import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeKEMGenerator; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeKEMExtractor; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeKEMGenerator; import org.bouncycastle.pqc.jcajce.provider.util.WrapUtil; @@ -37,7 +36,7 @@ class SNTRUPrimeCipherSpi { private final String algorithmName; private SNTRUPrimeKEMGenerator kemGen; - private KEMParameterSpec kemParameterSpec; + private KTSParameterSpec kemParameterSpec; private BCSNTRUPrimePublicKey wrapKey; private BCSNTRUPrimePrivateKey unwrapKey; private AlgorithmParameters engineParams; @@ -128,16 +127,16 @@ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec paramSpec, if (paramSpec == null) { // TODO: default should probably use shake. - kemParameterSpec = new KEMParameterSpec("AES-KWP"); + kemParameterSpec = new KTSParameterSpec.Builder("AES-KWP", 256).build(); } else { - if (!(paramSpec instanceof KEMParameterSpec)) + if (!(paramSpec instanceof KTSParameterSpec)) { throw new InvalidAlgorithmParameterException(algorithmName + " can only accept KTSParameterSpec"); } - kemParameterSpec = (KEMParameterSpec)paramSpec; + kemParameterSpec = (KTSParameterSpec)paramSpec; } if (opmode == Cipher.WRAP_MODE) @@ -179,7 +178,7 @@ protected void engineInit(int opmode, Key key, AlgorithmParameters algorithmPara { try { - paramSpec = algorithmParameters.getParameterSpec(KEMParameterSpec.class); + paramSpec = algorithmParameters.getParameterSpec(KTSParameterSpec.class); } catch (Exception e) { @@ -233,7 +232,7 @@ protected byte[] engineWrap( Wrapper kWrap = WrapUtil.getWrapper(kemParameterSpec.getKeyAlgorithmName()); - KeyParameter keyParameter = new KeyParameter(secEnc.getSecret()); + KeyParameter keyParameter = new KeyParameter(secEnc.getSecret(), 0, (kemParameterSpec.getKeySize() + 7) / 8); kWrap.init(true, keyParameter); @@ -278,7 +277,7 @@ protected Key engineUnwrap( Wrapper kWrap = WrapUtil.getWrapper(kemParameterSpec.getKeyAlgorithmName()); - KeyParameter keyParameter = new KeyParameter(secret); + KeyParameter keyParameter = new KeyParameter(secret, 0, (kemParameterSpec.getKeySize() + 7) / 8); Arrays.clear(secret); @@ -293,7 +292,7 @@ protected Key engineUnwrap( return rv; } catch (IllegalArgumentException e) - { e.printStackTrace(); + { throw new NoSuchAlgorithmException("unable to extract KTS secret: " + e.getMessage()); } catch (InvalidCipherTextException e) diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/sphincsplus/BCSPHINCSPlusPublicKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/sphincsplus/BCSPHINCSPlusPublicKey.java index 86e95e42f7..0e7d593d0e 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/sphincsplus/BCSPHINCSPlusPublicKey.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/sphincsplus/BCSPHINCSPlusPublicKey.java @@ -12,6 +12,7 @@ import org.bouncycastle.pqc.jcajce.interfaces.SPHINCSPlusPublicKey; import org.bouncycastle.pqc.jcajce.spec.SPHINCSPlusParameterSpec; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; public class BCSPHINCSPlusPublicKey implements SPHINCSPlusPublicKey @@ -67,11 +68,11 @@ public int hashCode() } /** - * @return name of the algorithm - "SPHINCS+" + * @return name of the algorithm - "SPHINCS+" followed by the parameter type. */ public final String getAlgorithm() { - return "SPHINCS+"; + return "SPHINCS+" + "-" + Strings.toUpperCase(params.getParameters().getName()); } public byte[] getEncoded() diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/sphincsplus/SPHINCSPlusKeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/sphincsplus/SPHINCSPlusKeyPairGeneratorSpi.java index f0376b03b5..286e6b45cd 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/sphincsplus/SPHINCSPlusKeyPairGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/sphincsplus/SPHINCSPlusKeyPairGeneratorSpi.java @@ -25,6 +25,13 @@ public class SPHINCSPlusKeyPairGeneratorSpi static { + parameters.put(SPHINCSPlusParameterSpec.sha2_128f_robust.getName(), SPHINCSPlusParameters.sha2_128f_robust); + parameters.put(SPHINCSPlusParameterSpec.sha2_128s_robust.getName(), SPHINCSPlusParameters.sha2_128s_robust); + parameters.put(SPHINCSPlusParameterSpec.sha2_192f_robust.getName(), SPHINCSPlusParameters.sha2_192f_robust); + parameters.put(SPHINCSPlusParameterSpec.sha2_192s_robust.getName(), SPHINCSPlusParameters.sha2_192s_robust); + parameters.put(SPHINCSPlusParameterSpec.sha2_256f_robust.getName(), SPHINCSPlusParameters.sha2_256f_robust); + parameters.put(SPHINCSPlusParameterSpec.sha2_256s_robust.getName(), SPHINCSPlusParameters.sha2_256s_robust); + parameters.put(SPHINCSPlusParameterSpec.sha2_128f.getName(), SPHINCSPlusParameters.sha2_128f); parameters.put(SPHINCSPlusParameterSpec.sha2_128s.getName(), SPHINCSPlusParameters.sha2_128s); parameters.put(SPHINCSPlusParameterSpec.sha2_192f.getName(), SPHINCSPlusParameters.sha2_192f); @@ -32,12 +39,12 @@ public class SPHINCSPlusKeyPairGeneratorSpi parameters.put(SPHINCSPlusParameterSpec.sha2_256f.getName(), SPHINCSPlusParameters.sha2_256f); parameters.put(SPHINCSPlusParameterSpec.sha2_256s.getName(), SPHINCSPlusParameters.sha2_256s); - parameters.put(SPHINCSPlusParameterSpec.sha2_128f_simple.getName(), SPHINCSPlusParameters.sha2_128f_simple); - parameters.put(SPHINCSPlusParameterSpec.sha2_128s_simple.getName(), SPHINCSPlusParameters.sha2_128s_simple); - parameters.put(SPHINCSPlusParameterSpec.sha2_192f_simple.getName(), SPHINCSPlusParameters.sha2_192f_simple); - parameters.put(SPHINCSPlusParameterSpec.sha2_192s_simple.getName(), SPHINCSPlusParameters.sha2_192s_simple); - parameters.put(SPHINCSPlusParameterSpec.sha2_256f_simple.getName(), SPHINCSPlusParameters.sha2_256f_simple); - parameters.put(SPHINCSPlusParameterSpec.sha2_256s_simple.getName(), SPHINCSPlusParameters.sha2_256s_simple); + parameters.put(SPHINCSPlusParameterSpec.shake_128f_robust.getName(), SPHINCSPlusParameters.shake_128f_robust); + parameters.put(SPHINCSPlusParameterSpec.shake_128s_robust.getName(), SPHINCSPlusParameters.shake_128s_robust); + parameters.put(SPHINCSPlusParameterSpec.shake_192f_robust.getName(), SPHINCSPlusParameters.shake_192f_robust); + parameters.put(SPHINCSPlusParameterSpec.shake_192s_robust.getName(), SPHINCSPlusParameters.shake_192s_robust); + parameters.put(SPHINCSPlusParameterSpec.shake_256f_robust.getName(), SPHINCSPlusParameters.shake_256f_robust); + parameters.put(SPHINCSPlusParameterSpec.shake_256s_robust.getName(), SPHINCSPlusParameters.shake_256s_robust); parameters.put(SPHINCSPlusParameterSpec.shake_128f.getName(), SPHINCSPlusParameters.shake_128f); parameters.put(SPHINCSPlusParameterSpec.shake_128s.getName(), SPHINCSPlusParameters.shake_128s); @@ -46,13 +53,6 @@ public class SPHINCSPlusKeyPairGeneratorSpi parameters.put(SPHINCSPlusParameterSpec.shake_256f.getName(), SPHINCSPlusParameters.shake_256f); parameters.put(SPHINCSPlusParameterSpec.shake_256s.getName(), SPHINCSPlusParameters.shake_256s); - parameters.put(SPHINCSPlusParameterSpec.shake_128f_simple.getName(), SPHINCSPlusParameters.shake_128f_simple); - parameters.put(SPHINCSPlusParameterSpec.shake_128s_simple.getName(), SPHINCSPlusParameters.shake_128s_simple); - parameters.put(SPHINCSPlusParameterSpec.shake_192f_simple.getName(), SPHINCSPlusParameters.shake_192f_simple); - parameters.put(SPHINCSPlusParameterSpec.shake_192s_simple.getName(), SPHINCSPlusParameters.shake_192s_simple); - parameters.put(SPHINCSPlusParameterSpec.shake_256f_simple.getName(), SPHINCSPlusParameters.shake_256f_simple); - parameters.put(SPHINCSPlusParameterSpec.shake_256s_simple.getName(), SPHINCSPlusParameters.shake_256s_simple); - parameters.put(SPHINCSPlusParameterSpec.haraka_128f.getName(), SPHINCSPlusParameters.haraka_128f); parameters.put(SPHINCSPlusParameterSpec.haraka_128s.getName(), SPHINCSPlusParameters.haraka_128s); parameters.put(SPHINCSPlusParameterSpec.haraka_192f.getName(), SPHINCSPlusParameters.haraka_192f); @@ -79,6 +79,16 @@ public SPHINCSPlusKeyPairGeneratorSpi() super("SPHINCS+"); } + protected SPHINCSPlusKeyPairGeneratorSpi(SPHINCSPlusParameterSpec paramSpec) + { + super("SPHINCS+" + "-" + Strings.toUpperCase(paramSpec.getName())); + + param = new SPHINCSPlusKeyGenerationParameters(random, (SPHINCSPlusParameters)parameters.get(paramSpec.getName())); + + engine.init(param); + initialised = true; + } + public void initialize( int strength, SecureRandom random) @@ -135,4 +145,112 @@ private static String getNameFromParams(AlgorithmParameterSpec paramSpec) return Strings.toLowerCase(SpecUtil.getNameFrom(paramSpec)); } } + + public static class Sha2_128s + extends SPHINCSPlusKeyPairGeneratorSpi + { + public Sha2_128s() + { + super(SPHINCSPlusParameterSpec.sha2_128s); + } + } + + public static class Sha2_128f + extends SPHINCSPlusKeyPairGeneratorSpi + { + public Sha2_128f() + { + super(SPHINCSPlusParameterSpec.sha2_128f); + } + } + + public static class Sha2_192s + extends SPHINCSPlusKeyPairGeneratorSpi + { + public Sha2_192s() + { + super(SPHINCSPlusParameterSpec.sha2_192s); + } + } + + public static class Sha2_192f + extends SPHINCSPlusKeyPairGeneratorSpi + { + public Sha2_192f() + { + super(SPHINCSPlusParameterSpec.sha2_192f); + } + } + + public static class Sha2_256s + extends SPHINCSPlusKeyPairGeneratorSpi + { + public Sha2_256s() + { + super(SPHINCSPlusParameterSpec.sha2_256s); + } + } + + public static class Sha2_256f + extends SPHINCSPlusKeyPairGeneratorSpi + { + public Sha2_256f() + { + super(SPHINCSPlusParameterSpec.sha2_256f); + } + } + + public static class Shake_128s + extends SPHINCSPlusKeyPairGeneratorSpi + { + public Shake_128s() + { + super(SPHINCSPlusParameterSpec.shake_128s); + } + } + + public static class Shake_128f + extends SPHINCSPlusKeyPairGeneratorSpi + { + public Shake_128f() + { + super(SPHINCSPlusParameterSpec.shake_128f); + } + } + + public static class Shake_192s + extends SPHINCSPlusKeyPairGeneratorSpi + { + public Shake_192s() + { + super(SPHINCSPlusParameterSpec.shake_192s); + } + } + + public static class Shake_192f + extends SPHINCSPlusKeyPairGeneratorSpi + { + public Shake_192f() + { + super(SPHINCSPlusParameterSpec.shake_192f); + } + } + + public static class Shake_256s + extends SPHINCSPlusKeyPairGeneratorSpi + { + public Shake_256s() + { + super(SPHINCSPlusParameterSpec.shake_256s); + } + } + + public static class Shake_256f + extends SPHINCSPlusKeyPairGeneratorSpi + { + public Shake_256f() + { + super(SPHINCSPlusParameterSpec.shake_256f); + } + } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/util/BaseKeyFactorySpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/util/BaseKeyFactorySpi.java index 5c3871f144..52433bc59b 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/util/BaseKeyFactorySpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/util/BaseKeyFactorySpi.java @@ -49,6 +49,10 @@ public PrivateKey engineGeneratePrivate(KeySpec keySpec) return generatePrivate(keyInfo); } + catch (InvalidKeySpecException e) + { + throw e; + } catch (Exception e) { throw new InvalidKeySpecException(e.toString()); @@ -76,6 +80,10 @@ public PublicKey engineGeneratePublic(KeySpec keySpec) return generatePublic(keyInfo); } + catch (InvalidKeySpecException e) + { + throw e; + } catch (Exception e) { throw new InvalidKeySpecException(e.toString()); diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/util/WrapUtil.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/util/WrapUtil.java index ddf4540fa8..cce10a7b91 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/util/WrapUtil.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/util/WrapUtil.java @@ -36,7 +36,7 @@ public static Wrapper getKeyWrapper(KTSParameterSpec ktsParameterSpec, byte[] se AlgorithmIdentifier kdfAlgorithm = ktsParameterSpec.getKdfAlgorithm(); if (kdfAlgorithm == null) { - kWrap.init(true, new KeyParameter(secret)); + kWrap.init(true, new KeyParameter(Arrays.copyOfRange(secret, 0, (ktsParameterSpec.getKeySize() + 7) / 8))); } else { @@ -54,7 +54,7 @@ public static Wrapper getKeyUnwrapper(KTSParameterSpec ktsParameterSpec, byte[] AlgorithmIdentifier kdfAlgorithm = ktsParameterSpec.getKdfAlgorithm(); if (kdfAlgorithm == null) { - kWrap.init(false, new KeyParameter(secret)); + kWrap.init(false, new KeyParameter(secret, 0, (ktsParameterSpec.getKeySize()+ 7) / 8)); } else { @@ -142,8 +142,6 @@ else if (NISTObjectIdentifiers.id_shake256.equals(kdfAlgorithm.getAlgorithm())) throw new InvalidKeyException("Unrecognized KDF: " + kdfAlgorithm.getAlgorithm()); } - Arrays.fill(secret, (byte)0); - return keyBytes; } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/xmss/DigestUtil.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/xmss/DigestUtil.java index eb43a28e59..0f0bbcdd0f 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/xmss/DigestUtil.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/xmss/DigestUtil.java @@ -3,7 +3,6 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Xof; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.digests.SHAKEDigest; @@ -57,30 +56,13 @@ static ASN1ObjectIdentifier getDigestOID(String digest) public static byte[] getDigestResult(Digest digest) { - byte[] hash = new byte[DigestUtil.getDigestSize(digest)]; + byte[] hash = new byte[digest.getDigestSize()]; - if (digest instanceof Xof) - { - ((Xof)digest).doFinal(hash, 0, hash.length); - } - else - { - digest.doFinal(hash, 0); - } + digest.doFinal(hash, 0); return hash; } - public static int getDigestSize(Digest digest) - { - if (digest instanceof Xof) - { - return digest.getDigestSize() * 2; - } - - return digest.getDigestSize(); - } - public static String getXMSSDigestName(ASN1ObjectIdentifier treeDigest) { if (treeDigest.equals(NISTObjectIdentifiers.id_sha256)) @@ -102,4 +84,51 @@ public static String getXMSSDigestName(ASN1ObjectIdentifier treeDigest) throw new IllegalArgumentException("unrecognized digest OID: " + treeDigest); } + + static class DoubleDigest + implements Digest + { + private SHAKEDigest digest; + + DoubleDigest(SHAKEDigest digest) + { + this.digest = digest; + } + + @Override + public String getAlgorithmName() + { + return digest.getAlgorithmName() + "/" + (digest.getDigestSize() * 2 * 8); + } + + @Override + public int getDigestSize() + { + return digest.getDigestSize() * 2; + } + + @Override + public void update(byte in) + { + digest.update(in); + } + + @Override + public void update(byte[] in, int inOff, int len) + { + digest.update(in, inOff, len); + } + + @Override + public int doFinal(byte[] out, int outOff) + { + return digest.doFinal(out, outOff, this.getDigestSize()); + } + + @Override + public void reset() + { + digest.reset(); + } + } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/xmss/XMSSMTSignatureSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/xmss/XMSSMTSignatureSpi.java index aeda0fcb2a..25fc87136d 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/xmss/XMSSMTSignatureSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/xmss/XMSSMTSignatureSpi.java @@ -232,6 +232,15 @@ public withShake128andPrehash() } } + static public class withShake128_512andPrehash + extends XMSSMTSignatureSpi + { + public withShake128_512andPrehash() + { + super("SHAKE128(512)withXMSSMT-SHAKE128", new DigestUtil.DoubleDigest(new SHAKEDigest(128)), new XMSSMTSigner()); + } + } + static public class withSha512andPrehash extends XMSSMTSignatureSpi { @@ -249,4 +258,13 @@ public withShake256andPrehash() super("SHAKE256withXMSSMT-SHAKE256", new SHAKEDigest(256), new XMSSMTSigner()); } } + + static public class withShake256_1024andPrehash + extends XMSSMTSignatureSpi + { + public withShake256_1024andPrehash() + { + super("SHAKE256(1024)withXMSSMT-SHAKE256", new DigestUtil.DoubleDigest(new SHAKEDigest(256)), new XMSSMTSigner()); + } + } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/xmss/XMSSSignatureSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/xmss/XMSSSignatureSpi.java index 7b7628cf27..670223ba3d 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/xmss/XMSSSignatureSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/xmss/XMSSSignatureSpi.java @@ -227,7 +227,16 @@ static public class withShake128andPrehash { public withShake128andPrehash() { - super("SHAKE128withXMSSMT-SHAKE128", new SHAKEDigest(128), new XMSSSigner()); + super("SHAKE128withXMSS-SHAKE128", new SHAKEDigest(128), new XMSSSigner()); + } + } + + static public class withShake128_512andPrehash + extends XMSSSignatureSpi + { + public withShake128_512andPrehash() + { + super("SHAKE128(512)withXMSS-SHAKE128", new DigestUtil.DoubleDigest(new SHAKEDigest(128)), new XMSSSigner()); } } @@ -248,4 +257,13 @@ public withShake256andPrehash() super("SHAKE256withXMSS-SHAKE256", new SHAKEDigest(256), new XMSSSigner()); } } + + static public class withShake256_1024andPrehash + extends XMSSSignatureSpi + { + public withShake256_1024andPrehash() + { + super("SHAKE256(1024)withXMSS-SHAKE256", new DigestUtil.DoubleDigest(new SHAKEDigest(256)), new XMSSSigner()); + } + } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/DilithiumParameterSpec.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/DilithiumParameterSpec.java index f3189674ef..2b1aeb05f6 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/DilithiumParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/DilithiumParameterSpec.java @@ -14,10 +14,6 @@ public class DilithiumParameterSpec public static final DilithiumParameterSpec dilithium3 = new DilithiumParameterSpec(DilithiumParameters.dilithium3); public static final DilithiumParameterSpec dilithium5 = new DilithiumParameterSpec(DilithiumParameters.dilithium5); - public static final DilithiumParameterSpec dilithium2_aes = new DilithiumParameterSpec(DilithiumParameters.dilithium2_aes); - public static final DilithiumParameterSpec dilithium3_aes = new DilithiumParameterSpec(DilithiumParameters.dilithium3_aes); - public static final DilithiumParameterSpec dilithium5_aes = new DilithiumParameterSpec(DilithiumParameters.dilithium5_aes); - private static Map parameters = new HashMap(); static @@ -25,9 +21,6 @@ public class DilithiumParameterSpec parameters.put("dilithium2", dilithium2); parameters.put("dilithium3", dilithium3); parameters.put("dilithium5", dilithium5); - parameters.put("dilithium2-aes", dilithium2_aes); - parameters.put("dilithium3-aes", dilithium3_aes); - parameters.put("dilithium5-aes", dilithium5_aes); } private final String name; diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/KyberParameterSpec.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/KyberParameterSpec.java index 09d7bc6eee..9cb5ddad20 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/KyberParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/KyberParameterSpec.java @@ -4,18 +4,15 @@ import java.util.HashMap; import java.util.Map; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; import org.bouncycastle.util.Strings; public class KyberParameterSpec implements AlgorithmParameterSpec { - public static final KyberParameterSpec kyber512 = new KyberParameterSpec(KyberParameters.kyber512); - public static final KyberParameterSpec kyber768 = new KyberParameterSpec(KyberParameters.kyber768); - public static final KyberParameterSpec kyber1024 = new KyberParameterSpec(KyberParameters.kyber1024); - public static final KyberParameterSpec kyber512_aes = new KyberParameterSpec(KyberParameters.kyber512_aes); - public static final KyberParameterSpec kyber768_aes = new KyberParameterSpec(KyberParameters.kyber768_aes); - public static final KyberParameterSpec kyber1024_aes = new KyberParameterSpec(KyberParameters.kyber1024_aes); + public static final KyberParameterSpec kyber512 = new KyberParameterSpec(MLKEMParameters.ml_kem_512); + public static final KyberParameterSpec kyber768 = new KyberParameterSpec(MLKEMParameters.ml_kem_768); + public static final KyberParameterSpec kyber1024 = new KyberParameterSpec(MLKEMParameters.ml_kem_1024); private static Map parameters = new HashMap(); @@ -24,14 +21,11 @@ public class KyberParameterSpec parameters.put("kyber512", kyber512); parameters.put("kyber768", kyber768); parameters.put("kyber1024", kyber1024); - parameters.put("kyber512-aes", kyber512_aes); - parameters.put("kyber768-aes", kyber768_aes); - parameters.put("kyber1024-aes", kyber1024_aes); } private final String name; - private KyberParameterSpec(KyberParameters parameters) + private KyberParameterSpec(MLKEMParameters parameters) { this.name = Strings.toUpperCase(parameters.getName()); } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/LMSKeyGenParameterSpec.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/LMSKeyGenParameterSpec.java index 4ed9cd8c50..492ca39314 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/LMSKeyGenParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/LMSKeyGenParameterSpec.java @@ -23,7 +23,22 @@ public class LMSKeyGenParameterSpec sigParameters.put("lms-sha256-n32-h15", LMSigParameters.lms_sha256_n32_h15); sigParameters.put("lms-sha256-n32-h20", LMSigParameters.lms_sha256_n32_h20); sigParameters.put("lms-sha256-n32-h25", LMSigParameters.lms_sha256_n32_h25); - + sigParameters.put("lms-sha256-n24-h5", LMSigParameters.lms_sha256_n24_h5); + sigParameters.put("lms-sha256-n24-h10", LMSigParameters.lms_sha256_n24_h10); + sigParameters.put("lms-sha256-n24-h15", LMSigParameters.lms_sha256_n24_h15); + sigParameters.put("lms-sha256-n24-h20", LMSigParameters.lms_sha256_n24_h20); + sigParameters.put("lms-sha256-n24-h25", LMSigParameters.lms_sha256_n24_h25); + sigParameters.put("lms-shake256-n32-h5", LMSigParameters.lms_shake256_n32_h5); + sigParameters.put("lms-shake256-n32-h10", LMSigParameters.lms_shake256_n32_h10); + sigParameters.put("lms-shake256-n32-h15", LMSigParameters.lms_shake256_n32_h15); + sigParameters.put("lms-shake256-n32-h20", LMSigParameters.lms_shake256_n32_h20); + sigParameters.put("lms-shake256-n32-h25", LMSigParameters.lms_shake256_n32_h25); + sigParameters.put("lms-shake256-n24-h5", LMSigParameters.lms_shake256_n24_h5); + sigParameters.put("lms-shake256-n24-h10", LMSigParameters.lms_shake256_n24_h10); + sigParameters.put("lms-shake256-n24-h15", LMSigParameters.lms_shake256_n24_h15); + sigParameters.put("lms-shake256-n24-h20", LMSigParameters.lms_shake256_n24_h20); + sigParameters.put("lms-shake256-n24-h25", LMSigParameters.lms_shake256_n24_h25); + otsParameters.put("sha256-n32-w1", LMOtsParameters.sha256_n32_w1); otsParameters.put("sha256-n32-w2", LMOtsParameters.sha256_n32_w2); otsParameters.put("sha256-n32-w4", LMOtsParameters.sha256_n32_w4); diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/NTRUParameterSpec.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/NTRUParameterSpec.java index 2f23040f68..e974e1b2ee 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/NTRUParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/NTRUParameterSpec.java @@ -13,7 +13,9 @@ public class NTRUParameterSpec public static final NTRUParameterSpec ntruhps2048509 = new NTRUParameterSpec(NTRUParameters.ntruhps2048509); public static final NTRUParameterSpec ntruhps2048677 = new NTRUParameterSpec(NTRUParameters.ntruhps2048677); public static final NTRUParameterSpec ntruhps4096821 = new NTRUParameterSpec(NTRUParameters.ntruhps4096821); + public static final NTRUParameterSpec ntruhps40961229 = new NTRUParameterSpec(NTRUParameters.ntruhps40961229); public static final NTRUParameterSpec ntruhrss701 = new NTRUParameterSpec(NTRUParameters.ntruhrss701); + public static final NTRUParameterSpec ntruhrss1373 = new NTRUParameterSpec(NTRUParameters.ntruhrss1373); private static Map parameters = new HashMap(); @@ -22,7 +24,9 @@ public class NTRUParameterSpec parameters.put("ntruhps2048509", ntruhps2048509); parameters.put("ntruhps2048677", ntruhps2048677); parameters.put("ntruhps4096821", ntruhps4096821); + parameters.put("ntruhps40961229", ntruhps40961229); parameters.put("ntruhrss701", ntruhrss701); + parameters.put("ntruhrss1373", ntruhrss1373); } private final String name; diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/SPHINCSPlusParameterSpec.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/SPHINCSPlusParameterSpec.java index 59159ba386..1493078648 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/SPHINCSPlusParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/SPHINCSPlusParameterSpec.java @@ -12,43 +12,43 @@ public class SPHINCSPlusParameterSpec implements AlgorithmParameterSpec { - public static final SPHINCSPlusParameterSpec sha2_128f = new SPHINCSPlusParameterSpec("sha2-128f-robust"); - public static final SPHINCSPlusParameterSpec sha2_128s = new SPHINCSPlusParameterSpec("sha2-128s-robust"); + public static final SPHINCSPlusParameterSpec sha2_128f_robust = new SPHINCSPlusParameterSpec("sha2-128f-robust"); + public static final SPHINCSPlusParameterSpec sha2_128s_robust = new SPHINCSPlusParameterSpec("sha2-128s-robust"); - public static final SPHINCSPlusParameterSpec sha2_192f = new SPHINCSPlusParameterSpec("sha2-192f-robust"); - public static final SPHINCSPlusParameterSpec sha2_192s = new SPHINCSPlusParameterSpec("sha2-192s-robust"); + public static final SPHINCSPlusParameterSpec sha2_192f_robust = new SPHINCSPlusParameterSpec("sha2-192f-robust"); + public static final SPHINCSPlusParameterSpec sha2_192s_robust = new SPHINCSPlusParameterSpec("sha2-192s-robust"); - public static final SPHINCSPlusParameterSpec sha2_256f = new SPHINCSPlusParameterSpec("sha2-256f-robust"); - public static final SPHINCSPlusParameterSpec sha2_256s = new SPHINCSPlusParameterSpec("sha2-256s-robust"); + public static final SPHINCSPlusParameterSpec sha2_256f_robust = new SPHINCSPlusParameterSpec("sha2-256f-robust"); + public static final SPHINCSPlusParameterSpec sha2_256s_robust = new SPHINCSPlusParameterSpec("sha2-256s-robust"); - public static final SPHINCSPlusParameterSpec sha2_128f_simple = new SPHINCSPlusParameterSpec("sha2-128s-simple"); - public static final SPHINCSPlusParameterSpec sha2_128s_simple = new SPHINCSPlusParameterSpec("sha2-128f-simple"); + public static final SPHINCSPlusParameterSpec sha2_128f = new SPHINCSPlusParameterSpec("sha2-128f"); + public static final SPHINCSPlusParameterSpec sha2_128s = new SPHINCSPlusParameterSpec("sha2-128s"); - public static final SPHINCSPlusParameterSpec sha2_192f_simple = new SPHINCSPlusParameterSpec("sha2-192f-simple"); - public static final SPHINCSPlusParameterSpec sha2_192s_simple = new SPHINCSPlusParameterSpec("sha2-192s-simple"); + public static final SPHINCSPlusParameterSpec sha2_192f = new SPHINCSPlusParameterSpec("sha2-192f"); + public static final SPHINCSPlusParameterSpec sha2_192s = new SPHINCSPlusParameterSpec("sha2-192s"); - public static final SPHINCSPlusParameterSpec sha2_256f_simple = new SPHINCSPlusParameterSpec("sha2-256f-simple"); - public static final SPHINCSPlusParameterSpec sha2_256s_simple = new SPHINCSPlusParameterSpec("sha2-256s-simple"); + public static final SPHINCSPlusParameterSpec sha2_256f = new SPHINCSPlusParameterSpec("sha2-256f"); + public static final SPHINCSPlusParameterSpec sha2_256s = new SPHINCSPlusParameterSpec("sha2-256s"); // SHAKE-256. - public static final SPHINCSPlusParameterSpec shake_128f = new SPHINCSPlusParameterSpec("shake-128f-robust"); - public static final SPHINCSPlusParameterSpec shake_128s = new SPHINCSPlusParameterSpec("shake-128s-robust"); + public static final SPHINCSPlusParameterSpec shake_128f_robust = new SPHINCSPlusParameterSpec("shake-128f-robust"); + public static final SPHINCSPlusParameterSpec shake_128s_robust = new SPHINCSPlusParameterSpec("shake-128s-robust"); - public static final SPHINCSPlusParameterSpec shake_192f = new SPHINCSPlusParameterSpec("shake-192f-robust"); - public static final SPHINCSPlusParameterSpec shake_192s = new SPHINCSPlusParameterSpec("shake-192s-robust"); + public static final SPHINCSPlusParameterSpec shake_192f_robust = new SPHINCSPlusParameterSpec("shake-192f-robust"); + public static final SPHINCSPlusParameterSpec shake_192s_robust = new SPHINCSPlusParameterSpec("shake-192s-robust"); - public static final SPHINCSPlusParameterSpec shake_256f = new SPHINCSPlusParameterSpec("shake-256f-robust"); - public static final SPHINCSPlusParameterSpec shake_256s = new SPHINCSPlusParameterSpec("shake-256s-robust"); + public static final SPHINCSPlusParameterSpec shake_256f_robust = new SPHINCSPlusParameterSpec("shake-256f-robust"); + public static final SPHINCSPlusParameterSpec shake_256s_robust = new SPHINCSPlusParameterSpec("shake-256s-robust"); - public static final SPHINCSPlusParameterSpec shake_128f_simple = new SPHINCSPlusParameterSpec("shake-128f-simple"); - public static final SPHINCSPlusParameterSpec shake_128s_simple = new SPHINCSPlusParameterSpec("shake-128s-simple"); + public static final SPHINCSPlusParameterSpec shake_128f = new SPHINCSPlusParameterSpec("shake-128f"); + public static final SPHINCSPlusParameterSpec shake_128s = new SPHINCSPlusParameterSpec("shake-128s"); - public static final SPHINCSPlusParameterSpec shake_192f_simple = new SPHINCSPlusParameterSpec("shake-192f-simple"); - public static final SPHINCSPlusParameterSpec shake_192s_simple = new SPHINCSPlusParameterSpec("shake-192s-simple"); + public static final SPHINCSPlusParameterSpec shake_192f = new SPHINCSPlusParameterSpec("shake-192f"); + public static final SPHINCSPlusParameterSpec shake_192s = new SPHINCSPlusParameterSpec("shake-192s"); - public static final SPHINCSPlusParameterSpec shake_256f_simple = new SPHINCSPlusParameterSpec("shake-256f-simple"); - public static final SPHINCSPlusParameterSpec shake_256s_simple = new SPHINCSPlusParameterSpec("shake-256s-simple"); + public static final SPHINCSPlusParameterSpec shake_256f = new SPHINCSPlusParameterSpec("shake-256f"); + public static final SPHINCSPlusParameterSpec shake_256s = new SPHINCSPlusParameterSpec("shake-256s"); public static final SPHINCSPlusParameterSpec haraka_128f = new SPHINCSPlusParameterSpec("haraka-128f-robust"); public static final SPHINCSPlusParameterSpec haraka_128s = new SPHINCSPlusParameterSpec("haraka-128s-robust"); @@ -72,6 +72,13 @@ public class SPHINCSPlusParameterSpec static { + parameters.put(SPHINCSPlusParameterSpec.sha2_128f_robust.getName(), SPHINCSPlusParameterSpec.sha2_128f_robust); + parameters.put(SPHINCSPlusParameterSpec.sha2_128s_robust.getName(), SPHINCSPlusParameterSpec.sha2_128s_robust); + parameters.put(SPHINCSPlusParameterSpec.sha2_192f_robust.getName(), SPHINCSPlusParameterSpec.sha2_192f_robust); + parameters.put(SPHINCSPlusParameterSpec.sha2_192s_robust.getName(), SPHINCSPlusParameterSpec.sha2_192s_robust); + parameters.put(SPHINCSPlusParameterSpec.sha2_256f_robust.getName(), SPHINCSPlusParameterSpec.sha2_256f_robust); + parameters.put(SPHINCSPlusParameterSpec.sha2_256s_robust.getName(), SPHINCSPlusParameterSpec.sha2_256s_robust); + parameters.put(SPHINCSPlusParameterSpec.sha2_128f.getName(), SPHINCSPlusParameterSpec.sha2_128f); parameters.put(SPHINCSPlusParameterSpec.sha2_128s.getName(), SPHINCSPlusParameterSpec.sha2_128s); parameters.put(SPHINCSPlusParameterSpec.sha2_192f.getName(), SPHINCSPlusParameterSpec.sha2_192f); @@ -79,12 +86,19 @@ public class SPHINCSPlusParameterSpec parameters.put(SPHINCSPlusParameterSpec.sha2_256f.getName(), SPHINCSPlusParameterSpec.sha2_256f); parameters.put(SPHINCSPlusParameterSpec.sha2_256s.getName(), SPHINCSPlusParameterSpec.sha2_256s); - parameters.put(SPHINCSPlusParameterSpec.sha2_128f_simple.getName(), SPHINCSPlusParameterSpec.sha2_128f_simple); - parameters.put(SPHINCSPlusParameterSpec.sha2_128s_simple.getName(), SPHINCSPlusParameterSpec.sha2_128s_simple); - parameters.put(SPHINCSPlusParameterSpec.sha2_192f_simple.getName(), SPHINCSPlusParameterSpec.sha2_192f_simple); - parameters.put(SPHINCSPlusParameterSpec.sha2_192s_simple.getName(), SPHINCSPlusParameterSpec.sha2_192s_simple); - parameters.put(SPHINCSPlusParameterSpec.sha2_256f_simple.getName(), SPHINCSPlusParameterSpec.sha2_256f_simple); - parameters.put(SPHINCSPlusParameterSpec.sha2_256s_simple.getName(), SPHINCSPlusParameterSpec.sha2_256s_simple); + parameters.put("sha2-128f", SPHINCSPlusParameterSpec.sha2_128f); + parameters.put("sha2-128s", SPHINCSPlusParameterSpec.sha2_128s); + parameters.put("sha2-192f", SPHINCSPlusParameterSpec.sha2_192f); + parameters.put("sha2-192s", SPHINCSPlusParameterSpec.sha2_192s); + parameters.put("sha2-256f", SPHINCSPlusParameterSpec.sha2_256f); + parameters.put("sha2-256s", SPHINCSPlusParameterSpec.sha2_256s); + + parameters.put(SPHINCSPlusParameterSpec.shake_128f_robust.getName(), SPHINCSPlusParameterSpec.shake_128f_robust); + parameters.put(SPHINCSPlusParameterSpec.shake_128s_robust.getName(), SPHINCSPlusParameterSpec.shake_128s_robust); + parameters.put(SPHINCSPlusParameterSpec.shake_192f_robust.getName(), SPHINCSPlusParameterSpec.shake_192f_robust); + parameters.put(SPHINCSPlusParameterSpec.shake_192s_robust.getName(), SPHINCSPlusParameterSpec.shake_192s_robust); + parameters.put(SPHINCSPlusParameterSpec.shake_256f_robust.getName(), SPHINCSPlusParameterSpec.shake_256f_robust); + parameters.put(SPHINCSPlusParameterSpec.shake_256s_robust.getName(), SPHINCSPlusParameterSpec.shake_256s_robust); parameters.put(SPHINCSPlusParameterSpec.shake_128f.getName(), SPHINCSPlusParameterSpec.shake_128f); parameters.put(SPHINCSPlusParameterSpec.shake_128s.getName(), SPHINCSPlusParameterSpec.shake_128s); @@ -93,12 +107,12 @@ public class SPHINCSPlusParameterSpec parameters.put(SPHINCSPlusParameterSpec.shake_256f.getName(), SPHINCSPlusParameterSpec.shake_256f); parameters.put(SPHINCSPlusParameterSpec.shake_256s.getName(), SPHINCSPlusParameterSpec.shake_256s); - parameters.put(SPHINCSPlusParameterSpec.shake_128f_simple.getName(), SPHINCSPlusParameterSpec.shake_128f_simple); - parameters.put(SPHINCSPlusParameterSpec.shake_128s_simple.getName(), SPHINCSPlusParameterSpec.shake_128s_simple); - parameters.put(SPHINCSPlusParameterSpec.shake_192f_simple.getName(), SPHINCSPlusParameterSpec.shake_192f_simple); - parameters.put(SPHINCSPlusParameterSpec.shake_192s_simple.getName(), SPHINCSPlusParameterSpec.shake_192s_simple); - parameters.put(SPHINCSPlusParameterSpec.shake_256f_simple.getName(), SPHINCSPlusParameterSpec.shake_256f_simple); - parameters.put(SPHINCSPlusParameterSpec.shake_256s_simple.getName(), SPHINCSPlusParameterSpec.shake_256s_simple); + parameters.put("shake-128f", SPHINCSPlusParameterSpec.shake_128f); + parameters.put("shake-128s", SPHINCSPlusParameterSpec.shake_128s); + parameters.put("shake-192f", SPHINCSPlusParameterSpec.shake_192f); + parameters.put("shake-192s", SPHINCSPlusParameterSpec.shake_192s); + parameters.put("shake-256f", SPHINCSPlusParameterSpec.shake_256f); + parameters.put("shake-256s", SPHINCSPlusParameterSpec.shake_256s); parameters.put(SPHINCSPlusParameterSpec.haraka_128f.getName(), SPHINCSPlusParameterSpec.haraka_128f); parameters.put(SPHINCSPlusParameterSpec.haraka_128s.getName(), SPHINCSPlusParameterSpec.haraka_128s); diff --git a/prov/src/main/java/org/bouncycastle/x509/PKIXCertPathReviewer.java b/prov/src/main/java/org/bouncycastle/x509/PKIXCertPathReviewer.java index 2ec2014273..d8d090f066 100644 --- a/prov/src/main/java/org/bouncycastle/x509/PKIXCertPathReviewer.java +++ b/prov/src/main/java/org/bouncycastle/x509/PKIXCertPathReviewer.java @@ -81,6 +81,7 @@ /** * PKIXCertPathReviewer
      * Validation of X.509 Certificate Paths. Tries to find as much errors in the Path as possible. + * @deprecated use org.bouncycastle.pkix.jcajce.PKIXCertPathReviewer in the bcpkix package */ public class PKIXCertPathReviewer extends CertPathValidatorUtilities { @@ -90,7 +91,9 @@ public class PKIXCertPathReviewer extends CertPathValidatorUtilities private static final String AUTH_INFO_ACCESS = Extension.authorityInfoAccess.getId(); private static final String RESOURCE_NAME = "org.bouncycastle.x509.CertPathReviewerMessages"; - + + private static final int NAME_CHECK_MAX = (1 << 10); + // input parameters protected CertPath certPath; @@ -500,9 +503,15 @@ private void checkNameConstraints() ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.subjAltNameExtError"); throw new CertPathReviewerException(msg,ae,certPath,index); } - + if (altName != null) { + if (altName.size() > NAME_CHECK_MAX) + { + ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.subjAltNameExtError"); + throw new CertPathReviewerException(msg,certPath,index); + } + for (int j = 0; j < altName.size(); j++) { GeneralName name = GeneralName.getInstance(altName.getObjectAt(j)); @@ -518,87 +527,6 @@ private void checkNameConstraints() new Object[] {new UntrustedInput(name)}); throw new CertPathReviewerException(msg,cpve,certPath,index); } -// switch(o.getTagNo()) TODO - move resources to PKIXNameConstraints -// { -// case 1: -// String email = DERIA5String.getInstance(o, true).getString(); -// -// try -// { -// checkPermittedEmail(permittedSubtreesEmail, email); -// } -// catch (CertPathValidatorException cpve) -// { -// ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.notPermittedEmail", -// new Object[] {new UntrustedInput(email)}); -// throw new CertPathReviewerException(msg,cpve,certPath,index); -// } -// -// try -// { -// checkExcludedEmail(excludedSubtreesEmail, email); -// } -// catch (CertPathValidatorException cpve) -// { -// ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.excludedEmail", -// new Object[] {new UntrustedInput(email)}); -// throw new CertPathReviewerException(msg,cpve,certPath,index); -// } -// -// break; -// case 4: -// ASN1Sequence altDN = ASN1Sequence.getInstance(o, true); -// -// try -// { -// checkPermittedDN(permittedSubtreesDN, altDN); -// } -// catch (CertPathValidatorException cpve) -// { -// X509Name altDNName = new X509Name(altDN); -// ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.notPermittedDN", -// new Object[] {new UntrustedInput(altDNName)}); -// throw new CertPathReviewerException(msg,cpve,certPath,index); -// } -// -// try -// { -// checkExcludedDN(excludedSubtreesDN, altDN); -// } -// catch (CertPathValidatorException cpve) -// { -// X509Name altDNName = new X509Name(altDN); -// ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.excludedDN", -// new Object[] {new UntrustedInput(altDNName)}); -// throw new CertPathReviewerException(msg,cpve,certPath,index); -// } -// -// break; -// case 7: -// byte[] ip = ASN1OctetString.getInstance(o, true).getOctets(); -// -// try -// { -// checkPermittedIP(permittedSubtreesIP, ip); -// } -// catch (CertPathValidatorException cpve) -// { -// ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.notPermittedIP", -// new Object[] {IPtoString(ip)}); -// throw new CertPathReviewerException(msg,cpve,certPath,index); -// } -// -// try -// { -// checkExcludedIP(excludedSubtreesIP, ip); -// } -// catch (CertPathValidatorException cpve) -// { -// ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.excludedIP", -// new Object[] {IPtoString(ip)}); -// throw new CertPathReviewerException(msg,cpve,certPath,index); -// } -// } } } } @@ -667,11 +595,8 @@ private void checkPathLength() X509Certificate cert = null; - int i; for (int index = certs.size() - 1; index > 0; index--) { - i = n - index; - cert = (X509Certificate) certs.get(index); // l) @@ -692,8 +617,7 @@ private void checkPathLength() BasicConstraints bc; try { - bc = BasicConstraints.getInstance(getExtensionValue(cert, - BASIC_CONSTRAINTS)); + bc = BasicConstraints.getInstance(getExtensionValue(cert, BASIC_CONSTRAINTS)); } catch (AnnotatedException ae) { @@ -702,21 +626,14 @@ private void checkPathLength() bc = null; } - if (bc != null) + if (bc != null && bc.isCA()) { - BigInteger _pathLengthConstraint = bc.getPathLenConstraint(); - - if (_pathLengthConstraint != null) + ASN1Integer pathLenConstraint = bc.getPathLenConstraintInteger(); + if (pathLenConstraint != null) { - int _plc = _pathLengthConstraint.intValue(); - - if (_plc < maxPathLength) - { - maxPathLength = _plc; - } + maxPathLength = Math.min(maxPathLength, pathLenConstraint.intPositiveValueExact()); } } - } ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.totalPathLength", diff --git a/prov/src/main/java/org/bouncycastle/x509/X509Util.java b/prov/src/main/java/org/bouncycastle/x509/X509Util.java index c72169e529..2be58a87f6 100644 --- a/prov/src/main/java/org/bouncycastle/x509/X509Util.java +++ b/prov/src/main/java/org/bouncycastle/x509/X509Util.java @@ -27,12 +27,12 @@ import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.Strings; diff --git a/prov/src/main/java/org/bouncycastle/x509/util/LDAPStoreHelper.java b/prov/src/main/java/org/bouncycastle/x509/util/LDAPStoreHelper.java index 9392bd2eb7..8121a498ed 100644 --- a/prov/src/main/java/org/bouncycastle/x509/util/LDAPStoreHelper.java +++ b/prov/src/main/java/org/bouncycastle/x509/util/LDAPStoreHelper.java @@ -36,6 +36,7 @@ import org.bouncycastle.jce.provider.X509CertPairParser; import org.bouncycastle.jce.provider.X509CertParser; import org.bouncycastle.util.StoreException; +import org.bouncycastle.util.Strings; import org.bouncycastle.x509.X509AttributeCertStoreSelector; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CRLStoreSelector; @@ -113,8 +114,8 @@ private DirContext connectLDAP() throws NamingException private String parseDN(String subject, String dNAttributeName) { String temp = subject; - int begin = temp.toLowerCase().indexOf( - dNAttributeName.toLowerCase() + "="); + int begin = Strings.toLowerCase(temp).indexOf( + Strings.toLowerCase(dNAttributeName) + "="); if (begin == -1) { return ""; diff --git a/prov/src/main/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java b/prov/src/main/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java index 8d127434dc..4d18dbfd1c 100644 --- a/prov/src/main/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java +++ b/prov/src/main/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java @@ -15,7 +15,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; diff --git a/prov/src/main/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureUtil.java b/prov/src/main/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureUtil.java index ef35f6a14c..8f32eaa550 100644 --- a/prov/src/main/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureUtil.java +++ b/prov/src/main/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureUtil.java @@ -17,7 +17,7 @@ import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; diff --git a/prov/src/main/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java b/prov/src/main/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java index c1eb4df3ae..21391a5323 100644 --- a/prov/src/main/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java +++ b/prov/src/main/jdk1.1/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java @@ -19,8 +19,8 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; diff --git a/prov/src/main/jdk1.1/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/prov/src/main/jdk1.1/org/bouncycastle/jce/provider/BouncyCastleProvider.java index b5a39e6297..22e4a21516 100644 --- a/prov/src/main/jdk1.1/org/bouncycastle/jce/provider/BouncyCastleProvider.java +++ b/prov/src/main/jdk1.1/org/bouncycastle/jce/provider/BouncyCastleProvider.java @@ -43,7 +43,7 @@ public final class BouncyCastleProvider extends Provider implements ConfigurableProvider { - private static String info = "BouncyCastle Security Provider v1.73"; + private static String info = "BouncyCastle Security Provider v1.78.1"; public static final String PROVIDER_NAME = "BC"; @@ -118,7 +118,7 @@ public final class BouncyCastleProvider extends Provider */ public BouncyCastleProvider() { - super(PROVIDER_NAME, 1.73, info); + super(PROVIDER_NAME, 1.7801, info); setup(); } diff --git a/prov/src/main/jdk1.1/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java b/prov/src/main/jdk1.1/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java index 55f39ee38a..e5ca7214bf 100644 --- a/prov/src/main/jdk1.1/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java +++ b/prov/src/main/jdk1.1/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java @@ -51,7 +51,7 @@ import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Enumerated; -import org.bouncycastle.asn1.DERIA5String; +import org.bouncycastle.asn1.ASN1IA5String; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1ObjectIdentifier; @@ -934,7 +934,7 @@ public CertPathValidatorResult engineValidate( switch(o.getTagNo()) { case 1: - String email = DERIA5String.getInstance(o, true).getString(); + String email = ASN1IA5String.getInstance(o, true).getString(); checkPermittedEmail(permittedSubtreesEmail, email); checkExcludedEmail(excludedSubtreesEmail, email); @@ -1334,7 +1334,7 @@ else if (policyMapping <= 0) switch(base.getTagNo()) { case 1: - permittedSubtreesEmail = intersectEmail(permittedSubtreesEmail, DERIA5String.getInstance(base.getName()).getString()); + permittedSubtreesEmail = intersectEmail(permittedSubtreesEmail, ASN1IA5String.getInstance(base.getName()).getString()); break; case 4: permittedSubtreesDN = intersectDN(permittedSubtreesDN, (ASN1Sequence)base.getName()); @@ -1360,7 +1360,7 @@ else if (policyMapping <= 0) switch(base.getTagNo()) { case 1: - excludedSubtreesEmail = unionEmail(excludedSubtreesEmail, DERIA5String.getInstance(base.getName()).getString()); + excludedSubtreesEmail = unionEmail(excludedSubtreesEmail, ASN1IA5String.getInstance(base.getName()).getString()); break; case 4: excludedSubtreesDN = unionDN(excludedSubtreesDN, (ASN1Sequence)base.getName()); diff --git a/prov/src/main/jdk1.1/org/bouncycastle/jce/provider/X509CertificateObject.java b/prov/src/main/jdk1.1/org/bouncycastle/jce/provider/X509CertificateObject.java index 2ae4e814a1..1e4c262dd3 100644 --- a/prov/src/main/jdk1.1/org/bouncycastle/jce/provider/X509CertificateObject.java +++ b/prov/src/main/jdk1.1/org/bouncycastle/jce/provider/X509CertificateObject.java @@ -42,10 +42,10 @@ import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; -import org.bouncycastle.asn1.misc.NetscapeCertType; -import org.bouncycastle.asn1.misc.NetscapeRevocationURL; -import org.bouncycastle.asn1.misc.VerisignCzagExtension; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.NetscapeCertType; +import org.bouncycastle.internal.asn1.misc.NetscapeRevocationURL; +import org.bouncycastle.internal.asn1.misc.VerisignCzagExtension; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.RFC4519Style; diff --git a/prov/src/main/jdk1.1/org/bouncycastle/x509/X509Util.java b/prov/src/main/jdk1.1/org/bouncycastle/x509/X509Util.java index 7677c48dc0..d97acd59b7 100644 --- a/prov/src/main/jdk1.1/org/bouncycastle/x509/X509Util.java +++ b/prov/src/main/jdk1.1/org/bouncycastle/x509/X509Util.java @@ -25,7 +25,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; diff --git a/prov/src/main/jdk1.11/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyAgreementSpi.java b/prov/src/main/jdk1.11/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyAgreementSpi.java index e6afd69838..58a475e28c 100644 --- a/prov/src/main/jdk1.11/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyAgreementSpi.java +++ b/prov/src/main/jdk1.11/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyAgreementSpi.java @@ -69,7 +69,7 @@ else if (priv instanceof X448PrivateKeyParameters) } else { - throw new IllegalStateException("unsupported private key type"); + throw new InvalidKeyException("unsupported private key type"); } ukmParameters = null; diff --git a/prov/src/main/jdk1.11/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java b/prov/src/main/jdk1.11/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java index 2af978a7ad..5fdbde7496 100644 --- a/prov/src/main/jdk1.11/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java +++ b/prov/src/main/jdk1.11/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java @@ -16,7 +16,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; diff --git a/prov/src/main/jdk1.11/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java b/prov/src/main/jdk1.11/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java index 580150495f..59226537fd 100644 --- a/prov/src/main/jdk1.11/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java +++ b/prov/src/main/jdk1.11/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java @@ -8,7 +8,7 @@ import java.security.spec.ECGenParameterSpec; import java.security.spec.NamedParameterSpec; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.CryptoServicesRegistrar; diff --git a/prov/src/main/jdk1.15/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java b/prov/src/main/jdk1.15/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java index 5b4916d2b4..f67a553fb7 100644 --- a/prov/src/main/jdk1.15/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java +++ b/prov/src/main/jdk1.15/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java @@ -16,7 +16,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; diff --git a/prov/src/main/jdk1.15/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java b/prov/src/main/jdk1.15/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java index 0a5ceaeabe..68f81687d4 100644 --- a/prov/src/main/jdk1.15/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java +++ b/prov/src/main/jdk1.15/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java @@ -8,7 +8,7 @@ import java.security.spec.ECGenParameterSpec; import java.security.spec.NamedParameterSpec; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.CryptoServicesRegistrar; diff --git a/prov/src/main/jdk1.15/org/bouncycastle/jcajce/provider/asymmetric/edec/SignatureSpi.java b/prov/src/main/jdk1.15/org/bouncycastle/jcajce/provider/asymmetric/edec/SignatureSpi.java index f0d67e54b3..6891498db8 100644 --- a/prov/src/main/jdk1.15/org/bouncycastle/jcajce/provider/asymmetric/edec/SignatureSpi.java +++ b/prov/src/main/jdk1.15/org/bouncycastle/jcajce/provider/asymmetric/edec/SignatureSpi.java @@ -56,7 +56,7 @@ else if (pub instanceof Ed448PublicKeyParameters) } else { - throw new IllegalStateException("unsupported public key type"); + throw new InvalidKeyException("unsupported public key type"); } signer.init(false, pub); @@ -77,7 +77,7 @@ else if (priv instanceof Ed448PrivateKeyParameters) } else { - throw new IllegalStateException("unsupported private key type"); + throw new InvalidKeyException("unsupported private key type"); } signer.init(true, priv); diff --git a/prov/src/main/jdk1.2/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java b/prov/src/main/jdk1.2/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java index 87d687c376..1fd6f0b351 100644 --- a/prov/src/main/jdk1.2/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java +++ b/prov/src/main/jdk1.2/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java @@ -3,6 +3,7 @@ import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PublicKey; +import java.security.PrivateKey; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; @@ -18,6 +19,14 @@ class ECUtils { + static AsymmetricKeyParameter generatePrivateKeyParameter( + PrivateKey key) + throws InvalidKeyException + { + return (key instanceof BCECPrivateKey) ? ((BCECPrivateKey)key).engineGetKeyParameters() : ECUtil.generatePrivateKeyParameter(key); + } + + static AsymmetricKeyParameter generatePublicKeyParameter( PublicKey key) throws InvalidKeyException diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureUtil.java b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureUtil.java index 158a0768d3..1b8cba63bb 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureUtil.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureUtil.java @@ -17,7 +17,7 @@ import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java index f91ca41a4b..527be010bf 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java @@ -31,6 +31,7 @@ import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1IA5String; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; @@ -38,13 +39,12 @@ import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.ASN1BitString; -import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; -import org.bouncycastle.asn1.misc.NetscapeCertType; -import org.bouncycastle.asn1.misc.NetscapeRevocationURL; -import org.bouncycastle.asn1.misc.VerisignCzagExtension; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.NetscapeCertType; +import org.bouncycastle.internal.asn1.misc.NetscapeRevocationURL; +import org.bouncycastle.internal.asn1.misc.VerisignCzagExtension; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.RFC4519Style; @@ -512,11 +512,11 @@ else if (oid.equals(MiscObjectIdentifiers.netscapeCertType)) } else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL)) { - buf.append(new NetscapeRevocationURL(DERIA5String.getInstance(dIn.readObject()))).append(nl); + buf.append(new NetscapeRevocationURL(ASN1IA5String.getInstance(dIn.readObject()))).append(nl); } else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension)) { - buf.append(new VerisignCzagExtension(DERIA5String.getInstance(dIn.readObject()))).append(nl); + buf.append(new VerisignCzagExtension(ASN1IA5String.getInstance(dIn.readObject()))).append(nl); } else { diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java index ea4c7e3678..a08a326deb 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java @@ -13,7 +13,6 @@ import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jcajce.util.JcaJceHelper; @@ -257,7 +256,7 @@ private static boolean[] createKeyUsage(org.bouncycastle.asn1.x509.Certificate c return null; } - ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(extOctets)); + ASN1BitString bits = ASN1BitString.getInstance(ASN1Primitive.fromByteArray(extOctets)); byte[] bytes = bits.getBytes(); int length = (bytes.length * 8) - bits.getPadBits(); diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java index 143b358dc0..925ccc3206 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java @@ -19,8 +19,8 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java index 5c460ed506..eecbda31f4 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java @@ -54,7 +54,7 @@ import org.bouncycastle.asn1.bc.SecretKeyData; import org.bouncycastle.internal.asn1.cms.CCMParameters; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.EncryptionScheme; import org.bouncycastle.asn1.pkcs.KeyDerivationFunc; diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java index b053d68fce..5d20eaddfc 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java @@ -59,7 +59,6 @@ import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java index baa66a9cc2..d24f8c0c66 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java @@ -1,18 +1,24 @@ package org.bouncycastle.jcajce.spec; import java.security.spec.AlgorithmParameterSpec; -import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Arrays; -/* - * SP 800-56C Hybrid Value spec, to allow the secret in a key agreement to be - * created as "Z | T" where T is some other secret value as described in Section 2. +/** + * SP 800-56C Hybrid Value spec, by default to allow the secret in a key agreement to be + * created as "Z | T" where T is some other secret value as described in Section 2. If the + * value doPrepend is set to true the spec will be used to calculate "T | Z" instead. + *

      + * Get methods throw IllegalStateException if destroy() is called. + *

      */ public class HybridValueParameterSpec implements AlgorithmParameterSpec { private final AtomicBoolean hasBeenDestroyed = new AtomicBoolean(false); + private final boolean doPrepend; + private volatile byte[] t; private volatile AlgorithmParameterSpec baseSpec; @@ -24,9 +30,31 @@ public class HybridValueParameterSpec * @param baseSpec the base spec for the agreements KDF. */ public HybridValueParameterSpec(byte[] t, AlgorithmParameterSpec baseSpec) + { + this(t, false, baseSpec); + } + + /** + * Create a spec with T set to t and the spec for the KDF in the agreement to baseSpec. + * Note: the t value is not copied. + * @param t a shared secret to be concatenated with the agreement's Z value. + * @param baseSpec the base spec for the agreements KDF. + */ + public HybridValueParameterSpec(byte[] t, boolean doPrepend, AlgorithmParameterSpec baseSpec) { this.t = t; this.baseSpec = baseSpec; + this.doPrepend = doPrepend; + } + + /** + * Return whether or not T should be prepended. + * + * @return true if T to be prepended, false otherwise. + */ + public boolean isPrependedT() + { + return doPrepend; } /** @@ -36,9 +64,11 @@ public HybridValueParameterSpec(byte[] t, AlgorithmParameterSpec baseSpec) */ public byte[] getT() { + byte[] tVal = t; + checkDestroyed(); - return t; + return tVal; } /** @@ -48,11 +78,19 @@ public byte[] getT() */ public AlgorithmParameterSpec getBaseParameterSpec() { + AlgorithmParameterSpec rv = this.baseSpec; + checkDestroyed(); - return baseSpec; + return rv; } + /** + * Return true if the destroy() method is called and the contents are + * erased. + * + * @return true if destroyed, false otherwise. + */ public boolean isDestroyed() { return this.hasBeenDestroyed.get(); diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jce/PKCS10CertificationRequest.java b/prov/src/main/jdk1.3/org/bouncycastle/jce/PKCS10CertificationRequest.java index c448324b21..d4f15cbf52 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jce/PKCS10CertificationRequest.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jce/PKCS10CertificationRequest.java @@ -29,7 +29,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jce/cert/CertUtil.java b/prov/src/main/jdk1.3/org/bouncycastle/jce/cert/CertUtil.java index 11a456ec26..135e1f521a 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jce/cert/CertUtil.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jce/cert/CertUtil.java @@ -1,17 +1,15 @@ package org.bouncycastle.jce.cert; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; +import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.DERIA5String; -import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.OIDTokenizer; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.util.Strings; @@ -336,12 +334,7 @@ static byte[] parseOID(String oid) throws IOException { throw new IOException("token: " + token + ": " + ex.toString()); } - ASN1Object derData = new ASN1ObjectIdentifier(oid); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - derOutStream.writeObject(derData); - derOutStream.close(); - return outStream.toByteArray(); + return new ASN1ObjectIdentifier(oid).getEncoded(ASN1Encoding.DER); } /** @@ -452,12 +445,7 @@ private static byte[] parseIPv6(String data) private static byte[] parseURI(String data) throws IOException { // TODO do parsing test - ASN1Object derData = new DERIA5String(data); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - derOutStream.writeObject(derData); - derOutStream.close(); - return outStream.toByteArray(); + return new DERIA5String(data).getEncoded(ASN1Encoding.DER); } /** @@ -479,13 +467,8 @@ private static byte[] parseRfc822(String data) throws IOException { throw new IOException("wrong format of rfc822Name:" + data); } - // TODO more test for illegal charateers - ASN1Object derData = new DERIA5String(data); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - derOutStream.writeObject(derData); - derOutStream.close(); - return outStream.toByteArray(); + // TODO more test for illegal characters + return new DERIA5String(data).getEncoded(ASN1Encoding.DER); } /** @@ -502,13 +485,8 @@ private static byte[] parseRfc822(String data) throws IOException */ private static byte[] parseDNSName(String data) throws IOException { - // TODO more test for illegal charateers - ASN1Object derData = new DERIA5String(data); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - derOutStream.writeObject(derData); - derOutStream.close(); - return outStream.toByteArray(); + // TODO more test for illegal characters + return new DERIA5String(data).getEncoded(ASN1Encoding.DER); } /** @@ -524,12 +502,8 @@ private static byte[] parseDNSName(String data) throws IOException */ private static byte[] parseX509Name(String data) throws IOException { - // TODO more test for illegal charateers - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - derOutStream.writeObject(new X509Name(trimX509Name(data))); - derOutStream.close(); - return outStream.toByteArray(); + // TODO more test for illegal characters + return new X509Name(trimX509Name(data)).getEncoded(ASN1Encoding.DER); } /** diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jce/cert/X509CertSelector.java b/prov/src/main/jdk1.3/org/bouncycastle/jce/cert/X509CertSelector.java index 830f7f1e7d..f971924e8d 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jce/cert/X509CertSelector.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jce/cert/X509CertSelector.java @@ -1,7 +1,5 @@ package org.bouncycastle.jce.cert; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.PublicKey; @@ -20,16 +18,15 @@ import java.util.List; import java.util.Set; -import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; -import org.bouncycastle.asn1.ASN1OutputStream; +import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DERGeneralizedTime; -import org.bouncycastle.asn1.ASN1GeneralizedTime; -import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; @@ -77,10 +74,8 @@ * TODO: implement name constraints * TODO: implement match check for path to names
      *
      - * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, + * Uses {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, - * {@link org.bouncycastle.asn1.ASN1OutputStream DEROutputStream}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.OIDTokenizer OIDTokenizer}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name}, @@ -284,8 +279,7 @@ public void setIssuer(String issuerDN) throws IOException * Note that the byte array specified here is cloned to protect against * subsequent modifications.
      *
      - * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, + * Uses {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} * @@ -305,9 +299,7 @@ public void setIssuer(byte[] issuerDN) throws IOException } else { - ByteArrayInputStream inStream = new ByteArrayInputStream(issuerDN); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object obj = derInStream.readObject(); + ASN1Object obj = ASN1Primitive.fromByteArray(issuerDN); if (obj instanceof ASN1Sequence) { this.issuerDNX509 = new X509Name((ASN1Sequence)obj); @@ -371,8 +363,7 @@ public void setSubject(String subjectDN) throws IOException * the ASN.1 notation for this structure, see * {@link #setIssuer(byte []) setIssuer(byte [] issuerDN)}.
      *
      - * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, + * Uses {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name} * @@ -392,10 +383,7 @@ public void setSubject(byte[] subjectDN) throws IOException } else { - ByteArrayInputStream inStream = new ByteArrayInputStream(subjectDN); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object obj = derInStream.readObject(); - + ASN1Object obj = ASN1Primitive.fromByteArray(subjectDN); if (obj instanceof ASN1Sequence) { this.subjectDNX509 = new X509Name((ASN1Sequence)obj); @@ -735,11 +723,11 @@ public void setExtendedKeyUsage(Set keyPurposeSet) throws IOException { if (keyPurposeSet == null || keyPurposeSet.isEmpty()) { - this.keyPurposeSet = keyPurposeSet; + this.keyPurposeSet = null; } else { - this.keyPurposeSet = new HashSet(); + HashSet checkKeyPurposeSet = new HashSet(); Iterator iter = keyPurposeSet.iterator(); Object obj; KeyPurposeId purposeID; @@ -748,15 +736,16 @@ public void setExtendedKeyUsage(Set keyPurposeSet) throws IOException obj = iter.next(); if (obj instanceof String) { - purposeID = (KeyPurposeId)keyPurposeIdMap.get((String)obj); + String str = (String)obj; + purposeID = (KeyPurposeId)keyPurposeIdMap.get(str); if (purposeID == null) { - throw new IOException("unknown purposeID " - + (String)obj); + throw new IOException("unknown purposeID " + str); } - this.keyPurposeSet.add(purposeID); + checkKeyPurposeSet.add(purposeID); } } + this.keyPurposeSet = Collections.unmodifiableSet(checkKeyPurposeSet); } } @@ -856,8 +845,7 @@ else if (data instanceof byte[]) } else { - throw new IOException( - "parsing error: unknown data type"); + throw new IOException("parsing error: unknown data type"); } } } @@ -908,6 +896,7 @@ public void addSubjectAlternativeName(int type, String name) tmpList.add(Integers.valueOf(type)); tmpList.add(name); subjectAltNames.add(tmpList); + // FIXME Surely this affects the entry we just added to subjectAltNames?? tmpList.set(1, encoded); subjectAltNamesByte.add(tmpList); } @@ -1094,7 +1083,7 @@ public void setPolicy(Set certPolicySet) throws IOException } else { - policyOID = new HashSet(); + HashSet checkPolicyOID = new HashSet(); Iterator iter = certPolicySet.iterator(); Object item; while (iter.hasNext()) @@ -1103,15 +1092,15 @@ public void setPolicy(Set certPolicySet) throws IOException if (item instanceof String) { CertUtil.parseOID((String)item); - policyOID.add(new ASN1ObjectIdentifier((String)item)); + checkPolicyOID.add(new ASN1ObjectIdentifier((String)item)); } else { - throw new IOException( - "certPolicySet contains null values or non String objects"); + throw new IOException("certPolicySet contains null values or non String objects"); } } - policy = new HashSet(certPolicySet); + this.policy = Collections.unmodifiableSet(new HashSet(certPolicySet)); + this.policyOID = Collections.unmodifiableSet(checkPolicyOID); } } @@ -1197,8 +1186,7 @@ else if (data instanceof byte[]) } else { - throw new IOException( - "parsing error: unknown data type"); + throw new IOException("parsing error: unknown data type"); } } } @@ -1248,6 +1236,7 @@ public void addPathToName(int type, String name) throws IOException tmpList.add(Integers.valueOf(type)); tmpList.add(name); pathToNames.add(tmpList); + // FIXME Surely this affects the entry we just added to pathToNames?? tmpList.set(1, encoded); pathToNamesByte.add(tmpList); throw new UnsupportedOperationException(); @@ -1340,7 +1329,7 @@ public String getIssuerAsString() { if (issuerDN instanceof String) { - return new String((String)issuerDN); + return (String)issuerDN; } else if (issuerDNX509 != null) { @@ -1364,8 +1353,7 @@ else if (issuerDNX509 != null) * Note that the byte array returned is cloned to protect against subsequent * modifications.
      *
      - * Uses {@link org.bouncycastle.asn1.ASN1OutputStream DEROutputStream}, - * {@link org.bouncycastle.asn1.x509.X509Name X509Name} to gnerate byte[] + * Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} to generate byte[] * output for String issuerDN. * * @return a byte array containing the required issuer distinguished name in @@ -1382,13 +1370,7 @@ public byte[] getIssuerAsBytes() throws IOException } else if (issuerDNX509 != null) { - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - - derOutStream.writeObject(issuerDNX509.toASN1Primitive()); - derOutStream.close(); - - return outStream.toByteArray(); + return issuerDNX509.getEncoded(ASN1Encoding.DER); } return null; @@ -1413,7 +1395,7 @@ public String getSubjectAsString() { if (subjectDN instanceof String) { - return new String((String)subjectDN); + return (String)subjectDN; } else if (subjectDNX509 != null) { @@ -1437,8 +1419,7 @@ else if (subjectDNX509 != null) * Note that the byte array returned is cloned to protect against subsequent * modifications.
      *
      - * Uses {@link org.bouncycastle.asn1.ASN1OutputStream DEROutputStream}, - * {@link org.bouncycastle.asn1.x509.X509Name X509Name} to gnerate byte[] + * Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} to generate byte[] * output for String subjectDN. * * @return a byte array containing the required subject distinguished name @@ -1455,13 +1436,7 @@ public byte[] getSubjectAsBytes() throws IOException } else if (subjectDNX509 != null) { - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - ASN1OutputStream derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - - derOutStream.writeObject(subjectDNX509.toASN1Primitive()); - derOutStream.close(); - - return outStream.toByteArray(); + return subjectDNX509.getEncoded(ASN1Encoding.DER); } return null; @@ -1634,19 +1609,7 @@ public boolean[] getKeyUsage() */ public Set getExtendedKeyUsage() { - if (keyPurposeSet == null || keyPurposeSet.isEmpty()) - { - return keyPurposeSet; - } - - Set returnSet = new HashSet(); - Iterator iter = keyPurposeSet.iterator(); - while (iter.hasNext()) - { - returnSet.add(iter.next().toString()); - } - - return Collections.unmodifiableSet(returnSet); + return keyPurposeSet; } /** @@ -1704,7 +1667,7 @@ public boolean getMatchAllSubjectAltNames() */ public Collection getSubjectAlternativeNames() { - if (subjectAltNames != null) + if (subjectAltNames == null) { return null; } @@ -1713,19 +1676,18 @@ public Collection getSubjectAlternativeNames() List returnList; Iterator iter = subjectAltNames.iterator(); List obj; + Object data; while (iter.hasNext()) { obj = (List)iter.next(); returnList = new ArrayList(); returnList.add(obj.get(0)); - if (obj.get(1) instanceof byte[]) + data = obj.get(1); + if (data instanceof byte[]) { - returnList.add(((byte[])obj.get(1)).clone()); - } - else - { - returnList.add(obj.get(1)); + data = data.clone(); } + returnList.add(data); returnAltNames.add(returnList); } @@ -1795,12 +1757,7 @@ public int getBasicConstraints() */ public Set getPolicy() { - if (policy == null) - { - return null; - } - - return Collections.unmodifiableSet(policy); + return policy; } /** @@ -1843,20 +1800,18 @@ public Collection getPathToNames() List returnList; Iterator iter = pathToNames.iterator(); List obj; - + Object data; while (iter.hasNext()) { obj = (List)iter.next(); returnList = new ArrayList(); returnList.add(obj.get(0)); - if (obj.get(1) instanceof byte[]) + data = obj.get(1); + if (data instanceof byte[]) { - returnList.add(((byte[])obj.get(1)).clone()); - } - else - { - returnList.add(obj.get(1)); + data = data.clone(); } + returnList.add(data); returnPathToNames.add(returnList); } @@ -1869,8 +1824,7 @@ public Collection getPathToNames() * TODO: implement output for currently unsupported options(name * constraints)
      *
      - * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, + * Uses {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, * {@link org.bouncycastle.asn1.x509.KeyPurposeId KeyPurposeId} * * @return a String describing the contents of the @@ -1900,19 +1854,13 @@ public String toString() { if (subjectKeyID != null) { - ByteArrayInputStream inStream = new ByteArrayInputStream( - subjectKeyID); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object derObject = derInStream.readObject(); + ASN1Object derObject = ASN1Primitive.fromByteArray(subjectKeyID); sb.append(" Subject Key Identifier: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } if (authorityKeyID != null) { - ByteArrayInputStream inStream = new ByteArrayInputStream( - authorityKeyID); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object derObject = derInStream.readObject(); + ASN1Object derObject = ASN1Primitive.fromByteArray(authorityKeyID); sb.append(" Authority Key Identifier: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } @@ -1965,10 +1913,7 @@ public String toString() while (iter.hasNext()) { obj = (List)iter.next(); - ByteArrayInputStream inStream = new ByteArrayInputStream( - (byte[])obj.get(1)); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object derObject = derInStream.readObject(); + ASN1Object derObject = ASN1Primitive.fromByteArray((byte[])obj.get(1)); sb.append(" Type: ").append(obj.get(0)).append(" Data: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } @@ -1989,10 +1934,7 @@ public String toString() while (iter.hasNext()) { obj = (List)iter.next(); - ByteArrayInputStream inStream = new ByteArrayInputStream( - (byte[])obj.get(1)); - ASN1InputStream derInStream = new ASN1InputStream(inStream); - ASN1Object derObject = derInStream.readObject(); + ASN1Object derObject = ASN1Primitive.fromByteArray((byte[])obj.get(1)); sb.append(" Type: ").append(obj.get(0)).append(" Data: ") .append(ASN1Dump.dumpAsString(derObject)).append('\n'); } @@ -2012,11 +1954,10 @@ public String toString() *
      * TODO: implement missing tests (name constraints and path to names)
      *
      - * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream}, - * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, + * Uses {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}, * {@link org.bouncycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier}, * {@link org.bouncycastle.asn1.ASN1Object ASN1Object}, - * {@link org.bouncycastle.asn1.DERGeneralizedTime DERGeneralizedTime}, + * {@link org.bouncycastle.asn1.ASN1GeneralizedTime ASN1GeneralizedTime}, * {@link org.bouncycastle.asn1.x509.X509Name X509Name}, * {@link org.bouncycastle.asn1.x509.X509Extensions X509Extensions}, * {@link org.bouncycastle.asn1.x509.ExtendedKeyUsage ExtendedKeyUsage}, @@ -2047,8 +1988,7 @@ public boolean match(Certificate cert) { return false; } - if (serialNumber != null - && !serialNumber.equals(certX509.getSerialNumber())) + if (serialNumber != null && !serialNumber.equals(certX509.getSerialNumber())) { return false; } @@ -2056,16 +1996,14 @@ public boolean match(Certificate cert) { if (issuerDNX509 != null) { - if (!issuerDNX509.equals(PrincipalUtil - .getIssuerX509Principal(certX509), true)) + if (!issuerDNX509.equals(PrincipalUtil.getIssuerX509Principal(certX509), true)) { return false; } } if (subjectDNX509 != null) { - if (!subjectDNX509.equals(PrincipalUtil - .getSubjectX509Principal(certX509), true)) + if (!subjectDNX509.equals(PrincipalUtil.getSubjectX509Principal(certX509), true)) { return false; } @@ -2077,19 +2015,14 @@ public boolean match(Certificate cert) } if (subjectKeyID != null) { - byte[] data = certX509 - .getExtensionValue(X509Extensions.SubjectKeyIdentifier - .getId()); + byte[] data = certX509.getExtensionValue(X509Extensions.SubjectKeyIdentifier.getId()); if (data == null) { return false; } try { - ByteArrayInputStream inStream = new ByteArrayInputStream(data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - byte[] testData = ((ASN1OctetString)derInputStream.readObject()) - .getOctets(); + byte[] testData = ASN1OctetString.getInstance(data).getOctets(); if (!Arrays.equals(subjectKeyID, testData)) { return false; @@ -2102,19 +2035,14 @@ public boolean match(Certificate cert) } if (authorityKeyID != null) { - byte[] data = certX509 - .getExtensionValue(X509Extensions.AuthorityKeyIdentifier - .getId()); + byte[] data = certX509.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (data == null) { return false; } try { - ByteArrayInputStream inStream = new ByteArrayInputStream(data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - byte[] testData = ((ASN1OctetString)derInputStream.readObject()) - .getOctets(); + byte[] testData = ASN1OctetString.getInstance(data).getOctets(); if (!Arrays.equals(authorityKeyID, testData)) { return false; @@ -2142,31 +2070,19 @@ public boolean match(Certificate cert) { try { - byte[] data = certX509 - .getExtensionValue(X509Extensions.PrivateKeyUsagePeriod - .getId()); + byte[] data = certX509.getExtensionValue(X509Extensions.PrivateKeyUsagePeriod.getId()); if (data != null) { - ByteArrayInputStream inStream = new ByteArrayInputStream( - data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - inStream = new ByteArrayInputStream( - ((ASN1OctetString)derInputStream.readObject()) - .getOctets()); - derInputStream = new ASN1InputStream(inStream); // TODO fix this, Sequence contains tagged objects - ASN1Sequence derObject = (ASN1Sequence)derInputStream - .readObject(); - ASN1GeneralizedTime derDate = ASN1GeneralizedTime - .getInstance(derObject.getObjectAt(0)); - SimpleDateFormat dateF = new SimpleDateFormat( - "yyyyMMddHHmmssZ"); + ASN1Sequence derObject = ASN1Sequence.getInstance( + ASN1OctetString.getInstance(data).getOctets()); + ASN1GeneralizedTime derDate = ASN1GeneralizedTime.getInstance(derObject.getObjectAt(0)); + SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssZ"); if (privateKeyValid.before(dateF.parse(derDate.getTime()))) { return false; } - derDate = ASN1GeneralizedTime.getInstance(derObject - .getObjectAt(1)); + derDate = ASN1GeneralizedTime.getInstance(derObject.getObjectAt(1)); if (privateKeyValid.after(dateF.parse(derDate.getTime()))) { return false; @@ -2182,7 +2098,8 @@ public boolean match(Certificate cert) { try { - SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(certX509.getPublicKey().getEncoded()); + SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance( + certX509.getPublicKey().getEncoded()); AlgorithmIdentifier algInfo = publicKeyInfo.getAlgorithmId(); if (!algInfo.getAlgorithm().equals(subjectKeyAlgID)) { @@ -2196,8 +2113,7 @@ public boolean match(Certificate cert) } if (subjectPublicKeyByte != null) { - if (!Arrays.equals(subjectPublicKeyByte, certX509.getPublicKey() - .getEncoded())) + if (!Arrays.equals(subjectPublicKeyByte, certX509.getPublicKey().getEncoded())) { return false; } @@ -2228,21 +2144,14 @@ public boolean match(Certificate cert) { try { - byte[] data = certX509 - .getExtensionValue(X509Extensions.ExtendedKeyUsage - .getId()); + byte[] data = certX509.getExtensionValue(X509Extensions.ExtendedKeyUsage.getId()); if (data != null) { - ByteArrayInputStream inStream = new ByteArrayInputStream( - data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - ExtendedKeyUsage extendedKeyUsage = ExtendedKeyUsage.getInstance( - derInputStream.readObject()); + ExtendedKeyUsage extendedKeyUsage = ExtendedKeyUsage.getInstance(data); tempIter = keyPurposeSet.iterator(); while (tempIter.hasNext()) { - if (!extendedKeyUsage - .hasKeyPurposeId((KeyPurposeId)tempIter.next())) + if (!extendedKeyUsage.hasKeyPurposeId((KeyPurposeId)tempIter.next())) { return false; } @@ -2270,30 +2179,21 @@ public boolean match(Certificate cert) { try { - byte[] data = certX509 - .getExtensionValue(X509Extensions.CertificatePolicies - .getId()); + byte[] data = certX509.getExtensionValue(X509Extensions.CertificatePolicies.getId()); if (data == null) { return false; } if (!policyOID.isEmpty()) { - ByteArrayInputStream inStream = new ByteArrayInputStream( - data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - inStream = new ByteArrayInputStream( - ((ASN1OctetString)derInputStream.readObject()) - .getOctets()); - derInputStream = new ASN1InputStream(inStream); - Enumeration policySequence = ((ASN1Sequence)derInputStream - .readObject()).getObjects(); + ASN1Sequence seq = ASN1Sequence.getInstance( + ASN1OctetString.getInstance(data).getOctets()); + Enumeration policySequence = seq.getObjects(); ASN1Sequence policyObject; boolean test = false; while (policySequence.hasMoreElements() && !test) { - policyObject = (ASN1Sequence)policySequence - .nextElement(); + policyObject = (ASN1Sequence)policySequence.nextElement(); if (policyOID.contains(policyObject.getObjectAt(0))) { test = true; @@ -2314,40 +2214,24 @@ public boolean match(Certificate cert) { try { - byte[] data = certX509 - .getExtensionValue(X509Extensions.SubjectAlternativeName - .getId()); + byte[] data = certX509.getExtensionValue(X509Extensions.SubjectAlternativeName.getId()); if (data == null) { return false; } - ByteArrayInputStream inStream = new ByteArrayInputStream(data); - ASN1InputStream derInputStream = new ASN1InputStream(inStream); - inStream = new ByteArrayInputStream( - ((ASN1OctetString)derInputStream.readObject()) - .getOctets()); - derInputStream = new ASN1InputStream(inStream); - Enumeration altNamesSequence = ((ASN1Sequence)derInputStream - .readObject()).getObjects(); - ASN1TaggedObject altNameObject; + ASN1Sequence seq = ASN1Sequence.getInstance( + ASN1OctetString.getInstance(data).getOctets()); + Enumeration altNamesSequence = seq.getObjects(); boolean test = false; Set testSet = new HashSet(subjectAltNamesByte); - List testList; - ASN1Object derData; - ByteArrayOutputStream outStream; - ASN1OutputStream derOutStream; while (altNamesSequence.hasMoreElements() && !test) { - altNameObject = (ASN1TaggedObject)altNamesSequence - .nextElement(); - testList = new ArrayList(2); + // TODO Should this be requiring explicit tagging? + ASN1TaggedObject altNameObject = ASN1TaggedObject.getInstance(altNamesSequence.nextElement(), + BERTags.CONTEXT_SPECIFIC); + List testList = new ArrayList(2); testList.add(Integers.valueOf(altNameObject.getTagNo())); - derData = altNameObject.getObject(); - outStream = new ByteArrayOutputStream(); - derOutStream = ASN1OutputStream.create(outStream, ASN1Encoding.DER); - derOutStream.writeObject(derData); - derOutStream.close(); - testList.add(outStream.toByteArray()); + testList.add(altNameObject.getBaseObject().getEncoded(ASN1Encoding.DER)); if (testSet.remove(testList)) { @@ -2401,8 +2285,7 @@ public Object clone() } if (subjectPublicKeyByte != null) { - copy.subjectPublicKeyByte = (byte[])subjectPublicKeyByte - .clone(); + copy.subjectPublicKeyByte = (byte[])subjectPublicKeyByte.clone(); } if (keyUsage != null) { @@ -2410,22 +2293,16 @@ public Object clone() } if (keyPurposeSet != null) { - copy.keyPurposeSet = new HashSet(keyPurposeSet); + copy.keyPurposeSet = keyPurposeSet; } if (policy != null) { - copy.policy = new HashSet(policy); - copy.policyOID = new HashSet(); - Iterator iter = policyOID.iterator(); - while (iter.hasNext()) - { - copy.policyOID.add(new ASN1ObjectIdentifier( - ((ASN1ObjectIdentifier)iter.next()).getId())); - } + copy.policy = policy; + copy.policyOID = policyOID; } if (subjectAltNames != null) { - copy.subjectAltNames = new HashSet(getSubjectAlternativeNames()); + copy.subjectAltNames = getSubjectAlternativeNames(); Iterator iter = subjectAltNamesByte.iterator(); List obj; List cloneObj; @@ -2440,7 +2317,7 @@ public Object clone() } if (pathToNames != null) { - copy.pathToNames = new HashSet(getPathToNames()); + copy.pathToNames = getPathToNames(); Iterator iter = pathToNamesByte.iterator(); List obj; List cloneObj; diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java b/prov/src/main/jdk1.3/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java index 209e993e25..9a60c755c3 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java @@ -13,14 +13,13 @@ import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; -import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.misc.CAST5CBCParameters; +import org.bouncycastle.internal.asn1.misc.CAST5CBCParameters; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.RC2CBCParameter; import org.bouncycastle.jce.spec.IESParameterSpec; diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jce/provider/X509CertificateObject.java b/prov/src/main/jdk1.3/org/bouncycastle/jce/provider/X509CertificateObject.java index a8f179e07c..21bae59d99 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jce/provider/X509CertificateObject.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jce/provider/X509CertificateObject.java @@ -42,10 +42,10 @@ import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; -import org.bouncycastle.asn1.misc.NetscapeCertType; -import org.bouncycastle.asn1.misc.NetscapeRevocationURL; -import org.bouncycastle.asn1.misc.VerisignCzagExtension; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.NetscapeCertType; +import org.bouncycastle.internal.asn1.misc.NetscapeRevocationURL; +import org.bouncycastle.internal.asn1.misc.VerisignCzagExtension; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.RFC4519Style; diff --git a/prov/src/main/jdk1.3/org/bouncycastle/pqc/jcajce/provider/kyber/KyberCipherSpi.java b/prov/src/main/jdk1.3/org/bouncycastle/pqc/jcajce/provider/kyber/KyberCipherSpi.java index 1994e1f3cf..b5903870fc 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/pqc/jcajce/provider/kyber/KyberCipherSpi.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/pqc/jcajce/provider/kyber/KyberCipherSpi.java @@ -24,8 +24,8 @@ import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.jcajce.spec.KEMParameterSpec; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKEMExtractor; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKEMGenerator; +import org.bouncycastle.pqc.crypto.mlkem.KyberKEMExtractor; +import org.bouncycastle.pqc.crypto.mlkem.KyberKEMGenerator; import org.bouncycastle.pqc.jcajce.provider.util.WrapUtil; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Exceptions; diff --git a/prov/src/main/jdk1.3/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyGeneratorSpi.java b/prov/src/main/jdk1.3/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyGeneratorSpi.java index 4896fd4325..2962f97d02 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyGeneratorSpi.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/pqc/jcajce/provider/kyber/KyberKeyGeneratorSpi.java @@ -12,8 +12,8 @@ import org.bouncycastle.jcajce.SecretKeyWithEncapsulation; import org.bouncycastle.jcajce.spec.KEMExtractSpec; import org.bouncycastle.jcajce.spec.KEMGenerateSpec; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKEMExtractor; -import org.bouncycastle.pqc.crypto.crystals.kyber.KyberKEMGenerator; +import org.bouncycastle.pqc.crypto.mlkem.KyberKEMExtractor; +import org.bouncycastle.pqc.crypto.mlkem.KyberKEMGenerator; import org.bouncycastle.util.Arrays; public class KyberKeyGeneratorSpi diff --git a/prov/src/main/jdk1.3/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeCipherSpi.java b/prov/src/main/jdk1.3/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeCipherSpi.java index 309a8f0a1e..5f2f4dce8f 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeCipherSpi.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeCipherSpi.java @@ -298,7 +298,7 @@ protected Key engineUnwrap( return rv; } catch (IllegalArgumentException e) - { e.printStackTrace(); + { throw new NoSuchAlgorithmException("unable to extract KTS secret: " + e.getMessage()); } catch (InvalidCipherTextException e) diff --git a/prov/src/main/jdk1.3/org/bouncycastle/x509/X509Util.java b/prov/src/main/jdk1.3/org/bouncycastle/x509/X509Util.java index 7815c1144f..c275362438 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/x509/X509Util.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/x509/X509Util.java @@ -25,7 +25,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/CompositePrivateKey.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/CompositePrivateKey.java index bfefbef0fb..e7ae707d2d 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/CompositePrivateKey.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/CompositePrivateKey.java @@ -9,7 +9,7 @@ import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/CompositePublicKey.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/CompositePublicKey.java index c5d56d19a4..d2caf0f044 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/CompositePublicKey.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/CompositePublicKey.java @@ -9,7 +9,7 @@ import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; @@ -81,6 +81,11 @@ public byte[] getEncoded() } } + public AlgorithmIdentifier getAlgorithmIdentifier() + { + return null; + } + public int hashCode() { return keys.hashCode(); diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ECGOST.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ECGOST.java index eb07ca664a..8b29e857e1 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ECGOST.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ECGOST.java @@ -1,7 +1,7 @@ package org.bouncycastle.jcajce.provider.asymmetric; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.ecgost.KeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java index da00d7736d..fa67a2b7d5 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java @@ -36,7 +36,7 @@ protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec) X9ECParameters params = ECNamedCurveTable.getByName(ecGenParameterSpec.getName()); curveName = ecGenParameterSpec.getName(); - ecParameterSpec = new ECParameterSpec(params.getCurve(), params.getG(), params.getN(), params.getH(), params.getSeed()); + ecParameterSpec = new ECNamedCurveParameterSpec(curveName, params.getCurve(), params.getG(), params.getN(), params.getH(), params.getSeed()); } else if (algorithmParameterSpec instanceof ECParameterSpec) { diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java index bd4c4a81fc..6df1bf6d2d 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java @@ -20,10 +20,12 @@ import org.bouncycastle.asn1.sec.ECPrivateKeyStructure; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.crypto.params.ECNamedDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; @@ -52,6 +54,7 @@ public class BCECPrivateKey private transient ProviderConfiguration configuration; private transient ASN1BitString publicKey; + private transient ECPrivateKeyParameters baseKey; private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); protected BCECPrivateKey() @@ -66,6 +69,7 @@ protected BCECPrivateKey() this.algorithm = key.getAlgorithm(); this.ecSpec = key.getParameters(); this.configuration = configuration; + this.baseKey = convertToBaseKey(this); } public BCECPrivateKey( @@ -77,6 +81,7 @@ public BCECPrivateKey( this.d = spec.getD(); this.ecSpec = spec.getParams(); this.configuration = configuration; + this.baseKey = convertToBaseKey(this); } public BCECPrivateKey( @@ -106,7 +111,8 @@ public BCECPrivateKey( this.ecSpec = spec; } - publicKey = getPublicKeyDetails(pubKey); + this.publicKey = getPublicKeyDetails(pubKey); + this.baseKey = convertToBaseKey(this); } public BCECPrivateKey( @@ -118,6 +124,7 @@ public BCECPrivateKey( this.d = params.getD(); this.ecSpec = null; this.configuration = configuration; + this.baseKey = convertToBaseKey(this); } public BCECPrivateKey( @@ -199,6 +206,7 @@ else if (params.isImplicitlyCA()) this.d = ec.getKey(); this.publicKey = ec.getPublicKey(); } + this.baseKey = convertToBaseKey(this); } public String getAlgorithm() @@ -260,6 +268,11 @@ public byte[] getEncoded() } } + ECPrivateKeyParameters engineGetKeyParameters() + { + return baseKey; + } + public ECParameterSpec getParams() { return (ECParameterSpec)ecSpec; @@ -269,7 +282,7 @@ public ECParameterSpec getParameters() { return (ECParameterSpec)ecSpec; } - + public BigInteger getD() { return d; @@ -292,7 +305,7 @@ public Enumeration getBagAttributeKeys() { return attrCarrier.getBagAttributeKeys(); } - + public void setPointFormat(String style) { withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); @@ -366,4 +379,31 @@ private void writeObject( out.writeObject(this.getEncoded()); } + + private static ECPrivateKeyParameters convertToBaseKey(BCECPrivateKey key) + { + org.bouncycastle.jce.interfaces.ECPrivateKey k = (org.bouncycastle.jce.interfaces.ECPrivateKey)key; + org.bouncycastle.jce.spec.ECParameterSpec s = k.getParameters(); + + if (s == null) + { + s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); + } + + if (k.getParameters() instanceof ECNamedCurveParameterSpec) + { + String name = ((ECNamedCurveParameterSpec)k.getParameters()).getName(); + if (name != null) + { + return new ECPrivateKeyParameters( + k.getD(), + new ECNamedDomainParameters(ECNamedCurveTable.getOID(name), + s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); + } + } + + return new ECPrivateKeyParameters( + k.getD(), + new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); + } } diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java index 2d9de7af30..d36ea9194b 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java @@ -2,6 +2,7 @@ import java.math.BigInteger; import java.security.InvalidKeyException; +import java.security.PrivateKey; import java.security.PublicKey; import java.util.Map; @@ -20,6 +21,13 @@ class ECUtils { + static AsymmetricKeyParameter generatePrivateKeyParameter( + PrivateKey key) + throws InvalidKeyException + { + return (key instanceof BCECPrivateKey) ? ((BCECPrivateKey)key).engineGetKeyParameters() : ECUtil.generatePrivateKeyParameter(key); + } + static AsymmetricKeyParameter generatePublicKeyParameter( PublicKey key) throws InvalidKeyException diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java index 1507cfaa9f..9c3baf34c6 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java @@ -64,7 +64,7 @@ protected void doEngineInitSign( { CipherParameters param; - param = ECUtil.generatePrivateKeyParameter(privateKey); + param = ECUtils.generatePrivateKeyParameter(privateKey); digest.reset(); diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java index 239dc0be88..4ac56c876e 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi.java @@ -16,7 +16,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java index 0278bc2ea3..05a8382128 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi.java @@ -6,7 +6,7 @@ import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.CryptoServicesRegistrar; diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java index b3fd4ef09a..8f7324dd70 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java @@ -329,11 +329,22 @@ public static X9ECParameters getNamedCurveByOid( public static X9ECParameters getNamedCurveByName( String curveName) { - X9ECParameters params = CustomNamedCurves.getByName(curveName); + String name; + + if (curveName.indexOf(' ') > 0) + { + name = curveName.substring(curveName.indexOf(' ') + 1); + } + else + { + name = curveName; + } + + X9ECParameters params = CustomNamedCurves.getByName(name); if (params == null) { - params = ECNamedCurveTable.getByName(curveName); + params = ECNamedCurveTable.getByName(name); } return params; diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java index 37647b803d..d6d85fd853 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java @@ -58,10 +58,10 @@ import org.bouncycastle.asn1.bc.PbkdMacIntegrityCheck; import org.bouncycastle.asn1.bc.SecretKeyData; import org.bouncycastle.internal.asn1.cms.CCMParameters; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; -import org.bouncycastle.asn1.misc.ScryptParams; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.ScryptParams; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.EncryptionScheme; import org.bouncycastle.asn1.pkcs.KeyDerivationFunc; diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java index 0b12b92b67..b107cf27d7 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java @@ -7,14 +7,20 @@ import org.bouncycastle.util.Arrays; /** - * SP 800-56C Hybrid Value spec, to allow the secret in a key agreement to be - * created as "Z | T" where T is some other secret value as described in Section 2. + * SP 800-56C Hybrid Value spec, by default to allow the secret in a key agreement to be + * created as "Z | T" where T is some other secret value as described in Section 2. If the + * value doPrepend is set to true the spec will be used to calculate "T | Z" instead. + *

      + * Get methods throw IllegalStateException if destroy() is called. + *

      */ public class HybridValueParameterSpec implements AlgorithmParameterSpec, Destroyable { private final AtomicBoolean hasBeenDestroyed = new AtomicBoolean(false); + private final boolean doPrepend; + private volatile byte[] t; private volatile AlgorithmParameterSpec baseSpec; @@ -26,9 +32,31 @@ public class HybridValueParameterSpec * @param baseSpec the base spec for the agreements KDF. */ public HybridValueParameterSpec(byte[] t, AlgorithmParameterSpec baseSpec) + { + this(t, false, baseSpec); + } + + /** + * Create a spec with T set to t and the spec for the KDF in the agreement to baseSpec. + * Note: the t value is not copied. + * @param t a shared secret to be concatenated with the agreement's Z value. + * @param baseSpec the base spec for the agreements KDF. + */ + public HybridValueParameterSpec(byte[] t, boolean doPrepend, AlgorithmParameterSpec baseSpec) { this.t = t; this.baseSpec = baseSpec; + this.doPrepend = doPrepend; + } + + /** + * Return whether or not T should be prepended. + * + * @return true if T to be prepended, false otherwise. + */ + public boolean isPrependedT() + { + return doPrepend; } /** @@ -38,9 +66,11 @@ public HybridValueParameterSpec(byte[] t, AlgorithmParameterSpec baseSpec) */ public byte[] getT() { + byte[] tVal = t; + checkDestroyed(); - return t; + return tVal; } /** @@ -50,11 +80,19 @@ public byte[] getT() */ public AlgorithmParameterSpec getBaseParameterSpec() { + AlgorithmParameterSpec rv = this.baseSpec; + checkDestroyed(); - return baseSpec; + return rv; } + /** + * Return true if the destroy() method is called and the contents are + * erased. + * + * @return true if destroyed, false otherwise. + */ public boolean isDestroyed() { return this.hasBeenDestroyed.get(); diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/prov/src/main/jdk1.4/org/bouncycastle/jce/provider/BouncyCastleProvider.java index f9e139e207..f2cc535c01 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jce/provider/BouncyCastleProvider.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jce/provider/BouncyCastleProvider.java @@ -11,6 +11,7 @@ import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; @@ -21,6 +22,7 @@ import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; import org.bouncycastle.pqc.jcajce.provider.newhope.NHKeyFactorySpi; import org.bouncycastle.pqc.jcajce.provider.sphincs.Sphincs256KeyFactorySpi; +import org.bouncycastle.pqc.jcajce.provider.dilithium.DilithiumKeyFactorySpi; /** * To add the provider at runtime use: @@ -49,7 +51,7 @@ public final class BouncyCastleProvider extends Provider implements ConfigurableProvider { - private static String info = "BouncyCastle Security Provider v1.73"; + private static String info = "BouncyCastle Security Provider v1.78.1"; public static final String PROVIDER_NAME = "BC"; @@ -94,7 +96,7 @@ public final class BouncyCastleProvider extends Provider private static final String[] ASYMMETRIC_CIPHERS = { - "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145", "GM", "EdEC" + "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145", "GM", "EdEC", "SPHINCSPlus", "Dilithium", "Falcon", "NTRU" }; /* @@ -133,7 +135,7 @@ public final class BouncyCastleProvider extends Provider */ public BouncyCastleProvider() { - super(PROVIDER_NAME, 1.73, info); + super(PROVIDER_NAME, 1.7801, info); AccessController.doPrivileged(new PrivilegedAction() { @@ -233,6 +235,9 @@ private void loadPQCKeys() { addKeyInfoConverter(PQCObjectIdentifiers.sphincs256, new Sphincs256KeyFactorySpi()); addKeyInfoConverter(PQCObjectIdentifiers.newHope, new NHKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.dilithium2, new DilithiumKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.dilithium3, new DilithiumKeyFactorySpi()); + addKeyInfoConverter(BCObjectIdentifiers.dilithium5, new DilithiumKeyFactorySpi()); } public void setParameter(String parameterName, Object parameter) diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jce/provider/X509LDAPCertStoreSpi.java b/prov/src/main/jdk1.4/org/bouncycastle/jce/provider/X509LDAPCertStoreSpi.java new file mode 100644 index 0000000000..8e44ed5f81 --- /dev/null +++ b/prov/src/main/jdk1.4/org/bouncycastle/jce/provider/X509LDAPCertStoreSpi.java @@ -0,0 +1,532 @@ +package org.bouncycastle.jce.provider; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.cert.CRL; +import java.security.cert.CRLSelector; +import java.security.cert.CertSelector; +import java.security.cert.CertStoreException; +import java.security.cert.CertStoreParameters; +import java.security.cert.CertStoreSpi; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.cert.X509CRLSelector; +import java.security.cert.X509CertSelector; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.Set; + +import javax.naming.Context; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; +import javax.security.auth.x500.X500Principal; + +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.x509.CertificatePair; +import org.bouncycastle.jce.X509LDAPCertStoreParameters; + +/** + * This is a general purpose implementation to get X.509 certificates and CRLs + * from a LDAP location. + *

      + * At first a search is performed in the ldap*AttributeNames of the + * {@link org.bouncycastle.jce.X509LDAPCertStoreParameters} with the given + * information of the subject (for all kind of certificates) or issuer (for + * CRLs), respectively, if a X509CertSelector is given with that details. For + * CRLs, CA certificates and cross certificates a coarse search is made only for + * entries with that content to get more possibly matching results. + */ +public class X509LDAPCertStoreSpi + extends CertStoreSpi +{ + private static String[] FILTER_ESCAPE_TABLE = new String['\\' + 1]; + + static + { + // Filter encoding table ------------------------------------- + + // fill with char itself + for (char c = 0; c < FILTER_ESCAPE_TABLE.length; c++) + { + FILTER_ESCAPE_TABLE[c] = String.valueOf(c); + } + + // escapes (RFC2254) + FILTER_ESCAPE_TABLE['*'] = "\\2a"; + FILTER_ESCAPE_TABLE['('] = "\\28"; + FILTER_ESCAPE_TABLE[')'] = "\\29"; + FILTER_ESCAPE_TABLE['\\'] = "\\5c"; + FILTER_ESCAPE_TABLE[0] = "\\00"; + } + + /** + * Initial Context Factory. + */ + private static String LDAP_PROVIDER = "com.sun.jndi.ldap.LdapCtxFactory"; + + /** + * Processing referrals.. + */ + private static String REFERRALS_IGNORE = "ignore"; + + /** + * Security level to be used for LDAP connections. + */ + private static final String SEARCH_SECURITY_LEVEL = "none"; + + /** + * Package Prefix for loading URL context factories. + */ + private static final String URL_CONTEXT_PREFIX = "com.sun.jndi.url"; + + private X509LDAPCertStoreParameters params; + + public X509LDAPCertStoreSpi(CertStoreParameters params) + throws InvalidAlgorithmParameterException + { + super(params); + + if (!(params instanceof X509LDAPCertStoreParameters)) + { + throw new InvalidAlgorithmParameterException( + X509LDAPCertStoreSpi.class.getName() + ": parameter must be a " + X509LDAPCertStoreParameters.class.getName() + " object\n" + + params.toString()); + } + + this.params = (X509LDAPCertStoreParameters)params; + } + + private DirContext connectLDAP() + throws NamingException + { + Properties props = new Properties(); + props.setProperty(Context.INITIAL_CONTEXT_FACTORY, LDAP_PROVIDER); + props.setProperty(Context.BATCHSIZE, "0"); + + props.setProperty(Context.PROVIDER_URL, params.getLdapURL()); + props.setProperty(Context.URL_PKG_PREFIXES, URL_CONTEXT_PREFIX); + props.setProperty(Context.REFERRAL, REFERRALS_IGNORE); + props.setProperty(Context.SECURITY_AUTHENTICATION, + SEARCH_SECURITY_LEVEL); + + DirContext ctx = new InitialDirContext(props); + return ctx; + } + + private String parseDN(String subject, String subjectAttributeName) + { + String temp = subject; + int begin = temp.toLowerCase().indexOf( + subjectAttributeName.toLowerCase()); + temp = temp.substring(begin + subjectAttributeName.length()); + int end = temp.indexOf(','); + if (end == -1) + { + end = temp.length(); + } + while (temp.charAt(end - 1) == '\\') + { + end = temp.indexOf(',', end + 1); + if (end == -1) + { + end = temp.length(); + } + } + temp = temp.substring(0, end); + begin = temp.indexOf('='); + temp = temp.substring(begin + 1); + if (temp.charAt(0) == ' ') + { + temp = temp.substring(1); + } + if (temp.startsWith("\"")) + { + temp = temp.substring(1); + } + if (temp.endsWith("\"")) + { + temp = temp.substring(0, temp.length() - 1); + } + return filterEncode(temp); + } + + public Collection engineGetCertificates(CertSelector selector) + throws CertStoreException + { + if (!(selector instanceof X509CertSelector)) + { + throw new CertStoreException("selector is not a X509CertSelector"); + } + X509CertSelector xselector = (X509CertSelector)selector; + + Set certSet = new HashSet(); + + Set set = getEndCertificates(xselector); + set.addAll(getCACertificates(xselector)); + set.addAll(getCrossCertificates(xselector)); + + Iterator it = set.iterator(); + + try + { + CertificateFactory cf = CertificateFactory.getInstance("X.509", + BouncyCastleProvider.PROVIDER_NAME); + while (it.hasNext()) + { + byte[] bytes = (byte[])it.next(); + if (bytes == null || bytes.length == 0) + { + continue; + } + + List bytesList = new ArrayList(); + bytesList.add(bytes); + + try + { + CertificatePair pair = CertificatePair + .getInstance(new ASN1InputStream(bytes) + .readObject()); + bytesList.clear(); + if (pair.getForward() != null) + { + bytesList.add(pair.getForward().getEncoded()); + } + if (pair.getReverse() != null) + { + bytesList.add(pair.getReverse().getEncoded()); + } + } + catch (IOException e) + { + + } + catch (IllegalArgumentException e) + { + + } + for (Iterator it2 = bytesList.iterator(); it2.hasNext(); ) + { + ByteArrayInputStream bIn = new ByteArrayInputStream( + (byte[])it2.next()); + try + { + Certificate cert = cf.generateCertificate(bIn); + // System.out.println(((X509Certificate) + // cert).getSubjectX500Principal()); + if (xselector.match(cert)) + { + certSet.add(cert); + } + } + catch (Exception e) + { + + } + } + } + } + catch (Exception e) + { + throw new CertStoreException( + "certificate cannot be constructed from LDAP result: " + e); + } + + return certSet; + } + + private Set certSubjectSerialSearch(X509CertSelector xselector, + String[] attrs, String attrName, String subjectAttributeName) + throws CertStoreException + { + Set set = new HashSet(); + try + { + if (xselector.getSubjectAsBytes() != null + || xselector.getSubjectAsString() != null + || xselector.getCertificate() != null) + { + String subject = null; + String serial = null; + if (xselector.getCertificate() != null) + { + subject = xselector.getCertificate() + .getSubjectX500Principal().getName("RFC1779"); + serial = xselector.getCertificate().getSerialNumber() + .toString(); + } + else + { + if (xselector.getSubjectAsBytes() != null) + { + subject = new X500Principal(xselector + .getSubjectAsBytes()).getName("RFC1779"); + } + else + { + subject = xselector.getSubjectAsString(); + } + } + String attrValue = parseDN(subject, subjectAttributeName); + set.addAll(search(attrName, "*" + attrValue + "*", attrs)); + if (serial != null + && params.getSearchForSerialNumberIn() != null) + { + attrValue = serial; + attrName = params.getSearchForSerialNumberIn(); + set.addAll(search(attrName, "*" + attrValue + "*", attrs)); + } + } + else + { + set.addAll(search(attrName, "*", attrs)); + } + } + catch (IOException e) + { + throw new CertStoreException("exception processing selector: " + e); + } + + return set; + } + + private Set getEndCertificates(X509CertSelector xselector) + throws CertStoreException + { + String[] attrs = {params.getUserCertificateAttribute()}; + String attrName = params.getLdapUserCertificateAttributeName(); + String subjectAttributeName = params.getUserCertificateSubjectAttributeName(); + + Set set = certSubjectSerialSearch(xselector, attrs, attrName, + subjectAttributeName); + return set; + } + + private Set getCACertificates(X509CertSelector xselector) + throws CertStoreException + { + String[] attrs = {params.getCACertificateAttribute()}; + String attrName = params.getLdapCACertificateAttributeName(); + String subjectAttributeName = params + .getCACertificateSubjectAttributeName(); + Set set = certSubjectSerialSearch(xselector, attrs, attrName, + subjectAttributeName); + + if (set.isEmpty()) + { + set.addAll(search(null, "*", attrs)); + } + + return set; + } + + private Set getCrossCertificates(X509CertSelector xselector) + throws CertStoreException + { + String[] attrs = {params.getCrossCertificateAttribute()}; + String attrName = params.getLdapCrossCertificateAttributeName(); + String subjectAttributeName = params + .getCrossCertificateSubjectAttributeName(); + Set set = certSubjectSerialSearch(xselector, attrs, attrName, + subjectAttributeName); + + if (set.isEmpty()) + { + set.addAll(search(null, "*", attrs)); + } + + return set; + } + + public Collection engineGetCRLs(CRLSelector selector) + throws CertStoreException + { + String[] attrs = {params.getCertificateRevocationListAttribute()}; + if (!(selector instanceof X509CRLSelector)) + { + throw new CertStoreException("selector is not a X509CRLSelector"); + } + X509CRLSelector xselector = (X509CRLSelector)selector; + + Set crlSet = new HashSet(); + + String attrName = params.getLdapCertificateRevocationListAttributeName(); + Set set = new HashSet(); + + if (xselector.getIssuerNames() != null) + { + for (Iterator it = xselector.getIssuerNames().iterator(); it + .hasNext(); ) + { + Object o = it.next(); + String attrValue = null; + if (o instanceof String) + { + String issuerAttributeName = params + .getCertificateRevocationListIssuerAttributeName(); + attrValue = parseDN((String)o, issuerAttributeName); + } + else + { + String issuerAttributeName = params + .getCertificateRevocationListIssuerAttributeName(); + attrValue = parseDN(new X500Principal((byte[])o) + .getName("RFC1779"), issuerAttributeName); + } + set.addAll(search(attrName, "*" + attrValue + "*", attrs)); + } + } + else + { + set.addAll(search(attrName, "*", attrs)); + } + set.addAll(search(null, "*", attrs)); + Iterator it = set.iterator(); + + try + { + CertificateFactory cf = CertificateFactory.getInstance("X.509", + BouncyCastleProvider.PROVIDER_NAME); + while (it.hasNext()) + { + CRL crl = cf.generateCRL(new ByteArrayInputStream((byte[])it + .next())); + if (xselector.match(crl)) + { + crlSet.add(crl); + } + } + } + catch (Exception e) + { + throw new CertStoreException( + "CRL cannot be constructed from LDAP result " + e); + } + + return crlSet; + } + + /** + * Escape a value for use in a filter. + * + * @param value the value to escape. + * @return a properly escaped representation of the supplied value. + */ + private String filterEncode(String value) + { + if (value == null) + { + return null; + } + + // make buffer roomy + StringBuffer encodedValue = new StringBuffer(value.length() * 2); + + int length = value.length(); + + for (int i = 0; i < length; i++) + { + char c = value.charAt(i); + + if (c < FILTER_ESCAPE_TABLE.length) + { + encodedValue.append(FILTER_ESCAPE_TABLE[c]); + } + else + { + // default: add the char + encodedValue.append(c); + } + } + + return encodedValue.toString(); + } + + /** + * Returns a Set of byte arrays with the certificate or CRL encodings. + * + * @param attributeName The attribute name to look for in the LDAP. + * @param attributeValue The value the attribute name must have. + * @param attrs The attributes in the LDAP which hold the certificate, + * certificate pair or CRL in a found entry. + * @return Set of byte arrays with the certificate encodings. + */ + private Set search(String attributeName, String attributeValue, + String[] attrs) + throws CertStoreException + { + String filter = attributeName + "=" + attributeValue; +// System.out.println(filter); + if (attributeName == null) + { + filter = null; + } + DirContext ctx = null; + Set set = new HashSet(); + try + { + ctx = connectLDAP(); + + SearchControls constraints = new SearchControls(); + constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); + constraints.setCountLimit(0); + for (int i = 0; i < attrs.length; i++) + { + String temp[] = new String[1]; + temp[0] = attrs[i]; + constraints.setReturningAttributes(temp); + + String filter2 = "(&(" + filter + ")(" + temp[0] + "=*))"; + if (filter == null) + { + filter2 = "(" + temp[0] + "=*)"; + } + NamingEnumeration results = ctx.search(params.getBaseDN(), + filter2, constraints); + while (results.hasMoreElements()) + { + SearchResult sr = (SearchResult)results.next(); + // should only be one attribute in the attribute set with + // one + // attribute value as byte array + NamingEnumeration enumeration = ((Attribute)(sr + .getAttributes().getAll().next())).getAll(); + while (enumeration.hasMore()) + { + Object o = enumeration.next(); + set.add(o); + } + } + } + } + catch (Exception e) + { + throw new CertStoreException( + "Error getting results from LDAP directory " + e); + } + finally + { + try + { + if (null != ctx) + { + ctx.close(); + } + } + catch (Exception e) + { + } + } + return set; + } +} diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jce/provider/X509SignatureUtil.java b/prov/src/main/jdk1.4/org/bouncycastle/jce/provider/X509SignatureUtil.java index a31d41904e..3338e07046 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jce/provider/X509SignatureUtil.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jce/provider/X509SignatureUtil.java @@ -11,7 +11,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; diff --git a/prov/src/main/jdk1.4/org/bouncycastle/pqc/jcajce/provider/dilithium/SignatureSpi.java b/prov/src/main/jdk1.4/org/bouncycastle/pqc/jcajce/provider/dilithium/SignatureSpi.java index 21648d4231..ff0ea3f809 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/pqc/jcajce/provider/dilithium/SignatureSpi.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/pqc/jcajce/provider/dilithium/SignatureSpi.java @@ -209,34 +209,4 @@ public Base5() super(new DilithiumSigner(), DilithiumParameters.dilithium5); } } - - public static class Base2_AES - extends SignatureSpi - { - public Base2_AES() - throws NoSuchAlgorithmException - { - super(new DilithiumSigner(), DilithiumParameters.dilithium2_aes); - } - } - - public static class Base3_AES - extends SignatureSpi - { - public Base3_AES() - throws NoSuchAlgorithmException - { - super(new DilithiumSigner(), DilithiumParameters.dilithium3_aes); - } - } - - public static class Base5_AES - extends SignatureSpi - { - public Base5_AES() - throws NoSuchAlgorithmException - { - super(new DilithiumSigner(), DilithiumParameters.dilithium5_aes); - } - } } diff --git a/prov/src/main/jdk1.9/module-info.java b/prov/src/main/jdk1.9/module-info.java index d5be9f09e5..3f9f09cd27 100644 --- a/prov/src/main/jdk1.9/module-info.java +++ b/prov/src/main/jdk1.9/module-info.java @@ -1,6 +1,7 @@ module org.bouncycastle.provider { requires java.sql; + requires java.logging; requires java.naming; provides java.security.Provider with org.bouncycastle.jce.provider.BouncyCastleProvider,org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; @@ -15,24 +16,10 @@ exports org.bouncycastle.asn1.anssi; exports org.bouncycastle.asn1.bc; exports org.bouncycastle.asn1.cryptopro; - exports org.bouncycastle.asn1.cryptlib; - exports org.bouncycastle.asn1.edec; exports org.bouncycastle.asn1.gm; - exports org.bouncycastle.asn1.gnu; - exports org.bouncycastle.asn1.iana; - exports org.bouncycastle.asn1.isara; - exports org.bouncycastle.asn1.iso; - exports org.bouncycastle.asn1.kisa; - exports org.bouncycastle.asn1.microsoft; - exports org.bouncycastle.asn1.misc; - exports org.bouncycastle.asn1.mozilla; exports org.bouncycastle.asn1.nist; - exports org.bouncycastle.asn1.nsri; - exports org.bouncycastle.asn1.ntt; exports org.bouncycastle.asn1.ocsp; - exports org.bouncycastle.asn1.oiw; exports org.bouncycastle.asn1.pkcs; - exports org.bouncycastle.asn1.rosstandart; exports org.bouncycastle.asn1.sec; exports org.bouncycastle.asn1.teletrust; exports org.bouncycastle.asn1.ua; @@ -76,6 +63,7 @@ exports org.bouncycastle.jcajce; exports org.bouncycastle.jcajce.io; exports org.bouncycastle.jcajce.provider.asymmetric; + exports org.bouncycastle.jcajce.provider.asymmetric.compositesignatures; exports org.bouncycastle.jcajce.provider.asymmetric.dh; exports org.bouncycastle.jcajce.provider.asymmetric.dsa; exports org.bouncycastle.jcajce.provider.asymmetric.dstu; @@ -124,7 +112,7 @@ exports org.bouncycastle.pqc.crypto.bike; exports org.bouncycastle.pqc.crypto.cmce; exports org.bouncycastle.pqc.crypto.crystals.dilithium; - exports org.bouncycastle.pqc.crypto.crystals.kyber; + exports org.bouncycastle.pqc.crypto.mlkem; exports org.bouncycastle.pqc.crypto.falcon; exports org.bouncycastle.pqc.crypto.frodo; exports org.bouncycastle.crypto.fpe; @@ -137,7 +125,6 @@ exports org.bouncycastle.pqc.crypto.picnic; exports org.bouncycastle.pqc.crypto.rainbow; exports org.bouncycastle.pqc.crypto.saber; - exports org.bouncycastle.pqc.legacy.crypto.sike; exports org.bouncycastle.pqc.crypto.sphincs; exports org.bouncycastle.pqc.crypto.sphincsplus; exports org.bouncycastle.pqc.crypto.util; diff --git a/prov/src/main/jdk21/org/bouncycastle/jcajce/provider/asymmetric/MLKEM.java b/prov/src/main/jdk21/org/bouncycastle/jcajce/provider/asymmetric/MLKEM.java new file mode 100644 index 0000000000..f8dc9c2d9f --- /dev/null +++ b/prov/src/main/jdk21/org/bouncycastle/jcajce/provider/asymmetric/MLKEM.java @@ -0,0 +1,60 @@ +package org.bouncycastle.jcajce.provider.asymmetric; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.jcajce.provider.asymmetric.mlkem.MLKEMKeyFactorySpi; +import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; + +public class MLKEM +{ + private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".mlkem."; + + public static class Mappings + extends AsymmetricAlgorithmProvider + { + public Mappings() + { + } + + public void configure(ConfigurableProvider provider) + { + provider.addAlgorithm("KeyFactory.ML-KEM", PREFIX + "MLKEMKeyFactorySpi"); + + addKeyFactoryAlgorithm(provider, "ML-KEM-512", PREFIX + "MLKEMKeyFactorySpi$MLKEM512", NISTObjectIdentifiers.id_alg_ml_kem_512, new MLKEMKeyFactorySpi.MLKEM512()); + addKeyFactoryAlgorithm(provider, "ML-KEM-768", PREFIX + "MLKEMKeyFactorySpi$MLKEM768", NISTObjectIdentifiers.id_alg_ml_kem_768, new MLKEMKeyFactorySpi.MLKEM768()); + addKeyFactoryAlgorithm(provider, "ML-KEM-1024", PREFIX + "MLKEMKeyFactorySpi$MLKEM1024", NISTObjectIdentifiers.id_alg_ml_kem_1024, new MLKEMKeyFactorySpi.MLKEM1024()); + + provider.addAlgorithm("KeyPairGenerator.ML-KEM", PREFIX + "MLKEMKeyPairGeneratorSpi"); + + addKeyPairGeneratorAlgorithm(provider, "ML-KEM-512", PREFIX + "MLKEMKeyPairGeneratorSpi$MLKEM512", NISTObjectIdentifiers.id_alg_ml_kem_512); + addKeyPairGeneratorAlgorithm(provider, "ML-KEM-768", PREFIX + "MLKEMKeyPairGeneratorSpi$MLKEM768", NISTObjectIdentifiers.id_alg_ml_kem_768); + addKeyPairGeneratorAlgorithm(provider, "ML-KEM-1024", PREFIX + "MLKEMKeyPairGeneratorSpi$MLKEM1024", NISTObjectIdentifiers.id_alg_ml_kem_1024); + + provider.addAlgorithm("KeyGenerator.ML-KEM", PREFIX + "MLKEMKeyGeneratorSpi"); + + addKeyGeneratorAlgorithm(provider, "ML-KEM-512", PREFIX + "MLKEMKeyGeneratorSpi$MLKEM512", NISTObjectIdentifiers.id_alg_ml_kem_512); + addKeyGeneratorAlgorithm(provider, "ML-KEM-768", PREFIX + "MLKEMKeyGeneratorSpi$MLKEM768", NISTObjectIdentifiers.id_alg_ml_kem_768); + addKeyGeneratorAlgorithm(provider, "ML-KEM-1024", PREFIX + "MLKEMKeyGeneratorSpi$MLKEM1024", NISTObjectIdentifiers.id_alg_ml_kem_1024); + + AsymmetricKeyInfoConverter keyFact = new MLKEMKeyFactorySpi(); + + provider.addAlgorithm("Cipher.ML-KEM", PREFIX + "MLKEMCipherSpi$Base"); + provider.addAlgorithm("Alg.Alias.Cipher." + (ASN1ObjectIdentifier) null, "ML-KEM"); + + addCipherAlgorithm(provider, "ML-KEM-512", PREFIX + "MLKEMCipherSpi$MLKEM512", NISTObjectIdentifiers.id_alg_ml_kem_512); + addCipherAlgorithm(provider, "ML-KEM-768", PREFIX + "MLKEMCipherSpi$MLKEM768", NISTObjectIdentifiers.id_alg_ml_kem_768); + addCipherAlgorithm(provider, "ML-KEM-1024", PREFIX + "MLKEMCipherSpi$MLKEM1024", NISTObjectIdentifiers.id_alg_ml_kem_1024); + + provider.addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_512, keyFact); + provider.addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_768, keyFact); + provider.addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_1024, keyFact); + + provider.addAlgorithm("Kem.ML-KEM", PREFIX + "MLKEMSpi"); + provider.addAlgorithm("Alg.Alias.Kem." + NISTObjectIdentifiers.id_alg_ml_kem_512, "ML-KEM"); + provider.addAlgorithm("Alg.Alias.Kem." + NISTObjectIdentifiers.id_alg_ml_kem_768, "ML-KEM"); + provider.addAlgorithm("Alg.Alias.Kem." + NISTObjectIdentifiers.id_alg_ml_kem_1024, "ML-KEM"); + } + } +} diff --git a/prov/src/main/jdk21/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMDecapsulatorSpi.java b/prov/src/main/jdk21/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMDecapsulatorSpi.java new file mode 100644 index 0000000000..5a3c0c1487 --- /dev/null +++ b/prov/src/main/jdk21/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMDecapsulatorSpi.java @@ -0,0 +1,90 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mlkem; + +import org.bouncycastle.jcajce.provider.asymmetric.mlkem.BCMLKEMPrivateKey; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor; +import org.bouncycastle.pqc.jcajce.provider.Util; + +import javax.crypto.DecapsulateException; +import javax.crypto.KEMSpi; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidKeyException; +import java.util.Arrays; +import java.util.Objects; + +public class MLKEMDecapsulatorSpi + implements KEMSpi.DecapsulatorSpi +{ + BCMLKEMPrivateKey privateKey; + KTSParameterSpec parameterSpec; + MLKEMExtractor kemExt; + + public MLKEMDecapsulatorSpi(BCMLKEMPrivateKey privateKey, KTSParameterSpec parameterSpec) + { + this.privateKey = privateKey; + this.parameterSpec = parameterSpec; + + this.kemExt = new MLKEMExtractor(privateKey.getKeyParams()); + } + + @Override + public SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, String algorithm) throws DecapsulateException + { + Objects.checkFromToIndex(from, to, engineSecretSize()); + Objects.requireNonNull(algorithm, "null algorithm"); + Objects.requireNonNull(encapsulation, "null encapsulation"); + + if (encapsulation.length != engineEncapsulationSize()) + { + throw new DecapsulateException("incorrect encapsulation size"); + } + + // if algorithm is Generic then use parameterSpec to wrap key + if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && + algorithm.equals("Generic")) + { + algorithm = parameterSpec.getKeyAlgorithmName(); + } + + // check spec algorithm mismatch provided algorithm + if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && + !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + { + throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + } + + // Only use KDF when ktsParameterSpec is provided + // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided + boolean useKDF = parameterSpec.getKdfAlgorithm() != null; + + byte[] secret = kemExt.extractSecret(encapsulation); + + if (useKDF) + { + try + { + secret = Util.makeKeyBytes(parameterSpec, secret); + } + catch (InvalidKeyException e) + { + throw new IllegalStateException(e); + } + } + byte[] secretKey = Arrays.copyOfRange(secret, from, to); + + return new SecretKeySpec(secretKey, algorithm); + } + + @Override + public int engineSecretSize() + { + return parameterSpec.getKeySize() / 8; + } + + @Override + public int engineEncapsulationSize() + { + return kemExt.getEncapsulationLength(); + } +} diff --git a/prov/src/main/jdk21/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMEncapsulatorSpi.java b/prov/src/main/jdk21/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMEncapsulatorSpi.java new file mode 100644 index 0000000000..8972072c23 --- /dev/null +++ b/prov/src/main/jdk21/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMEncapsulatorSpi.java @@ -0,0 +1,104 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mlkem; + +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.jcajce.provider.asymmetric.mlkem.BCMLKEMPublicKey; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator; +import org.bouncycastle.pqc.jcajce.provider.Util; + +import javax.crypto.KEM; +import javax.crypto.KEMSpi; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidKeyException; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.Objects; + +public class MLKEMEncapsulatorSpi + implements KEMSpi.EncapsulatorSpi +{ + private final BCMLKEMPublicKey publicKey; + private final KTSParameterSpec parameterSpec; + private final MLKEMGenerator kemGen; + + public MLKEMEncapsulatorSpi(BCMLKEMPublicKey publicKey, KTSParameterSpec parameterSpec, SecureRandom random) + { + this.publicKey = publicKey; + this.parameterSpec = parameterSpec; + + this.kemGen = new MLKEMGenerator(random); + } + + + @Override + public KEM.Encapsulated engineEncapsulate(int from, int to, String algorithm) + { + Objects.checkFromToIndex(from, to, engineSecretSize()); + Objects.requireNonNull(algorithm, "null algorithm"); + + // if algorithm is Generic then use parameterSpec to wrap key + if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && + algorithm.equals("Generic")) + { + algorithm = parameterSpec.getKeyAlgorithmName(); + } + + // check spec algorithm mismatch provided algorithm + if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && + !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + { + throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + } + + // Only use KDF when ktsParameterSpec is provided + // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided + boolean useKDF = parameterSpec.getKdfAlgorithm() != null; + + SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(publicKey.getKeyParams()); + + byte[] encapsulation = secEnc.getEncapsulation(); + byte[] secret = secEnc.getSecret(); + + byte[] secretKey; + + if (useKDF) + { + try + { + secret = Util.makeKeyBytes(parameterSpec, secret); + } + catch (InvalidKeyException e) + { + throw new IllegalStateException(e); + } + } + + secretKey = Arrays.copyOfRange(secret, from, to); + + return new KEM.Encapsulated(new SecretKeySpec(secretKey, algorithm), encapsulation, null); //TODO: DER encoding for params } + } + + @Override + public int engineSecretSize() + { + return parameterSpec.getKeySize() / 8; + } + + + @Override + public int engineEncapsulationSize() + { + //TODO: Maybe make parameterSet public or add getEncapsulationSize() in KEMGenerator.java + switch (publicKey.getKeyParams().getParameters().getName()) + { + case "ML-KEM-512": + return 768; + case "ML-KEM-768": + return 1088; + case "ML-KEM-1024": + return 1568; + default: + return -1; + } + } +} diff --git a/prov/src/main/jdk21/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMSpi.java b/prov/src/main/jdk21/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMSpi.java new file mode 100644 index 0000000000..db4fed4ff4 --- /dev/null +++ b/prov/src/main/jdk21/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMSpi.java @@ -0,0 +1,61 @@ +package org.bouncycastle.jcajce.provider.asymmetric.mlkem; + +import org.bouncycastle.jcajce.provider.asymmetric.mlkem.BCMLKEMPrivateKey; +import org.bouncycastle.jcajce.provider.asymmetric.mlkem.BCMLKEMPublicKey; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; + +import javax.crypto.KEMSpi; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +public class MLKEMSpi + implements KEMSpi +{ + @Override + public EncapsulatorSpi engineNewEncapsulator(PublicKey publicKey, AlgorithmParameterSpec spec, SecureRandom secureRandom) + throws InvalidAlgorithmParameterException, InvalidKeyException + { + if (!(publicKey instanceof BCMLKEMPublicKey)) + { + throw new InvalidKeyException("unsupported key"); + } + if (spec == null) + { + // Do not wrap key, no KDF + spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); + } + if (!(spec instanceof KTSParameterSpec)) + { + throw new InvalidAlgorithmParameterException("MLKEM can only accept KTSParameterSpec"); + } + if (secureRandom == null) + { + secureRandom = new SecureRandom(); + } + return new MLKEMEncapsulatorSpi((BCMLKEMPublicKey) publicKey, (KTSParameterSpec) spec, secureRandom); + } + + @Override + public DecapsulatorSpi engineNewDecapsulator(PrivateKey privateKey, AlgorithmParameterSpec spec) + throws InvalidAlgorithmParameterException, InvalidKeyException + { + if (!(privateKey instanceof BCMLKEMPrivateKey)) + { + throw new InvalidKeyException("unsupported key"); + } + if (spec == null) + { + // Do not unwrap key, no KDF + spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); + } + if (!(spec instanceof KTSParameterSpec)) + { + throw new InvalidAlgorithmParameterException("MLKEM can only accept KTSParameterSpec"); + } + return new MLKEMDecapsulatorSpi((BCMLKEMPrivateKey) privateKey, (KTSParameterSpec) spec); + } +} diff --git a/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/NTRU.java b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/NTRU.java new file mode 100644 index 0000000000..aa4377f28f --- /dev/null +++ b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/NTRU.java @@ -0,0 +1,43 @@ +package org.bouncycastle.pqc.jcajce.provider; + +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; +import org.bouncycastle.pqc.jcajce.provider.ntru.NTRUKeyFactorySpi; + +public class NTRU +{ + private static final String PREFIX = "org.bouncycastle.pqc.jcajce.provider" + ".ntru."; + + public static class Mappings + extends AsymmetricAlgorithmProvider + { + public Mappings() + { + } + + public void configure(ConfigurableProvider provider) + { + provider.addAlgorithm("KeyFactory.NTRU", PREFIX + "NTRUKeyFactorySpi"); + provider.addAlgorithm("KeyPairGenerator.NTRU", PREFIX + "NTRUKeyPairGeneratorSpi"); + + provider.addAlgorithm("KeyGenerator.NTRU", PREFIX + "NTRUKeyGeneratorSpi"); + + AsymmetricKeyInfoConverter keyFact = new NTRUKeyFactorySpi(); + + provider.addAlgorithm("Cipher.NTRU", PREFIX + "NTRUCipherSpi$Base"); + provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_ntru, "NTRU"); + + registerOid(provider, BCObjectIdentifiers.ntruhps2048509, "NTRU", keyFact); + registerOid(provider, BCObjectIdentifiers.ntruhps2048677, "NTRU", keyFact); + registerOid(provider, BCObjectIdentifiers.ntruhps4096821, "NTRU", keyFact); + registerOid(provider, BCObjectIdentifiers.ntruhps40961229, "NTRU", keyFact); + registerOid(provider, BCObjectIdentifiers.ntruhrss701, "NTRU", keyFact); + registerOid(provider, BCObjectIdentifiers.ntruhrss1373, "NTRU", keyFact); + + provider.addAlgorithm("Kem.NTRU", PREFIX + "NTRUKEMSpi"); + provider.addAlgorithm("Alg.Alias.Kem." + BCObjectIdentifiers.pqc_kem_ntru, "NTRU"); + } + } +} \ No newline at end of file diff --git a/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java new file mode 100644 index 0000000000..3501d6e969 --- /dev/null +++ b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java @@ -0,0 +1,61 @@ +package org.bouncycastle.pqc.jcajce.provider; + +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; +import org.bouncycastle.pqc.jcajce.provider.ntruprime.NTRULPRimeKeyFactorySpi; +import org.bouncycastle.pqc.jcajce.provider.ntruprime.SNTRUPrimeKeyFactorySpi; + +public class NTRUPrime +{ + private static final String PREFIX = "org.bouncycastle.pqc.jcajce.provider" + ".ntruprime."; + + public static class Mappings + extends AsymmetricAlgorithmProvider + { + public Mappings() + { + } + + public void configure(ConfigurableProvider provider) + { + provider.addAlgorithm("KeyFactory.NTRULPRIME", PREFIX + "NTRULPRimeKeyFactorySpi"); + provider.addAlgorithm("KeyPairGenerator.NTRULPRIME", PREFIX + "NTRULPRimeKeyPairGeneratorSpi"); + + provider.addAlgorithm("KeyGenerator.NTRULPRIME", PREFIX + "NTRULPRimeKeyGeneratorSpi"); + + AsymmetricKeyInfoConverter keyFact = new NTRULPRimeKeyFactorySpi(); + + provider.addAlgorithm("Cipher.NTRULPRIME", PREFIX + "NTRULPRimeCipherSpi$Base"); + provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_ntrulprime, "NTRU"); + + registerOid(provider, BCObjectIdentifiers.ntrulpr653, "NTRULPRIME", keyFact); + registerOid(provider, BCObjectIdentifiers.ntrulpr761, "NTRULPRIME", keyFact); + registerOid(provider, BCObjectIdentifiers.ntrulpr857, "NTRULPRIME", keyFact); + registerOid(provider, BCObjectIdentifiers.ntrulpr953, "NTRULPRIME", keyFact); + registerOid(provider, BCObjectIdentifiers.ntrulpr1013, "NTRULPRIME", keyFact); + registerOid(provider, BCObjectIdentifiers.ntrulpr1277, "NTRULPRIME", keyFact); + + provider.addAlgorithm("KeyFactory.SNTRUPRIME", PREFIX + "SNTRUPrimeKeyFactorySpi"); + provider.addAlgorithm("KeyPairGenerator.SNTRUPRIME", PREFIX + "SNTRUPrimeKeyPairGeneratorSpi"); + + provider.addAlgorithm("KeyGenerator.SNTRUPRIME", PREFIX + "SNTRUPrimeKeyGeneratorSpi"); + + keyFact = new SNTRUPrimeKeyFactorySpi(); + + provider.addAlgorithm("Cipher.SNTRUPRIME", PREFIX + "SNTRUPrimeCipherSpi$Base"); + provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_sntruprime, "NTRU"); + + registerOid(provider, BCObjectIdentifiers.sntrup653, "SNTRUPRIME", keyFact); + registerOid(provider, BCObjectIdentifiers.sntrup761, "SNTRUPRIME", keyFact); + registerOid(provider, BCObjectIdentifiers.sntrup857, "SNTRUPRIME", keyFact); + registerOid(provider, BCObjectIdentifiers.sntrup953, "SNTRUPRIME", keyFact); + registerOid(provider, BCObjectIdentifiers.sntrup1013, "SNTRUPRIME", keyFact); + registerOid(provider, BCObjectIdentifiers.sntrup1277, "SNTRUPRIME", keyFact); + + provider.addAlgorithm("Kem.SNTRUPRIME", PREFIX + "SNTRUPrimeKEMSpi"); + provider.addAlgorithm("Alg.Alias.Kem." + BCObjectIdentifiers.pqc_kem_sntruprime, "SNTRUPRIME"); + } + } +} \ No newline at end of file diff --git a/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/Util.java b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/Util.java new file mode 100644 index 0000000000..08f37ba137 --- /dev/null +++ b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/Util.java @@ -0,0 +1,85 @@ +package org.bouncycastle.pqc.jcajce.provider; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.crypto.DerivationFunction; +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.Xof; +import org.bouncycastle.crypto.agreement.kdf.ConcatenationKDFGenerator; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.digests.SHA512Digest; +import org.bouncycastle.crypto.digests.SHAKEDigest; +import org.bouncycastle.crypto.generators.KDF2BytesGenerator; +import org.bouncycastle.crypto.params.KDFParameters; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; + +import java.security.InvalidKeyException; + +public class Util +{ + public static byte[] makeKeyBytes(KTSParameterSpec ktsSpec, byte[] secret) + throws InvalidKeyException + { + AlgorithmIdentifier kdfAlgorithm = ktsSpec.getKdfAlgorithm(); + byte[] otherInfo = ktsSpec.getOtherInfo(); + byte[] keyBytes = new byte[(ktsSpec.getKeySize() + 7) / 8]; + + if (X9ObjectIdentifiers.id_kdf_kdf2.equals(kdfAlgorithm.getAlgorithm())) + { + AlgorithmIdentifier digAlg = AlgorithmIdentifier.getInstance(kdfAlgorithm.getParameters()); + DerivationFunction kdf = new KDF2BytesGenerator(getDigest(digAlg.getAlgorithm())); + + kdf.init(new KDFParameters(secret, otherInfo)); + + kdf.generateBytes(keyBytes, 0, keyBytes.length); + } + else if (X9ObjectIdentifiers.id_kdf_kdf3.equals(kdfAlgorithm.getAlgorithm())) + { + AlgorithmIdentifier digAlg = AlgorithmIdentifier.getInstance(kdfAlgorithm.getParameters()); + DerivationFunction kdf = new ConcatenationKDFGenerator(getDigest(digAlg.getAlgorithm())); + + kdf.init(new KDFParameters(secret, otherInfo)); + + kdf.generateBytes(keyBytes, 0, keyBytes.length); + } + else if (NISTObjectIdentifiers.id_shake256.equals(kdfAlgorithm.getAlgorithm())) + { + Xof xof = new SHAKEDigest(256); + + xof.update(secret, 0, secret.length); + xof.update(otherInfo, 0, otherInfo.length); + + xof.doFinal(keyBytes, 0, keyBytes.length); + } + else + { + throw new InvalidKeyException("Unrecognized KDF: " + kdfAlgorithm.getAlgorithm()); + } + + return keyBytes; + } + + static Digest getDigest(ASN1ObjectIdentifier oid) + { + if (oid.equals(NISTObjectIdentifiers.id_sha256)) + { + return new SHA256Digest(); + } + if (oid.equals(NISTObjectIdentifiers.id_sha512)) + { + return new SHA512Digest(); + } + if (oid.equals(NISTObjectIdentifiers.id_shake128)) + { + return new SHAKEDigest(128); + } + if (oid.equals(NISTObjectIdentifiers.id_shake256)) + { + return new SHAKEDigest(256); + } + + throw new IllegalArgumentException("unrecognized digest OID: " + oid); + } +} diff --git a/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUDecapsulatorSpi.java b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUDecapsulatorSpi.java new file mode 100644 index 0000000000..f51faf3509 --- /dev/null +++ b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUDecapsulatorSpi.java @@ -0,0 +1,91 @@ +package org.bouncycastle.pqc.jcajce.provider.ntru; + +import org.bouncycastle.jcajce.spec.KTSParameterSpec; + +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.ntru.NTRUKEMExtractor; +import org.bouncycastle.pqc.jcajce.provider.Util; + +import javax.crypto.DecapsulateException; +import javax.crypto.KEMSpi; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidKeyException; +import java.util.Arrays; +import java.util.Objects; + +public class NTRUDecapsulatorSpi + implements KEMSpi.DecapsulatorSpi +{ + BCNTRUPrivateKey privateKey; + KTSParameterSpec parameterSpec; + NTRUKEMExtractor kemExt; + + public NTRUDecapsulatorSpi(BCNTRUPrivateKey privateKey, KTSParameterSpec parameterSpec) + { + this.privateKey = privateKey; + this.parameterSpec = parameterSpec; + + this.kemExt = new NTRUKEMExtractor(privateKey.getKeyParams()); + } + + @Override + public SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, String algorithm) throws DecapsulateException + { + Objects.checkFromToIndex(from, to, engineSecretSize()); + Objects.requireNonNull(algorithm, "null algorithm"); + Objects.requireNonNull(encapsulation, "null encapsulation"); + + if (encapsulation.length != engineEncapsulationSize()) + { + throw new DecapsulateException("incorrect encapsulation size"); + } + + // if algorithm is Generic then use parameterSpec to wrap key + if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && + algorithm.equals("Generic")) + { + algorithm = parameterSpec.getKeyAlgorithmName(); + } + + // check spec algorithm mismatch provided algorithm + if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && + !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + { + throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + } + + // Only use KDF when ktsParameterSpec is provided + // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided + boolean useKDF = parameterSpec.getKdfAlgorithm() != null; + + byte[] secret = kemExt.extractSecret(encapsulation); + + if (useKDF) + { + try + { + secret = Util.makeKeyBytes(parameterSpec, secret); + } + catch (InvalidKeyException e) + { + throw new IllegalStateException(e); + } + } + byte[] secretKey = Arrays.copyOfRange(secret, from, to); + + return new SecretKeySpec(secretKey, algorithm); + } + + @Override + public int engineSecretSize() + { + return parameterSpec.getKeySize() / 8; + } + + @Override + public int engineEncapsulationSize() + { + return kemExt.getEncapsulationLength(); + } +} diff --git a/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUEncapsulatorSpi.java b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUEncapsulatorSpi.java new file mode 100644 index 0000000000..81c94d49e4 --- /dev/null +++ b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUEncapsulatorSpi.java @@ -0,0 +1,108 @@ +package org.bouncycastle.pqc.jcajce.provider.ntru; + +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.ntru.NTRUKEMGenerator; +import org.bouncycastle.pqc.jcajce.provider.Util; + +import javax.crypto.KEM; +import javax.crypto.KEMSpi; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidKeyException; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.Objects; + +public class NTRUEncapsulatorSpi + implements KEMSpi.EncapsulatorSpi +{ + private final BCNTRUPublicKey publicKey; + private final KTSParameterSpec parameterSpec; + private final NTRUKEMGenerator kemGen; + + public NTRUEncapsulatorSpi(BCNTRUPublicKey publicKey, KTSParameterSpec parameterSpec, SecureRandom random) + { + this.publicKey = publicKey; + this.parameterSpec = parameterSpec; + + this.kemGen = new NTRUKEMGenerator(random); + } + + @Override + public KEM.Encapsulated engineEncapsulate(int from, int to, String algorithm) + { + Objects.checkFromToIndex(from, to, engineSecretSize()); + Objects.requireNonNull(algorithm, "null algorithm"); + + // if algorithm is Generic then use parameterSpec to wrap key + if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && + algorithm.equals("Generic")) + { + algorithm = parameterSpec.getKeyAlgorithmName(); + } + + // check spec algorithm mismatch provided algorithm + if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && + !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + { + throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + } + + // Only use KDF when ktsParameterSpec is provided + // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided + boolean useKDF = parameterSpec.getKdfAlgorithm() != null; + + SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(publicKey.getKeyParams()); + + byte[] encapsulation = secEnc.getEncapsulation(); + byte[] secret = secEnc.getSecret(); + + byte[] secretKey; + + if (useKDF) + { + try + { + secret = Util.makeKeyBytes(parameterSpec, secret); + } + catch (InvalidKeyException e) + { + throw new IllegalStateException(e); + } + } + + secretKey = Arrays.copyOfRange(secret, from, to); + + return new KEM.Encapsulated(new SecretKeySpec(secretKey, algorithm), encapsulation, null); //TODO: DER encoding for params + + } + + @Override + public int engineSecretSize() + { + return parameterSpec.getKeySize() / 8; + } + + @Override + public int engineEncapsulationSize() + { + //TODO: Maybe make parameterSet public or add getEncapsulationSize() in NTRUKEMGenerator.java + switch (publicKey.getKeyParams().getParameters().getName()) + { + case "ntruhps2048509": + return 699; + case "ntruhps2048677": + return 930; + case "ntruhps4096821": + return 1230; + case "ntruhps40961229": + return 1843; + case "ntruhrss701": + return 1138; + case "ntruhrss1373": + return 2401; + default: + return -1; + } + } +} diff --git a/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKEMSpi.java b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKEMSpi.java new file mode 100644 index 0000000000..77b7a2bf54 --- /dev/null +++ b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKEMSpi.java @@ -0,0 +1,62 @@ +package org.bouncycastle.pqc.jcajce.provider.ntru; + +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.jcajce.provider.ntru.BCNTRUPrivateKey; +import org.bouncycastle.pqc.jcajce.provider.ntru.NTRUDecapsulatorSpi; + +import javax.crypto.KEMSpi; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +public class NTRUKEMSpi + implements KEMSpi +{ + + @Override + public EncapsulatorSpi engineNewEncapsulator(PublicKey publicKey, AlgorithmParameterSpec spec, SecureRandom secureRandom) + throws InvalidAlgorithmParameterException, InvalidKeyException + { + if (!(publicKey instanceof BCNTRUPublicKey)) + { + throw new InvalidKeyException("unsupported key"); + } + if (spec == null) + { + // Do not wrap key, no KDF + spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); + } + if (!(spec instanceof KTSParameterSpec)) + { + throw new InvalidAlgorithmParameterException("NTRU can only accept KTSParameterSpec"); + } + if (secureRandom == null) + { + secureRandom = new SecureRandom(); + } + return new NTRUEncapsulatorSpi((BCNTRUPublicKey) publicKey, (KTSParameterSpec) spec, secureRandom); + } + + @Override + public DecapsulatorSpi engineNewDecapsulator(PrivateKey privateKey, AlgorithmParameterSpec spec) + throws InvalidAlgorithmParameterException, InvalidKeyException + { + if (!(privateKey instanceof BCNTRUPrivateKey)) + { + throw new InvalidKeyException("unsupported key"); + } + if (spec == null) + { + // Do not unwrap key, no KDF + spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); + } + if (!(spec instanceof KTSParameterSpec)) + { + throw new InvalidAlgorithmParameterException("NTRU can only accept KTSParameterSpec"); + } + return new NTRUDecapsulatorSpi((BCNTRUPrivateKey) privateKey, (KTSParameterSpec) spec); + } +} diff --git a/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeDecapsulatorSpi.java b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeDecapsulatorSpi.java new file mode 100644 index 0000000000..847fd006e0 --- /dev/null +++ b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeDecapsulatorSpi.java @@ -0,0 +1,90 @@ +package org.bouncycastle.pqc.jcajce.provider.ntruprime; + +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeKEMExtractor; +import org.bouncycastle.pqc.jcajce.provider.Util; +import org.bouncycastle.util.Arrays; + +import javax.crypto.DecapsulateException; +import javax.crypto.KEMSpi; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidKeyException; +import java.util.Objects; + +class SNTRUPrimeDecapsulatorSpi + implements KEMSpi.DecapsulatorSpi +{ + BCSNTRUPrimePrivateKey privateKey; + KTSParameterSpec parameterSpec; + + SNTRUPrimeKEMExtractor kemExt; + + public SNTRUPrimeDecapsulatorSpi(BCSNTRUPrimePrivateKey privateKey, KTSParameterSpec parameterSpec) + { + this.privateKey = privateKey; + this.parameterSpec = parameterSpec; + + kemExt = new SNTRUPrimeKEMExtractor(privateKey.getKeyParams()); + } + + @Override + public SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, String algorithm) throws DecapsulateException + { + Objects.checkFromToIndex(from, to, engineSecretSize()); + Objects.requireNonNull(algorithm, "null algorithm"); + Objects.requireNonNull(encapsulation, "null encapsulation"); + + if (encapsulation.length != engineEncapsulationSize()) + { + throw new DecapsulateException("incorrect encapsulation size"); + } + + // if algorithm is Generic then use parameterSpec to wrap key + if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && + algorithm.equals("Generic")) + { + algorithm = parameterSpec.getKeyAlgorithmName(); + } + + // check spec algorithm mismatch provided algorithm + if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && + !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + { + throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + } + + // Only use KDF when ktsParameterSpec is provided + // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided + boolean useKDF = parameterSpec.getKdfAlgorithm() != null; + + byte[] secret = kemExt.extractSecret(encapsulation); + + if (useKDF) + { + try + { + secret = Util.makeKeyBytes(parameterSpec, secret); + } + catch (InvalidKeyException e) + { + throw new IllegalStateException(e); + } + } + byte[] secretKey = Arrays.copyOfRange(secret, from, to); + + return new SecretKeySpec(secretKey, algorithm); + } + + @Override + public int engineSecretSize() + { + return parameterSpec.getKeySize() / 8; + } + + @Override + public int engineEncapsulationSize() + { + return kemExt.getEncapsulationLength(); + } +} diff --git a/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeEncapsulatorSpi.java b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeEncapsulatorSpi.java new file mode 100644 index 0000000000..e15d83eed6 --- /dev/null +++ b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeEncapsulatorSpi.java @@ -0,0 +1,92 @@ +package org.bouncycastle.pqc.jcajce.provider.ntruprime; + +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeKEMGenerator; +import org.bouncycastle.pqc.jcajce.provider.Util; +import org.bouncycastle.util.Arrays; + +import javax.crypto.KEM; +import javax.crypto.KEMSpi; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidKeyException; +import java.security.SecureRandom; +import java.util.Objects; + +class SNTRUPrimeEncapsulatorSpi + implements KEMSpi.EncapsulatorSpi +{ + private final BCSNTRUPrimePublicKey publicKey; + private final KTSParameterSpec parameterSpec; + private final SNTRUPrimeKEMGenerator kemGen; + + + public SNTRUPrimeEncapsulatorSpi(BCSNTRUPrimePublicKey publicKey, KTSParameterSpec parameterSpec, SecureRandom random) + { + this.publicKey = publicKey; + this.parameterSpec = parameterSpec; + + kemGen = new SNTRUPrimeKEMGenerator(random); + } + + @Override + public KEM.Encapsulated engineEncapsulate(int from, int to, String algorithm) + { + Objects.checkFromToIndex(from, to, engineSecretSize()); + Objects.requireNonNull(algorithm, "null algorithm"); + + // if algorithm is Generic then use parameterSpec to wrap key + if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && + algorithm.equals("Generic")) + { + algorithm = parameterSpec.getKeyAlgorithmName(); + } + + // check spec algorithm mismatch provided algorithm + if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && + !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + { + throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + } + + // Only use KDF when ktsParameterSpec is provided + // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided + boolean useKDF = parameterSpec.getKdfAlgorithm() != null; + + SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(publicKey.getKeyParams()); + + byte[] encapsulation = secEnc.getEncapsulation(); + byte[] secret = secEnc.getSecret(); + + byte[] secretKey; + + if (useKDF) + { + try + { + secret = Util.makeKeyBytes(parameterSpec, secret); + } + catch (InvalidKeyException e) + { + throw new IllegalStateException(e); + } + } + + secretKey = Arrays.copyOfRange(secret, from, to); + + return new KEM.Encapsulated(new SecretKeySpec(secretKey, algorithm), encapsulation, null); //TODO: DER encoding for params + + } + + @Override + public int engineSecretSize() + { + return parameterSpec.getKeySize() / 8; + } + + @Override + public int engineEncapsulationSize() + { + return publicKey.getKeyParams().getParameters().getRoundedPolynomialBytes() + 32; + } +} diff --git a/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeKEMSpi.java b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeKEMSpi.java new file mode 100644 index 0000000000..64be2c116e --- /dev/null +++ b/prov/src/main/jdk21/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeKEMSpi.java @@ -0,0 +1,58 @@ +package org.bouncycastle.pqc.jcajce.provider.ntruprime; + +import org.bouncycastle.jcajce.spec.KTSParameterSpec; + +import javax.crypto.KEMSpi; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +public class SNTRUPrimeKEMSpi + implements KEMSpi +{ + + @Override + public EncapsulatorSpi engineNewEncapsulator(PublicKey publicKey, AlgorithmParameterSpec spec, SecureRandom secureRandom) throws InvalidAlgorithmParameterException, InvalidKeyException + { + if (!(publicKey instanceof BCSNTRUPrimePublicKey)) + { + throw new InvalidKeyException("unsupported key"); + } + if (spec == null) + { + // Do not wrap key, no KDF + spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); + } + if (!(spec instanceof KTSParameterSpec)) + { + throw new InvalidAlgorithmParameterException("SNTRUPrime can only accept KTSParameterSpec"); + } + if (secureRandom == null) + { + secureRandom = new SecureRandom(); + } + return new SNTRUPrimeEncapsulatorSpi((BCSNTRUPrimePublicKey) publicKey,(KTSParameterSpec) spec, secureRandom); + } + + @Override + public DecapsulatorSpi engineNewDecapsulator(PrivateKey privateKey, AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException, InvalidKeyException + { + if (!(privateKey instanceof BCSNTRUPrimePrivateKey)) + { + throw new InvalidKeyException("unsupported key"); + } + if (spec == null) + { + // Do not unwrap key, no KDF + spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); + } + if (!(spec instanceof KTSParameterSpec)) + { + throw new InvalidAlgorithmParameterException("SNTRUPrime can only accept KTSParameterSpec"); + } + return new SNTRUPrimeDecapsulatorSpi((BCSNTRUPrimePrivateKey) privateKey, (KTSParameterSpec) spec); + } +} diff --git a/prov/src/test/java/org/bouncycastle/jcajce/provider/test/AllTests.java b/prov/src/test/java/org/bouncycastle/jcajce/provider/test/AllTests.java index 51f57888d3..662cd00fe9 100644 --- a/prov/src/test/java/org/bouncycastle/jcajce/provider/test/AllTests.java +++ b/prov/src/test/java/org/bouncycastle/jcajce/provider/test/AllTests.java @@ -29,6 +29,8 @@ public static Test suite() suite.addTestSuite(RandomTest.class); suite.addTestSuite(RFC3211WrapTest.class); suite.addTestSuite(SP80038GTest.class); + suite.addTestSuite(CompositeKeyTest.class); + suite.addTestSuite(CompositeSignaturesTest.class); suite.addTestSuite(BouncyCastleProviderTest.class); return new BCTestSetup(suite); diff --git a/prov/src/test/java/org/bouncycastle/jcajce/provider/test/CompositeKeyTest.java b/prov/src/test/java/org/bouncycastle/jcajce/provider/test/CompositeKeyTest.java index c559e4aeb5..75d7a41762 100644 --- a/prov/src/test/java/org/bouncycastle/jcajce/provider/test/CompositeKeyTest.java +++ b/prov/src/test/java/org/bouncycastle/jcajce/provider/test/CompositeKeyTest.java @@ -6,8 +6,6 @@ import java.security.spec.X509EncodedKeySpec; import junit.framework.TestCase; -import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.jcajce.CompositePrivateKey; import org.bouncycastle.jcajce.CompositePublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -112,7 +110,7 @@ public void testGenericCompositeKey() KeyFactory keyFact = KeyFactory.getInstance("COMPOSITE", "BC"); CompositePublicKey compPubKey = (CompositePublicKey)keyFact.generatePublic(new X509EncodedKeySpec(genPubKey)); - System.err.println(ASN1Dump.dumpAsString(ASN1Primitive.fromByteArray(genPrivKey))) ; + CompositePrivateKey compPrivKey = (CompositePrivateKey)keyFact.generatePrivate(new PKCS8EncodedKeySpec(genPrivKey)); } @@ -123,7 +121,7 @@ public void testExplicitCompositeKey() CompositePublicKey compPubKey = (CompositePublicKey)keyFact.generatePublic(new X509EncodedKeySpec(expPubKey)); - System.out.println(ASN1Dump.dumpAsString(ASN1Primitive.fromByteArray(expPubKey))); + // System.out.println(ASN1Dump.dumpAsString(ASN1Primitive.fromByteArray(expPubKey))); CompositePrivateKey compPrivKey = (CompositePrivateKey)keyFact.generatePrivate(new PKCS8EncodedKeySpec(expPrivKey)); } } diff --git a/prov/src/test/java/org/bouncycastle/jcajce/provider/test/CompositeSignaturesTest.java b/prov/src/test/java/org/bouncycastle/jcajce/provider/test/CompositeSignaturesTest.java new file mode 100644 index 0000000000..1a92eefa40 --- /dev/null +++ b/prov/src/test/java/org/bouncycastle/jcajce/provider/test/CompositeSignaturesTest.java @@ -0,0 +1,208 @@ +package org.bouncycastle.jcajce.provider.test; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.Security; +import java.security.Signature; + +import junit.framework.TestCase; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.jcajce.CompositePrivateKey; +import org.bouncycastle.jcajce.CompositePublicKey; +import org.bouncycastle.jcajce.provider.asymmetric.compositesignatures.CompositeSignaturesConstants; +import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.Strings; + +public class CompositeSignaturesTest + extends TestCase +{ + + private static String[] compositeSignaturesOIDs = { + "2.16.840.1.114027.80.8.1.1", //id-MLDSA44-RSA2048-PSS-SHA256 + "2.16.840.1.114027.80.8.1.2", //id-MLDSA44-RSA2048-PKCS15-SHA256 + "2.16.840.1.114027.80.8.1.3", //id-MLDSA44-Ed25519-SHA512 + "2.16.840.1.114027.80.8.1.4", //id-MLDSA44-ECDSA-P256-SHA256 + "2.16.840.1.114027.80.8.1.5", //id-MLDSA44-ECDSA-brainpoolP256r1-SHA256 + "2.16.840.1.114027.80.8.1.6", //id-MLDSA65-RSA3072-PSS-SHA512 + "2.16.840.1.114027.80.8.1.7", //id-MLDSA65-RSA3072-PKCS15-SHA512 + "2.16.840.1.114027.80.8.1.8", //id-MLDSA65-ECDSA-P256-SHA512 + "2.16.840.1.114027.80.8.1.9", //id-MLDSA65-ECDSA-brainpoolP256r1-SHA512 + "2.16.840.1.114027.80.8.1.10", //id-MLDSA65-Ed25519-SHA512 + "2.16.840.1.114027.80.8.1.11", //id-MLDSA87-ECDSA-P384-SHA512 + "2.16.840.1.114027.80.8.1.12", //id-MLDSA87-ECDSA-brainpoolP384r1-SHA512 + "2.16.840.1.114027.80.8.1.13", //id-MLDSA87-Ed448-SHA512 + // Falcon composites below were excluded from the draft. See MiscObjectIdentifiers for details. + "2.16.840.1.114027.80.8.1.14", //id-Falcon512-ECDSA-P256-SHA256 + "2.16.840.1.114027.80.8.1.15", //id-Falcon512-ECDSA-brainpoolP256r1-SHA256 + "2.16.840.1.114027.80.8.1.16", //id-Falcon512-Ed25519-SHA512 + }; + + public static final String messageToBeSigned = "Hello, how was your day?"; + + public void setUp() + { + Security.addProvider(new BouncyCastleProvider()); + } + + public void testKeyPairGeneration() + throws Exception + { + for (String oid : compositeSignaturesOIDs) + { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(oid, "BC"); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + CompositePublicKey compositePublicKey = (CompositePublicKey)keyPair.getPublic(); + CompositePrivateKey compositePrivateKey = (CompositePrivateKey)keyPair.getPrivate(); + + String firstPublicKeyAlgorithm = Strings.toUpperCase(compositePublicKey.getPublicKeys().get(0).getAlgorithm()); + String secondPublicKeyAlgorithm = Strings.toUpperCase(compositePublicKey.getPublicKeys().get(1).getAlgorithm()); + String firstPrivateKeyAlgorithm = Strings.toUpperCase(compositePrivateKey.getPrivateKeys().get(0).getAlgorithm()); + String secondPrivateKeyAlgorithm = Strings.toUpperCase(compositePrivateKey.getPrivateKeys().get(1).getAlgorithm()); + + BCRSAPublicKey rsaPublicKey = null; + BCRSAPublicKey rsaPrivateKey = null; + + switch (CompositeSignaturesConstants.ASN1IdentifierCompositeNameMap.get(new ASN1ObjectIdentifier(oid))) + { + case MLDSA44_RSA2048_PSS_SHA256: + case MLDSA44_RSA2048_PKCS15_SHA256: + TestCase.assertEquals("ML-DSA-44", firstPublicKeyAlgorithm); + TestCase.assertEquals("ML-DSA-44", firstPrivateKeyAlgorithm); + TestCase.assertEquals("RSA", secondPublicKeyAlgorithm); + TestCase.assertEquals("RSA", secondPrivateKeyAlgorithm); + rsaPublicKey = (BCRSAPublicKey)compositePublicKey.getPublicKeys().get(1); + rsaPrivateKey = (BCRSAPublicKey)compositePublicKey.getPublicKeys().get(1); + TestCase.assertEquals(2048, rsaPublicKey.getModulus().bitLength()); + TestCase.assertEquals(2048, rsaPrivateKey.getModulus().bitLength()); + break; + case MLDSA44_Ed25519_SHA512: + TestCase.assertEquals("ML-DSA-44", firstPublicKeyAlgorithm); + TestCase.assertEquals("ML-DSA-44", firstPrivateKeyAlgorithm); + TestCase.assertEquals("ED25519", secondPublicKeyAlgorithm); + TestCase.assertEquals("ED25519", secondPrivateKeyAlgorithm); + break; + case MLDSA44_ECDSA_P256_SHA256: + case MLDSA44_ECDSA_brainpoolP256r1_SHA256: + TestCase.assertEquals("ML-DSA-44", firstPublicKeyAlgorithm); + TestCase.assertEquals("ML-DSA-44", firstPrivateKeyAlgorithm); + TestCase.assertEquals("ECDSA", secondPublicKeyAlgorithm); + TestCase.assertEquals("ECDSA", secondPrivateKeyAlgorithm); + break; + case MLDSA65_RSA3072_PSS_SHA512: + case MLDSA65_RSA3072_PKCS15_SHA512: + TestCase.assertEquals("ML-DSA-65", firstPublicKeyAlgorithm); + TestCase.assertEquals("ML-DSA-65", firstPrivateKeyAlgorithm); + TestCase.assertEquals("RSA", secondPublicKeyAlgorithm); + TestCase.assertEquals("RSA", secondPrivateKeyAlgorithm); + rsaPublicKey = (BCRSAPublicKey)compositePublicKey.getPublicKeys().get(1); + rsaPrivateKey = (BCRSAPublicKey)compositePublicKey.getPublicKeys().get(1); + TestCase.assertEquals(3072, rsaPublicKey.getModulus().bitLength()); + TestCase.assertEquals(3072, rsaPrivateKey.getModulus().bitLength()); + break; + case MLDSA65_Ed25519_SHA512: + TestCase.assertEquals("ML-DSA-65", firstPublicKeyAlgorithm); + TestCase.assertEquals("ML-DSA-65", firstPrivateKeyAlgorithm); + TestCase.assertEquals("ED25519", secondPublicKeyAlgorithm); + TestCase.assertEquals("ED25519", secondPrivateKeyAlgorithm); + break; + case MLDSA65_ECDSA_P256_SHA512: + case MLDSA65_ECDSA_brainpoolP256r1_SHA512: + TestCase.assertEquals("ML-DSA-65", firstPublicKeyAlgorithm); + TestCase.assertEquals("ML-DSA-65", firstPrivateKeyAlgorithm); + TestCase.assertEquals("ECDSA", secondPublicKeyAlgorithm); + TestCase.assertEquals("ECDSA", secondPrivateKeyAlgorithm); + break; + case MLDSA87_Ed448_SHA512: + TestCase.assertEquals("ML-DSA-87", firstPublicKeyAlgorithm); + TestCase.assertEquals("ML-DSA-87", firstPrivateKeyAlgorithm); + TestCase.assertEquals("ED448", secondPublicKeyAlgorithm); + TestCase.assertEquals("ED448", secondPrivateKeyAlgorithm); + break; + case MLDSA87_ECDSA_P384_SHA512: + case MLDSA87_ECDSA_brainpoolP384r1_SHA512: + TestCase.assertEquals("ML-DSA-87", firstPublicKeyAlgorithm); + TestCase.assertEquals("ML-DSA-87", firstPrivateKeyAlgorithm); + TestCase.assertEquals("ECDSA", secondPublicKeyAlgorithm); + TestCase.assertEquals("ECDSA", secondPrivateKeyAlgorithm); + break; + case Falcon512_Ed25519_SHA512: + TestCase.assertEquals("FALCON-512", firstPublicKeyAlgorithm); + TestCase.assertEquals("FALCON-512", firstPrivateKeyAlgorithm); + TestCase.assertEquals("ED25519", secondPublicKeyAlgorithm); + TestCase.assertEquals("ED25519", secondPrivateKeyAlgorithm); + break; + case Falcon512_ECDSA_P256_SHA256: + case Falcon512_ECDSA_brainpoolP256r1_SHA256: + TestCase.assertEquals("FALCON-512", firstPublicKeyAlgorithm); + TestCase.assertEquals("FALCON-512", firstPrivateKeyAlgorithm); + TestCase.assertEquals("ECDSA", secondPublicKeyAlgorithm); + TestCase.assertEquals("ECDSA", secondPrivateKeyAlgorithm); + break; + default: + throw new IllegalStateException( + "Unexpected key algorithm." + CompositeSignaturesConstants.ASN1IdentifierCompositeNameMap.get(new ASN1ObjectIdentifier(oid))); + } + } + } + + public void testSigningAndVerificationInternal() + throws Exception + { + for (String oid : compositeSignaturesOIDs) + { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(oid, "BC"); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + Signature signature = Signature.getInstance(oid, "BC"); + signature.initSign(keyPair.getPrivate()); + signature.update(Strings.toUTF8ByteArray(messageToBeSigned)); + byte[] signatureValue = signature.sign(); + + signature.initVerify(keyPair.getPublic()); + signature.update(Strings.toUTF8ByteArray(messageToBeSigned)); + TestCase.assertTrue(signature.verify(signatureValue)); + } + } + + /* + //TODO: samples now out of date + public void testDecodingAndVerificationExternal() + throws Exception + { + InputStream is = TestResourceFinder.findTestResource("pqc/composite", "compositeSignatures.sample"); + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + String line = null; + int count = 0; + while ((line = reader.readLine()) != null) + { + if (line.length() == 0) + { + continue; + } + + String[] lineParts = line.split(";"); + + if (lineParts.length != 4) + { + throw new IllegalStateException("Input file has unexpected format."); + } + String oid = lineParts[0]; + String signatureValueBase64 = lineParts[1]; + String publicKeyBase64 = lineParts[2]; + String messageBase64 = lineParts[3]; + + X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(Base64.decode(publicKeyBase64)); + KeyFactory keyFactory = KeyFactory.getInstance(oid, "BC"); + CompositePublicKey compositePublicKey = (CompositePublicKey)keyFactory.generatePublic(pubKeySpec); + + Signature signature = Signature.getInstance(oid, "BC"); + signature.initVerify(compositePublicKey); + signature.update(Base64.decode(messageBase64)); + assertTrue(oid.toString(), signature.verify(Base64.decode(signatureValueBase64))); + count++; + } + + assertEquals(compositeSignaturesOIDs.length, count); + } + */ +} diff --git a/prov/src/test/java/org/bouncycastle/jcajce/provider/test/GeneralKeyTest.java b/prov/src/test/java/org/bouncycastle/jcajce/provider/test/GeneralKeyTest.java index 34d95bbe27..781effb48b 100644 --- a/prov/src/test/java/org/bouncycastle/jcajce/provider/test/GeneralKeyTest.java +++ b/prov/src/test/java/org/bouncycastle/jcajce/provider/test/GeneralKeyTest.java @@ -328,8 +328,8 @@ public void testRSA() priv = keyFact.generatePrivate(new RSAPrivateKeySpec(((RSAPrivateKey)priv).getModulus(), ((RSAPrivateKey)priv).getPrivateExponent())); - assertEquals(priv, priv); - assertFalse(priv.equals(pub)); + assertTrue(priv.equals(priv)); + assertFalse(priv.equals(pub));// priv.equals(pub)); doSerialisationCheck(priv); @@ -365,8 +365,8 @@ private void doBasicTest(String algorithm, KeyPair kp) assertEquals(algorithm, pub.getAlgorithm()); assertEquals(algorithm, priv.getAlgorithm()); - assertEquals(pub, pub); - assertEquals(priv, priv); + assertTrue(pub.equals(pub)); + assertTrue(priv.equals(priv)); assertFalse(pub.equals(priv)); assertFalse(priv.equals(pub)); diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/AEADTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/AEADTest.java index a6eed872bb..19e7020cf3 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/AEADTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/AEADTest.java @@ -105,7 +105,7 @@ private void testTampering(boolean aeadAvailable) { if (!e.getClass().getName().equals("javax.crypto.AEADBadTagException")) { - fail("Tampered AEAD ciphertext should fail with AEADBadTagException when available."); + fail("Tampered AEAD ciphertext should fail with AEADBadTagException when available, got: "+e.getClass().getName()); } } } diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/ARIATest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/ARIATest.java index c49691e7ec..e366aeae6d 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/ARIATest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/ARIATest.java @@ -14,8 +14,8 @@ import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; -import org.bouncycastle.asn1.nsri.NSRIObjectIdentifiers; import org.bouncycastle.crypto.prng.FixedSecureRandom; +import org.bouncycastle.internal.asn1.nsri.NSRIObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/AllTests.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/AllTests.java index 9ce60e03b1..061f1fdb2f 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/AllTests.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/AllTests.java @@ -14,7 +14,7 @@ public class AllTests { public static void main(String[] args) { - PrintTestResult.printResult( junit.textui.TestRunner.run(suite())); + PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); } public static Test suite() diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/BCFKSStoreTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/BCFKSStoreTest.java index 0f39dd7555..3f4d0c57cb 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/BCFKSStoreTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/BCFKSStoreTest.java @@ -2,7 +2,6 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.Key; @@ -34,8 +33,6 @@ import org.bouncycastle.asn1.bc.ObjectStore; import org.bouncycastle.asn1.bc.ObjectStoreIntegrityCheck; import org.bouncycastle.asn1.bc.PbkdMacIntegrityCheck; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; -import org.bouncycastle.asn1.misc.ScryptParams; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; @@ -48,6 +45,8 @@ import org.bouncycastle.crypto.util.PBKDF2Config; import org.bouncycastle.crypto.util.PBKDFConfig; import org.bouncycastle.crypto.util.ScryptConfig; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.ScryptParams; import org.bouncycastle.jcajce.BCFKSLoadStoreParameter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; @@ -540,6 +539,7 @@ public void shouldStoreOnePrivateKeyWithChain() ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(false)); + X509Certificate finalCert = TestUtils.createSelfSignedCert("CN=Final", "SHA1withRSA", kp2); X509Certificate interCert = TestUtils.createCert( TestUtils.getCertSubject(finalCert), @@ -687,11 +687,7 @@ private void checkOnePrivateKey(PrivateKey key, KeyStore store1, X509Certificate isTrue("", "privkey".equals(en2.nextElement())); isTrue("", !en2.hasMoreElements()); - ByteArrayOutputStream Bout2 = new ByteArrayOutputStream(); - store1.store(Bout2, "fred".toCharArray()); - FileOutputStream fOut = new FileOutputStream("/tmp/b.fks"); - fOut.write(Bout2.toByteArray()); - fOut.close(); + privateKeyStorageCheck(store2, "privkey", key, certs[0], passwd); // check invalid load with content @@ -1590,30 +1586,30 @@ public String getName() public void performTest() throws Exception { -// shouldCreateEmptyBCFKSNoPassword(); -// shouldCreateEmptyBCFKSPassword(); -// shouldStoreMultipleKeys(); -// shouldStoreOneCertificate(); -// shouldStoreOneCertificateWithECDSASignature(); -// shouldStoreOneCertificateWithDSASignature(); -// shouldStoreOneCertificateWithRSASignature(); -// shouldStoreOneCertificateWithECDSASignatureAndCertificates(); -// shouldStoreOneECKeyWithChain(); -// shouldStoreOnePrivateKey(); + shouldCreateEmptyBCFKSNoPassword(); + shouldCreateEmptyBCFKSPassword(); + shouldStoreMultipleKeys(); + shouldStoreOneCertificate(); + shouldStoreOneCertificateWithECDSASignature(); + shouldStoreOneCertificateWithDSASignature(); + shouldStoreOneCertificateWithRSASignature(); + shouldStoreOneCertificateWithECDSASignatureAndCertificates(); + shouldStoreOneECKeyWithChain(); + shouldStoreOnePrivateKey(); shouldStoreOnePrivateKeyWithChain(); -// shouldStoreOneSecretKey(); -// shouldStoreSecretKeys(); -// shouldStoreUsingSCRYPT(); -// shouldStoreUsingPBKDF2(); -// shouldFailOnWrongPassword(); -// shouldParseKWPKeyStore(); -// shouldFailOnRemovesOrOverwrite(); -// shouldParseOldStores(); -// shouldStoreUsingKWP(); -// //shouldRejectInconsistentKeys(); -// shouldStoreOnePrivateKeyWithChainEdDSA(); -// shouldWorkWithNullLoadStoreParameter(); -// testJKS(); + shouldStoreOneSecretKey(); + shouldStoreSecretKeys(); + shouldStoreUsingSCRYPT(); + shouldStoreUsingPBKDF2(); + shouldFailOnWrongPassword(); + shouldParseKWPKeyStore(); + shouldFailOnRemovesOrOverwrite(); + shouldParseOldStores(); + shouldStoreUsingKWP(); + //shouldRejectInconsistentKeys(); + shouldStoreOnePrivateKeyWithChainEdDSA(); + shouldWorkWithNullLoadStoreParameter(); + testJKS(); } public static void main( diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/CamelliaTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/CamelliaTest.java index 9ee56c77be..3d64eb5752 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/CamelliaTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/CamelliaTest.java @@ -1,13 +1,5 @@ package org.bouncycastle.jce.provider.test; -import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.util.encoders.Hex; - -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; -import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -15,6 +7,15 @@ import java.security.Key; import java.security.Security; +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.spec.SecretKeySpec; + +import org.bouncycastle.internal.asn1.ntt.NTTObjectIdentifiers; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.encoders.Hex; + /** * basic test class for Camellia */ diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/CertPathBuilderTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/CertPathBuilderTest.java index 8221a86763..07a1e6b992 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/CertPathBuilderTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/CertPathBuilderTest.java @@ -81,9 +81,9 @@ private void v0Test() X509Certificate interCert = TestUtils.generateIntermediateCert(interPair.getPublic(), rootPair.getPrivate(), rootCert); X509Certificate endCert = TestUtils.generateEndEntityCert(endPair.getPublic(), interPair.getPrivate(), interCert); - BigInteger revokedSerialNumber = BigInteger.valueOf(2); - X509CRL rootCRL = TestUtils.createCRL(rootCert, rootPair.getPrivate(), revokedSerialNumber); - X509CRL interCRL = TestUtils.createCRL(interCert, interPair.getPrivate(), revokedSerialNumber); + BigInteger revokedSerialNumber = BigInteger.valueOf(2); + X509CRL rootCRL = TestCertificateGen.createCRL(rootCert, rootPair.getPrivate(), revokedSerialNumber); + X509CRL interCRL = TestCertificateGen.createCRL(interCert, interPair.getPrivate(), revokedSerialNumber); // create CertStore to support path building List list = new ArrayList(); diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java index 8f8fe305ce..8416ace7ab 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java @@ -42,27 +42,30 @@ import java.util.Date; import java.util.Enumeration; import java.util.HashSet; +import java.util.Hashtable; import java.util.List; import java.util.Set; +import java.util.Vector; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1IA5String; import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; -import org.bouncycastle.asn1.DERBitString; +import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; -import org.bouncycastle.asn1.misc.NetscapeCertType; -import org.bouncycastle.asn1.misc.NetscapeRevocationURL; -import org.bouncycastle.asn1.misc.VerisignCzagExtension; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.RFC4519Style; @@ -71,13 +74,16 @@ import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.KeyUsage; -import org.bouncycastle.asn1.x509.X509CertificateStructure; -import org.bouncycastle.asn1.x509.X509Extension; -import org.bouncycastle.asn1.x509.X509Extensions; -import org.bouncycastle.jce.X509Principal; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x509.Time; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.NetscapeCertType; +import org.bouncycastle.internal.asn1.misc.NetscapeRevocationURL; +import org.bouncycastle.internal.asn1.misc.VerisignCzagExtension; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; +import org.bouncycastle.util.Properties; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; @@ -387,11 +393,157 @@ private void constraintTest() } + private static byte[] crlFake = Base64.decode( + "MIIBzTCBtgIBATANBgkqhkiG9w0BAQsFADAiMQswCQYDVQQGEwJYWDETMBEGA1UE" + + "CgwKQ1JMcyAnciBVcxcNMjQwMzI1MTg0NzAwWhcNMjQwNDAxMTg0NzAwWqBgMF4w" + + "CgYDVR0UBAMCAQEwHwYDVR0jBBgwFoAU/NE0t8uklbG2WeoLBWIe6JqPtDowLwYD" + + "VR0cAQH/BCUwI6AeoByGGmh0dHA6Ly9mb28uZXhhbXBsZS9jcmwuZGxshAH/MA0G" + + "CSqGSIb3DQEBCwUAA4IBAQAN8oDSvWsg3JvUJ4MkXvczaFb72VH0J/VL5PV2cBSm" + + "MfaVBKnUsNr1IcxT06KF8gNrDTpKqJ9fetO290swZfcPt9sEVUBVQUpdlQc3tya1" + + "jYWmFkA3tkpqH5rBCQa3CBm1Cg8cbFBtwWgWr70NsVvfD6etjAEP9Ze+MSXnGV0p" + + "w9EeOV07HnSD/PGQwqCiaSn5DdIDVoH8eFSGmgNLw+b4SwUjmz8PqsZwvHxJvleV" + + "1D8cj7zdR4ywgRMjEfJZ8Bp+Tdu64Gv0doDS0iEJIshLHYkcW1okpq/tPm8kKAbD" + + "reparePNQwhScVcDiSL73eEBIPokgG3QhohiucP5MeF1"); + + private static byte[] crlIssuer = Base64.decode( + "MIIDMzCCAhugAwIBAgIUPOARSBZTC4SU8f/RrhdPXfZVh9EwDQYJKoZIhvcNAQEL\n" + + "BQAwIzELMAkGA1UEBhMCWFgxFDASBgNVBAoMC0NlcnRzICdyIFVzMB4XDTI0MDMy\n" + + "NTE4NDcwMFoXDTI1MDMyNTE4NDcwMFowIjELMAkGA1UEBhMCWFgxEzARBgNVBAoM\n" + + "CkNSTHMgJ3IgVXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCleY8S\n" + + "gEwPfvfUcIuix5dC7MgFudzaJROINa3u7cW0Rh+mivfepuGl9I683qinDebmE1Sq\n" + + "bVyHDi4RqpM+BCQ0EnW6idriL+13BqNU4QRd68gwF4eNXw9rtmixVGvcvcUngNnz\n" + + "XPrJyWqarjFQ8ECH09I9q/Fv3OAWPmTbzAgWdXV7cx/pCHFNEU3qSWeXkbumKV5l\n" + + "DqTs/J82/n5HZfRjUVIMbf4X6/9wA9BQX8aYbUMng49M5GVd/bg3RXGBLF4lXIUd\n" + + "IPpGYrKT2V+EFq9yKqbnXawTXKw7mBNoIbaN950f1VMdf8czsPNxdeCHJzNtQV70\n" + + "aOqa2hLzxAxzAz7DAgMBAAGjYDBeMB0GA1UdDgQWBBRdiKBrVfofgq1XL7AZu3Wk\n" + + "t83qzjAfBgNVHSMEGDAWgBS04fYwVDNa70uNyIJtV75OHwEHmTAMBgNVHRMBAf8E\n" + + "AjAAMA4GA1UdDwEB/wQEAwIBAjANBgkqhkiG9w0BAQsFAAOCAQEAF5XrOXxVfCFb\n" + + "S5EXxpAk8iXMAOfcfYiWEUT9DdJ3ABeAFnhbiLdlKq8J3BGr1Iiveo2pE9fKz9s/\n" + + "2tZjzbe9Kfg05mfyn9DS5AoWjieW5zaAZpDR9pKkq9/d7pDTbHwvDnNLoMMHRPZP\n" + + "2tsBhjcPPay8zWKLz+8dfPyrGpbGfFg/zd3KBNefc12Sl0Iw6XQUaIpDxyJBvpIU\n" + + "0Xo1R1F22gJ7oG1zI28mr6SGyBvJ8r1c0sQ1qQt+iA/0M5qXRjuLIhO8/ajlMQwP\n" + + "Sdasa53HOErxWqsxNRpwJkaynSiKSwGeqLxdTYwWcWrsYB7RqKgjbQnhSBSd3TKm\n" + + "H2P790A+oQ=="); + + private static byte[] crlSecretary = Base64.decode( + "MIIDejCCAmKgAwIBAgIUI4Xq9G+KWEr2NPfGbY4A2dfXp50wDQYJKoZIhvcNAQEL\n" + + "BQAwIzELMAkGA1UEBhMCWFgxFDASBgNVBAoMC0NlcnRzICdyIFVzMB4XDTI0MDMy\n" + + "NTE4NDcwMFoXDTI1MDMyNTE4NDcwMFowIjELMAkGA1UEBhMCWFgxEzARBgNVBAoM\n" + + "CkNSTHMgJ3IgVXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCkynb7\n" + + "zm0ooFfVkkqj9ppBiTh0YGUqv7/jQoFMDJ/XVtYGUJdyPTXoD9cP1ZypzONmK07U\n" + + "Rc0WMug47hv2tZgrVOxqrGQqDD7e4LM3luinwG5eW3XYT4eJr6Urbk8KSdKSYzqj\n" + + "wjY217KQ8DDgioUInWBUyz5UWrG014QbcEgwX0JGpQrwaaPQtbUd58f5x/LCdsXC\n" + + "p41ySSNsYoKhDawnNblLVxhr+Vp7eQ0wj7LaD/+k12ZDMQbkj3PsGBiWqm+e2uwV\n" + + "n9cq9kK6ARN0svju5dpDw5hERRrQ1GR87WvHWHUtmnR7s7+xacRpZTUvJ5Xsi0Rf\n" + + "Eq1SDPYPyT8ksrt7AgMBAAGjgaYwgaMwHQYDVR0OBBYEFPzRNLfLpJWxtlnqCwVi\n" + + "Huiaj7Q6MB8GA1UdIwQYMBaAFLTh9jBUM1rvS43Igm1Xvk4fAQeZMAwGA1UdEwEB\n" + + "/wQCMAAwUwYDVR0fBEwwSjBIoB6gHIYaaHR0cDovL2Zvby5leGFtcGxlL2NybC5k\n" + + "bGyiJqQkMCIxCzAJBgNVBAYTAlhYMRMwEQYDVQQKDApDUkxzICdyIFVzMA0GCSqG\n" + + "SIb3DQEBCwUAA4IBAQBY72Z1LwWsVbnYl6ZhWDAAuy0bwTMKwF8JwpG1PpFzC6p0\n" + + "DJd36c3ZOzRYgjpmApi3X9lFx0oyuZOjBIlMtqnXgKjYBytF2jmf8DziIsCnvMI8\n" + + "1IiFRjWjm56y0xaxBqv9yzvTqKG198vxakxPAUn8oONMtLvqHAvoQyHCBej5Xirg\n" + + "joJkPeHeRwl9sgYZcqowNHGHiBX8KtXeatkHkpmxZO5cunGD+RcOnBpJEfZJhopX\n" + + "GaW1DPRY0qqPFhnLcQsv8UZEyDxyYH/HuGaZy3u9lT1SqlOx2zzQnTK6EyIc92n3\n" + + "suILIm4MBrqXYXUlHkMzLmpJGH9lg9xaFn3vCU7Q"); + + private static byte[] crlRoot = Base64.decode( + "MIIDFjCCAf6gAwIBAgIUF/hP3a/TkmHlfhYYUiFNw/H5lMwwDQYJKoZIhvcNAQEL\n" + + "BQAwIzELMAkGA1UEBhMCWFgxFDASBgNVBAoMC0NlcnRzICdyIFVzMB4XDTI0MDMy\n" + + "NTE4NDcwMFoXDTI1MDMyNTE4NDcwMFowIzELMAkGA1UEBhMCWFgxFDASBgNVBAoM\n" + + "C0NlcnRzICdyIFVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAomfH\n" + + "KuGQzqGkFGSsKLESgJbRRRQsIuJ19w/sumNHNPnbl93rEgdoF1y2yUFcY0ZipZCg\n" + + "lIpfhOkp6I+WLtF59t8vLw30P1ZBwmbjC54EwGLH3WRDPS0j+33TfDjNdQRwY4u6\n" + + "j2EK6drXPhBPsaG0map3VfWQelaStAoIC6evoYFzfO2E7Ik4xv06U47WHefseBue\n" + + "ZcsFvfW3bf/E04PFc2YssUyqjiaa0sU/w7l9xj2P+vCqpM393ZWJX6GRcns/wUJ/\n" + + "na7iXpIO82EV3/eExeXoHc912L+m0HoB86RYQat+wyhX6Z5i1ApU6zXqGU7D8cPD\n" + + "DrbIjwLDMwKPbC9FjwIDAQABo0IwQDAdBgNVHQ4EFgQUtOH2MFQzWu9LjciCbVe+\n" + + "Th8BB5kwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAgQwDQYJKoZIhvcN\n" + + "AQELBQADggEBAJGeqkMrzOgesGaCHJJgX/qpG7bp4KPPL0bi7EYnT1cuy5ss053I\n" + + "Ooh5APYn+GrufWjYn4mwSekvuRTB6VdR4YMeoYPMxWJRp3l7s0aHLo98BbW9WX+4\n" + + "ju+K/Dndbrs1v7r4IB79hu4QtR7BVaEQ8UjqY+/I1VeYKtAd7scQGKpSNOPN3YVu\n" + + "+QY3fXy+nfDhj7drUeAHVj+Qz/6RZOIhmIPj7adsZhDQwvMG3cAkAfVGncP7n+cN\n" + + "nqZyYu8PPQp4g+QM42kXXBu5N8QwkCtcMe2nvKiQvEOZww70N3mTIK8CSxLla5pI\n" + + "635lNPBZubGF6m35P7EArB0JuU2KYNgUxis=\n"); + + private static byte[] crlVictim = Base64.decode( + "MIIDjTCCAnWgAwIBAgIUW8wsCzJEg7WzpMvkUKyloeKqKLYwDQYJKoZIhvcNAQEL\n" + + "BQAwIzELMAkGA1UEBhMCWFgxFDASBgNVBAoMC0NlcnRzICdyIFVzMB4XDTI0MDMy\n" + + "NTE4NDcwMFoXDTI1MDMyNTE4NDcwMFowJTELMAkGA1UEBhMCWFgxFjAUBgNVBAoM\n" + + "DVVubHVja3kgJ3IgV2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6\n" + + "erJm/+hf6IhoqCYfX+y6uiVSSF/J6VyENk+oXS2g71g1sapGCXRO8xlDqH1rhFzC\n" + + "IJ56nC14K9w4r+6D3FUKw4G5sKMRTMX7U5brjd8wRd3XHAIUdSCP9SVrNz6bmcjf\n" + + "B27vBT0ifIC7bQg7Y01BoqnBPObuwT7ufk951rFzCIagzSylzR/GRNhMYo4rO6jw\n" + + "Ih84LpAxUQ1vFAaBb5GCVhXoUWecu+RtIaIDo9tn8PF16O6VW8zPmsoV9HELD8Sx\n" + + "HuoSXXcsF2OW55XLeAO+l1tikAVqA6nUvQx03bb3TW7W+3v6nGzG308fHA32TdLk\n" + + "ZLK9nPnF5hF4pFmWpjwHAgMBAAGjgbYwgbMwHQYDVR0OBBYEFMitbC8lM9mw/hc6\n" + + "TnvL5vpAyfpZMB8GA1UdIwQYMBaAFLTh9jBUM1rvS43Igm1Xvk4fAQeZMAwGA1Ud\n" + + "EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMFMGA1UdHwRMMEowSKAeoByGGmh0dHA6\n" + + "Ly9mb28uZXhhbXBsZS9jcmwuZGxsoiakJDAiMQswCQYDVQQGEwJYWDETMBEGA1UE\n" + + "CgwKQ1JMcyAnciBVczANBgkqhkiG9w0BAQsFAAOCAQEAmysx1oqEUDUpLg98K9Rw\n" + + "AXTykVDjjG0ZKg7UtDcaIeBfomhXv+Sh2oz9zqqZQ5/4HGIwe2fAsbQZmlH//8Yb\n" + + "ovEZCo3WmhJSyTDB2KLebPJLw5HOi7QrAjYJWKR+pkuQmxMPoSAdMXRkiBmzYjZL\n" + + "lxHaT6Y2IMZ6kVtHCmcOFaHWJyPAUZ4ymO03cb/1M73ioecf9jMgIf7YBaopty2p\n" + + "X2GVHaCE1m7u+2WU45b34PBRY/ZvhZvuJKi3TfuaLMJFPz6HY4XbHPnlBP4EwXpC\n" + + "5VaJvOMXWZPWh/yrCVEKMzFxesbwHV/vyOUls0P4kIY383/78MvzchHLhwR7h2fy\n" + + "Iw=="); + + private void testNoKeyUsageCRLSigner() + throws Exception + { + CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); + + X509Certificate root = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(crlRoot)); + X509Certificate crlIss = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(crlIssuer)); + X509Certificate secretary = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(crlSecretary)); + X509Certificate victim = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(crlVictim)); + + X509CRL fakeCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(crlFake)); + + List list = new ArrayList(); + +// list.add(root); +// list.add(crlIss); + list.add(secretary); + list.add(victim); + list.add(fakeCrl); + + System.setProperty("org.bouncycastle.x509.allow_ca_without_crl_sign", "false"); + + CertPath cp = cf.generateCertPath(Collections.singletonList(victim)); + + CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); + CertStore store = CertStore.getInstance("Collection", ccsp, "BC"); + Date validDate = new Date(fakeCrl.getThisUpdate().getTime() + 60 * 60 * 1000); + + //Searching for rootCert by subjectDN without CRL + Set trust = new HashSet(); + trust.add(new TrustAnchor(root, null)); + // + CertPathValidator cpb = CertPathValidator.getInstance("PKIX", "BC"); + X509CertSelector targetConstraints = new X509CertSelector(); + targetConstraints.setSubject(victim.getSubjectX500Principal().getEncoded()); + PKIXParameters params = new PKIXParameters(trust); + params.addCertStore(store); + params.setDate(validDate); + + try + { + PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)cpb.validate(cp, params); + fail("path should have failed"); + } + catch (CertPathValidatorException e) + { + isTrue("No CRLs found for issuer \"o=Certs 'r Us,c=XX\"".equals(e.getMessage())); + } + + System.clearProperty("org.bouncycastle.x509.allow_ca_without_crl_sign"); + } + public void performTest() throws Exception { constraintTest(); - + testNoKeyUsageCRLSigner(); CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); // initialise CertStore @@ -425,6 +577,8 @@ public void performTest() MyChecker checker = new MyChecker(); param.addCertPathChecker(checker); + System.setProperty("org.bouncycastle.x509.allow_ca_without_crl_sign", "true"); + PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)cpv.validate(cp, param); PolicyNode policyTree = result.getPolicyTree(); @@ -457,6 +611,8 @@ public void performTest() result = (PKIXCertPathValidatorResult)cpv.validate(cp, param); + System.setProperty("org.bouncycastle.x509.allow_ca_without_crl_sign", "false"); + isTrue(result.getTrustAnchor().getTrustedCert().equals(rootCert)); // @@ -508,6 +664,8 @@ public void performTest() } } + System.clearProperty("org.bouncycastle.x509.allow_ca_without_crl_sign"); + checkCircProcessing(); checkPolicyProcessingAtDomainMatch(); validateWithExtendedKeyUsage(); @@ -583,9 +741,9 @@ private void checkInvalidCertPath() private void checkInvalidPath(byte[] root, byte[] inter, byte[] ee, String expected) throws Exception { - X509Certificate rootCert = new X509CertificateObject(X509CertificateStructure.getInstance(root)); - X509Certificate interCert = new X509CertificateObject(X509CertificateStructure.getInstance(inter)); - X509Certificate finalCert = new X509CertificateObject(X509CertificateStructure.getInstance(ee)); + X509Certificate rootCert = new X509CertificateObject(new DodgyCertificate(root)); + X509Certificate interCert = new X509CertificateObject(new DodgyCertificate(inter)); + X509Certificate finalCert = new X509CertificateObject(new DodgyCertificate(ee)); List list = new ArrayList(); list.add(rootCert); list.add(interCert); @@ -696,14 +854,14 @@ public static class X509CertificateObject static final String CRL_NUMBER = Extension.cRLNumber.getId(); static final String ANY_POLICY = "2.5.29.32.0"; - private org.bouncycastle.asn1.x509.X509CertificateStructure c; + private DodgyCertificate c; private BasicConstraints basicConstraints; private boolean[] keyUsage; private boolean hashValueSet; private int hashValue; public X509CertificateObject( - org.bouncycastle.asn1.x509.X509CertificateStructure c) + DodgyCertificate c) throws CertificateParsingException { this.c = c; @@ -727,7 +885,7 @@ public X509CertificateObject( byte[] bytes = this.getExtensionBytes("2.5.29.15"); if (bytes != null) { - ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes)); + ASN1BitString bits = ASN1BitString.getInstance(ASN1Primitive.fromByteArray(bytes)); bytes = bits.getBytes(); int length = (bytes.length * 8) - bits.getPadBits(); @@ -773,7 +931,7 @@ public void checkValidity( public int getVersion() { - return c.getVersion(); + return c.getVersion().intValueExact(); } public BigInteger getSerialNumber() @@ -783,14 +941,7 @@ public BigInteger getSerialNumber() public Principal getIssuerDN() { - try - { - return new X509Principal(X500Name.getInstance(c.getIssuer().getEncoded())); - } - catch (IOException e) - { - return null; - } + return getIssuerX500Principal(); } public X500Principal getIssuerX500Principal() @@ -807,7 +958,7 @@ public X500Principal getIssuerX500Principal() public Principal getSubjectDN() { - return new X509Principal(X500Name.getInstance(c.getSubject().toASN1Primitive())); + return getSubjectX500Principal(); } public X500Principal getSubjectX500Principal() @@ -991,26 +1142,18 @@ public List getExtendedKeyUsage() public int getBasicConstraints() { - if (basicConstraints != null) + if (basicConstraints == null || !basicConstraints.isCA()) { - if (basicConstraints.isCA()) - { - if (basicConstraints.getPathLenConstraint() == null) - { - return Integer.MAX_VALUE; - } - else - { - return basicConstraints.getPathLenConstraint().intValue(); - } - } - else - { - return -1; - } + return -1; } - return -1; + ASN1Integer pathLenConstraint = basicConstraints.getPathLenConstraintInteger(); + if (pathLenConstraint == null) + { + return Integer.MAX_VALUE; + } + + return pathLenConstraint.intPositiveValueExact(); } public Collection getSubjectAlternativeNames() @@ -1030,7 +1173,7 @@ public Set getCriticalExtensionOIDs() if (this.getVersion() == 3) { Set set = new HashSet(); - X509Extensions extensions = c.getTBSCertificate().getExtensions(); + DodgyExtensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { @@ -1039,7 +1182,7 @@ public Set getCriticalExtensionOIDs() while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); - X509Extension ext = extensions.getExtension(oid); + Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { @@ -1056,14 +1199,14 @@ public Set getCriticalExtensionOIDs() private byte[] getExtensionBytes(String oid) { - X509Extensions exts = c.getTBSCertificate().getExtensions(); + DodgyExtensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { - X509Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); + Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { - return ext.getValue().getOctets(); + return ext.getExtnValue().getOctets(); } } @@ -1072,17 +1215,17 @@ private byte[] getExtensionBytes(String oid) public byte[] getExtensionValue(String oid) { - X509Extensions exts = c.getTBSCertificate().getExtensions(); + DodgyExtensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { - X509Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); + Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { - return ext.getValue().getEncoded(); + return ext.getExtnValue().getEncoded(); } catch (Exception e) { @@ -1099,7 +1242,7 @@ public Set getNonCriticalExtensionOIDs() if (this.getVersion() == 3) { Set set = new HashSet(); - X509Extensions extensions = c.getTBSCertificate().getExtensions(); + DodgyExtensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { @@ -1108,7 +1251,7 @@ public Set getNonCriticalExtensionOIDs() while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); - X509Extension ext = extensions.getExtension(oid); + Extension ext = extensions.getExtension(oid); if (!ext.isCritical()) { @@ -1127,7 +1270,7 @@ public boolean hasUnsupportedCriticalExtension() { if (this.getVersion() == 3) { - X509Extensions extensions = c.getTBSCertificate().getExtensions(); + DodgyExtensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { @@ -1153,7 +1296,7 @@ public boolean hasUnsupportedCriticalExtension() continue; } - X509Extension ext = extensions.getExtension(oid); + Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { @@ -1277,7 +1420,7 @@ public String toString() } } - X509Extensions extensions = c.getTBSCertificate().getExtensions(); + DodgyExtensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { @@ -1291,11 +1434,11 @@ public String toString() while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); - X509Extension ext = extensions.getExtension(oid); + Extension ext = ((DodgyExtensions)extensions).getExtension(oid); - if (ext.getValue() != null) + if (ext.getExtnValue() != null) { - byte[] octs = ext.getValue().getOctets(); + byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append(ext.isCritical()).append(") "); try @@ -1310,7 +1453,7 @@ else if (oid.equals(Extension.keyUsage)) } else if (oid.equals(MiscObjectIdentifiers.netscapeCertType)) { - buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl); + buf.append(new NetscapeCertType((ASN1BitString)dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL)) { @@ -1524,5 +1667,485 @@ private static Collection getAlternativeNames(byte[] extVal) } } } + + private class DodgyCertificate + extends ASN1Object + { + ASN1Sequence seq; + DodgyTBSCertificate tbsCert; + AlgorithmIdentifier sigAlgId; + ASN1BitString sig; + + DodgyCertificate( + byte[] encoding) + { + this.seq = ASN1Sequence.getInstance(encoding); + + // + // correct x509 certficate + // + if (seq.size() == 3) + { + tbsCert = new DodgyTBSCertificate(ASN1Sequence.getInstance(seq.getObjectAt(0))); + sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); + + sig = ASN1BitString.getInstance(seq.getObjectAt(2)); + } + else + { + throw new IllegalArgumentException("sequence wrong size for a certificate"); + } + } + + public DodgyTBSCertificate getTBSCertificate() + { + return tbsCert; + } + + public ASN1Integer getVersion() + { + return tbsCert.getVersion(); + } + + public int getVersionNumber() + { + return tbsCert.getVersionNumber(); + } + + public ASN1Integer getSerialNumber() + { + return tbsCert.getSerialNumber(); + } + + public X500Name getIssuer() + { + return tbsCert.getIssuer(); + } + + public Time getStartDate() + { + return tbsCert.getStartDate(); + } + + public Time getEndDate() + { + return tbsCert.getEndDate(); + } + + public X500Name getSubject() + { + return tbsCert.getSubject(); + } + + public SubjectPublicKeyInfo getSubjectPublicKeyInfo() + { + return tbsCert.getSubjectPublicKeyInfo(); + } + + public AlgorithmIdentifier getSignatureAlgorithm() + { + return sigAlgId; + } + + public ASN1BitString getSignature() + { + return sig; + } + + public ASN1Primitive toASN1Primitive() + { + return seq; + } + } + + private class DodgyTBSCertificate + extends ASN1Object + { + ASN1Sequence seq; + + ASN1Integer version; + ASN1Integer serialNumber; + AlgorithmIdentifier signature; + X500Name issuer; + Time startDate, endDate; + X500Name subject; + SubjectPublicKeyInfo subjectPublicKeyInfo; + ASN1BitString issuerUniqueId; + ASN1BitString subjectUniqueId; + DodgyExtensions extensions; + + private DodgyTBSCertificate( + ASN1Sequence seq) + { + int seqStart = 0; + + this.seq = seq; + + // + // some certficates don't include a version number - we assume v1 + // + if (seq.getObjectAt(0) instanceof ASN1TaggedObject) + { + version = ASN1Integer.getInstance((ASN1TaggedObject)seq.getObjectAt(0), true); + } + else + { + seqStart = -1; // field 0 is missing! + version = new ASN1Integer(0); + } + + boolean isV1 = false; + boolean isV2 = false; + + if (version.hasValue(0)) + { + isV1 = true; + } + else if (version.hasValue(1)) + { + isV2 = true; + } +// else if (!version.hasValue(2)) +// { +// throw new IllegalArgumentException("version number not recognised"); +// } + + serialNumber = ASN1Integer.getInstance(seq.getObjectAt(seqStart + 1)); + + signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqStart + 2)); + issuer = X500Name.getInstance(seq.getObjectAt(seqStart + 3)); + + // + // before and after dates + // + ASN1Sequence dates = (ASN1Sequence)seq.getObjectAt(seqStart + 4); + + startDate = Time.getInstance(dates.getObjectAt(0)); + endDate = Time.getInstance(dates.getObjectAt(1)); + + subject = X500Name.getInstance(seq.getObjectAt(seqStart + 5)); + + // + // public key info. + // + subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(seqStart + 6)); + + int extras = seq.size() - (seqStart + 6) - 1; +// if (extras != 0 && isV1) +// { +// throw new IllegalArgumentException("version 1 certificate contains extra data"); +// } + + while (extras > 0) + { + ASN1TaggedObject extra = (ASN1TaggedObject)seq.getObjectAt(seqStart + 6 + extras); + + switch (extra.getTagNo()) + { + case 1: + issuerUniqueId = ASN1BitString.getInstance(extra, false); + break; + case 2: + subjectUniqueId = ASN1BitString.getInstance(extra, false); + break; + case 3: +// if (isV2) +// { +// throw new IllegalArgumentException("version 2 certificate cannot contain extensions"); +// } + extensions = new DodgyExtensions(ASN1Sequence.getInstance(extra, true)); + break; + default: + throw new IllegalArgumentException("Unknown tag encountered in structure: " + extra.getTagNo()); + } + extras--; + } + } + + public int getVersionNumber() + { + return version.intValueExact() + 1; + } + + public ASN1Integer getVersion() + { + return version; + } + + public ASN1Integer getSerialNumber() + { + return serialNumber; + } + + public AlgorithmIdentifier getSignature() + { + return signature; + } + + public X500Name getIssuer() + { + return issuer; + } + + public Time getStartDate() + { + return startDate; + } + + public Time getEndDate() + { + return endDate; + } + + public X500Name getSubject() + { + return subject; + } + + public SubjectPublicKeyInfo getSubjectPublicKeyInfo() + { + return subjectPublicKeyInfo; + } + + public ASN1BitString getIssuerUniqueId() + { + return issuerUniqueId; + } + + public ASN1BitString getSubjectUniqueId() + { + return subjectUniqueId; + } + + public DodgyExtensions getExtensions() + { + return extensions; + } + + public ASN1Primitive toASN1Primitive() + { + if (Properties.getPropertyValue("org.bouncycastle.x509.allow_non-der_tbscert") != null) + { + if (Properties.isOverrideSet("org.bouncycastle.x509.allow_non-der_tbscert")) + { + return seq; + } + } + else + { + return seq; + } + + ASN1EncodableVector v = new ASN1EncodableVector(); + + // DEFAULT Zero + if (!version.hasValue(0)) + { + v.add(new DERTaggedObject(true, 0, version)); + } + + v.add(serialNumber); + v.add(signature); + v.add(issuer); + + // + // before and after dates + // + { + ASN1EncodableVector validity = new ASN1EncodableVector(2); + validity.add(startDate); + validity.add(endDate); + + v.add(new DERSequence(validity)); + } + + if (subject != null) + { + v.add(subject); + } + else + { + v.add(new DERSequence()); + } + + v.add(subjectPublicKeyInfo); + + // Note: implicit tag + if (issuerUniqueId != null) + { + v.add(new DERTaggedObject(false, 1, issuerUniqueId)); + } + + // Note: implicit tag + if (subjectUniqueId != null) + { + v.add(new DERTaggedObject(false, 2, subjectUniqueId)); + } + + if (extensions != null) + { + v.add(new DERTaggedObject(true, 3, extensions)); + } + + return new DERSequence(v); + } + } + + public class DodgyExtensions + extends ASN1Object + { + private Hashtable extensions = new Hashtable(); + private Vector ordering = new Vector(); + + /** + * Constructor from ASN1Sequence. + *

      + * The extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString) + *

      + */ + DodgyExtensions( + ASN1Sequence seq) + { + Enumeration e = seq.getObjects(); + + while (e.hasMoreElements()) + { + Extension ext = Extension.getInstance(e.nextElement()); + + extensions.put(ext.getExtnId(), ext); + ordering.addElement(ext.getExtnId()); + } + } + + /** + * return an Enumeration of the extension field's object ids. + */ + public Enumeration oids() + { + return ordering.elements(); + } + + /** + * return the extension represented by the object identifier + * passed in. + * + * @return the extension if it's present, null otherwise. + */ + public Extension getExtension( + ASN1ObjectIdentifier oid) + { + return (Extension)extensions.get(oid); + } + + /** + * return the parsed value of the extension represented by the object identifier + * passed in. + * + * @return the parsed value of the extension if it's present, null otherwise. + */ + public ASN1Encodable getExtensionParsedValue(ASN1ObjectIdentifier oid) + { + Extension ext = this.getExtension(oid); + + if (ext != null) + { + return ext.getParsedValue(); + } + + return null; + } + + /** + *
      +         *     Extensions        ::=   SEQUENCE SIZE (1..MAX) OF Extension
      +         *
      +         *     Extension         ::=   SEQUENCE {
      +         *        extnId            EXTENSION.&id ({ExtensionSet}),
      +         *        critical          BOOLEAN DEFAULT FALSE,
      +         *        extnValue         OCTET STRING }
      +         * 
      + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector vec = new ASN1EncodableVector(ordering.size()); + + Enumeration e = ordering.elements(); + while (e.hasMoreElements()) + { + ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); + Extension ext = (Extension)extensions.get(oid); + + vec.add(ext); + } + + return new DERSequence(vec); + } + + public boolean equivalent( + DodgyExtensions other) + { + if (extensions.size() != other.extensions.size()) + { + return false; + } + + Enumeration e1 = extensions.keys(); + + while (e1.hasMoreElements()) + { + Object key = e1.nextElement(); + + if (!extensions.get(key).equals(other.extensions.get(key))) + { + return false; + } + } + + return true; + } + + public ASN1ObjectIdentifier[] getExtensionOIDs() + { + return toOidArray(ordering); + } + + public ASN1ObjectIdentifier[] getNonCriticalExtensionOIDs() + { + return getExtensionOIDs(false); + } + + public ASN1ObjectIdentifier[] getCriticalExtensionOIDs() + { + return getExtensionOIDs(true); + } + + private ASN1ObjectIdentifier[] getExtensionOIDs(boolean isCritical) + { + Vector oidVec = new Vector(); + + for (int i = 0; i != ordering.size(); i++) + { + Object oid = ordering.elementAt(i); + + if (((Extension)extensions.get(oid)).isCritical() == isCritical) + { + oidVec.addElement(oid); + } + } + + return toOidArray(oidVec); + } + + private ASN1ObjectIdentifier[] toOidArray(Vector oidVec) + { + ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[oidVec.size()]; + + for (int i = 0; i != oids.length; i++) + { + oids[i] = (ASN1ObjectIdentifier)oidVec.elementAt(i); + } + return oids; + } + } } diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/CertTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/CertTest.java index 5ae780f7f5..227ac33ae2 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/CertTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/CertTest.java @@ -6,7 +6,6 @@ import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.KeyFactory; @@ -1387,27 +1386,27 @@ private void pemTest() { fail("PEM cert with extraneous header not read"); } - CRL crl = cf.generateCRL(new ByteArrayInputStream(PEMData.CRL_1.getBytes("US-ASCII"))); + CRL crl = cf.generateCRL(new ByteArrayInputStream(Strings.toByteArray(PEMData.CRL_1))); if (crl == null) { fail("PEM crl not read"); } - Collection col = cf.generateCertificates(new ByteArrayInputStream(PEMData.CERTIFICATE_2.getBytes("US-ASCII"))); + Collection col = cf.generateCertificates(new ByteArrayInputStream(Strings.toByteArray(PEMData.CERTIFICATE_2))); if (col.size() != 1 || !col.contains(cert)) { fail("PEM cert collection not right"); } - col = cf.generateCertificates(new ByteArrayInputStream((PEMData.CERTIFICATE_2 + "z\n").getBytes("US-ASCII"))); + col = cf.generateCertificates(new ByteArrayInputStream(Strings.toByteArray((PEMData.CERTIFICATE_2 + "z\n")))); if (col.size() != 1 || !col.contains(cert)) { fail("PEM cert collection with extra not right"); } - col = cf.generateCRLs(new ByteArrayInputStream(PEMData.CRL_2.getBytes("US-ASCII"))); + col = cf.generateCRLs(new ByteArrayInputStream(Strings.toByteArray(PEMData.CRL_2))); if (col.size() != 1 || !col.contains(crl)) { fail("PEM crl collection not right"); } - col = cf.generateCRLs(new ByteArrayInputStream((PEMData.CRL_2 + "z\n").getBytes("US-ASCII"))); + col = cf.generateCRLs(new ByteArrayInputStream(Strings.toByteArray((PEMData.CRL_2 + "z\n")))); if (col.size() != 1 || !col.contains(crl)) { fail("PEM crl collection with extra not right"); @@ -1429,9 +1428,9 @@ private void pemTest() } private static Certificate readPEMCert(CertificateFactory cf, String pemData) - throws CertificateException, UnsupportedEncodingException + throws CertificateException { - return cf.generateCertificate(new ByteArrayInputStream(pemData.getBytes("US-ASCII"))); + return cf.generateCertificate(new ByteArrayInputStream(Strings.toByteArray(pemData))); } private void pkcs7Test() @@ -1531,7 +1530,7 @@ private void pkcs7Test() fail("wrong number of Certs: " + certCol.size()); } - in = new ByteArrayInputStream(pemPKCS7.getBytes("US-ASCII")); + in = new ByteArrayInputStream(Strings.toByteArray(pemPKCS7)); certCol = cf.generateCertificates(in); in.reset(); diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/CertUniqueIDTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/CertUniqueIDTest.java index 283c50be3f..b61018bc98 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/CertUniqueIDTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/CertUniqueIDTest.java @@ -2,6 +2,7 @@ import java.math.BigInteger; import java.security.KeyFactory; +import java.security.KeyPair; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; @@ -10,13 +11,12 @@ import java.security.spec.RSAPublicKeySpec; import java.util.Date; import java.util.Set; -import java.util.Vector; -import org.bouncycastle.jce.X509Principal; +import org.bouncycastle.asn1.x500.X500NameBuilder; +import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.test.SimpleTest; -import org.bouncycastle.x509.X509V3CertificateGenerator; public class CertUniqueIDTest extends SimpleTest @@ -68,20 +68,13 @@ public void checkCreation1() // // distinguished name table. // - Vector ord = new Vector(); - Vector values = new Vector(); + X500NameBuilder nBldr = new X500NameBuilder(); - ord.addElement(X509Principal.C); - ord.addElement(X509Principal.O); - ord.addElement(X509Principal.L); - ord.addElement(X509Principal.ST); - ord.addElement(X509Principal.E); - - values.addElement("AU"); - values.addElement("The Legion of the Bouncy Castle"); - values.addElement("Melbourne"); - values.addElement("Victoria"); - values.addElement("feedback-crypto@bouncycastle.org"); + nBldr.addRDN(BCStyle.C, "AU"); + nBldr.addRDN(BCStyle.O,"The Legion of the Bouncy Castle"); + nBldr.addRDN(BCStyle.L, "Melbourne"); + nBldr.addRDN(BCStyle.ST,"Victoria"); + nBldr.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); // // extensions @@ -90,17 +83,7 @@ public void checkCreation1() // // create the certificate - version 3 - without subject unique ID // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.setSerialNumber(BigInteger.valueOf(1)); - certGen.setIssuerDN(new X509Principal(ord, values)); - certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); - certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); - certGen.setSubjectDN(new X509Principal(ord, values)); - certGen.setPublicKey(pubKey); - certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); - - X509Certificate cert = certGen.generate(privKey); + X509Certificate cert = TestCertificateGen.createCertWithIDs(nBldr.build(), "SHA256withRSA", new KeyPair(pubKey, privKey), null, null); cert.checkValidity(new Date()); @@ -120,25 +103,12 @@ public void checkCreation1() // // create the certificate - version 3 - with subject unique ID // - certGen = new X509V3CertificateGenerator(); - - certGen.setSerialNumber(BigInteger.valueOf(1)); - certGen.setIssuerDN(new X509Principal(ord, values)); - certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); - certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); - certGen.setSubjectDN(new X509Principal(ord, values)); - certGen.setPublicKey(pubKey); - certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); boolean[] subjectUniqID = {true, false, false, false, true, false, false, true, false, true, true}; - certGen.setSubjectUniqueID(subjectUniqID); - boolean[] issuerUniqID = {false, false, true, false, true, false, false, false, true, false, false, true, false, true, true}; - - certGen.setIssuerUniqueID(issuerUniqID); - - cert = certGen.generate(privKey); + + cert = TestCertificateGen.createCertWithIDs(nBldr.build(), "SHA256withRSA", new KeyPair(pubKey, privKey), subjectUniqID, issuerUniqID); cert.checkValidity(new Date()); diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/ChaCha20Poly1305Test.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/ChaCha20Poly1305Test.java index b3cf3b5c46..5b8b6084dc 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/ChaCha20Poly1305Test.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/ChaCha20Poly1305Test.java @@ -18,6 +18,7 @@ import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; +import org.bouncycastle.util.test.TestFailedException; public class ChaCha20Poly1305Test extends SimpleTest @@ -91,13 +92,19 @@ public void performTest() throws Exception // check mac failure byte[] faulty = new byte[enc.length]; - System.arraycopy(enc, 0, faulty, 0, enc.length - 1); + System.arraycopy(enc, 0, faulty, 0, enc.length); + faulty[faulty.length - 1] ^= 0xff; + try { decCipher.doFinal(faulty); fail("no exception"); } + catch (TestFailedException e) + { + throw e; + } catch (Exception e) { if (aeadAvailable) diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/CipherStreamTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/CipherStreamTest.java index 39e37a696b..55181ad62a 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/CipherStreamTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/CipherStreamTest.java @@ -75,7 +75,8 @@ public class CipherStreamTest private static final byte[] CHA7539OUT = Hex.decode("aef50e541e12a65dc21e90ebb4c03987971c540f78eb536df692ff89fc47561ed17eb23b63eb714c09d0c50af703e01485926c140e994b3edff9df635a91d268"); private static final byte[] HCIN = new byte[64]; - private static final byte[] HCIV = new byte[32]; + private static final byte[] HC128IV = new byte[16]; + private static final byte[] HC256IV = new byte[32]; private static final byte[] HCK256A = new byte[32]; private static final byte[] HC256A = Hex.decode( @@ -416,10 +417,10 @@ public void performTest() testAlgorithm("ChaCha20", CHA7539K, CHA7539IV, CHA7539IN, CHA7539OUT); runTest("HC128"); testException("HC128"); - testAlgorithm("HC128", HCK128A, HCIV, HCIN, HC128A); + testAlgorithm("HC128", HCK128A, HC128IV, HCIN, HC128A); runTest("HC256"); testException("HC256"); - testAlgorithm("HC256", HCK256A, HCIV, HCIN, HC256A); + testAlgorithm("HC256", HCK256A, HC256IV, HCIN, HC256A); runTest("VMPC"); testException("VMPC"); //testAlgorithm("VMPC", a, iv, in, a); diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/CipherStreamTest2.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/CipherStreamTest2.java index cc0d2552dd..99f8c89c65 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/CipherStreamTest2.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/CipherStreamTest2.java @@ -20,7 +20,7 @@ import org.bouncycastle.util.test.SimpleTest; public class CipherStreamTest2 - extends SimpleTest + extends SimpleTest { private int streamSize; @@ -30,7 +30,7 @@ public String getName() } private void testModes(String algo, String[] transforms, boolean authenticated) - throws Exception + throws Exception { Key key = generateKey(algo); for (int i = 0; i != transforms.length; i++) @@ -61,7 +61,6 @@ private void testModes(String algo, String[] transforms, boolean authenticated) } - if (authenticated) { boolean aeadAvailable = false; @@ -91,20 +90,20 @@ private InputStream createInputStream(byte[] data, Cipher cipher, boolean useBc) { ByteArrayInputStream bytes = new ByteArrayInputStream(data); // cast required for earlier JDK - return useBc ? (InputStream)new CipherInputStream(bytes, cipher) : (InputStream)new javax.crypto.CipherInputStream(bytes, cipher); + return useBc ? (InputStream) new CipherInputStream(bytes, cipher) : (InputStream) new javax.crypto.CipherInputStream(bytes, cipher); } private OutputStream createOutputStream(ByteArrayOutputStream bytes, Cipher cipher, boolean useBc) { // cast required for earlier JDK - return useBc ? (OutputStream)new CipherOutputStream(bytes, cipher) : (OutputStream)new javax.crypto.CipherOutputStream(bytes, cipher); + return useBc ? (OutputStream) new CipherOutputStream(bytes, cipher) : (OutputStream) new javax.crypto.CipherOutputStream(bytes, cipher); } /** * Test tampering of ciphertext followed by read from decrypting CipherInputStream */ private void testTamperedRead(String name, Key key, boolean authenticated, boolean useBc) - throws Exception + throws Exception { Cipher encrypt = Cipher.getInstance(name, "BC"); Cipher decrypt = Cipher.getInstance(name, "BC"); @@ -154,7 +153,7 @@ private void testTamperedRead(String name, Key key, boolean authenticated, boole * decrypting CipherInputStream */ private void testTruncatedRead(String name, Key key, boolean authenticated, boolean useBc) - throws Exception + throws Exception { Cipher encrypt = Cipher.getInstance(name, "BC"); Cipher decrypt = Cipher.getInstance(name, "BC"); @@ -220,7 +219,7 @@ private void testTruncatedRead(String name, Key key, boolean authenticated, bool * Test tampering of ciphertext followed by write to decrypting CipherOutputStream */ private void testTamperedWrite(String name, Key key, boolean authenticated, boolean useBc) - throws Exception + throws Exception { Cipher encrypt = Cipher.getInstance(name, "BC"); Cipher decrypt = Cipher.getInstance(name, "BC"); @@ -261,12 +260,12 @@ private void testTamperedWrite(String name, Key key, boolean authenticated, bool * Test CipherOutputStream in ENCRYPT_MODE, CipherInputStream in DECRYPT_MODE */ private void testWriteRead(String name, Key key, boolean authenticated, boolean useBc, boolean blocks) - throws Exception + throws Exception { byte[] data = new byte[streamSize]; for (int i = 0; i < data.length; i++) { - data[i] = (byte)(i % 255); + data[i] = (byte) (i % 255); } testWriteRead(name, key, authenticated, useBc, blocks, data); @@ -276,7 +275,7 @@ private void testWriteRead(String name, Key key, boolean authenticated, boolean * Test CipherOutputStream in ENCRYPT_MODE, CipherInputStream in DECRYPT_MODE */ private void testWriteReadEmpty(String name, Key key, boolean authenticated, boolean useBc, boolean blocks) - throws Exception + throws Exception { byte[] data = new byte[0]; @@ -389,7 +388,7 @@ protected void fail(String message, Throwable throwable, boolean authenticated, * Test CipherInputStream in ENCRYPT_MODE, CipherOutputStream in DECRYPT_MODE */ private void testReadWrite(String name, Key key, boolean authenticated, boolean useBc, boolean blocks) - throws Exception + throws Exception { String lCode = "ABCDEFGHIJKLMNOPQRSTU"; @@ -449,7 +448,7 @@ private void testReadWrite(String name, Key key, boolean authenticated, boolean } private static Key generateKey(String name) - throws Exception + throws Exception { KeyGenerator kGen; @@ -465,7 +464,7 @@ private static Key generateKey(String name) } public void performTest() - throws Exception + throws Exception { int[] testSizes = new int[]{0, 1, 7, 8, 9, 15, 16, 17, 1023, 1024, 1025, 2047, 2048, 2049, 4095, 4096, 4097}; for (int i = 0; i < testSizes.length; i++) @@ -476,54 +475,62 @@ public void performTest() } private void performTests() - throws Exception + throws Exception { final String[] blockCiphers64 = new String[]{"BLOWFISH", "DES", "DESEDE", "TEA", "CAST5", "RC2", "XTEA"}; for (int i = 0; i != blockCiphers64.length; i++) { testModes(blockCiphers64[i], new String[]{ - "/ECB/PKCS5Padding", - "/CBC/PKCS5Padding", - "/OFB/NoPadding", - "/CFB/NoPadding", - "/CTS/NoPadding",}, false); + "/ECB/PKCS5Padding", + "/CBC/PKCS5Padding", + "/OFB/NoPadding", + "/CFB/NoPadding", + "/CTS/NoPadding",}, false); testModes(blockCiphers64[i], new String[]{"/EAX/NoPadding"}, true); } final String[] blockCiphers128 = new String[]{ - "AES", - "NOEKEON", - "Twofish", - "CAST6", - "SEED", - "Serpent", - "RC6", - "CAMELLIA"}; + "AES", + "NOEKEON", + "Twofish", + "CAST6", + "SEED", + "Serpent", + "RC6", + "CAMELLIA"}; for (int i = 0; i != blockCiphers128.length; i++) { testModes(blockCiphers128[i], new String[]{ - "/ECB/PKCS5Padding", - "/CBC/PKCS5Padding", - "/OFB/NoPadding", - "/CFB/NoPadding", - "/CTS/NoPadding", - "/CTR/NoPadding", - "/SIC/NoPadding"}, false); - testModes(blockCiphers128[i], new String[]{"/CCM/NoPadding", "/EAX/NoPadding", "/GCM/NoPadding", "/OCB/NoPadding"}, true); + "/ECB/PKCS5Padding", + "/CBC/PKCS5Padding", + "/OFB/NoPadding", + "/CFB/NoPadding", + "/CTS/NoPadding", + "/CTR/NoPadding", + "/SIC/NoPadding"}, false); + String jvm = System.getProperty("java.version"); + if (jvm.length() > 2 && (jvm.charAt(2) == '5' || jvm.charAt(2) == '6')) // can't use GCM due to JVM bug in this case. + { + testModes(blockCiphers128[i], new String[]{"/CCM/NoPadding", "/EAX/NoPadding", "/OCB/NoPadding"}, true); + } + else + { + testModes(blockCiphers128[i], new String[]{"/CCM/NoPadding", "/EAX/NoPadding", "/GCM/NoPadding", "/OCB/NoPadding"}, true); + } } final String[] streamCiphers = new String[]{ - "ARC4", - "SALSA20", - "XSalsa20", - "ChaCha", - "ChaCha7539", - "Grainv1", - "Grain128", - "HC128", - "HC256"}; + "ARC4", + "SALSA20", + "XSalsa20", + "ChaCha", + "ChaCha7539", + "Grainv1", + "Grain128", + "HC128", + "HC256"}; for (int i = 0; i != streamCiphers.length; i++) { diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/ContentInfo.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/ContentInfo.java index 8fc1431517..11e44bb891 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/ContentInfo.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/ContentInfo.java @@ -82,12 +82,12 @@ private ContentInfo( if (seq.size() > 1) { ASN1TaggedObject tagged = (ASN1TaggedObject)seq.getObjectAt(1); - if (!tagged.isExplicit() || tagged.getTagNo() != 0) + if (!tagged.isExplicit() || !tagged.hasContextTag(0)) { throw new IllegalArgumentException("Bad tag for 'content'"); } - content = tagged.getObject(); + content = tagged.getBaseObject(); } } diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/DSTU4145Test.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/DSTU4145Test.java index 5ad29923a7..44e89c2755 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/DSTU4145Test.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/DSTU4145Test.java @@ -54,7 +54,7 @@ public static void main(String[] args) private void generationTest() throws Exception { - ECCurve.F2m curve = new ECCurve.F2m(173, 1, 2, 10, BigInteger.ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16)); + ECCurve.F2m curve = new ECCurve.F2m(173, 1, 2, 10, BigInteger.ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16), null, null); ECParameterSpec spec = new ECParameterSpec( curve, @@ -133,7 +133,7 @@ private void DSTU4145Test() SecureRandom k = new TestRandomBigInteger(Hex.decode("00137449348C1249971759D99C252FFE1E14D8B31F00")); - ECCurve.F2m curve = new ECCurve.F2m(173, 1, 2, 10, BigInteger.ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16)); + ECCurve.F2m curve = new ECCurve.F2m(173, 1, 2, 10, BigInteger.ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16), null, null); ECParameterSpec spec = new ECParameterSpec( curve, diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/DigestTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/DigestTest.java index 99d72de5e2..d97132766b 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/DigestTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/DigestTest.java @@ -3,12 +3,12 @@ import java.security.MessageDigest; import java.security.Security; -import org.bouncycastle.asn1.iso.ISOIECObjectIdentifiers; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.ua.UAObjectIdentifiers; +import org.bouncycastle.internal.asn1.iso.ISOIECObjectIdentifiers; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/ECEncodingTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/ECEncodingTest.java index 559cf6fa9f..a6ae179024 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/ECEncodingTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/ECEncodingTest.java @@ -6,18 +6,14 @@ import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.PublicKey; import java.security.Security; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.security.spec.ECGenParameterSpec; -import java.util.Date; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.x9.X9ECParameters; -import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; @@ -26,7 +22,6 @@ import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; -import org.bouncycastle.x509.X509V3CertificateGenerator; public class ECEncodingTest extends SimpleTest @@ -67,7 +62,7 @@ public String getName() private void testPointCompression() throws Exception { - ECCurve curve = new ECCurve.F2m(m, k1, k2, k3, a, b); + ECCurve curve = new ECCurve.F2m(m, k1, k2, k3, a, b, null, null); curve.decodePoint(enc); int ks[] = new int[3]; @@ -211,7 +206,6 @@ private void testParams(byte[] ecParameterEncoded, boolean compress) private X509Certificate generateSelfSignedSoftECCert(KeyPair kp, boolean compress) throws Exception { - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); ECPrivateKey privECKey = (ECPrivateKey)kp.getPrivate(); ECPublicKey pubECKey = (ECPublicKey)kp.getPublic(); if (!compress) @@ -219,15 +213,8 @@ private X509Certificate generateSelfSignedSoftECCert(KeyPair kp, ((ECPointEncoder)privECKey).setPointFormat("UNCOMPRESSED"); ((ECPointEncoder)pubECKey).setPointFormat("UNCOMPRESSED"); } - certGen.setSignatureAlgorithm("ECDSAwithSHA1"); - certGen.setSerialNumber(BigInteger.valueOf(1)); - certGen.setIssuerDN(new X509Principal("CN=Software emul (EC Cert)")); - certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); - certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000000)); - certGen.setSubjectDN(new X509Principal("CN=Software emul (EC Cert)")); - certGen.setPublicKey((PublicKey)pubECKey); - - return certGen.generate((PrivateKey)privECKey); + + return TestCertificateGen.createSelfSignedCert("CN=Software emul (EC Cert)", "SHA1withECDSA", kp); } public static void main( diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/ECNRTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/ECNRTest.java index d84c2f7dc2..90160d306a 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/ECNRTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/ECNRTest.java @@ -104,7 +104,7 @@ private void testECNR192bitPrime() KeyFactory f = KeyFactory.getInstance("ECDSA", "BC"); byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; - + checkSignature(192, priKey, pubKey, sgr, k, message, r, s); } diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/EdECTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/EdECTest.java index f9cab0e513..6069675087 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/EdECTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/EdECTest.java @@ -33,9 +33,9 @@ import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.jcajce.interfaces.EdDSAPrivateKey; import org.bouncycastle.jcajce.spec.DHUParameterSpec; import org.bouncycastle.jcajce.spec.EdDSAParameterSpec; @@ -158,7 +158,7 @@ public void performTest() // yes, the demo certificate is invalid... sig.update(x25519Seq.getObjectAt(0).toASN1Primitive().getEncoded(ASN1Encoding.DL)); - isTrue(sig.verify(x25519Cert.getSignature().getBytes())); + isTrue(sig.verify(x25519Cert.getSignature().getOctets())); CertificateFactory certFact = CertificateFactory.getInstance("X.509", "BC"); diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/GOST3410Test.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/GOST3410Test.java index e98cbd1907..c875e20e54 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/GOST3410Test.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/GOST3410Test.java @@ -2,36 +2,26 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; -import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; -import java.security.SignatureException; -import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; -import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; -import java.util.Date; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.CipherParameters; @@ -39,8 +29,8 @@ import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.ECGOST3410Signer; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; -import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.ECPrivateKey; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.GOST3410PrivateKey; @@ -59,7 +49,6 @@ import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.TestRandomBigInteger; -import org.bouncycastle.x509.X509V3CertificateGenerator; //import java.security.spec.ECGenParameterSpec; @@ -497,6 +486,33 @@ private void ecGOST2012NameCurveGenerationTest() checkKeyPairAlgId(kp, expectedAlgId); + kpGen.initialize(new ECNamedCurveGenParameterSpec("Tc26-Gost-3410-12-256-paramSetB")); + + kp = kpGen.generateKeyPair(); + + expectedAlgId = new AlgorithmIdentifier(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, + new GOST3410PublicKeyAlgParameters(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetB, null)); + + checkKeyPairAlgId(kp, expectedAlgId); + + kpGen.initialize(new ECNamedCurveGenParameterSpec("Tc26-Gost-3410-12-256-paramSetC")); + + kp = kpGen.generateKeyPair(); + + expectedAlgId = new AlgorithmIdentifier(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, + new GOST3410PublicKeyAlgParameters(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetC, null)); + + checkKeyPairAlgId(kp, expectedAlgId); + + kpGen.initialize(new ECNamedCurveGenParameterSpec("Tc26-Gost-3410-12-256-paramSetD")); + + kp = kpGen.generateKeyPair(); + + expectedAlgId = new AlgorithmIdentifier(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, + new GOST3410PublicKeyAlgParameters(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetD, null)); + + checkKeyPairAlgId(kp, expectedAlgId); + kpGen.initialize(new ECNamedCurveGenParameterSpec("Tc26-Gost-3410-12-512-paramSetA")); kp = kpGen.generateKeyPair(); @@ -744,7 +760,7 @@ private void encodedGost12Test(KeyPair p) } private void keyStoreTest(PrivateKey sKey, PublicKey vKey) - throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, InvalidKeyException, UnrecoverableKeyException + throws Exception { // // keystore test @@ -752,21 +768,8 @@ private void keyStoreTest(PrivateKey sKey, PublicKey vKey) KeyStore ks = KeyStore.getInstance("JKS"); ks.load(null, null); - - // - // create the certificate - version 3 - // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.setSerialNumber(BigInteger.valueOf(1)); - certGen.setIssuerDN(new X509Principal("CN=Test")); - certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); - certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); - certGen.setSubjectDN(new X509Principal("CN=Test")); - certGen.setPublicKey(vKey); - certGen.setSignatureAlgorithm("GOST3411withGOST3410"); - - X509Certificate cert = certGen.generate(sKey, "BC"); + + X509Certificate cert = TestCertificateGen.createSelfSignedCert("CN=Test", "GOST3411withGOST3410", new KeyPair(vKey, sKey)); ks.setKeyEntry("gost", sKey, "gost".toCharArray(), new Certificate[]{cert}); @@ -896,7 +899,7 @@ public void performTest() ecGOST2012VerifyTest("ECGOST3410-2012-256", ecgostData, ecgost2012_256Key, ecgost2012_256Sig); ecGOST2012VerifyTest("ECGOST3410-2012-512", ecgostData, ecgost2012_512Key, ecgost2012_512Sig); } - + generationTest(); parametersTest(); } diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/HMacTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/HMacTest.java index bddf60cee7..49dab95ba7 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/HMacTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/HMacTest.java @@ -14,11 +14,11 @@ import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.gm.GMObjectIdentifiers; -import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.ua.UAObjectIdentifiers; +import org.bouncycastle.internal.asn1.iana.IANAObjectIdentifiers; +import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/KeyStoreTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/KeyStoreTest.java index 30dfa15ef7..e802c5404a 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/KeyStoreTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/KeyStoreTest.java @@ -21,18 +21,16 @@ import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Date; -import java.util.Hashtable; -import java.util.Vector; +import org.bouncycastle.asn1.x500.X500NameBuilder; +import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X9ECParameters; -import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; -import org.bouncycastle.x509.X509V3CertificateGenerator; /** * Exercise the various key stores, making sure we at least get back what we put in! @@ -93,39 +91,19 @@ public void ecStoreTest( // // distinguished name table. // - Hashtable attrs = new Hashtable(); - Vector order = new Vector(); - - attrs.put(X509Principal.C, "AU"); - attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); - attrs.put(X509Principal.L, "Melbourne"); - attrs.put(X509Principal.ST, "Victoria"); - attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); - - order.addElement(X509Principal.C); - order.addElement(X509Principal.O); - order.addElement(X509Principal.L); - order.addElement(X509Principal.ST); - order.addElement(X509Principal.E); - - // - // create the certificate - version 3 - // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.setSerialNumber(BigInteger.valueOf(1)); - certGen.setIssuerDN(new X509Principal(order, attrs)); - certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); - certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); - certGen.setSubjectDN(new X509Principal(order, attrs)); - certGen.setPublicKey(pubKey); - certGen.setSignatureAlgorithm("ECDSAwithSHA1"); + X500NameBuilder nBldr = new X500NameBuilder(); + nBldr.addRDN(BCStyle.C, "AU"); + nBldr.addRDN(BCStyle.O,"The Legion of the Bouncy Castle"); + nBldr.addRDN(BCStyle.L, "Melbourne"); + nBldr.addRDN(BCStyle.ST,"Victoria"); + nBldr.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); + Certificate[] chain = new Certificate[1]; try { - X509Certificate cert = certGen.generate(privKey); + X509Certificate cert = TestCertificateGen.createSelfSignedCert(nBldr.build(), "SHA1withECDSA", new KeyPair(pubKey, privKey)); cert.checkValidity(new Date()); @@ -222,20 +200,13 @@ public void keyStoreTest( // // distinguished name table. // - Hashtable attrs = new Hashtable(); - Vector order = new Vector(); + X500NameBuilder nBldr = new X500NameBuilder(); - attrs.put(X509Principal.C, "AU"); - attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); - attrs.put(X509Principal.L, "Melbourne"); - attrs.put(X509Principal.ST, "Victoria"); - attrs.put(X509Principal.EmailAddress, "feedback-crypto@bouncycastle.org"); - - order.addElement(X509Principal.C); - order.addElement(X509Principal.O); - order.addElement(X509Principal.L); - order.addElement(X509Principal.ST); - order.addElement(X509Principal.EmailAddress); + nBldr.addRDN(BCStyle.C, "AU"); + nBldr.addRDN(BCStyle.O,"The Legion of the Bouncy Castle"); + nBldr.addRDN(BCStyle.L, "Melbourne"); + nBldr.addRDN(BCStyle.ST,"Victoria"); + nBldr.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); // // extensions @@ -244,21 +215,11 @@ public void keyStoreTest( // // create the certificate. // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.setSerialNumber(BigInteger.valueOf(1)); - certGen.setIssuerDN(new X509Principal(order, attrs)); - certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); - certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); - certGen.setSubjectDN(new X509Principal(order, attrs)); - certGen.setPublicKey(pubKey); - certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); - Certificate[] chain = new Certificate[1]; try { - X509Certificate cert = certGen.generate(privKey); + X509Certificate cert = TestCertificateGen.createSelfSignedCert(nBldr.build(), "MD5WithRSAEncryption", new KeyPair(pubKey, privKey)); cert.checkValidity(new Date()); @@ -408,37 +369,20 @@ private void checkException() // // distinguished name table. // - Hashtable attrs = new Hashtable(); - Vector order = new Vector(); + X500NameBuilder nBldr = new X500NameBuilder(); - attrs.put(X509Principal.C, "AU"); - attrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); - attrs.put(X509Principal.L, "Melbourne"); - attrs.put(X509Principal.ST, "Victoria"); - attrs.put(X509Principal.E, "feedback-crypto@bouncycastle.org"); - - order.addElement(X509Principal.C); - order.addElement(X509Principal.O); - order.addElement(X509Principal.L); - order.addElement(X509Principal.ST); - order.addElement(X509Principal.E); + nBldr.addRDN(BCStyle.C, "AU"); + nBldr.addRDN(BCStyle.O,"The Legion of the Bouncy Castle"); + nBldr.addRDN(BCStyle.L, "Melbourne"); + nBldr.addRDN(BCStyle.ST,"Victoria"); + nBldr.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org"); // // create the certificate - version 3 // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.setSerialNumber(BigInteger.valueOf(1)); - certGen.setIssuerDN(new X509Principal(order, attrs)); - certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); - certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); - certGen.setSubjectDN(new X509Principal(order, attrs)); - certGen.setPublicKey(pubKey); - certGen.setSignatureAlgorithm("ECDSAwithSHA1"); - Certificate[] dummyChain = new Certificate[1]; - dummyChain[0] = certGen.generate(privKey); + dummyChain[0] = TestCertificateGen.createSelfSignedCert(nBldr.build(), "SHA1withECDSA", new KeyPair(pubKey, privKey)); ks = KeyStore.getInstance("BKS", "BC"); diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/PBETest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/PBETest.java index af1865c509..7a6791161f 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/PBETest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/PBETest.java @@ -40,7 +40,7 @@ /** * test out the various PBE modes, making sure the JCE implementations - * are compatible woth the light weight ones. + * are compatible with the light weight ones. */ public class PBETest extends SimpleTest diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/PKCS10CertRequestTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/PKCS10CertRequestTest.java index 84303eee6b..a8e07d73ce 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/PKCS10CertRequestTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/PKCS10CertRequestTest.java @@ -41,7 +41,6 @@ import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; -import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; @@ -215,7 +214,7 @@ private void createECRequest(String algorithm, ASN1ObjectIdentifier algOid, ASN1 sig.update(req.getCertificationRequestInfo().getEncoded()); - if (!sig.verify(req.getSignature().getBytes())) + if (!sig.verify(req.getSignature().getOctets())) { fail("signature not mapped correctly."); } @@ -294,7 +293,7 @@ private void createECRequest(String algorithm, ASN1ObjectIdentifier algOid) sig.update(req.getCertificationRequestInfo().getEncoded()); - if (!sig.verify(req.getSignature().getBytes())) + if (!sig.verify(req.getSignature().getOctets())) { fail("signature not mapped correctly."); } @@ -344,7 +343,7 @@ private void createECGOSTRequest() sig.update(req.getCertificationRequestInfo().getEncoded()); - if (!sig.verify(req.getSignature().getBytes())) + if (!sig.verify(req.getSignature().getOctets())) { fail("signature not mapped correctly."); } @@ -401,7 +400,7 @@ private void createPSSTest(String algorithm) sig.update(req.getCertificationRequestInfo().getEncoded()); - if (!sig.verify(req.getSignature().getBytes())) + if (!sig.verify(req.getSignature().getOctets())) { fail("signature not mapped correctly."); } diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/PKCS12StoreTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/PKCS12StoreTest.java index aaca58f61d..3a1dcc3f43 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/PKCS12StoreTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/PKCS12StoreTest.java @@ -2,6 +2,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.Key; @@ -31,7 +32,6 @@ import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DLSequenceParser; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; -import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.EncryptedData; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; @@ -44,12 +44,17 @@ import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.KeyPurposeId; +import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.jcajce.PKCS12StoreParameter; +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; import org.bouncycastle.jce.PKCS12Util; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.JDKPKCS12StoreParameter; import org.bouncycastle.jce.provider.X509CertificateObject; +import org.bouncycastle.pqc.jcajce.spec.FalconParameterSpec; +import org.bouncycastle.pqc.jcajce.spec.NTRUParameterSpec; +import org.bouncycastle.pqc.jcajce.spec.SPHINCSPlusParameterSpec; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -63,501 +68,501 @@ public class PKCS12StoreTest extends SimpleTest { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; - - static char[] passwd = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; + + static char[] passwd = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'}; // // pkcs-12 pfx-pdu // - byte[] pkcs12 = Base64.decode( - "MIACAQMwgAYJKoZIhvcNAQcBoIAkgAQBMAQBgAQBMAQBgAQBBgQBCQQJKoZI" - + "hvcNAQcBBAGgBAGABAEkBAGABAEEBAEBBAEwBAEEBAEDBAOCAzQEAQQEAQEE" - + "ATAEAQQEAQMEA4IDMAQBBAQBAQQBBgQBBAQBAQQBCwQBBAQBCwQLKoZIhvcN" - + "AQwKAQIEAQQEAQEEAaAEAQQEAQMEA4ICpQQBBAQBAQQBMAQBBAQBAwQDggKh" - + "BAEEBAEBBAEwBAEEBAEBBAEbBAEEBAEBBAEGBAEEBAEBBAEKBAEEBAEKBAoq" - + "hkiG9w0BDAEDBAEEBAEPBA8wDQQIoagiwNZPJR4CAQEEAQQEAQEEAQQEAQQE" - + "AQMEA4ICgAQBBAQDggKABIICgEPG0XlhMFyrs4ZWDrvEzl51ICfXd6K2ql2l" - + "nnxhszUbigtSj6x49VEx4PfOB9fQFeidc5L5An+nKp646NBMIY0UwXGs8BLQ" - + "au59jtOs987+l7QYIvl6fdGUIuLPhVSnZZDyqD+HQjU/0/ccKFHRif4tlEQq" - + "aErvZbFeH0pg4ijf1HfgX6gBJGRKdO+msa4qKGnZdHCSLZehyyxvxAmURetg" - + "yhtEl7RmedTB+4TDs7atekqxkNlD9tfwDUX6sb0IH6qbEA6P/DlVMdaD54Cl" - + "QDxRzOfIIjklZhv5OMFWtPK0aYPcqyxzLpw1qRAyoTVXpidkj/hpIpgCVBP/" - + "k5s2+WdGbLgA/4/zSrF6feRCE5llzM2IGxiHVq4oPzzngl3R+Fi5VCPDMcuW" - + "NRuIOzJA+RNV2NPOE/P3knThDnwiImq+rfxmvZ1u6T06s20RmWK6cxp7fTEw" - + "lQ9BOsv+mmyV8dr6cYJq4IlRzHdFOyEUBDwfHThyribNKKobO50xh2f93xYj" - + "Rn5UMOQBJIe3b7OKZt5HOIMrJSZO02IZgvImi9yQWi96PnWa419D1cAsLWvM" - + "xiN0HqZMbDFfxVM2BZmsxiexLhkHWKwLqfQDzRjJfmVww8fnXpWZhFXKyut9" - + "gMGEyCNoba4RU3QI/wHKWYaK74qtJpsucuLWBH6UcsHsCry6VZkwRxWwC0lb" - + "/F3Bm5UKHax5n9JHJ2amQm9zW3WJ0S5stpPObfmg5ArhbPY+pVOsTqBRlop1" - + "bYJLD/X8Qbs468Bwzej0FhoEU59ZxFrbjLSBsMUYrVrwD83JE9kEazMLVchc" - + "uCB9WT1g0hxYb7VA0BhOrWhL8F5ZH72RMCYLPI0EAQQEAQEEATEEAQQEAQEE" - + "AXgEAQQEAQEEATAEAQQEAQEEAVEEAQQEAQEEAQYEAQQEAQEEAQkEAQQEAQkE" - + "CSqGSIb3DQEJFAQBBAQBAQQBMQQBBAQBAQQBRAQBBAQBAQQBHgQBBAQBAQQB" - + "QgQBBAQBQgRCAEQAYQB2AGkAZAAgAEcALgAgAEgAbwBvAGsAJwBzACAAVgBl" - + "AHIAaQBTAGkAZwBuACwAIABJAG4AYwAuACAASQBEBAEEBAEBBAEwBAEEBAEB" - + "BAEjBAEEBAEBBAEGBAEEBAEBBAEJBAEEBAEJBAkqhkiG9w0BCRUEAQQEAQEE" - + "ATEEAQQEAQEEARYEAQQEAQEEAQQEAQQEAQEEARQEAQQEARQEFKEcMJ798oZL" - + "FkH0OnpbUBnrTLgWBAIAAAQCAAAEAgAABAEwBAGABAEGBAEJBAkqhkiG9w0B" - + "BwYEAaAEAYAEATAEAYAEAQIEAQEEAQAEATAEAYAEAQYEAQkECSqGSIb3DQEH" - + "AQQBMAQBGwQBBgQBCgQKKoZIhvcNAQwBBgQPMA0ECEE7euvmxxwYAgEBBAGg" - + "BAGABAEEBAEIBAgQIWDGlBWxnwQBBAQBCAQI2WsMhavhSCcEAQQEAQgECPol" - + "uHJy9bm/BAEEBAEQBBCiRxtllKXkJS2anKD2q3FHBAEEBAEIBAjKy6BRFysf" - + "7gQBBAQDggMwBIIDMJWRGu2ZLZild3oz7UBdpBDUVMOA6eSoWiRIfVTo4++l" - + "RUBm8TpmmGrVkV32PEoLkoV+reqlyWCvqqSjRzi3epQiVwPQ6PV+ccLqxDhV" - + "pGWDRQ5UttDBC2+u4fUQVZi2Z1i1g2tsk6SzB3MKUCrjoWKvaDUUwXo5k9Vz" - + "qSLWCLTZCjs3RaY+jg3NbLZYtfMDdYovhCU2jMYV9adJ8MxxmJRz+zPWAJph" - + "LH8hhfkKG+wJOSszqk9BqGZUa/mnZyzeQSMTEFga1ZB/kt2e8SZFWrTZEBgJ" - + "oszsL5MObbwMDowNurnZsnS+Mf7xi01LeG0VT1fjd6rn9BzVwuMwhoqyoCNo" - + "ziUqSUyLEwnGTYYpvXLxzhNiYzW8546KdoEKDkEjhfYsc4XqSjm9NYy/BW/M" - + "qR+aL92j8hqnkrWkrWyvocUe3mWaiqt7/oOzNZiMTcV2dgjjh9HfnjSHjFGe" - + "CVhnEWzV7dQIVyc/qvNzOuND8X5IyJ28xb6a/i1vScwGuo/UDgPAaMjGw28f" - + "siOZBShzde0Kj82y8NilfYLHHeIGRW+N/grUFWhW25mAcBReXDd5JwOqM/eF" - + "y+4+zBzlO84ws88T1pkSifwtMldglN0APwr4hvUH0swfiqQOWtwyeM4t+bHd" - + "5buAlXOkSeF5rrLzZ2/Lx+JJmI2pJ/CQx3ej3bxPlx/BmarUGAxaI4le5go4" - + "KNfs4GV8U+dbEHQz+yDYL+ksYNs1eb+DjI2khbl28jhoeAFKBtu2gGOL5M9M" - + "CIP/JDOCHimu1YZRuOTAf6WISnG/0Ri3pYZsgQ0i4cXj+WfYwYVjhKX5AcDj" - + "UKnc4/Cxp+TbbgZqEKRcYVb2q0kOAxkeaNo3WCm+qvUYrwAmKp4nVB+/24rK" - + "khHiyYJQsETxtOEyvJkVxAS01djY4amuJ4jL0sYnXIhW3Ag93eavbzksGT7W" - + "Fg1ywpr1x1xpXWIIuVt1k4e+g9fy7Yx7rx0IK1qCSjNwU3QPWbaef1rp0Q/X" - + "P9IVXYkqo1g/T3SyXqrbZLO+sDjiG4IT3z3fJJqt81sRSVT0QN1ND8l93BG4" - + "QKzghYw8sZ4FwKPtLky1dDcVTgQBBAQBCAQIK/85VMKWDWYEAQQEAQgECGsO" - + "Q85CcFwPBAEEBAEIBAhaup6ot9XnQAQBBAQCgaAEgaCeCMadSm5fkLfhErYQ" - + "DgePZl/rrjP9FQ3VJZ13XrjTSjTRknAbXi0DEu2tvAbmCf0sdoVNuZIZ92W0" - + "iyaa2/A3RHA2RLPNQz5meTi1RE2N361yR0q181dC3ztkkJ8PLyd74nCtgPUX" - + "0JlsvLRrdSjPBpBQ14GiM8VjqeIY7EVFy3vte6IbPzodxaviuSc70iXM4Yko" - + "fQq6oaSjNBFRqkHrBAEEBAEIBAjlIvOf8SnfugQBBAQBCAQIutCF3Jovvl0E" - + "AQQEAQgECO7jxbucdp/3BAEEBAEIBAidxK3XDLj+BwQBBAQBCAQI3m/HMbd3" - + "TwwEAQQEA4ICOASCAjgtoCiMfTkjpCRuMhF5gNLRBiNv+xjg6GvZftR12qiJ" - + "dLeCERI5bvXbh9GD6U+DjTUfhEab/37TbiI7VOFzsI/R137sYy9Tbnu7qkSx" - + "u0bTvyXSSmio6sMRiWIcakmDbv+TDWR/xgtj7+7C6p+1jfUGXn/RjB3vlyjL" - + "Q9lFe5F84qkZjnADo66p9gor2a48fgGm/nkABIUeyzFWCiTp9v6FEzuBfeuP" - + "T9qoKSnCitaXRCru5qekF6L5LJHLNXLtIMSrbO0bS3hZK58FZAUVMaqawesJ" - + "e/sVfQip9x/aFQ6U3KlSpJkmZK4TAqp9jIfxBC8CclbuwmoXPMomiCH57ykr" - + "vkFHOGcxRcCxax5HySCwSyPDr8I4+6Kocty61i/1Xr4xJjb+3oyFStIpB24x" - + "+ALb0Mz6mUa1ls76o+iQv0VM2YFwnx+TC8KC1+O4cNOE/gKeh0ircenVX83h" - + "GNez8C5Ltg81g6p9HqZPc2pkwsneX2sJ4jMsjDhewV7TyyS3x3Uy3vTpZPek" - + "VdjYeVIcgAz8VLJOpsIjyHMB57AyT7Yj87hVVy//VODnE1T88tRXZb+D+fCg" - + "lj2weQ/bZtFzDX0ReiEQP6+yklGah59omeklIy9wctGV1o9GNZnGBSLvQ5NI" - + "61e9zmQTJD2iDjihvQA/6+edKswCjGRX6rMjRWXT5Jv436l75DVoUj09tgR9" - + "ytXSathCjQUL9MNXzUMtr7mgEUPETjM/kYBR7CNrsc+gWTWHYaSWuqKVBAEE" - + "BAEIBAh6slfZ6iqkqwQBBAQBCAQI9McJKl5a+UwEAQQEATgEOBelrmiYMay3" - + "q0OW2x2a8QQodYqdUs1TCUU4JhfFGFRy+g3yU1cP/9ZSI8gcI4skdPc31cFG" - + "grP7BAEEBAEIBAhzv/wSV+RBJQQBBAQBCAQI837ImVqqlr4EAQQEAQgECGeU" - + "gjULLnylBAEEBAEIBAjD3P4hlSBCvQQBBAQBCAQISP/qivIzf50EAQQEAQgE" - + "CKIDMX9PKxICBAEEBAOCBOgEggTocP5VVT1vWvpAV6koZupKN1btJ3C01dR6" - + "16g1zJ5FK5xL1PTdA0r6iAwVtgYdxQYnU8tht3bkNXdPJC1BdsC9oTkBg9Nr" - + "dqlF5cCzXWIezcR3ObjGLpXu49SAHvChH4emT5rytv81MYxZ7bGmlQfp8BNa" - + "0cMZz05A56LXw//WWDEzZcbKSk4tCsfMXBdGk/ngs7aILZ4FGM620PBPtD92" - + "pz2Ui/tUZqtQ0WKdLzwga1E/rl02a/x78/OdlVRNeaIYWJWLmLavX98w0PhY" - + "ha3Tbj/fqq+H3ua6Vv2Ff4VeXazkXpp4tTiqUxhc6aAGiRYckwZaP7OPSbos" - + "RKFlRLVofSGu1IVSKO+7faxV4IrVaAAzqRwLGkpJZLV7NkzkU1BwgvsAZAI4" - + "WClPDF228ygbhLwrSN2NK0s+5bKhTCNAR/LCUf3k7uip3ZSe18IwEkUMWiaZ" - + "ayktcTYn2ZjmfIfV7wIxHgWPkP1DeB+RMS7VZe9zEgJKOA16L+9SNBwJSSs9" - + "5Sb1+nmhquZmnAltsXMgwOrR12JLIgdfyyqGcNq997U0/KuHybqBVDVu0Fyr" - + "6O+q5oRmQZq6rju7h+Hb/ZUqRxRoTTSPjGD4Cu9vUqkoNVgwYOT+88FIMYun" - + "g9eChhio2kwPYwU/9BNGGzh+hAvAKcUpO016mGLImYin+FpQxodJXfpNCFpG" - + "4v4HhIwKh71OOfL6ocM/518dYwuU4Ds2/JrDhYYFsn+KprLftjrnTBnSsfYS" - + "t68b+Xr16qv9r6sseEkXbsaNbrGiZAhfHEVBOxQ4lchHrMp4zpduxG4crmpc" - + "+Jy4SadvS0uaJvADgI03DpsDYffUdriECUqAfOg/Hr7HHyr6Q9XMo1GfIarz" - + "eUHBgi1Ny0nDTWkdb7I3bIajG+Unr3KfK6dZz5Lb3g5NeclU5zintB1045Jr" - + "j9fvGGk0/2lG0n17QViBiOzGs2poTlhn7YxmiskwlkRKVafxPZNPxKILpN9s" - + "YaWGz93qER/pGMJarGJxu8sFi3+yt6FZ4pVPkvKE8JZMEPBBrmH41batS3sw" - + "sfnJ5CicAkwd8bluQpoc6qQd81HdNpS6u7djaRSDwPtYnZWu/8Hhj4DXisje" - + "FJBAjQdn2nK4MV7WKVwr+mNcVgOdc5IuOZbRLOfc3Sff6kYVuQFfcCGgAFpd" - + "nbprF/FnYXR/rghWE7fT1gfzSMNv+z5UjZ5Rtg1S/IQfUM/P7t0UqQ01/w58" - + "bTlMGihTxHiJ4Qf3o5GUzNmAyryLvID+nOFqxpr5es6kqSN4GPRHsmUIpB9t" - + "f9Nw952vhsXI9uVkhQap3JvmdAKJaIyDz6Qi7JBZvhxpghVIDh73BQTaAFP9" - + "5GUcPbYOYJzKaU5MeYEsorGoanSqPDeKDeZxjxJD4xFsqJCoutyssqIxnXUN" - + "Y3Uojbz26IJOhqIBLaUn6QVFX79buWYjJ5ZkDS7D8kq6DZeqZclt5711AO5U" - + "uz/eDSrx3d4iVHR+kSeopxFKsrK+KCH3CbBUMIFGX/GE9WPhDWCtjjNKEe8W" - + "PinQtxvv8MlqGXtv3v7ObJ2BmfIfLD0rh3EB5WuRNKL7Ssxaq14KZGEBvc7G" - + "Fx7jXLOW6ZV3SH+C3deJGlKM2kVhDdIVjjODvQzD8qw8a/ZKqDO5hGGKUTGD" - + "Psdd7O/k/Wfn+XdE+YuKIhcEAQQEAQgECJJCZNJdIshRBAEEBAEIBAiGGrlG" - + "HlKwrAQBBAQBCAQIkdvKinJYjJcEAQQEAUAEQBGiIgN/s1bvPQr+p1aQNh/X" - + "UQFmay6Vm5HIvPhoNrX86gmMjr6/sg28/WCRtSfyuYjwQkK91n7MwFLOBaU3" - + "RrsEAQQEAQgECLRqESFR50+zBAEEBAEIBAguqbAEWMTiPwQBBAQBGAQYKzUv" - + "EetQEAe3cXEGlSsY4a/MNTbzu1WbBAEEBAEIBAiVpOv1dOWZ1AQCAAAEAgAA" - + "BAIAAAQCAAAEAgAABAIAAAAAAAAAADA1MCEwCQYFKw4DAhoFAAQUvMkeVqe6" - + "D4UmMHGEQwcb8O7ZwhgEEGiX9DeqtRwQnVi+iY/6Re8AAA=="); + byte[] pkcs12 = Base64.decode( + "MIACAQMwgAYJKoZIhvcNAQcBoIAkgAQBMAQBgAQBMAQBgAQBBgQBCQQJKoZI" + + "hvcNAQcBBAGgBAGABAEkBAGABAEEBAEBBAEwBAEEBAEDBAOCAzQEAQQEAQEE" + + "ATAEAQQEAQMEA4IDMAQBBAQBAQQBBgQBBAQBAQQBCwQBBAQBCwQLKoZIhvcN" + + "AQwKAQIEAQQEAQEEAaAEAQQEAQMEA4ICpQQBBAQBAQQBMAQBBAQBAwQDggKh" + + "BAEEBAEBBAEwBAEEBAEBBAEbBAEEBAEBBAEGBAEEBAEBBAEKBAEEBAEKBAoq" + + "hkiG9w0BDAEDBAEEBAEPBA8wDQQIoagiwNZPJR4CAQEEAQQEAQEEAQQEAQQE" + + "AQMEA4ICgAQBBAQDggKABIICgEPG0XlhMFyrs4ZWDrvEzl51ICfXd6K2ql2l" + + "nnxhszUbigtSj6x49VEx4PfOB9fQFeidc5L5An+nKp646NBMIY0UwXGs8BLQ" + + "au59jtOs987+l7QYIvl6fdGUIuLPhVSnZZDyqD+HQjU/0/ccKFHRif4tlEQq" + + "aErvZbFeH0pg4ijf1HfgX6gBJGRKdO+msa4qKGnZdHCSLZehyyxvxAmURetg" + + "yhtEl7RmedTB+4TDs7atekqxkNlD9tfwDUX6sb0IH6qbEA6P/DlVMdaD54Cl" + + "QDxRzOfIIjklZhv5OMFWtPK0aYPcqyxzLpw1qRAyoTVXpidkj/hpIpgCVBP/" + + "k5s2+WdGbLgA/4/zSrF6feRCE5llzM2IGxiHVq4oPzzngl3R+Fi5VCPDMcuW" + + "NRuIOzJA+RNV2NPOE/P3knThDnwiImq+rfxmvZ1u6T06s20RmWK6cxp7fTEw" + + "lQ9BOsv+mmyV8dr6cYJq4IlRzHdFOyEUBDwfHThyribNKKobO50xh2f93xYj" + + "Rn5UMOQBJIe3b7OKZt5HOIMrJSZO02IZgvImi9yQWi96PnWa419D1cAsLWvM" + + "xiN0HqZMbDFfxVM2BZmsxiexLhkHWKwLqfQDzRjJfmVww8fnXpWZhFXKyut9" + + "gMGEyCNoba4RU3QI/wHKWYaK74qtJpsucuLWBH6UcsHsCry6VZkwRxWwC0lb" + + "/F3Bm5UKHax5n9JHJ2amQm9zW3WJ0S5stpPObfmg5ArhbPY+pVOsTqBRlop1" + + "bYJLD/X8Qbs468Bwzej0FhoEU59ZxFrbjLSBsMUYrVrwD83JE9kEazMLVchc" + + "uCB9WT1g0hxYb7VA0BhOrWhL8F5ZH72RMCYLPI0EAQQEAQEEATEEAQQEAQEE" + + "AXgEAQQEAQEEATAEAQQEAQEEAVEEAQQEAQEEAQYEAQQEAQEEAQkEAQQEAQkE" + + "CSqGSIb3DQEJFAQBBAQBAQQBMQQBBAQBAQQBRAQBBAQBAQQBHgQBBAQBAQQB" + + "QgQBBAQBQgRCAEQAYQB2AGkAZAAgAEcALgAgAEgAbwBvAGsAJwBzACAAVgBl" + + "AHIAaQBTAGkAZwBuACwAIABJAG4AYwAuACAASQBEBAEEBAEBBAEwBAEEBAEB" + + "BAEjBAEEBAEBBAEGBAEEBAEBBAEJBAEEBAEJBAkqhkiG9w0BCRUEAQQEAQEE" + + "ATEEAQQEAQEEARYEAQQEAQEEAQQEAQQEAQEEARQEAQQEARQEFKEcMJ798oZL" + + "FkH0OnpbUBnrTLgWBAIAAAQCAAAEAgAABAEwBAGABAEGBAEJBAkqhkiG9w0B" + + "BwYEAaAEAYAEATAEAYAEAQIEAQEEAQAEATAEAYAEAQYEAQkECSqGSIb3DQEH" + + "AQQBMAQBGwQBBgQBCgQKKoZIhvcNAQwBBgQPMA0ECEE7euvmxxwYAgEBBAGg" + + "BAGABAEEBAEIBAgQIWDGlBWxnwQBBAQBCAQI2WsMhavhSCcEAQQEAQgECPol" + + "uHJy9bm/BAEEBAEQBBCiRxtllKXkJS2anKD2q3FHBAEEBAEIBAjKy6BRFysf" + + "7gQBBAQDggMwBIIDMJWRGu2ZLZild3oz7UBdpBDUVMOA6eSoWiRIfVTo4++l" + + "RUBm8TpmmGrVkV32PEoLkoV+reqlyWCvqqSjRzi3epQiVwPQ6PV+ccLqxDhV" + + "pGWDRQ5UttDBC2+u4fUQVZi2Z1i1g2tsk6SzB3MKUCrjoWKvaDUUwXo5k9Vz" + + "qSLWCLTZCjs3RaY+jg3NbLZYtfMDdYovhCU2jMYV9adJ8MxxmJRz+zPWAJph" + + "LH8hhfkKG+wJOSszqk9BqGZUa/mnZyzeQSMTEFga1ZB/kt2e8SZFWrTZEBgJ" + + "oszsL5MObbwMDowNurnZsnS+Mf7xi01LeG0VT1fjd6rn9BzVwuMwhoqyoCNo" + + "ziUqSUyLEwnGTYYpvXLxzhNiYzW8546KdoEKDkEjhfYsc4XqSjm9NYy/BW/M" + + "qR+aL92j8hqnkrWkrWyvocUe3mWaiqt7/oOzNZiMTcV2dgjjh9HfnjSHjFGe" + + "CVhnEWzV7dQIVyc/qvNzOuND8X5IyJ28xb6a/i1vScwGuo/UDgPAaMjGw28f" + + "siOZBShzde0Kj82y8NilfYLHHeIGRW+N/grUFWhW25mAcBReXDd5JwOqM/eF" + + "y+4+zBzlO84ws88T1pkSifwtMldglN0APwr4hvUH0swfiqQOWtwyeM4t+bHd" + + "5buAlXOkSeF5rrLzZ2/Lx+JJmI2pJ/CQx3ej3bxPlx/BmarUGAxaI4le5go4" + + "KNfs4GV8U+dbEHQz+yDYL+ksYNs1eb+DjI2khbl28jhoeAFKBtu2gGOL5M9M" + + "CIP/JDOCHimu1YZRuOTAf6WISnG/0Ri3pYZsgQ0i4cXj+WfYwYVjhKX5AcDj" + + "UKnc4/Cxp+TbbgZqEKRcYVb2q0kOAxkeaNo3WCm+qvUYrwAmKp4nVB+/24rK" + + "khHiyYJQsETxtOEyvJkVxAS01djY4amuJ4jL0sYnXIhW3Ag93eavbzksGT7W" + + "Fg1ywpr1x1xpXWIIuVt1k4e+g9fy7Yx7rx0IK1qCSjNwU3QPWbaef1rp0Q/X" + + "P9IVXYkqo1g/T3SyXqrbZLO+sDjiG4IT3z3fJJqt81sRSVT0QN1ND8l93BG4" + + "QKzghYw8sZ4FwKPtLky1dDcVTgQBBAQBCAQIK/85VMKWDWYEAQQEAQgECGsO" + + "Q85CcFwPBAEEBAEIBAhaup6ot9XnQAQBBAQCgaAEgaCeCMadSm5fkLfhErYQ" + + "DgePZl/rrjP9FQ3VJZ13XrjTSjTRknAbXi0DEu2tvAbmCf0sdoVNuZIZ92W0" + + "iyaa2/A3RHA2RLPNQz5meTi1RE2N361yR0q181dC3ztkkJ8PLyd74nCtgPUX" + + "0JlsvLRrdSjPBpBQ14GiM8VjqeIY7EVFy3vte6IbPzodxaviuSc70iXM4Yko" + + "fQq6oaSjNBFRqkHrBAEEBAEIBAjlIvOf8SnfugQBBAQBCAQIutCF3Jovvl0E" + + "AQQEAQgECO7jxbucdp/3BAEEBAEIBAidxK3XDLj+BwQBBAQBCAQI3m/HMbd3" + + "TwwEAQQEA4ICOASCAjgtoCiMfTkjpCRuMhF5gNLRBiNv+xjg6GvZftR12qiJ" + + "dLeCERI5bvXbh9GD6U+DjTUfhEab/37TbiI7VOFzsI/R137sYy9Tbnu7qkSx" + + "u0bTvyXSSmio6sMRiWIcakmDbv+TDWR/xgtj7+7C6p+1jfUGXn/RjB3vlyjL" + + "Q9lFe5F84qkZjnADo66p9gor2a48fgGm/nkABIUeyzFWCiTp9v6FEzuBfeuP" + + "T9qoKSnCitaXRCru5qekF6L5LJHLNXLtIMSrbO0bS3hZK58FZAUVMaqawesJ" + + "e/sVfQip9x/aFQ6U3KlSpJkmZK4TAqp9jIfxBC8CclbuwmoXPMomiCH57ykr" + + "vkFHOGcxRcCxax5HySCwSyPDr8I4+6Kocty61i/1Xr4xJjb+3oyFStIpB24x" + + "+ALb0Mz6mUa1ls76o+iQv0VM2YFwnx+TC8KC1+O4cNOE/gKeh0ircenVX83h" + + "GNez8C5Ltg81g6p9HqZPc2pkwsneX2sJ4jMsjDhewV7TyyS3x3Uy3vTpZPek" + + "VdjYeVIcgAz8VLJOpsIjyHMB57AyT7Yj87hVVy//VODnE1T88tRXZb+D+fCg" + + "lj2weQ/bZtFzDX0ReiEQP6+yklGah59omeklIy9wctGV1o9GNZnGBSLvQ5NI" + + "61e9zmQTJD2iDjihvQA/6+edKswCjGRX6rMjRWXT5Jv436l75DVoUj09tgR9" + + "ytXSathCjQUL9MNXzUMtr7mgEUPETjM/kYBR7CNrsc+gWTWHYaSWuqKVBAEE" + + "BAEIBAh6slfZ6iqkqwQBBAQBCAQI9McJKl5a+UwEAQQEATgEOBelrmiYMay3" + + "q0OW2x2a8QQodYqdUs1TCUU4JhfFGFRy+g3yU1cP/9ZSI8gcI4skdPc31cFG" + + "grP7BAEEBAEIBAhzv/wSV+RBJQQBBAQBCAQI837ImVqqlr4EAQQEAQgECGeU" + + "gjULLnylBAEEBAEIBAjD3P4hlSBCvQQBBAQBCAQISP/qivIzf50EAQQEAQgE" + + "CKIDMX9PKxICBAEEBAOCBOgEggTocP5VVT1vWvpAV6koZupKN1btJ3C01dR6" + + "16g1zJ5FK5xL1PTdA0r6iAwVtgYdxQYnU8tht3bkNXdPJC1BdsC9oTkBg9Nr" + + "dqlF5cCzXWIezcR3ObjGLpXu49SAHvChH4emT5rytv81MYxZ7bGmlQfp8BNa" + + "0cMZz05A56LXw//WWDEzZcbKSk4tCsfMXBdGk/ngs7aILZ4FGM620PBPtD92" + + "pz2Ui/tUZqtQ0WKdLzwga1E/rl02a/x78/OdlVRNeaIYWJWLmLavX98w0PhY" + + "ha3Tbj/fqq+H3ua6Vv2Ff4VeXazkXpp4tTiqUxhc6aAGiRYckwZaP7OPSbos" + + "RKFlRLVofSGu1IVSKO+7faxV4IrVaAAzqRwLGkpJZLV7NkzkU1BwgvsAZAI4" + + "WClPDF228ygbhLwrSN2NK0s+5bKhTCNAR/LCUf3k7uip3ZSe18IwEkUMWiaZ" + + "ayktcTYn2ZjmfIfV7wIxHgWPkP1DeB+RMS7VZe9zEgJKOA16L+9SNBwJSSs9" + + "5Sb1+nmhquZmnAltsXMgwOrR12JLIgdfyyqGcNq997U0/KuHybqBVDVu0Fyr" + + "6O+q5oRmQZq6rju7h+Hb/ZUqRxRoTTSPjGD4Cu9vUqkoNVgwYOT+88FIMYun" + + "g9eChhio2kwPYwU/9BNGGzh+hAvAKcUpO016mGLImYin+FpQxodJXfpNCFpG" + + "4v4HhIwKh71OOfL6ocM/518dYwuU4Ds2/JrDhYYFsn+KprLftjrnTBnSsfYS" + + "t68b+Xr16qv9r6sseEkXbsaNbrGiZAhfHEVBOxQ4lchHrMp4zpduxG4crmpc" + + "+Jy4SadvS0uaJvADgI03DpsDYffUdriECUqAfOg/Hr7HHyr6Q9XMo1GfIarz" + + "eUHBgi1Ny0nDTWkdb7I3bIajG+Unr3KfK6dZz5Lb3g5NeclU5zintB1045Jr" + + "j9fvGGk0/2lG0n17QViBiOzGs2poTlhn7YxmiskwlkRKVafxPZNPxKILpN9s" + + "YaWGz93qER/pGMJarGJxu8sFi3+yt6FZ4pVPkvKE8JZMEPBBrmH41batS3sw" + + "sfnJ5CicAkwd8bluQpoc6qQd81HdNpS6u7djaRSDwPtYnZWu/8Hhj4DXisje" + + "FJBAjQdn2nK4MV7WKVwr+mNcVgOdc5IuOZbRLOfc3Sff6kYVuQFfcCGgAFpd" + + "nbprF/FnYXR/rghWE7fT1gfzSMNv+z5UjZ5Rtg1S/IQfUM/P7t0UqQ01/w58" + + "bTlMGihTxHiJ4Qf3o5GUzNmAyryLvID+nOFqxpr5es6kqSN4GPRHsmUIpB9t" + + "f9Nw952vhsXI9uVkhQap3JvmdAKJaIyDz6Qi7JBZvhxpghVIDh73BQTaAFP9" + + "5GUcPbYOYJzKaU5MeYEsorGoanSqPDeKDeZxjxJD4xFsqJCoutyssqIxnXUN" + + "Y3Uojbz26IJOhqIBLaUn6QVFX79buWYjJ5ZkDS7D8kq6DZeqZclt5711AO5U" + + "uz/eDSrx3d4iVHR+kSeopxFKsrK+KCH3CbBUMIFGX/GE9WPhDWCtjjNKEe8W" + + "PinQtxvv8MlqGXtv3v7ObJ2BmfIfLD0rh3EB5WuRNKL7Ssxaq14KZGEBvc7G" + + "Fx7jXLOW6ZV3SH+C3deJGlKM2kVhDdIVjjODvQzD8qw8a/ZKqDO5hGGKUTGD" + + "Psdd7O/k/Wfn+XdE+YuKIhcEAQQEAQgECJJCZNJdIshRBAEEBAEIBAiGGrlG" + + "HlKwrAQBBAQBCAQIkdvKinJYjJcEAQQEAUAEQBGiIgN/s1bvPQr+p1aQNh/X" + + "UQFmay6Vm5HIvPhoNrX86gmMjr6/sg28/WCRtSfyuYjwQkK91n7MwFLOBaU3" + + "RrsEAQQEAQgECLRqESFR50+zBAEEBAEIBAguqbAEWMTiPwQBBAQBGAQYKzUv" + + "EetQEAe3cXEGlSsY4a/MNTbzu1WbBAEEBAEIBAiVpOv1dOWZ1AQCAAAEAgAA" + + "BAIAAAQCAAAEAgAABAIAAAAAAAAAADA1MCEwCQYFKw4DAhoFAAQUvMkeVqe6" + + "D4UmMHGEQwcb8O7ZwhgEEGiX9DeqtRwQnVi+iY/6Re8AAA=="); byte[] certUTF = Base64.decode( "MIIGVQIBAzCCBg8GCSqGSIb3DQEHAaCCBgAEggX8MIIF+DCCAsUGCSqGSIb3" - + "DQEHAaCCArYEggKyMIICrjCCAqoGCyqGSIb3DQEMCgEDoIIChTCCAoEGCiqG" - + "SIb3DQEJFgGgggJxBIICbTCCAmkwggHSoAMCAQICAQcwDQYJKoZIhvcNAQEF" - + "BQAwOTEPMA0GA1UEBxMGTGV1dmVuMRkwFwYDVQQKExBVdGltYWNvIFN1YiBD" - + "QSAyMQswCQYDVQQGEwJCRTAeFw05OTEyMzEyMzAwMDBaFw0xOTEyMzEyMzAw" - + "MDBaMFcxCzAJBgNVBAYTAkJFMQ8wDQYDVQQHEwZIYWFjaHQxEDAOBgNVBAoT" - + "B1V0aW1hY28xDDAKBgNVBAsMA1ImRDEXMBUGA1UEAxMOR2VlcnQgRGUgUHJp" - + "bnMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYGIyhTn/p0IA41ElLD" - + "fZ44PS88AAcDCiOd2DIMLck56ea+5nhI0JLyz1XgPHecc8SLFdl7vSIBA0eb" - + "tm/A7WIqIp0lcvgoyQ0qsak/dvzs+xw6r2xLCVogku4+/To6UebtfRsukXNI" - + "ckP5lWV/Ui4l+XvGdmENlEE9/BvOZIvLAgMBAAGjYzBhMBEGA1UdIwQKMAiA" - + "BlN1YkNBMjAQBgNVHQ4ECQQHVXNlcklEMjAOBgNVHQ8BAf8EBAMCBLAwGQYD" - + "VR0RBBIwEIEOVXNlcklEMkB1dGkuYmUwDwYDVR0TAQH/BAUwAwEBADANBgkq" - + "hkiG9w0BAQUFAAOBgQACS7iLLgMV4O5gFdriI7dqX55l7Qn6HiRNxlSH2kCX" - + "41X82gae4MHFc41qqsC4qm6KZWi1yvTN9XgSBCXTaw1SXGTK7SuNdoYh6ufC" - + "KuAwy5lsaetyARDksRiOIrNV9j+MRIjJMjPNg+S+ysIHTWZo2NTUuVuZ01D2" - + "jDtYPhcDFDESMBAGCSqGSIb3DQEJFTEDBAE3MIIDKwYJKoZIhvcNAQcGoIID" - + "HDCCAxgCAQAwggMRBgkqhkiG9w0BBwEwKAYKKoZIhvcNAQwBAzAaBBS5KxQC" - + "BMuZ1To+yed2j/TT45td6gICCACAggLYxQS+fu7W2sLQTkslI0EoNxLoH/WO" - + "L8NgiIgZ5temV3mgC2q0MxjVVq+SCvG89ZSTfptxOaSmYV772irFdzlrtotZ" - + "wmYk1axuFDYQ1gH0M6i9FWuhOnbk7qHclmOroXqrrbP6g3IsjwztH0+iwBCg" - + "39f63V0rr8DHiu7zZ2hBkU4/RHEsXLjaCBVNTUSssWhVLisLh2sqBJccPC2E" - + "1lw4c4WrshGQ+syLGG38ttFgXT1c+xYNpUKqJiJTLVouOH9kK3nH1hPRHKMN" - + "9CucBdUzibvkcRk1L53F3MfvjhCSNeWEmd9PKN+FtUtzRWQG3L84VGTM37Ws" - + "YcxaDwDFGcw3u1W8WFsCCkjpZecKN8P2Kp/ai/iugcXY77bYwAwpETDvQFvD" - + "nnL9oGi03HYdfeiXglC7x7dlojvnpkXDbE0nJiFwhe8Mxpx8GVlGHtP+siXg" - + "tklubg1eTCSoG9m1rsBJM717ZHXUGf32HNun2dn4vOWGocgBmokZ46KKMb9v" - + "reT39JTxi8Jlp+2cYb6Qr/oBzudR+D4iAiiVhhhEbJKPNHa61YyxF810fNI2" - + "GWlNIyN3KcI8XU6WJutm/0H3X8Y+iCSWrJ2exUktj8GiqNQ6Yx0YgEk9HI7W" - + "t9UVTIsPCgCqrV4SWCOPf6so1JqnpvlPvvNyNxSsAJ7DaJx1+oD2QQfhowk/" - + "bygkKnRo5Y15ThrTsIyQKsJHTIVy+6K5uFZnlT1DGV3DcNpuk3AY26hrAzWO" - + "TuWXsULZe7M6h6U2hTT/eplZ/mwHlXdF1VErIuusaCdkSI0doY4/Q223H40L" - + "BNU3pTezl41PLceSll00WGVr2MunlNeXKnXDJW06lnfs9BmnpV2+Lkfmf30W" - + "Pn4RKJQc+3D3SV4fCoQLIGrKiZLFfEdGJcMlySr+dJYcEtoZPuo6i/hb5xot" - + "le63h65ihNtXlEDrNpYSQqnfhjOzk5/+ZvYEcOtDObEwPTAhMAkGBSsOAwIa" - + "BQAEFMIeDI9l2Da24mtA1fbQIPc6+4dUBBQ8a4lD7j1CA1vRLhdEgPM+5hpD" - + "RgICCAA="); + + "DQEHAaCCArYEggKyMIICrjCCAqoGCyqGSIb3DQEMCgEDoIIChTCCAoEGCiqG" + + "SIb3DQEJFgGgggJxBIICbTCCAmkwggHSoAMCAQICAQcwDQYJKoZIhvcNAQEF" + + "BQAwOTEPMA0GA1UEBxMGTGV1dmVuMRkwFwYDVQQKExBVdGltYWNvIFN1YiBD" + + "QSAyMQswCQYDVQQGEwJCRTAeFw05OTEyMzEyMzAwMDBaFw0xOTEyMzEyMzAw" + + "MDBaMFcxCzAJBgNVBAYTAkJFMQ8wDQYDVQQHEwZIYWFjaHQxEDAOBgNVBAoT" + + "B1V0aW1hY28xDDAKBgNVBAsMA1ImRDEXMBUGA1UEAxMOR2VlcnQgRGUgUHJp" + + "bnMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYGIyhTn/p0IA41ElLD" + + "fZ44PS88AAcDCiOd2DIMLck56ea+5nhI0JLyz1XgPHecc8SLFdl7vSIBA0eb" + + "tm/A7WIqIp0lcvgoyQ0qsak/dvzs+xw6r2xLCVogku4+/To6UebtfRsukXNI" + + "ckP5lWV/Ui4l+XvGdmENlEE9/BvOZIvLAgMBAAGjYzBhMBEGA1UdIwQKMAiA" + + "BlN1YkNBMjAQBgNVHQ4ECQQHVXNlcklEMjAOBgNVHQ8BAf8EBAMCBLAwGQYD" + + "VR0RBBIwEIEOVXNlcklEMkB1dGkuYmUwDwYDVR0TAQH/BAUwAwEBADANBgkq" + + "hkiG9w0BAQUFAAOBgQACS7iLLgMV4O5gFdriI7dqX55l7Qn6HiRNxlSH2kCX" + + "41X82gae4MHFc41qqsC4qm6KZWi1yvTN9XgSBCXTaw1SXGTK7SuNdoYh6ufC" + + "KuAwy5lsaetyARDksRiOIrNV9j+MRIjJMjPNg+S+ysIHTWZo2NTUuVuZ01D2" + + "jDtYPhcDFDESMBAGCSqGSIb3DQEJFTEDBAE3MIIDKwYJKoZIhvcNAQcGoIID" + + "HDCCAxgCAQAwggMRBgkqhkiG9w0BBwEwKAYKKoZIhvcNAQwBAzAaBBS5KxQC" + + "BMuZ1To+yed2j/TT45td6gICCACAggLYxQS+fu7W2sLQTkslI0EoNxLoH/WO" + + "L8NgiIgZ5temV3mgC2q0MxjVVq+SCvG89ZSTfptxOaSmYV772irFdzlrtotZ" + + "wmYk1axuFDYQ1gH0M6i9FWuhOnbk7qHclmOroXqrrbP6g3IsjwztH0+iwBCg" + + "39f63V0rr8DHiu7zZ2hBkU4/RHEsXLjaCBVNTUSssWhVLisLh2sqBJccPC2E" + + "1lw4c4WrshGQ+syLGG38ttFgXT1c+xYNpUKqJiJTLVouOH9kK3nH1hPRHKMN" + + "9CucBdUzibvkcRk1L53F3MfvjhCSNeWEmd9PKN+FtUtzRWQG3L84VGTM37Ws" + + "YcxaDwDFGcw3u1W8WFsCCkjpZecKN8P2Kp/ai/iugcXY77bYwAwpETDvQFvD" + + "nnL9oGi03HYdfeiXglC7x7dlojvnpkXDbE0nJiFwhe8Mxpx8GVlGHtP+siXg" + + "tklubg1eTCSoG9m1rsBJM717ZHXUGf32HNun2dn4vOWGocgBmokZ46KKMb9v" + + "reT39JTxi8Jlp+2cYb6Qr/oBzudR+D4iAiiVhhhEbJKPNHa61YyxF810fNI2" + + "GWlNIyN3KcI8XU6WJutm/0H3X8Y+iCSWrJ2exUktj8GiqNQ6Yx0YgEk9HI7W" + + "t9UVTIsPCgCqrV4SWCOPf6so1JqnpvlPvvNyNxSsAJ7DaJx1+oD2QQfhowk/" + + "bygkKnRo5Y15ThrTsIyQKsJHTIVy+6K5uFZnlT1DGV3DcNpuk3AY26hrAzWO" + + "TuWXsULZe7M6h6U2hTT/eplZ/mwHlXdF1VErIuusaCdkSI0doY4/Q223H40L" + + "BNU3pTezl41PLceSll00WGVr2MunlNeXKnXDJW06lnfs9BmnpV2+Lkfmf30W" + + "Pn4RKJQc+3D3SV4fCoQLIGrKiZLFfEdGJcMlySr+dJYcEtoZPuo6i/hb5xot" + + "le63h65ihNtXlEDrNpYSQqnfhjOzk5/+ZvYEcOtDObEwPTAhMAkGBSsOAwIa" + + "BQAEFMIeDI9l2Da24mtA1fbQIPc6+4dUBBQ8a4lD7j1CA1vRLhdEgPM+5hpD" + + "RgICCAA="); byte[] pkcs12noFriendly = Base64.decode( "MIACAQMwgAYJKoZIhvcNAQcBoIAkgASCBAAwgDCABgkqhkiG9w0BBwGggCSA" - + "BIICvjCCArowggK2BgsqhkiG9w0BDAoBAqCCAqUwggKhMBsGCiqGSIb3DQEM" - + "AQMwDQQIyJDupEHvySECAQEEggKAupvM7RuZL3G4qNeJM3afElt03TVfynRT" - + "xUxAZOfx+zekHJTlnEuHJ+a16cOV6dQUgYfyMw1xcq4E+l59rVeMX9V3Zr0K" - + "tsMN9VYB/9zn62Kw6LQnY0rMlWYf4bt9Ut5ysq0hE5t9FL+NZ5FbFdWBOKsj" - + "/3oC6eNXOkOFyrY2haPJtD1hVHUosrlC0ffecV0YxPDsReeyx0R4CiYZpAUy" - + "ZD7rkxL+mSX7zTsShRiga2Q/NEhC1KZpbhO/qbyOgvH0r7CRumSMvijzDgaV" - + "IGqtrIZ2E2k5kscjcuFTW0x3OZTLAW/UnAh4JXJzC6isbdiWuswbAEBHifUC" - + "rk2f+bDJKe2gkH67J2K0yDQ3YSSibpjDX/bVfbtfmOoggK9MKQwqEeE0nbYE" - + "jzInH2OK5jPtmwppjmVA7i3Uk25w2+z7b/suUbft9hPCNjxFvzdbyCcXK4Vv" - + "xAgEbVWnIkvOQNbyaQi+DEF/4P26GwgJgXuJpMBn0zzsSZSIDLNl8eJHoKp2" - + "ZXknTi0SZkLaYlBxZlNhFoyXLfvQd6TI2aR5aCVqg1aZMBXyOWfz5t0JTVX8" - + "HTIcdXKis91iEsLB7vjcxIOASTAjKARr5tRp6OvaVterAyDOn2awYQJLLic5" - + "pQfditRAlsLkTxlDdu0/QBMXSPptO8g3R+dS7ntvCjXgZZyxpOeKkssS2l5v" - + "/B2EsfKmYA9hU4aBdW1S9o/PcF1wpVqABd8664TGJ77tCAkbdHe0VJ3Bop2X" - + "lNxlWeEeD0v0QUZLqkJoMEwi5SUE6HAWjbqGhRuHyey9E+UsdCVnQ8AxXQzL" - + "2UKOmIrXc6R25GsLPCysXuXPRFBB2Tul0V3re3hPcAAAAAAAADCABgkqhkiG" - + "9w0BBwaggDCAAgEAMIAGCSqGSIb3DQEHATAbBgoqhkiG9w0BDAEGMA0ECDXn" - + "UZu6xckzAgEBoIAEggTYQMbzAoGnRVJMbCaJJUYgaARJ4zMfxt2e12H4pX/e" - + "vnZrR1eKAMck5c2vJoEasr0i2VUcAcK12AntVIEnBwuRBcA2WrZnC28WR+O7" - + "rLdu9ymG2V3zmk66aTizaB6rcHAzs2lD74n+/zJhZNaDMBfu9LzAdWb/u6Rb" - + "AThmbw764Zyv9802pET6xrB8ureffgyvQAdlcGHM+yxaOV3ZEtS0cp7i+pb/" - + "NTiET4jAFoO1tbBrWGJSRrMKvx4ZREppMhG3e/pYglfMFl+1ejbDsOvEUKSt" - + "H+MVrgDgAv4NsUtNmBu+BIIEAIOCjrBSK3brtV0NZOWsa6hZSSGBhflbEY8s" - + "U1bDsgZIW4ZaJJvSYEXLmiWSBOgq9VxojMfjowY+zj6ePJJMyI3E7AcFa+on" - + "zZjeKxkKypER+TtpBeraqUfgf01b6olH8L2i4+1yotCQ0PS+15qRYPK6D+d3" - + "S+R4veOA6wEsNRijVcB3oQsBCi0FVdf+6MVDvjNzBCZXj0heVi+x0EE106Sz" - + "B3HaDbB/KNHMPZvvs3J3z2lWLj5w7YZ9eVmrVJKsgG2HRKxtt2IQquRj4BkS" - + "upFnMTBVgWxXgwXycauC9bgYZurs+DbijqhHfWpUrttDfavsP8aX6+i3gabK" - + "DH4LQRL7xrTcKkcUHxOTcPHLgDPhi+RevkV+BX9tdajbk4tqw1d+0wOkf1pW" - + "aTG8fUp0lUpra7EJ0lGy8t/MB3NEk/5tLk9qA2nsKKdNoEdZWiEBE0fMrH1o" - + "tWJDew3VhspT+Lkor2dLN5ydjcr3wkb76OETPeMxS91onNj5mrAMUBt66vb6" - + "Gx4CL8FTRNZ/l8Kzngzdv9PmmKPTIXbhYbn3XRGg3od2tC/oVfsqYlGAMgFO" - + "STt+BZ1BR9Phyi4jsiy8R0seCEDRWYQLbwgwVj0V8Rx9VptqRoCnB4XhGJoJ" - + "TdAz/MT7KOSxIh2F2FymTJpyImcV6X4Kcj9iY0AZQ4zj712g4yMR6xKGzRu6" - + "oIBDkFW2bdA3Lb9ePpo5GFtNyA7IbggIko6VOeeOKxaq9nALS2gsZc1yaYtp" - + "aKL8kB+dVTCXiLgQniO6eMzgonsuwFnG+42XM1vhEpAvFzeJRC0CYzebEK9n" - + "nGXKCPoqPFuw3gcPMn57NCZJ8MjT/p0wANIEm6AsgqrdFKwTRVJ1ytB/X9Ri" - + "ysmjMBs9zbFKjU9jVDg1vGBNtb7YnYg9IrYHa3e4yTu2wUJKGP2XWHVgjDR7" - + "6RtzlO4ljw0kkSMMEDle2ZbGZ6lVXbFwV0wPNPmGA6+XGJRxcddTnrM6R/41" - + "zqksFLgoNL2BdofMXwv7SzxGyvFhHdRRdBZ5dKj2K9OfXakEcm/asZGu87u8" - + "y9m7Cckw8ilSNPMdvYiFRoThICx9NiwYl1IIKGcWlb9p6RAx6XNSkY6ZZ6pE" - + "Vla1E26rbd7is1ssSeqxLXXV9anuG5HDwMIt+CIbD8fZmNTcWMzZRiaFajvR" - + "gXdyTu/UhVdhiQPF+lrxp4odgF0cXrpcGaKvOtPq04F4ad3O5EkSGucI210Q" - + "pR/jQs07Yp5xDPzsXAb8naHb84FvK1iONAEjWbfhDxqtH7KGrBbW4KEzJrv3" - + "B8GLDp+wOAFjGEdGDPkOx3y2L2HuI1XiS9LwL+psCily/A96OiUyRU8yEz4A" - + "AAAAAAAAAAAEAwAAAAAAAAAAADAtMCEwCQYFKw4DAhoFAAQU1NQjgVRH6Vg3" - + "tTy3wnQisALy9aYECKiM2gZrLi+fAAA="); - - static char[] noFriendlyPassword = "sschette12".toCharArray(); + + "BIICvjCCArowggK2BgsqhkiG9w0BDAoBAqCCAqUwggKhMBsGCiqGSIb3DQEM" + + "AQMwDQQIyJDupEHvySECAQEEggKAupvM7RuZL3G4qNeJM3afElt03TVfynRT" + + "xUxAZOfx+zekHJTlnEuHJ+a16cOV6dQUgYfyMw1xcq4E+l59rVeMX9V3Zr0K" + + "tsMN9VYB/9zn62Kw6LQnY0rMlWYf4bt9Ut5ysq0hE5t9FL+NZ5FbFdWBOKsj" + + "/3oC6eNXOkOFyrY2haPJtD1hVHUosrlC0ffecV0YxPDsReeyx0R4CiYZpAUy" + + "ZD7rkxL+mSX7zTsShRiga2Q/NEhC1KZpbhO/qbyOgvH0r7CRumSMvijzDgaV" + + "IGqtrIZ2E2k5kscjcuFTW0x3OZTLAW/UnAh4JXJzC6isbdiWuswbAEBHifUC" + + "rk2f+bDJKe2gkH67J2K0yDQ3YSSibpjDX/bVfbtfmOoggK9MKQwqEeE0nbYE" + + "jzInH2OK5jPtmwppjmVA7i3Uk25w2+z7b/suUbft9hPCNjxFvzdbyCcXK4Vv" + + "xAgEbVWnIkvOQNbyaQi+DEF/4P26GwgJgXuJpMBn0zzsSZSIDLNl8eJHoKp2" + + "ZXknTi0SZkLaYlBxZlNhFoyXLfvQd6TI2aR5aCVqg1aZMBXyOWfz5t0JTVX8" + + "HTIcdXKis91iEsLB7vjcxIOASTAjKARr5tRp6OvaVterAyDOn2awYQJLLic5" + + "pQfditRAlsLkTxlDdu0/QBMXSPptO8g3R+dS7ntvCjXgZZyxpOeKkssS2l5v" + + "/B2EsfKmYA9hU4aBdW1S9o/PcF1wpVqABd8664TGJ77tCAkbdHe0VJ3Bop2X" + + "lNxlWeEeD0v0QUZLqkJoMEwi5SUE6HAWjbqGhRuHyey9E+UsdCVnQ8AxXQzL" + + "2UKOmIrXc6R25GsLPCysXuXPRFBB2Tul0V3re3hPcAAAAAAAADCABgkqhkiG" + + "9w0BBwaggDCAAgEAMIAGCSqGSIb3DQEHATAbBgoqhkiG9w0BDAEGMA0ECDXn" + + "UZu6xckzAgEBoIAEggTYQMbzAoGnRVJMbCaJJUYgaARJ4zMfxt2e12H4pX/e" + + "vnZrR1eKAMck5c2vJoEasr0i2VUcAcK12AntVIEnBwuRBcA2WrZnC28WR+O7" + + "rLdu9ymG2V3zmk66aTizaB6rcHAzs2lD74n+/zJhZNaDMBfu9LzAdWb/u6Rb" + + "AThmbw764Zyv9802pET6xrB8ureffgyvQAdlcGHM+yxaOV3ZEtS0cp7i+pb/" + + "NTiET4jAFoO1tbBrWGJSRrMKvx4ZREppMhG3e/pYglfMFl+1ejbDsOvEUKSt" + + "H+MVrgDgAv4NsUtNmBu+BIIEAIOCjrBSK3brtV0NZOWsa6hZSSGBhflbEY8s" + + "U1bDsgZIW4ZaJJvSYEXLmiWSBOgq9VxojMfjowY+zj6ePJJMyI3E7AcFa+on" + + "zZjeKxkKypER+TtpBeraqUfgf01b6olH8L2i4+1yotCQ0PS+15qRYPK6D+d3" + + "S+R4veOA6wEsNRijVcB3oQsBCi0FVdf+6MVDvjNzBCZXj0heVi+x0EE106Sz" + + "B3HaDbB/KNHMPZvvs3J3z2lWLj5w7YZ9eVmrVJKsgG2HRKxtt2IQquRj4BkS" + + "upFnMTBVgWxXgwXycauC9bgYZurs+DbijqhHfWpUrttDfavsP8aX6+i3gabK" + + "DH4LQRL7xrTcKkcUHxOTcPHLgDPhi+RevkV+BX9tdajbk4tqw1d+0wOkf1pW" + + "aTG8fUp0lUpra7EJ0lGy8t/MB3NEk/5tLk9qA2nsKKdNoEdZWiEBE0fMrH1o" + + "tWJDew3VhspT+Lkor2dLN5ydjcr3wkb76OETPeMxS91onNj5mrAMUBt66vb6" + + "Gx4CL8FTRNZ/l8Kzngzdv9PmmKPTIXbhYbn3XRGg3od2tC/oVfsqYlGAMgFO" + + "STt+BZ1BR9Phyi4jsiy8R0seCEDRWYQLbwgwVj0V8Rx9VptqRoCnB4XhGJoJ" + + "TdAz/MT7KOSxIh2F2FymTJpyImcV6X4Kcj9iY0AZQ4zj712g4yMR6xKGzRu6" + + "oIBDkFW2bdA3Lb9ePpo5GFtNyA7IbggIko6VOeeOKxaq9nALS2gsZc1yaYtp" + + "aKL8kB+dVTCXiLgQniO6eMzgonsuwFnG+42XM1vhEpAvFzeJRC0CYzebEK9n" + + "nGXKCPoqPFuw3gcPMn57NCZJ8MjT/p0wANIEm6AsgqrdFKwTRVJ1ytB/X9Ri" + + "ysmjMBs9zbFKjU9jVDg1vGBNtb7YnYg9IrYHa3e4yTu2wUJKGP2XWHVgjDR7" + + "6RtzlO4ljw0kkSMMEDle2ZbGZ6lVXbFwV0wPNPmGA6+XGJRxcddTnrM6R/41" + + "zqksFLgoNL2BdofMXwv7SzxGyvFhHdRRdBZ5dKj2K9OfXakEcm/asZGu87u8" + + "y9m7Cckw8ilSNPMdvYiFRoThICx9NiwYl1IIKGcWlb9p6RAx6XNSkY6ZZ6pE" + + "Vla1E26rbd7is1ssSeqxLXXV9anuG5HDwMIt+CIbD8fZmNTcWMzZRiaFajvR" + + "gXdyTu/UhVdhiQPF+lrxp4odgF0cXrpcGaKvOtPq04F4ad3O5EkSGucI210Q" + + "pR/jQs07Yp5xDPzsXAb8naHb84FvK1iONAEjWbfhDxqtH7KGrBbW4KEzJrv3" + + "B8GLDp+wOAFjGEdGDPkOx3y2L2HuI1XiS9LwL+psCily/A96OiUyRU8yEz4A" + + "AAAAAAAAAAAEAwAAAAAAAAAAADAtMCEwCQYFKw4DAhoFAAQU1NQjgVRH6Vg3" + + "tTy3wnQisALy9aYECKiM2gZrLi+fAAA="); + + static char[] noFriendlyPassword = "sschette12".toCharArray(); byte[] pkcs12StorageIssue = Base64.decode( "MIIO8QIBAzCCDrEGCSqGSIb3DQEHAaCCDqIEgg6eMIIOmjCCBBMGCSqGSIb3" - + "DQEHAaCCBAQEggQAMIID/DCCA/gGCyqGSIb3DQEMCgECoIICtjCCArIwHAYK" - + "KoZIhvcNAQwBAzAOBAgURJ+/5hA2pgICB9AEggKQYZ4POE8clgH9Bjd1XO8m" - + "sr6NiRBiA08CllHSOn2RzyAgHTa+cKaWrEVVJ9mCd9XveSUCoBF9E1C3jSl0" - + "XIqLNgYd6mWK9BpeMRImM/5crjy///K4ab9kymzkc5qc0pIpdCQCZ04YmtFP" - + "B80VCgyaoh2xoxqgjBCIgdSg5XdepdA5nXkG9EsQ1oVUyCykv20lKgKKRseG" - + "Jo23AX8YUYR7ANqP2gz9lvlX6RBczuoZ62ujopUexiQgt5SZx97sgo3o/b/C" - + "px17A2L4wLdeAYCMCsZhC2UeaqnZCHSsvnPZfRGiuSEGbV5gHLmXszLDaEdQ" - + "Bo873GTpKTTzBfRFzNCtYtZRqh2AUsInWZWQUcCeX6Ogwa0wTonkp18/tqsh" - + "Fj1fVpnsRmjJTTXFxkPtUw5GPJnDAM0t1xqV7kOjN76XnZrMyk2azQ1Mf3Hn" - + "sGpF+VRGH6JtxbM0Jm5zD9uHcmkSfNR3tP/+vHOB1mkIR9tD2cHvBg7pAlPD" - + "RfDVWynhS+UBNlQ0SEM/pgR7PytRSUoKc/hhe3N8VerF7VL3BwWfBLlZFYZH" - + "FvPQg4coxF7+We7nrSQfXvdVBP9Zf0PTdf3pbZelGCPVjOzbzY/o/cB23IwC" - + "ONxlY8SC1nJDXrPZ5sY51cg/qUqor056YqipRlI6I+FoTMmMDKPAiV1V5ibo" - + "DNQJkyv/CAbTX4+oFlxgddTwYcPZgd/GoGjiP9yBHHdRISatHwMcM06CzXJS" - + "s3MhzXWD4aNxvvSpXAngDLdlB7cm4ja2klmMzL7IuxzLXFQFFvYf7IF5I1pC" - + "YZOmTlJgp0efL9bHjuHFnh0S0lPtlGDOjJ/4YpWvSKDplcPiXhaFVjsUtclE" - + "oxCC5xppRm8QWS8xggEtMA0GCSsGAQQBgjcRAjEAMBMGCSqGSIb3DQEJFTEG" - + "BAQBAAAAMGkGCSsGAQQBgjcRATFcHloATQBpAGMAcgBvAHMAbwBmAHQAIABS" - + "AFMAQQAgAFMAQwBoAGEAbgBuAGUAbAAgAEMAcgB5AHAAdABvAGcAcgBhAHAA" - + "aABpAGMAIABQAHIAbwB2AGkAZABlAHIwgZsGCSqGSIb3DQEJFDGBjR6BigA3" - + "AGQAZQBmADUAYgA0ADMANgBjAGEAYgBkADAAMAAyAGQAZAAyADkAMAAzAGIA" - + "MQA2ADgANgBjADcAOQA0ADgAXwA0ADYAZgAyADYAZgBkADQALQA4ADEAMgBk" - + "AC0ANABlAGYAYgAtADgAMAA4ADgALQA0ADUAYQBiADkAMQA5ADEAMAA3AGMA" - + "YzCCCn8GCSqGSIb3DQEHBqCCCnAwggpsAgEAMIIKZQYJKoZIhvcNAQcBMBwG" - + "CiqGSIb3DQEMAQYwDgQIbr2xdnQ9inMCAgfQgIIKOHg9VKz+jlM+3abi3cp6" - + "/XMathxDSEJLrxJs6j5DAVX17S4sw1Q/1pptjdMdd8QtTfUB6JpfgJ5Kpn+h" - + "gZMf6M8wWue0U/RZN0D9w7o+2n+X3ItdEXu80eJVDOm7I2p8qiXtijbMbXRL" - + "Cup1lgfPM5uv2D63/hmWRXLeG8eySrJnKENngpM559V8TI2JcTUBy1ZP3kcH" - + "KbcJ/tVPnIIe4qguxfsTmDtAQviGvWUohbt+RGFmtqfgntK7o6b+S8uRSwEs" - + "fOU/pnVE9M1ugtNJZI/xeGJq6umZWXA/OrAcK7feWUwqRvfivDGQJEoggByd" - + "4/g92PhK1JGkwlCb1HdfhOOKKChowQ4zVvSOm+uBxARGhk2i5uW9I20I0vSJ" - + "px42O2VFVJweOchfp+wBtSHBKYP1ZXyXWMvOtULClosSeesbYMAwvyBfpYEz" - + "3rQt/1iZkqDmEisXk8X1aEKG1KSWaSPyb/+6glWikDm+YdQw3Khu7IZt1l/H" - + "qWGecccel+R9mT4YjRzHlahUYk4U+RNVasVpH1Kxz2j3CZqL+b3jQOwSAPd/" - + "hKI+S/pjIpBPfiC4WxORAzGZzY2j+a79B70h1DO1D9jGur3vJDbdmGBNgs6d" - + "nonE1B527SICcGeXY1MtnZCLOPvySih0AvOekbN9x2CJg+Hp9e7A3Fxni53/" - + "oMLr9wGRRDki72eXCXW98mU8VJofoWYS1/VBLXGf/f+tJ9J02PpzxleqPH9T" - + "4mE+YHnZId6cqjCXmwvMr2cMw2clDVfvkbAJRE3eZHzL7IWSO8+giXzzrTsl" - + "VbMuXVkT4oniTN7TSRsBCT3zVVmCy1QL2hPBD6KsVc+bvLgAHRov84FPrI3f" - + "kY/oJufT36VE34Eu+QjzULlvVsLE3lhjutOerVIGSP//FM4LE99hp214P0JF" - + "DgBK+3J+ihmFdW8hUXOt6BU8/MBeiroiJMWo1/f/XcduekG2ZsdGv+GNPzXI" - + "PyHRpCgAgmck1+qoUPXxHRJuNqv223OZ5MN14X7iLl5OZ+f8IWfxUnZeZ9gj" - + "HNeceElwZ+YOup1CAi3haD9jxRWhZG4NDfB4IYi4Bc/TAkXE3jCPkYEvIbj9" - + "ExaU1Ts0+lqOOcwRmBoYjVrz0xbtfR/OWlopyrDHbeL5iQcQCW/loYRapWCZ" - + "E4ekHknpX9yoAwT355vtTkl0VKXeSZHE8jREhN95aY9zCoLYwbTQDTw7qUR5" - + "UamabLew0oS0XALtuOrfX4OUOZZUstUsGBle/Pw1TE3Bhe1clhrikp0F+Xgb" - + "Xx90KqxZX/36RMnCMAD7/q+57rV7WXp2Y5tT0AUgyUMjy1F1X/b1olUfqO1u" - + "rlWIUTl2znmQ3D9uO3W4ytfgGd5DpKcl2w84MBAT9qGwKuQg/UYKbP4K/+4L" - + "Y1DWCy3utmohQ28IJtlIUkPL1G7lHX1tfq/VA+bRNTJIhMrNn06ZJpuEJHDs" - + "/ferdlMFt/d6MrwVivmPVYkb8mSbHSiI8jZOFE44sA974depsDyXafFaSsl0" - + "bVzqOAu0C/n9dIednU0xxxgDF/djdZ/QhbaDIg2VJf11wx0nw9n76B0+eeyu" - + "QLaapzxCpQNDVOAM9doBb5F1I5pXQHFQqzTNtLmqDC4x0g8IH7asyk5LCglT" - + "b1pwMqPJOL2vGWKRLhPzT+9OfSpCmYGKytf593hmGmwIgEO13hQrw31F5TYt" - + "btkbDr+Q5XilOKEczhEM+Ug7YHU7bxkckOAbxu0YeRp/57GdGLokeLJ0dRlQ" - + "+V2CfQvWJoVC6PS4PUQtjwgK2p/LU10QsEFwM/S621fGq9zGrv7+FPBATRDb" - + "k4E9D/WaRylnW11ZTrOlTchQkoHcOh0xztlFxU8jzuIuDrPQQWkoqdl6B+yf" - + "lykRNJKKxwzFiPl40nLC3nEdIzCEvR4r/9QHiWQxAVSc/wQX+an5vakUmSXS" - + "oLFjgVdY1jmvdsx2r5BQPuOR8ONGmw/muvVSMaHV85brA4uk0lxn00HD9/a0" - + "A1LCeFkabNLn9wJT8RaJeOSNmFFllLR70OHaoPSb3GyzHpvd1e6aeaimdyVH" - + "BQWJ6Ufx+HjbOGuOiN46WyE6Q27dnWxx8qF89dKB4T/J0mEXqueiUjAUnnnR" - + "Cs4zPaX53hmNBdrZGaLs+xNG8xy+iyBUJIWWfQAQjCjfHYlT9nygiUWIbVQq" - + "RHkGkAN62jsSNLgHvWVzQPNNsYq0U8TPhyyci/vc8MJytujjptcz8FPqUjg2" - + "TPv34ef9buErsm4vsdEv/8Z+9aDaNex+O3Lo3N0Aw7M5NcntFBHjFY/nBFNZ" - + "whH5YA4gQ8PLZ5qshlGvb0DFXHV/9zxnsdPkLwH47ERm5IlEAuoaWtZFxg27" - + "BjLfwU1Opk+ybDSb5WZVZrs7ljsU85p3Vaf3a//yoyr9ITYj15tTXxSPoct0" - + "fDUy1I6LjJH/+eZXKA1WSda9mDQlRocvJ0IIIlI4weJpTdm8aHIJ8OngCqOF" - + "TufcSLDM41+nxEK1LqXeAScVy74kVvvqngj6mIrbylrINZOHheEgTXrUWEc0" - + "uXS8l1YqY6K6Ru5km2jVyWi/ujrDGb6QGShC09oiDYUuUGy4gwJ3XLVX/dR3" - + "pmMExohTGiVefFP400wVZaxB9g1BQmjSEZxIaW1U1K6fk8Yni8yWB3/L/PuD" - + "0+OV+98i1sQGaPe35crIpEc7R2XJdngL0Ol1ZuvCIBfy5DQwGIawTtBnjPdi" - + "hy//QTt/isdu7C5pGaJDkZFMrfxMibr6c3xXr7wwR75sTzPNmS8mquEdLsmG" - + "h8gTUnB8/K6V11JtUExMqTimTbUw+j8PggpeBelG36breWJIz1O+dmCTGuLM" - + "x/sK/i8eiUeRvWjqYpq5DYt4URWg2WlcpcKiUxQp07/NMx0svDC+mlQGwMnJ" - + "8KOJMW1qr3TGEJ/VVKKVn6sXn/RxA+VPofYzhwZByRX87XmNdPeQKC2DHQsW" - + "6v83dua5gcnv0cv/smXt7Yr/c12i0fbIaQvj3qjtUCDucjARoBey3eCyG5H6" - + "5VHSsFnPZ2HCTum+jRSw/ENsu/77XU4BIM2fjAfswp7iIr2Xi4OZWKIj6o6q" - + "+fNgnOJjemDYHAFK+hWxClrG8b+9Eaf21o4zcHkhCfBlYv4d+xcZOIDsDPwI" - + "sf+4V+CfoBLALsa2K0pXlPplGom/a8h7CjlyaICbWpEDItqwu7NQwdMRCa7i" - + "yAyM1sVjXUdcZByS1bjOFSeBe7ygAvEl78vApLxqt8Cw11XSsOtmwssecUN/" - + "pb7iHE4OMyOgsYx9u7rZ2hMyl42n3c29IwDYMumiNqk9cwCBpQTJAQEv4VzO" - + "QE5xYDBY9SEozni+4f7B7e2Wj/LOGb3vfNVYGNpDczBFxvr2FXTQla0lNYD/" - + "aePuC++QW4KvwiGL1Zx4Jo0eoDKWYlYj0qiNlQbWfVw+raaaFnlrq+je0W6P" - + "+BrKZCncho145y+CFKRLZrN5yl/cDxwsePMVhAIMr1DzVhgBXzA3MB8wBwYF" - + "Kw4DAhoEFN4Cwj9AtArnRbOIAsRhaaoZlTNJBBTIVPqCrloqLns145CWXjb0" - + "g141BQ=="); - - static char[] storagePassword = "pass".toCharArray(); + + "DQEHAaCCBAQEggQAMIID/DCCA/gGCyqGSIb3DQEMCgECoIICtjCCArIwHAYK" + + "KoZIhvcNAQwBAzAOBAgURJ+/5hA2pgICB9AEggKQYZ4POE8clgH9Bjd1XO8m" + + "sr6NiRBiA08CllHSOn2RzyAgHTa+cKaWrEVVJ9mCd9XveSUCoBF9E1C3jSl0" + + "XIqLNgYd6mWK9BpeMRImM/5crjy///K4ab9kymzkc5qc0pIpdCQCZ04YmtFP" + + "B80VCgyaoh2xoxqgjBCIgdSg5XdepdA5nXkG9EsQ1oVUyCykv20lKgKKRseG" + + "Jo23AX8YUYR7ANqP2gz9lvlX6RBczuoZ62ujopUexiQgt5SZx97sgo3o/b/C" + + "px17A2L4wLdeAYCMCsZhC2UeaqnZCHSsvnPZfRGiuSEGbV5gHLmXszLDaEdQ" + + "Bo873GTpKTTzBfRFzNCtYtZRqh2AUsInWZWQUcCeX6Ogwa0wTonkp18/tqsh" + + "Fj1fVpnsRmjJTTXFxkPtUw5GPJnDAM0t1xqV7kOjN76XnZrMyk2azQ1Mf3Hn" + + "sGpF+VRGH6JtxbM0Jm5zD9uHcmkSfNR3tP/+vHOB1mkIR9tD2cHvBg7pAlPD" + + "RfDVWynhS+UBNlQ0SEM/pgR7PytRSUoKc/hhe3N8VerF7VL3BwWfBLlZFYZH" + + "FvPQg4coxF7+We7nrSQfXvdVBP9Zf0PTdf3pbZelGCPVjOzbzY/o/cB23IwC" + + "ONxlY8SC1nJDXrPZ5sY51cg/qUqor056YqipRlI6I+FoTMmMDKPAiV1V5ibo" + + "DNQJkyv/CAbTX4+oFlxgddTwYcPZgd/GoGjiP9yBHHdRISatHwMcM06CzXJS" + + "s3MhzXWD4aNxvvSpXAngDLdlB7cm4ja2klmMzL7IuxzLXFQFFvYf7IF5I1pC" + + "YZOmTlJgp0efL9bHjuHFnh0S0lPtlGDOjJ/4YpWvSKDplcPiXhaFVjsUtclE" + + "oxCC5xppRm8QWS8xggEtMA0GCSsGAQQBgjcRAjEAMBMGCSqGSIb3DQEJFTEG" + + "BAQBAAAAMGkGCSsGAQQBgjcRATFcHloATQBpAGMAcgBvAHMAbwBmAHQAIABS" + + "AFMAQQAgAFMAQwBoAGEAbgBuAGUAbAAgAEMAcgB5AHAAdABvAGcAcgBhAHAA" + + "aABpAGMAIABQAHIAbwB2AGkAZABlAHIwgZsGCSqGSIb3DQEJFDGBjR6BigA3" + + "AGQAZQBmADUAYgA0ADMANgBjAGEAYgBkADAAMAAyAGQAZAAyADkAMAAzAGIA" + + "MQA2ADgANgBjADcAOQA0ADgAXwA0ADYAZgAyADYAZgBkADQALQA4ADEAMgBk" + + "AC0ANABlAGYAYgAtADgAMAA4ADgALQA0ADUAYQBiADkAMQA5ADEAMAA3AGMA" + + "YzCCCn8GCSqGSIb3DQEHBqCCCnAwggpsAgEAMIIKZQYJKoZIhvcNAQcBMBwG" + + "CiqGSIb3DQEMAQYwDgQIbr2xdnQ9inMCAgfQgIIKOHg9VKz+jlM+3abi3cp6" + + "/XMathxDSEJLrxJs6j5DAVX17S4sw1Q/1pptjdMdd8QtTfUB6JpfgJ5Kpn+h" + + "gZMf6M8wWue0U/RZN0D9w7o+2n+X3ItdEXu80eJVDOm7I2p8qiXtijbMbXRL" + + "Cup1lgfPM5uv2D63/hmWRXLeG8eySrJnKENngpM559V8TI2JcTUBy1ZP3kcH" + + "KbcJ/tVPnIIe4qguxfsTmDtAQviGvWUohbt+RGFmtqfgntK7o6b+S8uRSwEs" + + "fOU/pnVE9M1ugtNJZI/xeGJq6umZWXA/OrAcK7feWUwqRvfivDGQJEoggByd" + + "4/g92PhK1JGkwlCb1HdfhOOKKChowQ4zVvSOm+uBxARGhk2i5uW9I20I0vSJ" + + "px42O2VFVJweOchfp+wBtSHBKYP1ZXyXWMvOtULClosSeesbYMAwvyBfpYEz" + + "3rQt/1iZkqDmEisXk8X1aEKG1KSWaSPyb/+6glWikDm+YdQw3Khu7IZt1l/H" + + "qWGecccel+R9mT4YjRzHlahUYk4U+RNVasVpH1Kxz2j3CZqL+b3jQOwSAPd/" + + "hKI+S/pjIpBPfiC4WxORAzGZzY2j+a79B70h1DO1D9jGur3vJDbdmGBNgs6d" + + "nonE1B527SICcGeXY1MtnZCLOPvySih0AvOekbN9x2CJg+Hp9e7A3Fxni53/" + + "oMLr9wGRRDki72eXCXW98mU8VJofoWYS1/VBLXGf/f+tJ9J02PpzxleqPH9T" + + "4mE+YHnZId6cqjCXmwvMr2cMw2clDVfvkbAJRE3eZHzL7IWSO8+giXzzrTsl" + + "VbMuXVkT4oniTN7TSRsBCT3zVVmCy1QL2hPBD6KsVc+bvLgAHRov84FPrI3f" + + "kY/oJufT36VE34Eu+QjzULlvVsLE3lhjutOerVIGSP//FM4LE99hp214P0JF" + + "DgBK+3J+ihmFdW8hUXOt6BU8/MBeiroiJMWo1/f/XcduekG2ZsdGv+GNPzXI" + + "PyHRpCgAgmck1+qoUPXxHRJuNqv223OZ5MN14X7iLl5OZ+f8IWfxUnZeZ9gj" + + "HNeceElwZ+YOup1CAi3haD9jxRWhZG4NDfB4IYi4Bc/TAkXE3jCPkYEvIbj9" + + "ExaU1Ts0+lqOOcwRmBoYjVrz0xbtfR/OWlopyrDHbeL5iQcQCW/loYRapWCZ" + + "E4ekHknpX9yoAwT355vtTkl0VKXeSZHE8jREhN95aY9zCoLYwbTQDTw7qUR5" + + "UamabLew0oS0XALtuOrfX4OUOZZUstUsGBle/Pw1TE3Bhe1clhrikp0F+Xgb" + + "Xx90KqxZX/36RMnCMAD7/q+57rV7WXp2Y5tT0AUgyUMjy1F1X/b1olUfqO1u" + + "rlWIUTl2znmQ3D9uO3W4ytfgGd5DpKcl2w84MBAT9qGwKuQg/UYKbP4K/+4L" + + "Y1DWCy3utmohQ28IJtlIUkPL1G7lHX1tfq/VA+bRNTJIhMrNn06ZJpuEJHDs" + + "/ferdlMFt/d6MrwVivmPVYkb8mSbHSiI8jZOFE44sA974depsDyXafFaSsl0" + + "bVzqOAu0C/n9dIednU0xxxgDF/djdZ/QhbaDIg2VJf11wx0nw9n76B0+eeyu" + + "QLaapzxCpQNDVOAM9doBb5F1I5pXQHFQqzTNtLmqDC4x0g8IH7asyk5LCglT" + + "b1pwMqPJOL2vGWKRLhPzT+9OfSpCmYGKytf593hmGmwIgEO13hQrw31F5TYt" + + "btkbDr+Q5XilOKEczhEM+Ug7YHU7bxkckOAbxu0YeRp/57GdGLokeLJ0dRlQ" + + "+V2CfQvWJoVC6PS4PUQtjwgK2p/LU10QsEFwM/S621fGq9zGrv7+FPBATRDb" + + "k4E9D/WaRylnW11ZTrOlTchQkoHcOh0xztlFxU8jzuIuDrPQQWkoqdl6B+yf" + + "lykRNJKKxwzFiPl40nLC3nEdIzCEvR4r/9QHiWQxAVSc/wQX+an5vakUmSXS" + + "oLFjgVdY1jmvdsx2r5BQPuOR8ONGmw/muvVSMaHV85brA4uk0lxn00HD9/a0" + + "A1LCeFkabNLn9wJT8RaJeOSNmFFllLR70OHaoPSb3GyzHpvd1e6aeaimdyVH" + + "BQWJ6Ufx+HjbOGuOiN46WyE6Q27dnWxx8qF89dKB4T/J0mEXqueiUjAUnnnR" + + "Cs4zPaX53hmNBdrZGaLs+xNG8xy+iyBUJIWWfQAQjCjfHYlT9nygiUWIbVQq" + + "RHkGkAN62jsSNLgHvWVzQPNNsYq0U8TPhyyci/vc8MJytujjptcz8FPqUjg2" + + "TPv34ef9buErsm4vsdEv/8Z+9aDaNex+O3Lo3N0Aw7M5NcntFBHjFY/nBFNZ" + + "whH5YA4gQ8PLZ5qshlGvb0DFXHV/9zxnsdPkLwH47ERm5IlEAuoaWtZFxg27" + + "BjLfwU1Opk+ybDSb5WZVZrs7ljsU85p3Vaf3a//yoyr9ITYj15tTXxSPoct0" + + "fDUy1I6LjJH/+eZXKA1WSda9mDQlRocvJ0IIIlI4weJpTdm8aHIJ8OngCqOF" + + "TufcSLDM41+nxEK1LqXeAScVy74kVvvqngj6mIrbylrINZOHheEgTXrUWEc0" + + "uXS8l1YqY6K6Ru5km2jVyWi/ujrDGb6QGShC09oiDYUuUGy4gwJ3XLVX/dR3" + + "pmMExohTGiVefFP400wVZaxB9g1BQmjSEZxIaW1U1K6fk8Yni8yWB3/L/PuD" + + "0+OV+98i1sQGaPe35crIpEc7R2XJdngL0Ol1ZuvCIBfy5DQwGIawTtBnjPdi" + + "hy//QTt/isdu7C5pGaJDkZFMrfxMibr6c3xXr7wwR75sTzPNmS8mquEdLsmG" + + "h8gTUnB8/K6V11JtUExMqTimTbUw+j8PggpeBelG36breWJIz1O+dmCTGuLM" + + "x/sK/i8eiUeRvWjqYpq5DYt4URWg2WlcpcKiUxQp07/NMx0svDC+mlQGwMnJ" + + "8KOJMW1qr3TGEJ/VVKKVn6sXn/RxA+VPofYzhwZByRX87XmNdPeQKC2DHQsW" + + "6v83dua5gcnv0cv/smXt7Yr/c12i0fbIaQvj3qjtUCDucjARoBey3eCyG5H6" + + "5VHSsFnPZ2HCTum+jRSw/ENsu/77XU4BIM2fjAfswp7iIr2Xi4OZWKIj6o6q" + + "+fNgnOJjemDYHAFK+hWxClrG8b+9Eaf21o4zcHkhCfBlYv4d+xcZOIDsDPwI" + + "sf+4V+CfoBLALsa2K0pXlPplGom/a8h7CjlyaICbWpEDItqwu7NQwdMRCa7i" + + "yAyM1sVjXUdcZByS1bjOFSeBe7ygAvEl78vApLxqt8Cw11XSsOtmwssecUN/" + + "pb7iHE4OMyOgsYx9u7rZ2hMyl42n3c29IwDYMumiNqk9cwCBpQTJAQEv4VzO" + + "QE5xYDBY9SEozni+4f7B7e2Wj/LOGb3vfNVYGNpDczBFxvr2FXTQla0lNYD/" + + "aePuC++QW4KvwiGL1Zx4Jo0eoDKWYlYj0qiNlQbWfVw+raaaFnlrq+je0W6P" + + "+BrKZCncho145y+CFKRLZrN5yl/cDxwsePMVhAIMr1DzVhgBXzA3MB8wBwYF" + + "Kw4DAhoEFN4Cwj9AtArnRbOIAsRhaaoZlTNJBBTIVPqCrloqLns145CWXjb0" + + "g141BQ=="); + + static char[] storagePassword = "pass".toCharArray(); byte[] pkcs12nopass = Base64.decode( "MIIMvgIBAzCCDIQGCSqGSIb3DQEHAaCCDHUEggxxMIIMbTCCCS8GCSqGSIb3" - + "DQEHBqCCCSAwggkcAgEAMIIJFQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYw" - + "DgQIfnlhuZRR6/YCAggAgIII6DYgeRwq5n9kzvohZ3JuK+fB+9jZ7Or6EGBA" - + "GDxtBfHmSNUBWJEV/I8wV1zrKKoW/CaoZfA61pyrVZRd/roaqBx/koTFoh/g" - + "woyyWTRV9gYTXSVqPQgCH+e2dISAa6UGO+/YOWOOwG2X3t8tS+3FduFQFLt5" - + "cvUP98zENdm57Aef5pKpBSZDLIAoTASfmqwszWABRh2p/wKOHcCQ9Aj2e2vs" - + "pls/ntIv81MqPuxHttwX8e+3dKWGFrJRztLpCD2aua8VkSsHFsPxEHkezX4O" - + "6/VCjMCRFGophTS4dgKKtQIhZ9i/ESlr6sGKgIpyG99ALFpNEhtTKe+T3boE" - + "sEkhGDquSpu4PGz2m0W5sej1DyFkKX4zIbeMDAb1y3O7aP0F+Llo9QSeGsOA" - + "aCwND3NUAKBMOHzwdyNQcuCGCqY8j5rrSt99A5FMs3UVW3XU6hRCx7JlzO05" - + "PNCkcPRSnKSNzBhIR5W0qj4PAZnQTfX+wbtUaDLIqsObX4Muh2l3gl+JmdpO" - + "53U7ILqN8PAPly1eT+fIrUmlMmFhvo6LbTB7B2K728wsA/5wROlud/mOQz4s" - + "quS288YsnVc9ExSZKodWa3Pqcdb/cgKNJYDxrR6/eBHOj+0RLK/1yTK9ghj7" - + "IPYHoEqQbw768WK92RjM+RFGlXASkQhR9y4weWj/388uAWMIbQ+R2Zi4nb31" - + "knjqRPFThysG1bsRL04/9PgysaasfS9KYOeAlLqp+Ar4gJrof5fytBuY+6wm" - + "/J8eEdNw7VPV1cz/4rhrd2sfJQwDEN/iZoy8rTwe7wozpwZI0lwH11BBbav+" - + "1AMfI79jjxhqOeo7uxE2NzUmSd05JYI7a94tcRzGQyGEKpGxYCRamzFW23qb" - + "vG5Hcqi7Tdd7eTxw4c60l/vQLSo38g6ST5yZrK3URLiAtpioPyjrq2jnVfie" - + "QLsiAHhpHF01+t+OcKv3UjwdEyBmQ34h9klwiG7iwBFXZaPXFCF2Np1TqFVG" - + "jjBzmB+hRddEiYwN+XGCKB2Cvgc5ZMQ8LG9jQmEKLmOjuumz1ciAVY2qtl1s" - + "HYSvfNsIAV/gGzHshOVF19JmGtcQt3pMtupoRh+sh8jY2/x5eIKrj2Jx6HPd" - + "p/6IPUr54j0xSd6j7gWuXMj/eKp/utMNuBzAhkydnhXYedvTDYIj7SyPPIHa" - + "qtam8rxTDWn2AOxp7OXTgPmo1GU2zW1OLL1D3MFlS+oaRMfhgNrhW+QP5ay6" - + "ge4QLijpnSM+p0CbFAOClwzgdJV56bBVV09sDqSBXnG9MeEv5nDaH3I+GpPA" - + "UgDkaI4zT61kaGgk0uNMf3czy2ycoQzTx0iHDTXSdSqvUC1yFza8UG4AYaKz" - + "14gtSL7StvZtK0Y8oI084BINI1LgrWyrOLj7vkds4WrKhXm21BtM1GbN/pFh" - + "XI41h+XoD8KnEPqJ36rAgBo1uHqTNJCC7YikDE/dEvq6MkOx+Nug1YZRHEyi" - + "3AHry5u1HJHtxT34HXBwRXvnstuFhvU6cjc1WY1dJhu1p82TGnx7OBo/QbcM" - + "8MRrWmWuU5eW4jWbriGNGYfvZy+tHnGwy0bIeqrsHOG6/JwvfmYYXe64sryH" - + "5Qo96SZtcTJZaNFwuBY+bFUuOWm8YrT1L7Gl2Muf3pEVtNHLeYARBo1jEAym" - + "Cb4jw0oodZqbPKdyyzUZu69fdTJiQkMUcKDfHJEGK0Li9SvtdqJLiiJs57Tb" - + "YfOvn+TIuC40ssJFtmtlGCVH/0vtKLWYeW1NYAMzgI/nlhQ7W6Aroh8sZnqv" - + "SwxeQmRJaVLxiV6YveTKuVlCbqNVLeEtKYAujgnJtPemGCPbwZpwlBw6V+Dz" - + "oXveOBcUqATztWJeNv7RbU0Mk7k057+DNxXBIU+eHRGquyHQSBXxBbA+OFuu" - + "4SPfEAyoYed0HEaoKN9lIsBW1xTROI30MZvaJXvPdLsa8izXGPLnTGmoI+fv" - + "tJ644HtBCCCr3Reu82ZsTSDMxspZ9aa4ro9Oza+R5eULXDhVXedbhJBYiPPo" - + "J37El5lRqOgu2SEilhhVQq3ZCugsinCaY9P/RtWG4CFnH1IcIT5+/mivB48I" - + "2XfH6Xq6ziJdj2/r86mhEnz9sKunNvYPBDGlOvI7xucEf9AiEQoTR1xyFDbW" - + "ljL4BsJqgsHN02LyUzLwqMstwv+/JH1wUuXSK40Kik/N7+jEFW2C+/N8tN7l" - + "RPKSLaTjxVuTfdv/BH1dkV4iGFgpQrdWkWgkb+VZP9xE2mLz715eIAg13x6+" - + "n97tc9Hh375xZJqwr3QyYTXWpsK/vx04RThv8p0qMdqKvf3jVQWwnCnoeBv2" - + "L4h/uisOLY18qka/Y48ttympG+6DpmzXTwD1LycoG2SOWckCMmJhZK40+zr3" - + "NVmWf6iJtbLGMxI/kzTqbTaOfXc2MroertyM1rILRSpgnJFxJfai5Enspr9b" - + "SCwlP718jG2lQsnYlw8CuxoZAiaNy4MmC5Y3qNl3hlcggcHeLodyGkSyRsBg" - + "cEiKSL7JNvqr0X/nUeW28zVxkmQsWlp3KmST8agf+r+sQvw52fXNLdYznGZV" - + "rJrwgNOoRj0Z70MwTns3s/tCqDEsy5Sv/5dZW2uQEe7/wvmsP2WLu73Rwplg" - + "1dwi/Uo9lO9dkEzmoIK5wMPCDINxL1K+0Y79q0tIAEMDgaIxmtRpEh8/TEsA" - + "UwyEErkDsQqgGviH+ePmawJ/yehYHTRfYUgdUflwApJxRx65pDeSYkiYboMU" - + "8WSAQY2nh/p9hLlS4zbz9dCK2tzVyRkJgqNy/c4IpiHEx2l1iipW9vENglqx" - + "dYP4uqD8e3OOLjDQKizWx2t1u7GRwoEVQ3d3QzzOvsRcv7h+6vNsmYqE6phe" - + "wKFZLctpSn21zkyut444ij4sSr1OG68dEXLY0t0mATfTmXXy5GJBsdK/lLfk" - + "YTIPYYeDMle9aEicDqaKqkZUuYPnVchGp8UFMJ3M0n48OMDdDvpzBLTxxZeW" - + "cK5v/m3OEo3jgxy9wXfZdz//J3zXXqvX8LpMy1K9X0uCBTz6ERlawviMQhg1" - + "1okD5zCCAzYGCSqGSIb3DQEHAaCCAycEggMjMIIDHzCCAxsGCyqGSIb3DQEM" - + "CgECoIICpjCCAqIwHAYKKoZIhvcNAQwBAzAOBAj3QoojTSbZqgICCAAEggKA" - + "YOSp5XGdnG1pdm9CfvlAaUSHRCOyNLndoUTqteTZjHTEM9bGwNXAx4/R5H2Q" - + "PnPm5HB/ynVSXX0uKdW6YlbqUyAdV3eqE4X3Nl+K7ZoXmgAFnMr0tveBhT1b" - + "7rTi0TN4twjJzBTkKcxT8XKjvpVizUxGo+Ss5Wk8FrWLHAiC5dZvgRemtGcM" - + "w5S09Pwj+qXpjUhX1pB5/63qWPrjVf+Bfmlz4bWcqogGk0i7eg+OdTeWMrW0" - + "KR9nD1+/uNEyc4FdGtdIPnM+ax0E+vcco0ExQpTXe0xoX4JW7O71d550Wp89" - + "hAVPNrJA5eUbSWNsuz+38gjUJ+4XaAEhcA7HZIp6ZyxtzSJUoh7oqpRktoxu" - + "3cSVqVxIqAEqlNn6j0vbKfW91Od5DI5L+BIxY4xqXS7fdwipj9r6qWA8t9QU" - + "C2r1A+xXpZ4jEh6inHW9qlfACBBrYf8pSDakSR6yTbaA07LExw0IXz5oiQYt" - + "s7yx231CZlOH88bBmruLOIZsJjeg/lf63zI7Gg4F85QG3RqEJnY2pinLUTP7" - + "R62VErFZPc2a85r2dbFH1mSQIj/rT1IKe32zIW8xoHC4VwrPkT3bcLFAu2TH" - + "5k5zSI/gZUKjPDxb2dwLM4pvsj3gJ9vcFZp6BCuLkZc5rd7CyD8HK9PrBLKd" - + "H3Yngy4A08W4U3XUtIux95WE+5O/UEmSF7fr2vT//DwZArGUpBPq4Bikb8cv" - + "0wpOwUv8r0DXveeaPsxdipXlt29Ayywcs6KIidLtCaCX6/0u/XtMsGNFS+ah" - + "OlumTGBFpbLnagvIf0GKNhbg2lTjflACnxIj8d+QWsnrIU1uC1JRRKCnhpi2" - + "veeWd1m8GUb3aTFiMCMGCSqGSIb3DQEJFTEWBBS9g+Xmq/8B462FWFfaLWd/" - + "rlFxOTA7BgkqhkiG9w0BCRQxLh4sAEMAZQByAHQAeQBmAGkAawBhAHQAIAB1" - + "AHoAeQB0AGsAbwB3AG4AaQBrAGEwMTAhMAkGBSsOAwIaBQAEFKJpUOIj0OtI" - + "j2CPp38YIFBEqvjsBAi8G+yhJe3A/wICCAA="); + + "DQEHBqCCCSAwggkcAgEAMIIJFQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYw" + + "DgQIfnlhuZRR6/YCAggAgIII6DYgeRwq5n9kzvohZ3JuK+fB+9jZ7Or6EGBA" + + "GDxtBfHmSNUBWJEV/I8wV1zrKKoW/CaoZfA61pyrVZRd/roaqBx/koTFoh/g" + + "woyyWTRV9gYTXSVqPQgCH+e2dISAa6UGO+/YOWOOwG2X3t8tS+3FduFQFLt5" + + "cvUP98zENdm57Aef5pKpBSZDLIAoTASfmqwszWABRh2p/wKOHcCQ9Aj2e2vs" + + "pls/ntIv81MqPuxHttwX8e+3dKWGFrJRztLpCD2aua8VkSsHFsPxEHkezX4O" + + "6/VCjMCRFGophTS4dgKKtQIhZ9i/ESlr6sGKgIpyG99ALFpNEhtTKe+T3boE" + + "sEkhGDquSpu4PGz2m0W5sej1DyFkKX4zIbeMDAb1y3O7aP0F+Llo9QSeGsOA" + + "aCwND3NUAKBMOHzwdyNQcuCGCqY8j5rrSt99A5FMs3UVW3XU6hRCx7JlzO05" + + "PNCkcPRSnKSNzBhIR5W0qj4PAZnQTfX+wbtUaDLIqsObX4Muh2l3gl+JmdpO" + + "53U7ILqN8PAPly1eT+fIrUmlMmFhvo6LbTB7B2K728wsA/5wROlud/mOQz4s" + + "quS288YsnVc9ExSZKodWa3Pqcdb/cgKNJYDxrR6/eBHOj+0RLK/1yTK9ghj7" + + "IPYHoEqQbw768WK92RjM+RFGlXASkQhR9y4weWj/388uAWMIbQ+R2Zi4nb31" + + "knjqRPFThysG1bsRL04/9PgysaasfS9KYOeAlLqp+Ar4gJrof5fytBuY+6wm" + + "/J8eEdNw7VPV1cz/4rhrd2sfJQwDEN/iZoy8rTwe7wozpwZI0lwH11BBbav+" + + "1AMfI79jjxhqOeo7uxE2NzUmSd05JYI7a94tcRzGQyGEKpGxYCRamzFW23qb" + + "vG5Hcqi7Tdd7eTxw4c60l/vQLSo38g6ST5yZrK3URLiAtpioPyjrq2jnVfie" + + "QLsiAHhpHF01+t+OcKv3UjwdEyBmQ34h9klwiG7iwBFXZaPXFCF2Np1TqFVG" + + "jjBzmB+hRddEiYwN+XGCKB2Cvgc5ZMQ8LG9jQmEKLmOjuumz1ciAVY2qtl1s" + + "HYSvfNsIAV/gGzHshOVF19JmGtcQt3pMtupoRh+sh8jY2/x5eIKrj2Jx6HPd" + + "p/6IPUr54j0xSd6j7gWuXMj/eKp/utMNuBzAhkydnhXYedvTDYIj7SyPPIHa" + + "qtam8rxTDWn2AOxp7OXTgPmo1GU2zW1OLL1D3MFlS+oaRMfhgNrhW+QP5ay6" + + "ge4QLijpnSM+p0CbFAOClwzgdJV56bBVV09sDqSBXnG9MeEv5nDaH3I+GpPA" + + "UgDkaI4zT61kaGgk0uNMf3czy2ycoQzTx0iHDTXSdSqvUC1yFza8UG4AYaKz" + + "14gtSL7StvZtK0Y8oI084BINI1LgrWyrOLj7vkds4WrKhXm21BtM1GbN/pFh" + + "XI41h+XoD8KnEPqJ36rAgBo1uHqTNJCC7YikDE/dEvq6MkOx+Nug1YZRHEyi" + + "3AHry5u1HJHtxT34HXBwRXvnstuFhvU6cjc1WY1dJhu1p82TGnx7OBo/QbcM" + + "8MRrWmWuU5eW4jWbriGNGYfvZy+tHnGwy0bIeqrsHOG6/JwvfmYYXe64sryH" + + "5Qo96SZtcTJZaNFwuBY+bFUuOWm8YrT1L7Gl2Muf3pEVtNHLeYARBo1jEAym" + + "Cb4jw0oodZqbPKdyyzUZu69fdTJiQkMUcKDfHJEGK0Li9SvtdqJLiiJs57Tb" + + "YfOvn+TIuC40ssJFtmtlGCVH/0vtKLWYeW1NYAMzgI/nlhQ7W6Aroh8sZnqv" + + "SwxeQmRJaVLxiV6YveTKuVlCbqNVLeEtKYAujgnJtPemGCPbwZpwlBw6V+Dz" + + "oXveOBcUqATztWJeNv7RbU0Mk7k057+DNxXBIU+eHRGquyHQSBXxBbA+OFuu" + + "4SPfEAyoYed0HEaoKN9lIsBW1xTROI30MZvaJXvPdLsa8izXGPLnTGmoI+fv" + + "tJ644HtBCCCr3Reu82ZsTSDMxspZ9aa4ro9Oza+R5eULXDhVXedbhJBYiPPo" + + "J37El5lRqOgu2SEilhhVQq3ZCugsinCaY9P/RtWG4CFnH1IcIT5+/mivB48I" + + "2XfH6Xq6ziJdj2/r86mhEnz9sKunNvYPBDGlOvI7xucEf9AiEQoTR1xyFDbW" + + "ljL4BsJqgsHN02LyUzLwqMstwv+/JH1wUuXSK40Kik/N7+jEFW2C+/N8tN7l" + + "RPKSLaTjxVuTfdv/BH1dkV4iGFgpQrdWkWgkb+VZP9xE2mLz715eIAg13x6+" + + "n97tc9Hh375xZJqwr3QyYTXWpsK/vx04RThv8p0qMdqKvf3jVQWwnCnoeBv2" + + "L4h/uisOLY18qka/Y48ttympG+6DpmzXTwD1LycoG2SOWckCMmJhZK40+zr3" + + "NVmWf6iJtbLGMxI/kzTqbTaOfXc2MroertyM1rILRSpgnJFxJfai5Enspr9b" + + "SCwlP718jG2lQsnYlw8CuxoZAiaNy4MmC5Y3qNl3hlcggcHeLodyGkSyRsBg" + + "cEiKSL7JNvqr0X/nUeW28zVxkmQsWlp3KmST8agf+r+sQvw52fXNLdYznGZV" + + "rJrwgNOoRj0Z70MwTns3s/tCqDEsy5Sv/5dZW2uQEe7/wvmsP2WLu73Rwplg" + + "1dwi/Uo9lO9dkEzmoIK5wMPCDINxL1K+0Y79q0tIAEMDgaIxmtRpEh8/TEsA" + + "UwyEErkDsQqgGviH+ePmawJ/yehYHTRfYUgdUflwApJxRx65pDeSYkiYboMU" + + "8WSAQY2nh/p9hLlS4zbz9dCK2tzVyRkJgqNy/c4IpiHEx2l1iipW9vENglqx" + + "dYP4uqD8e3OOLjDQKizWx2t1u7GRwoEVQ3d3QzzOvsRcv7h+6vNsmYqE6phe" + + "wKFZLctpSn21zkyut444ij4sSr1OG68dEXLY0t0mATfTmXXy5GJBsdK/lLfk" + + "YTIPYYeDMle9aEicDqaKqkZUuYPnVchGp8UFMJ3M0n48OMDdDvpzBLTxxZeW" + + "cK5v/m3OEo3jgxy9wXfZdz//J3zXXqvX8LpMy1K9X0uCBTz6ERlawviMQhg1" + + "1okD5zCCAzYGCSqGSIb3DQEHAaCCAycEggMjMIIDHzCCAxsGCyqGSIb3DQEM" + + "CgECoIICpjCCAqIwHAYKKoZIhvcNAQwBAzAOBAj3QoojTSbZqgICCAAEggKA" + + "YOSp5XGdnG1pdm9CfvlAaUSHRCOyNLndoUTqteTZjHTEM9bGwNXAx4/R5H2Q" + + "PnPm5HB/ynVSXX0uKdW6YlbqUyAdV3eqE4X3Nl+K7ZoXmgAFnMr0tveBhT1b" + + "7rTi0TN4twjJzBTkKcxT8XKjvpVizUxGo+Ss5Wk8FrWLHAiC5dZvgRemtGcM" + + "w5S09Pwj+qXpjUhX1pB5/63qWPrjVf+Bfmlz4bWcqogGk0i7eg+OdTeWMrW0" + + "KR9nD1+/uNEyc4FdGtdIPnM+ax0E+vcco0ExQpTXe0xoX4JW7O71d550Wp89" + + "hAVPNrJA5eUbSWNsuz+38gjUJ+4XaAEhcA7HZIp6ZyxtzSJUoh7oqpRktoxu" + + "3cSVqVxIqAEqlNn6j0vbKfW91Od5DI5L+BIxY4xqXS7fdwipj9r6qWA8t9QU" + + "C2r1A+xXpZ4jEh6inHW9qlfACBBrYf8pSDakSR6yTbaA07LExw0IXz5oiQYt" + + "s7yx231CZlOH88bBmruLOIZsJjeg/lf63zI7Gg4F85QG3RqEJnY2pinLUTP7" + + "R62VErFZPc2a85r2dbFH1mSQIj/rT1IKe32zIW8xoHC4VwrPkT3bcLFAu2TH" + + "5k5zSI/gZUKjPDxb2dwLM4pvsj3gJ9vcFZp6BCuLkZc5rd7CyD8HK9PrBLKd" + + "H3Yngy4A08W4U3XUtIux95WE+5O/UEmSF7fr2vT//DwZArGUpBPq4Bikb8cv" + + "0wpOwUv8r0DXveeaPsxdipXlt29Ayywcs6KIidLtCaCX6/0u/XtMsGNFS+ah" + + "OlumTGBFpbLnagvIf0GKNhbg2lTjflACnxIj8d+QWsnrIU1uC1JRRKCnhpi2" + + "veeWd1m8GUb3aTFiMCMGCSqGSIb3DQEJFTEWBBS9g+Xmq/8B462FWFfaLWd/" + + "rlFxOTA7BgkqhkiG9w0BCRQxLh4sAEMAZQByAHQAeQBmAGkAawBhAHQAIAB1" + + "AHoAeQB0AGsAbwB3AG4AaQBrAGEwMTAhMAkGBSsOAwIaBQAEFKJpUOIj0OtI" + + "j2CPp38YIFBEqvjsBAi8G+yhJe3A/wICCAA="); private byte[] gostPfx = Base64.decode( "MIIHEgIBAzCCBssGCSqGSIb3DQEHAaCCBrwEgga4MIIGtDCCBYEGCSqGSIb3" - + "DQEHBqCCBXIwggVuAgEAMIIFZwYJKoZIhvcNAQcBMFUGCSqGSIb3DQEFDTBI" - + "MCcGCSqGSIb3DQEFDDAaBAi114+lRrpkXAICCAAwCgYGKoUDAgIKBQAwHQYG" - + "KoUDAgIVMBMECLEIQPMsz/ZZBgcqhQMCAh8BgIIFAbu13yJiW/BnSKYKbtv9" - + "tDJoTv6l9BVpCCI4tvpzJnMeLBJyVZU4JevcJNii+R1LilVuuB+xc8e7/P4G" - + "6TILWmnnispr9KPRAbYRfoCJOa59+TYJMur58wwDuYgMapQAFzsvpzyUWi62" - + "o3uQbbLKO9hQCeJW2L+K9cbg8k33MjXMLpnblKpqmZbHTmBJDFR3xGw7IEjD" - + "UNqruu7DlHY6jctiVJSii9UNEVetSo9AAzfROxRjROg38VsWxLyO9wEMBv/8" - + "H8ur+zOtmQPGqirNXmN+pa08OvZin9kh7CgswW03xIbfsdGGGLRAWtvCnEwJ" - + "mS2tEfH1SZcuVLpMomhq3FU/jsc12k+vq/jw4I2cmfDL41ieK72bwNj8xUXu" - + "JHeoFSPGX4z+nsJUrFbFG4VBuDs2Y0SCWLyYZvdjvJwYjfqtyi/RoFSZjGHF" - + "crstf9YNQ0vW0efCJ7pUBH44OrbnCx5ng2U5jFm1b3HBIKA2RX+Tlhv14MgT" - + "KSftPZ67eSmgdsyPuQAdMu6fEdBMpVKMNZNRV565690sqi+1jOmH94TUX8XU" - + "2pRQj6eGGLq6lgGnnDabcePUEPXW8zW2KYrDKYJ/1QZmVGldvlqnjZMNhIO+" - + "Afsqax/P8RBjMduGqdilGdRzbN8PdhVaN0Ys+WzFxiS9gtaA2yPzcQuedWDN" - + "T7sIrfIapgFYmmHRQ7ht4AKj+lmOyNadONYw+ww+8RzHB1d2Kk+iXeZCtvH0" - + "XFWJZtuoGKSt/gkI0E2vpDfMbLaczaRC7ityO0iJs25ozP4JhZRBVvOmpxc9" - + "YuIetbTnTf1TLJKXDgt1IwPZeugbofSeiNv117lx8VgtvMYFD4W+WQlB8HnO" - + "C8NOYjkMPElc6PCMB9gGm0cIu1fKLvY8ycLav93JJjdDuC0kgKLb2+8mC5+2" - + "DdMkcfgW6hy4c98xnJs8enCww3A4xkRbMU13zMq70liqmKHV2SSurg5hwUHM" - + "ZthT8p988ZBrnqW24lXfMBqTK4YtIBMeMnvKocYBXr96ig3GfahI1Aj2Bw2e" - + "bpZTVeayYUd+2xX8JJMdqna6Q61AL8/eUhJUETz5+fgQJtPjcKmdJfVHO6nB" - + "vOk1t/rjK17eiXLxHCyvfP+Tw8lSFOhcvr4eIeG8WfsWNRu2eKKosOU7uash" - + "QpnvQieqDeijuRxf+tbbJ5D86inwbJqdxra7wNuZXmiaB9gFDzNbNjhtL+6i" - + "gUyX/iQHKi9bNK+PH6pdH/gkwnG/juhdgqoNY6GRty/LUOPgXD+r5e/ST16R" - + "vnlwrlKp5FzRWBEkem+dhelj3rb+cxKEyvPe3TvIUFcmIlV1VCRQ1fBHtX18" - + "eC3a3GprH8c40z3S/kdyk7GlFQ27DRLka+iDN05b+MP5jlgvfqYBKxwLfeNu" - + "MpxWoCUvYWiQdMih86/l0H+0o5UB8SqRbpuvr6fY910JCk0hDaO1pgB3HlRz" - + "k1vb46pg25heXQm3JmO+ghxjOGliYBWjl8p7AfRS9cjS8ca+X02Mv9Viv7Ce" - + "3+Gz0MVwfK98viJ3CFxkaEBlM2LM0IeUQbkHG+YwYaTSfl4GYyrug4F0ZdrA" - + "KeY9/kIxa/OJxjcIMs2H+2mSpxmrb7ylmHZ2RB8ITiduRVtO091hn/J7N+eT" - + "h6BvLBKIFU+UFUdgjxoDNDk7ao++Mu9T3dQfceFBOYzW9vMQgX30yaPLSdan" - + "ZMAP0VtiNjCCASsGCSqGSIb3DQEHAaCCARwEggEYMIIBFDCCARAGCyqGSIb3" - + "DQEMCgECoIGyMIGvMFUGCSqGSIb3DQEFDTBIMCcGCSqGSIb3DQEFDDAaBAiQ" - + "Owewo16xzQICCAAwCgYGKoUDAgIKBQAwHQYGKoUDAgIVMBMECHSCNJJcQ2VI" - + "BgcqhQMCAh8BBFYCyRRpFtZgnsxeK7ZHT+aOyoVmzhtnLrqoBHgV4nJJW2/e" - + "UcJjc2Rlbzfd+3L/GWcRGF8Bgn+MjiaAqE64Rzaao9t2hc3myw1WrCfPnoEx" - + "VI7OPBM5FzFMMCMGCSqGSIb3DQEJFTEWBBTV7LvI27QWRmHD45X2WKXYs3ct" - + "AzAlBgkqhkiG9w0BCRQxGB4WAGMAcABfAGUAeABwAG8AcgB0AGUAZDA+MC4w" - + "CgYGKoUDAgIJBQAEIJbGZorQsNM63+xozwEI561cTFVCbyHAEEpkvF3eijT8" - + "BAgY5sDtkrVeBQICCAA="); + + "DQEHBqCCBXIwggVuAgEAMIIFZwYJKoZIhvcNAQcBMFUGCSqGSIb3DQEFDTBI" + + "MCcGCSqGSIb3DQEFDDAaBAi114+lRrpkXAICCAAwCgYGKoUDAgIKBQAwHQYG" + + "KoUDAgIVMBMECLEIQPMsz/ZZBgcqhQMCAh8BgIIFAbu13yJiW/BnSKYKbtv9" + + "tDJoTv6l9BVpCCI4tvpzJnMeLBJyVZU4JevcJNii+R1LilVuuB+xc8e7/P4G" + + "6TILWmnnispr9KPRAbYRfoCJOa59+TYJMur58wwDuYgMapQAFzsvpzyUWi62" + + "o3uQbbLKO9hQCeJW2L+K9cbg8k33MjXMLpnblKpqmZbHTmBJDFR3xGw7IEjD" + + "UNqruu7DlHY6jctiVJSii9UNEVetSo9AAzfROxRjROg38VsWxLyO9wEMBv/8" + + "H8ur+zOtmQPGqirNXmN+pa08OvZin9kh7CgswW03xIbfsdGGGLRAWtvCnEwJ" + + "mS2tEfH1SZcuVLpMomhq3FU/jsc12k+vq/jw4I2cmfDL41ieK72bwNj8xUXu" + + "JHeoFSPGX4z+nsJUrFbFG4VBuDs2Y0SCWLyYZvdjvJwYjfqtyi/RoFSZjGHF" + + "crstf9YNQ0vW0efCJ7pUBH44OrbnCx5ng2U5jFm1b3HBIKA2RX+Tlhv14MgT" + + "KSftPZ67eSmgdsyPuQAdMu6fEdBMpVKMNZNRV565690sqi+1jOmH94TUX8XU" + + "2pRQj6eGGLq6lgGnnDabcePUEPXW8zW2KYrDKYJ/1QZmVGldvlqnjZMNhIO+" + + "Afsqax/P8RBjMduGqdilGdRzbN8PdhVaN0Ys+WzFxiS9gtaA2yPzcQuedWDN" + + "T7sIrfIapgFYmmHRQ7ht4AKj+lmOyNadONYw+ww+8RzHB1d2Kk+iXeZCtvH0" + + "XFWJZtuoGKSt/gkI0E2vpDfMbLaczaRC7ityO0iJs25ozP4JhZRBVvOmpxc9" + + "YuIetbTnTf1TLJKXDgt1IwPZeugbofSeiNv117lx8VgtvMYFD4W+WQlB8HnO" + + "C8NOYjkMPElc6PCMB9gGm0cIu1fKLvY8ycLav93JJjdDuC0kgKLb2+8mC5+2" + + "DdMkcfgW6hy4c98xnJs8enCww3A4xkRbMU13zMq70liqmKHV2SSurg5hwUHM" + + "ZthT8p988ZBrnqW24lXfMBqTK4YtIBMeMnvKocYBXr96ig3GfahI1Aj2Bw2e" + + "bpZTVeayYUd+2xX8JJMdqna6Q61AL8/eUhJUETz5+fgQJtPjcKmdJfVHO6nB" + + "vOk1t/rjK17eiXLxHCyvfP+Tw8lSFOhcvr4eIeG8WfsWNRu2eKKosOU7uash" + + "QpnvQieqDeijuRxf+tbbJ5D86inwbJqdxra7wNuZXmiaB9gFDzNbNjhtL+6i" + + "gUyX/iQHKi9bNK+PH6pdH/gkwnG/juhdgqoNY6GRty/LUOPgXD+r5e/ST16R" + + "vnlwrlKp5FzRWBEkem+dhelj3rb+cxKEyvPe3TvIUFcmIlV1VCRQ1fBHtX18" + + "eC3a3GprH8c40z3S/kdyk7GlFQ27DRLka+iDN05b+MP5jlgvfqYBKxwLfeNu" + + "MpxWoCUvYWiQdMih86/l0H+0o5UB8SqRbpuvr6fY910JCk0hDaO1pgB3HlRz" + + "k1vb46pg25heXQm3JmO+ghxjOGliYBWjl8p7AfRS9cjS8ca+X02Mv9Viv7Ce" + + "3+Gz0MVwfK98viJ3CFxkaEBlM2LM0IeUQbkHG+YwYaTSfl4GYyrug4F0ZdrA" + + "KeY9/kIxa/OJxjcIMs2H+2mSpxmrb7ylmHZ2RB8ITiduRVtO091hn/J7N+eT" + + "h6BvLBKIFU+UFUdgjxoDNDk7ao++Mu9T3dQfceFBOYzW9vMQgX30yaPLSdan" + + "ZMAP0VtiNjCCASsGCSqGSIb3DQEHAaCCARwEggEYMIIBFDCCARAGCyqGSIb3" + + "DQEMCgECoIGyMIGvMFUGCSqGSIb3DQEFDTBIMCcGCSqGSIb3DQEFDDAaBAiQ" + + "Owewo16xzQICCAAwCgYGKoUDAgIKBQAwHQYGKoUDAgIVMBMECHSCNJJcQ2VI" + + "BgcqhQMCAh8BBFYCyRRpFtZgnsxeK7ZHT+aOyoVmzhtnLrqoBHgV4nJJW2/e" + + "UcJjc2Rlbzfd+3L/GWcRGF8Bgn+MjiaAqE64Rzaao9t2hc3myw1WrCfPnoEx" + + "VI7OPBM5FzFMMCMGCSqGSIb3DQEJFTEWBBTV7LvI27QWRmHD45X2WKXYs3ct" + + "AzAlBgkqhkiG9w0BCRQxGB4WAGMAcABfAGUAeABwAG8AcgB0AGUAZDA+MC4w" + + "CgYGKoUDAgIJBQAEIJbGZorQsNM63+xozwEI561cTFVCbyHAEEpkvF3eijT8" + + "BAgY5sDtkrVeBQICCAA="); byte[] certChainCycle = Base64.decode( "MIIKEAIBAzCCCcoGCSqGSIb3DQEHAaCCCbsEggm3MIIJszCCAyAGCSqGSIb3" - + "DQEHAaCCAxEEggMNMIIDCTCCAwUGCyqGSIb3DQEMCgECoIICsjCCAq4wKAYK" - + "KoZIhvcNAQwBAzAaBBQesw38x26DXisTDrMMSoAanDOAQgICBAAEggKAja8F" - + "U82RAAxhc36SWNXgWGV4CDSbDLFjlJuuXLTelz77KcX4dqPOQdKakm3OVl96" - + "cbp6mWNSOoo0F8bh/Qu51vayt7hT5NIuI8jJ/Q1FYUffMKRxGt14JwuuTQ8W" - + "5DO3z7422fm/rUu+Nkd6y+Sr0Q3FAE8QH/vNc9aUwusVAihr0AZCdT0/HwxK" - + "AKAXLtMHeTWRpdq3WPSilPEWeeZI9Gk14uKbjEeQIUsa8IujSxTE43XwNRQN" - + "z3Qm4oMxGOZP+DPxuKnj+Ug1OXgX5x+GD2fbwytzss9Isv/Zq8wq0gO3t1Ru" - + "PjpxPt/MH2PxNLe4JJTxg1tIXfNP5ZU1SivcIjGLWWcEu+xADG9uq2eDBOja" - + "mW2ZQ1cInSQw8mKcBbX7aEl0NVadSMfxMZxIw0unmoNEETmScoGr50G4Ha5H" - + "ty1iJLNtI69MUA1c2DsoOqyzlnumTTLwuqsZ/E8rFLfO4sHncMxMRdmCEUjn" - + "N2ZOfRqMrgtSFfBsYQ5YjxJ6CI1DLAJwIJhvx8tZgyGItgiI8pSyG8xsRliI" - + "WPQzocO39zHK0hG6ERGnfJyll62/MlDNl9BqjobswPu97BV9nMtPIl3yVBPa" - + "sZxj5LUPYt5nmBlIjIkT5K4cEOIWHKCHPOnAsk8AGW/vrugBcTsyw9nAsRx+" - + "PbmOmmgyo0g2SiPsUX0fGQIWOBVZNxkGP/E4qgDOFS0YavxrdUd2Bgo9q9Sc" - + "hENPI9wjhPztR2UNLtBviWd8utQJ7NhX+6guWEE4AN6Th/xLb/pe9c0sIsEO" - + "41ViDbu4wDGUz6kw3fpXjIu7i6QKniWXEUL9uuchUgZD1GJHQLhD8xgdR6YQ" - + "5SwfIadoWTFAMBkGCSqGSIb3DQEJFDEMHgoAYwB5AGMAbABlMCMGCSqGSIb3" - + "DQEJFTEWBBRoHxEy+w9gB2sa3ykN2Ok7sb3AajCCBosGCSqGSIb3DQEHBqCC" - + "BnwwggZ4AgEAMIIGcQYJKoZIhvcNAQcBMCgGCiqGSIb3DQEMAQYwGgQU40Mi" - + "gMmdUNKyHyGi8miA/3bKZO0CAgQAgIIGOIk1Ouu1n1yoHWGM7YsLpB5fqK6D" - + "LbhUoxsshDSxqemUX3QDJQVmPC9wQOUp1BUapkfB3uxsM15uUG/EUAPlF3iW" - + "0MKDpmcKTC8y1WzMtgZBmmXwRUbguH2gmn4nd6lI2SkLWQg5boQ47aHjZLO2" - + "MZsH1b/DUoT4m6fSrgsMnIVh03z1Gs2XO+Ky3qXqQJM9T3VtCfmeIJBIM2eP" - + "YqvWfnvoGZZZA+pmqVUSMu6q0U7cDA5CD9zhZ87tZvaJeQ198fVIKpMUHBdf" - + "WRGY/opZh4YTfqn+ZiiysEa9jjjx4hSkxS2XGkyUfwPEx4/1E2AdIBfi3KKW" - + "BSyx8hurMyf89YsjxqJudfCAQI2GdWLDEXwwHMi1mM3wn5NVFzZUqM/u+t2W" - + "f3gJGfykxwECxrn4TmerRJ3znyn7soLPEyy6Pp+JPNLyen3Z8gva5tU7Y2J4" - + "aW6YGbBuQ9iW6QcMA93UtWBMGRAJL1jZ9WDguaTkvH8ffSj90jfu7iTHCm/P" - + "4EEtEV7D4ciyLc5xVyq7gIQnIIViVRifAHyjbazrIFQ2yXYwINAk0yNmDqxu" - + "8W4KNxkhNTGvQP/kkk+oDpSCa7XfxMpny+2BudjEryen2q3skMp3HjU/svHQ" - + "+4Y9kxZ5rVYII9S8TRFmgxiRO7cQCdNEwiZndQVGahjVbLI3Jp3vmQhLg+2l" - + "QF07yT7Q0nxeyhbpDGUEizUyIKzs9Or0DEHbq0StU3YwLgHGLlllARLm0eAO" - + "SVhuxKGATS6GtCb/0jmzV+kX4GrK1Qkmit3Xxt9Lbq9b2v2eSMANqGrGpYyr" - + "ETfJ5Ri/UL0nF7M9+tXrrZam1dEM5nJXR04rXQXjxxIuxsrz5xhvS/I+45RY" - + "VKN9l1yw80wNYJlE3Un/eUxT0szk6XA7eguhB6ULGTZNDUMZdELAtwPcq+E4" - + "4+0oih/XLzo/losH10RZ1bBf58mFVl/SlZ0CDE3x6GnFyH/tyTb6pR3Vre1v" - + "TcBod/rkTyEnkPlFSztbBfCXXIRUcSUcbVXge3Vqn7Orhq1+sb6MPcr88uhU" - + "c9Z6g6oKf1liIhiELpMZ5qG06hTwmMlE8prE0tdReGP/eaS2eCu8MyN70adT" - + "IfW1PAopoZTfDYKxJYdsJUVkUojZUvmJ21sNeNREPaFBbwncHBR/y19afhqE" - + "yyvyzDhDJ1D81TkFUR0OwGk7FvV/5JEQCyJq0wIty9G6mJRbUi2tjCc5WpP7" - + "edDW5PBS/rfJPTDMGLy80LlD+obCTFc0sSaBI+dag02Xmxe31V9c96VPOsFt" - + "GQ532OFwZU52E9zYLQSL8L2sdNlEK+OCvTd1MNVbH6PGBYgxrmoDfNBQlYBh" - + "yX2R9wFClraNUBBV9Dtebb6MSqPW7m8xZWAXCmXkDqR9A9kP6qTMd4X3gSFT" - + "qJaezTWbHH44PTgffpK5A1ZBQj37se82QWtBKNPU14KEVvXcI+uuM/TmoAJY" - + "0hqMeXK/1JfzhxTuJsJl+c45LuGjq9dLY9tgTSqMLeKOqal7sLH1AVs4BCCA" - + "J/sHN5pgOjQNLZ1Zup5mZHXR/ynIhKnpYDADOfnAXLizn/UZZFs5huYJYQEQ" - + "K7zcDuzPuxcmFVqUa4AyL9Ul1N42rBx3VsKZ+pvcBTQU5mWsaYwPFox4wLx0" - + "HITx7v7cFYsqki7IHfgnvpJlIS8hrvqqXHl75b61T7ZfJMJNQjhf29//OZ36" - + "QU4mj7lXwudAe+qAJbn1De5B54dQhtLA7B6sX7/7Sy6xP42QJqXhlWngbhF1" - + "IsrgZZrFPJ7zeaKnjOfrLWr8bs1nthHNNoL4cqlPuYtliUGy5zxj9bpQH8xj" - + "oh8+PjTOT4H57IvUN/US/6R0awy8WafJ211diVjbU2IbjS/P+xa6Xlbaql4Z" - + "KlvXRmoMZNl6xPbJg4x6t2anadNmuS7TXHqfTpp+UxeSsr1phyPmxQZPujZY" - + "BADnjfNhTRi7esePheR/DPaPLwjllhetm+U7s7EZzMCdEcd5RB/jiceqRQ5b" - + "xoqSyvIW1ZcdTzRQEAFAhnMWRdVT0O0KYDATiSVqcBr0b70dIQ0lZvYk/TUy" - + "FdYhRXqC8Gzh8xQZPr3CBGoB02pWpp0Hbb5bHtpf3VnfsEmfwBtRPaEUMD0w" - + "ITAJBgUrDgMCGgUABBSsUQPThQeWi8r3oQZ22tcQW2dDqgQUSOpRzALP2lIV" - + "GOtPKKbIhe5YCbkCAgQA"); + + "DQEHAaCCAxEEggMNMIIDCTCCAwUGCyqGSIb3DQEMCgECoIICsjCCAq4wKAYK" + + "KoZIhvcNAQwBAzAaBBQesw38x26DXisTDrMMSoAanDOAQgICBAAEggKAja8F" + + "U82RAAxhc36SWNXgWGV4CDSbDLFjlJuuXLTelz77KcX4dqPOQdKakm3OVl96" + + "cbp6mWNSOoo0F8bh/Qu51vayt7hT5NIuI8jJ/Q1FYUffMKRxGt14JwuuTQ8W" + + "5DO3z7422fm/rUu+Nkd6y+Sr0Q3FAE8QH/vNc9aUwusVAihr0AZCdT0/HwxK" + + "AKAXLtMHeTWRpdq3WPSilPEWeeZI9Gk14uKbjEeQIUsa8IujSxTE43XwNRQN" + + "z3Qm4oMxGOZP+DPxuKnj+Ug1OXgX5x+GD2fbwytzss9Isv/Zq8wq0gO3t1Ru" + + "PjpxPt/MH2PxNLe4JJTxg1tIXfNP5ZU1SivcIjGLWWcEu+xADG9uq2eDBOja" + + "mW2ZQ1cInSQw8mKcBbX7aEl0NVadSMfxMZxIw0unmoNEETmScoGr50G4Ha5H" + + "ty1iJLNtI69MUA1c2DsoOqyzlnumTTLwuqsZ/E8rFLfO4sHncMxMRdmCEUjn" + + "N2ZOfRqMrgtSFfBsYQ5YjxJ6CI1DLAJwIJhvx8tZgyGItgiI8pSyG8xsRliI" + + "WPQzocO39zHK0hG6ERGnfJyll62/MlDNl9BqjobswPu97BV9nMtPIl3yVBPa" + + "sZxj5LUPYt5nmBlIjIkT5K4cEOIWHKCHPOnAsk8AGW/vrugBcTsyw9nAsRx+" + + "PbmOmmgyo0g2SiPsUX0fGQIWOBVZNxkGP/E4qgDOFS0YavxrdUd2Bgo9q9Sc" + + "hENPI9wjhPztR2UNLtBviWd8utQJ7NhX+6guWEE4AN6Th/xLb/pe9c0sIsEO" + + "41ViDbu4wDGUz6kw3fpXjIu7i6QKniWXEUL9uuchUgZD1GJHQLhD8xgdR6YQ" + + "5SwfIadoWTFAMBkGCSqGSIb3DQEJFDEMHgoAYwB5AGMAbABlMCMGCSqGSIb3" + + "DQEJFTEWBBRoHxEy+w9gB2sa3ykN2Ok7sb3AajCCBosGCSqGSIb3DQEHBqCC" + + "BnwwggZ4AgEAMIIGcQYJKoZIhvcNAQcBMCgGCiqGSIb3DQEMAQYwGgQU40Mi" + + "gMmdUNKyHyGi8miA/3bKZO0CAgQAgIIGOIk1Ouu1n1yoHWGM7YsLpB5fqK6D" + + "LbhUoxsshDSxqemUX3QDJQVmPC9wQOUp1BUapkfB3uxsM15uUG/EUAPlF3iW" + + "0MKDpmcKTC8y1WzMtgZBmmXwRUbguH2gmn4nd6lI2SkLWQg5boQ47aHjZLO2" + + "MZsH1b/DUoT4m6fSrgsMnIVh03z1Gs2XO+Ky3qXqQJM9T3VtCfmeIJBIM2eP" + + "YqvWfnvoGZZZA+pmqVUSMu6q0U7cDA5CD9zhZ87tZvaJeQ198fVIKpMUHBdf" + + "WRGY/opZh4YTfqn+ZiiysEa9jjjx4hSkxS2XGkyUfwPEx4/1E2AdIBfi3KKW" + + "BSyx8hurMyf89YsjxqJudfCAQI2GdWLDEXwwHMi1mM3wn5NVFzZUqM/u+t2W" + + "f3gJGfykxwECxrn4TmerRJ3znyn7soLPEyy6Pp+JPNLyen3Z8gva5tU7Y2J4" + + "aW6YGbBuQ9iW6QcMA93UtWBMGRAJL1jZ9WDguaTkvH8ffSj90jfu7iTHCm/P" + + "4EEtEV7D4ciyLc5xVyq7gIQnIIViVRifAHyjbazrIFQ2yXYwINAk0yNmDqxu" + + "8W4KNxkhNTGvQP/kkk+oDpSCa7XfxMpny+2BudjEryen2q3skMp3HjU/svHQ" + + "+4Y9kxZ5rVYII9S8TRFmgxiRO7cQCdNEwiZndQVGahjVbLI3Jp3vmQhLg+2l" + + "QF07yT7Q0nxeyhbpDGUEizUyIKzs9Or0DEHbq0StU3YwLgHGLlllARLm0eAO" + + "SVhuxKGATS6GtCb/0jmzV+kX4GrK1Qkmit3Xxt9Lbq9b2v2eSMANqGrGpYyr" + + "ETfJ5Ri/UL0nF7M9+tXrrZam1dEM5nJXR04rXQXjxxIuxsrz5xhvS/I+45RY" + + "VKN9l1yw80wNYJlE3Un/eUxT0szk6XA7eguhB6ULGTZNDUMZdELAtwPcq+E4" + + "4+0oih/XLzo/losH10RZ1bBf58mFVl/SlZ0CDE3x6GnFyH/tyTb6pR3Vre1v" + + "TcBod/rkTyEnkPlFSztbBfCXXIRUcSUcbVXge3Vqn7Orhq1+sb6MPcr88uhU" + + "c9Z6g6oKf1liIhiELpMZ5qG06hTwmMlE8prE0tdReGP/eaS2eCu8MyN70adT" + + "IfW1PAopoZTfDYKxJYdsJUVkUojZUvmJ21sNeNREPaFBbwncHBR/y19afhqE" + + "yyvyzDhDJ1D81TkFUR0OwGk7FvV/5JEQCyJq0wIty9G6mJRbUi2tjCc5WpP7" + + "edDW5PBS/rfJPTDMGLy80LlD+obCTFc0sSaBI+dag02Xmxe31V9c96VPOsFt" + + "GQ532OFwZU52E9zYLQSL8L2sdNlEK+OCvTd1MNVbH6PGBYgxrmoDfNBQlYBh" + + "yX2R9wFClraNUBBV9Dtebb6MSqPW7m8xZWAXCmXkDqR9A9kP6qTMd4X3gSFT" + + "qJaezTWbHH44PTgffpK5A1ZBQj37se82QWtBKNPU14KEVvXcI+uuM/TmoAJY" + + "0hqMeXK/1JfzhxTuJsJl+c45LuGjq9dLY9tgTSqMLeKOqal7sLH1AVs4BCCA" + + "J/sHN5pgOjQNLZ1Zup5mZHXR/ynIhKnpYDADOfnAXLizn/UZZFs5huYJYQEQ" + + "K7zcDuzPuxcmFVqUa4AyL9Ul1N42rBx3VsKZ+pvcBTQU5mWsaYwPFox4wLx0" + + "HITx7v7cFYsqki7IHfgnvpJlIS8hrvqqXHl75b61T7ZfJMJNQjhf29//OZ36" + + "QU4mj7lXwudAe+qAJbn1De5B54dQhtLA7B6sX7/7Sy6xP42QJqXhlWngbhF1" + + "IsrgZZrFPJ7zeaKnjOfrLWr8bs1nthHNNoL4cqlPuYtliUGy5zxj9bpQH8xj" + + "oh8+PjTOT4H57IvUN/US/6R0awy8WafJ211diVjbU2IbjS/P+xa6Xlbaql4Z" + + "KlvXRmoMZNl6xPbJg4x6t2anadNmuS7TXHqfTpp+UxeSsr1phyPmxQZPujZY" + + "BADnjfNhTRi7esePheR/DPaPLwjllhetm+U7s7EZzMCdEcd5RB/jiceqRQ5b" + + "xoqSyvIW1ZcdTzRQEAFAhnMWRdVT0O0KYDATiSVqcBr0b70dIQ0lZvYk/TUy" + + "FdYhRXqC8Gzh8xQZPr3CBGoB02pWpp0Hbb5bHtpf3VnfsEmfwBtRPaEUMD0w" + + "ITAJBgUrDgMCGgUABBSsUQPThQeWi8r3oQZ22tcQW2dDqgQUSOpRzALP2lIV" + + "GOtPKKbIhe5YCbkCAgQA"); byte[] gostOpenSSLIntegerDPfx = Base64.decode( "MIIC/wIBAzCCAsUGCSqGSIb3DQEHAaCCArYEggKyMIICrjCCAc8GCSqGSIb3" - + "DQEHBqCCAcAwggG8AgEAMIIBtQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYw" - + "DgQIb1OLAOp7o6ACAggAgIIBiFSfDqzkF2Lv9arM6fdxKrixa9Zu8sGkrsbN" - + "1mYEPYRRJFyfTHB2cOn4yl2I6Ldo9m9GKtnTGGYugMTAFLdBNe0f7X0c4fjr" - + "norM2ODUDfzuqI0a54DLwixvV4U9Q0qakLKQJDAHnCSsWu7N8tRktpYt9oIZ" - + "3sVJ9r01+yxBrDOapAqT3UtaFILSiUU94Zdyehu9hmL3cq33s7Y+orfESC8A" - + "O7OYYks7c6sEjNsvUHag2bC3GClzEapiboIs2F2vb12NoiQ0skU3dbO7Jr1T" - + "P6qkjBYFvG31c3vG8pNxJ7iwJr5+FonJ6uVg3y8EmYCROD5Eyd0MeGaa+eBr" - + "z/CPFaaM50NT6RAL3CTmfqOEzOlXE2qyKZiPD65TxowbjYOmDh8Tb/mfOQUK" - + "hx8Tgzttk0CHHHZmUQkMm0RXDj/n07JaeGuQJQ1pK/3Wg7ejfGxj7eFgzmPU" - + "jOhIAAe/fwOkxUC8quv/+db/L+EeSQBSEyacU5MliXwOPVytMUOP4pFMtonw" - + "C6NzBU5JMIHYBgkqhkiG9w0BBwGggcoEgccwgcQwgcEGCyqGSIb3DQEMCgEC" - + "oHIwcDAcBgoqhkiG9w0BDAEDMA4ECF6BMzmkD7DbAgIIAARQlev2YN09882U" - + "niwvu9nMIgS3hmjSlqlpkf5aYQLosSy5eaOWCq0Vskqgv5i+77vKyQYcKOH0" - + "VnQYu98kWUgZy4fNfesufL+m3d29LX/JGdoxPjAXBgkqhkiG9w0BCRQxCh4I" - + "AHQAZQBzAHQwIwYJKoZIhvcNAQkVMRYEFIaC9GvZM/XUGW4U50bkjCfsTrW8" - + "MDEwITAJBgUrDgMCGgUABBT3iAwuHw7KQXrl09gBkHaUVbOoBAQIIm90qua1" - + "2i4CAggA"); + + "DQEHBqCCAcAwggG8AgEAMIIBtQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYw" + + "DgQIb1OLAOp7o6ACAggAgIIBiFSfDqzkF2Lv9arM6fdxKrixa9Zu8sGkrsbN" + + "1mYEPYRRJFyfTHB2cOn4yl2I6Ldo9m9GKtnTGGYugMTAFLdBNe0f7X0c4fjr" + + "norM2ODUDfzuqI0a54DLwixvV4U9Q0qakLKQJDAHnCSsWu7N8tRktpYt9oIZ" + + "3sVJ9r01+yxBrDOapAqT3UtaFILSiUU94Zdyehu9hmL3cq33s7Y+orfESC8A" + + "O7OYYks7c6sEjNsvUHag2bC3GClzEapiboIs2F2vb12NoiQ0skU3dbO7Jr1T" + + "P6qkjBYFvG31c3vG8pNxJ7iwJr5+FonJ6uVg3y8EmYCROD5Eyd0MeGaa+eBr" + + "z/CPFaaM50NT6RAL3CTmfqOEzOlXE2qyKZiPD65TxowbjYOmDh8Tb/mfOQUK" + + "hx8Tgzttk0CHHHZmUQkMm0RXDj/n07JaeGuQJQ1pK/3Wg7ejfGxj7eFgzmPU" + + "jOhIAAe/fwOkxUC8quv/+db/L+EeSQBSEyacU5MliXwOPVytMUOP4pFMtonw" + + "C6NzBU5JMIHYBgkqhkiG9w0BBwGggcoEgccwgcQwgcEGCyqGSIb3DQEMCgEC" + + "oHIwcDAcBgoqhkiG9w0BDAEDMA4ECF6BMzmkD7DbAgIIAARQlev2YN09882U" + + "niwvu9nMIgS3hmjSlqlpkf5aYQLosSy5eaOWCq0Vskqgv5i+77vKyQYcKOH0" + + "VnQYu98kWUgZy4fNfesufL+m3d29LX/JGdoxPjAXBgkqhkiG9w0BCRQxCh4I" + + "AHQAZQBzAHQwIwYJKoZIhvcNAQkVMRYEFIaC9GvZM/XUGW4U50bkjCfsTrW8" + + "MDEwITAJBgUrDgMCGgUABBT3iAwuHw7KQXrl09gBkHaUVbOoBAQIIm90qua1" + + "2i4CAggA"); private static byte[] certsOnly = Base64.decode( "MIICnwIBAzCCApgGCSqGSIb3DQEHAaCCAokEggKFMIICgTCCAn0GCSqGSIb3" + @@ -579,372 +584,374 @@ public class PKCS12StoreTest static byte[] JKS_Store = Base64.decode( "/u3+7QAAAAIAAAAUAAAAAgAGY2VydDE5AAABVrqTp2QABVguNTA5AAACETCC" - + "Ag0wggG3oAMCAQICARQwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAkFV" - + "MSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIw" - + "EAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZI" - + "hvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0x" - + "NjA4MjQwMzIzMjRaFw0xNjA4MjQwMzI1MDRaMIGPMQswCQYDVQQGEwJBVTEo" - + "MCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAG" - + "A1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3" - + "DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwWjANBgkq" - + "hkiG9w0BAQEFAANJADBGAkEAtKfkYXBXTxapcIKyK+WLaipil5hBm+EocqS9" - + "umJs+umQD3ar+xITnc5d5WVk+rK2VDFloEDGBoh0IOM9ke1+1wIBETANBgkq" - + "hkiG9w0BAQsFAANBAAoDCxo2es5N6DeKPLEUAJMHGqFCc+FC5hp43qs5IwmR" - + "eWW1uUTTJg+eRL9DkJqc1Q5jjsSnE0OerHLr5QlvwxEAAAACAAZjZXJ0MTgA" - + "AAFWupOnYgAFWC41MDkAAAIRMIICDTCCAbegAwIBAgIBEzANBgkqhkiG9w0B" - + "AQsFADCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2Yg" - + "dGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UE" - + "CAwIVmljdG9yaWExLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bi" - + "b3VuY3ljYXN0bGUub3JnMB4XDTE2MDgyNDAzMjMyNFoXDTE2MDgyNDAzMjUw" - + "NFowgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRo" - + "ZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgM" - + "CFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91" - + "bmN5Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdP" - + "FqlwgrIr5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWg" - + "QMYGiHQg4z2R7X7XAgERMA0GCSqGSIb3DQEBCwUAA0EAglkbmZACXbtqdfpA" - + "PJKpEhJqG8WVSqxUMHqZCrMYBAxKCnfBTGKNoV506WY/KhhJICK8xg17iL+1" - + "NhCrt0zq8QAAAAIABmNlcnQxNwAAAVa6k6dhAAVYLjUwOQAAAhEwggINMIIB" - + "t6ADAgECAgESMA0GCSqGSIb3DQEBCwUAMIGPMQswCQYDVQQGEwJBVTEoMCYG" - + "A1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UE" - + "BwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJ" - + "ARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwHhcNMTYwODI0" - + "MDMyMzI0WhcNMTYwODI0MDMyNTA0WjCBjzELMAkGA1UEBhMCQVUxKDAmBgNV" - + "BAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcM" - + "CU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkqhkiG9w0BCQEW" - + "IGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMFowDQYJKoZIhvcN" - + "AQEBBQADSQAwRgJBALSn5GFwV08WqXCCsivli2oqYpeYQZvhKHKkvbpibPrp" - + "kA92q/sSE53OXeVlZPqytlQxZaBAxgaIdCDjPZHtftcCAREwDQYJKoZIhvcN" - + "AQELBQADQQCoKlzmG19aQKP9iqQT3k6sMzZdVZkRuHwaPTvdTVaSZtIsl2YX" - + "FzIygviAHkVWkoF7iuY3T1skQD+Cjpj4ri6rAAAAAgAGY2VydDE2AAABVrqT" - + "p18ABVguNTA5AAACETCCAg0wggG3oAMCAQICAREwDQYJKoZIhvcNAQELBQAw" - + "gY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBC" - + "b3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZp" - + "Y3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5" - + "Y2FzdGxlLm9yZzAeFw0xNjA4MjQwMzIzMjRaFw0xNjA4MjQwMzI1MDRaMIGP" - + "MQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91" - + "bmN5IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0" - + "b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNh" - + "c3RsZS5vcmcwWjANBgkqhkiG9w0BAQEFAANJADBGAkEAtKfkYXBXTxapcIKy" - + "K+WLaipil5hBm+EocqS9umJs+umQD3ar+xITnc5d5WVk+rK2VDFloEDGBoh0" - + "IOM9ke1+1wIBETANBgkqhkiG9w0BAQsFAANBAA/zyjwMVvjZt5aCStPAShfH" - + "BK2UDhEnu308Ir7k0M0g46CGD2lmaIn8wY1pBm+eZj5mKCK1iD6L7THJIxlh" - + "NUkAAAACAAZjZXJ0MTUAAAFWupOnXQAFWC41MDkAAAIRMIICDTCCAbegAwIB" - + "AgIBEDANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoM" - + "H1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1l" - + "bGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkqhkiG9w0BCQEWIGZl" - + "ZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMB4XDTE2MDgyNDAzMjMy" - + "NFoXDTE2MDgyNDAzMjUwNFowgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9U" - + "aGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxi" - + "b3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVk" - + "YmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEBAQUA" - + "A0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7" - + "EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERMA0GCSqGSIb3DQEBCwUA" - + "A0EArVzFb0Nh8n2Rm1I4Mrxk6vTPbbfPy7akWKp5F1AKa4rwwz37Ki+i3/qQ" - + "5/j1UsuG0v9dCXkZbGMSzW5uqu57QgAAAAIABmNlcnQxNAAAAVa6k6dcAAVY" - + "LjUwOQAAAhEwggINMIIBt6ADAgECAgEPMA0GCSqGSIb3DQEBCwUAMIGPMQsw" - + "CQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5" - + "IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3Jp" - + "YTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3Rs" - + "ZS5vcmcwHhcNMTYwODI0MDMyMzI0WhcNMTYwODI0MDMyNTA0WjCBjzELMAkG" - + "A1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBD" - + "YXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWEx" - + "LzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUu" - + "b3JnMFowDQYJKoZIhvcNAQEBBQADSQAwRgJBALSn5GFwV08WqXCCsivli2oq" - + "YpeYQZvhKHKkvbpibPrpkA92q/sSE53OXeVlZPqytlQxZaBAxgaIdCDjPZHt" - + "ftcCAREwDQYJKoZIhvcNAQELBQADQQBk9jFHwJ9RMpS3cTfFD4Jn94ZJo0Oo" - + "4pjPdpt2/uIqSOEA5QHgJVkY4+23hbgUvDDk6cU95tAINYMj1N7QlirNAAAA" - + "AgAGY2VydDEzAAABVrqTp1oABVguNTA5AAACETCCAg0wggG3oAMCAQICAQ4w" - + "DQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUg" - + "TGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3Vy" - + "bmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFj" - + "ay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0xNjA4MjQwMzIzMjRaFw0x" - + "NjA4MjQwMzI1MDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExl" - + "Z2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5l" - + "MREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2st" - + "Y3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwWjANBgkqhkiG9w0BAQEFAANJADBG" - + "AkEAtKfkYXBXTxapcIKyK+WLaipil5hBm+EocqS9umJs+umQD3ar+xITnc5d" - + "5WVk+rK2VDFloEDGBoh0IOM9ke1+1wIBETANBgkqhkiG9w0BAQsFAANBAF6x" - + "Fni4cQsdBiE+ksluexlGSGV721kieRIGrgQP9JWbyvDw3H8/AKrcjSEOru0M" - + "U3utomkk4ympScU+eL45bQUAAAACAAZjZXJ0MTIAAAFWupOnWAAFWC41MDkA" - + "AAIRMIICDTCCAbegAwIBAgIBDTANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UE" - + "BhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0" - + "bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAt" - + "BgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3Jn" - + "MB4XDTE2MDgyNDAzMjMyNFoXDTE2MDgyNDAzMjUwNFowgY8xCzAJBgNVBAYT" - + "AkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxl" - + "MRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJ" - + "KoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzBa" - + "MA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb" - + "4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgER" - + "MA0GCSqGSIb3DQEBCwUAA0EAcNDNuol1VdqEOBvZCJLWkNFVUfyIMX7Y4Czk" - + "hOJ9PWH97EOr989fdiBBDTKS5pQlI32z932cwH9vYZZ0TNWAngAAAAIABmNl" - + "cnQxMQAAAVa6k6dXAAVYLjUwOQAAAhEwggINMIIBt6ADAgECAgEMMA0GCSqG" - + "SIb3DQEBCwUAMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lv" - + "biBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREw" - + "DwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5" - + "cHRvQGJvdW5jeWNhc3RsZS5vcmcwHhcNMTYwODI0MDMyMzI0WhcNMTYwODI0" - + "MDMyNTA0WjCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24g" - + "b2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8G" - + "A1UECAwIVmljdG9yaWExLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0" - + "b0Bib3VuY3ljYXN0bGUub3JnMFowDQYJKoZIhvcNAQEBBQADSQAwRgJBALSn" - + "5GFwV08WqXCCsivli2oqYpeYQZvhKHKkvbpibPrpkA92q/sSE53OXeVlZPqy" - + "tlQxZaBAxgaIdCDjPZHtftcCAREwDQYJKoZIhvcNAQELBQADQQAtpD6dgY7n" - + "+wnuKxNsXfMr21VSx5PLqqbxVUMHl/NzonLFSYx0oMPJVWwGYz0uNlglwTCx" - + "l2cTpc3kQTSvUSGzAAAAAgAGY2VydDEwAAABVrqTp1UABVguNTA5AAACETCC" - + "Ag0wggG3oAMCAQICAQswDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAkFV" - + "MSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIw" - + "EAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZI" - + "hvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0x" - + "NjA4MjQwMzIzMjRaFw0xNjA4MjQwMzI1MDRaMIGPMQswCQYDVQQGEwJBVTEo" - + "MCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAG" - + "A1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3" - + "DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwWjANBgkq" - + "hkiG9w0BAQEFAANJADBGAkEAtKfkYXBXTxapcIKyK+WLaipil5hBm+EocqS9" - + "umJs+umQD3ar+xITnc5d5WVk+rK2VDFloEDGBoh0IOM9ke1+1wIBETANBgkq" - + "hkiG9w0BAQsFAANBALLlTLPkOYTYbI0CtvvJpThX4LvAspq5PH3LacfWB+tj" - + "/gEQhWrODkFSS2dWwNdR6IQpWl0L2xZHJCYG93IdJC0AAAACAAVjZXJ0OQAA" - + "AVa6k6dUAAVYLjUwOQAAAhEwggINMIIBt6ADAgECAgEKMA0GCSqGSIb3DQEB" - + "CwUAMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0" - + "aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREwDwYDVQQI" - + "DAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJv" - + "dW5jeWNhc3RsZS5vcmcwHhcNMTYwODI0MDMyMzI0WhcNMTYwODI0MDMyNTA0" - + "WjCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhl" - + "IEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwI" - + "VmljdG9yaWExLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3Vu" - + "Y3ljYXN0bGUub3JnMFowDQYJKoZIhvcNAQEBBQADSQAwRgJBALSn5GFwV08W" - + "qXCCsivli2oqYpeYQZvhKHKkvbpibPrpkA92q/sSE53OXeVlZPqytlQxZaBA" - + "xgaIdCDjPZHtftcCAREwDQYJKoZIhvcNAQELBQADQQB+rfnwKrVxuYjygj9Y" - + "VF2r7MWJj6YyaRmcZHQrKw7zmXMAnpXaJHaRvZ5yEZtWo57p+fDQLk5u0QoO" - + "MrSX8B8PAAAAAgAFY2VydDgAAAFWupOnUgAFWC41MDkAAAIRMIICDTCCAbeg" - + "AwIBAgIBCTANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCQVUxKDAmBgNV" - + "BAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcM" - + "CU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkqhkiG9w0BCQEW" - + "IGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMB4XDTE2MDgyNDAz" - + "MjMyNFoXDTE2MDgyNDAzMjUwNFowgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQK" - + "DB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlN" - + "ZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBm" - + "ZWVkYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEB" - + "AQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb4ShypL26Ymz66ZAP" - + "dqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERMA0GCSqGSIb3DQEB" - + "CwUAA0EAK/s6ltnp3JLH93++PIJ0Ui68ZcQP8CFcOfy/7tbeIameAdPb74pI" - + "QVLsJOQl57/ybe6jEjDNG+Ahd9Ce57GUQQAAAAIABWNlcnQ3AAABVrqTp1AA" - + "BVguNTA5AAACETCCAg0wggG3oAMCAQICAQgwDQYJKoZIhvcNAQELBQAwgY8x" - + "CzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3Vu" - + "Y3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3Rv" - + "cmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5Y2Fz" - + "dGxlLm9yZzAeFw0xNjA4MjQwMzIzMjRaFw0xNjA4MjQwMzI1MDRaMIGPMQsw" - + "CQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5" - + "IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3Jp" - + "YTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3Rs" - + "ZS5vcmcwWjANBgkqhkiG9w0BAQEFAANJADBGAkEAtKfkYXBXTxapcIKyK+WL" - + "aipil5hBm+EocqS9umJs+umQD3ar+xITnc5d5WVk+rK2VDFloEDGBoh0IOM9" - + "ke1+1wIBETANBgkqhkiG9w0BAQsFAANBAJDkyw3j/GCV2/2aLmYHF2WxBADi" - + "tlWWLu0X9Aer0LYUskv52EK2edFHq0tVYlRKDpJcPtfmQSCu5cciJ51aqy8A" - + "AAACAAVjZXJ0NgAAAVa6k6dOAAVYLjUwOQAAAhEwggINMIIBt6ADAgECAgEH" - + "MA0GCSqGSIb3DQEBCwUAMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhl" - + "IExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBwwJTWVsYm91" - + "cm5lMREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJh" - + "Y2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwHhcNMTYwODI0MDMyMzI0WhcN" - + "MTYwODI0MDMyNTA0WjCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBM" - + "ZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJu" - + "ZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNr" - + "LWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMFowDQYJKoZIhvcNAQEBBQADSQAw" - + "RgJBALSn5GFwV08WqXCCsivli2oqYpeYQZvhKHKkvbpibPrpkA92q/sSE53O" - + "XeVlZPqytlQxZaBAxgaIdCDjPZHtftcCAREwDQYJKoZIhvcNAQELBQADQQCY" - + "XkifQxQldNLcX6U1W7jFizMLbcr5gKw2m9Y4AknIwJ5L5l89wXOc0xfldWWF" - + "ohBCKbHMIwpQZykmm1DWi0h4AAAAAgAFY2VydDUAAAFWupOnTAAFWC41MDkA" - + "AAIRMIICDTCCAbegAwIBAgIBBjANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UE" - + "BhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0" - + "bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAt" - + "BgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3Jn" - + "MB4XDTE2MDgyNDAzMjMyNFoXDTE2MDgyNDAzMjUwNFowgY8xCzAJBgNVBAYT" - + "AkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxl" - + "MRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJ" - + "KoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzBa" - + "MA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb" - + "4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgER" - + "MA0GCSqGSIb3DQEBCwUAA0EAogFA+GTVCquJxRCXggv9TcvtT3jXEQ2n+ftY" - + "IcL4R05pqg/3kGyJpj73BI09PykEWx1nwT+mcZYZg6W/AQgomwAAAAIABWNl" - + "cnQ0AAABVrqTp0oABVguNTA5AAACETCCAg0wggG3oAMCAQICAQUwDQYJKoZI" - + "hvcNAQELBQAwgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9u" - + "IG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxETAP" - + "BgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlw" - + "dG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0xNjA4MjQwMzIzMjRaFw0xNjA4MjQw" - + "MzI1MDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBv" - + "ZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREwDwYD" - + "VQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRv" - + "QGJvdW5jeWNhc3RsZS5vcmcwWjANBgkqhkiG9w0BAQEFAANJADBGAkEAtKfk" - + "YXBXTxapcIKyK+WLaipil5hBm+EocqS9umJs+umQD3ar+xITnc5d5WVk+rK2" - + "VDFloEDGBoh0IOM9ke1+1wIBETANBgkqhkiG9w0BAQsFAANBAC7YKkm1uS5C" - + "XVTXObt9oYXXrtN3+Wvbtl+9HNgX3CVzFGDo70GSuCpgIq2lxMZHf8YrRKTv" - + "t+o6Dasw69ubfg8AAAACAAVjZXJ0MwAAAVa6k6dIAAVYLjUwOQAAAhEwggIN" - + "MIIBt6ADAgECAgEEMA0GCSqGSIb3DQEBCwUAMIGPMQswCQYDVQQGEwJBVTEo" - + "MCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAG" - + "A1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3" - + "DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwHhcNMTYw" - + "ODI0MDMyMzI0WhcNMTYwODI0MDMyNTA0WjCBjzELMAkGA1UEBhMCQVUxKDAm" - + "BgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNV" - + "BAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkqhkiG9w0B" - + "CQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMFowDQYJKoZI" - + "hvcNAQEBBQADSQAwRgJBALSn5GFwV08WqXCCsivli2oqYpeYQZvhKHKkvbpi" - + "bPrpkA92q/sSE53OXeVlZPqytlQxZaBAxgaIdCDjPZHtftcCAREwDQYJKoZI" - + "hvcNAQELBQADQQClzdQAN4gHAMyvFabp019/e73AsNbL+zNzvPGZdXjYZIve" - + "y9RjQV2Vtlx3kN7wJX9bqBJQLyHKdUpXSFTvHh1dAAAAAgAFY2VydDIAAAFW" - + "upOnRgAFWC41MDkAAAIRMIICDTCCAbegAwIBAgIBAzANBgkqhkiG9w0BAQsF" - + "ADCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhl" - + "IEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwI" - + "VmljdG9yaWExLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3Vu" - + "Y3ljYXN0bGUub3JnMB4XDTE2MDgyNDAzMjMyNFoXDTE2MDgyNDAzMjUwNFow" - + "gY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBC" - + "b3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZp" - + "Y3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5" - + "Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlw" - + "grIr5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYG" - + "iHQg4z2R7X7XAgERMA0GCSqGSIb3DQEBCwUAA0EAVlnwlvG4I9JVLkMoN5MJ" - + "4vIw4qXSLxdey++wMdF4aSoOe2I3p4o97VhNZBPYZbZCUw2ShsyhkXOytgXd" - + "NYdCBgAAAAIABWNlcnQxAAABVrqTp0QABVguNTA5AAACETCCAg0wggG3oAMC" - + "AQICAQIwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQK" - + "DB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlN" - + "ZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBm" - + "ZWVkYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0xNjA4MjQwMzIz" - + "MjRaFw0xNjA4MjQwMzI1MDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UECgwf" - + "VGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBwwJTWVs" - + "Ym91cm5lMREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVl" - + "ZGJhY2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwWjANBgkqhkiG9w0BAQEF" - + "AANJADBGAkEAtKfkYXBXTxapcIKyK+WLaipil5hBm+EocqS9umJs+umQD3ar" - + "+xITnc5d5WVk+rK2VDFloEDGBoh0IOM9ke1+1wIBETANBgkqhkiG9w0BAQsF" - + "AANBAKqAyBtKhOgy4NmjV2fc1JlcM2sQ8rEfZ9+PqJixFAqvKSLl6gASZ0dW" - + "Mrmof6ZkKSjEerwoPOXdKJ1VeqOjMBQAAAACAAVjZXJ0MAAAAVa6k6dCAAVY" - + "LjUwOQAAAhEwggINMIIBt6ADAgECAgEBMA0GCSqGSIb3DQEBCwUAMIGPMQsw" - + "CQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5" - + "IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3Jp" - + "YTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3Rs" - + "ZS5vcmcwHhcNMTYwODI0MDMyMzI0WhcNMTYwODI0MDMyNTA0WjCBjzELMAkG" - + "A1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBD" - + "YXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWEx" - + "LzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUu" - + "b3JnMFowDQYJKoZIhvcNAQEBBQADSQAwRgJBALSn5GFwV08WqXCCsivli2oq" - + "YpeYQZvhKHKkvbpibPrpkA92q/sSE53OXeVlZPqytlQxZaBAxgaIdCDjPZHt" - + "ftcCAREwDQYJKoZIhvcNAQELBQADQQAlNXGzWfJmbvK4blA3GCHRO4BMc9of" - + "9LOKSnZdIHpdxkLqoxqWhAbph3zqhDYOe6SuRR1ZZoOnbKVICqm9W1ps967o" - + "ndfs5jZEtLNpj106EQT4x9U="); + + "Ag0wggG3oAMCAQICARQwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAkFV" + + "MSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIw" + + "EAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZI" + + "hvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0x" + + "NjA4MjQwMzIzMjRaFw0xNjA4MjQwMzI1MDRaMIGPMQswCQYDVQQGEwJBVTEo" + + "MCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAG" + + "A1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3" + + "DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwWjANBgkq" + + "hkiG9w0BAQEFAANJADBGAkEAtKfkYXBXTxapcIKyK+WLaipil5hBm+EocqS9" + + "umJs+umQD3ar+xITnc5d5WVk+rK2VDFloEDGBoh0IOM9ke1+1wIBETANBgkq" + + "hkiG9w0BAQsFAANBAAoDCxo2es5N6DeKPLEUAJMHGqFCc+FC5hp43qs5IwmR" + + "eWW1uUTTJg+eRL9DkJqc1Q5jjsSnE0OerHLr5QlvwxEAAAACAAZjZXJ0MTgA" + + "AAFWupOnYgAFWC41MDkAAAIRMIICDTCCAbegAwIBAgIBEzANBgkqhkiG9w0B" + + "AQsFADCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2Yg" + + "dGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UE" + + "CAwIVmljdG9yaWExLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bi" + + "b3VuY3ljYXN0bGUub3JnMB4XDTE2MDgyNDAzMjMyNFoXDTE2MDgyNDAzMjUw" + + "NFowgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRo" + + "ZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgM" + + "CFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91" + + "bmN5Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdP" + + "FqlwgrIr5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWg" + + "QMYGiHQg4z2R7X7XAgERMA0GCSqGSIb3DQEBCwUAA0EAglkbmZACXbtqdfpA" + + "PJKpEhJqG8WVSqxUMHqZCrMYBAxKCnfBTGKNoV506WY/KhhJICK8xg17iL+1" + + "NhCrt0zq8QAAAAIABmNlcnQxNwAAAVa6k6dhAAVYLjUwOQAAAhEwggINMIIB" + + "t6ADAgECAgESMA0GCSqGSIb3DQEBCwUAMIGPMQswCQYDVQQGEwJBVTEoMCYG" + + "A1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UE" + + "BwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJ" + + "ARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwHhcNMTYwODI0" + + "MDMyMzI0WhcNMTYwODI0MDMyNTA0WjCBjzELMAkGA1UEBhMCQVUxKDAmBgNV" + + "BAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcM" + + "CU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkqhkiG9w0BCQEW" + + "IGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMFowDQYJKoZIhvcN" + + "AQEBBQADSQAwRgJBALSn5GFwV08WqXCCsivli2oqYpeYQZvhKHKkvbpibPrp" + + "kA92q/sSE53OXeVlZPqytlQxZaBAxgaIdCDjPZHtftcCAREwDQYJKoZIhvcN" + + "AQELBQADQQCoKlzmG19aQKP9iqQT3k6sMzZdVZkRuHwaPTvdTVaSZtIsl2YX" + + "FzIygviAHkVWkoF7iuY3T1skQD+Cjpj4ri6rAAAAAgAGY2VydDE2AAABVrqT" + + "p18ABVguNTA5AAACETCCAg0wggG3oAMCAQICAREwDQYJKoZIhvcNAQELBQAw" + + "gY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBC" + + "b3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZp" + + "Y3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5" + + "Y2FzdGxlLm9yZzAeFw0xNjA4MjQwMzIzMjRaFw0xNjA4MjQwMzI1MDRaMIGP" + + "MQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91" + + "bmN5IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0" + + "b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNh" + + "c3RsZS5vcmcwWjANBgkqhkiG9w0BAQEFAANJADBGAkEAtKfkYXBXTxapcIKy" + + "K+WLaipil5hBm+EocqS9umJs+umQD3ar+xITnc5d5WVk+rK2VDFloEDGBoh0" + + "IOM9ke1+1wIBETANBgkqhkiG9w0BAQsFAANBAA/zyjwMVvjZt5aCStPAShfH" + + "BK2UDhEnu308Ir7k0M0g46CGD2lmaIn8wY1pBm+eZj5mKCK1iD6L7THJIxlh" + + "NUkAAAACAAZjZXJ0MTUAAAFWupOnXQAFWC41MDkAAAIRMIICDTCCAbegAwIB" + + "AgIBEDANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoM" + + "H1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1l" + + "bGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkqhkiG9w0BCQEWIGZl" + + "ZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMB4XDTE2MDgyNDAzMjMy" + + "NFoXDTE2MDgyNDAzMjUwNFowgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9U" + + "aGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxi" + + "b3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVk" + + "YmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEBAQUA" + + "A0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7" + + "EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERMA0GCSqGSIb3DQEBCwUA" + + "A0EArVzFb0Nh8n2Rm1I4Mrxk6vTPbbfPy7akWKp5F1AKa4rwwz37Ki+i3/qQ" + + "5/j1UsuG0v9dCXkZbGMSzW5uqu57QgAAAAIABmNlcnQxNAAAAVa6k6dcAAVY" + + "LjUwOQAAAhEwggINMIIBt6ADAgECAgEPMA0GCSqGSIb3DQEBCwUAMIGPMQsw" + + "CQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5" + + "IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3Jp" + + "YTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3Rs" + + "ZS5vcmcwHhcNMTYwODI0MDMyMzI0WhcNMTYwODI0MDMyNTA0WjCBjzELMAkG" + + "A1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBD" + + "YXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWEx" + + "LzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUu" + + "b3JnMFowDQYJKoZIhvcNAQEBBQADSQAwRgJBALSn5GFwV08WqXCCsivli2oq" + + "YpeYQZvhKHKkvbpibPrpkA92q/sSE53OXeVlZPqytlQxZaBAxgaIdCDjPZHt" + + "ftcCAREwDQYJKoZIhvcNAQELBQADQQBk9jFHwJ9RMpS3cTfFD4Jn94ZJo0Oo" + + "4pjPdpt2/uIqSOEA5QHgJVkY4+23hbgUvDDk6cU95tAINYMj1N7QlirNAAAA" + + "AgAGY2VydDEzAAABVrqTp1oABVguNTA5AAACETCCAg0wggG3oAMCAQICAQ4w" + + "DQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUg" + + "TGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3Vy" + + "bmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFj" + + "ay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0xNjA4MjQwMzIzMjRaFw0x" + + "NjA4MjQwMzI1MDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExl" + + "Z2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5l" + + "MREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2st" + + "Y3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwWjANBgkqhkiG9w0BAQEFAANJADBG" + + "AkEAtKfkYXBXTxapcIKyK+WLaipil5hBm+EocqS9umJs+umQD3ar+xITnc5d" + + "5WVk+rK2VDFloEDGBoh0IOM9ke1+1wIBETANBgkqhkiG9w0BAQsFAANBAF6x" + + "Fni4cQsdBiE+ksluexlGSGV721kieRIGrgQP9JWbyvDw3H8/AKrcjSEOru0M" + + "U3utomkk4ympScU+eL45bQUAAAACAAZjZXJ0MTIAAAFWupOnWAAFWC41MDkA" + + "AAIRMIICDTCCAbegAwIBAgIBDTANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UE" + + "BhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0" + + "bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAt" + + "BgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3Jn" + + "MB4XDTE2MDgyNDAzMjMyNFoXDTE2MDgyNDAzMjUwNFowgY8xCzAJBgNVBAYT" + + "AkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxl" + + "MRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJ" + + "KoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzBa" + + "MA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb" + + "4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgER" + + "MA0GCSqGSIb3DQEBCwUAA0EAcNDNuol1VdqEOBvZCJLWkNFVUfyIMX7Y4Czk" + + "hOJ9PWH97EOr989fdiBBDTKS5pQlI32z932cwH9vYZZ0TNWAngAAAAIABmNl" + + "cnQxMQAAAVa6k6dXAAVYLjUwOQAAAhEwggINMIIBt6ADAgECAgEMMA0GCSqG" + + "SIb3DQEBCwUAMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lv" + + "biBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREw" + + "DwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5" + + "cHRvQGJvdW5jeWNhc3RsZS5vcmcwHhcNMTYwODI0MDMyMzI0WhcNMTYwODI0" + + "MDMyNTA0WjCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24g" + + "b2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8G" + + "A1UECAwIVmljdG9yaWExLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0" + + "b0Bib3VuY3ljYXN0bGUub3JnMFowDQYJKoZIhvcNAQEBBQADSQAwRgJBALSn" + + "5GFwV08WqXCCsivli2oqYpeYQZvhKHKkvbpibPrpkA92q/sSE53OXeVlZPqy" + + "tlQxZaBAxgaIdCDjPZHtftcCAREwDQYJKoZIhvcNAQELBQADQQAtpD6dgY7n" + + "+wnuKxNsXfMr21VSx5PLqqbxVUMHl/NzonLFSYx0oMPJVWwGYz0uNlglwTCx" + + "l2cTpc3kQTSvUSGzAAAAAgAGY2VydDEwAAABVrqTp1UABVguNTA5AAACETCC" + + "Ag0wggG3oAMCAQICAQswDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAkFV" + + "MSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIw" + + "EAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZI" + + "hvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0x" + + "NjA4MjQwMzIzMjRaFw0xNjA4MjQwMzI1MDRaMIGPMQswCQYDVQQGEwJBVTEo" + + "MCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAG" + + "A1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3" + + "DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwWjANBgkq" + + "hkiG9w0BAQEFAANJADBGAkEAtKfkYXBXTxapcIKyK+WLaipil5hBm+EocqS9" + + "umJs+umQD3ar+xITnc5d5WVk+rK2VDFloEDGBoh0IOM9ke1+1wIBETANBgkq" + + "hkiG9w0BAQsFAANBALLlTLPkOYTYbI0CtvvJpThX4LvAspq5PH3LacfWB+tj" + + "/gEQhWrODkFSS2dWwNdR6IQpWl0L2xZHJCYG93IdJC0AAAACAAVjZXJ0OQAA" + + "AVa6k6dUAAVYLjUwOQAAAhEwggINMIIBt6ADAgECAgEKMA0GCSqGSIb3DQEB" + + "CwUAMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0" + + "aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREwDwYDVQQI" + + "DAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJv" + + "dW5jeWNhc3RsZS5vcmcwHhcNMTYwODI0MDMyMzI0WhcNMTYwODI0MDMyNTA0" + + "WjCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhl" + + "IEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwI" + + "VmljdG9yaWExLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3Vu" + + "Y3ljYXN0bGUub3JnMFowDQYJKoZIhvcNAQEBBQADSQAwRgJBALSn5GFwV08W" + + "qXCCsivli2oqYpeYQZvhKHKkvbpibPrpkA92q/sSE53OXeVlZPqytlQxZaBA" + + "xgaIdCDjPZHtftcCAREwDQYJKoZIhvcNAQELBQADQQB+rfnwKrVxuYjygj9Y" + + "VF2r7MWJj6YyaRmcZHQrKw7zmXMAnpXaJHaRvZ5yEZtWo57p+fDQLk5u0QoO" + + "MrSX8B8PAAAAAgAFY2VydDgAAAFWupOnUgAFWC41MDkAAAIRMIICDTCCAbeg" + + "AwIBAgIBCTANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCQVUxKDAmBgNV" + + "BAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcM" + + "CU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkqhkiG9w0BCQEW" + + "IGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMB4XDTE2MDgyNDAz" + + "MjMyNFoXDTE2MDgyNDAzMjUwNFowgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQK" + + "DB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlN" + + "ZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBm" + + "ZWVkYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEB" + + "AQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb4ShypL26Ymz66ZAP" + + "dqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERMA0GCSqGSIb3DQEB" + + "CwUAA0EAK/s6ltnp3JLH93++PIJ0Ui68ZcQP8CFcOfy/7tbeIameAdPb74pI" + + "QVLsJOQl57/ybe6jEjDNG+Ahd9Ce57GUQQAAAAIABWNlcnQ3AAABVrqTp1AA" + + "BVguNTA5AAACETCCAg0wggG3oAMCAQICAQgwDQYJKoZIhvcNAQELBQAwgY8x" + + "CzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3Vu" + + "Y3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3Rv" + + "cmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5Y2Fz" + + "dGxlLm9yZzAeFw0xNjA4MjQwMzIzMjRaFw0xNjA4MjQwMzI1MDRaMIGPMQsw" + + "CQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5" + + "IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3Jp" + + "YTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3Rs" + + "ZS5vcmcwWjANBgkqhkiG9w0BAQEFAANJADBGAkEAtKfkYXBXTxapcIKyK+WL" + + "aipil5hBm+EocqS9umJs+umQD3ar+xITnc5d5WVk+rK2VDFloEDGBoh0IOM9" + + "ke1+1wIBETANBgkqhkiG9w0BAQsFAANBAJDkyw3j/GCV2/2aLmYHF2WxBADi" + + "tlWWLu0X9Aer0LYUskv52EK2edFHq0tVYlRKDpJcPtfmQSCu5cciJ51aqy8A" + + "AAACAAVjZXJ0NgAAAVa6k6dOAAVYLjUwOQAAAhEwggINMIIBt6ADAgECAgEH" + + "MA0GCSqGSIb3DQEBCwUAMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhl" + + "IExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBwwJTWVsYm91" + + "cm5lMREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJh" + + "Y2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwHhcNMTYwODI0MDMyMzI0WhcN" + + "MTYwODI0MDMyNTA0WjCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBM" + + "ZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJu" + + "ZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNr" + + "LWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMFowDQYJKoZIhvcNAQEBBQADSQAw" + + "RgJBALSn5GFwV08WqXCCsivli2oqYpeYQZvhKHKkvbpibPrpkA92q/sSE53O" + + "XeVlZPqytlQxZaBAxgaIdCDjPZHtftcCAREwDQYJKoZIhvcNAQELBQADQQCY" + + "XkifQxQldNLcX6U1W7jFizMLbcr5gKw2m9Y4AknIwJ5L5l89wXOc0xfldWWF" + + "ohBCKbHMIwpQZykmm1DWi0h4AAAAAgAFY2VydDUAAAFWupOnTAAFWC41MDkA" + + "AAIRMIICDTCCAbegAwIBAgIBBjANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UE" + + "BhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0" + + "bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAt" + + "BgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3Jn" + + "MB4XDTE2MDgyNDAzMjMyNFoXDTE2MDgyNDAzMjUwNFowgY8xCzAJBgNVBAYT" + + "AkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxl" + + "MRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJ" + + "KoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzBa" + + "MA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb" + + "4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgER" + + "MA0GCSqGSIb3DQEBCwUAA0EAogFA+GTVCquJxRCXggv9TcvtT3jXEQ2n+ftY" + + "IcL4R05pqg/3kGyJpj73BI09PykEWx1nwT+mcZYZg6W/AQgomwAAAAIABWNl" + + "cnQ0AAABVrqTp0oABVguNTA5AAACETCCAg0wggG3oAMCAQICAQUwDQYJKoZI" + + "hvcNAQELBQAwgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9u" + + "IG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxETAP" + + "BgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlw" + + "dG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0xNjA4MjQwMzIzMjRaFw0xNjA4MjQw" + + "MzI1MDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBv" + + "ZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREwDwYD" + + "VQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRv" + + "QGJvdW5jeWNhc3RsZS5vcmcwWjANBgkqhkiG9w0BAQEFAANJADBGAkEAtKfk" + + "YXBXTxapcIKyK+WLaipil5hBm+EocqS9umJs+umQD3ar+xITnc5d5WVk+rK2" + + "VDFloEDGBoh0IOM9ke1+1wIBETANBgkqhkiG9w0BAQsFAANBAC7YKkm1uS5C" + + "XVTXObt9oYXXrtN3+Wvbtl+9HNgX3CVzFGDo70GSuCpgIq2lxMZHf8YrRKTv" + + "t+o6Dasw69ubfg8AAAACAAVjZXJ0MwAAAVa6k6dIAAVYLjUwOQAAAhEwggIN" + + "MIIBt6ADAgECAgEEMA0GCSqGSIb3DQEBCwUAMIGPMQswCQYDVQQGEwJBVTEo" + + "MCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAG" + + "A1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3" + + "DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwHhcNMTYw" + + "ODI0MDMyMzI0WhcNMTYwODI0MDMyNTA0WjCBjzELMAkGA1UEBhMCQVUxKDAm" + + "BgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNV" + + "BAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkqhkiG9w0B" + + "CQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMFowDQYJKoZI" + + "hvcNAQEBBQADSQAwRgJBALSn5GFwV08WqXCCsivli2oqYpeYQZvhKHKkvbpi" + + "bPrpkA92q/sSE53OXeVlZPqytlQxZaBAxgaIdCDjPZHtftcCAREwDQYJKoZI" + + "hvcNAQELBQADQQClzdQAN4gHAMyvFabp019/e73AsNbL+zNzvPGZdXjYZIve" + + "y9RjQV2Vtlx3kN7wJX9bqBJQLyHKdUpXSFTvHh1dAAAAAgAFY2VydDIAAAFW" + + "upOnRgAFWC41MDkAAAIRMIICDTCCAbegAwIBAgIBAzANBgkqhkiG9w0BAQsF" + + "ADCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhl" + + "IEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwI" + + "VmljdG9yaWExLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3Vu" + + "Y3ljYXN0bGUub3JnMB4XDTE2MDgyNDAzMjMyNFoXDTE2MDgyNDAzMjUwNFow" + + "gY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBC" + + "b3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZp" + + "Y3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG9AYm91bmN5" + + "Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlw" + + "grIr5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYG" + + "iHQg4z2R7X7XAgERMA0GCSqGSIb3DQEBCwUAA0EAVlnwlvG4I9JVLkMoN5MJ" + + "4vIw4qXSLxdey++wMdF4aSoOe2I3p4o97VhNZBPYZbZCUw2ShsyhkXOytgXd" + + "NYdCBgAAAAIABWNlcnQxAAABVrqTp0QABVguNTA5AAACETCCAg0wggG3oAMC" + + "AQICAQIwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQK" + + "DB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlN" + + "ZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBm" + + "ZWVkYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0xNjA4MjQwMzIz" + + "MjRaFw0xNjA4MjQwMzI1MDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UECgwf" + + "VGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBwwJTWVs" + + "Ym91cm5lMREwDwYDVQQIDAhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVl" + + "ZGJhY2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwWjANBgkqhkiG9w0BAQEF" + + "AANJADBGAkEAtKfkYXBXTxapcIKyK+WLaipil5hBm+EocqS9umJs+umQD3ar" + + "+xITnc5d5WVk+rK2VDFloEDGBoh0IOM9ke1+1wIBETANBgkqhkiG9w0BAQsF" + + "AANBAKqAyBtKhOgy4NmjV2fc1JlcM2sQ8rEfZ9+PqJixFAqvKSLl6gASZ0dW" + + "Mrmof6ZkKSjEerwoPOXdKJ1VeqOjMBQAAAACAAVjZXJ0MAAAAVa6k6dCAAVY" + + "LjUwOQAAAhEwggINMIIBt6ADAgECAgEBMA0GCSqGSIb3DQEBCwUAMIGPMQsw" + + "CQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5" + + "IENhc3RsZTESMBAGA1UEBwwJTWVsYm91cm5lMREwDwYDVQQIDAhWaWN0b3Jp" + + "YTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3Rs" + + "ZS5vcmcwHhcNMTYwODI0MDMyMzI0WhcNMTYwODI0MDMyNTA0WjCBjzELMAkG" + + "A1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBD" + + "YXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWEx" + + "LzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUu" + + "b3JnMFowDQYJKoZIhvcNAQEBBQADSQAwRgJBALSn5GFwV08WqXCCsivli2oq" + + "YpeYQZvhKHKkvbpibPrpkA92q/sSE53OXeVlZPqytlQxZaBAxgaIdCDjPZHt" + + "ftcCAREwDQYJKoZIhvcNAQELBQADQQAlNXGzWfJmbvK4blA3GCHRO4BMc9of" + + "9LOKSnZdIHpdxkLqoxqWhAbph3zqhDYOe6SuRR1ZZoOnbKVICqm9W1ps967o" + + "ndfs5jZEtLNpj106EQT4x9U="); static final char[] JKS_TEST_PWD = "jkstest".toCharArray(); private static final byte[] repeatedLocalKeyIdPfx = Base64.decode( "MIISUQIBAzCCEhcGCSqGSIb3DQEHAaCCEggEghIEMIISADCCCDcGCSqGSIb3" - + "DQEHBqCCCCgwgggkAgEAMIIIHQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYw" - + "DgQICxSuOGaRUU4CAggAgIIH8EeSXfPe3pE5Dzzhpdd1OyFTfQnAMDBkTpxh" - + "TYnvxZc9uKGmMils1HHS6iKV+VfIyUUvnFoNULy9DIQkkOZK8panWq8ORX+8" - + "VgdJrlxbUGOB/O4MXgAptWpMHsL4Dc4CvIH3iR5oaRLI53e/9X8Y48T/k8Xx" - + "lKTS08lM6AP6rHjCEgKtkj4xVU1m+GZibc52edUtW5Tc3731n4n9kf85XGrx" - + "UJ4+PmwHx0DGjpmBRlAk0/AnQrW4MYIx5tuhR3412M2WaJM2M8pizCcMWVyn" - + "YlBJ8PkgfS3t5Nq2KJNWAnZj54zfINDKaLNL0SnZakN0+DHiMOB+Y7kFIqKD" - + "CM6aUP5LBpWYsZKUkTX6gcOOhz0+nzrtmP4tGL3xGpazrrOoZTrzQDZBVv1y" - + "KOwPoOrv0u44aVoqIXzlAm7VEHSsVkLLQouqsmqWagWypAn2zahVMR5rGflG" - + "04IgLGBWIU4hPx59TnxyOUtYn2mGS0pK7Xyim7nHVtCC63OFqy/Pm+4TQkLc" - + "+ZMLs8EdMtXuJSfOE5mMnPPkgwFAjF3MsG8ytjBS1xAdPCqsD4fH6MKeT/fF" - + "A6SFYd8M0btGa30dBRAVF2DNkF0zUwtTYysh6Z25dgxAf6HKYy+SpqMOJJl9" - + "eAGULAjFkB5i/PVDPjk7QuipgfVc35/zde38WAKXkfQuhvn9xkjtplRnhkMV" - + "7Sgvo5Yaaz1Ee8i3VeeR79JXd9UjOSEt62AOb6Isf8hx9v87hcGD4bUQUQNl" - + "zEHcifkEjRecB6EZHKq8MCAkz53bN2Vr6y3ET2ImBdzaYrKLixsTJNELCzbl" - + "L+U8JXJr2RcEUOSPW8mmypvpVV5GPmSi72Qx20raTyLhrVLY4yGt+pdNGqSd" - + "LjegYgSKnYgePXLU8pZVPSCLuZ9Bonv1l2PFPr7dQvrDALk9Q9FYLnAFc7Jf" - + "zYIiaSNAeiFCGvMpjiNIUMS1bqeAv6bnJg7YqFS24M4gztSxxooTY1L3ILLX" - + "aJfkYxPbQAonKgKuOHxUM6RHyxPTLLQCmLa2JeyKDEpC0pC+VL6d6UJyOI0e" - + "o2Lu+Anby5o/fvRtww4pz2yIbMsaEzxMyu+HtWkANo+g3NSxu6VylcrUq/QQ" - + "r5csLC+37eJyi2OKDKMSUPt3vkVk+5yu830oNHCEhn4kHCISC7rDb0QMfb8F" - + "hvmZXILcbmdxsKc+4Lzk4rhrsn2xBu4OL2JKNBYlfIV4n5GfPBBBuMzAC6eX" - + "2OLpaxq/DlbkKzaJtKyj6+npe8CGO/82Yl1OaG6vbLXoSD6DGMR6AHq287tq" - + "aCSiu5J/a33BUo1DfuEFOscXHipLPvkM5JFx7L/0OfvJcioe1VOtrL9sRZ1F" - + "8eWSonj2EEidxy6mDhbFDPMqnPo0ETay+VXNVznzmrW7mtuQ0ZOAZ84DMDUy" - + "JallUgpK1zvwae0sIXdblTN98DGU2hFpXMu9n030BmhkEEJRbKikxpEfWcxI" - + "0j7+276v6Z32C4BpoeGFxpfrpozwJzTBoGlkN408thpB/llqkBSeLtxEnSKO" - + "SbpKquR6kg4FYQwq7pbKQuSjvKztIhdCDanmi+cPNppHyGmbf4yDMtWOLGhU" - + "cLUbdMJ8jWcvDZiKwzB4s1Qka1Z8qVi5VVEPhpzh4E89WqSoRtgLbhkoy8mf" - + "BlptXBWggXs+eR/s2YXb3nF2ZPnYQcn1+alCMM8aXf9HEeaFGEsEAsANglu9" - + "lnlaGFLbzIeGwkpGFLVlj9Fd+s+a6OVmeaPCa1cZaTKzdC6FqHd3bxalLBc8" - + "fDcbJPDYsTYFEajw648HG3x3oyk+P5WOa9ULup6emu/zOhH5VPJcj9CniLqq" - + "EZDaIDPRqu0g5MZir0EdXL6FvRU2o7W8JE7fzSYxlAWcUbuY6TdaGO7SOvxq" - + "oRKpsIzcmBLpw1t5djii/SohQR/2mJhvqETWvOerfEQr3vXnwurVUC1u/vEO" - + "lCqCRNLH0qzQUFrwzm/kMWsaDMb85XYQpZ+StT6n5AHWNWuQG3bmZIjAY9R9" - + "AbPWi/eSYQF/1E4qZ6WE+S2VOg3i/iVT0MtJzuGXRl1rycZv2vPiskEvVGhT" - + "DbqPWapGugbXLIne6b0C83EtK9H8s/TdDcRupjzW9J/8+p8+DJROgg6y2wIm" - + "SiUKHMZsuU9+e5+z87HVB9t2y0RsARJdbB9NhuTZk7ELztNponTMdJmUyIT0" - + "phdz3U9MFEWnHccMMGo3KqopOsrGT9YqdcBSSfSOyckVBQzgzVt8ypWqusW5" - + "j53OudlwcoudmOTdUfYoEuDWGYgoGqSEOnaU8dqkl4ZffYUIeJuTwclJd9N+" - + "onB82b5FpzXo+sO6DWpNJ8lGE2mOqt4H/HvRwTJ5pfXlZSmGom4eq+WU6XfB" - + "CRE6ehopnU91wey0/lceYPshOQriqoVE577xJKU3zWuWzFwBvanrN2YxptdV" - + "xNiKabM3UmSxgGtxITEb1pCAGBTZzBL175CvmBF6VyamVe4YH7wuQ+C2jEle" - + "xH6xo+1eWyPT5L5CSVFgiJpxX2WoI/8qvnSdagJW0+IQWk1nfNJb2aNbBu4z" - + "Iw6txeGxtQHPhF5eyVgRDE6OannycbSOJMi14q8n4zhyJebsY1wldB31XOFV" - + "pnCRNUcMcueAMioxliO7K81O8SiQVbIyVsc2GYQqhevdDHwj2azat60kNytq" - + "nimsplgyD84oeMMwaqbciAOItPbdqbz7zGIwggnBBgkqhkiG9w0BBwGgggmy" - + "BIIJrjCCCaowggmmBgsqhkiG9w0BDAoBAqCCCW4wgglqMBwGCiqGSIb3DQEM" - + "AQMwDgQIGF7xpMpvXmgCAggABIIJSD9TY2dCx+BYL555TLN51ksuTf1NkXjD" - + "Az1uymDqjoQ1R67CbcHU2qPKwIW3fZT7OmpiPI8cgogKBvcFnngmfeuvZYST" - + "gOW2iD83m5PlaoIa2iXjqdPdCQF9rVwkBg6VUYWlVd9qR0LPKT3u3UsScN2d" - + "qPeeSVRL8W4ESR6OMgiEIts50cjUwb2acqy3So9LZU77/D6uynj5+iFwYxlb" - + "yX/70oegWqMZyiZfvGT1UNMQxF/hs0E7ZGW1RnWjixVI+p3Pvqw36mH9j3Xn" - + "ms5Eg4mhbyBXRPIsq3/95O5NRh84R9atvR+zn1Pd59DKIUVf11w6HZoNOtH+" - + "XrVG7MpLVFIbgxZWzr6JIOK7/bMkJi+aBwSfm3yR6U46XDYlDHfSeeL/xJFm" - + "0QSNf6S/K7lj+AwAoOrruaxXwHxO1zlaXGo8R8P5JVgr7/mbsMF2RnXp3JrW" - + "KIC5LsePgyy6bYBdFwbJZ/FQVFp0zCnByUvPP8xS9+TdZKvp9u6rgIzNCPFK" - + "m1f9XkgJhIn4TEgRVp/OGYbUX2g4Gbm15TUUwyXUFsas224Cyv2RwrzpKNXv" - + "SpriMdXtbEIzt6IRKH6oB1x5QbPz7cJhKL8pbhOUnjSourJC5S8LgazqyKaS" - + "VIon108lGcq6xJJKySxsA74luILEpQyTgZfpSUblCeRcOMdXW0OA+K6PhXqa" - + "e1EzWHo6F7iMTi0SSZ/XOV6Px9xV3e2vRXSt13+pzTpRZKpzVHjpkiWz7xYt" - + "NI2Vq+4LB/ZCi3jhJLYoRYSP9XEf2ilfplK4rGD8tIEDTkFLnKv8oKA+dnwX" - + "VNxKoJQnPuYLTDCU/KfODU4gAyefuTCH/8iAry/6UhOM9Pr50boQJ9KK5Ckz" - + "lkptnLqP6vCSFexkETdh+Vx2Jf87EmytpUhJXS1i2EOjihWH0hEUknEip7km" - + "a1m489qAMUzOMZ2RaIu0p/gDGlLkLem2yv6AOFcqBpQWo0yc4HaPf1Op06/7" - + "ZkykXPyekYI0kKKMrILrW7XifSyvAaPiuXIRzH7GpRIoPmNEEnm3jSpPfkZo" - + "ttCWxzktVVFD2ACTQXV6uDH6eiOrZpMtrg6tOqfbgdGkohfjLtnSjjfhAgTg" - + "N+Tb7w9FgGMZjvrA9Ht50m1iqGg25la5jBfCaD1ZOoAWe1mhRiWVFuEuVewb" - + "dA1hny6OSXxc+5v6pyXKYodMDjYW8m3hhgQfxo1vAoOIy9UWiZ+kVQbw68MO" - + "G7mOYw4WKKDPw4LaiPVSexmu08mYJXiOU+mNlvv0GseQ6gK+sDsQKiPa8KGi" - + "JllcaKnJ9qmO0ff5IZ2bDyAESkUgwb9CaT7yjTz+z78Q/IcAVafYLkbJb4FZ" - + "UFUTsLfw172NW1MzTeyfHe9YtZsOUuViuFLrKoWO8fDRYcA65J30C1S8P3bU" - + "aauukUZBoFndn6sz0DH6z+YLOjvoAlyze+692saz6OPf8iYPacq25i44He2v" - + "sRpbqrWw3Xn1fcd2WQABQ4Ig4sntuuvG6ZYFl9//8ZtNfe6hS9iZzyP4CPiz" - + "Q9cD15Xln24gW2EZuJ6yfgiK8AYfZIUmGu0fUO4x5kPNbkIEdb+a2HYDb4rs" - + "m8dFVKCKDPOjEojkfFz3DXycQn79xOxs7HEg7GZtV6/jnu0tel2qHQNBPM2i" - + "1RWHfiC+/kKWmiQlwbSYzyFcbwcPYMzGVcbJoL/SidqxcD4PeD7PnPmAHzy9" - + "2rvGPu6m0/7HhjsMicG/fyfczY+SPSkxoxa2N46yS397tKbUVJ9SfUATJ0vM" - + "YqnqqgKQTd0MzdQNcNOE6EozK3kCTV+6xjs1aSvwB51gp03vcw+Ln0mW4Dfd" - + "mM+HwFre9w37DJBajEXbzkI6aHApCQdN6VexsaSyxFewwavTqwmVeSTIflpa" - + "s2lFbJmLbMDcdgiIHyvOygg0oXy1JuFScuBZ4T21kcTAEX/hFPfLTGTUXeBA" - + "hMY+gkdol/IB9gNPL23KLskXv4+Z9sCVheG3eAi4qeLgkqr86L8aIYa0Akdl" - + "UnxREE0/sDeiqaV+fg/cHGa51YRVHhyG4/+//PQ46xW5ORhGnOSs7UHZB1XK" - + "5ROgOFDe1HpKhQwWbFEaMY+CLSBFDNmMZiaoArf1r5qIqwG6fy++T0f7plDm" - + "CdoZcV5IyIwmVwzZu6mMz7MRPEBYH/WitC/lP4jdtHqtHqKtPT+NXHzh2A/c" - + "tl3nOSR5RnDKzL7kUVXheL2cES+41jZ1LBy9T3ZxXd59Tf8IdC1JJ24pHmzJ" - + "KZNYxIr+rREvIxZsNvJI2urefS2/55AZCVC58hahjS4DWPzpxMkRb5xkL8L8" - + "Yt8OikvdsazHuamTlh2tggCiQ3LDqXtG+sk67UZQycWis0vG6pd6S+E6K4Sn" - + "mymsn/CbsSqr8rVd/JppqmYnPPmzkEw0oztNW2pNzfui+vvr6gFV81cWIdFt" - + "TOWlXSzOAwm7/Dj8kSYyIxZVrHsRCbnSdkmP0timKpBkGN+CCHsibzl0RJHj" - + "IIznWLUBCnwxUwLJCdo6qTZoOhegDYZFVgk4eExiL26XJjbLJj25tB+ITBiI" - + "RwR52Mxf9zoX3V8I1OCnvznt0fE5NBTob0LDXoqGy1PlTJv+8DKrI4Vzgk9/" - + "yDjMw/NJgimQS97cxU9CxnQO7FmCEnEeB/E9kniml5EGLEod3Ugf6ElcuADn" - + "Kp4E1cijOiRdHPX6vnxjw0n0OHpOpaCf9ynWF5fVXNoAofqTB7nGMn1YPJUo" - + "gl2pDlX6Z5dTZ1IyoOAxkOLTKH6ULY91wnPgC1k8LoOKAWJOtcdxBai+rxGe" - + "Nw6pYsl6L0ViIBsVHOlg+JEFtVEhL9vUuv9NcqWu6swt/bV84rU993vPj1FR" - + "bPasRjTBAIwJ4KVvQHtXg0bta8vWFIt7hOSjpKD+Fe8c59oZcmvmfCWo1yJE" - + "YMGZETkP58SlGtVUMOXYZxEzLe1OG2icd8guZ4d/DeCLv6JuO2q958UdM1I6" - + "yO8+1r1w6nzsTwaXZn0htKYbC8dYIl7jJK/5y/ITZWSJl5BbtoUXlVuz/GGx" - + "vllOfG+H/iSr3wQ8Meue+9zh1l+gdH10dWlLCjot0ri8e/xKU9ZaRt6dlHka" - + "c8Nh1U30ZrMBooXYBZmA/0+Ntz5WIEh6GQKeWV/ZwtOZdfGsYzC1L9t3Xknu" - + "GxVjEfV1l7b9Fx5j5jElMCMGCSqGSIb3DQEJFTEWBBRFy/ERb7PziymEs8ci" - + "TK5wp093iTAxMCEwCQYFKw4DAhoFAAQU1SGg9xV7jfLcJh3tzd+phZTMN38E" - + "CL6WgCtEom7kAgIIAA=="); - + + "DQEHBqCCCCgwgggkAgEAMIIIHQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYw" + + "DgQICxSuOGaRUU4CAggAgIIH8EeSXfPe3pE5Dzzhpdd1OyFTfQnAMDBkTpxh" + + "TYnvxZc9uKGmMils1HHS6iKV+VfIyUUvnFoNULy9DIQkkOZK8panWq8ORX+8" + + "VgdJrlxbUGOB/O4MXgAptWpMHsL4Dc4CvIH3iR5oaRLI53e/9X8Y48T/k8Xx" + + "lKTS08lM6AP6rHjCEgKtkj4xVU1m+GZibc52edUtW5Tc3731n4n9kf85XGrx" + + "UJ4+PmwHx0DGjpmBRlAk0/AnQrW4MYIx5tuhR3412M2WaJM2M8pizCcMWVyn" + + "YlBJ8PkgfS3t5Nq2KJNWAnZj54zfINDKaLNL0SnZakN0+DHiMOB+Y7kFIqKD" + + "CM6aUP5LBpWYsZKUkTX6gcOOhz0+nzrtmP4tGL3xGpazrrOoZTrzQDZBVv1y" + + "KOwPoOrv0u44aVoqIXzlAm7VEHSsVkLLQouqsmqWagWypAn2zahVMR5rGflG" + + "04IgLGBWIU4hPx59TnxyOUtYn2mGS0pK7Xyim7nHVtCC63OFqy/Pm+4TQkLc" + + "+ZMLs8EdMtXuJSfOE5mMnPPkgwFAjF3MsG8ytjBS1xAdPCqsD4fH6MKeT/fF" + + "A6SFYd8M0btGa30dBRAVF2DNkF0zUwtTYysh6Z25dgxAf6HKYy+SpqMOJJl9" + + "eAGULAjFkB5i/PVDPjk7QuipgfVc35/zde38WAKXkfQuhvn9xkjtplRnhkMV" + + "7Sgvo5Yaaz1Ee8i3VeeR79JXd9UjOSEt62AOb6Isf8hx9v87hcGD4bUQUQNl" + + "zEHcifkEjRecB6EZHKq8MCAkz53bN2Vr6y3ET2ImBdzaYrKLixsTJNELCzbl" + + "L+U8JXJr2RcEUOSPW8mmypvpVV5GPmSi72Qx20raTyLhrVLY4yGt+pdNGqSd" + + "LjegYgSKnYgePXLU8pZVPSCLuZ9Bonv1l2PFPr7dQvrDALk9Q9FYLnAFc7Jf" + + "zYIiaSNAeiFCGvMpjiNIUMS1bqeAv6bnJg7YqFS24M4gztSxxooTY1L3ILLX" + + "aJfkYxPbQAonKgKuOHxUM6RHyxPTLLQCmLa2JeyKDEpC0pC+VL6d6UJyOI0e" + + "o2Lu+Anby5o/fvRtww4pz2yIbMsaEzxMyu+HtWkANo+g3NSxu6VylcrUq/QQ" + + "r5csLC+37eJyi2OKDKMSUPt3vkVk+5yu830oNHCEhn4kHCISC7rDb0QMfb8F" + + "hvmZXILcbmdxsKc+4Lzk4rhrsn2xBu4OL2JKNBYlfIV4n5GfPBBBuMzAC6eX" + + "2OLpaxq/DlbkKzaJtKyj6+npe8CGO/82Yl1OaG6vbLXoSD6DGMR6AHq287tq" + + "aCSiu5J/a33BUo1DfuEFOscXHipLPvkM5JFx7L/0OfvJcioe1VOtrL9sRZ1F" + + "8eWSonj2EEidxy6mDhbFDPMqnPo0ETay+VXNVznzmrW7mtuQ0ZOAZ84DMDUy" + + "JallUgpK1zvwae0sIXdblTN98DGU2hFpXMu9n030BmhkEEJRbKikxpEfWcxI" + + "0j7+276v6Z32C4BpoeGFxpfrpozwJzTBoGlkN408thpB/llqkBSeLtxEnSKO" + + "SbpKquR6kg4FYQwq7pbKQuSjvKztIhdCDanmi+cPNppHyGmbf4yDMtWOLGhU" + + "cLUbdMJ8jWcvDZiKwzB4s1Qka1Z8qVi5VVEPhpzh4E89WqSoRtgLbhkoy8mf" + + "BlptXBWggXs+eR/s2YXb3nF2ZPnYQcn1+alCMM8aXf9HEeaFGEsEAsANglu9" + + "lnlaGFLbzIeGwkpGFLVlj9Fd+s+a6OVmeaPCa1cZaTKzdC6FqHd3bxalLBc8" + + "fDcbJPDYsTYFEajw648HG3x3oyk+P5WOa9ULup6emu/zOhH5VPJcj9CniLqq" + + "EZDaIDPRqu0g5MZir0EdXL6FvRU2o7W8JE7fzSYxlAWcUbuY6TdaGO7SOvxq" + + "oRKpsIzcmBLpw1t5djii/SohQR/2mJhvqETWvOerfEQr3vXnwurVUC1u/vEO" + + "lCqCRNLH0qzQUFrwzm/kMWsaDMb85XYQpZ+StT6n5AHWNWuQG3bmZIjAY9R9" + + "AbPWi/eSYQF/1E4qZ6WE+S2VOg3i/iVT0MtJzuGXRl1rycZv2vPiskEvVGhT" + + "DbqPWapGugbXLIne6b0C83EtK9H8s/TdDcRupjzW9J/8+p8+DJROgg6y2wIm" + + "SiUKHMZsuU9+e5+z87HVB9t2y0RsARJdbB9NhuTZk7ELztNponTMdJmUyIT0" + + "phdz3U9MFEWnHccMMGo3KqopOsrGT9YqdcBSSfSOyckVBQzgzVt8ypWqusW5" + + "j53OudlwcoudmOTdUfYoEuDWGYgoGqSEOnaU8dqkl4ZffYUIeJuTwclJd9N+" + + "onB82b5FpzXo+sO6DWpNJ8lGE2mOqt4H/HvRwTJ5pfXlZSmGom4eq+WU6XfB" + + "CRE6ehopnU91wey0/lceYPshOQriqoVE577xJKU3zWuWzFwBvanrN2YxptdV" + + "xNiKabM3UmSxgGtxITEb1pCAGBTZzBL175CvmBF6VyamVe4YH7wuQ+C2jEle" + + "xH6xo+1eWyPT5L5CSVFgiJpxX2WoI/8qvnSdagJW0+IQWk1nfNJb2aNbBu4z" + + "Iw6txeGxtQHPhF5eyVgRDE6OannycbSOJMi14q8n4zhyJebsY1wldB31XOFV" + + "pnCRNUcMcueAMioxliO7K81O8SiQVbIyVsc2GYQqhevdDHwj2azat60kNytq" + + "nimsplgyD84oeMMwaqbciAOItPbdqbz7zGIwggnBBgkqhkiG9w0BBwGgggmy" + + "BIIJrjCCCaowggmmBgsqhkiG9w0BDAoBAqCCCW4wgglqMBwGCiqGSIb3DQEM" + + "AQMwDgQIGF7xpMpvXmgCAggABIIJSD9TY2dCx+BYL555TLN51ksuTf1NkXjD" + + "Az1uymDqjoQ1R67CbcHU2qPKwIW3fZT7OmpiPI8cgogKBvcFnngmfeuvZYST" + + "gOW2iD83m5PlaoIa2iXjqdPdCQF9rVwkBg6VUYWlVd9qR0LPKT3u3UsScN2d" + + "qPeeSVRL8W4ESR6OMgiEIts50cjUwb2acqy3So9LZU77/D6uynj5+iFwYxlb" + + "yX/70oegWqMZyiZfvGT1UNMQxF/hs0E7ZGW1RnWjixVI+p3Pvqw36mH9j3Xn" + + "ms5Eg4mhbyBXRPIsq3/95O5NRh84R9atvR+zn1Pd59DKIUVf11w6HZoNOtH+" + + "XrVG7MpLVFIbgxZWzr6JIOK7/bMkJi+aBwSfm3yR6U46XDYlDHfSeeL/xJFm" + + "0QSNf6S/K7lj+AwAoOrruaxXwHxO1zlaXGo8R8P5JVgr7/mbsMF2RnXp3JrW" + + "KIC5LsePgyy6bYBdFwbJZ/FQVFp0zCnByUvPP8xS9+TdZKvp9u6rgIzNCPFK" + + "m1f9XkgJhIn4TEgRVp/OGYbUX2g4Gbm15TUUwyXUFsas224Cyv2RwrzpKNXv" + + "SpriMdXtbEIzt6IRKH6oB1x5QbPz7cJhKL8pbhOUnjSourJC5S8LgazqyKaS" + + "VIon108lGcq6xJJKySxsA74luILEpQyTgZfpSUblCeRcOMdXW0OA+K6PhXqa" + + "e1EzWHo6F7iMTi0SSZ/XOV6Px9xV3e2vRXSt13+pzTpRZKpzVHjpkiWz7xYt" + + "NI2Vq+4LB/ZCi3jhJLYoRYSP9XEf2ilfplK4rGD8tIEDTkFLnKv8oKA+dnwX" + + "VNxKoJQnPuYLTDCU/KfODU4gAyefuTCH/8iAry/6UhOM9Pr50boQJ9KK5Ckz" + + "lkptnLqP6vCSFexkETdh+Vx2Jf87EmytpUhJXS1i2EOjihWH0hEUknEip7km" + + "a1m489qAMUzOMZ2RaIu0p/gDGlLkLem2yv6AOFcqBpQWo0yc4HaPf1Op06/7" + + "ZkykXPyekYI0kKKMrILrW7XifSyvAaPiuXIRzH7GpRIoPmNEEnm3jSpPfkZo" + + "ttCWxzktVVFD2ACTQXV6uDH6eiOrZpMtrg6tOqfbgdGkohfjLtnSjjfhAgTg" + + "N+Tb7w9FgGMZjvrA9Ht50m1iqGg25la5jBfCaD1ZOoAWe1mhRiWVFuEuVewb" + + "dA1hny6OSXxc+5v6pyXKYodMDjYW8m3hhgQfxo1vAoOIy9UWiZ+kVQbw68MO" + + "G7mOYw4WKKDPw4LaiPVSexmu08mYJXiOU+mNlvv0GseQ6gK+sDsQKiPa8KGi" + + "JllcaKnJ9qmO0ff5IZ2bDyAESkUgwb9CaT7yjTz+z78Q/IcAVafYLkbJb4FZ" + + "UFUTsLfw172NW1MzTeyfHe9YtZsOUuViuFLrKoWO8fDRYcA65J30C1S8P3bU" + + "aauukUZBoFndn6sz0DH6z+YLOjvoAlyze+692saz6OPf8iYPacq25i44He2v" + + "sRpbqrWw3Xn1fcd2WQABQ4Ig4sntuuvG6ZYFl9//8ZtNfe6hS9iZzyP4CPiz" + + "Q9cD15Xln24gW2EZuJ6yfgiK8AYfZIUmGu0fUO4x5kPNbkIEdb+a2HYDb4rs" + + "m8dFVKCKDPOjEojkfFz3DXycQn79xOxs7HEg7GZtV6/jnu0tel2qHQNBPM2i" + + "1RWHfiC+/kKWmiQlwbSYzyFcbwcPYMzGVcbJoL/SidqxcD4PeD7PnPmAHzy9" + + "2rvGPu6m0/7HhjsMicG/fyfczY+SPSkxoxa2N46yS397tKbUVJ9SfUATJ0vM" + + "YqnqqgKQTd0MzdQNcNOE6EozK3kCTV+6xjs1aSvwB51gp03vcw+Ln0mW4Dfd" + + "mM+HwFre9w37DJBajEXbzkI6aHApCQdN6VexsaSyxFewwavTqwmVeSTIflpa" + + "s2lFbJmLbMDcdgiIHyvOygg0oXy1JuFScuBZ4T21kcTAEX/hFPfLTGTUXeBA" + + "hMY+gkdol/IB9gNPL23KLskXv4+Z9sCVheG3eAi4qeLgkqr86L8aIYa0Akdl" + + "UnxREE0/sDeiqaV+fg/cHGa51YRVHhyG4/+//PQ46xW5ORhGnOSs7UHZB1XK" + + "5ROgOFDe1HpKhQwWbFEaMY+CLSBFDNmMZiaoArf1r5qIqwG6fy++T0f7plDm" + + "CdoZcV5IyIwmVwzZu6mMz7MRPEBYH/WitC/lP4jdtHqtHqKtPT+NXHzh2A/c" + + "tl3nOSR5RnDKzL7kUVXheL2cES+41jZ1LBy9T3ZxXd59Tf8IdC1JJ24pHmzJ" + + "KZNYxIr+rREvIxZsNvJI2urefS2/55AZCVC58hahjS4DWPzpxMkRb5xkL8L8" + + "Yt8OikvdsazHuamTlh2tggCiQ3LDqXtG+sk67UZQycWis0vG6pd6S+E6K4Sn" + + "mymsn/CbsSqr8rVd/JppqmYnPPmzkEw0oztNW2pNzfui+vvr6gFV81cWIdFt" + + "TOWlXSzOAwm7/Dj8kSYyIxZVrHsRCbnSdkmP0timKpBkGN+CCHsibzl0RJHj" + + "IIznWLUBCnwxUwLJCdo6qTZoOhegDYZFVgk4eExiL26XJjbLJj25tB+ITBiI" + + "RwR52Mxf9zoX3V8I1OCnvznt0fE5NBTob0LDXoqGy1PlTJv+8DKrI4Vzgk9/" + + "yDjMw/NJgimQS97cxU9CxnQO7FmCEnEeB/E9kniml5EGLEod3Ugf6ElcuADn" + + "Kp4E1cijOiRdHPX6vnxjw0n0OHpOpaCf9ynWF5fVXNoAofqTB7nGMn1YPJUo" + + "gl2pDlX6Z5dTZ1IyoOAxkOLTKH6ULY91wnPgC1k8LoOKAWJOtcdxBai+rxGe" + + "Nw6pYsl6L0ViIBsVHOlg+JEFtVEhL9vUuv9NcqWu6swt/bV84rU993vPj1FR" + + "bPasRjTBAIwJ4KVvQHtXg0bta8vWFIt7hOSjpKD+Fe8c59oZcmvmfCWo1yJE" + + "YMGZETkP58SlGtVUMOXYZxEzLe1OG2icd8guZ4d/DeCLv6JuO2q958UdM1I6" + + "yO8+1r1w6nzsTwaXZn0htKYbC8dYIl7jJK/5y/ITZWSJl5BbtoUXlVuz/GGx" + + "vllOfG+H/iSr3wQ8Meue+9zh1l+gdH10dWlLCjot0ri8e/xKU9ZaRt6dlHka" + + "c8Nh1U30ZrMBooXYBZmA/0+Ntz5WIEh6GQKeWV/ZwtOZdfGsYzC1L9t3Xknu" + + "GxVjEfV1l7b9Fx5j5jElMCMGCSqGSIb3DQEJFTEWBBRFy/ERb7PziymEs8ci" + + "TK5wp093iTAxMCEwCQYFKw4DAhoFAAQU1SGg9xV7jfLcJh3tzd+phZTMN38E" + + "CL6WgCtEom7kAgIIAA=="); + + private static byte[] rawKeyBagStore = Base64.decode("MIIFlgIBAzCCBY8GCSqGSIb3DQEHAaCCBYAEggV8MIIFeDCCAv4GCSqGSIb3DQEHAaCCAu8EggLrMIIC5zCCAuMGCyqGSIb3DQEMCgEBoIICejCCAnYCAQAwDQYJKoZIhvcNAQEBBQAEggJgMIICXAIBAAKBgQCF4Tw78b8eDuwY+FomQazkPFuAxDbWTs//AozC4MvzBatdJeDu+s9WyK3PdU+gI7wFish0r2FP8M5dj/rA0ieCJ9UDTGWVKm06DB0y7zmAO3SS/3TXGQRekMmOXBtVlZa4AYVy8Tr+Ls69gfo3sgqJU8uH0ebWuoQTKJz/mpst0wIDAQABAoGBAIJbpu/jWylkdEV4BSd9CWCO2LYP2CliQirXC8JxaoTuf0ZKrLNlqd+htYPsgSS3xstKsBbV8hYJrpbxq8J2npok973j0bm9sW9RL8XmAYJbaat27IzQQkGj2j4CNWPJzQC3NsDWQJPMJMFHvT1ZIj5ASwvOHwKpM6haLPxX24o5AkEA/zBVPpO6Ic9Yfd8Fk+BN/DykpPbLMUNZFl/I2MavoXTh5Ng7J4/S5ABxkvvQdqKf1Nhal5CznakU4BjFUGr+dwJBAIZOLwlfToFgekV4SmcPnq4aNGdetDfEettRGJLrKf+qrZrTzW3Rj6N2cjxKHsE5/xOpyjOtgVv3cTQm0x//VoUCQAdQBUFTzmOlo22H9Ir2RIXT3wvzHoN84JKpkAHWP7YquUZrg9ZwYqSx9o81tBWSN25L/NyXAu6jp7t8OjtBtaUCQCILB1k0001wCw4444MkLnCrK8VX+A56uzmEYNo8ybSIquCn91Zy3BnvGB24G/uWm9V8IEjhHf0Vx5gUj0d5DZECQGRs4BMYE+y2Tpn7/zbjhZh/iAdttDq5/b2BBMbSiosSKRIGkOyHTu0SJKoxoDnHA5ryLK8NoSwoGjID5qESjA8xVjAjBgkqhkiG9w0BCRUxFgQU3U3Taaj7rCAV2GyyVEnAUZvc4JkwLwYJKoZIhvcNAQkUMSIeIABPAE4AVgBJAEYAXwBUAGUAcwB0AF8AQQBsAGkAYQBzMIICcgYJKoZIhvcNAQcBoIICYwSCAl8wggJbMIICVwYLKoZIhvcNAQwKAQOgggHuMIIB6gYKKoZIhvcNAQkWAaCCAdoEggHWMIIB0jCCATugAwIBAgIICNurBKCCK6gwDQYJKoZIhvcNAQEFBQAwIDERMA8GA1UEAwwIT05WSUYgVFQxCzAJBgNVBAYTAlVTMCAXDTcwMDEwMTAwMDAwMFoYDzk5OTkxMjMxMjM1OTU5WjAgMREwDwYDVQQDDAhPTlZJRiBUVDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIXhPDvxvx4O7Bj4WiZBrOQ8W4DENtZOz/8CjMLgy/MFq10l4O76z1bIrc91T6AjvAWKyHSvYU/wzl2P+sDSJ4In1QNMZZUqbToMHTLvOYA7dJL/dNcZBF6QyY5cG1WVlrgBhXLxOv4uzr2B+jeyColTy4fR5ta6hBMonP+amy3TAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEARmnQ9q/lUycK5P4shGFlwK0Uy3dHZs4VxOBSinejSTTy1FL4+SRzwA+YDMmfRrI0WHY/upUCYyugDj5kDg5K6/mSiIWGr0PDjl+8qw352fpUQgY4vnpGBaJoLQf/KRFilVhZJz0QDq5iHo16UkibDDHYQqdt6la5SHKx4U6AJwYxVjAjBgkqhkiG9w0BCRUxFgQU3U3Taaj7rCAV2GyyVEnAUZvc4JkwLwYJKoZIhvcNAQkUMSIeIABPAE4AVgBJAEYAXwBUAGUAcwB0AF8AQQBsAGkAYQBz"); + /** * we generate a self signed certificate for the sake of testing - RSA */ public Certificate createCert( - PublicKey pubKey, - PrivateKey privKey, - String issuerEmail, - String subjectEmail) + PublicKey pubKey, + PrivateKey privKey, + String issuerEmail, + String subjectEmail) throws Exception { // @@ -988,7 +995,7 @@ private void testCertsOnly() isTrue(pkcs12.containsAlias("alias")); - pkcs12.load(new ByteArrayInputStream(certsOnly), new char[] {}); + pkcs12.load(new ByteArrayInputStream(certsOnly), new char[]{}); isTrue(pkcs12.containsAlias("alias")); @@ -1003,11 +1010,12 @@ private void testCertsOnly() } System.setProperty("org.bouncycastle.pkcs12.ignore_useless_passwd", "true"); - + pkcs12.load(new ByteArrayInputStream(certsOnly), "1".toCharArray()); System.setProperty("org.bouncycastle.pkcs12.ignore_useless_passwd", "false"); } + private void testGOSTStore() throws Exception { @@ -1084,21 +1092,175 @@ private void testGOSTStore() isEquals(pk, pk2); } + private void testDilithiumStore() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-DSA", "BC"); + + kpg.initialize(MLDSAParameterSpec.ml_dsa_65); + + KeyPair kp = kpg.generateKeyPair(); + + Certificate cert = TestUtils.createSelfSignedCert("CN=Dilithium Test", "ML-DSA-65", kp); + + KeyStore pkcs12 = KeyStore.getInstance("PKCS12", BC); + + pkcs12.load(null, null); + + pkcs12.setKeyEntry("test", kp.getPrivate(), new char[0], new Certificate[]{cert}); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + pkcs12.store(bOut, "hello".toCharArray()); + + pkcs12 = KeyStore.getInstance("PKCS12", BC); + + pkcs12.load(new ByteArrayInputStream(bOut.toByteArray()), "hello".toCharArray()); + + Key key = pkcs12.getKey("test", new char[0]); + + isEquals(key, kp.getPrivate()); + + Certificate[] certs = pkcs12.getCertificateChain("test"); + + certs[0].verify(certs[0].getPublicKey()); + } + + private void testRawKeyBagStore() + throws Exception + { + KeyStore store = KeyStore.getInstance("PKCS12", "BC"); + + store.load(new ByteArrayInputStream(rawKeyBagStore), null); + + isTrue(store.isKeyEntry("ONVIF_Test_Alias")); + } + + private void testNTRUStore() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BC"); + + kpg.initialize(FalconParameterSpec.falcon_512); + + KeyPair skp = kpg.generateKeyPair(); + + kpg = KeyPairGenerator.getInstance("NTRU", "BC"); + + kpg.initialize(NTRUParameterSpec.ntruhrss701); + + KeyPair kp = kpg.generateKeyPair(); + + Certificate cert = TestUtils.createCert(new X500Name("CN=Falcon Signer"), skp.getPrivate(), new X500Name("CN=NTRU Key"), "Falcon-512", null, kp.getPublic()); + + KeyStore pkcs12 = KeyStore.getInstance("PKCS12", BC); + + pkcs12.load(null, null); + + pkcs12.setKeyEntry("test", kp.getPrivate(), new char[0], new Certificate[]{cert}); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + pkcs12.store(bOut, "hello".toCharArray()); + + pkcs12 = KeyStore.getInstance("PKCS12", BC); + + pkcs12.load(new ByteArrayInputStream(bOut.toByteArray()), "hello".toCharArray()); + + Key key = pkcs12.getKey("test", new char[0]); + + isEquals(key, kp.getPrivate()); + + Certificate[] certs = pkcs12.getCertificateChain("test"); + + certs[0].verify(skp.getPublic()); + + isEquals(certs[0].getPublicKey(), kp.getPublic()); + } + + private void testFalconStore() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BC"); + + kpg.initialize(FalconParameterSpec.falcon_512); + + KeyPair kp = kpg.generateKeyPair(); + + Certificate cert = TestUtils.createSelfSignedCert("CN=Falcon Test", "Falcon-512", kp); + + KeyStore pkcs12 = KeyStore.getInstance("PKCS12", BC); + + pkcs12.load(null, null); + + pkcs12.setKeyEntry("test", kp.getPrivate(), new char[0], new Certificate[]{cert}); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + pkcs12.store(bOut, "hello".toCharArray()); + + pkcs12 = KeyStore.getInstance("PKCS12", BC); + + pkcs12.load(new ByteArrayInputStream(bOut.toByteArray()), "hello".toCharArray()); + + Key key = pkcs12.getKey("test", new char[0]); + + isEquals(key, kp.getPrivate()); + + Certificate[] certs = pkcs12.getCertificateChain("test"); + + certs[0].verify(certs[0].getPublicKey()); + } + + private void testSphincsPlusStore() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCS+", "BC"); + + kpg.initialize(SPHINCSPlusParameterSpec.sha2_128f_robust); + + KeyPair kp = kpg.generateKeyPair(); + + Certificate cert = TestUtils.createSelfSignedCert("CN=SphincsPlus Test", "SPHINCS+", kp); + + KeyStore pkcs12 = KeyStore.getInstance("PKCS12", BC); + + pkcs12.load(null, null); + + pkcs12.setKeyEntry("test", kp.getPrivate(), new char[0], new Certificate[]{cert}); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + pkcs12.store(bOut, "hello".toCharArray()); + + pkcs12 = KeyStore.getInstance("PKCS12", BC); + + pkcs12.load(new ByteArrayInputStream(bOut.toByteArray()), "hello".toCharArray()); + + Key key = pkcs12.getKey("test", new char[0]); + + isEquals(key, kp.getPrivate()); + + Certificate[] certs = pkcs12.getCertificateChain("test"); + + certs[0].verify(certs[0].getPublicKey()); + } + public void testPKCS12Store() throws Exception { - BigInteger mod = new BigInteger("bb1be8074e4787a8d77967f1575ef72dd7582f9b3347724413c021beafad8f32dba5168e280cbf284df722283dad2fd4abc750e3d6487c2942064e2d8d80641aa5866d1f6f1f83eec26b9b46fecb3b1c9856a303148a5cc899c642fb16f3d9d72f52526c751dc81622c420c82e2cfda70fe8d13f16cc7d6a613a5b2a2b5894d1", 16); + BigInteger mod = new BigInteger("bb1be8074e4787a8d77967f1575ef72dd7582f9b3347724413c021beafad8f32dba5168e280cbf284df722283dad2fd4abc750e3d6487c2942064e2d8d80641aa5866d1f6f1f83eec26b9b46fecb3b1c9856a303148a5cc899c642fb16f3d9d72f52526c751dc81622c420c82e2cfda70fe8d13f16cc7d6a613a5b2a2b5894d1", 16); KeyStore store = KeyStore.getInstance("PKCS12", BC); ByteArrayInputStream stream = new ByteArrayInputStream(pkcs12); store.load(stream, passwd); Enumeration en = store.aliases(); - String pName = null; + String pName = null; while (en.hasMoreElements()) { - String n = (String)en.nextElement(); + String n = (String)en.nextElement(); if (store.isKeyEntry(n)) { pName = n; @@ -1124,7 +1286,7 @@ public void testPKCS12Store() fail("Modulus doesn't match."); } - Certificate[] ch = store.getCertificateChain(pName); + Certificate[] ch = store.getCertificateChain(pName); if (ch.length != 3) { @@ -1258,11 +1420,11 @@ public void testPKCS12Store() { fail("Failed deletion test."); } - + // cert chain test // store.setCertificateEntry("testCert", ch[2]); - + if (store.getCertificateChain("testCert") != null) { fail("Failed null chain test."); @@ -1301,12 +1463,12 @@ public void testPKCS12Store() // // set up the keys // - PrivateKey privKey = null; - PublicKey pubKey = null; + PrivateKey privKey = null; + PublicKey pubKey = null; try { - KeyFactory fact = KeyFactory.getInstance("RSA", BC); + KeyFactory fact = KeyFactory.getInstance("RSA", BC); privKey = fact.generatePrivate(privKeySpec); pubKey = fact.generatePublic(pubKeySpec); @@ -1327,22 +1489,22 @@ public void testPKCS12Store() store.load(null, null); store.setKeyEntry("privateKey", privKey, null, chain); - + if (!store.containsAlias("privateKey") || !store.containsAlias("PRIVATEKEY")) { fail("couldn't find alias privateKey"); } - + if (store.isCertificateEntry("privateKey")) { fail("key identified as certificate entry"); } - + if (!store.isKeyEntry("privateKey") || !store.isKeyEntry("PRIVATEKEY")) { fail("key not identified as key entry"); } - + if (!"privateKey".equals(store.getCertificateAlias(chain[0]))) { fail("Did not return alias for key certificate privateKey"); @@ -1389,7 +1551,7 @@ public void testPKCS12Store() ASN1Encodable keyUsageValue3 = usage3.getBagAttribute(MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage); - isEquals(new DERSet(new ASN1Encodable[] { KeyPurposeId.id_kp_capwapAC, KeyPurposeId.id_kp_capwapWTP }), keyUsageValue3); + isEquals(new DERSet(new ASN1Encodable[]{KeyPurposeId.id_kp_capwapAC, KeyPurposeId.id_kp_capwapWTP}), keyUsageValue3); // // no friendly name test @@ -1404,33 +1566,33 @@ public void testPKCS12Store() while (en.hasMoreElements()) { - String n = (String)en.nextElement(); + String n = (String)en.nextElement(); - if (store.isKeyEntry(n)) - { - pName = n; - } + if (store.isKeyEntry(n)) + { + pName = n; + } } - + ch = store.getCertificateChain(pName); for (int i = 0; i != ch.length; i++) { //System.out.println(ch[i]); } - + if (ch.length != 1) { fail("no cert found in pkcs12noFriendly"); } - + // // failure tests // ch = store.getCertificateChain("dummy"); store.getCertificateChain("DUMMY"); - + store.getCertificate("dummy"); store.getCertificate("DUMMY"); @@ -1448,14 +1610,14 @@ public void testPKCS12Store() while (en.hasMoreElements()) { - String n = (String)en.nextElement(); + String n = (String)en.nextElement(); - if (store.isKeyEntry(n)) - { - pName = n; - } + if (store.isKeyEntry(n)) + { + pName = n; + } } - + ch = store.getCertificateChain(pName); if (ch.length != 2) { @@ -1463,32 +1625,32 @@ public void testPKCS12Store() } store.store(new ByteArrayOutputStream(), storagePassword); - + // // basic certificate check // store.setCertificateEntry("cert", ch[1]); - + if (!store.containsAlias("cert") || !store.containsAlias("CERT")) { fail("couldn't find alias cert"); } - + if (!store.isCertificateEntry("cert") || !store.isCertificateEntry("CERT")) { fail("cert not identified as certificate entry"); } - + if (store.isKeyEntry("cert") || store.isKeyEntry("CERT")) { fail("cert identified as key entry"); } - + if (!store.entryInstanceOf("cert", KeyStore.TrustedCertificateEntry.class)) { fail("cert not identified as TrustedCertificateEntry"); } - + if (!store.entryInstanceOf("CERT", KeyStore.TrustedCertificateEntry.class)) { fail("CERT not identified as TrustedCertificateEntry"); @@ -1498,7 +1660,7 @@ public void testPKCS12Store() { fail("cert identified as key entry via PrivateKeyEntry"); } - + if (!"cert".equals(store.getCertificateAlias(ch[1]))) { fail("Did not return alias for certificate entry"); @@ -1508,47 +1670,47 @@ public void testPKCS12Store() // test restoring of a certificate with private key originally as a ca certificate // store = KeyStore.getInstance("PKCS12", BC); - + store.load(null, null); - + store.setCertificateEntry("cert", ch[0]); if (!store.containsAlias("cert") || !store.containsAlias("CERT")) { fail("restore: couldn't find alias cert"); } - + if (!store.isCertificateEntry("cert") || !store.isCertificateEntry("CERT")) { fail("restore: cert not identified as certificate entry"); } - + if (store.isKeyEntry("cert") || store.isKeyEntry("CERT")) { fail("restore: cert identified as key entry"); } - + if (store.entryInstanceOf("cert", KeyStore.PrivateKeyEntry.class)) { fail("restore: cert identified as key entry via PrivateKeyEntry"); } - + if (store.entryInstanceOf("CERT", KeyStore.PrivateKeyEntry.class)) { fail("restore: cert identified as key entry via PrivateKeyEntry"); } - + if (!store.entryInstanceOf("cert", KeyStore.TrustedCertificateEntry.class)) { fail("restore: cert not identified as TrustedCertificateEntry"); } - + // // test of reading incorrect zero-length encoding // store = KeyStore.getInstance("PKCS12", BC); stream = new ByteArrayInputStream(pkcs12nopass); - + store.load(stream, "".toCharArray()); } @@ -1707,7 +1869,7 @@ private void testNoExtraLocalKeyID(byte[] store1data) KeyStore store2 = KeyStore.getInstance("PKCS12", BC); store2.load(null, null); - + PrivateKey k1 = (PrivateKey)store1.getKey("privatekey", null); Certificate[] chain1 = store1.getCertificateChain("privatekey"); @@ -1721,7 +1883,7 @@ private void testNoExtraLocalKeyID(byte[] store1data) { fail("localKeyID not found initially"); } - + store2.setKeyEntry("new", newPair.getPrivate(), null, chain2); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); @@ -1760,7 +1922,7 @@ private void testOrphanedCertCleanup() X509Certificate kp1CA = TestUtils.generateIntermediateCert(kp1ca.getPublic(), new X500Name("CN=KP1 CA"), kp1.getPrivate(), kp1Root); X509Certificate kp1EE = TestUtils.generateEndEntityCert(kp1ee.getPublic(), new X500Name("CN=KP1 EE"), kp1ca.getPrivate(), kp1CA); - Certificate[] kp1Chain = new Certificate[] { kp1EE, kp1CA, kp1Root }; + Certificate[] kp1Chain = new Certificate[]{kp1EE, kp1CA, kp1Root}; KeyPair kp2 = TestUtils.generateRSAKeyPair(); KeyPair kp2ca = TestUtils.generateRSAKeyPair(); @@ -1770,7 +1932,7 @@ private void testOrphanedCertCleanup() X509Certificate kp2CA = TestUtils.generateIntermediateCert(kp2ca.getPublic(), new X500Name("CN=KP2 CA"), kp2.getPrivate(), kp1Root); X509Certificate kp2EE = TestUtils.generateEndEntityCert(kp2ee.getPublic(), new X500Name("CN=KP2 EE"), kp2ca.getPrivate(), kp1CA); - Certificate[] kp2Chain = new Certificate[] { kp2EE, kp2CA, kp2Root }; + Certificate[] kp2Chain = new Certificate[]{kp2EE, kp2CA, kp2Root}; KeyPair kp3 = TestUtils.generateRSAKeyPair(); X509Certificate kp3Root = TestUtils.generateRootCert(kp3, new X500Name("CN=KP3 ROOT")); @@ -1899,7 +2061,7 @@ private void testBCFKSLoad() X509Certificate kp1CA = TestUtils.generateIntermediateCert(kp1ca.getPublic(), new X500Name("CN=KP1 CA"), kp1.getPrivate(), kp1Root); X509Certificate kp1EE = TestUtils.generateEndEntityCert(kp1ee.getPublic(), new X500Name("CN=KP1 EE"), kp1ca.getPrivate(), kp1CA); - Certificate[] kp1Chain = new Certificate[] { kp1EE, kp1CA, kp1Root }; + Certificate[] kp1Chain = new Certificate[]{kp1EE, kp1CA, kp1Root}; KeyPair kp2 = TestUtils.generateRSAKeyPair(); KeyPair kp2ca = TestUtils.generateRSAKeyPair(); @@ -1909,7 +2071,7 @@ private void testBCFKSLoad() X509Certificate kp2CA = TestUtils.generateIntermediateCert(kp2ca.getPublic(), new X500Name("CN=KP2 CA"), kp2.getPrivate(), kp1Root); X509Certificate kp2EE = TestUtils.generateEndEntityCert(kp2ee.getPublic(), new X500Name("CN=KP2 EE"), kp2ca.getPrivate(), kp1CA); - Certificate[] kp2Chain = new Certificate[] { kp2EE, kp2CA, kp2Root }; + Certificate[] kp2Chain = new Certificate[]{kp2EE, kp2CA, kp2Root}; KeyPair kp3 = TestUtils.generateRSAKeyPair(); X509Certificate kp3Root = TestUtils.generateRootCert(kp3, new X500Name("CN=KP3 ROOT")); @@ -1935,7 +2097,7 @@ private void testBCFKSLoad() k12.load(new ByteArrayInputStream(bOut.toByteArray()), "fred".toCharArray()); } catch (IOException e) - { + { isTrue("illegal object in getInstance: org.bouncycastle.asn1.DLSequence".equals(e.getMessage())); } } @@ -1959,6 +2121,11 @@ public String getName() private void testJKS() throws Exception { + if (System.getProperty("java.version").indexOf("1.5.") == 0) + { + return; + } + KeyStore ks = KeyStore.getInstance("PKCS12", BC); ks.load(new ByteArrayInputStream(JKS_Store), JKS_TEST_PWD); @@ -1966,6 +2133,56 @@ private void testJKS() isTrue(ks.isCertificateEntry("cert0")); } + private void testStoreType(String storeType, boolean isMacExpected) + throws Exception + { + KeyPairGenerator kpGen = KeyPairGenerator.getInstance("EC", "BC"); + KeyPair kp = kpGen.generateKeyPair(); + X509Certificate cert = TestUtils.createSelfSignedCert(new X500Name("CN=PKCS12 Test"), "SHA256withECDSA", kp); + + KeyStore keyStore = KeyStore.getInstance(storeType, "BC"); + keyStore.load(null, null); + + keyStore.setKeyEntry("key", kp.getPrivate(), null, new Certificate[] { cert }); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + keyStore.store(bOut, passwd); + + KeyStore inStore = KeyStore.getInstance("PKCS12", "BC"); + + inStore.load(new ByteArrayInputStream(bOut.toByteArray()), passwd); + + FileOutputStream fOut = new FileOutputStream("/tmp/" + storeType + ".p12"); + fOut.write(bOut.toByteArray()); + fOut.close(); + Key k = inStore.getKey("key", null); + + Pfx pfx = Pfx.getInstance(bOut.toByteArray()); + + if (isMacExpected) + { + isTrue(pfx.getMacData() != null); + } + else + { + isTrue(pfx.getMacData() == null); + } + + } + + private void testAES256_AES128() + throws Exception + { + testStoreType("PKCS12-AES256-AES128", true); + } + + private void testAES256GCM_AES128_GCM() + throws Exception + { + testStoreType("PKCS12-AES256-AES128-GCM", false); + } + public void performTest() throws Exception { @@ -1977,6 +2194,14 @@ public void performTest() testCertsOnly(); testJKS(); testLoadRepeatedLocalKeyID(); + testDilithiumStore(); + testFalconStore(); + testNTRUStore(); + testSphincsPlusStore(); + testRawKeyBagStore(); + testAES256_AES128(); + testAES256GCM_AES128_GCM(); + // converter tests KeyStore kS = KeyStore.getInstance("PKCS12", BC); @@ -2011,7 +2236,7 @@ public void performTest() } public static void main( - String[] args) + String[] args) { Security.addProvider(new BouncyCastleProvider()); diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/PKIXPolicyMappingTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/PKIXPolicyMappingTest.java index f929a9de2b..a6736ecff3 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/PKIXPolicyMappingTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/PKIXPolicyMappingTest.java @@ -4,6 +4,7 @@ import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.KeyFactory; +import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; @@ -19,30 +20,27 @@ import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; -import java.util.Date; import java.util.HashSet; -import java.util.Hashtable; import java.util.Set; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.CertPolicyId; import org.bouncycastle.asn1.x509.CertificatePolicies; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.PolicyMappings; -import org.bouncycastle.asn1.x509.X509Extensions; -import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.TestFailedException; -import org.bouncycastle.x509.X509V3CertificateGenerator; public class PKIXPolicyMappingTest extends SimpleTest { - static X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator(); - public String getName() { return "PKIXPolicyMapping"; @@ -56,45 +54,28 @@ private X509Certificate createTrustCert( PrivateKey privKey) throws Exception { - String issuer = "C=JP, O=policyMappingAdditionalTest, OU=trustAnchor"; - String subject = "C=JP, O=policyMappingAdditionalTest, OU=trustAnchor"; - v3CertGen.setSerialNumber(BigInteger.valueOf(10)); - v3CertGen.setIssuerDN(new X509Principal(issuer)); - v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); - v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); - v3CertGen.setSubjectDN(new X509Principal(subject)); - v3CertGen.setPublicKey(pubKey); - v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); - X509Certificate cert = v3CertGen.generate(privKey); - return cert; + return TestCertificateGen.createSelfSignedCert("C=JP, O=policyMappingAdditionalTest, OU=trustAnchor", "SHA1withRSA", new KeyPair(pubKey, privKey)); } - + /** * intermediate cert */ private X509Certificate createIntmedCert( PublicKey pubKey, PrivateKey caPrivKey, - PublicKey caPubKey, CertificatePolicies policies, - Hashtable policyMap) + PolicyMappings policyMap) throws Exception { String issuer = "C=JP, O=policyMappingAdditionalTest, OU=trustAnchor"; String subject = "C=JP, O=policyMappingAdditionalTest, OU=intmedCA"; - v3CertGen.reset(); - v3CertGen.setSerialNumber(BigInteger.valueOf(20)); - v3CertGen.setIssuerDN(new X509Principal(issuer)); - v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); - v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); - v3CertGen.setSubjectDN(new X509Principal(subject)); - v3CertGen.setPublicKey(pubKey); - v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); - v3CertGen.addExtension(X509Extensions.CertificatePolicies, true, policies); - v3CertGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true)); - v3CertGen.addExtension(X509Extensions.PolicyMappings, true, new PolicyMappings(policyMap)); - X509Certificate cert = v3CertGen.generate(caPrivKey); - return cert; + + ExtensionsGenerator extGen = new ExtensionsGenerator(); + extGen.addExtension(Extension.certificatePolicies, true, policies); + extGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(true)); + extGen.addExtension(Extension.policyMappings, true, policyMap); + + return TestCertificateGen.createCert(new X500Name(issuer), caPrivKey, subject, "SHA1withRSA", extGen.generate(), pubKey); } /** @@ -103,23 +84,17 @@ private X509Certificate createIntmedCert( private X509Certificate createEndEntityCert( PublicKey pubKey, PrivateKey caPrivKey, - PublicKey caPubKey, ASN1EncodableVector policies) throws Exception { String issuer = "C=JP, O=policyMappingAdditionalTest, OU=intMedCA"; String subject = "C=JP, O=policyMappingAdditionalTest, OU=endEntity"; - v3CertGen.reset(); - v3CertGen.setSerialNumber(BigInteger.valueOf(20)); - v3CertGen.setIssuerDN(new X509Principal(issuer)); - v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); - v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); - v3CertGen.setSubjectDN(new X509Principal(subject)); - v3CertGen.setPublicKey(pubKey); - v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); - v3CertGen.addExtension(X509Extensions.CertificatePolicies,true,new DERSequence(policies)); - X509Certificate cert = v3CertGen.generate(caPrivKey); - return cert; + + ExtensionsGenerator extGen = new ExtensionsGenerator(); + extGen.addExtension(Extension.certificatePolicies, true, new DERSequence(policies)); + extGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(true)); + + return TestCertificateGen.createCert(new X500Name(issuer), caPrivKey, subject, "SHA1withRSA", extGen.generate(), pubKey); } private String testPolicies( @@ -264,19 +239,17 @@ public void performTest() X509Certificate trustCert = createTrustCert(caPubKey, caPrivKey); CertificatePolicies intPolicies = null; - Hashtable map = null; ASN1EncodableVector policies = null; Set requirePolicies = null; X509Certificate intCert = null; X509Certificate endCert = null; - /** + /* * valid test_00 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); - map = new Hashtable(); - map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); - intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); + intCert = createIntmedCert(intPubKey, caPrivKey, intPolicies, + createPolicyMappings("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2")); if (!"CertificatePolicies: [Policy information: 2.5.29.32.0]".equals(intPolicies.toString())) { @@ -285,47 +258,45 @@ public void performTest() policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); - endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); + endCert = createEndEntityCert(pubKey, intPrivKey, policies); requirePolicies = null; String msg = testPolicies(0, trustCert, intCert, endCert, requirePolicies, true); checkMessage(0, msg, ""); - /** + /* * test_01 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); - map = new Hashtable(); - map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); - intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); + PolicyMappings map = createPolicyMappings("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); + intCert = createIntmedCert(intPubKey, caPrivKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); - endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); + endCert = createEndEntityCert(pubKey, intPrivKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.1"); msg = testPolicies(1, trustCert, intCert, endCert, requirePolicies, true); checkMessage(1, msg, ""); - /** + /* * test_02 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); - map = new Hashtable(); - map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); - intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); + map = createPolicyMappings("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); + intCert = createIntmedCert(intPubKey, caPrivKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); - endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); + endCert = createEndEntityCert(pubKey, intPrivKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.5.29.32.0"); msg = testPolicies(2, trustCert, intCert, endCert, requirePolicies, true); checkMessage(2, msg, ""); - /** + /* * test_03 */ intPolicies = new CertificatePolicies(new PolicyInformation[] @@ -336,101 +307,95 @@ public void performTest() { fail("2nd toString() test"); } - - map = new Hashtable(); - map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); - intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); + + map = createPolicyMappings("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); + intCert = createIntmedCert(intPubKey, caPrivKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); - endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); + endCert = createEndEntityCert(pubKey, intPrivKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.1"); msg = testPolicies(3, trustCert, intCert, endCert, requirePolicies, true); checkMessage(3, msg, ""); - /** + /* * test_04 */ intPolicies = new CertificatePolicies(new PolicyInformation[] { new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.3")), new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0")) } ); - map = new Hashtable(); - map.put("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); - intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); + map = createPolicyMappings("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); + intCert = createIntmedCert(intPubKey, caPrivKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.3"))); - endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); + endCert = createEndEntityCert(pubKey, intPrivKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.3"); msg = testPolicies(4, trustCert, intCert, endCert, requirePolicies, true); checkMessage(4, msg, ""); - /** + /* * test_05 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); - map = new Hashtable(); - map.put("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); - intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); + map = createPolicyMappings("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); + intCert = createIntmedCert(intPubKey, caPrivKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); - endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); + endCert = createEndEntityCert(pubKey, intPrivKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.2"); msg = testPolicies(5, trustCert, intCert, endCert, requirePolicies, false); checkMessage(5, msg, "Path processing failed on policy."); - /** + /* * test_06 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); - map = new Hashtable(); - map.put("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); - intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); + map = createPolicyMappings("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); + intCert = createIntmedCert(intPubKey, caPrivKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.1"))); - endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); + endCert = createEndEntityCert(pubKey, intPrivKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.1"); msg = testPolicies(6, trustCert, intCert, endCert, requirePolicies, true); checkMessage(6, msg, ""); - /** + /* * test_07 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); - map = new Hashtable(); - map.put("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); - intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); + map = createPolicyMappings("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); + intCert = createIntmedCert(intPubKey, caPrivKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); - endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); + endCert = createEndEntityCert(pubKey, intPrivKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.3"); msg = testPolicies(7, trustCert, intCert, endCert, requirePolicies, false); checkMessage(7, msg, "Path processing failed on policy."); - /** + /* * test_08 */ intPolicies = new CertificatePolicies(new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0"))); - map = new Hashtable(); - map.put("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); - intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); + map = createPolicyMappings("2.16.840.1.101.3.2.1.48.1", "2.16.840.1.101.3.2.1.48.2"); + intCert = createIntmedCert(intPubKey, caPrivKey, intPolicies, map); policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.3"))); - endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); + endCert = createEndEntityCert(pubKey, intPrivKey, policies); requirePolicies = new HashSet(); requirePolicies.add("2.16.840.1.101.3.2.1.48.1"); @@ -450,6 +415,11 @@ private void checkMessage( } } + private PolicyMappings createPolicyMappings(String idp, String sdp) + { + return new PolicyMappings(CertPolicyId.getInstance(new ASN1ObjectIdentifier(idp)),CertPolicyId.getInstance(new ASN1ObjectIdentifier(sdp))); + } + public static void main( String[] args) { diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/RSATest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/RSATest.java index a2a7ea147f..81a406175a 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/RSATest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/RSATest.java @@ -41,7 +41,6 @@ import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAESOAEPparams; @@ -50,6 +49,7 @@ import org.bouncycastle.asn1.x509.DigestInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec; import org.bouncycastle.jcajce.spec.OpenSSHPublicKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/SEEDTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/SEEDTest.java index 203646470a..f1c9a21c56 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/SEEDTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/SEEDTest.java @@ -1,13 +1,5 @@ package org.bouncycastle.jce.provider.test; -import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.util.encoders.Hex; - -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; -import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -15,6 +7,15 @@ import java.security.Key; import java.security.Security; +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.spec.SecretKeySpec; + +import org.bouncycastle.internal.asn1.kisa.KISAObjectIdentifiers; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.encoders.Hex; + /** * basic test class for SEED */ diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/SimpleTestTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/SimpleTestTest.java index 1bd1eb44f7..2427f33d1b 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/SimpleTestTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/SimpleTestTest.java @@ -1,9 +1,9 @@ package org.bouncycastle.jce.provider.test; -import java.security.Provider; import java.security.Security; import junit.framework.TestCase; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.test.SimpleTestResult; public class SimpleTestTest @@ -11,6 +11,13 @@ public class SimpleTestTest { public void testJCE() { + System.setProperty("org.bouncycastle.bks.enable_v1", "true"); + + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastleProvider()); + } + org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; for (int i = 0; i != tests.length; i++) diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/TestCertificateGen.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/TestCertificateGen.java new file mode 100644 index 0000000000..1758e27387 --- /dev/null +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/TestCertificateGen.java @@ -0,0 +1,350 @@ +package org.bouncycastle.jce.provider.test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Signature; +import java.security.cert.CertificateFactory; +import java.security.cert.X509CRL; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.DERBitString; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; +import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.CRLNumber; +import org.bouncycastle.asn1.x509.CRLReason; +import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.Extensions; +import org.bouncycastle.asn1.x509.ExtensionsGenerator; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralNames; +import org.bouncycastle.asn1.x509.KeyUsage; +import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x509.TBSCertList; +import org.bouncycastle.asn1.x509.TBSCertificate; +import org.bouncycastle.asn1.x509.Time; +import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator; +import org.bouncycastle.asn1.x509.V2TBSCertListGenerator; +import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; + +public class TestCertificateGen +{ + private static volatile long serialNumber = System.currentTimeMillis(); + private static Map algIds = new HashMap(); + + static + { + algIds.put("GOST3411withGOST3410", new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94)); + algIds.put("SHA1withRSA", new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption, DERNull.INSTANCE)); + algIds.put("SHA256withRSA", new AlgorithmIdentifier(PKCSObjectIdentifiers.sha256WithRSAEncryption, DERNull.INSTANCE)); + algIds.put("SHA1withECDSA", new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA1)); + algIds.put("MD5WithRSAEncryption", new AlgorithmIdentifier(PKCSObjectIdentifiers.md5WithRSAEncryption, DERNull.INSTANCE)); + algIds.put("LMS", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig)); + algIds.put("Ed448", new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448)); + } + + private synchronized static long getSerialNumber() + { + return serialNumber++; + } + + public static X509Certificate createSelfSignedCert(String dn, String sigName, KeyPair keyPair) + throws Exception + { + return createSelfSignedCert(new X500Name(dn), sigName, keyPair); + } + + public static X509Certificate createSelfSignedCert(X500Name dn, String sigName, KeyPair keyPair) + throws Exception + { + V1TBSCertificateGenerator certGen = new V1TBSCertificateGenerator(); + + long time = System.currentTimeMillis(); + + certGen.setSerialNumber(new ASN1Integer(getSerialNumber())); + certGen.setIssuer(dn); + certGen.setSubject(dn); + certGen.setStartDate(new Time(new Date(time - 5000))); + certGen.setEndDate(new Time(new Date(time + 30 * 60 * 1000))); + certGen.setSignature((AlgorithmIdentifier)algIds.get(sigName)); + certGen.setSubjectPublicKeyInfo(SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded())); + + Signature sig = Signature.getInstance(sigName, "BC"); + + sig.initSign(keyPair.getPrivate()); + + sig.update(certGen.generateTBSCertificate().getEncoded(ASN1Encoding.DER)); + + TBSCertificate tbsCert = certGen.generateTBSCertificate(); + + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(tbsCert); + v.add((AlgorithmIdentifier)algIds.get(sigName)); + v.add(new DERBitString(sig.sign())); + + return (X509Certificate)CertificateFactory.getInstance("X.509", "BC").generateCertificate(new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER))); + } + + public static X509Certificate createCert(X500Name signerName, PrivateKey signerKey, String dn, String sigName, Extensions extensions, PublicKey pubKey) + throws Exception + { + return createCert(signerName, signerKey, new X500Name(dn), sigName, extensions, pubKey); + } + + public static X509Certificate createCert(X500Name signerName, PrivateKey signerKey, X500Name dn, String sigName, Extensions extensions, PublicKey pubKey) + throws Exception + { + V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator(); + + long time = System.currentTimeMillis(); + + certGen.setSerialNumber(new ASN1Integer(getSerialNumber())); + certGen.setIssuer(signerName); + certGen.setSubject(dn); + certGen.setStartDate(new Time(new Date(time - 5000))); + certGen.setEndDate(new Time(new Date(time + 30 * 60 * 1000))); + certGen.setSignature((AlgorithmIdentifier)algIds.get(sigName)); + certGen.setSubjectPublicKeyInfo(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded())); + certGen.setExtensions(extensions); + + Signature sig = Signature.getInstance(sigName, "BC"); + + sig.initSign(signerKey); + + sig.update(certGen.generateTBSCertificate().getEncoded(ASN1Encoding.DER)); + + TBSCertificate tbsCert = certGen.generateTBSCertificate(); + + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(tbsCert); + v.add((AlgorithmIdentifier)algIds.get(sigName)); + v.add(new DERBitString(sig.sign())); + + return (X509Certificate)CertificateFactory.getInstance("X.509", "BC").generateCertificate(new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER))); + } + + public static X509Certificate createCertWithIDs(X500Name signerName, String sigName, KeyPair keyPair, boolean[] subjectUniqID, boolean[] issuerUniqID) + throws Exception + { + V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator(); + + long time = System.currentTimeMillis(); + + certGen.setSerialNumber(new ASN1Integer(getSerialNumber())); + certGen.setIssuer(signerName); + certGen.setSubject(signerName); + certGen.setStartDate(new Time(new Date(time - 5000))); + certGen.setEndDate(new Time(new Date(time + 30 * 60 * 1000))); + certGen.setSignature((AlgorithmIdentifier)algIds.get(sigName)); + certGen.setSubjectPublicKeyInfo(SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded())); + + if (issuerUniqID != null) + { + certGen.setIssuerUniqueID(booleanToBitString(issuerUniqID)); + } + + if (subjectUniqID != null) + { + certGen.setSubjectUniqueID(booleanToBitString(subjectUniqID)); + } + + Signature sig = Signature.getInstance(sigName, "BC"); + + sig.initSign(keyPair.getPrivate()); + + sig.update(certGen.generateTBSCertificate().getEncoded(ASN1Encoding.DER)); + + TBSCertificate tbsCert = certGen.generateTBSCertificate(); + + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(tbsCert); + v.add((AlgorithmIdentifier)algIds.get(sigName)); + v.add(new DERBitString(sig.sign())); + + return (X509Certificate)CertificateFactory.getInstance("X.509", "BC").generateCertificate(new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER))); + } + + /** + * Create a random 1024 bit RSA key pair + */ + public static KeyPair generateRSAKeyPair() + throws Exception + { + KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); + + kpGen.initialize(1024, new SecureRandom()); + + return kpGen.generateKeyPair(); + } + + public static X509Certificate generateRootCert(KeyPair pair) + throws Exception + { + return createSelfSignedCert("CN=Test CA Certificate", "SHA256withRSA", pair); + } + + public static X509Certificate generateRootCert(KeyPair pair, X500Name dn) + throws Exception + { + return createSelfSignedCert(dn, "SHA256withRSA", pair); + } + + public static X509Certificate generateIntermediateCert(PublicKey intKey, PrivateKey caKey, X509Certificate caCert) + throws Exception + { + return generateIntermediateCert( + intKey, new X500Name("CN=Test Intermediate Certificate"), caKey, caCert); + } + + public static X509Certificate generateIntermediateCert(PublicKey intKey, X500Name subject, PrivateKey caKey, X509Certificate caCert) + throws Exception + { + Certificate caCertLw = Certificate.getInstance(caCert.getEncoded()); + + ExtensionsGenerator extGen = new ExtensionsGenerator(); + + extGen.addExtension(Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifier(getDigest(caCertLw.getSubjectPublicKeyInfo()), + new GeneralNames(new GeneralName(caCertLw.getIssuer())), + caCertLw.getSerialNumber().getValue())); + extGen.addExtension(Extension.subjectKeyIdentifier, false, new SubjectKeyIdentifier(getDigest(SubjectPublicKeyInfo.getInstance(intKey.getEncoded())))); + extGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(0)); + extGen.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyCertSign | KeyUsage.cRLSign)); + + return createCert( + caCertLw.getSubject(), + caKey, subject, "SHA256withRSA", extGen.generate(), intKey); + } + + public static X509Certificate generateEndEntityCert(PublicKey intKey, PrivateKey caKey, X509Certificate caCert) + throws Exception + { + return generateEndEntityCert( + intKey, new X500Name("CN=Test End Certificate"), caKey, caCert); + } + + public static X509Certificate generateEndEntityCert(PublicKey entityKey, X500Name subject, PrivateKey caKey, X509Certificate caCert) + throws Exception + { + Certificate caCertLw = Certificate.getInstance(caCert.getEncoded()); + + ExtensionsGenerator extGen = new ExtensionsGenerator(); + + extGen.addExtension(Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifier(getDigest(caCertLw.getSubjectPublicKeyInfo()), + new GeneralNames(new GeneralName(caCertLw.getIssuer())), + caCertLw.getSerialNumber().getValue())); + extGen.addExtension(Extension.subjectKeyIdentifier, false, new SubjectKeyIdentifier(getDigest(entityKey.getEncoded()))); + extGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(0)); + extGen.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyCertSign | KeyUsage.cRLSign)); + + return createCert( + caCertLw.getSubject(), + caKey, subject, "SHA256withRSA", extGen.generate(), entityKey); + } + + public static X509CRL createCRL( + X509Certificate caCert, + PrivateKey caKey, + BigInteger revokedSerialNumber) + throws Exception + { + V2TBSCertListGenerator crlGen = new V2TBSCertListGenerator(); + Date now = new Date(); + + X500Name issuer = new X500Name(caCert.getSubjectDN().getName()); + crlGen.setIssuer(issuer); + + crlGen.setThisUpdate(new Time(now)); + crlGen.setNextUpdate(new Time(new Date(now.getTime() + 100000))); + crlGen.setSignature((AlgorithmIdentifier)algIds.get("SHA256withRSA")); + + crlGen.addCRLEntry(new ASN1Integer(revokedSerialNumber), new Time(now), CRLReason.privilegeWithdrawn); + + ExtensionsGenerator extGen = new ExtensionsGenerator(); + + extGen.addExtension(Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifier(new GeneralNames(new GeneralName(issuer)), caCert.getSerialNumber())); + extGen.addExtension(Extension.cRLNumber, false, new CRLNumber(BigInteger.valueOf(1))); + + crlGen.setExtensions(extGen.generate()); + + Signature sig = Signature.getInstance("SHA256withRSA", "BC"); + + sig.initSign(caKey); + + sig.update(crlGen.generateTBSCertList().getEncoded(ASN1Encoding.DER)); + + TBSCertList tbsCrl = crlGen.generateTBSCertList(); + + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(tbsCrl); + v.add((AlgorithmIdentifier)algIds.get("SHA256withRSA")); + v.add(new DERBitString(sig.sign())); + + return (X509CRL)CertificateFactory.getInstance("X.509", "BC").generateCRL(new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER))); + } + + private static byte[] getDigest(SubjectPublicKeyInfo spki) + throws IOException + { + return getDigest(spki.getPublicKeyData().getBytes()); + } + + private static byte[] getDigest(byte[] bytes) + { + try + { + return MessageDigest.getInstance("SHA1").digest(bytes); + } + catch (NoSuchAlgorithmException e) + { + return null; + } + } + + private static DERBitString booleanToBitString(boolean[] id) + { + byte[] bytes = new byte[(id.length + 7) / 8]; + + for (int i = 0; i != id.length; i++) + { + bytes[i / 8] |= (id[i]) ? (1 << ((7 - (i % 8)))) : 0; + } + + int pad = id.length % 8; + + if (pad == 0) + { + return new DERBitString(bytes); + } + else + { + return new DERBitString(bytes, 8 - pad); + } + } +} diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/TestUtils.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/TestUtils.java index 9aed8e93b7..33d999849b 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/TestUtils.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/TestUtils.java @@ -18,7 +18,6 @@ import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateFactory; import java.security.cert.CertificateNotYetValidException; -import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.Date; import java.util.HashMap; @@ -31,15 +30,14 @@ import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; -import org.bouncycastle.asn1.x509.CRLNumber; -import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.Extension; @@ -58,9 +56,7 @@ import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; -import org.bouncycastle.jce.PrincipalUtil; -import org.bouncycastle.x509.X509V2CRLGenerator; -import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; /** * Test Utils @@ -78,6 +74,9 @@ class TestUtils algIds.put("SHA1withECDSA", new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA1)); algIds.put("SHA256withECDSA", new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA256)); algIds.put("Ed448", new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448)); + algIds.put("ML-DSA-65", new AlgorithmIdentifier(NISTObjectIdentifiers.id_ml_dsa_65)); + algIds.put("Falcon-512", new AlgorithmIdentifier(BCObjectIdentifiers.falcon_512)); + algIds.put("SPHINCS+", new AlgorithmIdentifier(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3)); } public static X509Certificate createSelfSignedCert(String dn, String sigName, KeyPair keyPair) @@ -265,30 +264,6 @@ public static X509Certificate generateEndEntityCert(PublicKey entityKey, X500Nam caKey, subject, "SHA256withRSA", extGen.generate(), entityKey); } - public static X509CRL createCRL( - X509Certificate caCert, - PrivateKey caKey, - BigInteger serialNumber) - throws Exception - { - X509V2CRLGenerator crlGen = new X509V2CRLGenerator(); - Date now = new Date(); - BigInteger revokedSerialNumber = BigInteger.valueOf(2); - - crlGen.setIssuerDN(PrincipalUtil.getSubjectX509Principal(caCert)); - - crlGen.setThisUpdate(now); - crlGen.setNextUpdate(new Date(now.getTime() + 100000)); - crlGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); - - crlGen.addCRLEntry(serialNumber, now, CRLReason.privilegeWithdrawn); - - crlGen.addExtension(Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert)); - crlGen.addExtension(Extension.cRLNumber, false, new CRLNumber(BigInteger.valueOf(1))); - - return crlGen.generate(caKey, "BC"); - } - public static X509Certificate createExceptionCertificate(boolean exceptionOnEncode) { return new ExceptionCertificate(exceptionOnEncode); diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/X509LDAPCertStoreTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/X509LDAPCertStoreTest.java index 27167127f3..98419dab77 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/X509LDAPCertStoreTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/X509LDAPCertStoreTest.java @@ -1,467 +1,234 @@ package org.bouncycastle.jce.provider.test; -import org.bouncycastle.jce.PrincipalUtil; +import com.unboundid.ldap.listener.InMemoryDirectoryServer; +import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; +import com.unboundid.ldap.listener.InMemoryListenerConfig; +import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; +import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor; +import com.unboundid.ldap.sdk.LDAPException; +import com.unboundid.ldap.sdk.LDAPResult; +import com.unboundid.ldap.sdk.ResultCode; +import com.unboundid.ldif.LDIFException; +import junit.framework.TestCase; +import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.jce.X509LDAPCertStoreParameters; -import org.bouncycastle.jce.X509Principal; +import org.bouncycastle.jce.exception.ExtCertPathBuilderException; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.util.encoders.Base64; -import org.bouncycastle.util.test.SimpleTest; -import org.bouncycastle.x509.X509CRLStoreSelector; -import org.bouncycastle.x509.X509CertStoreSelector; -import org.bouncycastle.x509.X509Store; - -import java.io.ByteArrayInputStream; +import org.bouncycastle.test.TestResourceFinder; + +import javax.net.ServerSocketFactory; +import javax.net.SocketFactory; +import javax.net.ssl.SSLSocketFactory; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.InetAddress; +import java.security.KeyPairGenerator; +import java.security.KeyStore; import java.security.Security; -import java.security.cert.CRLException; +import java.security.cert.CertPathBuilder; import java.security.cert.CertStore; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509CRL; -import java.security.cert.X509CRLSelector; +import java.security.cert.PKIXBuilderParameters; +import java.security.cert.PKIXCertPathBuilderResult; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; -public class X509LDAPCertStoreTest extends SimpleTest +public class X509LDAPCertStoreTest + extends TestCase { - private static final byte cert1[] = Base64 - .decode("MIIDyTCCAzKgAwIBAgIEL64+8zANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJE" - + "RTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKCBgEKBxQTATEw" - + "GAYDVQQDFBFUVEMgVGVzdCBDQSAxMTpQTjAeFw0wMzAzMjUxNDM1MzFaFw0wNjAz" - + "MjUxNDM1MzFaMGIxCzAJBgNVBAYTAkRFMRswGQYDVQQKDBJHRlQgU29sdXRpb25z" - + "IEdtYkgxEjAQBgNVBAsMCUhZUEFSQ0hJVjEWMBQGA1UEAwwNRGllZ2UsIFNpbW9u" - + "ZTEKMAgGA1UEBRMBMTCBoDANBgkqhkiG9w0BAQEFAAOBjgAwgYoCgYEAiEYsFbs4" - + "FesQpMjBkzJB92c0p8tJ02nbCNA5l17VVbbrv6/twnQHW4kgA+9lZlXfzI8iunT1" - + "KuiwVupWObHgFaGPkelIN/qIbuwbQzh7T+IUKdKETE12Lc+xk9YvQ6mJVgosmwpr" - + "nMMjezymh8DjPhe7MC7/H3AotrHVNM3mEJcCBEAAAIGjggGWMIIBkjAfBgNVHSME" - + "GDAWgBTQc8wTeltcAM3iTE63fk/wTA+IJTAdBgNVHQ4EFgQUq6ChBvXPiqhMHLS3" - + "kiKpSeGWDz4wDgYDVR0PAQH/BAQDAgQwMB8GA1UdEQQYMBaBFHNpbW9uZS5kaWVn" - + "ZUBnZnQuY29tMIHoBgNVHR8EgeAwgd0wgdqgaqBohjVsZGFwOi8vcGtzbGRhcC50" - + "dHRjLmRlOjM4OS9jPWRlLG89RGV1dHNjaGUgVGVsZWtvbSBBR4YvaHR0cDovL3d3" - + "dy50dHRjLmRlL3RlbGVzZWMvc2VydmxldC9kb3dubG9hZF9jcmyibKRqMGgxCzAJ" - + "BgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMTswDAYHAoIG" - + "AQoHFBMBMTArBgNVBAMUJFRlbGVTZWMgRGlyZWN0b3J5IFNlcnZpY2UgU2lnRyAx" - + "MDpQTjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly93d3cudHR0" - + "Yy5kZS9vY3NwcjANBgkqhkiG9w0BAQUFAAOBgQBCPudAtrP9Bx7GRhHQgYS6kaoN" - + "vYb/yDss86pyn0uiFuwT+mT1popcAfxPo2yxL0jqqlsDNFBC2hJob5rjihsKPmqV" - + "rSaW0VJu/zBihsX7hLKOVMf5gvUYMS5ulq/bp8jOj8a+5SmxVY+WWZVFghWjISse" - + "T3WABdTS9S3zjnQiyg=="); - - private static final byte[] directCRL = Base64 - .decode("MIIGXTCCBckCAQEwCgYGKyQDAwECBQAwdDELMAkGA1UEBhMCREUxHDAaBgNVBAoU" - + "E0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0MS4w" - + "DAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBOFw0w" - + "NjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIElTAVAgQvrj/pFw0wMzA3MjIw" - + "NTQxMjhaMBUCBC+uP+oXDTAzMDcyMjA1NDEyOFowFQIEL64/5xcNMDQwNDA1MTMx" - + "ODE3WjAVAgQvrj/oFw0wNDA0MDUxMzE4MTdaMBUCBC+uP+UXDTAzMDExMzExMTgx" - + "MVowFQIEL64/5hcNMDMwMTEzMTExODExWjAVAgQvrj/jFw0wMzAxMTMxMTI2NTZa" - + "MBUCBC+uP+QXDTAzMDExMzExMjY1NlowFQIEL64/4hcNMDQwNzEzMDc1ODM4WjAV" - + "AgQvrj/eFw0wMzAyMTcwNjMzMjVaMBUCBC+uP98XDTAzMDIxNzA2MzMyNVowFQIE" - + "L64/0xcNMDMwMjE3MDYzMzI1WjAVAgQvrj/dFw0wMzAxMTMxMTI4MTRaMBUCBC+u" - + "P9cXDTAzMDExMzExMjcwN1owFQIEL64/2BcNMDMwMTEzMTEyNzA3WjAVAgQvrj/V" - + "Fw0wMzA0MzAxMjI3NTNaMBUCBC+uP9YXDTAzMDQzMDEyMjc1M1owFQIEL64/xhcN" - + "MDMwMjEyMTM0NTQwWjAVAgQvrj/FFw0wMzAyMTIxMzQ1NDBaMBUCBC+uP8IXDTAz" - + "MDIxMjEzMDkxNlowFQIEL64/wRcNMDMwMjEyMTMwODQwWjAVAgQvrj++Fw0wMzAy" - + "MTcwNjM3MjVaMBUCBC+uP70XDTAzMDIxNzA2MzcyNVowFQIEL64/sBcNMDMwMjEy" - + "MTMwODU5WjAVAgQvrj+vFw0wMzAyMTcwNjM3MjVaMBUCBC+uP5MXDTAzMDQxMDA1" - + "MjYyOFowFQIEL64/khcNMDMwNDEwMDUyNjI4WjAVAgQvrj8/Fw0wMzAyMjYxMTA0" - + "NDRaMBUCBC+uPz4XDTAzMDIyNjExMDQ0NFowFQIEL64+zRcNMDMwNTIwMDUyNzM2" - + "WjAVAgQvrj7MFw0wMzA1MjAwNTI3MzZaMBUCBC+uPjwXDTAzMDYxNzEwMzQxNlow" - + "FQIEL64+OxcNMDMwNjE3MTAzNDE2WjAVAgQvrj46Fw0wMzA2MTcxMDM0MTZaMBUC" - + "BC+uPjkXDTAzMDYxNzEzMDEwMFowFQIEL64+OBcNMDMwNjE3MTMwMTAwWjAVAgQv" - + "rj43Fw0wMzA2MTcxMzAxMDBaMBUCBC+uPjYXDTAzMDYxNzEzMDEwMFowFQIEL64+" - + "MxcNMDMwNjE3MTAzNzQ5WjAVAgQvrj4xFw0wMzA2MTcxMDQyNThaMBUCBC+uPjAX" - + "DTAzMDYxNzEwNDI1OFowFQIEL649qRcNMDMxMDIyMTEzMjI0WjAVAgQvrjyyFw0w" - + "NTAzMTEwNjQ0MjRaMBUCBC+uPKsXDTA0MDQwMjA3NTQ1M1owFQIEL6466BcNMDUw" - + "MTI3MTIwMzI0WjAVAgQvrjq+Fw0wNTAyMTYwNzU3MTZaMBUCBC+uOqcXDTA1MDMx" - + "MDA1NTkzNVowFQIEL646PBcNMDUwNTExMTA0OTQ2WjAVAgQvrG3VFw0wNTExMTEx" - + "MDAzMjFaMBUCBC+uLmgXDTA2MDEyMzEwMjU1NVowFQIEL64mxxcNMDYwODAxMDk0" - + "ODQ0WqCBijCBhzALBgNVHRQEBAICEQwwHwYDVR0jBBgwFoAUA1vI26YMj3njkfCU" - + "IXbo244kLjkwVwYDVR0SBFAwToZMbGRhcDovL3Brc2xkYXAudHR0Yy5kZS9vdT1U" - + "LVRlbGVTZWMgVGVzdCBESVIgODpQTixvPURldXRzY2hlIFRlbGVrb20gQUcsYz1k" - + "ZTAKBgYrJAMDAQIFAAOBgQArj4eMlbAwuA2aS5O4UUUHQMKKdK/dtZi60+LJMiMY" - + "ojrMIf4+ZCkgm1Ca0Cd5T15MJxVHhh167Ehn/Hd48pdnAP6Dfz/6LeqkIHGWMHR+" - + "z6TXpwWB+P4BdUec1ztz04LypsznrHcLRa91ixg9TZCb1MrOG+InNhleRs1ImXk8" - + "MQ=="); - - private static final String ldapURL1 = "ldap://pksldap.tttc.de:389"; - - private static final X509LDAPCertStoreParameters params1 = new X509LDAPCertStoreParameters.Builder( - ldapURL1, "o=Deutsche Telekom AG, c=DE"). - setAACertificateSubjectAttributeName("ou cn"). - setAttributeAuthorityRevocationListIssuerAttributeName("cn"). - setAttributeCertificateAttributeSubjectAttributeName("cn"). - setAttributeCertificateRevocationListIssuerAttributeName("cn"). - setAttributeDescriptorCertificateSubjectAttributeName("ou cn"). - setAuthorityRevocationListIssuerAttributeName("cn"). - setCACertificateSubjectAttributeName("ou cn"). - setCertificateRevocationListIssuerAttributeName("cn"). - setCrossCertificateSubjectAttributeName("cn"). - setDeltaRevocationListIssuerAttributeName("cn"). - setSearchForSerialNumberIn("cn") - .build(); - - private static final String ldapURL2 = "ldap://directory.d-trust.de:389"; - - private static final X509LDAPCertStoreParameters params2 = new X509LDAPCertStoreParameters.Builder( - ldapURL2, "o=D-Trust GmbH, c=DE"). - setAACertificateSubjectAttributeName("cn o"). - setAttributeAuthorityRevocationListIssuerAttributeName("cn"). - setAttributeCertificateAttributeSubjectAttributeName("cn"). - setAttributeCertificateRevocationListIssuerAttributeName("cn"). - setAttributeDescriptorCertificateSubjectAttributeName("cn o"). - setAuthorityRevocationListIssuerAttributeName("cn"). - setCACertificateSubjectAttributeName("cn o"). - setCertificateRevocationListIssuerAttributeName("cn"). - setCrossCertificateSubjectAttributeName("cn o"). - setDeltaRevocationListIssuerAttributeName("cn"). - setSearchForSerialNumberIn("uid") - .build(); - - private static final byte[] cert2 = Base64 - .decode("MIIEADCCAuigAwIBAgIDAJ/QMA0GCSqGSIb3DQEBBQUAMD8xCzAJBgNVBAYTAkRF" - + "MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxGTAXBgNVBAMMEEQtVFJVU1QgRGVtbyBD" - + "QTEwHhcNMDYwMzAyMTYxNTU3WhcNMDgwMzEyMTYxNTU3WjB+MQswCQYDVQQGEwJE" - + "RTEUMBIGA1UECgwLTXVzdGVyIEdtYkgxFzAVBgNVBAMMDk1heCBNdXN0ZXJtYW5u" - + "MRMwEQYDVQQEDApNdXN0ZXJtYW5uMQwwCgYDVQQqDANNYXgxHTAbBgNVBAUTFERU" - + "UldFMTQxMjk5NDU1MTgwMTIxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC" - + "AQEAjLDFeviSZDEZgLzTdptU4biPgNV7SvLqsNholfqkyQm2r5WSghGZSjhKYIne" - + "qKmZ08W59a51bGqDEsifYR7Tw9JC/AhH19fyK01+1ZAXHalgVthaRtLw31lcoTVJ" - + "R7j9fvrnW0sMPVP4m5gePb3P5/pYHVmN1MjdPIm38us5aJOytOO5Li2IwQIG0t4M" - + "bEC6/1horBR5TgRl7ACamrdaPHOvO1QVweOqYU7uVxLgDTK4mSV6heyrisFMfkbj" - + "7jT/c44kXM7dtgNcmESINudu6bnqaB1CxOFTJ/Jzv81R5lf7pBX2LOG1Bu94Yw2x" - + "cHUVROs2UWY8kQrNUozsBHzQ0QIDAKq5o4HFMIHCMBMGA1UdIwQMMAqACEITKrPL" - + "WuYiMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZC10" - + "cnVzdC5uZXQwEAYDVR0gBAkwBzAFBgMqAwQwEQYDVR0OBAoECEvE8bXFHkFLMA4G" - + "A1UdDwEB/wQEAwIGQDAPBgUrJAgDCAQGDARUZXN0MB8GA1UdEQQYMBaBFG0ubXVz" - + "dGVybWFubkB0ZXN0LmRlMA8GBSskCAMPBAYMBFRlc3QwDQYJKoZIhvcNAQEFBQAD" - + "ggEBADD/X+UZZN30nCBDzJ7MtmgwvMBVDAU6HkPlzfyn9pxIKFrq3uR9wcY2pedM" - + "yQQk0NpTDCIhAYIjAHysMue0ViQnW5qq8uUCFn0+fsgMqqTQNRmE4NIqUrnYO40g" - + "WjcepCEApkTqGf3RFaDMf9zpRvj9qUx18De+V0GC22uD2vPKpqRcvS2dSw6pHBW2" - + "NwEU+RgNhoPXrHt332PEYdwO0zOL7eSLBD9AmkpP2uDjpMQ02Lu9kXG6OOfanwfS" - + "jHioCvDXyl5pwSHwrHNWQRb5dLF12Fg41LMapDwR7awAKE9h6qHBonvCMBPMvqrr" - + "NktqQcoQkluR9MItONJI5XHADtU="); - - private static final String ldapURL3 = "ldap://dir.signtrust.de:389"; - - private static final X509LDAPCertStoreParameters params3 = new X509LDAPCertStoreParameters.Builder( - ldapURL3, "o=Deutsche Post AG, c=de"). - setAACertificateSubjectAttributeName("ou"). - setAttributeAuthorityRevocationListIssuerAttributeName("cn"). - setAttributeCertificateAttributeSubjectAttributeName("cn"). - setAttributeCertificateRevocationListIssuerAttributeName("o"). - setAttributeDescriptorCertificateSubjectAttributeName("ou"). - setAuthorityRevocationListIssuerAttributeName("o"). - setCACertificateSubjectAttributeName("ou"). - setCertificateRevocationListIssuerAttributeName("o"). - setCrossCertificateSubjectAttributeName("o"). - setDeltaRevocationListIssuerAttributeName("o"). - setSearchForSerialNumberIn("serialNumber") - .build(); - - private static final byte[] cert3 = Base64 - .decode("MIICwDCCAimgAwIBAgIBKzANBgkqhkiG9w0BAQUFADA6MRAwDgYDVQQDEwdQQ0Ex" - + "OlBOMRkwFwYDVQQKExBEZXV0c2NoZSBQb3N0IEFHMQswCQYDVQQGEwJERTAeFw0w" - + "MDA0MTkyMjAwMDBaFw0wMzA0MTkyMjAwMDBaMIGOMRAwDgYDVQQEFAdN5G5jaGVy" - + "MQ4wDAYDVQQqEwVLbGF1czEWMBQGA1UEAxQNS2xhdXMgTeRuY2hlcjEVMBMGA1UE" - + "CRMMV2llc2Vuc3RyLiAzMQ4wDAYDVQQREwU2MzMyOTESMBAGA1UEBxMJRWdlbHNi" - + "YWNoMQswCQYDVQQGEwJERTEKMAgGA1UEBRMBMTCBnzANBgkqhkiG9w0BAQEFAAOB" - + "jQAwgYkCgYEAn7z6Ba9wpv/mNBIaricY/d0KpxGpqGAXdqKlvqkk/seJEoBLvmL7" - + "wZz88RPELQqzDhc4oXYohS2dh3NHus9FpSPMq0JzKAcE3ArrVDxwtXtlcwN2v7iS" - + "TcHurgLOb9C/r8JdsMHNgwHMkkdp96cJk/sioyP5sLPYmgWxg1JH0vMCAwEAAaOB" - + "gDB+MAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUDAwfAADBKBgNVHSMEQzBBoTyk" - + "OjEQMA4GA1UEAxMHUENBMTpQTjEZMBcGA1UEChMQRGV1dHNjaGUgUG9zdCBBRzEL" - + "MAkGA1UEBhMCREWCAQEwEQYDVR0OBAoECEAeJ6R3USjxMA0GCSqGSIb3DQEBBQUA" - + "A4GBADMRtdiQJF2fg7IcedTjnAW+QGl/wNSKy7A4oaBQeahcruo+hzH+ZU+DsiSu" - + "TJZaf2X1eUUEPmV+5zZlopGa3HvFfgmIYIXBw9ZO3Qb/HWGsPNgW0yg5eXEGwNEt" - + "vV85BTMGuMjiuDw841IuAZaMKqOKnVXHmd2pLJz7Wv0MLJhw"); - - private static final byte[] caCert3 = Base64 - .decode("MIICUjCCAb6gAwIBAgIDD2ptMAoGBiskAwMBAgUAMG8xCzAJBgNVBAYTAkRFMT0w" - + "OwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0" - + "aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjRSLUNBIDE6UE4w" - + "IhgPMjAwMDA0MTIwODIyMDNaGA8yMDA0MDQxMjA4MjIwM1owWzELMAkGA1UEBhMC" - + "REUxGTAXBgNVBAoUEERldXRzY2hlIFBvc3QgQUcxMTAMBgcCggYBCgcUEwExMCEG" - + "A1UEAxQaQ0EgREVSIERFVVRTQ0hFTiBQT1NUIDU6UE4wgZ8wDQYJKoZIhvcNAQEB" - + "BQADgY0AMIGJAoGBAIH3c+gig1KkY5ceR6n/AMq+xz7hi3f0PMdpwIe2v2w6Hu5k" - + "jipe++NvU3r6wakIY2royHl3gKWrExOisBico9aQmn8lMJnWZ7SUbB+WpRn0mAWN" - + "ZM9YT+/U5hRCffeeuLWClzrbScaWnAeaaI0G+N/QKnSSjrV/l64jogyADWCTAgMB" - + "AAGjEjAQMA4GA1UdDwEB/wQEAwIBBjAKBgYrJAMDAQIFAAOBgQAaV5WClEneXk9s" - + "LO8zTQAsf4KvDaLd1BFcFeYM7kLLRHKeWQ0MAd0xkuAMme5NVwWNpNZP74B4HX7Q" - + "/Q0h/wo/9LTgQaxw52lLs4Ml0HUyJbSFjoQ+sqgjg2fGNGw7aGkVNY5dQTAy8oSv" - + "iG8mxTsQ7Fxaush3cIB0qDDwXar/hg=="); - - private static final byte[] crossCert3 = Base64 - .decode("MIICVDCCAcCgAwIBAgIDDIOsMAoGBiskAwMBAgUAMG8xCzAJBgNVBAYTAkRFMT0w" - + "OwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0" - + "aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjRSLUNBIDE6UE4w" - + "IhgPMjAwMDAzMjIwOTQzNTBaGA8yMDA0MDEyMTE2MDQ1M1owbzELMAkGA1UEBhMC" - + "REUxPTA7BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11" - + "bmlrYXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNVItQ0Eg" - + "MTpQTjCBoTANBgkqhkiG9w0BAQEFAAOBjwAwgYsCgYEAih5BUycfBpqKhU8RDsaS" - + "vV5AtzWeXQRColL9CH3t0DKnhjKAlJ8iccFtJNv+d3bh8bb9sh0maRSo647xP7hs" - + "HTjKgTE4zM5BYNfXvST79OtcMgAzrnDiGjQIIWv8xbfV1MqxxdtZJygrwzRMb9jG" - + "CAGoJEymoyzAMNG7tSdBWnUCBQDAAAABMAoGBiskAwMBAgUAA4GBAIBWrl6aEy4d" - + "2d6U/924YK8Tv9oChmaKVhklkiTzcKv1N8dhLnLTibq4/stop03CY3rKU4X5aTfu" - + "0J77FIV1Poy9jLT5Tm1NBpi71m4uO3AUoSeyhJXGQGsYFjAc3URqkznbTL/nr9re" - + "IoBhf6u9cX+idnN6Uy1q+j/LOrcy3zgj"); - - public void performTest() throws Exception - { - certStoretest(); - x509StoreTest(); - } - - private void certStoretest() throws Exception + public void setUp() { - CertStore cs = CertStore.getInstance("X509LDAP", params1, "BC"); - X509CertSelector sl = new X509CertSelector(); - CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); - X509Certificate xcert = (X509Certificate)cf - .generateCertificate(new ByteArrayInputStream(cert1)); - sl.setCertificate(xcert); - Collection coll = cs.getCertificates(sl); - if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) - { - fail("certificate could not be picked from LDAP directory."); - } - - // System.out.println(coll.toArray()[0]); - - sl.setCertificate(null); - sl.setSubject(getSubject(xcert).getEncoded()); - coll = cs.getCertificates(sl); - if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) - { - fail("certificate could not be picked from LDAP directory."); - } - X509CRLSelector sl2 = new X509CRLSelector(); - X509CRL crl = (X509CRL)cf.generateCRL(new - ByteArrayInputStream(directCRL)); - sl2.addIssuerName(getCRLIssuer(crl).getEncoded()); - coll = cs.getCRLs(sl2); - if (!coll.iterator().hasNext()) + if (Security.getProvider("BC") == null) { - fail("CRL could not be picked from LDAP directory."); - } - // System.out.println(coll.toArray()[0]); - - cs = CertStore.getInstance("X509LDAP", params2, "BC"); - sl = new X509CertSelector(); - xcert = (X509Certificate)cf - .generateCertificate(new ByteArrayInputStream(cert2)); - sl.setCertificate(xcert); - coll = cs.getCertificates(sl); - if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) - { - fail("Certificate could not be picked from LDAP directory."); - } - - // System.out.println(coll.toArray()[0]); - - cs = CertStore.getInstance("X509LDAP", params3, "BC"); - sl = new X509CertSelector(); - xcert = (X509Certificate)cf - .generateCertificate(new ByteArrayInputStream(cert3)); - sl.setCertificate(xcert); - coll = cs.getCertificates(sl); - if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) - { - fail("Certificate could not be picked from LDAP directory."); + Security.addProvider(new BouncyCastleProvider()); } + } - // System.out.println(coll.toArray()[0]); + public void testLdapFilter() + throws Exception + { + BcFilterCheck filterCheck = new BcFilterCheck(); + + //start mock ldap server for logging + InMemoryDirectoryServer ds = mockLdapServer(filterCheck); + ds.startListening(); + + KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC"); + + kpg.initialize(256); + + //generate malicious certificate + String subject = "CN=chars[*()\\\0]"; + X509Certificate cert = TestUtils.createSelfSignedCert(new X500Name(subject), "SHA256withECDSA", kpg.generateKeyPair()); + +// Attribute[] attr1 = +// { +// new Attribute("objectClass", "top", "person", "organizationalPerson", +// "inetOrgPerson"), +// new Attribute("uid", "john.doe"), +// new Attribute("givenName", "John"), +// new Attribute("sn", "Doe"), +// new Attribute("cn", "chars[*()\\\0]") +// }; +// LDAPResult result = ds.add("dc=test", attr1); +// +// Attribute[] attributes = +// { +// new Attribute("objectClass", "top", "person", "organizationalPerson", +// "inetOrgPerson"), +// new Attribute("uid", "john.doe"), +// new Attribute("givenName", "John"), +// new Attribute("sn", "Doe"), +// new Attribute("cn", "chars[*()\\\0]") +// }; +// result = ds.add("uid=john.doe,dc=test", attributes); + readEntriesFromFile(ds); +// testMemberOf(ds); + + //trigger the exploit + verifyCert(cert); + + //shut down ldap server + ds.shutDown(true); + + assertTrue(filterCheck.isUsed()); + } - xcert = (X509Certificate)cf - .generateCertificate(new ByteArrayInputStream(caCert3)); - sl = new X509CertSelector(); - sl.setSubject(getSubject(xcert).getEncoded()); - coll = cs.getCertificates(sl); - boolean found = false; - if (coll.isEmpty()) - { - fail("Certificate could not be picked from LDAP directory."); - } + private static InMemoryDirectoryServer mockLdapServer(BcFilterCheck filterCheck) + throws Exception + { + InMemoryDirectoryServerConfig serverConfig = new InMemoryDirectoryServerConfig("dc=test"); + serverConfig.setListenerConfigs(new InMemoryListenerConfig( + "listen", + InetAddress.getByName("0.0.0.0"), + 1389, + ServerSocketFactory.getDefault(), + SocketFactory.getDefault(), + (SSLSocketFactory) SSLSocketFactory.getDefault())); + + serverConfig.addInMemoryOperationInterceptor(filterCheck); + + return new InMemoryDirectoryServer(serverConfig); + } - for (Iterator it = coll.iterator(); it.hasNext();) + public static void readEntriesFromFile(InMemoryDirectoryServer ds) throws IOException, LDAPException, LDIFException + { + InputStream src = TestResourceFinder.findTestResource("ldap/", "X509LDAPCertTest.ldif"); + BufferedReader bin = new BufferedReader(new InputStreamReader(src)); + String line = null; + List entry = new ArrayList(); + while ((line = bin.readLine()) != null) { - if (it.next().equals(xcert)) + if (line.isEmpty()) { - found = true; - break; + // End of entry, add to list and reset + if (entry.size() > 0) + { + addEntry(ds, entry.toArray(new String[0])); + entry.clear(); + } } - } - if (!found) - { - fail("Certificate could not be picked from LDAP directory."); - } - - // System.out.println(coll.toArray()[0]); - - sl = new X509CertSelector(); - xcert = (X509Certificate)cf - .generateCertificate(new ByteArrayInputStream(crossCert3)); - sl = new X509CertSelector(); - sl.setSubject(getSubject(xcert).getEncoded()); - coll = cs.getCertificates(sl); - if (coll.isEmpty()) - { - fail("Cross certificate pair could not be picked from LDAP directory."); - } - found = false; - for (Iterator it = coll.iterator(); it.hasNext();) - { - if (it.next().equals(xcert)) + else { - found = true; - break; + // Add entry line and attributes + line = line.replaceAll("\\\\0", "\0"); + entry.add(line); } } - if (!found) + bin.close(); + if (entry.size() > 0) { - fail("Cross certificate pair could not be picked from LDAP directory."); + addEntry(ds, entry.toArray(new String[0])); + entry.clear(); } - // System.out.println(coll.toArray()[0]); } - private void x509StoreTest() throws Exception +// public static void testMemberOf(InMemoryDirectoryServer ds) +// throws Exception +// { +// +// addEntry(ds, "dn: dc=test", "objectClass: top", "objectClass: domain", "dc: test"); +// +// ObjectClassDefinition oc = new ObjectClassDefinition("10.19.19.78", new String[]{"user"}, "", false, new String[]{"TOP"}, +// ObjectClassType.STRUCTURAL, new String[]{"memberOf"}, +// new String[]{}, new HashMap()); +// addEntry(ds, "dn: cn=schema2,dc=test", "objectClass: top", "objectClass: ldapSubEntry", "objectClass: subschema", "cn: schema2", +// "objectClasses: " + oc.toString()); +// +// addEntry(ds, "dn: dc=people,dc=test", "objectClass: top", "objectClass: domain", "dc: people"); +// addEntry(ds, "dn: dc=groups,dc=test", "objectClass: top", "objectClass: domain", "dc: groups"); +// addEntry(ds, "dn: cn=test-group,dc=groups,dc=test", "objectClass: groupOfUniqueNames", "cn: test group"); +// addEntry(ds, "dn: cn=Testy Tester,dc=people,dc=test", "objectClass: Person", "objectClass: organizationalPerson", "sn: Tester", "cn: Testy Tester"); +// addEntry(ds, "dn: cn=chars[*()\\\0],dc=people,dc=test", "objectClass: Person", "objectClass: organizationalPerson", "sn: chars", "cn: chars[*()\\\0]"); +// } + + public static void addEntry(InMemoryDirectoryServer ds, String... args) + throws LDIFException, LDAPException { - X509Store cs = X509Store.getInstance("CERTIFICATE/LDAP", params1, "BC"); - - X509CertStoreSelector sl = new X509CertStoreSelector(); - CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); - X509Certificate xcert = (X509Certificate)cf - .generateCertificate(new ByteArrayInputStream(cert1)); - sl.setCertificate(xcert); - Collection coll = cs.getMatches(sl); - if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) - { - fail("certificate could not be picked from LDAP directory."); - } - - // System.out.println(coll.toArray()[0]); - - sl.setCertificate(null); - sl.setSubject(getSubject(xcert).getEncoded()); - coll = cs.getMatches(sl); - if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) - { - fail("certificate could not be picked from LDAP directory."); - } - X509CRLStoreSelector sl2 = new X509CRLStoreSelector(); - X509CRL crl = (X509CRL)cf.generateCRL(new - ByteArrayInputStream(directCRL)); - sl2.setIssuers(Collections.singleton(crl.getIssuerX500Principal())); - cs = X509Store.getInstance("CRL/LDAP", params1, "BC"); - coll = cs.getMatches(sl2); - if (!coll.iterator().hasNext()) - { - fail("CRL could not be picked from LDAP directory."); - } - // System.out.println(coll.toArray()[0]); + LDAPResult result = ds.add(args); + assertEquals(0, result.getResultCode().intValue()); + } - cs = X509Store.getInstance("CERTIFICATE/LDAP", params2, "BC"); - sl = new X509CertStoreSelector(); - xcert = (X509Certificate)cf - .generateCertificate(new ByteArrayInputStream(cert2)); - sl.setCertificate(xcert); - coll = cs.getMatches(sl); - if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) - { - fail("Certificate could not be picked from LDAP directory."); - } + static void verifyCert(X509Certificate cert) + throws Exception + { + // Create the selector that specifies the starting certificate + X509CertSelector selector = new X509CertSelector(); + selector.setCertificate(cert); - // System.out.println(coll.toArray()[0]); + // Load the JDK's trusted certs + String filename = System.getProperty("java.home") + "/lib/security/cacerts".replace('/', File.separatorChar); + KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); + keystore.load(new FileInputStream(filename), "changeit".toCharArray()); - cs = X509Store.getInstance("CERTIFICATE/LDAP", params3, "BC"); - sl = new X509CertStoreSelector(); - xcert = (X509Certificate)cf - .generateCertificate(new ByteArrayInputStream(cert3)); - sl.setCertificate(xcert); - coll = cs.getMatches(sl); - if (coll.isEmpty() || !coll.iterator().next().equals(xcert)) - { - fail("Certificate could not be picked from LDAP directory."); - } + PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(keystore, selector); - // System.out.println(coll.toArray()[0]); + //setup additional LDAP store + X509LDAPCertStoreParameters CertStoreParameters = new X509LDAPCertStoreParameters.Builder("ldap://127.0.0.1:1389", "CN=certificates").build(); + CertStore certStore = CertStore.getInstance("LDAP", CertStoreParameters, "BC"); + pkixParams.addCertStore(certStore); - xcert = (X509Certificate)cf - .generateCertificate(new ByteArrayInputStream(caCert3)); - sl = new X509CertStoreSelector(); - sl.setSubject(getSubject(xcert).getEncoded()); - coll = cs.getMatches(sl); - boolean found = false; - if (coll.isEmpty()) + // Build and verify the certification chain + try { - fail("Certificate could not be picked from LDAP directory."); - } + CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC"); + PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult)builder.build(pkixParams); - for (Iterator it = coll.iterator(); it.hasNext();) - { - if (it.next().equals(xcert)) - { - found = true; - break; - } } - if (!found) + catch (ExtCertPathBuilderException exception) { - fail("Certificate could not be picked from LDAP directory."); + //expected to fail with ExtCertPathBuilderException: Error finding target certificate. } + } - // System.out.println(coll.toArray()[0]); + /* + check we get a suitably escaped subject. + */ + static class BcFilterCheck + extends InMemoryOperationInterceptor + { + private volatile boolean used = false; - sl = new X509CertStoreSelector(); - xcert = (X509Certificate)cf - .generateCertificate(new ByteArrayInputStream(crossCert3)); - sl.setSubject(getSubject(xcert).getEncoded()); - coll = cs.getMatches(sl); - if (coll.isEmpty()) - { - fail("Cross certificate pair could not be picked from LDAP directory."); - } - found = false; - for (Iterator it = coll.iterator(); it.hasNext();) + public void processSearchResult(InMemoryInterceptedSearchResult result) { - if (it.next().equals(xcert)) - { - found = true; - break; - } - } - if (!found) - { - fail("Cross certificate pair could not be picked from LDAP directory."); - } + String filter = result.getRequest().getFilter().toString(); - // System.out.println(coll.toArray()[0]); + assertEquals("(&(cn=*chars[\\2a\\28\\29\\00]*)(userCertificate=*))", filter); - } + used = true; - private X509Principal getSubject(X509Certificate cert) - throws CertificateEncodingException - { - return PrincipalUtil.getSubjectX509Principal(cert); - } - - private X509Principal getCRLIssuer(X509CRL crl) - throws CRLException - { - return PrincipalUtil.getIssuerX509Principal(crl); - } - - public String getName() - { - return "LDAPCertStoreTest"; - } + result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); + } - public static void main(String[] args) - { - Security.addProvider(new BouncyCastleProvider()); - runTest(new X509LDAPCertStoreTest()); + boolean isUsed() + { + return used; + } } } diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/X509StreamParserTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/X509StreamParserTest.java index b0d1ba76e3..2bd99d40f4 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/X509StreamParserTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/X509StreamParserTest.java @@ -1,25 +1,25 @@ package org.bouncycastle.jce.provider.test; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.security.Security; +import java.security.cert.X509CRL; +import java.security.cert.X509Certificate; +import java.util.Collection; + import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.internal.asn1.cms.CMSObjectIdentifiers; - import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509AttributeCertificate; import org.bouncycastle.x509.X509CertificatePair; import org.bouncycastle.x509.X509StreamParser; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.security.Security; -import java.security.cert.X509CRL; -import java.security.cert.X509Certificate; -import java.util.Collection; - public class X509StreamParserTest extends SimpleTest { @@ -139,7 +139,7 @@ public void performTest() // parser = X509StreamParser.getInstance("Certificate", "BC"); - parser.init(PEMData.CERTIFICATE_1.getBytes("US-ASCII")); + parser.init(Strings.toByteArray(PEMData.CERTIFICATE_1)); res = parser.readAll(); @@ -150,7 +150,7 @@ public void performTest() parser = X509StreamParser.getInstance("Certificate", "BC"); - parser.init(PEMData.CERTIFICATE_2.getBytes("US-ASCII")); + parser.init(Strings.toByteArray(PEMData.CERTIFICATE_2)); res = parser.readAll(); @@ -161,7 +161,7 @@ public void performTest() parser = X509StreamParser.getInstance("CRL", "BC"); - parser.init(PEMData.CRL_1.getBytes("US-ASCII")); + parser.init(Strings.toByteArray(PEMData.CRL_1)); res = parser.readAll(); @@ -172,7 +172,7 @@ public void performTest() parser = X509StreamParser.getInstance("CRL", "BC"); - parser.init(PEMData.CRL_2.getBytes("US-ASCII")); + parser.init(Strings.toByteArray(PEMData.CRL_2)); res = parser.readAll(); @@ -183,7 +183,7 @@ public void performTest() parser = X509StreamParser.getInstance("AttributeCertificate", "BC"); - parser.init(PEMData.ATTRIBUTE_CERTIFICATE_1.getBytes("US-ASCII")); + parser.init(Strings.toByteArray(PEMData.ATTRIBUTE_CERTIFICATE_1)); res = parser.readAll(); @@ -194,7 +194,7 @@ public void performTest() parser = X509StreamParser.getInstance("AttributeCertificate", "BC"); - parser.init(PEMData.ATTRIBUTE_CERTIFICATE_2.getBytes("US-ASCII")); + parser.init(Strings.toByteArray(PEMData.ATTRIBUTE_CERTIFICATE_2)); res = parser.readAll(); diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/nist/NistCertPathReviewerTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/nist/NistCertPathReviewerTest.java index f0daf7acd5..e6ecb03828 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/nist/NistCertPathReviewerTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/nist/NistCertPathReviewerTest.java @@ -33,7 +33,9 @@ import org.bouncycastle.i18n.ErrorBundle; import org.bouncycastle.test.PrintTestResult; import org.bouncycastle.test.TestResourceFinder; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.x509.PKIXCertPathReviewer; import org.bouncycastle.x509.extension.X509ExtensionUtil; @@ -43,6 +45,8 @@ public class NistCertPathReviewerTest extends TestCase { + private static final String NNBSP = Strings.fromUTF8ByteArray(Hex.decode("e280af")); + private static final String GOOD_CA_CERT = "GoodCACert"; private static final String GOOD_CA_CRL = "GoodCACRL"; @@ -522,7 +526,7 @@ private void doErrorTest( { ErrorBundle msg = (ErrorBundle) result.getErrors(index).iterator().next(); assertEquals(messageId,msg.getId()); - assertEquals(message,msg.getText(Locale.ENGLISH,TimeZone.getTimeZone("GMT")).replace("Greenwich Mean Time", "GMT")); + assertEquals(message,msg.getText(Locale.ENGLISH,TimeZone.getTimeZone("GMT")).replace("Greenwich Mean Time", "GMT").replace(NNBSP, " ")); } } diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/nist/PKITSTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/nist/PKITSTest.java index 6c7e47169c..327f1ed319 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/nist/PKITSTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/nist/PKITSTest.java @@ -40,8 +40,8 @@ class PKITSTest { private Set trustAnchors = new HashSet(); - private ArrayList certs = new ArrayList(); - private ArrayList crls = new ArrayList(); + private List certs = new ArrayList(); + private List crls = new ArrayList(); private Set policies = new HashSet(); // @@ -293,12 +293,12 @@ public Set getTrustAnchors() return trustAnchors; } - public ArrayList getCerts() + public List getCerts() { return certs; } - public ArrayList getCrls() + public List getCrls() { return crls; } @@ -403,7 +403,6 @@ private X509CRL loadCrl( crlBuffer.put(crlName, crl); } - return crl; } catch (Exception e) @@ -427,7 +426,7 @@ private TrustAnchor getTrustAnchor(String trustAnchorName) return new TrustAnchor(cert, null); } - + public PKITSTest withEndEntity(String endCert) { endCert = endCert.replace(" ", "").replace("-", ""); diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/rsa3/AllTests.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/rsa3/AllTests.java index 80013913b5..4df296759f 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/rsa3/AllTests.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/rsa3/AllTests.java @@ -14,7 +14,7 @@ public class AllTests { public static void main (String[] args) { - PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); + PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); } public static Test suite() diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/AllTests.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/AllTests.java index 96d2df782a..693dae7730 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/AllTests.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/AllTests.java @@ -46,6 +46,8 @@ public static Test suite() suite.addTestSuite(LMSTest.class); suite.addTestSuite(SphincsPlusTest.class); suite.addTestSuite(SphincsPlusKeyPairGeneratorTest.class); + suite.addTestSuite(SLHDSAKeyPairGeneratorTest.class); + suite.addTestSuite(SLHDSATest.class); suite.addTestSuite(PicnicTest.class); suite.addTestSuite(PicnicKeyPairGeneratorTest.class); suite.addTestSuite(CMCEKeyPairGeneratorTest.class); @@ -63,10 +65,16 @@ public static Test suite() suite.addTestSuite(SNTRUPrimeKeyPairGeneratorTest.class); suite.addTestSuite(KyberTest.class); suite.addTestSuite(KyberKeyPairGeneratorTest.class); + suite.addTestSuite(MLKEMTest.class); + suite.addTestSuite(MLKEMKeyPairGeneratorTest.class); suite.addTestSuite(DilithiumKeyPairGeneratorTest.class); suite.addTestSuite(DilithiumTest.class); + suite.addTestSuite(MLDSAKeyPairGeneratorTest.class); + suite.addTestSuite(MLDSATest.class); suite.addTestSuite(BIKEKeyPairGeneratorTest.class); suite.addTestSuite(BIKETest.class); + suite.addTestSuite(HQCKeyPairGeneratorTest.class); + suite.addTestSuite(HQCTest.class); suite.addTestSuite(RainbowKeyPairGeneratorTest.class); suite.addTestSuite(RainbowTest.class); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/DilithiumKeyPairGeneratorTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/DilithiumKeyPairGeneratorTest.java index 7d08d06086..122847af29 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/DilithiumKeyPairGeneratorTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/DilithiumKeyPairGeneratorTest.java @@ -1,13 +1,18 @@ package org.bouncycastle.pqc.jcajce.provider.test; import java.security.KeyFactory; +import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; +import java.security.Security; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.pqc.jcajce.spec.DilithiumParameterSpec; /** - * KeyFactory/KeyPairGenerator tests for Dilithium with BCPQC provider. + * KeyFactory/KeyPairGenerator tests for Dilithium with BC provider. */ public class DilithiumKeyPairGeneratorTest extends KeyPairGeneratorTest @@ -15,12 +20,42 @@ public class DilithiumKeyPairGeneratorTest protected void setUp() { super.setUp(); + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastleProvider()); + } } public void testKeyFactory() throws Exception { - kf = KeyFactory.getInstance("Dilithium", "BCPQC"); + kf = KeyFactory.getInstance("Dilithium", "BC"); + } + + public void testKeyPairGeneratorNames() + throws Exception + { + ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[] { + BCObjectIdentifiers.dilithium2, + BCObjectIdentifiers.dilithium3, + BCObjectIdentifiers.dilithium5 + }; + + String[] algs = new String[]{ + "DILITHIUM2", + "DILITHIUM3", + "DILITHIUM5" + }; + + for (int i = 0; i != oids.length; i++) + { + KeyPairGenerator kpGen = KeyPairGenerator.getInstance(oids[i].getId(), "BC"); + + KeyPair kp = kpGen.generateKeyPair(); + + assertEquals(algs[i], kp.getPrivate().getAlgorithm()); + assertEquals(algs[i], kp.getPublic().getAlgorithm()); + } } public void testKeyPairEncoding() @@ -32,9 +67,6 @@ public void testKeyPairEncoding() DilithiumParameterSpec.dilithium2, DilithiumParameterSpec.dilithium3, DilithiumParameterSpec.dilithium5, - DilithiumParameterSpec.dilithium2_aes, - DilithiumParameterSpec.dilithium3_aes, - DilithiumParameterSpec.dilithium5_aes, }; kf = KeyFactory.getInstance("Dilithium", "BCPQC"); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/DilithiumTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/DilithiumTest.java index 008b9176e5..dd043070d0 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/DilithiumTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/DilithiumTest.java @@ -18,17 +18,19 @@ import junit.framework.TestCase; import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1OctetString; -import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.pqc.jcajce.interfaces.DilithiumKey; import org.bouncycastle.pqc.jcajce.interfaces.DilithiumPrivateKey; -import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; import org.bouncycastle.pqc.jcajce.spec.DilithiumParameterSpec; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; +/** + * Dilithum now in BC provider + */ public class DilithiumTest extends TestCase { @@ -36,22 +38,22 @@ public class DilithiumTest public void setUp() { - if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { - Security.addProvider(new BouncyCastlePQCProvider()); + Security.addProvider(new BouncyCastleProvider()); } } public void testPrivateKeyRecovery() throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("Dilithium", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("Dilithium", "BC"); kpg.initialize(DilithiumParameterSpec.dilithium3, new DilithiumTest.RiggedRandom()); KeyPair kp = kpg.generateKeyPair(); - KeyFactory kFact = KeyFactory.getInstance("Dilithium", "BCPQC"); + KeyFactory kFact = KeyFactory.getInstance("Dilithium", "BC"); DilithiumKey privKey = (DilithiumKey)kFact.generatePrivate(new PKCS8EncodedKeySpec(kp.getPrivate().getEncoded())); @@ -84,13 +86,13 @@ public void testPrivateKeyRecovery() public void testPublicKeyRecovery() throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("Dilithium", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("Dilithium", "BC"); kpg.initialize(DilithiumParameterSpec.dilithium5, new DilithiumTest.RiggedRandom()); KeyPair kp = kpg.generateKeyPair(); - KeyFactory kFact = KeyFactory.getInstance("Dilithium", "BCPQC"); + KeyFactory kFact = KeyFactory.getInstance("Dilithium", "BC"); DilithiumKey pubKey = (DilithiumKey)kFact.generatePublic(new X509EncodedKeySpec(kp.getPublic().getEncoded())); @@ -120,21 +122,18 @@ public void testRestrictedSignature() doTestRestrictedSignature("DILITHIUM2", DilithiumParameterSpec.dilithium2, DilithiumParameterSpec.dilithium5); doTestRestrictedSignature("DILITHIUM3", DilithiumParameterSpec.dilithium3, DilithiumParameterSpec.dilithium5); doTestRestrictedSignature("DILITHIUM5", DilithiumParameterSpec.dilithium5, DilithiumParameterSpec.dilithium2); - doTestRestrictedSignature("DILITHIUM2-AES", DilithiumParameterSpec.dilithium2_aes, DilithiumParameterSpec.dilithium5); - doTestRestrictedSignature("DILITHIUM3-AES", DilithiumParameterSpec.dilithium3_aes, DilithiumParameterSpec.dilithium5); - doTestRestrictedSignature("DILITHIUM5-AES", DilithiumParameterSpec.dilithium5_aes, DilithiumParameterSpec.dilithium5); } private void doTestRestrictedSignature(String sigName, DilithiumParameterSpec spec, DilithiumParameterSpec altSpec) throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("Dilithium", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("Dilithium", "BC"); kpg.initialize(spec, new SecureRandom()); KeyPair kp = kpg.generateKeyPair(); - Signature sig = Signature.getInstance(sigName, "BCPQC"); + Signature sig = Signature.getInstance(sigName, "BC"); sig.initSign(kp.getPrivate(), new SecureRandom()); @@ -142,7 +141,7 @@ private void doTestRestrictedSignature(String sigName, DilithiumParameterSpec sp byte[] s = sig.sign(); - sig = Signature.getInstance(sigName, "BCPQC"); + sig = Signature.getInstance(sigName, "BC"); assertEquals(sigName, sig.getAlgorithm()); @@ -152,7 +151,7 @@ private void doTestRestrictedSignature(String sigName, DilithiumParameterSpec sp assertTrue(sig.verify(s)); - kpg = KeyPairGenerator.getInstance("Dilithium", "BCPQC"); + kpg = KeyPairGenerator.getInstance("Dilithium", "BC"); kpg.initialize(altSpec, new SecureRandom()); @@ -175,15 +174,12 @@ public void testRestrictedKeyPairGen() doTestRestrictedKeyPairGen(DilithiumParameterSpec.dilithium2, DilithiumParameterSpec.dilithium5); doTestRestrictedKeyPairGen(DilithiumParameterSpec.dilithium3, DilithiumParameterSpec.dilithium5); doTestRestrictedKeyPairGen(DilithiumParameterSpec.dilithium5, DilithiumParameterSpec.dilithium2); - doTestRestrictedKeyPairGen(DilithiumParameterSpec.dilithium2_aes, DilithiumParameterSpec.dilithium5); - doTestRestrictedKeyPairGen(DilithiumParameterSpec.dilithium3_aes, DilithiumParameterSpec.dilithium5); - doTestRestrictedKeyPairGen(DilithiumParameterSpec.dilithium5_aes, DilithiumParameterSpec.dilithium5); } private void doTestRestrictedKeyPairGen(DilithiumParameterSpec spec, DilithiumParameterSpec altSpec) throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance(spec.getName(), "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance(spec.getName(), "BC"); kpg.initialize(spec, new SecureRandom()); @@ -193,7 +189,7 @@ private void doTestRestrictedKeyPairGen(DilithiumParameterSpec spec, DilithiumPa assertEquals(spec.getName(), kp.getPublic().getAlgorithm()); assertEquals(spec.getName(), kp.getPrivate().getAlgorithm()); - kpg = KeyPairGenerator.getInstance(spec.getName(), "BCPQC"); + kpg = KeyPairGenerator.getInstance(spec.getName(), "BC"); try { @@ -209,13 +205,13 @@ private void doTestRestrictedKeyPairGen(DilithiumParameterSpec spec, DilithiumPa public void testDilithiumRandomSig() throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("Dilithium", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("Dilithium", "BC"); kpg.initialize(DilithiumParameterSpec.dilithium2, new SecureRandom()); KeyPair kp = kpg.generateKeyPair(); - Signature sig = Signature.getInstance("Dilithium", "BCPQC"); + Signature sig = Signature.getInstance("Dilithium", "BC"); sig.initSign(kp.getPrivate(), new SecureRandom()); @@ -223,7 +219,7 @@ public void testDilithiumRandomSig() byte[] s = sig.sign(); - sig = Signature.getInstance("Dilithium", "BCPQC"); + sig = Signature.getInstance("Dilithium", "BC"); sig.initVerify(kp.getPublic()); @@ -233,24 +229,25 @@ public void testDilithiumRandomSig() } /** - * count = 0 - * seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 - * mlen = 33 - * msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 - * pk = 096BA86CB658A8F445C9A5E4C28374BEC879C8655F68526923240918074D0147C03162E4A49200648C652803C6FD7509AE9AA799D6310D0BD42724E0635920186207000767CA5A8546B1755308C304B84FC93B069E265985B398D6B834698287FF829AA820F17A7F4226AB21F601EBD7175226BAB256D8888F009032566D6383D68457EA155A94301870D589C678ED304259E9D37B193BC2A7CCBCBEC51D69158C44073AEC9792630253318BC954DBF50D15028290DC2D309C7B7B02A6823744D463DA17749595CB77E6D16D20D1B4C3AAD89D320EBE5A672BB96D6CD5C1EFEC8B811200CBB062E473352540EDDEF8AF9499F8CDD1DC7C6873F0C7A6BCB7097560271F946849B7F373640BB69CA9B518AA380A6EB0A7275EE84E9C221AED88F5BFBAF43A3EDE8E6AA42558104FAF800E018441930376C6F6E751569971F47ADBCA5CA00C801988F317A18722A29298925EA154DBC9024E120524A2D41DC0F18FD8D909F6C50977404E201767078BA9A1F9E40A8B2BA9C01B7DA3A0B73A4C2A6B4F518BBEE3455D0AF2204DDC031C805C72CCB647940B1E6794D859AAEBCEA0DEB581D61B9248BD9697B5CB974A8176E8F910469CAE0AB4ED92D2AEE9F7EB50296DAF8057476305C1189D1D9840A0944F0447FB81E511420E67891B98FA6C257034D5A063437D379177CE8D3FA6EAF12E2DBB7EB8E498481612B1929617DA5FB45E4CDF893927D8BA842AA861D9C50471C6D0C6DF7E2BB26465A0EB6A3A709DE792AAFAAF922AA95DD5920B72B4B8856C6E632860B10F5CC08450003671AF388961872B466400ADB815BA81EA794945D19A100622A6CA0D41C4EA620C21DC125119E372418F04402D9FA7180F7BC89AFA54F8082244A42F46E5B5ABCE87B50A7D6FEBE8D7BBBAC92657CBDA1DB7C25572A4C1D0BAEA30447A865A2B1036B880037E2F4D26D453E9E913259779E9169B28A62EB809A5C744E04E260E1F2BBDA874F1AC674839DDB47B3148C5946DE0180148B7973D63C58193B17CD05D16E80CD7928C2A338363A23A81C0608C87505589B9DA1C617E7B70786B6754FBB30A5816810B9E126CFCC5AA49326E9D842973874B6359B5DB75610BA68A98C7B5E83F125A82522E13B83FB8F864E2A97B73B5D544A7415B6504A13939EAB1595D64FAF41FAB25A864A574DE524405E878339877886D2FC07FA0311508252413EDFA1158466667AFF78386DAF7CB4C9B850992F96E20525330599AB601D454688E294C8C3E - * sk = 59044102F3CFBE1BE03C144102F7EF75FBEF83043F7CFC20C20BEEC007DE3F041FBF0BFF401041030C40040FAE7E103F7E100085FC013D1410C80C2F000810461C2F480BEE8017D17F07F1411BA24013C1BDF83DC407D17E07C13917F0F9044045FC40BD0FF07D07EF0003DFC1F3CFFD1FC03FEFC0B8FC6E7B0BBDBD0FE0BE17D14307EFFE0FBFC6F81FBFF43EC1F87041D42083EC3DC2F4407BF84EC4140FC403F037F3FEC013E0FEE02180082F83FBE07BFFE043F40EC6FFB1BF200007FFBFFA0FFF6FFBCE83EBFEBEFC0FFDF3F103FC6F3FF0500A18718308007D03F200E4213BF04FFD17D000F0017A17F180E04FFF07DEC2244048148E8704503EE06F86080243F81FFF03BF4003F07EF3DE02FBFFC00420C1F40FBDF0707E043FF5FFD0000430400C4F49F4207C142F80EC3E010BFF7C13F07FF85F7F17E07C17FF33FC4EC303FFBCFFEEC41830FF0831BDF45F05F06FC503B0C0F84E4013E100E7E1441450C2FBEEBC0C0FBEFC60BCFFEF3CFBDF4303EF800BF2BE0BF001F01F43F41FFE08517B001141E00144F7EF8007CEBDFFFF4213A0B9F8A0FE04103C17E0820BB1C30C30C00FFFFC00007D18017CFF90C3101E7E103040FC4FBE04213E07AF80FFEFC80FBFBD0810BCFB8FBC087FB8FFF1010C2E81002F3EF3BF01F07E41FBC07F2C0FB8F43F401C5D81FFCEBE07C07E0BF17EEBEE830C514003FF7EF3E08403D1FFFFE105F840C20BDF0607FFFEF46E7EFFF08000400DE830000F3F82EF9D82E84EFFF3CEC4E81E01002103102EFC080F3B0801041BAE42F7F040F83EC31010031BC0410FAFF9F0004010133A089FFEF7BE8317A0020FEF010052BA04107E100F821C2F41F44F4EF7B000F02E41F82F380830FE08A1F707FF82EC7F42E81004041103E8307B13D0FDFF8F830F9FC5FFCD7E040F410FFFB9F423750860C11C5FFA144EC0080F02DC0F420820450790020BCF80EFFFBCEC4FBFF4200AFC00C02060C004303EF81FFA104107E4117AF01F81202FC1E44143FFE206EB3E881BB13F13920403FF7A000144102E7FFC2143E7FF4AF3F13F07E181DC317E240F4500303F2DDDCF1E1513E3EF15E8DC1309E50AEE03EFDC17081706FD03E6ECE4F30EBD1909051906E90CE806EB0B19E719EFFBF10D0DF1DC0CF6F1F4F8FEFBE9F9550E2107FCDCCBDFE9F4F7EE1AF8142115F910002AF2F5FF141ADA220AECFE040CEF0B29EB201930F2D3E401E5DEEFF4DDEA17F1FE141217F81C36050109F8F61F02DD19F90310C7F40208E9052C3942F8FFF2CCF9FDF83CFA12DC091C0D02F00411F5281E40D7F92DBA11D73D04C10BFD13E617110AF3ED05F6CFE705E0F70E1FF80533FC120C002CE81FF52638190FE3FED6F0FBBB23E6F408EF32220B13DD27F007E5FA00D72614F0E302210707EC111E070E2A032DF91DE3FCE800F1F9F2F7FE170101180412CBD1E90019F2011522DAEAED13F8E5F425DCEF24E01CE614E7DCEC01F2F4F914F4010107ED26E2E9DF0BF5F007EA07FAFBC6D7E607FAFCFD270DFD0D17FC4EF0EE00071AECDE09F8F215E113F80209CCF308D7E6251ECE0EDFED0CC9F4050B2714F61BF703F0EBF104010DEBFBF21AFC1BF01823FEDEFAF7F807E3F3020AEB01FE19EEE8E90D00E5FAED1EFDF628E5F0E6F0FC13F4FB05FB0B09EA0A0E08EE13293212E90CE4FEF223F4FF030BEBED1B402ED2F6171102BC0CF9E9F335ED0C01FAF0FEFAE41DF0050A162C11171CD90BEE211218EDFAFA0F03F4171412F319D60B01FAEE1F2823F0D6EF12D6DFEAFBFC170DECDA06E7CED500031E - * sm = 026833B3C07507E4201748494D832B6EE2A6C93BFF9B0EE343B550D1F85A3D0DE0D704C6D17842951309D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8290765843D1E460D17A527D2BCA405BD55BBC7DA09A8C620BE0AF4A767D9DB96B80F55E466676751EAABA7B93B86D71132DAA0EB376782B9EEE37519CE10FDD33FE9F29312C31D8736206D165CF4C528AA3DDC017845E1F0DD5B0A44FF961C42D874A95533E5B438982F524CA954D87533BFBE42C63FF2ABC77A34C79DB55A99171BBCB72C842A6530AF2F753F0C34AC632F9F1E7949F0BF6C67665B27722A8857D626B6FF1A136D923A39F4069B7477FF946E5247A6627791D49B59EDC9E2525A860E6E9828D18F64A9F17222E8166A02453859BBDA0B8186D8C9928BB571E4146401D7430E225904673AD21CCAC54C146C248A1DD69AB6491E901D6D71B152155BE97DE057F3916A3F1B4273308C29B2F4D9697167B90681B1583ED930A71E990467DEA368134BECEEBD597F9BEC922E816F1B0570D728F4AE0464C1F797657F87A4E52DCDCAEB9272662EA66D7C6CD8781B31AF555AD93F5F65E75816CB8DC306BB67E592B5261BACA7C509629EA2AF8ABB80CBA89EE535B76DFD9CCBBE3BF48F2BC8AA34B26E1103291053F5CB8DE3A45AFA5A76DF8B2122ED2C82FBCF2259290D41A14F86B12F35F5D49762B34CFF13EE7E42EDEC70201D7F37C33316288FA3078E36E58108865C3CFE263D563692043DECC62F3426F86061285B7B1B336F56FF41BB65E9CD6D9B92FD90F864AA1C923CB8C755F5CDE1770D862595427149D7721AAAB5D194AEA9ACDECA15BE43CBA6A62B5A33909E9FC4DA1C5814FBD7CD6A2FA572E318B42C6C319140B86E66392580A11A2B431F44C1F9270E4F7B2490F3B325A9977A71A575915636635B9969DBD6D220B24C3D99CEBBBD834B88222BD08C3ABE124E80 +count = 0 +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +mlen = 33 +msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 +pk = 1C0EE1111B08003F28E65E8B3BDEB037CF8F221DFCDAF5950EDB38D506D85BEF6177E3DE0D4F1EF5847735947B56D08E841DB2444FA2B729ADEB1417CA7ADF42A1490C5A097F002760C1FC419BE8325AAD0197C52CED80D3DF18E7774265B289912CECA1BE3A90D8A4FDE65C84C610864E47DEECAE3EEA4430B9909559408D11A6ABDB7DB9336DF7F96EAB4864A6579791265FA56C348CB7D2DDC90E133A95C3F6B13601429F5408BD999AA479C1018159550EC55A113C493BE648F4E036DD4F8C809E036B4FBB918C2C484AD8E1747AE05585AB433FDF461AF03C25A773700721AA05F7379FE7F5ED96175D4021076E7F52B60308EFF5D42BA6E093B3D0815EB3496646E49230A9B35C8D41900C2BB8D3B446A23127F7E096D85A1C794AD4C89277904FC6BFEC57B1CDD80DF9955030FDCA741AFBDAC827B13CCD5403588AF4644003C2265DFA4D419DBCCD2064892386518BE9D51C16498275EBECF5CDC7A820F2C29314AC4A6F08B2252AD3CFB199AA42FE0B4FB571975C1020D949E194EE1EAD937BFB550BB3BA8E357A029C29F077554602E1CA2F2289CB9169941C3AAFDB8E58C7F2AC77291FB4147C65F6B031D3EBA42F2ACFD9448A5BC22B476E07CCCEDA2306C554EC9B7AB655F1D7318C2B7E67D5F69BEDF56000FDA98986B5AB1B3A22D8DFD6681697B23A55C96E8710F3F98C044FB15F606313EE56C0F1F5CA0F512E08484FCB358E6E528FFA89F8A866CCFF3C0C5813147EC59AF0470C4AAD0141D34F101DA2E5E1BD52D0D4C9B13B3E3D87D1586105796754E7978CA1C68A7D85DF112B7AB921B359A9F03CBD27A7EAC87A9A80B0B26B4C9657ED85AD7FA2616AB345EB8226F69FC0F48183FF574BCD767B5676413ADB12EA2150A0E97683EE54243C25B7EA8A718606F86993D8D0DACE834ED341EEB724FE3D5FF0BC8B8A7B8104BA269D34133A4CF8300A2D688496B59B6FCBC61AE96062EA1D8E5B410C5671F424417ED693329CD983001FFCD10023D598859FB7AD5FD263547117100690C6CE7438956E6CC57F1B5DE53BB0DC72CE9B6DEAA85789599A70F0051F1A0E25E86D888B00DF36BDBC93EF7217C45ACE11C0790D70E9953E5B417BA2FD9A4CAF82F1FCE6F45F53E215B8355EF61D891DF1C794231C162DD24164B534A9D48467CDC323624C2F95D4402FF9D66AB1191A8124144AFA35D4E31DC86CAA797C31F68B85854CD959C4FAC5EC53B3B56D374B888A9E979A6576B6345EC8522C9606990281BF3EF7C5945D10FD21A2A1D2E5404C5CF21220641391B98BCF825398305B56E58B611FE5253203E3DF0D22466A73B3F0FBE43B9A62928091898B8A0E5B269DB586B0E4DDEF50D682A12D2C1BE824149AA254C6381BB412D77C3F9AA902B688C81715A59C839558556D35ED4FC83B4AB18181F40F73DCD76860D8D8BF94520237C2AC0E463BA09E3C9782380DC07FE4FCBA340CC2003439FD2314610638070D6C9EEA0A70BAE83B5D5D3C5D3FDE26DD01606C8C520158E7E5104020F248CEAA666457C10AEBF068F8A3BD5CE7B52C6AF0ABD5944AF1AD4752C9113976083C03B6C34E1D47ED69644CAD782C2F7D05F8A148961D965FA2E1723A8DDEBC22A90CD783DD1F4DB38FB9AE5A6714B3D946781643D317B7DD79381CF789A9588BB3E193B92A0B60D6B07D047F6984B0609EC57543C394CA8D5E5BCC2A731A79618BD1E2E0DA8704AF98F20F5F8F5452DDF646B95B341DD7F0D2CC1FA15BD9895CD5B65AA1CB94B5E2E788FDA9825B656639193D98328154A4F2C35495A38B6EA0D2FFAAA35DF92C203C7F31CBBCA7BD03C3C2302190CECD161FD49237E4F839E3F3 +sk = 1C0EE1111B08003F28E65E8B3BDEB037CF8F221DFCDAF5950EDB38D506D85BEF394D1695059DFF40AE256C5D5EDABFB69F5F40F37A588F50532CA408A8168AB187D0AD11522110931494BF2CAEAE36979711BC585B32F08C78496F379D604D5321C8C62B59EDC23AE1FC7742135918E01B02E411630E26E675400D5AD2C776FCC0A6711A966C11312AD9A821D8086542A600A4B42C1940720242628106210A43852331709308108B188C022492C1B28412C4218B042181C8610248059C9201C0348819326C582046891868A2C28D82346A1C094200A28CE3A6491C112CC24812E0902191985062C084622451CA062C64240E1BB3312496854B4606DB2668C38268441046C9B6211404811445502442084422710B92459AA0811A91709C241003957004C504C82692D29200C0B260C0A26809190AA2300E188969E0008DD84862DA14712018051907440412409B1240118010D142819928508B1091022464A0206D1246211C838C1B4769010690CC062481846920982C24120521B15041360298446ED1A63111056AD3A840CAA84C62B00003134A53344614194004C54CE306695AB08961168ECB10808B168ED990640B94602483851AB30454262251B8251C424A0B814842C4445A102023808409B7254CC64814854D19380E601651D8326A0A918908C170E0964D18468C01328D91C4054A0061230868A2104210A8611306218A248E620689C9B24508278451200D980466DC42054424852426282221612016090BA62C0A1144E0928158480D422210A006098B246E81288CC0248090308D8436404CA68450042494B68DA2926D18B344A00085E3B805140504A4C290842281C3262D0B2066CC903198382810166CC13445C0102224C688034632D840901C20680415289A188144988D9C206E9C302CC1B820614221080310A0C28C58128553204C0330814CA48D44C08D51404C1CA72C440865A03840DA20808106858C260DE2A88C9C4411594228C42604441426A1426408C0851101869B483199B20C80464459A88C0042089882900AB54562244812960544124600C88813A061E1284D0AB9914B962099B84400314E98128500B60183A00D14150E1881101901224A06681A498DE1A28411C63121262591A06D030524A1B6089444724334125BB42041B650D0888D0B074D1C94644C208E8B8808E0300944200549864D03134E19C9840937611A43684A80900204311C1742184080C8308EE1A241C33404A3282251247188D6FEF46712CA182872AB2919678AFF9D94E743E063A39E0C35CAF72A7F2EDA28E65858520D5D8467DE747CF340653B52C268F55413F5ADDC7D49011EC33EDD537423A84288869337AEA0781A124269071451722DB3BB8F2CE5B1552F83D2AF07F25613918A9F4E6F1257603888E589308CA5F95F07143D23BAAE17520B36B6E0E94FAF6845EB2131AEC383E63BC8644EE5F1ACCBA82F9211E57AFCBF509C1131A37466BC91B357DCBBBC14CCC319C4CC6AC75FCDC82C6596D07770C8277AD370B192A0B4E05F812E0E265D2912AA29F03FC9F72DFA69C9B1291A3FC583642B235F6991A954788347F60A0328C48ECEE51BA02DFF323ABD911667CB14549B618F1C5D250CAC9E35E071601992FBEC0BAE6F74213081404744D12F2A0E04BDB265E0924CADA40D1FA1F38ACA4606BFD4575712B8260A456FDDEEEFE7CA259BCDA97B9B939A5FD2889C9B49FB7D4E3553DEA61B3339BD0E6B16BF3BB227103BF9202E72DC502E28F7CE1559A4631F372520324E4EBA07545F78BF4D94B0E5B8BF51B8F176533D5CFEA5232F283A47605FA65DDB17C891C251011C4E98EEB6EB00CB65BA31C8F025C87A9FE02DBC10C5D83A065EBA5D7B2A19D5A1CB2C160AE166E867F2AF8C7D49D63FB83A614957FC0A3B5A5C74990E9A2B02120C7E6DE37E155FB472F50F0A45E47CF5F9D7A4C82982C9DC86AE877C3FD1885943E439FB003C7A9A42F71B4FF6F0A28B140CBDBA6E71B13AC31B23DE9EAB7837E15A69F833EB7B56A71D8BC2CAF1F2A31C345BD5F46EE013A7C689372337191DAA800C0AC6C46C9FF688B1A01347F257C474AA3D97C1D63A8C00E0A37B681673F57C1C9C8FCCD46F174C74A29D84CEB71F7E6B2F8CD2B089ED43F7C96DAE81A223418C20B16F1DF3D1A978AE28F6DF35EC559D04D20EC74B224AEA31A289B015B069E9CBBBF7CF6DE94CFB2A96E4AE3462C96003CDDA87DB561AF2CE3C0BA1D90413FDCE3CCF4390C02C1CB9F654F4820EC33015457D4A629FBF39419CAB7642D6885E103FCE0D4206CCE7C12C6FC44FA33AD0864C3371A7CBE820E3B371B656A38F2E7FF18FE4A50C8AB3F85D783FB57835CED8490B84EE0D99AF0D64C483CEB6366FF54F8AC8A40DB1AFA573A4FB326C74F0236ECEF3DA7120665CCE05DD654B5071723A8348E7CD7793513819B61CB64E1328E8B22E7664BD6B41B5710D19EA8809D4450850E907DFC4D0B75F588CECE962E9E0937CE1402446A4D2891A46E6617FB29D4FCD712606F7819ECA60F7E0D5B19E7FFB57C73C16FFEEB90038410CB9FCBB5E9D51EB3EB6297E9FF6AB7088FE2D9B237BC24CF7F8290118A5E0E00A0B903FB6375C848176CD0A8C8875CC59199CDA11A87A78F65CC404330B087571FD0633E27129FDAB5A8A1F793E52412B0083FD5C74DB3CF60C2543CE7C91B2800E40203F8D99FE5FDE5B108E7EDC80EBB9BB34986EC5C5A8F580E75752907FF0F294C866C2CF1F362E840B6881BD43219201781C63B0039A95BCFB4A0FECE569DF00523CE9C084B022B3B022242E28419796ACF0A0C995F948DBFFFD30D77ED105A3C9943C406B305BC81A6A248A291548F2A67F438D966A57D53F4B7BE15354E581BE16F7AD64D164E85787DF5849C810AFC28D06482F441B5FDE3DB2ED36DD25AA6664D4D43FFA32EDA25689C9F4A5D514FC66231C5401520922524438EF1DC78D693C9718DEBBD243312674C899F18910E389C8EBE505824BCC42CD4A9ACE193768220219011F3B1F335427BFF9E8BDED5C08711A09C2B71CB964C56A8393BFD2B56E9B6B2F513E682587DC1B8ED196066326871025628036700063176D345DE384E182D6C417A32AB11095EF59BB4D171B9CF81D17AC42664DED933CCB722C69857FFC53C8E7F2474B0CB2DFF2DDC8A5C601C84A701981199BCCF74112A6EC062C4FEB601A028AF01032ADB6BD15D4C2B9550AA850AD62CCC3A3665D5212B12E0FD5C5326A1E5EB1F10D557D94605E8E3F356E08FF7FD884ED3C4205463594C9AF2F39E4B1274695234B54EECED93F460EDF1A13C2CB4B17D322F6F79FE16F0357C1C4739863E796791F8647FABF730AB00E0DA509706D94571740F61F7BAF366D2774C9B5B8C61DD6BE9819A6028B264BB2E4AEA54B56D4ECAB5B528CE0C0C0CCDB73023352CB00445BAB6F7467B4644D4361C464FAC6B5B137D32391021B475FCB5F31774FD8ECABDF65475F25574C65559CB331F41C0F498B74DD941C344C50D8E64F9578714A32561FAACEAF78148E6DA4B566826925714B17108AFDD546385A3CD454D5CAA16960916282A47C4315CE236BD9E3255C604EBDC39772DB5CE0B236 +smlen = 2453 +sm = 3D7F3A26A1A6DC133D036981F7406AE0858C74121BDA303DD5DA8D9ACB68409F1051C88C4B163C252DDB5E78E8EB867279A17289B34CD3BA4AA199AE56B28356EE49FF8304086E7CAA6B0DBA7EF60AD5ED9411A82FF9BE7D6177908977EF67CCD532A4723F125F4748B350C3948F2AC6C4F006CACB8C92CDC0941CDE2EFB4B732BF85954F4BA8417561403A863E0261A29D79987859976B4F8BDC7BC5EF215A07ED6004343CC7CFE79ECC7143AFD525CA35ADB5D603CAF97BD0A80104E4DE48FB41668F314415096E3547554D25FA09E9C14E60BD15A6DDCD0710A0FED464079229CA65A636E15D9215283767241FB6EED385B51416660F95AA8A619B55FA38B9A7CB710FBC0AD6237C72BECFB9D3182229E06A696B5E32B4B2EF2164349B54266BA9734EAD45387CA913507E3E75B49FEA7D3BD03A7EEE2EE8AFE048DD9E38686D5A1C5DB31A8FC960FD3575496CD301CDB952D8CF85792DEDF7FF6FA5BBF5101288EE80AFE1183B4A6689AE72E66B50393DC3345DF62BA2DCB999158FD8FD9A75AF95ED9C3EA325FEC21C5B611B267B938AE02580C72FB94E8910DBA88A32811B6FEE8A04355EBDEEDFAEC85F5FFDD6811FA4A3CC6323CDD93E6CE7F98688022401AF54288BF888B289F972FB98ECABF0D2C364344BBD2FFDAAE518A66370FF6BCA7D996B03BA3140890840E5EDD3EB98672D266F47A2E15255656CA978F14943BD40B1B21041173F6058391AA259D7E4F76C10DA3CF3AEE9B71A127A55DCB80AD822337C1D79C763CD7774A31A58743A4797D52DD3959A66BDB08338D007E2CA7CD19B0C553045C40D3E7AB0D318378799DD9A02B6C2B0C7C9B8DB986668598605163709193AC4DF5B19A5CE28BDD7CAD59AFF10FAA2220284DBE5D4C7FDF2792C559A6076865081D5F4513CFAE092458FD410E18BE1BC5F970660BB0C89C020079C121A1953C2AF9298A6342D1C47C413B4B3C35DD91358DEBE7DC109F35A3512514DBEBB544851709EC1A750550422F1C9FA40B50DE08DBFDE90593D229E01BD9F0756CBA1EBACB8CC2139D4CADC778BF937BD524E8845ECF964A04F7C43CD056F6A7A810C77C8B8FA73359CD1EB8670E1AF7F4BC247B7EC515C1BBA404B76635762D4E0EF451150C8A58437C06FD2C4154A00D63408F1EEE5D1B67F7F4893C158A765237C4FDB215CC0E3F4D60437AF43EF9AC575C0C6B85A93D5493DAB60961D55C4BEACE3A907597CCFC7C6EFB5453DCF83796AFD070322A650BDEA47B76DFF7756CEA567961830E7DC49B2A8923C59BECADD06435D6EFBC7F5307FDA057DAEB1C5B4F6E64D8E141A46090C9EF90D3816453F975C3C7158560DAFEE463148AC0E1E5351020F0A7C08A7C14C1AA9581C936EF845E011E82DE64FB4CB49DA4E3C8D079EF7DEEB41665C6ED43A4F161CBB795AC4FE1A67D6FE18CFB1A15BC02066A2598EFAA9FACC5BDD7257C68E309B2E2622D8C647A3D4656DEB71D414100049AA42C991F997F81A9B391449C4DAB874F9F309463A508E950501590FBC2ED4E80C2D63CE0DB72DE74D7CF9AAC845BE2502B89247D971EB5169A583677CC88C569067E726F9DDD1B49E80220F5B764CE4A32049E20C7FC2A573BFB911EB4AF50B9C2E1F5195AE76FC2F54D0BA33F2CDE2DB3084C5E5F25155D8D81082EAEF09C598A699373B5CCFD7DFB9ED2DDA4DD4681B073B24D6135D65A8ECB41CEB156B8D8F77A4DA1747239D0E7DE48441E90C62FB26DDB0E802DEEA997A6A2569885D0CBB2833A12D4BE92FFCB9AE3A3CFB01874C6A82427A7052ED0E6652DA9BA95280E24B65F8EAB174812011DD12D9062B1004C60DE85685D7D41FB5F04E9707E034A305B60145DF6686818CCA3457BA1DEEE0235D3B1D026F69A2AC556A1A93455F712C3A737BB4A30CE52F0204AB79F65B3E305EF89686D213B08AA538F4BA486C8709C8627C51DE86596D8EB035D807AFFC6F68D88E0B145DEABE8AAAEB411D085827E7CB47E3C568207FBEE7BA9568B414C0CADB05DA7D36F83037847A9F7233135F49FC14496485071CA5C5A0D1725C016E7482B6F9892D64FF76C6AF73330EE4C654654943F9966DAF3356C7ED8E4A0DD2F58B73B144D5FA286ADBE2A24776FEB78A4DD241EC3BF1DF78D5DDE6A48F8655F6FFC7D28543CA41F52F15CDC7CF092F48CEA91356D0EB1444A3290451033871F0006373F5A62CE9586ED95D3E361EFAD629B3A4D2C3643405DB4B7F837B7128C11E55C95C7F2AD80D507247485CFD4BE0A2EDDB877B3CE385C3ECFE71FF27ECA5D608AED19424037154B56BDB1A36908A09F1A50B1D89A21E6C0FB5C8AD21EC6DD997124DDF07F13BE0058583B070B2DF895223B7FB4A3A00343620436D6DA8114B779BC85CF9DE15C7EB6F26FD49F668FB33073554051B35DD0E5F62A66C47AF7CB3585A56E310FD7FB6336A5923AC5ACD57C72B348A1D8B42F52ABED61BFA58CAEBC9B20531F707C8A07813E66101282C30D86739AAD90790CFE9DE3C5D438318B696BB15BC2160A11FF03211CCEC77939F420BE1B6A8211565332779B86F18DA825F2F1174F4B9DF8C8F6F617648EE78C882688C4CE10C5FDE814B3917FF757AD7FE749129988CC43762002F89B24FADDC2D0926484C0C8B12B9944B177DB4A890E4826F72A4A0E19018781ECE90FB485443C7BE06C20C9DA7055F0AA87706B5A90DDB91834FAF746C2836C7C47496D8A0FD36FDAC574E924F7B514EDD7828215810D7370699C6C6C22D0AF97C289B49B99E4521EE8E8946FFCA48189C6653FA7F81D185E420D39B3BB34EDEC3D672AC0BA3890108400E25ED4CC877729F241E0D5BAED7EFC2BCAFC453BCEF9653C722D62C694420E509968F0BD3AADCCBD4E078B5E5B7E6A7833758167EC693E590982DCD54DCEA98BD3672E486E2A6F64A54366EEE3179636552CB832684B100D2AD75E91D86D7892DB3D7B3565953D35328973DAEF53955D8519B54A812550D8C11DD2A284845394A5395A7BC20F12450DC0C41769A2EDDA0A3256CFCFAF408F2405D31D795A8E1BC8C2A3E324595A96173575EF054F04214B0321A9A607E6DC6FA0EAF5CD0F26A3C1DEB15BDA4DB06E196AA145ED7ACD2E311B5C29AFFB26BC126E37FDBA4ECBE3A171CE7901161D62064B5F6B667D6011CEB90A19B8D05A4D2B1BFDDD8886F8F622F63D7E14D61B87A9177AF6EFCBA41E95BA35B2D0E330F9CAE832EA3CAA46DFBA1CB2D88D96B34F5DE2C12255AF89D0BC7FA9E5AAF1FC0A84CC3B6E9BDF25652A44F0DB30C4CEBE9298373CF54E73DA942D060F112B2F525364A3ACB0D2D3DEE2E7F908202D3E7C8FAEC5CFD7E0E3F506272A405D7486A0A7B2C7D9F3F8FC06222546647AAEB4CCFE00000000000000000000000000000000000000000000000000111E2D37D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 * @throws Exception */ public void testDilithiumKATSig() throws Exception { - byte[] pubK = Hex.decode("1C0EE1111B08003F28E65E8B3BDEB037CF8F221DFCDAF5950EDB38D506D85BEF6177E3DE0D4F1EF5847735947B56D08E841DB2444FA2B729ADEB1417CA7ADF42A1490C5A097F002760C1FC419BE8325AAD0197C52CED80D3DF18E7774265B289912CECA1BE3A90D8A4FDE65C84C610864E47DEECAE3EEA4430B9909559408D11A6ABDB7DB9336DF7F96EAB4864A6579791265FA56C348CB7D2DDC90E133A95C3F6B13601429F5408BD999AA479C1018159550EC55A113C493BE648F4E036DD4F8C809E036B4FBB918C2C484AD8E1747AE05585AB433FDF461AF03C25A773700721AA05F7379FE7F5ED96175D4021076E7F52B60308EFF5D42BA6E093B3D0815EB3496646E49230A9B35C8D41900C2BB8D3B446A23127F7E096D85A1C794AD4C89277904FC6BFEC57B1CDD80DF9955030FDCA741AFBDAC827B13CCD5403588AF4644003C2265DFA4D419DBCCD2064892386518BE9D51C16498275EBECF5CDC7A820F2C29314AC4A6F08B2252AD3CFB199AA42FE0B4FB571975C1020D949E194EE1EAD937BFB550BB3BA8E357A029C29F077554602E1CA2F2289CB9169941C3AAFDB8E58C7F2AC77291FB4147C65F6B031D3EBA42F2ACFD9448A5BC22B476E07CCCEDA2306C554EC9B7AB655F1D7318C2B7E67D5F69BEDF56000FDA98986B5AB1B3A22D8DFD6681697B23A55C96E8710F3F98C044FB15F606313EE56C0F1F5CA0F512E08484FCB358E6E528FFA89F8A866CCFF3C0C5813147EC59AF0470C4AAD0141D34F101DA2E5E1BD52D0D4C9B13B3E3D87D1586105796754E7978CA1C68A7D85DF112B7AB921B359A9F03CBD27A7EAC87A9A80B0B26B4C9657ED85AD7FA2616AB345EB8226F69FC0F48183FF574BCD767B5676413ADB12EA2150A0E97683EE54243C25B7EA8A718606F86993D8D0DACE834ED341EEB724FE3D5FF0BC8B8A7B8104BA269D34133A4CF8300A2D688496B59B6FCBC61AE96062EA1D8E5B410C5671F424417ED693329CD983001FFCD10023D598859FB7AD5FD263547117100690C6CE7438956E6CC57F1B5DE53BB0DC72CE9B6DEAA85789599A70F0051F1A0E25E86D888B00DF36BDBC93EF7217C45ACE11C0790D70E9953E5B417BA2FD9A4CAF82F1FCE6F45F53E215B8355EF61D891DF1C794231C162DD24164B534A9D48467CDC323624C2F95D4402FF9D66AB1191A8124144AFA35D4E31DC86CAA797C31F68B85854CD959C4FAC5EC53B3B56D374B888A9E979A6576B6345EC8522C9606990281BF3EF7C5945D10FD21A2A1D2E5404C5CF21220641391B98BCF825398305B56E58B611FE5253203E3DF0D22466A73B3F0FBE43B9A62928091898B8A0E5B269DB586B0E4DDEF50D682A12D2C1BE824149AA254C6381BB412D77C3F9AA902B688C81715A59C839558556D35ED4FC83B4AB18181F40F73DCD76860D8D8BF94520237C2AC0E463BA09E3C9782380DC07FE4FCBA340CC2003439FD2314610638070D6C9EEA0A70BAE83B5D5D3C5D3FDE26DD01606C8C520158E7E5104020F248CEAA666457C10AEBF068F8A3BD5CE7B52C6AF0ABD5944AF1AD4752C9113976083C03B6C34E1D47ED69644CAD782C2F7D05F8A148961D965FA2E1723A8DDEBC22A90CD783DD1F4DB38FB9AE5A6714B3D946781643D317B7DD79381CF789A9588BB3E193B92A0B60D6B07D047F6984B0609EC57543C394CA8D5E5BCC2A731A79618BD1E2E0DA8704AF98F20F5F8F5452DDF646B95B341DD7F0D2CC1FA15BD9895CD5B65AA1CB94B5E2E788FDA9825B656639193D98328154A4F2C35495A38B6EA0D2FFAAA35DF92C203C7F31CBBCA7BD03C3C2302190CECD161FD49237E4F839E3F3"); - byte[] privK = Hex.decode("1C0EE1111B08003F28E65E8B3BDEB037CF8F221DFCDAF5950EDB38D506D85BEF394D1695059DFF40AE256C5D5EDABFB69F5F40F37A588F50532CA408A8168AB187D0AD11522110931494BF2CAEAE36979711BC585B32F08C78496F379D604D53C0A6711A966C11312AD9A821D8086542A600A4B42C1940720242628106210A43852331709308108B188C022492C1B28412C4218B042181C8610248059C9201C0348819326C582046891868A2C28D82346A1C094200A28CE3A6491C112CC24812E0902191985062C084622451CA062C64240E1BB3312496854B4606DB2668C38268441046C9B6211404811445502442084422710B92459AA0811A91709C241003957004C504C82692D29200C0B260C0A26809190AA2300E188969E0008DD84862DA14712018051907440412409B1240118010D142819928508B1091022464A0206D1246211C838C1B4769010690CC062481846920982C24120521B15041360298446ED1A63111056AD3A840CAA84C62B00003134A53344614194004C54CE306695AB08961168ECB10808B168ED990640B94602483851AB30454262251B8251C424A0B814842C4445A102023808409B7254CC64814854D19380E601651D8326A0A918908C170E0964D18468C01328D91C4054A0061230868A2104210A8611306218A248E620689C9B24508278451200D980466DC42054424852426282221612016090BA62C0A1144E0928158480D422210A006098B246E81288CC0248090308D8436404CA68450042494B68DA2926D18B344A00085E3B805140504A4C290842281C3262D0B2066CC903198382810166CC13445C0102224C688034632D840901C20680415289A188144988D9C206E9C302CC1B820614221080310A0C28C58128553204C0330814CA48D44C08D51404C1CA72C440865A03840DA20808106858C260DE2A88C9C4411594228C42604441426A1426408C0851101869B483199B20C80464459A88C0042089882900AB54562244812960544124600C88813A061E1284D0AB9914B962099B84400314E98128500B60183A00D14150E1881101901224A06681A498DE1A28411C63121262591A06D030524A1B6089444724334125BB42041B650D0888D0B074D1C94644C208E8B8808E0300944200549864D03134E19C9840937611A43684A80900204311C1742184080C8308EE1A241C33404A3282251247188D6FEF46712CA182872AB2919678AFF9D94E743E063A39E0C35CAF72A7F2EDA28E65858520D5D8467DE747CF340653B52C268F55413F5ADDC7D49011EC33EDD537423A84288869337AEA0781A124269071451722DB3BB8F2CE5B1552F83D2AF07F25613918A9F4E6F1257603888E589308CA5F95F07143D23BAAE17520B36B6E0E94FAF6845EB2131AEC383E63BC8644EE5F1ACCBA82F9211E57AFCBF509C1131A37466BC91B357DCBBBC14CCC319C4CC6AC75FCDC82C6596D07770C8277AD370B192A0B4E05F812E0E265D2912AA29F03FC9F72DFA69C9B1291A3FC583642B235F6991A954788347F60A0328C48ECEE51BA02DFF323ABD911667CB14549B618F1C5D250CAC9E35E071601992FBEC0BAE6F74213081404744D12F2A0E04BDB265E0924CADA40D1FA1F38ACA4606BFD4575712B8260A456FDDEEEFE7CA259BCDA97B9B939A5FD2889C9B49FB7D4E3553DEA61B3339BD0E6B16BF3BB227103BF9202E72DC502E28F7CE1559A4631F372520324E4EBA07545F78BF4D94B0E5B8BF51B8F176533D5CFEA5232F283A47605FA65DDB17C891C251011C4E98EEB6EB00CB65BA31C8F025C87A9FE02DBC10C5D83A065EBA5D7B2A19D5A1CB2C160AE166E867F2AF8C7D49D63FB83A614957FC0A3B5A5C74990E9A2B02120C7E6DE37E155FB472F50F0A45E47CF5F9D7A4C82982C9DC86AE877C3FD1885943E439FB003C7A9A42F71B4FF6F0A28B140CBDBA6E71B13AC31B23DE9EAB7837E15A69F833EB7B56A71D8BC2CAF1F2A31C345BD5F46EE013A7C689372337191DAA800C0AC6C46C9FF688B1A01347F257C474AA3D97C1D63A8C00E0A37B681673F57C1C9C8FCCD46F174C74A29D84CEB71F7E6B2F8CD2B089ED43F7C96DAE81A223418C20B16F1DF3D1A978AE28F6DF35EC559D04D20EC74B224AEA31A289B015B069E9CBBBF7CF6DE94CFB2A96E4AE3462C96003CDDA87DB561AF2CE3C0BA1D90413FDCE3CCF4390C02C1CB9F654F4820EC33015457D4A629FBF39419CAB7642D6885E103FCE0D4206CCE7C12C6FC44FA33AD0864C3371A7CBE820E3B371B656A38F2E7FF18FE4A50C8AB3F85D783FB57835CED8490B84EE0D99AF0D64C483CEB6366FF54F8AC8A40DB1AFA573A4FB326C74F0236ECEF3DA7120665CCE05DD654B5071723A8348E7CD7793513819B61CB64E1328E8B22E7664BD6B41B5710D19EA8809D4450850E907DFC4D0B75F588CECE962E9E0937CE1402446A4D2891A46E6617FB29D4FCD712606F7819ECA60F7E0D5B19E7FFB57C73C16FFEEB90038410CB9FCBB5E9D51EB3EB6297E9FF6AB7088FE2D9B237BC24CF7F8290118A5E0E00A0B903FB6375C848176CD0A8C8875CC59199CDA11A87A78F65CC404330B087571FD0633E27129FDAB5A8A1F793E52412B0083FD5C74DB3CF60C2543CE7C91B2800E40203F8D99FE5FDE5B108E7EDC80EBB9BB34986EC5C5A8F580E75752907FF0F294C866C2CF1F362E840B6881BD43219201781C63B0039A95BCFB4A0FECE569DF00523CE9C084B022B3B022242E28419796ACF0A0C995F948DBFFFD30D77ED105A3C9943C406B305BC81A6A248A291548F2A67F438D966A57D53F4B7BE15354E581BE16F7AD64D164E85787DF5849C810AFC28D06482F441B5FDE3DB2ED36DD25AA6664D4D43FFA32EDA25689C9F4A5D514FC66231C5401520922524438EF1DC78D693C9718DEBBD243312674C899F18910E389C8EBE505824BCC42CD4A9ACE193768220219011F3B1F335427BFF9E8BDED5C08711A09C2B71CB964C56A8393BFD2B56E9B6B2F513E682587DC1B8ED196066326871025628036700063176D345DE384E182D6C417A32AB11095EF59BB4D171B9CF81D17AC42664DED933CCB722C69857FFC53C8E7F2474B0CB2DFF2DDC8A5C601C84A701981199BCCF74112A6EC062C4FEB601A028AF01032ADB6BD15D4C2B9550AA850AD62CCC3A3665D5212B12E0FD5C5326A1E5EB1F10D557D94605E8E3F356E08FF7FD884ED3C4205463594C9AF2F39E4B1274695234B54EECED93F460EDF1A13C2CB4B17D322F6F79FE16F0357C1C4739863E796791F8647FABF730AB00E0DA509706D94571740F61F7BAF366D2774C9B5B8C61DD6BE9819A6028B264BB2E4AEA54B56D4ECAB5B528CE0C0C0CCDB73023352CB00445BAB6F7467B4644D4361C464FAC6B5B137D32391021B475FCB5F31774FD8ECABDF65475F25574C65559CB331F41C0F498B74DD941C344C50D8E64F9578714A32561FAACEAF78148E6DA4B566826925714B17108AFDD546385A3CD454D5CAA16960916282A47C4315CE236BD9E3255C604EBDC39772DB5CE0B236"); + byte[] pubK = Hex.decode("dc7bc9a2e0b6dc66823ae4fbde971c0cfc46f9d96bbfbeebb3470ae0a5a0139fdd6a6ce5bc76e94faa9e9250abd4cee02cf1ee46a8e99ce12d7395781fa7519021273da3365519724efbe279add6c35f92c9d42b032832f1bf29ebbecd3ec87a3af3da33c611f7f35fa35acab174024f118979e23bf2fe069269a2ec45fbc1b9c1fb0e1f05486a6a833eb48adc2960641d9af6eb8b7381b1ec55d889f26b084ddfa1c9ed9b962d342694cede83825309d9db6bd6ba7582132534861e44a04388a694242411761d34e7c085d282b723c65948a2ac764d9702bd8ed7fe9931d7d8704a39e6508844f3f84843c305594fe6e5404e08f18ed039ac6563cbaa34b0ca38320299d6256ec0f78d421f088159d49dc439cbc539a55884a3eb4efc9cf190b42f713441cb97004245d41437a39b7b77fc602fbbfd619a42363714b265173cae68fd8a1b3ca2bd30ae60c53e5604577a4a3b1f1506e697c37432dbd883553aac8d382a3d250cf5b29e4d1be2cbcd531ff0e07e89c1f7dbc8d4529aeebe55b5ce4d0214bfdec69e080bd3ef36cca6a54933f1ef2f37867c0d38fd5865b87929115808c7e2595458e993bacc6c5a3b9f5025001e9b41447708bfbaa0462efa63876c42f769908b432f5485508a393224960551d77eadfaf4411cbc49fdff46f2f155ddd6ec30867905b709888ca0f30f935fb8d7f4803cfc7a5f7790ca181d99ca21f2621d69a5c6d49c76b4969da62740a378470332b30947ab31ccdb9ba0c7b625879eec4bd81f0200ba23504a7dc3b118bc2ab1145df13af3c8cc39f577873b84911b3d85fbbf4cb19e4d36b10a938eeb78b599dc86615fd6cec6eb7b8f7afa5f6d6be19ea81630d36ccfb2f487de50d0cf46da8d3fe3512812043c0e3ef2d7231fb0b0a35a0fb283be30a1247780f30ae0294e8b6f5897383edb895595f577524df54593cdf927b4967616ee3913e4d6b29b0dbd7c33a2a45e4ef1b1954ea5d91ce37efc1302e7ce02a97395565da2a5c5d3fdb0d87684e9b1c0ad07ec33df2dfad528e2ea0966d2a47dd5ee88e77d653c0d004fab0165f0757c4da40af327e7192536c79947a80a827aa2107dacfae3debfc8fad3d6e08076d938c510a276bdf6721a1f087cb169515028ad5ce27a1047abd92809934ca63b893f71f9a34a99c0fd30310c47e9aa37394d0ab73b254d3ca69d9c5549c9479aae24264ac5ea64d3fd821c3962ec77e709f9d30bc7b65a52e48c16e80603558caca1811411c3155d1f949fc9cf9aa9385a7199e99be77a66fad7eed91258de55b2c4c83f9a050adebea5f09758f40dac4a1c394ee8d687879150d26426895ab1938e14ae11b376254c91fc6130436996f8ed43bd27be20ec9067111c116ec94cc2b06cc91a13c5d10bbd7eecea4792f17b2b77631ef145e9fb41a83eaa11c2b72a48fb90fdbd88644c4edf8ab20dce3118364b276ac1237b36c8926e346aab5a111aa0bf341c518b7bff9e9dbb8bcb4728601b3760663e67650331e6fb54ac82fc414cb8ddfc160a25311ec5272de46217fef8b992ff89754fbee351f21bb90b6c97078b510c983350681266c8fed1f0583c5151e7b8fe3b7292319699687cc6b641fdbd689428543bc0fa1facc109de65b62784c2d985ab15d77d3af12af6d03e8d1859a553688584d75ef673a1de74093ee108c761fff32c217c231b0e2953daf521429264c0963bc8a5cdeddc617a7285b934ea51ddb5cdab23bcede86be36e001bc65c65e9a1c94baff4fab8eb5f8ed42ec377423633fe00049142467c47c5d58a7202c8e9104841c1f7f380145a6a0a828c570235e507ae5868a6062f722bb98ff6be"); + byte[] privK = Hex.decode("dc7bc9a2e0b6dc66823ae4fbde971c0cfc46f9d96bbfbeebb3470ae0a5a0139ff037b84e75537e0a1cf02a517acfe323ffffe11df72e4f38430e0e66a2654b2f2ef757da47649d9f63fa03f1bf6fe6bc7c62971a98a2bd9d36eb0ec43ad4e9d940df3bb5874f5c92192aa31e0535d3cf70950bba858d11a688eaf854f63ecfc520c50d624891434265d8b0680c03061040299a104082c0910c8508d1100d44a6509408292211125b90508a2688e1302dc4021280028ac302611820851237808a000ae2040421b4910bb80550a08051b2511c28428a3672a494504910201bb45161424424a75001328181942d62a850023449ca94200b296213156408924c48122100b605030208e0060200a311e1802021116483a62898029291480801083041066613200e5b360951400c53000aa08851944842e316704ab2089b92440025121b0309418209c2a0800b290a819851c4340da4424500a0105b048e603400138928a4422648002c90202d194068e2146d19278a083746e4146914006422c660d3a03013242844965014166da0284dcc462e94367100232e1c114909a2040131060a2172c2142ada000c5a260d13228a62c444e3142d013445980224d33841c0308121a621e348720b1984d2c89108b8690887714a2884d496451a9301ca2285da30859ac851dcc00820106060465262302aa224251044640b2842988011540692144251d236719bb4900b082890188e41c469e1a469032160e01409d3020c20c88c1cb23164086218476920228ccb8470089528029550533270013405888424541041d202881aa84ccac88181008d0392899ab809d9900c9a1290614065c9322d89860c123521cc4266c8360010062411028ea3b44d44023043a0285a002ed1980c4882658922441c010212907084226e12134d011902519064113364c91806c2c04589262908b63024308cda022e0c27250b367058162c5116420b4946c1208841246c99466a04434e18a86c821661922028639409c30211029520211782d43868003460c84688e0160000a32dc0a82824b640831464c81022a2086503234ac8122ea098418c2072cc308a62c665093408412682da429089328514967081226001176d5948428ab88d592051d80892e2c0889044700ac0245a020904218a59c45094441094140820460209270c441020dcc8209212015038250c456e4a1666223770dc808ca426412222441ba3618a343099844099c42952046d88146ccb242a7cd129a8d333115c62d033b6a8357cf7cd10268ab12f16fceb7975d0a28a6c4822213c9a772df084ad91a669e2040550fc5e8d0aeb10fab2375fc9625ef9cd48c19631997a1cb6455d2c6286c569c9637add0317ce990996b28e51c3f3f717fb5907bbdd53961ad3497f2c3c473cce170906ac4c624a89aa8fbe624d99385e9c9548bf05e8cafd47d2476e41b73001f813726499e88b2b3b6f596ca311657850346598994c40e34747161e4e76264deef2a3019389d1594c942301af47b7544c23ecda2df2dece81e487d8f3f58ea89cd811d7275807ff1b0369ba86470088c174a3099fdafbe5fbb4d158801053b2b435d54059e26dee76d10a7a372f06b0b88b985b32f52052387438be8dc8bc6ae7369e2da9aa5e2585f8de403d091ccb7f790d54ddb34c608b0876f2825e9113be20a2b85867a01bda53287ac780bcd8b606d2e6d7712c56ce0142d22fe6b786de544963e134fecedfafb83d763061d799096a59e30d4472e440ae1faaabdf42640ce69740ceb9cae1a9612c21931b74af3f780236123321b205b6efd6cbb134f4c73d63c0c13e660b59d5920bc33197c355853d8d1cddc7959f7bc500ac81d985016f5b89a0eec79b0d9364ead8e38577c2a6549f2d067cb09438fdb21220aec80f6e22a476f332a2a4a0b7acbeb9e078d2b5a92ae84c924f7cb19fc7df377beb6546af97aa985c747cd111a127a674b4c26d89c14485b82e3a498a12d05406febd6c4d4b8bc051ab2cb91224b078538374b794b7dd9ddf3ac2b4a671fb7b9cf5acb78622ae2709eb2db16943aa24a9c97a81077bc784d25c0ea5991d2de883798a1f0e78f3361ed6a10dded81b1d683658331534fd7c01bc0eb00dfc4c3c84f0693046ff806bb200dd7bd4c0e6abca3f2934b4814fc0e1f8be615a2dda7c8a8d06cf9ce8566b40f4a6543b25bacddc926863fc0fa2007d6d7bf6d18dc98df696bd0865bf0be4c492b8043a32def8e3595ba7da345252f38f95be10fd7fb899b498fa01b09de5d5608eabc44a721aa04c4ef1dcb86102ac5f5f79c9708dcf5c5e896edd8c2c7bde3fa83e6ffce22d66174e31657a0b6361585e669d3031952f08631ae1f16ff90b90d0aad3c6d7e1dd0a9c41ab00a6e1c4f96af9ac5b79fcf821ffc016cb059245fb78dbe6c633d965aaab5333be07195c4b74b18e4600ce783c0a914ef4281016e80a7c9aa92d0fd789879c5e6751125ecb154432311e41cebd4fab3a31e4d2ce22d0f8c67737bf8a0dd85fe1349d5079a4d5feb3fee9378ca47ae46cc58a3f02038cfd53c4cee9cc4270cebc3d115a39c831e8ed41c4dbe4051b51d7872ba0c2bb163e0085201188eaa624a6bea9400a3a1fcc355a57f15704e61fda55a5dbaea8448fa5cb2d377a07f58305ad107e844ab4806e5bf99c1f513ee1d0a2acc04549f0801742169a77971d0adbfbfe0dd2ee5d16bc461e35748d1f3f6f4598321e8c49e79e740f990359858d2729dde007fcb26fdda9aa6e2ec4bd736f2836e7e4c83440191c849f6a53c72a4f8f830d001ea3b18f3cb4a5bd3cf066032b4932cfd2e62a9b55723fa61c688c935518af6860cd649bfbf1bf5fdc1f36dcaefaa157438d1cc8d56a150161511df82631f5e88e773e4ce263f276b7b3678d4c6fc75311d411c0d01bfdb595bb70552838e1b86517c837d909e772b428599e1fe569f77ce61531fde6fd31cdce1bdee4ba467fcbfbb9feeaad99fef67d4906e036c73662ddce158d4e5d4635e5d366f79f31a19d1b3dc4a591b0df194bb06c18147f41d88d1a409becdfb67eb063d16312266fd51b521ba9115e2e5e2aeae6ec511cede13ed4132ffbe0273f6c7039b3874f058804a54809af60557a21d9b4b831d04156a7c22dcbcdfe14f62437f449cb5ef12bf4251d485496cd835c0c2bc58bd845963dfa76ecd68519c4bdaf110be7ab052876dc3407591568c956ea3bf107c90fd5853a292f59a8d4b58b5d3fddf29bdbeac36852e3c69766fe460176a801831292b8e88a74a01ecbbe09a7b4d74cfd7fd628841944d9d556dbd60c76f96f07dc53443805ee9aa09365de4fb8179252c6b099b5dd351fdefc23dbd8090596c5d208ffd2c5661d8e5612dd574fc69045c769a969e600d77cfe192f1d3ae911289355c585811491b0ccd73692ab158824ab9edf8ac8193f0b33e6138b72c6dcd5d344f807b3da92425037de5ea4eead1c795effaa145e2ecdd327606eb2609929b9474b2bb04653602555c068385e92f06f29ca613ce5b4404f01ab1805db0acaa890330d291f40692df382509302b6dc8668f2c8f2d3a44fd58dca26e9802794f73d25b3149e6d576441"); byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); - byte[] s = Hex.decode("AF5920774603D20E98A79AA3ABFA32B6E22519E673E37AC4AC73FE85341E2C2923C1992E1B0BBE3873D7C8FC5662F207BF58EA381CD4A3A0C062DEC45BDAF8BA0AA52BEF6FA14F3F6CF28F7620BF94A92CC27D045414A64D65C014963052802428BF3987A2D47516CA5C78AAB96B7BE11BCA5F2C5A26F3FCE3A26E8E09A2738F386F75D448F937EF19A846BD4DD949CAAF36DB5629884AF53A023E3F180FE4C0FAFF7BE5DFE4E89ADE3095A65600421461AD08C129D6CEA851BB39C0D7A7D151405689A091FA4DEBAC373CF54AE078F0AF7557BBC6F06A535AE8949E0C65308A59840072375295802D0E2CE9A3DA98426A00FF03FE80218C0EEC8EFE581CB9CC9A7D66B20645A8CD0490D3CE4F7E6FEAE9C9EB7A57F964D0EBC7C90B7A9F86300B3E8095E64D1294CFC4B4D9E272E8FA8DB5707D7004AF22DBFF9CFD4863DF573FE004341DA3CD4A3082532C2620455FA37C562BAFD5684EA128AFC79E01FC9B31E8433BAD7C029F2F13CC10592D2332E3E08B80D350463DE72750B1F806F493E143BD5FCA7D1698081B31BF876B2A1BC9DF50952D13B6C1321B1111172145A627AE0B4427B98975CBFFF7D68275754B45B682D709E168522E84FEA7DD3BB0F41505FF71926431D1A90D4CBF9A527AD4E284976FFF8BD9D6224A4F260391A987FB6DA6EE42C2A4900F407CE1F02E322475D313FBEBB68C2E05730809448A7428A5940139EBDF1B5556FCC5D42E1A13F32230CB6F0724831D0D071BBA5A6704806F475B74BA91B6E385D48620958D0AB1BF2B184E10F3E753B71337BE9EB653786785B43AC7E5C494AC1BCB043D461425B36098AC93055A0105AB8523B61D024A6E9B56A42D3C04726512AE4CFE05710446B06F694234EE4FA8FEEDDDC5F28A65EDE2EB58E965FE3627A571BC45B397ED092AB4BE00041729C4D192FE30678279D223A848CF4366E92B3F68DEE97C9B4A7FF22F937BE6C56639961DB29FA3CFECFFF293140886FFB92EBC79DAB59CEAF869C64F8EAF585CE97DD6B78F892772DB88A958CF0AB557A7FAA83FE621477E2B84497AB5A8ECF4A7BD32DFB902F05D2CA31047D0F1919ADDE1EE6DFD58E59BC4DAB3CCBBA36AAAF6AFCCC7B095CA94A195BE9A289526B588C3A9C56876FC415D521D442BAC0298D302419AD527DA249C2A660CD064213FFAD563183F37972578EEB9F70AC67AEE6CC2B71F283A95930B554738555791C25E7A399E685636D58D69CB6BE793B45C1969E7D5615627EBC32EED45440F87880D2829FA4FC871866164D259ED95D2731871017FF51894066FAE1FFA6F4B4A6F84FCFFDA09E718FA17135EDB3F48558D5BA67F9E6F0900340BD04DFE59B7BD67745884FB84AE3F8EE763D202743652D4F7333450580490B9C744935B19C1D5FB0DB5FBB461411362838037EB7EC3F63F26C893E7CC1C3B3F4767ABAE00FEB7BB99B1420BB29EA614747896D9EDCF8107FE504C9C308A8264DACE318D87CFE4761803E9A60DEFA6144AABC1F10A45B140DED754E73586C467BB7BF19EDEF25BE0C65E93C5E5EB8F880CCE4A858757F8FF56062B1067F4106F76B7007F6EA6F945047E85BD0FAD9D26994F678A0612B87CCF9C0CF9A433D889C96E4C12BE372277005B06AD127105D16D8FB142AEAE5373ABD61D9ADCFC5550D623CA3B8824B0E2E08C2BF4E2841EAC4C5DC56CF8954CF207C263F27C9F309F10307C0D84A65878425031375DD810D2D7E51098A3814350795C4A077FA40DD44F0FA7510F7C3F631407CF34F604C7B335632A20D2AD419BD7CC6D4242B1C66C35E5A5EDCCB13CA37D3B50465F3B4AAFF7E3161E7936088AE08401FD2C37D67A2FF91D3E6F08686D64BC2FC6C57106E49FA384AC22219F07EE8996CA3DFF59DCC5092A4BADBE87AEDE7F69A04C79B33BDF35D4A0E4CB4B55019CB0BF275295B93BDABEA516CA2B616A56918600B724BE7A01EC4EF54312B30D66F507815F2780FFEE7C30F8425A92252CE550FAB4E902E7B382D46DBD20EFE1BB0EF8A496873C09C4CEB0303C7F1DABA0102DE94190B6AC6DC810F72BCA3AA292FF38BD51A7FAB8509EC4FBE0EAA3C986166A674B7871155C348C477EF8CEDC832B5ABEE71A8D18D06DD0F5221160ABEB71E6E82CFABF731EA3515A76EF07B2C16C63B37F7AB73B67F005929A753E453B930C0AF432277FD77D8A1EB8022CDE9665763B014F0A672A04160B0A06F5540F4C264B7F22740690A2352DC863B588303AD51F0AE162BF79797F07B534501CBBFDB713A724AA98E19532187180CCFADC6EBE3142FA7DB66CD4DE7B9FBD4C8235686DB68CAF489AFA4E1E87AEF0CEFD8037E3A578EE62EB7F94ED5BC0B58EEA4B4C45FC56D31D29944D095AC96C29083DA2C77181D97A55FE6E903A2F2783DE0BAA5F47D704785C33E8D5C87ED61E65459167310EB7A99574EF819AE9161A3BD09634803D9E1E4EC7386D7946984517213AB9CF66AEA551CC457C39F86AF294CF7B073F563ED4DAB9419BDF004BD05C92B4E80EC3CFEAC97E1DDA554FDA625C4B9B039BAA7C5A2F6F97057792483CF5F852D4C3AC71AD50F779953DCFE2F63ED235D8E1D5345D6C6DF0555CC2631DEAD9B714BC4C16501E01261381F3679715345123388C852D57DCF1941D0911D49FEA7143FD2FC343A5075B64CCA48291DC28B83F76074589EAB217C7847840652C0E3AE278B3B6FB0D800C5E7DB79D5CB9CC1A87450C00B7677812D22EE20FDE8C1753A7FB93BA8BBB8595A6393DF54AA9CDB6E0879A26E49BD3B01513C6053A0746C8596CE5E5B225CFCA26AB8BF12F1FE0A647A9E4453039A1226194C46E8B98ACD710F18FB7EC05476C1CD8FC3112CCDDB1582B8817C18FE315353E7A47C821E9EE3A43CADE1B80D92A0AE8DCEB4DFF766A54DF3665FEFE3C252B72DAD7B1E3359E7FA25562C3E39DB521CE1874111FB090DBD38B3180AD034B57B031DC4DD6AF7C1A8AF3F6CE7EDB1A9E4B6D4A5920E3620818820659762EF7A4243F51DF2D8A900737D58105699B4E10CBCB359C7F3A4007697C482050EC33CF8041916A3B919A50D96EF0F589FD4556F30DBDD942EAB79DFA97C07E30247074352E1BF98E349CC7EFA5A1B8FCE4F18F1FAF6F07C99C321448B0395C8A9CBC466412F89C1A98BF5715842844F0E8236FA4696C4658B8FDE4425D09D67A38AC7258E5D5966F2D3FF66A0C0CE76E7F6B81A1BCD047FD3A205BF0CCAEA3B11079909C6CE5698F32E1F3409658FFA01EAECB4AE2B092B78989DAAD6623BB11F49F0F8F8699EC05661502FFCAD03CF415191A222D3C4C7B8AB0B5B9BBC2D9DCEFF7202D3F4244494F525364666974C4D9E6F5FA0001041927373D5A7680B8C1C9FE2029383B3C484D565F65799D9EA6A9ADD2DEE5E7F7F9000000000000000012243248"); + byte[] s = Hex.decode("fcc4f40c043066771043d494eb13181802151a8f82c5c4e29582f6b0fa35023fa7042b68c6630fd99b8152265f4e439ff2430197e57d4195f3bdb6e92e707f964006001f748b94ed0249414226b5f439ab4daa261f9b549f40fd2c690521a5934230c808899473ce5abb67f406a020db59ead7c5eac5c53156a4bb603603b46db9c2fa5f5bf26fbb67c3a98a399ef245d30d761a1adda9d4439d1d1ce86480c2b123e984209fcc830a300b1c8108e320d34a27a752b2d0cec268de0f9f9eee7f4c7cca6f64d8a0288f6c92699cded9cacca31d80e6bb5107af87d1021fc6787d79f001e04a4aabfbaef2b172c5010e6389ab8075496f50558fba91c70e6440640f522b6a38bbe429cfd5352031eb651721823a3705514b6aebb9c3954f79fd01cb228d731d7a41b462cc1a1c855905ff17f14d7f8b71d0f17c03e4239d2881012f94466fcd1e66e62227d6812f8b81157b8954a671391c064838cb215c79fc6fc9d85ef0c891aea9e9ab16500cf06613a02ca82d25decfdbd1a81090b280b4e3213a5db5f7020d30d8169ea176975f72d1910c64684afc2516a35ec35308c4d127fd5c9f54786d2f7ff60c6110514d6bd7720507ec9ede750e4b9929b20ffa65dd714eb11e4e0865c3d2930d8170018e9eb29b72b1e66b7a65afae1617d752ea435f88db7f87dbd29e9859957eb73b766c38675e96d1be9c4404297e6e40b5009fa9adde177980d25bf3b76c130682f8105c1257bd20b9624b09157d2f6ed42dd9b080903603786a0ec3a0d8a847999eb4788f23f1a95db1f5818dadcbad60078a8b1be01d02ac3ee9ba88cf5909a4d4318d9fd2a439aa37e8da68f6208dc5ec3cd659a5aaa3362ad0ff4a3ba6ed5ea75cb710c83bda0afbc14ae4a61e19a0ab4e9597bcfdb9da986308322cd7f534b173f76e0151e693b52bd2029a7ea294bad8ced7ca0485e58c73a71eb5ddc1bfa12f2a0026aec90db969e6cea486e6628903e75275a39a1105aad7abe683660e02b6fc12bd59227358bc20a49eec69b4c03318c90bb3d9725ac1fe6f9609349b14eea21ea996cb118258035213a8fab19339cea94043667cf2ee596c3fb01d136d40450adbf9761d047e6897b975d291a53097b747bc9d6342e91b88bd0a2e7d6444973557ffae72123d84b228131951dda7a10f993f2427a9a9dc822d822363c9517dca0bfffa2f6aa66e3fe5802c05026b72c03813ef26a90855565d419d402ad1b3b1719c2d23637c425eb1cfaa6e5bb82c87735b802ffb1fdd6693385af5f96a73a8e482e9128f428571edd73c1495be9ffb2a6b5a28a1b8a30ec737f82989e328433255e53cb901764f0c0341cb67e5c6275fee34e35c3e6057cc1af790bb111b5a7a2f86de7c680f42d838ac4e8059677c9d382f167af649253f31c00120e797ec93d0a31af80b44ad2fbf0a8a1f67d1a63ee448d85442677f24c60d581555fb6c693bf8829e5062f4b3a66f028c7505600464138d4c026100e55d878434aba2d41d0e90d4dda9e2bd46c337efce479f999cb50adc080575ecebfd1ce6ad6450f9d7ec025c793493e8c11059d3fae194476efd16742fa2d1a399d6cdffc0a6cf1e4e13ec0f515c21846b9da843f2b0af70de17f7bcbc11a2f11e9cb1efa24a28477c0fc5ea4f6a644e608c028e5aab8f82109a07ce8a06e99012593f32051d865f561cfb365312ef49338ceeeb3842ce1ee2381a1641043c32c852a1add433075ddb94863749b3c7dc6ac10e681293deba2a355843a1ead7448f2af81beb5500357a81a5375355941ea2172c96e1cfb84120f93496943d344af409a8573bbf5961d1dd044bc2ce21ad2b7c5c721b324d697e786e711a8c08d358f52b96507b6d380048e4783740ff996610aa6a2b5e6788d68b065717b507bcb2df05e0af6268735bd5e929798ac5e0f12fdab6da267dab9102c6ae20451e644499c2c8408eeeac9abc7130dee6c33144819ef78905b45dbb9fef7ebc92871092a8aebaf9c754544b055fbdc52b760687b15b22d3582e3d881c5afc00b360f504c67fc90ccdb1ee8d8626f7f12596fdf9ba95621bd00a5f6331261da4340d5bc5a4cc222f60d9e220f6e1b56d1492b20d68b75d7cef20df2737821980efca83822f19cb4f5ece26665e6b07c43b65715df26632534e84d7b3d109a5fb026052bc9323a02a41a5d194ef0990713a578219b989b9a5383cb64e4cdd8ab3ca7807895272490b3cf72a01ae21615bf6af12f2283cc1cc400ed660bba87dfe9bc1e26c29c50ff3a01a14f83b52d20116f8b7b3b133810476a38c588d36f85c5c9def402b13e89201aacdacdf2c6ea8cc0e819423e86f080d6690a136ac4879c26e9a45c80a0d5d77d7ec4f0e395ac5bfb0b67d6ba617fff4f3f0bdbf50a383827db69a405590ad8bd752f55ef299800e1a5eeca7dec712b4343cd82ed6cd96c60fa0c65a960105d3717d3391ac116c868202c11b11ef2cdb2e8a3f3df1940c8f98c372c6d9989044b922f48b38e97168ce900a5af99bd9a81cd1e26109bf5de678e5c1d42b8fd29a738ee2125aca3ca9f5dc18a0e36a16bd64c04c498667e95fbc582affcdbc4ef896fcc1971352e2195d235321f750bb5ebb44bc3c411f7129518780dee0fb706ed16cc749753b8ee44ca7008a6922ab90c803002260f6f5c605436306d96c9b7c538a19cef0d35479d1dd5e5874e3b1a2ff4c1b50b942c3f166d7d9e51f870faba93a2ddf2b32b21f7552606af24772b428cf47d473f8a5cd2fab4c1bdbcbcc9abb6d017e2f0f3f18e224c4f3b1f0384021dd8d58e8b62c1f2011cf17343b0cf86774fc8b85882fbfc6e884cfc97bafb90d6381a647aef10dbcfe263863311fb30d91d885b049d41050f461b08de163cbb1b49ae1b4bcd64175bb3b96b154cd2946dd2961b629bd13beda7867c93b31242aaad973db6f92093880461a43071a62b361cff82bae2f32be33f1e36062f8f7ab7fb3c50c8c5ea6d7e0fb023ab994c45e8b43bcc6ace4e7b0529a41842b64aabf0cfa30c5d98f7897ace3074dd75f0f61f228d911def6258b3b3e95487d301ebdd9c80fe323e7929897784c04da3b52c5ff6fee1f28e309bede2ca244af7a30ae146137f472cff9ecfc2d1fb7e20f9108a6c8bcec4cbb877f3fa15820e5e21596949dd4b2d659f3e450d6f5e715cb307da9af905af6f695b519f5af28e2c3bc4c7633f1191486be9969746cc8c0b70405d9c7f77f8cadc2cacd9c492b774902cf9ced338fe612909795ae6c951258faa52b5f5a363ddedf5a10a4d4e8e253242b626f7ec8d5eff9050a393b3e44494b748397afb6cbccd4f8f9fa364955787a878a96a5acc0c6cbd9eaf6123242446e96a8b7c0d7dff1000000000000000000000000000000000000000000000000091c2c38"); - KeyPairGenerator kpg = KeyPairGenerator.getInstance("Dilithium", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("Dilithium", "BC"); SecureRandom katRandom = new NISTSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"), null); kpg.initialize(DilithiumParameterSpec.dilithium2, katRandom); @@ -260,24 +257,15 @@ public void testDilithiumKATSig() SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(kp.getPublic().getEncoded()); ASN1BitString pubSeq = pubInfo.getPublicKeyData(); + assertTrue(Arrays.areEqual(pubSeq.getOctets(), pubK)); PrivateKeyInfo privInfo = PrivateKeyInfo.getInstance(kp.getPrivate().getEncoded()); - ASN1Sequence seq = ASN1Sequence.getInstance(privInfo.parsePrivateKey()); - - byte[] concKey = Arrays.concatenate(new byte[][] - { - ASN1BitString.getInstance(seq.getObjectAt(1)).getOctets(), - ASN1BitString.getInstance(seq.getObjectAt(2)).getOctets(), - ASN1BitString.getInstance(seq.getObjectAt(3)).getOctets(), - ASN1BitString.getInstance(seq.getObjectAt(4)).getOctets(), - ASN1BitString.getInstance(seq.getObjectAt(5)).getOctets(), - ASN1BitString.getInstance(seq.getObjectAt(6)).getOctets() - }); + ASN1OctetString seq = ASN1OctetString.getInstance(privInfo.parsePrivateKey()); - assertTrue(Arrays.areEqual(concKey, privK)); + assertTrue(Arrays.areEqual(seq.getOctets(), privK)); - Signature sig = Signature.getInstance("Dilithium", "BCPQC"); + Signature sig = Signature.getInstance("Dilithium", "BC"); sig.initSign(kp.getPrivate()); @@ -286,8 +274,8 @@ public void testDilithiumKATSig() byte[] genS = sig.sign(); assertTrue(Arrays.areEqual(s, genS)); - - sig = Signature.getInstance("Dilithium", "BCPQC"); + + sig = Signature.getInstance("Dilithium", "BC"); sig.initVerify(kp.getPublic()); @@ -305,7 +293,7 @@ public void testDilithiumKATSig() assertFalse(Arrays.areEqual(s, genS)); - sig = Signature.getInstance("Dilithium", "BCPQC"); + sig = Signature.getInstance("Dilithium", "BC"); sig.initVerify(kp.getPublic()); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/FalconKeyPairGeneratorTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/FalconKeyPairGeneratorTest.java index fa7a213d4c..0505d2bc26 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/FalconKeyPairGeneratorTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/FalconKeyPairGeneratorTest.java @@ -3,11 +3,13 @@ import java.security.KeyFactory; import java.security.KeyPairGenerator; import java.security.SecureRandom; +import java.security.Security; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.pqc.jcajce.spec.FalconParameterSpec; /** - * KeyFactory/KeyPairGenerator tests for Falcon with BCPQC provider. + * KeyFactory/KeyPairGenerator tests for Falcon with BC provider. */ public class FalconKeyPairGeneratorTest extends KeyPairGeneratorTest @@ -15,14 +17,18 @@ public class FalconKeyPairGeneratorTest protected void setUp() { super.setUp(); + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastleProvider()); + } } public void testKeyFactory() throws Exception { - kf = KeyFactory.getInstance("Falcon", "BCPQC"); - KeyFactory kf1 = KeyFactory.getInstance("Falcon-512", "BCPQC"); - KeyFactory kf2 = KeyFactory.getInstance("Falcon-1024", "BCPQC"); + kf = KeyFactory.getInstance("Falcon", "BC"); + KeyFactory kf1 = KeyFactory.getInstance("Falcon-512", "BC"); + KeyFactory kf2 = KeyFactory.getInstance("Falcon-1024", "BC"); } @@ -35,9 +41,9 @@ public void testKeyPairEncoding() FalconParameterSpec.falcon_512, FalconParameterSpec.falcon_1024, }; - kf = KeyFactory.getInstance("Falcon", "BCPQC"); + kf = KeyFactory.getInstance("Falcon", "BC"); - kpg = KeyPairGenerator.getInstance("Falcon", "BCPQC"); + kpg = KeyPairGenerator.getInstance("Falcon", "BC"); for (int i = 0; i != specs.length; i++) { diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/FalconTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/FalconTest.java index 8441e1e1d2..5908b82825 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/FalconTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/FalconTest.java @@ -16,15 +16,13 @@ import java.security.spec.X509EncodedKeySpec; import junit.framework.TestCase; -import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.pqc.jcajce.interfaces.FalconKey; import org.bouncycastle.pqc.jcajce.interfaces.FalconPrivateKey; -import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; -import org.bouncycastle.pqc.jcajce.spec.DilithiumParameterSpec; import org.bouncycastle.pqc.jcajce.spec.FalconParameterSpec; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; @@ -37,22 +35,22 @@ public class FalconTest public void setUp() { - if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { - Security.addProvider(new BouncyCastlePQCProvider()); + Security.addProvider(new BouncyCastleProvider()); } } public void testPrivateKeyRecovery() throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BC"); kpg.initialize(FalconParameterSpec.falcon_512, new FalconTest.RiggedRandom()); KeyPair kp = kpg.generateKeyPair(); - KeyFactory kFact = KeyFactory.getInstance("Falcon", "BCPQC"); + KeyFactory kFact = KeyFactory.getInstance("Falcon", "BC"); FalconKey privKey = (FalconKey)kFact.generatePrivate(new PKCS8EncodedKeySpec(kp.getPrivate().getEncoded())); @@ -84,13 +82,13 @@ public void testPrivateKeyRecovery() public void testPublicKeyRecovery() throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BC"); kpg.initialize(FalconParameterSpec.falcon_1024, new FalconTest.RiggedRandom()); KeyPair kp = kpg.generateKeyPair(); - KeyFactory kFact = KeyFactory.getInstance("Falcon", "BCPQC"); + KeyFactory kFact = KeyFactory.getInstance("Falcon", "BC"); FalconKey pubKey = (FalconKey)kFact.generatePublic(new X509EncodedKeySpec(kp.getPublic().getEncoded())); @@ -117,13 +115,13 @@ public void testPublicKeyRecovery() public void testFalcon512() throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BC"); kpg.initialize(FalconParameterSpec.falcon_512, new SecureRandom()); KeyPair kp = kpg.generateKeyPair(); - Signature sig = Signature.getInstance("Falcon-512", "BCPQC"); + Signature sig = Signature.getInstance("Falcon-512", "BC"); sig.initSign(kp.getPrivate(), new SecureRandom()); @@ -131,9 +129,9 @@ public void testFalcon512() byte[] s = sig.sign(); - sig = Signature.getInstance("Falcon-512", "BCPQC"); + sig = Signature.getInstance("Falcon-512", "BC"); - assertEquals("Falcon-512", sig.getAlgorithm()); + assertEquals("FALCON-512", Strings.toUpperCase(sig.getAlgorithm())); sig.initVerify(kp.getPublic()); @@ -141,7 +139,7 @@ public void testFalcon512() assertTrue(sig.verify(s)); - kpg = KeyPairGenerator.getInstance("Falcon", "BCPQC"); + kpg = KeyPairGenerator.getInstance("Falcon", "BC"); kpg.initialize(FalconParameterSpec.falcon_1024, new SecureRandom()); @@ -161,13 +159,13 @@ public void testFalcon512() public void testFalcon1024() throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BC"); kpg.initialize(FalconParameterSpec.falcon_1024, new SecureRandom()); KeyPair kp = kpg.generateKeyPair(); - Signature sig = Signature.getInstance("Falcon-1024", "BCPQC"); + Signature sig = Signature.getInstance("Falcon-1024", "BC"); sig.initSign(kp.getPrivate(), new SecureRandom()); @@ -175,9 +173,9 @@ public void testFalcon1024() byte[] s = sig.sign(); - sig = Signature.getInstance("Falcon-1024", "BCPQC"); + sig = Signature.getInstance("Falcon-1024", "BC"); - assertEquals("Falcon-1024", sig.getAlgorithm()); + assertEquals("FALCON-1024", Strings.toUpperCase(sig.getAlgorithm())); sig.initVerify(kp.getPublic()); @@ -185,7 +183,7 @@ public void testFalcon1024() assertTrue(sig.verify(s)); - kpg = KeyPairGenerator.getInstance("Falcon", "BCPQC"); + kpg = KeyPairGenerator.getInstance("Falcon", "BC"); kpg.initialize(FalconParameterSpec.falcon_512, new SecureRandom()); @@ -212,7 +210,7 @@ public void testRestrictedKeyPairGen() private void doTestRestrictedKeyPairGen(FalconParameterSpec spec, FalconParameterSpec altSpec) throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance(spec.getName(), "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance(spec.getName(), "BC"); kpg.initialize(spec, new SecureRandom()); @@ -221,7 +219,7 @@ private void doTestRestrictedKeyPairGen(FalconParameterSpec spec, FalconParamete assertEquals(spec.getName(), kp.getPublic().getAlgorithm()); assertEquals(spec.getName(), kp.getPrivate().getAlgorithm()); - kpg = KeyPairGenerator.getInstance(spec.getName(), "BCPQC"); + kpg = KeyPairGenerator.getInstance(spec.getName(), "BC"); try { @@ -237,13 +235,13 @@ private void doTestRestrictedKeyPairGen(FalconParameterSpec spec, FalconParamete public void testFalconRandomSig() throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BC"); kpg.initialize(FalconParameterSpec.falcon_512, new SecureRandom()); KeyPair kp = kpg.generateKeyPair(); - Signature sig = Signature.getInstance("Falcon", "BCPQC"); + Signature sig = Signature.getInstance("Falcon", "BC"); sig.initSign(kp.getPrivate(), new SecureRandom()); @@ -251,7 +249,7 @@ public void testFalconRandomSig() byte[] s = sig.sign(); - sig = Signature.getInstance("Falcon", "BCPQC"); + sig = Signature.getInstance("Falcon", "BC"); sig.initVerify(kp.getPublic()); @@ -279,7 +277,7 @@ public void testFalconKATSig() byte[] s = Hex.decode("3933b3c07507e4201748494d832b6ee2a6c93bff9b0ee343b550d1f85a3d0de0d704c6d17842951309290765843d1e460d17a527d2bca405bd55bbc7da09a8c620be0af4a767d9db96b80f55e466676751eaaba7b93b86d71132daa0eb376782b9eee37519ce10fdd33fe9f29312c31d8736206d165cf4c528aa3ddc017845e1f0dd5b0a44ff961c42d874a95533e5b438982f524ca954d87533bfbe42c63ff2abc77a34c79db55a99171bbcb72c842a6530af2f753f0c34ac632f9f1e7949f0bf6c67665b27722a8857d626b6ff1a136d923a39f4069b7477ff946e5247a6627791d49b59edc9e2525a860e6e9828d18f64a9f17222e8166a02453859bbda0b8186d8c9928bb571e4146401d7430e225904673ad21ccac54c146c248a1dd69ab6491e901d6d71b152155be97de057f3916a3f1b4273308c29b2f4d9697167b90681b1583ed930a71e990467dea368134beceebd597f9bec922e816f1b0570d728f4ae0464c1f797657f87a4e52dcdcaeb9272662ea66d7c6cd8781b31af555ad93f5f65e75816cb8dc306bb67e592b5261baca7c509629ea2af8abb80cba89ee535b76dfd9ccbbe3bf48f2bc8aa34b26e1103291053f5cb8de3a45afa5a76df8b2122ed2c82fbcf2259290d41a14f86b12f35f5d49762b34cff13ee7e42edec70201d7f37c33316288fa3078e36e58108865c3cfe263d563692043decc62f3426f86061285b7b1b336f56ff41bb65e9cd6d9b92fd90f864aa1c923cb8c755f5cde1770d862595427149d7721aaab5d194aea9acdeca15be43cba6a62b5a33909e9fc4da1c5814fbd7cd6a2fa572e318b42c6c319140b86e66392580a11a2b431f44c1f9270e4f7b2490f3b325a9977a71a575915636635b9969dbd6d220b24c3d99cebbbd834b88222bd08c3abe124e80"); byte[] detachedSig = Arrays.concatenate(Arrays.copyOfRange(s, 0, 41), Arrays.copyOfRange(s, 42, s.length)); - KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("Falcon", "BC"); SecureRandom katRandom = new NISTSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"), null); kpg.initialize(FalconParameterSpec.falcon_512, katRandom); @@ -303,7 +301,7 @@ public void testFalconKATSig() assertTrue(Arrays.areEqual(privCat, privK)); - Signature sig = Signature.getInstance("Falcon", "BCPQC"); + Signature sig = Signature.getInstance("Falcon", "BC"); sig.initSign(kp.getPrivate(), katRandom); @@ -313,7 +311,7 @@ public void testFalconKATSig() assertTrue(Arrays.areEqual(detachedSig, genS)); - sig = Signature.getInstance("Falcon", "BCPQC"); + sig = Signature.getInstance("Falcon", "BC"); sig.initVerify(kp.getPublic()); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KeyStoreTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KeyStoreTest.java index 585d28e7a5..8aeaa7c993 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KeyStoreTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KeyStoreTest.java @@ -50,6 +50,7 @@ public class KeyStoreTest private static final long ONE_DAY_IN_MILLIS = 24 * 60 * 60 * 1000; private static final long TEN_YEARS_IN_MILLIS = 10l * 365 * ONE_DAY_IN_MILLIS; + private static AtomicLong serialNumber = new AtomicLong(System.currentTimeMillis()); private static Map algIds = new HashMap(); static @@ -201,7 +202,6 @@ private static X509Certificate createPQSelfSignedCert(X500Name dn, String sigNam { V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator(); long time = System.currentTimeMillis(); - AtomicLong serialNumber = new AtomicLong(System.currentTimeMillis()); certGen.setSerialNumber(new ASN1Integer(serialNumber.getAndIncrement())); certGen.setIssuer(dn); certGen.setSubject(dn); @@ -238,7 +238,6 @@ private static X509Certificate createCert(X500Name signerName, PrivateKey signer V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator(); long time = System.currentTimeMillis(); - AtomicLong serialNumber = new AtomicLong(System.currentTimeMillis()); certGen.setSerialNumber(new ASN1Integer(serialNumber.getAndIncrement())); certGen.setIssuer(signerName); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KyberKeyPairGeneratorTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KyberKeyPairGeneratorTest.java index bead479a34..d514e8dc73 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KyberKeyPairGeneratorTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KyberKeyPairGeneratorTest.java @@ -36,9 +36,6 @@ public void testKeyPairEncoding() KyberParameterSpec.kyber512, KyberParameterSpec.kyber768, KyberParameterSpec.kyber1024, - KyberParameterSpec.kyber512_aes, - KyberParameterSpec.kyber768_aes, - KyberParameterSpec.kyber1024_aes }; kf = KeyFactory.getInstance("Kyber", "BCPQC"); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KyberTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KyberTest.java index 64ea2891ca..1d00846de6 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KyberTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KyberTest.java @@ -18,6 +18,7 @@ import org.bouncycastle.jcajce.spec.KEMExtractSpec; import org.bouncycastle.jcajce.spec.KEMGenerateSpec; import org.bouncycastle.jcajce.spec.KEMParameterSpec; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; import org.bouncycastle.pqc.jcajce.spec.KyberParameterSpec; import org.bouncycastle.util.Arrays; @@ -57,8 +58,8 @@ public void testBasicKEMCamellia() KeyPairGenerator kpg = KeyPairGenerator.getInstance("Kyber", "BCPQC"); kpg.initialize(KyberParameterSpec.kyber512, new SecureRandom()); - performKEMScipher(kpg.generateKeyPair(), "Kyber", new KEMParameterSpec("Camellia")); - performKEMScipher(kpg.generateKeyPair(), "Kyber", new KEMParameterSpec("Camellia-KWP")); + performKEMScipher(kpg.generateKeyPair(), "Kyber", new KTSParameterSpec.Builder("Camellia", 128).withNoKdf().build()); + performKEMScipher(kpg.generateKeyPair(), "Kyber", new KTSParameterSpec.Builder("Camellia-KWP", 128).withNoKdf().build()); } public void testBasicKEMSEED() @@ -67,7 +68,7 @@ public void testBasicKEMSEED() KeyPairGenerator kpg = KeyPairGenerator.getInstance("Kyber", "BCPQC"); kpg.initialize(KyberParameterSpec.kyber512, new SecureRandom()); - performKEMScipher(kpg.generateKeyPair(), "Kyber", new KEMParameterSpec("SEED")); + performKEMScipher(kpg.generateKeyPair(), "Kyber", new KTSParameterSpec.Builder("SEED", 128).build()); } public void testBasicKEMARIA() @@ -76,11 +77,11 @@ public void testBasicKEMARIA() KeyPairGenerator kpg = KeyPairGenerator.getInstance("Kyber", "BCPQC"); kpg.initialize(KyberParameterSpec.kyber512, new SecureRandom()); - performKEMScipher(kpg.generateKeyPair(), "Kyber", new KEMParameterSpec("ARIA")); - performKEMScipher(kpg.generateKeyPair(), "Kyber", new KEMParameterSpec("ARIA-KWP")); + performKEMScipher(kpg.generateKeyPair(), "Kyber", new KTSParameterSpec.Builder("ARIA", 256).build()); + performKEMScipher(kpg.generateKeyPair(), "Kyber", new KTSParameterSpec.Builder("ARIA-KWP", 256).build()); } - private void performKEMScipher(KeyPair kp, String algorithm, KEMParameterSpec ktsParameterSpec) + private void performKEMScipher(KeyPair kp, String algorithm, KTSParameterSpec ktsParameterSpec) throws Exception { Cipher w1 = Cipher.getInstance(algorithm, "BCPQC"); @@ -119,14 +120,14 @@ public void testGenerateAES() KeyGenerator keyGen = KeyGenerator.getInstance("Kyber", "BCPQC"); - keyGen.init(new KEMGenerateSpec(kp.getPublic(), "AES"), new SecureRandom()); + keyGen.init(new KEMGenerateSpec(kp.getPublic(), "AES", 128), new SecureRandom()); SecretKeyWithEncapsulation secEnc1 = (SecretKeyWithEncapsulation)keyGen.generateKey(); assertEquals("AES", secEnc1.getAlgorithm()); assertEquals(16, secEnc1.getEncoded().length); - keyGen.init(new KEMExtractSpec(kp.getPrivate(), secEnc1.getEncapsulation(), "AES")); + keyGen.init(new KEMExtractSpec(kp.getPrivate(), secEnc1.getEncapsulation(), "AES", 128)); SecretKeyWithEncapsulation secEnc2 = (SecretKeyWithEncapsulation)keyGen.generateKey(); @@ -167,9 +168,6 @@ public void testRestrictedKeyPairGen() doTestRestrictedKeyPairGen(KyberParameterSpec.kyber512, KyberParameterSpec.kyber1024); doTestRestrictedKeyPairGen(KyberParameterSpec.kyber768, KyberParameterSpec.kyber1024); doTestRestrictedKeyPairGen(KyberParameterSpec.kyber1024, KyberParameterSpec.kyber512); - doTestRestrictedKeyPairGen(KyberParameterSpec.kyber512_aes, KyberParameterSpec.kyber1024); - doTestRestrictedKeyPairGen(KyberParameterSpec.kyber768_aes, KyberParameterSpec.kyber1024); - doTestRestrictedKeyPairGen(KyberParameterSpec.kyber1024_aes, KyberParameterSpec.kyber1024); } private void doTestRestrictedKeyPairGen(KyberParameterSpec spec, KyberParameterSpec altSpec) @@ -204,9 +202,6 @@ public void testRestrictedKeyGen() doTestRestrictedKeyGen(KyberParameterSpec.kyber512, KyberParameterSpec.kyber1024); doTestRestrictedKeyGen(KyberParameterSpec.kyber768, KyberParameterSpec.kyber1024); doTestRestrictedKeyGen(KyberParameterSpec.kyber1024, KyberParameterSpec.kyber512); - doTestRestrictedKeyGen(KyberParameterSpec.kyber512_aes, KyberParameterSpec.kyber1024); - doTestRestrictedKeyGen(KyberParameterSpec.kyber768_aes, KyberParameterSpec.kyber1024); - doTestRestrictedKeyGen(KyberParameterSpec.kyber1024_aes, KyberParameterSpec.kyber1024); } private void doTestRestrictedKeyGen(KyberParameterSpec spec, KyberParameterSpec altSpec) @@ -269,9 +264,6 @@ public void testRestrictedCipher() doTestRestrictedCipher(KyberParameterSpec.kyber512, KyberParameterSpec.kyber1024, new byte[16]); doTestRestrictedCipher(KyberParameterSpec.kyber768, KyberParameterSpec.kyber1024, new byte[24]); doTestRestrictedCipher(KyberParameterSpec.kyber1024, KyberParameterSpec.kyber512, new byte[32]); - doTestRestrictedCipher(KyberParameterSpec.kyber512_aes, KyberParameterSpec.kyber1024, new byte[16]); - doTestRestrictedCipher(KyberParameterSpec.kyber768_aes, KyberParameterSpec.kyber1024, new byte[24]); - doTestRestrictedCipher(KyberParameterSpec.kyber1024_aes, KyberParameterSpec.kyber1024, new byte[32]); } private void doTestRestrictedCipher(KyberParameterSpec spec, KyberParameterSpec altSpec, byte[] keyBytes) diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/MLDSAKeyPairGeneratorTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/MLDSAKeyPairGeneratorTest.java new file mode 100644 index 0000000000..dd2442e9b5 --- /dev/null +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/MLDSAKeyPairGeneratorTest.java @@ -0,0 +1,111 @@ +package org.bouncycastle.pqc.jcajce.provider.test; + +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.SecureRandom; +import java.security.Security; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; + +/** + * KeyFactory/KeyPairGenerator tests for MLDSA with BC provider. + */ +public class MLDSAKeyPairGeneratorTest + extends KeyPairGeneratorTest +{ + protected void setUp() + { + super.setUp(); + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + Security.addProvider(new BouncyCastleProvider()); + } + + public void testKeyFactory() + throws Exception + { + kf = KeyFactory.getInstance("ML-DSA", "BC"); + kf = KeyFactory.getInstance("HASH-ML-DSA", "BC"); + } + + public void testKeyPairGeneratorNames() + throws Exception + { + ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[] { + NISTObjectIdentifiers.id_ml_dsa_44, + NISTObjectIdentifiers.id_ml_dsa_65, + NISTObjectIdentifiers.id_ml_dsa_87, + NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512, + NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512, + NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512, + }; + + String[] algs = new String[]{ + "ML-DSA-44", + "ML-DSA-65", + "ML-DSA-87", + "ML-DSA-44-WITH-SHA512", + "ML-DSA-65-WITH-SHA512", + "ML-DSA-87-WITH-SHA512" + }; + + for (int i = 0; i != oids.length; i++) + { + KeyPairGenerator kpGen = KeyPairGenerator.getInstance(oids[i].getId(), "BC"); + + KeyPair kp = kpGen.generateKeyPair(); + + assertEquals(algs[i], kp.getPrivate().getAlgorithm()); + assertEquals(algs[i], kp.getPublic().getAlgorithm()); + } + } + + public void testKeyPairEncoding() + throws Exception + { + MLDSAParameterSpec[] params = + new MLDSAParameterSpec[] + { + MLDSAParameterSpec.ml_dsa_44, + MLDSAParameterSpec.ml_dsa_65, + MLDSAParameterSpec.ml_dsa_87, + MLDSAParameterSpec.ml_dsa_44_with_sha512, + MLDSAParameterSpec.ml_dsa_65_with_sha512, + MLDSAParameterSpec.ml_dsa_87_with_sha512, + }; + + // expected object identifiers + ASN1ObjectIdentifier[] oids = + { + NISTObjectIdentifiers.id_ml_dsa_44, + NISTObjectIdentifiers.id_ml_dsa_65, + NISTObjectIdentifiers.id_ml_dsa_87, + NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512, + NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512, + NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512, + }; + + // + // We use HASH here as (while not recommended) use of both pure and pre-hash keys allowed + kf = KeyFactory.getInstance("HASH-ML-DSA", "BC"); + + kpg = KeyPairGenerator.getInstance("HASH-ML-DSA", "BC"); + + for (int i = 0; i != params.length; i++) + { + kpg.initialize(params[i], new SecureRandom()); + KeyPair keyPair = kpg.generateKeyPair(); + performKeyPairEncodingTest(keyPair); + assertEquals(oids[i], SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded()).getAlgorithm().getAlgorithm()); + } + } + +} diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/MLDSATest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/MLDSATest.java new file mode 100644 index 0000000000..5396bca3c9 --- /dev/null +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/MLDSATest.java @@ -0,0 +1,423 @@ +package org.bouncycastle.pqc.jcajce.provider.test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.SecureRandom; +import java.security.Security; +import java.security.Signature; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import junit.framework.TestCase; +import org.bouncycastle.asn1.ASN1BitString; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.jcajce.interfaces.MLDSAKey; +import org.bouncycastle.jcajce.interfaces.MLDSAPrivateKey; +import org.bouncycastle.jcajce.spec.MLDSAParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Hex; + +/** + * MLDSA now in BC provider + */ +public class MLDSATest + extends TestCase +{ + byte[] msg = Strings.toByteArray("Hello World!"); + + public void setUp() + { + if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + Security.addProvider(new BouncyCastleProvider()); + } + + public void testKeyFactory() + throws Exception + { + KeyFactory kFact = KeyFactory.getInstance("ML-DSA", "BC"); + KeyPairGenerator kpGen44 = KeyPairGenerator.getInstance("ML-DSA-44"); + KeyPair kp44 = kpGen44.generateKeyPair(); + KeyPairGenerator kpGen65 = KeyPairGenerator.getInstance("ML-DSA-65"); + KeyPair kp65 = kpGen65.generateKeyPair(); + KeyPairGenerator kpGen87 = KeyPairGenerator.getInstance("ML-DSA-87"); + KeyPair kp87 = kpGen87.generateKeyPair(); + KeyPairGenerator kpGen44withSha512 = KeyPairGenerator.getInstance("ML-DSA-44-WITH-SHA512"); + KeyPair kp44withSha512 = kpGen44withSha512.generateKeyPair(); + KeyPairGenerator kpGen65withSha512 = KeyPairGenerator.getInstance("ML-DSA-65-WITH-SHA512"); + KeyPair kp65withSha512 = kpGen65withSha512.generateKeyPair(); + KeyPairGenerator kpGen87withSha512 = KeyPairGenerator.getInstance("ML-DSA-87-WITH-SHA512"); + KeyPair kp87withSha512 = kpGen87withSha512.generateKeyPair(); + + tryKeyFact(KeyFactory.getInstance("ML-DSA-44", "BC"), kp44, kp65, "2.16.840.1.101.3.4.3.18"); + tryKeyFact(KeyFactory.getInstance(NISTObjectIdentifiers.id_ml_dsa_44.toString(), "BC"), kp44, kp65, "2.16.840.1.101.3.4.3.18"); + tryKeyFact(KeyFactory.getInstance("ML-DSA-65", "BC"), kp65, kp44, "2.16.840.1.101.3.4.3.17"); + tryKeyFact(KeyFactory.getInstance(NISTObjectIdentifiers.id_ml_dsa_65.toString(), "BC"), kp65, kp44, "2.16.840.1.101.3.4.3.17"); + tryKeyFact(KeyFactory.getInstance("ML-DSA-87", "BC"), kp87, kp65, "2.16.840.1.101.3.4.3.18"); + tryKeyFact(KeyFactory.getInstance(NISTObjectIdentifiers.id_ml_dsa_87.toString(), "BC"), kp87, kp65, "2.16.840.1.101.3.4.3.18"); + tryKeyFact(KeyFactory.getInstance("ML-DSA-44-WITH-SHA512", "BC"), kp44withSha512, kp65, "2.16.840.1.101.3.4.3.18"); + tryKeyFact(KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512.toString(), "BC"), kp44withSha512, kp65, "2.16.840.1.101.3.4.3.18"); + tryKeyFact(KeyFactory.getInstance("ML-DSA-65-WITH-SHA512", "BC"), kp65withSha512, kp44, "2.16.840.1.101.3.4.3.17"); + tryKeyFact(KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512.toString(), "BC"), kp65withSha512, kp44, "2.16.840.1.101.3.4.3.17"); + tryKeyFact(KeyFactory.getInstance("ML-DSA-87-WITH-SHA512", "BC"), kp87withSha512, kp65, "2.16.840.1.101.3.4.3.18"); + tryKeyFact(KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_ml_dsa_87_with_sha512.toString(), "BC"), kp87withSha512, kp65, "2.16.840.1.101.3.4.3.18"); + } + + private void tryKeyFact(KeyFactory kFact, KeyPair kpValid, KeyPair kpInvalid, String oid) + throws Exception + { + kFact.generatePrivate(new PKCS8EncodedKeySpec(kpValid.getPrivate().getEncoded())); + kFact.generatePublic(new X509EncodedKeySpec(kpValid.getPublic().getEncoded())); + + try + { + kFact.generatePrivate(new PKCS8EncodedKeySpec(kpInvalid.getPrivate().getEncoded())); + fail("no exception"); + } + catch (InvalidKeySpecException e) + { + assertEquals("incorrect algorithm OID for key: " + oid, e.getMessage()); + } + try + { + kFact.generatePublic(new X509EncodedKeySpec(kpInvalid.getPublic().getEncoded())); + fail("no exception"); + } + catch (InvalidKeySpecException e) + { + assertEquals("incorrect algorithm OID for key: " + oid, e.getMessage()); + } + } + + public void testPrivateKeyRecovery() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-DSA", "BC"); + + kpg.initialize(MLDSAParameterSpec.ml_dsa_65, new MLDSATest.RiggedRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + KeyFactory kFact = KeyFactory.getInstance("ML-DSA", "BC"); + + MLDSAKey privKey = (MLDSAKey)kFact.generatePrivate(new PKCS8EncodedKeySpec(kp.getPrivate().getEncoded())); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ObjectOutputStream oOut = new ObjectOutputStream(bOut); + + oOut.writeObject(privKey); + + oOut.close(); + + ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray())); + + MLDSAKey privKey2 = (MLDSAKey)oIn.readObject(); + + assertEquals(privKey, privKey2); + + assertEquals(kp.getPublic(), ((MLDSAPrivateKey)privKey2).getPublicKey()); + assertEquals(((MLDSAPrivateKey)privKey).getPublicKey(), ((MLDSAPrivateKey)privKey2).getPublicKey()); + } + + public void testPublicKeyRecovery() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-DSA", "BC"); + + kpg.initialize(MLDSAParameterSpec.ml_dsa_87, new MLDSATest.RiggedRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + KeyFactory kFact = KeyFactory.getInstance("ML-DSA", "BC"); + + MLDSAKey pubKey = (MLDSAKey)kFact.generatePublic(new X509EncodedKeySpec(kp.getPublic().getEncoded())); + + assertEquals(kp.getPublic().hashCode(), pubKey.hashCode()); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ObjectOutputStream oOut = new ObjectOutputStream(bOut); + + oOut.writeObject(pubKey); + + oOut.close(); + + ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray())); + + MLDSAKey pubKey2 = (MLDSAKey)oIn.readObject(); + + assertEquals(pubKey, pubKey2); + assertEquals(pubKey.hashCode(), pubKey2.hashCode()); + } + + public void testRestrictedSignature() + throws Exception + { + doTestRestrictedSignature("ML-DSA-44", MLDSAParameterSpec.ml_dsa_44, MLDSAParameterSpec.ml_dsa_87); + doTestRestrictedSignature("ML-DSA-65", MLDSAParameterSpec.ml_dsa_65, MLDSAParameterSpec.ml_dsa_87); + doTestRestrictedSignature("ML-DSA-87", MLDSAParameterSpec.ml_dsa_87, MLDSAParameterSpec.ml_dsa_44); + doTestRestrictedSignature("ML-DSA-44-WITH-SHA512", MLDSAParameterSpec.ml_dsa_44_with_sha512, MLDSAParameterSpec.ml_dsa_87); + doTestRestrictedSignature("ML-DSA-65-WITH-SHA512", MLDSAParameterSpec.ml_dsa_65_with_sha512, MLDSAParameterSpec.ml_dsa_87); + doTestRestrictedSignature("ML-DSA-87-WITH-SHA512", MLDSAParameterSpec.ml_dsa_87_with_sha512, MLDSAParameterSpec.ml_dsa_44); + } + + private void doTestRestrictedSignature(String sigName, MLDSAParameterSpec spec, MLDSAParameterSpec altSpec) + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-DSA", "BC"); + + kpg.initialize(spec, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + Signature sig = Signature.getInstance(sigName, "BC"); + + sig.initSign(kp.getPrivate(), new SecureRandom()); + + sig.update(msg, 0, msg.length); + + byte[] s = sig.sign(); + + sig = Signature.getInstance(sigName, "BC"); + + assertEquals(sigName, sig.getAlgorithm()); + + sig.initVerify(kp.getPublic()); + + sig.update(msg, 0, msg.length); + + assertTrue(sig.verify(s)); + + kpg = KeyPairGenerator.getInstance("ML-DSA", "BC"); + + kpg.initialize(altSpec, new SecureRandom()); + + kp = kpg.generateKeyPair(); + + try + { + sig.initVerify(kp.getPublic()); + fail("no exception"); + } + catch (InvalidKeyException e) + { + assertEquals("signature configured for " + spec.getName(), e.getMessage()); + } + } + + public void testRestrictedKeyPairGen() + throws Exception + { + doTestRestrictedKeyPairGen(MLDSAParameterSpec.ml_dsa_44, MLDSAParameterSpec.ml_dsa_87); + doTestRestrictedKeyPairGen(MLDSAParameterSpec.ml_dsa_65, MLDSAParameterSpec.ml_dsa_87); + doTestRestrictedKeyPairGen(MLDSAParameterSpec.ml_dsa_87, MLDSAParameterSpec.ml_dsa_44); + doTestRestrictedKeyPairGen(MLDSAParameterSpec.ml_dsa_44_with_sha512, MLDSAParameterSpec.ml_dsa_87); + doTestRestrictedKeyPairGen(MLDSAParameterSpec.ml_dsa_65_with_sha512, MLDSAParameterSpec.ml_dsa_87); + doTestRestrictedKeyPairGen(MLDSAParameterSpec.ml_dsa_87_with_sha512, MLDSAParameterSpec.ml_dsa_44); + } + + private void doTestRestrictedKeyPairGen(MLDSAParameterSpec spec, MLDSAParameterSpec altSpec) + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance(spec.getName(), "BC"); + + kpg.initialize(spec, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + assertEquals(spec.getName(), kpg.getAlgorithm()); + assertEquals(spec.getName(), kp.getPublic().getAlgorithm()); + assertEquals(spec.getName(), kp.getPrivate().getAlgorithm()); + + kpg = KeyPairGenerator.getInstance(spec.getName(), "BC"); + + try + { + kpg.initialize(altSpec, new SecureRandom()); + fail("no exception"); + } + catch (InvalidAlgorithmParameterException e) + { + assertEquals("key pair generator locked to " + spec.getName(), e.getMessage()); + } + } + + public void testMLDSARandomSig() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-DSA", "BC"); + + kpg.initialize(MLDSAParameterSpec.ml_dsa_44, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + Signature sig = Signature.getInstance("ML-DSA", "BC"); + + sig.initSign(kp.getPrivate(), new SecureRandom()); + + sig.update(msg, 0, msg.length); + + byte[] s = sig.sign(); + + sig = Signature.getInstance("ML-DSA", "BC"); + + sig.initVerify(kp.getPublic()); + + sig.update(msg, 0, msg.length); + + assertTrue(sig.verify(s)); + } + + public void testMLDSAKATSig() + throws Exception + { + byte[] pubK = Hex.decode("dc7bc9a2e0b6dc66823ae4fbde971c0cfc46f9d96bbfbeebb3470ae0a5a0139fdd6a6ce5bc76e94faa9e9250abd4cee02cf1ee46a8e99ce12d7395781fa7519021273da3365519724efbe279add6c35f92c9d42b032832f1bf29ebbecd3ec87a3af3da33c611f7f35fa35acab174024f118979e23bf2fe069269a2ec45fbc1b9c1fb0e1f05486a6a833eb48adc2960641d9af6eb8b7381b1ec55d889f26b084ddfa1c9ed9b962d342694cede83825309d9db6bd6ba7582132534861e44a04388a694242411761d34e7c085d282b723c65948a2ac764d9702bd8ed7fe9931d7d8704a39e6508844f3f84843c305594fe6e5404e08f18ed039ac6563cbaa34b0ca38320299d6256ec0f78d421f088159d49dc439cbc539a55884a3eb4efc9cf190b42f713441cb97004245d41437a39b7b77fc602fbbfd619a42363714b265173cae68fd8a1b3ca2bd30ae60c53e5604577a4a3b1f1506e697c37432dbd883553aac8d382a3d250cf5b29e4d1be2cbcd531ff0e07e89c1f7dbc8d4529aeebe55b5ce4d0214bfdec69e080bd3ef36cca6a54933f1ef2f37867c0d38fd5865b87929115808c7e2595458e993bacc6c5a3b9f5025001e9b41447708bfbaa0462efa63876c42f769908b432f5485508a393224960551d77eadfaf4411cbc49fdff46f2f155ddd6ec30867905b709888ca0f30f935fb8d7f4803cfc7a5f7790ca181d99ca21f2621d69a5c6d49c76b4969da62740a378470332b30947ab31ccdb9ba0c7b625879eec4bd81f0200ba23504a7dc3b118bc2ab1145df13af3c8cc39f577873b84911b3d85fbbf4cb19e4d36b10a938eeb78b599dc86615fd6cec6eb7b8f7afa5f6d6be19ea81630d36ccfb2f487de50d0cf46da8d3fe3512812043c0e3ef2d7231fb0b0a35a0fb283be30a1247780f30ae0294e8b6f5897383edb895595f577524df54593cdf927b4967616ee3913e4d6b29b0dbd7c33a2a45e4ef1b1954ea5d91ce37efc1302e7ce02a97395565da2a5c5d3fdb0d87684e9b1c0ad07ec33df2dfad528e2ea0966d2a47dd5ee88e77d653c0d004fab0165f0757c4da40af327e7192536c79947a80a827aa2107dacfae3debfc8fad3d6e08076d938c510a276bdf6721a1f087cb169515028ad5ce27a1047abd92809934ca63b893f71f9a34a99c0fd30310c47e9aa37394d0ab73b254d3ca69d9c5549c9479aae24264ac5ea64d3fd821c3962ec77e709f9d30bc7b65a52e48c16e80603558caca1811411c3155d1f949fc9cf9aa9385a7199e99be77a66fad7eed91258de55b2c4c83f9a050adebea5f09758f40dac4a1c394ee8d687879150d26426895ab1938e14ae11b376254c91fc6130436996f8ed43bd27be20ec9067111c116ec94cc2b06cc91a13c5d10bbd7eecea4792f17b2b77631ef145e9fb41a83eaa11c2b72a48fb90fdbd88644c4edf8ab20dce3118364b276ac1237b36c8926e346aab5a111aa0bf341c518b7bff9e9dbb8bcb4728601b3760663e67650331e6fb54ac82fc414cb8ddfc160a25311ec5272de46217fef8b992ff89754fbee351f21bb90b6c97078b510c983350681266c8fed1f0583c5151e7b8fe3b7292319699687cc6b641fdbd689428543bc0fa1facc109de65b62784c2d985ab15d77d3af12af6d03e8d1859a553688584d75ef673a1de74093ee108c761fff32c217c231b0e2953daf521429264c0963bc8a5cdeddc617a7285b934ea51ddb5cdab23bcede86be36e001bc65c65e9a1c94baff4fab8eb5f8ed42ec377423633fe00049142467c47c5d58a7202c8e9104841c1f7f380145a6a0a828c570235e507ae5868a6062f722bb98ff6be"); + byte[] privK = Hex.decode("dc7bc9a2e0b6dc66823ae4fbde971c0cfc46f9d96bbfbeebb3470ae0a5a0139ff037b84e75537e0a1cf02a517acfe323ffffe11df72e4f38430e0e66a2654b2f2ef757da47649d9f63fa03f1bf6fe6bc7c62971a98a2bd9d36eb0ec43ad4e9d940df3bb5874f5c92192aa31e0535d3cf70950bba858d11a688eaf854f63ecfc520c50d624891434265d8b0680c03061040299a104082c0910c8508d1100d44a6509408292211125b90508a2688e1302dc4021280028ac302611820851237808a000ae2040421b4910bb80550a08051b2511c28428a3672a494504910201bb45161424424a75001328181942d62a850023449ca94200b296213156408924c48122100b605030208e0060200a311e1802021116483a62898029291480801083041066613200e5b360951400c53000aa08851944842e316704ab2089b92440025121b0309418209c2a0800b290a819851c4340da4424500a0105b048e603400138928a4422648002c90202d194068e2146d19278a083746e4146914006422c660d3a03013242844965014166da0284dcc462e94367100232e1c114909a2040131060a2172c2142ada000c5a260d13228a62c444e3142d013445980224d33841c0308121a621e348720b1984d2c89108b8690887714a2884d496451a9301ca2285da30859ac851dcc00820106060465262302aa224251044640b2842988011540692144251d236719bb4900b082890188e41c469e1a469032160e01409d3020c20c88c1cb23164086218476920228ccb8470089528029550533270013405888424541041d202881aa84ccac88181008d0392899ab809d9900c9a1290614065c9322d89860c123521cc4266c8360010062411028ea3b44d44023043a0285a002ed1980c4882658922441c010212907084226e12134d011902519064113364c91806c2c04589262908b63024308cda022e0c27250b367058162c5116420b4946c1208841246c99466a04434e18a86c821661922028639409c30211029520211782d43868003460c84688e0160000a32dc0a82824b640831464c81022a2086503234ac8122ea098418c2072cc308a62c665093408412682da429089328514967081226001176d5948428ab88d592051d80892e2c0889044700ac0245a020904218a59c45094441094140820460209270c441020dcc8209212015038250c456e4a1666223770dc808ca426412222441ba3618a343099844099c42952046d88146ccb242a7cd129a8d333115c62d033b6a8357cf7cd10268ab12f16fceb7975d0a28a6c4822213c9a772df084ad91a669e2040550fc5e8d0aeb10fab2375fc9625ef9cd48c19631997a1cb6455d2c6286c569c9637add0317ce990996b28e51c3f3f717fb5907bbdd53961ad3497f2c3c473cce170906ac4c624a89aa8fbe624d99385e9c9548bf05e8cafd47d2476e41b73001f813726499e88b2b3b6f596ca311657850346598994c40e34747161e4e76264deef2a3019389d1594c942301af47b7544c23ecda2df2dece81e487d8f3f58ea89cd811d7275807ff1b0369ba86470088c174a3099fdafbe5fbb4d158801053b2b435d54059e26dee76d10a7a372f06b0b88b985b32f52052387438be8dc8bc6ae7369e2da9aa5e2585f8de403d091ccb7f790d54ddb34c608b0876f2825e9113be20a2b85867a01bda53287ac780bcd8b606d2e6d7712c56ce0142d22fe6b786de544963e134fecedfafb83d763061d799096a59e30d4472e440ae1faaabdf42640ce69740ceb9cae1a9612c21931b74af3f780236123321b205b6efd6cbb134f4c73d63c0c13e660b59d5920bc33197c355853d8d1cddc7959f7bc500ac81d985016f5b89a0eec79b0d9364ead8e38577c2a6549f2d067cb09438fdb21220aec80f6e22a476f332a2a4a0b7acbeb9e078d2b5a92ae84c924f7cb19fc7df377beb6546af97aa985c747cd111a127a674b4c26d89c14485b82e3a498a12d05406febd6c4d4b8bc051ab2cb91224b078538374b794b7dd9ddf3ac2b4a671fb7b9cf5acb78622ae2709eb2db16943aa24a9c97a81077bc784d25c0ea5991d2de883798a1f0e78f3361ed6a10dded81b1d683658331534fd7c01bc0eb00dfc4c3c84f0693046ff806bb200dd7bd4c0e6abca3f2934b4814fc0e1f8be615a2dda7c8a8d06cf9ce8566b40f4a6543b25bacddc926863fc0fa2007d6d7bf6d18dc98df696bd0865bf0be4c492b8043a32def8e3595ba7da345252f38f95be10fd7fb899b498fa01b09de5d5608eabc44a721aa04c4ef1dcb86102ac5f5f79c9708dcf5c5e896edd8c2c7bde3fa83e6ffce22d66174e31657a0b6361585e669d3031952f08631ae1f16ff90b90d0aad3c6d7e1dd0a9c41ab00a6e1c4f96af9ac5b79fcf821ffc016cb059245fb78dbe6c633d965aaab5333be07195c4b74b18e4600ce783c0a914ef4281016e80a7c9aa92d0fd789879c5e6751125ecb154432311e41cebd4fab3a31e4d2ce22d0f8c67737bf8a0dd85fe1349d5079a4d5feb3fee9378ca47ae46cc58a3f02038cfd53c4cee9cc4270cebc3d115a39c831e8ed41c4dbe4051b51d7872ba0c2bb163e0085201188eaa624a6bea9400a3a1fcc355a57f15704e61fda55a5dbaea8448fa5cb2d377a07f58305ad107e844ab4806e5bf99c1f513ee1d0a2acc04549f0801742169a77971d0adbfbfe0dd2ee5d16bc461e35748d1f3f6f4598321e8c49e79e740f990359858d2729dde007fcb26fdda9aa6e2ec4bd736f2836e7e4c83440191c849f6a53c72a4f8f830d001ea3b18f3cb4a5bd3cf066032b4932cfd2e62a9b55723fa61c688c935518af6860cd649bfbf1bf5fdc1f36dcaefaa157438d1cc8d56a150161511df82631f5e88e773e4ce263f276b7b3678d4c6fc75311d411c0d01bfdb595bb70552838e1b86517c837d909e772b428599e1fe569f77ce61531fde6fd31cdce1bdee4ba467fcbfbb9feeaad99fef67d4906e036c73662ddce158d4e5d4635e5d366f79f31a19d1b3dc4a591b0df194bb06c18147f41d88d1a409becdfb67eb063d16312266fd51b521ba9115e2e5e2aeae6ec511cede13ed4132ffbe0273f6c7039b3874f058804a54809af60557a21d9b4b831d04156a7c22dcbcdfe14f62437f449cb5ef12bf4251d485496cd835c0c2bc58bd845963dfa76ecd68519c4bdaf110be7ab052876dc3407591568c956ea3bf107c90fd5853a292f59a8d4b58b5d3fddf29bdbeac36852e3c69766fe460176a801831292b8e88a74a01ecbbe09a7b4d74cfd7fd628841944d9d556dbd60c76f96f07dc53443805ee9aa09365de4fb8179252c6b099b5dd351fdefc23dbd8090596c5d208ffd2c5661d8e5612dd574fc69045c769a969e600d77cfe192f1d3ae911289355c585811491b0ccd73692ab158824ab9edf8ac8193f0b33e6138b72c6dcd5d344f807b3da92425037de5ea4eead1c795effaa145e2ecdd327606eb2609929b9474b2bb04653602555c068385e92f06f29ca613ce5b4404f01ab1805db0acaa890330d291f40692df382509302b6dc8668f2c8f2d3a44fd58dca26e9802794f73d25b3149e6d576441"); + byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); + byte[] s = Hex.decode("237c7b8820733d2cf35345f8a851996061675570ce42923ee2cd437e41b4a9b391481f71ece9e0b64c584a73710d8d688a930ac0bf02abf57c6e4709e724a9e4178c629018bc0b73b37a087dd3e7ea8da65b1145bcfeed1a7c1223607eaf0aef04ab2b60d47460945c621a4f9356130bcb5e94f00c710d1cfe99c05ea0cf9e0779577f3671560316bf24ec9cf2572b13e9a50d5fbcca4ddce481f740db1d7e200268459629d66eb5a0b5603ad6468a4a04498d84df62ee394d6fc5a3a7b1ef9de0cebe88168e5d6f771efc1ea315e78b83cb2c0ef88f167ee170dffddb9acaa5df380af1f80353746b6a5530c9fde8458eec99b478dcc6673236b277c41cde9eba586b9808146ccfae6fd8bea1d0654f65cac7583ab7050711b1a322d8da6c6aad16608a9053a655580d66016fc9cefaa17fe0fed5080dbd4daa9692f96794243a2813677ad542e1e164efa9341bd0fdba956a1b4b594f1a70fb3c14aed1217b861dcb749a56b281205d7df5d472a08fb376955524dda1017bcc8be85768191d0e18570fa8f263bd592a8d5358cf7f6ac28e0c664776acf51b689cf2e96603cb7de14978cc56f00819a217b5ae5e3c083c487f5a23c07939737c9ed6b2a51e04f39ddc69da569b88054fc64769098056d83539759d0cc487a711125bf73de1f6671695f5633645534e6cb2d374645c3c9fd39c5347c4b82fb1a452fbb6137f3c470eb1fc7240a5c2a281a1dd45670807552bcc0d160a6775b6dfebbc68500eb76e1e96db1ca0f31413c96f87354ab7071c7786c9e67d0d6476282bd676af23feeb7127b7864daca72f994a85bd10f1f66ea1240882f9b62895f19c0aaad1cf35cda81b311993194d977337d9a10728a7f3d82c8d7fe35cd7047d233c8efe1d9b66b2828c9b582dc2e4605683ace6be76ba351b6d7a1db23a81854d17e9601e7dc69beaae6426ef307300508d204b433026e0534dd0f0123b06252524769f2f86771c8cf5ee82f0b3b3010828a300578871af9b6031f34342cb2d5ea4093c50b621b10248d0a32c1cd5684ca50b5f9886e2df6deca3213bd5cd79d63b5dc8266beb4d80beeed82c9ee801ed35c6a9f69947e806e791173b5b883e20192573e85e7003f99c5ab417e72f03563eb93b163f4c2300675e8c1ab9f80cf62c88b1876fd0bd4258e0e083da712e341fbbceef37d59e090f6eca0cb3e8e6b7fe1c7f35c3a9db958cd273fcc581b285e30e3c35714f01d2eda306a6e66d9609d4ae88248bf76a991acb8b833255aaafcb27498d009eff0aa5264e1874b17eb646dfce4707e8bfb946babfa4f7affe388c0656b9dc4a8bbc670e64d42676db5b3cd017ce6d52e2547d43745e66ed9b1ca2228594546b4c2c636f524edec65d9ade60a9fd3b2586af169ada64574d85594cbaac5f3827d3c4317e51722c497f09dcaa4b7c4f03bd4fef3ba847d38d252fccecd7e207830fe4d60733b49527b5d29e71d2b736a97d9d34475fb081d0bc8810507f672ae03232bc32a33c711a3f12826fe1801f40962061e3d3fdeb3368e91eab892cdac18f0e06a4312e67f445578dbeaf54f5c3cbdbae0ab2dd84525a32253b3720d83c9b3e50ecf0554c89d15bd352b0636b40b79d38fc5cca5e696c1ff0cd2f0934fb3eaadccc1b6d5fac5544b6fe5c6e0a317c4fcfff2b1f70718b7e4e7cf3db3bf1c002031ef50c049bdffc3b78358e0be20eb57ed41bae04cdd09091afefa457a8aebb3376370ee04a7f48d444b7f1170edab68e0b970e8fc2850976536ce3bb14586af06baeac171278a5e949e00af7cdb0d4b841244ccccc797ff3fd4187077d4c9d33873cab0bf6e690591b9021f80c52d47494051ac1ff75554b6b1907903dc530ec6b42d025f723d7d4e539222e683e47532541f25f14b0c007b093b7ccbfc0172e78e543517f632149d842821a2b414d0db9aac1398b5e99c269ef4e303e1373f9bcdf8211b55c65ec19f93a0422a7148cabd4c311f11a49efc757534d00cae3c84cb849e975193145538917f81225cc96457bc1a2ab8fa72afa8563dc314766ffd19a10db92dabf9a0656066728d384f598229fa94e906b8a3222b0dfe164afd9c116f31c315ee53ffb0b0d582ee0abfad259f1b4095c00a347673fd4e17ea7d8f974dbf2ed90311cb167d61aebea7b0b17a34f5b721fecafcfbc3feac7091b81851f8a5b051add8e724a503386a53b70d106d86a99813d579ef75a065cf70cc1ab9d80c39a01d3c5946049efed8d4e383b5ca65827a9cee08cba792a903347f7547a64745f8e17d71a0d40d71d15484b9a6814c86230aa05539e907cddda5efb3162c356f35829bc32a28bc80ec9454e5bfec24a6dd74675e3b913647f3d176a6773c1a0e40edd17ecd13aee3493710b1154f855f2591e62cc7073c608bbaa77104e8d4993b67cf81f65af89c8c91d695f7560daa68ad14160cb7df4e7a61b1860255320dbb813676df1285c015aec994d7bc0ce29751416b31ed15b69172968ddaa515692b8febccb4e3298e8bf169c20b965903b80f26f20a6a3bd5facd1bc38c6c817e23bf35187ff75f982ae9ed65a43f6199b61ae84683e1befcf9c0178b8ea2890f96a6e08d33d44c3ce50d9ccbd1cdf96df6b2f5e8f1c6cb04300f7f6d483108390aea8ed31b07b32c87c542ab475946d525e24c16b2d0afb86687e47cce7abb5b7fc41d6a9953a59a8b221d057b793845cfab414726b3753d87c020253fb93722263ceee93a66acf163c86eb7bd62136f70ec414b5562862f1202deeb9feaf7981416be2a09c0e7c1f18ee95314b54d0497bac2986d90e9ed3990220e96ae1622e11f2ee91c1b16128e7384a87fabc6731c7b0b00bb707fd1abe0392c95e4c435460b47d2199829b076b4ef6b11ad32825cad85794a674eefdd6173dca39dcbf397c1b9531380a72d142b7d4005d884fcbd59211827820fc5b2bc605e5c717c31e124cd1f57180d4ba598833f097056f809b71214fbee25f7fe7f14e3df8cb6bbf6c3f3de82885f71bfd874e6b7ad11db7210fd73c0ccbaa60f008a86a59a9860c0c851672da17b077d35977c52cf35bf06d450f3ec061977f627324c55aada361c6abb3de77e828a63aef6dc37cdf0caf3b98c3a409e3cdbdd2edd0dc4feb1a6ede8df7252cb658413f22728142304d7d02b06e438b10814f7731a489e79b6b8a6b0fca6b63fe9a61ff2994704bdff918e1ae6a99df07d3e18a216890465397b6eda5f47ad2f216817544b8840c6af1704d9a71a02c73b6a29fb6fb17787d97a8984790a34736050607093d3f557d9ba5afb8ced3d4dee1e8eef1f8fc0117474f558c96b2b4c2d6d9f8439198aac0cad2d3eaed0d1a243d44456486cfdce4e6f1000000000000000000000000000000000000000000000015222c39"); + + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-DSA", "BC"); + SecureRandom katRandom = new NISTSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"), null); + + kpg.initialize(MLDSAParameterSpec.ml_dsa_44, katRandom); + + KeyPair kp = kpg.generateKeyPair(); + + SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(kp.getPublic().getEncoded()); + + ASN1BitString pubSeq = pubInfo.getPublicKeyData(); + + assertTrue(Arrays.areEqual(pubSeq.getOctets(), pubK)); + + PrivateKeyInfo privInfo = PrivateKeyInfo.getInstance(kp.getPrivate().getEncoded()); + ASN1OctetString seq = ASN1OctetString.getInstance(privInfo.parsePrivateKey()); + + assertTrue(Arrays.areEqual(seq.getOctets(), privK)); + + Signature sig = Signature.getInstance("ML-DSA", "BC"); + + sig.initSign(kp.getPrivate()); + + sig.update(msg, 0, msg.length); + + byte[] genS = sig.sign(); + + assertTrue(Arrays.areEqual(s, genS)); + + sig = Signature.getInstance("ML-DSA", "BC"); + + sig.initVerify(kp.getPublic()); + + sig.update(msg, 0, msg.length); + + assertTrue(sig.verify(s)); + + // check randomisation + + sig.initSign(kp.getPrivate(), new SecureRandom()); + + sig.update(msg, 0, msg.length); + + genS = sig.sign(); + + assertFalse(Arrays.areEqual(s, genS)); + + sig = Signature.getInstance("ML-DSA", "BC"); + + sig.initVerify(kp.getPublic()); + + sig.update(msg, 0, msg.length); + + assertTrue(sig.verify(s)); + } + + public void testHashMLDSAKATSig() + throws Exception + { + byte[] pubK = Hex.decode("dc7bc9a2e0b6dc66823ae4fbde971c0cfc46f9d96bbfbeebb3470ae0a5a0139fdd6a6ce5bc76e94faa9e9250abd4cee02cf1ee46a8e99ce12d7395781fa7519021273da3365519724efbe279add6c35f92c9d42b032832f1bf29ebbecd3ec87a3af3da33c611f7f35fa35acab174024f118979e23bf2fe069269a2ec45fbc1b9c1fb0e1f05486a6a833eb48adc2960641d9af6eb8b7381b1ec55d889f26b084ddfa1c9ed9b962d342694cede83825309d9db6bd6ba7582132534861e44a04388a694242411761d34e7c085d282b723c65948a2ac764d9702bd8ed7fe9931d7d8704a39e6508844f3f84843c305594fe6e5404e08f18ed039ac6563cbaa34b0ca38320299d6256ec0f78d421f088159d49dc439cbc539a55884a3eb4efc9cf190b42f713441cb97004245d41437a39b7b77fc602fbbfd619a42363714b265173cae68fd8a1b3ca2bd30ae60c53e5604577a4a3b1f1506e697c37432dbd883553aac8d382a3d250cf5b29e4d1be2cbcd531ff0e07e89c1f7dbc8d4529aeebe55b5ce4d0214bfdec69e080bd3ef36cca6a54933f1ef2f37867c0d38fd5865b87929115808c7e2595458e993bacc6c5a3b9f5025001e9b41447708bfbaa0462efa63876c42f769908b432f5485508a393224960551d77eadfaf4411cbc49fdff46f2f155ddd6ec30867905b709888ca0f30f935fb8d7f4803cfc7a5f7790ca181d99ca21f2621d69a5c6d49c76b4969da62740a378470332b30947ab31ccdb9ba0c7b625879eec4bd81f0200ba23504a7dc3b118bc2ab1145df13af3c8cc39f577873b84911b3d85fbbf4cb19e4d36b10a938eeb78b599dc86615fd6cec6eb7b8f7afa5f6d6be19ea81630d36ccfb2f487de50d0cf46da8d3fe3512812043c0e3ef2d7231fb0b0a35a0fb283be30a1247780f30ae0294e8b6f5897383edb895595f577524df54593cdf927b4967616ee3913e4d6b29b0dbd7c33a2a45e4ef1b1954ea5d91ce37efc1302e7ce02a97395565da2a5c5d3fdb0d87684e9b1c0ad07ec33df2dfad528e2ea0966d2a47dd5ee88e77d653c0d004fab0165f0757c4da40af327e7192536c79947a80a827aa2107dacfae3debfc8fad3d6e08076d938c510a276bdf6721a1f087cb169515028ad5ce27a1047abd92809934ca63b893f71f9a34a99c0fd30310c47e9aa37394d0ab73b254d3ca69d9c5549c9479aae24264ac5ea64d3fd821c3962ec77e709f9d30bc7b65a52e48c16e80603558caca1811411c3155d1f949fc9cf9aa9385a7199e99be77a66fad7eed91258de55b2c4c83f9a050adebea5f09758f40dac4a1c394ee8d687879150d26426895ab1938e14ae11b376254c91fc6130436996f8ed43bd27be20ec9067111c116ec94cc2b06cc91a13c5d10bbd7eecea4792f17b2b77631ef145e9fb41a83eaa11c2b72a48fb90fdbd88644c4edf8ab20dce3118364b276ac1237b36c8926e346aab5a111aa0bf341c518b7bff9e9dbb8bcb4728601b3760663e67650331e6fb54ac82fc414cb8ddfc160a25311ec5272de46217fef8b992ff89754fbee351f21bb90b6c97078b510c983350681266c8fed1f0583c5151e7b8fe3b7292319699687cc6b641fdbd689428543bc0fa1facc109de65b62784c2d985ab15d77d3af12af6d03e8d1859a553688584d75ef673a1de74093ee108c761fff32c217c231b0e2953daf521429264c0963bc8a5cdeddc617a7285b934ea51ddb5cdab23bcede86be36e001bc65c65e9a1c94baff4fab8eb5f8ed42ec377423633fe00049142467c47c5d58a7202c8e9104841c1f7f380145a6a0a828c570235e507ae5868a6062f722bb98ff6be"); + byte[] privK = Hex.decode("dc7bc9a2e0b6dc66823ae4fbde971c0cfc46f9d96bbfbeebb3470ae0a5a0139ff037b84e75537e0a1cf02a517acfe323ffffe11df72e4f38430e0e66a2654b2f2ef757da47649d9f63fa03f1bf6fe6bc7c62971a98a2bd9d36eb0ec43ad4e9d940df3bb5874f5c92192aa31e0535d3cf70950bba858d11a688eaf854f63ecfc520c50d624891434265d8b0680c03061040299a104082c0910c8508d1100d44a6509408292211125b90508a2688e1302dc4021280028ac302611820851237808a000ae2040421b4910bb80550a08051b2511c28428a3672a494504910201bb45161424424a75001328181942d62a850023449ca94200b296213156408924c48122100b605030208e0060200a311e1802021116483a62898029291480801083041066613200e5b360951400c53000aa08851944842e316704ab2089b92440025121b0309418209c2a0800b290a819851c4340da4424500a0105b048e603400138928a4422648002c90202d194068e2146d19278a083746e4146914006422c660d3a03013242844965014166da0284dcc462e94367100232e1c114909a2040131060a2172c2142ada000c5a260d13228a62c444e3142d013445980224d33841c0308121a621e348720b1984d2c89108b8690887714a2884d496451a9301ca2285da30859ac851dcc00820106060465262302aa224251044640b2842988011540692144251d236719bb4900b082890188e41c469e1a469032160e01409d3020c20c88c1cb23164086218476920228ccb8470089528029550533270013405888424541041d202881aa84ccac88181008d0392899ab809d9900c9a1290614065c9322d89860c123521cc4266c8360010062411028ea3b44d44023043a0285a002ed1980c4882658922441c010212907084226e12134d011902519064113364c91806c2c04589262908b63024308cda022e0c27250b367058162c5116420b4946c1208841246c99466a04434e18a86c821661922028639409c30211029520211782d43868003460c84688e0160000a32dc0a82824b640831464c81022a2086503234ac8122ea098418c2072cc308a62c665093408412682da429089328514967081226001176d5948428ab88d592051d80892e2c0889044700ac0245a020904218a59c45094441094140820460209270c441020dcc8209212015038250c456e4a1666223770dc808ca426412222441ba3618a343099844099c42952046d88146ccb242a7cd129a8d333115c62d033b6a8357cf7cd10268ab12f16fceb7975d0a28a6c4822213c9a772df084ad91a669e2040550fc5e8d0aeb10fab2375fc9625ef9cd48c19631997a1cb6455d2c6286c569c9637add0317ce990996b28e51c3f3f717fb5907bbdd53961ad3497f2c3c473cce170906ac4c624a89aa8fbe624d99385e9c9548bf05e8cafd47d2476e41b73001f813726499e88b2b3b6f596ca311657850346598994c40e34747161e4e76264deef2a3019389d1594c942301af47b7544c23ecda2df2dece81e487d8f3f58ea89cd811d7275807ff1b0369ba86470088c174a3099fdafbe5fbb4d158801053b2b435d54059e26dee76d10a7a372f06b0b88b985b32f52052387438be8dc8bc6ae7369e2da9aa5e2585f8de403d091ccb7f790d54ddb34c608b0876f2825e9113be20a2b85867a01bda53287ac780bcd8b606d2e6d7712c56ce0142d22fe6b786de544963e134fecedfafb83d763061d799096a59e30d4472e440ae1faaabdf42640ce69740ceb9cae1a9612c21931b74af3f780236123321b205b6efd6cbb134f4c73d63c0c13e660b59d5920bc33197c355853d8d1cddc7959f7bc500ac81d985016f5b89a0eec79b0d9364ead8e38577c2a6549f2d067cb09438fdb21220aec80f6e22a476f332a2a4a0b7acbeb9e078d2b5a92ae84c924f7cb19fc7df377beb6546af97aa985c747cd111a127a674b4c26d89c14485b82e3a498a12d05406febd6c4d4b8bc051ab2cb91224b078538374b794b7dd9ddf3ac2b4a671fb7b9cf5acb78622ae2709eb2db16943aa24a9c97a81077bc784d25c0ea5991d2de883798a1f0e78f3361ed6a10dded81b1d683658331534fd7c01bc0eb00dfc4c3c84f0693046ff806bb200dd7bd4c0e6abca3f2934b4814fc0e1f8be615a2dda7c8a8d06cf9ce8566b40f4a6543b25bacddc926863fc0fa2007d6d7bf6d18dc98df696bd0865bf0be4c492b8043a32def8e3595ba7da345252f38f95be10fd7fb899b498fa01b09de5d5608eabc44a721aa04c4ef1dcb86102ac5f5f79c9708dcf5c5e896edd8c2c7bde3fa83e6ffce22d66174e31657a0b6361585e669d3031952f08631ae1f16ff90b90d0aad3c6d7e1dd0a9c41ab00a6e1c4f96af9ac5b79fcf821ffc016cb059245fb78dbe6c633d965aaab5333be07195c4b74b18e4600ce783c0a914ef4281016e80a7c9aa92d0fd789879c5e6751125ecb154432311e41cebd4fab3a31e4d2ce22d0f8c67737bf8a0dd85fe1349d5079a4d5feb3fee9378ca47ae46cc58a3f02038cfd53c4cee9cc4270cebc3d115a39c831e8ed41c4dbe4051b51d7872ba0c2bb163e0085201188eaa624a6bea9400a3a1fcc355a57f15704e61fda55a5dbaea8448fa5cb2d377a07f58305ad107e844ab4806e5bf99c1f513ee1d0a2acc04549f0801742169a77971d0adbfbfe0dd2ee5d16bc461e35748d1f3f6f4598321e8c49e79e740f990359858d2729dde007fcb26fdda9aa6e2ec4bd736f2836e7e4c83440191c849f6a53c72a4f8f830d001ea3b18f3cb4a5bd3cf066032b4932cfd2e62a9b55723fa61c688c935518af6860cd649bfbf1bf5fdc1f36dcaefaa157438d1cc8d56a150161511df82631f5e88e773e4ce263f276b7b3678d4c6fc75311d411c0d01bfdb595bb70552838e1b86517c837d909e772b428599e1fe569f77ce61531fde6fd31cdce1bdee4ba467fcbfbb9feeaad99fef67d4906e036c73662ddce158d4e5d4635e5d366f79f31a19d1b3dc4a591b0df194bb06c18147f41d88d1a409becdfb67eb063d16312266fd51b521ba9115e2e5e2aeae6ec511cede13ed4132ffbe0273f6c7039b3874f058804a54809af60557a21d9b4b831d04156a7c22dcbcdfe14f62437f449cb5ef12bf4251d485496cd835c0c2bc58bd845963dfa76ecd68519c4bdaf110be7ab052876dc3407591568c956ea3bf107c90fd5853a292f59a8d4b58b5d3fddf29bdbeac36852e3c69766fe460176a801831292b8e88a74a01ecbbe09a7b4d74cfd7fd628841944d9d556dbd60c76f96f07dc53443805ee9aa09365de4fb8179252c6b099b5dd351fdefc23dbd8090596c5d208ffd2c5661d8e5612dd574fc69045c769a969e600d77cfe192f1d3ae911289355c585811491b0ccd73692ab158824ab9edf8ac8193f0b33e6138b72c6dcd5d344f807b3da92425037de5ea4eead1c795effaa145e2ecdd327606eb2609929b9474b2bb04653602555c068385e92f06f29ca613ce5b4404f01ab1805db0acaa890330d291f40692df382509302b6dc8668f2c8f2d3a44fd58dca26e9802794f73d25b3149e6d576441"); + byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); + byte[] s = Hex.decode("eea01acc8fe6631c9260996def0c75d84998cf4512c7b67bc4246bbfbff165a404d02bca30da1c2b61d91d7986a467fd4b3a1131077ac138b4011ef07fc1f3ca6237e7fc6550c7e071c939f4554f265362eb26158ee1a2e57c72d20beb78168d9e2d7faf54763755a44bdc29e575884133062453a9e3e761a13a82143d7db7215ab0b8628c096e0f298491a8d67517ab8a90be7db5d311eddc7e883d50eb873decd9b3e420155008c0a3632d51f93a9c67ea336273c8f26617c7cfa2a3aa6d9aa075e75fc60fb587fb5522cb6bac4ef1979a069a15aed3171660ce5da2c27af188e9d3bc62eebdbd798f1a650c7d46411e3cabeb27be3ae787b5f4d82a2e2cf4eee84b4fc82edea4533a47bf7d3791933d1c5ce19c1792a6420c9dcd540dc3a494d9b518ce5f4f85d7747c2fa45d812d16f089682c57a96061210c942dbaca8dbde509f56f498d68f0b4e6f4a51373c9f5a5db2e20ec8254ea9d59f69d732fd1b1149fbd0b608368086a3b6acbe5de156fc508390ddc9ca28d201fdc67140a767b2d99d08051255e73d423750e91b1aa31982cc7014e46c75b69ec972f15745bafbe4878f73d8800d80ad22716f15f4d964f0468e8583add1a4ba8f544e9b83dd6c5ebf744436e254bd699e8909e712d9f6e69fbda39be69a4e0bb58cdd0ddbd369cf5a6475b1ad5fe2849c439611516bd13de14b34b26a731c5a5bde4fae538782a6daeb6fbdaf4cf1af40f3b9c7896e87ac71b3fc95eea02f2f28bf62b9d613998ad973added64515a699fc89304b8fe4d4c97759662b720835c2b28585648e54dedfbfa40fd1455e8a945a390765e3b1a2588286bd4f2995eca39ce9eca6d2e32d92e18c930e4b99109f148db96f1763703aeb431c3c815d577c2b0282181932bb182325bf45e1355d91c8ec669ccd94429dc4ea0abc562988bd2b27b39f2dd0e4ace6fc9148cd064005e9cf0f8105a6534261942774c2a02f150f8d250822745b1cc40e1d57c68dea152c0f5088712266e5a37eb7760204c2747561688990d3cf7c76660e5671727c7ebde56420c91549a48b3763062ff92a4679e7d3e8569303eeff650c0ae606234d70a350aa9862b912825b13c1ec7bd6bf346717b0f30c45c1925873f04d469fd28f82f19375531ffb83851c471ebf623c86130d929e739bd8721d97ca9a83676f26c0a75493b5b02f0921aea91baae2da96532ab9db04dc997d5f800f58a891f6ef26e5478de1ce9b4da04eccac4cee81de5c3b1010ef28242217ec737beb36815c4af1de9a4160180ea896120ce96869bf551bb6be079482f4ab5c0f7f234c50bb4139ff9fba1b594c85cc3780434fc00f7d0492cfc86c0d1889784b113650e3c29bb2e9ed6f94df5ea42afac8060856fb90fab5f4c6fb6875fd67e0438335bcd5199b72706cf358492e5f4945bf2a686aa2861908d6a71ba4e760c87e75a7ff31169993cf048817512aeac4e960771879be541b1adcd6c2da9f9d2153e728d4ee1e91acd7f704e0b472856cfd8f85e2f30b0f6e427f190dbc1079343fdc71f9ac0b8aa5e6fdfd60fe9c90e4bebd4a91dbf16378bcc2a330aeed5b7e8dd617fbf3c6ed9b2c2ac82f2e9d03c975b2a832a667864090da9ca91ad1af97278f6cfebeaf2cc681957f3d75d17a5710de85444b636cf7e0dbac06852fe669f87bc7c430ff548ee0b34f1a68e86f1b26290f8a056c0bccd18a540ce04ee7fdee47f5176b811021a89d170e71250a040e10f8f900236617c6be92217b77aa00854d6376739d5a63d32a377da20c368092367fc6afb62e0b898c01462a399aa3dba4beb0d03d7f8a2e84b499a41e7a6e50cd5e09b4d6d8cb3e8ee3a2d1b50775f9caf7335f1ea15b2312352831418ce2529542011a19c6ece5c1e6dfe7e37821933594ca6f55ca6c799b32f88b21d59744c10538ea7208eb61a04d24476c326068ac9ad4199080e02b95766f6a18738c7e4506d18e9c5c526ef4f28ef14662667dc865ffd446026cefca1b39be77cdfd7773aac0bf570647c21979b9f0ff0d67f2a9940e1e1c27e9e3296c7d890c5627e9126fa09bed1f242aa23112d828529ce431939c9ecc0d4311742a1fa5f9f283eb0135093d3e6aa9e89d4641415678f0b2ecb1210a611d062c5e17f01521aa45d778e2a0770cfda540ce1b5bbb3fabfc783601480b080f4e7275e69705b6cff043a3b503da77fbdc05702b790b1cf4dccfb6b2df00bf0ee896420175e1293a6b8fbc96cf9759a6c0e56067dc9e2522621af2cf830e2bb648f0ca3560bdf9c2c0c01bb23806455bc40889472398f9daf71f0ab9e1aab2fe8d6c8c504a1a45d99229828a9588a559a7172b041b2bbcdbe2e59b749b3e1219abf51a39164c9fac17bd8c83eab1e0e04e029550b689134194d486083b956706a6706274324d63ff79c35f37cf8c2932910e60e1da7cc6c4d9b966fb11437f7d4e94221e4b9ce51ea04325e4b75e45dbbbaadeeadd432e776c9b14cff55529c24b43211b52d1f27de0d86c0f253ec3c2262fdfb1ecb18442174321bbed4c1454522d747be4f53f9ea445d4db360c5c0ddbac51179c7f6016249bcadcce47d4abaf0604047d806f556d11aba411239a32a80d4403c72198036917b6c3b9c5fefcbb73b4d11cea0cc09b419ab8bb0a093131b4c32280fac586bee305e14a18432bbaf1ad6ffc67863edd564df4f9518c6363b80d83c59440bde98c2eeed939bfa1d8f720a805088e2090ab1af71ad5190978b2e23a7d58fc28ab2ed623f2cc65d67629a2fbbe84309a3e0447f3805728155cca522217f9e66b5b2d794fec7131b091f7f77df37e8d726f150d416018941a7b48617fe291a3a3594df80bb1927d87d8f8d5cb945c39c977e7a4f9882e3facd6f26e42390a1f7d14e55797bd22ae78ac11208084be07399d2f9cd2fa331784c5e65de766d87c3d19aad2c7993485e65f11b2c03533f265d9268f8d7f9ce14f97a76891e2b764d2e0a7baf2f81c6fcfd15c78552bba4952fe375c9872a25fddfa19a29695320858fa8a910c29d0739edff01da6d80f757906f7103984c4910c44220ce83fb5b46527c918d186b5c096ea4d1c85df71b4e7d625bb2df5a898880a18238eb4388f66f0d5daf074bdfc6e3b4695ef5faaf754ed764b80463d724d1fc41b598861207d1971cfe1e857cf2bf8dcc4afae1e44c622d96194d3f85fa5a37aed9a154074fbc54d50724658678dfba30bce2fc853bf87f7379d80865f08f0a772afedd8f45808b49605ff3d2875a6ce7b90f4a61fc55734f791bf2e6ed554309111a385158627d7e828491a2b7c6d1f00315162c42435b62656f89bbbcbfe1e6e8f0f7f9000711123b5b6ea7b0b7b8c9d2e5e9f5fc09727a9b9e9fb3d3d6e9ebf4000000000000000000000000000011253642"); + + KeyPairGenerator kpg = KeyPairGenerator.getInstance("HASH-ML-DSA", "BC"); + SecureRandom katRandom = new NISTSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"), null); + + kpg.initialize(MLDSAParameterSpec.ml_dsa_44, katRandom); + + KeyPair kp = kpg.generateKeyPair(); + + SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(kp.getPublic().getEncoded()); + + ASN1BitString pubSeq = pubInfo.getPublicKeyData(); + + assertTrue(Arrays.areEqual(pubSeq.getOctets(), pubK)); + + PrivateKeyInfo privInfo = PrivateKeyInfo.getInstance(kp.getPrivate().getEncoded()); + ASN1OctetString seq = ASN1OctetString.getInstance(privInfo.parsePrivateKey()); + + assertTrue(Arrays.areEqual(seq.getOctets(), privK)); + + Signature sig = Signature.getInstance("HASH-ML-DSA", "BC"); + + sig.initSign(kp.getPrivate()); + + sig.update(msg, 0, msg.length); + + byte[] genS = sig.sign(); + + assertTrue(Arrays.areEqual(s, genS)); + + sig = Signature.getInstance("HASH-ML-DSA", "BC"); + + sig.initVerify(kp.getPublic()); + + sig.update(msg, 0, msg.length); + + assertTrue(sig.verify(s)); + + // check randomisation + + sig.initSign(kp.getPrivate(), new SecureRandom()); + + sig.update(msg, 0, msg.length); + + genS = sig.sign(); + + assertFalse(Arrays.areEqual(s, genS)); + + sig = Signature.getInstance("HASH-ML-DSA", "BC"); + + sig.initVerify(kp.getPublic()); + + sig.update(msg, 0, msg.length); + + assertTrue(sig.verify(s)); + } + + private static class RiggedRandom + extends SecureRandom + { + public void nextBytes(byte[] bytes) + { + for (int i = 0; i != bytes.length; i++) + { + bytes[i] = (byte)(i & 0xff); + } + } + } +} diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/MLKEMKeyPairGeneratorTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/MLKEMKeyPairGeneratorTest.java new file mode 100644 index 0000000000..161e03f106 --- /dev/null +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/MLKEMKeyPairGeneratorTest.java @@ -0,0 +1,70 @@ +package org.bouncycastle.pqc.jcajce.provider.test; + + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.jcajce.interfaces.MLKEMPrivateKey; +import org.bouncycastle.jcajce.spec.MLKEMParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; + +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.SecureRandom; +import java.security.Security; + +/** + * KeyFactory/KeyPairGenerator tests for MLKEM with BCPQC provider. + */ +public class MLKEMKeyPairGeneratorTest + extends KeyPairGeneratorTest +{ + protected void setUp() + { + super.setUp(); + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + Security.addProvider(new BouncyCastleProvider()); + } + + public void testKeyFactory() + throws Exception + { + kf = KeyFactory.getInstance("ML-KEM", "BC"); + } + + public void testKeyPairEncoding() + throws Exception + { + MLKEMParameterSpec[] params = + new MLKEMParameterSpec[] + { + MLKEMParameterSpec.ml_kem_512, + MLKEMParameterSpec.ml_kem_768, + MLKEMParameterSpec.ml_kem_1024, + }; + // expected object identifiers + ASN1ObjectIdentifier[] oids = + { + NISTObjectIdentifiers.id_alg_ml_kem_512, + NISTObjectIdentifiers.id_alg_ml_kem_768, + NISTObjectIdentifiers.id_alg_ml_kem_1024, + }; + kf = KeyFactory.getInstance("ML-KEM", "BC"); + + kpg = KeyPairGenerator.getInstance("ML-KEM", "BC"); + + for (int i = 0; i != params.length; i++) + { + kpg.initialize(params[i], new SecureRandom()); + KeyPair keyPair = kpg.generateKeyPair(); + performKeyPairEncodingTest(keyPair); + assertEquals(oids[i], SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded()).getAlgorithm().getAlgorithm()); + } + } + +} diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/MLKEMTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/MLKEMTest.java new file mode 100644 index 0000000000..2405074a65 --- /dev/null +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/MLKEMTest.java @@ -0,0 +1,359 @@ +package org.bouncycastle.pqc.jcajce.provider.test; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.SecureRandom; +import java.security.Security; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import junit.framework.TestCase; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.jcajce.SecretKeyWithEncapsulation; +import org.bouncycastle.jcajce.spec.KEMExtractSpec; +import org.bouncycastle.jcajce.spec.KEMGenerateSpec; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.jcajce.spec.MLKEMParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; + +/** + * KEM tests for MLKEM with the BC provider. + */ +public class MLKEMTest + extends TestCase +{ + public void setUp() + { + if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + Security.addProvider(new BouncyCastleProvider()); + } + + public void testKeyFactory() + throws Exception + { + KeyFactory kFact = KeyFactory.getInstance("ML-KEM", "BC"); + KeyPairGenerator kpGen512 = KeyPairGenerator.getInstance("ML-KEM-512"); + KeyPair kp512 = kpGen512.generateKeyPair(); + KeyPairGenerator kpGen768 = KeyPairGenerator.getInstance("ML-KEM-768"); + KeyPair kp768 = kpGen768.generateKeyPair(); + KeyPairGenerator kpGen1024 = KeyPairGenerator.getInstance("ML-KEM-1024"); + KeyPair kp1024 = kpGen1024.generateKeyPair(); + + tryKeyFact(KeyFactory.getInstance("ML-KEM-512", "BC"), kp512, kp768, "2.16.840.1.101.3.4.4.2"); + tryKeyFact(KeyFactory.getInstance(NISTObjectIdentifiers.id_alg_ml_kem_512.toString(), "BC"), kp512, kp768, "2.16.840.1.101.3.4.4.2"); + tryKeyFact(KeyFactory.getInstance("ML-KEM-768", "BC"), kp768, kp512, "2.16.840.1.101.3.4.4.1"); + tryKeyFact(KeyFactory.getInstance(NISTObjectIdentifiers.id_alg_ml_kem_768.toString(), "BC"), kp768, kp512, "2.16.840.1.101.3.4.4.1"); + tryKeyFact(KeyFactory.getInstance("ML-KEM-1024", "BC"), kp1024, kp768, "2.16.840.1.101.3.4.4.2"); + tryKeyFact(KeyFactory.getInstance(NISTObjectIdentifiers.id_alg_ml_kem_1024.toString(), "BC"), kp1024, kp768, "2.16.840.1.101.3.4.4.2"); + } + + private void tryKeyFact(KeyFactory kFact, KeyPair kpValid, KeyPair kpInvalid, String oid) + throws Exception + { + kFact.generatePrivate(new PKCS8EncodedKeySpec(kpValid.getPrivate().getEncoded())); + kFact.generatePublic(new X509EncodedKeySpec(kpValid.getPublic().getEncoded())); + + try + { + kFact.generatePrivate(new PKCS8EncodedKeySpec(kpInvalid.getPrivate().getEncoded())); + fail("no exception"); + } + catch (InvalidKeySpecException e) + { + assertEquals("incorrect algorithm OID for key: " + oid, e.getMessage()); + } + try + { + kFact.generatePublic(new X509EncodedKeySpec(kpInvalid.getPublic().getEncoded())); + fail("no exception"); + } + catch (InvalidKeySpecException e) + { + assertEquals("incorrect algorithm OID for key: " + oid, e.getMessage()); + } + } + + public void testBasicKEMCamellia() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM", "BC"); + kpg.initialize(MLKEMParameterSpec.ml_kem_512, new SecureRandom()); + + performKEMScipher(kpg.generateKeyPair(), "ML-KEM", new KTSParameterSpec.Builder("Camellia", 128).withNoKdf().build()); + performKEMScipher(kpg.generateKeyPair(), "ML-KEM", new KTSParameterSpec.Builder("Camellia-KWP", 128).withNoKdf().build()); + } + + public void testBasicKEMSEED() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM", "BC"); + kpg.initialize(MLKEMParameterSpec.ml_kem_512, new SecureRandom()); + + performKEMScipher(kpg.generateKeyPair(), "ML-KEM", new KTSParameterSpec.Builder("SEED", 128).build()); + } + + public void testBasicKEMARIA() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM", "BC"); + kpg.initialize(MLKEMParameterSpec.ml_kem_512, new SecureRandom()); + + performKEMScipher(kpg.generateKeyPair(), "ML-KEM", new KTSParameterSpec.Builder("ARIA", 256).build()); + performKEMScipher(kpg.generateKeyPair(), "ML-KEM", new KTSParameterSpec.Builder("ARIA-KWP", 256).build()); + } + + private void performKEMScipher(KeyPair kp, String algorithm, KTSParameterSpec ktsParameterSpec) + throws Exception + { + Cipher w1 = Cipher.getInstance(algorithm, "BC"); + + byte[] keyBytes; + if (algorithm.endsWith("KWP")) + { + keyBytes = Hex.decode("000102030405060708090a0b0c0d0e0faa"); + } + else + { + keyBytes = Hex.decode("000102030405060708090a0b0c0d0e0f"); + } + SecretKey key = new SecretKeySpec(keyBytes, "AES"); + + w1.init(Cipher.WRAP_MODE, kp.getPublic(), ktsParameterSpec); + + byte[] data = w1.wrap(key); + + Cipher w2 = Cipher.getInstance(algorithm, "BC"); + + w2.init(Cipher.UNWRAP_MODE, kp.getPrivate(), ktsParameterSpec); + + Key k = w2.unwrap(data, "AES", Cipher.SECRET_KEY); + + assertTrue(Arrays.areEqual(keyBytes, k.getEncoded())); + } + + public void testGenerateAES() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM", "BC"); + kpg.initialize(MLKEMParameterSpec.ml_kem_512, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + KeyGenerator keyGen = KeyGenerator.getInstance("ML-KEM", "BC"); + + keyGen.init(new KEMGenerateSpec(kp.getPublic(), "AES", 128), new SecureRandom()); + + SecretKeyWithEncapsulation secEnc1 = (SecretKeyWithEncapsulation)keyGen.generateKey(); + + assertEquals("AES", secEnc1.getAlgorithm()); + assertEquals(16, secEnc1.getEncoded().length); + + keyGen.init(new KEMExtractSpec(kp.getPrivate(), secEnc1.getEncapsulation(), "AES", 128)); + + SecretKeyWithEncapsulation secEnc2 = (SecretKeyWithEncapsulation)keyGen.generateKey(); + + assertEquals("AES", secEnc2.getAlgorithm()); + + assertTrue(Arrays.areEqual(secEnc1.getEncoded(), secEnc2.getEncoded())); + } + + public void testGenerateAES256() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM", "BC"); + kpg.initialize(MLKEMParameterSpec.ml_kem_1024, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + KeyGenerator keyGen = KeyGenerator.getInstance("ML-KEM", "BC"); + + keyGen.init(new KEMGenerateSpec(kp.getPublic(), "AES"), new SecureRandom()); + + SecretKeyWithEncapsulation secEnc1 = (SecretKeyWithEncapsulation)keyGen.generateKey(); + + assertEquals("AES", secEnc1.getAlgorithm()); + assertEquals(32, secEnc1.getEncoded().length); + + keyGen.init(new KEMExtractSpec(kp.getPrivate(), secEnc1.getEncapsulation(), "AES")); + + SecretKeyWithEncapsulation secEnc2 = (SecretKeyWithEncapsulation)keyGen.generateKey(); + + assertEquals("AES", secEnc2.getAlgorithm()); + + assertTrue(Arrays.areEqual(secEnc1.getEncoded(), secEnc2.getEncoded())); + } + + public void testRestrictedKeyPairGen() + throws Exception + { + doTestRestrictedKeyPairGen(MLKEMParameterSpec.ml_kem_512, MLKEMParameterSpec.ml_kem_1024); + doTestRestrictedKeyPairGen(MLKEMParameterSpec.ml_kem_768, MLKEMParameterSpec.ml_kem_1024); + doTestRestrictedKeyPairGen(MLKEMParameterSpec.ml_kem_1024, MLKEMParameterSpec.ml_kem_512); + } + + private void doTestRestrictedKeyPairGen(MLKEMParameterSpec spec, MLKEMParameterSpec altSpec) + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance(spec.getName(), "BC"); + + kpg.initialize(spec, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + assertEquals(spec.getName(), kpg.getAlgorithm()); + assertEquals(spec.getName(), kp.getPublic().getAlgorithm()); + assertEquals(spec.getName(), kp.getPrivate().getAlgorithm()); + + kpg = KeyPairGenerator.getInstance(spec.getName(), "BC"); + + try + { + kpg.initialize(altSpec, new SecureRandom()); + fail("no exception"); + } + catch (InvalidAlgorithmParameterException e) + { + assertEquals("key pair generator locked to " + spec.getName(), e.getMessage()); + } + } + + public void testRestrictedKeyGen() + throws Exception + { + doTestRestrictedKeyGen(MLKEMParameterSpec.ml_kem_512, MLKEMParameterSpec.ml_kem_1024); + doTestRestrictedKeyGen(MLKEMParameterSpec.ml_kem_768, MLKEMParameterSpec.ml_kem_1024); + doTestRestrictedKeyGen(MLKEMParameterSpec.ml_kem_1024, MLKEMParameterSpec.ml_kem_512); + } + + private void doTestRestrictedKeyGen(MLKEMParameterSpec spec, MLKEMParameterSpec altSpec) + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance(spec.getName(), "BC"); + + kpg.initialize(spec, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + assertEquals(spec.getName(), kpg.getAlgorithm()); + assertEquals(spec.getName(), kp.getPublic().getAlgorithm()); + assertEquals(spec.getName(), kp.getPrivate().getAlgorithm()); + + KeyGenerator keyGen = KeyGenerator.getInstance(spec.getName(), "BC"); + + assertEquals(spec.getName(), keyGen.getAlgorithm()); + + keyGen.init(new KEMGenerateSpec(kp.getPublic(), "AES"), new SecureRandom()); + + SecretKeyWithEncapsulation secEnc1 = (SecretKeyWithEncapsulation)keyGen.generateKey(); + + keyGen.init(new KEMExtractSpec(kp.getPrivate(), secEnc1.getEncapsulation(), "AES")); + + SecretKeyWithEncapsulation secEnc2 = (SecretKeyWithEncapsulation)keyGen.generateKey(); + + assertTrue(Arrays.areEqual(secEnc1.getEncoded(), secEnc2.getEncoded())); + + kpg = KeyPairGenerator.getInstance("ML-KEM", "BC"); + + kpg.initialize(altSpec, new SecureRandom()); + + kp = kpg.generateKeyPair(); + + try + { + keyGen.init(new KEMExtractSpec(kp.getPrivate(), secEnc1.getEncapsulation(), "AES")); + fail("no exception"); + } + catch (InvalidAlgorithmParameterException e) + { + assertEquals("key generator locked to " + spec.getName(), e.getMessage()); + } + + try + { + keyGen.init(new KEMGenerateSpec(kp.getPublic(), "AES")); + fail("no exception"); + } + catch (InvalidAlgorithmParameterException e) + { + assertEquals("key generator locked to " + spec.getName(), e.getMessage()); + } + } + + public void testRestrictedCipher() + throws Exception + { + doTestRestrictedCipher(MLKEMParameterSpec.ml_kem_512, MLKEMParameterSpec.ml_kem_1024, new byte[16]); + doTestRestrictedCipher(MLKEMParameterSpec.ml_kem_768, MLKEMParameterSpec.ml_kem_1024, new byte[24]); + doTestRestrictedCipher(MLKEMParameterSpec.ml_kem_1024, MLKEMParameterSpec.ml_kem_512, new byte[32]); + } + + private void doTestRestrictedCipher(MLKEMParameterSpec spec, MLKEMParameterSpec altSpec, byte[] keyBytes) + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance(spec.getName(), "BC"); + + kpg.initialize(spec, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + assertEquals(spec.getName(), kpg.getAlgorithm()); + assertEquals(spec.getName(), kp.getPublic().getAlgorithm()); + assertEquals(spec.getName(), kp.getPrivate().getAlgorithm()); + + Cipher cipher = Cipher.getInstance(spec.getName(), "BC"); + + assertEquals(spec.getName(), cipher.getAlgorithm()); + + cipher.init(Cipher.WRAP_MODE, kp.getPublic(), new SecureRandom()); + + byte[] wrapBytes = cipher.wrap(new SecretKeySpec(keyBytes, "AES")); + + cipher.init(Cipher.UNWRAP_MODE, kp.getPrivate()); + + Key unwrapKey = cipher.unwrap(wrapBytes, "AES", Cipher.SECRET_KEY); + + assertTrue(Arrays.areEqual(keyBytes, unwrapKey.getEncoded())); + + kpg = KeyPairGenerator.getInstance("ML-KEM", "BC"); + + kpg.initialize(altSpec, new SecureRandom()); + + kp = kpg.generateKeyPair(); + + try + { + cipher.init(Cipher.UNWRAP_MODE, kp.getPrivate()); + fail("no exception"); + } + catch (InvalidKeyException e) + { + assertEquals("cipher locked to " + spec.getName(), e.getMessage()); + } + + try + { + cipher.init(Cipher.WRAP_MODE, kp.getPublic(), new SecureRandom()); + fail("no exception"); + } + catch (InvalidKeyException e) + { + assertEquals("cipher locked to " + spec.getName(), e.getMessage()); + } + } +} diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUKeyPairGeneratorTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUKeyPairGeneratorTest.java index 28540c00ff..e0712eb702 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUKeyPairGeneratorTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUKeyPairGeneratorTest.java @@ -3,12 +3,14 @@ import java.security.KeyFactory; import java.security.KeyPairGenerator; import java.security.SecureRandom; +import java.security.Security; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.pqc.jcajce.spec.NTRUParameterSpec; /** - * KeyFactory/KeyPairGenerator tests for NTRU with BCPQC provider. + * KeyFactory/KeyPairGenerator tests for NTRU with BC provider. */ public class NTRUKeyPairGeneratorTest extends KeyPairGeneratorTest @@ -16,13 +18,17 @@ public class NTRUKeyPairGeneratorTest protected void setUp() { super.setUp(); + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastleProvider()); + } } public void testKeyFactory() throws Exception { - kf = KeyFactory.getInstance("NTRU", "BCPQC"); - kf = KeyFactory.getInstance(BCObjectIdentifiers.pqc_kem_ntru.getId(), "BCPQC"); + kf = KeyFactory.getInstance("NTRU", "BC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.pqc_kem_ntru.getId(), "BC"); } public void testKeyPairEncoding() @@ -34,11 +40,13 @@ public void testKeyPairEncoding() NTRUParameterSpec.ntruhps2048509, NTRUParameterSpec.ntruhps2048677, NTRUParameterSpec.ntruhps4096821, - NTRUParameterSpec.ntruhrss701 + NTRUParameterSpec.ntruhps40961229, + NTRUParameterSpec.ntruhrss701, + NTRUParameterSpec.ntruhrss1373 }; - kf = KeyFactory.getInstance("NTRU", "BCPQC"); + kf = KeyFactory.getInstance("NTRU", "BC"); - kpg = KeyPairGenerator.getInstance("NTRU", "BCPQC"); + kpg = KeyPairGenerator.getInstance("NTRU", "BC"); for (int i = 0; i != specs.length; i++) { diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRULPRimeTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRULPRimeTest.java index 0905c9f408..1a9f8346fd 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRULPRimeTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRULPRimeTest.java @@ -16,6 +16,7 @@ import org.bouncycastle.jcajce.spec.KEMExtractSpec; import org.bouncycastle.jcajce.spec.KEMGenerateSpec; import org.bouncycastle.jcajce.spec.KEMParameterSpec; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; import org.bouncycastle.pqc.jcajce.spec.NTRULPRimeParameterSpec; import org.bouncycastle.util.Arrays; @@ -65,7 +66,7 @@ public void testBasicKEMSEED() KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRULPRime", "BCPQC"); kpg.initialize(NTRULPRimeParameterSpec.ntrulpr653, new SecureRandom()); - performKEMScipher(kpg.generateKeyPair(), "NTRULPRime", new KEMParameterSpec("SEED")); + performKEMScipher(kpg.generateKeyPair(), "NTRULPRime", new KTSParameterSpec.Builder("SEED", 128).build()); } public void testBasicKEMARIA() @@ -78,7 +79,7 @@ public void testBasicKEMARIA() performKEMScipher(kpg.generateKeyPair(), "NTRULPRime", new KEMParameterSpec("ARIA-KWP")); } - private void performKEMScipher(KeyPair kp, String algorithm, KEMParameterSpec ktsParameterSpec) + private void performKEMScipher(KeyPair kp, String algorithm, KTSParameterSpec ktsParameterSpec) throws Exception { Cipher w1 = Cipher.getInstance(algorithm, "BCPQC"); @@ -122,7 +123,7 @@ public void testGenerateAES() SecretKeyWithEncapsulation secEnc1 = (SecretKeyWithEncapsulation)keyGen.generateKey(); assertEquals("AES", secEnc1.getAlgorithm()); - assertEquals(16, secEnc1.getEncoded().length); + assertEquals(32, secEnc1.getEncoded().length); keyGen.init(new KEMExtractSpec(kp.getPrivate(), secEnc1.getEncapsulation(), "AES"), new SecureRandom()); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUTest.java index ffc0528c6b..0b85163c85 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUTest.java @@ -16,29 +16,29 @@ import org.bouncycastle.jcajce.spec.KEMExtractSpec; import org.bouncycastle.jcajce.spec.KEMGenerateSpec; import org.bouncycastle.jcajce.spec.KEMParameterSpec; -import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.pqc.jcajce.spec.NTRUParameterSpec; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; /** - * KEM tests for NTRU with the BCPQC provider. + * KEM tests for NTRU with the BC provider. */ public class NTRUTest extends TestCase { public void setUp() { - if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { - Security.addProvider(new BouncyCastlePQCProvider()); + Security.addProvider(new BouncyCastleProvider()); } } public void testBasicKEMAES() throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BC"); kpg.initialize(NTRUParameterSpec.ntruhps2048509, new SecureRandom()); performKEMScipher(kpg.generateKeyPair(), "NTRU", new KEMParameterSpec("AES")); @@ -52,7 +52,7 @@ public void testBasicKEMAES() public void testBasicKEMCamellia() throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BC"); kpg.initialize(NTRUParameterSpec.ntruhps2048509, new SecureRandom()); performKEMScipher(kpg.generateKeyPair(), "NTRU", new KEMParameterSpec("Camellia")); @@ -62,16 +62,16 @@ public void testBasicKEMCamellia() public void testBasicKEMSEED() throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BC"); kpg.initialize(NTRUParameterSpec.ntruhps2048509, new SecureRandom()); - performKEMScipher(kpg.generateKeyPair(), "NTRU", new KEMParameterSpec("SEED")); + performKEMScipher(kpg.generateKeyPair(), "NTRU", new KEMParameterSpec("SEED", 128)); } public void testBasicKEMARIA() throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BC"); kpg.initialize(NTRUParameterSpec.ntruhps2048677, new SecureRandom()); performKEMScipher(kpg.generateKeyPair(), "NTRU", new KEMParameterSpec("ARIA")); @@ -81,7 +81,7 @@ public void testBasicKEMARIA() private void performKEMScipher(KeyPair kp, String algorithm, KEMParameterSpec ktsParameterSpec) throws Exception { - Cipher w1 = Cipher.getInstance(algorithm, "BCPQC"); + Cipher w1 = Cipher.getInstance(algorithm, "BC"); byte[] keyBytes; if (algorithm.endsWith("KWP")) @@ -98,7 +98,7 @@ private void performKEMScipher(KeyPair kp, String algorithm, KEMParameterSpec kt byte[] data = w1.wrap(key); - Cipher w2 = Cipher.getInstance(algorithm, "BCPQC"); + Cipher w2 = Cipher.getInstance(algorithm, "BC"); w2.init(Cipher.UNWRAP_MODE, kp.getPrivate(), ktsParameterSpec); @@ -108,23 +108,23 @@ private void performKEMScipher(KeyPair kp, String algorithm, KEMParameterSpec kt } public void testGenerateAES() - throws Exception + throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BC"); kpg.initialize(NTRUParameterSpec.ntruhps2048509, new SecureRandom()); KeyPair kp = kpg.generateKeyPair(); - KeyGenerator keyGen = KeyGenerator.getInstance("NTRU", "BCPQC"); + KeyGenerator keyGen = KeyGenerator.getInstance("NTRU", "BC"); - keyGen.init(new KEMGenerateSpec(kp.getPublic(), "AES"), new SecureRandom()); + keyGen.init(new KEMGenerateSpec(kp.getPublic(), "AES", 128), new SecureRandom()); SecretKeyWithEncapsulation secEnc1 = (SecretKeyWithEncapsulation)keyGen.generateKey(); assertEquals("AES", secEnc1.getAlgorithm()); assertEquals(16, secEnc1.getEncoded().length); - keyGen.init(new KEMExtractSpec(kp.getPrivate(), secEnc1.getEncapsulation(), "AES"), new SecureRandom()); + keyGen.init(new KEMExtractSpec(kp.getPrivate(), secEnc1.getEncapsulation(), "AES", 128), new SecureRandom()); SecretKeyWithEncapsulation secEnc2 = (SecretKeyWithEncapsulation)keyGen.generateKey(); @@ -136,12 +136,12 @@ public void testGenerateAES() public void testGenerateAES256() throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BCPQC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BC"); kpg.initialize(NTRUParameterSpec.ntruhps4096821, new SecureRandom()); KeyPair kp = kpg.generateKeyPair(); - KeyGenerator keyGen = KeyGenerator.getInstance("NTRU", "BCPQC"); + KeyGenerator keyGen = KeyGenerator.getInstance("NTRU", "BC"); keyGen.init(new KEMGenerateSpec(kp.getPublic(), "AES"), new SecureRandom()); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/RainbowTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/RainbowTest.java index c652c95a44..a6fd39d1ab 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/RainbowTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/RainbowTest.java @@ -169,7 +169,7 @@ private void doConfSigTest(String algorithmName, AlgorithmParameterSpec algSpec, sig = Signature.getInstance(algorithmName, "BCPQC"); - assertEquals(algorithmName, sig.getAlgorithm()); + assertEquals(Strings.toUpperCase(algorithmName), Strings.toUpperCase(sig.getAlgorithm())); sig.initVerify(kp.getPublic()); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SLHDSAKeyPairGeneratorTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SLHDSAKeyPairGeneratorTest.java new file mode 100644 index 0000000000..304012c671 --- /dev/null +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SLHDSAKeyPairGeneratorTest.java @@ -0,0 +1,154 @@ +package org.bouncycastle.pqc.jcajce.provider.test; + +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.SecureRandom; +import java.security.Security; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.Arrays; + + +/** + * KeyFactory/KeyPairGenerator tests for SLHDSA with the BC provider. + */ +public class SLHDSAKeyPairGeneratorTest + extends KeyPairGeneratorTest +{ + + protected void setUp() + { + super.setUp(); + Security.addProvider(new BouncyCastleProvider()); + } + + public void testKeyFactory() + throws Exception + { + kf = KeyFactory.getInstance("SLH-DSA", "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_slh_dsa_sha2_128s.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_slh_dsa_sha2_128f.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_slh_dsa_sha2_192s.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_slh_dsa_sha2_192f.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_slh_dsa_sha2_256s.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_slh_dsa_sha2_256f.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_slh_dsa_shake_128s.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_slh_dsa_shake_128f.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_slh_dsa_shake_192s.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_slh_dsa_shake_192f.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_slh_dsa_shake_256s.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_slh_dsa_shake_256f.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256.getId(), "BC"); + kf = KeyFactory.getInstance(NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256.getId(), "BC"); + } + + public void testKeySpecs() + throws Exception + { + kf = KeyFactory.getInstance("SLH-DSA", "BC"); + kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC"); + KeyPair kp = kpg.generateKeyPair(); + + PKCS8EncodedKeySpec privSpec = kf.getKeySpec(kp.getPrivate(), PKCS8EncodedKeySpec.class); + + assertTrue(Arrays.areEqual(kp.getPrivate().getEncoded(), privSpec.getEncoded())); + + X509EncodedKeySpec pubSpec = kf.getKeySpec(kp.getPublic(), X509EncodedKeySpec.class); + + assertTrue(Arrays.areEqual(kp.getPublic().getEncoded(), pubSpec.getEncoded())); + } + + public void testKeyPairEncoding() + throws Exception + { + kf = KeyFactory.getInstance("HASH-SLH-DSA", "BC"); + + SLHDSAParameterSpec[] params = + { + SLHDSAParameterSpec.slh_dsa_sha2_128s, + SLHDSAParameterSpec.slh_dsa_sha2_128f, + SLHDSAParameterSpec.slh_dsa_sha2_192s, + SLHDSAParameterSpec.slh_dsa_sha2_192f, + SLHDSAParameterSpec.slh_dsa_sha2_256s, + SLHDSAParameterSpec.slh_dsa_sha2_256f, + + SLHDSAParameterSpec.slh_dsa_shake_128s, + SLHDSAParameterSpec.slh_dsa_shake_128f, + SLHDSAParameterSpec.slh_dsa_shake_192s, + SLHDSAParameterSpec.slh_dsa_shake_192f, + SLHDSAParameterSpec.slh_dsa_shake_256s, + SLHDSAParameterSpec.slh_dsa_shake_256f, + + SLHDSAParameterSpec.slh_dsa_sha2_128s_with_sha256, + SLHDSAParameterSpec.slh_dsa_sha2_128f_with_sha256, + SLHDSAParameterSpec.slh_dsa_sha2_192s_with_sha512, + SLHDSAParameterSpec.slh_dsa_sha2_192f_with_sha512, + SLHDSAParameterSpec.slh_dsa_sha2_256s_with_sha512, + SLHDSAParameterSpec.slh_dsa_sha2_256f_with_sha512, + + SLHDSAParameterSpec.slh_dsa_shake_128s_with_shake128, + SLHDSAParameterSpec.slh_dsa_shake_128f_with_shake128, + SLHDSAParameterSpec.slh_dsa_shake_192s_with_shake256, + SLHDSAParameterSpec.slh_dsa_shake_192f_with_shake256, + SLHDSAParameterSpec.slh_dsa_shake_256s_with_shake256, + SLHDSAParameterSpec.slh_dsa_shake_256f_with_shake256, + }; + + // expected object identifiers + ASN1ObjectIdentifier[] oids = + { + NISTObjectIdentifiers.id_slh_dsa_sha2_128s, + NISTObjectIdentifiers.id_slh_dsa_sha2_128f, + NISTObjectIdentifiers.id_slh_dsa_sha2_192s, + NISTObjectIdentifiers.id_slh_dsa_sha2_192f, + NISTObjectIdentifiers.id_slh_dsa_sha2_256s, + NISTObjectIdentifiers.id_slh_dsa_sha2_256f, + NISTObjectIdentifiers.id_slh_dsa_shake_128s, + NISTObjectIdentifiers.id_slh_dsa_shake_128f, + NISTObjectIdentifiers.id_slh_dsa_shake_192s, + NISTObjectIdentifiers.id_slh_dsa_shake_192f, + NISTObjectIdentifiers.id_slh_dsa_shake_256s, + NISTObjectIdentifiers.id_slh_dsa_shake_256f, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256 + }; + + kpg = KeyPairGenerator.getInstance("HASH-SLH-DSA", "BC"); + + for (int i = 0; i != params.length; i++) + { + kpg.initialize(params[i], new SecureRandom()); + KeyPair keyPair = kpg.generateKeyPair(); + performKeyPairEncodingTest(keyPair); + assertEquals(oids[i], SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded()).getAlgorithm().getAlgorithm()); + } + } + +} diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SLHDSATest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SLHDSATest.java new file mode 100644 index 0000000000..4fef6e3543 --- /dev/null +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SLHDSATest.java @@ -0,0 +1,532 @@ +package org.bouncycastle.pqc.jcajce.provider.test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.SecureRandom; +import java.security.Security; +import java.security.Signature; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import junit.framework.TestCase; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.jcajce.interfaces.SLHDSAKey; +import org.bouncycastle.jcajce.interfaces.SLHDSAPrivateKey; +import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.FixedSecureRandom; + +/** + * Test cases for the use of SLH-DSA with the provider. + */ +public class SLHDSATest + extends TestCase +{ + // test vector courtesy the "Yawning Angel" GO implementation and the SUPERCOP reference implementation. + byte[] msg = Strings.toByteArray("Cthulhu Fthagn --What a wonderful phrase!Cthulhu Fthagn --Say it and you're crazed!"); + + public void setUp() + { + if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + Security.addProvider(new BouncyCastleProvider()); + } + + public void testKeyFactory() + throws Exception + { + KeyPairGenerator kpGen44 = KeyPairGenerator.getInstance("ML-DSA-44"); + KeyPair kp44 = kpGen44.generateKeyPair(); + + KeyFactory kFact = KeyFactory.getInstance("HASH-SLH-DSA", "BC"); + + String[] names = new String[] { + "SLH-DSA-SHA2-128F", + "SLH-DSA-SHA2-128S", + "SLH-DSA-SHA2-192F", + "SLH-DSA-SHA2-192S", + "SLH-DSA-SHA2-256F", + "SLH-DSA-SHA2-256S", + "SLH-DSA-SHAKE-128F", + "SLH-DSA-SHAKE-128S", + "SLH-DSA-SHAKE-192F", + "SLH-DSA-SHAKE-192S", + "SLH-DSA-SHAKE-256F", + "SLH-DSA-SHAKE-256S", + "SLH-DSA-SHA2-128F-WITH-SHA256", + "SLH-DSA-SHA2-128S-WITH-SHA256", + "SLH-DSA-SHA2-192F-WITH-SHA512", + "SLH-DSA-SHA2-192S-WITH-SHA512", + "SLH-DSA-SHA2-256F-WITH-SHA512", + "SLH-DSA-SHA2-256S-WITH-SHA512", + "SLH-DSA-SHAKE-128F-WITH-SHAKE128", + "SLH-DSA-SHAKE-128S-WITH-SHAKE128", + "SLH-DSA-SHAKE-192F-WITH-SHAKE256", + "SLH-DSA-SHAKE-192S-WITH-SHAKE256", + "SLH-DSA-SHAKE-256F-WITH-SHAKE256", + "SLH-DSA-SHAKE-256S-WITH-SHAKE256", + }; + + ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[] { + NISTObjectIdentifiers.id_slh_dsa_sha2_128f, + NISTObjectIdentifiers.id_slh_dsa_sha2_128s, + NISTObjectIdentifiers.id_slh_dsa_sha2_192f, + NISTObjectIdentifiers.id_slh_dsa_sha2_192s, + NISTObjectIdentifiers.id_slh_dsa_sha2_256f, + NISTObjectIdentifiers.id_slh_dsa_sha2_256s, + NISTObjectIdentifiers.id_slh_dsa_shake_128f, + NISTObjectIdentifiers.id_slh_dsa_shake_128s, + NISTObjectIdentifiers.id_slh_dsa_shake_192f, + NISTObjectIdentifiers.id_slh_dsa_shake_192s, + NISTObjectIdentifiers.id_slh_dsa_shake_256f, + NISTObjectIdentifiers.id_slh_dsa_shake_256s, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512, + NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256, + NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256, + }; + + for (int i = 0; i != names.length; i++) + { + KeyPairGenerator kpGen = KeyPairGenerator.getInstance(names[i]); + KeyPair kp = kpGen.generateKeyPair(); + + tryKeyFact(KeyFactory.getInstance(names[i], "BC"), kp, kp44, "2.16.840.1.101.3.4.3.17"); + tryKeyFact(KeyFactory.getInstance(oids[i].toString(), "BC"), kp, kp44, "2.16.840.1.101.3.4.3.17"); + } + } + + private void tryKeyFact(KeyFactory kFact, KeyPair kpValid, KeyPair kpInvalid, String oid) + throws Exception + { + kFact.generatePrivate(new PKCS8EncodedKeySpec(kpValid.getPrivate().getEncoded())); + kFact.generatePublic(new X509EncodedKeySpec(kpValid.getPublic().getEncoded())); + + try + { + kFact.generatePrivate(new PKCS8EncodedKeySpec(kpInvalid.getPrivate().getEncoded())); + fail("no exception"); + } + catch (InvalidKeySpecException e) + { + assertEquals("incorrect algorithm OID for key: " + oid, e.getMessage()); + } + try + { + kFact.generatePublic(new X509EncodedKeySpec(kpInvalid.getPublic().getEncoded())); + fail("no exception"); + } + catch (InvalidKeySpecException e) + { + assertEquals("incorrect algorithm OID for key: " + oid, e.getMessage()); + } + } + +// public void testSphincsDefaultKeyGen() +// throws Exception +// { +// KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC"); +// +// kpg.initialize(new SLHDSAKeyGenParameterSpec(), new RiggedRandom()); +// +// KeyPair kp = kpg.generateKeyPair(); +// +// SLHDSAKey pub = (SLHDSAKey)kp.getPublic(); +// +// assertTrue(Arrays.areEqual(expSha2Pub, pub.getKeyData())); +// +// SLHDSAKey priv = (SLHDSAKey)kp.getPrivate(); +// +// assertTrue(Arrays.areEqual(expSha2Priv, priv.getKeyData())); +// +// KeyFactory keyFact = KeyFactory.getInstance("SLH-DSA", "BC"); +// +// SLHDSAKey pub2 = (SLHDSAKey)keyFact.generatePublic(new X509EncodedKeySpec(pub.getEncoded())); +// +// assertTrue(Arrays.areEqual(expSha2Pub, pub2.getKeyData())); +// +// SLHDSAKey priv2 = (SLHDSAKey)keyFact.generatePrivate(new PKCS8EncodedKeySpec(priv.getEncoded())); +// +// assertTrue(Arrays.areEqual(expSha2Priv, priv2.getKeyData())); +// } + + public void testPrivateKeyRecovery() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC"); + + kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, new RiggedRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + KeyFactory kFact = KeyFactory.getInstance("SLH-DSA", "BC"); + + SLHDSAKey privKey = (SLHDSAKey)kFact.generatePrivate(new PKCS8EncodedKeySpec(kp.getPrivate().getEncoded())); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ObjectOutputStream oOut = new ObjectOutputStream(bOut); + + oOut.writeObject(privKey); + + oOut.close(); + + ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray())); + + SLHDSAKey privKey2 = (SLHDSAKey)oIn.readObject(); + + assertEquals(privKey, privKey2); + + assertEquals(kp.getPublic(), ((SLHDSAPrivateKey)privKey2).getPublicKey()); + assertEquals(((SLHDSAPrivateKey)privKey).getPublicKey(), ((SLHDSAPrivateKey)privKey2).getPublicKey()); + } + + public void testPublicKeyRecovery() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC"); + + kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, new RiggedRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + KeyFactory kFact = KeyFactory.getInstance("SLH-DSA", "BC"); + + SLHDSAKey pubKey = (SLHDSAKey)kFact.generatePublic(new X509EncodedKeySpec(kp.getPublic().getEncoded())); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ObjectOutputStream oOut = new ObjectOutputStream(bOut); + + oOut.writeObject(pubKey); + + oOut.close(); + + ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray())); + + SLHDSAKey pubKey2 = (SLHDSAKey)oIn.readObject(); + + assertEquals(pubKey, pubKey2); + } + +// public void testSphincsDefaultSha2KeyGen() +// throws Exception +// { +// KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC"); +// +// kpg.initialize(new SLHDSAKeyGenParameterSpec(SLHDSAKeyGenParameterSpec.SHA512_256), new RiggedRandom()); +// +// KeyPair kp = kpg.generateKeyPair(); +// +// SLHDSAKey pub = (SLHDSAKey)kp.getPublic(); +// +// assertTrue(Arrays.areEqual(expSha2Pub, pub.getKeyData())); +// +// SLHDSAKey priv = (SLHDSAKey)kp.getPrivate(); +// +// assertTrue(Arrays.areEqual(expSha2Priv, priv.getKeyData())); +// +// KeyFactory keyFact = KeyFactory.getInstance("SLH-DSA", "BC"); +// +// SLHDSAKey pub2 = (SLHDSAKey)keyFact.generatePublic(new X509EncodedKeySpec(pub.getEncoded())); +// +// assertTrue(Arrays.areEqual(expSha2Pub, pub2.getKeyData())); +// +// SubjectPublicKeyInfo pkInfo = SubjectPublicKeyInfo.getInstance(pub2.getEncoded()); +// +// assertEquals(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512_256), SLHDSAKeyParams.getInstance(pkInfo.getAlgorithm().getParameters()).getTreeDigest()); +// +// SLHDSAKey priv2 = (SLHDSAKey)keyFact.generatePrivate(new PKCS8EncodedKeySpec(priv.getEncoded())); +// +// assertTrue(Arrays.areEqual(expSha2Priv, priv2.getKeyData())); +// } +// +// public void testSphincsDefaultSha3KeyGen() +// throws Exception +// { +// KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC"); +// +// kpg.initialize(new SLHDSAKeyGenParameterSpec(SLHDSAKeyGenParameterSpec.SHA3_256), new RiggedRandom()); +// +// KeyPair kp = kpg.generateKeyPair(); +// +// SLHDSAKey pub = (SLHDSAKey)kp.getPublic(); +// +// assertTrue(Arrays.areEqual(expSha3Pub, pub.getKeyData())); +// +// SLHDSAKey priv = (SLHDSAKey)kp.getPrivate(); +// +// assertTrue(Arrays.areEqual(expSha3Priv, priv.getKeyData())); +// +// KeyFactory keyFact = KeyFactory.getInstance("SLH-DSA", "BC"); +// +// SLHDSAKey pub2 = (SLHDSAKey)keyFact.generatePublic(new X509EncodedKeySpec(pub.getEncoded())); +// +// assertTrue(Arrays.areEqual(expSha3Pub, pub2.getKeyData())); +// +// SubjectPublicKeyInfo pkInfo = SubjectPublicKeyInfo.getInstance(pub2.getEncoded()); +// +// assertEquals(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_256), SLHDSAKeyParams.getInstance(pkInfo.getAlgorithm().getParameters()).getTreeDigest()); +// +// SLHDSAKey priv2 = (SLHDSAKey)keyFact.generatePrivate(new PKCS8EncodedKeySpec(priv.getEncoded())); +// +// assertTrue(Arrays.areEqual(expSha3Priv, priv2.getKeyData())); +// } +// +// public void testSphincsSha2Signature() +// throws Exception +// { +// KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC"); +// +// kpg.initialize(new SLHDSAKeyGenParameterSpec(SLHDSAKeyGenParameterSpec.SHA512_256), new RiggedRandom()); +// +// KeyPair kp = kpg.generateKeyPair(); +// +// Signature sig = Signature.getInstance("SHA512withSPHINCSPlus", "BC"); +// +// sig.initSign(kp.getPrivate()); +// +// sig.update(msg, 0, msg.length); +// +// byte[] s = sig.sign(); +// +// assertTrue(Arrays.areEqual(expSha2Sig, s)); +// } +// +// public void testSphincsSha3Signature() +// throws Exception +// { +// KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC"); +// +// kpg.initialize(new SLHDSAKeyGenParameterSpec(SLHDSAKeyGenParameterSpec.SHA3_256), new RiggedRandom()); +// +// KeyPair kp = kpg.generateKeyPair(); +// +// Signature sig = Signature.getInstance("SHA3-512withSPHINCSPlus", "BC"); +// +// sig.initSign(kp.getPrivate()); +// +// sig.update(msg, 0, msg.length); +// +// byte[] s = sig.sign(); +// +// assertTrue(Arrays.areEqual(expSha3Sig, s)); +// } +// + + + public void testSphincsRandomSigSHA2() + throws Exception + { + SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3" + + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")); + byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); + + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC"); + + kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, random); + + KeyPair kp = kpg.generateKeyPair(); + + Signature sig = Signature.getInstance("SLH-DSA", "BC"); + + sig.initSign(kp.getPrivate(), new FixedSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"))); + + sig.update(msg, 0, msg.length); + + byte[] s = sig.sign(); + byte[] expected = Hex.decode("97abf8262ecc8090d912c7aab1d951fffe1d9aa683a5565490221122f945825b2ac44a170d76442f7fc9d8479c05fc5c044bef94a5007cb258ed8efeb8f35e30837001c505dfe87196966c3b2591d7ffefded746660ffadac38782fc9e887bd324e744023b2520d60b6b6916b0285a42e4943c476434754b1651d1e8414070e65933d5916d66359b682c3568e893083e8fbc333f6bfa9e1584cfe0b688be3a5b22e6fefd77ff194597a17c275251598d94c68e73a1aee194f80ebbbf1a43eeacee49907870366d6eff0a85e609e5a8cdb3067b0412c5d4e62591f78ddb8b90c8fab47aa311c6731aaf1b8b6449173bb4062873ddc668978b4042d369bcb3e645369dfe15cd1d6216db70094597bd0c5b8c8cd81c1919fea04ff18683716c8b85c3508c5a21307f5c47810c27c4c3718deb7d714da3b1a21831f7f46e3cb81c42d89acca9040845a0207e1f05843df19bbef671e6bcffab6c13ee26c81bdae2823ab931933ab4528ab725c3c2483e3a4d85a07f089e74ab31a1813ce8593f0c3cd69e0fa54010ae149ca1a7c8afd0006b9244fde5fd3dc295c499bec19bb43527f7d6c9333ec9cab552b8971e130b689a7cea652239bea9efa132ce57a4c890ca5316b82425020114554b5c740d9c26b2ed736755984bdc83af939529254f9535f6926820d4fdbfec80ce88704c4a916e1a1641edf36dc9f2e0c4a68bec42e86c5cbc63acac1bb7126cb1046caeaf82e6c8655e82ef599a01bf9f4b7685b9b8957aa22e27ad8a5ee9addd86189562da654d69b90d31fb25e5a67ca50fff17fa8f7798ff7773d0b715b3958d043503b0240bf36936b4f8330c1c8b09fecd0303c5969d251f37423db8f83c79a093d7989fe2138cb696bdbed6e1dca17d5f18b5bbdb8629fc36a97599fc29aa792204976fabf826f670150df32d3f8670d600d3b703a1e2dcdc314cb9f4a42384ae90ee75967dbb2509077cf63ca42da5ec94ff32409440e47280bfb838a4e4fd2f0c078227718a6e7ab20fd0465e5aab1a3a29c30f0aecd55f0ff760862a1aa13c0db77411cdb48a34a95f716224fcd4a39bcd828f668b7d5632050a5256c644f2a46001998cfb11afaf70794495a6c61e33e8eb01011225364f9e8503ee9272a6174ae35622e3a0e808b2ec5aaf55c955680a5d4df3717f08207d4602a429b0f5adc0a071ce29b322bd3dacc755ddb2d3190c1b7f40b539293221ec98a206daaace78eb178cc47f3d5f2c3f224a6fc32090a0d1591c9d061125ced2be9e9585f2bb07f6b819b1da276e435a191fefbe6b9d44563da04f5731ae33fcd67ac1ec6875e0d1f8bfcad6d947d173cfcdd6aec22365af44e19168d1c0e6ba5f02b4402ec2b719f94d7097ead10f133e8cb675e4a34558ae77a032ce082e12c0c6badb5db19e92fd1303397db5753d9afa4d18e57f9cc26e8b5bd102b77eec3bc47f16babb451ed4a69ddff494f8a5dcfc1b5f8bb9400ed508214084a6065cb7d0a8efb8a073e3d91905dc8f926cbe20b6b3a0beb9a2d4dd12f70341e80ed59375ad2c38650f9bec4db036b344d7e8fd9919de04d14a4f19d2e91a123e65221267a7878121d61104a6594003e605f45e230892bf8d0fe13af8404adb1dc5876917a4dfe435edccc65f15bb7ce066fed76d3f02ca16be94187fb7f37b5379eea8da682f958d263c42f45cfa181fead2b31cf893de43a9041d414cb1ef4424d95741b8e3a74ce7b2dbe16ef0fb4d596196c09d493380d9b49c6180801bb52d6497fe9ab692a4afc98124e80d63ddd1313b7b9c31622fa1cfb7f7c413684fe15ee4b33b51e5bafaa6d887fd38c334b65dee3f729211f34b776cc9eff13eff293a1b3055f5ae083a50c667b988b5996a2db63528eb6fdd4083a5d53df26d6bf8a6b5a4b981cc835617d928358c1b3ccc5dc87e3fc46f4050af2fc020fee26b84af757715ab9f63797e48778b245c3aa5d9f6401dff64a475421b0c1bd59f0ec4c39f736cacf0dd9ebe2b170586902addf1493356e9e4646133e8a118975219b672451d9bf480ea3db866f18fe5675eaf70632abf47e11bb16e1e1ab38dde2ba9bc2f8365491c3f82ba6113c44a0c3d00e2c8eff095270409058b43dec29a4838bda04fedc68ef3c3e8e2d176ae5f98278033dca09237a03cf89edb2040b3e66087ca363e1c07046748f5cd515141c481ea4280d172c1d53c56fe813c29fc8a798fe362f6a578a63a0879bb25090a425fd4806698c94af3f0771f923fdb51953753b7a705a49c1c25c38ad203a696d40079274813b5e2168b930fc646c771ec48870521ba5eedabdb0d5ae3e5efa24e86132e0e487bc0bf42721125518a63d08f8bf7f05f4afbd2b939bf74a3ac892aed06d9fff944e2e333f951e99109247aa63265d2652bdc528b569639fd0dc16c03666300bd04873ab72f95e98bd6c9ec60b3f29c2f1bcd986100a70c37421352a4eebcb58cdafc4dbc867438887bae9b03ba8412e7b118e5381707c394cf428047f27a5255dd86bb77adad9fa1b8ec93f845009b58b837a04fed5197ca8d8acf4fec81e61b04a40bbecd67c30a490ebb2c18bba756b307607af3f121e772e5f89a90a138aacc92d613b0c36fc508fc940e7f515e5c0010351c865e954a8bdbc06e7ef209b776f77396e64d01a5eb13fa129377effcd77b14fba76f5c40fd9b9322a8396993df67b491eb462f2c38702ee91fcc18f9bd217fa4c54827a90b949a7d491420d544ca0ff11a22233563527404b8ddf0b04260346fa1042aee73fa1173d77a1d2485029efa6db4a7a79e169a7029c7be5ca51d864cb447c3f9de535e21a45d9703f00c62c0a61aa07ea6ba7a62ca524bb797df74731f6a7adc356a9adb84389a42770d105d7b8987e00ee3116d49dde57eba0b4ca7dc8eddebf3f08909a3e2c41a4f94431d59d15053b27d5d48f0bb531eaf938452562de653eb889ecbeb0920f7c9a8c3e4c3839ab32e54e4cabd7dcbcc922150271539db17845ca82d09064b262066e82b514322c8391693d6c5a90cf63f69a36bcaa995e9fa0896634ad316c9f20a987d72dd9ba90855c313af0bef8db57fd2af833371116617680fa0359eb91d1f4e9978141a83fe4ea4bb7b8c7d5a418b4709376f47b5b2c9e25b89e9d9cc45edf3a8ccd1ccff3e4e7b6f0d7d1e5a80e8d8882f2e726db164add7d9795f47261e0a668f7d83b25803182af4c2fcd68e1f2b142bbb8dc15c07edbe583d5cdcc0f3394934a6d4020bcb3511ae23fe6a6b9de1d1c503014b172f5814ff655f9dec0fc065644ecbfbe879daae4646ef510900fc73101190eb26cc0e563f1b5a204826d84397badfb796f32b70beed7848fe58970dbfc36fd70fd2697efcd069bd92bf9109d0e4aa9419616097e8a4ed00042c7376b3f03da61b61d959bd43b398de469092918c08213fe31e6e95a2cd650abdac660b15a765481a2f2bc57862593518d2a90d628b550ae9c5a3d9047e12cf4d060a888a1266e4e9068feb5a1373c5dc806108acfd476af6b77153a5222e0ce624e06bf56ef1cca69f7fccb3e63c6c288e3c22ab86ae0309ef53490143e96da053b686a0d876ee3d675732be2c2ab87cabb2b089f8b6be38e9705ccc421c4ab153dbf16f3997e3f1b40fddfdee401139155cc3bcde2aa0667c99bdc381415e4e8395f0fa7b3ae0e5a73e35f66c8a327705637698578ed707f3bf1463acb68891a36857ed96cf5f21230b2026324359cc06244bea558d827b80f79eee48ec9aa55bf29ee872986b1320abaf5bf6b36836c7eaba504e8ab6dcb070d6e55616932a69f0aa88825f590ca2310f0306fb7cdf97961048174999c18ef0cbea0216c2944f43cfceb998a9fa2977815b2043aefc4a5565a88b0c41368dc47ab881d2d8ae676738415a73b0efe904964c4ee25ba0addbacb3f41870ef0ab91150d3363bb5f938b60b3a6badee17da834c3a885a32cd8f1cff4fe177065554f41c537f57f8360fe804701fc8ae7b2410bbaafa5bf8a735f263ab5fa9e3f786a188b2e5e187fb33486f98b6dc251ce723ea1b91a3b93d9026102467d98e3c2f144b2bffd60b493d986b84947c4d0b26c02923e40e9177339abfa48aec841cd6e086d5bed7339ad84a6470851fd5cf5ec50b999041092d6daa210e47c746f62d5eb4c00e84c5a92c0a1fc7a488739fe3adbb71473b4557fb4a12fac2e9c33afec4404d3d60efda9b21c307378dae06f8485d7f48591ce6e37bd43b14a44497b08ea071a941c88285abfbf6a2176adfdf36db642312a7422e17d9a9dd995406ef6927d4f8276f0e400209460ef1707f0998562bc1e25ba7696e4c0886e80f5815cb8f1e6e4435f8c4bbe9618f9cd9c5e2ee434f5d81abaed382e5ee08f18c7d491311e51b447305f2f7d0fc178ed8e05ea525a7b311e6287ca879ac17d6d6629dd5244baed1842ef2f92ba4c1121772e83a61f913158eab6dc3f43575ce2ba434e19e9dcb61668a9c0392f03dfc736827ccd0dad0cfbb16746e9d79ffd782c31614be641d970dce41d2238d8bcd06d9c31eaf3ed7798c6bed444361eaa29a24716955fb7d8a46ea5e5dd0d7369d99969d864e99a8bfcdd591e32166f687f163a3b01fb97e1552b4f40a243b0b6275a07cce9edf93e2b380822c63865aa6f1ca8f9eaf3ce0053fcb8a3f201ee750a24536baed662979bbd13c639ef81dad9ade1bfff5b54d89d3f92920e2c29913a4038b16926c9152857fc7ed4c74af5eee07e716a9f1fba3260a17d37d2101e0f777bca6e399f8d34227bebfa76c0b5acfbf0ad5b22c37f1cef28e23eb20bcf213f0ba8bede81b9a855f356152ab72aaac498b74d4c452f58d0b88e20704a4472f0b7f2ba7bec55cf0510cc09cc8111b8b12b87a8af18ebe301fbcaa07e8f1bc2cab769334bdc639b9843161461eac15bc9c80000e32be985108c7b45eebee8acbceff65b52cad542aac52626585b250c95d08292108f7d612c273f34ad0edb0ef3d1047d8cf9ab52d4ea08074776783b84fe29f0c202dbe090af676058bf6bb1d227aea4b7f1c5f08ab64099e5499b2f2d34cb5638104aca898e3915aeaeeab1ed10942751e755cce70605b0d3bcc65db4d5c0cbb25fbf8ed83850a1f3183430ebdea232afd14337fb123a2087ec3d5c2322eb4a195d8d9589d5378a4d787061b10d1bb57abec43e2d9c36c4e7b2405f04dcb629e57021fef2c1a8aa6ab36e779b98711d1fa53185c9842a28e708b2f814c066a88638996f098fb01dcc8687ac77c7897afdfca78e68129dfb458b05c4b174421197d911b71805a5673862f18c33810f4e7fb951ab060eca7d3b1a5f04f4d96cc63b09ddd3de8d6fcf4da5e639df75cec579463464eba92ade5926803a127fc7ae9d4b57cc604ebb350076b81c52a5c6d7257139f26fe04cff832ca5da4d2796e637655f79d9397249f672ea613ff55490bb8ad00e7be51aeb527132d2044eeb60112b48fb8ffdd2baa37061b96734291d71f29057307d3c06149925dfaf4502a42ff277496f835bafd5f98237209924e86f6999897ba32b9b830526b44a7af2b1f61fb00ade519983e93f3eb481e2792943a0da42027ef374e8713e06447bca767b9bc28f37e0700385afa391e61d00d90e2d314349d6f24f12cc26974c4218196cc18623a0d92ffb22f3f86437c182cbbdfae0d38075485a414c0c57ea4b34ec94e42bd6dc4476560672b316b2e618acbcebbeb2694d585d97685d0cbb3afdd1130d137de6b36c9992013064bb205b62f7ab521f0fff25c11b5fc380ea82ad9aa499dd37aa03053acfff8e266402756d8c07d36d5bc4775acebc197d301bed7d87fd09db7a96cbcc3baf8ea9f8908b7c6c69d9663c4894b562337d48e502609d9dc3709aa44cb3b09b81f735fc511d48c7230282ac2c9ba7cc6d6afe03ff02495f8fcd18f0e02ca99c789c99651da7262128332eb514637621af85a187c8fa219fcf4881a6d2dba360a0e22ea46011e2e254fe37f2efd87ea010524de715777218c91e9faa354fbf5250b73bef97365818e11a632aea1c29b98a30b7855be26f4392e540756810be7960cb7a3de41e7f03a03e57ff62216445899bb86f99bb3248b60de1dd9ed520fabc7db68c838c4ce8b34508bb0ad4351bb967e8c10777b2f290e536672b808e00563423e8b882a400b5feae1a0c1548447632d9ce45cfc69211143164f8264e1c0a985f121a272c3b2825a109373b7a27fa8e8172f1272f464d415b2c64100860c37102d2f9e75bda0f829d37be540950873dd05cfb9d20c91e9af38d7d489bd156220f7bb44323ac54229cda7c79ef133e27649f17854afe475bcd73b44b166de455cec19f3e50d8c32e4eacdd9d10d80756393144d8b04251769317a9eef49b0af63d9913daefa9b182b58886d1319d8ae6e0ad39e1d6d7c09e062c9bba257062b85655056b347f5fc5951db25767a05d14ab3180d4fe67f99d6fa566ffd99783b8cc48a95e77f71f21693ceb11b53e660d6d7bae6beef1418269613bd4005887b2a689fea9d0b8aed26a702794055a7155f6b384c93c9933e173719c6b4423f4f439cccb7e8151d5f17cfadfd8907f44fcc5ede6da12eadce5c4e71e7d62db34c5015734f7398c5486610fd2f513ab53cab2c2bfb5ffed441519daa946fbcc61d957f3d907b8c172d60667e9390a859560d302361046496c7bcd9d85effc160e1d5439260d0c2e521c721ade0bdcbc850dc5ab28a9df843ddbe62eefff6f3a9918e709b5103c77495118741df05cf2b51bddfe719d4838c526a254f5ca6b7ba9a0cc094b508a56ff0d63543b9ccc54049af61367d75a25ce6709f6b1c03bcfd7d47b7a330cf29d2f9ce8efc01d4813fcc3776ccc0f15743b0043c5d52261510cac6690e5e6ba5301745ce20fb83aa2da52ba309cf8b1cf8f0cef3331ac734207318d99cab8233eda7083cbe2ac0f8ca7f6499da3b36ee4fb61ee55a4c79d8660639e45dcb37eee87473d923e95237a5096f36bbbf8573444987533733537d578d474be1e2712e51d8e03e51e3479cf14799ba6ceda11c139855ec41f1406398dccfb7ecabf09e176e24c44a024cd6073182ac1f58cfb23bf6aadc375278f695709cc5e1d059dbf9cf5701aaefe8b43e5ef81b58090aa4ae41d7ac76905f6d504cbb3b8f66a6b9b74eb34de83431f7a03a9a0658627b07ba1dfd3f22f5af9fbf1c6d41d6b3bdfe6574cef264fe88085a80d9f2b011110c92486b81b3f6008d904708b98a061494c57476837ebb0f5f9445ee14585b6fd7e8245a06b4763345dcf0289b2bfbd8bd90a6e5faf749a7d5b96158028791542a38d06112f2facb7b894fad214868fc5abf2b960a6ad8371b2dbc41c52b16e50e89f22a25deccea1b28b334866bf4afc7c50ded23fb8029d9d988bce010f2cd487c2921683704e7127b0dffe8daf8021462a0068d4b42ca50c5cb96ac80ae73191c7af7af0bd228acd8dbb0b50066ca9af2b0c3fbe576fe956f8f37e498770ecb29e859f5c7c0b97e5ab51f671e80db0815aa3b74434fc7b716017aaf4e43533cf5c7d042bc3b5e4aade7df0a51e0f027c80bbefd2f5826d40d7e94ca8283ee492f9fa04b7a25a483c44b3ae79f9216b8a5607ae9f05e1fe39b95f589114942c176589d56b2d608275d0588c09f01b12e298907415370a6a907caf5a8d0f9e7eab5bebf3b63868b0d3e9631ecdc33aae40854ec63a2d77cd0093a0409bc68fa5b817d308fe2d01c76617563ea0631bb5252e875b4f870cf486304875b5248e18108eff0e9aacfa5a8fd8ac65fb25bd3b8171c7e348e095c9ff9d4aee7d57ef886c88bebcda35823d5df6d710fbdc7ded368234c98f08398ae117036cbda8441ab85e54766395b485480e552aed66d8b1eea979d420206c5342ed809f331f9aa750c8b69748ad7093eecfa7d1293ebf2eeeea810b6b41cb910635ed7ef69d7e8573c31e5bbf1261759aee31fc75eef1d91ad8cca33234ca51c2422cda19a88ceed475c31e8b7177bd45adf82b12d66f017d9f6438477989809f9b1a6005715170baf82bd82f4af747bb2d92ea1bfe874334b837e4fa503ea999df417aecc023cf44b002611d0fe34f526384aff6af39690f88707206e93a2b2d4d67cecca282dc1a1770ddd4ba03587cef40a9c6456e001b329b48c2b5ef9c139cfcd8d80024bc43582ee4b29cc5c7bcf62b4a34b0b2fbc191ac8a53e9ea1c4aa57bbfbfc5ca202857805fb6d7d89504a8e192279bbd4b3ac2a9ec2cff0c598d32f892aefe3d5c1de7dced020e0892297f947833b0821477a46e6a2019bb8c1316bf6543dad419babc2dc9066c580f3c5cf41aa0747419d410ee3acebaa3467118561cc1a20e50e468aa112a7177d68d47685f58d19115c509228c1c3a65c44fcee6a7fc83c6ab99d7656c952c2c0d9e5a2685734f1a3501703b66cc39600bec017edc40d26fd8696b72b751b1bfea966dcb4d075166e7386e76ba78ea39829be87647ed4e533e37701c5f6846694ee4d6a81350d8d2e67e8639b405bfe3a1d9c4ced6c8db7e86f2961b032c2b663557d5127228c69ce0a5cf77b6948857004263d510803f418c501acd83f1569e5c20ec55eaff2a364a62fc14c1243a78c49e7eb1a571883d584a2cb26a4341a292cb908ed5142d6d7c969ccaa7871f29aa739f7906657b076642493f6ebcd4bdc7501211861014539cd9173cf2a80a9a30b04c297810a701430538b0d4aa4594ef98c62ff89d43b1eac325e2bc4b0988548b0a4826c22445cded4cc6a5335da96f3c339800d3fcbbc0859f4f035d13438d5dc693145f4360c1f0f91801bc1b10da717fa42a41725f13380b6d20a349c4d33c1425d08864e2b99df50257005727dae94ac4f6a8f0f966351fc5b7d47d081e362440a1f8dd461cc73a2d1f342a6084bdd2542302efa964411d1116202ae4e0cc50e290e5cea8d87aa07b494d1cf8314fdf4d5db680676f06bce77739e77011774c510149c6fbfa38a8c52063cd446572b8ec4dc8f71a5386e08a55f53b0ab523a4847abc7e43086b5bdfe50042d10631842b1fa63db9a53a217e40aa27d84bc9f641a2efc138d6779e5210cbe477dd5b34b033a804be78b96125af980608df69393cbd83f722b20f2b2fa462f0d6f4252c3e451892be8d02cc1c0825d5b442199a4bfc22f262e2a1904aeb8631c7f794d939de6a3571c92ba91daf8290495ad0b24f529907b5cbb56adfeee47e35008d4f0c10df2608d1fa679a688df6ff1be7cd6633e7e0449745ecd513bd2778355f0eea6b75f4000a3b7a087fc950eca10e39e7bc6e89bcb2ad831430da37a1ec6fab6227c1a01ba8aa83530d201fa7216b04cd962b1b21a82bb47a7e31a363b34715b6b3b3ff23f6c6620be3460ab2fd2e093b05141091393312367c704a0bf1543eef068b6e9f38991dac66f1fd4da50387b099e4136b296c08c225d14af62c0fc084a48100b9938c5cff0472de42f3808866175b343ea19fdfaf32913cf6ad715f09c26368efed9b50342034108d86aef25b4ded8a18b8b4c8f56684a0fe1d3afe04e0956158b31b0a3420c22e2d48589f8a398398933f1aefa06e4f2fcd68fc60d5f426495c9b45f225747e1325d451d2d00587ad226b525e2105d4d67da17ec2f869e206a7ac6a34d6b777dab3d9b57f932af5c9f1c07b46d14dd1c7c9aea280082bb97c6912c49e634d75ebe6df6c13e9ea525ddc986f35439ec088930209308b213741b842bec6770403d8b15b96550e72429a2b2b48d73b2ab273f7146139de8b5c9326172f3ae5f58d5f6d197099a4738338c6007d707068be32876b07c684ab643c9b850d7cd321c13fe6535ad3f5bb0771cf9d8e9040d97b3c7130bfb6b74b658a1169b9e5686b652b29df367a8996e4b330160a1f6884209ffef3cb4bfd267c3a9f8986eb67293b59ae2c6e9f0e65791c662e8e8f6287cd47bdf8e9a868cc5683fe34eda17ae970fb09e56a22302de1daea74e3905136069136b1116c58011365bf18e5b7cc2723579c4a88ab19b7a1fe6049086726dcf4976cd44ea56babba182b93cf54db46167e1af13aaf9f4637fc5660284eca8cd3965f2b866d7824669f3c8d395b8f6cab85bdf61435c8df41b1f49dcb03c00f985768b7f6a7c97eec6ab31fc3c487de95b806a72ebe0b760cf306ead0a6374af57e2604f492ca3408f331c5f4557bebb57f886c07fedef9c32ff0724c38b51a6a796ed446e03f6ddbdd4b248e39925d8c52e1e40addea755803fa0b32b03f26a786863c569faf5fa399c648bbe94761230d38cdce923202df658bcda5342300d8c485a3e2878496fa64b5c60da3426ecf44ef74346b4a2109a30020fca529ebca031d1ff1c37c6e96d245067aaba18822215b9b14e07cfb613a6810fd7256ac926318d5c20e317816cc191f25db9930b03e301e86e052f108f7d6050f9f5436e03759072c4f66c47fbd7f99d8a16cade5b2586dbc6fd9cca63cfa6f01c35431fab1e07da99abb7c8ea81f1f3b7b61168eb55410c193059635997a289b95bc4f055cb48e3422786be082d3fe81ddd8c7724f509f265f88e8dc5735912f1f633256d168ae8348809ddad7c0893c244c41f9f83bc2c2bd9916a47a2ad0e0452694c01f1bd5535521cdff8756d70902cd34fb74ad0bff2a0a4be8a9ab9d0ffaccd31bbe7ebaafed0628592f5c4b268697719662b1780917d5446eba299e94e031b8e6bf5796eebf13515e5a34d1ce916a8e1c1692288f515b5239b64cf038d3e72fc20c68b4a3317b70120638d11e17e44c98578b596780ded9e13d3456329ce22cc4a5966a581347f3cb19f9d49b781caa25970a591cd04b23ae6e62d3afe692e6b29f46f12de0cc5aaa1a32e34b4633ca53587b362fa0209093f36fbe683a46464ba794ed9e03747f46aed2771a5c407f7595c3f6839fc77138e68cb32b649d5f8a603442430fa09e9d9abbb31aba1c9024a64c8c6682d3e4f150a5f4b9d877873a1984235d1271304b3baa775c4cdd6d8c0a1e579170fc5ea99ed4ffaf86a325932fcefc5ecda2b5773384b9c67bfbd7511a21290143adaa7c7d735295e680a9b113ab64e9bd15ae72769e947732a58e33479f2b184b9bed85cf766abbac27ae8a5724c641ed23ebe9b2a718cb0d1c3e23085a1ae90e9a497904cd1750ed6d5475f3c1266bff776b89b4ecb4423ebcd3512c246d209ef51994fd6e040f29639f784c2238f1d05ad5612be0bbc2285e70b44fa2b04ca409f1c221a8d07b8852817d0f21327f39bb0114d728ba005a4e8122cfc20f03836c0f41f5f8b4bb34f06ecdfc16281ebe99d9f3e34b8f744f8e7f68f36940f45e9a1b9b68d8b17048e3065882886a666301828fd9588a27719cbcdd07188524a30ccc1c8f9ec4a1def30b4bf9ceecece9e9ab3a7ce39ddbeb697f4e4e2ab8ac7d9fb149d7cd02752ac2ee2484412b0493a6fbbf434d314eb996fb58ff008ace1833cfc5b8834d899125c79f66253801d5d91bce8ab1515aaa52e3807011437b51eb8b14053e2baf4916e9fb675a810f414dd113a3029ffe153c83cfbb41af60b43949312cd97e77d2dbcba3c7f278ef916ba71ed3f041c113584654b357e79dd7e48be195620a30fd59916932129bce4ee71566f033452395ca6f74cea2d674d7756677a9a1db9fc9c91d06bfc3406ad56699454b46b8a8a4d43c850fc32b7b83853e0b01457faa4ab700bccc90415ed67e92244e43172fd7e1f0a8dc6d5425a2cf61a8ab1ec210c16566de4def8a5341c4744d386fd7676cba7a8b614cccf35d709758169dfc7c8d4f363e696c742c3b4b949b09c8239b2074c0209c27f1ccf57a246ffa3255b91313b9b0951863973434c43d03b71c25762e5a2b05074d74cbd85b40f5c783a034ca2f7c1e3e2ef116404b439166acf6714de2a947784142418f1e1e60459275dc93d785166cdad6d1d688774e9dfa59e0bc3095eedddf8abefb727524db25916a283dc10bcf1ab99c7c564086a34778ea1bd3e09d3c5e2e8cf02d3fc1e335ec3b78412d31bed7267b61ba0641fae39a0ccc697e1cb95a3d5225e6f7e9cb22922662d53775718d824bda63478a9d593e28ddfda63d2979248ecf18ee86b047f4b92a863eef48a8172802e3dacb7ccd2dd0f5ad6776435c1833e0c2e1eff78412316c3c2e92b8bc5bbc56d6d70a2add1475588eaa47e1a15863abb8f07b5c8bbe6f0e5652ed55b45be566533972e286eb3fb5cb64ad108f417d7183f19ec4e118343c57540f59ec712c44ef56102b233eb5546b9ec1a8e9eea1f26b5dbbc4afac5c0d8106eee4842f05d7653e147a9be7c7810c2b0a6238f1f4ba61127ddc523ebd68e01541b761ebaae6b3753cefa35f7ffe9fdd8582a91886a23e3cfc42b560befecc5c07e259698a1d8f015d2472b527290aaf51363c014fd756b18c616d163c9786bbe373d9e07e9c409f618eba278966a09f3949f9772c254255c297931aed9a265c692d20e32fd8198515559d7b11749630492f3a90cad732f4e6ab19d220cfea10ba1f374fd9d5f6d532ce62d7cada32c99d9808f8fa6697f3a94c264793122ffa03feaad79f379ac35924209cb4fc1200bca2d6553bd9a92d0d077e2ad1cf340e53ef5c83bbaa8c36d9a2e09e70258fc26a7c0b905354f12ab2c51f38bbf1c40c65e2ed22b8778ed52d164b4c4e48a02234ca1a43f65a6f25a55d5b1b42952706f9eb5a2dc79405cb456ad57f530d03ebaa7cf15859a01ba1cec9eff7029c5af310bd319bb6e22204f8515aa592fce3eebbfa92931fd3ab258c0bc18346f06d9d0a56195c61b7f5a58dd5378286bb7e2c4ce32c9409cdb8c214a3fa94612f371c012c5e83e3cfc065f87e03a27ec00f4435b5de8f865bc274a302ec6a808473b0b303466ae36bae92071f9343299bb06006666dd716b39cb28a06816da8344f93fd0ffb19039e30a053ea80cdc78a881730ae50d1049252e75bcbb0b5e72c532bde2725be61b47eab76b1231afe90da477974c2ecc6e0f80a38263d2b47f15ec8de44357496c9cce4b7dfacf729432d2ff712d95416574161c67ec8926a7af9c23c20e9e0ffc2c908fd120d6dc5da1622118cd98e49b0ed330088408028369a67e5cd9a40c055e342cb83410f15b074cea11928d1b963dbc1f2689ac9f74fa4d27a5cc4273cb130a86c66c76bb29c68aa5ce4761b8b3ece012e598c8f95f06266f65067db96a8d7a1ff8aac507ec9c28af3affedd3d033d61aa3af1221a664bc385dde601890bc1c359bc8c6b9fa0e3489de084cf67ca52af0215349dcbb810284f8b363b8115df6277922f1d1dcd1aa7de365bcda4e73ed5ea6b9066a98e2f3372afbfebf21b11ac98daa04f66f67e65feed614d4fad3aeb376a2fba2cd7517b71e8139ff5d550c588cb0ced6927bb18814e2d031739447218d03ad1ed8ea720fbedd968dedf50d65ff36c33a4dbb42f97615c585f537ed992a4d9f9ddcf236177357db565434d679298cb8b72dec3b1db2a43518d80fbb41b43d85880638555d664f4625b843a44b303f29660283e62a2f720438810b12eed5793e2d144d1e873c44c03dec5a99d564ac3d6a44869ae9d9775d786b4273d97459848913dfeecfae2e23cefcfa47a400ac27e6914135b4f2bbeff8e83fdb47425b8a5372733647a1d50905c5816559414bbf11a282ed793b3dc12aea60c102001c92a7b5be33ce2fc41bf0561926fcd6987f218592045ac0426316be2b44937e7c309197e01d19780d39a02c3b010caef6f26f5d01e0a54cbe3b61d24f16bf66358eff925ed848810b807b322e0ff31037fe5163919a687d3e1d7559d66108ca4e7e5d810a07222ec293538f832d43c926ad09e7f281f71289809849f34857e07e127e20c55d0071ba82c13f1d7e3530cacb505780e25c9f7d823fb19de0b116a245ffec4d34ea99e704bfde488d92f942dd738f2cbd3f5e384e032c9eea8a3cd235cf1712ab98e3c20ee2645bfbf5b0316c1bcdae9ead022b64481d64ce37a1bbf9c90b49c9bc6cb55c07ce51df1764c7e03184ab524012d136ce289a6fb8a15c48113b314ef6dfe32c76050517326246a74b080038e8d3941f0b5cd6782da7fb4e86dda204a62f49da9942ca19d703c483bf825ada5af1de7a82e8351589b3748771f9ed48e34aeed42eed22186c91eef6598df00ca9844a2c7041c6ebe9bc63eb1a91b6a49700cd545fe701362e6750e4d755f656b557b9e8a4d8bf1f019032a5a6226830b98485c1f0fd1329b9cf7ccbe3c6620f4ac2c5dfea9b5b89c704ea4130a8431f4bd6fa02cc1be30fe0609479223ee9fda764d759f2b093075bd977b0a2e4f7fbc2cf1767eaf5f23303a15113d3c501e4197efbb404319be08ce0e030eee54e33e59fe78d5076901a37bd46dc54ed329cf2e0c2af67ea99fb95b653c0f1e150c081773ca0c8d99f8f0c49b6ef6ed538d5210b13ec2a3bd85174ce90bd3addf0f0ecbb5c1a9a53547971c5179a03a10e34d297068a9cba538c27a8a022070b985dd84b94d6a1874547389e4fd31d93e57c4ae6b31152897802a5b9883d9c4415064e89737b56e33d70627f6f15996c5ce7494caf4a55c014468eec9f84294b731ff9c38daf38dbc85995a4894d2405575fe2de7091a09dded8b5b43c1c7cb716a81317fd71a1743c502c6b84decaadf21fdbbdc668c2b6454704d025aeb9c3398dfc156c5006950af70e963d541c6508b46cfc95f8e02c957378e82bb1be9c7e525d1501c4f0ef2c0371507869111a5b4782bb86dfbaccb76c78a533e7bc33e1a06e01b717fbd4feae95b7aaa5747e83ecec56e643572d886afe7ac6c07ef11929492da28c7313d337ce8d5d294886fdc8da4572e5047c44f0095f85dfe548c313f56c9b43484ebd5c9452fc57fb943af3f1893aa5574f9bdec0e686ea2359f37343913eefa3cd921f36576902980edbf71cff0856c01565220c7468015c85fe107d95834c36080d67d3f79c18ad9be238687ee3a2b665e7706b62660f7dd4f735779f81c72343bd755e8cdbeaa30fee1c31af79118b2579206fa2201b4776df802340062432e929ad4624648b05aa8bba638b1155f9edecc108d65646b153c1299e48c4f0898fca9d096502f07599ed198d079ef2a1f5769cf900c29c74261fce73b2bedfa1033beba9a4be9d2a1207ee0ae1dfbb0e0ee5cf5846b4acb583ca052876749761fc1b9d5e8e50c227703f1c24b3423dd0b8d952de9d6cfbc9732b155433bc3224ee5d5bb216a501ba10d6b35eef3c53c92aa5fa842ca0656cbe3cfdb706221e13df1d50dace07ca92540b539b9150ec59f64b0d094314f0400e3ffd83b36ef7057bf1d4f463cfea5bedeb2939f27df42197ab868c9b20c2281f273dd63d0e84dc948cb187e16c45a65b0fb5948da3bc519de12bb27b8bd1569ce1dda65ff9f2f493178f0296d11ca87fd651ea0956b43a04f9b6baedaa0e890ae84ec4794ba7113b0be9a7de46271088378254ea173063543ab891e7890db9c9a95cae5a2082cd22b0ec74059e0eab25ffbced3ecf5d3843f1db6b326bf77baf4dc3d982db339c5fc8b0fe689444a2eecb55c3dc6b3e0a6e81fb77c7850bfad8a838106b6ebcffe61f170c06956253e096e62ad7287951e5903b475b0849a89c31c0148a08455d5e156ea9705cea36e76f496613a3d05019bf41d83ac0dee90607584385e9812a74ae3490251a7c563b8a1f0afea8e0a55f33530dbf245c61ca8b5b79f08483f019d0ce62b3c9179ade5ed699112e5810a5444bd2e8a780db7ae0005e78c46fea3caa73810294d2d52d1b7a2f8b019227480e0b1bd89adfd5378bde1ecf9119d56ded4ad3416a6b0bbfb813708ce98c5e769b715686dffc4c1687f756f37b2edbd95c8f30f895ac951bbc141db005832a5c44cc7483127370d4d25c91d8727a6f33c7c71ff3472f4ed11235ebc1c43b84f682bfa08114867d49930fe9b04179c25c2bd47db25726612ec8e44d67d0c7f9922d1bbe21cef6eb2b137802b6601be77e4735f308541440cbb66d5016632b72ff1f5885efff556d3fb461fc600ffe037f4b4ffae3da2248645cbe1fffe323de6e32f4a096435924e833dfb4760ee711c6d40174067cddd5ffe921359743785f8065dada7cec548172865d7674e807b13d733ce90f5bdea5f2173b64a10706c1bc2f73118648a0b2a6da692d3c74836030041f2ea4a3ae0acb9f85968ee885656e1af41e5dfacba30093d39b10e6fd09a2b087b5d1087b4ef26c1376d2b85f98f15a77460f579cd5bc6540724ac2710abc8176f9bc0ac6ff6ec90998fa2e7ae445a24a8c37c2b5b45b35ddd98d6a886a6c373b8e6a54d28bd4965c56dcd7072a8d15be92b0a79729edc6f9dfb6e599e44e0c4915cc5867b3c7605837199e307da175a9795c6813d0d04ba34f29e5f8d10cd410fe60e255dac298f7ac5d50f356f44f77963a45c7488505c19bec4ff16863be1de19c6ddbeae9caf02491c099ba90419e6836f812e49eb9a13dcd8feb43aed62fdefc3d5d6e939b258b00041ba0fc26e3f17c153ecb58b135c2ad6d02d4d177dc06baf50483560267edfc4c40bf5b4fc4fed6aef910a5ae719a26683895dca1983e92ba0fa48cd2767fe4066cd5ec0bb4f1a400142ee1b3ca9a4cadf7a0ffff5eeeecdf25fe59ddb41c045cf73fe64f9d8b129f3044693c7288547ad3de0bcc27045ebfdd9dfd9aa63e57df278d53608f05f3ed4051faf1fe9d8313bdc909cd356821b75c4db091fbdca7024f74f6c1664f1f241f0477b35e5052a1a10dd2fa90f79b22a1d0b93b8ade6a63c77d579ffd0e09c15088a8075296ad51ae5cb51ecefd1d83e2b75c7ab6813db1a9f8058886bfb7266c9fbeb753f765082df60ed0b17ae6eb2c49b5d4fef742b2ded5620f82af66626d791df3b0bbcd9db3106d13a6fe001764e99655b694251e2274a57545d9287791a441f202315841617781e733224dc8fbf74923af0ce5aa0aeac1f7b2e7ac200a9e5a24b9d97ce889f35157a8d8fe9c064f2d0ebca6ddfb5155ef0cb042f18b0c840bfb0869a5299bd0082196d7dd0d59862ad3ae40faaf932e7e15c2355329e39e87938d0f502e30dcd394ea774e9107bf9f598d456658ecd209f5bdc5e3f653be2fee7fa3efa23a091c58a2392a053f39019261b2f038768278bcce4bf54883524d9ed775cb50fdc6a4afc82845b0a576b7a42d853fdb69aa2e5756ce9c57006234612fdc0ae5f29c35c5a1f528c4edfd62d0044ff7c6c30f457c77d4326094896de4c153e9c0a27114e3a773d425952d319a5c84f50be8fe3a823682197b22b0ccf9baf743545e46e2873470c2406b2b6606ba28726f98eac420f980b9623296149ef6401cc3220a5bf6a1b0bcfad3449a5987bad56312f64c484f247d12fda6a72e00be90e5a34803f4365a53d1d4bcc5c55ada765f82d59c8bba0e09729b28d60c2e57a14a0de999764404cc5dfc1cb2ba3f4411b54368782eac1927f5d5dde3ad674fd666c453b97a76c09806c1870b3406baeb0b6d5a4ed6e34f3a95ed69b93907970feeb1a9b58200ead013502e3180c8ebb24c21d6bcbd0775781082756acc35365bbbf17af65d8a717f7821532209db874e85f8322ebf01a74b798706560703f5b2b37edf43a67ac4d510f1188733656c3b211325c42783937e7f0507cc98521a76088b621d01c31fc5f1ae3d8be0e6a16fd9c6637154fb099d264a68960d9e34b6fcafeaff474b6691675c5060909fb5f625a248d33eb35bf7edc72bea2080c70f4004e66dbeec45bee6c01cf95f813cb9b8eeb91e7562ad7d53b1b8caaa9a8aae94cd18903430fab9df066056c0d4cacca11498ed4cab478c2d6bf999921d2251dcbf1f523f185bb86ca1002ba37b64de5464765e7dcb79a700f79f3cd75542cd9eb942789f260b40ca872f8f294997ad12bb01c1cbed55532f176157948729455c96239d6b5350f6149a3f1d7e6fd7fffed36400efc4c32cfb5eb53edfb9c6c0a9f146cb1521f520f08e5b96b6acf9f624782658be2bec7c2a26c7e0c7dac22c53bf532f649019ee870e24ceb78ecdc8873821cce98da0aabf423b3dc4408b7dabda2bb6c0286dcb6d8efc111ade62eeab90380e1f9f9ac03db2fac0208c2bb6dbaefcedfb5c50eed77568e7e7acffbc2c332608805e31f4ba9d3166e6ec4e64100d1341256e35dd18aeb83e73405e00190d53292fb5be179738027be8979fe1da2818a8d4f96406fd4d905d7c6502b5dde390923b0f6a682bd1ad33add7f49ba7ee087ce16db7bded565f95bcb7b7d715d7f4bc72028d098e832250b4631b78f4055a37ec2057823c5a3fd7a38a535e148f13a1d336da09697e6af1410a4a2606264fcdbae6cc748ca6bc89190c12a7d410909cd8c201c205c244e81f7e1126c6e1f140fbceefa720ed4847fdf18843055251ccfa22f8344887eb036a170dfc5e70395196481c4f2d0c57c7c3537d9a2ed32405d34edb92937335733de3454ced0835964004004a3f6ec93a57f22a5483a7327cf9ba5c147736a2a059760da4fd5786bfebbebc7303b389ead6904364f523affb90bb7d787a2d5f4b43430fe7f149ebe1991f9f9ac53e18afc5b955f0e021bc1338e849c0de9b7bda2a63ee6fe5510c4a69dc1b88403c1a15900d474c89553020f020a3be2e9727ffb1c645e0d708d82ca6097246d1dcd0ecd705ba755708737311bf3ced69ca805bcf8c658c228a3667a799516882c6f09768393d43e911de1fd4b934c3fdbaef809e46deb7b43b572222abf64293e0b387705ac39907a3246997739b5fff7e18fa58e001cca65d279b9dc76b20daf40c27f7735a147d323e3f841d890602bbae124b48f07f8a26989305cc09f125fba1357a9dbebe2de48d92f68bea59c5321423aa342da1fecafa77ae68bca3f0b99960922fec46850b44f282ff75b4bd2afe4c1da517d7fcebc8d61a8b5cc6c3f38a93ea39f28bb3532e4be7a8ceea325a268435464cdb6f9fc36e7a277c5b9a619e92b3b2e13353e25b12357275db463587a936a16aad58ce62da401b3e78a68c074725312c1e77edb921c6a73b01d37318ac6ef8634aed2e869a6f4912e2ac4c475a9cb6eac935f7d0820ecac9344fc9534616ff8bc1d78cd401b40e9e1ade99c20b49fedb1145659f3ee99d4f56d990717fda16473b3b02438ec1cedac9e873d97d3934d3571ae034ed1a4a04c7d965c8dec34532d6e2c92afd20d8b80cc5678d239b561b2a1822005f3920f84aa83c3225035966199232f2bfd92bf43f36d15d038c0b09c9a51fa4982c2060615f50c00b576aa2cbeea2ddf7f8ca0862e2352ea7f8884c11be06270515fbfd8a62c27fb3c64281118f18362f33e13eb6507cab7f0a7d5ded0c42c5ef5ecddc8fa746a823479b7a14ee86a2ff481f31bbb0b4d5da3e992aba9d7eae56d511c0a3113a3f39e199dbc0fd5789a4c1aed256280ea8299c517e043e95e29ddc00545024f3ab4c10c5917d571266549605dff5fc5be042bb6e0c017ee2bbdba6574ec379db3dad2e8712cfaaf575cac43174c185cc028662e68fed47d30374df08a4e99a643759739d2e6fa5d4a1ebaadfa89921f6d6d7e3345632c9acd22036f4446f7d6b6f487881210e51671e601f92674694c6b32ef0e4caa639311914673915164cdc446046437471a0b56fc860b979b6ff8261b0a363b14246011ff4390ad9045296573790eb5f43aef252cfe95b5a31a1019e68117526b8b7658d5b6e17558cee120f8700e9ac5ba36f2a0d8645dc264010c3b8a33d9340c53678b6069cd4999c81b8c53f8ad280c5b28ba33bed153401d6812949f6479b2d711561f59b64abfe741da366522f7d29b8859fefe1313790a752f7c501d33d3360adb3e46131df2ad9320f5e4754fb8bd4e913cec040c70dd221592e771b9f47e9901bc3e12f77fa8a0128b67e9fcad1ab9f1e71aa924abbb12e85a0fe41e2a0f7e19d6b9eeb5d708c375052a1df16c73ed0e2e0f7fd84834a6964c5835d17addc03f7a3abf5d68e3e2a0f0db6b2c4bbe74251b1c7c97f31a6a8190521f00ec6cf830b51a038498571635e4024141d8264e7c7f1d402f483c0f8fbdbe8c638c9c7d0e7b158881330ecf340395d3bb7eb4a5906c19b533dfad61a9c3378e68424268ee4abb2abb2c0d08dde3cf4b471a9822c431ba0eee168f9a5165b0540b813d7d46c5d99bcd7b628a756b2807b15c4c5b299383194781cba81e34ec18300427af4f46eabf49bd86e888ddcc91191ae3f33f81761fe734b2818afef82010372581ac8b13a3a8c2313f5ff6f9dcfc0b52103a1fa57ee7bf13b2415bf3b0b0d42281378148e387e688a97616b78e3fbf0867ea84a497370b54289b68c4d6b1d197f2f9c6fe76fcc54df5a81d9eb7a21d40603a598f0fabe659b63b40dc74d45a6d029332dc3211aae06dad2c4be3f7404048a4762d30be2b4137a258c6161a8f2bfd29a158346c648631d5894d58d2f8efaa8e07e7d00a968c027ec40b6b7fd1c2f1b1417aeb4df8ad4dba817f68098fde666b3bec38d61ed4b74c26ed335f7f68cf36be6cbb998f10f5d195837d7d91fd71b9825f5de96ad0b940d6bf9a98b46d08cdb00596d3dd4f17518de2c8171b972002acc4d639b39280cbfb559a632b5074476e28797174a1349abc5bef9a4404039180323747e89a8da4de2b1ec74df9b2a06366e17947c0d966bdd2c70a9715cff0690329645f269294fcdc831e4bf2379791b068b4546365cf0acd699b1b5eb7e51c1a10ee72bd493ac5d05aa9759af9e781947f98db7906dad373137358de4785d546fb4c95e3e68168da8f0c440ad2aa860c0527a8f3869b9df0f04ae9e88994d9313f58a221a60c4886d73e70d9bee39d6ea709055e12ce023b15cc81ee1b4560baad8dbc5377d9edefcc7ca46e1759695ce54974cb184bcb0fa669d0034e44e004b87300674b02fb645cdcd227499ba8a48e3e44becb24c626e80670fb54822f89caaad1c5e43117d9851550dde41867f069c6f937a24ba99ada3367dc54d4ef1c2d183d63291a90a78cd92c87d9f19d3ae6e1dfafd69cb07d4728da9e34bbfdc9a389babb0d6f157f6d0dfa7b9ed73ca00d28ed378304c9b366f4c866539a5b84acab9de71e167cf7dbbfb8d9a068ed32b60c47909b6e2b45ea971a9e5a1ac74c2b33941def6eea2484f085db24dc46d24d6065bd69def908ba87c3dc13967fc1f5de7390f4c35b81727272df5f9c6d6d421817c08fd98e93981ee5532d3e8b7bf2571e8d14616c4415cbeeb2b58e85649a611a019a54928fd778bdc6309109fa9e29a6a4d56fefcc73aa27c7e5232bf79842b0f59667081dc88c2849c8cbeb8e33a02b43eacb40fe19265ae11afa5037aab9a9362737d8452a1b53f3a81d7ccdbf4629bf95f5f945919962ad3677b7a8486d28caea667989b05044b887374f71a80dd1878ee910d6c52649b40b237affa2f3a9dde64b1b4160b1d5e6525a916e0a8005ec7d16e7c4cefe47fe79f4b694acec9a0fa512dc487f5b2fc71626f12d65cd4b2ed6bfec8b9e9cf95e372dde18e725524948d452018fe9812114bef446d419b9e5a9a7ae7fd687a4d75d37fd2b9436cdfacc9cd2d53549a8eeeae0b4ce3b4f1beaf3fe9fd5e7e8897464373267ce811167e6d9f6971e68a2353da8b622ecbcd37d7ae242f0c6c1585862cef39d1cd77b53dc7f34e4b4e57f52c239161607fd2c29628adbaef6426b1149a4aa75bb05a212803bb2aed21c0426395ba5697296c93f8f0dc24554d081b8c4ba28f3f0ec0d70f3cd67f3c183358082efbc632c13228ca62c68d50919755c4f57138f763bfe5565a1a1f4a7973c12bf0575942f15d240b3848c3b66cbba81537937eccb57e63d93d0a0bc228d427649db5e1f810fb38d82522cf87992243ca9aaae9c1c7b1a8154efa0d8117944018abfada4b70f053b98fc0bb75caf4b44161304213ad0ed6dc6b5dfb6f6afde9bd7ffa67ca475546737abf8ce31951880029a58581d40294cef9a8bfc2226180dc0bc218bf7ccb788d67b48836d250e6cba6fff491683d28bfbe5edef375c6fc89008e822668455a2777e9dd20fef8fa36ce818968c0e0e7d607e518cf6f330e61dfdfc3414fdc1afa0cb6e0d68d001cd32e989798e5ac2a6d277f9513ae4d52de7a484ec0b348736a4b15bdb288785ac644327960cd35b61b5b5e313fde177e5d74ac115e595e70a45d0bf18be4c3425dac8714c4e9d0e37e4ed301b2cd5e712ef071d6c2344bcc1531a227e342fd460b4088ced235c791862ea85eac8681072400e6076f7ea732e8d8d340275a96e1501de550847ac044e31ed0bfc8be10570a398e9c9adf07bbcf410b88440c17a4dfa18f3fdb48b0bd6c56d2e56be1758ab71ae1a72673e27b462da933c72151d2eb7e4848ef09483fa3a0163fb0b314c43679cba5f378f0e6fc56f64057823b6eced46b4ec56ec170131e1607b20d4500182ba68aeccd2cc9630bcdea660f6bc729e1244f48597f715d5f72e6f900c249de056856b78f1c89c74bc3408e11f4d5e42519e6b7b4ad3fc7abe1ee811ecbd0cee038e8cfb8296a188a410fb0baa73a40f614422e20291cc0a1e6ba61f6baf2707080df4f79966bdcb3b555f488fb58e294df376a240137c4bd7d8853d0b932c9fbac23df38f2be99a17b351f9bcc0c8961cb10fedf95890bba9db27304a9aeae383c71880ed2d5429d67cd7013480dd4ba81de5fcffcbd143b758b8948d9920a3d4e6e4d70f6b43458ec5c0994925a1073c8a49cdc07829597562593994e737d1ac61df02d678ec8ea899c94b58c6bc90b4d7ed0b3762b17ec876a65a65930b768292b7953792b5d8fab7e9a1be0d7c1ef8073b8413ee7b6e8bd0bc3a5a7f857bf2f09b445fa56d0015d32805a485181293a19cffa2ec07372d2e3fcaa32aa17f03aef8465ab84a8c0a829bdfaa6ac32aa3089d33e7c8d517771e2ae251a2c7ca50e0d126e198a56e12eee62d16f07ca88b380b2293082c7781bff7f0f6b216d72b0a1b294d664c9b29b6b49d4bae48030536057b60836208b5209f1b2ecfc2976dece375d18d112923f5cc05217613d6c34379deed5cd3881d419f663ddffbabad3ecc3c4e70e20efa80fe3ccfe6b72798a54fc7e419f786f3ec587994e3ff824b69ab21524e1d52fe583fe0a7e18ff13c004dd95b563b70f4bd6fd7c561420137fe78c467b7c0bfad030862e06ab6ded1b1d9dc36cfa810cd822d47b2627fb981f4da4cedb77a5714c9b9e5d62457c09daaeab00a5c32314a88f7673b337d2f5c888e08ccff826bc78a0fcc5eea12e81efda1bb0bd9b99a35b43514052f8f42d39b8142708fd6b0a0bb0486106220c83e1865ae11d571eda41ab47d2970134d0da96c6a3be5b3afd170efe24affc5e05b581e36e5949f660f8cebb5e6e2215897ab7408995602047bd1c26ada9632ac85d01ef9761413d31cce628515ee47b48fbd50b8f4ad9dd9781b0d3d4737c1699b78beb6eee6893d5d0f50f16b27cbc38b698544771bbad0c319117f02c7aa8b9b10d166cf2338f9e24644ed30025021659d877e64a20019e3b9c40c1f82fe83422bdb493f13612c5c97701e33128426a7ab4e910f08dcf624922a62a7a9cc09ff3bc042efe35d7c2378e65fdf9ab49ea6b4eb47108dd09899560cc4c5bd30838da0c37decf9bc2870f082223ce2897b9bd9e2df619df031e9814787961bdc410f3c3901f730d5b5398c0769568c9dc1752bd8abbb7c14a973caf6feaba27ae68080256bbe996349d8f8f48ec06debf78d88a79b18f1fe029401c810a31d910627132e3a0a0374fb215e1166dd82c73b88c76923f6ac036d0e1280f1c0b1ef9ffdbfa8eaafa871115f9ca2ae5b058aff94e48c6871de2ced19b9dd1a4e14e2c407b51894a7e21f8b732f2d1041085b3cc96be519881055abf9e5df8923be7386c86e9e82c5f9864709f47e6940906b7a99e7d7bc005032dcc7958e615b67a4e71170fcd12d38e46a4baf966d1842b76eb77c0991715f7e7d89b6de8d1b7db8374391826174bac900284cbdcf65bff785b815de974150911e974c101a2bbdba514737f7ac67c237f9eec57f94a78f92d122823d9730a4864a36776951c3882\n"); + assertTrue(Hex.toHexString(s), Arrays.areEqual(expected, s)); + + sig = Signature.getInstance("SLH-DSA", "BC"); + + sig.initVerify(kp.getPublic()); + + sig.update(msg, 0, msg.length); + + assertTrue(sig.verify(s)); + } + + public void testSLHDSARandomSigSHA2() + throws Exception + { + SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3" + + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")); + byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); + + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC"); + + kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, random); + + KeyPair kp = kpg.generateKeyPair(); + + Signature sig = Signature.getInstance("SLH-DSA", "BC"); + + sig.initSign(kp.getPrivate(), new FixedSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"))); + + sig.update(msg, 0, msg.length); + + byte[] s = sig.sign(); + byte[] expected = Hex.decode("97abf8262ecc8090d912c7aab1d951fffe1d9aa683a5565490221122f945825b2ac44a170d76442f7fc9d8479c05fc5c044bef94a5007cb258ed8efeb8f35e30837001c505dfe87196966c3b2591d7ffefded746660ffadac38782fc9e887bd324e744023b2520d60b6b6916b0285a42e4943c476434754b1651d1e8414070e65933d5916d66359b682c3568e893083e8fbc333f6bfa9e1584cfe0b688be3a5b22e6fefd77ff194597a17c275251598d94c68e73a1aee194f80ebbbf1a43eeacee49907870366d6eff0a85e609e5a8cdb3067b0412c5d4e62591f78ddb8b90c8fab47aa311c6731aaf1b8b6449173bb4062873ddc668978b4042d369bcb3e645369dfe15cd1d6216db70094597bd0c5b8c8cd81c1919fea04ff18683716c8b85c3508c5a21307f5c47810c27c4c3718deb7d714da3b1a21831f7f46e3cb81c42d89acca9040845a0207e1f05843df19bbef671e6bcffab6c13ee26c81bdae2823ab931933ab4528ab725c3c2483e3a4d85a07f089e74ab31a1813ce8593f0c3cd69e0fa54010ae149ca1a7c8afd0006b9244fde5fd3dc295c499bec19bb43527f7d6c9333ec9cab552b8971e130b689a7cea652239bea9efa132ce57a4c890ca5316b82425020114554b5c740d9c26b2ed736755984bdc83af939529254f9535f6926820d4fdbfec80ce88704c4a916e1a1641edf36dc9f2e0c4a68bec42e86c5cbc63acac1bb7126cb1046caeaf82e6c8655e82ef599a01bf9f4b7685b9b8957aa22e27ad8a5ee9addd86189562da654d69b90d31fb25e5a67ca50fff17fa8f7798ff7773d0b715b3958d043503b0240bf36936b4f8330c1c8b09fecd0303c5969d251f37423db8f83c79a093d7989fe2138cb696bdbed6e1dca17d5f18b5bbdb8629fc36a97599fc29aa792204976fabf826f670150df32d3f8670d600d3b703a1e2dcdc314cb9f4a42384ae90ee75967dbb2509077cf63ca42da5ec94ff32409440e47280bfb838a4e4fd2f0c078227718a6e7ab20fd0465e5aab1a3a29c30f0aecd55f0ff760862a1aa13c0db77411cdb48a34a95f716224fcd4a39bcd828f668b7d5632050a5256c644f2a46001998cfb11afaf70794495a6c61e33e8eb01011225364f9e8503ee9272a6174ae35622e3a0e808b2ec5aaf55c955680a5d4df3717f08207d4602a429b0f5adc0a071ce29b322bd3dacc755ddb2d3190c1b7f40b539293221ec98a206daaace78eb178cc47f3d5f2c3f224a6fc32090a0d1591c9d061125ced2be9e9585f2bb07f6b819b1da276e435a191fefbe6b9d44563da04f5731ae33fcd67ac1ec6875e0d1f8bfcad6d947d173cfcdd6aec22365af44e19168d1c0e6ba5f02b4402ec2b719f94d7097ead10f133e8cb675e4a34558ae77a032ce082e12c0c6badb5db19e92fd1303397db5753d9afa4d18e57f9cc26e8b5bd102b77eec3bc47f16babb451ed4a69ddff494f8a5dcfc1b5f8bb9400ed508214084a6065cb7d0a8efb8a073e3d91905dc8f926cbe20b6b3a0beb9a2d4dd12f70341e80ed59375ad2c38650f9bec4db036b344d7e8fd9919de04d14a4f19d2e91a123e65221267a7878121d61104a6594003e605f45e230892bf8d0fe13af8404adb1dc5876917a4dfe435edccc65f15bb7ce066fed76d3f02ca16be94187fb7f37b5379eea8da682f958d263c42f45cfa181fead2b31cf893de43a9041d414cb1ef4424d95741b8e3a74ce7b2dbe16ef0fb4d596196c09d493380d9b49c6180801bb52d6497fe9ab692a4afc98124e80d63ddd1313b7b9c31622fa1cfb7f7c413684fe15ee4b33b51e5bafaa6d887fd38c334b65dee3f729211f34b776cc9eff13eff293a1b3055f5ae083a50c667b988b5996a2db63528eb6fdd4083a5d53df26d6bf8a6b5a4b981cc835617d928358c1b3ccc5dc87e3fc46f4050af2fc020fee26b84af757715ab9f63797e48778b245c3aa5d9f6401dff64a475421b0c1bd59f0ec4c39f736cacf0dd9ebe2b170586902addf1493356e9e4646133e8a118975219b672451d9bf480ea3db866f18fe5675eaf70632abf47e11bb16e1e1ab38dde2ba9bc2f8365491c3f82ba6113c44a0c3d00e2c8eff095270409058b43dec29a4838bda04fedc68ef3c3e8e2d176ae5f98278033dca09237a03cf89edb2040b3e66087ca363e1c07046748f5cd515141c481ea4280d172c1d53c56fe813c29fc8a798fe362f6a578a63a0879bb25090a425fd4806698c94af3f0771f923fdb51953753b7a705a49c1c25c38ad203a696d40079274813b5e2168b930fc646c771ec48870521ba5eedabdb0d5ae3e5efa24e86132e0e487bc0bf42721125518a63d08f8bf7f05f4afbd2b939bf74a3ac892aed06d9fff944e2e333f951e99109247aa63265d2652bdc528b569639fd0dc16c03666300bd04873ab72f95e98bd6c9ec60b3f29c2f1bcd986100a70c37421352a4eebcb58cdafc4dbc867438887bae9b03ba8412e7b118e5381707c394cf428047f27a5255dd86bb77adad9fa1b8ec93f845009b58b837a04fed5197ca8d8acf4fec81e61b04a40bbecd67c30a490ebb2c18bba756b307607af3f121e772e5f89a90a138aacc92d613b0c36fc508fc940e7f515e5c0010351c865e954a8bdbc06e7ef209b776f77396e64d01a5eb13fa129377effcd77b14fba76f5c40fd9b9322a8396993df67b491eb462f2c38702ee91fcc18f9bd217fa4c54827a90b949a7d491420d544ca0ff11a22233563527404b8ddf0b04260346fa1042aee73fa1173d77a1d2485029efa6db4a7a79e169a7029c7be5ca51d864cb447c3f9de535e21a45d9703f00c62c0a61aa07ea6ba7a62ca524bb797df74731f6a7adc356a9adb84389a42770d105d7b8987e00ee3116d49dde57eba0b4ca7dc8eddebf3f08909a3e2c41a4f94431d59d15053b27d5d48f0bb531eaf938452562de653eb889ecbeb0920f7c9a8c3e4c3839ab32e54e4cabd7dcbcc922150271539db17845ca82d09064b262066e82b514322c8391693d6c5a90cf63f69a36bcaa995e9fa0896634ad316c9f20a987d72dd9ba90855c313af0bef8db57fd2af833371116617680fa0359eb91d1f4e9978141a83fe4ea4bb7b8c7d5a418b4709376f47b5b2c9e25b89e9d9cc45edf3a8ccd1ccff3e4e7b6f0d7d1e5a80e8d8882f2e726db164add7d9795f47261e0a668f7d83b25803182af4c2fcd68e1f2b142bbb8dc15c07edbe583d5cdcc0f3394934a6d4020bcb3511ae23fe6a6b9de1d1c503014b172f5814ff655f9dec0fc065644ecbfbe879daae4646ef510900fc73101190eb26cc0e563f1b5a204826d84397badfb796f32b70beed7848fe58970dbfc36fd70fd2697efcd069bd92bf9109d0e4aa9419616097e8a4ed00042c7376b3f03da61b61d959bd43b398de469092918c08213fe31e6e95a2cd650abdac660b15a765481a2f2bc57862593518d2a90d628b550ae9c5a3d9047e12cf4d060a888a1266e4e9068feb5a1373c5dc806108acfd476af6b77153a5222e0ce624e06bf56ef1cca69f7fccb3e63c6c288e3c22ab86ae0309ef53490143e96da053b686a0d876ee3d675732be2c2ab87cabb2b089f8b6be38e9705ccc421c4ab153dbf16f3997e3f1b40fddfdee401139155cc3bcde2aa0667c99bdc381415e4e8395f0fa7b3ae0e5a73e35f66c8a327705637698578ed707f3bf1463acb68891a36857ed96cf5f21230b2026324359cc06244bea558d827b80f79eee48ec9aa55bf29ee872986b1320abaf5bf6b36836c7eaba504e8ab6dcb070d6e55616932a69f0aa88825f590ca2310f0306fb7cdf97961048174999c18ef0cbea0216c2944f43cfceb998a9fa2977815b2043aefc4a5565a88b0c41368dc47ab881d2d8ae676738415a73b0efe904964c4ee25ba0addbacb3f41870ef0ab91150d3363bb5f938b60b3a6badee17da834c3a885a32cd8f1cff4fe177065554f41c537f57f8360fe804701fc8ae7b2410bbaafa5bf8a735f263ab5fa9e3f786a188b2e5e187fb33486f98b6dc251ce723ea1b91a3b93d9026102467d98e3c2f144b2bffd60b493d986b84947c4d0b26c02923e40e9177339abfa48aec841cd6e086d5bed7339ad84a6470851fd5cf5ec50b999041092d6daa210e47c746f62d5eb4c00e84c5a92c0a1fc7a488739fe3adbb71473b4557fb4a12fac2e9c33afec4404d3d60efda9b21c307378dae06f8485d7f48591ce6e37bd43b14a44497b08ea071a941c88285abfbf6a2176adfdf36db642312a7422e17d9a9dd995406ef6927d4f8276f0e400209460ef1707f0998562bc1e25ba7696e4c0886e80f5815cb8f1e6e4435f8c4bbe9618f9cd9c5e2ee434f5d81abaed382e5ee08f18c7d491311e51b447305f2f7d0fc178ed8e05ea525a7b311e6287ca879ac17d6d6629dd5244baed1842ef2f92ba4c1121772e83a61f913158eab6dc3f43575ce2ba434e19e9dcb61668a9c0392f03dfc736827ccd0dad0cfbb16746e9d79ffd782c31614be641d970dce41d2238d8bcd06d9c31eaf3ed7798c6bed444361eaa29a24716955fb7d8a46ea5e5dd0d7369d99969d864e99a8bfcdd591e32166f687f163a3b01fb97e1552b4f40a243b0b6275a07cce9edf93e2b380822c63865aa6f1ca8f9eaf3ce0053fcb8a3f201ee750a24536baed662979bbd13c639ef81dad9ade1bfff5b54d89d3f92920e2c29913a4038b16926c9152857fc7ed4c74af5eee07e716a9f1fba3260a17d37d2101e0f777bca6e399f8d34227bebfa76c0b5acfbf0ad5b22c37f1cef28e23eb20bcf213f0ba8bede81b9a855f356152ab72aaac498b74d4c452f58d0b88e20704a4472f0b7f2ba7bec55cf0510cc09cc8111b8b12b87a8af18ebe301fbcaa07e8f1bc2cab769334bdc639b9843161461eac15bc9c80000e32be985108c7b45eebee8acbceff65b52cad542aac52626585b250c95d08292108f7d612c273f34ad0edb0ef3d1047d8cf9ab52d4ea08074776783b84fe29f0c202dbe090af676058bf6bb1d227aea4b7f1c5f08ab64099e5499b2f2d34cb5638104aca898e3915aeaeeab1ed10942751e755cce70605b0d3bcc65db4d5c0cbb25fbf8ed83850a1f3183430ebdea232afd14337fb123a2087ec3d5c2322eb4a195d8d9589d5378a4d787061b10d1bb57abec43e2d9c36c4e7b2405f04dcb629e57021fef2c1a8aa6ab36e779b98711d1fa53185c9842a28e708b2f814c066a88638996f098fb01dcc8687ac77c7897afdfca78e68129dfb458b05c4b174421197d911b71805a5673862f18c33810f4e7fb951ab060eca7d3b1a5f04f4d96cc63b09ddd3de8d6fcf4da5e639df75cec579463464eba92ade5926803a127fc7ae9d4b57cc604ebb350076b81c52a5c6d7257139f26fe04cff832ca5da4d2796e637655f79d9397249f672ea613ff55490bb8ad00e7be51aeb527132d2044eeb60112b48fb8ffdd2baa37061b96734291d71f29057307d3c06149925dfaf4502a42ff277496f835bafd5f98237209924e86f6999897ba32b9b830526b44a7af2b1f61fb00ade519983e93f3eb481e2792943a0da42027ef374e8713e06447bca767b9bc28f37e0700385afa391e61d00d90e2d314349d6f24f12cc26974c4218196cc18623a0d92ffb22f3f86437c182cbbdfae0d38075485a414c0c57ea4b34ec94e42bd6dc4476560672b316b2e618acbcebbeb2694d585d97685d0cbb3afdd1130d137de6b36c9992013064bb205b62f7ab521f0fff25c11b5fc380ea82ad9aa499dd37aa03053acfff8e266402756d8c07d36d5bc4775acebc197d301bed7d87fd09db7a96cbcc3baf8ea9f8908b7c6c69d9663c4894b562337d48e502609d9dc3709aa44cb3b09b81f735fc511d48c7230282ac2c9ba7cc6d6afe03ff02495f8fcd18f0e02ca99c789c99651da7262128332eb514637621af85a187c8fa219fcf4881a6d2dba360a0e22ea46011e2e254fe37f2efd87ea010524de715777218c91e9faa354fbf5250b73bef97365818e11a632aea1c29b98a30b7855be26f4392e540756810be7960cb7a3de41e7f03a03e57ff62216445899bb86f99bb3248b60de1dd9ed520fabc7db68c838c4ce8b34508bb0ad4351bb967e8c10777b2f290e536672b808e00563423e8b882a400b5feae1a0c1548447632d9ce45cfc69211143164f8264e1c0a985f121a272c3b2825a109373b7a27fa8e8172f1272f464d415b2c64100860c37102d2f9e75bda0f829d37be540950873dd05cfb9d20c91e9af38d7d489bd156220f7bb44323ac54229cda7c79ef133e27649f17854afe475bcd73b44b166de455cec19f3e50d8c32e4eacdd9d10d80756393144d8b04251769317a9eef49b0af63d9913daefa9b182b58886d1319d8ae6e0ad39e1d6d7c09e062c9bba257062b85655056b347f5fc5951db25767a05d14ab3180d4fe67f99d6fa566ffd99783b8cc48a95e77f71f21693ceb11b53e660d6d7bae6beef1418269613bd4005887b2a689fea9d0b8aed26a702794055a7155f6b384c93c9933e173719c6b4423f4f439cccb7e8151d5f17cfadfd8907f44fcc5ede6da12eadce5c4e71e7d62db34c5015734f7398c5486610fd2f513ab53cab2c2bfb5ffed441519daa946fbcc61d957f3d907b8c172d60667e9390a859560d302361046496c7bcd9d85effc160e1d5439260d0c2e521c721ade0bdcbc850dc5ab28a9df843ddbe62eefff6f3a9918e709b5103c77495118741df05cf2b51bddfe719d4838c526a254f5ca6b7ba9a0cc094b508a56ff0d63543b9ccc54049af61367d75a25ce6709f6b1c03bcfd7d47b7a330cf29d2f9ce8efc01d4813fcc3776ccc0f15743b0043c5d52261510cac6690e5e6ba5301745ce20fb83aa2da52ba309cf8b1cf8f0cef3331ac734207318d99cab8233eda7083cbe2ac0f8ca7f6499da3b36ee4fb61ee55a4c79d8660639e45dcb37eee87473d923e95237a5096f36bbbf8573444987533733537d578d474be1e2712e51d8e03e51e3479cf14799ba6ceda11c139855ec41f1406398dccfb7ecabf09e176e24c44a024cd6073182ac1f58cfb23bf6aadc375278f695709cc5e1d059dbf9cf5701aaefe8b43e5ef81b58090aa4ae41d7ac76905f6d504cbb3b8f66a6b9b74eb34de83431f7a03a9a0658627b07ba1dfd3f22f5af9fbf1c6d41d6b3bdfe6574cef264fe88085a80d9f2b011110c92486b81b3f6008d904708b98a061494c57476837ebb0f5f9445ee14585b6fd7e8245a06b4763345dcf0289b2bfbd8bd90a6e5faf749a7d5b96158028791542a38d06112f2facb7b894fad214868fc5abf2b960a6ad8371b2dbc41c52b16e50e89f22a25deccea1b28b334866bf4afc7c50ded23fb8029d9d988bce010f2cd487c2921683704e7127b0dffe8daf8021462a0068d4b42ca50c5cb96ac80ae73191c7af7af0bd228acd8dbb0b50066ca9af2b0c3fbe576fe956f8f37e498770ecb29e859f5c7c0b97e5ab51f671e80db0815aa3b74434fc7b716017aaf4e43533cf5c7d042bc3b5e4aade7df0a51e0f027c80bbefd2f5826d40d7e94ca8283ee492f9fa04b7a25a483c44b3ae79f9216b8a5607ae9f05e1fe39b95f589114942c176589d56b2d608275d0588c09f01b12e298907415370a6a907caf5a8d0f9e7eab5bebf3b63868b0d3e9631ecdc33aae40854ec63a2d77cd0093a0409bc68fa5b817d308fe2d01c76617563ea0631bb5252e875b4f870cf486304875b5248e18108eff0e9aacfa5a8fd8ac65fb25bd3b8171c7e348e095c9ff9d4aee7d57ef886c88bebcda35823d5df6d710fbdc7ded368234c98f08398ae117036cbda8441ab85e54766395b485480e552aed66d8b1eea979d420206c5342ed809f331f9aa750c8b69748ad7093eecfa7d1293ebf2eeeea810b6b41cb910635ed7ef69d7e8573c31e5bbf1261759aee31fc75eef1d91ad8cca33234ca51c2422cda19a88ceed475c31e8b7177bd45adf82b12d66f017d9f6438477989809f9b1a6005715170baf82bd82f4af747bb2d92ea1bfe874334b837e4fa503ea999df417aecc023cf44b002611d0fe34f526384aff6af39690f88707206e93a2b2d4d67cecca282dc1a1770ddd4ba03587cef40a9c6456e001b329b48c2b5ef9c139cfcd8d80024bc43582ee4b29cc5c7bcf62b4a34b0b2fbc191ac8a53e9ea1c4aa57bbfbfc5ca202857805fb6d7d89504a8e192279bbd4b3ac2a9ec2cff0c598d32f892aefe3d5c1de7dced020e0892297f947833b0821477a46e6a2019bb8c1316bf6543dad419babc2dc9066c580f3c5cf41aa0747419d410ee3acebaa3467118561cc1a20e50e468aa112a7177d68d47685f58d19115c509228c1c3a65c44fcee6a7fc83c6ab99d7656c952c2c0d9e5a2685734f1a3501703b66cc39600bec017edc40d26fd8696b72b751b1bfea966dcb4d075166e7386e76ba78ea39829be87647ed4e533e37701c5f6846694ee4d6a81350d8d2e67e8639b405bfe3a1d9c4ced6c8db7e86f2961b032c2b663557d5127228c69ce0a5cf77b6948857004263d510803f418c501acd83f1569e5c20ec55eaff2a364a62fc14c1243a78c49e7eb1a571883d584a2cb26a4341a292cb908ed5142d6d7c969ccaa7871f29aa739f7906657b076642493f6ebcd4bdc7501211861014539cd9173cf2a80a9a30b04c297810a701430538b0d4aa4594ef98c62ff89d43b1eac325e2bc4b0988548b0a4826c22445cded4cc6a5335da96f3c339800d3fcbbc0859f4f035d13438d5dc693145f4360c1f0f91801bc1b10da717fa42a41725f13380b6d20a349c4d33c1425d08864e2b99df50257005727dae94ac4f6a8f0f966351fc5b7d47d081e362440a1f8dd461cc73a2d1f342a6084bdd2542302efa964411d1116202ae4e0cc50e290e5cea8d87aa07b494d1cf8314fdf4d5db680676f06bce77739e77011774c510149c6fbfa38a8c52063cd446572b8ec4dc8f71a5386e08a55f53b0ab523a4847abc7e43086b5bdfe50042d10631842b1fa63db9a53a217e40aa27d84bc9f641a2efc138d6779e5210cbe477dd5b34b033a804be78b96125af980608df69393cbd83f722b20f2b2fa462f0d6f4252c3e451892be8d02cc1c0825d5b442199a4bfc22f262e2a1904aeb8631c7f794d939de6a3571c92ba91daf8290495ad0b24f529907b5cbb56adfeee47e35008d4f0c10df2608d1fa679a688df6ff1be7cd6633e7e0449745ecd513bd2778355f0eea6b75f4000a3b7a087fc950eca10e39e7bc6e89bcb2ad831430da37a1ec6fab6227c1a01ba8aa83530d201fa7216b04cd962b1b21a82bb47a7e31a363b34715b6b3b3ff23f6c6620be3460ab2fd2e093b05141091393312367c704a0bf1543eef068b6e9f38991dac66f1fd4da50387b099e4136b296c08c225d14af62c0fc084a48100b9938c5cff0472de42f3808866175b343ea19fdfaf32913cf6ad715f09c26368efed9b50342034108d86aef25b4ded8a18b8b4c8f56684a0fe1d3afe04e0956158b31b0a3420c22e2d48589f8a398398933f1aefa06e4f2fcd68fc60d5f426495c9b45f225747e1325d451d2d00587ad226b525e2105d4d67da17ec2f869e206a7ac6a34d6b777dab3d9b57f932af5c9f1c07b46d14dd1c7c9aea280082bb97c6912c49e634d75ebe6df6c13e9ea525ddc986f35439ec088930209308b213741b842bec6770403d8b15b96550e72429a2b2b48d73b2ab273f7146139de8b5c9326172f3ae5f58d5f6d197099a4738338c6007d707068be32876b07c684ab643c9b850d7cd321c13fe6535ad3f5bb0771cf9d8e9040d97b3c7130bfb6b74b658a1169b9e5686b652b29df367a8996e4b330160a1f6884209ffef3cb4bfd267c3a9f8986eb67293b59ae2c6e9f0e65791c662e8e8f6287cd47bdf8e9a868cc5683fe34eda17ae970fb09e56a22302de1daea74e3905136069136b1116c58011365bf18e5b7cc2723579c4a88ab19b7a1fe6049086726dcf4976cd44ea56babba182b93cf54db46167e1af13aaf9f4637fc5660284eca8cd3965f2b866d7824669f3c8d395b8f6cab85bdf61435c8df41b1f49dcb03c00f985768b7f6a7c97eec6ab31fc3c487de95b806a72ebe0b760cf306ead0a6374af57e2604f492ca3408f331c5f4557bebb57f886c07fedef9c32ff0724c38b51a6a796ed446e03f6ddbdd4b248e39925d8c52e1e40addea755803fa0b32b03f26a786863c569faf5fa399c648bbe94761230d38cdce923202df658bcda5342300d8c485a3e2878496fa64b5c60da3426ecf44ef74346b4a2109a30020fca529ebca031d1ff1c37c6e96d245067aaba18822215b9b14e07cfb613a6810fd7256ac926318d5c20e317816cc191f25db9930b03e301e86e052f108f7d6050f9f5436e03759072c4f66c47fbd7f99d8a16cade5b2586dbc6fd9cca63cfa6f01c35431fab1e07da99abb7c8ea81f1f3b7b61168eb55410c193059635997a289b95bc4f055cb48e3422786be082d3fe81ddd8c7724f509f265f88e8dc5735912f1f633256d168ae8348809ddad7c0893c244c41f9f83bc2c2bd9916a47a2ad0e0452694c01f1bd5535521cdff8756d70902cd34fb74ad0bff2a0a4be8a9ab9d0ffaccd31bbe7ebaafed0628592f5c4b268697719662b1780917d5446eba299e94e031b8e6bf5796eebf13515e5a34d1ce916a8e1c1692288f515b5239b64cf038d3e72fc20c68b4a3317b70120638d11e17e44c98578b596780ded9e13d3456329ce22cc4a5966a581347f3cb19f9d49b781caa25970a591cd04b23ae6e62d3afe692e6b29f46f12de0cc5aaa1a32e34b4633ca53587b362fa0209093f36fbe683a46464ba794ed9e03747f46aed2771a5c407f7595c3f6839fc77138e68cb32b649d5f8a603442430fa09e9d9abbb31aba1c9024a64c8c6682d3e4f150a5f4b9d877873a1984235d1271304b3baa775c4cdd6d8c0a1e579170fc5ea99ed4ffaf86a325932fcefc5ecda2b5773384b9c67bfbd7511a21290143adaa7c7d735295e680a9b113ab64e9bd15ae72769e947732a58e33479f2b184b9bed85cf766abbac27ae8a5724c641ed23ebe9b2a718cb0d1c3e23085a1ae90e9a497904cd1750ed6d5475f3c1266bff776b89b4ecb4423ebcd3512c246d209ef51994fd6e040f29639f784c2238f1d05ad5612be0bbc2285e70b44fa2b04ca409f1c221a8d07b8852817d0f21327f39bb0114d728ba005a4e8122cfc20f03836c0f41f5f8b4bb34f06ecdfc16281ebe99d9f3e34b8f744f8e7f68f36940f45e9a1b9b68d8b17048e3065882886a666301828fd9588a27719cbcdd07188524a30ccc1c8f9ec4a1def30b4bf9ceecece9e9ab3a7ce39ddbeb697f4e4e2ab8ac7d9fb149d7cd02752ac2ee2484412b0493a6fbbf434d314eb996fb58ff008ace1833cfc5b8834d899125c79f66253801d5d91bce8ab1515aaa52e3807011437b51eb8b14053e2baf4916e9fb675a810f414dd113a3029ffe153c83cfbb41af60b43949312cd97e77d2dbcba3c7f278ef916ba71ed3f041c113584654b357e79dd7e48be195620a30fd59916932129bce4ee71566f033452395ca6f74cea2d674d7756677a9a1db9fc9c91d06bfc3406ad56699454b46b8a8a4d43c850fc32b7b83853e0b01457faa4ab700bccc90415ed67e92244e43172fd7e1f0a8dc6d5425a2cf61a8ab1ec210c16566de4def8a5341c4744d386fd7676cba7a8b614cccf35d709758169dfc7c8d4f363e696c742c3b4b949b09c8239b2074c0209c27f1ccf57a246ffa3255b91313b9b0951863973434c43d03b71c25762e5a2b05074d74cbd85b40f5c783a034ca2f7c1e3e2ef116404b439166acf6714de2a947784142418f1e1e60459275dc93d785166cdad6d1d688774e9dfa59e0bc3095eedddf8abefb727524db25916a283dc10bcf1ab99c7c564086a34778ea1bd3e09d3c5e2e8cf02d3fc1e335ec3b78412d31bed7267b61ba0641fae39a0ccc697e1cb95a3d5225e6f7e9cb22922662d53775718d824bda63478a9d593e28ddfda63d2979248ecf18ee86b047f4b92a863eef48a8172802e3dacb7ccd2dd0f5ad6776435c1833e0c2e1eff78412316c3c2e92b8bc5bbc56d6d70a2add1475588eaa47e1a15863abb8f07b5c8bbe6f0e5652ed55b45be566533972e286eb3fb5cb64ad108f417d7183f19ec4e118343c57540f59ec712c44ef56102b233eb5546b9ec1a8e9eea1f26b5dbbc4afac5c0d8106eee4842f05d7653e147a9be7c7810c2b0a6238f1f4ba61127ddc523ebd68e01541b761ebaae6b3753cefa35f7ffe9fdd8582a91886a23e3cfc42b560befecc5c07e259698a1d8f015d2472b527290aaf51363c014fd756b18c616d163c9786bbe373d9e07e9c409f618eba278966a09f3949f9772c254255c297931aed9a265c692d20e32fd8198515559d7b11749630492f3a90cad732f4e6ab19d220cfea10ba1f374fd9d5f6d532ce62d7cada32c99d9808f8fa6697f3a94c264793122ffa03feaad79f379ac35924209cb4fc1200bca2d6553bd9a92d0d077e2ad1cf340e53ef5c83bbaa8c36d9a2e09e70258fc26a7c0b905354f12ab2c51f38bbf1c40c65e2ed22b8778ed52d164b4c4e48a02234ca1a43f65a6f25a55d5b1b42952706f9eb5a2dc79405cb456ad57f530d03ebaa7cf15859a01ba1cec9eff7029c5af310bd319bb6e22204f8515aa592fce3eebbfa92931fd3ab258c0bc18346f06d9d0a56195c61b7f5a58dd5378286bb7e2c4ce32c9409cdb8c214a3fa94612f371c012c5e83e3cfc065f87e03a27ec00f4435b5de8f865bc274a302ec6a808473b0b303466ae36bae92071f9343299bb06006666dd716b39cb28a06816da8344f93fd0ffb19039e30a053ea80cdc78a881730ae50d1049252e75bcbb0b5e72c532bde2725be61b47eab76b1231afe90da477974c2ecc6e0f80a38263d2b47f15ec8de44357496c9cce4b7dfacf729432d2ff712d95416574161c67ec8926a7af9c23c20e9e0ffc2c908fd120d6dc5da1622118cd98e49b0ed330088408028369a67e5cd9a40c055e342cb83410f15b074cea11928d1b963dbc1f2689ac9f74fa4d27a5cc4273cb130a86c66c76bb29c68aa5ce4761b8b3ece012e598c8f95f06266f65067db96a8d7a1ff8aac507ec9c28af3affedd3d033d61aa3af1221a664bc385dde601890bc1c359bc8c6b9fa0e3489de084cf67ca52af0215349dcbb810284f8b363b8115df6277922f1d1dcd1aa7de365bcda4e73ed5ea6b9066a98e2f3372afbfebf21b11ac98daa04f66f67e65feed614d4fad3aeb376a2fba2cd7517b71e8139ff5d550c588cb0ced6927bb18814e2d031739447218d03ad1ed8ea720fbedd968dedf50d65ff36c33a4dbb42f97615c585f537ed992a4d9f9ddcf236177357db565434d679298cb8b72dec3b1db2a43518d80fbb41b43d85880638555d664f4625b843a44b303f29660283e62a2f720438810b12eed5793e2d144d1e873c44c03dec5a99d564ac3d6a44869ae9d9775d786b4273d97459848913dfeecfae2e23cefcfa47a400ac27e6914135b4f2bbeff8e83fdb47425b8a5372733647a1d50905c5816559414bbf11a282ed793b3dc12aea60c102001c92a7b5be33ce2fc41bf0561926fcd6987f218592045ac0426316be2b44937e7c309197e01d19780d39a02c3b010caef6f26f5d01e0a54cbe3b61d24f16bf66358eff925ed848810b807b322e0ff31037fe5163919a687d3e1d7559d66108ca4e7e5d810a07222ec293538f832d43c926ad09e7f281f71289809849f34857e07e127e20c55d0071ba82c13f1d7e3530cacb505780e25c9f7d823fb19de0b116a245ffec4d34ea99e704bfde488d92f942dd738f2cbd3f5e384e032c9eea8a3cd235cf1712ab98e3c20ee2645bfbf5b0316c1bcdae9ead022b64481d64ce37a1bbf9c90b49c9bc6cb55c07ce51df1764c7e03184ab524012d136ce289a6fb8a15c48113b314ef6dfe32c76050517326246a74b080038e8d3941f0b5cd6782da7fb4e86dda204a62f49da9942ca19d703c483bf825ada5af1de7a82e8351589b3748771f9ed48e34aeed42eed22186c91eef6598df00ca9844a2c7041c6ebe9bc63eb1a91b6a49700cd545fe701362e6750e4d755f656b557b9e8a4d8bf1f019032a5a6226830b98485c1f0fd1329b9cf7ccbe3c6620f4ac2c5dfea9b5b89c704ea4130a8431f4bd6fa02cc1be30fe0609479223ee9fda764d759f2b093075bd977b0a2e4f7fbc2cf1767eaf5f23303a15113d3c501e4197efbb404319be08ce0e030eee54e33e59fe78d5076901a37bd46dc54ed329cf2e0c2af67ea99fb95b653c0f1e150c081773ca0c8d99f8f0c49b6ef6ed538d5210b13ec2a3bd85174ce90bd3addf0f0ecbb5c1a9a53547971c5179a03a10e34d297068a9cba538c27a8a022070b985dd84b94d6a1874547389e4fd31d93e57c4ae6b31152897802a5b9883d9c4415064e89737b56e33d70627f6f15996c5ce7494caf4a55c014468eec9f84294b731ff9c38daf38dbc85995a4894d2405575fe2de7091a09dded8b5b43c1c7cb716a81317fd71a1743c502c6b84decaadf21fdbbdc668c2b6454704d025aeb9c3398dfc156c5006950af70e963d541c6508b46cfc95f8e02c957378e82bb1be9c7e525d1501c4f0ef2c0371507869111a5b4782bb86dfbaccb76c78a533e7bc33e1a06e01b717fbd4feae95b7aaa5747e83ecec56e643572d886afe7ac6c07ef11929492da28c7313d337ce8d5d294886fdc8da4572e5047c44f0095f85dfe548c313f56c9b43484ebd5c9452fc57fb943af3f1893aa5574f9bdec0e686ea2359f37343913eefa3cd921f36576902980edbf71cff0856c01565220c7468015c85fe107d95834c36080d67d3f79c18ad9be238687ee3a2b665e7706b62660f7dd4f735779f81c72343bd755e8cdbeaa30fee1c31af79118b2579206fa2201b4776df802340062432e929ad4624648b05aa8bba638b1155f9edecc108d65646b153c1299e48c4f0898fca9d096502f07599ed198d079ef2a1f5769cf900c29c74261fce73b2bedfa1033beba9a4be9d2a1207ee0ae1dfbb0e0ee5cf5846b4acb583ca052876749761fc1b9d5e8e50c227703f1c24b3423dd0b8d952de9d6cfbc9732b155433bc3224ee5d5bb216a501ba10d6b35eef3c53c92aa5fa842ca0656cbe3cfdb706221e13df1d50dace07ca92540b539b9150ec59f64b0d094314f0400e3ffd83b36ef7057bf1d4f463cfea5bedeb2939f27df42197ab868c9b20c2281f273dd63d0e84dc948cb187e16c45a65b0fb5948da3bc519de12bb27b8bd1569ce1dda65ff9f2f493178f0296d11ca87fd651ea0956b43a04f9b6baedaa0e890ae84ec4794ba7113b0be9a7de46271088378254ea173063543ab891e7890db9c9a95cae5a2082cd22b0ec74059e0eab25ffbced3ecf5d3843f1db6b326bf77baf4dc3d982db339c5fc8b0fe689444a2eecb55c3dc6b3e0a6e81fb77c7850bfad8a838106b6ebcffe61f170c06956253e096e62ad7287951e5903b475b0849a89c31c0148a08455d5e156ea9705cea36e76f496613a3d05019bf41d83ac0dee90607584385e9812a74ae3490251a7c563b8a1f0afea8e0a55f33530dbf245c61ca8b5b79f08483f019d0ce62b3c9179ade5ed699112e5810a5444bd2e8a780db7ae0005e78c46fea3caa73810294d2d52d1b7a2f8b019227480e0b1bd89adfd5378bde1ecf9119d56ded4ad3416a6b0bbfb813708ce98c5e769b715686dffc4c1687f756f37b2edbd95c8f30f895ac951bbc141db005832a5c44cc7483127370d4d25c91d8727a6f33c7c71ff3472f4ed11235ebc1c43b84f682bfa08114867d49930fe9b04179c25c2bd47db25726612ec8e44d67d0c7f9922d1bbe21cef6eb2b137802b6601be77e4735f308541440cbb66d5016632b72ff1f5885efff556d3fb461fc600ffe037f4b4ffae3da2248645cbe1fffe323de6e32f4a096435924e833dfb4760ee711c6d40174067cddd5ffe921359743785f8065dada7cec548172865d7674e807b13d733ce90f5bdea5f2173b64a10706c1bc2f73118648a0b2a6da692d3c74836030041f2ea4a3ae0acb9f85968ee885656e1af41e5dfacba30093d39b10e6fd09a2b087b5d1087b4ef26c1376d2b85f98f15a77460f579cd5bc6540724ac2710abc8176f9bc0ac6ff6ec90998fa2e7ae445a24a8c37c2b5b45b35ddd98d6a886a6c373b8e6a54d28bd4965c56dcd7072a8d15be92b0a79729edc6f9dfb6e599e44e0c4915cc5867b3c7605837199e307da175a9795c6813d0d04ba34f29e5f8d10cd410fe60e255dac298f7ac5d50f356f44f77963a45c7488505c19bec4ff16863be1de19c6ddbeae9caf02491c099ba90419e6836f812e49eb9a13dcd8feb43aed62fdefc3d5d6e939b258b00041ba0fc26e3f17c153ecb58b135c2ad6d02d4d177dc06baf50483560267edfc4c40bf5b4fc4fed6aef910a5ae719a26683895dca1983e92ba0fa48cd2767fe4066cd5ec0bb4f1a400142ee1b3ca9a4cadf7a0ffff5eeeecdf25fe59ddb41c045cf73fe64f9d8b129f3044693c7288547ad3de0bcc27045ebfdd9dfd9aa63e57df278d53608f05f3ed4051faf1fe9d8313bdc909cd356821b75c4db091fbdca7024f74f6c1664f1f241f0477b35e5052a1a10dd2fa90f79b22a1d0b93b8ade6a63c77d579ffd0e09c15088a8075296ad51ae5cb51ecefd1d83e2b75c7ab6813db1a9f8058886bfb7266c9fbeb753f765082df60ed0b17ae6eb2c49b5d4fef742b2ded5620f82af66626d791df3b0bbcd9db3106d13a6fe001764e99655b694251e2274a57545d9287791a441f202315841617781e733224dc8fbf74923af0ce5aa0aeac1f7b2e7ac200a9e5a24b9d97ce889f35157a8d8fe9c064f2d0ebca6ddfb5155ef0cb042f18b0c840bfb0869a5299bd0082196d7dd0d59862ad3ae40faaf932e7e15c2355329e39e87938d0f502e30dcd394ea774e9107bf9f598d456658ecd209f5bdc5e3f653be2fee7fa3efa23a091c58a2392a053f39019261b2f038768278bcce4bf54883524d9ed775cb50fdc6a4afc82845b0a576b7a42d853fdb69aa2e5756ce9c57006234612fdc0ae5f29c35c5a1f528c4edfd62d0044ff7c6c30f457c77d4326094896de4c153e9c0a27114e3a773d425952d319a5c84f50be8fe3a823682197b22b0ccf9baf743545e46e2873470c2406b2b6606ba28726f98eac420f980b9623296149ef6401cc3220a5bf6a1b0bcfad3449a5987bad56312f64c484f247d12fda6a72e00be90e5a34803f4365a53d1d4bcc5c55ada765f82d59c8bba0e09729b28d60c2e57a14a0de999764404cc5dfc1cb2ba3f4411b54368782eac1927f5d5dde3ad674fd666c453b97a76c09806c1870b3406baeb0b6d5a4ed6e34f3a95ed69b93907970feeb1a9b58200ead013502e3180c8ebb24c21d6bcbd0775781082756acc35365bbbf17af65d8a717f7821532209db874e85f8322ebf01a74b798706560703f5b2b37edf43a67ac4d510f1188733656c3b211325c42783937e7f0507cc98521a76088b621d01c31fc5f1ae3d8be0e6a16fd9c6637154fb099d264a68960d9e34b6fcafeaff474b6691675c5060909fb5f625a248d33eb35bf7edc72bea2080c70f4004e66dbeec45bee6c01cf95f813cb9b8eeb91e7562ad7d53b1b8caaa9a8aae94cd18903430fab9df066056c0d4cacca11498ed4cab478c2d6bf999921d2251dcbf1f523f185bb86ca1002ba37b64de5464765e7dcb79a700f79f3cd75542cd9eb942789f260b40ca872f8f294997ad12bb01c1cbed55532f176157948729455c96239d6b5350f6149a3f1d7e6fd7fffed36400efc4c32cfb5eb53edfb9c6c0a9f146cb1521f520f08e5b96b6acf9f624782658be2bec7c2a26c7e0c7dac22c53bf532f649019ee870e24ceb78ecdc8873821cce98da0aabf423b3dc4408b7dabda2bb6c0286dcb6d8efc111ade62eeab90380e1f9f9ac03db2fac0208c2bb6dbaefcedfb5c50eed77568e7e7acffbc2c332608805e31f4ba9d3166e6ec4e64100d1341256e35dd18aeb83e73405e00190d53292fb5be179738027be8979fe1da2818a8d4f96406fd4d905d7c6502b5dde390923b0f6a682bd1ad33add7f49ba7ee087ce16db7bded565f95bcb7b7d715d7f4bc72028d098e832250b4631b78f4055a37ec2057823c5a3fd7a38a535e148f13a1d336da09697e6af1410a4a2606264fcdbae6cc748ca6bc89190c12a7d410909cd8c201c205c244e81f7e1126c6e1f140fbceefa720ed4847fdf18843055251ccfa22f8344887eb036a170dfc5e70395196481c4f2d0c57c7c3537d9a2ed32405d34edb92937335733de3454ced0835964004004a3f6ec93a57f22a5483a7327cf9ba5c147736a2a059760da4fd5786bfebbebc7303b389ead6904364f523affb90bb7d787a2d5f4b43430fe7f149ebe1991f9f9ac53e18afc5b955f0e021bc1338e849c0de9b7bda2a63ee6fe5510c4a69dc1b88403c1a15900d474c89553020f020a3be2e9727ffb1c645e0d708d82ca6097246d1dcd0ecd705ba755708737311bf3ced69ca805bcf8c658c228a3667a799516882c6f09768393d43e911de1fd4b934c3fdbaef809e46deb7b43b572222abf64293e0b387705ac39907a3246997739b5fff7e18fa58e001cca65d279b9dc76b20daf40c27f7735a147d323e3f841d890602bbae124b48f07f8a26989305cc09f125fba1357a9dbebe2de48d92f68bea59c5321423aa342da1fecafa77ae68bca3f0b99960922fec46850b44f282ff75b4bd2afe4c1da517d7fcebc8d61a8b5cc6c3f38a93ea39f28bb3532e4be7a8ceea325a268435464cdb6f9fc36e7a277c5b9a619e92b3b2e13353e25b12357275db463587a936a16aad58ce62da401b3e78a68c074725312c1e77edb921c6a73b01d37318ac6ef8634aed2e869a6f4912e2ac4c475a9cb6eac935f7d0820ecac9344fc9534616ff8bc1d78cd401b40e9e1ade99c20b49fedb1145659f3ee99d4f56d990717fda16473b3b02438ec1cedac9e873d97d3934d3571ae034ed1a4a04c7d965c8dec34532d6e2c92afd20d8b80cc5678d239b561b2a1822005f3920f84aa83c3225035966199232f2bfd92bf43f36d15d038c0b09c9a51fa4982c2060615f50c00b576aa2cbeea2ddf7f8ca0862e2352ea7f8884c11be06270515fbfd8a62c27fb3c64281118f18362f33e13eb6507cab7f0a7d5ded0c42c5ef5ecddc8fa746a823479b7a14ee86a2ff481f31bbb0b4d5da3e992aba9d7eae56d511c0a3113a3f39e199dbc0fd5789a4c1aed256280ea8299c517e043e95e29ddc00545024f3ab4c10c5917d571266549605dff5fc5be042bb6e0c017ee2bbdba6574ec379db3dad2e8712cfaaf575cac43174c185cc028662e68fed47d30374df08a4e99a643759739d2e6fa5d4a1ebaadfa89921f6d6d7e3345632c9acd22036f4446f7d6b6f487881210e51671e601f92674694c6b32ef0e4caa639311914673915164cdc446046437471a0b56fc860b979b6ff8261b0a363b14246011ff4390ad9045296573790eb5f43aef252cfe95b5a31a1019e68117526b8b7658d5b6e17558cee120f8700e9ac5ba36f2a0d8645dc264010c3b8a33d9340c53678b6069cd4999c81b8c53f8ad280c5b28ba33bed153401d6812949f6479b2d711561f59b64abfe741da366522f7d29b8859fefe1313790a752f7c501d33d3360adb3e46131df2ad9320f5e4754fb8bd4e913cec040c70dd221592e771b9f47e9901bc3e12f77fa8a0128b67e9fcad1ab9f1e71aa924abbb12e85a0fe41e2a0f7e19d6b9eeb5d708c375052a1df16c73ed0e2e0f7fd84834a6964c5835d17addc03f7a3abf5d68e3e2a0f0db6b2c4bbe74251b1c7c97f31a6a8190521f00ec6cf830b51a038498571635e4024141d8264e7c7f1d402f483c0f8fbdbe8c638c9c7d0e7b158881330ecf340395d3bb7eb4a5906c19b533dfad61a9c3378e68424268ee4abb2abb2c0d08dde3cf4b471a9822c431ba0eee168f9a5165b0540b813d7d46c5d99bcd7b628a756b2807b15c4c5b299383194781cba81e34ec18300427af4f46eabf49bd86e888ddcc91191ae3f33f81761fe734b2818afef82010372581ac8b13a3a8c2313f5ff6f9dcfc0b52103a1fa57ee7bf13b2415bf3b0b0d42281378148e387e688a97616b78e3fbf0867ea84a497370b54289b68c4d6b1d197f2f9c6fe76fcc54df5a81d9eb7a21d40603a598f0fabe659b63b40dc74d45a6d029332dc3211aae06dad2c4be3f7404048a4762d30be2b4137a258c6161a8f2bfd29a158346c648631d5894d58d2f8efaa8e07e7d00a968c027ec40b6b7fd1c2f1b1417aeb4df8ad4dba817f68098fde666b3bec38d61ed4b74c26ed335f7f68cf36be6cbb998f10f5d195837d7d91fd71b9825f5de96ad0b940d6bf9a98b46d08cdb00596d3dd4f17518de2c8171b972002acc4d639b39280cbfb559a632b5074476e28797174a1349abc5bef9a4404039180323747e89a8da4de2b1ec74df9b2a06366e17947c0d966bdd2c70a9715cff0690329645f269294fcdc831e4bf2379791b068b4546365cf0acd699b1b5eb7e51c1a10ee72bd493ac5d05aa9759af9e781947f98db7906dad373137358de4785d546fb4c95e3e68168da8f0c440ad2aa860c0527a8f3869b9df0f04ae9e88994d9313f58a221a60c4886d73e70d9bee39d6ea709055e12ce023b15cc81ee1b4560baad8dbc5377d9edefcc7ca46e1759695ce54974cb184bcb0fa669d0034e44e004b87300674b02fb645cdcd227499ba8a48e3e44becb24c626e80670fb54822f89caaad1c5e43117d9851550dde41867f069c6f937a24ba99ada3367dc54d4ef1c2d183d63291a90a78cd92c87d9f19d3ae6e1dfafd69cb07d4728da9e34bbfdc9a389babb0d6f157f6d0dfa7b9ed73ca00d28ed378304c9b366f4c866539a5b84acab9de71e167cf7dbbfb8d9a068ed32b60c47909b6e2b45ea971a9e5a1ac74c2b33941def6eea2484f085db24dc46d24d6065bd69def908ba87c3dc13967fc1f5de7390f4c35b81727272df5f9c6d6d421817c08fd98e93981ee5532d3e8b7bf2571e8d14616c4415cbeeb2b58e85649a611a019a54928fd778bdc6309109fa9e29a6a4d56fefcc73aa27c7e5232bf79842b0f59667081dc88c2849c8cbeb8e33a02b43eacb40fe19265ae11afa5037aab9a9362737d8452a1b53f3a81d7ccdbf4629bf95f5f945919962ad3677b7a8486d28caea667989b05044b887374f71a80dd1878ee910d6c52649b40b237affa2f3a9dde64b1b4160b1d5e6525a916e0a8005ec7d16e7c4cefe47fe79f4b694acec9a0fa512dc487f5b2fc71626f12d65cd4b2ed6bfec8b9e9cf95e372dde18e725524948d452018fe9812114bef446d419b9e5a9a7ae7fd687a4d75d37fd2b9436cdfacc9cd2d53549a8eeeae0b4ce3b4f1beaf3fe9fd5e7e8897464373267ce811167e6d9f6971e68a2353da8b622ecbcd37d7ae242f0c6c1585862cef39d1cd77b53dc7f34e4b4e57f52c239161607fd2c29628adbaef6426b1149a4aa75bb05a212803bb2aed21c0426395ba5697296c93f8f0dc24554d081b8c4ba28f3f0ec0d70f3cd67f3c183358082efbc632c13228ca62c68d50919755c4f57138f763bfe5565a1a1f4a7973c12bf0575942f15d240b3848c3b66cbba81537937eccb57e63d93d0a0bc228d427649db5e1f810fb38d82522cf87992243ca9aaae9c1c7b1a8154efa0d8117944018abfada4b70f053b98fc0bb75caf4b44161304213ad0ed6dc6b5dfb6f6afde9bd7ffa67ca475546737abf8ce31951880029a58581d40294cef9a8bfc2226180dc0bc218bf7ccb788d67b48836d250e6cba6fff491683d28bfbe5edef375c6fc89008e822668455a2777e9dd20fef8fa36ce818968c0e0e7d607e518cf6f330e61dfdfc3414fdc1afa0cb6e0d68d001cd32e989798e5ac2a6d277f9513ae4d52de7a484ec0b348736a4b15bdb288785ac644327960cd35b61b5b5e313fde177e5d74ac115e595e70a45d0bf18be4c3425dac8714c4e9d0e37e4ed301b2cd5e712ef071d6c2344bcc1531a227e342fd460b4088ced235c791862ea85eac8681072400e6076f7ea732e8d8d340275a96e1501de550847ac044e31ed0bfc8be10570a398e9c9adf07bbcf410b88440c17a4dfa18f3fdb48b0bd6c56d2e56be1758ab71ae1a72673e27b462da933c72151d2eb7e4848ef09483fa3a0163fb0b314c43679cba5f378f0e6fc56f64057823b6eced46b4ec56ec170131e1607b20d4500182ba68aeccd2cc9630bcdea660f6bc729e1244f48597f715d5f72e6f900c249de056856b78f1c89c74bc3408e11f4d5e42519e6b7b4ad3fc7abe1ee811ecbd0cee038e8cfb8296a188a410fb0baa73a40f614422e20291cc0a1e6ba61f6baf2707080df4f79966bdcb3b555f488fb58e294df376a240137c4bd7d8853d0b932c9fbac23df38f2be99a17b351f9bcc0c8961cb10fedf95890bba9db27304a9aeae383c71880ed2d5429d67cd7013480dd4ba81de5fcffcbd143b758b8948d9920a3d4e6e4d70f6b43458ec5c0994925a1073c8a49cdc07829597562593994e737d1ac61df02d678ec8ea899c94b58c6bc90b4d7ed0b3762b17ec876a65a65930b768292b7953792b5d8fab7e9a1be0d7c1ef8073b8413ee7b6e8bd0bc3a5a7f857bf2f09b445fa56d0015d32805a485181293a19cffa2ec07372d2e3fcaa32aa17f03aef8465ab84a8c0a829bdfaa6ac32aa3089d33e7c8d517771e2ae251a2c7ca50e0d126e198a56e12eee62d16f07ca88b380b2293082c7781bff7f0f6b216d72b0a1b294d664c9b29b6b49d4bae48030536057b60836208b5209f1b2ecfc2976dece375d18d112923f5cc05217613d6c34379deed5cd3881d419f663ddffbabad3ecc3c4e70e20efa80fe3ccfe6b72798a54fc7e419f786f3ec587994e3ff824b69ab21524e1d52fe583fe0a7e18ff13c004dd95b563b70f4bd6fd7c561420137fe78c467b7c0bfad030862e06ab6ded1b1d9dc36cfa810cd822d47b2627fb981f4da4cedb77a5714c9b9e5d62457c09daaeab00a5c32314a88f7673b337d2f5c888e08ccff826bc78a0fcc5eea12e81efda1bb0bd9b99a35b43514052f8f42d39b8142708fd6b0a0bb0486106220c83e1865ae11d571eda41ab47d2970134d0da96c6a3be5b3afd170efe24affc5e05b581e36e5949f660f8cebb5e6e2215897ab7408995602047bd1c26ada9632ac85d01ef9761413d31cce628515ee47b48fbd50b8f4ad9dd9781b0d3d4737c1699b78beb6eee6893d5d0f50f16b27cbc38b698544771bbad0c319117f02c7aa8b9b10d166cf2338f9e24644ed30025021659d877e64a20019e3b9c40c1f82fe83422bdb493f13612c5c97701e33128426a7ab4e910f08dcf624922a62a7a9cc09ff3bc042efe35d7c2378e65fdf9ab49ea6b4eb47108dd09899560cc4c5bd30838da0c37decf9bc2870f082223ce2897b9bd9e2df619df031e9814787961bdc410f3c3901f730d5b5398c0769568c9dc1752bd8abbb7c14a973caf6feaba27ae68080256bbe996349d8f8f48ec06debf78d88a79b18f1fe029401c810a31d910627132e3a0a0374fb215e1166dd82c73b88c76923f6ac036d0e1280f1c0b1ef9ffdbfa8eaafa871115f9ca2ae5b058aff94e48c6871de2ced19b9dd1a4e14e2c407b51894a7e21f8b732f2d1041085b3cc96be519881055abf9e5df8923be7386c86e9e82c5f9864709f47e6940906b7a99e7d7bc005032dcc7958e615b67a4e71170fcd12d38e46a4baf966d1842b76eb77c0991715f7e7d89b6de8d1b7db8374391826174bac900284cbdcf65bff785b815de974150911e974c101a2bbdba514737f7ac67c237f9eec57f94a78f92d122823d9730a4864a36776951c3882\n"); + assertTrue(Hex.toHexString(s), Arrays.areEqual(expected, s)); + + sig = Signature.getInstance("SLH-DSA", "BC"); + + sig.initVerify(kp.getPublic()); + + sig.update(msg, 0, msg.length); + + assertTrue(sig.verify(s)); + } + + public void testSLHDSARandomPrehashSigSHA2() + throws Exception + { + SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3" + + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")); + byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); + + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC"); + + kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, random); + + KeyPair kp = kpg.generateKeyPair(); + + Signature sig = Signature.getInstance("SLH-DSA", "BC"); + + sig.initSign(kp.getPrivate(), new FixedSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"))); + + sig.update(msg, 0, msg.length); + + byte[] s = sig.sign(); + byte[] expected = Hex.decode("97abf8262ecc8090d912c7aab1d951fffe1d9aa683a5565490221122f945825b2ac44a170d76442f7fc9d8479c05fc5c044bef94a5007cb258ed8efeb8f35e30837001c505dfe87196966c3b2591d7ffefded746660ffadac38782fc9e887bd324e744023b2520d60b6b6916b0285a42e4943c476434754b1651d1e8414070e65933d5916d66359b682c3568e893083e8fbc333f6bfa9e1584cfe0b688be3a5b22e6fefd77ff194597a17c275251598d94c68e73a1aee194f80ebbbf1a43eeacee49907870366d6eff0a85e609e5a8cdb3067b0412c5d4e62591f78ddb8b90c8fab47aa311c6731aaf1b8b6449173bb4062873ddc668978b4042d369bcb3e645369dfe15cd1d6216db70094597bd0c5b8c8cd81c1919fea04ff18683716c8b85c3508c5a21307f5c47810c27c4c3718deb7d714da3b1a21831f7f46e3cb81c42d89acca9040845a0207e1f05843df19bbef671e6bcffab6c13ee26c81bdae2823ab931933ab4528ab725c3c2483e3a4d85a07f089e74ab31a1813ce8593f0c3cd69e0fa54010ae149ca1a7c8afd0006b9244fde5fd3dc295c499bec19bb43527f7d6c9333ec9cab552b8971e130b689a7cea652239bea9efa132ce57a4c890ca5316b82425020114554b5c740d9c26b2ed736755984bdc83af939529254f9535f6926820d4fdbfec80ce88704c4a916e1a1641edf36dc9f2e0c4a68bec42e86c5cbc63acac1bb7126cb1046caeaf82e6c8655e82ef599a01bf9f4b7685b9b8957aa22e27ad8a5ee9addd86189562da654d69b90d31fb25e5a67ca50fff17fa8f7798ff7773d0b715b3958d043503b0240bf36936b4f8330c1c8b09fecd0303c5969d251f37423db8f83c79a093d7989fe2138cb696bdbed6e1dca17d5f18b5bbdb8629fc36a97599fc29aa792204976fabf826f670150df32d3f8670d600d3b703a1e2dcdc314cb9f4a42384ae90ee75967dbb2509077cf63ca42da5ec94ff32409440e47280bfb838a4e4fd2f0c078227718a6e7ab20fd0465e5aab1a3a29c30f0aecd55f0ff760862a1aa13c0db77411cdb48a34a95f716224fcd4a39bcd828f668b7d5632050a5256c644f2a46001998cfb11afaf70794495a6c61e33e8eb01011225364f9e8503ee9272a6174ae35622e3a0e808b2ec5aaf55c955680a5d4df3717f08207d4602a429b0f5adc0a071ce29b322bd3dacc755ddb2d3190c1b7f40b539293221ec98a206daaace78eb178cc47f3d5f2c3f224a6fc32090a0d1591c9d061125ced2be9e9585f2bb07f6b819b1da276e435a191fefbe6b9d44563da04f5731ae33fcd67ac1ec6875e0d1f8bfcad6d947d173cfcdd6aec22365af44e19168d1c0e6ba5f02b4402ec2b719f94d7097ead10f133e8cb675e4a34558ae77a032ce082e12c0c6badb5db19e92fd1303397db5753d9afa4d18e57f9cc26e8b5bd102b77eec3bc47f16babb451ed4a69ddff494f8a5dcfc1b5f8bb9400ed508214084a6065cb7d0a8efb8a073e3d91905dc8f926cbe20b6b3a0beb9a2d4dd12f70341e80ed59375ad2c38650f9bec4db036b344d7e8fd9919de04d14a4f19d2e91a123e65221267a7878121d61104a6594003e605f45e230892bf8d0fe13af8404adb1dc5876917a4dfe435edccc65f15bb7ce066fed76d3f02ca16be94187fb7f37b5379eea8da682f958d263c42f45cfa181fead2b31cf893de43a9041d414cb1ef4424d95741b8e3a74ce7b2dbe16ef0fb4d596196c09d493380d9b49c6180801bb52d6497fe9ab692a4afc98124e80d63ddd1313b7b9c31622fa1cfb7f7c413684fe15ee4b33b51e5bafaa6d887fd38c334b65dee3f729211f34b776cc9eff13eff293a1b3055f5ae083a50c667b988b5996a2db63528eb6fdd4083a5d53df26d6bf8a6b5a4b981cc835617d928358c1b3ccc5dc87e3fc46f4050af2fc020fee26b84af757715ab9f63797e48778b245c3aa5d9f6401dff64a475421b0c1bd59f0ec4c39f736cacf0dd9ebe2b170586902addf1493356e9e4646133e8a118975219b672451d9bf480ea3db866f18fe5675eaf70632abf47e11bb16e1e1ab38dde2ba9bc2f8365491c3f82ba6113c44a0c3d00e2c8eff095270409058b43dec29a4838bda04fedc68ef3c3e8e2d176ae5f98278033dca09237a03cf89edb2040b3e66087ca363e1c07046748f5cd515141c481ea4280d172c1d53c56fe813c29fc8a798fe362f6a578a63a0879bb25090a425fd4806698c94af3f0771f923fdb51953753b7a705a49c1c25c38ad203a696d40079274813b5e2168b930fc646c771ec48870521ba5eedabdb0d5ae3e5efa24e86132e0e487bc0bf42721125518a63d08f8bf7f05f4afbd2b939bf74a3ac892aed06d9fff944e2e333f951e99109247aa63265d2652bdc528b569639fd0dc16c03666300bd04873ab72f95e98bd6c9ec60b3f29c2f1bcd986100a70c37421352a4eebcb58cdafc4dbc867438887bae9b03ba8412e7b118e5381707c394cf428047f27a5255dd86bb77adad9fa1b8ec93f845009b58b837a04fed5197ca8d8acf4fec81e61b04a40bbecd67c30a490ebb2c18bba756b307607af3f121e772e5f89a90a138aacc92d613b0c36fc508fc940e7f515e5c0010351c865e954a8bdbc06e7ef209b776f77396e64d01a5eb13fa129377effcd77b14fba76f5c40fd9b9322a8396993df67b491eb462f2c38702ee91fcc18f9bd217fa4c54827a90b949a7d491420d544ca0ff11a22233563527404b8ddf0b04260346fa1042aee73fa1173d77a1d2485029efa6db4a7a79e169a7029c7be5ca51d864cb447c3f9de535e21a45d9703f00c62c0a61aa07ea6ba7a62ca524bb797df74731f6a7adc356a9adb84389a42770d105d7b8987e00ee3116d49dde57eba0b4ca7dc8eddebf3f08909a3e2c41a4f94431d59d15053b27d5d48f0bb531eaf938452562de653eb889ecbeb0920f7c9a8c3e4c3839ab32e54e4cabd7dcbcc922150271539db17845ca82d09064b262066e82b514322c8391693d6c5a90cf63f69a36bcaa995e9fa0896634ad316c9f20a987d72dd9ba90855c313af0bef8db57fd2af833371116617680fa0359eb91d1f4e9978141a83fe4ea4bb7b8c7d5a418b4709376f47b5b2c9e25b89e9d9cc45edf3a8ccd1ccff3e4e7b6f0d7d1e5a80e8d8882f2e726db164add7d9795f47261e0a668f7d83b25803182af4c2fcd68e1f2b142bbb8dc15c07edbe583d5cdcc0f3394934a6d4020bcb3511ae23fe6a6b9de1d1c503014b172f5814ff655f9dec0fc065644ecbfbe879daae4646ef510900fc73101190eb26cc0e563f1b5a204826d84397badfb796f32b70beed7848fe58970dbfc36fd70fd2697efcd069bd92bf9109d0e4aa9419616097e8a4ed00042c7376b3f03da61b61d959bd43b398de469092918c08213fe31e6e95a2cd650abdac660b15a765481a2f2bc57862593518d2a90d628b550ae9c5a3d9047e12cf4d060a888a1266e4e9068feb5a1373c5dc806108acfd476af6b77153a5222e0ce624e06bf56ef1cca69f7fccb3e63c6c288e3c22ab86ae0309ef53490143e96da053b686a0d876ee3d675732be2c2ab87cabb2b089f8b6be38e9705ccc421c4ab153dbf16f3997e3f1b40fddfdee401139155cc3bcde2aa0667c99bdc381415e4e8395f0fa7b3ae0e5a73e35f66c8a327705637698578ed707f3bf1463acb68891a36857ed96cf5f21230b2026324359cc06244bea558d827b80f79eee48ec9aa55bf29ee872986b1320abaf5bf6b36836c7eaba504e8ab6dcb070d6e55616932a69f0aa88825f590ca2310f0306fb7cdf97961048174999c18ef0cbea0216c2944f43cfceb998a9fa2977815b2043aefc4a5565a88b0c41368dc47ab881d2d8ae676738415a73b0efe904964c4ee25ba0addbacb3f41870ef0ab91150d3363bb5f938b60b3a6badee17da834c3a885a32cd8f1cff4fe177065554f41c537f57f8360fe804701fc8ae7b2410bbaafa5bf8a735f263ab5fa9e3f786a188b2e5e187fb33486f98b6dc251ce723ea1b91a3b93d9026102467d98e3c2f144b2bffd60b493d986b84947c4d0b26c02923e40e9177339abfa48aec841cd6e086d5bed7339ad84a6470851fd5cf5ec50b999041092d6daa210e47c746f62d5eb4c00e84c5a92c0a1fc7a488739fe3adbb71473b4557fb4a12fac2e9c33afec4404d3d60efda9b21c307378dae06f8485d7f48591ce6e37bd43b14a44497b08ea071a941c88285abfbf6a2176adfdf36db642312a7422e17d9a9dd995406ef6927d4f8276f0e400209460ef1707f0998562bc1e25ba7696e4c0886e80f5815cb8f1e6e4435f8c4bbe9618f9cd9c5e2ee434f5d81abaed382e5ee08f18c7d491311e51b447305f2f7d0fc178ed8e05ea525a7b311e6287ca879ac17d6d6629dd5244baed1842ef2f92ba4c1121772e83a61f913158eab6dc3f43575ce2ba434e19e9dcb61668a9c0392f03dfc736827ccd0dad0cfbb16746e9d79ffd782c31614be641d970dce41d2238d8bcd06d9c31eaf3ed7798c6bed444361eaa29a24716955fb7d8a46ea5e5dd0d7369d99969d864e99a8bfcdd591e32166f687f163a3b01fb97e1552b4f40a243b0b6275a07cce9edf93e2b380822c63865aa6f1ca8f9eaf3ce0053fcb8a3f201ee750a24536baed662979bbd13c639ef81dad9ade1bfff5b54d89d3f92920e2c29913a4038b16926c9152857fc7ed4c74af5eee07e716a9f1fba3260a17d37d2101e0f777bca6e399f8d34227bebfa76c0b5acfbf0ad5b22c37f1cef28e23eb20bcf213f0ba8bede81b9a855f356152ab72aaac498b74d4c452f58d0b88e20704a4472f0b7f2ba7bec55cf0510cc09cc8111b8b12b87a8af18ebe301fbcaa07e8f1bc2cab769334bdc639b9843161461eac15bc9c80000e32be985108c7b45eebee8acbceff65b52cad542aac52626585b250c95d08292108f7d612c273f34ad0edb0ef3d1047d8cf9ab52d4ea08074776783b84fe29f0c202dbe090af676058bf6bb1d227aea4b7f1c5f08ab64099e5499b2f2d34cb5638104aca898e3915aeaeeab1ed10942751e755cce70605b0d3bcc65db4d5c0cbb25fbf8ed83850a1f3183430ebdea232afd14337fb123a2087ec3d5c2322eb4a195d8d9589d5378a4d787061b10d1bb57abec43e2d9c36c4e7b2405f04dcb629e57021fef2c1a8aa6ab36e779b98711d1fa53185c9842a28e708b2f814c066a88638996f098fb01dcc8687ac77c7897afdfca78e68129dfb458b05c4b174421197d911b71805a5673862f18c33810f4e7fb951ab060eca7d3b1a5f04f4d96cc63b09ddd3de8d6fcf4da5e639df75cec579463464eba92ade5926803a127fc7ae9d4b57cc604ebb350076b81c52a5c6d7257139f26fe04cff832ca5da4d2796e637655f79d9397249f672ea613ff55490bb8ad00e7be51aeb527132d2044eeb60112b48fb8ffdd2baa37061b96734291d71f29057307d3c06149925dfaf4502a42ff277496f835bafd5f98237209924e86f6999897ba32b9b830526b44a7af2b1f61fb00ade519983e93f3eb481e2792943a0da42027ef374e8713e06447bca767b9bc28f37e0700385afa391e61d00d90e2d314349d6f24f12cc26974c4218196cc18623a0d92ffb22f3f86437c182cbbdfae0d38075485a414c0c57ea4b34ec94e42bd6dc4476560672b316b2e618acbcebbeb2694d585d97685d0cbb3afdd1130d137de6b36c9992013064bb205b62f7ab521f0fff25c11b5fc380ea82ad9aa499dd37aa03053acfff8e266402756d8c07d36d5bc4775acebc197d301bed7d87fd09db7a96cbcc3baf8ea9f8908b7c6c69d9663c4894b562337d48e502609d9dc3709aa44cb3b09b81f735fc511d48c7230282ac2c9ba7cc6d6afe03ff02495f8fcd18f0e02ca99c789c99651da7262128332eb514637621af85a187c8fa219fcf4881a6d2dba360a0e22ea46011e2e254fe37f2efd87ea010524de715777218c91e9faa354fbf5250b73bef97365818e11a632aea1c29b98a30b7855be26f4392e540756810be7960cb7a3de41e7f03a03e57ff62216445899bb86f99bb3248b60de1dd9ed520fabc7db68c838c4ce8b34508bb0ad4351bb967e8c10777b2f290e536672b808e00563423e8b882a400b5feae1a0c1548447632d9ce45cfc69211143164f8264e1c0a985f121a272c3b2825a109373b7a27fa8e8172f1272f464d415b2c64100860c37102d2f9e75bda0f829d37be540950873dd05cfb9d20c91e9af38d7d489bd156220f7bb44323ac54229cda7c79ef133e27649f17854afe475bcd73b44b166de455cec19f3e50d8c32e4eacdd9d10d80756393144d8b04251769317a9eef49b0af63d9913daefa9b182b58886d1319d8ae6e0ad39e1d6d7c09e062c9bba257062b85655056b347f5fc5951db25767a05d14ab3180d4fe67f99d6fa566ffd99783b8cc48a95e77f71f21693ceb11b53e660d6d7bae6beef1418269613bd4005887b2a689fea9d0b8aed26a702794055a7155f6b384c93c9933e173719c6b4423f4f439cccb7e8151d5f17cfadfd8907f44fcc5ede6da12eadce5c4e71e7d62db34c5015734f7398c5486610fd2f513ab53cab2c2bfb5ffed441519daa946fbcc61d957f3d907b8c172d60667e9390a859560d302361046496c7bcd9d85effc160e1d5439260d0c2e521c721ade0bdcbc850dc5ab28a9df843ddbe62eefff6f3a9918e709b5103c77495118741df05cf2b51bddfe719d4838c526a254f5ca6b7ba9a0cc094b508a56ff0d63543b9ccc54049af61367d75a25ce6709f6b1c03bcfd7d47b7a330cf29d2f9ce8efc01d4813fcc3776ccc0f15743b0043c5d52261510cac6690e5e6ba5301745ce20fb83aa2da52ba309cf8b1cf8f0cef3331ac734207318d99cab8233eda7083cbe2ac0f8ca7f6499da3b36ee4fb61ee55a4c79d8660639e45dcb37eee87473d923e95237a5096f36bbbf8573444987533733537d578d474be1e2712e51d8e03e51e3479cf14799ba6ceda11c139855ec41f1406398dccfb7ecabf09e176e24c44a024cd6073182ac1f58cfb23bf6aadc375278f695709cc5e1d059dbf9cf5701aaefe8b43e5ef81b58090aa4ae41d7ac76905f6d504cbb3b8f66a6b9b74eb34de83431f7a03a9a0658627b07ba1dfd3f22f5af9fbf1c6d41d6b3bdfe6574cef264fe88085a80d9f2b011110c92486b81b3f6008d904708b98a061494c57476837ebb0f5f9445ee14585b6fd7e8245a06b4763345dcf0289b2bfbd8bd90a6e5faf749a7d5b96158028791542a38d06112f2facb7b894fad214868fc5abf2b960a6ad8371b2dbc41c52b16e50e89f22a25deccea1b28b334866bf4afc7c50ded23fb8029d9d988bce010f2cd487c2921683704e7127b0dffe8daf8021462a0068d4b42ca50c5cb96ac80ae73191c7af7af0bd228acd8dbb0b50066ca9af2b0c3fbe576fe956f8f37e498770ecb29e859f5c7c0b97e5ab51f671e80db0815aa3b74434fc7b716017aaf4e43533cf5c7d042bc3b5e4aade7df0a51e0f027c80bbefd2f5826d40d7e94ca8283ee492f9fa04b7a25a483c44b3ae79f9216b8a5607ae9f05e1fe39b95f589114942c176589d56b2d608275d0588c09f01b12e298907415370a6a907caf5a8d0f9e7eab5bebf3b63868b0d3e9631ecdc33aae40854ec63a2d77cd0093a0409bc68fa5b817d308fe2d01c76617563ea0631bb5252e875b4f870cf486304875b5248e18108eff0e9aacfa5a8fd8ac65fb25bd3b8171c7e348e095c9ff9d4aee7d57ef886c88bebcda35823d5df6d710fbdc7ded368234c98f08398ae117036cbda8441ab85e54766395b485480e552aed66d8b1eea979d420206c5342ed809f331f9aa750c8b69748ad7093eecfa7d1293ebf2eeeea810b6b41cb910635ed7ef69d7e8573c31e5bbf1261759aee31fc75eef1d91ad8cca33234ca51c2422cda19a88ceed475c31e8b7177bd45adf82b12d66f017d9f6438477989809f9b1a6005715170baf82bd82f4af747bb2d92ea1bfe874334b837e4fa503ea999df417aecc023cf44b002611d0fe34f526384aff6af39690f88707206e93a2b2d4d67cecca282dc1a1770ddd4ba03587cef40a9c6456e001b329b48c2b5ef9c139cfcd8d80024bc43582ee4b29cc5c7bcf62b4a34b0b2fbc191ac8a53e9ea1c4aa57bbfbfc5ca202857805fb6d7d89504a8e192279bbd4b3ac2a9ec2cff0c598d32f892aefe3d5c1de7dced020e0892297f947833b0821477a46e6a2019bb8c1316bf6543dad419babc2dc9066c580f3c5cf41aa0747419d410ee3acebaa3467118561cc1a20e50e468aa112a7177d68d47685f58d19115c509228c1c3a65c44fcee6a7fc83c6ab99d7656c952c2c0d9e5a2685734f1a3501703b66cc39600bec017edc40d26fd8696b72b751b1bfea966dcb4d075166e7386e76ba78ea39829be87647ed4e533e37701c5f6846694ee4d6a81350d8d2e67e8639b405bfe3a1d9c4ced6c8db7e86f2961b032c2b663557d5127228c69ce0a5cf77b6948857004263d510803f418c501acd83f1569e5c20ec55eaff2a364a62fc14c1243a78c49e7eb1a571883d584a2cb26a4341a292cb908ed5142d6d7c969ccaa7871f29aa739f7906657b076642493f6ebcd4bdc7501211861014539cd9173cf2a80a9a30b04c297810a701430538b0d4aa4594ef98c62ff89d43b1eac325e2bc4b0988548b0a4826c22445cded4cc6a5335da96f3c339800d3fcbbc0859f4f035d13438d5dc693145f4360c1f0f91801bc1b10da717fa42a41725f13380b6d20a349c4d33c1425d08864e2b99df50257005727dae94ac4f6a8f0f966351fc5b7d47d081e362440a1f8dd461cc73a2d1f342a6084bdd2542302efa964411d1116202ae4e0cc50e290e5cea8d87aa07b494d1cf8314fdf4d5db680676f06bce77739e77011774c510149c6fbfa38a8c52063cd446572b8ec4dc8f71a5386e08a55f53b0ab523a4847abc7e43086b5bdfe50042d10631842b1fa63db9a53a217e40aa27d84bc9f641a2efc138d6779e5210cbe477dd5b34b033a804be78b96125af980608df69393cbd83f722b20f2b2fa462f0d6f4252c3e451892be8d02cc1c0825d5b442199a4bfc22f262e2a1904aeb8631c7f794d939de6a3571c92ba91daf8290495ad0b24f529907b5cbb56adfeee47e35008d4f0c10df2608d1fa679a688df6ff1be7cd6633e7e0449745ecd513bd2778355f0eea6b75f4000a3b7a087fc950eca10e39e7bc6e89bcb2ad831430da37a1ec6fab6227c1a01ba8aa83530d201fa7216b04cd962b1b21a82bb47a7e31a363b34715b6b3b3ff23f6c6620be3460ab2fd2e093b05141091393312367c704a0bf1543eef068b6e9f38991dac66f1fd4da50387b099e4136b296c08c225d14af62c0fc084a48100b9938c5cff0472de42f3808866175b343ea19fdfaf32913cf6ad715f09c26368efed9b50342034108d86aef25b4ded8a18b8b4c8f56684a0fe1d3afe04e0956158b31b0a3420c22e2d48589f8a398398933f1aefa06e4f2fcd68fc60d5f426495c9b45f225747e1325d451d2d00587ad226b525e2105d4d67da17ec2f869e206a7ac6a34d6b777dab3d9b57f932af5c9f1c07b46d14dd1c7c9aea280082bb97c6912c49e634d75ebe6df6c13e9ea525ddc986f35439ec088930209308b213741b842bec6770403d8b15b96550e72429a2b2b48d73b2ab273f7146139de8b5c9326172f3ae5f58d5f6d197099a4738338c6007d707068be32876b07c684ab643c9b850d7cd321c13fe6535ad3f5bb0771cf9d8e9040d97b3c7130bfb6b74b658a1169b9e5686b652b29df367a8996e4b330160a1f6884209ffef3cb4bfd267c3a9f8986eb67293b59ae2c6e9f0e65791c662e8e8f6287cd47bdf8e9a868cc5683fe34eda17ae970fb09e56a22302de1daea74e3905136069136b1116c58011365bf18e5b7cc2723579c4a88ab19b7a1fe6049086726dcf4976cd44ea56babba182b93cf54db46167e1af13aaf9f4637fc5660284eca8cd3965f2b866d7824669f3c8d395b8f6cab85bdf61435c8df41b1f49dcb03c00f985768b7f6a7c97eec6ab31fc3c487de95b806a72ebe0b760cf306ead0a6374af57e2604f492ca3408f331c5f4557bebb57f886c07fedef9c32ff0724c38b51a6a796ed446e03f6ddbdd4b248e39925d8c52e1e40addea755803fa0b32b03f26a786863c569faf5fa399c648bbe94761230d38cdce923202df658bcda5342300d8c485a3e2878496fa64b5c60da3426ecf44ef74346b4a2109a30020fca529ebca031d1ff1c37c6e96d245067aaba18822215b9b14e07cfb613a6810fd7256ac926318d5c20e317816cc191f25db9930b03e301e86e052f108f7d6050f9f5436e03759072c4f66c47fbd7f99d8a16cade5b2586dbc6fd9cca63cfa6f01c35431fab1e07da99abb7c8ea81f1f3b7b61168eb55410c193059635997a289b95bc4f055cb48e3422786be082d3fe81ddd8c7724f509f265f88e8dc5735912f1f633256d168ae8348809ddad7c0893c244c41f9f83bc2c2bd9916a47a2ad0e0452694c01f1bd5535521cdff8756d70902cd34fb74ad0bff2a0a4be8a9ab9d0ffaccd31bbe7ebaafed0628592f5c4b268697719662b1780917d5446eba299e94e031b8e6bf5796eebf13515e5a34d1ce916a8e1c1692288f515b5239b64cf038d3e72fc20c68b4a3317b70120638d11e17e44c98578b596780ded9e13d3456329ce22cc4a5966a581347f3cb19f9d49b781caa25970a591cd04b23ae6e62d3afe692e6b29f46f12de0cc5aaa1a32e34b4633ca53587b362fa0209093f36fbe683a46464ba794ed9e03747f46aed2771a5c407f7595c3f6839fc77138e68cb32b649d5f8a603442430fa09e9d9abbb31aba1c9024a64c8c6682d3e4f150a5f4b9d877873a1984235d1271304b3baa775c4cdd6d8c0a1e579170fc5ea99ed4ffaf86a325932fcefc5ecda2b5773384b9c67bfbd7511a21290143adaa7c7d735295e680a9b113ab64e9bd15ae72769e947732a58e33479f2b184b9bed85cf766abbac27ae8a5724c641ed23ebe9b2a718cb0d1c3e23085a1ae90e9a497904cd1750ed6d5475f3c1266bff776b89b4ecb4423ebcd3512c246d209ef51994fd6e040f29639f784c2238f1d05ad5612be0bbc2285e70b44fa2b04ca409f1c221a8d07b8852817d0f21327f39bb0114d728ba005a4e8122cfc20f03836c0f41f5f8b4bb34f06ecdfc16281ebe99d9f3e34b8f744f8e7f68f36940f45e9a1b9b68d8b17048e3065882886a666301828fd9588a27719cbcdd07188524a30ccc1c8f9ec4a1def30b4bf9ceecece9e9ab3a7ce39ddbeb697f4e4e2ab8ac7d9fb149d7cd02752ac2ee2484412b0493a6fbbf434d314eb996fb58ff008ace1833cfc5b8834d899125c79f66253801d5d91bce8ab1515aaa52e3807011437b51eb8b14053e2baf4916e9fb675a810f414dd113a3029ffe153c83cfbb41af60b43949312cd97e77d2dbcba3c7f278ef916ba71ed3f041c113584654b357e79dd7e48be195620a30fd59916932129bce4ee71566f033452395ca6f74cea2d674d7756677a9a1db9fc9c91d06bfc3406ad56699454b46b8a8a4d43c850fc32b7b83853e0b01457faa4ab700bccc90415ed67e92244e43172fd7e1f0a8dc6d5425a2cf61a8ab1ec210c16566de4def8a5341c4744d386fd7676cba7a8b614cccf35d709758169dfc7c8d4f363e696c742c3b4b949b09c8239b2074c0209c27f1ccf57a246ffa3255b91313b9b0951863973434c43d03b71c25762e5a2b05074d74cbd85b40f5c783a034ca2f7c1e3e2ef116404b439166acf6714de2a947784142418f1e1e60459275dc93d785166cdad6d1d688774e9dfa59e0bc3095eedddf8abefb727524db25916a283dc10bcf1ab99c7c564086a34778ea1bd3e09d3c5e2e8cf02d3fc1e335ec3b78412d31bed7267b61ba0641fae39a0ccc697e1cb95a3d5225e6f7e9cb22922662d53775718d824bda63478a9d593e28ddfda63d2979248ecf18ee86b047f4b92a863eef48a8172802e3dacb7ccd2dd0f5ad6776435c1833e0c2e1eff78412316c3c2e92b8bc5bbc56d6d70a2add1475588eaa47e1a15863abb8f07b5c8bbe6f0e5652ed55b45be566533972e286eb3fb5cb64ad108f417d7183f19ec4e118343c57540f59ec712c44ef56102b233eb5546b9ec1a8e9eea1f26b5dbbc4afac5c0d8106eee4842f05d7653e147a9be7c7810c2b0a6238f1f4ba61127ddc523ebd68e01541b761ebaae6b3753cefa35f7ffe9fdd8582a91886a23e3cfc42b560befecc5c07e259698a1d8f015d2472b527290aaf51363c014fd756b18c616d163c9786bbe373d9e07e9c409f618eba278966a09f3949f9772c254255c297931aed9a265c692d20e32fd8198515559d7b11749630492f3a90cad732f4e6ab19d220cfea10ba1f374fd9d5f6d532ce62d7cada32c99d9808f8fa6697f3a94c264793122ffa03feaad79f379ac35924209cb4fc1200bca2d6553bd9a92d0d077e2ad1cf340e53ef5c83bbaa8c36d9a2e09e70258fc26a7c0b905354f12ab2c51f38bbf1c40c65e2ed22b8778ed52d164b4c4e48a02234ca1a43f65a6f25a55d5b1b42952706f9eb5a2dc79405cb456ad57f530d03ebaa7cf15859a01ba1cec9eff7029c5af310bd319bb6e22204f8515aa592fce3eebbfa92931fd3ab258c0bc18346f06d9d0a56195c61b7f5a58dd5378286bb7e2c4ce32c9409cdb8c214a3fa94612f371c012c5e83e3cfc065f87e03a27ec00f4435b5de8f865bc274a302ec6a808473b0b303466ae36bae92071f9343299bb06006666dd716b39cb28a06816da8344f93fd0ffb19039e30a053ea80cdc78a881730ae50d1049252e75bcbb0b5e72c532bde2725be61b47eab76b1231afe90da477974c2ecc6e0f80a38263d2b47f15ec8de44357496c9cce4b7dfacf729432d2ff712d95416574161c67ec8926a7af9c23c20e9e0ffc2c908fd120d6dc5da1622118cd98e49b0ed330088408028369a67e5cd9a40c055e342cb83410f15b074cea11928d1b963dbc1f2689ac9f74fa4d27a5cc4273cb130a86c66c76bb29c68aa5ce4761b8b3ece012e598c8f95f06266f65067db96a8d7a1ff8aac507ec9c28af3affedd3d033d61aa3af1221a664bc385dde601890bc1c359bc8c6b9fa0e3489de084cf67ca52af0215349dcbb810284f8b363b8115df6277922f1d1dcd1aa7de365bcda4e73ed5ea6b9066a98e2f3372afbfebf21b11ac98daa04f66f67e65feed614d4fad3aeb376a2fba2cd7517b71e8139ff5d550c588cb0ced6927bb18814e2d031739447218d03ad1ed8ea720fbedd968dedf50d65ff36c33a4dbb42f97615c585f537ed992a4d9f9ddcf236177357db565434d679298cb8b72dec3b1db2a43518d80fbb41b43d85880638555d664f4625b843a44b303f29660283e62a2f720438810b12eed5793e2d144d1e873c44c03dec5a99d564ac3d6a44869ae9d9775d786b4273d97459848913dfeecfae2e23cefcfa47a400ac27e6914135b4f2bbeff8e83fdb47425b8a5372733647a1d50905c5816559414bbf11a282ed793b3dc12aea60c102001c92a7b5be33ce2fc41bf0561926fcd6987f218592045ac0426316be2b44937e7c309197e01d19780d39a02c3b010caef6f26f5d01e0a54cbe3b61d24f16bf66358eff925ed848810b807b322e0ff31037fe5163919a687d3e1d7559d66108ca4e7e5d810a07222ec293538f832d43c926ad09e7f281f71289809849f34857e07e127e20c55d0071ba82c13f1d7e3530cacb505780e25c9f7d823fb19de0b116a245ffec4d34ea99e704bfde488d92f942dd738f2cbd3f5e384e032c9eea8a3cd235cf1712ab98e3c20ee2645bfbf5b0316c1bcdae9ead022b64481d64ce37a1bbf9c90b49c9bc6cb55c07ce51df1764c7e03184ab524012d136ce289a6fb8a15c48113b314ef6dfe32c76050517326246a74b080038e8d3941f0b5cd6782da7fb4e86dda204a62f49da9942ca19d703c483bf825ada5af1de7a82e8351589b3748771f9ed48e34aeed42eed22186c91eef6598df00ca9844a2c7041c6ebe9bc63eb1a91b6a49700cd545fe701362e6750e4d755f656b557b9e8a4d8bf1f019032a5a6226830b98485c1f0fd1329b9cf7ccbe3c6620f4ac2c5dfea9b5b89c704ea4130a8431f4bd6fa02cc1be30fe0609479223ee9fda764d759f2b093075bd977b0a2e4f7fbc2cf1767eaf5f23303a15113d3c501e4197efbb404319be08ce0e030eee54e33e59fe78d5076901a37bd46dc54ed329cf2e0c2af67ea99fb95b653c0f1e150c081773ca0c8d99f8f0c49b6ef6ed538d5210b13ec2a3bd85174ce90bd3addf0f0ecbb5c1a9a53547971c5179a03a10e34d297068a9cba538c27a8a022070b985dd84b94d6a1874547389e4fd31d93e57c4ae6b31152897802a5b9883d9c4415064e89737b56e33d70627f6f15996c5ce7494caf4a55c014468eec9f84294b731ff9c38daf38dbc85995a4894d2405575fe2de7091a09dded8b5b43c1c7cb716a81317fd71a1743c502c6b84decaadf21fdbbdc668c2b6454704d025aeb9c3398dfc156c5006950af70e963d541c6508b46cfc95f8e02c957378e82bb1be9c7e525d1501c4f0ef2c0371507869111a5b4782bb86dfbaccb76c78a533e7bc33e1a06e01b717fbd4feae95b7aaa5747e83ecec56e643572d886afe7ac6c07ef11929492da28c7313d337ce8d5d294886fdc8da4572e5047c44f0095f85dfe548c313f56c9b43484ebd5c9452fc57fb943af3f1893aa5574f9bdec0e686ea2359f37343913eefa3cd921f36576902980edbf71cff0856c01565220c7468015c85fe107d95834c36080d67d3f79c18ad9be238687ee3a2b665e7706b62660f7dd4f735779f81c72343bd755e8cdbeaa30fee1c31af79118b2579206fa2201b4776df802340062432e929ad4624648b05aa8bba638b1155f9edecc108d65646b153c1299e48c4f0898fca9d096502f07599ed198d079ef2a1f5769cf900c29c74261fce73b2bedfa1033beba9a4be9d2a1207ee0ae1dfbb0e0ee5cf5846b4acb583ca052876749761fc1b9d5e8e50c227703f1c24b3423dd0b8d952de9d6cfbc9732b155433bc3224ee5d5bb216a501ba10d6b35eef3c53c92aa5fa842ca0656cbe3cfdb706221e13df1d50dace07ca92540b539b9150ec59f64b0d094314f0400e3ffd83b36ef7057bf1d4f463cfea5bedeb2939f27df42197ab868c9b20c2281f273dd63d0e84dc948cb187e16c45a65b0fb5948da3bc519de12bb27b8bd1569ce1dda65ff9f2f493178f0296d11ca87fd651ea0956b43a04f9b6baedaa0e890ae84ec4794ba7113b0be9a7de46271088378254ea173063543ab891e7890db9c9a95cae5a2082cd22b0ec74059e0eab25ffbced3ecf5d3843f1db6b326bf77baf4dc3d982db339c5fc8b0fe689444a2eecb55c3dc6b3e0a6e81fb77c7850bfad8a838106b6ebcffe61f170c06956253e096e62ad7287951e5903b475b0849a89c31c0148a08455d5e156ea9705cea36e76f496613a3d05019bf41d83ac0dee90607584385e9812a74ae3490251a7c563b8a1f0afea8e0a55f33530dbf245c61ca8b5b79f08483f019d0ce62b3c9179ade5ed699112e5810a5444bd2e8a780db7ae0005e78c46fea3caa73810294d2d52d1b7a2f8b019227480e0b1bd89adfd5378bde1ecf9119d56ded4ad3416a6b0bbfb813708ce98c5e769b715686dffc4c1687f756f37b2edbd95c8f30f895ac951bbc141db005832a5c44cc7483127370d4d25c91d8727a6f33c7c71ff3472f4ed11235ebc1c43b84f682bfa08114867d49930fe9b04179c25c2bd47db25726612ec8e44d67d0c7f9922d1bbe21cef6eb2b137802b6601be77e4735f308541440cbb66d5016632b72ff1f5885efff556d3fb461fc600ffe037f4b4ffae3da2248645cbe1fffe323de6e32f4a096435924e833dfb4760ee711c6d40174067cddd5ffe921359743785f8065dada7cec548172865d7674e807b13d733ce90f5bdea5f2173b64a10706c1bc2f73118648a0b2a6da692d3c74836030041f2ea4a3ae0acb9f85968ee885656e1af41e5dfacba30093d39b10e6fd09a2b087b5d1087b4ef26c1376d2b85f98f15a77460f579cd5bc6540724ac2710abc8176f9bc0ac6ff6ec90998fa2e7ae445a24a8c37c2b5b45b35ddd98d6a886a6c373b8e6a54d28bd4965c56dcd7072a8d15be92b0a79729edc6f9dfb6e599e44e0c4915cc5867b3c7605837199e307da175a9795c6813d0d04ba34f29e5f8d10cd410fe60e255dac298f7ac5d50f356f44f77963a45c7488505c19bec4ff16863be1de19c6ddbeae9caf02491c099ba90419e6836f812e49eb9a13dcd8feb43aed62fdefc3d5d6e939b258b00041ba0fc26e3f17c153ecb58b135c2ad6d02d4d177dc06baf50483560267edfc4c40bf5b4fc4fed6aef910a5ae719a26683895dca1983e92ba0fa48cd2767fe4066cd5ec0bb4f1a400142ee1b3ca9a4cadf7a0ffff5eeeecdf25fe59ddb41c045cf73fe64f9d8b129f3044693c7288547ad3de0bcc27045ebfdd9dfd9aa63e57df278d53608f05f3ed4051faf1fe9d8313bdc909cd356821b75c4db091fbdca7024f74f6c1664f1f241f0477b35e5052a1a10dd2fa90f79b22a1d0b93b8ade6a63c77d579ffd0e09c15088a8075296ad51ae5cb51ecefd1d83e2b75c7ab6813db1a9f8058886bfb7266c9fbeb753f765082df60ed0b17ae6eb2c49b5d4fef742b2ded5620f82af66626d791df3b0bbcd9db3106d13a6fe001764e99655b694251e2274a57545d9287791a441f202315841617781e733224dc8fbf74923af0ce5aa0aeac1f7b2e7ac200a9e5a24b9d97ce889f35157a8d8fe9c064f2d0ebca6ddfb5155ef0cb042f18b0c840bfb0869a5299bd0082196d7dd0d59862ad3ae40faaf932e7e15c2355329e39e87938d0f502e30dcd394ea774e9107bf9f598d456658ecd209f5bdc5e3f653be2fee7fa3efa23a091c58a2392a053f39019261b2f038768278bcce4bf54883524d9ed775cb50fdc6a4afc82845b0a576b7a42d853fdb69aa2e5756ce9c57006234612fdc0ae5f29c35c5a1f528c4edfd62d0044ff7c6c30f457c77d4326094896de4c153e9c0a27114e3a773d425952d319a5c84f50be8fe3a823682197b22b0ccf9baf743545e46e2873470c2406b2b6606ba28726f98eac420f980b9623296149ef6401cc3220a5bf6a1b0bcfad3449a5987bad56312f64c484f247d12fda6a72e00be90e5a34803f4365a53d1d4bcc5c55ada765f82d59c8bba0e09729b28d60c2e57a14a0de999764404cc5dfc1cb2ba3f4411b54368782eac1927f5d5dde3ad674fd666c453b97a76c09806c1870b3406baeb0b6d5a4ed6e34f3a95ed69b93907970feeb1a9b58200ead013502e3180c8ebb24c21d6bcbd0775781082756acc35365bbbf17af65d8a717f7821532209db874e85f8322ebf01a74b798706560703f5b2b37edf43a67ac4d510f1188733656c3b211325c42783937e7f0507cc98521a76088b621d01c31fc5f1ae3d8be0e6a16fd9c6637154fb099d264a68960d9e34b6fcafeaff474b6691675c5060909fb5f625a248d33eb35bf7edc72bea2080c70f4004e66dbeec45bee6c01cf95f813cb9b8eeb91e7562ad7d53b1b8caaa9a8aae94cd18903430fab9df066056c0d4cacca11498ed4cab478c2d6bf999921d2251dcbf1f523f185bb86ca1002ba37b64de5464765e7dcb79a700f79f3cd75542cd9eb942789f260b40ca872f8f294997ad12bb01c1cbed55532f176157948729455c96239d6b5350f6149a3f1d7e6fd7fffed36400efc4c32cfb5eb53edfb9c6c0a9f146cb1521f520f08e5b96b6acf9f624782658be2bec7c2a26c7e0c7dac22c53bf532f649019ee870e24ceb78ecdc8873821cce98da0aabf423b3dc4408b7dabda2bb6c0286dcb6d8efc111ade62eeab90380e1f9f9ac03db2fac0208c2bb6dbaefcedfb5c50eed77568e7e7acffbc2c332608805e31f4ba9d3166e6ec4e64100d1341256e35dd18aeb83e73405e00190d53292fb5be179738027be8979fe1da2818a8d4f96406fd4d905d7c6502b5dde390923b0f6a682bd1ad33add7f49ba7ee087ce16db7bded565f95bcb7b7d715d7f4bc72028d098e832250b4631b78f4055a37ec2057823c5a3fd7a38a535e148f13a1d336da09697e6af1410a4a2606264fcdbae6cc748ca6bc89190c12a7d410909cd8c201c205c244e81f7e1126c6e1f140fbceefa720ed4847fdf18843055251ccfa22f8344887eb036a170dfc5e70395196481c4f2d0c57c7c3537d9a2ed32405d34edb92937335733de3454ced0835964004004a3f6ec93a57f22a5483a7327cf9ba5c147736a2a059760da4fd5786bfebbebc7303b389ead6904364f523affb90bb7d787a2d5f4b43430fe7f149ebe1991f9f9ac53e18afc5b955f0e021bc1338e849c0de9b7bda2a63ee6fe5510c4a69dc1b88403c1a15900d474c89553020f020a3be2e9727ffb1c645e0d708d82ca6097246d1dcd0ecd705ba755708737311bf3ced69ca805bcf8c658c228a3667a799516882c6f09768393d43e911de1fd4b934c3fdbaef809e46deb7b43b572222abf64293e0b387705ac39907a3246997739b5fff7e18fa58e001cca65d279b9dc76b20daf40c27f7735a147d323e3f841d890602bbae124b48f07f8a26989305cc09f125fba1357a9dbebe2de48d92f68bea59c5321423aa342da1fecafa77ae68bca3f0b99960922fec46850b44f282ff75b4bd2afe4c1da517d7fcebc8d61a8b5cc6c3f38a93ea39f28bb3532e4be7a8ceea325a268435464cdb6f9fc36e7a277c5b9a619e92b3b2e13353e25b12357275db463587a936a16aad58ce62da401b3e78a68c074725312c1e77edb921c6a73b01d37318ac6ef8634aed2e869a6f4912e2ac4c475a9cb6eac935f7d0820ecac9344fc9534616ff8bc1d78cd401b40e9e1ade99c20b49fedb1145659f3ee99d4f56d990717fda16473b3b02438ec1cedac9e873d97d3934d3571ae034ed1a4a04c7d965c8dec34532d6e2c92afd20d8b80cc5678d239b561b2a1822005f3920f84aa83c3225035966199232f2bfd92bf43f36d15d038c0b09c9a51fa4982c2060615f50c00b576aa2cbeea2ddf7f8ca0862e2352ea7f8884c11be06270515fbfd8a62c27fb3c64281118f18362f33e13eb6507cab7f0a7d5ded0c42c5ef5ecddc8fa746a823479b7a14ee86a2ff481f31bbb0b4d5da3e992aba9d7eae56d511c0a3113a3f39e199dbc0fd5789a4c1aed256280ea8299c517e043e95e29ddc00545024f3ab4c10c5917d571266549605dff5fc5be042bb6e0c017ee2bbdba6574ec379db3dad2e8712cfaaf575cac43174c185cc028662e68fed47d30374df08a4e99a643759739d2e6fa5d4a1ebaadfa89921f6d6d7e3345632c9acd22036f4446f7d6b6f487881210e51671e601f92674694c6b32ef0e4caa639311914673915164cdc446046437471a0b56fc860b979b6ff8261b0a363b14246011ff4390ad9045296573790eb5f43aef252cfe95b5a31a1019e68117526b8b7658d5b6e17558cee120f8700e9ac5ba36f2a0d8645dc264010c3b8a33d9340c53678b6069cd4999c81b8c53f8ad280c5b28ba33bed153401d6812949f6479b2d711561f59b64abfe741da366522f7d29b8859fefe1313790a752f7c501d33d3360adb3e46131df2ad9320f5e4754fb8bd4e913cec040c70dd221592e771b9f47e9901bc3e12f77fa8a0128b67e9fcad1ab9f1e71aa924abbb12e85a0fe41e2a0f7e19d6b9eeb5d708c375052a1df16c73ed0e2e0f7fd84834a6964c5835d17addc03f7a3abf5d68e3e2a0f0db6b2c4bbe74251b1c7c97f31a6a8190521f00ec6cf830b51a038498571635e4024141d8264e7c7f1d402f483c0f8fbdbe8c638c9c7d0e7b158881330ecf340395d3bb7eb4a5906c19b533dfad61a9c3378e68424268ee4abb2abb2c0d08dde3cf4b471a9822c431ba0eee168f9a5165b0540b813d7d46c5d99bcd7b628a756b2807b15c4c5b299383194781cba81e34ec18300427af4f46eabf49bd86e888ddcc91191ae3f33f81761fe734b2818afef82010372581ac8b13a3a8c2313f5ff6f9dcfc0b52103a1fa57ee7bf13b2415bf3b0b0d42281378148e387e688a97616b78e3fbf0867ea84a497370b54289b68c4d6b1d197f2f9c6fe76fcc54df5a81d9eb7a21d40603a598f0fabe659b63b40dc74d45a6d029332dc3211aae06dad2c4be3f7404048a4762d30be2b4137a258c6161a8f2bfd29a158346c648631d5894d58d2f8efaa8e07e7d00a968c027ec40b6b7fd1c2f1b1417aeb4df8ad4dba817f68098fde666b3bec38d61ed4b74c26ed335f7f68cf36be6cbb998f10f5d195837d7d91fd71b9825f5de96ad0b940d6bf9a98b46d08cdb00596d3dd4f17518de2c8171b972002acc4d639b39280cbfb559a632b5074476e28797174a1349abc5bef9a4404039180323747e89a8da4de2b1ec74df9b2a06366e17947c0d966bdd2c70a9715cff0690329645f269294fcdc831e4bf2379791b068b4546365cf0acd699b1b5eb7e51c1a10ee72bd493ac5d05aa9759af9e781947f98db7906dad373137358de4785d546fb4c95e3e68168da8f0c440ad2aa860c0527a8f3869b9df0f04ae9e88994d9313f58a221a60c4886d73e70d9bee39d6ea709055e12ce023b15cc81ee1b4560baad8dbc5377d9edefcc7ca46e1759695ce54974cb184bcb0fa669d0034e44e004b87300674b02fb645cdcd227499ba8a48e3e44becb24c626e80670fb54822f89caaad1c5e43117d9851550dde41867f069c6f937a24ba99ada3367dc54d4ef1c2d183d63291a90a78cd92c87d9f19d3ae6e1dfafd69cb07d4728da9e34bbfdc9a389babb0d6f157f6d0dfa7b9ed73ca00d28ed378304c9b366f4c866539a5b84acab9de71e167cf7dbbfb8d9a068ed32b60c47909b6e2b45ea971a9e5a1ac74c2b33941def6eea2484f085db24dc46d24d6065bd69def908ba87c3dc13967fc1f5de7390f4c35b81727272df5f9c6d6d421817c08fd98e93981ee5532d3e8b7bf2571e8d14616c4415cbeeb2b58e85649a611a019a54928fd778bdc6309109fa9e29a6a4d56fefcc73aa27c7e5232bf79842b0f59667081dc88c2849c8cbeb8e33a02b43eacb40fe19265ae11afa5037aab9a9362737d8452a1b53f3a81d7ccdbf4629bf95f5f945919962ad3677b7a8486d28caea667989b05044b887374f71a80dd1878ee910d6c52649b40b237affa2f3a9dde64b1b4160b1d5e6525a916e0a8005ec7d16e7c4cefe47fe79f4b694acec9a0fa512dc487f5b2fc71626f12d65cd4b2ed6bfec8b9e9cf95e372dde18e725524948d452018fe9812114bef446d419b9e5a9a7ae7fd687a4d75d37fd2b9436cdfacc9cd2d53549a8eeeae0b4ce3b4f1beaf3fe9fd5e7e8897464373267ce811167e6d9f6971e68a2353da8b622ecbcd37d7ae242f0c6c1585862cef39d1cd77b53dc7f34e4b4e57f52c239161607fd2c29628adbaef6426b1149a4aa75bb05a212803bb2aed21c0426395ba5697296c93f8f0dc24554d081b8c4ba28f3f0ec0d70f3cd67f3c183358082efbc632c13228ca62c68d50919755c4f57138f763bfe5565a1a1f4a7973c12bf0575942f15d240b3848c3b66cbba81537937eccb57e63d93d0a0bc228d427649db5e1f810fb38d82522cf87992243ca9aaae9c1c7b1a8154efa0d8117944018abfada4b70f053b98fc0bb75caf4b44161304213ad0ed6dc6b5dfb6f6afde9bd7ffa67ca475546737abf8ce31951880029a58581d40294cef9a8bfc2226180dc0bc218bf7ccb788d67b48836d250e6cba6fff491683d28bfbe5edef375c6fc89008e822668455a2777e9dd20fef8fa36ce818968c0e0e7d607e518cf6f330e61dfdfc3414fdc1afa0cb6e0d68d001cd32e989798e5ac2a6d277f9513ae4d52de7a484ec0b348736a4b15bdb288785ac644327960cd35b61b5b5e313fde177e5d74ac115e595e70a45d0bf18be4c3425dac8714c4e9d0e37e4ed301b2cd5e712ef071d6c2344bcc1531a227e342fd460b4088ced235c791862ea85eac8681072400e6076f7ea732e8d8d340275a96e1501de550847ac044e31ed0bfc8be10570a398e9c9adf07bbcf410b88440c17a4dfa18f3fdb48b0bd6c56d2e56be1758ab71ae1a72673e27b462da933c72151d2eb7e4848ef09483fa3a0163fb0b314c43679cba5f378f0e6fc56f64057823b6eced46b4ec56ec170131e1607b20d4500182ba68aeccd2cc9630bcdea660f6bc729e1244f48597f715d5f72e6f900c249de056856b78f1c89c74bc3408e11f4d5e42519e6b7b4ad3fc7abe1ee811ecbd0cee038e8cfb8296a188a410fb0baa73a40f614422e20291cc0a1e6ba61f6baf2707080df4f79966bdcb3b555f488fb58e294df376a240137c4bd7d8853d0b932c9fbac23df38f2be99a17b351f9bcc0c8961cb10fedf95890bba9db27304a9aeae383c71880ed2d5429d67cd7013480dd4ba81de5fcffcbd143b758b8948d9920a3d4e6e4d70f6b43458ec5c0994925a1073c8a49cdc07829597562593994e737d1ac61df02d678ec8ea899c94b58c6bc90b4d7ed0b3762b17ec876a65a65930b768292b7953792b5d8fab7e9a1be0d7c1ef8073b8413ee7b6e8bd0bc3a5a7f857bf2f09b445fa56d0015d32805a485181293a19cffa2ec07372d2e3fcaa32aa17f03aef8465ab84a8c0a829bdfaa6ac32aa3089d33e7c8d517771e2ae251a2c7ca50e0d126e198a56e12eee62d16f07ca88b380b2293082c7781bff7f0f6b216d72b0a1b294d664c9b29b6b49d4bae48030536057b60836208b5209f1b2ecfc2976dece375d18d112923f5cc05217613d6c34379deed5cd3881d419f663ddffbabad3ecc3c4e70e20efa80fe3ccfe6b72798a54fc7e419f786f3ec587994e3ff824b69ab21524e1d52fe583fe0a7e18ff13c004dd95b563b70f4bd6fd7c561420137fe78c467b7c0bfad030862e06ab6ded1b1d9dc36cfa810cd822d47b2627fb981f4da4cedb77a5714c9b9e5d62457c09daaeab00a5c32314a88f7673b337d2f5c888e08ccff826bc78a0fcc5eea12e81efda1bb0bd9b99a35b43514052f8f42d39b8142708fd6b0a0bb0486106220c83e1865ae11d571eda41ab47d2970134d0da96c6a3be5b3afd170efe24affc5e05b581e36e5949f660f8cebb5e6e2215897ab7408995602047bd1c26ada9632ac85d01ef9761413d31cce628515ee47b48fbd50b8f4ad9dd9781b0d3d4737c1699b78beb6eee6893d5d0f50f16b27cbc38b698544771bbad0c319117f02c7aa8b9b10d166cf2338f9e24644ed30025021659d877e64a20019e3b9c40c1f82fe83422bdb493f13612c5c97701e33128426a7ab4e910f08dcf624922a62a7a9cc09ff3bc042efe35d7c2378e65fdf9ab49ea6b4eb47108dd09899560cc4c5bd30838da0c37decf9bc2870f082223ce2897b9bd9e2df619df031e9814787961bdc410f3c3901f730d5b5398c0769568c9dc1752bd8abbb7c14a973caf6feaba27ae68080256bbe996349d8f8f48ec06debf78d88a79b18f1fe029401c810a31d910627132e3a0a0374fb215e1166dd82c73b88c76923f6ac036d0e1280f1c0b1ef9ffdbfa8eaafa871115f9ca2ae5b058aff94e48c6871de2ced19b9dd1a4e14e2c407b51894a7e21f8b732f2d1041085b3cc96be519881055abf9e5df8923be7386c86e9e82c5f9864709f47e6940906b7a99e7d7bc005032dcc7958e615b67a4e71170fcd12d38e46a4baf966d1842b76eb77c0991715f7e7d89b6de8d1b7db8374391826174bac900284cbdcf65bff785b815de974150911e974c101a2bbdba514737f7ac67c237f9eec57f94a78f92d122823d9730a4864a36776951c3882\n"); + assertTrue(Hex.toHexString(s), Arrays.areEqual(expected, s)); + + sig = Signature.getInstance("SLH-DSA", "BC"); + + sig.initVerify(kp.getPublic()); + + sig.update(msg, 0, msg.length); + + assertTrue(sig.verify(s)); + } + + // TODO + /* + public void testSphincsDeterministicSigSHA2() + throws Exception + { + SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3" + + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")); + byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); + + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC"); + + kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, random); + + KeyPair kp = kpg.generateKeyPair(); + + Signature sig = Signature.getInstance("SLH-DSA", "BC"); + + sig.initSign(kp.getPrivate()); + + sig.update(msg, 0, msg.length); + + byte[] s = sig.sign(); + + byte[] expected = Hex.decode("e8a1883716841afecbd6f9bd8648bbf86ab3badcb227b624633d51913eb337e07b68834818c993532f90581ff8e26477449fc5f0fb37c9d8462bee7d3f5825316afbd4c9a2a266d71d7f8ba4db064c665e02e7aa0d1ba9bac5d0ac0934db69fa09fc85234a701887cfc0af912c7b5d3186c0489e593fff2e9b5c79a0a77ac312aac4049d29ad57db8e86cec1c1264e819c5083bd03b4ac44b94be97756e2e4b491947a2103b371c1b54940bba71cbb7f9bbcc8eb90dac25795d1148fdbdc3cacef7945bf9744c966cb73cde15b98721440d2fce6294e77c39bb2cc37738bb2c2ec45a8d64a7fdda31c2a5f38e9cf17afe942470f1227e05b907ada0564ff9cc0e1154b1459f4a4b21485d901582c2cabd443635262c6a899e774e27d7428d980c77e2d42c15bf9f45b702462dce170042b696598fa8a850beed7517f717cb48fc98c8634296e3b8572284717fa5248eaca46c8b20670c31347b919d6569d351e4ba30595a5adbf887c8e971aed2dcceb4593ad18db1e5f9226ae82366e5c99c44e22ea292912d00aa6c53670bf6ed0e969c56a95015b8c5e0641885b4ceaf45bd2d90d5b93f5b0f63a8798a572935e2300319aa40e6435441b611149750638e3894e66e7c3ffc6a4f1cb37456a7c82b05e2b6d16f8365f05391f25539b835159ba9b775e85abda82d16d6b7b626f76bd2e98cb31b82ba8f18f0309c41677c2b4f5e822f255dffe17d21e7ecd421cecdb7e6a3f88e4d76fa0eeb3d7e9677c0c983223d029a025a147399ce72a13572edb7d2689b361993a06492df19fc5391a1e6e89d4d81cb5c3eaf1396941f9a51b8897cdf725ae8669f2b4b9435277ba13899a8f1805b77fddf5bd6b2d6dddf02a185d10f3196c571ab246bb8e3e1fc97b0b0b4e1c3e2186f6839b615c210613c4c3c7fd922d1907fedf6631bf3d1ca99914ad5c9fd34ca51ae4093e2a925c6a967b2c2e8c97fdf73d8dc3c6fb36ae587e50e0b31455f618811162c30ecbe1e2528d325a8c75afb13cceff548863c535bb6f72779fc150b74d33b4f98f7dca144fa554318cf48863fdaf16c73ab14e5c00580ff227803b1c8c383713bffb6144ae7b02f0cc1113fe2f57b72b93edc1e0c363ad4745e5a96bc61b2ebfe5fe1fe6008e734fa9382c0b818834e22611433ca213cf090c5af84a318cdfd038d8cf6936479d5b35dacc30be7b92e13920c0f80e5a6365ffa3b0c35ee637a4e861817b10b6c6b8f6532124c45289ddd027365e86e76b57ac42b6c15abff1b0426d1456299f9585b16aa0301d333837e751db28c0e3ef942d577655b70219353954384b649dbb4cfd8754d80250fe9ed859ab8d51e6c663ab32bc6c5972620214f3e08b3275829e1e97a19e2795ee39a43e56c1adab144951ef5b1cc1512eb250625d7bc18165a20e588f03075a524c0cac05c5da810632680e05516815c5b32262eb5b3b54851477edd61ce14d3238c3d02f4518d809887a49d148e84cdf7e50e0c06d82b41e152a5151a576c69fbc812c327d440b41edb75c02ab444ebc7da11143e440cfbda9c6c7916264b95692029e4c1bcbe56c55bcb2af6530131147de4a1b384b46179bce044dc104a3131ade59e4a1556e665d6ae0ba1bfcb433215d6b9d5be7b023045b0b49490685808b1a545577abc9abfd069aacd33863c2f5d0daf41b4c5af5224803f248356ca7c1269315c1bc4cf8256cda2e1dd2b1f227b7032ac29acf80732120ea3f9aa07945b602810e8aeafccea49d32e5050f248f72f3fc839962ae0e1443b46b586fbb48a2aae82cca180d580312f918ed208a2b6a493cd63b881a75e321a5622bf47314877bcdc9474019b5c64152e003d857b9eac87b3ea6c8f378592078326a4cb16d66caae17694b306ec4965f85a064175763ac9d4b457be3609188ccbeea07087f5051c66b5ca51fd88fb91a1dcc3f93ebb7840645283595fd3c4148bd62e8dcf0c5da4b89492222106228717ec8b473f7505defcf6da41c8e31965c76a067604da9f031f0b34235d7ef587748ba03cac0f104ebd1d29a44e0ac96c85359550a115aed8a8f15536032b6fbf4ac8239eb94391b2f66d7f001114457a938e5877f0eae1ad36ff6a853d96ebd8d5e44391e83a940fe538dfe2caaebcf7b6110cf4e51617f3619480c3396d7c9d2af597e113acdd794cf81de24a21285f4ca9bf56df99e02587bf89674e7db2a1a06cbc217940fda6248befcb93a3f947234e59ab6b03333932c015dba3c88092f362d0baac5c5b9f2d9d5a829dd3ad4644e0cde89d4d8df4d547187d66179f7b350112c4c004e6afc97fc97793530be06c13737386ba92b13cce0c0b6cb6b0aa0d82000d674d1998f05b271643ba85f7da6304dbb6f530d2c80c40c3e2f925b87d32603e377b3a9ac486e0f0186c191f4648fbb8e230f192185498e3e09e82d321a9a6058c553419e21c3ddbf147c2ed88f99398a7eba4db3a7ea39b45693285c4d6d6c8a1eb8e7bc0ed937838afd59d003d69623f6cc6740f2a7b1808073fc7638960d649256026d9b714d903719ac7959405eed2a22e4a9d72e33ab6f0aa5d07be4783b4ddf36af1b4d4c78585cfce80738b9c1225660f5e16d9de5c9ac285d24db80c9680525d419b626435fafebbb683c9b36bdc1cfc185cfe87b6ae93a14e3d63db6688f300154f288484c07c97d82f438fb9281afe6254170ea6d8037108d8984e88872f1c9072eaa46ed6ba426282ddf6365f010323e176e11309a3d80be22f8aba5cf93dbff8658665a9d2e3b428e05218d9da73aa0324f9500732920cb278bce651e21816c61376d1cf6d2899f02423b33be6a8217c217dc42b1f97abf8f63ebfc367b4fbf0f158a32cb2aac06616446a9773f6501692cbbab803074b5c026cb3b8ab7f48d6e5818e668198cc958b8acfd6469e8b835aca0e5bfa5a8f301ffdea73c8693f6c656cfa411e7efab0842da13aa7132db26176c792fd1a99c79551ab99482be3674bd2e37fcd8e0701f2a9cc801b56e717c8186cae04287fc741296e97c5563c4b64e7d36b76cfb41ff3ef32c5c88a4dc09ff91a215d157fcae725f7da8801e72086e3f063529eac6a11d4845c1eb0bd5845801cf9cc35deb27d7bdbb67055f641b9f4bfaacc0af6124853cee6cc3a858c1b102fde6da1d245390d6a6db8492b1142fc09b90d8c985ddd2a82e9e79355a070eccdcf125ba45a2543d473cab41cd9ec464b77fd57c54dd5b346f954b1c2acd37841f29f9b7dfa767fd029bddfbd0cd3aa285540a3943c6d1018f4cf87fd7c17fbbc65016d5668d2b90e01f3176218160ef5241caaf3bbd747c81da560d1debe3dc258197740839f93ca6eb41e7e635340e9de07aac1b24c5f48182d0bdee3672097d2ae48960224038c8fd710845d0927f647dbe09062c586842d31e1018950a3e16ea5d209402367badae58d2344d169cdc05f5a47f86903d18902ef3bed7d3deea961bc2e8e7019d77005ff88be637ed0977354b26ca98a7c0dd436af45341626540e050d7f4f03b703f254e32bd9a3d2f93997052732773c2274cd1a26da956105c5fa59dbfb002efbc28d3cca08f91f0fa76289a1f68decc6f943cad337f710e26e8287ced6a35b3c4a5b2598162fe2412cc2d44b49948f383403c23ec22c585e95f91063202da0755205bb592fbd345e10bf1b545187a7c14aa88106bfc37bc05dafa17f0e2bb8edc2179b3093bb1cd955beb621d2e222b39af3cc1ed26c7067012b4fdea539c983e1481b70dea56506a3ad912257cd7cd58da4cacfd4370a0dd292c319f23ee3ead9695bfe91c7e83bd846bc186b1703061a9d4a69eb961ba06415d4dfaf2cfe839337a6efa0e6b4f4a23c700f678e517a64e8a0c1eb28c6044440f203d9eac89c8b7d406a076bcabdce36195119001022e640155df8ef46241ea50204df095b96deeb70c2306cea56794e9729b3fe27e114a95344ad4d033175decb92e0ac3a88a16e5ba32f8c94853764fc7aeb16591cd3cdeb84b24ef6827a341355e7efe0ef360991a20e6ae77a04d66bee1da160f14ceeadabb7844e3baec99a057202d80f41c01c6f59d6affe7497b137f93e377e3b9f6df995df70480098c46a85e5b9d9b3fb7d4b7c6f4c72e1ea8fc442f92d4d74b41ce026aa5ecfac54ca2b4f45995799330082e0b558f18c5e31e698c67f2e82dca0ed3540f8493f8176b9163633481d4a444ce792b1b5b7c1f390853aad64979678de457086d7b7a0c0230ee0d0c269322812d5e7dc8e6e1e03dc0c977e81a6ac37b328af654ab070c6b073e3d0194046e9e91898e8459b90faba6e0c5a14a764d919db650c798aaf27ef1ef87a62b3b5d0b69a5abd7ea8e12e19a74754deadbcd82867ee271340c0687e7091091585e1163da7ac9655c91a62da7850478d2283fb6946306834f2e56025d863044b564818de7b43a7d895bc3b260f4d8c55fdcb09d8d01d11631e7409e3dffa027be768340e5a1a71c518396906b1ae32b44b08f6c0b54ca53c7e73375713656815e503a799205ef9b6753d177794c753ec2a067421a13272d09131fe37d212c19790d707c327146823e7442b56bca450f3de89888637e0dc249c2e42c6d6d47a6a49a27dad3aa5b543a0130d7d34f6310bbf8aca6e514be50e2cadc80a7133545d56bfe06a017191e5dd5ed598ba52bee9752896c65fcd4bcb9de79f7a89d781dd47601df7445e23104f2d7f9341d6c1e833247b1f5b56721255d2616e6edf75aee159735f15a70a170dcced4f0d029800b6462fe50379eec7119530650b4606ddd7721e568e52a934ea14565168c45cc0b4e540149badcdc1f70e3079f2adfc8ffa44333c88c5e875e64377780a23573a6f009d8f8d8bd3a2ec814f9a5636f19dedd93b0ab1f70a4b6666520d7b060925c95c2725ee065f52fd09b2f3b2b89201de0174ec755680cbba3e5828298a054bcdefa112aa739c554f847069ec6f4bc30c099c67eb930a68d20a01e5c68d12b9f1b1f3c557fc9ddbe6083aaa884880c95721c85ab22cbb5980bba49c708edeac69a95f7e0e70c9a75fe011411a1ee730f2f6699ae74708608ce6f33435efa0b31379f6c8bc2494dbe7145eb70f6d4d46f8d7827071c49d55c487f9fbfe1a56a7db761cf3d314205a18866b872aa8b9f4b68a930dca64e8fc294b6d59eefe25cfc1008689c78a1e90bca877ce9f46aa05f81e66a415092ef9bafff8d4732b12976b925bd83439e547e3df349eaac385d674bb2672e23290e5db0784ebabb24bed7831e9965c2db3dc8db4ca4c3525b3b132439fd0de7fd1480e2e697c2165e1a27b646898c1af610276c6f58fbc84104a345783be38749ae3f968c980e368b6c7943fcd5a3fdff44f4a44ee55cfd7f94d0eac235dad9296e979f32d5ee4fd624aaca794bf5cc30584e505382b852b880f6aff7da68d4c7970dab6d5510036bb453a7462d7cef59fa78d03de0ba69b266685dc2f17ce8e8a6c23e465175b352c977eacd5fc611d55a03dbb46a831e5016ea28329373d40cba6414193641f75e27a5099676670634008678c3b5d1f14e688a1196b08e4dd855611e56fb74146876ee12b6d7992dc34bfaf68462322e0f169e61b127c00b9c8817cdb59bc675387f671e913d64662128134932a50d8cb6f49a13646fcb10e2c3f1c8c517c5296d1285660549d1bc0ade7c03354749ea811002a9cf526100e264a6f9506c563211e56a811d8ee8eb8e2e917512d9bd38c0c1f51c6968cdb10b9d526d19f4762636bfd9353f904cee43d28b31f6a65266f46e0af9e7882aeed238450a985b493bcaceaf8eef545c93eb6b7a264dc278fd621c338f7dceddd29f68c20625619374410db7d45563e2d90341c475a5df5a5f8dccf3c648072e205adba8327eb36b9d2f0e7dc5ae59933063ef105538974bd47f11379566342c07461f6fce54bd2ddae8004824e93eb63cbe950663d88c31b9cf20e4abfdc1892405b4879cb32ce9c6eee7f93da5e7955d4c04b04cd13bb4ff3f13ee1ced444b80c92bd18d8c122f43020bb423a15142932bf522d9df402a29087bca975a852865ae27a9989a5921ad4345cb4a64f7e9f6aedb0217604a11b3eab8b4adaf2b9f527fc108b3a6d94bf6d0ecc63a237a70489041d1d499316396d67b5b8c73f6e6b91d0a6af32914fbfd860087ef4d14ca4553cea4781cb9b075e47a9fac71c38779892c87a21ebd942a596be33fa3f8473e869d99213782866fe8ad4a79d4d2dcee9abdd53de125a179af9bda9a8b8fa9092ea6ef17b6260da9099ffb1cda671fcc364ad5e40bb4028115be8833c9c6ee381e64c20d1ef056cb5132a04dbebadf2e62f8c545808f685f8f08e817558f27ac120970d6fb1250ae469d33f181ce62aa6a150fec671bc669427151da2e8de1f010c572a000172ca2a140ffd253a48c612c413eac55e9087817b42a468e929e116f4e33a63df26934e2478e806a583493c985f75c4edac0280317bfdb572f1ae1452aa26f3076e7e48fc91a253d689dfa76bb46b199abbfd6c5533da987747dbe90a4c9a8ca664661d8f09df9a2b6648e2b7185f459084f35a3d56f773da2bfc70b1d7ab0ddea709362afb0435c6e6f6a58d0cc42da9a884d76123b6df031accef92a77b67a906abe90abd54ffd358bd9aa977f926a71bc46a5d9b13ee0e4b761771ca5538601cbc7204463f3bc3821e06738acd83cbaf7571abbf032e9607ab7be96baee4ba563932f172ddee5d6adfa4c01b21439e8fa80101847ae4cf5ba289d46fd65545a45fb7f4186e02cf9a0aa2841bacd3c463d6f23ac88514c9039987671fdb263621b4ce663c7838dea4568905a5f1fa3ee4d82f222579ce278e145785c5403bcb37825d3f787ed3f4a657c7d06a77c31afdd33f4042d6baffa3898da308a9a2f367203bf5e6afa82a6d5c428cd8b8bfbf98a505cdd24282867d89d7dcc7ff7f56cfbfe6ed07ebb3fa36ce68ff1cbd2141a656a7e62ddd90e5fe72308c5a2a3a5f198bed49e4b7d373ae4920ea0ba52b3c9d8bd9fa45a655bbad9ebfc64f06a759a79d97f0693f73d25700a7aa7dad283b88c9d62d07951642561911f11e1c7bd760c9a021cbab298b0bddbccf828a2d203a10e36b7dc7d5f40df67c226a9a423f8e42a62a3e91b3ce9524e0bf9d2d18e07e1d0fcfb8c67693168871de6b5e683c0dcf46e95ce63b5887d2538f76078121a5cf124f2f0c06226387fe22be207b8b966b59f12a702bfbd6b00ba9b6d9ce2beec702e262af32ecdbf54811850c51ce03544087d7b0a292a87e0ae406e772bcfb02c84c513e05836ce62116a2e21920bd219d49d0d888156577204b6222e1b017a9bf5f6d57f43011ec2631a6323ee0238e89d0cb2b20b504c485f8a2a001e79d3ef7f56b71e8fd30add6013dddd984a2b5ceed885afd9b59bc639fb2dbc5903acb55bb2612e4bb7606f5431d864a12770f0cda1ab87a9323a40a8db68214aad3a00e3fcbf12d2327e33c658f629edb36355de41e91bc9ab3f4ae43dc43c7f457a28f51eb1e27a34db532a4a869242848dc23399572f4a02d07a52c58e8829d1c1a6e2cd123707240e1abf62f737ece64cfca027b31ff67d9dd567d4ca309f18a91d27a40fd2a4c1bb9297ac329222675d533d048d27909acd0d562589c137d6c0b4534ed1488eebc2e823eaecc1de95f120d2fa5292257c6c0e00b4352fe3da2880d08b7e4594770d2d0c8c5f2ffbc349b7555739226e5fc3c1f1e4effe5072f1fd8a6eb1bedfa334dfd7c6bed3580f5209773d7c1c133d26b758b7132436810f27f497b7470ea735fec626eb95b9d301ce012c8f61aa4db918c38baf9d52c67c0b2add59693bfed42a4e0263a7edcf473a481ee870260f3e8b22a42a820be4b65e797b801a86e2693a3d9364f687aff0a7177a6a3d35c535239585688255a2e378de152b88133be4a0524ad6ab72b539006e21f67cbe460ac56fb696174b87cff050b2c577b59c0c4b1677e5e325ea0b7d89d68a2438d9a2dcdfd898b05327bc8a8fb9c7df586c7659ed64de3032bce462832304726aa0f842cc12a4872172bbb364b5cb7e5d24eeb2d332d15bfafa591c9616363d945f14ff46c6b98ccbdc8e949a5647312fee2b8fdcf3ecbff2d7e259ef14d5beaa0cafdc81d8434afa394ca66769d230811330f7b1f68b6be89ac987a45904fc4e853134d5d3a6a140fb56a5e8decc3c37d98cfe3a9b43928f2e01efe9518a6bb7749dca1d7ae8089ee2e3861151c260c5a484e2f563c518bdffe45b2488cdd8e9e965aeab01bf894192b5987f1e96e18f75266e21e72c5a728ed2995a1605b33e8ecb21a9d56d25938730d6936c701a49a155eecb39075e4da05849c67dae2f2ad40962837ccd03743cc331e1b09dbba32ccffd77895201999664638a2b035fb346d2a65b3236253874cf6fd250666f68fa517328abf9014dc8545736eefbe2649140510f9e669b2e28bed80f2618898bd2eeffa0fb5e7f962f685d42a7f694255a33335842dd5f7f48969252a35edf0f8e6920ae85fd2836f89d358c3e451ef5c843c071230a2fe30ec1efac1e58fb506267a50043fe6b9b0aedaae9208520d7285bffa2857d0c7d276e9b7523a1c22b8889c5295b5a539387d6738b996964071e25841edee21f1884ef73fe4c1fafa393dbeb0a6bcb56598762c554ac650797c90fccf5973fca168c3a9ccf0570a791c80be4840039083318589138f566ed5a0222e4af8ff3a3569e4dd5914644208b2289e790f15e5b4c3daf9d4033b4e1c77c878fee8493e5b0f6f4a4ff5657922c0642a7fef854e5a1620af30d8804abc4315cffb8e271991353556fd2e957c235e028c2afbf0a2c35a998cfe3c87f1e9bf0da9bfa73a67e5a6f3ab73c9ffd554c82fe52b742a25587d43fe6675915f2e509a7f0c6566196f4c5aae24bd495579026328a85f668f685466fdf7f76a8becd25b2cbbac3efb8306b2691451414407ee41fa1471055a2ab02f5ec99b2c612d0d1cd16f1af866e773d6aec53ed2dda0fb6bb140b766c0b3a0f8e6012b7d67554e7c7a1876f51d0cffbee1fc1a11d46257bfca462c7a9c17a4f872476b9aebe991846fcd10c431beba46f02cb0376a632c4b6e8b10cae1eff3d96224886c1d885a8c46d9dc80e6a5edcde5d436b902cb0565be77baad995411199151f5ea61ac1d7ca5014fc2ebc01a8cb9d1e7662dd93f253eee23f474bf3a25285c4e992a0f77e7c707a412d50e5a04f49f1069a9b810f2ddc9ec9f468c389279b75bddc6beaeaacee970c768a05e1ca667a796cc4a5acf756401959738079b0578a61a80c1329ab59bdd2bc62fa98178b3acb2972d47539d7b97bdae13a81be76eac592537d096902a248eddcc8200030df3f9a2963ae7c8a3a86e83595940810a619b063d9bc6fc0cb75035e988acac64480f5a1a31a787855d8a83013919a793d4de679a6810208aae6835ba9aae843e6cde97ec57296398ec3c128891f3c7e44f3fe0c9779350f66f55ec3be94f9eed53dc6ebfbe53ed427cc44089a70100e605f554f9410bbbf77adbad858ce214f06ab334228b8f894fb7a9b2e3b4b53baa67fd4311fb910c424cdc486e6739cd432a711f570699a903c52a7071c2948a5c6c9d125abadccd242e24c2871e83d7c048dd2da6a476466a9ec31a35a652c06be1eaea5b6820e87f880d9b2faf5c2a7e60355e4a941e1b748fba735d0e75dfec06c6a9f2e57f12171ec9d6c69c0fbe3c6808324175ab324efaba125a22cecb55d7be793e6799d6a8c2a64774ecf894b09ee626146d46ee5b6875e74459751e16b62a4feabc675d887910cea345bdd470fca4229237d4ff79b7673a974bac5da0cd2f3df6ecd0c21ea039acb0cfc74472a7a97a2116d3250f183d0e427228a9602fe6d39497b02713c61e478b5c1dc68aa0d1e0294d7a5bd9bf4b8182d2cbaa1b9455c2cd2ee1120c83166d6f2dddf1311f40168fbad45b1c7afab59b95077540e64b638c159dda711a35e0bcfbcdc89f8ee8da56d7dfa2e23f39e8dfca2033783a3380c031deef512177f7128400ca8f49d8cdcac9ee38a5f86b8ff90664418509fee67e383bfbb478d7434ff7a6f50f6b4a279be9ab33b7270658f129e4f56526f32b38887eeeb13e2b068bca0914e730397ce5003d181f777b45744bc43fd05141178878e2f2705017b4616d23ea244d54aadc74c4d8ef3cbca173964a50521b13cf235c4348930f1c7d17552bf9f89c988f977ed6078fbda9f23d81e117404fac83961b7d23a91c7de2a5aeaeedc8ebaee2f0f76d9327e81a1f23fddc05cc577e4c0dbfed207bea589963c00c96ad79f2360d470e3304ad86d203e1c24738973b46bf04609f1f744dd1975c0c7f7f4e7a337bffbe7c9e83fba1c69c6e18287f3afa2d3996ffc1bd5193ce2b52444fdcdb0b19f701297d88d0fa29962cec5d2ef399feafe95db1f5e8c3c645ae63750de0406d519710dbeaaeef4139aa1b9687f4cf3ff77cf42acc00833bded8e853cfe5ffb8a369800b227fdeaaf6f54c182aa21d1398b29016cc7d468424beef0f5babde8ec7b1b7259b0fa178d98a5e2e2a6f100fc9b2dcc4ee5ea49b240bac283c9e4657eaee6a3f266b7f091d30e96666c14f1285a8671d02656a3e5583d4a4850da032e27bc13845a807b36a974593b1d232bc7742f3f20d1111781746deb4ea6ac95653a1acdf4f649bc060044d3224147133b44bd88fb13caebc41b36f7e48ec97b21e405ec941b270960837be1d49179664567d1ee2342cef5f9e4a559c7b27aa5aeb094a60845308aaa9c2afe5fd4cb808a44e4b6211111a69b40862e530247320863b7fd37fa77e69f05e05a8c43b51d3dbbaf3c715e5c348abfcfc5673f8c21a8126c762325ae3cffae51ffd43cee880f480006b7ef63e3a9ac33e6389466ef1a0b0e67e47537db6bf0f4950f735df6cd81ac960084df5f17d827ab400c074f8fc09bc5353bdd8cd17c6dec09842e7fdfe283f7f33133b33b704da89184ac05b9f98f0b64a5a437647107438cbacb161b6ec97814f56928e800ae519efd7129bfbcbcd4b305a9c703ec4c2b7fc685030e741f951e182da0e0297f99b28a1adec735e4a8b571e79035b78513b6ec12d815323fda7ed61353c52d490186450359c7fda3b45258bf276ee655cebb8bb23b20067bb914cfa50510832e93be450dfb9b7938d3e9888632938ba8d52760169055359373a558a7e2db3e3f7d31476c638a263c48b02f73131c737be93f29b9d9612b6d91434a26e6bce2b536a16d866985ad835a995781cb72680b8a5ab806da807bc77b9ab0f5cc39e845e2be7599db544dccf61c214b998469e8e7e568db4d171b66eddcecfcbc74535753a1b430c91c64e4ef97fbb70bc2468173d0362940a1379d90b358806eb49c2632398b2572b3d821cb12c0fc32c68106d6357b26ea2cce6c6fa8e1a17bda0fa64820c450752483cd066900f36ecbfc34b100799756296d7e46e48c5c48d38cdf333b98a8c7aa1adc2b02b58a0189f2cd046a18d1778192d98cd9510b40fb35350361fc4c3e917ac19c372f196e52c976c083ed500b4238f636fe21b9f3c362bd2556b16e45f67de52aa2e8f08d92bc19fd18a0030591df154df34ef121eac4ab0cba5b5fe8920c4c3f3a63a20f439ea9dcda4ec0d7601fe8849aff4f5d4d5552cab4c73b34d41543551fe1008032d101fe1d94ab4943256471f4bd06eff1f9593afab9fa8cd534d88258936cc593785464f4546b268f6adfd878911497d035a60a0e6c68b5884d76bb4898ad59c41160321b83d40a364cb427699c201ad78852a22eaaef3d5ceaf9de365018b271e16abf0ff5819345ed4764b70b88decf41c15dd243d81cc599a2fef2a3befb2949f2ab244fbcd412432ad3600eb5d92d116ba618f8730a477debcb3280d8b1dc04bed8b360ec7bb47b9cae89d25e702db37c5b583fd72c3f0c08a1495f75f15982a9931fca16b5b1ef1868c50a855116e6e0f49495ef82705f3a3c8d834d1725f0f0506060c2cc37e148f78f020fc701424fe46a5159e3a73dc834433d244568bbae114f475e5e60c13f47e9e14db1d21d451d2c5f39c39af0b60651d059a899af0181ba0b4c7fd5a7e1416adfb9f5381b24ce947b7d09a27a264acf7f0fa28d9db6f6f277d86e94ed96a4a53cbd3a7fe099d7177c2d6ec783314e08947f6811d60f069a1e65663b93f9aba00dd7de119c550181262340a88b316c191cff1c7b43d936a466c0226a5968c2e84ca61faf9a32cb3170fb8d105d25b3952395426d28531797154875af2cd089f7505dfa742c83a9fd15ea57427767df5db894e58f7e026eb4d126067eca69c7c2440d9e12486c63957013961c24359f94f5c1dc239bf532998ca339b3f0053961fa7b71c3c2a614d4b8a821b5e1a5544c4d079e71a43a7965c34e981a1c5460b25b6831979883e48f76c7ed34c844406cf5268936c01c3faf13a235b72444b9d7a701fa9a495231fcd8b8ed89ff2993e7a0241f8ff77e71badc7f0c471024a240f4824da0ace63db199ded2e6f3953c43cec3f5d60394f546eeac40331aa3f466af470311bff164fc90b00995228cda7e239b354a10269904304436ffc6f42c17e9b9ffe9a946c205fc0add8103e12e342b4542062ca0083c286a0be8ad469885fa7171c5526e2baa153c8cb43d33e9b1db7c635827ecd26041aa632829acbe53c38f63462e4d7a308f299efd555294be0894ecebd3a11d4242e1aef59cf77768197b77282aa0dd81d9085f87daf6bba680e40aa252629e2668d87eaf38be0e5399c95eccf3af5ef5b6b9d9da27251b8375343aba5406c6ae8f78d2311828bac89fad2291433cd2ee74ffb81fee1a3170ed32305ee77b1ecd22c7dc6b7b5b400d42917275058a2be78bcd1d79a661aee6ade1ce17fb1cbdbafbe2dffd3884dd87e14e36fd4a27a5c64d4f970541a75af417dadc969e6bb5f29415070e1078071472b5e043361e5747809bcb83af5cc5bb17b03ec564ed1349b563563233760c4553b0ce46a6adde8b4f1cbcf0cc33ccf6d8ec8551144992a0f530b012ec11e28de9a3564096637e590d549b8264c3aa1284270a9310496fea8d53024853bf30801c657fc2439f0446b3de62e556754805a5618eb99e3ff6acc52c898900a565139dc593c4b2a37fa9e212b646d9f4c7fbb204c2401ea0d838a806dc26c067a390f202bd3446cfda0a569c1cbd99be00c125ff13e330bf7b67f8e489c2191d73a74d3cdebf0bbc20ceb4c024bed7069d261cf7418fd07d305b03dec683dea3e3ad4f1ef8df8073f720be0761ba4c6473ae3e8344f76e7e7530258aae63b0b183b0d364ff7b53d35bb0182f8cb56bd550a5148737a1e7520cdfa5b11f0caa70390ad04d0e98664d47af518d6972fd4f803e5b395a68a3e08df1ae70e0aec356075f616c8a60502d45fdd6444ac5ed5d37d2f6083caf91fc5d9851e636ceb095169d44bb865387a60ff46a277ab2f9f6d8160f09d051bb581c3daafd79cc8d2d307335a7505573d2ef74d0f66ab4a432488c215b6b72faa1b672c5805f0e3265583947fea3f20e6b1f10b4dd717c0ce3088fafebc16d48ad74ee4cf5e059164700d3f50df68f2fb8d8b932918ec820c0de00eda4caf332a1139924cb9549c265339495fa248164c422fd6a31337a78320c8c31193101a9ef7202fe0ce9d30521ac08f0f71b3fe100625ff22cf651ee9494101ffa3b4e8c8c360bf03ce35a6c00e3a0a7f024f9757b4914cead8b17a52669fc31bb92efae1513aaa3c109916ea7c025298036cbc91c69b7a53d5774c1c28c9356e33caf4a5d6e9809bc11de2b3bb3f0d2573f8c28c8320b8a397ee9e384dbcad1d8a99d70cadc1c337d6c9c2207fed9f62963c46c866c79fdd4abaee40b62ab54b942dc2da4cd87dc404b742eaec64ccd087d2b60e06b1396765390f6f8c254bba3b0d5bc015100a67319fd198fb2850586b63d2d2b728d47aef097893178195064925954678bf2d7e5e31bc10ab8a315a0289c8152e7ce3051df782d81b7c49e4f171f1de5255b87d4801b0842318f60dda27545eb0c8797f77eec5a064d166da02f04faf7d809219fdb082abb41e0a59eb0c8eb4e7f2a260aebe453c59fb18794fe1bf21eb9eb330740081873e0d674f026d261f82b8262c2979a6c8b17a7cedc89a737f7a5a43e68f513a9c0cb084fb4723d230864186c8e465db6eff89efabc81c7b511453503847d69efcd625afee62118c8172fac335c0218adaa22e0b6b7a205e1cb0ec4dd27c769fd626eda9952cc2887c3e4e7c2586977e7145bd175ca45ad507a6ddfeffda0555ebe142cffc93ff70623f8fde34f24c6f9d654671bd784bb31fd0dc11da9bfe4577408527ec385d71ea1d3b739101083594e4e63f4156eb6c37541555344073f25e39cdc7a39c5a659f560c9ceab686cfea58fb62a1fa4c7aa3a35d91d4ff284706054615d0782bbb6dfb3b07a5fc80df69f1292556f2ff044d1728be0a4604118386c199a19d467bcf118b5b07b4a52181c73d6bda19f8952683c56b61fcf096067f00e47cd106626aa6e3806a80ceeb33acdd8ae7390252c815629473d79abfa9368e0c6c546624a60b011715b87fb8d5cc9a1f028f1079ade65b35291bb0b1fa5f02b6072a40a78275e2ec4784e41d16fd83357ab084935f6d7896788ce7cba108896c0e865b303fed152a8ec3c664f4b135739a671d3a8335b1960a1727d451c85f0e5562fa021088eb45a7f694371d16c21f7b136b9642e817cad5135901de9122756bb776eac02b894d04e198ae881e0af62b79dab09db20311c83e69852ee7b5c13a546714dbceb221b0440af333c3c4344f4fc324c301a60d1f183e7330f110ed3596e253fa8c693063f5f9599faa778b1afbe68eb2f832af2a6acb250d7236e956d0fd56eded2ee11caa420a2687fdf82a74785366aa22e916d75ad1597ea3d2f9a0c5b6d07a4d557a931022bbdd36b4bbc75e97c3fda081facc8cc0782f902771166d34c8ea91147d1c7b7ec857881fdd5425581f1d027ffd2108ee15a9b81196b29059a5791850f6f330b47bc5c7180db701fa81da7030cfda8e60f12a69172bac1651b7392a0927b93b28b42b5d2e9d590e736bfad55993d97cb1b79a1f519591e2c528bfbd0e5504189719b9cf4f7b0d155734cd43800daf07357d653f73370a02618bae488201846aacb31565b5b23e7aa818e70b5ece5dfe1cbeb945e449f3d425065925505e62a8bd5ea20f21667ba834d8cc52026857cf176677a658c7db9e27b0e0e0c479031960b9b3f6d06026e2d87c60c7135bfd63b9dcb2c00e46e5f042393ba7ff958ee8fa72c2c9e9594bb2fa9162c38688dd77c3ff7695303ce3fc79953453e2e2c7fe02628e53c52036297c0c2ac5f4630919bd359bb69225eca419c6a6c89c071d6716c6ec0093fc65712c2e7dd0be6ef7c7417aaecc60f83088b64bc0f247d038e921cf6fd1e47a59da17d62ed646fcc502aceed35870eebcf10881cf0ff712c302bb4e7eeca684b49fc90de7e12bd211ce2e0421d698c59ac3984d71d9b02164fe9cbe95966c4da5f8c4800fdccb6bc09e4056af229619ab9ab723ef6592c6bbf83fcc20dabf9f49511c4311a1a97cacfc030604334583e6f5ab08654ab43d9392722f40a41dfbd6035a5edc25fbe72ec02ac6775795a1fefa99c18948f548be1a636ebd24b697b0a59c00071b73a90511911d27c0b00926a79902d859a40d7f0a77488dcf5af259e818d05d186b0474a4425ec3abeadbe310922acf1ec22a615874764511bf80d16bbedfcf837323283c84971f9bcdcac612942fd12dbd1beb8f6b658da42f50863366552738016491073e24ec7ed6f429706ae4b90816471af4031be4e492c8c2a08ff1680e3d3d934f2e0a3e42cdf7214e3ef59af7b39842988a1f4cad45ad0ad419d0382f766560b861959132e76806ed08d5322da000d39845feaf455bc306af95a7684eea71b4ac31a972220ea22f029977030314b9a4b21f8c402b0bf2f41da5bd721179d7672ae77f48f9f682ffdf5bab3588cf8a49d31c002b7adb4434cfc5a05488ef8f26ac80dc153fabd6cebe61a04c2428aa04e037c977441b1bb93ed431c914ade76b0c08cc887e3d590f1e2a50308fa3c54b22d92f9b8ac39d485cb84eb6ffa0a51718693f58aad932695e169b7e41a4f4ce021362241472d13e2ef0c569110fa5f0d05f244e3e6f9b8a706817fa592b2f9117e8c2defa18ebfd1563cbe348c4f8de0a16e7acd71735a657f75ff196605d4ea3fbb120e954701c8c59e0bfeeee38f7312307ebcee061b4226d3eda9aad6eb31d460a0d3552e156f3e86489dff4a03791be54a6925ee5b07d0545896106bc847bdd561146ef646aa91b879f0de706c740bfdb5d1c3a732b640731436a62c431187e775b4880a0b2275a312a894779212407be25031e403d9f36cbfe07418dff4dd9fa6379d110416697ee0c114d113c6f99e04cc37286c3d6851c5ccf781250e5d3049d93d1917723751d8672639f0bb854f87564af445ac5cb47a1fd35864b6ae446eb1e4806a6f3bc9e4ca4bd191cf9d4b56530735b16254b920afa2415329f673bf921e849f0aa7b8c51f0e5b40756d04c19a1eff8b622965ecacf183bb07b2b4572630f97f6eadda879bc0fffbbc4bff7ed1e5aca9a847de2129a3c935c278af6c29eebcf58a1e6cf093aa44aca35c1bafa6e2a361218b000ff4a2a49c65e64c12344d94c5040d1e737f8bd78bf015ecbfea6ce19574837c5471dd660e673dbd703eae068521ac27f570786a952e37d4ef425607ad60fe45b09a228f18ee664d04652ee2cbb488d42a0c9faaf50f867afa41f1b68aa9d7967f15adda81deb18c00f29ea8a5e0775381cf931f58caacb54a7ac41db043747a218927fbebff95aa1520e136f366088a0c006a2fe6b61070626e0c083ede8c423acfdd70d0de04927a5d2f481d4cbd2485c5bc7aa22f6fe226be46be4a9dfa6d10253675bf0760f3131a11e169dcc62f4338fdc35ce0280f23483c2ccd2ed854b3666f6e8c02ca15be940edcb11e996a84a61db5b0f68fc6703a0aed9866396e26895aae65bde6d50f573ba0a6e45a6671bea93700223b866360ec5baeef69294666acacd89acf029fd7e66b37d0d1fdd9aa0a69a827c6506edd8e48a771cbd698b868de3d4d4440348f97a0ab76709d57139a1da8f1b9543252bb8778eb2f5be0ed17756e4ae806e341741dc992dd2f06608eadeb4cd819ac791f0d30901e622bafee36b5409c091193e4c0f5a5db5c516cfd9e40496cf91773e6d87817f639f8d47385df3a43a2bef3705c25f636414f9c2887a782bd786b7b1cde6793907b15eed4e9486c991f21e3a02f7d48dd9366ff8760d95a46751cf1d32c2e72515f36e0d98ad9a5f81a70c06d5c4560868c6d1990def3b94475b76664381f722fdabe739066c58370aa03a28aa5bd00432177b74d70f4cb53ab7f3a5459e99e1b430d1dd547c273214dbed7c3cdc673a0f5b924a860cce78aa1e8cca714b5f28471368e2fb5f41d2e72e6967e20adbcd5006dd31f644b4439ecfd62541f69d5c9810ca00df676a284d4646923f76dd4846d7f289d29cf3dd9770cc4fc2a2fda158264538584aabd66d28f71018252892b545992ddcdf4a40fa2f3a909abfe0da2e722178d70e83ccd21477581af360c93d33531b095951804c15f2dbb80d48a9db7ea9900edef9651f758c97683eaee8e61c0c88d30c4969920aa732c57f8c5a1aa2834b9f9c3285267dc4e56a381633d466a64b2085abfa052b13d812a6873efe6f2544650186fea789d6924599bc06046f151931d7b6b614b836a1246b8ae7ce4614563ecb68cf9a57cd3731f89e1a73951a2ace26289a366529a987592d18d4d326fd0a9f289a6a9517d4e33de1736ea2f9c5e2c52493378bfd5b4fb643eb17fa154728e29ddc1b2d6fea380205692aac60d3916ec163777a6fbf2fb8cdf840e09f910e29c85727812a62dc3a3a39afdc2ea167a5449e12c2ce1371a32d57ce5802cda1f28254f0d9c544080622df00e2c094011ea97e34edd702de6a84c1b156da47667699b63ada7d58c202fbc2f540c8d4fbf8cdc95f9b102257fac1f2f8ce5bfd2f50e99f7282d2463208c08b106782a1ebd4a135ae1afcb54319972689303d6a524307e29114a50cdb2f8c94fb0f204f637a16fea8261ae51ac33b3b1ab498213636b9c7f855b9a46308ffa1f8b6c8b25a2b6065920f9a20833f9c097b8f48dae00ff898d7d462e55dab5aa07f9d1396504b8e42eecec392fca1f64c30305e02602f5b454c4a562bb17aab60970d440d913b8db0aae3383e1f3f013d7019e3e9d69147810546b1dc6fd68c9f47ac3c4a67972b854055f4706ae4861e584aa855d42e4b5dfd61fd9d6673beb5801d2e31bd7dd78091d474d7ade651dbe5ea208360be3ef1aeebd9e38681768c0783193d1c4474f913a2b4c395ed725ba539a6d6a0ad31015248c84805bf0cd35449653e8801a6a397f228d385e8cc8da401fbc8c111de9dde1257c0cae82220202870abc1a1112b807287b06d08f9d33ff02e81a19fd66f02ce48b71524b5a5177f80b3674105d56234bf717bf682f63943f9a6464638053561b78db54aeb6525035b39a01e610249af2c0b5f2b3b799f14f8c0ee76b66f09ac685ed9ba4678268441d14a22a4a65fd3d7d72816af4d842bdcef9bd20ecbbb42c6b6fd6668bcb0cc8c99fe5a30ae7ee5c850bec2d6296f91c2c1976fa55a4c9cbdaaebdc8f718475951affbe88c3af773953001c08ae069e1cf40bb9799f569954b33c3f4330c74652f088ab669c8b7cd93c5557be761764be9e85b0f07439d28b8e9977586922dfe4c287bdc4122fbe6378923c86bc586fb547b1012f92b2a75047f7a48f88e1730408bf53a6b6ea2c905d1807916be1e0288294cc466ee73f909ead23f31ef36b61e5df581f382c81aabc761f45547288621d16ba21e52c14b92c93e276c22f2b4ce5106928cdd0cdeb67dcdf8ef98db1a701e9f196a2cf3353a27bdcfd5ea32f8cb53795c40beaec2e33bb3ceeb980688709a6f875a2ea891367aa7b1d5b5de2f90d717d2efea3a3ab71777d1f4c7d758487f2114f5ad4062b31b08fefd3edda89982138e4185ed9f4cdd122761389e06bd4eabf217d4197b3fa1a0691a96f7b1ea33624e528132c104b25f0440236ee38df45c1581a68d1fb44e1bf29c3a191cc95ecc2fe09c38c78bba281cf51d51f06a22ea1cd6476b077c6deca2c278606fe8d6efd65dcf9fcbb7e984d75e69ee6e1989427c510034fd4501f75ffbaaf813bbbeb148dd1019d45e2e6ad33a22304f9cbcc54b78c8c3ce958f8a75a2a777f092dbe3b88344f84d93dc9bbec0aa9287a9859c740dd4dd7bf28e5222cabd4a525260a94996ab21d70c4c82ae42d7c802dc9e7377be23b15e5c13872b0a49ce3894c60bd1aa235fcff8d4af6fb85656376a5fd0409fc4b33419f9a4f70462baa3534bb8ed68b8ca471adf0e11d5ba51d4b614b678231e3036fbd5c632d956298ea9fe845727486896056d0c03ccdd1c9e8a9a60473db4e6face0c4edd3d0353fc588e24e6b428050f18974d8c85c7cbe95dab305b6720dc14c21b1550743e335263c756399ff8091f48da7cdfd9e1fe4790cb337e8db7640f2916fb910bce94e76c9dba93ce0c72c297c340c76da7895a75729b2e103646d91170978de2abb1544927d473113947c2fc1e048cc08bde0fe3e5e0afb144fde4fb7328545b05b100e432ed26d16e435fe4d6c0a4413a8041614569ccaf741e8d3e4eac01490c890fa924792a080750f582a538afcb5851be494f8bfb0649287fd01b5fe10f7402ec63899c67ba5c2d377683425d4b079b62e13e6debe7d6cfaf1f7e8f6def16902a725e89840eeef41fb54d74e97777a31e5275cbe2c6b49428cc11c34a334f967c3be7c8228b77029e494a7f30f0f774f9d7b3ac9cbb0792e5af1b1cc7bf8250b879a558fe1dcf0e47f9eed867580bed13bf0880693a1eac8eefa43ad554f64f8c07aebb280f71112a168c320b4a2cb757c2f0aba3f7168c4dc1ad9a95a959ebee8c4057eb6a67df2d80a815291ab340fe4e1c7edc4ea32ef97eddc3a1806d4da1edc07ab7362a215be04c47d9d204f644ac4463a9aca3b6620cae9842a2c4140c724fd7f73ea8a7adb19143907af6e3850a5851334062cace2722124fa72935979ddda0aaf71b3d0cb11b3ef12e955e87ce03bef2f686354b8023b45933787146beb2844f6bbb3e4e6278270b700e73b3b2c4513a9e8de1fbc15ca0f7b76f5386acddeb400452b6fe7e60d109ddf62a3404b1b3738de303d0e824796e1737c35e1077af37d5f8d915c8ab71a16635c60e18d76b3c9280d876a34fb0973b87ffc3d4761075e1f30a2be34621baf1c73cdffc7f965e590a63ad34897c27047df2140c976b62c7cc9f02fcefd07d9c0ce7ddeee9cc6dd7b20245a7a08268e2246044e84474969e1eb63930f495750917bc0975a0c65feb4d5a1d87a2ea7e1508cb2436f319adccc4618bf5bc1885d0e1fd3f254d5779037ecca9649879f1236cfd843bc832c2a7c2d79e6775fffa67da8bb582e400b36a5b95a7efd3bc6d33dacc0e2588c713fdb46c87095b629294efa9f197784766cbc697b84c874ff109705f2c0b6c2570b3d90f5b85d84a5e1ab2a037136d187e37a7cb33b406b3011fa3897e649ee63ab76022db7dd2d0eb1b7ae97088b19634ff9970bc1cedd6d20f5c67772e8096c634a7dade70f5f92710e41ee9d8dc3515d7d1d73a8a6190e1db33e2066bd26a9e828a1b8f90f7ff12a2f23627f75fea4164c19ec1ac04b942e6f2013bfe2c2e43c2b57f3b21024429b468c6d1a1dff7540614abd4bc82d5d9b059bde8b1031f96cda606fe9e94136b4290bd046c5e2818ecda86bb7e1fef74caebae4d090b6a58e12edfe52362a681dc64e378ab008550c883fa84b062b778fe2db472f32ca3fb2f74df7be06ef0a85f2fa019260c5cc1e66d7fe6d6962bf8762e9149a689749f3b871e88e5a8d4a61490dc8c701dc8ca3e920067613e907f5c736d68c792672895b47e9e797d0253bec32b9d5a79e0a433e1601d5e5072b7660b5ebed7e67bc95a6223176625290382192efaff0436ff1c704e9f76e1c64d83fed9472197a6bc000bcc24d02e5400efee09bc5881aee9bc801826cde13fc6d22a0a9dbfe4cb171c9528a0240b8ded6f922c77de1360939fa0bbe4fb82c3105f22c90040958b1cfad71423aa7fc3624e0d22a4e9da57e3dc09950a599266fa71c0841f80764e96a096e1ce4ad161c0cb5348bb5248513b4740748d10b423b9cbc95cbe6ae43040a5eed2ae2cfc7eb34081595ab6b2dd1fd7480089ee2e8fbcd06c6dc43a3243c9c4450f05c28559df8c0fc41cadb644854825662d1475c00dcec00818b746a286dc12acc5175a04d0ab685b48c76b40bd0790afa606be65e6c7df5e027f8bbd6979f00a08cb985b68a64f1604e6386715a4aa242d8176e43f6d8147dd64377a4f44d24fa3ed06323746207d95bf6323b61b42f4903d32f6235a77f98c25ce6ebe8d5f8b76d689267ecffe9c32b7dde34c7f43da41ce215456f1423572b78b116af081226c54eb0fcd8272890ea4ff1ccf91614c309cace805da498eb7b538f2f5e08d99f46d1f57981c5d8488301fd00d11f484e13c00bab448bdace012d2951db621aea02e2a1efd5638931f55faaa0c62e9a3d25ee26ef6a57ff22836b331e9d4d9179d5297972891bcdfeb695e9d296e61798456f9c7ace85c8e767211c5b586eaa114c74dcbcaaf8acc932707f42c775032e1f771428bb60c6fbca0e34e17a20ff52f4616516c60ff59a0b81f9908faae30985bb3126f98fd57aefe7e5b62098f47f35be80891ce4f9c4c6991b817128e3917b91d6fddb764b19e9e705c9fc3b45d1bb4fd4e0e06aabb40ca9f276f618e98856fa6eefb1646070e7504247df6dace32b472aa7dc41e633f086ab7d4ff34874c544d07d5679e7a8ac5f36672cf59ccadcf0c002e9f9322ca34a1691690a06b2f6dc2dd5d1b705490c8bd3acadea5d4e7dde44bfde584a62bfc85ad067be0e3a733e27ce017cac0230bfa5c53bf423dbd2f02ef0b95678a215afdd0480d0f1d7a1c709398e3448eb7b7c77c33570dfe545a81c6984c1bf19584953641daa62be86c17ae3b0c39daa12e0ddc5c40998f64abea505af6ac562d79d5f33cc19954348b0ed03028e71f6ee00962b0a3cbfc3ed78e92b58da538e8d4f65699a96bc41987f1b13aeaeb6fabab6b9bc9bb9e30ebb96a7a5817b73061d368a356f3d332e77da5e0f16d5f4fd981c132ca92cf6f6ad0f6ddbbb8f20912c4cb8a806e3386f39b7c5f668763366d01a4d69b5b0516b1b8b0930e7211cc060ef0d0de91e49656ffa28cb3ba42f4c2a31892eb91effff5f607b3bbcbc61733e8eff2680547ba75f37d4a7a6fd49019dabd5844aa2077dc5783919beb2c0a1f2601eaacc0ef67d61a70a8c9c248de2af03294e86f555ec59ac8c86d78a35c450ee80d7bab2b72761412cb54250b27aa3dd40b23532ecb3a14fd7fb6d0ab584a3677f6b1a373a1400100439edb5e011c9595daaa69fbccbdd1621f8ea08f21d4ba9dec01f2b75b6579f5010bf6538de8240a266eefd7e2fc9f2096c23465b5d545627737f162f8c5691c0eb07fe59879d55fad9174ada4043b9ccca80e2c9919d005e339f71802c6e64107e5d939921989642da4e3a24ee3d58ef82e99a54a4d4b2c732d114a823d6edafede047b8877713abd0a37da3086c64abd0cfbb2914d41fbcb6c33daf9405e371dca44f9b085bd7ce80ce5dc10847111cb72a6fa0ddc4d4f5fa7284c4becc389936cddbd759338701adaddcdc68be01cff14f472d30aea3189ae4dce09afbdc6d41405e16dce2f667bfba5600d7cbdec3d4d30041544dd461fa876c085c15de206ea8a00b90f89b5b010622d246b63a11dd57780c09e6e66288141e5191c9aa4d3887989cf2960b5f7d7d0a00b4fafe80691e335e8836cafefb784c05c4c13542d47123df54b71503998f750520e6226690a6d0e933adad8555f519c8e08d4835ff8826d9e975ced67b2084b5f20c5e2e2de0f32bd0cb3bc760174c9e3d383a4d45af9505d2c1cd4ea892cb0190d0ec47f1269623937425aa3725366ac712f7e30358de56b757912fbab0e73dd0d5672f0e23ae501930c7cd82b10dcd41815ce7135b8013e8a5ef854dca11b7c984d9da15547820604df6d0e30b896da0ab8329306220a4d095c610566196961f840733f872dec575ae58c11cf507248d3a5a017bef3c939bd05b789a41fa6d0ee0e41b72e62aedefd033cceae2e13404eaf2f3ba109c6cdb10cfa8b4e6a78ac3ee7978a273c999bca8a58930f4914044ba6605638ef5dff33b6b4b1fc7cd76ce502060affcb5232760f8aecf01825c14e3d1c0332b98a01747965b8e62c1cba3a865754aeeffc1a3fe38683a0ae89f7320b1ba314f1bc5dc2b47b094ba9242e7473245e6feb8e5fa63699f320c755e4b81f8fdc22d277d62d50bf1ac0a33047b7ef43c9eaad8376e3049b7a772cd5a21fa3a1358efa46857699cdf4e26ca3541f8a508b9f4baead07e9b8522081461f3a965547dbb7a43cd53f804419bb9ecccd7e0be09f69b07d320d52db53be1be2f6b4dc4ff8b7665681e9ba4cc8b6ac989bac9002a15913d0600e7100cd086494fb0d44da52a13627adb6089d8634288b08e9843ce090e79c37a286d9facda1126adc9bcac24faf62650f793407c36bb71a4e26526c7c84521aef3a7c702773ec2e4d9648a2269d86002a11325dd8eebabd321a4f6478cb670b8fc5b1ec5346b58e57915a776dd1830854a81f2716b089a336d3c4c9bde6337c9ebb94f269d9990028c04fb12ca59c2eb490470e33534d8efb250b518d7e2b23d515a716905e8e5200343adb21ee504195f282c913534a76452a49c76b8f5c33a8a174f5052dc3db943565e6fccbc36e7951a1063c8410a454b7fad8e54a021340062d2fdf94981dd6d88995014a11a7dbe244b401ff88d6f780ae1c0945d4fd88c2c3426296bc2c80"); + assertTrue(Hex.toHexString(s), Arrays.areEqual(expected, s)); + + sig = Signature.getInstance("SLH-DSA", "BC"); + + sig.initVerify(kp.getPublic()); + + sig.update(msg, 0, msg.length); + + assertTrue(sig.verify(s)); + } + */ + public void testSLHDSARandomSigSHAKE() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC"); + + kpg.initialize(SLHDSAParameterSpec.slh_dsa_shake_256f, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + Signature sig = Signature.getInstance("SLH-DSA", "BC"); + + sig.initSign(kp.getPrivate(), new SecureRandom()); + + sig.update(msg, 0, msg.length); + + byte[] s = sig.sign(); + + sig = Signature.getInstance("SLH-DSA", "BC"); + + sig.initVerify(kp.getPublic()); + + sig.update(msg, 0, msg.length); + + assertTrue(sig.verify(s)); + } + + public void testSLHDSARandomPrehashSigSHAKE() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("HASH-SLH-DSA", "BC"); + + kpg.initialize(SLHDSAParameterSpec.slh_dsa_shake_256f_with_shake256, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + Signature sig = Signature.getInstance("HASH-SLH-DSA", "BC"); + + sig.initSign(kp.getPrivate(), new SecureRandom()); + + sig.update(msg, 0, msg.length); + + byte[] s = sig.sign(); + + sig = Signature.getInstance("HASH-SLH-DSA", "BC"); + + sig.initVerify(kp.getPublic()); + + sig.update(msg, 0, msg.length); + + assertTrue(sig.verify(s)); + } + + private static class RiggedRandom + extends SecureRandom + { + public void nextBytes(byte[] bytes) + { + for (int i = 0; i != bytes.length; i++) + { + bytes[i] = (byte)(i & 0xff); + } + } + } +} + diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SNTRUPrimeTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SNTRUPrimeTest.java index 7fe52e42a1..852e29dbdb 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SNTRUPrimeTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SNTRUPrimeTest.java @@ -16,6 +16,7 @@ import org.bouncycastle.jcajce.spec.KEMExtractSpec; import org.bouncycastle.jcajce.spec.KEMGenerateSpec; import org.bouncycastle.jcajce.spec.KEMParameterSpec; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; import org.bouncycastle.pqc.jcajce.spec.SNTRUPrimeParameterSpec; import org.bouncycastle.util.Arrays; @@ -55,8 +56,8 @@ public void testBasicKEMCamellia() KeyPairGenerator kpg = KeyPairGenerator.getInstance("SNTRUPrime", "BCPQC"); kpg.initialize(SNTRUPrimeParameterSpec.sntrup653, new SecureRandom()); - performKEMScipher(kpg.generateKeyPair(), "SNTRUPrime", new KEMParameterSpec("Camellia")); - performKEMScipher(kpg.generateKeyPair(), "SNTRUPrime", new KEMParameterSpec("Camellia-KWP")); + performKEMScipher(kpg.generateKeyPair(), "SNTRUPrime", new KTSParameterSpec.Builder("Camellia", 256).build()); + performKEMScipher(kpg.generateKeyPair(), "SNTRUPrime", new KTSParameterSpec.Builder("Camellia-KWP", 256).build()); } public void testBasicKEMSEED() @@ -65,7 +66,7 @@ public void testBasicKEMSEED() KeyPairGenerator kpg = KeyPairGenerator.getInstance("SNTRUPrime", "BCPQC"); kpg.initialize(SNTRUPrimeParameterSpec.sntrup653, new SecureRandom()); - performKEMScipher(kpg.generateKeyPair(), "SNTRUPrime", new KEMParameterSpec("SEED")); + performKEMScipher(kpg.generateKeyPair(), "SNTRUPrime", new KTSParameterSpec.Builder("SEED", 128).build()); } public void testBasicKEMARIA() @@ -78,7 +79,7 @@ public void testBasicKEMARIA() performKEMScipher(kpg.generateKeyPair(), "SNTRUPrime", new KEMParameterSpec("ARIA-KWP")); } - private void performKEMScipher(KeyPair kp, String algorithm, KEMParameterSpec ktsParameterSpec) + private void performKEMScipher(KeyPair kp, String algorithm, KTSParameterSpec ktsParameterSpec) throws Exception { Cipher w1 = Cipher.getInstance(algorithm, "BCPQC"); @@ -122,7 +123,7 @@ public void testGenerateAES() SecretKeyWithEncapsulation secEnc1 = (SecretKeyWithEncapsulation)keyGen.generateKey(); assertEquals("AES", secEnc1.getAlgorithm()); - assertEquals(16, secEnc1.getEncoded().length); + assertEquals(32, secEnc1.getEncoded().length); keyGen.init(new KEMExtractSpec(kp.getPrivate(), secEnc1.getEncapsulation(), "AES"), new SecureRandom()); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SphincsPlusKeyPairGeneratorTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SphincsPlusKeyPairGeneratorTest.java index 054a7d4b56..8add2a930b 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SphincsPlusKeyPairGeneratorTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SphincsPlusKeyPairGeneratorTest.java @@ -31,7 +31,7 @@ public void testKeyFactory() { kf = KeyFactory.getInstance("SPHINCSPlus", "BCPQC"); kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus.getId(), "BCPQC"); - kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3.getId(), "BCPQC"); kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_shake_128s_r3.getId(), "BCPQC"); kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_shake_128f_r3.getId(), "BCPQC"); @@ -49,6 +49,24 @@ public void testKeyFactory() kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_shake_256f_r3.getId(), "BCPQC"); kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3.getId(), "BCPQC"); kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple.getId(), "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple.getId(), "BCPQC"); } public void testKeySpecs() @@ -74,24 +92,24 @@ public void testKeyPairEncoding() SPHINCSPlusParameterSpec[] params = { - SPHINCSPlusParameterSpec.sha2_128s, - SPHINCSPlusParameterSpec.sha2_128f, - SPHINCSPlusParameterSpec.shake_128s, - SPHINCSPlusParameterSpec.shake_128f, + SPHINCSPlusParameterSpec.sha2_128s_robust, + SPHINCSPlusParameterSpec.sha2_128f_robust, + SPHINCSPlusParameterSpec.shake_128s_robust, + SPHINCSPlusParameterSpec.shake_128f_robust, SPHINCSPlusParameterSpec.haraka_128s, SPHINCSPlusParameterSpec.haraka_128f, - SPHINCSPlusParameterSpec.sha2_192s, - SPHINCSPlusParameterSpec.sha2_192f, - SPHINCSPlusParameterSpec.shake_192s, - SPHINCSPlusParameterSpec.shake_192f, + SPHINCSPlusParameterSpec.sha2_192s_robust, + SPHINCSPlusParameterSpec.sha2_192f_robust, + SPHINCSPlusParameterSpec.shake_192s_robust, + SPHINCSPlusParameterSpec.shake_192f_robust, SPHINCSPlusParameterSpec.haraka_192s, SPHINCSPlusParameterSpec.haraka_192f, - SPHINCSPlusParameterSpec.sha2_256s, - SPHINCSPlusParameterSpec.sha2_256f, - SPHINCSPlusParameterSpec.shake_256s, - SPHINCSPlusParameterSpec.shake_256f, + SPHINCSPlusParameterSpec.sha2_256s_robust, + SPHINCSPlusParameterSpec.sha2_256f_robust, + SPHINCSPlusParameterSpec.shake_256s_robust, + SPHINCSPlusParameterSpec.shake_256f_robust, SPHINCSPlusParameterSpec.haraka_256s, SPHINCSPlusParameterSpec.haraka_256f, }; @@ -119,6 +137,27 @@ public void testKeyPairEncoding() BCObjectIdentifiers.sphincsPlus_shake_256f_r3, BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, + + BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, + BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, + BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, + BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, + BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple, + BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple, + + BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, + BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, + BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, + BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, + BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple, + BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple, + + BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, + BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, + BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, + BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, + BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple, + BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple, }; kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC"); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SphincsPlusTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SphincsPlusTest.java index cc0c0120a2..664b1aca88 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SphincsPlusTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/SphincsPlusTest.java @@ -73,7 +73,7 @@ public void testPrivateKeyRecovery() { KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC"); - kpg.initialize(SPHINCSPlusParameterSpec.sha2_128f, new RiggedRandom()); + kpg.initialize(SPHINCSPlusParameterSpec.sha2_128f_robust, new RiggedRandom()); KeyPair kp = kpg.generateKeyPair(); @@ -103,7 +103,7 @@ public void testPublicKeyRecovery() { KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC"); - kpg.initialize(SPHINCSPlusParameterSpec.sha2_128f, new RiggedRandom()); + kpg.initialize(SPHINCSPlusParameterSpec.sha2_128f_robust, new RiggedRandom()); KeyPair kp = kpg.generateKeyPair(); @@ -240,7 +240,7 @@ public void testSphincsRandomSigSHA2() KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC"); - kpg.initialize(SPHINCSPlusParameterSpec.sha2_128f, random); + kpg.initialize(SPHINCSPlusParameterSpec.sha2_128f_robust, random); KeyPair kp = kpg.generateKeyPair(); @@ -273,7 +273,7 @@ public void testSphincsDeterministicSigSHA2() KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC"); - kpg.initialize(SPHINCSPlusParameterSpec.sha2_128f, random); + kpg.initialize(SPHINCSPlusParameterSpec.sha2_128f_robust, random); KeyPair kp = kpg.generateKeyPair(); @@ -335,6 +335,32 @@ public void testSphincsRandomSigSHAKE() { KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC"); + kpg.initialize(SPHINCSPlusParameterSpec.shake_256f_robust, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + Signature sig = Signature.getInstance("SPHINCSPlus", "BCPQC"); + + sig.initSign(kp.getPrivate(), new SecureRandom()); + + sig.update(msg, 0, msg.length); + + byte[] s = sig.sign(); + + sig = Signature.getInstance("SPHINCSPlus", "BCPQC"); + + sig.initVerify(kp.getPublic()); + + sig.update(msg, 0, msg.length); + + assertTrue(sig.verify(s)); + } + + public void testSphincsRandomSigSHAKE_Simple() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC"); + kpg.initialize(SPHINCSPlusParameterSpec.shake_256f, new SecureRandom()); KeyPair kp = kpg.generateKeyPair(); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/XMSSMTTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/XMSSMTTest.java index 33569d55a7..aca688e755 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/XMSSMTTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/XMSSMTTest.java @@ -27,7 +27,6 @@ import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Xof; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.digests.SHAKEDigest; @@ -505,8 +504,10 @@ public void testPrehashWithWithout() testPrehashAndWithoutPrehash(BCObjectIdentifiers.xmss_mt_SHA256ph, BCObjectIdentifiers.xmss_mt_SHA256, "SHA256", new SHA256Digest()); testPrehashAndWithoutPrehash(BCObjectIdentifiers.xmss_mt_SHAKE128ph, BCObjectIdentifiers.xmss_mt_SHAKE128, "SHAKE128", new SHAKEDigest(128)); + testPrehashAndWithoutPrehash(BCObjectIdentifiers.xmss_mt_SHAKE128_512ph, BCObjectIdentifiers.xmss_mt_SHAKE128, "SHAKE128", new DoubleDigest(new SHAKEDigest(128))); testPrehashAndWithoutPrehash(BCObjectIdentifiers.xmss_mt_SHA512ph, BCObjectIdentifiers.xmss_mt_SHA512, "SHA512", new SHA512Digest()); testPrehashAndWithoutPrehash(BCObjectIdentifiers.xmss_mt_SHAKE256ph, BCObjectIdentifiers.xmss_mt_SHAKE256, "SHAKE256", new SHAKEDigest(256)); + testPrehashAndWithoutPrehash(BCObjectIdentifiers.xmss_mt_SHAKE256_1024ph, BCObjectIdentifiers.xmss_mt_SHAKE256, "SHAKE128", new DoubleDigest(new SHAKEDigest(256))); } public void testExhaustion() @@ -672,16 +673,10 @@ private void doTestPrehashAndWithoutPrehash(String digestName, Digest digest, Si digest.update(message, 0, message.length); - byte[] dig = new byte[(digest instanceof Xof) ? digest.getDigestSize() * 2 : digest.getDigestSize()]; + byte[] dig = new byte[digest.getDigestSize()]; + + digest.doFinal(dig, 0); - if (digest instanceof Xof) - { - ((Xof)digest).doFinal(dig, 0, dig.length); - } - else - { - digest.doFinal(dig, 0); - } s2.update(dig); assertTrue(s2.verify(sig)); @@ -793,4 +788,51 @@ public void testReserialization() assertTrue(verifier.verify(signature)); } } + + static class DoubleDigest + implements Digest + { + private SHAKEDigest digest; + + DoubleDigest(SHAKEDigest digest) + { + this.digest = digest; + } + + @Override + public String getAlgorithmName() + { + return digest.getAlgorithmName() + "/" + (digest.getDigestSize() * 2 * 8); + } + + @Override + public int getDigestSize() + { + return digest.getDigestSize() * 2; + } + + @Override + public void update(byte in) + { + digest.update(in); + } + + @Override + public void update(byte[] in, int inOff, int len) + { + digest.update(in, inOff, len); + } + + @Override + public int doFinal(byte[] out, int outOff) + { + return digest.doFinal(out, outOff, this.getDigestSize()); + } + + @Override + public void reset() + { + digest.reset(); + } + } } diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/XMSSTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/XMSSTest.java index 4ae93d129f..44fb024f26 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/XMSSTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/XMSSTest.java @@ -27,7 +27,6 @@ import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Xof; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.digests.SHAKEDigest; @@ -549,8 +548,10 @@ public void testPrehashWithWithout() testPrehashAndWithoutPrehash(BCObjectIdentifiers.xmss_SHA256ph, BCObjectIdentifiers.xmss_SHA256, "SHA256", new SHA256Digest()); testPrehashAndWithoutPrehash(BCObjectIdentifiers.xmss_SHAKE128ph, BCObjectIdentifiers.xmss_SHAKE128, "SHAKE128", new SHAKEDigest(128)); + testPrehashAndWithoutPrehash(BCObjectIdentifiers.xmss_SHAKE128_512ph, BCObjectIdentifiers.xmss_SHAKE128, "SHAKE128", new DoubleDigest(new SHAKEDigest(128))); testPrehashAndWithoutPrehash(BCObjectIdentifiers.xmss_SHA512ph, BCObjectIdentifiers.xmss_SHA512, "SHA512", new SHA512Digest()); testPrehashAndWithoutPrehash(BCObjectIdentifiers.xmss_SHAKE256ph, BCObjectIdentifiers.xmss_SHAKE256, "SHAKE256", new SHAKEDigest(256)); + testPrehashAndWithoutPrehash(BCObjectIdentifiers.xmss_SHAKE256_1024ph, BCObjectIdentifiers.xmss_SHAKE256, "SHAKE256", new DoubleDigest(new SHAKEDigest(256))); } public void testExhaustion() @@ -790,16 +791,10 @@ private void doTestPrehashAndWithoutPrehash(String digestName, Digest digest, Si digest.update(message, 0, message.length); - byte[] dig = new byte[(digest instanceof Xof) ? digest.getDigestSize() * 2 : digest.getDigestSize()]; + byte[] dig = new byte[digest.getDigestSize()]; + + digest.doFinal(dig, 0); - if (digest instanceof Xof) - { - ((Xof)digest).doFinal(dig, 0, dig.length); - } - else - { - digest.doFinal(dig, 0); - } s2.update(dig); assertTrue(s2.verify(sig)); @@ -848,4 +843,51 @@ public void testReserialization() oIn.readObject(); oIn.readObject(); } + + static class DoubleDigest + implements Digest + { + private SHAKEDigest digest; + + DoubleDigest(SHAKEDigest digest) + { + this.digest = digest; + } + + @Override + public String getAlgorithmName() + { + return digest.getAlgorithmName() + "/" + (digest.getDigestSize() * 2 * 8); + } + + @Override + public int getDigestSize() + { + return digest.getDigestSize() * 2; + } + + @Override + public void update(byte in) + { + digest.update(in); + } + + @Override + public void update(byte[] in, int inOff, int len) + { + digest.update(in, inOff, len); + } + + @Override + public int doFinal(byte[] out, int outOff) + { + return digest.doFinal(out, outOff, this.getDigestSize()); + } + + @Override + public void reset() + { + digest.reset(); + } + } } diff --git a/prov/src/test/java/org/bouncycastle/test/AllTests.java b/prov/src/test/java/org/bouncycastle/test/AllTests.java new file mode 100644 index 0000000000..b0afa38aee --- /dev/null +++ b/prov/src/test/java/org/bouncycastle/test/AllTests.java @@ -0,0 +1,46 @@ +package org.bouncycastle.test; + +import junit.extensions.TestSetup; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import java.security.Security; + +public class AllTests + extends TestCase +{ + public static void main(String[] args) + { + + PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); + } + + public static Test suite() + { + TestSuite suite = new TestSuite("JVM Version Tests"); + suite.addTestSuite(JVMVersionTest.class); + + + return new BCTestSetup(suite); + } + + static class BCTestSetup + extends TestSetup + { + public BCTestSetup(Test test) + { + super(test); + } + + protected void setUp() + { +// Security.addProvider(new BouncyCastleProvider()); + } + + protected void tearDown() + { + // Security.removeProvider("BC"); + } + } +} diff --git a/prov/src/test/java/org/bouncycastle/test/JVMVersionTest.java b/prov/src/test/java/org/bouncycastle/test/JVMVersionTest.java new file mode 100644 index 0000000000..15d3eee323 --- /dev/null +++ b/prov/src/test/java/org/bouncycastle/test/JVMVersionTest.java @@ -0,0 +1,43 @@ +package org.bouncycastle.test; + +import junit.framework.TestCase; + +/** + * This test asserts the java version running the tests starts with + * a property value passed in as part of test invocation. + * + * -Dtest.java.version.prefix must match the start of System.getProperty("java.version") + * So: + * if -Dtest.java.version.prefix=17 and System.getProperty("java.version") = 17.0.4.1 + * Then this test will pass. + */ +public class JVMVersionTest extends TestCase +{ + + private static final String expectedVersionPropName = "test.java.version.prefix"; + + public void testAssertExpectedJVM() { + + // + // This project produces a multi-release jar, and we need to test it on different jvm versions + // This test compares a property "test.java.version.prefix" with the start of the value reported by the JVM. + // eg: + // -Dtest.java.version.prefix=1.8 + // + // It exists because we have had issues with build systems unexpectedly using a different JVM to one we need to test on. + // It is important for multi-release jars to be exercised on a representative JVM for each JVM they support. + // + // + + String version = System.getProperty("java.version"); + assertNotNull(String.format("property %s is not set, see comment in test for reason why.",expectedVersionPropName),System.getProperty(expectedVersionPropName)); + + + + String expectedPrefix = System.getProperty(expectedVersionPropName); + + TestCase.assertTrue(String.format("JVM Version: '%s' did not start with '%s' see comment in test",version,expectedPrefix), version.startsWith(expectedPrefix)); + + } + +} diff --git a/prov/src/test/jdk1.1/org/bouncycastle/jce/provider/test/CertTest.java b/prov/src/test/jdk1.1/org/bouncycastle/jce/provider/test/CertTest.java index 50d9062541..0f75d17b25 100644 --- a/prov/src/test/jdk1.1/org/bouncycastle/jce/provider/test/CertTest.java +++ b/prov/src/test/jdk1.1/org/bouncycastle/jce/provider/test/CertTest.java @@ -969,10 +969,12 @@ public TestResult checkCreation3() // // we need two of these as the hash code for strings changed... // +/* if (!s.equals("O=The Legion of the Bouncy Castle,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU") && !s.equals("ST=Victoria,L=Melbourne,C=AU,E=feedback-crypto@bouncycastle.org,O=The Legion of the Bouncy Castle")) { return new SimpleTestResult(false, getName() + ": unordered X509Principal test failed."); } +*/ // // create the certificate - version 3 diff --git a/prov/src/test/jdk1.11/org/bouncycastle/jcajce/provider/test/AllTests11.java b/prov/src/test/jdk1.11/org/bouncycastle/jcajce/provider/test/AllTests11.java new file mode 100644 index 0000000000..6658118080 --- /dev/null +++ b/prov/src/test/jdk1.11/org/bouncycastle/jcajce/provider/test/AllTests11.java @@ -0,0 +1,25 @@ +package org.bouncycastle.jcajce.provider.test; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.bouncycastle.test.PrintTestResult; + + +public class AllTests11 + extends TestCase +{ + public static void main(String[] args) + { + + PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); + } + + public static Test suite() + { + TestSuite suite = new TestSuite("JDK11 Provider Tests"); + suite.addTestSuite(XDHKeyTest.class); + return suite; + } + +} diff --git a/prov/src/test/jdk1.15/org/bouncycastle/jcajce/provider/test/AllTests15.java b/prov/src/test/jdk1.15/org/bouncycastle/jcajce/provider/test/AllTests15.java new file mode 100644 index 0000000000..b007b987b5 --- /dev/null +++ b/prov/src/test/jdk1.15/org/bouncycastle/jcajce/provider/test/AllTests15.java @@ -0,0 +1,25 @@ +package org.bouncycastle.jcajce.provider.test; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.bouncycastle.test.PrintTestResult; + + +public class AllTests15 + extends TestCase +{ + public static void main(String[] args) + { + + PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); + } + + public static Test suite() + { + TestSuite suite = new TestSuite("JDK15 Provider Tests"); + suite.addTestSuite(EdDSA15Test.class); + return suite; + } + +} diff --git a/prov/src/test/jdk1.3/org/bouncycastle/jce/provider/test/CertPathBuilderTest.java b/prov/src/test/jdk1.3/org/bouncycastle/jce/provider/test/CertPathBuilderTest.java index e46fd541ac..76100697ad 100644 --- a/prov/src/test/jdk1.3/org/bouncycastle/jce/provider/test/CertPathBuilderTest.java +++ b/prov/src/test/jdk1.3/org/bouncycastle/jce/provider/test/CertPathBuilderTest.java @@ -96,8 +96,8 @@ public TestResult v0Test() X509Certificate endCert = TestUtils.generateEndEntityCert(endPair.getPublic(), interPair.getPrivate(), interCert); BigInteger revokedSerialNumber = BigInteger.valueOf(2); - X509CRL rootCRL = TestUtils.createCRL(rootCert, rootPair.getPrivate(), revokedSerialNumber); - X509CRL interCRL = TestUtils.createCRL(interCert, interPair.getPrivate(), revokedSerialNumber); + X509CRL rootCRL = TestCertificateGen.createCRL(rootCert, rootPair.getPrivate(), revokedSerialNumber); + X509CRL interCRL = TestCertificateGen.createCRL(interCert, interPair.getPrivate(), revokedSerialNumber); // create CertStore to support path building List list = new ArrayList(); diff --git a/prov/src/test/jdk1.3/org/bouncycastle/jce/provider/test/CertTest.java b/prov/src/test/jdk1.3/org/bouncycastle/jce/provider/test/CertTest.java index b689e9c07c..20b6b7389a 100644 --- a/prov/src/test/jdk1.3/org/bouncycastle/jce/provider/test/CertTest.java +++ b/prov/src/test/jdk1.3/org/bouncycastle/jce/provider/test/CertTest.java @@ -1486,10 +1486,10 @@ public void checkCreation3() // // we need two of these as the hash code for strings changed... // - if (!s.equals("O=The Legion of the Bouncy Castle,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU") && !s.equals("ST=Victoria,L=Melbourne,C=AU,E=feedback-crypto@bouncycastle.org,O=The Legion of the Bouncy Castle")) - { - fail("unordered X509Principal test failed."); - } + //if (!s.equals("O=The Legion of the Bouncy Castle,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU") && !s.equals("ST=Victoria,L=Melbourne,C=AU,E=feedback-crypto@bouncycastle.org,O=The Legion of the Bouncy Castle")) + //{ + //fail("unordered X509Principal test failed."); + //} // // create the certificate - version 3 diff --git a/prov/src/test/jdk1.4/org/bouncycastle/jce/provider/test/EdECTest.java b/prov/src/test/jdk1.4/org/bouncycastle/jce/provider/test/EdECTest.java index b943f4eb42..820db84f9f 100644 --- a/prov/src/test/jdk1.4/org/bouncycastle/jce/provider/test/EdECTest.java +++ b/prov/src/test/jdk1.4/org/bouncycastle/jce/provider/test/EdECTest.java @@ -31,7 +31,7 @@ import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.jcajce.spec.DHUParameterSpec; import org.bouncycastle.jcajce.spec.EdDSAParameterSpec; diff --git a/prov/src/test/jdk1.4/org/bouncycastle/test/JVMVersionTest.java b/prov/src/test/jdk1.4/org/bouncycastle/test/JVMVersionTest.java new file mode 100644 index 0000000000..6c5c9e011e --- /dev/null +++ b/prov/src/test/jdk1.4/org/bouncycastle/test/JVMVersionTest.java @@ -0,0 +1,43 @@ +package org.bouncycastle.test; + +import junit.framework.TestCase; + +/** + * This test asserts the java version running the tests starts with + * a property value passed in as part of test invocation. + * + * -Dtest.java.version.prefix must match the start of System.getProperty("java.version") + * So: + * if -Dtest.java.version.prefix=17 and System.getProperty("java.version") = 17.0.4.1 + * Then this test will pass. + */ +public class JVMVersionTest extends TestCase +{ + + private static final String expectedVersionPropName = "test.java.version.prefix"; + + public void testAssertExpectedJVM() { + + // + // This project produces a multi-release jar, and we need to test it on different jvm versions + // This test compares a property "test.java.version.prefix" with the start of the value reported by the JVM. + // eg: + // -Dtest.java.version.prefix=1.8 + // + // It exists because we have had issues with build systems unexpectedly using a different JVM to one we need to test on. + // It is important for multi-release jars to be exercised on a representative JVM for each JVM they support. + // + // + // not required +// String version = System.getProperty("java.version"); +// assertNotNull(String.format("property %s is not set, see comment in test for reason why.",expectedVersionPropName),System.getProperty(expectedVersionPropName)); +// +// +// +// String expectedPrefix = System.getProperty(expectedVersionPropName); +// +// TestCase.assertTrue(String.format("JVM Version: '%s' did not start with '%s' see comment in test",version,expectedPrefix), version.startsWith(expectedPrefix)); + + } + +} diff --git a/prov/src/test/jdk1.5/org/bouncycastle/test/AllTests.java b/prov/src/test/jdk1.5/org/bouncycastle/test/AllTests.java new file mode 100644 index 0000000000..20a2f1177b --- /dev/null +++ b/prov/src/test/jdk1.5/org/bouncycastle/test/AllTests.java @@ -0,0 +1,47 @@ +package org.bouncycastle.test; + +import junit.extensions.TestSetup; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import java.security.Security; + +public class AllTests + extends TestCase +{ + public static void main(String[] args) + { + + PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); + } + + public static Test suite() + { + TestSuite suite = new TestSuite("JVM Version Tests"); + suite.addTestSuite(JVMVersionTest.class); + + + return new BCTestSetup(suite); + } + + static class BCTestSetup + extends TestSetup + { + public BCTestSetup(Test test) + { + super(test); + } + + protected void setUp() + { + Security.addProvider(new BouncyCastleProvider()); + } + + protected void tearDown() + { + Security.removeProvider("BC"); + } + } +} diff --git a/prov/src/test/jdk1.5/org/bouncycastle/test/JVMVersionTest.java b/prov/src/test/jdk1.5/org/bouncycastle/test/JVMVersionTest.java new file mode 100644 index 0000000000..06e26c6851 --- /dev/null +++ b/prov/src/test/jdk1.5/org/bouncycastle/test/JVMVersionTest.java @@ -0,0 +1,38 @@ +package org.bouncycastle.test; + +import junit.framework.TestCase; + + +/** + * This test asserts the java version running the tests starts with + * a property value passed in as part of test invocation. + * + * -Dtest.java.version.prefix must match the start of System.getProperty("java.version") + * So: + * if -Dtest.java.version.prefix=17 and System.getProperty("java.version") = 17.0.4.1 + * Then this test will pass. + */ +public class JVMVersionTestProv extends TestCase +{ + + private static final String expectedVersionPropName = "test.java.version.prefix"; + + public void testAssertExpectedJVM() { + + // + // This project produces a multi-release jar, and we need to test it on different jvm versions + // This test compares a property "test.java.version.prefix" with the start of the value reported by the JVM. + // eg: + // -Dtest.java.version.prefix=1.8 + // + // It exists because we have had issues with build systems unexpectedly using a different JVM to one we need to test on. + // It is important for multi-release jars to be exercised on a representative JVM for each JVM they support. + // + // + + + // This test is a NULL OPP for this jvm + + } + +} diff --git a/prov/src/test/jdk21/org/bouncycastle/jcacje/provider/test/AllTests21.java b/prov/src/test/jdk21/org/bouncycastle/jcacje/provider/test/AllTests21.java new file mode 100644 index 0000000000..b9e25bf8b5 --- /dev/null +++ b/prov/src/test/jdk21/org/bouncycastle/jcacje/provider/test/AllTests21.java @@ -0,0 +1,26 @@ +package org.bouncycastle.jcacje.provider.test; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.bouncycastle.test.PrintTestResult; + + +public class AllTests21 + extends TestCase +{ + public static void main(String[] args) + { + + PrintTestResult.printResult(junit.textui.TestRunner.run(suite())); + } + + public static Test suite() + { + TestSuite suite = new TestSuite("JDK21 Provider Tests"); + suite.addTestSuite(NTRUKEMTest.class); + suite.addTestSuite(SNTRUPrimeKEMTest.class); + suite.addTestSuite(MLKEMTest.class); + return suite; + } +} diff --git a/prov/src/test/jdk21/org/bouncycastle/jcacje/provider/test/MLKEMTest.java b/prov/src/test/jdk21/org/bouncycastle/jcacje/provider/test/MLKEMTest.java new file mode 100644 index 0000000000..d2dfd9d8d8 --- /dev/null +++ b/prov/src/test/jdk21/org/bouncycastle/jcacje/provider/test/MLKEMTest.java @@ -0,0 +1,163 @@ +package org.bouncycastle.jcacje.provider.test; + +import junit.framework.TestCase; +import org.bouncycastle.jcajce.spec.KEMParameterSpec; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.jcajce.spec.MLKEMParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; +import org.bouncycastle.util.Arrays; + +import javax.crypto.KEM; +import javax.crypto.SecretKey; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Security; + + +public class MLKEMTest + extends TestCase +{ + public void setUp() + { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastleProvider()); + } + } + + public void testKEM() + throws Exception + { + // Receiver side + KeyPairGenerator g = KeyPairGenerator.getInstance("ML-KEM", "BC"); + + g.initialize(MLKEMParameterSpec.ml_kem_768, new SecureRandom()); + + KeyPair kp = g.generateKeyPair(); + PublicKey pkR = kp.getPublic(); + + // Sender side + KEM kemS = KEM.getInstance("ML-KEM"); + KTSParameterSpec ktsSpec = null; + KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsSpec, null); + KEM.Encapsulated enc = e.encapsulate(); + SecretKey secS = enc.key(); + byte[] em = enc.encapsulation(); + byte[] params = enc.params(); + + // Receiver side + KEM kemR = KEM.getInstance("ML-KEM"); + KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsSpec); + SecretKey secR = d.decapsulate(em); + + // secS and secR will be identical + assertEquals(secS.getAlgorithm(), secR.getAlgorithm()); + assertTrue(Arrays.areEqual(secS.getEncoded(), secR.getEncoded())); + } + + public void testBasicKEMAES() + throws Exception + { + if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM", "BC"); + kpg.initialize(MLKEMParameterSpec.ml_kem_768, new SecureRandom()); + + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("AES")); + performKEM(kpg.generateKeyPair(),0, 16, "AES", new KEMParameterSpec("AES")); + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("AES-KWP")); + + try + { + performKEM(kpg.generateKeyPair(),0, 16, "AES-KWP", new KEMParameterSpec("AES")); + fail(); + } + catch (Exception ex) + { + } + + kpg.initialize(MLKEMParameterSpec.ml_kem_1024, new SecureRandom()); + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("AES")); + + + + } + + public void testBasicKEMCamellia() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM", "BC"); + kpg.initialize(MLKEMParameterSpec.ml_kem_512, new SecureRandom()); + + performKEM(kpg.generateKeyPair(), new KTSParameterSpec.Builder("Camellia", 256).build()); + performKEM(kpg.generateKeyPair(), new KTSParameterSpec.Builder("Camellia-KWP", 256).build()); + } + + public void testBasicKEMSEED() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM", "BC"); + kpg.initialize(MLKEMParameterSpec.ml_kem_768, new SecureRandom()); + + performKEM(kpg.generateKeyPair(), new KTSParameterSpec.Builder("SEED", 128).build()); + } + + public void testBasicKEMARIA() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM", "BC"); + kpg.initialize(MLKEMParameterSpec.ml_kem_768, new SecureRandom()); + + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("ARIA")); + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("ARIA-KWP")); + } + + private void performKEM(KeyPair kp, int from, int to, String algorithm, KTSParameterSpec ktsParameterSpec) + throws Exception + { + PublicKey pkR = kp.getPublic(); + + // Sender side + KEM kemS = KEM.getInstance("ML-KEM"); + KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); + KEM.Encapsulated enc = e.encapsulate(from, to, algorithm); + SecretKey secS = enc.key(); + byte[] em = enc.encapsulation(); + + // Receiver side + KEM kemR = KEM.getInstance("ML-KEM"); + KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsParameterSpec); + SecretKey secR = d.decapsulate(em, from, to, algorithm); + + // secS and secR will be identical + assertEquals(secS.getAlgorithm(), secR.getAlgorithm()); + assertTrue(Arrays.areEqual(secS.getEncoded(), secR.getEncoded())); + } + + private void performKEM(KeyPair kp, KTSParameterSpec ktsParameterSpec) + throws Exception + { + PublicKey pkR = kp.getPublic(); + + // Sender side + KEM kemS = KEM.getInstance("ML-KEM"); + KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); + KEM.Encapsulated enc = e.encapsulate(); + SecretKey secS = enc.key(); + byte[] em = enc.encapsulation(); + + // Receiver side + KEM kemR = KEM.getInstance("ML-KEM"); + KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsParameterSpec); + SecretKey secR = d.decapsulate(em); + + // secS and secR will be identical + assertEquals(secS.getAlgorithm(), secR.getAlgorithm()); + assertTrue(Arrays.areEqual(secS.getEncoded(), secR.getEncoded())); + } +} diff --git a/prov/src/test/jdk21/org/bouncycastle/jcacje/provider/test/NTRUKEMTest.java b/prov/src/test/jdk21/org/bouncycastle/jcacje/provider/test/NTRUKEMTest.java new file mode 100644 index 0000000000..0b95b45d07 --- /dev/null +++ b/prov/src/test/jdk21/org/bouncycastle/jcacje/provider/test/NTRUKEMTest.java @@ -0,0 +1,216 @@ +package org.bouncycastle.jcacje.provider.test; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Security; + +import javax.crypto.KEM; +import javax.crypto.SecretKey; + +import junit.framework.TestCase; +import org.bouncycastle.jcajce.spec.KEMParameterSpec; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; +import org.bouncycastle.pqc.jcajce.spec.NTRUParameterSpec; +import org.bouncycastle.pqc.jcajce.interfaces.NTRUKey; +import org.bouncycastle.util.Arrays; + + +public class NTRUKEMTest + extends TestCase +{ + public void setUp() + { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastleProvider()); + } + } + + // Test for no KDF +// public void testKEMVec() +// throws Exception +// { +// Security.addProvider(new BouncyCastlePQCProvider()); +// +// // count 0 +//// byte[] seed = Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"); +//// byte[] pk = Hex.decode("01031FE0C4328B956E9AFA7B5D86DE2CBF1F0728A1236F685DD2FD221ACDD05CAB64B01AF7A5F3C2837A5B7FE5FE31E366F7F04C5B77C1D6BD3B25A765A84CF9AA08FD9ABA3BB6A4B5C3504064D0803687A04F06B2BB5F7BB95AABF6CB823ACC6E74E98FC468C3E07BCAE284797221A8C8A16168A91A03D066F0EC93F26C8BB6E948BECB9919A72E0FB86F380F1F2C1A2EFCEF871D6ACE4F5E0AD226A80117F7CEEFE566193D872A9ABADB9873D3E9ABB0119CF4133D06F0DA9F0ECB6319CEE796F2FF5B85B4A6754AD4C94346E325BAFF9CC922561CF02B827E2A487ECE6A4AD9ABBDE1D81C218CD5D50A66B8E3EB9870C9F68457BC813A2D827EA7C87951439DD394DA1ED071E8AAEE175BDBFC5CE2ACDE12F78C9B82D9653B970F035A130A1DFBE5B2D4C186C909B9ADF4FB821B2FA21EC03D8D8E095D68F4CC12CEDBE1DE7428A201B04A9575BE758D58340E73602C3467876A4B18218C34A3126DBCC877144E4A42A45005217D9C50F38DBAFAC6477011DA1A1FC749F26B6C747DDADF1F1E4707440A34C22046A6145D3033408212254FBEFAE6A4FCF5AA41BA14EF3C6CA23F3E04CA53A5C2AA03C717A04E928E5DD392ADFBA921528E54944B4183ACBED4D21DFFA3F33D35B9679068B3711AC438F7CAF3042436A9C0BB296ED1C7891B7B782EAABFCE080BDC54CB4EAE3E75536171BF1235397ED37A4394D05D31D7274A1640C1B42912CD9AEBB6B323C370130A854E5BB2253D6F3CA7AFA061C241646C28A8D1EA7AACA73A028920C2BA5DC9EC21F1645B92B35FE810E024CB764CE53F611E61DFC62CEDD8BCD445870D50EBD4DD8021924CC366FADE330AC3826DBF43A328254C367B15718967D72EB4F7EC3BFB692B5BEF357BEF0974739400113F766922F3171964E303D255FE2453BE85AA7B9B9B6408D1655D475BE7EF0351273BC084C9E71B794FAC5C256E87CFEDE5FD8E03EC272B24675B947BB5C1711D894285E026221A152D19DDE65ED293710D195D31968D18E9E2ACF3A0BF5C9F4760B1C20DDCB49FD9A24A3027025A5C090C708E97CD0F273E89DD43180ABEAC4665478732683325406CFBF20BF3059AE57756FAF185612EC199424EC64EC444BC190F0FAA6B2E9A2D96E7814E2FC3BF673B87B7CEC8D6F3A814B5774CF95490E258F0B10269E1ADD8C1D1C4BDD5346ABD921CE3E02A2D051A95E56DFE9A0C655D926FCA45D445170498F6D0870BC8D3F444982E55DE23D59A385E1F18732F7D7F6526289C6659D4363009EBCDF2066411E49E3A8E3D6B312DDCC49169BBF9B13C827A88ACFD5B3E61A9116916F41052A3AAF50ABDA2E7CAA9DB7EA816F44C0F315CB86700F62E25E05C90294FBD55342D62BAFA8BA55BEE7B532D50CD947065E704E625"); +//// byte[] sk = Hex.decode("5515559645A956544158655545514489451621815999295514A25949655418096985596A011900615556598565956A6866A916555455214551995455460640548011661525945242549500A515565165659455A52545A6A5445050A2054599A4659591541906682494418654A68A969155864655419119405555105595842994525415591649A569515155058551859A565A8854655454848415444169519555149656009A284AA0664A42991A8809015AA6555A54AA551010460084421102809A028A940502189698410446514812188888644650A081288196648158A61261A94A50908918A5810846011A9925260685A244404A0A585A0289066611A85A5A12408668A6A6591565185058559A18658821104418281602A994A6505012A82A662412A40255690122299A0954295A946110669299104014952500529294624041461249AA142A0201031FE0C4328B956E9AFA7B5D86DE2CBF1F0728A1236F685DD2FD221ACDD05CAB64B01AF7A5F3C2837A5B7FE5FE31E366F7F04C5B77C1D6BD3B25A765A84CF9AA08FD9ABA3BB6A4B5C3504064D0803687A04F06B2BB5F7BB95AABF6CB823ACC6E74E98FC468C3E07BCAE284797221A8C8A16168A91A03D066F0EC93F26C8BB6E948BECB9919A72E0FB86F380F1F2C1A2EFCEF871D6ACE4F5E0AD226A80117F7CEEFE566193D872A9ABADB9873D3E9ABB0119CF4133D06F0DA9F0ECB6319CEE796F2FF5B85B4A6754AD4C94346E325BAFF9CC922561CF02B827E2A487ECE6A4AD9ABBDE1D81C218CD5D50A66B8E3EB9870C9F68457BC813A2D827EA7C87951439DD394DA1ED071E8AAEE175BDBFC5CE2ACDE12F78C9B82D9653B970F035A130A1DFBE5B2D4C186C909B9ADF4FB821B2FA21EC03D8D8E095D68F4CC12CEDBE1DE7428A201B04A9575BE758D58340E73602C3467876A4B18218C34A3126DBCC877144E4A42A45005217D9C50F38DBAFAC6477011DA1A1FC749F26B6C747DDADF1F1E4707440A34C22046A6145D3033408212254FBEFAE6A4FCF5AA41BA14EF3C6CA23F3E04CA53A5C2AA03C717A04E928E5DD392ADFBA921528E54944B4183ACBED4D21DFFA3F33D35B9679068B3711AC438F7CAF3042436A9C0BB296ED1C7891B7B782EAABFCE080BDC54CB4EAE3E75536171BF1235397ED37A4394D05D31D7274A1640C1B42912CD9AEBB6B323C370130A854E5BB2253D6F3CA7AFA061C241646C28A8D1EA7AACA73A028920C2BA5DC9EC21F1645B92B35FE810E024CB764CE53F611E61DFC62CEDD8BCD445870D50EBD4DD8021924CC366FADE330AC3826DBF43A328254C367B15718967D72EB4F7EC3BFB692B5BEF357BEF0974739400113F766922F3171964E303D255FE2453BE85AA7B9B9B6408D1655D475BE7EF0351273BC084C9E71B794FAC5C256E87CFEDE5FD8E03EC272B24675B947BB5C1711D894285E026221A152D19DDE65ED293710D195D31968D18E9E2ACF3A0BF5C9F4760B1C20DDCB49FD9A24A3027025A5C090C708E97CD0F273E89DD43180ABEAC4665478732683325406CFBF20BF3059AE57756FAF185612EC199424EC64EC444BC190F0FAA6B2E9A2D96E7814E2FC3BF673B87B7CEC8D6F3A814B5774CF95490E258F0B10269E1ADD8C1D1C4BDD5346ABD921CE3E02A2D051A95E56DFE9A0C655D926FCA45D445170498F6D0870BC8D3F444982E55DE23D59A385E1F18732F7D7F6526289C6659D4363009EBCDF2066411E49E3A8E3D6B312DDCC49169BBF9B13C827A88ACFD5B3E61A9116916F41052A3AAF50ABDA2E7CAA9DB7EA816F44C0F315CB86700F62E25E05C90294FBD55342D62BAFA8BA55BEE7B532D50CD947065E704E62500D57230D15E762228DA98178A193D7D95284B20E82D74228146FDF68D59B37C5E7F78C0E14E7C40BD4F4D9CF0B189B69983DD39E29AA6439ECAB0A5B294D2A1216CE31CAC6D1B2358D2B0476C4D8002519B6D63639B2D4564E2458C8E06BDEEBE82262570777780F43B110A96547415A69A38EF0ECE0C2AF16B9CF11FF8326E2DE6DD0333B2EDE445AA3A1057824478BFC71FD00DEE601938734810D816F4DADD35F4C152B10CF13957945F8CC47FEF0CE3BDD1F0C5D8CD24B07E3F6D2A5D01717CFD06"); +// byte[] ct = Hex.decode("BC60F537CD5FE3038DACE613B8819A0DC920B8FE092474F763A1BD05F69137A1A084AA1A45A5BF1055F9340368D60CE415217C2C382E7EFFCD289D62A0A9E1E7FA2EFD07EF4B75B02DD436535AED897AECD520763AC7F8DFAFEBC122594388F210DF28DE472E748CFB640E8899B07CB4514401DEF9E9C542DC89733F20F9605F641DD1DD6F332DC051C2E5B2C391ACE70FD00FBC251EE1EA2AB27D165F966DA338F8AA970AAF66931F7CC68E2846EE5AD7EAF8E15B9CA333AD1260163E2BE2324C03094E249D3418164A655BD469E506F5B8420BF4FF6080DA230373B18D74AF03F11C9B545E3791CCC9B3B9927B2222983B7A6DE620BE8520B215ECDA45302695C0229C2A9607260BFD3C6EB9D7EAFAB5E47FD5760FA23067BAC1E6A980C4727B0C187A5B6397AC43D3BE24C42A1D2FCFE43512494A7BFC5CC19455DF6AA6F2698A2903831CA2E5F4F84442E6A74BC9D3CC3D6FBEE97D5CF4B6C58D3DC9ADB359FB56CF35FE21F96E885624498ACDF0BAF3A52B7F2564D1EA384DDA7FD32167786C5E010C3BCF5D2E7164BD6ECE815366887250D184F8061E57C3935214F191B38E982132EF4262E91808FF1CFD902B5248F6E7C031A98234DE0D578D1234B7453F2F575A88B622B0F11902C2146F45912E9BDAFA0846AF7B6789E621ABE3C65A4D990A96488B6307BE210887E82BBADFB026B60CA7DF3C9D429D8FEFCCC93A82E345F3B17756F6341F5DB3151974B1B9C7AC4AA33E80923475FE38FFC0AE7F47529360787AC283008971D87FB07369BAD111F1B99FAA59F2E1B5C088A5F31A47ED6A8E30FF6465A7DC79967EA78891C8EBD462D2566A4EA30EDFB8B7BEDD3C4E2ABFEEE7B366125A19B6372CEE2EB2F85514648AE920D292F444E6F90346DF87FD7C107848796219027BA581B3D87704FA8605108CA88ACF262C5C07D9BFB42635A1944634AF0633B471D0D2B2E4D6284894E0E48D58AE5D07E95130C9FBA77A0F124F9348E1A570BA0D009B7B46E03CEB201B17114B935AA91691A7F830346636FD34ECE2CC295D0124AD8CA76CC81E942C1607699F0DFFD3BDB509392FAF8212363F562554B05F756FF252765E6FCAFB04C6F2CF6A76F2E59E14F5BD4EA8E2ECF50B17E632F346D697FFB7AEB82ADDEF5B4DEC0DEE73D2D96B1A33C6AB4BCF7A160B79114A48F224FA037315ADF0485AB63DC2BF09F02606DAD80F13F0ED0241E6F53B21BBBE584794F77D0B783A7093F53AC916A848FF0F9FA3FB08A053C4"); +// byte[] ss = Hex.decode("2FFCE8C89E97BBA86A7ECD68088FB116A20601B88B8E88A3783CF2D2ED439769"); +// +// byte[] fixedRandomBytes = Hex.decode("7c9935a0912822144249e045d113b6e7cca2aa19b94d210a458e4c8dffc19aa7053095f130f12e7d79262cf801e5f36f63bf9ba079264c836bb02cd0a45a6dee06b7ccda4d18d429cfb5c7784eedcf12e28519d7da3ffcd65731b6d5b773204a55671a9d60940059720a74baa026a7777cd11dd3f81dbf836a06906d60aea820cdb70b606781805857448d6233a8e174b9c5e89cace15b40002c75a3b2c820a2846de5d6bf7c655a9b794d36e4eacbefaebadc20b9b7018c4fb60bb77f17d924db45bfbf74d2d052f8ec84b04cd70f6693f2eac613a0b55d9ad4d951d3808e66cd9d716ed9338a25aa41a9fdad9f7b46f10c6c8338bf52f8b4e2bf25e5e4071beb03e83b558e5db80a224da29951496268ae19980cea3c200e489eeeed9c16e2f0ac2d8daa9822958a84a0ba2fc08d4dba8fe84a3e60acab2183d1e795e74e58ee25a9e6d1fbcb30e564f9628bab26a674f9969d2625b7b7473c29bcc926486d1620bb9e9fcc107f1dded7c80189e7fa361fe8dd996b9c2d8f683847caa95d1542678bd200063bdb5757a4b6a72e8071b246df24fd5b30cf94eedef6ac59c892eebb3d4288fcf80182fc36db2946706dad5059ade4674341081ea63cd695aed3afcf51d66d01b5e61623d4fce329dc33835317f300dd58a9624153d0f8a25518c946046de3d55fb45a09396f4c8816c7f359a1999e32a4eba8d25920002f0bbf2e3b9850cd67f90fc11d1e3da7a9abf920d4007a952b77a9c9c1ac449abbdb1cd35ff17ef9182ed94b50e5b60c6400735362dfc37b59d23606e265aba4e88d617daff717c07b15d63c59e7e72aa19fe6f360ba4cae860c9045ad03dc845edaf2786583fb53bcdf05d21b336d25901204d7794cd3b7dddc30d28b5ac4563be1a6515d323d821ae873d0b6e5ff48dec06d8f9585ed64f0bcca2a353b64c7dcf0d6ae9084529a30db3a40163bf8acac48251c7f82b5ade896d66f15ed82850bb86689746b0144561a25634a8b2f5f62470990d4a67e105183d208ccfdb9ed024c52ffe5f0afd3219022e95d10289de8a31ce0666f8ab7ee89583ca70109d7bc4fde5922bbc35c31691d4874e0a3c9c2b9f3731029fb14c6533b650a31242a3b33002c01a2add52c76d828acfecb87193e28ea8fcc99f2cc2d51c7f512ace14f864749f20fa8c554db03c2d8fd1cb5a2274ec97a470e18783d2ba66165798d0b1c0652615e5b5cf9941474a66dda526c474c7c8d2189058db7f1cb6cc3687e5c6fe322aa8a615cefbf6abdf0a0c36cbb32a0a58183c460a692e2e89a21fa709aa3da00270c6e7368b1a0178459c96c2c539074a72f7d1867a6aa8d9f545cd270930bb05c99a8c394357b0377eb66f90529882093cb5cd5b8ad08f538966fab56c5a29883214009c76d69de18aabbbc4f5cb757e8b5422d5d7869e91e3850ddbec01bc40ed11b2134d40d109508d812e7b7be26278c585a1703e935737ae3bff4ebf9bfa383ebba7e2f7d0fb9f4b78479a70c6a6d1c0394919fd1cda8600fd284418d6f4d3cae2b213f4078df0de5a860a23738fd7f85450f3d7f9903b306f863c7808296419c06a4a12a6149a0b699719aa762ba72f0a052e971b58ac97185ec95a5b8784b60355f163c4dbea0b1fea3e8e5f23eef6abbfc155846052f396d5d97731678e48ad0668391935a6594fabd5b33440b647f343601e909a3926719bae73df1cd6af5904bce016a4934b27b01b45288ab1c13a3d72531ad31adc304e7d38291b35e2f8c3cfc153127d5465a8b953a3af7f7e5cdc22174919e50d7c195cf5a7463facc8f17baf75118259bbf5316369bd70c7211a240def65fa94dfb58f3984985b9815e32c3591c93cc9fc47e75ebac8aa0044681e34791a1b847068386520e36bdba90735c870a3cc9fc8b7be1c084d4200c5f02b7476cc7c406e1b8335c4b3e05a98f6567a942a0dddf9d0c4e26a700454b34a6f174c776978dbb7c18c40070ab899752040fa824ccf63d31f15f7f86c44905e4898f0ed731becc9d20b9b35b92a57de9f5e42c38842ae6c7d94c8b246825f8d722db09b138db117d112968ebd1ff4bb835bff94cfed81fe6f22915d2e0ce4bd1cd743788ac146fe4aa7e2ed023f88e8f96715c97548bbaf0549f1e38fc16ca351206745e7ebb59649e9e534c1633289f8cb0071bbdee509cb131bcc7f26d3b548c17fd413a3a3101583b18f3335e0380098a3cfba480f7e0ff0b606c03338790d6d2e5b2307edfc311721f1587ca55501f4b4b5aeab9773ef78f27c40e8a42bcb57c887f99a6d56be4647f12a52367936bf3b63bea50319990cb58436a5dfb819c09c27299e778a68347f40ef386c6ae97e25f9fdfb7da6b8c6efd04ec9eb83e6cf431b2661a29f4203b286d4dfd860aed5eb5456b8e4a5b9cba46fdfa83aea1e043b3182784c8cef3feeee0343be2ff4d5cfae8c202049a53a20b35fdc1c82e7b246ad7cc7e0a2b05368d873d948284a206d12ff366456ecb1123a121c8d2eaa53a423aa6b4e4c36257b7a18d1ebdb28c0f5a76a3938cbff7b0e1b43dc5237a3fa7b6266bcfba4ee44d7ca17a84e0a97d8f4baf6b9843af217d5275e07336413a3a0790856b8a25c67f6d2822dd85120dc18d70d6ffa1501b3880d036876322c1769f08bb767e9c6a7948e9e8d87ba0fad66ed655973ce1bccb8dedd9c7f2c80250769e247ce679126cb3f2fe64ae05110691ea91626d8ea26f4cf674626e62850e4523ebbfef5a926c90d9d33fa67f6bc50d35737801604e5f5b119e08c306ba7b0c09f79f871e10b2261cd8f489ccc14bc17ace710a407e0ae21732192ab6febcf4d58c53ca415f0d53e4746267874ee026106209cf1ca11099ef5e59122f4cf17d50131d0197d3b7a1fbde22d3d40635b106b27315e033e2d8e8a0cd45ba504848b470cfb1fc78d47f65226cf0968aa51fd62568b9108adffcc25193d747e735dd5e06766ee213f5ae9032ddb28cfcef714ade717c9d18b7d63e4fc057ef88fcc0894a23d36f2aa16dd530086239279cdbe14764656bc51f78f4d448c38320e32e110bbe4e90bbcf11d924563469001ea8561f5710352f44619ca1c2f108d021f520008b542071ca87c936bbd87cf42c3a06e10976cd82e074974601ad86662b283ef5d2fd63486a98acc91758160a5e008333ad3b365be36836a196643b4136fbec90ef50bb944cb17ee0b55adc5a60dd81809e74d3f4ab5751a4c1b94fe7082f86c6935b867d15bc27328c3a7d9e5215fc8a2fc7f3d088446353ec9c92d3b5d01fa372540d1de064ea02030a300eaf73eb4eb40e5b2ec2b0c6d3d52f63369bdcc63d268a065e18aeee15474393c08eebfcb9d2a795e5422fd50fd099f85759966ba28127bf5b1eae0851b5c567c23ac33469791cbf78e827f98c4269b997008ac745188aa2a77cddd83574858a7a321f46cb0db5b89b100318c818500dd4d5a8aaf16c38bf32831099cac8b121e191ea8c50573f395bc70753839643e602b3b2242eaba726ec243a643392df202c6fde7e8436609969436aa1707fee35a08e0aafdfcd6471db08b9814e4547689f04e5f8b918fc0a8fd82784865ef5cbcc53da7e2fb1adc45e5a429833003b159edd94f3e1400b784181c81a270517c22fcaa0fd7286adafe160b3b17495ca6186e7e15c878be4c228cb5f79a4d940dbdfaf94392aec9aaa252c9eb0b58dded996e081fc1bad2a7a229f715b4690d8871ae7b086961f7b7d44e1f9a2bd093042919d0543007e29e222c057540f0ead016575771f85811d93583af887ca5f8094c9274b4b933f528788661c9eac7d6f736024051df17028b8d06f4ca6d33dcef7fcb6cb4a063b764706fd0d457c6119b6ce77fe47d40881bbc41d5fc042717fe4b599132af01cdb6032fcec422410c071f3d83eae54264ac430927e85a468308f96dfa26ede5fa047df6d63fadfd3861bd3507ae199274d6e0b3e329a10a58cef6535747ee4a6c5ca9ec10a39f2acff29a33b82d09b899d6c4c1271ac8e6721c0c77dbb6af1b4b4cb7fca8dfb716a76f6f587950d2ae419c4bfcdfbfe4fc08605627964b126c39ded0e22260c7450b7ae8e9397a27ad0f614577524224eed1976a085dbc1889d2495ce1b94a32153d9e433b27beecbd7e87a411248aeadb5c6d155148336bb55f23bfec0efc2d32463b46c2293206137ded47fe3c1cc7f64e135222308209640dadff7c9da43f9939894b7a67c298d7a790a5ec56391076f8c9518d85aa1d5df44cf3043c15ceaf489e6b7eeaad05907373c4fd7a16a4982299b66791d3436ddbdf438bfd98e2d94f0d41835c604b992d69249d798fc66ff358905dc801c79d60ae1a498898a7faded0502cbb751bb56ec28ce4069b4531c7c20c7dcdba2b0f21691bc776d7eb4295124f8411832f8941229c43b0881aee44425f6eb418143ed19d1fe79fe55cb5744259a4bc13c3512227c06a8c42563c9951516327ea8e90b9f4313e146e8b452814a93fac4564ea1bcd51360c8d19bbc07331ee161bff595e330397dfa532b2b2d25a428a999bf9b357335196ad4a7d7d2db12ca056549223039379aaaf5f89d281e04e986f5dba96ecaee589032db3d66118e4ce169a6a3034394baec899bc5eab4385973728be47fbdaba1d6cf6db50d77d394306727244eca23f2b68af3e38d275799bc81c840fd425e06d516cc33ca100c0d704ba1606ef4199d1b47d9a756a171309746ba0cdf48e9a0ee457cfe19a99d4112405d3318968ca97e13f72f271df0a5b487b3c5869fdddc6d53c1e7190ebcccad22f5d52bb99780a1887ac2fa0b933a0ca708ab7f20e1bb46ec6238351ecfee46cb42bb574270b46f4a3626ba8af5b5b3c96ccb7f1acd772b13277412fdd4ea740f8c6ea0d2383377115f8d17c095b8325ffc82ce966150413de37d622bc426c3f8ceb1cde12069e3c41e90d248ac627be702482c4efb2f028e2b2a607e2bbff190ddb710d7e36a7811621baab0f134434c254cbef59e86af197b6289e72d24714ca1ea3784bacb250676a778bf9d6ce2549799af999b917c8df2db58ec799ad51f10d0bd3707aa5f3c3aca8b8a105914825e6b78709eed6190de883b34bfe6f4bd0c91001a5a5d168a5212c95ec4ba15c700c937fd359e401899e56e3db259da628943951e8b2a366c94ec46b9f6b5d4da72943ba738d662d2cdb4fef6091ead96cc74d272c4c89077765ab6e93cafc737c82ab30b13b40d14c595d7a5efe4e89cccfb81275776c2b8df49db7c37f8a149a1a53703a255095021c125679d6929d8b46de63254204b79f43bef2f2bd7f0e2143de50616e19346239acb7db9a980baf1f212d2c26c69fae7d759c46da0aa97f443031d06f8b6a85794ec9fc778d30f08a4292a5e13488767741ff120121e0037c3830d32b6181008b47a8d48126af48719a7e7396ca1d6e787fba426a54410364baf076426f4c72dbddf964e5dc617bebfe8d381320150ec065cdd87288245115a18ded71c70b06cc02bdae6d695cbbb5b3d8a2aa16cdf80d84d511ac1b754f472f66ea6c5e312b4c67a66067e1f9d32de4d1d14c4c4e2cab3f40c2895c18a56b94fa40b75641723e7c147a594c89511956f046f0fbd26f3d3814c13ab717c7e164bdc9f8c0e5ca120724989897db7def83513e8325176d04a774021ba934b174af4b063e8764a8cf7c81822f8eb2c5870ad4b876051fe5c18c352cc03b885f74c65d22a5f9eb0fa399782ad33639c0ade4a2c1ff3ceab622373b98410f25c3de2d570f847fcb8492ba5b06661287a4e09af59374ccd9d080fcbce8ece50bc61c96d3b5ecfada0a974f04329d6f245083c3e7d49e7c59e2cc437de2add8bde7518f0b8961c7565705cafa86ff93a9f3fe8d22a7f76446e4e26a7534f8714081433b4f5c95d68a1cd7bf0e5cd74adfadc851287f9ac437cf0c67d3c5e7bfd49fb44f4277b860d657035303cb2d872fe8530e406d3607e3e33b45f47a8a42a229362cb0208cd5de79a7c0069b7fa8263c606b2f80b66d7562d975b9f096fe599cd28ba85521cd123f665d6c101665af1d4f6c850e28b3ee8b8f74d2c63e7331a55edea8024059810071122e0f8ec7c3776a148a28a987e2db7eef4f493c4e69e20f2ce2caeb305a23bede1aff4bcd706f87be91340d48eee4f8ea2fa7f496e882ee68c9f60daac3ef08c95452d936a8762d15a47659e4a791b03ab52cd0407cbe3677b4cb3b9c2d3f19b8f21250b28abfe1eb6c4e4bc92014fc4f10b165a594c30131f571aceb009e5574219584e2fd3f3281bd6156697e8347bffb50c3b699807bff24fabf9a7ced1d796078dce628d3ae6445b81c8fb6a633b9f25dd4d25a5a6d64b8af3c71c5b392822aa9e5748f3ce90b0c44f7857ec8dbe90d15c9b31152430b245139da98c63cf1efb6d89c674b15e51d30a282f779a6dc4b23a5e546fcf8cb0bdabaf6640651b98b6e8c7afc5c084938ef0d099f87466cd1648cb9aff11054c70ebd8921e459d6245b89ea05cc218d48c331e3138a7613a1500dbdc8b5077e9063b39a4a6aa8971e910228f026d3437b1344dc8f746bcc34a94605fa855200afc964565df617bd3c04d4998c162623cc4975fdea827256f8f61da092fef0e4a3023a03c6aa606579111dc80c118a470b9a690409b125cee61d64472d40eec1c222cffe7c3a59f8a00fe2fe51b072644af0be728bbf948f2848d1371b34d09f0fcf3fcc31d084ad69d7edc2e1aff6651f7f0123e1a83c44891567a34357b114e060e82464d18cb73a2e7e2b5f604c09938eb06df26a0141a55e7fc84f219c7728b022ecba2f1c71266a5e6aa7bd784a8c6e0db32b53cc03aa500fff71b06855acf22b8335531655fa414693b3fe9a320a98781ca9f60b955b3817f54873915ad3fcc843b172a4cbc5d3091dc4b301b4417a391b66895ee37ab81a6fe186fcf6ee7f61fe3b89556edda3130153e2562aa190be6994ef738fab5c2dda559e63f4b5b1f08faecf5e3cd9afc5d6336c45273ad5f93dd26d0894e2dc587f7fc1b26ea6b2428e55f07d9e175fdf9d9e0b58df7e169079cf203f21e5aafcd3a7710a0259d87be594ba30bcb2a6a2e26b28f499c3145889198e5aef16fafdbd1c440c300d83100d11d0a0647f0066608e847b6b109e9853b2549ffae9498ab5042823f0fe0ab248ca6ef9de115ecec752dcd1bf2e4e55e79cc0d17866c97ddff73f7e35eb598e60ecc8ac4cab0db57c948aca8750b1543bc926d2cd7a6239a683cba85400d0bcad56e943a4f614bea94990bc426e1eae75046b6baed05a59bf0084eb777d824d0d212e9819e2ea7db881c44fbb85bc374a0d6235f8392a3d9a761a5747d75d96cdc3c8dd7272eade200d57230d15e762228da98178a193d7d95284b20e82d74228146fdf68d59b37c5e7f78c0e14e7c40bd4f4d9cf0b189b69983dd39e29aa6439ecab0a5b294d2a1216ce31cac6d1b2358d2b0476c4d8002519b6d63639b2d4564e2458c8e06bdeebe82262570777780f43b110a96547415a69a38ef0ece0c2af16b9cf11ff8326e2de6dd0333b2ede445aa3a1057824478bfc71fd00dee601938734810d816f4dadd35f4c130598b9678682552d0d9bbf0116e52f71e30f449c6e70b673af7186d562e4591cfb9fcc9c591cfa471b8e3ea987e8e6b5f57d6ea8dd522e74d63169f343b20f9816236320cb16a04fc7b629e6240bc1686651f69bf37db30dde39875d57beccdc24c9d5575b0bb0b86f6d2e06f857152874f3a9034cb6018c5f83c55665f22a4195cb93fde9d0294d0769969423c54cdea07300e6f2bcda80f8e35f2631ceddbe3d29cfbb81a94d60b576e5c471ae1dacac226e9178369177bae4f33fec7b710b587ce317d3781e5fa8bae55167b7b93cdd061782786fe574fb7296b7c338edcd16642149ef44e694f8d30eb602193457a9956acb38b8ffdbf22b7bd93bda15b79cf2ed4c8e4606052696fbf38a852bef0ef9e8cecc8faa42493ff945a0b6cf235f7a64b03e4cf567ffe3687b6208c42c7df3272008f9c57ef92801444faf4932120223aa8882a57ed3cd8fdce71fe4ac4ea41dec00b74c0310d25260e0f95a4b89b5cd96ae446b33bc433181db39d0b4e48de172186f9c50ef7ac72adaebb2202b358a1250070349c66516d7f5d895ecf2dec601759abe52e2c7fec904db0b8a4390a4f8367db536a6a1eedc4435a6de58b62b3d4a946061b77adc10d21535a026657ec07ce19d9e097f93da31ef963ec7cfb971edaa8acea7537f5280b51188d88de355a79408f5c1fac07234ef9629ee992abfc874b33572362b95722ff1714cc238c68be7850c3bfa7bb5bf2c41122192cea2783f79cb558a65198c93a6009fd3102ed3d7cf677c5c632ec1a31abc087e2ab717c9abd04caf709a3855ddbfb70a81099f22ec5f49f3122e6633882f813bb76e2597670e37f36240e00a75b4b90a132cf2b4a652269ab8be1697087fa262593a16639f496edb72b0c906eee57a219c51dd548a697295bfac80d400d834c486a7642aab0d12aa4617abf1f604b5d6c9cf40c57fc8454761ba7fe54cebd8ec43daa495a6feba2e7524b6b771348100b3af4eb145642d006c3acf26262f8de8a6465f4eef60bea55615c19c50790daa8a0a39d42d66f89e4e6e3a5029cda85b50bb256ce3c57ee6aed2ae47db1d10b05bea586992a0b3a282d36d7c8d254badfa4a8b7f91d0fef5bc971b99b7c2d0aaf904a42b11139cc22d6450b6467c9453f1392193fd16b9aa565c757fa9457a9723fbfc6ce3b2f8381f0393b4eb984068adb273a50ccbe4e8fb708902179e0b8d645481a7f3919e07f758cfd12a3496bdd5b063d99ef127cb36dffefc4a29c23e63da9f4ab05a20faf7d73d70c619d48a92c653d415b7a9aca0c499937fd2acc6b1e6842d5f15c00bfa3b1d1c1655f8601c13f94291bcf76979b2c45d30384e4ce99a60ec088c9328a393581a8bf247609e5f9f025d98df1ed6c25ed4d6dfc67c98ec93b9158e7ccb8e8a50f4548479444ca7386ae077140d8a26459123dc28c9bcd531e3287f74cea298cd4f475c45e51792e439ba4368171a5ff60656c1ec132ce5affd6814f5f0fd786b15479a8bd2d2d3874bae96ab58e3b603bb251746b67bd00bb210f3d00e3725ad2a9441a11c8d320aa18e83383815f1eae1a7f195034f9dfe7ff7c4fd84acb7c2e22ec131d928e425cf96b64b562de90593cd61f237c11e2a4fc33a7f5333e1c6085a8f0d393e346646f36b3c4767c3681ce53c75414d72c57121fb10ac3f0eb8b784794cf2dcafcf0fe0c7b003d6171c20a3d63b44d168ef4bb79da894b5555c6f69a4d6e82fa558526e1bb75c63dc8e0fcbe3b9d462c0933eec9f034d4e917f30d48e98a93755c7c8771648711b81e5cb6f4e30680b7ce662cee5c8a02df4d1cc8f6aef8e632eaa09474321f231b7ed4cc9ba2a993693f4169b7752402bea7309d0412c9269799914894ebfaa9785716406225a18101a6f393dad47dc052c45bcad6f8bad49f108d6d179588d1c08db51ec9a50ce2702c9ecc1f9ad68633060579801e2d131d1044effa20ac6fe815f15d64e900c7d72d57ce8a398ac34119490d71b1058ffc111e089617145d592119352203f341c0ba91941455c29d5c253bd219bfed0d556212098a969a38b6d561be89635273ae7e4531210dd7b0d0310f2806a6e7a46c9f908c19862f9e05206d8408b246f4b8a508b9e78824cb9da63e4b6fcc2bdc9c391f2d4b9e3008dba425a937e025130b7cdd946dafe43e3a18f7331c04e063df4ee19cdd09e2c652acf3f4ced146b3b38f0fb8f8dae0f9fb1f87881cb1e7cbe6c33da4b704f03921810fbf3368a11c3014d2a4bfca1396ed43b3c3a3c6de41ee3740d40eb28983b2967f74a5a2a0515f68f70f4746dc94f29607f14b671c088df491386a38cc6f9765cc9b2ac7e91d80a2506624a9b0864aea397eddf2a9647d6f42cbdc68f4e8667f3d5614faf151b94acde040329ebcacd4d6ad474306c990998423ad8fb307e4a47e4e73463d913c812e3316a77bf238b89f69178dc0924253c110ca5396095d7c1689526e1cbf8dadb924f19df73aa7c97b59e013d6c4ddc687e06e10f82c7aeb21011e931222a777ab3a87759cb893b380ce15a22491ef3dacf62512e3d0561a137aa294d981601813767e44decfff7e84b4c33d6d73022f20faea96ce49976f75c85b390bfdd508a8c2a1f77681add20cfb715fffef359dda3e824d607ae19f298d7323210b7bd3fa6db1bdbdf613d13b6b7ef349278eabd1ec4ae836ad0307e3f5956e753b39c5edb973a6f90012962e3bb75f673461c211e711109320152825f5c9fe4b516f85eb0ba33e8719843f1ca4c965bacdf870dcd53dc05ea444696c615be7cb9214235f008b4c458fd0cff1b313e3433eed9ac1495785a57c4da01fded6650a61d29cecd2462a84faea9b689d050021f4b7d883edb39ad74a5eeec5a898f73f40fff5b74948fbf96ad6afd14d48a2f4b15782d163f219b069f2da414905b5b97576f4486fea35e93d2aaa4b41afeff1db600782acd9658479c960603aaaccf3fdb10bbe916936ca4526e2a3751ecef7abe2500bf18512d52006bc80c2fe5481727125e0a27d4342f3046e626b753b40eb210dbd64c8f67059fbe0c93146d09f30550cd33f3d03986f842a9421f07fc94f09ca898526e4cd51ba9b268beffeaa5f381c59964b5ca8b04918433b9229080b54be25920c8c3ddfa2b98d5c095a6800c1d3d03c8b30e989198fc96c3c8dae0d8d2ca09365d23c9e46abb40591d30817eb8e33985dedd0387b3ddc66fb655d37e41efbad4c05af86ce280afa66e591a619bf9236e5b7b7b31bdc87f63257aa652630afbe9ad8363750c04042c43ad5f392076f7481b3ca6b3dd83d7e87c604f8b08b0f13234fe8d8e5ab60756ae91d0d69eb144a3db813dd6095bcbee564b04a713152e40cf86285c1d51088832d18184b90f8db1d7e7d55bc79a2178b833523e0af31c027172271477162fc13d848d082b37bd1fc5700383cbb36ccc550ee3ec492266f9a86075bb32171abab9a335317d47a85de18d44809c6fbdbe76d2e5a5aec7cf00250eb24f453038b89e6cddb09e646676419c252e14f0d661f85747cc17f67732ca487012c3bb8ca822a9518695e68620af1ee12d2c6e48e0775128992922364c7bef20448e44025d399918109fc3ecc93f1c57c04be4409df78823aa4f098e3883282d7f9cbdac7aaa49dc8795c67578c862a0e45097499bbdf0b0e37"); +// FixedSecureRandom fixedRandom = new FixedSecureRandom(fixedRandomBytes); +// +// // Receiver side +// KeyPairGenerator g = KeyPairGenerator.getInstance("NTRU"); +// g.initialize(NTRUParameterSpec.sntrup653, fixedRandom); +// KeyPair kp = g.generateKeyPair(); +// NTRUKey pkR = (NTRUKey)kp.getPublic(); +// +// // Sender side +// KEM kemS = KEM.getInstance("NTRU"); +// KTSParameterSpec ktsSpec = null; +// KEM.Encapsulator e = kemS.newEncapsulator((PublicKey)pkR, ktsSpec, fixedRandom); +// KEM.Encapsulated enc = e.encapsulate(); +// SecretKey secS = enc.key(); +// byte[] em = enc.encapsulation(); +// byte[] params = enc.params(); +// +// assertTrue(Arrays.areEqual(em, ct)); +// assertTrue(Arrays.areEqual(enc.key().getEncoded(), ss)); +// +// // Receiver side +// KEM kemR = KEM.getInstance("NTRU"); +// KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsSpec); +// SecretKey secR = d.decapsulate(em); +// +// // secS and secR will be identical +// assertEquals(secS.getAlgorithm(), secR.getAlgorithm()); +// assertTrue(Arrays.areEqual(secS.getEncoded(), secR.getEncoded())); +// +// } + public void testKEM() + throws Exception + { + // Receiver side + KeyPairGenerator g = KeyPairGenerator.getInstance("NTRU", "BCPQC"); + + g.initialize(NTRUParameterSpec.ntruhrss701, new SecureRandom()); + + KeyPair kp = g.generateKeyPair(); + PublicKey pkR = kp.getPublic(); + + // Sender side + KEM kemS = KEM.getInstance("NTRU"); + KTSParameterSpec ktsSpec = null; + KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsSpec, null); + KEM.Encapsulated enc = e.encapsulate(); + SecretKey secS = enc.key(); + byte[] em = enc.encapsulation(); + byte[] params = enc.params(); + + // Receiver side + KEM kemR = KEM.getInstance("NTRU"); +// AlgorithmParameters algParams = AlgorithmParameters.getInstance("NTRU"); +// algParams.init(params); +// NTRUParameterSpec specR = algParams.getParameterSpec(NTRUParameterSpec.class); + KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsSpec); + SecretKey secR = d.decapsulate(em); + + // secS and secR will be identical + assertEquals(secS.getAlgorithm(), secR.getAlgorithm()); + assertTrue(Arrays.areEqual(secS.getEncoded(), secR.getEncoded())); + } + + public void testBasicKEMAES() + throws Exception + { + if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BC"); + kpg.initialize(NTRUParameterSpec.ntruhps2048509, new SecureRandom()); + + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("AES")); + performKEM(kpg.generateKeyPair(),0, 16, "AES", new KEMParameterSpec("AES")); + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("AES-KWP")); + + try + { + performKEM(kpg.generateKeyPair(),0, 16, "AES-KWP", new KEMParameterSpec("AES")); + fail(); + } + catch (Exception ex) + { + } + + kpg.initialize(NTRUParameterSpec.ntruhps4096821, new SecureRandom()); + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("AES")); + + + + } + + public void testBasicKEMCamellia() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BCPQC"); + kpg.initialize(NTRUParameterSpec.ntruhps2048509, new SecureRandom()); + + performKEM(kpg.generateKeyPair(), new KTSParameterSpec.Builder("Camellia", 256).build()); + performKEM(kpg.generateKeyPair(), new KTSParameterSpec.Builder("Camellia-KWP", 256).build()); + } + + public void testBasicKEMSEED() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BCPQC"); + kpg.initialize(NTRUParameterSpec.ntruhps2048509, new SecureRandom()); + + performKEM(kpg.generateKeyPair(), new KTSParameterSpec.Builder("SEED", 128).build()); + } + + public void testBasicKEMARIA() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BCPQC"); + kpg.initialize(NTRUParameterSpec.ntruhps2048677, new SecureRandom()); + + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("ARIA")); + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("ARIA-KWP")); + } + + private void performKEM(KeyPair kp, int from, int to, String algorithm, KTSParameterSpec ktsParameterSpec) + throws Exception + { + PublicKey pkR = kp.getPublic(); + + // Sender side + KEM kemS = KEM.getInstance("NTRU"); + KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); + KEM.Encapsulated enc = e.encapsulate(from, to, algorithm); + SecretKey secS = enc.key(); + byte[] em = enc.encapsulation(); + + // Receiver side + KEM kemR = KEM.getInstance("NTRU"); + KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsParameterSpec); + SecretKey secR = d.decapsulate(em, from, to, algorithm); + + // secS and secR will be identical + assertEquals(secS.getAlgorithm(), secR.getAlgorithm()); + assertTrue(Arrays.areEqual(secS.getEncoded(), secR.getEncoded())); + } + + private void performKEM(KeyPair kp, KTSParameterSpec ktsParameterSpec) + throws Exception + { + PublicKey pkR = kp.getPublic(); + + // Sender side + KEM kemS = KEM.getInstance("NTRU"); + KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); + KEM.Encapsulated enc = e.encapsulate(); + SecretKey secS = enc.key(); + byte[] em = enc.encapsulation(); + + // Receiver side + KEM kemR = KEM.getInstance("NTRU"); +// KTSParameterSpec RktsParameterSpec = new KTSParameterSpec.Builder( +// ktsParameterSpec.getKeyAlgorithmName(), +// enc.key().getEncoded().length +// ).withParameterSpec(ktsParameterSpec).build(); + KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsParameterSpec); + SecretKey secR = d.decapsulate(em); + + // secS and secR will be identical + assertEquals(secS.getAlgorithm(), secR.getAlgorithm()); + assertTrue(Arrays.areEqual(secS.getEncoded(), secR.getEncoded())); + } +} diff --git a/prov/src/test/jdk21/org/bouncycastle/jcacje/provider/test/SNTRUPrimeKEMTest.java b/prov/src/test/jdk21/org/bouncycastle/jcacje/provider/test/SNTRUPrimeKEMTest.java new file mode 100644 index 0000000000..e20c3838dd --- /dev/null +++ b/prov/src/test/jdk21/org/bouncycastle/jcacje/provider/test/SNTRUPrimeKEMTest.java @@ -0,0 +1,217 @@ +package org.bouncycastle.jcacje.provider.test; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Security; + +import javax.crypto.KEM; +import javax.crypto.SecretKey; + +import junit.framework.TestCase; +import org.bouncycastle.jcajce.spec.KEMParameterSpec; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; +import org.bouncycastle.pqc.jcajce.spec.SNTRUPrimeParameterSpec; +import org.bouncycastle.pqc.jcajce.interfaces.SNTRUPrimeKey; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.FixedSecureRandom; + + +public class SNTRUPrimeKEMTest + extends TestCase +{ + public void setUp() + { + if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + } + + // Test for no KDF + public void testKEMVec() + throws Exception + { + Security.addProvider(new BouncyCastlePQCProvider()); + + // count 0 +// byte[] seed = Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"); +// byte[] pk = Hex.decode("01031FE0C4328B956E9AFA7B5D86DE2CBF1F0728A1236F685DD2FD221ACDD05CAB64B01AF7A5F3C2837A5B7FE5FE31E366F7F04C5B77C1D6BD3B25A765A84CF9AA08FD9ABA3BB6A4B5C3504064D0803687A04F06B2BB5F7BB95AABF6CB823ACC6E74E98FC468C3E07BCAE284797221A8C8A16168A91A03D066F0EC93F26C8BB6E948BECB9919A72E0FB86F380F1F2C1A2EFCEF871D6ACE4F5E0AD226A80117F7CEEFE566193D872A9ABADB9873D3E9ABB0119CF4133D06F0DA9F0ECB6319CEE796F2FF5B85B4A6754AD4C94346E325BAFF9CC922561CF02B827E2A487ECE6A4AD9ABBDE1D81C218CD5D50A66B8E3EB9870C9F68457BC813A2D827EA7C87951439DD394DA1ED071E8AAEE175BDBFC5CE2ACDE12F78C9B82D9653B970F035A130A1DFBE5B2D4C186C909B9ADF4FB821B2FA21EC03D8D8E095D68F4CC12CEDBE1DE7428A201B04A9575BE758D58340E73602C3467876A4B18218C34A3126DBCC877144E4A42A45005217D9C50F38DBAFAC6477011DA1A1FC749F26B6C747DDADF1F1E4707440A34C22046A6145D3033408212254FBEFAE6A4FCF5AA41BA14EF3C6CA23F3E04CA53A5C2AA03C717A04E928E5DD392ADFBA921528E54944B4183ACBED4D21DFFA3F33D35B9679068B3711AC438F7CAF3042436A9C0BB296ED1C7891B7B782EAABFCE080BDC54CB4EAE3E75536171BF1235397ED37A4394D05D31D7274A1640C1B42912CD9AEBB6B323C370130A854E5BB2253D6F3CA7AFA061C241646C28A8D1EA7AACA73A028920C2BA5DC9EC21F1645B92B35FE810E024CB764CE53F611E61DFC62CEDD8BCD445870D50EBD4DD8021924CC366FADE330AC3826DBF43A328254C367B15718967D72EB4F7EC3BFB692B5BEF357BEF0974739400113F766922F3171964E303D255FE2453BE85AA7B9B9B6408D1655D475BE7EF0351273BC084C9E71B794FAC5C256E87CFEDE5FD8E03EC272B24675B947BB5C1711D894285E026221A152D19DDE65ED293710D195D31968D18E9E2ACF3A0BF5C9F4760B1C20DDCB49FD9A24A3027025A5C090C708E97CD0F273E89DD43180ABEAC4665478732683325406CFBF20BF3059AE57756FAF185612EC199424EC64EC444BC190F0FAA6B2E9A2D96E7814E2FC3BF673B87B7CEC8D6F3A814B5774CF95490E258F0B10269E1ADD8C1D1C4BDD5346ABD921CE3E02A2D051A95E56DFE9A0C655D926FCA45D445170498F6D0870BC8D3F444982E55DE23D59A385E1F18732F7D7F6526289C6659D4363009EBCDF2066411E49E3A8E3D6B312DDCC49169BBF9B13C827A88ACFD5B3E61A9116916F41052A3AAF50ABDA2E7CAA9DB7EA816F44C0F315CB86700F62E25E05C90294FBD55342D62BAFA8BA55BEE7B532D50CD947065E704E625"); +// byte[] sk = Hex.decode("5515559645A956544158655545514489451621815999295514A25949655418096985596A011900615556598565956A6866A916555455214551995455460640548011661525945242549500A515565165659455A52545A6A5445050A2054599A4659591541906682494418654A68A969155864655419119405555105595842994525415591649A569515155058551859A565A8854655454848415444169519555149656009A284AA0664A42991A8809015AA6555A54AA551010460084421102809A028A940502189698410446514812188888644650A081288196648158A61261A94A50908918A5810846011A9925260685A244404A0A585A0289066611A85A5A12408668A6A6591565185058559A18658821104418281602A994A6505012A82A662412A40255690122299A0954295A946110669299104014952500529294624041461249AA142A0201031FE0C4328B956E9AFA7B5D86DE2CBF1F0728A1236F685DD2FD221ACDD05CAB64B01AF7A5F3C2837A5B7FE5FE31E366F7F04C5B77C1D6BD3B25A765A84CF9AA08FD9ABA3BB6A4B5C3504064D0803687A04F06B2BB5F7BB95AABF6CB823ACC6E74E98FC468C3E07BCAE284797221A8C8A16168A91A03D066F0EC93F26C8BB6E948BECB9919A72E0FB86F380F1F2C1A2EFCEF871D6ACE4F5E0AD226A80117F7CEEFE566193D872A9ABADB9873D3E9ABB0119CF4133D06F0DA9F0ECB6319CEE796F2FF5B85B4A6754AD4C94346E325BAFF9CC922561CF02B827E2A487ECE6A4AD9ABBDE1D81C218CD5D50A66B8E3EB9870C9F68457BC813A2D827EA7C87951439DD394DA1ED071E8AAEE175BDBFC5CE2ACDE12F78C9B82D9653B970F035A130A1DFBE5B2D4C186C909B9ADF4FB821B2FA21EC03D8D8E095D68F4CC12CEDBE1DE7428A201B04A9575BE758D58340E73602C3467876A4B18218C34A3126DBCC877144E4A42A45005217D9C50F38DBAFAC6477011DA1A1FC749F26B6C747DDADF1F1E4707440A34C22046A6145D3033408212254FBEFAE6A4FCF5AA41BA14EF3C6CA23F3E04CA53A5C2AA03C717A04E928E5DD392ADFBA921528E54944B4183ACBED4D21DFFA3F33D35B9679068B3711AC438F7CAF3042436A9C0BB296ED1C7891B7B782EAABFCE080BDC54CB4EAE3E75536171BF1235397ED37A4394D05D31D7274A1640C1B42912CD9AEBB6B323C370130A854E5BB2253D6F3CA7AFA061C241646C28A8D1EA7AACA73A028920C2BA5DC9EC21F1645B92B35FE810E024CB764CE53F611E61DFC62CEDD8BCD445870D50EBD4DD8021924CC366FADE330AC3826DBF43A328254C367B15718967D72EB4F7EC3BFB692B5BEF357BEF0974739400113F766922F3171964E303D255FE2453BE85AA7B9B9B6408D1655D475BE7EF0351273BC084C9E71B794FAC5C256E87CFEDE5FD8E03EC272B24675B947BB5C1711D894285E026221A152D19DDE65ED293710D195D31968D18E9E2ACF3A0BF5C9F4760B1C20DDCB49FD9A24A3027025A5C090C708E97CD0F273E89DD43180ABEAC4665478732683325406CFBF20BF3059AE57756FAF185612EC199424EC64EC444BC190F0FAA6B2E9A2D96E7814E2FC3BF673B87B7CEC8D6F3A814B5774CF95490E258F0B10269E1ADD8C1D1C4BDD5346ABD921CE3E02A2D051A95E56DFE9A0C655D926FCA45D445170498F6D0870BC8D3F444982E55DE23D59A385E1F18732F7D7F6526289C6659D4363009EBCDF2066411E49E3A8E3D6B312DDCC49169BBF9B13C827A88ACFD5B3E61A9116916F41052A3AAF50ABDA2E7CAA9DB7EA816F44C0F315CB86700F62E25E05C90294FBD55342D62BAFA8BA55BEE7B532D50CD947065E704E62500D57230D15E762228DA98178A193D7D95284B20E82D74228146FDF68D59B37C5E7F78C0E14E7C40BD4F4D9CF0B189B69983DD39E29AA6439ECAB0A5B294D2A1216CE31CAC6D1B2358D2B0476C4D8002519B6D63639B2D4564E2458C8E06BDEEBE82262570777780F43B110A96547415A69A38EF0ECE0C2AF16B9CF11FF8326E2DE6DD0333B2EDE445AA3A1057824478BFC71FD00DEE601938734810D816F4DADD35F4C152B10CF13957945F8CC47FEF0CE3BDD1F0C5D8CD24B07E3F6D2A5D01717CFD06"); + byte[] ct = Hex.decode("BC60F537CD5FE3038DACE613B8819A0DC920B8FE092474F763A1BD05F69137A1A084AA1A45A5BF1055F9340368D60CE415217C2C382E7EFFCD289D62A0A9E1E7FA2EFD07EF4B75B02DD436535AED897AECD520763AC7F8DFAFEBC122594388F210DF28DE472E748CFB640E8899B07CB4514401DEF9E9C542DC89733F20F9605F641DD1DD6F332DC051C2E5B2C391ACE70FD00FBC251EE1EA2AB27D165F966DA338F8AA970AAF66931F7CC68E2846EE5AD7EAF8E15B9CA333AD1260163E2BE2324C03094E249D3418164A655BD469E506F5B8420BF4FF6080DA230373B18D74AF03F11C9B545E3791CCC9B3B9927B2222983B7A6DE620BE8520B215ECDA45302695C0229C2A9607260BFD3C6EB9D7EAFAB5E47FD5760FA23067BAC1E6A980C4727B0C187A5B6397AC43D3BE24C42A1D2FCFE43512494A7BFC5CC19455DF6AA6F2698A2903831CA2E5F4F84442E6A74BC9D3CC3D6FBEE97D5CF4B6C58D3DC9ADB359FB56CF35FE21F96E885624498ACDF0BAF3A52B7F2564D1EA384DDA7FD32167786C5E010C3BCF5D2E7164BD6ECE815366887250D184F8061E57C3935214F191B38E982132EF4262E91808FF1CFD902B5248F6E7C031A98234DE0D578D1234B7453F2F575A88B622B0F11902C2146F45912E9BDAFA0846AF7B6789E621ABE3C65A4D990A96488B6307BE210887E82BBADFB026B60CA7DF3C9D429D8FEFCCC93A82E345F3B17756F6341F5DB3151974B1B9C7AC4AA33E80923475FE38FFC0AE7F47529360787AC283008971D87FB07369BAD111F1B99FAA59F2E1B5C088A5F31A47ED6A8E30FF6465A7DC79967EA78891C8EBD462D2566A4EA30EDFB8B7BEDD3C4E2ABFEEE7B366125A19B6372CEE2EB2F85514648AE920D292F444E6F90346DF87FD7C107848796219027BA581B3D87704FA8605108CA88ACF262C5C07D9BFB42635A1944634AF0633B471D0D2B2E4D6284894E0E48D58AE5D07E95130C9FBA77A0F124F9348E1A570BA0D009B7B46E03CEB201B17114B935AA91691A7F830346636FD34ECE2CC295D0124AD8CA76CC81E942C1607699F0DFFD3BDB509392FAF8212363F562554B05F756FF252765E6FCAFB04C6F2CF6A76F2E59E14F5BD4EA8E2ECF50B17E632F346D697FFB7AEB82ADDEF5B4DEC0DEE73D2D96B1A33C6AB4BCF7A160B79114A48F224FA037315ADF0485AB63DC2BF09F02606DAD80F13F0ED0241E6F53B21BBBE584794F77D0B783A7093F53AC916A848FF0F9FA3FB08A053C4"); + byte[] ss = Hex.decode("2FFCE8C89E97BBA86A7ECD68088FB116A20601B88B8E88A3783CF2D2ED439769"); + + byte[] fixedRandomBytes = Hex.decode("7c9935a0912822144249e045d113b6e7cca2aa19b94d210a458e4c8dffc19aa7053095f130f12e7d79262cf801e5f36f63bf9ba079264c836bb02cd0a45a6dee06b7ccda4d18d429cfb5c7784eedcf12e28519d7da3ffcd65731b6d5b773204a55671a9d60940059720a74baa026a7777cd11dd3f81dbf836a06906d60aea820cdb70b606781805857448d6233a8e174b9c5e89cace15b40002c75a3b2c820a2846de5d6bf7c655a9b794d36e4eacbefaebadc20b9b7018c4fb60bb77f17d924db45bfbf74d2d052f8ec84b04cd70f6693f2eac613a0b55d9ad4d951d3808e66cd9d716ed9338a25aa41a9fdad9f7b46f10c6c8338bf52f8b4e2bf25e5e4071beb03e83b558e5db80a224da29951496268ae19980cea3c200e489eeeed9c16e2f0ac2d8daa9822958a84a0ba2fc08d4dba8fe84a3e60acab2183d1e795e74e58ee25a9e6d1fbcb30e564f9628bab26a674f9969d2625b7b7473c29bcc926486d1620bb9e9fcc107f1dded7c80189e7fa361fe8dd996b9c2d8f683847caa95d1542678bd200063bdb5757a4b6a72e8071b246df24fd5b30cf94eedef6ac59c892eebb3d4288fcf80182fc36db2946706dad5059ade4674341081ea63cd695aed3afcf51d66d01b5e61623d4fce329dc33835317f300dd58a9624153d0f8a25518c946046de3d55fb45a09396f4c8816c7f359a1999e32a4eba8d25920002f0bbf2e3b9850cd67f90fc11d1e3da7a9abf920d4007a952b77a9c9c1ac449abbdb1cd35ff17ef9182ed94b50e5b60c6400735362dfc37b59d23606e265aba4e88d617daff717c07b15d63c59e7e72aa19fe6f360ba4cae860c9045ad03dc845edaf2786583fb53bcdf05d21b336d25901204d7794cd3b7dddc30d28b5ac4563be1a6515d323d821ae873d0b6e5ff48dec06d8f9585ed64f0bcca2a353b64c7dcf0d6ae9084529a30db3a40163bf8acac48251c7f82b5ade896d66f15ed82850bb86689746b0144561a25634a8b2f5f62470990d4a67e105183d208ccfdb9ed024c52ffe5f0afd3219022e95d10289de8a31ce0666f8ab7ee89583ca70109d7bc4fde5922bbc35c31691d4874e0a3c9c2b9f3731029fb14c6533b650a31242a3b33002c01a2add52c76d828acfecb87193e28ea8fcc99f2cc2d51c7f512ace14f864749f20fa8c554db03c2d8fd1cb5a2274ec97a470e18783d2ba66165798d0b1c0652615e5b5cf9941474a66dda526c474c7c8d2189058db7f1cb6cc3687e5c6fe322aa8a615cefbf6abdf0a0c36cbb32a0a58183c460a692e2e89a21fa709aa3da00270c6e7368b1a0178459c96c2c539074a72f7d1867a6aa8d9f545cd270930bb05c99a8c394357b0377eb66f90529882093cb5cd5b8ad08f538966fab56c5a29883214009c76d69de18aabbbc4f5cb757e8b5422d5d7869e91e3850ddbec01bc40ed11b2134d40d109508d812e7b7be26278c585a1703e935737ae3bff4ebf9bfa383ebba7e2f7d0fb9f4b78479a70c6a6d1c0394919fd1cda8600fd284418d6f4d3cae2b213f4078df0de5a860a23738fd7f85450f3d7f9903b306f863c7808296419c06a4a12a6149a0b699719aa762ba72f0a052e971b58ac97185ec95a5b8784b60355f163c4dbea0b1fea3e8e5f23eef6abbfc155846052f396d5d97731678e48ad0668391935a6594fabd5b33440b647f343601e909a3926719bae73df1cd6af5904bce016a4934b27b01b45288ab1c13a3d72531ad31adc304e7d38291b35e2f8c3cfc153127d5465a8b953a3af7f7e5cdc22174919e50d7c195cf5a7463facc8f17baf75118259bbf5316369bd70c7211a240def65fa94dfb58f3984985b9815e32c3591c93cc9fc47e75ebac8aa0044681e34791a1b847068386520e36bdba90735c870a3cc9fc8b7be1c084d4200c5f02b7476cc7c406e1b8335c4b3e05a98f6567a942a0dddf9d0c4e26a700454b34a6f174c776978dbb7c18c40070ab899752040fa824ccf63d31f15f7f86c44905e4898f0ed731becc9d20b9b35b92a57de9f5e42c38842ae6c7d94c8b246825f8d722db09b138db117d112968ebd1ff4bb835bff94cfed81fe6f22915d2e0ce4bd1cd743788ac146fe4aa7e2ed023f88e8f96715c97548bbaf0549f1e38fc16ca351206745e7ebb59649e9e534c1633289f8cb0071bbdee509cb131bcc7f26d3b548c17fd413a3a3101583b18f3335e0380098a3cfba480f7e0ff0b606c03338790d6d2e5b2307edfc311721f1587ca55501f4b4b5aeab9773ef78f27c40e8a42bcb57c887f99a6d56be4647f12a52367936bf3b63bea50319990cb58436a5dfb819c09c27299e778a68347f40ef386c6ae97e25f9fdfb7da6b8c6efd04ec9eb83e6cf431b2661a29f4203b286d4dfd860aed5eb5456b8e4a5b9cba46fdfa83aea1e043b3182784c8cef3feeee0343be2ff4d5cfae8c202049a53a20b35fdc1c82e7b246ad7cc7e0a2b05368d873d948284a206d12ff366456ecb1123a121c8d2eaa53a423aa6b4e4c36257b7a18d1ebdb28c0f5a76a3938cbff7b0e1b43dc5237a3fa7b6266bcfba4ee44d7ca17a84e0a97d8f4baf6b9843af217d5275e07336413a3a0790856b8a25c67f6d2822dd85120dc18d70d6ffa1501b3880d036876322c1769f08bb767e9c6a7948e9e8d87ba0fad66ed655973ce1bccb8dedd9c7f2c80250769e247ce679126cb3f2fe64ae05110691ea91626d8ea26f4cf674626e62850e4523ebbfef5a926c90d9d33fa67f6bc50d35737801604e5f5b119e08c306ba7b0c09f79f871e10b2261cd8f489ccc14bc17ace710a407e0ae21732192ab6febcf4d58c53ca415f0d53e4746267874ee026106209cf1ca11099ef5e59122f4cf17d50131d0197d3b7a1fbde22d3d40635b106b27315e033e2d8e8a0cd45ba504848b470cfb1fc78d47f65226cf0968aa51fd62568b9108adffcc25193d747e735dd5e06766ee213f5ae9032ddb28cfcef714ade717c9d18b7d63e4fc057ef88fcc0894a23d36f2aa16dd530086239279cdbe14764656bc51f78f4d448c38320e32e110bbe4e90bbcf11d924563469001ea8561f5710352f44619ca1c2f108d021f520008b542071ca87c936bbd87cf42c3a06e10976cd82e074974601ad86662b283ef5d2fd63486a98acc91758160a5e008333ad3b365be36836a196643b4136fbec90ef50bb944cb17ee0b55adc5a60dd81809e74d3f4ab5751a4c1b94fe7082f86c6935b867d15bc27328c3a7d9e5215fc8a2fc7f3d088446353ec9c92d3b5d01fa372540d1de064ea02030a300eaf73eb4eb40e5b2ec2b0c6d3d52f63369bdcc63d268a065e18aeee15474393c08eebfcb9d2a795e5422fd50fd099f85759966ba28127bf5b1eae0851b5c567c23ac33469791cbf78e827f98c4269b997008ac745188aa2a77cddd83574858a7a321f46cb0db5b89b100318c818500dd4d5a8aaf16c38bf32831099cac8b121e191ea8c50573f395bc70753839643e602b3b2242eaba726ec243a643392df202c6fde7e8436609969436aa1707fee35a08e0aafdfcd6471db08b9814e4547689f04e5f8b918fc0a8fd82784865ef5cbcc53da7e2fb1adc45e5a429833003b159edd94f3e1400b784181c81a270517c22fcaa0fd7286adafe160b3b17495ca6186e7e15c878be4c228cb5f79a4d940dbdfaf94392aec9aaa252c9eb0b58dded996e081fc1bad2a7a229f715b4690d8871ae7b086961f7b7d44e1f9a2bd093042919d0543007e29e222c057540f0ead016575771f85811d93583af887ca5f8094c9274b4b933f528788661c9eac7d6f736024051df17028b8d06f4ca6d33dcef7fcb6cb4a063b764706fd0d457c6119b6ce77fe47d40881bbc41d5fc042717fe4b599132af01cdb6032fcec422410c071f3d83eae54264ac430927e85a468308f96dfa26ede5fa047df6d63fadfd3861bd3507ae199274d6e0b3e329a10a58cef6535747ee4a6c5ca9ec10a39f2acff29a33b82d09b899d6c4c1271ac8e6721c0c77dbb6af1b4b4cb7fca8dfb716a76f6f587950d2ae419c4bfcdfbfe4fc08605627964b126c39ded0e22260c7450b7ae8e9397a27ad0f614577524224eed1976a085dbc1889d2495ce1b94a32153d9e433b27beecbd7e87a411248aeadb5c6d155148336bb55f23bfec0efc2d32463b46c2293206137ded47fe3c1cc7f64e135222308209640dadff7c9da43f9939894b7a67c298d7a790a5ec56391076f8c9518d85aa1d5df44cf3043c15ceaf489e6b7eeaad05907373c4fd7a16a4982299b66791d3436ddbdf438bfd98e2d94f0d41835c604b992d69249d798fc66ff358905dc801c79d60ae1a498898a7faded0502cbb751bb56ec28ce4069b4531c7c20c7dcdba2b0f21691bc776d7eb4295124f8411832f8941229c43b0881aee44425f6eb418143ed19d1fe79fe55cb5744259a4bc13c3512227c06a8c42563c9951516327ea8e90b9f4313e146e8b452814a93fac4564ea1bcd51360c8d19bbc07331ee161bff595e330397dfa532b2b2d25a428a999bf9b357335196ad4a7d7d2db12ca056549223039379aaaf5f89d281e04e986f5dba96ecaee589032db3d66118e4ce169a6a3034394baec899bc5eab4385973728be47fbdaba1d6cf6db50d77d394306727244eca23f2b68af3e38d275799bc81c840fd425e06d516cc33ca100c0d704ba1606ef4199d1b47d9a756a171309746ba0cdf48e9a0ee457cfe19a99d4112405d3318968ca97e13f72f271df0a5b487b3c5869fdddc6d53c1e7190ebcccad22f5d52bb99780a1887ac2fa0b933a0ca708ab7f20e1bb46ec6238351ecfee46cb42bb574270b46f4a3626ba8af5b5b3c96ccb7f1acd772b13277412fdd4ea740f8c6ea0d2383377115f8d17c095b8325ffc82ce966150413de37d622bc426c3f8ceb1cde12069e3c41e90d248ac627be702482c4efb2f028e2b2a607e2bbff190ddb710d7e36a7811621baab0f134434c254cbef59e86af197b6289e72d24714ca1ea3784bacb250676a778bf9d6ce2549799af999b917c8df2db58ec799ad51f10d0bd3707aa5f3c3aca8b8a105914825e6b78709eed6190de883b34bfe6f4bd0c91001a5a5d168a5212c95ec4ba15c700c937fd359e401899e56e3db259da628943951e8b2a366c94ec46b9f6b5d4da72943ba738d662d2cdb4fef6091ead96cc74d272c4c89077765ab6e93cafc737c82ab30b13b40d14c595d7a5efe4e89cccfb81275776c2b8df49db7c37f8a149a1a53703a255095021c125679d6929d8b46de63254204b79f43bef2f2bd7f0e2143de50616e19346239acb7db9a980baf1f212d2c26c69fae7d759c46da0aa97f443031d06f8b6a85794ec9fc778d30f08a4292a5e13488767741ff120121e0037c3830d32b6181008b47a8d48126af48719a7e7396ca1d6e787fba426a54410364baf076426f4c72dbddf964e5dc617bebfe8d381320150ec065cdd87288245115a18ded71c70b06cc02bdae6d695cbbb5b3d8a2aa16cdf80d84d511ac1b754f472f66ea6c5e312b4c67a66067e1f9d32de4d1d14c4c4e2cab3f40c2895c18a56b94fa40b75641723e7c147a594c89511956f046f0fbd26f3d3814c13ab717c7e164bdc9f8c0e5ca120724989897db7def83513e8325176d04a774021ba934b174af4b063e8764a8cf7c81822f8eb2c5870ad4b876051fe5c18c352cc03b885f74c65d22a5f9eb0fa399782ad33639c0ade4a2c1ff3ceab622373b98410f25c3de2d570f847fcb8492ba5b06661287a4e09af59374ccd9d080fcbce8ece50bc61c96d3b5ecfada0a974f04329d6f245083c3e7d49e7c59e2cc437de2add8bde7518f0b8961c7565705cafa86ff93a9f3fe8d22a7f76446e4e26a7534f8714081433b4f5c95d68a1cd7bf0e5cd74adfadc851287f9ac437cf0c67d3c5e7bfd49fb44f4277b860d657035303cb2d872fe8530e406d3607e3e33b45f47a8a42a229362cb0208cd5de79a7c0069b7fa8263c606b2f80b66d7562d975b9f096fe599cd28ba85521cd123f665d6c101665af1d4f6c850e28b3ee8b8f74d2c63e7331a55edea8024059810071122e0f8ec7c3776a148a28a987e2db7eef4f493c4e69e20f2ce2caeb305a23bede1aff4bcd706f87be91340d48eee4f8ea2fa7f496e882ee68c9f60daac3ef08c95452d936a8762d15a47659e4a791b03ab52cd0407cbe3677b4cb3b9c2d3f19b8f21250b28abfe1eb6c4e4bc92014fc4f10b165a594c30131f571aceb009e5574219584e2fd3f3281bd6156697e8347bffb50c3b699807bff24fabf9a7ced1d796078dce628d3ae6445b81c8fb6a633b9f25dd4d25a5a6d64b8af3c71c5b392822aa9e5748f3ce90b0c44f7857ec8dbe90d15c9b31152430b245139da98c63cf1efb6d89c674b15e51d30a282f779a6dc4b23a5e546fcf8cb0bdabaf6640651b98b6e8c7afc5c084938ef0d099f87466cd1648cb9aff11054c70ebd8921e459d6245b89ea05cc218d48c331e3138a7613a1500dbdc8b5077e9063b39a4a6aa8971e910228f026d3437b1344dc8f746bcc34a94605fa855200afc964565df617bd3c04d4998c162623cc4975fdea827256f8f61da092fef0e4a3023a03c6aa606579111dc80c118a470b9a690409b125cee61d64472d40eec1c222cffe7c3a59f8a00fe2fe51b072644af0be728bbf948f2848d1371b34d09f0fcf3fcc31d084ad69d7edc2e1aff6651f7f0123e1a83c44891567a34357b114e060e82464d18cb73a2e7e2b5f604c09938eb06df26a0141a55e7fc84f219c7728b022ecba2f1c71266a5e6aa7bd784a8c6e0db32b53cc03aa500fff71b06855acf22b8335531655fa414693b3fe9a320a98781ca9f60b955b3817f54873915ad3fcc843b172a4cbc5d3091dc4b301b4417a391b66895ee37ab81a6fe186fcf6ee7f61fe3b89556edda3130153e2562aa190be6994ef738fab5c2dda559e63f4b5b1f08faecf5e3cd9afc5d6336c45273ad5f93dd26d0894e2dc587f7fc1b26ea6b2428e55f07d9e175fdf9d9e0b58df7e169079cf203f21e5aafcd3a7710a0259d87be594ba30bcb2a6a2e26b28f499c3145889198e5aef16fafdbd1c440c300d83100d11d0a0647f0066608e847b6b109e9853b2549ffae9498ab5042823f0fe0ab248ca6ef9de115ecec752dcd1bf2e4e55e79cc0d17866c97ddff73f7e35eb598e60ecc8ac4cab0db57c948aca8750b1543bc926d2cd7a6239a683cba85400d0bcad56e943a4f614bea94990bc426e1eae75046b6baed05a59bf0084eb777d824d0d212e9819e2ea7db881c44fbb85bc374a0d6235f8392a3d9a761a5747d75d96cdc3c8dd7272eade200d57230d15e762228da98178a193d7d95284b20e82d74228146fdf68d59b37c5e7f78c0e14e7c40bd4f4d9cf0b189b69983dd39e29aa6439ecab0a5b294d2a1216ce31cac6d1b2358d2b0476c4d8002519b6d63639b2d4564e2458c8e06bdeebe82262570777780f43b110a96547415a69a38ef0ece0c2af16b9cf11ff8326e2de6dd0333b2ede445aa3a1057824478bfc71fd00dee601938734810d816f4dadd35f4c130598b9678682552d0d9bbf0116e52f71e30f449c6e70b673af7186d562e4591cfb9fcc9c591cfa471b8e3ea987e8e6b5f57d6ea8dd522e74d63169f343b20f9816236320cb16a04fc7b629e6240bc1686651f69bf37db30dde39875d57beccdc24c9d5575b0bb0b86f6d2e06f857152874f3a9034cb6018c5f83c55665f22a4195cb93fde9d0294d0769969423c54cdea07300e6f2bcda80f8e35f2631ceddbe3d29cfbb81a94d60b576e5c471ae1dacac226e9178369177bae4f33fec7b710b587ce317d3781e5fa8bae55167b7b93cdd061782786fe574fb7296b7c338edcd16642149ef44e694f8d30eb602193457a9956acb38b8ffdbf22b7bd93bda15b79cf2ed4c8e4606052696fbf38a852bef0ef9e8cecc8faa42493ff945a0b6cf235f7a64b03e4cf567ffe3687b6208c42c7df3272008f9c57ef92801444faf4932120223aa8882a57ed3cd8fdce71fe4ac4ea41dec00b74c0310d25260e0f95a4b89b5cd96ae446b33bc433181db39d0b4e48de172186f9c50ef7ac72adaebb2202b358a1250070349c66516d7f5d895ecf2dec601759abe52e2c7fec904db0b8a4390a4f8367db536a6a1eedc4435a6de58b62b3d4a946061b77adc10d21535a026657ec07ce19d9e097f93da31ef963ec7cfb971edaa8acea7537f5280b51188d88de355a79408f5c1fac07234ef9629ee992abfc874b33572362b95722ff1714cc238c68be7850c3bfa7bb5bf2c41122192cea2783f79cb558a65198c93a6009fd3102ed3d7cf677c5c632ec1a31abc087e2ab717c9abd04caf709a3855ddbfb70a81099f22ec5f49f3122e6633882f813bb76e2597670e37f36240e00a75b4b90a132cf2b4a652269ab8be1697087fa262593a16639f496edb72b0c906eee57a219c51dd548a697295bfac80d400d834c486a7642aab0d12aa4617abf1f604b5d6c9cf40c57fc8454761ba7fe54cebd8ec43daa495a6feba2e7524b6b771348100b3af4eb145642d006c3acf26262f8de8a6465f4eef60bea55615c19c50790daa8a0a39d42d66f89e4e6e3a5029cda85b50bb256ce3c57ee6aed2ae47db1d10b05bea586992a0b3a282d36d7c8d254badfa4a8b7f91d0fef5bc971b99b7c2d0aaf904a42b11139cc22d6450b6467c9453f1392193fd16b9aa565c757fa9457a9723fbfc6ce3b2f8381f0393b4eb984068adb273a50ccbe4e8fb708902179e0b8d645481a7f3919e07f758cfd12a3496bdd5b063d99ef127cb36dffefc4a29c23e63da9f4ab05a20faf7d73d70c619d48a92c653d415b7a9aca0c499937fd2acc6b1e6842d5f15c00bfa3b1d1c1655f8601c13f94291bcf76979b2c45d30384e4ce99a60ec088c9328a393581a8bf247609e5f9f025d98df1ed6c25ed4d6dfc67c98ec93b9158e7ccb8e8a50f4548479444ca7386ae077140d8a26459123dc28c9bcd531e3287f74cea298cd4f475c45e51792e439ba4368171a5ff60656c1ec132ce5affd6814f5f0fd786b15479a8bd2d2d3874bae96ab58e3b603bb251746b67bd00bb210f3d00e3725ad2a9441a11c8d320aa18e83383815f1eae1a7f195034f9dfe7ff7c4fd84acb7c2e22ec131d928e425cf96b64b562de90593cd61f237c11e2a4fc33a7f5333e1c6085a8f0d393e346646f36b3c4767c3681ce53c75414d72c57121fb10ac3f0eb8b784794cf2dcafcf0fe0c7b003d6171c20a3d63b44d168ef4bb79da894b5555c6f69a4d6e82fa558526e1bb75c63dc8e0fcbe3b9d462c0933eec9f034d4e917f30d48e98a93755c7c8771648711b81e5cb6f4e30680b7ce662cee5c8a02df4d1cc8f6aef8e632eaa09474321f231b7ed4cc9ba2a993693f4169b7752402bea7309d0412c9269799914894ebfaa9785716406225a18101a6f393dad47dc052c45bcad6f8bad49f108d6d179588d1c08db51ec9a50ce2702c9ecc1f9ad68633060579801e2d131d1044effa20ac6fe815f15d64e900c7d72d57ce8a398ac34119490d71b1058ffc111e089617145d592119352203f341c0ba91941455c29d5c253bd219bfed0d556212098a969a38b6d561be89635273ae7e4531210dd7b0d0310f2806a6e7a46c9f908c19862f9e05206d8408b246f4b8a508b9e78824cb9da63e4b6fcc2bdc9c391f2d4b9e3008dba425a937e025130b7cdd946dafe43e3a18f7331c04e063df4ee19cdd09e2c652acf3f4ced146b3b38f0fb8f8dae0f9fb1f87881cb1e7cbe6c33da4b704f03921810fbf3368a11c3014d2a4bfca1396ed43b3c3a3c6de41ee3740d40eb28983b2967f74a5a2a0515f68f70f4746dc94f29607f14b671c088df491386a38cc6f9765cc9b2ac7e91d80a2506624a9b0864aea397eddf2a9647d6f42cbdc68f4e8667f3d5614faf151b94acde040329ebcacd4d6ad474306c990998423ad8fb307e4a47e4e73463d913c812e3316a77bf238b89f69178dc0924253c110ca5396095d7c1689526e1cbf8dadb924f19df73aa7c97b59e013d6c4ddc687e06e10f82c7aeb21011e931222a777ab3a87759cb893b380ce15a22491ef3dacf62512e3d0561a137aa294d981601813767e44decfff7e84b4c33d6d73022f20faea96ce49976f75c85b390bfdd508a8c2a1f77681add20cfb715fffef359dda3e824d607ae19f298d7323210b7bd3fa6db1bdbdf613d13b6b7ef349278eabd1ec4ae836ad0307e3f5956e753b39c5edb973a6f90012962e3bb75f673461c211e711109320152825f5c9fe4b516f85eb0ba33e8719843f1ca4c965bacdf870dcd53dc05ea444696c615be7cb9214235f008b4c458fd0cff1b313e3433eed9ac1495785a57c4da01fded6650a61d29cecd2462a84faea9b689d050021f4b7d883edb39ad74a5eeec5a898f73f40fff5b74948fbf96ad6afd14d48a2f4b15782d163f219b069f2da414905b5b97576f4486fea35e93d2aaa4b41afeff1db600782acd9658479c960603aaaccf3fdb10bbe916936ca4526e2a3751ecef7abe2500bf18512d52006bc80c2fe5481727125e0a27d4342f3046e626b753b40eb210dbd64c8f67059fbe0c93146d09f30550cd33f3d03986f842a9421f07fc94f09ca898526e4cd51ba9b268beffeaa5f381c59964b5ca8b04918433b9229080b54be25920c8c3ddfa2b98d5c095a6800c1d3d03c8b30e989198fc96c3c8dae0d8d2ca09365d23c9e46abb40591d30817eb8e33985dedd0387b3ddc66fb655d37e41efbad4c05af86ce280afa66e591a619bf9236e5b7b7b31bdc87f63257aa652630afbe9ad8363750c04042c43ad5f392076f7481b3ca6b3dd83d7e87c604f8b08b0f13234fe8d8e5ab60756ae91d0d69eb144a3db813dd6095bcbee564b04a713152e40cf86285c1d51088832d18184b90f8db1d7e7d55bc79a2178b833523e0af31c027172271477162fc13d848d082b37bd1fc5700383cbb36ccc550ee3ec492266f9a86075bb32171abab9a335317d47a85de18d44809c6fbdbe76d2e5a5aec7cf00250eb24f453038b89e6cddb09e646676419c252e14f0d661f85747cc17f67732ca487012c3bb8ca822a9518695e68620af1ee12d2c6e48e0775128992922364c7bef20448e44025d399918109fc3ecc93f1c57c04be4409df78823aa4f098e3883282d7f9cbdac7aaa49dc8795c67578c862a0e45097499bbdf0b0e37"); + FixedSecureRandom fixedRandom = new FixedSecureRandom(fixedRandomBytes); + + // Receiver side + KeyPairGenerator g = KeyPairGenerator.getInstance("SNTRUPrime"); + g.initialize(SNTRUPrimeParameterSpec.sntrup653, fixedRandom); + KeyPair kp = g.generateKeyPair(); + SNTRUPrimeKey pkR = (SNTRUPrimeKey)kp.getPublic(); + + // Sender side + KEM kemS = KEM.getInstance("SNTRUPrime"); //Should the name be "SNTRUPrime-KEM" ? + KTSParameterSpec ktsSpec = null; + KEM.Encapsulator e = kemS.newEncapsulator((PublicKey)pkR, ktsSpec, fixedRandom); + KEM.Encapsulated enc = e.encapsulate(); + SecretKey secS = enc.key(); + byte[] em = enc.encapsulation(); + byte[] params = enc.params(); + + assertTrue(Arrays.areEqual(em, ct)); + assertTrue(Arrays.areEqual(enc.key().getEncoded(), ss)); + + // Receiver side + KEM kemR = KEM.getInstance("SNTRUPrime"); + KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsSpec); + SecretKey secR = d.decapsulate(em); + + // secS and secR will be identical + assertEquals(secS.getAlgorithm(), secR.getAlgorithm()); + assertTrue(Arrays.areEqual(secS.getEncoded(), secR.getEncoded())); + + } + public void testKEM() + throws Exception + { + // Receiver side + KeyPairGenerator g = KeyPairGenerator.getInstance("SNTRUPrime"); + + g.initialize(SNTRUPrimeParameterSpec.sntrup653, new SecureRandom()); + + KeyPair kp = g.generateKeyPair(); + PublicKey pkR = kp.getPublic(); + + // Sender side + KEM kemS = KEM.getInstance("SNTRUPrime"); //Should the name be "SNTRUPrime-KEM" ? + KTSParameterSpec ktsSpec = null; + KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsSpec, null); + KEM.Encapsulated enc = e.encapsulate(); + SecretKey secS = enc.key(); + byte[] em = enc.encapsulation(); + byte[] params = enc.params(); + + // Receiver side + KEM kemR = KEM.getInstance("SNTRUPrime"); +// AlgorithmParameters algParams = AlgorithmParameters.getInstance("SNTRUPrime"); +// algParams.init(params); +// SNTRUPrimeParameterSpec specR = algParams.getParameterSpec(SNTRUPrimeParameterSpec.class); + KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsSpec); + SecretKey secR = d.decapsulate(em); + + // secS and secR will be identical + assertEquals(secS.getAlgorithm(), secR.getAlgorithm()); + assertTrue(Arrays.areEqual(secS.getEncoded(), secR.getEncoded())); + } + + public void testBasicKEMAES() + throws Exception + { + if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SNTRUPrime", "BCPQC"); + kpg.initialize(SNTRUPrimeParameterSpec.sntrup653, new SecureRandom()); + + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("AES")); + performKEM(kpg.generateKeyPair(),0, 16, "AES", new KEMParameterSpec("AES")); + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("AES-KWP")); + + try + { + performKEM(kpg.generateKeyPair(),0, 16, "AES-KWP", new KEMParameterSpec("AES")); + fail(); + } + catch (Exception ex) + { + } + + kpg.initialize(SNTRUPrimeParameterSpec.sntrup1013, new SecureRandom()); + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("AES")); + + + + } + + public void testBasicKEMCamellia() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SNTRUPrime", "BCPQC"); + kpg.initialize(SNTRUPrimeParameterSpec.sntrup653, new SecureRandom()); + + performKEM(kpg.generateKeyPair(), new KTSParameterSpec.Builder("Camellia", 256).build()); + performKEM(kpg.generateKeyPair(), new KTSParameterSpec.Builder("Camellia-KWP", 256).build()); + } + + public void testBasicKEMSEED() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SNTRUPrime", "BCPQC"); + kpg.initialize(SNTRUPrimeParameterSpec.sntrup653, new SecureRandom()); + + performKEM(kpg.generateKeyPair(), new KTSParameterSpec.Builder("SEED", 128).build()); + } + + public void testBasicKEMARIA() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("SNTRUPrime", "BCPQC"); + kpg.initialize(SNTRUPrimeParameterSpec.sntrup653, new SecureRandom()); + + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("ARIA")); + performKEM(kpg.generateKeyPair(), new KEMParameterSpec("ARIA-KWP")); + } + + private void performKEM(KeyPair kp, int from, int to, String algorithm, KTSParameterSpec ktsParameterSpec) + throws Exception + { + PublicKey pkR = kp.getPublic(); + + // Sender side + KEM kemS = KEM.getInstance("SNTRUPrime"); + KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); + KEM.Encapsulated enc = e.encapsulate(from, to, algorithm); + SecretKey secS = enc.key(); + byte[] em = enc.encapsulation(); + + // Receiver side + KEM kemR = KEM.getInstance("SNTRUPrime"); + KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsParameterSpec); + SecretKey secR = d.decapsulate(em, from, to, algorithm); + + // secS and secR will be identical + assertEquals(secS.getAlgorithm(), secR.getAlgorithm()); + assertTrue(Arrays.areEqual(secS.getEncoded(), secR.getEncoded())); + } + + private void performKEM(KeyPair kp, KTSParameterSpec ktsParameterSpec) + throws Exception + { + PublicKey pkR = kp.getPublic(); + + // Sender side + KEM kemS = KEM.getInstance("SNTRUPrime"); + KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); + KEM.Encapsulated enc = e.encapsulate(); + SecretKey secS = enc.key(); + byte[] em = enc.encapsulation(); + + // Receiver side + KEM kemR = KEM.getInstance("SNTRUPrime"); +// KTSParameterSpec RktsParameterSpec = new KTSParameterSpec.Builder( +// ktsParameterSpec.getKeyAlgorithmName(), +// enc.key().getEncoded().length +// ).withParameterSpec(ktsParameterSpec).build(); + KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsParameterSpec); + SecretKey secR = d.decapsulate(em); + + // secS and secR will be identical + assertEquals(secS.getAlgorithm(), secR.getAlgorithm()); + assertTrue(Arrays.areEqual(secS.getEncoded(), secR.getEncoded())); + } +} diff --git a/scripts/jdk1.1ed.sh b/scripts/jdk1.1ed.sh index d7f598a6bf..f3ea90bb3d 100644 --- a/scripts/jdk1.1ed.sh +++ b/scripts/jdk1.1ed.sh @@ -62,6 +62,19 @@ w q % +ed org/bouncycastle/asn1/x500/style/X500NameTokenizer.java <<% +g/private final .*/s/final// +w +w +q +% + +ed org/bouncycastle/asn1/x509/AltSignatureAlgorithm.java <<% +g/private final .*/s/final// +w +w +q +% ed org/bouncycastle/asn1/x509/AltSignatureAlgorithm.java <<% g/private final .*/s/final// w @@ -206,6 +219,18 @@ w q % +ed org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValue.java <<% +g/private final /s/final// +w +q +% + +ed org/bouncycastle/pkcs/PKCS10CertificationRequest.java <<% +g/private final /s/final// +w +q +% + ed org/bouncycastle/asn1/pkcs/PBKDF2Params.java <<% g/private final ASN1OctetString octStr;/s/final// g/private final ASN1Integer iterationCount;/s/final// @@ -232,6 +257,12 @@ w q % +ed org/bouncycastle/crypto/encodings/OAEPEncoding.java <<% +g/private final/s/final// +w +q +% + ed org/bouncycastle/asn1/x500/style/BCStyle.java <<% g/protected final .*defaultLookUp;/s/final// g/protected final .*defaultSymbols;/s/final// @@ -636,12 +667,24 @@ w q % +ed org/bouncycastle/bcpg/Packet.java <<% +g/private.*final.*;/s/final// +w +q +% + ed org/bouncycastle/bcpg/SignatureSubpacketInputStream.java <<% g/private.*final.*;/s/final// w q % +ed org/bouncycastle/bcpg/sig/PreferredAEADCiphersuites.java <<% +g/private.*final.*;/s/final// +w +q +% + ed org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java <<% g/private.*final.*;/s/final// w diff --git a/scripts/jdk1.2ed.sh b/scripts/jdk1.2ed.sh index 50f3cebc85..2cf02fd733 100644 --- a/scripts/jdk1.2ed.sh +++ b/scripts/jdk1.2ed.sh @@ -1,10 +1,15 @@ # # JDK 1.2 edits -for i in org/bouncycastle/pqc/jcajce/provider/*/*.java org/bouncycastle/pqc/*/*/*.java org/bouncycastle/pqc/*/*/*/*.java org/bouncycastle/crypto/digests/*.java org/bouncycastle/cert/cmp/*.java org/bouncycastle/crypto/engines/*.java org/bouncycastle/openpgp/*.java org/bouncycastle/bcpg/*.java org/bouncycastle/openpgp/test/*.java +for i in org/bouncycastle/pqc/jcajce/provider/*/*.java org/bouncycastle/pqc/*/*/*.java org/bouncycastle/pqc/*/*/*/*.java org/bouncycastle/crypto/digests/*.java org/bouncycastle/cert/cmp/*.java org/bouncycastle/crypto/engines/*.java org/bouncycastle/openpgp/operator/*.java org/bouncycastle/openpgp/operator/jcajce/*.java org/bouncycastle/openpgp/operator/bc/*.java org/bouncycastle/openpgp/*.java org/bouncycastle/bcpg/*.java org/bouncycastle/openpgp/test/*.java org/bouncycastle/bcpg/sig/* org/bouncycastle/cms/* org/bouncycastle/pkcs/* org/bouncycastle/gpg/* do ed $i <<%% -g/.Override/d +g/ .Override/d +g/ .Override/d +g/ .Deprecated/d +g/ .Deprecated/d +g/ .FunctionalInterface/d +g/ .FunctionalInterface/d w q %% @@ -104,7 +109,7 @@ w q % -ed org/bouncycastle/pqc/crypto/test/TestSampler.java <<% +ed org/bouncycastle/cms/CMSAuthEnvelopedDataParser.java <<% g/private final/s/final// w q @@ -128,6 +133,20 @@ w q % +ed org/bouncycastle/crypto/test/GCMSIVTest.java <<% +g/private final/s/final// +g/.SuppressWarnings/d +w +q +% + +ed org/bouncycastle/crypto/signers/SM2Signer.java <<% +g/private final/s/final// +g/.SuppressWarnings/d +w +q +% + ed org/bouncycastle/cms/CMSSignedDataGenerator.java <<% g/LinkedHashSet/s//HashSet/g w @@ -176,12 +195,38 @@ w q % +ed org/bouncycastle/bcpg/ArmoredOutputStream.java <<% +g/private final/s/final// +g/\\.\\.\\./s//[]/ +w +q +% + +ed org/bouncycastle/bcpg/ArmoredInputStream.java <<% +g/private static final/s/final// +g/private final/s/final// +w +q +% + ed org/bouncycastle/openpgp/PGPExtendedKeyAttribute.java <<% g/private final/s/final// w q % +ed org/bouncycastle/openpgp/operator/bc/BcAEADUtil.java <<% +g/private final/s/final// +w +q +% + +ed org/bouncycastle/gpg/SExprParser.java <<% +g//s///g +w +q +% + ed org/bouncycastle/gpg/SExpression.java <<% g/\.\.\. /s//[]/g w @@ -194,6 +239,18 @@ w q % +ed org/bouncycastle/openpgp/operator/jcajce/JcePGPDataEncryptorBuilder.java <<% +g/private final/s//private/g +w +q +% + +ed org/bouncycastle/openpgp/operator/bc/BcPGPDataEncryptorBuilder.java <<% +g/private final/s//private/g +w +q +% + ed org/bouncycastle/openpgp/PGPCanonicalizedDataGenerator.java <<% g/FileNotFoundException/s//IOException/ w diff --git a/settings.gradle b/settings.gradle index 2219c0701e..c54949b153 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,9 +1,10 @@ include "core" include "util" -include "mail" include "pg" include "pkix" include "prov" include "tls" include "test" include "mls" +include "mail" +include "jmail" diff --git a/test/build.gradle b/test/build.gradle index d0d035facb..62e12a040f 100644 --- a/test/build.gradle +++ b/test/build.gradle @@ -1,7 +1,7 @@ dependencies { implementation fileTree(dir: 'libs', include: '*.jar') implementation project(":core") - implementation project(":mail") + // implementation project(":mail") implementation project(":pg") implementation project(":util") implementation project(":pkix") diff --git a/test/libs/annotations-api-6.0.53.jar b/test/libs/annotations-api-6.0.53.jar new file mode 100644 index 0000000000..a1bfe9cec5 Binary files /dev/null and b/test/libs/annotations-api-6.0.53.jar differ diff --git a/test/libs/failureaccess-1.0.1.jar b/test/libs/failureaccess-1.0.1.jar new file mode 100644 index 0000000000..9b56dc751c Binary files /dev/null and b/test/libs/failureaccess-1.0.1.jar differ diff --git a/test/libs/grpc-api-1.58.0.jar b/test/libs/grpc-api-1.58.0.jar new file mode 100644 index 0000000000..cc4a4ba90e Binary files /dev/null and b/test/libs/grpc-api-1.58.0.jar differ diff --git a/test/libs/grpc-core-1.58.0.jar b/test/libs/grpc-core-1.58.0.jar new file mode 100644 index 0000000000..a4b2cbce7b Binary files /dev/null and b/test/libs/grpc-core-1.58.0.jar differ diff --git a/test/libs/grpc-netty-shaded-1.58.0.jar b/test/libs/grpc-netty-shaded-1.58.0.jar new file mode 100644 index 0000000000..1f340efe0a Binary files /dev/null and b/test/libs/grpc-netty-shaded-1.58.0.jar differ diff --git a/test/libs/grpc-protobuf-1.58.0.jar b/test/libs/grpc-protobuf-1.58.0.jar new file mode 100644 index 0000000000..510ee1a672 Binary files /dev/null and b/test/libs/grpc-protobuf-1.58.0.jar differ diff --git a/test/libs/grpc-protobuf-lite-1.58.0.jar b/test/libs/grpc-protobuf-lite-1.58.0.jar new file mode 100644 index 0000000000..75087e3f87 Binary files /dev/null and b/test/libs/grpc-protobuf-lite-1.58.0.jar differ diff --git a/test/libs/grpc-services-1.58.0.jar b/test/libs/grpc-services-1.58.0.jar new file mode 100644 index 0000000000..b7b939d891 Binary files /dev/null and b/test/libs/grpc-services-1.58.0.jar differ diff --git a/test/libs/grpc-stub-1.58.0.jar b/test/libs/grpc-stub-1.58.0.jar new file mode 100644 index 0000000000..9edd767f51 Binary files /dev/null and b/test/libs/grpc-stub-1.58.0.jar differ diff --git a/test/libs/guava-32.0.1-android.jar b/test/libs/guava-32.0.1-android.jar new file mode 100644 index 0000000000..16d9592040 Binary files /dev/null and b/test/libs/guava-32.0.1-android.jar differ diff --git a/test/libs/jna-4.3.0-sources.jar b/test/libs/jna-4.3.0-sources.jar new file mode 100644 index 0000000000..d888ab8f87 Binary files /dev/null and b/test/libs/jna-4.3.0-sources.jar differ diff --git a/test/libs/jna-platform-4.3.0-sources.jar b/test/libs/jna-platform-4.3.0-sources.jar new file mode 100644 index 0000000000..c9adeb3cf5 Binary files /dev/null and b/test/libs/jna-platform-4.3.0-sources.jar differ diff --git a/test/libs/perfmark-api-0.26.0.jar b/test/libs/perfmark-api-0.26.0.jar new file mode 100644 index 0000000000..ceacda48fd Binary files /dev/null and b/test/libs/perfmark-api-0.26.0.jar differ diff --git a/test/libs/protobuf-java-3.22.3.jar b/test/libs/protobuf-java-3.22.3.jar new file mode 100644 index 0000000000..7685cda197 Binary files /dev/null and b/test/libs/protobuf-java-3.22.3.jar differ diff --git a/test/src/main/java/org/bouncycastle/test/est/HttpResponder.java b/test/src/main/java/org/bouncycastle/test/est/HttpResponder.java index 0b3f87f0b6..4ea520720c 100644 --- a/test/src/main/java/org/bouncycastle/test/est/HttpResponder.java +++ b/test/src/main/java/org/bouncycastle/test/est/HttpResponder.java @@ -17,6 +17,7 @@ import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.util.List; import java.util.Random; @@ -27,7 +28,6 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; -import javax.security.cert.X509Certificate; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.util.io.pem.PemReader; @@ -256,7 +256,7 @@ public Object[] readCertAndKey(File path) return out; } - public HttpResponder withCreds(java.security.cert.X509Certificate cert, PrivateKey aPrivate) + public HttpResponder withCreds(X509Certificate cert, PrivateKey aPrivate) { this.creds = new Object[]{cert, aPrivate}; @@ -264,21 +264,21 @@ public HttpResponder withCreds(java.security.cert.X509Certificate cert, PrivateK } - public java.security.cert.X509Certificate toJavaX509Certificate(Object o) + public X509Certificate toJavaX509Certificate(Object o) throws Exception { CertificateFactory fac = CertificateFactory.getInstance("X509"); if (o instanceof X509CertificateHolder) { - return (java.security.cert.X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509CertificateHolder)o).getEncoded())); + return (X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509CertificateHolder)o).getEncoded())); } - else if (o instanceof X509Certificate) + else if (o instanceof javax.security.cert.X509Certificate) { - return (java.security.cert.X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509Certificate)o).getEncoded())); + return (X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((javax.security.cert.X509Certificate)o).getEncoded())); } - else if (o instanceof java.security.cert.X509Certificate) + else if (o instanceof X509Certificate) { - return (java.security.cert.X509Certificate)o; + return (X509Certificate)o; } throw new IllegalArgumentException("Object not X509CertificateHolder, javax..X509Certificate or java...X509Certificate"); } diff --git a/test/src/main/java/org/bouncycastle/test/est/examples/EnrollExample.java b/test/src/main/java/org/bouncycastle/test/est/examples/EnrollExample.java index 726b8d2d6e..4ed8eec77a 100644 --- a/test/src/main/java/org/bouncycastle/test/est/examples/EnrollExample.java +++ b/test/src/main/java/org/bouncycastle/test/est/examples/EnrollExample.java @@ -155,7 +155,8 @@ else if (arg.equals("--load")) { keyFile = ExampleUtils.nextArgAsString("Load keys from file", args, t); t += 1; - } else if (arg.equals("--sl")) + } + else if (arg.equals("--sl")) { suffixList = ExampleUtils.nextArgAsString("Suffix List", args, t); t += 1; diff --git a/test/src/main/java/org/bouncycastle/test/est/examples/ExampleUtils.java b/test/src/main/java/org/bouncycastle/test/est/examples/ExampleUtils.java index 50ff4cb8ce..776218c282 100644 --- a/test/src/main/java/org/bouncycastle/test/est/examples/ExampleUtils.java +++ b/test/src/main/java/org/bouncycastle/test/est/examples/ExampleUtils.java @@ -16,6 +16,7 @@ import java.security.Signature; import java.security.cert.CertificateFactory; import java.security.cert.TrustAnchor; +import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.util.ArrayList; import java.util.Date; @@ -25,8 +26,6 @@ import java.util.Map; import java.util.Set; -import javax.security.cert.X509Certificate; - import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; @@ -50,6 +49,7 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider; import org.bouncycastle.openssl.MiscPEMGenerator; +import org.bouncycastle.util.Integers; import org.bouncycastle.util.Strings; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemReader; @@ -114,15 +114,15 @@ public static Set toTrustAnchor(Object... oo) { if (o instanceof X509CertificateHolder) { - out.add(new TrustAnchor((java.security.cert.X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509CertificateHolder)o).getEncoded())), null)); + out.add(new TrustAnchor((X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509CertificateHolder)o).getEncoded())), null)); } - else if (o instanceof X509Certificate) + else if (o instanceof javax.security.cert.X509Certificate) { - out.add(new TrustAnchor((java.security.cert.X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509Certificate)o).getEncoded())), null)); + out.add(new TrustAnchor((X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509Certificate)o).getEncoded())), null)); } - else if (o instanceof java.security.cert.X509Certificate) + else if (o instanceof X509Certificate) { - out.add(new TrustAnchor((java.security.cert.X509Certificate)o, null)); + out.add(new TrustAnchor((X509Certificate)o, null)); } else if (o instanceof TrustAnchor) { @@ -137,26 +137,26 @@ else if (o instanceof TrustAnchor) return out; } - public static List toCertList(X509Certificate[] certs) + public static List toCertList(X509Certificate[] certs) throws Exception { CertificateFactory fac = CertificateFactory.getInstance("X509"); - ArrayList c = new ArrayList(); + ArrayList c = new ArrayList(); for (X509Certificate cc : certs) { - c.add((java.security.cert.X509Certificate)fac.generateCertificate(new ByteArrayInputStream(cc.getEncoded()))); + c.add((X509Certificate)fac.generateCertificate(new ByteArrayInputStream(cc.getEncoded()))); } return c; } - public static List toCertList(Object[] certs) + public static List toCertList(Object[] certs) throws Exception { CertificateFactory fac = CertificateFactory.getInstance("X509"); - ArrayList c = new ArrayList(); + ArrayList c = new ArrayList(); for (Object cc : certs) { c.add(toJavaX509Certificate(cc)); @@ -165,21 +165,21 @@ public static List toCertList(Object[] certs } - public static java.security.cert.X509Certificate toJavaX509Certificate(Object o) + public static X509Certificate toJavaX509Certificate(Object o) throws Exception { CertificateFactory fac = CertificateFactory.getInstance("X509"); if (o instanceof X509CertificateHolder) { - return (java.security.cert.X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509CertificateHolder)o).getEncoded())); + return (X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509CertificateHolder)o).getEncoded())); } - else if (o instanceof X509Certificate) + else if (o instanceof javax.security.cert.X509Certificate) { - return (java.security.cert.X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((X509Certificate)o).getEncoded())); + return (X509Certificate)fac.generateCertificate(new ByteArrayInputStream(((javax.security.cert.X509Certificate)o).getEncoded())); } - else if (o instanceof java.security.cert.X509Certificate) + else if (o instanceof X509Certificate) { - return (java.security.cert.X509Certificate)o; + return (X509Certificate)o; } throw new IllegalArgumentException("Object not X509CertificateHolder, javax..X509Certificate or java...X509Certificate"); } @@ -195,7 +195,7 @@ else if (o instanceof java.security.cert.X509Certificate) * @return A (java) X509Certificate. * @throws Exception */ - public static java.security.cert.X509Certificate createASignedCert( + public static X509Certificate createASignedCert( String sigName, X500Name subjectDN, SubjectPublicKeyInfo subjectPublicKeyInfo, @@ -251,7 +251,7 @@ public static java.security.cert.X509Certificate createASignedCert( v.add((AlgorithmIdentifier)algIds.get(sigName)); v.add(new DERBitString(sig.sign())); - return (java.security.cert.X509Certificate) + return (X509Certificate) CertificateFactory.getInstance("X.509", "BC") .generateCertificate( new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER) @@ -268,7 +268,7 @@ public static java.security.cert.X509Certificate createASignedCert( * @return A (java) X509Certificate. * @throws Exception */ - public static java.security.cert.X509Certificate createSelfsignedCert( + public static X509Certificate createSelfsignedCert( String sigName, X500Name subjectDN, SubjectPublicKeyInfo subjectPublicKeyInfo, @@ -309,7 +309,7 @@ public static java.security.cert.X509Certificate createSelfsignedCert( v.add((AlgorithmIdentifier)algIds.get(sigName)); v.add(new DERBitString(sig.sign())); - return (java.security.cert.X509Certificate) + return (X509Certificate) CertificateFactory.getInstance("X.509", "BC") .generateCertificate( new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER) @@ -413,7 +413,7 @@ static int nextArgAsInteger(String label, String[] args, int t) throw new IllegalArgumentException(label + ": Missing Integer argument"); } - return new Integer(args[t + 1]); + return Integers.valueOf(Integer.parseInt(args[t + 1])); } diff --git a/test/src/main/resources/libestserverwrap.dylib b/test/src/main/resources/libestserverwrap.dylib deleted file mode 100755 index 0ab08bb724..0000000000 Binary files a/test/src/main/resources/libestserverwrap.dylib and /dev/null differ diff --git a/test/src/test/java/org/bouncycastle/test/est/TestCACertsFetch.java b/test/src/test/java/org/bouncycastle/test/est/TestCACertsFetch.java index d231135076..fa78758fd9 100644 --- a/test/src/test/java/org/bouncycastle/test/est/TestCACertsFetch.java +++ b/test/src/test/java/org/bouncycastle/test/est/TestCACertsFetch.java @@ -787,8 +787,8 @@ public boolean isTrusted() } catch (Exception ex) { - Assert.assertEquals("Must be EST Exception", ESTException.class, ex.getClass()); - Assert.assertEquals("Cause is IO Exception.", IOException.class, IOException.class); + Assert.assertTrue("Must be EST Exception", ex.getClass().equals(ESTException.class)); + Assert.assertTrue("Cause is IO Exception.", ex.getCause().getClass().equals(IOException.class)); } } diff --git a/tls/build.gradle b/tls/build.gradle index dbf411297c..06fb3077b2 100644 --- a/tls/build.gradle +++ b/tls/build.gradle @@ -1,8 +1,6 @@ -dependencies { - implementation project(':core') - implementation project(':prov') - implementation project(':util') - implementation project(':pkix') + +plugins { + id "biz.aQute.bnd.builder" version "7.0.0" } jar.archiveBaseName = "bctls-$vmrange" @@ -13,17 +11,154 @@ sourceSets { srcDirs = ['src/main/java', 'src/main/jdk1.5'] } } + + java9 { + java { + srcDirs = ['src/main/jdk1.9'] + } + } + + test11 { + java { + compileClasspath += main.output + test.output + runtimeClasspath += test.output + srcDir(files("src/test/jdk1.11", "src/test/java")) + } + } + + test17 { + java { + compileClasspath += main.output + test.output + runtimeClasspath += test.output + srcDir(files("src/test/jdk1.11","src/test/jdk1.15", "src/test/java")) + } + } + + test21 { + java { + compileClasspath += main.output + test.output + runtimeClasspath += test.output + srcDir(files("src/test/jdk1.11","src/test/jdk1.15","src/test/jdk21", "src/test/java")) + } + } + } +dependencies { + implementation project(':core') + implementation project(':prov') + implementation project(':util') + implementation project(':pkix') + + java9Implementation project(':core') + java9Implementation project(':prov') + java9Implementation project(':util') + java9Implementation project(':pkix') + java9Implementation files(sourceSets.main.output.classesDirs) { + builtBy compileJava + } + + test11Implementation group: 'junit', name: 'junit', version: '4.13.2' + test17Implementation group: 'junit', name: 'junit', version: '4.13.2' + test21Implementation group: 'junit', name: 'junit', version: '4.13.2' + + + test11Implementation project(':core') + test11Implementation project(':prov') + test11Implementation project(':util') + test11Implementation project(':pkix') + + test17Implementation project(':core') + test17Implementation project(':prov') + test17Implementation project(':util') + test17Implementation project(':pkix') + + test21Implementation project(':core') + test21Implementation project(':prov') + test21Implementation project(':util') + test21Implementation project(':pkix') + +} + +compileJava { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + targetCompatibility = 1.8; + sourceCompatibility = 1.8; +} + +compileJava9Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + sourceCompatibility = 9 + targetCompatibility = 9 + options.compilerArgs += [ + '--module-path', "${bc_prov}${File.pathSeparator}${bc_util}${File.pathSeparator}${bc_pkix}" + ] + + options.sourcepath = files(['src/main/java', 'src/main/jdk1.9']) +} + +compileTest11Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + sourceCompatibility = 11 + targetCompatibility = 11 + options.sourcepath = files(['src/test/java', 'src/test/jdk1.11']) +} + +compileTest17Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + sourceCompatibility = 17 + targetCompatibility = 17 + options.sourcepath = files(['src/test/java', 'src/test/jdk1.15']) +} + +compileTest21Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(21) + } + sourceCompatibility = 21 + targetCompatibility = 21 + options.sourcepath = files(['src/test/java', 'src/test/jdk21']) +} + + + task sourcesJar(type: Jar) { - archiveBaseName = jar.archiveBaseName - classifier = 'sources' - from sourceSets.main.allSource + archiveBaseName = jar.archiveBaseName + archiveClassifier = 'sources' + from sourceSets.main.allSource + exclude("**/*.so") + into('META-INF/versions/9') { + from sourceSets.java9.allSource + } +} + +jar { + from sourceSets.main.output + into('META-INF/versions/9') { + from sourceSets.java9.output + } + String v = "${rootProject.extensions.ext.bundle_version}" + manifest.attributes('Multi-Release': 'true') + manifest.attributes('Bundle-Name': 'bctls') + manifest.attributes('Bundle-SymbolicName': 'bctls') + manifest.attributes('Bundle-RequiredExecutionEnvironment': 'JavaSE-1.8') + manifest.attributes('Export-Package': "org.bouncycastle.{jsse|tls}.*;version=${v}") + manifest.attributes('Import-Package': "java.*;resolution:=optional,javax.*;resolution:=optional,!org.bouncycastle.{jsse|tls}.*,org.bouncycastle.*;version=\"[${v},${maxVersion})\"") + manifest.attributes('Bundle-Version': "${v}") } + task javadocJar(type: Jar, dependsOn: javadoc) { archiveBaseName = jar.archiveBaseName - classifier = 'javadoc' + archiveClassifier = 'javadoc' from javadoc.destinationDir } @@ -33,3 +168,104 @@ artifacts { archives sourcesJar } +test { + jvmArgs = ['-Dtest.java.version.prefix=1.8'] +} + + +task test11(type: Test) { + + dependsOn(jar) + + testClassesDirs = sourceSets.test11.output.classesDirs + classpath = sourceSets.test11.runtimeClasspath + files(jar.archiveFile) + + forkEvery = 1; + maxParallelForks = 8; + + systemProperty 'bc.test.data.home', bcTestDataHome + maxHeapSize = "1536m" + testLogging.showStandardStreams = true + + javaLauncher = javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(11) + } + + jvmArgs = ['-Dtest.java.version.prefix=11.'] + + + finalizedBy jacocoTestReport + + filter { + includeTestsMatching "AllTest*" + if (project.hasProperty('excludeTests')) { + excludeTestsMatching "${excludeTests}" + } + } +} + +task test17(type: Test) { + + // This is testing the 1.15 code base + + dependsOn jar + + testClassesDirs = sourceSets.test17.output.classesDirs + classpath = sourceSets.test17.runtimeClasspath + files(jar.archiveFile) + + forkEvery = 1; + maxParallelForks = 8; + + systemProperty 'bc.test.data.home', bcTestDataHome + maxHeapSize = "1536m" + testLogging.showStandardStreams = true + + javaLauncher = javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(17) + } + + jvmArgs = ['-Dtest.java.version.prefix=17.'] + + + finalizedBy jacocoTestReport + + filter { + includeTestsMatching "AllTest*" + if (project.hasProperty('excludeTests')) { + excludeTestsMatching "${excludeTests}" + } + } +} + +task test21(type: Test) { + + // This is testing the 21 code base + + dependsOn jar + + testClassesDirs = sourceSets.test21.output.classesDirs + classpath = sourceSets.test21.runtimeClasspath + files(jar.archiveFile) + + forkEvery = 1; + maxParallelForks = 8; + + systemProperty 'bc.test.data.home', bcTestDataHome + maxHeapSize = "1536m" + testLogging.showStandardStreams = true + + javaLauncher = javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(21) + } + + jvmArgs = ['-Dtest.java.version.prefix=21'] + + + finalizedBy jacocoTestReport + + filter { + includeTestsMatching "AllTest*" + if (project.hasProperty('excludeTests')) { + excludeTestsMatching "${excludeTests}" + } + } +} diff --git a/tls/src/main/java/org/bouncycastle/jsse/BCSSLConnection.java b/tls/src/main/java/org/bouncycastle/jsse/BCSSLConnection.java index e8e2421922..430b7ec5e3 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/BCSSLConnection.java +++ b/tls/src/main/java/org/bouncycastle/jsse/BCSSLConnection.java @@ -26,6 +26,13 @@ public interface BCSSLConnection */ byte[] getChannelBinding(String channelBinding); + /** + * Return a String that uniquely identifies this connection during its lifetime within the current process. It + * can be used e.g. for logging but its contents and format are subject to change and should not be relied upon. + * @return A String identifying this connection. + */ + String getID(); + /** * Returns the SSL session in use by this connection * @return The {@link BCExtendedSSLSession}. diff --git a/tls/src/main/java/org/bouncycastle/jsse/BCSSLParameters.java b/tls/src/main/java/org/bouncycastle/jsse/BCSSLParameters.java index d905654962..0936596a90 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/BCSSLParameters.java +++ b/tls/src/main/java/org/bouncycastle/jsse/BCSSLParameters.java @@ -28,7 +28,6 @@ private static List copyList(Collection list) return Collections.unmodifiableList(new ArrayList(list)); } - private String[] applicationProtocols = TlsUtils.EMPTY_STRINGS; private String[] cipherSuites; private String[] protocols; private boolean wantClientAuth; @@ -38,7 +37,12 @@ private static List copyList(Collection list) private List serverNames; private List sniMatchers; private boolean useCipherSuitesOrder; + private boolean enableRetransmissions = true; private int maximumPacketSize = 0; + private String[] applicationProtocols = TlsUtils.EMPTY_STRINGS; + private String[] signatureSchemes = null; + private String[] signatureSchemesCert = null; + private String[] namedGroups = null; public BCSSLParameters() { @@ -55,30 +59,6 @@ public BCSSLParameters(String[] cipherSuites, String[] protocols) setProtocols(protocols); } - public String[] getApplicationProtocols() - { - return TlsUtils.clone(applicationProtocols); - } - - public void setApplicationProtocols(String[] applicationProtocols) - { - if (null == applicationProtocols) - { - throw new NullPointerException("'applicationProtocols' cannot be null"); - } - - String[] check = TlsUtils.clone(applicationProtocols); - for (String entry : check) - { - if (TlsUtils.isNullOrEmpty(entry)) - { - throw new IllegalArgumentException("'applicationProtocols' entries cannot be null or empty strings"); - } - } - - this.applicationProtocols = check; - } - public String[] getCipherSuites() { return TlsUtils.clone(cipherSuites); @@ -141,6 +121,11 @@ public void setAlgorithmConstraints(BCAlgorithmConstraints algorithmConstraints) this.algorithmConstraints = algorithmConstraints; } + public List getServerNames() + { + return copyList(this.serverNames); + } + public void setServerNames(List serverNames) { if (serverNames == null) @@ -165,9 +150,9 @@ public void setServerNames(List serverNames) } } - public List getServerNames() + public Collection getSNIMatchers() { - return copyList(this.serverNames); + return copyList(this.sniMatchers); } public void setSNIMatchers(Collection sniMatchers) @@ -194,9 +179,9 @@ public void setSNIMatchers(Collection sniMatchers) } } - public Collection getSNIMatchers() + public boolean getUseCipherSuitesOrder() { - return copyList(this.sniMatchers); + return useCipherSuitesOrder; } public void setUseCipherSuitesOrder(boolean useCipherSuitesOrder) @@ -204,9 +189,19 @@ public void setUseCipherSuitesOrder(boolean useCipherSuitesOrder) this.useCipherSuitesOrder = useCipherSuitesOrder; } - public boolean getUseCipherSuitesOrder() + public boolean getEnableRetransmissions() { - return useCipherSuitesOrder; + return enableRetransmissions; + } + + public void setEnableRetransmissions(boolean enableRetransmissions) + { + this.enableRetransmissions = enableRetransmissions; + } + + public int getMaximumPacketSize() + { + return maximumPacketSize; } public void setMaximumPacketSize(int maximumPacketSize) @@ -219,8 +214,105 @@ public void setMaximumPacketSize(int maximumPacketSize) this.maximumPacketSize = maximumPacketSize; } - public int getMaximumPacketSize() + public String[] getApplicationProtocols() { - return maximumPacketSize; + return TlsUtils.clone(applicationProtocols); + } + + public void setApplicationProtocols(String[] applicationProtocols) + { + if (null == applicationProtocols) + { + throw new NullPointerException("'applicationProtocols' cannot be null"); + } + + String[] check = TlsUtils.clone(applicationProtocols); + for (String entry : check) + { + if (TlsUtils.isNullOrEmpty(entry)) + { + throw new IllegalArgumentException("'applicationProtocols' entries cannot be null or empty strings"); + } + } + + this.applicationProtocols = check; + } + + public String[] getSignatureSchemes() + { + return TlsUtils.clone(signatureSchemes); + } + + public void setSignatureSchemes(String[] signatureSchemes) + { + String[] check = null; + + if (signatureSchemes != null) + { + check = TlsUtils.clone(signatureSchemes); + for (String entry : check) + { + if (TlsUtils.isNullOrEmpty(entry)) + { + throw new IllegalArgumentException("'signatureSchemes' entries cannot be null or empty strings"); + } + } + } + + this.signatureSchemes = check; + } + + public String[] getSignatureSchemesCert() + { + return TlsUtils.clone(signatureSchemesCert); + } + + public void setSignatureSchemesCert(String[] signatureSchemesCert) + { + String[] check = null; + + if (signatureSchemesCert != null) + { + check = TlsUtils.clone(signatureSchemesCert); + for (String entry : check) + { + if (TlsUtils.isNullOrEmpty(entry)) + { + throw new IllegalArgumentException("'signatureSchemesCert' entries cannot be null or empty strings"); + } + } + } + + this.signatureSchemesCert = check; + } + + public String[] getNamedGroups() + { + return TlsUtils.clone(namedGroups); + } + + public void setNamedGroups(String[] namedGroups) + { + String[] check = null; + + if (namedGroups != null) + { + check = TlsUtils.clone(namedGroups); + HashSet seenEntries = new HashSet(); + for (String entry : check) + { + if (TlsUtils.isNullOrEmpty(entry)) + { + throw new IllegalArgumentException("'namedGroups' entries cannot be null or empty strings"); + } + + if (!seenEntries.add(entry)) + { + throw new IllegalArgumentException("'namedGroups' contains duplicate entry: " + entry); + } + } + } + + this.namedGroups = check; } } diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/BouncyCastleJsseProvider.java b/tls/src/main/java/org/bouncycastle/jsse/provider/BouncyCastleJsseProvider.java index c439c615b8..0ac640de80 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/BouncyCastleJsseProvider.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/BouncyCastleJsseProvider.java @@ -13,6 +13,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCryptoProvider; import org.bouncycastle.util.Strings; @@ -25,10 +26,10 @@ public class BouncyCastleJsseProvider private static final String JSSE_CONFIG_PROPERTY = "org.bouncycastle.jsse.config"; - private static final double PROVIDER_VERSION = 1.0015; - private static final String PROVIDER_INFO = "Bouncy Castle JSSE Provider Version 1.0.15"; + private static final double PROVIDER_VERSION = 1.0019; + private static final String PROVIDER_INFO = "Bouncy Castle JSSE Provider Version 1.0.19"; - private final Map serviceMap = new HashMap(); + private final Map serviceMap = new ConcurrentHashMap(); private final Map creatorMap = new HashMap(); private final boolean isInFipsMode; @@ -262,11 +263,12 @@ void addAlias(String key, String value) doPut(key, value); } - public synchronized final Provider.Service getService(String type, String algorithm) + public final Provider.Service getService(String type, String algorithm) { String upperCaseAlgName = Strings.toUpperCase(algorithm); - - BcJsseService service = serviceMap.get(type + "." + upperCaseAlgName); + String serviceKey = type + "." + upperCaseAlgName; + + BcJsseService service = serviceMap.get(serviceKey); if (service == null) { @@ -285,7 +287,7 @@ public synchronized final Provider.Service getService(String type, String algori return null; } - String attributeKeyStart = type + "." + upperCaseAlgName + " "; + String attributeKeyStart = type + "." + realName + " "; List aliases = new ArrayList(); Map attributes = new HashMap(); @@ -306,9 +308,19 @@ public synchronized final Provider.Service getService(String type, String algori } } - service = new BcJsseService(this, type, upperCaseAlgName, className, aliases, getAttributeMap(attributes), creatorMap.get(className)); + synchronized (this) + { + if (!serviceMap.containsKey(serviceKey)) + { + service = new BcJsseService(this, type, upperCaseAlgName, className, aliases, getAttributeMap(attributes), creatorMap.get(className)); - serviceMap.put(type + "." + upperCaseAlgName, service); + serviceMap.put(serviceKey, service); + } + else + { + service = serviceMap.get(serviceKey); + } + } } return service; @@ -327,9 +339,9 @@ public synchronized final Set getServices() return bcServiceSet; } - private static final Map, Map > attributeMaps = new HashMap, Map>(); + private static final Map, Map> attributeMaps = new HashMap, Map>(); - private static Map getAttributeMap(Map attributeMap) + private static synchronized Map getAttributeMap(Map attributeMap) { Map attrMap = attributeMaps.get(attributeMap); if (attrMap != null) diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ContextData.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ContextData.java index 918d0bc6a1..bda556fe0c 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ContextData.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ContextData.java @@ -33,16 +33,30 @@ final class ContextData this.signatureSchemes = SignatureSchemeInfo.createPerContext(context.isFips(), crypto, namedGroups); } - NamedGroupInfo.PerConnection getNamedGroups(ProvSSLParameters sslParameters, ProtocolVersion[] activeProtocolVersions) + NamedGroupInfo.PerConnection getNamedGroupsClient(ProvSSLParameters sslParameters, + ProtocolVersion[] activeProtocolVersions) { - return NamedGroupInfo.createPerConnection(namedGroups, sslParameters, activeProtocolVersions); + return NamedGroupInfo.createPerConnectionClient(namedGroups, sslParameters, activeProtocolVersions); } - List getActiveCertsSignatureSchemes(boolean isServer, ProvSSLParameters sslParameters, + NamedGroupInfo.PerConnection getNamedGroupsServer(ProvSSLParameters sslParameters, + ProtocolVersion negotiatedVersion) + { + return NamedGroupInfo.createPerConnectionServer(namedGroups, sslParameters, negotiatedVersion); + } + + SignatureSchemeInfo.PerConnection getSignatureSchemesClient(ProvSSLParameters sslParameters, ProtocolVersion[] activeProtocolVersions, NamedGroupInfo.PerConnection namedGroups) { - return SignatureSchemeInfo.getActiveCertsSignatureSchemes(signatureSchemes, isServer, sslParameters, - activeProtocolVersions, namedGroups); + return SignatureSchemeInfo.createPerConnectionClient(signatureSchemes, sslParameters, activeProtocolVersions, + namedGroups); + } + + SignatureSchemeInfo.PerConnection getSignatureSchemesServer(ProvSSLParameters sslParameters, + ProtocolVersion negotiatedVersion, NamedGroupInfo.PerConnection namedGroups) + { + return SignatureSchemeInfo.createPerConnectionServer(signatureSchemes, sslParameters, negotiatedVersion, + namedGroups); } ProvSSLContextSpi getContext() diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ExportX509TrustManager_5.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ExportX509TrustManager_5.java index 6a626774cf..0be25c5846 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ExportX509TrustManager_5.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ExportX509TrustManager_5.java @@ -22,16 +22,16 @@ public BCX509ExtendedTrustManager unwrap() return x509TrustManager; } - public void checkClientTrusted(X509Certificate[] x509Certificates, String authType) + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - x509TrustManager.checkClientTrusted(x509Certificates, authType); + x509TrustManager.checkClientTrusted(chain, authType); } - public void checkServerTrusted(X509Certificate[] x509Certificates, String authType) + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - x509TrustManager.checkServerTrusted(x509Certificates, authType); + x509TrustManager.checkServerTrusted(chain, authType); } public X509Certificate[] getAcceptedIssuers() diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ExportX509TrustManager_7.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ExportX509TrustManager_7.java index 843403d059..4e735aacc7 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ExportX509TrustManager_7.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ExportX509TrustManager_7.java @@ -25,40 +25,44 @@ public BCX509ExtendedTrustManager unwrap() return x509TrustManager; } - public void checkClientTrusted(X509Certificate[] x509Certificates, String authType) + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - x509TrustManager.checkClientTrusted(x509Certificates, authType); + x509TrustManager.checkClientTrusted(chain, authType); } - public void checkClientTrusted(X509Certificate[] x509Certificates, String authType, Socket socket) + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { - x509TrustManager.checkClientTrusted(x509Certificates, authType, socket); + x509TrustManager.checkClientTrusted(chain, authType, socket); } - public void checkClientTrusted(X509Certificate[] x509Certificates, String authType, SSLEngine engine) + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { - x509TrustManager.checkClientTrusted(x509Certificates, authType, engine); + x509TrustManager.checkClientTrusted(chain, authType, engine); } - public void checkServerTrusted(X509Certificate[] x509Certificates, String authType) + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - x509TrustManager.checkServerTrusted(x509Certificates, authType); + x509TrustManager.checkServerTrusted(chain, authType); } - public void checkServerTrusted(X509Certificate[] x509Certificates, String authType, Socket socket) + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { - x509TrustManager.checkServerTrusted(x509Certificates, authType, socket); + x509TrustManager.checkServerTrusted(chain, authType, socket); } - public void checkServerTrusted(X509Certificate[] x509Certificates, String authType, SSLEngine engine) + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { - x509TrustManager.checkServerTrusted(x509Certificates, authType, engine); + x509TrustManager.checkServerTrusted(chain, authType, engine); } public X509Certificate[] getAcceptedIssuers() diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/FipsUtils.java b/tls/src/main/java/org/bouncycastle/jsse/provider/FipsUtils.java index 4a0628be9d..26cb817a9d 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/FipsUtils.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/FipsUtils.java @@ -18,7 +18,7 @@ abstract class FipsUtils private static final boolean provAllowGCMCiphersIn12 = false; private static final boolean provAllowRSAKeyExchange = PropertyUtils - .getBooleanSystemProperty("org.bouncycastle.jsse.fips.allowRSAKeyExchange", true); + .getBooleanSystemProperty("org.bouncycastle.jsse.fips.allowRSAKeyExchange", false); private static final Set FIPS_SUPPORTED_CIPHERSUITES = createFipsSupportedCipherSuites(); private static final Set FIPS_SUPPORTED_PROTOCOLS = createFipsSupportedProtocols(); diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ImportX509TrustManager_5.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ImportX509TrustManager_5.java index 65d3436561..468e0e1519 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ImportX509TrustManager_5.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ImportX509TrustManager_5.java @@ -44,6 +44,7 @@ public void checkClientTrusted(X509Certificate[] chain, String authType) checkAdditionalTrust(chain, authType, null, false); } + @Override public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { @@ -51,6 +52,7 @@ public void checkClientTrusted(X509Certificate[] chain, String authType, Socket checkAdditionalTrust(chain, authType, TransportData.from(socket), false); } + @Override public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { @@ -65,6 +67,7 @@ public void checkServerTrusted(X509Certificate[] chain, String authType) checkAdditionalTrust(chain, authType, null, true); } + @Override public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { @@ -72,6 +75,7 @@ public void checkServerTrusted(X509Certificate[] chain, String authType, Socket checkAdditionalTrust(chain, authType, TransportData.from(socket), true); } + @Override public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ImportX509TrustManager_7.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ImportX509TrustManager_7.java index 8d6daba417..916cb4a7c3 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ImportX509TrustManager_7.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ImportX509TrustManager_7.java @@ -32,12 +32,14 @@ public void checkClientTrusted(X509Certificate[] chain, String authType) x509TrustManager.checkClientTrusted(chain, authType); } + @Override public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { x509TrustManager.checkClientTrusted(chain, authType, socket); } + @Override public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { @@ -50,12 +52,14 @@ public void checkServerTrusted(X509Certificate[] chain, String authType) x509TrustManager.checkServerTrusted(chain, authType); } + @Override public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { x509TrustManager.checkServerTrusted(chain, authType, socket); } + @Override public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/JsseSecurityParameters.java b/tls/src/main/java/org/bouncycastle/jsse/provider/JsseSecurityParameters.java index 1f7a6509d0..e10fd4d481 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/JsseSecurityParameters.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/JsseSecurityParameters.java @@ -6,17 +6,14 @@ class JsseSecurityParameters { NamedGroupInfo.PerConnection namedGroups; - List localSigSchemes, localSigSchemesCert, peerSigSchemes, peerSigSchemesCert; + SignatureSchemeInfo.PerConnection signatureSchemes; List statusResponses; Principal[] trustedIssuers; void clear() { this.namedGroups = null; - this.localSigSchemes = null; - this.localSigSchemesCert = null; - this.peerSigSchemes = null; - this.peerSigSchemesCert = null; + this.signatureSchemes = null; this.statusResponses = null; this.trustedIssuers = null; } diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/JsseUtils.java b/tls/src/main/java/org/bouncycastle/jsse/provider/JsseUtils.java index 1b3b3523fd..5140748d91 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/JsseUtils.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/JsseUtils.java @@ -63,6 +63,7 @@ import org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCertificate; import org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto; import org.bouncycastle.tls.crypto.impl.jcajce.JceDefaultTlsCredentialedDecryptor; +import org.bouncycastle.util.encoders.Hex; abstract class JsseUtils { @@ -76,6 +77,9 @@ abstract class JsseUtils PropertyUtils.getIntegerSystemProperty("jdk.tls.maxHandshakeMessageSize", 32768, 1024, Integer.MAX_VALUE); private static final boolean provTlsRequireCloseNotify = PropertyUtils.getBooleanSystemProperty("com.sun.net.ssl.requireCloseNotify", true); + private static final boolean provTlsUseCompatibilityMode = + PropertyUtils.getBooleanSystemProperty("jdk.tls.client.useCompatibilityMode", true); + // TODO SunJSSE additionally checks KeyGenerator.getInstance("SunTlsExtendedMasterSecret") private static final boolean provTlsUseExtendedMasterSecret = PropertyUtils.getBooleanSystemProperty("jdk.tls.useExtendedMasterSecret", true); @@ -107,16 +111,62 @@ static boolean allowLegacyResumption() return provTlsAllowLegacyResumption; } - static String getSignatureAlgorithmsReport(String title, List signatureSchemes) + static void appendCipherSuiteDetail(StringBuilder sb, ProvSSLContextSpi context, int cipherSuite) { - String[] names = SignatureSchemeInfo.getJcaSignatureAlgorithmsBC(signatureSchemes); + // TODO Efficiency: precalculate "cipherSuiteID" and make context.getCipherSuiteName faster + sb.append("{0x"); // -DM Hex.toHexString + sb.append(Hex.toHexString(new byte[]{ (byte)(cipherSuite >> 8) })); + sb.append(",0x"); // -DM Hex.toHexString + sb.append(Hex.toHexString(new byte[]{ (byte)cipherSuite })); + sb.append('}'); + + String name = ProvSSLContextSpi.getCipherSuiteName(cipherSuite); + if (name == null) + { + sb.append('?'); + } + else + { + sb.append('('); + sb.append(name); + sb.append(')'); + } + } + + static String getPeerID(String root, ProvTlsManager manager) + { + long connectionID = ProvSSLConnection.allocateConnectionID(); + int transportID = manager.getTransportID(); + + return "[" + root + " #" + connectionID + " @" + Integer.toHexString(transportID) + "]"; + } + + static String getPeerReport(ProvTlsManager manager) + { + String peerHost = manager.getPeerHost(); + if (peerHost == null) + { + peerHost = "(unknown)"; + } + + int peerPort = manager.getPeerPort(); + String peerPortStr = peerPort < 0 ? "(unknown)" : Integer.toString(peerPort); + + return peerHost + ":" + peerPortStr; + } + + static String getSignatureAlgorithmsReport(String title, Iterable signatureSchemes) + { StringBuilder sb = new StringBuilder(title); sb.append(':'); - for (String name : names) + if (signatureSchemes != null) { - sb.append(' '); - sb.append(name); + for (SignatureSchemeInfo signatureScheme : signatureSchemes) + { + sb.append(' '); + sb.append(signatureScheme.getJcaSignatureAlgorithmBC()); + } } return sb.toString(); } @@ -609,9 +659,14 @@ static X500Principal getSubject(JcaTlsCrypto crypto, Certificate certificateMess } } - static String getAlertLogMessage(String root, short alertLevel, short alertDescription) + static String getAlertRaisedLogMessage(String id, short alertLevel, short alertDescription) + { + return id + " raised " + AlertLevel.getText(alertLevel) + " " + AlertDescription.getText(alertDescription) + " alert"; + } + + static String getAlertReceivedLogMessage(String id, short alertLevel, short alertDescription) { - return root + " " + AlertLevel.getText(alertLevel) + " " + AlertDescription.getText(alertDescription) + " alert"; + return id + " received " + AlertLevel.getText(alertLevel) + " " + AlertDescription.getText(alertDescription) + " alert"; } static String getKeyAlgorithm(Key key) @@ -637,10 +692,15 @@ static String getPrivateKeyAlgorithm(PrivateKey privateKey) */ if ("RSA".equalsIgnoreCase(algorithm)) { - PrivateKeyInfo pki = PrivateKeyInfo.getInstance(privateKey.getEncoded()); - if (PKCSObjectIdentifiers.id_RSASSA_PSS.equals(pki.getPrivateKeyAlgorithm().getAlgorithm())) + // NOTE: Private keys might not support encoding (e.g. for an HSM). + byte[] encoding = privateKey.getEncoded(); + if (encoding != null) { - return "RSASSA-PSS"; + PrivateKeyInfo pki = PrivateKeyInfo.getInstance(encoding); + if (PKCSObjectIdentifiers.id_RSASSA_PSS.equals(pki.getPrivateKeyAlgorithm().getAlgorithm())) + { + return "RSASSA-PSS"; + } } } @@ -866,6 +926,11 @@ private static String stripOuterChars(String s, char openChar, char closeChar) return s; } + static boolean useCompatibilityMode() + { + return provTlsUseCompatibilityMode; + } + static boolean useExtendedMasterSecret() { return provTlsUseExtendedMasterSecret; diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/NamedGroupInfo.java b/tls/src/main/java/org/bouncycastle/jsse/provider/NamedGroupInfo.java index fa259672bf..85b3024a85 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/NamedGroupInfo.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/NamedGroupInfo.java @@ -2,7 +2,6 @@ import java.security.AlgorithmParameters; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -10,6 +9,7 @@ import java.util.Set; import java.util.TreeMap; import java.util.Vector; +import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Logger; import org.bouncycastle.jsse.java.security.BCAlgorithmConstraints; @@ -20,6 +20,7 @@ import org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; +import org.bouncycastle.util.Properties; class NamedGroupInfo { @@ -73,7 +74,13 @@ private enum All ffdhe3072(NamedGroup.ffdhe3072, "DiffieHellman"), ffdhe4096(NamedGroup.ffdhe4096, "DiffieHellman"), ffdhe6144(NamedGroup.ffdhe6144, "DiffieHellman"), - ffdhe8192(NamedGroup.ffdhe8192, "DiffieHellman"); + ffdhe8192(NamedGroup.ffdhe8192, "DiffieHellman"), + + OQS_mlkem512(NamedGroup.OQS_mlkem512, "ML-KEM"), + OQS_mlkem768(NamedGroup.OQS_mlkem768, "ML-KEM"), + OQS_mlkem1024(NamedGroup.OQS_mlkem1024, "ML-KEM"), + DRAFT_mlkem768(NamedGroup.DRAFT_mlkem768, "ML-KEM"), + DRAFT_mlkem1024(NamedGroup.DRAFT_mlkem1024, "ML-KEM"); private final int namedGroup; private final String name; @@ -117,28 +124,33 @@ private All(int namedGroup, String jcaAlgorithm) static class PerConnection { - // NOTE: Should have predictable iteration order (by preference) - private final Map local; + private final LinkedHashMap local; private final boolean localECDSA; + private final AtomicReference> peer; - private List peer; - - PerConnection(Map local, boolean localECDSA) + PerConnection(LinkedHashMap local, boolean localECDSA) { + if (local == null) + { + throw new NullPointerException("local"); + } + this.local = local; this.localECDSA = localECDSA; - - this.peer = null; + this.peer = new AtomicReference>(); } - public synchronized List getPeer() + List getPeer() { - return peer; + return peer.get(); } - private synchronized void setPeer(List peer) + void notifyPeerData(int[] namedGroups) { - this.peer = peer; + // TODO[jsse] Is there any reason to preserve the unrecognized/disabled groups? + List namedGroupInfos = getNamedGroupInfos(local, namedGroups); + + peer.set(namedGroupInfos); } } @@ -154,10 +166,78 @@ static class PerContext } } - static PerConnection createPerConnection(PerContext perContext, ProvSSLParameters sslParameters, ProtocolVersion[] activeProtocolVersions) + static class DefaultedResult { - Map local = createLocal(perContext, sslParameters, activeProtocolVersions); - boolean localECDSA = createLocalECDSA(local); + private final int result; + private final boolean defaulted; + + DefaultedResult(int result, boolean defaulted) + { + this.result = result; + this.defaulted = defaulted; + } + + int getResult() + { + return result; + } + + boolean isDefaulted() + { + return defaulted; + } + } + + static PerConnection createPerConnectionClient(PerContext perContext, ProvSSLParameters sslParameters, + ProtocolVersion[] activeProtocolVersions) + { + ProtocolVersion latest = ProtocolVersion.getLatestTLS(activeProtocolVersions); + ProtocolVersion earliest = ProtocolVersion.getEarliestTLS(activeProtocolVersions); + + return createPerConnection(perContext, sslParameters, earliest, latest); + } + + static PerConnection createPerConnectionServer(PerContext perContext, ProvSSLParameters sslParameters, + ProtocolVersion negotiatedVersion) + { + return createPerConnection(perContext, sslParameters, negotiatedVersion, negotiatedVersion); + } + + private static PerConnection createPerConnection(PerContext perContext, ProvSSLParameters sslParameters, + ProtocolVersion earliest, ProtocolVersion latest) + { + String[] namedGroups = sslParameters.getNamedGroups(); + + int[] candidates; + if (namedGroups == null) + { + candidates = perContext.candidates; + } + else + { + candidates = createCandidates(perContext.index, namedGroups, "SSLParameters.namedGroups"); + } + + BCAlgorithmConstraints algorithmConstraints = sslParameters.getAlgorithmConstraints(); + boolean post13Active = TlsUtils.isTLSv13(latest); + boolean pre13Active = !TlsUtils.isTLSv13(earliest); + + int count = candidates.length; + LinkedHashMap local = new LinkedHashMap(count); + for (int i = 0; i < count; ++i) + { + Integer candidate = Integers.valueOf(candidates[i]); + NamedGroupInfo namedGroupInfo = perContext.index.get(candidate); + + if (null != namedGroupInfo + && namedGroupInfo.isActive(algorithmConstraints, post13Active, pre13Active)) + { + // NOTE: Re-insertion doesn't affect iteration order for insertion-order LinkedHashMap + local.put(candidate, namedGroupInfo); + } + } + + boolean localECDSA = hasAnyECDSA(local); return new PerConnection(local, localECDSA); } @@ -165,29 +245,79 @@ static PerConnection createPerConnection(PerContext perContext, ProvSSLParameter static PerContext createPerContext(boolean isFipsContext, JcaTlsCrypto crypto) { Map index = createIndex(isFipsContext, crypto); - int[] candidates = createCandidates(index); + int[] candidates = createCandidatesFromProperty(index, PROPERTY_NAMED_GROUPS); return new PerContext(index, candidates); } - static int getMaximumBitsServerECDH(PerConnection perConnection) + static DefaultedResult getMaximumBitsServerECDH(PerConnection perConnection) { int maxBits = 0; - for (NamedGroupInfo namedGroupInfo : getEffectivePeer(perConnection)) + List peer = perConnection.getPeer(); + if (peer != null) + { + for (NamedGroupInfo namedGroupInfo : peer) + { + int bits = namedGroupInfo.getBitsECDH(); + if (bits > maxBits) + { + if (perConnection.local.containsKey(namedGroupInfo.getNamedGroup())) + { + maxBits = bits; + } + } + } + } + else { - maxBits = Math.max(maxBits, namedGroupInfo.getBitsECDH()); + /* + * RFC 4492 4. A client that proposes ECC cipher suites may choose not to include these + * extensions. In this case, the server is free to choose any one of the elliptic curves or point + * formats [...]. + */ + for (NamedGroupInfo namedGroupInfo : perConnection.local.values()) + { + maxBits = Math.max(maxBits, namedGroupInfo.getBitsECDH()); + } } - return maxBits; + return new DefaultedResult(maxBits, peer == null); } - static int getMaximumBitsServerFFDHE(PerConnection perConnection) + static DefaultedResult getMaximumBitsServerFFDHE(PerConnection perConnection) { int maxBits = 0; - for (NamedGroupInfo namedGroupInfo : getEffectivePeer(perConnection)) + boolean anyPeerFF = false; + List peer = perConnection.getPeer(); + if (peer != null) { - maxBits = Math.max(maxBits, namedGroupInfo.getBitsFFDHE()); + for (NamedGroupInfo namedGroupInfo : peer) + { + int namedGroup = namedGroupInfo.getNamedGroup(); + anyPeerFF |= NamedGroup.isFiniteField(namedGroup); + + int bits = namedGroupInfo.getBitsFFDHE(); + if (bits > maxBits) + { + if (perConnection.local.containsKey(namedGroup)) + { + maxBits = bits; + } + } + } } - return maxBits; + if (!anyPeerFF) + { + /* + * RFC 7919 4. If [...] the Supported Groups extension is either absent from the ClientHello + * entirely or contains no FFDHE groups (i.e., no codepoints between 256 and 511, inclusive), then + * the server [...] MAY select an FFDHE cipher suite and offer an FFDHE group of its choice [...]. + */ + for (NamedGroupInfo namedGroupInfo : perConnection.local.values()) + { + maxBits = Math.max(maxBits, namedGroupInfo.getBitsFFDHE()); + } + } + return new DefaultedResult(maxBits, !anyPeerFF); } static NamedGroupInfo getNamedGroup(PerContext perContext, int namedGroup) @@ -222,35 +352,77 @@ static boolean hasLocal(PerConnection perConnection, int namedGroup) return perConnection.local.containsKey(namedGroup); } - static void notifyPeer(PerConnection perConnection, int[] peerNamedGroups) - { - List peer = createPeer(perConnection, peerNamedGroups); - - perConnection.setPeer(peer); - } - - static int selectServerECDH(PerConnection perConnection, int minimumBitsECDH) + static DefaultedResult selectServerECDH(PerConnection perConnection, int minimumBitsECDH) { - for (NamedGroupInfo namedGroupInfo : getEffectivePeer(perConnection)) + List peer = perConnection.getPeer(); + if (peer != null) { - if (namedGroupInfo.getBitsECDH() >= minimumBitsECDH) + for (NamedGroupInfo namedGroupInfo : peer) { - return namedGroupInfo.getNamedGroup(); + if (namedGroupInfo.getBitsECDH() >= minimumBitsECDH) + { + int namedGroup = namedGroupInfo.getNamedGroup(); + if (perConnection.local.containsKey(namedGroup)) + { + return new DefaultedResult(namedGroup, false); + } + } } } - return -1; + else + { + /* + * RFC 4492 4. A client that proposes ECC cipher suites may choose not to include these + * extensions. In this case, the server is free to choose any one of the elliptic curves or point + * formats [...]. + */ + for (NamedGroupInfo namedGroupInfo : perConnection.local.values()) + { + if (namedGroupInfo.getBitsECDH() >= minimumBitsECDH) + { + return new DefaultedResult(namedGroupInfo.getNamedGroup(), true); + } + } + } + return new DefaultedResult(-1, peer == null); } - static int selectServerFFDHE(PerConnection perConnection, int minimumBitsFFDHE) + static DefaultedResult selectServerFFDHE(PerConnection perConnection, int minimumBitsFFDHE) { - for (NamedGroupInfo namedGroupInfo : getEffectivePeer(perConnection)) + boolean anyPeerFF = false; + List peer = perConnection.getPeer(); + if (peer != null) { - if (namedGroupInfo.getBitsFFDHE() >= minimumBitsFFDHE) + for (NamedGroupInfo namedGroupInfo : peer) { - return namedGroupInfo.getNamedGroup(); + int namedGroup = namedGroupInfo.getNamedGroup(); + anyPeerFF |= NamedGroup.isFiniteField(namedGroup); + + if (namedGroupInfo.getBitsFFDHE() >= minimumBitsFFDHE) + { + if (perConnection.local.containsKey(namedGroup)) + { + return new DefaultedResult(namedGroup, false); + } + } } } - return -1; + if (!anyPeerFF) + { + /* + * RFC 7919 4. If [...] the Supported Groups extension is either absent from the ClientHello + * entirely or contains no FFDHE groups (i.e., no codepoints between 256 and 511, inclusive), then + * the server [...] MAY select an FFDHE cipher suite and offer an FFDHE group of its choice [...]. + */ + for (NamedGroupInfo namedGroupInfo : perConnection.local.values()) + { + if (namedGroupInfo.getBitsFFDHE() >= minimumBitsFFDHE) + { + return new DefaultedResult(namedGroupInfo.getNamedGroup(), true); + } + } + } + return new DefaultedResult(-1, !anyPeerFF); } private static void addNamedGroup(boolean isFipsContext, JcaTlsCrypto crypto, boolean disableChar2, @@ -290,14 +462,19 @@ private static void addNamedGroup(boolean isFipsContext, JcaTlsCrypto crypto, bo } } - private static int[] createCandidates(Map index) + private static int[] createCandidatesFromProperty(Map index, String propertyName) { - String[] names = PropertyUtils.getStringArraySystemProperty(PROPERTY_NAMED_GROUPS); + String[] names = PropertyUtils.getStringArraySystemProperty(propertyName); if (null == names) { return CANDIDATES_DEFAULT; } + return createCandidates(index, names, propertyName); + } + + private static int[] createCandidates(Map index, String[] names, String description) + { int[] result = new int[names.length]; int count = 0; for (String name : names) @@ -305,20 +482,20 @@ private static int[] createCandidates(Map index) int namedGroup = getNamedGroupByName(name); if (namedGroup < 0) { - LOG.warning("'" + PROPERTY_NAMED_GROUPS + "' contains unrecognised NamedGroup: " + name); + LOG.warning("'" + description + "' contains unrecognised NamedGroup: " + name); continue; } NamedGroupInfo namedGroupInfo = index.get(namedGroup); if (null == namedGroupInfo) { - LOG.warning("'" + PROPERTY_NAMED_GROUPS + "' contains unsupported NamedGroup: " + name); + LOG.warning("'" + description + "' contains unsupported NamedGroup: " + name); continue; } if (!namedGroupInfo.isEnabled()) { - LOG.warning("'" + PROPERTY_NAMED_GROUPS + "' contains disabled NamedGroup: " + name); + LOG.warning("'" + description + "' contains disabled NamedGroup: " + name); continue; } @@ -330,7 +507,7 @@ private static int[] createCandidates(Map index) } if (result.length < 1) { - LOG.severe("'" + PROPERTY_NAMED_GROUPS + "' contained no usable NamedGroup values"); + LOG.severe("'" + description + "' contained no usable NamedGroup values"); } return result; } @@ -339,8 +516,9 @@ private static Map createIndex(boolean isFipsContext, J { Map ng = new TreeMap(); - final boolean disableChar2 = PropertyUtils.getBooleanSystemProperty("org.bouncycastle.jsse.ec.disableChar2", false) - || PropertyUtils.getBooleanSystemProperty("org.bouncycastle.ec.disable_f2m", false); + final boolean disableChar2 = + PropertyUtils.getBooleanSystemProperty("org.bouncycastle.jsse.ec.disableChar2", false) || + Properties.isOverrideSet("org.bouncycastle.ec.disable_f2m"); final boolean disableFFDHE = !PropertyUtils.getBooleanSystemProperty("jsse.enableFFDHE", true); @@ -352,63 +530,6 @@ private static Map createIndex(boolean isFipsContext, J return ng; } - private static Map createLocal(PerContext perContext, - ProvSSLParameters sslParameters, ProtocolVersion[] activeProtocolVersions) - { - ProtocolVersion latest = ProtocolVersion.getLatestTLS(activeProtocolVersions); - ProtocolVersion earliest = ProtocolVersion.getEarliestTLS(activeProtocolVersions); - - BCAlgorithmConstraints algorithmConstraints = sslParameters.getAlgorithmConstraints(); - boolean post13Active = TlsUtils.isTLSv13(latest); - boolean pre13Active = !TlsUtils.isTLSv13(earliest); - - int count = perContext.candidates.length; - LinkedHashMap result = new LinkedHashMap(count); - for (int i = 0; i < count; ++i) - { - Integer candidate = Integers.valueOf(perContext.candidates[i]); - NamedGroupInfo namedGroupInfo = perContext.index.get(candidate); - - if (null != namedGroupInfo - && namedGroupInfo.isActive(algorithmConstraints, post13Active, pre13Active)) - { - // NOTE: Re-insertion doesn't affect iteration order for insertion-order LinkedHashMap - result.put(candidate, namedGroupInfo); - } - } - return result; - } - - private static boolean createLocalECDSA(Map local) - { - for (NamedGroupInfo namedGroupInfo : local.values()) - { - if (NamedGroup.refersToAnECDSACurve(namedGroupInfo.getNamedGroup())) - { - return true; - } - } - return false; - } - - private static List createPeer(PerConnection perConnection, int[] peerNamedGroups) - { - // TODO[jsse] Is there any reason to preserve the unrecognized/disabled groups? - - return getNamedGroupInfos(perConnection.local, peerNamedGroups); - } - - private static Collection getEffectivePeer(PerConnection perConnection) - { - List peer = perConnection.getPeer(); - if (!peer.isEmpty()) - { - return peer; - } - - return perConnection.local.values(); - } - private static int getNamedGroupByName(String name) { for (All all : All.values()) @@ -422,9 +543,14 @@ private static int getNamedGroupByName(String name) return -1; } - private static List getNamedGroupInfos(Map namedGroupInfos, int[] namedGroups) + private static List getNamedGroupInfos(Map namedGroupInfos, + int[] namedGroups) { - if (TlsUtils.isNullOrEmpty(namedGroups)) + if (namedGroups == null) + { + return null; + } + if (namedGroups.length < 1) { return Collections.emptyList(); } @@ -449,6 +575,18 @@ private static List getNamedGroupInfos(Map local) + { + for (NamedGroupInfo namedGroupInfo : local.values()) + { + if (NamedGroup.refersToAnECDSACurve(namedGroupInfo.getNamedGroup())) + { + return true; + } + } + return false; + } + private final All all; private final AlgorithmParameters algorithmParameters; private final boolean enabled; diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/PropertyUtils.java b/tls/src/main/java/org/bouncycastle/jsse/provider/PropertyUtils.java index fce1f4e7da..bc258f9eba 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/PropertyUtils.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/PropertyUtils.java @@ -47,17 +47,17 @@ static boolean getBooleanSecurityProperty(String propertyName, boolean defaultVa { if ("true".equalsIgnoreCase(propertyValue)) { - LOG.log(Level.INFO, "Found boolean security property [" + propertyName + "]: " + true); + LOG.info("Found boolean security property [" + propertyName + "]: " + true); return true; } if ("false".equalsIgnoreCase(propertyValue)) { - LOG.log(Level.INFO, "Found boolean security property [" + propertyName + "]: " + false); + LOG.info("Found boolean security property [" + propertyName + "]: " + false); return false; } - LOG.log(Level.WARNING, "Unrecognized value for boolean security property [" + propertyName + "]: " + propertyValue); + LOG.warning("Unrecognized value for boolean security property [" + propertyName + "]: " + propertyValue); } - LOG.log(Level.FINE, "Boolean security property [" + propertyName + "] defaulted to: " + defaultValue); + LOG.fine("Boolean security property [" + propertyName + "] defaulted to: " + defaultValue); return defaultValue; } @@ -68,17 +68,17 @@ static boolean getBooleanSystemProperty(String propertyName, boolean defaultValu { if ("true".equalsIgnoreCase(propertyValue)) { - LOG.log(Level.INFO, "Found boolean system property [" + propertyName + "]: " + true); + LOG.info("Found boolean system property [" + propertyName + "]: " + true); return true; } if ("false".equalsIgnoreCase(propertyValue)) { - LOG.log(Level.INFO, "Found boolean system property [" + propertyName + "]: " + false); + LOG.info("Found boolean system property [" + propertyName + "]: " + false); return false; } - LOG.log(Level.WARNING, "Unrecognized value for boolean system property [" + propertyName + "]: " + propertyValue); + LOG.warning("Unrecognized value for boolean system property [" + propertyName + "]: " + propertyValue); } - LOG.log(Level.FINE, "Boolean system property [" + propertyName + "] defaulted to: " + defaultValue); + LOG.fine("Boolean system property [" + propertyName + "] defaulted to: " + defaultValue); return defaultValue; } @@ -92,21 +92,21 @@ static int getIntegerSystemProperty(String propertyName, int defaultValue, int m int parsedValue = Integer.parseInt(propertyValue); if (parsedValue >= minimumValue && parsedValue <= maximumValue) { - LOG.log(Level. INFO, "Found integer system property [" + propertyName + "]: " + parsedValue); + LOG.info("Found integer system property [" + propertyName + "]: " + parsedValue); return parsedValue; } if (LOG.isLoggable(Level.WARNING)) { String range = getRangeString(minimumValue, maximumValue); - LOG.log(Level.WARNING, "Out-of-range (" + range + ") integer system property [" + propertyName + "]: " + propertyValue); + LOG.warning("Out-of-range (" + range + ") integer system property [" + propertyName + "]: " + propertyValue); } } catch (Exception e) { - LOG.log(Level.WARNING, "Unrecognized value for integer system property [" + propertyName + "]: " + propertyValue); + LOG.warning("Unrecognized value for integer system property [" + propertyName + "]: " + propertyValue); } } - LOG.log(Level.FINE, "Integer system property [" + propertyName + "] defaulted to: " + defaultValue); + LOG.fine("Integer system property [" + propertyName + "] defaulted to: " + defaultValue); return defaultValue; } @@ -126,7 +126,7 @@ static String getStringSecurityProperty(String propertyName) String propertyValue = getSecurityProperty(propertyName); if (null != propertyValue) { - LOG.log(Level.INFO, "Found string security property [" + propertyName + "]: " + propertyValue); + LOG.info("Found string security property [" + propertyName + "]: " + propertyValue); return propertyValue; } return null; @@ -137,10 +137,10 @@ static String getStringSecurityProperty(String propertyName, String defaultValue String propertyValue = getSecurityProperty(propertyName); if (null != propertyValue) { - LOG.log(Level.INFO, "Found string security property [" + propertyName + "]: " + propertyValue); + LOG.info("Found string security property [" + propertyName + "]: " + propertyValue); return propertyValue; } - LOG.log(Level.WARNING, "String security property [" + propertyName + "] defaulted to: " + defaultValue); + LOG.warning("String security property [" + propertyName + "] defaulted to: " + defaultValue); return defaultValue; } @@ -149,7 +149,7 @@ static String getStringSystemProperty(String propertyName) String propertyValue = getSystemProperty(propertyName); if (null != propertyValue) { - LOG.log(Level.INFO, "Found string system property [" + propertyName + "]: " + propertyValue); + LOG.info("Found string system property [" + propertyName + "]: " + propertyValue); return propertyValue; } return null; diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvAlgorithmConstraints.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvAlgorithmConstraints.java index d532676f21..7a9cb10664 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvAlgorithmConstraints.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvAlgorithmConstraints.java @@ -23,9 +23,11 @@ class ProvAlgorithmConstraints private static final String PROPERTY_TLS_DISABLED_ALGORITHMS = "jdk.tls.disabledAlgorithms"; private static final String DEFAULT_CERTPATH_DISABLED_ALGORITHMS = - "MD2, MD5, SHA1 jdkCA & usage TLSServer, RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224"; + "MD2, MD5, SHA1 jdkCA & usage TLSServer, RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224, " + + "SHA1 usage SignedJAR & denyAfter 2019-01-01"; private static final String DEFAULT_TLS_DISABLED_ALGORITHMS = - "SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL"; + "SSLv3, TLSv1, TLSv1.1, DTLSv1.0, RC4, DES, MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, " + + "anon, NULL, ECDH"; private static final DisabledAlgorithmConstraints provTlsDisabledAlgorithms = DisabledAlgorithmConstraints.create( ProvAlgorithmDecomposer.INSTANCE_TLS, PROPERTY_TLS_DISABLED_ALGORITHMS, DEFAULT_TLS_DISABLED_ALGORITHMS); private static final DisabledAlgorithmConstraints provX509DisabledAlgorithms = DisabledAlgorithmConstraints.create( diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLConnection.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLConnection.java index 65f73175ae..9ff9d52fb8 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLConnection.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLConnection.java @@ -1,5 +1,7 @@ package org.bouncycastle.jsse.provider; +import java.util.concurrent.atomic.AtomicLong; + import org.bouncycastle.jsse.BCSSLConnection; import org.bouncycastle.tls.ChannelBinding; import org.bouncycastle.tls.TlsContext; @@ -7,47 +9,62 @@ class ProvSSLConnection implements BCSSLConnection { - protected final TlsContext tlsContext; - protected final ProvSSLSession session; + private static final AtomicLong CONNECTION_IDS = new AtomicLong(0L); + + static long allocateConnectionID() + { + return CONNECTION_IDS.incrementAndGet(); + } + + protected final ProvTlsPeer tlsPeer; - ProvSSLConnection(TlsContext tlsContext, ProvSSLSession session) + ProvSSLConnection(ProvTlsPeer tlsPeer) { - this.tlsContext = tlsContext; - this.session = session; + this.tlsPeer = tlsPeer; } public byte[] exportKeyingMaterial(String asciiLabel, byte[] context_value, int length) { - return tlsContext.exportKeyingMaterial(asciiLabel, context_value, length); + return getTlsContext().exportKeyingMaterial(asciiLabel, context_value, length); } public String getApplicationProtocol() { - return JsseUtils.getApplicationProtocol(tlsContext.getSecurityParametersConnection()); + return JsseUtils.getApplicationProtocol(getTlsContext().getSecurityParametersConnection()); } public byte[] getChannelBinding(String channelBinding) { if (channelBinding.equals("tls-exporter")) { - return tlsContext.exportChannelBinding(ChannelBinding.tls_exporter); + return getTlsContext().exportChannelBinding(ChannelBinding.tls_exporter); } if (channelBinding.equals("tls-server-end-point")) { - return tlsContext.exportChannelBinding(ChannelBinding.tls_server_end_point); + return getTlsContext().exportChannelBinding(ChannelBinding.tls_server_end_point); } if (channelBinding.equals("tls-unique")) { - return tlsContext.exportChannelBinding(ChannelBinding.tls_unique); + return getTlsContext().exportChannelBinding(ChannelBinding.tls_unique); } throw new UnsupportedOperationException(); } + public String getID() + { + return tlsPeer.getID(); + } + public ProvSSLSession getSession() { - return session; + return tlsPeer.getSession(); + } + + protected TlsContext getTlsContext() + { + return tlsPeer.getTlsContext(); } } diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLContextSpi.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLContextSpi.java index 260ba5c921..923e68afa4 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLContextSpi.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLContextSpi.java @@ -135,15 +135,6 @@ private static List createDefaultCipherSuiteList(Set supportedCi cs.add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA"); cs.add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA"); - // Deprecated (not forward secret) - - cs.add("TLS_RSA_WITH_AES_256_GCM_SHA384"); - cs.add("TLS_RSA_WITH_AES_128_GCM_SHA256"); - cs.add("TLS_RSA_WITH_AES_256_CBC_SHA256"); - cs.add("TLS_RSA_WITH_AES_128_CBC_SHA256"); - cs.add("TLS_RSA_WITH_AES_256_CBC_SHA"); - cs.add("TLS_RSA_WITH_AES_128_CBC_SHA"); - cs.retainAll(supportedCipherSuiteSet); cs.trimToSize(); return Collections.unmodifiableList(cs); @@ -522,6 +513,11 @@ static String getCipherSuiteName(int cipherSuite) { return "SSL_NULL_WITH_NULL_NULL"; } + // TODO[jsse] Place into "understood" cipher suite map + if (CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV == cipherSuite) + { + return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; + } if (TlsUtils.isValidUint16(cipherSuite)) { // TODO[jsse] Add CipherSuiteInfo index by 'int' diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLEngine.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLEngine.java index 68067c7280..d01ea87007 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLEngine.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLEngine.java @@ -66,9 +66,9 @@ protected ProvSSLEngine(ContextData contextData) this(contextData, null, -1); } - protected ProvSSLEngine(ContextData contextData, String host, int port) + protected ProvSSLEngine(ContextData contextData, String peerHost, int peerPort) { - super(host, port); + super(peerHost, peerPort); this.contextData = contextData; this.sslParameters = contextData.getContext().getDefaultSSLParameters(useClientMode); @@ -328,6 +328,11 @@ public synchronized String[] getSupportedProtocols() return contextData.getContext().getSupportedProtocols(); } + public int getTransportID() + { + return System.identityHashCode(this); + } + @Override public synchronized boolean getUseClientMode() { @@ -729,7 +734,7 @@ private RecordPreview getRecordPreview(ByteBuffer src) int position = src.position(); src.get(recordHeader); - src.position(position); + ((java.nio.Buffer)src).position(position); return protocol.previewInputRecord(recordHeader); } diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLEngine_8.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLEngine_8.java index ef842624aa..b3cfd477a1 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLEngine_8.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLEngine_8.java @@ -13,9 +13,9 @@ protected ProvSSLEngine_8(ContextData contextData) super(contextData); } - protected ProvSSLEngine_8(ContextData contextData, String host, int port) + protected ProvSSLEngine_8(ContextData contextData, String peerHost, int peerPort) { - super(contextData, host, port); + super(contextData, peerHost, peerPort); } // An SSLEngine method from JDK 9 (and then 8u251) diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLParameters.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLParameters.java index 8ca6a883b4..184645ac1d 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLParameters.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLParameters.java @@ -33,15 +33,20 @@ private static List copyList(Collection list) private String[] cipherSuites; private String[] protocols; - private boolean needClientAuth = false; private boolean wantClientAuth = false; - private BCAlgorithmConstraints algorithmConstraints = ProvAlgorithmConstraints.DEFAULT; + private boolean needClientAuth = false; private String endpointIdentificationAlgorithm; + private BCAlgorithmConstraints algorithmConstraints = ProvAlgorithmConstraints.DEFAULT; + private List sniServerNames; + private List sniMatchers; private boolean useCipherSuitesOrder = true; + private boolean enableRetransmissions = true; private int maximumPacketSize = 0; - private List sniMatchers; - private List sniServerNames; private String[] applicationProtocols = TlsUtils.EMPTY_STRINGS; + private String[] signatureSchemes = null; + private String[] signatureSchemesCert = null; + private String[] namedGroups = null; + private BCApplicationProtocolSelector engineAPSelector; private BCApplicationProtocolSelector socketAPSelector; private ProvSSLSession sessionToResume; @@ -57,14 +62,19 @@ private static List copyList(Collection list) ProvSSLParameters copy() { ProvSSLParameters p = new ProvSSLParameters(context, cipherSuites, protocols); - p.needClientAuth = needClientAuth; p.wantClientAuth = wantClientAuth; - p.algorithmConstraints = algorithmConstraints; + p.needClientAuth = needClientAuth; p.endpointIdentificationAlgorithm = endpointIdentificationAlgorithm; - p.useCipherSuitesOrder = useCipherSuitesOrder; - p.sniMatchers = sniMatchers; + p.algorithmConstraints = algorithmConstraints; p.sniServerNames = sniServerNames; + p.sniMatchers = sniMatchers; + p.useCipherSuitesOrder = useCipherSuitesOrder; + p.enableRetransmissions = enableRetransmissions; + p.maximumPacketSize = maximumPacketSize; p.applicationProtocols = applicationProtocols; + p.signatureSchemes = signatureSchemes; + p.signatureSchemesCert = signatureSchemesCert; + p.namedGroups = namedGroups; p.engineAPSelector = engineAPSelector; p.socketAPSelector = socketAPSelector; p.sessionToResume = sessionToResume; @@ -132,6 +142,17 @@ void setProtocolsArray(String[] protocols) this.protocols = protocols; } + public boolean getWantClientAuth() + { + return wantClientAuth; + } + + public void setWantClientAuth(boolean wantClientAuth) + { + this.needClientAuth = false; + this.wantClientAuth = wantClientAuth; + } + public boolean getNeedClientAuth() { return needClientAuth; @@ -143,15 +164,14 @@ public void setNeedClientAuth(boolean needClientAuth) this.wantClientAuth = false; } - public boolean getWantClientAuth() + public String getEndpointIdentificationAlgorithm() { - return wantClientAuth; + return endpointIdentificationAlgorithm; } - public void setWantClientAuth(boolean wantClientAuth) + public void setEndpointIdentificationAlgorithm(String endpointIdentificationAlgorithm) { - this.needClientAuth = false; - this.wantClientAuth = wantClientAuth; + this.endpointIdentificationAlgorithm = endpointIdentificationAlgorithm; } public BCAlgorithmConstraints getAlgorithmConstraints() @@ -164,14 +184,24 @@ public void setAlgorithmConstraints(BCAlgorithmConstraints algorithmConstraints) this.algorithmConstraints = algorithmConstraints; } - public String getEndpointIdentificationAlgorithm() + public List getServerNames() { - return endpointIdentificationAlgorithm; + return copyList(sniServerNames); } - public void setEndpointIdentificationAlgorithm(String endpointIdentificationAlgorithm) + public void setServerNames(List serverNames) { - this.endpointIdentificationAlgorithm = endpointIdentificationAlgorithm; + this.sniServerNames = copyList(serverNames); + } + + public Collection getSNIMatchers() + { + return copyList(sniMatchers); + } + + public void setSNIMatchers(Collection matchers) + { + this.sniMatchers = copyList(matchers); } public boolean getUseCipherSuitesOrder() @@ -184,6 +214,16 @@ public void setUseCipherSuitesOrder(boolean useCipherSuitesOrder) this.useCipherSuitesOrder = useCipherSuitesOrder; } + public boolean getEnableRetransmissions() + { + return enableRetransmissions; + } + + public void setEnableRetransmissions(boolean enableRetransmissions) + { + this.enableRetransmissions = enableRetransmissions; + } + public int getMaximumPacketSize() { return maximumPacketSize; @@ -199,36 +239,46 @@ public void setMaximumPacketSize(int maximumPacketSize) this.maximumPacketSize = maximumPacketSize; } - public List getServerNames() + public String[] getApplicationProtocols() { - return copyList(sniServerNames); + return applicationProtocols.clone(); } - public void setServerNames(List serverNames) + public void setApplicationProtocols(String[] applicationProtocols) { - this.sniServerNames = copyList(serverNames); + this.applicationProtocols = applicationProtocols.clone(); } - public Collection getSNIMatchers() + public String[] getSignatureSchemes() { - return copyList(sniMatchers); + return TlsUtils.clone(signatureSchemes); } - public void setSNIMatchers(Collection matchers) + public void setSignatureSchemes(String[] signatureSchemes) { - this.sniMatchers = copyList(matchers); + this.signatureSchemes = TlsUtils.clone(signatureSchemes); } - public String[] getApplicationProtocols() + public String[] getSignatureSchemesCert() { - return applicationProtocols.clone(); + return TlsUtils.clone(signatureSchemesCert); } - public void setApplicationProtocols(String[] applicationProtocols) + public void setSignatureSchemesCert(String[] signatureSchemesCert) { - this.applicationProtocols = applicationProtocols.clone(); + this.signatureSchemesCert = TlsUtils.clone(signatureSchemesCert); } - + + public String[] getNamedGroups() + { + return TlsUtils.clone(namedGroups); + } + + public void setNamedGroups(String[] namedGroups) + { + this.namedGroups = TlsUtils.clone(namedGroups); + } + public BCApplicationProtocolSelector getEngineAPSelector() { return engineAPSelector; diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSessionHandshake.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSessionHandshake.java index 08f21bc967..6e708de145 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSessionHandshake.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSessionHandshake.java @@ -63,13 +63,13 @@ protected org.bouncycastle.tls.Certificate getLocalCertificateTLS() @Override public String[] getLocalSupportedSignatureAlgorithms() { - return SignatureSchemeInfo.getJcaSignatureAlgorithms(jsseSecurityParameters.localSigSchemesCert); + return jsseSecurityParameters.signatureSchemes.getLocalJcaSignatureAlgorithms(); } @Override public String[] getLocalSupportedSignatureAlgorithmsBC() { - return SignatureSchemeInfo.getJcaSignatureAlgorithmsBC(jsseSecurityParameters.localSigSchemesCert); + return jsseSecurityParameters.signatureSchemes.getLocalJcaSignatureAlgorithmsBC(); } @Override @@ -81,13 +81,13 @@ protected org.bouncycastle.tls.Certificate getPeerCertificateTLS() @Override public String[] getPeerSupportedSignatureAlgorithms() { - return SignatureSchemeInfo.getJcaSignatureAlgorithms(jsseSecurityParameters.peerSigSchemesCert); + return jsseSecurityParameters.signatureSchemes.getPeerJcaSignatureAlgorithms(); } @Override public String[] getPeerSupportedSignatureAlgorithmsBC() { - return SignatureSchemeInfo.getJcaSignatureAlgorithmsBC(jsseSecurityParameters.peerSigSchemesCert); + return jsseSecurityParameters.signatureSchemes.getPeerJcaSignatureAlgorithmsBC(); } @Override diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSocketDirect.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSocketDirect.java index 3d93079b1e..245b1eb461 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSocketDirect.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSocketDirect.java @@ -172,30 +172,6 @@ public void connect(SocketAddress endpoint, int timeout) throws IOException notifyConnected(); } - @Override - protected void finalize() throws Throwable - { - try - { - close(); - } - catch (IOException e1) - { - try - { - super.close(); - } - catch (IOException e2) - { - // Ignore - } - } - finally - { - super.finalize(); - } - } - // An SSLSocket method from JDK 9 (and then 8u251), but also a BCSSLSocket method public synchronized String getApplicationProtocol() { @@ -308,6 +284,11 @@ public synchronized String[] getSupportedProtocols() return contextData.getContext().getSupportedProtocols(); } + public int getTransportID() + { + return System.identityHashCode(this); + } + @Override public synchronized boolean getUseClientMode() { @@ -364,7 +345,6 @@ public synchronized void setEnableSessionCreation(boolean flag) public synchronized void setHost(String host) { this.peerHost = host; - this.peerHostSNI = host; } @Override @@ -550,6 +530,7 @@ synchronized void notifyConnected() InetAddress peerAddress = getInetAddress(); if (null == peerAddress) { + this.peerHostSNI = null; return; } @@ -557,8 +538,8 @@ synchronized void notifyConnected() * TODO[jsse] If we could somehow access the 'originalHostName' of peerAddress, it would be * usable as a default SNI host_name. */ -// String originalHostName = null; -// if (null != originalHostName) +// String originalHostName = peerAddress.holder().getOriginalHostName(); +// if (JsseUtils.isNameSpecified(originalHostName)) // { // this.peerHost = originalHostName; // this.peerHostSNI = originalHostName; @@ -574,13 +555,17 @@ synchronized void notifyConnected() return; } - if (useClientMode && provJdkTlsTrustNameService) + if (!useClientMode) + { + this.peerHost = peerAddress.getHostAddress(); + } + else if (provJdkTlsTrustNameService) { this.peerHost = peerAddress.getHostName(); } else { - this.peerHost = peerAddress.getHostAddress(); + this.peerHost = null; } this.peerHostSNI = null; diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSocketFactory.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSocketFactory.java index 5519dc20ee..292a2fc7d1 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSocketFactory.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSocketFactory.java @@ -52,7 +52,7 @@ public Socket createSocket(String host, int port, InetAddress localHost, int loc return SSLSocketUtil.create(contextData, host, port, localHost, localPort); } - @Override + // No @Override for 1.8 method public Socket createSocket(Socket s, InputStream consumed, boolean autoClose) throws IOException { return SSLSocketUtil.create(contextData, s, consumed, autoClose); diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSocketWrap.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSocketWrap.java index 2170a0b940..59fabd7bb4 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSocketWrap.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSocketWrap.java @@ -177,23 +177,6 @@ public void connect(SocketAddress endpoint, int timeout) throws IOException throw new SocketException("Wrapped socket should already be connected"); } - @Override - protected void finalize() throws Throwable - { - try - { - close(); - } - catch (IOException e) - { - // Ignore - } - finally - { - super.finalize(); - } - } - // An SSLSocket method from JDK 9 (and then 8u251), but also a BCSSLSocket method public synchronized String getApplicationProtocol() { @@ -396,6 +379,11 @@ public int getTrafficClass() throws SocketException return wrapSocket.getTrafficClass(); } + public int getTransportID() + { + return System.identityHashCode(this); + } + @Override public synchronized boolean getUseClientMode() { @@ -482,7 +470,6 @@ public synchronized void setEnableSessionCreation(boolean flag) public synchronized void setHost(String host) { this.peerHost = host; - this.peerHostSNI = host; } @Override @@ -732,6 +719,7 @@ synchronized void notifyConnected() InetAddress peerAddress = getInetAddress(); if (null == peerAddress) { + this.peerHostSNI = null; return; } @@ -739,8 +727,8 @@ synchronized void notifyConnected() * TODO[jsse] If we could somehow access the 'originalHostName' of peerAddress, it would be * usable as a default SNI host_name. */ -// String originalHostName = null; -// if (null != originalHostName) +// String originalHostName = peerAddress.holder().getOriginalHostName(); +// if (JsseUtils.isNameSpecified(originalHostName)) // { // this.peerHost = originalHostName; // this.peerHostSNI = originalHostName; @@ -756,13 +744,17 @@ synchronized void notifyConnected() return; } - if (useClientMode && provJdkTlsTrustNameService) + if (!useClientMode) + { + this.peerHost = peerAddress.getHostAddress(); + } + else if (provJdkTlsTrustNameService) { this.peerHost = peerAddress.getHostName(); } else { - this.peerHost = peerAddress.getHostAddress(); + this.peerHost = null; } this.peerHostSNI = null; diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsClient.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsClient.java index 92d34a7ef8..eb5d60eb4f 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsClient.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsClient.java @@ -16,6 +16,7 @@ import org.bouncycastle.jsse.BCSNIHostName; import org.bouncycastle.jsse.BCSNIServerName; import org.bouncycastle.jsse.BCX509Key; +import org.bouncycastle.jsse.provider.SignatureSchemeInfo.PerConnection; import org.bouncycastle.tls.AlertDescription; import org.bouncycastle.tls.AlertLevel; import org.bouncycastle.tls.CertificateRequest; @@ -33,6 +34,7 @@ import org.bouncycastle.tls.SignatureAlgorithm; import org.bouncycastle.tls.SignatureAndHashAlgorithm; import org.bouncycastle.tls.TlsAuthentication; +import org.bouncycastle.tls.TlsContext; import org.bouncycastle.tls.TlsCredentials; import org.bouncycastle.tls.TlsDHGroupVerifier; import org.bouncycastle.tls.TlsExtensionsUtils; @@ -64,9 +66,13 @@ class ProvTlsClient private static final boolean provClientEnableTrustedCAKeys = PropertyUtils .getBooleanSystemProperty("org.bouncycastle.jsse.client.enableTrustedCAKeysExtension", false); + private static final boolean provClientOmitSigAlgsCert = PropertyUtils + .getBooleanSystemProperty("org.bouncycastle.jsse.client.omitSigAlgsCertExtension", true); + private static final boolean provEnableSNIExtension = PropertyUtils .getBooleanSystemProperty("jsse.enableSNIExtension", true); + protected final String clientID; protected final ProvTlsManager manager; protected final ProvSSLParameters sslParameters; protected final JsseSecurityParameters jsseSecurityParameters = new JsseSecurityParameters(); @@ -78,10 +84,26 @@ class ProvTlsClient { super(manager.getContextData().getCrypto()); + this.clientID = JsseUtils.getPeerID("client", manager); this.manager = manager; this.sslParameters = sslParameters.copyForConnection(); } + public String getID() + { + return clientID; + } + + public ProvSSLSession getSession() + { + return sslSession; + } + + public TlsContext getTlsContext() + { + return context; + } + @Override protected Vector getCertificateAuthorities() { @@ -166,7 +188,7 @@ protected Vector getSNIServerNames() } catch (RuntimeException e) { - LOG.fine("Failed to add peer host as default SNI host_name: " + peerHostSNI); + LOG.fine(clientID + ": Failed to add peer host as default SNI host_name: " + peerHostSNI); } } } @@ -195,27 +217,21 @@ protected int[] getSupportedCipherSuites() @Override protected Vector getSupportedSignatureAlgorithms() { - ContextData contextData = manager.getContextData(); - ProtocolVersion[] activeProtocolVersions = getProtocolVersions(); - - List signatureSchemes = contextData.getActiveCertsSignatureSchemes(false, sslParameters, - activeProtocolVersions, jsseSecurityParameters.namedGroups); - - jsseSecurityParameters.localSigSchemes = signatureSchemes; - jsseSecurityParameters.localSigSchemesCert = signatureSchemes; - - return SignatureSchemeInfo.getSignatureAndHashAlgorithms(jsseSecurityParameters.localSigSchemes); + return jsseSecurityParameters.signatureSchemes.getLocalSignatureAndHashAlgorithms(); } @Override protected Vector getSupportedSignatureAlgorithmsCert() { -// if (jsseSecurityParameters.localSigSchemes != jsseSecurityParameters.localSigSchemesCert) -// { -// return SignatureSchemeInfo.getSignatureAndHashAlgorithms(jsseSecurityParameters.localSigSchemesCert); -// } + Vector result = jsseSecurityParameters.signatureSchemes + .getLocalSignatureAndHashAlgorithmsCert(); - return null; + if (result == null && !provClientOmitSigAlgsCert) + { + result = jsseSecurityParameters.signatureSchemes.getLocalSignatureAndHashAlgorithms(); + } + + return result; } @Override @@ -288,20 +304,26 @@ public TlsCredentials getClientCredentials(CertificateRequest certificateRequest * (if any) of these should be constrained by locally enabled schemes (especially once * jdk.tls.signatureSchemes support added). */ - jsseSecurityParameters.peerSigSchemes = contextData.getSignatureSchemes(serverSigAlgs); - jsseSecurityParameters.peerSigSchemesCert = (serverSigAlgs == serverSigAlgsCert) - ? jsseSecurityParameters.peerSigSchemes - : contextData.getSignatureSchemes(serverSigAlgsCert); + List peerSigSchemes = contextData.getSignatureSchemes(serverSigAlgs); + List peerSigSchemesCert = null; + if (serverSigAlgsCert != serverSigAlgs) + { + peerSigSchemesCert = contextData.getSignatureSchemes(serverSigAlgsCert); + } + + jsseSecurityParameters.signatureSchemes.notifyPeerData(peerSigSchemes, peerSigSchemesCert); if (LOG.isLoggable(Level.FINEST)) { - LOG.finest(JsseUtils.getSignatureAlgorithmsReport("Peer signature_algorithms", - jsseSecurityParameters.peerSigSchemes)); + { + String title = clientID + " peer signature_algorithms"; + LOG.finest(JsseUtils.getSignatureAlgorithmsReport(title, peerSigSchemes)); + } - if (jsseSecurityParameters.peerSigSchemesCert != jsseSecurityParameters.peerSigSchemes) + if (peerSigSchemesCert != null) { - LOG.finest(JsseUtils.getSignatureAlgorithmsReport("Peer signature_algorithms_cert", - jsseSecurityParameters.peerSigSchemesCert)); + String title = clientID + " peer signature_algorithms_cert"; + LOG.finest(JsseUtils.getSignatureAlgorithmsReport(title, peerSigSchemesCert)); } } } @@ -425,7 +447,7 @@ public void notifyAlertRaised(short alertLevel, short alertDescription, String m if (LOG.isLoggable(level)) { - String msg = JsseUtils.getAlertLogMessage("Client raised", alertLevel, alertDescription); + String msg = JsseUtils.getAlertRaisedLogMessage(clientID, alertLevel, alertDescription); if (message != null) { msg = msg + ": " + message; @@ -445,21 +467,40 @@ public void notifyAlertReceived(short alertLevel, short alertDescription) if (LOG.isLoggable(level)) { - String msg = JsseUtils.getAlertLogMessage("Client received", alertLevel, alertDescription); + String msg = JsseUtils.getAlertReceivedLogMessage(clientID, alertLevel, alertDescription); LOG.log(level, msg); } } + @Override + public void notifyConnectionClosed() + { + super.notifyConnectionClosed(); + + if (LOG.isLoggable(Level.INFO)) + { + LOG.info(clientID + " disconnected from " + JsseUtils.getPeerReport(manager)); + } + } + @Override public void notifyHandshakeBeginning() throws IOException { super.notifyHandshakeBeginning(); + if (LOG.isLoggable(Level.INFO)) + { + LOG.info(clientID + " opening connection to " + JsseUtils.getPeerReport(manager)); + } + ContextData contextData = manager.getContextData(); ProtocolVersion[] activeProtocolVersions = getProtocolVersions(); - jsseSecurityParameters.namedGroups = contextData.getNamedGroups(sslParameters, activeProtocolVersions); + jsseSecurityParameters.namedGroups = contextData.getNamedGroupsClient(sslParameters, activeProtocolVersions); + + jsseSecurityParameters.signatureSchemes = contextData.getSignatureSchemesClient(sslParameters, + activeProtocolVersions, jsseSecurityParameters.namedGroups); } @Override @@ -469,6 +510,11 @@ public synchronized void notifyHandshakeComplete() throws IOException this.handshakeComplete = true; + if (LOG.isLoggable(Level.INFO)) + { + LOG.info(clientID + " established connection with " + JsseUtils.getPeerReport(manager)); + } + TlsSession connectionTlsSession = context.getSession(); if (null == sslSession || sslSession.getTlsSession() != connectionTlsSession) @@ -485,7 +531,7 @@ public synchronized void notifyHandshakeComplete() throws IOException jsseSessionParameters, addToCache); } - manager.notifyHandshakeComplete(new ProvSSLConnection(context, sslSession)); + manager.notifyHandshakeComplete(new ProvSSLConnection(this)); } @Override @@ -509,7 +555,10 @@ public void notifySelectedCipherSuite(int selectedCipherSuite) String selectedCipherSuiteName = manager.getContextData().getContext() .validateNegotiatedCipherSuite(sslParameters, selectedCipherSuite); - LOG.fine("Client notified of selected cipher suite: " + selectedCipherSuiteName); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(clientID + " notified of selected cipher suite: " + selectedCipherSuiteName); + } super.notifySelectedCipherSuite(selectedCipherSuite); } @@ -520,7 +569,10 @@ public void notifyServerVersion(ProtocolVersion serverVersion) throws IOExceptio String serverVersionName = manager.getContextData().getContext().validateNegotiatedProtocol(sslParameters, serverVersion); - LOG.fine("Client notified of selected protocol version: " + serverVersionName); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(clientID + " notified of selected protocol version: " + serverVersionName); + } super.notifyServerVersion(serverVersion); } @@ -544,21 +596,27 @@ public void notifySessionID(byte[] sessionID) if (isResumed) { - // -DM Hex.toHexString - LOG.fine("Server resumed session: " + Hex.toHexString(sessionID)); + if (LOG.isLoggable(Level.FINE)) + { + // -DM Hex.toHexString + LOG.fine(clientID + ": Server resumed session: " + Hex.toHexString(sessionID)); + } } else { this.sslSession = null; - if (TlsUtils.isNullOrEmpty(sessionID)) + if (LOG.isLoggable(Level.FINE)) { - LOG.fine("Server did not specify a session ID"); - } - else - { - // -DM Hex.toHexString - LOG.fine("Server specified new session: " + Hex.toHexString(sessionID)); + if (TlsUtils.isNullOrEmpty(sessionID)) + { + LOG.fine(clientID + ": Server did not specify a session ID"); + } + else + { + // -DM Hex.toHexString + LOG.fine(clientID + ": Server specified new session: " + Hex.toHexString(sessionID)); + } } JsseUtils.checkSessionCreationEnabled(manager); @@ -579,7 +637,10 @@ public void processServerExtensions(@SuppressWarnings("rawtypes") Hashtable serv { boolean sniAccepted = TlsExtensionsUtils.hasServerNameExtensionServer(serverExtensions); - LOG.finer("Server accepted SNI?: " + sniAccepted); + if (LOG.isLoggable(Level.FINER)) + { + LOG.finer(clientID + ": Server accepted SNI?: " + sniAccepted); + } } } @@ -595,6 +656,12 @@ public boolean requiresExtendedMasterSecret() return !JsseUtils.allowLegacyMasterSecret(); } + @Override + public boolean shouldUseCompatibilityMode() + { + return JsseUtils.useCompatibilityMode(); + } + @Override public boolean shouldUseExtendedMasterSecret() { @@ -625,14 +692,19 @@ protected SessionParameters getResumableSessionParameters(ProvSSLSession provSSL { if (null == sessionParameters || - !ProtocolVersion.contains(getProtocolVersions(), sessionParameters.getNegotiatedVersion()) || !Arrays.contains(getCipherSuites(), sessionParameters.getCipherSuite())) { return null; } + ProtocolVersion sessionVersion = sessionParameters.getNegotiatedVersion(); + if (!ProtocolVersion.contains(getProtocolVersions(), sessionVersion)) + { + return null; + } + // TODO[tls13] Resumption/PSK - if (TlsUtils.isTLSv13(sessionParameters.getNegotiatedVersion())) + if (TlsUtils.isTLSv13(sessionVersion)) { return null; } @@ -646,8 +718,11 @@ protected SessionParameters getResumableSessionParameters(ProvSSLSession provSSL String sessionEndpointID = jsseSessionParameters.getEndpointIDAlgorithm(); if (!connectionEndpointID.equalsIgnoreCase(sessionEndpointID)) { - LOG.finer("Session not resumable - endpoint ID algorithm mismatch; connection: " - + connectionEndpointID + ", session: " + sessionEndpointID); + if (LOG.isLoggable(Level.FINER)) + { + LOG.finer(clientID + ": Session not resumable - endpoint ID algorithm mismatch; connection: " + + connectionEndpointID + ", session: " + sessionEndpointID); + } return null; } } @@ -665,8 +740,10 @@ protected TlsCredentials selectClientCredentials12(Principal[] issuers, short[] * with some hash/signature algorithm pair in supported_signature_algorithms. */ + PerConnection signatureSchemes = jsseSecurityParameters.signatureSchemes; + LinkedHashMap keyTypeMap = new LinkedHashMap(); - for (SignatureSchemeInfo signatureSchemeInfo : jsseSecurityParameters.peerSigSchemes) + for (SignatureSchemeInfo signatureSchemeInfo : signatureSchemes.getPeerSigSchemes()) { String keyType = signatureSchemeInfo.getKeyType(); if (keyTypeMap.containsKey(keyType)) @@ -681,7 +758,8 @@ protected TlsCredentials selectClientCredentials12(Principal[] issuers, short[] continue; } - if (!jsseSecurityParameters.localSigSchemes.contains(signatureSchemeInfo)) + if (!signatureSchemeInfo.isSupportedPre13() || + !signatureSchemes.hasLocalSignatureScheme(signatureSchemeInfo)) { continue; } @@ -691,7 +769,10 @@ protected TlsCredentials selectClientCredentials12(Principal[] issuers, short[] if (keyTypeMap.isEmpty()) { - LOG.fine("Client (1.2) found no usable signature schemes"); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(clientID + " (1.2) found no usable signature schemes"); + } return null; } @@ -701,7 +782,10 @@ protected TlsCredentials selectClientCredentials12(Principal[] issuers, short[] if (null == x509Key) { handleKeyManagerMisses(keyTypeMap, null); - LOG.fine("Client (1.2) did not select any credentials"); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(clientID + " (1.2) did not select any credentials"); + } return null; } @@ -716,7 +800,7 @@ protected TlsCredentials selectClientCredentials12(Principal[] issuers, short[] if (LOG.isLoggable(Level.FINE)) { - LOG.fine("Client (1.2) selected credentials for signature scheme '" + selectedSignatureSchemeInfo + LOG.fine(clientID + " (1.2) selected credentials for signature scheme '" + selectedSignatureSchemeInfo + "' (keyType '" + selectedKeyType + "'), with private key algorithm '" + JsseUtils.getPrivateKeyAlgorithm(x509Key.getPrivateKey()) + "'"); } @@ -728,17 +812,19 @@ protected TlsCredentials selectClientCredentials12(Principal[] issuers, short[] protected TlsCredentials selectClientCredentials13(Principal[] issuers, byte[] certificateRequestContext) throws IOException { + PerConnection signatureSchemes = jsseSecurityParameters.signatureSchemes; + LinkedHashMap keyTypeMap = new LinkedHashMap(); - for (SignatureSchemeInfo signatureSchemeInfo : jsseSecurityParameters.peerSigSchemes) + for (SignatureSchemeInfo signatureSchemeInfo : signatureSchemes.getPeerSigSchemes()) { - if (!signatureSchemeInfo.isSupportedPost13() || - !jsseSecurityParameters.localSigSchemes.contains(signatureSchemeInfo)) + String keyType = signatureSchemeInfo.getKeyType13(); + if (keyTypeMap.containsKey(keyType)) { continue; } - String keyType = signatureSchemeInfo.getKeyType13(); - if (keyTypeMap.containsKey(keyType)) + if (!signatureSchemeInfo.isSupportedPost13() || + !signatureSchemes.hasLocalSignatureScheme(signatureSchemeInfo)) { continue; } @@ -748,7 +834,10 @@ protected TlsCredentials selectClientCredentials13(Principal[] issuers, byte[] c if (keyTypeMap.isEmpty()) { - LOG.fine("Client (1.3) found no usable signature schemes"); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(clientID + " (1.3) found no usable signature schemes"); + } return null; } @@ -758,7 +847,10 @@ protected TlsCredentials selectClientCredentials13(Principal[] issuers, byte[] c if (null == x509Key) { handleKeyManagerMisses(keyTypeMap, null); - LOG.fine("Client (1.3) did not select any credentials"); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(clientID + " (1.3) did not select any credentials"); + } return null; } @@ -773,7 +865,7 @@ protected TlsCredentials selectClientCredentials13(Principal[] issuers, byte[] c if (LOG.isLoggable(Level.FINE)) { - LOG.fine("Client (1.3) selected credentials for signature scheme '" + selectedSignatureSchemeInfo + LOG.fine(clientID + " (1.3) selected credentials for signature scheme '" + selectedSignatureSchemeInfo + "' (keyType '" + selectedKeyType + "'), with private key algorithm '" + JsseUtils.getPrivateKeyAlgorithm(x509Key.getPrivateKey()) + "'"); } @@ -814,7 +906,7 @@ private void handleKeyManagerMisses(LinkedHashMap k { SignatureSchemeInfo signatureSchemeInfo = entry.getValue(); - LOG.finer("Client found no credentials for signature scheme '" + signatureSchemeInfo + LOG.finer(clientID + " found no credentials for signature scheme '" + signatureSchemeInfo + "' (keyType '" + keyType + "')"); } } diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsManager.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsManager.java index 83136a3347..bea7262ca9 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsManager.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsManager.java @@ -28,6 +28,8 @@ interface ProvTlsManager int getPeerPort(); + int getTransportID(); + void notifyHandshakeComplete(ProvSSLConnection connection); void notifyHandshakeSession(ProvSSLSessionContext sslSessionContext, SecurityParameters securityParameters, diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsPeer.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsPeer.java index ceabd8dba4..084ffb98df 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsPeer.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsPeer.java @@ -1,6 +1,14 @@ package org.bouncycastle.jsse.provider; +import org.bouncycastle.tls.TlsContext; + interface ProvTlsPeer { + String getID(); + + ProvSSLSession getSession(); + + TlsContext getTlsContext(); + boolean isHandshakeComplete(); } diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsServer.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsServer.java index 888bb4c99f..8eacfbed4b 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsServer.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsServer.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; import java.util.Hashtable; import java.util.LinkedHashMap; @@ -21,7 +22,7 @@ import org.bouncycastle.jsse.BCSNIMatcher; import org.bouncycastle.jsse.BCSNIServerName; import org.bouncycastle.jsse.BCX509Key; -import org.bouncycastle.jsse.java.security.BCAlgorithmConstraints; +import org.bouncycastle.jsse.provider.SignatureSchemeInfo.PerConnection; import org.bouncycastle.tls.AlertDescription; import org.bouncycastle.tls.AlertLevel; import org.bouncycastle.tls.Certificate; @@ -30,12 +31,14 @@ import org.bouncycastle.tls.ClientCertificateType; import org.bouncycastle.tls.DefaultTlsServer; import org.bouncycastle.tls.KeyExchangeAlgorithm; +import org.bouncycastle.tls.NamedGroup; import org.bouncycastle.tls.ProtocolName; import org.bouncycastle.tls.ProtocolVersion; import org.bouncycastle.tls.SecurityParameters; import org.bouncycastle.tls.ServerName; import org.bouncycastle.tls.SessionParameters; import org.bouncycastle.tls.SignatureAndHashAlgorithm; +import org.bouncycastle.tls.TlsContext; import org.bouncycastle.tls.TlsCredentials; import org.bouncycastle.tls.TlsDHUtils; import org.bouncycastle.tls.TlsExtensionsUtils; @@ -44,6 +47,7 @@ import org.bouncycastle.tls.TlsUtils; import org.bouncycastle.tls.TrustedAuthority; import org.bouncycastle.tls.crypto.DHGroup; +import org.bouncycastle.tls.crypto.TlsDHConfig; import org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; @@ -59,11 +63,6 @@ class ProvTlsServer // TODO[jsse] Integrate this into NamedGroupInfo private static final int provEphemeralDHKeySize = PropertyUtils.getIntegerSystemProperty("jdk.tls.ephemeralDHKeySize", 2048, 1024, 8192); - /* - * TODO[jsse] Does this selection override the restriction from 'jdk.tls.ephemeralDHKeySize'? - * TODO[fips] Probably should be ignored in fips mode? - */ - @SuppressWarnings("unused") private static final DHGroup[] provServerDefaultDHEParameters = getDefaultDHEParameters(); private static final boolean provServerEnableCA = PropertyUtils @@ -80,6 +79,9 @@ class ProvTlsServer private static final boolean provServerEnableTrustedCAKeys = PropertyUtils .getBooleanSystemProperty("org.bouncycastle.jsse.server.enableTrustedCAKeysExtension", false); + private static final boolean provServerOmitSigAlgsCert = PropertyUtils + .getBooleanSystemProperty("org.bouncycastle.jsse.server.omitSigAlgsCertExtension", true); + private static DHGroup[] getDefaultDHEParameters() { String propertyValue = PropertyUtils.getStringSecurityProperty(PROPERTY_DEFAULT_DHE_PARAMETERS); @@ -95,7 +97,7 @@ private static DHGroup[] getDefaultDHEParameters() return null; } - ArrayList result = new ArrayList(); + ArrayList dhGroups = new ArrayList(); int outerComma = -1; do { @@ -129,7 +131,7 @@ private static DHGroup[] getDefaultDHEParameters() DHGroup dhGroup = TlsDHUtils.getStandardGroupForDHParameters(p, g); if (null != dhGroup) { - result.add(dhGroup); + dhGroups.add(dhGroup); } else if (!p.isProbablePrime(120)) { @@ -138,7 +140,7 @@ else if (!p.isProbablePrime(120)) } else { - result.add(new DHGroup(p, null, g, 0)); + dhGroups.add(new DHGroup(p, null, g, 0)); } } catch (Exception e) @@ -149,7 +151,15 @@ else if (!p.isProbablePrime(120)) outerComma = closeBrace + 1; if (outerComma >= limit) { - return result.toArray(new DHGroup[result.size()]); + DHGroup[] result = dhGroups.toArray(new DHGroup[dhGroups.size()]); + java.util.Arrays.sort(result, new Comparator() + { + public int compare(DHGroup a, DHGroup b) + { + return a.getP().bitLength() - b.getP().bitLength(); + } + }); + return result; } } while (',' == input.charAt(outerComma)); @@ -164,6 +174,7 @@ private static BigInteger parseDHParameter(String s, int beginIndex, int endInde return new BigInteger(s.substring(beginIndex, endIndex), 16); } + protected final String serverID; protected final ProvTlsManager manager; protected final ProvSSLParameters sslParameters; protected final JsseSecurityParameters jsseSecurityParameters = new JsseSecurityParameters(); @@ -178,10 +189,26 @@ private static BigInteger parseDHParameter(String s, int beginIndex, int endInde { super(manager.getContextData().getCrypto()); + this.serverID = JsseUtils.getPeerID("server", manager); this.manager = manager; this.sslParameters = sslParameters.copyForConnection(); } + public String getID() + { + return serverID; + } + + public ProvSSLSession getSession() + { + return sslSession; + } + + public TlsContext getTlsContext() + { + return context; + } + @Override protected boolean allowCertificateStatus() { @@ -200,16 +227,67 @@ protected boolean allowTrustedCAIndication() return null != jsseSecurityParameters.trustedIssuers; } + @Override + protected String getDetailMessageNoCipherSuite() + { + // CAUTION: Required for Common Criteria + + StringBuilder sb = new StringBuilder(serverID); + + int[] offered = offeredCipherSuites; + if (TlsUtils.isNullOrEmpty(offered)) + { + sb.append(" found no selectable cipher suite because none were offered."); + } + else + { + sb.append(" found no selectable cipher suite among the "); + sb.append(offered.length); + sb.append(" offered: "); + + ProvSSLContextSpi context = manager.getContextData().getContext(); + + sb.append('['); + JsseUtils.appendCipherSuiteDetail(sb, context, offered[0]); + + for (int i = 1; i < offered.length; ++i) + { + sb.append(", "); + JsseUtils.appendCipherSuiteDetail(sb, context, offered[i]); + } + + sb.append(']'); + } + + return sb.toString(); + } + @Override protected int getMaximumNegotiableCurveBits() { - return NamedGroupInfo.getMaximumBitsServerECDH(jsseSecurityParameters.namedGroups); + NamedGroupInfo.DefaultedResult maxBitsResult = NamedGroupInfo.getMaximumBitsServerECDH( + jsseSecurityParameters.namedGroups); + + int maxBits = maxBitsResult.getResult(); + + return maxBits; } @Override protected int getMaximumNegotiableFiniteFieldBits() { - int maxBits = NamedGroupInfo.getMaximumBitsServerFFDHE(jsseSecurityParameters.namedGroups); + NamedGroupInfo.DefaultedResult maxBitsResult = NamedGroupInfo.getMaximumBitsServerFFDHE( + jsseSecurityParameters.namedGroups); + + int maxBits = maxBitsResult.getResult(); + + if (maxBitsResult.isDefaulted() && + !TlsUtils.isNullOrEmpty(provServerDefaultDHEParameters) && + !manager.getContextData().getContext().isFips()) + { + DHGroup largest = provServerDefaultDHEParameters[provServerDefaultDHEParameters.length - 1]; + maxBits = Math.max(maxBits, largest.getP().bitLength()); + } return maxBits >= provEphemeralDHKeySize ? maxBits : 0; } @@ -252,7 +330,10 @@ protected boolean selectCipherSuite(int cipherSuite) throws IOException if (null == cipherSuiteCredentials) { String cipherSuiteName = ProvSSLContextSpi.getCipherSuiteName(cipherSuite); - LOG.finer("Server found no credentials for cipher suite: " + cipherSuiteName); + if (LOG.isLoggable(Level.FINER)) + { + LOG.finer(serverID + " found no credentials for cipher suite: " + cipherSuiteName); + } return false; } } @@ -266,11 +347,41 @@ protected boolean selectCipherSuite(int cipherSuite) throws IOException } @Override - protected int selectDH(int minimumFiniteFieldBits) + public TlsDHConfig getDHConfig() throws IOException { + int minimumFiniteFieldBits = TlsDHUtils.getMinimumFiniteFieldBits(selectedCipherSuite); minimumFiniteFieldBits = Math.max(minimumFiniteFieldBits, provEphemeralDHKeySize); - return NamedGroupInfo.selectServerFFDHE(jsseSecurityParameters.namedGroups, minimumFiniteFieldBits); + NamedGroupInfo.DefaultedResult namedGroupResult = NamedGroupInfo.selectServerFFDHE( + jsseSecurityParameters.namedGroups, minimumFiniteFieldBits); + + int namedGroup = namedGroupResult.getResult(); + + if (namedGroupResult.isDefaulted() && + !TlsUtils.isNullOrEmpty(provServerDefaultDHEParameters) && + !manager.getContextData().getContext().isFips()) + { + for (DHGroup dhGroup : provServerDefaultDHEParameters) + { + int bits = dhGroup.getP().bitLength(); + if (bits >= minimumFiniteFieldBits) + { + if (namedGroup < 0 || bits <= NamedGroup.getFiniteFieldBits(namedGroup)) + { + return new TlsDHConfig(dhGroup); + } + break; + } + } + } + + return TlsDHUtils.createNamedDHConfig(context, namedGroup); + } + + @Override + protected int selectDH(int minimumFiniteFieldBits) + { + throw new UnsupportedOperationException(); } @Override @@ -282,7 +393,7 @@ protected int selectDHDefault(int minimumFiniteFieldBits) @Override protected int selectECDH(int minimumCurveBits) { - return NamedGroupInfo.selectServerECDH(jsseSecurityParameters.namedGroups, minimumCurveBits); + return NamedGroupInfo.selectServerECDH(jsseSecurityParameters.namedGroups, minimumCurveBits).getResult(); } @Override @@ -372,16 +483,8 @@ public CertificateRequest getCertificateRequest() throws IOException final ContextData contextData = manager.getContextData(); final ProtocolVersion negotiatedVersion = context.getServerVersion(); - // TODO[jsse] May want this selection to depend on the peer's supported_groups (create alternate method)? - List signatureSchemes = contextData.getActiveCertsSignatureSchemes(true, sslParameters, - new ProtocolVersion[]{ negotiatedVersion }, jsseSecurityParameters.namedGroups); - - // TODO[tls13] From TLS 1.3 these are allowed to be different (no JSSE API to configure this though) - jsseSecurityParameters.localSigSchemes = signatureSchemes; - jsseSecurityParameters.localSigSchemesCert = signatureSchemes; - - Vector serverSigAlgs = SignatureSchemeInfo - .getSignatureAndHashAlgorithms(jsseSecurityParameters.localSigSchemes); + Vector serverSigAlgs = + jsseSecurityParameters.signatureSchemes.getLocalSignatureAndHashAlgorithms(); Vector certificateAuthorities = null; if (provServerEnableCA) @@ -403,11 +506,12 @@ public CertificateRequest getCertificateRequest() throws IOException */ byte[] certificateRequestContext = TlsUtils.EMPTY_BYTES; - Vector serverSigAlgsCert = null; - if (jsseSecurityParameters.localSigSchemes != jsseSecurityParameters.localSigSchemesCert) + Vector serverSigAlgsCert = + jsseSecurityParameters.signatureSchemes.getLocalSignatureAndHashAlgorithmsCert(); + + if (serverSigAlgsCert == null && !provServerOmitSigAlgsCert) { - serverSigAlgsCert = SignatureSchemeInfo - .getSignatureAndHashAlgorithms(jsseSecurityParameters.localSigSchemesCert); + serverSigAlgsCert = jsseSecurityParameters.signatureSchemes.getLocalSignatureAndHashAlgorithms(); } return new CertificateRequest(certificateRequestContext, serverSigAlgs, serverSigAlgsCert, @@ -486,9 +590,10 @@ public int[] getSupportedGroups() throws IOException { // Setup the local supported groups { - ProtocolVersion[] activeProtocolVersions = new ProtocolVersion[]{ context.getServerVersion() }; + ContextData contextData = manager.getContextData(); + ProtocolVersion negotiatedVersion = context.getServerVersion(); - jsseSecurityParameters.namedGroups = manager.getContextData().getNamedGroups(sslParameters, activeProtocolVersions); + jsseSecurityParameters.namedGroups = contextData.getNamedGroupsServer(sslParameters, negotiatedVersion); } return NamedGroupInfo.getSupportedGroupsLocalServer(jsseSecurityParameters.namedGroups); @@ -500,11 +605,20 @@ public int getSelectedCipherSuite() throws IOException final ContextData contextData = manager.getContextData(); final SecurityParameters securityParameters = context.getSecurityParametersHandshake(); - // Setup the peer supported groups + // Set up the peer supported groups { int[] clientSupportedGroups = securityParameters.getClientSupportedGroups(); - NamedGroupInfo.notifyPeer(jsseSecurityParameters.namedGroups, clientSupportedGroups); + jsseSecurityParameters.namedGroups.notifyPeerData(clientSupportedGroups); + } + + // Setup the local supported signature schemes + { + ProtocolVersion negotiatedVersion = context.getServerVersion(); + + // TODO[jsse] May want this selection to depend on the peer's supported_groups + jsseSecurityParameters.signatureSchemes = contextData.getSignatureSchemesServer(sslParameters, + negotiatedVersion, jsseSecurityParameters.namedGroups); } // Setup the peer supported signature schemes @@ -521,20 +635,26 @@ public int getSelectedCipherSuite() throws IOException * (if any) of these should be constrained by locally enabled schemes (especially once * jdk.tls.signatureSchemes support added). */ - jsseSecurityParameters.peerSigSchemes = contextData.getSignatureSchemes(clientSigAlgs); - jsseSecurityParameters.peerSigSchemesCert = (clientSigAlgs == clientSigAlgsCert) - ? jsseSecurityParameters.peerSigSchemes - : contextData.getSignatureSchemes(clientSigAlgsCert); + List peerSigSchemes = contextData.getSignatureSchemes(clientSigAlgs); + List peerSigSchemesCert = null; + if (clientSigAlgsCert != clientSigAlgs) + { + peerSigSchemesCert = contextData.getSignatureSchemes(clientSigAlgsCert); + } + + jsseSecurityParameters.signatureSchemes.notifyPeerData(peerSigSchemes, peerSigSchemesCert); if (LOG.isLoggable(Level.FINEST)) { - LOG.finest(JsseUtils.getSignatureAlgorithmsReport("Peer signature_algorithms", - jsseSecurityParameters.peerSigSchemes)); + { + String title = serverID + " peer signature_algorithms"; + LOG.finest(JsseUtils.getSignatureAlgorithmsReport(title, peerSigSchemes)); + } - if (jsseSecurityParameters.peerSigSchemesCert != jsseSecurityParameters.peerSigSchemes) + if (peerSigSchemesCert != null) { - LOG.finest(JsseUtils.getSignatureAlgorithmsReport("Peer signature_algorithms_cert", - jsseSecurityParameters.peerSigSchemesCert)); + String title = serverID + " peer signature_algorithms_cert"; + LOG.finest(JsseUtils.getSignatureAlgorithmsReport(title, peerSigSchemesCert)); } } } @@ -551,10 +671,13 @@ public int getSelectedCipherSuite() throws IOException keyManagerMissCache = null; - String selectedCipherSuiteName = manager.getContextData().getContext() - .validateNegotiatedCipherSuite(sslParameters, selectedCipherSuite); + String selectedCipherSuiteName = contextData.getContext().validateNegotiatedCipherSuite(sslParameters, + selectedCipherSuite); - LOG.fine("Server selected cipher suite: " + selectedCipherSuiteName); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(serverID + " selected cipher suite: " + selectedCipherSuiteName); + } return selectedCipherSuite; } @@ -624,21 +747,27 @@ public void notifySession(TlsSession session) boolean isResumed = (null != sslSession && sslSession.getTlsSession() == session); if (isResumed) { - // -DM Hex.toHexString - LOG.fine("Server resumed session: " + Hex.toHexString(sessionID)); + if (LOG.isLoggable(Level.FINE)) + { + // -DM Hex.toHexString + LOG.fine(serverID + " resumed session: " + Hex.toHexString(sessionID)); + } } else { this.sslSession = null; - if (TlsUtils.isNullOrEmpty(sessionID)) + if (LOG.isLoggable(Level.FINE)) { - LOG.fine("Server did not specify a session ID"); - } - else - { - // -DM Hex.toHexString - LOG.fine("Server specified new session: " + Hex.toHexString(sessionID)); + if (TlsUtils.isNullOrEmpty(sessionID)) + { + LOG.fine(serverID + " did not specify a session ID"); + } + else + { + // -DM Hex.toHexString + LOG.fine(serverID + " specified new session: " + Hex.toHexString(sessionID)); + } } JsseUtils.checkSessionCreationEnabled(manager); @@ -657,7 +786,7 @@ public void notifyAlertRaised(short alertLevel, short alertDescription, String m if (LOG.isLoggable(level)) { - String msg = JsseUtils.getAlertLogMessage("Server raised", alertLevel, alertDescription); + String msg = JsseUtils.getAlertRaisedLogMessage(serverID, alertLevel, alertDescription); if (message != null) { msg = msg + ": " + message; @@ -677,7 +806,7 @@ public void notifyAlertReceived(short alertLevel, short alertDescription) if (LOG.isLoggable(level)) { - String msg = JsseUtils.getAlertLogMessage("Server received", alertLevel, alertDescription); + String msg = JsseUtils.getAlertReceivedLogMessage(serverID, alertLevel, alertDescription); LOG.log(level, msg); } @@ -691,7 +820,10 @@ public ProtocolVersion getServerVersion() throws IOException String serverVersionName = manager.getContextData().getContext().validateNegotiatedProtocol(sslParameters, serverVersion); - LOG.fine("Server selected protocol version: " + serverVersionName); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(serverID + " selected protocol version: " + serverVersionName); + } return serverVersion; } @@ -730,6 +862,28 @@ public void notifyClientCertificate(Certificate clientCertificate) throws IOExce } } + @Override + public void notifyConnectionClosed() + { + super.notifyConnectionClosed(); + + if (LOG.isLoggable(Level.INFO)) + { + LOG.info(serverID + " disconnected from " + JsseUtils.getPeerReport(manager)); + } + } + + @Override + public void notifyHandshakeBeginning() throws IOException + { + super.notifyHandshakeBeginning(); + + if (LOG.isLoggable(Level.INFO)) + { + LOG.info(serverID + " accepting connection from " + JsseUtils.getPeerReport(manager)); + } + } + @Override public synchronized void notifyHandshakeComplete() throws IOException { @@ -737,6 +891,11 @@ public synchronized void notifyHandshakeComplete() throws IOException this.handshakeComplete = true; + if (LOG.isLoggable(Level.INFO)) + { + LOG.info(serverID + " established connection with " + JsseUtils.getPeerReport(manager)); + } + TlsSession connectionTlsSession = context.getSession(); if (null == sslSession || sslSession.getTlsSession() != connectionTlsSession) @@ -744,16 +903,16 @@ public synchronized void notifyHandshakeComplete() throws IOException ProvSSLSessionContext sslSessionContext = manager.getContextData().getServerSessionContext(); String peerHost = manager.getPeerHost(); int peerPort = manager.getPeerPort(); - JsseSessionParameters jsseSessionParameters = new JsseSessionParameters(null, matchedSNIServerName); + JsseSessionParameters jsseSessionParameters = new JsseSessionParameters( + sslParameters.getEndpointIdentificationAlgorithm(), matchedSNIServerName); // TODO[tls13] Resumption/PSK - boolean addToCache = provServerEnableSessionResumption && !TlsUtils.isTLSv13(context) - && context.getSecurityParametersConnection().isExtendedMasterSecret(); + boolean addToCache = provServerEnableSessionResumption && !TlsUtils.isTLSv13(context); this.sslSession = sslSessionContext.reportSession(peerHost, peerPort, connectionTlsSession, jsseSessionParameters, addToCache); } - manager.notifyHandshakeComplete(new ProvSSLConnection(context, sslSession)); + manager.notifyHandshakeComplete(new ProvSSLConnection(this)); } @Override @@ -788,7 +947,10 @@ public void processClientExtensions(@SuppressWarnings("rawtypes") Hashtable clie Collection sniMatchers = sslParameters.getSNIMatchers(); if (null == sniMatchers || sniMatchers.isEmpty()) { - LOG.fine("Server ignored SNI (no matchers specified)"); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(serverID + " ignored SNI (no matchers specified)"); + } } else { @@ -798,7 +960,10 @@ public void processClientExtensions(@SuppressWarnings("rawtypes") Hashtable clie throw new TlsFatalAlert(AlertDescription.unrecognized_name); } - LOG.fine("Server accepted SNI: " + matchedSNIServerName); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(serverID + " accepted SNI: " + matchedSNIServerName); + } } } @@ -872,11 +1037,28 @@ protected boolean isResumable(ProvSSLSession provSSLSession, TlsSession tlsSessi return false; } - // TODO[resumption] Consider support for related system properties - if (!sessionParameters.isExtendedMasterSecret()) + if (sslParameters.getNeedClientAuth() && sessionParameters.getPeerCertificate() == null) { return false; } + + { + String connectionEndpointID = sslParameters.getEndpointIdentificationAlgorithm(); + if (null != connectionEndpointID) + { + JsseSessionParameters jsseSessionParameters = provSSLSession.getJsseSessionParameters(); + String sessionEndpointID = jsseSessionParameters.getEndpointIDAlgorithm(); + if (!connectionEndpointID.equalsIgnoreCase(sessionEndpointID)) + { + if (LOG.isLoggable(Level.FINER)) + { + LOG.finer(serverID + ": Session not resumable - endpoint ID algorithm mismatch; connection: " + + connectionEndpointID + ", session: " + sessionEndpointID); + } + return false; + } + } + } } { @@ -899,8 +1081,11 @@ protected boolean isResumable(ProvSSLSession provSSLSession, TlsSession tlsSessi if (!JsseUtils.equals(connectionSNI, sessionSNI)) { - LOG.finest( - "Session not resumable - SNI mismatch; connection: " + connectionSNI + ", session: " + sessionSNI); + if (LOG.isLoggable(Level.FINEST)) + { + LOG.finest(serverID + ": Session not resumable - SNI mismatch; connection: " + connectionSNI + + ", session: " + sessionSNI); + } return false; } } @@ -941,12 +1126,12 @@ protected TlsCredentials selectCredentials(Principal[] issuers, int keyExchangeA protected TlsCredentials selectServerCredentials12(Principal[] issuers, int keyExchangeAlgorithm) throws IOException { - BCAlgorithmConstraints algorithmConstraints = sslParameters.getAlgorithmConstraints(); - final short legacySignatureAlgorithm = TlsUtils.getLegacySignatureAlgorithmServer(keyExchangeAlgorithm); + PerConnection signatureSchemes = jsseSecurityParameters.signatureSchemes; + LinkedHashMap keyTypeMap = new LinkedHashMap(); - for (SignatureSchemeInfo signatureSchemeInfo : jsseSecurityParameters.peerSigSchemes) + for (SignatureSchemeInfo signatureSchemeInfo : signatureSchemes.getPeerSigSchemes()) { if (!TlsUtils.isValidSignatureSchemeForServerKeyExchange(signatureSchemeInfo.getSignatureScheme(), keyExchangeAlgorithm)) @@ -969,8 +1154,8 @@ protected TlsCredentials selectServerCredentials12(Principal[] issuers, int keyE continue; } - // TODO[jsse] Somewhat redundant if we get all active signature schemes later (for CertificateRequest) - if (!signatureSchemeInfo.isActive(algorithmConstraints, false, true, jsseSecurityParameters.namedGroups)) + if (!signatureSchemeInfo.isSupportedPre13() || + !signatureSchemes.hasLocalSignatureScheme(signatureSchemeInfo)) { continue; } @@ -980,7 +1165,10 @@ protected TlsCredentials selectServerCredentials12(Principal[] issuers, int keyE if (keyTypeMap.isEmpty()) { - LOG.fine("Server (1.2) has no key types to try for KeyExchangeAlgorithm " + keyExchangeAlgorithm); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(serverID + " (1.2) has no key types to try for KeyExchangeAlgorithm " + keyExchangeAlgorithm); + } return null; } @@ -990,7 +1178,10 @@ protected TlsCredentials selectServerCredentials12(Principal[] issuers, int keyE if (null == x509Key) { handleKeyManagerMisses(keyTypeMap, null); - LOG.fine("Server (1.2) did not select any credentials for KeyExchangeAlgorithm " + keyExchangeAlgorithm); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(serverID + " (1.2) did not select any credentials for KeyExchangeAlgorithm " + keyExchangeAlgorithm); + } return null; } @@ -1005,7 +1196,7 @@ protected TlsCredentials selectServerCredentials12(Principal[] issuers, int keyE if (LOG.isLoggable(Level.FINE)) { - LOG.fine("Server (1.2) selected credentials for signature scheme '" + selectedSignatureSchemeInfo + LOG.fine(serverID + " (1.2) selected credentials for signature scheme '" + selectedSignatureSchemeInfo + "' (keyType '" + selectedKeyType + "'), with private key algorithm '" + JsseUtils.getPrivateKeyAlgorithm(x509Key.getPrivateKey()) + "'"); } @@ -1017,10 +1208,10 @@ protected TlsCredentials selectServerCredentials12(Principal[] issuers, int keyE protected TlsCredentials selectServerCredentials13(Principal[] issuers, byte[] certificateRequestContext) throws IOException { - BCAlgorithmConstraints algorithmConstraints = sslParameters.getAlgorithmConstraints(); + PerConnection signatureSchemes = jsseSecurityParameters.signatureSchemes; LinkedHashMap keyTypeMap = new LinkedHashMap(); - for (SignatureSchemeInfo signatureSchemeInfo : jsseSecurityParameters.peerSigSchemes) + for (SignatureSchemeInfo signatureSchemeInfo : signatureSchemes.getPeerSigSchemes()) { String keyType = signatureSchemeInfo.getKeyType13(); if (keyManagerMissCache.contains(keyType)) @@ -1032,8 +1223,8 @@ protected TlsCredentials selectServerCredentials13(Principal[] issuers, byte[] c continue; } - // TODO[jsse] Somewhat redundant if we get all active signature schemes later (for CertificateRequest) - if (!signatureSchemeInfo.isActive(algorithmConstraints, true, false, jsseSecurityParameters.namedGroups)) + if (!signatureSchemeInfo.isSupportedPost13() || + !signatureSchemes.hasLocalSignatureScheme(signatureSchemeInfo)) { continue; } @@ -1043,7 +1234,10 @@ protected TlsCredentials selectServerCredentials13(Principal[] issuers, byte[] c if (keyTypeMap.isEmpty()) { - LOG.fine("Server (1.3) found no usable signature schemes"); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(serverID + " (1.3) found no usable signature schemes"); + } return null; } @@ -1053,7 +1247,10 @@ protected TlsCredentials selectServerCredentials13(Principal[] issuers, byte[] c if (null == x509Key) { handleKeyManagerMisses(keyTypeMap, null); - LOG.fine("Server (1.3) did not select any credentials"); + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine(serverID + " (1.3) did not select any credentials"); + } return null; } @@ -1068,7 +1265,7 @@ protected TlsCredentials selectServerCredentials13(Principal[] issuers, byte[] c if (LOG.isLoggable(Level.FINE)) { - LOG.fine("Server (1.3) selected credentials for signature scheme '" + selectedSignatureSchemeInfo + LOG.fine(serverID + " (1.3) selected credentials for signature scheme '" + selectedSignatureSchemeInfo + "' (keyType '" + selectedKeyType + "'), with private key algorithm '" + JsseUtils.getPrivateKeyAlgorithm(x509Key.getPrivateKey()) + "'"); } @@ -1117,7 +1314,7 @@ private void handleKeyManagerMisses(LinkedHashMap k { SignatureSchemeInfo signatureSchemeInfo = entry.getValue(); - LOG.finer("Server found no credentials for signature scheme '" + signatureSchemeInfo + LOG.finer(serverID + " found no credentials for signature scheme '" + signatureSchemeInfo + "' (keyType '" + keyType + "')"); } } diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvX509TrustManager.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvX509TrustManager.java index d8cf540c4c..7b74c75015 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvX509TrustManager.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvX509TrustManager.java @@ -7,7 +7,6 @@ import java.security.Provider; import java.security.cert.CertPath; import java.security.cert.CertPathBuilder; -import java.security.cert.CertPathBuilderException; import java.security.cert.CertSelector; import java.security.cert.CertStore; import java.security.cert.CertStoreParameters; @@ -158,12 +157,14 @@ public void checkClientTrusted(X509Certificate[] chain, String authType) checkTrusted(chain, authType, null, false); } + @Override public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { checkTrusted(chain, authType, TransportData.from(socket), false); } + @Override public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { @@ -176,12 +177,14 @@ public void checkServerTrusted(X509Certificate[] chain, String authType) checkTrusted(chain, authType, null, true); } + @Override public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { checkTrusted(chain, authType, TransportData.from(socket), true); } + @Override public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { @@ -313,10 +316,6 @@ private X509Certificate[] validateChain(X509Certificate[] chain, String authType { throw e; } - catch (CertPathBuilderException e) - { - throw new CertificateException(e.getMessage(), e.getCause()); - } catch (GeneralSecurityException e) { throw new CertificateException("Unable to construct a valid chain", e); diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ReflectionUtil.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ReflectionUtil.java index 5edcb5872d..19540cfded 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ReflectionUtil.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ReflectionUtil.java @@ -29,6 +29,7 @@ static boolean hasMethod(Method[] methods, String name) return null != findMethod(methods, name); } + static Class getClass(final String className) { if (null == className) diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/SignatureSchemeInfo.java b/tls/src/main/java/org/bouncycastle/jsse/provider/SignatureSchemeInfo.java index 4fc287f564..08eea6bdde 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/SignatureSchemeInfo.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/SignatureSchemeInfo.java @@ -9,6 +9,7 @@ import java.util.Set; import java.util.TreeMap; import java.util.Vector; +import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Logger; import org.bouncycastle.jsse.java.security.BCAlgorithmConstraints; @@ -36,6 +37,9 @@ class SignatureSchemeInfo private static final String PROPERTY_CLIENT_SIGNATURE_SCHEMES = "jdk.tls.client.SignatureSchemes"; private static final String PROPERTY_SERVER_SIGNATURE_SCHEMES = "jdk.tls.server.SignatureSchemes"; + private static final String PROPERTY_CLIENT_SIGNATURE_SCHEMES_CERT = "org.bouncycastle.jsse.client.SignatureSchemesCert"; + private static final String PROPERTY_SERVER_SIGNATURE_SCHEMES_CERT = "org.bouncycastle.jsse.server.SignatureSchemesCert"; + // NOTE: Not all of these are necessarily enabled/supported; it will be checked at runtime private enum All { @@ -140,97 +144,253 @@ private All(int signatureScheme, String name, String jcaSignatureAlgorithm, Stri private static final int[] CANDIDATES_DEFAULT = createCandidatesDefault(); + static class PerConnection + { + private final List localSigSchemes; + private final List localSigSchemesCert; + private final AtomicReference> peerSigSchemes; + private final AtomicReference> peerSigSchemesCert; + + PerConnection(List localSigSchemes, List localSigSchemesCert) + { + this.localSigSchemes = localSigSchemes; + this.localSigSchemesCert = localSigSchemesCert; + this.peerSigSchemes = new AtomicReference>(); + this.peerSigSchemesCert = new AtomicReference>(); + } + + String[] getLocalJcaSignatureAlgorithms() + { + return getJcaSignatureAlgorithms(getLocalSigSchemesCert()); + } + + String[] getLocalJcaSignatureAlgorithmsBC() + { + return getJcaSignatureAlgorithmsBC(getLocalSigSchemesCert()); + } + + Vector getLocalSignatureAndHashAlgorithms() + { + return getSignatureAndHashAlgorithms(localSigSchemes); + } + + Vector getLocalSignatureAndHashAlgorithmsCert() + { + return getSignatureAndHashAlgorithms(localSigSchemesCert); + } + + List getLocalSigSchemes() + { + return localSigSchemes; + } + + List getLocalSigSchemesCert() + { + return localSigSchemesCert != null ? localSigSchemesCert : getLocalSigSchemes(); + } + + String[] getPeerJcaSignatureAlgorithms() + { + return getJcaSignatureAlgorithms(getPeerSigSchemesCert()); + } + + String[] getPeerJcaSignatureAlgorithmsBC() + { + return getJcaSignatureAlgorithmsBC(getPeerSigSchemesCert()); + } + + List getPeerSigSchemes() + { + return peerSigSchemes.get(); + } + + List getPeerSigSchemesCert() + { + List sigSchemesCert = peerSigSchemesCert.get(); + + return sigSchemesCert != null ? sigSchemesCert : getPeerSigSchemes(); + } + + boolean hasLocalSignatureScheme(SignatureSchemeInfo signatureSchemeInfo) + { + return localSigSchemes.contains(signatureSchemeInfo); + } + + void notifyPeerData(List sigSchemes, List sigSchemesCert) + { + peerSigSchemes.set(sigSchemes); + peerSigSchemesCert.set(sigSchemesCert); + } + } + static class PerContext { private final Map index; private final int[] candidatesClient, candidatesServer; + private final int[] candidatesCertClient, candidatesCertServer; - PerContext(Map index, int[] candidatesClient, int[] candidatesServer) + PerContext(Map index, int[] candidatesClient, int[] candidatesServer, + int[] candidatesCertClient, int[] candidatesCertServer) { this.index = index; this.candidatesClient = candidatesClient; this.candidatesServer = candidatesServer; + this.candidatesCertClient = candidatesCertClient; + this.candidatesCertServer = candidatesCertServer; } } - static PerContext createPerContext(boolean isFipsContext, JcaTlsCrypto crypto, - NamedGroupInfo.PerContext namedGroups) + static PerConnection createPerConnectionClient(PerContext perContext, ProvSSLParameters sslParameters, + ProtocolVersion[] activeProtocolVersions, NamedGroupInfo.PerConnection namedGroups) { - Map index = createIndex(isFipsContext, crypto, namedGroups); - int[] candidatesClient = createCandidates(index, PROPERTY_CLIENT_SIGNATURE_SCHEMES); - int[] candidatesServer = createCandidates(index, PROPERTY_SERVER_SIGNATURE_SCHEMES); + ProtocolVersion latest = ProtocolVersion.getLatestTLS(activeProtocolVersions); + if (!TlsUtils.isSignatureAlgorithmsExtensionAllowed(latest)) + { + return new PerConnection(null, null); + } + + ProtocolVersion earliest = ProtocolVersion.getEarliestTLS(activeProtocolVersions); - return new PerContext(index, candidatesClient, candidatesServer); + return createPerConnection(perContext, false, sslParameters, earliest, latest, namedGroups); } - static List getActiveCertsSignatureSchemes(PerContext perContext, boolean isServer, - ProvSSLParameters sslParameters, ProtocolVersion[] activeProtocolVersions, - NamedGroupInfo.PerConnection namedGroups) + static PerConnection createPerConnectionServer(PerContext perContext, ProvSSLParameters sslParameters, + ProtocolVersion negotiatedVersion, NamedGroupInfo.PerConnection namedGroups) { - ProtocolVersion latest = ProtocolVersion.getLatestTLS(activeProtocolVersions); - if (!TlsUtils.isSignatureAlgorithmsExtensionAllowed(latest)) + if (!TlsUtils.isSignatureAlgorithmsExtensionAllowed(negotiatedVersion)) { - return null; + return new PerConnection(null, null); } - int[] candidates = isServer ? perContext.candidatesServer : perContext.candidatesClient; + return createPerConnection(perContext, true, sslParameters, negotiatedVersion, negotiatedVersion, namedGroups); + } - ProtocolVersion earliest = ProtocolVersion.getEarliestTLS(activeProtocolVersions); + private static PerConnection createPerConnection(PerContext perContext, boolean isServer, ProvSSLParameters sslParameters, + ProtocolVersion earliest, ProtocolVersion latest, NamedGroupInfo.PerConnection namedGroups) + { + int[] candidates; + { + String[] signatureSchemes = sslParameters.getSignatureSchemes(); + + if (signatureSchemes == null) + { + candidates = isServer ? perContext.candidatesServer : perContext.candidatesClient; + + if (candidates == null) + { + candidates = CANDIDATES_DEFAULT; + } + } + else + { + candidates = createCandidates(perContext.index, signatureSchemes, "SSLParameters.signatureSchemes"); + } + } + + int[] candidatesCert; + { + String[] signatureSchemesCert = sslParameters.getSignatureSchemesCert(); + + if (signatureSchemesCert == null) + { + candidatesCert = isServer ? perContext.candidatesCertServer : perContext.candidatesCertClient; + } + else + { + candidatesCert = createCandidates(perContext.index, signatureSchemesCert, + "SSLParameters.signatureSchemesCert"); + } + } BCAlgorithmConstraints algorithmConstraints = sslParameters.getAlgorithmConstraints(); boolean post13Active = TlsUtils.isTLSv13(latest); boolean pre13Active = !TlsUtils.isTLSv13(earliest); - int count = candidates.length; - ArrayList result = new ArrayList(count); - for (int i = 0; i < count; ++i) + ArrayList localSigSchemes; { - Integer candidate = Integers.valueOf(candidates[i]); - SignatureSchemeInfo signatureSchemeInfo = perContext.index.get(candidate); - - if (null != signatureSchemeInfo - && signatureSchemeInfo.isActiveCerts(algorithmConstraints, post13Active, pre13Active, namedGroups)) + int count = candidates.length; + localSigSchemes = new ArrayList(count); + for (int i = 0; i < count; ++i) { - result.add(signatureSchemeInfo); + Integer candidate = Integers.valueOf(candidates[i]); + SignatureSchemeInfo signatureSchemeInfo = perContext.index.get(candidate); + + if (null != signatureSchemeInfo + && signatureSchemeInfo.isActiveCerts(algorithmConstraints, post13Active, pre13Active, namedGroups)) + { + localSigSchemes.add(signatureSchemeInfo); + } } + localSigSchemes.trimToSize(); } - if (result.isEmpty()) + + ArrayList localSigSchemesCert = null; + if (candidatesCert != null) { - return Collections.emptyList(); + int count = candidatesCert.length; + localSigSchemesCert = new ArrayList(count); + for (int i = 0; i < count; ++i) + { + Integer candidate = Integers.valueOf(candidatesCert[i]); + SignatureSchemeInfo signatureSchemeInfo = perContext.index.get(candidate); + + if (null != signatureSchemeInfo + && signatureSchemeInfo.isActiveCerts(algorithmConstraints, post13Active, pre13Active, namedGroups)) + { + localSigSchemesCert.add(signatureSchemeInfo); + } + } + localSigSchemesCert.trimToSize(); } - result.trimToSize(); - return Collections.unmodifiableList(result); + + return new PerConnection(localSigSchemes, localSigSchemesCert); } - static String[] getJcaSignatureAlgorithms(Collection infos) + static PerContext createPerContext(boolean isFipsContext, JcaTlsCrypto crypto, + NamedGroupInfo.PerContext namedGroups) + { + Map index = createIndex(isFipsContext, crypto, namedGroups); + + int[] candidatesClient = createCandidatesFromProperty(index, PROPERTY_CLIENT_SIGNATURE_SCHEMES); + int[] candidatesServer = createCandidatesFromProperty(index, PROPERTY_SERVER_SIGNATURE_SCHEMES); + + int[] candidatesCertClient = createCandidatesFromProperty(index, PROPERTY_CLIENT_SIGNATURE_SCHEMES_CERT); + int[] candidatesCertServer = createCandidatesFromProperty(index, PROPERTY_SERVER_SIGNATURE_SCHEMES_CERT); + + return new PerContext(index, candidatesClient, candidatesServer, candidatesCertClient, candidatesCertServer); + } + + private static String[] getJcaSignatureAlgorithms(Collection infos) { if (null == infos) { return TlsUtils.EMPTY_STRINGS; } - ArrayList result = new ArrayList(); + String[] result = new String[infos.size()]; + int resultPos = 0; for (SignatureSchemeInfo info : infos) { // TODO The two kinds of PSS signature scheme can give duplicates here - result.add(info.getJcaSignatureAlgorithm()); + result[resultPos++] = info.getJcaSignatureAlgorithm(); } - return result.toArray(TlsUtils.EMPTY_STRINGS); + return result; } - static String[] getJcaSignatureAlgorithmsBC(Collection infos) + private static String[] getJcaSignatureAlgorithmsBC(Collection infos) { if (null == infos) { return TlsUtils.EMPTY_STRINGS; } - ArrayList result = new ArrayList(); + String[] result = new String[infos.size()]; + int resultPos = 0; for (SignatureSchemeInfo info : infos) { - result.add(info.getJcaSignatureAlgorithmBC()); + result[resultPos++] = info.getJcaSignatureAlgorithmBC(); } - return result.toArray(TlsUtils.EMPTY_STRINGS); + return result; } static SignatureAndHashAlgorithm getSignatureAndHashAlgorithm(int signatureScheme) @@ -243,7 +403,8 @@ static SignatureAndHashAlgorithm getSignatureAndHashAlgorithm(int signatureSchem return SignatureScheme.getSignatureAndHashAlgorithm(signatureScheme); } - static Vector getSignatureAndHashAlgorithms(List signatureSchemeInfos) + private static Vector getSignatureAndHashAlgorithms( + Collection signatureSchemeInfos) { // TODO[tls13] Actually should return empty for empty? if (null == signatureSchemeInfos || signatureSchemeInfos.isEmpty()) @@ -352,14 +513,19 @@ private static void addSignatureScheme(boolean isFipsContext, JcaTlsCrypto crypt } } - private static int[] createCandidates(Map index, String propertyName) + private static int[] createCandidatesFromProperty(Map index, String propertyName) { String[] names = PropertyUtils.getStringArraySystemProperty(propertyName); if (null == names) { - return CANDIDATES_DEFAULT; + return null; } + return createCandidates(index, names, propertyName); + } + + private static int[] createCandidates(Map index, String[] names, String description) + { int[] result = new int[names.length]; int count = 0; for (String name : names) @@ -367,20 +533,20 @@ private static int[] createCandidates(Map index, S int signatureScheme = getSignatureSchemeByName(name); if (signatureScheme < 0) { - LOG.warning("'" + propertyName + "' contains unrecognised SignatureScheme: " + name); + LOG.warning("'" + description + "' contains unrecognised SignatureScheme: " + name); continue; } SignatureSchemeInfo signatureSchemeInfo = index.get(signatureScheme); if (null == signatureSchemeInfo) { - LOG.warning("'" + propertyName + "' contains unsupported SignatureScheme: " + name); + LOG.warning("'" + description + "' contains unsupported SignatureScheme: " + name); continue; } if (!signatureSchemeInfo.isEnabled()) { - LOG.warning("'" + propertyName + "' contains disabled SignatureScheme: " + name); + LOG.warning("'" + description + "' contains disabled SignatureScheme: " + name); continue; } @@ -392,7 +558,7 @@ private static int[] createCandidates(Map index, S } if (result.length < 1) { - LOG.severe("'" + propertyName + "' contained no usable SignatureScheme values"); + LOG.severe("'" + description + "' contained no usable SignatureScheme values"); } return result; } @@ -517,22 +683,6 @@ int getSignatureScheme() return all.signatureScheme; } - boolean isActive(BCAlgorithmConstraints algorithmConstraints, boolean post13Active, boolean pre13Active, - NamedGroupInfo.PerConnection namedGroupInfos) - { - return enabled - && isNamedGroupOK(post13Active && isSupportedPost13(), pre13Active && isSupportedPre13(), namedGroupInfos) - && isPermittedBy(algorithmConstraints); - } - - boolean isActiveCerts(BCAlgorithmConstraints algorithmConstraints, boolean post13Active, boolean pre13Active, - NamedGroupInfo.PerConnection namedGroupInfos) - { - return enabled - && isNamedGroupOK(post13Active && isSupportedCerts13(), pre13Active && isSupportedPre13(), namedGroupInfos) - && isPermittedBy(algorithmConstraints); - } - boolean isEnabled() { return enabled; @@ -559,6 +709,23 @@ public String toString() return all.text; } + // TODO Refactor to use this in non-cert contexts (careful for signatureSchemesCert defaulting case) +// private boolean isActive(BCAlgorithmConstraints algorithmConstraints, boolean post13Active, boolean pre13Active, +// NamedGroupInfo.PerConnection namedGroupInfos) +// { +// return enabled +// && isNamedGroupOK(post13Active && isSupportedPost13(), pre13Active && isSupportedPre13(), namedGroupInfos) +// && isPermittedBy(algorithmConstraints); +// } + + private boolean isActiveCerts(BCAlgorithmConstraints algorithmConstraints, boolean post13Active, + boolean pre13Active, NamedGroupInfo.PerConnection namedGroupInfos) + { + return enabled + && isNamedGroupOK(post13Active && isSupportedCerts13(), pre13Active && isSupportedPre13(), namedGroupInfos) + && isPermittedBy(algorithmConstraints); + } + private boolean isNamedGroupOK(boolean post13Allowed, boolean pre13Allowed, NamedGroupInfo.PerConnection namedGroupInfos) { if (null != namedGroupInfo) diff --git a/tls/src/main/java/org/bouncycastle/jsse/util/CustomSSLSocketFactory.java b/tls/src/main/java/org/bouncycastle/jsse/util/CustomSSLSocketFactory.java index 1700501a13..8f3347da8c 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/util/CustomSSLSocketFactory.java +++ b/tls/src/main/java/org/bouncycastle/jsse/util/CustomSSLSocketFactory.java @@ -54,7 +54,7 @@ public Socket createSocket(String host, int port, InetAddress localHost, int loc return configureSocket(delegate.createSocket(host, port, localHost, localPort)); } - @Override + // No @Override for 1.8 method public Socket createSocket(Socket s, InputStream consumed, boolean autoClose) throws IOException { return configureSocket(delegate.createSocket(s, consumed, autoClose)); diff --git a/tls/src/main/java/org/bouncycastle/jsse/util/SetHostSocketFactory.java b/tls/src/main/java/org/bouncycastle/jsse/util/SetHostSocketFactory.java new file mode 100644 index 0000000000..a4ff4d37b8 --- /dev/null +++ b/tls/src/main/java/org/bouncycastle/jsse/util/SetHostSocketFactory.java @@ -0,0 +1,81 @@ +package org.bouncycastle.jsse.util; + +import java.net.Socket; +import java.net.URL; +import java.util.concurrent.Callable; +import java.util.logging.Logger; + +import javax.net.SocketFactory; +import javax.net.ssl.SSLSocketFactory; + +import org.bouncycastle.jsse.BCSSLSocket; + +public class SetHostSocketFactory extends CustomSSLSocketFactory +{ + private static final Logger LOG = Logger.getLogger(SetHostSocketFactory.class.getName()); + + protected static final ThreadLocal threadLocal = new ThreadLocal(); + + /** + * Signature matches {@link SSLSocketFactory#getDefault()} so that it can be + * used with e.g. the "java.naming.ldap.factory.socket" property or similar. + * + * @see #call(Callable) + */ + public static SocketFactory getDefault() + { + SSLSocketFactory sslSocketFactory = threadLocal.get(); + if (null != sslSocketFactory) + { + return sslSocketFactory; + } + + return SSLSocketFactory.getDefault(); + } + + protected final String host; + + public SetHostSocketFactory(SSLSocketFactory delegate, URL url) + { + this(delegate, url == null ? null : url.getHost()); + } + + public SetHostSocketFactory(SSLSocketFactory delegate, String host) + { + super(delegate); + + this.host = host; + } + + /** + * Calls a {@link Callable} in a context where this class's static + * {@link #getDefault()} method will return this {@link SetHostSocketFactory}. + */ + public V call(Callable callable) throws Exception + { + try + { + threadLocal.set(this); + + return callable.call(); + } + finally + { + threadLocal.remove(); + } + } + + @Override + protected Socket configureSocket(Socket s) + { + if (host != null && s instanceof BCSSLSocket) + { + BCSSLSocket ssl = (BCSSLSocket)s; + + LOG.fine("Setting host on socket: " + host); + + ssl.setHost(host); + } + return s; + } +} diff --git a/tls/src/main/java/org/bouncycastle/jsse/util/URLConnectionUtil.java b/tls/src/main/java/org/bouncycastle/jsse/util/URLConnectionUtil.java index 63a7db5a0b..6eb4861f2d 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/util/URLConnectionUtil.java +++ b/tls/src/main/java/org/bouncycastle/jsse/util/URLConnectionUtil.java @@ -66,6 +66,6 @@ protected URLConnection configureConnection(URL url, URLConnection connection) protected SSLSocketFactory createSSLSocketFactory(SSLSocketFactory delegate, URL url) { - return new SNISocketFactory(delegate, url); + return new SetHostSocketFactory(delegate, url); } } diff --git a/tls/src/main/java/org/bouncycastle/tls/AbstractTlsClient.java b/tls/src/main/java/org/bouncycastle/tls/AbstractTlsClient.java index d8acd70c98..446eec9898 100644 --- a/tls/src/main/java/org/bouncycastle/tls/AbstractTlsClient.java +++ b/tls/src/main/java/org/bouncycastle/tls/AbstractTlsClient.java @@ -79,6 +79,19 @@ protected void checkForUnexpectedServerExtension(Hashtable serverExtensions, Int } } + /** + * RFC 9146 DTLS connection ID. + *

      + * The default {@link #getClientExtensions()} implementation calls this to get the connection_id extension the + * client will send. As future communication doesn't include the connection IDs length, this should either + * be fixed-length or include the connection ID's length. (see explanation in RFC 9146 4. "cid:") + * @return The connection ID to use. + */ + protected byte[] getNewConnectionID() + { + return null; + } + public TlsPSKIdentity getPSKIdentity() throws IOException { return null; @@ -243,11 +256,13 @@ public Hashtable getClientExtensions() boolean offeringTLSv13Plus = false; boolean offeringPreTLSv13 = false; + boolean offeringDTLSv12 = false; { ProtocolVersion[] supportedVersions = getProtocolVersions(); for (int i = 0; i < supportedVersions.length; ++i) { - if (TlsUtils.isTLSv13(supportedVersions[i])) + ProtocolVersion supportedVersion = supportedVersions[i]; + if (TlsUtils.isTLSv13(supportedVersion)) { offeringTLSv13Plus = true; } @@ -255,6 +270,8 @@ public Hashtable getClientExtensions() { offeringPreTLSv13 = true; } + + offeringDTLSv12 |= ProtocolVersion.DTLSv12.equals(supportedVersion); } } @@ -347,31 +364,43 @@ public Hashtable getClientExtensions() } } - /* - * RFC 7250 4.1: - * - * If the client has no remaining certificate types to send in - * the client hello, other than the default X.509 type, it MUST omit the - * client_certificate_type extension in the client hello. - */ - short[] clientCertTypes = getAllowedClientCertificateTypes(); - if (clientCertTypes != null && (clientCertTypes.length > 1 || clientCertTypes[0] != CertificateType.X509)) { - TlsExtensionsUtils.addClientCertificateTypeExtensionClient(clientExtensions, clientCertTypes); + /* + * RFC 7250 4.1. If the client has no remaining certificate types to send in the client hello, other than + * the default X.509 type, it MUST omit the client_certificate_type extension [..]. + */ + short[] clientCertTypes = getAllowedClientCertificateTypes(); + if (clientCertTypes != null && + TlsUtils.containsNot(clientCertTypes, 0, clientCertTypes.length, CertificateType.X509)) + { + TlsExtensionsUtils.addClientCertificateTypeExtensionClient(clientExtensions, clientCertTypes); + } } - /* - * RFC 7250 4.1: - * - * If the client has no remaining certificate types to send in - * the client hello, other than the default X.509 certificate type, it - * MUST omit the entire server_certificate_type extension from the - * client hello. - */ - short[] serverCertTypes = getAllowedServerCertificateTypes(); - if (serverCertTypes != null && (serverCertTypes.length > 1 || serverCertTypes[0] != CertificateType.X509)) { - TlsExtensionsUtils.addServerCertificateTypeExtensionClient(clientExtensions, serverCertTypes); + /* + * RFC 7250 4.1. If the client has no remaining certificate types to send in the client hello, other than + * the default X.509 certificate type, it MUST omit the entire server_certificate_type extension [..]. + */ + short[] serverCertTypes = getAllowedServerCertificateTypes(); + if (serverCertTypes != null && + TlsUtils.containsNot(serverCertTypes, 0, serverCertTypes.length, CertificateType.X509)) + { + TlsExtensionsUtils.addServerCertificateTypeExtensionClient(clientExtensions, serverCertTypes); + } + } + + if (offeringDTLSv12) + { + /* + * RFC 9146 3. When a DTLS session is resumed or renegotiated, the "connection_id" extension is + * negotiated afresh. + */ + byte[] clientConnectionID = getNewConnectionID(); + if (clientConnectionID != null) + { + TlsExtensionsUtils.addConnectionIDExtension(clientExtensions, clientConnectionID); + } } return clientExtensions; @@ -401,6 +430,11 @@ public Vector getEarlyKeyShareGroups() return TlsUtils.vectorOfOne(supportedGroups.elementAt(0)); } + public boolean shouldUseCompatibilityMode() + { + return true; + } + public void notifyServerVersion(ProtocolVersion serverVersion) throws IOException { diff --git a/tls/src/main/java/org/bouncycastle/tls/AbstractTlsPeer.java b/tls/src/main/java/org/bouncycastle/tls/AbstractTlsPeer.java index 99dd0e0bd4..f3e92e2760 100644 --- a/tls/src/main/java/org/bouncycastle/tls/AbstractTlsPeer.java +++ b/tls/src/main/java/org/bouncycastle/tls/AbstractTlsPeer.java @@ -62,6 +62,11 @@ public int getHandshakeTimeoutMillis() return 0; } + public int getHandshakeResendTimeMillis() + { + return 1000; + } + public boolean allowLegacyResumption() { return false; @@ -139,6 +144,10 @@ public void notifyAlertReceived(short alertLevel, short alertDescription) { } + public void notifyConnectionClosed() + { + } + public void notifyHandshakeComplete() throws IOException { } diff --git a/tls/src/main/java/org/bouncycastle/tls/AbstractTlsServer.java b/tls/src/main/java/org/bouncycastle/tls/AbstractTlsServer.java index df5f3b1349..1214988396 100644 --- a/tls/src/main/java/org/bouncycastle/tls/AbstractTlsServer.java +++ b/tls/src/main/java/org/bouncycastle/tls/AbstractTlsServer.java @@ -7,6 +7,7 @@ import org.bouncycastle.tls.crypto.TlsCrypto; import org.bouncycastle.tls.crypto.TlsDHConfig; import org.bouncycastle.tls.crypto.TlsECConfig; +import org.bouncycastle.util.Integers; /** * Base class for a TLS server. @@ -72,39 +73,65 @@ protected Hashtable checkServerExtensions() return serverExtensions; } + protected String getDetailMessageNoCipherSuite() + { + return "No selectable cipher suite"; + } + + protected int getMaximumDefaultCurveBits() + { + return NamedGroup.getCurveBits(NamedGroup.secp521r1); + } + + protected int getMaximumDefaultFiniteFieldBits() + { + return NamedGroup.getFiniteFieldBits(NamedGroup.ffdhe8192); + } + protected int getMaximumNegotiableCurveBits() { + int maxBits = 0; int[] clientSupportedGroups = context.getSecurityParametersHandshake().getClientSupportedGroups(); - if (clientSupportedGroups == null) + if (clientSupportedGroups != null) + { + for (int i = 0; i < clientSupportedGroups.length; ++i) + { + maxBits = Math.max(maxBits, NamedGroup.getCurveBits(clientSupportedGroups[i])); + } + } + else { /* * RFC 4492 4. A client that proposes ECC cipher suites may choose not to include these - * extensions. In this case, the server is free to choose any one of the elliptic curves - * or point formats [...]. + * extensions. In this case, the server is free to choose any one of the elliptic curves or point + * formats [...]. */ - return NamedGroup.getMaximumCurveBits(); - } - - int maxBits = 0; - for (int i = 0; i < clientSupportedGroups.length; ++i) - { - maxBits = Math.max(maxBits, NamedGroup.getCurveBits(clientSupportedGroups[i])); + maxBits = getMaximumDefaultCurveBits(); } return maxBits; } protected int getMaximumNegotiableFiniteFieldBits() { + int maxBits = 0; + boolean anyPeerFF = false; int[] clientSupportedGroups = context.getSecurityParametersHandshake().getClientSupportedGroups(); - if (clientSupportedGroups == null) + if (clientSupportedGroups != null) { - return NamedGroup.getMaximumFiniteFieldBits(); + for (int i = 0; i < clientSupportedGroups.length; ++i) + { + anyPeerFF |= NamedGroup.isFiniteField(clientSupportedGroups[i]); + maxBits = Math.max(maxBits, NamedGroup.getFiniteFieldBits(clientSupportedGroups[i])); + } } - - int maxBits = 0; - for (int i = 0; i < clientSupportedGroups.length; ++i) + if (!anyPeerFF) { - maxBits = Math.max(maxBits, NamedGroup.getFiniteFieldBits(clientSupportedGroups[i])); + /* + * RFC 7919 4. If [...] the Supported Groups extension is either absent from the ClientHello + * entirely or contains no FFDHE groups (i.e., no codepoints between 256 and 511, inclusive), then + * the server [...] MAY select an FFDHE cipher suite and offer an FFDHE group of its choice [...]. + */ + maxBits = getMaximumDefaultFiniteFieldBits(); } return maxBits; } @@ -136,22 +163,32 @@ protected boolean selectCipherSuite(int cipherSuite) throws IOException protected int selectDH(int minimumFiniteFieldBits) { + boolean anyPeerFF = false; int[] clientSupportedGroups = context.getSecurityParametersHandshake().getClientSupportedGroups(); - if (clientSupportedGroups == null) + if (clientSupportedGroups != null) { - return selectDHDefault(minimumFiniteFieldBits); - } - - // Try to find a supported named group of the required size from the client's list. - for (int i = 0; i < clientSupportedGroups.length; ++i) - { - int namedGroup = clientSupportedGroups[i]; - if (NamedGroup.getFiniteFieldBits(namedGroup) >= minimumFiniteFieldBits) + // Try to find a supported named group of the required size from the client's list. + for (int i = 0; i < clientSupportedGroups.length; ++i) { - return namedGroup; + int namedGroup = clientSupportedGroups[i]; + anyPeerFF |= NamedGroup.isFiniteField(namedGroup); + + if (NamedGroup.getFiniteFieldBits(namedGroup) >= minimumFiniteFieldBits) + { + // This default server implementation supports all NamedGroup finite fields + return namedGroup; + } } } - + if (!anyPeerFF) + { + /* + * RFC 7919 4. If [...] the Supported Groups extension is either absent from the ClientHello + * entirely or contains no FFDHE groups (i.e., no codepoints between 256 and 511, inclusive), then + * the server [...] MAY select an FFDHE cipher suite and offer an FFDHE group of its choice [...]. + */ + return selectDHDefault(minimumFiniteFieldBits); + } return -1; } @@ -170,6 +207,11 @@ protected int selectECDH(int minimumCurveBits) int[] clientSupportedGroups = context.getSecurityParametersHandshake().getClientSupportedGroups(); if (clientSupportedGroups == null) { + /* + * RFC 4492 4. A client that proposes ECC cipher suites may choose not to include these + * extensions. In this case, the server is free to choose any one of the elliptic curves or point + * formats [...]. + */ return selectECDHDefault(minimumCurveBits); } @@ -179,6 +221,7 @@ protected int selectECDH(int minimumCurveBits) int namedGroup = clientSupportedGroups[i]; if (NamedGroup.getCurveBits(namedGroup) >= minimumCurveBits) { + // This default server implementation supports all NamedGroup curves return namedGroup; } } @@ -239,6 +282,20 @@ protected short[] getAllowedClientCertificateTypes() return null; } + /** + * RFC 9146 DTLS connection ID. + *

      + * This method will be called if a connection_id extension was sent by the client. + * If the return value is non-null, the server will send this connection ID to the client to use in future packets. + * As future communication doesn't include the connection IDs length, this should either be fixed-length + * or include the connection ID's length. (see explanation in RFC 9146 4. "cid:") + * @return The connection ID to use. + */ + protected byte[] getNewConnectionID() + { + return null; + } + public void init(TlsServerContext context) { this.context = context; @@ -450,7 +507,7 @@ && selectCipherSuite(cipherSuite)) } } - throw new TlsFatalAlert(AlertDescription.handshake_failure, "No selectable cipher suite"); + throw new TlsFatalAlert(AlertDescription.handshake_failure, getDetailMessageNoCipherSuite()); } // Hashtable is (Integer -> byte[]) @@ -538,18 +595,29 @@ else if (null != this.certificateStatusRequest && allowCertificateStatus()) if (serverCertTypes != null) { TlsCredentials credentials = getCredentials(); - - if (credentials == null || - !TlsUtils.contains(serverCertTypes, 0, serverCertTypes.length, credentials.getCertificate().getCertificateType())) + if (credentials != null) { - // outcome 2: we support the extension but have no common types - throw new TlsFatalAlert(AlertDescription.unsupported_certificate); - } + // TODO An X509 certificate should still be usable as RawPublicKey + short serverCertificateType = credentials.getCertificate().getCertificateType(); - // outcome 3: we support the extension and have a common type - TlsExtensionsUtils.addServerCertificateTypeExtensionServer(serverExtensions, credentials.getCertificate().getCertificateType()); + if (CertificateType.OpenPGP == serverCertificateType && isTLSv13) + { + throw new TlsFatalAlert(AlertDescription.internal_error, + "The OpenPGP certificate type MUST NOT be used with TLS 1.3"); + } + + if (!TlsUtils.contains(serverCertTypes, 0, serverCertTypes.length, serverCertificateType)) + { + // outcome 2: we support the extension but have no common types + throw new TlsFatalAlert(AlertDescription.unsupported_certificate); + } + + // outcome 3: we support the extension and have a common type + TlsExtensionsUtils.addServerCertificateTypeExtensionServer(serverExtensions, serverCertificateType); + } } + // TODO If we won't be sending a CertificateRequest, this extension can be ignored // RFC 7250 4.2 for client_certificate_type short[] remoteClientCertTypes = TlsExtensionsUtils.getClientCertificateTypeExtensionClient(clientExtensions); if (remoteClientCertTypes != null) @@ -573,13 +641,20 @@ else if (null != this.certificateStatusRequest && allowCertificateStatus()) short selectedType = -1; for (int i = 0; i < preferredTypes.length; i++) { - if (TlsUtils.contains(nonPreferredTypes, 0, nonPreferredTypes.length, preferredTypes[i])) + short preferredType = preferredTypes[i]; + if (CertificateType.OpenPGP == preferredType && isTLSv13) { - selectedType = preferredTypes[i]; + continue; + } + + if (TlsUtils.contains(nonPreferredTypes, 0, nonPreferredTypes.length, preferredType)) + { + selectedType = preferredType; break; } } + // TODO Shouldn't be an error unless we REQUIRE client authentication if (selectedType == -1) { // outcome 2: we support the extension but have no common types @@ -617,6 +692,22 @@ public void getServerExtensionsForConnection(Hashtable serverExtensions) throws { TlsExtensionsUtils.addALPNExtensionServer(serverExtensions, selectedProtocolName); } + + if (ProtocolVersion.DTLSv12.equals(context.getServerVersion())) + { + /* + * RFC 9146 3. When a DTLS session is resumed or renegotiated, the "connection_id" extension is + * negotiated afresh. + */ + if (clientExtensions != null && clientExtensions.containsKey(Integers.valueOf(ExtensionType.connection_id))) + { + byte[] serverConnectionID = getNewConnectionID(); + if (serverConnectionID != null) + { + TlsExtensionsUtils.addConnectionIDExtension(serverExtensions, serverConnectionID); + } + } + } } public Vector getServerSupplementalData() diff --git a/tls/src/main/java/org/bouncycastle/tls/ByteQueue.java b/tls/src/main/java/org/bouncycastle/tls/ByteQueue.java index 3288de7cfc..9c9a4fa199 100644 --- a/tls/src/main/java/org/bouncycastle/tls/ByteQueue.java +++ b/tls/src/main/java/org/bouncycastle/tls/ByteQueue.java @@ -203,6 +203,16 @@ public int readInt32() return TlsUtils.readInt32(databuf, skipped); } + public short readUint8(int skip) + { + if (available < skip + 1) + { + throw new IllegalStateException("Not enough data to read"); + } + + return TlsUtils.readUint8(databuf, skipped + skip); + } + public int readUint16(int skip) { if (available < skip + 2) diff --git a/tls/src/main/java/org/bouncycastle/tls/CertificateRequest.java b/tls/src/main/java/org/bouncycastle/tls/CertificateRequest.java index ca9cc53e43..f5dc25c3d4 100644 --- a/tls/src/main/java/org/bouncycastle/tls/CertificateRequest.java +++ b/tls/src/main/java/org/bouncycastle/tls/CertificateRequest.java @@ -31,8 +31,8 @@ * Revised for RFC 8446: *

        * struct {
      - *     opaque certificate_request_context<0..2^8-1>;
      - *     Extension extensions<2..2^16-1>;
      + *     opaque certificate_request_context<0..2^8-1>;
      + *     Extension extensions<2..2^16-1>;
        * } CertificateRequest;
        * 
      * diff --git a/tls/src/main/java/org/bouncycastle/tls/CertificateType.java b/tls/src/main/java/org/bouncycastle/tls/CertificateType.java index ea1dded2d9..7bc524cd28 100644 --- a/tls/src/main/java/org/bouncycastle/tls/CertificateType.java +++ b/tls/src/main/java/org/bouncycastle/tls/CertificateType.java @@ -7,9 +7,14 @@ public class CertificateType { public static final short X509 = 0; public static final short OpenPGP = 1; - + /* * RFC 7250 */ public static final short RawPublicKey = 2; + + public static boolean isValid(short certificateType) + { + return certificateType >= X509 && certificateType <= RawPublicKey; + } } diff --git a/tls/src/main/java/org/bouncycastle/tls/CipherSuite.java b/tls/src/main/java/org/bouncycastle/tls/CipherSuite.java index c4938e1562..42b1e38de7 100644 --- a/tls/src/main/java/org/bouncycastle/tls/CipherSuite.java +++ b/tls/src/main/java/org/bouncycastle/tls/CipherSuite.java @@ -452,7 +452,7 @@ public static boolean isSCSV(int cipherSuite) public static final int TLS_SM4_CCM_SM3 = 0x00C7; /* - * draft-smyshlyaev-tls12-gost-suites-10 + * RFC 9189 */ public static final int TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC = 0xC100; public static final int TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC = 0xC101; diff --git a/tls/src/main/java/org/bouncycastle/tls/ClientCertificateType.java b/tls/src/main/java/org/bouncycastle/tls/ClientCertificateType.java index 125142984b..b4130b7978 100644 --- a/tls/src/main/java/org/bouncycastle/tls/ClientCertificateType.java +++ b/tls/src/main/java/org/bouncycastle/tls/ClientCertificateType.java @@ -21,7 +21,7 @@ public class ClientCertificateType public static final short ecdsa_fixed_ecdh = 66; /* - * draft-smyshlyaev-tls12-gost-suites-10 + * RFC 9189 */ public static final short gost_sign256 = 67; public static final short gost_sign512 = 68; diff --git a/tls/src/main/java/org/bouncycastle/tls/ContentType.java b/tls/src/main/java/org/bouncycastle/tls/ContentType.java index cb3575f670..0ed5167555 100644 --- a/tls/src/main/java/org/bouncycastle/tls/ContentType.java +++ b/tls/src/main/java/org/bouncycastle/tls/ContentType.java @@ -10,6 +10,7 @@ public class ContentType public static final short handshake = 22; public static final short application_data = 23; public static final short heartbeat = 24; + public static final short tls12_cid = 25; public static String getName(short contentType) { @@ -25,6 +26,8 @@ public static String getName(short contentType) return "handshake"; case heartbeat: return "heartbeat"; + case tls12_cid: + return "tls12_cid"; default: return "UNKNOWN"; } diff --git a/tls/src/main/java/org/bouncycastle/tls/DTLSClientProtocol.java b/tls/src/main/java/org/bouncycastle/tls/DTLSClientProtocol.java index eb58742486..e3bce90b85 100644 --- a/tls/src/main/java/org/bouncycastle/tls/DTLSClientProtocol.java +++ b/tls/src/main/java/org/bouncycastle/tls/DTLSClientProtocol.java @@ -7,6 +7,7 @@ import java.util.Hashtable; import java.util.Vector; +import org.bouncycastle.tls.crypto.TlsCrypto; import org.bouncycastle.tls.crypto.TlsSecret; import org.bouncycastle.tls.crypto.TlsStreamSigner; import org.bouncycastle.util.Arrays; @@ -31,43 +32,19 @@ public DTLSTransport connect(TlsClient client, DatagramTransport transport) throw new IllegalArgumentException("'transport' cannot be null"); } + TlsClientContextImpl clientContext = new TlsClientContextImpl(client.getCrypto()); + ClientHandshakeState state = new ClientHandshakeState(); state.client = client; - state.clientContext = new TlsClientContextImpl(client.getCrypto()); + state.clientContext = clientContext; - client.init(state.clientContext); - state.clientContext.handshakeBeginning(client); + client.init(clientContext); + clientContext.handshakeBeginning(client); - SecurityParameters securityParameters = state.clientContext.getSecurityParametersHandshake(); + SecurityParameters securityParameters = clientContext.getSecurityParametersHandshake(); securityParameters.extendedPadding = client.shouldUseExtendedPadding(); - TlsSession sessionToResume = state.client.getSessionToResume(); - if (sessionToResume != null && sessionToResume.isResumable()) - { - SessionParameters sessionParameters = sessionToResume.exportSessionParameters(); - - /* - * NOTE: If we ever enable session resumption without extended_master_secret, then - * renegotiation MUST be disabled (see RFC 7627 5.4). - */ - if (sessionParameters != null - && (sessionParameters.isExtendedMasterSecret() - || (!state.client.requiresExtendedMasterSecret() && state.client.allowLegacyResumption()))) - { - TlsSecret masterSecret = sessionParameters.getMasterSecret(); - synchronized (masterSecret) - { - if (masterSecret.isAlive()) - { - state.tlsSession = sessionToResume; - state.sessionParameters = sessionParameters; - state.sessionMasterSecret = state.clientContext.getCrypto().adoptSecret(masterSecret); - } - } - } - } - - DTLSRecordLayer recordLayer = new DTLSRecordLayer(state.clientContext, state.client, transport); + DTLSRecordLayer recordLayer = new DTLSRecordLayer(clientContext, client, transport); client.notifyCloseHandle(recordLayer); try @@ -104,9 +81,12 @@ protected void abortClientHandshake(ClientHandshakeState state, DTLSRecordLayer protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLayer recordLayer) throws IOException { - SecurityParameters securityParameters = state.clientContext.getSecurityParametersHandshake(); - DTLSReliableHandshake handshake = new DTLSReliableHandshake(state.clientContext, recordLayer, - state.client.getHandshakeTimeoutMillis(), null); + TlsClient client = state.client; + TlsClientContextImpl clientContext = state.clientContext; + SecurityParameters securityParameters = clientContext.getSecurityParametersHandshake(); + + DTLSReliableHandshake handshake = new DTLSReliableHandshake(clientContext, recordLayer, + client.getHandshakeTimeoutMillis(), client.getHandshakeResendTimeMillis(), null); byte[] clientHelloBody = generateClientHello(state); @@ -136,6 +116,8 @@ protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLa recordLayer.setWriteVersion(recordLayerVersion); processServerHello(state, serverMessage.getBody()); + + applyMaxFragmentLengthExtension(recordLayer, securityParameters.getMaxFragmentLength()); } else { @@ -144,20 +126,19 @@ protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLa handshake.getHandshakeHash().notifyPRFDetermined(); - applyMaxFragmentLengthExtension(recordLayer, securityParameters.getMaxFragmentLength()); - - if (state.resumedSession) + if (securityParameters.isResumedSession()) { securityParameters.masterSecret = state.sessionMasterSecret; - recordLayer.initPendingEpoch(TlsUtils.initCipher(state.clientContext)); + recordLayer.initPendingEpoch(TlsUtils.initCipher(clientContext)); // NOTE: Calculated exclusive of the actual Finished message from the server - securityParameters.peerVerifyData = TlsUtils.calculateVerifyData(state.clientContext, + securityParameters.peerVerifyData = TlsUtils.calculateVerifyData(clientContext, handshake.getHandshakeHash(), true); - processFinished(handshake.receiveMessageBody(HandshakeType.finished), securityParameters.getPeerVerifyData()); + processFinished(handshake.receiveMessageBody(HandshakeType.finished), + securityParameters.getPeerVerifyData()); // NOTE: Calculated exclusive of the Finished message itself - securityParameters.localVerifyData = TlsUtils.calculateVerifyData(state.clientContext, + securityParameters.localVerifyData = TlsUtils.calculateVerifyData(clientContext, handshake.getHandshakeHash(), false); handshake.sendMessage(HandshakeType.finished, securityParameters.getLocalVerifyData()); @@ -173,7 +154,7 @@ protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLa securityParameters.pskIdentity = state.sessionParameters.getPSKIdentity(); securityParameters.srpIdentity = state.sessionParameters.getSRPIdentity(); - state.clientContext.handshakeComplete(state.client, state.tlsSession); + clientContext.handshakeComplete(client, state.tlsSession); recordLayer.initHeartbeat(state.heartbeat, HeartbeatMode.peer_allowed_to_send == state.heartbeatPolicy); @@ -192,10 +173,10 @@ protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLa } else { - state.client.processServerSupplementalData(null); + client.processServerSupplementalData(null); } - state.keyExchange = TlsUtils.initKeyExchangeClient(state.clientContext, state.client); + state.keyExchange = TlsUtils.initKeyExchangeClient(clientContext, client); if (serverMessage.getType() == HandshakeType.certificate) { @@ -223,7 +204,7 @@ protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLa // Okay, CertificateStatus is optional } - TlsUtils.processServerCertificate(state.clientContext, state.certificateStatus, state.keyExchange, + TlsUtils.processServerCertificate(clientContext, state.certificateStatus, state.keyExchange, state.authentication, state.clientExtensions, state.serverExtensions); if (serverMessage.getType() == HandshakeType.server_key_exchange) @@ -312,7 +293,7 @@ protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLa state.keyExchange.processClientCredentials(clientAuthCredentials); } - Vector clientSupplementalData = state.client.getClientSupplementalData(); + Vector clientSupplementalData = client.getClientSupplementalData(); if (clientSupplementalData != null) { byte[] supplementalDataBody = generateSupplementalData(clientSupplementalData); @@ -321,7 +302,7 @@ protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLa if (null != state.certificateRequest) { - sendCertificateMessage(state.clientContext, handshake, clientAuthCertificate, null); + sendCertificateMessage(clientContext, handshake, clientAuthCertificate, null); } byte[] clientKeyExchangeBody = generateClientKeyExchange(state); @@ -329,12 +310,12 @@ protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLa securityParameters.sessionHash = TlsUtils.getCurrentPRFHash(handshake.getHandshakeHash()); - TlsProtocol.establishMasterSecret(state.clientContext, state.keyExchange); - recordLayer.initPendingEpoch(TlsUtils.initCipher(state.clientContext)); + TlsProtocol.establishMasterSecret(clientContext, state.keyExchange); + recordLayer.initPendingEpoch(TlsUtils.initCipher(clientContext)); if (clientAuthSigner != null) { - DigitallySigned certificateVerify = TlsUtils.generateCertificateVerifyClient(state.clientContext, + DigitallySigned certificateVerify = TlsUtils.generateCertificateVerifyClient(clientContext, clientAuthSigner, clientAuthAlgorithm, clientAuthStreamSigner, handshake.getHandshakeHash()); byte[] certificateVerifyBody = generateCertificateVerify(state, certificateVerify); handshake.sendMessage(HandshakeType.certificate_verify, certificateVerifyBody); @@ -342,8 +323,8 @@ protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLa handshake.prepareToFinish(); - securityParameters.localVerifyData = TlsUtils.calculateVerifyData(state.clientContext, - handshake.getHandshakeHash(), false); + securityParameters.localVerifyData = TlsUtils.calculateVerifyData(clientContext, handshake.getHandshakeHash(), + false); handshake.sendMessage(HandshakeType.finished, securityParameters.getLocalVerifyData()); if (state.expectSessionTicket) @@ -368,8 +349,8 @@ protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLa } // NOTE: Calculated exclusive of the actual Finished message from the server - securityParameters.peerVerifyData = TlsUtils.calculateVerifyData(state.clientContext, - handshake.getHandshakeHash(), true); + securityParameters.peerVerifyData = TlsUtils.calculateVerifyData(clientContext, handshake.getHandshakeHash(), + true); processFinished(handshake.receiveMessageBody(HandshakeType.finished), securityParameters.getPeerVerifyData()); handshake.finish(); @@ -378,10 +359,9 @@ protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLa state.sessionParameters = new SessionParameters.Builder() .setCipherSuite(securityParameters.getCipherSuite()) - .setCompressionAlgorithm(securityParameters.getCompressionAlgorithm()) .setExtendedMasterSecret(securityParameters.isExtendedMasterSecret()) .setLocalCertificate(securityParameters.getLocalCertificate()) - .setMasterSecret(state.clientContext.getCrypto().adoptSecret(state.sessionMasterSecret)) + .setMasterSecret(clientContext.getCrypto().adoptSecret(state.sessionMasterSecret)) .setNegotiatedVersion(securityParameters.getNegotiatedVersion()) .setPeerCertificate(securityParameters.getPeerCertificate()) .setPSKIdentity(securityParameters.getPSKIdentity()) @@ -394,7 +374,7 @@ protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLa securityParameters.tlsUnique = securityParameters.getLocalVerifyData(); - state.clientContext.handshakeComplete(state.client, state.tlsSession); + clientContext.handshakeComplete(client, state.tlsSession); recordLayer.initHeartbeat(state.heartbeat, HeartbeatMode.peer_allowed_to_send == state.heartbeatPolicy); @@ -412,75 +392,129 @@ protected byte[] generateCertificateVerify(ClientHandshakeState state, Digitally protected byte[] generateClientHello(ClientHandshakeState state) throws IOException { - TlsClientContextImpl context = state.clientContext; - SecurityParameters securityParameters = context.getSecurityParametersHandshake(); + TlsClient client = state.client; + TlsClientContextImpl clientContext = state.clientContext; + SecurityParameters securityParameters = clientContext.getSecurityParametersHandshake(); + + ProtocolVersion[] supportedVersions = client.getProtocolVersions(); - context.setClientSupportedVersions(state.client.getProtocolVersions()); + ProtocolVersion earliestVersion = ProtocolVersion.getEarliestDTLS(supportedVersions); + ProtocolVersion latestVersion = ProtocolVersion.getLatestDTLS(supportedVersions); - ProtocolVersion client_version = ProtocolVersion.getLatestDTLS(context.getClientSupportedVersions()); - if (!ProtocolVersion.isSupportedDTLSVersionClient(client_version)) + if (!ProtocolVersion.isSupportedDTLSVersionClient(latestVersion)) { throw new TlsFatalAlert(AlertDescription.internal_error); } - context.setClientVersion(client_version); + clientContext.setClientVersion(latestVersion); + clientContext.setClientSupportedVersions(supportedVersions); + + boolean offeringDTLSv12Minus = ProtocolVersion.DTLSv12.isEqualOrLaterVersionOf(earliestVersion); + boolean offeringDTLSv13Plus = ProtocolVersion.DTLSv13.isEqualOrEarlierVersionOf(latestVersion); { - boolean useGMTUnixTime = ProtocolVersion.DTLSv12.isEqualOrLaterVersionOf(client_version) - && state.client.shouldUseGMTUnixTime(); + boolean useGMTUnixTime = !offeringDTLSv13Plus && client.shouldUseGMTUnixTime(); - securityParameters.clientRandom = TlsProtocol.createRandomBlock(useGMTUnixTime, state.clientContext); + securityParameters.clientRandom = TlsProtocol.createRandomBlock(useGMTUnixTime, clientContext); } - byte[] session_id = TlsUtils.getSessionID(state.tlsSession); + TlsSession sessionToResume = offeringDTLSv12Minus ? client.getSessionToResume() : null; - boolean fallback = state.client.isFallback(); + boolean fallback = client.isFallback(); - state.offeredCipherSuites = state.client.getCipherSuites(); + state.offeredCipherSuites = client.getCipherSuites(); - if (session_id.length > 0 && state.sessionParameters != null) + state.clientExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(client.getClientExtensions()); + + final boolean shouldUseEMS = client.shouldUseExtendedMasterSecret(); + + establishSession(state, sessionToResume); + + byte[] legacy_session_id = TlsUtils.getSessionID(state.tlsSession); + + if (legacy_session_id.length > 0) { - if (!Arrays.contains(state.offeredCipherSuites, state.sessionParameters.getCipherSuite()) - || CompressionMethod._null != state.sessionParameters.getCompressionAlgorithm()) + if (!Arrays.contains(state.offeredCipherSuites, state.sessionParameters.getCipherSuite())) { - session_id = TlsUtils.EMPTY_BYTES; + legacy_session_id = TlsUtils.EMPTY_BYTES; } } - state.clientExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(state.client.getClientExtensions()); + ProtocolVersion sessionVersion = null; + if (legacy_session_id.length > 0) + { + sessionVersion = state.sessionParameters.getNegotiatedVersion(); - ProtocolVersion legacy_version = client_version; - if (client_version.isLaterVersionOf(ProtocolVersion.DTLSv12)) + if (!ProtocolVersion.contains(supportedVersions, sessionVersion)) + { + legacy_session_id = TlsUtils.EMPTY_BYTES; + } + } + + if (legacy_session_id.length > 0 && TlsUtils.isExtendedMasterSecretOptional(sessionVersion)) + { + if (shouldUseEMS) + { + if (!state.sessionParameters.isExtendedMasterSecret() && + !client.allowLegacyResumption()) + { + legacy_session_id = TlsUtils.EMPTY_BYTES; + } + } + else + { + if (state.sessionParameters.isExtendedMasterSecret()) + { + legacy_session_id = TlsUtils.EMPTY_BYTES; + } + } + } + + if (legacy_session_id.length < 1) + { + cancelSession(state); + } + + client.notifySessionToResume(state.tlsSession); + + ProtocolVersion legacy_version = latestVersion; + if (offeringDTLSv13Plus) { legacy_version = ProtocolVersion.DTLSv12; - TlsExtensionsUtils.addSupportedVersionsExtensionClient(state.clientExtensions, - context.getClientSupportedVersions()); + TlsExtensionsUtils.addSupportedVersionsExtensionClient(state.clientExtensions, supportedVersions); + + /* + * RFC 9147 5. DTLS implementations do not use the TLS 1.3 "compatibility mode" [..]. + */ } - context.setRSAPreMasterSecretVersion(legacy_version); + clientContext.setRSAPreMasterSecretVersion(legacy_version); securityParameters.clientServerNames = TlsExtensionsUtils.getServerNameExtensionClient(state.clientExtensions); - if (TlsUtils.isSignatureAlgorithmsExtensionAllowed(client_version)) + if (TlsUtils.isSignatureAlgorithmsExtensionAllowed(latestVersion)) { TlsUtils.establishClientSigAlgs(securityParameters, state.clientExtensions); } securityParameters.clientSupportedGroups = TlsExtensionsUtils.getSupportedGroupsExtension(state.clientExtensions); - state.clientAgreements = TlsUtils.addKeyShareToClientHello(state.clientContext, state.client, - state.clientExtensions); + // TODO[dtls13] +// state.clientBinders = TlsUtils.addPreSharedKeyToClientHello(clientContext, client, state.clientExtensions, +// state.offeredCipherSuites); + state.clientBinders = null; + + // TODO[tls13-psk] Perhaps don't add key_share if external PSK(s) offered and 'psk_dhe_ke' not offered + state.clientAgreements = TlsUtils.addKeyShareToClientHello(clientContext, client, state.clientExtensions); - if (TlsUtils.isExtendedMasterSecretOptionalDTLS(context.getClientSupportedVersions()) - && state.client.shouldUseExtendedMasterSecret()) + if (shouldUseEMS && TlsUtils.isExtendedMasterSecretOptional(supportedVersions)) { TlsExtensionsUtils.addExtendedMasterSecretExtension(state.clientExtensions); } - else if (!TlsUtils.isTLSv13(client_version) - && state.client.requiresExtendedMasterSecret()) + else { - throw new TlsFatalAlert(AlertDescription.internal_error); + state.clientExtensions.remove(TlsExtensionsUtils.EXT_extended_master_secret); } // Cipher Suites (and SCSV) @@ -513,8 +547,8 @@ else if (!TlsUtils.isTLSv13(client_version) // Heartbeats { - state.heartbeat = state.client.getHeartbeat(); - state.heartbeatPolicy = state.client.getHeartbeatPolicy(); + state.heartbeat = client.getHeartbeat(); + state.heartbeatPolicy = client.getHeartbeatPolicy(); if (null != state.heartbeat || HeartbeatMode.peer_allowed_to_send == state.heartbeatPolicy) { @@ -524,11 +558,17 @@ else if (!TlsUtils.isTLSv13(client_version) - ClientHello clientHello = new ClientHello(legacy_version, securityParameters.getClientRandom(), session_id, - TlsUtils.EMPTY_BYTES, state.offeredCipherSuites, state.clientExtensions, 0); + int bindersSize = null == state.clientBinders ? 0 : state.clientBinders.bindersSize; + + ClientHello clientHello = new ClientHello(legacy_version, securityParameters.getClientRandom(), + legacy_session_id, TlsUtils.EMPTY_BYTES, state.offeredCipherSuites, state.clientExtensions, bindersSize); + /* + * TODO[dtls13] See TlsClientProtocol.sendClientHelloMessage for how to prepare/encode binders and also consider + * the impact of binders on cookie patching after HelloVerifyRequest. + */ ByteArrayOutputStream buf = new ByteArrayOutputStream(); - clientHello.encode(state.clientContext, buf); + clientHello.encode(clientContext, buf); return buf.toByteArray(); } @@ -540,7 +580,7 @@ protected byte[] generateClientKeyExchange(ClientHandshakeState state) return buf.toByteArray(); } - protected void invalidateSession(ClientHandshakeState state) + protected void cancelSession(ClientHandshakeState state) { if (state.sessionMasterSecret != null) { @@ -554,11 +594,60 @@ protected void invalidateSession(ClientHandshakeState state) state.sessionParameters = null; } + state.tlsSession = null; + } + + protected boolean establishSession(ClientHandshakeState state, TlsSession sessionToResume) + { + state.tlsSession = null; + state.sessionParameters = null; + state.sessionMasterSecret = null; + + if (null == sessionToResume || !sessionToResume.isResumable()) + { + return false; + } + + SessionParameters sessionParameters = sessionToResume.exportSessionParameters(); + if (null == sessionParameters) + { + return false; + } + + ProtocolVersion sessionVersion = sessionParameters.getNegotiatedVersion(); + if (null == sessionVersion || !sessionVersion.isDTLS()) + { + return false; + } + + if (!sessionParameters.isExtendedMasterSecret() && + !TlsUtils.isExtendedMasterSecretOptional(sessionVersion)) + { + return false; + } + + TlsCrypto crypto = state.clientContext.getCrypto(); + TlsSecret sessionMasterSecret = TlsUtils.getSessionMasterSecret(crypto, sessionParameters.getMasterSecret()); + if (null == sessionMasterSecret) + { + return false; + } + + state.tlsSession = sessionToResume; + state.sessionParameters = sessionParameters; + state.sessionMasterSecret = sessionMasterSecret; + + return true; + } + + protected void invalidateSession(ClientHandshakeState state) + { if (state.tlsSession != null) { state.tlsSession.invalidate(); - state.tlsSession = null; } + + cancelSession(state); } protected void processCertificateRequest(ClientHandshakeState state, byte[] body) throws IOException @@ -579,9 +668,6 @@ protected void processCertificateRequest(ClientHandshakeState state, byte[] body TlsProtocol.assertEmpty(buf); state.certificateRequest = TlsUtils.validateCertificateRequest(certificateRequest, state.keyExchange); - - state.clientContext.getSecurityParametersHandshake().clientCertificateType = - TlsExtensionsUtils.getClientCertificateTypeExtensionServer(state.serverExtensions, CertificateType.X509); } protected void processCertificateStatus(ClientHandshakeState state, byte[] body) @@ -644,24 +730,60 @@ protected void processServerCertificate(ClientHandshakeState state, byte[] body) protected void processServerHello(ClientHandshakeState state, byte[] body) throws IOException { - ByteArrayInputStream buf = new ByteArrayInputStream(body); + TlsClient client = state.client; + TlsClientContextImpl clientContext = state.clientContext; + SecurityParameters securityParameters = clientContext.getSecurityParametersHandshake(); + ByteArrayInputStream buf = new ByteArrayInputStream(body); ServerHello serverHello = ServerHello.parse(buf); - ProtocolVersion server_version = serverHello.getVersion(); - state.serverExtensions = serverHello.getExtensions(); + Hashtable serverHelloExtensions = serverHello.getExtensions(); + ProtocolVersion legacy_version = serverHello.getVersion(); + ProtocolVersion supported_version = TlsExtensionsUtils.getSupportedVersionsExtensionServer( + serverHelloExtensions); + ProtocolVersion server_version; + if (null == supported_version) + { + server_version = legacy_version; + } + else + { + if (!ProtocolVersion.DTLSv12.equals(legacy_version) || + !ProtocolVersion.DTLSv13.isEqualOrEarlierVersionOf(supported_version)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } - SecurityParameters securityParameters = state.clientContext.getSecurityParametersHandshake(); + server_version = supported_version; + } - // TODO[dtls13] Check supported_version extension for negotiated version + // NOT renegotiating + { + reportServerVersion(state, server_version); + } + + // NOTE: This is integrated into reportServerVersion call above +// TlsUtils.negotiatedVersionDTLSClient(clientContext, state.client); - reportServerVersion(state, server_version); + // TODO[dtls13] +// if (ProtocolVersion.DTLSv13.isEqualOrEarlierVersionOf(server_version)) +// { +// process13ServerHello(serverHello, false); +// return; +// } + + int[] offeredCipherSuites = state.offeredCipherSuites; + + // TODO[dtls13] +// state.clientHello = null; +// state.retryCookie = null; +// state.retryGroup = -1; securityParameters.serverRandom = serverHello.getRandom(); - if (!state.clientContext.getClientVersion().equals(server_version)) + if (!clientContext.getClientVersion().equals(server_version)) { TlsUtils.checkDowngradeMarker(server_version, securityParameters.getServerRandom()); } @@ -669,9 +791,19 @@ protected void processServerHello(ClientHandshakeState state, byte[] body) { byte[] selectedSessionID = serverHello.getSessionID(); securityParameters.sessionID = selectedSessionID; - state.client.notifySessionID(selectedSessionID); - state.resumedSession = selectedSessionID.length > 0 && state.tlsSession != null + client.notifySessionID(selectedSessionID); + securityParameters.resumedSession = selectedSessionID.length > 0 && state.tlsSession != null && Arrays.areEqual(selectedSessionID, state.tlsSession.getSessionID()); + + if (securityParameters.isResumedSession()) + { + if (serverHello.getCipherSuite() != state.sessionParameters.getCipherSuite() || + !securityParameters.getNegotiatedVersion().equals(state.sessionParameters.getNegotiatedVersion())) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, + "ServerHello parameters do not match resumed session"); + } + } } /* @@ -682,65 +814,15 @@ protected void processServerHello(ClientHandshakeState state, byte[] body) int cipherSuite = validateSelectedCipherSuite(serverHello.getCipherSuite(), AlertDescription.illegal_parameter); - if (!TlsUtils.isValidCipherSuiteSelection(state.offeredCipherSuites, cipherSuite) || + if (!TlsUtils.isValidCipherSuiteSelection(offeredCipherSuites, cipherSuite) || !TlsUtils.isValidVersionForCipherSuite(cipherSuite, securityParameters.getNegotiatedVersion())) { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); + throw new TlsFatalAlert(AlertDescription.illegal_parameter, + "ServerHello selected invalid cipher suite"); } TlsUtils.negotiatedCipherSuite(securityParameters, cipherSuite); - state.client.notifySelectedCipherSuite(cipherSuite); - } - - /* - * RFC3546 2.2 The extended server hello message format MAY be sent in place of the server - * hello message when the client has requested extended functionality via the extended - * client hello message specified in Section 2.1. ... Note that the extended server hello - * message is only sent in response to an extended client hello message. This prevents the - * possibility that the extended server hello message could "break" existing TLS 1.0 - * clients. - */ - - /* - * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore - * extensions appearing in the client hello, and send a server hello containing no - * extensions. - */ - - /* - * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended - * master secret [..]. (and see 5.2, 5.3) - * - * RFC 8446 Appendix D. Because TLS 1.3 always hashes in the transcript up to the server - * Finished, implementations which support both TLS 1.3 and earlier versions SHOULD indicate - * the use of the Extended Master Secret extension in their APIs whenever TLS 1.3 is used. - */ - if (TlsUtils.isTLSv13(server_version)) - { - securityParameters.extendedMasterSecret = true; - } - else - { - final boolean acceptedExtendedMasterSecret = TlsExtensionsUtils.hasExtendedMasterSecretExtension( - state.serverExtensions); - - if (acceptedExtendedMasterSecret) - { - if (!state.resumedSession && !state.client.shouldUseExtendedMasterSecret()) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - } - else - { - if (state.client.requiresExtendedMasterSecret() - || (state.resumedSession && !state.client.allowLegacyResumption())) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - } - - securityParameters.extendedMasterSecret = acceptedExtendedMasterSecret; + client.notifySelectedCipherSuite(cipherSuite); } /* @@ -749,9 +831,10 @@ protected void processServerHello(ClientHandshakeState state, byte[] body) * extended client hello message. However, see RFC 5746 exception below. We always include * the SCSV, so an Extended Server Hello is always allowed. */ - if (state.serverExtensions != null) + state.serverExtensions = serverHelloExtensions; + if (serverHelloExtensions != null) { - Enumeration e = state.serverExtensions.keys(); + Enumeration e = serverHelloExtensions.keys(); while (e.hasMoreElements()) { Integer extType = (Integer)e.nextElement(); @@ -785,7 +868,7 @@ protected void processServerHello(ClientHandshakeState state, byte[] body) * extensions appearing in the client hello, and send a server hello containing no * extensions[.] */ - if (state.resumedSession) + if (securityParameters.isResumedSession()) { // TODO[compat-gnutls] GnuTLS test server sends server extensions e.g. ec_point_formats // TODO[compat-openssl] OpenSSL test server sends server extensions e.g. ec_point_formats @@ -795,16 +878,29 @@ protected void processServerHello(ClientHandshakeState state, byte[] body) } } - /* - * RFC 5746 3.4. Client Behavior: Initial Handshake - */ + byte[] renegExtData = TlsUtils.getExtensionData(serverHelloExtensions, TlsProtocol.EXT_RenegotiationInfo); + + // NOT renegotiating { + /* + * RFC 5746 3.4. Client Behavior: Initial Handshake (both full and session-resumption) + */ + /* * When a ServerHello is received, the client MUST check if it includes the * "renegotiation_info" extension: */ - byte[] renegExtData = TlsUtils.getExtensionData(state.serverExtensions, TlsProtocol.EXT_RenegotiationInfo); - if (renegExtData != null) + if (renegExtData == null) + { + /* + * If the extension is not present, the server does not support secure + * renegotiation; set secure_renegotiation flag to FALSE. In this case, some clients + * may want to terminate the handshake instead of continuing; see Section 4.1 for + * discussion. + */ + securityParameters.secureRenegotiation = false; + } + else { /* * If the extension is present, set the secure_renegotiation flag to TRUE. The @@ -823,19 +919,77 @@ protected void processServerHello(ClientHandshakeState state, byte[] body) } // TODO[compat-gnutls] GnuTLS test server fails to send renegotiation_info extension when resuming - state.client.notifySecureRenegotiation(securityParameters.isSecureRenegotiation()); + client.notifySecureRenegotiation(securityParameters.isSecureRenegotiation()); + + // extended_master_secret + { + boolean negotiatedEMS = false; + + if (TlsExtensionsUtils.hasExtendedMasterSecretExtension(state.clientExtensions)) + { + negotiatedEMS = TlsExtensionsUtils.hasExtendedMasterSecretExtension(serverHelloExtensions); + + if (TlsUtils.isExtendedMasterSecretOptional(server_version)) + { + if (!negotiatedEMS && + client.requiresExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure, + "Extended Master Secret extension is required"); + } + } + else + { + if (negotiatedEMS) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, + "Server sent an unexpected extended_master_secret extension negotiating " + server_version); + } + } + } + + securityParameters.extendedMasterSecret = negotiatedEMS; + } + + if (securityParameters.isResumedSession() && + securityParameters.isExtendedMasterSecret() != state.sessionParameters.isExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure, + "Server resumed session with mismatched extended_master_secret negotiation"); + } /* * RFC 7301 3.1. When session resumption or session tickets [...] are used, the previous * contents of this extension are irrelevant, and only the values in the new handshake * messages are considered. */ - securityParameters.applicationProtocol = TlsExtensionsUtils.getALPNExtensionServer(state.serverExtensions); + securityParameters.applicationProtocol = TlsExtensionsUtils.getALPNExtensionServer(serverHelloExtensions); securityParameters.applicationProtocolSet = true; + // Connection ID + if (ProtocolVersion.DTLSv12.equals(securityParameters.getNegotiatedVersion())) + { + /* + * RFC 9146 3. When a DTLS session is resumed or renegotiated, the "connection_id" extension is + * negotiated afresh. + */ + byte[] serverConnectionID = TlsExtensionsUtils.getConnectionIDExtension(serverHelloExtensions); + if (serverConnectionID != null) + { + byte[] clientConnectionID = TlsExtensionsUtils.getConnectionIDExtension(state.clientExtensions); + if (clientConnectionID == null) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + securityParameters.connectionIDLocal = serverConnectionID; + securityParameters.connectionIDPeer = clientConnectionID; + } + } + // Heartbeats { - HeartbeatExtension heartbeatExtension = TlsExtensionsUtils.getHeartbeatExtension(state.serverExtensions); + HeartbeatExtension heartbeatExtension = TlsExtensionsUtils.getHeartbeatExtension(serverHelloExtensions); if (null == heartbeatExtension) { state.heartbeat = null; @@ -847,19 +1001,10 @@ else if (HeartbeatMode.peer_allowed_to_send != heartbeatExtension.getMode()) } } + Hashtable sessionClientExtensions = state.clientExtensions, sessionServerExtensions = serverHelloExtensions; - - Hashtable sessionClientExtensions = state.clientExtensions, sessionServerExtensions = state.serverExtensions; - - if (state.resumedSession) + if (securityParameters.isResumedSession()) { - if (securityParameters.getCipherSuite() != state.sessionParameters.getCipherSuite() - || CompressionMethod._null != state.sessionParameters.getCompressionAlgorithm() - || !server_version.equals(state.sessionParameters.getNegotiatedVersion())) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - sessionClientExtensions = null; sessionServerExtensions = state.sessionParameters.readServerExtensions(); } @@ -881,12 +1026,12 @@ else if (HeartbeatMode.peer_allowed_to_send != heartbeatExtension.getMode()) securityParameters.encryptThenMAC = serverSentEncryptThenMAC; } - securityParameters.maxFragmentLength = evaluateMaxFragmentLengthExtension(state.resumedSession, - sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + securityParameters.maxFragmentLength = TlsUtils.processMaxFragmentLengthExtension(sessionClientExtensions, + sessionServerExtensions, AlertDescription.illegal_parameter); securityParameters.truncatedHMac = TlsExtensionsUtils.hasTruncatedHMacExtension(sessionServerExtensions); - if (!state.resumedSession) + if (!securityParameters.isResumedSession()) { // TODO[tls13] See RFC 8446 4.4.2.1 if (TlsUtils.hasExpectedEmptyExtensionData(sessionServerExtensions, TlsExtensionsUtils.EXT_status_request_v2, @@ -899,16 +1044,20 @@ else if (TlsUtils.hasExpectedEmptyExtensionData(sessionServerExtensions, TlsExte { securityParameters.statusRequestVersion = 1; } - } - state.expectSessionTicket = !state.resumedSession - && TlsUtils.hasExpectedEmptyExtensionData(sessionServerExtensions, TlsProtocol.EXT_SessionTicket, - AlertDescription.illegal_parameter); + securityParameters.clientCertificateType = TlsUtils.processClientCertificateTypeExtension( + sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + securityParameters.serverCertificateType = TlsUtils.processServerCertificateTypeExtension( + sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + + state.expectSessionTicket = TlsUtils.hasExpectedEmptyExtensionData(sessionServerExtensions, + TlsProtocol.EXT_SessionTicket, AlertDescription.illegal_parameter); + } } if (sessionClientExtensions != null) { - state.client.processServerExtensions(sessionServerExtensions); + client.processServerExtensions(sessionServerExtensions); } } @@ -933,8 +1082,8 @@ protected void processServerSupplementalData(ClientHandshakeState state, byte[] protected void reportServerVersion(ClientHandshakeState state, ProtocolVersion server_version) throws IOException { - TlsClientContextImpl context = state.clientContext; - SecurityParameters securityParameters = context.getSecurityParametersHandshake(); + TlsClientContextImpl clientContext = state.clientContext; + SecurityParameters securityParameters = clientContext.getSecurityParametersHandshake(); ProtocolVersion currentServerVersion = securityParameters.getNegotiatedVersion(); if (null != currentServerVersion) @@ -946,14 +1095,20 @@ protected void reportServerVersion(ClientHandshakeState state, ProtocolVersion s return; } - if (!ProtocolVersion.contains(context.getClientSupportedVersions(), server_version)) + if (!ProtocolVersion.contains(clientContext.getClientSupportedVersions(), server_version)) { throw new TlsFatalAlert(AlertDescription.protocol_version); } + // TODO[dtls13] Read draft/RFC for guidance on the legacy_record_version field +// ProtocolVersion legacy_record_version = server_version.isLaterVersionOf(ProtocolVersion.DTLSv12) +// ? ProtocolVersion.DTLSv12 +// : server_version; +// +// recordLayer.setWriteVersion(legacy_record_version); securityParameters.negotiatedVersion = server_version; - TlsUtils.negotiatedVersionDTLSClient(state.clientContext, state.client); + TlsUtils.negotiatedVersionDTLSClient(clientContext, state.client); } protected static byte[] patchClientHelloWithCookie(byte[] clientHelloBody, byte[] cookie) @@ -970,8 +1125,8 @@ protected static byte[] patchClientHelloWithCookie(byte[] clientHelloBody, byte[ TlsUtils.checkUint8(cookie.length); TlsUtils.writeUint8(cookie.length, patched, cookieLengthPos); System.arraycopy(cookie, 0, patched, cookiePos, cookie.length); - System.arraycopy(clientHelloBody, cookiePos, patched, cookiePos + cookie.length, clientHelloBody.length - - cookiePos); + System.arraycopy(clientHelloBody, cookiePos, patched, cookiePos + cookie.length, + clientHelloBody.length - cookiePos); return patched; } @@ -987,9 +1142,9 @@ protected static class ClientHandshakeState int[] offeredCipherSuites = null; Hashtable clientExtensions = null; Hashtable serverExtensions = null; - boolean resumedSession = false; boolean expectSessionTicket = false; Hashtable clientAgreements = null; + OfferedPsks.BindersConfig clientBinders = null; TlsKeyExchange keyExchange = null; TlsAuthentication authentication = null; CertificateStatus certificateStatus = null; diff --git a/tls/src/main/java/org/bouncycastle/tls/DTLSEpoch.java b/tls/src/main/java/org/bouncycastle/tls/DTLSEpoch.java index 72f8d406f0..1bae3509b6 100644 --- a/tls/src/main/java/org/bouncycastle/tls/DTLSEpoch.java +++ b/tls/src/main/java/org/bouncycastle/tls/DTLSEpoch.java @@ -10,10 +10,11 @@ class DTLSEpoch private final int epoch; private final TlsCipher cipher; + private final int recordHeaderLengthRead, recordHeaderLengthWrite; private long sequenceNumber = 0; - DTLSEpoch(int epoch, TlsCipher cipher) + DTLSEpoch(int epoch, TlsCipher cipher, int recordHeaderLengthRead, int recordHeaderLengthWrite) { if (epoch < 0) { @@ -26,6 +27,8 @@ class DTLSEpoch this.epoch = epoch; this.cipher = cipher; + this.recordHeaderLengthRead = recordHeaderLengthRead; + this.recordHeaderLengthWrite = recordHeaderLengthWrite; } synchronized long allocateSequenceNumber() throws IOException @@ -48,6 +51,16 @@ int getEpoch() return epoch; } + int getRecordHeaderLengthRead() + { + return recordHeaderLengthRead; + } + + int getRecordHeaderLengthWrite() + { + return recordHeaderLengthWrite; + } + DTLSReplayWindow getReplayWindow() { return replayWindow; diff --git a/tls/src/main/java/org/bouncycastle/tls/DTLSProtocol.java b/tls/src/main/java/org/bouncycastle/tls/DTLSProtocol.java index 919b5ec581..199425b2c1 100644 --- a/tls/src/main/java/org/bouncycastle/tls/DTLSProtocol.java +++ b/tls/src/main/java/org/bouncycastle/tls/DTLSProtocol.java @@ -45,20 +45,14 @@ protected static void applyMaxFragmentLengthExtension(DTLSRecordLayer recordLaye } } + /** + * @deprecated Will be removed. + */ protected static short evaluateMaxFragmentLengthExtension(boolean resumedSession, Hashtable clientExtensions, Hashtable serverExtensions, short alertDescription) throws IOException { - short maxFragmentLength = TlsExtensionsUtils.getMaxFragmentLengthExtension(serverExtensions); - if (maxFragmentLength >= 0) - { - if (!MaxFragmentLength.isValid(maxFragmentLength) - || (!resumedSession && maxFragmentLength != TlsExtensionsUtils - .getMaxFragmentLengthExtension(clientExtensions))) - { - throw new TlsFatalAlert(alertDescription); - } - } - return maxFragmentLength; + return TlsUtils.processMaxFragmentLengthExtension(resumedSession ? null : clientExtensions, serverExtensions, + alertDescription); } protected static byte[] generateCertificate(TlsContext context, Certificate certificate, OutputStream endPointHash) @@ -100,14 +94,15 @@ protected static void sendCertificateMessage(TlsContext context, DTLSReliableHan protected static int validateSelectedCipherSuite(int selectedCipherSuite, short alertDescription) throws IOException { - switch (TlsUtils.getEncryptionAlgorithm(selectedCipherSuite)) + int encryptionAlgorithm = TlsUtils.getEncryptionAlgorithm(selectedCipherSuite); + if (EncryptionAlgorithm.NULL != encryptionAlgorithm) { - case EncryptionAlgorithm.RC4_40: - case EncryptionAlgorithm.RC4_128: - case -1: - throw new TlsFatalAlert(alertDescription); - default: - return selectedCipherSuite; + int cipherType = TlsUtils.getEncryptionAlgorithmType(encryptionAlgorithm); + if (cipherType < 0 || CipherType.stream == cipherType) + { + throw new TlsFatalAlert(alertDescription); + } } + return selectedCipherSuite; } } diff --git a/tls/src/main/java/org/bouncycastle/tls/DTLSRecordCallback.java b/tls/src/main/java/org/bouncycastle/tls/DTLSRecordCallback.java new file mode 100644 index 0000000000..aa797f9023 --- /dev/null +++ b/tls/src/main/java/org/bouncycastle/tls/DTLSRecordCallback.java @@ -0,0 +1,10 @@ +package org.bouncycastle.tls; + +public interface DTLSRecordCallback +{ + /** + * Called when a record is accepted by the record layer. + * @param flags see {@link DTLSRecordFlags} for constants. + */ + void recordAccepted(int flags); +} diff --git a/tls/src/main/java/org/bouncycastle/tls/DTLSRecordFlags.java b/tls/src/main/java/org/bouncycastle/tls/DTLSRecordFlags.java new file mode 100644 index 0000000000..3bdde87f23 --- /dev/null +++ b/tls/src/main/java/org/bouncycastle/tls/DTLSRecordFlags.java @@ -0,0 +1,12 @@ +package org.bouncycastle.tls; + +public abstract class DTLSRecordFlags +{ + public static final int NONE = 0; + + /** The record is newer (by epoch and sequence number) than any record received previously. */ + public static final int IS_NEWEST = 1; + + /** The record includes the (valid) connection ID (RFC 9146) for this connection. */ + public static final int USES_CONNECTION_ID = 2; +} diff --git a/tls/src/main/java/org/bouncycastle/tls/DTLSRecordLayer.java b/tls/src/main/java/org/bouncycastle/tls/DTLSRecordLayer.java index 0def458e5f..abdcd29f35 100644 --- a/tls/src/main/java/org/bouncycastle/tls/DTLSRecordLayer.java +++ b/tls/src/main/java/org/bouncycastle/tls/DTLSRecordLayer.java @@ -15,51 +15,58 @@ class DTLSRecordLayer implements DatagramTransport { - private static final int RECORD_HEADER_LENGTH = 13; + static final int RECORD_HEADER_LENGTH = 13; + private static final int MAX_FRAGMENT_LENGTH = 1 << 14; private static final long TCP_MSL = 1000L * 60 * 2; private static final long RETRANSMIT_TIMEOUT = TCP_MSL * 2; - static byte[] receiveClientHelloRecord(byte[] data, int dataOff, int dataLen) throws IOException + static int receiveClientHelloRecord(byte[] data, int dataOff, int dataLen) throws IOException { if (dataLen < RECORD_HEADER_LENGTH) { - return null; + return -1; } short contentType = TlsUtils.readUint8(data, dataOff + 0); if (ContentType.handshake != contentType) { - return null; + return -1; } ProtocolVersion version = TlsUtils.readVersion(data, dataOff + 1); if (!ProtocolVersion.DTLSv10.isEqualOrEarlierVersionOf(version)) { - return null; + return -1; } int epoch = TlsUtils.readUint16(data, dataOff + 3); if (0 != epoch) { - return null; + return -1; } // long sequenceNumber = TlsUtils.readUint48(data, dataOff + 5); int length = TlsUtils.readUint16(data, dataOff + 11); + if (length < 1 || length > MAX_FRAGMENT_LENGTH) + { + return -1; + } + if (dataLen < RECORD_HEADER_LENGTH + length) { - return null; + return -1; } - if (length > MAX_FRAGMENT_LENGTH) + short msgType = TlsUtils.readUint8(data, dataOff + RECORD_HEADER_LENGTH); + if (HandshakeType.client_hello != msgType) { - return null; + return -1; } // NOTE: We ignore/drop any data after the first record - return TlsUtils.copyOfRangeExact(data, dataOff + RECORD_HEADER_LENGTH, dataOff + RECORD_HEADER_LENGTH + length); + return length; } static void sendHelloVerifyRequestRecord(DatagramSender sender, long recordSeq, byte[] message) throws IOException @@ -130,7 +137,7 @@ private static void sendDatagram(DatagramSender sender, byte[] buf, int off, int this.inHandshake = true; - this.currentEpoch = new DTLSEpoch(0, TlsNullNullCipher.INSTANCE); + this.currentEpoch = new DTLSEpoch(0, TlsNullNullCipher.INSTANCE, RECORD_HEADER_LENGTH, RECORD_HEADER_LENGTH); this.pendingEpoch = null; this.readEpoch = currentEpoch; this.writeEpoch = currentEpoch; @@ -189,8 +196,15 @@ void initPendingEpoch(TlsCipher pendingCipher) * lifetime." */ + SecurityParameters securityParameters = context.getSecurityParameters(); + byte[] connectionIDLocal = securityParameters.getConnectionIDLocal(); + byte[] connectionIDPeer = securityParameters.getConnectionIDPeer(); + int recordHeaderLengthRead = RECORD_HEADER_LENGTH + (connectionIDPeer != null ? connectionIDPeer.length : 0); + int recordHeaderLengthWrite = RECORD_HEADER_LENGTH + (connectionIDLocal != null ? connectionIDLocal.length : 0); + // TODO Check for overflow - this.pendingEpoch = new DTLSEpoch(writeEpoch.getEpoch() + 1, pendingCipher); + this.pendingEpoch = new DTLSEpoch(writeEpoch.getEpoch() + 1, pendingCipher, recordHeaderLengthRead, + recordHeaderLengthWrite); } void handshakeSuccessful(DTLSHandshakeRetransmit retransmit) @@ -244,19 +258,33 @@ void resetWriteEpoch() public int getReceiveLimit() throws IOException { - return Math.min(this.plaintextLimit, - readEpoch.getCipher().getPlaintextLimit(transport.getReceiveLimit() - RECORD_HEADER_LENGTH)); + int ciphertextLimit = transport.getReceiveLimit() - readEpoch.getRecordHeaderLengthRead(); + TlsCipher cipher = readEpoch.getCipher(); + + int plaintextDecodeLimit = cipher.getPlaintextDecodeLimit(ciphertextLimit); + + return Math.min(plaintextLimit, plaintextDecodeLimit); } public int getSendLimit() throws IOException { - return Math.min(this.plaintextLimit, - writeEpoch.getCipher().getPlaintextLimit(transport.getSendLimit() - RECORD_HEADER_LENGTH)); + TlsCipher cipher = writeEpoch.getCipher(); + int ciphertextLimit = transport.getSendLimit() - writeEpoch.getRecordHeaderLengthWrite(); + + int plaintextEncodeLimit = cipher.getPlaintextEncodeLimit(ciphertextLimit); + + return Math.min(plaintextLimit, plaintextEncodeLimit); } public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException + { + return receive(buf, off, len, waitMillis, null); + } + + int receive(byte[] buf, int off, int len, int waitMillis, DTLSRecordCallback recordCallback) + throws IOException { long currentTimeMillis = System.currentTimeMillis(); @@ -283,7 +311,7 @@ public int receive(byte[] buf, int off, int len, int waitMillis) heartbeat.generatePayload()); this.heartbeatTimeout = new Timeout(heartbeat.getTimeoutMillis(), currentTimeMillis); - this.heartbeatResendMillis = DTLSReliableHandshake.INITIAL_RESEND_MILLIS; + this.heartbeatResendMillis = peer.getHandshakeResendTimeMillis(); this.heartbeatResendTimeout = new Timeout(heartbeatResendMillis, currentTimeMillis); sendHeartbeatMessage(heartbeatInFlight); @@ -305,14 +333,14 @@ else if (Timeout.hasExpired(heartbeatResendTimeout, currentTimeMillis)) waitMillis = 1; } - int receiveLimit = Math.min(len, getReceiveLimit()) + RECORD_HEADER_LENGTH; + int receiveLimit = transport.getReceiveLimit(); if (null == record || record.length < receiveLimit) { record = new byte[receiveLimit]; } int received = receiveRecord(record, 0, receiveLimit, waitMillis); - int processed = processRecord(received, record, buf, off); + int processed = processRecord(received, record, buf, off, len, recordCallback); if (processed >= 0) { return processed; @@ -325,6 +353,29 @@ record = new byte[receiveLimit]; return -1; } + int receivePending(byte[] buf, int off, int len, DTLSRecordCallback recordCallback) + throws IOException + { + if (recordQueue.available() > 0) + { + int receiveLimit = recordQueue.available(); + byte[] record = new byte[receiveLimit]; + + do + { + int received = receivePendingRecord(record, 0, receiveLimit); + int processed = processRecord(received, record, buf, off, len, recordCallback); + if (processed >= 0) + { + return processed; + } + } + while (recordQueue.available() > 0); + } + + return -1; + } + public void send(byte[] buf, int off, int len) throws IOException { @@ -462,21 +513,30 @@ private int receiveDatagram(byte[] buf, int off, int len, int waitMillis) { try { - return transport.receive(buf, off, len, waitMillis); + // NOTE: the buffer is sized to support transport.getReceiveLimit(). + int received = transport.receive(buf, off, len, waitMillis); + + // Check the transport returned a sensible value, otherwise discard the datagram. + if (received <= len) + { + return received; + } } catch (SocketTimeoutException e) { - return -1; } catch (InterruptedIOException e) { e.bytesTransferred = 0; throw e; } + + return -1; } // TODO Include 'currentTimeMillis' as an argument, use with Timeout, resetHeartbeat - private int processRecord(int received, byte[] record, byte[] buf, int off) + private int processRecord(int received, byte[] record, byte[] buf, int off, int len, + DTLSRecordCallback recordCallback) throws IOException { // NOTE: received < 0 (timeout) is covered by this first case @@ -484,11 +544,6 @@ private int processRecord(int received, byte[] record, byte[] buf, int off) { return -1; } - int length = TlsUtils.readUint16(record, 11); - if (received != (length + RECORD_HEADER_LENGTH)) - { - return -1; - } // TODO[dtls13] Deal with opaque record type for 1.3 AEAD ciphers short recordType = TlsUtils.readUint8(record, 0); @@ -500,11 +555,18 @@ private int processRecord(int received, byte[] record, byte[] buf, int off) case ContentType.change_cipher_spec: case ContentType.handshake: case ContentType.heartbeat: + case ContentType.tls12_cid: break; default: return -1; } + ProtocolVersion recordVersion = TlsUtils.readVersion(record, 1); + if (!recordVersion.isDTLS()) + { + return -1; + } + int epoch = TlsUtils.readUint16(record, 3); DTLSEpoch recordEpoch = null; @@ -512,10 +574,12 @@ private int processRecord(int received, byte[] record, byte[] buf, int off) { recordEpoch = readEpoch; } - else if (recordType == ContentType.handshake && null != retransmitEpoch - && epoch == retransmitEpoch.getEpoch()) + else if (null != retransmitEpoch && epoch == retransmitEpoch.getEpoch()) { - recordEpoch = retransmitEpoch; + if (recordType == ContentType.handshake) + { + recordEpoch = retransmitEpoch; + } } if (null == recordEpoch) @@ -529,8 +593,35 @@ else if (recordType == ContentType.handshake && null != retransmitEpoch return -1; } - ProtocolVersion recordVersion = TlsUtils.readVersion(record, 1); - if (!recordVersion.isDTLS()) + int recordHeaderLength = recordEpoch.getRecordHeaderLengthRead(); + if (recordHeaderLength > RECORD_HEADER_LENGTH) + { + if (ContentType.tls12_cid != recordType) + { + return -1; + } + + if (received < recordHeaderLength) + { + return -1; + } + + byte[] connectionID = context.getSecurityParameters().getConnectionIDPeer(); + if (!Arrays.constantTimeAreEqual(connectionID.length, connectionID, 0, record, 11)) + { + return -1; + } + } + else + { + if (ContentType.tls12_cid == recordType) + { + return -1; + } + } + + int length = TlsUtils.readUint16(record, recordHeaderLength - 2); + if (received != (length + recordHeaderLength)) { return -1; } @@ -546,7 +637,7 @@ else if (recordType == ContentType.handshake && null != retransmitEpoch getReadEpoch() == 0 && length > 0 && ContentType.handshake == recordType - && HandshakeType.client_hello == TlsUtils.readUint8(record, RECORD_HEADER_LENGTH); + && HandshakeType.client_hello == TlsUtils.readUint8(record, recordHeaderLength); if (!isClientHelloFragment) { @@ -556,10 +647,25 @@ else if (recordType == ContentType.handshake && null != retransmitEpoch long macSeqNo = getMacSequenceNumber(recordEpoch.getEpoch(), seq); - TlsDecodeResult decoded = recordEpoch.getCipher().decodeCiphertext(macSeqNo, recordType, recordVersion, record, - RECORD_HEADER_LENGTH, length); + TlsDecodeResult decoded; + try + { + decoded = recordEpoch.getCipher().decodeCiphertext(macSeqNo, recordType, recordVersion, record, + recordHeaderLength, length); + } + catch (TlsFatalAlert fatalAlert) + { + if (AlertDescription.bad_record_mac == fatalAlert.getAlertDescription()) + { + /* + * RFC 9146 6. DTLS implementations MUST silently discard records with bad MACs or that are otherwise + * invalid. + */ + return -1; + } - recordEpoch.getReplayWindow().reportAuthenticated(seq); + throw fatalAlert; + } if (decoded.len > this.plaintextLimit) { @@ -576,7 +682,7 @@ else if (recordType == ContentType.handshake && null != retransmitEpoch getReadEpoch() == 0 && length > 0 && ContentType.handshake == recordType - && HandshakeType.hello_verify_request == TlsUtils.readUint8(record, RECORD_HEADER_LENGTH); + && HandshakeType.hello_verify_request == TlsUtils.readUint8(record, recordHeaderLength); if (isHelloVerifyRequest) { @@ -597,6 +703,29 @@ else if (recordType == ContentType.handshake && null != retransmitEpoch } } + boolean isLatestConfirmed = recordEpoch.getReplayWindow().reportAuthenticated(seq); + + /* + * NOTE: The record has passed record layer validation and will be dispatched according to the decoded + * content type. + */ + if (recordCallback != null) + { + int flags = DTLSRecordFlags.NONE; + + if (recordEpoch == readEpoch && isLatestConfirmed) + { + flags |= DTLSRecordFlags.IS_NEWEST; + } + + if (ContentType.tls12_cid == recordType) + { + flags |= DTLSRecordFlags.USES_CONNECTION_ID; + } + + recordCallback.recordAccepted(flags); + } + switch (decoded.contentType) { case ContentType.alert: @@ -713,6 +842,7 @@ else if (recordType == ContentType.handshake && null != retransmitEpoch return -1; } + case ContentType.tls12_cid: default: return -1; } @@ -728,26 +858,61 @@ else if (recordType == ContentType.handshake && null != retransmitEpoch this.retransmitTimeout = null; } + // NOTE: Internal error implies getReceiveLimit() was not used to allocate result space + if (decoded.len > len) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + System.arraycopy(decoded.buf, decoded.off, buf, off, decoded.len); return decoded.len; } - private int receiveRecord(byte[] buf, int off, int len, int waitMillis) + private int receivePendingRecord(byte[] buf, int off, int len) throws IOException { - if (recordQueue.available() > 0) +// assert recordQueue.available() > 0; + + int recordLength = RECORD_HEADER_LENGTH; + if (recordQueue.available() >= recordLength) { - int length = 0; - if (recordQueue.available() >= RECORD_HEADER_LENGTH) + int epoch = recordQueue.readUint16(3); + + DTLSEpoch recordEpoch = null; + if (epoch == readEpoch.getEpoch()) { - byte[] lengthBytes = new byte[2]; - recordQueue.read(lengthBytes, 0, 2, 11); - length = TlsUtils.readUint16(lengthBytes, 0); + recordEpoch = readEpoch; } + else if (null != retransmitEpoch && epoch == retransmitEpoch.getEpoch()) + { + recordEpoch = retransmitEpoch; + } + + if (null == recordEpoch) + { + recordQueue.removeData(recordQueue.available()); + return -1; + } + + recordLength = recordEpoch.getRecordHeaderLengthRead(); + if (recordQueue.available() >= recordLength) + { + int fragmentLength = recordQueue.readUint16(recordLength - 2); + recordLength += fragmentLength; + } + } - int received = Math.min(recordQueue.available(), RECORD_HEADER_LENGTH + length); - recordQueue.removeData(buf, off, received, 0); - return received; + int received = Math.min(recordQueue.available(), recordLength); + recordQueue.removeData(buf, off, received, 0); + return received; + } + + private int receiveRecord(byte[] buf, int off, int len, int waitMillis) + throws IOException + { + if (recordQueue.available() > 0) + { + return receivePendingRecord(buf, off, len); } int received = receiveDatagram(buf, off, len, waitMillis); @@ -755,12 +920,33 @@ private int receiveRecord(byte[] buf, int off, int len, int waitMillis) { this.inConnection = true; - int fragmentLength = TlsUtils.readUint16(buf, off + 11); - int recordLength = RECORD_HEADER_LENGTH + fragmentLength; - if (received > recordLength) + int epoch = TlsUtils.readUint16(buf, off + 3); + + DTLSEpoch recordEpoch = null; + if (epoch == readEpoch.getEpoch()) + { + recordEpoch = readEpoch; + } + else if (null != retransmitEpoch && epoch == retransmitEpoch.getEpoch()) { - recordQueue.addData(buf, off + recordLength, received - recordLength); - received = recordLength; + recordEpoch = retransmitEpoch; + } + + if (null == recordEpoch) + { + return -1; + } + + int recordHeaderLength = recordEpoch.getRecordHeaderLengthRead(); + if (received >= recordHeaderLength) + { + int fragmentLength = TlsUtils.readUint16(buf, off + recordHeaderLength - 2); + int recordLength = recordHeaderLength + fragmentLength; + if (received > recordLength) + { + recordQueue.addData(buf, off + recordLength, received - recordLength); + received = recordLength; + } } } @@ -820,17 +1006,26 @@ private void sendRecord(short contentType, byte[] buf, int off, int len) throws long macSequenceNumber = getMacSequenceNumber(recordEpoch, recordSequenceNumber); ProtocolVersion recordVersion = writeVersion; + int recordHeaderLength = writeEpoch.getRecordHeaderLengthWrite(); + TlsEncodeResult encoded = writeEpoch.getCipher().encodePlaintext(macSequenceNumber, contentType, - recordVersion, RECORD_HEADER_LENGTH, buf, off, len); + recordVersion, recordHeaderLength, buf, off, len); - int ciphertextLength = encoded.len - RECORD_HEADER_LENGTH; + int ciphertextLength = encoded.len - recordHeaderLength; TlsUtils.checkUint16(ciphertextLength); TlsUtils.writeUint8(encoded.recordType, encoded.buf, encoded.off + 0); TlsUtils.writeVersion(recordVersion, encoded.buf, encoded.off + 1); TlsUtils.writeUint16(recordEpoch, encoded.buf, encoded.off + 3); TlsUtils.writeUint48(recordSequenceNumber, encoded.buf, encoded.off + 5); - TlsUtils.writeUint16(ciphertextLength, encoded.buf, encoded.off + 11); + + if (recordHeaderLength > RECORD_HEADER_LENGTH) + { + byte[] connectionID = context.getSecurityParameters().getConnectionIDLocal(); + System.arraycopy(connectionID, 0, encoded.buf, encoded.off + 11, connectionID.length); + } + + TlsUtils.writeUint16(ciphertextLength, encoded.buf, encoded.off + (recordHeaderLength - 2)); sendDatagram(transport, encoded.buf, encoded.off, encoded.len); } diff --git a/tls/src/main/java/org/bouncycastle/tls/DTLSReliableHandshake.java b/tls/src/main/java/org/bouncycastle/tls/DTLSReliableHandshake.java index d64fe510ae..9d3fbb2034 100644 --- a/tls/src/main/java/org/bouncycastle/tls/DTLSReliableHandshake.java +++ b/tls/src/main/java/org/bouncycastle/tls/DTLSReliableHandshake.java @@ -3,7 +3,6 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.OutputStream; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; @@ -12,59 +11,52 @@ class DTLSReliableHandshake { - private static final int MAX_RECEIVE_AHEAD = 16; - private static final int MESSAGE_HEADER_LENGTH = 12; + static final int MESSAGE_HEADER_LENGTH = 12; - static final int INITIAL_RESEND_MILLIS = 1000; + private static final int MAX_RECEIVE_AHEAD = 16; private static final int MAX_RESEND_MILLIS = 60000; - static DTLSRequest readClientRequest(byte[] data, int dataOff, int dataLen, OutputStream dtlsOutput) - throws IOException + static ByteArrayInputStream receiveClientHelloMessage(byte[] msg, int msgOff, int msgLen) throws IOException { // TODO Support the possibility of a fragmented ClientHello datagram - byte[] message = DTLSRecordLayer.receiveClientHelloRecord(data, dataOff, dataLen); - if (null == message || message.length < MESSAGE_HEADER_LENGTH) + if (msgLen < MESSAGE_HEADER_LENGTH) { return null; } - long recordSeq = TlsUtils.readUint48(data, dataOff + 5); - - short msgType = TlsUtils.readUint8(message, 0); + short msgType = TlsUtils.readUint8(msg, msgOff); if (HandshakeType.client_hello != msgType) { return null; } - int length = TlsUtils.readUint24(message, 1); - if (message.length != MESSAGE_HEADER_LENGTH + length) + int length = TlsUtils.readUint24(msg, msgOff + 1); + if (msgLen != MESSAGE_HEADER_LENGTH + length) { return null; } // TODO Consider stricter HelloVerifyRequest-related checks -// int messageSeq = TlsUtils.readUint16(message, 4); +// int messageSeq = TlsUtils.readUint16(msg, msgOff + 4); // if (messageSeq > 1) // { // return null; // } - int fragmentOffset = TlsUtils.readUint24(message, 6); + int fragmentOffset = TlsUtils.readUint24(msg, msgOff + 6); if (0 != fragmentOffset) { return null; } - int fragmentLength = TlsUtils.readUint24(message, 9); + int fragmentLength = TlsUtils.readUint24(msg, msgOff + 9); if (length != fragmentLength) { return null; } - ClientHello clientHello = ClientHello.parse(new ByteArrayInputStream(message, MESSAGE_HEADER_LENGTH, length), dtlsOutput); - - return new DTLSRequest(recordSeq, message, clientHello); + return new ByteArrayInputStream(msg, msgOff + MESSAGE_HEADER_LENGTH, length); } static void sendHelloVerifyRequest(DatagramSender sender, long recordSeq, byte[] cookie) throws IOException @@ -99,20 +91,23 @@ static void sendHelloVerifyRequest(DatagramSender sender, long recordSeq, byte[] private Hashtable previousInboundFlight = null; private Vector outboundFlight = new Vector(); + private int initialResendMillis; private int resendMillis = -1; private Timeout resendTimeout = null; private int next_send_seq = 0, next_receive_seq = 0; - DTLSReliableHandshake(TlsContext context, DTLSRecordLayer transport, int timeoutMillis, DTLSRequest request) + DTLSReliableHandshake(TlsContext context, DTLSRecordLayer transport, int timeoutMillis, int initialResendMillis, + DTLSRequest request) { this.recordLayer = transport; this.handshakeHash = new DeferredHash(context); this.handshakeTimeout = Timeout.forWaitMillis(timeoutMillis); + this.initialResendMillis = initialResendMillis; if (null != request) { - resendMillis = INITIAL_RESEND_MILLIS; + resendMillis = initialResendMillis; resendTimeout = new Timeout(resendMillis); long recordSeq = request.getRecordSeq(); @@ -322,7 +317,7 @@ private Message implReceiveMessage() if (null == resendTimeout) { - resendMillis = INITIAL_RESEND_MILLIS; + resendMillis = initialResendMillis; resendTimeout = new Timeout(resendMillis, currentTimeMillis); prepareInboundFlight(new Hashtable()); diff --git a/tls/src/main/java/org/bouncycastle/tls/DTLSReplayWindow.java b/tls/src/main/java/org/bouncycastle/tls/DTLSReplayWindow.java index 8360adc326..79eada85df 100644 --- a/tls/src/main/java/org/bouncycastle/tls/DTLSReplayWindow.java +++ b/tls/src/main/java/org/bouncycastle/tls/DTLSReplayWindow.java @@ -49,7 +49,7 @@ boolean shouldDiscard(long seq) * * @param seq the 48-bit DTLSPlainText.sequence_number field of an authenticated record. */ - void reportAuthenticated(long seq) + boolean reportAuthenticated(long seq) { if ((seq & VALID_SEQ_MASK) != seq) { @@ -63,6 +63,7 @@ void reportAuthenticated(long seq) { bitmap |= (1L << diff); } + return false; } else { @@ -77,6 +78,7 @@ void reportAuthenticated(long seq) bitmap |= 1; } latestConfirmedSeq = seq; + return true; } } diff --git a/tls/src/main/java/org/bouncycastle/tls/DTLSServerProtocol.java b/tls/src/main/java/org/bouncycastle/tls/DTLSServerProtocol.java index ba7d437429..bda746305b 100644 --- a/tls/src/main/java/org/bouncycastle/tls/DTLSServerProtocol.java +++ b/tls/src/main/java/org/bouncycastle/tls/DTLSServerProtocol.java @@ -6,6 +6,7 @@ import java.util.Hashtable; import java.util.Vector; +import org.bouncycastle.tls.crypto.TlsCrypto; import org.bouncycastle.tls.crypto.TlsSecret; import org.bouncycastle.util.Arrays; @@ -47,16 +48,19 @@ public DTLSTransport accept(TlsServer server, DatagramTransport transport, DTLSR throw new IllegalArgumentException("'transport' cannot be null"); } + TlsServerContextImpl serverContext = new TlsServerContextImpl(server.getCrypto()); + ServerHandshakeState state = new ServerHandshakeState(); state.server = server; - state.serverContext = new TlsServerContextImpl(server.getCrypto()); - server.init(state.serverContext); - state.serverContext.handshakeBeginning(server); + state.serverContext = serverContext; + + server.init(serverContext); + serverContext.handshakeBeginning(server); - SecurityParameters securityParameters = state.serverContext.getSecurityParametersHandshake(); + SecurityParameters securityParameters = serverContext.getSecurityParametersHandshake(); securityParameters.extendedPadding = server.shouldUseExtendedPadding(); - DTLSRecordLayer recordLayer = new DTLSRecordLayer(state.serverContext, state.server, transport); + DTLSRecordLayer recordLayer = new DTLSRecordLayer(serverContext, server, transport); server.notifyCloseHandle(recordLayer); try @@ -93,9 +97,12 @@ protected void abortServerHandshake(ServerHandshakeState state, DTLSRecordLayer protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLayer recordLayer, DTLSRequest request) throws IOException { - SecurityParameters securityParameters = state.serverContext.getSecurityParametersHandshake(); - DTLSReliableHandshake handshake = new DTLSReliableHandshake(state.serverContext, recordLayer, - state.server.getHandshakeTimeoutMillis(), request); + TlsServer server = state.server; + TlsServerContextImpl serverContext = state.serverContext; + SecurityParameters securityParameters = serverContext.getSecurityParametersHandshake(); + + DTLSReliableHandshake handshake = new DTLSReliableHandshake(serverContext, recordLayer, + server.getHandshakeTimeoutMillis(), server.getHandshakeResendTimeMillis(), request); DTLSReliableHandshake.Message clientMessage = null; @@ -114,36 +121,22 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa { throw new TlsFatalAlert(AlertDescription.unexpected_message); } + + clientMessage = null; } else { processClientHello(state, request.getClientHello()); - } - /* - * NOTE: Currently no server support for session resumption - * - * If adding support, ensure securityParameters.tlsUnique is set to the localVerifyData, but - * ONLY when extended_master_secret has been negotiated (otherwise NULL). - */ - { - // TODO[resumption] - - state.tlsSession = TlsUtils.importSession(TlsUtils.EMPTY_BYTES, null); - state.sessionParameters = null; - state.sessionMasterSecret = null; + request = null; } - securityParameters.sessionID = state.tlsSession.getSessionID(); - - state.server.notifySession(state.tlsSession); - { byte[] serverHelloBody = generateServerHello(state, recordLayer); // TODO[dtls13] Ideally, move this into generateServerHello once legacy_record_version clarified { - ProtocolVersion recordLayerVersion = state.serverContext.getServerVersion(); + ProtocolVersion recordLayerVersion = serverContext.getServerVersion(); recordLayer.setReadVersion(recordLayerVersion); recordLayer.setWriteVersion(recordLayerVersion); } @@ -153,20 +146,55 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa handshake.getHandshakeHash().notifyPRFDetermined(); - Vector serverSupplementalData = state.server.getServerSupplementalData(); + if (securityParameters.isResumedSession()) + { + securityParameters.masterSecret = state.sessionMasterSecret; + recordLayer.initPendingEpoch(TlsUtils.initCipher(serverContext)); + + // NOTE: Calculated exclusive of the Finished message itself + securityParameters.localVerifyData = TlsUtils.calculateVerifyData(serverContext, + handshake.getHandshakeHash(), true); + handshake.sendMessage(HandshakeType.finished, securityParameters.getLocalVerifyData()); + + // NOTE: Calculated exclusive of the actual Finished message from the client + securityParameters.peerVerifyData = TlsUtils.calculateVerifyData(serverContext, + handshake.getHandshakeHash(), false); + processFinished(handshake.receiveMessageBody(HandshakeType.finished), + securityParameters.getPeerVerifyData()); + + handshake.finish(); + + if (securityParameters.isExtendedMasterSecret()) + { + securityParameters.tlsUnique = securityParameters.getLocalVerifyData(); + } + + securityParameters.localCertificate = state.sessionParameters.getLocalCertificate(); + securityParameters.peerCertificate = state.sessionParameters.getPeerCertificate(); + securityParameters.pskIdentity = state.sessionParameters.getPSKIdentity(); + securityParameters.srpIdentity = state.sessionParameters.getSRPIdentity(); + + serverContext.handshakeComplete(server, state.tlsSession); + + recordLayer.initHeartbeat(state.heartbeat, HeartbeatMode.peer_allowed_to_send == state.heartbeatPolicy); + + return new DTLSTransport(recordLayer); + } + + Vector serverSupplementalData = server.getServerSupplementalData(); if (serverSupplementalData != null) { byte[] supplementalDataBody = generateSupplementalData(serverSupplementalData); handshake.sendMessage(HandshakeType.supplemental_data, supplementalDataBody); } - state.keyExchange = TlsUtils.initKeyExchangeServer(state.serverContext, state.server); + state.keyExchange = TlsUtils.initKeyExchangeServer(serverContext, server); state.serverCredentials = null; if (!KeyExchangeAlgorithm.isAnonymous(securityParameters.getKeyExchangeAlgorithm())) { - state.serverCredentials = TlsUtils.establishServerCredentials(state.server); + state.serverCredentials = TlsUtils.establishServerCredentials(server); } // Server certificate @@ -184,7 +212,7 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa serverCertificate = state.serverCredentials.getCertificate(); - sendCertificateMessage(state.serverContext, handshake, serverCertificate, endPointHash); + sendCertificateMessage(serverContext, handshake, serverCertificate, endPointHash); } securityParameters.tlsServerEndPoint = endPointHash.toByteArray(); @@ -197,7 +225,7 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa if (securityParameters.getStatusRequestVersion() > 0) { - CertificateStatus certificateStatus = state.server.getCertificateStatus(); + CertificateStatus certificateStatus = server.getCertificateStatus(); if (certificateStatus != null) { byte[] certificateStatusBody = generateCertificateStatus(state, certificateStatus); @@ -213,7 +241,7 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa if (state.serverCredentials != null) { - state.certificateRequest = state.server.getCertificateRequest(); + state.certificateRequest = server.getCertificateRequest(); if (null == state.certificateRequest) { @@ -229,7 +257,7 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa } else { - if (TlsUtils.isTLSv12(state.serverContext) != (state.certificateRequest.getSupportedSignatureAlgorithms() != null)) + if (TlsUtils.isTLSv12(serverContext) != (state.certificateRequest.getSupportedSignatureAlgorithms() != null)) { throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -242,14 +270,14 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa { TlsUtils.trackHashAlgorithms(handshake.getHandshakeHash(), securityParameters.getServerSigAlgs()); - if (state.serverContext.getCrypto().hasAnyStreamVerifiers(securityParameters.getServerSigAlgs())) + if (serverContext.getCrypto().hasAnyStreamVerifiers(securityParameters.getServerSigAlgs())) { handshake.getHandshakeHash().forceBuffering(); } } else { - if (state.serverContext.getCrypto().hasAnyStreamVerifiersLegacy(state.certificateRequest.getCertificateTypes())) + if (serverContext.getCrypto().hasAnyStreamVerifiersLegacy(state.certificateRequest.getCertificateTypes())) { handshake.getHandshakeHash().forceBuffering(); } @@ -276,7 +304,7 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa } else { - state.server.processClientSupplementalData(null); + server.processClientSupplementalData(null); } if (state.certificateRequest == null) @@ -292,7 +320,7 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa } else { - if (TlsUtils.isTLSv12(state.serverContext)) + if (TlsUtils.isTLSv12(serverContext)) { /* * RFC 5246 If no suitable certificate is available, the client MUST send a @@ -318,8 +346,8 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa securityParameters.sessionHash = TlsUtils.getCurrentPRFHash(handshake.getHandshakeHash()); - TlsProtocol.establishMasterSecret(state.serverContext, state.keyExchange); - recordLayer.initPendingEpoch(TlsUtils.initCipher(state.serverContext)); + TlsProtocol.establishMasterSecret(serverContext, state.keyExchange); + recordLayer.initPendingEpoch(TlsUtils.initCipher(serverContext)); /* * RFC 5246 7.4.8 This message is only sent following a client certificate that has signing @@ -341,9 +369,11 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa } } + clientMessage = null; + // NOTE: Calculated exclusive of the actual Finished message from the client - securityParameters.peerVerifyData = TlsUtils.calculateVerifyData(state.serverContext, - handshake.getHandshakeHash(), false); + securityParameters.peerVerifyData = TlsUtils.calculateVerifyData(serverContext, handshake.getHandshakeHash(), + false); processFinished(handshake.receiveMessageBody(HandshakeType.finished), securityParameters.getPeerVerifyData()); if (state.expectSessionTicket) @@ -353,14 +383,14 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa * is going to ignore any session ID it received once it sees the new_session_ticket message. */ - NewSessionTicket newSessionTicket = state.server.getNewSessionTicket(); + NewSessionTicket newSessionTicket = server.getNewSessionTicket(); byte[] newSessionTicketBody = generateNewSessionTicket(state, newSessionTicket); handshake.sendMessage(HandshakeType.new_session_ticket, newSessionTicketBody); } // NOTE: Calculated exclusive of the Finished message itself - securityParameters.localVerifyData = TlsUtils.calculateVerifyData(state.serverContext, - handshake.getHandshakeHash(), true); + securityParameters.localVerifyData = TlsUtils.calculateVerifyData(serverContext, handshake.getHandshakeHash(), + true); handshake.sendMessage(HandshakeType.finished, securityParameters.getLocalVerifyData()); handshake.finish(); @@ -369,10 +399,9 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa state.sessionParameters = new SessionParameters.Builder() .setCipherSuite(securityParameters.getCipherSuite()) - .setCompressionAlgorithm(securityParameters.getCompressionAlgorithm()) .setExtendedMasterSecret(securityParameters.isExtendedMasterSecret()) .setLocalCertificate(securityParameters.getLocalCertificate()) - .setMasterSecret(state.serverContext.getCrypto().adoptSecret(state.sessionMasterSecret)) + .setMasterSecret(serverContext.getCrypto().adoptSecret(state.sessionMasterSecret)) .setNegotiatedVersion(securityParameters.getNegotiatedVersion()) .setPeerCertificate(securityParameters.getPeerCertificate()) .setPSKIdentity(securityParameters.getPSKIdentity()) @@ -381,11 +410,11 @@ protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLa .setServerExtensions(state.serverExtensions) .build(); - state.tlsSession = TlsUtils.importSession(state.tlsSession.getSessionID(), state.sessionParameters); + state.tlsSession = TlsUtils.importSession(securityParameters.getSessionID(), state.sessionParameters); securityParameters.tlsUnique = securityParameters.getPeerVerifyData(); - state.serverContext.handshakeComplete(state.server, state.tlsSession); + serverContext.handshakeComplete(server, state.tlsSession); recordLayer.initHeartbeat(state.heartbeat, HeartbeatMode.peer_allowed_to_send == state.heartbeatPolicy); @@ -420,12 +449,18 @@ protected byte[] generateNewSessionTicket(ServerHandshakeState state, NewSession protected byte[] generateServerHello(ServerHandshakeState state, DTLSRecordLayer recordLayer) throws IOException { - TlsServerContextImpl context = state.serverContext; - SecurityParameters securityParameters = context.getSecurityParametersHandshake(); + TlsServer server = state.server; + TlsServerContextImpl serverContext = state.serverContext; + SecurityParameters securityParameters = serverContext.getSecurityParametersHandshake(); + + // TODO[dtls13] Negotiate cipher suite first? + + ProtocolVersion serverVersion; - ProtocolVersion server_version = state.server.getServerVersion(); + // NOT renegotiating { - if (!ProtocolVersion.contains(context.getClientSupportedVersions(), server_version)) + serverVersion = server.getServerVersion(); + if (!ProtocolVersion.contains(serverContext.getClientSupportedVersions(), serverVersion)) { throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -436,28 +471,113 @@ protected byte[] generateServerHello(ServerHandshakeState state, DTLSRecordLayer // : server_version; // // recordLayer.setWriteVersion(legacy_record_version); - securityParameters.negotiatedVersion = server_version; + securityParameters.negotiatedVersion = serverVersion; + } + + // TODO[dtls13] +// if (ProtocolVersion.DTLSv13.isEqualOrEarlierVersionOf(serverVersion)) +// { +// // See RFC 8446 D.4. +// recordStream.setIgnoreChangeCipherSpec(true); +// +// recordStream.setWriteVersion(ProtocolVersion.DTLSv12); +// +// return generate13ServerHello(clientHello, clientHelloMessage, false); +// } +// +// recordStream.setWriteVersion(serverVersion); + + { + boolean useGMTUnixTime = server.shouldUseGMTUnixTime(); + + securityParameters.serverRandom = TlsProtocol.createRandomBlock(useGMTUnixTime, serverContext); + + if (!serverVersion.equals(ProtocolVersion.getLatestDTLS(server.getProtocolVersions()))) + { + TlsUtils.writeDowngradeMarker(serverVersion, securityParameters.getServerRandom()); + } + } - TlsUtils.negotiatedVersionDTLSServer(context); + Hashtable clientHelloExtensions = state.clientHello.getExtensions(); + + TlsSession sessionToResume = server.getSessionToResume(state.clientHello.getSessionID()); + + boolean resumedSession = establishSession(state, sessionToResume); + + if (resumedSession && !serverVersion.equals(state.sessionParameters.getNegotiatedVersion())) + { + resumedSession = false; } + // TODO Check the session cipher suite is selectable by the same rules that getSelectedCipherSuite uses + + // TODO Check the resumed session has a peer certificate if we NEED client-auth + + // extended_master_secret { - boolean useGMTUnixTime = ProtocolVersion.DTLSv12.isEqualOrLaterVersionOf(server_version) - && state.server.shouldUseGMTUnixTime(); + boolean negotiateEMS = false; + + if (TlsUtils.isExtendedMasterSecretOptional(serverVersion) && + server.shouldUseExtendedMasterSecret()) + { + if (TlsExtensionsUtils.hasExtendedMasterSecretExtension(clientHelloExtensions)) + { + negotiateEMS = true; + } + else if (server.requiresExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure, + "Extended Master Secret extension is required"); + } + else if (resumedSession) + { + if (state.sessionParameters.isExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure, + "Extended Master Secret extension is required for EMS session resumption"); + } - securityParameters.serverRandom = TlsProtocol.createRandomBlock(useGMTUnixTime, context); + if (!server.allowLegacyResumption()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure, + "Extended Master Secret extension is required for legacy session resumption"); + } + } + } - if (!server_version.equals(ProtocolVersion.getLatestDTLS(state.server.getProtocolVersions()))) + if (resumedSession && negotiateEMS != state.sessionParameters.isExtendedMasterSecret()) { - TlsUtils.writeDowngradeMarker(server_version, securityParameters.getServerRandom()); + resumedSession = false; } + + securityParameters.extendedMasterSecret = negotiateEMS; } + if (!resumedSession) { - int cipherSuite = validateSelectedCipherSuite(state.server.getSelectedCipherSuite(), + cancelSession(state); + + byte[] newSessionID = server.getNewSessionID(); + if (null == newSessionID) + { + newSessionID = TlsUtils.EMPTY_BYTES; + } + + state.tlsSession = TlsUtils.importSession(newSessionID, null); + } + + securityParameters.resumedSession = resumedSession; + securityParameters.sessionID = state.tlsSession.getSessionID(); + + server.notifySession(state.tlsSession); + + TlsUtils.negotiatedVersionDTLSServer(serverContext); + + { + int cipherSuite = validateSelectedCipherSuite(server.getSelectedCipherSuite(), AlertDescription.internal_error); - if (!TlsUtils.isValidCipherSuiteSelection(state.offeredCipherSuites, cipherSuite) || + if (!TlsUtils.isValidCipherSuiteSelection(state.clientHello.getCipherSuites(), cipherSuite) || !TlsUtils.isValidVersionForCipherSuite(cipherSuite, securityParameters.getNegotiatedVersion())) { throw new TlsFatalAlert(AlertDescription.internal_error); @@ -466,74 +586,54 @@ protected byte[] generateServerHello(ServerHandshakeState state, DTLSRecordLayer TlsUtils.negotiatedCipherSuite(securityParameters, cipherSuite); } - state.serverExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(state.server.getServerExtensions()); - - state.server.getServerExtensionsForConnection(state.serverExtensions); - - ProtocolVersion legacy_version = server_version; - if (server_version.isLaterVersionOf(ProtocolVersion.DTLSv12)) { - legacy_version = ProtocolVersion.DTLSv12; + Hashtable sessionServerExtensions = resumedSession + ? state.sessionParameters.readServerExtensions() + : server.getServerExtensions(); - TlsExtensionsUtils.addSupportedVersionsExtensionServer(state.serverExtensions, server_version); + state.serverExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(sessionServerExtensions); } - /* - * RFC 5746 3.6. Server Behavior: Initial Handshake - */ - if (securityParameters.isSecureRenegotiation()) - { - byte[] renegExtData = TlsUtils.getExtensionData(state.serverExtensions, TlsProtocol.EXT_RenegotiationInfo); - boolean noRenegExt = (null == renegExtData); + server.getServerExtensionsForConnection(state.serverExtensions); - if (noRenegExt) + // NOT renegotiating + { + /* + * RFC 5746 3.6. Server Behavior: Initial Handshake (both full and session-resumption) + */ + if (securityParameters.isSecureRenegotiation()) { - /* - * Note that sending a "renegotiation_info" extension in response to a ClientHello - * containing only the SCSV is an explicit exception to the prohibition in RFC 5246, - * Section 7.4.1.4, on the server sending unsolicited extensions and is only allowed - * because the client is signaling its willingness to receive the extension via the - * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. - */ + byte[] serverRenegExtData = TlsUtils.getExtensionData(state.serverExtensions, + TlsProtocol.EXT_RenegotiationInfo); + boolean noRenegExt = (null == serverRenegExtData); - /* - * If the secure_renegotiation flag is set to TRUE, the server MUST include an empty - * "renegotiation_info" extension in the ServerHello message. - */ - state.serverExtensions.put(TlsProtocol.EXT_RenegotiationInfo, - TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES)); + if (noRenegExt) + { + /* + * Note that sending a "renegotiation_info" extension in response to a ClientHello + * containing only the SCSV is an explicit exception to the prohibition in RFC 5246, + * Section 7.4.1.4, on the server sending unsolicited extensions and is only allowed + * because the client is signaling its willingness to receive the extension via the + * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. + */ + + /* + * If the secure_renegotiation flag is set to TRUE, the server MUST include an empty + * "renegotiation_info" extension in the ServerHello message. + */ + state.serverExtensions.put(TlsProtocol.EXT_RenegotiationInfo, + TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES)); + } } } - /* - * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended - * master secret [..]. (and see 5.2, 5.3) - * - * RFC 8446 Appendix D. Because TLS 1.3 always hashes in the transcript up to the server - * Finished, implementations which support both TLS 1.3 and earlier versions SHOULD indicate - * the use of the Extended Master Secret extension in their APIs whenever TLS 1.3 is used. - */ - if (TlsUtils.isTLSv13(server_version)) + if (securityParameters.isExtendedMasterSecret()) { - securityParameters.extendedMasterSecret = true; + TlsExtensionsUtils.addExtendedMasterSecretExtension(state.serverExtensions); } else { - securityParameters.extendedMasterSecret = state.offeredExtendedMasterSecret - && state.server.shouldUseExtendedMasterSecret(); - - if (securityParameters.isExtendedMasterSecret()) - { - TlsExtensionsUtils.addExtendedMasterSecretExtension(state.serverExtensions); - } - else if (state.server.requiresExtendedMasterSecret()) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - else if (state.resumedSession && !state.server.allowLegacyResumption()) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } + state.serverExtensions.remove(TlsExtensionsUtils.EXT_extended_master_secret); } // Heartbeats @@ -542,37 +642,42 @@ else if (state.resumedSession && !state.server.allowLegacyResumption()) TlsExtensionsUtils.addHeartbeatExtension(state.serverExtensions, new HeartbeatExtension(state.heartbeatPolicy)); } - - - /* - * RFC 7301 3.1. When session resumption or session tickets [...] are used, the previous - * contents of this extension are irrelevant, and only the values in the new handshake - * messages are considered. - */ securityParameters.applicationProtocol = TlsExtensionsUtils.getALPNExtensionServer(state.serverExtensions); securityParameters.applicationProtocolSet = true; - /* - * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore - * extensions appearing in the client hello, and send a server hello containing no - * extensions. - */ + // Connection ID + if (ProtocolVersion.DTLSv12.equals(securityParameters.getNegotiatedVersion())) + { + /* + * RFC 9146 3. When a DTLS session is resumed or renegotiated, the "connection_id" extension is + * negotiated afresh. + */ + byte[] serverConnectionID = TlsExtensionsUtils.getConnectionIDExtension(state.serverExtensions); + if (serverConnectionID != null) + { + byte[] clientConnectionID = TlsExtensionsUtils.getConnectionIDExtension(clientHelloExtensions); + if (clientConnectionID == null) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + securityParameters.connectionIDLocal = clientConnectionID; + securityParameters.connectionIDPeer = serverConnectionID; + } + } + if (!state.serverExtensions.isEmpty()) { securityParameters.encryptThenMAC = TlsExtensionsUtils.hasEncryptThenMACExtension(state.serverExtensions); - securityParameters.maxFragmentLength = evaluateMaxFragmentLengthExtension(state.resumedSession, - state.clientExtensions, state.serverExtensions, AlertDescription.internal_error); + securityParameters.maxFragmentLength = TlsUtils.processMaxFragmentLengthExtension( + resumedSession ? null : clientHelloExtensions, state.serverExtensions, + AlertDescription.internal_error); securityParameters.truncatedHMac = TlsExtensionsUtils.hasTruncatedHMacExtension(state.serverExtensions); - /* - * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in - * a session resumption handshake. - */ - if (!state.resumedSession) + if (!resumedSession) { - // TODO[tls13] See RFC 8446 4.4.2.1 if (TlsUtils.hasExpectedEmptyExtensionData(state.serverExtensions, TlsExtensionsUtils.EXT_status_request_v2, AlertDescription.internal_error)) { @@ -583,26 +688,30 @@ else if (TlsUtils.hasExpectedEmptyExtensionData(state.serverExtensions, { securityParameters.statusRequestVersion = 1; } - } - state.expectSessionTicket = !state.resumedSession - && TlsUtils.hasExpectedEmptyExtensionData(state.serverExtensions, TlsProtocol.EXT_SessionTicket, - AlertDescription.internal_error); - } + securityParameters.clientCertificateType = TlsUtils.processClientCertificateTypeExtension( + clientHelloExtensions, state.serverExtensions, AlertDescription.internal_error); + securityParameters.serverCertificateType = TlsUtils.processServerCertificateTypeExtension( + clientHelloExtensions, state.serverExtensions, AlertDescription.internal_error); - applyMaxFragmentLengthExtension(recordLayer, securityParameters.getMaxFragmentLength()); + state.expectSessionTicket = TlsUtils.hasExpectedEmptyExtensionData(state.serverExtensions, + TlsProtocol.EXT_SessionTicket, AlertDescription.internal_error); + } + } + ServerHello serverHello = new ServerHello(serverVersion, securityParameters.getServerRandom(), + securityParameters.getSessionID(), securityParameters.getCipherSuite(), state.serverExtensions); + state.clientHello = null; - ServerHello serverHello = new ServerHello(legacy_version, securityParameters.getServerRandom(), - state.tlsSession.getSessionID(), securityParameters.getCipherSuite(), state.serverExtensions); + applyMaxFragmentLengthExtension(recordLayer, securityParameters.getMaxFragmentLength()); ByteArrayOutputStream buf = new ByteArrayOutputStream(); - serverHello.encode(state.serverContext, buf); + serverHello.encode(serverContext, buf); return buf.toByteArray(); } - protected void invalidateSession(ServerHandshakeState state) + protected void cancelSession(ServerHandshakeState state) { if (state.sessionMasterSecret != null) { @@ -616,11 +725,60 @@ protected void invalidateSession(ServerHandshakeState state) state.sessionParameters = null; } + state.tlsSession = null; + } + + protected boolean establishSession(ServerHandshakeState state, TlsSession sessionToResume) + { + state.tlsSession = null; + state.sessionParameters = null; + state.sessionMasterSecret = null; + + if (null == sessionToResume || !sessionToResume.isResumable()) + { + return false; + } + + SessionParameters sessionParameters = sessionToResume.exportSessionParameters(); + if (null == sessionParameters) + { + return false; + } + + ProtocolVersion sessionVersion = sessionParameters.getNegotiatedVersion(); + if (null == sessionVersion || !sessionVersion.isDTLS()) + { + return false; + } + + if (!sessionParameters.isExtendedMasterSecret() && + !TlsUtils.isExtendedMasterSecretOptional(sessionVersion)) + { + return false; + } + + TlsCrypto crypto = state.serverContext.getCrypto(); + TlsSecret sessionMasterSecret = TlsUtils.getSessionMasterSecret(crypto, sessionParameters.getMasterSecret()); + if (null == sessionMasterSecret) + { + return false; + } + + state.tlsSession = sessionToResume; + state.sessionParameters = sessionParameters; + state.sessionMasterSecret = sessionMasterSecret; + + return true; + } + + protected void invalidateSession(ServerHandshakeState state) + { if (state.tlsSession != null) { state.tlsSession.invalidate(); - state.tlsSession = null; } + + cancelSession(state); } protected void notifyClientCertificate(ServerHandshakeState state, Certificate clientCertificate) @@ -640,7 +798,7 @@ protected void processClientCertificate(ServerHandshakeState state, byte[] body) ByteArrayInputStream buf = new ByteArrayInputStream(body); Certificate.ParseOptions options = new Certificate.ParseOptions() - .setCertificateType(TlsExtensionsUtils.getClientCertificateTypeExtensionServer(state.clientExtensions, CertificateType.X509)) + .setCertificateType(state.serverContext.getSecurityParametersHandshake().getClientCertificateType()) .setMaxChainLength(state.server.getMaxCertificateChainLength()); Certificate clientCertificate = Certificate.parse(options, state.serverContext, buf, null); @@ -660,12 +818,13 @@ protected void processCertificateVerify(ServerHandshakeState state, byte[] body, ByteArrayInputStream buf = new ByteArrayInputStream(body); - TlsServerContextImpl context = state.serverContext; - DigitallySigned certificateVerify = DigitallySigned.parse(context, buf); + TlsServerContextImpl serverContext = state.serverContext; + DigitallySigned certificateVerify = DigitallySigned.parse(serverContext, buf); TlsProtocol.assertEmpty(buf); - TlsUtils.verifyCertificateVerifyClient(context, state.certificateRequest, certificateVerify, handshakeHash); + TlsUtils.verifyCertificateVerifyClient(serverContext, state.certificateRequest, certificateVerify, + handshakeHash); } protected void processClientHello(ServerHandshakeState state, byte[] body) @@ -679,45 +838,42 @@ protected void processClientHello(ServerHandshakeState state, byte[] body) protected void processClientHello(ServerHandshakeState state, ClientHello clientHello) throws IOException { + state.clientHello = clientHello; + // TODO Read RFCs for guidance on the expected record layer version number ProtocolVersion legacy_version = clientHello.getVersion(); - state.offeredCipherSuites = clientHello.getCipherSuites(); + int[] offeredCipherSuites = clientHello.getCipherSuites(); + Hashtable clientHelloExtensions = clientHello.getExtensions(); - /* - * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore - * extensions appearing in the client hello, and send a server hello containing no - * extensions. - */ - state.clientExtensions = clientHello.getExtensions(); - - - TlsServerContextImpl context = state.serverContext; - SecurityParameters securityParameters = context.getSecurityParametersHandshake(); + + TlsServer server = state.server; + TlsServerContextImpl serverContext = state.serverContext; + SecurityParameters securityParameters = serverContext.getSecurityParametersHandshake(); if (!legacy_version.isDTLS()) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } - context.setRSAPreMasterSecretVersion(legacy_version); + serverContext.setRSAPreMasterSecretVersion(legacy_version); - context.setClientSupportedVersions( - TlsExtensionsUtils.getSupportedVersionsExtensionClient(state.clientExtensions)); + serverContext.setClientSupportedVersions( + TlsExtensionsUtils.getSupportedVersionsExtensionClient(clientHelloExtensions)); ProtocolVersion client_version = legacy_version; - if (null == context.getClientSupportedVersions()) + if (null == serverContext.getClientSupportedVersions()) { if (client_version.isLaterVersionOf(ProtocolVersion.DTLSv12)) { client_version = ProtocolVersion.DTLSv12; } - context.setClientSupportedVersions(client_version.downTo(ProtocolVersion.DTLSv10)); + serverContext.setClientSupportedVersions(client_version.downTo(ProtocolVersion.DTLSv10)); } else { - client_version = ProtocolVersion.getLatestDTLS(context.getClientSupportedVersions()); + client_version = ProtocolVersion.getLatestDTLS(serverContext.getClientSupportedVersions()); } if (!ProtocolVersion.SERVER_EARLIEST_SUPPORTED_DTLS.isEqualOrEarlierVersionOf(client_version)) @@ -725,24 +881,29 @@ protected void processClientHello(ServerHandshakeState state, ClientHello client throw new TlsFatalAlert(AlertDescription.protocol_version); } - context.setClientVersion(client_version); + serverContext.setClientVersion(client_version); - state.server.notifyClientVersion(context.getClientVersion()); + server.notifyClientVersion(serverContext.getClientVersion()); securityParameters.clientRandom = clientHello.getRandom(); - state.server.notifyFallback(Arrays.contains(state.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV)); + server.notifyFallback(Arrays.contains(offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV)); - state.server.notifyOfferedCipherSuites(state.offeredCipherSuites); + server.notifyOfferedCipherSuites(offeredCipherSuites); /* * TODO[resumption] Check RFC 7627 5.4. for required behaviour */ - /* - * RFC 5746 3.6. Server Behavior: Initial Handshake - */ + byte[] clientRenegExtData = TlsUtils.getExtensionData(clientHelloExtensions, + TlsProtocol.EXT_RenegotiationInfo); + + // NOT renegotiatiing { + /* + * RFC 5746 3.6. Server Behavior: Initial Handshake (both full and session-resumption) + */ + /* * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the @@ -754,7 +915,7 @@ protected void processClientHello(ServerHandshakeState state, ClientHello client * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag * to TRUE. */ - if (Arrays.contains(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) + if (Arrays.contains(offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) { securityParameters.secureRenegotiation = true; } @@ -763,8 +924,7 @@ protected void processClientHello(ServerHandshakeState state, ClientHello client * The server MUST check if the "renegotiation_info" extension is included in the * ClientHello. */ - byte[] renegExtData = TlsUtils.getExtensionData(state.clientExtensions, TlsProtocol.EXT_RenegotiationInfo); - if (renegExtData != null) + if (clientRenegExtData != null) { /* * If the extension is present, set secure_renegotiation flag to TRUE. The @@ -773,23 +933,22 @@ protected void processClientHello(ServerHandshakeState state, ClientHello client */ securityParameters.secureRenegotiation = true; - if (!Arrays.constantTimeAreEqual(renegExtData, TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) + if (!Arrays.constantTimeAreEqual(clientRenegExtData, + TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) { throw new TlsFatalAlert(AlertDescription.handshake_failure); } } } - state.server.notifySecureRenegotiation(securityParameters.isSecureRenegotiation()); - - state.offeredExtendedMasterSecret = TlsExtensionsUtils.hasExtendedMasterSecretExtension(state.clientExtensions); + server.notifySecureRenegotiation(securityParameters.isSecureRenegotiation()); - if (state.clientExtensions != null) + if (clientHelloExtensions != null) { // NOTE: Validates the padding extension data, if present - TlsExtensionsUtils.getPaddingExtension(state.clientExtensions); + TlsExtensionsUtils.getPaddingExtension(clientHelloExtensions); - securityParameters.clientServerNames = TlsExtensionsUtils.getServerNameExtensionClient(state.clientExtensions); + securityParameters.clientServerNames = TlsExtensionsUtils.getServerNameExtensionClient(clientHelloExtensions); /* * RFC 5246 7.4.1.4.1. Note: this extension is not meaningful for TLS versions prior @@ -797,26 +956,26 @@ protected void processClientHello(ServerHandshakeState state, ClientHello client */ if (TlsUtils.isSignatureAlgorithmsExtensionAllowed(client_version)) { - TlsUtils.establishClientSigAlgs(securityParameters, state.clientExtensions); + TlsUtils.establishClientSigAlgs(securityParameters, clientHelloExtensions); } - securityParameters.clientSupportedGroups = TlsExtensionsUtils.getSupportedGroupsExtension(state.clientExtensions); + securityParameters.clientSupportedGroups = TlsExtensionsUtils.getSupportedGroupsExtension(clientHelloExtensions); // Heartbeats { - HeartbeatExtension heartbeatExtension = TlsExtensionsUtils.getHeartbeatExtension(state.clientExtensions); + HeartbeatExtension heartbeatExtension = TlsExtensionsUtils.getHeartbeatExtension(clientHelloExtensions); if (null != heartbeatExtension) { if (HeartbeatMode.peer_allowed_to_send == heartbeatExtension.getMode()) { - state.heartbeat = state.server.getHeartbeat(); + state.heartbeat = server.getHeartbeat(); } - state.heartbeatPolicy = state.server.getHeartbeatPolicy(); + state.heartbeatPolicy = server.getHeartbeatPolicy(); } } - state.server.processClientExtensions(state.clientExtensions); + server.processClientExtensions(clientHelloExtensions); } } @@ -859,11 +1018,8 @@ protected static class ServerHandshakeState SessionParameters sessionParameters = null; TlsSecret sessionMasterSecret = null; SessionParameters.Builder sessionParametersBuilder = null; - int[] offeredCipherSuites = null; - Hashtable clientExtensions = null; + ClientHello clientHello = null; Hashtable serverExtensions = null; - boolean offeredExtendedMasterSecret = false; - boolean resumedSession = false; boolean expectSessionTicket = false; TlsKeyExchange keyExchange = null; TlsCredentials serverCredentials = null; diff --git a/tls/src/main/java/org/bouncycastle/tls/DTLSTransport.java b/tls/src/main/java/org/bouncycastle/tls/DTLSTransport.java index 74a4bd710d..bd51764b04 100644 --- a/tls/src/main/java/org/bouncycastle/tls/DTLSTransport.java +++ b/tls/src/main/java/org/bouncycastle/tls/DTLSTransport.java @@ -27,6 +27,12 @@ public int getSendLimit() public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException + { + return receive(buf, off, len, waitMillis, null); + } + + public int receive(byte[] buf, int off, int len, int waitMillis, DTLSRecordCallback recordCallback) + throws IOException { if (null == buf) { @@ -47,10 +53,67 @@ public int receive(byte[] buf, int off, int len, int waitMillis) try { - return recordLayer.receive(buf, off, len, waitMillis); + return recordLayer.receive(buf, off, len, waitMillis, recordCallback); } catch (TlsFatalAlert fatalAlert) { + if (AlertDescription.bad_record_mac == fatalAlert.getAlertDescription()) + { + return -1; + } + + recordLayer.fail(fatalAlert.getAlertDescription()); + throw fatalAlert; + } + catch (InterruptedIOException e) + { + throw e; + } + catch (IOException e) + { + recordLayer.fail(AlertDescription.internal_error); + throw e; + } + catch (RuntimeException e) + { + recordLayer.fail(AlertDescription.internal_error); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + + public int receivePending(byte[] buf, int off, int len) + throws IOException + { + return receivePending(buf, off, len, null); + } + + public int receivePending(byte[] buf, int off, int len, DTLSRecordCallback recordCallback) + throws IOException + { + if (null == buf) + { + throw new NullPointerException("'buf' cannot be null"); + } + if (off < 0 || off >= buf.length) + { + throw new IllegalArgumentException("'off' is an invalid offset: " + off); + } + if (len < 0 || len > buf.length - off) + { + throw new IllegalArgumentException("'len' is an invalid length: " + len); + } + + try + { + return recordLayer.receivePending(buf, off, len, recordCallback); + } + catch (TlsFatalAlert fatalAlert) + { + if (AlertDescription.bad_record_mac == fatalAlert.getAlertDescription()) + { + return -1; + } + recordLayer.fail(fatalAlert.getAlertDescription()); throw fatalAlert; } diff --git a/tls/src/main/java/org/bouncycastle/tls/DTLSVerifier.java b/tls/src/main/java/org/bouncycastle/tls/DTLSVerifier.java index cde7a0fac4..a67d181a2c 100644 --- a/tls/src/main/java/org/bouncycastle/tls/DTLSVerifier.java +++ b/tls/src/main/java/org/bouncycastle/tls/DTLSVerifier.java @@ -1,5 +1,7 @@ package org.bouncycastle.tls; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import org.bouncycastle.tls.crypto.TlsCrypto; @@ -7,81 +9,79 @@ import org.bouncycastle.tls.crypto.TlsMACOutputStream; import org.bouncycastle.util.Arrays; +/** + * Implements cookie generation/verification for a DTLS server as described in RFC 4347, + * 4.2.1. Denial of Service Countermeasures. + *

      + * RFC 4347 4.2.1 additionally recommends changing the secret frequently. This class does not handle that + * internally, so the instance should be replaced instead. + */ public class DTLSVerifier { - private static TlsMAC createCookieMAC(TlsCrypto crypto) - { - TlsMAC mac = crypto.createHMAC(MACAlgorithm.hmac_sha256); - - byte[] secret = new byte[mac.getMacLength()]; - crypto.getSecureRandom().nextBytes(secret); - - mac.setKey(secret, 0, secret.length); - - return mac; - } - - private final TlsMAC cookieMAC; - private final TlsMACOutputStream cookieMACOutputStream; + private final TlsCrypto crypto; + private final byte[] macKey; public DTLSVerifier(TlsCrypto crypto) { - this.cookieMAC = createCookieMAC(crypto); - this.cookieMACOutputStream = new TlsMACOutputStream(cookieMAC); + this.crypto = crypto; + this.macKey = new byte[32]; + crypto.getSecureRandom().nextBytes(macKey); } - public synchronized DTLSRequest verifyRequest(byte[] clientID, byte[] data, int dataOff, int dataLen, - DatagramSender sender) + public DTLSRequest verifyRequest(byte[] clientID, byte[] data, int dataOff, int dataLen, DatagramSender sender) { - boolean resetCookieMAC = true; - try { - cookieMAC.update(clientID, 0, clientID.length); + int msgLen = DTLSRecordLayer.receiveClientHelloRecord(data, dataOff, dataLen); + if (msgLen < 0) + { + return null; + } + + int bodyLength = msgLen - DTLSReliableHandshake.MESSAGE_HEADER_LENGTH; + if (bodyLength < 39) // Minimum (syntactically) valid DTLS ClientHello length + { + return null; + } + + int msgOff = dataOff + DTLSRecordLayer.RECORD_HEADER_LENGTH; + + ByteArrayInputStream buf = DTLSReliableHandshake.receiveClientHelloMessage(data, msgOff, msgLen); + if (buf == null) + { + return null; + } + + ByteArrayOutputStream macInput = new ByteArrayOutputStream(bodyLength); + ClientHello clientHello = ClientHello.parse(buf, macInput); + if (clientHello == null) + { + return null; + } + + long recordSeq = TlsUtils.readUint48(data, dataOff + 5); + + byte[] cookie = clientHello.getCookie(); - DTLSRequest request = DTLSReliableHandshake.readClientRequest(data, dataOff, dataLen, cookieMACOutputStream); - if (null != request) + TlsMAC mac = crypto.createHMAC(MACAlgorithm.hmac_sha256); + mac.setKey(macKey, 0, macKey.length); + mac.update(clientID, 0, clientID.length); + macInput.writeTo(new TlsMACOutputStream(mac)); + byte[] expectedCookie = mac.calculateMAC(); + + if (Arrays.constantTimeAreEqual(expectedCookie, cookie)) { - byte[] expectedCookie = cookieMAC.calculateMAC(); - resetCookieMAC = false; - - // TODO Consider stricter HelloVerifyRequest protocol -// switch (request.getMessageSeq()) -// { -// case 0: -// { -// DTLSReliableHandshake.sendHelloVerifyRequest(sender, request.getRecordSeq(), expectedCookie); -// break; -// } -// case 1: -// { -// if (Arrays.constantTimeAreEqual(expectedCookie, request.getClientHello().getCookie())) -// { -// return request; -// } -// break; -// } -// } - - if (Arrays.constantTimeAreEqual(expectedCookie, request.getClientHello().getCookie())) - { - return request; - } - - DTLSReliableHandshake.sendHelloVerifyRequest(sender, request.getRecordSeq(), expectedCookie); + byte[] message = TlsUtils.copyOfRangeExact(data, msgOff, msgOff + msgLen); + + return new DTLSRequest(recordSeq, message, clientHello); } + + DTLSReliableHandshake.sendHelloVerifyRequest(sender, recordSeq, expectedCookie); } catch (IOException e) { // Ignore } - finally - { - if (resetCookieMAC) - { - cookieMAC.reset(); - } - } return null; } diff --git a/tls/src/main/java/org/bouncycastle/tls/DefaultTlsClient.java b/tls/src/main/java/org/bouncycastle/tls/DefaultTlsClient.java index 81fac1bc9f..c5e192f55e 100644 --- a/tls/src/main/java/org/bouncycastle/tls/DefaultTlsClient.java +++ b/tls/src/main/java/org/bouncycastle/tls/DefaultTlsClient.java @@ -28,9 +28,6 @@ public abstract class DefaultTlsClient CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, - CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256, - CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, - CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, }; public DefaultTlsClient(TlsCrypto crypto) diff --git a/tls/src/main/java/org/bouncycastle/tls/DefaultTlsServer.java b/tls/src/main/java/org/bouncycastle/tls/DefaultTlsServer.java index ac186f8984..c0b33d929e 100644 --- a/tls/src/main/java/org/bouncycastle/tls/DefaultTlsServer.java +++ b/tls/src/main/java/org/bouncycastle/tls/DefaultTlsServer.java @@ -33,12 +33,6 @@ public abstract class DefaultTlsServer CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, - CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384, - CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256, - CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256, - CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, - CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, - CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, }; public DefaultTlsServer(TlsCrypto crypto) diff --git a/tls/src/main/java/org/bouncycastle/tls/EncryptionAlgorithm.java b/tls/src/main/java/org/bouncycastle/tls/EncryptionAlgorithm.java index 1af112ca9e..a1e44979ab 100644 --- a/tls/src/main/java/org/bouncycastle/tls/EncryptionAlgorithm.java +++ b/tls/src/main/java/org/bouncycastle/tls/EncryptionAlgorithm.java @@ -77,4 +77,11 @@ public class EncryptionAlgorithm * GMT 0024-2014 */ public static final int SM4_CBC = 28; + + /* + * RFC 9189 + */ + public static final int KUZNYECHIK_CTR_OMAC = 29; + public static final int MAGMA_CTR_OMAC = 30; + public static final int _28147_CNT_IMIT = 31; } diff --git a/tls/src/main/java/org/bouncycastle/tls/ExtensionType.java b/tls/src/main/java/org/bouncycastle/tls/ExtensionType.java index a2293ed19d..7c5163a766 100644 --- a/tls/src/main/java/org/bouncycastle/tls/ExtensionType.java +++ b/tls/src/main/java/org/bouncycastle/tls/ExtensionType.java @@ -133,6 +133,11 @@ public class ExtensionType public static final int signature_algorithms_cert = 50; public static final int key_share = 51; + /* + * RFC 9146 + */ + public static final int connection_id = 54; + /* * RFC 5746 3.2. */ @@ -220,6 +225,8 @@ public static String getName(int extensionType) return "signature_algorithms_cert"; case key_share: return "key_share"; + case connection_id: + return "connection_id"; case renegotiation_info: return "renegotiation_info"; default: @@ -275,6 +282,7 @@ public static boolean isRecognized(int extensionType) case post_handshake_auth: case signature_algorithms_cert: case key_share: + case connection_id: case renegotiation_info: return true; default: diff --git a/tls/src/main/java/org/bouncycastle/tls/KeyExchangeAlgorithm.java b/tls/src/main/java/org/bouncycastle/tls/KeyExchangeAlgorithm.java index 619577f0cb..7329ae843e 100644 --- a/tls/src/main/java/org/bouncycastle/tls/KeyExchangeAlgorithm.java +++ b/tls/src/main/java/org/bouncycastle/tls/KeyExchangeAlgorithm.java @@ -59,6 +59,11 @@ public class KeyExchangeAlgorithm */ public static final int SM2 = 25; + /* + * RFC 9189 + */ + public static final int GOSTR341112_256 = 26; + public static boolean isAnonymous(int keyExchangeAlgorithm) { switch (keyExchangeAlgorithm) diff --git a/tls/src/main/java/org/bouncycastle/tls/NamedGroup.java b/tls/src/main/java/org/bouncycastle/tls/NamedGroup.java index a8aaeb14a9..7e28d6ed65 100644 --- a/tls/src/main/java/org/bouncycastle/tls/NamedGroup.java +++ b/tls/src/main/java/org/bouncycastle/tls/NamedGroup.java @@ -61,7 +61,7 @@ public class NamedGroup public static final int brainpoolP512r1tls13 = 33; /* - * draft-smyshlyaev-tls12-gost-suites-10 + * RFC 9189 */ public static final int GC256A = 34; public static final int GC256B = 35; @@ -102,6 +102,21 @@ public class NamedGroup public static final int arbitrary_explicit_prime_curves = 0xFF01; public static final int arbitrary_explicit_char2_curves = 0xFF02; + /** Experimental API (unstable): unofficial value from Open Quantum Safe project. */ + public static final int OQS_mlkem512 = 0x0247; + /** Experimental API (unstable): unofficial value from Open Quantum Safe project. */ + public static final int OQS_mlkem768 = 0x0248; + /** Experimental API (unstable): unofficial value from Open Quantum Safe project. */ + public static final int OQS_mlkem1024 = 0x0249; + + /* + * draft-connolly-tls-mlkem-key-agreement-01 + */ + /** Experimental API (unstable): draft value requested in draft-connolly-tls-mlkem-key-agreement. */ + public static final int DRAFT_mlkem768 = 0x0768; + /** Experimental API (unstable): draft value requested in draft-connolly-tls-mlkem-key-agreement. */ + public static final int DRAFT_mlkem1024 = 0x1024; + /* Names of the actual underlying elliptic curves (not necessarily matching the NamedGroup names). */ private static final String[] CURVE_NAMES = new String[] { "sect163k1", "sect163r1", "sect163r2", "sect193r1", "sect193r2", "sect233k1", "sect233r1", "sect239k1", "sect283k1", "sect283r1", "sect409k1", "sect409r1", @@ -117,26 +132,49 @@ public class NamedGroup public static boolean canBeNegotiated(int namedGroup, ProtocolVersion version) { - if (TlsUtils.isTLSv13(version)) + switch (namedGroup) { - if ((namedGroup >= sect163k1 && namedGroup <= secp256k1) - || (namedGroup >= brainpoolP256r1 && namedGroup <= brainpoolP512r1) - || (namedGroup >= GC256A && namedGroup <= GC512C) - || (namedGroup >= arbitrary_explicit_prime_curves && namedGroup <= arbitrary_explicit_char2_curves)) - { - return false; - } + case secp256r1: + case secp384r1: + case secp521r1: + case x25519: + case x448: + return true; } - else + + if (refersToASpecificFiniteField(namedGroup)) { - if ((namedGroup >= brainpoolP256r1tls13 && namedGroup <= brainpoolP512r1tls13) - || (namedGroup == curveSM2)) + return true; + } + + boolean isTLSv13 = TlsUtils.isTLSv13(version); + + // NOTE: Version-independent curves checked above + if (refersToASpecificCurve(namedGroup)) + { + switch (namedGroup) { - return false; + case brainpoolP256r1tls13: + case brainpoolP384r1tls13: + case brainpoolP512r1tls13: + case curveSM2: + return isTLSv13; + default: + return !isTLSv13; } } - return isValid(namedGroup); + if (refersToASpecificKem(namedGroup)) + { + return isTLSv13; + } + + if (namedGroup >= arbitrary_explicit_prime_curves && namedGroup <= arbitrary_explicit_char2_curves) + { + return !isTLSv13; + } + + return isPrivate(namedGroup); } public static int getCurveBits(int namedGroup) @@ -260,6 +298,23 @@ public static String getFiniteFieldName(int namedGroup) return null; } + public static String getKemName(int namedGroup) + { + switch (namedGroup) + { + case OQS_mlkem512: + return "ML-KEM-512"; + case OQS_mlkem768: + case DRAFT_mlkem768: + return "ML-KEM-768"; + case OQS_mlkem1024: + case DRAFT_mlkem1024: + return "ML-KEM-1024"; + default: + return null; + } + } + public static int getMaximumChar2CurveBits() { return 571; @@ -315,6 +370,16 @@ public static String getName(int namedGroup) return "GC512C"; case curveSM2: return "curveSM2"; + case OQS_mlkem512: + return "OQS_mlkem512"; + case OQS_mlkem768: + return "OQS_mlkem768"; + case OQS_mlkem1024: + return "OQS_mlkem1024"; + case DRAFT_mlkem768: + return "DRAFT_mlkem768"; + case DRAFT_mlkem1024: + return "DRAFT_mlkem1024"; case arbitrary_explicit_prime_curves: return "arbitrary_explicit_prime_curves"; case arbitrary_explicit_char2_curves: @@ -344,6 +409,12 @@ public static String getStandardName(int namedGroup) return finiteFieldName; } + String kemName = getKemName(namedGroup); + if (null != kemName) + { + return kemName; + } + return null; } @@ -358,6 +429,11 @@ public static boolean isChar2Curve(int namedGroup) || (namedGroup == arbitrary_explicit_char2_curves); } + public static boolean isFiniteField(int namedGroup) + { + return (namedGroup & 0xFFFFFF00) == 0x00000100; + } + public static boolean isPrimeCurve(int namedGroup) { return (namedGroup >= secp160k1 && namedGroup <= curveSM2) @@ -410,6 +486,22 @@ public static boolean refersToASpecificFiniteField(int namedGroup) public static boolean refersToASpecificGroup(int namedGroup) { return refersToASpecificCurve(namedGroup) - || refersToASpecificFiniteField(namedGroup); + || refersToASpecificFiniteField(namedGroup) + || refersToASpecificKem(namedGroup); + } + + public static boolean refersToASpecificKem(int namedGroup) + { + switch (namedGroup) + { + case OQS_mlkem512: + case OQS_mlkem768: + case OQS_mlkem1024: + case DRAFT_mlkem768: + case DRAFT_mlkem1024: + return true; + default: + return false; + } } } diff --git a/tls/src/main/java/org/bouncycastle/tls/NamedGroupRole.java b/tls/src/main/java/org/bouncycastle/tls/NamedGroupRole.java index 724cfcc167..eea7d9262c 100644 --- a/tls/src/main/java/org/bouncycastle/tls/NamedGroupRole.java +++ b/tls/src/main/java/org/bouncycastle/tls/NamedGroupRole.java @@ -9,4 +9,5 @@ public class NamedGroupRole public static final int dh = 1; public static final int ecdh = 2; public static final int ecdsa = 3; + public static final int kem = 4; } diff --git a/tls/src/main/java/org/bouncycastle/tls/PRFAlgorithm.java b/tls/src/main/java/org/bouncycastle/tls/PRFAlgorithm.java index 0b7c1cf97c..360ab7a75b 100644 --- a/tls/src/main/java/org/bouncycastle/tls/PRFAlgorithm.java +++ b/tls/src/main/java/org/bouncycastle/tls/PRFAlgorithm.java @@ -16,6 +16,7 @@ public class PRFAlgorithm public static final int tls13_hkdf_sha384 = 5; // public static final int tls13_hkdf_sha512 = 6; public static final int tls13_hkdf_sm3 = 7; + public static final int tls_prf_gostr3411_2012_256 = 8; public static String getName(int prfAlgorithm) { @@ -35,6 +36,8 @@ public static String getName(int prfAlgorithm) return "tls13_hkdf_sha384"; case tls13_hkdf_sm3: return "tls13_hkdf_sm3"; + case tls_prf_gostr3411_2012_256: + return "tls_prf_gostr3411_2012_256"; default: return "UNKNOWN"; } diff --git a/tls/src/main/java/org/bouncycastle/tls/RecordStream.java b/tls/src/main/java/org/bouncycastle/tls/RecordStream.java index 4522a1f4c5..5fdd9dc0d5 100644 --- a/tls/src/main/java/org/bouncycastle/tls/RecordStream.java +++ b/tls/src/main/java/org/bouncycastle/tls/RecordStream.java @@ -156,7 +156,9 @@ RecordPreview previewRecordHeader(byte[] recordHeader) throws IOException // NOTE: For TLS 1.3, this only MIGHT be application data if (ContentType.application_data == recordType && handler.isApplicationDataReady()) { - applicationDataLimit = Math.max(0, Math.min(plaintextLimit, readCipher.getPlaintextLimit(length))); + int plaintextDecodeLimit = readCipher.getPlaintextDecodeLimit(length); + + applicationDataLimit = Math.max(0, Math.min(plaintextLimit, plaintextDecodeLimit)); } return new RecordPreview(recordSize, applicationDataLimit); @@ -172,7 +174,7 @@ RecordPreview previewOutputRecord(int contentLength) int previewOutputRecordSize(int contentLength) { // assert contentLength <= plaintextLimit - return RecordFormat.FRAGMENT_OFFSET + writeCipher.getCiphertextEncodeLimit(contentLength, plaintextLimit); + return RecordFormat.FRAGMENT_OFFSET + writeCipher.getCiphertextEncodeLimit(contentLength); } boolean readFullRecord(byte[] input, int inputOff, int inputLen) @@ -373,7 +375,7 @@ private short checkRecordType(byte[] buf, int off) this.ciphertextLimit = readCipher.getCiphertextDecodeLimit(plaintextLimit); readSeqNo.reset(); } - else if (readCipher.usesOpaqueRecordType()) + else if (readCipher.usesOpaqueRecordTypeDecode()) { if (ContentType.application_data != recordType) { diff --git a/tls/src/main/java/org/bouncycastle/tls/SecurityParameters.java b/tls/src/main/java/org/bouncycastle/tls/SecurityParameters.java index 47d5c52689..3a933d2858 100644 --- a/tls/src/main/java/org/bouncycastle/tls/SecurityParameters.java +++ b/tls/src/main/java/org/bouncycastle/tls/SecurityParameters.java @@ -15,11 +15,9 @@ public class SecurityParameters boolean renegotiating = false; boolean secureRenegotiation = false; int cipherSuite = CipherSuite.TLS_NULL_WITH_NULL_NULL; - final short compressionAlgorithm = CompressionMethod._null; short maxFragmentLength = -1; int prfAlgorithm = -1; int prfCryptoHashAlgorithm = -1; - short prfHashAlgorithm = -1; int prfHashLength = -1; int verifyDataLength = -1; TlsSecret baseKeyClient = null; @@ -58,12 +56,18 @@ public class SecurityParameters Certificate peerCertificate = null; ProtocolVersion negotiatedVersion = null; int statusRequestVersion = 0; - short clientCertificateType = -1; + short clientCertificateType = CertificateType.X509; + short serverCertificateType = CertificateType.X509; // TODO[tls-ops] Investigate whether we can handle verify data using TlsSecret byte[] localVerifyData = null; byte[] peerVerifyData = null; + /** Connection ID we use during communication to the peer. */ + byte[] connectionIDLocal; + /** Connection ID our peer uses for communication to us. */ + byte[] connectionIDPeer; + void clear() { this.sessionHash = null; @@ -143,6 +147,16 @@ public int[] getClientSupportedGroups() return clientSupportedGroups; } + public byte[] getConnectionIDLocal() + { + return connectionIDLocal; + } + + public byte[] getConnectionIDPeer() + { + return connectionIDPeer; + } + public Vector getServerSigAlgs() { return serverSigAlgs; @@ -160,10 +174,12 @@ public int[] getServerSupportedGroups() /** * @return {@link CompressionMethod} + * + * @deprecated Will be removed. Use constant CompressionMethod._null instead. */ public short getCompressionAlgorithm() { - return compressionAlgorithm; + return CompressionMethod._null; } /** @@ -198,16 +214,6 @@ public int getPRFCryptoHashAlgorithm() return prfCryptoHashAlgorithm; } - /** - * @return {@link HashAlgorithm} for the current {@link PRFAlgorithm} - * - * @deprecated Use {@link #getPRFCryptoHashAlgorithm()} instead. - */ - public short getPRFHashAlgorithm() - { - return prfHashAlgorithm; - } - public int getPRFHashLength() { return prfHashLength; @@ -373,6 +379,11 @@ public short getClientCertificateType() return clientCertificateType; } + public short getServerCertificateType() + { + return serverCertificateType; + } + private static TlsSecret clearSecret(TlsSecret secret) { if (null != secret) diff --git a/tls/src/main/java/org/bouncycastle/tls/SessionParameters.java b/tls/src/main/java/org/bouncycastle/tls/SessionParameters.java index 5986f88775..772e7271d0 100644 --- a/tls/src/main/java/org/bouncycastle/tls/SessionParameters.java +++ b/tls/src/main/java/org/bouncycastle/tls/SessionParameters.java @@ -13,7 +13,6 @@ public final class SessionParameters public static final class Builder { private int cipherSuite = -1; - private short compressionAlgorithm = -1; private Certificate localCertificate = null; private TlsSecret masterSecret = null; private ProtocolVersion negotiatedVersion; @@ -30,11 +29,9 @@ public Builder() public SessionParameters build() { validate(this.cipherSuite >= 0, "cipherSuite"); - validate(this.compressionAlgorithm >= 0, "compressionAlgorithm"); validate(this.masterSecret != null, "masterSecret"); - return new SessionParameters(cipherSuite, compressionAlgorithm, localCertificate, masterSecret, - negotiatedVersion, peerCertificate, pskIdentity, srpIdentity, encodedServerExtensions, - extendedMasterSecret); + return new SessionParameters(cipherSuite, localCertificate, masterSecret, negotiatedVersion, + peerCertificate, pskIdentity, srpIdentity, encodedServerExtensions, extendedMasterSecret); } public Builder setCipherSuite(int cipherSuite) @@ -43,12 +40,6 @@ public Builder setCipherSuite(int cipherSuite) return this; } - public Builder setCompressionAlgorithm(short compressionAlgorithm) - { - this.compressionAlgorithm = compressionAlgorithm; - return this; - } - public Builder setExtendedMasterSecret(boolean extendedMasterSecret) { this.extendedMasterSecret = extendedMasterSecret; @@ -116,7 +107,6 @@ private void validate(boolean condition, String parameter) } private int cipherSuite; - private short compressionAlgorithm; private Certificate localCertificate; private TlsSecret masterSecret; private ProtocolVersion negotiatedVersion; @@ -126,12 +116,11 @@ private void validate(boolean condition, String parameter) private byte[] encodedServerExtensions; private boolean extendedMasterSecret; - private SessionParameters(int cipherSuite, short compressionAlgorithm, Certificate localCertificate, - TlsSecret masterSecret, ProtocolVersion negotiatedVersion, Certificate peerCertificate, byte[] pskIdentity, - byte[] srpIdentity, byte[] encodedServerExtensions, boolean extendedMasterSecret) + private SessionParameters(int cipherSuite, Certificate localCertificate, TlsSecret masterSecret, + ProtocolVersion negotiatedVersion, Certificate peerCertificate, byte[] pskIdentity, byte[] srpIdentity, + byte[] encodedServerExtensions, boolean extendedMasterSecret) { this.cipherSuite = cipherSuite; - this.compressionAlgorithm = compressionAlgorithm; this.localCertificate = localCertificate; this.masterSecret = masterSecret; this.negotiatedVersion = negotiatedVersion; @@ -152,9 +141,8 @@ public void clear() public SessionParameters copy() { - return new SessionParameters(cipherSuite, compressionAlgorithm, localCertificate, masterSecret, - negotiatedVersion, peerCertificate, pskIdentity, srpIdentity, encodedServerExtensions, - extendedMasterSecret); + return new SessionParameters(cipherSuite, localCertificate, masterSecret, negotiatedVersion, peerCertificate, + pskIdentity, srpIdentity, encodedServerExtensions, extendedMasterSecret); } public int getCipherSuite() @@ -162,11 +150,6 @@ public int getCipherSuite() return cipherSuite; } - public short getCompressionAlgorithm() - { - return compressionAlgorithm; - } - public Certificate getLocalCertificate() { return localCertificate; diff --git a/tls/src/main/java/org/bouncycastle/tls/SignatureAlgorithm.java b/tls/src/main/java/org/bouncycastle/tls/SignatureAlgorithm.java index 889b1d9145..4acfab6d38 100644 --- a/tls/src/main/java/org/bouncycastle/tls/SignatureAlgorithm.java +++ b/tls/src/main/java/org/bouncycastle/tls/SignatureAlgorithm.java @@ -35,7 +35,7 @@ public class SignatureAlgorithm public static final short ecdsa_brainpoolP512r1tls13_sha512 = 28; /* - * draft-smyshlyaev-tls12-gost-suites-10 + * RFC 9189 */ public static final short gostr34102012_256 = 64; public static final short gostr34102012_512 = 65; diff --git a/tls/src/main/java/org/bouncycastle/tls/SignatureScheme.java b/tls/src/main/java/org/bouncycastle/tls/SignatureScheme.java index 863433f17d..2a980300fc 100644 --- a/tls/src/main/java/org/bouncycastle/tls/SignatureScheme.java +++ b/tls/src/main/java/org/bouncycastle/tls/SignatureScheme.java @@ -178,7 +178,7 @@ public static int getNamedGroup(int signatureScheme) } } - /** @deprecated Use {@link #getCryptoHashAlgorithm(int) instead. */ + /** @deprecated Use {@link #getCryptoHashAlgorithm(int)} instead. */ public static int getRSAPSSCryptoHashAlgorithm(int signatureScheme) { switch (signatureScheme) diff --git a/tls/src/main/java/org/bouncycastle/tls/TlsClient.java b/tls/src/main/java/org/bouncycastle/tls/TlsClient.java index 148f5bd0f3..3f488dcff4 100644 --- a/tls/src/main/java/org/bouncycastle/tls/TlsClient.java +++ b/tls/src/main/java/org/bouncycastle/tls/TlsClient.java @@ -48,6 +48,8 @@ Hashtable getClientExtensions() */ Vector getEarlyKeyShareGroups(); + boolean shouldUseCompatibilityMode(); + void notifyServerVersion(ProtocolVersion selectedVersion) throws IOException; @@ -84,7 +86,7 @@ void notifyServerVersion(ProtocolVersion selectedVersion) * NOTE: This is not called for session resumption handshakes. * * @param serverExtensions - * (Integer -> byte[]) + * (Integer -> byte[]) * @throws IOException */ void processServerExtensions(Hashtable serverExtensions) diff --git a/tls/src/main/java/org/bouncycastle/tls/TlsClientProtocol.java b/tls/src/main/java/org/bouncycastle/tls/TlsClientProtocol.java index 5bcea54ed8..d581f10ae8 100644 --- a/tls/src/main/java/org/bouncycastle/tls/TlsClientProtocol.java +++ b/tls/src/main/java/org/bouncycastle/tls/TlsClientProtocol.java @@ -372,7 +372,7 @@ protected void handleHandshakeMessage(short type, HandshakeMessageInput buf) throw new TlsFatalAlert(AlertDescription.internal_error); } - if (securityParameters.isResumedSession()) + if (securityParameters.isResumedSession() && type != HandshakeType.hello_request) { if (type != HandshakeType.finished || this.connection_state != CS_SERVER_HELLO) { @@ -1099,8 +1099,8 @@ protected void processServerHello(ServerHello serverHello) Hashtable serverHelloExtensions = serverHello.getExtensions(); final ProtocolVersion legacy_version = serverHello.getVersion(); - final ProtocolVersion supported_version = TlsExtensionsUtils - .getSupportedVersionsExtensionServer(serverHelloExtensions); + final ProtocolVersion supported_version = TlsExtensionsUtils.getSupportedVersionsExtensionServer( + serverHelloExtensions); final ProtocolVersion server_version; if (null == supported_version) @@ -1170,6 +1170,16 @@ protected void processServerHello(ServerHello serverHello) tlsClient.notifySessionID(selectedSessionID); securityParameters.resumedSession = selectedSessionID.length > 0 && this.tlsSession != null && Arrays.areEqual(selectedSessionID, this.tlsSession.getSessionID()); + + if (securityParameters.isResumedSession()) + { + if (serverHello.getCipherSuite() != sessionParameters.getCipherSuite() || + !securityParameters.getNegotiatedVersion().equals(sessionParameters.getNegotiatedVersion())) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, + "ServerHello parameters do not match resumed session"); + } + } } /* @@ -1182,7 +1192,8 @@ protected void processServerHello(ServerHello serverHello) if (!TlsUtils.isValidCipherSuiteSelection(offeredCipherSuites, cipherSuite) || !TlsUtils.isValidVersionForCipherSuite(cipherSuite, securityParameters.getNegotiatedVersion())) { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); + throw new TlsFatalAlert(AlertDescription.illegal_parameter, + "ServerHello selected invalid cipher suite"); } TlsUtils.negotiatedCipherSuite(securityParameters, cipherSuite); @@ -1197,9 +1208,9 @@ protected void processServerHello(ServerHello serverHello) * Hello is always allowed. */ this.serverExtensions = serverHelloExtensions; - if (this.serverExtensions != null) + if (serverHelloExtensions != null) { - Enumeration e = this.serverExtensions.keys(); + Enumeration e = serverHelloExtensions.keys(); while (e.hasMoreElements()) { Integer extType = (Integer)e.nextElement(); @@ -1225,7 +1236,8 @@ protected void processServerHello(ServerHello serverHello) */ if (null == TlsUtils.getExtensionData(this.clientExtensions, extType)) { - throw new TlsFatalAlert(AlertDescription.unsupported_extension); + throw new TlsFatalAlert(AlertDescription.unsupported_extension, + "Unrequested extension in ServerHello: " + ExtensionType.getText(extType.intValue())); } /* @@ -1243,7 +1255,7 @@ protected void processServerHello(ServerHello serverHello) } } - byte[] renegExtData = TlsUtils.getExtensionData(this.serverExtensions, EXT_RenegotiationInfo); + byte[] renegExtData = TlsUtils.getExtensionData(serverHelloExtensions, EXT_RenegotiationInfo); if (securityParameters.isRenegotiating()) { @@ -1320,37 +1332,41 @@ protected void processServerHello(ServerHello serverHello) // TODO[compat-gnutls] GnuTLS test server fails to send renegotiation_info extension when resuming tlsClient.notifySecureRenegotiation(securityParameters.isSecureRenegotiation()); - /* - * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended - * master secret [..]. (and see 5.2, 5.3) - * - * RFC 8446 Appendix D. Because TLS 1.3 always hashes in the transcript up to the server - * Finished, implementations which support both TLS 1.3 and earlier versions SHOULD indicate - * the use of the Extended Master Secret extension in their APIs whenever TLS 1.3 is used. - */ + // extended_master_secret { - final boolean acceptedExtendedMasterSecret = TlsExtensionsUtils.hasExtendedMasterSecretExtension( - serverExtensions); - final boolean resumedSession = securityParameters.isResumedSession(); + boolean negotiatedEMS = false; - if (acceptedExtendedMasterSecret) + if (TlsExtensionsUtils.hasExtendedMasterSecretExtension(clientExtensions)) { - if (server_version.isSSL() - || (!resumedSession && !tlsClient.shouldUseExtendedMasterSecret())) + negotiatedEMS = TlsExtensionsUtils.hasExtendedMasterSecretExtension(serverHelloExtensions); + + if (TlsUtils.isExtendedMasterSecretOptional(server_version)) { - throw new TlsFatalAlert(AlertDescription.handshake_failure); + if (!negotiatedEMS && + tlsClient.requiresExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure, + "Extended Master Secret extension is required"); + } } - } - else - { - if (tlsClient.requiresExtendedMasterSecret() - || (resumedSession && !tlsClient.allowLegacyResumption())) + else { - throw new TlsFatalAlert(AlertDescription.handshake_failure); + if (negotiatedEMS) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, + "Server sent an unexpected extended_master_secret extension negotiating " + server_version); + } } } - securityParameters.extendedMasterSecret = acceptedExtendedMasterSecret; + securityParameters.extendedMasterSecret = negotiatedEMS; + } + + if (securityParameters.isResumedSession() && + securityParameters.isExtendedMasterSecret() != sessionParameters.isExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure, + "Server resumed session with mismatched extended_master_secret negotiation"); } /* @@ -1358,19 +1374,12 @@ protected void processServerHello(ServerHello serverHello) * contents of this extension are irrelevant, and only the values in the new handshake * messages are considered. */ - securityParameters.applicationProtocol = TlsExtensionsUtils.getALPNExtensionServer(serverExtensions); + securityParameters.applicationProtocol = TlsExtensionsUtils.getALPNExtensionServer(serverHelloExtensions); securityParameters.applicationProtocolSet = true; - Hashtable sessionClientExtensions = clientExtensions, sessionServerExtensions = serverExtensions; + Hashtable sessionClientExtensions = clientExtensions, sessionServerExtensions = serverHelloExtensions; if (securityParameters.isResumedSession()) { - if (securityParameters.getCipherSuite() != this.sessionParameters.getCipherSuite() - || CompressionMethod._null != this.sessionParameters.getCompressionAlgorithm() - || !server_version.equals(this.sessionParameters.getNegotiatedVersion())) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - sessionClientExtensions = null; sessionServerExtensions = this.sessionParameters.readServerExtensions(); } @@ -1392,15 +1401,11 @@ protected void processServerHello(ServerHello serverHello) securityParameters.encryptThenMAC = serverSentEncryptThenMAC; } - securityParameters.maxFragmentLength = processMaxFragmentLengthExtension(sessionClientExtensions, + securityParameters.maxFragmentLength = TlsUtils.processMaxFragmentLengthExtension(sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); securityParameters.truncatedHMac = TlsExtensionsUtils.hasTruncatedHMacExtension(sessionServerExtensions); - /* - * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in - * a session resumption handshake. - */ if (!securityParameters.isResumedSession()) { // TODO[tls13] See RFC 8446 4.4.2.1 @@ -1415,6 +1420,11 @@ else if (TlsUtils.hasExpectedEmptyExtensionData(sessionServerExtensions, TlsExte securityParameters.statusRequestVersion = 1; } + securityParameters.clientCertificateType = TlsUtils.processClientCertificateTypeExtension( + sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + securityParameters.serverCertificateType = TlsUtils.processServerCertificateTypeExtension( + sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + this.expectSessionTicket = TlsUtils.hasExpectedEmptyExtensionData(sessionServerExtensions, TlsProtocol.EXT_SessionTicket, AlertDescription.illegal_parameter); } @@ -1469,9 +1479,6 @@ protected void receive13CertificateRequest(ByteArrayInputStream buf, boolean pos this.certificateRequest = certificateRequest; - tlsClientContext.getSecurityParametersHandshake().clientCertificateType = - TlsExtensionsUtils.getClientCertificateTypeExtensionServer(serverExtensions, CertificateType.X509); - TlsUtils.establishServerSigAlgs(tlsClientContext.getSecurityParametersHandshake(), certificateRequest); } @@ -1514,30 +1521,31 @@ protected void receive13EncryptedExtensions(ByteArrayInputStream buf) Hashtable sessionClientExtensions = clientExtensions, sessionServerExtensions = serverExtensions; if (securityParameters.isResumedSession()) { - if (securityParameters.getCipherSuite() != sessionParameters.getCipherSuite() - || CompressionMethod._null != sessionParameters.getCompressionAlgorithm() - || !negotiatedVersion.equals(sessionParameters.getNegotiatedVersion())) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - sessionClientExtensions = null; sessionServerExtensions = sessionParameters.readServerExtensions(); } - securityParameters.maxFragmentLength = processMaxFragmentLengthExtension(sessionClientExtensions, + securityParameters.maxFragmentLength = TlsUtils.processMaxFragmentLengthExtension(sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); securityParameters.encryptThenMAC = false; securityParameters.truncatedHMac = false; - /* - * TODO[tls13] RFC 8446 4.4.2.1. OCSP Status and SCT Extensions. - * - * OCSP information is carried in an extension for a CertificateEntry. - */ - securityParameters.statusRequestVersion = clientExtensions.containsKey(TlsExtensionsUtils.EXT_status_request) - ? 1 : 0; + if (!securityParameters.isResumedSession()) + { + /* + * TODO[tls13] RFC 8446 4.4.2.1. OCSP Status and SCT Extensions. + * + * OCSP information is carried in an extension for a CertificateEntry. + */ + securityParameters.statusRequestVersion = clientExtensions.containsKey(TlsExtensionsUtils.EXT_status_request) + ? 1 : 0; + + securityParameters.clientCertificateType = TlsUtils.processClientCertificateTypeExtension13( + sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + securityParameters.serverCertificateType = TlsUtils.processServerCertificateTypeExtension13( + sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + } this.expectSessionTicket = false; @@ -1627,9 +1635,6 @@ protected void receiveCertificateRequest(ByteArrayInputStream buf) throws IOExce assertEmpty(buf); this.certificateRequest = TlsUtils.validateCertificateRequest(certificateRequest, keyExchange); - - tlsClientContext.getSecurityParametersHandshake().clientCertificateType = - TlsExtensionsUtils.getClientCertificateTypeExtensionServer(serverExtensions, CertificateType.X509); } protected void receiveNewSessionTicket(ByteArrayInputStream buf) @@ -1782,29 +1787,64 @@ protected void sendClientHello() securityParameters.clientRandom = createRandomBlock(useGMTUnixTime, tlsClientContext); } - establishSession(offeringTLSv12Minus ? tlsClient.getSessionToResume() : null); - tlsClient.notifySessionToResume(tlsSession); - - /* - * TODO RFC 5077 3.4. When presenting a ticket, the client MAY generate and include a - * Session ID in the TLS ClientHello. - */ - byte[] legacy_session_id = TlsUtils.getSessionID(tlsSession); + TlsSession sessionToResume = offeringTLSv12Minus ? tlsClient.getSessionToResume() : null; boolean fallback = tlsClient.isFallback(); int[] offeredCipherSuites = tlsClient.getCipherSuites(); - if (legacy_session_id.length > 0 && this.sessionParameters != null) + this.clientExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(tlsClient.getClientExtensions()); + + final boolean shouldUseEMS = tlsClient.shouldUseExtendedMasterSecret(); + + establishSession(sessionToResume); + + byte[] legacy_session_id = TlsUtils.getSessionID(tlsSession); + + if (legacy_session_id.length > 0) { - if (!Arrays.contains(offeredCipherSuites, sessionParameters.getCipherSuite()) - || CompressionMethod._null != sessionParameters.getCompressionAlgorithm()) + if (!Arrays.contains(offeredCipherSuites, sessionParameters.getCipherSuite())) { legacy_session_id = TlsUtils.EMPTY_BYTES; } } - this.clientExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(tlsClient.getClientExtensions()); + ProtocolVersion sessionVersion = null; + if (legacy_session_id.length > 0) + { + sessionVersion = sessionParameters.getNegotiatedVersion(); + + if (!ProtocolVersion.contains(supportedVersions, sessionVersion)) + { + legacy_session_id = TlsUtils.EMPTY_BYTES; + } + } + + if (legacy_session_id.length > 0 && TlsUtils.isExtendedMasterSecretOptional(sessionVersion)) + { + if (shouldUseEMS) + { + if (!sessionParameters.isExtendedMasterSecret() && + !tlsClient.allowLegacyResumption()) + { + legacy_session_id = TlsUtils.EMPTY_BYTES; + } + } + else + { + if (sessionParameters.isExtendedMasterSecret()) + { + legacy_session_id = TlsUtils.EMPTY_BYTES; + } + } + } + + if (legacy_session_id.length < 1) + { + cancelSession(); + } + + tlsClient.notifySessionToResume(tlsSession); ProtocolVersion legacy_version = latestVersion; if (offeringTLSv13Plus) @@ -1814,10 +1854,10 @@ protected void sendClientHello() TlsExtensionsUtils.addSupportedVersionsExtensionClient(clientExtensions, supportedVersions); /* - * RFC 8446 4.2.1. In compatibility mode [..], this field MUST be non-empty, so a client + * RFC 8446 4.1.2. In compatibility mode [..], this field MUST be non-empty, so a client * not offering a pre-TLS 1.3 session MUST generate a new 32-byte value. */ - if (legacy_session_id.length < 1) + if (legacy_session_id.length < 1 && tlsClient.shouldUseCompatibilityMode()) { legacy_session_id = tlsClientContext.getNonceGenerator().generateNonce(32); } @@ -1840,15 +1880,13 @@ protected void sendClientHello() // TODO[tls13-psk] Perhaps don't add key_share if external PSK(s) offered and 'psk_dhe_ke' not offered this.clientAgreements = TlsUtils.addKeyShareToClientHello(tlsClientContext, tlsClient, clientExtensions); - if (TlsUtils.isExtendedMasterSecretOptionalTLS(supportedVersions) - && (tlsClient.shouldUseExtendedMasterSecret() || - (null != sessionParameters && sessionParameters.isExtendedMasterSecret()))) + if (shouldUseEMS && TlsUtils.isExtendedMasterSecretOptional(supportedVersions)) { TlsExtensionsUtils.addExtendedMasterSecretExtension(this.clientExtensions); } - else if (!offeringTLSv13Plus && tlsClient.requiresExtendedMasterSecret()) + else { - throw new TlsFatalAlert(AlertDescription.internal_error); + this.clientExtensions.remove(TlsExtensionsUtils.EXT_extended_master_secret); } if (securityParameters.isRenegotiating()) diff --git a/tls/src/main/java/org/bouncycastle/tls/TlsECCUtils.java b/tls/src/main/java/org/bouncycastle/tls/TlsECCUtils.java index 0a03ed9dba..95ed67a83c 100644 --- a/tls/src/main/java/org/bouncycastle/tls/TlsECCUtils.java +++ b/tls/src/main/java/org/bouncycastle/tls/TlsECCUtils.java @@ -40,6 +40,7 @@ public static boolean isECCCipherSuite(int cipherSuite) case KeyExchangeAlgorithm.ECDHE_ECDSA: case KeyExchangeAlgorithm.ECDHE_PSK: case KeyExchangeAlgorithm.ECDHE_RSA: + case KeyExchangeAlgorithm.GOSTR341112_256: return true; default: diff --git a/tls/src/main/java/org/bouncycastle/tls/TlsExtensionsUtils.java b/tls/src/main/java/org/bouncycastle/tls/TlsExtensionsUtils.java index 16320722f4..a44904459e 100644 --- a/tls/src/main/java/org/bouncycastle/tls/TlsExtensionsUtils.java +++ b/tls/src/main/java/org/bouncycastle/tls/TlsExtensionsUtils.java @@ -21,6 +21,7 @@ public class TlsExtensionsUtils public static final Integer EXT_client_certificate_type = Integers.valueOf(ExtensionType.client_certificate_type); public static final Integer EXT_client_certificate_url = Integers.valueOf(ExtensionType.client_certificate_url); public static final Integer EXT_compress_certificate = Integers.valueOf(ExtensionType.compress_certificate); + public static final Integer EXT_connection_id = Integers.valueOf(ExtensionType.connection_id); public static final Integer EXT_cookie = Integers.valueOf(ExtensionType.cookie); public static final Integer EXT_early_data = Integers.valueOf(ExtensionType.early_data); public static final Integer EXT_ec_point_formats = Integers.valueOf(ExtensionType.ec_point_formats); @@ -91,6 +92,11 @@ public static void addCompressCertificateExtension(Hashtable extensions, int[] a extensions.put(EXT_compress_certificate, createCompressCertificateExtension(algorithms)); } + public static void addConnectionIDExtension(Hashtable extensions, byte[] connectionID) throws IOException + { + extensions.put(EXT_connection_id, createConnectionIDExtension(connectionID)); + } + public static void addCookieExtension(Hashtable extensions, byte[] cookie) throws IOException { extensions.put(EXT_cookie, createCookieExtension(cookie)); @@ -304,6 +310,16 @@ public static short[] getClientCertificateTypeExtensionClient(Hashtable extensio return extensionData == null ? null : readCertificateTypeExtensionClient(extensionData); } + public static short getClientCertificateTypeExtensionServer(Hashtable extensions) + throws IOException + { + byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_client_certificate_type); + return extensionData == null ? -1 : readCertificateTypeExtensionServer(extensionData); + } + + /** + * @deprecated Use version without defaultValue instead + */ public static short getClientCertificateTypeExtensionServer(Hashtable extensions, short defaultValue) throws IOException { @@ -318,6 +334,12 @@ public static int[] getCompressCertificateExtension(Hashtable extensions) return extensionData == null ? null : readCompressCertificateExtension(extensionData); } + public static byte[] getConnectionIDExtension(Hashtable extensions) throws IOException + { + byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_connection_id); + return extensionData == null ? null : readConnectionIDExtension(extensionData); + } + public static byte[] getCookieExtension(Hashtable extensions) throws IOException { @@ -415,6 +437,16 @@ public static short[] getServerCertificateTypeExtensionClient(Hashtable extensio return extensionData == null ? null : readCertificateTypeExtensionClient(extensionData); } + public static short getServerCertificateTypeExtensionServer(Hashtable extensions) + throws IOException + { + byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_server_certificate_type); + return extensionData == null ? -1 : readCertificateTypeExtensionServer(extensionData); + } + + /** + * @deprecated Use version without defaultValue instead + */ public static short getServerCertificateTypeExtensionServer(Hashtable extensions, short defaultValue) throws IOException { @@ -622,6 +654,14 @@ public static byte[] createCompressCertificateExtension(int[] algorithms) throws return TlsUtils.encodeUint16ArrayWithUint8Length(algorithms); } + public static byte[] createConnectionIDExtension(byte[] connectionID) throws IOException + { + if (connectionID == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsUtils.encodeOpaque8(connectionID); + } + public static byte[] createCookieExtension(byte[] cookie) throws IOException { if (TlsUtils.isNullOrEmpty(cookie) || cookie.length >= (1 << 16)) @@ -1077,6 +1117,11 @@ public static int[] readCompressCertificateExtension(byte[] extensionData) throw return algorithms; } + public static byte[] readConnectionIDExtension(byte[] extensionData) throws IOException + { + return TlsUtils.decodeOpaque8(extensionData); + } + public static byte[] readCookieExtension(byte[] extensionData) throws IOException { return TlsUtils.decodeOpaque16(extensionData, 1); diff --git a/tls/src/main/java/org/bouncycastle/tls/TlsPeer.java b/tls/src/main/java/org/bouncycastle/tls/TlsPeer.java index 3f68bf9f7c..777d61857d 100644 --- a/tls/src/main/java/org/bouncycastle/tls/TlsPeer.java +++ b/tls/src/main/java/org/bouncycastle/tls/TlsPeer.java @@ -39,6 +39,18 @@ public interface TlsPeer */ int getHandshakeTimeoutMillis(); + /** + *

      + * NOTE: Currently only respected by DTLS protocols. + *

      + *

      + * Specify the time, in milliseconds, after which a handshake packet is resent. + *

      + * + * @return the handshake resend time, in milliseconds. + */ + int getHandshakeResendTimeMillis(); + boolean allowLegacyResumption(); int getMaxCertificateChainLength(); @@ -139,6 +151,11 @@ public interface TlsPeer */ void notifyAlertReceived(short alertLevel, short alertDescription); + /** + * Notifies the peer that the connection has been closed. + */ + void notifyConnectionClosed(); + /** * Notifies the peer that the handshake has been successfully completed. */ diff --git a/tls/src/main/java/org/bouncycastle/tls/TlsProtocol.java b/tls/src/main/java/org/bouncycastle/tls/TlsProtocol.java index bf005097db..ce2630bb8c 100644 --- a/tls/src/main/java/org/bouncycastle/tls/TlsProtocol.java +++ b/tls/src/main/java/org/bouncycastle/tls/TlsProtocol.java @@ -12,6 +12,7 @@ import java.util.Hashtable; import java.util.Vector; +import org.bouncycastle.tls.crypto.TlsCrypto; import org.bouncycastle.tls.crypto.TlsSecret; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; @@ -299,6 +300,8 @@ protected void handleClose(boolean user_canceled) raiseAlertWarning(AlertDescription.close_notify, "Connection closed"); closeConnection(); + + getPeer().notifyConnectionClosed(); } } @@ -336,6 +339,8 @@ protected void handleFailure() throws IOException } closeConnection(); + + getPeer().notifyConnectionClosed(); } protected abstract void handleHandshakeMessage(short type, HandshakeMessageInput buf) @@ -515,7 +520,6 @@ protected void completeHandshake() this.sessionParameters = new SessionParameters.Builder() .setCipherSuite(securityParameters.getCipherSuite()) - .setCompressionAlgorithm(securityParameters.getCompressionAlgorithm()) .setExtendedMasterSecret(securityParameters.isExtendedMasterSecret()) .setLocalCertificate(securityParameters.getLocalCertificate()) .setMasterSecret(context.getCrypto().adoptSecret(this.sessionMasterSecret)) @@ -1572,22 +1576,22 @@ protected boolean establishSession(TlsSession sessionToResume) return false; } - if (!sessionParameters.isExtendedMasterSecret()) + ProtocolVersion sessionVersion = sessionParameters.getNegotiatedVersion(); + if (null == sessionVersion || !sessionVersion.isTLS()) + { + return false; + } + + if (!TlsUtils.isExtendedMasterSecretOptional(sessionVersion)) { - TlsPeer peer = getPeer(); - if (!peer.allowLegacyResumption() || peer.requiresExtendedMasterSecret()) + if (sessionParameters.isExtendedMasterSecret() == sessionVersion.isSSL()) { return false; } - - /* - * NOTE: For session resumption without extended_master_secret, renegotiation MUST be disabled - * (see RFC 7627 5.4). - */ } - TlsSecret sessionMasterSecret = TlsUtils.getSessionMasterSecret(getContext().getCrypto(), - sessionParameters.getMasterSecret()); + TlsCrypto crypto = getContext().getCrypto(); + TlsSecret sessionMasterSecret = TlsUtils.getSessionMasterSecret(crypto, sessionParameters.getMasterSecret()); if (null == sessionMasterSecret) { return false; @@ -1600,7 +1604,7 @@ protected boolean establishSession(TlsSession sessionToResume) return true; } - protected void invalidateSession() + protected void cancelSession() { if (this.sessionMasterSecret != null) { @@ -1614,11 +1618,17 @@ protected void invalidateSession() this.sessionParameters = null; } + this.tlsSession = null; + } + + protected void invalidateSession() + { if (this.tlsSession != null) { this.tlsSession.invalidate(); - this.tlsSession = null; } + + cancelSession(); } protected void processFinishedMessage(ByteArrayInputStream buf) @@ -1928,21 +1938,14 @@ public boolean isHandshaking() return null != context && context.isHandshaking(); } + /** + * @deprecated Will be removed. + */ protected short processMaxFragmentLengthExtension(Hashtable clientExtensions, Hashtable serverExtensions, short alertDescription) throws IOException { - short maxFragmentLength = TlsExtensionsUtils.getMaxFragmentLengthExtension(serverExtensions); - if (maxFragmentLength >= 0) - { - if (!MaxFragmentLength.isValid(maxFragmentLength) || - (clientExtensions != null && - maxFragmentLength != TlsExtensionsUtils.getMaxFragmentLengthExtension(clientExtensions))) - { - throw new TlsFatalAlert(alertDescription); - } - } - return maxFragmentLength; + return TlsUtils.processMaxFragmentLengthExtension(clientExtensions, serverExtensions, alertDescription); } protected void refuseRenegotiation() throws IOException diff --git a/tls/src/main/java/org/bouncycastle/tls/TlsServerProtocol.java b/tls/src/main/java/org/bouncycastle/tls/TlsServerProtocol.java index 65ea7715f4..3ace602565 100644 --- a/tls/src/main/java/org/bouncycastle/tls/TlsServerProtocol.java +++ b/tls/src/main/java/org/bouncycastle/tls/TlsServerProtocol.java @@ -12,6 +12,7 @@ import org.bouncycastle.tls.crypto.TlsCrypto; import org.bouncycastle.tls.crypto.TlsDHConfig; import org.bouncycastle.tls.crypto.TlsECConfig; +import org.bouncycastle.tls.crypto.TlsKemConfig; import org.bouncycastle.tls.crypto.TlsSecret; import org.bouncycastle.util.Arrays; @@ -356,9 +357,17 @@ protected ServerHello generate13ServerHello(ClientHello clientHello, HandshakeMe if (!serverEncryptedExtensions.isEmpty()) { - securityParameters.maxFragmentLength = processMaxFragmentLengthExtension( + securityParameters.maxFragmentLength = TlsUtils.processMaxFragmentLengthExtension( securityParameters.isResumedSession() ? null : clientHelloExtensions, serverEncryptedExtensions, AlertDescription.internal_error); + + if (!securityParameters.isResumedSession()) + { + securityParameters.clientCertificateType = TlsUtils.processClientCertificateTypeExtension13( + clientHelloExtensions, serverEncryptedExtensions, AlertDescription.internal_error); + securityParameters.serverCertificateType = TlsUtils.processServerCertificateTypeExtension13( + clientHelloExtensions, serverEncryptedExtensions, AlertDescription.internal_error); + } } securityParameters.encryptThenMAC = false; @@ -389,7 +398,7 @@ protected ServerHello generate13ServerHello(ClientHello clientHello, HandshakeMe int namedGroup = clientShare.getNamedGroup(); TlsAgreement agreement; - if (NamedGroup.refersToASpecificCurve(namedGroup)) + if (NamedGroup.refersToAnECDHCurve(namedGroup)) { agreement = crypto.createECDomain(new TlsECConfig(namedGroup)).createECDH(); } @@ -397,16 +406,21 @@ else if (NamedGroup.refersToASpecificFiniteField(namedGroup)) { agreement = crypto.createDHDomain(new TlsDHConfig(namedGroup, true)).createDH(); } + else if (NamedGroup.refersToASpecificKem(namedGroup)) + { + agreement = crypto.createKemDomain(new TlsKemConfig(namedGroup, true)).createKem(); + } else { throw new TlsFatalAlert(AlertDescription.internal_error); } + agreement.receivePeerValue(clientShare.getKeyExchange()); + byte[] key_exchange = agreement.generateEphemeral(); KeyShareEntry serverShare = new KeyShareEntry(namedGroup, key_exchange); TlsExtensionsUtils.addKeyShareServerHello(serverHelloExtensions, serverShare); - agreement.receivePeerValue(clientShare.getKeyExchange()); sharedSecret = agreement.calculateSecret(); } @@ -625,8 +639,6 @@ protected ServerHello generateServerHello(ClientHello clientHello, HandshakeMess tlsServer.notifySecureRenegotiation(securityParameters.isSecureRenegotiation()); - boolean offeredExtendedMasterSecret = TlsExtensionsUtils.hasExtendedMasterSecretExtension(clientExtensions); - if (clientExtensions != null) { // NOTE: Validates the padding extension data, if present @@ -648,11 +660,63 @@ protected ServerHello generateServerHello(ClientHello clientHello, HandshakeMess tlsServer.processClientExtensions(clientExtensions); } - boolean resumedSession = establishSession(tlsServer.getSessionToResume(clientHello.getSessionID())); - securityParameters.resumedSession = resumedSession; + TlsSession sessionToResume = tlsServer.getSessionToResume(clientHello.getSessionID()); + + boolean resumedSession = establishSession(sessionToResume); + + if (resumedSession && !serverVersion.equals(sessionParameters.getNegotiatedVersion())) + { + resumedSession = false; + } + + // TODO Check the session cipher suite is selectable by the same rules that getSelectedCipherSuite uses + + // TODO Check the resumed session has a peer certificate if we NEED client-auth + + // extended_master_secret + { + boolean negotiateEMS = false; + + if (TlsUtils.isExtendedMasterSecretOptional(serverVersion) && + tlsServer.shouldUseExtendedMasterSecret()) + { + if (TlsExtensionsUtils.hasExtendedMasterSecretExtension(clientExtensions)) + { + negotiateEMS = true; + } + else if (tlsServer.requiresExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure, + "Extended Master Secret extension is required"); + } + else if (resumedSession) + { + if (sessionParameters.isExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure, + "Extended Master Secret extension is required for EMS session resumption"); + } + + if (!tlsServer.allowLegacyResumption()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure, + "Extended Master Secret extension is required for legacy session resumption"); + } + } + } + + if (resumedSession && negotiateEMS != sessionParameters.isExtendedMasterSecret()) + { + resumedSession = false; + } + + securityParameters.extendedMasterSecret = negotiateEMS; + } if (!resumedSession) { + cancelSession(); + byte[] newSessionID = tlsServer.getNewSessionID(); if (null == newSessionID) { @@ -660,10 +724,9 @@ protected ServerHello generateServerHello(ClientHello clientHello, HandshakeMess } this.tlsSession = TlsUtils.importSession(newSessionID, null); - this.sessionParameters = null; - this.sessionMasterSecret = null; } + securityParameters.resumedSession = resumedSession; securityParameters.sessionID = tlsSession.getSessionID(); tlsServer.notifySession(tlsSession); @@ -739,43 +802,13 @@ protected ServerHello generateServerHello(ClientHello clientHello, HandshakeMess } } - /* - * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended - * master secret [..]. (and see 5.2, 5.3) - */ - if (resumedSession) + if (securityParameters.isExtendedMasterSecret()) { - if (!sessionParameters.isExtendedMasterSecret()) - { - /* - * TODO[resumption] ProvTlsServer currently only resumes EMS sessions. Revisit this - * in relation to 'tlsServer.allowLegacyResumption()'. - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - if (!offeredExtendedMasterSecret) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - - securityParameters.extendedMasterSecret = true; - TlsExtensionsUtils.addExtendedMasterSecretExtension(serverExtensions); } else { - securityParameters.extendedMasterSecret = offeredExtendedMasterSecret && !serverVersion.isSSL() - && tlsServer.shouldUseExtendedMasterSecret(); - - if (securityParameters.isExtendedMasterSecret()) - { - TlsExtensionsUtils.addExtendedMasterSecretExtension(serverExtensions); - } - else if (tlsServer.requiresExtendedMasterSecret()) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } + serverExtensions.remove(TlsExtensionsUtils.EXT_extended_master_secret); } securityParameters.applicationProtocol = TlsExtensionsUtils.getALPNExtensionServer(serverExtensions); @@ -785,7 +818,7 @@ else if (tlsServer.requiresExtendedMasterSecret()) { securityParameters.encryptThenMAC = TlsExtensionsUtils.hasEncryptThenMACExtension(serverExtensions); - securityParameters.maxFragmentLength = processMaxFragmentLengthExtension( + securityParameters.maxFragmentLength = TlsUtils.processMaxFragmentLengthExtension( resumedSession ? null : clientExtensions, serverExtensions, AlertDescription.internal_error); securityParameters.truncatedHMac = TlsExtensionsUtils.hasTruncatedHMacExtension(serverExtensions); @@ -803,6 +836,11 @@ else if (TlsUtils.hasExpectedEmptyExtensionData(serverExtensions, TlsExtensionsU securityParameters.statusRequestVersion = 1; } + securityParameters.clientCertificateType = TlsUtils.processClientCertificateTypeExtension( + clientExtensions, serverExtensions, AlertDescription.internal_error); + securityParameters.serverCertificateType = TlsUtils.processServerCertificateTypeExtension( + clientExtensions, serverExtensions, AlertDescription.internal_error); + this.expectSessionTicket = TlsUtils.hasExpectedEmptyExtensionData(serverExtensions, TlsProtocol.EXT_SessionTicket, AlertDescription.internal_error); } @@ -810,7 +848,7 @@ else if (TlsUtils.hasExpectedEmptyExtensionData(serverExtensions, TlsExtensionsU applyMaxFragmentLengthExtension(securityParameters.getMaxFragmentLength()); - return new ServerHello(serverVersion, securityParameters.getServerRandom(), tlsSession.getSessionID(), + return new ServerHello(serverVersion, securityParameters.getServerRandom(), securityParameters.getSessionID(), securityParameters.getCipherSuite(), serverExtensions); } @@ -984,7 +1022,7 @@ protected void handleHandshakeMessage(short type, HandshakeMessageInput buf) throw new TlsFatalAlert(AlertDescription.internal_error); } - if (securityParameters.isResumedSession()) + if (securityParameters.isResumedSession() && type != HandshakeType.client_hello) { if (type != HandshakeType.finished || this.connection_state != CS_SERVER_FINISHED) { @@ -1418,7 +1456,7 @@ protected void receive13ClientCertificate(ByteArrayInputStream buf) } Certificate.ParseOptions options = new Certificate.ParseOptions() - .setCertificateType(TlsExtensionsUtils.getClientCertificateTypeExtensionServer(serverExtensions, CertificateType.X509)) + .setCertificateType(tlsServerContext.getSecurityParametersHandshake().getClientCertificateType()) .setMaxChainLength(tlsServer.getMaxCertificateChainLength()); Certificate clientCertificate = Certificate.parse(options, tlsServerContext, buf, null); @@ -1458,7 +1496,7 @@ protected void receiveCertificateMessage(ByteArrayInputStream buf) } Certificate.ParseOptions options = new Certificate.ParseOptions() - .setCertificateType(TlsExtensionsUtils.getClientCertificateTypeExtensionServer(serverExtensions, CertificateType.X509)) + .setCertificateType(tlsServerContext.getSecurityParametersHandshake().getClientCertificateType()) .setMaxChainLength(tlsServer.getMaxCertificateChainLength()); Certificate clientCertificate = Certificate.parse(options, tlsServerContext, buf, null); diff --git a/tls/src/main/java/org/bouncycastle/tls/TlsUtils.java b/tls/src/main/java/org/bouncycastle/tls/TlsUtils.java index 50e22a9c5f..69b8930203 100644 --- a/tls/src/main/java/org/bouncycastle/tls/TlsUtils.java +++ b/tls/src/main/java/org/bouncycastle/tls/TlsUtils.java @@ -40,6 +40,7 @@ import org.bouncycastle.tls.crypto.TlsEncryptor; import org.bouncycastle.tls.crypto.TlsHash; import org.bouncycastle.tls.crypto.TlsHashOutputStream; +import org.bouncycastle.tls.crypto.TlsKemConfig; import org.bouncycastle.tls.crypto.TlsSecret; import org.bouncycastle.tls.crypto.TlsStreamSigner; import org.bouncycastle.tls.crypto.TlsStreamVerifier; @@ -649,6 +650,10 @@ public static short[] decodeUint8ArrayWithUint8Length(byte[] buf) throws IOExcep { throw new IllegalArgumentException("'buf' cannot be null"); } + if (buf.length < 1) + { + throw new TlsFatalAlert(AlertDescription.decode_error); + } int count = readUint8(buf, 0); if (buf.length != (count + 1)) @@ -1288,17 +1293,28 @@ public static TlsSession importSession(byte[] sessionID, SessionParameters sessi return new TlsSessionImpl(sessionID, sessionParameters); } - static boolean isExtendedMasterSecretOptionalDTLS(ProtocolVersion[] activeProtocolVersions) + static boolean isExtendedMasterSecretOptional(ProtocolVersion protocolVersion) { - return ProtocolVersion.contains(activeProtocolVersions, ProtocolVersion.DTLSv12) - || ProtocolVersion.contains(activeProtocolVersions, ProtocolVersion.DTLSv10); + ProtocolVersion tlsVersion = protocolVersion.getEquivalentTLSVersion(); + + return ProtocolVersion.TLSv12.equals(tlsVersion) + || ProtocolVersion.TLSv11.equals(tlsVersion) + || ProtocolVersion.TLSv10.equals(tlsVersion); } - static boolean isExtendedMasterSecretOptionalTLS(ProtocolVersion[] activeProtocolVersions) + static boolean isExtendedMasterSecretOptional(ProtocolVersion[] protocolVersions) { - return ProtocolVersion.contains(activeProtocolVersions, ProtocolVersion.TLSv12) - || ProtocolVersion.contains(activeProtocolVersions, ProtocolVersion.TLSv11) - || ProtocolVersion.contains(activeProtocolVersions, ProtocolVersion.TLSv10); + if (protocolVersions != null) + { + for (int i = 0; i < protocolVersions.length; ++i) + { + if (isExtendedMasterSecretOptional(protocolVersions[i])) + { + return true; + } + } + } + return false; } public static boolean isNullOrContainsNull(Object[] array) @@ -1944,30 +1960,6 @@ private static TlsSecret update13TrafficSecret(SecurityParameters securityParame EMPTY_BYTES, securityParameters.getPRFHashLength()); } - /** - * @deprecated Will be removed. {@link TlsCryptoUtils#getHashForPRF(int)} should be a useful alternative. - */ - public static short getHashAlgorithmForPRFAlgorithm(int prfAlgorithm) - { - switch (prfAlgorithm) - { - case PRFAlgorithm.ssl_prf_legacy: - case PRFAlgorithm.tls_prf_legacy: - throw new IllegalArgumentException("legacy PRF not a valid algorithm"); - case PRFAlgorithm.tls_prf_sha256: - case PRFAlgorithm.tls13_hkdf_sha256: - return HashAlgorithm.sha256; - case PRFAlgorithm.tls_prf_sha384: - case PRFAlgorithm.tls13_hkdf_sha384: - return HashAlgorithm.sha384; - // TODO[RFC 8998] -// case PRFAlgorithm.tls13_hkdf_sm3: -// return HashAlgorithm.sm3; - default: - throw new IllegalArgumentException("unknown PRFAlgorithm: " + PRFAlgorithm.getText(prfAlgorithm)); - } - } - public static ASN1ObjectIdentifier getOIDForHashAlgorithm(short hashAlgorithm) { switch (hashAlgorithm) @@ -2227,6 +2219,17 @@ static int getPRFAlgorithm(SecurityParameters securityParameters, int cipherSuit throw new TlsFatalAlert(AlertDescription.illegal_parameter); } + case CipherSuite.TLS_GOSTR341112_256_WITH_28147_CNT_IMIT: + case CipherSuite.TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC: + case CipherSuite.TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC: + { + if (isTLSv12Exactly) + { + return PRFAlgorithm.tls_prf_gostr3411_2012_256; + } + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: @@ -2715,6 +2718,9 @@ public static int getEncryptionAlgorithm(int cipherSuite) { switch (cipherSuite) { + case CipherSuite.TLS_GOSTR341112_256_WITH_28147_CNT_IMIT: + return EncryptionAlgorithm._28147_CNT_IMIT; + case CipherSuite.TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: @@ -3015,6 +3021,12 @@ public static int getEncryptionAlgorithm(int cipherSuite) case CipherSuite.TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: return EncryptionAlgorithm.CHACHA20_POLY1305; + case CipherSuite.TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC: + return EncryptionAlgorithm.KUZNYECHIK_CTR_OMAC; + + case CipherSuite.TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC: + return EncryptionAlgorithm.MAGMA_CTR_OMAC; + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: @@ -3093,6 +3105,9 @@ public static int getEncryptionAlgorithmType(int encryptionAlgorithm) case EncryptionAlgorithm.SM4_CBC: return CipherType.block; + case EncryptionAlgorithm._28147_CNT_IMIT: + case EncryptionAlgorithm.KUZNYECHIK_CTR_OMAC: + case EncryptionAlgorithm.MAGMA_CTR_OMAC: case EncryptionAlgorithm.NULL: case EncryptionAlgorithm.RC4_40: case EncryptionAlgorithm.RC4_128: @@ -3340,6 +3355,11 @@ public static int getKeyExchangeAlgorithm(int cipherSuite) case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: return KeyExchangeAlgorithm.ECDHE_RSA; + case CipherSuite.TLS_GOSTR341112_256_WITH_28147_CNT_IMIT: + case CipherSuite.TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC: + case CipherSuite.TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC: + return KeyExchangeAlgorithm.GOSTR341112_256; + case CipherSuite.TLS_AES_128_CCM_8_SHA256: case CipherSuite.TLS_AES_128_CCM_SHA256: case CipherSuite.TLS_AES_128_GCM_SHA256: @@ -3913,6 +3933,9 @@ public static ProtocolVersion getMinimumVersion(int cipherSuite) case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_GOSTR341112_256_WITH_28147_CNT_IMIT: + case CipherSuite.TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC: + case CipherSuite.TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC: case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: case CipherSuite.TLS_PSK_WITH_AES_128_CCM: @@ -4007,6 +4030,7 @@ public static Vector getNamedGroupRoles(Vector keyExchangeAlgorithms) // TODO[tls13] We're conservatively adding both here, though maybe only one is needed addToSet(result, NamedGroupRole.dh); addToSet(result, NamedGroupRole.ecdh); + addToSet(result, NamedGroupRole.kem); break; } } @@ -4097,8 +4121,6 @@ static boolean isValidKeyShareSelection(ProtocolVersion negotiatedVersion, int[] static boolean isValidSignatureAlgorithmForServerKeyExchange(short signatureAlgorithm, int keyExchangeAlgorithm) { - // TODO[tls13] - switch (keyExchangeAlgorithm) { case KeyExchangeAlgorithm.DHE_RSA: @@ -4136,6 +4158,7 @@ static boolean isValidSignatureAlgorithmForServerKeyExchange(short signatureAlgo case KeyExchangeAlgorithm.NULL: return SignatureAlgorithm.anonymous != signatureAlgorithm; + case KeyExchangeAlgorithm.GOSTR341112_256: default: return false; } @@ -4418,6 +4441,9 @@ public static boolean isSupportedKeyExchange(TlsCrypto crypto, int keyExchangeAl return crypto.hasSRPAuthentication() && hasAnyRSASigAlgs(crypto); + // TODO[RFC 9189] + case KeyExchangeAlgorithm.GOSTR341112_256: + default: return false; } @@ -4928,7 +4954,7 @@ static CertificateRequest normalizeCertificateRequest(CertificateRequest certifi certificateRequest.getCertificateAuthorities()); } - static boolean contains(short[] buf, int off, int len, int value) + static boolean contains(short[] buf, int off, int len, short value) { for (int i = 0; i < len; ++i) { @@ -4964,6 +4990,18 @@ static boolean containsAll(short[] container, short[] elements) return true; } + static boolean containsNot(short[] buf, int off, int len, short value) + { + for (int i = 0; i < len; ++i) + { + if (value != buf[off + i]) + { + return true; + } + } + return false; + } + static short[] retainAll(short[] retainer, short[] elements) { short[] retained = new short[Math.min(retainer.length, elements.length)]; @@ -5147,7 +5185,7 @@ static TlsAuthentication receiveServerCertificate(TlsClientContext clientContext ByteArrayOutputStream endPointHash = new ByteArrayOutputStream(); Certificate.ParseOptions options = new Certificate.ParseOptions() - .setCertificateType(TlsExtensionsUtils.getServerCertificateTypeExtensionServer(serverExtensions, CertificateType.X509)) + .setCertificateType(securityParameters.getServerCertificateType()) .setMaxChainLength(client.getMaxCertificateChainLength()); Certificate serverCertificate = Certificate.parse(options, clientContext, buf, endPointHash); @@ -5188,7 +5226,7 @@ static TlsAuthentication receive13ServerCertificate(TlsClientContext clientConte } Certificate.ParseOptions options = new Certificate.ParseOptions() - .setCertificateType(TlsExtensionsUtils.getServerCertificateTypeExtensionServer(serverExtensions, CertificateType.X509)) + .setCertificateType(securityParameters.getServerCertificateType()) .setMaxChainLength(client.getMaxCertificateChainLength()); Certificate serverCertificate = Certificate.parse(options, clientContext, buf, null); @@ -5276,7 +5314,7 @@ static Hashtable addKeyShareToClientHello(TlsClientContext clientContext, TlsCli Hashtable clientAgreements = new Hashtable(3); Vector clientShares = new Vector(2); - collectKeyShares(clientContext.getCrypto(), supportedGroups, keyShareGroups, clientAgreements, clientShares); + collectKeyShares(clientContext, supportedGroups, keyShareGroups, clientAgreements, clientShares); // TODO[tls13-psk] When clientShares empty, consider not adding extension if pre_shared_key in use TlsExtensionsUtils.addKeyShareClientHello(clientExtensions, clientShares); @@ -5292,7 +5330,7 @@ static Hashtable addKeyShareToClientHelloRetry(TlsClientContext clientContext, H Hashtable clientAgreements = new Hashtable(1, 1.0f); Vector clientShares = new Vector(1); - collectKeyShares(clientContext.getCrypto(), supportedGroups, keyShareGroups, clientAgreements, clientShares); + collectKeyShares(clientContext, supportedGroups, keyShareGroups, clientAgreements, clientShares); TlsExtensionsUtils.addKeyShareClientHello(clientExtensions, clientShares); @@ -5305,9 +5343,10 @@ static Hashtable addKeyShareToClientHelloRetry(TlsClientContext clientContext, H return clientAgreements; } - private static void collectKeyShares(TlsCrypto crypto, int[] supportedGroups, Vector keyShareGroups, + private static void collectKeyShares(TlsClientContext clientContext, int[] supportedGroups, Vector keyShareGroups, Hashtable clientAgreements, Vector clientShares) throws IOException { + TlsCrypto crypto = clientContext.getCrypto(); if (isNullOrEmpty(supportedGroups)) { return; @@ -5330,7 +5369,7 @@ private static void collectKeyShares(TlsCrypto crypto, int[] supportedGroups, Ve } TlsAgreement agreement = null; - if (NamedGroup.refersToASpecificCurve(supportedGroup)) + if (NamedGroup.refersToAnECDHCurve(supportedGroup)) { if (crypto.hasECDHAgreement()) { @@ -5344,6 +5383,13 @@ else if (NamedGroup.refersToASpecificFiniteField(supportedGroup)) agreement = crypto.createDHDomain(new TlsDHConfig(supportedGroup, true)).createDH(); } } + else if (NamedGroup.refersToASpecificKem(supportedGroup)) + { + if (crypto.hasKemAgreement()) + { + agreement = crypto.createKemDomain(new TlsKemConfig(supportedGroup, false)).createKem(); + } + } if (null != agreement) { @@ -5396,8 +5442,9 @@ static KeyShareEntry selectKeyShare(TlsCrypto crypto, ProtocolVersion negotiated continue; } - if ((NamedGroup.refersToASpecificCurve(group) && !crypto.hasECDHAgreement()) || - (NamedGroup.refersToASpecificFiniteField(group) && !crypto.hasDHAgreement())) + if ((NamedGroup.refersToAnECDHCurve(group) && !crypto.hasECDHAgreement()) || + (NamedGroup.refersToASpecificFiniteField(group) && !crypto.hasDHAgreement()) || + (NamedGroup.refersToASpecificKem(group) && !crypto.hasKemAgreement())) { continue; } @@ -5432,8 +5479,9 @@ static int selectKeyShareGroup(TlsCrypto crypto, ProtocolVersion negotiatedVersi continue; } - if ((NamedGroup.refersToASpecificCurve(group) && !crypto.hasECDHAgreement()) || - (NamedGroup.refersToASpecificFiniteField(group) && !crypto.hasDHAgreement())) + if ((NamedGroup.refersToAnECDHCurve(group) && !crypto.hasECDHAgreement()) || + (NamedGroup.refersToASpecificFiniteField(group) && !crypto.hasDHAgreement()) || + (NamedGroup.refersToASpecificKem(group) && !crypto.hasKemAgreement())) { continue; } @@ -5583,7 +5631,6 @@ static void negotiatedCipherSuite(SecurityParameters securityParameters, int cip case PRFAlgorithm.tls_prf_legacy: { securityParameters.prfCryptoHashAlgorithm = -1; - securityParameters.prfHashAlgorithm = -1; securityParameters.prfHashLength = -1; break; } @@ -5592,7 +5639,6 @@ static void negotiatedCipherSuite(SecurityParameters securityParameters, int cip int prfCryptoHashAlgorithm = TlsCryptoUtils.getHashForPRF(prfAlgorithm); securityParameters.prfCryptoHashAlgorithm = prfCryptoHashAlgorithm; - securityParameters.prfHashAlgorithm = getHashAlgorithmForPRFAlgorithm(prfAlgorithm); securityParameters.prfHashLength = TlsCryptoUtils.getHashOutputSize(prfCryptoHashAlgorithm); break; } @@ -5607,9 +5653,32 @@ static void negotiatedCipherSuite(SecurityParameters securityParameters, int cip { securityParameters.verifyDataLength = securityParameters.getPRFHashLength(); } + else if (negotiatedVersion.isSSL()) + { + securityParameters.verifyDataLength = 36; + } else { - securityParameters.verifyDataLength = negotiatedVersion.isSSL() ? 36 : 12; + /* + * RFC 9189 4.2.6. The verify_data_length value is equal to 32 for the CTR_OMAC cipher + * suites and is equal to 12 for the CNT_IMIT cipher suite. + */ + switch (cipherSuite) + { + case CipherSuite.TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC: + case CipherSuite.TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC: + { + securityParameters.verifyDataLength = 32; + break; + } + + case CipherSuite.TLS_GOSTR341112_256_WITH_28147_CNT_IMIT: + default: + { + securityParameters.verifyDataLength = 12; + break; + } + } } } @@ -6102,4 +6171,100 @@ static Vector getPSKIndices(TlsPSK[] psks, int prfAlgorithm) } return v; } + + static short processMaxFragmentLengthExtension(Hashtable clientExtensions, Hashtable serverExtensions, + short alertDescription) + throws IOException + { + short maxFragmentLength = TlsExtensionsUtils.getMaxFragmentLengthExtension(serverExtensions); + if (maxFragmentLength >= 0) + { + if (!MaxFragmentLength.isValid(maxFragmentLength) || + (clientExtensions != null && + maxFragmentLength != TlsExtensionsUtils.getMaxFragmentLengthExtension(clientExtensions))) + { + throw new TlsFatalAlert(alertDescription); + } + } + return maxFragmentLength; + } + + static short processClientCertificateTypeExtension(Hashtable clientExtensions, Hashtable serverExtensions, + short alertDescription) + throws IOException + { + short serverValue = TlsExtensionsUtils.getClientCertificateTypeExtensionServer(serverExtensions); + if (serverValue < 0) + { + return CertificateType.X509; + } + + if (!CertificateType.isValid(serverValue)) + { + throw new TlsFatalAlert(alertDescription, "Unknown value for client_certificate_type"); + } + + short[] clientValues = TlsExtensionsUtils.getClientCertificateTypeExtensionClient(clientExtensions); + if (clientValues == null || !contains(clientValues, 0, clientValues.length, serverValue)) + { + throw new TlsFatalAlert(alertDescription, "Invalid selection for client_certificate_type"); + } + + return serverValue; + } + + static short processClientCertificateTypeExtension13(Hashtable clientExtensions, Hashtable serverExtensions, + short alertDescription) + throws IOException + { + short certificateType = processClientCertificateTypeExtension(clientExtensions, serverExtensions, + alertDescription); + + return validateCertificateType13(certificateType, alertDescription); + } + + static short processServerCertificateTypeExtension(Hashtable clientExtensions, Hashtable serverExtensions, + short alertDescription) + throws IOException + { + short serverValue = TlsExtensionsUtils.getServerCertificateTypeExtensionServer(serverExtensions); + if (serverValue < 0) + { + return CertificateType.X509; + } + + if (!CertificateType.isValid(serverValue)) + { + throw new TlsFatalAlert(alertDescription, "Unknown value for server_certificate_type"); + } + + short[] clientValues = TlsExtensionsUtils.getServerCertificateTypeExtensionClient(clientExtensions); + if (clientValues == null || !contains(clientValues, 0, clientValues.length, serverValue)) + { + throw new TlsFatalAlert(alertDescription, "Invalid selection for server_certificate_type"); + } + + return serverValue; + } + + static short processServerCertificateTypeExtension13(Hashtable clientExtensions, Hashtable serverExtensions, + short alertDescription) + throws IOException + { + short certificateType = processServerCertificateTypeExtension(clientExtensions, serverExtensions, + alertDescription); + + return validateCertificateType13(certificateType, alertDescription); + } + + private static short validateCertificateType13(short certificateType, short alertDescription) + throws IOException + { + if (CertificateType.OpenPGP == certificateType) + { + throw new TlsFatalAlert(alertDescription, "The OpenPGP certificate type MUST NOT be used with TLS 1.3"); + } + + return certificateType; + } } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/CryptoHashAlgorithm.java b/tls/src/main/java/org/bouncycastle/tls/crypto/CryptoHashAlgorithm.java index b0ce733b4a..1beb7e1de8 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/CryptoHashAlgorithm.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/CryptoHashAlgorithm.java @@ -9,4 +9,5 @@ public abstract class CryptoHashAlgorithm public static final int sha384 = 5; public static final int sha512 = 6; public static final int sm3 = 7; + public static final int gostr3411_2012_256 = 8; } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCipher.java b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCipher.java index b3426a6a63..9bbebd639f 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCipher.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCipher.java @@ -1,4 +1,4 @@ -package org.bouncycastle.tls.crypto; + package org.bouncycastle.tls.crypto; import java.io.IOException; @@ -15,28 +15,35 @@ public interface TlsCipher * * @param plaintextLimit * the maximum output size for the plaintext. - * @return the maximum input size of the ciphertext for plaintextlimit bytes of output. + * @return the maximum input size of the ciphertext for plaintextLimit bytes of output. */ int getCiphertextDecodeLimit(int plaintextLimit); /** - * Return the maximum output size for a ciphertext given an actual input plaintext size of - * plaintextLength bytes and a maximum input plaintext size of plaintextLimit bytes. + * Return the maximum output size for a ciphertext given a maximum input size for the plaintext of + * plaintextLimit bytes. * - * @param plaintextLength - * the actual input size for the plaintext. * @param plaintextLimit * the maximum input size for the plaintext. - * @return the maximum output size of the ciphertext for plaintextlimit bytes of input. + * @return the maximum output size of the ciphertext for plaintextLimit bytes of input. */ - int getCiphertextEncodeLimit(int plaintextLength, int plaintextLimit); + int getCiphertextEncodeLimit(int plaintextLimit); /** - * Return the maximum size for the plaintext given ciphertextlimit bytes of ciphertext. - * @param ciphertextLimit the maximum number of bytes of ciphertext. - * @return the maximum size of the plaintext for ciphertextlimit bytes of input. + * Return the maximum output size for the plaintext given a maximum input size for the ciphertext of + * ciphertextLimit bytes. + * @param ciphertextLimit the maximum input size for the ciphertext. + * @return the maximum output size of the plaintext for ciphertextLimit bytes of input. */ - int getPlaintextLimit(int ciphertextLimit); + int getPlaintextDecodeLimit(int ciphertextLimit); + + /** + * Return the maximum input size for the plaintext given a maximum output size for the ciphertext of + * ciphertextLimit bytes. + * @param ciphertextLimit the maximum output size for the ciphertext. + * @return the maximum input size of the plaintext for ciphertextLimit bytes of output. + */ + int getPlaintextEncodeLimit(int ciphertextLimit); /** * Encode the passed in plaintext using the current bulk cipher. @@ -51,6 +58,7 @@ public interface TlsCipher * @return A {@link TlsEncodeResult} containing the result of encoding (after 'headerAllocation' unused bytes). * @throws IOException */ + // TODO[api] Add a parameter for how much (D)TLSInnerPlaintext padding to add TlsEncodeResult encodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, int headerAllocation, byte[] plaintext, int offset, int len) throws IOException; @@ -73,5 +81,7 @@ TlsDecodeResult decodeCiphertext(long seqNo, short recordType, ProtocolVersion r void rekeyEncoder() throws IOException; - boolean usesOpaqueRecordType(); + boolean usesOpaqueRecordTypeDecode(); + + boolean usesOpaqueRecordTypeEncode(); } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCrypto.java b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCrypto.java index 2534d6aaee..a154e64238 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCrypto.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCrypto.java @@ -69,6 +69,13 @@ public interface TlsCrypto */ boolean hasECDHAgreement(); + /** + * Return true if this TlsCrypto can support KEM key agreement. + * + * @return true if this instance can support KEM key agreement, false otherwise. + */ + boolean hasKemAgreement(); + /** * Return true if this TlsCrypto can support the passed in block/stream encryption algorithm. * @@ -213,6 +220,14 @@ TlsCipher createCipher(TlsCryptoParameters cryptoParams, int encryptionAlgorithm */ TlsECDomain createECDomain(TlsECConfig ecConfig); + /** + * Create a domain object supporting the domain parameters described in kemConfig. + * + * @param kemConfig the config describing the KEM parameters to use. + * @return a TlsKemDomain supporting the parameters in kemConfig. + */ + TlsKemDomain createKemDomain(TlsKemConfig kemConfig); + /** * Adopt the passed in secret, creating a new copy of it. * diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCryptoUtils.java b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCryptoUtils.java index 3b716fdcec..8b51aa6910 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCryptoUtils.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCryptoUtils.java @@ -5,6 +5,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.tls.AlertDescription; import org.bouncycastle.tls.HashAlgorithm; @@ -74,6 +75,8 @@ public static int getHashForPRF(int prfAlgorithm) return CryptoHashAlgorithm.sha384; case PRFAlgorithm.tls13_hkdf_sm3: return CryptoHashAlgorithm.sm3; + case PRFAlgorithm.tls_prf_gostr3411_2012_256: + return CryptoHashAlgorithm.gostr3411_2012_256; default: throw new IllegalArgumentException("unknown PRFAlgorithm: " + PRFAlgorithm.getText(prfAlgorithm)); } @@ -88,6 +91,7 @@ public static int getHashInternalSize(int cryptoHashAlgorithm) case CryptoHashAlgorithm.sha224: case CryptoHashAlgorithm.sha256: case CryptoHashAlgorithm.sm3: + case CryptoHashAlgorithm.gostr3411_2012_256: return 64; case CryptoHashAlgorithm.sha384: case CryptoHashAlgorithm.sha512: @@ -109,6 +113,7 @@ public static int getHashOutputSize(int cryptoHashAlgorithm) return 28; case CryptoHashAlgorithm.sha256: case CryptoHashAlgorithm.sm3: + case CryptoHashAlgorithm.gostr3411_2012_256: return 32; case CryptoHashAlgorithm.sha384: return 48; @@ -138,6 +143,8 @@ public static ASN1ObjectIdentifier getOIDForHash(int cryptoHashAlgorithm) // TODO[RFC 8998] // case CryptoHashAlgorithm.sm3: // return GMObjectIdentifiers.sm3; + case CryptoHashAlgorithm.gostr3411_2012_256: + return RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256; default: throw new IllegalArgumentException(); } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/TlsKemConfig.java b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsKemConfig.java new file mode 100644 index 0000000000..d064bc8d68 --- /dev/null +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsKemConfig.java @@ -0,0 +1,23 @@ +package org.bouncycastle.tls.crypto; + +public class TlsKemConfig +{ + protected final int namedGroup; + protected final boolean isServer; + + public TlsKemConfig(int namedGroup, boolean isServer) + { + this.namedGroup = namedGroup; + this.isServer = isServer; + } + + public int getNamedGroup() + { + return namedGroup; + } + + public boolean isServer() + { + return isServer; + } +} diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/TlsKemDomain.java b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsKemDomain.java new file mode 100644 index 0000000000..6d73de8163 --- /dev/null +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsKemDomain.java @@ -0,0 +1,6 @@ +package org.bouncycastle.tls.crypto; + +public interface TlsKemDomain +{ + TlsAgreement createKem(); +} diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/TlsNullNullCipher.java b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsNullNullCipher.java index f3261f5348..cb5a9275c1 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/TlsNullNullCipher.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsNullNullCipher.java @@ -19,12 +19,17 @@ public int getCiphertextDecodeLimit(int plaintextLimit) return plaintextLimit; } - public int getCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) + public int getCiphertextEncodeLimit(int plaintextLimit) { - return plaintextLength; + return plaintextLimit; + } + + public int getPlaintextDecodeLimit(int ciphertextLimit) + { + return ciphertextLimit; } - public int getPlaintextLimit(int ciphertextLimit) + public int getPlaintextEncodeLimit(int ciphertextLimit) { return ciphertextLimit; } @@ -53,7 +58,12 @@ public void rekeyEncoder() throws IOException throw new TlsFatalAlert(AlertDescription.internal_error); } - public boolean usesOpaqueRecordType() + public boolean usesOpaqueRecordTypeDecode() + { + return false; + } + + public boolean usesOpaqueRecordTypeEncode() { return false; } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsAEADCipher.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsAEADCipher.java index 7f6467edef..d7910ccd5c 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsAEADCipher.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsAEADCipher.java @@ -14,11 +14,12 @@ import org.bouncycastle.tls.crypto.TlsDecodeResult; import org.bouncycastle.tls.crypto.TlsEncodeResult; import org.bouncycastle.tls.crypto.TlsSecret; +import org.bouncycastle.util.Arrays; /** * A generic TLS 1.2 AEAD cipher. */ -public class TlsAEADCipher +public final class TlsAEADCipher implements TlsCipher { public static final int AEAD_CCM = 1; @@ -27,18 +28,21 @@ public class TlsAEADCipher private static final int NONCE_RFC5288 = 1; private static final int NONCE_RFC7905 = 2; + private static final long SEQUENCE_NUMBER_PLACEHOLDER = -1L; - protected final TlsCryptoParameters cryptoParams; - protected final int keySize; - protected final int macSize; - protected final int fixed_iv_length; - protected final int record_iv_length; + private final TlsCryptoParameters cryptoParams; + private final int keySize; + private final int macSize; + private final int fixed_iv_length; + private final int record_iv_length; - protected final TlsAEADCipherImpl decryptCipher, encryptCipher; - protected final byte[] decryptNonce, encryptNonce; + private final TlsAEADCipherImpl decryptCipher, encryptCipher; + private final byte[] decryptNonce, encryptNonce; + private final byte[] decryptConnectionID, encryptConnectionID; + private final boolean decryptUseInnerPlaintext, encryptUseInnerPlaintext; - protected final boolean isTLSv13; - protected final int nonceMode; + private final boolean isTLSv13; + private final int nonceMode; public TlsAEADCipher(TlsCryptoParameters cryptoParams, TlsAEADCipherImpl encryptCipher, TlsAEADCipherImpl decryptCipher, int keySize, int macSize, int aeadType) throws IOException @@ -54,6 +58,12 @@ public TlsAEADCipher(TlsCryptoParameters cryptoParams, TlsAEADCipherImpl encrypt this.isTLSv13 = TlsImplUtils.isTLSv13(negotiatedVersion); this.nonceMode = getNonceMode(isTLSv13, aeadType); + decryptConnectionID = securityParameters.getConnectionIDPeer(); + encryptConnectionID = securityParameters.getConnectionIDLocal(); + + decryptUseInnerPlaintext = isTLSv13 || !Arrays.isNullOrEmpty(decryptConnectionID); + encryptUseInnerPlaintext = isTLSv13 || !Arrays.isNullOrEmpty(encryptConnectionID); + switch (nonceMode) { case NONCE_RFC5288: @@ -111,40 +121,34 @@ public TlsAEADCipher(TlsCryptoParameters cryptoParams, TlsAEADCipherImpl encrypt { throw new TlsFatalAlert(AlertDescription.internal_error); } - - int nonceLength = fixed_iv_length + record_iv_length; - - // NOTE: Ensure dummy nonce is not part of the generated sequence(s) - byte[] dummyNonce = new byte[nonceLength]; - dummyNonce[0] = (byte)~encryptNonce[0]; - dummyNonce[1] = (byte)~decryptNonce[1]; - - encryptCipher.init(dummyNonce, macSize, null); - decryptCipher.init(dummyNonce, macSize, null); } public int getCiphertextDecodeLimit(int plaintextLimit) { - return plaintextLimit + macSize + record_iv_length + (isTLSv13 ? 1 : 0); + int innerPlaintextLimit = plaintextLimit + (decryptUseInnerPlaintext ? 1 : 0); + + return innerPlaintextLimit + macSize + record_iv_length; } - public int getCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) + public int getCiphertextEncodeLimit(int plaintextLimit) { - int innerPlaintextLimit = plaintextLength; - if (isTLSv13) - { - // TODO[tls13] Add support for padding - int maxPadding = 0; - - innerPlaintextLimit = 1 + Math.min(plaintextLimit, plaintextLength + maxPadding); - } + int innerPlaintextLimit = plaintextLimit + (encryptUseInnerPlaintext ? 1 : 0); return innerPlaintextLimit + macSize + record_iv_length; } - public int getPlaintextLimit(int ciphertextLimit) + public int getPlaintextDecodeLimit(int ciphertextLimit) + { + int innerPlaintextLimit = ciphertextLimit - macSize - record_iv_length; + + return innerPlaintextLimit - (decryptUseInnerPlaintext ? 1 : 0); + } + + public int getPlaintextEncodeLimit(int ciphertextLimit) { - return ciphertextLimit - macSize - record_iv_length - (isTLSv13 ? 1 : 0); + int innerPlaintextLimit = ciphertextLimit - macSize - record_iv_length; + + return innerPlaintextLimit - (encryptUseInnerPlaintext ? 1 : 0); } public TlsEncodeResult encodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, @@ -170,10 +174,12 @@ public TlsEncodeResult encodePlaintext(long seqNo, short contentType, ProtocolVe throw new TlsFatalAlert(AlertDescription.internal_error); } - int extraLength = (isTLSv13 ? 1 : 0); + // TODO[tls13, cid] If we support adding padding to (D)TLSInnerPlaintext, this will need review + int innerPlaintextLength = plaintextLength + (encryptUseInnerPlaintext ? 1 : 0); - // TODO[tls13] If we support adding padding to TLSInnerPlaintext, this will need review - int encryptionLength = encryptCipher.getOutputSize(plaintextLength + extraLength); + encryptCipher.init(nonce, macSize); + + int encryptionLength = encryptCipher.getOutputSize(innerPlaintextLength); int ciphertextLength = record_iv_length + encryptionLength; byte[] output = new byte[headerAllocation + ciphertextLength]; @@ -185,20 +191,25 @@ public TlsEncodeResult encodePlaintext(long seqNo, short contentType, ProtocolVe outputPos += record_iv_length; } - short recordType = isTLSv13 ? ContentType.application_data : contentType; + short recordType = contentType; + if (encryptUseInnerPlaintext) + { + recordType = isTLSv13 ? ContentType.application_data : ContentType.tls12_cid; + } - byte[] additionalData = getAdditionalData(seqNo, recordType, recordVersion, ciphertextLength, plaintextLength); + byte[] additionalData = getAdditionalData(seqNo, recordType, recordVersion, ciphertextLength, + innerPlaintextLength, encryptConnectionID); try { System.arraycopy(plaintext, plaintextOffset, output, outputPos, plaintextLength); - if (isTLSv13) + if (encryptUseInnerPlaintext) { output[outputPos + plaintextLength] = (byte)contentType; } - encryptCipher.init(nonce, macSize, additionalData); - outputPos += encryptCipher.doFinal(output, outputPos, plaintextLength + extraLength, output, outputPos); + outputPos += encryptCipher.doFinal(additionalData, output, outputPos, innerPlaintextLength, output, + outputPos); } catch (RuntimeException e) { @@ -217,7 +228,7 @@ public TlsEncodeResult encodePlaintext(long seqNo, short contentType, ProtocolVe public TlsDecodeResult decodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, byte[] ciphertext, int ciphertextOffset, int ciphertextLength) throws IOException { - if (getPlaintextLimit(ciphertextLength) < 0) + if (getPlaintextDecodeLimit(ciphertextLength) < 0) { throw new TlsFatalAlert(AlertDescription.decode_error); } @@ -241,47 +252,49 @@ public TlsDecodeResult decodeCiphertext(long seqNo, short recordType, ProtocolVe throw new TlsFatalAlert(AlertDescription.internal_error); } + decryptCipher.init(nonce, macSize); + int encryptionOffset = ciphertextOffset + record_iv_length; int encryptionLength = ciphertextLength - record_iv_length; - int plaintextLength = decryptCipher.getOutputSize(encryptionLength); + int innerPlaintextLength = decryptCipher.getOutputSize(encryptionLength); - byte[] additionalData = getAdditionalData(seqNo, recordType, recordVersion, ciphertextLength, plaintextLength); + byte[] additionalData = getAdditionalData(seqNo, recordType, recordVersion, ciphertextLength, + innerPlaintextLength, decryptConnectionID); int outputPos; try { - decryptCipher.init(nonce, macSize, additionalData); - outputPos = decryptCipher.doFinal(ciphertext, encryptionOffset, encryptionLength, ciphertext, - encryptionOffset); + outputPos = decryptCipher.doFinal(additionalData, ciphertext, encryptionOffset, encryptionLength, + ciphertext, encryptionOffset); } catch (RuntimeException e) { throw new TlsFatalAlert(AlertDescription.bad_record_mac, e); } - if (outputPos != plaintextLength) + if (outputPos != innerPlaintextLength) { // NOTE: The additional data mechanism for AEAD ciphers requires exact output size prediction. throw new TlsFatalAlert(AlertDescription.internal_error); } short contentType = recordType; - if (isTLSv13) + int plaintextLength = innerPlaintextLength; + + if (decryptUseInnerPlaintext) { // Strip padding and read true content type from TLSInnerPlaintext - int pos = plaintextLength; for (;;) { - if (--pos < 0) + if (--plaintextLength < 0) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } - byte octet = ciphertext[encryptionOffset + pos]; + byte octet = ciphertext[encryptionOffset + plaintextLength]; if (0 != octet) { contentType = (short)(octet & 0xFF); - plaintextLength = pos; break; } } @@ -300,15 +313,38 @@ public void rekeyEncoder() throws IOException rekeyCipher(cryptoParams.getSecurityParametersConnection(), encryptCipher, encryptNonce, cryptoParams.isServer()); } - public boolean usesOpaqueRecordType() + public boolean usesOpaqueRecordTypeDecode() { - return isTLSv13; + return decryptUseInnerPlaintext; } - protected byte[] getAdditionalData(long seqNo, short recordType, ProtocolVersion recordVersion, - int ciphertextLength, int plaintextLength) throws IOException + public boolean usesOpaqueRecordTypeEncode() { - if (isTLSv13) + return encryptUseInnerPlaintext; + } + + private byte[] getAdditionalData(long seqNo, short recordType, ProtocolVersion recordVersion, + int ciphertextLength, int plaintextLength, byte[] connectionID) throws IOException + { + if (!Arrays.isNullOrEmpty(connectionID)) + { + /* + * seq_num_placeholder + tls12_cid + cid_length + tls12_cid + DTLSCiphertext.version + epoch + * + sequence_number + cid + length_of_DTLSInnerPlaintext + */ + int cidLength = connectionID.length; + byte[] additional_data = new byte[23 + cidLength]; + TlsUtils.writeUint64(SEQUENCE_NUMBER_PLACEHOLDER, additional_data, 0); + TlsUtils.writeUint8(ContentType.tls12_cid, additional_data, 8); + TlsUtils.writeUint8(cidLength, additional_data, 9); + TlsUtils.writeUint8(ContentType.tls12_cid, additional_data, 10); + TlsUtils.writeVersion(recordVersion, additional_data, 11); + TlsUtils.writeUint64(seqNo, additional_data, 13); + System.arraycopy(connectionID, 0, additional_data, 21, cidLength); + TlsUtils.writeUint16(plaintextLength, additional_data, 21 + cidLength); + return additional_data; + } + else if (isTLSv13) { /* * TLSCiphertext.opaque_type || TLSCiphertext.legacy_record_version || TLSCiphertext.length @@ -333,7 +369,7 @@ protected byte[] getAdditionalData(long seqNo, short recordType, ProtocolVersion } } - protected void rekeyCipher(SecurityParameters securityParameters, TlsAEADCipherImpl cipher, byte[] nonce, + private void rekeyCipher(SecurityParameters securityParameters, TlsAEADCipherImpl cipher, byte[] nonce, boolean serverSecret) throws IOException { if (!isTLSv13) @@ -354,7 +390,7 @@ protected void rekeyCipher(SecurityParameters securityParameters, TlsAEADCipherI setup13Cipher(cipher, nonce, secret, securityParameters.getPRFCryptoHashAlgorithm()); } - protected void setup13Cipher(TlsAEADCipherImpl cipher, byte[] nonce, TlsSecret secret, int cryptoHashAlgorithm) + private void setup13Cipher(TlsAEADCipherImpl cipher, byte[] nonce, TlsSecret secret, int cryptoHashAlgorithm) throws IOException { byte[] key = TlsCryptoUtils.hkdfExpandLabel(secret, cryptoHashAlgorithm, "key", TlsUtils.EMPTY_BYTES, keySize).extract(); @@ -362,10 +398,6 @@ protected void setup13Cipher(TlsAEADCipherImpl cipher, byte[] nonce, TlsSecret s cipher.setKey(key, 0, keySize); System.arraycopy(iv, 0, nonce, 0, fixed_iv_length); - - // NOTE: Ensure dummy nonce is not part of the generated sequence(s) - iv[0] ^= 0x80; - cipher.init(iv, macSize, null); } private static int getNonceMode(boolean isTLSv13, int aeadType) throws IOException diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsAEADCipherImpl.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsAEADCipherImpl.java index 9e3b751797..7bcaf09d8a 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsAEADCipherImpl.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsAEADCipherImpl.java @@ -21,10 +21,9 @@ public interface TlsAEADCipherImpl * * @param nonce the nonce. * @param macSize MAC size in bytes. - * @param additionalData any additional data to be included in the MAC calculation. * @throws IOException if the parameters are inappropriate. */ - void init(byte[] nonce, int macSize, byte[] additionalData) throws IOException; + void init(byte[] nonce, int macSize) throws IOException; /** * Return the maximum size of the output for input of inputLength bytes. @@ -39,6 +38,7 @@ public interface TlsAEADCipherImpl *

      * Note: we have to use doFinal() here as it is the only way to guarantee output from the underlying cipher. *

      + * @param additionalData any additional data to be included in the MAC calculation. * @param input array holding input data to the cipher. * @param inputOffset offset into input array data starts at. * @param inputLength length of the input data in the array. @@ -47,6 +47,6 @@ public interface TlsAEADCipherImpl * @return the amount of data written to output. * @throws IOException in case of failure. */ - int doFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) + int doFinal(byte[] additionalData, byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) throws IOException; } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsBlockCipher.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsBlockCipher.java index 441c71172b..2c4d46a29f 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsBlockCipher.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsBlockCipher.java @@ -3,6 +3,7 @@ import java.io.IOException; import org.bouncycastle.tls.AlertDescription; +import org.bouncycastle.tls.ContentType; import org.bouncycastle.tls.ProtocolVersion; import org.bouncycastle.tls.SecurityParameters; import org.bouncycastle.tls.TlsFatalAlert; @@ -12,23 +13,27 @@ import org.bouncycastle.tls.crypto.TlsDecodeResult; import org.bouncycastle.tls.crypto.TlsEncodeResult; import org.bouncycastle.tls.crypto.TlsHMAC; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Integers; import org.bouncycastle.util.Pack; /** * A generic TLS 1.0-1.2 block cipher. This can be used for AES or 3DES for example. */ -public class TlsBlockCipher +public final class TlsBlockCipher implements TlsCipher { - protected final TlsCryptoParameters cryptoParams; - protected final byte[] randomData; - protected final boolean encryptThenMAC; - protected final boolean useExplicitIV; - protected final boolean acceptExtraPadding; - protected final boolean useExtraPadding; - - protected final TlsBlockCipherImpl decryptCipher, encryptCipher; - protected final TlsSuiteMac readMac, writeMac; + private final TlsCryptoParameters cryptoParams; + private final byte[] randomData; + private final boolean encryptThenMAC; + private final boolean useExplicitIV; + private final boolean acceptExtraPadding; + private final boolean useExtraPadding; + + private final TlsBlockCipherImpl decryptCipher, encryptCipher; + private final TlsSuiteMac readMac, writeMac; + private final byte[] decryptConnectionID, encryptConnectionID; + private final boolean decryptUseInnerPlaintext, encryptUseInnerPlaintext; public TlsBlockCipher(TlsCryptoParameters cryptoParams, TlsBlockCipherImpl encryptCipher, TlsBlockCipherImpl decryptCipher, TlsHMAC clientMac, TlsHMAC serverMac, int cipherKeySize) throws IOException @@ -41,6 +46,12 @@ public TlsBlockCipher(TlsCryptoParameters cryptoParams, TlsBlockCipherImpl encry throw new TlsFatalAlert(AlertDescription.internal_error); } + this.decryptConnectionID = securityParameters.getConnectionIDPeer(); + this.encryptConnectionID = securityParameters.getConnectionIDLocal(); + + this.decryptUseInnerPlaintext = !Arrays.isNullOrEmpty(decryptConnectionID); + this.encryptUseInnerPlaintext = !Arrays.isNullOrEmpty(encryptConnectionID); + this.cryptoParams = cryptoParams; this.randomData = cryptoParams.getNonceGenerator().generateNonce(256); @@ -136,48 +147,39 @@ public int getCiphertextDecodeLimit(int plaintextLimit) int blockSize = decryptCipher.getBlockSize(); int macSize = readMac.getSize(); int maxPadding = 256; + int innerPlaintextLimit = plaintextLimit + (decryptUseInnerPlaintext ? 1 : 0); - return getCiphertextLength(blockSize, macSize, maxPadding, plaintextLimit); + return getCiphertextLength(blockSize, macSize, maxPadding, innerPlaintextLimit); } - public int getCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) + public int getCiphertextEncodeLimit(int plaintextLimit) { int blockSize = encryptCipher.getBlockSize(); int macSize = writeMac.getSize(); int maxPadding = useExtraPadding ? 256 : blockSize; + int innerPlaintextLimit = plaintextLimit + (encryptUseInnerPlaintext ? 1 : 0); - return getCiphertextLength(blockSize, macSize, maxPadding, plaintextLength); + return getCiphertextLength(blockSize, macSize, maxPadding, innerPlaintextLimit); } - public int getPlaintextLimit(int ciphertextLimit) + public int getPlaintextDecodeLimit(int ciphertextLimit) { - int blockSize = encryptCipher.getBlockSize(); - int macSize = writeMac.getSize(); + int blockSize = decryptCipher.getBlockSize(); + int macSize = readMac.getSize(); - int plaintextLimit = ciphertextLimit; + int innerPlaintextLimit = getPlaintextLength(blockSize, macSize, ciphertextLimit); - // Leave room for the MAC, and require block-alignment - if (encryptThenMAC) - { - plaintextLimit -= macSize; - plaintextLimit -= plaintextLimit % blockSize; - } - else - { - plaintextLimit -= plaintextLimit % blockSize; - plaintextLimit -= macSize; - } + return innerPlaintextLimit - (decryptUseInnerPlaintext ? 1 : 0); + } - // Minimum 1 byte of padding - --plaintextLimit; + public int getPlaintextEncodeLimit(int ciphertextLimit) + { + int blockSize = encryptCipher.getBlockSize(); + int macSize = writeMac.getSize(); - // An explicit IV consumes 1 block - if (useExplicitIV) - { - plaintextLimit -= blockSize; - } + int innerPlaintextLimit = getPlaintextLength(blockSize, macSize, ciphertextLimit); - return plaintextLimit; + return innerPlaintextLimit - (encryptUseInnerPlaintext ? 1 : 0); } public TlsEncodeResult encodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, @@ -186,7 +188,10 @@ public TlsEncodeResult encodePlaintext(long seqNo, short contentType, ProtocolVe int blockSize = encryptCipher.getBlockSize(); int macSize = writeMac.getSize(); - int enc_input_length = len; + // TODO[cid] If we support adding padding to DTLSInnerPlaintext, this will need review + int innerPlaintextLength = len + (encryptUseInnerPlaintext ? 1 : 0); + + int enc_input_length = innerPlaintextLength; if (!encryptThenMAC) { enc_input_length += macSize; @@ -201,7 +206,7 @@ public TlsEncodeResult encodePlaintext(long seqNo, short contentType, ProtocolVe padding_length += actualExtraPadBlocks * blockSize; } - int totalSize = len + macSize + padding_length; + int totalSize = innerPlaintextLength + macSize + padding_length; if (useExplicitIV) { totalSize += blockSize; @@ -218,12 +223,22 @@ public TlsEncodeResult encodePlaintext(long seqNo, short contentType, ProtocolVe outOff += blockSize; } + int innerPlaintextOffset = outOff; + System.arraycopy(plaintext, offset, outBuf, outOff, len); outOff += len; + short recordType = contentType; + if (encryptUseInnerPlaintext) + { + outBuf[outOff++] = (byte)contentType; + recordType = ContentType.tls12_cid; + } + if (!encryptThenMAC) { - byte[] mac = writeMac.calculateMac(seqNo, contentType, plaintext, offset, len); + byte[] mac = writeMac.calculateMac(seqNo, recordType, encryptConnectionID, outBuf, innerPlaintextOffset, + innerPlaintextLength); System.arraycopy(mac, 0, outBuf, outOff, mac.length); outOff += mac.length; } @@ -238,7 +253,8 @@ public TlsEncodeResult encodePlaintext(long seqNo, short contentType, ProtocolVe if (encryptThenMAC) { - byte[] mac = writeMac.calculateMac(seqNo, contentType, outBuf, headerAllocation, outOff - headerAllocation); + byte[] mac = writeMac.calculateMac(seqNo, recordType, encryptConnectionID, outBuf, headerAllocation, + outOff - headerAllocation); System.arraycopy(mac, 0, outBuf, outOff, mac.length); outOff += mac.length; } @@ -248,7 +264,7 @@ public TlsEncodeResult encodePlaintext(long seqNo, short contentType, ProtocolVe throw new TlsFatalAlert(AlertDescription.internal_error); } - return new TlsEncodeResult(outBuf, 0, outBuf.length, contentType); + return new TlsEncodeResult(outBuf, 0, outBuf.length, recordType); } public TlsDecodeResult decodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, @@ -290,11 +306,12 @@ public TlsDecodeResult decodeCiphertext(long seqNo, short recordType, ProtocolVe if (encryptThenMAC) { - byte[] expectedMac = readMac.calculateMac(seqNo, recordType, ciphertext, offset, len - macSize); + byte[] expectedMac = readMac.calculateMac(seqNo, recordType, decryptConnectionID, ciphertext, + offset, len - macSize); - boolean badMac = !TlsUtils.constantTimeAreEqual(macSize, expectedMac, 0, ciphertext, + boolean checkMac = TlsUtils.constantTimeAreEqual(macSize, expectedMac, 0, ciphertext, offset + len - macSize); - if (badMac) + if (!checkMac) { /* * RFC 7366 3. The MAC SHALL be evaluated before any further processing such as @@ -317,19 +334,21 @@ public TlsDecodeResult decodeCiphertext(long seqNo, short recordType, ProtocolVe } // If there's anything wrong with the padding, this will return zero - int totalPad = checkPaddingConstantTime(ciphertext, offset, blocks_length, blockSize, encryptThenMAC ? 0 : macSize); + int totalPad = checkPaddingConstantTime(ciphertext, offset, blocks_length, blockSize, + encryptThenMAC ? 0 : macSize); boolean badMac = (totalPad == 0); - int dec_output_length = blocks_length - totalPad; + int innerPlaintextLength = blocks_length - totalPad; if (!encryptThenMAC) { - dec_output_length -= macSize; + innerPlaintextLength -= macSize; - byte[] expectedMac = readMac.calculateMacConstantTime(seqNo, recordType, ciphertext, offset, - dec_output_length, blocks_length - macSize, randomData); + byte[] expectedMac = readMac.calculateMacConstantTime(seqNo, recordType, decryptConnectionID, + ciphertext, offset, innerPlaintextLength, blocks_length - macSize, randomData); - badMac |= !TlsUtils.constantTimeAreEqual(macSize, expectedMac, 0, ciphertext, offset + dec_output_length); + badMac |= !TlsUtils.constantTimeAreEqual(macSize, expectedMac, 0, ciphertext, + offset + innerPlaintextLength); } if (badMac) @@ -337,7 +356,29 @@ public TlsDecodeResult decodeCiphertext(long seqNo, short recordType, ProtocolVe throw new TlsFatalAlert(AlertDescription.bad_record_mac); } - return new TlsDecodeResult(ciphertext, offset, dec_output_length, recordType); + short contentType = recordType; + int plaintextLength = innerPlaintextLength; + + if (decryptUseInnerPlaintext) + { + // Strip padding and read true content type from DTLSInnerPlaintext + for (;;) + { + if (--plaintextLength < 0) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + byte octet = ciphertext[offset + plaintextLength]; + if (0 != octet) + { + contentType = (short)(octet & 0xFF); + break; + } + } + } + + return new TlsDecodeResult(ciphertext, offset, plaintextLength, contentType); } public void rekeyDecoder() throws IOException @@ -350,12 +391,17 @@ public void rekeyEncoder() throws IOException throw new TlsFatalAlert(AlertDescription.internal_error); } - public boolean usesOpaqueRecordType() + public boolean usesOpaqueRecordTypeDecode() + { + return decryptUseInnerPlaintext; + } + + public boolean usesOpaqueRecordTypeEncode() { - return false; + return encryptUseInnerPlaintext; } - protected int checkPaddingConstantTime(byte[] buf, int off, int len, int blockSize, int macSize) + private int checkPaddingConstantTime(byte[] buf, int off, int len, int blockSize, int macSize) { int end = off + len; byte lastByte = buf[end - 1]; @@ -402,15 +448,15 @@ protected int checkPaddingConstantTime(byte[] buf, int off, int len, int blockSi return totalPad; } - protected int chooseExtraPadBlocks(int max) + private int chooseExtraPadBlocks(int max) { byte[] random = cryptoParams.getNonceGenerator().generateNonce(4); int x = Pack.littleEndianToInt(random, 0); - int n = lowestBitSet(x); + int n = Integers.numberOfTrailingZeros(x); return Math.min(n, max); } - protected int getCiphertextLength(int blockSize, int macSize, int maxPadding, int plaintextLength) + private int getCiphertextLength(int blockSize, int macSize, int maxPadding, int plaintextLength) { int ciphertextLength = plaintextLength; @@ -438,19 +484,31 @@ protected int getCiphertextLength(int blockSize, int macSize, int maxPadding, in return ciphertextLength; } - protected int lowestBitSet(int x) + private int getPlaintextLength(int blockSize, int macSize, int ciphertextLength) { - if (x == 0) + int plaintextLength = ciphertextLength; + + // Leave room for the MAC, and require block-alignment + if (encryptThenMAC) + { + plaintextLength -= macSize; + plaintextLength -= plaintextLength % blockSize; + } + else { - return 32; + plaintextLength -= plaintextLength % blockSize; + plaintextLength -= macSize; } - int n = 0; - while ((x & 1) == 0) + // Minimum 1 byte of padding + --plaintextLength; + + // An explicit IV consumes 1 block + if (useExplicitIV) { - ++n; - x >>= 1; + plaintextLength -= blockSize; } - return n; + + return plaintextLength; } } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsNullCipher.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsNullCipher.java index 07f18e3deb..dad183f1cf 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsNullCipher.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsNullCipher.java @@ -3,7 +3,9 @@ import java.io.IOException; import org.bouncycastle.tls.AlertDescription; +import org.bouncycastle.tls.ContentType; import org.bouncycastle.tls.ProtocolVersion; +import org.bouncycastle.tls.SecurityParameters; import org.bouncycastle.tls.TlsFatalAlert; import org.bouncycastle.tls.TlsUtils; import org.bouncycastle.tls.crypto.TlsCipher; @@ -11,25 +13,34 @@ import org.bouncycastle.tls.crypto.TlsDecodeResult; import org.bouncycastle.tls.crypto.TlsEncodeResult; import org.bouncycastle.tls.crypto.TlsHMAC; +import org.bouncycastle.util.Arrays; /** * The NULL cipher. */ -public class TlsNullCipher +public final class TlsNullCipher implements TlsCipher { - protected final TlsCryptoParameters cryptoParams; - protected final TlsSuiteHMac readMac, writeMac; + private final TlsSuiteHMac readMac, writeMac; + private final byte[] decryptConnectionID, encryptConnectionID; + private final boolean decryptUseInnerPlaintext, encryptUseInnerPlaintext; public TlsNullCipher(TlsCryptoParameters cryptoParams, TlsHMAC clientMac, TlsHMAC serverMac) throws IOException { - if (TlsImplUtils.isTLSv13(cryptoParams)) + SecurityParameters securityParameters = cryptoParams.getSecurityParametersHandshake(); + ProtocolVersion negotiatedVersion = securityParameters.getNegotiatedVersion(); + + if (TlsImplUtils.isTLSv13(negotiatedVersion)) { throw new TlsFatalAlert(AlertDescription.internal_error); } - this.cryptoParams = cryptoParams; + this.decryptConnectionID = securityParameters.getConnectionIDPeer(); + this.encryptConnectionID = securityParameters.getConnectionIDLocal(); + + this.decryptUseInnerPlaintext = !Arrays.isNullOrEmpty(decryptConnectionID); + this.encryptUseInnerPlaintext = !Arrays.isNullOrEmpty(encryptConnectionID); int key_block_size = clientMac.getMacLength() + serverMac.getMacLength(); byte[] key_block = TlsImplUtils.calculateKeyBlock(cryptoParams, key_block_size); @@ -60,49 +71,100 @@ public TlsNullCipher(TlsCryptoParameters cryptoParams, TlsHMAC clientMac, TlsHMA public int getCiphertextDecodeLimit(int plaintextLimit) { - return plaintextLimit + writeMac.getSize(); + int innerPlaintextLimit = plaintextLimit + (decryptUseInnerPlaintext ? 1 : 0); + + return innerPlaintextLimit + readMac.getSize(); + } + + public int getCiphertextEncodeLimit(int plaintextLimit) + { + int innerPlaintextLimit = plaintextLimit + (encryptUseInnerPlaintext ? 1 : 0); + + return innerPlaintextLimit + writeMac.getSize(); } - public int getCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) + public int getPlaintextDecodeLimit(int ciphertextLimit) { - return plaintextLength + writeMac.getSize(); + int innerPlaintextLimit = ciphertextLimit - readMac.getSize(); + + return innerPlaintextLimit - (decryptUseInnerPlaintext ? 1 : 0); } - public int getPlaintextLimit(int ciphertextLimit) + public int getPlaintextEncodeLimit(int ciphertextLimit) { - return ciphertextLimit - writeMac.getSize(); + int innerPlaintextLimit = ciphertextLimit - writeMac.getSize(); + + return innerPlaintextLimit - (encryptUseInnerPlaintext ? 1 : 0); } public TlsEncodeResult encodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, int headerAllocation, byte[] plaintext, int offset, int len) throws IOException { - byte[] mac = writeMac.calculateMac(seqNo, contentType, plaintext, offset, len); - byte[] ciphertext = new byte[headerAllocation + len + mac.length]; + int macSize = writeMac.getSize(); + + // TODO[cid] If we support adding padding to DTLSInnerPlaintext, this will need review + int innerPlaintextLength = len + (encryptUseInnerPlaintext ? 1 : 0); + + byte[] ciphertext = new byte[headerAllocation + innerPlaintextLength + macSize]; System.arraycopy(plaintext, offset, ciphertext, headerAllocation, len); - System.arraycopy(mac, 0, ciphertext, headerAllocation + len, mac.length); - return new TlsEncodeResult(ciphertext, 0, ciphertext.length, contentType); + + short recordType = contentType; + if (encryptUseInnerPlaintext) + { + ciphertext[headerAllocation + len] = (byte)contentType; + recordType = ContentType.tls12_cid; + } + + byte[] mac = writeMac.calculateMac(seqNo, recordType, encryptConnectionID, ciphertext, headerAllocation, + innerPlaintextLength); + System.arraycopy(mac, 0, ciphertext, headerAllocation + innerPlaintextLength, mac.length); + + return new TlsEncodeResult(ciphertext, 0, ciphertext.length, recordType); } public TlsDecodeResult decodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, byte[] ciphertext, int offset, int len) throws IOException { int macSize = readMac.getSize(); - if (len < macSize) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - int macInputLen = len - macSize; + int innerPlaintextLength = len - macSize; + + if (innerPlaintextLength < (decryptUseInnerPlaintext ? 1 : 0)) + throw new TlsFatalAlert(AlertDescription.decode_error); - byte[] expectedMac = readMac.calculateMac(seqNo, recordType, ciphertext, offset, macInputLen); + byte[] expectedMac = readMac.calculateMac(seqNo, recordType, decryptConnectionID, ciphertext, offset, + innerPlaintextLength); - boolean badMac = !TlsUtils.constantTimeAreEqual(macSize, expectedMac, 0, ciphertext, offset + macInputLen); + boolean badMac = !TlsUtils.constantTimeAreEqual(macSize, expectedMac, 0, ciphertext, + offset + innerPlaintextLength); if (badMac) { throw new TlsFatalAlert(AlertDescription.bad_record_mac); } - return new TlsDecodeResult(ciphertext, offset, macInputLen, recordType); + short contentType = recordType; + int plaintextLength = innerPlaintextLength; + + if (decryptUseInnerPlaintext) + { + // Strip padding and read true content type from DTLSInnerPlaintext + for (;;) + { + if (--plaintextLength < 0) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + byte octet = ciphertext[offset + plaintextLength]; + if (0 != octet) + { + contentType = (short)(octet & 0xFF); + break; + } + } + } + + return new TlsDecodeResult(ciphertext, offset, plaintextLength, contentType); } public void rekeyDecoder() throws IOException @@ -115,8 +177,13 @@ public void rekeyEncoder() throws IOException throw new TlsFatalAlert(AlertDescription.internal_error); } - public boolean usesOpaqueRecordType() + public boolean usesOpaqueRecordTypeDecode() + { + return decryptUseInnerPlaintext; + } + + public boolean usesOpaqueRecordTypeEncode() { - return false; + return encryptUseInnerPlaintext; } } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsSuiteHMac.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsSuiteHMac.java index e07eabfe3d..d12d1365eb 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsSuiteHMac.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsSuiteHMac.java @@ -1,5 +1,6 @@ package org.bouncycastle.tls.crypto.impl; +import org.bouncycastle.tls.ContentType; import org.bouncycastle.tls.ProtocolVersion; import org.bouncycastle.tls.TlsUtils; import org.bouncycastle.tls.crypto.TlsCryptoParameters; @@ -10,10 +11,12 @@ /** * A generic TLS MAC implementation, acting as an HMAC based on some underlying Digest. */ -public class TlsSuiteHMac +public final class TlsSuiteHMac implements TlsSuiteMac { - protected static int getMacSize(TlsCryptoParameters cryptoParams, TlsMAC mac) + private static final long SEQUENCE_NUMBER_PLACEHOLDER = -1L; + + private static int getMacSize(TlsCryptoParameters cryptoParams, TlsMAC mac) { int macSize = mac.getMacLength(); if (cryptoParams.getSecurityParametersHandshake().isTruncatedHMac()) @@ -23,12 +26,12 @@ protected static int getMacSize(TlsCryptoParameters cryptoParams, TlsMAC mac) return macSize; } - protected final TlsCryptoParameters cryptoParams; - protected final TlsHMAC mac; - protected final int digestBlockSize; - protected final int digestOverhead; - protected final int macSize; - + private final TlsCryptoParameters cryptoParams; + private final TlsHMAC mac; + private final int digestBlockSize; + private final int digestOverhead; + private final int macSize; + /** * Generate a new instance of a TlsMac. * @@ -61,39 +64,54 @@ public int getSize() return macSize; } - public byte[] calculateMac(long seqNo, short type, byte[] msg, int msgOff, int msgLen) + public byte[] calculateMac(long seqNo, short type, byte[] connectionID, byte[] msg, int msgOff, int msgLen) { ProtocolVersion serverVersion = cryptoParams.getServerVersion(); - boolean isSSL = serverVersion.isSSL(); - byte[] macHeader = new byte[isSSL ? 11 : 13]; - TlsUtils.writeUint64(seqNo, macHeader, 0); - TlsUtils.writeUint8(type, macHeader, 8); - if (!isSSL) + if (!Arrays.isNullOrEmpty(connectionID)) + { + int cidLength = connectionID.length; + byte[] macHeader = new byte[23 + cidLength]; + TlsUtils.writeUint64(SEQUENCE_NUMBER_PLACEHOLDER, macHeader, 0); + TlsUtils.writeUint8(ContentType.tls12_cid, macHeader, 8); + TlsUtils.writeUint8(cidLength, macHeader, 9); + TlsUtils.writeUint8(ContentType.tls12_cid, macHeader, 10); + TlsUtils.writeVersion(serverVersion, macHeader, 11); + TlsUtils.writeUint64(seqNo, macHeader, 13); + System.arraycopy(connectionID, 0, macHeader, 21, cidLength); + TlsUtils.writeUint16(msgLen, macHeader, 21 + cidLength); + + mac.update(macHeader, 0, macHeader.length); + } + else { + byte[] macHeader = new byte[13]; + TlsUtils.writeUint64(seqNo, macHeader, 0); + TlsUtils.writeUint8(type, macHeader, 8); TlsUtils.writeVersion(serverVersion, macHeader, 9); + TlsUtils.writeUint16(msgLen, macHeader, 11); + + mac.update(macHeader, 0, macHeader.length); } - TlsUtils.writeUint16(msgLen, macHeader, macHeader.length - 2); - mac.update(macHeader, 0, macHeader.length); mac.update(msg, msgOff, msgLen); return truncate(mac.calculateMAC()); } - public byte[] calculateMacConstantTime(long seqNo, short type, byte[] msg, int msgOff, int msgLen, - int fullLength, byte[] dummyData) + public byte[] calculateMacConstantTime(long seqNo, short type, byte[] connectionID, byte[] msg, int msgOff, + int msgLen, int fullLength, byte[] dummyData) { /* * Actual MAC only calculated on 'length' bytes... */ - byte[] result = calculateMac(seqNo, type, msg, msgOff, msgLen); + byte[] result = calculateMac(seqNo, type, connectionID, msg, msgOff, msgLen); /* * ...but ensure a constant number of complete digest blocks are processed (as many as would * be needed for 'fullLength' bytes of input). */ - int headerLength = TlsImplUtils.isSSL(cryptoParams) ? 11 : 13; + int headerLength = getHeaderLength(connectionID); // How many extra full blocks do we need to calculate? int extra = getDigestBlockCount(headerLength + fullLength) - getDigestBlockCount(headerLength + msgLen); @@ -110,7 +128,7 @@ public byte[] calculateMacConstantTime(long seqNo, short type, byte[] msg, int m return result; } - protected int getDigestBlockCount(int inputLength) + private int getDigestBlockCount(int inputLength) { // NOTE: The input pad for HMAC is always a full digest block @@ -118,7 +136,23 @@ protected int getDigestBlockCount(int inputLength) return (inputLength + digestOverhead) / digestBlockSize; } - protected byte[] truncate(byte[] bs) + private int getHeaderLength(byte[] connectionID) + { + if (TlsImplUtils.isSSL(cryptoParams)) + { + return 11; + } + else if (!Arrays.isNullOrEmpty(connectionID)) + { + return 23 + connectionID.length; + } + else + { + return 13; + } + } + + private byte[] truncate(byte[] bs) { if (bs.length <= macSize) { diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsSuiteMac.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsSuiteMac.java index a3d48507f1..cc8a035379 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsSuiteMac.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/TlsSuiteMac.java @@ -22,7 +22,7 @@ public interface TlsSuiteMac * @param length The length of the message. * @return A new byte array containing the MAC value. */ - byte[] calculateMac(long seqNo, short type, byte[] message, int offset, int length); + byte[] calculateMac(long seqNo, short type, byte[] connectionID, byte[] message, int offset, int length); /** * Constant time calculation of the MAC for some given data with a given expected length. @@ -36,6 +36,6 @@ public interface TlsSuiteMac * @param randomData Random data for padding out the MAC calculation if required. * @return A new byte array containing the MAC value. */ - byte[] calculateMacConstantTime(long seqNo, short type, byte[] message, int offset, int length, int expectedLength, - byte[] randomData); + byte[] calculateMacConstantTime(long seqNo, short type, byte[] connectionID, byte[] message, int offset, + int length, int expectedLength, byte[] randomData); } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcChaCha20Poly1305.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcChaCha20Poly1305.java index 6a9822861e..8a40cf45f7 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcChaCha20Poly1305.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcChaCha20Poly1305.java @@ -22,16 +22,22 @@ public class BcChaCha20Poly1305 implements TlsAEADCipherImpl protected final boolean isEncrypting; - protected int additionalDataLength; - public BcChaCha20Poly1305(boolean isEncrypting) { this.isEncrypting = isEncrypting; } - public int doFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) + public int doFinal(byte[] additionalData, byte[] input, int inputOffset, int inputLength, byte[] output, + int outputOffset) throws IOException { + int additionalDataLength = 0; + if (!Arrays.isNullOrEmpty(additionalData)) + { + additionalDataLength = additionalData.length; + updateMAC(additionalData, 0, additionalData.length); + } + if (isEncrypting) { int ciphertextLength = inputLength; @@ -87,7 +93,7 @@ public int getOutputSize(int inputLength) return isEncrypting ? inputLength + 16 : inputLength - 16; } - public void init(byte[] nonce, int macSize, byte[] additionalData) throws IOException + public void init(byte[] nonce, int macSize) throws IOException { if (nonce == null || nonce.length != 12 || macSize != 16) { @@ -96,15 +102,6 @@ public void init(byte[] nonce, int macSize, byte[] additionalData) throws IOExce cipher.init(isEncrypting, new ParametersWithIV(null, nonce)); initMAC(); - if (additionalData == null) - { - this.additionalDataLength = 0; - } - else - { - this.additionalDataLength = additionalData.length; - updateMAC(additionalData, 0, additionalData.length); - } } public void setKey(byte[] key, int keyOff, int keyLen) throws IOException diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.java index 2175bdf18e..7e0c4492dd 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.java @@ -1,20 +1,14 @@ package org.bouncycastle.tls.crypto.impl.bc; import java.io.IOException; -import java.security.SecureRandom; -import org.bouncycastle.crypto.encodings.PKCS1Encoding; -import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.tls.Certificate; import org.bouncycastle.tls.ProtocolVersion; import org.bouncycastle.tls.TlsCredentialedDecryptor; import org.bouncycastle.tls.crypto.TlsCryptoParameters; import org.bouncycastle.tls.crypto.TlsSecret; -import org.bouncycastle.tls.crypto.impl.TlsImplUtils; -import org.bouncycastle.util.Arrays; /** * Credentialed class decrypting RSA encrypted secrets sent from a peer for our end of the TLS connection using the BC light-weight API. @@ -27,7 +21,7 @@ public class BcDefaultTlsCredentialedDecryptor protected AsymmetricKeyParameter privateKey; public BcDefaultTlsCredentialedDecryptor(BcTlsCrypto crypto, Certificate certificate, - AsymmetricKeyParameter privateKey) + AsymmetricKeyParameter privateKey) { if (crypto == null) { @@ -76,82 +70,18 @@ public TlsSecret decrypt(TlsCryptoParameters cryptoParams, byte[] ciphertext) th } /* - * TODO[tls-ops] Probably need to make RSA encryption/decryption into TlsCrypto functions so - * that users can implement "generic" encryption credentials externally + * TODO[tls-ops] Probably need to make RSA encryption/decryption into TlsCrypto functions so that users + * can implement "generic" encryption credentials externally */ - protected TlsSecret safeDecryptPreMasterSecret(TlsCryptoParameters cryptoParams, RSAKeyParameters rsaServerPrivateKey, - byte[] encryptedPreMasterSecret) + protected TlsSecret safeDecryptPreMasterSecret(TlsCryptoParameters cryptoParams, + RSAKeyParameters rsaServerPrivateKey, byte[] encryptedPreMasterSecret) { - SecureRandom secureRandom = crypto.getSecureRandom(); - - /* - * RFC 5246 7.4.7.1. - */ ProtocolVersion expectedVersion = cryptoParams.getRSAPreMasterSecretVersion(); - // TODO Provide as configuration option? - boolean versionNumberCheckDisabled = false; - - /* - * Generate 48 random bytes we can use as a Pre-Master-Secret, if the - * PKCS1 padding check should fail. - */ - byte[] fallback = new byte[48]; - secureRandom.nextBytes(fallback); - - byte[] M = Arrays.clone(fallback); - try - { - PKCS1Encoding encoding = new PKCS1Encoding(new RSABlindedEngine(), fallback); - encoding.init(false, new ParametersWithRandom(rsaServerPrivateKey, secureRandom)); - - M = encoding.processBlock(encryptedPreMasterSecret, 0, encryptedPreMasterSecret.length); - } - catch (Exception e) - { - /* - * This should never happen since the decryption should never throw an exception - * and return a random value instead. - * - * In any case, a TLS server MUST NOT generate an alert if processing an - * RSA-encrypted premaster secret message fails, or the version number is not as - * expected. Instead, it MUST continue the handshake with a randomly generated - * premaster secret. - */ - } - - /* - * If ClientHello.legacy_version is TLS 1.1 or higher, server implementations MUST check the - * version number [..]. - */ - if (versionNumberCheckDisabled && !TlsImplUtils.isTLSv11(expectedVersion)) - { - /* - * If the version number is TLS 1.0 or earlier, server implementations SHOULD check the - * version number, but MAY have a configuration option to disable the check. - */ - } - else - { - /* - * Compare the version number in the decrypted Pre-Master-Secret with the legacy_version - * field from the ClientHello. If they don't match, continue the handshake with the - * randomly generated 'fallback' value. - * - * NOTE: The comparison and replacement must be constant-time. - */ - int mask = (expectedVersion.getMajorVersion() ^ (M[0] & 0xFF)) - | (expectedVersion.getMinorVersion() ^ (M[1] & 0xFF)); - - // 'mask' will be all 1s if the versions matched, or else all 0s. - mask = (mask - 1) >> 31; - - for (int i = 0; i < 48; i++) - { - M[i] = (byte)((M[i] & mask) | (fallback[i] & ~mask)); - } - } + byte[] preMasterSecret = org.bouncycastle.crypto.tls.TlsRsaKeyExchange.decryptPreMasterSecret( + encryptedPreMasterSecret, 0, encryptedPreMasterSecret.length, rsaServerPrivateKey, + expectedVersion.getFullVersion(), crypto.getSecureRandom()); - return crypto.createSecret(M); + return crypto.createSecret(preMasterSecret); } } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsAEADCipherImpl.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsAEADCipherImpl.java index 49832fbec4..8096e31eaf 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsAEADCipherImpl.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsAEADCipherImpl.java @@ -9,6 +9,7 @@ import org.bouncycastle.tls.AlertDescription; import org.bouncycastle.tls.TlsFatalAlert; import org.bouncycastle.tls.crypto.impl.TlsAEADCipherImpl; +import org.bouncycastle.util.Arrays; final class BcTlsAEADCipherImpl implements TlsAEADCipherImpl @@ -29,9 +30,9 @@ public void setKey(byte[] key, int keyOff, int keyLen) this.key = new KeyParameter(key, keyOff, keyLen); } - public void init(byte[] nonce, int macSize, byte[] additionalData) + public void init(byte[] nonce, int macSize) { - cipher.init(isEncrypting, new AEADParameters(key, macSize * 8, nonce, additionalData)); + cipher.init(isEncrypting, new AEADParameters(key, macSize * 8, nonce, null)); } public int getOutputSize(int inputLength) @@ -39,9 +40,14 @@ public int getOutputSize(int inputLength) return cipher.getOutputSize(inputLength); } - public int doFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) + public int doFinal(byte[] additionalData, byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) throws IOException { + if (!Arrays.isNullOrEmpty(additionalData)) + { + cipher.processAADBytes(additionalData, 0, additionalData.length); + } + int len = cipher.processBytes(input, inputOffset, inputLength, output, outputOffset); try diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsCrypto.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsCrypto.java index a911a8be9b..9746ee43ba 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsCrypto.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsCrypto.java @@ -10,6 +10,7 @@ import org.bouncycastle.crypto.agreement.srp.SRP6Client; import org.bouncycastle.crypto.agreement.srp.SRP6Server; import org.bouncycastle.crypto.agreement.srp.SRP6VerifierGenerator; +import org.bouncycastle.crypto.digests.GOST3411_2012_256Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA224Digest; @@ -54,6 +55,8 @@ import org.bouncycastle.tls.crypto.TlsECDomain; import org.bouncycastle.tls.crypto.TlsHMAC; import org.bouncycastle.tls.crypto.TlsHash; +import org.bouncycastle.tls.crypto.TlsKemConfig; +import org.bouncycastle.tls.crypto.TlsKemDomain; import org.bouncycastle.tls.crypto.TlsNonceGenerator; import org.bouncycastle.tls.crypto.TlsSRP6Client; import org.bouncycastle.tls.crypto.TlsSRP6Server; @@ -79,6 +82,12 @@ public class BcTlsCrypto { private final SecureRandom entropySource; + // TODO[tls] Better default SecureRandom? + public BcTlsCrypto() + { + this(new SecureRandom()); + } + public BcTlsCrypto(SecureRandom entropySource) { this.entropySource = entropySource; @@ -176,9 +185,12 @@ public TlsCipher createCipher(TlsCryptoParameters cryptoParams, int encryptionAl // NOTE: Ignores macAlgorithm return createCipher_SM4_GCM(cryptoParams); + case EncryptionAlgorithm._28147_CNT_IMIT: case EncryptionAlgorithm.DES40_CBC: case EncryptionAlgorithm.DES_CBC: case EncryptionAlgorithm.IDEA_CBC: + case EncryptionAlgorithm.KUZNYECHIK_CTR_OMAC: + case EncryptionAlgorithm.MAGMA_CTR_OMAC: case EncryptionAlgorithm.RC2_CBC_40: case EncryptionAlgorithm.RC4_128: case EncryptionAlgorithm.RC4_40: @@ -205,6 +217,11 @@ public TlsECDomain createECDomain(TlsECConfig ecConfig) } } + public TlsKemDomain createKemDomain(TlsKemConfig kemConfig) + { + return new BcTlsMLKemDomain(this, kemConfig); + } + public TlsNonceGenerator createNonceGenerator(byte[] additionalSeedMaterial) { int cryptoHashAlgorithm = CryptoHashAlgorithm.sha256; @@ -252,6 +269,7 @@ public boolean hasCryptoHashAlgorithm(int cryptoHashAlgorithm) case CryptoHashAlgorithm.sha384: case CryptoHashAlgorithm.sha512: case CryptoHashAlgorithm.sm3: + case CryptoHashAlgorithm.gostr3411_2012_256: return true; default: @@ -276,7 +294,7 @@ public boolean hasCryptoSignatureAlgorithm(int cryptoSignatureAlgorithm) case CryptoSignatureAlgorithm.rsa_pss_pss_sha512: return true; - // TODO[draft-smyshlyaev-tls12-gost-suites-10] + // TODO[RFC 9189] case CryptoSignatureAlgorithm.gostr34102012_256: case CryptoSignatureAlgorithm.gostr34102012_512: @@ -298,6 +316,11 @@ public boolean hasECDHAgreement() return true; } + public boolean hasKemAgreement() + { + return true; + } + public boolean hasEncryptionAlgorithm(int encryptionAlgorithm) { switch (encryptionAlgorithm) @@ -327,9 +350,12 @@ public boolean hasEncryptionAlgorithm(int encryptionAlgorithm) case EncryptionAlgorithm.SM4_GCM: return true; + case EncryptionAlgorithm._28147_CNT_IMIT: case EncryptionAlgorithm.DES_CBC: case EncryptionAlgorithm.DES40_CBC: case EncryptionAlgorithm.IDEA_CBC: + case EncryptionAlgorithm.KUZNYECHIK_CTR_OMAC: + case EncryptionAlgorithm.MAGMA_CTR_OMAC: case EncryptionAlgorithm.RC2_CBC_40: case EncryptionAlgorithm.RC4_128: case EncryptionAlgorithm.RC4_40: @@ -399,11 +425,13 @@ public boolean hasSignatureAlgorithm(short signatureAlgorithm) case SignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512: return true; - // TODO[draft-smyshlyaev-tls12-gost-suites-10] + // TODO[RFC 9189] case SignatureAlgorithm.gostr34102012_256: case SignatureAlgorithm.gostr34102012_512: + // TODO[RFC 8998] // case SignatureAlgorithm.sm2: + default: return false; } @@ -483,13 +511,15 @@ public Digest cloneDigest(int cryptoHashAlgorithm, Digest digest) case CryptoHashAlgorithm.sha224: return new SHA224Digest((SHA224Digest)digest); case CryptoHashAlgorithm.sha256: - return new SHA256Digest((SHA256Digest)digest); + return SHA256Digest.newInstance(digest); case CryptoHashAlgorithm.sha384: return new SHA384Digest((SHA384Digest)digest); case CryptoHashAlgorithm.sha512: return new SHA512Digest((SHA512Digest)digest); case CryptoHashAlgorithm.sm3: return new SM3Digest((SM3Digest)digest); + case CryptoHashAlgorithm.gostr3411_2012_256: + return new GOST3411_2012_256Digest((GOST3411_2012_256Digest)digest); default: throw new IllegalArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm); } @@ -513,6 +543,8 @@ public Digest createDigest(int cryptoHashAlgorithm) return new SHA512Digest(); case CryptoHashAlgorithm.sm3: return new SM3Digest(); + case CryptoHashAlgorithm.gostr3411_2012_256: + return new GOST3411_2012_256Digest(); default: throw new IllegalArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm); } @@ -550,7 +582,7 @@ protected BlockCipher createBlockCipher(int encryptionAlgorithm) protected BlockCipher createCBCBlockCipher(BlockCipher blockCipher) { - return new CBCBlockCipher(blockCipher); + return CBCBlockCipher.newInstance(blockCipher); } protected BlockCipher createCBCBlockCipher(int encryptionAlgorithm) @@ -640,7 +672,7 @@ protected TlsNullCipher createNullCipher(TlsCryptoParameters cryptoParams, int m protected BlockCipher createAESEngine() { - return new AESEngine(); + return AESEngine.newInstance(); } protected BlockCipher createARIAEngine() @@ -676,7 +708,7 @@ protected AEADBlockCipher createCCMMode(BlockCipher engine) protected AEADBlockCipher createGCMMode(BlockCipher engine) { // TODO Consider allowing custom configuration of multiplier - return new GCMBlockCipher(engine); + return GCMBlockCipher.newInstance(engine); } protected AEADBlockCipher createAEADBlockCipher_AES_CCM() diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsMLKem.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsMLKem.java new file mode 100644 index 0000000000..897536f380 --- /dev/null +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsMLKem.java @@ -0,0 +1,61 @@ +package org.bouncycastle.tls.crypto.impl.bc; + +import java.io.IOException; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; +import org.bouncycastle.tls.crypto.TlsAgreement; +import org.bouncycastle.tls.crypto.TlsSecret; + +public class BcTlsMLKem implements TlsAgreement +{ + protected final BcTlsMLKemDomain domain; + + protected MLKEMPrivateKeyParameters privateKey; + protected MLKEMPublicKeyParameters publicKey; + protected TlsSecret secret; + + public BcTlsMLKem(BcTlsMLKemDomain domain) + { + this.domain = domain; + } + + public byte[] generateEphemeral() throws IOException + { + if (domain.isServer()) + { + SecretWithEncapsulation encap = domain.encapsulate(publicKey); + this.publicKey = null; + this.secret = domain.adoptLocalSecret(encap.getSecret()); + return encap.getEncapsulation(); + } + else + { + AsymmetricCipherKeyPair kp = domain.generateKeyPair(); + this.privateKey = (MLKEMPrivateKeyParameters)kp.getPrivate(); + return domain.encodePublicKey((MLKEMPublicKeyParameters)kp.getPublic()); + } + } + + public void receivePeerValue(byte[] peerValue) throws IOException + { + if (domain.isServer()) + { + this.publicKey = domain.decodePublicKey(peerValue); + } + else + { + this.secret = domain.decapsulate(privateKey, peerValue); + this.privateKey = null; + } + } + + public TlsSecret calculateSecret() throws IOException + { + TlsSecret secret = this.secret; + this.secret = null; + return secret; + } +} diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsMLKemDomain.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsMLKemDomain.java new file mode 100644 index 0000000000..11576c722c --- /dev/null +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsMLKemDomain.java @@ -0,0 +1,91 @@ +package org.bouncycastle.tls.crypto.impl.bc; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyPairGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; +import org.bouncycastle.tls.NamedGroup; +import org.bouncycastle.tls.crypto.TlsAgreement; +import org.bouncycastle.tls.crypto.TlsKemConfig; +import org.bouncycastle.tls.crypto.TlsKemDomain; + +public class BcTlsMLKemDomain implements TlsKemDomain +{ + protected static MLKEMParameters getKyberParameters(int namedGroup) + { + switch (namedGroup) + { + case NamedGroup.OQS_mlkem512: + return MLKEMParameters.ml_kem_512; + case NamedGroup.OQS_mlkem768: + case NamedGroup.DRAFT_mlkem768: + return MLKEMParameters.ml_kem_768; + case NamedGroup.OQS_mlkem1024: + case NamedGroup.DRAFT_mlkem1024: + return MLKEMParameters.ml_kem_1024; + default: + return null; + } + } + + protected final BcTlsCrypto crypto; + protected final MLKEMParameters kyberParameters; + protected final boolean isServer; + + public BcTlsMLKemDomain(BcTlsCrypto crypto, TlsKemConfig kemConfig) + { + this.crypto = crypto; + this.kyberParameters = getKyberParameters(kemConfig.getNamedGroup()); + this.isServer = kemConfig.isServer(); + } + + public BcTlsSecret adoptLocalSecret(byte[] secret) + { + return crypto.adoptLocalSecret(secret); + } + + public TlsAgreement createKem() + { + return new BcTlsMLKem(this); + } + + public BcTlsSecret decapsulate(MLKEMPrivateKeyParameters privateKey, byte[] ciphertext) + { + MLKEMExtractor kemExtract = new MLKEMExtractor(privateKey); + byte[] secret = kemExtract.extractSecret(ciphertext); + return adoptLocalSecret(secret); + } + + public MLKEMPublicKeyParameters decodePublicKey(byte[] encoding) + { + return new MLKEMPublicKeyParameters(kyberParameters, encoding); + } + + public SecretWithEncapsulation encapsulate(MLKEMPublicKeyParameters publicKey) + { + MLKEMGenerator kemGen = new MLKEMGenerator(crypto.getSecureRandom()); + return kemGen.generateEncapsulated(publicKey); + } + + public byte[] encodePublicKey(MLKEMPublicKeyParameters publicKey) + { + return publicKey.getEncoded(); + } + + public AsymmetricCipherKeyPair generateKeyPair() + { + MLKEMKeyPairGenerator keyPairGenerator = new MLKEMKeyPairGenerator(); + keyPairGenerator.init(new MLKEMKeyGenerationParameters(crypto.getSecureRandom(), kyberParameters)); + return keyPairGenerator.generateKeyPair(); + } + + public boolean isServer() + { + return isServer; + } +} diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsRSAPSSSigner.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsRSAPSSSigner.java index 8caaa2fc26..fe8c6153fa 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsRSAPSSSigner.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsRSAPSSSigner.java @@ -43,8 +43,7 @@ public byte[] generateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] h int cryptoHashAlgorithm = SignatureScheme.getCryptoHashAlgorithm(signatureScheme); Digest digest = crypto.createDigest(cryptoHashAlgorithm); - PSSSigner signer = PSSSigner.createRawSigner(new RSABlindedEngine(), digest, digest, digest.getDigestSize(), - PSSSigner.TRAILER_IMPLICIT); + PSSSigner signer = PSSSigner.createRawSigner(new RSABlindedEngine(), digest); signer.init(true, new ParametersWithRandom(privateKey, crypto.getSecureRandom())); signer.update(hash, 0, hash.length); try diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsRSAPSSVerifier.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsRSAPSSVerifier.java index 421af25b4b..6818456edb 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsRSAPSSVerifier.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsRSAPSSVerifier.java @@ -41,8 +41,7 @@ public boolean verifyRawSignature(DigitallySigned digitallySigned, byte[] hash) int cryptoHashAlgorithm = SignatureScheme.getCryptoHashAlgorithm(signatureScheme); Digest digest = crypto.createDigest(cryptoHashAlgorithm); - PSSSigner verifier = PSSSigner.createRawSigner(new RSAEngine(), digest, digest, digest.getDigestSize(), - PSSSigner.TRAILER_IMPLICIT); + PSSSigner verifier = PSSSigner.createRawSigner(new RSAEngine(), digest); verifier.init(false, publicKey); verifier.update(hash, 0, hash.length); return verifier.verifySignature(digitallySigned.getSignature()); diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsRawKeyCertificate.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsRawKeyCertificate.java index de5efc2203..cb5ddc5f68 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsRawKeyCertificate.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/bc/BcTlsRawKeyCertificate.java @@ -141,6 +141,10 @@ public TlsVerifier createVerifier(short signatureAlgorithm) throws IOException return new BcTlsRSAPSSVerifier(crypto, getPubKeyRSA(), signatureScheme); } + // TODO[RFC 9189] + case SignatureAlgorithm.gostr34102012_256: + case SignatureAlgorithm.gostr34102012_512: + default: throw new TlsFatalAlert(AlertDescription.certificate_unknown); } @@ -504,6 +508,10 @@ protected boolean supportsSignatureAlgorithm(short signatureAlgorithm, int keyUs return supportsRSA_PSS_PSS(signatureAlgorithm) && publicKey instanceof RSAKeyParameters; + // TODO[RFC 9189] + case SignatureAlgorithm.gostr34102012_256: + case SignatureAlgorithm.gostr34102012_512: + default: return false; } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/GCMUtil.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/GCMUtil.java index 72954b7cdf..c61091c5dd 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/GCMUtil.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/GCMUtil.java @@ -44,11 +44,16 @@ public Constructor run() try { String className = "javax.crypto.spec.GCMParameterSpec"; - + // + // needs to be exactly the same as in provider + // ClassLoader classLoader = GCMUtil.class.getClassLoader(); - Class clazz = (null == classLoader) - ? Class.forName(className) - : classLoader.loadClass(className); + if (classLoader == null) + { + classLoader = ClassLoader.getSystemClassLoader(); + } + + Class clazz = classLoader.loadClass(className); if (clazz != null && AlgorithmParameterSpec.class.isAssignableFrom(clazz)) { @SuppressWarnings("unchecked") diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCertificate.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCertificate.java index dedd63c8fb..0a45af98b4 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCertificate.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCertificate.java @@ -182,6 +182,10 @@ public TlsVerifier createVerifier(short signatureAlgorithm) throws IOException return new JcaTlsRSAPSSVerifier(crypto, getPubKeyRSA(), signatureScheme); } + // TODO[RFC 9189] + case SignatureAlgorithm.gostr34102012_256: + case SignatureAlgorithm.gostr34102012_512: + default: throw new TlsFatalAlert(AlertDescription.certificate_unknown); } @@ -506,6 +510,10 @@ protected boolean implSupportsSignatureAlgorithm(short signatureAlgorithm) throw return supportsRSA_PSS_PSS(signatureAlgorithm) && publicKey instanceof RSAPublicKey; + // TODO[RFC 9189] + case SignatureAlgorithm.gostr34102012_256: + case SignatureAlgorithm.gostr34102012_512: + default: return false; } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCrypto.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCrypto.java index 02d687bdb4..ed41f98699 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCrypto.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCrypto.java @@ -4,6 +4,7 @@ import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; +import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; @@ -47,6 +48,8 @@ import org.bouncycastle.tls.crypto.TlsECDomain; import org.bouncycastle.tls.crypto.TlsHMAC; import org.bouncycastle.tls.crypto.TlsHash; +import org.bouncycastle.tls.crypto.TlsKemConfig; +import org.bouncycastle.tls.crypto.TlsKemDomain; import org.bouncycastle.tls.crypto.TlsNonceGenerator; import org.bouncycastle.tls.crypto.TlsSRP6Client; import org.bouncycastle.tls.crypto.TlsSRP6Server; @@ -67,6 +70,7 @@ import org.bouncycastle.tls.crypto.impl.jcajce.srp.SRP6VerifierGenerator; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; +import org.bouncycastle.util.Strings; /** * Class for providing cryptographic services for TLS based on implementations in the JCA/JCE. @@ -233,9 +237,12 @@ public TlsCipher createCipher(TlsCryptoParameters cryptoParams, int encryptionAl // NOTE: Ignores macAlgorithm return createCipher_SM4_GCM(cryptoParams); + case EncryptionAlgorithm._28147_CNT_IMIT: case EncryptionAlgorithm.DES40_CBC: case EncryptionAlgorithm.DES_CBC: case EncryptionAlgorithm.IDEA_CBC: + case EncryptionAlgorithm.KUZNYECHIK_CTR_OMAC: + case EncryptionAlgorithm.MAGMA_CTR_OMAC: case EncryptionAlgorithm.RC2_CBC_40: case EncryptionAlgorithm.RC4_128: case EncryptionAlgorithm.RC4_40: @@ -404,6 +411,8 @@ String getHMACAlgorithmName(int cryptoHashAlgorithm) return "HmacSHA512"; case CryptoHashAlgorithm.sm3: return "HmacSM3"; + case CryptoHashAlgorithm.gostr3411_2012_256: + return "HmacGOST3411-2012-256"; default: throw new IllegalArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm); } @@ -434,6 +443,21 @@ else if (NamedGroup.refersToASpecificFiniteField(namedGroup)) { return DHUtil.getAlgorithmParameters(this, TlsDHUtils.getNamedDHGroup(namedGroup)); } + else if (NamedGroup.refersToASpecificKem(namedGroup)) + { + switch (namedGroup) + { + /* + * TODO[tls-kem] Return AlgorithmParameters to check against disabled algorithms? + */ + case NamedGroup.OQS_mlkem512: + case NamedGroup.OQS_mlkem768: + case NamedGroup.OQS_mlkem1024: + case NamedGroup.DRAFT_mlkem768: + case NamedGroup.DRAFT_mlkem1024: + return null; + } + } throw new IllegalArgumentException("NamedGroup not supported: " + NamedGroup.getText(namedGroup)); } @@ -536,7 +560,7 @@ public boolean hasCryptoSignatureAlgorithm(int cryptoSignatureAlgorithm) case CryptoSignatureAlgorithm.rsa_pss_pss_sha512: return true; - // TODO[draft-smyshlyaev-tls12-gost-suites-10] + // TODO[RFC 9189] case CryptoSignatureAlgorithm.gostr34102012_256: case CryptoSignatureAlgorithm.gostr34102012_512: @@ -557,6 +581,11 @@ public boolean hasECDHAgreement() { return true; } + + public boolean hasKemAgreement() + { + return true; + } public boolean hasEncryptionAlgorithm(int encryptionAlgorithm) { @@ -713,11 +742,13 @@ public boolean hasSignatureAlgorithm(short signatureAlgorithm) case SignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512: return true; - // TODO[draft-smyshlyaev-tls12-gost-suites-10] + // TODO[RFC 9189] case SignatureAlgorithm.gostr34102012_256: case SignatureAlgorithm.gostr34102012_512: + // TODO[RFC 8998] // case SignatureAlgorithm.sm2: + default: return false; } @@ -821,6 +852,11 @@ public TlsECDomain createECDomain(TlsECConfig ecConfig) return new JceTlsECDomain(this, ecConfig); } } + + public TlsKemDomain createKemDomain(TlsKemConfig kemConfig) + { + return new JceTlsMLKemDomain(this, kemConfig); + } public TlsSecret hkdfInit(int cryptoHashAlgorithm) { @@ -840,7 +876,7 @@ public TlsSecret hkdfInit(int cryptoHashAlgorithm) protected TlsAEADCipherImpl createAEADCipher(String cipherName, String algorithm, int keySize, boolean isEncrypting) throws GeneralSecurityException { - return new JceAEADCipherImpl(helper, cipherName, algorithm, keySize, isEncrypting); + return new JceAEADCipherImpl(this, helper, cipherName, algorithm, keySize, isEncrypting); } /** @@ -853,10 +889,11 @@ protected TlsAEADCipherImpl createAEADCipher(String cipherName, String algorithm * @return a block cipher. * @throws GeneralSecurityException in case of failure. */ - protected TlsBlockCipherImpl createBlockCipher(String cipherName, String algorithm, int keySize, boolean isEncrypting) + protected TlsBlockCipherImpl createBlockCipher(String cipherName, String algorithm, int keySize, + boolean isEncrypting) throws GeneralSecurityException { - return new JceBlockCipherImpl(helper.createCipher(cipherName), algorithm, keySize, isEncrypting); + return new JceBlockCipherImpl(this, helper.createCipher(cipherName), algorithm, keySize, isEncrypting); } /** @@ -869,10 +906,11 @@ protected TlsBlockCipherImpl createBlockCipher(String cipherName, String algorit * @return a block cipher. * @throws GeneralSecurityException in case of failure. */ - protected TlsBlockCipherImpl createBlockCipherWithCBCImplicitIV(String cipherName, String algorithm, int keySize, boolean isEncrypting) + protected TlsBlockCipherImpl createBlockCipherWithCBCImplicitIV(String cipherName, String algorithm, int keySize, + boolean isEncrypting) throws GeneralSecurityException { - return new JceBlockCipherWithCBCImplicitIVImpl(helper.createCipher(cipherName), algorithm, isEncrypting); + return new JceBlockCipherWithCBCImplicitIVImpl(this, helper.createCipher(cipherName), algorithm, isEncrypting); } /** @@ -919,20 +957,38 @@ protected TlsStreamSigner createStreamSigner(String algorithmName, AlgorithmPara SecureRandom random = needsRandom ? getSecureRandom() : null; JcaJceHelper helper = getHelper(); - if (null != parameter) + + try { - Signature dummySigner = helper.createSignature(algorithmName); - dummySigner.initSign(privateKey, random); - helper = new ProviderJcaJceHelper(dummySigner.getProvider()); - } + if (null != parameter) + { + Signature dummySigner = helper.createSignature(algorithmName); + dummySigner.initSign(privateKey, random); + helper = new ProviderJcaJceHelper(dummySigner.getProvider()); + } - Signature signer = helper.createSignature(algorithmName); - if (null != parameter) + Signature signer = helper.createSignature(algorithmName); + if (null != parameter) + { + signer.setParameter(parameter); + } + signer.initSign(privateKey, random); + return new JcaTlsStreamSigner(signer); + } + catch (InvalidKeyException e) { - signer.setParameter(parameter); + String upperAlg = Strings.toUpperCase(algorithmName); + if (upperAlg.endsWith("MGF1")) + { + // ANDMGF1 has vanished from the Sun PKCS11 provider. + algorithmName = upperAlg.replace("ANDMGF1", "SSA-PSS"); + return createStreamSigner(algorithmName, parameter, privateKey, needsRandom); + } + else + { + throw e; + } } - signer.initSign(privateKey, random); - return new JcaTlsStreamSigner(signer); } catch (GeneralSecurityException e) { @@ -1083,9 +1139,12 @@ protected Boolean isSupportedEncryptionAlgorithm(int encryptionAlgorithm) case EncryptionAlgorithm.SM4_GCM: return isUsableCipher("SM4/GCM/NoPadding", 128); + case EncryptionAlgorithm._28147_CNT_IMIT: case EncryptionAlgorithm.DES_CBC: case EncryptionAlgorithm.DES40_CBC: case EncryptionAlgorithm.IDEA_CBC: + case EncryptionAlgorithm.KUZNYECHIK_CTR_OMAC: + case EncryptionAlgorithm.MAGMA_CTR_OMAC: case EncryptionAlgorithm.RC2_CBC_40: case EncryptionAlgorithm.RC4_128: case EncryptionAlgorithm.RC4_40: @@ -1126,6 +1185,11 @@ protected Boolean isSupportedNamedGroup(int namedGroup) } } } + else if (NamedGroup.refersToASpecificKem(namedGroup)) + { + // TODO[tls-kem] When implemented via provider, need to check for support dynamically + return Boolean.TRUE; + } else if (NamedGroup.refersToAnECDSACurve(namedGroup)) { return Boolean.valueOf(ECUtil.isCurveSupported(this, NamedGroup.getCurveName(namedGroup))); @@ -1193,8 +1257,8 @@ protected TlsBlockCipherImpl createCBCBlockCipherImpl(TlsCryptoParameters crypto private TlsCipher createChaCha20Poly1305(TlsCryptoParameters cryptoParams) throws IOException, GeneralSecurityException { - return new TlsAEADCipher(cryptoParams, new JceChaCha20Poly1305(helper, true), - new JceChaCha20Poly1305(helper, false), 32, 16, TlsAEADCipher.AEAD_CHACHA20_POLY1305); + return new TlsAEADCipher(cryptoParams, new JceChaCha20Poly1305(this, helper, true), + new JceChaCha20Poly1305(this, helper, false), 32, 16, TlsAEADCipher.AEAD_CHACHA20_POLY1305); } private TlsAEADCipher createCipher_AES_CCM(TlsCryptoParameters cryptoParams, int cipherKeySize, int macSize) @@ -1278,6 +1342,8 @@ String getDigestName(int cryptoHashAlgorithm) return "SHA-512"; case CryptoHashAlgorithm.sm3: return "SM3"; + case CryptoHashAlgorithm.gostr3411_2012_256: + return "GOST3411-2012-256"; default: throw new IllegalArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm); } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCryptoProvider.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCryptoProvider.java index 6ac903823d..8368e8682c 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCryptoProvider.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCryptoProvider.java @@ -61,6 +61,8 @@ public JcaTlsCrypto create(SecureRandom random) { try { + JcaJceHelper helper = getHelper(); + if (random == null) { if (helper instanceof DefaultJcaJceHelper) @@ -69,7 +71,7 @@ public JcaTlsCrypto create(SecureRandom random) } else { - random = SecureRandom.getInstance("DEFAULT", helper.createDigest("SHA-512").getProvider()); + random = SecureRandom.getInstance("DEFAULT", helper.createMessageDigest("SHA-512").getProvider()); } } @@ -90,7 +92,7 @@ public JcaTlsCrypto create(SecureRandom random) */ public JcaTlsCrypto create(SecureRandom keyRandom, SecureRandom nonceRandom) { - return new JcaTlsCrypto(helper, keyRandom, nonceRandom); + return new JcaTlsCrypto(getHelper(), keyRandom, nonceRandom); } public JcaJceHelper getHelper() @@ -105,7 +107,7 @@ private static class NonceEntropySource NonceEntropySource(JcaJceHelper helper, SecureRandom random) throws GeneralSecurityException { - super(new NonceEntropySourceSpi(random, helper.createDigest("SHA-512")), random.getProvider()); + super(new NonceEntropySourceSpi(random, helper.createMessageDigest("SHA-512")), random.getProvider()); } private static class NonceEntropySourceSpi diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceAEADCipherImpl.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceAEADCipherImpl.java index 60a3158840..978acfaeb7 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceAEADCipherImpl.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceAEADCipherImpl.java @@ -5,6 +5,7 @@ import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.PrivilegedAction; +import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.SecretKey; @@ -14,6 +15,7 @@ import org.bouncycastle.jcajce.spec.AEADParameterSpec; import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.tls.crypto.impl.TlsAEADCipherImpl; +import org.bouncycastle.util.Arrays; /** * A basic wrapper for a JCE Cipher class to provide the needed AEAD cipher functionality for TLS. @@ -57,6 +59,7 @@ private static String getAlgParamsName(JcaJceHelper helper, String cipherName) } } + private final JcaTlsCrypto crypto; private final JcaJceHelper helper; private final int cipherMode; private final Cipher cipher; @@ -65,15 +68,19 @@ private static String getAlgParamsName(JcaJceHelper helper, String cipherName) private final String algorithmParamsName; private SecretKey key; + private byte[] nonce; + private int macSize; - public JceAEADCipherImpl(JcaJceHelper helper, String cipherName, String algorithm, int keySize, boolean isEncrypting) + public JceAEADCipherImpl(JcaTlsCrypto crypto, JcaJceHelper helper, String cipherName, String algorithm, int keySize, + boolean isEncrypting) throws GeneralSecurityException { + this.crypto = crypto; this.helper = helper; this.cipher = helper.createCipher(cipherName); this.algorithm = algorithm; this.keySize = keySize; - this.cipherMode = (isEncrypting) ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; + this.cipherMode = isEncrypting ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; this.algorithmParamsName = getAlgParamsName(helper, cipherName); } @@ -87,8 +94,11 @@ public void setKey(byte[] key, int keyOff, int keyLen) this.key = new SecretKeySpec(key, keyOff, keyLen, algorithm); } - public void init(byte[] nonce, int macSize, byte[] additionalData) + public void init(byte[] nonce, int macSize) { + // NOTE: Shouldn't need a SecureRandom, but this is cheaper if the provider would auto-create one + SecureRandom random = crypto.getSecureRandom(); + try { if (canDoAEAD && algorithmParamsName != null) @@ -106,17 +116,14 @@ public void init(byte[] nonce, int macSize, byte[] additionalData) algParams.init(new GCMParameters(nonce, macSize).getEncoded()); } - cipher.init(cipherMode, key, algParams, null); - - if (additionalData != null && additionalData.length > 0) - { - cipher.updateAAD(additionalData); - } + cipher.init(cipherMode, key, algParams, random); } else { // Otherwise fall back to the BC-specific AEADParameterSpec - cipher.init(cipherMode, key, new AEADParameterSpec(nonce, macSize * 8, additionalData), null); + cipher.init(cipherMode, key, new AEADParameterSpec(nonce, macSize * 8, null), random); + this.nonce = Arrays.clone(nonce); + this.macSize = macSize; } } catch (Exception e) @@ -130,9 +137,28 @@ public int getOutputSize(int inputLength) return cipher.getOutputSize(inputLength); } - public int doFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) + public int doFinal(byte[] additionalData, byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) throws IOException { + if (!Arrays.isNullOrEmpty(additionalData)) + { + if (canDoAEAD) + { + cipher.updateAAD(additionalData); + } + else + { + try + { + cipher.init(cipherMode, key, new AEADParameterSpec(nonce, macSize * 8, additionalData)); + } + catch (Exception e) + { + throw new IOException(e); + } + } + } + /* * NOTE: Some providers don't allow cipher update methods with AEAD decryption, * since they may return partial data that has not yet been authenticated. So we diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceBlockCipherImpl.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceBlockCipherImpl.java index 6c84656f84..8269b3e886 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceBlockCipherImpl.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceBlockCipherImpl.java @@ -1,6 +1,7 @@ package org.bouncycastle.tls.crypto.impl.jcajce; import java.security.GeneralSecurityException; +import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.SecretKey; @@ -17,20 +18,22 @@ public class JceBlockCipherImpl { private static final int BUF_SIZE = 32 * 1024; - private final int cipherMode; + private final JcaTlsCrypto crypto; private final Cipher cipher; private final String algorithm; private final int keySize; + private final int cipherMode; private SecretKey key; - public JceBlockCipherImpl(Cipher cipher, String algorithm, int keySize, boolean isEncrypting) + public JceBlockCipherImpl(JcaTlsCrypto crypto, Cipher cipher, String algorithm, int keySize, boolean isEncrypting) throws GeneralSecurityException { + this.crypto = crypto; this.cipher = cipher; this.algorithm = algorithm; this.keySize = keySize; - this.cipherMode = (isEncrypting) ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; + this.cipherMode = isEncrypting ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; } public void setKey(byte[] key, int keyOff, int keyLen) @@ -45,9 +48,12 @@ public void setKey(byte[] key, int keyOff, int keyLen) public void init(byte[] iv, int ivOff, int ivLen) { + // NOTE: Shouldn't need a SecureRandom, but this is cheaper if the provider would auto-create one + SecureRandom random = crypto.getSecureRandom(); + try { - cipher.init(cipherMode, key, new IvParameterSpec(iv, ivOff, ivLen), null); + cipher.init(cipherMode, key, new IvParameterSpec(iv, ivOff, ivLen), random); } catch (GeneralSecurityException e) { diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceBlockCipherWithCBCImplicitIVImpl.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceBlockCipherWithCBCImplicitIVImpl.java index 918ee5c10d..d674cdba58 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceBlockCipherWithCBCImplicitIVImpl.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceBlockCipherWithCBCImplicitIVImpl.java @@ -1,6 +1,7 @@ package org.bouncycastle.tls.crypto.impl.jcajce; import java.security.GeneralSecurityException; +import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.SecretKey; @@ -19,19 +20,22 @@ public class JceBlockCipherWithCBCImplicitIVImpl { private static final int BUF_SIZE = 32 * 1024; + private final JcaTlsCrypto crypto; private final Cipher cipher; private final String algorithm; - private final boolean isEncrypting; + private final int cipherMode; private SecretKey key; private byte[] nextIV; - public JceBlockCipherWithCBCImplicitIVImpl(Cipher cipher, String algorithm, boolean isEncrypting) + public JceBlockCipherWithCBCImplicitIVImpl(JcaTlsCrypto crypto, Cipher cipher, String algorithm, + boolean isEncrypting) throws GeneralSecurityException { + this.crypto = crypto; this.cipher = cipher; this.algorithm = algorithm; - this.isEncrypting = isEncrypting; + this.cipherMode = isEncrypting ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; } public void setKey(byte[] key, int keyOff, int keyLen) @@ -51,13 +55,16 @@ public void init(byte[] iv, int ivOff, int ivLen) public int doFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) { + // NOTE: Shouldn't need a SecureRandom, but this is cheaper if the provider would auto-create one + SecureRandom random = crypto.getSecureRandom(); + try { - cipher.init(isEncrypting ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, key, new IvParameterSpec(nextIV), null); + cipher.init(cipherMode, key, new IvParameterSpec(nextIV), random); nextIV = null; - if (!isEncrypting) + if (Cipher.ENCRYPT_MODE != cipherMode) { nextIV = TlsUtils.copyOfRangeExact(input, inputOffset + inputLength - cipher.getBlockSize(), inputOffset + inputLength); } @@ -75,7 +82,7 @@ public int doFinal(byte[] input, int inputOffset, int inputLength, byte[] output totLen += cipher.update(input, inputOffset, inputLength, output, outputOffset + totLen); totLen += cipher.doFinal(output, outputOffset + totLen); - if (isEncrypting) + if (Cipher.ENCRYPT_MODE == cipherMode) { nextIV = TlsUtils.copyOfRangeExact(output, outputOffset + totLen - cipher.getBlockSize(), outputOffset + totLen); } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceChaCha20Poly1305.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceChaCha20Poly1305.java index 4503b7b226..d9b5464bec 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceChaCha20Poly1305.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceChaCha20Poly1305.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; +import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.Mac; @@ -15,27 +16,31 @@ import org.bouncycastle.tls.TlsFatalAlert; import org.bouncycastle.tls.TlsUtils; import org.bouncycastle.tls.crypto.impl.TlsAEADCipherImpl; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Pack; public class JceChaCha20Poly1305 implements TlsAEADCipherImpl { private static final byte[] ZEROES = new byte[15]; + protected final JcaTlsCrypto crypto; protected final Cipher cipher; protected final Mac mac; protected final int cipherMode; protected SecretKey cipherKey; - protected byte[] additionalData; - public JceChaCha20Poly1305(JcaJceHelper helper, boolean isEncrypting) throws GeneralSecurityException + public JceChaCha20Poly1305(JcaTlsCrypto crypto, JcaJceHelper helper, boolean isEncrypting) + throws GeneralSecurityException { + this.crypto = crypto; this.cipher = helper.createCipher("ChaCha7539"); this.mac = helper.createMac("Poly1305"); this.cipherMode = isEncrypting ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; } - public int doFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) + public int doFinal(byte[] additionalData, byte[] input, int inputOffset, int inputLength, byte[] output, + int outputOffset) throws IOException { /* @@ -59,11 +64,18 @@ public int doFinal(byte[] input, int inputOffset, int inputLength, byte[] output System.arraycopy(tmp, 64, output, outputOffset, ciphertextLength); initMAC(tmp); - updateMAC(additionalData, 0, additionalData.length); + + int additionalDataLength = 0; + if (!Arrays.isNullOrEmpty(additionalData)) + { + additionalDataLength = additionalData.length; + updateMAC(additionalData, 0, additionalData.length); + } + updateMAC(tmp, 64, ciphertextLength); byte[] lengths = new byte[16]; - Pack.longToLittleEndian(additionalData.length & 0xFFFFFFFFL, lengths, 0); + Pack.longToLittleEndian(additionalDataLength & 0xFFFFFFFFL, lengths, 0); Pack.longToLittleEndian(ciphertextLength & 0xFFFFFFFFL, lengths, 8); mac.update(lengths, 0, 16); @@ -81,11 +93,18 @@ public int doFinal(byte[] input, int inputOffset, int inputLength, byte[] output runCipher(tmp); initMAC(tmp); - updateMAC(additionalData, 0, additionalData.length); + + int additionalDataLength = 0; + if (!Arrays.isNullOrEmpty(additionalData)) + { + additionalDataLength = additionalData.length; + updateMAC(additionalData, 0, additionalData.length); + } + updateMAC(input, inputOffset, ciphertextLength); byte[] expectedMac = new byte[16]; - Pack.longToLittleEndian(additionalData.length & 0xFFFFFFFFL, expectedMac, 0); + Pack.longToLittleEndian(additionalDataLength & 0xFFFFFFFFL, expectedMac, 0); Pack.longToLittleEndian(ciphertextLength & 0xFFFFFFFFL, expectedMac, 8); mac.update(expectedMac, 0, 16); mac.doFinal(expectedMac, 0); @@ -113,23 +132,24 @@ public int getOutputSize(int inputLength) return cipherMode == Cipher.ENCRYPT_MODE ? inputLength + 16 : inputLength - 16; } - public void init(byte[] nonce, int macSize, byte[] additionalData) throws IOException + public void init(byte[] nonce, int macSize) throws IOException { if (nonce == null || nonce.length != 12 || macSize != 16) { throw new TlsFatalAlert(AlertDescription.internal_error); } + // NOTE: Shouldn't need a SecureRandom, but this is cheaper if the provider would auto-create one + SecureRandom random = crypto.getSecureRandom(); + try { - cipher.init(cipherMode, cipherKey, new IvParameterSpec(nonce), null); + cipher.init(cipherMode, cipherKey, new IvParameterSpec(nonce), random); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } - - this.additionalData = additionalData; } public void setKey(byte[] key, int keyOff, int keyLen) throws IOException diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceDefaultTlsCredentialedDecryptor.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceDefaultTlsCredentialedDecryptor.java index 21345c464a..a55935ab11 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceDefaultTlsCredentialedDecryptor.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceDefaultTlsCredentialedDecryptor.java @@ -7,12 +7,12 @@ import javax.crypto.Cipher; +import org.bouncycastle.jcajce.spec.TLSRSAPremasterSecretParameterSpec; import org.bouncycastle.tls.Certificate; import org.bouncycastle.tls.ProtocolVersion; import org.bouncycastle.tls.TlsCredentialedDecryptor; import org.bouncycastle.tls.crypto.TlsCryptoParameters; import org.bouncycastle.tls.crypto.TlsSecret; -import org.bouncycastle.tls.crypto.impl.TlsImplUtils; import org.bouncycastle.util.Arrays; /** @@ -70,11 +70,11 @@ public TlsSecret decrypt(TlsCryptoParameters cryptoParams, byte[] ciphertext) th } /* - * TODO[tls-ops] Probably need to make RSA encryption/decryption into TlsCrypto functions so - * that users can implement "generic" encryption credentials externally + * TODO[tls-ops] Probably need to make RSA encryption/decryption into TlsCrypto functions so that users + * can implement "generic" encryption credentials externally */ protected TlsSecret safeDecryptPreMasterSecret(TlsCryptoParameters cryptoParams, PrivateKey rsaServerPrivateKey, - byte[] encryptedPreMasterSecret) + byte[] encryptedPreMasterSecret) { SecureRandom secureRandom = crypto.getSecureRandom(); @@ -82,60 +82,60 @@ protected TlsSecret safeDecryptPreMasterSecret(TlsCryptoParameters cryptoParams, * RFC 5246 7.4.7.1. */ ProtocolVersion expectedVersion = cryptoParams.getRSAPreMasterSecretVersion(); + byte[] M; - // TODO Provide as configuration option? - boolean versionNumberCheckDisabled = false; - - /* - * Generate 48 random bytes we can use as a Pre-Master-Secret, if the - * PKCS1 padding check should fail. - */ - byte[] fallback = new byte[48]; - secureRandom.nextBytes(fallback); - - byte[] M = Arrays.clone(fallback); try { + // The use of the TLSRSAPremasterSecretParameterSpec signals to the BC provider that + // that the underlying implementation should not throw exceptions but return a random + // value on failures where the plaintext turns out to be invalid. Cipher c = crypto.createRSAEncryptionCipher(); - c.init(Cipher.DECRYPT_MODE, rsaServerPrivateKey, secureRandom); - byte[] m = c.doFinal(encryptedPreMasterSecret); - if (m != null && m.length == 48) - { - M = m; - } + + c.init(Cipher.DECRYPT_MODE, rsaServerPrivateKey, new TLSRSAPremasterSecretParameterSpec(expectedVersion.getFullVersion()), secureRandom); + M = c.doFinal(encryptedPreMasterSecret); } - catch (Exception e) + catch (Exception ex) { - /* - * A TLS server MUST NOT generate an alert if processing an - * RSA-encrypted premaster secret message fails, or the version number is not as - * expected. Instead, it MUST continue the handshake with a randomly generated - * premaster secret. - */ - } + // Fallback - note this will likely result in some level of a timing signal as traditionally + // JCE RSA providers will signal padding errors by throwing exceptions. The real answer to this + // problem is not to use RSA encryption based cipher suites. - /* - * If ClientHello.legacy_version is TLS 1.1 or higher, server implementations MUST check the - * version number [..]. - */ - if (versionNumberCheckDisabled && !TlsImplUtils.isTLSv11(expectedVersion)) - { /* - * If the version number is TLS 1.0 or earlier, server implementations SHOULD check the - * version number, but MAY have a configuration option to disable the check. + * Generate 48 random bytes we can use as a Pre-Master-Secret, if the PKCS1 padding check should fail. */ - } - else - { + byte[] fallback = new byte[48]; + secureRandom.nextBytes(fallback); + + M = Arrays.clone(fallback); + try + { + Cipher c = crypto.createRSAEncryptionCipher(); + + c.init(Cipher.DECRYPT_MODE, rsaServerPrivateKey, secureRandom); + byte[] m = c.doFinal(encryptedPreMasterSecret); + if (m != null && m.length == 48) + { + M = m; + } + } + catch (Exception e) + { + /* + * A TLS server MUST NOT generate an alert if processing an RSA-encrypted premaster secret message + * fails, or the version number is not as expected. Instead, it MUST continue the handshake with a + * randomly generated premaster secret. + */ + } + /* - * Compare the version number in the decrypted Pre-Master-Secret with the legacy_version - * field from the ClientHello. If they don't match, continue the handshake with the - * randomly generated 'fallback' value. + * Compare the version number in the decrypted Pre-Master-Secret with the legacy_version field from + * the ClientHello. If they don't match, continue the handshake with the randomly generated 'fallback' + * value. * * NOTE: The comparison and replacement must be constant-time. */ int mask = (expectedVersion.getMajorVersion() ^ (M[0] & 0xFF)) - | (expectedVersion.getMinorVersion() ^ (M[1] & 0xFF)); + | (expectedVersion.getMinorVersion() ^ (M[1] & 0xFF)); // 'mask' will be all 1s if the versions matched, or else all 0s. mask = (mask - 1) >> 31; diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsMLKem.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsMLKem.java new file mode 100644 index 0000000000..44f73f2bbb --- /dev/null +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsMLKem.java @@ -0,0 +1,61 @@ +package org.bouncycastle.tls.crypto.impl.jcajce; + +import java.io.IOException; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; +import org.bouncycastle.tls.crypto.TlsAgreement; +import org.bouncycastle.tls.crypto.TlsSecret; + +public class JceTlsMLKem implements TlsAgreement +{ + protected final JceTlsMLKemDomain domain; + + protected MLKEMPrivateKeyParameters privateKey; + protected MLKEMPublicKeyParameters publicKey; + protected TlsSecret secret; + + public JceTlsMLKem(JceTlsMLKemDomain domain) + { + this.domain = domain; + } + + public byte[] generateEphemeral() throws IOException + { + if (domain.isServer()) + { + SecretWithEncapsulation encap = domain.encapsulate(publicKey); + this.publicKey = null; + this.secret = domain.adoptLocalSecret(encap.getSecret()); + return encap.getEncapsulation(); + } + else + { + AsymmetricCipherKeyPair kp = domain.generateKeyPair(); + this.privateKey = (MLKEMPrivateKeyParameters)kp.getPrivate(); + return domain.encodePublicKey((MLKEMPublicKeyParameters)kp.getPublic()); + } + } + + public void receivePeerValue(byte[] peerValue) throws IOException + { + if (domain.isServer()) + { + this.publicKey = domain.decodePublicKey(peerValue); + } + else + { + this.secret = domain.decapsulate(privateKey, peerValue); + this.privateKey = null; + } + } + + public TlsSecret calculateSecret() throws IOException + { + TlsSecret secret = this.secret; + this.secret = null; + return secret; + } +} diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsMLKemDomain.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsMLKemDomain.java new file mode 100644 index 0000000000..a829b851a0 --- /dev/null +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsMLKemDomain.java @@ -0,0 +1,91 @@ +package org.bouncycastle.tls.crypto.impl.jcajce; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyPairGenerator; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; +import org.bouncycastle.tls.NamedGroup; +import org.bouncycastle.tls.crypto.TlsAgreement; +import org.bouncycastle.tls.crypto.TlsKemConfig; +import org.bouncycastle.tls.crypto.TlsKemDomain; + +public class JceTlsMLKemDomain implements TlsKemDomain +{ + protected static MLKEMParameters getKyberParameters(int namedGroup) + { + switch (namedGroup) + { + case NamedGroup.OQS_mlkem512: + return MLKEMParameters.ml_kem_512; + case NamedGroup.OQS_mlkem768: + case NamedGroup.DRAFT_mlkem768: + return MLKEMParameters.ml_kem_768; + case NamedGroup.OQS_mlkem1024: + case NamedGroup.DRAFT_mlkem1024: + return MLKEMParameters.ml_kem_1024; + default: + return null; + } + } + + protected final JcaTlsCrypto crypto; + protected final MLKEMParameters kyberParameters; + protected final boolean isServer; + + public JceTlsMLKemDomain(JcaTlsCrypto crypto, TlsKemConfig kemConfig) + { + this.crypto = crypto; + this.kyberParameters = getKyberParameters(kemConfig.getNamedGroup()); + this.isServer = kemConfig.isServer(); + } + + public JceTlsSecret adoptLocalSecret(byte[] secret) + { + return crypto.adoptLocalSecret(secret); + } + + public TlsAgreement createKem() + { + return new JceTlsMLKem(this); + } + + public JceTlsSecret decapsulate(MLKEMPrivateKeyParameters privateKey, byte[] ciphertext) + { + MLKEMExtractor kemExtract = new MLKEMExtractor(privateKey); + byte[] secret = kemExtract.extractSecret(ciphertext); + return adoptLocalSecret(secret); + } + + public MLKEMPublicKeyParameters decodePublicKey(byte[] encoding) + { + return new MLKEMPublicKeyParameters(kyberParameters, encoding); + } + + public SecretWithEncapsulation encapsulate(MLKEMPublicKeyParameters publicKey) + { + MLKEMGenerator kemGen = new MLKEMGenerator(crypto.getSecureRandom()); + return kemGen.generateEncapsulated(publicKey); + } + + public byte[] encodePublicKey(MLKEMPublicKeyParameters publicKey) + { + return publicKey.getEncoded(); + } + + public AsymmetricCipherKeyPair generateKeyPair() + { + MLKEMKeyPairGenerator keyPairGenerator = new MLKEMKeyPairGenerator(); + keyPairGenerator.init(new MLKEMKeyGenerationParameters(crypto.getSecureRandom(), kyberParameters)); + return keyPairGenerator.generateKeyPair(); + } + + public boolean isServer() + { + return isServer; + } +} diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsSecret.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsSecret.java index 421c18bb5e..b05c0a1761 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsSecret.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsSecret.java @@ -226,8 +226,8 @@ protected byte[] prf(int prfAlgorithm, String label, byte[] seed, int length) protected byte[] prf_SSL(byte[] seed, int length) throws GeneralSecurityException { - MessageDigest md5 = crypto.getHelper().createDigest("MD5"); - MessageDigest sha1 = crypto.getHelper().createDigest("SHA-1"); + MessageDigest md5 = crypto.getHelper().createMessageDigest("MD5"); + MessageDigest sha1 = crypto.getHelper().createMessageDigest("SHA-1"); int md5Size = md5.getDigestLength(); int sha1Size = sha1.getDigestLength(); diff --git a/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/GCMUtil.java b/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/GCMUtil.java index cd945a06c0..6c1f7455a9 100644 --- a/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/GCMUtil.java +++ b/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/GCMUtil.java @@ -1,73 +1,17 @@ package org.bouncycastle.tls.crypto.impl.jcajce; -import java.lang.reflect.Constructor; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; import java.security.spec.AlgorithmParameterSpec; -import org.bouncycastle.util.Integers; - class GCMUtil { - static final Constructor gcmParameterSpec = getConstructor(); - static AlgorithmParameterSpec createGCMParameterSpec(final int tLen, final byte[] src) throws Exception { - if (gcmParameterSpec == null) - { - throw new IllegalStateException(); - } - -/* - return AccessController.doPrivileged(new PrivilegedExceptionAction() - { - public AlgorithmParameterSpec run() - throws Exception - { - return gcmParameterSpec.newInstance(new Object[]{ Integers.valueOf(tLen), src }); - } - }); -*/ - return null; + throw new IllegalStateException(); } static boolean isGCMParameterSpecAvailable() { - return gcmParameterSpec != null; - } - - private static Constructor getConstructor() - { -/* - return AccessController.doPrivileged(new PrivilegedAction>() - { - public Constructor run() - { - try - { - String className = "javax.crypto.spec.GCMParameterSpec"; - - ClassLoader classLoader = GCMUtil.class.getClassLoader(); - Class clazz = (null == classLoader) - ? Class.forName(className) - : classLoader.loadClass(className); - if (clazz != null && AlgorithmParameterSpec.class.isAssignableFrom(clazz)) - { - @SuppressWarnings("unchecked") - Class typedClazz = (Class)clazz; - return typedClazz.getConstructor(new Class[]{ Integer.TYPE, byte[].class }); - } - } - catch (Exception e) - { - } - - return null; - } - }); -*/ - return null; + return false; } } diff --git a/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCertificate.java b/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCertificate.java index 99638a65f5..a1ae6d10a1 100644 --- a/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCertificate.java +++ b/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCertificate.java @@ -182,6 +182,10 @@ public TlsVerifier createVerifier(short signatureAlgorithm) throws IOException return new JcaTlsRSAPSSVerifier(crypto, getPubKeyRSA(), signatureScheme); } + // TODO[RFC 9189] + case SignatureAlgorithm.gostr34102012_256: + case SignatureAlgorithm.gostr34102012_512: + default: throw new TlsFatalAlert(AlertDescription.certificate_unknown); } @@ -506,6 +510,10 @@ protected boolean implSupportsSignatureAlgorithm(short signatureAlgorithm) throw return supportsRSA_PSS_PSS(signatureAlgorithm) && publicKey instanceof RSAPublicKey; + // TODO[RFC 9189] + case SignatureAlgorithm.gostr34102012_256: + case SignatureAlgorithm.gostr34102012_512: + default: return false; } diff --git a/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCrypto.java b/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCrypto.java index 587930516f..2f6b8dbdbe 100644 --- a/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCrypto.java +++ b/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCrypto.java @@ -47,6 +47,8 @@ import org.bouncycastle.tls.crypto.TlsECDomain; import org.bouncycastle.tls.crypto.TlsHMAC; import org.bouncycastle.tls.crypto.TlsHash; +import org.bouncycastle.tls.crypto.TlsKemConfig; +import org.bouncycastle.tls.crypto.TlsKemDomain; import org.bouncycastle.tls.crypto.TlsNonceGenerator; import org.bouncycastle.tls.crypto.TlsSRP6Client; import org.bouncycastle.tls.crypto.TlsSRP6Server; @@ -233,9 +235,12 @@ public TlsCipher createCipher(TlsCryptoParameters cryptoParams, int encryptionAl // NOTE: Ignores macAlgorithm return createCipher_SM4_GCM(cryptoParams); + case EncryptionAlgorithm._28147_CNT_IMIT: case EncryptionAlgorithm.DES40_CBC: case EncryptionAlgorithm.DES_CBC: case EncryptionAlgorithm.IDEA_CBC: + case EncryptionAlgorithm.KUZNYECHIK_CTR_OMAC: + case EncryptionAlgorithm.MAGMA_CTR_OMAC: case EncryptionAlgorithm.RC2_CBC_40: case EncryptionAlgorithm.RC4_128: case EncryptionAlgorithm.RC4_40: @@ -404,6 +409,8 @@ String getHMACAlgorithmName(int cryptoHashAlgorithm) return "HmacSHA512"; case CryptoHashAlgorithm.sm3: return "HmacSM3"; + case CryptoHashAlgorithm.gostr3411_2012_256: + return "HmacGOST3411-2012-256"; default: throw new IllegalArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm); } @@ -536,7 +543,7 @@ public boolean hasCryptoSignatureAlgorithm(int cryptoSignatureAlgorithm) case CryptoSignatureAlgorithm.rsa_pss_pss_sha512: return true; - // TODO[draft-smyshlyaev-tls12-gost-suites-10] + // TODO[RFC 9189] case CryptoSignatureAlgorithm.gostr34102012_256: case CryptoSignatureAlgorithm.gostr34102012_512: @@ -558,6 +565,11 @@ public boolean hasECDHAgreement() return true; } + public boolean hasKemAgreement() + { + return true; + } + public boolean hasEncryptionAlgorithm(int encryptionAlgorithm) { final Integer key = Integers.valueOf(encryptionAlgorithm); @@ -713,11 +725,13 @@ public boolean hasSignatureAlgorithm(short signatureAlgorithm) case SignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512: return true; - // TODO[draft-smyshlyaev-tls12-gost-suites-10] + // TODO[RFC 9189] case SignatureAlgorithm.gostr34102012_256: case SignatureAlgorithm.gostr34102012_512: + // TODO[RFC 8998] // case SignatureAlgorithm.sm2: + default: return false; } @@ -822,6 +836,11 @@ public TlsECDomain createECDomain(TlsECConfig ecConfig) } } + public TlsKemDomain createKemDomain(TlsKemConfig kemConfig) + { + return new JceTlsMLKemDomain(this, kemConfig); + } + public TlsSecret hkdfInit(int cryptoHashAlgorithm) { return adoptLocalSecret(new byte[TlsCryptoUtils.getHashOutputSize(cryptoHashAlgorithm)]); @@ -840,7 +859,7 @@ public TlsSecret hkdfInit(int cryptoHashAlgorithm) protected TlsAEADCipherImpl createAEADCipher(String cipherName, String algorithm, int keySize, boolean isEncrypting) throws GeneralSecurityException { - return new JceAEADCipherImpl(helper, cipherName, algorithm, keySize, isEncrypting); + return new JceAEADCipherImpl(this, helper, cipherName, algorithm, keySize, isEncrypting); } /** @@ -853,10 +872,11 @@ protected TlsAEADCipherImpl createAEADCipher(String cipherName, String algorithm * @return a block cipher. * @throws GeneralSecurityException in case of failure. */ - protected TlsBlockCipherImpl createBlockCipher(String cipherName, String algorithm, int keySize, boolean isEncrypting) + protected TlsBlockCipherImpl createBlockCipher(String cipherName, String algorithm, int keySize, + boolean isEncrypting) throws GeneralSecurityException { - return new JceBlockCipherImpl(helper.createCipher(cipherName), algorithm, keySize, isEncrypting); + return new JceBlockCipherImpl(this, helper.createCipher(cipherName), algorithm, keySize, isEncrypting); } /** @@ -869,10 +889,11 @@ protected TlsBlockCipherImpl createBlockCipher(String cipherName, String algorit * @return a block cipher. * @throws GeneralSecurityException in case of failure. */ - protected TlsBlockCipherImpl createBlockCipherWithCBCImplicitIV(String cipherName, String algorithm, int keySize, boolean isEncrypting) + protected TlsBlockCipherImpl createBlockCipherWithCBCImplicitIV(String cipherName, String algorithm, int keySize, + boolean isEncrypting) throws GeneralSecurityException { - return new JceBlockCipherWithCBCImplicitIVImpl(helper.createCipher(cipherName), algorithm, isEncrypting); + return new JceBlockCipherWithCBCImplicitIVImpl(this, helper.createCipher(cipherName), algorithm, isEncrypting); } /** @@ -885,7 +906,7 @@ protected TlsBlockCipherImpl createBlockCipherWithCBCImplicitIV(String cipherNam protected TlsHash createHash(String digestName) throws GeneralSecurityException { - return new JcaTlsHash(helper.createDigest(digestName)); + return new JcaTlsHash(helper.createMessageDigest(digestName)); } /** @@ -1083,9 +1104,12 @@ protected Boolean isSupportedEncryptionAlgorithm(int encryptionAlgorithm) case EncryptionAlgorithm.SM4_GCM: return Boolean.valueOf(isUsableCipher("SM4/GCM/NoPadding", 128)); + case EncryptionAlgorithm._28147_CNT_IMIT: case EncryptionAlgorithm.DES_CBC: case EncryptionAlgorithm.DES40_CBC: case EncryptionAlgorithm.IDEA_CBC: + case EncryptionAlgorithm.KUZNYECHIK_CTR_OMAC: + case EncryptionAlgorithm.MAGMA_CTR_OMAC: case EncryptionAlgorithm.RC2_CBC_40: case EncryptionAlgorithm.RC4_128: case EncryptionAlgorithm.RC4_40: @@ -1195,8 +1219,8 @@ protected TlsBlockCipherImpl createCBCBlockCipherImpl(TlsCryptoParameters crypto private TlsCipher createChaCha20Poly1305(TlsCryptoParameters cryptoParams) throws IOException, GeneralSecurityException { - return new TlsAEADCipher(cryptoParams, new JceChaCha20Poly1305(helper, true), - new JceChaCha20Poly1305(helper, false), 32, 16, TlsAEADCipher.AEAD_CHACHA20_POLY1305); + return new TlsAEADCipher(cryptoParams, new JceChaCha20Poly1305(this, helper, true), + new JceChaCha20Poly1305(this, helper, false), 32, 16, TlsAEADCipher.AEAD_CHACHA20_POLY1305); } private TlsAEADCipher createCipher_AES_CCM(TlsCryptoParameters cryptoParams, int cipherKeySize, int macSize) @@ -1280,6 +1304,8 @@ String getDigestName(int cryptoHashAlgorithm) return "SHA-512"; case CryptoHashAlgorithm.sm3: return "SM3"; + case CryptoHashAlgorithm.gostr3411_2012_256: + return "GOST3411-2012-256"; default: throw new IllegalArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm); } diff --git a/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCryptoProvider.java b/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCryptoProvider.java index 81a1ff3378..e8de6fe40a 100644 --- a/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCryptoProvider.java +++ b/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCryptoProvider.java @@ -70,7 +70,7 @@ public TlsCrypto create(SecureRandom random) } else { - random = SecureRandom.getInstance("DEFAULT", helper.createDigest("SHA-512").getProvider()); + random = SecureRandom.getInstance("DEFAULT", helper.createMessageDigest("SHA-512").getProvider()); } } @@ -106,7 +106,7 @@ private static class NonceEntropySource NonceEntropySource(JcaJceHelper helper, SecureRandom random) throws GeneralSecurityException { - super(new NonceEntropySourceSpi(random, helper.createDigest("SHA-512")), random.getProvider()); + super(new NonceEntropySourceSpi(random, helper.createMessageDigest("SHA-512")), random.getProvider()); } private static class NonceEntropySourceSpi diff --git a/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JceAEADCipherImpl.java b/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JceAEADCipherImpl.java index ad41c910b1..e7000f5102 100644 --- a/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JceAEADCipherImpl.java +++ b/tls/src/main/jdk1.4/org/bouncycastle/tls/crypto/impl/jcajce/JceAEADCipherImpl.java @@ -5,6 +5,7 @@ import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.PrivilegedAction; +import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.SecretKey; @@ -14,6 +15,7 @@ import org.bouncycastle.jcajce.spec.AEADParameterSpec; import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.tls.crypto.impl.TlsAEADCipherImpl; +import org.bouncycastle.util.Arrays; /** * A basic wrapper for a JCE Cipher class to provide the needed AEAD cipher functionality for TLS. @@ -56,6 +58,7 @@ private static String getAlgParamsName(JcaJceHelper helper, String cipherName) } } + private final JcaTlsCrypto crypto; private final JcaJceHelper helper; private final int cipherMode; private final Cipher cipher; @@ -65,14 +68,16 @@ private static String getAlgParamsName(JcaJceHelper helper, String cipherName) private SecretKey key; - public JceAEADCipherImpl(JcaJceHelper helper, String cipherName, String algorithm, int keySize, boolean isEncrypting) + public JceAEADCipherImpl(JcaTlsCrypto crypto, JcaJceHelper helper, String cipherName, String algorithm, int keySize, + boolean isEncrypting) throws GeneralSecurityException { + this.crypto = crypto; this.helper = helper; this.cipher = helper.createCipher(cipherName); this.algorithm = algorithm; this.keySize = keySize; - this.cipherMode = (isEncrypting) ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; + this.cipherMode = isEncrypting ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; this.algorithmParamsName = getAlgParamsName(helper, cipherName); } @@ -86,8 +91,14 @@ public void setKey(byte[] key, int keyOff, int keyLen) this.key = new SecretKeySpec(key, keyOff, keyLen, algorithm); } - public void init(byte[] nonce, int macSize, byte[] additionalData) + private byte[] nonce; + private int macSize; + + public void init(byte[] nonce, int macSize) { + // NOTE: Shouldn't need a SecureRandom, but this is cheaper if the provider would auto-create one + SecureRandom random = crypto.getSecureRandom(); + try { // if (canDoAEAD && algorithmParamsName != null) @@ -107,7 +118,8 @@ public void init(byte[] nonce, int macSize, byte[] additionalData) // else // { // Otherwise fall back to the BC-specific AEADParameterSpec - cipher.init(cipherMode, key, new AEADParameterSpec(nonce, macSize * 8, additionalData)); + this.nonce = Arrays.clone(nonce); + this.macSize = macSize; // } } catch (Exception e) @@ -121,9 +133,25 @@ public int getOutputSize(int inputLength) return cipher.getOutputSize(inputLength); } - public int doFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) + public int doFinal(byte[] additionalData, byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) throws IOException { + try + { + if (!Arrays.isNullOrEmpty(additionalData)) + { + cipher.init(cipherMode, key, new AEADParameterSpec(nonce, macSize * 8, additionalData)); + } + else + { + cipher.init(cipherMode, key, new AEADParameterSpec(nonce, macSize * 8, null)); + } + } + catch (Exception e) + { + throw new IOException(e.toString()); + } + /* * NOTE: Some providers don't allow cipher update methods with AEAD decryption, * since they may return partial data that has not yet been authenticated. So we diff --git a/tls/src/main/jdk1.5/org/bouncycastle/jsse/provider/SSLParametersUtil.java b/tls/src/main/jdk1.5/org/bouncycastle/jsse/provider/SSLParametersUtil.java index 702239291d..237ca8cf24 100644 --- a/tls/src/main/jdk1.5/org/bouncycastle/jsse/provider/SSLParametersUtil.java +++ b/tls/src/main/jdk1.5/org/bouncycastle/jsse/provider/SSLParametersUtil.java @@ -17,16 +17,22 @@ abstract class SSLParametersUtil private static final Method setAlgorithmConstraints; private static final Method getApplicationProtocols; private static final Method setApplicationProtocols; + private static final Method getEnableRetransmissions; + private static final Method setEnableRetransmissions; private static final Method getEndpointIdentificationAlgorithm; private static final Method setEndpointIdentificationAlgorithm; + private static final Method getMaximumPacketSize; + private static final Method setMaximumPacketSize; + private static final Method getNamedGroups; + private static final Method setNamedGroups; private static final Method getServerNames; private static final Method setServerNames; + private static final Method getSignatureSchemes; + private static final Method setSignatureSchemes; private static final Method getSNIMatchers; private static final Method setSNIMatchers; private static final Method getUseCipherSuitesOrder; private static final Method setUseCipherSuitesOrder; - private static final Method getMaximumPacketSize; - private static final Method setMaximumPacketSize; static { @@ -36,16 +42,22 @@ abstract class SSLParametersUtil setAlgorithmConstraints = ReflectionUtil.findMethod(methods, "setAlgorithmConstraints"); getApplicationProtocols = ReflectionUtil.findMethod(methods, "getApplicationProtocols"); setApplicationProtocols = ReflectionUtil.findMethod(methods, "setApplicationProtocols"); + getEnableRetransmissions = ReflectionUtil.findMethod(methods, "getEnableRetransmissions"); + setEnableRetransmissions = ReflectionUtil.findMethod(methods, "setEnableRetransmissions"); getEndpointIdentificationAlgorithm = ReflectionUtil.findMethod(methods, "getEndpointIdentificationAlgorithm"); setEndpointIdentificationAlgorithm = ReflectionUtil.findMethod(methods, "setEndpointIdentificationAlgorithm"); + getMaximumPacketSize = ReflectionUtil.findMethod(methods, "getMaximumPacketSize"); + setMaximumPacketSize = ReflectionUtil.findMethod(methods, "setMaximumPacketSize"); + getNamedGroups = ReflectionUtil.findMethod(methods, "getNamedGroups"); + setNamedGroups = ReflectionUtil.findMethod(methods, "setNamedGroups"); getServerNames = ReflectionUtil.findMethod(methods, "getServerNames"); setServerNames = ReflectionUtil.findMethod(methods, "setServerNames"); + getSignatureSchemes = ReflectionUtil.findMethod(methods, "getSignatureSchemes"); + setSignatureSchemes = ReflectionUtil.findMethod(methods, "setSignatureSchemes"); getSNIMatchers = ReflectionUtil.findMethod(methods, "getSNIMatchers"); setSNIMatchers = ReflectionUtil.findMethod(methods, "setSNIMatchers"); getUseCipherSuitesOrder = ReflectionUtil.findMethod(methods, "getUseCipherSuitesOrder"); setUseCipherSuitesOrder = ReflectionUtil.findMethod(methods, "setUseCipherSuitesOrder"); - getMaximumPacketSize = ReflectionUtil.findMethod(methods, "getMaximumPacketSize"); - setMaximumPacketSize = ReflectionUtil.findMethod(methods, "setMaximumPacketSize"); } static BCSSLParameters getParameters(ProvSSLParameters prov) @@ -62,13 +74,17 @@ static BCSSLParameters getParameters(ProvSSLParameters prov) ssl.setWantClientAuth(prov.getWantClientAuth()); } - ssl.setAlgorithmConstraints(prov.getAlgorithmConstraints()); ssl.setEndpointIdentificationAlgorithm(prov.getEndpointIdentificationAlgorithm()); - ssl.setUseCipherSuitesOrder(prov.getUseCipherSuitesOrder()); + ssl.setAlgorithmConstraints(prov.getAlgorithmConstraints()); ssl.setServerNames(prov.getServerNames()); ssl.setSNIMatchers(prov.getSNIMatchers()); + ssl.setUseCipherSuitesOrder(prov.getUseCipherSuitesOrder()); ssl.setApplicationProtocols(prov.getApplicationProtocols()); + ssl.setEnableRetransmissions(prov.getEnableRetransmissions()); ssl.setMaximumPacketSize(prov.getMaximumPacketSize()); + ssl.setSignatureSchemes(prov.getSignatureSchemes()); + ssl.setSignatureSchemesCert(prov.getSignatureSchemesCert()); + ssl.setNamedGroups(prov.getNamedGroups()); return ssl; } @@ -100,12 +116,7 @@ static SSLParameters getSSLParameters(ProvSSLParameters prov) set(ssl, setEndpointIdentificationAlgorithm, prov.getEndpointIdentificationAlgorithm()); } - // From JDK 1.8 - - if (null != setUseCipherSuitesOrder) - { - set(ssl, setUseCipherSuitesOrder, prov.getUseCipherSuitesOrder()); - } + // From JDK 8 if (null != setServerNames) { @@ -125,6 +136,11 @@ static SSLParameters getSSLParameters(ProvSSLParameters prov) } } + if (null != setUseCipherSuitesOrder) + { + set(ssl, setUseCipherSuitesOrder, prov.getUseCipherSuitesOrder()); + } + // From JDK 9 originally, then added to 8u251 if (null != setApplicationProtocols) @@ -138,11 +154,37 @@ static SSLParameters getSSLParameters(ProvSSLParameters prov) // From JDK 9 + if (null != setEnableRetransmissions) + { + set(ssl, setEnableRetransmissions, prov.getEnableRetransmissions()); + } + if (null != setMaximumPacketSize) { set(ssl, setMaximumPacketSize, prov.getMaximumPacketSize()); } + // From JDK 19 + + if (null != setSignatureSchemes) + { + set(ssl, setSignatureSchemes, prov.getSignatureSchemes()); + } + + // From JDK 20 + + if (null != setNamedGroups) + { + set(ssl, setNamedGroups, prov.getNamedGroups()); + } + + // Unsupported as of JDK 21 + +// if (null != setSignatureSchemesCert) +// { +// set(ssl, setSignatureSchemesCert, prov.getSignatureSchemesCert()); +// } + return ssl; } @@ -162,15 +204,6 @@ static BCSSLParameters importSSLParameters(SSLParameters ssl) // From JDK 1.7 - if (null != getAlgorithmConstraints) - { - Object constraints = get(ssl, getAlgorithmConstraints); - if (null != constraints) - { - bc.setAlgorithmConstraints(JsseUtils_7.importAlgorithmConstraintsDynamic(constraints)); - } - } - if (null != getEndpointIdentificationAlgorithm) { String endpointIdentificationAlgorithm = (String)get(ssl, getEndpointIdentificationAlgorithm); @@ -180,13 +213,17 @@ static BCSSLParameters importSSLParameters(SSLParameters ssl) } } - // From JDK 1.8 - - if (null != getUseCipherSuitesOrder) + if (null != getAlgorithmConstraints) { - bc.setUseCipherSuitesOrder((Boolean)get(ssl, getUseCipherSuitesOrder)); + Object constraints = get(ssl, getAlgorithmConstraints); + if (null != constraints) + { + bc.setAlgorithmConstraints(JsseUtils_7.importAlgorithmConstraintsDynamic(constraints)); + } } + // From JDK 8 + if (null != getServerNames) { Object serverNames = get(ssl, getServerNames); @@ -205,6 +242,11 @@ static BCSSLParameters importSSLParameters(SSLParameters ssl) } } + if (null != getUseCipherSuitesOrder) + { + bc.setUseCipherSuitesOrder((Boolean)get(ssl, getUseCipherSuitesOrder)); + } + // From JDK 9 originally, then added to 8u251 if (null != getApplicationProtocols) @@ -216,13 +258,39 @@ static BCSSLParameters importSSLParameters(SSLParameters ssl) } } - // From JDK 1.9 + // From JDK 9 + + if (null != getEnableRetransmissions) + { + bc.setEnableRetransmissions((Boolean)get(ssl, getEnableRetransmissions)); + } if (null != getMaximumPacketSize) { bc.setMaximumPacketSize((Integer)get(ssl, getMaximumPacketSize)); } + // From JDK 19 + + if (null != getSignatureSchemes) + { + bc.setSignatureSchemes((String[])get(ssl, getSignatureSchemes)); + } + + // From JDK 20 + + if (null != getNamedGroups) + { + bc.setNamedGroups((String[])get(ssl, getNamedGroups)); + } + + // Unsupported as of JDK 21 + +// if (null != getSignatureSchemesCert) +// { +// bc.setSignatureSchemesCert((String[])get(ssl, getSignatureSchemesCert)); +// } + return bc; } @@ -250,19 +318,17 @@ static void setParameters(ProvSSLParameters prov, BCSSLParameters ssl) prov.setWantClientAuth(ssl.getWantClientAuth()); } - BCAlgorithmConstraints algorithmConstraints = ssl.getAlgorithmConstraints(); - if (null != algorithmConstraints) - { - prov.setAlgorithmConstraints(algorithmConstraints); - } - String endpointIdentificationAlgorithm = ssl.getEndpointIdentificationAlgorithm(); if (null != endpointIdentificationAlgorithm) { prov.setEndpointIdentificationAlgorithm(endpointIdentificationAlgorithm); } - prov.setUseCipherSuitesOrder(ssl.getUseCipherSuitesOrder()); + BCAlgorithmConstraints algorithmConstraints = ssl.getAlgorithmConstraints(); + if (null != algorithmConstraints) + { + prov.setAlgorithmConstraints(algorithmConstraints); + } List serverNames = ssl.getServerNames(); if (null != serverNames) @@ -276,13 +342,23 @@ static void setParameters(ProvSSLParameters prov, BCSSLParameters ssl) prov.setSNIMatchers(sniMatchers); } + prov.setUseCipherSuitesOrder(ssl.getUseCipherSuitesOrder()); + String[] applicationProtocols = ssl.getApplicationProtocols(); if (null != applicationProtocols) { prov.setApplicationProtocols(applicationProtocols); } + prov.setEnableRetransmissions(ssl.getEnableRetransmissions()); + prov.setMaximumPacketSize(ssl.getMaximumPacketSize()); + + prov.setSignatureSchemes(ssl.getSignatureSchemes()); + + prov.setNamedGroups(ssl.getNamedGroups()); + + prov.setSignatureSchemesCert(ssl.getSignatureSchemesCert()); } static void setSSLParameters(ProvSSLParameters prov, SSLParameters ssl) @@ -311,15 +387,6 @@ static void setSSLParameters(ProvSSLParameters prov, SSLParameters ssl) // From JDK 1.7 - if (null != getAlgorithmConstraints) - { - Object constraints = get(ssl, getAlgorithmConstraints); - if (null != constraints) - { - prov.setAlgorithmConstraints(JsseUtils_7.importAlgorithmConstraintsDynamic(constraints)); - } - } - if (null != getEndpointIdentificationAlgorithm) { String endpointIdentificationAlgorithm = (String)get(ssl, getEndpointIdentificationAlgorithm); @@ -329,13 +396,17 @@ static void setSSLParameters(ProvSSLParameters prov, SSLParameters ssl) } } - // From JDK 1.8 - - if (null != getUseCipherSuitesOrder) + if (null != getAlgorithmConstraints) { - prov.setUseCipherSuitesOrder((Boolean)get(ssl, getUseCipherSuitesOrder)); + Object constraints = get(ssl, getAlgorithmConstraints); + if (null != constraints) + { + prov.setAlgorithmConstraints(JsseUtils_7.importAlgorithmConstraintsDynamic(constraints)); + } } + // From JDK 8 + if (null != getServerNames) { Object serverNames = get(ssl, getServerNames); @@ -354,6 +425,11 @@ static void setSSLParameters(ProvSSLParameters prov, SSLParameters ssl) } } + if (null != getUseCipherSuitesOrder) + { + prov.setUseCipherSuitesOrder((Boolean)get(ssl, getUseCipherSuitesOrder)); + } + // From JDK 9 originally, then added to 8u251 if (null != getApplicationProtocols) @@ -367,10 +443,36 @@ static void setSSLParameters(ProvSSLParameters prov, SSLParameters ssl) // From JDK 9 + if (null != getEnableRetransmissions) + { + prov.setEnableRetransmissions((Boolean)get(ssl, getEnableRetransmissions)); + } + if (null != getMaximumPacketSize) { prov.setMaximumPacketSize((Integer)get(ssl, getMaximumPacketSize)); } + + // From JDK 19 + + if (null != getSignatureSchemes) + { + prov.setSignatureSchemes((String[])get(ssl, getSignatureSchemes)); + } + + // From JDK 20 + + if (null != getNamedGroups) + { + prov.setNamedGroups((String[])get(ssl, getNamedGroups)); + } + + // Unsupported as of JDK 21 + +// if (null != getSignatureSchemesCert) +// { +// prov.setSignatureSchemesCert((String[])get(ssl, getSignatureSchemesCert)); +// } } private static Object get(Object obj, Method method) diff --git a/tls/src/main/jdk1.9/org/bouncycastle/jsse/provider/ProvSSLEngine_9.java b/tls/src/main/jdk1.9/org/bouncycastle/jsse/provider/ProvSSLEngine_9.java index 44ecb0252a..5c22c6db34 100644 --- a/tls/src/main/jdk1.9/org/bouncycastle/jsse/provider/ProvSSLEngine_9.java +++ b/tls/src/main/jdk1.9/org/bouncycastle/jsse/provider/ProvSSLEngine_9.java @@ -8,8 +8,8 @@ protected ProvSSLEngine_9(ContextData contextData) super(contextData); } - protected ProvSSLEngine_9(ContextData contextData, String host, int port) + protected ProvSSLEngine_9(ContextData contextData, String peerHost, int peerPort) { - super(contextData, host, port); + super(contextData, peerHost, peerPort); } } diff --git a/tls/src/main/jdk1.9/org/bouncycastle/jsse/provider/SSLParametersUtil.java b/tls/src/main/jdk1.9/org/bouncycastle/jsse/provider/SSLParametersUtil.java index 9dab7ea420..02ae707506 100644 --- a/tls/src/main/jdk1.9/org/bouncycastle/jsse/provider/SSLParametersUtil.java +++ b/tls/src/main/jdk1.9/org/bouncycastle/jsse/provider/SSLParametersUtil.java @@ -1,5 +1,6 @@ package org.bouncycastle.jsse.provider; +import java.lang.reflect.Method; import java.security.AlgorithmConstraints; import java.util.Collection; import java.util.List; @@ -15,6 +16,21 @@ abstract class SSLParametersUtil { + private static final Method getNamedGroups; + private static final Method setNamedGroups; + private static final Method getSignatureSchemes; + private static final Method setSignatureSchemes; + + static + { + Method[] methods = ReflectionUtil.getMethods("javax.net.ssl.SSLParameters"); + + getNamedGroups = ReflectionUtil.findMethod(methods, "getNamedGroups"); + setNamedGroups = ReflectionUtil.findMethod(methods, "setNamedGroups"); + getSignatureSchemes = ReflectionUtil.findMethod(methods, "getSignatureSchemes"); + setSignatureSchemes = ReflectionUtil.findMethod(methods, "setSignatureSchemes"); + } + static BCSSLParameters getParameters(ProvSSLParameters prov) { BCSSLParameters ssl = new BCSSLParameters(prov.getCipherSuites(), prov.getProtocols()); @@ -29,13 +45,17 @@ static BCSSLParameters getParameters(ProvSSLParameters prov) ssl.setWantClientAuth(prov.getWantClientAuth()); } - ssl.setAlgorithmConstraints(prov.getAlgorithmConstraints()); ssl.setEndpointIdentificationAlgorithm(prov.getEndpointIdentificationAlgorithm()); - ssl.setUseCipherSuitesOrder(prov.getUseCipherSuitesOrder()); + ssl.setAlgorithmConstraints(prov.getAlgorithmConstraints()); ssl.setServerNames(prov.getServerNames()); ssl.setSNIMatchers(prov.getSNIMatchers()); + ssl.setUseCipherSuitesOrder(prov.getUseCipherSuitesOrder()); ssl.setApplicationProtocols(prov.getApplicationProtocols()); + ssl.setEnableRetransmissions(prov.getEnableRetransmissions()); ssl.setMaximumPacketSize(prov.getMaximumPacketSize()); + ssl.setSignatureSchemes(prov.getSignatureSchemes()); + ssl.setSignatureSchemesCert(prov.getSignatureSchemesCert()); + ssl.setNamedGroups(prov.getNamedGroups()); return ssl; } @@ -56,13 +76,11 @@ static SSLParameters getSSLParameters(ProvSSLParameters prov) // From JDK 1.7 - ssl.setAlgorithmConstraints(JsseUtils_7.exportAlgorithmConstraints(prov.getAlgorithmConstraints())); - ssl.setEndpointIdentificationAlgorithm(prov.getEndpointIdentificationAlgorithm()); - // From JDK 1.8 + ssl.setAlgorithmConstraints(JsseUtils_7.exportAlgorithmConstraints(prov.getAlgorithmConstraints())); - ssl.setUseCipherSuitesOrder(prov.getUseCipherSuitesOrder()); + // From JDK 8 { List serverNames = prov.getServerNames(); @@ -80,6 +98,8 @@ static SSLParameters getSSLParameters(ProvSSLParameters prov) } } + ssl.setUseCipherSuitesOrder(prov.getUseCipherSuitesOrder()); + // From JDK 9 originally, then added to 8u251 { @@ -92,8 +112,31 @@ static SSLParameters getSSLParameters(ProvSSLParameters prov) // From JDK 9 + ssl.setEnableRetransmissions(prov.getEnableRetransmissions()); + ssl.setMaximumPacketSize(prov.getMaximumPacketSize()); + // From JDK 19 + + if (null != setSignatureSchemes) + { + set(ssl, setSignatureSchemes, prov.getSignatureSchemes()); + } + + // From JDK 20 + + if (null != setNamedGroups) + { + set(ssl, setNamedGroups, prov.getNamedGroups()); + } + + // Unsupported as of JDK 21 + +// if (null != setSignatureSchemesCert) +// { +// set(ssl, setSignatureSchemesCert, prov.getSignatureSchemesCert()); +// } + return ssl; } @@ -114,24 +157,22 @@ static BCSSLParameters importSSLParameters(SSLParameters ssl) // From JDK 1.7 { - AlgorithmConstraints constraints = ssl.getAlgorithmConstraints(); - if (null != constraints) + String endpointIdentificationAlgorithm = ssl.getEndpointIdentificationAlgorithm(); + if (null != endpointIdentificationAlgorithm) { - bc.setAlgorithmConstraints(JsseUtils_7.importAlgorithmConstraints(constraints)); + bc.setEndpointIdentificationAlgorithm(endpointIdentificationAlgorithm); } } { - String endpointIdentificationAlgorithm = ssl.getEndpointIdentificationAlgorithm(); - if (null != endpointIdentificationAlgorithm) + AlgorithmConstraints constraints = ssl.getAlgorithmConstraints(); + if (null != constraints) { - bc.setEndpointIdentificationAlgorithm(endpointIdentificationAlgorithm); + bc.setAlgorithmConstraints(JsseUtils_7.importAlgorithmConstraints(constraints)); } } - // From JDK 1.8 - - bc.setUseCipherSuitesOrder(ssl.getUseCipherSuitesOrder()); + // From JDK 8 { List serverNames = ssl.getServerNames(); @@ -149,6 +190,8 @@ static BCSSLParameters importSSLParameters(SSLParameters ssl) } } + bc.setUseCipherSuitesOrder(ssl.getUseCipherSuitesOrder()); + // From JDK 9 originally, then added to 8u251 { @@ -161,8 +204,31 @@ static BCSSLParameters importSSLParameters(SSLParameters ssl) // From JDK 9 + bc.setEnableRetransmissions(ssl.getEnableRetransmissions()); + bc.setMaximumPacketSize(ssl.getMaximumPacketSize()); + // From JDK 19 + + if (null != getSignatureSchemes) + { + bc.setSignatureSchemes((String[])get(ssl, getSignatureSchemes)); + } + + // From JDK 20 + + if (null != getNamedGroups) + { + bc.setNamedGroups((String[])get(ssl, getNamedGroups)); + } + + // Unsupported as of JDK 21 + +// if (null != getSignatureSchemesCert) +// { +// bc.setSignatureSchemesCert((String[])get(ssl, getSignatureSchemesCert)); +// } + return bc; } @@ -190,19 +256,17 @@ static void setParameters(ProvSSLParameters prov, BCSSLParameters ssl) prov.setWantClientAuth(ssl.getWantClientAuth()); } - BCAlgorithmConstraints algorithmConstraints = ssl.getAlgorithmConstraints(); - if (null != algorithmConstraints) - { - prov.setAlgorithmConstraints(algorithmConstraints); - } - String endpointIdentificationAlgorithm = ssl.getEndpointIdentificationAlgorithm(); if (null != endpointIdentificationAlgorithm) { prov.setEndpointIdentificationAlgorithm(endpointIdentificationAlgorithm); } - prov.setUseCipherSuitesOrder(ssl.getUseCipherSuitesOrder()); + BCAlgorithmConstraints algorithmConstraints = ssl.getAlgorithmConstraints(); + if (null != algorithmConstraints) + { + prov.setAlgorithmConstraints(algorithmConstraints); + } List serverNames = ssl.getServerNames(); if (null != serverNames) @@ -216,13 +280,23 @@ static void setParameters(ProvSSLParameters prov, BCSSLParameters ssl) prov.setSNIMatchers(sniMatchers); } + prov.setUseCipherSuitesOrder(ssl.getUseCipherSuitesOrder()); + String[] applicationProtocols = ssl.getApplicationProtocols(); if (null != applicationProtocols) { prov.setApplicationProtocols(applicationProtocols); } + prov.setEnableRetransmissions(ssl.getEnableRetransmissions()); + prov.setMaximumPacketSize(ssl.getMaximumPacketSize()); + + prov.setSignatureSchemes(ssl.getSignatureSchemes()); + + prov.setNamedGroups(ssl.getNamedGroups()); + + prov.setSignatureSchemesCert(ssl.getSignatureSchemesCert()); } static void setSSLParameters(ProvSSLParameters prov, SSLParameters ssl) @@ -252,24 +326,22 @@ static void setSSLParameters(ProvSSLParameters prov, SSLParameters ssl) // From JDK 1.7 { - AlgorithmConstraints constraints = ssl.getAlgorithmConstraints(); - if (null != constraints) + String endpointIdentificationAlgorithm = ssl.getEndpointIdentificationAlgorithm(); + if (null != endpointIdentificationAlgorithm) { - prov.setAlgorithmConstraints(JsseUtils_7.importAlgorithmConstraints(constraints)); + prov.setEndpointIdentificationAlgorithm(endpointIdentificationAlgorithm); } } { - String endpointIdentificationAlgorithm = ssl.getEndpointIdentificationAlgorithm(); - if (null != endpointIdentificationAlgorithm) + AlgorithmConstraints constraints = ssl.getAlgorithmConstraints(); + if (null != constraints) { - prov.setEndpointIdentificationAlgorithm(endpointIdentificationAlgorithm); + prov.setAlgorithmConstraints(JsseUtils_7.importAlgorithmConstraints(constraints)); } } - // From JDK 1.8 - - prov.setUseCipherSuitesOrder(ssl.getUseCipherSuitesOrder()); + // From JDK 8 { List serverNames = ssl.getServerNames(); @@ -287,6 +359,8 @@ static void setSSLParameters(ProvSSLParameters prov, SSLParameters ssl) } } + prov.setUseCipherSuitesOrder(ssl.getUseCipherSuitesOrder()); + // From JDK 9 originally, then added to 8u251 { @@ -299,6 +373,39 @@ static void setSSLParameters(ProvSSLParameters prov, SSLParameters ssl) // From JDK 9 + prov.setEnableRetransmissions(ssl.getEnableRetransmissions()); + prov.setMaximumPacketSize(ssl.getMaximumPacketSize()); + + // From JDK 19 + + if (null != getSignatureSchemes) + { + prov.setSignatureSchemes((String[])get(ssl, getSignatureSchemes)); + } + + // From JDK 20 + + if (null != getNamedGroups) + { + prov.setNamedGroups((String[])get(ssl, getNamedGroups)); + } + + // Unsupported as of JDK 21 + +// if (null != getSignatureSchemesCert) +// { +// prov.setSignatureSchemesCert((String[])get(ssl, getSignatureSchemesCert)); +// } + } + + private static Object get(Object obj, Method method) + { + return ReflectionUtil.invokeGetter(obj, method); + } + + private static void set(Object obj, Method method, Object arg) + { + ReflectionUtil.invokeSetter(obj, method, arg); } } diff --git a/tls/src/main/jdk1.9/org/bouncycastle/tls/crypto/impl/jcajce/GCMUtil.java b/tls/src/main/jdk1.9/org/bouncycastle/tls/crypto/impl/jcajce/GCMUtil.java new file mode 100644 index 0000000000..fc551a5d16 --- /dev/null +++ b/tls/src/main/jdk1.9/org/bouncycastle/tls/crypto/impl/jcajce/GCMUtil.java @@ -0,0 +1,19 @@ +package org.bouncycastle.tls.crypto.impl.jcajce; + +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.spec.GCMParameterSpec; + +class GCMUtil +{ + static AlgorithmParameterSpec createGCMParameterSpec(final int tLen, final byte[] src) + throws Exception + { + return new GCMParameterSpec(tLen, src); + } + + static boolean isGCMParameterSpecAvailable() + { + return true; + } +} diff --git a/tls/src/main/jdk1.9/org/bouncycastle/tls/crypto/impl/jcajce/GcmSpecUtil.java b/tls/src/main/jdk1.9/org/bouncycastle/tls/crypto/impl/jcajce/GcmSpecUtil.java deleted file mode 100644 index cce2153c50..0000000000 --- a/tls/src/main/jdk1.9/org/bouncycastle/tls/crypto/impl/jcajce/GcmSpecUtil.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.bouncycastle.tls.crypto.impl.jcajce; - -import java.lang.reflect.Constructor; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.spec.AlgorithmParameterSpec; -import java.security.spec.InvalidParameterSpecException; - -import javax.crypto.spec.GCMParameterSpec; - -import org.bouncycastle.util.Integers; - -class GcmSpecUtil -{ - static boolean gcmSpecExists() - { - return true; - } - - static AlgorithmParameterSpec createGcmSpec(byte[] nonce, int macLen) - throws InvalidParameterSpecException - { - return new GCMParameterSpec(macLen * 8, nonce); - } -} diff --git a/tls/src/test/java/org/bouncycastle/jsse/provider/test/BCJSSEClientTest.java b/tls/src/test/java/org/bouncycastle/jsse/provider/test/BCJSSEClientTest.java index 80603db792..e799f74ef9 100644 --- a/tls/src/test/java/org/bouncycastle/jsse/provider/test/BCJSSEClientTest.java +++ b/tls/src/test/java/org/bouncycastle/jsse/provider/test/BCJSSEClientTest.java @@ -32,6 +32,7 @@ import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jsse.BCExtendedSSLSession; import org.bouncycastle.jsse.BCSSLSocket; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemReader; @@ -260,7 +261,7 @@ public void handshakeCompleted(HandshakeCompletedEvent event) private static void writeUTF8Line(OutputStream output, String line) throws IOException { - output.write((line + "\r\n").getBytes("UTF-8")); + output.write(Strings.toUTF8ByteArray(line + "\r\n")); System.out.println(">>> " + line); } diff --git a/tls/src/test/java/org/bouncycastle/jsse/provider/test/BasicClientAuthTlsTest.java b/tls/src/test/java/org/bouncycastle/jsse/provider/test/BasicClientAuthTlsTest.java index 46a92abf94..017138757f 100644 --- a/tls/src/test/java/org/bouncycastle/jsse/provider/test/BasicClientAuthTlsTest.java +++ b/tls/src/test/java/org/bouncycastle/jsse/provider/test/BasicClientAuthTlsTest.java @@ -24,8 +24,6 @@ import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509ExtendedKeyManager; -import org.junit.Assert; - import junit.framework.TestCase; public class BasicClientAuthTlsTest @@ -86,7 +84,7 @@ public Exception call() SSLSession session = cSock.getSession(); assertNotNull(session); - Assert.assertNotEquals("SSL_NULL_WITH_NULL_NULL", session.getCipherSuite()); + assertFalse("SSL_NULL_WITH_NULL_NULL".equals(session.getCipherSuite())); assertEquals("CN=Test CA Certificate", session.getLocalPrincipal().getName()); assertEquals("CN=Test CA Certificate", session.getPeerPrincipal().getName()); @@ -232,7 +230,7 @@ public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket so SSLSession session = cSock.getSession(); assertNotNull(session); - Assert.assertNotEquals("SSL_NULL_WITH_NULL_NULL", session.getCipherSuite()); + assertFalse("SSL_NULL_WITH_NULL_NULL".equals(session.getCipherSuite())); assertEquals("CN=Test CA Certificate", session.getLocalPrincipal().getName()); assertEquals("CN=Test CA Certificate", session.getPeerPrincipal().getName()); @@ -289,7 +287,7 @@ public Exception call() SSLSession session = cSock.getSession(); assertNotNull(session); - Assert.assertNotEquals("SSL_NULL_WITH_NULL_NULL", session.getCipherSuite()); + assertFalse("SSL_NULL_WITH_NULL_NULL".equals(session.getCipherSuite())); assertNull(session.getLocalPrincipal()); assertEquals("CN=Test CA Certificate", session.getPeerPrincipal().getName()); @@ -374,7 +372,7 @@ public Exception call() SSLSession session = sslSock.getSession(); assertNotNull(session); - Assert.assertNotEquals("SSL_NULL_WITH_NULL_NULL", session.getCipherSuite()); + assertFalse("SSL_NULL_WITH_NULL_NULL".equals(session.getCipherSuite())); assertEquals("CN=Test CA Certificate", session.getLocalPrincipal().getName()); if (needClientAuth) @@ -386,7 +384,7 @@ public Exception call() try { session.getPeerPrincipal(); - Assert.fail(); + fail(); } catch (SSLPeerUnverifiedException e) { diff --git a/tls/src/test/java/org/bouncycastle/jsse/provider/test/BasicTlsTest.java b/tls/src/test/java/org/bouncycastle/jsse/provider/test/BasicTlsTest.java index de1cbcaee2..03f5bf58a7 100644 --- a/tls/src/test/java/org/bouncycastle/jsse/provider/test/BasicTlsTest.java +++ b/tls/src/test/java/org/bouncycastle/jsse/provider/test/BasicTlsTest.java @@ -24,6 +24,7 @@ public class BasicTlsTest protected void setUp() { ProviderUtils.setupLowPriority(false); +// System.setProperty("jdk.tls.namedGroups", "kyber768"); } private static final String HOST = "localhost"; diff --git a/tls/src/test/java/org/bouncycastle/jsse/provider/test/CipherSuitesEngineTestCase.java b/tls/src/test/java/org/bouncycastle/jsse/provider/test/CipherSuitesEngineTestCase.java index cce6f06e85..528d8d8141 100644 --- a/tls/src/test/java/org/bouncycastle/jsse/provider/test/CipherSuitesEngineTestCase.java +++ b/tls/src/test/java/org/bouncycastle/jsse/provider/test/CipherSuitesEngineTestCase.java @@ -13,6 +13,8 @@ import javax.net.ssl.TrustManagerFactory; import junit.framework.TestCase; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; public class CipherSuitesEngineTestCase extends TestCase { @@ -98,8 +100,8 @@ private void runTestConnection() throws Throwable ByteBuffer clientToServer = ByteBuffer.allocate(clientNetBufSize); ByteBuffer serverToClient = ByteBuffer.allocate(serverNetBufSize); - ByteBuffer clientOut = ByteBuffer.wrap("Dear Prudence, won't you come out to play?".getBytes("UTF-8")); - ByteBuffer serverOut = ByteBuffer.wrap("Impudence! I won't come out to today.".getBytes("UTF-8")); + ByteBuffer clientOut = ByteBuffer.wrap(Strings.toUTF8ByteArray("Dear Prudence, won't you come out to play?")); + ByteBuffer serverOut = ByteBuffer.wrap(Strings.toUTF8ByteArray("Impudence! I won't come out to today.")); SSLEngineResult clientResult; SSLEngineResult serverResult; @@ -113,8 +115,8 @@ private void runTestConnection() throws Throwable serverResult = serverEngine.wrap(serverOut, serverToClient); runDelegatedTasks(serverEngine, serverResult); - clientToServer.flip(); - serverToClient.flip(); + ((java.nio.Buffer)clientToServer).flip(); + ((java.nio.Buffer)serverToClient).flip(); clientResult = clientEngine.unwrap(serverToClient, clientIn); runDelegatedTasks(clientEngine, clientResult); @@ -136,19 +138,29 @@ private void runTestConnection() throws Throwable dataDone = true; } } + + byte[] clientTlsUnique = TestUtils.getChannelBinding(clientEngine, "tls-unique"); + byte[] serverTlsUnique = TestUtils.getChannelBinding(serverEngine, "tls-unique"); + + if (TestUtils.isTlsUniqueProtocol(config.protocol)) + { + TestCase.assertNotNull(clientTlsUnique); + TestCase.assertNotNull(serverTlsUnique); + } + TestCase.assertTrue(Arrays.areEqual(clientTlsUnique, serverTlsUnique)); } private static void checkData(ByteBuffer a, ByteBuffer b) throws Exception { - a.flip(); - b.flip(); + ((java.nio.Buffer)a).flip(); + ((java.nio.Buffer)b).flip(); assertEquals(a, b); - a.position(a.limit()); - b.position(b.limit()); - a.limit(a.capacity()); - b.limit(b.capacity()); + ((java.nio.Buffer)a).position(a.limit()); + ((java.nio.Buffer)b).position(b.limit()); + ((java.nio.Buffer)a).limit(a.capacity()); + ((java.nio.Buffer)b).limit(b.capacity()); } private SSLContext createSSLContextClient() throws GeneralSecurityException diff --git a/tls/src/test/java/org/bouncycastle/jsse/provider/test/CipherSuitesTestCase.java b/tls/src/test/java/org/bouncycastle/jsse/provider/test/CipherSuitesTestCase.java index 2302a2e373..61d1badd58 100644 --- a/tls/src/test/java/org/bouncycastle/jsse/provider/test/CipherSuitesTestCase.java +++ b/tls/src/test/java/org/bouncycastle/jsse/provider/test/CipherSuitesTestCase.java @@ -79,17 +79,17 @@ protected void runTest() throws Throwable private void runTestConnection(int port, SSLContext clientContext, SSLContext serverContext) throws Throwable { - SimpleServer server = new SimpleServer(serverContext, port, config); SimpleClient client = new SimpleClient(clientContext, port, config); + SimpleServer server = new SimpleServer(serverContext, port, config); TestProtocolUtil.runClientAndServer(server, client); - if (!"TLSv1.3".equals(config.protocol)) + if (TestUtils.isTlsUniqueProtocol(config.protocol)) { - TestCase.assertNotNull(server.tlsUnique); TestCase.assertNotNull(client.tlsUnique); + TestCase.assertNotNull(server.tlsUnique); } - TestCase.assertTrue(Arrays.areEqual(server.tlsUnique, client.tlsUnique)); + TestCase.assertTrue(Arrays.areEqual(client.tlsUnique, server.tlsUnique)); } private SSLContext createClientContext() throws Exception @@ -122,7 +122,7 @@ private SSLContext createServerContext() throws Exception } private static final String HOST = "localhost"; - private static final AtomicInteger PORT_NO = new AtomicInteger(9100); + private static final AtomicInteger PORT_NO = new AtomicInteger(19000); static class SimpleClient implements TestProtocolUtil.BlockingCallable diff --git a/tls/src/test/java/org/bouncycastle/jsse/provider/test/SSLUtils.java b/tls/src/test/java/org/bouncycastle/jsse/provider/test/SSLUtils.java index 01babfe5f6..f64d9ba28e 100644 --- a/tls/src/test/java/org/bouncycastle/jsse/provider/test/SSLUtils.java +++ b/tls/src/test/java/org/bouncycastle/jsse/provider/test/SSLUtils.java @@ -59,15 +59,23 @@ public void run() { try { - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("PKIX"); + boolean isJdk15 = System.getProperty("java.version").indexOf("1.5.") == 0; + + KeyManagerFactory keyManagerFactory = isJdk15 ? + KeyManagerFactory.getInstance("PKIX", ProviderUtils.PROVIDER_NAME_BCJSSE) : + KeyManagerFactory.getInstance("PKIX"); keyManagerFactory.init(keyStore, password); - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX"); + TrustManagerFactory trustManagerFactory = isJdk15 ? + TrustManagerFactory.getInstance("PKIX", ProviderUtils.PROVIDER_NAME_BCJSSE) : + TrustManagerFactory.getInstance("PKIX"); trustManagerFactory.init(serverStore); - SSLContext context = SSLContext.getInstance("TLS"); + SSLContext context = isJdk15 ? + SSLContext.getInstance("TLS", ProviderUtils.PROVIDER_NAME_BCJSSE) : + SSLContext.getInstance("TLS"); context.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); @@ -92,9 +100,10 @@ public void run() ss.close(); } - catch (Exception e) + catch (Throwable e) { - e.printStackTrace(); + Thread.currentThread().interrupt(); + latch.countDown(); } } }; @@ -109,7 +118,7 @@ public void run() } catch (InterruptedException e) { - + e.printStackTrace(); } } } diff --git a/tls/src/test/java/org/bouncycastle/jsse/provider/test/TestUtils.java b/tls/src/test/java/org/bouncycastle/jsse/provider/test/TestUtils.java index 7779311afc..05963eb4b6 100644 --- a/tls/src/test/java/org/bouncycastle/jsse/provider/test/TestUtils.java +++ b/tls/src/test/java/org/bouncycastle/jsse/provider/test/TestUtils.java @@ -27,12 +27,14 @@ import java.util.Date; import java.util.EnumSet; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLSocket; import org.bouncycastle.asn1.ASN1EncodableVector; @@ -77,11 +79,12 @@ class TestUtils static final SecureRandom RANDOM = new SecureRandom(); private static AtomicLong serialNumber = new AtomicLong(System.currentTimeMillis()); - private static Map algIDs = createAlgIds(); + private static Map algIDs = createAlgIDs(); + private static Set tlsUniqueProtocols = createTlsUniqueProtocols(); - private static Map createAlgIds() + private static Map createAlgIDs() { - Map algIDs = new HashMap(); + HashMap algIDs = new HashMap(); algIDs.put("SHA1withDSA", new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa_with_sha1)); algIDs.put("SHA224withDSA", new AlgorithmIdentifier(NISTObjectIdentifiers.dsa_with_sha224)); @@ -104,6 +107,22 @@ private static Map createAlgIds() return Collections.unmodifiableMap(algIDs); } + private static Set createTlsUniqueProtocols() + { + /* + * NOTE: This is slightly simplified. tls-unique is available pre-TLSv1.3 when extended_master_secret is + * negotiated OR a full handshake is performed (i.e. not a session resumption). All relevant tests negotiate + * EMS except SSLv3, which we just ignore here since it is not long for this world. + */ + HashSet tlsUniqueProtocols = new HashSet(); + + tlsUniqueProtocols.add("TLSv1"); + tlsUniqueProtocols.add("TLSv1.1"); + tlsUniqueProtocols.add("TLSv1.2"); + + return Collections.unmodifiableSet(tlsUniqueProtocols); + } + private static AlgorithmIdentifier getAlgID(String sigAlgName) { AlgorithmIdentifier algID = algIDs.get(sigAlgName); @@ -420,6 +439,19 @@ public static byte[] getChannelBinding(SSLSocket s, String channelBinding) return null; } + public static byte[] getChannelBinding(SSLEngine e, String channelBinding) + { + if (e instanceof BCSSLEngine) + { + BCSSLConnection connection = ((BCSSLEngine)e).getConnection(); + if (connection != null) + { + return connection.getChannelBinding(channelBinding); + } + } + return null; + } + public static List getTestableProtocols(SSLContext sslContext, boolean fips) { BCSSLEngine sslEngine = (BCSSLEngine)sslContext.createSSLEngine(); @@ -436,6 +468,11 @@ public static List getTestableProtocols(SSLContext sslContext, boolean f return result; } + public static boolean isTlsUniqueProtocol(String protocol) + { + return tlsUniqueProtocols.contains(protocol); + } + private static void addTestableProtocols(ArrayList result, BCAlgorithmConstraints algorithmConstraints, Set primitives, String... protocols) { diff --git a/tls/src/test/java/org/bouncycastle/test/AllTest.java b/tls/src/test/java/org/bouncycastle/test/AllTest.java new file mode 100644 index 0000000000..11b64a1563 --- /dev/null +++ b/tls/src/test/java/org/bouncycastle/test/AllTest.java @@ -0,0 +1,46 @@ +package org.bouncycastle.test; + + +import junit.extensions.TestSetup; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class AllTest extends TestCase +{ + public static void main(String[] args) + throws Exception + { + PrintTestResult.printResult( junit.textui.TestRunner.run(suite())); + } + + public static Test suite() + throws Exception + { + TestSuite suite = new TestSuite("JVM Version test"); + + suite.addTestSuite(JVMVersionTest.class); + + return new BCTestSetup(suite); + } + + static class BCTestSetup + extends TestSetup + { + public BCTestSetup(Test test) + { + super(test); + } + + protected void setUp() + { + + } + + protected void tearDown() + { + + } + } + +} diff --git a/tls/src/test/java/org/bouncycastle/test/JVMVersionTest.java b/tls/src/test/java/org/bouncycastle/test/JVMVersionTest.java new file mode 100644 index 0000000000..15a643c81d --- /dev/null +++ b/tls/src/test/java/org/bouncycastle/test/JVMVersionTest.java @@ -0,0 +1,48 @@ +package org.bouncycastle.test; + +import junit.framework.TestCase; +import org.junit.Test; + +/** + * This test asserts the java version running the tests starts with + * a property value passed in as part of test invocation. + *

      + * -Dtest.java.version.prefix must match the start of System.getProperty("java.version") + * So: + * if -Dtest.java.version.prefix=17 and System.getProperty("java.version") = 17.0.4.1 + * Then this test will pass. + */ +public class JVMVersionTest + extends TestCase +{ + + private static final String expectedVersionPropName = "test.java.version.prefix"; + + + @Test + public void testAssertExpectedJVM() + { + + + // + // This project produces a multi-release jar, and we need to test it on different jvm versions + // This test compares a property "test.java.version.prefix" with the start of the value reported by the JVM. + // eg: + // -Dtest.java.version.prefix=1.8 + // + // It exists because we have had issues with build systems unexpectedly using a different JVM to one we need to test on. + // It is important for multi-release jars to be exercised on a representative JVM for each JVM they support. + // + // + assertNotNull(String.format("property %s is not set, see comment in test for reason why.", expectedVersionPropName), System.getProperty(expectedVersionPropName)); + + + String version = System.getProperty("java.version"); + String expectedPrefix = System.getProperty(expectedVersionPropName); + + assertTrue(String.format("JVM Version: '%s' did not start with '%s' see comment in test", version, expectedPrefix), version.startsWith(expectedPrefix)); + + + } + +} diff --git a/tls/src/test/java/org/bouncycastle/tls/crypto/test/BcTlsCryptoTest.java b/tls/src/test/java/org/bouncycastle/tls/crypto/test/BcTlsCryptoTest.java index 6e32171aab..96f70b3903 100644 --- a/tls/src/test/java/org/bouncycastle/tls/crypto/test/BcTlsCryptoTest.java +++ b/tls/src/test/java/org/bouncycastle/tls/crypto/test/BcTlsCryptoTest.java @@ -9,6 +9,6 @@ public class BcTlsCryptoTest { public BcTlsCryptoTest() { - super(new BcTlsCrypto(new SecureRandom())); + super(new BcTlsCrypto()); } } diff --git a/tls/src/test/java/org/bouncycastle/tls/crypto/test/TlsCryptoTest.java b/tls/src/test/java/org/bouncycastle/tls/crypto/test/TlsCryptoTest.java index a03fbe2cd8..63dc7377b9 100644 --- a/tls/src/test/java/org/bouncycastle/tls/crypto/test/TlsCryptoTest.java +++ b/tls/src/test/java/org/bouncycastle/tls/crypto/test/TlsCryptoTest.java @@ -29,6 +29,8 @@ import org.bouncycastle.tls.crypto.TlsECConfig; import org.bouncycastle.tls.crypto.TlsECDomain; import org.bouncycastle.tls.crypto.TlsHash; +import org.bouncycastle.tls.crypto.TlsKemConfig; +import org.bouncycastle.tls.crypto.TlsKemDomain; import org.bouncycastle.tls.crypto.TlsSecret; import org.bouncycastle.tls.crypto.TlsStreamSigner; import org.bouncycastle.tls.crypto.TlsStreamVerifier; @@ -152,7 +154,7 @@ protected TlsCredentialedSigner loadCredentialedSigner12(TlsCryptoParameters cry case SignatureAlgorithm.rsa_pss_rsae_sha512: return loadCredentialedSigner(cryptoParams, "rsa-sign", signatureAndHashAlgorithm); - // TODO[draft-smyshlyaev-tls12-gost-suites-10] Add test resources for these + // TODO[RFC 9189] Add test resources for these case SignatureAlgorithm.gostr34102012_256: case SignatureAlgorithm.gostr34102012_512: @@ -444,7 +446,7 @@ public void testHKDFExpandLimit() { int[] hashes = new int[] { CryptoHashAlgorithm.md5, CryptoHashAlgorithm.sha1, CryptoHashAlgorithm.sha224, CryptoHashAlgorithm.sha256, CryptoHashAlgorithm.sha384, CryptoHashAlgorithm.sha512, - CryptoHashAlgorithm.sm3 }; + CryptoHashAlgorithm.sm3, CryptoHashAlgorithm.gostr3411_2012_256 }; for (int i = 0; i < hashes.length; ++i) { @@ -486,6 +488,24 @@ public void testHKDFExpandLimit() } } + public void testKemDomain() throws Exception + { + if (!crypto.hasKemAgreement()) + { + return; + } + + for (int namedGroup = 0; namedGroup < 0x10000; ++namedGroup) + { + if (!NamedGroup.refersToASpecificKem(namedGroup) || !crypto.hasNamedGroup(namedGroup)) + { + continue; + } + + implTestKemDomain(namedGroup); + } + } + public void testSignaturesLegacy() throws Exception { short[] signatureAlgorithms = new short[]{ SignatureAlgorithm.dsa, SignatureAlgorithm.ecdsa, @@ -648,11 +668,13 @@ private byte[] implPrehash(SignatureAndHashAlgorithm signatureAndHashAlgorithm, private void implTestAgreement(TlsAgreement aA, TlsAgreement aB) throws IOException { + // NOTE: Order is important since some agreements are actually KEMs + byte[] pA = aA.generateEphemeral(); - byte[] pB = aB.generateEphemeral(); + aB.receivePeerValue(pA); + byte[] pB = aB.generateEphemeral(); aA.receivePeerValue(pB); - aB.receivePeerValue(pA); TlsSecret sA = aA.calculateSecret(); TlsSecret sB = aB.calculateSecret(); @@ -696,6 +718,20 @@ private void implTestECDomain(TlsECConfig ecConfig) throws IOException } } + private void implTestKemDomain(int namedGroup) throws IOException + { + TlsKemDomain clientDomain = crypto.createKemDomain(new TlsKemConfig(namedGroup, false)); + TlsKemDomain serverDomain = crypto.createKemDomain(new TlsKemConfig(namedGroup, true)); + + for (int i = 0; i < 2; ++i) + { + TlsAgreement clientKem = clientDomain.createKem(); + TlsAgreement serverKem = serverDomain.createKem(); + + implTestAgreement(clientKem, serverKem); + } + } + private void implTestSignatureLegacy(TlsCredentialedSigner credentialedSigner) throws IOException { byte[] message = crypto.createNonceGenerator(TlsUtils.EMPTY_BYTES).generateNonce(100); diff --git a/tls/src/test/java/org/bouncycastle/tls/test/AllTests.java b/tls/src/test/java/org/bouncycastle/tls/test/AllTests.java index a0ec6b0adf..64b985fe45 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/AllTests.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/AllTests.java @@ -1,10 +1,11 @@ package org.bouncycastle.tls.test; +import org.bouncycastle.test.PrintTestResult; + import junit.extensions.TestSetup; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import org.bouncycastle.test.PrintTestResult; public class AllTests extends TestCase @@ -22,8 +23,11 @@ public static Test suite() suite.addTestSuite(BasicTlsTest.class); suite.addTestSuite(ByteQueueInputStreamTest.class); + suite.addTestSuite(DTLSAggregatedHandshakeRetransmissionTest.class); + suite.addTestSuite(DTLSHandshakeRetransmissionTest.class); suite.addTestSuite(DTLSProtocolTest.class); suite.addTestSuite(DTLSPSKProtocolTest.class); + suite.addTestSuite(DTLSRawKeysProtocolTest.class); suite.addTestSuite(OCSPTest.class); suite.addTestSuite(PRFTest.class); suite.addTestSuite(Tls13PSKProtocolTest.class); diff --git a/tls/src/test/java/org/bouncycastle/tls/test/BasicTlsTest.java b/tls/src/test/java/org/bouncycastle/tls/test/BasicTlsTest.java index c0e09377d2..42df39eb73 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/BasicTlsTest.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/BasicTlsTest.java @@ -5,7 +5,6 @@ import java.io.OutputStream; import java.io.PrintStream; import java.net.Socket; -import java.security.SecureRandom; import java.util.Vector; import org.bouncycastle.test.PrintTestResult; @@ -172,7 +171,7 @@ public void notifyAlertReceived(short alertLevel, short alertDescription) MyTlsClient(TlsAuthentication authentication) { - super(new BcTlsCrypto(new SecureRandom())); + super(new BcTlsCrypto()); this.authentication = authentication; diff --git a/tls/src/test/java/org/bouncycastle/tls/test/DTLSAggregatedHandshakeRetransmissionTest.java b/tls/src/test/java/org/bouncycastle/tls/test/DTLSAggregatedHandshakeRetransmissionTest.java new file mode 100644 index 0000000000..1181654938 --- /dev/null +++ b/tls/src/test/java/org/bouncycastle/tls/test/DTLSAggregatedHandshakeRetransmissionTest.java @@ -0,0 +1,138 @@ +package org.bouncycastle.tls.test; + +import org.bouncycastle.tls.DTLSClientProtocol; +import org.bouncycastle.tls.DTLSRequest; +import org.bouncycastle.tls.DTLSServerProtocol; +import org.bouncycastle.tls.DTLSTransport; +import org.bouncycastle.tls.DTLSVerifier; +import org.bouncycastle.tls.DatagramTransport; +import org.bouncycastle.tls.crypto.TlsCrypto; +import org.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; + +import junit.framework.TestCase; + +public class DTLSAggregatedHandshakeRetransmissionTest + extends TestCase +{ + public void testClientServer() throws Exception + { + DTLSClientProtocol clientProtocol = new DTLSClientProtocol(); + DTLSServerProtocol serverProtocol = new DTLSServerProtocol(); + + MockDatagramAssociation network = new MockDatagramAssociation(1500); + + ServerThread serverThread = new ServerThread(serverProtocol, network.getServer()); + serverThread.start(); + + DatagramTransport clientTransport = network.getClient(); + + clientTransport = new ServerHandshakeDropper(clientTransport, true); + + clientTransport = new LoggingDatagramTransport(clientTransport, System.out); + + clientTransport = new MinimalHandshakeAggregator(clientTransport, false, true); + + MockDTLSClient client = new MockDTLSClient(null); + + client.setHandshakeTimeoutMillis(30000); // Test gets stuck, so we need it to time out. + + DTLSTransport dtlsClient = clientProtocol.connect(client, clientTransport); + + for (int i = 1; i <= 10; ++i) + { + byte[] data = new byte[i]; + Arrays.fill(data, (byte)i); + dtlsClient.send(data, 0, data.length); + } + + byte[] buf = new byte[dtlsClient.getReceiveLimit()]; + while (dtlsClient.receive(buf, 0, buf.length, 100) >= 0) + { + } + + dtlsClient.close(); + + serverThread.shutdown(); + } + + static class ServerThread + extends Thread + { + private final DTLSServerProtocol serverProtocol; + private final DatagramTransport serverTransport; + private volatile boolean isShutdown = false; + + ServerThread(DTLSServerProtocol serverProtocol, DatagramTransport serverTransport) + { + this.serverProtocol = serverProtocol; + this.serverTransport = serverTransport; + } + + public void run() + { + try + { + TlsCrypto serverCrypto = new BcTlsCrypto(); + + DTLSRequest request = null; + + // Use DTLSVerifier to require a HelloVerifyRequest cookie exchange before accepting + { + DTLSVerifier verifier = new DTLSVerifier(serverCrypto); + + // NOTE: Test value only - would typically be the client IP address + byte[] clientID = Strings.toUTF8ByteArray("MockDtlsClient"); + + int receiveLimit = serverTransport.getReceiveLimit(); + int dummyOffset = serverCrypto.getSecureRandom().nextInt(16) + 1; + byte[] buf = new byte[dummyOffset + serverTransport.getReceiveLimit()]; + + do + { + if (isShutdown) + return; + + int length = serverTransport.receive(buf, dummyOffset, receiveLimit, 100); + if (length > 0) + { + request = verifier.verifyRequest(clientID, buf, dummyOffset, length, serverTransport); + } + } + while (request == null); + } + + // NOTE: A real server would handle each DTLSRequest in a new task/thread and continue accepting + { + MockDTLSServer server = new MockDTLSServer(serverCrypto); + DTLSTransport dtlsTransport = serverProtocol.accept(server, serverTransport, request); + byte[] buf = new byte[dtlsTransport.getReceiveLimit()]; + while (!isShutdown) + { + int length = dtlsTransport.receive(buf, 0, buf.length, 100); + if (length >= 0) + { + dtlsTransport.send(buf, 0, length); + } + } + dtlsTransport.close(); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + void shutdown() + throws InterruptedException + { + if (!isShutdown) + { + isShutdown = true; + this.join(); + } + } + } +} diff --git a/tls/src/test/java/org/bouncycastle/tls/test/DTLSClientTest.java b/tls/src/test/java/org/bouncycastle/tls/test/DTLSClientTest.java index 8739b5120b..c68c7d6011 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/DTLSClientTest.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/DTLSClientTest.java @@ -11,6 +11,7 @@ import org.bouncycastle.tls.TlsClient; import org.bouncycastle.tls.TlsSession; import org.bouncycastle.tls.UDPTransport; +import org.bouncycastle.util.Strings; /** * A simple test designed to conduct a DTLS handshake with an external DTLS server. @@ -40,7 +41,7 @@ public static void main(String[] args) // Send and hopefully receive a packet back - byte[] request = "Hello World!\n".getBytes("UTF-8"); + byte[] request = Strings.toUTF8ByteArray("Hello World!\n"); dtls.send(request, 0, request.length); byte[] response = new byte[dtls.getReceiveLimit()]; diff --git a/tls/src/test/java/org/bouncycastle/tls/test/DTLSHandshakeRetransmissionTest.java b/tls/src/test/java/org/bouncycastle/tls/test/DTLSHandshakeRetransmissionTest.java new file mode 100644 index 0000000000..7d6de6df6c --- /dev/null +++ b/tls/src/test/java/org/bouncycastle/tls/test/DTLSHandshakeRetransmissionTest.java @@ -0,0 +1,134 @@ +package org.bouncycastle.tls.test; + +import org.bouncycastle.tls.DTLSClientProtocol; +import org.bouncycastle.tls.DTLSRequest; +import org.bouncycastle.tls.DTLSServerProtocol; +import org.bouncycastle.tls.DTLSTransport; +import org.bouncycastle.tls.DTLSVerifier; +import org.bouncycastle.tls.DatagramTransport; +import org.bouncycastle.tls.crypto.TlsCrypto; +import org.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; + +import junit.framework.TestCase; + +public class DTLSHandshakeRetransmissionTest + extends TestCase +{ + public void testClientServer() throws Exception + { + DTLSClientProtocol clientProtocol = new DTLSClientProtocol(); + DTLSServerProtocol serverProtocol = new DTLSServerProtocol(); + + MockDatagramAssociation network = new MockDatagramAssociation(1500); + + ServerThread serverThread = new ServerThread(serverProtocol, network.getServer()); + serverThread.start(); + + DatagramTransport clientTransport = network.getClient(); + + clientTransport = new ServerHandshakeDropper(clientTransport, true); + + clientTransport = new LoggingDatagramTransport(clientTransport, System.out); + + MockDTLSClient client = new MockDTLSClient(null); + + DTLSTransport dtlsClient = clientProtocol.connect(client, clientTransport); + + for (int i = 1; i <= 10; ++i) + { + byte[] data = new byte[i]; + Arrays.fill(data, (byte)i); + dtlsClient.send(data, 0, data.length); + } + + byte[] buf = new byte[dtlsClient.getReceiveLimit()]; + while (dtlsClient.receive(buf, 0, buf.length, 100) >= 0) + { + } + + dtlsClient.close(); + + serverThread.shutdown(); + } + + static class ServerThread + extends Thread + { + private final DTLSServerProtocol serverProtocol; + private final DatagramTransport serverTransport; + private volatile boolean isShutdown = false; + + ServerThread(DTLSServerProtocol serverProtocol, DatagramTransport serverTransport) + { + this.serverProtocol = serverProtocol; + this.serverTransport = serverTransport; + } + + public void run() + { + try + { + TlsCrypto serverCrypto = new BcTlsCrypto(); + + DTLSRequest request = null; + + // Use DTLSVerifier to require a HelloVerifyRequest cookie exchange before accepting + { + DTLSVerifier verifier = new DTLSVerifier(serverCrypto); + + // NOTE: Test value only - would typically be the client IP address + byte[] clientID = Strings.toUTF8ByteArray("MockDtlsClient"); + + int receiveLimit = serverTransport.getReceiveLimit(); + int dummyOffset = serverCrypto.getSecureRandom().nextInt(16) + 1; + byte[] buf = new byte[dummyOffset + serverTransport.getReceiveLimit()]; + + do + { + if (isShutdown) + return; + + int length = serverTransport.receive(buf, dummyOffset, receiveLimit, 100); + if (length > 0) + { + request = verifier.verifyRequest(clientID, buf, dummyOffset, length, serverTransport); + } + } + while (request == null); + } + + // NOTE: A real server would handle each DTLSRequest in a new task/thread and continue accepting + { + MockDTLSServer server = new MockDTLSServer(serverCrypto); + DTLSTransport dtlsTransport = serverProtocol.accept(server, serverTransport, request); + byte[] buf = new byte[dtlsTransport.getReceiveLimit()]; + while (!isShutdown) + { + int length = dtlsTransport.receive(buf, 0, buf.length, 100); + if (length >= 0) + { + dtlsTransport.send(buf, 0, length); + } + } + dtlsTransport.close(); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + void shutdown() + throws InterruptedException + { + if (!isShutdown) + { + isShutdown = true; + this.join(); + } + } + } +} diff --git a/tls/src/test/java/org/bouncycastle/tls/test/DTLSPSKProtocolTest.java b/tls/src/test/java/org/bouncycastle/tls/test/DTLSPSKProtocolTest.java index 20e33ff5b2..1ee37bbe1f 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/DTLSPSKProtocolTest.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/DTLSPSKProtocolTest.java @@ -74,7 +74,7 @@ public void run() byte[] buf = new byte[dtlsServer.getReceiveLimit()]; while (!isShutdown) { - int length = dtlsServer.receive(buf, 0, buf.length, 1000); + int length = dtlsServer.receive(buf, 0, buf.length, 100); if (length >= 0) { dtlsServer.send(buf, 0, length); diff --git a/tls/src/test/java/org/bouncycastle/tls/test/DTLSProtocolTest.java b/tls/src/test/java/org/bouncycastle/tls/test/DTLSProtocolTest.java index 73bc1b819d..3bb3a51254 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/DTLSProtocolTest.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/DTLSProtocolTest.java @@ -3,10 +3,15 @@ import java.security.SecureRandom; import org.bouncycastle.tls.DTLSClientProtocol; +import org.bouncycastle.tls.DTLSRequest; import org.bouncycastle.tls.DTLSServerProtocol; import org.bouncycastle.tls.DTLSTransport; +import org.bouncycastle.tls.DTLSVerifier; import org.bouncycastle.tls.DatagramTransport; +import org.bouncycastle.tls.crypto.TlsCrypto; +import org.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; import junit.framework.TestCase; @@ -69,18 +74,50 @@ public void run() { try { - MockDTLSServer server = new MockDTLSServer(); - DTLSTransport dtlsServer = serverProtocol.accept(server, serverTransport); - byte[] buf = new byte[dtlsServer.getReceiveLimit()]; - while (!isShutdown) + TlsCrypto serverCrypto = new BcTlsCrypto(); + + DTLSRequest request = null; + + // Use DTLSVerifier to require a HelloVerifyRequest cookie exchange before accepting + { + DTLSVerifier verifier = new DTLSVerifier(serverCrypto); + + // NOTE: Test value only - would typically be the client IP address + byte[] clientID = Strings.toUTF8ByteArray("MockDtlsClient"); + + int receiveLimit = serverTransport.getReceiveLimit(); + int dummyOffset = serverCrypto.getSecureRandom().nextInt(16) + 1; + byte[] buf = new byte[dummyOffset + serverTransport.getReceiveLimit()]; + + do + { + if (isShutdown) + return; + + int length = serverTransport.receive(buf, dummyOffset, receiveLimit, 100); + if (length > 0) + { + request = verifier.verifyRequest(clientID, buf, dummyOffset, length, serverTransport); + } + } + while (request == null); + } + + // NOTE: A real server would handle each DTLSRequest in a new task/thread and continue accepting { - int length = dtlsServer.receive(buf, 0, buf.length, 1000); - if (length >= 0) + MockDTLSServer server = new MockDTLSServer(serverCrypto); + DTLSTransport dtlsTransport = serverProtocol.accept(server, serverTransport, request); + byte[] buf = new byte[dtlsTransport.getReceiveLimit()]; + while (!isShutdown) { - dtlsServer.send(buf, 0, length); + int length = dtlsTransport.receive(buf, 0, buf.length, 100); + if (length >= 0) + { + dtlsTransport.send(buf, 0, length); + } } + dtlsTransport.close(); } - dtlsServer.close(); } catch (Exception e) { diff --git a/tls/src/test/java/org/bouncycastle/tls/test/DTLSRawKeysProtocolTest.java b/tls/src/test/java/org/bouncycastle/tls/test/DTLSRawKeysProtocolTest.java new file mode 100644 index 0000000000..c833062fe1 --- /dev/null +++ b/tls/src/test/java/org/bouncycastle/tls/test/DTLSRawKeysProtocolTest.java @@ -0,0 +1,408 @@ +package org.bouncycastle.tls.test; + +import java.security.SecureRandom; + +import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; +import org.bouncycastle.tls.CertificateType; +import org.bouncycastle.tls.DTLSClientProtocol; +import org.bouncycastle.tls.DTLSRequest; +import org.bouncycastle.tls.DTLSServerProtocol; +import org.bouncycastle.tls.DTLSTransport; +import org.bouncycastle.tls.DTLSVerifier; +import org.bouncycastle.tls.DatagramTransport; +import org.bouncycastle.tls.ProtocolVersion; +import org.bouncycastle.tls.TlsClient; +import org.bouncycastle.tls.TlsExtensionsUtils; +import org.bouncycastle.tls.TlsServer; +import org.bouncycastle.tls.crypto.TlsCrypto; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; + +import junit.framework.TestCase; + +public class DTLSRawKeysProtocolTest + extends TestCase +{ + private final SecureRandom RANDOM = new SecureRandom(); + + public void testClientSendsExtensionButServerDoesNotSupportIt() throws Exception + { + testClientSendsExtensionButServerDoesNotSupportIt(ProtocolVersion.DTLSv12); + } + + // TODO[dtls13] +// public void testClientSendsExtensionButServerDoesNotSupportIt_13() throws Exception +// { +// testClientSendsExtensionButServerDoesNotSupportIt(ProtocolVersion.DTLSv13); +// } + + private void testClientSendsExtensionButServerDoesNotSupportIt(ProtocolVersion tlsVersion) throws Exception + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient( + CertificateType.X509, + (short) -1, + new short[] {CertificateType.RawPublicKey, CertificateType.X509}, + null, + generateKeyPair(), + tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer( + CertificateType.X509, + (short) -1, + null, + generateKeyPair(), + tlsVersion); + pumpData(client, server); + } + + public void testExtensionsAreOmittedIfSpecifiedButOnlyContainX509() throws Exception + { + testExtensionsAreOmittedIfSpecifiedButOnlyContainX509(ProtocolVersion.DTLSv12); + } + + // TODO[dtls13] +// public void testExtensionsAreOmittedIfSpecifiedButOnlyContainX509_13() throws Exception +// { +// testExtensionsAreOmittedIfSpecifiedButOnlyContainX509(ProtocolVersion.DTLSv13); +// } + + private void testExtensionsAreOmittedIfSpecifiedButOnlyContainX509(ProtocolVersion tlsVersion) throws Exception + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient( + CertificateType.X509, + CertificateType.X509, + new short[] {CertificateType.X509}, + new short[] {CertificateType.X509}, + generateKeyPair(), + tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer( + CertificateType.X509, + CertificateType.X509, + new short[] {CertificateType.X509}, + generateKeyPair(), + tlsVersion); + pumpData(client, server); + + assertFalse( + "client cert type extension should not be sent", + server.receivedClientExtensions.containsKey(TlsExtensionsUtils.EXT_client_certificate_type)); + assertFalse( + "server cert type extension should not be sent", + server.receivedClientExtensions.containsKey(TlsExtensionsUtils.EXT_server_certificate_type)); + } + + public void testBothSidesUseRawKey() throws Exception + { + testBothSidesUseRawKey(ProtocolVersion.DTLSv12); + } + + // TODO[dtls13] +// public void testBothSidesUseRawKey_13() throws Exception +// { +// testBothSidesUseRawKey(ProtocolVersion.DTLSv13); +// } + + private void testBothSidesUseRawKey(ProtocolVersion tlsVersion) throws Exception + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient( + CertificateType.RawPublicKey, + CertificateType.RawPublicKey, + new short[] {CertificateType.RawPublicKey}, + new short[] {CertificateType.RawPublicKey}, + generateKeyPair(), + tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer( + CertificateType.RawPublicKey, + CertificateType.RawPublicKey, + new short[] {CertificateType.RawPublicKey}, + generateKeyPair(), + tlsVersion); + pumpData(client, server); + } + + public void testServerUsesRawKeyAndClientIsAnonymous() throws Exception + { + testServerUsesRawKeyAndClientIsAnonymous(ProtocolVersion.DTLSv12); + } + + // TODO[dtls13] +// public void testServerUsesRawKeyAndClientIsAnonymous_13() throws Exception +// { +// testServerUsesRawKeyAndClientIsAnonymous(ProtocolVersion.DTLSv13); +// } + + private void testServerUsesRawKeyAndClientIsAnonymous(ProtocolVersion tlsVersion) throws Exception + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient( + CertificateType.RawPublicKey, + (short) -1, + new short[] {CertificateType.RawPublicKey}, + null, + generateKeyPair(), + tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer( + CertificateType.RawPublicKey, + (short) -1, + null, + generateKeyPair(), + tlsVersion); + pumpData(client, server); + } + + public void testServerUsesRawKeyAndClientUsesX509() throws Exception + { + testServerUsesRawKeyAndClientUsesX509(ProtocolVersion.DTLSv12); + } + + // TODO[dtls13] +// public void testServerUsesRawKeyAndClientUsesX509_13() throws Exception +// { +// testServerUsesRawKeyAndClientUsesX509(ProtocolVersion.DTLSv13); +// } + + private void testServerUsesRawKeyAndClientUsesX509(ProtocolVersion tlsVersion) throws Exception + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient( + CertificateType.RawPublicKey, + CertificateType.X509, + new short[] {CertificateType.RawPublicKey}, + null, + generateKeyPair(), + tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer( + CertificateType.RawPublicKey, + CertificateType.X509, + null, + generateKeyPair(), + tlsVersion); + pumpData(client, server); + } + + public void testServerUsesX509AndClientUsesRawKey() throws Exception + { + testServerUsesX509AndClientUsesRawKey(ProtocolVersion.DTLSv12); + } + + // TODO[dtls13] +// public void testServerUsesX509AndClientUsesRawKey_13() throws Exception +// { +// testServerUsesX509AndClientUsesRawKey(ProtocolVersion.DTLSv13); +// } + + private void testServerUsesX509AndClientUsesRawKey(ProtocolVersion tlsVersion) throws Exception + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient( + CertificateType.X509, + CertificateType.RawPublicKey, + null, + new short[] {CertificateType.RawPublicKey}, + generateKeyPair(), + tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer( + CertificateType.X509, + CertificateType.RawPublicKey, + new short[] {CertificateType.RawPublicKey}, + generateKeyPair(), + tlsVersion); + pumpData(client, server); + } + + // NOTE: Test disabled because of problems getting a clean exit of the DTLS server after a fatal alert. +/* + public void testClientSendsClientCertExtensionButServerHasNoCommonTypes() throws Exception + { + testClientSendsClientCertExtensionButServerHasNoCommonTypes(ProtocolVersion.DTLSv12); + } + + // TODO[dtls13] +// public void testClientSendsClientCertExtensionButServerHasNoCommonTypes_13() throws Exception +// { +// testClientSendsClientCertExtensionButServerHasNoCommonTypes(ProtocolVersion.DTLSv13); +// } + + private void testClientSendsClientCertExtensionButServerHasNoCommonTypes(ProtocolVersion tlsVersion) throws Exception + { + try + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient( + CertificateType.X509, + CertificateType.RawPublicKey, + null, + new short[] {CertificateType.RawPublicKey}, + generateKeyPair(), + tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer( + CertificateType.X509, + CertificateType.X509, + new short[] {CertificateType.X509}, + generateKeyPair(), + tlsVersion); + pumpData(client, server); + fail("Should have caused unsupported_certificate alert"); + } + catch (TlsFatalAlertReceived alert) + { + assertEquals("Should have caused unsupported_certificate alert", alert.getAlertDescription(), AlertDescription.unsupported_certificate); + } + } +*/ + + // NOTE: Test disabled because of problems getting a clean exit of the DTLS server after a fatal alert. +/* + public void testClientSendsServerCertExtensionButServerHasNoCommonTypes() throws Exception + { + testClientSendsServerCertExtensionButServerHasNoCommonTypes(ProtocolVersion.DTLSv12); + } + + // TODO[dtls13] +// public void testClientSendsServerCertExtensionButServerHasNoCommonTypes_13() throws Exception +// { +// testClientSendsServerCertExtensionButServerHasNoCommonTypes(ProtocolVersion.DTLSv13); +// } + + private void testClientSendsServerCertExtensionButServerHasNoCommonTypes(ProtocolVersion tlsVersion) throws Exception + { + try + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient( + CertificateType.RawPublicKey, + CertificateType.RawPublicKey, + new short[] {CertificateType.RawPublicKey}, + null, + generateKeyPair(), + tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer( + CertificateType.X509, + CertificateType.RawPublicKey, + new short[] {CertificateType.RawPublicKey}, + generateKeyPair(), + tlsVersion); + pumpData(client, server); + fail("Should have caused unsupported_certificate alert"); + } + catch (TlsFatalAlertReceived alert) + { + assertEquals("Should have caused unsupported_certificate alert", alert.getAlertDescription(), AlertDescription.unsupported_certificate); + } + } +*/ + + private Ed25519PrivateKeyParameters generateKeyPair() + { + return new Ed25519PrivateKeyParameters(RANDOM); + } + + private void pumpData(TlsClient client, TlsServer server) throws Exception + { + DTLSClientProtocol clientProtocol = new DTLSClientProtocol(); + DTLSServerProtocol serverProtocol = new DTLSServerProtocol(); + + MockDatagramAssociation network = new MockDatagramAssociation(1500); + + ServerThread serverThread = new ServerThread(serverProtocol, server, network.getServer()); + serverThread.start(); + + DatagramTransport clientTransport = network.getClient(); + + clientTransport = new UnreliableDatagramTransport(clientTransport, RANDOM, 0, 0); + + clientTransport = new LoggingDatagramTransport(clientTransport, System.out); + + DTLSTransport dtlsClient = clientProtocol.connect(client, clientTransport); + + for (int i = 1; i <= 10; ++i) + { + byte[] data = new byte[i]; + Arrays.fill(data, (byte)i); + dtlsClient.send(data, 0, data.length); + } + + byte[] buf = new byte[dtlsClient.getReceiveLimit()]; + while (dtlsClient.receive(buf, 0, buf.length, 100) >= 0) + { + } + + dtlsClient.close(); + + serverThread.shutdown(); + } + + static class ServerThread + extends Thread + { + private final DTLSServerProtocol serverProtocol; + private final TlsServer server; + private final DatagramTransport serverTransport; + private volatile boolean isShutdown = false; + + ServerThread(DTLSServerProtocol serverProtocol, TlsServer server, DatagramTransport serverTransport) + { + this.serverProtocol = serverProtocol; + this.server = server; + this.serverTransport = serverTransport; + } + + public void run() + { + try + { + TlsCrypto serverCrypto = server.getCrypto(); + + DTLSRequest request = null; + + // Use DTLSVerifier to require a HelloVerifyRequest cookie exchange before accepting + { + DTLSVerifier verifier = new DTLSVerifier(serverCrypto); + + // NOTE: Test value only - would typically be the client IP address + byte[] clientID = Strings.toUTF8ByteArray("MockRawKeysTlsClient"); + + int receiveLimit = serverTransport.getReceiveLimit(); + int dummyOffset = serverCrypto.getSecureRandom().nextInt(16) + 1; + byte[] buf = new byte[dummyOffset + serverTransport.getReceiveLimit()]; + + do + { + if (isShutdown) + return; + + int length = serverTransport.receive(buf, dummyOffset, receiveLimit, 100); + if (length > 0) + { + request = verifier.verifyRequest(clientID, buf, dummyOffset, length, serverTransport); + } + } + while (request == null); + } + + // NOTE: A real server would handle each DTLSRequest in a new task/thread and continue accepting + { + DTLSTransport dtlsTransport = serverProtocol.accept(server, serverTransport, request); + byte[] buf = new byte[dtlsTransport.getReceiveLimit()]; + while (!isShutdown) + { + int length = dtlsTransport.receive(buf, 0, buf.length, 100); + if (length >= 0) + { + dtlsTransport.send(buf, 0, length); + } + } + dtlsTransport.close(); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + void shutdown() + throws InterruptedException + { + if (!isShutdown) + { + isShutdown = true; + this.join(); + } + } + } +} diff --git a/tls/src/test/java/org/bouncycastle/tls/test/DTLSServerTest.java b/tls/src/test/java/org/bouncycastle/tls/test/DTLSServerTest.java index af7104a46b..a4282131a7 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/DTLSServerTest.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/DTLSServerTest.java @@ -4,7 +4,6 @@ import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketTimeoutException; -import java.security.SecureRandom; import org.bouncycastle.tls.AlertDescription; import org.bouncycastle.tls.DTLSRequest; @@ -15,6 +14,7 @@ import org.bouncycastle.tls.DatagramTransport; import org.bouncycastle.tls.TlsFatalAlert; import org.bouncycastle.tls.UDPTransport; +import org.bouncycastle.tls.crypto.TlsCrypto; import org.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto; /** @@ -32,7 +32,9 @@ public static void main(String[] args) int port = 5556; final int mtu = 1500; - DTLSVerifier verifier = new DTLSVerifier(new BcTlsCrypto(new SecureRandom())); + TlsCrypto serverCrypto = new BcTlsCrypto(); + + DTLSVerifier verifier = new DTLSVerifier(serverCrypto); DTLSRequest request = null; byte[] data = new byte[mtu]; @@ -77,7 +79,7 @@ public void send(byte[] buf, int off, int len) throws IOException // Uncomment to see packets // transport = new LoggingDatagramTransport(transport, System.out); - MockDTLSServer server = new MockDTLSServer(); + MockDTLSServer server = new MockDTLSServer(serverCrypto); DTLSServerProtocol serverProtocol = new DTLSServerProtocol(); DTLSTransport dtlsServer = serverProtocol.accept(server, transport, request); diff --git a/tls/src/test/java/org/bouncycastle/tls/test/FilteredDatagramTransport.java b/tls/src/test/java/org/bouncycastle/tls/test/FilteredDatagramTransport.java new file mode 100644 index 0000000000..d07ef82cbd --- /dev/null +++ b/tls/src/test/java/org/bouncycastle/tls/test/FilteredDatagramTransport.java @@ -0,0 +1,89 @@ +package org.bouncycastle.tls.test; + +import java.io.IOException; + +import org.bouncycastle.tls.DatagramTransport; + +public class FilteredDatagramTransport + implements DatagramTransport +{ + public interface FilterPredicate + { + boolean allowPacket(byte[] buf, int off, int len); + } + + public static final FilterPredicate ALWAYS_ALLOW = new FilterPredicate() + { + public boolean allowPacket(byte[] buf, int off, int len) + { + return true; + } + }; + + private final DatagramTransport transport; + + private final FilterPredicate allowReceiving, allowSending; + + public FilteredDatagramTransport(DatagramTransport transport, FilterPredicate allowReceiving, + FilterPredicate allowSending) + { + this.transport = transport; + this.allowReceiving = allowReceiving; + this.allowSending = allowSending; + } + + public int getReceiveLimit() + throws IOException + { + return transport.getReceiveLimit(); + } + + public int getSendLimit() + throws IOException + { + return transport.getSendLimit(); + } + + public int receive(byte[] buf, int off, int len, int waitMillis) + throws IOException + { + long endMillis = System.currentTimeMillis() + waitMillis; + for (;;) + { + int length = transport.receive(buf, off, len, waitMillis); + if (length < 0 || allowReceiving.allowPacket(buf, off, len)) + { + return length; + } + + System.out.println("PACKET FILTERED (" + length + " byte packet not received)"); + + long now = System.currentTimeMillis(); + if (now >= endMillis) + { + return -1; + } + + waitMillis = (int)(endMillis - now); + } + } + + public void send(byte[] buf, int off, int len) + throws IOException + { + if (!allowSending.allowPacket(buf, off, len)) + { + System.out.println("PACKET FILTERED (" + len + " byte packet not sent)"); + } + else + { + transport.send(buf, off, len); + } + } + + public void close() + throws IOException + { + transport.close(); + } +} diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MinimalHandshakeAggregator.java b/tls/src/test/java/org/bouncycastle/tls/test/MinimalHandshakeAggregator.java new file mode 100644 index 0000000000..d1f2fd273b --- /dev/null +++ b/tls/src/test/java/org/bouncycastle/tls/test/MinimalHandshakeAggregator.java @@ -0,0 +1,164 @@ +package org.bouncycastle.tls.test; + +import java.io.IOException; + +import org.bouncycastle.tls.ContentType; +import org.bouncycastle.tls.DatagramTransport; +import org.bouncycastle.tls.HandshakeType; +import org.bouncycastle.tls.TlsUtils; + +/** + * A very minimal and stupid class to aggregate DTLS handshake messages. Only sufficient for unit tests. + */ +public class MinimalHandshakeAggregator + implements DatagramTransport +{ + private final DatagramTransport transport; + + private final boolean aggregateReceiving, aggregateSending; + + byte[] receiveBuf, sendBuf; + + int receiveRecordCount, sendRecordCount; + + private byte[] addToBuf(byte[] baseBuf, byte[] buf, int off, int len) + { + byte[] ret = new byte[baseBuf.length + len]; + System.arraycopy(baseBuf, 0, ret, 0, baseBuf.length); + System.arraycopy(buf, off, ret, baseBuf.length, len); + return ret; + } + + private void addToReceiveBuf(byte[] buf, int off, int len) + { + receiveBuf = addToBuf(receiveBuf, buf, off, len); + receiveRecordCount++; + } + + private void resetReceiveBuf() + { + receiveBuf = new byte[0]; + receiveRecordCount = 0; + } + + private void addToSendBuf(byte[] buf, int off, int len) + { + sendBuf = addToBuf(sendBuf, buf, off, len); + sendRecordCount++; + } + + private void resetSendBuf() + { + sendBuf = new byte[0]; + sendRecordCount = 0; + } + + /** Whether the buffered aggregated data should be flushed after this packet. + * This is done on the end of the first flight - ClientHello and ServerHelloDone - and anything that is + * Epoch 1. + */ + private boolean flushAfterThisPacket(byte[] buf, int off, int len) + { + int epoch = TlsUtils.readUint16(buf, off + 3); + if (epoch > 0) + { + return true; + } + short contentType = TlsUtils.readUint8(buf, off); + if (ContentType.handshake != contentType) + { + return false; + } + short msgType = TlsUtils.readUint8(buf, off + 13); + switch (msgType) { + case HandshakeType.client_hello: + case HandshakeType.server_hello_done: + return true; + default: + return false; + } + } + + public MinimalHandshakeAggregator(DatagramTransport transport, boolean aggregateReceiving, boolean aggregateSending) + { + this.transport = transport; + this.aggregateReceiving = aggregateReceiving; + this.aggregateSending = aggregateSending; + resetReceiveBuf(); + resetSendBuf(); + } + + public int getReceiveLimit() + throws IOException + { + return transport.getReceiveLimit(); + } + + public int getSendLimit() + throws IOException + { + return transport.getSendLimit(); + } + + public int receive(byte[] buf, int off, int len, int waitMillis) + throws IOException + { + long endMillis = System.currentTimeMillis() + waitMillis; + for (;;) + { + int length = transport.receive(buf, off, len, waitMillis); + if (length < 0 || !aggregateReceiving) + { + return length; + } + + addToReceiveBuf(buf, off, length); + + if (flushAfterThisPacket(buf, off, length)) { + if (receiveRecordCount > 1) + { + System.out.println("RECEIVING " + receiveRecordCount + " RECORDS IN " + length + " BYTE PACKET"); + } + int resultLength = Math.min(len, receiveBuf.length); + System.arraycopy(receiveBuf, 0, buf, off, resultLength); + resetReceiveBuf(); + return resultLength; + } + + long now = System.currentTimeMillis(); + if (now >= endMillis) + { + return -1; + } + + waitMillis = (int)(endMillis - now); + } + } + + public void send(byte[] buf, int off, int len) + throws IOException + { + if (!aggregateSending) + { + transport.send(buf, off, len); + return; + } + addToSendBuf(buf, off, len); + + if (flushAfterThisPacket(buf, off, len)) + { + if (sendRecordCount > 1) + { + System.out.println("SENDING " + sendRecordCount + " RECORDS IN " + sendBuf.length + " BYTE PACKET"); + } + transport.send(sendBuf, 0, sendBuf.length); + resetSendBuf(); + } + } + + public void close() + throws IOException + { + transport.close(); + } +} diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockDTLSClient.java b/tls/src/test/java/org/bouncycastle/tls/test/MockDTLSClient.java index 568118eb26..16c178e12a 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockDTLSClient.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockDTLSClient.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.PrintStream; -import java.security.SecureRandom; import java.util.Hashtable; import org.bouncycastle.asn1.x509.Certificate; @@ -31,9 +30,11 @@ class MockDTLSClient { TlsSession session; + private int handshakeTimeoutMillis = 0; + MockDTLSClient(TlsSession session) { - super(new BcTlsCrypto(new SecureRandom())); + super(new BcTlsCrypto()); this.session = session; } @@ -43,6 +44,16 @@ public TlsSession getSessionToResume() return this.session; } + public int getHandshakeTimeoutMillis() + { + return handshakeTimeoutMillis; + } + + public void setHandshakeTimeoutMillis(int millis) + { + handshakeTimeoutMillis = millis; + } + public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Throwable cause) { PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockDTLSServer.java b/tls/src/test/java/org/bouncycastle/tls/test/MockDTLSServer.java index 00f4c4fa8f..b4995fcd5e 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockDTLSServer.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockDTLSServer.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.PrintStream; -import java.security.SecureRandom; import java.util.Hashtable; import java.util.Vector; @@ -22,6 +21,7 @@ import org.bouncycastle.tls.TlsFatalAlert; import org.bouncycastle.tls.TlsUtils; import org.bouncycastle.tls.crypto.TlsCertificate; +import org.bouncycastle.tls.crypto.TlsCrypto; import org.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto; import org.bouncycastle.util.encoders.Hex; @@ -30,7 +30,12 @@ class MockDTLSServer { MockDTLSServer() { - super(new BcTlsCrypto(new SecureRandom())); + this(new BcTlsCrypto()); + } + + MockDTLSServer(TlsCrypto crypto) + { + super(crypto); } public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Throwable cause) diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockPSKDTLSClient.java b/tls/src/test/java/org/bouncycastle/tls/test/MockPSKDTLSClient.java index 26db19ad0e..7eb0f0b2cb 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockPSKDTLSClient.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockPSKDTLSClient.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.PrintStream; -import java.security.SecureRandom; import java.util.Hashtable; import org.bouncycastle.asn1.x509.Certificate; @@ -38,7 +37,7 @@ class MockPSKDTLSClient MockPSKDTLSClient(TlsSession session, TlsPSKIdentity pskIdentity) { - super(new BcTlsCrypto(new SecureRandom()), pskIdentity); + super(new BcTlsCrypto(), pskIdentity); this.session = session; } diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockPSKDTLSServer.java b/tls/src/test/java/org/bouncycastle/tls/test/MockPSKDTLSServer.java index db7473ec54..453887e30e 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockPSKDTLSServer.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockPSKDTLSServer.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.PrintStream; -import java.security.SecureRandom; import java.util.Hashtable; import org.bouncycastle.tls.AlertDescription; @@ -23,7 +22,7 @@ class MockPSKDTLSServer { MockPSKDTLSServer() { - super(new BcTlsCrypto(new SecureRandom()), new MyIdentityManager()); + super(new BcTlsCrypto(), new MyIdentityManager()); } public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Throwable cause) diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTls13Client.java b/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTls13Client.java index 10d9a2dc7c..d6a3e515f9 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTls13Client.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTls13Client.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.PrintStream; -import java.security.SecureRandom; import java.util.Hashtable; import java.util.Vector; @@ -27,7 +26,7 @@ class MockPSKTls13Client { MockPSKTls13Client() { - super(new BcTlsCrypto(new SecureRandom())); + super(new BcTlsCrypto()); } // public Vector getEarlyKeyShareGroups() diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTls13Server.java b/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTls13Server.java index c96722c414..54ed274df8 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTls13Server.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTls13Server.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.PrintStream; -import java.security.SecureRandom; import java.util.Hashtable; import java.util.Vector; @@ -28,7 +27,7 @@ class MockPSKTls13Server { MockPSKTls13Server() { - super(new BcTlsCrypto(new SecureRandom())); + super(new BcTlsCrypto()); } public TlsCredentials getCredentials() throws IOException diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTlsClient.java b/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTlsClient.java index 50ddd38ddb..99261f1d32 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTlsClient.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTlsClient.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.PrintStream; -import java.security.SecureRandom; import java.util.Hashtable; import java.util.Vector; @@ -41,7 +40,7 @@ class MockPSKTlsClient MockPSKTlsClient(TlsSession session, TlsPSKIdentity pskIdentity) { - super(new BcTlsCrypto(new SecureRandom()), pskIdentity); + super(new BcTlsCrypto(), pskIdentity); this.session = session; } diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTlsServer.java b/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTlsServer.java index aef6479e0b..69bdfd20f3 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTlsServer.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockPSKTlsServer.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.PrintStream; -import java.security.SecureRandom; import java.util.Hashtable; import java.util.Vector; @@ -24,7 +23,7 @@ class MockPSKTlsServer { MockPSKTlsServer() { - super(new BcTlsCrypto(new SecureRandom()), new MyIdentityManager()); + super(new BcTlsCrypto(), new MyIdentityManager()); } protected Vector getProtocolNames() diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockRawKeysTlsClient.java b/tls/src/test/java/org/bouncycastle/tls/test/MockRawKeysTlsClient.java index 88ac63be89..05a41ce611 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockRawKeysTlsClient.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockRawKeysTlsClient.java @@ -1,7 +1,6 @@ package org.bouncycastle.tls.test; import java.io.IOException; -import java.security.SecureRandom; import java.util.Vector; import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; @@ -44,7 +43,7 @@ class MockRawKeysTlsClient short[] offerClientCertTypes, Ed25519PrivateKeyParameters privateKey, ProtocolVersion tlsVersion) throws Exception { - super(new BcTlsCrypto(new SecureRandom())); + super(new BcTlsCrypto()); this.serverCertType = serverCertType; this.clientCertType = clientCertType; diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockRawKeysTlsServer.java b/tls/src/test/java/org/bouncycastle/tls/test/MockRawKeysTlsServer.java index 0c0ccbc24d..184fbe8635 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockRawKeysTlsServer.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockRawKeysTlsServer.java @@ -1,7 +1,6 @@ package org.bouncycastle.tls.test; import java.io.IOException; -import java.security.SecureRandom; import java.util.Hashtable; import java.util.Vector; @@ -42,7 +41,7 @@ class MockRawKeysTlsServer extends DefaultTlsServer MockRawKeysTlsServer(short serverCertType, short clientCertType, short[] allowedClientCertTypes, Ed25519PrivateKeyParameters privateKey, ProtocolVersion tlsVersion) throws Exception { - super(new BcTlsCrypto(new SecureRandom())); + super(new BcTlsCrypto()); this.serverCertType = serverCertType; this.clientCertType = clientCertType; diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockSRPTlsClient.java b/tls/src/test/java/org/bouncycastle/tls/test/MockSRPTlsClient.java index ee71acb08e..bafec7bd69 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockSRPTlsClient.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockSRPTlsClient.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.PrintStream; -import java.security.SecureRandom; import java.util.Hashtable; import java.util.Vector; @@ -34,7 +33,7 @@ class MockSRPTlsClient MockSRPTlsClient(TlsSession session, TlsSRPIdentity srpIdentity) { - super(new BcTlsCrypto(new SecureRandom()), srpIdentity); + super(new BcTlsCrypto(), srpIdentity); this.session = session; } diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockSRPTlsServer.java b/tls/src/test/java/org/bouncycastle/tls/test/MockSRPTlsServer.java index f64b5b29a2..3b01c4c1fa 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockSRPTlsServer.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockSRPTlsServer.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.io.PrintStream; import java.math.BigInteger; -import java.security.SecureRandom; import java.util.Hashtable; import java.util.Vector; @@ -45,7 +44,13 @@ class MockSRPTlsServer MockSRPTlsServer() throws IOException { - super(new BcTlsCrypto(new SecureRandom()), new MyIdentityManager(new BcTlsCrypto(new SecureRandom()))); + this(new BcTlsCrypto()); + } + + MockSRPTlsServer(TlsCrypto crypto) + throws IOException + { + super(crypto, new MyIdentityManager(crypto)); } protected Vector getProtocolNames() diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockTlsClient.java b/tls/src/test/java/org/bouncycastle/tls/test/MockTlsClient.java index f5ba98f99a..5adb80ab24 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockTlsClient.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockTlsClient.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.PrintStream; -import java.security.SecureRandom; import java.util.Hashtable; import java.util.Vector; @@ -36,7 +35,7 @@ class MockTlsClient MockTlsClient(TlsSession session) { - super(new BcTlsCrypto(new SecureRandom())); + super(new BcTlsCrypto()); this.session = session; } diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockTlsKemClient.java b/tls/src/test/java/org/bouncycastle/tls/test/MockTlsKemClient.java new file mode 100644 index 0000000000..a69fbf77ce --- /dev/null +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockTlsKemClient.java @@ -0,0 +1,243 @@ +package org.bouncycastle.tls.test; + +import java.io.IOException; +import java.io.PrintStream; +import java.util.Hashtable; +import java.util.Vector; + +import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.tls.AlertDescription; +import org.bouncycastle.tls.AlertLevel; +import org.bouncycastle.tls.CertificateRequest; +import org.bouncycastle.tls.ChannelBinding; +import org.bouncycastle.tls.ClientCertificateType; +import org.bouncycastle.tls.DefaultTlsClient; +import org.bouncycastle.tls.MaxFragmentLength; +import org.bouncycastle.tls.NamedGroup; +import org.bouncycastle.tls.NamedGroupRole; +import org.bouncycastle.tls.ProtocolName; +import org.bouncycastle.tls.ProtocolVersion; +import org.bouncycastle.tls.SignatureAlgorithm; +import org.bouncycastle.tls.TlsAuthentication; +import org.bouncycastle.tls.TlsCredentials; +import org.bouncycastle.tls.TlsExtensionsUtils; +import org.bouncycastle.tls.TlsFatalAlert; +import org.bouncycastle.tls.TlsServerCertificate; +import org.bouncycastle.tls.TlsSession; +import org.bouncycastle.tls.TlsUtils; +import org.bouncycastle.tls.crypto.TlsCertificate; +import org.bouncycastle.tls.crypto.TlsCrypto; +import org.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Integers; +import org.bouncycastle.util.encoders.Hex; + +class MockTlsKemClient + extends DefaultTlsClient +{ + TlsSession session; + + MockTlsKemClient(TlsSession session) + { + super(new BcTlsCrypto()); + + this.session = session; + } + + protected Vector getProtocolNames() + { + Vector protocolNames = new Vector(); + protocolNames.addElement(ProtocolName.HTTP_1_1); + protocolNames.addElement(ProtocolName.HTTP_2_TLS); + return protocolNames; + } + + public int[] supportedGroups = new int[] { + NamedGroup.OQS_mlkem512, + NamedGroup.OQS_mlkem768, + NamedGroup.OQS_mlkem1024 + }; + + public void setSupportedGroups(int[] supportedGroups) + { + this.supportedGroups = supportedGroups; + } + + protected Vector getSupportedGroups(Vector namedGroupRoles) { + TlsCrypto crypto = getCrypto(); + Vector supportedGroups = new Vector(); + + if (namedGroupRoles.contains(Integers.valueOf(NamedGroupRole.kem))) { + TlsUtils.addIfSupported(supportedGroups, crypto, + this.supportedGroups); + }; + return supportedGroups; + } + + public TlsSession getSessionToResume() + { + return this.session; + } + + public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Throwable cause) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("TLS client raised alert: " + AlertLevel.getText(alertLevel) + + ", " + AlertDescription.getText(alertDescription)); + if (message != null) + { + out.println("> " + message); + } + if (cause != null) + { + cause.printStackTrace(out); + } + } + + public void notifyAlertReceived(short alertLevel, short alertDescription) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("TLS KEM client received alert: " + AlertLevel.getText(alertLevel) + + ", " + AlertDescription.getText(alertDescription)); + } + + public Hashtable getClientExtensions() throws IOException + { + if (context.getSecurityParametersHandshake().getClientRandom() == null) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + Hashtable clientExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(super.getClientExtensions()); + { + /* + * NOTE: If you are copying test code, do not blindly set these extensions in your own client. + */ + TlsExtensionsUtils.addMaxFragmentLengthExtension(clientExtensions, MaxFragmentLength.pow2_9); + TlsExtensionsUtils.addPaddingExtension(clientExtensions, context.getCrypto().getSecureRandom().nextInt(16)); + TlsExtensionsUtils.addTruncatedHMacExtension(clientExtensions); + } + return clientExtensions; + } + + public void notifyServerVersion(ProtocolVersion serverVersion) throws IOException + { + super.notifyServerVersion(serverVersion); + + System.out.println("TLS KEM client negotiated " + serverVersion); + } + + public TlsAuthentication getAuthentication() throws IOException + { + return new TlsAuthentication() + { + public void notifyServerCertificate(TlsServerCertificate serverCertificate) throws IOException + { + TlsCertificate[] chain = serverCertificate.getCertificate().getCertificateList(); + + System.out.println("TLS KEM client received server certificate chain of length " + chain.length); + for (int i = 0; i != chain.length; i++) + { + Certificate entry = Certificate.getInstance(chain[i].getEncoded()); + // TODO Create fingerprint based on certificate signature algorithm digest + System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" + + entry.getSubject() + ")"); + } + + boolean isEmpty = serverCertificate == null || serverCertificate.getCertificate() == null + || serverCertificate.getCertificate().isEmpty(); + + if (isEmpty) + { + throw new TlsFatalAlert(AlertDescription.bad_certificate); + } + + String[] trustedCertResources = new String[]{ "x509-server-dsa.pem", "x509-server-ecdh.pem", + "x509-server-ecdsa.pem", "x509-server-ed25519.pem", "x509-server-ed448.pem", + "x509-server-rsa_pss_256.pem", "x509-server-rsa_pss_384.pem", "x509-server-rsa_pss_512.pem", + "x509-server-rsa-enc.pem", "x509-server-rsa-sign.pem" }; + + TlsCertificate[] certPath = TlsTestUtils.getTrustedCertPath(context.getCrypto(), chain[0], + trustedCertResources); + + if (null == certPath) + { + throw new TlsFatalAlert(AlertDescription.bad_certificate); + } + + TlsUtils.checkPeerSigAlgs(context, certPath); + } + + public TlsCredentials getClientCredentials(CertificateRequest certificateRequest) throws IOException + { + short[] certificateTypes = certificateRequest.getCertificateTypes(); + if (certificateTypes == null || !Arrays.contains(certificateTypes, ClientCertificateType.rsa_sign)) + { + return null; + } + + return TlsTestUtils.loadSignerCredentials(context, certificateRequest.getSupportedSignatureAlgorithms(), + SignatureAlgorithm.rsa, "x509-client-rsa.pem", "x509-client-key-rsa.pem"); + } + }; + } + + public void notifyHandshakeComplete() throws IOException + { + super.notifyHandshakeComplete(); + + ProtocolName protocolName = context.getSecurityParametersConnection().getApplicationProtocol(); + if (protocolName != null) + { + System.out.println("KEM Client ALPN: " + protocolName.getUtf8Decoding()); + } + + TlsSession newSession = context.getSession(); + if (newSession != null) + { + if (newSession.isResumable()) + { + byte[] newSessionID = newSession.getSessionID(); + String hex = hex(newSessionID); + + if (this.session != null && Arrays.areEqual(this.session.getSessionID(), newSessionID)) + { + System.out.println("KEM Client resumed session: " + hex); + } + else + { + System.out.println("KEM Client established session: " + hex); + } + + this.session = newSession; + } + + byte[] tlsServerEndPoint = context.exportChannelBinding(ChannelBinding.tls_server_end_point); + if (null != tlsServerEndPoint) + { + System.out.println("KEM Client 'tls-server-end-point': " + hex(tlsServerEndPoint)); + } + + byte[] tlsUnique = context.exportChannelBinding(ChannelBinding.tls_unique); + System.out.println("KEM Client 'tls-unique': " + hex(tlsUnique)); + + byte[] tlsExporter = context.exportChannelBinding(ChannelBinding.tls_exporter); + System.out.println("KEM Client 'tls-exporter': " + hex(tlsExporter)); + } + } + + public void processServerExtensions(Hashtable serverExtensions) throws IOException + { + if (context.getSecurityParametersHandshake().getServerRandom() == null) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + super.processServerExtensions(serverExtensions); + } + + protected String hex(byte[] data) + { + return data == null ? "(null)" : Hex.toHexString(data); + } +} \ No newline at end of file diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockTlsKemServer.java b/tls/src/test/java/org/bouncycastle/tls/test/MockTlsKemServer.java new file mode 100644 index 0000000000..198f3a826d --- /dev/null +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockTlsKemServer.java @@ -0,0 +1,243 @@ +package org.bouncycastle.tls.test; + +import java.io.IOException; +import java.io.PrintStream; +import java.util.Hashtable; +import java.util.Vector; + +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.tls.AlertDescription; +import org.bouncycastle.tls.AlertLevel; +import org.bouncycastle.tls.CertificateRequest; +import org.bouncycastle.tls.ChannelBinding; +import org.bouncycastle.tls.ClientCertificateType; +import org.bouncycastle.tls.DefaultTlsServer; +import org.bouncycastle.tls.NamedGroup; +import org.bouncycastle.tls.ProtocolName; +import org.bouncycastle.tls.ProtocolVersion; +import org.bouncycastle.tls.SignatureAlgorithm; +import org.bouncycastle.tls.TlsCredentialedDecryptor; +import org.bouncycastle.tls.TlsCredentialedSigner; +import org.bouncycastle.tls.TlsCredentials; +import org.bouncycastle.tls.TlsFatalAlert; +import org.bouncycastle.tls.TlsUtils; +import org.bouncycastle.tls.crypto.TlsCertificate; +import org.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto; +import org.bouncycastle.util.encoders.Hex; + +class MockTlsKemServer + extends DefaultTlsServer +{ + MockTlsKemServer() + { + super(new BcTlsCrypto()); + } + + protected Vector getProtocolNames() + { + Vector protocolNames = new Vector(); + protocolNames.addElement(ProtocolName.HTTP_2_TLS); + protocolNames.addElement(ProtocolName.HTTP_1_1); + return protocolNames; + } + + public int[] supportedGroups = new int[] { + NamedGroup.OQS_mlkem512, + NamedGroup.OQS_mlkem768, + NamedGroup.OQS_mlkem1024, + NamedGroup.x25519 + }; + + public void setSupportedGroups(int[] supportedGroups) + { + this.supportedGroups = supportedGroups; + } + + public int[] getSupportedGroups() throws IOException { + return supportedGroups; + } + + public TlsCredentials getCredentials() throws IOException + { + /* + * TODO[tls13] Should really be finding the first client-supported signature scheme that the + * server also supports and has credentials for. + */ + if (TlsUtils.isTLSv13(context)) + { + return getRSASignerCredentials(); + } + + return super.getCredentials(); + } + + public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Throwable cause) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("TLS KEM server raised alert: " + AlertLevel.getText(alertLevel) + + ", " + AlertDescription.getText(alertDescription)); + if (message != null) + { + out.println("> " + message); + } + if (cause != null) + { + cause.printStackTrace(out); + } + } + + public void notifyAlertReceived(short alertLevel, short alertDescription) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("TLS KEM server received alert: " + AlertLevel.getText(alertLevel) + + ", " + AlertDescription.getText(alertDescription)); + } + + public ProtocolVersion getServerVersion() throws IOException + { + ProtocolVersion serverVersion = super.getServerVersion(); + + System.out.println("TLS KEM server negotiated " + serverVersion); + + return serverVersion; + } + + public CertificateRequest getCertificateRequest() throws IOException + { + Vector serverSigAlgs = null; + if (TlsUtils.isSignatureAlgorithmsExtensionAllowed(context.getServerVersion())) + { + serverSigAlgs = TlsUtils.getDefaultSupportedSignatureAlgorithms(context); + } + + Vector certificateAuthorities = new Vector(); +// certificateAuthorities.addElement(TlsTestUtils.loadBcCertificateResource("x509-ca-dsa.pem").getSubject()); +// certificateAuthorities.addElement(TlsTestUtils.loadBcCertificateResource("x509-ca-ecdsa.pem").getSubject()); +// certificateAuthorities.addElement(TlsTestUtils.loadBcCertificateResource("x509-ca-rsa.pem").getSubject()); + + // All the CA certificates are currently configured with this subject + certificateAuthorities.addElement(new X500Name("CN=BouncyCastle TLS Test CA")); + + if (TlsUtils.isTLSv13(context)) + { + // TODO[tls13] Support for non-empty request context + byte[] certificateRequestContext = TlsUtils.EMPTY_BYTES; + + // TODO[tls13] Add TlsTestConfig.serverCertReqSigAlgsCert + Vector serverSigAlgsCert = null; + + return new CertificateRequest(certificateRequestContext, serverSigAlgs, serverSigAlgsCert, + certificateAuthorities); + } + else + { + short[] certificateTypes = new short[]{ ClientCertificateType.rsa_sign, + ClientCertificateType.dss_sign, ClientCertificateType.ecdsa_sign }; + + return new CertificateRequest(certificateTypes, serverSigAlgs, certificateAuthorities); + } + } + + public void notifyClientCertificate(org.bouncycastle.tls.Certificate clientCertificate) throws IOException + { + TlsCertificate[] chain = clientCertificate.getCertificateList(); + + System.out.println("TLS KEM server received client certificate chain of length " + chain.length); + for (int i = 0; i != chain.length; i++) + { + Certificate entry = Certificate.getInstance(chain[i].getEncoded()); + // TODO Create fingerprint based on certificate signature algorithm digest + System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" + + entry.getSubject() + ")"); + } + + boolean isEmpty = (clientCertificate == null || clientCertificate.isEmpty()); + + if (isEmpty) + { + return; + } + + String[] trustedCertResources = new String[]{ "x509-client-dsa.pem", "x509-client-ecdh.pem", + "x509-client-ecdsa.pem", "x509-client-ed25519.pem", "x509-client-ed448.pem", "x509-client-rsa_pss_256.pem", + "x509-client-rsa_pss_384.pem", "x509-client-rsa_pss_512.pem", "x509-client-rsa.pem" }; + + TlsCertificate[] certPath = TlsTestUtils.getTrustedCertPath(context.getCrypto(), chain[0], + trustedCertResources); + + if (null == certPath) + { + throw new TlsFatalAlert(AlertDescription.bad_certificate); + } + + TlsUtils.checkPeerSigAlgs(context, certPath); + } + + public void notifyHandshakeComplete() throws IOException + { + super.notifyHandshakeComplete(); + + ProtocolName protocolName = context.getSecurityParametersConnection().getApplicationProtocol(); + if (protocolName != null) + { + System.out.println("KEM Server ALPN: " + protocolName.getUtf8Decoding()); + } + + byte[] tlsServerEndPoint = context.exportChannelBinding(ChannelBinding.tls_server_end_point); + System.out.println("KEM Server 'tls-server-end-point': " + hex(tlsServerEndPoint)); + + byte[] tlsUnique = context.exportChannelBinding(ChannelBinding.tls_unique); + System.out.println("KEM Server 'tls-unique': " + hex(tlsUnique)); + + byte[] tlsExporter = context.exportChannelBinding(ChannelBinding.tls_exporter); + System.out.println("KEM Server 'tls-exporter': " + hex(tlsExporter)); + } + + public void processClientExtensions(Hashtable clientExtensions) throws IOException + { + if (context.getSecurityParametersHandshake().getClientRandom() == null) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + super.processClientExtensions(clientExtensions); + } + + public Hashtable getServerExtensions() throws IOException + { + if (context.getSecurityParametersHandshake().getServerRandom() == null) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + return super.getServerExtensions(); + } + + public void getServerExtensionsForConnection(Hashtable serverExtensions) throws IOException + { + if (context.getSecurityParametersHandshake().getServerRandom() == null) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + super.getServerExtensionsForConnection(serverExtensions); + } + + protected TlsCredentialedDecryptor getRSAEncryptionCredentials() throws IOException + { + return TlsTestUtils.loadEncryptionCredentials(context, new String[]{ "x509-server-rsa-enc.pem", "x509-ca-rsa.pem" }, + "x509-server-key-rsa-enc.pem"); + } + + protected TlsCredentialedSigner getRSASignerCredentials() throws IOException + { + Vector clientSigAlgs = context.getSecurityParametersHandshake().getClientSigAlgs(); + return TlsTestUtils.loadSignerCredentialsServer(context, clientSigAlgs, SignatureAlgorithm.rsa); + } + + protected String hex(byte[] data) + { + return data == null ? "(null)" : Hex.toHexString(data); + } +} \ No newline at end of file diff --git a/tls/src/test/java/org/bouncycastle/tls/test/MockTlsServer.java b/tls/src/test/java/org/bouncycastle/tls/test/MockTlsServer.java index b7b68382cb..a60001980b 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/MockTlsServer.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/MockTlsServer.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.PrintStream; -import java.security.SecureRandom; import java.util.Hashtable; import java.util.Vector; @@ -31,7 +30,7 @@ class MockTlsServer { MockTlsServer() { - super(new BcTlsCrypto(new SecureRandom())); + super(new BcTlsCrypto()); } protected Vector getProtocolNames() diff --git a/tls/src/test/java/org/bouncycastle/tls/test/PRFTest.java b/tls/src/test/java/org/bouncycastle/tls/test/PRFTest.java index a7e0c1f602..bbac1779be 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/PRFTest.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/PRFTest.java @@ -30,7 +30,7 @@ public void testLwTLS11() byte[] msSeed = Arrays.concatenate(clientHello_random, serverHello_random); - BcTlsCrypto crypto = new BcTlsCrypto(new SecureRandom()); + BcTlsCrypto crypto = new BcTlsCrypto(); TlsSecret masterSecret = new BcTlsSecret(crypto, pre_master_secret) .deriveUsingPRF(PRFAlgorithm.tls_prf_legacy, ExporterLabel.master_secret, msSeed, master_secret.length); @@ -56,7 +56,7 @@ public void testLwTLS12_SHA256PRF() byte[] msSeed = Arrays.concatenate(clientHello_random, serverHello_random); - BcTlsCrypto crypto = new BcTlsCrypto(new SecureRandom()); + BcTlsCrypto crypto = new BcTlsCrypto(); TlsSecret masterSecret = new BcTlsSecret(crypto, pre_master_secret) .deriveUsingPRF(PRFAlgorithm.tls_prf_sha256, ExporterLabel.master_secret, msSeed, master_secret.length); @@ -82,7 +82,7 @@ public void testLwTLS12_SHA384PRF() byte[] msSeed = Arrays.concatenate(clientHello_random, serverHello_random); - BcTlsCrypto crypto = new BcTlsCrypto(new SecureRandom()); + BcTlsCrypto crypto = new BcTlsCrypto(); TlsSecret masterSecret = new BcTlsSecret(crypto, pre_master_secret) .deriveUsingPRF(PRFAlgorithm.tls_prf_sha384, ExporterLabel.master_secret, msSeed, master_secret.length); diff --git a/tls/src/test/java/org/bouncycastle/tls/test/PSKTls13ClientTest.java b/tls/src/test/java/org/bouncycastle/tls/test/PSKTls13ClientTest.java index 79cdab434f..06f183193e 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/PSKTls13ClientTest.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/PSKTls13ClientTest.java @@ -10,6 +10,7 @@ import org.bouncycastle.tls.TlsClient; import org.bouncycastle.tls.TlsClientProtocol; +import org.bouncycastle.util.Strings; public class PSKTls13ClientTest { @@ -27,7 +28,7 @@ public static void main(String[] args) throws Exception System.out.println("Elapsed: " + (time1 - time0) + "ms"); OutputStream output = protocol.getOutputStream(); - output.write("GET / HTTP/1.1\r\n\r\n".getBytes("UTF-8")); + output.write(Strings.toUTF8ByteArray("GET / HTTP/1.1\r\n\r\n")); output.flush(); InputStream input = protocol.getInputStream(); diff --git a/tls/src/test/java/org/bouncycastle/tls/test/PSKTlsClientTest.java b/tls/src/test/java/org/bouncycastle/tls/test/PSKTlsClientTest.java index 0187ef2d28..c8eb43ffab 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/PSKTlsClientTest.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/PSKTlsClientTest.java @@ -59,7 +59,7 @@ public static void main(String[] args) throws Exception System.out.println("Elapsed 2: " + (time3 - time2) + "ms"); OutputStream output = protocol.getOutputStream(); - output.write("GET / HTTP/1.1\r\n\r\n".getBytes("UTF-8")); + output.write(Strings.toUTF8ByteArray("GET / HTTP/1.1\r\n\r\n")); output.flush(); InputStream input = protocol.getInputStream(); diff --git a/tls/src/test/java/org/bouncycastle/tls/test/ServerHandshakeDropper.java b/tls/src/test/java/org/bouncycastle/tls/test/ServerHandshakeDropper.java new file mode 100644 index 0000000000..9f247378b9 --- /dev/null +++ b/tls/src/test/java/org/bouncycastle/tls/test/ServerHandshakeDropper.java @@ -0,0 +1,60 @@ +package org.bouncycastle.tls.test; + +import org.bouncycastle.tls.ContentType; +import org.bouncycastle.tls.DatagramTransport; +import org.bouncycastle.tls.TlsUtils; + +/** This is a [Transport] wrapper which causes the first retransmission of the second flight of a server + * handshake to be dropped. */ +public class ServerHandshakeDropper extends FilteredDatagramTransport +{ + public ServerHandshakeDropper(DatagramTransport transport, boolean dropOnReceive) + { + super(transport, + dropOnReceive ? new DropFirstServerFinalFlight() : ALWAYS_ALLOW, + dropOnReceive ? ALWAYS_ALLOW : new DropFirstServerFinalFlight() + ); + } + + /** This drops the first instance of DTLS packets that either begin with a ChangeCipherSpec, or handshake in + * epoch 1. This is the server's final flight of the handshake. It will test whether the client properly + * retransmits its second flight, and the server properly retransmits the dropped flight. + */ + private static class DropFirstServerFinalFlight implements FilteredDatagramTransport.FilterPredicate { + + boolean sawChangeCipherSpec = false; + boolean sawEpoch1Handshake = false; + + private boolean isChangeCipherSpec(byte[] buf, int off, int len) + { + short contentType = TlsUtils.readUint8(buf, off); + return ContentType.change_cipher_spec == contentType; + } + + private boolean isEpoch1Handshake(byte[] buf, int off, int len) + { + short contentType = TlsUtils.readUint8(buf, off); + if (ContentType.handshake != contentType) + { + return false; + } + + int epoch = TlsUtils.readUint16(buf, off + 3); + return 1 == epoch; + } + + public boolean allowPacket(byte[] buf, int off, int len) + { + if (!sawChangeCipherSpec && isChangeCipherSpec(buf, off, len)) + { + sawChangeCipherSpec = true; + return false; + } + if (!sawEpoch1Handshake && isEpoch1Handshake(buf, off, len)) { + sawEpoch1Handshake = true; + return false; + } + return true; + } + } +} diff --git a/tls/src/test/java/org/bouncycastle/tls/test/TlsClientRawKeysTest.java b/tls/src/test/java/org/bouncycastle/tls/test/TlsClientRawKeysTest.java index f54d5028e3..7f932947da 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/TlsClientRawKeysTest.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/TlsClientRawKeysTest.java @@ -14,6 +14,7 @@ import org.bouncycastle.tls.ProtocolVersion; import org.bouncycastle.tls.TlsClient; import org.bouncycastle.tls.TlsClientProtocol; +import org.bouncycastle.util.Strings; /** * A simple test designed to conduct a TLS handshake with an external TLS server. @@ -46,7 +47,7 @@ static void runTest(InetAddress address, int port, ProtocolVersion tlsVersion) t TlsClientProtocol protocol = openTlsConnection(address, port, client); OutputStream output = protocol.getOutputStream(); - output.write("GET / HTTP/1.1\r\n\r\n".getBytes("UTF-8")); + output.write(Strings.toUTF8ByteArray("GET / HTTP/1.1\r\n\r\n")); output.flush(); InputStream input = protocol.getInputStream(); diff --git a/tls/src/test/java/org/bouncycastle/tls/test/TlsClientTest.java b/tls/src/test/java/org/bouncycastle/tls/test/TlsClientTest.java index c4da9cf7e5..ebf09805bc 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/TlsClientTest.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/TlsClientTest.java @@ -10,6 +10,7 @@ import org.bouncycastle.tls.TlsClient; import org.bouncycastle.tls.TlsClientProtocol; +import org.bouncycastle.util.Strings; /** * A simple test designed to conduct a TLS handshake with an external TLS server. @@ -42,7 +43,7 @@ public static void main(String[] args) System.out.println("Elapsed 2: " + (time3 - time2) + "ms"); OutputStream output = protocol.getOutputStream(); - output.write("GET / HTTP/1.1\r\n\r\n".getBytes("UTF-8")); + output.write(Strings.toUTF8ByteArray("GET / HTTP/1.1\r\n\r\n")); output.flush(); InputStream input = protocol.getInputStream(); diff --git a/tls/src/test/java/org/bouncycastle/tls/test/TlsProtocolKemTest.java b/tls/src/test/java/org/bouncycastle/tls/test/TlsProtocolKemTest.java new file mode 100644 index 0000000000..358edd16f4 --- /dev/null +++ b/tls/src/test/java/org/bouncycastle/tls/test/TlsProtocolKemTest.java @@ -0,0 +1,144 @@ +package org.bouncycastle.tls.test; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; + +import org.bouncycastle.tls.NamedGroup; +import org.bouncycastle.tls.TlsClientProtocol; +import org.bouncycastle.tls.TlsServerProtocol; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.io.Streams; + +import junit.framework.TestCase; + +public class TlsProtocolKemTest + extends TestCase +{ + + // mismatched ML-KEM strengths w/o classical crypto + public void testMismatchStrength() throws Exception + { + PipedInputStream clientRead = TlsTestUtils.createPipedInputStream(); + PipedInputStream serverRead = TlsTestUtils.createPipedInputStream(); + PipedOutputStream clientWrite = new PipedOutputStream(serverRead); + PipedOutputStream serverWrite = new PipedOutputStream(clientRead); + + TlsClientProtocol clientProtocol = new TlsClientProtocol(clientRead, clientWrite); + TlsServerProtocol serverProtocol = new TlsServerProtocol(serverRead, serverWrite); + + ServerThread serverThread = new ServerThread(serverProtocol, new int[] {NamedGroup.OQS_mlkem768}, true); + try + { + serverThread.start(); + } + catch (Exception ignored) + { + } + MockTlsKemClient client = new MockTlsKemClient(null); + client.setSupportedGroups(new int[] {NamedGroup.OQS_mlkem512}); + try + { + clientProtocol.connect(client); + fail(); + } + catch (Exception ex) + { + } + + serverThread.join(); + } + + public void testClientServer() throws Exception + { + PipedInputStream clientRead = TlsTestUtils.createPipedInputStream(); + PipedInputStream serverRead = TlsTestUtils.createPipedInputStream(); + PipedOutputStream clientWrite = new PipedOutputStream(serverRead); + PipedOutputStream serverWrite = new PipedOutputStream(clientRead); + + TlsClientProtocol clientProtocol = new TlsClientProtocol(clientRead, clientWrite); + TlsServerProtocol serverProtocol = new TlsServerProtocol(serverRead, serverWrite); + + ServerThread serverThread = new ServerThread(serverProtocol, false); + serverThread.start(); + + MockTlsKemClient client = new MockTlsKemClient(null); + clientProtocol.connect(client); + + // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity + int length = 1000; + + byte[] data = new byte[length]; + client.getCrypto().getSecureRandom().nextBytes(data); + + OutputStream output = clientProtocol.getOutputStream(); + output.write(data); + + byte[] echo = new byte[data.length]; + int count = Streams.readFully(clientProtocol.getInputStream(), echo); + + assertEquals(count, data.length); + assertTrue(Arrays.areEqual(data, echo)); + + output.close(); + + serverThread.join(); + } + + static class ServerThread + extends Thread + { + private final TlsServerProtocol serverProtocol; + private final int[] supportedGroups; + + private boolean shouldFail = false; + + ServerThread(TlsServerProtocol serverProtocol, int[] supportedGroups, boolean fail) + { + this.serverProtocol = serverProtocol; + this.supportedGroups = supportedGroups; + this.shouldFail = fail; + } + ServerThread(TlsServerProtocol serverProtocol, boolean fail) + { + this.serverProtocol = serverProtocol; + this.supportedGroups = null; + this.shouldFail = fail; + } + + public void run() + { + try + { + MockTlsKemServer server = new MockTlsKemServer(); + if (supportedGroups != null) + { + server.setSupportedGroups(supportedGroups); + } + + try + { + serverProtocol.accept(server); + if (shouldFail) + { + fail(); + } + } + catch (IOException ignored) + { + if (!shouldFail) + { + fail(); + } + } + + Streams.pipeAll(serverProtocol.getInputStream(), serverProtocol.getOutputStream()); + serverProtocol.close(); + } + catch (Exception e) + { + } + } + } +} \ No newline at end of file diff --git a/tls/src/test/java/org/bouncycastle/tls/test/TlsTestSuite.java b/tls/src/test/java/org/bouncycastle/tls/test/TlsTestSuite.java index 03d3e00b52..9ee15d6df1 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/TlsTestSuite.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/TlsTestSuite.java @@ -4,8 +4,6 @@ import java.security.Security; import java.util.Vector; -import junit.framework.Test; -import junit.framework.TestSuite; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.tls.AlertDescription; import org.bouncycastle.tls.HashAlgorithm; @@ -16,12 +14,16 @@ import org.bouncycastle.tls.TlsUtils; import org.bouncycastle.tls.crypto.TlsCrypto; import org.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto; +import org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto; import org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCryptoProvider; +import junit.framework.Test; +import junit.framework.TestSuite; + public class TlsTestSuite extends TestSuite { - static TlsCrypto BC_CRYPTO = new BcTlsCrypto(new SecureRandom()); - static TlsCrypto JCA_CRYPTO = new JcaTlsCryptoProvider().setProvider(new BouncyCastleProvider()).create(new SecureRandom()); + static BcTlsCrypto BC_CRYPTO = new BcTlsCrypto(); + static JcaTlsCrypto JCA_CRYPTO = (JcaTlsCrypto)new JcaTlsCryptoProvider().setProvider(new BouncyCastleProvider()).create(new SecureRandom()); static TlsCrypto getCrypto(TlsTestConfig config) { diff --git a/tls/src/test/java/org/bouncycastle/tls/test/TlsTestUtils.java b/tls/src/test/java/org/bouncycastle/tls/test/TlsTestUtils.java index f350697759..918983da2a 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/TlsTestUtils.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/TlsTestUtils.java @@ -197,6 +197,11 @@ static String getResourceName(short signatureAlgorithm) throws IOException return "rsa_pss_384"; case SignatureAlgorithm.rsa_pss_pss_sha512: return "rsa_pss_512"; + + // TODO[RFC 9189] Choose names here and apply reverse mappings in getCACertResource(String) + case SignatureAlgorithm.gostr34102012_256: + case SignatureAlgorithm.gostr34102012_512: + default: throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -409,7 +414,7 @@ static AsymmetricKeyParameter loadBcPrivateKeyResource(String resource) if (pem.getType().equals("EC PRIVATE KEY")) { ECPrivateKey pKey = ECPrivateKey.getInstance(pem.getContent()); - AlgorithmIdentifier algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, pKey.getParameters()); + AlgorithmIdentifier algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, pKey.getParametersObject()); PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey); return PrivateKeyFactory.createKey(privInfo); } diff --git a/tls/src/test/java/org/bouncycastle/tls/test/UnreliableDatagramTransport.java b/tls/src/test/java/org/bouncycastle/tls/test/UnreliableDatagramTransport.java index b8a55b0263..d194fafedb 100644 --- a/tls/src/test/java/org/bouncycastle/tls/test/UnreliableDatagramTransport.java +++ b/tls/src/test/java/org/bouncycastle/tls/test/UnreliableDatagramTransport.java @@ -47,7 +47,7 @@ public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { long endMillis = System.currentTimeMillis() + waitMillis; - for (; ; ) + for (;;) { int length = transport.receive(buf, off, len, waitMillis); if (length < 0 || !lostPacket(percentPacketLossReceiving)) diff --git a/tls/src/test/jdk1.4/org/bouncycastle/test/JVMVersionTest.java b/tls/src/test/jdk1.4/org/bouncycastle/test/JVMVersionTest.java new file mode 100644 index 0000000000..6c5c9e011e --- /dev/null +++ b/tls/src/test/jdk1.4/org/bouncycastle/test/JVMVersionTest.java @@ -0,0 +1,43 @@ +package org.bouncycastle.test; + +import junit.framework.TestCase; + +/** + * This test asserts the java version running the tests starts with + * a property value passed in as part of test invocation. + * + * -Dtest.java.version.prefix must match the start of System.getProperty("java.version") + * So: + * if -Dtest.java.version.prefix=17 and System.getProperty("java.version") = 17.0.4.1 + * Then this test will pass. + */ +public class JVMVersionTest extends TestCase +{ + + private static final String expectedVersionPropName = "test.java.version.prefix"; + + public void testAssertExpectedJVM() { + + // + // This project produces a multi-release jar, and we need to test it on different jvm versions + // This test compares a property "test.java.version.prefix" with the start of the value reported by the JVM. + // eg: + // -Dtest.java.version.prefix=1.8 + // + // It exists because we have had issues with build systems unexpectedly using a different JVM to one we need to test on. + // It is important for multi-release jars to be exercised on a representative JVM for each JVM they support. + // + // + // not required +// String version = System.getProperty("java.version"); +// assertNotNull(String.format("property %s is not set, see comment in test for reason why.",expectedVersionPropName),System.getProperty(expectedVersionPropName)); +// +// +// +// String expectedPrefix = System.getProperty(expectedVersionPropName); +// +// TestCase.assertTrue(String.format("JVM Version: '%s' did not start with '%s' see comment in test",version,expectedPrefix), version.startsWith(expectedPrefix)); + + } + +} diff --git a/tls/src/test/jdk1.5/org/bouncycastle/jsse/provider/test/AllTests.java b/tls/src/test/jdk1.5/org/bouncycastle/jsse/provider/test/AllTests.java new file mode 100644 index 0000000000..887f0afeb6 --- /dev/null +++ b/tls/src/test/jdk1.5/org/bouncycastle/jsse/provider/test/AllTests.java @@ -0,0 +1,65 @@ +package org.bouncycastle.jsse.provider.test; + +import junit.extensions.TestSetup; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.bouncycastle.test.PrintTestResult; + +public class AllTests + extends TestCase +{ + public static void main(String[] args) + throws Exception + { + PrintTestResult.printResult( junit.textui.TestRunner.run(suite())); + } + + public static Test suite() + throws Exception + { + TestSuite suite = new TestSuite("JSSE tests"); +// +// suite.addTestSuite(BasicClientAuthTlsTest.class); +// suite.addTestSuite(BasicTlsTest.class); + suite.addTestSuite(ConfigTest.class); +// suite.addTestSuite(ECDSACredentialsTest.class); +// suite.addTestSuite(EdDSACredentialsTest.class); + suite.addTestSuite(InstanceTest.class); + suite.addTestSuite(KeyManagerFactoryTest.class); + + return new BCTestSetup(suite); + } + + static class BCTestSetup + extends TestSetup + { + public BCTestSetup(Test test) + { + super(test); + } + + protected void setUp() + { + + } + + protected void tearDown() + { + + } + } + + private static boolean hasClass(String name) + { + try + { + AllTests.class.getClassLoader().loadClass(name); + return true; + } + catch (Exception e) + { + return false; + } + } +} diff --git a/tls/src/test/jdk1.5/org/bouncycastle/test/JVMVersionTest.java b/tls/src/test/jdk1.5/org/bouncycastle/test/JVMVersionTest.java new file mode 100644 index 0000000000..4c90339564 --- /dev/null +++ b/tls/src/test/jdk1.5/org/bouncycastle/test/JVMVersionTest.java @@ -0,0 +1,38 @@ +package org.bouncycastle.test; + +import junit.framework.TestCase; + +/** + * This test asserts the java version running the tests starts with + * a property value passed in as part of test invocation. + *

      + * -Dtest.java.version.prefix must match the start of System.getProperty("java.version") + * So: + * if -Dtest.java.version.prefix=17 and System.getProperty("java.version") = 17.0.4.1 + * Then this test will pass. + */ +public class JVMVersionTest extends TestCase +{ + + private static final String expectedVersionPropName = "test.java.version.prefix"; + + + public void testAssertExpectedJVM() + { + + // + // This project produces a multi-release jar, and we need to test it on different jvm versions + // This test compares a property "test.java.version.prefix" with the start of the value reported by the JVM. + // eg: + // -Dtest.java.version.prefix=1.8 + // + // It exists because we have had issues with build systems unexpectedly using a different JVM to one we need to test on. + // It is important for multi-release jars to be exercised on a representative JVM for each JVM they support. + // + // + + // This is a NULL OPP on this JVM + + } + +} diff --git a/util/build.gradle b/util/build.gradle index f9b24cce45..31e96d4152 100644 --- a/util/build.gradle +++ b/util/build.gradle @@ -1,20 +1,93 @@ -dependencies { - implementation project(':core') - testImplementation group: 'junit', name: 'junit', version: '4.11' +plugins { + id "biz.aQute.bnd.builder" version "7.0.0" } jar.archiveBaseName = "bcutil-$vmrange" + +sourceSets { + java9 { + java { + srcDirs = ['src/main/jdk1.9'] + } + } + +} + + +dependencies { + implementation project(':core') + implementation project(':prov') + implementation files("${bc_prov}") + // implementation project(path: ':core') + implementation project(path: ':prov') + + testImplementation group: 'junit', name: 'junit', version: '4.11' + + java9Implementation files([sourceSets.main.output.classesDirs]) { + builtBy compileJava + } + java9Implementation project(':prov') + // java9Implementation project(':core') + java9Implementation project(path:':prov') + +} + +compileJava { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + targetCompatibility = 1.8; + sourceCompatibility = 1.8; +} + + +compileJava9Java { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + + options.compilerArgs += [ + '--module-path', "${bc_prov}" + ] + + sourceCompatibility = 9 + targetCompatibility = 9 + options.sourcepath = files(['src/main/java', 'src/main/jdk1.9']) +} + + +jar { + from sourceSets.main.output + into('META-INF/versions/9') { + from sourceSets.java9.output + } + String packages = 'org.bouncycastle.asn1.{bsi|cmc|cmp|cms|crmf|cryptlib|dvcs|eac|edec|esf|ess|est|gnu|iana|icao|isara|isismtt|iso|kisa|microsoft|misc|mozilla|nsri|ntt|oiw|rosstandart|smime|tsp}.*' + String v = "${rootProject.extensions.ext.bundle_version}" + manifest.attributes('Multi-Release': 'true') + manifest.attributes('Bundle-Name': 'bcutil') + manifest.attributes('Bundle-SymbolicName': 'bcutil') + manifest.attributes('Bundle-RequiredExecutionEnvironment': 'JavaSE-1.8') + manifest.attributes('Export-Package': "${packages};version=${v},org.bouncycastle.oer.*;version=${v}") + manifest.attributes('Import-Package': "java.*;resolution:=optional,javax.*;resolution:=optional,!${packages},!org.bouncycastle.oer.*,org.bouncycastle.*;version=\"[${v},${maxVersion})\"") + manifest.attributes('Bundle-Version': "${v}") +} + + task sourcesJar(type: Jar) { - archiveBaseName = jar.archiveBaseName - classifier = 'sources' - from sourceSets.main.allSource + archiveBaseName = jar.archiveBaseName + archiveClassifier = 'sources' + from sourceSets.main.allSource + exclude("**/*.so") + into('META-INF/versions/9') { + from sourceSets.java9.allSource + } } task javadocJar(type: Jar, dependsOn: javadoc) { archiveBaseName = jar.archiveBaseName - classifier = 'javadoc' + archiveClassifier = 'javadoc' from javadoc.destinationDir } @@ -24,3 +97,8 @@ artifacts { archives sourcesJar } +test { + forkEvery = 1; + maxParallelForks = 8; +} + diff --git a/util/src/main/j2me/org/bouncycastle/asn1/cms/Time.java b/util/src/main/j2me/org/bouncycastle/asn1/cms/Time.java index 2477d6f261..7819d4ca95 100644 --- a/util/src/main/j2me/org/bouncycastle/asn1/cms/Time.java +++ b/util/src/main/j2me/org/bouncycastle/asn1/cms/Time.java @@ -20,7 +20,12 @@ public static Time getInstance( ASN1TaggedObject obj, boolean explicit) { - return getInstance(obj.getObject()); // must be explicitly tagged + if (!explicit) + { + throw new IllegalArgumentException("choice item must be explicitly tagged"); + } + + return getInstance(obj.getExplicitBaseObject()); } public Time( diff --git a/util/src/main/java/org/bouncycastle/asn1/cmc/CMCStatusInfoV2.java b/util/src/main/java/org/bouncycastle/asn1/cmc/CMCStatusInfoV2.java index 13fce7e5de..c175d613e5 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmc/CMCStatusInfoV2.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmc/CMCStatusInfoV2.java @@ -89,7 +89,14 @@ else if (seq.getObjectAt(2) instanceof ASN1UTF8String) } } + public CMCStatus getCMCStatus() + { + return cMCStatus; + } + /** + * @deprecated use getCMCStatus(); + */ public CMCStatus getcMCStatus() { return cMCStatus; diff --git a/util/src/main/java/org/bouncycastle/asn1/cmc/CertificationRequest.java b/util/src/main/java/org/bouncycastle/asn1/cmc/CertificationRequest.java index 67bd1f04ee..5b111ac646 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmc/CertificationRequest.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmc/CertificationRequest.java @@ -12,7 +12,6 @@ import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.X500Name; @@ -63,7 +62,7 @@ private CertificationRequest(ASN1Sequence seq) } this.certificationRequestInfo = new CertificationRequestInfo(ASN1Sequence.getInstance(seq.getObjectAt(0))); this.signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1)); - this.signature = DERBitString.getInstance(seq.getObjectAt(2)); + this.signature = ASN1BitString.getInstance(seq.getObjectAt(2)); } public static CertificationRequest getInstance(Object o) @@ -103,7 +102,7 @@ public AlgorithmIdentifier getSubjectPublicKeyAlgorithm() public ASN1BitString getSubjectPublicKey() { - return DERBitString.getInstance(certificationRequestInfo.getSubjectPublicKeyInfo().getObjectAt(1)); + return ASN1BitString.getInstance(certificationRequestInfo.getSubjectPublicKeyInfo().getObjectAt(1)); } /** diff --git a/util/src/main/java/org/bouncycastle/asn1/cmc/PKIResponse.java b/util/src/main/java/org/bouncycastle/asn1/cmc/PKIResponse.java index 91853787cb..26fffc5b83 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmc/PKIResponse.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmc/PKIResponse.java @@ -24,6 +24,9 @@ public class PKIResponse extends ASN1Object { + public static final TaggedContentInfo[] EMPTY_CMS_SEQUENCE = new TaggedContentInfo[0]; + public static final OtherMsg[] EMPTY_OTHER_MSG = new OtherMsg[0]; + private final ASN1Sequence controlSequence; private final ASN1Sequence cmsSequence; private final ASN1Sequence otherMsgSequence; @@ -39,7 +42,6 @@ private PKIResponse(ASN1Sequence seq) this.otherMsgSequence = ASN1Sequence.getInstance(seq.getObjectAt(2)); } - public static PKIResponse getInstance(Object o) { if (o instanceof PKIResponse) @@ -62,6 +64,20 @@ public static PKIResponse getInstance( return getInstance(ASN1Sequence.getInstance(obj, explicit)); } + public PKIResponse(TaggedAttribute controlSequence) + { + this.controlSequence = new DERSequence(controlSequence); + this.cmsSequence = new DERSequence(); + this.otherMsgSequence = new DERSequence(); + } + + public PKIResponse(TaggedAttribute[] controlSequence, TaggedContentInfo[] cmsSequence, OtherMsg[] otherMsgSequence) + { + this.controlSequence = new DERSequence(controlSequence); + this.cmsSequence = new DERSequence(cmsSequence); + this.otherMsgSequence = new DERSequence(otherMsgSequence); + } + public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(3); diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/CMPCertificate.java b/util/src/main/java/org/bouncycastle/asn1/cmp/CMPCertificate.java index d9f413cd54..012f2e06b3 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/CMPCertificate.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/CMPCertificate.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.Certificate; @@ -60,7 +61,7 @@ public static CMPCertificate getInstance(ASN1TaggedObject ato, boolean isExplici { if (isExplicit) { - return CMPCertificate.getInstance(ato.getObject()); + return CMPCertificate.getInstance(ato.getExplicitBaseObject()); } else { @@ -96,9 +97,9 @@ public static CMPCertificate getInstance(Object o) if (o instanceof ASN1TaggedObject) { - ASN1TaggedObject taggedObject = (ASN1TaggedObject)o; + ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC); - return new CMPCertificate(taggedObject.getTagNo(), taggedObject.getObject()); + return new CMPCertificate(taggedObject.getTagNo(), taggedObject.getBaseObject()); } throw new IllegalArgumentException("Invalid object: " + o.getClass().getName()); diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/CMPObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/cmp/CMPObjectIdentifiers.java index 5dcd78b9bc..dfe71835ef 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/CMPObjectIdentifiers.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/CMPObjectIdentifiers.java @@ -59,108 +59,108 @@ public interface CMPObjectIdentifiers // and // id-it OBJECT IDENTIFIER ::= {id-pkix 4} - /** RFC 4120: it-id: PKIX.4 = 1.3.6.1.5.5.7.4 */ - + /** RFC 4120: id-it: PKIX.4 = 1.3.6.1.5.5.7.4 */ + ASN1ObjectIdentifier id_it = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4"); /** * RFC 4120: 1.3.6.1.5.5.7.4.1 */ - ASN1ObjectIdentifier it_caProtEncCert = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.1"); + ASN1ObjectIdentifier it_caProtEncCert = id_it.branch("1"); /** * RFC 4120: 1.3.6.1.5.5.7.4.2 */ - ASN1ObjectIdentifier it_signKeyPairTypes = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.2"); + ASN1ObjectIdentifier it_signKeyPairTypes = id_it.branch("2"); /** * RFC 4120: 1.3.6.1.5.5.7.4.3 */ - ASN1ObjectIdentifier it_encKeyPairTypes = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.3"); + ASN1ObjectIdentifier it_encKeyPairTypes = id_it.branch("3"); /** * RFC 4120: 1.3.6.1.5.5.7.4.4 */ - ASN1ObjectIdentifier it_preferredSymAlg = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.4"); + ASN1ObjectIdentifier it_preferredSymAlg = id_it.branch("4"); /** * RFC 4120: 1.3.6.1.5.5.7.4.5 */ - ASN1ObjectIdentifier it_caKeyUpdateInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.5"); + ASN1ObjectIdentifier it_caKeyUpdateInfo = id_it.branch("5"); /** * RFC 4120: 1.3.6.1.5.5.7.4.6 */ - ASN1ObjectIdentifier it_currentCRL = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.6"); + ASN1ObjectIdentifier it_currentCRL = id_it.branch("6"); /** * RFC 4120: 1.3.6.1.5.5.7.4.7 */ - ASN1ObjectIdentifier it_unsupportedOIDs = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.7"); + ASN1ObjectIdentifier it_unsupportedOIDs = id_it.branch("7"); /** * RFC 4120: 1.3.6.1.5.5.7.4.10 */ - ASN1ObjectIdentifier it_keyPairParamReq = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.10"); + ASN1ObjectIdentifier it_keyPairParamReq = id_it.branch("10"); /** * RFC 4120: 1.3.6.1.5.5.7.4.11 */ - ASN1ObjectIdentifier it_keyPairParamRep = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.11"); + ASN1ObjectIdentifier it_keyPairParamRep = id_it.branch("11"); /** * RFC 4120: 1.3.6.1.5.5.7.4.12 */ - ASN1ObjectIdentifier it_revPassphrase = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.12"); + ASN1ObjectIdentifier it_revPassphrase = id_it.branch("12"); /** * RFC 4120: 1.3.6.1.5.5.7.4.13 */ - ASN1ObjectIdentifier it_implicitConfirm = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.13"); + ASN1ObjectIdentifier it_implicitConfirm = id_it.branch("13"); /** * RFC 4120: 1.3.6.1.5.5.7.4.14 */ - ASN1ObjectIdentifier it_confirmWaitTime = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.14"); + ASN1ObjectIdentifier it_confirmWaitTime = id_it.branch("14"); /** * RFC 4120: 1.3.6.1.5.5.7.4.15 */ - ASN1ObjectIdentifier it_origPKIMessage = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.15"); + ASN1ObjectIdentifier it_origPKIMessage = id_it.branch("15"); /** * RFC 4120: 1.3.6.1.5.5.7.4.16 */ - ASN1ObjectIdentifier it_suppLangTags = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.16"); + ASN1ObjectIdentifier it_suppLangTags = id_it.branch("16"); /** * Update 16, RFC 4210 * {id-it 17} */ - ASN1ObjectIdentifier id_it_caCerts = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.17"); + ASN1ObjectIdentifier id_it_caCerts = id_it.branch("17"); /** * Update 16, RFC 4210 * GenRep: {id-it 18}, RootCaKeyUpdateContent */ - ASN1ObjectIdentifier id_it_rootCaKeyUpdate = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.18"); + ASN1ObjectIdentifier id_it_rootCaKeyUpdate = id_it.branch("18"); /** * Update 16, RFC 4210 * {id-it 19} */ - ASN1ObjectIdentifier id_it_certReqTemplate = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.19"); + ASN1ObjectIdentifier id_it_certReqTemplate = id_it.branch("19"); /** * Update 16, RFC 4210 * GenMsg: {id-it 20}, RootCaCertValue */ - ASN1ObjectIdentifier id_it_rootCaCert = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.20"); + ASN1ObjectIdentifier id_it_rootCaCert = id_it.branch("20"); /** * Update-16 to RFC 4210 * id-it-certProfile OBJECT IDENTIFIER ::= {id-it 21} */ - ASN1ObjectIdentifier id_it_certProfile = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.21"); - - ASN1ObjectIdentifier id_it_crlStatusList = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.22"); - - ASN1ObjectIdentifier id_it_crls = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.23"); + ASN1ObjectIdentifier id_it_certProfile = id_it.branch("21"); - // Not yet formally defined. + ASN1ObjectIdentifier id_it_crlStatusList = id_it.branch("22"); - // ASN1ObjectIdentifier id_it_crlStatusList = null; - // ASN1ObjectIdentifier id_it_crls = null; + ASN1ObjectIdentifier id_it_crls = id_it.branch("23"); + // TODO Update once OID allocated. + /* + * id-it-KemCiphertextInfo OBJECT IDENTIFIER ::= { id-it TBD1 } + */ +// ASN1ObjectIdentifier id_it_KemCiphertextInfo = id_it.branch("TBD1"); // RFC 4211 @@ -255,5 +255,9 @@ public interface CMPObjectIdentifiers */ ASN1ObjectIdentifier id_regCtrl_rsaKeyLen = id_pkip.branch("1.12"); - + // TODO Update once OID allocated. + /* + * id-KemBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 TBD4} + */ +// ASN1ObjectIdentifier id_KemBasedMac = new ASN1ObjectIdentifier("1.2.840.113533.7.66.TBD4"); } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/CRLSource.java b/util/src/main/java/org/bouncycastle/asn1/cmp/CRLSource.java index d1b2141baa..c41d56da91 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/CRLSource.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/CRLSource.java @@ -4,6 +4,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.ASN1Util; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.DistributionPointName; import org.bouncycastle.asn1.x509.GeneralNames; @@ -28,18 +29,19 @@ public class CRLSource private CRLSource(ASN1TaggedObject ato) { - switch (ato.getTagNo()) + if (ato.hasContextTag(0)) { - case 0: dpn = DistributionPointName.getInstance(ato, true); issuer = null; - break; - case 1: + } + else if (ato.hasContextTag(1)) + { dpn = null; issuer = GeneralNames.getInstance(ato, true); - break; - default: - throw new IllegalArgumentException("unknown tag " + ato.getTagNo()); + } + else + { + throw new IllegalArgumentException("unknown tag " + ASN1Util.getTagText(ato)); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/CertAnnContent.java b/util/src/main/java/org/bouncycastle/asn1/cmp/CertAnnContent.java index 8e000a2653..129752dee5 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/CertAnnContent.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/CertAnnContent.java @@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.Certificate; @@ -43,7 +44,7 @@ public static CertAnnContent getInstance(ASN1TaggedObject ato, boolean isExplici { if (isExplicit) { - return CertAnnContent.getInstance(ato.getObject()); + return CertAnnContent.getInstance(ato.getExplicitBaseObject()); } else { @@ -91,13 +92,11 @@ public static CertAnnContent getInstance(Object o) if (o instanceof ASN1TaggedObject) { - ASN1TaggedObject taggedObject = (ASN1TaggedObject)o; + ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC); - return new CertAnnContent(taggedObject.getTagNo(), taggedObject.getObject()); + return new CertAnnContent(taggedObject.getTagNo(), taggedObject.getExplicitBaseObject()); } throw new IllegalArgumentException("Invalid object: " + o.getClass().getName()); } - - } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/CertOrEncCert.java b/util/src/main/java/org/bouncycastle/asn1/cmp/CertOrEncCert.java index 8bbbd72051..b660cea49d 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/CertOrEncCert.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/CertOrEncCert.java @@ -4,6 +4,8 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.ASN1Util; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.crmf.EncryptedKey; import org.bouncycastle.asn1.crmf.EncryptedValue; @@ -23,17 +25,17 @@ public class CertOrEncCert private CertOrEncCert(ASN1TaggedObject tagged) { - if (tagged.getTagNo() == 0) + if (tagged.hasContextTag(0)) { - certificate = CMPCertificate.getInstance(tagged.getObject()); + certificate = CMPCertificate.getInstance(tagged.getExplicitBaseObject()); } - else if (tagged.getTagNo() == 1) + else if (tagged.hasContextTag(1)) { - encryptedCert = EncryptedKey.getInstance(tagged.getObject()); + encryptedCert = EncryptedKey.getInstance(tagged.getExplicitBaseObject()); } else { - throw new IllegalArgumentException("unknown tag: " + tagged.getTagNo()); + throw new IllegalArgumentException("unknown tag: " + ASN1Util.getTagText(tagged)); } } @@ -47,24 +49,24 @@ public CertOrEncCert(CMPCertificate certificate) this.certificate = certificate; } - public CertOrEncCert(EncryptedValue encryptedCert) + public CertOrEncCert(EncryptedValue encryptedValue) { - if (encryptedCert == null) + if (encryptedValue == null) { throw new IllegalArgumentException("'encryptedCert' cannot be null"); } - this.encryptedCert = new EncryptedKey(encryptedCert); + this.encryptedCert = new EncryptedKey(encryptedValue); } - public CertOrEncCert(EncryptedKey encryptedCert) + public CertOrEncCert(EncryptedKey encryptedKey) { - if (encryptedCert == null) + if (encryptedKey == null) { throw new IllegalArgumentException("'encryptedCert' cannot be null"); } - this.encryptedCert = encryptedCert; + this.encryptedCert = encryptedKey; } public static CertOrEncCert getInstance(Object o) @@ -76,7 +78,7 @@ public static CertOrEncCert getInstance(Object o) if (o instanceof ASN1TaggedObject) { - return new CertOrEncCert((ASN1TaggedObject)o); + return new CertOrEncCert(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/CertRepMessage.java b/util/src/main/java/org/bouncycastle/asn1/cmp/CertRepMessage.java index 2a8e36aa40..fdcacf24a3 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/CertRepMessage.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/CertRepMessage.java @@ -18,7 +18,7 @@ public class CertRepMessage extends ASN1Object { - private ASN1Sequence caPubs; + private final ASN1Sequence caPubs; private final ASN1Sequence response; private CertRepMessage(ASN1Sequence seq) @@ -29,6 +29,10 @@ private CertRepMessage(ASN1Sequence seq) { caPubs = ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(index++), true); } + else + { + caPubs = null; + } response = ASN1Sequence.getInstance(seq.getObjectAt(index)); } @@ -44,6 +48,10 @@ public CertRepMessage(CMPCertificate[] caPubs, CertResponse[] response) { this.caPubs = new DERSequence(caPubs); } + else + { + this.caPubs = null; + } this.response = new DERSequence(response); } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/CertResponse.java b/util/src/main/java/org/bouncycastle/asn1/cmp/CertResponse.java index 9fbf7dda32..2afe363670 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/CertResponse.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/CertResponse.java @@ -111,6 +111,11 @@ public CertifiedKeyPair getCertifiedKeyPair() return certifiedKeyPair; } + public ASN1OctetString getRspInfo() + { + return rspInfo; + } + /** *

            * CertResponse ::= SEQUENCE {
      diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/CertStatus.java b/util/src/main/java/org/bouncycastle/asn1/cmp/CertStatus.java
      index fa356fdd25..0e3d5ccc81 100644
      --- a/util/src/main/java/org/bouncycastle/asn1/cmp/CertStatus.java
      +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/CertStatus.java
      @@ -10,6 +10,7 @@
       import org.bouncycastle.asn1.ASN1Primitive;
       import org.bouncycastle.asn1.ASN1Sequence;
       import org.bouncycastle.asn1.ASN1TaggedObject;
      +import org.bouncycastle.asn1.ASN1Util;
       import org.bouncycastle.asn1.DEROctetString;
       import org.bouncycastle.asn1.DERSequence;
       import org.bouncycastle.asn1.DERTaggedObject;
      @@ -29,13 +30,16 @@ public class CertStatus
       {
           private final ASN1OctetString certHash;
           private final ASN1Integer certReqId;
      -    private PKIStatusInfo statusInfo;
      -    private AlgorithmIdentifier hashAlg;
      +    private final PKIStatusInfo statusInfo;
      +    private final AlgorithmIdentifier hashAlg;
       
           private CertStatus(ASN1Sequence seq)
           {
      -        certHash = ASN1OctetString.getInstance(seq.getObjectAt(0));
      -        certReqId = ASN1Integer.getInstance(seq.getObjectAt(1));
      +        this.certHash = ASN1OctetString.getInstance(seq.getObjectAt(0));
      +        this.certReqId = ASN1Integer.getInstance(seq.getObjectAt(1));
      +
      +        PKIStatusInfo statusInfo = null;
      +        AlgorithmIdentifier hashAlg = null;
       
               if (seq.size() > 2)
               {
      @@ -49,14 +53,17 @@ private CertStatus(ASN1Sequence seq)
                       if (p instanceof ASN1TaggedObject)
                       {
                           ASN1TaggedObject dto = (ASN1TaggedObject)p;
      -                    if (dto.getTagNo() != 0)
      +                    if (!dto.hasContextTag(0))
                           {
      -                        throw new IllegalArgumentException("unknown tag " + dto.getTagNo());
      +                        throw new IllegalArgumentException("unknown tag " + ASN1Util.getTagText(dto));
                           }
                           hashAlg = AlgorithmIdentifier.getInstance(dto, true);
                       }
                   }
               }
      +
      +        this.statusInfo = statusInfo;
      +        this.hashAlg = hashAlg;
           }
       
           public CertStatus(byte[] certHash, BigInteger certReqId)
      @@ -68,6 +75,8 @@ public CertStatus(byte[] certHash, ASN1Integer certReqId)
           {
               this.certHash = new DEROctetString(certHash);
               this.certReqId = certReqId;
      +        this.statusInfo = null;
      +        this.hashAlg = null;
           }
       
           public CertStatus(byte[] certHash, BigInteger certReqId, PKIStatusInfo statusInfo)
      @@ -75,6 +84,7 @@ public CertStatus(byte[] certHash, BigInteger certReqId, PKIStatusInfo statusInf
               this.certHash = new DEROctetString(certHash);
               this.certReqId = new ASN1Integer(certReqId);
               this.statusInfo = statusInfo;
      +        this.hashAlg = null;
           }
       
           public CertStatus(byte[] certHash, BigInteger certReqId, PKIStatusInfo statusInfo, AlgorithmIdentifier hashAlg)
      diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/CertifiedKeyPair.java b/util/src/main/java/org/bouncycastle/asn1/cmp/CertifiedKeyPair.java
      index 3adc14446a..f362082e8a 100644
      --- a/util/src/main/java/org/bouncycastle/asn1/cmp/CertifiedKeyPair.java
      +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/CertifiedKeyPair.java
      @@ -5,6 +5,7 @@
       import org.bouncycastle.asn1.ASN1Primitive;
       import org.bouncycastle.asn1.ASN1Sequence;
       import org.bouncycastle.asn1.ASN1TaggedObject;
      +import org.bouncycastle.asn1.BERTags;
       import org.bouncycastle.asn1.DERSequence;
       import org.bouncycastle.asn1.DERTaggedObject;
       import org.bouncycastle.asn1.crmf.EncryptedKey;
      @@ -36,20 +37,20 @@ private CertifiedKeyPair(ASN1Sequence seq)
               {
                   if (seq.size() == 2)
                   {
      -                ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(seq.getObjectAt(1));
      +                ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(seq.getObjectAt(1), BERTags.CONTEXT_SPECIFIC);
                       if (tagged.getTagNo() == 0)
                       {
      -                    privateKey = EncryptedKey.getInstance(tagged.getObject());
      +                    privateKey = EncryptedKey.getInstance(tagged.getExplicitBaseObject());
                       }
                       else
                       {
      -                    publicationInfo = PKIPublicationInfo.getInstance(tagged.getObject());
      +                    publicationInfo = PKIPublicationInfo.getInstance(tagged.getExplicitBaseObject());
                       }
                   }
                   else
                   {
      -                privateKey = EncryptedKey.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getObject());
      -                publicationInfo = PKIPublicationInfo.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(2)).getObject());
      +                privateKey = EncryptedKey.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(1), BERTags.CONTEXT_SPECIFIC).getExplicitBaseObject());
      +                publicationInfo = PKIPublicationInfo.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(2), BERTags.CONTEXT_SPECIFIC).getExplicitBaseObject());
                   }
               }
           }
      diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/Challenge.java b/util/src/main/java/org/bouncycastle/asn1/cmp/Challenge.java
      index 6083017ebc..cf447017aa 100644
      --- a/util/src/main/java/org/bouncycastle/asn1/cmp/Challenge.java
      +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/Challenge.java
      @@ -41,7 +41,7 @@
       public class Challenge
           extends ASN1Object
       {
      -    private AlgorithmIdentifier owf;
      +    private final AlgorithmIdentifier owf;
           private final ASN1OctetString witness;
           private final ASN1OctetString challenge;
       
      @@ -53,6 +53,10 @@ private Challenge(ASN1Sequence seq)
               {
                   owf = AlgorithmIdentifier.getInstance(seq.getObjectAt(index++));
               }
      +        else
      +        {
      +            owf = null;
      +        }
       
               witness = ASN1OctetString.getInstance(seq.getObjectAt(index++));
               challenge = ASN1OctetString.getInstance(seq.getObjectAt(index));
      diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/KemBMParameter.java b/util/src/main/java/org/bouncycastle/asn1/cmp/KemBMParameter.java
      new file mode 100644
      index 0000000000..3a5705e280
      --- /dev/null
      +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/KemBMParameter.java
      @@ -0,0 +1,108 @@
      +package org.bouncycastle.asn1.cmp;
      +
      +import org.bouncycastle.asn1.ASN1EncodableVector;
      +import org.bouncycastle.asn1.ASN1Integer;
      +import org.bouncycastle.asn1.ASN1Object;
      +import org.bouncycastle.asn1.ASN1Primitive;
      +import org.bouncycastle.asn1.ASN1Sequence;
      +import org.bouncycastle.asn1.DERSequence;
      +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
      +
      +/**
      + * 
      + *  KemBMParameter ::= SEQUENCE {
      + *      kdf              AlgorithmIdentifier{KEY-DERIVATION, {...}},
      + *      len              INTEGER (1..MAX),
      + *      mac              AlgorithmIdentifier{MAC-ALGORITHM, {...}}
      + *   }
      + * 
      + */ +public class KemBMParameter + extends ASN1Object +{ + private final AlgorithmIdentifier kdf; + private final ASN1Integer len; + private final AlgorithmIdentifier mac; + + private KemBMParameter(ASN1Sequence seq) + { + if (seq.size() != 3) + { + throw new IllegalArgumentException("sequence size should 3"); + } + + kdf = AlgorithmIdentifier.getInstance(seq.getObjectAt(0)); + len = ASN1Integer.getInstance(seq.getObjectAt(1)); + mac = AlgorithmIdentifier.getInstance(seq.getObjectAt(2)); + } + + public KemBMParameter( + AlgorithmIdentifier kdf, + ASN1Integer len, + AlgorithmIdentifier mac) + { + this.kdf = kdf; + this.len = len; + this.mac = mac; + } + + public KemBMParameter( + AlgorithmIdentifier kdf, + long len, + AlgorithmIdentifier mac) + { + this(kdf, new ASN1Integer(len), mac); + } + + public static KemBMParameter getInstance(Object o) + { + if (o instanceof KemBMParameter) + { + return (KemBMParameter)o; + } + + if (o != null) + { + return new KemBMParameter(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public AlgorithmIdentifier getKdf() + { + return kdf; + } + + public ASN1Integer getLen() + { + return len; + } + + public AlgorithmIdentifier getMac() + { + return mac; + } + + /** + *
      +     *  KemBMParameter ::= SEQUENCE {
      +     *      kdf              AlgorithmIdentifier{KEY-DERIVATION, {...}},
      +     *      len              INTEGER (1..MAX),
      +     *      mac              AlgorithmIdentifier{MAC-ALGORITHM, {...}}
      +     *    }
      +     * 
      + * + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(3); + + v.add(kdf); + v.add(len); + v.add(mac); + + return new DERSequence(v); + } +} diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/KemCiphertextInfo.java b/util/src/main/java/org/bouncycastle/asn1/cmp/KemCiphertextInfo.java new file mode 100644 index 0000000000..c6da437184 --- /dev/null +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/KemCiphertextInfo.java @@ -0,0 +1,89 @@ +package org.bouncycastle.asn1.cmp; + +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +/** + *
      + *    KemCiphertextInfo ::= SEQUENCE {
      + *      kem              AlgorithmIdentifier{KEM-ALGORITHM, {...}},
      + *      ct               OCTET STRING
      + *    }
      + * 
      + */ +public class KemCiphertextInfo + extends ASN1Object +{ + private final AlgorithmIdentifier kem; + private final ASN1OctetString ct; + + private KemCiphertextInfo(ASN1Sequence seq) + { + if (seq.size() != 2) + { + throw new IllegalArgumentException("sequence size should 2"); + } + + kem = AlgorithmIdentifier.getInstance(seq.getObjectAt(0)); + ct = ASN1OctetString.getInstance(seq.getObjectAt(1)); + } + + + public KemCiphertextInfo( + AlgorithmIdentifier kem, + ASN1OctetString ct) + { + this.kem = kem; + this.ct = ct; + } + + public static KemCiphertextInfo getInstance(Object o) + { + if (o instanceof KemCiphertextInfo) + { + return (KemCiphertextInfo)o; + } + + if (o != null) + { + return new KemCiphertextInfo(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public AlgorithmIdentifier getKem() + { + return kem; + } + + public ASN1OctetString getCt() + { + return ct; + } + + /** + *
      +     *    KemCiphertextInfo ::= SEQUENCE {
      +     *      kem              AlgorithmIdentifier{KEM-ALGORITHM, {...}},
      +     *      ct               OCTET STRING
      +     *    }
      +     * 
      + * + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(2); + + v.add(kem); + v.add(ct); + + return new DERSequence(v); + } +} diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/KemOtherInfo.java b/util/src/main/java/org/bouncycastle/asn1/cmp/KemOtherInfo.java new file mode 100644 index 0000000000..5140a22ceb --- /dev/null +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/KemOtherInfo.java @@ -0,0 +1,229 @@ +package org.bouncycastle.asn1.cmp; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.ASN1Util; +import org.bouncycastle.asn1.BERTags; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +/* + *
      + * KemOtherInfo ::= SEQUENCE {
      + *   staticString      PKIFreeText,  -- MUST be "CMP-KEM"
      + *   transactionID [0] OCTET STRING     OPTIONAL,
      + *   senderNonce   [1] OCTET STRING     OPTIONAL,
      + *   recipNonce    [2] OCTET STRING     OPTIONAL,
      + *   len               INTEGER (1..MAX),
      + *   mac               AlgorithmIdentifier{MAC-ALGORITHM, {...}}
      + *   ct                OCTET STRING
      + * }
      + * 
      + */ +public class KemOtherInfo + extends ASN1Object +{ + private static final PKIFreeText DEFAULT_staticString = new PKIFreeText("CMP-KEM"); + + private final PKIFreeText staticString; + private final ASN1OctetString transactionID; + private final ASN1OctetString senderNonce; + private final ASN1OctetString recipNonce; + private final ASN1Integer len; + private final AlgorithmIdentifier mac; + private final ASN1OctetString ct; + + public KemOtherInfo( + ASN1OctetString transactionID, + ASN1OctetString senderNonce, + ASN1OctetString recipNonce, + ASN1Integer len, + AlgorithmIdentifier mac, + ASN1OctetString ct) + { + this.staticString = DEFAULT_staticString; + this.transactionID = transactionID; + this.senderNonce = senderNonce; + this.recipNonce = recipNonce; + this.len = len; + this.mac = mac; + this.ct = ct; + } + + public KemOtherInfo( + ASN1OctetString transactionID, + ASN1OctetString senderNonce, + ASN1OctetString recipNonce, + long len, + AlgorithmIdentifier mac, + ASN1OctetString ct) + { + this(transactionID, senderNonce, recipNonce, new ASN1Integer(len), mac, ct); + } + + private KemOtherInfo(ASN1Sequence seq) + { + if (seq.size() < 4 || seq.size() > 7) + { + throw new IllegalArgumentException("sequence size should be between 4 and 7 inclusive"); + } + + int seqPos = 0; + + this.staticString = PKIFreeText.getInstance(seq.getObjectAt(seqPos)); + if (!DEFAULT_staticString.equals(staticString)) + { + throw new IllegalArgumentException("staticString field should be " + DEFAULT_staticString); + } + + ASN1OctetString transactionID = null; + ASN1OctetString senderNonce = null; + ASN1OctetString recipNonce = null; + + ASN1TaggedObject tagged = tryGetTagged(seq, ++seqPos); + + if (tagged != null) + { + ASN1Primitive _transactionID = ASN1Util.tryGetContextBaseUniversal(tagged, 0, true, BERTags.OCTET_STRING); + if (_transactionID != null) + { + transactionID = (ASN1OctetString)_transactionID; + tagged = tryGetTagged(seq, ++seqPos); + } + } + + if (tagged != null) + { + ASN1Primitive _senderNonce = ASN1Util.tryGetContextBaseUniversal(tagged, 1, true, BERTags.OCTET_STRING); + if (_senderNonce != null) + { + senderNonce = (ASN1OctetString)_senderNonce; + tagged = tryGetTagged(seq, ++seqPos); + } + } + + if (tagged != null) + { + ASN1Primitive _recipNonce = ASN1Util.tryGetContextBaseUniversal(tagged, 2, true, BERTags.OCTET_STRING); + if (_recipNonce != null) + { + recipNonce = (ASN1OctetString)_recipNonce; + tagged = tryGetTagged(seq, ++seqPos); + } + } + + if (tagged != null) + { + throw new IllegalArgumentException("unknown tag: " + ASN1Util.getTagText(tagged)); + } + + this.transactionID = transactionID; + this.senderNonce = senderNonce; + this.recipNonce = recipNonce; + + this.len = ASN1Integer.getInstance(seq.getObjectAt(seqPos)); + this.mac = AlgorithmIdentifier.getInstance(seq.getObjectAt(++seqPos)); + this.ct = ASN1OctetString.getInstance(seq.getObjectAt(++seqPos)); + + if (++seqPos != seq.size()) + { + throw new IllegalArgumentException("unexpected data at end of sequence"); + } + } + + public static KemOtherInfo getInstance(Object o) + { + if (o instanceof KemOtherInfo) + { + return (KemOtherInfo)o; + } + + if (o != null) + { + return new KemOtherInfo(ASN1Sequence.getInstance(o)); + } + + return null; + } + + public ASN1OctetString getTransactionID() + { + return transactionID; + } + + public ASN1OctetString getSenderNonce() + { + return senderNonce; + } + + public ASN1OctetString getRecipNonce() + { + return recipNonce; + } + + public ASN1Integer getLen() + { + return len; + } + + public AlgorithmIdentifier getMac() + { + return mac; + } + + public ASN1OctetString getCt() + { + return ct; + } + + /** + *
      +     * KemOtherInfo ::= SEQUENCE {
      +     *   staticString      PKIFreeText,   -- MUST be "CMP-KEM"
      +     *   transactionID [0] OCTET STRING     OPTIONAL,
      +     *   senderNonce   [1] OCTET STRING     OPTIONAL,
      +     *   recipNonce    [2] OCTET STRING     OPTIONAL,
      +     *   len               INTEGER (1..MAX),
      +     *   mac               AlgorithmIdentifier{MAC-ALGORITHM, {...}}
      +     *   ct                OCTET STRING
      +     * }
      +     * 
      + * + * @return a basic ASN.1 object representation. + */ + public ASN1Primitive toASN1Primitive() + { + ASN1EncodableVector v = new ASN1EncodableVector(7); + + v.add(staticString); + addOptional(v, 0, transactionID); + addOptional(v, 1, senderNonce); + addOptional(v, 2, recipNonce); + v.add(len); + v.add(mac); + v.add(ct); + + return new DERSequence(v); + } + + private static void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj) + { + if (obj != null) + { + v.add(new DERTaggedObject(true, tagNo, obj)); + } + } + + private static ASN1TaggedObject tryGetTagged(ASN1Sequence seq, int seqPos) + { + ASN1Encodable element = seq.getObjectAt(seqPos); + return element instanceof ASN1TaggedObject ? (ASN1TaggedObject)element : null; + } +} diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/KeyRecRepContent.java b/util/src/main/java/org/bouncycastle/asn1/cmp/KeyRecRepContent.java index a1aec2adf0..58870f63c1 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/KeyRecRepContent.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/KeyRecRepContent.java @@ -8,6 +8,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; @@ -37,18 +38,18 @@ private KeyRecRepContent(ASN1Sequence seq) while (en.hasMoreElements()) { - ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(en.nextElement()); + ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(en.nextElement(), BERTags.CONTEXT_SPECIFIC); switch (tObj.getTagNo()) { case 0: - newSigCert = CMPCertificate.getInstance(tObj.getObject()); + newSigCert = CMPCertificate.getInstance(tObj.getExplicitBaseObject()); break; case 1: - caCerts = ASN1Sequence.getInstance(tObj.getObject()); + caCerts = ASN1Sequence.getInstance(tObj.getExplicitBaseObject()); break; case 2: - keyPairHist = ASN1Sequence.getInstance(tObj.getObject()); + keyPairHist = ASN1Sequence.getInstance(tObj.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("unknown tag number: " + tObj.getTagNo()); diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/OOBCert.java b/util/src/main/java/org/bouncycastle/asn1/cmp/OOBCert.java index e2adc0d83b..1963bb2f60 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/OOBCert.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/OOBCert.java @@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.Certificate; @@ -18,7 +19,7 @@ public class OOBCert public OOBCert(AttributeCertificate x509v2AttrCert) { - super(x509v2AttrCert); + super(1, x509v2AttrCert); } public OOBCert(int type, ASN1Object otherCert) @@ -37,7 +38,7 @@ public static OOBCert getInstance(ASN1TaggedObject ato, boolean isExplicit) { if (isExplicit) { - return OOBCert.getInstance(ato.getObject()); + return OOBCert.getInstance(ato.getExplicitBaseObject()); } else { @@ -86,9 +87,9 @@ public static OOBCert getInstance(Object o) if (o instanceof ASN1TaggedObject) { - ASN1TaggedObject taggedObject = (ASN1TaggedObject)o; + ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC); - return new OOBCert(taggedObject.getTagNo(), taggedObject.getObject()); + return new OOBCert(taggedObject.getTagNo(), taggedObject.getExplicitBaseObject()); } throw new IllegalArgumentException("Invalid object: " + o.getClass().getName()); diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/OOBCertHash.java b/util/src/main/java/org/bouncycastle/asn1/cmp/OOBCertHash.java index 5c70f112e5..ad8dc3ad6a 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/OOBCertHash.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/OOBCertHash.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.ASN1Util; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; @@ -27,30 +28,39 @@ public class OOBCertHash extends ASN1Object { - private AlgorithmIdentifier hashAlg; - private CertId certId; + private final AlgorithmIdentifier hashAlg; + private final CertId certId; private final ASN1BitString hashVal; private OOBCertHash(ASN1Sequence seq) { int index = seq.size() - 1; - hashVal = ASN1BitString.getInstance(seq.getObjectAt(index--)); + this.hashVal = ASN1BitString.getInstance(seq.getObjectAt(index--)); + + AlgorithmIdentifier hashAlg = null; + CertId certId = null; for (int i = index; i >= 0; i--) { ASN1TaggedObject tObj = (ASN1TaggedObject)seq.getObjectAt(i); - if (tObj.getTagNo() == 0) + if (tObj.hasContextTag(0)) { hashAlg = AlgorithmIdentifier.getInstance(tObj, true); } - else + else if (tObj.hasContextTag(1)) { certId = CertId.getInstance(tObj, true); } + else + { + throw new IllegalArgumentException("unknown tag " + ASN1Util.getTagText(tObj)); + } } + this.hashAlg = hashAlg; + this.certId = certId; } public OOBCertHash(AlgorithmIdentifier hashAlg, CertId certId, byte[] hashVal) diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIBody.java b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIBody.java index 13bdc9547f..d4351c6858 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIBody.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIBody.java @@ -8,6 +8,7 @@ import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.crmf.CertReqMessages; import org.bouncycastle.asn1.pkcs.CertificationRequest; +import org.bouncycastle.util.Exceptions; /** * PKIBody ::= CHOICE { -- message-specific body elements @@ -78,7 +79,18 @@ public class PKIBody private PKIBody(ASN1TaggedObject tagged) { tagNo = tagged.getTagNo(); - body = getBodyForType(tagNo, tagged.getObject()); + try + { + body = getBodyForType(tagNo, tagged.getExplicitBaseObject()); + } + catch (ClassCastException e) + { + throw Exceptions.illegalArgumentException("malformed body found: " + e.getMessage(), e); + } + catch (IllegalArgumentException e) + { + throw Exceptions.illegalArgumentException("malformed body found: " + e.getMessage(), e); + } } /** @@ -114,64 +126,75 @@ private static ASN1Encodable getBodyForType( int type, ASN1Encodable o) { - switch (type) + try + { + switch (type) + { + case TYPE_INIT_REQ: + return CertReqMessages.getInstance(o); + case TYPE_INIT_REP: + return CertRepMessage.getInstance(o); + case TYPE_CERT_REQ: + return CertReqMessages.getInstance(o); + case TYPE_CERT_REP: + return CertRepMessage.getInstance(o); + case TYPE_P10_CERT_REQ: + return CertificationRequest.getInstance(o); + case TYPE_POPO_CHALL: + return POPODecKeyChallContent.getInstance(o); + case TYPE_POPO_REP: + return POPODecKeyRespContent.getInstance(o); + case TYPE_KEY_UPDATE_REQ: + return CertReqMessages.getInstance(o); + case TYPE_KEY_UPDATE_REP: + return CertRepMessage.getInstance(o); + case TYPE_KEY_RECOVERY_REQ: + return CertReqMessages.getInstance(o); + case TYPE_KEY_RECOVERY_REP: + return KeyRecRepContent.getInstance(o); + case TYPE_REVOCATION_REQ: + return RevReqContent.getInstance(o); + case TYPE_REVOCATION_REP: + return RevRepContent.getInstance(o); + case TYPE_CROSS_CERT_REQ: + return CertReqMessages.getInstance(o); + case TYPE_CROSS_CERT_REP: + return CertRepMessage.getInstance(o); + case TYPE_CA_KEY_UPDATE_ANN: + return CAKeyUpdAnnContent.getInstance(o); + case TYPE_CERT_ANN: + return CMPCertificate.getInstance(o); + case TYPE_REVOCATION_ANN: + return RevAnnContent.getInstance(o); + case TYPE_CRL_ANN: + return CRLAnnContent.getInstance(o); + case TYPE_CONFIRM: + return PKIConfirmContent.getInstance(o); + case TYPE_NESTED: + return PKIMessages.getInstance(o); + case TYPE_GEN_MSG: + return GenMsgContent.getInstance(o); + case TYPE_GEN_REP: + return GenRepContent.getInstance(o); + case TYPE_ERROR: + return ErrorMsgContent.getInstance(o); + case TYPE_CERT_CONFIRM: + return CertConfirmContent.getInstance(o); + case TYPE_POLL_REQ: + return PollReqContent.getInstance(o); + case TYPE_POLL_REP: + return PollRepContent.getInstance(o); + default: + throw new IllegalArgumentException("unknown tag number: " + type); + } + } + catch (ClassCastException e) + { + throw new IllegalArgumentException("body type of " + type + " has incorrect type got: " + o.getClass()); + } + catch (IllegalArgumentException e) { - case TYPE_INIT_REQ: - return CertReqMessages.getInstance(o); - case TYPE_INIT_REP: - return CertRepMessage.getInstance(o); - case TYPE_CERT_REQ: - return CertReqMessages.getInstance(o); - case TYPE_CERT_REP: - return CertRepMessage.getInstance(o); - case TYPE_P10_CERT_REQ: - return CertificationRequest.getInstance(o); - case TYPE_POPO_CHALL: - return POPODecKeyChallContent.getInstance(o); - case TYPE_POPO_REP: - return POPODecKeyRespContent.getInstance(o); - case TYPE_KEY_UPDATE_REQ: - return CertReqMessages.getInstance(o); - case TYPE_KEY_UPDATE_REP: - return CertRepMessage.getInstance(o); - case TYPE_KEY_RECOVERY_REQ: - return CertReqMessages.getInstance(o); - case TYPE_KEY_RECOVERY_REP: - return KeyRecRepContent.getInstance(o); - case TYPE_REVOCATION_REQ: - return RevReqContent.getInstance(o); - case TYPE_REVOCATION_REP: - return RevRepContent.getInstance(o); - case TYPE_CROSS_CERT_REQ: - return CertReqMessages.getInstance(o); - case TYPE_CROSS_CERT_REP: - return CertRepMessage.getInstance(o); - case TYPE_CA_KEY_UPDATE_ANN: - return CAKeyUpdAnnContent.getInstance(o); - case TYPE_CERT_ANN: - return CMPCertificate.getInstance(o); - case TYPE_REVOCATION_ANN: - return RevAnnContent.getInstance(o); - case TYPE_CRL_ANN: - return CRLAnnContent.getInstance(o); - case TYPE_CONFIRM: - return PKIConfirmContent.getInstance(o); - case TYPE_NESTED: - return PKIMessages.getInstance(o); - case TYPE_GEN_MSG: - return GenMsgContent.getInstance(o); - case TYPE_GEN_REP: - return GenRepContent.getInstance(o); - case TYPE_ERROR: - return ErrorMsgContent.getInstance(o); - case TYPE_CERT_CONFIRM: - return CertConfirmContent.getInstance(o); - case TYPE_POLL_REQ: - return PollReqContent.getInstance(o); - case TYPE_POLL_REP: - return PollRepContent.getInstance(o); - default: - throw new IllegalArgumentException("unknown tag number: " + type); + throw new IllegalArgumentException("body type of " + type + " has incorrect type got: " + o.getClass()); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIHeader.java b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIHeader.java index 3c14d4f5dc..acd06f529c 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIHeader.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIHeader.java @@ -11,6 +11,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.ASN1Util; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x500.X500Name; @@ -89,6 +90,10 @@ private PKIHeader(ASN1Sequence seq) while (en.hasMoreElements()) { ASN1TaggedObject tObj = (ASN1TaggedObject)en.nextElement(); + if (!tObj.hasContextTag()) + { + throw new IllegalArgumentException("unknown tag: " + ASN1Util.getTagText(tObj)); + } switch (tObj.getTagNo()) { diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIMessage.java b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIMessage.java index 878fcb1687..7971b2efa9 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIMessage.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIMessage.java @@ -9,7 +9,6 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; @@ -27,15 +26,25 @@ public class PKIMessage { private final PKIHeader header; private final PKIBody body; - private ASN1BitString protection; - private ASN1Sequence extraCerts; + private final ASN1BitString protection; + private final ASN1Sequence extraCerts; private PKIMessage(ASN1Sequence seq) { Enumeration en = seq.getObjects(); header = PKIHeader.getInstance(en.nextElement()); - body = PKIBody.getInstance(en.nextElement()); + if (en.hasMoreElements()) + { + body = PKIBody.getInstance(en.nextElement()); + } + else + { + throw new IllegalArgumentException("PKIMessage missing PKIBody structure"); + } + + ASN1BitString protection = null; + ASN1Sequence extraCerts = null; while (en.hasMoreElements()) { @@ -43,13 +52,16 @@ private PKIMessage(ASN1Sequence seq) if (tObj.getTagNo() == 0) { - protection = DERBitString.getInstance(tObj, true); + protection = ASN1BitString.getInstance(tObj, true); } else { extraCerts = ASN1Sequence.getInstance(tObj, true); } } + + this.protection = protection; + this.extraCerts = extraCerts; } /** @@ -73,6 +85,10 @@ public PKIMessage( { this.extraCerts = new DERSequence(extraCerts); } + else + { + this.extraCerts = null; + } } public PKIMessage( diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIStatusInfo.java b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIStatusInfo.java index a369412018..7e656e0770 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIStatusInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIStatusInfo.java @@ -37,7 +37,7 @@ private PKIStatusInfo( if (seq.size() > 2) { this.statusString = PKIFreeText.getInstance(seq.getObjectAt(1)); - this.failInfo = DERBitString.getInstance(seq.getObjectAt(2)); + this.failInfo = ASN1BitString.getInstance(seq.getObjectAt(2)); } else if (seq.size() > 1) { diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/RevRepContent.java b/util/src/main/java/org/bouncycastle/asn1/cmp/RevRepContent.java index 5a456bf7cb..7d28dfd239 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/RevRepContent.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/RevRepContent.java @@ -43,11 +43,11 @@ private RevRepContent(ASN1Sequence seq) { ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(en.nextElement()); - if (tObj.getTagNo() == 0) + if (tObj.hasContextTag(0)) { revCerts = ASN1Sequence.getInstance(tObj, true); } - else + else if (tObj.hasContextTag(1)) { crls = ASN1Sequence.getInstance(tObj, true); } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/RootCaKeyUpdateContent.java b/util/src/main/java/org/bouncycastle/asn1/cmp/RootCaKeyUpdateContent.java index 4966c3e444..27699e4fb9 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/RootCaKeyUpdateContent.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/RootCaKeyUpdateContent.java @@ -61,11 +61,11 @@ private RootCaKeyUpdateContent(ASN1Sequence seq) while (encodable.hasNext()) { ASN1TaggedObject ato = ASN1TaggedObject.getInstance(encodable.next()); - if (ato.getTagNo() == 0) + if (ato.hasContextTag(0)) { newWithOld = CMPCertificate.getInstance(ato, true); } - else if (ato.getTagNo() == 1) + else if (ato.hasContextTag(1)) { oldWithNew = CMPCertificate.getInstance(ato, true); } @@ -74,7 +74,6 @@ else if (ato.getTagNo() == 1) this.newWithNew = newWithNew; this.newWithOld = newWithOld; this.oldWithNew = oldWithNew; - } public static RootCaKeyUpdateContent getInstance(Object o) diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedData.java b/util/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedData.java index 4577d81929..8883199e28 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedData.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedData.java @@ -1,7 +1,6 @@ package org.bouncycastle.asn1.cms; -import java.util.Enumeration; - +import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; @@ -256,54 +255,68 @@ public ASN1Primitive toASN1Primitive() public static int calculateVersion(OriginatorInfo origInfo) { - if (origInfo == null) - { - return 0; - } - else + /* + * IF (originatorInfo is present) AND + * ((any certificates with a type of other are present) OR + * (any crls with a type of other are present)) + * THEN version is 3 + * ELSE + * IF ((originatorInfo is present) AND + * (any version 2 attribute certificates are present)) + * THEN version is 1 + * ELSE version is 0 + */ + + if (origInfo != null) { - int ver = 0; - - for (Enumeration e = origInfo.getCertificates().getObjects(); e.hasMoreElements();) + ASN1Set crls = origInfo.getCRLs(); + if (crls != null) { - Object obj = e.nextElement(); - - if (obj instanceof ASN1TaggedObject) + for (int i = 0, count = crls.size(); i < count; ++i) { - ASN1TaggedObject tag = (ASN1TaggedObject)obj; - - if (tag.getTagNo() == 2) - { - ver = 1; - } - else if (tag.getTagNo() == 3) + ASN1Encodable element = crls.getObjectAt(i); + if (element instanceof ASN1TaggedObject) { - ver = 3; - break; + ASN1TaggedObject tagged = (ASN1TaggedObject)element; + + // RevocationInfoChoice.other + if (tagged.hasContextTag(1)) + { + return 3; + } } } } - if (origInfo.getCRLs() != null) + ASN1Set certs = origInfo.getCertificates(); + if (certs != null) { - for (Enumeration e = origInfo.getCRLs().getObjects(); e.hasMoreElements();) - { - Object obj = e.nextElement(); + boolean anyV2AttrCerts = false; - if (obj instanceof ASN1TaggedObject) + for (int i = 0, count = certs.size(); i < count; ++i) + { + ASN1Encodable element = certs.getObjectAt(i); + if (element instanceof ASN1TaggedObject) { - ASN1TaggedObject tag = (ASN1TaggedObject)obj; + ASN1TaggedObject tagged = (ASN1TaggedObject)element; - if (tag.getTagNo() == 1) + // CertificateChoices.other + if (tagged.hasContextTag(3)) { - ver = 3; - break; + return 3; } + + // CertificateChoices.v2AttrCert + anyV2AttrCerts = anyV2AttrCerts || tagged.hasContextTag(2); } } - } - return ver; + if (anyV2AttrCerts) + { + return 1; + } + } } + return 0; } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/CMSObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/cms/CMSObjectIdentifiers.java index 13cd14dfe1..c2e910bcef 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/CMSObjectIdentifiers.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/CMSObjectIdentifiers.java @@ -59,4 +59,10 @@ public interface CMSObjectIdentifiers ASN1ObjectIdentifier id_ori = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.13"); ASN1ObjectIdentifier id_ori_kem = id_ori.branch("3"); + + /** + * id-alg-cek-hkdf-sha256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) + * us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 31 } + */ + ASN1ObjectIdentifier id_alg_cek_hkdf_sha256 = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.31"); } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java index 8b8603b75e..f35c844977 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java @@ -9,6 +9,7 @@ import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.BERTaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DLSequence; @@ -84,13 +85,13 @@ private ContentInfo( if (seq.size() > 1) { - ASN1TaggedObject tagged = (ASN1TaggedObject)seq.getObjectAt(1); + ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(seq.getObjectAt(1), BERTags.CONTEXT_SPECIFIC); if (!tagged.isExplicit() || tagged.getTagNo() != 0) { throw new IllegalArgumentException("Bad tag for 'content'"); } - content = tagged.getObject(); + content = tagged.getExplicitBaseObject(); } else { @@ -103,6 +104,12 @@ public ContentInfo( ASN1ObjectIdentifier contentType, ASN1Encodable content) { + // TODO[cms] Blocked by CMSSignedDataGenerator.generateCounterSigners transient usage of null here +// if (contentType == null) +// { +// throw new NullPointerException("'contentType' cannot be null"); +// } + this.contentType = contentType; this.content = content; if (content != null) diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/EnvelopedData.java b/util/src/main/java/org/bouncycastle/asn1/cms/EnvelopedData.java index 8d5738ab2c..29c4845111 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/EnvelopedData.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/EnvelopedData.java @@ -1,7 +1,5 @@ package org.bouncycastle.asn1.cms; -import java.util.Enumeration; - import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; @@ -184,42 +182,100 @@ public ASN1Primitive toASN1Primitive() public static int calculateVersion(OriginatorInfo originatorInfo, ASN1Set recipientInfos, ASN1Set unprotectedAttrs) { - // TODO: still not quite correct - Enumeration e = recipientInfos.getObjects(); - - boolean nonZeroFound = false; - boolean pwriOrOri = false; + /* + * IF (originatorInfo is present) AND + * ((any certificates with a type of other are present) OR + * (any crls with a type of other are present)) + * THEN version is 4 + * ELSE + * IF ((originatorInfo is present) AND + * (any version 2 attribute certificates are present)) OR + * (any RecipientInfo structures include pwri) OR + * (any RecipientInfo structures include ori) + * THEN version is 3 + * ELSE + * IF (originatorInfo is absent) AND + * (unprotectedAttrs is absent) AND + * (all RecipientInfo structures are version 0) + * THEN version is 0 + * ELSE version is 2 + */ - while (e.hasMoreElements()) + if (originatorInfo != null) { - RecipientInfo ri = RecipientInfo.getInstance(e.nextElement()); - - if (!ri.getVersion().hasValue(0)) + ASN1Set crls = originatorInfo.getCRLs(); + if (crls != null) { - nonZeroFound = true; + for (int i = 0, count = crls.size(); i < count; ++i) + { + ASN1Encodable element = crls.getObjectAt(i); + if (element instanceof ASN1TaggedObject) + { + ASN1TaggedObject tagged = (ASN1TaggedObject)element; + + // RevocationInfoChoice.other + if (tagged.hasContextTag(1)) + { + return 4; + } + } + } } - ASN1Encodable info = ri.getInfo(); - if (info instanceof PasswordRecipientInfo || info instanceof OtherRecipientInfo) + + ASN1Set certs = originatorInfo.getCertificates(); + if (certs != null) { - pwriOrOri = true; + boolean anyV2AttrCerts = false; + + for (int i = 0, count = certs.size(); i < count; ++i) + { + ASN1Encodable element = certs.getObjectAt(i); + if (element instanceof ASN1TaggedObject) + { + ASN1TaggedObject tagged = (ASN1TaggedObject)element; + + // CertificateChoices.other + if (tagged.hasContextTag(3)) + { + return 4; + } + + // CertificateChoices.v2AttrCert + anyV2AttrCerts = anyV2AttrCerts || tagged.hasContextTag(2); + } + } + + if (anyV2AttrCerts) + { + return 3; + } } } - if (pwriOrOri) + boolean allV0Recipients = true; + for (int i = 0, count = recipientInfos.size(); i < count; ++i) { - return 3; - } + RecipientInfo recipientInfo = RecipientInfo.getInstance(recipientInfos.getObjectAt(i)); - if (nonZeroFound) - { - return 2; + // (any RecipientInfo structures include pwri) OR + // (any RecipientInfo structures include ori) + if (recipientInfo.isPasswordOrOther()) + { + return 3; + } + + // (all RecipientInfo structures are version 0) + // -- 'kari.version' is always 3 + // -- 'kekri.version' is always 4 + // -- 'pwri' and 'ori' have already been excluded + allV0Recipients = allV0Recipients && recipientInfo.isKeyTransV0(); } - if (originatorInfo != null || unprotectedAttrs != null) + if (originatorInfo == null && unprotectedAttrs == null && allV0Recipients) { - return 2; + return 0; } - return 0; + return 2; } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/Evidence.java b/util/src/main/java/org/bouncycastle/asn1/cms/Evidence.java index 48c02d49de..474ac9b43d 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/Evidence.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/Evidence.java @@ -5,6 +5,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.tsp.EvidenceRecord; @@ -78,7 +79,7 @@ public static Evidence getInstance(Object obj) } else if (obj instanceof ASN1TaggedObject) { - return new Evidence(ASN1TaggedObject.getInstance(obj)); + return new Evidence(ASN1TaggedObject.getInstance(obj, BERTags.CONTEXT_SPECIFIC)); } throw new IllegalArgumentException("unknown object in getInstance"); @@ -88,7 +89,12 @@ public static Evidence getInstance( ASN1TaggedObject obj, boolean explicit) { - return getInstance(obj.getObject()); // must be explicitly tagged + if (!explicit) + { + throw new IllegalArgumentException("choice item must be explicitly tagged"); + } + + return getInstance(obj.getExplicitBaseObject()); } public TimeStampTokenEvidence getTstEvidence() diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/KEMRecipientInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/KEMRecipientInfo.java index aeb2df8aa4..2dc74b84b3 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/KEMRecipientInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/KEMRecipientInfo.java @@ -12,16 +12,21 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** + *

      + * Defined in RFC 9629. + *

      + *
        *   KEMRecipientInfo ::= SEQUENCE {
        *     version CMSVersion,  -- always set to 0
        *     rid RecipientIdentifier,
        *     kem KEMAlgorithmIdentifier,
        *     kemct OCTET STRING,
        *     kdf KeyDerivationAlgorithmIdentifier,
      - *     kekLength INTEGER (1..MAX),
      + *     kekLength INTEGER (1..65535),
        *     ukm [0] EXPLICIT UserKeyingMaterial OPTIONAL,
        *     wrap KeyEncryptionAlgorithmIdentifier,
        *     encryptedKey EncryptedKey }
      + * 
      */ public class KEMRecipientInfo extends ASN1Object @@ -47,6 +52,10 @@ public KEMRecipientInfo(RecipientIdentifier rid, AlgorithmIdentifier kem, ASN1Oc { throw new NullPointerException("wrap cannot be null"); } + if (kekLength.intValueExact() > 65535) + { + throw new IllegalArgumentException("kekLength must be <= 65535"); + } this.cmsVersion = new ASN1Integer(0); this.rid = rid; this.kem = kem; @@ -74,9 +83,9 @@ else if (o != null) private KEMRecipientInfo(ASN1Sequence seq) { - if (seq.size() != 3) + if (seq.size() < 8 || seq.size() > 9) { - throw new IllegalArgumentException("sequence must consist of 3 elements"); + throw new IllegalArgumentException("bad sequence size: " + seq.size()); } cmsVersion = ASN1Integer.getInstance(seq.getObjectAt(0)); @@ -86,6 +95,11 @@ private KEMRecipientInfo(ASN1Sequence seq) kdf = AlgorithmIdentifier.getInstance(seq.getObjectAt(4)); kekLength = ASN1Integer.getInstance(seq.getObjectAt(5)); + if (kekLength.intValueExact() > 65535) + { + throw new IllegalArgumentException("kekLength must be <= 65535"); + } + int elt = 6; if (seq.getObjectAt(6) instanceof ASN1TaggedObject) { diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java b/util/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java index f67d3b88a3..98ca19a504 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java @@ -3,8 +3,8 @@ import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.ASN1Util; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -37,9 +37,14 @@ public static KeyAgreeRecipientIdentifier getInstance( ASN1TaggedObject obj, boolean explicit) { - return getInstance(ASN1Sequence.getInstance(obj, explicit)); + if (!explicit) + { + throw new IllegalArgumentException("choice item must be explicitly tagged"); + } + + return getInstance(obj.getExplicitBaseObject()); } - + /** * Return an KeyAgreeRecipientIdentifier object from the given object. *

      @@ -62,19 +67,20 @@ public static KeyAgreeRecipientIdentifier getInstance( { return (KeyAgreeRecipientIdentifier)obj; } - - if (obj instanceof ASN1Sequence) - { - return new KeyAgreeRecipientIdentifier(IssuerAndSerialNumber.getInstance(obj)); - } - - if (obj instanceof ASN1TaggedObject && ((ASN1TaggedObject)obj).getTagNo() == 0) + + if (obj instanceof ASN1TaggedObject) { - return new KeyAgreeRecipientIdentifier(RecipientKeyIdentifier.getInstance( - (ASN1TaggedObject)obj, false)); + ASN1TaggedObject taggedObject = (ASN1TaggedObject)obj; + if (taggedObject.hasContextTag(0)) + { + return new KeyAgreeRecipientIdentifier(RecipientKeyIdentifier.getInstance(taggedObject, false)); + } + + throw new IllegalArgumentException("Invalid KeyAgreeRecipientIdentifier tag: " + + ASN1Util.getTagText(taggedObject)); } - - throw new IllegalArgumentException("Invalid KeyAgreeRecipientIdentifier: " + obj.getClass().getName()); + + return new KeyAgreeRecipientIdentifier(IssuerAndSerialNumber.getInstance(obj)); } public KeyAgreeRecipientIdentifier( diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java b/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java index 0dbeb4bae4..de35fdb3df 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; @@ -84,7 +85,7 @@ public static OriginatorIdentifierOrKey getInstance( "Can't implicitly tag OriginatorIdentifierOrKey"); } - return getInstance(o.getObject()); + return getInstance(o.getExplicitBaseObject()); } /** @@ -101,30 +102,35 @@ public static OriginatorIdentifierOrKey getInstance( * @param o the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ - public static OriginatorIdentifierOrKey getInstance( - Object o) + public static OriginatorIdentifierOrKey getInstance(Object o) { if (o == null || o instanceof OriginatorIdentifierOrKey) { return (OriginatorIdentifierOrKey)o; } - if (o instanceof IssuerAndSerialNumber || o instanceof ASN1Sequence) + if (o instanceof IssuerAndSerialNumber) + { + return new OriginatorIdentifierOrKey((IssuerAndSerialNumber)o); + } + + if (o instanceof ASN1Sequence) { return new OriginatorIdentifierOrKey(IssuerAndSerialNumber.getInstance(o)); } if (o instanceof ASN1TaggedObject) { - ASN1TaggedObject tagged = (ASN1TaggedObject)o; + ASN1TaggedObject taggedObject = (ASN1TaggedObject)o; - if (tagged.getTagNo() == 0) + if (taggedObject.hasContextTag(0)) { - return new OriginatorIdentifierOrKey(SubjectKeyIdentifier.getInstance(tagged, false)); + return new OriginatorIdentifierOrKey(SubjectKeyIdentifier.getInstance(taggedObject, false)); } - else if (tagged.getTagNo() == 1) + + if (taggedObject.hasContextTag(1)) { - return new OriginatorIdentifierOrKey(OriginatorPublicKey.getInstance(tagged, false)); + return new OriginatorIdentifierOrKey(OriginatorPublicKey.getInstance(taggedObject, false)); } } @@ -148,9 +154,13 @@ public IssuerAndSerialNumber getIssuerAndSerialNumber() public SubjectKeyIdentifier getSubjectKeyIdentifier() { - if (id instanceof ASN1TaggedObject && ((ASN1TaggedObject)id).getTagNo() == 0) + if (id instanceof ASN1TaggedObject) { - return SubjectKeyIdentifier.getInstance((ASN1TaggedObject)id, false); + ASN1TaggedObject taggedObject = (ASN1TaggedObject)id; + if (taggedObject.hasContextTag(0)) + { + return SubjectKeyIdentifier.getInstance(taggedObject, false); + } } return null; @@ -158,9 +168,13 @@ public SubjectKeyIdentifier getSubjectKeyIdentifier() public OriginatorPublicKey getOriginatorKey() { - if (id instanceof ASN1TaggedObject && ((ASN1TaggedObject)id).getTagNo() == 1) + if (id instanceof ASN1TaggedObject) { - return OriginatorPublicKey.getInstance((ASN1TaggedObject)id, false); + ASN1TaggedObject taggedObject = (ASN1TaggedObject)id; + if (taggedObject.hasContextTag(1)) + { + return OriginatorPublicKey.getInstance(taggedObject, false); + } } return null; diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorPublicKey.java b/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorPublicKey.java index 44696d66dd..c35f9c0ac3 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorPublicKey.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorPublicKey.java @@ -1,5 +1,6 @@ package org.bouncycastle.asn1.cms; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; @@ -24,8 +25,8 @@ public class OriginatorPublicKey extends ASN1Object { private AlgorithmIdentifier algorithm; - private DERBitString publicKey; - + private ASN1BitString publicKey; + public OriginatorPublicKey( AlgorithmIdentifier algorithm, byte[] publicKey) @@ -34,6 +35,14 @@ public OriginatorPublicKey( this.publicKey = new DERBitString(publicKey); } + public OriginatorPublicKey( + AlgorithmIdentifier algorithm, + ASN1BitString publicKey) + { + this.algorithm = algorithm; + this.publicKey = publicKey; + } + private OriginatorPublicKey( ASN1Sequence seq) { @@ -54,7 +63,7 @@ public static OriginatorPublicKey getInstance( ASN1TaggedObject obj, boolean explicit) { - return getInstance(ASN1Sequence.getInstance(obj, explicit)); + return new OriginatorPublicKey(ASN1Sequence.getInstance(obj, explicit)); } /** @@ -91,7 +100,15 @@ public AlgorithmIdentifier getAlgorithm() return algorithm; } + /** + * @deprecated Use {@link #getPublicKeyData()} instead. + */ public DERBitString getPublicKey() + { + return DERBitString.convert(publicKey); + } + + public ASN1BitString getPublicKeyData() { return publicKey; } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/OtherKeyAttribute.java b/util/src/main/java/org/bouncycastle/asn1/cms/OtherKeyAttribute.java index c141a54b82..ca97ae7dc8 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/OtherKeyAttribute.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/OtherKeyAttribute.java @@ -57,7 +57,11 @@ private OtherKeyAttribute( ASN1Sequence seq) { keyAttrId = (ASN1ObjectIdentifier)seq.getObjectAt(0); - keyAttr = seq.getObjectAt(1); + + if (seq.size() > 1) + { + keyAttr = seq.getObjectAt(1); + } } public OtherKeyAttribute( @@ -86,7 +90,11 @@ public ASN1Primitive toASN1Primitive() ASN1EncodableVector v = new ASN1EncodableVector(2); v.add(keyAttrId); - v.add(keyAttr); + + if (keyAttr != null) + { + v.add(keyAttr); + } return new DERSequence(v); } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/RecipientInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/RecipientInfo.java index 01ea91a670..23f6c0a043 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/RecipientInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/RecipientInfo.java @@ -98,69 +98,68 @@ else if (o instanceof ASN1TaggedObject) + o.getClass().getName()); } + /** @deprecated Will be removed */ public ASN1Integer getVersion() { - if (info instanceof ASN1TaggedObject) + if (!(info instanceof ASN1TaggedObject)) { - ASN1TaggedObject o = (ASN1TaggedObject)info; + return KeyTransRecipientInfo.getInstance(info).getVersion(); + } - switch (o.getTagNo()) + ASN1TaggedObject tagged = (ASN1TaggedObject)info; + if (tagged.hasContextTag()) + { + switch (tagged.getTagNo()) { case 1: - return KeyAgreeRecipientInfo.getInstance(o, false).getVersion(); + return KeyAgreeRecipientInfo.getInstance(tagged, false).getVersion(); case 2: - return getKEKInfo(o).getVersion(); + return getKEKInfo(tagged).getVersion(); case 3: - return PasswordRecipientInfo.getInstance(o, false).getVersion(); + return PasswordRecipientInfo.getInstance(tagged, false).getVersion(); case 4: return new ASN1Integer(0); // no syntax version for OtherRecipientInfo - default: - throw new IllegalStateException("unknown tag"); } } - - return KeyTransRecipientInfo.getInstance(info).getVersion(); + throw new IllegalStateException("unknown tag"); } public boolean isTagged() { - return (info instanceof ASN1TaggedObject); + return info instanceof ASN1TaggedObject; } public ASN1Encodable getInfo() { - if (info instanceof ASN1TaggedObject) + if (!(info instanceof ASN1TaggedObject)) { - ASN1TaggedObject o = (ASN1TaggedObject)info; + return KeyTransRecipientInfo.getInstance(info); + } - switch (o.getTagNo()) + ASN1TaggedObject tagged = (ASN1TaggedObject)info; + if (tagged.hasContextTag()) + { + switch (tagged.getTagNo()) { case 1: - return KeyAgreeRecipientInfo.getInstance(o, false); + return KeyAgreeRecipientInfo.getInstance(tagged, false); case 2: - return getKEKInfo(o); + return getKEKInfo(tagged); case 3: - return PasswordRecipientInfo.getInstance(o, false); + return PasswordRecipientInfo.getInstance(tagged, false); case 4: - return OtherRecipientInfo.getInstance(o, false); - default: - throw new IllegalStateException("unknown tag"); + return OtherRecipientInfo.getInstance(tagged, false); } } - - return KeyTransRecipientInfo.getInstance(info); + throw new IllegalStateException("unknown tag"); } private KEKRecipientInfo getKEKInfo(ASN1TaggedObject o) { - if (o.isExplicit()) - { // compatibilty with erroneous version - return KEKRecipientInfo.getInstance(o, true); - } - else - { - return KEKRecipientInfo.getInstance(o, false); - } + // For compatibility with erroneous version, we don't always pass 'false' here + boolean declaredExplicit = o.isExplicit(); + + return KEKRecipientInfo.getInstance(o, declaredExplicit); } /** @@ -170,4 +169,34 @@ public ASN1Primitive toASN1Primitive() { return info.toASN1Primitive(); } + + boolean isKeyTransV0() + { + if (info instanceof ASN1TaggedObject) + { + return false; + } + + KeyTransRecipientInfo ktri = KeyTransRecipientInfo.getInstance(info); + + return ktri.getVersion().hasValue(0); + } + + boolean isPasswordOrOther() + { + if (info instanceof ASN1TaggedObject) + { + ASN1TaggedObject tagged = (ASN1TaggedObject)info; + if (tagged.hasContextTag()) + { + switch (tagged.getTagNo()) + { + case 3: + case 4: + return true; + } + } + } + return false; + } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/Time.java b/util/src/main/java/org/bouncycastle/asn1/cms/Time.java index 1f91c28ac9..ecc9b199c6 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/Time.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/Time.java @@ -42,7 +42,12 @@ public static Time getInstance( ASN1TaggedObject obj, boolean explicit) { - return getInstance(obj.getObject()); + if (!explicit) + { + throw new IllegalArgumentException("choice item must be explicitly tagged"); + } + + return getInstance(obj.getExplicitBaseObject()); } private Time( diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/TimeStampAndCRL.java b/util/src/main/java/org/bouncycastle/asn1/cms/TimeStampAndCRL.java index dfa97a9433..3a89834d46 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/TimeStampAndCRL.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/TimeStampAndCRL.java @@ -24,8 +24,14 @@ public class TimeStampAndCRL private CertificateList crl; public TimeStampAndCRL(ContentInfo timeStamp) + { + this(timeStamp, null); + } + + public TimeStampAndCRL(ContentInfo timeStamp, CertificateList crl) { this.timeStamp = timeStamp; + this.crl = crl; } private TimeStampAndCRL(ASN1Sequence seq) diff --git a/util/src/main/java/org/bouncycastle/asn1/crmf/CertReqMsg.java b/util/src/main/java/org/bouncycastle/asn1/crmf/CertReqMsg.java index db225f283c..4d83f1c78d 100644 --- a/util/src/main/java/org/bouncycastle/asn1/crmf/CertReqMsg.java +++ b/util/src/main/java/org/bouncycastle/asn1/crmf/CertReqMsg.java @@ -88,16 +88,14 @@ public CertRequest getCertReq() return certReq; } - - /** - * @deprecated use getPopo - */ public ProofOfPossession getPop() { return pop; } - + /** + * @deprecated use getPop + */ public ProofOfPossession getPopo() { return pop; diff --git a/util/src/main/java/org/bouncycastle/asn1/crmf/PKIArchiveOptions.java b/util/src/main/java/org/bouncycastle/asn1/crmf/PKIArchiveOptions.java index 46e0e44ce2..e97bcbea8a 100644 --- a/util/src/main/java/org/bouncycastle/asn1/crmf/PKIArchiveOptions.java +++ b/util/src/main/java/org/bouncycastle/asn1/crmf/PKIArchiveOptions.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; public class PKIArchiveOptions @@ -27,7 +28,7 @@ public static PKIArchiveOptions getInstance(Object o) } else if (o instanceof ASN1TaggedObject) { - return new PKIArchiveOptions((ASN1TaggedObject)o); + return new PKIArchiveOptions(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } throw new IllegalArgumentException("unknown object: " + o); @@ -38,7 +39,7 @@ private PKIArchiveOptions(ASN1TaggedObject tagged) switch (tagged.getTagNo()) { case encryptedPrivKey: - value = EncryptedKey.getInstance(tagged.getObject()); + value = EncryptedKey.getInstance(tagged.getExplicitBaseObject()); break; case keyGenParameters: value = ASN1OctetString.getInstance(tagged, false); diff --git a/util/src/main/java/org/bouncycastle/asn1/crmf/POPOPrivKey.java b/util/src/main/java/org/bouncycastle/asn1/crmf/POPOPrivKey.java index 82500afb0e..5165acfa0b 100644 --- a/util/src/main/java/org/bouncycastle/asn1/crmf/POPOPrivKey.java +++ b/util/src/main/java/org/bouncycastle/asn1/crmf/POPOPrivKey.java @@ -1,12 +1,12 @@ package org.bouncycastle.asn1.crmf; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.EnvelopedData; @@ -30,13 +30,13 @@ private POPOPrivKey(ASN1TaggedObject obj) switch (tagNo) { case thisMessage: - this.obj = DERBitString.getInstance(obj, false); + this.obj = ASN1BitString.getInstance(obj, false); break; case subsequentMessage: this.obj = SubsequentMessage.valueOf(ASN1Integer.getInstance(obj, false).intValueExact()); break; case dhMAC: - this.obj = DERBitString.getInstance(obj, false); + this.obj = ASN1BitString.getInstance(obj, false); break; case agreeMAC: this.obj = PKMACValue.getInstance(obj, false); diff --git a/util/src/main/java/org/bouncycastle/asn1/crmf/POPOSigningKey.java b/util/src/main/java/org/bouncycastle/asn1/crmf/POPOSigningKey.java index 8aac0736d3..956d3d24b8 100644 --- a/util/src/main/java/org/bouncycastle/asn1/crmf/POPOSigningKey.java +++ b/util/src/main/java/org/bouncycastle/asn1/crmf/POPOSigningKey.java @@ -6,6 +6,8 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.ASN1Util; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; @@ -23,14 +25,10 @@ private POPOSigningKey(ASN1Sequence seq) if (seq.getObjectAt(index) instanceof ASN1TaggedObject) { - ASN1TaggedObject tagObj - = (ASN1TaggedObject)seq.getObjectAt(index++); - if (tagObj.getTagNo() != 0) - { - throw new IllegalArgumentException( - "Unknown POPOSigningKeyInput tag: " + tagObj.getTagNo()); - } - poposkInput = POPOSigningKeyInput.getInstance(tagObj.getObject()); + ASN1TaggedObject tagObj = (ASN1TaggedObject)seq.getObjectAt(index++); + + poposkInput = POPOSigningKeyInput.getInstance( + ASN1Util.getContextBaseUniversal(tagObj, 0, false, BERTags.SEQUENCE)); } algorithmIdentifier = AlgorithmIdentifier.getInstance(seq.getObjectAt(index++)); signature = ASN1BitString.getInstance(seq.getObjectAt(index)); diff --git a/util/src/main/java/org/bouncycastle/asn1/crmf/POPOSigningKeyInput.java b/util/src/main/java/org/bouncycastle/asn1/crmf/POPOSigningKeyInput.java index d84474ef0c..3782b4cee8 100644 --- a/util/src/main/java/org/bouncycastle/asn1/crmf/POPOSigningKeyInput.java +++ b/util/src/main/java/org/bouncycastle/asn1/crmf/POPOSigningKeyInput.java @@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.ASN1Util; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.GeneralName; @@ -25,12 +26,8 @@ private POPOSigningKeyInput(ASN1Sequence seq) if (authInfo instanceof ASN1TaggedObject) { ASN1TaggedObject tagObj = (ASN1TaggedObject)authInfo; - if (tagObj.getTagNo() != 0) - { - throw new IllegalArgumentException( - "Unknown authInfo tag: " + tagObj.getTagNo()); - } - sender = GeneralName.getInstance(tagObj.getObject()); + + sender = GeneralName.getInstance(ASN1Util.getExplicitContextBaseObject(tagObj, 0)); } else { diff --git a/core/src/main/java/org/bouncycastle/asn1/cryptlib/CryptlibObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/cryptlib/CryptlibObjectIdentifiers.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/cryptlib/CryptlibObjectIdentifiers.java rename to util/src/main/java/org/bouncycastle/asn1/cryptlib/CryptlibObjectIdentifiers.java diff --git a/util/src/main/java/org/bouncycastle/asn1/dvcs/CertEtcToken.java b/util/src/main/java/org/bouncycastle/asn1/dvcs/CertEtcToken.java index 3f69c52f00..c54c03c185 100644 --- a/util/src/main/java/org/bouncycastle/asn1/dvcs/CertEtcToken.java +++ b/util/src/main/java/org/bouncycastle/asn1/dvcs/CertEtcToken.java @@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cmp.PKIStatusInfo; import org.bouncycastle.asn1.cms.ContentInfo; @@ -79,19 +80,19 @@ private CertEtcToken(ASN1TaggedObject choice) value = Certificate.getInstance(choice, false); break; case TAG_ESSCERTID: - value = ESSCertID.getInstance(choice.getObject()); + value = ESSCertID.getInstance(choice.getExplicitBaseObject()); break; case TAG_PKISTATUS: value = PKIStatusInfo.getInstance(choice, false); break; case TAG_ASSERTION: - value = ContentInfo.getInstance(choice.getObject()); + value = ContentInfo.getInstance(choice.getExplicitBaseObject()); break; case TAG_CRL: value = CertificateList.getInstance(choice, false); break; case TAG_OCSPCERTSTATUS: - value = CertStatus.getInstance(choice.getObject()); + value = CertStatus.getInstance(choice.getExplicitBaseObject()); break; case TAG_OCSPCERTID: value = CertID.getInstance(choice, false); @@ -100,7 +101,7 @@ private CertEtcToken(ASN1TaggedObject choice) value = OCSPResponse.getInstance(choice, false); break; case TAG_CAPABILITIES: - value = SMIMECapabilities.getInstance(choice.getObject()); + value = SMIMECapabilities.getInstance(choice.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("Unknown tag: " + tagNo); @@ -115,7 +116,7 @@ public static CertEtcToken getInstance(Object obj) } else if (obj instanceof ASN1TaggedObject) { - return new CertEtcToken((ASN1TaggedObject)obj); + return new CertEtcToken(ASN1TaggedObject.getInstance(obj, BERTags.CONTEXT_SPECIFIC)); } else if (obj != null) { diff --git a/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSTime.java b/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSTime.java index 1d67a10ced..2ad99baeb6 100644 --- a/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSTime.java +++ b/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSTime.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.cms.ContentInfo; /** @@ -65,7 +66,12 @@ public static DVCSTime getInstance( ASN1TaggedObject obj, boolean explicit) { - return getInstance(obj.getObject()); // must be explicitly tagged + if (!explicit) + { + throw new IllegalArgumentException("choice item must be explicitly tagged"); + } + + return getInstance(ASN1TaggedObject.getInstance(obj, BERTags.CONTEXT_SPECIFIC).getExplicitBaseObject()); // must be explicitly tagged } diff --git a/util/src/main/java/org/bouncycastle/asn1/dvcs/Data.java b/util/src/main/java/org/bouncycastle/asn1/dvcs/Data.java index 9c661f1f7b..863e6cde3a 100644 --- a/util/src/main/java/org/bouncycastle/asn1/dvcs/Data.java +++ b/util/src/main/java/org/bouncycastle/asn1/dvcs/Data.java @@ -85,7 +85,7 @@ public static Data getInstance( ASN1TaggedObject obj, boolean explicit) { - return getInstance(obj.getObject()); + return getInstance(obj.getExplicitBaseObject()); } public ASN1Primitive toASN1Primitive() diff --git a/util/src/main/java/org/bouncycastle/asn1/eac/CVCertificate.java b/util/src/main/java/org/bouncycastle/asn1/eac/CVCertificate.java index 36b4b89cf4..085ea6c388 100644 --- a/util/src/main/java/org/bouncycastle/asn1/eac/CVCertificate.java +++ b/util/src/main/java/org/bouncycastle/asn1/eac/CVCertificate.java @@ -2,16 +2,19 @@ import java.io.IOException; +import java.util.Enumeration; -import org.bouncycastle.asn1.ASN1ApplicationSpecific; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1ParsingException; import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.DERApplicationSpecific; -import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; +import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.util.Arrays; @@ -36,35 +39,35 @@ public class CVCertificate /** * Sets the values of the certificate (body and signature). * - * @param appSpe is a ASN1ApplicationSpecific object containing body and signature. + * @param appSpe is a ASN1TaggedObject object containing body and signature. * @throws IOException if tags or value are incorrect. */ - private void setPrivateData(ASN1ApplicationSpecific appSpe) + private void setPrivateData(ASN1TaggedObject appSpe) throws IOException { valid = 0; - if (appSpe.getApplicationTag() == EACTags.CARDHOLDER_CERTIFICATE) + if (appSpe.hasTag(BERTags.APPLICATION, EACTags.CARDHOLDER_CERTIFICATE)) { - ASN1InputStream content = new ASN1InputStream(appSpe.getContents()); - ASN1Primitive tmpObj; - while ((tmpObj = content.readObject()) != null) + ASN1Sequence content = ASN1Sequence.getInstance(appSpe.getBaseUniversal(false, BERTags.SEQUENCE)); + Enumeration en = content.getObjects(); + while (en.hasMoreElements()) { - ASN1ApplicationSpecific aSpe; - if (tmpObj instanceof ASN1ApplicationSpecific) + Object obj = en.nextElement(); + if (obj instanceof ASN1TaggedObject) { - aSpe = (ASN1ApplicationSpecific)tmpObj; - switch (aSpe.getApplicationTag()) + ASN1TaggedObject aSpe = ASN1TaggedObject.getInstance(obj, BERTags.APPLICATION); + switch (aSpe.getTagNo()) { case EACTags.CERTIFICATE_CONTENT_TEMPLATE: certificateBody = CertificateBody.getInstance(aSpe); valid |= bodyValid; break; case EACTags.STATIC_INTERNAL_AUTHENTIFICATION_ONE_STEP: - signature = aSpe.getContents(); + signature = ASN1OctetString.getInstance(aSpe.getBaseUniversal(false, BERTags.OCTET_STRING)).getOctets(); valid |= signValid; break; default: - throw new IOException("Invalid tag, not an Iso7816CertificateStructure :" + aSpe.getApplicationTag()); + throw new IOException("Invalid tag, not an Iso7816CertificateStructure :" + aSpe.getTagNo()); } } else @@ -72,16 +75,15 @@ private void setPrivateData(ASN1ApplicationSpecific appSpe) throw new IOException("Invalid Object, not an Iso7816CertificateStructure"); } } - content.close(); } else { - throw new IOException("not a CARDHOLDER_CERTIFICATE :" + appSpe.getApplicationTag()); + throw new IOException("not a CARDHOLDER_CERTIFICATE :" + appSpe.getTagNo()); } if (valid != (signValid | bodyValid)) { - throw new IOException("invalid CARDHOLDER_CERTIFICATE :" + appSpe.getApplicationTag()); + throw new IOException("invalid CARDHOLDER_CERTIFICATE :" + appSpe.getTagNo()); } } @@ -103,9 +105,9 @@ private void initFrom(ASN1InputStream aIS) ASN1Primitive obj; while ((obj = aIS.readObject()) != null) { - if (obj instanceof ASN1ApplicationSpecific) + if (obj instanceof ASN1TaggedObject) { - setPrivateData((ASN1ApplicationSpecific)obj); + setPrivateData((ASN1TaggedObject)obj); } else { @@ -115,13 +117,13 @@ private void initFrom(ASN1InputStream aIS) } /** - * Create an iso7816Certificate structure from a ASN1ApplicationSpecific. + * Create an iso7816Certificate structure from a ASN1TaggedObject. * - * @param appSpe the ASN1ApplicationSpecific object. - * @return the Iso7816CertificateStructure represented by the ASN1ApplicationSpecific object. + * @param appSpe the ASN1TaggedObject object. + * @return the Iso7816CertificateStructure represented by the ASN1TaggedObject object. * @throws IOException if there is a problem parsing the data. */ - private CVCertificate(ASN1ApplicationSpecific appSpe) + private CVCertificate(ASN1TaggedObject appSpe) throws IOException { setPrivateData(appSpe); @@ -160,7 +162,7 @@ else if (obj != null) { try { - return new CVCertificate((ASN1ApplicationSpecific)ASN1ApplicationSpecific.getInstance(obj)); + return new CVCertificate(ASN1TaggedObject.getInstance(obj, BERTags.APPLICATION)); } catch (IOException e) { @@ -200,17 +202,9 @@ public ASN1Primitive toASN1Primitive() ASN1EncodableVector v = new ASN1EncodableVector(2); v.add(certificateBody); + v.add(EACTagged.create(EACTags.STATIC_INTERNAL_AUTHENTIFICATION_ONE_STEP, signature)); - try - { - v.add(new DERApplicationSpecific(false, EACTags.STATIC_INTERNAL_AUTHENTIFICATION_ONE_STEP, new DEROctetString(signature))); - } - catch (IOException e) - { - throw new IllegalStateException("unable to convert signature!"); - } - - return new DERApplicationSpecific(EACTags.CARDHOLDER_CERTIFICATE, v); + return EACTagged.create(EACTags.CARDHOLDER_CERTIFICATE, new DERSequence(v)); } /** diff --git a/util/src/main/java/org/bouncycastle/asn1/eac/CVCertificateRequest.java b/util/src/main/java/org/bouncycastle/asn1/eac/CVCertificateRequest.java index 2c03b42704..8a11b2c902 100644 --- a/util/src/main/java/org/bouncycastle/asn1/eac/CVCertificateRequest.java +++ b/util/src/main/java/org/bouncycastle/asn1/eac/CVCertificateRequest.java @@ -3,21 +3,21 @@ import java.io.IOException; import java.util.Enumeration; -import org.bouncycastle.asn1.ASN1ApplicationSpecific; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1ParsingException; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERTags; -import org.bouncycastle.asn1.DERApplicationSpecific; -import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.util.Arrays; public class CVCertificateRequest extends ASN1Object { - private final ASN1ApplicationSpecific original; + private final ASN1TaggedObject original; private CertificateBody certificateBody; @@ -27,18 +27,19 @@ public class CVCertificateRequest private static final int bodyValid = 0x01; private static final int signValid = 0x02; - private CVCertificateRequest(ASN1ApplicationSpecific request) + private CVCertificateRequest(ASN1TaggedObject request) throws IOException { this.original = request; - if (request.isConstructed() && request.getApplicationTag() == EACTags.AUTHENTIFICATION_DATA) + if (request.hasTag(BERTags.APPLICATION, EACTags.AUTHENTIFICATION_DATA)) { - ASN1Sequence seq = ASN1Sequence.getInstance(request.getObject(BERTags.SEQUENCE)); + ASN1Sequence seq = ASN1Sequence.getInstance(request.getBaseUniversal(false, BERTags.SEQUENCE)); - initCertBody((ASN1ApplicationSpecific)ASN1ApplicationSpecific.getInstance(seq.getObjectAt(0))); + initCertBody(ASN1TaggedObject.getInstance(seq.getObjectAt(0), BERTags.APPLICATION)); - outerSignature = ((ASN1ApplicationSpecific)ASN1ApplicationSpecific.getInstance(seq.getObjectAt(seq.size() - 1))).getContents(); + outerSignature = ASN1OctetString.getInstance( + ASN1TaggedObject.getInstance(seq.getObjectAt(seq.size() - 1)).getBaseUniversal(false, BERTags.OCTET_STRING)).getOctets(); } else { @@ -46,38 +47,39 @@ private CVCertificateRequest(ASN1ApplicationSpecific request) } } - private void initCertBody(ASN1ApplicationSpecific request) + private void initCertBody(ASN1TaggedObject request) throws IOException { - if (request.getApplicationTag() == EACTags.CARDHOLDER_CERTIFICATE) + if (request.hasTag(BERTags.APPLICATION, EACTags.CARDHOLDER_CERTIFICATE)) { int valid = 0; - ASN1Sequence seq = ASN1Sequence.getInstance(request.getObject(BERTags.SEQUENCE)); + ASN1Sequence seq = ASN1Sequence.getInstance(request.getBaseUniversal(false, BERTags.SEQUENCE)); for (Enumeration en = seq.getObjects(); en.hasMoreElements();) { - ASN1ApplicationSpecific obj = (ASN1ApplicationSpecific)ASN1ApplicationSpecific.getInstance(en.nextElement()); - switch (obj.getApplicationTag()) + ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(en.nextElement(), BERTags.APPLICATION); + switch (tObj.getTagNo()) { case EACTags.CERTIFICATE_CONTENT_TEMPLATE: - certificateBody = CertificateBody.getInstance(obj); + certificateBody = CertificateBody.getInstance(tObj); valid |= bodyValid; break; case EACTags.STATIC_INTERNAL_AUTHENTIFICATION_ONE_STEP: - innerSignature = obj.getContents(); + innerSignature = ASN1OctetString.getInstance( + tObj.getBaseUniversal(false, BERTags.OCTET_STRING)).getOctets(); valid |= signValid; break; default: - throw new IOException("Invalid tag, not an CV Certificate Request element:" + obj.getApplicationTag()); + throw new IOException("Invalid tag, not an CV Certificate Request element:" + tObj.getTagNo()); } } if ((valid & (bodyValid | signValid)) == 0) { - throw new IOException("Invalid CARDHOLDER_CERTIFICATE in request:" + request.getApplicationTag()); + throw new IOException("Invalid CARDHOLDER_CERTIFICATE in request:" + request.getTagNo()); } } else { - throw new IOException("not a CARDHOLDER_CERTIFICATE in request:" + request.getApplicationTag()); + throw new IOException("not a CARDHOLDER_CERTIFICATE in request:" + request.getTagNo()); } } @@ -91,7 +93,7 @@ else if (obj != null) { try { - return new CVCertificateRequest((ASN1ApplicationSpecific)ASN1ApplicationSpecific.getInstance(obj)); + return new CVCertificateRequest(ASN1TaggedObject.getInstance(obj, BERTags.APPLICATION)); } catch (IOException e) { @@ -147,17 +149,9 @@ public ASN1Primitive toASN1Primitive() ASN1EncodableVector v = new ASN1EncodableVector(2); v.add(certificateBody); + v.add(EACTagged.create(EACTags.STATIC_INTERNAL_AUTHENTIFICATION_ONE_STEP, innerSignature)); - try - { - v.add(new DERApplicationSpecific(false, EACTags.STATIC_INTERNAL_AUTHENTIFICATION_ONE_STEP, new DEROctetString(innerSignature))); - } - catch (IOException e) - { - throw new IllegalStateException("unable to convert signature!"); - } - - return new DERApplicationSpecific(EACTags.CARDHOLDER_CERTIFICATE, v); + return EACTagged.create(EACTags.CARDHOLDER_CERTIFICATE, new DERSequence(v)); } } } diff --git a/util/src/main/java/org/bouncycastle/asn1/eac/CertificateBody.java b/util/src/main/java/org/bouncycastle/asn1/eac/CertificateBody.java index aec5320a04..ad79efa54b 100644 --- a/util/src/main/java/org/bouncycastle/asn1/eac/CertificateBody.java +++ b/util/src/main/java/org/bouncycastle/asn1/eac/CertificateBody.java @@ -2,14 +2,15 @@ import java.io.IOException; -import org.bouncycastle.asn1.ASN1ApplicationSpecific; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERTags; -import org.bouncycastle.asn1.DERApplicationSpecific; -import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; /** @@ -17,24 +18,24 @@ *

        *  CertificateBody ::= SEQUENCE {
        *      // version of the certificate format. Must be 0 (version 1)
      - *      CertificateProfileIdentifer         ASN1ApplicationSpecific,
      - *      //uniquely identifies the issuinng CA's signature key pair
      + *      CertificateProfileIdentifer         ASN1TaggedObject,
      + *      // uniquely identifies the issuing CA's signature key pair
        *      // contains the iso3166-1 alpha2 encoded country code, the
        *      // name of issuer and the sequence number of the key pair.
      - *      CertificationAuthorityReference        ASN1ApplicationSpecific,
      + *      CertificationAuthorityReference        ASN1TaggedObject,
        *      // stores the encoded public key
        *      PublicKey                            Iso7816PublicKey,
      - *      //associates the public key contained in the certificate with a unique name
      + *      // associates the public key contained in the certificate with a unique name
        *      // contains the iso3166-1 alpha2 encoded country code, the
        *      // name of the holder and the sequence number of the key pair.
      - *      certificateHolderReference            ASN1ApplicationSpecific,
      + *      certificateHolderReference            ASN1TaggedObject,
        *      // Encodes the role of the holder (i.e. CVCA, DV, IS) and assigns read/write
        *      // access rights to data groups storing sensitive data
        *      certificateHolderAuthorization        Iso7816CertificateHolderAuthorization,
        *      // the date of the certificate generation
      - *      CertificateEffectiveDate            ASN1ApplicationSpecific,
      - *      // the date after wich the certificate expires
      - *      certificateExpirationDate            ASN1ApplicationSpecific
      + *      CertificateEffectiveDate            ASN1TaggedObject,
      + *      // the date after which the certificate expires
      + *      certificateExpirationDate            ASN1TaggedObject
        *  }
        * 
      */ @@ -42,13 +43,13 @@ public class CertificateBody extends ASN1Object { ASN1InputStream seq; - private ASN1ApplicationSpecific certificateProfileIdentifier;// version of the certificate format. Must be 0 (version 1) - private ASN1ApplicationSpecific certificationAuthorityReference;//uniquely identifies the issuinng CA's signature key pair + private ASN1TaggedObject certificateProfileIdentifier;// version of the certificate format. Must be 0 (version 1) + private ASN1TaggedObject certificationAuthorityReference;//uniquely identifies the issuing CA's signature key pair private PublicKeyDataObject publicKey;// stores the encoded public key - private ASN1ApplicationSpecific certificateHolderReference;//associates the public key contained in the certificate with a unique name + private ASN1TaggedObject certificateHolderReference;//associates the public key contained in the certificate with a unique name private CertificateHolderAuthorization certificateHolderAuthorization;// Encodes the role of the holder (i.e. CVCA, DV, IS) and assigns read/write access rights to data groups storing sensitive data - private ASN1ApplicationSpecific certificateEffectiveDate;// the date of the certificate generation - private ASN1ApplicationSpecific certificateExpirationDate;// the date after wich the certificate expires + private ASN1TaggedObject certificateEffectiveDate;// the date of the certificate generation + private ASN1TaggedObject certificateExpirationDate;// the date after which the certificate expires private int certificateType = 0;// bit field of initialized data. This will tell us if the data are valid. private static final int CPI = 0x01;//certificate Profile Identifier private static final int CAR = 0x02;//certification Authority Reference @@ -58,36 +59,34 @@ public class CertificateBody private static final int CEfD = 0x20;//certificate Effective Date private static final int CExD = 0x40;//certificate Expiration Date + /** @deprecated */ public static final int profileType = 0x7f;//Profile type Certificate + private static final int profileType_m = 0x7f;//Profile type Certificate MUST + private static final int profileType_r = 0x00;//Profile type Certificate SHOULD + + /** @deprecated */ public static final int requestType = 0x0D;// Request type Certificate + private static final int requestType_m = 0x0D;// Request type Certificate MUST + private static final int requestType_r = 0x02;// Request type Certificate SHOULD - private void setIso7816CertificateBody(ASN1ApplicationSpecific appSpe) + private void setIso7816CertificateBody(ASN1TaggedObject appSpe) throws IOException { - byte[] content; - if (appSpe.getApplicationTag() == EACTags.CERTIFICATE_CONTENT_TEMPLATE) + ASN1Sequence content; + if (appSpe.hasTag(BERTags.APPLICATION, EACTags.CERTIFICATE_CONTENT_TEMPLATE)) { - content = appSpe.getContents(); + content = ASN1Sequence.getInstance(appSpe.getBaseUniversal(false, BERTags.SEQUENCE)); } else { throw new IOException("Bad tag : not an iso7816 CERTIFICATE_CONTENT_TEMPLATE"); } - ASN1InputStream aIS = new ASN1InputStream(content); - ASN1Primitive obj; - while ((obj = aIS.readObject()) != null) + + for (int i = 0, count = content.size(); i < count; ++i) { - ASN1ApplicationSpecific aSpe; + ASN1TaggedObject aSpe = ASN1TaggedObject.getInstance(content.getObjectAt(i), BERTags.APPLICATION); - if (obj instanceof ASN1ApplicationSpecific) - { - aSpe = (ASN1ApplicationSpecific)obj; - } - else - { - throw new IOException("Not a valid iso7816 content : not a ASN1ApplicationSpecific Object :" + EACTags.encodeTag(appSpe) + obj.getClass()); - } - switch (aSpe.getApplicationTag()) + switch (aSpe.getTagNo()) { case EACTags.INTERCHANGE_PROFILE: setCertificateProfileIdentifier(aSpe); @@ -96,7 +95,7 @@ private void setIso7816CertificateBody(ASN1ApplicationSpecific appSpe) setCertificationAuthorityReference(aSpe); break; case EACTags.CARDHOLDER_PUBLIC_KEY_TEMPLATE: - setPublicKey(PublicKeyDataObject.getInstance(aSpe.getObject(BERTags.SEQUENCE))); + setPublicKey(PublicKeyDataObject.getInstance(aSpe.getBaseUniversal(false, BERTags.SEQUENCE))); break; case EACTags.CARDHOLDER_NAME: setCertificateHolderReference(aSpe); @@ -112,10 +111,9 @@ private void setIso7816CertificateBody(ASN1ApplicationSpecific appSpe) break; default: certificateType = 0; - throw new IOException("Not a valid iso7816 ASN1ApplicationSpecific tag " + aSpe.getApplicationTag()); + throw new IOException("Not a valid iso7816 ASN1TaggedObject tag " + aSpe.getTagNo()); } } - aIS.close(); } /** @@ -131,7 +129,7 @@ private void setIso7816CertificateBody(ASN1ApplicationSpecific appSpe) * @param certificateExpirationDate */ public CertificateBody( - ASN1ApplicationSpecific certificateProfileIdentifier, + ASN1TaggedObject certificateProfileIdentifier, CertificationAuthorityReference certificationAuthorityReference, PublicKeyDataObject publicKey, CertificateHolderReference certificateHolderReference, @@ -141,32 +139,21 @@ public CertificateBody( ) { setCertificateProfileIdentifier(certificateProfileIdentifier); - setCertificationAuthorityReference(new DERApplicationSpecific( - EACTags.ISSUER_IDENTIFICATION_NUMBER, certificationAuthorityReference.getEncoded())); + setCertificationAuthorityReference(EACTagged.create(EACTags.ISSUER_IDENTIFICATION_NUMBER, certificationAuthorityReference.getEncoded())); setPublicKey(publicKey); - setCertificateHolderReference(new DERApplicationSpecific( - EACTags.CARDHOLDER_NAME, certificateHolderReference.getEncoded())); + setCertificateHolderReference(EACTagged.create(EACTags.CARDHOLDER_NAME, certificateHolderReference.getEncoded())); setCertificateHolderAuthorization(certificateHolderAuthorization); - try - { - setCertificateEffectiveDate(new DERApplicationSpecific( - false, EACTags.APPLICATION_EFFECTIVE_DATE, new DEROctetString(certificateEffectiveDate.getEncoding()))); - setCertificateExpirationDate(new DERApplicationSpecific( - false, EACTags.APPLICATION_EXPIRATION_DATE, new DEROctetString(certificateExpirationDate.getEncoding()))); - } - catch (IOException e) - { - throw new IllegalArgumentException("unable to encode dates: " + e.getMessage()); - } + setCertificateEffectiveDate(EACTagged.create(EACTags.APPLICATION_EFFECTIVE_DATE, certificateEffectiveDate.getEncoding())); + setCertificateExpirationDate(EACTagged.create(EACTags.APPLICATION_EXPIRATION_DATE, certificateExpirationDate.getEncoding())); } /** * builds an Iso7816CertificateBody with an ASN1InputStream. * - * @param obj ASN1ApplicationSpecific containing the whole body. + * @param obj ASN1TaggedObject containing the whole body. * @throws IOException if the body is not valid. */ - private CertificateBody(ASN1ApplicationSpecific obj) + private CertificateBody(ASN1TaggedObject obj) throws IOException { setIso7816CertificateBody(obj); @@ -176,7 +163,7 @@ private CertificateBody(ASN1ApplicationSpecific obj) * create a profile type Iso7816CertificateBody. * * @return return the "profile" type certificate body. - * @throws IOException if the ASN1ApplicationSpecific cannot be created. + * @throws IOException if the ASN1TaggedObject cannot be created. */ private ASN1Primitive profileToASN1Object() throws IOException @@ -185,32 +172,32 @@ private ASN1Primitive profileToASN1Object() v.add(certificateProfileIdentifier); v.add(certificationAuthorityReference); - v.add(new DERApplicationSpecific(false, EACTags.CARDHOLDER_PUBLIC_KEY_TEMPLATE, publicKey)); + v.add(EACTagged.create(EACTags.CARDHOLDER_PUBLIC_KEY_TEMPLATE, publicKey)); v.add(certificateHolderReference); v.add(certificateHolderAuthorization); v.add(certificateEffectiveDate); v.add(certificateExpirationDate); - return new DERApplicationSpecific(EACTags.CERTIFICATE_CONTENT_TEMPLATE, v); + return EACTagged.create(EACTags.CERTIFICATE_CONTENT_TEMPLATE, new DERSequence(v)); } - private void setCertificateProfileIdentifier(ASN1ApplicationSpecific certificateProfileIdentifier) + private void setCertificateProfileIdentifier(ASN1TaggedObject certificateProfileIdentifier) throws IllegalArgumentException { - if (certificateProfileIdentifier.getApplicationTag() == EACTags.INTERCHANGE_PROFILE) + if (certificateProfileIdentifier.hasTag(BERTags.APPLICATION, EACTags.INTERCHANGE_PROFILE)) { this.certificateProfileIdentifier = certificateProfileIdentifier; certificateType |= CPI; } else { - throw new IllegalArgumentException("Not an Iso7816Tags.INTERCHANGE_PROFILE tag :" + EACTags.encodeTag(certificateProfileIdentifier)); + throw new IllegalArgumentException("Not an Iso7816Tags.INTERCHANGE_PROFILE tag :" + certificateProfileIdentifier.getTagNo()); } } - private void setCertificateHolderReference(ASN1ApplicationSpecific certificateHolderReference) + private void setCertificateHolderReference(ASN1TaggedObject certificateHolderReference) throws IllegalArgumentException { - if (certificateHolderReference.getApplicationTag() == EACTags.CARDHOLDER_NAME) + if (certificateHolderReference.hasTag(BERTags.APPLICATION, EACTags.CARDHOLDER_NAME)) { this.certificateHolderReference = certificateHolderReference; certificateType |= CHR; @@ -225,14 +212,14 @@ private void setCertificateHolderReference(ASN1ApplicationSpecific certificateHo * set the CertificationAuthorityReference. * * @param certificationAuthorityReference - * the ASN1ApplicationSpecific containing the CertificationAuthorityReference. - * @throws IllegalArgumentException if the ASN1ApplicationSpecific is not valid. + * the ASN1TaggedObject containing the CertificationAuthorityReference. + * @throws IllegalArgumentException if the ASN1TaggedObject is not valid. */ private void setCertificationAuthorityReference( - ASN1ApplicationSpecific certificationAuthorityReference) + ASN1TaggedObject certificationAuthorityReference) throws IllegalArgumentException { - if (certificationAuthorityReference.getApplicationTag() == EACTags.ISSUER_IDENTIFICATION_NUMBER) + if (certificationAuthorityReference.hasTag(BERTags.APPLICATION, EACTags.ISSUER_IDENTIFICATION_NUMBER)) { this.certificationAuthorityReference = certificationAuthorityReference; certificateType |= CAR; @@ -246,7 +233,7 @@ private void setCertificationAuthorityReference( /** * set the public Key * - * @param publicKey : the ASN1ApplicationSpecific containing the public key + * @param publicKey : the ASN1TaggedObject containing the public key * @throws java.io.IOException */ private void setPublicKey(PublicKeyDataObject publicKey) @@ -259,7 +246,7 @@ private void setPublicKey(PublicKeyDataObject publicKey) * create a request type Iso7816CertificateBody. * * @return return the "request" type certificate body. - * @throws IOException if the ASN1ApplicationSpecific cannot be created. + * @throws IOException if the ASN1TaggedObject cannot be created. */ private ASN1Primitive requestToASN1Object() throws IOException @@ -267,9 +254,13 @@ private ASN1Primitive requestToASN1Object() ASN1EncodableVector v = new ASN1EncodableVector(3); v.add(certificateProfileIdentifier); - v.add(new DERApplicationSpecific(false, EACTags.CARDHOLDER_PUBLIC_KEY_TEMPLATE, publicKey)); + if (certificationAuthorityReference != null) + { + v.add(certificationAuthorityReference); + } + v.add(EACTagged.create(EACTags.CARDHOLDER_PUBLIC_KEY_TEMPLATE, publicKey)); v.add(certificateHolderReference); - return new DERApplicationSpecific(EACTags.CERTIFICATE_CONTENT_TEMPLATE, v); + return EACTagged.create(EACTags.CERTIFICATE_CONTENT_TEMPLATE, new DERSequence(v)); } /** @@ -281,18 +272,17 @@ public ASN1Primitive toASN1Primitive() { try { - if (certificateType == profileType) + if ((certificateType & ~profileType_r) == profileType_m) { return profileToASN1Object(); } - if (certificateType == requestType) + if ((certificateType & ~requestType_r) == requestType_m) { return requestToASN1Object(); } } catch (IOException e) { - return null; } return null; } @@ -323,7 +313,7 @@ public static CertificateBody getInstance(Object obj) } else if (obj != null) { - return new CertificateBody((ASN1ApplicationSpecific)ASN1ApplicationSpecific.getInstance(obj)); + return new CertificateBody(ASN1TaggedObject.getInstance(obj, BERTags.APPLICATION)); } return null; @@ -337,7 +327,8 @@ public PackedDate getCertificateEffectiveDate() if ((this.certificateType & CertificateBody.CEfD) == CertificateBody.CEfD) { - return new PackedDate(certificateEffectiveDate.getContents()); + return new PackedDate( + ASN1OctetString.getInstance(certificateEffectiveDate.getBaseUniversal(false, BERTags.OCTET_STRING)).getOctets()); } return null; } @@ -345,25 +336,25 @@ public PackedDate getCertificateEffectiveDate() /** * set the date of the certificate generation * - * @param ced ASN1ApplicationSpecific containing the date of the certificate generation + * @param ced ASN1TaggedObject containing the date of the certificate generation * @throws IllegalArgumentException if the tag is not Iso7816Tags.APPLICATION_EFFECTIVE_DATE */ - private void setCertificateEffectiveDate(ASN1ApplicationSpecific ced) + private void setCertificateEffectiveDate(ASN1TaggedObject ced) throws IllegalArgumentException { - if (ced.getApplicationTag() == EACTags.APPLICATION_EFFECTIVE_DATE) + if (ced.hasTag(BERTags.APPLICATION, EACTags.APPLICATION_EFFECTIVE_DATE)) { this.certificateEffectiveDate = ced; certificateType |= CEfD; } else { - throw new IllegalArgumentException("Not an Iso7816Tags.APPLICATION_EFFECTIVE_DATE tag :" + EACTags.encodeTag(ced)); + throw new IllegalArgumentException("Not an Iso7816Tags.APPLICATION_EFFECTIVE_DATE tag :" + ced.getTagNo()); } } /** - * @return the date after wich the certificate expires + * @return the date after which the certificate expires */ public PackedDate getCertificateExpirationDate() throws IOException @@ -371,21 +362,22 @@ public PackedDate getCertificateExpirationDate() if ((this.certificateType & CertificateBody.CExD) == CertificateBody.CExD) { - return new PackedDate(certificateExpirationDate.getContents()); + return new PackedDate( + ASN1OctetString.getInstance(certificateExpirationDate.getBaseUniversal(false, BERTags.OCTET_STRING)).getOctets()); } throw new IOException("certificate Expiration Date not set"); } /** - * set the date after wich the certificate expires + * set the date after which the certificate expires * - * @param ced ASN1ApplicationSpecific containing the date after wich the certificate expires + * @param ced ASN1TaggedObject containing the date after which the certificate expires * @throws IllegalArgumentException if the tag is not Iso7816Tags.APPLICATION_EXPIRATION_DATE */ - private void setCertificateExpirationDate(ASN1ApplicationSpecific ced) + private void setCertificateExpirationDate(ASN1TaggedObject ced) throws IllegalArgumentException { - if (ced.getApplicationTag() == EACTags.APPLICATION_EXPIRATION_DATE) + if (ced.hasTag(BERTags.APPLICATION, EACTags.APPLICATION_EXPIRATION_DATE)) { this.certificateExpirationDate = ced; certificateType |= CExD; @@ -434,7 +426,8 @@ private void setCertificateHolderAuthorization( */ public CertificateHolderReference getCertificateHolderReference() { - return new CertificateHolderReference(certificateHolderReference.getContents()); + return new CertificateHolderReference( + ASN1OctetString.getInstance(certificateHolderReference.getBaseUniversal(false, BERTags.OCTET_STRING)).getOctets()); } /** @@ -442,14 +435,14 @@ public CertificateHolderReference getCertificateHolderReference() * * @return the CertificateProfileIdentifier */ - public ASN1ApplicationSpecific getCertificateProfileIdentifier() + public ASN1TaggedObject getCertificateProfileIdentifier() { return certificateProfileIdentifier; } /** * get the certificationAuthorityReference - * certificationAuthorityReference : uniquely identifies the issuinng CA's signature key pair + * certificationAuthorityReference : uniquely identifies the issuing CA's signature key pair * * @return the certificationAuthorityReference */ @@ -459,7 +452,8 @@ public CertificationAuthorityReference getCertificationAuthorityReference() if ((this.certificateType & CertificateBody.CAR) == CertificateBody.CAR) { - return new CertificationAuthorityReference(certificationAuthorityReference.getContents()); + return new CertificationAuthorityReference( + ASN1OctetString.getInstance(certificationAuthorityReference.getBaseUniversal(false, BERTags.OCTET_STRING)).getOctets()); } throw new IOException("Certification authority reference not set"); } diff --git a/util/src/main/java/org/bouncycastle/asn1/eac/CertificateHolderAuthorization.java b/util/src/main/java/org/bouncycastle/asn1/eac/CertificateHolderAuthorization.java index 49179aedbb..ae5f0ccd66 100644 --- a/util/src/main/java/org/bouncycastle/asn1/eac/CertificateHolderAuthorization.java +++ b/util/src/main/java/org/bouncycastle/asn1/eac/CertificateHolderAuthorization.java @@ -1,15 +1,18 @@ package org.bouncycastle.asn1.eac; import java.io.IOException; -import java.util.Hashtable; +import java.util.HashMap; +import java.util.Map; -import org.bouncycastle.asn1.ASN1ApplicationSpecific; import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.DERApplicationSpecific; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; +import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.util.Integers; /** @@ -20,16 +23,15 @@ * // level * ASN1ObjectIdentifier oid, * // access rights - * DERApplicationSpecific accessRights, + * ASN1TaggedObject accessRights, * } *
      */ public class CertificateHolderAuthorization extends ASN1Object { - ASN1ObjectIdentifier oid; - ASN1ApplicationSpecific accessRights; public static final ASN1ObjectIdentifier id_role_EAC = EACObjectIdentifiers.bsi_de.branch("3.1.2.1"); + public static final int CVCA = 0xC0; public static final int DV_DOMESTIC = 0x80; public static final int DV_FOREIGN = 0x40; @@ -37,9 +39,8 @@ public class CertificateHolderAuthorization public static final int RADG4 = 0x02;//Read Access to DG4 (Iris) public static final int RADG3 = 0x01;//Read Access to DG3 (fingerprint) - static Hashtable RightsDecodeMap = new Hashtable(); + static Map RightsDecodeMap = new HashMap(); static BidirectionalMap AuthorizationRole = new BidirectionalMap(); - static Hashtable ReverseMap = new Hashtable(); static { @@ -50,16 +51,11 @@ public class CertificateHolderAuthorization AuthorizationRole.put(Integers.valueOf(DV_DOMESTIC), "DV_DOMESTIC"); AuthorizationRole.put(Integers.valueOf(DV_FOREIGN), "DV_FOREIGN"); AuthorizationRole.put(Integers.valueOf(IS), "IS"); - - /* - for (int i : RightsDecodeMap.keySet()) - ReverseMap.put(RightsDecodeMap.get(i), i); - - for (int i : AuthorizationRole.keySet()) - ReverseMap.put(AuthorizationRole.get(i), i); - */ } + private ASN1ObjectIdentifier oid; + private byte accessRights; + public static String getRoleDescription(int i) { return (String)AuthorizationRole.get(Integers.valueOf(i)); @@ -76,11 +72,10 @@ public static int getFlag(String description) return i.intValue(); } - private void setPrivateData(ASN1InputStream cha) - throws IOException + private void setPrivateData(ASN1Sequence seq) { ASN1Primitive obj; - obj = cha.readObject(); + obj = (ASN1Primitive)seq.getObjectAt(0); if (obj instanceof ASN1ObjectIdentifier) { this.oid = (ASN1ObjectIdentifier)obj; @@ -89,10 +84,11 @@ private void setPrivateData(ASN1InputStream cha) { throw new IllegalArgumentException("no Oid in CerticateHolderAuthorization"); } - obj = cha.readObject(); - if (obj instanceof ASN1ApplicationSpecific) + obj = (ASN1Primitive)seq.getObjectAt(1); + if (obj instanceof ASN1TaggedObject) { - this.accessRights = (ASN1ApplicationSpecific)obj; + ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(obj, BERTags.APPLICATION, EACTags.DISCRETIONARY_DATA); + this.accessRights = ASN1OctetString.getInstance(tObj.getBaseUniversal(false, BERTags.OCTET_STRING)).getOctets()[0]; } else { @@ -117,17 +113,21 @@ public CertificateHolderAuthorization(ASN1ObjectIdentifier oid, int rights) } /** - * create an Iso7816CertificateHolderAuthorization according to the {@link ASN1ApplicationSpecific} + * create an Iso7816CertificateHolderAuthorization according to the {@link ASN1TaggedObject} * - * @param aSpe the DERApplicationSpecific containing the data + * @param aSpe the ASN1TaggedObject containing the data * @throws IOException */ - public CertificateHolderAuthorization(ASN1ApplicationSpecific aSpe) + public CertificateHolderAuthorization(ASN1TaggedObject aSpe) throws IOException { - if (aSpe.getApplicationTag() == EACTags.CERTIFICATE_HOLDER_AUTHORIZATION_TEMPLATE) + if (aSpe.hasTag(BERTags.APPLICATION, EACTags.CERTIFICATE_HOLDER_AUTHORIZATION_TEMPLATE)) + { + setPrivateData(ASN1Sequence.getInstance(aSpe.getBaseUniversal(false, BERTags.SEQUENCE))); + } + else { - setPrivateData(new ASN1InputStream(aSpe.getContents())); + throw new IllegalArgumentException("Unrecognized object in CerticateHolderAuthorization"); } } @@ -136,19 +136,17 @@ public CertificateHolderAuthorization(ASN1ApplicationSpecific aSpe) */ public int getAccessRights() { - return accessRights.getContents()[0] & 0xff; + return accessRights & 0xff; } /** - * create a DERApplicationSpecific and set the access rights to "rights" + * create an ASN1TaggedObject and set the access rights to "rights" * * @param rights byte containing the rights. */ private void setAccessRights(byte rights) { - byte[] accessRights = new byte[1]; - accessRights[0] = rights; - this.accessRights = new DERApplicationSpecific(EACTags.DISCRETIONARY_DATA, accessRights); + this.accessRights = rights; } /** @@ -170,15 +168,15 @@ private void setOid(ASN1ObjectIdentifier oid) } /** - * return the Certificate Holder Authorization as a DERApplicationSpecific Object + * return the Certificate Holder Authorization as an ASN1TaggedObject */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(2); v.add(oid); - v.add(accessRights); + v.add(EACTagged.create(EACTags.DISCRETIONARY_DATA, new byte[] { accessRights })); - return new DERApplicationSpecific(EACTags.CERTIFICATE_HOLDER_AUTHORIZATION_TEMPLATE, v); + return EACTagged.create(EACTags.CERTIFICATE_HOLDER_AUTHORIZATION_TEMPLATE, new DERSequence(v)); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/eac/EACTagged.java b/util/src/main/java/org/bouncycastle/asn1/eac/EACTagged.java new file mode 100644 index 0000000000..6189b6f9b0 --- /dev/null +++ b/util/src/main/java/org/bouncycastle/asn1/eac/EACTagged.java @@ -0,0 +1,25 @@ +package org.bouncycastle.asn1.eac; + +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERTaggedObject; + +class EACTagged +{ + static ASN1TaggedObject create(int eacTag, ASN1Sequence seq) + { + return new DERTaggedObject(false, BERTags.APPLICATION, eacTag, seq); + } + + static ASN1TaggedObject create(int eacTag, PublicKeyDataObject key) + { + return new DERTaggedObject(false, BERTags.APPLICATION, eacTag, key); + } + + static ASN1TaggedObject create(int eacTag, byte[] octets) + { + return new DERTaggedObject(false, BERTags.APPLICATION, eacTag, new DEROctetString(octets)); + } +} diff --git a/util/src/main/java/org/bouncycastle/asn1/eac/EACTags.java b/util/src/main/java/org/bouncycastle/asn1/eac/EACTags.java index 46439235c9..fa07b21b8c 100644 --- a/util/src/main/java/org/bouncycastle/asn1/eac/EACTags.java +++ b/util/src/main/java/org/bouncycastle/asn1/eac/EACTags.java @@ -1,10 +1,12 @@ package org.bouncycastle.asn1.eac; -import org.bouncycastle.asn1.ASN1ApplicationSpecific; -import org.bouncycastle.asn1.BERTags; - public class EACTags { + private EACTags() + { + + } + public static final int COUNTRY_CODE_NATIONAL_DATA = 0x01; public static final int ISSUER_IDENTIFICATION_NUMBER = 0x02; //0x42; public static final int CARD_SERVICE_DATA = 0x03; @@ -113,97 +115,4 @@ public class EACTags public static final int CERTIFICATE_BODY = 0x4E; // 0x7F4E; public static final int BIOMETRIC_INFORMATION_TEMPLATE = 0x00; // 0x60 public static final int BIOMETRIC_INFORMATION_GROUP_TEMPLATE = 0x01; // 0x61 - - public static int getTag(int encodedTag) - { - /* - int i; - for (i = 24; i>=0; i-=8) { - if (((0xFF<> i); - } - return 0; - */ - return decodeTag(encodedTag); - } - - public static int getTagNo(int tag) - { - int i; - for (i = 24; i >= 0; i -= 8) - { - if (((0xFF << i) & tag) != 0) - { - return ((~(0xFF << i)) & tag); - } - } - return 0; - } - - public static int encodeTag(ASN1ApplicationSpecific spec) - { - int retValue = BERTags.APPLICATION; - boolean constructed = spec.isConstructed(); - if (constructed) - { - retValue |= BERTags.CONSTRUCTED; - } - - int tag = spec.getApplicationTag(); - - if (tag > 31) - { - retValue |= 0x1F; - retValue <<= 8; - - int currentByte = tag & 0x7F; - retValue |= currentByte; - tag >>= 7; - - while (tag > 0) - { - retValue |= 0x80; - retValue <<= 8; - - currentByte = tag & 0x7F; - retValue |= currentByte; - tag >>= 7; - } - } - else - { - retValue |= tag; - } - - return retValue; - } - - public static int decodeTag(int tag) - { - int retValue = 0; - boolean multiBytes = false; - for (int i = 24; i >= 0; i -= 8) - { - int currentByte = tag >> i & 0xFF; - if (currentByte == 0) - { - continue; - } - - if (multiBytes) - { - retValue <<= 7; - retValue |= currentByte & 0x7F; - } - else if ((currentByte & 0x1F) == 0x1F) - { - multiBytes = true; - } - else - { - return currentByte & 0x1F; // higher order bit are for DER.Constructed and type - } - } - return retValue; - } } diff --git a/core/src/main/java/org/bouncycastle/asn1/edec/EdECObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/edec/EdECObjectIdentifiers.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/edec/EdECObjectIdentifiers.java rename to util/src/main/java/org/bouncycastle/asn1/edec/EdECObjectIdentifiers.java diff --git a/util/src/main/java/org/bouncycastle/asn1/esf/CrlOcspRef.java b/util/src/main/java/org/bouncycastle/asn1/esf/CrlOcspRef.java index 1739e1828b..b81dc6176a 100644 --- a/util/src/main/java/org/bouncycastle/asn1/esf/CrlOcspRef.java +++ b/util/src/main/java/org/bouncycastle/asn1/esf/CrlOcspRef.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; @@ -46,17 +47,17 @@ private CrlOcspRef(ASN1Sequence seq) Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { - ASN1TaggedObject o = (ASN1TaggedObject)e.nextElement(); + ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement(), BERTags.CONTEXT_SPECIFIC); switch (o.getTagNo()) { case 0: - this.crlids = CrlListID.getInstance(o.getObject()); + this.crlids = CrlListID.getInstance(o.getExplicitBaseObject()); break; case 1: - this.ocspids = OcspListID.getInstance(o.getObject()); + this.ocspids = OcspListID.getInstance(o.getExplicitBaseObject()); break; case 2: - this.otherRev = OtherRevRefs.getInstance(o.getObject()); + this.otherRev = OtherRevRefs.getInstance(o.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("illegal tag"); diff --git a/util/src/main/java/org/bouncycastle/asn1/esf/RevocationValues.java b/util/src/main/java/org/bouncycastle/asn1/esf/RevocationValues.java index 8ae6f55578..7196a38bf6 100644 --- a/util/src/main/java/org/bouncycastle/asn1/esf/RevocationValues.java +++ b/util/src/main/java/org/bouncycastle/asn1/esf/RevocationValues.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; @@ -52,11 +53,11 @@ private RevocationValues(ASN1Sequence seq) Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { - ASN1TaggedObject o = (ASN1TaggedObject)e.nextElement(); + ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement(), BERTags.CONTEXT_SPECIFIC); switch (o.getTagNo()) { case 0: - ASN1Sequence crlValsSeq = (ASN1Sequence)o.getObject(); + ASN1Sequence crlValsSeq = (ASN1Sequence)o.getExplicitBaseObject(); Enumeration crlValsEnum = crlValsSeq.getObjects(); while (crlValsEnum.hasMoreElements()) { @@ -65,7 +66,7 @@ private RevocationValues(ASN1Sequence seq) this.crlVals = crlValsSeq; break; case 1: - ASN1Sequence ocspValsSeq = (ASN1Sequence)o.getObject(); + ASN1Sequence ocspValsSeq = (ASN1Sequence)o.getExplicitBaseObject(); Enumeration ocspValsEnum = ocspValsSeq.getObjects(); while (ocspValsEnum.hasMoreElements()) { @@ -74,7 +75,7 @@ private RevocationValues(ASN1Sequence seq) this.ocspVals = ocspValsSeq; break; case 2: - this.otherRevVals = OtherRevVals.getInstance(o.getObject()); + this.otherRevVals = OtherRevVals.getInstance(o.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("invalid tag: " diff --git a/util/src/main/java/org/bouncycastle/asn1/esf/SPuri.java b/util/src/main/java/org/bouncycastle/asn1/esf/SPuri.java index 6c909319ef..1e59eb90db 100644 --- a/util/src/main/java/org/bouncycastle/asn1/esf/SPuri.java +++ b/util/src/main/java/org/bouncycastle/asn1/esf/SPuri.java @@ -2,7 +2,6 @@ import org.bouncycastle.asn1.ASN1IA5String; import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.DERIA5String; public class SPuri { @@ -29,16 +28,6 @@ public SPuri( this.uri = uri; } - /** - * @deprecated Use {@link #getUriIA5()} instead. - */ - public DERIA5String getUri() - { - return null == uri || uri instanceof DERIA5String - ? (DERIA5String)uri - : new DERIA5String(uri.getString(), false); - } - public ASN1IA5String getUriIA5() { return uri; diff --git a/util/src/main/java/org/bouncycastle/asn1/esf/SignerLocation.java b/util/src/main/java/org/bouncycastle/asn1/esf/SignerLocation.java index 84ef84490b..1a2132446f 100644 --- a/util/src/main/java/org/bouncycastle/asn1/esf/SignerLocation.java +++ b/util/src/main/java/org/bouncycastle/asn1/esf/SignerLocation.java @@ -8,6 +8,7 @@ import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.ASN1UTF8String; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTF8String; @@ -39,7 +40,7 @@ private SignerLocation( while (e.hasMoreElements()) { - ASN1TaggedObject o = (ASN1TaggedObject)e.nextElement(); + ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement(), BERTags.CONTEXT_SPECIFIC); switch (o.getTagNo()) { diff --git a/core/src/main/java/org/bouncycastle/asn1/gnu/GNUObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/gnu/GNUObjectIdentifiers.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/gnu/GNUObjectIdentifiers.java rename to util/src/main/java/org/bouncycastle/asn1/gnu/GNUObjectIdentifiers.java diff --git a/core/src/main/java/org/bouncycastle/asn1/iana/IANAObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/iana/IANAObjectIdentifiers.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/iana/IANAObjectIdentifiers.java rename to util/src/main/java/org/bouncycastle/asn1/iana/IANAObjectIdentifiers.java diff --git a/core/src/main/java/org/bouncycastle/asn1/isara/IsaraObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/isara/IsaraObjectIdentifiers.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/isara/IsaraObjectIdentifiers.java rename to util/src/main/java/org/bouncycastle/asn1/isara/IsaraObjectIdentifiers.java diff --git a/util/src/main/java/org/bouncycastle/asn1/isismtt/ocsp/RequestedCertificate.java b/util/src/main/java/org/bouncycastle/asn1/isismtt/ocsp/RequestedCertificate.java index b2e249c38f..9237e9833e 100644 --- a/util/src/main/java/org/bouncycastle/asn1/isismtt/ocsp/RequestedCertificate.java +++ b/util/src/main/java/org/bouncycastle/asn1/isismtt/ocsp/RequestedCertificate.java @@ -84,7 +84,7 @@ public static RequestedCertificate getInstance(ASN1TaggedObject obj, boolean exp throw new IllegalArgumentException("choice item must be explicitly tagged"); } - return getInstance(obj.getObject()); + return getInstance(obj.getExplicitBaseObject()); } private RequestedCertificate(ASN1TaggedObject tagged) diff --git a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/AdmissionSyntax.java b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/AdmissionSyntax.java index 2aed65f4a3..d5980f4cda 100644 --- a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/AdmissionSyntax.java +++ b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/AdmissionSyntax.java @@ -76,7 +76,7 @@ * in the fields professionItems and professionOIDs and by a registration number * in the field registrationNumber. An indication in text form must always be * present, whereas the other indications are optional. The component - * addProfessionInfo may contain additional applicationspecific information in + * addProfessionInfo may contain additional application-specific information in * DER-encoded form. * *

      diff --git a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/DeclarationOfMajority.java b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/DeclarationOfMajority.java index 6d27307f0e..7530244339 100644 --- a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/DeclarationOfMajority.java +++ b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/DeclarationOfMajority.java @@ -9,6 +9,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; @@ -83,7 +84,7 @@ public static DeclarationOfMajority getInstance(Object obj) if (obj instanceof ASN1TaggedObject) { - return new DeclarationOfMajority((ASN1TaggedObject)obj); + return new DeclarationOfMajority(ASN1TaggedObject.getInstance(obj, BERTags.CONTEXT_SPECIFIC)); } throw new IllegalArgumentException("illegal object in getInstance: " diff --git a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProcurationSyntax.java b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProcurationSyntax.java index c0790552e4..88d809e5aa 100644 --- a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProcurationSyntax.java +++ b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProcurationSyntax.java @@ -9,6 +9,7 @@ import org.bouncycastle.asn1.ASN1PrintableString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; @@ -104,7 +105,7 @@ private ProcurationSyntax(ASN1Sequence seq) while (e.hasMoreElements()) { - ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement()); + ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement(), BERTags.CONTEXT_SPECIFIC); switch (o.getTagNo()) { case 1: @@ -114,7 +115,7 @@ private ProcurationSyntax(ASN1Sequence seq) typeOfSubstitution = DirectoryString.getInstance(o, true); break; case 3: - ASN1Encodable signingFor = o.getObject(); + ASN1Encodable signingFor = o.getExplicitBaseObject(); if (signingFor instanceof ASN1TaggedObject) { thirdPerson = GeneralName.getInstance(signingFor); diff --git a/core/src/main/java/org/bouncycastle/asn1/iso/ISOIECObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/iso/ISOIECObjectIdentifiers.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/iso/ISOIECObjectIdentifiers.java rename to util/src/main/java/org/bouncycastle/asn1/iso/ISOIECObjectIdentifiers.java diff --git a/core/src/main/java/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java rename to util/src/main/java/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java diff --git a/core/src/main/java/org/bouncycastle/asn1/microsoft/MicrosoftObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/microsoft/MicrosoftObjectIdentifiers.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/microsoft/MicrosoftObjectIdentifiers.java rename to util/src/main/java/org/bouncycastle/asn1/microsoft/MicrosoftObjectIdentifiers.java diff --git a/core/src/main/java/org/bouncycastle/asn1/misc/CAST5CBCParameters.java b/util/src/main/java/org/bouncycastle/asn1/misc/CAST5CBCParameters.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/misc/CAST5CBCParameters.java rename to util/src/main/java/org/bouncycastle/asn1/misc/CAST5CBCParameters.java diff --git a/core/src/main/java/org/bouncycastle/asn1/misc/IDEACBCPar.java b/util/src/main/java/org/bouncycastle/asn1/misc/IDEACBCPar.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/misc/IDEACBCPar.java rename to util/src/main/java/org/bouncycastle/asn1/misc/IDEACBCPar.java diff --git a/core/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java similarity index 72% rename from core/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java rename to util/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java index 195978fe72..8608d2c0a7 100644 --- a/core/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java +++ b/util/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java @@ -163,4 +163,32 @@ public interface MiscObjectIdentifiers ASN1ObjectIdentifier id_composite_key = new ASN1ObjectIdentifier("2.16.840.1.114027.80.4.1"); ASN1ObjectIdentifier id_oracle_pkcs12_trusted_key_usage = new ASN1ObjectIdentifier("2.16.840.1.113894.746875.1.1"); + + + // COMPOSITE SIGNATURES START + // -- To be replaced by IANA + // Composite signature related OIDs. Based https://www.ietf.org/archive/id/draft-ounsworth-pq-composite-sigs-13.html + // The current OIDs are EXPERIMENTAL and are going to change. + ASN1ObjectIdentifier id_composite_signatures = new ASN1ObjectIdentifier("2.16.840.1.114027.80.8.1"); + ASN1ObjectIdentifier id_MLDSA44_RSA2048_PSS_SHA256 = id_composite_signatures.branch("1"); + ASN1ObjectIdentifier id_MLDSA44_RSA2048_PKCS15_SHA256 = id_composite_signatures.branch("2"); + ASN1ObjectIdentifier id_MLDSA44_Ed25519_SHA512 = id_composite_signatures.branch("3"); + ASN1ObjectIdentifier id_MLDSA44_ECDSA_P256_SHA256 = id_composite_signatures.branch("4"); + ASN1ObjectIdentifier id_MLDSA44_ECDSA_brainpoolP256r1_SHA256 = id_composite_signatures.branch("5"); + ASN1ObjectIdentifier id_MLDSA65_RSA3072_PSS_SHA512 = id_composite_signatures.branch("6"); + ASN1ObjectIdentifier id_MLDSA65_RSA3072_PKCS15_SHA512 = id_composite_signatures.branch("7"); + ASN1ObjectIdentifier id_MLDSA65_ECDSA_P256_SHA512 = id_composite_signatures.branch("8"); + ASN1ObjectIdentifier id_MLDSA65_ECDSA_brainpoolP256r1_SHA512 = id_composite_signatures.branch("9"); + ASN1ObjectIdentifier id_MLDSA65_Ed25519_SHA512 = id_composite_signatures.branch("10"); + ASN1ObjectIdentifier id_MLDSA87_ECDSA_P384_SHA512 = id_composite_signatures.branch("11"); + ASN1ObjectIdentifier id_MLDSA87_ECDSA_brainpoolP384r1_SHA512 = id_composite_signatures.branch("12"); + ASN1ObjectIdentifier id_MLDSA87_Ed448_SHA512 = id_composite_signatures.branch("13"); + + // Falcon-based composites below were removed from the IETF draft in version 13 and are expected to be included in a later/separate standard. + // Most likely due to the fact that the Falcon (FN-DSA) NIST standard is going to be released after the Dilithium (ML-DSA) standard. + // However, we still leave their implementation for experimental usage. + ASN1ObjectIdentifier id_Falcon512_ECDSA_P256_SHA256 = id_composite_signatures.branch("14"); + ASN1ObjectIdentifier id_Falcon512_ECDSA_brainpoolP256r1_SHA256 = id_composite_signatures.branch("15"); + ASN1ObjectIdentifier id_Falcon512_Ed25519_SHA512 = id_composite_signatures.branch("16"); + // COMPOSITE SIGNATURES END } diff --git a/core/src/main/java/org/bouncycastle/asn1/misc/NetscapeCertType.java b/util/src/main/java/org/bouncycastle/asn1/misc/NetscapeCertType.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/misc/NetscapeCertType.java rename to util/src/main/java/org/bouncycastle/asn1/misc/NetscapeCertType.java diff --git a/core/src/main/java/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java b/util/src/main/java/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java rename to util/src/main/java/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java diff --git a/core/src/main/java/org/bouncycastle/asn1/misc/ScryptParams.java b/util/src/main/java/org/bouncycastle/asn1/misc/ScryptParams.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/misc/ScryptParams.java rename to util/src/main/java/org/bouncycastle/asn1/misc/ScryptParams.java diff --git a/core/src/main/java/org/bouncycastle/asn1/misc/VerisignCzagExtension.java b/util/src/main/java/org/bouncycastle/asn1/misc/VerisignCzagExtension.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/misc/VerisignCzagExtension.java rename to util/src/main/java/org/bouncycastle/asn1/misc/VerisignCzagExtension.java diff --git a/core/src/main/java/org/bouncycastle/asn1/mozilla/PublicKeyAndChallenge.java b/util/src/main/java/org/bouncycastle/asn1/mozilla/PublicKeyAndChallenge.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/mozilla/PublicKeyAndChallenge.java rename to util/src/main/java/org/bouncycastle/asn1/mozilla/PublicKeyAndChallenge.java diff --git a/core/src/main/java/org/bouncycastle/asn1/mozilla/SignedPublicKeyAndChallenge.java b/util/src/main/java/org/bouncycastle/asn1/mozilla/SignedPublicKeyAndChallenge.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/mozilla/SignedPublicKeyAndChallenge.java rename to util/src/main/java/org/bouncycastle/asn1/mozilla/SignedPublicKeyAndChallenge.java diff --git a/core/src/main/java/org/bouncycastle/asn1/nsri/NSRIObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/nsri/NSRIObjectIdentifiers.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/nsri/NSRIObjectIdentifiers.java rename to util/src/main/java/org/bouncycastle/asn1/nsri/NSRIObjectIdentifiers.java diff --git a/core/src/main/java/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java rename to util/src/main/java/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java diff --git a/core/src/main/java/org/bouncycastle/asn1/oiw/ElGamalParameter.java b/util/src/main/java/org/bouncycastle/asn1/oiw/ElGamalParameter.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/oiw/ElGamalParameter.java rename to util/src/main/java/org/bouncycastle/asn1/oiw/ElGamalParameter.java diff --git a/core/src/main/java/org/bouncycastle/asn1/oiw/OIWObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/oiw/OIWObjectIdentifiers.java similarity index 100% rename from core/src/main/java/org/bouncycastle/asn1/oiw/OIWObjectIdentifiers.java rename to util/src/main/java/org/bouncycastle/asn1/oiw/OIWObjectIdentifiers.java diff --git a/core/src/main/java/org/bouncycastle/asn1/rosstandart/RosstandartObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/rosstandart/RosstandartObjectIdentifiers.java similarity index 85% rename from core/src/main/java/org/bouncycastle/asn1/rosstandart/RosstandartObjectIdentifiers.java rename to util/src/main/java/org/bouncycastle/asn1/rosstandart/RosstandartObjectIdentifiers.java index 888b40dbd2..a011873c6d 100644 --- a/core/src/main/java/org/bouncycastle/asn1/rosstandart/RosstandartObjectIdentifiers.java +++ b/util/src/main/java/org/bouncycastle/asn1/rosstandart/RosstandartObjectIdentifiers.java @@ -34,6 +34,12 @@ public interface RosstandartObjectIdentifiers static final ASN1ObjectIdentifier id_tc26_gost_3410_12_256_paramSetA = id_tc26_gost_3410_12_256_paramSet.branch("1"); + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_256_paramSetB = id_tc26_gost_3410_12_256_paramSet.branch("2"); + + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_256_paramSetC = id_tc26_gost_3410_12_256_paramSet.branch("3"); + + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_256_paramSetD = id_tc26_gost_3410_12_256_paramSet.branch("4"); + static final ASN1ObjectIdentifier id_tc26_gost_3410_12_512_paramSet = id_tc26.branch("2.1.2"); static final ASN1ObjectIdentifier id_tc26_gost_3410_12_512_paramSetA = id_tc26_gost_3410_12_512_paramSet.branch("1"); diff --git a/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStamp.java b/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStamp.java index 13da62fd73..90e404e266 100644 --- a/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStamp.java +++ b/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStamp.java @@ -17,7 +17,7 @@ /** * Implementation of the Archive Timestamp type defined in RFC4998. - * {@see RFC 4998} + * @see RFC 4998 *

      * ASN.1 Archive Timestamp *

      diff --git a/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStampChain.java b/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStampChain.java index 39f26cf2ae..b966631074 100644 --- a/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStampChain.java +++ b/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStampChain.java @@ -19,7 +19,7 @@ public class ArchiveTimeStampChain extends ASN1Object { - private ASN1Sequence archiveTimestamps; + private ASN1Sequence archiveTimeStamps; /** * Return an ArchiveTimeStampChain from the given object. @@ -44,12 +44,12 @@ else if (obj != null) public ArchiveTimeStampChain(ArchiveTimeStamp archiveTimeStamp) { - archiveTimestamps = new DERSequence(archiveTimeStamp); + this.archiveTimeStamps = new DERSequence(archiveTimeStamp); } public ArchiveTimeStampChain(ArchiveTimeStamp[] archiveTimeStamps) { - archiveTimestamps = new DERSequence(archiveTimeStamps); + this.archiveTimeStamps = new DERSequence(archiveTimeStamps); } private ArchiveTimeStampChain(final ASN1Sequence sequence) @@ -62,16 +62,16 @@ private ArchiveTimeStampChain(final ASN1Sequence sequence) vector.add(ArchiveTimeStamp.getInstance(objects.nextElement())); } - archiveTimestamps = new DERSequence(vector); + this.archiveTimeStamps = new DERSequence(vector); } public ArchiveTimeStamp[] getArchiveTimestamps() { - ArchiveTimeStamp[] rv = new ArchiveTimeStamp[archiveTimestamps.size()]; + ArchiveTimeStamp[] rv = new ArchiveTimeStamp[archiveTimeStamps.size()]; for (int i = 0; i != rv.length; i++) { - rv[i] = ArchiveTimeStamp.getInstance(archiveTimestamps.getObjectAt(i)); + rv[i] = ArchiveTimeStamp.getInstance(archiveTimeStamps.getObjectAt(i)); } return rv; @@ -85,11 +85,11 @@ public ArchiveTimeStamp[] getArchiveTimestamps() */ public ArchiveTimeStampChain append(final ArchiveTimeStamp archiveTimeStamp) { - ASN1EncodableVector v = new ASN1EncodableVector(archiveTimestamps.size() + 1); + ASN1EncodableVector v = new ASN1EncodableVector(archiveTimeStamps.size() + 1); - for (int i = 0; i != archiveTimestamps.size(); i++) + for (int i = 0; i != archiveTimeStamps.size(); i++) { - v.add(archiveTimestamps.getObjectAt(i)); + v.add(archiveTimeStamps.getObjectAt(i)); } v.add(archiveTimeStamp); @@ -99,6 +99,6 @@ public ArchiveTimeStampChain append(final ArchiveTimeStamp archiveTimeStamp) public ASN1Primitive toASN1Primitive() { - return archiveTimestamps; + return archiveTimeStamps; } } diff --git a/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStampSequence.java b/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStampSequence.java index f1c34ad186..727d6df58b 100644 --- a/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStampSequence.java +++ b/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStampSequence.java @@ -30,7 +30,7 @@ public class ArchiveTimeStampSequence */ public static ArchiveTimeStampSequence getInstance(final Object obj) { - if (obj instanceof ArchiveTimeStampChain) + if (obj instanceof ArchiveTimeStampSequence) { return (ArchiveTimeStampSequence)obj; } @@ -43,7 +43,6 @@ else if (obj != null) } private ArchiveTimeStampSequence(final ASN1Sequence sequence) - throws IllegalArgumentException { final ASN1EncodableVector vector = new ASN1EncodableVector(sequence.size()); diff --git a/util/src/main/java/org/bouncycastle/asn1/tsp/EncryptionInfo.java b/util/src/main/java/org/bouncycastle/asn1/tsp/EncryptionInfo.java index c89134e340..0157084acf 100644 --- a/util/src/main/java/org/bouncycastle/asn1/tsp/EncryptionInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/tsp/EncryptionInfo.java @@ -25,7 +25,7 @@ * encryptionInfoType ENCINFO-TYPE.&id * ({SupportedEncryptionAlgorithms}), * encryptionInfoValue ENCINFO-TYPE.&Type - * ({SupportedEncryptionAlgorithms}{@encryptionInfoType}) + * ({SupportedEncryptionAlgorithms}{@encryptionInfoType}) * } *

      * ENCINFO-TYPE ::= TYPE-IDENTIFIER @@ -46,7 +46,15 @@ public class EncryptionInfo */ private ASN1Encodable encryptionInfoValue; + /** + * @deprecated Use {@link EncryptionInfo#getInstance(Object)} instead. + */ public static EncryptionInfo getInstance(final ASN1Object obj) + { + return getInstance((Object)obj); + } + + public static EncryptionInfo getInstance(final Object obj) { if (obj instanceof EncryptionInfo) { @@ -64,7 +72,7 @@ public static EncryptionInfo getInstance( ASN1TaggedObject obj, boolean explicit) { - return getInstance(ASN1Sequence.getInstance(obj, explicit)); + return getInstance((Object)ASN1Sequence.getInstance(obj, explicit)); } private EncryptionInfo(ASN1Sequence sequence) @@ -85,6 +93,16 @@ public EncryptionInfo(ASN1ObjectIdentifier encryptionInfoType, this.encryptionInfoValue = encryptionInfoValue; } + public ASN1ObjectIdentifier getEncryptionInfoType() + { + return encryptionInfoType; + } + + public ASN1Encodable getEncryptionInfoValue() + { + return encryptionInfoValue; + } + public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(2); diff --git a/util/src/main/java/org/bouncycastle/asn1/tsp/PartialHashtree.java b/util/src/main/java/org/bouncycastle/asn1/tsp/PartialHashtree.java index 26c80562f1..6357326467 100644 --- a/util/src/main/java/org/bouncycastle/asn1/tsp/PartialHashtree.java +++ b/util/src/main/java/org/bouncycastle/asn1/tsp/PartialHashtree.java @@ -51,7 +51,7 @@ private PartialHashtree(final ASN1Sequence values) { for (int i = 0; i != values.size(); i++) { - if (!(values.getObjectAt(i) instanceof DEROctetString)) + if (!(values.getObjectAt(i) instanceof ASN1OctetString)) { throw new IllegalArgumentException("unknown object in constructor: " + values .getObjectAt(i).getClass().getName()); diff --git a/util/src/main/java/org/bouncycastle/oer/OEROutputStream.java b/util/src/main/java/org/bouncycastle/oer/OEROutputStream.java index bf3cf3790f..fdfdb4ebc3 100644 --- a/util/src/main/java/org/bouncycastle/oer/OEROutputStream.java +++ b/util/src/main/java/org/bouncycastle/oer/OEROutputStream.java @@ -9,6 +9,7 @@ import java.util.Iterator; import java.util.List; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Enumerated; @@ -21,7 +22,6 @@ import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.ASN1UTF8String; import org.bouncycastle.asn1.BERTags; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Pack; import org.bouncycastle.util.Strings; @@ -373,13 +373,17 @@ else if (encodable instanceof ASN1Sequence) if (item instanceof ASN1TaggedObject) { ASN1TaggedObject taggedObject = (ASN1TaggedObject)item; - if (BERTags.APPLICATION == taggedObject.getTagClass()) + switch (taggedObject.getTagClass()) { + case BERTags.APPLICATION: debugPrint(oerElement.appendLabel("AS")); - } - else - { + break; + case BERTags.CONTEXT_SPECIFIC: debugPrint(oerElement.appendLabel("CS")); + break; + case BERTags.PRIVATE: + debugPrint(oerElement.appendLabel("PR")); + break; } } } @@ -581,8 +585,7 @@ else if (intBytesForRange < 0) } case BIT_STRING: { - - DERBitString bitString = DERBitString.getInstance(encodable); + ASN1BitString bitString = ASN1BitString.getInstance(encodable); byte[] bytes = bitString.getBytes(); if (oerElement.isFixedLength()) { diff --git a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlCommand.java b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlCommand.java index f7779c36db..b5659bbed2 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlCommand.java +++ b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlCommand.java @@ -5,6 +5,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -37,10 +38,10 @@ private CtlCommand(ASN1TaggedObject ato) switch (choice) { case add: - ctlCommand = CtlEntry.getInstance(ato.getObject()); + ctlCommand = CtlEntry.getInstance(ato.getExplicitBaseObject()); return; case delete: - ctlCommand = CtlDelete.getInstance(ato.getObject()); + ctlCommand = CtlDelete.getInstance(ato.getExplicitBaseObject()); return; } @@ -56,7 +57,7 @@ public static CtlCommand getInstance(Object o) if (o != null) { - return new CtlCommand(ASN1TaggedObject.getInstance(o)); + return new CtlCommand(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlDelete.java b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlDelete.java index dd512bc84c..11c987ac2a 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlDelete.java +++ b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlDelete.java @@ -5,6 +5,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.HashedId8; @@ -54,7 +55,7 @@ public CtlDelete(int choice, ASN1Encodable value) private CtlDelete(ASN1TaggedObject value) { - this(value.getTagNo(), value.getObject()); + this(value.getTagNo(), value.getExplicitBaseObject()); } public static CtlDelete getInstance(Object o) @@ -66,7 +67,7 @@ public static CtlDelete getInstance(Object o) if (o != null) { - return new CtlDelete(ASN1TaggedObject.getInstance(o)); + return new CtlDelete(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; } diff --git a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlEntry.java b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlEntry.java index 3b0e18e1e3..cf8b2aaed5 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlEntry.java +++ b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlEntry.java @@ -5,6 +5,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -43,19 +44,19 @@ private CtlEntry(ASN1TaggedObject ato) switch (choice) { case rca: - ctlEntry = RootCaEntry.getInstance(ato.getObject()); + ctlEntry = RootCaEntry.getInstance(ato.getExplicitBaseObject()); return; case ea: - ctlEntry = EaEntry.getInstance(ato.getObject()); + ctlEntry = EaEntry.getInstance(ato.getExplicitBaseObject()); return; case aa: - ctlEntry = AaEntry.getInstance(ato.getObject()); + ctlEntry = AaEntry.getInstance(ato.getExplicitBaseObject()); return; case dc: - ctlEntry = DcEntry.getInstance(ato.getObject()); + ctlEntry = DcEntry.getInstance(ato.getExplicitBaseObject()); return; case tlm: - ctlEntry = TlmEntry.getInstance(ato.getObject()); + ctlEntry = TlmEntry.getInstance(ato.getExplicitBaseObject()); return; } @@ -73,7 +74,7 @@ public static CtlEntry getInstance(Object o) if (o != null) { - return new CtlEntry(ASN1TaggedObject.getInstance(o)); + return new CtlEntry(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; } diff --git a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/EtsiTs102941DataContent.java b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/EtsiTs102941DataContent.java index 717d710ca1..441f467e9d 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/EtsiTs102941DataContent.java +++ b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/EtsiTs102941DataContent.java @@ -5,6 +5,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -64,31 +65,31 @@ private EtsiTs102941DataContent(ASN1TaggedObject asn1TaggedObject) switch (choice) { case enrolmentRequest: - etsiTs102941DataContent = InnerEcRequestSignedForPop.getInstance(asn1TaggedObject.getObject()); + etsiTs102941DataContent = InnerEcRequestSignedForPop.getInstance(asn1TaggedObject.getExplicitBaseObject()); return; case enrolmentResponse: - etsiTs102941DataContent = InnerEcResponse.getInstance(asn1TaggedObject.getObject()); + etsiTs102941DataContent = InnerEcResponse.getInstance(asn1TaggedObject.getExplicitBaseObject()); return; case authorizationRequest: - etsiTs102941DataContent = InnerAtRequest.getInstance(asn1TaggedObject.getObject()); + etsiTs102941DataContent = InnerAtRequest.getInstance(asn1TaggedObject.getExplicitBaseObject()); return; case authorizationResponse: - etsiTs102941DataContent = InnerAtResponse.getInstance(asn1TaggedObject.getObject()); + etsiTs102941DataContent = InnerAtResponse.getInstance(asn1TaggedObject.getExplicitBaseObject()); return; case certificateTrustListTlm: - etsiTs102941DataContent = ToBeSignedTlmCtl.getInstance(asn1TaggedObject.getObject()); + etsiTs102941DataContent = ToBeSignedTlmCtl.getInstance(asn1TaggedObject.getExplicitBaseObject()); return; case certificateTrustListRca: - etsiTs102941DataContent = ToBeSignedRcaCtl.getInstance(asn1TaggedObject.getObject()); + etsiTs102941DataContent = ToBeSignedRcaCtl.getInstance(asn1TaggedObject.getExplicitBaseObject()); return; case authorizationValidationRequest: - etsiTs102941DataContent = AuthorizationValidationRequest.getInstance(asn1TaggedObject.getObject()); + etsiTs102941DataContent = AuthorizationValidationRequest.getInstance(asn1TaggedObject.getExplicitBaseObject()); return; case authorizationValidationResponse: - etsiTs102941DataContent = AuthorizationValidationResponse.getInstance(asn1TaggedObject.getObject()); + etsiTs102941DataContent = AuthorizationValidationResponse.getInstance(asn1TaggedObject.getExplicitBaseObject()); return; case caCertificateRequest: - etsiTs102941DataContent = CaCertificateRequest.getInstance(asn1TaggedObject.getObject()); + etsiTs102941DataContent = CaCertificateRequest.getInstance(asn1TaggedObject.getExplicitBaseObject()); return; // // This is incomplete @@ -119,7 +120,7 @@ public static EtsiTs102941DataContent getInstance(Object o) if (o != null) { - return new EtsiTs102941DataContent(DERTaggedObject.getInstance(o)); + return new EtsiTs102941DataContent(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/basetypes/EcSignature.java b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/basetypes/EcSignature.java index c7ec90c51e..e875b26a49 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/basetypes/EcSignature.java +++ b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/basetypes/EcSignature.java @@ -5,6 +5,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.etsi103097.EtsiTs103097DataEncrypted; import org.bouncycastle.oer.its.etsi103097.EtsiTs103097DataSignedExternalPayload; @@ -40,10 +41,10 @@ private EcSignature(ASN1TaggedObject ato) switch (choice) { case encryptedEcSignature: - _ecSignature = EtsiTs103097DataEncrypted.getInstance(ato.getObject()); + _ecSignature = EtsiTs103097DataEncrypted.getInstance(ato.getExplicitBaseObject()); return; case ecSignature: - _ecSignature = EtsiTs103097DataSignedExternalPayload.getInstance(ato.getObject()); + _ecSignature = EtsiTs103097DataSignedExternalPayload.getInstance(ato.getExplicitBaseObject()); return; } @@ -58,7 +59,7 @@ public static EcSignature getInstance(Object o) } if (o != null) { - return new EcSignature(ASN1TaggedObject.getInstance(o)); + return new EcSignature(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/CertificateId.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/CertificateId.java index 4ad83c56d0..c914942850 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/CertificateId.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/CertificateId.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; @@ -46,16 +47,16 @@ private CertificateId(ASN1TaggedObject asn1TaggedObject) switch (choice) { case linkageData: - certificateId = LinkageData.getInstance(asn1TaggedObject.getObject()); + certificateId = LinkageData.getInstance(asn1TaggedObject.getExplicitBaseObject()); break; case name: - certificateId = Hostname.getInstance(asn1TaggedObject.getObject()); + certificateId = Hostname.getInstance(asn1TaggedObject.getExplicitBaseObject()); break; case binaryId: - certificateId = DEROctetString.getInstance(asn1TaggedObject.getObject()); + certificateId = DEROctetString.getInstance(asn1TaggedObject.getExplicitBaseObject()); break; case none: - certificateId = ASN1Null.getInstance(asn1TaggedObject.getObject()); + certificateId = ASN1Null.getInstance(asn1TaggedObject.getExplicitBaseObject()); break; default: @@ -97,7 +98,7 @@ public static CertificateId getInstance(Object o) if (o != null) { - return new CertificateId(ASN1TaggedObject.getInstance(o)); + return new CertificateId(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/EncryptedDataEncryptionKey.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/EncryptedDataEncryptionKey.java index 1e1a3bb973..3242efed94 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/EncryptedDataEncryptionKey.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/EncryptedDataEncryptionKey.java @@ -3,9 +3,9 @@ import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; -import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.EciesP256EncryptedKey; @@ -40,7 +40,7 @@ private EncryptedDataEncryptionKey(ASN1TaggedObject ato) { case eciesNistP256: case eciesBrainpoolP256r1: - encryptedDataEncryptionKey = EciesP256EncryptedKey.getInstance(ato.getObject()); + encryptedDataEncryptionKey = EciesP256EncryptedKey.getInstance(ato.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("invalid choice value " + ato.getTagNo()); @@ -56,7 +56,7 @@ public static EncryptedDataEncryptionKey getInstance(Object o) if (o != null) { - return new EncryptedDataEncryptionKey(ASN1TaggedObject.getInstance(o)); + return new EncryptedDataEncryptionKey(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/EndEntityType.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/EndEntityType.java index 2bdc438bbd..359c67acf2 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/EndEntityType.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/EndEntityType.java @@ -23,7 +23,7 @@ public EndEntityType(int eeType) this(new DERBitString(eeType)); } - private EndEntityType(DERBitString str) + private EndEntityType(ASN1BitString str) { this.type = str; } @@ -36,7 +36,7 @@ public static EndEntityType getInstance(Object src) } else if (src != null) { - return new EndEntityType(DERBitString.getInstance(src)); + return new EndEntityType(ASN1BitString.getInstance(src)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/HashedData.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/HashedData.java index ae9454fb12..4c108e1b24 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/HashedData.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/HashedData.java @@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.util.Arrays; @@ -46,7 +47,7 @@ private HashedData(ASN1TaggedObject dto) case sha384HashedData: case reserved: this.choice = dto.getTagNo(); - this.hashedData = DEROctetString.getInstance(dto.getObject()); + this.hashedData = DEROctetString.getInstance(dto.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("invalid choice value " + dto.getTagNo()); @@ -92,7 +93,7 @@ public static HashedData getInstance(Object o) if (o != null) { - return new HashedData(ASN1TaggedObject.getInstance(o)); + return new HashedData(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/Ieee1609Dot2Content.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/Ieee1609Dot2Content.java index 838695c0f7..3e21cecc41 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/Ieee1609Dot2Content.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/Ieee1609Dot2Content.java @@ -5,6 +5,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.util.Arrays; @@ -79,13 +80,13 @@ private Ieee1609Dot2Content(ASN1TaggedObject to) { case unsecuredData: case signedCertificateRequest: - ieee1609Dot2Content = Opaque.getInstance(to.getObject()); + ieee1609Dot2Content = Opaque.getInstance(to.getExplicitBaseObject()); return; case signedData: - ieee1609Dot2Content = SignedData.getInstance(to.getObject()); + ieee1609Dot2Content = SignedData.getInstance(to.getExplicitBaseObject()); return; case encryptedData: - ieee1609Dot2Content = EncryptedData.getInstance(to.getObject()); + ieee1609Dot2Content = EncryptedData.getInstance(to.getExplicitBaseObject()); return; default: throw new IllegalArgumentException("invalid choice value " + to.getTagNo()); @@ -102,7 +103,7 @@ public static Ieee1609Dot2Content getInstance(Object src) if (src != null) { - return new Ieee1609Dot2Content(ASN1TaggedObject.getInstance(src)); + return new Ieee1609Dot2Content(ASN1TaggedObject.getInstance(src, BERTags.CONTEXT_SPECIFIC)); } return null; } diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/IssuerIdentifier.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/IssuerIdentifier.java index 5810a9aefe..e30df5f265 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/IssuerIdentifier.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/IssuerIdentifier.java @@ -3,10 +3,9 @@ import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; -import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.HashAlgorithm; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.HashedId8; @@ -59,7 +58,7 @@ public IssuerIdentifier(int choice, ASN1Encodable value) private IssuerIdentifier(ASN1TaggedObject ato) { choice = ato.getTagNo(); - Object o = ato.getObject(); + Object o = ato.getExplicitBaseObject(); switch (choice) { case sha384AndDigest: // sha384AndDigest HashedId8 @@ -84,7 +83,7 @@ public static IssuerIdentifier getInstance(Object choice) if (choice != null) { - return new IssuerIdentifier(ASN1TaggedObject.getInstance(choice)); + return new IssuerIdentifier(ASN1TaggedObject.getInstance(choice, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/RecipientInfo.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/RecipientInfo.java index 5e61797dfd..eb11b5969b 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/RecipientInfo.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/RecipientInfo.java @@ -5,6 +5,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -45,15 +46,15 @@ private RecipientInfo(ASN1TaggedObject instance) switch (choice) { case pskRecipInfo: - recipientInfo = PreSharedKeyRecipientInfo.getInstance(instance.getObject()); + recipientInfo = PreSharedKeyRecipientInfo.getInstance(instance.getExplicitBaseObject()); break; case symmRecipInfo: - recipientInfo = SymmRecipientInfo.getInstance(instance.getObject()); + recipientInfo = SymmRecipientInfo.getInstance(instance.getExplicitBaseObject()); break; case certRecipInfo: case signedDataRecipInfo: case rekRecipInfo: - recipientInfo = PKRecipientInfo.getInstance(instance.getObject()); + recipientInfo = PKRecipientInfo.getInstance(instance.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("invalid choice value " + choice); @@ -69,7 +70,7 @@ public static RecipientInfo getInstance(Object object) if (object != null) { - return new RecipientInfo(ASN1TaggedObject.getInstance(object)); + return new RecipientInfo(ASN1TaggedObject.getInstance(object, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SignerIdentifier.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SignerIdentifier.java index 5412bf68bd..8ae0765b34 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SignerIdentifier.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SignerIdentifier.java @@ -3,11 +3,10 @@ import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; -import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.HashedId8; @@ -97,13 +96,13 @@ private SignerIdentifier(ASN1TaggedObject ato) switch (choice) { case digest: - signerIdentifier = HashedId8.getInstance(ato.getObject()); + signerIdentifier = HashedId8.getInstance(ato.getExplicitBaseObject()); break; case certificate: - signerIdentifier = SequenceOfCertificate.getInstance(ato.getObject()); + signerIdentifier = SequenceOfCertificate.getInstance(ato.getExplicitBaseObject()); break; case self: - signerIdentifier = DERNull.getInstance(ato.getObject()); + signerIdentifier = DERNull.getInstance(ato.getExplicitBaseObject()); break; default: @@ -122,7 +121,7 @@ public static SignerIdentifier getInstance(Object src) if (src != null) { - return new SignerIdentifier(ASN1TaggedObject.getInstance(src)); + return new SignerIdentifier(ASN1TaggedObject.getInstance(src, BERTags.CONTEXT_SPECIFIC)); } return null; @@ -164,4 +163,4 @@ public ASN1Encodable getSignerIdentifier() -} \ No newline at end of file +} diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SubjectPermissions.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SubjectPermissions.java index 10cf5d4562..4752294792 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SubjectPermissions.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SubjectPermissions.java @@ -4,11 +4,10 @@ import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1Object; -import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.SequenceOfPsidSspRange; @@ -58,10 +57,10 @@ private SubjectPermissions(ASN1TaggedObject ato) switch (choice) { case explicit: - subjectPermissions = SequenceOfPsidSspRange.getInstance(ato.getObject()); + subjectPermissions = SequenceOfPsidSspRange.getInstance(ato.getExplicitBaseObject()); break; case all: - subjectPermissions = ASN1Null.getInstance(ato.getObject()); + subjectPermissions = ASN1Null.getInstance(ato.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("invalid choice value " + choice); @@ -78,7 +77,7 @@ public static SubjectPermissions getInstance(Object src) if (src != null) { - return new SubjectPermissions(ASN1TaggedObject.getInstance(src)); + return new SubjectPermissions(ASN1TaggedObject.getInstance(src, BERTags.CONTEXT_SPECIFIC)); } return null; } diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SymmetricCiphertext.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SymmetricCiphertext.java index da7071114c..e568675684 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SymmetricCiphertext.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SymmetricCiphertext.java @@ -3,10 +3,9 @@ import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; -import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -37,7 +36,7 @@ private SymmetricCiphertext(ASN1TaggedObject ato) switch (choice) { case aes128ccm: - symmetricCiphertext = AesCcmCiphertext.getInstance(ato.getObject()); + symmetricCiphertext = AesCcmCiphertext.getInstance(ato.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("invalid choice value " + choice); @@ -60,7 +59,7 @@ public static SymmetricCiphertext getInstance(Object o) if (o != null) { - return new SymmetricCiphertext(ASN1TaggedObject.getInstance(o)); + return new SymmetricCiphertext(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/VerificationKeyIndicator.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/VerificationKeyIndicator.java index 7dd32cdc99..1550334920 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/VerificationKeyIndicator.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/VerificationKeyIndicator.java @@ -3,10 +3,9 @@ import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; -import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.EccP256CurvePoint; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.PublicVerificationKey; @@ -43,10 +42,10 @@ private VerificationKeyIndicator(ASN1TaggedObject ato) switch (choice) { case verificationKey: - verificationKeyIndicator = PublicVerificationKey.getInstance(ato.getObject()); + verificationKeyIndicator = PublicVerificationKey.getInstance(ato.getExplicitBaseObject()); break; case reconstructionValue: - verificationKeyIndicator = EccP256CurvePoint.getInstance(ato.getObject()); + verificationKeyIndicator = EccP256CurvePoint.getInstance(ato.getExplicitBaseObject()); break; default: @@ -75,7 +74,7 @@ public static VerificationKeyIndicator getInstance(Object src) if (src != null) { - return new VerificationKeyIndicator(ASN1TaggedObject.getInstance(src)); + return new VerificationKeyIndicator(ASN1TaggedObject.getInstance(src, BERTags.CONTEXT_SPECIFIC)); } return null; @@ -98,4 +97,4 @@ public ASN1Primitive toASN1Primitive() return new DERTaggedObject(choice, verificationKeyIndicator); } -} \ No newline at end of file +} diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/BasePublicEncryptionKey.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/BasePublicEncryptionKey.java index f01f575265..75e0921b94 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/BasePublicEncryptionKey.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/BasePublicEncryptionKey.java @@ -5,7 +5,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -32,7 +32,7 @@ private BasePublicEncryptionKey(ASN1TaggedObject dto) { case eciesNistP256: case eciesBrainpoolP256r1: - basePublicEncryptionKey = EccP256CurvePoint.getInstance(dto.getObject()); + basePublicEncryptionKey = EccP256CurvePoint.getInstance(dto.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("invalid choice value " + dto.getTagNo()); @@ -54,7 +54,7 @@ public static BasePublicEncryptionKey getInstance(Object objectAt) if (objectAt != null) { - return new BasePublicEncryptionKey(ASN1TaggedObject.getInstance(objectAt)); + return new BasePublicEncryptionKey(ASN1TaggedObject.getInstance(objectAt, BERTags.CONTEXT_SPECIFIC)); } return null; } diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Duration.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Duration.java index 8644d30da8..f619199e6c 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Duration.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Duration.java @@ -4,6 +4,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -54,7 +55,7 @@ private Duration(ASN1TaggedObject taggedObject) case years: try { - duration = UINT16.getInstance(taggedObject.getObject()); + duration = UINT16.getInstance(taggedObject.getExplicitBaseObject()); } catch (Exception ioex) { @@ -75,7 +76,7 @@ public static Duration getInstance(Object o) if (o != null) { - return new Duration(ASN1TaggedObject.getInstance(o)); + return new Duration(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP256CurvePoint.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP256CurvePoint.java index 580aacb741..fa6e4205e4 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP256CurvePoint.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP256CurvePoint.java @@ -8,6 +8,7 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; @@ -54,15 +55,15 @@ private EccP256CurvePoint(ASN1TaggedObject ato) switch (ato.getTagNo()) { case fill: - eccp256CurvePoint = ASN1Null.getInstance(ato.getObject()); + eccp256CurvePoint = ASN1Null.getInstance(ato.getExplicitBaseObject()); break; case xonly: case compressedY0: case compressedY1: - eccp256CurvePoint = ASN1OctetString.getInstance(ato.getObject()); + eccp256CurvePoint = ASN1OctetString.getInstance(ato.getExplicitBaseObject()); break; case uncompressedP256: - eccp256CurvePoint = Point256.getInstance(ato.getObject()); + eccp256CurvePoint = Point256.getInstance(ato.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("invalid choice value " + ato.getTagNo()); @@ -164,7 +165,7 @@ else if (encoded[0] == 0x03) choice = compressedY1; } byte[] copy = new byte[encoded.length - 1]; - System.arraycopy(encoded, 0, copy, 0, copy.length); + System.arraycopy(encoded, 1, copy, 0, copy.length); return new EccP256CurvePoint(choice, new DEROctetString(copy)); } @@ -177,7 +178,7 @@ public static EccP256CurvePoint getInstance(Object object) if (object != null) { - return new EccP256CurvePoint(ASN1TaggedObject.getInstance(object)); + return new EccP256CurvePoint(ASN1TaggedObject.getInstance(object, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP384CurvePoint.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP384CurvePoint.java index 22fc65227c..9e50905198 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP384CurvePoint.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP384CurvePoint.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; @@ -51,15 +52,15 @@ private EccP384CurvePoint(ASN1TaggedObject ato) switch (ato.getTagNo()) { case fill: - eccP384CurvePoint = ASN1Null.getInstance(ato.getObject()); + eccP384CurvePoint = ASN1Null.getInstance(ato.getExplicitBaseObject()); break; case xonly: case compressedY0: case compressedY1: - eccP384CurvePoint = ASN1OctetString.getInstance(ato.getObject()); + eccP384CurvePoint = ASN1OctetString.getInstance(ato.getExplicitBaseObject()); break; case uncompressedP384: - eccP384CurvePoint = ASN1Sequence.getInstance(ato.getObject()); + eccP384CurvePoint = ASN1Sequence.getInstance(ato.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("invalid choice value " + ato.getTagNo()); @@ -75,7 +76,7 @@ public static EccP384CurvePoint getInstance(Object object) if (object != null) { - return new EccP384CurvePoint(ASN1TaggedObject.getInstance(object)); + return new EccP384CurvePoint(ASN1TaggedObject.getInstance(object, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EncryptionKey.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EncryptionKey.java index 542e528f22..630f1660ca 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EncryptionKey.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EncryptionKey.java @@ -5,6 +5,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -33,7 +34,7 @@ public static EncryptionKey getInstance(Object o) } if (o != null) { - return new EncryptionKey(ASN1TaggedObject.getInstance(o)); + return new EncryptionKey(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; } @@ -66,7 +67,7 @@ public static EncryptionKey symmetric(SymmetricEncryptionKey key) private EncryptionKey(ASN1TaggedObject value) { - this(value.getTagNo(), value.getObject()); + this(value.getTagNo(), value.getExplicitBaseObject()); } public int getChoice() diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/GeographicRegion.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/GeographicRegion.java index 5db43b6fec..0cb46dacd6 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/GeographicRegion.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/GeographicRegion.java @@ -3,10 +3,9 @@ import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; -import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -47,16 +46,16 @@ private GeographicRegion(ASN1TaggedObject taggedObject) switch (choice) { case circularRegion: - geographicRegion = CircularRegion.getInstance(taggedObject.getObject()); + geographicRegion = CircularRegion.getInstance(taggedObject.getExplicitBaseObject()); break; case rectangularRegion: - geographicRegion = SequenceOfRectangularRegion.getInstance(taggedObject.getObject()); + geographicRegion = SequenceOfRectangularRegion.getInstance(taggedObject.getExplicitBaseObject()); break; case polygonalRegion: - geographicRegion = PolygonalRegion.getInstance(taggedObject.getObject()); + geographicRegion = PolygonalRegion.getInstance(taggedObject.getExplicitBaseObject()); break; case identifiedRegion: - geographicRegion = SequenceOfIdentifiedRegion.getInstance(taggedObject.getObject()); + geographicRegion = SequenceOfIdentifiedRegion.getInstance(taggedObject.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("invalid choice value " + choice); @@ -92,7 +91,7 @@ public static GeographicRegion getInstance(Object o) } if (o != null) { - return new GeographicRegion(ASN1TaggedObject.getInstance(o)); + return new GeographicRegion(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/IdentifiedRegion.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/IdentifiedRegion.java index f29e87511a..9ebfd332ae 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/IdentifiedRegion.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/IdentifiedRegion.java @@ -3,10 +3,9 @@ import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; -import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; @@ -43,13 +42,13 @@ private IdentifiedRegion(ASN1TaggedObject ato) switch (choice) { case countryOnly: - identifiedRegion = CountryOnly.getInstance(ato.getObject()); + identifiedRegion = CountryOnly.getInstance(ato.getExplicitBaseObject()); break; case countryAndRegions: - identifiedRegion = CountryAndRegions.getInstance(ato.getObject()); + identifiedRegion = CountryAndRegions.getInstance(ato.getExplicitBaseObject()); break; case countryAndSubregions: - identifiedRegion = CountryAndSubregions.getInstance(ato.getObject()); + identifiedRegion = CountryAndSubregions.getInstance(ato.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("invalid choice value " + choice); @@ -80,7 +79,7 @@ public static IdentifiedRegion getInstance(Object o) } if (o != null) { - return new IdentifiedRegion(ASN1TaggedObject.getInstance(o)); + return new IdentifiedRegion(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/PolygonalRegion.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/PolygonalRegion.java index 627334475a..721a7c7144 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/PolygonalRegion.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/PolygonalRegion.java @@ -34,7 +34,7 @@ private PolygonalRegion(ASN1Sequence s) ArrayList l = new ArrayList(); for (Iterator it = s.iterator(); it.hasNext(); ) { - l.add(TwoDLocation.getInstance(s)); + l.add(TwoDLocation.getInstance(it.next())); } twoDLocations = Collections.unmodifiableList(l); } @@ -48,7 +48,7 @@ public static PolygonalRegion getInstance(Object o) } else if (o != null) { - return new PolygonalRegion(ItsUtils.fillList(TwoDLocation.class, ASN1Sequence.getInstance(o))); + return new PolygonalRegion(ASN1Sequence.getInstance(o)); } return null; } diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/PublicVerificationKey.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/PublicVerificationKey.java index 376969174c..f5a733b8c9 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/PublicVerificationKey.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/PublicVerificationKey.java @@ -3,9 +3,9 @@ import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; -import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; @@ -43,10 +43,10 @@ private PublicVerificationKey(ASN1TaggedObject taggedObject) { case ecdsaNistP256: case ecdsaBrainpoolP256r1: - publicVerificationKey = EccP256CurvePoint.getInstance(taggedObject.getObject()); + publicVerificationKey = EccP256CurvePoint.getInstance(taggedObject.getExplicitBaseObject()); return; case ecdsaBrainpoolP384r1: - publicVerificationKey = EccP384CurvePoint.getInstance(taggedObject.getObject()); + publicVerificationKey = EccP384CurvePoint.getInstance(taggedObject.getExplicitBaseObject()); return; } throw new IllegalArgumentException("invalid choice value " + taggedObject.getTagNo()); @@ -79,7 +79,7 @@ public static PublicVerificationKey getInstance(Object object) if (object != null) { - return new PublicVerificationKey(ASN1TaggedObject.getInstance(object)); + return new PublicVerificationKey(ASN1TaggedObject.getInstance(object, BERTags.CONTEXT_SPECIFIC)); } return null; } diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/ServiceSpecificPermissions.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/ServiceSpecificPermissions.java index 9df4ecc953..e49fdb26db 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/ServiceSpecificPermissions.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/ServiceSpecificPermissions.java @@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.ieee1609dot2.Opaque; @@ -40,10 +41,10 @@ private ServiceSpecificPermissions(ASN1TaggedObject sto) switch (choice) { case opaque: - serviceSpecificPermissions = Opaque.getInstance(sto.getObject()); + serviceSpecificPermissions = Opaque.getInstance(sto.getExplicitBaseObject()); return; case bitmapSsp: - serviceSpecificPermissions = BitmapSsp.getInstance(sto.getObject()); + serviceSpecificPermissions = BitmapSsp.getInstance(sto.getExplicitBaseObject()); return; } throw new IllegalArgumentException("invalid choice value " + choice); @@ -60,7 +61,7 @@ public static ServiceSpecificPermissions getInstance(Object o) if (o != null) { - return new ServiceSpecificPermissions(ASN1TaggedObject.getInstance(o)); + return new ServiceSpecificPermissions(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Signature.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Signature.java index 7a9ba65bef..cdd54e9d1d 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Signature.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Signature.java @@ -5,7 +5,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -58,10 +58,10 @@ private Signature(ASN1TaggedObject ato) { case ecdsaNistP256Signature: case ecdsaBrainpoolP256r1Signature: - signature = EcdsaP256Signature.getInstance(ato.getObject()); + signature = EcdsaP256Signature.getInstance(ato.getExplicitBaseObject()); break; case ecdsaBrainpoolP384r1Signature: - signature = EcdsaP384Signature.getInstance(ato.getObject()); + signature = EcdsaP384Signature.getInstance(ato.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("invalid choice value " + ato.getTagNo()); @@ -79,7 +79,7 @@ public static Signature getInstance(Object objectAt) if (objectAt != null) { - return new Signature(ASN1TaggedObject.getInstance(objectAt)); + return new Signature(ASN1TaggedObject.getInstance(objectAt, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SspRange.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SspRange.java index f6bd96d522..65c31cdb53 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SspRange.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SspRange.java @@ -3,11 +3,10 @@ import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; -import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -70,7 +69,7 @@ public SspRange(int choice, ASN1Encodable value) private SspRange(ASN1TaggedObject ato) { - this(ato.getTagNo(), ato.getObject()); + this(ato.getTagNo(), ato.getExplicitBaseObject()); } @@ -83,7 +82,7 @@ public static SspRange getInstance(Object src) if (src != null) { - return new SspRange(ASN1TaggedObject.getInstance(src)); + return new SspRange(ASN1TaggedObject.getInstance(src, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SymmetricEncryptionKey.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SymmetricEncryptionKey.java index 86d9d53b79..c573c01488 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SymmetricEncryptionKey.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SymmetricEncryptionKey.java @@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; @@ -37,7 +38,7 @@ private SymmetricEncryptionKey(ASN1TaggedObject instance) this.choice = instance.getTagNo(); if (choice == aes128ccm) { - ASN1OctetString str = DEROctetString.getInstance(instance.getObject()); + ASN1OctetString str = DEROctetString.getInstance(instance.getExplicitBaseObject()); if (str.getOctets().length != 16) { throw new IllegalArgumentException("aes128ccm string not 16 bytes"); @@ -58,7 +59,7 @@ public static SymmetricEncryptionKey getInstance(Object o) } if (o != null) { - return new SymmetricEncryptionKey(ASN1TaggedObject.getInstance(o)); + return new SymmetricEncryptionKey(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/AdditionalParams.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/AdditionalParams.java index cd395c00a9..79eb52733e 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/AdditionalParams.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/AdditionalParams.java @@ -5,6 +5,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.PublicEncryptionKey; @@ -55,7 +56,7 @@ private AdditionalParams(int choice, ASN1Encodable additionalParams) private AdditionalParams(ASN1TaggedObject ato) { - this(ato.getTagNo(), ato.getObject()); + this(ato.getTagNo(), ato.getExplicitBaseObject()); } public static AdditionalParams getInstance(Object o) @@ -67,8 +68,7 @@ public static AdditionalParams getInstance(Object o) if (o != null) { - ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(o); - return new AdditionalParams(taggedObject.getTagNo(), taggedObject.getObject()); + return new AdditionalParams(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/ButterflyExpansion.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/ButterflyExpansion.java index 5165b89b49..45e614c0cc 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/ButterflyExpansion.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/ButterflyExpansion.java @@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; @@ -38,7 +39,7 @@ private ButterflyExpansion(ASN1TaggedObject ato) { case aes128: - this.butterflyExpansion = DEROctetString.getInstance(ato.getObject()); + this.butterflyExpansion = DEROctetString.getInstance(ato.getExplicitBaseObject()); break; default: throw new IllegalArgumentException("invalid choice value " + choice); @@ -54,7 +55,7 @@ public static ButterflyExpansion getInstance(Object o) if (o != null) { - return new ButterflyExpansion(ASN1TaggedObject.getInstance(o)); + return new ButterflyExpansion(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/template/etsi103097/extension/EtsiTs103097ExtensionModule.java b/util/src/main/java/org/bouncycastle/oer/its/template/etsi103097/extension/EtsiTs103097ExtensionModule.java index 2824d37ac8..333008cbe4 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/template/etsi103097/extension/EtsiTs103097ExtensionModule.java +++ b/util/src/main/java/org/bouncycastle/oer/its/template/etsi103097/extension/EtsiTs103097ExtensionModule.java @@ -69,7 +69,7 @@ public class EtsiTs103097ExtensionModule public static final OERDefinition.Builder Extension = OERDefinition.seq(ExtId.label("id"), OERDefinition.aSwitch( - /** + /* * Switch to examine "Extension.id" and select the correct oer definition. */ new Switch() diff --git a/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/CertAnnContent.java b/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/CertAnnContent.java index d215740379..24cfcc801c 100644 --- a/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/CertAnnContent.java +++ b/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/CertAnnContent.java @@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.Certificate; @@ -43,7 +44,7 @@ public static CMPCertificate getInstance(ASN1TaggedObject ato, boolean isExplici { if (isExplicit) { - return CertAnnContent.getInstance(ato.getObject()); + return CertAnnContent.getInstance(ato.getExplicitBaseObject()); } else { @@ -91,13 +92,11 @@ public static CMPCertificate getInstance(Object o) if (o instanceof ASN1TaggedObject) { - ASN1TaggedObject taggedObject = (ASN1TaggedObject)o; + ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC); - return new CertAnnContent(taggedObject.getTagNo(), taggedObject.getObject()); + return new CertAnnContent(taggedObject.getTagNo(), taggedObject.getExplicitBaseObject()); } throw new IllegalArgumentException("Invalid object: " + o.getClass().getName()); } - - } diff --git a/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/OOBCert.java b/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/OOBCert.java index 7c3230b10a..30f0f7641a 100644 --- a/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/OOBCert.java +++ b/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/OOBCert.java @@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.Certificate; @@ -37,7 +38,7 @@ public static CMPCertificate getInstance(ASN1TaggedObject ato, boolean isExplici { if (isExplicit) { - return OOBCert.getInstance(ato.getObject()); + return OOBCert.getInstance(ato.getExplicitBaseObject()); } else { @@ -86,9 +87,9 @@ public static CMPCertificate getInstance(Object o) if (o instanceof ASN1TaggedObject) { - ASN1TaggedObject taggedObject = (ASN1TaggedObject)o; + ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC); - return new OOBCert(taggedObject.getTagNo(), taggedObject.getObject()); + return new OOBCert(taggedObject.getTagNo(), taggedObject.getExplicitBaseObject()); } throw new IllegalArgumentException("Invalid object: " + o.getClass().getName()); diff --git a/util/src/main/jdk1.9/module-info.java b/util/src/main/jdk1.9/module-info.java index 36886ceda4..cbeb391b31 100644 --- a/util/src/main/jdk1.9/module-info.java +++ b/util/src/main/jdk1.9/module-info.java @@ -8,15 +8,29 @@ exports org.bouncycastle.asn1.cms; exports org.bouncycastle.asn1.cms.ecc; exports org.bouncycastle.asn1.crmf; + exports org.bouncycastle.asn1.cryptlib; exports org.bouncycastle.asn1.dvcs; exports org.bouncycastle.asn1.eac; + exports org.bouncycastle.asn1.edec; exports org.bouncycastle.asn1.esf; exports org.bouncycastle.asn1.ess; exports org.bouncycastle.asn1.est; + exports org.bouncycastle.asn1.gnu; + exports org.bouncycastle.asn1.iana; exports org.bouncycastle.asn1.icao; + exports org.bouncycastle.asn1.isara; exports org.bouncycastle.asn1.isismtt; exports org.bouncycastle.asn1.isismtt.ocsp; exports org.bouncycastle.asn1.isismtt.x509; + exports org.bouncycastle.asn1.iso; + exports org.bouncycastle.asn1.kisa; + exports org.bouncycastle.asn1.microsoft; + exports org.bouncycastle.asn1.misc; + exports org.bouncycastle.asn1.mozilla; + exports org.bouncycastle.asn1.nsri; + exports org.bouncycastle.asn1.ntt; + exports org.bouncycastle.asn1.oiw; + exports org.bouncycastle.asn1.rosstandart; exports org.bouncycastle.asn1.smime; exports org.bouncycastle.asn1.tsp; exports org.bouncycastle.oer; diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCFailInfoTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCFailInfoTest.java index a2045076cc..774a4e2b2b 100644 --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCFailInfoTest.java +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCFailInfoTest.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.cmc.CMCFailInfo; +import org.bouncycastle.util.Longs; import org.bouncycastle.util.test.SimpleTest; public class CMCFailInfoTest @@ -16,20 +17,20 @@ public class CMCFailInfoTest // From Page 68, CMC: Structures RFC 5272 private static Object[][] types = new Object[][] { - {"badAlg", new Long(0L) }, - {"badMessageCheck", new Long(1L) }, - {"badRequest", new Long(2L) }, - {"badTime", new Long(3L) }, - {"badCertId", new Long(4L) }, - {"unsupportedExt", new Long(5L) }, - {"mustArchiveKeys", new Long(6L) }, - {"badIdentity", new Long(7L) }, - {"popRequired", new Long(8L) }, - {"popFailed", new Long(9L) }, - {"noKeyReuse", new Long(10L) }, - {"internalCAError", new Long(11L) }, - {"tryLater", new Long(12L) }, - {"authDataFail", new Long(13L)} + {"badAlg", Longs.valueOf(0L) }, + {"badMessageCheck", Longs.valueOf(1L) }, + {"badRequest", Longs.valueOf(2L) }, + {"badTime", Longs.valueOf(3L) }, + {"badCertId", Longs.valueOf(4L) }, + {"unsupportedExt", Longs.valueOf(5L) }, + {"mustArchiveKeys", Longs.valueOf(6L) }, + {"badIdentity", Longs.valueOf(7L) }, + {"popRequired", Longs.valueOf(8L) }, + {"popFailed", Longs.valueOf(9L) }, + {"noKeyReuse", Longs.valueOf(10L) }, + {"internalCAError", Longs.valueOf(11L) }, + {"tryLater", Longs.valueOf(12L) }, + {"authDataFail", Longs.valueOf(13L)} }; private static Map typesMap = new HashMap(); @@ -62,7 +63,7 @@ public void performTest() for (Iterator rangeKeys = range.keySet().iterator(); rangeKeys.hasNext(); ) { Object j = rangeKeys.next(); - if (!typesMap.containsKey(new Long(((ASN1Integer)j).getValue().longValue()))) + if (!typesMap.containsKey(Longs.valueOf(((ASN1Integer)j).getValue().longValue()))) { fail("The 'range' map in CMCFailInfo contains a value not in the test ('typesMap') map, value was: " + j.toString()); } diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCStatusTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCStatusTest.java index 2395980d73..683a4db298 100644 --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCStatusTest.java +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCStatusTest.java @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.cmc.CMCStatus; +import org.bouncycastle.util.Longs; import org.bouncycastle.util.test.SimpleTest; @@ -26,14 +27,14 @@ public String getName() // From Page 68, CMC: Structures RFC 5272 private static Object[][] types = new Object[][]{ - {"success", new Long(0L) }, + {"success", Longs.valueOf(0L) }, // -- reserved (1), - {"failed", new Long(2L) }, - {"pending", new Long(3L) }, - {"noSupport", new Long(4L) }, - {"confirmRequired", new Long(5L) }, - {"popRequired", new Long(6L) }, - {"partial", new Long(7L) } + {"failed", Longs.valueOf(2L) }, + {"pending", Longs.valueOf(3L) }, + {"noSupport", Longs.valueOf(4L) }, + {"confirmRequired", Longs.valueOf(5L) }, + {"popRequired", Longs.valueOf(6L) }, + {"partial", Longs.valueOf(7L) } }; private static Map typesMap = new HashMap(); @@ -66,7 +67,7 @@ public void performTest() for (Iterator rangeKeys = range.keySet().iterator(); rangeKeys.hasNext(); ) { Object j = rangeKeys.next(); - if (!typesMap.containsKey(new Long(((ASN1Integer)j).getValue().longValue()))) + if (!typesMap.containsKey(Longs.valueOf(((ASN1Integer)j).getValue().longValue()))) { fail("The 'range' map in CMCStatus contains a value not in the test ('typesMap') map, value was: " + j.toString()); } diff --git a/util/src/test/java/org/bouncycastle/asn1/cms/test/KEMRecipientInfoTest.java b/util/src/test/java/org/bouncycastle/asn1/cms/test/KEMRecipientInfoTest.java new file mode 100644 index 0000000000..acb796978b --- /dev/null +++ b/util/src/test/java/org/bouncycastle/asn1/cms/test/KEMRecipientInfoTest.java @@ -0,0 +1,122 @@ +package org.bouncycastle.asn1.cms.test; + +import junit.framework.TestCase; +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.cms.KEMRecipientInfo; +import org.bouncycastle.asn1.cms.RecipientIdentifier; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.util.encoders.Base64; + +public class KEMRecipientInfoTest + extends TestCase +{ + private static byte[] outOfRangeEnc = Base64.decode("MDoCAQCAADALBglghkgBZQMEBAEEADAMBgorgQUQhkgJLAECAgMKrmCgAgQAMAsGCWCGSAFlAwQBMAQA"); + + public void testOutOfRange() + throws Exception + { + try + { + new KEMRecipientInfo( + new RecipientIdentifier(new DEROctetString(new byte[0])), + new AlgorithmIdentifier(NISTObjectIdentifiers.id_alg_ml_kem_512), + new DEROctetString(new byte[0]), + new AlgorithmIdentifier(X9ObjectIdentifiers.id_kdf_kdf3), + new ASN1Integer(700000), new DEROctetString(new byte[0]), + new AlgorithmIdentifier(NISTObjectIdentifiers.id_aes256_wrap_pad), + new DEROctetString(new byte[0])); + fail("no exception"); + } + catch (IllegalArgumentException e) + { + assertEquals("kekLength must be <= 65535", e.getMessage()); + } + + try + { + KEMRecipientInfo.getInstance(ASN1Primitive.fromByteArray(outOfRangeEnc)); + fail("no exception"); + } + catch (IllegalArgumentException e) + { + assertEquals("kekLength must be <= 65535", e.getMessage()); + } + } + + public void testNullWrap() + throws Exception + { + try + { + new KEMRecipientInfo( + new RecipientIdentifier(new DEROctetString(new byte[0])), + new AlgorithmIdentifier(NISTObjectIdentifiers.id_alg_ml_kem_512), + new DEROctetString(new byte[0]), + new AlgorithmIdentifier(X9ObjectIdentifiers.id_kdf_kdf3), + new ASN1Integer(7000), new DEROctetString(new byte[0]), + null, + new DEROctetString(new byte[0])); + fail("no exception"); + } + catch (NullPointerException e) + { + assertEquals("wrap cannot be null", e.getMessage()); + } + } + + public void testNullKem() + throws Exception + { + try + { + new KEMRecipientInfo( + new RecipientIdentifier(new DEROctetString(new byte[0])), + null, + new DEROctetString(new byte[0]), + new AlgorithmIdentifier(X9ObjectIdentifiers.id_kdf_kdf3), + new ASN1Integer(7000), new DEROctetString(new byte[0]), + new AlgorithmIdentifier(NISTObjectIdentifiers.id_aes256_wrap_pad), + new DEROctetString(new byte[0])); + fail("no exception"); + } + catch (NullPointerException e) + { + assertEquals("kem cannot be null", e.getMessage()); + } + } + + public void testSequenceSize() + throws Exception + { + try + { + KEMRecipientInfo.getInstance(new DERSequence(new RecipientIdentifier(new DEROctetString(new byte[0])))); + fail("no exception"); + } + catch (IllegalArgumentException e) + { + assertEquals("bad sequence size: 1", e.getMessage()); + } + + try + { + ASN1Encodable[] elements = new ASN1Encodable[10]; + for (int i = 0; i != elements.length; i++) + { + elements[i] = new ASN1Integer(1); + } + KEMRecipientInfo.getInstance(new DERSequence(elements)); + fail("no exception"); + } + catch (IllegalArgumentException e) + { + assertEquals("bad sequence size: 10", e.getMessage()); + } + } +} diff --git a/util/src/test/java/org/bouncycastle/asn1/cms/test/OctetStringTest.java b/util/src/test/java/org/bouncycastle/asn1/cms/test/OctetStringTest.java index f5b36baf59..bb5daf1ace 100644 --- a/util/src/test/java/org/bouncycastle/asn1/cms/test/OctetStringTest.java +++ b/util/src/test/java/org/bouncycastle/asn1/cms/test/OctetStringTest.java @@ -12,7 +12,6 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1OctetStringParser; -import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1SequenceParser; import org.bouncycastle.asn1.ASN1StreamParser; import org.bouncycastle.asn1.BEROctetString; @@ -24,6 +23,8 @@ import org.bouncycastle.asn1.cms.CompressedDataParser; import org.bouncycastle.asn1.cms.ContentInfoParser; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.Hex; public class OctetStringTest extends TestCase @@ -142,16 +143,11 @@ public void testReadingWritingNestedDirect() new BEROctetString(new byte[20]) }); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - ASN1OutputStream aOut = ASN1OutputStream.create(bOut); - - aOut.writeObject(str); + byte[] encoding = str.getEncoded(); - aOut.close(); + ASN1OctetString decoded = ASN1OctetString.getInstance(encoding); - ASN1InputStream aIn = new ASN1InputStream(bOut.toByteArray()); - - assertTrue(Arrays.areEqual(new byte[30], ASN1OctetString.getInstance(aIn.readObject()).getOctets())); + assertTrue(Arrays.areEqual(new byte[30], decoded.getOctets())); } public void testNestedStructure() @@ -221,7 +217,39 @@ public void testNestedStructure() assertEquals(28, count); } - + + public void testShortConstructed() + throws Exception + { + byte[] data = Hex.decode("2480040a000000000000000000000000"); + + ASN1InputStream aIn = new ASN1InputStream(data); + + assertTrue(Arrays.areEqual(data, aIn.readObject().getEncoded())); + } + + public void testLongConstructed() + throws Exception + { + byte[] data = Base64.decode("JIAEggPoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASCAfQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + + ASN1InputStream aIn = new ASN1InputStream(data); + + assertTrue(Arrays.areEqual(data, aIn.readObject().getEncoded())); + } + public static Test suite() { return new TestSuite(OctetStringTest.class); diff --git a/util/src/test/java/org/bouncycastle/asn1/esf/test/SignerLocationUnitTest.java b/util/src/test/java/org/bouncycastle/asn1/esf/test/SignerLocationUnitTest.java index 458993f94b..e27ade6550 100644 --- a/util/src/test/java/org/bouncycastle/asn1/esf/test/SignerLocationUnitTest.java +++ b/util/src/test/java/org/bouncycastle/asn1/esf/test/SignerLocationUnitTest.java @@ -156,24 +156,24 @@ private void checkValues( { if (countryName != null) { - if (!countryName.equals(sl.getCountryName())) + if (!countryName.equals(sl.getCountry())) { fail("countryNames don't match."); } } - else if (sl.getCountryName() != null) + else if (sl.getCountry() != null) { fail("countryName found when none expected."); } if (localityName != null) { - if (!localityName.equals(sl.getLocalityName())) + if (!localityName.equals(sl.getLocality())) { fail("localityNames don't match."); } } - else if (sl.getLocalityName() != null) + else if (sl.getLocality() != null) { fail("localityName found when none expected."); } diff --git a/util/src/test/java/org/bouncycastle/asn1/misc/test/GetInstanceTest.java b/util/src/test/java/org/bouncycastle/asn1/misc/test/GetInstanceTest.java index 5c95713cd6..d13cc6cd4f 100644 --- a/util/src/test/java/org/bouncycastle/asn1/misc/test/GetInstanceTest.java +++ b/util/src/test/java/org/bouncycastle/asn1/misc/test/GetInstanceTest.java @@ -6,6 +6,7 @@ import java.util.Vector; import junit.framework.TestCase; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1Choice; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; @@ -18,7 +19,6 @@ import org.bouncycastle.asn1.ASN1UTCTime; import org.bouncycastle.asn1.ASN1UTF8String; import org.bouncycastle.asn1.DERBMPString; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERGeneralString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; @@ -181,8 +181,6 @@ import org.bouncycastle.asn1.isismtt.x509.ProcurationSyntax; import org.bouncycastle.asn1.isismtt.x509.ProfessionInfo; import org.bouncycastle.asn1.isismtt.x509.Restriction; -import org.bouncycastle.asn1.misc.CAST5CBCParameters; -import org.bouncycastle.asn1.misc.IDEACBCPar; import org.bouncycastle.asn1.mozilla.PublicKeyAndChallenge; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; @@ -296,6 +294,8 @@ import org.bouncycastle.asn1.x9.DHValidationParms; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; +import org.bouncycastle.asn1.misc.CAST5CBCParameters; +import org.bouncycastle.asn1.misc.IDEACBCPar; import org.bouncycastle.util.Integers; import org.bouncycastle.util.encoders.Base64; @@ -819,7 +819,7 @@ public void testGetInstance() IssuerSerial.getInstance(null); IssuingDistributionPoint.getInstance(null); IssuingDistributionPoint.getInstance(null); - DERBitString.getInstance(null); + ASN1BitString.getInstance(null); v.clear(); v.add(generalSubtree);